From 7b53c48f0375b14573d61fc14a49429dab010f6d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 04:01:38 +0000 Subject: [PATCH 1/5] Corpus: summary, summary_truncate, and plpgsql suites Extend the oracle protocol with summary (truncation limit riding along as a directive line in summary_truncate case inputs) and parse_plpgsql ops, extract libpg_query's summary test calls and the plpgsql_regress + plpgsql_samples tiers, and wire the three new suites through cmd/regenerate, the corpus harness, and difftodo. - postgres_regress runs summary untruncated plus summary_truncate at limit 100; inline summary calls keep their upstream limits and also run at limit 50. - plpgsql_regress feeds the standard SQL suites too; all of those cases pass the existing implementation and are harvested immediately. - Goldens verified byte-identical across two regeneration runs. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01C5Ummi5YEg7pxk5fvRUd3U --- cmd/difftodo/main.go | 39 +- cmd/regenerate/extract_summary.go | 80 + cmd/regenerate/main.go | 117 +- cmd/regenerate/oracle.go | 62 +- internal/testfile/golden.go | 112 + oracle/main.go | 89 +- oracle/oracle | Bin 13564592 -> 13580608 bytes parser/corpus_test.go | 50 + .../plpgsql_array.metadata.json | 3 + .../plpgsql_regress/plpgsql_array.test | 291 + .../plpgsql_cache.metadata.json | 3 + .../plpgsql_regress/plpgsql_cache.test | 91 + .../plpgsql_call.metadata.json | 3 + .../deparse/plpgsql_regress/plpgsql_call.test | 1079 ++ .../plpgsql_control.metadata.json | 3 + .../plpgsql_regress/plpgsql_control.test | 1008 ++ .../plpgsql_copy.metadata.json | 3 + .../deparse/plpgsql_regress/plpgsql_copy.test | 21 + .../plpgsql_domain.metadata.json | 3 + .../plpgsql_regress/plpgsql_domain.test | 588 + .../plpgsql_misc.metadata.json | 3 + .../deparse/plpgsql_regress/plpgsql_misc.test | 89 + .../plpgsql_record.metadata.json | 3 + .../plpgsql_regress/plpgsql_record.test | 1225 ++ .../plpgsql_simple.metadata.json | 3 + .../plpgsql_regress/plpgsql_simple.test | 205 + .../plpgsql_transaction.metadata.json | 3 + .../plpgsql_regress/plpgsql_transaction.test | 1163 ++ .../plpgsql_trap.metadata.json | 3 + .../deparse/plpgsql_regress/plpgsql_trap.test | 395 + .../plpgsql_trigger.metadata.json | 3 + .../plpgsql_regress/plpgsql_trigger.test | 46 + .../plpgsql_varprops.metadata.json | 3 + .../plpgsql_regress/plpgsql_varprops.test | 488 + .../plpgsql_array.metadata.json | 3 + .../plpgsql_regress/plpgsql_array.test | 218 + .../plpgsql_cache.metadata.json | 3 + .../plpgsql_regress/plpgsql_cache.test | 82 + .../plpgsql_call.metadata.json | 3 + .../plpgsql_regress/plpgsql_call.test | 748 + .../plpgsql_control.metadata.json | 3 + .../plpgsql_regress/plpgsql_control.test | 627 + .../plpgsql_copy.metadata.json | 3 + .../plpgsql_regress/plpgsql_copy.test | 21 + .../plpgsql_domain.metadata.json | 3 + .../plpgsql_regress/plpgsql_domain.test | 483 + .../plpgsql_misc.metadata.json | 3 + .../plpgsql_regress/plpgsql_misc.test | 77 + .../plpgsql_record.metadata.json | 3 + .../plpgsql_regress/plpgsql_record.test | 990 ++ .../plpgsql_simple.metadata.json | 3 + .../plpgsql_regress/plpgsql_simple.test | 164 + .../plpgsql_transaction.metadata.json | 3 + .../plpgsql_regress/plpgsql_transaction.test | 853 + .../plpgsql_trap.metadata.json | 3 + .../plpgsql_regress/plpgsql_trap.test | 291 + .../plpgsql_trigger.metadata.json | 3 + .../plpgsql_regress/plpgsql_trigger.test | 37 + .../plpgsql_varprops.metadata.json | 3 + .../plpgsql_regress/plpgsql_varprops.test | 325 + .../plpgsql_array.metadata.json | 3 + .../plpgsql_regress/plpgsql_array.test | 239 + .../plpgsql_cache.metadata.json | 3 + .../plpgsql_regress/plpgsql_cache.test | 103 + .../plpgsql_call.metadata.json | 3 + .../plpgsql_regress/plpgsql_call.test | 833 + .../plpgsql_control.metadata.json | 3 + .../plpgsql_regress/plpgsql_control.test | 661 + .../plpgsql_copy.metadata.json | 3 + .../plpgsql_regress/plpgsql_copy.test | 21 + .../plpgsql_domain.metadata.json | 3 + .../plpgsql_regress/plpgsql_domain.test | 533 + .../plpgsql_misc.metadata.json | 3 + .../plpgsql_regress/plpgsql_misc.test | 86 + .../plpgsql_record.metadata.json | 3 + .../plpgsql_regress/plpgsql_record.test | 1113 ++ .../plpgsql_simple.metadata.json | 3 + .../plpgsql_regress/plpgsql_simple.test | 191 + .../plpgsql_transaction.metadata.json | 3 + .../plpgsql_regress/plpgsql_transaction.test | 928 ++ .../plpgsql_trap.metadata.json | 3 + .../plpgsql_regress/plpgsql_trap.test | 310 + .../plpgsql_trigger.metadata.json | 3 + .../plpgsql_regress/plpgsql_trigger.test | 41 + .../plpgsql_varprops.metadata.json | 3 + .../plpgsql_regress/plpgsql_varprops.test | 339 + .../plpgsql_array.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_array.test | 218 + .../plpgsql_cache.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_cache.test | 82 + .../plpgsql_call.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_call.test | 748 + .../plpgsql_control.metadata.json | 3 + .../plpgsql_regress/plpgsql_control.test | 627 + .../plpgsql_copy.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_copy.test | 21 + .../plpgsql_domain.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_domain.test | 483 + .../plpgsql_misc.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_misc.test | 77 + .../plpgsql_record.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_record.test | 990 ++ .../plpgsql_simple.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_simple.test | 164 + .../plpgsql_transaction.metadata.json | 3 + .../plpgsql_regress/plpgsql_transaction.test | 853 + .../plpgsql_trap.metadata.json | 3 + .../parse/plpgsql_regress/plpgsql_trap.test | 291 + .../plpgsql_trigger.metadata.json | 3 + .../plpgsql_regress/plpgsql_trigger.test | 37 + .../plpgsql_varprops.metadata.json | 3 + .../plpgsql_regress/plpgsql_varprops.test | 325 + .../plpgsql_array.metadata.json | 35 + .../plpgsql_regress/plpgsql_array.test | 270 + .../plpgsql_cache.metadata.json | 17 + .../plpgsql_regress/plpgsql_cache.test | 87 + .../plpgsql_call.metadata.json | 87 + .../plpgsql/plpgsql_regress/plpgsql_call.test | 842 + .../plpgsql_control.metadata.json | 57 + .../plpgsql_regress/plpgsql_control.test | 689 + .../plpgsql_copy.metadata.json | 5 + .../plpgsql/plpgsql_regress/plpgsql_copy.test | 21 + .../plpgsql_domain.metadata.json | 86 + .../plpgsql_regress/plpgsql_domain.test | 530 + .../plpgsql_misc.metadata.json | 18 + .../plpgsql/plpgsql_regress/plpgsql_misc.test | 103 + .../plpgsql_record.metadata.json | 162 + .../plpgsql_regress/plpgsql_record.test | 1136 ++ .../plpgsql_simple.metadata.json | 28 + .../plpgsql_regress/plpgsql_simple.test | 186 + .../plpgsql_transaction.metadata.json | 121 + .../plpgsql_regress/plpgsql_transaction.test | 933 ++ .../plpgsql_trap.metadata.json | 46 + .../plpgsql/plpgsql_regress/plpgsql_trap.test | 305 + .../plpgsql_trigger.metadata.json | 10 + .../plpgsql_regress/plpgsql_trigger.test | 39 + .../plpgsql_varprops.metadata.json | 41 + .../plpgsql_regress/plpgsql_varprops.test | 400 + .../plpgsql/plpgsql_samples.metadata.json | 33 + parser/testdata/plpgsql/plpgsql_samples.test | 728 + .../plpgsql_array.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_array.test | 326 + .../plpgsql_cache.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_cache.test | 168 + .../plpgsql_call.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_call.test | 1315 ++ .../plpgsql_control.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_control.test | 973 ++ .../plpgsql_copy.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_copy.test | 21 + .../plpgsql_domain.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_domain.test | 1389 ++ .../plpgsql_misc.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_misc.test | 103 + .../plpgsql_record.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_record.test | 2259 +++ .../plpgsql_simple.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_simple.test | 337 + .../plpgsql_transaction.metadata.json | 3 + .../plpgsql_regress/plpgsql_transaction.test | 1403 ++ .../plpgsql_trap.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_trap.test | 531 + .../plpgsql_trigger.metadata.json | 3 + .../scan/plpgsql_regress/plpgsql_trigger.test | 98 + .../plpgsql_varprops.metadata.json | 3 + .../plpgsql_regress/plpgsql_varprops.test | 403 + .../summary/libpg_query.metadata.json | 106 + parser/testdata/summary/libpg_query.test | 911 ++ .../plpgsql_array.metadata.json | 35 + .../plpgsql_regress/plpgsql_array.test | 225 + .../plpgsql_cache.metadata.json | 17 + .../plpgsql_regress/plpgsql_cache.test | 93 + .../plpgsql_call.metadata.json | 87 + .../summary/plpgsql_regress/plpgsql_call.test | 807 + .../plpgsql_control.metadata.json | 57 + .../plpgsql_regress/plpgsql_control.test | 674 + .../plpgsql_copy.metadata.json | 5 + .../summary/plpgsql_regress/plpgsql_copy.test | 21 + .../plpgsql_domain.metadata.json | 86 + .../plpgsql_regress/plpgsql_domain.test | 557 + .../plpgsql_misc.metadata.json | 18 + .../summary/plpgsql_regress/plpgsql_misc.test | 78 + .../plpgsql_record.metadata.json | 162 + .../plpgsql_regress/plpgsql_record.test | 1116 ++ .../plpgsql_simple.metadata.json | 28 + .../plpgsql_regress/plpgsql_simple.test | 184 + .../plpgsql_transaction.metadata.json | 121 + .../plpgsql_regress/plpgsql_transaction.test | 951 ++ .../plpgsql_trap.metadata.json | 46 + .../summary/plpgsql_regress/plpgsql_trap.test | 329 + .../plpgsql_trigger.metadata.json | 10 + .../plpgsql_regress/plpgsql_trigger.test | 44 + .../plpgsql_varprops.metadata.json | 41 + .../plpgsql_regress/plpgsql_varprops.test | 325 + .../advisory_lock.metadata.json | 42 + .../postgres_regress/advisory_lock.test | 333 + .../postgres_regress/aggregates.metadata.json | 518 + .../summary/postgres_regress/aggregates.test | 4009 +++++ .../alter_generic.metadata.json | 336 + .../postgres_regress/alter_generic.test | 1809 +++ .../alter_operator.metadata.json | 69 + .../postgres_regress/alter_operator.test | 452 + .../alter_table.metadata.json | 1657 ++ .../summary/postgres_regress/alter_table.test | 9502 ++++++++++++ .../postgres_regress/amutils.metadata.json | 14 + .../summary/postgres_regress/amutils.test | 161 + .../postgres_regress/arrays.metadata.json | 488 + .../summary/postgres_regress/arrays.test | 2785 ++++ .../postgres_regress/async.metadata.json | 15 + .../summary/postgres_regress/async.test | 60 + .../postgres_regress/bit.metadata.json | 136 + .../summary/postgres_regress/bit.test | 813 + .../postgres_regress/bitmapops.metadata.json | 14 + .../summary/postgres_regress/bitmapops.test | 77 + .../postgres_regress/boolean.metadata.json | 102 + .../summary/postgres_regress/boolean.test | 579 + .../postgres_regress/box.metadata.json | 105 + .../summary/postgres_regress/box.test | 764 + .../postgres_regress/brin.metadata.json | 72 + .../summary/postgres_regress/brin.test | 849 + .../postgres_regress/brin_bloom.metadata.json | 44 + .../summary/postgres_regress/brin_bloom.test | 574 + .../postgres_regress/brin_multi.metadata.json | 176 + .../summary/postgres_regress/brin_multi.test | 1466 ++ .../btree_index.metadata.json | 100 + .../summary/postgres_regress/btree_index.test | 695 + .../postgres_regress/case.metadata.json | 68 + .../summary/postgres_regress/case.test | 490 + .../postgres_regress/char.metadata.json | 36 + .../summary/postgres_regress/char.test | 212 + .../postgres_regress/circle.metadata.json | 26 + .../summary/postgres_regress/circle.test | 158 + .../postgres_regress/cluster.metadata.json | 208 + .../summary/postgres_regress/cluster.test | 1236 ++ .../collate.icu.utf8.metadata.json | 505 + .../postgres_regress/collate.icu.utf8.test | 2980 ++++ .../collate.linux.utf8.metadata.json | 207 + .../postgres_regress/collate.linux.utf8.test | 1269 ++ .../postgres_regress/collate.metadata.json | 148 + .../summary/postgres_regress/collate.test | 911 ++ .../collate.utf8.metadata.json | 28 + .../postgres_regress/collate.utf8.test | 155 + .../collate.windows.win1252.metadata.json | 177 + .../collate.windows.win1252.test | 1095 ++ .../postgres_regress/combocid.metadata.json | 66 + .../summary/postgres_regress/combocid.test | 339 + .../postgres_regress/comments.metadata.json | 10 + .../summary/postgres_regress/comments.test | 59 + .../compression.metadata.json | 91 + .../summary/postgres_regress/compression.test | 524 + .../constraints.metadata.json | 323 + .../summary/postgres_regress/constraints.test | 1887 +++ .../postgres_regress/conversion.metadata.json | 69 + .../summary/postgres_regress/conversion.test | 677 + .../postgres_regress/copy.metadata.json | 91 + .../summary/postgres_regress/copy.test | 595 + .../postgres_regress/copy2.metadata.json | 5 + .../summary/postgres_regress/copy2.test | 373 + .../postgres_regress/copydml.metadata.json | 63 + .../summary/postgres_regress/copydml.test | 324 + .../postgres_regress/copyselect.metadata.json | 25 + .../summary/postgres_regress/copyselect.test | 148 + .../create_aggregate.metadata.json | 63 + .../postgres_regress/create_aggregate.test | 476 + .../postgres_regress/create_am.metadata.json | 146 + .../summary/postgres_regress/create_am.test | 1019 ++ .../create_cast.metadata.json | 28 + .../summary/postgres_regress/create_cast.test | 166 + .../create_function_c.metadata.json | 9 + .../postgres_regress/create_function_c.test | 53 + .../create_function_sql.metadata.json | 159 + .../postgres_regress/create_function_sql.test | 985 ++ .../create_index.metadata.json | 615 + .../postgres_regress/create_index.test | 3911 +++++ .../create_index_spgist.metadata.json | 206 + .../postgres_regress/create_index_spgist.test | 1585 ++ .../create_misc.metadata.json | 92 + .../summary/postgres_regress/create_misc.test | 588 + .../create_operator.metadata.json | 94 + .../postgres_regress/create_operator.test | 530 + .../create_procedure.metadata.json | 113 + .../postgres_regress/create_procedure.test | 654 + .../create_role.metadata.json | 141 + .../summary/postgres_regress/create_role.test | 609 + .../create_schema.metadata.json | 31 + .../postgres_regress/create_schema.test | 145 + .../create_table.metadata.json | 330 + .../postgres_regress/create_table.test | 1980 +++ .../create_table_like.metadata.json | 148 + .../postgres_regress/create_table_like.test | 822 + .../create_type.metadata.json | 89 + .../summary/postgres_regress/create_type.test | 578 + .../create_view.metadata.json | 311 + .../summary/postgres_regress/create_view.test | 2312 +++ .../postgres_regress/database.metadata.json | 20 + .../summary/postgres_regress/database.test | 72 + .../postgres_regress/date.metadata.json | 274 + .../summary/postgres_regress/date.test | 1362 ++ .../postgres_regress/dbsize.metadata.json | 29 + .../summary/postgres_regress/dbsize.test | 167 + .../postgres_regress/delete.metadata.json | 14 + .../summary/postgres_regress/delete.test | 66 + .../postgres_regress/dependency.metadata.json | 66 + .../summary/postgres_regress/dependency.test | 302 + .../postgres_regress/domain.metadata.json | 323 + .../summary/postgres_regress/domain.test | 1789 +++ .../drop_if_exists.metadata.json | 165 + .../postgres_regress/drop_if_exists.test | 750 + .../drop_operator.metadata.json | 16 + .../postgres_regress/drop_operator.test | 109 + .../postgres_regress/enum.metadata.json | 174 + .../summary/postgres_regress/enum.test | 927 ++ .../postgres_regress/equivclass.metadata.json | 83 + .../summary/postgres_regress/equivclass.test | 640 + .../postgres_regress/errors.metadata.json | 89 + .../summary/postgres_regress/errors.test | 666 + .../event_trigger.metadata.json | 234 + .../postgres_regress/event_trigger.test | 1367 ++ .../event_trigger_login.metadata.json | 15 + .../postgres_regress/event_trigger_login.test | 64 + .../postgres_regress/explain.metadata.json | 55 + .../summary/postgres_regress/explain.test | 348 + .../expressions.metadata.json | 75 + .../summary/postgres_regress/expressions.test | 452 + .../fast_default.metadata.json | 273 + .../postgres_regress/fast_default.test | 1617 ++ .../postgres_regress/float4.metadata.json | 104 + .../summary/postgres_regress/float4.test | 747 + .../postgres_regress/float8.metadata.json | 173 + .../summary/postgres_regress/float8.test | 1173 ++ .../foreign_data.metadata.json | 534 + .../postgres_regress/foreign_data.test | 2652 ++++ .../foreign_key.metadata.json | 1158 ++ .../summary/postgres_regress/foreign_key.test | 6735 ++++++++ .../functional_deps.metadata.json | 44 + .../postgres_regress/functional_deps.test | 395 + .../postgres_regress/generated.metadata.json | 123 + .../summary/postgres_regress/generated.test | 699 + .../postgres_regress/geometry.metadata.json | 166 + .../summary/postgres_regress/geometry.test | 1570 ++ .../postgres_regress/gin.metadata.json | 63 + .../summary/postgres_regress/gin.test | 438 + .../postgres_regress/gist.metadata.json | 66 + .../summary/postgres_regress/gist.test | 584 + .../groupingsets.metadata.json | 176 + .../postgres_regress/groupingsets.test | 1405 ++ .../postgres_regress/guc.metadata.json | 218 + .../summary/postgres_regress/guc.test | 1034 ++ .../postgres_regress/hash_func.metadata.json | 47 + .../summary/postgres_regress/hash_func.test | 803 + .../postgres_regress/hash_index.metadata.json | 101 + .../summary/postgres_regress/hash_index.test | 688 + .../postgres_regress/hash_part.metadata.json | 32 + .../summary/postgres_regress/hash_part.test | 184 + .../postgres_regress/horology.metadata.json | 392 + .../summary/postgres_regress/horology.test | 1995 +++ .../postgres_regress/identity.metadata.json | 274 + .../summary/postgres_regress/identity.test | 1600 ++ .../incremental_sort.metadata.json | 123 + .../postgres_regress/incremental_sort.test | 803 + .../index_including.metadata.json | 139 + .../postgres_regress/index_including.test | 862 ++ .../index_including_gist.metadata.json | 54 + .../index_including_gist.test | 368 + .../postgres_regress/indexing.metadata.json | 564 + .../summary/postgres_regress/indexing.test | 3228 ++++ .../indirect_toast.metadata.json | 32 + .../postgres_regress/indirect_toast.test | 198 + .../postgres_regress/inet.metadata.json | 115 + .../summary/postgres_regress/inet.test | 759 + .../infinite_recurse.metadata.json | 7 + .../postgres_regress/infinite_recurse.test | 33 + .../postgres_regress/inherit.metadata.json | 681 + .../summary/postgres_regress/inherit.test | 4183 +++++ .../postgres_regress/init_privs.metadata.json | 8 + .../summary/postgres_regress/init_privs.test | 25 + .../postgres_regress/insert.metadata.json | 391 + .../summary/postgres_regress/insert.test | 2298 +++ .../insert_conflict.metadata.json | 261 + .../postgres_regress/insert_conflict.test | 1691 ++ .../postgres_regress/int2.metadata.json | 80 + .../summary/postgres_regress/int2.test | 438 + .../postgres_regress/int4.metadata.json | 98 + .../summary/postgres_regress/int4.test | 556 + .../postgres_regress/int8.metadata.json | 171 + .../summary/postgres_regress/int8.test | 921 ++ .../postgres_regress/interval.metadata.json | 447 + .../summary/postgres_regress/interval.test | 2252 +++ .../postgres_regress/join.metadata.json | 719 + .../summary/postgres_regress/join.test | 7366 +++++++++ .../postgres_regress/join_hash.metadata.json | 283 + .../summary/postgres_regress/join_hash.test | 1812 +++ .../postgres_regress/json.metadata.json | 464 + .../summary/postgres_regress/json.test | 2566 ++++ .../json_encoding.metadata.json | 48 + .../postgres_regress/json_encoding.test | 231 + .../postgres_regress/jsonb.metadata.json | 1063 ++ .../summary/postgres_regress/jsonb.test | 5586 +++++++ .../jsonb_jsonpath.metadata.json | 825 + .../postgres_regress/jsonb_jsonpath.test | 4255 +++++ .../postgres_regress/jsonpath.metadata.json | 228 + .../summary/postgres_regress/jsonpath.test | 923 ++ .../jsonpath_encoding.metadata.json | 36 + .../postgres_regress/jsonpath_encoding.test | 171 + .../largeobject.metadata.json | 128 + .../summary/postgres_regress/largeobject.test | 764 + .../postgres_regress/limit.metadata.json | 84 + .../summary/postgres_regress/limit.test | 509 + .../postgres_regress/line.metadata.json | 39 + .../summary/postgres_regress/line.test | 212 + .../postgres_regress/lock.metadata.json | 135 + .../summary/postgres_regress/lock.test | 725 + .../postgres_regress/lseg.metadata.json | 20 + .../summary/postgres_regress/lseg.test | 107 + .../postgres_regress/macaddr.metadata.json | 39 + .../summary/postgres_regress/macaddr.test | 215 + .../postgres_regress/macaddr8.metadata.json | 75 + .../summary/postgres_regress/macaddr8.test | 418 + .../maintain_every.metadata.json | 20 + .../postgres_regress/maintain_every.test | 86 + .../postgres_regress/matview.metadata.json | 183 + .../summary/postgres_regress/matview.test | 1116 ++ .../postgres_regress/md5.metadata.json | 18 + .../summary/postgres_regress/md5.test | 79 + .../postgres_regress/memoize.metadata.json | 73 + .../summary/postgres_regress/memoize.test | 510 + .../postgres_regress/merge.metadata.json | 576 + .../summary/postgres_regress/merge.test | 4075 +++++ .../postgres_regress/misc.metadata.json | 65 + .../summary/postgres_regress/misc.test | 520 + .../misc_functions.metadata.json | 123 + .../postgres_regress/misc_functions.test | 781 + .../misc_sanity.metadata.json | 9 + .../summary/postgres_regress/misc_sanity.test | 118 + .../postgres_regress/money.metadata.json | 113 + .../summary/postgres_regress/money.test | 525 + .../multirangetypes.metadata.json | 609 + .../postgres_regress/multirangetypes.test | 4086 +++++ .../postgres_regress/mvcc.metadata.json | 15 + .../summary/postgres_regress/mvcc.test | 79 + .../postgres_regress/name.metadata.json | 44 + .../summary/postgres_regress/name.test | 250 + .../postgres_regress/namespace.metadata.json | 46 + .../summary/postgres_regress/namespace.test | 249 + .../postgres_regress/numeric.metadata.json | 1022 ++ .../summary/postgres_regress/numeric.test | 6239 ++++++++ .../numeric_big.metadata.json | 556 + .../summary/postgres_regress/numeric_big.test | 4180 +++++ .../postgres_regress/numerology.metadata.json | 5 + .../summary/postgres_regress/numerology.test | 200 + .../object_address.metadata.json | 85 + .../postgres_regress/object_address.test | 579 + .../postgres_regress/oid.metadata.json | 41 + .../summary/postgres_regress/oid.test | 223 + .../postgres_regress/oidjoins.metadata.json | 5 + .../summary/postgres_regress/oidjoins.test | 52 + .../postgres_regress/opr_sanity.metadata.json | 134 + .../summary/postgres_regress/opr_sanity.test | 3189 ++++ .../partition_aggregate.metadata.json | 139 + .../postgres_regress/partition_aggregate.test | 1132 ++ .../partition_info.metadata.json | 77 + .../postgres_regress/partition_info.test | 425 + .../partition_join.metadata.json | 604 + .../postgres_regress/partition_join.test | 4915 ++++++ .../partition_prune.metadata.json | 702 + .../postgres_regress/partition_prune.test | 4633 ++++++ .../postgres_regress/password.metadata.json | 55 + .../summary/postgres_regress/password.test | 274 + .../postgres_regress/path.metadata.json | 27 + .../summary/postgres_regress/path.test | 147 + .../postgres_regress/pg_lsn.metadata.json | 35 + .../summary/postgres_regress/pg_lsn.test | 181 + .../postgres_regress/plancache.metadata.json | 101 + .../summary/postgres_regress/plancache.test | 559 + .../postgres_regress/plpgsql.metadata.json | 945 ++ .../summary/postgres_regress/plpgsql.test | 8012 ++++++++++ .../postgres_regress/point.metadata.json | 47 + .../summary/postgres_regress/point.test | 308 + .../postgres_regress/polygon.metadata.json | 66 + .../summary/postgres_regress/polygon.test | 444 + .../polymorphism.metadata.json | 427 + .../postgres_regress/polymorphism.test | 2812 ++++ .../postgres_regress/portals.metadata.json | 353 + .../summary/postgres_regress/portals.test | 1625 ++ .../postgres_regress/portals_p2.metadata.json | 45 + .../summary/postgres_regress/portals_p2.test | 181 + .../postgres_regress/predicate.metadata.json | 46 + .../summary/postgres_regress/predicate.test | 431 + .../postgres_regress/prepare.metadata.json | 37 + .../summary/postgres_regress/prepare.test | 202 + .../prepared_xacts.metadata.json | 87 + .../postgres_regress/prepared_xacts.test | 439 + .../postgres_regress/privileges.metadata.json | 335 + .../summary/postgres_regress/privileges.test | 1881 +++ .../postgres_regress/psql.metadata.json | 200 + .../summary/postgres_regress/psql.test | 1032 ++ .../psql_crosstab.metadata.json | 12 + .../postgres_regress/psql_crosstab.test | 145 + .../publication.metadata.json | 659 + .../summary/postgres_regress/publication.test | 3236 ++++ .../postgres_regress/random.metadata.json | 52 + .../summary/postgres_regress/random.test | 514 + .../postgres_regress/rangefuncs.metadata.json | 432 + .../summary/postgres_regress/rangefuncs.test | 2557 +++ .../postgres_regress/rangetypes.metadata.json | 411 + .../summary/postgres_regress/rangetypes.test | 2802 ++++ .../postgres_regress/regex.metadata.json | 109 + .../summary/postgres_regress/regex.test | 527 + .../postgres_regress/regproc.metadata.json | 109 + .../summary/postgres_regress/regproc.test | 562 + .../reindex_catalog.metadata.json | 24 + .../postgres_regress/reindex_catalog.test | 129 + .../postgres_regress/reloptions.metadata.json | 70 + .../summary/postgres_regress/reloptions.test | 400 + .../replica_identity.metadata.json | 60 + .../postgres_regress/replica_identity.test | 342 + .../postgres_regress/returning.metadata.json | 81 + .../summary/postgres_regress/returning.test | 491 + .../roleattributes.metadata.json | 84 + .../postgres_regress/roleattributes.test | 393 + .../rowsecurity.metadata.json | 779 + .../summary/postgres_regress/rowsecurity.test | 4822 ++++++ .../postgres_regress/rowtypes.metadata.json | 241 + .../summary/postgres_regress/rowtypes.test | 1424 ++ .../postgres_regress/rules.metadata.json | 624 + .../summary/postgres_regress/rules.test | 4008 +++++ .../sanity_check.metadata.json | 7 + .../postgres_regress/sanity_check.test | 49 + .../security_label.metadata.json | 32 + .../postgres_regress/security_label.test | 142 + .../postgres_regress/select.metadata.json | 91 + .../summary/postgres_regress/select.test | 637 + .../select_distinct.metadata.json | 80 + .../postgres_regress/select_distinct.test | 487 + .../select_distinct_on.metadata.json | 12 + .../postgres_regress/select_distinct_on.test | 78 + .../select_having.metadata.json | 27 + .../postgres_regress/select_having.test | 166 + .../select_implicit.metadata.json | 48 + .../postgres_regress/select_implicit.test | 384 + .../select_into.metadata.json | 71 + .../summary/postgres_regress/select_into.test | 449 + .../select_parallel.metadata.json | 239 + .../postgres_regress/select_parallel.test | 1540 ++ .../select_views.metadata.json | 56 + .../postgres_regress/select_views.test | 449 + .../postgres_regress/sequence.metadata.json | 264 + .../summary/postgres_regress/sequence.test | 1314 ++ .../postgres_regress/spgist.metadata.json | 35 + .../summary/postgres_regress/spgist.test | 239 + .../postgres_regress/sqljson.metadata.json | 223 + .../summary/postgres_regress/sqljson.test | 1163 ++ .../sqljson_jsontable.metadata.json | 121 + .../postgres_regress/sqljson_jsontable.test | 913 ++ .../sqljson_queryfuncs.metadata.json | 314 + .../postgres_regress/sqljson_queryfuncs.test | 1455 ++ .../postgres_regress/stats.metadata.json | 451 + .../summary/postgres_regress/stats.test | 2782 ++++ .../postgres_regress/stats_ext.metadata.json | 820 + .../summary/postgres_regress/stats_ext.test | 4569 ++++++ .../postgres_regress/strings.metadata.json | 5 + .../summary/postgres_regress/strings.test | 868 ++ .../subscription.metadata.json | 163 + .../postgres_regress/subscription.test | 733 + .../postgres_regress/subselect.metadata.json | 273 + .../summary/postgres_regress/subselect.test | 2560 +++ .../postgres_regress/sysviews.metadata.json | 31 + .../summary/postgres_regress/sysviews.test | 199 + .../tablesample.metadata.json | 60 + .../summary/postgres_regress/tablesample.test | 327 + .../postgres_regress/tablespace.metadata.json | 208 + .../summary/postgres_regress/tablespace.test | 1200 ++ .../postgres_regress/temp.metadata.json | 166 + .../summary/postgres_regress/temp.test | 864 ++ .../postgres_regress/test_setup.metadata.json | 73 + .../summary/postgres_regress/test_setup.test | 540 + .../postgres_regress/text.metadata.json | 77 + .../summary/postgres_regress/text.test | 401 + .../postgres_regress/tid.metadata.json | 45 + .../summary/postgres_regress/tid.test | 239 + .../tidrangescan.metadata.json | 49 + .../postgres_regress/tidrangescan.test | 312 + .../postgres_regress/tidscan.metadata.json | 53 + .../summary/postgres_regress/tidscan.test | 340 + .../postgres_regress/time.metadata.json | 48 + .../summary/postgres_regress/time.test | 260 + .../postgres_regress/timestamp.metadata.json | 175 + .../summary/postgres_regress/timestamp.test | 1164 ++ .../timestamptz.metadata.json | 386 + .../summary/postgres_regress/timestamptz.test | 2227 +++ .../postgres_regress/timetz.metadata.json | 61 + .../summary/postgres_regress/timetz.test | 349 + .../transactions.metadata.json | 494 + .../postgres_regress/transactions.test | 2554 +++ .../postgres_regress/triggers.metadata.json | 1060 ++ .../summary/postgres_regress/triggers.test | 6940 +++++++++ .../postgres_regress/truncate.metadata.json | 197 + .../summary/postgres_regress/truncate.test | 1111 ++ .../postgres_regress/tsdicts.metadata.json | 135 + .../summary/postgres_regress/tsdicts.test | 732 + .../postgres_regress/tsearch.metadata.json | 446 + .../summary/postgres_regress/tsearch.test | 2992 ++++ .../postgres_regress/tsrf.metadata.json | 78 + .../summary/postgres_regress/tsrf.test | 547 + .../postgres_regress/tstypes.metadata.json | 242 + .../summary/postgres_regress/tstypes.test | 1110 ++ .../postgres_regress/tuplesort.metadata.json | 110 + .../summary/postgres_regress/tuplesort.test | 659 + .../postgres_regress/txid.metadata.json | 51 + .../summary/postgres_regress/txid.test | 284 + .../type_sanity.metadata.json | 65 + .../summary/postgres_regress/type_sanity.test | 1180 ++ .../typed_table.metadata.json | 32 + .../summary/postgres_regress/typed_table.test | 163 + .../postgres_regress/unicode.metadata.json | 21 + .../summary/postgres_regress/unicode.test | 100 + .../postgres_regress/union.metadata.json | 195 + .../summary/postgres_regress/union.test | 1333 ++ .../updatable_views.metadata.json | 1104 ++ .../postgres_regress/updatable_views.test | 7250 +++++++++ .../postgres_regress/update.metadata.json | 261 + .../summary/postgres_regress/update.test | 1678 ++ .../postgres_regress/uuid.metadata.json | 48 + .../summary/postgres_regress/uuid.test | 312 + .../postgres_regress/vacuum.metadata.json | 300 + .../summary/postgres_regress/vacuum.test | 1674 ++ .../vacuum_parallel.metadata.json | 18 + .../postgres_regress/vacuum_parallel.test | 110 + .../postgres_regress/varchar.metadata.json | 26 + .../summary/postgres_regress/varchar.test | 163 + .../postgres_regress/window.metadata.json | 390 + .../summary/postgres_regress/window.test | 3859 +++++ .../postgres_regress/with.metadata.json | 297 + .../summary/postgres_regress/with.test | 3310 ++++ .../write_parallel.metadata.json | 26 + .../postgres_regress/write_parallel.test | 149 + .../postgres_regress/xid.metadata.json | 88 + .../summary/postgres_regress/xid.test | 475 + .../postgres_regress/xml.metadata.json | 274 + .../summary/postgres_regress/xml.test | 1650 ++ .../postgres_regress/xmlmap.metadata.json | 44 + .../summary/postgres_regress/xmlmap.test | 209 + .../libpg_query.metadata.json | 120 + .../summary_truncate/libpg_query.test | 1222 ++ .../advisory_lock.metadata.json | 42 + .../postgres_regress/advisory_lock.test | 394 + .../postgres_regress/aggregates.metadata.json | 518 + .../postgres_regress/aggregates.test | 5035 ++++++ .../alter_generic.metadata.json | 336 + .../postgres_regress/alter_generic.test | 2472 +++ .../alter_operator.metadata.json | 69 + .../postgres_regress/alter_operator.test | 582 + .../alter_table.metadata.json | 1657 ++ .../postgres_regress/alter_table.test | 12806 ++++++++++++++++ .../postgres_regress/amutils.metadata.json | 14 + .../postgres_regress/amutils.test | 181 + .../postgres_regress/arrays.metadata.json | 488 + .../postgres_regress/arrays.test | 3752 +++++ .../postgres_regress/async.metadata.json | 15 + .../postgres_regress/async.test | 82 + .../postgres_regress/bit.metadata.json | 136 + .../postgres_regress/bit.test | 1077 ++ .../postgres_regress/bitmapops.metadata.json | 14 + .../postgres_regress/bitmapops.test | 97 + .../postgres_regress/boolean.metadata.json | 102 + .../postgres_regress/boolean.test | 775 + .../postgres_regress/box.metadata.json | 105 + .../postgres_regress/box.test | 966 ++ .../postgres_regress/brin.metadata.json | 72 + .../postgres_regress/brin.test | 985 ++ .../postgres_regress/brin_bloom.metadata.json | 44 + .../postgres_regress/brin_bloom.test | 654 + .../postgres_regress/brin_multi.metadata.json | 176 + .../postgres_regress/brin_multi.test | 1810 +++ .../btree_index.metadata.json | 100 + .../postgres_regress/btree_index.test | 883 ++ .../postgres_regress/case.metadata.json | 68 + .../postgres_regress/case.test | 618 + .../postgres_regress/char.metadata.json | 36 + .../postgres_regress/char.test | 276 + .../postgres_regress/circle.metadata.json | 26 + .../postgres_regress/circle.test | 202 + .../postgres_regress/cluster.metadata.json | 208 + .../postgres_regress/cluster.test | 1644 ++ .../collate.icu.utf8.metadata.json | 505 + .../postgres_regress/collate.icu.utf8.test | 3980 +++++ .../collate.linux.utf8.metadata.json | 207 + .../postgres_regress/collate.linux.utf8.test | 1673 ++ .../postgres_regress/collate.metadata.json | 148 + .../postgres_regress/collate.test | 1198 ++ .../collate.utf8.metadata.json | 28 + .../postgres_regress/collate.utf8.test | 203 + .../collate.windows.win1252.metadata.json | 177 + .../collate.windows.win1252.test | 1439 ++ .../postgres_regress/combocid.metadata.json | 66 + .../postgres_regress/combocid.test | 463 + .../postgres_regress/comments.metadata.json | 10 + .../postgres_regress/comments.test | 71 + .../compression.metadata.json | 91 + .../postgres_regress/compression.test | 698 + .../constraints.metadata.json | 323 + .../postgres_regress/constraints.test | 2521 +++ .../postgres_regress/conversion.metadata.json | 69 + .../postgres_regress/conversion.test | 805 + .../postgres_regress/copy.metadata.json | 91 + .../postgres_regress/copy.test | 759 + .../postgres_regress/copy2.metadata.json | 5 + .../postgres_regress/copy2.test | 374 + .../postgres_regress/copydml.metadata.json | 63 + .../postgres_regress/copydml.test | 442 + .../postgres_regress/copyselect.metadata.json | 25 + .../postgres_regress/copyselect.test | 188 + .../create_aggregate.metadata.json | 63 + .../postgres_regress/create_aggregate.test | 594 + .../postgres_regress/create_am.metadata.json | 146 + .../postgres_regress/create_am.test | 1300 ++ .../create_cast.metadata.json | 28 + .../postgres_regress/create_cast.test | 214 + .../create_function_c.metadata.json | 9 + .../postgres_regress/create_function_c.test | 60 + .../create_function_sql.metadata.json | 159 + .../postgres_regress/create_function_sql.test | 1288 ++ .../create_index.metadata.json | 615 + .../postgres_regress/create_index.test | 5129 +++++++ .../create_index_spgist.metadata.json | 206 + .../postgres_regress/create_index_spgist.test | 1989 +++ .../create_misc.metadata.json | 92 + .../postgres_regress/create_misc.test | 764 + .../create_operator.metadata.json | 94 + .../postgres_regress/create_operator.test | 708 + .../create_procedure.metadata.json | 113 + .../postgres_regress/create_procedure.test | 870 ++ .../create_role.metadata.json | 141 + .../postgres_regress/create_role.test | 883 ++ .../create_schema.metadata.json | 31 + .../postgres_regress/create_schema.test | 199 + .../create_table.metadata.json | 330 + .../postgres_regress/create_table.test | 2628 ++++ .../create_table_like.metadata.json | 148 + .../postgres_regress/create_table_like.test | 1110 ++ .../create_type.metadata.json | 89 + .../postgres_regress/create_type.test | 743 + .../create_view.metadata.json | 311 + .../postgres_regress/create_view.test | 2924 ++++ .../postgres_regress/database.metadata.json | 20 + .../postgres_regress/database.test | 104 + .../postgres_regress/date.metadata.json | 274 + .../postgres_regress/date.test | 1902 +++ .../postgres_regress/dbsize.metadata.json | 29 + .../postgres_regress/dbsize.test | 217 + .../postgres_regress/delete.metadata.json | 14 + .../postgres_regress/delete.test | 86 + .../postgres_regress/dependency.metadata.json | 66 + .../postgres_regress/dependency.test | 426 + .../postgres_regress/domain.metadata.json | 323 + .../postgres_regress/domain.test | 2424 +++ .../drop_if_exists.metadata.json | 165 + .../postgres_regress/drop_if_exists.test | 1072 ++ .../drop_operator.metadata.json | 16 + .../postgres_regress/drop_operator.test | 133 + .../postgres_regress/enum.metadata.json | 174 + .../postgres_regress/enum.test | 1267 ++ .../postgres_regress/equivclass.metadata.json | 83 + .../postgres_regress/equivclass.test | 798 + .../postgres_regress/errors.metadata.json | 89 + .../postgres_regress/errors.test | 795 + .../event_trigger.metadata.json | 234 + .../postgres_regress/event_trigger.test | 1826 +++ .../event_trigger_login.metadata.json | 15 + .../postgres_regress/event_trigger_login.test | 85 + .../postgres_regress/explain.metadata.json | 55 + .../postgres_regress/explain.test | 450 + .../expressions.metadata.json | 75 + .../postgres_regress/expressions.test | 594 + .../fast_default.metadata.json | 273 + .../postgres_regress/fast_default.test | 2155 +++ .../postgres_regress/float4.metadata.json | 104 + .../postgres_regress/float4.test | 947 ++ .../postgres_regress/float8.metadata.json | 173 + .../postgres_regress/float8.test | 1511 ++ .../foreign_data.metadata.json | 534 + .../postgres_regress/foreign_data.test | 3708 +++++ .../foreign_key.metadata.json | 1158 ++ .../postgres_regress/foreign_key.test | 9039 +++++++++++ .../functional_deps.metadata.json | 44 + .../postgres_regress/functional_deps.test | 475 + .../postgres_regress/generated.metadata.json | 123 + .../postgres_regress/generated.test | 936 ++ .../postgres_regress/geometry.metadata.json | 166 + .../postgres_regress/geometry.test | 1894 +++ .../postgres_regress/gin.metadata.json | 63 + .../postgres_regress/gin.test | 556 + .../postgres_regress/gist.metadata.json | 66 + .../postgres_regress/gist.test | 708 + .../groupingsets.metadata.json | 176 + .../postgres_regress/groupingsets.test | 1749 +++ .../postgres_regress/guc.metadata.json | 218 + .../postgres_regress/guc.test | 1462 ++ .../postgres_regress/hash_func.metadata.json | 47 + .../postgres_regress/hash_func.test | 889 ++ .../postgres_regress/hash_index.metadata.json | 101 + .../postgres_regress/hash_index.test | 878 ++ .../postgres_regress/hash_part.metadata.json | 32 + .../postgres_regress/hash_part.test | 240 + .../postgres_regress/horology.metadata.json | 392 + .../postgres_regress/horology.test | 2771 ++++ .../postgres_regress/identity.metadata.json | 274 + .../postgres_regress/identity.test | 2140 +++ .../incremental_sort.metadata.json | 123 + .../postgres_regress/incremental_sort.test | 1041 ++ .../index_including.metadata.json | 139 + .../postgres_regress/index_including.test | 1132 ++ .../index_including_gist.metadata.json | 54 + .../index_including_gist.test | 468 + .../postgres_regress/indexing.metadata.json | 564 + .../postgres_regress/indexing.test | 4348 ++++++ .../indirect_toast.metadata.json | 32 + .../postgres_regress/indirect_toast.test | 253 + .../postgres_regress/inet.metadata.json | 115 + .../postgres_regress/inet.test | 981 ++ .../infinite_recurse.metadata.json | 7 + .../postgres_regress/infinite_recurse.test | 39 + .../postgres_regress/inherit.metadata.json | 681 + .../postgres_regress/inherit.test | 5537 +++++++ .../postgres_regress/init_privs.metadata.json | 8 + .../postgres_regress/init_privs.test | 33 + .../postgres_regress/insert.metadata.json | 391 + .../postgres_regress/insert.test | 3071 ++++ .../insert_conflict.metadata.json | 261 + .../postgres_regress/insert_conflict.test | 2205 +++ .../postgres_regress/int2.metadata.json | 80 + .../postgres_regress/int2.test | 590 + .../postgres_regress/int4.metadata.json | 98 + .../postgres_regress/int4.test | 744 + .../postgres_regress/int8.metadata.json | 171 + .../postgres_regress/int8.test | 1255 ++ .../postgres_regress/interval.metadata.json | 447 + .../postgres_regress/interval.test | 3138 ++++ .../postgres_regress/join.metadata.json | 719 + .../postgres_regress/join.test | 8796 +++++++++++ .../postgres_regress/join_hash.metadata.json | 283 + .../postgres_regress/join_hash.test | 2370 +++ .../postgres_regress/json.metadata.json | 464 + .../postgres_regress/json.test | 3486 +++++ .../json_encoding.metadata.json | 48 + .../postgres_regress/json_encoding.test | 319 + .../postgres_regress/jsonb.metadata.json | 1063 ++ .../postgres_regress/jsonb.test | 7703 ++++++++++ .../jsonb_jsonpath.metadata.json | 825 + .../postgres_regress/jsonb_jsonpath.test | 5897 +++++++ .../postgres_regress/jsonpath.metadata.json | 228 + .../postgres_regress/jsonpath.test | 1371 ++ .../jsonpath_encoding.metadata.json | 36 + .../postgres_regress/jsonpath_encoding.test | 235 + .../largeobject.metadata.json | 128 + .../postgres_regress/largeobject.test | 996 ++ .../postgres_regress/limit.metadata.json | 84 + .../postgres_regress/limit.test | 667 + .../postgres_regress/line.metadata.json | 39 + .../postgres_regress/line.test | 282 + .../postgres_regress/lock.metadata.json | 135 + .../postgres_regress/lock.test | 986 ++ .../postgres_regress/lseg.metadata.json | 20 + .../postgres_regress/lseg.test | 139 + .../postgres_regress/macaddr.metadata.json | 39 + .../postgres_regress/macaddr.test | 285 + .../postgres_regress/macaddr8.metadata.json | 75 + .../postgres_regress/macaddr8.test | 560 + .../maintain_every.metadata.json | 20 + .../postgres_regress/maintain_every.test | 118 + .../postgres_regress/matview.metadata.json | 183 + .../postgres_regress/matview.test | 1474 ++ .../postgres_regress/md5.metadata.json | 18 + .../postgres_regress/md5.test | 107 + .../postgres_regress/memoize.metadata.json | 73 + .../postgres_regress/memoize.test | 648 + .../postgres_regress/merge.metadata.json | 576 + .../postgres_regress/merge.test | 5210 +++++++ .../postgres_regress/misc.metadata.json | 65 + .../postgres_regress/misc.test | 636 + .../misc_functions.metadata.json | 123 + .../postgres_regress/misc_functions.test | 1011 ++ .../misc_sanity.metadata.json | 9 + .../postgres_regress/misc_sanity.test | 128 + .../postgres_regress/money.metadata.json | 113 + .../postgres_regress/money.test | 743 + .../multirangetypes.metadata.json | 609 + .../postgres_regress/multirangetypes.test | 5296 +++++++ .../postgres_regress/mvcc.metadata.json | 15 + .../postgres_regress/mvcc.test | 100 + .../postgres_regress/name.metadata.json | 44 + .../postgres_regress/name.test | 330 + .../postgres_regress/namespace.metadata.json | 46 + .../postgres_regress/namespace.test | 332 + .../postgres_regress/numeric.metadata.json | 1022 ++ .../postgres_regress/numeric.test | 8275 ++++++++++ .../numeric_big.metadata.json | 556 + .../postgres_regress/numeric_big.test | 5284 +++++++ .../postgres_regress/numerology.metadata.json | 5 + .../postgres_regress/numerology.test | 201 + .../object_address.metadata.json | 85 + .../postgres_regress/object_address.test | 741 + .../postgres_regress/oid.metadata.json | 41 + .../postgres_regress/oid.test | 297 + .../postgres_regress/oidjoins.metadata.json | 5 + .../postgres_regress/oidjoins.test | 54 + .../postgres_regress/opr_sanity.metadata.json | 134 + .../postgres_regress/opr_sanity.test | 3449 +++++ .../partition_aggregate.metadata.json | 139 + .../postgres_regress/partition_aggregate.test | 1402 ++ .../partition_info.metadata.json | 77 + .../postgres_regress/partition_info.test | 571 + .../partition_join.metadata.json | 604 + .../postgres_regress/partition_join.test | 6115 ++++++++ .../partition_prune.metadata.json | 702 + .../postgres_regress/partition_prune.test | 6029 ++++++++ .../postgres_regress/password.metadata.json | 55 + .../postgres_regress/password.test | 376 + .../postgres_regress/path.metadata.json | 27 + .../postgres_regress/path.test | 193 + .../postgres_regress/pg_lsn.metadata.json | 35 + .../postgres_regress/pg_lsn.test | 243 + .../postgres_regress/plancache.metadata.json | 101 + .../postgres_regress/plancache.test | 753 + .../postgres_regress/plpgsql.metadata.json | 945 ++ .../postgres_regress/plpgsql.test | 9894 ++++++++++++ .../postgres_regress/point.metadata.json | 47 + .../postgres_regress/point.test | 394 + .../postgres_regress/polygon.metadata.json | 66 + .../postgres_regress/polygon.test | 568 + .../polymorphism.metadata.json | 427 + .../postgres_regress/polymorphism.test | 3658 +++++ .../postgres_regress/portals.metadata.json | 353 + .../postgres_regress/portals.test | 2323 +++ .../postgres_regress/portals_p2.metadata.json | 45 + .../postgres_regress/portals_p2.test | 263 + .../postgres_regress/predicate.metadata.json | 46 + .../postgres_regress/predicate.test | 515 + .../postgres_regress/prepare.metadata.json | 37 + .../postgres_regress/prepare.test | 268 + .../prepared_xacts.metadata.json | 87 + .../postgres_regress/prepared_xacts.test | 605 + .../postgres_regress/privileges.metadata.json | 335 + .../postgres_regress/privileges.test | 2542 +++ .../postgres_regress/psql.metadata.json | 200 + .../postgres_regress/psql.test | 1410 ++ .../psql_crosstab.metadata.json | 12 + .../postgres_regress/psql_crosstab.test | 158 + .../publication.metadata.json | 659 + .../postgres_regress/publication.test | 4537 ++++++ .../postgres_regress/random.metadata.json | 52 + .../postgres_regress/random.test | 610 + .../postgres_regress/rangefuncs.metadata.json | 432 + .../postgres_regress/rangefuncs.test | 3413 ++++ .../postgres_regress/rangetypes.metadata.json | 411 + .../postgres_regress/rangetypes.test | 3616 +++++ .../postgres_regress/regex.metadata.json | 109 + .../postgres_regress/regex.test | 737 + .../postgres_regress/regproc.metadata.json | 109 + .../postgres_regress/regproc.test | 772 + .../reindex_catalog.metadata.json | 24 + .../postgres_regress/reindex_catalog.test | 169 + .../postgres_regress/reloptions.metadata.json | 70 + .../postgres_regress/reloptions.test | 529 + .../replica_identity.metadata.json | 60 + .../postgres_regress/replica_identity.test | 454 + .../postgres_regress/returning.metadata.json | 81 + .../postgres_regress/returning.test | 645 + .../roleattributes.metadata.json | 84 + .../postgres_regress/roleattributes.test | 553 + .../rowsecurity.metadata.json | 779 + .../postgres_regress/rowsecurity.test | 6370 ++++++++ .../postgres_regress/rowtypes.metadata.json | 241 + .../postgres_regress/rowtypes.test | 1898 +++ .../postgres_regress/rules.metadata.json | 624 + .../postgres_regress/rules.test | 5245 +++++++ .../sanity_check.metadata.json | 7 + .../postgres_regress/sanity_check.test | 55 + .../security_label.metadata.json | 32 + .../postgres_regress/security_label.test | 198 + .../postgres_regress/select.metadata.json | 91 + .../postgres_regress/select.test | 811 + .../select_distinct.metadata.json | 80 + .../postgres_regress/select_distinct.test | 639 + .../select_distinct_on.metadata.json | 12 + .../postgres_regress/select_distinct_on.test | 94 + .../select_having.metadata.json | 27 + .../postgres_regress/select_having.test | 212 + .../select_implicit.metadata.json | 48 + .../postgres_regress/select_implicit.test | 472 + .../select_into.metadata.json | 71 + .../postgres_regress/select_into.test | 583 + .../select_parallel.metadata.json | 239 + .../postgres_regress/select_parallel.test | 2010 +++ .../select_views.metadata.json | 56 + .../postgres_regress/select_views.test | 553 + .../postgres_regress/sequence.metadata.json | 264 + .../postgres_regress/sequence.test | 1834 +++ .../postgres_regress/spgist.metadata.json | 35 + .../postgres_regress/spgist.test | 301 + .../postgres_regress/sqljson.metadata.json | 223 + .../postgres_regress/sqljson.test | 1596 ++ .../sqljson_jsontable.metadata.json | 121 + .../postgres_regress/sqljson_jsontable.test | 1143 ++ .../sqljson_queryfuncs.metadata.json | 314 + .../postgres_regress/sqljson_queryfuncs.test | 2075 +++ .../postgres_regress/stats.metadata.json | 451 + .../postgres_regress/stats.test | 3593 +++++ .../postgres_regress/stats_ext.metadata.json | 820 + .../postgres_regress/stats_ext.test | 6196 ++++++++ .../postgres_regress/strings.metadata.json | 5 + .../postgres_regress/strings.test | 869 ++ .../subscription.metadata.json | 163 + .../postgres_regress/subscription.test | 1048 ++ .../postgres_regress/subselect.metadata.json | 273 + .../postgres_regress/subselect.test | 3098 ++++ .../postgres_regress/sysviews.metadata.json | 31 + .../postgres_regress/sysviews.test | 253 + .../tablesample.metadata.json | 60 + .../postgres_regress/tablesample.test | 438 + .../postgres_regress/tablespace.metadata.json | 208 + .../postgres_regress/tablespace.test | 1606 ++ .../postgres_regress/temp.metadata.json | 166 + .../postgres_regress/temp.test | 1188 ++ .../postgres_regress/test_setup.metadata.json | 73 + .../postgres_regress/test_setup.test | 669 + .../postgres_regress/text.metadata.json | 77 + .../postgres_regress/text.test | 547 + .../postgres_regress/tid.metadata.json | 45 + .../postgres_regress/tid.test | 321 + .../tidrangescan.metadata.json | 49 + .../postgres_regress/tidrangescan.test | 402 + .../postgres_regress/tidscan.metadata.json | 53 + .../postgres_regress/tidscan.test | 438 + .../postgres_regress/time.metadata.json | 48 + .../postgres_regress/time.test | 348 + .../postgres_regress/timestamp.metadata.json | 175 + .../postgres_regress/timestamp.test | 1506 ++ .../timestamptz.metadata.json | 386 + .../postgres_regress/timestamptz.test | 2991 ++++ .../postgres_regress/timetz.metadata.json | 61 + .../postgres_regress/timetz.test | 463 + .../transactions.metadata.json | 494 + .../postgres_regress/transactions.test | 3477 +++++ .../postgres_regress/triggers.metadata.json | 1060 ++ .../postgres_regress/triggers.test | 9044 +++++++++++ .../postgres_regress/truncate.metadata.json | 197 + .../postgres_regress/truncate.test | 1497 ++ .../postgres_regress/tsdicts.metadata.json | 135 + .../postgres_regress/tsdicts.test | 994 ++ .../postgres_regress/tsearch.metadata.json | 446 + .../postgres_regress/tsearch.test | 3874 +++++ .../postgres_regress/tsrf.metadata.json | 78 + .../postgres_regress/tsrf.test | 695 + .../postgres_regress/tstypes.metadata.json | 242 + .../postgres_regress/tstypes.test | 1586 ++ .../postgres_regress/tuplesort.metadata.json | 110 + .../postgres_regress/tuplesort.test | 869 ++ .../postgres_regress/txid.metadata.json | 51 + .../postgres_regress/txid.test | 373 + .../type_sanity.metadata.json | 65 + .../postgres_regress/type_sanity.test | 1302 ++ .../typed_table.metadata.json | 32 + .../postgres_regress/typed_table.test | 219 + .../postgres_regress/unicode.metadata.json | 21 + .../postgres_regress/unicode.test | 134 + .../postgres_regress/union.metadata.json | 195 + .../postgres_regress/union.test | 1715 +++ .../updatable_views.metadata.json | 1104 ++ .../postgres_regress/updatable_views.test | 9450 ++++++++++++ .../postgres_regress/update.metadata.json | 261 + .../postgres_regress/update.test | 2192 +++ .../postgres_regress/uuid.metadata.json | 48 + .../postgres_regress/uuid.test | 400 + .../postgres_regress/vacuum.metadata.json | 300 + .../postgres_regress/vacuum.test | 2263 +++ .../vacuum_parallel.metadata.json | 18 + .../postgres_regress/vacuum_parallel.test | 138 + .../postgres_regress/varchar.metadata.json | 26 + .../postgres_regress/varchar.test | 207 + .../postgres_regress/window.metadata.json | 390 + .../postgres_regress/window.test | 4627 ++++++ .../postgres_regress/with.metadata.json | 297 + .../postgres_regress/with.test | 3894 +++++ .../write_parallel.metadata.json | 26 + .../postgres_regress/write_parallel.test | 193 + .../postgres_regress/xid.metadata.json | 88 + .../postgres_regress/xid.test | 638 + .../postgres_regress/xml.metadata.json | 274 + .../postgres_regress/xml.test | 2189 +++ .../postgres_regress/xmlmap.metadata.json | 44 + .../postgres_regress/xmlmap.test | 289 + 1092 files changed, 785171 insertions(+), 14 deletions(-) create mode 100644 cmd/regenerate/extract_summary.go create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_array.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_array.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_cache.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_cache.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_call.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_call.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_control.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_control.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_copy.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_copy.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_domain.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_domain.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_misc.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_misc.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_record.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_record.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_simple.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_simple.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_trap.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_trap.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.test create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.metadata.json create mode 100644 parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.test create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.metadata.json create mode 100644 parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_array.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_array.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_cache.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_cache.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_call.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_call.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_control.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_control.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_copy.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_copy.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_domain.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_domain.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_misc.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_misc.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_record.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_record.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_simple.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_simple.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_trap.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_trap.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.test create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.metadata.json create mode 100644 parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_array.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_array.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_cache.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_cache.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_call.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_call.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_control.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_control.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_copy.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_copy.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_domain.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_domain.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_misc.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_misc.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_record.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_record.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_simple.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_simple.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_transaction.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_transaction.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_trap.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_trap.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_trigger.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_trigger.test create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_varprops.metadata.json create mode 100644 parser/testdata/parse/plpgsql_regress/plpgsql_varprops.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.test create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.test create mode 100644 parser/testdata/plpgsql/plpgsql_samples.metadata.json create mode 100644 parser/testdata/plpgsql/plpgsql_samples.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_array.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_array.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_cache.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_cache.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_call.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_call.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_control.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_control.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_copy.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_copy.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_domain.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_domain.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_misc.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_misc.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_record.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_record.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_simple.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_simple.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_transaction.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_transaction.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_trap.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_trap.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_trigger.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_trigger.test create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_varprops.metadata.json create mode 100644 parser/testdata/scan/plpgsql_regress/plpgsql_varprops.test create mode 100644 parser/testdata/summary/libpg_query.metadata.json create mode 100644 parser/testdata/summary/libpg_query.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_array.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_cache.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_call.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_control.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_copy.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_domain.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_misc.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_record.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_simple.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_transaction.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_trap.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_trigger.test create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json create mode 100644 parser/testdata/summary/plpgsql_regress/plpgsql_varprops.test create mode 100644 parser/testdata/summary/postgres_regress/advisory_lock.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/advisory_lock.test create mode 100644 parser/testdata/summary/postgres_regress/aggregates.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/aggregates.test create mode 100644 parser/testdata/summary/postgres_regress/alter_generic.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/alter_generic.test create mode 100644 parser/testdata/summary/postgres_regress/alter_operator.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/alter_operator.test create mode 100644 parser/testdata/summary/postgres_regress/alter_table.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/alter_table.test create mode 100644 parser/testdata/summary/postgres_regress/amutils.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/amutils.test create mode 100644 parser/testdata/summary/postgres_regress/arrays.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/arrays.test create mode 100644 parser/testdata/summary/postgres_regress/async.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/async.test create mode 100644 parser/testdata/summary/postgres_regress/bit.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/bit.test create mode 100644 parser/testdata/summary/postgres_regress/bitmapops.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/bitmapops.test create mode 100644 parser/testdata/summary/postgres_regress/boolean.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/boolean.test create mode 100644 parser/testdata/summary/postgres_regress/box.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/box.test create mode 100644 parser/testdata/summary/postgres_regress/brin.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/brin.test create mode 100644 parser/testdata/summary/postgres_regress/brin_bloom.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/brin_bloom.test create mode 100644 parser/testdata/summary/postgres_regress/brin_multi.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/brin_multi.test create mode 100644 parser/testdata/summary/postgres_regress/btree_index.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/btree_index.test create mode 100644 parser/testdata/summary/postgres_regress/case.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/case.test create mode 100644 parser/testdata/summary/postgres_regress/char.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/char.test create mode 100644 parser/testdata/summary/postgres_regress/circle.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/circle.test create mode 100644 parser/testdata/summary/postgres_regress/cluster.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/cluster.test create mode 100644 parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/collate.icu.utf8.test create mode 100644 parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/collate.linux.utf8.test create mode 100644 parser/testdata/summary/postgres_regress/collate.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/collate.test create mode 100644 parser/testdata/summary/postgres_regress/collate.utf8.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/collate.utf8.test create mode 100644 parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/collate.windows.win1252.test create mode 100644 parser/testdata/summary/postgres_regress/combocid.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/combocid.test create mode 100644 parser/testdata/summary/postgres_regress/comments.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/comments.test create mode 100644 parser/testdata/summary/postgres_regress/compression.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/compression.test create mode 100644 parser/testdata/summary/postgres_regress/constraints.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/constraints.test create mode 100644 parser/testdata/summary/postgres_regress/conversion.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/conversion.test create mode 100644 parser/testdata/summary/postgres_regress/copy.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/copy.test create mode 100644 parser/testdata/summary/postgres_regress/copy2.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/copy2.test create mode 100644 parser/testdata/summary/postgres_regress/copydml.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/copydml.test create mode 100644 parser/testdata/summary/postgres_regress/copyselect.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/copyselect.test create mode 100644 parser/testdata/summary/postgres_regress/create_aggregate.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_aggregate.test create mode 100644 parser/testdata/summary/postgres_regress/create_am.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_am.test create mode 100644 parser/testdata/summary/postgres_regress/create_cast.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_cast.test create mode 100644 parser/testdata/summary/postgres_regress/create_function_c.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_function_c.test create mode 100644 parser/testdata/summary/postgres_regress/create_function_sql.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_function_sql.test create mode 100644 parser/testdata/summary/postgres_regress/create_index.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_index.test create mode 100644 parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_index_spgist.test create mode 100644 parser/testdata/summary/postgres_regress/create_misc.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_misc.test create mode 100644 parser/testdata/summary/postgres_regress/create_operator.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_operator.test create mode 100644 parser/testdata/summary/postgres_regress/create_procedure.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_procedure.test create mode 100644 parser/testdata/summary/postgres_regress/create_role.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_role.test create mode 100644 parser/testdata/summary/postgres_regress/create_schema.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_schema.test create mode 100644 parser/testdata/summary/postgres_regress/create_table.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_table.test create mode 100644 parser/testdata/summary/postgres_regress/create_table_like.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_table_like.test create mode 100644 parser/testdata/summary/postgres_regress/create_type.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_type.test create mode 100644 parser/testdata/summary/postgres_regress/create_view.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/create_view.test create mode 100644 parser/testdata/summary/postgres_regress/database.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/database.test create mode 100644 parser/testdata/summary/postgres_regress/date.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/date.test create mode 100644 parser/testdata/summary/postgres_regress/dbsize.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/dbsize.test create mode 100644 parser/testdata/summary/postgres_regress/delete.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/delete.test create mode 100644 parser/testdata/summary/postgres_regress/dependency.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/dependency.test create mode 100644 parser/testdata/summary/postgres_regress/domain.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/domain.test create mode 100644 parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/drop_if_exists.test create mode 100644 parser/testdata/summary/postgres_regress/drop_operator.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/drop_operator.test create mode 100644 parser/testdata/summary/postgres_regress/enum.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/enum.test create mode 100644 parser/testdata/summary/postgres_regress/equivclass.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/equivclass.test create mode 100644 parser/testdata/summary/postgres_regress/errors.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/errors.test create mode 100644 parser/testdata/summary/postgres_regress/event_trigger.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/event_trigger.test create mode 100644 parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/event_trigger_login.test create mode 100644 parser/testdata/summary/postgres_regress/explain.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/explain.test create mode 100644 parser/testdata/summary/postgres_regress/expressions.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/expressions.test create mode 100644 parser/testdata/summary/postgres_regress/fast_default.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/fast_default.test create mode 100644 parser/testdata/summary/postgres_regress/float4.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/float4.test create mode 100644 parser/testdata/summary/postgres_regress/float8.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/float8.test create mode 100644 parser/testdata/summary/postgres_regress/foreign_data.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/foreign_data.test create mode 100644 parser/testdata/summary/postgres_regress/foreign_key.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/foreign_key.test create mode 100644 parser/testdata/summary/postgres_regress/functional_deps.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/functional_deps.test create mode 100644 parser/testdata/summary/postgres_regress/generated.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/generated.test create mode 100644 parser/testdata/summary/postgres_regress/geometry.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/geometry.test create mode 100644 parser/testdata/summary/postgres_regress/gin.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/gin.test create mode 100644 parser/testdata/summary/postgres_regress/gist.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/gist.test create mode 100644 parser/testdata/summary/postgres_regress/groupingsets.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/groupingsets.test create mode 100644 parser/testdata/summary/postgres_regress/guc.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/guc.test create mode 100644 parser/testdata/summary/postgres_regress/hash_func.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/hash_func.test create mode 100644 parser/testdata/summary/postgres_regress/hash_index.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/hash_index.test create mode 100644 parser/testdata/summary/postgres_regress/hash_part.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/hash_part.test create mode 100644 parser/testdata/summary/postgres_regress/horology.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/horology.test create mode 100644 parser/testdata/summary/postgres_regress/identity.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/identity.test create mode 100644 parser/testdata/summary/postgres_regress/incremental_sort.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/incremental_sort.test create mode 100644 parser/testdata/summary/postgres_regress/index_including.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/index_including.test create mode 100644 parser/testdata/summary/postgres_regress/index_including_gist.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/index_including_gist.test create mode 100644 parser/testdata/summary/postgres_regress/indexing.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/indexing.test create mode 100644 parser/testdata/summary/postgres_regress/indirect_toast.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/indirect_toast.test create mode 100644 parser/testdata/summary/postgres_regress/inet.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/inet.test create mode 100644 parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/infinite_recurse.test create mode 100644 parser/testdata/summary/postgres_regress/inherit.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/inherit.test create mode 100644 parser/testdata/summary/postgres_regress/init_privs.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/init_privs.test create mode 100644 parser/testdata/summary/postgres_regress/insert.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/insert.test create mode 100644 parser/testdata/summary/postgres_regress/insert_conflict.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/insert_conflict.test create mode 100644 parser/testdata/summary/postgres_regress/int2.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/int2.test create mode 100644 parser/testdata/summary/postgres_regress/int4.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/int4.test create mode 100644 parser/testdata/summary/postgres_regress/int8.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/int8.test create mode 100644 parser/testdata/summary/postgres_regress/interval.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/interval.test create mode 100644 parser/testdata/summary/postgres_regress/join.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/join.test create mode 100644 parser/testdata/summary/postgres_regress/join_hash.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/join_hash.test create mode 100644 parser/testdata/summary/postgres_regress/json.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/json.test create mode 100644 parser/testdata/summary/postgres_regress/json_encoding.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/json_encoding.test create mode 100644 parser/testdata/summary/postgres_regress/jsonb.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/jsonb.test create mode 100644 parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/jsonb_jsonpath.test create mode 100644 parser/testdata/summary/postgres_regress/jsonpath.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/jsonpath.test create mode 100644 parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/jsonpath_encoding.test create mode 100644 parser/testdata/summary/postgres_regress/largeobject.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/largeobject.test create mode 100644 parser/testdata/summary/postgres_regress/limit.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/limit.test create mode 100644 parser/testdata/summary/postgres_regress/line.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/line.test create mode 100644 parser/testdata/summary/postgres_regress/lock.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/lock.test create mode 100644 parser/testdata/summary/postgres_regress/lseg.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/lseg.test create mode 100644 parser/testdata/summary/postgres_regress/macaddr.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/macaddr.test create mode 100644 parser/testdata/summary/postgres_regress/macaddr8.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/macaddr8.test create mode 100644 parser/testdata/summary/postgres_regress/maintain_every.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/maintain_every.test create mode 100644 parser/testdata/summary/postgres_regress/matview.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/matview.test create mode 100644 parser/testdata/summary/postgres_regress/md5.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/md5.test create mode 100644 parser/testdata/summary/postgres_regress/memoize.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/memoize.test create mode 100644 parser/testdata/summary/postgres_regress/merge.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/merge.test create mode 100644 parser/testdata/summary/postgres_regress/misc.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/misc.test create mode 100644 parser/testdata/summary/postgres_regress/misc_functions.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/misc_functions.test create mode 100644 parser/testdata/summary/postgres_regress/misc_sanity.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/misc_sanity.test create mode 100644 parser/testdata/summary/postgres_regress/money.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/money.test create mode 100644 parser/testdata/summary/postgres_regress/multirangetypes.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/multirangetypes.test create mode 100644 parser/testdata/summary/postgres_regress/mvcc.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/mvcc.test create mode 100644 parser/testdata/summary/postgres_regress/name.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/name.test create mode 100644 parser/testdata/summary/postgres_regress/namespace.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/namespace.test create mode 100644 parser/testdata/summary/postgres_regress/numeric.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/numeric.test create mode 100644 parser/testdata/summary/postgres_regress/numeric_big.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/numeric_big.test create mode 100644 parser/testdata/summary/postgres_regress/numerology.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/numerology.test create mode 100644 parser/testdata/summary/postgres_regress/object_address.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/object_address.test create mode 100644 parser/testdata/summary/postgres_regress/oid.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/oid.test create mode 100644 parser/testdata/summary/postgres_regress/oidjoins.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/oidjoins.test create mode 100644 parser/testdata/summary/postgres_regress/opr_sanity.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/opr_sanity.test create mode 100644 parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/partition_aggregate.test create mode 100644 parser/testdata/summary/postgres_regress/partition_info.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/partition_info.test create mode 100644 parser/testdata/summary/postgres_regress/partition_join.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/partition_join.test create mode 100644 parser/testdata/summary/postgres_regress/partition_prune.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/partition_prune.test create mode 100644 parser/testdata/summary/postgres_regress/password.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/password.test create mode 100644 parser/testdata/summary/postgres_regress/path.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/path.test create mode 100644 parser/testdata/summary/postgres_regress/pg_lsn.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/pg_lsn.test create mode 100644 parser/testdata/summary/postgres_regress/plancache.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/plancache.test create mode 100644 parser/testdata/summary/postgres_regress/plpgsql.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/plpgsql.test create mode 100644 parser/testdata/summary/postgres_regress/point.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/point.test create mode 100644 parser/testdata/summary/postgres_regress/polygon.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/polygon.test create mode 100644 parser/testdata/summary/postgres_regress/polymorphism.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/polymorphism.test create mode 100644 parser/testdata/summary/postgres_regress/portals.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/portals.test create mode 100644 parser/testdata/summary/postgres_regress/portals_p2.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/portals_p2.test create mode 100644 parser/testdata/summary/postgres_regress/predicate.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/predicate.test create mode 100644 parser/testdata/summary/postgres_regress/prepare.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/prepare.test create mode 100644 parser/testdata/summary/postgres_regress/prepared_xacts.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/prepared_xacts.test create mode 100644 parser/testdata/summary/postgres_regress/privileges.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/privileges.test create mode 100644 parser/testdata/summary/postgres_regress/psql.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/psql.test create mode 100644 parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/psql_crosstab.test create mode 100644 parser/testdata/summary/postgres_regress/publication.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/publication.test create mode 100644 parser/testdata/summary/postgres_regress/random.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/random.test create mode 100644 parser/testdata/summary/postgres_regress/rangefuncs.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/rangefuncs.test create mode 100644 parser/testdata/summary/postgres_regress/rangetypes.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/rangetypes.test create mode 100644 parser/testdata/summary/postgres_regress/regex.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/regex.test create mode 100644 parser/testdata/summary/postgres_regress/regproc.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/regproc.test create mode 100644 parser/testdata/summary/postgres_regress/reindex_catalog.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/reindex_catalog.test create mode 100644 parser/testdata/summary/postgres_regress/reloptions.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/reloptions.test create mode 100644 parser/testdata/summary/postgres_regress/replica_identity.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/replica_identity.test create mode 100644 parser/testdata/summary/postgres_regress/returning.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/returning.test create mode 100644 parser/testdata/summary/postgres_regress/roleattributes.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/roleattributes.test create mode 100644 parser/testdata/summary/postgres_regress/rowsecurity.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/rowsecurity.test create mode 100644 parser/testdata/summary/postgres_regress/rowtypes.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/rowtypes.test create mode 100644 parser/testdata/summary/postgres_regress/rules.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/rules.test create mode 100644 parser/testdata/summary/postgres_regress/sanity_check.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/sanity_check.test create mode 100644 parser/testdata/summary/postgres_regress/security_label.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/security_label.test create mode 100644 parser/testdata/summary/postgres_regress/select.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select.test create mode 100644 parser/testdata/summary/postgres_regress/select_distinct.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select_distinct.test create mode 100644 parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select_distinct_on.test create mode 100644 parser/testdata/summary/postgres_regress/select_having.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select_having.test create mode 100644 parser/testdata/summary/postgres_regress/select_implicit.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select_implicit.test create mode 100644 parser/testdata/summary/postgres_regress/select_into.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select_into.test create mode 100644 parser/testdata/summary/postgres_regress/select_parallel.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select_parallel.test create mode 100644 parser/testdata/summary/postgres_regress/select_views.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/select_views.test create mode 100644 parser/testdata/summary/postgres_regress/sequence.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/sequence.test create mode 100644 parser/testdata/summary/postgres_regress/spgist.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/spgist.test create mode 100644 parser/testdata/summary/postgres_regress/sqljson.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/sqljson.test create mode 100644 parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/sqljson_jsontable.test create mode 100644 parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/sqljson_queryfuncs.test create mode 100644 parser/testdata/summary/postgres_regress/stats.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/stats.test create mode 100644 parser/testdata/summary/postgres_regress/stats_ext.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/stats_ext.test create mode 100644 parser/testdata/summary/postgres_regress/strings.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/strings.test create mode 100644 parser/testdata/summary/postgres_regress/subscription.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/subscription.test create mode 100644 parser/testdata/summary/postgres_regress/subselect.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/subselect.test create mode 100644 parser/testdata/summary/postgres_regress/sysviews.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/sysviews.test create mode 100644 parser/testdata/summary/postgres_regress/tablesample.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tablesample.test create mode 100644 parser/testdata/summary/postgres_regress/tablespace.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tablespace.test create mode 100644 parser/testdata/summary/postgres_regress/temp.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/temp.test create mode 100644 parser/testdata/summary/postgres_regress/test_setup.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/test_setup.test create mode 100644 parser/testdata/summary/postgres_regress/text.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/text.test create mode 100644 parser/testdata/summary/postgres_regress/tid.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tid.test create mode 100644 parser/testdata/summary/postgres_regress/tidrangescan.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tidrangescan.test create mode 100644 parser/testdata/summary/postgres_regress/tidscan.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tidscan.test create mode 100644 parser/testdata/summary/postgres_regress/time.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/time.test create mode 100644 parser/testdata/summary/postgres_regress/timestamp.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/timestamp.test create mode 100644 parser/testdata/summary/postgres_regress/timestamptz.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/timestamptz.test create mode 100644 parser/testdata/summary/postgres_regress/timetz.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/timetz.test create mode 100644 parser/testdata/summary/postgres_regress/transactions.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/transactions.test create mode 100644 parser/testdata/summary/postgres_regress/triggers.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/triggers.test create mode 100644 parser/testdata/summary/postgres_regress/truncate.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/truncate.test create mode 100644 parser/testdata/summary/postgres_regress/tsdicts.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tsdicts.test create mode 100644 parser/testdata/summary/postgres_regress/tsearch.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tsearch.test create mode 100644 parser/testdata/summary/postgres_regress/tsrf.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tsrf.test create mode 100644 parser/testdata/summary/postgres_regress/tstypes.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tstypes.test create mode 100644 parser/testdata/summary/postgres_regress/tuplesort.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/tuplesort.test create mode 100644 parser/testdata/summary/postgres_regress/txid.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/txid.test create mode 100644 parser/testdata/summary/postgres_regress/type_sanity.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/type_sanity.test create mode 100644 parser/testdata/summary/postgres_regress/typed_table.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/typed_table.test create mode 100644 parser/testdata/summary/postgres_regress/unicode.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/unicode.test create mode 100644 parser/testdata/summary/postgres_regress/union.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/union.test create mode 100644 parser/testdata/summary/postgres_regress/updatable_views.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/updatable_views.test create mode 100644 parser/testdata/summary/postgres_regress/update.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/update.test create mode 100644 parser/testdata/summary/postgres_regress/uuid.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/uuid.test create mode 100644 parser/testdata/summary/postgres_regress/vacuum.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/vacuum.test create mode 100644 parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/vacuum_parallel.test create mode 100644 parser/testdata/summary/postgres_regress/varchar.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/varchar.test create mode 100644 parser/testdata/summary/postgres_regress/window.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/window.test create mode 100644 parser/testdata/summary/postgres_regress/with.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/with.test create mode 100644 parser/testdata/summary/postgres_regress/write_parallel.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/write_parallel.test create mode 100644 parser/testdata/summary/postgres_regress/xid.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/xid.test create mode 100644 parser/testdata/summary/postgres_regress/xml.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/xml.test create mode 100644 parser/testdata/summary/postgres_regress/xmlmap.metadata.json create mode 100644 parser/testdata/summary/postgres_regress/xmlmap.test create mode 100644 parser/testdata/summary_truncate/libpg_query.metadata.json create mode 100644 parser/testdata/summary_truncate/libpg_query.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/advisory_lock.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/aggregates.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/alter_generic.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/alter_operator.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/alter_table.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/amutils.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/arrays.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/async.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/async.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/bit.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/bit.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/bitmapops.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/boolean.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/box.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/box.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/brin.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/brin.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/brin_bloom.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/brin_multi.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/btree_index.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/case.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/case.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/char.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/char.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/circle.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/circle.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/cluster.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.utf8.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/combocid.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/comments.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/comments.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/compression.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/compression.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/constraints.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/conversion.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/copy.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/copy.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/copy2.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/copydml.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/copyselect.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_aggregate.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_am.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_cast.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_function_c.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_function_sql.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_index.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_index_spgist.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_misc.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_operator.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_procedure.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_role.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_schema.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_table.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_table_like.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_type.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/create_view.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/database.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/database.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/date.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/date.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/dbsize.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/delete.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/delete.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/dependency.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/domain.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/domain.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/drop_if_exists.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/drop_operator.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/enum.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/enum.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/equivclass.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/errors.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/errors.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/event_trigger.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/event_trigger_login.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/explain.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/explain.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/expressions.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/fast_default.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/float4.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/float4.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/float8.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/float8.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/foreign_data.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/foreign_key.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/functional_deps.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/generated.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/generated.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/geometry.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/gin.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/gin.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/gist.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/gist.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/groupingsets.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/guc.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/guc.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/hash_func.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/hash_index.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/hash_part.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/horology.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/horology.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/identity.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/identity.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/incremental_sort.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/index_including.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/index_including_gist.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/indexing.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/indirect_toast.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/inet.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/inet.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/infinite_recurse.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/inherit.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/init_privs.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/insert.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/insert.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/insert_conflict.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/int2.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/int2.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/int4.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/int4.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/int8.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/int8.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/interval.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/interval.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/join.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/join.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/join_hash.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/json.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/json.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/json_encoding.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonb.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonpath.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/largeobject.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/limit.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/limit.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/line.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/line.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/lock.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/lock.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/lseg.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/macaddr.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/macaddr8.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/maintain_every.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/matview.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/matview.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/md5.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/md5.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/memoize.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/merge.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/merge.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/misc.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/misc.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/misc_functions.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/misc_sanity.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/money.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/money.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/multirangetypes.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/mvcc.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/name.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/name.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/namespace.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/numeric.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/numeric_big.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/numerology.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/object_address.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/oid.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/oid.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/oidjoins.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/opr_sanity.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_aggregate.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_info.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_join.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/partition_prune.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/password.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/password.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/path.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/path.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/pg_lsn.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/plancache.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/plpgsql.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/point.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/point.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/polygon.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/polymorphism.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/portals.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/portals.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/portals_p2.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/predicate.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/prepare.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/prepared_xacts.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/privileges.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/psql.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/psql.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/psql_crosstab.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/publication.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/publication.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/random.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/random.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/rangefuncs.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/rangetypes.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/regex.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/regex.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/regproc.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/regproc.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/reindex_catalog.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/reindex_catalog.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/reloptions.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/reloptions.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/replica_identity.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/returning.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/returning.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/roleattributes.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/rowsecurity.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/rowtypes.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/rules.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/rules.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/sanity_check.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/security_label.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_distinct.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_distinct_on.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_having.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_implicit.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_into.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_parallel.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/select_views.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/sequence.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/spgist.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/sqljson.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/stats.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/stats.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/stats_ext.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/strings.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/strings.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/subscription.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/subselect.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/sysviews.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tablesample.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tablespace.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/temp.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/temp.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/test_setup.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/text.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/text.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tid.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tid.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tidrangescan.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tidscan.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/time.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/time.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/timestamp.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/timestamptz.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/timetz.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/transactions.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/triggers.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/truncate.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tsdicts.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tsearch.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tsrf.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tstypes.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/tuplesort.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/txid.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/txid.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/type_sanity.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/typed_table.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/unicode.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/union.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/union.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/updatable_views.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/update.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/update.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/uuid.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/vacuum.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/varchar.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/window.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/window.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/with.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/with.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/write_parallel.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/xid.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/xid.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/xml.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/xml.test create mode 100644 parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json create mode 100644 parser/testdata/summary_truncate/postgres_regress/xmlmap.test diff --git a/cmd/difftodo/main.go b/cmd/difftodo/main.go index 80f567b..1708e16 100644 --- a/cmd/difftodo/main.go +++ b/cmd/difftodo/main.go @@ -23,7 +23,8 @@ func main() { } suite := "parse" for _, s := range []string{"parse", "scan", "normalize", "normalize_utility", - "fingerprint", "deparse", "split_scanner", "split_parser"} { + "fingerprint", "deparse", "split_scanner", "split_parser", + "summary", "summary_truncate", "plpgsql"} { if strings.Contains(path, "/"+s+"/") { suite = s } @@ -76,6 +77,42 @@ func evaluate(suite, input string) string { if err == nil { out, err = pg_query.Deparse(tree) } + case "summary", "summary_truncate": + limit, sql := -1, input + if suite == "summary_truncate" { + limit, sql, err = testfile.SplitTruncateLimit(input) + if err != nil { + return "BAD CASE: " + err.Error() + } + } + var res *pg_query.SummaryResult + res, err = pg_query.Summary(sql, limit) + if err == nil { + e := testfile.SummaryExpectation{ + Aliases: res.Aliases, + CteNames: res.CteNames, + StatementTypes: res.StatementTypes, + TruncatedQuery: res.TruncatedQuery, + } + for _, t := range res.Tables { + e.Tables = append(e.Tables, testfile.SummaryTable{ + Name: t.Name, SchemaName: t.SchemaName, TableName: t.TableName, Context: t.Context.String(), + }) + } + for _, f := range res.Functions { + e.Functions = append(e.Functions, testfile.SummaryFunction{ + Name: f.Name, FunctionName: f.FunctionName, SchemaName: f.SchemaName, Context: f.Context.String(), + }) + } + for _, f := range res.FilterColumns { + e.FilterColumns = append(e.FilterColumns, testfile.SummaryFilterColumn{ + SchemaName: f.SchemaName, TableName: f.TableName, Column: f.Column, + }) + } + out = testfile.RenderSummary(e) + } + case "plpgsql": + out, err = pg_query.ParsePlPgSqlToJSON(input) default: panic("difftodo: unsupported suite " + suite) } diff --git a/cmd/regenerate/extract_summary.go b/cmd/regenerate/extract_summary.go new file mode 100644 index 0000000..a84ed00 --- /dev/null +++ b/cmd/regenerate/extract_summary.go @@ -0,0 +1,80 @@ +package main + +import ( + "regexp" + "strconv" + "strings" +) + +// --- summary test-call extraction -------------------------------------------- +// +// libpg_query's summary tests (test/summary_tests.c, test/summary_truncate.c) +// are not tests[] tables: each test body calls summary("...", 0, limit) or +// summary(query, 0, limit) after a `char *query = "...";` assignment. The +// INPUTS (query text + truncation limit) are transcribed mechanically here; +// the EXPECTATIONS always come from the live oracle, never from the C +// asserts, so a pattern drift can only lose cases (visible in review), not +// corrupt goldens. + +type summaryCall struct { + SQL string + Limit int +} + +var ( + // `char *query = "...";` (or `char* sql = "..."`): the identifier and its + // string literal, which summary(, ...) calls resolve against. + summaryAssignRe = regexp.MustCompile(`\*\s*(\w+)\s*=\s*("(?:[^"\\]|\\.)*")`) + // summary("...", 0, -1) / summary_internal(query, 0, 40): first argument + // is a string literal or an identifier; second is parser_options; third + // is the truncation limit. + summaryCallRe = regexp.MustCompile(`\bsummary(?:_internal)?\s*\(\s*(?:("(?:[^"\\]|\\.)*")|(\w+))\s*,\s*(-?\d+)\s*,\s*(-?\d+)\s*\)`) +) + +// extractSummaryCalls returns the (query, limit) pairs of every summary()/ +// summary_internal() call with parser_options 0 whose query is a string +// literal or resolvable single-assignment identifier. C line splices +// (backslash-newline, translation phase 2) are removed up front, exactly as +// the C compiler does before tokenization. +func extractSummaryCalls(src string) ([]summaryCall, error) { + src = strings.ReplaceAll(src, "\\\n", "") + + assigns := summaryAssignRe.FindAllStringSubmatchIndex(src, -1) + calls := summaryCallRe.FindAllStringSubmatchIndex(src, -1) + + var out []summaryCall + for _, m := range calls { + var lit string + switch { + case m[2] >= 0: // literal first argument + lit = src[m[2]:m[3]] + case m[4] >= 0: // identifier: latest preceding assignment wins + ident := src[m[4]:m[5]] + for _, a := range assigns { + if a[0] > m[0] { + break + } + if src[a[2]:a[3]] == ident { + lit = src[a[4]:a[5]] + } + } + if lit == "" { + continue // unresolvable identifier: lose the case, visibly + } + } + opts := src[m[6]:m[7]] + if opts != "0" { + continue // oracle always calls with parser_options 0 + } + limit, err := strconv.Atoi(src[m[8]:m[9]]) + if err != nil { + return nil, err + } + sql, _, err := readCStringLiteral(lit) + if err != nil { + return nil, err + } + out = append(out, summaryCall{SQL: sql, Limit: limit}) + } + return out, nil +} diff --git a/cmd/regenerate/main.go b/cmd/regenerate/main.go index 5272ab4..7cc1225 100644 --- a/cmd/regenerate/main.go +++ b/cmd/regenerate/main.go @@ -49,7 +49,10 @@ func main() { check(err) defer oracle.Close() - // Tier: PostgreSQL regression suite. + // Tier: PostgreSQL regression suite. The summary suite runs untruncated; + // summary_truncate re-runs every statement at limit 100 (the limit rides + // along as a directive line in the case input) to exercise the + // deparse-driven truncation machinery across the whole corpus. regressDir := filepath.Join(*libpgQuery, "test", "sql", "postgres_regress") regressFiles := sqlFiles(regressDir) fmt.Fprintf(os.Stderr, "regenerate: postgres_regress: %d files\n", len(regressFiles)) @@ -59,9 +62,34 @@ func main() { stmts := splitStatements(oracle, preprocessRegress(string(src))) base := strings.TrimSuffix(f, ".sql") emitSQLSuites(oracle, *out, "postgres_regress", base, stmts, - []string{"parse", "scan", "normalize", "fingerprint", "deparse"}) + []string{"parse", "scan", "normalize", "fingerprint", "deparse", "summary"}) + emitSQLSuites(oracle, *out, "postgres_regress", base, withTruncateLimit(stmts, 100), + []string{"summary_truncate"}) } + // Tier: PL/pgSQL regression suite (test/sql/plpgsql_regress). The plpgsql + // suite is the milestone-11 gate; the standard SQL suites run over the + // same statements since CREATE FUNCTION bodies are plain SQL to them. + plpgsqlDir := filepath.Join(*libpgQuery, "test", "sql", "plpgsql_regress") + plpgsqlFiles := sqlFiles(plpgsqlDir) + fmt.Fprintf(os.Stderr, "regenerate: plpgsql_regress: %d files\n", len(plpgsqlFiles)) + for _, f := range plpgsqlFiles { + src, err := os.ReadFile(filepath.Join(plpgsqlDir, f)) + check(err) + stmts := splitStatements(oracle, preprocessRegress(string(src))) + base := strings.TrimSuffix(f, ".sql") + emitSQLSuites(oracle, *out, "plpgsql_regress", base, stmts, + []string{"parse", "scan", "normalize", "fingerprint", "deparse", "summary", "plpgsql"}) + } + + // Tier: libpg_query's PL/pgSQL samples (test/plpgsql_samples.sql, the + // upstream acceptance corpus for pg_query_parse_plpgsql). + samplesSrc, err := os.ReadFile(filepath.Join(*libpgQuery, "test", "plpgsql_samples.sql")) + check(err) + samples := splitStatements(oracle, string(samplesSrc)) + fmt.Fprintf(os.Stderr, "regenerate: plpgsql_samples.sql: %d statements\n", len(samples)) + emitSQLSuites(oracle, *out, "", "plpgsql_samples", samples, []string{"plpgsql"}) + // Tier: deparser roundtrip corpora. deparse/ is flat .sql files; // deparse-depesz/ is .d/ directories of .psql files. deparseDir := filepath.Join(*libpgQuery, "test", "sql", "deparse") @@ -134,6 +162,35 @@ func main() { emitSQLSuites(oracle, *out, "", "libpg_query", inputs, tbl.suites) } + // Tier: libpg_query summary test calls (test/summary_tests.c, + // test/summary_truncate.c — call sites, not tests[] tables; see + // extract_summary.go). Untruncated calls feed the summary suite; + // truncating calls keep their exact upstream limits. + var summaryInputs, truncateInputs []string + for _, file := range []string{"summary_tests.c", "summary_truncate.c"} { + src, err := os.ReadFile(filepath.Join(*libpgQuery, "test", file)) + check(err) + calls, err := extractSummaryCalls(string(src)) + if err != nil { + check(fmt.Errorf("%s: %w", file, err)) + } + fmt.Fprintf(os.Stderr, "regenerate: %s: %d calls\n", file, len(calls)) + for _, c := range calls { + if c.Limit == -1 { + summaryInputs = append(summaryInputs, c.SQL) + } else { + truncateInputs = append(truncateInputs, testfile.WithTruncateLimit(c.Limit, c.SQL)) + } + } + } + // Every untruncated summary input also runs at limit 50, so the inline + // tier exercises truncation beyond the handful of upstream limits. + for _, sql := range summaryInputs { + truncateInputs = append(truncateInputs, testfile.WithTruncateLimit(50, sql)) + } + emitSQLSuites(oracle, *out, "", "libpg_query", summaryInputs, []string{"summary"}) + emitSQLSuites(oracle, *out, "", "libpg_query", truncateInputs, []string{"summary_truncate"}) + // Tier: pg_query_go fingerprint corpus (incl. the 1.1 MB stress insert). var fpCases []struct { Input string `json:"input"` @@ -281,10 +338,66 @@ func goldenFor(oracle *Oracle, suite, sql string) string { return renderOracleError(oerr) } return testfile.RenderSplit(stmts) + case "summary": + sum, oerr, err := oracle.Summary(sql, -1) + check(err) + if oerr != nil { + return renderOracleError(oerr) + } + return renderOracleSummary(sum) + case "summary_truncate": + limit, raw, err := testfile.SplitTruncateLimit(sql) + check(err) + sum, oerr, err := oracle.Summary(raw, limit) + check(err) + if oerr != nil { + return renderOracleError(oerr) + } + return renderOracleSummary(sum) + case "plpgsql": + text, oerr, err := oracle.Text("parse_plpgsql", sql) + check(err) + if oerr != nil { + return renderOracleError(oerr) + } + return text } panic("unknown suite " + suite) } +func withTruncateLimit(stmts []string, limit int) []string { + out := make([]string, len(stmts)) + for i, s := range stmts { + out[i] = testfile.WithTruncateLimit(limit, s) + } + return out +} + +func renderOracleSummary(s *oracleSummary) string { + e := testfile.SummaryExpectation{ + Aliases: s.Aliases, + CteNames: s.CteNames, + StatementTypes: s.StatementTypes, + TruncatedQuery: s.TruncatedQuery, + } + for _, t := range s.Tables { + e.Tables = append(e.Tables, testfile.SummaryTable{ + Name: t.Name, SchemaName: t.SchemaName, TableName: t.TableName, Context: t.Context, + }) + } + for _, f := range s.Functions { + e.Functions = append(e.Functions, testfile.SummaryFunction{ + Name: f.Name, FunctionName: f.FunctionName, SchemaName: f.SchemaName, Context: f.Context, + }) + } + for _, f := range s.FilterColumns { + e.FilterColumns = append(e.FilterColumns, testfile.SummaryFilterColumn{ + SchemaName: f.SchemaName, TableName: f.TableName, Column: f.Column, + }) + } + return testfile.RenderSummary(e) +} + func renderOracleError(e *oracleError) string { return testfile.RenderError(testfile.ErrorExpectation{ Message: e.Message, diff --git a/cmd/regenerate/oracle.go b/cmd/regenerate/oracle.go index 81e1b35..25c9111 100644 --- a/cmd/regenerate/oracle.go +++ b/cmd/regenerate/oracle.go @@ -19,9 +19,10 @@ type Oracle struct { } type oracleReq struct { - Op string `json:"op"` - SQL string `json:"sql"` - TrimSpace bool `json:"trim_space,omitempty"` + Op string `json:"op"` + SQL string `json:"sql"` + TrimSpace bool `json:"trim_space,omitempty"` + TruncateLimit *int `json:"truncate_limit,omitempty"` } type oracleError struct { @@ -40,10 +41,41 @@ type oracleToken struct { } type oracleRes struct { - Text *string `json:"text"` - Stmts []string `json:"stmts"` - Tokens []oracleToken `json:"tokens"` - Err *oracleError `json:"error"` + Text *string `json:"text"` + Stmts []string `json:"stmts"` + Tokens []oracleToken `json:"tokens"` + Summary *oracleSummary `json:"summary"` + Err *oracleError `json:"error"` +} + +type oracleSummaryTable struct { + Name string `json:"name"` + SchemaName string `json:"schema_name"` + TableName string `json:"table_name"` + Context string `json:"context"` +} + +type oracleSummaryFunction struct { + Name string `json:"name"` + FunctionName string `json:"function_name"` + SchemaName string `json:"schema_name"` + Context string `json:"context"` +} + +type oracleSummaryFilterColumn struct { + SchemaName string `json:"schema_name"` + TableName string `json:"table_name"` + Column string `json:"column"` +} + +type oracleSummary struct { + Tables []oracleSummaryTable `json:"tables"` + Aliases map[string]string `json:"aliases"` + CteNames []string `json:"cte_names"` + Functions []oracleSummaryFunction `json:"functions"` + FilterColumns []oracleSummaryFilterColumn `json:"filter_columns"` + StatementTypes []string `json:"statement_types"` + TruncatedQuery string `json:"truncated_query"` } // StartOracle builds (if needed) and starts the oracle binary. bin may name a @@ -123,6 +155,22 @@ func (o *Oracle) Scan(sql string) ([]oracleToken, *oracleError, error) { return res.Tokens, res.Err, nil } +// Summary runs the summary op at the given truncation limit (-1 disables +// truncation, matching pg_query.Summary). +func (o *Oracle) Summary(sql string, truncateLimit int) (*oracleSummary, *oracleError, error) { + res, err := o.call(oracleReq{Op: "summary", SQL: sql, TruncateLimit: &truncateLimit}) + if err != nil { + return nil, nil, err + } + if res.Err != nil { + return nil, res.Err, nil + } + if res.Summary == nil { + return nil, nil, fmt.Errorf("oracle op summary returned neither summary nor error") + } + return res.Summary, nil, nil +} + func (o *Oracle) Split(op, sql string, trimSpace bool) ([]string, *oracleError, error) { res, err := o.call(oracleReq{Op: op, SQL: sql, TrimSpace: trimSpace}) if err != nil { diff --git a/internal/testfile/golden.go b/internal/testfile/golden.go index 80ffc58..60abacc 100644 --- a/internal/testfile/golden.go +++ b/internal/testfile/golden.go @@ -2,6 +2,7 @@ package testfile import ( "fmt" + "sort" "strconv" "strings" ) @@ -106,3 +107,114 @@ func RenderSplit(stmts []string) string { } return strings.Join(lines, "\n") } + +// --- summary goldens --------------------------------------------------------- + +// SummaryTable / SummaryFunction / SummaryFilterColumn / SummaryExpectation +// mirror the SummaryResult protobuf field-for-field, with Context enums as +// their protobuf value names ("None", "Select", "DML", "DDL", "Call"). +type SummaryTable struct { + Name string + SchemaName string + TableName string + Context string +} + +type SummaryFunction struct { + Name string + FunctionName string + SchemaName string + Context string +} + +type SummaryFilterColumn struct { + SchemaName string + TableName string + Column string +} + +type SummaryExpectation struct { + Tables []SummaryTable + Aliases map[string]string + CteNames []string + Functions []SummaryFunction + FilterColumns []SummaryFilterColumn + StatementTypes []string + TruncatedQuery string +} + +// RenderSummary encodes a SummaryResult golden, one entry per line. Repeated +// fields keep their protobuf order; aliases (a protobuf map, unordered by +// definition) are sorted by key. The empty summary renders as "". +// +// TABLE: name="public.x" schema="public" table="x" ctx=DDL +// ALIAS: "a"="b" +// CTE: "cte" +// FUNCTION: name="pg_catalog.substr" function="substr" schema="pg_catalog" ctx=Call +// FILTER: schema="" table="t" column="c" +// STMT: SelectStmt +// TRUNCATED: "SELECT ..." +func RenderSummary(s SummaryExpectation) string { + var lines []string + for _, t := range s.Tables { + lines = append(lines, fmt.Sprintf("TABLE: name=%q schema=%q table=%q ctx=%s", + t.Name, t.SchemaName, t.TableName, t.Context)) + } + keys := make([]string, 0, len(s.Aliases)) + for k := range s.Aliases { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + lines = append(lines, fmt.Sprintf("ALIAS: %q=%q", k, s.Aliases[k])) + } + for _, c := range s.CteNames { + lines = append(lines, fmt.Sprintf("CTE: %q", c)) + } + for _, f := range s.Functions { + lines = append(lines, fmt.Sprintf("FUNCTION: name=%q function=%q schema=%q ctx=%s", + f.Name, f.FunctionName, f.SchemaName, f.Context)) + } + for _, f := range s.FilterColumns { + lines = append(lines, fmt.Sprintf("FILTER: schema=%q table=%q column=%q", + f.SchemaName, f.TableName, f.Column)) + } + for _, t := range s.StatementTypes { + lines = append(lines, "STMT: "+t) + } + if s.TruncatedQuery != "" { + lines = append(lines, fmt.Sprintf("TRUNCATED: %q", s.TruncatedQuery)) + } + return strings.Join(lines, "\n") +} + +// --- summary_truncate case inputs -------------------------------------------- + +// The summary_truncate suite carries the truncation limit as a leading +// comment line in the case input; both cmd/regenerate and the corpus harness +// strip it before calling Summary, so the SQL the oracle and oliphant see is +// byte-identical to the raw statement. +const TruncateLimitPrefix = "-- truncate_limit: " + +// WithTruncateLimit prepends the truncation-limit directive to a statement. +func WithTruncateLimit(limit int, sql string) string { + return fmt.Sprintf("%s%d\n%s", TruncateLimitPrefix, limit, sql) +} + +// SplitTruncateLimit strips the truncation-limit directive from a +// summary_truncate case input. +func SplitTruncateLimit(input string) (limit int, sql string, err error) { + if !strings.HasPrefix(input, TruncateLimitPrefix) { + return 0, "", fmt.Errorf("summary_truncate input missing %q directive", TruncateLimitPrefix) + } + rest := input[len(TruncateLimitPrefix):] + line, sql, ok := strings.Cut(rest, "\n") + if !ok { + return 0, "", fmt.Errorf("summary_truncate input is only a directive line") + } + limit, err = strconv.Atoi(line) + if err != nil { + return 0, "", fmt.Errorf("bad truncate_limit %q: %w", line, err) + } + return limit, sql, nil +} diff --git a/oracle/main.go b/oracle/main.go index 0dc4711..cc83e9a 100644 --- a/oracle/main.go +++ b/oracle/main.go @@ -25,6 +25,9 @@ type req struct { Op string `json:"op"` SQL string `json:"sql"` TrimSpace bool `json:"trim_space,omitempty"` + // TruncateLimit is the summary op's truncation limit; nil means -1 + // (no truncation), matching pg_query.Summary's convention. + TruncateLimit *int `json:"truncate_limit,omitempty"` } type oracleError struct { @@ -43,10 +46,43 @@ type token struct { } type res struct { - Text *string `json:"text,omitempty"` - Stmts []string `json:"stmts,omitempty"` - Tokens []token `json:"tokens,omitempty"` - Err *oracleError `json:"error,omitempty"` + Text *string `json:"text,omitempty"` + Stmts []string `json:"stmts,omitempty"` + Tokens []token `json:"tokens,omitempty"` + Summary *summaryRes `json:"summary,omitempty"` + Err *oracleError `json:"error,omitempty"` +} + +// summaryRes mirrors SummaryResult field-for-field, with Context enums +// rendered as their protobuf value names. +type summaryTable struct { + Name string `json:"name"` + SchemaName string `json:"schema_name"` + TableName string `json:"table_name"` + Context string `json:"context"` +} + +type summaryFunction struct { + Name string `json:"name"` + FunctionName string `json:"function_name"` + SchemaName string `json:"schema_name"` + Context string `json:"context"` +} + +type summaryFilterColumn struct { + SchemaName string `json:"schema_name"` + TableName string `json:"table_name"` + Column string `json:"column"` +} + +type summaryRes struct { + Tables []summaryTable `json:"tables"` + Aliases map[string]string `json:"aliases"` + CteNames []string `json:"cte_names"` + Functions []summaryFunction `json:"functions"` + FilterColumns []summaryFilterColumn `json:"filter_columns"` + StatementTypes []string `json:"statement_types"` + TruncatedQuery string `json:"truncated_query"` } func main() { @@ -131,6 +167,51 @@ func handle(r req) res { return errRes(err) } return res{Stmts: emptyNotNil(stmts)} + case "summary": + limit := -1 + if r.TruncateLimit != nil { + limit = *r.TruncateLimit + } + sr, err := pg_query.Summary(r.SQL, limit) + if err != nil { + return errRes(err) + } + out := &summaryRes{ + Aliases: sr.Aliases, + CteNames: sr.CteNames, + StatementTypes: sr.StatementTypes, + TruncatedQuery: sr.TruncatedQuery, + } + for _, t := range sr.Tables { + out.Tables = append(out.Tables, summaryTable{ + Name: t.Name, + SchemaName: t.SchemaName, + TableName: t.TableName, + Context: t.Context.String(), + }) + } + for _, f := range sr.Functions { + out.Functions = append(out.Functions, summaryFunction{ + Name: f.Name, + FunctionName: f.FunctionName, + SchemaName: f.SchemaName, + Context: f.Context.String(), + }) + } + for _, f := range sr.FilterColumns { + out.FilterColumns = append(out.FilterColumns, summaryFilterColumn{ + SchemaName: f.SchemaName, + TableName: f.TableName, + Column: f.Column, + }) + } + return res{Summary: out} + case "parse_plpgsql": + out, err := pg_query.ParsePlPgSqlToJSON(r.SQL) + if err != nil { + return errRes(err) + } + return res{Text: &out} default: return res{Err: &oracleError{Message: "unknown op " + r.Op}} } diff --git a/oracle/oracle b/oracle/oracle index 19b19c10d18e76f80285859add157058cbbe24b3..f3c374e06ff9d20f5fc64eb7462716d9a65c9a55 100755 GIT binary patch delta 6147800 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

iBVq*7-uet}h4V{~oE@$|;kRdmps2V1_f10#Zx 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

yobUom2AbUv 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

d?B`kJ~}vK~<%?a(_E*Io5Br0#@=Rt+?F{EDuZ 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

p`Nxdb_}}rHoLSORmShX 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�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

Uo}e>ZzxytE*~? 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

gfv2zs(Zk7^GuF6A)w^-Fd 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 >Y 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
0FJj=A;3kW^lvF|lu=b<9d8?D)3B08 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�WbH;4pZth$zp1qhkWUsU$YUUdB!IA<7u$h-Y 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

;qo+2aQh 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೚LlsS|S+`}yW2qk_kiP|IaXVt9(97Vk{0&xQq$rUH~YfrQ>o zufsO%YMV<&rA{!RhR8Y;A_t0`G{Rl37c(6b*nmq$Mb0Qfotm$!e*%&&b=9!QQB_cH zND{>zy&4&4@s*d1${X)ly7h7*%#}nNu5YQLrQ4CSIZe^os&GYH-U1D-sTvftyrr_$ zZblNf#OY5cLjVm7Vr=|-KK(G5#(un68Bi`_Szu+sx8&1+* zig)v{h;B+YF}!ZX_%&}uSs@t1$rU~0;(C7KJ$~YQjyh=5f4Ia59sD&tJSaMvrRvz; zHbi7t>emJ{13#^183enHaW1hHUl!4Z8~?&jZu!4E!|3c!M;u!7OV z2ES&>iM^6S;}TO-3eqhzi69(%d=24T*Nf6aoeU}H)+#4 zNQo|%&!HKpZBWA|oe*Zq2McM~x_M)Sne)MdI)2`;U1(TP6NFpx!GoKJhBj~AjCdHR z-`SR&*ghgo`vi%jYota*_H3P)k`x!4+9)E0BV`sbe?SV2kBEyib{haUij5H;SkcET ztJ0gsMZ|<9CN)il`gCZ1BM6+(5dImFq4{kgP#UJhBiJQBxOtP-iOEb!Wl{bi;P9^_ zy0I%9gd1o8@Raz-n8Zlv=pths5UF26WJt2j#=I8MEQV;rs2j5lVi{`ub!1|4B7P?Z zaa;{?f1+&Ndc`zmyxP}6tRjY3F_Dd8;QPZJ67d_vfLPQRG11mHmdkT103jw3!H%g{ zfRiw$0Hc^82D?0tinBEYI|cQIuX+J$aYNL2)z}`!@WfW{8uV8t^rB+uInSS3-1b!Z(Ofq9Baaf7p22*Z6HoKr3m8mJ%DI8L*TwO23p; zTfEk9A7@x!r}T+UjqHxduNxtEV7*TwwCGf0i>uZ#!39orVTo{Wa4b5zb##C&@rgRO>G345{RuNOE zfBI$8Q;alJaa%!r=EHVO3<4W_)TUbxHU*>@X{sVpmkL$0O%ngWcT^Kwv@N-LLUf{0 z?v{I{;y9)V35T1A@Entbzyn86ksK0)G`9Fw7eM*3Koow6NIw*a)YgW-tdQ-NA3(z0^Fv5_ zvHTDcUpzkqJ}?6y$Mg-=H}P}K+5jSk4*43s^Au<6OTgC*fwk-Ko;i#zE(jyQe<3-; zVlB2CWMgbEmCx9Gxe0*|nU|#rY<9@8ltd8ZkX`vYAppuaR!#WYDS(vC2Vqyi2q{-! zD3G)_^a!wQBQI6~if?`t{H#2{D(YcjP-3Zy9O<4efv+ z2L&4?rgj&ge36NYs8HKCi1VT#oKQ@OF}(bKUI-_F^Q<78CW)z0_&=ikTM$~C=xBC*e;1aR*eW79 zhG)^I1uBw2-!0ZMq| z2L-%g4Zqw~52Y5v^M*I&e+{`R7K^;G6sew|lz@Y^tlfzu$`64gCsrq~oT*j{`-^X# zy2j;|19@$(33=s&yf@%r0BiRQA{I9KtsbkC2jI?Y`gcbPZQ#3z{sBrFq0dn@CN`bh#_r48n+HZ)cpmbhSvQkpf5vi-w_dW3q%YF zY5aaY_!|F{yaFIFSR^(|?v-k5nwT8P13FtNW`qR^%iS{c z!_8=Ite2I!N@0Pxe`1=8l1-kI_G*C`8K2ZGF{+bp=xfO?xOe-P39}A32ups3I^A+W#QG0e3>sKDw{cCwaqetyHRK%fyfDj z9<3vLo&7mhXeSS{+>t~y*{{~gcw4;f8|a$oV5sfnY|D%)aj0Y4kxxPbIphAHi#m^Hflw!;3Qf;vU zI}1eAVP7Koe^5v2*x~LGDc#?VOpat%4W&zGx+s}f`G+!nU#hE|(4sN%kBnd!i!lj_ zaj`s+3x1zpYwys3f{DVCW7#!_5>6y1b)*q`(pa0#*0@!0yH<*w&}QC{(Px<0-;S>t zcleXptn~;-4}66VyGjbA#KHwqa70fVyUb-;n|w@ue@TgP{S>8x8NQ&Wygs)$E1L3? zgd`@hf;?4_y(yEy=fi-kQmj$|KW4=UmA8;#52YgibQdi2`L{`kwBa?Cskq56T2WS2 zgfEz}Mt1$z&ZJc0m(^Zy$EQ+~^4e4uSCwLvl7OaDDIz(td&Axlv2mbGV|6$bQ*Beh zc+G=?e}WX#R#SeI=B$X}(A^GD-gog$&v#6I&@<|DL^s}R_@X0}DwTRG{`@0g#=g=$ zHab-?wKf4IGodorgVCz|q)&%Ih$JRQ*^>QR1<@t9sl3Ur8yBPZC-^M2@QFvq^q-}! zUM*TFKKr4f++sCN^=jPC8^cUW-5YRD#y;+?e<-i968iB)Ljq3rA%0ARcC9Qxuewy(KuWE$1s{G-{Q_Z8(&ZlU&n3QIwp ze^oS97C zuBT)Y!@rLgVz?%GlHvN~IT~(Jo@}^#e|b*D)>V`fT-=5e1sU$cdya)jet`ce<-3L z<(WCs2=A;;{Vt|jn6A1&zBTjG2Invzr2WOEe{93;dMn^85?-FJ&N2)FGu*7YYO zTx=w}7|_a7Uy^=A)dF&315+(td^P|vy%`%Ww!s5%vFfSHCvdQywR?EaNALO!gNRDG;1{l3XG{flhJqQO znu{mT0A1OE;`R+YYAUX2=ohHkSjRHRSin(=OM0ufyj|(|9 zkHCkGd!@p60q|a5F++0hY3`QH%A3$Wki$)dpnk}37Z5Itl@7O;V_I^zWD)L&7*{=R z_lVwl%s5&zd-D@hK^j2Dh3bW2|3Q4A+|psgaEVT37t|@Z5>>miv+(ZV_`6$j3+f2) zk`y~$kYbJ(f6gGDjjg-IP85S35|Vq#33%|9kF zE+QeuKQTGx-K6Bi)WmMRqTjV8L?%Wt_u(z6w!W!K=|2{_uhO-x7;r-~`Y)@1?*ahjTU;i^dyw4PDOG$}{Vb{y;{;${uB}A!Azx=;qiu=g$aR^g{%F{1Je46~f z*&!h!DW!WNyWSsY{=d?|DIMic45N~Hn4X0)`wYr!eRs%gj*-Gv&u!- z3^j`#bSQ$8<$qF`W)4;mb4_c`mo-jBjZ;D6bS4b$C8dI9{}$!yr-J$)xe4_V2FJD8 zae8^^iWm%Ld*uhPbPB_+Zc9#9egK5|aF*CBe^nWcbTaZR|wtQoFNQi==fFp~1zJlaY1YG8`xrpfzF$~uNw ze?6WHZ(>V{RA!lG2C~Z(59S3APE}H}$qO<~)&{35DI-{W+_G~p*?Kq!du~U2*7X(^+|K>X?PsR&z@>Ci`J2|4eJpMmXb2;)K4J&^f4%>E zr$QMNwwx&8)St_L$o)FP`*lS03%hXyyV0Nob>j$j<46fl_4zIyF0esCIcnU>3=bOnaM|mA0i=tGicye?P^(fQNFP$t}5zuVPuw?c+_q#o52#%!C`TkmKIs zxa|n1nn`AX_K|c+0x1ZP{8dscGPVJEp)HYT;Yt#dV_%~ z`*`w1F~kAKSAm5#U7m1Xz!dae#D!dALbrYFr-ab?-z-==BveqwtR#(Be`&HFo2>I0 zD4EH!E@cO6eZVyL7`JqyzGV8ZZrCa|C6!&%bD`bW$u2n5j4n9TtP8E7W*EE1uQMNv zL)xL{ku0$$L{4>=IND2AoaIdw=?nq0w@A}GN2*%^eCR(;p<*=TNz|7HgOOD!p9^n(}zl zCdBHBP2o$hDF=m*#imT&v=f^iRZ=rSwe7Ufv_mu43O;x?KXRI1{eK{3{v62?@lx(q z*=Fk%cKTjrhH-}-45-2m{$>X&tAJNPF1|$!ckR>|Z#H8tepZEYaZpuY{DRR1665t| zYs082%6@GGsPWf0cUF0wv}=cb4gfDDDqR4Q|8ib%*vUXbTM=a zQ)cJ40jQia!)4Wqw~<}@h`3%haxPLy;-(z+ zQR*MyJ^SQ<W_n>KDPQ_u1gg=jmYG~`aALXgsZ8TMcKfl;S;WKVtLoo_|e(_FAq^NN$52r z;lWH^i+4#loPT_;7p}a~-(Xu2ZNYjs9-e$Dz2pxUC7ZVA0WbP! zmlTrNr;cJ8WH$M+R0wIOQg2q3gyNnNW5OudH64~n`zaonOn%s+D8tMJ6V<56a=+D| zKcAVH+^-=c&1FK_h46_oisBcm;MPbd^Ny0f9% z$Oga(T8)}9@a%D0m~)x8+N}Oi@~|q#Wq(*_6v`T&U&cqKS?W!V?EX3H>Ua}!?E+k#beTWj%p4{@vA3;hY%(j%O`qW& zp33D5>y9eb>W`~^1G&gn5sd}ASJPWvwrkR?cNG*t(sCyej*peXw9jwxjOZL6v+j!0bWamRykMR zF@KIQQ&SvmDm0F|*H%oco#%-7h@Q5P>JHCFvIgkD-|zCf120T4`F#=qXAylH#xd&%ltlrej^;?LOn-)_ zn^GG`Bt=BB48Sh60qq_`tIj4?ysbSOYnhbVaL1sxEjb#-YYtZ7Zgp524?JZ764tN7 z3HgkytTbnrRg?tQ=#j_Dt?Kb?X8RQpKd1}WVS&Hlip^>)FnU0fdy6YRN;+$X{?0L5 zzhS3a8K81McJK%=+N~f=~jXKpV4|A!m>m=2qTn2IQWBiw9uR8S4Gqcg77o!;nMq-d#b{Y=h>&EVRN^L>&1(YsrL`ROK3S+w?x)(D4WBH@hIlzFuROoPX@}{`+vr z$qqjJ0BrY&9R(7`GqbhYRUf4%16cjp!7_GG`2%)P{6pCD!45uU2ks&4Ad^VWnyo*w z(}AqrI)okUhJ!Ke;Ms@x1|VQ>C*1xPWZ&Ty2m!$Lf1Qm>cGOPLu_hyc;kvMsZjHPtjcJv%4k&O zg9bvC(Wpv#1EI=j6n#TgWwfk{c2WmU__Z<4JCpG>R82l%t{BS_{C`Y5?ZZypz|M6@ zqxbh~0W`*fwqEoJ_|h(R6iy>I(_($XPA#9Z0W)9oQM!EUN&c8c7#SAy$1$IhKVJLP z^JVRm*b84u6G*0Ml`ETQHaF31G*S7_go$ROiBdlkCYp^_*#DU@(QMg7vt_F+LNn9| zB&#gL(=P)dL9wn>$A8*;2~v*+oW!2&49GVJLh1p_wIxN{AJ8l}hg3d^Mt#&T}C6Aj67bsD|2<(S#{>uSQuW}^?vwp+<FzI({41aTivdXfJovdId9@#4} zy=_1-SD_{3cerO0mxu$u6*-1AVeM?b;O+SOq1_0W-UO3_n-{a*FzV;{T+Q@rE!KA! zXg{F2zsHUOS8~H{wOA9_sVRsVwl6#QJP0rbf5D~~!q{f9u3)Eg5HN>!{iV1I02xZbNc#vY6HCOaM8)cIhA^h#ASX<&*Uk_YH0AE2W+KnI(O0Xm8U z1yQ+E-gRC8Q?g@0CvzWy$N8Qhbf8Mg$I%Tw+0J&b~?)YJB@y;_k@aV9inUo6wm7fDMyy6ZUc-Q#CQl87^vPyIJE2$El?-A zV4zlS1EY0=9i{zY7JxF>eU#1&V6DgwMj=KGc7K#j7>ix3?bzv21axIb${G&X>0%uY zq#=xS9FT^HED%B%(_JtN91Wo?@a7jH3uF?;3>VA-Q2=n8%b4^frTa_DPj#{GW}wAL zU5cUGi8|B8+K8P7v=uqTcP$6}?1DL@Pg}|%8{3K;5>6QNTrh_e2?fAm#yyh&%Ul$< z*MDyKD5c5P6_09)EOW7b&OpJTqN8>qTEjb<7D^r65h^+wu#RJ_?E;&4C4;XHQk{(l8Ck+Pnvb-=~io1GqK?KRV&U2z-Der^!! zN0M?!Us5^R*-c8#J1#4CoGW)6l`Gy}D0du{`=UMEn26}6oN$54eoA}Y)zU*3xFk5& z9;5mcMs?W^aDA{Iqxu|1bt`DGLkr}V%NTfTI*1HjMV*mT|B?Wd}<-3dalI!0mgPJ6_RFR6hq{>b1U+JBlCv(1hr)1N}_@9(V=mj647dS$H zb`~S_0!Jv|OOdr-pecucDNH%S6@N^5iJg1+ZZz}TNBv#l_EDKGc$;w}&1w@6@%t{K zU_3=y*pF*{Npr=5F{_K1+_E-ulT2{M$<6&Mn%ug5B_=mz6QxU6oZKdUMU&f|ubkT> z3hlvTDv*rfdRjKhJXbWzJXbJErLMv#^IX9wFUY>o?uMb7j-sPgv8hEbI)B<+8(c3it*XaG zq@=&bxRI<&_!2#7aO!>=HN2PCB!)%%`X%n2F%(c0x;qc3Na!J5d{Orf>bm)ack>B$vrl)?%_rE+4c#$1o?>+5u@kiQ zP+~CZjFcye@Y!k%wSUdf!K|AYs7mas6}L^9W$V^a?8K?+Iia>Y`#a5qYEQ$(!49!P z?P<8+m=mj}foZs!SfPhV1Jn2eVm(BOJIy4QxU)=<6BhNr5_ct%y7ZJXz-q+)pr>5o zuEn+5MK73(Tn@4p&-Q0|55A&bjmIy@!+#|XSFa#bWHMst<}4Ft zhY#XJcCc#z$PPW?C_BuI6WPIc8^>5=!t78yUY!RCFwcb9;nR4^4pZVq5_pdk`-px4 zd#(wSz#c?`Fm6V`_7c)BCJgE4@f6Y>6F?}GhM6QZ%futuPUq`Q7{DVC5oG&r=YW-5 z-o^w~Z33+3YJZnaB(;+hg+_ZwlS`6DYq>`A5=o;MiLdT_@7GfT$?1mMh4U42biO)C zdgseXa&W%KNt*M)lHl9l6y|(`zLA{o+&B50uViw5=L<@foUboC@yOaPIp43W#d8() zWWzaQ=R23II-mCrvr?6EytA81t%`xkz8(ef(T_-!3zFUwB{izH>;rwy)%U=MnpM zU)lREVViG1^uBFo@V?M~P(Dx7!pzJthPZ9mof(spr^?=qwJ z-R>v6FIxkE_xXNH-WU3<@IGZX$2ej}@7w&Xx_{J0fCFY6#)sdEOMw3g@B52P{f{(^ z`^@MK{r@M%x+rNcdILxY%{bP-|BuGn>pS6nX(aTdnR{P0onJAd_ci=Zc%QO|1I}@I zso$w;6W}~od;fQ&c8%|aM)OINO_D~JxJF-oPa3WK{uP(FRUZsxKIlun_roROgRr5z z1b@0<3Gl#c-wO{c0S;LH2jOoe@HvDZgu9jC-o}?;OT!B6%pWBGDg)rRexw$>pH~)d zcBYBzn)-11c^W!fN$|D*rNI-$d+>>3U#PWyg9h)t=zNv%rSSc+_6A$ps2@r63%w|V zX06{}6p_OTHb%nvgqQ9UsA+}-YJd)!fPds5LclU5oKI22Y`}4Mx#^=MG3}t;&-yVt zJHpznjo87*13Z<=E!aUO9JFNzhuMMKmq2lmbL(|ct`pX%d8cPj^ zwflYOAD59!v%wOVt4J{#kkadF&by1K2SAY4m^V(1vtM)@h&d4H+%Y4R~IaFLKkq2N3vvFWi-~g75$I2+75$h=a58qhZ{Jvh0ygo#|m+ z$Ic>Hd*vK<@Czcq+NGTky5rKNGKP&5EL}Dm1LJy>p?*evXi2~LY8h*ZTRzISfLxv( zY-R_QE3<=#NCj7sA%q<+Q6)GxAMVJ^CYr4}>y6;wZW>_%`&CaDgMT=}3pNhSWJgk(?zx$iwWh8u|f@gPIoTHnxxynQ+S>n zE7nb?BIbm#{La%(mI zHNs=)(Kk@q&od;CzJ&sA0aDg6*`x0vpyEu;qZ6s8y?<|NHowR{y6sHi(E|8CJra2I z)S2YbduIxd&O65Ke~Ei^sSM%KA%AkfRqoM0W(beYB*10v(c3e~qdjM-YgQU5cy!<_ z^5~RV!lRFpZYL!jpO8nNp|Xs(>2KVT zJIBoO&N1=y5^Qa!P3EXkI&#@I*OPnw2s3#72Y)|%>QQmGtuh9e1af|c3!Gq^Z@i7h6+z&`ur{wsUi-6aE0sDF=r=^`c zdl2&ZFY@KVVQibj+B_%R<;LAgzkD;nK1BEz*m;&C^S7d3zM0@CV!XRR3&`#?T#2_e zmwy>y#(?a$Km?=!eyc}$v3n?J|7O7K=MhXGhZV?6K&_yC3uaa)JBptKN{BD09wLQ_n@KPXmkqDk*cR0}N zj)wF*U*E7S1|+zTD}ZGrq?Km8ef$1mb$_xt%avWs7jI{XbjcNqZ}N&vEKmX53q` zY>CJU;RKk=mtr0-p{(%PQjrxh3FBuoW`!Y3MX&4x*h6bROQ~0{|0Z+}u+tRGb$?F! zO-M~5z+o_hez)lqpa3O2GFm+M-0lQtojE zd+*B$>oHGQk1=6oW{HIL7!%e%S!#-UjNu--Or)sC7-55#sXNMe!#{dfk_ou&$%cf6>yoJQ(Ckw{& z`rj#@ORofMh{(2t)kVS{WWk7RzETYrk~NHPH~elTIo7e2!m-i_V>sV#_x8OQjLURKEK$c(riFTmp>c8x+%4i=g$stWrSG zo?J~q>-mRp)@bsrp7*uxPPI69R@!V~C$g!3$u2s}f-XAC0xsI_58l}6-EX3w%>);OaRe360hk*0zw3(^Q1K!!U9%wep3GJ%OT|IdHeUzBQZa6$m`^fE#7PUzC$l!HnU??y zcz}3qq5x^PNzJ@BIL0C#ATu|K*+O~91-d`f1kdNea!I95BI@OwIyBppc27(rs!WM` zr3H6SOv@IbmPOR-cz>wv%cfBC*(@R|k1*Eri0ZOgL{z{{x~8&VAkEz@Z21~RfX`o= z;9Rn08ESi92SZ!lLR`CL!GEh*Gz%wLe_Qyf*;cV?wzW`;@F(5i-Hu8o*oi+Mnyo_3hHMvC6sugEJbuCjz;k5EW6sd^vCMcKFWGQO=c-om#fI%AAUHjp?5={WBu&byJb?+(Fv_semH zeVYkPZFYfZ(Vp{2r=#>+9lt1% zq6{nocMQe>l1DmlhbQg&;j;U}B9OAS?V-o-`oUnW#kMYcY2JsXbwxn?F?&Vm24ns3 zvTlPXpn`c(zJiQ3Sd82(?P1ut*wg{xoUVp5`v-1Sv76BWV zI)HKm@0lelJVUun4@g#cj#lV*fW~lMQDEhfE0kD;=eArJ^!sub1{DQXi*un1S@&_O zn15arSe?Zt?+2R3e;|(%2PKVpQpC;1d|PH?faaDBjkxTp^PnpyZhQ75@l05vDs1t zC$C|LX!2Trh$gSQhs5M{lla_~_-!k~uYa~h+XEd8cTM{prd`wR4vT6imxS&tg4NK_ z!&D8eJ1puM@4q<4t|C0xL+Jce5sdLWfQWmf*F5C{v!7~$PZ!}AI-URJZQcIWV1tWd zKPw%feuf>PehxVz`Z<))M@nSFiz@Cdn03=hkKskF{n+VRAaWnTj&cbwrl|Edc7J*s z_^)OMzDGqJcbeGQCAQOxVjUNHR9MFQZ_Z|3Q8dWlqrxB|1ejkG3p_irg_1Mm8E4n! znZ|Z~Q7k`89TT#L5pa}*w4KY2KPHOTbP{otQ)eDiSJnxzzbG32$uVL4y~OUI#P&c@ zF7gqzJ(XZ*xX7?Sg{j*;=fFThs^G z`@6w?+Da#1;@({fe*~OF2bpCR#=D^kL|3NJ%6EzWWF0D*MKu3hcCwSK4-*UpDd)=ct)Me;%v$?)aKq9 zyr@;&vsvVNKjou6!_9hwou-}@>nHz^tz1nF)zO~i#@A2IQd+T`qqNfXobdIggx*pj zo9)JZU9^ShVCd^(&ylZhJturUgfyG)hQ97$CtnY>3t!J9j9=U^TYpTqi%_-`V6huI z{RKNYz4g5Cl>@^cDd7bKP42R$r#K06f1;Zvm)%1(yWD&EB?f(|usk24W|7v%Xiz%{E;j zH+$o%aI=<#9wL$LCN~pp?Q}47v*4@bW@%T2oB6(=&(v@?+kbJD+|28my6Qj}x!ld# zT~ikn2yleE*^F!CW*4ssHycYTOp;VN%H6Ey^_RMfl?*Ta2qgasb`yT)#{Pz(n}vaI zd~;oRSr|Ck>g(Le!obI#U*}s^@MAga`5h{cycg(4UBQiN-+(7E6braf1bERZXh<_z zz>6ZmA#OlJfPa}aL@LqnHm7Dc$wOcWvl#&NiNH}CbCX8x*i9O>rnkUgFf!g2jv0+( z(C?NS>eQZ$LvZXC4MBz5fbcIABq~DrJ3h*{tle6b9bCJuMm!<(!jb5Bhel%79l;^M zMIZo&fA0{79(QpR)US6!97ftwQfhx4&7YkJCzE$6CVxy1d*e%(r2U#F?{aJ7Ud~Q= z>gG*&OyX3Y!{$v4vwC3Eq(3X^j{8HG5zR`8wi-H3oxePln&31Ff5raaf!G5BY&~P`v!H<*Im=0KCbY#encz0{U3=H zUf-geNdsKq{r!qt&v1RW&SNp_b|R)dB<7!BT-hE|I9+-ymU=T)Ca}_5<{w(= zZSfCqgB8fB#AT(#trahW?L^xgtKjedQPZItZ*PKD&H9Hz@!cn)$j&8RM8d&L_q(Sx1dYBI)ZP$7Fko$@UPF zPoMCZY!5N{?Nbqx?IDP+J{2+9URug&FKrp?2cG`jzZ9R}!P#&BVtjrN@p<82iqAB@ z1?w3GXkQ+nNp2!Qdq4m!d?v+9Pn><9$$tSF2h87l&O+#2>P;gL#}G;cvhL3@K=a(x z03C=MW2Qfcdl&8)p+j&lOwkweeL39n@-b`jd{~?_E}Bok2tMUA%ax2Dx}qsAdqKwGzLv zCLXJ~L_L~s&FKq7{BqEP1BUUfIe&|REtt2as~1J5h!YYyP(!!;!(HYPztYZ_4;e@%|o9213W4sIX&n=!$%7`J)0 zDdI%|n}ZJ=&_F8$ z_+8{v!p#dJJP)_GHGz|SJ9i!2QiTo=n3DXDN(wz- zKf10$zeZYMg&tE%C{Y5gey*4DDyTyL!N*Ig(3kmmsTKMqA1|pwFY`KPo4WitfWT6^ z3Vp)sUJe!dNztNJ=)R@B6wiN3@D5l?8dm6`rNIy$*`@Rq`hQ^7>=EvxRp|GD*AC)! zw1iPnHp$HkN26O0>Kl_bjWQ>hp*L zug6E0r3B?wP9&(n*Es^O#~YTT{FGBpc}G#z+7ZheEYQv7NWA~!W4roj?(UXKTsr_{8myhu%fDig>|_sdges`{pw zQzULwkEanWug5#SDUwDuwexy>#G4ep#VUxLv66VLk$CcY{F4e|g1kmj}NctrPkvcDtgKFcwR*e$G$uql`^_|e4wwFLp{FR*UPaU_pZc3$d!8I<6~Hl zH?D-?m{!K29`DWCJ$%bb_4ozgwzm}La;}td@%_4=6p>`l@RHh4@Z$S(KM|2hWw~GQ z;(Mi^h=0g&L^DaE<;C|kKYc`I5eHs;$5f_>JW^Riq*9I}@Z!5@6^h8zDk35S34x05 zU#h4fNy06qG$p9`K3Rog(zB|F$uwd^#dly;5tP{kpyK;zRS}g9iEmqpKNa6@)hH~7 zR1;yTyrHszxLjL};_`Mi5tjpqPlm)#6yJeFO@GC=Z*_G#Cjb@Sq17og4^% zl-N@7?OH>`=6wSGB_Z+R`@%+ctH-r{X*KT?(bNchyiL zHdK7CcvlT20#Nb&d4LF|8l^ekdZjh~RDXPr37}BA79c{&+gD`+p;W#$g;ML%~EJTYc`f93DN{RpGGsubP)eXAuu)}lMTDj%Wg{Pn&;A5(PC`dCD_cQuYN zgTLPQ%EuJlf%QdnhY&^v-!7a|UqtuE<@ne&EvGq42H!5cwmwDo?fN3R(|?K0e7;@S zw}FW6TmmfM+l5y)5Yau9_)d`c|H3zL{@Z|}yWJ-ux_zswY#_RaenQc`?h_H+dx%f2 z#BZ&I$Im%xyC}gn@*TY9PepVK;4KMhlLe#uy-!7SCy^d2`TpYWpNipPPCIlrB z#!)V)Tp$Tb4ir4H2;(^CF)xsKJP$1FIyQv`bRY$CZUqt0@Cbhl#d8dVbM1yaoMRxG zXEqek90PBDDBef}bBq+rX*g@j;jPW=SXWIsiDdvXYjDPx5V+`>hf#usx zSmpZWn{=H|zdYLe;#A%Qr*f+rgClT;9oGcIZWvCgN)QV>yA{K3G)k`*B$eRlSQEss zCeH!X@39peOXP9<5#=DQM2;m}#nUfXDgjI6^MJ))Xg`kd|tMF zE+RLb03-Okd=CK-xpo2!<8$!`%_&;vHdmwd9hDTK^;mO?R`(WObd!7!>6R<$IE9`G zJxpy6bTHhU-k^mVh$LbnuYD6+s8^)~NawZh>J}6Rm0OB49^>0ym_LdwRD^TPgt#Nv(Wzj#If3vlh z_H2HqHY_?6e}9YiZ2qV=QgrZV^Rro#r_eoYAzE~}lQy1jX~th@!tnSw zM1)70KOe)5JUk|ZP9vHCh@0d{ZrZ%Qu;x3q>%^At13sw5K;II!NPA{J02ZFu<-L~FQQ`zej+iUy@-w> za^W`-3xB`6?d8JnH$?cL1A0FHOzr9paFe38DEww4#?21k?P;~C@LPebf;wU_{fI*8h?o~wh8ec zehGzNJ&ZB_Mz;oCq!`JRJ!>Ib|h)q;5l*nitass-QUdpgnnI?1xCoiF4^&bJnPK4+GV8IjT9ghITAt%0Rkw!gc5r1olvFsUPF`K zt0MB7_vX#+>?M4EvUk7VACTLbx9{`b%)HOMo!y-kAyce4x2q2?#r+?y2 zm%E`N_ERkoy;d9DbU9DDE|t_w9?fsMMA_butSbHle7cM<03I4BNBHFce!7jrmjm=X z9R+$he2Sr?Af9p(@6^VJ%sSFM+zgH?c0%R|!2KCI5jnH~ZkWf8yzJjv__o|tU{~(1 zJ45hhek&NM9_XIL3gNwjdNAW3M1KjTib@)7fHTZtNE5AqCC0GdUWck6OSHusuVE5N z{ET;8rIKbbVV#s;@co7^z=l;V5@!ZO`Oq%XiY~QUApM0l`xaYzQx`EGr!f^!-VC`V ze^=s`n683bvPd8Rsbx)9qL%l=1+`ee;{q*^S?YufX315Wu6asp=q->~hJS_=v1|$# z#1cqKS|YFHicnXOsJso*N_>Q%74PqPc`Ia<^%2A>r6UEa1bi<}#7{p&5~&P}6r{41 z%=$wzuPdL1_fXL-xe90D%t%25>7>6i^1$OrbrPoXpD_r7qbLXuM1cUli&~8fw8zIf zP0@m*D$~%eT1EqH%ikgZ8Gn3eKAO%A!Dl(oMZY1VRkBD&aydC%;wfC>AzbQrlsVYGZ}N(0CwoLq#A|K z029Q|xmbvf2h~LU@XfS-isJ#qchgFZ!wIsw8bQ-Ao826TAv6`U*?$)Ckj?sI49(=5 zT*XU4#J93q7w-^7eD_>acUY|Tm&0fQR@CpV#nDS@PQ_R2nk1gs_U^EKL>Dcz#Bmx)JfS!qDB`$7c@E#Dyni+vpYS+tIFRDF??5ql2a;5Z zBt4HOiDw3iU_V4y|L|bXJxBz*eX%o#n*z;4_x4JqEcE2HFO}8~wwv&X8(H$Ebm4!)lC%NB2Lj+q` z8*>}S@PADFw;^i6O%(%p9_*e%Y|$Y_UCIQ6K?H`;HXBCl5$sAm6H|*ig|W zr^uvpl4*(DwB8_u+Y41}!p~0O+Y8+ts?Oh3F@kU7Q#V!Eyo4$ibDO88lFcttRf|Ys zDYvNAFrl+zQ(m!_>s&NUbWsou^{|SXsheSIAb&hBIF4Mh8{cfnN-(rd`=2KWOW>4$U%h;O|KjG?zy1%)`DerN5fk86k2i?&?Ijqu#x~=h ztNvfYtda2rG4<^+@Yn94oMrvuhF$4lQqSxZ6>1BP?-Z+iRQ`pVV*i}?bu=5ZeoDP4 zYe+-k7HFpk4{Mvx%vV6T0d|#z)AyCYVgc*dSIuT5nKU>!9#> zW?j?xh+rG*$PCh#b=82rChUqSsFTjuznH!Vrmx=yLk(vO57lfNX66mocb9QpwSr3@v2*tnRm$WEXLw{iuoifOtVepY_=b+dw+M}B48 z&X%^Gaoo;PF0>Q0GA3|^oppM~*&<`Zq9WztGudJ)){|-U+UA@_UAOmlMrjLMO!u%5 z-5B4&^u;oLjn5j;S2HLU!Vi1qHdDm(47_1jPu=+NaIWi))4BqJVr-FdK!09}>8^{k zDW=CxYifWS)SI3-tw?bDQ|C>J4G0ekv2~6L4+Wxn=6q{`NCT=?OwXNAC`T-eS57Vc zrI3w;0i(dm@_$p#G{z$D)nX@x*J1`Mrk_zA=qMVj{4yQ>_6Uk?6$zUFg+#^Jl=hGz z6b(~4K#Ef|L9`^j8@*FKiJ6OC&FH0U2QF}*A-J^)-S<|vb6-*nZ`PLI7FuCARYEAW?|)3+zY(n({$>_c zFR;crG-+IzYP}J!HvaAztJLYT(K$SI%$XXz5v`#>Ym|QUtgfnsn$D!-Ce*d}zB9Ves1t@Yg~hVVgRoFcAw?FxfoWso^j$yJ zD`Bw|r7hTnu7cNqZ=Fv?#m9u$8b^f$;YjfH3r>KAO4D+drGK){Z}5o0bXAmZv&=Ai ztT1CtM0I7q48TdVG{mAV#VN|-P*DcFeCtNaS*c7h@Dz8IK9Tp7aFs%yah7zI zIxUGU<+3K!CupTzrB`LfGOimvah(;Duj|x>bY=0Wn991WDI=nzVi*aV%DGCTHq(FR zDwUL{ly{jvDStiib6Fg!IY0%MsnoM6&yQU*kU+F$LNpsnm0YS*yUO|81$v?5b+pb> zRd#W6#Z^ib(>JbCNVNW~tMmz4ui`3&oP(>nN}WdQ-?^*_^|b!ItMsb0Ud>e+aha7V ztnMm>&26!aK5U`TqD-&9tMy|37>f(vE{Y$GKx(>Fr+-EuwOphZJ4?qR^-*)`O;>8h zOFtKCB|d5BQl)}a8o5*}r-8;U)v3`-6W2DYo@1K2RJlqt&0O2QbgdTP+F`3j@DHw6 ztc7uN7bvHkQWwN+OvNG;rRG1b)2o<%bfHcP;GbNmQiN|?7wY6e*3N|*wb1?9mCdOS z++SR%T7M1O_Aa%zNlA;Sp$BR{%iBu#$d3VCet#X~BSR`F{-mj!su9*|w^~f}g&E6u zD?Z)!R{H6t0spJmNp*Za0Rc}GwKMs_t%G(QmzY^e`KWj{MYsENxmgJu0Z-){hKG_9qLto_*wIJ7v7<<(H>`&@ z_zfN#2H^;$9~AU~%I-=((7pIKe6244YsZ_Qde!gXtVh+563VO(xPeRQFPJ&r_-axn8<#_jy2L+{D1bBl#vBe>vUCH3GNA3GnI!MV%4ChW{nlk zcvt(lirGm_#ZEZMI=t!}uR7qJR`IIW_}(}k&*ahxW`+*VpTqeBoYy!3=U)rI!R{X1 z*+S0VpO!66DqJu&mSun zQ?h^9C_+KsiR>tYi4>o~e!Mq6kK(bA{dh)d^OIV4_V1d-cNeRw1~RAFkLM0D-?M*H z%)aJtiYYUhO!4>Gk9Q~V$Hg)E1#bSRniykENxa*~+8BRpj$>@cWaDG3Zd6P}5KAS6()_YbEx1iBz^1}e zSgOPNsYPmrS@{7DV%PyZc$Ll$jK;Z|Wm^fjsLp_v+<=xi=B7ZSL|0;mPNfvO4BVgK zYUp5FaoAQk?4}CXR(qVtEW}f%&EVOWKtjt`Kt^rPQQPCtW2m0z1B)ouANYUF-NEw} zI|^h+`4!kg^wXdsO24Vl@1FhG&m|-l>N$-aDb2Z9jpF;*(M}XIXm`CR;$l7lkiq42 zhKF;*!@=;sri!5(ZfpYJ56X)f(w~49=m1kprtemHC0{@^QI!w{wL^bRzE#6~lr>BUBd$5sg-J3KO&D_drWtBe?i}4y$|SX4 z6_kBTBj3`{x7yQ$Z)v7YjUb%^;{%%W-u{gnJedi3g28E2PDVa+#z_6Djz8HrMrZ37 zvULpF>N{Q7I>z*3mRU43oe@(|Ys4|!?!@V$p{XvcV77)nJKY67&?0|KI;nrAb7Cwx zF&3T3GebBr*5o-yII)P%I3gK1mOIgD205{e>UL*$B6EflP7p&YpK!IopUB3KBjd-R z@sDS4jvi+Mk}frqlk_+fuyp)P11!xg&{*0|;Qe(*j3*<;qY-mv3c?(3`l_B0#*|)f zQ8Q%%JgWnqO2AW1@Y;XN*_op2rVfyW>%T0jyQ*sT9m4oURLezzYWG7~k6SL5XxD4Kfv#<+iXYekZgT5-6FA`ktPi5Fk3>IEBx@3ZvjedWgB^v$`_2O|l>qa59 z7cXNkuABvI{yXcfMN}n3LG5Le?^#xLW0r_ds@pBe{LSOD#%x3Jsro0~0kD#5WpplH zCl{}yi*d7si`PxYE+bWBx<}woXybLLHwg6xqRv)PZ;J*{`1^mBJk0r^2!ux5$lK=tj4>!i`%rOM)AD=!~xlYbM^}ZtR&$ZoE%* zzJ;^7QGA|j+@OgvkPtTL{J2ei+(tiI&l7&!HvKwV_z{0eXZ$YNc$@pNcpmu?Lv=&4 z`{6O)SwHmmbTSE|P!ZXYJLJe6bfoHh;m93Ro?*g~19aw7$;dn0k>BQ%BS)z2W_CyJ zI_Zex{Ua+m&`0OUU2^0uI$~WQ9Jwp?h##HNs)%OfUG7N20&?VYs%uarns2x<4?Xc)%o;6{%w&W=E5pR0%?%s)AUSU)IMeH~pX#sPB`)2#{+a2f)a zU8=4MP}jOAvKFw?DdFm=zB^g*FRJuN+(ds=@i@dvza*ii#WX$~Y4*+E)kjHVC-_>~ zk8Mk_i^{T}b`smC>5gQ@f2+Djk?x+X^fwY(B8hStc2T0hd+k!#~^?H z9u!2`4ady+X+%v}z?~)P;n)5K#xKs0*D#Wr1DW)-fnPoK3ETS4W4toN$*T?g15d zxpOTnKm!SEvJP|wfv!MM(@Ful!u;>&PB=@T>e7&sPN>Ut=qm|*C8B?+qOX568(R+& zTe(C<#s!5%hDCP5tA8bvK#%CaR}uIs1n;DRuQHEn;1Y03r<5#$?Nv&KUrq3<5q^RS zzuIgpnIw2Y(aqjZSt2yq=E?pG1lnT@TYif|$~(+R9+X&H1Qfo?=lWt9Nk$lde` zWLHzALzT^Dc&g^7RZg%MCDDI&g1@XYV+WbB1I?(snkUga%#cKPSoN`O^#zy}HVAOaUz zBYNSWL2kjgf(Zj2BkydB3ky;F32>AS_yhxv3WdM951N(cD)0&CfYpEXUIII-13gWk zrx7$+1wBny4D(2OT^aR?;S63etXX4Z{E@PBi)7GzyN;S=W5kQScH+L5Fp)>VJe? zLM);xAqr|=ntcm~`zWKpE6)tc1=%yM;Sww}69% z*9!;j7P^)#!R+*>Q|hRv`bM$hA5`i77Gu}4l9hNp8%O{)osEBqWMd-QI6y^Bv>3ad zl~CntT04R6*MTPycoKrIR>6}jJeP(p9!_U0E30*1k_EfidjoaxD5{%VHd_~mZE&`W zRUfiQd*gDl4+F@D0qDb|4Z?>37JfAhKHQ@--!G@xH-P)_RQT|SWIW4d^P%ZReCQXh z+4EEF=XyoGf`9NoS0b>`dk! z$7~XJ0jO?Bc8~XNLXTl3VI0*i(`$m2gnu{DNT@}AMAI3|KGS+Mg`0aUQ$#e?&HXIf*eJin*@%`GGqMQa zPn{b>$&I1tM&K6V#!%;bn-(;b@*K}nUdBx&+*HIJt>UJ-0v8uGtc2&Q!yQJr!w`3; ziaU(D4JLo8qI5>d@>-V+v*2X)*A^$^k1uTaljd4F+lG^E!_l_SwyJBq&bJ9IZUhpZ zO@}*za7Q3+2NidO#n`og9+zKr+X*pQhnz;pX^1>ZMNV@bSz6>sC(OG#?2&{$60vuv z*dwI?UPNackw(Hu9>9gSiL8t2c9+i`@zFX<>1 z=!$=%f^5QAGGQ#5Fk3ZYti{-pj${HZ>sSe`hYocdp^ih;Gb-vh%U5b2`q3H9D`@>Q zj`!ggJHGOh%Ovy0a~Jae zA%-E<&CTvYw?CY9fv&Z)NO#SOvIi5$g9(4=!OTDSwe|!HTx*~FgI{Y;u)wu;sa-~% zvD3`ZuD1ipf*_qG6UmZ^Xvt5z#P#+>=hsm$iVt<1LF81^9hKv0KHi{Nel@Nag zwHqwHn^{$(-D29Iy4{k@PCme9?lv^QRR5aT;yOo##wu3wtGmv>E#%)8^zYxjqKQlc68e-hUYd*$NEkUPkn4y3ACsVd^>?} zNAQ^{_;!P_!H10WE(4+U)}ijP@P{_`SYDlCLuaoTI(sNI8j^I|&(+Y_i=pxEJ|k(j zFseahbUYgkq%>7$(jhYG5SsM;K4H=!gA=9N5b<#UnoeK~bfAX`^e}=(tDt{}odj(V z+afN;78JqKgIeKX@HTNK;qK7kA0hlBh(ANcKVtAgBL{pKjkXvii*T>$@Q)JyQN%x? z;vaPqU#vlYLCNwLGUzb^J%*s3`+3|S!?^!$Kacxk823Z>8+v$&+aN7M6MTQ28OOSm(ruB&MQA!+8 zpMkY#FI!t%^2L_h7JS>f%>jDbdgB3l+xj4Bdq{t!x2+!>ptr3LImk$FTem()Z(DCT z$ltbh&&O=>C({~fCbne7_YbO1w_5lMvhKgI;y{v0(xj)e;$nx?M@WAy{3Sd0`K&md zq!wt>cUW;NRr;}ozjg2aloe-^)DBJht4JSZuqyq;LNCo%W5rn{bw`u#$BNgh(oZe; z*1QM2VSkl`ZhxuGk54W5mi@g$_^i@kcCPXjt*(5fsyxJsiyl@VMWmQ=Kh27*Bvn+C zE*j;dv^=anKPW~*Syq4SPf`;#=~z}gh)MhQW;cj3;kqxmQB-N{c_7)7_@N>kl@1KHsPR#Ut)`%(KOI}_qHlL0UdkX;fUTsEFvG7@M-$H0TT1b|v>YLLE_s=q^~9 z?FM_1R5}f5c;a`(l%6Eg?^`VbXSuztuj;ld>fM>WQWQ&Y{Ply z^6;%?wzPZvcvF>O`g9fZOTZZ26MLipq3XHexTMb(`E^Q@!5jvzfDz%uzggeO*jR`HnZ< zgzuzFBsbp;tZF%E_85KfBV|5Su9k#0y75SO(3(fWCLRf&T%btke}N*wzl|;uR$QP+ zu(#1gLcxm^3HFQp3$iincdu$3Fr%6V%z#$2s-1sK%y%>U@pYDwoHkU79Q?YGVx?hp zt)?!;WW$NY0sH%aHRq%(BG1D}J(si8jFUHfwl41VhOSRCy`f_8n<|FAsbbWdD#pI4 zV$z!`8oi->+M7;j_J;CVZ#rTA|EqAZO?tAY^JiEQr#uDvXfaA(>&n(N6I0pIVnk;b}PI6JW6<9_(-`# zHIF5U>uzORuqwslXZHVf2LTWEZ@S5M3aeUw3GYlkV?SR~?MF2#yD-(3l+;{wR z#gxydvSm`;Syq>q)oq}%ZBpHNx3WKAQ+f{F$in~aMf;W?Y+XOqq|wJGys{|fn5iDvmP$aoHAztY&5P+rRSAUpc{s_{KD)Y+?rjZHaL z@?+P}vOn@>4t=lkEyLQwG`5W$l#Y(Eb;k#ilwf!maKAAAB2ftV_Wd1Rq`u~Z zr6;LWdI<;18{FmP>gFa`x*kfSqhf!#+E6Gee~%ZbYO!<~l}c){yu^K8uBye-{!kiR zQL%wL7w*HinSZ4H&N_iNl^@W4XPscbvvm(}zq3wo=3VyN%ib1uH0ufl?H=NOXI(+l z@Q3(8=by253cmCe@)$bF%MNA1%32eMjbUY8{vB`>tV5~uPgsdH5KK_kW66KlPxFA1 z4R|o?DPnBEvn|hXLh{NCM3q~y@FXkrsu+wax8XVMUa*ow!Dz}3ELrga-Pn!?`Tjzc zJMirOe{q%3A*gaM7Pk5unk5uf?!$9>zl5)>+tAAWSW@;MwDJHREdB>o9>BAUyy7aA zj;Qh&7CwFj3Ob?6@b=Rn|bbFN11fg-uE>-+GftH z_`b8di1NbBQ9!NIg{$p_YRg+lZD1Fj+Vn26+6P@^wdP!;wsJ01iyMF6r3COW8yBF3 z`V_wLT{y_Y#&`GO2W)&-%snsP`0f<@p?HQfLn?OVW-T!JE@6l7y~8BdvL8RNAI0~x zA1B@c(Ua^~I*Bee`4*1xQ7(Eg(bDWkNlzwPmHmkD1kpO|mv=Z9U1stf&JG*C%S6Yr zA8G7I@%ik>sdqtiCHsG6C()HA-+$QQ%J-OPu2>)CCHqml0Q*tP3%qr6o|^nvVq}Zy z5fj9&VzY>yKKn(ml*ywwpi+6BU$o{7^bKS+*4%jwFeKkGLeG%?qzU;;ih<%2^!6_y?9!(o3I9Koocz>Z3b`>L_Z z6)fD(3cVhLV>DewgtG6mlFSI=t!pMAuCx#Ha^kvX0_OS`4kOtCXsG1FN=+ANLUsTCa*x7_zUia4#$LS`tODc6_ZZ;A4Wdn*nyy#|Uf3 zFD5-?2VVZssCItS)Z(l%*m8Tu(`a4kT+($fCMi!u0d0l{F z<@16RD}S;d{QRB4{Jg`#+WDzwJiovvbpD`E==^n`(D{oB85ub0i;nuSlSO0ZWH)*2 zjG{LkN8y`}mkRN*GYZ?J^rtj-MwwykbSp|@XOtPn&YFLsGc^nEZE}mCEJM-c%OXPK&o_R%+l6j?>cs!PMER|P374zbsO6PT) zi+M%kGI?>@oq%3e_hkd4VmBH{lhD#fzBG^~;XsNnivwvAo;{~547?Z|DCt=8Q8^q) z>8P$jIT(LP72~jeE7lkEgKqRni^Hfnj$%#xKudQV&?iu8ZUt5n*aPRFlUP!#VqQ>k z3J;c7M37T>ws$2S5#BvfOC91rH zXV3nUt4!~ODz9T<@2{AGL%mVu4Lm3KYgS_IgDQV-V#%?uQROW>s9hOV-omq2ROWLS zOcrT0P26bj=5v}~9bD_eQ2l&?auvZM;d%9SbsmBKAL9_6Sqq2gW9)^K?7++Zs|C8^ zxfwq1{%&pTq~}=ueQg+`-u-Zh+Hv_L8j2K;@7cxOh8S+v<`}K{UzvS-v#J>&g+j-v z@{}a>k_(-vEjscERlb&l>=x`u&pOnRJ?ei@N6xE59T{KO&}^yQz1P!TI<<0254pAV zkD<<~%UgS(1zOuwk7#e81!(Vf1ERfw7NEV)8xrje#FctmLr!}Gu^Cr4gb?gU9hHjD zr{8Kw9hGW{?<*Y`D-^b(){Y}VTZ=2 zMjzWtZv1(4dw3q+9`4bMH~u_yX=5{L{CU{;?VD5M&%?&gXikkk4;%kfbKdy#(Dkw{ zVAS`g#$SSs|4R#M{3Y1mQ-qqjk^LZ32h0Do5t(cW4*1F z+PFItXhKiW8h1T!+;Od_aot-}<9^$k8n=8KP~Z;fVmdX+IkjmpR}2J+w`=`~psqG` z!{01YSF*3%;s>C`gW)eU>gYDS#SfsLci0hMB{;zEYvDD=gGA1ZM=ZW=+2McuADIVm z_2KptU3~;3(bb1GvDRxC|6r1j@Khe^7Tmjwsbu*s%>80d~fA3 z|0b*Ivp@NIQs?t=^7%OW{6||DIWe}5VLhP;9Q_-LV&gkf5wykU?L=D~r?vpwD-Pgo zal(Ser?(^HkF_%rD%viV&4Yh>;QgsAvirMVh5a9}|3BdC9v{HC_xSm(M}+{2vBgG( zcekmzkw1Y{NR+_}GB8|H!j+&Opuj)b;&}EKwAxPhLIUmFm`?N;O!~q}kEOKFpL~r5-P`HR59!jDynxuKy&`A%~#UwlVRdJB)Ux4rr zH~lTrLG$ki@Xyu(=Bk0{NON%H1{5qAh@ICO3VsaC`}VQv*b9t{Yug}PZIK}fia%Lc zGDWtugRry%SbCnp;`M)Q2e<)MJcx6A2e5er9CV?BS3x3JQBWxzqXfDwGb>$#p+g2) zpdje!Etbtg!4fF2g?_FCgK$g;rsUp((fy9#?I~8|l|GoHI>Dv%FQHs&2)?@86{eh- zp~hogABu9TP-~PNCbvpA(JI}bRT6E?bx07q!BafDY`j&vK|_Ch*^##j9!&2jS_K86 z5n`ZKygM=X(uQEG#6qi#g#!N+nBJJbaUlG0XY@Bc1zV*jv`XL3aCJ14q!J)EHHUGj zq1Y;Yp;a1$8E+LeV*ox^{HX~}jF+1t$;8Pp30Eyjcj5C_5-u1-u%ptY=u6m}TAGxI zNLBz}rG}wCh_8P+LQw>7cdfK(6bK5M(8_N>c`Oeut#oWO;_$C;!xy>hc4GxGK|MrX zKN!s!#!A&&m%rehOD}6GB_%^~btEE&l9HjgIM+a*N0=ZZ^ozxe za0FHd#bW9{9Fvl9SoB*gCN1L-{f}7a2lRL|8<$GT8)=qI6B* zqdE7rNCnyx>YoT{46*L2&_apWXz)FqoRQU5a41&g{!dFiA) zW47FGYiUt;EiUSIO68Qt@7yd*rHiDsxTve7IWSYbGzUr?p2n$)mU7pbt{pZh$J6xu zwH|+UKN^{xztTn#e`O+n9T`RZm5Kc2KN|Tf6Nw~tG%Qt&Mrz@=cxH`8e%g-OPmjjc zvEQ-&FxI~w!&k?C$4Q6ZaQS>JtkBU7ml0$05@k%8N{Mp1)*S~pWxN_olu>YeUb=+w z9>YU^j|nef{3p>R%%DlcU`xixmoN*bic5c(2V>+*m?u-|5+-1*%xP8AiPNIfwPoTV zGr3{E&D0D$%vmZUomlFFX~a@>rx8p2Gfl8m`dDuAS(&9OOn1>p`%f&DNu#jcod3>J zL#N9uwQ0H|OFf*fW2tXu$Sl=$h5?o`=pAFJK=Lcsyf?Dc=^2hJk)4DF6PhQcn~z2(j7);_|#A`}$)ch4~__+lHBuN)Ie2D!sZwWM8Eg(^BGM zO*)M)$sbxpom_4;b#nXF)XAT(5xjP2BImW=%o4BJ*0^#E{5Nu=@zHMCeIpV(cO3h#qU_WH@S1OLkQ;1lr94KZNHY8 z`inqbYT4p=5y;DzZE=Y5## zR*gO^!YzQt@6j8w5JfMs(lRmZARkO6@NDgL)Vdk9-rUQt|EFWZwiC+=?Zbp^C!RiS zA1uJku;2q{f8b7BdG~+gIRP{9oc(xC&HZ@JemrODepr2h>ZnlV0B)g_`v6{(0)Hqo zIe#pY`NRK!$P3qR;KQcgMva~}a5AfZkjQMzVUZX5ld`#H%nR!rrMxipDCLD&Gv&On z>T!`5R?Lv|!o=g07p7&%dExHklo$ScT+0iqZsUg4-KH71ne%_=7bl26r=1}FJa&Tk zbN)%epII5)&Trw&g!`H@L8EVKRX9eIZMZ#C(iwU?YT;dvX{FvaqoZc zx$n-)Jr{M}vFCrLpV#%=>~46}s^Mv*%#eODEUr?0;j=rCf0Axs4ZeJ@@fNx#wao z!UGxlo-35)nx0d40w-&8AC#>=P7~j8ocI#6_{7H_966f>L^+FQg_Afd^t?>7!bzMJ z{=A%5dx)gK704oIV-|T9p9N@q1+&PrSl#amWQm!xk>7u>@|o|7`YgbA2e?_)4`{q~ ziQneGc11i3(26R5l!PvFq5M}x1{p_{{Uo8QoBgf zlA?yrI3zdtEi+z8@yAwfUE^0$xA^quWt~HfeFqzR&~<9;JJ{GyuVZ81!KN#718zaj z!Nz`ojop9l1~&EstR8*?A2OSRjr|uEZMmUcNs&o~4{1&G7jL2`H>in%Z&DNeev_Ig z@RsvUr2n*pl1T>SIVQIe?7|lef1r&<-{Ng#w_qFjNhyShOK6!)dM@?-9lwyEXm*S* z?5HpB(6Lv=xzx^yc*=VSdC3x5Z!qxjIB1~)~62nGWE>rOL7lQw(z?olP!>Pt$)O6 zV={k#sO2%`%aieT`0(d+y*nA7t2q9gu6HNna}|YN@ax^l*ffzZ9P-?0FB~%A8!vbk z2`?t&9r@{qS>Z2zaybJ_3;vTg`x`<3w^wGomdvNYk%5Eb1I3#Ujtm?ek#HEv4#3`N z?7%BvAr6kYI5>_$bp$(r>UT`6+J6zxG*^FFAk(bEiXbo-;eg2G57MwQrXUk--UR|) z)+Jbf2f~FoxHJ79h z@t_&=zBdn=hwuY}ro;!{JZK7i=uOj1>IHt@hzr{J8!b4^Gy@?_lpieRO?BQPCCZ6V z?UKOzZ;K2Rlcvh^)H`v2x0EHIE`xvsu3 z)ta5(+ac9DlVA2A|Ca?M53C~!Kuj*vrCQ$>bVaWT?y-`sx39@IXAxs&A!ANuh`^Xx z81paKk(YfL(au$*o!<))?Oa9Lv3!cOa}^2UYj)seU5>PK18FDhQ>2|6SUrE~Q=pK{ z)LSLyuUs2^ZlF%bA)VZ*T#Q>^o zCkZ{}u{g0X#iC~sipB4WP%OSBm)Oofu_N7lmC6gW8SN+(NHdik-;*v_ z5_)un$V%K`1UxNCBOuWYMnFg@907@LfHQ_2cs*Fb7i6(ycPX4i2BNxuO5q4t$+Hry zzflH90Fddc>qKuiv@S_?Lo)rum&mkISz)hb~ z2gZ~aJZW7;IgXpelNse*)xZCVC;h4K&))v;JgNA}Jo$y6BTshp)A8g&Kba@9{0#7< zQTG^6W|3pbci+g9O)EI^Wd8~}o;+JY=E<)svJn=zO2?B~6^-;-PR~p8yU}E9spqoM zW87%dK{t3_x^5*NnPY!&T&Gr|$QWM% z?^$97>7aF;MNR>|s;enr;5vTBJU2`MYgDHcaBy`>0S~Q{Q^3(RL<;D=UQPke)SwhF zaJ`%Y7OhDsVC$M%3TS`C2f(yP8pSYpNCAh|6e-|Ss*HcE2`%NUwW%ht)<3lbYpo!u z&64yA&RXx(CDwlmu1l=-dtG9!@OolyOM1f38~8*!e})^*ZBy$BYD-_wn`(Fu}rI(j=>U#7P_4GhqmGcE$fk#os^y^-SjG;pN2 z#SL^6=h;xExX^|$iLTdCT%Ja*>OFOHMY8vsm$Kd4iRFK`Bg@4#;w-lv<9t6m@~XIj zXk{nTN|z=?D?5=^PBlSV*@-0ZUQ;H&WCPO59;B6OO_5giV0E{qNE;jZgD_Y$v#FX6 zCjZUN8vM8PpbH=9C!30BnoN~*B%#ARn%-?j(bTgUMbrFd6iwX&jI?F;_dEF0n$&!G z&8?+oJn4VN-|sl-2Jd&w4dBgq5}WaU08JJrak41V(qXdb*wSILSlE)!3S!&HQ*Lkr z?MX}hTyYwe=WET{JZ&TO(K+m+hpnlP&S4*QXoG!p4qJRw8<5|GeUODEJK7+%XQ8?m zZJ>|roB6A%Sl_uVQhU~BypMGs%O19j%g4%C@pfr9laW^&ehEVJIEK-cy4f8snVjf3^N z@$kPn??s@@dF6r}Ij?lU%d8$u8;`uWqm-<0S;^81HDX z%y@r(A#kCYsbjoTAx3&m?AE6bQaf4N^*!0*XKwUySvT0NuUaS%(q}k`2ZU0PKEoiL z+=;HWp5YErS3A+Q)-yM_)+*PTUu!*c54gvkVvp#fRB4o8N)(DxI6uPf4 zbPIH$(0zrW8`lLx_Z8yI?gG=q7NpnyxqyFO&vZe0?T@R;xw}H>MsLN?O~E4nt{B=W z*yypmejC=0#rg)3>b2PHcX&%x^=PdI<8Qezbo)e7=#GjKp_@fgw8jTj1weqXd5SiiMb>a2#J4l z*--jV9AKwm_KDYj=YUOdG6y`2bL4;$@j4FZ8ZUFelz0OiVAwxK0ao&CNA5RLfLC`% z3aH*)M*-uz%M|d09eH_g*HOTf9>&(c!fg#AqN8HsVtxG@+ai@LGV+>gY(e&aepC5q z_J775v*Om%n_d{nkN07mgREzZWBGp?hpL-LhAe=P1pu;gPfi&H0I-XSUtq|$M)oMx z;nOCqfdsu(XF@?Vp&*zr8BB;}2e3iwAvlO(2XHA}B*D;Xs$_$Hv(zjy;gZgjPtcT4 zz?9|*-n2jFC&so%hHGf*Z6z-U$(2_ID~@2r?=rCD1ku{XjrBHxK|fmwBtU-$Rsz9F z0N9!Y-p?ff>b8npVuGPhVi9uvpjai45O?d4OCoYfKrY;icW+66`k|LVE@^BBU_urf z;}d92ZyCH4f|mmD83bMm#@2~md~B71u~o9Sfw4vC`cV}~;6XYgN}~~_!H6Gwi&0hD zsZpiwqG~6klRCsQh*$;?hxUIK&5Vb9&(r`$Y9Qx}Tc%!RBDiJhG*U8?{<6u+(3YtV zMv6CWNb9kDvZ=nn&t<_hkB|F6;tzZqt9%ASB)N|fvL*CdooyjqTL*=Qg(_Ku==p(+ z{53Yx*8qLLk7%T?f#emhL)?nWU`4UMFx@WU(iyeY!-j3QOe$c|BXFW ziud=4Dy(E;Nu8+;(bR_1?wXZueTAtFjZuY+2z=pBNbx$vMu^x55NGz~e9;Iuu~6X~ z;S=pn!2@a73AX-+GJIo%Zw&D7{>tDPhc^DXvRV25R{`G`NyE!~2kWTtSfxo@Hh&Lb zwO-LX@G7t=Si7JfD>#3|3d+PN&Az&ak4-8b{w)7GO0XwC(7H09Y=6kl6ps}4=L%I^ zmjs%Z-HifHIW6Ww@^`Dw@3!c7Tk!j0Kh9Tefv?`TbG~W|d=+FjvZN%L;4l@E1($S| zv_nhUfhE7$1!=W2Mp`nq%3O*Mhil^_!~Tr0KLhL^cG1^($eDku;!e(7zaVp2`xA2& zB_$<%oMWz>EG7C1B-OT$WP5)B`f3mMd9>*7WVh%6;oUug+Np!=V8S=AaWgOmiEm!x zCSd(Vdv(CrV1@;vVM?NthRIY)rg#*PP3nxj))~;gNEB9dMk*~66Rm_{=y^r&#K`P| zyF)QC7L;B1YcYRWJ26DNQix)N*87+vH2PQzzz8`)!>A%c5{RM*MY=vh6&3Sq0?|6U zMzJ`mJ|>Ap>RH_#46>5TB~{na8nK&a0`Ld)KTN3TXMc=MVY@$Q_THuc4 zN+2muDJXYEZl|8gbxFoMn*T|o1-k7$2X5SULDizR`+vcS89mZzX5 z&`<7`52)f3oq$2�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

qSPr4KZ7zXO;VO8f6K(3 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%0Dv>v%6n>a07GJ8Bf;5y&bXNwm0I9wx>(MfG@Va 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 c+{lx()f51DQ?+S`wm* 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 Mp~9Z;dYqPpKPj>` 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�_QX4&=4NzqH3)zoREH`M0o#f+E_J=txWk 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 z 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%0DgOM~T4+SkdTh`>iaeH{P&t3Lr3MFBWYp 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

@_GU!YL(ki89D>6B_{+K>D0@E=RtIF~Wi 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

g4M47M6PFqCZfVJ)Hb3N@Katy;IwjoS8t@=^ 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
)aar2@~|I-4;n6Z;sBr{rvp%!bdmG?C3;a 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 z zrkyU#ISj%|WcEo|H2;DqY9k&0sSqsY89HZp;Pt7FJ4}sW+2zfgePQ3hVxNbfCx|dW zOEx?FRgF?UG%g0*h%b(jhd5oA=(SUz(>f*hu7f}qtLI4vnDv-Ns&{Uj%u`J^VqqfL zC?ZXBd7modtpg8OknqNwgtYEBnz&WjvLNu7yj~gIY*0t@J2+IS`S@mF@ zrlie7;`W^=2iE4RhP$AO6;fq!?JT^-^@vDWbd!B?YQ!IwAus#?+3`$=B0icv2|k3p z{?5}&N(1oX8PZvc*r?c~SJAnz+ToB#P9%In;B9^$62)lQPU%g-AlK0EpA@qxyhld2 z1AInU(4)103HZUJ(01oy<+#~qO^xsL&$QBV!OjjNcMtp3&BjqM&$iB7_iCSzx?xf* za`P0qiD_mRP4umr%nqu&r2G-mqQsm0#0q0DP`|$oPtAlyfm+x* zMSZbdO&S4|(eV}Z?RCE;6|X;#$P#LMb~47asS*sn&TmR$X<-|S$q%YnCH@FaQjr(#T+)1tG45}q~HhYc?=*BNT z`i(CU>22hGM{Xl#k-kUQppP-NmAy|DUqHSu>5f;k`Nf?~+X_$Gbo9d=)fw_Xm)dl9 z9~wrx-eO@r=eORw*m-rL4e56FzwsZafamU?%T&+J(fCuZG=-K)hGqrlsWynLa{C7b zA2Rx@7{jeQ=0-4P6_zJ=r=Y(V`r*-Q{%Tk2dyS04Y~9%(qGI7MLHWjF{_-&|kq$xL zLk%4)%WWGjwY%3m?KvGYq9-Q%C8)RkAm@nRa^ZlZxNC=8gHiBW?u*>^}3z_=*f z;q#79jBLN)T_RD;i$2j6xHFz*k7dq?e$RhB1A5#H&Yebm%2t4{ko3<`;q7O;WftE3 z2p#cSVH|v+_Bw~Ru^AVo6i~VZB9XGWB7gs6`LDTi^{`)*=Wm2)(;;Qu!w*X7Z-T8^ zObE8S?-No{{Ky9U?5Q7}2Y}EY;8U1u!T9~TTHwVubQxh4DyBjK=HEJA{y{#e(#VR$ z`7z}f<5uoZ7KPKNjJ5Mc|7m0HVX*UVvh%Kkm_Yo6)|{ffvZFNILu)IeLrgs;2s!h! zk(hXckLK-qYf-h@3Fke?@)F&Dz){kq?fal3V$T(x%Vkluk_tCme;@}blK|2BkGo*Y zo!j{KR>G$o+wS0r^p4r>an)EyHR*>#80q;B#9=b+zHJTt+4Z&Usyr2K=9W9K0*-e* z&+n#Sp~au7S^KVUh`cwQTYL`D%t>>*a`4aAs~~C&X!e7C^>=aWUa_0T=l$F9=SlSU zH1E{73u*Q@rNwd9KtMR<`6VGugK~aed1)ayZv+ji$GwQOTq*pOpFJIH5-rzk_3o7q zXO#G;&~mDCHq$gyXR|A(Sd6^xYb2^+s|gdDftA< z7=Oy7RpL4^{+^nJ{9=~|C1QO4MR<u0Qk$_p$}>aKIaYq(3Rjpv zC*bP^oqVhTBteg+HZCE-)eb5e>$cz`%lC3ULf%3>s@w~_y?i6zdw5Hviysg&EK2P| zo)YQ?2UTYRaWfFK`%pBNi=Wm|$~>i&%iW1m!etb*)1i}a%;M;ihn%PjF76-e%NKCS zx}y%!V*vSnKU;qGeUKZCv9y?WS=C!2ofO%nig$W|zgS&rwK*rU06U%=q@M$#nrDn_ z@xJ+k-DN0-%Xdr{4jY^W;nsPiHG6oTb@CGq;}$H67Ukl+x@9`xHGT&a5P?+}ou-am8yj zl1XCD&LpD?Q5DX|G%Psxp(y;+QBg;l#B-RGusKPFfg=&aOtQs4#xuTGE3wI;i&Gy8 zPGxMbilOnVzAeiGr`uHKT$6(l zu=-kj?Llo~SymF`+4jPNGb&zX-Gjs(H%~6c_}4?%Dun6cFY(Hk9DK2Snw`X=uOx=u zpdrx}B<$)&w&65=nn9NN;V-k*{OlLab~sbsd?O!+tq#y2cqc?&?21Cs?46o5h{ zBy-D`sjcEh^GIu0DTbl{>#ya*-|UMlfBsTr+ZOG<6pUR7!}UvUlV#Hn5>29eV2@J4oXdn%u){vCO*mU*J9>Ps$7kB*mNGsXL# zl~^}1I#k8PN5A_V!BH|Id?9qd4d-^G8-358qW%wY(33Fq#l&GNXQA&^8BiP8r;Pnc zFM*|i?U-SzG`aeX>o+l}|0o)@T+V&yi6F^YpINr1ntL3sy*%q3>Ikm*rBdO9%d_!E zZOccn)`cYlWru&{>sN1NeeAbBsK6#1oVKAbPnf&in^#9db@f1Lq_*;fJ)!LnBU;#y z9SDp^?)m5oQV_>RMkQ_PdSpN#1#oly=4QK;)c{U9gMm5PORo5IDSMSw+ zA%FO0*p1Xznm%U*(F&%q4i=*Su86obtmqFC;-8lXLB!ICnbcV0OkNA#1K$fM7jvxa7JT!q@%V_Q%zKc^-&fTcHL-;u%*-+!(`SlgC3HPixy^DOklfhpw zH7{-CgB)Gq$eqboJ1~0L_l>j|TuhINd>L&SO0W-og~`;IlSSO3t?LrKxM_aW9!7}z z%0ZcLg2%n#F?)hKggkh1;XRcJC$@>@p`O{w7o>#rJpd=9!ZySammD{LYcw7KJ`yhA zAvxKbjrueSrdl&r=;Z6oPU-2AQ2mdW$3tS%~IqmBnGjv8M{NmQ&RjhP>Wb+ImgJ4jF5`1UmPd>=1FWDK$aY>T7 zu}v(HG#;gX0yTVdT&go4QdL#GeE|@EECl+r8uwqSFpRo*(#}N%+!fAhn2O0u7b(*` z<&zfMe*9$fmD`2YzeU)&2XNvZ>}#+X`5H#+ zV}F47)aE+b3wizQ=3~qS4y^4lCI(389wo2B-JymY(6YQ(MN90;o^XcNi#ZaMj6oD5 z5*a3Icj(jp{}bvr*{Ke_W?W+?gUvz*Y>B`%z9=5YBuFBzG<2(<2l1}&#LPk1%6#2s znn5napt@Wfa3@4`#$O`1yAhE(0M3_pKzu?l{X7`-Z(1J+E^dzjHDrK@hItwdJ_*fy z_(Q-_jG|Hc*Fy+h1m_xg8v$ zlz_bucrAU>MvJJod7dW29P6w67#XSS9U)O|oO_DeCSeX|*RfC!e`C z^kDKNMe;DoNATNeMrdc%eDmP5igm4*&kp4$LXA5VC7k&=e%HVjjRf8i)q}bcnIb;P zk{BPoIyl#Y4yr;?q0zpUf38${!wZ1Y+8tB0##Y2eiKud$Jdh(350qmt_(R(feCUJJ zkN4Q9ezb%wxX{#Ol$o9mBybC3aOJis`^>#!bx^T7A>Z50)S$PYpq1GuhwbpS!OuzT z(8wekXy9Mg85W|$*Whh`r0X2i!yJDca0()yx1Q-}Mk2TM%9=b5H~q$;kdj1Cn#&0?CYW)XqTSB>QjP_YVr?&%U`*9L}K6*!ck2z}z^QOxiYn-dgHk)&Ze+ zre!;_ba-Jh=I^ZS%-_DD=>*=rX*PJvz24;-E)A+-kX#r;340Sok*uuOdn(jky0RLiq*O}N)e7(&^Sme z%_A9Gn>NH%RA^KnEdqAPsbF^W<_#l(DtUSQ5*W=t^c&%b_xkJsEW8j5=B% zUVNleWxX_5;3l+nxnKE&+eWH2s}C)#mJ_xc5f-~Ag8I*B`F`UlAC~3l#(0c9{4S9< zL7PRD>_=Ti-SET|{k&CW*DHjnHj4ei)CJ>+n(4LKUL>MUFkEY{N4-afA?;+7Z0!B#xBO98B#vKY``4ZACNn30CN&1y6HF~^QU5^>k@r~gSR^5sOYAthq8^w7Bu z?);^QN&588x1BrI_>}7XiJ(IxXZwAa>G_zIgz4d{9iJhmYrogKZ$ffvHzg>$5QJ^; zGKut(6=%j(SN}?iymCUGEOv5g7Ml+5h~m!7ycHzML7W9Jt@{pnuXJ?f@+c(oCn~ZRVB~K$EBD907)Qs8 zTh*YMu6pTc^S0Wn|14l4Un`H5SLSW?WFj53w$)8oTB%_@bD=XijxRcMF_p%#mrStZ zkbit!Hv_|^YGn-XsgHh`@k#LNPhYZ#kS`Cst;hJ{-7G1k%#^dQ0?+mHki zS9XB_#onK)kc}BW^_A;;3$e$L;08+ASSTH@DC%-rsG}n)x~=DDsopB&rA2q#-_PJud^p+wUEP&rrr78v{-3pZv3wr`)ve>l9r0SG?G zzwrAe$d^5*(}nC3ykv)K{7QGjU;25}=RU?y5<9c0+$Gz&66mzW$Q3?d!8+r7(c6m-{ihG>>>}Z8v*|Ld;y<`={b+g4(ZGv8}tA9HGIKhl{+n zC-mnn(T-0W++g%I?ot6W86MrRx(zuu_ zvE1w3qoT@AskZ&JuSj@1NbhoTq<4`uUFdbr)d}LtF3l*?iYtLVJgNMgdIfIX60BmP zjaW-DBDedu!VMQjh>Y!Qu>&8k3`0jgUYW!5%lrv)35E1Q@30bj%`jHC3+k;!?LCa* zK}L~#^DO<;-sxs)*a6(FB~Mh2x8{}rR)O92ctd-LzB+2haJ!!jH_GipPw_ic=B~RD z2~pd4){~xEAcU+X=+lJ!^G{Z5l{U19dEuk)yuQ4#_-TZ>+4YWev`60wvz7Jx+-G@; zgc&Ig=ry@r>Mu+OzlNMfj9M*#A7({R&2u@vvf@1xIo0>HofYh+vwgBQd zmukl6o#3BY(KsCjk}~kQGjTDSiiKzh>Fxe#kb^$h65jJ&p*|Ev7mK04O5Mo47rZ2%`2&fSEJGZ@r{h3!IOc#AVDBMANGizf=JmH9u$>?AZ?7$MqoBK&mnuyVl zGgeLACLb?Z2H_-E7WYYWA2zM#uo5NHWUGl{p3#-FyD|t~_{+>iqh#`VfJSsGw(n4O7gG~DPs0%u7DknO0_0$C z0TNifIx%=Dpedw6WR|3rrgZVVTM0HW=fr~a?b*0KbAqe430=UnTN_fM0$I;9%(k3= z2;v#^MmtMEbU`F5-YtS4qB}T9o`6OvMZ_clo!u$igxoUUYm38ki z2=~qCWb)5e0j`;|f6IgOJS2YoJ&v>F8Pw`LmomHuX1iNRu225Vc6*Z$e!EIUh^1x_ zGrs)>+wlK#Xvzr~K5WeKRR7xun+>@wH&0S_VB+~PNzM6h*Xr7{6 zVuXEfrds+DG$$mr2B34Uk&H|+(lT;yG10HtEc@|p<-Td}31^afzlBV{X0=SpyY(Lb z$r{2gp+vQ2nYqyY{Kz_rRWJaC%)f;RfYO1H^g%HGSD7{)MaHSOh9{#xZBp1A45E2k z65hvBTB9ejNRf(fISYmUs>N7@pxa91i`YwBgy27^lgeJO04y1A9PZ#Cn;_nUrL2V+ zoM^W3e5K9^HB9;uV~6~RV3t4NkNgv${HFR+#F{N{oqpQV2vwFpL?8K0r1BTM6#0Ud zd-}euAx&Dp<}ds}T@|w)T_T;xVn)hzMPab^LIY*B*1)CK*!P@r7!lBm;u_6Y7fVxm zlX(0#daYTw6L>v~v&X`A@V#ZxGTxF!-d{MfWJiQFkBVrI>Ru>IT%pmBRCOzVT){(? z)YFDO*IeOxl32JkA{nttK!eAB#YpawOr`kDY?nW+?N+&8)f44M#B-!*X8XafxYr5V zXh&mzK_Z^hO)ZQeMi<7YE7!B!Gn|V@IE_77!9$^z!~o9}lC@&?BnbNpIhc}64|SHj zbVWe`xsEtD7+MKv&5)0X{;2lZFL|%Q$4LJtIk9m@Vb(LS5Z_WCDEw~y+2aI<56h5x z8Wb*v5mMzjO8(kcCXI^D4!WhqH1z&E1CiT#_!nCjk1RJgZ1~sg!Ju>cH5oAJc znL!Yw0&u$iXhRx=TYu_7G}6qKu+A_KX?Y-Ls2+n=2#A8X!Px4oJ- z%+f_{ZMdsheQ+me6=$u2adjY-1d?+R$8_k7YMx~iGss|ft;u3HB*2D#Ia^Rx~Ab-J0^GAIP(rx%lgbTjY`d&@*@>2a(^;W6`u(G z2!st8Kd*B0oZRly3n9y=AB?A?t_mx7XplxXVT$V23$(>Mv_|m)$?s$DcPR<)OOj*& zM_(6G8tSmme!0Sx4DQ93Vd3mzhV3`1r(%E3J2&!B>a-+UqwGF?%5RTAJFM8 zEof=Rmk712_wQ}UE*4OglYE`uqeH7me$k}0qm@{J_q$amR-SJlqp}n1UU@>WI^>P* zwY(LgXCbX*_YEDDH>5kBD$d(64G{)5R1u_+c;tfX0w@GFn8nal_eDfqx~Ni|_$=E;ohI%Q$&y%DtIPMs3H0)Z*)4J@bWG1&v;t+QyY z1Qv(d2_eQ4y`0VPhYnj&5iBRuavwIGHMm zG(9BdXFE?eq`yK{Bx?lvurHeDqxb^Ho^J|hIMlF<3kuA*z5eub7uGxza%INySZ!+6QzH*^r zX4FY$3kmk6BPRM&97DQ-eARgGWp1*>S5L@ARNUeV?m3gbaGqt-Iry*A;&Jb}->vZW zB*$@fP5MXf^=J=%I9!=qHT#OO-}mgZaxF>8uGIadF&2lrW5nE|RsIX`wdYPAZAli5 z%#=~Jw0h;k&lTRNubiPArYK{_S;1b38_=(>icD?r812F+tjFJMH6@bItney$gbd(} z4y8#|w<{ciJf6QvT}At(^ZG##>0QW^IX|GcQy2##X6mK0v`W2got&v`%G+fZnz8P- zwSl3L!(2kQkdRxxhZ;Kp@cfE%T%k9WwUC_&OB3S!W;Q>8r}+)!fj7SnHLop|=jX~c z;hOYo2Oc9~dTODx{E{-cYK@8e2%ZXaX*mD@F48;m;<_^g|dgM#joCcpt?> zD3cc+N>(z?@u=Goa>VCPyn7GdPoITt@7=$6sWb`A>D{DYO#nweqccvm{cqsmvW
%;LLdsjg2jXr|(WglO{ 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

SY?1b5vG% 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

{#sKb!uMFBfZZKIX$bS*WKFKJ#TJl<=x?DrH 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

r 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

GCuuMw8%MxPf&w(Jtp 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

p4goEp$aSjxrt@heU~PFEQp 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�TeC%l2Y>}Du!3*&~$gDu|E+NZG{BMUM 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 z

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

@%Zsd)RJjH0Bio*^z9bO{K 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

uXq^D-scsGOU6HqZnXJ7$EbccB`FCLA{k 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�I@-7Q_!00i(tTu0-S`iim6i-Ufq^IB6q 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�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 r;@qBfaS~V_V6AW@Nph= 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 tpj|l%<(i8nJw7VMB8t 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

    ri(bt7B3~7E`-R$k#;>Pzr96dI)cjE2F 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

    66l-yJ zio3geafdhe|9L+pYqFA+mCQABopbj7?Pu$kx_4%C25Ojs#*)3I3;H79&f>p^O-8+U zc7&=l`wic}MtJcFdRB0Bcd2`8;db+@Aj6M<>tuK#G#!ls{c-T!rG8DC;qc$Zfe8{- zQSNs|XVEO}F4Na$8ZVtEY}yxZeI#wFt`f6PX*6+VfvdedAP+estKGnJ2E1ArQ`@<2 za`6vmU@g(HxQG9p)J#E+!w&z!$VllkNqX);�%BXsIN0+Tw*T@W53wrQkYW^pNo@ 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%0AIC4!Q!Ox;{Ivt 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�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 z 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 z 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

    =1*S}8>0iTWJh_;v3zcZpgW#Oay=qS$Y-YH!2 z->Z00tgxLyyCFgHM=kn~ph+HHf9ShZX3Y^RnN?}KzIWe+W2S{!ov}5ktYu!oi?bMM z)+0teBp#7yA|o!p(<*H5v0gA8#WU6t6nXo-Xi52-SBXk(OjL_Y-EY7-FeveVhV&F2Wz}~_~=S} ztbEM*#@hF(EZNPDfmrXDIwbF-^(FK`dJ)~%kaIL6Xf*riBotm1)cp87M-2sM=^UyqVCglZ_|;iN7p{`<2>z( ztJ~(xdIEAcCwo=cLHf|i^05pflw9kci?oEag`o!xvS1H!+7tRcE8>G1FZq*^>k1w& zP2`7&%o$LZgs=?b7M0?%kBjDjp)UvJ;)7*Q*Ie9|7La4yalUHbLsEbA#Q&4ss@%xF!wE#LFl*FU5p z@YBEAyw##UerQG>g&$c-7wP2I*8hTN$EQv2YY)vpSPzX4ULIM$|K#jKf�HQeJE_ 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

    _rhOnW}7zl_Wb*8Mhf>5Ys= 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 XoSe;6SH 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 fue_oRXF-ka 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

    t8JxZP>h;O=REz{(- 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

    i%j!sJLfVUHj~LYGFmm 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

    n5KgM|;C)bfQ?*>xLVfS=*>5^CUh3i*Go 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�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%0D^A+6}&-a8TFIU~(+Y{Wr49D;T+&4P27QK|= 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 s^L$_B!+tt^!F*epGK4lVfobD~S{LD~6nCk_K$ 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
      Yt+Z|J^R^BW+bSzjWjocaY%E?#DYA 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 z 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铛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%0A5Q?aJ7(3}m`;ImQlkrG6X}JJpr*Fm{0}v*==3 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

      a%!}*XGLz+%;dIz17 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%0Ae^ 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 z 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�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 k@%*G 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

      ~lJ}L4B7;;Pz&B;D{uIFz| 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

      7#$8k3isS&Y&wtZsh_H`>54PNrp2Ec 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�wyy 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 z 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 z z5`+bv;ZssFRLV)l?%F-p$h+_qPT4YEzLIk+sdm5jj_cp#?jgG)Ddb{1OtHEzc8Ez( z^stSaURBG`Q0tO@Zb?|-#9Hm$agQA7P)jWa?V=W_YhR6jxZ$0fIU=6$ETi6?YQ!Dq zi=v-09XLUw<|BCFZpnoY!W8AfH(9NM*f#p$04r3Eva>$cWB1x8a<#%>RF(TffIxaN zuNewCr_|8I*_m^s{Osp*J*B!=AHd$G zUXp`q>SH(TOi2k(*rl>!pBte_WC}LYal0QXxW}4&0uoI#@~bxb%U+Z*61sJUv+z4U z)s3`GEL9;1sVPn9T_l}x_D@OZaH(L~0O(k;q%_aJt${W37?Eh~NMG6VV<;6>^ zsfwiTPFr(_iw>!$kCzAw;FM}TKN~ToAs`Zymam02d+t5y_g=>BFWOJ)ay&!uq*v#O z&GAWi8t+DS{4F!rjWuk`V|8gxi9if)6>U5chO5n^hW~`HErF=!DW1f{B)KEZQZB}r zv%t)^dA~%`hd1N<4ZFUd7s>Lh9eL}g`t_Awuht&?SW02uSIe=5jS_LAvyb?#h{oRsI8@>9&NW9asW&`!ud{V;_{ z+kG(vr$Ok5Qe+}fAc#Nz+U$Dqr|`wQyXhG7O5FA=9~>&u_fI)*Dm>mgPuol>7XMVUuiK?uVCu5`t*m44vmO^&|gRE;+ z(<_<6=(^i`&jG!yM~$!5vhVJjoV>+Dg4m7(V?t6A1nXZg2l(Grf>*y>=8|x&{Y#D9 zt!Fdau%i zrzdVrQYzKU3lEB0OWuB)FYYJ(ewsS!9gVcJ7E0Y7mTEWp1D9}elJLnAzN5n8qC%fL zzvB4c@ma{lX&^t#>|WkSe4dtgFDbm%Rph?n^z6^hyfukQfttI;;c;p5>s9iue;77) zMht?2)f`uJQKVQ2xg{ZF%_R*h2J?G)fem>?avxkI$Edm5Nb`EfJO7xhMcuI0yRs1y z|DLBXVi2NjF%)XCz!=!E+c7MI-X}}%P5JYMBOrMAiJ?Zb#)AR@fR5=Z`~0-ad0X)_ zvM7u}sk*Fa!&#Q@4oDfa6Q>n&08+RU59?MHN_8_xjTEMP;f;0`c`dl}BF4>P`;}17 z!vrclOZo6Xg_y=6cd?Im$C6PmE6ItW--0odwc_)m-e_Qb>S% zp=QrWC2kRq6BhS4ZMJ218W09zb)CY_75}WI^4!b;?21fnZosbKx$w?_v1`;hbE699 zK3<74#^a)4Cu7(M+P4ThaEh(B9Ynl@Ha%#e?txT;BB+A*|EG`qJ?SkT50Zaj04R3* z&VbKSE%)NZH)-nV<5|ex)yNx3*cZ-QbyomDh6TN8HKFf%i%~^kFdJ1Y!dycwFPH_3 z=f$$nt=kL$3UXQt-iwpqg&f)z?1<0Y{G6OUrUCFwkcyZ#2u9K>yZW)dSpoxpCP@*yMyf=Hz6JbO6pAbX{t2z8* zN9yz^%ZLx13~$ir-777L8do1pz%kjG{n=G>Mv~<63#_dTY8;p#;J9>b!yu}VA1ER_ z-H6Y)CyOZ1bf-}(&@u$EmNJ8E$5(J-`xQ7nH%qQ1#op>Zu%UUCZO%+*dT`C zz1)vvFF7~cwI|`|>`_49IVQ_igHt=H2q;euQm#Q?`4hw#&B`};HW0aoC0dSn^C^$L z*TA(&>2o+d*8IPwe?TO&a)^-4hGjr`7Kg2~kz2;paK1QN*bR|fWMMsWEgAa{`!@Nv z31e{iIFLu$94c=;@{?r4se27P^46|%rzLly8AZ(oJYnR;4Z@e~1~xTc4yO&DPJoZy ztuAR+oZRok!CQSK41-74yha33q8P<*{D^@Addx%D7IW$4MYqlKHF=QhstAfWy{uaO zELh?+Ir#2Jmg+Y+B>z36W{UP0p?6zlNb&OXPslaJ2Q5UD)w_MYYM-n{zKi!3?Su4L zHakb1Uq+a~%^eNk5f1PX8Zxs2p*Wq;!9lt0h*nj>Y|swXFG19A;#X9v5wZf^ z*}j!$qH6E21#$15qSLac0`hSvE#a#frj)TIDrvAD{yZ*k!Jp34>(+ zb7@lwU|nWEACSctxVFgSa0-6Bo1^}BlnB~QYJR_F1l1Joj4P^3+ zox-y!i7SFp+f7Icyu z69-*JqeVD2`ZMtqF*8#loJ-}dTu4}{60j5lox7bsJbxze-P?DiIkLSm;DGeri4qj7 z|HNi4161@mI9!E9f)=W_3RpYh{-g}CMi>>5aFyp3dl9s z2UfG!iYU_tA-~9%f~(~)qpdVwH$)f2-pIGvls!PT2~0xms4G<+i-E2WP?65(J8LhOM=utulX0`$hFm-0%trT9;Rp z7a{JW7F&6^sbnS#z`{DvbOX^2REUQ9+6NuRiBZ+Ckt8m@IYSV{&RR875bRX;zXRJS zsy|1VVqPQ8)Y<*igKAoL%54uQfSz7!77a47Mwn zj#REe@)y&#|CGmj(PCO;hA?#`uv-~O#@z}`c!-pmF+%Vi0;2SHz(F1%q)?uk_>yVz zMHCA`JB!f4LNRrCuXVxGH@u~|=iu%D#*MGGWi29YO>J^ul;~xS=#gaiDL6#LDln`A zvJO;X7&eTBAZU(xu7ivj5N^cbCr9YM!^YLgfxRzWYK}CrHsr)7+;Jid zx%4C`uYoxxSMT%XywBj;_9w3z1e+^>^#mXUOW!*y68tOLzQytiIxMASQ?vJC)U6iu zX;Y%Y1ba=NY8apf-q0z23G@DHrroUN^V%0l5VXX&9SeJgek*XJ%r_=L$7#dx3h+yN zo$6Br@Cq(;z9&mj5#y^lId7t^0A|*X3Bs%z0)ozUfx0T3J_>%2vhxFtZjr^Pe$jYg zx8Lpyp3wr@*yl9!IL7)j%9S~?Z$!6tB@Q?9orgPVI0sx&RCZWLxDes}T>_Sq;=>5tPzVvk_D42T z=l~kFN4|nG<>+0`Pc%^glSECZQjGH{Ny7D(Qsa?ZW5SGof`pvHOnQEm2yeYUb);gr zaG$-VTy-KR!9;>-<|Cjn#(Q^yMr_(JrDXYv({M{LPlMlM8(xf?tC%_=SaEBEQ34}g zlJO1i#ZI6YWW++&PCd^bK2j{QUPNAf@SvqL>~3Drceb1NbC8>sm#$nEU(Qx@e6E2a zz5q5JF$Bs5n49YHLvp~UC|5J4r|f#3Gy9S&>VSS)>&+qkx2TGIPb3baN2h3Z+K>y)nExM5 zQ624$W=poZJBE4wN^bA-aKqDYxTB1|g%nCRdiilzX6_X;4I}tZVQ5f)Qx?BJ40AFi zz7}R5nif0@%>B{c&q+awr|9{9m&Ft|HjscM^J#WTxt`UsLoLlwiTh4^6Lo2?fLAIr;!$=o0Lpz{? zqBg*^%MB@di_1;-au$)F|I1H^0HS1tTQ}lmPUkxtEf+Q z^0Q#jyMc@n>F%#(vXJlmGZDwbayn?DUk^fg6XmDz6yWaZno%)r&A7##8k zE_@)1xR5sbA)r+iPz`B=&-t`BX5ZEY@&z+sECLZ+6j{;Y*4v2nc7+nTv<5MSri52LQ z*>8fR$TdLmYiUzg_8I>}*s$%&jEwyDG9f4e?F2{!dkWmJ0RA7a*z+Xch$OArxB4d{0hXu42mclWx)=@|*^f(61y^z3YfQUD&SgVzl}P6UJk05M(> z3(bsYJ8085iMS8-a2NH3GKYXMk5}i~)(ihXn|zu_ZTj}g+)eeuxLC=H)TpWr?l3Ig z@1ES6qhQqi2GZn0*_DJILuPz6`vaWL#7-H=w;0*w=zv9mXf$c_fES*jupK z=zpXp{^84WKW1Snph)bR)*uIGYlzZ>aQ%hJ+3h3?v29^NN!~)KlI<46m!riifgQHG zwb-_Gj$nD#AqKfY{`$I*t0N1bM^D9r-yx%&xVp7b>P<{0C9;kdRY%vydhVOUCr4L# zBO<)>dsSTqV9h0=hu#mZIoMqYb5Hkx_F$ZeVdDE5kc}r%@UKO1;Gm@)Q)!{^LKFu~ z&QfVWIYB9elAVFk3ZX7Scg}XoXah@(v@wHvTw`j*HRng?1%P)F~b@bKhLrrPUj74G9^}a{6?Md>Es~lS~F1Hn6F3Lb-k2>*f`q)SXVM7|wcI=11ls9o{?4 z9ICmoc`u9x^{7QsQew1wQYeV0gvxU{Km$x*G`?d}_(dwv0JAqcqXo2lFdR(Z zKyaJIno46PzO6Uqnpux!n?LNh8JIk({vqaEr*A^ zIy#69QEOLeS4nUZ4h-kSK9RqTCpBz=i4}dq9Z*8^V=Q*r%=}<|v0we5GVNk;>G;r7 zRb>yqjNh}CLSE2b`<}Vy69}}<-602jLMV2uWJ7WdHsHiav+4&ml7n_>9ouK5En%5} z;X2}W<=T9255CSe z+ry6`;|J?Pr^xm_S9{oDp&66{7+BE*x|S5aeKxYryy#KN?ziMW63Mw_1ocuL!-F@T z`A-+_1=6%)uPP6f`%`ZE?l!yE7TJG)i&|Vajl?4Tn)R-8Y7=BUXy=KK6;1J^413k0 zN75w;8ts&WU%SD_iut(S%1+m02YU7Jiq^>WJjHACg3PzbuqTgSR6J--4}BWFe{1uT>G!tf3O6)#x2l z+<7>ka71yFv+Xyj+zWvR&fI}Gs+SL+(YIieo?%x74K4HAI#|TsDMl6}{epckG|Yj? zfo(XwR%|`)O41vy4)QG@8nqH;n!NYjLq*s( zWoES$yjah+zMwl89#Pe#w|^-^lQ+`cPVRUVUzv2WOFnVgv~s`Ahz@#^QY8bbw z|EcZ%IOz#q%+Eo>o+Na;oOX5QzPJ*p9vJ z&2t|k&S~;NclJM9?_ge&cd%2`GDlrcLW%k!$bWqE6<;1a6V9w^&uQEpRxCHvO%t3ufY zpsQ%`47(s`-(~qA<(7+5SPQal6+#oh+4z>a?7632rsv~D4rezED{>(o9nUaRX?b7J zqK?UI7XkTbGmNSlLIzsJq$XRNgTms4v`oKCw715o{`AvM~iaQ zT5_`9`4FqPFMwf)5P*2wyg^kBA|vQ`&B#XF?$Yjv_7-EW(I}mrG5crH2{(6$R4+%- zT6QWs`Ls;-&!dmtJk!f8`DVpUE*qSM9Oq5*-y&TuTYvY1FaFVpzkG5&TH3E>esU^} z)s{e#cAdEm)oWRH02zMdWz9(G=-vi+Chstqd^UB#Ff@43%}v>WN^KOGL%X|HQb~{6 zy)ZNlo*++nLxBMEs{e{iml`&rTrL$mq+fkfU5XWOO3t*mq1GRcR*VjPnM zToOp7h;K5T_TpPH+P9$+Ony6-Wx&tut0))#ZG(~tVt@oc|tka^!B=8^3f;J(p0 zmq+0eGvFiK&;7SR2&*}Mp7jVb@>m|q-Fm|hy7K8YLf0SqpI$etqVVG-A1Q6ZT|1{` zwoXa);j1EuUpIsWP3GU*Yiky;bG2)FhE1Wb7YUnrp$$3N*4fwl!(q#i-Lz zY7X;$gG0j`%X*FVzFVo~TdhX;G+#eT|EdJskgEIKPz!eZJr-*N4kre@6_64RWhC{v z25zB?b+q%i@8T6DWAfeZtR&AEdku^+bB?k-PhyTu-sPFz3FETZjkhux$0+fpJjHJ@ zU;0m0gy9K17xtA{H&S5ubQdb&{8+MRNH*p%$BwVc4h8u!8O1h3lvic|RN(nPPKQC% zjC6I;Xi-15V9OX&fu8cE(Xw0Z5s>q(bBB!T1g>SCg}{$@C~3OhcN>urKd)3S=tPst zx|bsntBDx_oG;4Sht|lw0yDYp#MESI*)}R%{Yqbt2ZI&ckrb6iLkEewZF9|G{PS%K z9x)?X=?~q3^6cYgH4o`$jMi?J(P?+7IDhc6*K_wl%`xSM{Y5uw)F0jyl1mP}9BY#8 zkE|4Ta1qyi%lM;>>$>hRheTwe`Jjq$YpU+EGb_tcI_YJE$g*mpTMbcD`)ge?FUoa(?Iam%bHt`n#pmB z=#qO0IP?Dswphen`p20bwvEJYqlxJ8pGPJ$P7Nk!L9mtzjKuNNM0uE3)|67y-5eD% z9eiJ8Mr$=6)}|<3{Ai?}hnj?ce`HX3{=*Z{wHa~oC%l4`d^Oqdnq#4jZC+D zi^|A;Bf(ZQcLxi-W{F2PBWwvu`UGo;<&{jl;?s&*9#TymD1Y<`Tr5WamB_(pJWy4b z7fskp_N+gfClH#{9x4w<^GN?`2E6rMgS9&``hl0P>k}+k)Ul`+Hwj6y4;eGzYTRFl zpFuoRjKzx$wUGVJWe4iEeESAuYH87{w()5*@EX#^QnYZQN3H4m4>!*fBV$XjNvDCA zr-Jw+WGRd?iOr5jy5hwDSgm)2oH0uKFlsd>h;Egs-Sm!?)Wb$rQv#i{*@$CcuD4_n z`%v*@=~YMhVO$Fk9DC!%KZN4-X1Y8?)2I7k~Zjh#$7^Q5$cO3~?=Q?$w}WO3|=BKJ!T~94j}J;yVawLtkO>aK7Gw z8s{njnOre>nx8Sr2?<*E{>}I`qM5G{}#9`?e^z7CBMAz zp=>nmPN%-x)2>e>R%5vKL0#PX96$T8Vy&6Fh}Q$ze8f(*zk1!2aLmrj5cGn^XP}$? zQt0L5=^JDzbrhoPN}*=dAK4&U)8#V1Ygv2e!7Jm=i6c9d2k*9hJ8C=2?R%Pe@j?D})X|0$8i0|fi;F$?6Q`X9{eyQdJ>bv;0*NOS2w+C+Wmv6#cPuYw(o(~1a zC$rLdxVL6v@RrXj6zNIg9v@Z@3ULp?m)TASKgjh6uAv|4^j7_J6twU+58Hx?+mxXu z)RDXp=9(4wd1rWJ!v1TB+uq?9s?awY6{P7duvaw7j9a73t8B+ta&lLk&%%F~Xu!@f zLkDfn@K?JsipJs3xgR&BeismSLAL20L%jYdB2cO(?$RGw+jONYwVwR4 zy(!1;59_0t#+SunW$pO{<8xF$^a$rt$%`e(h?ML~*qMKr~JHYS@QC**|g(gSd z`fB;#n=w(IS2gGkh}#^RI*LYrhWcu7w}ez22x~>+@3h06iw@)?J&#@Beh#^%k%)tb z`(wd>J7Ojc%=|Ic*vxg+B8$>D1-|;#=jM=L;3mQg?SNwN!vtljeGkp7p(w^;R?C#K z2FeYl)jznTTh)V5YSPj~d+oAGRo|&Kbk%4Tt|nhs3#aY|!uQw|{S7=;NUbp%zdzg8 zSqURG^Q@`%pK?P@(i>1Y){pYDZx1AH)o#Kb6%p9uOWC{%oLv?Y(*|^ENM7tmmFPqd zZ{*(ts7e3qsj2p;I}LNlZ%jxVF2ssU%au#GNigsh8FL*)^DvS4lnabe;uZ%{9q6+s z-lZlRIkmsn0AcEA)d>!T8<}B@p8fEAuf1@|OLQ$tT+J3w z%6X<*6kCc;&$pX47}HbmgEAwa-?exfZk;TxeGkiQep7<2zN37$XTJ}IrXF8=_ZXT~ zYQ|`;p$;}J%eNXE23mR{m!Z03#4!U~!VCSgrshW=A5B22p4(-8zMSj(2y60w!hF}B zEAA>rj89nJb^)<9a`w95@-1f?wN(M8PHeOSMfYJgP}6vZO&0`p(nc_*1tP;Ijq?1J0uI_9 z(Ss|rg|bVQv7m%5)Kpz6wA+)3zZcW}hm6?tzOoL9i#lF3s@(sT#{s{uY}A}HPMBSj zTnd7{S2$>K-$wk-eUGwrgv;HkY#Gd`%`HR|8ehsOX#bh4TvJJKlkY{Y`MCc%Umw=? z46m48vBr~NlBxLXJtA$TEz*=Q@QQEPd86!ButDY9kW%=SUo@O4x&^~);U{Z$rh7sHM=Wwa949qlUbiQS(~;oo{Z!)|m?x2Y zN&Z0LVX_~`^h=p!yyC+OAPn5>_bok%kpu{073j~c|Bw652X6_~He4Q5-6ob~Mq7BQ zKQ9J)gt+u9hi$i@_8-6u_&*hMwNSOpj2DckV^GA?FTaE7U4prv+{3+lj@>E&fnZL5p&unV@J~R8w%POuX-v|gQg4W zRH@nM&F~oPbFs|E6mvox!Ips5CkR0H@A6pGDViZ>f)#UoR^f+oP!A1^ZJ5f7o>|>+ zzD9$2_}94C`FRrvwr~%X{_;yCD^0Ts$2Hh%N5&V;0nj};=u-_}Bc ze}{QmP}{;&C)-n=4%gt+@2C{?yzIsYqEs>Ns9 z6*v!IkIPU_Ema$rx1D<;w_Tn!HY5EaaIsvtd6#tiVoatdbtIjj0--#NGSalF*xnkd zmFWjXnC+@Uau<707xf7#EM0Rws3`>Wb%-X}de`=AdALZUfek?~_T1qewYSPd5x)|&BR4KIT)zeAWV^Ah98S-pEnSQ z$<`T@pjsSYQVpb{!MyL5YQH?OX=-$vJ+&nK7Id!)r1j%rZOu68F&#H?HO?Z@e&hBc zQU}zQP}YxSE&;3&ZJ=zQ>=`r8=ZrS0#$bP0{J?E->or6NKM~571xhM^aA&vNR-N7h z8-169`ZDBr+r+;#Y|qr-w~*e|+um58GTJuJVoSekjqs25z*h+E0yaA;DcBEM%ROfS z)rtt^wAg)~_5g+GGYT2!!hzQ{8QBmNWnxA^yzeM$az194$h{z+S&h+`sow4%tk1@W zCRbRplisy|Na^}dHhEhd<;nUT)ReiPrX;s8$sC708beSmeq!o4g)`-LcMFrf{Oesq z@+&1#Ct7ToFAZz@p;H&kD&6f?{_WPS8gvfh;xDP|G|-)8e(N0z@?#c?F6O8is*9Lo z0}bx`x1kEvw+k?Zfb0kK4zDUFVN^BSAD!OWgifjATe0D|m4%zoKV0-86E>-t3|{Bv zJ#p&=sNMd1xh6Sv?z{~FpJLO#12v}erD&GEC%?-_stRvphKJvTa@GW24yj8JnM*~c zFZF<;2(9lIXU-*Vj%2RJ+RgYvE##my6ps5~Eq5sf^f%qMKf`NW;r&`2AIF2f-|^-*jcYB*?P&TPo$co%c9faa(xZJSx_^bEX38EkC6alCRG<%n04Nq5@_b7`M>O-? z?MF!$-Lb55d|(&9zzwftCa1#<RW#3Z}w$_E$GIu|Xkx6j+AE{aXutkZ1sKt*)r z;uUcfmNXC#AQ#5u2LBz~GN4vNqAew?&v7VqooHR>w^?3NSOvqU#0J*8${$<*L#7xQOasEM}+c&oT+44DP^DBJX4gOUXqIC@9 z3#s)9-&ib^yHTEl$PFgHG713lC_KUz*iD-IiRAp6!Wb*-m|A!Zi1CS@?V6;aOm#1} z2tN@%?E>eI4&5gE_3Bq4F0cJIw96}aM+4wu3;-9a$I-XP!q0;Csd<#eKY;5!Sq&Om zijIzj9q=OG+u_)WDs8u+&3#I+<=`Oh4md?hI`Jc;W8Zt~)?lJpv+s^SLkA<|Dn_Zi zQ%poq7`&Fp`<7A&h+T9z>06bvK0=z8a0ro2lik_#HRxN;8uiERNo4&U1P*8|xffYc zBi@`aSgl$V(_dJdza&3+=gsvRv{31pU=T0zmr$OU>X4>g2^QL{oYh`#a8>z(OVX}c zlvk4hf~2U^isO(_(#IFx<-u5tCsgc{K^z2@;fJzNIf0no1ECtUcPUysafr7tfV2G` zYU32+eaGdZ*sBQy=}iNlaAbC9bDn)}-rjzmc>H*Qc;v#pJV_Q5bln;uwxOApB~5s6aRPY0N%mQs{#T!a6F2IUR1k z_%G0h0{lj*Cl>$4{lBwCa@$1Wd1`xA{-WdEZ<81@E)Ee?N8`14tkcM3>+W78&x?{1 zo|vEgzA8|jEh3y7SK@FBYM|4_Xmz(;t{HK7_vW`klu1{*+s`4EFjM^JJhK*1frszIvqr2p3i%{{>)Q~}zA=Xr`HL&x3O8XvA^)w? zFhY;lK=jhu?X@M$Q2#~|SVEMm+G4mdpcB%bghZT3)1>$Z`?cYG7&n$RGwW2M)J@OI z!C&o4XA0*qh?~GyxEca{{KNfarw>*p84#ao?aI(MWTA0;#L=_H5vGa0sGUx+p29)8 zdmG`q#JWaIKv@`np(=LctU%9hWxP87qD&7RxC;`m&(|sK6eyoJC}8BgH^0I^UPgLK z4`7=aw4cM_O{WjX!?bMOsb8+l;E<%O4$#mWb+#RZ>JPFc#->!n>9e&;uU(9fX!z8#NHBb! zVWg&qky`m6xpJ}f`e919du}v3K6rwzbsfU#ug31r0AW(^kGJiPv!(JI2D;mtBFkKf z?8)P;NiXCz4}Tij4C3%k1Nni>0_|JloB5zSX{^c;ZvZ!E%z)n@*HgCrt!J; zS7wWUzg>)%3>*X9$&shK0_HjZYW^ESe;tDnC*I;~B&sDS?z{X$wb)ux&9YL>1o^Y` z*<^1-VYbBLBbFhHlVLkuT%n1S4((6!>%iPN-~M$nwd804%I+8E;6g=|%gM>6gNOvv z5xb2w`6bH8<)(3~tD>y(6R9p!0GUwgOLH82cjUka>LDhTe>p|)moiwp zr|U*QT7J{NQt(iiw}X#D#-F^XLllVBJj3z{di!aDhlLo?K7s$fMsh6Y`6eGKM)Bt< z@mDY6UQJZOLiCKyQf30dg=tCVPR{pwUBMc0LHdc;l*WcD=U zULOoDm>rY~AGwzMum7#xa@PNDBv7s(&U#0WP6NSzB8(9ek?1Ds@hHU1!VMPLJcm%0RzguTk`Mn&0xu7=#9>7nOci4JLB+1lZIsq@H zpq=oY)>YoPs_(ZolqYu?-X;emhKVy~w%W|4=&ea#MfLZn;XWh~mi{mqIE@YmfR5IL zxnE(fAZLm5jpmtPhCT6Jj)DRggH6)7%Q2@cfw5x5K%gjrMvuXPL+}&(|PpkCG-N(x`DX|u) zr5em~)sR$P7or*Z_D0GNjWY&+n5$HvAIdS^k-C?@bRysAqF(P(v|O4M!d5VF9}Ar{ z#FMJ!YzdTW)l`ubp5Bw z?EzY^vQ5~l5o{UlFEWue*at^O=!idbdmRcD7TgLje=u&Bfhc@|tUIs*e1WEbHr%Z$ z+-^N?MO`QmMfRtTqBbNs*1?(R0lEBD(qgv_eB{->r&NlVuR2jry+u*Oz9at<*K7t= ztC;qx*k2&(c{LJcs6sIpD2y;n!e5kr$ti>rqME9aeqUPuAz&f@jsNEwV_NdVIq>$j za~XPT&z3NGC<|m09=$q@0J92q362S+Dc*S0?qOK&xYL7Zc)l-cu=H4|hQwM*5=;zF zlAQaK6Nifx%~DxfiB5g~t#b zBhDG8VE&2TtnO+bY82n)Xr6&6uSV|nP=W1IcIfx2!XfH$AxlB-kH~Wub?77QqH0}< z!VupvOjr#`xs-G#(Sm+Qhd}!PY#7h{Z7AnOW!SPZb7yq4=v)4N|LPe~?543d7C6$*?47>}J(2#$ zNIAo$SNF^yHua@6N{(VRWtP!i4R8?$65P-Uu0u}j2G(vB`h-g?qwU?m1+F5LgG9jz z_$XKBZMcg-j&Gw7bBa`^uKy16kV!f_U0t<;KiQ^tcF6x#W4f3NyeaIcqfIdrozbhN zgpW`8RL4N?L-bz&<3Yd}ExNzhc=V{)eI^RSLTMq?qW(}_S?GYKs%_M()?+{N<9i+z zg`c1R0Gl?9O}Rt#V_S5U*8$Qh8GMSot6ckz)Sc`Qg>yHrK2^V^G2$(SQoVmE9;=d5 z#`A9NF~Hx`ZP=!a1O`x&KEe_qfSpz&^FhjfVlH2SJ)(z+5B^5I|Z`qs!)uSr3jYSw3gBRmM!IB6#7 z0p6gu)(^TM2L<-3)!@Ivq)#AY`O`UwV!*hI=*1wgU*-TXyn`W*vqijdjfsKo zu&C^aD=3C~Q3D5!za7PGO&l_Uz2GBw7H=wffV!ydxZ{(KTLnL`ZGIqcVG?8v64RxwMu;Y^JD;pU_`NO`!Dn zbMNuJ=2)g3+gDAGH8JL|*B!SCudZCFD7B5xqvd_+m6|t1%rG{pdu)9#UOyy>-YVuC z7bKM+9U!D9D`azhaT%CQH5Du}+#UTx0Y8&+XhV zS9Q%liSbt?JBQ;X`{Fvt{79}JI$mi2EKI5-HQoCR3oDs)#Yny}Lb!1GoM@%WoUtrY z+TQmB$oURIae)>ssbN{EXL+yo75)F%h^$~8%17mll(IFz{Ee++G!N$bugkU(q8J)X z{Sm0Z(B4$zGtkKN7LV`1sKlqf&nX*v8xMF-P0fOXW&+-#E*{svmdF?#c{3PGwY`b| zIgR0D_?=%JvZXEdLai>|e2^g|%tPV9Tg>%UyD|SgsI<#{k!8@utqjnn39FH@xhW*G zrDUc2c%?!`hgDzZB%IcZ5O+SNq@?N?S z3Z2YuL}Oy%B<`(Qs5GY8=b_iE$NQ`G+<2$URYXsF%arSP072gA?odY)O z{QT$P4@dgfIwlb0o67yMG=ME&x58=s&Dc_F=({c9Mkz@$vCMYW^=Gm%lEc+=+P1Rg zM>N>F7cyTiouwJS!)RX^cc<~~$0YC`1Ft9yQxr{Y0MrO^MrAy0`?e@{J1YF@Q+QMO znqxNrUAbxsDIFYGih4mKKu#*ORhRde7G%B@MI8!?#jY`hg;5>z`jz{8PIORpg@ET< zFpF^=x3}h;MGutmOP6wXbZrSIZQX<)Z?j{S|8`=rCGD&YD9(=nd-&v>JATy;lNL5s zL*X(>qPFl;G4m7YOZO=^d~2dQ>hCXCLE6)0x^wvq>dCRLZ*Rr!0`x+X{<=pHheYu+ zbAne2;L~Seb;)+Rff4!rQc^&oz(-(s?g(#N>KhD9A93_7Mfu&Ehi?tv9+NF`w%k;>EQd7bzQ#a#Ctc(-!Guv^D!1cet zH9VN8OSSJwo$L(~-_mbeHn=F97aWzdBfrAXUurn{-Zc<`0a}irfyxt^Lz1CyE*hqkI%I-K`cI!G?USq z_EGzoDJkh?cade$#7`d!_h8xge0*+{NiC0;&@!5~>6)^8{nHhMdvr{_p^ z2LXYFWz)~4oNMJHF*c(@xV0$vlSNDi2RWHA)Ex#n)Z3%oS{Fl&^>A(CXKYym2mdo7 zhO*R#XN0z4|~??Q(rr=;5= zYO5QT@W+&mQ&!pTsH#J(+th6f$AhrA`j64}_Y?55&nv(LWxk54-f!K)FWQ-y_~$pF zziN4hou@>2a_-e{9{dNIZBVCI3R5Ok%l+0+nGO>C;s3k2Dz*fjf8E^9UXZ!@jpCn2bMDV`;ua_H~fVa%9$U2hNvD&VziMt30WAd5s z=?9y{&m;YYn5T8ppNihfn%5?p2%cR477u!R@UlC1AeMinE$X<<{MhYjWoRP%<~OvAHU_tIPH517OK3OqI%fB z-+9lCQy5@oX$?P5RA@#YT=j3mDIHW~N;)^u#;DGU%`zQ7gN*idOOQKuKk%*)ebpe) zw?x?@&fF+(AEn@NQOfS=h9k#@YUrKLroXEQ&cu`TTxLLFCGem(XVU%n(tYT{&O64cN$tN~~$1 zzJVu2F{>8+O%ym`+Q+B9Z#}Zr?nBCpIw?AsslN=(a0^quQE7P?8!MhHG(Y)Ex8f2W zv#K&&^keaoica1+0+wmKGEvPR+Qp(x_yMtm|A*gy0-VtjT3o@X4UY+umwtEfqA~$- zqX@kg(}4P^WH`oCxX4C79*nytK)7xePs3Sb6>+%N%@P>XbAS=1@O%!Et{ ztO9(he?V^giTx^%X6CM^UR*Amh%r~$AB4DnWYf{`NrwTJDV;MMv-Oxa463g3 zQFraafA`9NO`gz?uCa+vuo%Y8XkH!S_f?l+Cyc7FIE3Z5&9V#E+m0C@hW&aK%ay`- z<*iQH^NpZPPuzy3P2p$C4CAV?ht}%OoxbWu2=yiYH_6|H{_M%`y}H<^&F`;1dRg5@ zV{uLB#qO+eIK9j6-vhRRx0f+nX37s!>;~L_p;V)9-p-9qM$k=P-Ukb5_X6nqJOnDG ze}kWFrnlJ1@ac!1-h2R`!Oke2U*4|5Hch(Ix!rq~y8M81?lB-PhYg-A4jd0N96e@8 zL2`yy4fN%=ME~5Yr0_Lb?P0!rM)3S(OFN-~zUyXcUcA0l6FNpi`D(g5~YP}e+CCup)c3Dy)sv-+-WQ>n#RJI%@#3oz^ znTM@;f2dXef-uYT%BX?4XqnTuJ%8^I+sQ6(Autwx+-AGbz7$Huqa@^8a@B%PB;sdT z>~+5fWj(+>yq+?TO5#QS8G!b8H!0T0g{YM0xcuwJiMHW6G{n}Sa({c21KzJ}^oJ9W z6)8((eWG^h{~Nzs+pa@bk0|EYZ2uKq`I}u0$E)|lvw3W~Uzn0nNbOgn=J})dHq4je zG1J{jKAi4zzt3^XK0c?!Nm{>P5ge|FT(&OgT?^n&=&YHQD-NHsKsh{-+6#swx6+-fTe{OJ7PQ7WSDF8$oL zvX0%8EmjAkg=-g1p`$`@Q~yW2I#)$o_uz19&jewmTQzv#irio(TdDV>RxQO? zX>jl_5ZMFFe9pcXc@>8JC)$}czlyQKj#l#qCYsrvq~58=jGw;;YX7A9)uYIXyt zVI%BhC(tOl>Hi|AWb>T}OGa$p%y^}x)~MXOTXeYC;B|YAt1>Ov)~qv2`6JB}KBWso zHbKQ$k=G}s-I#foA~S=l%mUvA4NSO@!#Bjt_4%r?Pk-8K8V4}X1`LdyG_;mc;Xqn;cJIhXt;0EWcF(B(aOpE2=3YCIX{dkOb z2NbN>&?w02r!?Viy_q!lbKGy@`y85(&lZ6f_pxZolY}P)-dZ?Cc7KdxW|5hUe#Dm zjJ|5opB6_JoP4@qHjhjzR^Vk};eZ5AvK9&NPm-MZkO?1=pYy>cH8!p;SBM-@y(&mv z3>iD281Uqb0{-Ya@_<9+mG z5N|Ik!(j#X{T)g*L67onk^<*TAA4;=yT#fwBlnl)gz59S;|SX^0YlGbt*boX0ob#! zqk^4(txM22KplIDL?jR*%_Jv9JPfYPnMuyUTE)pn-HTi6`E1)6%c^?*UK0_T~A?Kn9l?L}tks*TsiPK5@yr zoK;T4U|n!2DH0q*lZvd1@7A~^Q5%m(I&mc+&>NcfU$p8EXg_CN8#OR95z`#}g~$Wj zSAj(Qeu!^L16ij6}fVaUyjicKPwlFDEHl|BRL>{UVnk>fRbF}*gOjJkXpJ; zk&NHQtg@y5n`5fY~(StE)JDC z%Ib8!t^6GJSdbYne&U&qh|l}-LYIFeBz$5tseqEPJ32U0E>QjKajhs4A_Wb?&ur@nU zc8m6Lq~RYB!afL=4b5h5PXg9(Pqhw^+v3~b*XQj(P~_1^O@dX~m(`85B9>o&Q`2pM zq<~e_ZvK~l1o3xpeNxxkNuOb<#77;?Mz8KJV~D?C`#zB4WBZ^yVI7T3rpIu#_Zgam zJ0p`zqFxxwI<&HRlodGLoTV+G08=*S?=B-?WcnO@!hN5$Xlr&X-6xPBdm zbk7}SOCq2c9O0)FQIl#w1XK?CN26mCxGpf5?eh02sEwUVz0xq_e-%Wq&S+XF=wOC2 zwkJhA3*$;6qV?8({Z4_MoOYum-ytPwY7a0-yL~OUK7%@LQ$p3V%^{dg@4D>y)$j(n zCfUrmSUvlzKN=~T?+5s*Q-7p~U{o;6@UP%bjt)(RxTU;0q~FO03x}Axdvj=Hx@l6` zj(-Z`{Oi+vf~59E$a0gS!C1eU07?sQOm??i2(_{OLQ`9Pbv@z$GNI!(7eSr;Rq-4k zE`0+HvY3;Tp-Lnz>a>bGlZNgM{zGw0UVVx2PQaD2akaVt1|I7z%upHYedqwy&sR?IWSIhl z`*wwS{$j(rC*j}22lRQC_HT^!?%cCJ>hRyOq60SUjpX~y{(kE~5+cVv zeap87rroyJ#WK%oiIQ025Xc=Gi3xH%ZXx?&dGJK9Subr%EpFz+`a#Z@^~M@_iN~6A z7g@jitDL9zFqucQC$#}hjJ_KV-39t;sK$w~L;v-w@CmCfr{%*(dd;`eYUJYxU4H9V zB__tzAyYqjUW{3y!sGAg%}-oPzV2S)uP$M{05v@N@q=(a&#<|4HRr<+Bb;vcg^tZpnrt;>~ zUn+d!_~gKG^832^88!F4X`H7u$_k#=>D^{)+pxiXg$tXjtW||6{#2!EQyZgtV8ORe zqH?;CpRr}X#WC?dnBR+RL11>w-zP=XT_&bDpaTWp|&pzXe0ke9qwv4xoN?GVY76KeP3_p(Bs=G+9%sqTkn?NFnAM3#PMCehH=>_f12OeO|6}j1g6fF2cF~1P z0t9z=cMa|?!5u=7;O@}4JHg#uf`{Pl?(XgmLC)HB9`3`f`p8Vs%8*Q}DAw(sdc(9W}(dp+6CnbG%TC zGZe-#mvGBX=!s`(ryr4_glzLFgmdNXRNxYhlIVxFe{S~3(j2mo0uuA&H@ziT8 z-98(cX^V$BvuY`*o8`3ba-FP0NAX6HA~)r?gj;V0FXfOYtn2Il*xBMC65(M=!tfx+ z`G-tfn7e{uoL+mX+kOu4IMT7Uqt7G$pejv(w1hkV7AB^tk^2==pI&6hOyf!Ki`XRC zh7*ixs^*GEgRtv^OShT9n?=9~6)B^}zUW$;BSb@u<1O8ufK7gMwzWUsfci}OqvGDT zHkvmVx;@qlZ0<=zRy*vV44}+Yp;Y?PneyjGljsBfmJj85+8yvVSNGZIAGU6CwSJjL zZ#49?O6`%X&aEWo!NI=jm>guEF4*~J%-i?CtAEV41`z#inVqaR?+WI`8Z$(<@Bf4b z+de_>E8B{w&tP?^p&ImN7Udt!BWU?9Z?3iJouOojE*&?&WN3&Z_0q}Qc3`<)9TnYj z-kBDB)kX4Qdk2E!Q`jgP1AVD-+3Bb1{Vy&z*ZA%F+uY&ZK3Q;`bEpXaQ%^Xsq1iE# zK4IXf?j>4F9y<<2|Di5fh}k%165)6dg?LNv=S2ZpPKnPIXML@t>95e{2zG}p87{A< z?+*{CJR7WmHr8~C%JPVCNuFuQaXejng;hRP{tFV%DF(Rgq(ha5Ew4md6Fh@pr zY7q4qhFzlTvgj^^$On#8wLbpp8!7X`hLPU~ULPlXpF9|b!C#!S@Gt+MPzc$$$FSsqOX#=NeI2uxzh1v8AO?b@W7}MY z=J%d!5>%02G(4l?nBOR&7--qstQG{!aWTz|?hx8YKH^){Eltt{T79Q z!H}@I4K7VROk!nRczE^lP8ELCabYa+m6t0qyZ>ZMH%jv#j$!BiN+i;$*{pATKroTV z6p*FSie^U1{3f9#*_t35r+A4Nbu3HkkNF4N-br5qpB`mEXH3?_XWHsZp(-S z0z&0W*S_ao^2X525VXJ~V<6g(MZ@6!R_&zNXW?^;f+)Tb)7(+F=2p``5N(f!-CZm57djTeEx7Qp!ri!I=600W%gX7!2B3(Y2ts!2z zlh3leXxOf+HkC(+G}y=~4do|%l9PFMH{IW@E&tf^X{KvkyUO|7tUJ%j*P*^%ZknPy zU)4&#S}wbaC#!pe^$t3~Dzt*Ok>x&{hB2Kif;ZNJVBX6@5gNfs7CT#+RE?ea=mN&D zDvXthUUF!^9v!6r6lj}|(YmDhcA`tWu94#qOY~=gsY2|y1npFZ&?g_IZZdB44gWRU zBq5;3s{Y}iqLei`>TdwQ3cG2$z$GRmKbaAuG z7^qg#N5>^L{bR)t7I#*3pFtk|WvgmGL;d5KwNVp7pV=B1XkhD``LeRL{tx345bNjV=#HJ`@An5fz{^7RbPM zGBS1aB~qSmC47C?;U!6#v_9tH`(v+lng-$d`GwSy*G4Nn(srVh_Fe(LCswj!lmv{k zF0CA-)nQG+NDJ{`g#Etr3sdbFIs@VyQb^&NQXP#JcQsU-TZ9BDpJl|qpID7^`nkNB z#ww*u==#0dO&u3}FPzC2hf9Fhb}L#63EyOXUhAXh(;f_##BuqQHM%y3%pq( zHAEg!O&ToIgu`E3{b(q!rXNR7kgG<-l{F7w=5EvKd(r#ecV|H z=lD&ojxdvSRVIVdMAQH{oyyYrtX6KeD#bb%c^{SJ7H}8KwSj^b~~ zT9kj{h)J=(p+68*Q&gl8rOOGs%*In-cTw4FS!86-g|3*A%x?jh^x6lZ%93okAZt6e z(1l-XezQUHdxTf+2{cbp*vlwmX)-D_b=+ylr{iFbcL^GLUf4@Bas}h_WtlHu4oF0% zz^_T6YYxfUXQodjq>Okw_Mp{xxqrf{c}RntBij0))qE+a85oI=;W`hg(YNm*DbOp6 zNIYO*Xv7bC91(#;*J|ejMbDvDn(5vqM#*Gzu~MF8=&|=b4(~eXWoRo}8BwE8Nn~#I zy}Yo~y{)o|TphJ`l!-T@zlS@oym-G6-!LjkcHz;-{jD7nlD6~I4Z#Sa)Fd-B9!?q- ze`-fuhL-z8;pJaK_XmPkgFJCNab5;hO9yEN>V!a?ueTMjOb{jxvWzFJeKlf(GpJEO zHqBGrtDNdTNw~hU6=3T|axM4)X*~pljcz*eh6{{xY8CO;u!pg-jNge&>(Kj}u<>)(X`2V!qshS%swq_v0IE5T8@ z*I*B&6tH6>mVSv-nL>X_nCaS#t%T~a|Mq3$T*+312}&Au2@z`8UaN=X8-hVNiJK8) z;4p{Q#FraXL7`t$o$}~1X1$la(j=8WJmHWlsC%CPmM98=ymOjw1WjiaY<-Cn*hHU3 z3B(k;blxdq^JGnAaPFQRe$X;_@N0jzp^nR%vLqV@xnzhB2(NZZV|bgfEq|&ijuSC( z=6jSQ`N+5nIp>UK2xa8VsthfXNL;=8_n8eknJbYXbaIUBxhnt|l2|gRm!X)mNA^I; zNs~JP{`PjneTF!AE+l^K@M8$#W1y(XvyGHisb$Y9v4drz?^p-KVQEgj(;&br27rufs}w0aRjs z_T0a_=)I(WYE2l-KsMb7e)pq1qn^x5fE!XfVuTw;)_NyJgVJTm=Aa3hGX9496dRX( zb)j;DnCujln(K*BNb>5N*$`-%NkT#VMiytP?611V^6Hz;5UOE5gfw)-z$#)h8Lu7( z?0VcF2m<~bA+l6xkzd~?(7Crd#qoqqnG#o(i|F?lYxOC~jeaf;QIvkT>>zoplg#HG za1Toy2{ngdv#e2FbOE6pkSl+GK>Tov)eENFq=u*sqHu&yC64=E`w;pAMe8c8GIZl6 z72Mnh{TLPN#5{zaJHhpUs^O>R&7}s~NK%Z3nZvo2+sTNxZ)=7zw0iK_P%Spm=;saz zNxS0Y>$?A54)bgEz}11Cgc4q_UZ`ha96#i-dT%=8;;(M$|3Fx84*gt`+#IIWxR!P>P*&PR`!9e7U;X8OdO@+P`IcJVdA@P9=Km~*t?liqfRE?@ERF# zyT%uH9yI)LTzSN8@Jt82ON3Zi#Jm6Qc>Enc3uE-P@N8iP1Y_nZ`EE1Rj*;OQ7GYbl z3c|TCgj`#PMVOqy<=hQE@i5dw576hfQs$Y#9N${GGhonzcDrlyXFvcvF>Rm&)Dpib ztM6ys7J`8s($yOrz~4X%Vs|y}ju_`KI9-@+_5TaFs)g&WUWX7V;j18@GDCh2Mqn|2?w%_rq5ZCgG^n! zmXP8^^MEyUKLs2~W)=)NcJ z2K?Y_DR&2s0ZBlb57ETV-t_Z8Fz8At3I#N(MZn1MawYm7G&5xz9Q*ene#?KP@_lc6)`JAUq*BHsSw5(=1R$J@#^~e1;V^ zj0i+V!Ut@@6D@Z^m$e#R*9m{1C~t3-)c|Gr0wk<8qF9Twu?n+Fh}DGOglPRPfMYi) zRwA=40Q!xx%NDokOTz{t>T;)YJ_^L?40%L0e#Iu~H_=0)18`i~uZGES{`E#mvHC*L z^T870Jyap!DEV^|47Px|YS5M0wa#Ut=zrt_fEfN{utW}Q8tFK@@*bqKBwjXr);7T} zOs+K#8WfHezw4YUL$U#;xDkmX=C}h&Ehq{fT!O%8PnZ$JOZ|R#lDU1n0rIYaQylDZ zDQc9RBIU^p9P`OyZ_1|d7&x~5nW~`4mht>YIW`GxJFhEawPK-V7R0n8-L!#|9f6}9 z!28zEEn)pgdaR0)VQ!E-G%36Mn7cYyMUBZ+I`}SUpqFGQG`7Z7M@?_4~nyHEZf3MEen{NKfa9nm1V{ulFf{J1~n-jc{6U+;7GBX2($9? zC<6O3#6{hS-D?K((T{NpwXYiDXx*zD_U37nR&JwjLX*U$h46#*CAyb-}}POh3f|WjHkd3$<>CG8qUI+={>lirmW*S;9v=- z+zjnh)j*ZbG&f^FSjkbL!3_M0si742`xZqUUM48_!X|fur}(zQGZgN z=>#jw*@GtRIxlLJj$G;oY-y&1k+k8AXO68ox{ZwN@q>t1QDcTK7N0M@jm<&77b@*2 z-0p|j0{ORzv1;3ahrnF^PDFP;01g^+W|m6B2ct4ut)bx||E*UzB`xs%2*LqoewCNaECYUj??EQ$gZ6YcuZMwaBlQ? zO=|x__%qY*-obKwlt;!*XzsPmRx4ab_Q@Iv$Jz+T?D7Mumu2;lMUro?bu5ykhD_@) zJB^zr&}|C#_w&y{8A=3>rDLgFkr1>gzsxdeBfX7E9Dj%B9WH0Rjvw@dDgQ#J9Xxgf z`Iu0mNLiSeaYBvt1i2A=ftJ?|J3b~uNB^#t*EqNkhvz26J4=77V&B>qqsj^c8wf=(iJyxpm z9kQzRv?~+~h!_yX!Td*_!bDK^wy_L%^4PwGB{iw-u&7R^>4Vk0wdwFX6HGW8qsSGw z@@vNd_e1w1(pn3`XSyj(1^&&8n|=H-O{zvEiEaH!-?01+4A`Y#B4i;Dr!BCqk%o$Y z&G4Z2h_qZ0LjcXxP{qn1a2_V&QJ!ie8vB2*otFYCA zbGPG-Y;&0{hIo<1dOkV`5o?H{X~sf4dZq1=+|f`eTkO-U4H>6!d$w*6MbO+%)RitC zSw3nU#2X}uKR-+CZcXP{k*UKTk*pC=3~diwB--(zqHllD$}Dcnq4CO7*0>L3IGHFX zn#{M~YqiA<0#I9ycq~%0VK)p0!_$}syp#uRhfXP06Qom2@Vu`$hQq#$8pS~F!hUWYaA?XdBk^h z?L!Z%1J-wrY;WgZ-mXzKY^71;SjKXNjwD&aRQ7|0V#qsC*OP7>SnCp0^dksP%wVqX-1BQNZX8WDgXUhlfU8XlIs91AwyC0RV* zWgR(-ysgX~Efnz|Q)<)iSWbQ(%V54;Fwi=1vTKsRtnJWOKEP%esa{<~*zh_&ztBmo zHXhIewD#!jE_>{?CL?cL1SP(#=QDY}Kt8K3JEWOU5o*r;^c4BMuIMRp&2u(#_bfy} zUb}e&slcXt&leGYsm-(?Sdh(>EuSf|y15pqVsL}%`x5U5C9Hr)kh>{8OX!P52J}q! z{6KwW5OwXD%%?#0#Uf|kHh1`j^-zf^P5$%@z@;H(Rg!7L2+_y8KWV3}1>~qp|8c@; zBxTl|jns+Wesm3bm$-UxAN3W5>#`+Gg0O!$4np?3T>l2!1zrn<4|K64h6_^CD){Ut z*V*d~BGAL1g<$zyb_8namNx}uvZqf$T%FaVBKvh3D8qK?PR@iAy7$t^!*yXM(?D$j z3U?^VU3f>taX~8XfGOy;0wWJ<>nVB!#Pg^O7SWMOSwKX52(u9O_Yz>cE?>GqJU2w( zF$`V^grLW>kYiBG2mn?;>D%KB(xU=_NB-pl%P2%-VEK(D>miWXu-_RJ^)5B<;wPiR zaejQfzC1O^I@+^Q%K-E`Nb%gn$Gh(pQlLwJ!GOkq7J;S+BY{6Ep@6}ZP!SLCLqtRy z3y28QR>5G+6L(tZ+&DRYyL8X~TJ73eQC^{{?$%y!w+ip4OHhXjGQ6XL>r!eThPb-7 zLxAr3Hvnz`{t*cKGYNmt(_vvW=xK190Mz+bE)05|SM~=1PhK;@kXy7W;h?ABV@L@5 z;tcSZSYz;*h6JcBAAB3=E~yS|ct37MEO@_DGVdc-puj|6 z{c!UKKu=mR;vjDkX%f)8PX*X38G2;D%}pC}aALEewo;0nK;ACYUkRvx#g7ueWyW?uPp&#FSjy6 z3(Cfehxf~AlO+Ke_+|)$GPOv*fIhw|kbr!J7*Ij6xz+igmQ`agwl6i{qs8nTL2XeC zO5jCg@z60qIp;sgK}?45-gWLTGRS^!#9%Om8o_Wu*$YElr6Pbq2A;qu>Dm1P2cseY z_F2bKhX!Qu7!Ni@5&^lj27uiaYJ!B+&n!102MN9i;X~N3a)Vt~*{cCZoO*x?(?y*O zPXB844(O@L3OxK1aU&{-+i)1d{-c=(st6(`W^4uBM+ZnIJ0 z{XTwzi)kMT65k(^4*rX8v6%~cs$=E_RksX-v1kJq=+~d#-$0p`gAl+~3pMyaE8X3F`h3(X7;w^- zMSXKow?IGhFXKc zS^!>C6?5>Cc>OLt-XdJ^edCwJV#HH?yw4dy_f=oShRXOw#DG8>A8KgFU!BB(;R#RT2kAV+#*$jo&ExGA2Kr znwJZY_A`sF@y;~)7ExaE8^1}$3m|1|{sj8H*P7l*0;kG9O1_-ed|5CQy{n4Qlny5< zu{k9^83&J)BfR1;h?Cg;g6)^DDQCU3^K1&w*@rUcFoPvW8Gsa@7-}Kr?dta+q`TI- zS?n&hCe|u$gDUo3#ke9ARv~;X#`+yug&#G=e@EU>L?zVy^`{)^kC5s8CMuZq8Hdx)0_Z)ZcX84tJW0>jODJyZoWS-Hr<=+HeCYvQT8XG>A^C8|+>>^QU394-)2jHwLy0G3X zxy3MIdQYzb@yGF=a+}Cyv7aCH{r^n1UBj4d12;(*9{qMnlQ$73 z#q{O~nQzfQ{(kNVJ@Uny2u*$Ge70$-)!iLX{)`tzFXm89zM)CO$5mHl*5n=~%hfCa zr>nzgeLW%2G(Us2KXhv$5yG$dFNYDYv3ovm2%$F|73O@qKWxCn-ixLh$P76Zb0C3| zl68VqYVP7_V>$rfGHQCd?Neam3ce&=1!YXRS@HZC&2EDQJwbpI7X0>Xm^<4cv;;u&(k=MMk0Mqoe_jUEeB+>?ZRl`vCb$YPrWx1!Qs!hnD zERz-B8(tv*s%n9nGz^?4vp4!*bl+S9|r!i(r z_adR!|I|SG-ES&k-zWZN&|-kmPTciRtKX*K9J#r_TffB^L%|ng0kbLfHKMkMv@TQOrg4AU_A1-0!$nTPLuvx%!d{TH;<)hAEC1_4p#bS}-X5?ys0z z!MA3;w_N$Kjz6NS{K>&++dp2=lAIigZ!?{)!x0GkPt|>~u+$x|IrjU}X-~R>Mi1B^ z&v-d+la^e?<9HL`KAo_j$999fnrr6mdj>2RCtTSG3bCtP&4F}UtTXJr5OVg0$awxYd1 zw`obhNKv(8DtYesbUA`WJcqfUKSwxg0WP)6Jv}f`3IMgWRT85jG5Uf)6HXR=m6r`G zbBLRNr0HH+byI))=CuYNQ-LbwBaSgfdFv{faib{DJ(Y^DYTs`4yAG7M zVIU8eyw>Fmf5hs7SJP8s>0|i4k)BnA%zn^)9-}K!SAQ{$5D|CAcOefxDeK=`+TMUd z&=R+}R?dufsTg>U^1TI}DqQz?|HmEa9#-97p9hdiN?QmuGk54#lsgLdf8sIm_LGlW zpIW86bAii~2S5b3_B3mPB7yCHYdh-uwRLnmoBM5VB$X0^BwNlfK3(=NW`=DNce|AE zY$Suvl4naHpOhS6kdBBg^wR-LU7?lyQ@f^nbgk8e$vFq1-33)WvD-IIJer1pH?v5J zXSvSR?`nj`Zz7+xf&YMYeA)63qqlhLMl};({2%f18N0Vgw0lfI;72L7eKM6zcPeY`CqYh$SQU5>?ze#7Yq)jFetjv8B#?EkmiMJi1 zYDrg^QY4XXu8N7an?|CA|BTryGu^@;^$c;>7Ap)C*%bqZDV#emsx9v>klPhDm>V`H z^80+c$Mr~0-uQw-vI?o)p;315&|eDmgkCJnV9SO|!e7&UZ*HM_xslY|K@kQv>q(_r8{MfD#G_&UbZG&#~iYg8x_n{zSJ zR1k(ptSfNT{$oJExT|NcDC9}i_DLt(_b5iv9By)4fT8@&=d!|9GnaY%%7&yAPp!O0 z0t>qwvWcP)W_XV~GeSRrcg1q;8RpyidXGnU-%IwLd49IYkw}Z*W>;6!x`O`Op#&c* z{BsW=7dt-k_vYoN2Ij=-YcSD=u+VSx3NZ~yBI3OYOZ=RLD2(yX0pH2O1;#oPe+i+eCDnUDKhedqZA!Vzi=Sa z8h*2~w)x>KB%>tO{zltWkrnCJ!5iluN0KB5wh&wjRLd-y1@1hO&hJi*!)r1mHy-zL zaWq!H;-6-xNwhceKM|bPy+^&wWh>7|D0Ei@z#CQB`@UMn$4>CL^AA^%1E z6BTwQ+u>DxU1Fd=92);%?indVRgNsvDt63$H50h{$u{2OC`cpkz&NmSC7dU@ybS=e zMlA;mz4mXJpB*p?AbaN(j;B|ceK3=N_C(o%Z1IGK=;(*fNqm$Jak5{DYviLZvT^I| zaWf6wk>Y>H<{+tP!#^dCyv6uhcB;b?^O7PiiKTM#MnV;_pjWXZ+<6uM{IZgQ=IVJeJ8SP`dT5NY^GN_UxLNBu_0ZUHhOzG_rYDP`wl&)QF z=riL{37tZWJ}N9u5(R@52~-qS2xr%k8aDmEnwjSPO2{sk9pb%4l2-o^bj~UG0+DG! znpNR~*n}sp2w1#;IpN)CJd3Dlz!Xn&PS_+I@uI}ATmJ{f`D$ZS(c=o=womy2NsWawt$8^8zl${XfKFh>Z<>o@aE){8fNB)IK(&@lmS6Q z!o7$anwBgw;ce?d#fIywSUuW*Qw1rk>xh2Cspg5=Nm3}~d-0q|T8Wnp7{t}52S>vu z=PSv7g7Tznwv+$Vn>l%&V!^;t_30$<8?YSkj!%HlSb+A2ye|<1F@GZCQ&ep$HCnSG zoY#Q#H}02 z!75Y1LDxtKW6vi$q43iNXg{cPP;_LTLc&`Ki_{HPn9!R|j~qO7SM|hn@GPX|Amfs6 z#B8uPX)@eDxQ&xKN6fg8I68{_2bwAT>}Ub6E<4;X%Jd@+ly@i;))Z0s3a(wGHCkKr zI$>D1i3{g@hM6PwF8mhud=_6Cs5bwviQ)FJ?oe(T4KT`rxLZiT+HyxAbin5;*b4<) zxwU#TKW_U&miQcqjjr~z@cjSugKz5DTUuNW_p2!us@TA~npsp5!27cdwJH6%?XeSD zAag&VaU$l~Kup1e!!qfpWlY0_OI|Qqz=Gw0=d9n)T(GSq)8a1M(-6)g`9B3^|0J(s z>nXEO%kKb}#=_VXD|3McFwx(W)$=HxaptW8#>g%zIphm)%yR$R8}Q#Y@PE(`{P#or zA3Xs6>j?jk=5zml{QqZsaLl%Truvr{!)Axzy5s$SF982V-TybLf&XrJ|3?>q{|2c4 zN2~vjQQ*In*Z*4=fd5`;{l8o=0I|~uv&2?a zg$gPm+ylil1;!{D`BCVX%NVA5ox{a6yGgaVG$xOT#uAm#JQVcsX}K%G+_7~~uJe5+ zMu!*TQ{P@e0m-uf6wL2iVu-)JPvtC}Rh&zWN0#V+BYn!jizmVJTT*sWFRKh~8}Sv! zz^5vr5(gfKa7|r1L(b>ttZIzO=E^%J$9+{cp13bou@cWTi?{3~yneXghW@GIhQ&Do z-hYEi+PRH*D<3?bk3{Ev3?xU&-*BQHH?HB|KP~-V`mo(Q`nue|JzUgiHN%ipx;nq_qWELH)D?@ z>KE)>qdmxHENK0JK%|;{zF3WU`E%Tva;=z;rYDSw@6|I>Iz0X5S{wbe$yR^9XkJO0 zzYHM_mR{NW{8BGVA8L<~c4=dz8aq@dq^uM#89`IByzl8AaR07TR-}(mVn&{yWVZC% z3smP}Z8AhgMhxAE0St!WA5Gp)ebZ52L8tcAV}oN@;}Z8a)f5mGzxny%5?rW+c#ut9 zHPu5$JPX%&-Hfk;f!RQ9+ObAhC)&Kf1AfJ9DB8>}vfz#$ym=bdL$BXAo%YwFFqDYl zk?K^%Pbx38P)x~ENGIUCQVTZv^wS7!V&#--y17ZAYiJW3Kk!MJsX>gZD{WxnWkyz= zDRlc=ZM5@9#lA+j%rtX@g2XM}UtKzw0`eLU7CxqGthyT==z?9eFN~u$#slL6vw#=9 z>0e_08=c|fI~g=$ZjbMUf+RO|ZwiI7`cbCW{>fVV#lHTHt}~iEBRatI?ftB#Vpd{Oo zf~iJCW!iOlMQ98J%nWB>S;G9%fP^d9MgaH6VgZ z|G@n#9hZ7uN6Pa*6S89V_!>t3z(`Ef8-pUg`c#?;@fCCjbo45=^$;`%c67?LQFJwP zB6I<^<{8QC>`C#?F}>7X4JueOs&*MAELK*2RX{gkp?QBpN_6lC^15Q*hgM*C8oNUH zeHQ;j$x1L)91x$-zxK+FeR;Fx*r}gWr379Bc(n*lSP+o9TCb~PW4_7EdEaoL1dxl zhN|{(bIp>Xqt1+^HRR(7%AAb?bd~we=-WFCRe1Cpq88&>?G4Apx<4^R6@wSV8y8L_ zvh-_BbPGIDZJ>`I0`QOdPK~b6P`%&}?Qp$g@H6@ zA=1+=1!3jVt63CCA$9?SS83u>k-^%4c`qz0!-AUH2Layj1wnfMgyUgRBH;?YxZ7+Q zCDe;Px?*)zg^CM8;kDv$g4$2K9o5I7)_;&;9IDqS!MmZeqTGkb=CUJY=T`Z%v?!(^hdR%*oOU7VPNL~+4>!`EK8`))mABbIc`>c!ZlIXdFpI=82rE$) z30wboT1R_P*6*ih6rHvomp6aBT#np>?ZB}j^)(@j2dG_zwxQbDB9N)D*(sVuu z=pnd{wVN_O4;UrkrH2ywwx7pTo8j28MA`Xd$hQo$yoYBl-R*{4M{$YUa1zFU(5fgc zb^mz3H%_?uML1UIh6kWF_BxOLR_$|Y2Fn#GQ}ykw>k<=6v#gq&>eiIGIxil&L_u}R zHCM5eBA+t^jdn?tgF|`{Qa^YyQ_VHExN0VDh1sc<*?fkQXI0KS%8OS@9#GXzzjr@+ z@S>dRZFiQs9=^3r+OP}!1MPB*WB!6ul=v~o(o3Wg@}f^^?d83nN@W>2_Xd!|a?Xzp)Wl&8~Z zDfedSqrFK!7T&$D*x?3Mpy|Fmgo>MmDb#&(vWlGqE^x15HXq1#tp05yl3PSLujf!Q z)&D7uK$f^Pgpk$u91154N~qahG=S|`s*pc6yTteEcPl^LI(6Oovc(GfiR+l6Hc^zQ zPU1M5R+)Co^%w%+VFUsPa?=6!%Rc*DRiLi?HRg9hZ@n)NjXF)mjwmJ2gSi&Cu_AUSxCTdhq- ztuKyBg^R{9yH}>sf^FeMIbBejtJ20sO!fy(rt0rW4d&TBO9ioZ@?`0RjXcGqFM<)j zq_-Bbjr|qa6UmP z_#3QH17(ljwM0LV{|K4)zv@bk0pKlEA?!CMavzHcs@VW$74%Z!d961=R5u-G_G7y9 zQkKpS9P^&;&t9&4Tod-Si~LdWq=u?0j18VVEX+zb0ro7ON&=FUpL+dgN9g9@@zF(% zTFtchD3}rQ%2Iq%Yi*YVGQoFCD#lN;mI{IPQ(SxGCHQ!GV=XF6I7rqr{l>r_c(Ad1 zJOec_d9my19BY&p?m%NYYQ;ve&Eg!@Nr3&A79AH<#}o5C+W>`DLoFgWlUmvHR8r~P z(VmL~hF#JShduZtA~T%LnWWNf|LIKDf*}@7=qSR>r(&s)K$xzdB9qmKw-I>qL9E8? zs3a@`Tnwvo-R;n77XBF*cR*&XZhN(gv2BZU8#^<>S$>UCmbMYB_;e7XDgvA$RED3|zS=_1SaPSF#~NJ>swD$y6<4xbtdL zivLX9jCnO68)v@u)X~mM_wz?JoA+EaYqz`Mw#Uv<*gOQG8xcAZ=>TG$m+Vz>gwoB2 z(Z6jy(_}j=?ugbSq1y`cUNDF$- zh)eH`XT1ux4?9demEguCVYn9HmZ#y0k5PJWP{JT~du%r|oWhlQ>rb~M!E2W}Ifn2F zYa#F}5PurozQ1ZBLIJWo_|M*x=8xzLrpFIeR6AMm2!&fbdo22F*B-mw%ejonssxN- zw7aADRg29hO}(&gW`u(FZPYjr(t-~ka7{mulxmbLt5e{aR?dQ`T`EwNPC9LPgeSg+ z|Lwf=+^w?>WE@V!yFy?(o$wC++^gzF+Iyv0j<4C6f*@Dc{RxOSc3-w_b9s*mX-cx9 zB%#;eh~Jl1v{WH%Ho@t@==ye>+!6J6Xo`sA@)0`ZGRnXn zgSe_MhK#2$gBQ5LSjzGk91FynAgQeg+Ou!0`yE}~KkIBI)s#nFrUnrMzrts0D>mEl zP_(MKvnQMvhit*e`@*oI?Z&!X8i^j&n1#}--P_*(g>HG&Ax|ov{g}FL z^clH^?7ngQg~wlLkn6Oz(5Fc$w@x^Ty?YE#G#HShb3)$4m9$8vvJ&&wyAb~hi>_A9$Y zahHrvVA^4mOtyl5c>1tpq7IX1!xha4!*OAZB&o)2L@a}ZFLftX45C(Mb89FVY5T+f zTA~TTCgYVy)Hhy}u1Vbhx{ye7G6y#HqT=Yj5~X zy3~vAhFvZ-=oDx2+ z?40FEv)naw;Ade#LmMwrQEOSow`Fcv-`)TA6so43#C`huorM}A`FSGJzPtHkT4OJh zo{VXgLtV;k5?#^0@~p=U!Qz*1LS@*1A{AD!k6CJ3!|XEnn*M`0Dmi$bMaOK<==;UW zSm0-Xa`qnqZ;ouyRb6ZT-Dr$%)$gBU6$4LaY-er(U18%s!WpYBii(BiHM~sX9ut*< zeK#&u_FGpS+o_yrWHWGte@bw0KT{Oj`~KD@-*keVg`*S1uJ2fOJi=S`6R5q`))S-z z-<`{0dpNtsD(^6fqUndzD0St z138lr$WMinJdU5Qr3JphnEX>3teWb>*|Ib7qt*O!Uy~SA8^<*W3=n+K!(FnVWolbo zvV3n7V^LT|{nN}k!xQGPEwp?QF8MMAXGv`EUNjQwr%Ka;+uGTd`WKFJ_7AFdplneS z5MRPUrBAzKure3b)+SvhQR7%h&=O4G{YRu#mO|^!Jzp&n+JWOyPefb^!<<+#%t|tV zCq2|yB`DN5UeyFrbX(fq)hCzFp^O+IVA^aQ#5J4#i-&ugrc+B*AQSu~^W&3El&>P? z=ey+elgmu8_Jw#o=R1js;d7q+`AJwy;G>qJXSDx|P2a>ySTEy69Q5b73$*yaaA{;x zp0uw!QO{G6XN4jYDlBOl4Gn8#>Z)>9*_}`DZlXIB10x4 zTTsmUC%JckUPqS-EL4~39)uN9g=wakh+_#<-d0>D(6OfRTkJTrH;H2lE>(KW~S@igH!wr$&X8mEnI+cqv}j5dvJyRmKCP8!?%zWKfX z?B3np-sf|7yR$R%JUjF2t`D{8JK(|&wj}XmNamMh(1OoTEjcJ5LrVO!oKf!krSdyU?RcO?@)c(VZ!av#KU{ePXXnC>Lkx7~` zvH(_G1Qrjd(4cgHGpE-B72sZ<#o05(HOYufh%Hi(`ax`y5tAUa_(X~Z@fxE}o)Y`t z39qrb7mO?jEsj11>}S!J&Z?Bgyo=@vIQM$jX`IL;B)m+^;~Z8zL}Pv|^j~P#(^h6C2h43^{Wp zUi|-*5#ALp>J6ro)=Gpuq|j?92trCpz+O&DZssE>@>pK!nN%~^`D7KQT1&~pHfaHJ zW;W0(+p?xo+_7$%8}Cjs%m$UkCNh+2x!_gGOoYB&94q?tD@Ce4fg5O?t+NARk3Ua@ zyUUw+#pyc-50I+!%hEfQE95X^;Q2Mu(oxIfwz!~oL)#MZ&@MZxG7?H-eJVQF`%%(M zeW?KrCA*WE&f*(s$?q3%W@Wi93^$!Di_j1H8N(yyu5?vTH5~y{N=1$iVLF!*Q?vn< zDCJ?9C%zN^#LBl%Z^5lW!B9krD46MRYOu=cWj&EnF)#x+`}AtbqEco|FHlN5RjQF$ zGB?vb^r&s(Ddm znZzc&)PQ5HETeXU)Gvu9=INJF%}iLbi*wD>C3x_wnY~f z4^IDJbbU*8y-zt?#ycf`FVky-Ss}sYUZoly9o~n=<&fZpp;r++ng&Z4!x%Oxse|$Q zl`3h!W}8_gk~uYmJ|n9j`sr$9n=q50Q-8%B4*+CkJd7LV({tpfnvOnm+!)luDKgE; zKYSx>|1&?~>PS4YcuX*#$}`@`rWZ|+Fy@-bu5^f1HMj9jqf_jmXaRPT;c$|p`wy%o zCK9uPGF6Qp>thybL!nFgDQ7vGJl|yv%J1J)qDZ#j2CeCHlXPc0GB5R3EhEs`$pXi( zMhPV9S~3ZINWE5dNvrTqmcNF#>Os|>e9=yM=byNjicv~BV5aqJ*k@*6B9;@nb7M*{ zsHtRR8>;HH@ASiY+ZAgvxzs%{xonSh_xMZvfS--U zm{tx2A=G#XvVoFFz->h+$r}Il61}tC!k13Qi$E=hB8dx(o#SSG-x<-jKTbi={R-k` z;`)rw*aO7rg<7S)(i&bHRI$V~0}~^@FDR(h&b1+_Ni4fxsgg|Hr~Oa61|zFR-{fUV zK~Tb8EVt0lZ6E0jhqdDk6A_+K*|uZRL-9?i%c-RZeO+Vyx2ZgQPkvP{Bz3JR;m9dG z8KqH^FD%$2Tf}DmZQ0?!S|)4959|4!vmI;EQ;iN$oiegB#?BZ>c5SHqfy*$BwCo<7 zCUN2R={JH8B-p4WU42G)mV!58(+&5hO%7`hIObS~gQ1@~h5fR!ltB^4dfy3C$%77D z+V7YmsBY&#=7QZszyGv{CLwY;t%Jt>)i8htam)K5N%U63ng-VXFVOIi9D3w|q zdE{^(WZsi@*uM3cj!euRi-iSv{GD-+?k(*
      Ia2bMEh$+>IYx^Lxy{L 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%0D$yUcEwU`!#vJoYT|%8xv_zSvgu5h>?3wv} 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%0A^W&`P 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 z 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

      #w>6EmVb92qC=qSqho{Y-;m{IjqL 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

      vqEhQi9%DRpa7zuG~a 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 z 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 rAu-$|^=MMCm}L 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 z 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%0A=idlK5L5xeDia1BGTqdpDw0KY@ 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

      S`R>M6XiT8 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

      Vw#3TmOEk$wkUT!en9$TPvo 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

      fWktKb%!9YLM9j|g}p`~ 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ʔ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
    1. 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�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�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%0DFqg-~3kqwN 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 y;YG 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 z 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%0Dp2{2W{5+n79iv6Nud+|KA})6N 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:jP#1slm?3~u8HH;|+D$xPPR1R;5+3=Y zJpj@rSzKYANgCfd2r+7mW>3ifBaTs6g?~=okK+;DmLj;{kl5R z_8)|Zh6LZL0y$H%xWd8+U~M%5$T28Dyf+&hPcHbc9UMy+mpCNn!!kAi9yJo+QIP|w z6JURTQmr@`i~(0LaYDc`^c)xx+8*)ygn&+==b)(T8PZM>Q63s>dJPL>NCsR$^iDO_Ah@$=Re#j+To|F9F#D@r9dAUWpwwbaAn79 z9})jVHR^%$^0ipbqFL~CrXL;s3-j>2su*&c%0DvRusag#n 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%0Degbrip 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ⅅu$cJJgoAP~7Jx1Q5@ERTtQK>0V44`( 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

      &BvFy^lEt%OM^n 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

      2Y41D|K69CEkCq1aBE9GMvd?GS9Ml)?XJo; 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
      l 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

      df6)h# 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%0A%CvsruQ> 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�bb!%=)yWWgWC}m&1jiL9kaS-(XwmO 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 y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); + RAISE INFO 'x = %, y = %', x, y; + CALL test_proc6(2, c => y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +== 023 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +== 024 +DO +LANGUAGE plpgsql +$$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +== 025 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +== 026 +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +-- +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) LANGUAGE plpgsql AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +== 027 +CALL test_proc7(100, -1, -1) +-- +CALL test_proc7(100, -1, -1) +== 028 +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +-- +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) LANGUAGE plpgsql AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +== 029 +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +-- +CREATE PROCEDURE test_proc7cc(_x int) LANGUAGE plpgsql AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +== 030 +CALL test_proc7cc(10) +-- +CALL test_proc7cc(10) +== 031 +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +-- +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +== 032 +CALL test_proc8a(10, 20) +-- +CALL test_proc8a(10, 20) +== 033 +CALL test_proc8a(b => 20, a => 10) +-- +CALL test_proc8a(b := 20, a := 10) +== 034 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +== 035 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +== 036 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 037 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int = 11) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +== 038 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 039 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 040 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 041 +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +-- +CREATE PROCEDURE test_proc9(IN a int, OUT b int) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +== 042 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +== 043 +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +-- +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int = 11) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +== 044 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 045 +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +-- +CREATE PROCEDURE test_proc11(OUT a int, VARIADIC b int[]) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +== 046 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 047 +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +-- +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +== 048 +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 049 +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +== 050 +-- transition variable assignment + +TRUNCATE test1 +-- +TRUNCATE test1 +== 051 +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +-- +CREATE FUNCTION triggerfunc1() RETURNS trigger LANGUAGE plpgsql AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +== 052 +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +-- +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE FUNCTION triggerfunc1() +== 053 +INSERT INTO test1 VALUES (1), (2), (3) +-- +INSERT INTO test1 VALUES (1), (2), (3) +== 054 +UPDATE test1 SET a = 22 WHERE a = 2 +-- +UPDATE test1 SET a = 22 WHERE a = 2 +== 055 +SELECT * FROM test1 ORDER BY a +-- +SELECT * FROM test1 ORDER BY a +== 056 +DROP PROCEDURE test_proc1 +-- +DROP PROCEDURE test_proc1 +== 057 +DROP PROCEDURE test_proc3 +-- +DROP PROCEDURE test_proc3 +== 058 +DROP PROCEDURE test_proc4 +-- +DROP PROCEDURE test_proc4 +== 059 +DROP TABLE test1 +-- +DROP TABLE test1 +== 060 +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +-- +CREATE PROCEDURE p1(v_cnt int, INOUT v_text text = NULL) AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +== 061 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +== 062 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +== 063 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +== 064 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +== 065 +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +-- +CREATE PROCEDURE inner_p(f1 int) AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +== 066 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +-- +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +== 067 +CREATE PROCEDURE outer_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +CREATE PROCEDURE outer_p(f1 int) AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +== 068 +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION outer_f(f1 int) RETURNS void AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +== 069 +CALL outer_p(42) +-- +CALL outer_p(42) +== 070 +SELECT outer_f(42) +-- +SELECT outer_f(42) +== 071 +DROP FUNCTION f(int) +-- +DROP FUNCTION f(int) +== 072 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +-- +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +== 073 +CALL outer_p(42) +-- +CALL outer_p(42) +== 074 +SELECT outer_f(42) +-- +SELECT outer_f(42) +== 075 +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +-- +CREATE TABLE t_test (x int) +== 076 +INSERT INTO t_test VALUES (0) +-- +INSERT INTO t_test VALUES (0) +== 077 +CREATE FUNCTION f_get_x () RETURNS int +AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +-- +CREATE FUNCTION f_get_x() RETURNS int AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +== 078 +CREATE PROCEDURE f_print_x (x int) +AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +-- +CREATE PROCEDURE f_print_x(x int) AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +== 079 +-- test in non-atomic context +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +-- +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +== 080 +-- test in non-atomic context, except exception block is locally atomic +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +-- +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +== 081 +-- test in atomic context +BEGIN +-- +BEGIN +== 082 +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +-- +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +== 083 +ROLLBACK +-- +ROLLBACK diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_control.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_control.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_control.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_control.test new file mode 100644 index 0000000..e4389b4 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_control.test @@ -0,0 +1,1008 @@ +== 001 +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +-- +DO $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +== 002 +-- BY can't be zero or negative +do $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +-- +DO $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +== 003 +do $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +-- +DO $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +== 004 +do $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +-- +DO $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +== 005 +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +-- +CREATE TABLE conttesttbl (idx serial, v int) +== 006 +insert into conttesttbl(v) values(10) +-- +INSERT INTO conttesttbl (v) VALUES (10) +== 007 +insert into conttesttbl(v) values(20) +-- +INSERT INTO conttesttbl (v) VALUES (20) +== 008 +insert into conttesttbl(v) values(30) +-- +INSERT INTO conttesttbl (v) VALUES (30) +== 009 +insert into conttesttbl(v) values(40) +-- +INSERT INTO conttesttbl (v) VALUES (40) +== 010 +create function continue_test1() returns void as $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ language plpgsql +-- +CREATE FUNCTION continue_test1() RETURNS void AS $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ LANGUAGE plpgsql +== 011 +select continue_test1() +-- +SELECT continue_test1() +== 012 +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $$ +begin + begin + continue; + end; +end; +$$ language plpgsql +-- +CREATE FUNCTION continue_error1() RETURNS void AS $$ +begin + begin + continue; + end; +end; +$$ LANGUAGE plpgsql +== 013 +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $$ +begin + begin + exit; + end; +end; +$$ language plpgsql +-- +CREATE FUNCTION exit_error1() RETURNS void AS $$ +begin + begin + exit; + end; +end; +$$ LANGUAGE plpgsql +== 014 +-- should fail: no such label +create function continue_error2() returns void as $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +CREATE FUNCTION continue_error2() RETURNS void AS $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ LANGUAGE plpgsql +== 015 +-- should fail: no such label +create function exit_error2() returns void as $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +CREATE FUNCTION exit_error2() RETURNS void AS $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ LANGUAGE plpgsql +== 016 +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ language plpgsql +-- +CREATE FUNCTION continue_error3() RETURNS void AS $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ LANGUAGE plpgsql +== 017 +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ language plpgsql +-- +CREATE FUNCTION exit_block1() RETURNS void AS $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ LANGUAGE plpgsql +== 018 +select exit_block1() +-- +SELECT exit_block1() +== 019 +-- verbose end block and end loop +create function end_label1() returns void as $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ language plpgsql +-- +CREATE FUNCTION end_label1() RETURNS void AS $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ LANGUAGE plpgsql +== 020 +select end_label1() +-- +SELECT end_label1() +== 021 +-- should fail: undefined end label +create function end_label2() returns void as $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ language plpgsql +-- +CREATE FUNCTION end_label2() RETURNS void AS $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ LANGUAGE plpgsql +== 022 +-- should fail: end label does not match start label +create function end_label3() returns void as $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +CREATE FUNCTION end_label3() RETURNS void AS $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ LANGUAGE plpgsql +== 023 +-- should fail: end label on a block without a start label +create function end_label4() returns void as $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +CREATE FUNCTION end_label4() RETURNS void AS $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ LANGUAGE plpgsql +== 024 +-- unlabeled exit matches no blocks +do $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +-- +DO $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +== 025 +-- check exit out of an unlabeled block to a labeled one +do $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +-- +DO $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +== 026 +-- check exit out of outermost block +do $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +-- +DO $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +== 027 +-- unlabeled exit does match a while loop +do $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +-- +DO $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +== 028 +-- check exit out of an unlabeled while to a labeled one +do $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +-- +DO $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +== 029 +-- continue to an outer while +do $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +-- +DO $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +== 030 +-- return out of a while +create function return_from_while() returns int language plpgsql as $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +-- +CREATE FUNCTION return_from_while() RETURNS int LANGUAGE plpgsql AS $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +== 031 +select return_from_while() +-- +SELECT return_from_while() +== 032 +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $proc$ +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice '%', i; + end loop; + -- fore with record var + for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop + raise notice '% % %', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice '%', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop + raise notice '% % %', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop + raise notice '% % %', a, b, c; + end loop; +end; +$proc$ language plpgsql +-- +CREATE FUNCTION for_vect() RETURNS void AS ' +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice ''%'', i; + end loop; + -- fore with record var + for r in select gs as aa, ''BB'' as bb, ''CC'' as cc from generate_series(1,4) gs loop + raise notice ''% % %'', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice ''%'', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, ''BB'',''CC'' from generate_series(1,4) gs loop + raise notice ''% % %'', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, ''bb'',''cc'' from generate_series(1,4) gs$$ loop + raise notice ''% % %'', a, b, c; + end loop; +end; +' LANGUAGE plpgsql +== 033 +select for_vect() +-- +SELECT for_vect() +== 034 +-- CASE statement + +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ language plpgsql immutable +-- +CREATE OR REPLACE FUNCTION case_test(bigint) RETURNS text AS $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ LANGUAGE plpgsql IMMUTABLE +== 035 +select case_test(1) +-- +SELECT case_test(1) +== 036 +select case_test(2) +-- +SELECT case_test(2) +== 037 +select case_test(3) +-- +SELECT case_test(3) +== 038 +select case_test(4) +-- +SELECT case_test(4) +== 039 +select case_test(5) +-- +SELECT case_test(5) +== 040 +-- fails +select case_test(8) +-- +SELECT case_test(8) +== 041 +select case_test(10) +-- +SELECT case_test(10) +== 042 +select case_test(11) +-- +SELECT case_test(11) +== 043 +select case_test(12) +-- +SELECT case_test(12) +== 044 +select case_test(13) +-- +SELECT case_test(13) +== 045 +-- fails + +create or replace function catch() returns void as $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ language plpgsql +-- +CREATE OR REPLACE FUNCTION catch() RETURNS void AS $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ LANGUAGE plpgsql +== 046 +select catch() +-- +SELECT catch() +== 047 +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +CREATE OR REPLACE FUNCTION case_test(bigint) RETURNS text AS $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ LANGUAGE plpgsql IMMUTABLE +== 048 +select case_test(1) +-- +SELECT case_test(1) +== 049 +select case_test(2) +-- +SELECT case_test(2) +== 050 +select case_test(12) +-- +SELECT case_test(12) +== 051 +select case_test(13) +-- +SELECT case_test(13) +== 052 +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +CREATE OR REPLACE FUNCTION case_comment(int) RETURNS text AS $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ LANGUAGE plpgsql IMMUTABLE +== 053 +select case_comment(1) +-- +SELECT case_comment(1) diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_copy.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_copy.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_copy.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_copy.test new file mode 100644 index 0000000..2788c56 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_copy.test @@ -0,0 +1,21 @@ +== 001 +-- directory paths are passed to us in environment variables + +-- set up file names to use + +CREATE TABLE copy1 (a int, b float); + +-- COPY TO/FROM not authorized from client. +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 TO stdout; +END; +$$; +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 FROM stdin; +-- +ERROR: "unterminated dollar-quoted string at or near \"$$\nBEGIN\n COPY copy1 FROM stdin;\"" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_domain.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_domain.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_domain.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_domain.test new file mode 100644 index 0000000..3daf488 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_domain.test @@ -0,0 +1,588 @@ +== 001 +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +-- +CREATE DOMAIN booltrue AS bool CHECK (value IS TRUE OR value IS NULL) +== 002 +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +== 003 +SELECT * FROM test_argresult_booltrue(true, true) +-- +SELECT * FROM test_argresult_booltrue(true, true) +== 004 +SELECT * FROM test_argresult_booltrue(false, true) +-- +SELECT * FROM test_argresult_booltrue(false, true) +== 005 +SELECT * FROM test_argresult_booltrue(true, false) +-- +SELECT * FROM test_argresult_booltrue(true, false) +== 006 +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +== 007 +SELECT * FROM test_assign_booltrue(true, true) +-- +SELECT * FROM test_assign_booltrue(true, true) +== 008 +SELECT * FROM test_assign_booltrue(false, true) +-- +SELECT * FROM test_assign_booltrue(false, true) +== 009 +SELECT * FROM test_assign_booltrue(true, false) +-- +SELECT * FROM test_assign_booltrue(true, false) +== 010 +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +-- +CREATE DOMAIN uint2 AS int2 CHECK (value >= 0) +== 011 +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +== 012 +SELECT * FROM test_argresult_uint2(100::uint2, 50) +-- +SELECT * FROM test_argresult_uint2(100::uint2, 50) +== 013 +SELECT * FROM test_argresult_uint2(100::uint2, -50) +-- +SELECT * FROM test_argresult_uint2(100::uint2, -50) +== 014 +SELECT * FROM test_argresult_uint2(null, 1) +-- +SELECT * FROM test_argresult_uint2(NULL, 1) +== 015 +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +== 016 +SELECT * FROM test_assign_uint2(100, 50) +-- +SELECT * FROM test_assign_uint2(100, 50) +== 017 +SELECT * FROM test_assign_uint2(100, -50) +-- +SELECT * FROM test_assign_uint2(100, -50) +== 018 +SELECT * FROM test_assign_uint2(-100, 50) +-- +SELECT * FROM test_assign_uint2(-100, 50) +== 019 +SELECT * FROM test_assign_uint2(null, 1) +-- +SELECT * FROM test_assign_uint2(NULL, 1) +== 020 +CREATE DOMAIN nnint AS int NOT NULL +-- +CREATE DOMAIN nnint AS int NOT NULL +== 021 +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +== 022 +SELECT * FROM test_argresult_nnint(10, 20) +-- +SELECT * FROM test_argresult_nnint(10, 20) +== 023 +SELECT * FROM test_argresult_nnint(null, 20) +-- +SELECT * FROM test_argresult_nnint(NULL, 20) +== 024 +SELECT * FROM test_argresult_nnint(10, null) +-- +SELECT * FROM test_argresult_nnint(10, NULL) +== 025 +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +== 026 +SELECT * FROM test_assign_nnint(10, 20) +-- +SELECT * FROM test_assign_nnint(10, 20) +== 027 +SELECT * FROM test_assign_nnint(null, 20) +-- +SELECT * FROM test_assign_nnint(NULL, 20) +== 028 +SELECT * FROM test_assign_nnint(10, null) +-- +SELECT * FROM test_assign_nnint(10, NULL) +== 029 +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +-- +CREATE DOMAIN ordered_pair_domain AS int[] CHECK (array_length(value, 1) = 2 AND value[1] < value[2]) +== 030 +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +== 031 +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +-- +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +== 032 +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +-- +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +== 033 +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_array_domain_check_violation() RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +== 034 +SELECT * FROM test_argresult_array_domain_check_violation() +-- +SELECT * FROM test_argresult_array_domain_check_violation() +== 035 +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +== 036 +SELECT * FROM test_assign_ordered_pair_domain(1,2,3) +-- +SELECT * FROM test_assign_ordered_pair_domain(1, 2, 3) +== 037 +SELECT * FROM test_assign_ordered_pair_domain(1,2,0) +-- +SELECT * FROM test_assign_ordered_pair_domain(1, 2, 0) +== 038 +SELECT * FROM test_assign_ordered_pair_domain(2,1,3) +-- +SELECT * FROM test_assign_ordered_pair_domain(2, 1, 3) +== 039 +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +== 040 +select test_read_uint2_array(array[1::uint2]) +-- +SELECT test_read_uint2_array(ARRAY[1::uint2]) +== 041 +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +== 042 +select test_build_uint2_array(1::int2) +-- +SELECT test_build_uint2_array(1::int2) +== 043 +select test_build_uint2_array(-1::int2) +-- +SELECT test_build_uint2_array(- 1::int2) +== 044 +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_domain_array(x int[]) RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +== 045 +select test_argresult_domain_array(array[2,4]) +-- +SELECT test_argresult_domain_array(ARRAY[2, 4]) +== 046 +select test_argresult_domain_array(array[4,2]) +-- +SELECT test_argresult_domain_array(ARRAY[4, 2]) +== 047 +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) RETURNS int AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +== 048 +select test_argresult_domain_array2(array[2,4]) +-- +SELECT test_argresult_domain_array2(ARRAY[2, 4]) +== 049 +select test_argresult_domain_array2(array[4,2]) +-- +SELECT test_argresult_domain_array2(ARRAY[4, 2]) +== 050 +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +== 051 +select test_argresult_array_domain_array(array[array[2,4]::ordered_pair_domain]) +-- +SELECT test_argresult_array_domain_array(ARRAY[ARRAY[2, 4]::ordered_pair_domain]) +== 052 +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +-- +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +== 053 +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_result_nnint_container(x int, y int) RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +== 054 +SELECT test_result_nnint_container(null, 3) +-- +SELECT test_result_nnint_container(NULL, 3) +== 055 +SELECT test_result_nnint_container(3, null) +-- +SELECT test_result_nnint_container(3, NULL) +== 056 +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +== 057 +SELECT * FROM test_assign_nnint_container(1,2,3) +-- +SELECT * FROM test_assign_nnint_container(1, 2, 3) +== 058 +SELECT * FROM test_assign_nnint_container(1,2,null) +-- +SELECT * FROM test_assign_nnint_container(1, 2, NULL) +== 059 +SELECT * FROM test_assign_nnint_container(1,null,3) +-- +SELECT * FROM test_assign_nnint_container(1, NULL, 3) +== 060 +-- Since core system allows this: +SELECT null::nnint_container +-- +SELECT NULL::nnint_container +== 061 +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +== 062 +SELECT * FROM test_assign_nnint_container2(1,2,3) +-- +SELECT * FROM test_assign_nnint_container2(1, 2, 3) +== 063 +SELECT * FROM test_assign_nnint_container2(1,2,null) +-- +SELECT * FROM test_assign_nnint_container2(1, 2, NULL) +== 064 +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +-- +CREATE TYPE named_pair AS (i int, j int) +== 065 +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +-- +CREATE DOMAIN ordered_named_pair AS named_pair CHECK ((value).i <= (value).j) +== 066 +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS int AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +== 067 +SELECT read_ordered_named_pair(row(1, 2)) +-- +SELECT read_ordered_named_pair(ROW(1, 2)) +== 068 +SELECT read_ordered_named_pair(row(2, 1)) +-- +SELECT read_ordered_named_pair(ROW(2, 1)) +== 069 +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +== 070 +SELECT build_ordered_named_pair(1,2) +-- +SELECT build_ordered_named_pair(1, 2) +== 071 +SELECT build_ordered_named_pair(2,1) +-- +SELECT build_ordered_named_pair(2, 1) +== 072 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +== 073 +SELECT * FROM test_assign_ordered_named_pair(1,2,3) +-- +SELECT * FROM test_assign_ordered_named_pair(1, 2, 3) +== 074 +SELECT * FROM test_assign_ordered_named_pair(1,2,0) +-- +SELECT * FROM test_assign_ordered_named_pair(1, 2, 0) +== 075 +SELECT * FROM test_assign_ordered_named_pair(2,1,3) +-- +SELECT * FROM test_assign_ordered_named_pair(2, 1, 3) +== 076 +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +== 077 +SELECT build_ordered_named_pairs(1,2) +-- +SELECT build_ordered_named_pairs(1, 2) +== 078 +SELECT build_ordered_named_pairs(2,1) +-- +SELECT build_ordered_named_pairs(2, 1) +== 079 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +== 080 +SELECT * FROM test_assign_ordered_named_pairs(1,2,3) +-- +SELECT * FROM test_assign_ordered_named_pairs(1, 2, 3) +== 081 +SELECT * FROM test_assign_ordered_named_pairs(2,1,3) +-- +SELECT * FROM test_assign_ordered_named_pairs(2, 1, 3) +== 082 +SELECT * FROM test_assign_ordered_named_pairs(1,2,0) +-- +SELECT * FROM test_assign_ordered_named_pairs(1, 2, 0) diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_misc.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_misc.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_misc.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_misc.test new file mode 100644 index 0000000..e27ac16 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_misc.test @@ -0,0 +1,89 @@ +== 001 +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +-- +DO $$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +== 002 +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +-- +CREATE TABLE misc_table (f1 int) +== 003 +do $$ declare x foo%type; begin end $$ +-- +DO $$ declare x foo%type; begin end $$ +== 004 +do $$ declare x notice%type; begin end $$ +-- +DO $$ declare x notice%type; begin end $$ +== 005 +-- covers unreserved-keyword case +do $$ declare x foo.bar%type; begin end $$ +-- +DO $$ declare x foo.bar%type; begin end $$ +== 006 +do $$ declare x foo.bar.baz%type; begin end $$ +-- +DO $$ declare x foo.bar.baz%type; begin end $$ +== 007 +do $$ declare x public.foo.bar%type; begin end $$ +-- +DO $$ declare x public.foo.bar%type; begin end $$ +== 008 +do $$ declare x public.misc_table.zed%type; begin end $$ +-- +DO $$ declare x public.misc_table.zed%type; begin end $$ +== 009 +do $$ declare x foo%rowtype; begin end $$ +-- +DO $$ declare x foo%rowtype; begin end $$ +== 010 +do $$ declare x notice%rowtype; begin end $$ +-- +DO $$ declare x notice%rowtype; begin end $$ +== 011 +-- covers unreserved-keyword case +do $$ declare x foo.bar%rowtype; begin end $$ +-- +DO $$ declare x foo.bar%rowtype; begin end $$ +== 012 +do $$ declare x foo.bar.baz%rowtype; begin end $$ +-- +DO $$ declare x foo.bar.baz%rowtype; begin end $$ +== 013 +do $$ declare x public.foo%rowtype; begin end $$ +-- +DO $$ declare x public.foo%rowtype; begin end $$ +== 014 +do $$ declare x public.misc_table%rowtype; begin end $$ +-- +DO $$ declare x public.misc_table%rowtype; begin end $$ diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_record.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_record.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_record.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_record.test new file mode 100644 index 0000000..5ae0b19 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_record.test @@ -0,0 +1,1225 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +-- +CREATE TYPE two_int4s AS (f1 int4, f2 int4) +== 002 +create type more_int4s as (f0 text, f1 int4, f2 int4) +-- +CREATE TYPE more_int4s AS (f0 text, f1 int4, f2 int4) +== 003 +create type two_int8s as (q1 int8, q2 int8) +-- +CREATE TYPE two_int8s AS (q1 int8, q2 int8) +== 004 +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +-- +CREATE TYPE nested_int8s AS (c1 two_int8s, c2 two_int8s) +== 005 +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1)::two_int8s; end $$ +-- +CREATE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ begin return row($1,1)::two_int8s; end $$ +== 006 +select retc(42) +-- +SELECT retc(42) +== 007 +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8); end $$ +-- +CREATE OR REPLACE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ begin return row($1::int8, 1::int8); end $$ +== 008 +select retc(42) +-- +SELECT retc(42) +== 009 +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1); end $$ +-- +CREATE OR REPLACE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ begin return row($1,1); end $$ +== 010 +select retc(42) +-- +SELECT retc(42) +== 011 +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8, 42); end $$ +-- +CREATE OR REPLACE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ begin return row($1::int8, 1::int8, 42); end $$ +== 012 +select retc(42) +-- +SELECT retc(42) +== 013 +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +-- +CREATE OR REPLACE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +== 014 +select retc(42) +-- +SELECT retc(42) +== 015 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,1); return r; end $$ +-- +CREATE OR REPLACE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ declare r record; begin r := row($1,1); return r; end $$ +== 016 +select retc(42) +-- +SELECT retc(42) +== 017 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +CREATE OR REPLACE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +== 018 +select retc(42) +-- +SELECT retc(42) +== 019 +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +CREATE OR REPLACE FUNCTION retc(int) RETURNS two_int8s LANGUAGE plpgsql AS $$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +== 020 +select retc(42) +-- +SELECT retc(42) +== 021 +do $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +-- +DO $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +== 022 +do $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +-- +DO $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +== 023 +do $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +-- +DO $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +== 024 +do $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +-- +DO $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +== 025 +-- block-qualified naming +do $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +-- +DO $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +== 026 +-- error cases +do $$ declare c two_int8s; begin c.x = 1; end $$ +-- +DO $$ declare c two_int8s; begin c.x = 1; end $$ +== 027 +do $$ declare c nested_int8s; begin c.x = 1; end $$ +-- +DO $$ declare c nested_int8s; begin c.x = 1; end $$ +== 028 +do $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +-- +DO $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +== 029 +do $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +-- +DO $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +== 030 +do $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +-- +DO $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +== 031 +do $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +-- +DO $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +== 032 +do $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +-- +DO $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +== 033 +do $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +-- +DO $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +== 034 +do $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +-- +DO $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +== 035 +do $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +-- +DO $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +== 036 +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +-- +CREATE FUNCTION getq1(two_int8s) RETURNS int8 LANGUAGE plpgsql AS $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +== 037 +select getq1(retc(344)) +-- +SELECT getq1(retc(344)) +== 038 +select getq1(row(1,2)) +-- +SELECT getq1(ROW(1, 2)) +== 039 +do $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +== 040 +-- check assignments of composites +do $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +-- +DO $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +== 041 +-- fields of named-type vars read as null if uninitialized +do $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +-- +DO $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +== 042 +do $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +DO $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +== 043 +-- records, not so much +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +-- +DO $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +== 044 +-- but OK if you assign first +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +DO $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +== 045 +-- check %type with block-qualified variable names +do $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +-- +DO $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +== 046 +-- check that type record can be passed through %type +do $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +-- +DO $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +== 047 +-- arrays of record are not supported at the moment +do $$ +declare r1 record[]; +begin +end$$ +-- +DO $$ +declare r1 record[]; +begin +end$$ +== 048 +do $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +-- +DO $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +== 049 +-- check repeated assignments to composite fields +create table some_table (id int, data text) +-- +CREATE TABLE some_table (id int, data text) +== 050 +do $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +-- +DO $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +== 051 +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1); end $$ +-- +CREATE FUNCTION returnsrecord(int) RETURNS record LANGUAGE plpgsql AS $$ begin return row($1,$1+1); end $$ +== 052 +select returnsrecord(42) +-- +SELECT returnsrecord(42) +== 053 +select * from returnsrecord(42) as r(x int, y int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int) +== 054 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int, z int) +== 055 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +SELECT * FROM returnsrecord(42) r (x int, y bigint) +== 056 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1); return r; end $$ +-- +CREATE OR REPLACE FUNCTION returnsrecord(int) RETURNS record LANGUAGE plpgsql AS $$ declare r record; begin r := row($1,$1+1); return r; end $$ +== 057 +select returnsrecord(42) +-- +SELECT returnsrecord(42) +== 058 +select * from returnsrecord(42) as r(x int, y int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int) +== 059 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int, z int) +== 060 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +SELECT * FROM returnsrecord(42) r (x int, y bigint) +== 061 +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +-- +CREATE TABLE has_hole (f1 int, f2 int, f3 int) +== 062 +alter table has_hole drop column f2 +-- +ALTER TABLE has_hole DROP f2 +== 063 +create or replace function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1)::has_hole; end $$ +-- +CREATE OR REPLACE FUNCTION returnsrecord(int) RETURNS record LANGUAGE plpgsql AS $$ begin return row($1,$1+1)::has_hole; end $$ +== 064 +select returnsrecord(42) +-- +SELECT returnsrecord(42) +== 065 +select * from returnsrecord(42) as r(x int, y int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int) +== 066 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int, z int) +== 067 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +SELECT * FROM returnsrecord(42) r (x int, y bigint) +== 068 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +-- +CREATE OR REPLACE FUNCTION returnsrecord(int) RETURNS record LANGUAGE plpgsql AS $$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +== 069 +select returnsrecord(42) +-- +SELECT returnsrecord(42) +== 070 +select * from returnsrecord(42) as r(x int, y int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int) +== 071 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +SELECT * FROM returnsrecord(42) r (x int, y int, z int) +== 072 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +SELECT * FROM returnsrecord(42) r (x int, y bigint) +== 073 +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$$ begin return x.f1; end $$ +-- +CREATE FUNCTION getf1(x record) RETURNS int LANGUAGE plpgsql AS $$ begin return x.f1; end $$ +== 074 +select getf1(1) +-- +SELECT getf1(1) +== 075 +select getf1(row(1,2)) +-- +SELECT getf1(ROW(1, 2)) +== 076 +select getf1(row(1,2)::two_int4s) +-- +SELECT getf1(ROW(1, 2)::two_int4s) +== 077 +select getf1(row('foo',123,456)::more_int4s) +-- +SELECT getf1(ROW('foo', 123, 456)::more_int4s) +== 078 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row(1,2)::two_int8s) +-- +SELECT getf1(ROW(1, 2)::two_int8s) +== 079 +select getf1(row(1,2)) +-- +SELECT getf1(ROW(1, 2)) +== 080 +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$$ begin return $1.f2; end $$ +-- +CREATE FUNCTION getf2(record) RETURNS int LANGUAGE plpgsql AS $$ begin return $1.f2; end $$ +== 081 +select getf2(row(1,2)) +-- +SELECT getf2(ROW(1, 2)) +== 082 +-- ideally would work, but does not +select getf2(row(1,2)::two_int4s) +-- +SELECT getf2(ROW(1, 2)::two_int4s) +== 083 +select getf2(row('foo',123,456)::more_int4s) +-- +SELECT getf2(ROW('foo', 123, 456)::more_int4s) +== 084 +-- check behavior when assignment to FOR-loop variable requires coercion +do $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +-- +DO $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +== 085 +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +-- +CREATE FUNCTION returnssetofholes() RETURNS SETOF has_hole LANGUAGE plpgsql AS $$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +== 086 +select returnssetofholes() +-- +SELECT returnssetofholes() +== 087 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +-- +CREATE OR REPLACE FUNCTION returnssetofholes() RETURNS SETOF has_hole LANGUAGE plpgsql AS $$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +== 088 +select returnssetofholes() +-- +SELECT returnssetofholes() +== 089 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +begin + return next row(1,2,3); -- fails +end$$ +-- +CREATE OR REPLACE FUNCTION returnssetofholes() RETURNS SETOF has_hole LANGUAGE plpgsql AS $$ +begin + return next row(1,2,3); -- fails +end$$ +== 090 +select returnssetofholes() +-- +SELECT returnssetofholes() +== 091 +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +-- +CREATE TABLE mutable (f1 int, f2 text) +== 092 +create function sillyaddone(int) returns int language plpgsql as +$$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +CREATE FUNCTION sillyaddone(int) RETURNS int LANGUAGE plpgsql AS $$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +== 093 +select sillyaddone(42) +-- +SELECT sillyaddone(42) +== 094 +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +-- +ALTER TABLE mutable DROP f1 +== 095 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone(42) +-- +SELECT sillyaddone(42) +== 096 +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$$ begin return x.f3; end $$ +-- +CREATE FUNCTION getf3(x mutable) RETURNS int LANGUAGE plpgsql AS $$ begin return x.f3; end $$ +== 097 +select getf3(null::mutable) +-- +SELECT getf3(NULL::mutable) +== 098 +-- doesn't work yet +alter table mutable add column f3 int +-- +ALTER TABLE mutable ADD COLUMN f3 int +== 099 +select getf3(null::mutable) +-- +SELECT getf3(NULL::mutable) +== 100 +-- now it works +alter table mutable drop column f3 +-- +ALTER TABLE mutable DROP f3 +== 101 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3(null::mutable) +-- +SELECT getf3(NULL::mutable) +== 102 +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off +-- +SET check_function_bodies TO OFF +== 103 +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +-- +CREATE FUNCTION sillyaddtwo(int) RETURNS int LANGUAGE plpgsql AS $$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +== 104 +reset check_function_bodies +-- +RESET check_function_bodies +== 105 +select sillyaddtwo(42) +-- +SELECT sillyaddtwo(42) +== 106 +-- fail +create table mutable2(f1 int, f2 text) +-- +CREATE TABLE mutable2 (f1 int, f2 text) +== 107 +select sillyaddtwo(42) +-- +SELECT sillyaddtwo(42) +== 108 +drop table mutable2 +-- +DROP TABLE mutable2 +== 109 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo(42) +-- +SELECT sillyaddtwo(42) +== 110 +-- fail +create table mutable2(f0 text, f1 int, f2 text) +-- +CREATE TABLE mutable2 (f0 text, f1 int, f2 text) +== 111 +select sillyaddtwo(42) +-- +SELECT sillyaddtwo(42) +== 112 +select sillyaddtwo(43) +-- +SELECT sillyaddtwo(43) +== 113 +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +-- +CREATE FUNCTION sillytrig() RETURNS trigger LANGUAGE plpgsql AS $$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +== 114 +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +-- +CREATE TRIGGER mutable_trig BEFORE UPDATE ON mutable FOR EACH ROW EXECUTE FUNCTION sillytrig() +== 115 +insert into mutable values ('foo'), ('bar') +-- +INSERT INTO mutable VALUES ('foo'), ('bar') +== 116 +update mutable set f2 = f2 || ' baz' +-- +UPDATE mutable SET f2 = f2 || ' baz' +== 117 +table mutable +-- +SELECT * FROM mutable +== 118 +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$$begin + return row(new.*); +end$$ +-- +CREATE OR REPLACE FUNCTION sillytrig() RETURNS trigger LANGUAGE plpgsql AS $$begin + return row(new.*); +end$$ +== 119 +update mutable set f2 = f2 || ' baz' +-- +UPDATE mutable SET f2 = f2 || ' baz' +== 120 +table mutable +-- +SELECT * FROM mutable +== 121 +create or replace function sillytrig() returns trigger language plpgsql as +$$declare r record; +begin + r := row(new.*); + return r; +end$$ +-- +CREATE OR REPLACE FUNCTION sillytrig() RETURNS trigger LANGUAGE plpgsql AS $$declare r record; +begin + r := row(new.*); + return r; +end$$ +== 122 +update mutable set f2 = f2 || ' baz' +-- +UPDATE mutable SET f2 = f2 || ' baz' +== 123 +table mutable +-- +SELECT * FROM mutable +== 124 +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +-- +CREATE DOMAIN ordered_int8s AS two_int8s CHECK ((value).q1 <= (value).q2) +== 125 +create function read_ordered_int8s(p ordered_int8s) returns int8 as $$ +begin return p.q1 + p.q2; end +$$ language plpgsql +-- +CREATE FUNCTION read_ordered_int8s(p ordered_int8s) RETURNS int8 AS $$ +begin return p.q1 + p.q2; end +$$ LANGUAGE plpgsql +== 126 +select read_ordered_int8s(row(1, 2)) +-- +SELECT read_ordered_int8s(ROW(1, 2)) +== 127 +select read_ordered_int8s(row(2, 1)) +-- +SELECT read_ordered_int8s(ROW(2, 1)) +== 128 +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $$ +begin return row(i,j); end +$$ language plpgsql +-- +CREATE FUNCTION build_ordered_int8s(i int8, j int8) RETURNS ordered_int8s AS $$ +begin return row(i,j); end +$$ LANGUAGE plpgsql +== 129 +select build_ordered_int8s(1,2) +-- +SELECT build_ordered_int8s(1, 2) +== 130 +select build_ordered_int8s(2,1) +-- +SELECT build_ordered_int8s(2, 1) +== 131 +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $$ +declare r record; begin r := row(i,j); return r; end +$$ language plpgsql +-- +CREATE FUNCTION build_ordered_int8s_2(i int8, j int8) RETURNS ordered_int8s AS $$ +declare r record; begin r := row(i,j); return r; end +$$ LANGUAGE plpgsql +== 132 +select build_ordered_int8s_2(1,2) +-- +SELECT build_ordered_int8s_2(1, 2) +== 133 +select build_ordered_int8s_2(2,1) +-- +SELECT build_ordered_int8s_2(2, 1) +== 134 +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +CREATE FUNCTION build_ordered_int8s_3(i int8, j int8) RETURNS ordered_int8s AS $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ LANGUAGE plpgsql +== 135 +select build_ordered_int8s_3(1,2) +-- +SELECT build_ordered_int8s_3(1, 2) +== 136 +select build_ordered_int8s_3(2,1) +-- +SELECT build_ordered_int8s_3(2, 1) +== 137 +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +CREATE FUNCTION build_ordered_int8s_4(i int8, j int8) RETURNS ordered_int8s AS $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ LANGUAGE plpgsql +== 138 +select build_ordered_int8s_4(1,2) +-- +SELECT build_ordered_int8s_4(1, 2) +== 139 +select build_ordered_int8s_4(2,1) +-- +SELECT build_ordered_int8s_4(2, 1) +== 140 +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ language plpgsql +-- +CREATE FUNCTION build_ordered_int8s_a(i int8, j int8) RETURNS ordered_int8s[] AS $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ LANGUAGE plpgsql +== 141 +select build_ordered_int8s_a(1,2) +-- +SELECT build_ordered_int8s_a(1, 2) +== 142 +select build_ordered_int8s_a(2,1) +-- +SELECT build_ordered_int8s_a(2, 1) +== 143 +-- fail + +-- check field assignment +do $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +-- +DO $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +== 144 +-- check whole-row assignment +do $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +-- +DO $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +== 145 +-- check assignment in for-loop +do $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +-- +DO $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +== 146 +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +-- +CREATE TYPE two_texts AS (f1 text, f2 text) +== 147 +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +-- +CREATE DOMAIN ordered_texts AS two_texts CHECK ((value).f1 <= (value).f2) +== 148 +create table sometable (id int, a text, b text) +-- +CREATE TABLE sometable (id int, a text, b text) +== 149 +-- b should be compressed, but in-line +insert into sometable values (1, 'a', repeat('ffoob',1000)) +-- +INSERT INTO sometable VALUES (1, 'a', repeat('ffoob', 1000)) +== 150 +-- this b should be out-of-line +insert into sometable values (2, 'a', repeat('ffoob',100000)) +-- +INSERT INTO sometable VALUES (2, 'a', repeat('ffoob', 100000)) +== 151 +-- this pair should fail the domain check +insert into sometable values (3, 'z', repeat('ffoob',100000)) +-- +INSERT INTO sometable VALUES (3, 'z', repeat('ffoob', 100000)) +== 152 +do $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +-- +DO $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +== 153 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +-- +DO $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +== 154 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +-- +DO $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +== 155 +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$ +-- +CREATE FUNCTION compresult(int8) RETURNS two_int8s LANGUAGE plpgsql AS $$ declare r record; begin r := row($1,$1); return r; end $$ +== 156 +create table two_int8s_tab (f1 two_int8s) +-- +CREATE TABLE two_int8s_tab (f1 two_int8s) +== 157 +insert into two_int8s_tab values (compresult(42)) +-- +INSERT INTO two_int8s_tab VALUES (compresult(42)) +== 158 +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab +-- +SELECT * FROM two_int8s_tab diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_simple.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_simple.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_simple.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_simple.test new file mode 100644 index 0000000..265b847 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_simple.test @@ -0,0 +1,205 @@ +== 001 +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as 'select $1' +-- +CREATE FUNCTION simplesql(int) RETURNS int LANGUAGE sql AS $$select $1$$ +== 002 +create function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +-- +CREATE FUNCTION simplecaller() RETURNS int LANGUAGE plpgsql AS $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +== 003 +select simplecaller() +-- +SELECT simplecaller() +== 004 +-- Check that changes in search path are dealt with correctly +create schema simple1 +-- +CREATE SCHEMA simple1 +== 005 +create function simple1.simpletarget(int) returns int language plpgsql +as $$begin return $1; end$$ +-- +CREATE FUNCTION simple1.simpletarget(int) RETURNS int LANGUAGE plpgsql AS $$begin return $1; end$$ +== 006 +create function simpletarget(int) returns int language plpgsql +as $$begin return $1 + 100; end$$ +-- +CREATE FUNCTION simpletarget(int) RETURNS int LANGUAGE plpgsql AS $$begin return $1 + 100; end$$ +== 007 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +-- +CREATE OR REPLACE FUNCTION simplecaller() RETURNS int LANGUAGE plpgsql AS $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +== 008 +select simplecaller() +-- +SELECT simplecaller() +== 009 +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +-- +ALTER FUNCTION simple1.simpletarget(int) IMMUTABLE +== 010 +alter function simpletarget(int) immutable +-- +ALTER FUNCTION simpletarget(int) IMMUTABLE +== 011 +select simplecaller() +-- +SELECT simplecaller() +== 012 +-- make sure flushing local caches changes nothing + +select simplecaller() +-- +SELECT simplecaller() +== 013 +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $$select 1 / 0$$ +-- +CREATE FUNCTION simplesql() RETURNS int LANGUAGE sql AS $$select 1 / 0$$ +== 014 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +-- +CREATE OR REPLACE FUNCTION simplecaller() RETURNS int LANGUAGE plpgsql AS $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +== 015 +select simplecaller() +-- +SELECT simplecaller() +== 016 +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $$select 2 + 2$$ +-- +CREATE OR REPLACE FUNCTION simplesql() RETURNS int LANGUAGE sql AS $$select 2 + 2$$ +== 017 +select simplecaller() +-- +SELECT simplecaller() +== 018 +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +-- +CREATE OR REPLACE FUNCTION simplecaller() RETURNS int LANGUAGE plpgsql AS $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +== 019 +select simplecaller() +-- +SELECT simplecaller() +== 020 +drop function simplesql() +-- +DROP FUNCTION simplesql() +== 021 +create function simplesql() returns setof int language sql +as $$select 22 + 22$$ +-- +CREATE FUNCTION simplesql() RETURNS SETOF int LANGUAGE sql AS $$select 22 + 22$$ +== 022 +select simplecaller() +-- +SELECT simplecaller() +== 023 +select simplecaller() +-- +SELECT simplecaller() +== 024 +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ +-- +DO $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.test new file mode 100644 index 0000000..ebd107b --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_transaction.test @@ -0,0 +1,1163 @@ +== 001 +CREATE TABLE test1 (a int, b text) +-- +CREATE TABLE test1 (a int, b text) +== 002 +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +CREATE PROCEDURE transaction_test1(x int, y text) LANGUAGE plpgsql AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +== 003 +CALL transaction_test1(9, 'foo') +-- +CALL transaction_test1(9, 'foo') +== 004 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 005 +TRUNCATE test1 +-- +TRUNCATE test1 +== 006 +DO +LANGUAGE plpgsql +$$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +== 007 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 008 +-- transaction commands not allowed when called in transaction block +START TRANSACTION +-- +START TRANSACTION +== 009 +CALL transaction_test1(9, 'error') +-- +CALL transaction_test1(9, 'error') +== 010 +COMMIT +-- +COMMIT +== 011 +START TRANSACTION +-- +START TRANSACTION +== 012 +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +-- +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +== 013 +COMMIT +-- +COMMIT +== 014 +TRUNCATE test1 +-- +TRUNCATE test1 +== 015 +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +-- +CREATE FUNCTION transaction_test2() RETURNS int LANGUAGE plpgsql AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +== 016 +SELECT transaction_test2() +-- +SELECT transaction_test2() +== 017 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 018 +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +-- +CREATE FUNCTION transaction_test3() RETURNS int LANGUAGE plpgsql AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +== 019 +SELECT transaction_test3() +-- +SELECT transaction_test3() +== 020 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 021 +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +-- +CREATE FUNCTION transaction_test4() RETURNS int LANGUAGE plpgsql AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +== 022 +SELECT transaction_test4() +-- +SELECT transaction_test4() +== 023 +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = 555 +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +CREATE PROCEDURE transaction_test5() LANGUAGE plpgsql SET work_mem TO 555 AS $$ +BEGIN + COMMIT; +END; +$$ +== 024 +CALL transaction_test5() +-- +CALL transaction_test5() +== 025 +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +CREATE PROCEDURE transaction_test5b() LANGUAGE plpgsql SECURITY DEFINER AS $$ +BEGIN + COMMIT; +END; +$$ +== 026 +CALL transaction_test5b() +-- +CALL transaction_test5b() +== 027 +TRUNCATE test1 +-- +TRUNCATE test1 +== 028 +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +-- +CREATE PROCEDURE transaction_test6(c text) LANGUAGE plpgsql AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +== 029 +CALL transaction_test6('bar') +-- +CALL transaction_test6('bar') +== 030 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 031 +TRUNCATE test1 +-- +TRUNCATE test1 +== 032 +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +-- +CREATE PROCEDURE transaction_test7() LANGUAGE plpgsql AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +== 033 +CALL transaction_test7() +-- +CALL transaction_test7() +== 034 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 035 +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +-- +CREATE PROCEDURE transaction_test8() LANGUAGE plpgsql AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +== 036 +CALL transaction_test8() +-- +CALL transaction_test8() +== 037 +-- commit inside cursor loop +CREATE TABLE test2 (x int) +-- +CREATE TABLE test2 (x int) +== 038 +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +-- +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +== 039 +TRUNCATE test1 +-- +TRUNCATE test1 +== 040 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +== 041 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 042 +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 043 +-- error in cursor loop with commit +TRUNCATE test1 +-- +TRUNCATE test1 +== 044 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +== 045 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 046 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 047 +-- rollback inside cursor loop +TRUNCATE test1 +-- +TRUNCATE test1 +== 048 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +== 049 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 050 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 051 +-- first commit then rollback inside cursor loop +TRUNCATE test1 +-- +TRUNCATE test1 +== 052 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +== 053 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 054 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 055 +-- rollback inside cursor loop +TRUNCATE test1 +-- +TRUNCATE test1 +== 056 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +== 057 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 058 +SELECT * FROM test2 +-- +SELECT * FROM test2 +== 059 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 060 +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +-- +TRUNCATE test1 +== 061 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +INSERT INTO test1 VALUES (1, 'one'), (2, 'two'), (3, 'three') +== 062 +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +== 063 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 064 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 065 +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +-- +TRUNCATE test1 +== 066 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +INSERT INTO test1 VALUES (1, 'one'), (2, 'two'), (3, 'three') +== 067 +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +== 068 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 069 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 070 +-- commit inside block with exception handler +TRUNCATE test1 +-- +TRUNCATE test1 +== 071 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +== 072 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 073 +-- rollback inside block with exception handler +TRUNCATE test1 +-- +TRUNCATE test1 +== 074 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +== 075 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 076 +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +-- +TRUNCATE test1 +== 077 +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +== 078 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 079 +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +-- +CREATE TEMPORARY TABLE test4 (f1 text) +== 080 +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +-- +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE external +== 081 +-- disable compression +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +-- +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +== 082 +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS 'select f1 from test4' IMMUTABLE +-- +CREATE FUNCTION data_source(i int) RETURNS text LANGUAGE sql AS $$select f1 from test4$$ IMMUTABLE +== 083 +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +-- +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +== 084 +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +-- +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +== 085 +-- COMMIT failures +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +== 086 +SELECT * FROM test3 +-- +SELECT * FROM test3 +== 087 +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +-- +CREATE PROCEDURE cursor_fail_during_commit() LANGUAGE plpgsql AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +== 088 +TRUNCATE test1 +-- +TRUNCATE test1 +== 089 +CALL cursor_fail_during_commit() +-- +CALL cursor_fail_during_commit() +== 090 +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +-- +SELECT count(*) FROM test1 +== 091 +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +-- +CREATE PROCEDURE cursor_fail_during_rollback() LANGUAGE plpgsql AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +== 092 +TRUNCATE test1 +-- +TRUNCATE test1 +== 093 +CALL cursor_fail_during_rollback() +-- +CALL cursor_fail_during_rollback() +== 094 +SELECT count(*) FROM test1 +-- +SELECT count(*) FROM test1 +== 095 +-- SET TRANSACTION +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +== 096 +-- error cases +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +== 097 +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +== 098 +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +== 099 +-- snapshot handling test +TRUNCATE test2 +-- +TRUNCATE test2 +== 100 +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$ +-- +CREATE PROCEDURE transaction_test9() LANGUAGE sql AS $$ +INSERT INTO test2 VALUES (42); +$$ +== 101 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +== 102 +SELECT * FROM test2 +-- +SELECT * FROM test2 +== 103 +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $$ SELECT COUNT(*) FROM test2 $$ +-- +CREATE FUNCTION report_count() RETURNS int STABLE LANGUAGE sql AS $$ SELECT COUNT(*) FROM test2 $$ +== 104 +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +-- +CREATE PROCEDURE transaction_test9b(cnt int) LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +== 105 +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +-- +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +== 106 +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +-- +CREATE PROCEDURE transaction_test10a(INOUT x int) LANGUAGE plpgsql AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +== 107 +CALL transaction_test10a(10) +-- +CALL transaction_test10a(10) +== 108 +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +-- +CREATE PROCEDURE transaction_test10b(INOUT x int) LANGUAGE plpgsql AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +== 109 +CALL transaction_test10b(10) +-- +CALL transaction_test10b(10) +== 110 +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +-- +CREATE PROCEDURE transaction_test11() LANGUAGE plpgsql AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +== 111 +CALL transaction_test11() +-- +CALL transaction_test11() +== 112 +-- transaction chain + +TRUNCATE test1 +-- +TRUNCATE test1 +== 113 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +-- +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +== 114 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 115 +DROP TABLE test1 +-- +DROP TABLE test1 +== 116 +DROP TABLE test2 +-- +DROP TABLE test2 +== 117 +DROP TABLE test3 +-- +DROP TABLE test3 diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_trap.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_trap.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_trap.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_trap.test new file mode 100644 index 0000000..169a0c4 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_trap.test @@ -0,0 +1,395 @@ +== 001 +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +CREATE FUNCTION trap_zero_divide(int) RETURNS int AS $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ LANGUAGE plpgsql +== 002 +select trap_zero_divide(50) +-- +SELECT trap_zero_divide(50) +== 003 +select trap_zero_divide(0) +-- +SELECT trap_zero_divide(0) +== 004 +select trap_zero_divide(100000) +-- +SELECT trap_zero_divide(100000) +== 005 +select trap_zero_divide(-100) +-- +SELECT trap_zero_divide(-100) +== 006 +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +-- +CREATE TABLE match_source AS SELECT x AS id, x * 10 AS data, x / 10 AS ten FROM generate_series(1, 100) x +== 007 +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +CREATE FUNCTION trap_matching_test(int) RETURNS int AS $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ LANGUAGE plpgsql +== 008 +select trap_matching_test(50) +-- +SELECT trap_matching_test(50) +== 009 +select trap_matching_test(0) +-- +SELECT trap_matching_test(0) +== 010 +select trap_matching_test(100000) +-- +SELECT trap_matching_test(100000) +== 011 +select trap_matching_test(1) +-- +SELECT trap_matching_test(1) +== 012 +create temp table foo (f1 int) +-- +CREATE TEMPORARY TABLE foo (f1 int) +== 013 +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql +-- +CREATE FUNCTION subxact_rollback_semantics() RETURNS int AS $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ LANGUAGE plpgsql +== 014 +select subxact_rollback_semantics() +-- +SELECT subxact_rollback_semantics() +== 015 +select * from foo +-- +SELECT * FROM foo +== 016 +drop table foo +-- +DROP TABLE foo +== 017 +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql +-- +CREATE FUNCTION trap_timeout() RETURNS void AS $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ LANGUAGE plpgsql +== 018 +begin +-- +BEGIN +== 019 +set statement_timeout to 1000 +-- +SET statement_timeout TO 1000 +== 020 +select trap_timeout() +-- +SELECT trap_timeout() +== 021 +rollback +-- +ROLLBACK +== 022 +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql +-- +CREATE FUNCTION test_variable_storage() RETURNS text AS $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ LANGUAGE plpgsql +== 023 +select test_variable_storage() +-- +SELECT test_variable_storage() +== 024 +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +-- +CREATE TEMPORARY TABLE root (f1 int PRIMARY KEY) +== 025 +create temp table leaf(f1 int references root deferrable) +-- +CREATE TEMPORARY TABLE leaf (f1 int REFERENCES root DEFERRABLE) +== 026 +insert into root values(1) +-- +INSERT INTO root VALUES (1) +== 027 +insert into leaf values(1) +-- +INSERT INTO leaf VALUES (1) +== 028 +insert into leaf values(2) +-- +INSERT INTO leaf VALUES (2) +== 029 +-- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +CREATE FUNCTION trap_foreign_key(int) RETURNS int AS $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ LANGUAGE plpgsql +== 030 +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +CREATE FUNCTION trap_foreign_key_2() RETURNS int AS $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ LANGUAGE plpgsql +== 031 +select trap_foreign_key(1) +-- +SELECT trap_foreign_key(1) +== 032 +select trap_foreign_key(2) +-- +SELECT trap_foreign_key(2) +== 033 +-- detects FK violation + +begin +-- +BEGIN +== 034 +set constraints all deferred +-- +SET CONSTRAINTS ALL DEFERRED +== 035 +select trap_foreign_key(2) +-- +SELECT trap_foreign_key(2) +== 036 +-- should not detect FK violation + savepoint x +-- +SAVEPOINT x +== 037 +set constraints all immediate +-- +SET CONSTRAINTS ALL IMMEDIATE +== 038 +-- fails + rollback to x +-- +ROLLBACK TO SAVEPOINT x +== 039 +select trap_foreign_key_2() +-- +SELECT trap_foreign_key_2() +== 040 +-- detects FK violation +commit +-- +COMMIT +== 041 +-- still fails + +drop function trap_foreign_key(int) +-- +DROP FUNCTION trap_foreign_key(int) +== 042 +drop function trap_foreign_key_2() +-- +DROP FUNCTION trap_foreign_key_2() diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.test new file mode 100644 index 0000000..5ecb682 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_trigger.test @@ -0,0 +1,46 @@ +== 001 +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +-- +CREATE TABLE testtr (a int, b text) +== 002 +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +-- +CREATE FUNCTION testtr_trigger() RETURNS trigger LANGUAGE plpgsql AS $$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +== 003 +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +-- +CREATE TRIGGER testtr_trigger BEFORE INSERT OR DELETE OR UPDATE ON testtr FOR EACH ROW EXECUTE FUNCTION testtr_trigger() +== 004 +insert into testtr values (1, 'one'), (2, 'two') +-- +INSERT INTO testtr VALUES (1, 'one'), (2, 'two') +== 005 +update testtr set a = a + 1 +-- +UPDATE testtr SET a = a + 1 +== 006 +delete from testtr +-- +DELETE FROM testtr diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.test b/parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.test new file mode 100644 index 0000000..b8a3c76 --- /dev/null +++ b/parser/testdata/deparse/plpgsql_regress/plpgsql_varprops.test @@ -0,0 +1,488 @@ +== 001 +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +-- +CREATE TYPE var_record AS (f1 int4, f2 int4) +== 002 +create domain int_nn as int not null +-- +CREATE DOMAIN int_nn AS int NOT NULL +== 003 +create domain var_record_nn as var_record not null +-- +CREATE DOMAIN var_record_nn AS var_record NOT NULL +== 004 +create domain var_record_colnn as var_record check((value).f2 is not null) +-- +CREATE DOMAIN var_record_colnn AS var_record CHECK ((value).f2 IS NOT NULL) +== 005 +-- CONSTANT + +do $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +== 006 +do $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +-- +DO $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +== 007 +do $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +DO $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +== 008 +do $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +-- +DO $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +== 009 +do $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +-- +DO $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +== 010 +do $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +-- +DO $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +== 011 +do $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +DO $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +== 012 +-- initializer expressions + +do $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +== 013 +do $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +== 014 +do $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +== 015 +do $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +== 016 +do $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +== 017 +-- NOT NULL + +do $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 018 +do $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +DO $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +== 019 +do $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 020 +do $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 021 +do $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +DO $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +== 022 +do $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 023 +do $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 024 +do $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +DO $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +== 025 +do $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 026 +-- Check that variables are reinitialized on block re-entry. + +do $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +-- +DO $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +== 027 +-- Check enforcement of domain constraints during initialization + +do $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +== 028 +do $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 029 +do $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +DO $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +== 030 +do $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +== 031 +do $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 032 +do $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +-- +DO $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +== 033 +do $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +== 034 +do $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +== 035 +do $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +-- +DO $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +== 036 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +DO $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +== 037 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ +-- +DO $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.test new file mode 100644 index 0000000..d64dd6f --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_array.test @@ -0,0 +1,218 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of array variables +|-- +-- We also check arrays of composites here, so this has some overlap +-- with the plpgsql_record tests. +|-- + +create type complex as (r float8, i float8) +-- +9b73912a478ebdaf +== 002 +create type quadarray as (c1 complex[], c2 complex) +-- +9767160e950143ef +== 003 +do $$ declare a int[]; +begin a := array[1,2]; a[3] := 4; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 004 +do $$ declare a int[]; +begin a[3] := 4; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 005 +do $$ declare a int[]; +begin a[1][4] := 4; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 006 +do $$ declare a int[]; +begin a[1] := 23::text; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 007 +-- lax typing + +do $$ declare a int[]; +begin a := array[1,2]; a[2:3] := array[3,4]; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 008 +do $$ declare a int[]; +begin a := array[1,2]; a[2] := a[2] + 1; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 009 +do $$ declare a int[]; +begin a[1:2] := array[3,4]; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 010 +do $$ declare a int[]; +begin a[1:2] := 4; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 011 +-- error + +do $$ declare a complex[]; +begin a[1] := (1,2); a[1].i := 11; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 012 +do $$ declare a complex[]; +begin a[1].i := 11; raise notice 'a = %, a[1].i = %', a, a[1].i; end$$ +-- +f936eab75b8c1b90 +== 013 +-- perhaps this ought to work, but for now it doesn't: +do $$ declare a complex[]; +begin a[1:2].i := array[11,12]; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 014 +do $$ declare a quadarray; +begin a.c1[1].i := 11; raise notice 'a = %, a.c1[1].i = %', a, a.c1[1].i; end$$ +-- +f936eab75b8c1b90 +== 015 +do $$ declare a int[]; +begin a := array_agg(x) from (values(1),(2),(3)) v(x); raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 016 +create temp table onecol as select array[1,2] as f1 +-- +1a341c41250d954c +== 017 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 018 +do $$ declare a int[]; +begin a := * from onecol for update; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 019 +-- error cases: + +do $$ declare a int[]; +begin a := from onecol; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 020 +do $$ declare a int[]; +begin a := f1, f1 from onecol; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 021 +insert into onecol values(array[11]) +-- +9eb30ae770fe7be0 +== 022 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 023 +do $$ declare a int[]; +begin a := f1 from onecol limit 1; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 024 +do $$ declare a real; +begin a[1] := 2; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 025 +do $$ declare a complex; +begin a.r[1] := 2; raise notice 'a = %', a; end$$ +-- +f936eab75b8c1b90 +== 026 +|-- +-- test of %type[] and %rowtype[] syntax +|-- + +-- check supported syntax +do $$ +declare + v int; + v1 v%type; + v2 v%type[]; + v3 v%type[1]; + v4 v%type[][]; + v5 v%type[1][3]; + v6 v%type array; + v7 v%type array[]; + v8 v%type array[1]; + v9 v%type array[1][1]; + v10 pg_catalog.pg_class%rowtype[]; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(v3); + raise notice '%', pg_typeof(v4); + raise notice '%', pg_typeof(v5); + raise notice '%', pg_typeof(v6); + raise notice '%', pg_typeof(v7); + raise notice '%', pg_typeof(v8); + raise notice '%', pg_typeof(v9); + raise notice '%', pg_typeof(v10); +end; +$$ +-- +f936eab75b8c1b90 +== 027 +-- some types don't support arrays +do $$ +declare + v pg_node_tree; + v1 v%type[]; +begin +end; +$$ +-- +f936eab75b8c1b90 +== 028 +-- check functionality +do $$ +declare + v1 int; + v2 varchar; + a1 v1%type[]; + a2 v2%type[]; +begin + v1 := 10; + v2 := 'Hi'; + a1 := array[v1,v1]; + a2 := array[v2,v2]; + raise notice '% %', a1, a2; +end; +$$ +-- +f936eab75b8c1b90 +== 029 +create table array_test_table(a int, b varchar) +-- +5175081ae65e3bc6 +== 030 +insert into array_test_table values(1, 'first'), (2, 'second') +-- +6b5a91a8a312e633 +== 031 +do $$ +declare tg array_test_table%rowtype[]; +begin + tg := array(select array_test_table from array_test_table); + raise notice '%', tg; + tg := array(select row(a,b) from array_test_table); + raise notice '%', tg; +end; +$$ +-- +f936eab75b8c1b90 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.test new file mode 100644 index 0000000..04a2aed --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_cache.test @@ -0,0 +1,82 @@ +== 001 +|-- +-- Cache-behavior-dependent test cases +|-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- depending on debug_discard_caches, so we must have two expected-output +-- files to cover both cases. To minimize the maintenance effort resulting +-- from that, this file should contain only tests that do have different +-- results under debug_discard_caches. +|-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text) +-- +ba5c14746e7b2b98 +== 002 +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +f8f8fbcaba44ec6c +== 003 +select c_sillyaddone(42) +-- +55e0b998386fc67e +== 004 +alter table c_mutable drop column f1 +-- +c75396a33282b8f4 +== 005 +alter table c_mutable add column f1 float8 +-- +467a28ec0cd9f5ac +== 006 +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but if debug_discard_caches is on, it will succeed) +select c_sillyaddone(42) +-- +55e0b998386fc67e +== 007 +-- but it's OK if we force plan rebuilding +discard plans +-- +6e200ea45baf3637 +== 008 +select c_sillyaddone(42) +-- +55e0b998386fc67e +== 009 +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$ +-- +dc44c7b2134dd920 +== 010 +select show_result_type('select 1 as a') +-- +12fbce0557f5f36b +== 011 +-- currently this fails due to cached plan for pg_typeof expression +-- (but if debug_discard_caches is on, it will succeed) +select show_result_type('select 2.0 as a') +-- +12fbce0557f5f36b +== 012 +-- but it's OK if we force plan rebuilding +discard plans +-- +6e200ea45baf3637 +== 013 +select show_result_type('select 2.0 as a') +-- +12fbce0557f5f36b diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.test new file mode 100644 index 0000000..0724f82 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_call.test @@ -0,0 +1,748 @@ +== 001 +|-- +-- Tests for procedures / CALL syntax +|-- + +CREATE PROCEDURE test_proc1() +LANGUAGE plpgsql +AS $$ +BEGIN + NULL; +END; +$$ +-- +e9dd3336c4aa28f3 +== 002 +CALL test_proc1() +-- +3d6abb3a56fcc481 +== 003 +-- error: can't return non-NULL +CREATE PROCEDURE test_proc2() +LANGUAGE plpgsql +AS $$ +BEGIN + RETURN 5; +END; +$$ +-- +b5f7d687dcf57801 +== 004 +CREATE TABLE test1 (a int) +-- +5d991a76abfb450a +== 005 +CREATE PROCEDURE test_proc3(x int) +LANGUAGE plpgsql +AS $$ +BEGIN + INSERT INTO test1 VALUES (x); +END; +$$ +-- +866232853128ca34 +== 006 +CALL test_proc3(55) +-- +431da5ad31538a6b +== 007 +SELECT * FROM test1 +-- +57550c6644afee58 +== 008 +-- Check that plan revalidation doesn't prevent setting transaction properties +-- (bug #18059). This test must include the first temp-object creation in +-- this script, or it won't exercise the bug scenario. Hence we put it early. +CREATE PROCEDURE test_proc3a() +LANGUAGE plpgsql +AS $$ +BEGIN + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + RAISE NOTICE 'done'; +END; +$$ +-- +17b6bc3126a1f1e7 +== 009 +CALL test_proc3a() +-- +322b42515635f84a +== 010 +CREATE TEMP TABLE tt1(f1 int) +-- +cecd718310a73ba0 +== 011 +CALL test_proc3a() +-- +322b42515635f84a +== 012 +-- nested CALL +TRUNCATE TABLE test1 +-- +5270aa06ddf1345c +== 013 +CREATE PROCEDURE test_proc4(y int) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL test_proc3(y); + CALL test_proc3($1); +END; +$$ +-- +5bfb8aab078a294d +== 014 +CALL test_proc4(66) +-- +fc948affa2254718 +== 015 +SELECT * FROM test1 +-- +57550c6644afee58 +== 016 +CALL test_proc4(66) +-- +fc948affa2254718 +== 017 +SELECT * FROM test1 +-- +57550c6644afee58 +== 018 +-- output arguments + +CREATE PROCEDURE test_proc5(INOUT a text) +LANGUAGE plpgsql +AS $$ +BEGIN + a := a || '+' || a; +END; +$$ +-- +af71540045d2690e +== 019 +CALL test_proc5('abc') +-- +83d041a11f606bd8 +== 020 +CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + b := b * a; + c := c * a; +END; +$$ +-- +a8d1fe8db1fa00dc +== 021 +CALL test_proc6(2, 3, 4) +-- +b04b4952f4321a1e +== 022 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); + RAISE INFO 'x = %, y = %', x, y; + CALL test_proc6(2, c => y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +f936eab75b8c1b90 +== 023 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +f936eab75b8c1b90 +== 024 +DO +LANGUAGE plpgsql +$$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +-- +f936eab75b8c1b90 +== 025 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 026 +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +-- +03ca97f927b47af3 +== 027 +CALL test_proc7(100, -1, -1) +-- +48bd0eabd8627223 +== 028 +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +-- +b585a526e7a169c8 +== 029 +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +-- +95d88b16513ff4b1 +== 030 +CALL test_proc7cc(10) +-- +3424ffefe2bbc51f +== 031 +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +-- +2075976b27f4e886 +== 032 +CALL test_proc8a(10, 20) +-- +b84a8c2dbe3dc4f0 +== 033 +CALL test_proc8a(b => 20, a => 10) +-- +d0cd181cb59220f6 +== 034 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +f936eab75b8c1b90 +== 035 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +687d3c801927d20e +== 036 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 037 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +d4a8196e77430542 +== 038 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 039 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 040 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 041 +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +-- +3acc392753e1f2c2 +== 042 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +f936eab75b8c1b90 +== 043 +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +-- +0d4d81ff81a348a1 +== 044 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 045 +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +-- +a70a29eeba8be880 +== 046 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 047 +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +-- +0a3596dde6e74d78 +== 048 +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 049 +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +f936eab75b8c1b90 +== 050 +-- transition variable assignment + +TRUNCATE test1 +-- +5270aa06ddf1345c +== 051 +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +-- +8fdfbce35a1ebb83 +== 052 +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +-- +6e7fdd5607284b34 +== 053 +INSERT INTO test1 VALUES (1), (2), (3) +-- +8c91d6c1e15fa014 +== 054 +UPDATE test1 SET a = 22 WHERE a = 2 +-- +188f76fda8d32674 +== 055 +SELECT * FROM test1 ORDER BY a +-- +8c2f028d19e22473 +== 056 +DROP PROCEDURE test_proc1 +-- +21e1fe5c0562ec99 +== 057 +DROP PROCEDURE test_proc3 +-- +5fee600485c371b6 +== 058 +DROP PROCEDURE test_proc4 +-- +7e41ba85b2b2a6ae +== 059 +DROP TABLE test1 +-- +9fdd9d3006af8e29 +== 060 +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +-- +bed5f4fec9529681 +== 061 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +-- +f936eab75b8c1b90 +== 062 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +f936eab75b8c1b90 +== 063 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +f936eab75b8c1b90 +== 064 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +f936eab75b8c1b90 +== 065 +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +-- +76d7981eac9aaec5 +== 066 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +-- +af1ccbbbfac0e515 +== 067 +CREATE PROCEDURE outer_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +2448e38ee42bcea2 +== 068 +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +13311a0879c5418b +== 069 +CALL outer_p(42) +-- +1230824a2dc132db +== 070 +SELECT outer_f(42) +-- +275b575dbfc1c2e7 +== 071 +DROP FUNCTION f(int) +-- +d32f4a9fe630273b +== 072 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +-- +af1ccbbbfac0e515 +== 073 +CALL outer_p(42) +-- +1230824a2dc132db +== 074 +SELECT outer_f(42) +-- +275b575dbfc1c2e7 +== 075 +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +-- +7d6c6c8cc430cfec +== 076 +INSERT INTO t_test VALUES (0) +-- +1a0c8dc5f97f5d8c +== 077 +CREATE FUNCTION f_get_x () RETURNS int +AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +-- +aa553f4de4ea282c +== 078 +CREATE PROCEDURE f_print_x (x int) +AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +-- +f599f9d54ea6a780 +== 079 +-- test in non-atomic context +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +-- +f936eab75b8c1b90 +== 080 +-- test in non-atomic context, except exception block is locally atomic +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +-- +f936eab75b8c1b90 +== 081 +-- test in atomic context +BEGIN +-- +b16b431979fc3e05 +== 082 +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +-- +f936eab75b8c1b90 +== 083 +ROLLBACK +-- +a46081a556fda027 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.test new file mode 100644 index 0000000..673c49c --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_control.test @@ -0,0 +1,627 @@ +== 001 +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 002 +-- BY can't be zero or negative +do $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 003 +do $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 004 +do $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 005 +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +-- +96c84b60e0663c15 +== 006 +insert into conttesttbl(v) values(10) +-- +81c5163797b3e367 +== 007 +insert into conttesttbl(v) values(20) +-- +81c5163797b3e367 +== 008 +insert into conttesttbl(v) values(30) +-- +81c5163797b3e367 +== 009 +insert into conttesttbl(v) values(40) +-- +81c5163797b3e367 +== 010 +create function continue_test1() returns void as $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ language plpgsql +-- +23017af17050a0ff +== 011 +select continue_test1() +-- +56a2eff9030d6a03 +== 012 +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $$ +begin + begin + continue; + end; +end; +$$ language plpgsql +-- +3544bac913ab9916 +== 013 +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $$ +begin + begin + exit; + end; +end; +$$ language plpgsql +-- +3138c9300d8a8018 +== 014 +-- should fail: no such label +create function continue_error2() returns void as $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +951ce6db50cf2013 +== 015 +-- should fail: no such label +create function exit_error2() returns void as $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +b86df4d6b04598f0 +== 016 +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ language plpgsql +-- +e36577ac743cce59 +== 017 +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ language plpgsql +-- +a86649bfc445511a +== 018 +select exit_block1() +-- +d25bcc8f3324ec9f +== 019 +-- verbose end block and end loop +create function end_label1() returns void as $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ language plpgsql +-- +3b484e47afc38700 +== 020 +select end_label1() +-- +426409857206cd96 +== 021 +-- should fail: undefined end label +create function end_label2() returns void as $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ language plpgsql +-- +e99320a55304a15c +== 022 +-- should fail: end label does not match start label +create function end_label3() returns void as $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +29aa52982dd97b28 +== 023 +-- should fail: end label on a block without a start label +create function end_label4() returns void as $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +3ce5dcc3733a0fd1 +== 024 +-- unlabeled exit matches no blocks +do $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +-- +f936eab75b8c1b90 +== 025 +-- check exit out of an unlabeled block to a labeled one +do $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +-- +f936eab75b8c1b90 +== 026 +-- check exit out of outermost block +do $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +-- +f936eab75b8c1b90 +== 027 +-- unlabeled exit does match a while loop +do $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +-- +f936eab75b8c1b90 +== 028 +-- check exit out of an unlabeled while to a labeled one +do $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +-- +f936eab75b8c1b90 +== 029 +-- continue to an outer while +do $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +-- +f936eab75b8c1b90 +== 030 +-- return out of a while +create function return_from_while() returns int language plpgsql as $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +-- +d1c13ef629707f4d +== 031 +select return_from_while() +-- +d19da47eaba6bbfe +== 032 +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $proc$ +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice '%', i; + end loop; + -- fore with record var + for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop + raise notice '% % %', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice '%', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop + raise notice '% % %', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop + raise notice '% % %', a, b, c; + end loop; +end; +$proc$ language plpgsql +-- +e08c9dabeec0efa8 +== 033 +select for_vect() +-- +b0f6142c08412ede +== 034 +-- CASE statement + +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ language plpgsql immutable +-- +dc36eb4267ae485a +== 035 +select case_test(1) +-- +25b1382a48c321f7 +== 036 +select case_test(2) +-- +25b1382a48c321f7 +== 037 +select case_test(3) +-- +25b1382a48c321f7 +== 038 +select case_test(4) +-- +25b1382a48c321f7 +== 039 +select case_test(5) +-- +25b1382a48c321f7 +== 040 +-- fails +select case_test(8) +-- +25b1382a48c321f7 +== 041 +select case_test(10) +-- +25b1382a48c321f7 +== 042 +select case_test(11) +-- +25b1382a48c321f7 +== 043 +select case_test(12) +-- +25b1382a48c321f7 +== 044 +select case_test(13) +-- +25b1382a48c321f7 +== 045 +-- fails + +create or replace function catch() returns void as $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ language plpgsql +-- +d4cf615ef8422787 +== 046 +select catch() +-- +eb7514820113c76c +== 047 +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +dc36eb4267ae485a +== 048 +select case_test(1) +-- +25b1382a48c321f7 +== 049 +select case_test(2) +-- +25b1382a48c321f7 +== 050 +select case_test(12) +-- +25b1382a48c321f7 +== 051 +select case_test(13) +-- +25b1382a48c321f7 +== 052 +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +5c017dd6a0b0b605 +== 053 +select case_comment(1) +-- +cb83a6cbf93bda28 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.test new file mode 100644 index 0000000..2788c56 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_copy.test @@ -0,0 +1,21 @@ +== 001 +-- directory paths are passed to us in environment variables + +-- set up file names to use + +CREATE TABLE copy1 (a int, b float); + +-- COPY TO/FROM not authorized from client. +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 TO stdout; +END; +$$; +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 FROM stdin; +-- +ERROR: "unterminated dollar-quoted string at or near \"$$\nBEGIN\n COPY copy1 FROM stdin;\"" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.test new file mode 100644 index 0000000..6ed168d --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_domain.test @@ -0,0 +1,483 @@ +== 001 +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +-- +69370178a944aef6 +== 002 +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +74a64ea51e65b183 +== 003 +SELECT * FROM test_argresult_booltrue(true, true) +-- +593384214f9540c2 +== 004 +SELECT * FROM test_argresult_booltrue(false, true) +-- +593384214f9540c2 +== 005 +SELECT * FROM test_argresult_booltrue(true, false) +-- +593384214f9540c2 +== 006 +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +3d8911e942aee034 +== 007 +SELECT * FROM test_assign_booltrue(true, true) +-- +ff497d95c79fe36d +== 008 +SELECT * FROM test_assign_booltrue(false, true) +-- +ff497d95c79fe36d +== 009 +SELECT * FROM test_assign_booltrue(true, false) +-- +ff497d95c79fe36d +== 010 +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +-- +0d9162e9122b24bb +== 011 +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +d9dd266e971f0878 +== 012 +SELECT * FROM test_argresult_uint2(100::uint2, 50) +-- +16eb0e0503b4dd49 +== 013 +SELECT * FROM test_argresult_uint2(100::uint2, -50) +-- +16eb0e0503b4dd49 +== 014 +SELECT * FROM test_argresult_uint2(null, 1) +-- +16eb0e0503b4dd49 +== 015 +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +0c5cc9372a53cf11 +== 016 +SELECT * FROM test_assign_uint2(100, 50) +-- +a9222b86a0db996e +== 017 +SELECT * FROM test_assign_uint2(100, -50) +-- +a9222b86a0db996e +== 018 +SELECT * FROM test_assign_uint2(-100, 50) +-- +a9222b86a0db996e +== 019 +SELECT * FROM test_assign_uint2(null, 1) +-- +a9222b86a0db996e +== 020 +CREATE DOMAIN nnint AS int NOT NULL +-- +520b04831cc1ff7f +== 021 +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +aef122d32b05027b +== 022 +SELECT * FROM test_argresult_nnint(10, 20) +-- +3325272165b1809a +== 023 +SELECT * FROM test_argresult_nnint(null, 20) +-- +3325272165b1809a +== 024 +SELECT * FROM test_argresult_nnint(10, null) +-- +3325272165b1809a +== 025 +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +d4dff5e37a8053dd +== 026 +SELECT * FROM test_assign_nnint(10, 20) +-- +b9ce10d353f45dec +== 027 +SELECT * FROM test_assign_nnint(null, 20) +-- +b9ce10d353f45dec +== 028 +SELECT * FROM test_assign_nnint(10, null) +-- +b9ce10d353f45dec +== 029 +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +-- +1f50674eeebfb0fa +== 030 +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +-- +513e509c7977a4dd +== 031 +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +-- +03c4e1dbbbb8e703 +== 032 +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +-- +4b22b0fc3151b8fa +== 033 +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +-- +c2ca4b8de182b1fb +== 034 +SELECT * FROM test_argresult_array_domain_check_violation() +-- +ec920a6d65c94883 +== 035 +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +-- +6dd3dfeda7281efa +== 036 +SELECT * FROM test_assign_ordered_pair_domain(1,2,3) +-- +bf34e6db717719b0 +== 037 +SELECT * FROM test_assign_ordered_pair_domain(1,2,0) +-- +bf34e6db717719b0 +== 038 +SELECT * FROM test_assign_ordered_pair_domain(2,1,3) +-- +bf34e6db717719b0 +== 039 +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +bf9e107bd9c2e65c +== 040 +select test_read_uint2_array(array[1::uint2]) +-- +4766659b49f4383b +== 041 +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +-- +a69ebefc5925f8a5 +== 042 +select test_build_uint2_array(1::int2) +-- +3cad921290368c5c +== 043 +select test_build_uint2_array(-1::int2) +-- +4c8e4aff79477a13 +== 044 +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +-- +3475547a538dbdcd +== 045 +select test_argresult_domain_array(array[2,4]) +-- +388a34e1f616c7d1 +== 046 +select test_argresult_domain_array(array[4,2]) +-- +388a34e1f616c7d1 +== 047 +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +4d2e87d61fa34eca +== 048 +select test_argresult_domain_array2(array[2,4]) +-- +0f71233a196a9545 +== 049 +select test_argresult_domain_array2(array[4,2]) +-- +0f71233a196a9545 +== 050 +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +38800d15407f49f2 +== 051 +select test_argresult_array_domain_array(array[array[2,4]::ordered_pair_domain]) +-- +28f96aaffb5f93c8 +== 052 +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +-- +fed8252ea7ebb7cf +== 053 +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +-- +56a9b84d3f2866fa +== 054 +SELECT test_result_nnint_container(null, 3) +-- +39c9f00133e056f8 +== 055 +SELECT test_result_nnint_container(3, null) +-- +39c9f00133e056f8 +== 056 +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +14fbd54ec4c1d083 +== 057 +SELECT * FROM test_assign_nnint_container(1,2,3) +-- +51282e382b0662d6 +== 058 +SELECT * FROM test_assign_nnint_container(1,2,null) +-- +51282e382b0662d6 +== 059 +SELECT * FROM test_assign_nnint_container(1,null,3) +-- +51282e382b0662d6 +== 060 +-- Since core system allows this: +SELECT null::nnint_container +-- +50fde20626009aba +== 061 +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +95aa56170d8a8000 +== 062 +SELECT * FROM test_assign_nnint_container2(1,2,3) +-- +e39c33bdd101ccbe +== 063 +SELECT * FROM test_assign_nnint_container2(1,2,null) +-- +e39c33bdd101ccbe +== 064 +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +-- +db9827d9a76c7f34 +== 065 +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +-- +b125c9d27057ed9d +== 066 +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +-- +af732c5102df0fb9 +== 067 +SELECT read_ordered_named_pair(row(1, 2)) +-- +99ab12d530b4c8f6 +== 068 +SELECT read_ordered_named_pair(row(2, 1)) +-- +99ab12d530b4c8f6 +== 069 +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +-- +8d4cab8e5d21a6bd +== 070 +SELECT build_ordered_named_pair(1,2) +-- +2e8e719e7086bcfb +== 071 +SELECT build_ordered_named_pair(2,1) +-- +2e8e719e7086bcfb +== 072 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +c3cf333d0584116b +== 073 +SELECT * FROM test_assign_ordered_named_pair(1,2,3) +-- +d217c8ce1c60387e +== 074 +SELECT * FROM test_assign_ordered_named_pair(1,2,0) +-- +d217c8ce1c60387e +== 075 +SELECT * FROM test_assign_ordered_named_pair(2,1,3) +-- +d217c8ce1c60387e +== 076 +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +-- +d92acb3b6fa1faa8 +== 077 +SELECT build_ordered_named_pairs(1,2) +-- +412ede52728698e8 +== 078 +SELECT build_ordered_named_pairs(2,1) +-- +412ede52728698e8 +== 079 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +f88b5f02dd081a96 +== 080 +SELECT * FROM test_assign_ordered_named_pairs(1,2,3) +-- +eaf6cdf00d44e9f2 +== 081 +SELECT * FROM test_assign_ordered_named_pairs(2,1,3) +-- +eaf6cdf00d44e9f2 +== 082 +SELECT * FROM test_assign_ordered_named_pairs(1,2,0) +-- +eaf6cdf00d44e9f2 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.test new file mode 100644 index 0000000..d0ae262 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_misc.test @@ -0,0 +1,77 @@ +== 001 +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +-- +f936eab75b8c1b90 +== 002 +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +-- +aa00ab4efdbf21c6 +== 003 +do $$ declare x foo%type; begin end $$ +-- +f936eab75b8c1b90 +== 004 +do $$ declare x notice%type; begin end $$ +-- +f936eab75b8c1b90 +== 005 +-- covers unreserved-keyword case +do $$ declare x foo.bar%type; begin end $$ +-- +f936eab75b8c1b90 +== 006 +do $$ declare x foo.bar.baz%type; begin end $$ +-- +f936eab75b8c1b90 +== 007 +do $$ declare x public.foo.bar%type; begin end $$ +-- +f936eab75b8c1b90 +== 008 +do $$ declare x public.misc_table.zed%type; begin end $$ +-- +f936eab75b8c1b90 +== 009 +do $$ declare x foo%rowtype; begin end $$ +-- +f936eab75b8c1b90 +== 010 +do $$ declare x notice%rowtype; begin end $$ +-- +f936eab75b8c1b90 +== 011 +-- covers unreserved-keyword case +do $$ declare x foo.bar%rowtype; begin end $$ +-- +f936eab75b8c1b90 +== 012 +do $$ declare x foo.bar.baz%rowtype; begin end $$ +-- +f936eab75b8c1b90 +== 013 +do $$ declare x public.foo%rowtype; begin end $$ +-- +f936eab75b8c1b90 +== 014 +do $$ declare x public.misc_table%rowtype; begin end $$ +-- +f936eab75b8c1b90 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.test new file mode 100644 index 0000000..f662b31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_record.test @@ -0,0 +1,990 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +-- +beec9e99b48bd933 +== 002 +create type more_int4s as (f0 text, f1 int4, f2 int4) +-- +870a6ac953d930e0 +== 003 +create type two_int8s as (q1 int8, q2 int8) +-- +489ac2c2ae61e609 +== 004 +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +-- +4b99a0af17044d9d +== 005 +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1)::two_int8s; end $$ +-- +dd1c31f6aa367c45 +== 006 +select retc(42) +-- +0f388b2602dd5c3b +== 007 +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8); end $$ +-- +d53a9736868e4965 +== 008 +select retc(42) +-- +0f388b2602dd5c3b +== 009 +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1); end $$ +-- +d53a9736868e4965 +== 010 +select retc(42) +-- +0f388b2602dd5c3b +== 011 +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8, 42); end $$ +-- +d53a9736868e4965 +== 012 +select retc(42) +-- +0f388b2602dd5c3b +== 013 +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +-- +d53a9736868e4965 +== 014 +select retc(42) +-- +0f388b2602dd5c3b +== 015 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,1); return r; end $$ +-- +d53a9736868e4965 +== 016 +select retc(42) +-- +0f388b2602dd5c3b +== 017 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +d53a9736868e4965 +== 018 +select retc(42) +-- +0f388b2602dd5c3b +== 019 +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +d53a9736868e4965 +== 020 +select retc(42) +-- +0f388b2602dd5c3b +== 021 +do $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +-- +f936eab75b8c1b90 +== 022 +do $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +-- +f936eab75b8c1b90 +== 023 +do $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +-- +f936eab75b8c1b90 +== 024 +do $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +-- +f936eab75b8c1b90 +== 025 +-- block-qualified naming +do $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +-- +f936eab75b8c1b90 +== 026 +-- error cases +do $$ declare c two_int8s; begin c.x = 1; end $$ +-- +f936eab75b8c1b90 +== 027 +do $$ declare c nested_int8s; begin c.x = 1; end $$ +-- +f936eab75b8c1b90 +== 028 +do $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +-- +f936eab75b8c1b90 +== 029 +do $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +-- +f936eab75b8c1b90 +== 030 +do $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +-- +f936eab75b8c1b90 +== 031 +do $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +-- +f936eab75b8c1b90 +== 032 +do $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +-- +f936eab75b8c1b90 +== 033 +do $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +-- +f936eab75b8c1b90 +== 034 +do $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +-- +f936eab75b8c1b90 +== 035 +do $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +-- +f936eab75b8c1b90 +== 036 +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +-- +4f324f6b3490e353 +== 037 +select getq1(retc(344)) +-- +f8d60b3f490377b2 +== 038 +select getq1(row(1,2)) +-- +f3e68499b1c67ff3 +== 039 +do $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 040 +-- check assignments of composites +do $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +-- +f936eab75b8c1b90 +== 041 +-- fields of named-type vars read as null if uninitialized +do $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +-- +f936eab75b8c1b90 +== 042 +do $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +f936eab75b8c1b90 +== 043 +-- records, not so much +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +-- +f936eab75b8c1b90 +== 044 +-- but OK if you assign first +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +f936eab75b8c1b90 +== 045 +-- check %type with block-qualified variable names +do $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +-- +f936eab75b8c1b90 +== 046 +-- check that type record can be passed through %type +do $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +-- +f936eab75b8c1b90 +== 047 +-- arrays of record are not supported at the moment +do $$ +declare r1 record[]; +begin +end$$ +-- +f936eab75b8c1b90 +== 048 +do $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +-- +f936eab75b8c1b90 +== 049 +-- check repeated assignments to composite fields +create table some_table (id int, data text) +-- +3d5673c2182fd703 +== 050 +do $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +-- +f936eab75b8c1b90 +== 051 +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1); end $$ +-- +8a8ebef209b2e0ad +== 052 +select returnsrecord(42) +-- +45ab315a2f768e0e +== 053 +select * from returnsrecord(42) as r(x int, y int) +-- +cdeb7c1b5cf2cd43 +== 054 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +216d87745f41273c +== 055 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +184298095c814cd1 +== 056 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1); return r; end $$ +-- +5af4f0a64afdeac4 +== 057 +select returnsrecord(42) +-- +45ab315a2f768e0e +== 058 +select * from returnsrecord(42) as r(x int, y int) +-- +cdeb7c1b5cf2cd43 +== 059 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +216d87745f41273c +== 060 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +184298095c814cd1 +== 061 +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +-- +1b70c47c0821c3c2 +== 062 +alter table has_hole drop column f2 +-- +69f1362388cb8399 +== 063 +create or replace function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1)::has_hole; end $$ +-- +5af4f0a64afdeac4 +== 064 +select returnsrecord(42) +-- +45ab315a2f768e0e +== 065 +select * from returnsrecord(42) as r(x int, y int) +-- +cdeb7c1b5cf2cd43 +== 066 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +216d87745f41273c +== 067 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +184298095c814cd1 +== 068 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +-- +5af4f0a64afdeac4 +== 069 +select returnsrecord(42) +-- +45ab315a2f768e0e +== 070 +select * from returnsrecord(42) as r(x int, y int) +-- +cdeb7c1b5cf2cd43 +== 071 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +216d87745f41273c +== 072 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +184298095c814cd1 +== 073 +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$$ begin return x.f1; end $$ +-- +3022ce6d0870e014 +== 074 +select getf1(1) +-- +7de13ad2fa71cae8 +== 075 +select getf1(row(1,2)) +-- +b7239cb129a0647a +== 076 +select getf1(row(1,2)::two_int4s) +-- +2ec68937a66e7f4b +== 077 +select getf1(row('foo',123,456)::more_int4s) +-- +d9707a25b1084cc7 +== 078 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row(1,2)::two_int8s) +-- +b0f12f8013d83beb +== 079 +select getf1(row(1,2)) +-- +b7239cb129a0647a +== 080 +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$$ begin return $1.f2; end $$ +-- +2dbd3b08b3db8f0b +== 081 +select getf2(row(1,2)) +-- +b37566d209b13f41 +== 082 +-- ideally would work, but does not +select getf2(row(1,2)::two_int4s) +-- +ae5d997f2625cd5f +== 083 +select getf2(row('foo',123,456)::more_int4s) +-- +8b9d582719207525 +== 084 +-- check behavior when assignment to FOR-loop variable requires coercion +do $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 085 +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +-- +2bc4f6f4ec20f9dc +== 086 +select returnssetofholes() +-- +cc564d34f7dd4ad0 +== 087 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +-- +53ee1becf6a2677a +== 088 +select returnssetofholes() +-- +cc564d34f7dd4ad0 +== 089 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +begin + return next row(1,2,3); -- fails +end$$ +-- +53ee1becf6a2677a +== 090 +select returnssetofholes() +-- +cc564d34f7dd4ad0 +== 091 +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +-- +399c9615f41783ee +== 092 +create function sillyaddone(int) returns int language plpgsql as +$$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +e004e78d7dc89716 +== 093 +select sillyaddone(42) +-- +72c91c0ff0daf28f +== 094 +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +-- +2d6722abd5871810 +== 095 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone(42) +-- +72c91c0ff0daf28f +== 096 +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$$ begin return x.f3; end $$ +-- +95daa0e80befc108 +== 097 +select getf3(null::mutable) +-- +f1aaf7660139c314 +== 098 +-- doesn't work yet +alter table mutable add column f3 int +-- +11573d958da6948c +== 099 +select getf3(null::mutable) +-- +f1aaf7660139c314 +== 100 +-- now it works +alter table mutable drop column f3 +-- +a4c0f5606421f3dc +== 101 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3(null::mutable) +-- +f1aaf7660139c314 +== 102 +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off +-- +f8d4a000b73082a4 +== 103 +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +-- +93f412cfccac2d88 +== 104 +reset check_function_bodies +-- +507d70c54f92e61b +== 105 +select sillyaddtwo(42) +-- +f553c3580fb50a15 +== 106 +-- fail +create table mutable2(f1 int, f2 text) +-- +70b73cede4134f10 +== 107 +select sillyaddtwo(42) +-- +f553c3580fb50a15 +== 108 +drop table mutable2 +-- +6efea2a02986013c +== 109 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo(42) +-- +f553c3580fb50a15 +== 110 +-- fail +create table mutable2(f0 text, f1 int, f2 text) +-- +63f274197c355177 +== 111 +select sillyaddtwo(42) +-- +f553c3580fb50a15 +== 112 +select sillyaddtwo(43) +-- +f553c3580fb50a15 +== 113 +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +-- +f7d7356f6933307a +== 114 +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +-- +8a16021e4853656d +== 115 +insert into mutable values ('foo'), ('bar') +-- +c958c44442943532 +== 116 +update mutable set f2 = f2 || ' baz' +-- +199ed2107f52c5b0 +== 117 +table mutable +-- +6628f285331408be +== 118 +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$$begin + return row(new.*); +end$$ +-- +32a152421f4c5480 +== 119 +update mutable set f2 = f2 || ' baz' +-- +199ed2107f52c5b0 +== 120 +table mutable +-- +6628f285331408be +== 121 +create or replace function sillytrig() returns trigger language plpgsql as +$$declare r record; +begin + r := row(new.*); + return r; +end$$ +-- +32a152421f4c5480 +== 122 +update mutable set f2 = f2 || ' baz' +-- +199ed2107f52c5b0 +== 123 +table mutable +-- +6628f285331408be +== 124 +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +-- +007f203b2858f04c +== 125 +create function read_ordered_int8s(p ordered_int8s) returns int8 as $$ +begin return p.q1 + p.q2; end +$$ language plpgsql +-- +da46572d125775f7 +== 126 +select read_ordered_int8s(row(1, 2)) +-- +5909bb9e251c9dc5 +== 127 +select read_ordered_int8s(row(2, 1)) +-- +5909bb9e251c9dc5 +== 128 +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $$ +begin return row(i,j); end +$$ language plpgsql +-- +c558ce340f32c308 +== 129 +select build_ordered_int8s(1,2) +-- +5e8c235269a5dc11 +== 130 +select build_ordered_int8s(2,1) +-- +5e8c235269a5dc11 +== 131 +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $$ +declare r record; begin r := row(i,j); return r; end +$$ language plpgsql +-- +d9ff9f21fb47525d +== 132 +select build_ordered_int8s_2(1,2) +-- +2888bb305ce4bbc4 +== 133 +select build_ordered_int8s_2(2,1) +-- +2888bb305ce4bbc4 +== 134 +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +d6a8f1c1171d9b4f +== 135 +select build_ordered_int8s_3(1,2) +-- +f352ab0b3c879e26 +== 136 +select build_ordered_int8s_3(2,1) +-- +f352ab0b3c879e26 +== 137 +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +c0bb7a6096372a95 +== 138 +select build_ordered_int8s_4(1,2) +-- +b47ca5f3e93cd1e6 +== 139 +select build_ordered_int8s_4(2,1) +-- +b47ca5f3e93cd1e6 +== 140 +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ language plpgsql +-- +538b16284108d4fd +== 141 +select build_ordered_int8s_a(1,2) +-- +40b2459a90b3f23c +== 142 +select build_ordered_int8s_a(2,1) +-- +40b2459a90b3f23c +== 143 +-- fail + +-- check field assignment +do $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +-- +f936eab75b8c1b90 +== 144 +-- check whole-row assignment +do $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +-- +f936eab75b8c1b90 +== 145 +-- check assignment in for-loop +do $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 146 +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +-- +f1d3bb611e7aa58d +== 147 +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +-- +318168cb672a6cf8 +== 148 +create table sometable (id int, a text, b text) +-- +4f147bbee6d1fa56 +== 149 +-- b should be compressed, but in-line +insert into sometable values (1, 'a', repeat('ffoob',1000)) +-- +f2f9ceb7ae00dcaf +== 150 +-- this b should be out-of-line +insert into sometable values (2, 'a', repeat('ffoob',100000)) +-- +f2f9ceb7ae00dcaf +== 151 +-- this pair should fail the domain check +insert into sometable values (3, 'z', repeat('ffoob',100000)) +-- +f2f9ceb7ae00dcaf +== 152 +do $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 153 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +-- +f936eab75b8c1b90 +== 154 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 155 +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$ +-- +ff451c154b6dd3b8 +== 156 +create table two_int8s_tab (f1 two_int8s) +-- +ddde24e70645e4a6 +== 157 +insert into two_int8s_tab values (compresult(42)) +-- +b9fdfa09349645a2 +== 158 +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab +-- +f961d045d8fb63d1 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.test new file mode 100644 index 0000000..251a6cd --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_simple.test @@ -0,0 +1,164 @@ +== 001 +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as 'select $1' +-- +783ef15990c552ff +== 002 +create function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +-- +d8872044e04b8a81 +== 003 +select simplecaller() +-- +a95148bc1c9c7d17 +== 004 +-- Check that changes in search path are dealt with correctly +create schema simple1 +-- +d031bf9fd3fa1db9 +== 005 +create function simple1.simpletarget(int) returns int language plpgsql +as $$begin return $1; end$$ +-- +9e6421a8d6d3ec20 +== 006 +create function simpletarget(int) returns int language plpgsql +as $$begin return $1 + 100; end$$ +-- +d34839c95f66568a +== 007 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +-- +2cf6983ca6dd1c57 +== 008 +select simplecaller() +-- +a95148bc1c9c7d17 +== 009 +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +-- +67cd42590375fd8d +== 010 +alter function simpletarget(int) immutable +-- +b4073d41bf67acdf +== 011 +select simplecaller() +-- +a95148bc1c9c7d17 +== 012 +-- make sure flushing local caches changes nothing + +select simplecaller() +-- +a95148bc1c9c7d17 +== 013 +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $$select 1 / 0$$ +-- +622a52bb06b85a4d +== 014 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +-- +2cf6983ca6dd1c57 +== 015 +select simplecaller() +-- +a95148bc1c9c7d17 +== 016 +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $$select 2 + 2$$ +-- +14234346f0950c33 +== 017 +select simplecaller() +-- +a95148bc1c9c7d17 +== 018 +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +-- +2cf6983ca6dd1c57 +== 019 +select simplecaller() +-- +a95148bc1c9c7d17 +== 020 +drop function simplesql() +-- +708466fde18d7326 +== 021 +create function simplesql() returns setof int language sql +as $$select 22 + 22$$ +-- +491d881dd0d40368 +== 022 +select simplecaller() +-- +a95148bc1c9c7d17 +== 023 +select simplecaller() +-- +a95148bc1c9c7d17 +== 024 +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ +-- +f936eab75b8c1b90 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.test new file mode 100644 index 0000000..b8ee38a --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_transaction.test @@ -0,0 +1,853 @@ +== 001 +CREATE TABLE test1 (a int, b text) +-- +310497266bba736f +== 002 +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +8cb979b355d54145 +== 003 +CALL transaction_test1(9, 'foo') +-- +999fcfadcca15917 +== 004 +SELECT * FROM test1 +-- +57550c6644afee58 +== 005 +TRUNCATE test1 +-- +5270aa06ddf1345c +== 006 +DO +LANGUAGE plpgsql +$$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +f936eab75b8c1b90 +== 007 +SELECT * FROM test1 +-- +57550c6644afee58 +== 008 +-- transaction commands not allowed when called in transaction block +START TRANSACTION +-- +4ca25828c835d55a +== 009 +CALL transaction_test1(9, 'error') +-- +999fcfadcca15917 +== 010 +COMMIT +-- +7bbcde9cfab6c79c +== 011 +START TRANSACTION +-- +4ca25828c835d55a +== 012 +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +-- +f936eab75b8c1b90 +== 013 +COMMIT +-- +7bbcde9cfab6c79c +== 014 +TRUNCATE test1 +-- +5270aa06ddf1345c +== 015 +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +-- +e780925bc9c169f2 +== 016 +SELECT transaction_test2() +-- +3d23c908ed564388 +== 017 +SELECT * FROM test1 +-- +57550c6644afee58 +== 018 +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +-- +068faaa67249da56 +== 019 +SELECT transaction_test3() +-- +75224f68d20688c7 +== 020 +SELECT * FROM test1 +-- +57550c6644afee58 +== 021 +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +-- +0e6be338e1c8bcdb +== 022 +SELECT transaction_test4() +-- +05d5664b277b08fc +== 023 +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = 555 +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +237043e2ca19568e +== 024 +CALL transaction_test5() +-- +9f83214af562a680 +== 025 +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +8dfd0c0c1fddd321 +== 026 +CALL transaction_test5b() +-- +5b0faea7cc860fec +== 027 +TRUNCATE test1 +-- +5270aa06ddf1345c +== 028 +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +-- +3912d73101e04905 +== 029 +CALL transaction_test6('bar') +-- +1cd0a9856b436d21 +== 030 +SELECT * FROM test1 +-- +57550c6644afee58 +== 031 +TRUNCATE test1 +-- +5270aa06ddf1345c +== 032 +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +-- +aba28920fc1e1097 +== 033 +CALL transaction_test7() +-- +1310913c7455b2ac +== 034 +SELECT * FROM test1 +-- +57550c6644afee58 +== 035 +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +-- +7323ae1ad1582190 +== 036 +CALL transaction_test8() +-- +1b7e5c74d5564e3e +== 037 +-- commit inside cursor loop +CREATE TABLE test2 (x int) +-- +c2b08f4f9618da43 +== 038 +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +-- +787d4df9296af90d +== 039 +TRUNCATE test1 +-- +5270aa06ddf1345c +== 040 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 041 +SELECT * FROM test1 +-- +57550c6644afee58 +== 042 +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +-- +9deb0bd4b88ee03c +== 043 +-- error in cursor loop with commit +TRUNCATE test1 +-- +5270aa06ddf1345c +== 044 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 045 +SELECT * FROM test1 +-- +57550c6644afee58 +== 046 +SELECT * FROM pg_cursors +-- +9deb0bd4b88ee03c +== 047 +-- rollback inside cursor loop +TRUNCATE test1 +-- +5270aa06ddf1345c +== 048 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 049 +SELECT * FROM test1 +-- +57550c6644afee58 +== 050 +SELECT * FROM pg_cursors +-- +9deb0bd4b88ee03c +== 051 +-- first commit then rollback inside cursor loop +TRUNCATE test1 +-- +5270aa06ddf1345c +== 052 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 053 +SELECT * FROM test1 +-- +57550c6644afee58 +== 054 +SELECT * FROM pg_cursors +-- +9deb0bd4b88ee03c +== 055 +-- rollback inside cursor loop +TRUNCATE test1 +-- +5270aa06ddf1345c +== 056 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 057 +SELECT * FROM test1 +-- +57550c6644afee58 +== 058 +SELECT * FROM test2 +-- +81c0729760618373 +== 059 +SELECT * FROM pg_cursors +-- +9deb0bd4b88ee03c +== 060 +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +-- +5270aa06ddf1345c +== 061 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +8c91d6c1e15fa014 +== 062 +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 063 +SELECT * FROM test1 +-- +57550c6644afee58 +== 064 +SELECT * FROM pg_cursors +-- +9deb0bd4b88ee03c +== 065 +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +-- +5270aa06ddf1345c +== 066 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +8c91d6c1e15fa014 +== 067 +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 068 +SELECT * FROM test1 +-- +57550c6644afee58 +== 069 +SELECT * FROM pg_cursors +-- +9deb0bd4b88ee03c +== 070 +-- commit inside block with exception handler +TRUNCATE test1 +-- +5270aa06ddf1345c +== 071 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +f936eab75b8c1b90 +== 072 +SELECT * FROM test1 +-- +57550c6644afee58 +== 073 +-- rollback inside block with exception handler +TRUNCATE test1 +-- +5270aa06ddf1345c +== 074 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +f936eab75b8c1b90 +== 075 +SELECT * FROM test1 +-- +57550c6644afee58 +== 076 +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +-- +5270aa06ddf1345c +== 077 +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +-- +f936eab75b8c1b90 +== 078 +SELECT * FROM test1 +-- +57550c6644afee58 +== 079 +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +-- +7ea44b42efa9163f +== 080 +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +-- +a6e6ed8d9804cac5 +== 081 +-- disable compression +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +-- +402b9851977a408b +== 082 +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS 'select f1 from test4' IMMUTABLE +-- +457d6b414127e3f6 +== 083 +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +-- +f936eab75b8c1b90 +== 084 +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +-- +f936eab75b8c1b90 +== 085 +-- COMMIT failures +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +-- +f936eab75b8c1b90 +== 086 +SELECT * FROM test3 +-- +f4be0d9907a2fc72 +== 087 +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +-- +3d6801a97d776bac +== 088 +TRUNCATE test1 +-- +5270aa06ddf1345c +== 089 +CALL cursor_fail_during_commit() +-- +ea534c392cb2ac7a +== 090 +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +-- +454db05f0e610aee +== 091 +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +-- +24807733fc8e10b6 +== 092 +TRUNCATE test1 +-- +5270aa06ddf1345c +== 093 +CALL cursor_fail_during_rollback() +-- +0091c4d7de036dc4 +== 094 +SELECT count(*) FROM test1 +-- +454db05f0e610aee +== 095 +-- SET TRANSACTION +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +-- +f936eab75b8c1b90 +== 096 +-- error cases +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +-- +f936eab75b8c1b90 +== 097 +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +-- +f936eab75b8c1b90 +== 098 +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +-- +f936eab75b8c1b90 +== 099 +-- snapshot handling test +TRUNCATE test2 +-- +69c51800d2467c57 +== 100 +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$ +-- +4610387d7fe5b84d +== 101 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +-- +f936eab75b8c1b90 +== 102 +SELECT * FROM test2 +-- +81c0729760618373 +== 103 +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $$ SELECT COUNT(*) FROM test2 $$ +-- +eb1a26b11a95899a +== 104 +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +-- +0c1cfaa2489cc2ef +== 105 +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +-- +f936eab75b8c1b90 +== 106 +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +-- +d699fe6dc61bd7c5 +== 107 +CALL transaction_test10a(10) +-- +3baf7be226f567ab +== 108 +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +-- +97e3bd4c609be7f7 +== 109 +CALL transaction_test10b(10) +-- +eb7ff4efb90f679f +== 110 +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +-- +b10aa0009a0ff1c3 +== 111 +CALL transaction_test11() +-- +5ee95d212cdf7687 +== 112 +-- transaction chain + +TRUNCATE test1 +-- +5270aa06ddf1345c +== 113 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +-- +f936eab75b8c1b90 +== 114 +SELECT * FROM test1 +-- +57550c6644afee58 +== 115 +DROP TABLE test1 +-- +9fdd9d3006af8e29 +== 116 +DROP TABLE test2 +-- +bf67a7944ee4e24d +== 117 +DROP TABLE test3 +-- +993db9da3609cea1 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.test new file mode 100644 index 0000000..ec99b13 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trap.test @@ -0,0 +1,291 @@ +== 001 +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +bd1aa8e9d66bf52c +== 002 +select trap_zero_divide(50) +-- +2bbb1cbdaaa0ded3 +== 003 +select trap_zero_divide(0) +-- +2bbb1cbdaaa0ded3 +== 004 +select trap_zero_divide(100000) +-- +2bbb1cbdaaa0ded3 +== 005 +select trap_zero_divide(-100) +-- +2bbb1cbdaaa0ded3 +== 006 +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +-- +da74b730bbf89a6a +== 007 +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +9293e840e4e15232 +== 008 +select trap_matching_test(50) +-- +e4601855319c5095 +== 009 +select trap_matching_test(0) +-- +e4601855319c5095 +== 010 +select trap_matching_test(100000) +-- +e4601855319c5095 +== 011 +select trap_matching_test(1) +-- +e4601855319c5095 +== 012 +create temp table foo (f1 int) +-- +cecd718310a73ba0 +== 013 +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql +-- +2f0e8d9eb784dbb3 +== 014 +select subxact_rollback_semantics() +-- +02150efd8727d69d +== 015 +select * from foo +-- +671ce24f54594ab4 +== 016 +drop table foo +-- +fdd1164b8bc60029 +== 017 +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql +-- +0184881afc2baf3f +== 018 +begin +-- +b16b431979fc3e05 +== 019 +set statement_timeout to 1000 +-- +c943c893daafa8b8 +== 020 +select trap_timeout() +-- +d26946d60332bcd6 +== 021 +rollback +-- +a46081a556fda027 +== 022 +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql +-- +f04ec1c5918fc4d4 +== 023 +select test_variable_storage() +-- +0303027e0cdd55fb +== 024 +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +-- +18b9bc59d0e6f1a9 +== 025 +create temp table leaf(f1 int references root deferrable) +-- +a8b99a618f059e46 +== 026 +insert into root values(1) +-- +a92eba14c9f19381 +== 027 +insert into leaf values(1) +-- +62387c2b723b4df8 +== 028 +insert into leaf values(2) +-- +62387c2b723b4df8 +== 029 +-- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +647a265123653108 +== 030 +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +d17b895494e93efc +== 031 +select trap_foreign_key(1) +-- +223f4703fe1f56b4 +== 032 +select trap_foreign_key(2) +-- +223f4703fe1f56b4 +== 033 +-- detects FK violation + +begin +-- +b16b431979fc3e05 +== 034 +set constraints all deferred +-- +8d0c5ef5969a4768 +== 035 +select trap_foreign_key(2) +-- +223f4703fe1f56b4 +== 036 +-- should not detect FK violation + savepoint x +-- +8ebd566ea1bf947b +== 037 +set constraints all immediate +-- +893dbdab72abe4b5 +== 038 +-- fails + rollback to x +-- +ede7bfabb934a1db +== 039 +select trap_foreign_key_2() +-- +ebd72c69eba4d60a +== 040 +-- detects FK violation +commit +-- +7bbcde9cfab6c79c +== 041 +-- still fails + +drop function trap_foreign_key(int) +-- +d171dab74d844f75 +== 042 +drop function trap_foreign_key_2() +-- +58c782aa3f7416e8 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.test new file mode 100644 index 0000000..c28c85f --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_trigger.test @@ -0,0 +1,37 @@ +== 001 +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +-- +454099cc06c22e27 +== 002 +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +-- +7a024a9a2eeef6d6 +== 003 +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +-- +b50479ce4d6d3755 +== 004 +insert into testtr values (1, 'one'), (2, 'two') +-- +99a6b39b45595a36 +== 005 +update testtr set a = a + 1 +-- +c191d316e9970716 +== 006 +delete from testtr +-- +4e0537b873f19003 diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.test b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.test new file mode 100644 index 0000000..18141d5 --- /dev/null +++ b/parser/testdata/fingerprint/plpgsql_regress/plpgsql_varprops.test @@ -0,0 +1,325 @@ +== 001 +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +-- +ce91632adb82917c +== 002 +create domain int_nn as int not null +-- +1d48e6d7e6371daf +== 003 +create domain var_record_nn as var_record not null +-- +3fbf080f7452caf1 +== 004 +create domain var_record_colnn as var_record check((value).f2 is not null) +-- +c932943a61e9b591 +== 005 +-- CONSTANT + +do $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 006 +do $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +-- +f936eab75b8c1b90 +== 007 +do $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +f936eab75b8c1b90 +== 008 +do $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +-- +f936eab75b8c1b90 +== 009 +do $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +-- +f936eab75b8c1b90 +== 010 +do $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +-- +f936eab75b8c1b90 +== 011 +do $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +f936eab75b8c1b90 +== 012 +-- initializer expressions + +do $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 013 +do $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 014 +do $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 015 +do $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 016 +do $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 017 +-- NOT NULL + +do $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 018 +do $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +f936eab75b8c1b90 +== 019 +do $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 020 +do $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 021 +do $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +f936eab75b8c1b90 +== 022 +do $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 023 +do $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 024 +do $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +f936eab75b8c1b90 +== 025 +do $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 026 +-- Check that variables are reinitialized on block re-entry. + +do $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +-- +f936eab75b8c1b90 +== 027 +-- Check enforcement of domain constraints during initialization + +do $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 028 +do $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 029 +do $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +f936eab75b8c1b90 +== 030 +do $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 031 +do $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 032 +do $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +-- +f936eab75b8c1b90 +== 033 +do $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 034 +do $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 035 +do $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +-- +f936eab75b8c1b90 +== 036 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +f936eab75b8c1b90 +== 037 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ +-- +f936eab75b8c1b90 diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_array.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_array.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_array.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_array.test new file mode 100644 index 0000000..c2a2652 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_array.test @@ -0,0 +1,239 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of array variables +|-- +-- We also check arrays of composites here, so this has some overlap +-- with the plpgsql_record tests. +|-- + +create type complex as (r float8, i float8) +-- +|-- +-- Tests for PL/pgSQL handling of array variables +|-- +-- We also check arrays of composites here, so this has some overlap +-- with the plpgsql_record tests. +|-- + +create type complex as (r float8, i float8) +== 002 +create type quadarray as (c1 complex[], c2 complex) +-- +create type quadarray as (c1 complex[], c2 complex) +== 003 +do $$ declare a int[]; +begin a := array[1,2]; a[3] := 4; raise notice 'a = %', a; end$$ +-- +do $1 +== 004 +do $$ declare a int[]; +begin a[3] := 4; raise notice 'a = %', a; end$$ +-- +do $1 +== 005 +do $$ declare a int[]; +begin a[1][4] := 4; raise notice 'a = %', a; end$$ +-- +do $1 +== 006 +do $$ declare a int[]; +begin a[1] := 23::text; raise notice 'a = %', a; end$$ +-- +do $1 +== 007 +-- lax typing + +do $$ declare a int[]; +begin a := array[1,2]; a[2:3] := array[3,4]; raise notice 'a = %', a; end$$ +-- +-- lax typing + +do $1 +== 008 +do $$ declare a int[]; +begin a := array[1,2]; a[2] := a[2] + 1; raise notice 'a = %', a; end$$ +-- +do $1 +== 009 +do $$ declare a int[]; +begin a[1:2] := array[3,4]; raise notice 'a = %', a; end$$ +-- +do $1 +== 010 +do $$ declare a int[]; +begin a[1:2] := 4; raise notice 'a = %', a; end$$ +-- +do $1 +== 011 +-- error + +do $$ declare a complex[]; +begin a[1] := (1,2); a[1].i := 11; raise notice 'a = %', a; end$$ +-- +-- error + +do $1 +== 012 +do $$ declare a complex[]; +begin a[1].i := 11; raise notice 'a = %, a[1].i = %', a, a[1].i; end$$ +-- +do $1 +== 013 +-- perhaps this ought to work, but for now it doesn't: +do $$ declare a complex[]; +begin a[1:2].i := array[11,12]; raise notice 'a = %', a; end$$ +-- +-- perhaps this ought to work, but for now it doesn't: +do $1 +== 014 +do $$ declare a quadarray; +begin a.c1[1].i := 11; raise notice 'a = %, a.c1[1].i = %', a, a.c1[1].i; end$$ +-- +do $1 +== 015 +do $$ declare a int[]; +begin a := array_agg(x) from (values(1),(2),(3)) v(x); raise notice 'a = %', a; end$$ +-- +do $1 +== 016 +create temp table onecol as select array[1,2] as f1 +-- +create temp table onecol as select array[1,2] as f1 +== 017 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +do $1 +== 018 +do $$ declare a int[]; +begin a := * from onecol for update; raise notice 'a = %', a; end$$ +-- +do $1 +== 019 +-- error cases: + +do $$ declare a int[]; +begin a := from onecol; raise notice 'a = %', a; end$$ +-- +-- error cases: + +do $1 +== 020 +do $$ declare a int[]; +begin a := f1, f1 from onecol; raise notice 'a = %', a; end$$ +-- +do $1 +== 021 +insert into onecol values(array[11]) +-- +insert into onecol values(array[$1]) +== 022 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +do $1 +== 023 +do $$ declare a int[]; +begin a := f1 from onecol limit 1; raise notice 'a = %', a; end$$ +-- +do $1 +== 024 +do $$ declare a real; +begin a[1] := 2; raise notice 'a = %', a; end$$ +-- +do $1 +== 025 +do $$ declare a complex; +begin a.r[1] := 2; raise notice 'a = %', a; end$$ +-- +do $1 +== 026 +|-- +-- test of %type[] and %rowtype[] syntax +|-- + +-- check supported syntax +do $$ +declare + v int; + v1 v%type; + v2 v%type[]; + v3 v%type[1]; + v4 v%type[][]; + v5 v%type[1][3]; + v6 v%type array; + v7 v%type array[]; + v8 v%type array[1]; + v9 v%type array[1][1]; + v10 pg_catalog.pg_class%rowtype[]; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(v3); + raise notice '%', pg_typeof(v4); + raise notice '%', pg_typeof(v5); + raise notice '%', pg_typeof(v6); + raise notice '%', pg_typeof(v7); + raise notice '%', pg_typeof(v8); + raise notice '%', pg_typeof(v9); + raise notice '%', pg_typeof(v10); +end; +$$ +-- +|-- +-- test of %type[] and %rowtype[] syntax +|-- + +-- check supported syntax +do $1 +== 027 +-- some types don't support arrays +do $$ +declare + v pg_node_tree; + v1 v%type[]; +begin +end; +$$ +-- +-- some types don't support arrays +do $1 +== 028 +-- check functionality +do $$ +declare + v1 int; + v2 varchar; + a1 v1%type[]; + a2 v2%type[]; +begin + v1 := 10; + v2 := 'Hi'; + a1 := array[v1,v1]; + a2 := array[v2,v2]; + raise notice '% %', a1, a2; +end; +$$ +-- +-- check functionality +do $1 +== 029 +create table array_test_table(a int, b varchar) +-- +create table array_test_table(a int, b varchar) +== 030 +insert into array_test_table values(1, 'first'), (2, 'second') +-- +insert into array_test_table values($1, $2), ($3, $4) +== 031 +do $$ +declare tg array_test_table%rowtype[]; +begin + tg := array(select array_test_table from array_test_table); + raise notice '%', tg; + tg := array(select row(a,b) from array_test_table); + raise notice '%', tg; +end; +$$ +-- +do $1 diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_cache.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_cache.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_cache.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_cache.test new file mode 100644 index 0000000..3fda2f6 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_cache.test @@ -0,0 +1,103 @@ +== 001 +|-- +-- Cache-behavior-dependent test cases +|-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- depending on debug_discard_caches, so we must have two expected-output +-- files to cover both cases. To minimize the maintenance effort resulting +-- from that, this file should contain only tests that do have different +-- results under debug_discard_caches. +|-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text) +-- +|-- +-- Cache-behavior-dependent test cases +|-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- depending on debug_discard_caches, so we must have two expected-output +-- files to cover both cases. To minimize the maintenance effort resulting +-- from that, this file should contain only tests that do have different +-- results under debug_discard_caches. +|-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text) +== 002 +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +create function c_sillyaddone(int) returns int language plpgsql as +$1 +== 003 +select c_sillyaddone(42) +-- +select c_sillyaddone($1) +== 004 +alter table c_mutable drop column f1 +-- +alter table c_mutable drop column f1 +== 005 +alter table c_mutable add column f1 float8 +-- +alter table c_mutable add column f1 float8 +== 006 +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but if debug_discard_caches is on, it will succeed) +select c_sillyaddone(42) +-- +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but if debug_discard_caches is on, it will succeed) +select c_sillyaddone($1) +== 007 +-- but it's OK if we force plan rebuilding +discard plans +-- +-- but it's OK if we force plan rebuilding +discard plans +== 008 +select c_sillyaddone(42) +-- +select c_sillyaddone($1) +== 009 +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$ +-- +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$1 +== 010 +select show_result_type('select 1 as a') +-- +select show_result_type($1) +== 011 +-- currently this fails due to cached plan for pg_typeof expression +-- (but if debug_discard_caches is on, it will succeed) +select show_result_type('select 2.0 as a') +-- +-- currently this fails due to cached plan for pg_typeof expression +-- (but if debug_discard_caches is on, it will succeed) +select show_result_type($1) +== 012 +-- but it's OK if we force plan rebuilding +discard plans +-- +-- but it's OK if we force plan rebuilding +discard plans +== 013 +select show_result_type('select 2.0 as a') +-- +select show_result_type($1) diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_call.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_call.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_call.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_call.test new file mode 100644 index 0000000..a1bf916 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_call.test @@ -0,0 +1,833 @@ +== 001 +|-- +-- Tests for procedures / CALL syntax +|-- + +CREATE PROCEDURE test_proc1() +LANGUAGE plpgsql +AS $$ +BEGIN + NULL; +END; +$$ +-- +|-- +-- Tests for procedures / CALL syntax +|-- + +CREATE PROCEDURE test_proc1() +LANGUAGE plpgsql +AS $1 +== 002 +CALL test_proc1() +-- +CALL test_proc1() +== 003 +-- error: can't return non-NULL +CREATE PROCEDURE test_proc2() +LANGUAGE plpgsql +AS $$ +BEGIN + RETURN 5; +END; +$$ +-- +-- error: can't return non-NULL +CREATE PROCEDURE test_proc2() +LANGUAGE plpgsql +AS $1 +== 004 +CREATE TABLE test1 (a int) +-- +CREATE TABLE test1 (a int) +== 005 +CREATE PROCEDURE test_proc3(x int) +LANGUAGE plpgsql +AS $$ +BEGIN + INSERT INTO test1 VALUES (x); +END; +$$ +-- +CREATE PROCEDURE test_proc3(x int) +LANGUAGE plpgsql +AS $1 +== 006 +CALL test_proc3(55) +-- +CALL test_proc3($1) +== 007 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 008 +-- Check that plan revalidation doesn't prevent setting transaction properties +-- (bug #18059). This test must include the first temp-object creation in +-- this script, or it won't exercise the bug scenario. Hence we put it early. +CREATE PROCEDURE test_proc3a() +LANGUAGE plpgsql +AS $$ +BEGIN + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + RAISE NOTICE 'done'; +END; +$$ +-- +-- Check that plan revalidation doesn't prevent setting transaction properties +-- (bug #18059). This test must include the first temp-object creation in +-- this script, or it won't exercise the bug scenario. Hence we put it early. +CREATE PROCEDURE test_proc3a() +LANGUAGE plpgsql +AS $1 +== 009 +CALL test_proc3a() +-- +CALL test_proc3a() +== 010 +CREATE TEMP TABLE tt1(f1 int) +-- +CREATE TEMP TABLE tt1(f1 int) +== 011 +CALL test_proc3a() +-- +CALL test_proc3a() +== 012 +-- nested CALL +TRUNCATE TABLE test1 +-- +-- nested CALL +TRUNCATE TABLE test1 +== 013 +CREATE PROCEDURE test_proc4(y int) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL test_proc3(y); + CALL test_proc3($1); +END; +$$ +-- +CREATE PROCEDURE test_proc4(y int) +LANGUAGE plpgsql +AS $1 +== 014 +CALL test_proc4(66) +-- +CALL test_proc4($1) +== 015 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 016 +CALL test_proc4(66) +-- +CALL test_proc4($1) +== 017 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 018 +-- output arguments + +CREATE PROCEDURE test_proc5(INOUT a text) +LANGUAGE plpgsql +AS $$ +BEGIN + a := a || '+' || a; +END; +$$ +-- +-- output arguments + +CREATE PROCEDURE test_proc5(INOUT a text) +LANGUAGE plpgsql +AS $1 +== 019 +CALL test_proc5('abc') +-- +CALL test_proc5($1) +== 020 +CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + b := b * a; + c := c * a; +END; +$$ +-- +CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $1 +== 021 +CALL test_proc6(2, 3, 4) +-- +CALL test_proc6($1, $2, $3) +== 022 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); + RAISE INFO 'x = %, y = %', x, y; + CALL test_proc6(2, c => y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +DO +LANGUAGE plpgsql +$1 +== 023 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +DO +LANGUAGE plpgsql +$1 +== 024 +DO +LANGUAGE plpgsql +$$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +-- +DO +LANGUAGE plpgsql +$1 +== 025 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +-- +DO +LANGUAGE plpgsql +$1 +== 026 +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +-- +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $1 +== 027 +CALL test_proc7(100, -1, -1) +-- +CALL test_proc7($1, $2, $3) +== 028 +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +-- +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $1 +== 029 +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +-- +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $1 +== 030 +CALL test_proc7cc(10) +-- +CALL test_proc7cc($1) +== 031 +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +-- +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $1 +== 032 +CALL test_proc8a(10, 20) +-- +CALL test_proc8a($1, $2) +== 033 +CALL test_proc8a(b => 20, a => 10) +-- +CALL test_proc8a(b => $1, a => $2) +== 034 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +DO $1 +== 035 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $1 +== 036 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 037 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $1 +== 038 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 039 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 040 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 041 +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +-- +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $1 +== 042 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +DO $1 +== 043 +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +-- +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $1 +== 044 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 045 +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +-- +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $1 +== 046 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 047 +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +-- +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $1 +== 048 +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 049 +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +DO $1 +== 050 +-- transition variable assignment + +TRUNCATE test1 +-- +-- transition variable assignment + +TRUNCATE test1 +== 051 +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +-- +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $1 +== 052 +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +-- +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +== 053 +INSERT INTO test1 VALUES (1), (2), (3) +-- +INSERT INTO test1 VALUES ($1), ($2), ($3) +== 054 +UPDATE test1 SET a = 22 WHERE a = 2 +-- +UPDATE test1 SET a = $1 WHERE a = $2 +== 055 +SELECT * FROM test1 ORDER BY a +-- +SELECT * FROM test1 ORDER BY a +== 056 +DROP PROCEDURE test_proc1 +-- +DROP PROCEDURE test_proc1 +== 057 +DROP PROCEDURE test_proc3 +-- +DROP PROCEDURE test_proc3 +== 058 +DROP PROCEDURE test_proc4 +-- +DROP PROCEDURE test_proc4 +== 059 +DROP TABLE test1 +-- +DROP TABLE test1 +== 060 +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +-- +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $1 LANGUAGE plpgsql +== 061 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $1 +== 062 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $1 +== 063 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $1 +== 064 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +DO $1 +== 065 +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +-- +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $1 LANGUAGE plpgsql +== 066 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +-- +CREATE FUNCTION f(int) RETURNS int AS $1 LANGUAGE sql +== 067 +CREATE PROCEDURE outer_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +CREATE PROCEDURE outer_p (f1 int) +AS $1 LANGUAGE plpgsql +== 068 +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $1 LANGUAGE plpgsql +== 069 +CALL outer_p(42) +-- +CALL outer_p($1) +== 070 +SELECT outer_f(42) +-- +SELECT outer_f($1) +== 071 +DROP FUNCTION f(int) +-- +DROP FUNCTION f(int) +== 072 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +-- +CREATE FUNCTION f(int) RETURNS int AS $1 LANGUAGE sql +== 073 +CALL outer_p(42) +-- +CALL outer_p($1) +== 074 +SELECT outer_f(42) +-- +SELECT outer_f($1) +== 075 +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +-- +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +== 076 +INSERT INTO t_test VALUES (0) +-- +INSERT INTO t_test VALUES ($1) +== 077 +CREATE FUNCTION f_get_x () RETURNS int +AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +-- +CREATE FUNCTION f_get_x () RETURNS int +AS $1 LANGUAGE plpgsql STABLE +== 078 +CREATE PROCEDURE f_print_x (x int) +AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +-- +CREATE PROCEDURE f_print_x (x int) +AS $1 LANGUAGE plpgsql +== 079 +-- test in non-atomic context +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +-- +-- test in non-atomic context +DO $1 +== 080 +-- test in non-atomic context, except exception block is locally atomic +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +-- +-- test in non-atomic context, except exception block is locally atomic +DO $1 +== 081 +-- test in atomic context +BEGIN +-- +-- test in atomic context +BEGIN +== 082 +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +-- +DO $1 +== 083 +ROLLBACK +-- +ROLLBACK diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_control.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_control.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_control.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_control.test new file mode 100644 index 0000000..8b34cbc --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_control.test @@ -0,0 +1,661 @@ +== 001 +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +-- +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $1 +== 002 +-- BY can't be zero or negative +do $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +-- +-- BY can't be zero or negative +do $1 +== 003 +do $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +-- +do $1 +== 004 +do $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +-- +do $1 +== 005 +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +-- +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +== 006 +insert into conttesttbl(v) values(10) +-- +insert into conttesttbl(v) values($1) +== 007 +insert into conttesttbl(v) values(20) +-- +insert into conttesttbl(v) values($1) +== 008 +insert into conttesttbl(v) values(30) +-- +insert into conttesttbl(v) values($1) +== 009 +insert into conttesttbl(v) values(40) +-- +insert into conttesttbl(v) values($1) +== 010 +create function continue_test1() returns void as $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ language plpgsql +-- +create function continue_test1() returns void as $1 language plpgsql +== 011 +select continue_test1() +-- +select continue_test1() +== 012 +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $$ +begin + begin + continue; + end; +end; +$$ language plpgsql +-- +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $1 language plpgsql +== 013 +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $$ +begin + begin + exit; + end; +end; +$$ language plpgsql +-- +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $1 language plpgsql +== 014 +-- should fail: no such label +create function continue_error2() returns void as $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +-- should fail: no such label +create function continue_error2() returns void as $1 language plpgsql +== 015 +-- should fail: no such label +create function exit_error2() returns void as $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +-- should fail: no such label +create function exit_error2() returns void as $1 language plpgsql +== 016 +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ language plpgsql +-- +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $1 language plpgsql +== 017 +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ language plpgsql +-- +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $1 language plpgsql +== 018 +select exit_block1() +-- +select exit_block1() +== 019 +-- verbose end block and end loop +create function end_label1() returns void as $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ language plpgsql +-- +-- verbose end block and end loop +create function end_label1() returns void as $1 language plpgsql +== 020 +select end_label1() +-- +select end_label1() +== 021 +-- should fail: undefined end label +create function end_label2() returns void as $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ language plpgsql +-- +-- should fail: undefined end label +create function end_label2() returns void as $1 language plpgsql +== 022 +-- should fail: end label does not match start label +create function end_label3() returns void as $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +-- should fail: end label does not match start label +create function end_label3() returns void as $1 language plpgsql +== 023 +-- should fail: end label on a block without a start label +create function end_label4() returns void as $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +-- should fail: end label on a block without a start label +create function end_label4() returns void as $1 language plpgsql +== 024 +-- unlabeled exit matches no blocks +do $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +-- +-- unlabeled exit matches no blocks +do $1 +== 025 +-- check exit out of an unlabeled block to a labeled one +do $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +-- +-- check exit out of an unlabeled block to a labeled one +do $1 +== 026 +-- check exit out of outermost block +do $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +-- +-- check exit out of outermost block +do $1 +== 027 +-- unlabeled exit does match a while loop +do $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +-- +-- unlabeled exit does match a while loop +do $1 +== 028 +-- check exit out of an unlabeled while to a labeled one +do $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +-- +-- check exit out of an unlabeled while to a labeled one +do $1 +== 029 +-- continue to an outer while +do $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +-- +-- continue to an outer while +do $1 +== 030 +-- return out of a while +create function return_from_while() returns int language plpgsql as $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +-- +-- return out of a while +create function return_from_while() returns int language plpgsql as $1 +== 031 +select return_from_while() +-- +select return_from_while() +== 032 +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $proc$ +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice '%', i; + end loop; + -- fore with record var + for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop + raise notice '% % %', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice '%', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop + raise notice '% % %', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop + raise notice '% % %', a, b, c; + end loop; +end; +$proc$ language plpgsql +-- +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $1 language plpgsql +== 033 +select for_vect() +-- +select for_vect() +== 034 +-- CASE statement + +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ language plpgsql immutable +-- +-- CASE statement + +create or replace function case_test(bigint) returns text as $1 language plpgsql immutable +== 035 +select case_test(1) +-- +select case_test($1) +== 036 +select case_test(2) +-- +select case_test($1) +== 037 +select case_test(3) +-- +select case_test($1) +== 038 +select case_test(4) +-- +select case_test($1) +== 039 +select case_test(5) +-- +select case_test($1) +== 040 +-- fails +select case_test(8) +-- +-- fails +select case_test($1) +== 041 +select case_test(10) +-- +select case_test($1) +== 042 +select case_test(11) +-- +select case_test($1) +== 043 +select case_test(12) +-- +select case_test($1) +== 044 +select case_test(13) +-- +select case_test($1) +== 045 +-- fails + +create or replace function catch() returns void as $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ language plpgsql +-- +-- fails + +create or replace function catch() returns void as $1 language plpgsql +== 046 +select catch() +-- +select catch() +== 047 +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $1 language plpgsql immutable +== 048 +select case_test(1) +-- +select case_test($1) +== 049 +select case_test(2) +-- +select case_test($1) +== 050 +select case_test(12) +-- +select case_test($1) +== 051 +select case_test(13) +-- +select case_test($1) +== 052 +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $1 language plpgsql immutable +== 053 +select case_comment(1) +-- +select case_comment($1) diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_copy.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_copy.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_copy.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_copy.test new file mode 100644 index 0000000..2788c56 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_copy.test @@ -0,0 +1,21 @@ +== 001 +-- directory paths are passed to us in environment variables + +-- set up file names to use + +CREATE TABLE copy1 (a int, b float); + +-- COPY TO/FROM not authorized from client. +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 TO stdout; +END; +$$; +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 FROM stdin; +-- +ERROR: "unterminated dollar-quoted string at or near \"$$\nBEGIN\n COPY copy1 FROM stdin;\"" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_domain.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_domain.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_domain.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_domain.test new file mode 100644 index 0000000..ec6ada2 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_domain.test @@ -0,0 +1,533 @@ +== 001 +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +-- +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +== 002 +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $1 LANGUAGE plpgsql +== 003 +SELECT * FROM test_argresult_booltrue(true, true) +-- +SELECT * FROM test_argresult_booltrue($1, $2) +== 004 +SELECT * FROM test_argresult_booltrue(false, true) +-- +SELECT * FROM test_argresult_booltrue($1, $2) +== 005 +SELECT * FROM test_argresult_booltrue(true, false) +-- +SELECT * FROM test_argresult_booltrue($1, $2) +== 006 +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $1 LANGUAGE plpgsql +== 007 +SELECT * FROM test_assign_booltrue(true, true) +-- +SELECT * FROM test_assign_booltrue($1, $2) +== 008 +SELECT * FROM test_assign_booltrue(false, true) +-- +SELECT * FROM test_assign_booltrue($1, $2) +== 009 +SELECT * FROM test_assign_booltrue(true, false) +-- +SELECT * FROM test_assign_booltrue($1, $2) +== 010 +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +-- +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +== 011 +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $1 LANGUAGE plpgsql +== 012 +SELECT * FROM test_argresult_uint2(100::uint2, 50) +-- +SELECT * FROM test_argresult_uint2($1::uint2, $2) +== 013 +SELECT * FROM test_argresult_uint2(100::uint2, -50) +-- +SELECT * FROM test_argresult_uint2($1::uint2, $2) +== 014 +SELECT * FROM test_argresult_uint2(null, 1) +-- +SELECT * FROM test_argresult_uint2($1, $2) +== 015 +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $1 LANGUAGE plpgsql +== 016 +SELECT * FROM test_assign_uint2(100, 50) +-- +SELECT * FROM test_assign_uint2($1, $2) +== 017 +SELECT * FROM test_assign_uint2(100, -50) +-- +SELECT * FROM test_assign_uint2($1, $2) +== 018 +SELECT * FROM test_assign_uint2(-100, 50) +-- +SELECT * FROM test_assign_uint2($1, $2) +== 019 +SELECT * FROM test_assign_uint2(null, 1) +-- +SELECT * FROM test_assign_uint2($1, $2) +== 020 +CREATE DOMAIN nnint AS int NOT NULL +-- +CREATE DOMAIN nnint AS int NOT NULL +== 021 +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $1 LANGUAGE plpgsql +== 022 +SELECT * FROM test_argresult_nnint(10, 20) +-- +SELECT * FROM test_argresult_nnint($1, $2) +== 023 +SELECT * FROM test_argresult_nnint(null, 20) +-- +SELECT * FROM test_argresult_nnint($1, $2) +== 024 +SELECT * FROM test_argresult_nnint(10, null) +-- +SELECT * FROM test_argresult_nnint($1, $2) +== 025 +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $1 LANGUAGE plpgsql +== 026 +SELECT * FROM test_assign_nnint(10, 20) +-- +SELECT * FROM test_assign_nnint($1, $2) +== 027 +SELECT * FROM test_assign_nnint(null, 20) +-- +SELECT * FROM test_assign_nnint($1, $2) +== 028 +SELECT * FROM test_assign_nnint(10, null) +-- +SELECT * FROM test_assign_nnint($1, $2) +== 029 +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +-- +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +== 030 +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $1 LANGUAGE plpgsql +== 031 +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +-- +SELECT * FROM test_argresult_array_domain(ARRAY[$1, $2]::ordered_pair_domain) +== 032 +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +-- +SELECT * FROM test_argresult_array_domain($1::ordered_pair_domain) +== 033 +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $1 LANGUAGE plpgsql +== 034 +SELECT * FROM test_argresult_array_domain_check_violation() +-- +SELECT * FROM test_argresult_array_domain_check_violation() +== 035 +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $1 LANGUAGE plpgsql +== 036 +SELECT * FROM test_assign_ordered_pair_domain(1,2,3) +-- +SELECT * FROM test_assign_ordered_pair_domain($1,$2,$3) +== 037 +SELECT * FROM test_assign_ordered_pair_domain(1,2,0) +-- +SELECT * FROM test_assign_ordered_pair_domain($1,$2,$3) +== 038 +SELECT * FROM test_assign_ordered_pair_domain(2,1,3) +-- +SELECT * FROM test_assign_ordered_pair_domain($1,$2,$3) +== 039 +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $1 LANGUAGE plpgsql +== 040 +select test_read_uint2_array(array[1::uint2]) +-- +select test_read_uint2_array(array[$1::uint2]) +== 041 +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $1 LANGUAGE plpgsql +== 042 +select test_build_uint2_array(1::int2) +-- +select test_build_uint2_array($1::int2) +== 043 +select test_build_uint2_array(-1::int2) +-- +select test_build_uint2_array(-$1::int2) +== 044 +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +-- +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $1 LANGUAGE plpgsql +== 045 +select test_argresult_domain_array(array[2,4]) +-- +select test_argresult_domain_array(array[$1,$2]) +== 046 +select test_argresult_domain_array(array[4,2]) +-- +select test_argresult_domain_array(array[$1,$2]) +== 047 +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $1 LANGUAGE plpgsql +== 048 +select test_argresult_domain_array2(array[2,4]) +-- +select test_argresult_domain_array2(array[$1,$2]) +== 049 +select test_argresult_domain_array2(array[4,2]) +-- +select test_argresult_domain_array2(array[$1,$2]) +== 050 +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $1 LANGUAGE plpgsql +== 051 +select test_argresult_array_domain_array(array[array[2,4]::ordered_pair_domain]) +-- +select test_argresult_array_domain_array(array[array[$1,$2]::ordered_pair_domain]) +== 052 +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +-- +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +== 053 +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $1 LANGUAGE plpgsql +== 054 +SELECT test_result_nnint_container(null, 3) +-- +SELECT test_result_nnint_container($1, $2) +== 055 +SELECT test_result_nnint_container(3, null) +-- +SELECT test_result_nnint_container($1, $2) +== 056 +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $1 LANGUAGE plpgsql +== 057 +SELECT * FROM test_assign_nnint_container(1,2,3) +-- +SELECT * FROM test_assign_nnint_container($1,$2,$3) +== 058 +SELECT * FROM test_assign_nnint_container(1,2,null) +-- +SELECT * FROM test_assign_nnint_container($1,$2,$3) +== 059 +SELECT * FROM test_assign_nnint_container(1,null,3) +-- +SELECT * FROM test_assign_nnint_container($1,$2,$3) +== 060 +-- Since core system allows this: +SELECT null::nnint_container +-- +-- Since core system allows this: +SELECT $1::nnint_container +== 061 +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $1 LANGUAGE plpgsql +== 062 +SELECT * FROM test_assign_nnint_container2(1,2,3) +-- +SELECT * FROM test_assign_nnint_container2($1,$2,$3) +== 063 +SELECT * FROM test_assign_nnint_container2(1,2,null) +-- +SELECT * FROM test_assign_nnint_container2($1,$2,$3) +== 064 +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +-- +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +== 065 +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +-- +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +== 066 +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $1 LANGUAGE plpgsql +== 067 +SELECT read_ordered_named_pair(row(1, 2)) +-- +SELECT read_ordered_named_pair(row($1, $2)) +== 068 +SELECT read_ordered_named_pair(row(2, 1)) +-- +SELECT read_ordered_named_pair(row($1, $2)) +== 069 +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +-- +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $1 LANGUAGE plpgsql +== 070 +SELECT build_ordered_named_pair(1,2) +-- +SELECT build_ordered_named_pair($1,$2) +== 071 +SELECT build_ordered_named_pair(2,1) +-- +SELECT build_ordered_named_pair($1,$2) +== 072 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $1 LANGUAGE plpgsql +== 073 +SELECT * FROM test_assign_ordered_named_pair(1,2,3) +-- +SELECT * FROM test_assign_ordered_named_pair($1,$2,$3) +== 074 +SELECT * FROM test_assign_ordered_named_pair(1,2,0) +-- +SELECT * FROM test_assign_ordered_named_pair($1,$2,$3) +== 075 +SELECT * FROM test_assign_ordered_named_pair(2,1,3) +-- +SELECT * FROM test_assign_ordered_named_pair($1,$2,$3) +== 076 +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +-- +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $1 LANGUAGE plpgsql +== 077 +SELECT build_ordered_named_pairs(1,2) +-- +SELECT build_ordered_named_pairs($1,$2) +== 078 +SELECT build_ordered_named_pairs(2,1) +-- +SELECT build_ordered_named_pairs($1,$2) +== 079 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $1 LANGUAGE plpgsql +== 080 +SELECT * FROM test_assign_ordered_named_pairs(1,2,3) +-- +SELECT * FROM test_assign_ordered_named_pairs($1,$2,$3) +== 081 +SELECT * FROM test_assign_ordered_named_pairs(2,1,3) +-- +SELECT * FROM test_assign_ordered_named_pairs($1,$2,$3) +== 082 +SELECT * FROM test_assign_ordered_named_pairs(1,2,0) +-- +SELECT * FROM test_assign_ordered_named_pairs($1,$2,$3) diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_misc.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_misc.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_misc.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_misc.test new file mode 100644 index 0000000..a34edeb --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_misc.test @@ -0,0 +1,86 @@ +== 001 +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +-- +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$1 +== 002 +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +-- +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +== 003 +do $$ declare x foo%type; begin end $$ +-- +do $1 +== 004 +do $$ declare x notice%type; begin end $$ +-- +do $1 +== 005 +-- covers unreserved-keyword case +do $$ declare x foo.bar%type; begin end $$ +-- +-- covers unreserved-keyword case +do $1 +== 006 +do $$ declare x foo.bar.baz%type; begin end $$ +-- +do $1 +== 007 +do $$ declare x public.foo.bar%type; begin end $$ +-- +do $1 +== 008 +do $$ declare x public.misc_table.zed%type; begin end $$ +-- +do $1 +== 009 +do $$ declare x foo%rowtype; begin end $$ +-- +do $1 +== 010 +do $$ declare x notice%rowtype; begin end $$ +-- +do $1 +== 011 +-- covers unreserved-keyword case +do $$ declare x foo.bar%rowtype; begin end $$ +-- +-- covers unreserved-keyword case +do $1 +== 012 +do $$ declare x foo.bar.baz%rowtype; begin end $$ +-- +do $1 +== 013 +do $$ declare x public.foo%rowtype; begin end $$ +-- +do $1 +== 014 +do $$ declare x public.misc_table%rowtype; begin end $$ +-- +do $1 diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_record.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_record.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_record.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_record.test new file mode 100644 index 0000000..f7c8eba --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_record.test @@ -0,0 +1,1113 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +-- +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +== 002 +create type more_int4s as (f0 text, f1 int4, f2 int4) +-- +create type more_int4s as (f0 text, f1 int4, f2 int4) +== 003 +create type two_int8s as (q1 int8, q2 int8) +-- +create type two_int8s as (q1 int8, q2 int8) +== 004 +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +-- +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +== 005 +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1)::two_int8s; end $$ +-- +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$1 +== 006 +select retc(42) +-- +select retc($1) +== 007 +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8); end $$ +-- +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$1 +== 008 +select retc(42) +-- +select retc($1) +== 009 +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1); end $$ +-- +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$1 +== 010 +select retc(42) +-- +select retc($1) +== 011 +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8, 42); end $$ +-- +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$1 +== 012 +select retc(42) +-- +select retc($1) +== 013 +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +-- +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$1 +== 014 +select retc(42) +-- +select retc($1) +== 015 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,1); return r; end $$ +-- +create or replace function retc(int) returns two_int8s language plpgsql as +$1 +== 016 +select retc(42) +-- +select retc($1) +== 017 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +create or replace function retc(int) returns two_int8s language plpgsql as +$1 +== 018 +select retc(42) +-- +select retc($1) +== 019 +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$1 +== 020 +select retc(42) +-- +select retc($1) +== 021 +do $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +-- +do $1 +== 022 +do $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +-- +do $1 +== 023 +do $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +-- +do $1 +== 024 +do $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +-- +do $1 +== 025 +-- block-qualified naming +do $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +-- +-- block-qualified naming +do $1 +== 026 +-- error cases +do $$ declare c two_int8s; begin c.x = 1; end $$ +-- +-- error cases +do $1 +== 027 +do $$ declare c nested_int8s; begin c.x = 1; end $$ +-- +do $1 +== 028 +do $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +-- +do $1 +== 029 +do $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +-- +do $1 +== 030 +do $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +-- +do $1 +== 031 +do $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +-- +do $1 +== 032 +do $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +-- +do $1 +== 033 +do $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +-- +do $1 +== 034 +do $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +-- +do $1 +== 035 +do $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +-- +do $1 +== 036 +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +-- +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $1 +== 037 +select getq1(retc(344)) +-- +select getq1(retc($1)) +== 038 +select getq1(row(1,2)) +-- +select getq1(row($1,$2)) +== 039 +do $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +-- +do $1 +== 040 +-- check assignments of composites +do $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +-- +-- check assignments of composites +do $1 +== 041 +-- fields of named-type vars read as null if uninitialized +do $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +-- +-- fields of named-type vars read as null if uninitialized +do $1 +== 042 +do $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +do $1 +== 043 +-- records, not so much +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +-- +-- records, not so much +do $1 +== 044 +-- but OK if you assign first +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +-- but OK if you assign first +do $1 +== 045 +-- check %type with block-qualified variable names +do $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +-- +-- check %type with block-qualified variable names +do $1 +== 046 +-- check that type record can be passed through %type +do $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +-- +-- check that type record can be passed through %type +do $1 +== 047 +-- arrays of record are not supported at the moment +do $$ +declare r1 record[]; +begin +end$$ +-- +-- arrays of record are not supported at the moment +do $1 +== 048 +do $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +-- +do $1 +== 049 +-- check repeated assignments to composite fields +create table some_table (id int, data text) +-- +-- check repeated assignments to composite fields +create table some_table (id int, data text) +== 050 +do $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +-- +do $1 +== 051 +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1); end $$ +-- +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$1 +== 052 +select returnsrecord(42) +-- +select returnsrecord($1) +== 053 +select * from returnsrecord(42) as r(x int, y int) +-- +select * from returnsrecord($1) as r(x int, y int) +== 054 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +select * from returnsrecord($1) as r(x int, y int, z int) +== 055 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +-- fail +select * from returnsrecord($1) as r(x int, y bigint) +== 056 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1); return r; end $$ +-- +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$1 +== 057 +select returnsrecord(42) +-- +select returnsrecord($1) +== 058 +select * from returnsrecord(42) as r(x int, y int) +-- +select * from returnsrecord($1) as r(x int, y int) +== 059 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +select * from returnsrecord($1) as r(x int, y int, z int) +== 060 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +-- fail +select * from returnsrecord($1) as r(x int, y bigint) +== 061 +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +-- +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +== 062 +alter table has_hole drop column f2 +-- +alter table has_hole drop column f2 +== 063 +create or replace function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1)::has_hole; end $$ +-- +create or replace function returnsrecord(int) returns record language plpgsql as +$1 +== 064 +select returnsrecord(42) +-- +select returnsrecord($1) +== 065 +select * from returnsrecord(42) as r(x int, y int) +-- +select * from returnsrecord($1) as r(x int, y int) +== 066 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +select * from returnsrecord($1) as r(x int, y int, z int) +== 067 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +-- fail +select * from returnsrecord($1) as r(x int, y bigint) +== 068 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +-- +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$1 +== 069 +select returnsrecord(42) +-- +select returnsrecord($1) +== 070 +select * from returnsrecord(42) as r(x int, y int) +-- +select * from returnsrecord($1) as r(x int, y int) +== 071 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +select * from returnsrecord($1) as r(x int, y int, z int) +== 072 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +-- fail +select * from returnsrecord($1) as r(x int, y bigint) +== 073 +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$$ begin return x.f1; end $$ +-- +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$1 +== 074 +select getf1(1) +-- +select getf1($1) +== 075 +select getf1(row(1,2)) +-- +select getf1(row($1,$2)) +== 076 +select getf1(row(1,2)::two_int4s) +-- +select getf1(row($1,$2)::two_int4s) +== 077 +select getf1(row('foo',123,456)::more_int4s) +-- +select getf1(row($1,$2,$3)::more_int4s) +== 078 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row(1,2)::two_int8s) +-- +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row($1,$2)::two_int8s) +== 079 +select getf1(row(1,2)) +-- +select getf1(row($1,$2)) +== 080 +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$$ begin return $1.f2; end $$ +-- +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$1 +== 081 +select getf2(row(1,2)) +-- +select getf2(row($1,$2)) +== 082 +-- ideally would work, but does not +select getf2(row(1,2)::two_int4s) +-- +-- ideally would work, but does not +select getf2(row($1,$2)::two_int4s) +== 083 +select getf2(row('foo',123,456)::more_int4s) +-- +select getf2(row($1,$2,$3)::more_int4s) +== 084 +-- check behavior when assignment to FOR-loop variable requires coercion +do $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +-- +-- check behavior when assignment to FOR-loop variable requires coercion +do $1 +== 085 +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +-- +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$1 +== 086 +select returnssetofholes() +-- +select returnssetofholes() +== 087 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +-- +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$1 +== 088 +select returnssetofholes() +-- +select returnssetofholes() +== 089 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +begin + return next row(1,2,3); -- fails +end$$ +-- +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$1 +== 090 +select returnssetofholes() +-- +select returnssetofholes() +== 091 +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +-- +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +== 092 +create function sillyaddone(int) returns int language plpgsql as +$$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +create function sillyaddone(int) returns int language plpgsql as +$1 +== 093 +select sillyaddone(42) +-- +select sillyaddone($1) +== 094 +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +-- +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +== 095 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone(42) +-- +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone($1) +== 096 +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$$ begin return x.f3; end $$ +-- +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$1 +== 097 +select getf3(null::mutable) +-- +select getf3($1::mutable) +== 098 +-- doesn't work yet +alter table mutable add column f3 int +-- +-- doesn't work yet +alter table mutable add column f3 int +== 099 +select getf3(null::mutable) +-- +select getf3($1::mutable) +== 100 +-- now it works +alter table mutable drop column f3 +-- +-- now it works +alter table mutable drop column f3 +== 101 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3(null::mutable) +-- +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3($1::mutable) +== 102 +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off +-- +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = $1 +== 103 +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +-- +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$1 +== 104 +reset check_function_bodies +-- +reset check_function_bodies +== 105 +select sillyaddtwo(42) +-- +select sillyaddtwo($1) +== 106 +-- fail +create table mutable2(f1 int, f2 text) +-- +-- fail +create table mutable2(f1 int, f2 text) +== 107 +select sillyaddtwo(42) +-- +select sillyaddtwo($1) +== 108 +drop table mutable2 +-- +drop table mutable2 +== 109 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo(42) +-- +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo($1) +== 110 +-- fail +create table mutable2(f0 text, f1 int, f2 text) +-- +-- fail +create table mutable2(f0 text, f1 int, f2 text) +== 111 +select sillyaddtwo(42) +-- +select sillyaddtwo($1) +== 112 +select sillyaddtwo(43) +-- +select sillyaddtwo($1) +== 113 +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +-- +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$1 +== 114 +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +-- +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +== 115 +insert into mutable values ('foo'), ('bar') +-- +insert into mutable values ($1), ($2) +== 116 +update mutable set f2 = f2 || ' baz' +-- +update mutable set f2 = f2 || $1 +== 117 +table mutable +-- +table mutable +== 118 +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$$begin + return row(new.*); +end$$ +-- +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$1 +== 119 +update mutable set f2 = f2 || ' baz' +-- +update mutable set f2 = f2 || $1 +== 120 +table mutable +-- +table mutable +== 121 +create or replace function sillytrig() returns trigger language plpgsql as +$$declare r record; +begin + r := row(new.*); + return r; +end$$ +-- +create or replace function sillytrig() returns trigger language plpgsql as +$1 +== 122 +update mutable set f2 = f2 || ' baz' +-- +update mutable set f2 = f2 || $1 +== 123 +table mutable +-- +table mutable +== 124 +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +-- +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +== 125 +create function read_ordered_int8s(p ordered_int8s) returns int8 as $$ +begin return p.q1 + p.q2; end +$$ language plpgsql +-- +create function read_ordered_int8s(p ordered_int8s) returns int8 as $1 language plpgsql +== 126 +select read_ordered_int8s(row(1, 2)) +-- +select read_ordered_int8s(row($1, $2)) +== 127 +select read_ordered_int8s(row(2, 1)) +-- +select read_ordered_int8s(row($1, $2)) +== 128 +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $$ +begin return row(i,j); end +$$ language plpgsql +-- +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $1 language plpgsql +== 129 +select build_ordered_int8s(1,2) +-- +select build_ordered_int8s($1,$2) +== 130 +select build_ordered_int8s(2,1) +-- +select build_ordered_int8s($1,$2) +== 131 +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $$ +declare r record; begin r := row(i,j); return r; end +$$ language plpgsql +-- +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $1 language plpgsql +== 132 +select build_ordered_int8s_2(1,2) +-- +select build_ordered_int8s_2($1,$2) +== 133 +select build_ordered_int8s_2(2,1) +-- +select build_ordered_int8s_2($1,$2) +== 134 +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $1 language plpgsql +== 135 +select build_ordered_int8s_3(1,2) +-- +select build_ordered_int8s_3($1,$2) +== 136 +select build_ordered_int8s_3(2,1) +-- +select build_ordered_int8s_3($1,$2) +== 137 +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $1 language plpgsql +== 138 +select build_ordered_int8s_4(1,2) +-- +select build_ordered_int8s_4($1,$2) +== 139 +select build_ordered_int8s_4(2,1) +-- +select build_ordered_int8s_4($1,$2) +== 140 +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ language plpgsql +-- +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $1 language plpgsql +== 141 +select build_ordered_int8s_a(1,2) +-- +select build_ordered_int8s_a($1,$2) +== 142 +select build_ordered_int8s_a(2,1) +-- +select build_ordered_int8s_a($1,$2) +== 143 +-- fail + +-- check field assignment +do $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +-- +-- fail + +-- check field assignment +do $1 +== 144 +-- check whole-row assignment +do $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +-- +-- check whole-row assignment +do $1 +== 145 +-- check assignment in for-loop +do $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +-- +-- check assignment in for-loop +do $1 +== 146 +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +-- +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +== 147 +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +-- +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +== 148 +create table sometable (id int, a text, b text) +-- +create table sometable (id int, a text, b text) +== 149 +-- b should be compressed, but in-line +insert into sometable values (1, 'a', repeat('ffoob',1000)) +-- +-- b should be compressed, but in-line +insert into sometable values ($1, $2, repeat($3,$4)) +== 150 +-- this b should be out-of-line +insert into sometable values (2, 'a', repeat('ffoob',100000)) +-- +-- this b should be out-of-line +insert into sometable values ($1, $2, repeat($3,$4)) +== 151 +-- this pair should fail the domain check +insert into sometable values (3, 'z', repeat('ffoob',100000)) +-- +-- this pair should fail the domain check +insert into sometable values ($1, $2, repeat($3,$4)) +== 152 +do $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +-- +do $1 +== 153 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +-- +do $1 +== 154 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +-- +do $1 +== 155 +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$ +-- +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$1 +== 156 +create table two_int8s_tab (f1 two_int8s) +-- +create table two_int8s_tab (f1 two_int8s) +== 157 +insert into two_int8s_tab values (compresult(42)) +-- +insert into two_int8s_tab values (compresult($1)) +== 158 +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab +-- +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_simple.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_simple.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_simple.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_simple.test new file mode 100644 index 0000000..2699b6c --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_simple.test @@ -0,0 +1,191 @@ +== 001 +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as 'select $1' +-- +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as $1 +== 002 +create function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +-- +create function simplecaller() returns int language plpgsql +as $1 +== 003 +select simplecaller() +-- +select simplecaller() +== 004 +-- Check that changes in search path are dealt with correctly +create schema simple1 +-- +-- Check that changes in search path are dealt with correctly +create schema simple1 +== 005 +create function simple1.simpletarget(int) returns int language plpgsql +as $$begin return $1; end$$ +-- +create function simple1.simpletarget(int) returns int language plpgsql +as $1 +== 006 +create function simpletarget(int) returns int language plpgsql +as $$begin return $1 + 100; end$$ +-- +create function simpletarget(int) returns int language plpgsql +as $1 +== 007 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +-- +create or replace function simplecaller() returns int language plpgsql +as $1 +== 008 +select simplecaller() +-- +select simplecaller() +== 009 +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +-- +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +== 010 +alter function simpletarget(int) immutable +-- +alter function simpletarget(int) immutable +== 011 +select simplecaller() +-- +select simplecaller() +== 012 +-- make sure flushing local caches changes nothing + +select simplecaller() +-- +-- make sure flushing local caches changes nothing + +select simplecaller() +== 013 +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $$select 1 / 0$$ +-- +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $1 +== 014 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +-- +create or replace function simplecaller() returns int language plpgsql +as $1 +== 015 +select simplecaller() +-- +select simplecaller() +== 016 +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $$select 2 + 2$$ +-- +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $1 +== 017 +select simplecaller() +-- +select simplecaller() +== 018 +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +-- +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $1 +== 019 +select simplecaller() +-- +select simplecaller() +== 020 +drop function simplesql() +-- +drop function simplesql() +== 021 +create function simplesql() returns setof int language sql +as $$select 22 + 22$$ +-- +create function simplesql() returns setof int language sql +as $1 +== 022 +select simplecaller() +-- +select simplecaller() +== 023 +select simplecaller() +-- +select simplecaller() +== 024 +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ +-- +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $1 diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.test new file mode 100644 index 0000000..9bc1ce6 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_transaction.test @@ -0,0 +1,928 @@ +== 001 +CREATE TABLE test1 (a int, b text) +-- +CREATE TABLE test1 (a int, b text) +== 002 +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $1 +== 003 +CALL transaction_test1(9, 'foo') +-- +CALL transaction_test1($1, $2) +== 004 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 005 +TRUNCATE test1 +-- +TRUNCATE test1 +== 006 +DO +LANGUAGE plpgsql +$$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +DO +LANGUAGE plpgsql +$1 +== 007 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 008 +-- transaction commands not allowed when called in transaction block +START TRANSACTION +-- +-- transaction commands not allowed when called in transaction block +START TRANSACTION +== 009 +CALL transaction_test1(9, 'error') +-- +CALL transaction_test1($1, $2) +== 010 +COMMIT +-- +COMMIT +== 011 +START TRANSACTION +-- +START TRANSACTION +== 012 +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +-- +DO LANGUAGE plpgsql $1 +== 013 +COMMIT +-- +COMMIT +== 014 +TRUNCATE test1 +-- +TRUNCATE test1 +== 015 +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +-- +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $1 +== 016 +SELECT transaction_test2() +-- +SELECT transaction_test2() +== 017 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 018 +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +-- +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $1 +== 019 +SELECT transaction_test3() +-- +SELECT transaction_test3() +== 020 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 021 +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +-- +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $1 +== 022 +SELECT transaction_test4() +-- +SELECT transaction_test4() +== 023 +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = 555 +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = $2 +AS $1 +== 024 +CALL transaction_test5() +-- +CALL transaction_test5() +== 025 +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $1 +== 026 +CALL transaction_test5b() +-- +CALL transaction_test5b() +== 027 +TRUNCATE test1 +-- +TRUNCATE test1 +== 028 +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +-- +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $1 +== 029 +CALL transaction_test6('bar') +-- +CALL transaction_test6($1) +== 030 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 031 +TRUNCATE test1 +-- +TRUNCATE test1 +== 032 +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +-- +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $1 +== 033 +CALL transaction_test7() +-- +CALL transaction_test7() +== 034 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 035 +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +-- +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $1 +== 036 +CALL transaction_test8() +-- +CALL transaction_test8() +== 037 +-- commit inside cursor loop +CREATE TABLE test2 (x int) +-- +-- commit inside cursor loop +CREATE TABLE test2 (x int) +== 038 +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +-- +INSERT INTO test2 VALUES ($1), ($2), ($3), ($4), ($5) +== 039 +TRUNCATE test1 +-- +TRUNCATE test1 +== 040 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 041 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 042 +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +-- +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +== 043 +-- error in cursor loop with commit +TRUNCATE test1 +-- +-- error in cursor loop with commit +TRUNCATE test1 +== 044 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 045 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 046 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 047 +-- rollback inside cursor loop +TRUNCATE test1 +-- +-- rollback inside cursor loop +TRUNCATE test1 +== 048 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 049 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 050 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 051 +-- first commit then rollback inside cursor loop +TRUNCATE test1 +-- +-- first commit then rollback inside cursor loop +TRUNCATE test1 +== 052 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 053 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 054 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 055 +-- rollback inside cursor loop +TRUNCATE test1 +-- +-- rollback inside cursor loop +TRUNCATE test1 +== 056 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 057 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 058 +SELECT * FROM test2 +-- +SELECT * FROM test2 +== 059 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 060 +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +-- +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +== 061 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +INSERT INTO test1 VALUES ($1,$2), ($3,$4), ($5,$6) +== 062 +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 063 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 064 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 065 +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +-- +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +== 066 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +INSERT INTO test1 VALUES ($1,$2), ($3,$4), ($5,$6) +== 067 +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 068 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 069 +SELECT * FROM pg_cursors +-- +SELECT * FROM pg_cursors +== 070 +-- commit inside block with exception handler +TRUNCATE test1 +-- +-- commit inside block with exception handler +TRUNCATE test1 +== 071 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 072 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 073 +-- rollback inside block with exception handler +TRUNCATE test1 +-- +-- rollback inside block with exception handler +TRUNCATE test1 +== 074 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 075 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 076 +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +-- +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +== 077 +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 078 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 079 +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +-- +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +== 080 +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +-- +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +== 081 +-- disable compression +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +-- +-- disable compression +INSERT INTO test4 SELECT repeat($1, $2) +== 082 +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS 'select f1 from test4' IMMUTABLE +-- +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS $1 IMMUTABLE +== 083 +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +-- +DO $1 +== 084 +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +-- +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $1 +== 085 +-- COMMIT failures +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +-- +-- COMMIT failures +DO LANGUAGE plpgsql $1 +== 086 +SELECT * FROM test3 +-- +SELECT * FROM test3 +== 087 +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +-- +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $1 +== 088 +TRUNCATE test1 +-- +TRUNCATE test1 +== 089 +CALL cursor_fail_during_commit() +-- +CALL cursor_fail_during_commit() +== 090 +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +-- +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +== 091 +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +-- +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $1 +== 092 +TRUNCATE test1 +-- +TRUNCATE test1 +== 093 +CALL cursor_fail_during_rollback() +-- +CALL cursor_fail_during_rollback() +== 094 +SELECT count(*) FROM test1 +-- +SELECT count(*) FROM test1 +== 095 +-- SET TRANSACTION +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +-- +-- SET TRANSACTION +DO LANGUAGE plpgsql $1 +== 096 +-- error cases +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +-- +-- error cases +DO LANGUAGE plpgsql $1 +== 097 +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 098 +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +-- +DO LANGUAGE plpgsql $1 +== 099 +-- snapshot handling test +TRUNCATE test2 +-- +-- snapshot handling test +TRUNCATE test2 +== 100 +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$ +-- +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $1 +== 101 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +-- +DO LANGUAGE plpgsql $1 +== 102 +SELECT * FROM test2 +-- +SELECT * FROM test2 +== 103 +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $$ SELECT COUNT(*) FROM test2 $$ +-- +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $1 +== 104 +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +-- +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $1 +== 105 +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +-- +DO $1 +== 106 +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +-- +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $1 +== 107 +CALL transaction_test10a(10) +-- +CALL transaction_test10a($1) +== 108 +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +-- +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $1 +== 109 +CALL transaction_test10b(10) +-- +CALL transaction_test10b($1) +== 110 +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +-- +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $1 +== 111 +CALL transaction_test11() +-- +CALL transaction_test11() +== 112 +-- transaction chain + +TRUNCATE test1 +-- +-- transaction chain + +TRUNCATE test1 +== 113 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +-- +DO LANGUAGE plpgsql $1 +== 114 +SELECT * FROM test1 +-- +SELECT * FROM test1 +== 115 +DROP TABLE test1 +-- +DROP TABLE test1 +== 116 +DROP TABLE test2 +-- +DROP TABLE test2 +== 117 +DROP TABLE test3 +-- +DROP TABLE test3 diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_trap.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_trap.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_trap.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_trap.test new file mode 100644 index 0000000..057eada --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_trap.test @@ -0,0 +1,310 @@ +== 001 +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $1 language plpgsql +== 002 +select trap_zero_divide(50) +-- +select trap_zero_divide($1) +== 003 +select trap_zero_divide(0) +-- +select trap_zero_divide($1) +== 004 +select trap_zero_divide(100000) +-- +select trap_zero_divide($1) +== 005 +select trap_zero_divide(-100) +-- +select trap_zero_divide($1) +== 006 +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +-- +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +== 007 +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +create function trap_matching_test(int) returns int as $1 language plpgsql +== 008 +select trap_matching_test(50) +-- +select trap_matching_test($1) +== 009 +select trap_matching_test(0) +-- +select trap_matching_test($1) +== 010 +select trap_matching_test(100000) +-- +select trap_matching_test($1) +== 011 +select trap_matching_test(1) +-- +select trap_matching_test($1) +== 012 +create temp table foo (f1 int) +-- +create temp table foo (f1 int) +== 013 +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql +-- +create function subxact_rollback_semantics() returns int as $1 language plpgsql +== 014 +select subxact_rollback_semantics() +-- +select subxact_rollback_semantics() +== 015 +select * from foo +-- +select * from foo +== 016 +drop table foo +-- +drop table foo +== 017 +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql +-- +create function trap_timeout() returns void as $1 language plpgsql +== 018 +begin +-- +begin +== 019 +set statement_timeout to 1000 +-- +set statement_timeout to $1 +== 020 +select trap_timeout() +-- +select trap_timeout() +== 021 +rollback +-- +rollback +== 022 +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql +-- +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $1 language plpgsql +== 023 +select test_variable_storage() +-- +select test_variable_storage() +== 024 +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +-- +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +== 025 +create temp table leaf(f1 int references root deferrable) +-- +create temp table leaf(f1 int references root deferrable) +== 026 +insert into root values(1) +-- +insert into root values($1) +== 027 +insert into leaf values(1) +-- +insert into leaf values($1) +== 028 +insert into leaf values(2) +-- +insert into leaf values($1) +== 029 +-- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +-- fails + +create function trap_foreign_key(int) returns int as $1 language plpgsql +== 030 +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +create function trap_foreign_key_2() returns int as $1 language plpgsql +== 031 +select trap_foreign_key(1) +-- +select trap_foreign_key($1) +== 032 +select trap_foreign_key(2) +-- +select trap_foreign_key($1) +== 033 +-- detects FK violation + +begin +-- +-- detects FK violation + +begin +== 034 +set constraints all deferred +-- +set constraints all deferred +== 035 +select trap_foreign_key(2) +-- +select trap_foreign_key($1) +== 036 +-- should not detect FK violation + savepoint x +-- +-- should not detect FK violation + savepoint x +== 037 +set constraints all immediate +-- +set constraints all immediate +== 038 +-- fails + rollback to x +-- +-- fails + rollback to x +== 039 +select trap_foreign_key_2() +-- +select trap_foreign_key_2() +== 040 +-- detects FK violation +commit +-- +-- detects FK violation +commit +== 041 +-- still fails + +drop function trap_foreign_key(int) +-- +-- still fails + +drop function trap_foreign_key(int) +== 042 +drop function trap_foreign_key_2() +-- +drop function trap_foreign_key_2() diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.test new file mode 100644 index 0000000..100da3c --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_trigger.test @@ -0,0 +1,41 @@ +== 001 +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +-- +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +== 002 +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +-- +create function testtr_trigger() returns trigger language plpgsql as +$1 +== 003 +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +-- +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +== 004 +insert into testtr values (1, 'one'), (2, 'two') +-- +insert into testtr values ($1, $2), ($3, $4) +== 005 +update testtr set a = a + 1 +-- +update testtr set a = a + $1 +== 006 +delete from testtr +-- +delete from testtr diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.test b/parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.test new file mode 100644 index 0000000..feb57c4 --- /dev/null +++ b/parser/testdata/normalize/plpgsql_regress/plpgsql_varprops.test @@ -0,0 +1,339 @@ +== 001 +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +-- +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +== 002 +create domain int_nn as int not null +-- +create domain int_nn as int not null +== 003 +create domain var_record_nn as var_record not null +-- +create domain var_record_nn as var_record not null +== 004 +create domain var_record_colnn as var_record check((value).f2 is not null) +-- +create domain var_record_colnn as var_record check((value).f2 is not null) +== 005 +-- CONSTANT + +do $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +-- +-- CONSTANT + +do $1 +== 006 +do $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +-- +do $1 +== 007 +do $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +do $1 +== 008 +do $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +-- +do $1 +== 009 +do $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +-- +do $1 +== 010 +do $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +-- +do $1 +== 011 +do $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +do $1 +== 012 +-- initializer expressions + +do $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +-- +-- initializer expressions + +do $1 +== 013 +do $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 014 +do $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 015 +do $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 016 +do $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 017 +-- NOT NULL + +do $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +-- NOT NULL + +do $1 +== 018 +do $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +do $1 +== 019 +do $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 020 +do $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 021 +do $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +do $1 +== 022 +do $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 023 +do $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 024 +do $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +do $1 +== 025 +do $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 026 +-- Check that variables are reinitialized on block re-entry. + +do $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +-- +-- Check that variables are reinitialized on block re-entry. + +do $1 +== 027 +-- Check enforcement of domain constraints during initialization + +do $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +-- Check enforcement of domain constraints during initialization + +do $1 +== 028 +do $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 029 +do $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +do $1 +== 030 +do $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 031 +do $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 032 +do $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +-- +do $1 +== 033 +do $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 034 +do $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 035 +do $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +-- +do $1 +== 036 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +do $1 +== 037 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ +-- +do $1 diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_array.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_array.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_array.test b/parser/testdata/parse/plpgsql_regress/plpgsql_array.test new file mode 100644 index 0000000..29f70aa --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_array.test @@ -0,0 +1,218 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of array variables +|-- +-- We also check arrays of composites here, so this has some overlap +-- with the plpgsql_record tests. +|-- + +create type complex as (r float8, i float8) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"complex","relpersistence":"p","location":175},"coldeflist":[{"ColumnDef":{"colname":"r","typeName":{"names":[{"String":{"sval":"float8"}}],"typemod":-1,"location":189},"is_local":true,"location":187}},{"ColumnDef":{"colname":"i","typeName":{"names":[{"String":{"sval":"float8"}}],"typemod":-1,"location":199},"is_local":true,"location":197}}]}}}]} +== 002 +create type quadarray as (c1 complex[], c2 complex) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"quadarray","relpersistence":"p","location":12},"coldeflist":[{"ColumnDef":{"colname":"c1","typeName":{"names":[{"String":{"sval":"complex"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":29},"is_local":true,"location":26}},{"ColumnDef":{"colname":"c2","typeName":{"names":[{"String":{"sval":"complex"}}],"typemod":-1,"location":43},"is_local":true,"location":40}}]}}}]} +== 003 +do $$ declare a int[]; +begin a := array[1,2]; a[3] := 4; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := array[1,2]; a[3] := 4; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 004 +do $$ declare a int[]; +begin a[3] := 4; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a[3] := 4; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 005 +do $$ declare a int[]; +begin a[1][4] := 4; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a[1][4] := 4; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 006 +do $$ declare a int[]; +begin a[1] := 23::text; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a[1] := 23::text; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 007 +-- lax typing + +do $$ declare a int[]; +begin a := array[1,2]; a[2:3] := array[3,4]; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := array[1,2]; a[2:3] := array[3,4]; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":18}}]}}}]} +== 008 +do $$ declare a int[]; +begin a := array[1,2]; a[2] := a[2] + 1; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := array[1,2]; a[2] := a[2] + 1; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 009 +do $$ declare a int[]; +begin a[1:2] := array[3,4]; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a[1:2] := array[3,4]; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 010 +do $$ declare a int[]; +begin a[1:2] := 4; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a[1:2] := 4; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 011 +-- error + +do $$ declare a complex[]; +begin a[1] := (1,2); a[1].i := 11; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a complex[];\nbegin a[1] := (1,2); a[1].i := 11; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":13}}]}}}]} +== 012 +do $$ declare a complex[]; +begin a[1].i := 11; raise notice 'a = %, a[1].i = %', a, a[1].i; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a complex[];\nbegin a[1].i := 11; raise notice 'a = %, a[1].i = %', a, a[1].i; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 013 +-- perhaps this ought to work, but for now it doesn't: +do $$ declare a complex[]; +begin a[1:2].i := array[11,12]; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a complex[];\nbegin a[1:2].i := array[11,12]; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":58}}]}}}]} +== 014 +do $$ declare a quadarray; +begin a.c1[1].i := 11; raise notice 'a = %, a.c1[1].i = %', a, a.c1[1].i; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a quadarray;\nbegin a.c1[1].i := 11; raise notice 'a = %, a.c1[1].i = %', a, a.c1[1].i; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 015 +do $$ declare a int[]; +begin a := array_agg(x) from (values(1),(2),(3)) v(x); raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := array_agg(x) from (values(1),(2),(3)) v(x); raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 016 +create temp table onecol as select array[1,2] as f1 +-- +{"version":170007,"stmts":[{"stmt":{"CreateTableAsStmt":{"query":{"SelectStmt":{"targetList":[{"ResTarget":{"name":"f1","val":{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{"ival":1},"location":41}},{"A_Const":{"ival":{"ival":2},"location":43}}],"location":35}},"location":35}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"into":{"rel":{"relname":"onecol","inh":true,"relpersistence":"t","location":18},"onCommit":"ONCOMMIT_NOOP"},"objtype":"OBJECT_TABLE"}}}]} +== 017 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := f1 from onecol; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 018 +do $$ declare a int[]; +begin a := * from onecol for update; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := * from onecol for update; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 019 +-- error cases: + +do $$ declare a int[]; +begin a := from onecol; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := from onecol; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 020 +do $$ declare a int[]; +begin a := f1, f1 from onecol; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := f1, f1 from onecol; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 021 +insert into onecol values(array[11]) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"onecol","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{"ival":11},"location":32}}],"location":26}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 022 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := f1 from onecol; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 023 +do $$ declare a int[]; +begin a := f1 from onecol limit 1; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a int[];\nbegin a := f1 from onecol limit 1; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 024 +do $$ declare a real; +begin a[1] := 2; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a real;\nbegin a[1] := 2; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 025 +do $$ declare a complex; +begin a.r[1] := 2; raise notice 'a = %', a; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare a complex;\nbegin a.r[1] := 2; raise notice 'a = %', a; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 026 +|-- +-- test of %type[] and %rowtype[] syntax +|-- + +-- check supported syntax +do $$ +declare + v int; + v1 v%type; + v2 v%type[]; + v3 v%type[1]; + v4 v%type[][]; + v5 v%type[1][3]; + v6 v%type array; + v7 v%type array[]; + v8 v%type array[1]; + v9 v%type array[1][1]; + v10 pg_catalog.pg_class%rowtype[]; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(v3); + raise notice '%', pg_typeof(v4); + raise notice '%', pg_typeof(v5); + raise notice '%', pg_typeof(v6); + raise notice '%', pg_typeof(v7); + raise notice '%', pg_typeof(v8); + raise notice '%', pg_typeof(v9); + raise notice '%', pg_typeof(v10); +end; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare\n v int;\n v1 v%type;\n v2 v%type[];\n v3 v%type[1];\n v4 v%type[][];\n v5 v%type[1][3];\n v6 v%type array;\n v7 v%type array[];\n v8 v%type array[1];\n v9 v%type array[1][1];\n v10 pg_catalog.pg_class%rowtype[];\nbegin\n raise notice '%', pg_typeof(v1);\n raise notice '%', pg_typeof(v2);\n raise notice '%', pg_typeof(v3);\n raise notice '%', pg_typeof(v4);\n raise notice '%', pg_typeof(v5);\n raise notice '%', pg_typeof(v6);\n raise notice '%', pg_typeof(v7);\n raise notice '%', pg_typeof(v8);\n raise notice '%', pg_typeof(v9);\n raise notice '%', pg_typeof(v10);\nend;\n"}},"defaction":"DEFELEM_UNSPEC","location":77}}]}}}]} +== 027 +-- some types don't support arrays +do $$ +declare + v pg_node_tree; + v1 v%type[]; +begin +end; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare\n v pg_node_tree;\n v1 v%type[];\nbegin\nend;\n"}},"defaction":"DEFELEM_UNSPEC","location":38}}]}}}]} +== 028 +-- check functionality +do $$ +declare + v1 int; + v2 varchar; + a1 v1%type[]; + a2 v2%type[]; +begin + v1 := 10; + v2 := 'Hi'; + a1 := array[v1,v1]; + a2 := array[v2,v2]; + raise notice '% %', a1, a2; +end; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare\n v1 int;\n v2 varchar;\n a1 v1%type[];\n a2 v2%type[];\nbegin\n v1 := 10;\n v2 := 'Hi';\n a1 := array[v1,v1];\n a2 := array[v2,v2];\n raise notice '% %', a1, a2;\nend;\n"}},"defaction":"DEFELEM_UNSPEC","location":26}}]}}}]} +== 029 +create table array_test_table(a int, b varchar) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"array_test_table","inh":true,"relpersistence":"p","location":13},"tableElts":[{"ColumnDef":{"colname":"a","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":32},"is_local":true,"location":30}},{"ColumnDef":{"colname":"b","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"varchar"}}],"typemod":-1,"location":39},"is_local":true,"location":37}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 030 +insert into array_test_table values(1, 'first'), (2, 'second') +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"array_test_table","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":36}},{"A_Const":{"sval":{"sval":"first"},"location":39}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":50}},{"A_Const":{"sval":{"sval":"second"},"location":53}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 031 +do $$ +declare tg array_test_table%rowtype[]; +begin + tg := array(select array_test_table from array_test_table); + raise notice '%', tg; + tg := array(select row(a,b) from array_test_table); + raise notice '%', tg; +end; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare tg array_test_table%rowtype[];\nbegin\n tg := array(select array_test_table from array_test_table);\n raise notice '%', tg;\n tg := array(select row(a,b) from array_test_table);\n raise notice '%', tg;\nend;\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_cache.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_cache.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_cache.test b/parser/testdata/parse/plpgsql_regress/plpgsql_cache.test new file mode 100644 index 0000000..52fae3f --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_cache.test @@ -0,0 +1,82 @@ +== 001 +|-- +-- Cache-behavior-dependent test cases +|-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- depending on debug_discard_caches, so we must have two expected-output +-- files to cover both cases. To minimize the maintenance effort resulting +-- from that, this file should contain only tests that do have different +-- results under debug_discard_caches. +|-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"c_mutable","inh":true,"relpersistence":"p","location":527},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":540},"is_local":true,"location":537}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":548},"is_local":true,"location":545}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 002 +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"c_sillyaddone"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":30},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":43},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":47}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":64}}]}}}]} +== 003 +select c_sillyaddone(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"c_sillyaddone"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 004 +alter table c_mutable drop column f1 +-- +{"version":170007,"stmts":[{"stmt":{"AlterTableStmt":{"relation":{"relname":"c_mutable","inh":true,"relpersistence":"p","location":12},"cmds":[{"AlterTableCmd":{"subtype":"AT_DropColumn","name":"f1","behavior":"DROP_RESTRICT"}}],"objtype":"OBJECT_TABLE"}}}]} +== 005 +alter table c_mutable add column f1 float8 +-- +{"version":170007,"stmts":[{"stmt":{"AlterTableStmt":{"relation":{"relname":"c_mutable","inh":true,"relpersistence":"p","location":12},"cmds":[{"AlterTableCmd":{"subtype":"AT_AddColumn","def":{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"float8"}}],"typemod":-1,"location":36},"is_local":true,"location":33}},"behavior":"DROP_RESTRICT"}}],"objtype":"OBJECT_TABLE"}}}]} +== 006 +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but if debug_discard_caches is on, it will succeed) +select c_sillyaddone(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"c_sillyaddone"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":147}}],"funcformat":"COERCE_EXPLICIT_CALL","location":133}},"location":133}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 007 +-- but it's OK if we force plan rebuilding +discard plans +-- +{"version":170007,"stmts":[{"stmt":{"DiscardStmt":{"target":"DISCARD_PLANS"}}}]} +== 008 +select c_sillyaddone(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"c_sillyaddone"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 009 +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"show_result_type"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":84},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":98},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":103}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\n declare\n r record;\n t text;\n begin\n execute $1 into r;\n select pg_typeof(r.a) into t;\n return format('type %s value %s', t, r.a::text);\n end;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":120}}]}}}]} +== 010 +select show_result_type('select 1 as a') +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"show_result_type"}}],"args":[{"A_Const":{"sval":{"sval":"select 1 as a"},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 011 +-- currently this fails due to cached plan for pg_typeof expression +-- (but if debug_discard_caches is on, it will succeed) +select show_result_type('select 2.0 as a') +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"show_result_type"}}],"args":[{"A_Const":{"sval":{"sval":"select 2.0 as a"},"location":148}}],"funcformat":"COERCE_EXPLICIT_CALL","location":131}},"location":131}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 012 +-- but it's OK if we force plan rebuilding +discard plans +-- +{"version":170007,"stmts":[{"stmt":{"DiscardStmt":{"target":"DISCARD_PLANS"}}}]} +== 013 +select show_result_type('select 2.0 as a') +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"show_result_type"}}],"args":[{"A_Const":{"sval":{"sval":"select 2.0 as a"},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_call.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_call.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_call.test b/parser/testdata/parse/plpgsql_regress/plpgsql_call.test new file mode 100644 index 0000000..3ee8766 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_call.test @@ -0,0 +1,748 @@ +== 001 +|-- +-- Tests for procedures / CALL syntax +|-- + +CREATE PROCEDURE test_proc1() +LANGUAGE plpgsql +AS $$ +BEGIN + NULL; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc1"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":75}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n NULL;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":92}}]}}}]} +== 002 +CALL test_proc1() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc1"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 003 +-- error: can't return non-NULL +CREATE PROCEDURE test_proc2() +LANGUAGE plpgsql +AS $$ +BEGIN + RETURN 5; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc2"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":62}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RETURN 5;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":79}}]}}}]} +== 004 +CREATE TABLE test1 (a int) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"test1","inh":true,"relpersistence":"p","location":13},"tableElts":[{"ColumnDef":{"colname":"a","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":22},"is_local":true,"location":20}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 005 +CREATE PROCEDURE test_proc3(x int) +LANGUAGE plpgsql +AS $$ +BEGIN + INSERT INTO test1 VALUES (x); +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc3"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":30},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":35}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n INSERT INTO test1 VALUES (x);\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":52}}]}}}]} +== 006 +CALL test_proc3(55) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc3"}}],"args":[{"A_Const":{"ival":{"ival":55},"location":16}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 007 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 008 +-- Check that plan revalidation doesn't prevent setting transaction properties +-- (bug #18059). This test must include the first temp-object creation in +-- this script, or it won't exercise the bug scenario. Hence we put it early. +CREATE PROCEDURE test_proc3a() +LANGUAGE plpgsql +AS $$ +BEGIN + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + RAISE NOTICE 'done'; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc3a"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":264}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n COMMIT;\n SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;\n RAISE NOTICE 'done';\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":281}}]}}}]} +== 009 +CALL test_proc3a() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc3a"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 010 +CREATE TEMP TABLE tt1(f1 int) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"tt1","inh":true,"relpersistence":"t","location":18},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":25},"is_local":true,"location":22}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 011 +CALL test_proc3a() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc3a"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 012 +-- nested CALL +TRUNCATE TABLE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":30}}],"behavior":"DROP_RESTRICT"}}}]} +== 013 +CREATE PROCEDURE test_proc4(y int) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL test_proc3(y); + CALL test_proc3($1); +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc4"}}],"parameters":[{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":30},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":35}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n CALL test_proc3(y);\n CALL test_proc3($1);\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":52}}]}}}]} +== 014 +CALL test_proc4(66) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc4"}}],"args":[{"A_Const":{"ival":{"ival":66},"location":16}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 015 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 016 +CALL test_proc4(66) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc4"}}],"args":[{"A_Const":{"ival":{"ival":66},"location":16}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 017 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 018 +-- output arguments + +CREATE PROCEDURE test_proc5(INOUT a text) +LANGUAGE plpgsql +AS $$ +BEGIN + a := a || '+' || a; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc5"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":57},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":63}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n a := a || '+' || a;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":80}}]}}}]} +== 019 +CALL test_proc5('abc') +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc5"}}],"args":[{"A_Const":{"sval":{"sval":"abc"},"location":16}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 020 +CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + b := b * a; + c := c * a; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc6"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":30},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":43},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"c","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":56},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":61}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n b := b * a;\n c := c * a;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":78}}]}}}]} +== 021 +CALL test_proc6(2, 3, 4) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc6"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":16}},{"A_Const":{"ival":{"ival":3},"location":19}},{"A_Const":{"ival":{"ival":4},"location":22}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 022 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); + RAISE INFO 'x = %, y = %', x, y; + CALL test_proc6(2, c => y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n x int := 3;\n y int := 4;\nBEGIN\n CALL test_proc6(2, x, y);\n RAISE INFO 'x = %, y = %', x, y;\n CALL test_proc6(2, c =\u003e y, b =\u003e x);\n RAISE INFO 'x = %, y = %', x, y;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 023 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n x int := 3;\n y int := 4;\nBEGIN\n CALL test_proc6(2, x + 1, y); -- error\n RAISE INFO 'x = %, y = %', x, y;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 024 +DO +LANGUAGE plpgsql +$$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n x constant int := 3;\n y int := 4;\nBEGIN\n CALL test_proc6(2, x, y); -- error because x is constant\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 025 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n x int := 3;\n y int := 4;\nBEGIN\n FOR i IN 1..5 LOOP\n CALL test_proc6(i, x, y);\n RAISE INFO 'x = %, y = %', x, y;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 026 +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc7"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":66},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":79},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"numeric"}}],"typemod":-1,"location":92},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":101}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\nIF x \u003e 1 THEN\n a := x / 10;\n b := x / 2;\n CALL test_proc7(b::int, a, b);\nEND IF;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":118}}]}}}]} +== 027 +CALL test_proc7(100, -1, -1) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc7"}}],"args":[{"A_Const":{"ival":{"ival":100},"location":16}},{"A_Const":{"ival":{"ival":-1},"location":21}},{"A_Const":{"ival":{"ival":-1},"location":25}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 028 +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc7c"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":70},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":83},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"numeric"}}],"typemod":-1,"location":96},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":105}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n a := x / 10;\n b := x / 2;\n COMMIT;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":122}}]}}}]} +== 029 +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc7cc"}}],"parameters":[{"FunctionParameter":{"name":"_x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":33},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":38}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nDECLARE _a int; _b numeric;\nBEGIN\n CALL test_proc7c(_x, _a, _b);\n RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":55}}]}}}]} +== 030 +CALL test_proc7cc(10) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc7cc"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":18}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 031 +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc8a"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":71},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":84},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":89}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'a: %, b: %', a, b;\n a := a * 10;\n b := b + 10;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":106}}]}}}]} +== 032 +CALL test_proc8a(10, 20) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc8a"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":17}},{"A_Const":{"ival":{"ival":20},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 033 +CALL test_proc8a(b => 20, a => 10) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"test_proc8a"}}],"args":[{"NamedArgExpr":{"arg":{"A_Const":{"ival":{"ival":20},"location":22}},"name":"b","argnumber":-1,"location":17}},{"NamedArgExpr":{"arg":{"A_Const":{"ival":{"ival":10},"location":31}},"name":"a","argnumber":-1,"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 034 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int;\nBEGIN\n _a := 10; _b := 30;\n CALL test_proc8a(_a, _b);\n RAISE NOTICE '_a: %, _b: %', _a, _b;\n CALL test_proc8a(b =\u003e _b, a =\u003e _a);\n RAISE NOTICE '_a: %, _b: %', _a, _b;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 035 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc8b"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":37},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":50},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"c","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":63},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":68}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'a: %, b: %, c: %', a, b, c;\n a := a * 10;\n b := b + 10;\n c := c * -10;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":85}}]}}}]} +== 036 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c int;\nBEGIN\n _a := 10; _b := 30; _c := 50;\n CALL test_proc8b(_a, _b, _c);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n CALL test_proc8b(_a, c =\u003e _c, b =\u003e _b);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 037 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc8c"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":37},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":50},"mode":"FUNC_PARAM_INOUT"}},{"FunctionParameter":{"name":"c","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":63},"mode":"FUNC_PARAM_INOUT","defexpr":{"A_Const":{"ival":{"ival":11},"location":75}}}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":79}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'a: %, b: %, c: %', a, b, c;\n a := a * 10;\n b := b + 10;\n c := c * -10;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":96}}]}}}]} +== 038 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c int;\nBEGIN\n _a := 10; _b := 30; _c := 50;\n CALL test_proc8c(_a, _b, _c);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n _a := 10; _b := 30; _c := 50;\n CALL test_proc8c(_a, c =\u003e _c, b =\u003e _b);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n _a := 10; _b := 30; _c := 50;\n CALL test_proc8c(c =\u003e _c, b =\u003e _b, a =\u003e _a);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 039 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c int;\nBEGIN\n _a := 10; _b := 30; _c := 50;\n CALL test_proc8c(_a, _b); -- fail, no output argument for c\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 040 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c int;\nBEGIN\n _a := 10; _b := 30; _c := 50;\n CALL test_proc8c(_a, b =\u003e _b); -- fail, no output argument for c\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 041 +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc9"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":52},"mode":"FUNC_PARAM_IN"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":63},"mode":"FUNC_PARAM_OUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":68}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'a: %, b: %', a, b;\n b := a * 2;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":85}}]}}}]} +== 042 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int;\nBEGIN\n _a := 10; _b := 30;\n CALL test_proc9(_a, _b);\n RAISE NOTICE '_a: %, _b: %', _a, _b;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 043 +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc10"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":34},"mode":"FUNC_PARAM_IN"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":45},"mode":"FUNC_PARAM_OUT"}},{"FunctionParameter":{"name":"c","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":55},"mode":"FUNC_PARAM_IN","defexpr":{"A_Const":{"ival":{"ival":11},"location":67}}}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":71}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'a: %, b: %, c: %', a, b, c;\n b := a - c;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":88}}]}}}]} +== 044 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c int;\nBEGIN\n _a := 10; _b := 30; _c := 7;\n CALL test_proc10(_a, _b, _c);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n\n _a := 10; _b := 30; _c := 7;\n CALL test_proc10(_a, _b, c =\u003e _c);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n\n _a := 10; _b := 30; _c := 7;\n CALL test_proc10(a =\u003e _a, b =\u003e _b, c =\u003e _c);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n\n _a := 10; _b := 30; _c := 7;\n CALL test_proc10(_a, c =\u003e _c, b =\u003e _b);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n\n _a := 10; _b := 30; _c := 7;\n CALL test_proc10(_a, _b);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n\n _a := 10; _b := 30; _c := 7;\n CALL test_proc10(_a, b =\u003e _b);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\n\n _a := 10; _b := 30; _c := 7;\n CALL test_proc10(b =\u003e _b, a =\u003e _a);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 045 +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc11"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":54},"mode":"FUNC_PARAM_OUT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":70},"mode":"FUNC_PARAM_VARIADIC"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":77}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'a: %, b: %', a, b;\n a := b[1] + b[2];\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":94}}]}}}]} +== 046 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c int;\nBEGIN\n _a := 10; _b := 30; _c := 7;\n CALL test_proc11(_a, _b, _c);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 047 +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"test_proc12"}}],"parameters":[{"FunctionParameter":{"name":"a","argType":{"names":[{"String":{"sval":"anyelement"}}],"typemod":-1,"location":61},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"b","argType":{"names":[{"String":{"sval":"anyelement"}}],"typemod":-1,"location":79},"mode":"FUNC_PARAM_OUT"}},{"FunctionParameter":{"name":"c","argType":{"names":[{"String":{"sval":"anyarray"}}],"typemod":-1,"location":97},"mode":"FUNC_PARAM_OUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":107}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'a: %', a;\n b := a;\n c := array[a];\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":124}}]}}}]} +== 048 +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c int[];\nBEGIN\n _a := 10;\n CALL test_proc12(_a, _b, _c);\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 049 +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE _a int; _b int; _c text[];\nBEGIN\n _a := 10;\n CALL test_proc12(_a, _b, _c); -- error\n RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 050 +-- transition variable assignment + +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":44}}],"behavior":"DROP_RESTRICT"}}}]} +== 051 +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"triggerfunc1"}}],"returnType":{"names":[{"String":{"sval":"trigger"}}],"typemod":-1,"location":39},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":47}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nDECLARE\n z int := 0;\nBEGIN\n CALL test_proc6(2, NEW.a, NEW.a);\n RETURN NEW;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":64}}]}}}]} +== 052 +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +-- +{"version":170007,"stmts":[{"stmt":{"CreateTrigStmt":{"trigname":"t1","relation":{"relname":"test1","inh":true,"relpersistence":"p","location":35},"funcname":[{"String":{"sval":"triggerfunc1"}}],"timing":2,"events":4}}}]} +== 053 +INSERT INTO test1 VALUES (1), (2), (3) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"test1","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":26}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":31}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":3},"location":36}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 054 +UPDATE test1 SET a = 22 WHERE a = 2 +-- +{"version":170007,"stmts":[{"stmt":{"UpdateStmt":{"relation":{"relname":"test1","inh":true,"relpersistence":"p","location":7},"targetList":[{"ResTarget":{"name":"a","val":{"A_Const":{"ival":{"ival":22},"location":21}},"location":17}}],"whereClause":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"="}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"a"}}],"location":30}},"rexpr":{"A_Const":{"ival":{"ival":2},"location":34}},"location":32}}}}}]} +== 055 +SELECT * FROM test1 ORDER BY a +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"sortClause":[{"SortBy":{"node":{"ColumnRef":{"fields":[{"String":{"sval":"a"}}],"location":29}},"sortby_dir":"SORTBY_DEFAULT","sortby_nulls":"SORTBY_NULLS_DEFAULT","location":-1}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 056 +DROP PROCEDURE test_proc1 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"ObjectWithArgs":{"objname":[{"String":{"sval":"test_proc1"}}],"args_unspecified":true}}],"removeType":"OBJECT_PROCEDURE","behavior":"DROP_RESTRICT"}}}]} +== 057 +DROP PROCEDURE test_proc3 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"ObjectWithArgs":{"objname":[{"String":{"sval":"test_proc3"}}],"args_unspecified":true}}],"removeType":"OBJECT_PROCEDURE","behavior":"DROP_RESTRICT"}}}]} +== 058 +DROP PROCEDURE test_proc4 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"ObjectWithArgs":{"objname":[{"String":{"sval":"test_proc4"}}],"args_unspecified":true}}],"removeType":"OBJECT_PROCEDURE","behavior":"DROP_RESTRICT"}}}]} +== 059 +DROP TABLE test1 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"List":{"items":[{"String":{"sval":"test1"}}]}}],"removeType":"OBJECT_TABLE","behavior":"DROP_RESTRICT"}}}]} +== 060 +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"p1"}}],"parameters":[{"FunctionParameter":{"name":"v_cnt","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":71},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"v_text","argType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":89},"mode":"FUNC_PARAM_INOUT","defexpr":{"A_Const":{"isnull":true,"location":96}}}}],"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n v_Text := 'v_cnt = ' || v_cnt;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":102}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":154}}]}}}]} +== 061 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n v_Text text;\n v_cnt integer := 42;\nBEGIN\n CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text\n RAISE NOTICE '%', v_Text;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 062 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n v_Text text;\n v_cnt integer := 42;\nBEGIN\n CALL p1(v_cnt := v_cnt, v_Text := v_Text);\n RAISE NOTICE '%', v_Text;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 063 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n v_Text text;\nBEGIN\n CALL p1(10, v_Text := v_Text);\n RAISE NOTICE '%', v_Text;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 064 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n v_Text text;\n v_cnt integer;\nBEGIN\n CALL p1(v_Text := v_Text, v_cnt := v_cnt);\n RAISE NOTICE '%', v_Text;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 065 +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"inner_p"}}],"parameters":[{"FunctionParameter":{"name":"f1","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":164},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'inner_p(%)', f1;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":169}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":221}}]}}}]} +== 066 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"f"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":18},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":31},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" SELECT $1 + 1 "}}]}},"defaction":"DEFELEM_UNSPEC","location":35}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":58}}]}}}]} +== 067 +CREATE PROCEDURE outer_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"outer_p"}}],"parameters":[{"FunctionParameter":{"name":"f1","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":29},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'outer_p(%)', f1;\n CALL inner_p(f(f1));\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":34}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":109}}]}}}]} +== 068 +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"outer_f"}}],"parameters":[{"FunctionParameter":{"name":"f1","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":28},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":41},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'outer_f(%)', f1;\n CALL inner_p(f(f1));\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":46}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":121}}]}}}]} +== 069 +CALL outer_p(42) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"outer_p"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 070 +SELECT outer_f(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"outer_f"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":15}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 071 +DROP FUNCTION f(int) +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"ObjectWithArgs":{"objname":[{"String":{"sval":"f"}}],"objargs":[{"TypeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":16}}],"objfuncargs":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":16},"mode":"FUNC_PARAM_DEFAULT"}}]}}],"removeType":"OBJECT_FUNCTION","behavior":"DROP_RESTRICT"}}}]} +== 072 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"f"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":18},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":31},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" SELECT $1 + 2 "}}]}},"defaction":"DEFELEM_UNSPEC","location":35}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":58}}]}}}]} +== 073 +CALL outer_p(42) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"outer_p"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 074 +SELECT outer_f(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"outer_f"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":15}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 075 +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"t_test","inh":true,"relpersistence":"p","location":78},"tableElts":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":88},"is_local":true,"location":86}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 076 +INSERT INTO t_test VALUES (0) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"t_test","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{},"location":27}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 077 +CREATE FUNCTION f_get_x () RETURNS int +AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"f_get_x"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":35},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nDECLARE l_result int;\nBEGIN\n SELECT x INTO l_result FROM t_test;\n RETURN l_result;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":39}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":137}},{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"stable"}},"defaction":"DEFELEM_UNSPEC","location":154}}]}}}]} +== 078 +CREATE PROCEDURE f_print_x (x int) +AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"f_print_x"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":30},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'f_print_x(%)', x;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":35}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":88}}]}}}]} +== 079 +-- test in non-atomic context +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n UPDATE t_test SET x = x + 1;\n RAISE NOTICE 'f_get_x(%)', f_get_x();\n CALL f_print_x(f_get_x());\n UPDATE t_test SET x = x + 1;\n RAISE NOTICE 'f_get_x(%)', f_get_x();\n CALL f_print_x(f_get_x());\n ROLLBACK;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":33}}]}}}]} +== 080 +-- test in non-atomic context, except exception block is locally atomic +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n BEGIN\n UPDATE t_test SET x = x + 1;\n RAISE NOTICE 'f_get_x(%)', f_get_x();\n CALL f_print_x(f_get_x());\n UPDATE t_test SET x = x + 1;\n RAISE NOTICE 'f_get_x(%)', f_get_x();\n CALL f_print_x(f_get_x());\n EXCEPTION WHEN division_by_zero THEN\n RAISE NOTICE '%', SQLERRM;\n END;\n ROLLBACK;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":75}}]}}}]} +== 081 +-- test in atomic context +BEGIN +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_BEGIN","location":-1}}}]} +== 082 +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n UPDATE t_test SET x = x + 1;\n RAISE NOTICE 'f_get_x(%)', f_get_x();\n CALL f_print_x(f_get_x());\n UPDATE t_test SET x = x + 1;\n RAISE NOTICE 'f_get_x(%)', f_get_x();\n CALL f_print_x(f_get_x());\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 083 +ROLLBACK +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_ROLLBACK","location":-1}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_control.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_control.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_control.test b/parser/testdata/parse/plpgsql_regress/plpgsql_control.test new file mode 100644 index 0000000..d127671 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_control.test @@ -0,0 +1,627 @@ +== 001 +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\n -- basic case\n for i in 1..3 loop\n raise notice '1..3: i = %', i;\n end loop;\n -- with BY, end matches exactly\n for i in 1..10 by 3 loop\n raise notice '1..10 by 3: i = %', i;\n end loop;\n -- with BY, end does not match\n for i in 1..11 by 3 loop\n raise notice '1..11 by 3: i = %', i;\n end loop;\n -- zero iterations\n for i in 1..0 by 3 loop\n raise notice '1..0 by 3: i = %', i;\n end loop;\n -- REVERSE\n for i in reverse 10..0 by 3 loop\n raise notice 'reverse 10..0 by 3: i = %', i;\n end loop;\n -- potential overflow\n for i in 2147483620..2147483647 by 10 loop\n raise notice '2147483620..2147483647 by 10: i = %', i;\n end loop;\n -- potential overflow, reverse direction\n for i in reverse -2147483620..-2147483647 by 10 loop\n raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":72}}]}}}]} +== 002 +-- BY can't be zero or negative +do $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\n for i in 1..3 by 0 loop\n raise notice '1..3 by 0: i = %', i;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":35}}]}}}]} +== 003 +do $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\n for i in 1..3 by -1 loop\n raise notice '1..3 by -1: i = %', i;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 004 +do $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\n for i in reverse 1..3 by -1 loop\n raise notice 'reverse 1..3 by -1: i = %', i;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 005 +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"conttesttbl","inh":true,"relpersistence":"p","location":36},"tableElts":[{"ColumnDef":{"colname":"idx","typeName":{"names":[{"String":{"sval":"serial"}}],"typemod":-1,"location":52},"is_local":true,"location":48}},{"ColumnDef":{"colname":"v","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":62},"is_local":true,"location":60}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 006 +insert into conttesttbl(v) values(10) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"conttesttbl","inh":true,"relpersistence":"p","location":12},"cols":[{"ResTarget":{"name":"v","location":24}}],"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":10},"location":34}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 007 +insert into conttesttbl(v) values(20) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"conttesttbl","inh":true,"relpersistence":"p","location":12},"cols":[{"ResTarget":{"name":"v","location":24}}],"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":20},"location":34}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 008 +insert into conttesttbl(v) values(30) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"conttesttbl","inh":true,"relpersistence":"p","location":12},"cols":[{"ResTarget":{"name":"v","location":24}}],"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":30},"location":34}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 009 +insert into conttesttbl(v) values(40) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"conttesttbl","inh":true,"relpersistence":"p","location":12},"cols":[{"ResTarget":{"name":"v","location":24}}],"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":40},"location":34}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 010 +create function continue_test1() returns void as $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"continue_test1"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":41},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare _i integer = 0; _r record;\nbegin\n raise notice '---1---';\n loop\n _i := _i + 1;\n raise notice '%', _i;\n continue when _i \u003c 10;\n exit;\n end loop;\n\n raise notice '---2---';\n \u003c\u003clbl\u003e\u003e\n loop\n _i := _i - 1;\n loop\n raise notice '%', _i;\n continue lbl when _i \u003e 0;\n exit lbl;\n end loop;\n end loop;\n\n raise notice '---3---';\n \u003c\u003cthe_loop\u003e\u003e\n while _i \u003c 10 loop\n _i := _i + 1;\n continue the_loop when _i % 2 = 0;\n raise notice '%', _i;\n end loop;\n\n raise notice '---4---';\n for _i in 1..10 loop\n begin\n -- applies to outer loop, not the nested begin block\n continue when _i \u003c 5;\n raise notice '%', _i;\n end;\n end loop;\n\n raise notice '---5---';\n for _r in select * from conttesttbl loop\n continue when _r.v \u003c= 20;\n raise notice '%', _r.v;\n end loop;\n\n raise notice '---6---';\n for _r in execute 'select * from conttesttbl' loop\n continue when _r.v \u003c= 20;\n raise notice '%', _r.v;\n end loop;\n\n raise notice '---7---';\n \u003c\u003clooplabel\u003e\u003e\n for _i in 1..3 loop\n continue looplabel when _i = 2;\n raise notice '%', _i;\n end loop;\n\n raise notice '---8---';\n _i := 1;\n while _i \u003c= 3 loop\n raise notice '%', _i;\n _i := _i + 1;\n continue when _i = 3;\n end loop;\n\n raise notice '---9---';\n for _r in select * from conttesttbl order by v limit 1 loop\n raise notice '%', _r.v;\n continue;\n end loop;\n\n raise notice '---10---';\n for _r in execute 'select * from conttesttbl order by v limit 1' loop\n raise notice '%', _r.v;\n continue;\n end loop;\n\n raise notice '---11---';\n \u003c\u003couterlooplabel\u003e\u003e\n for _i in 1..2 loop\n raise notice 'outer %', _i;\n \u003c\u003cinnerlooplabel\u003e\u003e\n for _j in 1..3 loop\n continue outerlooplabel when _j = 2;\n raise notice 'inner %', _j;\n end loop;\n end loop;\nend; "}}]}},"defaction":"DEFELEM_UNSPEC","location":46}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":1874}}]}}}]} +== 011 +select continue_test1() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"continue_test1"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 012 +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $$ +begin + begin + continue; + end; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"continue_error1"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":95},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n begin\n continue;\n end;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":100}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":157}}]}}}]} +== 013 +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $$ +begin + begin + exit; + end; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"exit_error1"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":97},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n begin\n exit;\n end;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":102}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":155}}]}}}]} +== 014 +-- should fail: no such label +create function continue_error2() returns void as $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"continue_error2"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":72},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n begin\n loop\n continue no_such_label;\n end loop;\n end;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":77}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":183}}]}}}]} +== 015 +-- should fail: no such label +create function exit_error2() returns void as $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"exit_error2"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":68},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n begin\n loop\n exit no_such_label;\n end loop;\n end;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":73}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":175}}]}}}]} +== 016 +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"continue_error3"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":110},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n \u003c\u003cbegin_block1\u003e\u003e\n begin\n loop\n continue begin_block1;\n end loop;\n end;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":115}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":241}}]}}}]} +== 017 +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"exit_block1"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":108},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n \u003c\u003cbegin_block1\u003e\u003e\n begin\n loop\n exit begin_block1;\n raise exception 'should not get here';\n end loop;\n end;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":113}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":286}}]}}}]} +== 018 +select exit_block1() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"exit_block1"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 019 +-- verbose end block and end loop +create function end_label1() returns void as $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"end_label1"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":71},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\n\u003c\u003cblbl\u003e\u003e\nbegin\n \u003c\u003cflbl1\u003e\u003e\n for i in 1 .. 10 loop\n raise notice 'i = %', i;\n exit flbl1;\n end loop flbl1;\n \u003c\u003cflbl2\u003e\u003e\n for j in 1 .. 10 loop\n raise notice 'j = %', j;\n exit flbl2;\n end loop;\nend blbl;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":76}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":302}}]}}}]} +== 020 +select end_label1() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"end_label1"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 021 +-- should fail: undefined end label +create function end_label2() returns void as $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"end_label2"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":73},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n for _i in 1 .. 10 loop\n exit;\n end loop flbl1;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":78}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":151}}]}}}]} +== 022 +-- should fail: end label does not match start label +create function end_label3() returns void as $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"end_label3"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":90},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\n\u003c\u003couter_label\u003e\u003e\nbegin\n \u003c\u003cinner_label\u003e\u003e\n for _i in 1 .. 10 loop\n exit;\n end loop outer_label;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":95}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":208}}]}}}]} +== 023 +-- should fail: end label on a block without a start label +create function end_label4() returns void as $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"end_label4"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":96},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\n\u003c\u003couter_label\u003e\u003e\nbegin\n for _i in 1 .. 10 loop\n exit;\n end loop outer_label;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":101}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":196}}]}}}]} +== 024 +-- unlabeled exit matches no blocks +do $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\nfor i in 1..10 loop\n \u003c\u003cinnerblock\u003e\u003e\n begin\n begin -- unlabeled block\n exit;\n raise notice 'should not get here';\n end;\n raise notice 'should not get here, either';\n end;\n raise notice 'nor here';\nend loop;\nraise notice 'should get here';\nend"}},"defaction":"DEFELEM_UNSPEC","location":39}}]}}}]} +== 025 +-- check exit out of an unlabeled block to a labeled one +do $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\n\u003c\u003couterblock\u003e\u003e\nbegin\n \u003c\u003cinnerblock\u003e\u003e\n begin\n \u003c\u003cmoreinnerblock\u003e\u003e\n begin\n begin -- unlabeled block\n exit innerblock;\n raise notice 'should not get here';\n end;\n raise notice 'should not get here, either';\n end;\n raise notice 'nor here';\n end;\n raise notice 'should get here';\nend"}},"defaction":"DEFELEM_UNSPEC","location":60}}]}}}]} +== 026 +-- check exit out of outermost block +do $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\n\u003c\u003couterblock\u003e\u003e\nbegin\n \u003c\u003cinnerblock\u003e\u003e\n begin\n exit outerblock;\n raise notice 'should not get here';\n end;\n raise notice 'should not get here, either';\nend"}},"defaction":"DEFELEM_UNSPEC","location":40}}]}}}]} +== 027 +-- unlabeled exit does match a while loop +do $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\n \u003c\u003coutermostwhile\u003e\u003e\n while 1 \u003e 0 loop\n \u003c\u003couterwhile\u003e\u003e\n while 1 \u003e 0 loop\n \u003c\u003cinnerwhile\u003e\u003e\n while 1 \u003e 0 loop\n exit;\n raise notice 'should not get here';\n end loop;\n raise notice 'should get here';\n exit outermostwhile;\n raise notice 'should not get here, either';\n end loop;\n raise notice 'nor here';\n end loop;\n raise notice 'should get here, too';\nend"}},"defaction":"DEFELEM_UNSPEC","location":45}}]}}}]} +== 028 +-- check exit out of an unlabeled while to a labeled one +do $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\n \u003c\u003couterwhile\u003e\u003e\n while 1 \u003e 0 loop\n while 1 \u003e 0 loop\n exit outerwhile;\n raise notice 'should not get here';\n end loop;\n raise notice 'should not get here, either';\n end loop;\n raise notice 'should get here';\nend"}},"defaction":"DEFELEM_UNSPEC","location":60}}]}}}]} +== 029 +-- continue to an outer while +do $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare i int := 0;\nbegin\n \u003c\u003coutermostwhile\u003e\u003e\n while i \u003c 2 loop\n raise notice 'outermostwhile, i = %', i;\n i := i + 1;\n \u003c\u003couterwhile\u003e\u003e\n while 1 \u003e 0 loop\n \u003c\u003cinnerwhile\u003e\u003e\n while 1 \u003e 0 loop\n continue outermostwhile;\n raise notice 'should not get here';\n end loop;\n raise notice 'should not get here, either';\n end loop;\n raise notice 'nor here';\n end loop;\n raise notice 'out of outermostwhile, i = %', i;\nend"}},"defaction":"DEFELEM_UNSPEC","location":33}}]}}}]} +== 030 +-- return out of a while +create function return_from_while() returns int language plpgsql as $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"return_from_while"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":69},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":73}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare i int := 0;\nbegin\n while i \u003c 10 loop\n if i \u003e 2 then\n return i;\n end if;\n i := i + 1;\n end loop;\n return null;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":90}}]}}}]} +== 031 +select return_from_while() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"return_from_while"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 032 +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $proc$ +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice '%', i; + end loop; + -- fore with record var + for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop + raise notice '% % %', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice '%', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop + raise notice '% % %', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop + raise notice '% % %', a, b, c; + end loop; +end; +$proc$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"for_vect"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":83},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\n\u003c\u003clbl\u003e\u003edeclare a integer; b varchar; c varchar; r record;\nbegin\n -- fori\n for i in 1 .. 3 loop\n raise notice '%', i;\n end loop;\n -- fore with record var\n for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop\n raise notice '% % %', r.aa, r.bb, r.cc;\n end loop;\n -- fore with single scalar\n for a in select gs from generate_series(1,4) gs loop\n raise notice '%', a;\n end loop;\n -- fore with multiple scalars\n for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop\n raise notice '% % %', a, b, c;\n end loop;\n -- using qualified names in fors, fore is enabled, disabled only for fori\n for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop\n raise notice '% % %', a, b, c;\n end loop;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":88}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":900}}]}}}]} +== 033 +select for_vect() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"for_vect"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 034 +-- CASE statement + +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ language plpgsql immutable +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"case_test"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int8"}}],"typemod":-1,"location":56},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":72},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare a int = 10;\n b int = 1;\nbegin\n case $1\n when 1 then\n return 'one';\n when 2 then\n return 'two';\n when 3,4,3+5 then\n return 'three, four or eight';\n when a then\n return 'ten';\n when a+b, a+b+1 then\n return 'eleven, twelve';\n end case;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":77}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":381}},{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"immutable"}},"defaction":"DEFELEM_UNSPEC","location":398}}]}}}]} +== 035 +select case_test(1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 036 +select case_test(2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 037 +select case_test(3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":3},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 038 +select case_test(4) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":4},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 039 +select case_test(5) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":5},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 040 +-- fails +select case_test(8) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":8},"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":16}},"location":16}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 041 +select case_test(10) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 042 +select case_test(11) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":11},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 043 +select case_test(12) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":12},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 044 +select case_test(13) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":13},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 045 +-- fails + +create or replace function catch() returns void as $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"catch"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":53},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n raise notice '%', case_test(6);\nexception\n when case_not_found then\n raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":58}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":213}}]}}}]} +== 046 +select catch() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"catch"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 047 +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"case_test"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int8"}}],"typemod":-1,"location":87},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":103},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare a int = 10;\nbegin\n case\n when $1 = 1 then\n return 'one';\n when $1 = a + 2 then\n return 'twelve';\n else\n return 'other';\n end case;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":108}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":287}},{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"immutable"}},"defaction":"DEFELEM_UNSPEC","location":304}}]}}}]} +== 048 +select case_test(1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 049 +select case_test(2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 050 +select case_test(12) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":12},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 051 +select case_test(13) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_test"}}],"args":[{"A_Const":{"ival":{"ival":13},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 052 +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"case_comment"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":83},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":96},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n case $1\n when 1 -- comment before THEN\n then return 'one';\n else\n return 'other';\n end case;\nend;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":101}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":233}},{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"immutable"}},"defaction":"DEFELEM_UNSPEC","location":250}}]}}}]} +== 053 +select case_comment(1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"case_comment"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":20}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_copy.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_copy.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_copy.test b/parser/testdata/parse/plpgsql_regress/plpgsql_copy.test new file mode 100644 index 0000000..2788c56 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_copy.test @@ -0,0 +1,21 @@ +== 001 +-- directory paths are passed to us in environment variables + +-- set up file names to use + +CREATE TABLE copy1 (a int, b float); + +-- COPY TO/FROM not authorized from client. +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 TO stdout; +END; +$$; +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 FROM stdin; +-- +ERROR: "unterminated dollar-quoted string at or near \"$$\nBEGIN\n COPY copy1 FROM stdin;\"" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_domain.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_domain.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_domain.test b/parser/testdata/parse/plpgsql_regress/plpgsql_domain.test new file mode 100644 index 0000000..77bf696 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_domain.test @@ -0,0 +1,483 @@ +== 001 +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"booltrue"}}],"typeName":{"names":[{"String":{"sval":"bool"}}],"typemod":-1,"location":84},"constraints":[{"Constraint":{"contype":"CONSTR_CHECK","initially_valid":true,"raw_expr":{"BoolExpr":{"boolop":"OR_EXPR","args":[{"BooleanTest":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":96}},"booltesttype":"IS_TRUE","location":102}},{"NullTest":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":113}},"nulltesttype":"IS_NULL","location":119}}],"location":110}},"location":89}}]}}}]} +== 002 +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_booltrue"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"booltrue"}}],"typemod":-1,"location":42},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"bool"}}],"typemod":-1,"location":54},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"booltrue"}}],"typemod":-1,"location":68},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn y;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":77}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":106}}]}}}]} +== 003 +SELECT * FROM test_argresult_booltrue(true, true) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_booltrue"}}],"args":[{"A_Const":{"boolval":{"boolval":true},"location":38}},{"A_Const":{"boolval":{"boolval":true},"location":44}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 004 +SELECT * FROM test_argresult_booltrue(false, true) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_booltrue"}}],"args":[{"A_Const":{"boolval":{},"location":38}},{"A_Const":{"boolval":{"boolval":true},"location":45}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 005 +SELECT * FROM test_argresult_booltrue(true, false) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_booltrue"}}],"args":[{"A_Const":{"boolval":{"boolval":true},"location":38}},{"A_Const":{"boolval":{},"location":44}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 006 +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_booltrue"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"bool"}}],"typemod":-1,"location":39},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"bool"}}],"typemod":-1,"location":47},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"booltrue"}}],"typemod":-1,"location":61},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v booltrue := x;\nbegin\nv := y;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":70}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":132}}]}}}]} +== 007 +SELECT * FROM test_assign_booltrue(true, true) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_booltrue"}}],"args":[{"A_Const":{"boolval":{"boolval":true},"location":35}},{"A_Const":{"boolval":{"boolval":true},"location":41}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 008 +SELECT * FROM test_assign_booltrue(false, true) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_booltrue"}}],"args":[{"A_Const":{"boolval":{},"location":35}},{"A_Const":{"boolval":{"boolval":true},"location":42}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 009 +SELECT * FROM test_assign_booltrue(true, false) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_booltrue"}}],"args":[{"A_Const":{"boolval":{"boolval":true},"location":35}},{"A_Const":{"boolval":{},"location":41}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 010 +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"uint2"}}],"typeName":{"names":[{"String":{"sval":"int2"}}],"typemod":-1,"location":23},"constraints":[{"Constraint":{"contype":"CONSTR_CHECK","initially_valid":true,"raw_expr":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"\u003e="}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":35}},"rexpr":{"A_Const":{"ival":{},"location":44}},"location":41}},"location":28}}]}}}]} +== 011 +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_uint2"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"location":39},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":48},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"location":61},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn y;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":67}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":96}}]}}}]} +== 012 +SELECT * FROM test_argresult_uint2(100::uint2, 50) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_uint2"}}],"args":[{"TypeCast":{"arg":{"A_Const":{"ival":{"ival":100},"location":35}},"typeName":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"location":40},"location":38}},{"A_Const":{"ival":{"ival":50},"location":47}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 013 +SELECT * FROM test_argresult_uint2(100::uint2, -50) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_uint2"}}],"args":[{"TypeCast":{"arg":{"A_Const":{"ival":{"ival":100},"location":35}},"typeName":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"location":40},"location":38}},{"A_Const":{"ival":{"ival":-50},"location":47}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 014 +SELECT * FROM test_argresult_uint2(null, 1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_uint2"}}],"args":[{"A_Const":{"isnull":true,"location":35}},{"A_Const":{"ival":{"ival":1},"location":41}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 015 +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_uint2"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":36},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":43},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"location":56},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v uint2 := x;\nbegin\nv := y;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":62}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":121}}]}}}]} +== 016 +SELECT * FROM test_assign_uint2(100, 50) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_uint2"}}],"args":[{"A_Const":{"ival":{"ival":100},"location":32}},{"A_Const":{"ival":{"ival":50},"location":37}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 017 +SELECT * FROM test_assign_uint2(100, -50) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_uint2"}}],"args":[{"A_Const":{"ival":{"ival":100},"location":32}},{"A_Const":{"ival":{"ival":-50},"location":37}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 018 +SELECT * FROM test_assign_uint2(-100, 50) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_uint2"}}],"args":[{"A_Const":{"ival":{"ival":-100},"location":32}},{"A_Const":{"ival":{"ival":50},"location":38}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 019 +SELECT * FROM test_assign_uint2(null, 1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_uint2"}}],"args":[{"A_Const":{"isnull":true,"location":32}},{"A_Const":{"ival":{"ival":1},"location":38}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 020 +CREATE DOMAIN nnint AS int NOT NULL +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"nnint"}}],"typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":23},"constraints":[{"Constraint":{"contype":"CONSTR_NOTNULL","location":27}}]}}}]} +== 021 +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_nnint"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"nnint"}}],"typemod":-1,"location":39},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":48},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"nnint"}}],"typemod":-1,"location":61},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn y;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":67}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":96}}]}}}]} +== 022 +SELECT * FROM test_argresult_nnint(10, 20) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_nnint"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":35}},{"A_Const":{"ival":{"ival":20},"location":39}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 023 +SELECT * FROM test_argresult_nnint(null, 20) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_nnint"}}],"args":[{"A_Const":{"isnull":true,"location":35}},{"A_Const":{"ival":{"ival":20},"location":41}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 024 +SELECT * FROM test_argresult_nnint(10, null) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_nnint"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":35}},{"A_Const":{"isnull":true,"location":39}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 025 +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_nnint"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":36},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":43},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"nnint"}}],"typemod":-1,"location":56},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v nnint := x;\nbegin\nv := y;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":62}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":121}}]}}}]} +== 026 +SELECT * FROM test_assign_nnint(10, 20) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":32}},{"A_Const":{"ival":{"ival":20},"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 027 +SELECT * FROM test_assign_nnint(null, 20) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint"}}],"args":[{"A_Const":{"isnull":true,"location":32}},{"A_Const":{"ival":{"ival":20},"location":38}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 028 +SELECT * FROM test_assign_nnint(10, null) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":32}},{"A_Const":{"isnull":true,"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 029 +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"ordered_pair_domain"}}],"typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":67},"constraints":[{"Constraint":{"contype":"CONSTR_CHECK","initially_valid":true,"raw_expr":{"BoolExpr":{"boolop":"AND_EXPR","args":[{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"="}}],"lexpr":{"FuncCall":{"funcname":[{"String":{"sval":"array_length"}}],"args":[{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":97}},{"A_Const":{"ival":{"ival":1},"location":103}}],"funcformat":"COERCE_EXPLICIT_CALL","location":84}},"rexpr":{"A_Const":{"ival":{"ival":2},"location":106}},"location":105}},{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"\u003c"}}],"lexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":112}},"indirection":[{"A_Indices":{"uidx":{"A_Const":{"ival":{"ival":1},"location":118}}}}]}},"rexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":123}},"indirection":[{"A_Indices":{"uidx":{"A_Const":{"ival":{"ival":2},"location":129}}}}]}},"location":121}}],"location":108}},"location":77}}]}}}]} +== 030 +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_array_domain"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":46},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":77},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn x;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":97}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":126}}]}}}]} +== 031 +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_array_domain"}}],"args":[{"TypeCast":{"arg":{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{},"location":48}},{"A_Const":{"ival":{"ival":100},"location":51}}],"location":42}},"typeName":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":57},"location":55}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 032 +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_array_domain"}}],"args":[{"TypeCast":{"arg":{"A_Const":{"isnull":true,"location":42}},"typeName":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":48},"location":46}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 033 +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_array_domain_check_violation"}}],"returnType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":72},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn array[2,1];\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":92}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":130}}]}}}]} +== 034 +SELECT * FROM test_argresult_array_domain_check_violation() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_array_domain_check_violation"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 035 +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_ordered_pair_domain"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":50},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":57},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"z","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":64},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":77},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v ordered_pair_domain := array[x, y];\nbegin\nv[2] := z;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":97}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":183}}]}}}]} +== 036 +SELECT * FROM test_assign_ordered_pair_domain(1,2,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_pair_domain"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":46}},{"A_Const":{"ival":{"ival":2},"location":48}},{"A_Const":{"ival":{"ival":3},"location":50}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 037 +SELECT * FROM test_assign_ordered_pair_domain(1,2,0) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_pair_domain"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":46}},{"A_Const":{"ival":{"ival":2},"location":48}},{"A_Const":{"ival":{},"location":50}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 038 +SELECT * FROM test_assign_ordered_pair_domain(2,1,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_pair_domain"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":46}},{"A_Const":{"ival":{"ival":1},"location":48}},{"A_Const":{"ival":{"ival":3},"location":50}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 039 +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_read_uint2_array"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":68},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"location":85},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn x[1];\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":91}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":123}}]}}}]} +== 040 +select test_read_uint2_array(array[1::uint2]) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_read_uint2_array"}}],"args":[{"A_ArrayExpr":{"elements":[{"TypeCast":{"arg":{"A_Const":{"ival":{"ival":1},"location":35}},"typeName":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"location":38},"location":36}}],"location":29}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 041 +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_build_uint2_array"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"int2"}}],"typemod":-1,"location":41},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"uint2"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":55},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn array[x, x];\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":63}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":102}}]}}}]} +== 042 +select test_build_uint2_array(1::int2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_build_uint2_array"}}],"args":[{"TypeCast":{"arg":{"A_Const":{"ival":{"ival":1},"location":30}},"typeName":{"names":[{"String":{"sval":"int2"}}],"typemod":-1,"location":33},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 043 +select test_build_uint2_array(-1::int2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_build_uint2_array"}}],"args":[{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"-"}}],"rexpr":{"TypeCast":{"arg":{"A_Const":{"ival":{"ival":1},"location":31}},"typeName":{"names":[{"String":{"sval":"int2"}}],"typemod":-1,"location":34},"location":32}},"location":30}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 044 +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_domain_array"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":55},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":76},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn array[x::ordered_pair_domain, x::ordered_pair_domain];\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":98}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":179}}]}}}]} +== 045 +select test_argresult_domain_array(array[2,4]) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_domain_array"}}],"args":[{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{"ival":2},"location":41}},{"A_Const":{"ival":{"ival":4},"location":43}}],"location":35}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 046 +select test_argresult_domain_array(array[4,2]) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_domain_array"}}],"args":[{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{"ival":4},"location":41}},{"A_Const":{"ival":{"ival":2},"location":43}}],"location":35}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 047 +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_domain_array2"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":56},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":87},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn x[1];\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":95}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":127}}]}}}]} +== 048 +select test_argresult_domain_array2(array[2,4]) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_domain_array2"}}],"args":[{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{"ival":2},"location":42}},{"A_Const":{"ival":{"ival":4},"location":44}}],"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 049 +select test_argresult_domain_array2(array[4,2]) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_domain_array2"}}],"args":[{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{"ival":4},"location":42}},{"A_Const":{"ival":{"ival":2},"location":44}}],"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 050 +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_argresult_array_domain_array"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":61},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":94},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn x[1];\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":114}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":146}}]}}}]} +== 051 +select test_argresult_array_domain_array(array[array[2,4]::ordered_pair_domain]) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_argresult_array_domain_array"}}],"args":[{"A_ArrayExpr":{"elements":[{"TypeCast":{"arg":{"A_ArrayExpr":{"elements":[{"A_Const":{"ival":{"ival":2},"location":53}},{"A_Const":{"ival":{"ival":4},"location":55}}],"location":47}},"typeName":{"names":[{"String":{"sval":"ordered_pair_domain"}}],"typemod":-1,"location":59},"location":57}}],"location":41}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 052 +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"nnint_container","relpersistence":"p","location":47},"coldeflist":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":70},"is_local":true,"location":67}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"nnint"}}],"typemod":-1,"location":78},"is_local":true,"location":75}}]}}}]} +== 053 +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_result_nnint_container"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":53},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"nnint_container"}}],"typemod":-1,"location":68},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn row(x, y)::nnint_container;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":84}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":138}}]}}}]} +== 054 +SELECT test_result_nnint_container(null, 3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_result_nnint_container"}}],"args":[{"A_Const":{"isnull":true,"location":35}},{"A_Const":{"ival":{"ival":3},"location":41}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 055 +SELECT test_result_nnint_container(3, null) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_result_nnint_container"}}],"args":[{"A_Const":{"ival":{"ival":3},"location":35}},{"A_Const":{"isnull":true,"location":38}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 056 +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_nnint_container"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":55},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":62},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"z","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":69},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"nnint_container"}}],"typemod":-1,"location":84},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v nnint_container := row(x, y);\nbegin\nv.f2 := z;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":100}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":180}}]}}}]} +== 057 +SELECT * FROM test_assign_nnint_container(1,2,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint_container"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":42}},{"A_Const":{"ival":{"ival":2},"location":44}},{"A_Const":{"ival":{"ival":3},"location":46}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 058 +SELECT * FROM test_assign_nnint_container(1,2,null) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint_container"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":42}},{"A_Const":{"ival":{"ival":2},"location":44}},{"A_Const":{"isnull":true,"location":46}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 059 +SELECT * FROM test_assign_nnint_container(1,null,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint_container"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":42}},{"A_Const":{"isnull":true,"location":44}},{"A_Const":{"ival":{"ival":3},"location":49}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 060 +-- Since core system allows this: +SELECT null::nnint_container +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"TypeCast":{"arg":{"A_Const":{"isnull":true,"location":41}},"typeName":{"names":[{"String":{"sval":"nnint_container"}}],"typemod":-1,"location":47},"location":45}},"location":41}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 061 +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_nnint_container2"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":70},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":77},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"z","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":84},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"nnint_container"}}],"typemod":-1,"location":99},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v nnint_container;\nbegin\nv.f2 := z;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":115}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":182}}]}}}]} +== 062 +SELECT * FROM test_assign_nnint_container2(1,2,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint_container2"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":43}},{"A_Const":{"ival":{"ival":2},"location":45}},{"A_Const":{"ival":{"ival":3},"location":47}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 063 +SELECT * FROM test_assign_nnint_container2(1,2,null) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_nnint_container2"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":43}},{"A_Const":{"ival":{"ival":2},"location":45}},{"A_Const":{"isnull":true,"location":47}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 064 +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"named_pair","relpersistence":"p","location":43},"coldeflist":[{"ColumnDef":{"colname":"i","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":65},"is_local":true,"location":63}},{"ColumnDef":{"colname":"j","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":80},"is_local":true,"location":78}}]}}}]} +== 065 +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"ordered_named_pair"}}],"typeName":{"names":[{"String":{"sval":"named_pair"}}],"typemod":-1,"location":36},"constraints":[{"Constraint":{"contype":"CONSTR_CHECK","initially_valid":true,"raw_expr":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"\u003c="}}],"lexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":54}},"indirection":[{"String":{"sval":"i"}}]}},"rexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":67}},"indirection":[{"String":{"sval":"j"}}]}},"location":63}},"location":47}}]}}}]} +== 066 +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"read_ordered_named_pair"}}],"parameters":[{"FunctionParameter":{"name":"p","argType":{"names":[{"String":{"sval":"ordered_named_pair"}}],"typemod":-1,"location":42},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":70},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn p.i + p.j;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":78}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":115}}]}}}]} +== 067 +SELECT read_ordered_named_pair(row(1, 2)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"read_ordered_named_pair"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":35}},{"A_Const":{"ival":{"ival":2},"location":38}}],"row_format":"COERCE_EXPLICIT_CALL","location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 068 +SELECT read_ordered_named_pair(row(2, 1)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"read_ordered_named_pair"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":2},"location":35}},{"A_Const":{"ival":{"ival":1},"location":38}}],"row_format":"COERCE_EXPLICIT_CALL","location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 069 +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"build_ordered_named_pair"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":52},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"j","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":59},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_named_pair"}}],"typemod":-1,"location":72},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn row(i, j);\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":91}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":128}}]}}}]} +== 070 +SELECT build_ordered_named_pair(1,2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_named_pair"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":32}},{"A_Const":{"ival":{"ival":2},"location":34}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 071 +SELECT build_ordered_named_pair(2,1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_named_pair"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":32}},{"A_Const":{"ival":{"ival":1},"location":34}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 072 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pair"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":58},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":65},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"z","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":72},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_named_pair"}}],"typemod":-1,"location":87},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v ordered_named_pair := row(x, y);\nbegin\nv.j := z;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":106}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":188}}]}}}]} +== 073 +SELECT * FROM test_assign_ordered_named_pair(1,2,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pair"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":45}},{"A_Const":{"ival":{"ival":2},"location":47}},{"A_Const":{"ival":{"ival":3},"location":49}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 074 +SELECT * FROM test_assign_ordered_named_pair(1,2,0) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pair"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":45}},{"A_Const":{"ival":{"ival":2},"location":47}},{"A_Const":{"ival":{},"location":49}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 075 +SELECT * FROM test_assign_ordered_named_pair(2,1,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pair"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":45}},{"A_Const":{"ival":{"ival":1},"location":47}},{"A_Const":{"ival":{"ival":3},"location":49}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 076 +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"build_ordered_named_pairs"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":44},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"j","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":51},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_named_pair"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":64},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\nreturn array[row(i, j), row(i, j+1)];\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":85}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":142}}]}}}]} +== 077 +SELECT build_ordered_named_pairs(1,2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_named_pairs"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":33}},{"A_Const":{"ival":{"ival":2},"location":35}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 078 +SELECT build_ordered_named_pairs(2,1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_named_pairs"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":33}},{"A_Const":{"ival":{"ival":1},"location":35}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 079 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pairs"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":59},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":66},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"z","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":73},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_named_pair"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":88},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare v ordered_named_pair[] := array[row(x, y)];\nbegin\n-- ideally this would work, but it doesn't yet:\n-- v[1].j := z;\nreturn v;\nend\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":109}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":254}}]}}}]} +== 080 +SELECT * FROM test_assign_ordered_named_pairs(1,2,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pairs"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":46}},{"A_Const":{"ival":{"ival":2},"location":48}},{"A_Const":{"ival":{"ival":3},"location":50}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 081 +SELECT * FROM test_assign_ordered_named_pairs(2,1,3) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pairs"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":46}},{"A_Const":{"ival":{"ival":1},"location":48}},{"A_Const":{"ival":{"ival":3},"location":50}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 082 +SELECT * FROM test_assign_ordered_named_pairs(1,2,0) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"test_assign_ordered_named_pairs"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":46}},{"A_Const":{"ival":{"ival":2},"location":48}},{"A_Const":{"ival":{},"location":50}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_misc.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_misc.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_misc.test b/parser/testdata/parse/plpgsql_regress/plpgsql_misc.test new file mode 100644 index 0000000..f6b8829 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_misc.test @@ -0,0 +1,77 @@ +== 001 +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\n declare procedure int; -- check we still recognize non-keywords as vars\n begin\n create function test1() returns int\n begin atomic\n select 2 + 2;\n end;\n create or replace procedure test2(x int)\n begin atomic\n select x + 2;\n end;\n end\n"}},"defaction":"DEFELEM_UNSPEC","location":98}}]}}}]} +== 002 +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"misc_table","inh":true,"relpersistence":"p","location":52},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":66},"is_local":true,"location":63}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 003 +do $$ declare x foo%type; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x foo%type; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 004 +do $$ declare x notice%type; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x notice%type; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 005 +-- covers unreserved-keyword case +do $$ declare x foo.bar%type; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x foo.bar%type; begin end "}},"defaction":"DEFELEM_UNSPEC","location":37}}]}}}]} +== 006 +do $$ declare x foo.bar.baz%type; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x foo.bar.baz%type; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 007 +do $$ declare x public.foo.bar%type; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x public.foo.bar%type; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 008 +do $$ declare x public.misc_table.zed%type; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x public.misc_table.zed%type; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 009 +do $$ declare x foo%rowtype; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x foo%rowtype; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 010 +do $$ declare x notice%rowtype; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x notice%rowtype; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 011 +-- covers unreserved-keyword case +do $$ declare x foo.bar%rowtype; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x foo.bar%rowtype; begin end "}},"defaction":"DEFELEM_UNSPEC","location":37}}]}}}]} +== 012 +do $$ declare x foo.bar.baz%rowtype; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x foo.bar.baz%rowtype; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 013 +do $$ declare x public.foo%rowtype; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x public.foo%rowtype; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 014 +do $$ declare x public.misc_table%rowtype; begin end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare x public.misc_table%rowtype; begin end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_record.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_record.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_record.test b/parser/testdata/parse/plpgsql_regress/plpgsql_record.test new file mode 100644 index 0000000..25a35f0 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_record.test @@ -0,0 +1,990 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"two_int4s","relpersistence":"p","location":82},"coldeflist":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"int4"}}],"typemod":-1,"location":99},"is_local":true,"location":96}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"int4"}}],"typemod":-1,"location":108},"is_local":true,"location":105}}]}}}]} +== 002 +create type more_int4s as (f0 text, f1 int4, f2 int4) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"more_int4s","relpersistence":"p","location":12},"coldeflist":[{"ColumnDef":{"colname":"f0","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":30},"is_local":true,"location":27}},{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":36}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"int4"}}],"typemod":-1,"location":48},"is_local":true,"location":45}}]}}}]} +== 003 +create type two_int8s as (q1 int8, q2 int8) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"two_int8s","relpersistence":"p","location":12},"coldeflist":[{"ColumnDef":{"colname":"q1","typeName":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":29},"is_local":true,"location":26}},{"ColumnDef":{"colname":"q2","typeName":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":38},"is_local":true,"location":35}}]}}}]} +== 004 +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"nested_int8s","relpersistence":"p","location":12},"coldeflist":[{"ColumnDef":{"colname":"c1","typeName":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":32},"is_local":true,"location":29}},{"ColumnDef":{"colname":"c2","typeName":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":46},"is_local":true,"location":43}}]}}}]} +== 005 +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1)::two_int8s; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":61},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":74},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":84}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return row($1,1)::two_int8s; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":101}}]}}}]} +== 006 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 007 +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8); end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":71},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":84},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":94}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return row($1::int8, 1::int8); end "}}]}},"defaction":"DEFELEM_UNSPEC","location":111}}]}}}]} +== 008 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 009 +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1); end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":79},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":92},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":102}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return row($1,1); end "}}]}},"defaction":"DEFELEM_UNSPEC","location":119}}]}}}]} +== 010 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 011 +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8, 42); end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":53},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":66},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":76}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return row($1::int8, 1::int8, 42); end "}}]}},"defaction":"DEFELEM_UNSPEC","location":93}}]}}}]} +== 012 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 013 +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":85},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":98},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":108}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r record; begin r := row($1::int8, 1::int8); return r; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":125}}]}}}]} +== 014 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 015 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,1); return r; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":32},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":45},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":55}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r record; begin r := row($1,1); return r; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":72}}]}}}]} +== 016 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 017 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":32},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":45},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":55}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r record; begin r := row($1::int8, 1::int8, 42); return r; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":72}}]}}}]} +== 018 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 019 +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"retc"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":138},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":151},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":161}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":178}}]}}}]} +== 020 +select retc(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":12}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 021 +do $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c two_int8s;\nbegin c := row(1,2); raise notice 'c = %', c; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 022 +do $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c two_int8s;\nbegin for c in select 1,2 loop raise notice 'c = %', c; end loop; end"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 023 +do $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c4 two_int4s; c8 two_int8s;\nbegin\n c8 := row(1,2);\n c4 := c8;\n c8 := c4;\n raise notice 'c4 = %', c4;\n raise notice 'c8 = %', c8;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 024 +do $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c two_int8s; d nested_int8s;\nbegin\n c := row(1,2);\n d := row(c, row(c.q1, c.q2+1));\n raise notice 'c = %, d = %', c, d;\n c.q1 := 10;\n d.c1 := row(11,12);\n d.c2.q2 := 42;\n raise notice 'c = %, d = %', c, d;\n raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2;\n raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens\n raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 025 +-- block-qualified naming +do $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" \u003c\u003cb\u003e\u003e declare c two_int8s; d nested_int8s;\nbegin\n b.c := row(1,2);\n b.d := row(b.c, row(b.c.q1, b.c.q2+1));\n raise notice 'b.c = %, b.d = %', b.c, b.d;\n b.c.q1 := 10;\n b.d.c1 := row(11,12);\n b.d.c2.q2 := 42;\n raise notice 'b.c = %, b.d = %', b.c, b.d;\n raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2;\n raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens\n raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens\nend"}},"defaction":"DEFELEM_UNSPEC","location":29}}]}}}]} +== 026 +-- error cases +do $$ declare c two_int8s; begin c.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c two_int8s; begin c.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":18}}]}}}]} +== 027 +do $$ declare c nested_int8s; begin c.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c nested_int8s; begin c.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 028 +do $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c nested_int8s; begin c.x.q1 = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 029 +do $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c nested_int8s; begin c.c2.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 030 +do $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" declare c nested_int8s; begin d.c2.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 031 +do $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" \u003c\u003cb\u003e\u003e declare c two_int8s; begin b.c.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 032 +do $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" \u003c\u003cb\u003e\u003e declare c nested_int8s; begin b.c.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 033 +do $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" \u003c\u003cb\u003e\u003e declare c nested_int8s; begin b.c.x.q1 = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 034 +do $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" \u003c\u003cb\u003e\u003e declare c nested_int8s; begin b.c.c2.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 035 +do $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":" \u003c\u003cb\u003e\u003e declare c nested_int8s; begin b.d.c2.x = 1; end "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 036 +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"getq1"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":76},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":95},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":100}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare r two_int8s; begin r := $1; return r.q1; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":117}}]}}}]} +== 037 +select getq1(retc(344)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getq1"}}],"args":[{"FuncCall":{"funcname":[{"String":{"sval":"retc"}}],"args":[{"A_Const":{"ival":{"ival":344},"location":18}}],"funcformat":"COERCE_EXPLICIT_CALL","location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 038 +select getq1(row(1,2)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getq1"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":17}},{"A_Const":{"ival":{"ival":2},"location":19}}],"row_format":"COERCE_EXPLICIT_CALL","location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 039 +do $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 two_int8s; r2 record; x int8;\nbegin\n r1 := retc(345);\n perform getq1(r1);\n x := getq1(r1);\n raise notice 'x = %', x;\n r2 := retc(346);\n perform getq1(r2);\n x := getq1(r2);\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 040 +-- check assignments of composites +do $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 two_int8s; r2 two_int8s; r3 record; r4 record;\nbegin\n r1 := row(1,2);\n raise notice 'r1 = %', r1;\n r1 := r1; -- shouldn't do anything\n raise notice 'r1 = %', r1;\n r2 := r1;\n raise notice 'r1 = %', r1;\n raise notice 'r2 = %', r2;\n r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage\n raise notice 'r1 = %', r1;\n raise notice 'r2 = %', r2;\n r1 := null;\n raise notice 'r1 = %', r1;\n raise notice 'r2 = %', r2;\n r1 := row(7,11)::two_int8s;\n r2 := r1;\n raise notice 'r1 = %', r1;\n raise notice 'r2 = %', r2;\n r3 := row(1,2);\n r4 := r3;\n raise notice 'r3 = %', r3;\n raise notice 'r4 = %', r4;\n r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage\n raise notice 'r3 = %', r3;\n raise notice 'r4 = %', r4;\n r1 := r3;\n raise notice 'r1 = %', r1;\n r4 := r1;\n raise notice 'r4 = %', r4;\n r4.q2 := r4.q2 + 1; -- r4's field names have changed\n raise notice 'r4 = %', r4;\nend"}},"defaction":"DEFELEM_UNSPEC","location":38}}]}}}]} +== 041 +-- fields of named-type vars read as null if uninitialized +do $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 two_int8s;\nbegin\n raise notice 'r1 = %', r1;\n raise notice 'r1.q1 = %', r1.q1;\n raise notice 'r1.q2 = %', r1.q2;\n raise notice 'r1 = %', r1;\nend"}},"defaction":"DEFELEM_UNSPEC","location":62}}]}}}]} +== 042 +do $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 two_int8s;\nbegin\n raise notice 'r1.q1 = %', r1.q1;\n raise notice 'r1.q2 = %', r1.q2;\n raise notice 'r1 = %', r1;\n raise notice 'r1.nosuchfield = %', r1.nosuchfield;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 043 +-- records, not so much +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 record;\nbegin\n raise notice 'r1 = %', r1;\n raise notice 'r1.f1 = %', r1.f1;\n raise notice 'r1.f2 = %', r1.f2;\n raise notice 'r1 = %', r1;\nend"}},"defaction":"DEFELEM_UNSPEC","location":27}}]}}}]} +== 044 +-- but OK if you assign first +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 record;\nbegin\n raise notice 'r1 = %', r1;\n r1 := row(1,2);\n raise notice 'r1.f1 = %', r1.f1;\n raise notice 'r1.f2 = %', r1.f2;\n raise notice 'r1 = %', r1;\n raise notice 'r1.nosuchfield = %', r1.nosuchfield;\nend"}},"defaction":"DEFELEM_UNSPEC","location":33}}]}}}]} +== 045 +-- check %type with block-qualified variable names +do $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\n\u003c\u003cblk\u003e\u003e\ndeclare\n v int;\n r two_int8s;\n v1 v%type;\n v2 blk.v%type;\n r1 r%type;\n r2 blk.r%type;\nbegin\n raise notice '%', pg_typeof(v1);\n raise notice '%', pg_typeof(v2);\n raise notice '%', pg_typeof(r1);\n raise notice '%', pg_typeof(r2);\nend"}},"defaction":"DEFELEM_UNSPEC","location":54}}]}}}]} +== 046 +-- check that type record can be passed through %type +do $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 record;\n r2 r1%type;\nbegin\n r2 := row(1,2);\n raise notice 'r2 = %', r2;\n r2 := row(3,4,5);\n raise notice 'r2 = %', r2;\nend"}},"defaction":"DEFELEM_UNSPEC","location":57}}]}}}]} +== 047 +-- arrays of record are not supported at the moment +do $$ +declare r1 record[]; +begin +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 record[];\nbegin\nend"}},"defaction":"DEFELEM_UNSPEC","location":55}}]}}}]} +== 048 +do $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r1 record;\n r2 r1%type[];\nbegin\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 049 +-- check repeated assignments to composite fields +create table some_table (id int, data text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"some_table","inh":true,"relpersistence":"p","location":63},"tableElts":[{"ColumnDef":{"colname":"id","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":78},"is_local":true,"location":75}},{"ColumnDef":{"colname":"data","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":88},"is_local":true,"location":83}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 050 +do $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r some_table;\nbegin\n r := (23, 'skidoo');\n for i in 1 .. 10 loop\n r.id := r.id + i;\n r.data := r.data || ' ' || i;\n end loop;\n raise notice 'r = %', r;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 051 +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1); end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"returnsrecord"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":89},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"record"}}],"typemod":-1,"location":102},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":109}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return row($1,$1+1); end "}}]}},"defaction":"DEFELEM_UNSPEC","location":126}}]}}}]} +== 052 +select returnsrecord(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 053 +select * from returnsrecord(42) as r(x int, y int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 054 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}},{"ColumnDef":{"colname":"z","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":53},"is_local":true,"location":51}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 055 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":15}},"location":15}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":22}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":47},"is_local":true,"location":45}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int8"}}],"typemod":-1,"location":54},"is_local":true,"location":52}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 056 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1); return r; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"returnsrecord"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":95},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"record"}}],"typemod":-1,"location":108},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":115}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r record; begin r := row($1,$1+1); return r; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":132}}]}}}]} +== 057 +select returnsrecord(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 058 +select * from returnsrecord(42) as r(x int, y int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 059 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}},{"ColumnDef":{"colname":"z","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":53},"is_local":true,"location":51}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 060 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":15}},"location":15}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":22}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":47},"is_local":true,"location":45}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int8"}}],"typemod":-1,"location":54},"is_local":true,"location":52}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 061 +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"has_hole","inh":true,"relpersistence":"p","location":95},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":107},"is_local":true,"location":104}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":115},"is_local":true,"location":112}},{"ColumnDef":{"colname":"f3","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":123},"is_local":true,"location":120}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 062 +alter table has_hole drop column f2 +-- +{"version":170007,"stmts":[{"stmt":{"AlterTableStmt":{"relation":{"relname":"has_hole","inh":true,"relpersistence":"p","location":12},"cmds":[{"AlterTableCmd":{"subtype":"AT_DropColumn","name":"f2","behavior":"DROP_RESTRICT"}}],"objtype":"OBJECT_TABLE"}}}]} +== 063 +create or replace function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1)::has_hole; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"returnsrecord"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":41},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"record"}}],"typemod":-1,"location":54},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":61}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return row($1,$1+1)::has_hole; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":78}}]}}}]} +== 064 +select returnsrecord(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 065 +select * from returnsrecord(42) as r(x int, y int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 066 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}},{"ColumnDef":{"colname":"z","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":53},"is_local":true,"location":51}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 067 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":15}},"location":15}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":22}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":47},"is_local":true,"location":45}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int8"}}],"typemod":-1,"location":54},"is_local":true,"location":52}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 068 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"returnsrecord"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":95},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"record"}}],"typemod":-1,"location":108},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":115}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r record; begin r := row($1,$1+1)::has_hole; return r; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":132}}]}}}]} +== 069 +select returnsrecord(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 070 +select * from returnsrecord(42) as r(x int, y int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 071 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":28}}],"funcformat":"COERCE_EXPLICIT_CALL","location":14}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"is_local":true,"location":37}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":46},"is_local":true,"location":44}},{"ColumnDef":{"colname":"z","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":53},"is_local":true,"location":51}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 072 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":15}},"location":15}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"returnsrecord"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":36}}],"funcformat":"COERCE_EXPLICIT_CALL","location":22}},{}]}}],"alias":{"aliasname":"r"},"coldeflist":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":47},"is_local":true,"location":45}},{"ColumnDef":{"colname":"y","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int8"}}],"typemod":-1,"location":54},"is_local":true,"location":52}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 073 +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$$ begin return x.f1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"getf1"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"record"}}],"typemod":-1,"location":93},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":109},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":113}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return x.f1; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":130}}]}}}]} +== 074 +select getf1(1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf1"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 075 +select getf1(row(1,2)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf1"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":17}},{"A_Const":{"ival":{"ival":2},"location":19}}],"row_format":"COERCE_EXPLICIT_CALL","location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 076 +select getf1(row(1,2)::two_int4s) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf1"}}],"args":[{"TypeCast":{"arg":{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":17}},{"A_Const":{"ival":{"ival":2},"location":19}}],"row_format":"COERCE_EXPLICIT_CALL","location":13}},"typeName":{"names":[{"String":{"sval":"two_int4s"}}],"typemod":-1,"location":23},"location":21}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 077 +select getf1(row('foo',123,456)::more_int4s) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf1"}}],"args":[{"TypeCast":{"arg":{"RowExpr":{"args":[{"A_Const":{"sval":{"sval":"foo"},"location":17}},{"A_Const":{"ival":{"ival":123},"location":23}},{"A_Const":{"ival":{"ival":456},"location":27}}],"row_format":"COERCE_EXPLICIT_CALL","location":13}},"typeName":{"names":[{"String":{"sval":"more_int4s"}}],"typemod":-1,"location":33},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 078 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row(1,2)::two_int8s) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf1"}}],"args":[{"TypeCast":{"arg":{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":115}},{"A_Const":{"ival":{"ival":2},"location":117}}],"row_format":"COERCE_EXPLICIT_CALL","location":111}},"typeName":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":121},"location":119}}],"funcformat":"COERCE_EXPLICIT_CALL","location":105}},"location":105}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 079 +select getf1(row(1,2)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf1"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":17}},{"A_Const":{"ival":{"ival":2},"location":19}}],"row_format":"COERCE_EXPLICIT_CALL","location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 080 +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$$ begin return $1.f2; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"getf2"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"record"}}],"typemod":-1,"location":149},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":165},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":169}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return $1.f2; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":186}}]}}}]} +== 081 +select getf2(row(1,2)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf2"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":17}},{"A_Const":{"ival":{"ival":2},"location":19}}],"row_format":"COERCE_EXPLICIT_CALL","location":13}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 082 +-- ideally would work, but does not +select getf2(row(1,2)::two_int4s) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf2"}}],"args":[{"TypeCast":{"arg":{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":53}},{"A_Const":{"ival":{"ival":2},"location":55}}],"row_format":"COERCE_EXPLICIT_CALL","location":49}},"typeName":{"names":[{"String":{"sval":"two_int4s"}}],"typemod":-1,"location":59},"location":57}}],"funcformat":"COERCE_EXPLICIT_CALL","location":43}},"location":43}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 083 +select getf2(row('foo',123,456)::more_int4s) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf2"}}],"args":[{"TypeCast":{"arg":{"RowExpr":{"args":[{"A_Const":{"sval":{"sval":"foo"},"location":17}},{"A_Const":{"ival":{"ival":123},"location":23}},{"A_Const":{"ival":{"ival":456},"location":27}}],"row_format":"COERCE_EXPLICIT_CALL","location":13}},"typeName":{"names":[{"String":{"sval":"more_int4s"}}],"typemod":-1,"location":33},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 084 +-- check behavior when assignment to FOR-loop variable requires coercion +do $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r two_int8s;\nbegin\n for r in select i, i+1 from generate_series(1,4) i\n loop\n raise notice 'r = %', r;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":76}}]}}}]} +== 085 +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"returnssetofholes"}}],"returnType":{"names":[{"String":{"sval":"has_hole"}}],"setof":true,"typemod":-1,"location":99},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":108}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare r record;\n h has_hole;\nbegin\n return next h;\n r := (1,2);\n h := (3,4);\n return next r;\n return next h;\n return next row(5,6);\n return next row(7,8)::has_hole;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":125}}]}}}]} +== 086 +select returnssetofholes() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"returnssetofholes"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 087 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"returnssetofholes"}}],"returnType":{"names":[{"String":{"sval":"has_hole"}}],"setof":true,"typemod":-1,"location":61},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":70}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare r record;\nbegin\n return next r; -- fails, not assigned yet\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":87}}]}}}]} +== 088 +select returnssetofholes() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"returnssetofholes"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 089 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +begin + return next row(1,2,3); -- fails +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"returnssetofholes"}}],"returnType":{"names":[{"String":{"sval":"has_hole"}}],"setof":true,"typemod":-1,"location":61},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":70}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n return next row(1,2,3); -- fails\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":87}}]}}}]} +== 090 +select returnssetofholes() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"returnssetofholes"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 091 +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":63},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":74},"is_local":true,"location":71}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":82},"is_local":true,"location":79}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 092 +create function sillyaddone(int) returns int language plpgsql as +$$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"sillyaddone"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":28},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":41},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":45}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r mutable; begin r.f1 := $1; return r.f1 + 1; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":62}}]}}}]} +== 093 +select sillyaddone(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"sillyaddone"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":19}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 094 +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +-- +{"version":170007,"stmts":[{"stmt":{"AlterTableStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":111},"cmds":[{"AlterTableCmd":{"subtype":"AT_DropColumn","name":"f1","behavior":"DROP_RESTRICT"}}],"objtype":"OBJECT_TABLE"}}}]} +== 095 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"sillyaddone"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":117}}],"funcformat":"COERCE_EXPLICIT_CALL","location":105}},"location":105}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 096 +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$$ begin return x.f3; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"getf3"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"mutable"}}],"typemod":-1,"location":33},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":50},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":54}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" begin return x.f3; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":71}}]}}}]} +== 097 +select getf3(null::mutable) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf3"}}],"args":[{"TypeCast":{"arg":{"A_Const":{"isnull":true,"location":13}},"typeName":{"names":[{"String":{"sval":"mutable"}}],"typemod":-1,"location":19},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 098 +-- doesn't work yet +alter table mutable add column f3 int +-- +{"version":170007,"stmts":[{"stmt":{"AlterTableStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":32},"cmds":[{"AlterTableCmd":{"subtype":"AT_AddColumn","def":{"ColumnDef":{"colname":"f3","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":54},"is_local":true,"location":51}},"behavior":"DROP_RESTRICT"}}],"objtype":"OBJECT_TABLE"}}}]} +== 099 +select getf3(null::mutable) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf3"}}],"args":[{"TypeCast":{"arg":{"A_Const":{"isnull":true,"location":13}},"typeName":{"names":[{"String":{"sval":"mutable"}}],"typemod":-1,"location":19},"location":17}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 100 +-- now it works +alter table mutable drop column f3 +-- +{"version":170007,"stmts":[{"stmt":{"AlterTableStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":28},"cmds":[{"AlterTableCmd":{"subtype":"AT_DropColumn","name":"f3","behavior":"DROP_RESTRICT"}}],"objtype":"OBJECT_TABLE"}}}]} +== 101 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3(null::mutable) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"getf3"}}],"args":[{"TypeCast":{"arg":{"A_Const":{"isnull":true,"location":111}},"typeName":{"names":[{"String":{"sval":"mutable"}}],"typemod":-1,"location":117},"location":115}}],"funcformat":"COERCE_EXPLICIT_CALL","location":105}},"location":105}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 102 +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off +-- +{"version":170007,"stmts":[{"stmt":{"VariableSetStmt":{"kind":"VAR_SET_VALUE","name":"check_function_bodies","args":[{"A_Const":{"sval":{"sval":"off"},"location":101}}]}}}]} +== 103 +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"sillyaddtwo"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":73},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":86},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":90}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":107}}]}}}]} +== 104 +reset check_function_bodies +-- +{"version":170007,"stmts":[{"stmt":{"VariableSetStmt":{"kind":"VAR_RESET","name":"check_function_bodies"}}}]} +== 105 +select sillyaddtwo(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"sillyaddtwo"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":19}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 106 +-- fail +create table mutable2(f1 int, f2 text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"mutable2","inh":true,"relpersistence":"p","location":21},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":33},"is_local":true,"location":30}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":41},"is_local":true,"location":38}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 107 +select sillyaddtwo(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"sillyaddtwo"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":19}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 108 +drop table mutable2 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"List":{"items":[{"String":{"sval":"mutable2"}}]}}],"removeType":"OBJECT_TABLE","behavior":"DROP_RESTRICT"}}}]} +== 109 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"sillyaddtwo"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":117}}],"funcformat":"COERCE_EXPLICIT_CALL","location":105}},"location":105}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 110 +-- fail +create table mutable2(f0 text, f1 int, f2 text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"mutable2","inh":true,"relpersistence":"p","location":21},"tableElts":[{"ColumnDef":{"colname":"f0","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":33},"is_local":true,"location":30}},{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":42},"is_local":true,"location":39}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":50},"is_local":true,"location":47}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 111 +select sillyaddtwo(42) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"sillyaddtwo"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":19}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 112 +select sillyaddtwo(43) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"sillyaddtwo"}}],"args":[{"A_Const":{"ival":{"ival":43},"location":19}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 113 +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"sillytrig"}}],"returnType":{"names":[{"String":{"sval":"trigger"}}],"typemod":-1,"location":92},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":100}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"begin\n raise notice 'old.ctid = %', old.ctid;\n raise notice 'old.tableoid = %', old.tableoid::regclass;\n return new;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":117}}]}}}]} +== 114 +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +-- +{"version":170007,"stmts":[{"stmt":{"CreateTrigStmt":{"trigname":"mutable_trig","relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":45},"funcname":[{"String":{"sval":"sillytrig"}}],"row":true,"timing":2,"events":16}}}]} +== 115 +insert into mutable values ('foo'), ('bar') +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"sval":{"sval":"foo"},"location":28}}]}},{"List":{"items":[{"A_Const":{"sval":{"sval":"bar"},"location":37}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 116 +update mutable set f2 = f2 || ' baz' +-- +{"version":170007,"stmts":[{"stmt":{"UpdateStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":7},"targetList":[{"ResTarget":{"name":"f2","val":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"||"}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"f2"}}],"location":24}},"rexpr":{"A_Const":{"sval":{"sval":" baz"},"location":30}},"location":27}},"location":19}}]}}}]} +== 117 +table mutable +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":-1}},"location":-1}}],"fromClause":[{"RangeVar":{"relname":"mutable","inh":true,"relpersistence":"p","location":6}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 118 +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$$begin + return row(new.*); +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"sillytrig"}}],"returnType":{"names":[{"String":{"sval":"trigger"}}],"typemod":-1,"location":100},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":108}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"begin\n return row(new.*);\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":125}}]}}}]} +== 119 +update mutable set f2 = f2 || ' baz' +-- +{"version":170007,"stmts":[{"stmt":{"UpdateStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":7},"targetList":[{"ResTarget":{"name":"f2","val":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"||"}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"f2"}}],"location":24}},"rexpr":{"A_Const":{"sval":{"sval":" baz"},"location":30}},"location":27}},"location":19}}]}}}]} +== 120 +table mutable +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":-1}},"location":-1}}],"fromClause":[{"RangeVar":{"relname":"mutable","inh":true,"relpersistence":"p","location":6}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 121 +create or replace function sillytrig() returns trigger language plpgsql as +$$declare r record; +begin + r := row(new.*); + return r; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"sillytrig"}}],"returnType":{"names":[{"String":{"sval":"trigger"}}],"typemod":-1,"location":47},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":55}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"declare r record;\nbegin\n r := row(new.*);\n return r;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":72}}]}}}]} +== 122 +update mutable set f2 = f2 || ' baz' +-- +{"version":170007,"stmts":[{"stmt":{"UpdateStmt":{"relation":{"relname":"mutable","inh":true,"relpersistence":"p","location":7},"targetList":[{"ResTarget":{"name":"f2","val":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"||"}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"f2"}}],"location":24}},"rexpr":{"A_Const":{"sval":{"sval":" baz"},"location":30}},"location":27}},"location":19}}]}}}]} +== 123 +table mutable +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":-1}},"location":-1}}],"fromClause":[{"RangeVar":{"relname":"mutable","inh":true,"relpersistence":"p","location":6}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 124 +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"ordered_int8s"}}],"typeName":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":62},"constraints":[{"Constraint":{"contype":"CONSTR_CHECK","initially_valid":true,"raw_expr":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"\u003c="}}],"lexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":79}},"indirection":[{"String":{"sval":"q1"}}]}},"rexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":93}},"indirection":[{"String":{"sval":"q2"}}]}},"location":89}},"location":72}}]}}}]} +== 125 +create function read_ordered_int8s(p ordered_int8s) returns int8 as $$ +begin return p.q1 + p.q2; end +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"read_ordered_int8s"}}],"parameters":[{"FunctionParameter":{"name":"p","argType":{"names":[{"String":{"sval":"ordered_int8s"}}],"typemod":-1,"location":37},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":60},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin return p.q1 + p.q2; end\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":65}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":104}}]}}}]} +== 126 +select read_ordered_int8s(row(1, 2)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"read_ordered_int8s"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":1},"location":30}},{"A_Const":{"ival":{"ival":2},"location":33}}],"row_format":"COERCE_EXPLICIT_CALL","location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 127 +select read_ordered_int8s(row(2, 1)) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"read_ordered_int8s"}}],"args":[{"RowExpr":{"args":[{"A_Const":{"ival":{"ival":2},"location":30}},{"A_Const":{"ival":{"ival":1},"location":33}}],"row_format":"COERCE_EXPLICIT_CALL","location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 128 +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $$ +begin return row(i,j); end +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"build_ordered_int8s"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":47},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"j","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":55},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_int8s"}}],"typemod":-1,"location":69},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin return row(i,j); end\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":83}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":119}}]}}}]} +== 129 +select build_ordered_int8s(1,2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":27}},{"A_Const":{"ival":{"ival":2},"location":29}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 130 +select build_ordered_int8s(2,1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":27}},{"A_Const":{"ival":{"ival":1},"location":29}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 131 +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $$ +declare r record; begin r := row(i,j); return r; end +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"build_ordered_int8s_2"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":49},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"j","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":57},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_int8s"}}],"typemod":-1,"location":71},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare r record; begin r := row(i,j); return r; end\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":85}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":147}}]}}}]} +== 132 +select build_ordered_int8s_2(1,2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_2"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":29}},{"A_Const":{"ival":{"ival":2},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 133 +select build_ordered_int8s_2(2,1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_2"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":29}},{"A_Const":{"ival":{"ival":1},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 134 +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"build_ordered_int8s_3"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":49},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"j","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":57},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_int8s"}}],"typemod":-1,"location":71},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare r two_int8s; begin r := row(i,j); return r; end\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":85}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":150}}]}}}]} +== 135 +select build_ordered_int8s_3(1,2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_3"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":29}},{"A_Const":{"ival":{"ival":2},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 136 +select build_ordered_int8s_3(2,1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_3"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":29}},{"A_Const":{"ival":{"ival":1},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 137 +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"build_ordered_int8s_4"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":49},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"j","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":57},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_int8s"}}],"typemod":-1,"location":71},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare r ordered_int8s; begin r := row(i,j); return r; end\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":85}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":154}}]}}}]} +== 138 +select build_ordered_int8s_4(1,2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_4"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":29}},{"A_Const":{"ival":{"ival":2},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 139 +select build_ordered_int8s_4(2,1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_4"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":29}},{"A_Const":{"ival":{"ival":1},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 140 +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"build_ordered_int8s_a"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":49},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"j","argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":57},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"ordered_int8s"}}],"typemod":-1,"arrayBounds":[{"Integer":{"ival":-1}}],"location":71},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin return array[row(i,j), row(i,j+1)]; end\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":87}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":142}}]}}}]} +== 141 +select build_ordered_int8s_a(1,2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_a"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":29}},{"A_Const":{"ival":{"ival":2},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 142 +select build_ordered_int8s_a(2,1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"build_ordered_int8s_a"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":29}},{"A_Const":{"ival":{"ival":1},"location":31}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 143 +-- fail + +-- check field assignment +do $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r ordered_int8s;\nbegin\n r.q1 := null;\n r.q2 := 43;\n r.q1 := 42;\n r.q2 := 41; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":38}}]}}}]} +== 144 +-- check whole-row assignment +do $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r ordered_int8s;\nbegin\n r := null;\n r := row(null,null);\n r := row(1,2);\n r := row(2,1); -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":33}}]}}}]} +== 145 +-- check assignment in for-loop +do $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r ordered_int8s;\nbegin\n for r in values (1,2),(3,4),(6,5) loop\n raise notice 'r = %', r;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":35}}]}}}]} +== 146 +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"two_texts","relpersistence":"p","location":58},"coldeflist":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":75},"is_local":true,"location":72}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":84},"is_local":true,"location":81}}]}}}]} +== 147 +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"ordered_texts"}}],"typeName":{"names":[{"String":{"sval":"two_texts"}}],"typemod":-1,"location":31},"constraints":[{"Constraint":{"contype":"CONSTR_CHECK","initially_valid":true,"raw_expr":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"\u003c="}}],"lexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":48}},"indirection":[{"String":{"sval":"f1"}}]}},"rexpr":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":62}},"indirection":[{"String":{"sval":"f2"}}]}},"location":58}},"location":41}}]}}}]} +== 148 +create table sometable (id int, a text, b text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"sometable","inh":true,"relpersistence":"p","location":13},"tableElts":[{"ColumnDef":{"colname":"id","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":27},"is_local":true,"location":24}},{"ColumnDef":{"colname":"a","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":34},"is_local":true,"location":32}},{"ColumnDef":{"colname":"b","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":42},"is_local":true,"location":40}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 149 +-- b should be compressed, but in-line +insert into sometable values (1, 'a', repeat('ffoob',1000)) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"sometable","inh":true,"relpersistence":"p","location":51},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":69}},{"A_Const":{"sval":{"sval":"a"},"location":72}},{"FuncCall":{"funcname":[{"String":{"sval":"repeat"}}],"args":[{"A_Const":{"sval":{"sval":"ffoob"},"location":84}},{"A_Const":{"ival":{"ival":1000},"location":92}}],"funcformat":"COERCE_EXPLICIT_CALL","location":77}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 150 +-- this b should be out-of-line +insert into sometable values (2, 'a', repeat('ffoob',100000)) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"sometable","inh":true,"relpersistence":"p","location":44},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":62}},{"A_Const":{"sval":{"sval":"a"},"location":65}},{"FuncCall":{"funcname":[{"String":{"sval":"repeat"}}],"args":[{"A_Const":{"sval":{"sval":"ffoob"},"location":77}},{"A_Const":{"ival":{"ival":100000},"location":85}}],"funcformat":"COERCE_EXPLICIT_CALL","location":70}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 151 +-- this pair should fail the domain check +insert into sometable values (3, 'z', repeat('ffoob',100000)) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"sometable","inh":true,"relpersistence":"p","location":54},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":3},"location":72}},{"A_Const":{"sval":{"sval":"z"},"location":75}},{"FuncCall":{"funcname":[{"String":{"sval":"repeat"}}],"args":[{"A_Const":{"sval":{"sval":"ffoob"},"location":87}},{"A_Const":{"ival":{"ival":100000},"location":95}}],"funcformat":"COERCE_EXPLICIT_CALL","location":80}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 152 +do $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare d ordered_texts;\nbegin\n for d in select a, b from sometable loop\n raise notice 'succeeded at \"%\"', d.f1;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 153 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r record; d ordered_texts;\nbegin\n for r in select * from sometable loop\n raise notice 'processing row %', r.id;\n d := row(r.a, r.b);\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 154 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare r record; d ordered_texts;\nbegin\n for r in select * from sometable loop\n raise notice 'processing row %', r.id;\n d := null;\n d.f1 := r.a;\n d.f2 := r.b;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 155 +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"compresult"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"int8"}}],"typemod":-1,"location":104},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":118},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":128}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" declare r record; begin r := row($1,$1); return r; end "}}]}},"defaction":"DEFELEM_UNSPEC","location":145}}]}}}]} +== 156 +create table two_int8s_tab (f1 two_int8s) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"two_int8s_tab","inh":true,"relpersistence":"p","location":13},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"two_int8s"}}],"typemod":-1,"location":31},"is_local":true,"location":28}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 157 +insert into two_int8s_tab values (compresult(42)) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"two_int8s_tab","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"compresult"}}],"args":[{"A_Const":{"ival":{"ival":42},"location":45}}],"funcformat":"COERCE_EXPLICIT_CALL","location":34}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 158 +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":-1}},"location":-1}}],"fromClause":[{"RangeVar":{"relname":"two_int8s_tab","inh":true,"relpersistence":"p","location":76}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_simple.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_simple.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_simple.test b/parser/testdata/parse/plpgsql_regress/plpgsql_simple.test new file mode 100644 index 0000000..b0c1b2b --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_simple.test @@ -0,0 +1,164 @@ +== 001 +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as 'select $1' +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"simplesql"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":160},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":173},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":177}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"select $1"}}]}},"defaction":"DEFELEM_UNSPEC","location":190}}]}}}]} +== 002 +create function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"simplecaller"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":39},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":43}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare\n sum int := 0;\nbegin\n for n in 1..10 loop\n sum := sum + simplesql(n);\n if n = 5 then\n create or replace function simplesql(int) returns int language sql\n as 'select $1 + 100';\n end if;\n end loop;\n return sum;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":60}}]}}}]} +== 003 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 004 +-- Check that changes in search path are dealt with correctly +create schema simple1 +-- +{"version":170007,"stmts":[{"stmt":{"CreateSchemaStmt":{"schemaname":"simple1"}}}]} +== 005 +create function simple1.simpletarget(int) returns int language plpgsql +as $$begin return $1; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"simple1"}},{"String":{"sval":"simpletarget"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":37},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":50},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":54}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"begin return $1; end"}}]}},"defaction":"DEFELEM_UNSPEC","location":71}}]}}}]} +== 006 +create function simpletarget(int) returns int language plpgsql +as $$begin return $1 + 100; end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"simpletarget"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":29},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":42},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":46}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"begin return $1 + 100; end"}}]}},"defaction":"DEFELEM_UNSPEC","location":63}}]}}}]} +== 007 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"simplecaller"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":50},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":54}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare\n sum int := 0;\nbegin\n for n in 1..10 loop\n sum := sum + simpletarget(n);\n if n = 5 then\n set local search_path = 'simple1';\n end if;\n end loop;\n return sum;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":71}}]}}}]} +== 008 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 009 +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +-- +{"version":170007,"stmts":[{"stmt":{"AlterFunctionStmt":{"objtype":"OBJECT_FUNCTION","func":{"objname":[{"String":{"sval":"simple1"}},{"String":{"sval":"simpletarget"}}],"objargs":[{"TypeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":79}}],"objfuncargs":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":79},"mode":"FUNC_PARAM_DEFAULT"}}]},"actions":[{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"immutable"}},"defaction":"DEFELEM_UNSPEC","location":84}}]}}}]} +== 010 +alter function simpletarget(int) immutable +-- +{"version":170007,"stmts":[{"stmt":{"AlterFunctionStmt":{"objtype":"OBJECT_FUNCTION","func":{"objname":[{"String":{"sval":"simpletarget"}}],"objargs":[{"TypeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":28}}],"objfuncargs":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":28},"mode":"FUNC_PARAM_DEFAULT"}}]},"actions":[{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"immutable"}},"defaction":"DEFELEM_UNSPEC","location":33}}]}}}]} +== 011 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 012 +-- make sure flushing local caches changes nothing + +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":59}},"location":59}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 013 +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $$select 1 / 0$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"simplesql"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":105},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":109}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"select 1 / 0"}}]}},"defaction":"DEFELEM_UNSPEC","location":122}}]}}}]} +== 014 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"simplecaller"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":50},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":54}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare x int;\nbegin\n select simplesql() into x;\n return x;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":71}}]}}}]} +== 015 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 016 +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $$select 2 + 2$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"simplesql"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":100},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":104}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"select 2 + 2"}}]}},"defaction":"DEFELEM_UNSPEC","location":117}}]}}}]} +== 017 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 018 +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"replace":true,"funcname":[{"String":{"sval":"simplecaller"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":128},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":132}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare x int;\nbegin\n x := simplesql();\n return x;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":149}}]}}}]} +== 019 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 020 +drop function simplesql() +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"ObjectWithArgs":{"objname":[{"String":{"sval":"simplesql"}}]}}],"removeType":"OBJECT_FUNCTION","behavior":"DROP_RESTRICT"}}}]} +== 021 +create function simplesql() returns setof int language sql +as $$select 22 + 22$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"simplesql"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"setof":true,"typemod":-1,"location":42},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":46}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"select 22 + 22"}}]}},"defaction":"DEFELEM_UNSPEC","location":59}}]}}}]} +== 022 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 023 +select simplecaller() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"simplecaller"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 024 +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare\n p_CurData refcursor;\n val int;\nbegin\n open p_CurData scroll for select 42;\n fetch p_CurData into val;\n raise notice 'val = %', val;\nend; "}},"defaction":"DEFELEM_UNSPEC","location":79}}]}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_transaction.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_transaction.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_transaction.test b/parser/testdata/parse/plpgsql_regress/plpgsql_transaction.test new file mode 100644 index 0000000..23effe9 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_transaction.test @@ -0,0 +1,853 @@ +== 001 +CREATE TABLE test1 (a int, b text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"test1","inh":true,"relpersistence":"p","location":13},"tableElts":[{"ColumnDef":{"colname":"a","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":22},"is_local":true,"location":20}},{"ColumnDef":{"colname":"b","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":29},"is_local":true,"location":27}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 002 +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test1"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":37},"mode":"FUNC_PARAM_DEFAULT"}},{"FunctionParameter":{"name":"y","argType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":44},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":50}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n FOR i IN 0..x LOOP\n INSERT INTO test1 (a, b) VALUES (i, y);\n IF i % 2 = 0 THEN\n COMMIT;\n ELSE\n ROLLBACK;\n END IF;\n END LOOP;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":67}}]}}}]} +== 003 +CALL transaction_test1(9, 'foo') +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test1"}}],"args":[{"A_Const":{"ival":{"ival":9},"location":23}},{"A_Const":{"sval":{"sval":"foo"},"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 004 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 005 +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":9}}],"behavior":"DROP_RESTRICT"}}}]} +== 006 +DO +LANGUAGE plpgsql +$$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n FOR i IN 0..9 LOOP\n INSERT INTO test1 (a) VALUES (i);\n IF i % 2 = 0 THEN\n COMMIT;\n ELSE\n ROLLBACK;\n END IF;\n END LOOP;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 007 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 008 +-- transaction commands not allowed when called in transaction block +START TRANSACTION +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_START","location":-1}}}]} +== 009 +CALL transaction_test1(9, 'error') +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test1"}}],"args":[{"A_Const":{"ival":{"ival":9},"location":23}},{"A_Const":{"sval":{"sval":"error"},"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 010 +COMMIT +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_COMMIT","location":-1}}}]} +== 011 +START TRANSACTION +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_START","location":-1}}}]} +== 012 +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":" BEGIN COMMIT; END "}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 013 +COMMIT +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_COMMIT","location":-1}}}]} +== 014 +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":9}}],"behavior":"DROP_RESTRICT"}}}]} +== 015 +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"transaction_test2"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":73},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":77}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n FOR i IN 0..9 LOOP\n INSERT INTO test1 (a) VALUES (i);\n IF i % 2 = 0 THEN\n COMMIT;\n ELSE\n ROLLBACK;\n END IF;\n END LOOP;\n RETURN 1;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":94}}]}}}]} +== 016 +SELECT transaction_test2() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"transaction_test2"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 017 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 018 +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"transaction_test3"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":103},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":107}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n CALL transaction_test1(9, 'error');\n RETURN 1;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":124}}]}}}]} +== 019 +SELECT transaction_test3() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"transaction_test3"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 020 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 021 +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"transaction_test4"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":72},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":76}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$';\n RETURN 1;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":93}}]}}}]} +== 022 +SELECT transaction_test4() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"transaction_test4"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 023 +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = 555 +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test5"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":101}},{"DefElem":{"defname":"set","arg":{"VariableSetStmt":{"kind":"VAR_SET_VALUE","name":"work_mem","args":[{"A_Const":{"ival":{"ival":555},"location":133}}]}},"defaction":"DEFELEM_UNSPEC","location":118}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n COMMIT;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":137}}]}}}]} +== 024 +CALL transaction_test5() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test5"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 025 +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test5b"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":100}},{"DefElem":{"defname":"security","arg":{"Boolean":{"boolval":true}},"defaction":"DEFELEM_UNSPEC","location":117}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n COMMIT;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":134}}]}}}]} +== 026 +CALL transaction_test5b() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test5b"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 027 +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":9}}],"behavior":"DROP_RESTRICT"}}}]} +== 028 +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test6"}}],"parameters":[{"FunctionParameter":{"name":"c","argType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":63},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":69}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n CALL transaction_test1(9, c);\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":86}}]}}}]} +== 029 +CALL transaction_test6('bar') +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test6"}}],"args":[{"A_Const":{"sval":{"sval":"bar"},"location":23}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 030 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 031 +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":9}}],"behavior":"DROP_RESTRICT"}}}]} +== 032 +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test7"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":37}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;';\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":54}}]}}}]} +== 033 +CALL transaction_test7() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test7"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 034 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 035 +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test8"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":37}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n EXECUTE 'CALL transaction_test1(10, $x$baz$x$)';\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":54}}]}}}]} +== 036 +CALL transaction_test8() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test8"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 037 +-- commit inside cursor loop +CREATE TABLE test2 (x int) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"test2","inh":true,"relpersistence":"p","location":42},"tableElts":[{"ColumnDef":{"colname":"x","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":51},"is_local":true,"location":49}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 038 +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"test2","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{},"location":26}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":31}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":36}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":3},"location":41}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":4},"location":46}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 039 +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":9}}],"behavior":"DROP_RESTRICT"}}}]} +== 040 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n r RECORD;\nBEGIN\n FOR r IN SELECT * FROM test2 ORDER BY x LOOP\n INSERT INTO test1 (a) VALUES (r.x);\n COMMIT;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 041 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 042 +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":57}},"location":57}}],"fromClause":[{"RangeVar":{"relname":"pg_cursors","inh":true,"relpersistence":"p","location":64}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 043 +-- error in cursor loop with commit +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":45}}],"behavior":"DROP_RESTRICT"}}}]} +== 044 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n r RECORD;\nBEGIN\n FOR r IN SELECT * FROM test2 ORDER BY x LOOP\n INSERT INTO test1 (a) VALUES (12/(r.x-2));\n COMMIT;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 045 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 046 +SELECT * FROM pg_cursors +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"pg_cursors","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 047 +-- rollback inside cursor loop +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":40}}],"behavior":"DROP_RESTRICT"}}}]} +== 048 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n r RECORD;\nBEGIN\n FOR r IN SELECT * FROM test2 ORDER BY x LOOP\n INSERT INTO test1 (a) VALUES (r.x);\n ROLLBACK;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 049 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 050 +SELECT * FROM pg_cursors +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"pg_cursors","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 051 +-- first commit then rollback inside cursor loop +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":58}}],"behavior":"DROP_RESTRICT"}}}]} +== 052 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n r RECORD;\nBEGIN\n FOR r IN SELECT * FROM test2 ORDER BY x LOOP\n INSERT INTO test1 (a) VALUES (r.x);\n IF r.x % 2 = 0 THEN\n COMMIT;\n ELSE\n ROLLBACK;\n END IF;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 053 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 054 +SELECT * FROM pg_cursors +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"pg_cursors","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 055 +-- rollback inside cursor loop +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":40}}],"behavior":"DROP_RESTRICT"}}}]} +== 056 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n r RECORD;\nBEGIN\n FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP\n INSERT INTO test1 (a) VALUES (r.x);\n ROLLBACK;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 057 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 058 +SELECT * FROM test2 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test2","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 059 +SELECT * FROM pg_cursors +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"pg_cursors","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 060 +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":82}}],"behavior":"DROP_RESTRICT"}}}]} +== 061 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"test1","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":26}},{"A_Const":{"sval":{"sval":"one"},"location":28}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":37}},{"A_Const":{"sval":{"sval":"two"},"location":39}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":3},"location":48}},{"A_Const":{"sval":{"sval":"three"},"location":50}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 062 +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE\n l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE;\nBEGIN\n FOR r IN l_cur LOOP\n UPDATE test1 SET b = b || ' ' || b WHERE a = r.a;\n COMMIT;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 063 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 064 +SELECT * FROM pg_cursors +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"pg_cursors","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 065 +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":54}}],"behavior":"DROP_RESTRICT"}}}]} +== 066 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"test1","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":26}},{"A_Const":{"sval":{"sval":"one"},"location":28}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":37}},{"A_Const":{"sval":{"sval":"two"},"location":39}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":3},"location":48}},{"A_Const":{"sval":{"sval":"three"},"location":50}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 067 +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nDECLARE r RECORD;\nBEGIN\n FOR r IN SELECT a FROM test1 FOR UPDATE LOOP\n UPDATE test1 SET b = b || ' ' || b WHERE a = r.a;\n COMMIT;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 068 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 069 +SELECT * FROM pg_cursors +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"pg_cursors","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 070 +-- commit inside block with exception handler +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":55}}],"behavior":"DROP_RESTRICT"}}}]} +== 071 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n BEGIN\n INSERT INTO test1 (a) VALUES (1);\n COMMIT;\n INSERT INTO test1 (a) VALUES (1/0);\n COMMIT;\n EXCEPTION\n WHEN division_by_zero THEN\n RAISE NOTICE 'caught division_by_zero';\n END;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 072 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 073 +-- rollback inside block with exception handler +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":57}}],"behavior":"DROP_RESTRICT"}}}]} +== 074 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n BEGIN\n INSERT INTO test1 (a) VALUES (1);\n ROLLBACK;\n INSERT INTO test1 (a) VALUES (1/0);\n ROLLBACK;\n EXCEPTION\n WHEN division_by_zero THEN\n RAISE NOTICE 'caught division_by_zero';\n END;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 075 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 076 +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":63}}],"behavior":"DROP_RESTRICT"}}}]} +== 077 +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n FOR i IN 1..10 LOOP\n BEGIN\n INSERT INTO test1 VALUES (i, 'good');\n INSERT INTO test1 VALUES (i/0, 'bad');\n EXCEPTION\n WHEN division_by_zero THEN\n INSERT INTO test1 VALUES (i, 'exception');\n IF (i % 3) \u003e 0 THEN COMMIT; ELSE ROLLBACK; END IF;\n END;\n END LOOP;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 078 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 079 +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"test4","inh":true,"relpersistence":"t","location":70},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":79},"is_local":true,"location":76}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 080 +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +-- +{"version":170007,"stmts":[{"stmt":{"AlterTableStmt":{"relation":{"relname":"test4","inh":true,"relpersistence":"p","location":12},"cmds":[{"AlterTableCmd":{"subtype":"AT_SetStorage","name":"f1","def":{"String":{"sval":"external"}},"behavior":"DROP_RESTRICT"}}],"objtype":"OBJECT_TABLE"}}}]} +== 081 +-- disable compression +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"test4","inh":true,"relpersistence":"p","location":35},"selectStmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"repeat"}}],"args":[{"A_Const":{"sval":{"sval":"xyzzy"},"location":55}},{"A_Const":{"ival":{"ival":2000},"location":64}}],"funcformat":"COERCE_EXPLICIT_CALL","location":48}},"location":48}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 082 +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS 'select f1 from test4' IMMUTABLE +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"data_source"}}],"parameters":[{"FunctionParameter":{"name":"i","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":150},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":163},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":168}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"select f1 from test4"}}]}},"defaction":"DEFELEM_UNSPEC","location":181}},{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"immutable"}},"defaction":"DEFELEM_UNSPEC","location":207}}]}}}]} +== 083 +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x text;\nbegin\n for i in 1..3 loop\n x := data_source(i);\n commit;\n end loop;\n raise notice 'length(x) = %', length(x);\nend "}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 084 +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":62}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare\n c test1 := row(42, 'hello');\n r bool;\nbegin\n for i in 1..3 loop\n r := c is not null;\n raise notice 'r = %', r;\n commit;\n end loop;\n for i in 1..3 loop\n r := c is null;\n raise notice 'r = %', r;\n rollback;\n end loop;\nend\n"}},"defaction":"DEFELEM_UNSPEC","location":79}}]}}}]} +== 085 +-- COMMIT failures +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":22}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED);\n COMMIT;\n INSERT INTO test3 (y) VALUES (1);\n COMMIT;\n INSERT INTO test3 (y) VALUES (1);\n INSERT INTO test3 (y) VALUES (2);\n COMMIT;\n INSERT INTO test3 (y) VALUES (3); -- won't get here\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":39}}]}}}]} +== 086 +SELECT * FROM test3 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test3","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 087 +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"cursor_fail_during_commit"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":124}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\n DECLARE id int;\n BEGIN\n FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP\n INSERT INTO test1 VALUES(id);\n COMMIT;\n END LOOP;\n END;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":141}}]}}}]} +== 088 +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":9}}],"behavior":"DROP_RESTRICT"}}}]} +== 089 +CALL cursor_fail_during_commit() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"cursor_fail_during_commit"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 090 +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"count"}}],"agg_star":true,"funcformat":"COERCE_EXPLICIT_CALL","location":80}},"location":80}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":94}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 091 +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"cursor_fail_during_rollback"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":48}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\n DECLARE id int;\n BEGIN\n FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP\n INSERT INTO test1 VALUES(id);\n ROLLBACK;\n END LOOP;\n END;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":65}}]}}}]} +== 092 +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":9}}],"behavior":"DROP_RESTRICT"}}}]} +== 093 +CALL cursor_fail_during_rollback() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"cursor_fail_during_rollback"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 094 +SELECT count(*) FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"count"}}],"agg_star":true,"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":21}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 095 +-- SET TRANSACTION +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":22}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n PERFORM 1;\n RAISE INFO '%', current_setting('transaction_isolation');\n COMMIT;\n SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;\n PERFORM 1;\n RAISE INFO '%', current_setting('transaction_isolation');\n COMMIT;\n SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\n PERFORM 1;\n RAISE INFO '%', current_setting('transaction_isolation');\n COMMIT;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":39}}]}}}]} +== 096 +-- error cases +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":18}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":35}}]}}}]} +== 097 +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n SAVEPOINT foo;\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 098 +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n EXECUTE 'COMMIT';\nEND;\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 099 +-- snapshot handling test +TRUNCATE test2 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test2","inh":true,"relpersistence":"p","location":35}}],"behavior":"DROP_RESTRICT"}}}]} +== 100 +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test9"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":37}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nINSERT INTO test2 VALUES (42);\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":50}}]}}}]} +== 101 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n ROLLBACK;\n CALL transaction_test9();\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 102 +SELECT * FROM test2 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test2","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 103 +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $$ SELECT COUNT(*) FROM test2 $$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"report_count"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":157},"options":[{"DefElem":{"defname":"volatility","arg":{"String":{"sval":"stable"}},"defaction":"DEFELEM_UNSPEC","location":161}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"sql"}},"defaction":"DEFELEM_UNSPEC","location":168}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":" SELECT COUNT(*) FROM test2 "}}]}},"defaction":"DEFELEM_UNSPEC","location":181}}]}}}]} +== 104 +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test9b"}}],"parameters":[{"FunctionParameter":{"name":"cnt","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":40},"mode":"FUNC_PARAM_DEFAULT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":45}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n RAISE NOTICE 'count = %', cnt;\nEND\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":62}}]}}}]} +== 105 +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n CALL transaction_test9b(report_count());\n INSERT INTO test2 VALUES(43);\n CALL transaction_test9b(report_count());\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 106 +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test10a"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":182},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":187}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n x := x + 1;\n COMMIT;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":204}}]}}}]} +== 107 +CALL transaction_test10a(10) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test10a"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":25}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 108 +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test10b"}}],"parameters":[{"FunctionParameter":{"name":"x","argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":45},"mode":"FUNC_PARAM_INOUT"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":50}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nBEGIN\n x := x - 1;\n ROLLBACK;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":67}}]}}}]} +== 109 +CALL transaction_test10b(10) +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test10b"}}],"args":[{"A_Const":{"ival":{"ival":10},"location":25}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 110 +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"is_procedure":true,"funcname":[{"String":{"sval":"transaction_test11"}}],"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":87}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nDECLARE\n s1 timestamp with time zone;\n s2 timestamp with time zone;\n s3 timestamp with time zone;\n t1 timestamp with time zone;\n t2 timestamp with time zone;\n t3 timestamp with time zone;\nBEGIN\n s1 := statement_timestamp();\n t1 := transaction_timestamp();\n ASSERT s1 = t1;\n PERFORM pg_sleep(0.001);\n COMMIT;\n s2 := statement_timestamp();\n t2 := transaction_timestamp();\n ASSERT s2 = s1;\n ASSERT t2 \u003e t1;\n PERFORM pg_sleep(0.001);\n ROLLBACK;\n s3 := statement_timestamp();\n t3 := transaction_timestamp();\n ASSERT s3 = s1;\n ASSERT t3 \u003e t2;\nEND;\n"}}]}},"defaction":"DEFELEM_UNSPEC","location":104}}]}}}]} +== 111 +CALL transaction_test11() +-- +{"version":170007,"stmts":[{"stmt":{"CallStmt":{"funccall":{"funcname":[{"String":{"sval":"transaction_test11"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":5}}}}]} +== 112 +-- transaction chain + +TRUNCATE test1 +-- +{"version":170007,"stmts":[{"stmt":{"TruncateStmt":{"relations":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":31}}],"behavior":"DROP_RESTRICT"}}}]} +== 113 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":3}},{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nBEGIN\n ROLLBACK;\n SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;\n FOR i IN 0..3 LOOP\n RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation');\n INSERT INTO test1 (a) VALUES (i);\n IF i % 2 = 0 THEN\n COMMIT AND CHAIN;\n ELSE\n ROLLBACK AND CHAIN;\n END IF;\n END LOOP;\nEND\n"}},"defaction":"DEFELEM_UNSPEC","location":20}}]}}}]} +== 114 +SELECT * FROM test1 +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"test1","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 115 +DROP TABLE test1 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"List":{"items":[{"String":{"sval":"test1"}}]}}],"removeType":"OBJECT_TABLE","behavior":"DROP_RESTRICT"}}}]} +== 116 +DROP TABLE test2 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"List":{"items":[{"String":{"sval":"test2"}}]}}],"removeType":"OBJECT_TABLE","behavior":"DROP_RESTRICT"}}}]} +== 117 +DROP TABLE test3 +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"List":{"items":[{"String":{"sval":"test3"}}]}}],"removeType":"OBJECT_TABLE","behavior":"DROP_RESTRICT"}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_trap.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_trap.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_trap.test b/parser/testdata/parse/plpgsql_regress/plpgsql_trap.test new file mode 100644 index 0000000..4db7298 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_trap.test @@ -0,0 +1,291 @@ +== 001 +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"trap_zero_divide"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":63},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":76},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare x int;\n\tsx smallint;\nbegin\n\tbegin\t-- start a subtransaction\n\t\traise notice 'should see this';\n\t\tx := 100 / $1;\n\t\traise notice 'should see this only if % \u003c\u003e 0', $1;\n\t\tsx := $1;\n\t\traise notice 'should see this only if % fits in smallint', $1;\n\t\tif $1 \u003c 0 then\n\t\t\traise exception '% is less than zero', $1;\n\t\tend if;\n\texception\n\t\twhen division_by_zero then\n\t\t\traise notice 'caught division_by_zero';\n\t\t\tx := -1;\n\t\twhen NUMERIC_VALUE_OUT_OF_RANGE then\n\t\t\traise notice 'caught numeric_value_out_of_range';\n\t\t\tx := -2;\n\tend;\n\treturn x;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":80}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":630}}]}}}]} +== 002 +select trap_zero_divide(50) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_zero_divide"}}],"args":[{"A_Const":{"ival":{"ival":50},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 003 +select trap_zero_divide(0) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_zero_divide"}}],"args":[{"A_Const":{"ival":{},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 004 +select trap_zero_divide(100000) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_zero_divide"}}],"args":[{"A_Const":{"ival":{"ival":100000},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 005 +select trap_zero_divide(-100) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_zero_divide"}}],"args":[{"A_Const":{"ival":{"ival":-100},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 006 +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +-- +{"version":170007,"stmts":[{"stmt":{"CreateTableAsStmt":{"query":{"SelectStmt":{"targetList":[{"ResTarget":{"name":"id","val":{"ColumnRef":{"fields":[{"String":{"sval":"x"}}],"location":38}},"location":38}},{"ResTarget":{"name":"data","val":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"*"}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"x"}}],"location":47}},"rexpr":{"A_Const":{"ival":{"ival":10},"location":49}},"location":48}},"location":47}},{"ResTarget":{"name":"ten","val":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"/"}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"x"}}],"location":61}},"rexpr":{"A_Const":{"ival":{"ival":10},"location":63}},"location":62}},"location":61}}],"fromClause":[{"RangeFunction":{"functions":[{"List":{"items":[{"FuncCall":{"funcname":[{"String":{"sval":"generate_series"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":94}},{"A_Const":{"ival":{"ival":100},"location":96}}],"funcformat":"COERCE_EXPLICIT_CALL","location":78}},{}]}}],"alias":{"aliasname":"x"}}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"into":{"rel":{"relname":"match_source","inh":true,"relpersistence":"p","location":13},"onCommit":"ONCOMMIT_NOOP"},"objtype":"OBJECT_TABLE"}}}]} +== 007 +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"trap_matching_test"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":35},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":48},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare x int;\n\tsx smallint;\n\ty int;\nbegin\n\tbegin\t-- start a subtransaction\n\t\tx := 100 / $1;\n\t\tsx := $1;\n\t\tselect into y data from match_source where id =\n\t\t\t(select id from match_source b where ten = $1);\n\texception\n\t\twhen data_exception then -- category match\n\t\t\traise notice 'caught data_exception';\n\t\t\tx := -1;\n\t\twhen NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then\n\t\t\traise notice 'caught numeric_value_out_of_range or cardinality_violation';\n\t\t\tx := -2;\n\tend;\n\treturn x;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":52}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":551}}]}}}]} +== 008 +select trap_matching_test(50) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_matching_test"}}],"args":[{"A_Const":{"ival":{"ival":50},"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 009 +select trap_matching_test(0) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_matching_test"}}],"args":[{"A_Const":{"ival":{},"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 010 +select trap_matching_test(100000) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_matching_test"}}],"args":[{"A_Const":{"ival":{"ival":100000},"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 011 +select trap_matching_test(1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_matching_test"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":26}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 012 +create temp table foo (f1 int) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"foo","inh":true,"relpersistence":"t","location":18},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":26},"is_local":true,"location":23}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 013 +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"subxact_rollback_semantics"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":53},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare x int;\nbegin\n x := 1;\n insert into foo values(x);\n begin\n x := x + 1;\n insert into foo values(x);\n raise exception 'inner';\n exception\n when others then\n x := x * 10;\n end;\n insert into foo values(x);\n return x;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":57}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":313}}]}}}]} +== 014 +select subxact_rollback_semantics() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"subxact_rollback_semantics"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 015 +select * from foo +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"foo","inh":true,"relpersistence":"p","location":14}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 016 +drop table foo +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"List":{"items":[{"String":{"sval":"foo"}}]}}],"removeType":"OBJECT_TABLE","behavior":"DROP_RESTRICT"}}}]} +== 017 +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"trap_timeout"}}],"returnType":{"names":[{"String":{"sval":"void"}}],"typemod":-1,"location":39},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n declare x int;\n begin\n -- we assume this will take longer than 1 second:\n select count(*) into x from generate_series(1, 1_000_000_000_000);\n exception\n when others then\n raise notice 'caught others?';\n when query_canceled then\n raise notice 'nyeah nyeah, can''t stop me';\n end;\n -- Abort transaction to abandon the statement_timeout setting. Otherwise,\n -- the next top-level statement would be vulnerable to the timeout.\n raise exception 'end of function';\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":44}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":552}}]}}}]} +== 018 +begin +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_BEGIN","location":-1}}}]} +== 019 +set statement_timeout to 1000 +-- +{"version":170007,"stmts":[{"stmt":{"VariableSetStmt":{"kind":"VAR_SET_VALUE","name":"statement_timeout","args":[{"A_Const":{"ival":{"ival":1000},"location":25}}]}}}]} +== 020 +select trap_timeout() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_timeout"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 021 +rollback +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_ROLLBACK","location":-1}}}]} +== 022 +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"test_variable_storage"}}],"returnType":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":110},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\ndeclare x text;\nbegin\n x := '1234';\n begin\n x := x || '5678';\n -- force error inside subtransaction SPI context\n perform trap_zero_divide(-100);\n exception\n when others then\n x := x || '9012';\n end;\n return x;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":115}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":359}}]}}}]} +== 023 +select test_variable_storage() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"test_variable_storage"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 024 +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"root","inh":true,"relpersistence":"t","location":60},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":68},"is_local":true,"constraints":[{"Constraint":{"contype":"CONSTR_PRIMARY","location":72}}],"location":65}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 025 +create temp table leaf(f1 int references root deferrable) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"leaf","inh":true,"relpersistence":"t","location":18},"tableElts":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":26},"is_local":true,"constraints":[{"Constraint":{"contype":"CONSTR_FOREIGN","initially_valid":true,"pktable":{"relname":"root","inh":true,"relpersistence":"p","location":41},"fk_matchtype":"s","fk_upd_action":"a","fk_del_action":"a","location":30}},{"Constraint":{"contype":"CONSTR_ATTR_DEFERRABLE","location":46}}],"location":23}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 026 +insert into root values(1) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"root","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":24}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 027 +insert into leaf values(1) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"leaf","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":24}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 028 +insert into leaf values(2) +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"leaf","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":24}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 029 +-- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"trap_foreign_key"}}],"parameters":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":43},"mode":"FUNC_PARAM_DEFAULT"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":56},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n\tbegin\t-- start a subtransaction\n\t\tinsert into leaf values($1);\n\texception\n\t\twhen foreign_key_violation then\n\t\t\traise notice 'caught foreign_key_violation';\n\t\t\treturn 0;\n\tend;\n\treturn 1;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":60}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":265}}]}}}]} +== 030 +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"trap_foreign_key_2"}}],"returnType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":45},"options":[{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"\nbegin\n\tbegin\t-- start a subtransaction\n\t\tset constraints all immediate;\n\texception\n\t\twhen foreign_key_violation then\n\t\t\traise notice 'caught foreign_key_violation';\n\t\t\treturn 0;\n\tend;\n\treturn 1;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":49}},{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":256}}]}}}]} +== 031 +select trap_foreign_key(1) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_foreign_key"}}],"args":[{"A_Const":{"ival":{"ival":1},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 032 +select trap_foreign_key(2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_foreign_key"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 033 +-- detects FK violation + +begin +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_BEGIN","location":-1}}}]} +== 034 +set constraints all deferred +-- +{"version":170007,"stmts":[{"stmt":{"ConstraintsSetStmt":{"deferred":true}}}]} +== 035 +select trap_foreign_key(2) +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_foreign_key"}}],"args":[{"A_Const":{"ival":{"ival":2},"location":24}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 036 +-- should not detect FK violation + savepoint x +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_SAVEPOINT","savepoint_name":"x","location":46}}}]} +== 037 +set constraints all immediate +-- +{"version":170007,"stmts":[{"stmt":{"ConstraintsSetStmt":{}}}]} +== 038 +-- fails + rollback to x +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_ROLLBACK_TO","savepoint_name":"x","location":23}}}]} +== 039 +select trap_foreign_key_2() +-- +{"version":170007,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"FuncCall":{"funcname":[{"String":{"sval":"trap_foreign_key_2"}}],"funcformat":"COERCE_EXPLICIT_CALL","location":7}},"location":7}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]} +== 040 +-- detects FK violation +commit +-- +{"version":170007,"stmts":[{"stmt":{"TransactionStmt":{"kind":"TRANS_STMT_COMMIT","location":-1}}}]} +== 041 +-- still fails + +drop function trap_foreign_key(int) +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"ObjectWithArgs":{"objname":[{"String":{"sval":"trap_foreign_key"}}],"objargs":[{"TypeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":47}}],"objfuncargs":[{"FunctionParameter":{"argType":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":47},"mode":"FUNC_PARAM_DEFAULT"}}]}}],"removeType":"OBJECT_FUNCTION","behavior":"DROP_RESTRICT"}}}]} +== 042 +drop function trap_foreign_key_2() +-- +{"version":170007,"stmts":[{"stmt":{"DropStmt":{"objects":[{"ObjectWithArgs":{"objname":[{"String":{"sval":"trap_foreign_key_2"}}]}}],"removeType":"OBJECT_FUNCTION","behavior":"DROP_RESTRICT"}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_trigger.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_trigger.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_trigger.test b/parser/testdata/parse/plpgsql_regress/plpgsql_trigger.test new file mode 100644 index 0000000..7e169c5 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_trigger.test @@ -0,0 +1,37 @@ +== 001 +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +-- +{"version":170007,"stmts":[{"stmt":{"CreateStmt":{"relation":{"relname":"testtr","inh":true,"relpersistence":"p","location":90},"tableElts":[{"ColumnDef":{"colname":"a","typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":100},"is_local":true,"location":98}},{"ColumnDef":{"colname":"b","typeName":{"names":[{"String":{"sval":"text"}}],"typemod":-1,"location":107},"is_local":true,"location":105}}],"oncommit":"ONCOMMIT_NOOP"}}}]} +== 002 +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"CreateFunctionStmt":{"funcname":[{"String":{"sval":"testtr_trigger"}}],"returnType":{"names":[{"String":{"sval":"trigger"}}],"typemod":-1,"location":41},"options":[{"DefElem":{"defname":"language","arg":{"String":{"sval":"plpgsql"}},"defaction":"DEFELEM_UNSPEC","location":49}},{"DefElem":{"defname":"as","arg":{"List":{"items":[{"String":{"sval":"begin\n raise notice 'tg_op = %', tg_op;\n raise notice 'old(%) = %', old.a, row(old.*);\n raise notice 'new(%) = %', new.a, row(new.*);\n if (tg_op = 'DELETE') then\n return old;\n else\n return new;\n end if;\nend"}}]}},"defaction":"DEFELEM_UNSPEC","location":66}}]}}}]} +== 003 +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +-- +{"version":170007,"stmts":[{"stmt":{"CreateTrigStmt":{"trigname":"testtr_trigger","relation":{"relname":"testtr","inh":true,"relpersistence":"p","location":67},"funcname":[{"String":{"sval":"testtr_trigger"}}],"row":true,"timing":2,"events":28}}}]} +== 004 +insert into testtr values (1, 'one'), (2, 'two') +-- +{"version":170007,"stmts":[{"stmt":{"InsertStmt":{"relation":{"relname":"testtr","inh":true,"relpersistence":"p","location":12},"selectStmt":{"SelectStmt":{"valuesLists":[{"List":{"items":[{"A_Const":{"ival":{"ival":1},"location":27}},{"A_Const":{"sval":{"sval":"one"},"location":30}}]}},{"List":{"items":[{"A_Const":{"ival":{"ival":2},"location":39}},{"A_Const":{"sval":{"sval":"two"},"location":42}}]}}],"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}},"override":"OVERRIDING_NOT_SET"}}}]} +== 005 +update testtr set a = a + 1 +-- +{"version":170007,"stmts":[{"stmt":{"UpdateStmt":{"relation":{"relname":"testtr","inh":true,"relpersistence":"p","location":7},"targetList":[{"ResTarget":{"name":"a","val":{"A_Expr":{"kind":"AEXPR_OP","name":[{"String":{"sval":"+"}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"sval":"a"}}],"location":22}},"rexpr":{"A_Const":{"ival":{"ival":1},"location":26}},"location":24}},"location":18}}]}}}]} +== 006 +delete from testtr +-- +{"version":170007,"stmts":[{"stmt":{"DeleteStmt":{"relation":{"relname":"testtr","inh":true,"relpersistence":"p","location":12}}}}]} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/parse/plpgsql_regress/plpgsql_varprops.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_varprops.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/parse/plpgsql_regress/plpgsql_varprops.test b/parser/testdata/parse/plpgsql_regress/plpgsql_varprops.test new file mode 100644 index 0000000..4931575 --- /dev/null +++ b/parser/testdata/parse/plpgsql_regress/plpgsql_varprops.test @@ -0,0 +1,325 @@ +== 001 +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +-- +{"version":170007,"stmts":[{"stmt":{"CompositeTypeStmt":{"typevar":{"relname":"var_record","relpersistence":"p","location":95},"coldeflist":[{"ColumnDef":{"colname":"f1","typeName":{"names":[{"String":{"sval":"int4"}}],"typemod":-1,"location":113},"is_local":true,"location":110}},{"ColumnDef":{"colname":"f2","typeName":{"names":[{"String":{"sval":"int4"}}],"typemod":-1,"location":122},"is_local":true,"location":119}}]}}}]} +== 002 +create domain int_nn as int not null +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"int_nn"}}],"typeName":{"names":[{"String":{"sval":"pg_catalog"}},{"String":{"sval":"int4"}}],"typemod":-1,"location":24},"constraints":[{"Constraint":{"contype":"CONSTR_NOTNULL","location":28}}]}}}]} +== 003 +create domain var_record_nn as var_record not null +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"var_record_nn"}}],"typeName":{"names":[{"String":{"sval":"var_record"}}],"typemod":-1,"location":31},"constraints":[{"Constraint":{"contype":"CONSTR_NOTNULL","location":42}}]}}}]} +== 004 +create domain var_record_colnn as var_record check((value).f2 is not null) +-- +{"version":170007,"stmts":[{"stmt":{"CreateDomainStmt":{"domainname":[{"String":{"sval":"var_record_colnn"}}],"typeName":{"names":[{"String":{"sval":"var_record"}}],"typemod":-1,"location":34},"constraints":[{"Constraint":{"contype":"CONSTR_CHECK","initially_valid":true,"raw_expr":{"NullTest":{"arg":{"A_Indirection":{"arg":{"ColumnRef":{"fields":[{"String":{"sval":"value"}}],"location":52}},"indirection":[{"String":{"sval":"f2"}}]}},"nulltesttype":"IS_NOT_NULL","location":62}},"location":45}}]}}}]} +== 005 +-- CONSTANT + +do $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x constant int := 42;\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":16}}]}}}]} +== 006 +do $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x constant int;\nbegin\n x := 42; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 007 +do $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x constant int; y int;\nbegin\n for x, y in select 1, 2 loop -- fail\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 008 +do $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x constant int[];\nbegin\n x[1] := 42; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 009 +do $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x constant int[]; y int;\nbegin\n for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax)\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 010 +do $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x constant var_record;\nbegin\n x.f1 := 42; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 011 +do $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x constant var_record; y int;\nbegin\n for x.f1, y in select 1, 2 loop -- fail\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 012 +-- initializer expressions + +do $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int := sin(0);\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":31}}]}}}]} +== 013 +do $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int := 1/0; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 014 +do $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x bigint[] := array[1,3,5];\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 015 +do $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x record := row(1,2,3);\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 016 +do $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record := row(1,2);\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 017 +-- NOT NULL + +do $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int not null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":16}}]}}}]} +== 018 +do $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int not null := 42;\nbegin\n raise notice 'x = %', x;\n x := null; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 019 +do $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int not null := null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 020 +do $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x record not null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 021 +do $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x record not null := row(42);\nbegin\n raise notice 'x = %', x;\n x := row(null); -- ok\n raise notice 'x = %', x;\n x := null; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 022 +do $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x record not null := null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 023 +do $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record not null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 024 +do $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record not null := row(41,42);\nbegin\n raise notice 'x = %', x;\n x := row(null,null); -- ok\n raise notice 'x = %', x;\n x := null; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 025 +do $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record not null := null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 026 +-- Check that variables are reinitialized on block re-entry. + +do $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\nbegin\n for i in 1..3 loop\n declare\n x int;\n y int := i;\n r record;\n c var_record;\n begin\n if i = 1 then\n x := 42;\n r := row(i, i+1);\n c := row(i, i+1);\n end if;\n raise notice 'x = %', x;\n raise notice 'y = %', y;\n raise notice 'r = %', r;\n raise notice 'c = %', c;\n end;\n end loop;\nend"}},"defaction":"DEFELEM_UNSPEC","location":65}}]}}}]} +== 027 +-- Check enforcement of domain constraints during initialization + +do $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int_nn; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":69}}]}}}]} +== 028 +do $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int_nn := null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 029 +do $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x int_nn := 42;\nbegin\n raise notice 'x = %', x;\n x := null; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 030 +do $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_nn; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 031 +do $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_nn := null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 032 +do $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_nn := row(1,2);\nbegin\n raise notice 'x = %', x;\n x := row(null,null); -- ok\n x := null; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 033 +do $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_colnn; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 034 +do $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_colnn := null; -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 035 +do $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_colnn := row(1,null); -- fail\nbegin\n raise notice 'x = %', x;\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 036 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_colnn := row(1,2);\nbegin\n raise notice 'x = %', x;\n x := null; -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} +== 037 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ +-- +{"version":170007,"stmts":[{"stmt":{"DoStmt":{"args":[{"DefElem":{"defname":"as","arg":{"String":{"sval":"\ndeclare x var_record_colnn := row(1,2);\nbegin\n raise notice 'x = %', x;\n x := row(null,null); -- fail\nend"}},"defaction":"DEFELEM_UNSPEC","location":3}}]}}}]} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json new file mode 100644 index 0000000..442b788 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json @@ -0,0 +1,35 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.test new file mode 100644 index 0000000..8ee83ff --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.test @@ -0,0 +1,270 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of array variables +|-- +-- We also check arrays of composites here, so this has some overlap +-- with the plpgsql_record tests. +|-- + +create type complex as (r float8, i float8) +-- +[] +== 002 +create type quadarray as (c1 complex[], c2 complex) +-- +[] +== 003 +do $$ declare a int[]; +begin a := array[1,2]; a[3] := 4; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := array[1,2]","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[3] := 4","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 004 +do $$ declare a int[]; +begin a[3] := 4; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[3] := 4","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 005 +do $$ declare a int[]; +begin a[1][4] := 4; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1][4] := 4","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 006 +do $$ declare a int[]; +begin a[1] := 23::text; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1] := 23::text","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 007 +-- lax typing + +do $$ declare a int[]; +begin a := array[1,2]; a[2:3] := array[3,4]; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := array[1,2]","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[2:3] := array[3,4]","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 008 +do $$ declare a int[]; +begin a := array[1,2]; a[2] := a[2] + 1; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := array[1,2]","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[2] := a[2] + 1","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 009 +do $$ declare a int[]; +begin a[1:2] := array[3,4]; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1:2] := array[3,4]","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 010 +do $$ declare a int[]; +begin a[1:2] := 4; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1:2] := 4","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 011 +-- error + +do $$ declare a complex[]; +begin a[1] := (1,2); a[1].i := 11; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"complex[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1] := (1,2)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1].i := 11","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 012 +do $$ declare a complex[]; +begin a[1].i := 11; raise notice 'a = %, a[1].i = %', a, a[1].i; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"complex[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1].i := 11","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %, a[1].i = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"a[1].i","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 013 +-- perhaps this ought to work, but for now it doesn't: +do $$ declare a complex[]; +begin a[1:2].i := array[11,12]; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"complex[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1:2].i := array[11,12]","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 014 +do $$ declare a quadarray; +begin a.c1[1].i := 11; raise notice 'a = %, a.c1[1].i = %', a, a.c1[1].i; end$$ +-- +ERROR: "a.c1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 015 +do $$ declare a int[]; +begin a := array_agg(x) from (values(1),(2),(3)) v(x); raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := array_agg(x) from (values(1),(2),(3)) v(x)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 016 +create temp table onecol as select array[1,2] as f1 +-- +[] +== 017 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := f1 from onecol","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 018 +do $$ declare a int[]; +begin a := * from onecol for update; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := * from onecol for update","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 019 +-- error cases: + +do $$ declare a int[]; +begin a := from onecol; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := from onecol","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 020 +do $$ declare a int[]; +begin a := f1, f1 from onecol; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := f1, f1 from onecol","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 021 +insert into onecol values(array[11]) +-- +[] +== 022 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := f1 from onecol","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 023 +do $$ declare a int[]; +begin a := f1 from onecol limit 1; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := f1 from onecol limit 1","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 024 +do $$ declare a real; +begin a[1] := 2; raise notice 'a = %', a; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"real"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a[1] := 2","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"a = %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 025 +do $$ declare a complex; +begin a.r[1] := 2; raise notice 'a = %', a; end$$ +-- +ERROR: "a.r" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 026 +|-- +-- test of %type[] and %rowtype[] syntax +|-- + +-- check supported syntax +do $$ +declare + v int; + v1 v%type; + v2 v%type[]; + v3 v%type[1]; + v4 v%type[][]; + v5 v%type[1][3]; + v6 v%type array; + v7 v%type array[]; + v8 v%type array[1]; + v9 v%type array[1][1]; + v10 pg_catalog.pg_class%rowtype[]; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(v3); + raise notice '%', pg_typeof(v4); + raise notice '%', pg_typeof(v5); + raise notice '%', pg_typeof(v6); + raise notice '%', pg_typeof(v7); + raise notice '%', pg_typeof(v8); + raise notice '%', pg_typeof(v9); + raise notice '%', pg_typeof(v10); +end; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"v1","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"v%type"}}}},{"PLpgSQL_var":{"refname":"v2","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"v%type[]"}}}},{"PLpgSQL_var":{"refname":"v3","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"v%type[1]"}}}},{"PLpgSQL_var":{"refname":"v4","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"v%type[][]"}}}},{"PLpgSQL_var":{"refname":"v5","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"v%type[1][3]"}}}},{"PLpgSQL_var":{"refname":"v6","lineno":9,"datatype":{"PLpgSQL_type":{"typname":"v%type array"}}}},{"PLpgSQL_var":{"refname":"v7","lineno":10,"datatype":{"PLpgSQL_type":{"typname":"v%type array[]"}}}},{"PLpgSQL_var":{"refname":"v8","lineno":11,"datatype":{"PLpgSQL_type":{"typname":"v%type array[1]"}}}},{"PLpgSQL_var":{"refname":"v9","lineno":12,"datatype":{"PLpgSQL_type":{"typname":"v%type array[1][1]"}}}},{"PLpgSQL_var":{"refname":"v10","lineno":13,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.pg_class%rowtype[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":14,"body":[{"PLpgSQL_stmt_raise":{"lineno":15,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v1)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":16,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v2)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":17,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v3)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":18,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v4)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":19,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v5)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":20,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v6)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":21,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v7)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":22,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v8)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":23,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v9)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":24,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v10)","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 027 +-- some types don't support arrays +do $$ +declare + v pg_node_tree; + v1 v%type[]; +begin +end; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_node_tree"}}}},{"PLpgSQL_var":{"refname":"v1","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"v%type[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 028 +-- check functionality +do $$ +declare + v1 int; + v2 varchar; + a1 v1%type[]; + a2 v2%type[]; +begin + v1 := 10; + v2 := 'Hi'; + a1 := array[v1,v1]; + a2 := array[v2,v2]; + raise notice '% %', a1, a2; +end; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v1","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"v2","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"a1","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"v1%type[]"}}}},{"PLpgSQL_var":{"refname":"a2","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"v2%type[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":7,"body":[{"PLpgSQL_stmt_assign":{"lineno":8,"varno":1,"expr":{"PLpgSQL_expr":{"query":"v1 := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":9,"varno":2,"expr":{"PLpgSQL_expr":{"query":"v2 := 'Hi'","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":10,"varno":3,"expr":{"PLpgSQL_expr":{"query":"a1 := array[v1,v1]","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":11,"varno":4,"expr":{"PLpgSQL_expr":{"query":"a2 := array[v2,v2]","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":18,"message":"% %","params":[{"PLpgSQL_expr":{"query":"a1","parseMode":2}},{"PLpgSQL_expr":{"query":"a2","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 029 +create table array_test_table(a int, b varchar) +-- +[] +== 030 +insert into array_test_table values(1, 'first'), (2, 'second') +-- +[] +== 031 +do $$ +declare tg array_test_table%rowtype[]; +begin + tg := array(select array_test_table from array_test_table); + raise notice '%', tg; + tg := array(select row(a,b) from array_test_table); + raise notice '%', tg; +end; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"tg","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"array_test_table%rowtype[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"tg := array(select array_test_table from array_test_table)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"tg","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"tg := array(select row(a,b) from array_test_table)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"tg","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json new file mode 100644 index 0000000..70c818b --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json @@ -0,0 +1,17 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.test new file mode 100644 index 0000000..07f6d4d --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.test @@ -0,0 +1,87 @@ +== 001 +|-- +-- Cache-behavior-dependent test cases +|-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- depending on debug_discard_caches, so we must have two expected-output +-- files to cover both cases. To minimize the maintenance effort resulting +-- from that, this file should contain only tests that do have different +-- results under debug_discard_caches. +|-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text) +-- +[] +== 002 +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +ERROR: "r.f1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"c_sillyaddone\" near line 1" +== 003 +select c_sillyaddone(42) +-- +[] +== 004 +alter table c_mutable drop column f1 +-- +[] +== 005 +alter table c_mutable add column f1 float8 +-- +[] +== 006 +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but if debug_discard_caches is on, it will succeed) +select c_sillyaddone(42) +-- +[] +== 007 +-- but it's OK if we force plan rebuilding +discard plans +-- +[] +== 008 +select c_sillyaddone(42) +-- +[] +== 009 +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":3}},{"PLpgSQL_var":{"refname":"t","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_recfield":{"fieldname":"a","recparentno":2}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":7,"fields":[{"name":"t","varno":3}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_dynexecute":{"lineno":6,"query":{"PLpgSQL_expr":{"query":"$1","parseMode":2}},"into":true,"target":{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":3}}}},{"PLpgSQL_stmt_execsql":{"lineno":7,"sqlstmt":{"PLpgSQL_expr":{"query":"select pg_typeof(r.a)","parseMode":0}},"into":true,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":7,"fields":[{"name":"t","varno":3}]}}}},{"PLpgSQL_stmt_return":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"format('type %s value %s', t, r.a::text)","parseMode":2}}}}]}}}} +] +== 010 +select show_result_type('select 1 as a') +-- +[] +== 011 +-- currently this fails due to cached plan for pg_typeof expression +-- (but if debug_discard_caches is on, it will succeed) +select show_result_type('select 2.0 as a') +-- +[] +== 012 +-- but it's OK if we force plan rebuilding +discard plans +-- +[] +== 013 +select show_result_type('select 2.0 as a') +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json new file mode 100644 index 0000000..449cbc1 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json @@ -0,0 +1,87 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.test new file mode 100644 index 0000000..1d57855 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.test @@ -0,0 +1,842 @@ +== 001 +|-- +-- Tests for procedures / CALL syntax +|-- + +CREATE PROCEDURE test_proc1() +LANGUAGE plpgsql +AS $$ +BEGIN + NULL; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 002 +CALL test_proc1() +-- +[] +== 003 +-- error: can't return non-NULL +CREATE PROCEDURE test_proc2() +LANGUAGE plpgsql +AS $$ +BEGIN + RETURN 5; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"5","parseMode":2}}}}]}}}} +] +== 004 +CREATE TABLE test1 (a int) +-- +[] +== 005 +CREATE PROCEDURE test_proc3(x int) +LANGUAGE plpgsql +AS $$ +BEGIN + INSERT INTO test1 VALUES (x); +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 VALUES (x)","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 006 +CALL test_proc3(55) +-- +[] +== 007 +SELECT * FROM test1 +-- +[] +== 008 +-- Check that plan revalidation doesn't prevent setting transaction properties +-- (bug #18059). This test must include the first temp-object creation in +-- this script, or it won't exercise the bug scenario. Hence we put it early. +CREATE PROCEDURE test_proc3a() +LANGUAGE plpgsql +AS $$ +BEGIN + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + RAISE NOTICE 'done'; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_commit":{"lineno":3}},{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"SET TRANSACTION ISOLATION LEVEL REPEATABLE READ","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"done"}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 009 +CALL test_proc3a() +-- +[] +== 010 +CREATE TEMP TABLE tt1(f1 int) +-- +[] +== 011 +CALL test_proc3a() +-- +[] +== 012 +-- nested CALL +TRUNCATE TABLE test1 +-- +[] +== 013 +CREATE PROCEDURE test_proc4(y int) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL test_proc3(y); + CALL test_proc3($1); +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_call":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc3(y)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_call":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc3($1)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 014 +CALL test_proc4(66) +-- +[] +== 015 +SELECT * FROM test1 +-- +[] +== 016 +CALL test_proc4(66) +-- +[] +== 017 +SELECT * FROM test1 +-- +[] +== 018 +-- output arguments + +CREATE PROCEDURE test_proc5(INOUT a text) +LANGUAGE plpgsql +AS $$ +BEGIN + a := a || '+' || a; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"a := a || '+' || a","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 019 +CALL test_proc5('abc') +-- +[] +== 020 +CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + b := b * a; + c := c * a; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"c","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":1,"expr":{"PLpgSQL_expr":{"query":"b := b * a","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"c := c * a","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 021 +CALL test_proc6(2, 3, 4) +-- +[] +== 022 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); + RAISE INFO 'x = %, y = %', x, y; + CALL test_proc6(2, c => y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"3","parseMode":2}}}},{"PLpgSQL_var":{"refname":"y","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"4","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc6(2, x, y)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":17,"message":"x = %, y = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}},{"PLpgSQL_expr":{"query":"y","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc6(2, c =\u003e y, b =\u003e x)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":17,"message":"x = %, y = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}},{"PLpgSQL_expr":{"query":"y","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 023 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"3","parseMode":2}}}},{"PLpgSQL_var":{"refname":"y","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"4","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc6(2, x + 1, y)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":17,"message":"x = %, y = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}},{"PLpgSQL_expr":{"query":"y","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 024 +DO +LANGUAGE plpgsql +$$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"isconst":true,"default_val":{"PLpgSQL_expr":{"query":"3","parseMode":2}}}},{"PLpgSQL_var":{"refname":"y","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"4","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc6(2, x, y)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 025 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"3","parseMode":2}}}},{"PLpgSQL_var":{"refname":"y","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"4","parseMode":2}}}},{"PLpgSQL_var":{"refname":"i","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_fori":{"lineno":6,"var":{"PLpgSQL_var":{"refname":"i","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"5","parseMode":2}},"body":[{"PLpgSQL_stmt_call":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc6(i, x, y)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":17,"message":"x = %, y = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}},{"PLpgSQL_expr":{"query":"y","parseMode":2}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 026 +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"numeric\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_if":{"lineno":3,"cond":{"PLpgSQL_expr":{"query":"x \u003e 1","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := x / 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":2,"expr":{"PLpgSQL_expr":{"query":"b := x / 2","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc7(b::int, a, b)","parseMode":0}},"is_call":true}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 027 +CALL test_proc7(100, -1, -1) +-- +[] +== 028 +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"numeric\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":1,"expr":{"PLpgSQL_expr":{"query":"a := x / 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"b := x / 2","parseMode":3}}}},{"PLpgSQL_stmt_commit":{"lineno":5}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 029 +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"_x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"numeric"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_call":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc7c(_x, _a, _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"_x: %,_a: %, _b: %","params":[{"PLpgSQL_expr":{"query":"_x","parseMode":2}},{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 030 +CALL test_proc7cc(10) +-- +[] +== 031 +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"a: %, b: %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"a := a * 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"b := b + 10","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 032 +CALL test_proc8a(10, 20) +-- +[] +== 033 +CALL test_proc8a(b => 20, a => 10) +-- +[] +== 034 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8a(_a, _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8a(b =\u003e _b, a =\u003e _a)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"_a: %, _b: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 035 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"c","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"a: %, b: %, c: %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}},{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"a := a * 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"b := b + 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":2,"expr":{"PLpgSQL_expr":{"query":"c := c * -10","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 036 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 50","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8b(_a, _b, _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8b(_a, c =\u003e _c, b =\u003e _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 037 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"c","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"a: %, b: %, c: %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}},{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"a := a * 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"b := b + 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":2,"expr":{"PLpgSQL_expr":{"query":"c := c * -10","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 038 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 50","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8c(_a, _b, _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 50","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8c(_a, c =\u003e _c, b =\u003e _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":10,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":10,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":10,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 50","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":11,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8c(c =\u003e _c, b =\u003e _b, a =\u003e _a)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 039 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 50","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8c(_a, _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 040 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 50","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc8c(_a, b =\u003e _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 041 +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"a: %, b: %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"b := a * 2","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 042 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc9(_a, _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 043 +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"c","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"a: %, b: %, c: %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}},{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"b := a - c","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 044 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc10(_a, _b, _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":8,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":8,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":8,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":9,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc10(_a, _b, c =\u003e _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":12,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":12,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":12,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":13,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc10(a =\u003e _a, b =\u003e _b, c =\u003e _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":14,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":16,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":16,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":16,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":17,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc10(_a, c =\u003e _c, b =\u003e _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":18,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":20,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":20,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":20,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":21,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc10(_a, _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":22,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":24,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":24,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":24,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":25,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc10(_a, b =\u003e _b)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":26,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":28,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":28,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":28,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":29,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc10(b =\u003e _b, a =\u003e _a)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":30,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 045 +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"a: %, b: %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"a := b[1] + b[2]","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 046 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":2,"expr":{"PLpgSQL_expr":{"query":"_b := 30","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"_c := 7","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc11(_a, _b, _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 047 +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"anyelement"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"anyelement"}}}},{"PLpgSQL_var":{"refname":"c","datatype":{"PLpgSQL_type":{"typname":"anyarray"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"a: %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"b := a","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":2,"expr":{"PLpgSQL_expr":{"query":"c := array[a]","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 048 +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc12(_a, _b, _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 049 +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"_c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"text[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_a := 10","parseMode":3}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc12(_a, _b, _c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"_a: %, _b: %, _c: %","params":[{"PLpgSQL_expr":{"query":"_a","parseMode":2}},{"PLpgSQL_expr":{"query":"_b","parseMode":2}},{"PLpgSQL_expr":{"query":"_c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 050 +-- transition variable assignment + +TRUNCATE test1 +-- +[] +== 051 +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_var":{"refname":"z","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}},{"PLpgSQL_recfield":{"fieldname":"a","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL test_proc6(2, NEW.a, NEW.a)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"NEW","parseMode":2}}}}]}}}} +] +== 052 +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +-- +[] +== 053 +INSERT INTO test1 VALUES (1), (2), (3) +-- +[] +== 054 +UPDATE test1 SET a = 22 WHERE a = 2 +-- +[] +== 055 +SELECT * FROM test1 ORDER BY a +-- +[] +== 056 +DROP PROCEDURE test_proc1 +-- +[] +== 057 +DROP PROCEDURE test_proc3 +-- +[] +== 058 +DROP PROCEDURE test_proc4 +-- +[] +== 059 +DROP TABLE test1 +-- +[] +== 060 +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"v_cnt","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"v_text","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":1,"expr":{"PLpgSQL_expr":{"query":"v_Text := 'v_cnt = ' || v_cnt","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 061 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v_text","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"v_cnt","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"integer "}},"default_val":{"PLpgSQL_expr":{"query":"42","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL p1(v_cnt := v_cnt)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"v_Text","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 062 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v_text","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"v_cnt","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"integer "}},"default_val":{"PLpgSQL_expr":{"query":"42","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL p1(v_cnt := v_cnt, v_Text := v_Text)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"v_Text","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 063 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v_text","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"text"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL p1(10, v_Text := v_Text)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"v_Text","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 064 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v_text","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"v_cnt","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL p1(v_Text := v_Text, v_cnt := v_cnt)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"v_Text","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 065 +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"f1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"inner_p(%)","params":[{"PLpgSQL_expr":{"query":"f1","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 066 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 067 +CREATE PROCEDURE outer_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"f1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"outer_p(%)","params":[{"PLpgSQL_expr":{"query":"f1","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"CALL inner_p(f(f1))","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 068 +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"f1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"outer_f(%)","params":[{"PLpgSQL_expr":{"query":"f1","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"CALL inner_p(f(f1))","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 069 +CALL outer_p(42) +-- +[] +== 070 +SELECT outer_f(42) +-- +[] +== 071 +DROP FUNCTION f(int) +-- +[] +== 072 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 073 +CALL outer_p(42) +-- +[] +== 074 +SELECT outer_f(42) +-- +[] +== 075 +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +-- +[] +== 076 +INSERT INTO t_test VALUES (0) +-- +[] +== 077 +CREATE FUNCTION f_get_x () RETURNS int +AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"l_result","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"l_result","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"SELECT x FROM t_test","parseMode":0}},"into":true,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"l_result","varno":1}]}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"l_result","parseMode":2}}}}]}}}} +] +== 078 +CREATE PROCEDURE f_print_x (x int) +AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"f_print_x(%)","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 079 +-- test in non-atomic context +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE t_test SET x = x + 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"f_get_x(%)","params":[{"PLpgSQL_expr":{"query":"f_get_x()","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL f_print_x(f_get_x())","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE t_test SET x = x + 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"f_get_x(%)","params":[{"PLpgSQL_expr":{"query":"f_get_x()","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"CALL f_print_x(f_get_x())","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_rollback":{"lineno":9}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 080 +-- test in non-atomic context, except exception block is locally atomic +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":10,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":10,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE t_test SET x = x + 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"f_get_x(%)","params":[{"PLpgSQL_expr":{"query":"f_get_x()","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"CALL f_print_x(f_get_x())","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_execsql":{"lineno":7,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE t_test SET x = x + 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"f_get_x(%)","params":[{"PLpgSQL_expr":{"query":"f_get_x()","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":9,"expr":{"PLpgSQL_expr":{"query":"CALL f_print_x(f_get_x())","parseMode":0}},"is_call":true}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"division_by_zero"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":11,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"SQLERRM","parseMode":2}}]}}]}}]}}}},{"PLpgSQL_stmt_rollback":{"lineno":13}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 081 +-- test in atomic context +BEGIN +-- +[] +== 082 +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE t_test SET x = x + 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"f_get_x(%)","params":[{"PLpgSQL_expr":{"query":"f_get_x()","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL f_print_x(f_get_x())","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE t_test SET x = x + 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"f_get_x(%)","params":[{"PLpgSQL_expr":{"query":"f_get_x()","parseMode":2}}]}},{"PLpgSQL_stmt_call":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"CALL f_print_x(f_get_x())","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 083 +ROLLBACK +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json new file mode 100644 index 0000000..706d53c --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json @@ -0,0 +1,57 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.test new file mode 100644 index 0000000..5545eec --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.test @@ -0,0 +1,689 @@ +== 001 +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":12,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":16,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":20,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":24,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":28,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":4,"var":{"PLpgSQL_var":{"refname":"i","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"1..3: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_fori":{"lineno":8,"var":{"PLpgSQL_var":{"refname":"i","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":18,"message":"1..10 by 3: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_fori":{"lineno":12,"var":{"PLpgSQL_var":{"refname":"i","lineno":12,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"11","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":13,"elog_level":18,"message":"1..11 by 3: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_fori":{"lineno":16,"var":{"PLpgSQL_var":{"refname":"i","lineno":16,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"0","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":17,"elog_level":18,"message":"1..0 by 3: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_fori":{"lineno":20,"var":{"PLpgSQL_var":{"refname":"i","lineno":20,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"0","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"reverse":true,"body":[{"PLpgSQL_stmt_raise":{"lineno":21,"elog_level":18,"message":"reverse 10..0 by 3: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_fori":{"lineno":24,"var":{"PLpgSQL_var":{"refname":"i","lineno":24,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"2147483620","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"2147483647","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":25,"elog_level":18,"message":"2147483620..2147483647 by 10: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_fori":{"lineno":28,"var":{"PLpgSQL_var":{"refname":"i","lineno":28,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"-2147483620","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"-2147483647","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"reverse":true,"body":[{"PLpgSQL_stmt_raise":{"lineno":29,"elog_level":18,"message":"reverse -2147483620..-2147483647 by 10: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 002 +-- BY can't be zero or negative +do $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"0","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"1..3 by 0: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 003 +do $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"-1","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"1..3 by -1: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 004 +do $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"step":{"PLpgSQL_expr":{"query":"-1","parseMode":2}},"reverse":true,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"reverse 1..3 by -1: i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 005 +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +-- +[] +== 006 +insert into conttesttbl(v) values(10) +-- +[] +== 007 +insert into conttesttbl(v) values(20) +-- +[] +== 008 +insert into conttesttbl(v) values(30) +-- +[] +== 009 +insert into conttesttbl(v) values(40) +-- +[] +== 010 +create function continue_test1() returns void as $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_i","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"integer "}},"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}},{"PLpgSQL_rec":{"refname":"_r","dno":2,"lineno":2}},{"PLpgSQL_var":{"refname":"_i","lineno":32,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_recfield":{"fieldname":"v","recparentno":2}},{"PLpgSQL_var":{"refname":"_i","lineno":54,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"_i","lineno":81,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"_j","lineno":84,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"---1---"}},{"PLpgSQL_stmt_loop":{"lineno":5,"body":[{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_i := _i + 1","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_i","parseMode":2}}]}},{"PLpgSQL_stmt_exit":{"lineno":8,"cond":{"PLpgSQL_expr":{"query":"_i \u003c 10","parseMode":2}}}},{"PLpgSQL_stmt_exit":{"lineno":9,"is_exit":true}}]}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":18,"message":"---2---"}},{"PLpgSQL_stmt_loop":{"lineno":14,"label":"lbl","body":[{"PLpgSQL_stmt_assign":{"lineno":15,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_i := _i - 1","parseMode":3}}}},{"PLpgSQL_stmt_loop":{"lineno":16,"body":[{"PLpgSQL_stmt_raise":{"lineno":17,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_i","parseMode":2}}]}},{"PLpgSQL_stmt_exit":{"lineno":18,"label":"lbl","cond":{"PLpgSQL_expr":{"query":"_i \u003e 0","parseMode":2}}}},{"PLpgSQL_stmt_exit":{"lineno":19,"is_exit":true,"label":"lbl"}}]}}]}},{"PLpgSQL_stmt_raise":{"lineno":23,"elog_level":18,"message":"---3---"}},{"PLpgSQL_stmt_while":{"lineno":25,"label":"the_loop","cond":{"PLpgSQL_expr":{"query":"_i \u003c 10","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":26,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_i := _i + 1","parseMode":3}}}},{"PLpgSQL_stmt_exit":{"lineno":27,"label":"the_loop","cond":{"PLpgSQL_expr":{"query":"_i % 2 = 0","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":28,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_raise":{"lineno":31,"elog_level":18,"message":"---4---"}},{"PLpgSQL_stmt_fori":{"lineno":32,"var":{"PLpgSQL_var":{"refname":"_i","lineno":32,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_block":{"lineno":33,"body":[{"PLpgSQL_stmt_exit":{"lineno":35,"cond":{"PLpgSQL_expr":{"query":"_i \u003c 5","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":36,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_i","parseMode":2}}]}}]}}]}},{"PLpgSQL_stmt_raise":{"lineno":40,"elog_level":18,"message":"---5---"}},{"PLpgSQL_stmt_fors":{"lineno":41,"var":{"PLpgSQL_rec":{"refname":"_r","dno":2,"lineno":2}},"body":[{"PLpgSQL_stmt_exit":{"lineno":42,"cond":{"PLpgSQL_expr":{"query":"_r.v \u003c= 20","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":43,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_r.v","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"select * from conttesttbl","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":46,"elog_level":18,"message":"---6---"}},{"PLpgSQL_stmt_dynfors":{"lineno":47,"var":{"PLpgSQL_rec":{"refname":"_r","dno":2,"lineno":2}},"body":[{"PLpgSQL_stmt_exit":{"lineno":48,"cond":{"PLpgSQL_expr":{"query":"_r.v \u003c= 20","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":49,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_r.v","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"'select * from conttesttbl'","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":52,"elog_level":18,"message":"---7---"}},{"PLpgSQL_stmt_fori":{"lineno":54,"label":"looplabel","var":{"PLpgSQL_var":{"refname":"_i","lineno":54,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_exit":{"lineno":55,"label":"looplabel","cond":{"PLpgSQL_expr":{"query":"_i = 2","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":56,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_raise":{"lineno":59,"elog_level":18,"message":"---8---"}},{"PLpgSQL_stmt_assign":{"lineno":60,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_i := 1","parseMode":3}}}},{"PLpgSQL_stmt_while":{"lineno":61,"cond":{"PLpgSQL_expr":{"query":"_i \u003c= 3","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":62,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_i","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":63,"varno":1,"expr":{"PLpgSQL_expr":{"query":"_i := _i + 1","parseMode":3}}}},{"PLpgSQL_stmt_exit":{"lineno":64,"cond":{"PLpgSQL_expr":{"query":"_i = 3","parseMode":2}}}}]}},{"PLpgSQL_stmt_raise":{"lineno":67,"elog_level":18,"message":"---9---"}},{"PLpgSQL_stmt_fors":{"lineno":68,"var":{"PLpgSQL_rec":{"refname":"_r","dno":2,"lineno":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":69,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_r.v","parseMode":2}}]}},{"PLpgSQL_stmt_exit":{"lineno":70}}],"query":{"PLpgSQL_expr":{"query":"select * from conttesttbl order by v limit 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":73,"elog_level":18,"message":"---10---"}},{"PLpgSQL_stmt_dynfors":{"lineno":74,"var":{"PLpgSQL_rec":{"refname":"_r","dno":2,"lineno":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":75,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"_r.v","parseMode":2}}]}},{"PLpgSQL_stmt_exit":{"lineno":76}}],"query":{"PLpgSQL_expr":{"query":"'select * from conttesttbl order by v limit 1'","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":79,"elog_level":18,"message":"---11---"}},{"PLpgSQL_stmt_fori":{"lineno":81,"label":"outerlooplabel","var":{"PLpgSQL_var":{"refname":"_i","lineno":81,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"2","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":82,"elog_level":18,"message":"outer %","params":[{"PLpgSQL_expr":{"query":"_i","parseMode":2}}]}},{"PLpgSQL_stmt_fori":{"lineno":84,"label":"innerlooplabel","var":{"PLpgSQL_var":{"refname":"_j","lineno":84,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_exit":{"lineno":85,"label":"outerlooplabel","cond":{"PLpgSQL_expr":{"query":"_j = 2","parseMode":2}}}},{"PLpgSQL_stmt_raise":{"lineno":86,"elog_level":18,"message":"inner %","params":[{"PLpgSQL_expr":{"query":"_j","parseMode":2}}]}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 011 +select continue_test1() +-- +[] +== 012 +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $$ +begin + begin + continue; + end; +end; +$$ language plpgsql +-- +ERROR: CONTINUE cannot be used outside a loop +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"continue_error1\" near line 4" +== 013 +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $$ +begin + begin + exit; + end; +end; +$$ language plpgsql +-- +ERROR: EXIT cannot be used outside a loop, unless it has a label +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"exit_error1\" near line 4" +== 014 +-- should fail: no such label +create function continue_error2() returns void as $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +ERROR: there is no label "no_such_label" attached to any block or loop enclosing this statement +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"continue_error2\" near line 5" +== 015 +-- should fail: no such label +create function exit_error2() returns void as $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +ERROR: there is no label "no_such_label" attached to any block or loop enclosing this statement +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"exit_error2\" near line 5" +== 016 +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ language plpgsql +-- +ERROR: block label "begin_block1" cannot be used in CONTINUE +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"continue_error3\" near line 6" +== 017 +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_block":{"lineno":4,"label":"begin_block1","body":[{"PLpgSQL_stmt_loop":{"lineno":5,"body":[{"PLpgSQL_stmt_exit":{"lineno":6,"is_exit":true,"label":"begin_block1"}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":21,"message":"should not get here"}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 018 +select exit_block1() +-- +[] +== 019 +-- verbose end block and end loop +create function end_label1() returns void as $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"j","lineno":10,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"label":"blbl","body":[{"PLpgSQL_stmt_fori":{"lineno":5,"label":"flbl1","var":{"PLpgSQL_var":{"refname":"i","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}},{"PLpgSQL_stmt_exit":{"lineno":7,"is_exit":true,"label":"flbl1"}}]}},{"PLpgSQL_stmt_fori":{"lineno":10,"label":"flbl2","var":{"PLpgSQL_var":{"refname":"j","lineno":10,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":11,"elog_level":18,"message":"j = %","params":[{"PLpgSQL_expr":{"query":"j","parseMode":2}}]}},{"PLpgSQL_stmt_exit":{"lineno":12,"is_exit":true,"label":"flbl2"}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 020 +select end_label1() +-- +[] +== 021 +-- should fail: undefined end label +create function end_label2() returns void as $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ language plpgsql +-- +ERROR: end label "flbl1" specified for unlabeled block +FILENAME: pl_gram.y +FUNCNAME: check_labels +CONTEXT: "compilation of PL/pgSQL function \"end_label2\" near line 3" +== 022 +-- should fail: end label does not match start label +create function end_label3() returns void as $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +ERROR: end label "outer_label" differs from block's label "inner_label" +FILENAME: pl_gram.y +FUNCNAME: check_labels +CONTEXT: "compilation of PL/pgSQL function \"end_label3\" near line 5" +== 023 +-- should fail: end label on a block without a start label +create function end_label4() returns void as $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +ERROR: end label "outer_label" specified for unlabeled block +FILENAME: pl_gram.y +FUNCNAME: check_labels +CONTEXT: "compilation of PL/pgSQL function \"end_label4\" near line 4" +== 024 +-- unlabeled exit matches no blocks +do $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_block":{"lineno":5,"label":"innerblock","body":[{"PLpgSQL_stmt_block":{"lineno":6,"body":[{"PLpgSQL_stmt_exit":{"lineno":7,"is_exit":true}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"should not get here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"should not get here, either"}}]}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":18,"message":"nor here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":14,"elog_level":18,"message":"should get here"}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 025 +-- check exit out of an unlabeled block to a labeled one +do $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"body":[{"PLpgSQL_stmt_block":{"lineno":3,"label":"outerblock","body":[{"PLpgSQL_stmt_block":{"lineno":5,"label":"innerblock","body":[{"PLpgSQL_stmt_block":{"lineno":7,"label":"moreinnerblock","body":[{"PLpgSQL_stmt_block":{"lineno":8,"body":[{"PLpgSQL_stmt_exit":{"lineno":9,"is_exit":true,"label":"innerblock"}},{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"should not get here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":18,"message":"should not get here, either"}}]}},{"PLpgSQL_stmt_raise":{"lineno":14,"elog_level":18,"message":"nor here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":16,"elog_level":18,"message":"should get here"}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 026 +-- check exit out of outermost block +do $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"body":[{"PLpgSQL_stmt_block":{"lineno":3,"label":"outerblock","body":[{"PLpgSQL_stmt_block":{"lineno":5,"label":"innerblock","body":[{"PLpgSQL_stmt_exit":{"lineno":6,"is_exit":true,"label":"outerblock"}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"should not get here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":18,"message":"should not get here, either"}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 027 +-- unlabeled exit does match a while loop +do $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_while":{"lineno":4,"label":"outermostwhile","cond":{"PLpgSQL_expr":{"query":"1 \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_while":{"lineno":6,"label":"outerwhile","cond":{"PLpgSQL_expr":{"query":"1 \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_while":{"lineno":8,"label":"innerwhile","cond":{"PLpgSQL_expr":{"query":"1 \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_exit":{"lineno":9,"is_exit":true}},{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"should not get here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":18,"message":"should get here"}},{"PLpgSQL_stmt_exit":{"lineno":13,"is_exit":true,"label":"outermostwhile"}},{"PLpgSQL_stmt_raise":{"lineno":14,"elog_level":18,"message":"should not get here, either"}}]}},{"PLpgSQL_stmt_raise":{"lineno":16,"elog_level":18,"message":"nor here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":18,"elog_level":18,"message":"should get here, too"}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 028 +-- check exit out of an unlabeled while to a labeled one +do $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_while":{"lineno":4,"label":"outerwhile","cond":{"PLpgSQL_expr":{"query":"1 \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_while":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"1 \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_exit":{"lineno":6,"is_exit":true,"label":"outerwhile"}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"should not get here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":18,"message":"should not get here, either"}}]}},{"PLpgSQL_stmt_raise":{"lineno":11,"elog_level":18,"message":"should get here"}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 029 +-- continue to an outer while +do $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_while":{"lineno":5,"label":"outermostwhile","cond":{"PLpgSQL_expr":{"query":"i \u003c 2","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"outermostwhile, i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":1,"expr":{"PLpgSQL_expr":{"query":"i := i + 1","parseMode":3}}}},{"PLpgSQL_stmt_while":{"lineno":9,"label":"outerwhile","cond":{"PLpgSQL_expr":{"query":"1 \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_while":{"lineno":11,"label":"innerwhile","cond":{"PLpgSQL_expr":{"query":"1 \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_exit":{"lineno":12,"label":"outermostwhile"}},{"PLpgSQL_stmt_raise":{"lineno":13,"elog_level":18,"message":"should not get here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":15,"elog_level":18,"message":"should not get here, either"}}]}},{"PLpgSQL_stmt_raise":{"lineno":17,"elog_level":18,"message":"nor here"}}]}},{"PLpgSQL_stmt_raise":{"lineno":19,"elog_level":18,"message":"out of outermostwhile, i = %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 030 +-- return out of a while +create function return_from_while() returns int language plpgsql as $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_while":{"lineno":4,"cond":{"PLpgSQL_expr":{"query":"i \u003c 10","parseMode":2}},"body":[{"PLpgSQL_stmt_if":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"i \u003e 2","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"i","parseMode":2}}}}]}},{"PLpgSQL_stmt_assign":{"lineno":8,"varno":1,"expr":{"PLpgSQL_expr":{"query":"i := i + 1","parseMode":3}}}}]}},{"PLpgSQL_stmt_return":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"null","parseMode":2}}}}]}}}} +] +== 031 +select return_from_while() +-- +[] +== 032 +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $proc$ +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice '%', i; + end loop; + -- fore with record var + for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop + raise notice '% % %', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice '%', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop + raise notice '% % %', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop + raise notice '% % %', a, b, c; + end loop; +end; +$proc$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_var":{"refname":"b","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"c","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_rec":{"refname":"r","dno":4,"lineno":2}},{"PLpgSQL_var":{"refname":"i","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_recfield":{"fieldname":"aa","recparentno":4}},{"PLpgSQL_recfield":{"fieldname":"bb","recparentno":4}},{"PLpgSQL_recfield":{"fieldname":"cc","recparentno":4}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":13,"fields":[{"name":"a","varno":1}]}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":17,"fields":[{"name":"a","varno":1},{"name":"b","varno":2},{"name":"c","varno":3}]}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":21,"fields":[{"name":"lbl.a","varno":1},{"name":"lbl.b","varno":2},{"name":"lbl.c","varno":3}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"label":"lbl","body":[{"PLpgSQL_stmt_fori":{"lineno":5,"var":{"PLpgSQL_var":{"refname":"i","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}]}},{"PLpgSQL_stmt_fors":{"lineno":9,"var":{"PLpgSQL_rec":{"refname":"r","dno":4,"lineno":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"% % %","params":[{"PLpgSQL_expr":{"query":"r.aa","parseMode":2}},{"PLpgSQL_expr":{"query":"r.bb","parseMode":2}},{"PLpgSQL_expr":{"query":"r.cc","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs","parseMode":0}}}},{"PLpgSQL_stmt_fors":{"lineno":13,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":13,"fields":[{"name":"a","varno":1}]}},"body":[{"PLpgSQL_stmt_raise":{"lineno":14,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"select gs from generate_series(1,4) gs","parseMode":0}}}},{"PLpgSQL_stmt_fors":{"lineno":17,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":17,"fields":[{"name":"a","varno":1},{"name":"b","varno":2},{"name":"c","varno":3}]}},"body":[{"PLpgSQL_stmt_raise":{"lineno":18,"elog_level":18,"message":"% % %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}},{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"select gs, 'BB','CC' from generate_series(1,4) gs","parseMode":0}}}},{"PLpgSQL_stmt_dynfors":{"lineno":21,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":21,"fields":[{"name":"lbl.a","varno":1},{"name":"lbl.b","varno":2},{"name":"lbl.c","varno":3}]}},"body":[{"PLpgSQL_stmt_raise":{"lineno":22,"elog_level":18,"message":"% % %","params":[{"PLpgSQL_expr":{"query":"a","parseMode":2}},{"PLpgSQL_expr":{"query":"b","parseMode":2}},{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"$$select gs, 'bb','cc' from generate_series(1,4) gs$$","parseMode":2}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 033 +select for_vect() +-- +[] +== 034 +-- CASE statement + +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ language plpgsql immutable +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"10","parseMode":2}}}},{"PLpgSQL_var":{"refname":"b","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}},{"PLpgSQL_var":{"refname":"__Case__Variable_4__","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_case":{"lineno":5,"t_expr":{"PLpgSQL_expr":{"query":"$1","parseMode":2}},"t_varno":4,"case_when_list":[{"PLpgSQL_case_when":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"\"__Case__Variable_4__\" IN (1)","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"'one'","parseMode":2}}}}]}},{"PLpgSQL_case_when":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"\"__Case__Variable_4__\" IN (2)","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":9,"expr":{"PLpgSQL_expr":{"query":"'two'","parseMode":2}}}}]}},{"PLpgSQL_case_when":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"\"__Case__Variable_4__\" IN (3,4,3+5)","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":11,"expr":{"PLpgSQL_expr":{"query":"'three, four or eight'","parseMode":2}}}}]}},{"PLpgSQL_case_when":{"lineno":12,"expr":{"PLpgSQL_expr":{"query":"\"__Case__Variable_4__\" IN (a)","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":13,"expr":{"PLpgSQL_expr":{"query":"'ten'","parseMode":2}}}}]}},{"PLpgSQL_case_when":{"lineno":14,"expr":{"PLpgSQL_expr":{"query":"\"__Case__Variable_4__\" IN (a+b, a+b+1)","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":15,"expr":{"PLpgSQL_expr":{"query":"'eleven, twelve'","parseMode":2}}}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 035 +select case_test(1) +-- +[] +== 036 +select case_test(2) +-- +[] +== 037 +select case_test(3) +-- +[] +== 038 +select case_test(4) +-- +[] +== 039 +select case_test(5) +-- +[] +== 040 +-- fails +select case_test(8) +-- +[] +== 041 +select case_test(10) +-- +[] +== 042 +select case_test(11) +-- +[] +== 043 +select case_test(12) +-- +[] +== 044 +select case_test(13) +-- +[] +== 045 +-- fails + +create or replace function catch() returns void as $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"body":[{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"case_test(6)","parseMode":2}}]}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"case_not_found"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"caught case_not_found % %","params":[{"PLpgSQL_expr":{"query":"SQLSTATE","parseMode":2}},{"PLpgSQL_expr":{"query":"SQLERRM","parseMode":2}}]}}]}}]}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 046 +select catch() +-- +[] +== 047 +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"10","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_case":{"lineno":4,"case_when_list":[{"PLpgSQL_case_when":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"$1 = 1","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"'one'","parseMode":2}}}}]}},{"PLpgSQL_case_when":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"$1 = a + 2","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"'twelve'","parseMode":2}}}}]}}],"have_else":true,"else_stmts":[{"PLpgSQL_stmt_return":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"'other'","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 048 +select case_test(1) +-- +[] +== 049 +select case_test(2) +-- +[] +== 050 +select case_test(12) +-- +[] +== 051 +select case_test(13) +-- +[] +== 052 +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"__Case__Variable_2__","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_case":{"lineno":3,"t_expr":{"PLpgSQL_expr":{"query":"$1","parseMode":2}},"t_varno":2,"case_when_list":[{"PLpgSQL_case_when":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"\"__Case__Variable_2__\" IN (1)","parseMode":2}},"stmts":[{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"'one'","parseMode":2}}}}]}}],"have_else":true,"else_stmts":[{"PLpgSQL_stmt_return":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"'other'","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 053 +select case_comment(1) +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.test new file mode 100644 index 0000000..2788c56 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.test @@ -0,0 +1,21 @@ +== 001 +-- directory paths are passed to us in environment variables + +-- set up file names to use + +CREATE TABLE copy1 (a int, b float); + +-- COPY TO/FROM not authorized from client. +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 TO stdout; +END; +$$; +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 FROM stdin; +-- +ERROR: "unterminated dollar-quoted string at or near \"$$\nBEGIN\n COPY copy1 FROM stdin;\"" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json new file mode 100644 index 0000000..aa06c83 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json @@ -0,0 +1,86 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.test new file mode 100644 index 0000000..aca9591 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.test @@ -0,0 +1,530 @@ +== 001 +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +-- +[] +== 002 +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"booltrue"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"bool"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"y","parseMode":2}}}}]}}}} +] +== 003 +SELECT * FROM test_argresult_booltrue(true, true) +-- +[] +== 004 +SELECT * FROM test_argresult_booltrue(false, true) +-- +[] +== 005 +SELECT * FROM test_argresult_booltrue(true, false) +-- +[] +== 006 +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"bool"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"bool"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"booltrue "}},"default_val":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"v := y","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"v","parseMode":2}}}}]}}}} +] +== 007 +SELECT * FROM test_assign_booltrue(true, true) +-- +[] +== 008 +SELECT * FROM test_assign_booltrue(false, true) +-- +[] +== 009 +SELECT * FROM test_assign_booltrue(true, false) +-- +[] +== 010 +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +-- +[] +== 011 +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"uint2"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"y","parseMode":2}}}}]}}}} +] +== 012 +SELECT * FROM test_argresult_uint2(100::uint2, 50) +-- +[] +== 013 +SELECT * FROM test_argresult_uint2(100::uint2, -50) +-- +[] +== 014 +SELECT * FROM test_argresult_uint2(null, 1) +-- +[] +== 015 +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"uint2 "}},"default_val":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"v := y","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"v","parseMode":2}}}}]}}}} +] +== 016 +SELECT * FROM test_assign_uint2(100, 50) +-- +[] +== 017 +SELECT * FROM test_assign_uint2(100, -50) +-- +[] +== 018 +SELECT * FROM test_assign_uint2(-100, 50) +-- +[] +== 019 +SELECT * FROM test_assign_uint2(null, 1) +-- +[] +== 020 +CREATE DOMAIN nnint AS int NOT NULL +-- +[] +== 021 +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"nnint"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"y","parseMode":2}}}}]}}}} +] +== 022 +SELECT * FROM test_argresult_nnint(10, 20) +-- +[] +== 023 +SELECT * FROM test_argresult_nnint(null, 20) +-- +[] +== 024 +SELECT * FROM test_argresult_nnint(10, null) +-- +[] +== 025 +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"nnint "}},"default_val":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"v := y","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"v","parseMode":2}}}}]}}}} +] +== 026 +SELECT * FROM test_assign_nnint(10, 20) +-- +[] +== 027 +SELECT * FROM test_assign_nnint(null, 20) +-- +[] +== 028 +SELECT * FROM test_assign_nnint(10, null) +-- +[] +== 029 +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +-- +[] +== 030 +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"ordered_pair_domain"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}]}}}} +] +== 031 +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +-- +[] +== 032 +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +-- +[] +== 033 +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"array[2,1]","parseMode":2}}}}]}}}} +] +== 034 +SELECT * FROM test_argresult_array_domain_check_violation() +-- +[] +== 035 +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"z","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"ordered_pair_domain "}},"default_val":{"PLpgSQL_expr":{"query":"array[x, y]","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":4,"expr":{"PLpgSQL_expr":{"query":"v[2] := z","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"v","parseMode":2}}}}]}}}} +] +== 036 +SELECT * FROM test_assign_ordered_pair_domain(1,2,3) +-- +[] +== 037 +SELECT * FROM test_assign_ordered_pair_domain(1,2,0) +-- +[] +== 038 +SELECT * FROM test_assign_ordered_pair_domain(2,1,3) +-- +[] +== 039 +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"uint2"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"x[1]","parseMode":2}}}}]}}}} +] +== 040 +select test_read_uint2_array(array[1::uint2]) +-- +[] +== 041 +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"int2"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"array[x, x]","parseMode":2}}}}]}}}} +] +== 042 +select test_build_uint2_array(1::int2) +-- +[] +== 043 +select test_build_uint2_array(-1::int2) +-- +[] +== 044 +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"array[x::ordered_pair_domain, x::ordered_pair_domain]","parseMode":2}}}}]}}}} +] +== 045 +select test_argresult_domain_array(array[2,4]) +-- +[] +== 046 +select test_argresult_domain_array(array[4,2]) +-- +[] +== 047 +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"ordered_pair_domain"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"x[1]","parseMode":2}}}}]}}}} +] +== 048 +select test_argresult_domain_array2(array[2,4]) +-- +[] +== 049 +select test_argresult_domain_array2(array[4,2]) +-- +[] +== 050 +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"ordered_pair_domain"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"x[1]","parseMode":2}}}}]}}}} +] +== 051 +select test_argresult_array_domain_array(array[array[2,4]::ordered_pair_domain]) +-- +[] +== 052 +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +-- +[] +== 053 +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"row(x, y)::nnint_container","parseMode":2}}}}]}}}} +] +== 054 +SELECT test_result_nnint_container(null, 3) +-- +[] +== 055 +SELECT test_result_nnint_container(3, null) +-- +[] +== 056 +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +ERROR: "v.f2" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"test_assign_nnint_container\" near line 2" +== 057 +SELECT * FROM test_assign_nnint_container(1,2,3) +-- +[] +== 058 +SELECT * FROM test_assign_nnint_container(1,2,null) +-- +[] +== 059 +SELECT * FROM test_assign_nnint_container(1,null,3) +-- +[] +== 060 +-- Since core system allows this: +SELECT null::nnint_container +-- +[] +== 061 +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +ERROR: "v.f2" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"test_assign_nnint_container2\" near line 2" +== 062 +SELECT * FROM test_assign_nnint_container2(1,2,3) +-- +[] +== 063 +SELECT * FROM test_assign_nnint_container2(1,2,null) +-- +[] +== 064 +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +-- +[] +== 065 +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +-- +[] +== 066 +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"p","datatype":{"PLpgSQL_type":{"typname":"ordered_named_pair"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"p.i + p.j","parseMode":2}}}}]}}}} +] +== 067 +SELECT read_ordered_named_pair(row(1, 2)) +-- +[] +== 068 +SELECT read_ordered_named_pair(row(2, 1)) +-- +[] +== 069 +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"i","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"j","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"row(i, j)","parseMode":2}}}}]}}}} +] +== 070 +SELECT build_ordered_named_pair(1,2) +-- +[] +== 071 +SELECT build_ordered_named_pair(2,1) +-- +[] +== 072 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +ERROR: "v.j" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"test_assign_ordered_named_pair\" near line 2" +== 073 +SELECT * FROM test_assign_ordered_named_pair(1,2,3) +-- +[] +== 074 +SELECT * FROM test_assign_ordered_named_pair(1,2,0) +-- +[] +== 075 +SELECT * FROM test_assign_ordered_named_pair(2,1,3) +-- +[] +== 076 +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"i","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"j","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"array[row(i, j), row(i, j+1)]","parseMode":2}}}}]}}}} +] +== 077 +SELECT build_ordered_named_pairs(1,2) +-- +[] +== 078 +SELECT build_ordered_named_pairs(2,1) +-- +[] +== 079 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"z","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"ordered_named_pair[] "}},"default_val":{"PLpgSQL_expr":{"query":"array[row(x, y)]","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"v","parseMode":2}}}}]}}}} +] +== 080 +SELECT * FROM test_assign_ordered_named_pairs(1,2,3) +-- +[] +== 081 +SELECT * FROM test_assign_ordered_named_pairs(2,1,3) +-- +[] +== 082 +SELECT * FROM test_assign_ordered_named_pairs(1,2,0) +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json new file mode 100644 index 0000000..5a08d01 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json @@ -0,0 +1,18 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.test new file mode 100644 index 0000000..6ae0e96 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.test @@ -0,0 +1,103 @@ +== 001 +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"procedure","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"create function test1() returns int\n begin atomic\n select 2 + 2;\n end","parseMode":0}}}},{"PLpgSQL_stmt_execsql":{"lineno":8,"sqlstmt":{"PLpgSQL_expr":{"query":"create or replace procedure test2(x int)\n begin atomic\n select x + 2;\n end","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 002 +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +-- +[] +== 003 +do $$ declare x foo%type; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"foo%type"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 004 +do $$ declare x notice%type; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"notice%type"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 005 +-- covers unreserved-keyword case +do $$ declare x foo.bar%type; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"foo.bar%type"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 006 +do $$ declare x foo.bar.baz%type; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"foo.bar.baz%type"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 007 +do $$ declare x public.foo.bar%type; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"public.foo.bar%type"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 008 +do $$ declare x public.misc_table.zed%type; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"public.misc_table.zed%type"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 009 +do $$ declare x foo%rowtype; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"foo%rowtype"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 010 +do $$ declare x notice%rowtype; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"notice%rowtype"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 011 +-- covers unreserved-keyword case +do $$ declare x foo.bar%rowtype; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"foo.bar%rowtype"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 012 +do $$ declare x foo.bar.baz%rowtype; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"foo.bar.baz%rowtype"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 013 +do $$ declare x public.foo%rowtype; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"public.foo%rowtype"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 014 +do $$ declare x public.misc_table%rowtype; begin end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"public.misc_table%rowtype"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json new file mode 100644 index 0000000..780860b --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json @@ -0,0 +1,162 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.test new file mode 100644 index 0000000..e63c9e5 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.test @@ -0,0 +1,1136 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +-- +[] +== 002 +create type more_int4s as (f0 text, f1 int4, f2 int4) +-- +[] +== 003 +create type two_int8s as (q1 int8, q2 int8) +-- +[] +== 004 +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +-- +[] +== 005 +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1)::two_int8s; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"row($1,1)::two_int8s","parseMode":2}}}}]}}}} +] +== 006 +select retc(42) +-- +[] +== 007 +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8); end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"row($1::int8, 1::int8)","parseMode":2}}}}]}}}} +] +== 008 +select retc(42) +-- +[] +== 009 +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1); end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"row($1,1)","parseMode":2}}}}]}}}} +] +== 010 +select retc(42) +-- +[] +== 011 +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8, 42); end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"row($1::int8, 1::int8, 42)","parseMode":2}}}}]}}}} +] +== 012 +select retc(42) +-- +[] +== 013 +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_assign":{"lineno":1,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := row($1::int8, 1::int8)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 014 +select retc(42) +-- +[] +== 015 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,1); return r; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_assign":{"lineno":1,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := row($1,1)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 016 +select retc(42) +-- +[] +== 017 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_assign":{"lineno":1,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := row($1::int8, 1::int8, 42)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 018 +select retc(42) +-- +[] +== 019 +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_assign":{"lineno":1,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := row($1::int8, 1::int8, 42)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 020 +select retc(42) +-- +[] +== 021 +do $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"c","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":1,"expr":{"PLpgSQL_expr":{"query":"c := row(1,2)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"c = %","params":[{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 022 +do $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"c","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":2,"fields":[{"name":"c","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fors":{"lineno":2,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":2,"fields":[{"name":"c","varno":1}]}},"body":[{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"c = %","params":[{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"select 1,2","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 023 +do $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"c4","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"two_int4s"}}}},{"PLpgSQL_var":{"refname":"c8","lineno":1,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":2,"expr":{"PLpgSQL_expr":{"query":"c8 := row(1,2)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"c4 := c8","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":2,"expr":{"PLpgSQL_expr":{"query":"c8 := c4","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"c4 = %","params":[{"PLpgSQL_expr":{"query":"c4","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"c8 = %","params":[{"PLpgSQL_expr":{"query":"c8","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 024 +do $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +-- +ERROR: "c.q1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 5" +== 025 +-- block-qualified naming +do $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +-- +ERROR: "b.c.q1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 5" +== 026 +-- error cases +do $$ declare c two_int8s; begin c.x = 1; end $$ +-- +ERROR: "c.x" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 027 +do $$ declare c nested_int8s; begin c.x = 1; end $$ +-- +ERROR: "c.x" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 028 +do $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +-- +ERROR: "c.x.q1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 029 +do $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +-- +ERROR: "c.c2.x" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 030 +do $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +-- +ERROR: "d.c2.x" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 031 +do $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +-- +ERROR: "b.c.x" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 032 +do $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +-- +ERROR: "b.c.x" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 033 +do $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +-- +ERROR: "b.c.x" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 034 +do $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +-- +ERROR: "b.c.c2" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 035 +do $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +-- +ERROR: "b.d.c2" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 1" +== 036 +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := $1","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"r.q1","parseMode":2}}}}]}}}} +] +== 037 +select getq1(retc(344)) +-- +[] +== 038 +select getq1(row(1,2)) +-- +[] +== 039 +do $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r1","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}},{"PLpgSQL_rec":{"refname":"r2","dno":2,"lineno":2}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int8"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"r1 := retc(345)","parseMode":3}}}},{"PLpgSQL_stmt_perform":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"SELECT getq1(r1)","parseMode":0}}}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":3,"expr":{"PLpgSQL_expr":{"query":"x := getq1(r1)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":8,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r2 := retc(346)","parseMode":3}}}},{"PLpgSQL_stmt_perform":{"lineno":9,"expr":{"PLpgSQL_expr":{"query":"SELECT getq1(r2)","parseMode":0}}}},{"PLpgSQL_stmt_assign":{"lineno":10,"varno":3,"expr":{"PLpgSQL_expr":{"query":"x := getq1(r2)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":11,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 040 +-- check assignments of composites +do $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +-- +ERROR: "r2.q2" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 10" +== 041 +-- fields of named-type vars read as null if uninitialized +do $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r1","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"r1 = %","params":[{"PLpgSQL_expr":{"query":"r1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"r1.q1 = %","params":[{"PLpgSQL_expr":{"query":"r1.q1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"r1.q2 = %","params":[{"PLpgSQL_expr":{"query":"r1.q2","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"r1 = %","params":[{"PLpgSQL_expr":{"query":"r1","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 042 +do $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r1","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"r1.q1 = %","params":[{"PLpgSQL_expr":{"query":"r1.q1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"r1.q2 = %","params":[{"PLpgSQL_expr":{"query":"r1.q2","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"r1 = %","params":[{"PLpgSQL_expr":{"query":"r1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"r1.nosuchfield = %","params":[{"PLpgSQL_expr":{"query":"r1.nosuchfield","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 043 +-- records, not so much +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r1","dno":1,"lineno":2}},{"PLpgSQL_recfield":{"fieldname":"f1","recparentno":1}},{"PLpgSQL_recfield":{"fieldname":"f2","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"r1 = %","params":[{"PLpgSQL_expr":{"query":"r1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"r1.f1 = %","params":[{"PLpgSQL_expr":{"query":"r1.f1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"r1.f2 = %","params":[{"PLpgSQL_expr":{"query":"r1.f2","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"r1 = %","params":[{"PLpgSQL_expr":{"query":"r1","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 044 +-- but OK if you assign first +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r1","dno":1,"lineno":2}},{"PLpgSQL_recfield":{"fieldname":"f1","recparentno":1}},{"PLpgSQL_recfield":{"fieldname":"f2","recparentno":1}},{"PLpgSQL_recfield":{"fieldname":"nosuchfield","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"r1 = %","params":[{"PLpgSQL_expr":{"query":"r1","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"r1 := row(1,2)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"r1.f1 = %","params":[{"PLpgSQL_expr":{"query":"r1.f1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"r1.f2 = %","params":[{"PLpgSQL_expr":{"query":"r1.f2","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"r1 = %","params":[{"PLpgSQL_expr":{"query":"r1","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":18,"message":"r1.nosuchfield = %","params":[{"PLpgSQL_expr":{"query":"r1.nosuchfield","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 045 +-- check %type with block-qualified variable names +do $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"v","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"r","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}},{"PLpgSQL_var":{"refname":"v1","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"v%type"}}}},{"PLpgSQL_var":{"refname":"v2","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"blk.v%type"}}}},{"PLpgSQL_var":{"refname":"r1","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"r%type"}}}},{"PLpgSQL_var":{"refname":"r2","lineno":9,"datatype":{"PLpgSQL_type":{"typname":"blk.r%type"}}}}],"action":{"PLpgSQL_stmt_block":{"body":[{"PLpgSQL_stmt_block":{"lineno":10,"label":"blk","body":[{"PLpgSQL_stmt_raise":{"lineno":11,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v1)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(v2)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":13,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(r1)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":14,"elog_level":18,"message":"%","params":[{"PLpgSQL_expr":{"query":"pg_typeof(r2)","parseMode":2}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 046 +-- check that type record can be passed through %type +do $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r1","dno":1,"lineno":2}},{"PLpgSQL_var":{"refname":"r2","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"r1%type"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_assign":{"lineno":5,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r2 := row(1,2)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"r2 = %","params":[{"PLpgSQL_expr":{"query":"r2","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r2 := row(3,4,5)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"r2 = %","params":[{"PLpgSQL_expr":{"query":"r2","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 047 +-- arrays of record are not supported at the moment +do $$ +declare r1 record[]; +begin +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r1","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"record[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 048 +do $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r1","dno":1,"lineno":2}},{"PLpgSQL_var":{"refname":"r2","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"r1%type[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_return":{}}]}}}} +] +== 049 +-- check repeated assignments to composite fields +create table some_table (id int, data text) +-- +[] +== 050 +do $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +-- +ERROR: "r.id" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 5" +== 051 +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1); end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"row($1,$1+1)","parseMode":2}}}}]}}}} +] +== 052 +select returnsrecord(42) +-- +[] +== 053 +select * from returnsrecord(42) as r(x int, y int) +-- +[] +== 054 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +[] +== 055 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +[] +== 056 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1); return r; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_assign":{"lineno":1,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := row($1,$1+1)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 057 +select returnsrecord(42) +-- +[] +== 058 +select * from returnsrecord(42) as r(x int, y int) +-- +[] +== 059 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +[] +== 060 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +[] +== 061 +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +-- +[] +== 062 +alter table has_hole drop column f2 +-- +[] +== 063 +create or replace function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1)::has_hole; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"row($1,$1+1)::has_hole","parseMode":2}}}}]}}}} +] +== 064 +select returnsrecord(42) +-- +[] +== 065 +select * from returnsrecord(42) as r(x int, y int) +-- +[] +== 066 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +[] +== 067 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +[] +== 068 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_assign":{"lineno":1,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := row($1,$1+1)::has_hole","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 069 +select returnsrecord(42) +-- +[] +== 070 +select * from returnsrecord(42) as r(x int, y int) +-- +[] +== 071 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +[] +== 072 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +[] +== 073 +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$$ begin return x.f1; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"record"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"x.f1","parseMode":2}}}}]}}}} +] +== 074 +select getf1(1) +-- +[] +== 075 +select getf1(row(1,2)) +-- +[] +== 076 +select getf1(row(1,2)::two_int4s) +-- +[] +== 077 +select getf1(row('foo',123,456)::more_int4s) +-- +[] +== 078 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row(1,2)::two_int8s) +-- +[] +== 079 +select getf1(row(1,2)) +-- +[] +== 080 +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$$ begin return $1.f2; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"record"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"$1.f2","parseMode":2}}}}]}}}} +] +== 081 +select getf2(row(1,2)) +-- +[] +== 082 +-- ideally would work, but does not +select getf2(row(1,2)::two_int4s) +-- +[] +== 083 +select getf2(row('foo',123,456)::more_int4s) +-- +[] +== 084 +-- check behavior when assignment to FOR-loop variable requires coercion +do $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"r","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fors":{"lineno":4,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"r","varno":1}]}},"body":[{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"r = %","params":[{"PLpgSQL_expr":{"query":"r","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"select i, i+1 from generate_series(1,4) i","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 085 +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":2}},{"PLpgSQL_var":{"refname":"h","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"has_hole"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_return_next":{"lineno":5}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"r := (1,2)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"h := (3,4)","parseMode":3}}}},{"PLpgSQL_stmt_return_next":{"lineno":8}},{"PLpgSQL_stmt_return_next":{"lineno":9}},{"PLpgSQL_stmt_return_next":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"row(5,6)","parseMode":2}}}},{"PLpgSQL_stmt_return_next":{"lineno":11,"expr":{"PLpgSQL_expr":{"query":"row(7,8)::has_hole","parseMode":2}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 086 +select returnssetofholes() +-- +[] +== 087 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_return_next":{"lineno":4}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 088 +select returnssetofholes() +-- +[] +== 089 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +begin + return next row(1,2,3); -- fails +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return_next":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"row(1,2,3)","parseMode":2}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 090 +select returnssetofholes() +-- +[] +== 091 +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +-- +[] +== 092 +create function sillyaddone(int) returns int language plpgsql as +$$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +ERROR: "r.f1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"sillyaddone\" near line 1" +== 093 +select sillyaddone(42) +-- +[] +== 094 +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +-- +[] +== 095 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone(42) +-- +[] +== 096 +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$$ begin return x.f3; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"mutable"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"x.f3","parseMode":2}}}}]}}}} +] +== 097 +select getf3(null::mutable) +-- +[] +== 098 +-- doesn't work yet +alter table mutable add column f3 int +-- +[] +== 099 +select getf3(null::mutable) +-- +[] +== 100 +-- now it works +alter table mutable drop column f3 +-- +[] +== 101 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3(null::mutable) +-- +[] +== 102 +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off +-- +[] +== 103 +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +-- +ERROR: "r.f1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"sillyaddtwo\" near line 1" +== 104 +reset check_function_bodies +-- +[] +== 105 +select sillyaddtwo(42) +-- +[] +== 106 +-- fail +create table mutable2(f1 int, f2 text) +-- +[] +== 107 +select sillyaddtwo(42) +-- +[] +== 108 +drop table mutable2 +-- +[] +== 109 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo(42) +-- +[] +== 110 +-- fail +create table mutable2(f0 text, f1 int, f2 text) +-- +[] +== 111 +select sillyaddtwo(42) +-- +[] +== 112 +select sillyaddtwo(43) +-- +[] +== 113 +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_recfield":{"fieldname":"ctid","recparentno":2}},{"PLpgSQL_recfield":{"fieldname":"tableoid","recparentno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"old.ctid = %","params":[{"PLpgSQL_expr":{"query":"old.ctid","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"old.tableoid = %","params":[{"PLpgSQL_expr":{"query":"old.tableoid::regclass","parseMode":2}}]}},{"PLpgSQL_stmt_return":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"new","parseMode":2}}}}]}}}} +] +== 114 +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +-- +[] +== 115 +insert into mutable values ('foo'), ('bar') +-- +[] +== 116 +update mutable set f2 = f2 || ' baz' +-- +[] +== 117 +table mutable +-- +[] +== 118 +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$$begin + return row(new.*); +end$$ +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"row(new.*)","parseMode":2}}}}]}}}} +] +== 119 +update mutable set f2 = f2 || ' baz' +-- +[] +== 120 +table mutable +-- +[] +== 121 +create or replace function sillytrig() returns trigger language plpgsql as +$$declare r record; +begin + r := row(new.*); + return r; +end$$ +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_rec":{"refname":"r","dno":3,"lineno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":3,"expr":{"PLpgSQL_expr":{"query":"r := row(new.*)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 122 +update mutable set f2 = f2 || ' baz' +-- +[] +== 123 +table mutable +-- +[] +== 124 +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +-- +[] +== 125 +create function read_ordered_int8s(p ordered_int8s) returns int8 as $$ +begin return p.q1 + p.q2; end +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"p","datatype":{"PLpgSQL_type":{"typname":"ordered_int8s"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"p.q1 + p.q2","parseMode":2}}}}]}}}} +] +== 126 +select read_ordered_int8s(row(1, 2)) +-- +[] +== 127 +select read_ordered_int8s(row(2, 1)) +-- +[] +== 128 +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $$ +begin return row(i,j); end +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"i","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"j","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"row(i,j)","parseMode":2}}}}]}}}} +] +== 129 +select build_ordered_int8s(1,2) +-- +[] +== 130 +select build_ordered_int8s(2,1) +-- +[] +== 131 +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $$ +declare r record; begin r := row(i,j); return r; end +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"i","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"j","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":3,"lineno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":3,"expr":{"PLpgSQL_expr":{"query":"r := row(i,j)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 132 +select build_ordered_int8s_2(1,2) +-- +[] +== 133 +select build_ordered_int8s_2(2,1) +-- +[] +== 134 +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"i","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"j","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"two_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":3,"expr":{"PLpgSQL_expr":{"query":"r := row(i,j)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 135 +select build_ordered_int8s_3(1,2) +-- +[] +== 136 +select build_ordered_int8s_3(2,1) +-- +[] +== 137 +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"i","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"j","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"ordered_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":2,"varno":3,"expr":{"PLpgSQL_expr":{"query":"r := row(i,j)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 138 +select build_ordered_int8s_4(1,2) +-- +[] +== 139 +select build_ordered_int8s_4(2,1) +-- +[] +== 140 +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"i","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"j","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"array[row(i,j), row(i,j+1)]","parseMode":2}}}}]}}}} +] +== 141 +select build_ordered_int8s_a(1,2) +-- +[] +== 142 +select build_ordered_int8s_a(2,1) +-- +[] +== 143 +-- fail + +-- check field assignment +do $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +-- +ERROR: "r.q1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 144 +-- check whole-row assignment +do $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"ordered_int8s"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"r := null","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"r := row(null,null)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"r := row(1,2)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":1,"expr":{"PLpgSQL_expr":{"query":"r := row(2,1)","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 145 +-- check assignment in for-loop +do $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"ordered_int8s"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"r","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fors":{"lineno":4,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"r","varno":1}]}},"body":[{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"r = %","params":[{"PLpgSQL_expr":{"query":"r","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"values (1,2),(3,4),(6,5)","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 146 +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +-- +[] +== 147 +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +-- +[] +== 148 +create table sometable (id int, a text, b text) +-- +[] +== 149 +-- b should be compressed, but in-line +insert into sometable values (1, 'a', repeat('ffoob',1000)) +-- +[] +== 150 +-- this b should be out-of-line +insert into sometable values (2, 'a', repeat('ffoob',100000)) +-- +[] +== 151 +-- this pair should fail the domain check +insert into sometable values (3, 'z', repeat('ffoob',100000)) +-- +[] +== 152 +do $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"d","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"ordered_texts"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"d","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fors":{"lineno":4,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"d","varno":1}]}},"body":[{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"succeeded at \"%\"","params":[{"PLpgSQL_expr":{"query":"d.f1","parseMode":2}}]}}],"query":{"PLpgSQL_expr":{"query":"select a, b from sometable","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 153 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":2}},{"PLpgSQL_var":{"refname":"d","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"ordered_texts"}}}},{"PLpgSQL_recfield":{"fieldname":"id","recparentno":1}},{"PLpgSQL_recfield":{"fieldname":"a","recparentno":1}},{"PLpgSQL_recfield":{"fieldname":"b","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fors":{"lineno":4,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":5,"elog_level":18,"message":"processing row %","params":[{"PLpgSQL_expr":{"query":"r.id","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":2,"expr":{"PLpgSQL_expr":{"query":"d := row(r.a, r.b)","parseMode":3}}}}],"query":{"PLpgSQL_expr":{"query":"select * from sometable","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 154 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +-- +ERROR: "d.f1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 6" +== 155 +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_assign":{"lineno":1,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := row($1,$1)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"r","parseMode":2}}}}]}}}} +] +== 156 +create table two_int8s_tab (f1 two_int8s) +-- +[] +== 157 +insert into two_int8s_tab values (compresult(42)) +-- +[] +== 158 +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json new file mode 100644 index 0000000..5d34ab7 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json @@ -0,0 +1,28 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.test new file mode 100644 index 0000000..fdc29c8 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.test @@ -0,0 +1,186 @@ +== 001 +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as 'select $1' +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 002 +create function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sum","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}},{"PLpgSQL_var":{"refname":"n","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fori":{"lineno":5,"var":{"PLpgSQL_var":{"refname":"n","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"sum := sum + simplesql(n)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":7,"cond":{"PLpgSQL_expr":{"query":"n = 5","parseMode":2}},"then_body":[{"PLpgSQL_stmt_execsql":{"lineno":8,"sqlstmt":{"PLpgSQL_expr":{"query":"create or replace function simplesql(int) returns int language sql\n as 'select $1 + 100'","parseMode":0}}}}]}}]}},{"PLpgSQL_stmt_return":{"lineno":12,"expr":{"PLpgSQL_expr":{"query":"sum","parseMode":2}}}}]}}}} +] +== 003 +select simplecaller() +-- +[] +== 004 +-- Check that changes in search path are dealt with correctly +create schema simple1 +-- +[] +== 005 +create function simple1.simpletarget(int) returns int language plpgsql +as $$begin return $1; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"$1","parseMode":2}}}}]}}}} +] +== 006 +create function simpletarget(int) returns int language plpgsql +as $$begin return $1 + 100; end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":1,"expr":{"PLpgSQL_expr":{"query":"$1 + 100","parseMode":2}}}}]}}}} +] +== 007 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sum","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}},{"PLpgSQL_var":{"refname":"n","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fori":{"lineno":5,"var":{"PLpgSQL_var":{"refname":"n","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"sum := sum + simpletarget(n)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":7,"cond":{"PLpgSQL_expr":{"query":"n = 5","parseMode":2}},"then_body":[{"PLpgSQL_stmt_execsql":{"lineno":8,"sqlstmt":{"PLpgSQL_expr":{"query":"set local search_path = 'simple1'","parseMode":0}}}}]}}]}},{"PLpgSQL_stmt_return":{"lineno":11,"expr":{"PLpgSQL_expr":{"query":"sum","parseMode":2}}}}]}}}} +] +== 008 +select simplecaller() +-- +[] +== 009 +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +-- +[] +== 010 +alter function simpletarget(int) immutable +-- +[] +== 011 +select simplecaller() +-- +[] +== 012 +-- make sure flushing local caches changes nothing + +select simplecaller() +-- +[] +== 013 +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $$select 1 / 0$$ +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 014 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"x","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"select simplesql()","parseMode":0}},"into":true,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"x","varno":1}]}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}]}}}} +] +== 015 +select simplecaller() +-- +[] +== 016 +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $$select 2 + 2$$ +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 017 +select simplecaller() +-- +[] +== 018 +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := simplesql()","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}]}}}} +] +== 019 +select simplecaller() +-- +[] +== 020 +drop function simplesql() +-- +[] +== 021 +create function simplesql() returns setof int language sql +as $$select 22 + 22$$ +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 022 +select simplecaller() +-- +[] +== 023 +select simplecaller() +-- +[] +== 024 +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"p_curdata","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"refcursor"}}}},{"PLpgSQL_var":{"refname":"val","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":7,"fields":[{"name":"val","varno":2}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_open":{"lineno":6,"curvar":1,"cursor_options":258,"query":{"PLpgSQL_expr":{"query":"select 42","parseMode":0}}}},{"PLpgSQL_stmt_fetch":{"lineno":7,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":7,"fields":[{"name":"val","varno":2}]}},"curvar":1,"direction":0,"how_many":1}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"val = %","params":[{"PLpgSQL_expr":{"query":"val","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json new file mode 100644 index 0000000..17a73dc --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json @@ -0,0 +1,121 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.test new file mode 100644 index 0000000..a26ac63 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.test @@ -0,0 +1,933 @@ +== 001 +CREATE TABLE test1 (a int, b text) +-- +[] +== 002 +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"y","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"0","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"x","parseMode":2}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a, b) VALUES (i, y)","parseMode":0}}}},{"PLpgSQL_stmt_if":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"i % 2 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_commit":{"lineno":6}}],"else_body":[{"PLpgSQL_stmt_rollback":{"lineno":8}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 003 +CALL transaction_test1(9, 'foo') +-- +[] +== 004 +SELECT * FROM test1 +-- +[] +== 005 +TRUNCATE test1 +-- +[] +== 006 +DO +LANGUAGE plpgsql +$$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"0","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"9","parseMode":2}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (i)","parseMode":0}}}},{"PLpgSQL_stmt_if":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"i % 2 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_commit":{"lineno":6}}],"else_body":[{"PLpgSQL_stmt_rollback":{"lineno":8}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 007 +SELECT * FROM test1 +-- +[] +== 008 +-- transaction commands not allowed when called in transaction block +START TRANSACTION +-- +[] +== 009 +CALL transaction_test1(9, 'error') +-- +[] +== 010 +COMMIT +-- +[] +== 011 +START TRANSACTION +-- +[] +== 012 +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_commit":{"lineno":1}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 013 +COMMIT +-- +[] +== 014 +TRUNCATE test1 +-- +[] +== 015 +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"0","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"9","parseMode":2}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (i)","parseMode":0}}}},{"PLpgSQL_stmt_if":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"i % 2 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_commit":{"lineno":6}}],"else_body":[{"PLpgSQL_stmt_rollback":{"lineno":8}}]}}]}},{"PLpgSQL_stmt_return":{"lineno":11,"expr":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}}]}}}} +] +== 016 +SELECT transaction_test2() +-- +[] +== 017 +SELECT * FROM test1 +-- +[] +== 018 +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_call":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"CALL transaction_test1(9, 'error')","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}}]}}}} +] +== 019 +SELECT transaction_test3() +-- +[] +== 020 +SELECT * FROM test1 +-- +[] +== 021 +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_dynexecute":{"lineno":3,"query":{"PLpgSQL_expr":{"query":"'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'","parseMode":2}}}},{"PLpgSQL_stmt_return":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}}]}}}} +] +== 022 +SELECT transaction_test4() +-- +[] +== 023 +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = 555 +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_commit":{"lineno":3}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 024 +CALL transaction_test5() +-- +[] +== 025 +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_commit":{"lineno":3}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 026 +CALL transaction_test5b() +-- +[] +== 027 +TRUNCATE test1 +-- +[] +== 028 +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"c","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_call":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"CALL transaction_test1(9, c)","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 029 +CALL transaction_test6('bar') +-- +[] +== 030 +SELECT * FROM test1 +-- +[] +== 031 +TRUNCATE test1 +-- +[] +== 032 +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_call":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 033 +CALL transaction_test7() +-- +[] +== 034 +SELECT * FROM test1 +-- +[] +== 035 +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_dynexecute":{"lineno":3,"query":{"PLpgSQL_expr":{"query":"'CALL transaction_test1(10, $x$baz$x$)'","parseMode":2}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 036 +CALL transaction_test8() +-- +[] +== 037 +-- commit inside cursor loop +CREATE TABLE test2 (x int) +-- +[] +== 038 +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +-- +[] +== 039 +TRUNCATE test1 +-- +[] +== 040 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},{"PLpgSQL_recfield":{"fieldname":"x","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fors":{"lineno":5,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (r.x)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":7}}],"query":{"PLpgSQL_expr":{"query":"SELECT * FROM test2 ORDER BY x","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 041 +SELECT * FROM test1 +-- +[] +== 042 +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +-- +[] +== 043 +-- error in cursor loop with commit +TRUNCATE test1 +-- +[] +== 044 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},{"PLpgSQL_recfield":{"fieldname":"x","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fors":{"lineno":5,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (12/(r.x-2))","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":7}}],"query":{"PLpgSQL_expr":{"query":"SELECT * FROM test2 ORDER BY x","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 045 +SELECT * FROM test1 +-- +[] +== 046 +SELECT * FROM pg_cursors +-- +[] +== 047 +-- rollback inside cursor loop +TRUNCATE test1 +-- +[] +== 048 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},{"PLpgSQL_recfield":{"fieldname":"x","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fors":{"lineno":5,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (r.x)","parseMode":0}}}},{"PLpgSQL_stmt_rollback":{"lineno":7}}],"query":{"PLpgSQL_expr":{"query":"SELECT * FROM test2 ORDER BY x","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 049 +SELECT * FROM test1 +-- +[] +== 050 +SELECT * FROM pg_cursors +-- +[] +== 051 +-- first commit then rollback inside cursor loop +TRUNCATE test1 +-- +[] +== 052 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},{"PLpgSQL_recfield":{"fieldname":"x","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fors":{"lineno":5,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (r.x)","parseMode":0}}}},{"PLpgSQL_stmt_if":{"lineno":7,"cond":{"PLpgSQL_expr":{"query":"r.x % 2 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_commit":{"lineno":8}}],"else_body":[{"PLpgSQL_stmt_rollback":{"lineno":10}}]}}],"query":{"PLpgSQL_expr":{"query":"SELECT * FROM test2 ORDER BY x","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 053 +SELECT * FROM test1 +-- +[] +== 054 +SELECT * FROM pg_cursors +-- +[] +== 055 +-- rollback inside cursor loop +TRUNCATE test1 +-- +[] +== 056 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},{"PLpgSQL_recfield":{"fieldname":"x","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fors":{"lineno":5,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":3}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (r.x)","parseMode":0}}}},{"PLpgSQL_stmt_rollback":{"lineno":7}}],"query":{"PLpgSQL_expr":{"query":"UPDATE test2 SET x = x * 2 RETURNING x","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 057 +SELECT * FROM test1 +-- +[] +== 058 +SELECT * FROM test2 +-- +[] +== 059 +SELECT * FROM pg_cursors +-- +[] +== 060 +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +-- +[] +== 061 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +[] +== 062 +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"l_cur","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.refcursor"}},"cursor_explicit_expr":{"PLpgSQL_expr":{"query":"SELECT a FROM test1 ORDER BY 1 FOR UPDATE","parseMode":0}},"cursor_explicit_argrow":-1,"cursor_options":256}},{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":5}},{"PLpgSQL_recfield":{"fieldname":"a","recparentno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_forc":{"lineno":5,"var":{"PLpgSQL_rec":{"refname":"r","dno":2,"lineno":5}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE test1 SET b = b || ' ' || b WHERE a = r.a","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":7}}],"curvar":1}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 063 +SELECT * FROM test1 +-- +[] +== 064 +SELECT * FROM pg_cursors +-- +[] +== 065 +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +-- +[] +== 066 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +[] +== 067 +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":2}},{"PLpgSQL_recfield":{"fieldname":"a","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fors":{"lineno":4,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":2}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE test1 SET b = b || ' ' || b WHERE a = r.a","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":6}}],"query":{"PLpgSQL_expr":{"query":"SELECT a FROM test1 FOR UPDATE","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 068 +SELECT * FROM test1 +-- +[] +== 069 +SELECT * FROM pg_cursors +-- +[] +== 070 +-- commit inside block with exception handler +TRUNCATE test1 +-- +[] +== 071 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (1)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":5}},{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (1/0)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":7}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"division_by_zero"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"caught division_by_zero"}}]}}]}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 072 +SELECT * FROM test1 +-- +[] +== 073 +-- rollback inside block with exception handler +TRUNCATE test1 +-- +[] +== 074 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (1)","parseMode":0}}}},{"PLpgSQL_stmt_rollback":{"lineno":5}},{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (1/0)","parseMode":0}}}},{"PLpgSQL_stmt_rollback":{"lineno":7}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"division_by_zero"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"caught division_by_zero"}}]}}]}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 075 +SELECT * FROM test1 +-- +[] +== 076 +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +-- +[] +== 077 +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"10","parseMode":2}},"body":[{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 VALUES (i, 'good')","parseMode":0}}}},{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 VALUES (i/0, 'bad')","parseMode":0}}}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"division_by_zero"}}],"action":[{"PLpgSQL_stmt_execsql":{"lineno":9,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 VALUES (i, 'exception')","parseMode":0}}}},{"PLpgSQL_stmt_if":{"lineno":10,"cond":{"PLpgSQL_expr":{"query":"(i % 3) \u003e 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_commit":{"lineno":10}}],"else_body":[{"PLpgSQL_stmt_rollback":{"lineno":10}}]}}]}}]}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 078 +SELECT * FROM test1 +-- +[] +== 079 +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +-- +[] +== 080 +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +-- +[] +== 081 +-- disable compression +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +-- +[] +== 082 +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS 'select f1 from test4' IMMUTABLE +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 083 +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"i","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fori":{"lineno":4,"var":{"PLpgSQL_var":{"refname":"i","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := data_source(i)","parseMode":3}}}},{"PLpgSQL_stmt_commit":{"lineno":6}}]}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"length(x) = %","params":[{"PLpgSQL_expr":{"query":"length(x)","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 084 +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"c","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"test1 "}},"default_val":{"PLpgSQL_expr":{"query":"row(42, 'hello')","parseMode":2}}}},{"PLpgSQL_var":{"refname":"r","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"bool"}}}},{"PLpgSQL_var":{"refname":"i","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":11,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_fori":{"lineno":6,"var":{"PLpgSQL_var":{"refname":"i","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := c is not null","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"r = %","params":[{"PLpgSQL_expr":{"query":"r","parseMode":2}}]}},{"PLpgSQL_stmt_commit":{"lineno":9}}]}},{"PLpgSQL_stmt_fori":{"lineno":11,"var":{"PLpgSQL_var":{"refname":"i","lineno":11,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":12,"varno":2,"expr":{"PLpgSQL_expr":{"query":"r := c is null","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":13,"elog_level":18,"message":"r = %","params":[{"PLpgSQL_expr":{"query":"r","parseMode":2}}]}},{"PLpgSQL_stmt_rollback":{"lineno":14}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 085 +-- COMMIT failures +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":4}},{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test3 (y) VALUES (1)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":6}},{"PLpgSQL_stmt_execsql":{"lineno":7,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test3 (y) VALUES (1)","parseMode":0}}}},{"PLpgSQL_stmt_execsql":{"lineno":8,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test3 (y) VALUES (2)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":9}},{"PLpgSQL_stmt_execsql":{"lineno":10,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test3 (y) VALUES (3)","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 086 +SELECT * FROM test3 +-- +[] +== 087 +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"id","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"id","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fors":{"lineno":4,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"id","varno":1}]}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 VALUES(id)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":6}}],"query":{"PLpgSQL_expr":{"query":"SELECT 1/(x-1000) FROM generate_series(1,1000) x","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 088 +TRUNCATE test1 +-- +[] +== 089 +CALL cursor_fail_during_commit() +-- +[] +== 090 +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +-- +[] +== 091 +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"id","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"id","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_fors":{"lineno":4,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":4,"fields":[{"name":"id","varno":1}]}},"body":[{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 VALUES(id)","parseMode":0}}}},{"PLpgSQL_stmt_rollback":{"lineno":6}}],"query":{"PLpgSQL_expr":{"query":"SELECT 1/(x-1000) FROM generate_series(1,1000) x","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 092 +TRUNCATE test1 +-- +[] +== 093 +CALL cursor_fail_during_rollback() +-- +[] +== 094 +SELECT count(*) FROM test1 +-- +[] +== 095 +-- SET TRANSACTION +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_perform":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"SELECT 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":17,"message":"%","params":[{"PLpgSQL_expr":{"query":"current_setting('transaction_isolation')","parseMode":2}}]}},{"PLpgSQL_stmt_commit":{"lineno":5}},{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"SET TRANSACTION ISOLATION LEVEL REPEATABLE READ","parseMode":0}}}},{"PLpgSQL_stmt_perform":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"SELECT 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":17,"message":"%","params":[{"PLpgSQL_expr":{"query":"current_setting('transaction_isolation')","parseMode":2}}]}},{"PLpgSQL_stmt_commit":{"lineno":9}},{"PLpgSQL_stmt_execsql":{"lineno":10,"sqlstmt":{"PLpgSQL_expr":{"query":"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE","parseMode":0}}}},{"PLpgSQL_stmt_perform":{"lineno":11,"expr":{"PLpgSQL_expr":{"query":"SELECT 1","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":17,"message":"%","params":[{"PLpgSQL_expr":{"query":"current_setting('transaction_isolation')","parseMode":2}}]}},{"PLpgSQL_stmt_commit":{"lineno":13}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 096 +-- error cases +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"SET TRANSACTION ISOLATION LEVEL REPEATABLE READ","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 097 +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"SAVEPOINT foo","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 098 +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_dynexecute":{"lineno":3,"query":{"PLpgSQL_expr":{"query":"'COMMIT'","parseMode":2}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 099 +-- snapshot handling test +TRUNCATE test2 +-- +[] +== 100 +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$ +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 101 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_rollback":{"lineno":3}},{"PLpgSQL_stmt_call":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"CALL transaction_test9()","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 102 +SELECT * FROM test2 +-- +[] +== 103 +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $$ SELECT COUNT(*) FROM test2 $$ +-- +[ +{"PLpgSQL_function":{"datums":[]}} +] +== 104 +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"cnt","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"count = %","params":[{"PLpgSQL_expr":{"query":"cnt","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 105 +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_call":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"CALL transaction_test9b(report_count())","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test2 VALUES(43)","parseMode":0}}}},{"PLpgSQL_stmt_call":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"CALL transaction_test9b(report_count())","parseMode":0}},"is_call":true}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 106 +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"x := x + 1","parseMode":3}}}},{"PLpgSQL_stmt_commit":{"lineno":4}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 107 +CALL transaction_test10a(10) +-- +[] +== 108 +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"x","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"x := x - 1","parseMode":3}}}},{"PLpgSQL_stmt_rollback":{"lineno":4}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 109 +CALL transaction_test10b(10) +-- +[] +== 110 +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"s1","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"timestamp with time zone"}}}},{"PLpgSQL_var":{"refname":"s2","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"timestamp with time zone"}}}},{"PLpgSQL_var":{"refname":"s3","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"timestamp with time zone"}}}},{"PLpgSQL_var":{"refname":"t1","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"timestamp with time zone"}}}},{"PLpgSQL_var":{"refname":"t2","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"timestamp with time zone"}}}},{"PLpgSQL_var":{"refname":"t3","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"timestamp with time zone"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":9,"body":[{"PLpgSQL_stmt_assign":{"lineno":10,"varno":1,"expr":{"PLpgSQL_expr":{"query":"s1 := statement_timestamp()","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":11,"varno":4,"expr":{"PLpgSQL_expr":{"query":"t1 := transaction_timestamp()","parseMode":3}}}},{"PLpgSQL_stmt_assert":{"lineno":12,"cond":{"PLpgSQL_expr":{"query":"s1 = t1","parseMode":2}}}},{"PLpgSQL_stmt_perform":{"lineno":13,"expr":{"PLpgSQL_expr":{"query":"SELECT pg_sleep(0.001)","parseMode":0}}}},{"PLpgSQL_stmt_commit":{"lineno":14}},{"PLpgSQL_stmt_assign":{"lineno":15,"varno":2,"expr":{"PLpgSQL_expr":{"query":"s2 := statement_timestamp()","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":16,"varno":5,"expr":{"PLpgSQL_expr":{"query":"t2 := transaction_timestamp()","parseMode":3}}}},{"PLpgSQL_stmt_assert":{"lineno":17,"cond":{"PLpgSQL_expr":{"query":"s2 = s1","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":18,"cond":{"PLpgSQL_expr":{"query":"t2 \u003e t1","parseMode":2}}}},{"PLpgSQL_stmt_perform":{"lineno":19,"expr":{"PLpgSQL_expr":{"query":"SELECT pg_sleep(0.001)","parseMode":0}}}},{"PLpgSQL_stmt_rollback":{"lineno":20}},{"PLpgSQL_stmt_assign":{"lineno":21,"varno":3,"expr":{"PLpgSQL_expr":{"query":"s3 := statement_timestamp()","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":22,"varno":6,"expr":{"PLpgSQL_expr":{"query":"t3 := transaction_timestamp()","parseMode":3}}}},{"PLpgSQL_stmt_assert":{"lineno":23,"cond":{"PLpgSQL_expr":{"query":"s3 = s1","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":24,"cond":{"PLpgSQL_expr":{"query":"t3 \u003e t2","parseMode":2}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 111 +CALL transaction_test11() +-- +[] +== 112 +-- transaction chain + +TRUNCATE test1 +-- +[] +== 113 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_rollback":{"lineno":3}},{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"SET TRANSACTION ISOLATION LEVEL REPEATABLE READ","parseMode":0}}}},{"PLpgSQL_stmt_fori":{"lineno":5,"var":{"PLpgSQL_var":{"refname":"i","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"0","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":17,"message":"transaction_isolation = %","params":[{"PLpgSQL_expr":{"query":"current_setting('transaction_isolation')","parseMode":2}}]}},{"PLpgSQL_stmt_execsql":{"lineno":7,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO test1 (a) VALUES (i)","parseMode":0}}}},{"PLpgSQL_stmt_if":{"lineno":8,"cond":{"PLpgSQL_expr":{"query":"i % 2 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_commit":{"lineno":9,"chain":true}}],"else_body":[{"PLpgSQL_stmt_rollback":{"lineno":11,"chain":true}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 114 +SELECT * FROM test1 +-- +[] +== 115 +DROP TABLE test1 +-- +[] +== 116 +DROP TABLE test2 +-- +[] +== 117 +DROP TABLE test3 +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json new file mode 100644 index 0000000..6e8763d --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json @@ -0,0 +1,46 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.test new file mode 100644 index 0000000..cd3c220 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.test @@ -0,0 +1,305 @@ +== 001 +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"sx","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"smallint"}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":14,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":14,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"should see this"}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"x := 100 / $1","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":8,"elog_level":18,"message":"should see this only if % \u003c\u003e 0","params":[{"PLpgSQL_expr":{"query":"$1","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":9,"varno":3,"expr":{"PLpgSQL_expr":{"query":"sx := $1","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":18,"message":"should see this only if % fits in smallint","params":[{"PLpgSQL_expr":{"query":"$1","parseMode":2}}]}},{"PLpgSQL_stmt_if":{"lineno":11,"cond":{"PLpgSQL_expr":{"query":"$1 \u003c 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_raise":{"lineno":12,"elog_level":21,"message":"% is less than zero","params":[{"PLpgSQL_expr":{"query":"$1","parseMode":2}}]}}]}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"division_by_zero"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":16,"elog_level":18,"message":"caught division_by_zero"}},{"PLpgSQL_stmt_assign":{"lineno":17,"varno":2,"expr":{"PLpgSQL_expr":{"query":"x := -1","parseMode":3}}}}]}},{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"numeric_value_out_of_range"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":19,"elog_level":18,"message":"caught numeric_value_out_of_range"}},{"PLpgSQL_stmt_assign":{"lineno":20,"varno":2,"expr":{"PLpgSQL_expr":{"query":"x := -2","parseMode":3}}}}]}}]}}}},{"PLpgSQL_stmt_return":{"lineno":22,"expr":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}]}}}} +] +== 002 +select trap_zero_divide(50) +-- +[] +== 003 +select trap_zero_divide(0) +-- +[] +== 004 +select trap_zero_divide(100000) +-- +[] +== 005 +select trap_zero_divide(-100) +-- +[] +== 006 +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +-- +[] +== 007 +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"sx","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"smallint"}}}},{"PLpgSQL_var":{"refname":"y","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":9,"fields":[{"name":"y","varno":4}]}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":11,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":11,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_block":{"lineno":6,"body":[{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"x := 100 / $1","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":8,"varno":3,"expr":{"PLpgSQL_expr":{"query":"sx := $1","parseMode":3}}}},{"PLpgSQL_stmt_execsql":{"lineno":9,"sqlstmt":{"PLpgSQL_expr":{"query":"select data from match_source where id =\n\t\t\t(select id from match_source b where ten = $1)","parseMode":0}},"into":true,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":9,"fields":[{"name":"y","varno":4}]}}}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"data_exception"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":13,"elog_level":18,"message":"caught data_exception"}},{"PLpgSQL_stmt_assign":{"lineno":14,"varno":2,"expr":{"PLpgSQL_expr":{"query":"x := -1","parseMode":3}}}}]}},{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"numeric_value_out_of_range"}},{"PLpgSQL_condition":{"condname":"cardinality_violation"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":16,"elog_level":18,"message":"caught numeric_value_out_of_range or cardinality_violation"}},{"PLpgSQL_stmt_assign":{"lineno":17,"varno":2,"expr":{"PLpgSQL_expr":{"query":"x := -2","parseMode":3}}}}]}}]}}}},{"PLpgSQL_stmt_return":{"lineno":19,"expr":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}]}}}} +] +== 008 +select trap_matching_test(50) +-- +[] +== 009 +select trap_matching_test(0) +-- +[] +== 010 +select trap_matching_test(100000) +-- +[] +== 011 +select trap_matching_test(1) +-- +[] +== 012 +create temp table foo (f1 int) +-- +[] +== 013 +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":10,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":10,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := 1","parseMode":3}}}},{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"insert into foo values(x)","parseMode":0}}}},{"PLpgSQL_stmt_block":{"lineno":6,"body":[{"PLpgSQL_stmt_assign":{"lineno":7,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := x + 1","parseMode":3}}}},{"PLpgSQL_stmt_execsql":{"lineno":8,"sqlstmt":{"PLpgSQL_expr":{"query":"insert into foo values(x)","parseMode":0}}}},{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":21,"message":"inner"}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"others"}}],"action":[{"PLpgSQL_stmt_assign":{"lineno":12,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := x * 10","parseMode":3}}}}]}}]}}}},{"PLpgSQL_stmt_execsql":{"lineno":14,"sqlstmt":{"PLpgSQL_expr":{"query":"insert into foo values(x)","parseMode":0}}}},{"PLpgSQL_stmt_return":{"lineno":15,"expr":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}]}}}} +] +== 014 +select subxact_rollback_semantics() +-- +[] +== 015 +select * from foo +-- +[] +== 016 +drop table foo +-- +[] +== 017 +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":6,"fields":[{"name":"x","varno":1}]}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"select count(*) from generate_series(1, 1_000_000_000_000)","parseMode":0}},"into":true,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":6,"fields":[{"name":"x","varno":1}]}}}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"others"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":9,"elog_level":18,"message":"caught others?"}}]}},{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"query_canceled"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":11,"elog_level":18,"message":"nyeah nyeah, can't stop me"}}]}}]}}}},{"PLpgSQL_stmt_raise":{"lineno":15,"elog_level":21,"message":"end of function"}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 018 +begin +-- +[] +== 019 +set statement_timeout to 1000 +-- +[] +== 020 +select trap_timeout() +-- +[] +== 021 +rollback +-- +[] +== 022 +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":9,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":9,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := '1234'","parseMode":3}}}},{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := x || '5678'","parseMode":3}}}},{"PLpgSQL_stmt_perform":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"SELECT trap_zero_divide(-100)","parseMode":0}}}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"others"}}],"action":[{"PLpgSQL_stmt_assign":{"lineno":11,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := x || '9012'","parseMode":3}}}}]}}]}}}},{"PLpgSQL_stmt_return":{"lineno":13,"expr":{"PLpgSQL_expr":{"query":"x","parseMode":2}}}}]}}}} +] +== 023 +select test_variable_storage() +-- +[] +== 024 +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +-- +[] +== 025 +create temp table leaf(f1 int references root deferrable) +-- +[] +== 026 +insert into root values(1) +-- +[] +== 027 +insert into leaf values(1) +-- +[] +== 028 +insert into leaf values(2) +-- +[] +== 029 +-- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"insert into leaf values($1)","parseMode":0}}}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"foreign_key_violation"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"caught foreign_key_violation"}},{"PLpgSQL_stmt_return":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}]}}]}}}},{"PLpgSQL_stmt_return":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}}]}}}} +] +== 030 +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_execsql":{"lineno":4,"sqlstmt":{"PLpgSQL_expr":{"query":"set constraints all immediate","parseMode":0}}}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"foreign_key_violation"}}],"action":[{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"caught foreign_key_violation"}},{"PLpgSQL_stmt_return":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}]}}]}}}},{"PLpgSQL_stmt_return":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}}]}}}} +] +== 031 +select trap_foreign_key(1) +-- +[] +== 032 +select trap_foreign_key(2) +-- +[] +== 033 +-- detects FK violation + +begin +-- +[] +== 034 +set constraints all deferred +-- +[] +== 035 +select trap_foreign_key(2) +-- +[] +== 036 +-- should not detect FK violation + savepoint x +-- +[] +== 037 +set constraints all immediate +-- +[] +== 038 +-- fails + rollback to x +-- +[] +== 039 +select trap_foreign_key_2() +-- +[] +== 040 +-- detects FK violation +commit +-- +[] +== 041 +-- still fails + +drop function trap_foreign_key(int) +-- +[] +== 042 +drop function trap_foreign_key_2() +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json new file mode 100644 index 0000000..980156f --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json @@ -0,0 +1,10 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.test new file mode 100644 index 0000000..76890f9 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.test @@ -0,0 +1,39 @@ +== 001 +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +-- +[] +== 002 +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_recfield":{"fieldname":"a","recparentno":2}},{"PLpgSQL_recfield":{"fieldname":"a","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_raise":{"lineno":2,"elog_level":18,"message":"tg_op = %","params":[{"PLpgSQL_expr":{"query":"tg_op","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":3,"elog_level":18,"message":"old(%) = %","params":[{"PLpgSQL_expr":{"query":"old.a","parseMode":2}},{"PLpgSQL_expr":{"query":"row(old.*)","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"new(%) = %","params":[{"PLpgSQL_expr":{"query":"new.a","parseMode":2}},{"PLpgSQL_expr":{"query":"row(new.*)","parseMode":2}}]}},{"PLpgSQL_stmt_if":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"(tg_op = 'DELETE')","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"old","parseMode":2}}}}],"else_body":[{"PLpgSQL_stmt_return":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"new","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 003 +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +-- +[] +== 004 +insert into testtr values (1, 'one'), (2, 'two') +-- +[] +== 005 +update testtr set a = a + 1 +-- +[] +== 006 +delete from testtr +-- +[] diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json new file mode 100644 index 0000000..6a83420 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json @@ -0,0 +1,41 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.test b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.test new file mode 100644 index 0000000..0c2059f --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.test @@ -0,0 +1,400 @@ +== 001 +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +-- +[] +== 002 +create domain int_nn as int not null +-- +[] +== 003 +create domain var_record_nn as var_record not null +-- +[] +== 004 +create domain var_record_colnn as var_record check((value).f2 is not null) +-- +[] +== 005 +-- CONSTANT + +do $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"isconst":true,"default_val":{"PLpgSQL_expr":{"query":"42","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 006 +do $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +-- +ERROR: variable "x" is declared CONSTANT +FILENAME: pl_gram.y +FUNCNAME: check_assignable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 007 +do $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +ERROR: variable "x" is declared CONSTANT +FILENAME: pl_gram.y +FUNCNAME: check_assignable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 4" +== 008 +do $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +-- +ERROR: variable "x" is declared CONSTANT +FILENAME: pl_gram.y +FUNCNAME: check_assignable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 009 +do $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +-- +ERROR: syntax error at or near "[" +FILENAME: src_pl_plpgsql_src_pl_scanner.c +FUNCNAME: plpgsql_yyerror +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 4" +== 010 +do $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +-- +ERROR: "x.f1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 011 +do $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +ERROR: "x.f1" is not a known variable +FILENAME: pl_gram.y +FUNCNAME: cword_is_not_variable +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 012 +-- initializer expressions + +do $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"sin(0)","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 013 +do $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"1/0","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 014 +do $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"bigint[] "}},"default_val":{"PLpgSQL_expr":{"query":"array[1,3,5]","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 015 +do $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"x","dno":1,"lineno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 016 +do $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record "}},"default_val":{"PLpgSQL_expr":{"query":"row(1,2)","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 017 +-- NOT NULL + +do $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +ERROR: variable "x" must have a default value, since it's declared NOT NULL +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 018 +do $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"notnull":true,"default_val":{"PLpgSQL_expr":{"query":"42","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := null","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 019 +do $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int "}},"notnull":true,"default_val":{"PLpgSQL_expr":{"query":"null","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 020 +do $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +ERROR: variable "x" must have a default value, since it's declared NOT NULL +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 021 +do $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"x","dno":1,"lineno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := row(null)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := null","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 022 +do $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"x","dno":1,"lineno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 023 +do $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +ERROR: variable "x" must have a default value, since it's declared NOT NULL +FILENAME: pl_gram.y +FUNCNAME: plpgsql_yyparse +CONTEXT: "compilation of PL/pgSQL function \"inline_code_block\" near line 2" +== 024 +do $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record "}},"notnull":true,"default_val":{"PLpgSQL_expr":{"query":"row(41,42)","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := row(null,null)","parseMode":3}}}},{"PLpgSQL_stmt_raise":{"lineno":6,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := null","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 025 +do $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record "}},"notnull":true,"default_val":{"PLpgSQL_expr":{"query":"null","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 026 +-- Check that variables are reinitialized on block re-entry. + +do $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"int"}}}},{"PLpgSQL_var":{"refname":"y","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"int "}},"default_val":{"PLpgSQL_expr":{"query":"i","parseMode":2}}}},{"PLpgSQL_rec":{"refname":"r","dno":4,"lineno":7}},{"PLpgSQL_var":{"refname":"c","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"var_record"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fori":{"lineno":3,"var":{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"3","parseMode":2}},"body":[{"PLpgSQL_stmt_block":{"lineno":9,"body":[{"PLpgSQL_stmt_if":{"lineno":10,"cond":{"PLpgSQL_expr":{"query":"i = 1","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":11,"varno":2,"expr":{"PLpgSQL_expr":{"query":"x := 42","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":12,"varno":4,"expr":{"PLpgSQL_expr":{"query":"r := row(i, i+1)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":13,"varno":5,"expr":{"PLpgSQL_expr":{"query":"c := row(i, i+1)","parseMode":3}}}}]}},{"PLpgSQL_stmt_raise":{"lineno":15,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":16,"elog_level":18,"message":"y = %","params":[{"PLpgSQL_expr":{"query":"y","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":17,"elog_level":18,"message":"r = %","params":[{"PLpgSQL_expr":{"query":"r","parseMode":2}}]}},{"PLpgSQL_stmt_raise":{"lineno":18,"elog_level":18,"message":"c = %","params":[{"PLpgSQL_expr":{"query":"c","parseMode":2}}]}}]}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 027 +-- Check enforcement of domain constraints during initialization + +do $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int_nn"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 028 +do $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int_nn "}},"default_val":{"PLpgSQL_expr":{"query":"null","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 029 +do $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int_nn "}},"default_val":{"PLpgSQL_expr":{"query":"42","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := null","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 030 +do $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_nn"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 031 +do $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_nn "}},"default_val":{"PLpgSQL_expr":{"query":"null","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 032 +do $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_nn "}},"default_val":{"PLpgSQL_expr":{"query":"row(1,2)","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := row(null,null)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := null","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 033 +do $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_colnn"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 034 +do $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_colnn "}},"default_val":{"PLpgSQL_expr":{"query":"null","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 035 +do $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_colnn "}},"default_val":{"PLpgSQL_expr":{"query":"row(1,null)","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 036 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_colnn "}},"default_val":{"PLpgSQL_expr":{"query":"row(1,2)","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := null","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 037 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"x","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"var_record_colnn "}},"default_val":{"PLpgSQL_expr":{"query":"row(1,2)","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_raise":{"lineno":4,"elog_level":18,"message":"x = %","params":[{"PLpgSQL_expr":{"query":"x","parseMode":2}}]}},{"PLpgSQL_stmt_assign":{"lineno":5,"varno":1,"expr":{"PLpgSQL_expr":{"query":"x := row(null,null)","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] diff --git a/parser/testdata/plpgsql/plpgsql_samples.metadata.json b/parser/testdata/plpgsql/plpgsql_samples.metadata.json new file mode 100644 index 0000000..d389286 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_samples.metadata.json @@ -0,0 +1,33 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029" + ] +} diff --git a/parser/testdata/plpgsql/plpgsql_samples.test b/parser/testdata/plpgsql/plpgsql_samples.test new file mode 100644 index 0000000..188d145 --- /dev/null +++ b/parser/testdata/plpgsql/plpgsql_samples.test @@ -0,0 +1,728 @@ +== 001 +-- Examples from https://www.postgresql.org/docs/9.6/static/plpgsql-control-structures.html + +CREATE OR REPLACE FUNCTION get_all_foo() RETURNS SETOF foo AS +$BODY$ +DECLARE + r foo%rowtype; +BEGIN + FOR r IN + SELECT * FROM foo WHERE fooid > 0 + LOOP + -- can do some processing here + RETURN NEXT r; -- return current row of SELECT + END LOOP; + RETURN; +END +$BODY$ +LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"r","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"foo%rowtype"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":5,"fields":[{"name":"r","varno":1}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_fors":{"lineno":5,"var":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":5,"fields":[{"name":"r","varno":1}]}},"body":[{"PLpgSQL_stmt_return_next":{"lineno":9}}],"query":{"PLpgSQL_expr":{"query":"SELECT * FROM foo WHERE fooid \u003e 0","parseMode":0}}}},{"PLpgSQL_stmt_return":{"lineno":11}}]}}}} +] +== 002 +CREATE FUNCTION get_available_flightid(date) RETURNS SETOF integer AS +$BODY$ +BEGIN + RETURN QUERY SELECT flightid + FROM flight + WHERE flightdate >= $1 + AND flightdate < ($1 + 1); + + -- Since execution is not finished, we can check whether rows were returned + -- and raise exception if not. + IF NOT FOUND THEN + RAISE EXCEPTION 'No flight at %.', $1; + END IF; + + RETURN; + END +$BODY$ +LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"date"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_return_query":{"lineno":3,"query":{"PLpgSQL_expr":{"query":"SELECT flightid\n FROM flight\n WHERE flightdate \u003e= $1\n AND flightdate \u003c ($1 + 1)","parseMode":0}}}},{"PLpgSQL_stmt_if":{"lineno":10,"cond":{"PLpgSQL_expr":{"query":"NOT FOUND","parseMode":2}},"then_body":[{"PLpgSQL_stmt_raise":{"lineno":11,"elog_level":21,"message":"No flight at %.","params":[{"PLpgSQL_expr":{"query":"$1","parseMode":2}}]}}]}},{"PLpgSQL_stmt_return":{"lineno":14}}]}}}} +] +== 003 +-- Examples from https://www.postgresql.org/docs/9.6/static/plpgsql-porting.html + +CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar, + v_version varchar) +RETURNS varchar AS $$ +BEGIN + IF v_version IS NULL THEN + RETURN v_name; + END IF; + RETURN v_name || '/' || v_version; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"v_name","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"v_version","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_if":{"lineno":3,"cond":{"PLpgSQL_expr":{"query":"v_version IS NULL","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"v_name","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"v_name || '/' || v_version","parseMode":2}}}}]}}}} +] +== 004 +-- CREATE OR REPLACE FUNCTION cs_update_referrer_type_proc() RETURNS void AS $func$ +-- DECLARE +-- referrer_keys CURSOR IS +-- SELECT * FROM cs_referrer_keys +-- ORDER BY try_order; +-- func_body text; +-- func_cmd text; +-- BEGIN +-- func_body := 'BEGIN'; +-- -- Notice how we scan through the results of a query in a FOR loop +-- -- using the FOR construct. +-- FOR referrer_key IN SELECT * FROM cs_referrer_keys ORDER BY try_order LOOP +-- func_body := func_body || +-- ' IF v_' || referrer_key.kind +-- || ' LIKE ' || quote_literal(referrer_key.key_string) +-- || ' THEN RETURN ' || quote_literal(referrer_key.referrer_type) +-- || '; END IF;' ; +-- END LOOP; +-- func_body := func_body || ' RETURN NULL; END;'; +-- func_cmd := +-- 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host varchar, +-- v_domain varchar, +-- v_url varchar) +-- RETURNS varchar AS ' +-- || quote_literal(func_body) +-- || ' LANGUAGE plpgsql;' ; +-- EXECUTE func_cmd; +-- END;$func$; + +CREATE OR REPLACE FUNCTION cs_parse_url( + v_url IN VARCHAR, + v_host OUT VARCHAR, -- This will be passed back + v_path OUT VARCHAR, -- This one too + v_query OUT VARCHAR) -- And this one +AS $$ +DECLARE + a_pos1 INTEGER; + a_pos2 INTEGER; +BEGIN + v_host := NULL; + v_path := NULL; + v_query := NULL; + a_pos1 := instr(v_url, '//'); + + IF a_pos1 = 0 THEN + RETURN; + END IF; + a_pos2 := instr(v_url, '/', a_pos1 + 2); + IF a_pos2 = 0 THEN + v_host := substr(v_url, a_pos1 + 2); + v_path := '/'; + RETURN; + END IF; + + v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2); + a_pos1 := instr(v_url, '?', a_pos2 + 1); + + IF a_pos1 = 0 THEN + v_path := substr(v_url, a_pos2); + RETURN; + END IF; + + v_path := substr(v_url, a_pos2, a_pos1 - a_pos2); + v_query := substr(v_url, a_pos1 + 1); +END; +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"v_url","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"v_host","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"v_path","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"v_query","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a_pos1","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}},{"PLpgSQL_var":{"refname":"a_pos2","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_assign":{"lineno":6,"varno":1,"expr":{"PLpgSQL_expr":{"query":"v_host := NULL","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"v_path := NULL","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":8,"varno":3,"expr":{"PLpgSQL_expr":{"query":"v_query := NULL","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":9,"varno":5,"expr":{"PLpgSQL_expr":{"query":"a_pos1 := instr(v_url, '//')","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":11,"cond":{"PLpgSQL_expr":{"query":"a_pos1 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":12}}]}},{"PLpgSQL_stmt_assign":{"lineno":14,"varno":6,"expr":{"PLpgSQL_expr":{"query":"a_pos2 := instr(v_url, '/', a_pos1 + 2)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":15,"cond":{"PLpgSQL_expr":{"query":"a_pos2 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":16,"varno":1,"expr":{"PLpgSQL_expr":{"query":"v_host := substr(v_url, a_pos1 + 2)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":17,"varno":2,"expr":{"PLpgSQL_expr":{"query":"v_path := '/'","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":18}}]}},{"PLpgSQL_stmt_assign":{"lineno":21,"varno":1,"expr":{"PLpgSQL_expr":{"query":"v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":22,"varno":5,"expr":{"PLpgSQL_expr":{"query":"a_pos1 := instr(v_url, '?', a_pos2 + 1)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":24,"cond":{"PLpgSQL_expr":{"query":"a_pos1 = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":25,"varno":2,"expr":{"PLpgSQL_expr":{"query":"v_path := substr(v_url, a_pos2)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":26}}]}},{"PLpgSQL_stmt_assign":{"lineno":29,"varno":2,"expr":{"PLpgSQL_expr":{"query":"v_path := substr(v_url, a_pos2, a_pos1 - a_pos2)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":30,"varno":3,"expr":{"PLpgSQL_expr":{"query":"v_query := substr(v_url, a_pos1 + 1)","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 005 +CREATE OR REPLACE FUNCTION cs_create_job(v_job_id integer) RETURNS void AS $$ +DECLARE + a_running_job_count integer; +BEGIN + LOCK TABLE cs_jobs IN EXCLUSIVE MODE; + + SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; + + IF a_running_job_count > 0 THEN + RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; + END IF; + + DELETE FROM cs_active_job; + INSERT INTO cs_active_job(job_id) VALUES (v_job_id); + + BEGIN + INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); + EXCEPTION + WHEN unique_violation THEN + -- don't worry if it already exists + END; +END; +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"v_job_id","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"a_running_job_count","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":7,"fields":[{"name":"a_running_job_count","varno":2}]}},{"PLpgSQL_var":{"refname":"sqlstate","lineno":18,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}},{"PLpgSQL_var":{"refname":"sqlerrm","lineno":18,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.text"}},"isconst":true}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"LOCK TABLE cs_jobs IN EXCLUSIVE MODE","parseMode":0}}}},{"PLpgSQL_stmt_execsql":{"lineno":7,"sqlstmt":{"PLpgSQL_expr":{"query":"SELECT count(*) FROM cs_jobs WHERE end_stamp IS NULL","parseMode":0}},"into":true,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":7,"fields":[{"name":"a_running_job_count","varno":2}]}}}},{"PLpgSQL_stmt_if":{"lineno":9,"cond":{"PLpgSQL_expr":{"query":"a_running_job_count \u003e 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_raise":{"lineno":10,"elog_level":21,"message":"Unable to create a new job: a job is currently running"}}]}},{"PLpgSQL_stmt_execsql":{"lineno":13,"sqlstmt":{"PLpgSQL_expr":{"query":"DELETE FROM cs_active_job","parseMode":0}}}},{"PLpgSQL_stmt_execsql":{"lineno":14,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO cs_active_job(job_id) VALUES (v_job_id)","parseMode":0}}}},{"PLpgSQL_stmt_block":{"lineno":16,"body":[{"PLpgSQL_stmt_execsql":{"lineno":17,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now())","parseMode":0}}}}],"exceptions":{"PLpgSQL_exception_block":{"exc_list":[{"PLpgSQL_exception":{"conditions":[{"PLpgSQL_condition":{"condname":"unique_violation"}}]}}]}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 006 +CREATE FUNCTION instr(varchar, varchar) RETURNS integer AS $$ +DECLARE + pos integer; +BEGIN + pos:= instr($1, $2, 1); + RETURN pos; +END; +$$ LANGUAGE plpgsql STRICT IMMUTABLE +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"$2","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"pos","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_assign":{"lineno":5,"varno":3,"expr":{"PLpgSQL_expr":{"query":"pos:= instr($1, $2, 1)","parseMode":3}}}},{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"pos","parseMode":2}}}}]}}}} +] +== 007 +CREATE FUNCTION instr(string varchar, string_to_search varchar, beg_index integer) +RETURNS integer AS $$ +DECLARE + pos integer NOT NULL DEFAULT 0; + temp_str varchar; + beg integer; + length integer; + ss_length integer; +BEGIN + IF beg_index > 0 THEN + temp_str := substring(string FROM beg_index); + pos := position(string_to_search IN temp_str); + + IF pos = 0 THEN + RETURN 0; + ELSE + RETURN pos + beg_index - 1; + END IF; + ELSIF beg_index < 0 THEN + ss_length := char_length(string_to_search); + length := char_length(string); + beg := length + beg_index - ss_length + 2; + + WHILE beg > 0 LOOP + temp_str := substring(string FROM beg FOR ss_length); + pos := position(string_to_search IN temp_str); + + IF pos > 0 THEN + RETURN beg; + END IF; + + beg := beg - 1; + END LOOP; + + RETURN 0; + ELSE + RETURN 0; + END IF; +END; +$$ LANGUAGE plpgsql STRICT IMMUTABLE +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"string","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"string_to_search","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"beg_index","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"pos","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"integer "}},"notnull":true,"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}},{"PLpgSQL_var":{"refname":"temp_str","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"beg","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_var":{"refname":"length","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_var":{"refname":"ss_length","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":8,"body":[{"PLpgSQL_stmt_if":{"lineno":9,"cond":{"PLpgSQL_expr":{"query":"beg_index \u003e 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":10,"varno":5,"expr":{"PLpgSQL_expr":{"query":"temp_str := substring(string FROM beg_index)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":11,"varno":4,"expr":{"PLpgSQL_expr":{"query":"pos := position(string_to_search IN temp_str)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":13,"cond":{"PLpgSQL_expr":{"query":"pos = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":14,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}],"else_body":[{"PLpgSQL_stmt_return":{"lineno":16,"expr":{"PLpgSQL_expr":{"query":"pos + beg_index - 1","parseMode":2}}}}]}}],"elsif_list":[{"PLpgSQL_if_elsif":{"lineno":18,"cond":{"PLpgSQL_expr":{"query":"beg_index \u003c 0","parseMode":2}},"stmts":[{"PLpgSQL_stmt_assign":{"lineno":19,"varno":8,"expr":{"PLpgSQL_expr":{"query":"ss_length := char_length(string_to_search)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":20,"varno":7,"expr":{"PLpgSQL_expr":{"query":"length := char_length(string)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":21,"varno":6,"expr":{"PLpgSQL_expr":{"query":"beg := length + beg_index - ss_length + 2","parseMode":3}}}},{"PLpgSQL_stmt_while":{"lineno":23,"cond":{"PLpgSQL_expr":{"query":"beg \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":24,"varno":5,"expr":{"PLpgSQL_expr":{"query":"temp_str := substring(string FROM beg FOR ss_length)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":25,"varno":4,"expr":{"PLpgSQL_expr":{"query":"pos := position(string_to_search IN temp_str)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":27,"cond":{"PLpgSQL_expr":{"query":"pos \u003e 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":28,"expr":{"PLpgSQL_expr":{"query":"beg","parseMode":2}}}}]}},{"PLpgSQL_stmt_assign":{"lineno":31,"varno":6,"expr":{"PLpgSQL_expr":{"query":"beg := beg - 1","parseMode":3}}}}]}},{"PLpgSQL_stmt_return":{"lineno":34,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}]}}],"else_body":[{"PLpgSQL_stmt_return":{"lineno":36,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 008 +CREATE FUNCTION instr(string varchar, string_to_search varchar, + beg_index integer, occur_index integer) +RETURNS integer AS $$ +DECLARE + pos integer NOT NULL DEFAULT 0; + occur_number integer NOT NULL DEFAULT 0; + temp_str varchar; + beg integer; + i integer; + length integer; + ss_length integer; +BEGIN + IF beg_index > 0 THEN + beg := beg_index; + temp_str := substring(string FROM beg_index); + + FOR i IN 1..occur_index LOOP + pos := position(string_to_search IN temp_str); + + IF i = 1 THEN + beg := beg + pos - 1; + ELSE + beg := beg + pos; + END IF; + + temp_str := substring(string FROM beg + 1); + END LOOP; + + IF pos = 0 THEN + RETURN 0; + ELSE + RETURN beg; + END IF; + ELSIF beg_index < 0 THEN + ss_length := char_length(string_to_search); + length := char_length(string); + beg := length + beg_index - ss_length + 2; + + WHILE beg > 0 LOOP + temp_str := substring(string FROM beg FOR ss_length); + pos := position(string_to_search IN temp_str); + + IF pos > 0 THEN + occur_number := occur_number + 1; + + IF occur_number = occur_index THEN + RETURN beg; + END IF; + END IF; + + beg := beg - 1; + END LOOP; + + RETURN 0; + ELSE + RETURN 0; + END IF; +END; +$$ LANGUAGE plpgsql STRICT IMMUTABLE +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"string","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"string_to_search","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"beg_index","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"occur_index","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"pos","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"integer "}},"notnull":true,"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}},{"PLpgSQL_var":{"refname":"occur_number","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"integer "}},"notnull":true,"default_val":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}},{"PLpgSQL_var":{"refname":"temp_str","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"varchar"}}}},{"PLpgSQL_var":{"refname":"beg","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_var":{"refname":"i","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_var":{"refname":"length","lineno":8,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_var":{"refname":"ss_length","lineno":9,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_var":{"refname":"i","lineno":15,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":10,"body":[{"PLpgSQL_stmt_if":{"lineno":11,"cond":{"PLpgSQL_expr":{"query":"beg_index \u003e 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":12,"varno":8,"expr":{"PLpgSQL_expr":{"query":"beg := beg_index","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":13,"varno":7,"expr":{"PLpgSQL_expr":{"query":"temp_str := substring(string FROM beg_index)","parseMode":3}}}},{"PLpgSQL_stmt_fori":{"lineno":15,"var":{"PLpgSQL_var":{"refname":"i","lineno":15,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"occur_index","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":16,"varno":5,"expr":{"PLpgSQL_expr":{"query":"pos := position(string_to_search IN temp_str)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":18,"cond":{"PLpgSQL_expr":{"query":"i = 1","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":19,"varno":8,"expr":{"PLpgSQL_expr":{"query":"beg := beg + pos - 1","parseMode":3}}}}],"else_body":[{"PLpgSQL_stmt_assign":{"lineno":21,"varno":8,"expr":{"PLpgSQL_expr":{"query":"beg := beg + pos","parseMode":3}}}}]}},{"PLpgSQL_stmt_assign":{"lineno":24,"varno":7,"expr":{"PLpgSQL_expr":{"query":"temp_str := substring(string FROM beg + 1)","parseMode":3}}}}]}},{"PLpgSQL_stmt_if":{"lineno":27,"cond":{"PLpgSQL_expr":{"query":"pos = 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":28,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}],"else_body":[{"PLpgSQL_stmt_return":{"lineno":30,"expr":{"PLpgSQL_expr":{"query":"beg","parseMode":2}}}}]}}],"elsif_list":[{"PLpgSQL_if_elsif":{"lineno":32,"cond":{"PLpgSQL_expr":{"query":"beg_index \u003c 0","parseMode":2}},"stmts":[{"PLpgSQL_stmt_assign":{"lineno":33,"varno":11,"expr":{"PLpgSQL_expr":{"query":"ss_length := char_length(string_to_search)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":34,"varno":10,"expr":{"PLpgSQL_expr":{"query":"length := char_length(string)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":35,"varno":8,"expr":{"PLpgSQL_expr":{"query":"beg := length + beg_index - ss_length + 2","parseMode":3}}}},{"PLpgSQL_stmt_while":{"lineno":37,"cond":{"PLpgSQL_expr":{"query":"beg \u003e 0","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":38,"varno":7,"expr":{"PLpgSQL_expr":{"query":"temp_str := substring(string FROM beg FOR ss_length)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":39,"varno":5,"expr":{"PLpgSQL_expr":{"query":"pos := position(string_to_search IN temp_str)","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":41,"cond":{"PLpgSQL_expr":{"query":"pos \u003e 0","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":42,"varno":6,"expr":{"PLpgSQL_expr":{"query":"occur_number := occur_number + 1","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":44,"cond":{"PLpgSQL_expr":{"query":"occur_number = occur_index","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":45,"expr":{"PLpgSQL_expr":{"query":"beg","parseMode":2}}}}]}}]}},{"PLpgSQL_stmt_assign":{"lineno":49,"varno":8,"expr":{"PLpgSQL_expr":{"query":"beg := beg - 1","parseMode":3}}}}]}},{"PLpgSQL_stmt_return":{"lineno":52,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}]}}],"else_body":[{"PLpgSQL_stmt_return":{"lineno":54,"expr":{"PLpgSQL_expr":{"query":"0","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 009 +-- Additional test data below kindly provided by Olivier Auverlot and used with permission + +CREATE FUNCTION displayDate(endDate date, canceled boolean) RETURNS text + LANGUAGE plpgsql + AS $$BEGIN + IF canceled = true THEN + return null; + ELSE + return endDate; + END IF; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"enddate","datatype":{"PLpgSQL_type":{"typname":"date"}}}},{"PLpgSQL_var":{"refname":"canceled","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.bool"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_if":{"lineno":2,"cond":{"PLpgSQL_expr":{"query":"canceled = true","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":3,"expr":{"PLpgSQL_expr":{"query":"null","parseMode":2}}}}],"else_body":[{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"endDate","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 010 +CREATE FUNCTION calcule_theYear_these(date_inscription date, date_observation date) RETURNS smallint + LANGUAGE plpgsql + AS $$BEGIN + return (calcule_duree(date_inscription,date_observation) + 1); +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"date_inscription","datatype":{"PLpgSQL_type":{"typname":"date"}}}},{"PLpgSQL_var":{"refname":"date_observation","datatype":{"PLpgSQL_type":{"typname":"date"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":1,"body":[{"PLpgSQL_stmt_return":{"lineno":2,"expr":{"PLpgSQL_expr":{"query":"(calcule_duree(date_inscription,date_observation) + 1)","parseMode":2}}}}]}}}} +] +== 011 +CREATE FUNCTION calcule_duree(origine date, atDate date) RETURNS integer + LANGUAGE plpgsql + AS $$DECLARE + theDay INTEGER; + theMonth INTEGER; + theYear INTEGER; + theDay_now INTEGER; + theMonth_now INTEGER; + theYear_now INTEGER; +BEGIN + theDay := EXTRACT(DAY FROM origine); + theMonth := EXTRACT(MONTH FROM origine); + theYear := EXTRACT(YEAR FROM origine); + + theDay_now := EXTRACT(DAY FROM atDate); + theMonth_now := EXTRACT(MONTH FROM atDate); + theYear_now := EXTRACT(YEAR FROM atDate); + + theYear := theYear_now - theYear; + if theMonth_now <= theMonth THEN + IF theMonth = theMonth_now THEN + IF theDay > theDay_now THEN + theYear := theYear - 1; + END IF; + ELSE + theYear := theYear - 1; + END IF; + END IF; + + return theYear; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"origine","datatype":{"PLpgSQL_type":{"typname":"date"}}}},{"PLpgSQL_var":{"refname":"atdate","datatype":{"PLpgSQL_type":{"typname":"date"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"theday","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}},{"PLpgSQL_var":{"refname":"themonth","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}},{"PLpgSQL_var":{"refname":"theyear","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}},{"PLpgSQL_var":{"refname":"theday_now","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}},{"PLpgSQL_var":{"refname":"themonth_now","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}},{"PLpgSQL_var":{"refname":"theyear_now","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"INTEGER"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":8,"body":[{"PLpgSQL_stmt_assign":{"lineno":9,"varno":3,"expr":{"PLpgSQL_expr":{"query":"theDay := EXTRACT(DAY FROM origine)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":10,"varno":4,"expr":{"PLpgSQL_expr":{"query":"theMonth := EXTRACT(MONTH FROM origine)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":11,"varno":5,"expr":{"PLpgSQL_expr":{"query":"theYear := EXTRACT(YEAR FROM origine)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":13,"varno":6,"expr":{"PLpgSQL_expr":{"query":"theDay_now := EXTRACT(DAY FROM atDate)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":14,"varno":7,"expr":{"PLpgSQL_expr":{"query":"theMonth_now := EXTRACT(MONTH FROM atDate)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":15,"varno":8,"expr":{"PLpgSQL_expr":{"query":"theYear_now := EXTRACT(YEAR FROM atDate)","parseMode":3}}}},{"PLpgSQL_stmt_assign":{"lineno":17,"varno":5,"expr":{"PLpgSQL_expr":{"query":"theYear := theYear_now - theYear","parseMode":3}}}},{"PLpgSQL_stmt_if":{"lineno":18,"cond":{"PLpgSQL_expr":{"query":"theMonth_now \u003c= theMonth","parseMode":2}},"then_body":[{"PLpgSQL_stmt_if":{"lineno":19,"cond":{"PLpgSQL_expr":{"query":"theMonth = theMonth_now","parseMode":2}},"then_body":[{"PLpgSQL_stmt_if":{"lineno":20,"cond":{"PLpgSQL_expr":{"query":"theDay \u003e theDay_now","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":21,"varno":5,"expr":{"PLpgSQL_expr":{"query":"theYear := theYear - 1","parseMode":3}}}}]}}],"else_body":[{"PLpgSQL_stmt_assign":{"lineno":24,"varno":5,"expr":{"PLpgSQL_expr":{"query":"theYear := theYear - 1","parseMode":3}}}}]}}]}},{"PLpgSQL_stmt_return":{"lineno":28,"expr":{"PLpgSQL_expr":{"query":"theYear","parseMode":2}}}}]}}}} +] +== 012 +CREATE FUNCTION endDatedUID(uidmember character varying) RETURNS integer + LANGUAGE plpgsql + AS $$DECLARE + memberID int4; + +BEGIN + SELECT key INTO memberID + FROM + member + WHERE + uidmember = uid; + + RETURN memberID; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"uidmember","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"memberid","lineno":2,"datatype":{"PLpgSQL_type":{"typname":"int4"}}}},{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":5,"fields":[{"name":"memberid","varno":2}]}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_execsql":{"lineno":5,"sqlstmt":{"PLpgSQL_expr":{"query":"SELECT key FROM\n\t\tmember\n\tWHERE\n\t\tuidmember = uid","parseMode":0}},"into":true,"target":{"PLpgSQL_row":{"refname":"(unnamed row)","lineno":5,"fields":[{"name":"memberid","varno":2}]}}}},{"PLpgSQL_stmt_return":{"lineno":11,"expr":{"PLpgSQL_expr":{"query":"memberID","parseMode":2}}}}]}}}} +] +== 013 +CREATE FUNCTION currentEmployer(memberID integer, jobID integer, jobEnd date) RETURNS boolean + LANGUAGE plpgsql + AS $$DECLARE + lastJob RECORD; + lastEmployer record; + updateJob BOOL; +BEGIN + updateJob := false; + + SELECT * INTO lastJob FROM lire_lastJob(memberID) AS (jobID INT,startsupport DATE,jobEnd DATE); + IF lastJob.jobID = jobID THEN + SELECT + r_perlab.key AS positionHeld, + r_perlab.endDate AS positionEnd + INTO lastEmployer + FROM + r_perlab, + (SELECT + r_perlab.key_member AS col_memberID, + max(r_perlab.start) AS startrattachement + FROM r_perlab + GROUP BY col_memberID) positions + WHERE ((positions.col_memberID = memberID) AND (r_perlab.key_member = positions.col_memberID) AND (r_perlab.start = startrattachement)); + + IF lastEmployer.positionHeld IS NOT NULL THEN + updateJob := true; + UPDATE r_perlab SET endDate = jobEnd WHERE key = lastEmployer.positionHeld; + END IF; + END IF; + + RETURN updateJob; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"memberid","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"jobid","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"jobend","datatype":{"PLpgSQL_type":{"typname":"date"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"lastjob","dno":4,"lineno":2}},{"PLpgSQL_rec":{"refname":"lastemployer","dno":5,"lineno":3}},{"PLpgSQL_var":{"refname":"updatejob","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"BOOL"}}}},{"PLpgSQL_recfield":{"fieldname":"jobid","recparentno":4}},{"PLpgSQL_recfield":{"fieldname":"positionheld","recparentno":5}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_assign":{"lineno":6,"varno":6,"expr":{"PLpgSQL_expr":{"query":"updateJob := false","parseMode":3}}}},{"PLpgSQL_stmt_execsql":{"lineno":8,"sqlstmt":{"PLpgSQL_expr":{"query":"SELECT * FROM lire_lastJob(memberID) AS (jobID INT,startsupport DATE,jobEnd DATE)","parseMode":0}},"into":true,"target":{"PLpgSQL_rec":{"refname":"lastjob","dno":4,"lineno":2}}}},{"PLpgSQL_stmt_if":{"lineno":9,"cond":{"PLpgSQL_expr":{"query":"lastJob.jobID = jobID","parseMode":2}},"then_body":[{"PLpgSQL_stmt_execsql":{"lineno":10,"sqlstmt":{"PLpgSQL_expr":{"query":"SELECT\n\t\t\tr_perlab.key AS positionHeld,\n\t\t\tr_perlab.endDate AS positionEnd\n\t\t FROM\n\t\t\tr_perlab,\n\t\t\t(SELECT\n\t\t\t\tr_perlab.key_member AS col_memberID,\n\t\t\t\tmax(r_perlab.start) AS startrattachement\n\t\t\tFROM r_perlab\n\t\t\tGROUP BY col_memberID) positions\n\t\tWHERE ((positions.col_memberID = memberID) AND (r_perlab.key_member = positions.col_memberID) AND (r_perlab.start = startrattachement))","parseMode":0}},"into":true,"target":{"PLpgSQL_rec":{"refname":"lastemployer","dno":5,"lineno":3}}}},{"PLpgSQL_stmt_if":{"lineno":23,"cond":{"PLpgSQL_expr":{"query":"lastEmployer.positionHeld IS NOT NULL","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":24,"varno":6,"expr":{"PLpgSQL_expr":{"query":"updateJob := true","parseMode":3}}}},{"PLpgSQL_stmt_execsql":{"lineno":25,"sqlstmt":{"PLpgSQL_expr":{"query":"UPDATE r_perlab SET endDate = jobEnd WHERE key = lastEmployer.positionHeld","parseMode":0}}}}]}}]}},{"PLpgSQL_stmt_return":{"lineno":29,"expr":{"PLpgSQL_expr":{"query":"updateJob","parseMode":2}}}}]}}}} +] +== 014 +-- CREATE FUNCTION getArrivalDate(memberID integer, teamID integer, atDate date) RETURNS date +-- LANGUAGE plpgsql +-- AS $$ +-- DECLARE +-- affectations affectation[]; +-- aff affectation; +|-- +-- DELAI_MAX CONSTANT INTEGER := 30; +|-- +-- idx INTEGER; +-- nbr_aff INTEGER; +-- start DATE; +-- endDate DATE; +-- sortie BOOLEAN; +|-- +-- arrivalDate DATE; +|-- +-- crs_affectation CURSOR (memberID INTEGER) FOR +-- SELECT +-- affectation.key, +-- affectation.key_team, +-- affectation.key_support, +-- affectation.start, +-- affectation.endDate, +-- affectation.repartition, +-- affectation.key_typeaffectation +-- FROM support,affectation +-- WHERE +-- support.key_member = memberID +-- AND affectation.key_support = support.key +-- AND affectation.start <= atDate +-- AND affectation.key_team = teamID +-- ORDER BY affectation.start DESC; +-- BEGIN +-- OPEN crs_affectation(memberID); +-- LOOP +-- IF NOT FOUND THEN +-- EXIT; +-- END IF; +-- FETCH crs_affectation into aff.key,aff.key_team,aff.key_support,aff.start,aff.endDate,aff.repartition,aff.key_typeaffectation; +-- affectations := ARRAY_APPEND(affectations,aff); +-- END LOOP; +-- CLOSE crs_affectation; +|-- +-- nbr_aff := ARRAY_LENGTH(affectations, 1); +-- idx := 1; +-- sortie := FALSE; +|-- +-- WHILE (idx <= nbr_aff AND sortie = FALSE) LOOP +-- IF(arrivalDate IS NULL) THEN +-- arrivalDate := affectations[idx].start; +-- endDate := affectations[idx].endDate; +-- ELSE +-- IF(arrivalDate - affectations[idx].endDate) < DELAI_MAX THEN +-- arrivalDate := affectations[idx].start; +-- endDate := affectations[idx].endDate; +-- ELSE +-- sortie := TRUE; +-- END IF; +-- END IF; +-- idx := idx + 1; +-- END LOOP; +|-- +-- RETURN arrivalDate; +-- END;$$; + +CREATE FUNCTION cleanString(str character varying) RETURNS character varying + LANGUAGE plpgsql + AS $$ + +DECLARE + spechar VARCHAR[ ] := ARRAY['à','â','é','è','ê','ë','ï','î','ô','û','ù','À','Â','É','È','Ê','Ë','Ï','Î','ô','û','ù','ç' ]; + lettres VARCHAR[ ] := ARRAY['a','a','e','e','e','e','i','i','o','u','u','a','a','e','e','e','e','i','i','o','u','u','c' ]; + resultat VARCHAR; + nbrspechar INTEGER := 23; + +BEGIN + IF (str IS NOT NULL) THEN + resultat := str; + FOR i IN 1..nbrspechar LOOP + resultat := regexp_replace(resultat,spechar[i],lettres[i],'g'); + END LOOP; + END IF; + RETURN resultat; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"str","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"spechar","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"VARCHAR[ ] "}},"default_val":{"PLpgSQL_expr":{"query":"ARRAY['à','â','é','è','ê','ë','ï','î','ô','û','ù','À','Â','É','È','Ê','Ë','Ï','Î','ô','û','ù','ç' ]","parseMode":2}}}},{"PLpgSQL_var":{"refname":"lettres","lineno":5,"datatype":{"PLpgSQL_type":{"typname":"VARCHAR[ ] "}},"default_val":{"PLpgSQL_expr":{"query":"ARRAY['a','a','e','e','e','e','i','i','o','u','u','a','a','e','e','e','e','i','i','o','u','u','c' ]","parseMode":2}}}},{"PLpgSQL_var":{"refname":"resultat","lineno":6,"datatype":{"PLpgSQL_type":{"typname":"VARCHAR"}}}},{"PLpgSQL_var":{"refname":"nbrspechar","lineno":7,"datatype":{"PLpgSQL_type":{"typname":"INTEGER "}},"default_val":{"PLpgSQL_expr":{"query":"23","parseMode":2}}}},{"PLpgSQL_var":{"refname":"i","lineno":12,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":9,"body":[{"PLpgSQL_stmt_if":{"lineno":10,"cond":{"PLpgSQL_expr":{"query":"(str IS NOT NULL)","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":11,"varno":4,"expr":{"PLpgSQL_expr":{"query":"resultat := str","parseMode":3}}}},{"PLpgSQL_stmt_fori":{"lineno":12,"var":{"PLpgSQL_var":{"refname":"i","lineno":12,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"integer\""}}}},"lower":{"PLpgSQL_expr":{"query":"1","parseMode":2}},"upper":{"PLpgSQL_expr":{"query":"nbrspechar","parseMode":2}},"body":[{"PLpgSQL_stmt_assign":{"lineno":13,"varno":4,"expr":{"PLpgSQL_expr":{"query":"resultat := regexp_replace(resultat,spechar[i],lettres[i],'g')","parseMode":3}}}}]}}]}},{"PLpgSQL_stmt_return":{"lineno":16,"expr":{"PLpgSQL_expr":{"query":"resultat","parseMode":2}}}}]}}}} +] +== 015 +CREATE FUNCTION t_update() RETURNS trigger + LANGUAGE plpgsql + AS $$ + +BEGIN + NEW.name = upper(cleanString(NEW.name)); + return NEW; +END;$$ +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_recfield":{"fieldname":"name","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"NEW.name = upper(cleanString(NEW.name))","parseMode":4}}}},{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"NEW","parseMode":2}}}}]}}}} +] +== 016 +CREATE FUNCTION t_create() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + INSERT INTO list(key,date) VALUES(NEW.key,NEW.end); + RETURN NEW; +END;$$ +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}},{"PLpgSQL_recfield":{"fieldname":"key","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_execsql":{"lineno":3,"sqlstmt":{"PLpgSQL_expr":{"query":"INSERT INTO list(key,date) VALUES(NEW.key,NEW.end)","parseMode":0}}}},{"PLpgSQL_stmt_return":{"lineno":4,"expr":{"PLpgSQL_expr":{"query":"NEW","parseMode":2}}}}]}}}} +] +== 017 +CREATE OR REPLACE FUNCTION test.test_parse ( + p_time_start timestamptz, + p_time_end timestamptz, + p_time_interval interval default NULL +) RETURNS TABLE ( + ts timestamptz, + arbitrary_return bigint +) AS $$ +BEGIN + -- some comment + -- some other comment + + IF p_time_interval IS NULL + THEN p_time_interval := interval_from_start_end(p_time_start, p_time_end); + END IF; + RETURN QUERY + SELECT + bucket_function(p_time_interval, timestamp) AS ts, + arbitrary_return + FROM test.some_table + WHERE + start >= p_time_start + AND "end" < p_time_end + GROUP BY 1; +END; $$ LANGUAGE plpgsql SECURITY DEFINER PARALLEL UNSAFE +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"p_time_start","datatype":{"PLpgSQL_type":{"typname":"timestamptz"}}}},{"PLpgSQL_var":{"refname":"p_time_end","datatype":{"PLpgSQL_type":{"typname":"timestamptz"}}}},{"PLpgSQL_var":{"refname":"p_time_interval","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"interval\""}}}},{"PLpgSQL_var":{"refname":"ts","datatype":{"PLpgSQL_type":{"typname":"timestamptz"}}}},{"PLpgSQL_var":{"refname":"arbitrary_return","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int8"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_if":{"lineno":6,"cond":{"PLpgSQL_expr":{"query":"p_time_interval IS NULL","parseMode":2}},"then_body":[{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"p_time_interval := interval_from_start_end(p_time_start, p_time_end)","parseMode":3}}}}]}},{"PLpgSQL_stmt_return_query":{"lineno":9,"query":{"PLpgSQL_expr":{"query":"SELECT\n bucket_function(p_time_interval, timestamp) AS ts,\n arbitrary_return\n FROM test.some_table\n WHERE\n start \u003e= p_time_start\n AND \"end\" \u003c p_time_end\n GROUP BY 1","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 018 +CREATE FUNCTION public.somefunc(OUT _result uuid[]) + RETURNS uuid[] + LANGUAGE 'plpgsql' + +AS $BODY$ +DECLARE + active_on_to_date uuid[]; +BEGIN +_result := ARRAY( SELECT some_id FROM some_table); +END; +$BODY$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"_result","datatype":{"PLpgSQL_type":{"typname":"uuid"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"active_on_to_date","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"uuid[]"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_assign":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"_result := ARRAY( SELECT some_id FROM some_table)","parseMode":3}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 019 +CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar, v_version varchar) +RETURNS varchar AS $$ +DECLARE +_a int; +_v_name_alias ALIAS FOR $1; +BEGIN +IF v_version IS NULL THEN +RETURN v_name; +END IF; + +RETURN v_name || '/' || v_version; +END; $$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"v_name","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"v_version","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"_a","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"int"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_if":{"lineno":6,"cond":{"PLpgSQL_expr":{"query":"v_version IS NULL","parseMode":2}},"then_body":[{"PLpgSQL_stmt_return":{"lineno":7,"expr":{"PLpgSQL_expr":{"query":"v_name","parseMode":2}}}}]}},{"PLpgSQL_stmt_return":{"lineno":10,"expr":{"PLpgSQL_expr":{"query":"v_name || '/' || v_version","parseMode":2}}}}]}}}} +] +== 020 +CREATE FUNCTION test(str character varying) RETURNS integer +LANGUAGE plpgsql +AS $$ +DECLARE + v3 RECORD; + v4 integer; +BEGIN + select 1 as c1, 2 as c2 into v3; + v3.c1 := 4; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"str","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"varchar\""}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"v3","dno":2,"lineno":3}},{"PLpgSQL_var":{"refname":"v4","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"integer"}}}},{"PLpgSQL_recfield":{"fieldname":"c1","recparentno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_execsql":{"lineno":6,"sqlstmt":{"PLpgSQL_expr":{"query":"select 1 as c1, 2 as c2","parseMode":0}},"into":true,"target":{"PLpgSQL_rec":{"refname":"v3","dno":2,"lineno":3}}}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":4,"expr":{"PLpgSQL_expr":{"query":"v3.c1 := 4","parseMode":4}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 021 +CREATE FUNCTION test_assert() RETURNS integer +LANGUAGE plpgsql +AS $$ +BEGIN + ASSERT true; + ASSERT now() < '2000-01-01'; + ASSERT false, 'msg'; + ASSERT false, version(); + + RETURN 1; +END;$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assert":{"lineno":3,"cond":{"PLpgSQL_expr":{"query":"true","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":4,"cond":{"PLpgSQL_expr":{"query":"now() \u003c '2000-01-01'","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":5,"cond":{"PLpgSQL_expr":{"query":"false","parseMode":2}},"message":{"PLpgSQL_expr":{"query":"'msg'","parseMode":2}}}},{"PLpgSQL_stmt_assert":{"lineno":6,"cond":{"PLpgSQL_expr":{"query":"false","parseMode":2}},"message":{"PLpgSQL_expr":{"query":"version()","parseMode":2}}}},{"PLpgSQL_stmt_return":{"lineno":8,"expr":{"PLpgSQL_expr":{"query":"1","parseMode":2}}}}]}}}} +] +== 022 +-- Example from https://www.postgresql.org/docs/current/sql-do.html +DO $$DECLARE r record; +BEGIN + FOR r IN SELECT table_schema, table_name FROM information_schema.tables + WHERE table_type = 'VIEW' AND table_schema = 'public' + LOOP + EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser'; + END LOOP; +END$$ +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":1}},{"PLpgSQL_recfield":{"fieldname":"table_schema","recparentno":1}},{"PLpgSQL_recfield":{"fieldname":"table_name","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_fors":{"lineno":3,"var":{"PLpgSQL_rec":{"refname":"r","dno":1,"lineno":1}},"body":[{"PLpgSQL_stmt_dynexecute":{"lineno":6,"query":{"PLpgSQL_expr":{"query":"'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser'","parseMode":2}}}}],"query":{"PLpgSQL_expr":{"query":"SELECT table_schema, table_name FROM information_schema.tables\n WHERE table_type = 'VIEW' AND table_schema = 'public'","parseMode":0}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 023 +CREATE FUNCTION test_cursor() RETURNS void AS $$ + DECLARE + i INT; + c CURSOR FOR SELECT generate_series(1,10); + BEGIN + FOR i IN c LOOP + RAISE NOTICE 'i is %',i; + END LOOP; + END +$$ language plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"i","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"INT"}}}},{"PLpgSQL_var":{"refname":"c","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"pg_catalog.refcursor"}},"cursor_explicit_expr":{"PLpgSQL_expr":{"query":"SELECT generate_series(1,10)","parseMode":0}},"cursor_explicit_argrow":-1,"cursor_options":256}},{"PLpgSQL_rec":{"refname":"i","dno":3,"lineno":6}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_forc":{"lineno":6,"var":{"PLpgSQL_rec":{"refname":"i","dno":3,"lineno":6}},"body":[{"PLpgSQL_stmt_raise":{"lineno":7,"elog_level":18,"message":"i is %","params":[{"PLpgSQL_expr":{"query":"i","parseMode":2}}]}}],"curvar":2}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 024 +CREATE FUNCTION public.dz_sumfunc( + IN p_in INTEGER + ,OUT p_out public.dz_sumthing +) +AS $BODY$ +DECLARE +BEGIN + p_out.sumattribute := p_in; +END; +$BODY$ +LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"p_in","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_rec":{"refname":"p_out","dno":1}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_recfield":{"fieldname":"sumattribute","recparentno":1}}],"action":{"PLpgSQL_stmt_block":{"lineno":3,"body":[{"PLpgSQL_stmt_assign":{"lineno":4,"varno":3,"expr":{"PLpgSQL_expr":{"query":"p_out.sumattribute := p_in","parseMode":4}}}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 025 +-- Examples from https://www.postgresql.org/docs/16/plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS +CREATE FUNCTION sales_tax(real) RETURNS real AS $$ +DECLARE + subtotal ALIAS FOR $1; +BEGIN + RETURN subtotal * 0.06; +END; +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"$1","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.float4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_return":{"lineno":5,"expr":{"PLpgSQL_expr":{"query":"subtotal * 0.06","parseMode":2}}}}]}}}} +] +== 026 +-- RETURN NEXT; with no expression https://www.postgresql.org/docs/16/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING-RETURN-NEXT +CREATE OR REPLACE FUNCTION public.test_pl(s integer, e integer) + RETURNS TABLE(id INTEGER) AS $$ +BEGIN + id := s; +LOOP + EXIT WHEN id>e; + RETURN NEXT; + id := id + 1; +END LOOP; +END +$$ + LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"s","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"e","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"id","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.int4"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":2,"body":[{"PLpgSQL_stmt_assign":{"lineno":3,"varno":2,"expr":{"PLpgSQL_expr":{"query":"id := s","parseMode":3}}}},{"PLpgSQL_stmt_loop":{"lineno":4,"body":[{"PLpgSQL_stmt_exit":{"lineno":5,"is_exit":true,"cond":{"PLpgSQL_expr":{"query":"id\u003ee","parseMode":2}}}},{"PLpgSQL_stmt_return_next":{"lineno":6}},{"PLpgSQL_stmt_assign":{"lineno":7,"varno":2,"expr":{"PLpgSQL_expr":{"query":"id := id + 1","parseMode":3}}}}]}},{"PLpgSQL_stmt_return":{}}]}}}} +] +== 027 +CREATE OR REPLACE FUNCTION trgfn() + RETURNS trigger AS $$ +DECLARE + prior ALIAS FOR old; + updated ALIAS FOR new; +BEGIN + RETURN; +END; +$$ + LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"new_varno":1,"old_varno":2,"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_rec":{"refname":"new","dno":1}},{"PLpgSQL_rec":{"refname":"old","dno":2}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_return":{"lineno":6}}]}}}} +] +== 028 +-- Example from https://www.postgresql.org/docs/16/plpgsql-cursors.html +CREATE FUNCTION reffunc2() RETURNS refcursor AS ' +DECLARE + ref refcursor; +BEGIN + OPEN ref FOR SELECT col FROM test; + RETURN ref; +END; +' LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"ref","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"refcursor"}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":4,"body":[{"PLpgSQL_stmt_open":{"lineno":5,"curvar":1,"cursor_options":256,"query":{"PLpgSQL_expr":{"query":"SELECT col FROM test","parseMode":0}}}},{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"ref","parseMode":2}}}}]}}}} +] +== 029 +-- Example from https://www.postgresql.org/docs/16/plpgsql-declarations.html#PLPGSQL-DECLARATION-COLLATION +CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ +DECLARE + local_a text COLLATE "en_US" := a; + local_b text := b; +BEGIN + RETURN local_a < local_b; +END; +$$ LANGUAGE plpgsql +-- +[ +{"PLpgSQL_function":{"datums":[{"PLpgSQL_var":{"refname":"a","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"b","datatype":{"PLpgSQL_type":{"typname":"text"}}}},{"PLpgSQL_var":{"refname":"found","datatype":{"PLpgSQL_type":{"typname":"pg_catalog.\"boolean\""}}}},{"PLpgSQL_var":{"refname":"local_a","lineno":3,"datatype":{"PLpgSQL_type":{"typname":"text "}},"default_val":{"PLpgSQL_expr":{"query":"a","parseMode":2}}}},{"PLpgSQL_var":{"refname":"local_b","lineno":4,"datatype":{"PLpgSQL_type":{"typname":"text "}},"default_val":{"PLpgSQL_expr":{"query":"b","parseMode":2}}}}],"action":{"PLpgSQL_stmt_block":{"lineno":5,"body":[{"PLpgSQL_stmt_return":{"lineno":6,"expr":{"PLpgSQL_expr":{"query":"local_a \u003c local_b","parseMode":2}}}}]}}}} +] diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_array.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_array.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_array.test b/parser/testdata/scan/plpgsql_regress/plpgsql_array.test new file mode 100644 index 0000000..b400188 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_array.test @@ -0,0 +1,326 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of array variables +|-- +-- We also check arrays of composites here, so this has some overlap +-- with the plpgsql_record tests. +|-- + +create type complex as (r float8, i float8) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 52 SQL_COMMENT NO_KEYWORD +53 55 SQL_COMMENT NO_KEYWORD +56 124 SQL_COMMENT NO_KEYWORD +125 158 SQL_COMMENT NO_KEYWORD +159 161 SQL_COMMENT NO_KEYWORD +163 169 CREATE RESERVED_KEYWORD +170 174 TYPE_P UNRESERVED_KEYWORD +175 182 IDENT NO_KEYWORD +183 185 AS RESERVED_KEYWORD +186 187 ASCII_40 NO_KEYWORD +187 188 IDENT NO_KEYWORD +189 195 IDENT NO_KEYWORD +195 196 ASCII_44 NO_KEYWORD +197 198 IDENT NO_KEYWORD +199 205 IDENT NO_KEYWORD +205 206 ASCII_41 NO_KEYWORD +== 002 +create type quadarray as (c1 complex[], c2 complex) +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TYPE_P UNRESERVED_KEYWORD +12 21 IDENT NO_KEYWORD +22 24 AS RESERVED_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 28 IDENT NO_KEYWORD +29 36 IDENT NO_KEYWORD +36 37 ASCII_91 NO_KEYWORD +37 38 ASCII_93 NO_KEYWORD +38 39 ASCII_44 NO_KEYWORD +40 42 IDENT NO_KEYWORD +43 50 IDENT NO_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 003 +do $$ declare a int[]; +begin a := array[1,2]; a[3] := 4; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 87 SCONST NO_KEYWORD +== 004 +do $$ declare a int[]; +begin a[3] := 4; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 70 SCONST NO_KEYWORD +== 005 +do $$ declare a int[]; +begin a[1][4] := 4; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 73 SCONST NO_KEYWORD +== 006 +do $$ declare a int[]; +begin a[1] := 23::text; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 77 SCONST NO_KEYWORD +== 007 +-- lax typing + +do $$ declare a int[]; +begin a := array[1,2]; a[2:3] := array[3,4]; raise notice 'a = %', a; end$$ +-- +0 13 SQL_COMMENT NO_KEYWORD +15 17 DO RESERVED_KEYWORD +18 113 SCONST NO_KEYWORD +== 008 +do $$ declare a int[]; +begin a := array[1,2]; a[2] := a[2] + 1; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 94 SCONST NO_KEYWORD +== 009 +do $$ declare a int[]; +begin a[1:2] := array[3,4]; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 81 SCONST NO_KEYWORD +== 010 +do $$ declare a int[]; +begin a[1:2] := 4; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 72 SCONST NO_KEYWORD +== 011 +-- error + +do $$ declare a complex[]; +begin a[1] := (1,2); a[1].i := 11; raise notice 'a = %', a; end$$ +-- +0 8 SQL_COMMENT NO_KEYWORD +10 12 DO RESERVED_KEYWORD +13 102 SCONST NO_KEYWORD +== 012 +do $$ declare a complex[]; +begin a[1].i := 11; raise notice 'a = %, a[1].i = %', a, a[1].i; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 97 SCONST NO_KEYWORD +== 013 +-- perhaps this ought to work, but for now it doesn't: +do $$ declare a complex[]; +begin a[1:2].i := array[11,12]; raise notice 'a = %', a; end$$ +-- +0 54 SQL_COMMENT NO_KEYWORD +55 57 DO RESERVED_KEYWORD +58 144 SCONST NO_KEYWORD +== 014 +do $$ declare a quadarray; +begin a.c1[1].i := 11; raise notice 'a = %, a.c1[1].i = %', a, a.c1[1].i; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 106 SCONST NO_KEYWORD +== 015 +do $$ declare a int[]; +begin a := array_agg(x) from (values(1),(2),(3)) v(x); raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 108 SCONST NO_KEYWORD +== 016 +create temp table onecol as select array[1,2] as f1 +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TEMP UNRESERVED_KEYWORD +12 17 TABLE RESERVED_KEYWORD +18 24 IDENT NO_KEYWORD +25 27 AS RESERVED_KEYWORD +28 34 SELECT RESERVED_KEYWORD +35 40 ARRAY RESERVED_KEYWORD +40 41 ASCII_91 NO_KEYWORD +41 42 ICONST NO_KEYWORD +42 43 ASCII_44 NO_KEYWORD +43 44 ICONST NO_KEYWORD +44 45 ASCII_93 NO_KEYWORD +46 48 AS RESERVED_KEYWORD +49 51 IDENT NO_KEYWORD +== 017 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 80 SCONST NO_KEYWORD +== 018 +do $$ declare a int[]; +begin a := * from onecol for update; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 90 SCONST NO_KEYWORD +== 019 +-- error cases: + +do $$ declare a int[]; +begin a := from onecol; raise notice 'a = %', a; end$$ +-- +0 15 SQL_COMMENT NO_KEYWORD +17 19 DO RESERVED_KEYWORD +20 94 SCONST NO_KEYWORD +== 020 +do $$ declare a int[]; +begin a := f1, f1 from onecol; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 84 SCONST NO_KEYWORD +== 021 +insert into onecol values(array[11]) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 18 IDENT NO_KEYWORD +19 25 VALUES COL_NAME_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 31 ARRAY RESERVED_KEYWORD +31 32 ASCII_91 NO_KEYWORD +32 34 ICONST NO_KEYWORD +34 35 ASCII_93 NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +== 022 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 80 SCONST NO_KEYWORD +== 023 +do $$ declare a int[]; +begin a := f1 from onecol limit 1; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 88 SCONST NO_KEYWORD +== 024 +do $$ declare a real; +begin a[1] := 2; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 69 SCONST NO_KEYWORD +== 025 +do $$ declare a complex; +begin a.r[1] := 2; raise notice 'a = %', a; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 74 SCONST NO_KEYWORD +== 026 +|-- +-- test of %type[] and %rowtype[] syntax +|-- + +-- check supported syntax +do $$ +declare + v int; + v1 v%type; + v2 v%type[]; + v3 v%type[1]; + v4 v%type[][]; + v5 v%type[1][3]; + v6 v%type array; + v7 v%type array[]; + v8 v%type array[1]; + v9 v%type array[1][1]; + v10 pg_catalog.pg_class%rowtype[]; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(v3); + raise notice '%', pg_typeof(v4); + raise notice '%', pg_typeof(v5); + raise notice '%', pg_typeof(v6); + raise notice '%', pg_typeof(v7); + raise notice '%', pg_typeof(v8); + raise notice '%', pg_typeof(v9); + raise notice '%', pg_typeof(v10); +end; +$$ +-- +0 2 SQL_COMMENT NO_KEYWORD +3 43 SQL_COMMENT NO_KEYWORD +44 46 SQL_COMMENT NO_KEYWORD +48 73 SQL_COMMENT NO_KEYWORD +74 76 DO RESERVED_KEYWORD +77 665 SCONST NO_KEYWORD +== 027 +-- some types don't support arrays +do $$ +declare + v pg_node_tree; + v1 v%type[]; +begin +end; +$$ +-- +0 34 SQL_COMMENT NO_KEYWORD +35 37 DO RESERVED_KEYWORD +38 95 SCONST NO_KEYWORD +== 028 +-- check functionality +do $$ +declare + v1 int; + v2 varchar; + a1 v1%type[]; + a2 v2%type[]; +begin + v1 := 10; + v2 := 'Hi'; + a1 := array[v1,v1]; + a2 := array[v2,v2]; + raise notice '% %', a1, a2; +end; +$$ +-- +0 22 SQL_COMMENT NO_KEYWORD +23 25 DO RESERVED_KEYWORD +26 206 SCONST NO_KEYWORD +== 029 +create table array_test_table(a int, b varchar) +-- +0 6 CREATE RESERVED_KEYWORD +7 12 TABLE RESERVED_KEYWORD +13 29 IDENT NO_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 31 IDENT NO_KEYWORD +32 35 INT_P COL_NAME_KEYWORD +35 36 ASCII_44 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 46 VARCHAR COL_NAME_KEYWORD +46 47 ASCII_41 NO_KEYWORD +== 030 +insert into array_test_table values(1, 'first'), (2, 'second') +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 28 IDENT NO_KEYWORD +29 35 VALUES COL_NAME_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 37 ICONST NO_KEYWORD +37 38 ASCII_44 NO_KEYWORD +39 46 SCONST NO_KEYWORD +46 47 ASCII_41 NO_KEYWORD +47 48 ASCII_44 NO_KEYWORD +49 50 ASCII_40 NO_KEYWORD +50 51 ICONST NO_KEYWORD +51 52 ASCII_44 NO_KEYWORD +53 61 SCONST NO_KEYWORD +61 62 ASCII_41 NO_KEYWORD +== 031 +do $$ +declare tg array_test_table%rowtype[]; +begin + tg := array(select array_test_table from array_test_table); + raise notice '%', tg; + tg := array(select row(a,b) from array_test_table); + raise notice '%', tg; +end; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 222 SCONST NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_cache.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_cache.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_cache.test b/parser/testdata/scan/plpgsql_regress/plpgsql_cache.test new file mode 100644 index 0000000..58b7737 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_cache.test @@ -0,0 +1,168 @@ +== 001 +|-- +-- Cache-behavior-dependent test cases +|-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- depending on debug_discard_caches, so we must have two expected-output +-- files to cover both cases. To minimize the maintenance effort resulting +-- from that, this file should contain only tests that do have different +-- results under debug_discard_caches. +|-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 41 SQL_COMMENT NO_KEYWORD +42 44 SQL_COMMENT NO_KEYWORD +45 119 SQL_COMMENT NO_KEYWORD +120 197 SQL_COMMENT NO_KEYWORD +198 271 SQL_COMMENT NO_KEYWORD +272 347 SQL_COMMENT NO_KEYWORD +348 420 SQL_COMMENT NO_KEYWORD +421 459 SQL_COMMENT NO_KEYWORD +460 462 SQL_COMMENT NO_KEYWORD +464 513 SQL_COMMENT NO_KEYWORD +514 520 CREATE RESERVED_KEYWORD +521 526 TABLE RESERVED_KEYWORD +527 536 IDENT NO_KEYWORD +536 537 ASCII_40 NO_KEYWORD +537 539 IDENT NO_KEYWORD +540 543 INT_P COL_NAME_KEYWORD +543 544 ASCII_44 NO_KEYWORD +545 547 IDENT NO_KEYWORD +548 552 TEXT_P UNRESERVED_KEYWORD +552 553 ASCII_41 NO_KEYWORD +== 002 +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 29 IDENT NO_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 33 INT_P COL_NAME_KEYWORD +33 34 ASCII_41 NO_KEYWORD +35 42 RETURNS UNRESERVED_KEYWORD +43 46 INT_P COL_NAME_KEYWORD +47 55 LANGUAGE UNRESERVED_KEYWORD +56 63 IDENT NO_KEYWORD +64 66 AS RESERVED_KEYWORD +67 132 SCONST NO_KEYWORD +== 003 +select c_sillyaddone(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 20 IDENT NO_KEYWORD +20 21 ASCII_40 NO_KEYWORD +21 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 004 +alter table c_mutable drop column f1 +-- +0 5 ALTER UNRESERVED_KEYWORD +6 11 TABLE RESERVED_KEYWORD +12 21 IDENT NO_KEYWORD +22 26 DROP UNRESERVED_KEYWORD +27 33 COLUMN RESERVED_KEYWORD +34 36 IDENT NO_KEYWORD +== 005 +alter table c_mutable add column f1 float8 +-- +0 5 ALTER UNRESERVED_KEYWORD +6 11 TABLE RESERVED_KEYWORD +12 21 IDENT NO_KEYWORD +22 25 ADD_P UNRESERVED_KEYWORD +26 32 COLUMN RESERVED_KEYWORD +33 35 IDENT NO_KEYWORD +36 42 IDENT NO_KEYWORD +== 006 +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but if debug_discard_caches is on, it will succeed) +select c_sillyaddone(42) +-- +0 69 SQL_COMMENT NO_KEYWORD +70 125 SQL_COMMENT NO_KEYWORD +126 132 SELECT RESERVED_KEYWORD +133 146 IDENT NO_KEYWORD +146 147 ASCII_40 NO_KEYWORD +147 149 ICONST NO_KEYWORD +149 150 ASCII_41 NO_KEYWORD +== 007 +-- but it's OK if we force plan rebuilding +discard plans +-- +0 42 SQL_COMMENT NO_KEYWORD +43 50 DISCARD UNRESERVED_KEYWORD +51 56 PLANS UNRESERVED_KEYWORD +== 008 +select c_sillyaddone(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 20 IDENT NO_KEYWORD +20 21 ASCII_40 NO_KEYWORD +21 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 009 +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$ +-- +0 50 SQL_COMMENT NO_KEYWORD +51 57 CREATE RESERVED_KEYWORD +58 66 FUNCTION UNRESERVED_KEYWORD +67 83 IDENT NO_KEYWORD +83 84 ASCII_40 NO_KEYWORD +84 88 TEXT_P UNRESERVED_KEYWORD +88 89 ASCII_41 NO_KEYWORD +90 97 RETURNS UNRESERVED_KEYWORD +98 102 TEXT_P UNRESERVED_KEYWORD +103 111 LANGUAGE UNRESERVED_KEYWORD +112 119 IDENT NO_KEYWORD +120 122 AS RESERVED_KEYWORD +123 315 SCONST NO_KEYWORD +== 010 +select show_result_type('select 1 as a') +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 39 SCONST NO_KEYWORD +39 40 ASCII_41 NO_KEYWORD +== 011 +-- currently this fails due to cached plan for pg_typeof expression +-- (but if debug_discard_caches is on, it will succeed) +select show_result_type('select 2.0 as a') +-- +0 67 SQL_COMMENT NO_KEYWORD +68 123 SQL_COMMENT NO_KEYWORD +124 130 SELECT RESERVED_KEYWORD +131 147 IDENT NO_KEYWORD +147 148 ASCII_40 NO_KEYWORD +148 165 SCONST NO_KEYWORD +165 166 ASCII_41 NO_KEYWORD +== 012 +-- but it's OK if we force plan rebuilding +discard plans +-- +0 42 SQL_COMMENT NO_KEYWORD +43 50 DISCARD UNRESERVED_KEYWORD +51 56 PLANS UNRESERVED_KEYWORD +== 013 +select show_result_type('select 2.0 as a') +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 41 SCONST NO_KEYWORD +41 42 ASCII_41 NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_call.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_call.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_call.test b/parser/testdata/scan/plpgsql_regress/plpgsql_call.test new file mode 100644 index 0000000..0dd32d1 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_call.test @@ -0,0 +1,1315 @@ +== 001 +|-- +-- Tests for procedures / CALL syntax +|-- + +CREATE PROCEDURE test_proc1() +LANGUAGE plpgsql +AS $$ +BEGIN + NULL; +END; +$$ +-- +0 2 SQL_COMMENT NO_KEYWORD +3 40 SQL_COMMENT NO_KEYWORD +41 43 SQL_COMMENT NO_KEYWORD +45 51 CREATE RESERVED_KEYWORD +52 61 PROCEDURE UNRESERVED_KEYWORD +62 72 IDENT NO_KEYWORD +72 73 ASCII_40 NO_KEYWORD +73 74 ASCII_41 NO_KEYWORD +75 83 LANGUAGE UNRESERVED_KEYWORD +84 91 IDENT NO_KEYWORD +92 94 AS RESERVED_KEYWORD +95 121 SCONST NO_KEYWORD +== 002 +CALL test_proc1() +-- +0 4 CALL UNRESERVED_KEYWORD +5 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 17 ASCII_41 NO_KEYWORD +== 003 +-- error: can't return non-NULL +CREATE PROCEDURE test_proc2() +LANGUAGE plpgsql +AS $$ +BEGIN + RETURN 5; +END; +$$ +-- +0 31 SQL_COMMENT NO_KEYWORD +32 38 CREATE RESERVED_KEYWORD +39 48 PROCEDURE UNRESERVED_KEYWORD +49 59 IDENT NO_KEYWORD +59 60 ASCII_40 NO_KEYWORD +60 61 ASCII_41 NO_KEYWORD +62 70 LANGUAGE UNRESERVED_KEYWORD +71 78 IDENT NO_KEYWORD +79 81 AS RESERVED_KEYWORD +82 112 SCONST NO_KEYWORD +== 004 +CREATE TABLE test1 (a int) +-- +0 6 CREATE RESERVED_KEYWORD +7 12 TABLE RESERVED_KEYWORD +13 18 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 IDENT NO_KEYWORD +22 25 INT_P COL_NAME_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 005 +CREATE PROCEDURE test_proc3(x int) +LANGUAGE plpgsql +AS $$ +BEGIN + INSERT INTO test1 VALUES (x); +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 29 IDENT NO_KEYWORD +30 33 INT_P COL_NAME_KEYWORD +33 34 ASCII_41 NO_KEYWORD +35 43 LANGUAGE UNRESERVED_KEYWORD +44 51 IDENT NO_KEYWORD +52 54 AS RESERVED_KEYWORD +55 105 SCONST NO_KEYWORD +== 006 +CALL test_proc3(55) +-- +0 4 CALL UNRESERVED_KEYWORD +5 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 007 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 008 +-- Check that plan revalidation doesn't prevent setting transaction properties +-- (bug #18059). This test must include the first temp-object creation in +-- this script, or it won't exercise the bug scenario. Hence we put it early. +CREATE PROCEDURE test_proc3a() +LANGUAGE plpgsql +AS $$ +BEGIN + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + RAISE NOTICE 'done'; +END; +$$ +-- +0 78 SQL_COMMENT NO_KEYWORD +79 153 SQL_COMMENT NO_KEYWORD +154 232 SQL_COMMENT NO_KEYWORD +233 239 CREATE RESERVED_KEYWORD +240 249 PROCEDURE UNRESERVED_KEYWORD +250 261 IDENT NO_KEYWORD +261 262 ASCII_40 NO_KEYWORD +262 263 ASCII_41 NO_KEYWORD +264 272 LANGUAGE UNRESERVED_KEYWORD +273 280 IDENT NO_KEYWORD +281 283 AS RESERVED_KEYWORD +284 387 SCONST NO_KEYWORD +== 009 +CALL test_proc3a() +-- +0 4 CALL UNRESERVED_KEYWORD +5 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ASCII_41 NO_KEYWORD +== 010 +CREATE TEMP TABLE tt1(f1 int) +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TEMP UNRESERVED_KEYWORD +12 17 TABLE RESERVED_KEYWORD +18 21 IDENT NO_KEYWORD +21 22 ASCII_40 NO_KEYWORD +22 24 IDENT NO_KEYWORD +25 28 INT_P COL_NAME_KEYWORD +28 29 ASCII_41 NO_KEYWORD +== 011 +CALL test_proc3a() +-- +0 4 CALL UNRESERVED_KEYWORD +5 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ASCII_41 NO_KEYWORD +== 012 +-- nested CALL +TRUNCATE TABLE test1 +-- +0 14 SQL_COMMENT NO_KEYWORD +15 23 TRUNCATE UNRESERVED_KEYWORD +24 29 TABLE RESERVED_KEYWORD +30 35 IDENT NO_KEYWORD +== 013 +CREATE PROCEDURE test_proc4(y int) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL test_proc3(y); + CALL test_proc3($1); +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 29 IDENT NO_KEYWORD +30 33 INT_P COL_NAME_KEYWORD +33 34 ASCII_41 NO_KEYWORD +35 43 LANGUAGE UNRESERVED_KEYWORD +44 51 IDENT NO_KEYWORD +52 54 AS RESERVED_KEYWORD +55 120 SCONST NO_KEYWORD +== 014 +CALL test_proc4(66) +-- +0 4 CALL UNRESERVED_KEYWORD +5 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 015 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 016 +CALL test_proc4(66) +-- +0 4 CALL UNRESERVED_KEYWORD +5 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 017 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 018 +-- output arguments + +CREATE PROCEDURE test_proc5(INOUT a text) +LANGUAGE plpgsql +AS $$ +BEGIN + a := a || '+' || a; +END; +$$ +-- +0 19 SQL_COMMENT NO_KEYWORD +21 27 CREATE RESERVED_KEYWORD +28 37 PROCEDURE UNRESERVED_KEYWORD +38 48 IDENT NO_KEYWORD +48 49 ASCII_40 NO_KEYWORD +49 54 INOUT COL_NAME_KEYWORD +55 56 IDENT NO_KEYWORD +57 61 TEXT_P UNRESERVED_KEYWORD +61 62 ASCII_41 NO_KEYWORD +63 71 LANGUAGE UNRESERVED_KEYWORD +72 79 IDENT NO_KEYWORD +80 82 AS RESERVED_KEYWORD +83 123 SCONST NO_KEYWORD +== 019 +CALL test_proc5('abc') +-- +0 4 CALL UNRESERVED_KEYWORD +5 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 21 SCONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 020 +CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + b := b * a; + c := c * a; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 29 IDENT NO_KEYWORD +30 33 INT_P COL_NAME_KEYWORD +33 34 ASCII_44 NO_KEYWORD +35 40 INOUT COL_NAME_KEYWORD +41 42 IDENT NO_KEYWORD +43 46 INT_P COL_NAME_KEYWORD +46 47 ASCII_44 NO_KEYWORD +48 53 INOUT COL_NAME_KEYWORD +54 55 IDENT NO_KEYWORD +56 59 INT_P COL_NAME_KEYWORD +59 60 ASCII_41 NO_KEYWORD +61 69 LANGUAGE UNRESERVED_KEYWORD +70 77 IDENT NO_KEYWORD +78 80 AS RESERVED_KEYWORD +81 129 SCONST NO_KEYWORD +== 021 +CALL test_proc6(2, 3, 4) +-- +0 4 CALL UNRESERVED_KEYWORD +5 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 17 ICONST NO_KEYWORD +17 18 ASCII_44 NO_KEYWORD +19 20 ICONST NO_KEYWORD +20 21 ASCII_44 NO_KEYWORD +22 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 022 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); + RAISE INFO 'x = %, y = %', x, y; + CALL test_proc6(2, c => y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 220 SCONST NO_KEYWORD +== 023 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 157 SCONST NO_KEYWORD +== 024 +DO +LANGUAGE plpgsql +$$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 147 SCONST NO_KEYWORD +== 025 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 188 SCONST NO_KEYWORD +== 026 +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +-- +0 34 SQL_COMMENT NO_KEYWORD +36 42 CREATE RESERVED_KEYWORD +43 52 PROCEDURE UNRESERVED_KEYWORD +53 63 IDENT NO_KEYWORD +63 64 ASCII_40 NO_KEYWORD +64 65 IDENT NO_KEYWORD +66 69 INT_P COL_NAME_KEYWORD +69 70 ASCII_44 NO_KEYWORD +71 76 INOUT COL_NAME_KEYWORD +77 78 IDENT NO_KEYWORD +79 82 INT_P COL_NAME_KEYWORD +82 83 ASCII_44 NO_KEYWORD +84 89 INOUT COL_NAME_KEYWORD +90 91 IDENT NO_KEYWORD +92 99 NUMERIC COL_NAME_KEYWORD +99 100 ASCII_41 NO_KEYWORD +101 109 LANGUAGE UNRESERVED_KEYWORD +110 117 IDENT NO_KEYWORD +118 120 AS RESERVED_KEYWORD +121 227 SCONST NO_KEYWORD +== 027 +CALL test_proc7(100, -1, -1) +-- +0 4 CALL UNRESERVED_KEYWORD +5 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 19 ICONST NO_KEYWORD +19 20 ASCII_44 NO_KEYWORD +21 22 ASCII_45 NO_KEYWORD +22 23 ICONST NO_KEYWORD +23 24 ASCII_44 NO_KEYWORD +25 26 ASCII_45 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +== 028 +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +-- +0 37 SQL_COMMENT NO_KEYWORD +39 45 CREATE RESERVED_KEYWORD +46 55 PROCEDURE UNRESERVED_KEYWORD +56 67 IDENT NO_KEYWORD +67 68 ASCII_40 NO_KEYWORD +68 69 IDENT NO_KEYWORD +70 73 INT_P COL_NAME_KEYWORD +73 74 ASCII_44 NO_KEYWORD +75 80 INOUT COL_NAME_KEYWORD +81 82 IDENT NO_KEYWORD +83 86 INT_P COL_NAME_KEYWORD +86 87 ASCII_44 NO_KEYWORD +88 93 INOUT COL_NAME_KEYWORD +94 95 IDENT NO_KEYWORD +96 103 NUMERIC COL_NAME_KEYWORD +103 104 ASCII_41 NO_KEYWORD +105 113 LANGUAGE UNRESERVED_KEYWORD +114 121 IDENT NO_KEYWORD +122 124 AS RESERVED_KEYWORD +125 180 SCONST NO_KEYWORD +== 029 +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 29 IDENT NO_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 32 IDENT NO_KEYWORD +33 36 INT_P COL_NAME_KEYWORD +36 37 ASCII_41 NO_KEYWORD +38 46 LANGUAGE UNRESERVED_KEYWORD +47 54 IDENT NO_KEYWORD +55 57 AS RESERVED_KEYWORD +58 182 SCONST NO_KEYWORD +== 030 +CALL test_proc7cc(10) +-- +0 4 CALL UNRESERVED_KEYWORD +5 17 IDENT NO_KEYWORD +17 18 ASCII_40 NO_KEYWORD +18 20 ICONST NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 031 +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +-- +0 32 SQL_COMMENT NO_KEYWORD +34 40 CREATE RESERVED_KEYWORD +41 50 PROCEDURE UNRESERVED_KEYWORD +51 62 IDENT NO_KEYWORD +62 63 ASCII_40 NO_KEYWORD +63 68 INOUT COL_NAME_KEYWORD +69 70 IDENT NO_KEYWORD +71 74 INT_P COL_NAME_KEYWORD +74 75 ASCII_44 NO_KEYWORD +76 81 INOUT COL_NAME_KEYWORD +82 83 IDENT NO_KEYWORD +84 87 INT_P COL_NAME_KEYWORD +87 88 ASCII_41 NO_KEYWORD +89 97 LANGUAGE UNRESERVED_KEYWORD +98 105 IDENT NO_KEYWORD +106 108 AS RESERVED_KEYWORD +109 190 SCONST NO_KEYWORD +== 032 +CALL test_proc8a(10, 20) +-- +0 4 CALL UNRESERVED_KEYWORD +5 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 19 ICONST NO_KEYWORD +19 20 ASCII_44 NO_KEYWORD +21 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 033 +CALL test_proc8a(b => 20, a => 10) +-- +0 4 CALL UNRESERVED_KEYWORD +5 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 IDENT NO_KEYWORD +19 21 EQUALS_GREATER NO_KEYWORD +22 24 ICONST NO_KEYWORD +24 25 ASCII_44 NO_KEYWORD +26 27 IDENT NO_KEYWORD +28 30 EQUALS_GREATER NO_KEYWORD +31 33 ICONST NO_KEYWORD +33 34 ASCII_41 NO_KEYWORD +== 034 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 208 SCONST NO_KEYWORD +== 035 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 34 INOUT COL_NAME_KEYWORD +35 36 IDENT NO_KEYWORD +37 40 INT_P COL_NAME_KEYWORD +40 41 ASCII_44 NO_KEYWORD +42 47 INOUT COL_NAME_KEYWORD +48 49 IDENT NO_KEYWORD +50 53 INT_P COL_NAME_KEYWORD +53 54 ASCII_44 NO_KEYWORD +55 60 INOUT COL_NAME_KEYWORD +61 62 IDENT NO_KEYWORD +63 66 INT_P COL_NAME_KEYWORD +66 67 ASCII_41 NO_KEYWORD +68 76 LANGUAGE UNRESERVED_KEYWORD +77 84 IDENT NO_KEYWORD +85 87 AS RESERVED_KEYWORD +88 194 SCONST NO_KEYWORD +== 036 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 256 SCONST NO_KEYWORD +== 037 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 34 INOUT COL_NAME_KEYWORD +35 36 IDENT NO_KEYWORD +37 40 INT_P COL_NAME_KEYWORD +40 41 ASCII_44 NO_KEYWORD +42 47 INOUT COL_NAME_KEYWORD +48 49 IDENT NO_KEYWORD +50 53 INT_P COL_NAME_KEYWORD +53 54 ASCII_44 NO_KEYWORD +55 60 INOUT COL_NAME_KEYWORD +61 62 IDENT NO_KEYWORD +63 66 INT_P COL_NAME_KEYWORD +67 74 DEFAULT RESERVED_KEYWORD +75 77 ICONST NO_KEYWORD +77 78 ASCII_41 NO_KEYWORD +79 87 LANGUAGE UNRESERVED_KEYWORD +88 95 IDENT NO_KEYWORD +96 98 AS RESERVED_KEYWORD +99 205 SCONST NO_KEYWORD +== 038 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 417 SCONST NO_KEYWORD +== 039 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 195 SCONST NO_KEYWORD +== 040 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 200 SCONST NO_KEYWORD +== 041 +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +-- +0 17 SQL_COMMENT NO_KEYWORD +19 25 CREATE RESERVED_KEYWORD +26 35 PROCEDURE UNRESERVED_KEYWORD +36 46 IDENT NO_KEYWORD +46 47 ASCII_40 NO_KEYWORD +47 49 IN_P RESERVED_KEYWORD +50 51 IDENT NO_KEYWORD +52 55 INT_P COL_NAME_KEYWORD +55 56 ASCII_44 NO_KEYWORD +57 60 OUT_P COL_NAME_KEYWORD +61 62 IDENT NO_KEYWORD +63 66 INT_P COL_NAME_KEYWORD +66 67 ASCII_41 NO_KEYWORD +68 76 LANGUAGE UNRESERVED_KEYWORD +77 84 IDENT NO_KEYWORD +85 87 AS RESERVED_KEYWORD +88 153 SCONST NO_KEYWORD +== 042 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 130 SCONST NO_KEYWORD +== 043 +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 31 IN_P RESERVED_KEYWORD +32 33 IDENT NO_KEYWORD +34 37 INT_P COL_NAME_KEYWORD +37 38 ASCII_44 NO_KEYWORD +39 42 OUT_P COL_NAME_KEYWORD +43 44 IDENT NO_KEYWORD +45 48 INT_P COL_NAME_KEYWORD +48 49 ASCII_44 NO_KEYWORD +50 52 IN_P RESERVED_KEYWORD +53 54 IDENT NO_KEYWORD +55 58 INT_P COL_NAME_KEYWORD +59 66 DEFAULT RESERVED_KEYWORD +67 69 ICONST NO_KEYWORD +69 70 ASCII_41 NO_KEYWORD +71 79 LANGUAGE UNRESERVED_KEYWORD +80 87 IDENT NO_KEYWORD +88 90 AS RESERVED_KEYWORD +91 165 SCONST NO_KEYWORD +== 044 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 880 SCONST NO_KEYWORD +== 045 +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +-- +0 17 SQL_COMMENT NO_KEYWORD +19 25 CREATE RESERVED_KEYWORD +26 35 PROCEDURE UNRESERVED_KEYWORD +36 47 IDENT NO_KEYWORD +47 48 ASCII_40 NO_KEYWORD +48 49 IDENT NO_KEYWORD +50 53 OUT_P COL_NAME_KEYWORD +54 57 INT_P COL_NAME_KEYWORD +57 58 ASCII_44 NO_KEYWORD +59 67 VARIADIC RESERVED_KEYWORD +68 69 IDENT NO_KEYWORD +70 73 INT_P COL_NAME_KEYWORD +73 74 ASCII_91 NO_KEYWORD +74 75 ASCII_93 NO_KEYWORD +75 76 ASCII_41 NO_KEYWORD +77 85 LANGUAGE UNRESERVED_KEYWORD +86 93 IDENT NO_KEYWORD +94 96 AS RESERVED_KEYWORD +97 168 SCONST NO_KEYWORD +== 046 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 163 SCONST NO_KEYWORD +== 047 +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +-- +0 28 SQL_COMMENT NO_KEYWORD +30 36 CREATE RESERVED_KEYWORD +37 46 PROCEDURE UNRESERVED_KEYWORD +47 58 IDENT NO_KEYWORD +58 59 ASCII_40 NO_KEYWORD +59 60 IDENT NO_KEYWORD +61 71 IDENT NO_KEYWORD +71 72 ASCII_44 NO_KEYWORD +73 76 OUT_P COL_NAME_KEYWORD +77 78 IDENT NO_KEYWORD +79 89 IDENT NO_KEYWORD +89 90 ASCII_44 NO_KEYWORD +91 94 OUT_P COL_NAME_KEYWORD +95 96 IDENT NO_KEYWORD +97 105 IDENT NO_KEYWORD +105 106 ASCII_41 NO_KEYWORD +107 115 LANGUAGE UNRESERVED_KEYWORD +116 123 IDENT NO_KEYWORD +124 126 AS RESERVED_KEYWORD +127 196 SCONST NO_KEYWORD +== 048 +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 146 SCONST NO_KEYWORD +== 049 +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 157 SCONST NO_KEYWORD +== 050 +-- transition variable assignment + +TRUNCATE test1 +-- +0 33 SQL_COMMENT NO_KEYWORD +35 43 TRUNCATE UNRESERVED_KEYWORD +44 49 IDENT NO_KEYWORD +== 051 +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ASCII_41 NO_KEYWORD +31 38 RETURNS UNRESERVED_KEYWORD +39 46 TRIGGER UNRESERVED_KEYWORD +47 55 LANGUAGE UNRESERVED_KEYWORD +56 63 IDENT NO_KEYWORD +64 66 AS RESERVED_KEYWORD +67 161 SCONST NO_KEYWORD +== 052 +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +-- +0 6 CREATE RESERVED_KEYWORD +7 14 TRIGGER UNRESERVED_KEYWORD +15 17 IDENT NO_KEYWORD +18 24 BEFORE UNRESERVED_KEYWORD +25 31 INSERT UNRESERVED_KEYWORD +32 34 ON RESERVED_KEYWORD +35 40 IDENT NO_KEYWORD +41 48 EXECUTE UNRESERVED_KEYWORD +49 58 PROCEDURE UNRESERVED_KEYWORD +59 71 IDENT NO_KEYWORD +71 72 ASCII_40 NO_KEYWORD +72 73 ASCII_41 NO_KEYWORD +== 053 +INSERT INTO test1 VALUES (1), (2), (3) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 17 IDENT NO_KEYWORD +18 24 VALUES COL_NAME_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +28 29 ASCII_44 NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +33 34 ASCII_44 NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 37 ICONST NO_KEYWORD +37 38 ASCII_41 NO_KEYWORD +== 054 +UPDATE test1 SET a = 22 WHERE a = 2 +-- +0 6 UPDATE UNRESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +13 16 SET UNRESERVED_KEYWORD +17 18 IDENT NO_KEYWORD +19 20 ASCII_61 NO_KEYWORD +21 23 ICONST NO_KEYWORD +24 29 WHERE RESERVED_KEYWORD +30 31 IDENT NO_KEYWORD +32 33 ASCII_61 NO_KEYWORD +34 35 ICONST NO_KEYWORD +== 055 +SELECT * FROM test1 ORDER BY a +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +20 25 ORDER RESERVED_KEYWORD +26 28 BY UNRESERVED_KEYWORD +29 30 IDENT NO_KEYWORD +== 056 +DROP PROCEDURE test_proc1 +-- +0 4 DROP UNRESERVED_KEYWORD +5 14 PROCEDURE UNRESERVED_KEYWORD +15 25 IDENT NO_KEYWORD +== 057 +DROP PROCEDURE test_proc3 +-- +0 4 DROP UNRESERVED_KEYWORD +5 14 PROCEDURE UNRESERVED_KEYWORD +15 25 IDENT NO_KEYWORD +== 058 +DROP PROCEDURE test_proc4 +-- +0 4 DROP UNRESERVED_KEYWORD +5 14 PROCEDURE UNRESERVED_KEYWORD +15 25 IDENT NO_KEYWORD +== 059 +DROP TABLE test1 +-- +0 4 DROP UNRESERVED_KEYWORD +5 10 TABLE RESERVED_KEYWORD +11 16 IDENT NO_KEYWORD +== 060 +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +-- +0 43 SQL_COMMENT NO_KEYWORD +45 51 CREATE RESERVED_KEYWORD +52 61 PROCEDURE UNRESERVED_KEYWORD +62 64 IDENT NO_KEYWORD +64 65 ASCII_40 NO_KEYWORD +65 70 IDENT NO_KEYWORD +71 74 INT_P COL_NAME_KEYWORD +74 75 ASCII_44 NO_KEYWORD +76 82 IDENT NO_KEYWORD +83 88 INOUT COL_NAME_KEYWORD +89 93 TEXT_P UNRESERVED_KEYWORD +94 95 ASCII_61 NO_KEYWORD +96 100 NULL_P RESERVED_KEYWORD +100 101 ASCII_41 NO_KEYWORD +102 104 AS RESERVED_KEYWORD +105 153 SCONST NO_KEYWORD +154 162 LANGUAGE UNRESERVED_KEYWORD +163 170 IDENT NO_KEYWORD +== 061 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 165 SCONST NO_KEYWORD +== 062 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 139 SCONST NO_KEYWORD +== 063 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 103 SCONST NO_KEYWORD +== 064 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 133 SCONST NO_KEYWORD +== 065 +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +-- +0 54 SQL_COMMENT NO_KEYWORD +55 133 SQL_COMMENT NO_KEYWORD +135 141 CREATE RESERVED_KEYWORD +142 151 PROCEDURE UNRESERVED_KEYWORD +152 159 IDENT NO_KEYWORD +160 161 ASCII_40 NO_KEYWORD +161 163 IDENT NO_KEYWORD +164 167 INT_P COL_NAME_KEYWORD +167 168 ASCII_41 NO_KEYWORD +169 171 AS RESERVED_KEYWORD +172 220 SCONST NO_KEYWORD +221 229 LANGUAGE UNRESERVED_KEYWORD +230 237 IDENT NO_KEYWORD +== 066 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 17 IDENT NO_KEYWORD +17 18 ASCII_40 NO_KEYWORD +18 21 INT_P COL_NAME_KEYWORD +21 22 ASCII_41 NO_KEYWORD +23 30 RETURNS UNRESERVED_KEYWORD +31 34 INT_P COL_NAME_KEYWORD +35 37 AS RESERVED_KEYWORD +38 57 SCONST NO_KEYWORD +58 66 LANGUAGE UNRESERVED_KEYWORD +67 70 SQL_P UNRESERVED_KEYWORD +== 067 +CREATE PROCEDURE outer_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 24 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 28 IDENT NO_KEYWORD +29 32 INT_P COL_NAME_KEYWORD +32 33 ASCII_41 NO_KEYWORD +34 36 AS RESERVED_KEYWORD +37 108 SCONST NO_KEYWORD +109 117 LANGUAGE UNRESERVED_KEYWORD +118 125 IDENT NO_KEYWORD +== 068 +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 23 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 27 IDENT NO_KEYWORD +28 31 INT_P COL_NAME_KEYWORD +31 32 ASCII_41 NO_KEYWORD +33 40 RETURNS UNRESERVED_KEYWORD +41 45 IDENT NO_KEYWORD +46 48 AS RESERVED_KEYWORD +49 120 SCONST NO_KEYWORD +121 129 LANGUAGE UNRESERVED_KEYWORD +130 137 IDENT NO_KEYWORD +== 069 +CALL outer_p(42) +-- +0 4 CALL UNRESERVED_KEYWORD +5 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 15 ICONST NO_KEYWORD +15 16 ASCII_41 NO_KEYWORD +== 070 +SELECT outer_f(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 14 IDENT NO_KEYWORD +14 15 ASCII_40 NO_KEYWORD +15 17 ICONST NO_KEYWORD +17 18 ASCII_41 NO_KEYWORD +== 071 +DROP FUNCTION f(int) +-- +0 4 DROP UNRESERVED_KEYWORD +5 13 FUNCTION UNRESERVED_KEYWORD +14 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 19 INT_P COL_NAME_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 072 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 17 IDENT NO_KEYWORD +17 18 ASCII_40 NO_KEYWORD +18 21 INT_P COL_NAME_KEYWORD +21 22 ASCII_41 NO_KEYWORD +23 30 RETURNS UNRESERVED_KEYWORD +31 34 INT_P COL_NAME_KEYWORD +35 37 AS RESERVED_KEYWORD +38 57 SCONST NO_KEYWORD +58 66 LANGUAGE UNRESERVED_KEYWORD +67 70 SQL_P UNRESERVED_KEYWORD +== 073 +CALL outer_p(42) +-- +0 4 CALL UNRESERVED_KEYWORD +5 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 15 ICONST NO_KEYWORD +15 16 ASCII_41 NO_KEYWORD +== 074 +SELECT outer_f(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 14 IDENT NO_KEYWORD +14 15 ASCII_40 NO_KEYWORD +15 17 ICONST NO_KEYWORD +17 18 ASCII_41 NO_KEYWORD +== 075 +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +-- +0 63 SQL_COMMENT NO_KEYWORD +65 71 CREATE RESERVED_KEYWORD +72 77 TABLE RESERVED_KEYWORD +78 84 IDENT NO_KEYWORD +85 86 ASCII_40 NO_KEYWORD +86 87 IDENT NO_KEYWORD +88 91 INT_P COL_NAME_KEYWORD +91 92 ASCII_41 NO_KEYWORD +== 076 +INSERT INTO t_test VALUES (0) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 18 IDENT NO_KEYWORD +19 25 VALUES COL_NAME_KEYWORD +26 27 ASCII_40 NO_KEYWORD +27 28 ICONST NO_KEYWORD +28 29 ASCII_41 NO_KEYWORD +== 077 +CREATE FUNCTION f_get_x () RETURNS int +AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 23 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +27 34 RETURNS UNRESERVED_KEYWORD +35 38 INT_P COL_NAME_KEYWORD +39 41 AS RESERVED_KEYWORD +42 136 SCONST NO_KEYWORD +137 145 LANGUAGE UNRESERVED_KEYWORD +146 153 IDENT NO_KEYWORD +154 160 STABLE UNRESERVED_KEYWORD +== 078 +CREATE PROCEDURE f_print_x (x int) +AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 26 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 29 IDENT NO_KEYWORD +30 33 INT_P COL_NAME_KEYWORD +33 34 ASCII_41 NO_KEYWORD +35 37 AS RESERVED_KEYWORD +38 87 SCONST NO_KEYWORD +88 96 LANGUAGE UNRESERVED_KEYWORD +97 104 IDENT NO_KEYWORD +== 079 +-- test in non-atomic context +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +-- +0 29 SQL_COMMENT NO_KEYWORD +30 32 DO RESERVED_KEYWORD +33 260 SCONST NO_KEYWORD +== 080 +-- test in non-atomic context, except exception block is locally atomic +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +-- +0 71 SQL_COMMENT NO_KEYWORD +72 74 DO RESERVED_KEYWORD +75 383 SCONST NO_KEYWORD +== 081 +-- test in atomic context +BEGIN +-- +0 25 SQL_COMMENT NO_KEYWORD +26 31 BEGIN_P UNRESERVED_KEYWORD +== 082 +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 218 SCONST NO_KEYWORD +== 083 +ROLLBACK +-- +0 8 ROLLBACK UNRESERVED_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_control.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_control.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_control.test b/parser/testdata/scan/plpgsql_regress/plpgsql_control.test new file mode 100644 index 0000000..b2768de --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_control.test @@ -0,0 +1,973 @@ +== 001 +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +-- +0 2 SQL_COMMENT NO_KEYWORD +3 43 SQL_COMMENT NO_KEYWORD +44 46 SQL_COMMENT NO_KEYWORD +48 67 SQL_COMMENT NO_KEYWORD +69 71 DO RESERVED_KEYWORD +72 924 SCONST NO_KEYWORD +== 002 +-- BY can't be zero or negative +do $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +-- +0 31 SQL_COMMENT NO_KEYWORD +32 34 DO RESERVED_KEYWORD +35 127 SCONST NO_KEYWORD +== 003 +do $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 97 SCONST NO_KEYWORD +== 004 +do $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 113 SCONST NO_KEYWORD +== 005 +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +-- +0 21 SQL_COMMENT NO_KEYWORD +23 29 CREATE RESERVED_KEYWORD +30 35 TABLE RESERVED_KEYWORD +36 47 IDENT NO_KEYWORD +47 48 ASCII_40 NO_KEYWORD +48 51 IDENT NO_KEYWORD +52 58 IDENT NO_KEYWORD +58 59 ASCII_44 NO_KEYWORD +60 61 IDENT NO_KEYWORD +62 69 INTEGER COL_NAME_KEYWORD +69 70 ASCII_41 NO_KEYWORD +== 006 +insert into conttesttbl(v) values(10) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 IDENT NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +27 33 VALUES COL_NAME_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 36 ICONST NO_KEYWORD +36 37 ASCII_41 NO_KEYWORD +== 007 +insert into conttesttbl(v) values(20) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 IDENT NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +27 33 VALUES COL_NAME_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 36 ICONST NO_KEYWORD +36 37 ASCII_41 NO_KEYWORD +== 008 +insert into conttesttbl(v) values(30) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 IDENT NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +27 33 VALUES COL_NAME_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 36 ICONST NO_KEYWORD +36 37 ASCII_41 NO_KEYWORD +== 009 +insert into conttesttbl(v) values(40) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 IDENT NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +27 33 VALUES COL_NAME_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 36 ICONST NO_KEYWORD +36 37 ASCII_41 NO_KEYWORD +== 010 +create function continue_test1() returns void as $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ language plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 30 IDENT NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 32 ASCII_41 NO_KEYWORD +33 40 RETURNS UNRESERVED_KEYWORD +41 45 IDENT NO_KEYWORD +46 48 AS RESERVED_KEYWORD +49 1873 SCONST NO_KEYWORD +1874 1882 LANGUAGE UNRESERVED_KEYWORD +1883 1890 IDENT NO_KEYWORD +== 011 +select continue_test1() +-- +0 6 SELECT RESERVED_KEYWORD +7 21 IDENT NO_KEYWORD +21 22 ASCII_40 NO_KEYWORD +22 23 ASCII_41 NO_KEYWORD +== 012 +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $$ +begin + begin + continue; + end; +end; +$$ language plpgsql +-- +0 52 SQL_COMMENT NO_KEYWORD +53 59 CREATE RESERVED_KEYWORD +60 68 FUNCTION UNRESERVED_KEYWORD +69 84 IDENT NO_KEYWORD +84 85 ASCII_40 NO_KEYWORD +85 86 ASCII_41 NO_KEYWORD +87 94 RETURNS UNRESERVED_KEYWORD +95 99 IDENT NO_KEYWORD +100 102 AS RESERVED_KEYWORD +103 156 SCONST NO_KEYWORD +157 165 LANGUAGE UNRESERVED_KEYWORD +166 173 IDENT NO_KEYWORD +== 013 +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $$ +begin + begin + exit; + end; +end; +$$ language plpgsql +-- +0 58 SQL_COMMENT NO_KEYWORD +59 65 CREATE RESERVED_KEYWORD +66 74 FUNCTION UNRESERVED_KEYWORD +75 86 IDENT NO_KEYWORD +86 87 ASCII_40 NO_KEYWORD +87 88 ASCII_41 NO_KEYWORD +89 96 RETURNS UNRESERVED_KEYWORD +97 101 IDENT NO_KEYWORD +102 104 AS RESERVED_KEYWORD +105 154 SCONST NO_KEYWORD +155 163 LANGUAGE UNRESERVED_KEYWORD +164 171 IDENT NO_KEYWORD +== 014 +-- should fail: no such label +create function continue_error2() returns void as $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +0 29 SQL_COMMENT NO_KEYWORD +30 36 CREATE RESERVED_KEYWORD +37 45 FUNCTION UNRESERVED_KEYWORD +46 61 IDENT NO_KEYWORD +61 62 ASCII_40 NO_KEYWORD +62 63 ASCII_41 NO_KEYWORD +64 71 RETURNS UNRESERVED_KEYWORD +72 76 IDENT NO_KEYWORD +77 79 AS RESERVED_KEYWORD +80 182 SCONST NO_KEYWORD +183 191 LANGUAGE UNRESERVED_KEYWORD +192 199 IDENT NO_KEYWORD +== 015 +-- should fail: no such label +create function exit_error2() returns void as $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +0 29 SQL_COMMENT NO_KEYWORD +30 36 CREATE RESERVED_KEYWORD +37 45 FUNCTION UNRESERVED_KEYWORD +46 57 IDENT NO_KEYWORD +57 58 ASCII_40 NO_KEYWORD +58 59 ASCII_41 NO_KEYWORD +60 67 RETURNS UNRESERVED_KEYWORD +68 72 IDENT NO_KEYWORD +73 75 AS RESERVED_KEYWORD +76 174 SCONST NO_KEYWORD +175 183 LANGUAGE UNRESERVED_KEYWORD +184 191 IDENT NO_KEYWORD +== 016 +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ language plpgsql +-- +0 67 SQL_COMMENT NO_KEYWORD +68 74 CREATE RESERVED_KEYWORD +75 83 FUNCTION UNRESERVED_KEYWORD +84 99 IDENT NO_KEYWORD +99 100 ASCII_40 NO_KEYWORD +100 101 ASCII_41 NO_KEYWORD +102 109 RETURNS UNRESERVED_KEYWORD +110 114 IDENT NO_KEYWORD +115 117 AS RESERVED_KEYWORD +118 240 SCONST NO_KEYWORD +241 249 LANGUAGE UNRESERVED_KEYWORD +250 257 IDENT NO_KEYWORD +== 017 +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ language plpgsql +-- +0 69 SQL_COMMENT NO_KEYWORD +70 76 CREATE RESERVED_KEYWORD +77 85 FUNCTION UNRESERVED_KEYWORD +86 97 IDENT NO_KEYWORD +97 98 ASCII_40 NO_KEYWORD +98 99 ASCII_41 NO_KEYWORD +100 107 RETURNS UNRESERVED_KEYWORD +108 112 IDENT NO_KEYWORD +113 115 AS RESERVED_KEYWORD +116 285 SCONST NO_KEYWORD +286 294 LANGUAGE UNRESERVED_KEYWORD +295 302 IDENT NO_KEYWORD +== 018 +select exit_block1() +-- +0 6 SELECT RESERVED_KEYWORD +7 18 IDENT NO_KEYWORD +18 19 ASCII_40 NO_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 019 +-- verbose end block and end loop +create function end_label1() returns void as $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ language plpgsql +-- +0 33 SQL_COMMENT NO_KEYWORD +34 40 CREATE RESERVED_KEYWORD +41 49 FUNCTION UNRESERVED_KEYWORD +50 60 IDENT NO_KEYWORD +60 61 ASCII_40 NO_KEYWORD +61 62 ASCII_41 NO_KEYWORD +63 70 RETURNS UNRESERVED_KEYWORD +71 75 IDENT NO_KEYWORD +76 78 AS RESERVED_KEYWORD +79 301 SCONST NO_KEYWORD +302 310 LANGUAGE UNRESERVED_KEYWORD +311 318 IDENT NO_KEYWORD +== 020 +select end_label1() +-- +0 6 SELECT RESERVED_KEYWORD +7 17 IDENT NO_KEYWORD +17 18 ASCII_40 NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 021 +-- should fail: undefined end label +create function end_label2() returns void as $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ language plpgsql +-- +0 35 SQL_COMMENT NO_KEYWORD +36 42 CREATE RESERVED_KEYWORD +43 51 FUNCTION UNRESERVED_KEYWORD +52 62 IDENT NO_KEYWORD +62 63 ASCII_40 NO_KEYWORD +63 64 ASCII_41 NO_KEYWORD +65 72 RETURNS UNRESERVED_KEYWORD +73 77 IDENT NO_KEYWORD +78 80 AS RESERVED_KEYWORD +81 150 SCONST NO_KEYWORD +151 159 LANGUAGE UNRESERVED_KEYWORD +160 167 IDENT NO_KEYWORD +== 022 +-- should fail: end label does not match start label +create function end_label3() returns void as $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +0 52 SQL_COMMENT NO_KEYWORD +53 59 CREATE RESERVED_KEYWORD +60 68 FUNCTION UNRESERVED_KEYWORD +69 79 IDENT NO_KEYWORD +79 80 ASCII_40 NO_KEYWORD +80 81 ASCII_41 NO_KEYWORD +82 89 RETURNS UNRESERVED_KEYWORD +90 94 IDENT NO_KEYWORD +95 97 AS RESERVED_KEYWORD +98 207 SCONST NO_KEYWORD +208 216 LANGUAGE UNRESERVED_KEYWORD +217 224 IDENT NO_KEYWORD +== 023 +-- should fail: end label on a block without a start label +create function end_label4() returns void as $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +0 58 SQL_COMMENT NO_KEYWORD +59 65 CREATE RESERVED_KEYWORD +66 74 FUNCTION UNRESERVED_KEYWORD +75 85 IDENT NO_KEYWORD +85 86 ASCII_40 NO_KEYWORD +86 87 ASCII_41 NO_KEYWORD +88 95 RETURNS UNRESERVED_KEYWORD +96 100 IDENT NO_KEYWORD +101 103 AS RESERVED_KEYWORD +104 195 SCONST NO_KEYWORD +196 204 LANGUAGE UNRESERVED_KEYWORD +205 212 IDENT NO_KEYWORD +== 024 +-- unlabeled exit matches no blocks +do $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +-- +0 35 SQL_COMMENT NO_KEYWORD +36 38 DO RESERVED_KEYWORD +39 315 SCONST NO_KEYWORD +== 025 +-- check exit out of an unlabeled block to a labeled one +do $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +-- +0 56 SQL_COMMENT NO_KEYWORD +57 59 DO RESERVED_KEYWORD +60 388 SCONST NO_KEYWORD +== 026 +-- check exit out of outermost block +do $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +-- +0 36 SQL_COMMENT NO_KEYWORD +37 39 DO RESERVED_KEYWORD +40 208 SCONST NO_KEYWORD +== 027 +-- unlabeled exit does match a while loop +do $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +-- +0 41 SQL_COMMENT NO_KEYWORD +42 44 DO RESERVED_KEYWORD +45 466 SCONST NO_KEYWORD +== 028 +-- check exit out of an unlabeled while to a labeled one +do $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +-- +0 56 SQL_COMMENT NO_KEYWORD +57 59 DO RESERVED_KEYWORD +60 304 SCONST NO_KEYWORD +== 029 +-- continue to an outer while +do $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +-- +0 29 SQL_COMMENT NO_KEYWORD +30 32 DO RESERVED_KEYWORD +33 500 SCONST NO_KEYWORD +== 030 +-- return out of a while +create function return_from_while() returns int language plpgsql as $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +-- +0 24 SQL_COMMENT NO_KEYWORD +25 31 CREATE RESERVED_KEYWORD +32 40 FUNCTION UNRESERVED_KEYWORD +41 58 IDENT NO_KEYWORD +58 59 ASCII_40 NO_KEYWORD +59 60 ASCII_41 NO_KEYWORD +61 68 RETURNS UNRESERVED_KEYWORD +69 72 INT_P COL_NAME_KEYWORD +73 81 LANGUAGE UNRESERVED_KEYWORD +82 89 IDENT NO_KEYWORD +90 92 AS RESERVED_KEYWORD +93 236 SCONST NO_KEYWORD +== 031 +select return_from_while() +-- +0 6 SELECT RESERVED_KEYWORD +7 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 032 +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $proc$ +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice '%', i; + end loop; + -- fore with record var + for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop + raise notice '% % %', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice '%', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop + raise notice '% % %', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop + raise notice '% % %', a, b, c; + end loop; +end; +$proc$ language plpgsql +-- +0 47 SQL_COMMENT NO_KEYWORD +48 54 CREATE RESERVED_KEYWORD +55 63 FUNCTION UNRESERVED_KEYWORD +64 72 IDENT NO_KEYWORD +72 73 ASCII_40 NO_KEYWORD +73 74 ASCII_41 NO_KEYWORD +75 82 RETURNS UNRESERVED_KEYWORD +83 87 IDENT NO_KEYWORD +88 90 AS RESERVED_KEYWORD +91 899 SCONST NO_KEYWORD +900 908 LANGUAGE UNRESERVED_KEYWORD +909 916 IDENT NO_KEYWORD +== 033 +select for_vect() +-- +0 6 SELECT RESERVED_KEYWORD +7 15 IDENT NO_KEYWORD +15 16 ASCII_40 NO_KEYWORD +16 17 ASCII_41 NO_KEYWORD +== 034 +-- CASE statement + +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ language plpgsql immutable +-- +0 17 SQL_COMMENT NO_KEYWORD +19 25 CREATE RESERVED_KEYWORD +26 28 OR RESERVED_KEYWORD +29 36 REPLACE UNRESERVED_KEYWORD +37 45 FUNCTION UNRESERVED_KEYWORD +46 55 IDENT NO_KEYWORD +55 56 ASCII_40 NO_KEYWORD +56 62 BIGINT COL_NAME_KEYWORD +62 63 ASCII_41 NO_KEYWORD +64 71 RETURNS UNRESERVED_KEYWORD +72 76 TEXT_P UNRESERVED_KEYWORD +77 79 AS RESERVED_KEYWORD +80 380 SCONST NO_KEYWORD +381 389 LANGUAGE UNRESERVED_KEYWORD +390 397 IDENT NO_KEYWORD +398 407 IMMUTABLE UNRESERVED_KEYWORD +== 035 +select case_test(1) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 036 +select case_test(2) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 037 +select case_test(3) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 038 +select case_test(4) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 039 +select case_test(5) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 040 +-- fails +select case_test(8) +-- +0 8 SQL_COMMENT NO_KEYWORD +9 15 SELECT RESERVED_KEYWORD +16 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +== 041 +select case_test(10) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 19 ICONST NO_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 042 +select case_test(11) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 19 ICONST NO_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 043 +select case_test(12) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 19 ICONST NO_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 044 +select case_test(13) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 19 ICONST NO_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 045 +-- fails + +create or replace function catch() returns void as $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ language plpgsql +-- +0 8 SQL_COMMENT NO_KEYWORD +10 16 CREATE RESERVED_KEYWORD +17 19 OR RESERVED_KEYWORD +20 27 REPLACE UNRESERVED_KEYWORD +28 36 FUNCTION UNRESERVED_KEYWORD +37 42 IDENT NO_KEYWORD +42 43 ASCII_40 NO_KEYWORD +43 44 ASCII_41 NO_KEYWORD +45 52 RETURNS UNRESERVED_KEYWORD +53 57 IDENT NO_KEYWORD +58 60 AS RESERVED_KEYWORD +61 212 SCONST NO_KEYWORD +213 221 LANGUAGE UNRESERVED_KEYWORD +222 229 IDENT NO_KEYWORD +== 046 +select catch() +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 14 ASCII_41 NO_KEYWORD +== 047 +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +0 49 SQL_COMMENT NO_KEYWORD +50 56 CREATE RESERVED_KEYWORD +57 59 OR RESERVED_KEYWORD +60 67 REPLACE UNRESERVED_KEYWORD +68 76 FUNCTION UNRESERVED_KEYWORD +77 86 IDENT NO_KEYWORD +86 87 ASCII_40 NO_KEYWORD +87 93 BIGINT COL_NAME_KEYWORD +93 94 ASCII_41 NO_KEYWORD +95 102 RETURNS UNRESERVED_KEYWORD +103 107 TEXT_P UNRESERVED_KEYWORD +108 110 AS RESERVED_KEYWORD +111 286 SCONST NO_KEYWORD +287 295 LANGUAGE UNRESERVED_KEYWORD +296 303 IDENT NO_KEYWORD +304 313 IMMUTABLE UNRESERVED_KEYWORD +== 048 +select case_test(1) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 049 +select case_test(2) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_41 NO_KEYWORD +== 050 +select case_test(12) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 19 ICONST NO_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 051 +select case_test(13) +-- +0 6 SELECT RESERVED_KEYWORD +7 16 IDENT NO_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 19 ICONST NO_KEYWORD +19 20 ASCII_41 NO_KEYWORD +== 052 +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +0 42 SQL_COMMENT NO_KEYWORD +43 49 CREATE RESERVED_KEYWORD +50 52 OR RESERVED_KEYWORD +53 60 REPLACE UNRESERVED_KEYWORD +61 69 FUNCTION UNRESERVED_KEYWORD +70 82 IDENT NO_KEYWORD +82 83 ASCII_40 NO_KEYWORD +83 86 INT_P COL_NAME_KEYWORD +86 87 ASCII_41 NO_KEYWORD +88 95 RETURNS UNRESERVED_KEYWORD +96 100 TEXT_P UNRESERVED_KEYWORD +101 103 AS RESERVED_KEYWORD +104 232 SCONST NO_KEYWORD +233 241 LANGUAGE UNRESERVED_KEYWORD +242 249 IDENT NO_KEYWORD +250 259 IMMUTABLE UNRESERVED_KEYWORD +== 053 +select case_comment(1) +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ICONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_copy.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_copy.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_copy.test b/parser/testdata/scan/plpgsql_regress/plpgsql_copy.test new file mode 100644 index 0000000..2788c56 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_copy.test @@ -0,0 +1,21 @@ +== 001 +-- directory paths are passed to us in environment variables + +-- set up file names to use + +CREATE TABLE copy1 (a int, b float); + +-- COPY TO/FROM not authorized from client. +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 TO stdout; +END; +$$; +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 FROM stdin; +-- +ERROR: "unterminated dollar-quoted string at or near \"$$\nBEGIN\n COPY copy1 FROM stdin;\"" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_domain.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_domain.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_domain.test b/parser/testdata/scan/plpgsql_regress/plpgsql_domain.test new file mode 100644 index 0000000..9dc2e72 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_domain.test @@ -0,0 +1,1389 @@ +== 001 +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 53 SQL_COMMENT NO_KEYWORD +54 56 SQL_COMMENT NO_KEYWORD +58 64 CREATE RESERVED_KEYWORD +65 71 DOMAIN_P UNRESERVED_KEYWORD +72 80 IDENT NO_KEYWORD +81 83 AS RESERVED_KEYWORD +84 88 IDENT NO_KEYWORD +89 94 CHECK RESERVED_KEYWORD +95 96 ASCII_40 NO_KEYWORD +96 101 VALUE_P UNRESERVED_KEYWORD +102 104 IS TYPE_FUNC_NAME_KEYWORD +105 109 TRUE_P RESERVED_KEYWORD +110 112 OR RESERVED_KEYWORD +113 118 VALUE_P UNRESERVED_KEYWORD +119 121 IS TYPE_FUNC_NAME_KEYWORD +122 126 NULL_P RESERVED_KEYWORD +126 127 ASCII_41 NO_KEYWORD +== 002 +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 39 IDENT NO_KEYWORD +39 40 ASCII_40 NO_KEYWORD +40 41 IDENT NO_KEYWORD +42 50 IDENT NO_KEYWORD +50 51 ASCII_44 NO_KEYWORD +52 53 IDENT NO_KEYWORD +54 58 IDENT NO_KEYWORD +58 59 ASCII_41 NO_KEYWORD +60 67 RETURNS UNRESERVED_KEYWORD +68 76 IDENT NO_KEYWORD +77 79 AS RESERVED_KEYWORD +80 105 SCONST NO_KEYWORD +106 114 LANGUAGE UNRESERVED_KEYWORD +115 122 IDENT NO_KEYWORD +== 003 +SELECT * FROM test_argresult_booltrue(true, true) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 37 IDENT NO_KEYWORD +37 38 ASCII_40 NO_KEYWORD +38 42 TRUE_P RESERVED_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 48 TRUE_P RESERVED_KEYWORD +48 49 ASCII_41 NO_KEYWORD +== 004 +SELECT * FROM test_argresult_booltrue(false, true) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 37 IDENT NO_KEYWORD +37 38 ASCII_40 NO_KEYWORD +38 43 FALSE_P RESERVED_KEYWORD +43 44 ASCII_44 NO_KEYWORD +45 49 TRUE_P RESERVED_KEYWORD +49 50 ASCII_41 NO_KEYWORD +== 005 +SELECT * FROM test_argresult_booltrue(true, false) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 37 IDENT NO_KEYWORD +37 38 ASCII_40 NO_KEYWORD +38 42 TRUE_P RESERVED_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 49 FALSE_P RESERVED_KEYWORD +49 50 ASCII_41 NO_KEYWORD +== 006 +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 43 IDENT NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +45 46 IDENT NO_KEYWORD +47 51 IDENT NO_KEYWORD +51 52 ASCII_41 NO_KEYWORD +53 60 RETURNS UNRESERVED_KEYWORD +61 69 IDENT NO_KEYWORD +70 72 AS RESERVED_KEYWORD +73 131 SCONST NO_KEYWORD +132 140 LANGUAGE UNRESERVED_KEYWORD +141 148 IDENT NO_KEYWORD +== 007 +SELECT * FROM test_assign_booltrue(true, true) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 39 TRUE_P RESERVED_KEYWORD +39 40 ASCII_44 NO_KEYWORD +41 45 TRUE_P RESERVED_KEYWORD +45 46 ASCII_41 NO_KEYWORD +== 008 +SELECT * FROM test_assign_booltrue(false, true) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 40 FALSE_P RESERVED_KEYWORD +40 41 ASCII_44 NO_KEYWORD +42 46 TRUE_P RESERVED_KEYWORD +46 47 ASCII_41 NO_KEYWORD +== 009 +SELECT * FROM test_assign_booltrue(true, false) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 39 TRUE_P RESERVED_KEYWORD +39 40 ASCII_44 NO_KEYWORD +41 46 FALSE_P RESERVED_KEYWORD +46 47 ASCII_41 NO_KEYWORD +== 010 +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +-- +0 6 CREATE RESERVED_KEYWORD +7 13 DOMAIN_P UNRESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +20 22 AS RESERVED_KEYWORD +23 27 IDENT NO_KEYWORD +28 33 CHECK RESERVED_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 40 VALUE_P UNRESERVED_KEYWORD +41 43 GREATER_EQUALS NO_KEYWORD +44 45 ICONST NO_KEYWORD +45 46 ASCII_41 NO_KEYWORD +== 011 +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 44 IDENT NO_KEYWORD +44 45 ASCII_44 NO_KEYWORD +46 47 IDENT NO_KEYWORD +48 51 INT_P COL_NAME_KEYWORD +51 52 ASCII_41 NO_KEYWORD +53 60 RETURNS UNRESERVED_KEYWORD +61 66 IDENT NO_KEYWORD +67 69 AS RESERVED_KEYWORD +70 95 SCONST NO_KEYWORD +96 104 LANGUAGE UNRESERVED_KEYWORD +105 112 IDENT NO_KEYWORD +== 012 +SELECT * FROM test_argresult_uint2(100::uint2, 50) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 38 ICONST NO_KEYWORD +38 40 TYPECAST NO_KEYWORD +40 45 IDENT NO_KEYWORD +45 46 ASCII_44 NO_KEYWORD +47 49 ICONST NO_KEYWORD +49 50 ASCII_41 NO_KEYWORD +== 013 +SELECT * FROM test_argresult_uint2(100::uint2, -50) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 38 ICONST NO_KEYWORD +38 40 TYPECAST NO_KEYWORD +40 45 IDENT NO_KEYWORD +45 46 ASCII_44 NO_KEYWORD +47 48 ASCII_45 NO_KEYWORD +48 50 ICONST NO_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 014 +SELECT * FROM test_argresult_uint2(null, 1) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 39 NULL_P RESERVED_KEYWORD +39 40 ASCII_44 NO_KEYWORD +41 42 ICONST NO_KEYWORD +42 43 ASCII_41 NO_KEYWORD +== 015 +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 33 IDENT NO_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 35 IDENT NO_KEYWORD +36 39 INT_P COL_NAME_KEYWORD +39 40 ASCII_44 NO_KEYWORD +41 42 IDENT NO_KEYWORD +43 46 INT_P COL_NAME_KEYWORD +46 47 ASCII_41 NO_KEYWORD +48 55 RETURNS UNRESERVED_KEYWORD +56 61 IDENT NO_KEYWORD +62 64 AS RESERVED_KEYWORD +65 120 SCONST NO_KEYWORD +121 129 LANGUAGE UNRESERVED_KEYWORD +130 137 IDENT NO_KEYWORD +== 016 +SELECT * FROM test_assign_uint2(100, 50) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 35 ICONST NO_KEYWORD +35 36 ASCII_44 NO_KEYWORD +37 39 ICONST NO_KEYWORD +39 40 ASCII_41 NO_KEYWORD +== 017 +SELECT * FROM test_assign_uint2(100, -50) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 35 ICONST NO_KEYWORD +35 36 ASCII_44 NO_KEYWORD +37 38 ASCII_45 NO_KEYWORD +38 40 ICONST NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +== 018 +SELECT * FROM test_assign_uint2(-100, 50) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 33 ASCII_45 NO_KEYWORD +33 36 ICONST NO_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 40 ICONST NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +== 019 +SELECT * FROM test_assign_uint2(null, 1) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 36 NULL_P RESERVED_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 39 ICONST NO_KEYWORD +39 40 ASCII_41 NO_KEYWORD +== 020 +CREATE DOMAIN nnint AS int NOT NULL +-- +0 6 CREATE RESERVED_KEYWORD +7 13 DOMAIN_P UNRESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +20 22 AS RESERVED_KEYWORD +23 26 INT_P COL_NAME_KEYWORD +27 30 NOT RESERVED_KEYWORD +31 35 NULL_P RESERVED_KEYWORD +== 021 +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 44 IDENT NO_KEYWORD +44 45 ASCII_44 NO_KEYWORD +46 47 IDENT NO_KEYWORD +48 51 INT_P COL_NAME_KEYWORD +51 52 ASCII_41 NO_KEYWORD +53 60 RETURNS UNRESERVED_KEYWORD +61 66 IDENT NO_KEYWORD +67 69 AS RESERVED_KEYWORD +70 95 SCONST NO_KEYWORD +96 104 LANGUAGE UNRESERVED_KEYWORD +105 112 IDENT NO_KEYWORD +== 022 +SELECT * FROM test_argresult_nnint(10, 20) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 37 ICONST NO_KEYWORD +37 38 ASCII_44 NO_KEYWORD +39 41 ICONST NO_KEYWORD +41 42 ASCII_41 NO_KEYWORD +== 023 +SELECT * FROM test_argresult_nnint(null, 20) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 39 NULL_P RESERVED_KEYWORD +39 40 ASCII_44 NO_KEYWORD +41 43 ICONST NO_KEYWORD +43 44 ASCII_41 NO_KEYWORD +== 024 +SELECT * FROM test_argresult_nnint(10, null) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 37 ICONST NO_KEYWORD +37 38 ASCII_44 NO_KEYWORD +39 43 NULL_P RESERVED_KEYWORD +43 44 ASCII_41 NO_KEYWORD +== 025 +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 33 IDENT NO_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 35 IDENT NO_KEYWORD +36 39 INT_P COL_NAME_KEYWORD +39 40 ASCII_44 NO_KEYWORD +41 42 IDENT NO_KEYWORD +43 46 INT_P COL_NAME_KEYWORD +46 47 ASCII_41 NO_KEYWORD +48 55 RETURNS UNRESERVED_KEYWORD +56 61 IDENT NO_KEYWORD +62 64 AS RESERVED_KEYWORD +65 120 SCONST NO_KEYWORD +121 129 LANGUAGE UNRESERVED_KEYWORD +130 137 IDENT NO_KEYWORD +== 026 +SELECT * FROM test_assign_nnint(10, 20) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 34 ICONST NO_KEYWORD +34 35 ASCII_44 NO_KEYWORD +36 38 ICONST NO_KEYWORD +38 39 ASCII_41 NO_KEYWORD +== 027 +SELECT * FROM test_assign_nnint(null, 20) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 36 NULL_P RESERVED_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 40 ICONST NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +== 028 +SELECT * FROM test_assign_nnint(10, null) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 34 ICONST NO_KEYWORD +34 35 ASCII_44 NO_KEYWORD +36 40 NULL_P RESERVED_KEYWORD +40 41 ASCII_41 NO_KEYWORD +== 029 +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 25 SQL_COMMENT NO_KEYWORD +26 28 SQL_COMMENT NO_KEYWORD +30 36 CREATE RESERVED_KEYWORD +37 43 DOMAIN_P UNRESERVED_KEYWORD +44 63 IDENT NO_KEYWORD +64 66 AS RESERVED_KEYWORD +67 74 INTEGER COL_NAME_KEYWORD +74 75 ASCII_91 NO_KEYWORD +75 76 ASCII_93 NO_KEYWORD +77 82 CHECK RESERVED_KEYWORD +83 84 ASCII_40 NO_KEYWORD +84 96 IDENT NO_KEYWORD +96 97 ASCII_40 NO_KEYWORD +97 102 VALUE_P UNRESERVED_KEYWORD +102 103 ASCII_44 NO_KEYWORD +103 104 ICONST NO_KEYWORD +104 105 ASCII_41 NO_KEYWORD +105 106 ASCII_61 NO_KEYWORD +106 107 ICONST NO_KEYWORD +108 111 AND RESERVED_KEYWORD +112 117 VALUE_P UNRESERVED_KEYWORD +117 118 ASCII_91 NO_KEYWORD +118 119 ICONST NO_KEYWORD +119 120 ASCII_93 NO_KEYWORD +121 122 ASCII_60 NO_KEYWORD +123 128 VALUE_P UNRESERVED_KEYWORD +128 129 ASCII_91 NO_KEYWORD +129 130 ICONST NO_KEYWORD +130 131 ASCII_93 NO_KEYWORD +131 132 ASCII_41 NO_KEYWORD +== 030 +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 43 IDENT NO_KEYWORD +43 44 ASCII_40 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 65 IDENT NO_KEYWORD +65 66 ASCII_41 NO_KEYWORD +69 76 RETURNS UNRESERVED_KEYWORD +77 96 IDENT NO_KEYWORD +97 99 AS RESERVED_KEYWORD +100 125 SCONST NO_KEYWORD +126 134 LANGUAGE UNRESERVED_KEYWORD +135 142 IDENT NO_KEYWORD +== 031 +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 41 IDENT NO_KEYWORD +41 42 ASCII_40 NO_KEYWORD +42 47 ARRAY RESERVED_KEYWORD +47 48 ASCII_91 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +51 54 ICONST NO_KEYWORD +54 55 ASCII_93 NO_KEYWORD +55 57 TYPECAST NO_KEYWORD +57 76 IDENT NO_KEYWORD +76 77 ASCII_41 NO_KEYWORD +== 032 +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 41 IDENT NO_KEYWORD +41 42 ASCII_40 NO_KEYWORD +42 46 NULL_P RESERVED_KEYWORD +46 48 TYPECAST NO_KEYWORD +48 67 IDENT NO_KEYWORD +67 68 ASCII_41 NO_KEYWORD +== 033 +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 59 IDENT NO_KEYWORD +59 60 ASCII_40 NO_KEYWORD +60 61 ASCII_41 NO_KEYWORD +64 71 RETURNS UNRESERVED_KEYWORD +72 91 IDENT NO_KEYWORD +92 94 AS RESERVED_KEYWORD +95 129 SCONST NO_KEYWORD +130 138 LANGUAGE UNRESERVED_KEYWORD +139 146 IDENT NO_KEYWORD +== 034 +SELECT * FROM test_argresult_array_domain_check_violation() +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 57 IDENT NO_KEYWORD +57 58 ASCII_40 NO_KEYWORD +58 59 ASCII_41 NO_KEYWORD +== 035 +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 47 IDENT NO_KEYWORD +47 48 ASCII_40 NO_KEYWORD +48 49 IDENT NO_KEYWORD +50 53 INT_P COL_NAME_KEYWORD +53 54 ASCII_44 NO_KEYWORD +55 56 IDENT NO_KEYWORD +57 60 INT_P COL_NAME_KEYWORD +60 61 ASCII_44 NO_KEYWORD +62 63 IDENT NO_KEYWORD +64 67 INT_P COL_NAME_KEYWORD +67 68 ASCII_41 NO_KEYWORD +69 76 RETURNS UNRESERVED_KEYWORD +77 96 IDENT NO_KEYWORD +97 99 AS RESERVED_KEYWORD +100 182 SCONST NO_KEYWORD +183 191 LANGUAGE UNRESERVED_KEYWORD +192 199 IDENT NO_KEYWORD +== 036 +SELECT * FROM test_assign_ordered_pair_domain(1,2,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 45 IDENT NO_KEYWORD +45 46 ASCII_40 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_44 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 51 ICONST NO_KEYWORD +51 52 ASCII_41 NO_KEYWORD +== 037 +SELECT * FROM test_assign_ordered_pair_domain(1,2,0) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 45 IDENT NO_KEYWORD +45 46 ASCII_40 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_44 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 51 ICONST NO_KEYWORD +51 52 ASCII_41 NO_KEYWORD +== 038 +SELECT * FROM test_assign_ordered_pair_domain(2,1,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 45 IDENT NO_KEYWORD +45 46 ASCII_40 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_44 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 51 ICONST NO_KEYWORD +51 52 ASCII_41 NO_KEYWORD +== 039 +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +0 2 SQL_COMMENT NO_KEYWORD +3 23 SQL_COMMENT NO_KEYWORD +24 26 SQL_COMMENT NO_KEYWORD +28 34 CREATE RESERVED_KEYWORD +35 43 FUNCTION UNRESERVED_KEYWORD +44 65 IDENT NO_KEYWORD +65 66 ASCII_40 NO_KEYWORD +66 67 IDENT NO_KEYWORD +68 73 IDENT NO_KEYWORD +73 74 ASCII_91 NO_KEYWORD +74 75 ASCII_93 NO_KEYWORD +75 76 ASCII_41 NO_KEYWORD +77 84 RETURNS UNRESERVED_KEYWORD +85 90 IDENT NO_KEYWORD +91 93 AS RESERVED_KEYWORD +94 122 SCONST NO_KEYWORD +123 131 LANGUAGE UNRESERVED_KEYWORD +132 139 IDENT NO_KEYWORD +== 040 +select test_read_uint2_array(array[1::uint2]) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 34 ARRAY RESERVED_KEYWORD +34 35 ASCII_91 NO_KEYWORD +35 36 ICONST NO_KEYWORD +36 38 TYPECAST NO_KEYWORD +38 43 IDENT NO_KEYWORD +43 44 ASCII_93 NO_KEYWORD +44 45 ASCII_41 NO_KEYWORD +== 041 +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 38 IDENT NO_KEYWORD +38 39 ASCII_40 NO_KEYWORD +39 40 IDENT NO_KEYWORD +41 45 IDENT NO_KEYWORD +45 46 ASCII_41 NO_KEYWORD +47 54 RETURNS UNRESERVED_KEYWORD +55 60 IDENT NO_KEYWORD +60 61 ASCII_91 NO_KEYWORD +61 62 ASCII_93 NO_KEYWORD +63 65 AS RESERVED_KEYWORD +66 101 SCONST NO_KEYWORD +102 110 LANGUAGE UNRESERVED_KEYWORD +111 118 IDENT NO_KEYWORD +== 042 +select test_build_uint2_array(1::int2) +-- +0 6 SELECT RESERVED_KEYWORD +7 29 IDENT NO_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 31 ICONST NO_KEYWORD +31 33 TYPECAST NO_KEYWORD +33 37 IDENT NO_KEYWORD +37 38 ASCII_41 NO_KEYWORD +== 043 +select test_build_uint2_array(-1::int2) +-- +0 6 SELECT RESERVED_KEYWORD +7 29 IDENT NO_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 31 ASCII_45 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 34 TYPECAST NO_KEYWORD +34 38 IDENT NO_KEYWORD +38 39 ASCII_41 NO_KEYWORD +== 044 +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 52 IDENT NO_KEYWORD +52 53 ASCII_40 NO_KEYWORD +53 54 IDENT NO_KEYWORD +55 62 INTEGER COL_NAME_KEYWORD +62 63 ASCII_91 NO_KEYWORD +63 64 ASCII_93 NO_KEYWORD +64 65 ASCII_41 NO_KEYWORD +68 75 RETURNS UNRESERVED_KEYWORD +76 95 IDENT NO_KEYWORD +95 96 ASCII_91 NO_KEYWORD +96 97 ASCII_93 NO_KEYWORD +98 100 AS RESERVED_KEYWORD +101 178 SCONST NO_KEYWORD +179 187 LANGUAGE UNRESERVED_KEYWORD +188 195 IDENT NO_KEYWORD +== 045 +select test_argresult_domain_array(array[2,4]) +-- +0 6 SELECT RESERVED_KEYWORD +7 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 40 ARRAY RESERVED_KEYWORD +40 41 ASCII_91 NO_KEYWORD +41 42 ICONST NO_KEYWORD +42 43 ASCII_44 NO_KEYWORD +43 44 ICONST NO_KEYWORD +44 45 ASCII_93 NO_KEYWORD +45 46 ASCII_41 NO_KEYWORD +== 046 +select test_argresult_domain_array(array[4,2]) +-- +0 6 SELECT RESERVED_KEYWORD +7 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 40 ARRAY RESERVED_KEYWORD +40 41 ASCII_91 NO_KEYWORD +41 42 ICONST NO_KEYWORD +42 43 ASCII_44 NO_KEYWORD +43 44 ICONST NO_KEYWORD +44 45 ASCII_93 NO_KEYWORD +45 46 ASCII_41 NO_KEYWORD +== 047 +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 53 IDENT NO_KEYWORD +53 54 ASCII_40 NO_KEYWORD +54 55 IDENT NO_KEYWORD +56 75 IDENT NO_KEYWORD +75 76 ASCII_41 NO_KEYWORD +79 86 RETURNS UNRESERVED_KEYWORD +87 94 INTEGER COL_NAME_KEYWORD +95 97 AS RESERVED_KEYWORD +98 126 SCONST NO_KEYWORD +127 135 LANGUAGE UNRESERVED_KEYWORD +136 143 IDENT NO_KEYWORD +== 048 +select test_argresult_domain_array2(array[2,4]) +-- +0 6 SELECT RESERVED_KEYWORD +7 35 IDENT NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 41 ARRAY RESERVED_KEYWORD +41 42 ASCII_91 NO_KEYWORD +42 43 ICONST NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +44 45 ICONST NO_KEYWORD +45 46 ASCII_93 NO_KEYWORD +46 47 ASCII_41 NO_KEYWORD +== 049 +select test_argresult_domain_array2(array[4,2]) +-- +0 6 SELECT RESERVED_KEYWORD +7 35 IDENT NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 41 ARRAY RESERVED_KEYWORD +41 42 ASCII_91 NO_KEYWORD +42 43 ICONST NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +44 45 ICONST NO_KEYWORD +45 46 ASCII_93 NO_KEYWORD +46 47 ASCII_41 NO_KEYWORD +== 050 +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 58 IDENT NO_KEYWORD +58 59 ASCII_40 NO_KEYWORD +59 60 IDENT NO_KEYWORD +61 80 IDENT NO_KEYWORD +80 81 ASCII_91 NO_KEYWORD +81 82 ASCII_93 NO_KEYWORD +82 83 ASCII_41 NO_KEYWORD +86 93 RETURNS UNRESERVED_KEYWORD +94 113 IDENT NO_KEYWORD +114 116 AS RESERVED_KEYWORD +117 145 SCONST NO_KEYWORD +146 154 LANGUAGE UNRESERVED_KEYWORD +155 162 IDENT NO_KEYWORD +== 051 +select test_argresult_array_domain_array(array[array[2,4]::ordered_pair_domain]) +-- +0 6 SELECT RESERVED_KEYWORD +7 40 IDENT NO_KEYWORD +40 41 ASCII_40 NO_KEYWORD +41 46 ARRAY RESERVED_KEYWORD +46 47 ASCII_91 NO_KEYWORD +47 52 ARRAY RESERVED_KEYWORD +52 53 ASCII_91 NO_KEYWORD +53 54 ICONST NO_KEYWORD +54 55 ASCII_44 NO_KEYWORD +55 56 ICONST NO_KEYWORD +56 57 ASCII_93 NO_KEYWORD +57 59 TYPECAST NO_KEYWORD +59 78 IDENT NO_KEYWORD +78 79 ASCII_93 NO_KEYWORD +79 80 ASCII_41 NO_KEYWORD +== 052 +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 30 SQL_COMMENT NO_KEYWORD +31 33 SQL_COMMENT NO_KEYWORD +35 41 CREATE RESERVED_KEYWORD +42 46 TYPE_P UNRESERVED_KEYWORD +47 62 IDENT NO_KEYWORD +63 65 AS RESERVED_KEYWORD +66 67 ASCII_40 NO_KEYWORD +67 69 IDENT NO_KEYWORD +70 73 INT_P COL_NAME_KEYWORD +73 74 ASCII_44 NO_KEYWORD +75 77 IDENT NO_KEYWORD +78 83 IDENT NO_KEYWORD +83 84 ASCII_41 NO_KEYWORD +== 053 +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 43 IDENT NO_KEYWORD +43 44 ASCII_40 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_44 NO_KEYWORD +51 52 IDENT NO_KEYWORD +53 56 INT_P COL_NAME_KEYWORD +56 57 ASCII_41 NO_KEYWORD +60 67 RETURNS UNRESERVED_KEYWORD +68 83 IDENT NO_KEYWORD +84 86 AS RESERVED_KEYWORD +87 137 SCONST NO_KEYWORD +138 146 LANGUAGE UNRESERVED_KEYWORD +147 154 IDENT NO_KEYWORD +== 054 +SELECT test_result_nnint_container(null, 3) +-- +0 6 SELECT RESERVED_KEYWORD +7 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 39 NULL_P RESERVED_KEYWORD +39 40 ASCII_44 NO_KEYWORD +41 42 ICONST NO_KEYWORD +42 43 ASCII_41 NO_KEYWORD +== 055 +SELECT test_result_nnint_container(3, null) +-- +0 6 SELECT RESERVED_KEYWORD +7 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 ICONST NO_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 42 NULL_P RESERVED_KEYWORD +42 43 ASCII_41 NO_KEYWORD +== 056 +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 52 IDENT NO_KEYWORD +52 53 ASCII_40 NO_KEYWORD +53 54 IDENT NO_KEYWORD +55 58 INT_P COL_NAME_KEYWORD +58 59 ASCII_44 NO_KEYWORD +60 61 IDENT NO_KEYWORD +62 65 INT_P COL_NAME_KEYWORD +65 66 ASCII_44 NO_KEYWORD +67 68 IDENT NO_KEYWORD +69 72 INT_P COL_NAME_KEYWORD +72 73 ASCII_41 NO_KEYWORD +76 83 RETURNS UNRESERVED_KEYWORD +84 99 IDENT NO_KEYWORD +100 102 AS RESERVED_KEYWORD +103 179 SCONST NO_KEYWORD +180 188 LANGUAGE UNRESERVED_KEYWORD +189 196 IDENT NO_KEYWORD +== 057 +SELECT * FROM test_assign_nnint_container(1,2,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 41 IDENT NO_KEYWORD +41 42 ASCII_40 NO_KEYWORD +42 43 ICONST NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +44 45 ICONST NO_KEYWORD +45 46 ASCII_44 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_41 NO_KEYWORD +== 058 +SELECT * FROM test_assign_nnint_container(1,2,null) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 41 IDENT NO_KEYWORD +41 42 ASCII_40 NO_KEYWORD +42 43 ICONST NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +44 45 ICONST NO_KEYWORD +45 46 ASCII_44 NO_KEYWORD +46 50 NULL_P RESERVED_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 059 +SELECT * FROM test_assign_nnint_container(1,null,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 41 IDENT NO_KEYWORD +41 42 ASCII_40 NO_KEYWORD +42 43 ICONST NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +44 48 NULL_P RESERVED_KEYWORD +48 49 ASCII_44 NO_KEYWORD +49 50 ICONST NO_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 060 +-- Since core system allows this: +SELECT null::nnint_container +-- +0 33 SQL_COMMENT NO_KEYWORD +34 40 SELECT RESERVED_KEYWORD +41 45 NULL_P RESERVED_KEYWORD +45 47 TYPECAST NO_KEYWORD +47 62 IDENT NO_KEYWORD +== 061 +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +0 21 SQL_COMMENT NO_KEYWORD +23 29 CREATE RESERVED_KEYWORD +30 38 FUNCTION UNRESERVED_KEYWORD +39 67 IDENT NO_KEYWORD +67 68 ASCII_40 NO_KEYWORD +68 69 IDENT NO_KEYWORD +70 73 INT_P COL_NAME_KEYWORD +73 74 ASCII_44 NO_KEYWORD +75 76 IDENT NO_KEYWORD +77 80 INT_P COL_NAME_KEYWORD +80 81 ASCII_44 NO_KEYWORD +82 83 IDENT NO_KEYWORD +84 87 INT_P COL_NAME_KEYWORD +87 88 ASCII_41 NO_KEYWORD +91 98 RETURNS UNRESERVED_KEYWORD +99 114 IDENT NO_KEYWORD +115 117 AS RESERVED_KEYWORD +118 181 SCONST NO_KEYWORD +182 190 LANGUAGE UNRESERVED_KEYWORD +191 198 IDENT NO_KEYWORD +== 062 +SELECT * FROM test_assign_nnint_container2(1,2,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 42 IDENT NO_KEYWORD +42 43 ASCII_40 NO_KEYWORD +43 44 ICONST NO_KEYWORD +44 45 ASCII_44 NO_KEYWORD +45 46 ICONST NO_KEYWORD +46 47 ASCII_44 NO_KEYWORD +47 48 ICONST NO_KEYWORD +48 49 ASCII_41 NO_KEYWORD +== 063 +SELECT * FROM test_assign_nnint_container2(1,2,null) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 42 IDENT NO_KEYWORD +42 43 ASCII_40 NO_KEYWORD +43 44 ICONST NO_KEYWORD +44 45 ASCII_44 NO_KEYWORD +45 46 ICONST NO_KEYWORD +46 47 ASCII_44 NO_KEYWORD +47 51 NULL_P RESERVED_KEYWORD +51 52 ASCII_41 NO_KEYWORD +== 064 +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 26 SQL_COMMENT NO_KEYWORD +27 29 SQL_COMMENT NO_KEYWORD +31 37 CREATE RESERVED_KEYWORD +38 42 TYPE_P UNRESERVED_KEYWORD +43 53 IDENT NO_KEYWORD +54 56 AS RESERVED_KEYWORD +57 58 ASCII_40 NO_KEYWORD +63 64 IDENT NO_KEYWORD +65 72 INTEGER COL_NAME_KEYWORD +72 73 ASCII_44 NO_KEYWORD +78 79 IDENT NO_KEYWORD +80 87 INTEGER COL_NAME_KEYWORD +88 89 ASCII_41 NO_KEYWORD +== 065 +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +-- +0 6 CREATE RESERVED_KEYWORD +7 13 DOMAIN_P UNRESERVED_KEYWORD +14 32 IDENT NO_KEYWORD +33 35 AS RESERVED_KEYWORD +36 46 IDENT NO_KEYWORD +47 52 CHECK RESERVED_KEYWORD +52 53 ASCII_40 NO_KEYWORD +53 54 ASCII_40 NO_KEYWORD +54 59 VALUE_P UNRESERVED_KEYWORD +59 60 ASCII_41 NO_KEYWORD +60 61 ASCII_46 NO_KEYWORD +61 62 IDENT NO_KEYWORD +63 65 LESS_EQUALS NO_KEYWORD +66 67 ASCII_40 NO_KEYWORD +67 72 VALUE_P UNRESERVED_KEYWORD +72 73 ASCII_41 NO_KEYWORD +73 74 ASCII_46 NO_KEYWORD +74 75 IDENT NO_KEYWORD +75 76 ASCII_41 NO_KEYWORD +== 066 +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 39 IDENT NO_KEYWORD +39 40 ASCII_40 NO_KEYWORD +40 41 IDENT NO_KEYWORD +42 60 IDENT NO_KEYWORD +60 61 ASCII_41 NO_KEYWORD +62 69 RETURNS UNRESERVED_KEYWORD +70 77 INTEGER COL_NAME_KEYWORD +78 80 AS RESERVED_KEYWORD +81 114 SCONST NO_KEYWORD +115 123 LANGUAGE UNRESERVED_KEYWORD +124 131 IDENT NO_KEYWORD +== 067 +SELECT read_ordered_named_pair(row(1, 2)) +-- +0 6 SELECT RESERVED_KEYWORD +7 30 IDENT NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 34 ROW COL_NAME_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 ICONST NO_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 39 ICONST NO_KEYWORD +39 40 ASCII_41 NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +== 068 +SELECT read_ordered_named_pair(row(2, 1)) +-- +0 6 SELECT RESERVED_KEYWORD +7 30 IDENT NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 34 ROW COL_NAME_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 ICONST NO_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 39 ICONST NO_KEYWORD +39 40 ASCII_41 NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +== 069 +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 49 IDENT NO_KEYWORD +49 50 ASCII_40 NO_KEYWORD +50 51 IDENT NO_KEYWORD +52 55 INT_P COL_NAME_KEYWORD +55 56 ASCII_44 NO_KEYWORD +57 58 IDENT NO_KEYWORD +59 62 INT_P COL_NAME_KEYWORD +62 63 ASCII_41 NO_KEYWORD +64 71 RETURNS UNRESERVED_KEYWORD +72 90 IDENT NO_KEYWORD +91 93 AS RESERVED_KEYWORD +94 127 SCONST NO_KEYWORD +128 136 LANGUAGE UNRESERVED_KEYWORD +137 144 IDENT NO_KEYWORD +== 070 +SELECT build_ordered_named_pair(1,2) +-- +0 6 SELECT RESERVED_KEYWORD +7 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 33 ICONST NO_KEYWORD +33 34 ASCII_44 NO_KEYWORD +34 35 ICONST NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +== 071 +SELECT build_ordered_named_pair(2,1) +-- +0 6 SELECT RESERVED_KEYWORD +7 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 33 ICONST NO_KEYWORD +33 34 ASCII_44 NO_KEYWORD +34 35 ICONST NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +== 072 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 55 IDENT NO_KEYWORD +55 56 ASCII_40 NO_KEYWORD +56 57 IDENT NO_KEYWORD +58 61 INT_P COL_NAME_KEYWORD +61 62 ASCII_44 NO_KEYWORD +63 64 IDENT NO_KEYWORD +65 68 INT_P COL_NAME_KEYWORD +68 69 ASCII_44 NO_KEYWORD +70 71 IDENT NO_KEYWORD +72 75 INT_P COL_NAME_KEYWORD +75 76 ASCII_41 NO_KEYWORD +79 86 RETURNS UNRESERVED_KEYWORD +87 105 IDENT NO_KEYWORD +106 108 AS RESERVED_KEYWORD +109 187 SCONST NO_KEYWORD +188 196 LANGUAGE UNRESERVED_KEYWORD +197 204 IDENT NO_KEYWORD +== 073 +SELECT * FROM test_assign_ordered_named_pair(1,2,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 ICONST NO_KEYWORD +46 47 ASCII_44 NO_KEYWORD +47 48 ICONST NO_KEYWORD +48 49 ASCII_44 NO_KEYWORD +49 50 ICONST NO_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 074 +SELECT * FROM test_assign_ordered_named_pair(1,2,0) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 ICONST NO_KEYWORD +46 47 ASCII_44 NO_KEYWORD +47 48 ICONST NO_KEYWORD +48 49 ASCII_44 NO_KEYWORD +49 50 ICONST NO_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 075 +SELECT * FROM test_assign_ordered_named_pair(2,1,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 ICONST NO_KEYWORD +46 47 ASCII_44 NO_KEYWORD +47 48 ICONST NO_KEYWORD +48 49 ASCII_44 NO_KEYWORD +49 50 ICONST NO_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 076 +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 41 IDENT NO_KEYWORD +41 42 ASCII_40 NO_KEYWORD +42 43 IDENT NO_KEYWORD +44 47 INT_P COL_NAME_KEYWORD +47 48 ASCII_44 NO_KEYWORD +49 50 IDENT NO_KEYWORD +51 54 INT_P COL_NAME_KEYWORD +54 55 ASCII_41 NO_KEYWORD +56 63 RETURNS UNRESERVED_KEYWORD +64 82 IDENT NO_KEYWORD +82 83 ASCII_91 NO_KEYWORD +83 84 ASCII_93 NO_KEYWORD +85 87 AS RESERVED_KEYWORD +88 141 SCONST NO_KEYWORD +142 150 LANGUAGE UNRESERVED_KEYWORD +151 158 IDENT NO_KEYWORD +== 077 +SELECT build_ordered_named_pairs(1,2) +-- +0 6 SELECT RESERVED_KEYWORD +7 32 IDENT NO_KEYWORD +32 33 ASCII_40 NO_KEYWORD +33 34 ICONST NO_KEYWORD +34 35 ASCII_44 NO_KEYWORD +35 36 ICONST NO_KEYWORD +36 37 ASCII_41 NO_KEYWORD +== 078 +SELECT build_ordered_named_pairs(2,1) +-- +0 6 SELECT RESERVED_KEYWORD +7 32 IDENT NO_KEYWORD +32 33 ASCII_40 NO_KEYWORD +33 34 ICONST NO_KEYWORD +34 35 ASCII_44 NO_KEYWORD +35 36 ICONST NO_KEYWORD +36 37 ASCII_41 NO_KEYWORD +== 079 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 56 IDENT NO_KEYWORD +56 57 ASCII_40 NO_KEYWORD +57 58 IDENT NO_KEYWORD +59 62 INT_P COL_NAME_KEYWORD +62 63 ASCII_44 NO_KEYWORD +64 65 IDENT NO_KEYWORD +66 69 INT_P COL_NAME_KEYWORD +69 70 ASCII_44 NO_KEYWORD +71 72 IDENT NO_KEYWORD +73 76 INT_P COL_NAME_KEYWORD +76 77 ASCII_41 NO_KEYWORD +80 87 RETURNS UNRESERVED_KEYWORD +88 106 IDENT NO_KEYWORD +106 107 ASCII_91 NO_KEYWORD +107 108 ASCII_93 NO_KEYWORD +109 111 AS RESERVED_KEYWORD +112 253 SCONST NO_KEYWORD +254 262 LANGUAGE UNRESERVED_KEYWORD +263 270 IDENT NO_KEYWORD +== 080 +SELECT * FROM test_assign_ordered_named_pairs(1,2,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 45 IDENT NO_KEYWORD +45 46 ASCII_40 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_44 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 51 ICONST NO_KEYWORD +51 52 ASCII_41 NO_KEYWORD +== 081 +SELECT * FROM test_assign_ordered_named_pairs(2,1,3) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 45 IDENT NO_KEYWORD +45 46 ASCII_40 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_44 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 51 ICONST NO_KEYWORD +51 52 ASCII_41 NO_KEYWORD +== 082 +SELECT * FROM test_assign_ordered_named_pairs(1,2,0) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 45 IDENT NO_KEYWORD +45 46 ASCII_40 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_44 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 51 ICONST NO_KEYWORD +51 52 ASCII_41 NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_misc.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_misc.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_misc.test b/parser/testdata/scan/plpgsql_regress/plpgsql_misc.test new file mode 100644 index 0000000..95622dd --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_misc.test @@ -0,0 +1,103 @@ +== 001 +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +-- +0 2 SQL_COMMENT NO_KEYWORD +3 26 SQL_COMMENT NO_KEYWORD +27 29 SQL_COMMENT NO_KEYWORD +31 94 SQL_COMMENT NO_KEYWORD +95 97 DO RESERVED_KEYWORD +98 365 SCONST NO_KEYWORD +== 002 +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +-- +0 38 SQL_COMMENT NO_KEYWORD +39 45 CREATE RESERVED_KEYWORD +46 51 TABLE RESERVED_KEYWORD +52 62 IDENT NO_KEYWORD +62 63 ASCII_40 NO_KEYWORD +63 65 IDENT NO_KEYWORD +66 69 INT_P COL_NAME_KEYWORD +69 70 ASCII_41 NO_KEYWORD +== 003 +do $$ declare x foo%type; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 38 SCONST NO_KEYWORD +== 004 +do $$ declare x notice%type; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 41 SCONST NO_KEYWORD +== 005 +-- covers unreserved-keyword case +do $$ declare x foo.bar%type; begin end $$ +-- +0 33 SQL_COMMENT NO_KEYWORD +34 36 DO RESERVED_KEYWORD +37 76 SCONST NO_KEYWORD +== 006 +do $$ declare x foo.bar.baz%type; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 46 SCONST NO_KEYWORD +== 007 +do $$ declare x public.foo.bar%type; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 49 SCONST NO_KEYWORD +== 008 +do $$ declare x public.misc_table.zed%type; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 56 SCONST NO_KEYWORD +== 009 +do $$ declare x foo%rowtype; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 41 SCONST NO_KEYWORD +== 010 +do $$ declare x notice%rowtype; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 44 SCONST NO_KEYWORD +== 011 +-- covers unreserved-keyword case +do $$ declare x foo.bar%rowtype; begin end $$ +-- +0 33 SQL_COMMENT NO_KEYWORD +34 36 DO RESERVED_KEYWORD +37 79 SCONST NO_KEYWORD +== 012 +do $$ declare x foo.bar.baz%rowtype; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 49 SCONST NO_KEYWORD +== 013 +do $$ declare x public.foo%rowtype; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 48 SCONST NO_KEYWORD +== 014 +do $$ declare x public.misc_table%rowtype; begin end $$ +-- +0 2 DO RESERVED_KEYWORD +3 55 SCONST NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_record.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_record.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_record.test b/parser/testdata/scan/plpgsql_regress/plpgsql_record.test new file mode 100644 index 0000000..76c5d2cc --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_record.test @@ -0,0 +1,2259 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 65 SQL_COMMENT NO_KEYWORD +66 68 SQL_COMMENT NO_KEYWORD +70 76 CREATE RESERVED_KEYWORD +77 81 TYPE_P UNRESERVED_KEYWORD +82 91 IDENT NO_KEYWORD +92 94 AS RESERVED_KEYWORD +95 96 ASCII_40 NO_KEYWORD +96 98 IDENT NO_KEYWORD +99 103 IDENT NO_KEYWORD +103 104 ASCII_44 NO_KEYWORD +105 107 IDENT NO_KEYWORD +108 112 IDENT NO_KEYWORD +112 113 ASCII_41 NO_KEYWORD +== 002 +create type more_int4s as (f0 text, f1 int4, f2 int4) +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TYPE_P UNRESERVED_KEYWORD +12 22 IDENT NO_KEYWORD +23 25 AS RESERVED_KEYWORD +26 27 ASCII_40 NO_KEYWORD +27 29 IDENT NO_KEYWORD +30 34 TEXT_P UNRESERVED_KEYWORD +34 35 ASCII_44 NO_KEYWORD +36 38 IDENT NO_KEYWORD +39 43 IDENT NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +45 47 IDENT NO_KEYWORD +48 52 IDENT NO_KEYWORD +52 53 ASCII_41 NO_KEYWORD +== 003 +create type two_int8s as (q1 int8, q2 int8) +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TYPE_P UNRESERVED_KEYWORD +12 21 IDENT NO_KEYWORD +22 24 AS RESERVED_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 28 IDENT NO_KEYWORD +29 33 IDENT NO_KEYWORD +33 34 ASCII_44 NO_KEYWORD +35 37 IDENT NO_KEYWORD +38 42 IDENT NO_KEYWORD +42 43 ASCII_41 NO_KEYWORD +== 004 +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TYPE_P UNRESERVED_KEYWORD +12 24 IDENT NO_KEYWORD +25 27 AS RESERVED_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 31 IDENT NO_KEYWORD +32 41 IDENT NO_KEYWORD +41 42 ASCII_44 NO_KEYWORD +43 45 IDENT NO_KEYWORD +46 55 IDENT NO_KEYWORD +55 56 ASCII_41 NO_KEYWORD +== 005 +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1)::two_int8s; end $$ +-- +0 39 SQL_COMMENT NO_KEYWORD +40 46 CREATE RESERVED_KEYWORD +47 55 FUNCTION UNRESERVED_KEYWORD +56 60 IDENT NO_KEYWORD +60 61 ASCII_40 NO_KEYWORD +61 64 INT_P COL_NAME_KEYWORD +64 65 ASCII_41 NO_KEYWORD +66 73 RETURNS UNRESERVED_KEYWORD +74 83 IDENT NO_KEYWORD +84 92 LANGUAGE UNRESERVED_KEYWORD +93 100 IDENT NO_KEYWORD +101 103 AS RESERVED_KEYWORD +104 148 SCONST NO_KEYWORD +== 006 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 007 +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8); end $$ +-- +0 38 SQL_COMMENT NO_KEYWORD +39 45 CREATE RESERVED_KEYWORD +46 48 OR RESERVED_KEYWORD +49 56 REPLACE UNRESERVED_KEYWORD +57 65 FUNCTION UNRESERVED_KEYWORD +66 70 IDENT NO_KEYWORD +70 71 ASCII_40 NO_KEYWORD +71 74 INT_P COL_NAME_KEYWORD +74 75 ASCII_41 NO_KEYWORD +76 83 RETURNS UNRESERVED_KEYWORD +84 93 IDENT NO_KEYWORD +94 102 LANGUAGE UNRESERVED_KEYWORD +103 110 IDENT NO_KEYWORD +111 113 AS RESERVED_KEYWORD +114 160 SCONST NO_KEYWORD +== 008 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 009 +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1); end $$ +-- +0 46 SQL_COMMENT NO_KEYWORD +47 53 CREATE RESERVED_KEYWORD +54 56 OR RESERVED_KEYWORD +57 64 REPLACE UNRESERVED_KEYWORD +65 73 FUNCTION UNRESERVED_KEYWORD +74 78 IDENT NO_KEYWORD +78 79 ASCII_40 NO_KEYWORD +79 82 INT_P COL_NAME_KEYWORD +82 83 ASCII_41 NO_KEYWORD +84 91 RETURNS UNRESERVED_KEYWORD +92 101 IDENT NO_KEYWORD +102 110 LANGUAGE UNRESERVED_KEYWORD +111 118 IDENT NO_KEYWORD +119 121 AS RESERVED_KEYWORD +122 155 SCONST NO_KEYWORD +== 010 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 011 +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8, 42); end $$ +-- +0 20 SQL_COMMENT NO_KEYWORD +21 27 CREATE RESERVED_KEYWORD +28 30 OR RESERVED_KEYWORD +31 38 REPLACE UNRESERVED_KEYWORD +39 47 FUNCTION UNRESERVED_KEYWORD +48 52 IDENT NO_KEYWORD +52 53 ASCII_40 NO_KEYWORD +53 56 INT_P COL_NAME_KEYWORD +56 57 ASCII_41 NO_KEYWORD +58 65 RETURNS UNRESERVED_KEYWORD +66 75 IDENT NO_KEYWORD +76 84 LANGUAGE UNRESERVED_KEYWORD +85 92 IDENT NO_KEYWORD +93 95 AS RESERVED_KEYWORD +96 146 SCONST NO_KEYWORD +== 012 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 013 +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +-- +0 52 SQL_COMMENT NO_KEYWORD +53 59 CREATE RESERVED_KEYWORD +60 62 OR RESERVED_KEYWORD +63 70 REPLACE UNRESERVED_KEYWORD +71 79 FUNCTION UNRESERVED_KEYWORD +80 84 IDENT NO_KEYWORD +84 85 ASCII_40 NO_KEYWORD +85 88 INT_P COL_NAME_KEYWORD +88 89 ASCII_41 NO_KEYWORD +90 97 RETURNS UNRESERVED_KEYWORD +98 107 IDENT NO_KEYWORD +108 116 LANGUAGE UNRESERVED_KEYWORD +117 124 IDENT NO_KEYWORD +125 127 AS RESERVED_KEYWORD +128 200 SCONST NO_KEYWORD +== 014 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 015 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,1); return r; end $$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 35 INT_P COL_NAME_KEYWORD +35 36 ASCII_41 NO_KEYWORD +37 44 RETURNS UNRESERVED_KEYWORD +45 54 IDENT NO_KEYWORD +55 63 LANGUAGE UNRESERVED_KEYWORD +64 71 IDENT NO_KEYWORD +72 74 AS RESERVED_KEYWORD +75 134 SCONST NO_KEYWORD +== 016 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 017 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 31 IDENT NO_KEYWORD +31 32 ASCII_40 NO_KEYWORD +32 35 INT_P COL_NAME_KEYWORD +35 36 ASCII_41 NO_KEYWORD +37 44 RETURNS UNRESERVED_KEYWORD +45 54 IDENT NO_KEYWORD +55 63 LANGUAGE UNRESERVED_KEYWORD +64 71 IDENT NO_KEYWORD +72 74 AS RESERVED_KEYWORD +75 151 SCONST NO_KEYWORD +== 018 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 019 +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +0 67 SQL_COMMENT NO_KEYWORD +68 105 SQL_COMMENT NO_KEYWORD +106 112 CREATE RESERVED_KEYWORD +113 115 OR RESERVED_KEYWORD +116 123 REPLACE UNRESERVED_KEYWORD +124 132 FUNCTION UNRESERVED_KEYWORD +133 137 IDENT NO_KEYWORD +137 138 ASCII_40 NO_KEYWORD +138 141 INT_P COL_NAME_KEYWORD +141 142 ASCII_41 NO_KEYWORD +143 150 RETURNS UNRESERVED_KEYWORD +151 160 IDENT NO_KEYWORD +161 169 LANGUAGE UNRESERVED_KEYWORD +170 177 IDENT NO_KEYWORD +178 180 AS RESERVED_KEYWORD +181 260 SCONST NO_KEYWORD +== 020 +select retc(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 11 IDENT NO_KEYWORD +11 12 ASCII_40 NO_KEYWORD +12 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 021 +do $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 78 SCONST NO_KEYWORD +== 022 +do $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +-- +0 2 DO RESERVED_KEYWORD +3 98 SCONST NO_KEYWORD +== 023 +do $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 153 SCONST NO_KEYWORD +== 024 +do $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 431 SCONST NO_KEYWORD +== 025 +-- block-qualified naming +do $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +-- +0 25 SQL_COMMENT NO_KEYWORD +26 28 DO RESERVED_KEYWORD +29 511 SCONST NO_KEYWORD +== 026 +-- error cases +do $$ declare c two_int8s; begin c.x = 1; end $$ +-- +0 14 SQL_COMMENT NO_KEYWORD +15 17 DO RESERVED_KEYWORD +18 63 SCONST NO_KEYWORD +== 027 +do $$ declare c nested_int8s; begin c.x = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 51 SCONST NO_KEYWORD +== 028 +do $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 54 SCONST NO_KEYWORD +== 029 +do $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 54 SCONST NO_KEYWORD +== 030 +do $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 54 SCONST NO_KEYWORD +== 031 +do $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 56 SCONST NO_KEYWORD +== 032 +do $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 59 SCONST NO_KEYWORD +== 033 +do $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 62 SCONST NO_KEYWORD +== 034 +do $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 62 SCONST NO_KEYWORD +== 035 +do $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +-- +0 2 DO RESERVED_KEYWORD +3 62 SCONST NO_KEYWORD +== 036 +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +-- +0 53 SQL_COMMENT NO_KEYWORD +54 60 CREATE RESERVED_KEYWORD +61 69 FUNCTION UNRESERVED_KEYWORD +70 75 IDENT NO_KEYWORD +75 76 ASCII_40 NO_KEYWORD +76 85 IDENT NO_KEYWORD +85 86 ASCII_41 NO_KEYWORD +87 94 RETURNS UNRESERVED_KEYWORD +95 99 IDENT NO_KEYWORD +100 108 LANGUAGE UNRESERVED_KEYWORD +109 116 IDENT NO_KEYWORD +117 119 AS RESERVED_KEYWORD +120 178 SCONST NO_KEYWORD +== 037 +select getq1(retc(344)) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 17 IDENT NO_KEYWORD +17 18 ASCII_40 NO_KEYWORD +18 21 ICONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +22 23 ASCII_41 NO_KEYWORD +== 038 +select getq1(row(1,2)) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 16 ROW COL_NAME_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_44 NO_KEYWORD +19 20 ICONST NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 039 +do $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 228 SCONST NO_KEYWORD +== 040 +-- check assignments of composites +do $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +-- +0 34 SQL_COMMENT NO_KEYWORD +35 37 DO RESERVED_KEYWORD +38 958 SCONST NO_KEYWORD +== 041 +-- fields of named-type vars read as null if uninitialized +do $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +-- +0 58 SQL_COMMENT NO_KEYWORD +59 61 DO RESERVED_KEYWORD +62 226 SCONST NO_KEYWORD +== 042 +do $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 191 SCONST NO_KEYWORD +== 043 +-- records, not so much +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +-- +0 23 SQL_COMMENT NO_KEYWORD +24 26 DO RESERVED_KEYWORD +27 188 SCONST NO_KEYWORD +== 044 +-- but OK if you assign first +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +0 29 SQL_COMMENT NO_KEYWORD +30 32 DO RESERVED_KEYWORD +33 265 SCONST NO_KEYWORD +== 045 +-- check %type with block-qualified variable names +do $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +-- +0 50 SQL_COMMENT NO_KEYWORD +51 53 DO RESERVED_KEYWORD +54 308 SCONST NO_KEYWORD +== 046 +-- check that type record can be passed through %type +do $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +-- +0 53 SQL_COMMENT NO_KEYWORD +54 56 DO RESERVED_KEYWORD +57 206 SCONST NO_KEYWORD +== 047 +-- arrays of record are not supported at the moment +do $$ +declare r1 record[]; +begin +end$$ +-- +0 51 SQL_COMMENT NO_KEYWORD +52 54 DO RESERVED_KEYWORD +55 90 SCONST NO_KEYWORD +== 048 +do $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 58 SCONST NO_KEYWORD +== 049 +-- check repeated assignments to composite fields +create table some_table (id int, data text) +-- +0 49 SQL_COMMENT NO_KEYWORD +50 56 CREATE RESERVED_KEYWORD +57 62 TABLE RESERVED_KEYWORD +63 73 IDENT NO_KEYWORD +74 75 ASCII_40 NO_KEYWORD +75 77 IDENT NO_KEYWORD +78 81 INT_P COL_NAME_KEYWORD +81 82 ASCII_44 NO_KEYWORD +83 87 DATA_P UNRESERVED_KEYWORD +88 92 TEXT_P UNRESERVED_KEYWORD +92 93 ASCII_41 NO_KEYWORD +== 050 +do $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 181 SCONST NO_KEYWORD +== 051 +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1); end $$ +-- +0 57 SQL_COMMENT NO_KEYWORD +59 65 CREATE RESERVED_KEYWORD +66 74 FUNCTION UNRESERVED_KEYWORD +75 88 IDENT NO_KEYWORD +88 89 ASCII_40 NO_KEYWORD +89 92 INT_P COL_NAME_KEYWORD +92 93 ASCII_41 NO_KEYWORD +94 101 RETURNS UNRESERVED_KEYWORD +102 108 IDENT NO_KEYWORD +109 117 LANGUAGE UNRESERVED_KEYWORD +118 125 IDENT NO_KEYWORD +126 128 AS RESERVED_KEYWORD +129 165 SCONST NO_KEYWORD +== 052 +select returnsrecord(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 20 IDENT NO_KEYWORD +20 21 ASCII_40 NO_KEYWORD +21 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 053 +select * from returnsrecord(42) as r(x int, y int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_41 NO_KEYWORD +== 054 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_44 NO_KEYWORD +51 52 IDENT NO_KEYWORD +53 56 INT_P COL_NAME_KEYWORD +56 57 ASCII_41 NO_KEYWORD +== 055 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +0 7 SQL_COMMENT NO_KEYWORD +8 14 SELECT RESERVED_KEYWORD +15 16 ASCII_42 NO_KEYWORD +17 21 FROM RESERVED_KEYWORD +22 35 IDENT NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 38 ICONST NO_KEYWORD +38 39 ASCII_41 NO_KEYWORD +40 42 AS RESERVED_KEYWORD +43 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 IDENT NO_KEYWORD +47 50 INT_P COL_NAME_KEYWORD +50 51 ASCII_44 NO_KEYWORD +52 53 IDENT NO_KEYWORD +54 60 BIGINT COL_NAME_KEYWORD +60 61 ASCII_41 NO_KEYWORD +== 056 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1); return r; end $$ +-- +0 7 SQL_COMMENT NO_KEYWORD +9 53 SQL_COMMENT NO_KEYWORD +54 60 CREATE RESERVED_KEYWORD +61 63 OR RESERVED_KEYWORD +64 71 REPLACE UNRESERVED_KEYWORD +72 80 FUNCTION UNRESERVED_KEYWORD +81 94 IDENT NO_KEYWORD +94 95 ASCII_40 NO_KEYWORD +95 98 INT_P COL_NAME_KEYWORD +98 99 ASCII_41 NO_KEYWORD +100 107 RETURNS UNRESERVED_KEYWORD +108 114 IDENT NO_KEYWORD +115 123 LANGUAGE UNRESERVED_KEYWORD +124 131 IDENT NO_KEYWORD +132 134 AS RESERVED_KEYWORD +135 197 SCONST NO_KEYWORD +== 057 +select returnsrecord(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 20 IDENT NO_KEYWORD +20 21 ASCII_40 NO_KEYWORD +21 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 058 +select * from returnsrecord(42) as r(x int, y int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_41 NO_KEYWORD +== 059 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_44 NO_KEYWORD +51 52 IDENT NO_KEYWORD +53 56 INT_P COL_NAME_KEYWORD +56 57 ASCII_41 NO_KEYWORD +== 060 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +0 7 SQL_COMMENT NO_KEYWORD +8 14 SELECT RESERVED_KEYWORD +15 16 ASCII_42 NO_KEYWORD +17 21 FROM RESERVED_KEYWORD +22 35 IDENT NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 38 ICONST NO_KEYWORD +38 39 ASCII_41 NO_KEYWORD +40 42 AS RESERVED_KEYWORD +43 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 IDENT NO_KEYWORD +47 50 INT_P COL_NAME_KEYWORD +50 51 ASCII_44 NO_KEYWORD +52 53 IDENT NO_KEYWORD +54 60 BIGINT COL_NAME_KEYWORD +60 61 ASCII_41 NO_KEYWORD +== 061 +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +-- +0 7 SQL_COMMENT NO_KEYWORD +9 81 SQL_COMMENT NO_KEYWORD +82 88 CREATE RESERVED_KEYWORD +89 94 TABLE RESERVED_KEYWORD +95 103 IDENT NO_KEYWORD +103 104 ASCII_40 NO_KEYWORD +104 106 IDENT NO_KEYWORD +107 110 INT_P COL_NAME_KEYWORD +110 111 ASCII_44 NO_KEYWORD +112 114 IDENT NO_KEYWORD +115 118 INT_P COL_NAME_KEYWORD +118 119 ASCII_44 NO_KEYWORD +120 122 IDENT NO_KEYWORD +123 126 INT_P COL_NAME_KEYWORD +126 127 ASCII_41 NO_KEYWORD +== 062 +alter table has_hole drop column f2 +-- +0 5 ALTER UNRESERVED_KEYWORD +6 11 TABLE RESERVED_KEYWORD +12 20 IDENT NO_KEYWORD +21 25 DROP UNRESERVED_KEYWORD +26 32 COLUMN RESERVED_KEYWORD +33 35 IDENT NO_KEYWORD +== 063 +create or replace function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1)::has_hole; end $$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 40 IDENT NO_KEYWORD +40 41 ASCII_40 NO_KEYWORD +41 44 INT_P COL_NAME_KEYWORD +44 45 ASCII_41 NO_KEYWORD +46 53 RETURNS UNRESERVED_KEYWORD +54 60 IDENT NO_KEYWORD +61 69 LANGUAGE UNRESERVED_KEYWORD +70 77 IDENT NO_KEYWORD +78 80 AS RESERVED_KEYWORD +81 127 SCONST NO_KEYWORD +== 064 +select returnsrecord(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 20 IDENT NO_KEYWORD +20 21 ASCII_40 NO_KEYWORD +21 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 065 +select * from returnsrecord(42) as r(x int, y int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_41 NO_KEYWORD +== 066 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_44 NO_KEYWORD +51 52 IDENT NO_KEYWORD +53 56 INT_P COL_NAME_KEYWORD +56 57 ASCII_41 NO_KEYWORD +== 067 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +0 7 SQL_COMMENT NO_KEYWORD +8 14 SELECT RESERVED_KEYWORD +15 16 ASCII_42 NO_KEYWORD +17 21 FROM RESERVED_KEYWORD +22 35 IDENT NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 38 ICONST NO_KEYWORD +38 39 ASCII_41 NO_KEYWORD +40 42 AS RESERVED_KEYWORD +43 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 IDENT NO_KEYWORD +47 50 INT_P COL_NAME_KEYWORD +50 51 ASCII_44 NO_KEYWORD +52 53 IDENT NO_KEYWORD +54 60 BIGINT COL_NAME_KEYWORD +60 61 ASCII_41 NO_KEYWORD +== 068 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +-- +0 7 SQL_COMMENT NO_KEYWORD +9 53 SQL_COMMENT NO_KEYWORD +54 60 CREATE RESERVED_KEYWORD +61 63 OR RESERVED_KEYWORD +64 71 REPLACE UNRESERVED_KEYWORD +72 80 FUNCTION UNRESERVED_KEYWORD +81 94 IDENT NO_KEYWORD +94 95 ASCII_40 NO_KEYWORD +95 98 INT_P COL_NAME_KEYWORD +98 99 ASCII_41 NO_KEYWORD +100 107 RETURNS UNRESERVED_KEYWORD +108 114 IDENT NO_KEYWORD +115 123 LANGUAGE UNRESERVED_KEYWORD +124 131 IDENT NO_KEYWORD +132 134 AS RESERVED_KEYWORD +135 207 SCONST NO_KEYWORD +== 069 +select returnsrecord(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 20 IDENT NO_KEYWORD +20 21 ASCII_40 NO_KEYWORD +21 23 ICONST NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 070 +select * from returnsrecord(42) as r(x int, y int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_41 NO_KEYWORD +== 071 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +32 34 AS RESERVED_KEYWORD +35 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 IDENT NO_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +42 43 ASCII_44 NO_KEYWORD +44 45 IDENT NO_KEYWORD +46 49 INT_P COL_NAME_KEYWORD +49 50 ASCII_44 NO_KEYWORD +51 52 IDENT NO_KEYWORD +53 56 INT_P COL_NAME_KEYWORD +56 57 ASCII_41 NO_KEYWORD +== 072 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +0 7 SQL_COMMENT NO_KEYWORD +8 14 SELECT RESERVED_KEYWORD +15 16 ASCII_42 NO_KEYWORD +17 21 FROM RESERVED_KEYWORD +22 35 IDENT NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 38 ICONST NO_KEYWORD +38 39 ASCII_41 NO_KEYWORD +40 42 AS RESERVED_KEYWORD +43 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 IDENT NO_KEYWORD +47 50 INT_P COL_NAME_KEYWORD +50 51 ASCII_44 NO_KEYWORD +52 53 IDENT NO_KEYWORD +54 60 BIGINT COL_NAME_KEYWORD +60 61 ASCII_41 NO_KEYWORD +== 073 +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$$ begin return x.f1; end $$ +-- +0 7 SQL_COMMENT NO_KEYWORD +9 68 SQL_COMMENT NO_KEYWORD +69 75 CREATE RESERVED_KEYWORD +76 84 FUNCTION UNRESERVED_KEYWORD +85 90 IDENT NO_KEYWORD +90 91 ASCII_40 NO_KEYWORD +91 92 IDENT NO_KEYWORD +93 99 IDENT NO_KEYWORD +99 100 ASCII_41 NO_KEYWORD +101 108 RETURNS UNRESERVED_KEYWORD +109 112 INT_P COL_NAME_KEYWORD +113 121 LANGUAGE UNRESERVED_KEYWORD +122 129 IDENT NO_KEYWORD +130 132 AS RESERVED_KEYWORD +133 161 SCONST NO_KEYWORD +== 074 +select getf1(1) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 14 ICONST NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +== 075 +select getf1(row(1,2)) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 16 ROW COL_NAME_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_44 NO_KEYWORD +19 20 ICONST NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 076 +select getf1(row(1,2)::two_int4s) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 16 ROW COL_NAME_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_44 NO_KEYWORD +19 20 ICONST NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +21 23 TYPECAST NO_KEYWORD +23 32 IDENT NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 077 +select getf1(row('foo',123,456)::more_int4s) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 16 ROW COL_NAME_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 22 SCONST NO_KEYWORD +22 23 ASCII_44 NO_KEYWORD +23 26 ICONST NO_KEYWORD +26 27 ASCII_44 NO_KEYWORD +27 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +31 33 TYPECAST NO_KEYWORD +33 43 IDENT NO_KEYWORD +43 44 ASCII_41 NO_KEYWORD +== 078 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row(1,2)::two_int8s) +-- +0 59 SQL_COMMENT NO_KEYWORD +60 97 SQL_COMMENT NO_KEYWORD +98 104 SELECT RESERVED_KEYWORD +105 110 IDENT NO_KEYWORD +110 111 ASCII_40 NO_KEYWORD +111 114 ROW COL_NAME_KEYWORD +114 115 ASCII_40 NO_KEYWORD +115 116 ICONST NO_KEYWORD +116 117 ASCII_44 NO_KEYWORD +117 118 ICONST NO_KEYWORD +118 119 ASCII_41 NO_KEYWORD +119 121 TYPECAST NO_KEYWORD +121 130 IDENT NO_KEYWORD +130 131 ASCII_41 NO_KEYWORD +== 079 +select getf1(row(1,2)) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 16 ROW COL_NAME_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_44 NO_KEYWORD +19 20 ICONST NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 080 +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$$ begin return $1.f2; end $$ +-- +0 60 SQL_COMMENT NO_KEYWORD +61 126 SQL_COMMENT NO_KEYWORD +127 133 CREATE RESERVED_KEYWORD +134 142 FUNCTION UNRESERVED_KEYWORD +143 148 IDENT NO_KEYWORD +148 149 ASCII_40 NO_KEYWORD +149 155 IDENT NO_KEYWORD +155 156 ASCII_41 NO_KEYWORD +157 164 RETURNS UNRESERVED_KEYWORD +165 168 INT_P COL_NAME_KEYWORD +169 177 LANGUAGE UNRESERVED_KEYWORD +178 185 IDENT NO_KEYWORD +186 188 AS RESERVED_KEYWORD +189 218 SCONST NO_KEYWORD +== 081 +select getf2(row(1,2)) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 16 ROW COL_NAME_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 18 ICONST NO_KEYWORD +18 19 ASCII_44 NO_KEYWORD +19 20 ICONST NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 082 +-- ideally would work, but does not +select getf2(row(1,2)::two_int4s) +-- +0 35 SQL_COMMENT NO_KEYWORD +36 42 SELECT RESERVED_KEYWORD +43 48 IDENT NO_KEYWORD +48 49 ASCII_40 NO_KEYWORD +49 52 ROW COL_NAME_KEYWORD +52 53 ASCII_40 NO_KEYWORD +53 54 ICONST NO_KEYWORD +54 55 ASCII_44 NO_KEYWORD +55 56 ICONST NO_KEYWORD +56 57 ASCII_41 NO_KEYWORD +57 59 TYPECAST NO_KEYWORD +59 68 IDENT NO_KEYWORD +68 69 ASCII_41 NO_KEYWORD +== 083 +select getf2(row('foo',123,456)::more_int4s) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 16 ROW COL_NAME_KEYWORD +16 17 ASCII_40 NO_KEYWORD +17 22 SCONST NO_KEYWORD +22 23 ASCII_44 NO_KEYWORD +23 26 ICONST NO_KEYWORD +26 27 ASCII_44 NO_KEYWORD +27 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +31 33 TYPECAST NO_KEYWORD +33 43 IDENT NO_KEYWORD +43 44 ASCII_41 NO_KEYWORD +== 084 +-- check behavior when assignment to FOR-loop variable requires coercion +do $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +-- +0 72 SQL_COMMENT NO_KEYWORD +73 75 DO RESERVED_KEYWORD +76 212 SCONST NO_KEYWORD +== 085 +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +-- +0 48 SQL_COMMENT NO_KEYWORD +49 55 CREATE RESERVED_KEYWORD +56 64 FUNCTION UNRESERVED_KEYWORD +65 82 IDENT NO_KEYWORD +82 83 ASCII_40 NO_KEYWORD +83 84 ASCII_41 NO_KEYWORD +85 92 RETURNS UNRESERVED_KEYWORD +93 98 SETOF COL_NAME_KEYWORD +99 107 IDENT NO_KEYWORD +108 116 LANGUAGE UNRESERVED_KEYWORD +117 124 IDENT NO_KEYWORD +125 127 AS RESERVED_KEYWORD +128 311 SCONST NO_KEYWORD +== 086 +select returnssetofholes() +-- +0 6 SELECT RESERVED_KEYWORD +7 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 087 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 ASCII_41 NO_KEYWORD +47 54 RETURNS UNRESERVED_KEYWORD +55 60 SETOF COL_NAME_KEYWORD +61 69 IDENT NO_KEYWORD +70 78 LANGUAGE UNRESERVED_KEYWORD +79 86 IDENT NO_KEYWORD +87 89 AS RESERVED_KEYWORD +90 167 SCONST NO_KEYWORD +== 088 +select returnssetofholes() +-- +0 6 SELECT RESERVED_KEYWORD +7 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 089 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +begin + return next row(1,2,3); -- fails +end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 ASCII_41 NO_KEYWORD +47 54 RETURNS UNRESERVED_KEYWORD +55 60 SETOF COL_NAME_KEYWORD +61 69 IDENT NO_KEYWORD +70 78 LANGUAGE UNRESERVED_KEYWORD +79 86 IDENT NO_KEYWORD +87 89 AS RESERVED_KEYWORD +90 140 SCONST NO_KEYWORD +== 090 +select returnssetofholes() +-- +0 6 SELECT RESERVED_KEYWORD +7 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 091 +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +-- +0 49 SQL_COMMENT NO_KEYWORD +50 56 CREATE RESERVED_KEYWORD +57 62 TABLE RESERVED_KEYWORD +63 70 IDENT NO_KEYWORD +70 71 ASCII_40 NO_KEYWORD +71 73 IDENT NO_KEYWORD +74 77 INT_P COL_NAME_KEYWORD +77 78 ASCII_44 NO_KEYWORD +79 81 IDENT NO_KEYWORD +82 86 TEXT_P UNRESERVED_KEYWORD +86 87 ASCII_41 NO_KEYWORD +== 092 +create function sillyaddone(int) returns int language plpgsql as +$$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 31 INT_P COL_NAME_KEYWORD +31 32 ASCII_41 NO_KEYWORD +33 40 RETURNS UNRESERVED_KEYWORD +41 44 INT_P COL_NAME_KEYWORD +45 53 LANGUAGE UNRESERVED_KEYWORD +54 61 IDENT NO_KEYWORD +62 64 AS RESERVED_KEYWORD +65 128 SCONST NO_KEYWORD +== 093 +select sillyaddone(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 18 IDENT NO_KEYWORD +18 19 ASCII_40 NO_KEYWORD +19 21 ICONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 094 +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +-- +0 63 SQL_COMMENT NO_KEYWORD +64 97 SQL_COMMENT NO_KEYWORD +99 104 ALTER UNRESERVED_KEYWORD +105 110 TABLE RESERVED_KEYWORD +111 118 IDENT NO_KEYWORD +119 123 DROP UNRESERVED_KEYWORD +124 130 COLUMN RESERVED_KEYWORD +131 133 IDENT NO_KEYWORD +== 095 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone(42) +-- +0 59 SQL_COMMENT NO_KEYWORD +60 97 SQL_COMMENT NO_KEYWORD +98 104 SELECT RESERVED_KEYWORD +105 116 IDENT NO_KEYWORD +116 117 ASCII_40 NO_KEYWORD +117 119 ICONST NO_KEYWORD +119 120 ASCII_41 NO_KEYWORD +== 096 +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$$ begin return x.f3; end $$ +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 30 IDENT NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 32 IDENT NO_KEYWORD +33 40 IDENT NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +42 49 RETURNS UNRESERVED_KEYWORD +50 53 INT_P COL_NAME_KEYWORD +54 62 LANGUAGE UNRESERVED_KEYWORD +63 70 IDENT NO_KEYWORD +71 73 AS RESERVED_KEYWORD +74 102 SCONST NO_KEYWORD +== 097 +select getf3(null::mutable) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 17 NULL_P RESERVED_KEYWORD +17 19 TYPECAST NO_KEYWORD +19 26 IDENT NO_KEYWORD +26 27 ASCII_41 NO_KEYWORD +== 098 +-- doesn't work yet +alter table mutable add column f3 int +-- +0 19 SQL_COMMENT NO_KEYWORD +20 25 ALTER UNRESERVED_KEYWORD +26 31 TABLE RESERVED_KEYWORD +32 39 IDENT NO_KEYWORD +40 43 ADD_P UNRESERVED_KEYWORD +44 50 COLUMN RESERVED_KEYWORD +51 53 IDENT NO_KEYWORD +54 57 INT_P COL_NAME_KEYWORD +== 099 +select getf3(null::mutable) +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 17 NULL_P RESERVED_KEYWORD +17 19 TYPECAST NO_KEYWORD +19 26 IDENT NO_KEYWORD +26 27 ASCII_41 NO_KEYWORD +== 100 +-- now it works +alter table mutable drop column f3 +-- +0 15 SQL_COMMENT NO_KEYWORD +16 21 ALTER UNRESERVED_KEYWORD +22 27 TABLE RESERVED_KEYWORD +28 35 IDENT NO_KEYWORD +36 40 DROP UNRESERVED_KEYWORD +41 47 COLUMN RESERVED_KEYWORD +48 50 IDENT NO_KEYWORD +== 101 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3(null::mutable) +-- +0 59 SQL_COMMENT NO_KEYWORD +60 97 SQL_COMMENT NO_KEYWORD +98 104 SELECT RESERVED_KEYWORD +105 110 IDENT NO_KEYWORD +110 111 ASCII_40 NO_KEYWORD +111 115 NULL_P RESERVED_KEYWORD +115 117 TYPECAST NO_KEYWORD +117 124 IDENT NO_KEYWORD +124 125 ASCII_41 NO_KEYWORD +== 102 +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off +-- +0 14 SQL_COMMENT NO_KEYWORD +16 72 SQL_COMMENT NO_KEYWORD +73 76 SET UNRESERVED_KEYWORD +77 98 IDENT NO_KEYWORD +99 100 ASCII_61 NO_KEYWORD +101 104 OFF UNRESERVED_KEYWORD +== 103 +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +-- +0 43 SQL_COMMENT NO_KEYWORD +45 51 CREATE RESERVED_KEYWORD +52 60 FUNCTION UNRESERVED_KEYWORD +61 72 IDENT NO_KEYWORD +72 73 ASCII_40 NO_KEYWORD +73 76 INT_P COL_NAME_KEYWORD +76 77 ASCII_41 NO_KEYWORD +78 85 RETURNS UNRESERVED_KEYWORD +86 89 INT_P COL_NAME_KEYWORD +90 98 LANGUAGE UNRESERVED_KEYWORD +99 106 IDENT NO_KEYWORD +107 109 AS RESERVED_KEYWORD +110 174 SCONST NO_KEYWORD +== 104 +reset check_function_bodies +-- +0 5 RESET UNRESERVED_KEYWORD +6 27 IDENT NO_KEYWORD +== 105 +select sillyaddtwo(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 18 IDENT NO_KEYWORD +18 19 ASCII_40 NO_KEYWORD +19 21 ICONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 106 +-- fail +create table mutable2(f1 int, f2 text) +-- +0 7 SQL_COMMENT NO_KEYWORD +8 14 CREATE RESERVED_KEYWORD +15 20 TABLE RESERVED_KEYWORD +21 29 IDENT NO_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 32 IDENT NO_KEYWORD +33 36 INT_P COL_NAME_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 40 IDENT NO_KEYWORD +41 45 TEXT_P UNRESERVED_KEYWORD +45 46 ASCII_41 NO_KEYWORD +== 107 +select sillyaddtwo(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 18 IDENT NO_KEYWORD +18 19 ASCII_40 NO_KEYWORD +19 21 ICONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 108 +drop table mutable2 +-- +0 4 DROP UNRESERVED_KEYWORD +5 10 TABLE RESERVED_KEYWORD +11 19 IDENT NO_KEYWORD +== 109 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo(42) +-- +0 59 SQL_COMMENT NO_KEYWORD +60 97 SQL_COMMENT NO_KEYWORD +98 104 SELECT RESERVED_KEYWORD +105 116 IDENT NO_KEYWORD +116 117 ASCII_40 NO_KEYWORD +117 119 ICONST NO_KEYWORD +119 120 ASCII_41 NO_KEYWORD +== 110 +-- fail +create table mutable2(f0 text, f1 int, f2 text) +-- +0 7 SQL_COMMENT NO_KEYWORD +8 14 CREATE RESERVED_KEYWORD +15 20 TABLE RESERVED_KEYWORD +21 29 IDENT NO_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 32 IDENT NO_KEYWORD +33 37 TEXT_P UNRESERVED_KEYWORD +37 38 ASCII_44 NO_KEYWORD +39 41 IDENT NO_KEYWORD +42 45 INT_P COL_NAME_KEYWORD +45 46 ASCII_44 NO_KEYWORD +47 49 IDENT NO_KEYWORD +50 54 TEXT_P UNRESERVED_KEYWORD +54 55 ASCII_41 NO_KEYWORD +== 111 +select sillyaddtwo(42) +-- +0 6 SELECT RESERVED_KEYWORD +7 18 IDENT NO_KEYWORD +18 19 ASCII_40 NO_KEYWORD +19 21 ICONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 112 +select sillyaddtwo(43) +-- +0 6 SELECT RESERVED_KEYWORD +7 18 IDENT NO_KEYWORD +18 19 ASCII_40 NO_KEYWORD +19 21 ICONST NO_KEYWORD +21 22 ASCII_41 NO_KEYWORD +== 113 +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +-- +0 54 SQL_COMMENT NO_KEYWORD +56 62 CREATE RESERVED_KEYWORD +63 71 FUNCTION UNRESERVED_KEYWORD +72 81 IDENT NO_KEYWORD +81 82 ASCII_40 NO_KEYWORD +82 83 ASCII_41 NO_KEYWORD +84 91 RETURNS UNRESERVED_KEYWORD +92 99 TRIGGER UNRESERVED_KEYWORD +100 108 LANGUAGE UNRESERVED_KEYWORD +109 116 IDENT NO_KEYWORD +117 119 AS RESERVED_KEYWORD +120 247 SCONST NO_KEYWORD +== 114 +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +-- +0 6 CREATE RESERVED_KEYWORD +7 14 TRIGGER UNRESERVED_KEYWORD +15 27 IDENT NO_KEYWORD +28 34 BEFORE UNRESERVED_KEYWORD +35 41 UPDATE UNRESERVED_KEYWORD +42 44 ON RESERVED_KEYWORD +45 52 IDENT NO_KEYWORD +53 56 FOR RESERVED_KEYWORD +57 61 EACH UNRESERVED_KEYWORD +62 65 ROW COL_NAME_KEYWORD +66 73 EXECUTE UNRESERVED_KEYWORD +74 83 PROCEDURE UNRESERVED_KEYWORD +84 93 IDENT NO_KEYWORD +93 94 ASCII_40 NO_KEYWORD +94 95 ASCII_41 NO_KEYWORD +== 115 +insert into mutable values ('foo'), ('bar') +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 26 VALUES COL_NAME_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 33 SCONST NO_KEYWORD +33 34 ASCII_41 NO_KEYWORD +34 35 ASCII_44 NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 42 SCONST NO_KEYWORD +42 43 ASCII_41 NO_KEYWORD +== 116 +update mutable set f2 = f2 || ' baz' +-- +0 6 UPDATE UNRESERVED_KEYWORD +7 14 IDENT NO_KEYWORD +15 18 SET UNRESERVED_KEYWORD +19 21 IDENT NO_KEYWORD +22 23 ASCII_61 NO_KEYWORD +24 26 IDENT NO_KEYWORD +27 29 Op NO_KEYWORD +30 36 SCONST NO_KEYWORD +== 117 +table mutable +-- +0 5 TABLE RESERVED_KEYWORD +6 13 IDENT NO_KEYWORD +== 118 +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$$begin + return row(new.*); +end$$ +-- +0 51 SQL_COMMENT NO_KEYWORD +53 59 CREATE RESERVED_KEYWORD +60 62 OR RESERVED_KEYWORD +63 70 REPLACE UNRESERVED_KEYWORD +71 79 FUNCTION UNRESERVED_KEYWORD +80 89 IDENT NO_KEYWORD +89 90 ASCII_40 NO_KEYWORD +90 91 ASCII_41 NO_KEYWORD +92 99 RETURNS UNRESERVED_KEYWORD +100 107 TRIGGER UNRESERVED_KEYWORD +108 116 LANGUAGE UNRESERVED_KEYWORD +117 124 IDENT NO_KEYWORD +125 127 AS RESERVED_KEYWORD +128 162 SCONST NO_KEYWORD +== 119 +update mutable set f2 = f2 || ' baz' +-- +0 6 UPDATE UNRESERVED_KEYWORD +7 14 IDENT NO_KEYWORD +15 18 SET UNRESERVED_KEYWORD +19 21 IDENT NO_KEYWORD +22 23 ASCII_61 NO_KEYWORD +24 26 IDENT NO_KEYWORD +27 29 Op NO_KEYWORD +30 36 SCONST NO_KEYWORD +== 120 +table mutable +-- +0 5 TABLE RESERVED_KEYWORD +6 13 IDENT NO_KEYWORD +== 121 +create or replace function sillytrig() returns trigger language plpgsql as +$$declare r record; +begin + r := row(new.*); + return r; +end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 ASCII_41 NO_KEYWORD +39 46 RETURNS UNRESERVED_KEYWORD +47 54 TRIGGER UNRESERVED_KEYWORD +55 63 LANGUAGE UNRESERVED_KEYWORD +64 71 IDENT NO_KEYWORD +72 74 AS RESERVED_KEYWORD +75 137 SCONST NO_KEYWORD +== 122 +update mutable set f2 = f2 || ' baz' +-- +0 6 UPDATE UNRESERVED_KEYWORD +7 14 IDENT NO_KEYWORD +15 18 SET UNRESERVED_KEYWORD +19 21 IDENT NO_KEYWORD +22 23 ASCII_61 NO_KEYWORD +24 26 IDENT NO_KEYWORD +27 29 Op NO_KEYWORD +30 36 SCONST NO_KEYWORD +== 123 +table mutable +-- +0 5 TABLE RESERVED_KEYWORD +6 13 IDENT NO_KEYWORD +== 124 +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 26 SQL_COMMENT NO_KEYWORD +27 29 SQL_COMMENT NO_KEYWORD +31 37 CREATE RESERVED_KEYWORD +38 44 DOMAIN_P UNRESERVED_KEYWORD +45 58 IDENT NO_KEYWORD +59 61 AS RESERVED_KEYWORD +62 71 IDENT NO_KEYWORD +72 77 CHECK RESERVED_KEYWORD +77 78 ASCII_40 NO_KEYWORD +78 79 ASCII_40 NO_KEYWORD +79 84 VALUE_P UNRESERVED_KEYWORD +84 85 ASCII_41 NO_KEYWORD +85 86 ASCII_46 NO_KEYWORD +86 88 IDENT NO_KEYWORD +89 91 LESS_EQUALS NO_KEYWORD +92 93 ASCII_40 NO_KEYWORD +93 98 VALUE_P UNRESERVED_KEYWORD +98 99 ASCII_41 NO_KEYWORD +99 100 ASCII_46 NO_KEYWORD +100 102 IDENT NO_KEYWORD +102 103 ASCII_41 NO_KEYWORD +== 125 +create function read_ordered_int8s(p ordered_int8s) returns int8 as $$ +begin return p.q1 + p.q2; end +$$ language plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 IDENT NO_KEYWORD +37 50 IDENT NO_KEYWORD +50 51 ASCII_41 NO_KEYWORD +52 59 RETURNS UNRESERVED_KEYWORD +60 64 IDENT NO_KEYWORD +65 67 AS RESERVED_KEYWORD +68 103 SCONST NO_KEYWORD +104 112 LANGUAGE UNRESERVED_KEYWORD +113 120 IDENT NO_KEYWORD +== 126 +select read_ordered_int8s(row(1, 2)) +-- +0 6 SELECT RESERVED_KEYWORD +7 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 29 ROW COL_NAME_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 31 ICONST NO_KEYWORD +31 32 ASCII_44 NO_KEYWORD +33 34 ICONST NO_KEYWORD +34 35 ASCII_41 NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +== 127 +select read_ordered_int8s(row(2, 1)) +-- +0 6 SELECT RESERVED_KEYWORD +7 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 29 ROW COL_NAME_KEYWORD +29 30 ASCII_40 NO_KEYWORD +30 31 ICONST NO_KEYWORD +31 32 ASCII_44 NO_KEYWORD +33 34 ICONST NO_KEYWORD +34 35 ASCII_41 NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +== 128 +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $$ +begin return row(i,j); end +$$ language plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 IDENT NO_KEYWORD +47 51 IDENT NO_KEYWORD +51 52 ASCII_44 NO_KEYWORD +53 54 IDENT NO_KEYWORD +55 59 IDENT NO_KEYWORD +59 60 ASCII_41 NO_KEYWORD +61 68 RETURNS UNRESERVED_KEYWORD +69 82 IDENT NO_KEYWORD +83 85 AS RESERVED_KEYWORD +86 118 SCONST NO_KEYWORD +119 127 LANGUAGE UNRESERVED_KEYWORD +128 135 IDENT NO_KEYWORD +== 129 +select build_ordered_int8s(1,2) +-- +0 6 SELECT RESERVED_KEYWORD +7 26 IDENT NO_KEYWORD +26 27 ASCII_40 NO_KEYWORD +27 28 ICONST NO_KEYWORD +28 29 ASCII_44 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +== 130 +select build_ordered_int8s(2,1) +-- +0 6 SELECT RESERVED_KEYWORD +7 26 IDENT NO_KEYWORD +26 27 ASCII_40 NO_KEYWORD +27 28 ICONST NO_KEYWORD +28 29 ASCII_44 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +== 131 +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $$ +declare r record; begin r := row(i,j); return r; end +$$ language plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 46 IDENT NO_KEYWORD +46 47 ASCII_40 NO_KEYWORD +47 48 IDENT NO_KEYWORD +49 53 IDENT NO_KEYWORD +53 54 ASCII_44 NO_KEYWORD +55 56 IDENT NO_KEYWORD +57 61 IDENT NO_KEYWORD +61 62 ASCII_41 NO_KEYWORD +63 70 RETURNS UNRESERVED_KEYWORD +71 84 IDENT NO_KEYWORD +85 87 AS RESERVED_KEYWORD +88 146 SCONST NO_KEYWORD +147 155 LANGUAGE UNRESERVED_KEYWORD +156 163 IDENT NO_KEYWORD +== 132 +select build_ordered_int8s_2(1,2) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 133 +select build_ordered_int8s_2(2,1) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 134 +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 46 IDENT NO_KEYWORD +46 47 ASCII_40 NO_KEYWORD +47 48 IDENT NO_KEYWORD +49 53 IDENT NO_KEYWORD +53 54 ASCII_44 NO_KEYWORD +55 56 IDENT NO_KEYWORD +57 61 IDENT NO_KEYWORD +61 62 ASCII_41 NO_KEYWORD +63 70 RETURNS UNRESERVED_KEYWORD +71 84 IDENT NO_KEYWORD +85 87 AS RESERVED_KEYWORD +88 149 SCONST NO_KEYWORD +150 158 LANGUAGE UNRESERVED_KEYWORD +159 166 IDENT NO_KEYWORD +== 135 +select build_ordered_int8s_3(1,2) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 136 +select build_ordered_int8s_3(2,1) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 137 +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 46 IDENT NO_KEYWORD +46 47 ASCII_40 NO_KEYWORD +47 48 IDENT NO_KEYWORD +49 53 IDENT NO_KEYWORD +53 54 ASCII_44 NO_KEYWORD +55 56 IDENT NO_KEYWORD +57 61 IDENT NO_KEYWORD +61 62 ASCII_41 NO_KEYWORD +63 70 RETURNS UNRESERVED_KEYWORD +71 84 IDENT NO_KEYWORD +85 87 AS RESERVED_KEYWORD +88 153 SCONST NO_KEYWORD +154 162 LANGUAGE UNRESERVED_KEYWORD +163 170 IDENT NO_KEYWORD +== 138 +select build_ordered_int8s_4(1,2) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 139 +select build_ordered_int8s_4(2,1) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 140 +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ language plpgsql +-- +0 7 SQL_COMMENT NO_KEYWORD +9 15 CREATE RESERVED_KEYWORD +16 24 FUNCTION UNRESERVED_KEYWORD +25 46 IDENT NO_KEYWORD +46 47 ASCII_40 NO_KEYWORD +47 48 IDENT NO_KEYWORD +49 53 IDENT NO_KEYWORD +53 54 ASCII_44 NO_KEYWORD +55 56 IDENT NO_KEYWORD +57 61 IDENT NO_KEYWORD +61 62 ASCII_41 NO_KEYWORD +63 70 RETURNS UNRESERVED_KEYWORD +71 84 IDENT NO_KEYWORD +84 85 ASCII_91 NO_KEYWORD +85 86 ASCII_93 NO_KEYWORD +87 89 AS RESERVED_KEYWORD +90 141 SCONST NO_KEYWORD +142 150 LANGUAGE UNRESERVED_KEYWORD +151 158 IDENT NO_KEYWORD +== 141 +select build_ordered_int8s_a(1,2) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 142 +select build_ordered_int8s_a(2,1) +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ICONST NO_KEYWORD +30 31 ASCII_44 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 143 +-- fail + +-- check field assignment +do $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +-- +0 7 SQL_COMMENT NO_KEYWORD +9 34 SQL_COMMENT NO_KEYWORD +35 37 DO RESERVED_KEYWORD +38 144 SCONST NO_KEYWORD +== 144 +-- check whole-row assignment +do $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +-- +0 29 SQL_COMMENT NO_KEYWORD +30 32 DO RESERVED_KEYWORD +33 151 SCONST NO_KEYWORD +== 145 +-- check assignment in for-loop +do $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +-- +0 31 SQL_COMMENT NO_KEYWORD +32 34 DO RESERVED_KEYWORD +35 156 SCONST NO_KEYWORD +== 146 +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +-- +0 44 SQL_COMMENT NO_KEYWORD +46 52 CREATE RESERVED_KEYWORD +53 57 TYPE_P UNRESERVED_KEYWORD +58 67 IDENT NO_KEYWORD +68 70 AS RESERVED_KEYWORD +71 72 ASCII_40 NO_KEYWORD +72 74 IDENT NO_KEYWORD +75 79 TEXT_P UNRESERVED_KEYWORD +79 80 ASCII_44 NO_KEYWORD +81 83 IDENT NO_KEYWORD +84 88 TEXT_P UNRESERVED_KEYWORD +88 89 ASCII_41 NO_KEYWORD +== 147 +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +-- +0 6 CREATE RESERVED_KEYWORD +7 13 DOMAIN_P UNRESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +28 30 AS RESERVED_KEYWORD +31 40 IDENT NO_KEYWORD +41 46 CHECK RESERVED_KEYWORD +46 47 ASCII_40 NO_KEYWORD +47 48 ASCII_40 NO_KEYWORD +48 53 VALUE_P UNRESERVED_KEYWORD +53 54 ASCII_41 NO_KEYWORD +54 55 ASCII_46 NO_KEYWORD +55 57 IDENT NO_KEYWORD +58 60 LESS_EQUALS NO_KEYWORD +61 62 ASCII_40 NO_KEYWORD +62 67 VALUE_P UNRESERVED_KEYWORD +67 68 ASCII_41 NO_KEYWORD +68 69 ASCII_46 NO_KEYWORD +69 71 IDENT NO_KEYWORD +71 72 ASCII_41 NO_KEYWORD +== 148 +create table sometable (id int, a text, b text) +-- +0 6 CREATE RESERVED_KEYWORD +7 12 TABLE RESERVED_KEYWORD +13 22 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 26 IDENT NO_KEYWORD +27 30 INT_P COL_NAME_KEYWORD +30 31 ASCII_44 NO_KEYWORD +32 33 IDENT NO_KEYWORD +34 38 TEXT_P UNRESERVED_KEYWORD +38 39 ASCII_44 NO_KEYWORD +40 41 IDENT NO_KEYWORD +42 46 TEXT_P UNRESERVED_KEYWORD +46 47 ASCII_41 NO_KEYWORD +== 149 +-- b should be compressed, but in-line +insert into sometable values (1, 'a', repeat('ffoob',1000)) +-- +0 38 SQL_COMMENT NO_KEYWORD +39 45 INSERT UNRESERVED_KEYWORD +46 50 INTO RESERVED_KEYWORD +51 60 IDENT NO_KEYWORD +61 67 VALUES COL_NAME_KEYWORD +68 69 ASCII_40 NO_KEYWORD +69 70 ICONST NO_KEYWORD +70 71 ASCII_44 NO_KEYWORD +72 75 SCONST NO_KEYWORD +75 76 ASCII_44 NO_KEYWORD +77 83 IDENT NO_KEYWORD +83 84 ASCII_40 NO_KEYWORD +84 91 SCONST NO_KEYWORD +91 92 ASCII_44 NO_KEYWORD +92 96 ICONST NO_KEYWORD +96 97 ASCII_41 NO_KEYWORD +97 98 ASCII_41 NO_KEYWORD +== 150 +-- this b should be out-of-line +insert into sometable values (2, 'a', repeat('ffoob',100000)) +-- +0 31 SQL_COMMENT NO_KEYWORD +32 38 INSERT UNRESERVED_KEYWORD +39 43 INTO RESERVED_KEYWORD +44 53 IDENT NO_KEYWORD +54 60 VALUES COL_NAME_KEYWORD +61 62 ASCII_40 NO_KEYWORD +62 63 ICONST NO_KEYWORD +63 64 ASCII_44 NO_KEYWORD +65 68 SCONST NO_KEYWORD +68 69 ASCII_44 NO_KEYWORD +70 76 IDENT NO_KEYWORD +76 77 ASCII_40 NO_KEYWORD +77 84 SCONST NO_KEYWORD +84 85 ASCII_44 NO_KEYWORD +85 91 ICONST NO_KEYWORD +91 92 ASCII_41 NO_KEYWORD +92 93 ASCII_41 NO_KEYWORD +== 151 +-- this pair should fail the domain check +insert into sometable values (3, 'z', repeat('ffoob',100000)) +-- +0 41 SQL_COMMENT NO_KEYWORD +42 48 INSERT UNRESERVED_KEYWORD +49 53 INTO RESERVED_KEYWORD +54 63 IDENT NO_KEYWORD +64 70 VALUES COL_NAME_KEYWORD +71 72 ASCII_40 NO_KEYWORD +72 73 ICONST NO_KEYWORD +73 74 ASCII_44 NO_KEYWORD +75 78 SCONST NO_KEYWORD +78 79 ASCII_44 NO_KEYWORD +80 86 IDENT NO_KEYWORD +86 87 ASCII_40 NO_KEYWORD +87 94 SCONST NO_KEYWORD +94 95 ASCII_44 NO_KEYWORD +95 101 ICONST NO_KEYWORD +101 102 ASCII_41 NO_KEYWORD +102 103 ASCII_41 NO_KEYWORD +== 152 +do $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 140 SCONST NO_KEYWORD +== 153 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 171 SCONST NO_KEYWORD +== 154 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 196 SCONST NO_KEYWORD +== 155 +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$ +-- +0 76 SQL_COMMENT NO_KEYWORD +77 83 CREATE RESERVED_KEYWORD +84 92 FUNCTION UNRESERVED_KEYWORD +93 103 IDENT NO_KEYWORD +103 104 ASCII_40 NO_KEYWORD +104 108 IDENT NO_KEYWORD +108 109 ASCII_41 NO_KEYWORD +110 117 RETURNS UNRESERVED_KEYWORD +118 127 IDENT NO_KEYWORD +128 136 LANGUAGE UNRESERVED_KEYWORD +137 144 IDENT NO_KEYWORD +145 147 AS RESERVED_KEYWORD +148 208 SCONST NO_KEYWORD +== 156 +create table two_int8s_tab (f1 two_int8s) +-- +0 6 CREATE RESERVED_KEYWORD +7 12 TABLE RESERVED_KEYWORD +13 26 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 30 IDENT NO_KEYWORD +31 40 IDENT NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +== 157 +insert into two_int8s_tab values (compresult(42)) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 25 IDENT NO_KEYWORD +26 32 VALUES COL_NAME_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 47 ICONST NO_KEYWORD +47 48 ASCII_41 NO_KEYWORD +48 49 ASCII_41 NO_KEYWORD +== 158 +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab +-- +0 69 SQL_COMMENT NO_KEYWORD +70 75 TABLE RESERVED_KEYWORD +76 89 IDENT NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_simple.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_simple.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_simple.test b/parser/testdata/scan/plpgsql_regress/plpgsql_simple.test new file mode 100644 index 0000000..d0d401e --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_simple.test @@ -0,0 +1,337 @@ +== 001 +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as 'select $1' +-- +0 2 SQL_COMMENT NO_KEYWORD +3 58 SQL_COMMENT NO_KEYWORD +59 61 SQL_COMMENT NO_KEYWORD +63 133 SQL_COMMENT NO_KEYWORD +134 140 CREATE RESERVED_KEYWORD +141 149 FUNCTION UNRESERVED_KEYWORD +150 159 IDENT NO_KEYWORD +159 160 ASCII_40 NO_KEYWORD +160 163 INT_P COL_NAME_KEYWORD +163 164 ASCII_41 NO_KEYWORD +165 172 RETURNS UNRESERVED_KEYWORD +173 176 INT_P COL_NAME_KEYWORD +177 185 LANGUAGE UNRESERVED_KEYWORD +186 189 SQL_P UNRESERVED_KEYWORD +190 192 AS RESERVED_KEYWORD +193 204 SCONST NO_KEYWORD +== 002 +create function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ASCII_41 NO_KEYWORD +31 38 RETURNS UNRESERVED_KEYWORD +39 42 INT_P COL_NAME_KEYWORD +43 51 LANGUAGE UNRESERVED_KEYWORD +52 59 IDENT NO_KEYWORD +60 62 AS RESERVED_KEYWORD +63 311 SCONST NO_KEYWORD +== 003 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 004 +-- Check that changes in search path are dealt with correctly +create schema simple1 +-- +0 61 SQL_COMMENT NO_KEYWORD +62 68 CREATE RESERVED_KEYWORD +69 75 SCHEMA UNRESERVED_KEYWORD +76 83 IDENT NO_KEYWORD +== 005 +create function simple1.simpletarget(int) returns int language plpgsql +as $$begin return $1; end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 23 IDENT NO_KEYWORD +23 24 ASCII_46 NO_KEYWORD +24 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 40 INT_P COL_NAME_KEYWORD +40 41 ASCII_41 NO_KEYWORD +42 49 RETURNS UNRESERVED_KEYWORD +50 53 INT_P COL_NAME_KEYWORD +54 62 LANGUAGE UNRESERVED_KEYWORD +63 70 IDENT NO_KEYWORD +71 73 AS RESERVED_KEYWORD +74 98 SCONST NO_KEYWORD +== 006 +create function simpletarget(int) returns int language plpgsql +as $$begin return $1 + 100; end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 32 INT_P COL_NAME_KEYWORD +32 33 ASCII_41 NO_KEYWORD +34 41 RETURNS UNRESERVED_KEYWORD +42 45 INT_P COL_NAME_KEYWORD +46 54 LANGUAGE UNRESERVED_KEYWORD +55 62 IDENT NO_KEYWORD +63 65 AS RESERVED_KEYWORD +66 96 SCONST NO_KEYWORD +== 007 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 39 IDENT NO_KEYWORD +39 40 ASCII_40 NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +42 49 RETURNS UNRESERVED_KEYWORD +50 53 INT_P COL_NAME_KEYWORD +54 62 LANGUAGE UNRESERVED_KEYWORD +63 70 IDENT NO_KEYWORD +71 73 AS RESERVED_KEYWORD +74 265 SCONST NO_KEYWORD +== 008 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 009 +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +-- +0 42 SQL_COMMENT NO_KEYWORD +43 48 ALTER UNRESERVED_KEYWORD +49 57 FUNCTION UNRESERVED_KEYWORD +58 65 IDENT NO_KEYWORD +65 66 ASCII_46 NO_KEYWORD +66 78 IDENT NO_KEYWORD +78 79 ASCII_40 NO_KEYWORD +79 82 INT_P COL_NAME_KEYWORD +82 83 ASCII_41 NO_KEYWORD +84 93 IMMUTABLE UNRESERVED_KEYWORD +== 010 +alter function simpletarget(int) immutable +-- +0 5 ALTER UNRESERVED_KEYWORD +6 14 FUNCTION UNRESERVED_KEYWORD +15 27 IDENT NO_KEYWORD +27 28 ASCII_40 NO_KEYWORD +28 31 INT_P COL_NAME_KEYWORD +31 32 ASCII_41 NO_KEYWORD +33 42 IMMUTABLE UNRESERVED_KEYWORD +== 011 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 012 +-- make sure flushing local caches changes nothing + +select simplecaller() +-- +0 50 SQL_COMMENT NO_KEYWORD +52 58 SELECT RESERVED_KEYWORD +59 71 IDENT NO_KEYWORD +71 72 ASCII_40 NO_KEYWORD +72 73 ASCII_41 NO_KEYWORD +== 013 +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $$select 1 / 0$$ +-- +0 67 SQL_COMMENT NO_KEYWORD +69 75 CREATE RESERVED_KEYWORD +76 84 FUNCTION UNRESERVED_KEYWORD +85 94 IDENT NO_KEYWORD +94 95 ASCII_40 NO_KEYWORD +95 96 ASCII_41 NO_KEYWORD +97 104 RETURNS UNRESERVED_KEYWORD +105 108 INT_P COL_NAME_KEYWORD +109 117 LANGUAGE UNRESERVED_KEYWORD +118 121 SQL_P UNRESERVED_KEYWORD +122 124 AS RESERVED_KEYWORD +125 141 SCONST NO_KEYWORD +== 014 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 9 OR RESERVED_KEYWORD +10 17 REPLACE UNRESERVED_KEYWORD +18 26 FUNCTION UNRESERVED_KEYWORD +27 39 IDENT NO_KEYWORD +39 40 ASCII_40 NO_KEYWORD +40 41 ASCII_41 NO_KEYWORD +42 49 RETURNS UNRESERVED_KEYWORD +50 53 INT_P COL_NAME_KEYWORD +54 62 LANGUAGE UNRESERVED_KEYWORD +63 70 IDENT NO_KEYWORD +71 73 AS RESERVED_KEYWORD +74 144 SCONST NO_KEYWORD +== 015 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 016 +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $$select 2 + 2$$ +-- +0 51 SQL_COMMENT NO_KEYWORD +53 59 CREATE RESERVED_KEYWORD +60 62 OR RESERVED_KEYWORD +63 70 REPLACE UNRESERVED_KEYWORD +71 79 FUNCTION UNRESERVED_KEYWORD +80 89 IDENT NO_KEYWORD +89 90 ASCII_40 NO_KEYWORD +90 91 ASCII_41 NO_KEYWORD +92 99 RETURNS UNRESERVED_KEYWORD +100 103 INT_P COL_NAME_KEYWORD +104 112 LANGUAGE UNRESERVED_KEYWORD +113 116 SQL_P UNRESERVED_KEYWORD +117 119 AS RESERVED_KEYWORD +120 136 SCONST NO_KEYWORD +== 017 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 018 +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +-- +0 76 SQL_COMMENT NO_KEYWORD +78 84 CREATE RESERVED_KEYWORD +85 87 OR RESERVED_KEYWORD +88 95 REPLACE UNRESERVED_KEYWORD +96 104 FUNCTION UNRESERVED_KEYWORD +105 117 IDENT NO_KEYWORD +117 118 ASCII_40 NO_KEYWORD +118 119 ASCII_41 NO_KEYWORD +120 127 RETURNS UNRESERVED_KEYWORD +128 131 INT_P COL_NAME_KEYWORD +132 140 LANGUAGE UNRESERVED_KEYWORD +141 148 IDENT NO_KEYWORD +149 151 AS RESERVED_KEYWORD +152 213 SCONST NO_KEYWORD +== 019 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 020 +drop function simplesql() +-- +0 4 DROP UNRESERVED_KEYWORD +5 13 FUNCTION UNRESERVED_KEYWORD +14 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ASCII_41 NO_KEYWORD +== 021 +create function simplesql() returns setof int language sql +as $$select 22 + 22$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ASCII_41 NO_KEYWORD +28 35 RETURNS UNRESERVED_KEYWORD +36 41 SETOF COL_NAME_KEYWORD +42 45 INT_P COL_NAME_KEYWORD +46 54 LANGUAGE UNRESERVED_KEYWORD +55 58 SQL_P UNRESERVED_KEYWORD +59 61 AS RESERVED_KEYWORD +62 80 SCONST NO_KEYWORD +== 022 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 023 +select simplecaller() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 024 +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ +-- +0 74 SQL_COMMENT NO_KEYWORD +76 78 DO RESERVED_KEYWORD +79 230 SCONST NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_transaction.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_transaction.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_transaction.test b/parser/testdata/scan/plpgsql_regress/plpgsql_transaction.test new file mode 100644 index 0000000..f61c29b --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_transaction.test @@ -0,0 +1,1403 @@ +== 001 +CREATE TABLE test1 (a int, b text) +-- +0 6 CREATE RESERVED_KEYWORD +7 12 TABLE RESERVED_KEYWORD +13 18 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 IDENT NO_KEYWORD +22 25 INT_P COL_NAME_KEYWORD +25 26 ASCII_44 NO_KEYWORD +27 28 IDENT NO_KEYWORD +29 33 TEXT_P UNRESERVED_KEYWORD +33 34 ASCII_41 NO_KEYWORD +== 002 +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 IDENT NO_KEYWORD +37 40 INT_P COL_NAME_KEYWORD +40 41 ASCII_44 NO_KEYWORD +42 43 IDENT NO_KEYWORD +44 48 TEXT_P UNRESERVED_KEYWORD +48 49 ASCII_41 NO_KEYWORD +50 58 LANGUAGE UNRESERVED_KEYWORD +59 66 IDENT NO_KEYWORD +67 69 AS RESERVED_KEYWORD +70 267 SCONST NO_KEYWORD +== 003 +CALL transaction_test1(9, 'foo') +-- +0 4 CALL UNRESERVED_KEYWORD +5 22 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 24 ICONST NO_KEYWORD +24 25 ASCII_44 NO_KEYWORD +26 31 SCONST NO_KEYWORD +31 32 ASCII_41 NO_KEYWORD +== 004 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 005 +TRUNCATE test1 +-- +0 8 TRUNCATE UNRESERVED_KEYWORD +9 14 IDENT NO_KEYWORD +== 006 +DO +LANGUAGE plpgsql +$$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 211 SCONST NO_KEYWORD +== 007 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 008 +-- transaction commands not allowed when called in transaction block +START TRANSACTION +-- +0 68 SQL_COMMENT NO_KEYWORD +69 74 START UNRESERVED_KEYWORD +75 86 TRANSACTION UNRESERVED_KEYWORD +== 009 +CALL transaction_test1(9, 'error') +-- +0 4 CALL UNRESERVED_KEYWORD +5 22 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 24 ICONST NO_KEYWORD +24 25 ASCII_44 NO_KEYWORD +26 33 SCONST NO_KEYWORD +33 34 ASCII_41 NO_KEYWORD +== 010 +COMMIT +-- +0 6 COMMIT UNRESERVED_KEYWORD +== 011 +START TRANSACTION +-- +0 5 START UNRESERVED_KEYWORD +6 17 TRANSACTION UNRESERVED_KEYWORD +== 012 +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 43 SCONST NO_KEYWORD +== 013 +COMMIT +-- +0 6 COMMIT UNRESERVED_KEYWORD +== 014 +TRUNCATE test1 +-- +0 8 TRUNCATE UNRESERVED_KEYWORD +9 14 IDENT NO_KEYWORD +== 015 +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +-- +0 28 SQL_COMMENT NO_KEYWORD +29 35 CREATE RESERVED_KEYWORD +36 44 FUNCTION UNRESERVED_KEYWORD +45 62 IDENT NO_KEYWORD +62 63 ASCII_40 NO_KEYWORD +63 64 ASCII_41 NO_KEYWORD +65 72 RETURNS UNRESERVED_KEYWORD +73 76 INT_P COL_NAME_KEYWORD +77 85 LANGUAGE UNRESERVED_KEYWORD +86 93 IDENT NO_KEYWORD +94 96 AS RESERVED_KEYWORD +97 302 SCONST NO_KEYWORD +== 016 +SELECT transaction_test2() +-- +0 6 SELECT RESERVED_KEYWORD +7 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 017 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 018 +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +-- +0 58 SQL_COMMENT NO_KEYWORD +59 65 CREATE RESERVED_KEYWORD +66 74 FUNCTION UNRESERVED_KEYWORD +75 92 IDENT NO_KEYWORD +92 93 ASCII_40 NO_KEYWORD +93 94 ASCII_41 NO_KEYWORD +95 102 RETURNS UNRESERVED_KEYWORD +103 106 INT_P COL_NAME_KEYWORD +107 115 LANGUAGE UNRESERVED_KEYWORD +116 123 IDENT NO_KEYWORD +124 126 AS RESERVED_KEYWORD +127 197 SCONST NO_KEYWORD +== 019 +SELECT transaction_test3() +-- +0 6 SELECT RESERVED_KEYWORD +7 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 020 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 021 +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +-- +0 27 SQL_COMMENT NO_KEYWORD +28 34 CREATE RESERVED_KEYWORD +35 43 FUNCTION UNRESERVED_KEYWORD +44 61 IDENT NO_KEYWORD +61 62 ASCII_40 NO_KEYWORD +62 63 ASCII_41 NO_KEYWORD +64 71 RETURNS UNRESERVED_KEYWORD +72 75 INT_P COL_NAME_KEYWORD +76 84 LANGUAGE UNRESERVED_KEYWORD +85 92 IDENT NO_KEYWORD +93 95 AS RESERVED_KEYWORD +96 187 SCONST NO_KEYWORD +== 022 +SELECT transaction_test4() +-- +0 6 SELECT RESERVED_KEYWORD +7 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 023 +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = 555 +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +0 63 SQL_COMMENT NO_KEYWORD +64 70 CREATE RESERVED_KEYWORD +71 80 PROCEDURE UNRESERVED_KEYWORD +81 98 IDENT NO_KEYWORD +98 99 ASCII_40 NO_KEYWORD +99 100 ASCII_41 NO_KEYWORD +101 109 LANGUAGE UNRESERVED_KEYWORD +110 117 IDENT NO_KEYWORD +118 121 SET UNRESERVED_KEYWORD +122 130 IDENT NO_KEYWORD +131 132 ASCII_61 NO_KEYWORD +133 136 ICONST NO_KEYWORD +137 139 AS RESERVED_KEYWORD +140 168 SCONST NO_KEYWORD +== 024 +CALL transaction_test5() +-- +0 4 CALL UNRESERVED_KEYWORD +5 22 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 025 +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +0 61 SQL_COMMENT NO_KEYWORD +62 68 CREATE RESERVED_KEYWORD +69 78 PROCEDURE UNRESERVED_KEYWORD +79 97 IDENT NO_KEYWORD +97 98 ASCII_40 NO_KEYWORD +98 99 ASCII_41 NO_KEYWORD +100 108 LANGUAGE UNRESERVED_KEYWORD +109 116 IDENT NO_KEYWORD +117 125 SECURITY UNRESERVED_KEYWORD +126 133 DEFINER UNRESERVED_KEYWORD +134 136 AS RESERVED_KEYWORD +137 165 SCONST NO_KEYWORD +== 026 +CALL transaction_test5b() +-- +0 4 CALL UNRESERVED_KEYWORD +5 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ASCII_41 NO_KEYWORD +== 027 +TRUNCATE test1 +-- +0 8 TRUNCATE UNRESERVED_KEYWORD +9 14 IDENT NO_KEYWORD +== 028 +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +-- +0 25 SQL_COMMENT NO_KEYWORD +26 32 CREATE RESERVED_KEYWORD +33 42 PROCEDURE UNRESERVED_KEYWORD +43 60 IDENT NO_KEYWORD +60 61 ASCII_40 NO_KEYWORD +61 62 IDENT NO_KEYWORD +63 67 TEXT_P UNRESERVED_KEYWORD +67 68 ASCII_41 NO_KEYWORD +69 77 LANGUAGE UNRESERVED_KEYWORD +78 85 IDENT NO_KEYWORD +86 88 AS RESERVED_KEYWORD +89 139 SCONST NO_KEYWORD +== 029 +CALL transaction_test6('bar') +-- +0 4 CALL UNRESERVED_KEYWORD +5 22 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 28 SCONST NO_KEYWORD +28 29 ASCII_41 NO_KEYWORD +== 030 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 031 +TRUNCATE test1 +-- +0 8 TRUNCATE UNRESERVED_KEYWORD +9 14 IDENT NO_KEYWORD +== 032 +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +37 45 LANGUAGE UNRESERVED_KEYWORD +46 53 IDENT NO_KEYWORD +54 56 AS RESERVED_KEYWORD +57 132 SCONST NO_KEYWORD +== 033 +CALL transaction_test7() +-- +0 4 CALL UNRESERVED_KEYWORD +5 22 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 034 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 035 +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +37 45 LANGUAGE UNRESERVED_KEYWORD +46 53 IDENT NO_KEYWORD +54 56 AS RESERVED_KEYWORD +57 126 SCONST NO_KEYWORD +== 036 +CALL transaction_test8() +-- +0 4 CALL UNRESERVED_KEYWORD +5 22 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 24 ASCII_41 NO_KEYWORD +== 037 +-- commit inside cursor loop +CREATE TABLE test2 (x int) +-- +0 28 SQL_COMMENT NO_KEYWORD +29 35 CREATE RESERVED_KEYWORD +36 41 TABLE RESERVED_KEYWORD +42 47 IDENT NO_KEYWORD +48 49 ASCII_40 NO_KEYWORD +49 50 IDENT NO_KEYWORD +51 54 INT_P COL_NAME_KEYWORD +54 55 ASCII_41 NO_KEYWORD +== 038 +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 17 IDENT NO_KEYWORD +18 24 VALUES COL_NAME_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +28 29 ASCII_44 NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +33 34 ASCII_44 NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 37 ICONST NO_KEYWORD +37 38 ASCII_41 NO_KEYWORD +38 39 ASCII_44 NO_KEYWORD +40 41 ASCII_40 NO_KEYWORD +41 42 ICONST NO_KEYWORD +42 43 ASCII_41 NO_KEYWORD +43 44 ASCII_44 NO_KEYWORD +45 46 ASCII_40 NO_KEYWORD +46 47 ICONST NO_KEYWORD +47 48 ASCII_41 NO_KEYWORD +== 039 +TRUNCATE test1 +-- +0 8 TRUNCATE UNRESERVED_KEYWORD +9 14 IDENT NO_KEYWORD +== 040 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 181 SCONST NO_KEYWORD +== 041 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 042 +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +-- +0 49 SQL_COMMENT NO_KEYWORD +50 56 SELECT RESERVED_KEYWORD +57 58 ASCII_42 NO_KEYWORD +59 63 FROM RESERVED_KEYWORD +64 74 IDENT NO_KEYWORD +== 043 +-- error in cursor loop with commit +TRUNCATE test1 +-- +0 35 SQL_COMMENT NO_KEYWORD +36 44 TRUNCATE UNRESERVED_KEYWORD +45 50 IDENT NO_KEYWORD +== 044 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 188 SCONST NO_KEYWORD +== 045 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 046 +SELECT * FROM pg_cursors +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 24 IDENT NO_KEYWORD +== 047 +-- rollback inside cursor loop +TRUNCATE test1 +-- +0 30 SQL_COMMENT NO_KEYWORD +31 39 TRUNCATE UNRESERVED_KEYWORD +40 45 IDENT NO_KEYWORD +== 048 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 183 SCONST NO_KEYWORD +== 049 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 050 +SELECT * FROM pg_cursors +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 24 IDENT NO_KEYWORD +== 051 +-- first commit then rollback inside cursor loop +TRUNCATE test1 +-- +0 48 SQL_COMMENT NO_KEYWORD +49 57 TRUNCATE UNRESERVED_KEYWORD +58 63 IDENT NO_KEYWORD +== 052 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 264 SCONST NO_KEYWORD +== 053 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 054 +SELECT * FROM pg_cursors +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 24 IDENT NO_KEYWORD +== 055 +-- rollback inside cursor loop +TRUNCATE test1 +-- +0 30 SQL_COMMENT NO_KEYWORD +31 39 TRUNCATE UNRESERVED_KEYWORD +40 45 IDENT NO_KEYWORD +== 056 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 191 SCONST NO_KEYWORD +== 057 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 058 +SELECT * FROM test2 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 059 +SELECT * FROM pg_cursors +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 24 IDENT NO_KEYWORD +== 060 +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +-- +0 72 SQL_COMMENT NO_KEYWORD +73 81 TRUNCATE UNRESERVED_KEYWORD +82 87 IDENT NO_KEYWORD +== 061 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 17 IDENT NO_KEYWORD +18 24 VALUES COL_NAME_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_44 NO_KEYWORD +28 33 SCONST NO_KEYWORD +33 34 ASCII_41 NO_KEYWORD +34 35 ASCII_44 NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 ICONST NO_KEYWORD +38 39 ASCII_44 NO_KEYWORD +39 44 SCONST NO_KEYWORD +44 45 ASCII_41 NO_KEYWORD +45 46 ASCII_44 NO_KEYWORD +47 48 ASCII_40 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 57 SCONST NO_KEYWORD +57 58 ASCII_41 NO_KEYWORD +== 062 +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 216 SCONST NO_KEYWORD +== 063 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 064 +SELECT * FROM pg_cursors +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 24 IDENT NO_KEYWORD +== 065 +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +-- +0 44 SQL_COMMENT NO_KEYWORD +45 53 TRUNCATE UNRESERVED_KEYWORD +54 59 IDENT NO_KEYWORD +== 066 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 17 IDENT NO_KEYWORD +18 24 VALUES COL_NAME_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_44 NO_KEYWORD +28 33 SCONST NO_KEYWORD +33 34 ASCII_41 NO_KEYWORD +34 35 ASCII_44 NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 38 ICONST NO_KEYWORD +38 39 ASCII_44 NO_KEYWORD +39 44 SCONST NO_KEYWORD +44 45 ASCII_41 NO_KEYWORD +45 46 ASCII_44 NO_KEYWORD +47 48 ASCII_40 NO_KEYWORD +48 49 ICONST NO_KEYWORD +49 50 ASCII_44 NO_KEYWORD +50 57 SCONST NO_KEYWORD +57 58 ASCII_41 NO_KEYWORD +== 067 +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 187 SCONST NO_KEYWORD +== 068 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 069 +SELECT * FROM pg_cursors +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 24 IDENT NO_KEYWORD +== 070 +-- commit inside block with exception handler +TRUNCATE test1 +-- +0 45 SQL_COMMENT NO_KEYWORD +46 54 TRUNCATE UNRESERVED_KEYWORD +55 60 IDENT NO_KEYWORD +== 071 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 274 SCONST NO_KEYWORD +== 072 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 073 +-- rollback inside block with exception handler +TRUNCATE test1 +-- +0 47 SQL_COMMENT NO_KEYWORD +48 56 TRUNCATE UNRESERVED_KEYWORD +57 62 IDENT NO_KEYWORD +== 074 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 278 SCONST NO_KEYWORD +== 075 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 076 +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +-- +0 53 SQL_COMMENT NO_KEYWORD +54 62 TRUNCATE UNRESERVED_KEYWORD +63 68 IDENT NO_KEYWORD +== 077 +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 359 SCONST NO_KEYWORD +== 078 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 079 +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +-- +0 51 SQL_COMMENT NO_KEYWORD +52 58 CREATE RESERVED_KEYWORD +59 63 TEMP UNRESERVED_KEYWORD +64 69 TABLE RESERVED_KEYWORD +70 75 IDENT NO_KEYWORD +75 76 ASCII_40 NO_KEYWORD +76 78 IDENT NO_KEYWORD +79 83 TEXT_P UNRESERVED_KEYWORD +83 84 ASCII_41 NO_KEYWORD +== 080 +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +-- +0 5 ALTER UNRESERVED_KEYWORD +6 11 TABLE RESERVED_KEYWORD +12 17 IDENT NO_KEYWORD +18 23 ALTER UNRESERVED_KEYWORD +24 30 COLUMN RESERVED_KEYWORD +31 33 IDENT NO_KEYWORD +34 37 SET UNRESERVED_KEYWORD +38 45 STORAGE UNRESERVED_KEYWORD +46 54 EXTERNAL UNRESERVED_KEYWORD +== 081 +-- disable compression +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +-- +0 22 SQL_COMMENT NO_KEYWORD +23 29 INSERT UNRESERVED_KEYWORD +30 34 INTO RESERVED_KEYWORD +35 40 IDENT NO_KEYWORD +41 47 SELECT RESERVED_KEYWORD +48 54 IDENT NO_KEYWORD +54 55 ASCII_40 NO_KEYWORD +55 62 SCONST NO_KEYWORD +62 63 ASCII_44 NO_KEYWORD +64 68 ICONST NO_KEYWORD +68 69 ASCII_41 NO_KEYWORD +== 082 +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS 'select f1 from test4' IMMUTABLE +-- +0 77 SQL_COMMENT NO_KEYWORD +78 119 SQL_COMMENT NO_KEYWORD +120 126 CREATE RESERVED_KEYWORD +127 135 FUNCTION UNRESERVED_KEYWORD +136 147 IDENT NO_KEYWORD +147 148 ASCII_40 NO_KEYWORD +148 149 IDENT NO_KEYWORD +150 153 INT_P COL_NAME_KEYWORD +153 154 ASCII_41 NO_KEYWORD +155 162 RETURNS UNRESERVED_KEYWORD +163 167 TEXT_P UNRESERVED_KEYWORD +168 176 LANGUAGE UNRESERVED_KEYWORD +177 180 SQL_P UNRESERVED_KEYWORD +181 183 AS RESERVED_KEYWORD +184 206 SCONST NO_KEYWORD +207 216 IMMUTABLE UNRESERVED_KEYWORD +== 083 +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +-- +0 2 DO RESERVED_KEYWORD +3 147 SCONST NO_KEYWORD +== 084 +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +-- +0 58 SQL_COMMENT NO_KEYWORD +59 61 DO RESERVED_KEYWORD +62 70 LANGUAGE UNRESERVED_KEYWORD +71 78 IDENT NO_KEYWORD +79 337 SCONST NO_KEYWORD +== 085 +-- COMMIT failures +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +-- +0 18 SQL_COMMENT NO_KEYWORD +19 21 DO RESERVED_KEYWORD +22 30 LANGUAGE UNRESERVED_KEYWORD +31 38 IDENT NO_KEYWORD +39 331 SCONST NO_KEYWORD +== 086 +SELECT * FROM test3 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 087 +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +-- +0 77 SQL_COMMENT NO_KEYWORD +78 84 CREATE RESERVED_KEYWORD +85 94 PROCEDURE UNRESERVED_KEYWORD +95 120 IDENT NO_KEYWORD +120 121 ASCII_40 NO_KEYWORD +121 122 ASCII_41 NO_KEYWORD +124 132 LANGUAGE UNRESERVED_KEYWORD +133 140 IDENT NO_KEYWORD +141 143 AS RESERVED_KEYWORD +144 318 SCONST NO_KEYWORD +== 088 +TRUNCATE test1 +-- +0 8 TRUNCATE UNRESERVED_KEYWORD +9 14 IDENT NO_KEYWORD +== 089 +CALL cursor_fail_during_commit() +-- +0 4 CALL UNRESERVED_KEYWORD +5 30 IDENT NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 32 ASCII_41 NO_KEYWORD +== 090 +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +-- +0 72 SQL_COMMENT NO_KEYWORD +73 79 SELECT RESERVED_KEYWORD +80 85 IDENT NO_KEYWORD +85 86 ASCII_40 NO_KEYWORD +86 87 ASCII_42 NO_KEYWORD +87 88 ASCII_41 NO_KEYWORD +89 93 FROM RESERVED_KEYWORD +94 99 IDENT NO_KEYWORD +== 091 +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 44 IDENT NO_KEYWORD +44 45 ASCII_40 NO_KEYWORD +45 46 ASCII_41 NO_KEYWORD +48 56 LANGUAGE UNRESERVED_KEYWORD +57 64 IDENT NO_KEYWORD +65 67 AS RESERVED_KEYWORD +68 244 SCONST NO_KEYWORD +== 092 +TRUNCATE test1 +-- +0 8 TRUNCATE UNRESERVED_KEYWORD +9 14 IDENT NO_KEYWORD +== 093 +CALL cursor_fail_during_rollback() +-- +0 4 CALL UNRESERVED_KEYWORD +5 32 IDENT NO_KEYWORD +32 33 ASCII_40 NO_KEYWORD +33 34 ASCII_41 NO_KEYWORD +== 094 +SELECT count(*) FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 12 IDENT NO_KEYWORD +12 13 ASCII_40 NO_KEYWORD +13 14 ASCII_42 NO_KEYWORD +14 15 ASCII_41 NO_KEYWORD +16 20 FROM RESERVED_KEYWORD +21 26 IDENT NO_KEYWORD +== 095 +-- SET TRANSACTION +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +-- +0 18 SQL_COMMENT NO_KEYWORD +19 21 DO RESERVED_KEYWORD +22 30 LANGUAGE UNRESERVED_KEYWORD +31 38 IDENT NO_KEYWORD +39 425 SCONST NO_KEYWORD +== 096 +-- error cases +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +-- +0 14 SQL_COMMENT NO_KEYWORD +15 17 DO RESERVED_KEYWORD +18 26 LANGUAGE UNRESERVED_KEYWORD +27 34 IDENT NO_KEYWORD +35 104 SCONST NO_KEYWORD +== 097 +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 55 SCONST NO_KEYWORD +== 098 +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 58 SCONST NO_KEYWORD +== 099 +-- snapshot handling test +TRUNCATE test2 +-- +0 25 SQL_COMMENT NO_KEYWORD +26 34 TRUNCATE UNRESERVED_KEYWORD +35 40 IDENT NO_KEYWORD +== 100 +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +37 45 LANGUAGE UNRESERVED_KEYWORD +46 49 SQL_P UNRESERVED_KEYWORD +50 52 AS RESERVED_KEYWORD +53 89 SCONST NO_KEYWORD +== 101 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 75 SCONST NO_KEYWORD +== 102 +SELECT * FROM test2 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 103 +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $$ SELECT COUNT(*) FROM test2 $$ +-- +0 70 SQL_COMMENT NO_KEYWORD +71 117 SQL_COMMENT NO_KEYWORD +118 124 CREATE RESERVED_KEYWORD +125 133 FUNCTION UNRESERVED_KEYWORD +134 146 IDENT NO_KEYWORD +146 147 ASCII_40 NO_KEYWORD +147 148 ASCII_41 NO_KEYWORD +149 156 RETURNS UNRESERVED_KEYWORD +157 160 INT_P COL_NAME_KEYWORD +161 167 STABLE UNRESERVED_KEYWORD +168 176 LANGUAGE UNRESERVED_KEYWORD +177 180 SQL_P UNRESERVED_KEYWORD +181 183 AS RESERVED_KEYWORD +184 216 SCONST NO_KEYWORD +== 104 +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 35 IDENT NO_KEYWORD +35 36 ASCII_40 NO_KEYWORD +36 39 IDENT NO_KEYWORD +40 43 INT_P COL_NAME_KEYWORD +43 44 ASCII_41 NO_KEYWORD +45 53 LANGUAGE UNRESERVED_KEYWORD +54 61 IDENT NO_KEYWORD +62 64 AS RESERVED_KEYWORD +65 113 SCONST NO_KEYWORD +== 105 +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 142 SCONST NO_KEYWORD +== 106 +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +-- +0 69 SQL_COMMENT NO_KEYWORD +70 136 SQL_COMMENT NO_KEYWORD +137 143 CREATE RESERVED_KEYWORD +144 153 PROCEDURE UNRESERVED_KEYWORD +154 173 IDENT NO_KEYWORD +173 174 ASCII_40 NO_KEYWORD +174 179 INOUT COL_NAME_KEYWORD +180 181 IDENT NO_KEYWORD +182 185 INT_P COL_NAME_KEYWORD +185 186 ASCII_41 NO_KEYWORD +187 195 LANGUAGE UNRESERVED_KEYWORD +196 203 IDENT NO_KEYWORD +204 206 AS RESERVED_KEYWORD +207 247 SCONST NO_KEYWORD +== 107 +CALL transaction_test10a(10) +-- +0 4 CALL UNRESERVED_KEYWORD +5 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +== 108 +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 16 PROCEDURE UNRESERVED_KEYWORD +17 36 IDENT NO_KEYWORD +36 37 ASCII_40 NO_KEYWORD +37 42 INOUT COL_NAME_KEYWORD +43 44 IDENT NO_KEYWORD +45 48 INT_P COL_NAME_KEYWORD +48 49 ASCII_41 NO_KEYWORD +50 58 LANGUAGE UNRESERVED_KEYWORD +59 66 IDENT NO_KEYWORD +67 69 AS RESERVED_KEYWORD +70 112 SCONST NO_KEYWORD +== 109 +CALL transaction_test10b(10) +-- +0 4 CALL UNRESERVED_KEYWORD +5 24 IDENT NO_KEYWORD +24 25 ASCII_40 NO_KEYWORD +25 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +== 110 +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +-- +0 48 SQL_COMMENT NO_KEYWORD +49 55 CREATE RESERVED_KEYWORD +56 65 PROCEDURE UNRESERVED_KEYWORD +66 84 IDENT NO_KEYWORD +84 85 ASCII_40 NO_KEYWORD +85 86 ASCII_41 NO_KEYWORD +87 95 LANGUAGE UNRESERVED_KEYWORD +96 103 IDENT NO_KEYWORD +104 106 AS RESERVED_KEYWORD +107 675 SCONST NO_KEYWORD +== 111 +CALL transaction_test11() +-- +0 4 CALL UNRESERVED_KEYWORD +5 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ASCII_41 NO_KEYWORD +== 112 +-- transaction chain + +TRUNCATE test1 +-- +0 20 SQL_COMMENT NO_KEYWORD +22 30 TRUNCATE UNRESERVED_KEYWORD +31 36 IDENT NO_KEYWORD +== 113 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +-- +0 2 DO RESERVED_KEYWORD +3 11 LANGUAGE UNRESERVED_KEYWORD +12 19 IDENT NO_KEYWORD +20 388 SCONST NO_KEYWORD +== 114 +SELECT * FROM test1 +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 19 IDENT NO_KEYWORD +== 115 +DROP TABLE test1 +-- +0 4 DROP UNRESERVED_KEYWORD +5 10 TABLE RESERVED_KEYWORD +11 16 IDENT NO_KEYWORD +== 116 +DROP TABLE test2 +-- +0 4 DROP UNRESERVED_KEYWORD +5 10 TABLE RESERVED_KEYWORD +11 16 IDENT NO_KEYWORD +== 117 +DROP TABLE test3 +-- +0 4 DROP UNRESERVED_KEYWORD +5 10 TABLE RESERVED_KEYWORD +11 16 IDENT NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_trap.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_trap.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_trap.test b/parser/testdata/scan/plpgsql_regress/plpgsql_trap.test new file mode 100644 index 0000000..8d0a560 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_trap.test @@ -0,0 +1,531 @@ +== 001 +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +0 2 SQL_COMMENT NO_KEYWORD +3 25 SQL_COMMENT NO_KEYWORD +26 28 SQL_COMMENT NO_KEYWORD +30 36 CREATE RESERVED_KEYWORD +37 45 FUNCTION UNRESERVED_KEYWORD +46 62 IDENT NO_KEYWORD +62 63 ASCII_40 NO_KEYWORD +63 66 INT_P COL_NAME_KEYWORD +66 67 ASCII_41 NO_KEYWORD +68 75 RETURNS UNRESERVED_KEYWORD +76 79 INT_P COL_NAME_KEYWORD +80 82 AS RESERVED_KEYWORD +83 629 SCONST NO_KEYWORD +630 638 LANGUAGE UNRESERVED_KEYWORD +639 646 IDENT NO_KEYWORD +== 002 +select trap_zero_divide(50) +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 26 ICONST NO_KEYWORD +26 27 ASCII_41 NO_KEYWORD +== 003 +select trap_zero_divide(0) +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ICONST NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 004 +select trap_zero_divide(100000) +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 30 ICONST NO_KEYWORD +30 31 ASCII_41 NO_KEYWORD +== 005 +select trap_zero_divide(-100) +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ASCII_45 NO_KEYWORD +25 28 ICONST NO_KEYWORD +28 29 ASCII_41 NO_KEYWORD +== 006 +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +-- +0 6 CREATE RESERVED_KEYWORD +7 12 TABLE RESERVED_KEYWORD +13 25 IDENT NO_KEYWORD +26 28 AS RESERVED_KEYWORD +31 37 SELECT RESERVED_KEYWORD +38 39 IDENT NO_KEYWORD +40 42 AS RESERVED_KEYWORD +43 45 IDENT NO_KEYWORD +45 46 ASCII_44 NO_KEYWORD +47 48 IDENT NO_KEYWORD +48 49 ASCII_42 NO_KEYWORD +49 51 ICONST NO_KEYWORD +52 54 AS RESERVED_KEYWORD +55 59 DATA_P UNRESERVED_KEYWORD +59 60 ASCII_44 NO_KEYWORD +61 62 IDENT NO_KEYWORD +62 63 ASCII_47 NO_KEYWORD +63 65 ICONST NO_KEYWORD +66 68 AS RESERVED_KEYWORD +69 72 IDENT NO_KEYWORD +73 77 FROM RESERVED_KEYWORD +78 93 IDENT NO_KEYWORD +93 94 ASCII_40 NO_KEYWORD +94 95 ICONST NO_KEYWORD +95 96 ASCII_44 NO_KEYWORD +96 99 ICONST NO_KEYWORD +99 100 ASCII_41 NO_KEYWORD +101 102 IDENT NO_KEYWORD +== 007 +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 38 INT_P COL_NAME_KEYWORD +38 39 ASCII_41 NO_KEYWORD +40 47 RETURNS UNRESERVED_KEYWORD +48 51 INT_P COL_NAME_KEYWORD +52 54 AS RESERVED_KEYWORD +55 550 SCONST NO_KEYWORD +551 559 LANGUAGE UNRESERVED_KEYWORD +560 567 IDENT NO_KEYWORD +== 008 +select trap_matching_test(50) +-- +0 6 SELECT RESERVED_KEYWORD +7 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 28 ICONST NO_KEYWORD +28 29 ASCII_41 NO_KEYWORD +== 009 +select trap_matching_test(0) +-- +0 6 SELECT RESERVED_KEYWORD +7 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +== 010 +select trap_matching_test(100000) +-- +0 6 SELECT RESERVED_KEYWORD +7 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 32 ICONST NO_KEYWORD +32 33 ASCII_41 NO_KEYWORD +== 011 +select trap_matching_test(1) +-- +0 6 SELECT RESERVED_KEYWORD +7 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ICONST NO_KEYWORD +27 28 ASCII_41 NO_KEYWORD +== 012 +create temp table foo (f1 int) +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TEMP UNRESERVED_KEYWORD +12 17 TABLE RESERVED_KEYWORD +18 21 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 25 IDENT NO_KEYWORD +26 29 INT_P COL_NAME_KEYWORD +29 30 ASCII_41 NO_KEYWORD +== 013 +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 42 IDENT NO_KEYWORD +42 43 ASCII_40 NO_KEYWORD +43 44 ASCII_41 NO_KEYWORD +45 52 RETURNS UNRESERVED_KEYWORD +53 56 INT_P COL_NAME_KEYWORD +57 59 AS RESERVED_KEYWORD +60 312 SCONST NO_KEYWORD +313 321 LANGUAGE UNRESERVED_KEYWORD +322 329 IDENT NO_KEYWORD +== 014 +select subxact_rollback_semantics() +-- +0 6 SELECT RESERVED_KEYWORD +7 33 IDENT NO_KEYWORD +33 34 ASCII_40 NO_KEYWORD +34 35 ASCII_41 NO_KEYWORD +== 015 +select * from foo +-- +0 6 SELECT RESERVED_KEYWORD +7 8 ASCII_42 NO_KEYWORD +9 13 FROM RESERVED_KEYWORD +14 17 IDENT NO_KEYWORD +== 016 +drop table foo +-- +0 4 DROP UNRESERVED_KEYWORD +5 10 TABLE RESERVED_KEYWORD +11 14 IDENT NO_KEYWORD +== 017 +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ASCII_41 NO_KEYWORD +31 38 RETURNS UNRESERVED_KEYWORD +39 43 IDENT NO_KEYWORD +44 46 AS RESERVED_KEYWORD +47 551 SCONST NO_KEYWORD +552 560 LANGUAGE UNRESERVED_KEYWORD +561 568 IDENT NO_KEYWORD +== 018 +begin +-- +0 5 BEGIN_P UNRESERVED_KEYWORD +== 019 +set statement_timeout to 1000 +-- +0 3 SET UNRESERVED_KEYWORD +4 21 IDENT NO_KEYWORD +22 24 TO RESERVED_KEYWORD +25 29 ICONST NO_KEYWORD +== 020 +select trap_timeout() +-- +0 6 SELECT RESERVED_KEYWORD +7 19 IDENT NO_KEYWORD +19 20 ASCII_40 NO_KEYWORD +20 21 ASCII_41 NO_KEYWORD +== 021 +rollback +-- +0 8 ROLLBACK UNRESERVED_KEYWORD +== 022 +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql +-- +0 61 SQL_COMMENT NO_KEYWORD +62 68 CREATE RESERVED_KEYWORD +69 77 FUNCTION UNRESERVED_KEYWORD +78 99 IDENT NO_KEYWORD +99 100 ASCII_40 NO_KEYWORD +100 101 ASCII_41 NO_KEYWORD +102 109 RETURNS UNRESERVED_KEYWORD +110 114 TEXT_P UNRESERVED_KEYWORD +115 117 AS RESERVED_KEYWORD +118 358 SCONST NO_KEYWORD +359 367 LANGUAGE UNRESERVED_KEYWORD +368 375 IDENT NO_KEYWORD +== 023 +select test_variable_storage() +-- +0 6 SELECT RESERVED_KEYWORD +7 28 IDENT NO_KEYWORD +28 29 ASCII_40 NO_KEYWORD +29 30 ASCII_41 NO_KEYWORD +== 024 +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 37 SQL_COMMENT NO_KEYWORD +38 40 SQL_COMMENT NO_KEYWORD +42 48 CREATE RESERVED_KEYWORD +49 53 TEMP UNRESERVED_KEYWORD +54 59 TABLE RESERVED_KEYWORD +60 64 IDENT NO_KEYWORD +64 65 ASCII_40 NO_KEYWORD +65 67 IDENT NO_KEYWORD +68 71 INT_P COL_NAME_KEYWORD +72 79 PRIMARY RESERVED_KEYWORD +80 83 KEY UNRESERVED_KEYWORD +83 84 ASCII_41 NO_KEYWORD +== 025 +create temp table leaf(f1 int references root deferrable) +-- +0 6 CREATE RESERVED_KEYWORD +7 11 TEMP UNRESERVED_KEYWORD +12 17 TABLE RESERVED_KEYWORD +18 22 IDENT NO_KEYWORD +22 23 ASCII_40 NO_KEYWORD +23 25 IDENT NO_KEYWORD +26 29 INT_P COL_NAME_KEYWORD +30 40 REFERENCES RESERVED_KEYWORD +41 45 IDENT NO_KEYWORD +46 56 DEFERRABLE RESERVED_KEYWORD +56 57 ASCII_41 NO_KEYWORD +== 026 +insert into root values(1) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 16 IDENT NO_KEYWORD +17 23 VALUES COL_NAME_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ICONST NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 027 +insert into leaf values(1) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 16 IDENT NO_KEYWORD +17 23 VALUES COL_NAME_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ICONST NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 028 +insert into leaf values(2) +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 16 IDENT NO_KEYWORD +17 23 VALUES COL_NAME_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ICONST NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 029 +-- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +0 8 SQL_COMMENT NO_KEYWORD +10 16 CREATE RESERVED_KEYWORD +17 25 FUNCTION UNRESERVED_KEYWORD +26 42 IDENT NO_KEYWORD +42 43 ASCII_40 NO_KEYWORD +43 46 INT_P COL_NAME_KEYWORD +46 47 ASCII_41 NO_KEYWORD +48 55 RETURNS UNRESERVED_KEYWORD +56 59 INT_P COL_NAME_KEYWORD +60 62 AS RESERVED_KEYWORD +63 264 SCONST NO_KEYWORD +265 273 LANGUAGE UNRESERVED_KEYWORD +274 281 IDENT NO_KEYWORD +== 030 +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 34 IDENT NO_KEYWORD +34 35 ASCII_40 NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +37 44 RETURNS UNRESERVED_KEYWORD +45 48 INT_P COL_NAME_KEYWORD +49 51 AS RESERVED_KEYWORD +52 255 SCONST NO_KEYWORD +256 264 LANGUAGE UNRESERVED_KEYWORD +265 272 IDENT NO_KEYWORD +== 031 +select trap_foreign_key(1) +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ICONST NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 032 +select trap_foreign_key(2) +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ICONST NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 033 +-- detects FK violation + +begin +-- +0 23 SQL_COMMENT NO_KEYWORD +25 30 BEGIN_P UNRESERVED_KEYWORD +== 034 +set constraints all deferred +-- +0 3 SET UNRESERVED_KEYWORD +4 15 CONSTRAINTS UNRESERVED_KEYWORD +16 19 ALL RESERVED_KEYWORD +20 28 DEFERRED UNRESERVED_KEYWORD +== 035 +select trap_foreign_key(2) +-- +0 6 SELECT RESERVED_KEYWORD +7 23 IDENT NO_KEYWORD +23 24 ASCII_40 NO_KEYWORD +24 25 ICONST NO_KEYWORD +25 26 ASCII_41 NO_KEYWORD +== 036 +-- should not detect FK violation + savepoint x +-- +0 33 SQL_COMMENT NO_KEYWORD +36 45 SAVEPOINT UNRESERVED_KEYWORD +46 47 IDENT NO_KEYWORD +== 037 +set constraints all immediate +-- +0 3 SET UNRESERVED_KEYWORD +4 15 CONSTRAINTS UNRESERVED_KEYWORD +16 19 ALL RESERVED_KEYWORD +20 29 IMMEDIATE UNRESERVED_KEYWORD +== 038 +-- fails + rollback to x +-- +0 8 SQL_COMMENT NO_KEYWORD +11 19 ROLLBACK UNRESERVED_KEYWORD +20 22 TO RESERVED_KEYWORD +23 24 IDENT NO_KEYWORD +== 039 +select trap_foreign_key_2() +-- +0 6 SELECT RESERVED_KEYWORD +7 25 IDENT NO_KEYWORD +25 26 ASCII_40 NO_KEYWORD +26 27 ASCII_41 NO_KEYWORD +== 040 +-- detects FK violation +commit +-- +0 23 SQL_COMMENT NO_KEYWORD +24 30 COMMIT UNRESERVED_KEYWORD +== 041 +-- still fails + +drop function trap_foreign_key(int) +-- +0 14 SQL_COMMENT NO_KEYWORD +16 20 DROP UNRESERVED_KEYWORD +21 29 FUNCTION UNRESERVED_KEYWORD +30 46 IDENT NO_KEYWORD +46 47 ASCII_40 NO_KEYWORD +47 50 INT_P COL_NAME_KEYWORD +50 51 ASCII_41 NO_KEYWORD +== 042 +drop function trap_foreign_key_2() +-- +0 4 DROP UNRESERVED_KEYWORD +5 13 FUNCTION UNRESERVED_KEYWORD +14 32 IDENT NO_KEYWORD +32 33 ASCII_40 NO_KEYWORD +33 34 ASCII_41 NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_trigger.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_trigger.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_trigger.test b/parser/testdata/scan/plpgsql_regress/plpgsql_trigger.test new file mode 100644 index 0000000..8987a1d --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_trigger.test @@ -0,0 +1,98 @@ +== 001 +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +-- +0 75 SQL_COMMENT NO_KEYWORD +77 83 CREATE RESERVED_KEYWORD +84 89 TABLE RESERVED_KEYWORD +90 96 IDENT NO_KEYWORD +97 98 ASCII_40 NO_KEYWORD +98 99 IDENT NO_KEYWORD +100 103 INT_P COL_NAME_KEYWORD +103 104 ASCII_44 NO_KEYWORD +105 106 IDENT NO_KEYWORD +107 111 TEXT_P UNRESERVED_KEYWORD +111 112 ASCII_41 NO_KEYWORD +== 002 +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +-- +0 6 CREATE RESERVED_KEYWORD +7 15 FUNCTION UNRESERVED_KEYWORD +16 30 IDENT NO_KEYWORD +30 31 ASCII_40 NO_KEYWORD +31 32 ASCII_41 NO_KEYWORD +33 40 RETURNS UNRESERVED_KEYWORD +41 48 TRIGGER UNRESERVED_KEYWORD +49 57 LANGUAGE UNRESERVED_KEYWORD +58 65 IDENT NO_KEYWORD +66 68 AS RESERVED_KEYWORD +69 291 SCONST NO_KEYWORD +== 003 +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +-- +0 6 CREATE RESERVED_KEYWORD +7 14 TRIGGER UNRESERVED_KEYWORD +15 29 IDENT NO_KEYWORD +30 36 BEFORE UNRESERVED_KEYWORD +37 43 INSERT UNRESERVED_KEYWORD +44 46 OR RESERVED_KEYWORD +47 53 DELETE_P UNRESERVED_KEYWORD +54 56 OR RESERVED_KEYWORD +57 63 UPDATE UNRESERVED_KEYWORD +64 66 ON RESERVED_KEYWORD +67 73 IDENT NO_KEYWORD +76 79 FOR RESERVED_KEYWORD +80 84 EACH UNRESERVED_KEYWORD +85 88 ROW COL_NAME_KEYWORD +89 96 EXECUTE UNRESERVED_KEYWORD +97 105 FUNCTION UNRESERVED_KEYWORD +106 120 IDENT NO_KEYWORD +120 121 ASCII_40 NO_KEYWORD +121 122 ASCII_41 NO_KEYWORD +== 004 +insert into testtr values (1, 'one'), (2, 'two') +-- +0 6 INSERT UNRESERVED_KEYWORD +7 11 INTO RESERVED_KEYWORD +12 18 IDENT NO_KEYWORD +19 25 VALUES COL_NAME_KEYWORD +26 27 ASCII_40 NO_KEYWORD +27 28 ICONST NO_KEYWORD +28 29 ASCII_44 NO_KEYWORD +30 35 SCONST NO_KEYWORD +35 36 ASCII_41 NO_KEYWORD +36 37 ASCII_44 NO_KEYWORD +38 39 ASCII_40 NO_KEYWORD +39 40 ICONST NO_KEYWORD +40 41 ASCII_44 NO_KEYWORD +42 47 SCONST NO_KEYWORD +47 48 ASCII_41 NO_KEYWORD +== 005 +update testtr set a = a + 1 +-- +0 6 UPDATE UNRESERVED_KEYWORD +7 13 IDENT NO_KEYWORD +14 17 SET UNRESERVED_KEYWORD +18 19 IDENT NO_KEYWORD +20 21 ASCII_61 NO_KEYWORD +22 23 IDENT NO_KEYWORD +24 25 ASCII_43 NO_KEYWORD +26 27 ICONST NO_KEYWORD +== 006 +delete from testtr +-- +0 6 DELETE_P UNRESERVED_KEYWORD +7 11 FROM RESERVED_KEYWORD +12 18 IDENT NO_KEYWORD diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/scan/plpgsql_regress/plpgsql_varprops.metadata.json new file mode 100644 index 0000000..737fd31 --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_varprops.metadata.json @@ -0,0 +1,3 @@ +{ + "todo": [] +} diff --git a/parser/testdata/scan/plpgsql_regress/plpgsql_varprops.test b/parser/testdata/scan/plpgsql_regress/plpgsql_varprops.test new file mode 100644 index 0000000..70f17dd --- /dev/null +++ b/parser/testdata/scan/plpgsql_regress/plpgsql_varprops.test @@ -0,0 +1,403 @@ +== 001 +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +-- +0 2 SQL_COMMENT NO_KEYWORD +3 78 SQL_COMMENT NO_KEYWORD +79 81 SQL_COMMENT NO_KEYWORD +83 89 CREATE RESERVED_KEYWORD +90 94 TYPE_P UNRESERVED_KEYWORD +95 105 IDENT NO_KEYWORD +106 108 AS RESERVED_KEYWORD +109 110 ASCII_40 NO_KEYWORD +110 112 IDENT NO_KEYWORD +113 117 IDENT NO_KEYWORD +117 118 ASCII_44 NO_KEYWORD +119 121 IDENT NO_KEYWORD +122 126 IDENT NO_KEYWORD +126 127 ASCII_41 NO_KEYWORD +== 002 +create domain int_nn as int not null +-- +0 6 CREATE RESERVED_KEYWORD +7 13 DOMAIN_P UNRESERVED_KEYWORD +14 20 IDENT NO_KEYWORD +21 23 AS RESERVED_KEYWORD +24 27 INT_P COL_NAME_KEYWORD +28 31 NOT RESERVED_KEYWORD +32 36 NULL_P RESERVED_KEYWORD +== 003 +create domain var_record_nn as var_record not null +-- +0 6 CREATE RESERVED_KEYWORD +7 13 DOMAIN_P UNRESERVED_KEYWORD +14 27 IDENT NO_KEYWORD +28 30 AS RESERVED_KEYWORD +31 41 IDENT NO_KEYWORD +42 45 NOT RESERVED_KEYWORD +46 50 NULL_P RESERVED_KEYWORD +== 004 +create domain var_record_colnn as var_record check((value).f2 is not null) +-- +0 6 CREATE RESERVED_KEYWORD +7 13 DOMAIN_P UNRESERVED_KEYWORD +14 30 IDENT NO_KEYWORD +31 33 AS RESERVED_KEYWORD +34 44 IDENT NO_KEYWORD +45 50 CHECK RESERVED_KEYWORD +50 51 ASCII_40 NO_KEYWORD +51 52 ASCII_40 NO_KEYWORD +52 57 VALUE_P UNRESERVED_KEYWORD +57 58 ASCII_41 NO_KEYWORD +58 59 ASCII_46 NO_KEYWORD +59 61 IDENT NO_KEYWORD +62 64 IS TYPE_FUNC_NAME_KEYWORD +65 68 NOT RESERVED_KEYWORD +69 73 NULL_P RESERVED_KEYWORD +73 74 ASCII_41 NO_KEYWORD +== 005 +-- CONSTANT + +do $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +-- +0 11 SQL_COMMENT NO_KEYWORD +13 15 DO RESERVED_KEYWORD +16 87 SCONST NO_KEYWORD +== 006 +do $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 61 SCONST NO_KEYWORD +== 007 +do $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 100 SCONST NO_KEYWORD +== 008 +do $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 66 SCONST NO_KEYWORD +== 009 +do $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 137 SCONST NO_KEYWORD +== 010 +do $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 71 SCONST NO_KEYWORD +== 011 +do $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 110 SCONST NO_KEYWORD +== 012 +-- initializer expressions + +do $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +-- +0 26 SQL_COMMENT NO_KEYWORD +28 30 DO RESERVED_KEYWORD +31 97 SCONST NO_KEYWORD +== 013 +do $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 75 SCONST NO_KEYWORD +== 014 +do $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 80 SCONST NO_KEYWORD +== 015 +do $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 76 SCONST NO_KEYWORD +== 016 +do $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 78 SCONST NO_KEYWORD +== 017 +-- NOT NULL + +do $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 11 SQL_COMMENT NO_KEYWORD +13 15 DO RESERVED_KEYWORD +16 90 SCONST NO_KEYWORD +== 018 +do $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 96 SCONST NO_KEYWORD +== 019 +do $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 85 SCONST NO_KEYWORD +== 020 +do $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 80 SCONST NO_KEYWORD +== 021 +do $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 156 SCONST NO_KEYWORD +== 022 +do $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 88 SCONST NO_KEYWORD +== 023 +do $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 84 SCONST NO_KEYWORD +== 024 +do $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 168 SCONST NO_KEYWORD +== 025 +do $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 92 SCONST NO_KEYWORD +== 026 +-- Check that variables are reinitialized on block re-entry. + +do $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +-- +0 60 SQL_COMMENT NO_KEYWORD +62 64 DO RESERVED_KEYWORD +65 437 SCONST NO_KEYWORD +== 027 +-- Check enforcement of domain constraints during initialization + +do $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 64 SQL_COMMENT NO_KEYWORD +66 68 DO RESERVED_KEYWORD +69 137 SCONST NO_KEYWORD +== 028 +do $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 79 SCONST NO_KEYWORD +== 029 +do $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 90 SCONST NO_KEYWORD +== 030 +do $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 78 SCONST NO_KEYWORD +== 031 +do $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 86 SCONST NO_KEYWORD +== 032 +do $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 133 SCONST NO_KEYWORD +== 033 +do $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 81 SCONST NO_KEYWORD +== 034 +do $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 89 SCONST NO_KEYWORD +== 035 +do $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 96 SCONST NO_KEYWORD +== 036 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 106 SCONST NO_KEYWORD +== 037 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ +-- +0 2 DO RESERVED_KEYWORD +3 116 SCONST NO_KEYWORD diff --git a/parser/testdata/summary/libpg_query.metadata.json b/parser/testdata/summary/libpg_query.metadata.json new file mode 100644 index 0000000..59f8291 --- /dev/null +++ b/parser/testdata/summary/libpg_query.metadata.json @@ -0,0 +1,106 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102" + ] +} diff --git a/parser/testdata/summary/libpg_query.test b/parser/testdata/summary/libpg_query.test new file mode 100644 index 0000000..b6b7ce8 --- /dev/null +++ b/parser/testdata/summary/libpg_query.test @@ -0,0 +1,911 @@ +== 001 +SELECT * FROM test WHERE a = 1 +-- +TABLE: name="test" schema="" table="test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 002 +SELECT * FROM test AS x WHERE a = 1 +-- +TABLE: name="test" schema="" table="test" ctx=Select +ALIAS: "x"="test" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 003 +SELECT * FROM test WHERE col1 = (SELECT col2 FROM test2 WHERE col3 = 123) +-- +TABLE: name="test" schema="" table="test" ctx=Select +TABLE: name="test2" schema="" table="test2" ctx=Select +FILTER: schema="" table="" column="col1" +FILTER: schema="" table="" column="col3" +STMT: SelectStmt +== 004 +CREATE RANDOM ix_test ON contacts.person; +-- +ERROR: syntax error at or near "RANDOM" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +SELECT 'ERR +-- +ERROR: unterminated quoted string at or near "'ERR" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +SELECT * FROM "t0" +-- +TABLE: name="t0" schema="" table="t0" ctx=Select +STMT: SelectStmt +== 007 +SELECT * FROM "t0" JOIN "t1" ON (1) +-- +TABLE: name="t0" schema="" table="t0" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 008 +SELECT * FROM "t0" + JOIN "t1" ON (1) JOIN "t2" ON (1) JOIN "t3" ON (1) JOIN "t4" ON (1) JOIN "t5" ON (1) + JOIN "t6" ON (1) JOIN "t7" ON (1) JOIN "t8" ON (1) JOIN "t9" ON (1) JOIN "t10" ON (1) + JOIN "t11" ON (1) JOIN "t12" ON (1) JOIN "t13" ON (1) JOIN "t14" ON (1) JOIN "t15" ON (1) + JOIN "t16" ON (1) JOIN "t17" ON (1) JOIN "t18" ON (1) JOIN "t19" ON (1) JOIN "t20" ON (1) + JOIN "t21" ON (1) JOIN "t22" ON (1) JOIN "t23" ON (1) JOIN "t24" ON (1) JOIN "t25" ON (1) + JOIN "t26" ON (1) JOIN "t27" ON (1) JOIN "t28" ON (1) JOIN "t29" ON (1) +-- +TABLE: name="t0" schema="" table="t0" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +TABLE: name="t4" schema="" table="t4" ctx=Select +TABLE: name="t5" schema="" table="t5" ctx=Select +TABLE: name="t6" schema="" table="t6" ctx=Select +TABLE: name="t7" schema="" table="t7" ctx=Select +TABLE: name="t8" schema="" table="t8" ctx=Select +TABLE: name="t9" schema="" table="t9" ctx=Select +TABLE: name="t10" schema="" table="t10" ctx=Select +TABLE: name="t11" schema="" table="t11" ctx=Select +TABLE: name="t12" schema="" table="t12" ctx=Select +TABLE: name="t13" schema="" table="t13" ctx=Select +TABLE: name="t14" schema="" table="t14" ctx=Select +TABLE: name="t15" schema="" table="t15" ctx=Select +TABLE: name="t16" schema="" table="t16" ctx=Select +TABLE: name="t17" schema="" table="t17" ctx=Select +TABLE: name="t18" schema="" table="t18" ctx=Select +TABLE: name="t19" schema="" table="t19" ctx=Select +TABLE: name="t20" schema="" table="t20" ctx=Select +TABLE: name="t21" schema="" table="t21" ctx=Select +TABLE: name="t22" schema="" table="t22" ctx=Select +TABLE: name="t23" schema="" table="t23" ctx=Select +TABLE: name="t24" schema="" table="t24" ctx=Select +TABLE: name="t25" schema="" table="t25" ctx=Select +TABLE: name="t26" schema="" table="t26" ctx=Select +TABLE: name="t27" schema="" table="t27" ctx=Select +TABLE: name="t28" schema="" table="t28" ctx=Select +TABLE: name="t29" schema="" table="t29" ctx=Select +STMT: SelectStmt +== 009 + + SELECT memory_total_bytes, memory_free_bytes, memory_pagecache_bytes, memory_buffers_bytes, memory_applications_bytes, + (memory_swap_total_bytes - memory_swap_free_bytes) AS swap, date_part($0, s.collected_at) AS collected_at + FROM snapshots s JOIN system_snapshots ON (snapshot_id = s.id) + WHERE s.database_id = $0 AND s.collected_at BETWEEN $0 AND $0 + ORDER BY collected_at +-- +TABLE: name="snapshots" schema="" table="snapshots" ctx=Select +TABLE: name="system_snapshots" schema="" table="system_snapshots" ctx=Select +ALIAS: "s"="snapshots" +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FILTER: schema="" table="s" column="database_id" +FILTER: schema="" table="s" column="collected_at" +STMT: SelectStmt +== 010 +-- nothing +-- + +== 011 +SELECT .1 +-- +STMT: SelectStmt +== 012 +SELECT X'EFFF' +-- +STMT: SelectStmt +== 013 +ALTER TABLE test ADD PRIMARY KEY (gid) +-- +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: AlterTableStmt +== 014 +SET statement_timeout=1 +-- +STMT: VariableSetStmt +== 015 +SHOW work_mem +-- +STMT: VariableShowStmt +== 016 +COPY test (id) TO stdout +-- +TABLE: name="test" schema="" table="test" ctx=Select +STMT: CopyStmt +== 017 +drop table abc.test123 cascade +-- +TABLE: name="abc.test123" schema="abc" table="test123" ctx=DDL +STMT: DropStmt +== 018 +drop table abc.test123, test +-- +TABLE: name="abc.test123" schema="abc" table="test123" ctx=DDL +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: DropStmt +== 019 +COMMIT +-- +STMT: TransactionStmt +== 020 +CHECKPOINT +-- +STMT: CheckPointStmt +== 021 +VACUUM my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: VacuumStmt +== 022 +WITH cte AS (SELECT * FROM g.other_table CROSS JOIN p) MERGE INTO my_table USING cte ON (id=oid) WHEN MATCHED THEN UPDATE SET a=b WHEN NOT MATCHED THEN INSERT (id, a) VALUES (oid, b); +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +TABLE: name="g.other_table" schema="g" table="other_table" ctx=Select +TABLE: name="p" schema="" table="p" ctx=Select +CTE: "cte" +STMT: MergeStmt +STMT: SelectStmt +== 023 +EXPLAIN DELETE FROM test +-- +TABLE: name="test" schema="" table="test" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 024 +CREATE TEMP TABLE test AS SELECT 1 +-- +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 025 +LOCK TABLE public.schema_migrations IN ACCESS SHARE MODE +-- +TABLE: name="public.schema_migrations" schema="public" table="schema_migrations" ctx=DDL +STMT: LockStmt +== 026 +CREATE TABLE test (a int4) +-- +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: CreateStmt +== 027 +CREATE TABLE foo AS SELECT * FROM bar; +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 028 +CREATE TABLE foo AS SELECT id FROM bar UNION SELECT id from baz; +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="baz" schema="" table="baz" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 029 +CREATE TABLE test (a int4) WITH OIDS +-- +ERROR: syntax error at or near "OIDS" +CURSORPOS: 33 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 030 +CREATE INDEX testidx ON test USING btree (a, (lower(b) || upper(c))) WHERE pow(a, 2) > 25 +-- +TABLE: name="test" schema="" table="test" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="pow" function="pow" schema="" ctx=Call +STMT: IndexStmt +== 031 +CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe +-- +STMT: CreateSchemaStmt +== 032 +CREATE VIEW myview AS SELECT * FROM mytab +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +TABLE: name="mytab" schema="" table="mytab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 033 +REFRESH MATERIALIZED VIEW myview +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: RefreshMatViewStmt +== 034 +CREATE RULE shoe_ins_protect AS ON INSERT TO shoe DO INSTEAD NOTHING +-- +TABLE: name="shoe" schema="" table="shoe" ctx=DDL +STMT: RuleStmt +== 035 +CREATE TRIGGER check_update BEFORE UPDATE ON accounts FOR EACH ROW EXECUTE PROCEDURE check_account_update() +-- +TABLE: name="accounts" schema="" table="accounts" ctx=DDL +STMT: CreateTrigStmt +== 036 +DROP SCHEMA myschema +-- +STMT: DropStmt +== 037 +DROP VIEW myview, myview2 +-- +STMT: DropStmt +== 038 +DROP INDEX CONCURRENTLY myindex +-- +STMT: DropStmt +== 039 +DROP RULE myrule ON mytable CASCADE +-- +TABLE: name="mytable" schema="" table="mytable" ctx=DDL +STMT: DropStmt +== 040 +DROP TRIGGER IF EXISTS mytrigger ON mytable RESTRICT +-- +TABLE: name="mytable" schema="" table="mytable" ctx=DDL +STMT: DropStmt +== 041 +GRANT INSERT, UPDATE ON mytable TO myuser +-- +TABLE: name="mytable" schema="" table="mytable" ctx=DDL +STMT: GrantStmt +== 042 +REVOKE admins FROM joe +-- +STMT: GrantRoleStmt +== 043 +TRUNCATE bigtable, "fattable" RESTART IDENTITY +-- +TABLE: name="bigtable" schema="" table="bigtable" ctx=DDL +TABLE: name="fattable" schema="" table="fattable" ctx=DDL +STMT: TruncateStmt +== 044 +WITH a AS (SELECT * FROM x WHERE x.y = $1 AND x.z = 1) SELECT * FROM a +-- +TABLE: name="x" schema="" table="x" ctx=Select +CTE: "a" +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +== 045 +CREATE OR REPLACE FUNCTION thing(parameter_thing text) + RETURNS bigint AS +$BODY$ +DECLARE + local_thing_id BIGINT := 0; +BEGIN + SELECT thing_id INTO local_thing_id FROM thing_map + WHERE + thing_map_field = parameter_thing + ORDER BY 1 LIMIT 1; + + IF NOT FOUND THEN + local_thing_id = 0; + END IF; + RETURN local_thing_id; +END; +$BODY$ + LANGUAGE plpgsql STABLE +-- +FUNCTION: name="thing" function="thing" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 046 +CREATE FUNCTION getfoo(int) RETURNS TABLE (f1 int) AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getfoo" function="getfoo" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 047 +SELECT testfunc(1); +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=Call +STMT: SelectStmt +== 048 +CALL testfunc(1); +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=Call +STMT: CallStmt +== 049 +DROP FUNCTION IF EXISTS testfunc(x integer); +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=DDL +STMT: DropStmt +== 050 +ALTER FUNCTION testfunc(integer) RENAME TO testfunc2; +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=DDL +FUNCTION: name="testfunc2" function="testfunc2" schema="" ctx=DDL +STMT: RenameStmt +== 051 +select u.email, (select count(*) from enrollments e where e.user_id = u.id) as num_enrollments from users u +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="enrollments" schema="" table="enrollments" ctx=Select +ALIAS: "e"="enrollments" +ALIAS: "u"="users" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="e" column="user_id" +FILTER: schema="" table="u" column="id" +STMT: SelectStmt +== 052 +WITH cte_name AS (SELECT 1) SELECT * FROM table_name, cte_name +-- +TABLE: name="table_name" schema="" table="table_name" ctx=Select +CTE: "cte_name" +STMT: SelectStmt +== 053 +SELECT * FROM tbl TABLESAMPLE sample(1) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +STMT: SelectStmt +== 054 +SELECT xmltable.* FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text) +-- +TABLE: name="xmlelements" schema="" table="xmlelements" ctx=Select +STMT: SelectStmt +== 055 +SELECT jt.* FROM my_films, JSON_TABLE (js, '$.favorites[*]' COLUMNS (id FOR ORDINALITY, kind text PATH '$.kind')) AS jt; +-- +TABLE: name="my_films" schema="" table="my_films" ctx=Select +STMT: SelectStmt +== 056 +select u.* from (select * from users) u +-- +TABLE: name="users" schema="" table="users" ctx=Select +STMT: SelectStmt +== 057 +select users.id from users where 1 = (select count(*) from user_roles) +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 058 + + SELECT * + FROM pg_catalog.pg_class c + JOIN ( + SELECT 17650 AS oid + UNION ALL + SELECT 17663 AS oid + ) vals ON c.oid = vals.oid + +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +STMT: SelectStmt +== 059 + + select users.* + from users + where users.id IN (select user_roles.user_id from user_roles) + and (users.created_at between '2016-06-01' and '2016-06-30') + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +== 060 + + select users.* + from users + order by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +== 061 + + select users.* + from users + order by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) asc, ( + select max(user_logins.role_id) + from user_logins + where user_logins.user_id = users.id + ) desc + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +FILTER: schema="" table="user_logins" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +== 062 + + select users.* + from users + group by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +== 063 + + select users.* + from users + group by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ), ( + select max(user_logins.role_id) + from user_logins + where user_logins.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +FILTER: schema="" table="user_logins" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +== 064 + + select users.* + from users + group by users.id + having 1 > ( + select count(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +== 065 + + select users.* + from users + group by users.id + having true and 1 > ( + select count(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +== 066 + + select foo.* + from foo + join ( select * from bar ) b + on b.baz = foo.quux + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: SelectStmt +== 067 + + SELECT * + FROM foo + INNER JOIN join_a ON foo.id = join_a.id AND join_a.id IN ( + SELECT id + FROM sub_a + INNER JOIN sub_b ON sub_a.id = sub_b.id AND sub_b.id IN ( + SELECT id + FROM sub_c + INNER JOIN sub_d ON sub_c.id IN (SELECT id from sub_e) + ) + ) + INNER JOIN join_b ON foo.id = join_b.id AND join_b.id IN ( + SELECT id FROM sub_f + ) + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="join_a" schema="" table="join_a" ctx=Select +TABLE: name="join_b" schema="" table="join_b" ctx=Select +TABLE: name="sub_a" schema="" table="sub_a" ctx=Select +TABLE: name="sub_b" schema="" table="sub_b" ctx=Select +TABLE: name="sub_c" schema="" table="sub_c" ctx=Select +TABLE: name="sub_d" schema="" table="sub_d" ctx=Select +TABLE: name="sub_e" schema="" table="sub_e" ctx=Select +TABLE: name="sub_f" schema="" table="sub_f" ctx=Select +STMT: SelectStmt +== 068 + + WITH cte_a AS ( + SELECT * FROM table_a + ), cte_b AS ( + SELECT * FROM table_b + ) + SELECT id FROM table_c + LEFT JOIN cte_b ON table_c.id = cte_b.c_id + UNION + SELECT * FROM cte_a + +-- +TABLE: name="table_a" schema="" table="table_a" ctx=Select +TABLE: name="table_b" schema="" table="table_b" ctx=Select +TABLE: name="table_c" schema="" table="table_c" ctx=Select +CTE: "cte_a" +CTE: "cte_b" +STMT: SelectStmt +== 069 + + WITH cte_a AS ( + SELECT * FROM table_a + ), cte_b AS ( + SELECT * FROM table_b + ) + SELECT id FROM table_c + LEFT JOIN cte_b ON table_c.id = cte_b.c_id + EXCEPT + SELECT * FROM cte_a + +-- +TABLE: name="table_a" schema="" table="table_a" ctx=Select +TABLE: name="table_b" schema="" table="table_b" ctx=Select +TABLE: name="table_c" schema="" table="table_c" ctx=Select +CTE: "cte_a" +CTE: "cte_b" +STMT: SelectStmt +== 070 + + WITH cte_a AS ( + SELECT * FROM table_a + ), cte_b AS ( + SELECT * FROM table_b + ) + SELECT id FROM table_c + LEFT JOIN cte_b ON table_c.id = cte_b.c_id + INTERSECT + SELECT * FROM cte_a + +-- +TABLE: name="table_a" schema="" table="table_a" ctx=Select +TABLE: name="table_b" schema="" table="table_b" ctx=Select +TABLE: name="table_c" schema="" table="table_c" ctx=Select +CTE: "cte_a" +CTE: "cte_b" +STMT: SelectStmt +== 071 + + SELECT GREATEST( + date_trunc($1, $2::timestamptz) + $3::interval, + COALESCE( + ( + SELECT first_aggregate_starts_at + FROM schema_aggregate_infos + WHERE base_table = $4 LIMIT $5 + ), + now() + $6::interval + ) + ) AS first_hourly_start_ts + +-- +TABLE: name="schema_aggregate_infos" schema="" table="schema_aggregate_infos" ctx=Select +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="" column="base_table" +STMT: SelectStmt +== 072 + + SELECT + CASE + WHEN id IN (SELECT foo_id FROM when_a) THEN (SELECT MAX(id) FROM then_a) + WHEN id IN (SELECT foo_id FROM when_b) THEN (SELECT MAX(id) FROM then_b) + ELSE (SELECT MAX(id) FROM elsey) + END + FROM foo + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="when_a" schema="" table="when_a" ctx=Select +TABLE: name="then_a" schema="" table="then_a" ctx=Select +TABLE: name="when_b" schema="" table="when_b" ctx=Select +TABLE: name="then_b" schema="" table="then_b" ctx=Select +TABLE: name="elsey" schema="" table="elsey" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 073 + + SELECT 1 + FROM foo + WHERE x = any(cast(array(SELECT a FROM bar) as bigint[])) + OR x = any(array(SELECT a FROM baz)::bigint[]) + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="baz" schema="" table="baz" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 074 +SELECT * FROM my_custom_func() +-- +FUNCTION: name="my_custom_func" function="my_custom_func" schema="" ctx=Call +STMT: SelectStmt +== 075 + + SELECT * + FROM unnest($1::text[]) AS a(x) + LEFT OUTER JOIN LATERAL ( + SELECT json_build_object($2, z.z) + FROM ( + SELECT * + FROM ( + SELECT row_to_json( + (SELECT * FROM (SELECT public.my_function(b) FROM public.c) d) + ) + ) e + ) f + ) AS g ON (1) + +-- +TABLE: name="public.c" schema="public" table="c" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="public.my_function" function="my_function" schema="public" ctx=Call +STMT: SelectStmt +== 076 +insert into users(pk, name) values (1, 'bob'); +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +insert into users(pk, name) select pk, name from other_users; +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 078 + + with cte as ( + select pk, name from other_users + ) + insert into users(pk, name) select * from cte; + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +CTE: "cte" +STMT: InsertStmt +STMT: SelectStmt +== 079 +update users set name = 'bob'; +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: UpdateStmt +== 080 +update users set name = (select name from other_users limit 1); +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +== 081 + + with cte as ( + select name from other_users limit 1 + ) + update users set name = (select name from cte); + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +CTE: "cte" +STMT: UpdateStmt +STMT: SelectStmt +== 082 + + with cte as ( + select name from other_users limit 1 + ) + update users set name = (select name from cte); + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +CTE: "cte" +STMT: UpdateStmt +STMT: SelectStmt +== 083 +DELETE FROM users; +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: DeleteStmt +== 084 + + DELETE FROM users USING foo + WHERE foo_id = foo.id AND foo.action = 'delete'; + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: DeleteStmt +== 085 + + DELETE FROM users USING foo + WHERE foo_id = foo.id AND foo.action = 'delete'; + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: DeleteStmt +== 086 +DROP TYPE IF EXISTS repack.pk_something +-- +STMT: DropStmt +== 087 +SELECT * FROM x WHERE y = $1 AND z = 1 +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +== 088 +SELECT * FROM x WHERE x.y = $1 AND x.z = 1 +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +== 089 +WITH a AS (SELECT * FROM x WHERE x.y = $1 AND x.z = 1) SELECT * FROM a WHERE b = 5 +-- +TABLE: name="x" schema="" table="x" ctx=Select +CTE: "a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +== 090 +SELECT * FROM x WHERE x.y IS TRUE AND x.z IS NOT FALSE +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +== 091 +SELECT * FROM x WHERE x.y IS NULL AND x.z IS NOT NULL +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +== 092 +SELECT * FROM x WHERE x.y = COALESCE(z.a, z.b) +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z" column="b" +STMT: SelectStmt +== 093 +SELECT * FROM x where y = $1 UNION SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +== 094 +SELECT * FROM x where y = $1 UNION ALL SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +== 095 +SELECT * FROM x where y = $1 EXCEPT SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +== 096 +SELECT * FROM x where y = $1 EXCEPT ALL SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +== 097 +SELECT * FROM x where y = $1 INTERSECT SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +== 098 +SELECT * FROM x where y = $1 INTERSECT ALL SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +== 099 +SELECT a, y, z FROM x WHERE x.y = $1 AND x.z = 1 +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +== 100 +SELECT * FROM x WHERE x.y = $1 AND x.z = 1 ORDER BY a, b +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +== 101 +GRANT SELECT ON ALL TABLES IN SCHEMA public TO myrole +-- +STMT: GrantStmt +== 102 +SELECT * FROM b.c WHERE a.b.c = 1 +-- +TABLE: name="b.c" schema="b" table="c" ctx=Select +FILTER: schema="a" table="b" column="c" +STMT: SelectStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json new file mode 100644 index 0000000..442b788 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json @@ -0,0 +1,35 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_array.test b/parser/testdata/summary/plpgsql_regress/plpgsql_array.test new file mode 100644 index 0000000..54f09cb --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_array.test @@ -0,0 +1,225 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of array variables +|-- +-- We also check arrays of composites here, so this has some overlap +-- with the plpgsql_record tests. +|-- + +create type complex as (r float8, i float8) +-- +STMT: CompositeTypeStmt +== 002 +create type quadarray as (c1 complex[], c2 complex) +-- +STMT: CompositeTypeStmt +== 003 +do $$ declare a int[]; +begin a := array[1,2]; a[3] := 4; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 004 +do $$ declare a int[]; +begin a[3] := 4; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 005 +do $$ declare a int[]; +begin a[1][4] := 4; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 006 +do $$ declare a int[]; +begin a[1] := 23::text; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 007 +-- lax typing + +do $$ declare a int[]; +begin a := array[1,2]; a[2:3] := array[3,4]; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 008 +do $$ declare a int[]; +begin a := array[1,2]; a[2] := a[2] + 1; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 009 +do $$ declare a int[]; +begin a[1:2] := array[3,4]; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 010 +do $$ declare a int[]; +begin a[1:2] := 4; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 011 +-- error + +do $$ declare a complex[]; +begin a[1] := (1,2); a[1].i := 11; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 012 +do $$ declare a complex[]; +begin a[1].i := 11; raise notice 'a = %, a[1].i = %', a, a[1].i; end$$ +-- +STMT: DoStmt +== 013 +-- perhaps this ought to work, but for now it doesn't: +do $$ declare a complex[]; +begin a[1:2].i := array[11,12]; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 014 +do $$ declare a quadarray; +begin a.c1[1].i := 11; raise notice 'a = %, a.c1[1].i = %', a, a.c1[1].i; end$$ +-- +STMT: DoStmt +== 015 +do $$ declare a int[]; +begin a := array_agg(x) from (values(1),(2),(3)) v(x); raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 016 +create temp table onecol as select array[1,2] as f1 +-- +TABLE: name="onecol" schema="" table="onecol" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 017 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 018 +do $$ declare a int[]; +begin a := * from onecol for update; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 019 +-- error cases: + +do $$ declare a int[]; +begin a := from onecol; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 020 +do $$ declare a int[]; +begin a := f1, f1 from onecol; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 021 +insert into onecol values(array[11]) +-- +TABLE: name="onecol" schema="" table="onecol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +do $$ declare a int[]; +begin a := f1 from onecol; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 023 +do $$ declare a int[]; +begin a := f1 from onecol limit 1; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 024 +do $$ declare a real; +begin a[1] := 2; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 025 +do $$ declare a complex; +begin a.r[1] := 2; raise notice 'a = %', a; end$$ +-- +STMT: DoStmt +== 026 +|-- +-- test of %type[] and %rowtype[] syntax +|-- + +-- check supported syntax +do $$ +declare + v int; + v1 v%type; + v2 v%type[]; + v3 v%type[1]; + v4 v%type[][]; + v5 v%type[1][3]; + v6 v%type array; + v7 v%type array[]; + v8 v%type array[1]; + v9 v%type array[1][1]; + v10 pg_catalog.pg_class%rowtype[]; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(v3); + raise notice '%', pg_typeof(v4); + raise notice '%', pg_typeof(v5); + raise notice '%', pg_typeof(v6); + raise notice '%', pg_typeof(v7); + raise notice '%', pg_typeof(v8); + raise notice '%', pg_typeof(v9); + raise notice '%', pg_typeof(v10); +end; +$$ +-- +STMT: DoStmt +== 027 +-- some types don't support arrays +do $$ +declare + v pg_node_tree; + v1 v%type[]; +begin +end; +$$ +-- +STMT: DoStmt +== 028 +-- check functionality +do $$ +declare + v1 int; + v2 varchar; + a1 v1%type[]; + a2 v2%type[]; +begin + v1 := 10; + v2 := 'Hi'; + a1 := array[v1,v1]; + a2 := array[v2,v2]; + raise notice '% %', a1, a2; +end; +$$ +-- +STMT: DoStmt +== 029 +create table array_test_table(a int, b varchar) +-- +TABLE: name="array_test_table" schema="" table="array_test_table" ctx=DDL +STMT: CreateStmt +== 030 +insert into array_test_table values(1, 'first'), (2, 'second') +-- +TABLE: name="array_test_table" schema="" table="array_test_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +do $$ +declare tg array_test_table%rowtype[]; +begin + tg := array(select array_test_table from array_test_table); + raise notice '%', tg; + tg := array(select row(a,b) from array_test_table); + raise notice '%', tg; +end; +$$ +-- +STMT: DoStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json new file mode 100644 index 0000000..70c818b --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json @@ -0,0 +1,17 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_cache.test b/parser/testdata/summary/plpgsql_regress/plpgsql_cache.test new file mode 100644 index 0000000..b357d7e --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_cache.test @@ -0,0 +1,93 @@ +== 001 +|-- +-- Cache-behavior-dependent test cases +|-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- depending on debug_discard_caches, so we must have two expected-output +-- files to cover both cases. To minimize the maintenance effort resulting +-- from that, this file should contain only tests that do have different +-- results under debug_discard_caches. +|-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text) +-- +TABLE: name="c_mutable" schema="" table="c_mutable" ctx=DDL +STMT: CreateStmt +== 002 +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +FUNCTION: name="c_sillyaddone" function="c_sillyaddone" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +select c_sillyaddone(42) +-- +FUNCTION: name="c_sillyaddone" function="c_sillyaddone" schema="" ctx=Call +STMT: SelectStmt +== 004 +alter table c_mutable drop column f1 +-- +TABLE: name="c_mutable" schema="" table="c_mutable" ctx=DDL +STMT: AlterTableStmt +== 005 +alter table c_mutable add column f1 float8 +-- +TABLE: name="c_mutable" schema="" table="c_mutable" ctx=DDL +STMT: AlterTableStmt +== 006 +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but if debug_discard_caches is on, it will succeed) +select c_sillyaddone(42) +-- +FUNCTION: name="c_sillyaddone" function="c_sillyaddone" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- but it's OK if we force plan rebuilding +discard plans +-- +STMT: DiscardStmt +== 008 +select c_sillyaddone(42) +-- +FUNCTION: name="c_sillyaddone" function="c_sillyaddone" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$ +-- +FUNCTION: name="show_result_type" function="show_result_type" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 010 +select show_result_type('select 1 as a') +-- +FUNCTION: name="show_result_type" function="show_result_type" schema="" ctx=Call +STMT: SelectStmt +== 011 +-- currently this fails due to cached plan for pg_typeof expression +-- (but if debug_discard_caches is on, it will succeed) +select show_result_type('select 2.0 as a') +-- +FUNCTION: name="show_result_type" function="show_result_type" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- but it's OK if we force plan rebuilding +discard plans +-- +STMT: DiscardStmt +== 013 +select show_result_type('select 2.0 as a') +-- +FUNCTION: name="show_result_type" function="show_result_type" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json new file mode 100644 index 0000000..449cbc1 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json @@ -0,0 +1,87 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_call.test b/parser/testdata/summary/plpgsql_regress/plpgsql_call.test new file mode 100644 index 0000000..df9e24f --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_call.test @@ -0,0 +1,807 @@ +== 001 +|-- +-- Tests for procedures / CALL syntax +|-- + +CREATE PROCEDURE test_proc1() +LANGUAGE plpgsql +AS $$ +BEGIN + NULL; +END; +$$ +-- +FUNCTION: name="test_proc1" function="test_proc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +CALL test_proc1() +-- +FUNCTION: name="test_proc1" function="test_proc1" schema="" ctx=Call +STMT: CallStmt +== 003 +-- error: can't return non-NULL +CREATE PROCEDURE test_proc2() +LANGUAGE plpgsql +AS $$ +BEGIN + RETURN 5; +END; +$$ +-- +FUNCTION: name="test_proc2" function="test_proc2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 004 +CREATE TABLE test1 (a int) +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: CreateStmt +== 005 +CREATE PROCEDURE test_proc3(x int) +LANGUAGE plpgsql +AS $$ +BEGIN + INSERT INTO test1 VALUES (x); +END; +$$ +-- +FUNCTION: name="test_proc3" function="test_proc3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +CALL test_proc3(55) +-- +FUNCTION: name="test_proc3" function="test_proc3" schema="" ctx=Call +STMT: CallStmt +== 007 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 008 +-- Check that plan revalidation doesn't prevent setting transaction properties +-- (bug #18059). This test must include the first temp-object creation in +-- this script, or it won't exercise the bug scenario. Hence we put it early. +CREATE PROCEDURE test_proc3a() +LANGUAGE plpgsql +AS $$ +BEGIN + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + RAISE NOTICE 'done'; +END; +$$ +-- +FUNCTION: name="test_proc3a" function="test_proc3a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 009 +CALL test_proc3a() +-- +FUNCTION: name="test_proc3a" function="test_proc3a" schema="" ctx=Call +STMT: CallStmt +== 010 +CREATE TEMP TABLE tt1(f1 int) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +== 011 +CALL test_proc3a() +-- +FUNCTION: name="test_proc3a" function="test_proc3a" schema="" ctx=Call +STMT: CallStmt +== 012 +-- nested CALL +TRUNCATE TABLE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 013 +CREATE PROCEDURE test_proc4(y int) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL test_proc3(y); + CALL test_proc3($1); +END; +$$ +-- +FUNCTION: name="test_proc4" function="test_proc4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 014 +CALL test_proc4(66) +-- +FUNCTION: name="test_proc4" function="test_proc4" schema="" ctx=Call +STMT: CallStmt +== 015 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 016 +CALL test_proc4(66) +-- +FUNCTION: name="test_proc4" function="test_proc4" schema="" ctx=Call +STMT: CallStmt +== 017 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 018 +-- output arguments + +CREATE PROCEDURE test_proc5(INOUT a text) +LANGUAGE plpgsql +AS $$ +BEGIN + a := a || '+' || a; +END; +$$ +-- +FUNCTION: name="test_proc5" function="test_proc5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 019 +CALL test_proc5('abc') +-- +FUNCTION: name="test_proc5" function="test_proc5" schema="" ctx=Call +STMT: CallStmt +== 020 +CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + b := b * a; + c := c * a; +END; +$$ +-- +FUNCTION: name="test_proc6" function="test_proc6" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 021 +CALL test_proc6(2, 3, 4) +-- +FUNCTION: name="test_proc6" function="test_proc6" schema="" ctx=Call +STMT: CallStmt +== 022 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); + RAISE INFO 'x = %, y = %', x, y; + CALL test_proc6(2, c => y, b => x); + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +STMT: DoStmt +== 023 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x + 1, y); -- error + RAISE INFO 'x = %, y = %', x, y; +END; +$$ +-- +STMT: DoStmt +== 024 +DO +LANGUAGE plpgsql +$$ +DECLARE + x constant int := 3; + y int := 4; +BEGIN + CALL test_proc6(2, x, y); -- error because x is constant +END; +$$ +-- +STMT: DoStmt +== 025 +DO +LANGUAGE plpgsql +$$ +DECLARE + x int := 3; + y int := 4; +BEGIN + FOR i IN 1..5 LOOP + CALL test_proc6(i, x, y); + RAISE INFO 'x = %, y = %', x, y; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 026 +-- recursive with output arguments + +CREATE PROCEDURE test_proc7(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN +IF x > 1 THEN + a := x / 10; + b := x / 2; + CALL test_proc7(b::int, a, b); +END IF; +END; +$$ +-- +FUNCTION: name="test_proc7" function="test_proc7" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 027 +CALL test_proc7(100, -1, -1) +-- +FUNCTION: name="test_proc7" function="test_proc7" schema="" ctx=Call +STMT: CallStmt +== 028 +-- inner COMMIT with output arguments + +CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric) +LANGUAGE plpgsql +AS $$ +BEGIN + a := x / 10; + b := x / 2; + COMMIT; +END; +$$ +-- +FUNCTION: name="test_proc7c" function="test_proc7c" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +CREATE PROCEDURE test_proc7cc(_x int) +LANGUAGE plpgsql +AS $$ +DECLARE _a int; _b numeric; +BEGIN + CALL test_proc7c(_x, _a, _b); + RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b; +END +$$ +-- +FUNCTION: name="test_proc7cc" function="test_proc7cc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 030 +CALL test_proc7cc(10) +-- +FUNCTION: name="test_proc7cc" function="test_proc7cc" schema="" ctx=Call +STMT: CallStmt +== 031 +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$ +-- +FUNCTION: name="test_proc8a" function="test_proc8a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +CALL test_proc8a(10, 20) +-- +FUNCTION: name="test_proc8a" function="test_proc8a" schema="" ctx=Call +STMT: CallStmt +== 033 +CALL test_proc8a(b => 20, a => 10) +-- +FUNCTION: name="test_proc8a" function="test_proc8a" schema="" ctx=Call +STMT: CallStmt +== 034 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +STMT: DoStmt +== 035 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +FUNCTION: name="test_proc8b" function="test_proc8b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 037 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$ +-- +FUNCTION: name="test_proc8c" function="test_proc8c" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 038 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 039 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 040 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 041 +-- OUT parameters + +CREATE PROCEDURE test_proc9(IN a int, OUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + b := a * 2; +END; +$$ +-- +FUNCTION: name="test_proc9" function="test_proc9" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 042 +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc9(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$ +-- +STMT: DoStmt +== 043 +CREATE PROCEDURE test_proc10(IN a int, OUT b int, IN c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + b := a - c; +END; +$$ +-- +FUNCTION: name="test_proc10" function="test_proc10" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 044 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(a => _a, b => _b, c => _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(_a, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + + _a := 10; _b := 30; _c := 7; + CALL test_proc10(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 045 +-- OUT + VARIADIC + +CREATE PROCEDURE test_proc11(a OUT int, VARIADIC b int[]) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := b[1] + b[2]; +END; +$$ +-- +FUNCTION: name="test_proc11" function="test_proc11" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 046 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 7; + CALL test_proc11(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 047 +-- polymorphic OUT arguments + +CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %', a; + b := a; + c := array[a]; +END; +$$ +-- +FUNCTION: name="test_proc12" function="test_proc12" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 048 +DO $$ +DECLARE _a int; _b int; _c int[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 049 +DO $$ +DECLARE _a int; _b int; _c text[]; +BEGIN + _a := 10; + CALL test_proc12(_a, _b, _c); -- error + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$ +-- +STMT: DoStmt +== 050 +-- transition variable assignment + +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 051 +CREATE FUNCTION triggerfunc1() RETURNS trigger +LANGUAGE plpgsql +AS $$ +DECLARE + z int := 0; +BEGIN + CALL test_proc6(2, NEW.a, NEW.a); + RETURN NEW; +END; +$$ +-- +FUNCTION: name="triggerfunc1" function="triggerfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 052 +CREATE TRIGGER t1 BEFORE INSERT ON test1 EXECUTE PROCEDURE triggerfunc1() +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: CreateTrigStmt +== 053 +INSERT INTO test1 VALUES (1), (2), (3) +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +UPDATE test1 SET a = 22 WHERE a = 2 +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: UpdateStmt +== 055 +SELECT * FROM test1 ORDER BY a +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 056 +DROP PROCEDURE test_proc1 +-- +STMT: DropStmt +== 057 +DROP PROCEDURE test_proc3 +-- +STMT: DropStmt +== 058 +DROP PROCEDURE test_proc4 +-- +STMT: DropStmt +== 059 +DROP TABLE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: DropStmt +== 060 +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="p1" function="p1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 061 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$ +-- +STMT: DoStmt +== 062 +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +STMT: DoStmt +== 063 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +STMT: DoStmt +== 064 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$ +-- +STMT: DoStmt +== 065 +-- check that we detect change of dependencies in CALL +-- atomic and non-atomic call sites used to do this differently, so check both + +CREATE PROCEDURE inner_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'inner_p(%)', f1; +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="inner_p" function="inner_p" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 066 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 1 $$ LANGUAGE sql +-- +FUNCTION: name="f" function="f" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 067 +CREATE PROCEDURE outer_p (f1 int) +AS $$ +BEGIN + RAISE NOTICE 'outer_p(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="outer_p" function="outer_p" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 068 +CREATE FUNCTION outer_f (f1 int) RETURNS void +AS $$ +BEGIN + RAISE NOTICE 'outer_f(%)', f1; + CALL inner_p(f(f1)); +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="outer_f" function="outer_f" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 069 +CALL outer_p(42) +-- +FUNCTION: name="outer_p" function="outer_p" schema="" ctx=Call +STMT: CallStmt +== 070 +SELECT outer_f(42) +-- +FUNCTION: name="outer_f" function="outer_f" schema="" ctx=Call +STMT: SelectStmt +== 071 +DROP FUNCTION f(int) +-- +FUNCTION: name="f" function="f" schema="" ctx=DDL +STMT: DropStmt +== 072 +CREATE FUNCTION f(int) RETURNS int AS $$ SELECT $1 + 2 $$ LANGUAGE sql +-- +FUNCTION: name="f" function="f" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 073 +CALL outer_p(42) +-- +FUNCTION: name="outer_p" function="outer_p" schema="" ctx=Call +STMT: CallStmt +== 074 +SELECT outer_f(42) +-- +FUNCTION: name="outer_f" function="outer_f" schema="" ctx=Call +STMT: SelectStmt +== 075 +-- Check that stable functions in CALL see the correct snapshot + +CREATE TABLE t_test (x int) +-- +TABLE: name="t_test" schema="" table="t_test" ctx=DDL +STMT: CreateStmt +== 076 +INSERT INTO t_test VALUES (0) +-- +TABLE: name="t_test" schema="" table="t_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +CREATE FUNCTION f_get_x () RETURNS int +AS $$ +DECLARE l_result int; +BEGIN + SELECT x INTO l_result FROM t_test; + RETURN l_result; +END +$$ LANGUAGE plpgsql STABLE +-- +FUNCTION: name="f_get_x" function="f_get_x" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 078 +CREATE PROCEDURE f_print_x (x int) +AS $$ +BEGIN + RAISE NOTICE 'f_print_x(%)', x; +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="f_print_x" function="f_print_x" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 079 +-- test in non-atomic context +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + ROLLBACK; +END +$$ +-- +STMT: DoStmt +== 080 +-- test in non-atomic context, except exception block is locally atomic +DO $$ +BEGIN + BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + EXCEPTION WHEN division_by_zero THEN + RAISE NOTICE '%', SQLERRM; + END; + ROLLBACK; +END +$$ +-- +STMT: DoStmt +== 081 +-- test in atomic context +BEGIN +-- +STMT: TransactionStmt +== 082 +DO $$ +BEGIN + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); + UPDATE t_test SET x = x + 1; + RAISE NOTICE 'f_get_x(%)', f_get_x(); + CALL f_print_x(f_get_x()); +END +$$ +-- +STMT: DoStmt +== 083 +ROLLBACK +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json new file mode 100644 index 0000000..706d53c --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json @@ -0,0 +1,57 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_control.test b/parser/testdata/summary/plpgsql_regress/plpgsql_control.test new file mode 100644 index 0000000..6cc5621 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_control.test @@ -0,0 +1,674 @@ +== 001 +|-- +-- Tests for PL/pgSQL control structures +|-- + +-- integer FOR loop + +do $$ +begin + -- basic case + for i in 1..3 loop + raise notice '1..3: i = %', i; + end loop; + -- with BY, end matches exactly + for i in 1..10 by 3 loop + raise notice '1..10 by 3: i = %', i; + end loop; + -- with BY, end does not match + for i in 1..11 by 3 loop + raise notice '1..11 by 3: i = %', i; + end loop; + -- zero iterations + for i in 1..0 by 3 loop + raise notice '1..0 by 3: i = %', i; + end loop; + -- REVERSE + for i in reverse 10..0 by 3 loop + raise notice 'reverse 10..0 by 3: i = %', i; + end loop; + -- potential overflow + for i in 2147483620..2147483647 by 10 loop + raise notice '2147483620..2147483647 by 10: i = %', i; + end loop; + -- potential overflow, reverse direction + for i in reverse -2147483620..-2147483647 by 10 loop + raise notice 'reverse -2147483620..-2147483647 by 10: i = %', i; + end loop; +end$$ +-- +STMT: DoStmt +== 002 +-- BY can't be zero or negative +do $$ +begin + for i in 1..3 by 0 loop + raise notice '1..3 by 0: i = %', i; + end loop; +end$$ +-- +STMT: DoStmt +== 003 +do $$ +begin + for i in 1..3 by -1 loop + raise notice '1..3 by -1: i = %', i; + end loop; +end$$ +-- +STMT: DoStmt +== 004 +do $$ +begin + for i in reverse 1..3 by -1 loop + raise notice 'reverse 1..3 by -1: i = %', i; + end loop; +end$$ +-- +STMT: DoStmt +== 005 +-- CONTINUE statement + +create table conttesttbl(idx serial, v integer) +-- +TABLE: name="conttesttbl" schema="" table="conttesttbl" ctx=DDL +STMT: CreateStmt +== 006 +insert into conttesttbl(v) values(10) +-- +TABLE: name="conttesttbl" schema="" table="conttesttbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +insert into conttesttbl(v) values(20) +-- +TABLE: name="conttesttbl" schema="" table="conttesttbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +insert into conttesttbl(v) values(30) +-- +TABLE: name="conttesttbl" schema="" table="conttesttbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +insert into conttesttbl(v) values(40) +-- +TABLE: name="conttesttbl" schema="" table="conttesttbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +create function continue_test1() returns void as $$ +declare _i integer = 0; _r record; +begin + raise notice '---1---'; + loop + _i := _i + 1; + raise notice '%', _i; + continue when _i < 10; + exit; + end loop; + + raise notice '---2---'; + <> + loop + _i := _i - 1; + loop + raise notice '%', _i; + continue lbl when _i > 0; + exit lbl; + end loop; + end loop; + + raise notice '---3---'; + <> + while _i < 10 loop + _i := _i + 1; + continue the_loop when _i % 2 = 0; + raise notice '%', _i; + end loop; + + raise notice '---4---'; + for _i in 1..10 loop + begin + -- applies to outer loop, not the nested begin block + continue when _i < 5; + raise notice '%', _i; + end; + end loop; + + raise notice '---5---'; + for _r in select * from conttesttbl loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---6---'; + for _r in execute 'select * from conttesttbl' loop + continue when _r.v <= 20; + raise notice '%', _r.v; + end loop; + + raise notice '---7---'; + <> + for _i in 1..3 loop + continue looplabel when _i = 2; + raise notice '%', _i; + end loop; + + raise notice '---8---'; + _i := 1; + while _i <= 3 loop + raise notice '%', _i; + _i := _i + 1; + continue when _i = 3; + end loop; + + raise notice '---9---'; + for _r in select * from conttesttbl order by v limit 1 loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---10---'; + for _r in execute 'select * from conttesttbl order by v limit 1' loop + raise notice '%', _r.v; + continue; + end loop; + + raise notice '---11---'; + <> + for _i in 1..2 loop + raise notice 'outer %', _i; + <> + for _j in 1..3 loop + continue outerlooplabel when _j = 2; + raise notice 'inner %', _j; + end loop; + end loop; +end; $$ language plpgsql +-- +FUNCTION: name="continue_test1" function="continue_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 011 +select continue_test1() +-- +FUNCTION: name="continue_test1" function="continue_test1" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- should fail: CONTINUE is only legal inside a loop +create function continue_error1() returns void as $$ +begin + begin + continue; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="continue_error1" function="continue_error1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 013 +-- should fail: unlabeled EXIT is only legal inside a loop +create function exit_error1() returns void as $$ +begin + begin + exit; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="exit_error1" function="exit_error1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 014 +-- should fail: no such label +create function continue_error2() returns void as $$ +begin + begin + loop + continue no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="continue_error2" function="continue_error2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 015 +-- should fail: no such label +create function exit_error2() returns void as $$ +begin + begin + loop + exit no_such_label; + end loop; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="exit_error2" function="exit_error2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +-- should fail: CONTINUE can't reference the label of a named block +create function continue_error3() returns void as $$ +begin + <> + begin + loop + continue begin_block1; + end loop; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="continue_error3" function="continue_error3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +-- On the other hand, EXIT *can* reference the label of a named block +create function exit_block1() returns void as $$ +begin + <> + begin + loop + exit begin_block1; + raise exception 'should not get here'; + end loop; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="exit_block1" function="exit_block1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 018 +select exit_block1() +-- +FUNCTION: name="exit_block1" function="exit_block1" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- verbose end block and end loop +create function end_label1() returns void as $$ +<> +begin + <> + for i in 1 .. 10 loop + raise notice 'i = %', i; + exit flbl1; + end loop flbl1; + <> + for j in 1 .. 10 loop + raise notice 'j = %', j; + exit flbl2; + end loop; +end blbl; +$$ language plpgsql +-- +FUNCTION: name="end_label1" function="end_label1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 020 +select end_label1() +-- +FUNCTION: name="end_label1" function="end_label1" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- should fail: undefined end label +create function end_label2() returns void as $$ +begin + for _i in 1 .. 10 loop + exit; + end loop flbl1; +end; +$$ language plpgsql +-- +FUNCTION: name="end_label2" function="end_label2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 022 +-- should fail: end label does not match start label +create function end_label3() returns void as $$ +<> +begin + <> + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +FUNCTION: name="end_label3" function="end_label3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 023 +-- should fail: end label on a block without a start label +create function end_label4() returns void as $$ +<> +begin + for _i in 1 .. 10 loop + exit; + end loop outer_label; +end; +$$ language plpgsql +-- +FUNCTION: name="end_label4" function="end_label4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 024 +-- unlabeled exit matches no blocks +do $$ +begin +for i in 1..10 loop + <> + begin + begin -- unlabeled block + exit; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; +end loop; +raise notice 'should get here'; +end$$ +-- +STMT: DoStmt +== 025 +-- check exit out of an unlabeled block to a labeled one +do $$ +<> +begin + <> + begin + <> + begin + begin -- unlabeled block + exit innerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; + end; + raise notice 'nor here'; + end; + raise notice 'should get here'; +end$$ +-- +STMT: DoStmt +== 026 +-- check exit out of outermost block +do $$ +<> +begin + <> + begin + exit outerblock; + raise notice 'should not get here'; + end; + raise notice 'should not get here, either'; +end$$ +-- +STMT: DoStmt +== 027 +-- unlabeled exit does match a while loop +do $$ +begin + <> + while 1 > 0 loop + <> + while 1 > 0 loop + <> + while 1 > 0 loop + exit; + raise notice 'should not get here'; + end loop; + raise notice 'should get here'; + exit outermostwhile; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'should get here, too'; +end$$ +-- +STMT: DoStmt +== 028 +-- check exit out of an unlabeled while to a labeled one +do $$ +begin + <> + while 1 > 0 loop + while 1 > 0 loop + exit outerwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'should get here'; +end$$ +-- +STMT: DoStmt +== 029 +-- continue to an outer while +do $$ +declare i int := 0; +begin + <> + while i < 2 loop + raise notice 'outermostwhile, i = %', i; + i := i + 1; + <> + while 1 > 0 loop + <> + while 1 > 0 loop + continue outermostwhile; + raise notice 'should not get here'; + end loop; + raise notice 'should not get here, either'; + end loop; + raise notice 'nor here'; + end loop; + raise notice 'out of outermostwhile, i = %', i; +end$$ +-- +STMT: DoStmt +== 030 +-- return out of a while +create function return_from_while() returns int language plpgsql as $$ +declare i int := 0; +begin + while i < 10 loop + if i > 2 then + return i; + end if; + i := i + 1; + end loop; + return null; +end$$ +-- +FUNCTION: name="return_from_while" function="return_from_while" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 031 +select return_from_while() +-- +FUNCTION: name="return_from_while" function="return_from_while" schema="" ctx=Call +STMT: SelectStmt +== 032 +-- using list of scalars in fori and fore stmts +create function for_vect() returns void as $proc$ +<>declare a integer; b varchar; c varchar; r record; +begin + -- fori + for i in 1 .. 3 loop + raise notice '%', i; + end loop; + -- fore with record var + for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop + raise notice '% % %', r.aa, r.bb, r.cc; + end loop; + -- fore with single scalar + for a in select gs from generate_series(1,4) gs loop + raise notice '%', a; + end loop; + -- fore with multiple scalars + for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop + raise notice '% % %', a, b, c; + end loop; + -- using qualified names in fors, fore is enabled, disabled only for fori + for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop + raise notice '% % %', a, b, c; + end loop; +end; +$proc$ language plpgsql +-- +FUNCTION: name="for_vect" function="for_vect" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 033 +select for_vect() +-- +FUNCTION: name="for_vect" function="for_vect" schema="" ctx=Call +STMT: SelectStmt +== 034 +-- CASE statement + +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; + b int = 1; +begin + case $1 + when 1 then + return 'one'; + when 2 then + return 'two'; + when 3,4,3+5 then + return 'three, four or eight'; + when a then + return 'ten'; + when a+b, a+b+1 then + return 'eleven, twelve'; + end case; +end; +$$ language plpgsql immutable +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 035 +select case_test(1) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 036 +select case_test(2) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 037 +select case_test(3) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 038 +select case_test(4) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 039 +select case_test(5) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 040 +-- fails +select case_test(8) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 041 +select case_test(10) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 042 +select case_test(11) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 043 +select case_test(12) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 044 +select case_test(13) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- fails + +create or replace function catch() returns void as $$ +begin + raise notice '%', case_test(6); +exception + when case_not_found then + raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM; +end +$$ language plpgsql +-- +FUNCTION: name="catch" function="catch" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 046 +select catch() +-- +FUNCTION: name="catch" function="catch" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- test the searched variant too, as well as ELSE +create or replace function case_test(bigint) returns text as $$ +declare a int = 10; +begin + case + when $1 = 1 then + return 'one'; + when $1 = a + 2 then + return 'twelve'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 048 +select case_test(1) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 049 +select case_test(2) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 050 +select case_test(12) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 051 +select case_test(13) +-- +FUNCTION: name="case_test" function="case_test" schema="" ctx=Call +STMT: SelectStmt +== 052 +-- test line comment between WHEN and THEN +create or replace function case_comment(int) returns text as $$ +begin + case $1 + when 1 -- comment before THEN + then return 'one'; + else + return 'other'; + end case; +end; +$$ language plpgsql immutable +-- +FUNCTION: name="case_comment" function="case_comment" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 053 +select case_comment(1) +-- +FUNCTION: name="case_comment" function="case_comment" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_copy.test b/parser/testdata/summary/plpgsql_regress/plpgsql_copy.test new file mode 100644 index 0000000..2788c56 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_copy.test @@ -0,0 +1,21 @@ +== 001 +-- directory paths are passed to us in environment variables + +-- set up file names to use + +CREATE TABLE copy1 (a int, b float); + +-- COPY TO/FROM not authorized from client. +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 TO stdout; +END; +$$; +DO LANGUAGE plpgsql $$ +BEGIN + COPY copy1 FROM stdin; +-- +ERROR: "unterminated dollar-quoted string at or near \"$$\nBEGIN\n COPY copy1 FROM stdin;\"" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json new file mode 100644 index 0000000..aa06c83 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json @@ -0,0 +1,86 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_domain.test b/parser/testdata/summary/plpgsql_regress/plpgsql_domain.test new file mode 100644 index 0000000..c8305f6 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_domain.test @@ -0,0 +1,557 @@ +== 001 +|-- +-- Tests for PL/pgSQL's behavior with domain types +|-- + +CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL) +-- +STMT: CreateDomainStmt +== 002 +CREATE FUNCTION test_argresult_booltrue(x booltrue, y bool) RETURNS booltrue AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_booltrue" function="test_argresult_booltrue" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +SELECT * FROM test_argresult_booltrue(true, true) +-- +FUNCTION: name="test_argresult_booltrue" function="test_argresult_booltrue" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT * FROM test_argresult_booltrue(false, true) +-- +FUNCTION: name="test_argresult_booltrue" function="test_argresult_booltrue" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT * FROM test_argresult_booltrue(true, false) +-- +FUNCTION: name="test_argresult_booltrue" function="test_argresult_booltrue" schema="" ctx=Call +STMT: SelectStmt +== 006 +CREATE FUNCTION test_assign_booltrue(x bool, y bool) RETURNS booltrue AS $$ +declare v booltrue := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_booltrue" function="test_assign_booltrue" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +SELECT * FROM test_assign_booltrue(true, true) +-- +FUNCTION: name="test_assign_booltrue" function="test_assign_booltrue" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT * FROM test_assign_booltrue(false, true) +-- +FUNCTION: name="test_assign_booltrue" function="test_assign_booltrue" schema="" ctx=Call +STMT: SelectStmt +== 009 +SELECT * FROM test_assign_booltrue(true, false) +-- +FUNCTION: name="test_assign_booltrue" function="test_assign_booltrue" schema="" ctx=Call +STMT: SelectStmt +== 010 +CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0) +-- +STMT: CreateDomainStmt +== 011 +CREATE FUNCTION test_argresult_uint2(x uint2, y int) RETURNS uint2 AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_uint2" function="test_argresult_uint2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 012 +SELECT * FROM test_argresult_uint2(100::uint2, 50) +-- +FUNCTION: name="test_argresult_uint2" function="test_argresult_uint2" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT * FROM test_argresult_uint2(100::uint2, -50) +-- +FUNCTION: name="test_argresult_uint2" function="test_argresult_uint2" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT * FROM test_argresult_uint2(null, 1) +-- +FUNCTION: name="test_argresult_uint2" function="test_argresult_uint2" schema="" ctx=Call +STMT: SelectStmt +== 015 +CREATE FUNCTION test_assign_uint2(x int, y int) RETURNS uint2 AS $$ +declare v uint2 := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_uint2" function="test_assign_uint2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +SELECT * FROM test_assign_uint2(100, 50) +-- +FUNCTION: name="test_assign_uint2" function="test_assign_uint2" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT * FROM test_assign_uint2(100, -50) +-- +FUNCTION: name="test_assign_uint2" function="test_assign_uint2" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT * FROM test_assign_uint2(-100, 50) +-- +FUNCTION: name="test_assign_uint2" function="test_assign_uint2" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT * FROM test_assign_uint2(null, 1) +-- +FUNCTION: name="test_assign_uint2" function="test_assign_uint2" schema="" ctx=Call +STMT: SelectStmt +== 020 +CREATE DOMAIN nnint AS int NOT NULL +-- +STMT: CreateDomainStmt +== 021 +CREATE FUNCTION test_argresult_nnint(x nnint, y int) RETURNS nnint AS $$ +begin +return y; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_nnint" function="test_argresult_nnint" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 022 +SELECT * FROM test_argresult_nnint(10, 20) +-- +FUNCTION: name="test_argresult_nnint" function="test_argresult_nnint" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT * FROM test_argresult_nnint(null, 20) +-- +FUNCTION: name="test_argresult_nnint" function="test_argresult_nnint" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT * FROM test_argresult_nnint(10, null) +-- +FUNCTION: name="test_argresult_nnint" function="test_argresult_nnint" schema="" ctx=Call +STMT: SelectStmt +== 025 +CREATE FUNCTION test_assign_nnint(x int, y int) RETURNS nnint AS $$ +declare v nnint := x; +begin +v := y; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_nnint" function="test_assign_nnint" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 026 +SELECT * FROM test_assign_nnint(10, 20) +-- +FUNCTION: name="test_assign_nnint" function="test_assign_nnint" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT * FROM test_assign_nnint(null, 20) +-- +FUNCTION: name="test_assign_nnint" function="test_assign_nnint" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT * FROM test_assign_nnint(10, null) +-- +FUNCTION: name="test_assign_nnint" function="test_assign_nnint" schema="" ctx=Call +STMT: SelectStmt +== 029 +|-- +-- Domains over arrays +|-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]) +-- +STMT: CreateDomainStmt +== 030 +CREATE FUNCTION test_argresult_array_domain(x ordered_pair_domain) + RETURNS ordered_pair_domain AS $$ +begin +return x; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_array_domain" function="test_argresult_array_domain" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 031 +SELECT * FROM test_argresult_array_domain(ARRAY[0, 100]::ordered_pair_domain) +-- +FUNCTION: name="test_argresult_array_domain" function="test_argresult_array_domain" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT * FROM test_argresult_array_domain(NULL::ordered_pair_domain) +-- +FUNCTION: name="test_argresult_array_domain" function="test_argresult_array_domain" schema="" ctx=Call +STMT: SelectStmt +== 033 +CREATE FUNCTION test_argresult_array_domain_check_violation() + RETURNS ordered_pair_domain AS $$ +begin +return array[2,1]; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_array_domain_check_violation" function="test_argresult_array_domain_check_violation" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 034 +SELECT * FROM test_argresult_array_domain_check_violation() +-- +FUNCTION: name="test_argresult_array_domain_check_violation" function="test_argresult_array_domain_check_violation" schema="" ctx=Call +STMT: SelectStmt +== 035 +CREATE FUNCTION test_assign_ordered_pair_domain(x int, y int, z int) RETURNS ordered_pair_domain AS $$ +declare v ordered_pair_domain := array[x, y]; +begin +v[2] := z; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_ordered_pair_domain" function="test_assign_ordered_pair_domain" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +SELECT * FROM test_assign_ordered_pair_domain(1,2,3) +-- +FUNCTION: name="test_assign_ordered_pair_domain" function="test_assign_ordered_pair_domain" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT * FROM test_assign_ordered_pair_domain(1,2,0) +-- +FUNCTION: name="test_assign_ordered_pair_domain" function="test_assign_ordered_pair_domain" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT * FROM test_assign_ordered_pair_domain(2,1,3) +-- +FUNCTION: name="test_assign_ordered_pair_domain" function="test_assign_ordered_pair_domain" schema="" ctx=Call +STMT: SelectStmt +== 039 +|-- +-- Arrays of domains +|-- + +CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_read_uint2_array" function="test_read_uint2_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 040 +select test_read_uint2_array(array[1::uint2]) +-- +FUNCTION: name="test_read_uint2_array" function="test_read_uint2_array" schema="" ctx=Call +STMT: SelectStmt +== 041 +CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$ +begin +return array[x, x]; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_build_uint2_array" function="test_build_uint2_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 042 +select test_build_uint2_array(1::int2) +-- +FUNCTION: name="test_build_uint2_array" function="test_build_uint2_array" schema="" ctx=Call +STMT: SelectStmt +== 043 +select test_build_uint2_array(-1::int2) +-- +FUNCTION: name="test_build_uint2_array" function="test_build_uint2_array" schema="" ctx=Call +STMT: SelectStmt +== 044 +-- fail + +CREATE FUNCTION test_argresult_domain_array(x integer[]) + RETURNS ordered_pair_domain[] AS $$ +begin +return array[x::ordered_pair_domain, x::ordered_pair_domain]; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_domain_array" function="test_argresult_domain_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 045 +select test_argresult_domain_array(array[2,4]) +-- +FUNCTION: name="test_argresult_domain_array" function="test_argresult_domain_array" schema="" ctx=Call +STMT: SelectStmt +== 046 +select test_argresult_domain_array(array[4,2]) +-- +FUNCTION: name="test_argresult_domain_array" function="test_argresult_domain_array" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- fail + +CREATE FUNCTION test_argresult_domain_array2(x ordered_pair_domain) + RETURNS integer AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_domain_array2" function="test_argresult_domain_array2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 048 +select test_argresult_domain_array2(array[2,4]) +-- +FUNCTION: name="test_argresult_domain_array2" function="test_argresult_domain_array2" schema="" ctx=Call +STMT: SelectStmt +== 049 +select test_argresult_domain_array2(array[4,2]) +-- +FUNCTION: name="test_argresult_domain_array2" function="test_argresult_domain_array2" schema="" ctx=Call +STMT: SelectStmt +== 050 +-- fail + +CREATE FUNCTION test_argresult_array_domain_array(x ordered_pair_domain[]) + RETURNS ordered_pair_domain AS $$ +begin +return x[1]; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_argresult_array_domain_array" function="test_argresult_array_domain_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 051 +select test_argresult_array_domain_array(array[array[2,4]::ordered_pair_domain]) +-- +FUNCTION: name="test_argresult_array_domain_array" function="test_argresult_array_domain_array" schema="" ctx=Call +STMT: SelectStmt +== 052 +|-- +-- Domains within composite +|-- + +CREATE TYPE nnint_container AS (f1 int, f2 nnint) +-- +STMT: CompositeTypeStmt +== 053 +CREATE FUNCTION test_result_nnint_container(x int, y int) + RETURNS nnint_container AS $$ +begin +return row(x, y)::nnint_container; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_result_nnint_container" function="test_result_nnint_container" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 054 +SELECT test_result_nnint_container(null, 3) +-- +FUNCTION: name="test_result_nnint_container" function="test_result_nnint_container" schema="" ctx=Call +STMT: SelectStmt +== 055 +SELECT test_result_nnint_container(3, null) +-- +FUNCTION: name="test_result_nnint_container" function="test_result_nnint_container" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- fail + +CREATE FUNCTION test_assign_nnint_container(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container := row(x, y); +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_nnint_container" function="test_assign_nnint_container" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 057 +SELECT * FROM test_assign_nnint_container(1,2,3) +-- +FUNCTION: name="test_assign_nnint_container" function="test_assign_nnint_container" schema="" ctx=Call +STMT: SelectStmt +== 058 +SELECT * FROM test_assign_nnint_container(1,2,null) +-- +FUNCTION: name="test_assign_nnint_container" function="test_assign_nnint_container" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT * FROM test_assign_nnint_container(1,null,3) +-- +FUNCTION: name="test_assign_nnint_container" function="test_assign_nnint_container" schema="" ctx=Call +STMT: SelectStmt +== 060 +-- Since core system allows this: +SELECT null::nnint_container +-- +STMT: SelectStmt +== 061 +-- so should PL/PgSQL + +CREATE FUNCTION test_assign_nnint_container2(x int, y int, z int) + RETURNS nnint_container AS $$ +declare v nnint_container; +begin +v.f2 := z; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_nnint_container2" function="test_assign_nnint_container2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 062 +SELECT * FROM test_assign_nnint_container2(1,2,3) +-- +FUNCTION: name="test_assign_nnint_container2" function="test_assign_nnint_container2" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT * FROM test_assign_nnint_container2(1,2,null) +-- +FUNCTION: name="test_assign_nnint_container2" function="test_assign_nnint_container2" schema="" ctx=Call +STMT: SelectStmt +== 064 +|-- +-- Domains of composite +|-- + +CREATE TYPE named_pair AS ( + i integer, + j integer +) +-- +STMT: CompositeTypeStmt +== 065 +CREATE DOMAIN ordered_named_pair AS named_pair CHECK((VALUE).i <= (VALUE).j) +-- +STMT: CreateDomainStmt +== 066 +CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$ +begin +return p.i + p.j; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="read_ordered_named_pair" function="read_ordered_named_pair" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 067 +SELECT read_ordered_named_pair(row(1, 2)) +-- +FUNCTION: name="read_ordered_named_pair" function="read_ordered_named_pair" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT read_ordered_named_pair(row(2, 1)) +-- +FUNCTION: name="read_ordered_named_pair" function="read_ordered_named_pair" schema="" ctx=Call +STMT: SelectStmt +== 069 +-- fail + +CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$ +begin +return row(i, j); +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="build_ordered_named_pair" function="build_ordered_named_pair" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 070 +SELECT build_ordered_named_pair(1,2) +-- +FUNCTION: name="build_ordered_named_pair" function="build_ordered_named_pair" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT build_ordered_named_pair(2,1) +-- +FUNCTION: name="build_ordered_named_pair" function="build_ordered_named_pair" schema="" ctx=Call +STMT: SelectStmt +== 072 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pair(x int, y int, z int) + RETURNS ordered_named_pair AS $$ +declare v ordered_named_pair := row(x, y); +begin +v.j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_ordered_named_pair" function="test_assign_ordered_named_pair" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 073 +SELECT * FROM test_assign_ordered_named_pair(1,2,3) +-- +FUNCTION: name="test_assign_ordered_named_pair" function="test_assign_ordered_named_pair" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT * FROM test_assign_ordered_named_pair(1,2,0) +-- +FUNCTION: name="test_assign_ordered_named_pair" function="test_assign_ordered_named_pair" schema="" ctx=Call +STMT: SelectStmt +== 075 +SELECT * FROM test_assign_ordered_named_pair(2,1,3) +-- +FUNCTION: name="test_assign_ordered_named_pair" function="test_assign_ordered_named_pair" schema="" ctx=Call +STMT: SelectStmt +== 076 +CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$ +begin +return array[row(i, j), row(i, j+1)]; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="build_ordered_named_pairs" function="build_ordered_named_pairs" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 077 +SELECT build_ordered_named_pairs(1,2) +-- +FUNCTION: name="build_ordered_named_pairs" function="build_ordered_named_pairs" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT build_ordered_named_pairs(2,1) +-- +FUNCTION: name="build_ordered_named_pairs" function="build_ordered_named_pairs" schema="" ctx=Call +STMT: SelectStmt +== 079 +-- fail + +CREATE FUNCTION test_assign_ordered_named_pairs(x int, y int, z int) + RETURNS ordered_named_pair[] AS $$ +declare v ordered_named_pair[] := array[row(x, y)]; +begin +-- ideally this would work, but it doesn't yet: +-- v[1].j := z; +return v; +end +$$ LANGUAGE plpgsql +-- +FUNCTION: name="test_assign_ordered_named_pairs" function="test_assign_ordered_named_pairs" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 080 +SELECT * FROM test_assign_ordered_named_pairs(1,2,3) +-- +FUNCTION: name="test_assign_ordered_named_pairs" function="test_assign_ordered_named_pairs" schema="" ctx=Call +STMT: SelectStmt +== 081 +SELECT * FROM test_assign_ordered_named_pairs(2,1,3) +-- +FUNCTION: name="test_assign_ordered_named_pairs" function="test_assign_ordered_named_pairs" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT * FROM test_assign_ordered_named_pairs(1,2,0) +-- +FUNCTION: name="test_assign_ordered_named_pairs" function="test_assign_ordered_named_pairs" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json new file mode 100644 index 0000000..5a08d01 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json @@ -0,0 +1,18 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_misc.test b/parser/testdata/summary/plpgsql_regress/plpgsql_misc.test new file mode 100644 index 0000000..2f4c85c --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_misc.test @@ -0,0 +1,78 @@ +== 001 +|-- +-- Miscellaneous topics +|-- + +-- Verify that we can parse new-style CREATE FUNCTION/PROCEDURE +do +$$ + declare procedure int; -- check we still recognize non-keywords as vars + begin + create function test1() returns int + begin atomic + select 2 + 2; + end; + create or replace procedure test2(x int) + begin atomic + select x + 2; + end; + end +$$ +-- +STMT: DoStmt +== 002 +-- Test %TYPE and %ROWTYPE error cases +create table misc_table(f1 int) +-- +TABLE: name="misc_table" schema="" table="misc_table" ctx=DDL +STMT: CreateStmt +== 003 +do $$ declare x foo%type; begin end $$ +-- +STMT: DoStmt +== 004 +do $$ declare x notice%type; begin end $$ +-- +STMT: DoStmt +== 005 +-- covers unreserved-keyword case +do $$ declare x foo.bar%type; begin end $$ +-- +STMT: DoStmt +== 006 +do $$ declare x foo.bar.baz%type; begin end $$ +-- +STMT: DoStmt +== 007 +do $$ declare x public.foo.bar%type; begin end $$ +-- +STMT: DoStmt +== 008 +do $$ declare x public.misc_table.zed%type; begin end $$ +-- +STMT: DoStmt +== 009 +do $$ declare x foo%rowtype; begin end $$ +-- +STMT: DoStmt +== 010 +do $$ declare x notice%rowtype; begin end $$ +-- +STMT: DoStmt +== 011 +-- covers unreserved-keyword case +do $$ declare x foo.bar%rowtype; begin end $$ +-- +STMT: DoStmt +== 012 +do $$ declare x foo.bar.baz%rowtype; begin end $$ +-- +STMT: DoStmt +== 013 +do $$ declare x public.foo%rowtype; begin end $$ +-- +STMT: DoStmt +== 014 +do $$ declare x public.misc_table%rowtype; begin end $$ +-- +STMT: DoStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json new file mode 100644 index 0000000..780860b --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json @@ -0,0 +1,162 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_record.test b/parser/testdata/summary/plpgsql_regress/plpgsql_record.test new file mode 100644 index 0000000..da085c0 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_record.test @@ -0,0 +1,1116 @@ +== 001 +|-- +-- Tests for PL/pgSQL handling of composite (record) variables +|-- + +create type two_int4s as (f1 int4, f2 int4) +-- +STMT: CompositeTypeStmt +== 002 +create type more_int4s as (f0 text, f1 int4, f2 int4) +-- +STMT: CompositeTypeStmt +== 003 +create type two_int8s as (q1 int8, q2 int8) +-- +STMT: CompositeTypeStmt +== 004 +create type nested_int8s as (c1 two_int8s, c2 two_int8s) +-- +STMT: CompositeTypeStmt +== 005 +-- base-case return of a composite type +create function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1)::two_int8s; end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- ok to return a matching record type +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8); end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 008 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- we don't currently support implicit casting +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1,1); end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 010 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 011 +-- nor extra columns +create or replace function retc(int) returns two_int8s language plpgsql as +$$ begin return row($1::int8, 1::int8, 42); end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 012 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- same cases with an intermediate "record" variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8); return r; end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 014 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 015 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,1); return r; end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 017 +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 018 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- but, for mostly historical reasons, we do convert when assigning +-- to a named-composite-type variable +create or replace function retc(int) returns two_int8s language plpgsql as +$$ declare r two_int8s; begin r := row($1::int8, 1::int8, 42); return r; end $$ +-- +FUNCTION: name="retc" function="retc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 020 +select retc(42) +-- +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 021 +do $$ declare c two_int8s; +begin c := row(1,2); raise notice 'c = %', c; end$$ +-- +STMT: DoStmt +== 022 +do $$ declare c two_int8s; +begin for c in select 1,2 loop raise notice 'c = %', c; end loop; end$$ +-- +STMT: DoStmt +== 023 +do $$ declare c4 two_int4s; c8 two_int8s; +begin + c8 := row(1,2); + c4 := c8; + c8 := c4; + raise notice 'c4 = %', c4; + raise notice 'c8 = %', c8; +end$$ +-- +STMT: DoStmt +== 024 +do $$ declare c two_int8s; d nested_int8s; +begin + c := row(1,2); + d := row(c, row(c.q1, c.q2+1)); + raise notice 'c = %, d = %', c, d; + c.q1 := 10; + d.c1 := row(11,12); + d.c2.q2 := 42; + raise notice 'c = %, d = %', c, d; + raise notice 'c.q1 = %, d.c2 = %', c.q1, d.c2; + raise notice '(d).c2.q2 = %', (d).c2.q2; -- doesn't work without parens + raise notice '(d.c2).q2 = %', (d.c2).q2; -- doesn't work without parens +end$$ +-- +STMT: DoStmt +== 025 +-- block-qualified naming +do $$ <> declare c two_int8s; d nested_int8s; +begin + b.c := row(1,2); + b.d := row(b.c, row(b.c.q1, b.c.q2+1)); + raise notice 'b.c = %, b.d = %', b.c, b.d; + b.c.q1 := 10; + b.d.c1 := row(11,12); + b.d.c2.q2 := 42; + raise notice 'b.c = %, b.d = %', b.c, b.d; + raise notice 'b.c.q1 = %, b.d.c2 = %', b.c.q1, b.d.c2; + raise notice '(b.d).c2.q2 = %', (b.d).c2.q2; -- doesn't work without parens + raise notice '(b.d.c2).q2 = %', (b.d.c2).q2; -- doesn't work without parens +end$$ +-- +STMT: DoStmt +== 026 +-- error cases +do $$ declare c two_int8s; begin c.x = 1; end $$ +-- +STMT: DoStmt +== 027 +do $$ declare c nested_int8s; begin c.x = 1; end $$ +-- +STMT: DoStmt +== 028 +do $$ declare c nested_int8s; begin c.x.q1 = 1; end $$ +-- +STMT: DoStmt +== 029 +do $$ declare c nested_int8s; begin c.c2.x = 1; end $$ +-- +STMT: DoStmt +== 030 +do $$ declare c nested_int8s; begin d.c2.x = 1; end $$ +-- +STMT: DoStmt +== 031 +do $$ <> declare c two_int8s; begin b.c.x = 1; end $$ +-- +STMT: DoStmt +== 032 +do $$ <> declare c nested_int8s; begin b.c.x = 1; end $$ +-- +STMT: DoStmt +== 033 +do $$ <> declare c nested_int8s; begin b.c.x.q1 = 1; end $$ +-- +STMT: DoStmt +== 034 +do $$ <> declare c nested_int8s; begin b.c.c2.x = 1; end $$ +-- +STMT: DoStmt +== 035 +do $$ <> declare c nested_int8s; begin b.d.c2.x = 1; end $$ +-- +STMT: DoStmt +== 036 +-- check passing composite result to another function +create function getq1(two_int8s) returns int8 language plpgsql as $$ +declare r two_int8s; begin r := $1; return r.q1; end $$ +-- +FUNCTION: name="getq1" function="getq1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 037 +select getq1(retc(344)) +-- +FUNCTION: name="getq1" function="getq1" schema="" ctx=Call +FUNCTION: name="retc" function="retc" schema="" ctx=Call +STMT: SelectStmt +== 038 +select getq1(row(1,2)) +-- +FUNCTION: name="getq1" function="getq1" schema="" ctx=Call +STMT: SelectStmt +== 039 +do $$ +declare r1 two_int8s; r2 record; x int8; +begin + r1 := retc(345); + perform getq1(r1); + x := getq1(r1); + raise notice 'x = %', x; + r2 := retc(346); + perform getq1(r2); + x := getq1(r2); + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 040 +-- check assignments of composites +do $$ +declare r1 two_int8s; r2 two_int8s; r3 record; r4 record; +begin + r1 := row(1,2); + raise notice 'r1 = %', r1; + r1 := r1; -- shouldn't do anything + raise notice 'r1 = %', r1; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r2.q2 = r1.q1 + 3; -- check that r2 has distinct storage + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := null; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r1 := row(7,11)::two_int8s; + r2 := r1; + raise notice 'r1 = %', r1; + raise notice 'r2 = %', r2; + r3 := row(1,2); + r4 := r3; + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r4.f1 := r4.f1 + 3; -- check that r4 has distinct storage + raise notice 'r3 = %', r3; + raise notice 'r4 = %', r4; + r1 := r3; + raise notice 'r1 = %', r1; + r4 := r1; + raise notice 'r4 = %', r4; + r4.q2 := r4.q2 + 1; -- r4's field names have changed + raise notice 'r4 = %', r4; +end$$ +-- +STMT: DoStmt +== 041 +-- fields of named-type vars read as null if uninitialized +do $$ +declare r1 two_int8s; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; +end$$ +-- +STMT: DoStmt +== 042 +do $$ +declare r1 two_int8s; +begin + raise notice 'r1.q1 = %', r1.q1; + raise notice 'r1.q2 = %', r1.q2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +STMT: DoStmt +== 043 +-- records, not so much +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; +end$$ +-- +STMT: DoStmt +== 044 +-- but OK if you assign first +do $$ +declare r1 record; +begin + raise notice 'r1 = %', r1; + r1 := row(1,2); + raise notice 'r1.f1 = %', r1.f1; + raise notice 'r1.f2 = %', r1.f2; + raise notice 'r1 = %', r1; + raise notice 'r1.nosuchfield = %', r1.nosuchfield; +end$$ +-- +STMT: DoStmt +== 045 +-- check %type with block-qualified variable names +do $$ +<> +declare + v int; + r two_int8s; + v1 v%type; + v2 blk.v%type; + r1 r%type; + r2 blk.r%type; +begin + raise notice '%', pg_typeof(v1); + raise notice '%', pg_typeof(v2); + raise notice '%', pg_typeof(r1); + raise notice '%', pg_typeof(r2); +end$$ +-- +STMT: DoStmt +== 046 +-- check that type record can be passed through %type +do $$ +declare r1 record; + r2 r1%type; +begin + r2 := row(1,2); + raise notice 'r2 = %', r2; + r2 := row(3,4,5); + raise notice 'r2 = %', r2; +end$$ +-- +STMT: DoStmt +== 047 +-- arrays of record are not supported at the moment +do $$ +declare r1 record[]; +begin +end$$ +-- +STMT: DoStmt +== 048 +do $$ +declare r1 record; + r2 r1%type[]; +begin +end$$ +-- +STMT: DoStmt +== 049 +-- check repeated assignments to composite fields +create table some_table (id int, data text) +-- +TABLE: name="some_table" schema="" table="some_table" ctx=DDL +STMT: CreateStmt +== 050 +do $$ +declare r some_table; +begin + r := (23, 'skidoo'); + for i in 1 .. 10 loop + r.id := r.id + i; + r.data := r.data || ' ' || i; + end loop; + raise notice 'r = %', r; +end$$ +-- +STMT: DoStmt +== 051 +-- check behavior of function declared to return "record" + +create function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1); end $$ +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 052 +select returnsrecord(42) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 053 +select * from returnsrecord(42) as r(x int, y int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 054 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 055 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1); return r; end $$ +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 057 +select returnsrecord(42) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 058 +select * from returnsrecord(42) as r(x int, y int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 059 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 060 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 061 +-- fail + +-- should work the same with a missing column in the actual result value +create table has_hole(f1 int, f2 int, f3 int) +-- +TABLE: name="has_hole" schema="" table="has_hole" ctx=DDL +STMT: CreateStmt +== 062 +alter table has_hole drop column f2 +-- +TABLE: name="has_hole" schema="" table="has_hole" ctx=DDL +STMT: AlterTableStmt +== 063 +create or replace function returnsrecord(int) returns record language plpgsql as +$$ begin return row($1,$1+1)::has_hole; end $$ +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 064 +select returnsrecord(42) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 065 +select * from returnsrecord(42) as r(x int, y int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 066 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 067 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 068 +-- fail + +-- same with an intermediate record variable +create or replace function returnsrecord(int) returns record language plpgsql as +$$ declare r record; begin r := row($1,$1+1)::has_hole; return r; end $$ +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 069 +select returnsrecord(42) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 070 +select * from returnsrecord(42) as r(x int, y int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 071 +select * from returnsrecord(42) as r(x int, y int, z int) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 072 +-- fail +select * from returnsrecord(42) as r(x int, y bigint) +-- +FUNCTION: name="returnsrecord" function="returnsrecord" schema="" ctx=Call +STMT: SelectStmt +== 073 +-- fail + +-- check access to a field of an argument declared "record" +create function getf1(x record) returns int language plpgsql as +$$ begin return x.f1; end $$ +-- +FUNCTION: name="getf1" function="getf1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 074 +select getf1(1) +-- +FUNCTION: name="getf1" function="getf1" schema="" ctx=Call +STMT: SelectStmt +== 075 +select getf1(row(1,2)) +-- +FUNCTION: name="getf1" function="getf1" schema="" ctx=Call +STMT: SelectStmt +== 076 +select getf1(row(1,2)::two_int4s) +-- +FUNCTION: name="getf1" function="getf1" schema="" ctx=Call +STMT: SelectStmt +== 077 +select getf1(row('foo',123,456)::more_int4s) +-- +FUNCTION: name="getf1" function="getf1" schema="" ctx=Call +STMT: SelectStmt +== 078 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf1(row(1,2)::two_int8s) +-- +FUNCTION: name="getf1" function="getf1" schema="" ctx=Call +STMT: SelectStmt +== 079 +select getf1(row(1,2)) +-- +FUNCTION: name="getf1" function="getf1" schema="" ctx=Call +STMT: SelectStmt +== 080 +-- this seemingly-equivalent case behaves a bit differently, +-- because the core parser's handling of $N symbols is simplistic +create function getf2(record) returns int language plpgsql as +$$ begin return $1.f2; end $$ +-- +FUNCTION: name="getf2" function="getf2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 081 +select getf2(row(1,2)) +-- +FUNCTION: name="getf2" function="getf2" schema="" ctx=Call +STMT: SelectStmt +== 082 +-- ideally would work, but does not +select getf2(row(1,2)::two_int4s) +-- +FUNCTION: name="getf2" function="getf2" schema="" ctx=Call +STMT: SelectStmt +== 083 +select getf2(row('foo',123,456)::more_int4s) +-- +FUNCTION: name="getf2" function="getf2" schema="" ctx=Call +STMT: SelectStmt +== 084 +-- check behavior when assignment to FOR-loop variable requires coercion +do $$ +declare r two_int8s; +begin + for r in select i, i+1 from generate_series(1,4) i + loop + raise notice 'r = %', r; + end loop; +end$$ +-- +STMT: DoStmt +== 085 +-- check behavior when returning setof composite +create function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; + h has_hole; +begin + return next h; + r := (1,2); + h := (3,4); + return next r; + return next h; + return next row(5,6); + return next row(7,8)::has_hole; +end$$ +-- +FUNCTION: name="returnssetofholes" function="returnssetofholes" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 086 +select returnssetofholes() +-- +FUNCTION: name="returnssetofholes" function="returnssetofholes" schema="" ctx=Call +STMT: SelectStmt +== 087 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +declare r record; +begin + return next r; -- fails, not assigned yet +end$$ +-- +FUNCTION: name="returnssetofholes" function="returnssetofholes" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 088 +select returnssetofholes() +-- +FUNCTION: name="returnssetofholes" function="returnssetofholes" schema="" ctx=Call +STMT: SelectStmt +== 089 +create or replace function returnssetofholes() returns setof has_hole language plpgsql as +$$ +begin + return next row(1,2,3); -- fails +end$$ +-- +FUNCTION: name="returnssetofholes" function="returnssetofholes" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 090 +select returnssetofholes() +-- +FUNCTION: name="returnssetofholes" function="returnssetofholes" schema="" ctx=Call +STMT: SelectStmt +== 091 +-- check behavior with changes of a named rowtype +create table mutable(f1 int, f2 text) +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DDL +STMT: CreateStmt +== 092 +create function sillyaddone(int) returns int language plpgsql as +$$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$ +-- +FUNCTION: name="sillyaddone" function="sillyaddone" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 093 +select sillyaddone(42) +-- +FUNCTION: name="sillyaddone" function="sillyaddone" schema="" ctx=Call +STMT: SelectStmt +== 094 +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test + +alter table mutable drop column f1 +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DDL +STMT: AlterTableStmt +== 095 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddone(42) +-- +FUNCTION: name="sillyaddone" function="sillyaddone" schema="" ctx=Call +STMT: SelectStmt +== 096 +-- fail + +create function getf3(x mutable) returns int language plpgsql as +$$ begin return x.f3; end $$ +-- +FUNCTION: name="getf3" function="getf3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 097 +select getf3(null::mutable) +-- +FUNCTION: name="getf3" function="getf3" schema="" ctx=Call +STMT: SelectStmt +== 098 +-- doesn't work yet +alter table mutable add column f3 int +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DDL +STMT: AlterTableStmt +== 099 +select getf3(null::mutable) +-- +FUNCTION: name="getf3" function="getf3" schema="" ctx=Call +STMT: SelectStmt +== 100 +-- now it works +alter table mutable drop column f3 +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DDL +STMT: AlterTableStmt +== 101 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select getf3(null::mutable) +-- +FUNCTION: name="getf3" function="getf3" schema="" ctx=Call +STMT: SelectStmt +== 102 +-- fails again + +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off +-- +STMT: VariableSetStmt +== 103 +-- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$ +-- +FUNCTION: name="sillyaddtwo" function="sillyaddtwo" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 104 +reset check_function_bodies +-- +STMT: VariableSetStmt +== 105 +select sillyaddtwo(42) +-- +FUNCTION: name="sillyaddtwo" function="sillyaddtwo" schema="" ctx=Call +STMT: SelectStmt +== 106 +-- fail +create table mutable2(f1 int, f2 text) +-- +TABLE: name="mutable2" schema="" table="mutable2" ctx=DDL +STMT: CreateStmt +== 107 +select sillyaddtwo(42) +-- +FUNCTION: name="sillyaddtwo" function="sillyaddtwo" schema="" ctx=Call +STMT: SelectStmt +== 108 +drop table mutable2 +-- +TABLE: name="mutable2" schema="" table="mutable2" ctx=DDL +STMT: DropStmt +== 109 +-- the context stack is different when debug_discard_caches +-- is set, so suppress context output +select sillyaddtwo(42) +-- +FUNCTION: name="sillyaddtwo" function="sillyaddtwo" schema="" ctx=Call +STMT: SelectStmt +== 110 +-- fail +create table mutable2(f0 text, f1 int, f2 text) +-- +TABLE: name="mutable2" schema="" table="mutable2" ctx=DDL +STMT: CreateStmt +== 111 +select sillyaddtwo(42) +-- +FUNCTION: name="sillyaddtwo" function="sillyaddtwo" schema="" ctx=Call +STMT: SelectStmt +== 112 +select sillyaddtwo(43) +-- +FUNCTION: name="sillyaddtwo" function="sillyaddtwo" schema="" ctx=Call +STMT: SelectStmt +== 113 +-- check access to system columns in a record variable + +create function sillytrig() returns trigger language plpgsql as +$$begin + raise notice 'old.ctid = %', old.ctid; + raise notice 'old.tableoid = %', old.tableoid::regclass; + return new; +end$$ +-- +FUNCTION: name="sillytrig" function="sillytrig" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 114 +create trigger mutable_trig before update on mutable for each row +execute procedure sillytrig() +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DDL +STMT: CreateTrigStmt +== 115 +insert into mutable values ('foo'), ('bar') +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +update mutable set f2 = f2 || ' baz' +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DML +STMT: UpdateStmt +== 117 +table mutable +-- +TABLE: name="mutable" schema="" table="mutable" ctx=Select +STMT: SelectStmt +== 118 +-- check returning a composite datum from a trigger + +create or replace function sillytrig() returns trigger language plpgsql as +$$begin + return row(new.*); +end$$ +-- +FUNCTION: name="sillytrig" function="sillytrig" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 119 +update mutable set f2 = f2 || ' baz' +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DML +STMT: UpdateStmt +== 120 +table mutable +-- +TABLE: name="mutable" schema="" table="mutable" ctx=Select +STMT: SelectStmt +== 121 +create or replace function sillytrig() returns trigger language plpgsql as +$$declare r record; +begin + r := row(new.*); + return r; +end$$ +-- +FUNCTION: name="sillytrig" function="sillytrig" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 122 +update mutable set f2 = f2 || ' baz' +-- +TABLE: name="mutable" schema="" table="mutable" ctx=DML +STMT: UpdateStmt +== 123 +table mutable +-- +TABLE: name="mutable" schema="" table="mutable" ctx=Select +STMT: SelectStmt +== 124 +|-- +-- Domains of composite +|-- + +create domain ordered_int8s as two_int8s check((value).q1 <= (value).q2) +-- +STMT: CreateDomainStmt +== 125 +create function read_ordered_int8s(p ordered_int8s) returns int8 as $$ +begin return p.q1 + p.q2; end +$$ language plpgsql +-- +FUNCTION: name="read_ordered_int8s" function="read_ordered_int8s" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 126 +select read_ordered_int8s(row(1, 2)) +-- +FUNCTION: name="read_ordered_int8s" function="read_ordered_int8s" schema="" ctx=Call +STMT: SelectStmt +== 127 +select read_ordered_int8s(row(2, 1)) +-- +FUNCTION: name="read_ordered_int8s" function="read_ordered_int8s" schema="" ctx=Call +STMT: SelectStmt +== 128 +-- fail + +create function build_ordered_int8s(i int8, j int8) returns ordered_int8s as $$ +begin return row(i,j); end +$$ language plpgsql +-- +FUNCTION: name="build_ordered_int8s" function="build_ordered_int8s" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 129 +select build_ordered_int8s(1,2) +-- +FUNCTION: name="build_ordered_int8s" function="build_ordered_int8s" schema="" ctx=Call +STMT: SelectStmt +== 130 +select build_ordered_int8s(2,1) +-- +FUNCTION: name="build_ordered_int8s" function="build_ordered_int8s" schema="" ctx=Call +STMT: SelectStmt +== 131 +-- fail + +create function build_ordered_int8s_2(i int8, j int8) returns ordered_int8s as $$ +declare r record; begin r := row(i,j); return r; end +$$ language plpgsql +-- +FUNCTION: name="build_ordered_int8s_2" function="build_ordered_int8s_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 132 +select build_ordered_int8s_2(1,2) +-- +FUNCTION: name="build_ordered_int8s_2" function="build_ordered_int8s_2" schema="" ctx=Call +STMT: SelectStmt +== 133 +select build_ordered_int8s_2(2,1) +-- +FUNCTION: name="build_ordered_int8s_2" function="build_ordered_int8s_2" schema="" ctx=Call +STMT: SelectStmt +== 134 +-- fail + +create function build_ordered_int8s_3(i int8, j int8) returns ordered_int8s as $$ +declare r two_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +FUNCTION: name="build_ordered_int8s_3" function="build_ordered_int8s_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 135 +select build_ordered_int8s_3(1,2) +-- +FUNCTION: name="build_ordered_int8s_3" function="build_ordered_int8s_3" schema="" ctx=Call +STMT: SelectStmt +== 136 +select build_ordered_int8s_3(2,1) +-- +FUNCTION: name="build_ordered_int8s_3" function="build_ordered_int8s_3" schema="" ctx=Call +STMT: SelectStmt +== 137 +-- fail + +create function build_ordered_int8s_4(i int8, j int8) returns ordered_int8s as $$ +declare r ordered_int8s; begin r := row(i,j); return r; end +$$ language plpgsql +-- +FUNCTION: name="build_ordered_int8s_4" function="build_ordered_int8s_4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 138 +select build_ordered_int8s_4(1,2) +-- +FUNCTION: name="build_ordered_int8s_4" function="build_ordered_int8s_4" schema="" ctx=Call +STMT: SelectStmt +== 139 +select build_ordered_int8s_4(2,1) +-- +FUNCTION: name="build_ordered_int8s_4" function="build_ordered_int8s_4" schema="" ctx=Call +STMT: SelectStmt +== 140 +-- fail + +create function build_ordered_int8s_a(i int8, j int8) returns ordered_int8s[] as $$ +begin return array[row(i,j), row(i,j+1)]; end +$$ language plpgsql +-- +FUNCTION: name="build_ordered_int8s_a" function="build_ordered_int8s_a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 141 +select build_ordered_int8s_a(1,2) +-- +FUNCTION: name="build_ordered_int8s_a" function="build_ordered_int8s_a" schema="" ctx=Call +STMT: SelectStmt +== 142 +select build_ordered_int8s_a(2,1) +-- +FUNCTION: name="build_ordered_int8s_a" function="build_ordered_int8s_a" schema="" ctx=Call +STMT: SelectStmt +== 143 +-- fail + +-- check field assignment +do $$ +declare r ordered_int8s; +begin + r.q1 := null; + r.q2 := 43; + r.q1 := 42; + r.q2 := 41; -- fail +end$$ +-- +STMT: DoStmt +== 144 +-- check whole-row assignment +do $$ +declare r ordered_int8s; +begin + r := null; + r := row(null,null); + r := row(1,2); + r := row(2,1); -- fail +end$$ +-- +STMT: DoStmt +== 145 +-- check assignment in for-loop +do $$ +declare r ordered_int8s; +begin + for r in values (1,2),(3,4),(6,5) loop + raise notice 'r = %', r; + end loop; +end$$ +-- +STMT: DoStmt +== 146 +-- check behavior with toastable fields, too + +create type two_texts as (f1 text, f2 text) +-- +STMT: CompositeTypeStmt +== 147 +create domain ordered_texts as two_texts check((value).f1 <= (value).f2) +-- +STMT: CreateDomainStmt +== 148 +create table sometable (id int, a text, b text) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DDL +STMT: CreateStmt +== 149 +-- b should be compressed, but in-line +insert into sometable values (1, 'a', repeat('ffoob',1000)) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 150 +-- this b should be out-of-line +insert into sometable values (2, 'a', repeat('ffoob',100000)) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 151 +-- this pair should fail the domain check +insert into sometable values (3, 'z', repeat('ffoob',100000)) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 152 +do $$ +declare d ordered_texts; +begin + for d in select a, b from sometable loop + raise notice 'succeeded at "%"', d.f1; + end loop; +end$$ +-- +STMT: DoStmt +== 153 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := row(r.a, r.b); + end loop; +end$$ +-- +STMT: DoStmt +== 154 +do $$ +declare r record; d ordered_texts; +begin + for r in select * from sometable loop + raise notice 'processing row %', r.id; + d := null; + d.f1 := r.a; + d.f2 := r.b; + end loop; +end$$ +-- +STMT: DoStmt +== 155 +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$ +-- +FUNCTION: name="compresult" function="compresult" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 156 +create table two_int8s_tab (f1 two_int8s) +-- +TABLE: name="two_int8s_tab" schema="" table="two_int8s_tab" ctx=DDL +STMT: CreateStmt +== 157 +insert into two_int8s_tab values (compresult(42)) +-- +TABLE: name="two_int8s_tab" schema="" table="two_int8s_tab" ctx=DML +FUNCTION: name="compresult" function="compresult" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 158 +-- reconnect so we lose any local knowledge of anonymous record types +table two_int8s_tab +-- +TABLE: name="two_int8s_tab" schema="" table="two_int8s_tab" ctx=Select +STMT: SelectStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json new file mode 100644 index 0000000..5d34ab7 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json @@ -0,0 +1,28 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_simple.test b/parser/testdata/summary/plpgsql_regress/plpgsql_simple.test new file mode 100644 index 0000000..3d2e049 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_simple.test @@ -0,0 +1,184 @@ +== 001 +|-- +-- Tests for plpgsql's handling of "simple" expressions +|-- + +-- Check that changes to an inline-able function are handled correctly +create function simplesql(int) returns int language sql +as 'select $1' +-- +FUNCTION: name="simplesql" function="simplesql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +create function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simplesql(n); + if n = 5 then + create or replace function simplesql(int) returns int language sql + as 'select $1 + 100'; + end if; + end loop; + return sum; +end$$ +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 004 +-- Check that changes in search path are dealt with correctly +create schema simple1 +-- +STMT: CreateSchemaStmt +== 005 +create function simple1.simpletarget(int) returns int language plpgsql +as $$begin return $1; end$$ +-- +FUNCTION: name="simple1.simpletarget" function="simpletarget" schema="simple1" ctx=DDL +STMT: CreateFunctionStmt +== 006 +create function simpletarget(int) returns int language plpgsql +as $$begin return $1 + 100; end$$ +-- +FUNCTION: name="simpletarget" function="simpletarget" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare + sum int := 0; +begin + for n in 1..10 loop + sum := sum + simpletarget(n); + if n = 5 then + set local search_path = 'simple1'; + end if; + end loop; + return sum; +end$$ +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 008 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- try it with non-volatile functions, too +alter function simple1.simpletarget(int) immutable +-- +STMT: AlterFunctionStmt +== 010 +alter function simpletarget(int) immutable +-- +STMT: AlterFunctionStmt +== 011 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- make sure flushing local caches changes nothing + +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- Check case where first attempt to determine if it's simple fails + +create function simplesql() returns int language sql +as $$select 1 / 0$$ +-- +FUNCTION: name="simplesql" function="simplesql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 014 +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + select simplesql() into x; + return x; +end$$ +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 015 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- division by zero occurs during simple-expr check + +create or replace function simplesql() returns int language sql +as $$select 2 + 2$$ +-- +FUNCTION: name="simplesql" function="simplesql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- Check case where called function changes from non-SRF to SRF (bug #18497) + +create or replace function simplecaller() returns int language plpgsql +as $$ +declare x int; +begin + x := simplesql(); + return x; +end$$ +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 019 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 020 +drop function simplesql() +-- +FUNCTION: name="simplesql" function="simplesql" schema="" ctx=DDL +STMT: DropStmt +== 021 +create function simplesql() returns setof int language sql +as $$select 22 + 22$$ +-- +FUNCTION: name="simplesql" function="simplesql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 022 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 023 +select simplecaller() +-- +FUNCTION: name="simplecaller" function="simplecaller" schema="" ctx=Call +STMT: SelectStmt +== 024 +-- Check handling of simple expression in a scrollable cursor (bug #18859) + +do $$ +declare + p_CurData refcursor; + val int; +begin + open p_CurData scroll for select 42; + fetch p_CurData into val; + raise notice 'val = %', val; +end; $$ +-- +STMT: DoStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json new file mode 100644 index 0000000..17a73dc --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json @@ -0,0 +1,121 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.test b/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.test new file mode 100644 index 0000000..e711447 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.test @@ -0,0 +1,951 @@ +== 001 +CREATE TABLE test1 (a int, b text) +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: CreateStmt +== 002 +CREATE PROCEDURE transaction_test1(x int, y text) +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..x LOOP + INSERT INTO test1 (a, b) VALUES (i, y); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +FUNCTION: name="transaction_test1" function="transaction_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +CALL transaction_test1(9, 'foo') +-- +FUNCTION: name="transaction_test1" function="transaction_test1" schema="" ctx=Call +STMT: CallStmt +== 004 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 005 +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 006 +DO +LANGUAGE plpgsql +$$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END +$$ +-- +STMT: DoStmt +== 007 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 008 +-- transaction commands not allowed when called in transaction block +START TRANSACTION +-- +STMT: TransactionStmt +== 009 +CALL transaction_test1(9, 'error') +-- +FUNCTION: name="transaction_test1" function="transaction_test1" schema="" ctx=Call +STMT: CallStmt +== 010 +COMMIT +-- +STMT: TransactionStmt +== 011 +START TRANSACTION +-- +STMT: TransactionStmt +== 012 +DO LANGUAGE plpgsql $$ BEGIN COMMIT; END $$ +-- +STMT: DoStmt +== 013 +COMMIT +-- +STMT: TransactionStmt +== 014 +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 015 +-- not allowed in a function +CREATE FUNCTION transaction_test2() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; + RETURN 1; +END +$$ +-- +FUNCTION: name="transaction_test2" function="transaction_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +SELECT transaction_test2() +-- +FUNCTION: name="transaction_test2" function="transaction_test2" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 018 +-- also not allowed if procedure is called from a function +CREATE FUNCTION transaction_test3() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, 'error'); + RETURN 1; +END; +$$ +-- +FUNCTION: name="transaction_test3" function="transaction_test3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 019 +SELECT transaction_test3() +-- +FUNCTION: name="transaction_test3" function="transaction_test3" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 021 +-- DO block inside function +CREATE FUNCTION transaction_test4() RETURNS int +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'DO LANGUAGE plpgsql $x$ BEGIN COMMIT; END $x$'; + RETURN 1; +END; +$$ +-- +FUNCTION: name="transaction_test4" function="transaction_test4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 022 +SELECT transaction_test4() +-- +FUNCTION: name="transaction_test4" function="transaction_test4" schema="" ctx=Call +STMT: SelectStmt +== 023 +-- proconfig settings currently disallow transaction statements +CREATE PROCEDURE transaction_test5() +LANGUAGE plpgsql +SET work_mem = 555 +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +FUNCTION: name="transaction_test5" function="transaction_test5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 024 +CALL transaction_test5() +-- +FUNCTION: name="transaction_test5" function="transaction_test5" schema="" ctx=Call +STMT: CallStmt +== 025 +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$ +-- +FUNCTION: name="transaction_test5b" function="transaction_test5b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 026 +CALL transaction_test5b() +-- +FUNCTION: name="transaction_test5b" function="transaction_test5b" schema="" ctx=Call +STMT: CallStmt +== 027 +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 028 +-- nested procedure calls +CREATE PROCEDURE transaction_test6(c text) +LANGUAGE plpgsql +AS $$ +BEGIN + CALL transaction_test1(9, c); +END; +$$ +-- +FUNCTION: name="transaction_test6" function="transaction_test6" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +CALL transaction_test6('bar') +-- +FUNCTION: name="transaction_test6" function="transaction_test6" schema="" ctx=Call +STMT: CallStmt +== 030 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 031 +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 032 +CREATE PROCEDURE transaction_test7() +LANGUAGE plpgsql +AS $$ +BEGIN + DO 'BEGIN CALL transaction_test1(9, $x$baz$x$); END;'; +END; +$$ +-- +FUNCTION: name="transaction_test7" function="transaction_test7" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 033 +CALL transaction_test7() +-- +FUNCTION: name="transaction_test7" function="transaction_test7" schema="" ctx=Call +STMT: CallStmt +== 034 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 035 +CREATE PROCEDURE transaction_test8() +LANGUAGE plpgsql +AS $$ +BEGIN + EXECUTE 'CALL transaction_test1(10, $x$baz$x$)'; +END; +$$ +-- +FUNCTION: name="transaction_test8" function="transaction_test8" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +CALL transaction_test8() +-- +FUNCTION: name="transaction_test8" function="transaction_test8" schema="" ctx=Call +STMT: CallStmt +== 037 +-- commit inside cursor loop +CREATE TABLE test2 (x int) +-- +TABLE: name="test2" schema="" table="test2" ctx=DDL +STMT: CreateStmt +== 038 +INSERT INTO test2 VALUES (0), (1), (2), (3), (4) +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 040 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 041 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 042 +-- check that this doesn't leak a holdable portal +SELECT * FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 043 +-- error in cursor loop with commit +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 044 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (12/(r.x-2)); + COMMIT; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 045 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 046 +SELECT * FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 047 +-- rollback inside cursor loop +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 048 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 049 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 050 +SELECT * FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 051 +-- first commit then rollback inside cursor loop +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 052 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + IF r.x % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 053 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 054 +SELECT * FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 055 +-- rollback inside cursor loop +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 056 +DO LANGUAGE plpgsql $$ +DECLARE + r RECORD; +BEGIN + FOR r IN UPDATE test2 SET x = x * 2 RETURNING x LOOP + INSERT INTO test1 (a) VALUES (r.x); + ROLLBACK; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 057 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 058 +SELECT * FROM test2 +-- +TABLE: name="test2" schema="" table="test2" ctx=Select +STMT: SelectStmt +== 059 +SELECT * FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 060 +-- interaction of FOR UPDATE cursor with subsequent updates (bug #17050) +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 061 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +DO LANGUAGE plpgsql $$ +DECLARE + l_cur CURSOR FOR SELECT a FROM test1 ORDER BY 1 FOR UPDATE; +BEGIN + FOR r IN l_cur LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 063 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 064 +SELECT * FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 065 +-- like bug #17050, but with implicit cursor +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 066 +INSERT INTO test1 VALUES (1,'one'), (2,'two'), (3,'three') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +DO LANGUAGE plpgsql $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT a FROM test1 FOR UPDATE LOOP + UPDATE test1 SET b = b || ' ' || b WHERE a = r.a; + COMMIT; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 068 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 069 +SELECT * FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 070 +-- commit inside block with exception handler +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 071 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + COMMIT; + INSERT INTO test1 (a) VALUES (1/0); + COMMIT; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +STMT: DoStmt +== 072 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 073 +-- rollback inside block with exception handler +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 074 +DO LANGUAGE plpgsql $$ +BEGIN + BEGIN + INSERT INTO test1 (a) VALUES (1); + ROLLBACK; + INSERT INTO test1 (a) VALUES (1/0); + ROLLBACK; + EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + END; +END; +$$ +-- +STMT: DoStmt +== 075 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 076 +-- test commit/rollback inside exception handler, too +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 077 +DO LANGUAGE plpgsql $$ +BEGIN + FOR i IN 1..10 LOOP + BEGIN + INSERT INTO test1 VALUES (i, 'good'); + INSERT INTO test1 VALUES (i/0, 'bad'); + EXCEPTION + WHEN division_by_zero THEN + INSERT INTO test1 VALUES (i, 'exception'); + IF (i % 3) > 0 THEN COMMIT; ELSE ROLLBACK; END IF; + END; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 078 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 079 +-- detoast result of simple expression after commit +CREATE TEMP TABLE test4(f1 text) +-- +TABLE: name="test4" schema="" table="test4" ctx=DDL +STMT: CreateStmt +== 080 +ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL +-- +TABLE: name="test4" schema="" table="test4" ctx=DDL +STMT: AlterTableStmt +== 081 +-- disable compression +INSERT INTO test4 SELECT repeat('xyzzy', 2000) +-- +TABLE: name="test4" schema="" table="test4" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 082 +-- immutable mark is a bit of a lie, but it serves to make call a simple expr +-- that will return a still-toasted value +CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql +AS 'select f1 from test4' IMMUTABLE +-- +FUNCTION: name="data_source" function="data_source" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 083 +DO $$ +declare x text; +begin + for i in 1..3 loop + x := data_source(i); + commit; + end loop; + raise notice 'length(x) = %', length(x); +end $$ +-- +STMT: DoStmt +== 084 +-- operations on composite types vs. internal transactions +DO LANGUAGE plpgsql $$ +declare + c test1 := row(42, 'hello'); + r bool; +begin + for i in 1..3 loop + r := c is not null; + raise notice 'r = %', r; + commit; + end loop; + for i in 1..3 loop + r := c is null; + raise notice 'r = %', r; + rollback; + end loop; +end +$$ +-- +STMT: DoStmt +== 085 +-- COMMIT failures +DO LANGUAGE plpgsql $$ +BEGIN + CREATE TABLE test3 (y int UNIQUE DEFERRABLE INITIALLY DEFERRED); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + COMMIT; + INSERT INTO test3 (y) VALUES (1); + INSERT INTO test3 (y) VALUES (2); + COMMIT; + INSERT INTO test3 (y) VALUES (3); -- won't get here +END; +$$ +-- +STMT: DoStmt +== 086 +SELECT * FROM test3 +-- +TABLE: name="test3" schema="" table="test3" ctx=Select +STMT: SelectStmt +== 087 +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$ +-- +FUNCTION: name="cursor_fail_during_commit" function="cursor_fail_during_commit" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 088 +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 089 +CALL cursor_fail_during_commit() +-- +FUNCTION: name="cursor_fail_during_commit" function="cursor_fail_during_commit" schema="" ctx=Call +STMT: CallStmt +== 090 +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 091 +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$ +-- +FUNCTION: name="cursor_fail_during_rollback" function="cursor_fail_during_rollback" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 092 +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 093 +CALL cursor_fail_during_rollback() +-- +FUNCTION: name="cursor_fail_during_rollback" function="cursor_fail_during_rollback" schema="" ctx=Call +STMT: CallStmt +== 094 +SELECT count(*) FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 095 +-- SET TRANSACTION +DO LANGUAGE plpgsql $$ +BEGIN + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; + SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + PERFORM 1; + RAISE INFO '%', current_setting('transaction_isolation'); + COMMIT; +END; +$$ +-- +STMT: DoStmt +== 096 +-- error cases +DO LANGUAGE plpgsql $$ +BEGIN + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +END; +$$ +-- +STMT: DoStmt +== 097 +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$ +-- +STMT: DoStmt +== 098 +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$ +-- +STMT: DoStmt +== 099 +-- snapshot handling test +TRUNCATE test2 +-- +TABLE: name="test2" schema="" table="test2" ctx=DDL +STMT: TruncateStmt +== 100 +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$ +-- +FUNCTION: name="transaction_test9" function="transaction_test9" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 101 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$ +-- +STMT: DoStmt +== 102 +SELECT * FROM test2 +-- +TABLE: name="test2" schema="" table="test2" ctx=Select +STMT: SelectStmt +== 103 +-- another snapshot handling case: argument expressions of a CALL need +-- to be evaluated with an up-to-date snapshot +CREATE FUNCTION report_count() RETURNS int +STABLE LANGUAGE sql +AS $$ SELECT COUNT(*) FROM test2 $$ +-- +FUNCTION: name="report_count" function="report_count" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 104 +CREATE PROCEDURE transaction_test9b(cnt int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'count = %', cnt; +END +$$ +-- +FUNCTION: name="transaction_test9b" function="transaction_test9b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 105 +DO $$ +BEGIN + CALL transaction_test9b(report_count()); + INSERT INTO test2 VALUES(43); + CALL transaction_test9b(report_count()); +END +$$ +-- +STMT: DoStmt +== 106 +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$ +-- +FUNCTION: name="transaction_test10a" function="transaction_test10a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 107 +CALL transaction_test10a(10) +-- +FUNCTION: name="transaction_test10a" function="transaction_test10a" schema="" ctx=Call +STMT: CallStmt +== 108 +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$ +-- +FUNCTION: name="transaction_test10b" function="transaction_test10b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 109 +CALL transaction_test10b(10) +-- +FUNCTION: name="transaction_test10b" function="transaction_test10b" schema="" ctx=Call +STMT: CallStmt +== 110 +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$ +-- +FUNCTION: name="transaction_test11" function="transaction_test11" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 111 +CALL transaction_test11() +-- +FUNCTION: name="transaction_test11" function="transaction_test11" schema="" ctx=Call +STMT: CallStmt +== 112 +-- transaction chain + +TRUNCATE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: TruncateStmt +== 113 +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$ +-- +STMT: DoStmt +== 114 +SELECT * FROM test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: SelectStmt +== 115 +DROP TABLE test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: DropStmt +== 116 +DROP TABLE test2 +-- +TABLE: name="test2" schema="" table="test2" ctx=DDL +STMT: DropStmt +== 117 +DROP TABLE test3 +-- +TABLE: name="test3" schema="" table="test3" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json new file mode 100644 index 0000000..6e8763d --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json @@ -0,0 +1,46 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_trap.test b/parser/testdata/summary/plpgsql_regress/plpgsql_trap.test new file mode 100644 index 0000000..91f9b48 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_trap.test @@ -0,0 +1,329 @@ +== 001 +|-- +-- Test error trapping +|-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +FUNCTION: name="trap_zero_divide" function="trap_zero_divide" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +select trap_zero_divide(50) +-- +FUNCTION: name="trap_zero_divide" function="trap_zero_divide" schema="" ctx=Call +STMT: SelectStmt +== 003 +select trap_zero_divide(0) +-- +FUNCTION: name="trap_zero_divide" function="trap_zero_divide" schema="" ctx=Call +STMT: SelectStmt +== 004 +select trap_zero_divide(100000) +-- +FUNCTION: name="trap_zero_divide" function="trap_zero_divide" schema="" ctx=Call +STMT: SelectStmt +== 005 +select trap_zero_divide(-100) +-- +FUNCTION: name="trap_zero_divide" function="trap_zero_divide" schema="" ctx=Call +STMT: SelectStmt +== 006 +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x +-- +TABLE: name="match_source" schema="" table="match_source" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 007 +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql +-- +FUNCTION: name="trap_matching_test" function="trap_matching_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 008 +select trap_matching_test(50) +-- +FUNCTION: name="trap_matching_test" function="trap_matching_test" schema="" ctx=Call +STMT: SelectStmt +== 009 +select trap_matching_test(0) +-- +FUNCTION: name="trap_matching_test" function="trap_matching_test" schema="" ctx=Call +STMT: SelectStmt +== 010 +select trap_matching_test(100000) +-- +FUNCTION: name="trap_matching_test" function="trap_matching_test" schema="" ctx=Call +STMT: SelectStmt +== 011 +select trap_matching_test(1) +-- +FUNCTION: name="trap_matching_test" function="trap_matching_test" schema="" ctx=Call +STMT: SelectStmt +== 012 +create temp table foo (f1 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 013 +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql +-- +FUNCTION: name="subxact_rollback_semantics" function="subxact_rollback_semantics" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 014 +select subxact_rollback_semantics() +-- +FUNCTION: name="subxact_rollback_semantics" function="subxact_rollback_semantics" schema="" ctx=Call +STMT: SelectStmt +== 015 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 016 +drop table foo +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: DropStmt +== 017 +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1_000_000_000_000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql +-- +FUNCTION: name="trap_timeout" function="trap_timeout" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 018 +begin +-- +STMT: TransactionStmt +== 019 +set statement_timeout to 1000 +-- +STMT: VariableSetStmt +== 020 +select trap_timeout() +-- +FUNCTION: name="trap_timeout" function="trap_timeout" schema="" ctx=Call +STMT: SelectStmt +== 021 +rollback +-- +STMT: TransactionStmt +== 022 +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql +-- +FUNCTION: name="test_variable_storage" function="test_variable_storage" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 023 +select test_variable_storage() +-- +FUNCTION: name="test_variable_storage" function="test_variable_storage" schema="" ctx=Call +STMT: SelectStmt +== 024 +|-- +-- test foreign key error trapping +|-- + +create temp table root(f1 int primary key) +-- +TABLE: name="root" schema="" table="root" ctx=DDL +STMT: CreateStmt +== 025 +create temp table leaf(f1 int references root deferrable) +-- +TABLE: name="leaf" schema="" table="leaf" ctx=DDL +STMT: CreateStmt +== 026 +insert into root values(1) +-- +TABLE: name="root" schema="" table="root" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +insert into leaf values(1) +-- +TABLE: name="leaf" schema="" table="leaf" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +insert into leaf values(2) +-- +TABLE: name="leaf" schema="" table="leaf" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +-- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +FUNCTION: name="trap_foreign_key" function="trap_foreign_key" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 030 +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql +-- +FUNCTION: name="trap_foreign_key_2" function="trap_foreign_key_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 031 +select trap_foreign_key(1) +-- +FUNCTION: name="trap_foreign_key" function="trap_foreign_key" schema="" ctx=Call +STMT: SelectStmt +== 032 +select trap_foreign_key(2) +-- +FUNCTION: name="trap_foreign_key" function="trap_foreign_key" schema="" ctx=Call +STMT: SelectStmt +== 033 +-- detects FK violation + +begin +-- +STMT: TransactionStmt +== 034 +set constraints all deferred +-- +STMT: ConstraintsSetStmt +== 035 +select trap_foreign_key(2) +-- +FUNCTION: name="trap_foreign_key" function="trap_foreign_key" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- should not detect FK violation + savepoint x +-- +STMT: TransactionStmt +== 037 +set constraints all immediate +-- +STMT: ConstraintsSetStmt +== 038 +-- fails + rollback to x +-- +STMT: TransactionStmt +== 039 +select trap_foreign_key_2() +-- +FUNCTION: name="trap_foreign_key_2" function="trap_foreign_key_2" schema="" ctx=Call +STMT: SelectStmt +== 040 +-- detects FK violation +commit +-- +STMT: TransactionStmt +== 041 +-- still fails + +drop function trap_foreign_key(int) +-- +FUNCTION: name="trap_foreign_key" function="trap_foreign_key" schema="" ctx=DDL +STMT: DropStmt +== 042 +drop function trap_foreign_key_2() +-- +FUNCTION: name="trap_foreign_key_2" function="trap_foreign_key_2" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json new file mode 100644 index 0000000..980156f --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json @@ -0,0 +1,10 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.test b/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.test new file mode 100644 index 0000000..76e946b --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.test @@ -0,0 +1,44 @@ +== 001 +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text) +-- +TABLE: name="testtr" schema="" table="testtr" ctx=DDL +STMT: CreateStmt +== 002 +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$ +-- +FUNCTION: name="testtr_trigger" function="testtr_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger() +-- +TABLE: name="testtr" schema="" table="testtr" ctx=DDL +STMT: CreateTrigStmt +== 004 +insert into testtr values (1, 'one'), (2, 'two') +-- +TABLE: name="testtr" schema="" table="testtr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +update testtr set a = a + 1 +-- +TABLE: name="testtr" schema="" table="testtr" ctx=DML +STMT: UpdateStmt +== 006 +delete from testtr +-- +TABLE: name="testtr" schema="" table="testtr" ctx=DML +STMT: DeleteStmt diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json new file mode 100644 index 0000000..6a83420 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json @@ -0,0 +1,41 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037" + ] +} diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.test b/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.test new file mode 100644 index 0000000..ce18138 --- /dev/null +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.test @@ -0,0 +1,325 @@ +== 001 +|-- +-- Tests for PL/pgSQL variable properties: CONSTANT, NOT NULL, initializers +|-- + +create type var_record as (f1 int4, f2 int4) +-- +STMT: CompositeTypeStmt +== 002 +create domain int_nn as int not null +-- +STMT: CreateDomainStmt +== 003 +create domain var_record_nn as var_record not null +-- +STMT: CreateDomainStmt +== 004 +create domain var_record_colnn as var_record check((value).f2 is not null) +-- +STMT: CreateDomainStmt +== 005 +-- CONSTANT + +do $$ +declare x constant int := 42; +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 006 +do $$ +declare x constant int; +begin + x := 42; -- fail +end$$ +-- +STMT: DoStmt +== 007 +do $$ +declare x constant int; y int; +begin + for x, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +STMT: DoStmt +== 008 +do $$ +declare x constant int[]; +begin + x[1] := 42; -- fail +end$$ +-- +STMT: DoStmt +== 009 +do $$ +declare x constant int[]; y int; +begin + for x[1], y in select 1, 2 loop -- fail (currently, unsupported syntax) + end loop; +end$$ +-- +STMT: DoStmt +== 010 +do $$ +declare x constant var_record; +begin + x.f1 := 42; -- fail +end$$ +-- +STMT: DoStmt +== 011 +do $$ +declare x constant var_record; y int; +begin + for x.f1, y in select 1, 2 loop -- fail + end loop; +end$$ +-- +STMT: DoStmt +== 012 +-- initializer expressions + +do $$ +declare x int := sin(0); +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 013 +do $$ +declare x int := 1/0; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 014 +do $$ +declare x bigint[] := array[1,3,5]; +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 015 +do $$ +declare x record := row(1,2,3); +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 016 +do $$ +declare x var_record := row(1,2); +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 017 +-- NOT NULL + +do $$ +declare x int not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 018 +do $$ +declare x int not null := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +STMT: DoStmt +== 019 +do $$ +declare x int not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 020 +do $$ +declare x record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 021 +do $$ +declare x record not null := row(42); +begin + raise notice 'x = %', x; + x := row(null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +STMT: DoStmt +== 022 +do $$ +declare x record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 023 +do $$ +declare x var_record not null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 024 +do $$ +declare x var_record not null := row(41,42); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +STMT: DoStmt +== 025 +do $$ +declare x var_record not null := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 026 +-- Check that variables are reinitialized on block re-entry. + +do $$ +begin + for i in 1..3 loop + declare + x int; + y int := i; + r record; + c var_record; + begin + if i = 1 then + x := 42; + r := row(i, i+1); + c := row(i, i+1); + end if; + raise notice 'x = %', x; + raise notice 'y = %', y; + raise notice 'r = %', r; + raise notice 'c = %', c; + end; + end loop; +end$$ +-- +STMT: DoStmt +== 027 +-- Check enforcement of domain constraints during initialization + +do $$ +declare x int_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 028 +do $$ +declare x int_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 029 +do $$ +declare x int_nn := 42; +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +STMT: DoStmt +== 030 +do $$ +declare x var_record_nn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 031 +do $$ +declare x var_record_nn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 032 +do $$ +declare x var_record_nn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- ok + x := null; -- fail +end$$ +-- +STMT: DoStmt +== 033 +do $$ +declare x var_record_colnn; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 034 +do $$ +declare x var_record_colnn := null; -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 035 +do $$ +declare x var_record_colnn := row(1,null); -- fail +begin + raise notice 'x = %', x; +end$$ +-- +STMT: DoStmt +== 036 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := null; -- fail +end$$ +-- +STMT: DoStmt +== 037 +do $$ +declare x var_record_colnn := row(1,2); +begin + raise notice 'x = %', x; + x := row(null,null); -- fail +end$$ +-- +STMT: DoStmt diff --git a/parser/testdata/summary/postgres_regress/advisory_lock.metadata.json b/parser/testdata/summary/postgres_regress/advisory_lock.metadata.json new file mode 100644 index 0000000..251a33e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/advisory_lock.metadata.json @@ -0,0 +1,42 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038" + ] +} diff --git a/parser/testdata/summary/postgres_regress/advisory_lock.test b/parser/testdata/summary/postgres_regress/advisory_lock.test new file mode 100644 index 0000000..40a45f9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/advisory_lock.test @@ -0,0 +1,333 @@ +== 001 +|-- +-- ADVISORY LOCKS +|-- + +SELECT oid AS datoid FROM pg_database WHERE datname = current_database() +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +== 002 +BEGIN +-- +STMT: TransactionStmt +== 003 +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- pg_advisory_unlock_all() shouldn't release xact locks +SELECT pg_advisory_unlock_all() +-- +FUNCTION: name="pg_advisory_unlock_all" function="pg_advisory_unlock_all" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- can't unlock xact locks +SELECT + pg_advisory_unlock(1), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- automatically release xact locks at commit +COMMIT +-- +STMT: TransactionStmt +== 009 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 010 +BEGIN +-- +STMT: TransactionStmt +== 011 +-- holding both session and xact locks on the same objects, xact first +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 013 +SELECT + pg_advisory_lock(1), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 014 +ROLLBACK +-- +STMT: TransactionStmt +== 015 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 016 +-- unlocking session locks +SELECT + pg_advisory_unlock(1), pg_advisory_unlock(1), + pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), + pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 018 +BEGIN +-- +STMT: TransactionStmt +== 019 +-- holding both session and xact locks on the same objects, session first +SELECT + pg_advisory_lock(1), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 021 +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 022 +ROLLBACK +-- +STMT: TransactionStmt +== 023 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +-- releasing all session locks +SELECT pg_advisory_unlock_all() +-- +FUNCTION: name="pg_advisory_unlock_all" function="pg_advisory_unlock_all" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +BEGIN +-- +STMT: TransactionStmt +== 027 +-- grabbing txn locks multiple times + +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock(1), + pg_advisory_xact_lock_shared(2), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock(1, 1), + pg_advisory_xact_lock_shared(2, 2), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +COMMIT +-- +STMT: TransactionStmt +== 030 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 031 +-- grabbing session locks multiple times + +SELECT + pg_advisory_lock(1), pg_advisory_lock(1), + pg_advisory_lock_shared(2), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock(1, 1), + pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 033 +SELECT + pg_advisory_unlock(1), pg_advisory_unlock(1), + pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), + pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 035 +-- .. and releasing them all at once + +SELECT + pg_advisory_lock(1), pg_advisory_lock(1), + pg_advisory_lock_shared(2), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock(1, 1), + pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 037 +SELECT pg_advisory_unlock_all() +-- +FUNCTION: name="pg_advisory_unlock_all" function="pg_advisory_unlock_all" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary/postgres_regress/aggregates.metadata.json b/parser/testdata/summary/postgres_regress/aggregates.metadata.json new file mode 100644 index 0000000..592c419 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/aggregates.metadata.json @@ -0,0 +1,518 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514" + ] +} diff --git a/parser/testdata/summary/postgres_regress/aggregates.test b/parser/testdata/summary/postgres_regress/aggregates.test new file mode 100644 index 0000000..810e78d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/aggregates.test @@ -0,0 +1,4009 @@ +== 001 +|-- +-- AGGREGATES +|-- + +-- directory paths are passed to us in environment variables + +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +== 002 +-- prepare some test data +CREATE TABLE aggtest ( + a int2, + b float4 +) +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=DDL +STMT: CreateStmt +== 003 +COPY aggtest FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +ANALYZE aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=DDL +STMT: VacuumStmt +== 005 +SELECT avg(four) AS avg_1 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100 +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 007 +SELECT any_value(v) FROM (VALUES (1), (2), (3)) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT any_value(v) FROM (VALUES (NULL)) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +== 009 +SELECT any_value(v) FROM (VALUES (NULL), (1), (2)) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT any_value(v) FROM (VALUES (array['hello', 'world'])) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +== 011 +-- In 7.1, avg(float4) is computed using float8 arithmetic. +-- Round the result to 3 digits to avoid platform-specific results. + +SELECT avg(b)::numeric(10,3) AS avg_107_943 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT avg(gpa) AS avg_3_4 FROM ONLY student +-- +TABLE: name="student" schema="" table="student" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT sum(four) AS sum_1500 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT sum(a) AS sum_198 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT sum(b) AS avg_431_773 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT sum(gpa) AS avg_6_8 FROM ONLY student +-- +TABLE: name="student" schema="" table="student" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT max(four) AS max_3 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT max(a) AS max_100 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT max(aggtest.b) AS max_324_78 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT max(student.gpa) AS max_3_7 FROM student +-- +TABLE: name="student" schema="" table="student" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT stddev_pop(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT stddev_samp(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT var_pop(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT var_samp(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT stddev_pop(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +== 026 +SELECT stddev_samp(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT var_pop(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT var_samp(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 029 +-- population variance is defined for a single tuple, sample variance +-- is not +SELECT var_pop(1.0::float8), var_samp(2.0::float8) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT stddev_pop(3.0::float8), stddev_samp(4.0::float8) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT var_pop('inf'::float8), var_samp('inf'::float8) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT stddev_pop('inf'::float8), stddev_samp('inf'::float8) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT var_pop('nan'::float8), var_samp('nan'::float8) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT stddev_pop('nan'::float8), stddev_samp('nan'::float8) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT var_pop(1.0::float4), var_samp(2.0::float4) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT stddev_pop(3.0::float4), stddev_samp(4.0::float4) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT var_pop('inf'::float4), var_samp('inf'::float4) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT stddev_pop('inf'::float4), stddev_samp('inf'::float4) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT var_pop('nan'::float4), var_samp('nan'::float4) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT stddev_pop('nan'::float4), stddev_samp('nan'::float4) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT var_pop(1.0::numeric), var_samp(2.0::numeric) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 042 +SELECT stddev_pop(3.0::numeric), stddev_samp(4.0::numeric) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT var_pop('inf'::numeric), var_samp('inf'::numeric) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT stddev_pop('inf'::numeric), stddev_samp('inf'::numeric) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 045 +SELECT var_pop('nan'::numeric), var_samp('nan'::numeric) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 046 +SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- verify correct results for null and NaN inputs +select sum(null::int4) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 048 +select sum(null::int8) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 049 +select sum(null::numeric) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 050 +select sum(null::float8) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 051 +select avg(null::int4) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 052 +select avg(null::int8) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 053 +select avg(null::numeric) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 054 +select avg(null::float8) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 055 +select sum('NaN'::numeric) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 056 +select avg('NaN'::numeric) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- verify correct results for infinite inputs +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('1'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 058 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('1')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('-infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 062 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('1'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('infinity'), ('1')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('-infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('-infinity'), ('-infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 067 +-- test accuracy with a large input offset +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (100000003), (100000004), (100000006), (100000007)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (7000000000005), (7000000000007)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 069 +-- SQL2003 binary aggregates +SELECT regr_count(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_count" function="regr_count" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT regr_sxx(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT regr_syy(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT regr_sxy(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +STMT: SelectStmt +== 073 +SELECT regr_avgx(b, a), regr_avgy(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_avgx" function="regr_avgx" schema="" ctx=Call +FUNCTION: name="regr_avgy" function="regr_avgy" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT regr_r2(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_r2" function="regr_r2" schema="" ctx=Call +STMT: SelectStmt +== 075 +SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_slope" function="regr_slope" schema="" ctx=Call +FUNCTION: name="regr_intercept" function="regr_intercept" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +== 077 +SELECT corr(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="corr" function="corr" schema="" ctx=Call +STMT: SelectStmt +== 078 +-- check single-tuple behavior +SELECT covar_pop(1::float8,2::float8), covar_samp(3::float8,4::float8) +-- +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +== 079 +SELECT covar_pop(1::float8,'inf'::float8), covar_samp(3::float8,'inf'::float8) +-- +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +== 080 +SELECT covar_pop(1::float8,'nan'::float8), covar_samp(3::float8,'nan'::float8) +-- +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +== 081 +-- test accum and combine functions directly +CREATE TABLE regr_test (x float8, y float8) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=DDL +STMT: CreateStmt +== 082 +INSERT INTO regr_test VALUES (10,150),(20,250),(30,350),(80,540),(100,200) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30,80) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 084 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT float8_accum('{4,140,2900}'::float8[], 100) +-- +FUNCTION: name="float8_accum" function="float8_accum" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT float8_regr_accum('{4,140,2900,1290,83075,15050}'::float8[], 200, 100) +-- +FUNCTION: name="float8_regr_accum" function="float8_regr_accum" schema="" ctx=Call +STMT: SelectStmt +== 087 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 088 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (80,100) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 089 +SELECT float8_combine('{3,60,200}'::float8[], '{0,0,0}'::float8[]) +-- +FUNCTION: name="float8_combine" function="float8_combine" schema="" ctx=Call +STMT: SelectStmt +== 090 +SELECT float8_combine('{0,0,0}'::float8[], '{2,180,200}'::float8[]) +-- +FUNCTION: name="float8_combine" function="float8_combine" schema="" ctx=Call +STMT: SelectStmt +== 091 +SELECT float8_combine('{3,60,200}'::float8[], '{2,180,200}'::float8[]) +-- +FUNCTION: name="float8_combine" function="float8_combine" schema="" ctx=Call +STMT: SelectStmt +== 092 +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{0,0,0,0,0,0}'::float8[]) +-- +FUNCTION: name="float8_regr_combine" function="float8_regr_combine" schema="" ctx=Call +STMT: SelectStmt +== 093 +SELECT float8_regr_combine('{0,0,0,0,0,0}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]) +-- +FUNCTION: name="float8_regr_combine" function="float8_regr_combine" schema="" ctx=Call +STMT: SelectStmt +== 094 +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]) +-- +FUNCTION: name="float8_regr_combine" function="float8_regr_combine" schema="" ctx=Call +STMT: SelectStmt +== 095 +DROP TABLE regr_test +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=DDL +STMT: DropStmt +== 096 +-- test count, distinct +SELECT count(four) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 097 +SELECT count(DISTINCT four) AS cnt_4 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 098 +select ten, count(*), sum(four) from onek +group by ten order by ten +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 099 +select ten, count(four), sum(DISTINCT four) from onek +group by ten order by ten +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 100 +-- user-defined aggregates +SELECT newavg(four) AS avg_1 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newavg" function="newavg" schema="" ctx=Call +STMT: SelectStmt +== 101 +SELECT newsum(four) AS sum_1500 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newsum" function="newsum" schema="" ctx=Call +STMT: SelectStmt +== 102 +SELECT newcnt(four) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newcnt" function="newcnt" schema="" ctx=Call +STMT: SelectStmt +== 103 +SELECT newcnt(*) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newcnt" function="newcnt" schema="" ctx=Call +STMT: SelectStmt +== 104 +SELECT oldcnt(*) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="oldcnt" function="oldcnt" schema="" ctx=Call +STMT: SelectStmt +== 105 +SELECT sum2(q1,q2) FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="sum2" function="sum2" schema="" ctx=Call +STMT: SelectStmt +== 106 +-- test for outer-level aggregates + +-- this should work +select ten, sum(distinct four) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +== 107 +-- this should fail because subquery has an agg of its own in WHERE +select ten, sum(distinct four) from onek a +group by ten +having exists (select 1 from onek b + where sum(distinct a.four + b.four) = b.four) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +== 108 +-- Test handling of sublinks within outer-level aggregates. +-- Per bug report from Daniel Grace. +select + (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1))) +from tenk1 o +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i"="tenk1" +ALIAS: "o"="tenk1" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +STMT: SelectStmt +== 109 +-- Test handling of Params within aggregate arguments in hashed aggregation. +-- Per bug report from Jeevan Chalke. +explain (verbose, costs off) +select s1, s2, sm +from generate_series(1, 3) s1, + lateral (select s2, sum(s1 + s2) sm + from generate_series(1, 3) s2 group by s2) ss +order by 1, 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 110 +select s1, s2, sm +from generate_series(1, 3) s1, + lateral (select s2, sum(s1 + s2) sm + from generate_series(1, 3) s2 group by s2) ss +order by 1, 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 111 +explain (verbose, costs off) +select array(select sum(x+y) s + from generate_series(1,3) y group by y order by s) + from generate_series(1,3) x +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 112 +select array(select sum(x+y) s + from generate_series(1,3) y group by y order by s) + from generate_series(1,3) x +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 113 +|-- +-- test for bitwise integer aggregates +|-- +CREATE TEMPORARY TABLE bitwise_test( + i2 INT2, + i4 INT4, + i8 INT8, + i INTEGER, + x INT2, + y BIT(4) +) +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=DDL +STMT: CreateStmt +== 114 +-- empty case +SELECT + BIT_AND(i2) AS "?", + BIT_OR(i4) AS "?", + BIT_XOR(i8) AS "?" +FROM bitwise_test +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=Select +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +STMT: SelectStmt +== 115 +COPY bitwise_test FROM STDIN NULL 'null' +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=Select +STMT: CopyStmt +== 116 +SELECT + BIT_AND(i2) AS "1", + BIT_AND(i4) AS "1", + BIT_AND(i8) AS "1", + BIT_AND(i) AS "?", + BIT_AND(x) AS "0", + BIT_AND(y) AS "0100", + + BIT_OR(i2) AS "7", + BIT_OR(i4) AS "7", + BIT_OR(i8) AS "7", + BIT_OR(i) AS "?", + BIT_OR(x) AS "7", + BIT_OR(y) AS "1101", + + BIT_XOR(i2) AS "5", + BIT_XOR(i4) AS "5", + BIT_XOR(i8) AS "5", + BIT_XOR(i) AS "?", + BIT_XOR(x) AS "7", + BIT_XOR(y) AS "1101" +FROM bitwise_test +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=Select +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +STMT: SelectStmt +== 117 +|-- +-- test boolean aggregates +|-- +-- first test all possible transition and final states + +SELECT + -- boolean and transitions + -- null because strict + booland_statefunc(NULL, NULL) IS NULL AS "t", + booland_statefunc(TRUE, NULL) IS NULL AS "t", + booland_statefunc(FALSE, NULL) IS NULL AS "t", + booland_statefunc(NULL, TRUE) IS NULL AS "t", + booland_statefunc(NULL, FALSE) IS NULL AS "t", + -- and actual computations + booland_statefunc(TRUE, TRUE) AS "t", + NOT booland_statefunc(TRUE, FALSE) AS "t", + NOT booland_statefunc(FALSE, TRUE) AS "t", + NOT booland_statefunc(FALSE, FALSE) AS "t" +-- +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +STMT: SelectStmt +== 118 +SELECT + -- boolean or transitions + -- null because strict + boolor_statefunc(NULL, NULL) IS NULL AS "t", + boolor_statefunc(TRUE, NULL) IS NULL AS "t", + boolor_statefunc(FALSE, NULL) IS NULL AS "t", + boolor_statefunc(NULL, TRUE) IS NULL AS "t", + boolor_statefunc(NULL, FALSE) IS NULL AS "t", + -- actual computations + boolor_statefunc(TRUE, TRUE) AS "t", + boolor_statefunc(TRUE, FALSE) AS "t", + boolor_statefunc(FALSE, TRUE) AS "t", + NOT boolor_statefunc(FALSE, FALSE) AS "t" +-- +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +STMT: SelectStmt +== 119 +CREATE TEMPORARY TABLE bool_test( + b1 BOOL, + b2 BOOL, + b3 BOOL, + b4 BOOL) +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=DDL +STMT: CreateStmt +== 120 +-- empty case +SELECT + BOOL_AND(b1) AS "n", + BOOL_OR(b3) AS "n" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +== 121 +COPY bool_test FROM STDIN NULL 'null' +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +STMT: CopyStmt +== 122 +SELECT + BOOL_AND(b1) AS "f", + BOOL_AND(b2) AS "t", + BOOL_AND(b3) AS "f", + BOOL_AND(b4) AS "n", + BOOL_AND(NOT b2) AS "f", + BOOL_AND(NOT b3) AS "t" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +STMT: SelectStmt +== 123 +SELECT + EVERY(b1) AS "f", + EVERY(b2) AS "t", + EVERY(b3) AS "f", + EVERY(b4) AS "n", + EVERY(NOT b2) AS "f", + EVERY(NOT b3) AS "t" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +STMT: SelectStmt +== 124 +SELECT + BOOL_OR(b1) AS "t", + BOOL_OR(b2) AS "t", + BOOL_OR(b3) AS "f", + BOOL_OR(b4) AS "n", + BOOL_OR(NOT b2) AS "f", + BOOL_OR(NOT b3) AS "t" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +== 125 +|-- +-- Test cases that should be optimized into indexscans instead of +-- the generic aggregate implementation. +|-- + +-- Basic cases +explain (costs off) + select min(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 126 +select min(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 127 +explain (costs off) + select max(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 128 +select max(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 129 +explain (costs off) + select max(unique1) from tenk1 where unique1 < 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 130 +select max(unique1) from tenk1 where unique1 < 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 131 +explain (costs off) + select max(unique1) from tenk1 where unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 132 +select max(unique1) from tenk1 where unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 133 +-- the planner may choose a generic aggregate here if parallel query is +-- enabled, since that plan will be parallel safe and the "optimized" +-- plan, which has almost identical cost, will not be. we want to test +-- the optimized plan, so temporarily disable parallel query. +begin +-- +STMT: TransactionStmt +== 134 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 135 +explain (costs off) + select max(unique1) from tenk1 where unique1 > 42000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 136 +select max(unique1) from tenk1 where unique1 > 42000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 137 +rollback +-- +STMT: TransactionStmt +== 138 +-- multi-column index (uses tenk1_thous_tenthous) +explain (costs off) + select max(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 139 +select max(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 140 +explain (costs off) + select min(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 141 +select min(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 142 +-- check parameter propagation into an indexscan subquery +explain (costs off) + select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt + from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 143 +select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt + from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 144 +-- check some cases that were handled incorrectly in 8.3.0 +explain (costs off) + select distinct max(unique2) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 145 +select distinct max(unique2) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 146 +explain (costs off) + select max(unique2) from tenk1 order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 147 +select max(unique2) from tenk1 order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 148 +explain (costs off) + select max(unique2) from tenk1 order by max(unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 149 +select max(unique2) from tenk1 order by max(unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 150 +explain (costs off) + select max(unique2) from tenk1 order by max(unique2)+1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 151 +select max(unique2) from tenk1 order by max(unique2)+1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 152 +explain (costs off) + select max(unique2), generate_series(1,3) as g from tenk1 order by g desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 153 +select max(unique2), generate_series(1,3) as g from tenk1 order by g desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 154 +-- interesting corner case: constant gets optimized into a seqscan +explain (costs off) + select max(100) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 155 +select max(100) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 156 +-- try it on an inheritance tree +create table minmaxtest(f1 int) +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DDL +STMT: CreateStmt +== 157 +create table minmaxtest1() inherits (minmaxtest) +-- +TABLE: name="minmaxtest1" schema="" table="minmaxtest1" ctx=DDL +STMT: CreateStmt +== 158 +create table minmaxtest2() inherits (minmaxtest) +-- +TABLE: name="minmaxtest2" schema="" table="minmaxtest2" ctx=DDL +STMT: CreateStmt +== 159 +create table minmaxtest3() inherits (minmaxtest) +-- +TABLE: name="minmaxtest3" schema="" table="minmaxtest3" ctx=DDL +STMT: CreateStmt +== 160 +create index minmaxtesti on minmaxtest(f1) +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DDL +STMT: IndexStmt +== 161 +create index minmaxtest1i on minmaxtest1(f1) +-- +TABLE: name="minmaxtest1" schema="" table="minmaxtest1" ctx=DDL +STMT: IndexStmt +== 162 +create index minmaxtest2i on minmaxtest2(f1 desc) +-- +TABLE: name="minmaxtest2" schema="" table="minmaxtest2" ctx=DDL +STMT: IndexStmt +== 163 +create index minmaxtest3i on minmaxtest3(f1) where f1 is not null +-- +TABLE: name="minmaxtest3" schema="" table="minmaxtest3" ctx=DDL +STMT: IndexStmt +== 164 +insert into minmaxtest values(11), (12) +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +insert into minmaxtest1 values(13), (14) +-- +TABLE: name="minmaxtest1" schema="" table="minmaxtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +insert into minmaxtest2 values(15), (16) +-- +TABLE: name="minmaxtest2" schema="" table="minmaxtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 167 +insert into minmaxtest3 values(17), (18) +-- +TABLE: name="minmaxtest3" schema="" table="minmaxtest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +explain (costs off) + select min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 169 +select min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 170 +-- DISTINCT doesn't do anything useful here, but it shouldn't fail +explain (costs off) + select distinct min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 171 +select distinct min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 172 +drop table minmaxtest cascade +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DDL +STMT: DropStmt +== 173 +-- DISTINCT can also trigger wrong answers with hash aggregation (bug #18465) +begin +-- +STMT: TransactionStmt +== 174 +set local enable_sort = off +-- +STMT: VariableSetStmt +== 175 +explain (costs off) + select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1) + from int4_tbl t0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t0"="int4_tbl" +ALIAS: "t1"="int4_tbl" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="t0" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 176 +select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1) +from int4_tbl t0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t0"="int4_tbl" +ALIAS: "t1"="int4_tbl" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="t0" column="f1" +STMT: SelectStmt +== 177 +rollback +-- +STMT: TransactionStmt +== 178 +-- check for correct detection of nested-aggregate errors +select max(min(unique1)) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 179 +select (select max(min(unique1)) from int8_tbl) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 180 +select avg((select avg(a1.col1 order by (select avg(a2.col2) from tenk1 a3)) + from tenk1 a1(col1))) +from tenk1 a2(col2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a1"="tenk1" +ALIAS: "a2"="tenk1" +ALIAS: "a3"="tenk1" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 181 +|-- +-- Test removal of redundant GROUP BY columns +|-- + +create temp table t1 (a int, b int, c int, d int, primary key (a, b)) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 182 +create temp table t2 (x int, y int, z int, primary key (x, y)) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 183 +create temp table t3 (a int, b int, c int, primary key(a, b) deferrable) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +== 184 +-- Non-primary-key columns can be removed from GROUP BY +explain (costs off) select * from t1 group by a,b,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 185 +-- No removal can happen if the complete PK is not present in GROUP BY +explain (costs off) select a,c from t1 group by a,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 186 +-- Test removal across multiple relations +explain (costs off) select * +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.y,t2.z +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 187 +-- Test case where t1 can be optimized but not t2 +explain (costs off) select t1.*,t2.x,t2.z +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 188 +-- Cannot optimize when PK is deferrable +explain (costs off) select * from t3 group by a,b,c +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 189 +create temp table t1c () inherits (t1) +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: CreateStmt +== 190 +-- Ensure we don't remove any columns when t1 has a child table +explain (costs off) select * from t1 group by a,b,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 191 +-- Okay to remove columns if we're only querying the parent. +explain (costs off) select * from only t1 group by a,b,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 192 +create temp table p_t1 ( + a int, + b int, + c int, + d int, + primary key(a,b) +) partition by list(a) +-- +TABLE: name="p_t1" schema="" table="p_t1" ctx=DDL +STMT: CreateStmt +== 193 +create temp table p_t1_1 partition of p_t1 for values in(1) +-- +TABLE: name="p_t1_1" schema="" table="p_t1_1" ctx=DDL +STMT: CreateStmt +== 194 +create temp table p_t1_2 partition of p_t1 for values in(2) +-- +TABLE: name="p_t1_2" schema="" table="p_t1_2" ctx=DDL +STMT: CreateStmt +== 195 +-- Ensure we can remove non-PK columns for partitioned tables. +explain (costs off) select * from p_t1 group by a,b,c,d +-- +TABLE: name="p_t1" schema="" table="p_t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 196 +drop table t1 cascade +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 197 +drop table t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +== 198 +drop table t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: DropStmt +== 199 +drop table p_t1 +-- +TABLE: name="p_t1" schema="" table="p_t1" ctx=DDL +STMT: DropStmt +== 200 +|-- +-- Test GROUP BY matching of join columns that are type-coerced due to USING +|-- + +create temp table t1(f1 int, f2 int) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 201 +create temp table t2(f1 bigint, f2 oid) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 202 +select f1 from t1 left join t2 using (f1) group by f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 203 +select f1 from t1 left join t2 using (f1) group by t1.f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 204 +select t1.f1 from t1 left join t2 using (f1) group by t1.f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 205 +-- only this one should fail: +select t1.f1 from t1 left join t2 using (f1) group by f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 206 +-- check case where we have to inject nullingrels into coerced join alias +select f1, count(*) from +t1 x(x0,x1) left join (t1 left join t2 using(f1)) on (x0 = 0) +group by f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "x"="t1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 207 +-- same, for a RelabelType coercion +select f2, count(*) from +t1 x(x0,x1) left join (t1 left join t2 using(f2)) on (x0 = 0) +group by f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "x"="t1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 208 +drop table t1, t2 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +== 209 +|-- +-- Test planner's selection of pathkeys for ORDER BY aggregates +|-- + +-- Ensure we order by four. This suits the most aggregate functions. +explain (costs off) +select sum(two order by two),max(four order by four), min(four order by four) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 210 +-- Ensure we order by two. It's a tie between ordering by two and four but +-- we tiebreak on the aggregate's position. +explain (costs off) +select + sum(two order by two), max(four order by four), + min(four order by four), max(two order by two) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 211 +-- Similar to above, but tiebreak on ordering by four +explain (costs off) +select + max(four order by four), sum(two order by two), + min(four order by four), max(two order by two) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 212 +-- Ensure this one orders by ten since there are 3 aggregates that require ten +-- vs two that suit two and four. +explain (costs off) +select + max(four order by four), sum(two order by two), + min(four order by four), max(two order by two), + sum(ten order by ten), min(ten order by ten), max(ten order by ten) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 213 +-- Try a case involving a GROUP BY clause where the GROUP BY column is also +-- part of an aggregate's ORDER BY clause. We want a sort order that works +-- for the GROUP BY along with the first and the last aggregate. +explain (costs off) +select + sum(unique1 order by ten, two), sum(unique1 order by four), + sum(unique1 order by two, four) +from tenk1 +group by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 214 +-- Ensure that we never choose to provide presorted input to an Aggref with +-- a volatile function in the ORDER BY / DISTINCT clause. We want to ensure +-- these sorts are performed individually rather than at the query level. +explain (costs off) +select + sum(unique1 order by two), sum(unique1 order by four), + sum(unique1 order by four, two), sum(unique1 order by two, random()), + sum(unique1 order by two, random(), random() + 1) +from tenk1 +group by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 215 +-- Ensure consecutive NULLs are properly treated as distinct from each other +select array_agg(distinct val) +from (select null as val from generate_series(1, 2)) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 216 +-- Ensure no ordering is requested when enable_presorted_aggregate is off +set enable_presorted_aggregate to off +-- +STMT: VariableSetStmt +== 217 +explain (costs off) +select sum(two order by two) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 218 +reset enable_presorted_aggregate +-- +STMT: VariableSetStmt +== 219 +|-- +-- Test cases with FILTER clause +|-- + +-- Ensure we presort when the aggregate contains plain Vars +explain (costs off) +select sum(two order by two) filter (where two > 1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 220 +-- Ensure we presort for RelabelType'd Vars +explain (costs off) +select string_agg(distinct f1, ',') filter (where length(f1) > 1) +from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 221 +-- Ensure we don't presort when the aggregate's argument contains an +-- explicit cast. +explain (costs off) +select string_agg(distinct f1::varchar(2), ',') filter (where length(f1) > 1) +from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 222 +|-- +-- Test combinations of DISTINCT and/or ORDER BY +|-- + +select array_agg(a order by b) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 223 +select array_agg(a order by a) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 224 +select array_agg(a order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 225 +select array_agg(b order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 226 +select array_agg(distinct a) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 227 +select array_agg(distinct a order by a) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 228 +select array_agg(distinct a order by a desc) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 229 +select array_agg(distinct a order by a desc nulls last) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 230 +-- multi-arg aggs, strict/nonstrict, distinct/order by + +select aggfstr(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +FUNCTION: name="aggfstr" function="aggfstr" schema="" ctx=Call +STMT: SelectStmt +== 231 +select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: SelectStmt +== 232 +select aggfstr(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfstr" function="aggfstr" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 233 +select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 234 +select aggfstr(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfstr" function="aggfstr" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 235 +select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 236 +-- test specific code paths + +select aggfns(distinct a,a,c order by c using ~<~,a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 237 +select aggfns(distinct a,a,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 238 +select aggfns(distinct a,a,c order by a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 239 +select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 240 +-- test a more complex permutation that has previous caused issues +select + string_agg(distinct 'a', ','), + sum(( + select sum(1) + from (values(1)) b(id) + where a.id = b.id +)) from unnest(array[1]) a(id) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="b" column="id" +STMT: SelectStmt +== 241 +-- check node I/O via view creation and usage, also deparsing logic + +create view agg_view1 as + select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 242 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +== 243 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 244 +create or replace view agg_view1 as + select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 245 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +== 246 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 247 +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 248 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +== 249 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 250 +create or replace view agg_view1 as + select aggfns(a,b,c order by b+1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 251 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +== 252 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 253 +create or replace view agg_view1 as + select aggfns(a,a,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 254 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +== 255 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 256 +create or replace view agg_view1 as + select aggfns(a,b,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 257 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +== 258 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 259 +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 260 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +== 261 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 262 +drop view agg_view1 +-- +STMT: DropStmt +== 263 +-- incorrect DISTINCT usage errors + +select aggfns(distinct a,b,c order by i) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 264 +select aggfns(distinct a,b,c order by a,b+1) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 265 +select aggfns(distinct a,b,c order by a,b,i,c) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 266 +select aggfns(distinct a,a,c order by a,b) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 267 +-- string_agg tests +select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 268 +select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 269 +select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 270 +select string_agg(a,',') from (values(null),(null)) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 271 +-- check some implicit casting cases, as per bug #5564 +select string_agg(distinct f1, ',' order by f1) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 272 +-- ok +select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 273 +-- not ok +select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 274 +-- not ok +select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 275 +-- ok + +-- string_agg bytea tests +create table bytea_test_table(v bytea) +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DDL +STMT: CreateStmt +== 276 +select string_agg(v, '') from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 277 +insert into bytea_test_table values(decode('ff','hex')) +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DML +FUNCTION: name="decode" function="decode" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 278 +select string_agg(v, '') from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 279 +insert into bytea_test_table values(decode('aa','hex')) +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DML +FUNCTION: name="decode" function="decode" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 280 +select string_agg(v, '') from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 281 +select string_agg(v, NULL) from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 282 +select string_agg(v, decode('ee', 'hex')) from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="decode" function="decode" schema="" ctx=Call +STMT: SelectStmt +== 283 +drop table bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DDL +STMT: DropStmt +== 284 +-- Test parallel string_agg and array_agg +create table pagg_test (x int, y int) with (autovacuum_enabled = off) +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=DDL +STMT: CreateStmt +== 285 +insert into pagg_test +select (case x % 4 when 1 then null else x end), x % 10 +from generate_series(1,5000) x +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 286 +set parallel_setup_cost TO 0 +-- +STMT: VariableSetStmt +== 287 +set parallel_tuple_cost TO 0 +-- +STMT: VariableSetStmt +== 288 +set parallel_leader_participation TO 0 +-- +STMT: VariableSetStmt +== 289 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 290 +set bytea_output = 'escape' +-- +STMT: VariableSetStmt +== 291 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 292 +-- create a view as we otherwise have to repeat this query a few times. +create view v_pagg_test AS +select + y, + min(t) AS tmin,max(t) AS tmax,count(distinct t) AS tndistinct, + min(b) AS bmin,max(b) AS bmax,count(distinct b) AS bndistinct, + min(a) AS amin,max(a) AS amax,count(distinct a) AS andistinct, + min(aa) AS aamin,max(aa) AS aamax,count(distinct aa) AS aandistinct +from ( + select + y, + unnest(regexp_split_to_array(a1.t, ','))::int AS t, + unnest(regexp_split_to_array(a1.b::text, ',')) AS b, + unnest(a1.a) AS a, + unnest(a1.aa) AS aa + from ( + select + y, + string_agg(x::text, ',') AS t, + string_agg(x::text::bytea, ',') AS b, + array_agg(x) AS a, + array_agg(ARRAY[x]) AS aa + from pagg_test + group by y + ) a1 +) a2 +group by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=DDL +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="regexp_split_to_array" function="regexp_split_to_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="regexp_split_to_array" function="regexp_split_to_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 293 +-- Ensure results are correct. +select * from v_pagg_test order by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=Select +STMT: SelectStmt +== 294 +-- Ensure parallel aggregation is actually being used. +explain (costs off) select * from v_pagg_test order by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 295 +-- Ensure results are the same without parallel aggregation. +set max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 296 +select * from v_pagg_test order by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=Select +STMT: SelectStmt +== 297 +-- Check that we don't fail on anonymous record types. +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 298 +explain (costs off) +select array_dims(array_agg(s)) from (select * from pagg_test) s +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 299 +select array_dims(array_agg(s)) from (select * from pagg_test) s +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 300 +-- Clean up +reset max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +== 301 +reset bytea_output +-- +STMT: VariableSetStmt +== 302 +reset min_parallel_table_scan_size +-- +STMT: VariableSetStmt +== 303 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +== 304 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +== 305 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +== 306 +drop view v_pagg_test +-- +STMT: DropStmt +== 307 +drop table pagg_test +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=DDL +STMT: DropStmt +== 308 +-- FILTER tests + +select min(unique1) filter (where unique1 > 100) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 309 +select sum(1/ten) filter (where ten > 0) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 310 +select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +group by ten +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 311 +select ten, sum(distinct four) filter (where four > 10) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +== 312 +select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') +from (values ('a', 'b')) AS v(foo,bar) +-- +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 313 +select any_value(v) filter (where v > 2) from (values (1), (2), (3)) as v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +== 314 +-- outer reference in FILTER (PostgreSQL extension) +select (select count(*) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 315 +-- inner query is aggregation query +select (select count(*) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 316 +-- outer query is aggregation query +select (select count(inner_c) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 317 +-- inner query is aggregation query +select + (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)) + filter (where o.unique1 < 10)) +from tenk1 o +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i"="tenk1" +ALIAS: "o"="tenk1" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +STMT: SelectStmt +== 318 +-- outer query is aggregation query + +-- subquery in FILTER clause (PostgreSQL extension) +select sum(unique1) FILTER (WHERE + unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 319 +-- exercise lots of aggregate parts with FILTER +select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 320 +-- check handling of bare boolean Var in FILTER +select max(0) filter (where b1) from bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 321 +select (select max(0) filter (where b1)) from bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 322 +-- check for correct detection of nested-aggregate errors in FILTER +select max(unique1) filter (where sum(ten) > 0) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 323 +select (select max(unique1) filter (where sum(ten) > 0) from int8_tbl) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 324 +select max(unique1) filter (where bool_or(ten > 0)) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +== 325 +select (select max(unique1) filter (where bool_or(ten > 0)) from int8_tbl) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +== 326 +-- ordered-set aggregates + +select p, percentile_cont(p) within group (order by x::float8) +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 327 +select p, percentile_cont(p order by p) within group (order by x) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +ERROR: cannot use multiple ORDER BY clauses with WITHIN GROUP +CURSORPOS: 41 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 328 +select p, sum() within group (order by x::float8) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 329 +select p, percentile_cont(p,p) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 330 +select percentile_cont(0.5) within group (order by b) from aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +STMT: SelectStmt +== 331 +select percentile_cont(0.5) within group (order by b), sum(b) from aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 332 +select percentile_cont(0.5) within group (order by thousand) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +STMT: SelectStmt +== 333 +select percentile_disc(0.5) within group (order by thousand) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +== 334 +select rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 335 +select cume_dist(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="cume_dist" function="cume_dist" schema="" ctx=Call +STMT: SelectStmt +== 336 +select percent_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4),(5)) v(x) +-- +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +STMT: SelectStmt +== 337 +select dense_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +STMT: SelectStmt +== 338 +select percentile_disc(array[0,0.1,0.25,0.5,0.75,0.9,1]) within group (order by thousand) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +== 339 +select percentile_cont(array[0,0.25,0.5,0.75,1]) within group (order by thousand) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +STMT: SelectStmt +== 340 +select percentile_disc(array[[null,1,0.5],[0.75,0.25,null]]) within group (order by thousand) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +== 341 +select percentile_cont(array[0,1,0.25,0.75,0.5,1,0.3,0.32,0.35,0.38,0.4]) within group (order by x) +from generate_series(1,6) x +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 342 +select ten, mode() within group (order by string4) from tenk1 group by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="mode" function="mode" schema="" ctx=Call +STMT: SelectStmt +== 343 +select percentile_disc(array[0.25,0.5,0.75]) within group (order by x) +from unnest('{fred,jim,fred,jack,jill,fred,jill,jim,jim,sheila,jim,sheila}'::text[]) u(x) +-- +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 344 +-- check collation propagates up in suitable cases: +select pg_collation_for(percentile_disc(1) within group (order by x collate "POSIX")) + from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="pg_collation_for" function="pg_collation_for" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +== 345 +-- ordered-set aggs created with CREATE AGGREGATE +select test_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="test_rank" function="test_rank" schema="" ctx=Call +STMT: SelectStmt +== 346 +select test_percentile_disc(0.5) within group (order by thousand) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="test_percentile_disc" function="test_percentile_disc" schema="" ctx=Call +STMT: SelectStmt +== 347 +-- ordered-set aggs can't use ungrouped vars in direct args: +select rank(x) within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 348 +-- outer-level agg can't use a grouped arg of a lower level, either: +select array(select percentile_disc(a) within group (order by x) + from (values (0.3),(0.7)) v(a) group by a) + from generate_series(1,5) g(x) +-- +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 349 +-- agg in the direct args is a grouping violation, too: +select rank(sum(x)) within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 350 +-- hypothetical-set type unification and argument-count failures: +select rank(3) within group (order by x) from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 351 +select rank(3) within group (order by stringu1,stringu2) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 352 +select rank('fred') within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 353 +select rank('adam'::text collate "C") within group (order by x collate "POSIX") + from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 354 +-- hypothetical-set type unification successes: +select rank('adam'::varchar) within group (order by x) from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 355 +select rank('3') within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 356 +-- divide by zero check +select percent_rank(0) within group (order by x) from generate_series(1,0) x +-- +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 357 +-- deparse and multiple features: +create view aggordview1 as +select ten, + percentile_disc(0.5) within group (order by thousand) as p50, + percentile_disc(0.5) within group (order by thousand) filter (where hundred=1) as px, + rank(5,'AZZZZ',50) within group (order by hundred, string4 desc, hundred) + from tenk1 + group by ten order by ten +-- +TABLE: name="aggordview1" schema="" table="aggordview1" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 358 +select pg_get_viewdef('aggordview1') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 359 +select * from aggordview1 order by ten +-- +TABLE: name="aggordview1" schema="" table="aggordview1" ctx=Select +STMT: SelectStmt +== 360 +drop view aggordview1 +-- +STMT: DropStmt +== 361 +-- variadic aggregates +select least_agg(q1,q2) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="least_agg" function="least_agg" schema="" ctx=Call +STMT: SelectStmt +== 362 +select least_agg(variadic array[q1,q2]) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="least_agg" function="least_agg" schema="" ctx=Call +STMT: SelectStmt +== 363 +select cleast_agg(q1,q2) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +== 364 +select cleast_agg(4.5,f1) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +== 365 +select cleast_agg(variadic array[4.5,f1]) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +== 366 +select pg_typeof(cleast_agg(variadic array[4.5,f1])) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +== 367 +-- test aggregates with common transition functions share the same states +begin work +-- +STMT: TransactionStmt +== 368 +create type avg_state as (total bigint, count bigint) +-- +STMT: CompositeTypeStmt +== 369 +create or replace function avg_transfn(state avg_state, n int) returns avg_state as +$$ +declare new_state avg_state; +begin + raise notice 'avg_transfn called with %', n; + if state is null then + if n is not null then + new_state.total := n; + new_state.count := 1; + return new_state; + end if; + return null; + elsif n is not null then + state.total := state.total + n; + state.count := state.count + 1; + return state; + end if; + + return null; +end +$$ language plpgsql +-- +FUNCTION: name="avg_transfn" function="avg_transfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 370 +create function avg_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total / state.count; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="avg_finalfn" function="avg_finalfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 371 +create function sum_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="sum_finalfn" function="sum_finalfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 372 +create aggregate my_avg(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn +) +-- +STMT: DefineStmt +== 373 +create aggregate my_sum(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn +) +-- +STMT: DefineStmt +== 374 +-- aggregate state should be shared as aggs are the same. +select my_avg(one),my_avg(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +STMT: SelectStmt +== 375 +-- aggregate state should be shared as transfn is the same for both aggs. +select my_avg(one),my_sum(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +== 376 +-- same as previous one, but with DISTINCT, which requires sorting the input. +select my_avg(distinct one),my_sum(distinct one) from (values(1),(3),(1)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +== 377 +-- shouldn't share states due to the distinctness not matching. +select my_avg(distinct one),my_sum(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +== 378 +-- shouldn't share states due to the filter clause not matching. +select my_avg(one) filter (where one > 1),my_sum(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +== 379 +-- this should not share the state due to different input columns. +select my_avg(one),my_sum(two) from (values(1,2),(3,4)) t(one,two) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +== 380 +-- exercise cases where OSAs share state +select + percentile_cont(0.5) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a) +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +== 381 +select + percentile_cont(0.25) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a) +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +== 382 +-- these can't share state currently +select + rank(4) within group (order by a), + dense_rank(4) within group (order by a) +from (values(1),(3),(5),(7)) t(a) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +STMT: SelectStmt +== 383 +-- test that aggs with the same sfunc and initcond share the same agg state +create aggregate my_sum_init(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn, + initcond = '(10,0)' +) +-- +STMT: DefineStmt +== 384 +create aggregate my_avg_init(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(10,0)' +) +-- +STMT: DefineStmt +== 385 +create aggregate my_avg_init2(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(4,0)' +) +-- +STMT: DefineStmt +== 386 +-- state should be shared if INITCONDs are matching +select my_sum_init(one),my_avg_init(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_sum_init" function="my_sum_init" schema="" ctx=Call +FUNCTION: name="my_avg_init" function="my_avg_init" schema="" ctx=Call +STMT: SelectStmt +== 387 +-- Varying INITCONDs should cause the states not to be shared. +select my_sum_init(one),my_avg_init2(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_sum_init" function="my_sum_init" schema="" ctx=Call +FUNCTION: name="my_avg_init2" function="my_avg_init2" schema="" ctx=Call +STMT: SelectStmt +== 388 +rollback +-- +STMT: TransactionStmt +== 389 +-- test aggregate state sharing to ensure it works if one aggregate has a +-- finalfn and the other one has none. +begin work +-- +STMT: TransactionStmt +== 390 +create or replace function sum_transfn(state int4, n int4) returns int4 as +$$ +declare new_state int4; +begin + raise notice 'sum_transfn called with %', n; + if state is null then + if n is not null then + new_state := n; + return new_state; + end if; + return null; + elsif n is not null then + state := state + n; + return state; + end if; + + return null; +end +$$ language plpgsql +-- +FUNCTION: name="sum_transfn" function="sum_transfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 391 +create function halfsum_finalfn(state int4) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state / 2; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="halfsum_finalfn" function="halfsum_finalfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 392 +create aggregate my_sum(int4) +( + stype = int4, + sfunc = sum_transfn +) +-- +STMT: DefineStmt +== 393 +create aggregate my_half_sum(int4) +( + stype = int4, + sfunc = sum_transfn, + finalfunc = halfsum_finalfn +) +-- +STMT: DefineStmt +== 394 +-- Agg state should be shared even though my_sum has no finalfn +select my_sum(one),my_half_sum(one) from (values(1),(2),(3),(4)) t(one) +-- +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +FUNCTION: name="my_half_sum" function="my_half_sum" schema="" ctx=Call +STMT: SelectStmt +== 395 +rollback +-- +STMT: TransactionStmt +== 396 +-- test that the aggregate transition logic correctly handles +-- transition / combine functions returning NULL + +-- First test the case of a normal transition function returning NULL +BEGIN +-- +STMT: TransactionStmt +== 397 +CREATE FUNCTION balkifnull(int8, int4) +RETURNS int8 +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$ +-- +FUNCTION: name="balkifnull" function="balkifnull" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 398 +CREATE AGGREGATE balk(int4) +( + SFUNC = balkifnull(int8, int4), + STYPE = int8, + PARALLEL = SAFE, + INITCOND = '0' +) +-- +STMT: DefineStmt +== 399 +SELECT balk(hundred) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="balk" function="balk" schema="" ctx=Call +STMT: SelectStmt +== 400 +ROLLBACK +-- +STMT: TransactionStmt +== 401 +-- GROUP BY optimization by reordering GROUP BY clauses +CREATE TABLE btg AS SELECT + i % 10 AS x, + i % 10 AS y, + 'abc' || i % 10 AS z, + i AS w +FROM generate_series(1, 100) AS i +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 402 +CREATE INDEX btg_x_y_idx ON btg(x, y) +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: IndexStmt +== 403 +ANALYZE btg +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: VacuumStmt +== 404 +SET enable_hashagg = off +-- +STMT: VariableSetStmt +== 405 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 406 +-- Utilize the ordering of index scan to avoid a Sort operation +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY y, x +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 407 +-- Engage incremental sort +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY z, y, w, x +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 408 +-- Utilize the ordering of subquery scan to avoid a Sort operation +EXPLAIN (COSTS OFF) SELECT count(*) +FROM (SELECT * FROM btg ORDER BY x, y, w, z) AS q1 +GROUP BY w, x, z, y +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 409 +-- Utilize the ordering of merge join to avoid a full Sort operation +SET enable_hashjoin = off +-- +STMT: VariableSetStmt +== 410 +SET enable_nestloop = off +-- +STMT: VariableSetStmt +== 411 +EXPLAIN (COSTS OFF) +SELECT count(*) + FROM btg t1 JOIN btg t2 ON t1.z = t2.z AND t1.w = t2.w AND t1.x = t2.x + GROUP BY t1.x, t1.y, t1.z, t1.w +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +TABLE: name="btg" schema="" table="btg" ctx=Select +ALIAS: "t1"="btg" +ALIAS: "t2"="btg" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 412 +RESET enable_nestloop +-- +STMT: VariableSetStmt +== 413 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 414 +-- Should work with and without GROUP-BY optimization +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY w, x, z, y ORDER BY y, x, z, w +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 415 +-- Utilize incremental sort to make the ORDER BY rule a bit cheaper +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY w, x, y, z ORDER BY x*x, z +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 416 +-- Test the case where the number of incoming subtree path keys is more than +-- the number of grouping keys. +CREATE INDEX btg_y_x_w_idx ON btg(y, x, w) +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: IndexStmt +== 417 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT y, x, array_agg(distinct w) + FROM btg WHERE y < 0 GROUP BY x, y +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 418 +-- Ensure that we do not select the aggregate pathkeys instead of the grouping +-- pathkeys +CREATE TABLE group_agg_pk AS SELECT + i % 10 AS x, + i % 2 AS y, + i % 2 AS z, + 2 AS w, + i % 10 AS f +FROM generate_series(1,100) AS i +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 419 +ANALYZE group_agg_pk +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=DDL +STMT: VacuumStmt +== 420 +SET enable_nestloop = off +-- +STMT: VariableSetStmt +== 421 +SET enable_hashjoin = off +-- +STMT: VariableSetStmt +== 422 +EXPLAIN (COSTS OFF) +SELECT avg(c1.f ORDER BY c1.x, c1.y) +FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x +GROUP BY c1.w, c1.z +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 423 +SELECT avg(c1.f ORDER BY c1.x, c1.y) +FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x +GROUP BY c1.w, c1.z +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 424 +-- Pathkeys, built in a subtree, can be used to optimize GROUP-BY clause +-- ordering. Also, here we check that it doesn't depend on the initial clause +-- order in the GROUP-BY list. +EXPLAIN (COSTS OFF) +SELECT c1.y,c1.x FROM group_agg_pk c1 + JOIN group_agg_pk c2 + ON c1.x = c2.x +GROUP BY c1.y,c1.x,c2.x +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +STMT: ExplainStmt +STMT: SelectStmt +== 425 +EXPLAIN (COSTS OFF) +SELECT c1.y,c1.x FROM group_agg_pk c1 + JOIN group_agg_pk c2 + ON c1.x = c2.x +GROUP BY c1.y,c2.x,c1.x +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +STMT: ExplainStmt +STMT: SelectStmt +== 426 +RESET enable_nestloop +-- +STMT: VariableSetStmt +== 427 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 428 +DROP TABLE group_agg_pk +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=DDL +STMT: DropStmt +== 429 +-- Test the case where the ordering of the scan matches the ordering within the +-- aggregate but cannot be found in the group-by list +CREATE TABLE agg_sort_order (c1 int PRIMARY KEY, c2 int) +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: CreateStmt +== 430 +CREATE UNIQUE INDEX agg_sort_order_c2_idx ON agg_sort_order(c2) +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: IndexStmt +== 431 +INSERT INTO agg_sort_order SELECT i, i FROM generate_series(1,100)i +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 432 +ANALYZE agg_sort_order +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: VacuumStmt +== 433 +EXPLAIN (COSTS OFF) +SELECT array_agg(c1 ORDER BY c2),c2 +FROM agg_sort_order WHERE c2 < 100 GROUP BY c1 ORDER BY 2 +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +== 434 +DROP TABLE agg_sort_order CASCADE +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: DropStmt +== 435 +DROP TABLE btg +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: DropStmt +== 436 +RESET enable_hashagg +-- +STMT: VariableSetStmt +== 437 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 438 +-- Secondly test the case of a parallel aggregate combiner function +-- returning NULL. For that use normal transition function, but a +-- combiner function returning NULL. +BEGIN +-- +STMT: TransactionStmt +== 439 +CREATE FUNCTION balkifnull(int8, int8) +RETURNS int8 +PARALLEL SAFE +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$ +-- +FUNCTION: name="balkifnull" function="balkifnull" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 440 +CREATE AGGREGATE balk(int4) +( + SFUNC = int4_sum(int8, int4), + STYPE = int8, + COMBINEFUNC = balkifnull(int8, int8), + PARALLEL = SAFE, + INITCOND = '0' +) +-- +STMT: DefineStmt +== 441 +-- force use of parallelism +ALTER TABLE tenk1 set (parallel_workers = 4) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +== 442 +SET LOCAL parallel_setup_cost=0 +-- +STMT: VariableSetStmt +== 443 +SET LOCAL max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +== 444 +EXPLAIN (COSTS OFF) SELECT balk(hundred) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="balk" function="balk" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 445 +SELECT balk(hundred) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="balk" function="balk" schema="" ctx=Call +STMT: SelectStmt +== 446 +ROLLBACK +-- +STMT: TransactionStmt +== 447 +-- test multiple usage of an aggregate whose finalfn returns a R/W datum +BEGIN +-- +STMT: TransactionStmt +== 448 +CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray +LANGUAGE plpgsql IMMUTABLE AS $$ +BEGIN + RETURN array_fill(y[1], ARRAY[4]); +END; +$$ +-- +FUNCTION: name="rwagg_sfunc" function="rwagg_sfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 449 +CREATE FUNCTION rwagg_finalfunc(x anyarray) RETURNS anyarray +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +DECLARE + res x%TYPE; +BEGIN + -- assignment is essential for this test, it expands the array to R/W + res := array_fill(x[1], ARRAY[4]); + RETURN res; +END; +$$ +-- +FUNCTION: name="rwagg_finalfunc" function="rwagg_finalfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 450 +CREATE AGGREGATE rwagg(anyarray) ( + STYPE = anyarray, + SFUNC = rwagg_sfunc, + FINALFUNC = rwagg_finalfunc +) +-- +STMT: DefineStmt +== 451 +CREATE FUNCTION eatarray(x real[]) RETURNS real[] +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +BEGIN + x[1] := x[1] + 1; + RETURN x; +END; +$$ +-- +FUNCTION: name="eatarray" function="eatarray" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 452 +SELECT eatarray(rwagg(ARRAY[1.0::real])), eatarray(rwagg(ARRAY[1.0::real])) +-- +FUNCTION: name="eatarray" function="eatarray" schema="" ctx=Call +FUNCTION: name="rwagg" function="rwagg" schema="" ctx=Call +FUNCTION: name="eatarray" function="eatarray" schema="" ctx=Call +FUNCTION: name="rwagg" function="rwagg" schema="" ctx=Call +STMT: SelectStmt +== 453 +ROLLBACK +-- +STMT: TransactionStmt +== 454 +-- test coverage for aggregate combine/serial/deserial functions +BEGIN +-- +STMT: TransactionStmt +== 455 +SET parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 456 +SET parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 457 +SET min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 458 +SET max_parallel_workers_per_gather = 4 +-- +STMT: VariableSetStmt +== 459 +SET parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 460 +SET enable_indexonlyscan = off +-- +STMT: VariableSetStmt +== 461 +-- variance(int4) covers numeric_poly_combine +-- sum(int8) covers int8_avg_combine +-- regr_count(float8, float8) covers int8inc_float8_float8 and aggregates with > 1 arg +EXPLAIN (COSTS OFF, VERBOSE) +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_count" function="regr_count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 462 +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_count" function="regr_count" schema="" ctx=Call +STMT: SelectStmt +== 463 +-- variance(int8) covers numeric_combine +-- avg(numeric) covers numeric_avg_combine +EXPLAIN (COSTS OFF, VERBOSE) +SELECT variance(unique1::int8), avg(unique1::numeric) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 464 +SELECT variance(unique1::int8), avg(unique1::numeric) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 465 +ROLLBACK +-- +STMT: TransactionStmt +== 466 +-- test coverage for dense_rank +SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (1),(1),(2),(2),(3),(3)) v(x) GROUP BY (x) ORDER BY 1 +-- +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +STMT: SelectStmt +== 467 +-- Ensure that the STRICT checks for aggregates does not take NULLness +-- of ORDER BY columns into account. See bug report around +-- 2a505161-2727-2473-7c46-591ed108ac52@email.cz +SELECT min(x ORDER BY y) FROM (VALUES(1, NULL)) AS d(x,y) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 468 +SELECT min(x ORDER BY y) FROM (VALUES(1, 2)) AS d(x,y) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 469 +-- check collation-sensitive matching between grouping expressions +select v||'a', case v||'a' when 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 470 +select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 471 +-- Make sure that generation of HashAggregate for uniqification purposes +-- does not lead to array overflow due to unexpected duplicate hash keys +-- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com +set enable_memoize to off +-- +STMT: VariableSetStmt +== 472 +explain (costs off) + select 1 from tenk1 + where (hundred, thousand) in (select twothousand, twothousand from onek) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 473 +reset enable_memoize +-- +STMT: VariableSetStmt +== 474 +|-- +-- Hash Aggregation Spill tests +|-- + +set enable_sort=false +-- +STMT: VariableSetStmt +== 475 +set work_mem='64kB' +-- +STMT: VariableSetStmt +== 476 +select unique1, count(*), sum(twothousand) from tenk1 +group by unique1 +having sum(fivethous) > 4975 +order by sum(twothousand) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 477 +set work_mem to default +-- +STMT: VariableSetStmt +== 478 +set enable_sort to default +-- +STMT: VariableSetStmt +== 479 +|-- +-- 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' +-- +STMT: VariableSetStmt +== 480 +create table agg_data_2k as +select g from generate_series(0, 1999) g +-- +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 481 +analyze agg_data_2k +-- +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=DDL +STMT: VacuumStmt +== 482 +create table agg_data_20k as +select g from generate_series(0, 19999) g +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 483 +analyze agg_data_20k +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=DDL +STMT: VacuumStmt +== 484 +-- Produce results with sorting. + +set enable_hashagg = false +-- +STMT: VariableSetStmt +== 485 +set jit_above_cost = 0 +-- +STMT: VariableSetStmt +== 486 +explain (costs off) +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000 +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 487 +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 +-- +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=DDL +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 488 +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 +-- +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="r" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 489 +set jit_above_cost to default +-- +STMT: VariableSetStmt +== 490 +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 +-- +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 491 +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 +-- +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 492 +-- Produce results with hash aggregation + +set enable_hashagg = true +-- +STMT: VariableSetStmt +== 493 +set enable_sort = false +-- +STMT: VariableSetStmt +== 494 +set jit_above_cost = 0 +-- +STMT: VariableSetStmt +== 495 +explain (costs off) +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000 +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 496 +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 +-- +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=DDL +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 497 +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 +-- +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="r" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 498 +set jit_above_cost to default +-- +STMT: VariableSetStmt +== 499 +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 +-- +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 500 +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 +-- +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 501 +set enable_sort = true +-- +STMT: VariableSetStmt +== 502 +set work_mem to default +-- +STMT: VariableSetStmt +== 503 +-- 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) +-- +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=Select +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=Select +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=Select +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=Select +STMT: SelectStmt +== 504 +(select * from agg_hash_2 except select * from agg_group_2) + union all +(select * from agg_group_2 except select * from agg_hash_2) +-- +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=Select +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=Select +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=Select +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=Select +STMT: SelectStmt +== 505 +(select * from agg_hash_3 except select * from agg_group_3) + union all +(select * from agg_group_3 except select * from agg_hash_3) +-- +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=Select +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=Select +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=Select +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=Select +STMT: SelectStmt +== 506 +(select * from agg_hash_4 except select * from agg_group_4) + union all +(select * from agg_group_4 except select * from agg_hash_4) +-- +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=Select +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=Select +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=Select +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=Select +STMT: SelectStmt +== 507 +drop table agg_group_1 +-- +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=DDL +STMT: DropStmt +== 508 +drop table agg_group_2 +-- +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=DDL +STMT: DropStmt +== 509 +drop table agg_group_3 +-- +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=DDL +STMT: DropStmt +== 510 +drop table agg_group_4 +-- +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=DDL +STMT: DropStmt +== 511 +drop table agg_hash_1 +-- +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=DDL +STMT: DropStmt +== 512 +drop table agg_hash_2 +-- +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=DDL +STMT: DropStmt +== 513 +drop table agg_hash_3 +-- +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=DDL +STMT: DropStmt +== 514 +drop table agg_hash_4 +-- +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/alter_generic.metadata.json b/parser/testdata/summary/postgres_regress/alter_generic.metadata.json new file mode 100644 index 0000000..d5998bc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/alter_generic.metadata.json @@ -0,0 +1,336 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332" + ] +} diff --git a/parser/testdata/summary/postgres_regress/alter_generic.test b/parser/testdata/summary/postgres_regress/alter_generic.test new file mode 100644 index 0000000..c208b9d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/alter_generic.test @@ -0,0 +1,1809 @@ +== 001 +|-- +-- Test for ALTER some_object {RENAME TO, OWNER TO, SET SCHEMA} +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION test_opclass_options_func(internal) + RETURNS void + AS :'regresslib', 'test_opclass_options_func' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 224 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- Clean up in case a prior regression run failed +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +== 003 +DROP ROLE IF EXISTS regress_alter_generic_user1 +-- +STMT: DropRoleStmt +== 004 +DROP ROLE IF EXISTS regress_alter_generic_user2 +-- +STMT: DropRoleStmt +== 005 +DROP ROLE IF EXISTS regress_alter_generic_user3 +-- +STMT: DropRoleStmt +== 006 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 007 +CREATE USER regress_alter_generic_user3 +-- +STMT: CreateRoleStmt +== 008 +CREATE USER regress_alter_generic_user2 +-- +STMT: CreateRoleStmt +== 009 +CREATE USER regress_alter_generic_user1 IN ROLE regress_alter_generic_user3 +-- +STMT: CreateRoleStmt +== 010 +CREATE SCHEMA alt_nsp1 +-- +STMT: CreateSchemaStmt +== 011 +CREATE SCHEMA alt_nsp2 +-- +STMT: CreateSchemaStmt +== 012 +GRANT ALL ON SCHEMA alt_nsp1, alt_nsp2 TO public +-- +STMT: GrantStmt +== 013 +SET search_path = alt_nsp1, public +-- +STMT: VariableSetStmt +== 014 +|-- +-- Function and Aggregate +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 015 +CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 + 1' +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 - 1' +-- +FUNCTION: name="alt_func2" function="alt_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +CREATE AGGREGATE alt_agg1 ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 0 +) +-- +STMT: DefineStmt +== 018 +CREATE AGGREGATE alt_agg2 ( + sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = 0 +) +-- +STMT: DefineStmt +== 019 +ALTER AGGREGATE alt_func1(int) RENAME TO alt_func3 +-- +STMT: RenameStmt +== 020 +-- failed (not aggregate) +ALTER AGGREGATE alt_func1(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 021 +-- failed (not aggregate) +ALTER AGGREGATE alt_func1(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 022 +-- failed (not aggregate) + +ALTER FUNCTION alt_func1(int) RENAME TO alt_func2 +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +FUNCTION: name="alt_func2" function="alt_func2" schema="" ctx=DDL +STMT: RenameStmt +== 023 +-- failed (name conflict) +ALTER FUNCTION alt_func1(int) RENAME TO alt_func3 +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +FUNCTION: name="alt_func3" function="alt_func3" schema="" ctx=DDL +STMT: RenameStmt +== 024 +-- OK +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 025 +-- failed (no role membership) +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 026 +-- OK +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp1 +-- +STMT: AlterObjectSchemaStmt +== 027 +-- OK, already there +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 028 +-- OK + +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg2 +-- +STMT: RenameStmt +== 029 +-- failed (name conflict) +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg3 +-- +STMT: RenameStmt +== 030 +-- OK +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 031 +-- failed (no role membership) +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 032 +-- OK +ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 033 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +== 034 +CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 + 2' +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 035 +CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 - 2' +-- +FUNCTION: name="alt_func2" function="alt_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +CREATE AGGREGATE alt_agg1 ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 100 +) +-- +STMT: DefineStmt +== 037 +CREATE AGGREGATE alt_agg2 ( + sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = -100 +) +-- +STMT: DefineStmt +== 038 +ALTER FUNCTION alt_func3(int) RENAME TO alt_func4 +-- +FUNCTION: name="alt_func3" function="alt_func3" schema="" ctx=DDL +FUNCTION: name="alt_func4" function="alt_func4" schema="" ctx=DDL +STMT: RenameStmt +== 039 +-- failed (not owner) +ALTER FUNCTION alt_func1(int) RENAME TO alt_func4 +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +FUNCTION: name="alt_func4" function="alt_func4" schema="" ctx=DDL +STMT: RenameStmt +== 040 +-- OK +ALTER FUNCTION alt_func3(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 041 +-- failed (not owner) +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 042 +-- failed (no role membership) +ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 043 +-- failed (not owner) +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 044 +-- failed (name conflicts) + +ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4 +-- +STMT: RenameStmt +== 045 +-- failed (not owner) +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4 +-- +STMT: RenameStmt +== 046 +-- OK +ALTER AGGREGATE alt_agg3(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 047 +-- failed (not owner) +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 048 +-- failed (no role membership) +ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 049 +-- failed (not owner) +ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 050 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 051 +SELECT n.nspname, proname, prorettype::regtype, prokind, a.rolname + FROM pg_proc p, pg_namespace n, pg_authid a + WHERE p.pronamespace = n.oid AND p.proowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="p" column="pronamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="p" column="proowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 052 +|-- +-- We would test collations here, but it's not possible because the error +-- messages tend to be nonportable. +|-- + +|-- +-- Conversion +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 053 +CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 054 +CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 055 +ALTER CONVERSION alt_conv1 RENAME TO alt_conv2 +-- +STMT: RenameStmt +== 056 +-- failed (name conflict) +ALTER CONVERSION alt_conv1 RENAME TO alt_conv3 +-- +STMT: RenameStmt +== 057 +-- OK +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 058 +-- failed (no role membership) +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 059 +-- OK +ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 060 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +== 061 +CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 062 +CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 063 +ALTER CONVERSION alt_conv3 RENAME TO alt_conv4 +-- +STMT: RenameStmt +== 064 +-- failed (not owner) +ALTER CONVERSION alt_conv1 RENAME TO alt_conv4 +-- +STMT: RenameStmt +== 065 +-- OK +ALTER CONVERSION alt_conv3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 066 +-- failed (not owner) +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 067 +-- failed (no role membership) +ALTER CONVERSION alt_conv3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 068 +-- failed (not owner) +ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 069 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 070 +SELECT n.nspname, c.conname, a.rolname + FROM pg_conversion c, pg_namespace n, pg_authid a + WHERE c.connamespace = n.oid AND c.conowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, conname +-- +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "c"="pg_conversion" +ALIAS: "n"="pg_namespace" +FILTER: schema="" table="c" column="connamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="c" column="conowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 071 +|-- +-- Foreign Data Wrapper and Foreign Server +|-- +CREATE FOREIGN DATA WRAPPER alt_fdw1 +-- +STMT: CreateFdwStmt +== 072 +CREATE FOREIGN DATA WRAPPER alt_fdw2 +-- +STMT: CreateFdwStmt +== 073 +CREATE SERVER alt_fserv1 FOREIGN DATA WRAPPER alt_fdw1 +-- +STMT: CreateForeignServerStmt +== 074 +CREATE SERVER alt_fserv2 FOREIGN DATA WRAPPER alt_fdw2 +-- +STMT: CreateForeignServerStmt +== 075 +ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw2 +-- +STMT: RenameStmt +== 076 +-- failed (name conflict) +ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw3 +-- +STMT: RenameStmt +== 077 +-- OK + +ALTER SERVER alt_fserv1 RENAME TO alt_fserv2 +-- +STMT: RenameStmt +== 078 +-- failed (name conflict) +ALTER SERVER alt_fserv1 RENAME TO alt_fserv3 +-- +STMT: RenameStmt +== 079 +-- OK + +SELECT fdwname FROM pg_foreign_data_wrapper WHERE fdwname like 'alt_fdw%' +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +== 080 +SELECT srvname FROM pg_foreign_server WHERE srvname like 'alt_fserv%' +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +== 081 +|-- +-- Procedural Language +|-- +CREATE LANGUAGE alt_lang1 HANDLER plpgsql_call_handler +-- +STMT: CreatePLangStmt +== 082 +CREATE LANGUAGE alt_lang2 HANDLER plpgsql_call_handler +-- +STMT: CreatePLangStmt +== 083 +ALTER LANGUAGE alt_lang1 OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +== 084 +-- OK +ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 085 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 086 +ALTER LANGUAGE alt_lang1 RENAME TO alt_lang2 +-- +STMT: RenameStmt +== 087 +-- failed (name conflict) +ALTER LANGUAGE alt_lang2 RENAME TO alt_lang3 +-- +STMT: RenameStmt +== 088 +-- failed (not owner) +ALTER LANGUAGE alt_lang1 RENAME TO alt_lang3 +-- +STMT: RenameStmt +== 089 +-- OK + +ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 090 +-- failed (not owner) +ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 091 +-- failed (no role membership) +ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 092 +-- OK + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 093 +SELECT lanname, a.rolname + FROM pg_language l, pg_authid a + WHERE l.lanowner = a.oid AND l.lanname like 'alt_lang%' + ORDER BY lanname +-- +TABLE: name="pg_language" schema="" table="pg_language" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "l"="pg_language" +FILTER: schema="" table="l" column="lanowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="l" column="lanname" +STMT: SelectStmt +== 094 +|-- +-- Operator +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 095 +CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi ) +-- +STMT: DefineStmt +== 096 +CREATE OPERATOR @+@ ( leftarg = int4, rightarg = int4, procedure = int4pl ) +-- +STMT: DefineStmt +== 097 +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 098 +-- failed (no role membership) +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 099 +-- OK +ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +== 101 +CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi ) +-- +STMT: DefineStmt +== 102 +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 103 +-- failed (not owner) +ALTER OPERATOR @-@(int4, int4) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 104 +-- failed (no role membership) +ALTER OPERATOR @+@(int4, int4) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 105 +-- failed (not owner) +-- can't test this: the error message includes the raw oid of namespace +-- ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2; -- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 106 +SELECT n.nspname, oprname, a.rolname, + oprleft::regtype, oprright::regtype, oprcode::regproc + FROM pg_operator o, pg_namespace n, pg_authid a + WHERE o.oprnamespace = n.oid AND o.oprowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, oprname +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "o"="pg_operator" +FILTER: schema="" table="o" column="oprnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="o" column="oprowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 107 +|-- +-- OpFamily and OpClass +|-- +CREATE OPERATOR FAMILY alt_opf1 USING hash +-- +STMT: CreateOpFamilyStmt +== 108 +CREATE OPERATOR FAMILY alt_opf2 USING hash +-- +STMT: CreateOpFamilyStmt +== 109 +ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +== 110 +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +== 111 +CREATE OPERATOR CLASS alt_opc1 FOR TYPE uuid USING hash AS STORAGE uuid +-- +STMT: CreateOpClassStmt +== 112 +CREATE OPERATOR CLASS alt_opc2 FOR TYPE uuid USING hash AS STORAGE uuid +-- +STMT: CreateOpClassStmt +== 113 +ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +== 114 +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +== 115 +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 116 +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf2 +-- +STMT: RenameStmt +== 117 +-- failed (name conflict) +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf3 +-- +STMT: RenameStmt +== 118 +-- OK +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 119 +-- failed (no role membership) +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 120 +-- OK +ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 121 +-- OK + +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc2 +-- +STMT: RenameStmt +== 122 +-- failed (name conflict) +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc3 +-- +STMT: RenameStmt +== 123 +-- OK +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 124 +-- failed (no role membership) +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 125 +-- OK +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 126 +-- OK + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 127 +CREATE OPERATOR FAMILY alt_opf1 USING hash +-- +STMT: CreateOpFamilyStmt +== 128 +CREATE OPERATOR FAMILY alt_opf2 USING hash +-- +STMT: CreateOpFamilyStmt +== 129 +ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 130 +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 131 +CREATE OPERATOR CLASS alt_opc1 FOR TYPE macaddr USING hash AS STORAGE macaddr +-- +STMT: CreateOpClassStmt +== 132 +CREATE OPERATOR CLASS alt_opc2 FOR TYPE macaddr USING hash AS STORAGE macaddr +-- +STMT: CreateOpClassStmt +== 133 +ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 134 +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 135 +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +== 136 +ALTER OPERATOR FAMILY alt_opf3 USING hash RENAME TO alt_opf4 +-- +STMT: RenameStmt +== 137 +-- failed (not owner) +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf4 +-- +STMT: RenameStmt +== 138 +-- OK +ALTER OPERATOR FAMILY alt_opf3 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 139 +-- failed (not owner) +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 140 +-- failed (no role membership) +ALTER OPERATOR FAMILY alt_opf3 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 141 +-- failed (not owner) +ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 142 +-- failed (name conflict) + +ALTER OPERATOR CLASS alt_opc3 USING hash RENAME TO alt_opc4 +-- +STMT: RenameStmt +== 143 +-- failed (not owner) +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc4 +-- +STMT: RenameStmt +== 144 +-- OK +ALTER OPERATOR CLASS alt_opc3 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 145 +-- failed (not owner) +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 146 +-- failed (no role membership) +ALTER OPERATOR CLASS alt_opc3 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 147 +-- failed (not owner) +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 148 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 149 +SELECT nspname, opfname, amname, rolname + FROM pg_opfamily o, pg_am m, pg_namespace n, pg_authid a + WHERE o.opfmethod = m.oid AND o.opfnamespace = n.oid AND o.opfowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + AND NOT opfname LIKE 'alt_opc%' + ORDER BY nspname, opfname +-- +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "m"="pg_am" +ALIAS: "n"="pg_namespace" +ALIAS: "o"="pg_opfamily" +FILTER: schema="" table="o" column="opfmethod" +FILTER: schema="" table="m" column="oid" +FILTER: schema="" table="o" column="opfnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="o" column="opfowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +FILTER: schema="" table="" column="opfname" +STMT: SelectStmt +== 150 +SELECT nspname, opcname, amname, rolname + FROM pg_opclass o, pg_am m, pg_namespace n, pg_authid a + WHERE o.opcmethod = m.oid AND o.opcnamespace = n.oid AND o.opcowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, opcname +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "m"="pg_am" +ALIAS: "n"="pg_namespace" +ALIAS: "o"="pg_opclass" +FILTER: schema="" table="o" column="opcmethod" +FILTER: schema="" table="m" column="oid" +FILTER: schema="" table="o" column="opcnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="o" column="opcowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 151 +-- ALTER OPERATOR FAMILY ... ADD/DROP + +-- Should work. Textbook case of CREATE / ALTER ADD / ALTER DROP / DROP +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 152 +CREATE OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: CreateOpFamilyStmt +== 153 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD + -- int4 vs int2 + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 154 +ALTER OPERATOR FAMILY alt_opf4 USING btree DROP + -- int4 vs int2 + OPERATOR 1 (int4, int2) , + OPERATOR 2 (int4, int2) , + OPERATOR 3 (int4, int2) , + OPERATOR 4 (int4, int2) , + OPERATOR 5 (int4, int2) , + FUNCTION 1 (int4, int2) +-- +STMT: AlterOpFamilyStmt +== 155 +DROP OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: DropStmt +== 156 +ROLLBACK +-- +STMT: TransactionStmt +== 157 +-- Should fail. Invalid values for ALTER OPERATOR FAMILY .. ADD / DROP +CREATE OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: CreateOpFamilyStmt +== 158 +ALTER OPERATOR FAMILY alt_opf4 USING invalid_index_method ADD OPERATOR 1 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +== 159 +-- invalid indexing_method +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 6 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +== 160 +-- operator number should be between 1 and 5 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 0 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +== 161 +-- operator number should be between 1 and 5 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 1 < +-- +STMT: AlterOpFamilyStmt +== 162 +-- operator without argument types +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 0 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 163 +-- invalid options parsing function +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 6 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 164 +-- function number should be between 1 and 5 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD STORAGE invalid_storage +-- +STMT: AlterOpFamilyStmt +== 165 +-- Ensure STORAGE is not a part of ALTER OPERATOR FAMILY +DROP OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: DropStmt +== 166 +-- Should fail. Need to be SUPERUSER to do ALTER OPERATOR FAMILY .. ADD / DROP +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 167 +CREATE ROLE regress_alter_generic_user5 NOSUPERUSER +-- +STMT: CreateRoleStmt +== 168 +CREATE OPERATOR FAMILY alt_opf5 USING btree +-- +STMT: CreateOpFamilyStmt +== 169 +SET ROLE regress_alter_generic_user5 +-- +STMT: VariableSetStmt +== 170 +ALTER OPERATOR FAMILY alt_opf5 USING btree ADD OPERATOR 1 < (int4, int2), FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 171 +RESET ROLE +-- +STMT: VariableSetStmt +== 172 +DROP OPERATOR FAMILY alt_opf5 USING btree +-- +STMT: DropStmt +== 173 +ROLLBACK +-- +STMT: TransactionStmt +== 174 +-- Should fail. Need rights to namespace for ALTER OPERATOR FAMILY .. ADD / DROP +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 175 +CREATE ROLE regress_alter_generic_user6 +-- +STMT: CreateRoleStmt +== 176 +CREATE SCHEMA alt_nsp6 +-- +STMT: CreateSchemaStmt +== 177 +REVOKE ALL ON SCHEMA alt_nsp6 FROM regress_alter_generic_user6 +-- +STMT: GrantStmt +== 178 +CREATE OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree +-- +STMT: CreateOpFamilyStmt +== 179 +SET ROLE regress_alter_generic_user6 +-- +STMT: VariableSetStmt +== 180 +ALTER OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree ADD OPERATOR 1 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +== 181 +ROLLBACK +-- +STMT: TransactionStmt +== 182 +-- Should fail. Only two arguments required for ALTER OPERATOR FAMILY ... DROP OPERATOR +CREATE OPERATOR FAMILY alt_opf7 USING btree +-- +STMT: CreateOpFamilyStmt +== 183 +ALTER OPERATOR FAMILY alt_opf7 USING btree ADD OPERATOR 1 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +== 184 +ALTER OPERATOR FAMILY alt_opf7 USING btree DROP OPERATOR 1 (int4, int2, int8) +-- +STMT: AlterOpFamilyStmt +== 185 +DROP OPERATOR FAMILY alt_opf7 USING btree +-- +STMT: DropStmt +== 186 +-- Should work. During ALTER OPERATOR FAMILY ... DROP OPERATOR +-- when left type is the same as right type, a DROP with only one argument type should work +CREATE OPERATOR FAMILY alt_opf8 USING btree +-- +STMT: CreateOpFamilyStmt +== 187 +ALTER OPERATOR FAMILY alt_opf8 USING btree ADD OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 188 +DROP OPERATOR FAMILY alt_opf8 USING btree +-- +STMT: DropStmt +== 189 +-- Should work. Textbook case of ALTER OPERATOR FAMILY ... ADD OPERATOR with FOR ORDER BY +CREATE OPERATOR FAMILY alt_opf9 USING gist +-- +STMT: CreateOpFamilyStmt +== 190 +ALTER OPERATOR FAMILY alt_opf9 USING gist ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops +-- +STMT: AlterOpFamilyStmt +== 191 +DROP OPERATOR FAMILY alt_opf9 USING gist +-- +STMT: DropStmt +== 192 +-- Should fail. Ensure correct ordering methods in ALTER OPERATOR FAMILY ... ADD OPERATOR .. FOR ORDER BY +CREATE OPERATOR FAMILY alt_opf10 USING btree +-- +STMT: CreateOpFamilyStmt +== 193 +ALTER OPERATOR FAMILY alt_opf10 USING btree ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops +-- +STMT: AlterOpFamilyStmt +== 194 +DROP OPERATOR FAMILY alt_opf10 USING btree +-- +STMT: DropStmt +== 195 +-- Should work. Textbook case of ALTER OPERATOR FAMILY ... ADD OPERATOR with FOR ORDER BY +CREATE OPERATOR FAMILY alt_opf11 USING gist +-- +STMT: CreateOpFamilyStmt +== 196 +ALTER OPERATOR FAMILY alt_opf11 USING gist ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops +-- +STMT: AlterOpFamilyStmt +== 197 +ALTER OPERATOR FAMILY alt_opf11 USING gist DROP OPERATOR 1 (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 198 +DROP OPERATOR FAMILY alt_opf11 USING gist +-- +STMT: DropStmt +== 199 +-- Should fail. btree comparison functions should return INTEGER in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 200 +CREATE OPERATOR FAMILY alt_opf12 USING btree +-- +STMT: CreateOpFamilyStmt +== 201 +CREATE FUNCTION fn_opf12 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf12" function="fn_opf12" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 202 +ALTER OPERATOR FAMILY alt_opf12 USING btree ADD FUNCTION 1 fn_opf12(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 203 +DROP OPERATOR FAMILY alt_opf12 USING btree +-- +STMT: DropStmt +== 204 +ROLLBACK +-- +STMT: TransactionStmt +== 205 +-- Should fail. hash comparison functions should return INTEGER in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 206 +CREATE OPERATOR FAMILY alt_opf13 USING hash +-- +STMT: CreateOpFamilyStmt +== 207 +CREATE FUNCTION fn_opf13 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf13" function="fn_opf13" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 208 +ALTER OPERATOR FAMILY alt_opf13 USING hash ADD FUNCTION 1 fn_opf13(int4) +-- +STMT: AlterOpFamilyStmt +== 209 +DROP OPERATOR FAMILY alt_opf13 USING hash +-- +STMT: DropStmt +== 210 +ROLLBACK +-- +STMT: TransactionStmt +== 211 +-- Should fail. btree comparison functions should have two arguments in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 212 +CREATE OPERATOR FAMILY alt_opf14 USING btree +-- +STMT: CreateOpFamilyStmt +== 213 +CREATE FUNCTION fn_opf14 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf14" function="fn_opf14" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 214 +ALTER OPERATOR FAMILY alt_opf14 USING btree ADD FUNCTION 1 fn_opf14(int4) +-- +STMT: AlterOpFamilyStmt +== 215 +DROP OPERATOR FAMILY alt_opf14 USING btree +-- +STMT: DropStmt +== 216 +ROLLBACK +-- +STMT: TransactionStmt +== 217 +-- Should fail. hash comparison functions should have one argument in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 218 +CREATE OPERATOR FAMILY alt_opf15 USING hash +-- +STMT: CreateOpFamilyStmt +== 219 +CREATE FUNCTION fn_opf15 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf15" function="fn_opf15" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 220 +ALTER OPERATOR FAMILY alt_opf15 USING hash ADD FUNCTION 1 fn_opf15(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 221 +DROP OPERATOR FAMILY alt_opf15 USING hash +-- +STMT: DropStmt +== 222 +ROLLBACK +-- +STMT: TransactionStmt +== 223 +-- Should fail. In gist throw an error when giving different data types for function argument +-- without defining left / right type in ALTER OPERATOR FAMILY ... ADD FUNCTION +CREATE OPERATOR FAMILY alt_opf16 USING gist +-- +STMT: CreateOpFamilyStmt +== 224 +ALTER OPERATOR FAMILY alt_opf16 USING gist ADD FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 225 +DROP OPERATOR FAMILY alt_opf16 USING gist +-- +STMT: DropStmt +== 226 +-- Should fail. duplicate operator number / function number in ALTER OPERATOR FAMILY ... ADD FUNCTION +CREATE OPERATOR FAMILY alt_opf17 USING btree +-- +STMT: CreateOpFamilyStmt +== 227 +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4), OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 228 +-- operator # appears twice in same statement +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 229 +-- operator 1 requested first-time +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 230 +-- operator 1 requested again in separate statement +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 231 +-- procedure 1 appears twice in same statement +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 232 +-- procedure 1 appears first time +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 233 +-- procedure 1 requested again in separate statement +DROP OPERATOR FAMILY alt_opf17 USING btree +-- +STMT: DropStmt +== 234 +-- Should fail. Ensure that DROP requests for missing OPERATOR / FUNCTIONS +-- return appropriate message in ALTER OPERATOR FAMILY ... DROP OPERATOR / FUNCTION +CREATE OPERATOR FAMILY alt_opf18 USING btree +-- +STMT: CreateOpFamilyStmt +== 235 +ALTER OPERATOR FAMILY alt_opf18 USING btree DROP OPERATOR 1 (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 236 +ALTER OPERATOR FAMILY alt_opf18 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 237 +-- Should fail. Not allowed to have cross-type equalimage function. +ALTER OPERATOR FAMILY alt_opf18 USING btree + ADD FUNCTION 4 (int4, int2) btequalimage(oid) +-- +STMT: AlterOpFamilyStmt +== 238 +ALTER OPERATOR FAMILY alt_opf18 USING btree DROP FUNCTION 2 (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 239 +DROP OPERATOR FAMILY alt_opf18 USING btree +-- +STMT: DropStmt +== 240 +-- Should fail. Invalid opclass options function (#5) specifications. +CREATE OPERATOR FAMILY alt_opf19 USING btree +-- +STMT: CreateOpFamilyStmt +== 241 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 test_opclass_options_func(internal, text[], bool) +-- +STMT: AlterOpFamilyStmt +== 242 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 243 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4, int2) btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +== 244 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) test_opclass_options_func(internal) +-- +STMT: AlterOpFamilyStmt +== 245 +-- Ok +ALTER OPERATOR FAMILY alt_opf19 USING btree DROP FUNCTION 5 (int4, int4) +-- +STMT: AlterOpFamilyStmt +== 246 +DROP OPERATOR FAMILY alt_opf19 USING btree +-- +STMT: DropStmt +== 247 +|-- +-- Statistics +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 248 +CREATE TABLE alt_regress_1 (a INTEGER, b INTEGER) +-- +TABLE: name="alt_regress_1" schema="" table="alt_regress_1" ctx=DDL +STMT: CreateStmt +== 249 +CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_1 +-- +STMT: CreateStatsStmt +== 250 +CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_1 +-- +STMT: CreateStatsStmt +== 251 +ALTER STATISTICS alt_stat1 RENAME TO alt_stat2 +-- +STMT: RenameStmt +== 252 +-- failed (name conflict) +ALTER STATISTICS alt_stat1 RENAME TO alt_stat3 +-- +STMT: RenameStmt +== 253 +-- OK +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 254 +-- failed (no role membership) +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 255 +-- OK +ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 256 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +== 257 +CREATE TABLE alt_regress_2 (a INTEGER, b INTEGER) +-- +TABLE: name="alt_regress_2" schema="" table="alt_regress_2" ctx=DDL +STMT: CreateStmt +== 258 +CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_2 +-- +STMT: CreateStatsStmt +== 259 +CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_2 +-- +STMT: CreateStatsStmt +== 260 +ALTER STATISTICS alt_stat3 RENAME TO alt_stat4 +-- +STMT: RenameStmt +== 261 +-- failed (not owner) +ALTER STATISTICS alt_stat1 RENAME TO alt_stat4 +-- +STMT: RenameStmt +== 262 +-- OK +ALTER STATISTICS alt_stat3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 263 +-- failed (not owner) +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 264 +-- failed (no role membership) +ALTER STATISTICS alt_stat3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 265 +-- failed (not owner) +ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 266 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 267 +SELECT nspname, stxname, rolname + FROM pg_statistic_ext s, pg_namespace n, pg_authid a + WHERE s.stxnamespace = n.oid AND s.stxowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, stxname +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="s" column="stxowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 268 +|-- +-- Text Search Dictionary +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 269 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple) +-- +STMT: DefineStmt +== 270 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple) +-- +STMT: DefineStmt +== 271 +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict2 +-- +STMT: RenameStmt +== 272 +-- failed (name conflict) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict3 +-- +STMT: RenameStmt +== 273 +-- OK +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 274 +-- failed (no role membership) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 275 +-- OK +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 276 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +== 277 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple) +-- +STMT: DefineStmt +== 278 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple) +-- +STMT: DefineStmt +== 279 +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 RENAME TO alt_ts_dict4 +-- +STMT: RenameStmt +== 280 +-- failed (not owner) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict4 +-- +STMT: RenameStmt +== 281 +-- OK +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 282 +-- failed (not owner) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 283 +-- failed (no role membership) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 284 +-- failed (not owner) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 285 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 286 +SELECT nspname, dictname, rolname + FROM pg_ts_dict t, pg_namespace n, pg_authid a + WHERE t.dictnamespace = n.oid AND t.dictowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, dictname +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_dict" +FILTER: schema="" table="t" column="dictnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="t" column="dictowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 287 +|-- +-- Text Search Configuration +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +== 288 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english) +-- +STMT: DefineStmt +== 289 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english) +-- +STMT: DefineStmt +== 290 +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf2 +-- +STMT: RenameStmt +== 291 +-- failed (name conflict) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf3 +-- +STMT: RenameStmt +== 292 +-- OK +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 293 +-- failed (no role membership) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 294 +-- OK +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 295 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +== 296 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english) +-- +STMT: DefineStmt +== 297 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english) +-- +STMT: DefineStmt +== 298 +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 RENAME TO alt_ts_conf4 +-- +STMT: RenameStmt +== 299 +-- failed (not owner) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf4 +-- +STMT: RenameStmt +== 300 +-- OK +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +== 301 +-- failed (not owner) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +== 302 +-- failed (no role membership) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 303 +-- failed (not owner) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 304 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 305 +SELECT nspname, cfgname, rolname + FROM pg_ts_config t, pg_namespace n, pg_authid a + WHERE t.cfgnamespace = n.oid AND t.cfgowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, cfgname +-- +TABLE: name="pg_ts_config" schema="" table="pg_ts_config" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_config" +FILTER: schema="" table="t" column="cfgnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="t" column="cfgowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 306 +|-- +-- Text Search Template +|-- +CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize) +-- +STMT: DefineStmt +== 307 +CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize) +-- +STMT: DefineStmt +== 308 +ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2 +-- +STMT: RenameStmt +== 309 +-- failed (name conflict) +ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp3 +-- +STMT: RenameStmt +== 310 +-- OK +ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 311 +-- OK + +CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize) +-- +STMT: DefineStmt +== 312 +ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 313 +-- failed (name conflict) + +-- invalid: non-lowercase quoted identifiers +CREATE TEXT SEARCH TEMPLATE tstemp_case ("Init" = init_function) +-- +STMT: DefineStmt +== 314 +SELECT nspname, tmplname + FROM pg_ts_template t, pg_namespace n + WHERE t.tmplnamespace = n.oid AND nspname like 'alt_nsp%' + ORDER BY nspname, tmplname +-- +TABLE: name="pg_ts_template" schema="" table="pg_ts_template" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_template" +FILTER: schema="" table="t" column="tmplnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 315 +|-- +-- Text Search Parser +|-- + +CREATE TEXT SEARCH PARSER alt_ts_prs1 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +== 316 +CREATE TEXT SEARCH PARSER alt_ts_prs2 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +== 317 +ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs2 +-- +STMT: RenameStmt +== 318 +-- failed (name conflict) +ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs3 +-- +STMT: RenameStmt +== 319 +-- OK +ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 320 +-- OK + +CREATE TEXT SEARCH PARSER alt_ts_prs2 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +== 321 +ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +== 322 +-- failed (name conflict) + +-- invalid: non-lowercase quoted identifiers +CREATE TEXT SEARCH PARSER tspars_case ("Start" = start_function) +-- +STMT: DefineStmt +== 323 +SELECT nspname, prsname + FROM pg_ts_parser t, pg_namespace n + WHERE t.prsnamespace = n.oid AND nspname like 'alt_nsp%' + ORDER BY nspname, prsname +-- +TABLE: name="pg_ts_parser" schema="" table="pg_ts_parser" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_parser" +FILTER: schema="" table="t" column="prsnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 324 +--- +--- Cleanup resources +--- +DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE +-- +STMT: DropStmt +== 325 +DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE +-- +STMT: DropStmt +== 326 +DROP LANGUAGE alt_lang2 CASCADE +-- +STMT: DropStmt +== 327 +DROP LANGUAGE alt_lang3 CASCADE +-- +STMT: DropStmt +== 328 +DROP SCHEMA alt_nsp1 CASCADE +-- +STMT: DropStmt +== 329 +DROP SCHEMA alt_nsp2 CASCADE +-- +STMT: DropStmt +== 330 +DROP USER regress_alter_generic_user1 +-- +STMT: DropRoleStmt +== 331 +DROP USER regress_alter_generic_user2 +-- +STMT: DropRoleStmt +== 332 +DROP USER regress_alter_generic_user3 +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/alter_operator.metadata.json b/parser/testdata/summary/postgres_regress/alter_operator.metadata.json new file mode 100644 index 0000000..8836c0c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/alter_operator.metadata.json @@ -0,0 +1,69 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065" + ] +} diff --git a/parser/testdata/summary/postgres_regress/alter_operator.test b/parser/testdata/summary/postgres_regress/alter_operator.test new file mode 100644 index 0000000..b949dbf --- /dev/null +++ b/parser/testdata/summary/postgres_regress/alter_operator.test @@ -0,0 +1,452 @@ +== 001 +CREATE FUNCTION alter_op_test_fn(boolean, boolean) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="alter_op_test_fn" function="alter_op_test_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +CREATE FUNCTION customcontsel(internal, oid, internal, integer) +RETURNS float8 AS 'contsel' LANGUAGE internal STABLE STRICT +-- +FUNCTION: name="customcontsel" function="customcontsel" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn, + COMMUTATOR = ===, + NEGATOR = !==, + RESTRICT = customcontsel, + JOIN = contjoinsel, + HASHES, MERGES +) +-- +STMT: DefineStmt +== 004 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 005 +|-- +-- Test resetting and setting restrict and join attributes. +|-- + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE) +-- +STMT: AlterOperatorStmt +== 006 +ALTER OPERATOR === (boolean, boolean) SET (JOIN = NONE) +-- +STMT: AlterOperatorStmt +== 007 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +== 008 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 009 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel) +-- +STMT: AlterOperatorStmt +== 010 +ALTER OPERATOR === (boolean, boolean) SET (JOIN = contjoinsel) +-- +STMT: AlterOperatorStmt +== 011 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +== 012 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 013 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE, JOIN = NONE) +-- +STMT: AlterOperatorStmt +== 014 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +== 015 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 016 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = customcontsel, JOIN = contjoinsel) +-- +STMT: AlterOperatorStmt +== 017 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +== 018 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 019 +|-- +-- Test invalid options. +|-- +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = non_existent_func) +-- +STMT: AlterOperatorStmt +== 020 +ALTER OPERATOR === (boolean, boolean) SET (JOIN = non_existent_func) +-- +STMT: AlterOperatorStmt +== 021 +-- invalid: non-lowercase quoted identifiers +ALTER OPERATOR & (bit, bit) SET ("Restrict" = _int_contsel, "Join" = _int_contjoinsel) +-- +STMT: AlterOperatorStmt +== 022 +|-- +-- Test permission check. Must be owner to ALTER OPERATOR. +|-- +CREATE USER regress_alter_op_user +-- +STMT: CreateRoleStmt +== 023 +SET SESSION AUTHORIZATION regress_alter_op_user +-- +STMT: VariableSetStmt +== 024 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE) +-- +STMT: AlterOperatorStmt +== 025 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 026 +|-- +-- Test setting commutator, negator, merges, and hashes attributes, +-- which can only be set if not already set +|-- + +CREATE FUNCTION alter_op_test_fn_bool_real(boolean, real) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="alter_op_test_fn_bool_real" function="alter_op_test_fn_bool_real" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 027 +CREATE FUNCTION alter_op_test_fn_real_bool(real, boolean) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="alter_op_test_fn_real_bool" function="alter_op_test_fn_real_bool" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 028 +-- operator +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +) +-- +STMT: DefineStmt +== 029 +-- commutator +CREATE OPERATOR ==== ( + LEFTARG = real, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn_real_bool +) +-- +STMT: DefineStmt +== 030 +-- negator +CREATE OPERATOR !==== ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +) +-- +STMT: DefineStmt +== 031 +-- No-op setting already false hashes and merges to false works +ALTER OPERATOR === (boolean, real) SET (MERGES = false) +-- +STMT: AlterOperatorStmt +== 032 +ALTER OPERATOR === (boolean, real) SET (HASHES = false) +-- +STMT: AlterOperatorStmt +== 033 +-- Test setting merges and hashes +ALTER OPERATOR === (boolean, real) SET (MERGES) +-- +STMT: AlterOperatorStmt +== 034 +ALTER OPERATOR === (boolean, real) SET (HASHES) +-- +STMT: AlterOperatorStmt +== 035 +SELECT oprcanmerge, oprcanhash +FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +== 036 +-- Test setting commutator +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = ====) +-- +STMT: AlterOperatorStmt +== 037 +-- Check that oprcom has been set on both the operator and commutator, +-- that they reference each other, and that the operator used is the existing +-- one we created and not a new shell operator. +SELECT op.oprname AS operator_name, com.oprname AS commutator_name, + com.oprcode AS commutator_func + FROM pg_operator op + INNER JOIN pg_operator com ON (op.oid = com.oprcom AND op.oprcom = com.oid) + WHERE op.oprname = '===' + AND op.oprleft = 'boolean'::regtype AND op.oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "com"="pg_operator" +ALIAS: "op"="pg_operator" +FILTER: schema="" table="op" column="oprname" +FILTER: schema="" table="op" column="oprleft" +FILTER: schema="" table="op" column="oprright" +STMT: SelectStmt +== 038 +-- Cannot set self as negator +ALTER OPERATOR === (boolean, real) SET (NEGATOR = ===) +-- +STMT: AlterOperatorStmt +== 039 +-- Test setting negator +ALTER OPERATOR === (boolean, real) SET (NEGATOR = !====) +-- +STMT: AlterOperatorStmt +== 040 +-- Check that oprnegate has been set on both the operator and negator, +-- that they reference each other, and that the operator used is the existing +-- one we created and not a new shell operator. +SELECT op.oprname AS operator_name, neg.oprname AS negator_name, + neg.oprcode AS negator_func + FROM pg_operator op + INNER JOIN pg_operator neg ON (op.oid = neg.oprnegate AND op.oprnegate = neg.oid) + WHERE op.oprname = '===' + AND op.oprleft = 'boolean'::regtype AND op.oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "neg"="pg_operator" +ALIAS: "op"="pg_operator" +FILTER: schema="" table="op" column="oprname" +FILTER: schema="" table="op" column="oprleft" +FILTER: schema="" table="op" column="oprright" +STMT: SelectStmt +== 041 +-- Test that no-op set succeeds +ALTER OPERATOR === (boolean, real) SET (NEGATOR = !====) +-- +STMT: AlterOperatorStmt +== 042 +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = ====) +-- +STMT: AlterOperatorStmt +== 043 +ALTER OPERATOR === (boolean, real) SET (MERGES) +-- +STMT: AlterOperatorStmt +== 044 +ALTER OPERATOR === (boolean, real) SET (HASHES) +-- +STMT: AlterOperatorStmt +== 045 +-- Check that the final state of the operator is as we expect +SELECT oprcanmerge, oprcanhash, + pg_describe_object('pg_operator'::regclass, oprcom, 0) AS commutator, + pg_describe_object('pg_operator'::regclass, oprnegate, 0) AS negator + FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +== 046 +-- Cannot change commutator, negator, merges, and hashes when already set + +CREATE OPERATOR @= ( + LEFTARG = real, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn_real_bool +) +-- +STMT: DefineStmt +== 047 +CREATE OPERATOR @!= ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +) +-- +STMT: DefineStmt +== 048 +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = @=) +-- +STMT: AlterOperatorStmt +== 049 +ALTER OPERATOR === (boolean, real) SET (NEGATOR = @!=) +-- +STMT: AlterOperatorStmt +== 050 +ALTER OPERATOR === (boolean, real) SET (MERGES = false) +-- +STMT: AlterOperatorStmt +== 051 +ALTER OPERATOR === (boolean, real) SET (HASHES = false) +-- +STMT: AlterOperatorStmt +== 052 +-- Cannot set an operator that already has a commutator as the commutator +ALTER OPERATOR @=(real, boolean) SET (COMMUTATOR = ===) +-- +STMT: AlterOperatorStmt +== 053 +-- Cannot set an operator that already has a negator as the negator +ALTER OPERATOR @!=(boolean, real) SET (NEGATOR = ===) +-- +STMT: AlterOperatorStmt +== 054 +-- Check no changes made +SELECT oprcanmerge, oprcanhash, + pg_describe_object('pg_operator'::regclass, oprcom, 0) AS commutator, + pg_describe_object('pg_operator'::regclass, oprnegate, 0) AS negator + FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +== 055 +|-- +-- Clean up +|-- + +DROP USER regress_alter_op_user +-- +STMT: DropRoleStmt +== 056 +DROP OPERATOR === (boolean, boolean) +-- +STMT: DropStmt +== 057 +DROP OPERATOR === (boolean, real) +-- +STMT: DropStmt +== 058 +DROP OPERATOR ==== (real, boolean) +-- +STMT: DropStmt +== 059 +DROP OPERATOR !==== (boolean, real) +-- +STMT: DropStmt +== 060 +DROP OPERATOR @= (real, boolean) +-- +STMT: DropStmt +== 061 +DROP OPERATOR @!= (boolean, real) +-- +STMT: DropStmt +== 062 +DROP FUNCTION customcontsel(internal, oid, internal, integer) +-- +FUNCTION: name="customcontsel" function="customcontsel" schema="" ctx=DDL +STMT: DropStmt +== 063 +DROP FUNCTION alter_op_test_fn(boolean, boolean) +-- +FUNCTION: name="alter_op_test_fn" function="alter_op_test_fn" schema="" ctx=DDL +STMT: DropStmt +== 064 +DROP FUNCTION alter_op_test_fn_bool_real(boolean, real) +-- +FUNCTION: name="alter_op_test_fn_bool_real" function="alter_op_test_fn_bool_real" schema="" ctx=DDL +STMT: DropStmt +== 065 +DROP FUNCTION alter_op_test_fn_real_bool(real, boolean) +-- +FUNCTION: name="alter_op_test_fn_real_bool" function="alter_op_test_fn_real_bool" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/alter_table.metadata.json b/parser/testdata/summary/postgres_regress/alter_table.metadata.json new file mode 100644 index 0000000..bfe6d13 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/alter_table.metadata.json @@ -0,0 +1,1657 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "1060", + "1061", + "1062", + "1063", + "1064", + "1065", + "1066", + "1067", + "1068", + "1069", + "107", + "1070", + "1071", + "1072", + "1073", + "1074", + "1075", + "1076", + "1077", + "1078", + "1079", + "108", + "1080", + "1081", + "1082", + "1083", + "1084", + "1085", + "1086", + "1087", + "1088", + "1089", + "109", + "1090", + "1091", + "1092", + "1093", + "1094", + "1095", + "1096", + "1097", + "1098", + "1099", + "110", + "1100", + "1101", + "1102", + "1103", + "1104", + "1105", + "1106", + "1107", + "1108", + "1109", + "111", + "1110", + "1111", + "1112", + "1113", + "1114", + "1115", + "1116", + "1117", + "1118", + "1119", + "112", + "1120", + "1121", + "1122", + "1123", + "1124", + "1125", + "1126", + "1127", + "1128", + "1129", + "113", + "1130", + "1131", + "1132", + "1133", + "1134", + "1135", + "1136", + "1137", + "1138", + "1139", + "114", + "1140", + "1141", + "1142", + "1143", + "1144", + "1145", + "1146", + "1147", + "1148", + "1149", + "115", + "1150", + "1151", + "1152", + "1153", + "1154", + "1155", + "1156", + "1157", + "1158", + "1159", + "116", + "1160", + "1161", + "1162", + "1163", + "1164", + "1165", + "1166", + "1167", + "1168", + "1169", + "117", + "1170", + "1171", + "1172", + "1173", + "1174", + "1175", + "1176", + "1177", + "1178", + "1179", + "118", + "1180", + "1181", + "1182", + "1183", + "1184", + "1185", + "1186", + "1187", + "1188", + "1189", + "119", + "1190", + "1191", + "1192", + "1193", + "1194", + "1195", + "1196", + "1197", + "1198", + "1199", + "120", + "1200", + "1201", + "1202", + "1203", + "1204", + "1205", + "1206", + "1207", + "1208", + "1209", + "121", + "1210", + "1211", + "1212", + "1213", + "1214", + "1215", + "1216", + "1217", + "1218", + "1219", + "122", + "1220", + "1221", + "1222", + "1223", + "1224", + "1225", + "1226", + "1227", + "1228", + "1229", + "123", + "1230", + "1231", + "1232", + "1233", + "1234", + "1235", + "1236", + "1237", + "1238", + "1239", + "124", + "1240", + "1241", + "1242", + "1243", + "1244", + "1245", + "1246", + "1247", + "1248", + "1249", + "125", + "1250", + "1251", + "1252", + "1253", + "1254", + "1255", + "1256", + "1257", + "1258", + "1259", + "126", + "1260", + "1261", + "1262", + "1263", + "1264", + "1265", + "1266", + "1267", + "1268", + "1269", + "127", + "1270", + "1271", + "1272", + "1273", + "1274", + "1275", + "1276", + "1277", + "1278", + "1279", + "128", + "1280", + "1281", + "1282", + "1283", + "1284", + "1285", + "1286", + "1287", + "1288", + "1289", + "129", + "1290", + "1291", + "1292", + "1293", + "1294", + "1295", + "1296", + "1297", + "1298", + "1299", + "130", + "1300", + "1301", + "1302", + "1303", + "1304", + "1305", + "1306", + "1307", + "1308", + "1309", + "131", + "1310", + "1311", + "1312", + "1313", + "1314", + "1315", + "1316", + "1317", + "1318", + "1319", + "132", + "1320", + "1321", + "1322", + "1323", + "1324", + "1325", + "1326", + "1327", + "1328", + "1329", + "133", + "1330", + "1331", + "1332", + "1333", + "1334", + "1335", + "1336", + "1337", + "1338", + "1339", + "134", + "1340", + "1341", + "1342", + "1343", + "1344", + "1345", + "1346", + "1347", + "1348", + "1349", + "135", + "1350", + "1351", + "1352", + "1353", + "1354", + "1355", + "1356", + "1357", + "1358", + "1359", + "136", + "1360", + "1361", + "1362", + "1363", + "1364", + "1365", + "1366", + "1367", + "1368", + "1369", + "137", + "1370", + "1371", + "1372", + "1373", + "1374", + "1375", + "1376", + "1377", + "1378", + "1379", + "138", + "1380", + "1381", + "1382", + "1383", + "1384", + "1385", + "1386", + "1387", + "1388", + "1389", + "139", + "1390", + "1391", + "1392", + "1393", + "1394", + "1395", + "1396", + "1397", + "1398", + "1399", + "140", + "1400", + "1401", + "1402", + "1403", + "1404", + "1405", + "1406", + "1407", + "1408", + "1409", + "141", + "1410", + "1411", + "1412", + "1413", + "1414", + "1415", + "1416", + "1417", + "1418", + "1419", + "142", + "1420", + "1421", + "1422", + "1423", + "1424", + "1425", + "1426", + "1427", + "1428", + "1429", + "143", + "1430", + "1431", + "1432", + "1433", + "1434", + "1435", + "1436", + "1437", + "1438", + "1439", + "144", + "1440", + "1441", + "1442", + "1443", + "1444", + "1445", + "1446", + "1447", + "1448", + "1449", + "145", + "1450", + "1451", + "1452", + "1453", + "1454", + "1455", + "1456", + "1457", + "1458", + "1459", + "146", + "1460", + "1461", + "1462", + "1463", + "1464", + "1465", + "1466", + "1467", + "1468", + "1469", + "147", + "1470", + "1471", + "1472", + "1473", + "1474", + "1475", + "1476", + "1477", + "1478", + "1479", + "148", + "1480", + "1481", + "1482", + "1483", + "1484", + "1485", + "1486", + "1487", + "1488", + "1489", + "149", + "1490", + "1491", + "1492", + "1493", + "1494", + "1495", + "1496", + "1497", + "1498", + "1499", + "150", + "1500", + "1501", + "1502", + "1503", + "1504", + "1505", + "1506", + "1507", + "1508", + "1509", + "151", + "1510", + "1511", + "1512", + "1513", + "1514", + "1515", + "1516", + "1517", + "1518", + "1519", + "152", + "1520", + "1521", + "1522", + "1523", + "1524", + "1525", + "1526", + "1527", + "1528", + "1529", + "153", + "1530", + "1531", + "1532", + "1533", + "1534", + "1535", + "1536", + "1537", + "1538", + "1539", + "154", + "1540", + "1541", + "1542", + "1543", + "1544", + "1545", + "1546", + "1547", + "1548", + "1549", + "155", + "1550", + "1551", + "1552", + "1553", + "1554", + "1555", + "1556", + "1557", + "1558", + "1559", + "156", + "1560", + "1561", + "1562", + "1563", + "1564", + "1565", + "1566", + "1567", + "1568", + "1569", + "157", + "1570", + "1571", + "1572", + "1573", + "1574", + "1575", + "1576", + "1577", + "1578", + "1579", + "158", + "1580", + "1581", + "1582", + "1583", + "1584", + "1585", + "1586", + "1587", + "1588", + "1589", + "159", + "1590", + "1591", + "1592", + "1593", + "1594", + "1595", + "1596", + "1597", + "1598", + "1599", + "160", + "1600", + "1601", + "1602", + "1603", + "1604", + "1605", + "1606", + "1607", + "1608", + "1609", + "161", + "1610", + "1611", + "1612", + "1613", + "1614", + "1615", + "1616", + "1617", + "1618", + "1619", + "162", + "1620", + "1621", + "1622", + "1623", + "1624", + "1625", + "1626", + "1627", + "1628", + "1629", + "163", + "1630", + "1631", + "1632", + "1633", + "1634", + "1635", + "1636", + "1637", + "1638", + "1639", + "164", + "1640", + "1641", + "1642", + "1643", + "1644", + "1645", + "1646", + "1647", + "1648", + "1649", + "165", + "1650", + "1651", + "1652", + "1653", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary/postgres_regress/alter_table.test b/parser/testdata/summary/postgres_regress/alter_table.test new file mode 100644 index 0000000..5660b98 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/alter_table.test @@ -0,0 +1,9502 @@ +== 001 +|-- +-- ALTER_TABLE +|-- + +-- Clean up in case a prior regression run failed +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +== 002 +DROP ROLE IF EXISTS regress_alter_table_user1 +-- +STMT: DropRoleStmt +== 003 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 004 +CREATE USER regress_alter_table_user1 +-- +STMT: CreateRoleStmt +== 005 +|-- +-- add attribute +|-- + +CREATE TABLE attmp (initial int4) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +== 006 +COMMENT ON TABLE attmp_wrong IS 'table comment' +-- +STMT: CommentStmt +== 007 +COMMENT ON TABLE attmp IS 'table comment' +-- +STMT: CommentStmt +== 008 +COMMENT ON TABLE attmp IS NULL +-- +STMT: CommentStmt +== 009 +ALTER TABLE attmp ADD COLUMN xmin integer +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 010 +-- fails + +ALTER TABLE attmp ADD COLUMN a int4 default 3 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 011 +ALTER TABLE attmp ADD COLUMN b name +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 012 +ALTER TABLE attmp ADD COLUMN c text +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 013 +ALTER TABLE attmp ADD COLUMN d float8 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 014 +ALTER TABLE attmp ADD COLUMN e float4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 015 +ALTER TABLE attmp ADD COLUMN f int2 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 016 +ALTER TABLE attmp ADD COLUMN g polygon +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 017 +ALTER TABLE attmp ADD COLUMN i char +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 018 +ALTER TABLE attmp ADD COLUMN k int4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 019 +ALTER TABLE attmp ADD COLUMN l tid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 020 +ALTER TABLE attmp ADD COLUMN m xid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 021 +ALTER TABLE attmp ADD COLUMN n oidvector +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 022 +--ALTER TABLE attmp ADD COLUMN o lock; +ALTER TABLE attmp ADD COLUMN p boolean +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 023 +ALTER TABLE attmp ADD COLUMN q point +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 024 +ALTER TABLE attmp ADD COLUMN r lseg +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 025 +ALTER TABLE attmp ADD COLUMN s path +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 026 +ALTER TABLE attmp ADD COLUMN t box +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 027 +ALTER TABLE attmp ADD COLUMN v timestamp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 028 +ALTER TABLE attmp ADD COLUMN w interval +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 029 +ALTER TABLE attmp ADD COLUMN x float8[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 030 +ALTER TABLE attmp ADD COLUMN y float4[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 031 +ALTER TABLE attmp ADD COLUMN z int2[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 032 +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, + v, w, x, y, z) + VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', + 'c', + 314159, '(1,1)', '512', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', + 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}') +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +== 034 +DROP TABLE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: DropStmt +== 035 +-- the wolf bug - schema mods caused inconsistent row descriptors +CREATE TABLE attmp ( + initial int4 +) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +== 036 +ALTER TABLE attmp ADD COLUMN a int4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 037 +ALTER TABLE attmp ADD COLUMN b name +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 038 +ALTER TABLE attmp ADD COLUMN c text +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 039 +ALTER TABLE attmp ADD COLUMN d float8 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 040 +ALTER TABLE attmp ADD COLUMN e float4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 041 +ALTER TABLE attmp ADD COLUMN f int2 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 042 +ALTER TABLE attmp ADD COLUMN g polygon +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 043 +ALTER TABLE attmp ADD COLUMN i char +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 044 +ALTER TABLE attmp ADD COLUMN k int4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 045 +ALTER TABLE attmp ADD COLUMN l tid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 046 +ALTER TABLE attmp ADD COLUMN m xid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 047 +ALTER TABLE attmp ADD COLUMN n oidvector +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 048 +--ALTER TABLE attmp ADD COLUMN o lock; +ALTER TABLE attmp ADD COLUMN p boolean +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 049 +ALTER TABLE attmp ADD COLUMN q point +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 050 +ALTER TABLE attmp ADD COLUMN r lseg +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 051 +ALTER TABLE attmp ADD COLUMN s path +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 052 +ALTER TABLE attmp ADD COLUMN t box +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 053 +ALTER TABLE attmp ADD COLUMN v timestamp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 054 +ALTER TABLE attmp ADD COLUMN w interval +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 055 +ALTER TABLE attmp ADD COLUMN x float8[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 056 +ALTER TABLE attmp ADD COLUMN y float4[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 057 +ALTER TABLE attmp ADD COLUMN z int2[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 058 +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, + v, w, x, y, z) + VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', + 'c', + 314159, '(1,1)', '512', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', + 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}') +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +== 060 +CREATE INDEX attmp_idx ON attmp (a, (d + e), b) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: IndexStmt +== 061 +ALTER INDEX attmp_idx ALTER COLUMN 0 SET STATISTICS 1000 +-- +ERROR: column number must be in range from 1 to 32767 +CURSORPOS: 36 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 062 +ALTER INDEX attmp_idx ALTER COLUMN 1 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 063 +ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 064 +ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 065 +ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 066 +ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1 +-- +STMT: AlterTableStmt +== 067 +DROP TABLE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: DropStmt +== 068 +|-- +-- rename - check on both non-temp and temp tables +|-- +CREATE TABLE attmp (regtable int) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +== 069 +CREATE TEMP TABLE attmp (attmptable int) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +== 070 +ALTER TABLE attmp RENAME TO attmp_new +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=DDL +STMT: RenameStmt +== 071 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +== 072 +SELECT * FROM attmp_new +-- +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=Select +STMT: SelectStmt +== 073 +ALTER TABLE attmp RENAME TO attmp_new2 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +TABLE: name="attmp_new2" schema="" table="attmp_new2" ctx=DDL +STMT: RenameStmt +== 074 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +== 075 +-- should fail +SELECT * FROM attmp_new +-- +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=Select +STMT: SelectStmt +== 076 +SELECT * FROM attmp_new2 +-- +TABLE: name="attmp_new2" schema="" table="attmp_new2" ctx=Select +STMT: SelectStmt +== 077 +DROP TABLE attmp_new +-- +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=DDL +STMT: DropStmt +== 078 +DROP TABLE attmp_new2 +-- +TABLE: name="attmp_new2" schema="" table="attmp_new2" ctx=DDL +STMT: DropStmt +== 079 +-- check rename of partitioned tables and indexes also +CREATE TABLE part_attmp (a int primary key) partition by range (a) +-- +TABLE: name="part_attmp" schema="" table="part_attmp" ctx=DDL +STMT: CreateStmt +== 080 +CREATE TABLE part_attmp1 PARTITION OF part_attmp FOR VALUES FROM (0) TO (100) +-- +TABLE: name="part_attmp1" schema="" table="part_attmp1" ctx=DDL +STMT: CreateStmt +== 081 +ALTER INDEX part_attmp_pkey RENAME TO part_attmp_index +-- +STMT: RenameStmt +== 082 +ALTER INDEX part_attmp1_pkey RENAME TO part_attmp1_index +-- +STMT: RenameStmt +== 083 +ALTER TABLE part_attmp RENAME TO part_at2tmp +-- +TABLE: name="part_attmp" schema="" table="part_attmp" ctx=DDL +TABLE: name="part_at2tmp" schema="" table="part_at2tmp" ctx=DDL +STMT: RenameStmt +== 084 +ALTER TABLE part_attmp1 RENAME TO part_at2tmp1 +-- +TABLE: name="part_attmp1" schema="" table="part_attmp1" ctx=DDL +TABLE: name="part_at2tmp1" schema="" table="part_at2tmp1" ctx=DDL +STMT: RenameStmt +== 085 +SET ROLE regress_alter_table_user1 +-- +STMT: VariableSetStmt +== 086 +ALTER INDEX part_attmp_index RENAME TO fail +-- +STMT: RenameStmt +== 087 +ALTER INDEX part_attmp1_index RENAME TO fail +-- +STMT: RenameStmt +== 088 +ALTER TABLE part_at2tmp RENAME TO fail +-- +TABLE: name="part_at2tmp" schema="" table="part_at2tmp" ctx=DDL +TABLE: name="fail" schema="" table="fail" ctx=DDL +STMT: RenameStmt +== 089 +ALTER TABLE part_at2tmp1 RENAME TO fail +-- +TABLE: name="part_at2tmp1" schema="" table="part_at2tmp1" ctx=DDL +TABLE: name="fail" schema="" table="fail" ctx=DDL +STMT: RenameStmt +== 090 +RESET ROLE +-- +STMT: VariableSetStmt +== 091 +DROP TABLE part_at2tmp +-- +TABLE: name="part_at2tmp" schema="" table="part_at2tmp" ctx=DDL +STMT: DropStmt +== 092 +|-- +-- check renaming to a table's array type's autogenerated name +-- (the array type's name should get out of the way) +|-- +CREATE TABLE attmp_array (id int) +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +STMT: CreateStmt +== 093 +CREATE TABLE attmp_array2 (id int) +-- +TABLE: name="attmp_array2" schema="" table="attmp_array2" ctx=DDL +STMT: CreateStmt +== 094 +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 095 +SELECT typname FROM pg_type WHERE oid = 'attmp_array2[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 096 +ALTER TABLE attmp_array2 RENAME TO _attmp_array +-- +TABLE: name="attmp_array2" schema="" table="attmp_array2" ctx=DDL +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: RenameStmt +== 097 +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 098 +SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 099 +DROP TABLE _attmp_array +-- +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: DropStmt +== 100 +DROP TABLE attmp_array +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +STMT: DropStmt +== 101 +-- renaming to table's own array type's name is an interesting corner case +CREATE TABLE attmp_array (id int) +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +STMT: CreateStmt +== 102 +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 103 +ALTER TABLE attmp_array RENAME TO _attmp_array +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: RenameStmt +== 104 +SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 105 +DROP TABLE _attmp_array +-- +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: DropStmt +== 106 +-- ALTER TABLE ... RENAME on non-table relations +-- renaming indexes (FIXME: this should probably test the index's functionality) +ALTER INDEX IF EXISTS __onek_unique1 RENAME TO attmp_onek_unique1 +-- +STMT: RenameStmt +== 107 +ALTER INDEX IF EXISTS __attmp_onek_unique1 RENAME TO onek_unique1 +-- +STMT: RenameStmt +== 108 +ALTER INDEX onek_unique1 RENAME TO attmp_onek_unique1 +-- +STMT: RenameStmt +== 109 +ALTER INDEX attmp_onek_unique1 RENAME TO onek_unique1 +-- +STMT: RenameStmt +== 110 +SET ROLE regress_alter_table_user1 +-- +STMT: VariableSetStmt +== 111 +ALTER INDEX onek_unique1 RENAME TO fail +-- +STMT: RenameStmt +== 112 +-- permission denied +RESET ROLE +-- +STMT: VariableSetStmt +== 113 +-- rename statements with mismatching statement and object types +CREATE TABLE alter_idx_rename_test (a INT) +-- +TABLE: name="alter_idx_rename_test" schema="" table="alter_idx_rename_test" ctx=DDL +STMT: CreateStmt +== 114 +CREATE INDEX alter_idx_rename_test_idx ON alter_idx_rename_test (a) +-- +TABLE: name="alter_idx_rename_test" schema="" table="alter_idx_rename_test" ctx=DDL +STMT: IndexStmt +== 115 +CREATE TABLE alter_idx_rename_test_parted (a INT) PARTITION BY LIST (a) +-- +TABLE: name="alter_idx_rename_test_parted" schema="" table="alter_idx_rename_test_parted" ctx=DDL +STMT: CreateStmt +== 116 +CREATE INDEX alter_idx_rename_test_parted_idx ON alter_idx_rename_test_parted (a) +-- +TABLE: name="alter_idx_rename_test_parted" schema="" table="alter_idx_rename_test_parted" ctx=DDL +STMT: IndexStmt +== 117 +BEGIN +-- +STMT: TransactionStmt +== 118 +ALTER INDEX alter_idx_rename_test RENAME TO alter_idx_rename_test_2 +-- +STMT: RenameStmt +== 119 +ALTER INDEX alter_idx_rename_test_parted RENAME TO alter_idx_rename_test_parted_2 +-- +STMT: RenameStmt +== 120 +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C" +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="locktype" +FILTER: schema="" table="" column="relation" +STMT: SelectStmt +== 121 +COMMIT +-- +STMT: TransactionStmt +== 122 +BEGIN +-- +STMT: TransactionStmt +== 123 +ALTER INDEX alter_idx_rename_test_idx RENAME TO alter_idx_rename_test_idx_2 +-- +STMT: RenameStmt +== 124 +ALTER INDEX alter_idx_rename_test_parted_idx RENAME TO alter_idx_rename_test_parted_idx_2 +-- +STMT: RenameStmt +== 125 +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C" +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="locktype" +FILTER: schema="" table="" column="relation" +STMT: SelectStmt +== 126 +COMMIT +-- +STMT: TransactionStmt +== 127 +BEGIN +-- +STMT: TransactionStmt +== 128 +ALTER TABLE alter_idx_rename_test_idx_2 RENAME TO alter_idx_rename_test_idx_3 +-- +TABLE: name="alter_idx_rename_test_idx_2" schema="" table="alter_idx_rename_test_idx_2" ctx=DDL +TABLE: name="alter_idx_rename_test_idx_3" schema="" table="alter_idx_rename_test_idx_3" ctx=DDL +STMT: RenameStmt +== 129 +ALTER TABLE alter_idx_rename_test_parted_idx_2 RENAME TO alter_idx_rename_test_parted_idx_3 +-- +TABLE: name="alter_idx_rename_test_parted_idx_2" schema="" table="alter_idx_rename_test_parted_idx_2" ctx=DDL +TABLE: name="alter_idx_rename_test_parted_idx_3" schema="" table="alter_idx_rename_test_parted_idx_3" ctx=DDL +STMT: RenameStmt +== 130 +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C" +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="locktype" +FILTER: schema="" table="" column="relation" +STMT: SelectStmt +== 131 +COMMIT +-- +STMT: TransactionStmt +== 132 +DROP TABLE alter_idx_rename_test_2 +-- +TABLE: name="alter_idx_rename_test_2" schema="" table="alter_idx_rename_test_2" ctx=DDL +STMT: DropStmt +== 133 +-- renaming views +CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1 +-- +TABLE: name="attmp_view" schema="" table="attmp_view" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 134 +ALTER TABLE attmp_view RENAME TO attmp_view_new +-- +TABLE: name="attmp_view" schema="" table="attmp_view" ctx=DDL +TABLE: name="attmp_view_new" schema="" table="attmp_view_new" ctx=DDL +STMT: RenameStmt +== 135 +SET ROLE regress_alter_table_user1 +-- +STMT: VariableSetStmt +== 136 +ALTER VIEW attmp_view_new RENAME TO fail +-- +STMT: RenameStmt +== 137 +-- permission denied +RESET ROLE +-- +STMT: VariableSetStmt +== 138 +-- hack to ensure we get an indexscan here +set enable_seqscan to off +-- +STMT: VariableSetStmt +== 139 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +== 140 +-- 5 values, sorted +SELECT unique1 FROM tenk1 WHERE unique1 < 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 141 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 142 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 143 +DROP VIEW attmp_view_new +-- +STMT: DropStmt +== 144 +-- toast-like relation name +alter table stud_emp rename to pg_toast_stud_emp +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +TABLE: name="pg_toast_stud_emp" schema="" table="pg_toast_stud_emp" ctx=DDL +STMT: RenameStmt +== 145 +alter table pg_toast_stud_emp rename to stud_emp +-- +TABLE: name="pg_toast_stud_emp" schema="" table="pg_toast_stud_emp" ctx=DDL +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: RenameStmt +== 146 +-- renaming index should rename constraint as well +ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +== 147 +ALTER INDEX onek_unique1_constraint RENAME TO onek_unique1_constraint_foo +-- +STMT: RenameStmt +== 148 +ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +== 149 +-- renaming constraint +ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= 0) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +== 150 +ALTER TABLE onek RENAME CONSTRAINT onek_check_constraint TO onek_check_constraint_foo +-- +STMT: RenameStmt +== 151 +ALTER TABLE onek DROP CONSTRAINT onek_check_constraint_foo +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +== 152 +-- renaming constraint should rename index as well +ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +== 153 +DROP INDEX onek_unique1_constraint +-- +STMT: DropStmt +== 154 +-- to see whether it's there +ALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo +-- +STMT: RenameStmt +== 155 +DROP INDEX onek_unique1_constraint_foo +-- +STMT: DropStmt +== 156 +-- to see whether it's there +ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +== 157 +-- renaming constraints vs. inheritance +CREATE TABLE constraint_rename_test (a int CONSTRAINT con1 CHECK (a > 0), b int, c int) +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: CreateStmt +== 158 +CREATE TABLE constraint_rename_test2 (a int CONSTRAINT con1 CHECK (a > 0), d int) INHERITS (constraint_rename_test) +-- +TABLE: name="constraint_rename_test2" schema="" table="constraint_rename_test2" ctx=DDL +STMT: CreateStmt +== 159 +ALTER TABLE constraint_rename_test2 RENAME CONSTRAINT con1 TO con1foo +-- +STMT: RenameStmt +== 160 +-- fail +ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con1 TO con1foo +-- +STMT: RenameStmt +== 161 +-- fail +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con1 TO con1foo +-- +STMT: RenameStmt +== 162 +-- ok +ALTER TABLE constraint_rename_test ADD CONSTRAINT con2 CHECK (b > 0) NO INHERIT +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: AlterTableStmt +== 163 +ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con2 TO con2foo +-- +STMT: RenameStmt +== 164 +-- ok +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con2foo TO con2bar +-- +STMT: RenameStmt +== 165 +-- ok +ALTER TABLE constraint_rename_test ADD CONSTRAINT con3 PRIMARY KEY (a) +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: AlterTableStmt +== 166 +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con3 TO con3foo +-- +STMT: RenameStmt +== 167 +-- ok +DROP TABLE constraint_rename_test2 +-- +TABLE: name="constraint_rename_test2" schema="" table="constraint_rename_test2" ctx=DDL +STMT: DropStmt +== 168 +DROP TABLE constraint_rename_test +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: DropStmt +== 169 +ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo +-- +STMT: RenameStmt +== 170 +-- ok +ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a) +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: AlterTableStmt +== 171 +-- renaming constraints with cache reset of target relation +CREATE TABLE constraint_rename_cache (a int, + CONSTRAINT chk_a CHECK (a > 0), + PRIMARY KEY (a)) +-- +TABLE: name="constraint_rename_cache" schema="" table="constraint_rename_cache" ctx=DDL +STMT: CreateStmt +== 172 +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT chk_a TO chk_a_new +-- +STMT: RenameStmt +== 173 +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT constraint_rename_cache_pkey TO constraint_rename_pkey_new +-- +STMT: RenameStmt +== 174 +CREATE TABLE like_constraint_rename_cache + (LIKE constraint_rename_cache INCLUDING ALL) +-- +TABLE: name="like_constraint_rename_cache" schema="" table="like_constraint_rename_cache" ctx=DDL +STMT: CreateStmt +== 175 +DROP TABLE constraint_rename_cache +-- +TABLE: name="constraint_rename_cache" schema="" table="constraint_rename_cache" ctx=DDL +STMT: DropStmt +== 176 +DROP TABLE like_constraint_rename_cache +-- +TABLE: name="like_constraint_rename_cache" schema="" table="like_constraint_rename_cache" ctx=DDL +STMT: DropStmt +== 177 +-- FOREIGN KEY CONSTRAINT adding TEST + +CREATE TABLE attmp2 (a int primary key) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DDL +STMT: CreateStmt +== 178 +CREATE TABLE attmp3 (a int, b int) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: CreateStmt +== 179 +CREATE TABLE attmp4 (a int, b int, unique(a,b)) +-- +TABLE: name="attmp4" schema="" table="attmp4" ctx=DDL +STMT: CreateStmt +== 180 +CREATE TABLE attmp5 (a int, b int) +-- +TABLE: name="attmp5" schema="" table="attmp5" ctx=DDL +STMT: CreateStmt +== 181 +-- Insert rows into attmp2 (pktable) +INSERT INTO attmp2 values (1) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 182 +INSERT INTO attmp2 values (2) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 183 +INSERT INTO attmp2 values (3) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 184 +INSERT INTO attmp2 values (4) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +-- Insert rows into attmp3 +INSERT INTO attmp3 values (1,10) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +INSERT INTO attmp3 values (1,20) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +INSERT INTO attmp3 values (5,50) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +-- Try (and fail) to add constraint due to invalid source columns +ALTER TABLE attmp3 add constraint attmpconstr foreign key(c) references attmp2 match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 189 +-- Try (and fail) to add constraint due to invalid destination columns explicitly given +ALTER TABLE attmp3 add constraint attmpconstr foreign key(a) references attmp2(b) match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 190 +-- Try (and fail) to add constraint due to invalid data +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 191 +-- Delete failing row +DELETE FROM attmp3 where a=5 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: DeleteStmt +== 192 +-- Try (and succeed) +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 193 +ALTER TABLE attmp3 drop constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 194 +INSERT INTO attmp3 values (5,50) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 195 +-- Try NOT VALID and then VALIDATE CONSTRAINT, but fails. Delete failure then re-validate +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 196 +ALTER TABLE attmp3 validate constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 197 +-- Delete failing row +DELETE FROM attmp3 where a=5 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: DeleteStmt +== 198 +-- Try (and succeed) and repeat to show it works on already valid constraint +ALTER TABLE attmp3 validate constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 199 +ALTER TABLE attmp3 validate constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 200 +-- Try a non-verified CHECK constraint +ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 201 +-- fail +ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 202 +-- succeeds +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 203 +-- fails +DELETE FROM attmp3 WHERE NOT b > 10 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: DeleteStmt +== 204 +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 205 +-- succeeds +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 206 +-- succeeds + +-- Test inherited NOT VALID CHECK constraints +select * from attmp3 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=Select +STMT: SelectStmt +== 207 +CREATE TABLE attmp6 () INHERITS (attmp3) +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DDL +STMT: CreateStmt +== 208 +CREATE TABLE attmp7 () INHERITS (attmp3) +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DDL +STMT: CreateStmt +== 209 +INSERT INTO attmp6 VALUES (6, 30), (7, 16) +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 210 +ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 211 +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 212 +-- fails +DELETE FROM attmp6 WHERE b > 20 +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DML +STMT: DeleteStmt +== 213 +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 214 +-- succeeds + +-- An already validated constraint must not be revalidated +CREATE FUNCTION boo(int) RETURNS int IMMUTABLE STRICT LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'boo: %', $1; RETURN $1; END; $$ +-- +FUNCTION: name="boo" function="boo" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 215 +INSERT INTO attmp7 VALUES (8, 18) +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +ALTER TABLE attmp7 ADD CONSTRAINT identity CHECK (b = boo(b)) +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DDL +STMT: AlterTableStmt +== 217 +ALTER TABLE attmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 218 +ALTER TABLE attmp3 VALIDATE CONSTRAINT identity +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +== 219 +-- A NO INHERIT constraint should not be looked for in children during VALIDATE CONSTRAINT +create table parent_noinh_convalid (a int) +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: CreateStmt +== 220 +create table child_noinh_convalid () inherits (parent_noinh_convalid) +-- +TABLE: name="child_noinh_convalid" schema="" table="child_noinh_convalid" ctx=DDL +STMT: CreateStmt +== 221 +insert into parent_noinh_convalid values (1) +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 222 +insert into child_noinh_convalid values (1) +-- +TABLE: name="child_noinh_convalid" schema="" table="child_noinh_convalid" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 223 +alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: AlterTableStmt +== 224 +-- fail, because of the row in parent +alter table parent_noinh_convalid validate constraint check_a_is_2 +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: AlterTableStmt +== 225 +delete from only parent_noinh_convalid +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DML +STMT: DeleteStmt +== 226 +-- ok (parent itself contains no violating rows) +alter table parent_noinh_convalid validate constraint check_a_is_2 +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: AlterTableStmt +== 227 +select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid'::regclass and conname = 'check_a_is_2' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 228 +-- cleanup +drop table parent_noinh_convalid, child_noinh_convalid +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +TABLE: name="child_noinh_convalid" schema="" table="child_noinh_convalid" ctx=DDL +STMT: DropStmt +== 229 +-- Try (and fail) to create constraint from attmp5(a) to attmp4(a) - unique constraint on +-- attmp4 is a,b + +ALTER TABLE attmp5 add constraint attmpconstr foreign key(a) references attmp4(a) match full +-- +TABLE: name="attmp5" schema="" table="attmp5" ctx=DDL +STMT: AlterTableStmt +== 230 +DROP TABLE attmp7 +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DDL +STMT: DropStmt +== 231 +DROP TABLE attmp6 +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DDL +STMT: DropStmt +== 232 +DROP TABLE attmp5 +-- +TABLE: name="attmp5" schema="" table="attmp5" ctx=DDL +STMT: DropStmt +== 233 +DROP TABLE attmp4 +-- +TABLE: name="attmp4" schema="" table="attmp4" ctx=DDL +STMT: DropStmt +== 234 +DROP TABLE attmp3 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: DropStmt +== 235 +DROP TABLE attmp2 +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DDL +STMT: DropStmt +== 236 +-- NOT VALID with plan invalidation -- ensure we don't use a constraint for +-- exclusion until validated +set constraint_exclusion TO 'partition' +-- +STMT: VariableSetStmt +== 237 +create table nv_parent (d date, check (false) no inherit not valid) +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=DDL +STMT: CreateStmt +== 238 +-- not valid constraint added at creation time should automatically become valid + +create table nv_child_2010 () inherits (nv_parent) +-- +TABLE: name="nv_child_2010" schema="" table="nv_child_2010" ctx=DDL +STMT: CreateStmt +== 239 +create table nv_child_2011 () inherits (nv_parent) +-- +TABLE: name="nv_child_2011" schema="" table="nv_child_2011" ctx=DDL +STMT: CreateStmt +== 240 +alter table nv_child_2010 add check (d between '2010-01-01'::date and '2010-12-31'::date) not valid +-- +TABLE: name="nv_child_2010" schema="" table="nv_child_2010" ctx=DDL +STMT: AlterTableStmt +== 241 +alter table nv_child_2011 add check (d between '2011-01-01'::date and '2011-12-31'::date) not valid +-- +TABLE: name="nv_child_2011" schema="" table="nv_child_2011" ctx=DDL +STMT: AlterTableStmt +== 242 +explain (costs off) select * from nv_parent where d between '2011-08-01' and '2011-08-31' +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +== 243 +create table nv_child_2009 (check (d between '2009-01-01'::date and '2009-12-31'::date)) inherits (nv_parent) +-- +TABLE: name="nv_child_2009" schema="" table="nv_child_2009" ctx=DDL +STMT: CreateStmt +== 244 +explain (costs off) select * from nv_parent where d between '2011-08-01'::date and '2011-08-31'::date +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +== 245 +explain (costs off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +== 246 +-- after validation, the constraint should be used +alter table nv_child_2011 VALIDATE CONSTRAINT nv_child_2011_d_check +-- +TABLE: name="nv_child_2011" schema="" table="nv_child_2011" ctx=DDL +STMT: AlterTableStmt +== 247 +explain (costs off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +== 248 +-- add an inherited NOT VALID constraint +alter table nv_parent add check (d between '2001-01-01'::date and '2099-12-31'::date) not valid +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=DDL +STMT: AlterTableStmt +== 249 +-- we leave nv_parent and children around to help test pg_dump logic + +-- Foreign key adding test with mixed types + +-- Note: these tables are TEMP to avoid name conflicts when this test +-- is run in parallel with foreign_key.sql. + +CREATE TEMP TABLE PKTABLE (ptest1 int PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 250 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 251 +CREATE TEMP TABLE FKTABLE (ftest1 inet) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 252 +-- This next should fail, because int=inet does not exist +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 253 +-- This should also fail for the same reason, but here we +-- give the column name +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 254 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 255 +-- This should succeed, even though they are different types, +-- because int=int8 exists and is a member of the integer opfamily +CREATE TEMP TABLE FKTABLE (ftest1 int8) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 256 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 257 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 258 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 259 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 260 +-- This should fail, because we'd have to cast numeric to int which is +-- not an implicit coercion (or use numeric=numeric, but that's not part +-- of the integer opfamily) +CREATE TEMP TABLE FKTABLE (ftest1 numeric) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 261 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 262 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 263 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 264 +-- On the other hand, this should work because int implicitly promotes to +-- numeric, and we allow promotion on the FK side +CREATE TEMP TABLE PKTABLE (ptest1 numeric PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 265 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 266 +CREATE TEMP TABLE FKTABLE (ftest1 int) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 267 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 268 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 270 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 271 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 272 +CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet, + PRIMARY KEY(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 273 +-- This should fail, because we just chose really odd types +CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 274 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 275 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 276 +-- Again, so should this... +CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 277 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) + references pktable(ptest1, ptest2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 278 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 279 +-- This fails because we mixed up the column ordering +CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 280 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) + references pktable(ptest2, ptest1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 281 +-- As does this... +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1) + references pktable(ptest1, ptest2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 282 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 283 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 284 +-- Test that ALTER CONSTRAINT updates trigger deferrability properly + +CREATE TEMP TABLE PKTABLE (ptest1 int primary key) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 285 +CREATE TEMP TABLE FKTABLE (ftest1 int) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 286 +ALTER TABLE FKTABLE ADD CONSTRAINT fknd FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 287 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdd FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 288 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdi FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 289 +ALTER TABLE FKTABLE ADD CONSTRAINT fknd2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 290 +ALTER TABLE FKTABLE ALTER CONSTRAINT fknd2 NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 291 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdd2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 292 +ALTER TABLE FKTABLE ALTER CONSTRAINT fkdd2 DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 293 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdi2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 294 +ALTER TABLE FKTABLE ALTER CONSTRAINT fkdi2 DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 295 +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred +FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint +WHERE tgrelid = 'pktable'::regclass +ORDER BY 1,2,3 +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 296 +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred +FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint +WHERE tgrelid = 'fktable'::regclass +ORDER BY 1,2,3 +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 297 +-- temp tables should go away by themselves, need not drop them. + +-- test check constraint adding + +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 298 +-- add a check constraint +alter table atacc1 add constraint atacc_test1 check (test>3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 299 +-- should fail +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 300 +-- should succeed +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 301 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 302 +-- let's do one where the check fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 303 +-- insert a soon to be failing row +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 304 +-- add a check constraint (fails) +alter table atacc1 add constraint atacc_test1 check (test>3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 305 +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 307 +-- let's do one where the check fails because the column doesn't exist +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 308 +-- add a check constraint (fails) +alter table atacc1 add constraint atacc_test1 check (test1>3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 309 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 310 +-- something a little more complicated +create table atacc1 ( test int, test2 int, test3 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 311 +-- add a check constraint (fails) +alter table atacc1 add constraint atacc_test1 check (test+test23), test2 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 316 +alter table atacc1 add check (test2>test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 317 +-- should fail for $2 +insert into atacc1 (test2, test) values (3, 4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 318 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 319 +-- inheritance related tests +create table atacc1 (test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 320 +create table atacc2 (test2 int) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +== 321 +create table atacc3 (test3 int) inherits (atacc1, atacc2) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: CreateStmt +== 322 +alter table atacc2 add constraint foo check (test2>0) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +== 323 +-- fail and then succeed on atacc2 +insert into atacc2 (test2) values (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 324 +insert into atacc2 (test2) values (3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 325 +-- fail and then succeed on atacc3 +insert into atacc3 (test2) values (-3) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 326 +insert into atacc3 (test2) values (3) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 327 +drop table atacc3 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: DropStmt +== 328 +drop table atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +== 329 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 330 +-- same things with one created with INHERIT +create table atacc1 (test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 331 +create table atacc2 (test2 int) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +== 332 +create table atacc3 (test3 int) inherits (atacc1, atacc2) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: CreateStmt +== 333 +alter table atacc3 no inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 334 +-- fail +alter table atacc3 no inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 335 +-- make sure it really isn't a child +insert into atacc3 (test2) values (3) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 336 +select test2 from atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=Select +STMT: SelectStmt +== 337 +-- fail due to missing constraint +alter table atacc2 add constraint foo check (test2>0) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +== 338 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 339 +-- fail due to missing column +alter table atacc3 rename test2 to testx +-- +STMT: RenameStmt +== 340 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 341 +-- fail due to mismatched data type +alter table atacc3 add test2 bool +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 342 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 343 +alter table atacc3 drop test2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 344 +-- succeed +alter table atacc3 add test2 int +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 345 +update atacc3 set test2 = 4 where test2 is null +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: UpdateStmt +== 346 +alter table atacc3 add constraint foo check (test2>0) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 347 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 348 +-- fail due to duplicates and circular inheritance +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +== 349 +alter table atacc2 inherit atacc3 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +== 350 +alter table atacc2 inherit atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +== 351 +-- test that we really are a child now (should see 4 not 3 and cascade should go through) +select test2 from atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=Select +STMT: SelectStmt +== 352 +drop table atacc2 cascade +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +== 353 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 354 +-- adding only to a parent is allowed as of 9.2 + +create table atacc1 (test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 355 +create table atacc2 (test2 int) inherits (atacc1) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +== 356 +-- ok: +alter table atacc1 add constraint foo check (test>0) no inherit +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 357 +-- check constraint is not there on child +insert into atacc2 (test) values (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 358 +-- check constraint is there on parent +insert into atacc1 (test) values (-3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 359 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +-- fail, violating row: +alter table atacc2 add constraint foo check (test>0) no inherit +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +== 361 +drop table atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +== 362 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 363 +-- test unique constraint adding + +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 364 +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 365 +-- insert first value +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 366 +-- should fail +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 367 +-- should succeed +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 368 +-- try to create duplicates via alter table using - should fail +alter table atacc1 alter column test type integer using 0 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 369 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 370 +-- let's do one where the unique constraint fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 371 +-- insert soon to be failing rows +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 372 +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 373 +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 374 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 375 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 376 +-- let's do one where the unique constraint fails +-- because the column doesn't exist +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 377 +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 378 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 379 +-- something a little more complicated +create table atacc1 ( test int, test2 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 380 +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test, test2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 381 +-- insert initial value +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 382 +-- should fail +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 383 +-- should all succeed +insert into atacc1 (test,test2) values (4,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 384 +insert into atacc1 (test,test2) values (5,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 385 +insert into atacc1 (test,test2) values (5,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 386 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 387 +-- lets do some naming tests +create table atacc1 (test int, test2 int, unique(test)) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 388 +alter table atacc1 add unique (test2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 389 +-- should fail for @@ second one @@ +insert into atacc1 (test2, test) values (3, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 390 +insert into atacc1 (test2, test) values (2, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 391 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 392 +-- test primary key constraint adding + +create table atacc1 ( id serial, test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 393 +-- add a primary key constraint +alter table atacc1 add constraint atacc_test1 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 394 +-- insert first value +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 395 +-- should fail +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 396 +-- should succeed +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 397 +-- inserting NULL should fail +insert into atacc1 (test) values(NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 398 +-- try adding a second primary key (should fail) +alter table atacc1 add constraint atacc_oid1 primary key(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 399 +-- drop first primary key constraint +alter table atacc1 drop constraint atacc_test1 restrict +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 400 +-- try adding a primary key on oid (should succeed) +alter table atacc1 add constraint atacc_oid1 primary key(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 401 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 402 +-- let's do one where the primary key constraint fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 403 +-- insert soon to be failing rows +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 404 +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 405 +-- add a primary key (fails) +alter table atacc1 add constraint atacc_test1 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 406 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 407 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 408 +-- let's do another one where the primary key constraint fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 409 +-- insert soon to be failing row +insert into atacc1 (test) values (NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 410 +-- add a primary key (fails) +alter table atacc1 add constraint atacc_test1 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 411 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 412 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 413 +-- let's do one where the primary key constraint fails +-- because the column doesn't exist +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 414 +-- add a primary key constraint (fails) +alter table atacc1 add constraint atacc_test1 primary key (test1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 415 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 416 +-- adding a new column as primary key to a non-empty table. +-- should fail unless the column has a non-null default value. +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 417 +insert into atacc1 (test) values (0) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 418 +-- add a primary key column without a default (fails). +alter table atacc1 add column test2 int primary key +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 419 +-- now add a primary key column with a default (succeeds). +alter table atacc1 add column test2 int default 0 primary key +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 420 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 421 +-- this combination used to have order-of-execution problems (bug #15580) +create table atacc1 (a int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 422 +insert into atacc1 values(1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 423 +alter table atacc1 + add column b float8 not null default random(), + add primary key(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 424 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 425 +-- additionally, we've seen issues with foreign key validation not being +-- properly delayed until after a table rewrite. Check that works ok. +create table atacc1 (a int primary key) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 426 +alter table atacc1 add constraint atacc1_fkey foreign key (a) references atacc1 (a) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 427 +alter table atacc1 validate constraint atacc1_fkey, alter a type bigint +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 428 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 429 +-- we've also seen issues with check constraints being validated at the wrong +-- time when there's a pending table rewrite. +create table atacc1 (a bigint, b int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 430 +insert into atacc1 values(1,1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 431 +alter table atacc1 add constraint atacc1_chk check(b = 1) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 432 +alter table atacc1 validate constraint atacc1_chk, alter a type int +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 433 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 434 +-- same as above, but ensure the constraint violation is detected +create table atacc1 (a bigint, b int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 435 +insert into atacc1 values(1,2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 436 +alter table atacc1 add constraint atacc1_chk check(b = 1) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 437 +alter table atacc1 validate constraint atacc1_chk, alter a type int +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 438 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 439 +-- something a little more complicated +create table atacc1 ( test int, test2 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 440 +-- add a primary key constraint +alter table atacc1 add constraint atacc_test1 primary key (test, test2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 441 +-- try adding a second primary key - should fail +alter table atacc1 add constraint atacc_test2 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 442 +-- insert initial value +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 443 +-- should fail +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 444 +insert into atacc1 (test,test2) values (NULL,3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 445 +insert into atacc1 (test,test2) values (3, NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 446 +insert into atacc1 (test,test2) values (NULL,NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 447 +-- should all succeed +insert into atacc1 (test,test2) values (4,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 448 +insert into atacc1 (test,test2) values (5,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 449 +insert into atacc1 (test,test2) values (5,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 450 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 451 +-- lets do some naming tests +create table atacc1 (test int, test2 int, primary key(test)) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 452 +-- only first should succeed +insert into atacc1 (test2, test) values (3, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 453 +insert into atacc1 (test2, test) values (2, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 454 +insert into atacc1 (test2, test) values (1, NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 455 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 456 +-- alter table / alter column [set/drop] not null tests +-- try altering system catalogs, should fail +alter table pg_class alter column relname drop not null +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: AlterTableStmt +== 457 +alter table pg_class alter relname set not null +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: AlterTableStmt +== 458 +-- try altering non-existent table, should fail +alter table non_existent alter column bar set not null +-- +TABLE: name="non_existent" schema="" table="non_existent" ctx=DDL +STMT: AlterTableStmt +== 459 +alter table non_existent alter column bar drop not null +-- +TABLE: name="non_existent" schema="" table="non_existent" ctx=DDL +STMT: AlterTableStmt +== 460 +-- test setting columns to null and not null and vice versa +-- test checking for null values and primary key +create table atacc1 (test int not null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 461 +alter table atacc1 add constraint "atacc1_pkey" primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 462 +alter table atacc1 alter column test drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 463 +alter table atacc1 drop constraint "atacc1_pkey" +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 464 +alter table atacc1 alter column test drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 465 +insert into atacc1 values (null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 466 +alter table atacc1 alter test set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 467 +delete from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +== 468 +alter table atacc1 alter test set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 469 +-- try altering a non-existent column, should fail +alter table atacc1 alter bar set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 470 +alter table atacc1 alter bar drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 471 +-- try creating a view and altering that, should fail +create view myview as select * from atacc1 +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 472 +alter table myview alter column test drop not null +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: AlterTableStmt +== 473 +alter table myview alter column test set not null +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: AlterTableStmt +== 474 +drop view myview +-- +STMT: DropStmt +== 475 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 476 +-- set not null verified by constraints +create table atacc1 (test_a int, test_b int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 477 +insert into atacc1 values (null, 1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 478 +-- constraint not cover all values, should fail +alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 479 +alter table atacc1 alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 480 +alter table atacc1 drop constraint atacc1_constr_or +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 481 +-- not valid constraint, should fail +alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 482 +alter table atacc1 alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 483 +alter table atacc1 drop constraint atacc1_constr_invalid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 484 +-- with valid constraint +update atacc1 set test_a = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +== 485 +alter table atacc1 add constraint atacc1_constr_a_valid check(test_a is not null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 486 +alter table atacc1 alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 487 +delete from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +== 488 +insert into atacc1 values (2, null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 489 +alter table atacc1 alter test_a drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 490 +-- test multiple set not null at same time +-- test_a checked by atacc1_constr_a_valid, test_b should fail by table scan +alter table atacc1 alter test_a set not null, alter test_b set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 491 +-- commands order has no importance +alter table atacc1 alter test_b set not null, alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 492 +-- valid one by table scan, one by check constraints +update atacc1 set test_b = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +== 493 +alter table atacc1 alter test_b set not null, alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 494 +alter table atacc1 alter test_a drop not null, alter test_b drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 495 +-- both column has check constraints +alter table atacc1 add constraint atacc1_constr_b_valid check(test_b is not null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 496 +alter table atacc1 alter test_b set not null, alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 497 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 498 +-- test inheritance +create table parent (a int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 499 +create table child (b varchar(255)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 500 +alter table parent alter a set not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 501 +insert into parent values (NULL) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 502 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 503 +alter table parent alter a drop not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 504 +insert into parent values (NULL) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 505 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 506 +alter table only parent alter a set not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 507 +alter table child alter a set not null +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +== 508 +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +== 509 +alter table only parent alter a set not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 510 +insert into parent values (NULL) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 511 +alter table child alter a set not null +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +== 512 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 513 +delete from child +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: DeleteStmt +== 514 +alter table child alter a set not null +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +== 515 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 516 +drop table child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 517 +drop table parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 518 +-- test setting and removing default values +create table def_test ( + c1 int4 default 5, + c2 text default 'initial_default' +) +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: CreateStmt +== 519 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +== 520 +alter table def_test alter column c1 drop default +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +== 521 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +== 522 +alter table def_test alter column c2 drop default +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +== 523 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +== 524 +alter table def_test alter column c1 set default 10 +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +== 525 +alter table def_test alter column c2 set default 'new_default' +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +== 526 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +== 527 +select * from def_test +-- +TABLE: name="def_test" schema="" table="def_test" ctx=Select +STMT: SelectStmt +== 528 +-- set defaults to an incorrect type: this should fail +alter table def_test alter column c1 set default 'wrong_datatype' +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +== 529 +alter table def_test alter column c2 set default 20 +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +== 530 +-- set defaults on a non-existent column: this should fail +alter table def_test alter column c3 set default 30 +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +== 531 +-- set defaults on views: we need to create a view, add a rule +-- to allow insertions into it, and then alter the view to add +-- a default +create view def_view_test as select * from def_test +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +TABLE: name="def_test" schema="" table="def_test" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 532 +create rule def_view_test_ins as + on insert to def_view_test + do instead insert into def_test select new.* +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: RuleStmt +== 533 +insert into def_view_test default values +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DML +STMT: InsertStmt +== 534 +alter table def_view_test alter column c1 set default 45 +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: AlterTableStmt +== 535 +insert into def_view_test default values +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DML +STMT: InsertStmt +== 536 +alter table def_view_test alter column c2 set default 'view_default' +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: AlterTableStmt +== 537 +insert into def_view_test default values +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DML +STMT: InsertStmt +== 538 +select * from def_view_test +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=Select +STMT: SelectStmt +== 539 +drop rule def_view_test_ins on def_view_test +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: DropStmt +== 540 +drop view def_view_test +-- +STMT: DropStmt +== 541 +drop table def_test +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: DropStmt +== 542 +-- alter table / drop column tests +-- try altering system catalogs, should fail +alter table pg_class drop column relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: AlterTableStmt +== 543 +-- try altering non-existent table, should fail +alter table nosuchtable drop column bar +-- +TABLE: name="nosuchtable" schema="" table="nosuchtable" ctx=DDL +STMT: AlterTableStmt +== 544 +-- test dropping columns +create table atacc1 (a int4 not null, b int4, c int4 not null, d int4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 545 +insert into atacc1 values (1, 2, 3, 4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 546 +alter table atacc1 drop a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 547 +alter table atacc1 drop a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 548 +-- SELECTs +select * from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 549 +select * from atacc1 order by a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 550 +select * from atacc1 order by "........pg.dropped.1........" +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 551 +select * from atacc1 group by a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 552 +select * from atacc1 group by "........pg.dropped.1........" +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 553 +select atacc1.* from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 554 +select a from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 555 +select atacc1.a from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 556 +select b,c,d from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 557 +select a,b,c,d from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 558 +select * from atacc1 where a = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 559 +select "........pg.dropped.1........" from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 560 +select atacc1."........pg.dropped.1........" from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 561 +select "........pg.dropped.1........",b,c,d from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 562 +select * from atacc1 where "........pg.dropped.1........" = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +FILTER: schema="" table="" column="........pg.dropped.1........" +STMT: SelectStmt +== 563 +-- UPDATEs +update atacc1 set a = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +== 564 +update atacc1 set b = 2 where a = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +== 565 +update atacc1 set "........pg.dropped.1........" = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +== 566 +update atacc1 set b = 2 where "........pg.dropped.1........" = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +== 567 +-- INSERTs +insert into atacc1 values (10, 11, 12, 13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 568 +insert into atacc1 values (default, 11, 12, 13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 569 +insert into atacc1 values (11, 12, 13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 570 +insert into atacc1 (a) values (10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 571 +insert into atacc1 (a) values (default) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 572 +insert into atacc1 (a,b,c,d) values (10,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 573 +insert into atacc1 (a,b,c,d) values (default,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 574 +insert into atacc1 (b,c,d) values (11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 575 +insert into atacc1 ("........pg.dropped.1........") values (10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 576 +insert into atacc1 ("........pg.dropped.1........") values (default) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 577 +insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 578 +insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 579 +-- DELETEs +delete from atacc1 where a = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +== 580 +delete from atacc1 where "........pg.dropped.1........" = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +== 581 +delete from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +== 582 +-- try dropping a non-existent column, should fail +alter table atacc1 drop bar +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 583 +-- try removing an oid column, should succeed (as it's nonexistent) +alter table atacc1 SET WITHOUT OIDS +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 584 +-- try adding an oid column, should fail (not supported) +alter table atacc1 SET WITH OIDS +-- +ERROR: syntax error at or near "WITH" +CURSORPOS: 81 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 585 +-- try dropping the xmin column, should fail +alter table atacc1 drop xmin +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 586 +-- try creating a view and altering that, should fail +create view myview as select * from atacc1 +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 587 +select * from myview +-- +TABLE: name="myview" schema="" table="myview" ctx=Select +STMT: SelectStmt +== 588 +alter table myview drop d +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: AlterTableStmt +== 589 +drop view myview +-- +STMT: DropStmt +== 590 +-- test some commands to make sure they fail on the dropped column +analyze atacc1(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +== 591 +analyze atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +== 592 +vacuum analyze atacc1(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +== 593 +vacuum analyze atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +== 594 +comment on column atacc1.a is 'testing' +-- +STMT: CommentStmt +== 595 +comment on column atacc1."........pg.dropped.1........" is 'testing' +-- +STMT: CommentStmt +== 596 +alter table atacc1 alter a set storage plain +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 597 +alter table atacc1 alter "........pg.dropped.1........" set storage plain +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 598 +alter table atacc1 alter a set statistics 0 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 599 +alter table atacc1 alter "........pg.dropped.1........" set statistics 0 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 600 +alter table atacc1 alter a set default 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 601 +alter table atacc1 alter "........pg.dropped.1........" set default 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 602 +alter table atacc1 alter a drop default +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 603 +alter table atacc1 alter "........pg.dropped.1........" drop default +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 604 +alter table atacc1 alter a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 605 +alter table atacc1 alter "........pg.dropped.1........" set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 606 +alter table atacc1 alter a drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 607 +alter table atacc1 alter "........pg.dropped.1........" drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 608 +alter table atacc1 rename a to x +-- +STMT: RenameStmt +== 609 +alter table atacc1 rename "........pg.dropped.1........" to x +-- +STMT: RenameStmt +== 610 +alter table atacc1 add primary key(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 611 +alter table atacc1 add primary key("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 612 +alter table atacc1 add unique(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 613 +alter table atacc1 add unique("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 614 +alter table atacc1 add check (a > 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 615 +alter table atacc1 add check ("........pg.dropped.1........" > 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 616 +create table atacc2 (id int4 unique) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +== 617 +alter table atacc1 add foreign key (a) references atacc2(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 618 +alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 619 +alter table atacc2 add foreign key (id) references atacc1(a) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +== 620 +alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +== 621 +drop table atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +== 622 +create index "testing_idx" on atacc1(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: IndexStmt +== 623 +create index "testing_idx" on atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: IndexStmt +== 624 +-- test create as and select into +insert into atacc1 values (21, 22, 23) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 625 +create table attest1 as select * from atacc1 +-- +TABLE: name="attest1" schema="" table="attest1" ctx=DDL +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 626 +select * from attest1 +-- +TABLE: name="attest1" schema="" table="attest1" ctx=Select +STMT: SelectStmt +== 627 +drop table attest1 +-- +TABLE: name="attest1" schema="" table="attest1" ctx=DDL +STMT: DropStmt +== 628 +select * into attest2 from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +TABLE: name="attest2" schema="" table="attest2" ctx=DDL +STMT: SelectStmt +== 629 +select * from attest2 +-- +TABLE: name="attest2" schema="" table="attest2" ctx=Select +STMT: SelectStmt +== 630 +drop table attest2 +-- +TABLE: name="attest2" schema="" table="attest2" ctx=DDL +STMT: DropStmt +== 631 +-- try dropping all columns +alter table atacc1 drop c +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 632 +alter table atacc1 drop d +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 633 +alter table atacc1 drop b +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 634 +select * from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +== 635 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 636 +-- test constraint error reporting in presence of dropped columns +create table atacc1 (id serial primary key, value int check (value < 10)) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 637 +insert into atacc1(value) values (100) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 638 +alter table atacc1 drop column value +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 639 +alter table atacc1 add column value int check (value < 10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +== 640 +insert into atacc1(value) values (100) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 641 +insert into atacc1(id, value) values (null, 0) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 642 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 643 +-- test inheritance +create table parent (a int, b int, c int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 644 +insert into parent values (1, 2, 3) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 645 +alter table parent drop a +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 646 +create table child (d varchar(255)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 647 +insert into child values (12, 13, 'testing') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 648 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 649 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +== 650 +alter table parent drop c +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 651 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 652 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +== 653 +drop table child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 654 +drop table parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 655 +-- check error cases for inheritance column merging +create table parent (a float8, b numeric(10,4), c text collate "C") +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 656 +create table child (a float4) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 657 +-- fail +create table child (b decimal(10,7)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 658 +-- fail +create table child (c text collate "POSIX") inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 659 +-- fail +create table child (a double precision, b decimal(10,4)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 660 +drop table child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 661 +drop table parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 662 +-- test copy in/out +create table attest (a int4, b int4, c int4) +-- +TABLE: name="attest" schema="" table="attest" ctx=DDL +STMT: CreateStmt +== 663 +insert into attest values (1,2,3) +-- +TABLE: name="attest" schema="" table="attest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 664 +alter table attest drop a +-- +TABLE: name="attest" schema="" table="attest" ctx=DDL +STMT: AlterTableStmt +== 665 +copy attest to stdout +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +== 666 +copy attest(a) to stdout +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +== 667 +copy attest("........pg.dropped.1........") to stdout +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +== 668 +copy attest from stdin +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +== 669 +select * from attest +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: SelectStmt +== 670 +copy attest from stdin +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +== 671 +select * from attest +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: SelectStmt +== 672 +copy attest(a) from stdin +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +== 673 +select * from attest +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: SelectStmt +== 674 +drop table attest +-- +TABLE: name="attest" schema="" table="attest" ctx=DDL +STMT: DropStmt +== 675 +-- test inheritance + +create table dropColumn (a int, b int, e int) +-- +TABLE: name="dropcolumn" schema="" table="dropcolumn" ctx=DDL +STMT: CreateStmt +== 676 +create table dropColumnChild (c int) inherits (dropColumn) +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: CreateStmt +== 677 +create table dropColumnAnother (d int) inherits (dropColumnChild) +-- +TABLE: name="dropcolumnanother" schema="" table="dropcolumnanother" ctx=DDL +STMT: CreateStmt +== 678 +-- these two should fail +alter table dropColumnchild drop column a +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: AlterTableStmt +== 679 +alter table only dropColumnChild drop column b +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: AlterTableStmt +== 680 +-- these three should work +alter table only dropColumn drop column e +-- +TABLE: name="dropcolumn" schema="" table="dropcolumn" ctx=DDL +STMT: AlterTableStmt +== 681 +alter table dropColumnChild drop column c +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: AlterTableStmt +== 682 +alter table dropColumn drop column a +-- +TABLE: name="dropcolumn" schema="" table="dropcolumn" ctx=DDL +STMT: AlterTableStmt +== 683 +create table renameColumn (a int) +-- +TABLE: name="renamecolumn" schema="" table="renamecolumn" ctx=DDL +STMT: CreateStmt +== 684 +create table renameColumnChild (b int) inherits (renameColumn) +-- +TABLE: name="renamecolumnchild" schema="" table="renamecolumnchild" ctx=DDL +STMT: CreateStmt +== 685 +create table renameColumnAnother (c int) inherits (renameColumnChild) +-- +TABLE: name="renamecolumnanother" schema="" table="renamecolumnanother" ctx=DDL +STMT: CreateStmt +== 686 +-- these three should fail +alter table renameColumnChild rename column a to d +-- +STMT: RenameStmt +== 687 +alter table only renameColumnChild rename column a to d +-- +STMT: RenameStmt +== 688 +alter table only renameColumn rename column a to d +-- +STMT: RenameStmt +== 689 +-- these should work +alter table renameColumn rename column a to d +-- +STMT: RenameStmt +== 690 +alter table renameColumnChild rename column b to a +-- +STMT: RenameStmt +== 691 +-- these should work +alter table if exists doesnt_exist_tab rename column a to d +-- +STMT: RenameStmt +== 692 +alter table if exists doesnt_exist_tab rename column b to a +-- +STMT: RenameStmt +== 693 +-- this should work +alter table renameColumn add column w int +-- +TABLE: name="renamecolumn" schema="" table="renamecolumn" ctx=DDL +STMT: AlterTableStmt +== 694 +-- this should fail +alter table only renameColumn add column x int +-- +TABLE: name="renamecolumn" schema="" table="renamecolumn" ctx=DDL +STMT: AlterTableStmt +== 695 +-- Test corner cases in dropping of inherited columns + +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 696 +create table c1 (f1 int not null) inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 697 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 698 +-- should work +alter table p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 699 +-- c1.f1 is still there, but no longer inherited +select f1 from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +STMT: SelectStmt +== 700 +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 701 +select f1 from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +STMT: SelectStmt +== 702 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 703 +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 704 +create table c1 () inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 705 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 706 +alter table p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 707 +-- c1.f1 is dropped now, since there is no local definition for it +select f1 from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +STMT: SelectStmt +== 708 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 709 +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 710 +create table c1 () inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 711 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 712 +alter table only p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 713 +-- c1.f1 is NOT dropped, but must now be considered non-inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 714 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 715 +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 716 +create table c1 (f1 int not null) inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 717 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 718 +alter table only p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 719 +-- c1.f1 is still there, but no longer inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 720 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 721 +create table p1(id int, name text) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 722 +create table p2(id2 int, name text, height int) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +== 723 +create table c1(age int) inherits(p1,p2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 724 +create table gc1() inherits (c1) +-- +TABLE: name="gc1" schema="" table="gc1" ctx=DDL +STMT: CreateStmt +== 725 +select relname, attname, attinhcount, attislocal +from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid) +where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped +order by relname, attnum +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attisdropped" +STMT: SelectStmt +== 726 +-- should work +alter table only p1 drop column name +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 727 +-- should work. Now c1.name is local and inhcount is 0. +alter table p2 drop column name +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +== 728 +-- should be rejected since its inherited +alter table gc1 drop column name +-- +TABLE: name="gc1" schema="" table="gc1" ctx=DDL +STMT: AlterTableStmt +== 729 +-- should work, and drop gc1.name along +alter table c1 drop column name +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +== 730 +-- should fail: column does not exist +alter table gc1 drop column name +-- +TABLE: name="gc1" schema="" table="gc1" ctx=DDL +STMT: AlterTableStmt +== 731 +-- should work and drop the attribute in all tables +alter table p2 drop column height +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +== 732 +-- IF EXISTS test +create table dropColumnExists () +-- +TABLE: name="dropcolumnexists" schema="" table="dropcolumnexists" ctx=DDL +STMT: CreateStmt +== 733 +alter table dropColumnExists drop column non_existing +-- +TABLE: name="dropcolumnexists" schema="" table="dropcolumnexists" ctx=DDL +STMT: AlterTableStmt +== 734 +--fail +alter table dropColumnExists drop column if exists non_existing +-- +TABLE: name="dropcolumnexists" schema="" table="dropcolumnexists" ctx=DDL +STMT: AlterTableStmt +== 735 +--succeed + +select relname, attname, attinhcount, attislocal +from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid) +where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped +order by relname, attnum +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attisdropped" +STMT: SelectStmt +== 736 +drop table p1, p2 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +== 737 +-- test attinhcount tracking with merged columns + +create table depth0() +-- +TABLE: name="depth0" schema="" table="depth0" ctx=DDL +STMT: CreateStmt +== 738 +create table depth1(c text) inherits (depth0) +-- +TABLE: name="depth1" schema="" table="depth1" ctx=DDL +STMT: CreateStmt +== 739 +create table depth2() inherits (depth1) +-- +TABLE: name="depth2" schema="" table="depth2" ctx=DDL +STMT: CreateStmt +== 740 +alter table depth0 add c text +-- +TABLE: name="depth0" schema="" table="depth0" ctx=DDL +STMT: AlterTableStmt +== 741 +select attrelid::regclass, attname, attinhcount, attislocal +from pg_attribute +where attnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2') +order by attrelid::regclass::text, attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +== 742 +-- test renumbering of child-table columns in inherited operations + +create table p1 (f1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 743 +create table c1 (f2 text, f3 int) inherits (p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 744 +alter table p1 add column a1 int check (a1 > 0) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 745 +alter table p1 add column f2 text +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 746 +insert into p1 values (1,2,'abc') +-- +TABLE: name="p1" schema="" table="p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 747 +insert into c1 values(11,'xyz',33,0) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 748 +-- should fail +insert into c1 values(11,'xyz',33,22) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 749 +select * from p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=Select +STMT: SelectStmt +== 750 +update p1 set a1 = a1 + 1, f2 = upper(f2) +-- +TABLE: name="p1" schema="" table="p1" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: UpdateStmt +== 751 +select * from p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=Select +STMT: SelectStmt +== 752 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 753 +-- test that operations with a dropped column do not try to reference +-- its datatype + +create domain mytype as text +-- +STMT: CreateDomainStmt +== 754 +create temp table foo (f1 text, f2 mytype, f3 text) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 755 +insert into foo values('bb','cc','dd') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 756 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 757 +drop domain mytype cascade +-- +STMT: DropStmt +== 758 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 759 +insert into foo values('qq','rr') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 760 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 761 +update foo set f3 = 'zz' +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: UpdateStmt +== 762 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 763 +select f3,max(f1) from foo group by f3 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 764 +-- Simple tests for alter table column type +alter table foo alter f1 TYPE integer +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: AlterTableStmt +== 765 +-- fails +alter table foo alter f1 TYPE varchar(10) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: AlterTableStmt +== 766 +create table anothertab (atcol1 serial8, atcol2 boolean, + constraint anothertab_chk check (atcol1 <= 3)) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: CreateStmt +== 767 +insert into anothertab (atcol1, atcol2) values (default, true) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 768 +insert into anothertab (atcol1, atcol2) values (default, false) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 769 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +== 770 +alter table anothertab alter column atcol1 type boolean +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 771 +-- fails +alter table anothertab alter column atcol1 type boolean using atcol1::int +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 772 +-- fails +alter table anothertab alter column atcol1 type integer +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 773 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +== 774 +insert into anothertab (atcol1, atcol2) values (45, null) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 775 +-- fails +insert into anothertab (atcol1, atcol2) values (default, null) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 776 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +== 777 +alter table anothertab alter column atcol2 type text + using case when atcol2 is true then 'IT WAS TRUE' + when atcol2 is false then 'IT WAS FALSE' + else 'IT WAS NULL!' end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 778 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +== 779 +alter table anothertab alter column atcol1 type boolean + using case when atcol1 % 2 = 0 then true else false end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 780 +-- fails +alter table anothertab alter column atcol1 drop default +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 781 +alter table anothertab alter column atcol1 type boolean + using case when atcol1 % 2 = 0 then true else false end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 782 +-- fails +alter table anothertab drop constraint anothertab_chk +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 783 +alter table anothertab drop constraint anothertab_chk +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 784 +-- fails +alter table anothertab drop constraint IF EXISTS anothertab_chk +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 785 +-- succeeds + +alter table anothertab alter column atcol1 type boolean + using case when atcol1 % 2 = 0 then true else false end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 786 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +== 787 +drop table anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: DropStmt +== 788 +-- Test index handling in alter table column type (cf. bugs #15835, #15865) +create table anothertab(f1 int primary key, f2 int unique, + f3 int, f4 int, f5 int) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: CreateStmt +== 789 +alter table anothertab + add exclude using btree (f3 with =) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 790 +alter table anothertab + add exclude using btree (f4 with =) where (f4 is not null) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 791 +alter table anothertab + add exclude using btree (f4 with =) where (f5 > 0) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 792 +alter table anothertab + add unique(f1,f4) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 793 +create index on anothertab(f2,f3) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: IndexStmt +== 794 +create unique index on anothertab(f4) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: IndexStmt +== 795 +alter table anothertab alter column f1 type bigint +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 796 +alter table anothertab + alter column f2 type bigint, + alter column f3 type bigint, + alter column f4 type bigint +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 797 +alter table anothertab alter column f5 type bigint +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +== 798 +drop table anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: DropStmt +== 799 +-- test that USING expressions are parsed before column alter type / drop steps +create table another (f1 int, f2 text, f3 text) +-- +TABLE: name="another" schema="" table="another" ctx=DDL +STMT: CreateStmt +== 800 +insert into another values(1, 'one', 'uno') +-- +TABLE: name="another" schema="" table="another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 801 +insert into another values(2, 'two', 'due') +-- +TABLE: name="another" schema="" table="another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 802 +insert into another values(3, 'three', 'tre') +-- +TABLE: name="another" schema="" table="another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 803 +select * from another +-- +TABLE: name="another" schema="" table="another" ctx=Select +STMT: SelectStmt +== 804 +alter table another + alter f1 type text using f2 || ' and ' || f3 || ' more', + alter f2 type bigint using f1 * 10, + drop column f3 +-- +TABLE: name="another" schema="" table="another" ctx=DDL +STMT: AlterTableStmt +== 805 +select * from another +-- +TABLE: name="another" schema="" table="another" ctx=Select +STMT: SelectStmt +== 806 +drop table another +-- +TABLE: name="another" schema="" table="another" ctx=DDL +STMT: DropStmt +== 807 +-- Create an index that skips WAL, then perform a SET DATA TYPE that skips +-- rewriting the index. +begin +-- +STMT: TransactionStmt +== 808 +create table skip_wal_skip_rewrite_index (c varchar(10) primary key) +-- +TABLE: name="skip_wal_skip_rewrite_index" schema="" table="skip_wal_skip_rewrite_index" ctx=DDL +STMT: CreateStmt +== 809 +alter table skip_wal_skip_rewrite_index alter c type varchar(20) +-- +TABLE: name="skip_wal_skip_rewrite_index" schema="" table="skip_wal_skip_rewrite_index" ctx=DDL +STMT: AlterTableStmt +== 810 +commit +-- +STMT: TransactionStmt +== 811 +-- We disallow changing table's row type if it's used for storage +create table at_tab1 (a int, b text) +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: CreateStmt +== 812 +create table at_tab2 (x int, y at_tab1) +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: CreateStmt +== 813 +alter table at_tab1 alter column b type varchar +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: AlterTableStmt +== 814 +-- fails +drop table at_tab2 +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: DropStmt +== 815 +-- Use of row type in an expression is defended differently +create table at_tab2 (x int, y text, check((x,y)::at_tab1 = (1,'42')::at_tab1)) +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: CreateStmt +== 816 +alter table at_tab1 alter column b type varchar +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: AlterTableStmt +== 817 +-- allowed, but ... +insert into at_tab2 values(1,'42') +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 818 +-- ... this will fail +drop table at_tab1, at_tab2 +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: DropStmt +== 819 +-- Check it for a partitioned table, too +create table at_tab1 (a int, b text) partition by list(a) +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: CreateStmt +== 820 +create table at_tab2 (x int, y at_tab1) +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: CreateStmt +== 821 +alter table at_tab1 alter column b type varchar +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: AlterTableStmt +== 822 +-- fails +drop table at_tab1, at_tab2 +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: DropStmt +== 823 +-- Alter column type that's part of a partitioned index +create table at_partitioned (a int, b text) partition by range (a) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: CreateStmt +== 824 +create table at_part_1 partition of at_partitioned for values from (0) to (1000) +-- +TABLE: name="at_part_1" schema="" table="at_part_1" ctx=DDL +STMT: CreateStmt +== 825 +insert into at_partitioned values (512, '0.123') +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 826 +create table at_part_2 (b text, a int) +-- +TABLE: name="at_part_2" schema="" table="at_part_2" ctx=DDL +STMT: CreateStmt +== 827 +insert into at_part_2 values ('1.234', 1024) +-- +TABLE: name="at_part_2" schema="" table="at_part_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 828 +create index on at_partitioned (b) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: IndexStmt +== 829 +create index on at_partitioned (a) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: IndexStmt +== 830 +alter table at_partitioned attach partition at_part_2 for values from (1000) to (2000) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: AlterTableStmt +== 831 +alter table at_partitioned alter column b type numeric using b::numeric +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: AlterTableStmt +== 832 +drop table at_partitioned +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: DropStmt +== 833 +-- Alter column type when no table rewrite is required +-- Also check that comments are preserved +create table at_partitioned(id int, name varchar(64), unique (id, name)) + partition by hash(id) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: CreateStmt +== 834 +comment on constraint at_partitioned_id_name_key on at_partitioned is 'parent constraint' +-- +STMT: CommentStmt +== 835 +comment on index at_partitioned_id_name_key is 'parent index' +-- +STMT: CommentStmt +== 836 +create table at_partitioned_0 partition of at_partitioned + for values with (modulus 2, remainder 0) +-- +TABLE: name="at_partitioned_0" schema="" table="at_partitioned_0" ctx=DDL +STMT: CreateStmt +== 837 +comment on constraint at_partitioned_0_id_name_key on at_partitioned_0 is 'child 0 constraint' +-- +STMT: CommentStmt +== 838 +comment on index at_partitioned_0_id_name_key is 'child 0 index' +-- +STMT: CommentStmt +== 839 +create table at_partitioned_1 partition of at_partitioned + for values with (modulus 2, remainder 1) +-- +TABLE: name="at_partitioned_1" schema="" table="at_partitioned_1" ctx=DDL +STMT: CreateStmt +== 840 +comment on constraint at_partitioned_1_id_name_key on at_partitioned_1 is 'child 1 constraint' +-- +STMT: CommentStmt +== 841 +comment on index at_partitioned_1_id_name_key is 'child 1 index' +-- +STMT: CommentStmt +== 842 +insert into at_partitioned values(1, 'foo') +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 843 +insert into at_partitioned values(3, 'bar') +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 844 +create temp table old_oids as + select relname, oid as oldoid, relfilenode as oldfilenode + from pg_class where relname like 'at_partitioned%' +-- +TABLE: name="old_oids" schema="" table="old_oids" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 845 +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="old_oids" schema="" table="old_oids" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 846 +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 847 +alter table at_partitioned alter column name type varchar(127) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: AlterTableStmt +== 848 +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="old_oids" schema="" table="old_oids" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 849 +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 850 +-- Don't remove this DROP, it exposes bug #15672 +drop table at_partitioned +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: DropStmt +== 851 +-- disallow recursive containment of row types +create temp table recur1 (f1 int) +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: CreateStmt +== 852 +alter table recur1 add column f2 recur1 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +== 853 +-- fails +alter table recur1 add column f2 recur1[] +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +== 854 +-- fails +create domain array_of_recur1 as recur1[] +-- +STMT: CreateDomainStmt +== 855 +alter table recur1 add column f2 array_of_recur1 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +== 856 +-- fails +create temp table recur2 (f1 int, f2 recur1) +-- +TABLE: name="recur2" schema="" table="recur2" ctx=DDL +STMT: CreateStmt +== 857 +alter table recur1 add column f2 recur2 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +== 858 +-- fails +alter table recur1 add column f2 int +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +== 859 +alter table recur1 alter column f2 type recur2 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +== 860 +-- fails + +-- SET STORAGE may need to add a TOAST table +create table test_storage (a text, c text storage plain) +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: CreateStmt +== 861 +select reltoastrelid <> 0 as has_toast_table + from pg_class where oid = 'test_storage'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 862 +alter table test_storage alter a set storage plain +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +== 863 +-- rewrite table to remove its TOAST table; need a non-constant column default +alter table test_storage add b int default random()::int +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +== 864 +select reltoastrelid <> 0 as has_toast_table + from pg_class where oid = 'test_storage'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 865 +alter table test_storage alter a set storage default +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +== 866 +-- re-add TOAST table +select reltoastrelid <> 0 as has_toast_table + from pg_class where oid = 'test_storage'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 867 +-- check STORAGE correctness +create table test_storage_failed (a text, b int storage extended) +-- +TABLE: name="test_storage_failed" schema="" table="test_storage_failed" ctx=DDL +STMT: CreateStmt +== 868 +-- test that SET STORAGE propagates to index correctly +create index test_storage_idx on test_storage (b, a) +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: IndexStmt +== 869 +alter table test_storage alter column a set storage external +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +== 870 +-- ALTER COLUMN TYPE with a check constraint and a child table (bug #13779) +CREATE TABLE test_inh_check (a float check (a > 10.2), b float) +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: CreateStmt +== 871 +CREATE TABLE test_inh_check_child() INHERITS(test_inh_check) +-- +TABLE: name="test_inh_check_child" schema="" table="test_inh_check_child" ctx=DDL +STMT: CreateStmt +== 872 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +== 873 +ALTER TABLE test_inh_check ALTER COLUMN a TYPE numeric +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +== 874 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +== 875 +-- also try noinherit, local, and local+inherited cases +ALTER TABLE test_inh_check ADD CONSTRAINT bnoinherit CHECK (b > 100) NO INHERIT +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +== 876 +ALTER TABLE test_inh_check_child ADD CONSTRAINT blocal CHECK (b < 1000) +-- +TABLE: name="test_inh_check_child" schema="" table="test_inh_check_child" ctx=DDL +STMT: AlterTableStmt +== 877 +ALTER TABLE test_inh_check_child ADD CONSTRAINT bmerged CHECK (b > 1) +-- +TABLE: name="test_inh_check_child" schema="" table="test_inh_check_child" ctx=DDL +STMT: AlterTableStmt +== 878 +ALTER TABLE test_inh_check ADD CONSTRAINT bmerged CHECK (b > 1) +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +== 879 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +== 880 +ALTER TABLE test_inh_check ALTER COLUMN b TYPE numeric +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +== 881 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +== 882 +-- ALTER COLUMN TYPE with different schema in children +-- Bug at https://postgr.es/m/20170102225618.GA10071@telsasoft.com +CREATE TABLE test_type_diff (f1 int) +-- +TABLE: name="test_type_diff" schema="" table="test_type_diff" ctx=DDL +STMT: CreateStmt +== 883 +CREATE TABLE test_type_diff_c (extra smallint) INHERITS (test_type_diff) +-- +TABLE: name="test_type_diff_c" schema="" table="test_type_diff_c" ctx=DDL +STMT: CreateStmt +== 884 +ALTER TABLE test_type_diff ADD COLUMN f2 int +-- +TABLE: name="test_type_diff" schema="" table="test_type_diff" ctx=DDL +STMT: AlterTableStmt +== 885 +INSERT INTO test_type_diff_c VALUES (1, 2, 3) +-- +TABLE: name="test_type_diff_c" schema="" table="test_type_diff_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 886 +ALTER TABLE test_type_diff ALTER COLUMN f2 TYPE bigint USING f2::bigint +-- +TABLE: name="test_type_diff" schema="" table="test_type_diff" ctx=DDL +STMT: AlterTableStmt +== 887 +CREATE TABLE test_type_diff2 (int_two int2, int_four int4, int_eight int8) +-- +TABLE: name="test_type_diff2" schema="" table="test_type_diff2" ctx=DDL +STMT: CreateStmt +== 888 +CREATE TABLE test_type_diff2_c1 (int_four int4, int_eight int8, int_two int2) +-- +TABLE: name="test_type_diff2_c1" schema="" table="test_type_diff2_c1" ctx=DDL +STMT: CreateStmt +== 889 +CREATE TABLE test_type_diff2_c2 (int_eight int8, int_two int2, int_four int4) +-- +TABLE: name="test_type_diff2_c2" schema="" table="test_type_diff2_c2" ctx=DDL +STMT: CreateStmt +== 890 +CREATE TABLE test_type_diff2_c3 (int_two int2, int_four int4, int_eight int8) +-- +TABLE: name="test_type_diff2_c3" schema="" table="test_type_diff2_c3" ctx=DDL +STMT: CreateStmt +== 891 +ALTER TABLE test_type_diff2_c1 INHERIT test_type_diff2 +-- +TABLE: name="test_type_diff2_c1" schema="" table="test_type_diff2_c1" ctx=DDL +STMT: AlterTableStmt +== 892 +ALTER TABLE test_type_diff2_c2 INHERIT test_type_diff2 +-- +TABLE: name="test_type_diff2_c2" schema="" table="test_type_diff2_c2" ctx=DDL +STMT: AlterTableStmt +== 893 +ALTER TABLE test_type_diff2_c3 INHERIT test_type_diff2 +-- +TABLE: name="test_type_diff2_c3" schema="" table="test_type_diff2_c3" ctx=DDL +STMT: AlterTableStmt +== 894 +INSERT INTO test_type_diff2_c1 VALUES (1, 2, 3) +-- +TABLE: name="test_type_diff2_c1" schema="" table="test_type_diff2_c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 895 +INSERT INTO test_type_diff2_c2 VALUES (4, 5, 6) +-- +TABLE: name="test_type_diff2_c2" schema="" table="test_type_diff2_c2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 896 +INSERT INTO test_type_diff2_c3 VALUES (7, 8, 9) +-- +TABLE: name="test_type_diff2_c3" schema="" table="test_type_diff2_c3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 897 +ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int8 USING int_four::int8 +-- +TABLE: name="test_type_diff2" schema="" table="test_type_diff2" ctx=DDL +STMT: AlterTableStmt +== 898 +-- whole-row references are disallowed +ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int4 USING (pg_column_size(test_type_diff2)) +-- +TABLE: name="test_type_diff2" schema="" table="test_type_diff2" ctx=DDL +STMT: AlterTableStmt +== 899 +-- check for rollback of ANALYZE corrupting table property flags (bug #11638) +CREATE TABLE check_fk_presence_1 (id int PRIMARY KEY, t text) +-- +TABLE: name="check_fk_presence_1" schema="" table="check_fk_presence_1" ctx=DDL +STMT: CreateStmt +== 900 +CREATE TABLE check_fk_presence_2 (id int REFERENCES check_fk_presence_1, t text) +-- +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: CreateStmt +== 901 +BEGIN +-- +STMT: TransactionStmt +== 902 +ALTER TABLE check_fk_presence_2 DROP CONSTRAINT check_fk_presence_2_id_fkey +-- +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: AlterTableStmt +== 903 +ANALYZE check_fk_presence_2 +-- +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: VacuumStmt +== 904 +ROLLBACK +-- +STMT: TransactionStmt +== 905 +DROP TABLE check_fk_presence_1, check_fk_presence_2 +-- +TABLE: name="check_fk_presence_1" schema="" table="check_fk_presence_1" ctx=DDL +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: DropStmt +== 906 +-- check column addition within a view (bug #14876) +create table at_base_table(id int, stuff text) +-- +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=DDL +STMT: CreateStmt +== 907 +insert into at_base_table values (23, 'skidoo') +-- +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 908 +create view at_view_1 as select * from at_base_table bt +-- +TABLE: name="at_view_1" schema="" table="at_view_1" ctx=DDL +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=Select +ALIAS: "bt"="at_base_table" +STMT: ViewStmt +STMT: SelectStmt +== 909 +create view at_view_2 as select *, to_json(v1) as j from at_view_1 v1 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=DDL +TABLE: name="at_view_1" schema="" table="at_view_1" ctx=Select +ALIAS: "v1"="at_view_1" +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 910 +explain (verbose, costs off) select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 911 +select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: SelectStmt +== 912 +create or replace view at_view_1 as select *, 2+2 as more from at_base_table bt +-- +TABLE: name="at_view_1" schema="" table="at_view_1" ctx=DDL +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=Select +ALIAS: "bt"="at_base_table" +STMT: ViewStmt +STMT: SelectStmt +== 913 +explain (verbose, costs off) select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 914 +select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: SelectStmt +== 915 +drop view at_view_2 +-- +STMT: DropStmt +== 916 +drop view at_view_1 +-- +STMT: DropStmt +== 917 +drop table at_base_table +-- +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=DDL +STMT: DropStmt +== 918 +-- related case (bug #17811) +begin +-- +STMT: TransactionStmt +== 919 +create temp table t1 as select * from int8_tbl +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 920 +create temp view v1 as select 1::int8 as q1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 921 +create temp view v2 as select * from v1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 922 +create or replace temp view v1 with (security_barrier = true) + as select * from t1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 923 +create temp table log (q1 int8, q2 int8) +-- +TABLE: name="log" schema="" table="log" ctx=DDL +STMT: CreateStmt +== 924 +create rule v1_upd_rule as on update to v1 + do also insert into log values (new.*) +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: RuleStmt +== 925 +update v2 set q1 = q1 + 1 where q1 = 123 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +== 926 +select * from t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 927 +select * from log +-- +TABLE: name="log" schema="" table="log" ctx=Select +STMT: SelectStmt +== 928 +rollback +-- +STMT: TransactionStmt +== 929 +-- check adding a column not itself requiring a rewrite, together with +-- a column requiring a default (bug #16038) + +-- ensure that rewrites aren't silently optimized away, removing the +-- value of the test +CREATE FUNCTION check_ddl_rewrite(p_tablename regclass, p_ddl text) +RETURNS boolean +LANGUAGE plpgsql AS $$ +DECLARE + v_relfilenode oid; +BEGIN + v_relfilenode := relfilenode FROM pg_class WHERE oid = p_tablename; + + EXECUTE p_ddl; + + RETURN v_relfilenode <> (SELECT relfilenode FROM pg_class WHERE oid = p_tablename); +END; +$$ +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 930 +CREATE TABLE rewrite_test(col text) +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DDL +STMT: CreateStmt +== 931 +INSERT INTO rewrite_test VALUES ('something') +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 932 +INSERT INTO rewrite_test VALUES (NULL) +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 933 +-- empty[12] don't need rewrite, but notempty[12]_rewrite will force one +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN empty1 text, + ADD COLUMN notempty1_rewrite serial; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 934 +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN notempty2_rewrite serial, + ADD COLUMN empty2 text; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 935 +-- also check that fast defaults cause no problem, first without rewrite +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN empty3 text, + ADD COLUMN notempty3_norewrite int default 42; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 936 +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN notempty4_norewrite int default 42, + ADD COLUMN empty4 text; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 937 +-- then with rewrite +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN empty5 text, + ADD COLUMN notempty5_norewrite int default 42, + ADD COLUMN notempty5_rewrite serial; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 938 +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN notempty6_rewrite serial, + ADD COLUMN empty6 text, + ADD COLUMN notempty6_norewrite int default 42; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 939 +-- cleanup +DROP FUNCTION check_ddl_rewrite(regclass, text) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=DDL +STMT: DropStmt +== 940 +DROP TABLE rewrite_test +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DDL +STMT: DropStmt +== 941 +|-- +-- lock levels +|-- +drop type lockmodes +-- +STMT: DropStmt +== 942 +create type lockmodes as enum ( + 'SIReadLock' +,'AccessShareLock' +,'RowShareLock' +,'RowExclusiveLock' +,'ShareUpdateExclusiveLock' +,'ShareLock' +,'ShareRowExclusiveLock' +,'ExclusiveLock' +,'AccessExclusiveLock' +) +-- +STMT: CreateEnumStmt +== 943 +drop view my_locks +-- +STMT: DropStmt +== 944 +create or replace view my_locks as +select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode +from pg_locks l join pg_class c on l.relation = c.oid +where virtualtransaction = ( + select virtualtransaction + from pg_locks + where transactionid = pg_current_xact_id()::xid) +and locktype = 'relation' +and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog') +and c.relname != 'my_locks' +group by c.relname +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="" column="virtualtransaction" +FILTER: schema="" table="" column="transactionid" +FILTER: schema="" table="" column="nspname" +STMT: ViewStmt +STMT: SelectStmt +== 945 +create table alterlock (f1 int primary key, f2 text) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: CreateStmt +== 946 +insert into alterlock values (1, 'foo') +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 947 +create table alterlock2 (f3 int primary key, f1 int) +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: CreateStmt +== 948 +insert into alterlock2 values (1, 1) +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 949 +begin +-- +STMT: TransactionStmt +== 950 +alter table alterlock alter column f2 set statistics 150 +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 951 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 952 +rollback +-- +STMT: TransactionStmt +== 953 +begin +-- +STMT: TransactionStmt +== 954 +alter table alterlock cluster on alterlock_pkey +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 955 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 956 +commit +-- +STMT: TransactionStmt +== 957 +begin +-- +STMT: TransactionStmt +== 958 +alter table alterlock set without cluster +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 959 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 960 +commit +-- +STMT: TransactionStmt +== 961 +begin +-- +STMT: TransactionStmt +== 962 +alter table alterlock set (fillfactor = 100) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 963 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 964 +commit +-- +STMT: TransactionStmt +== 965 +begin +-- +STMT: TransactionStmt +== 966 +alter table alterlock reset (fillfactor) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 967 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 968 +commit +-- +STMT: TransactionStmt +== 969 +begin +-- +STMT: TransactionStmt +== 970 +alter table alterlock set (toast.autovacuum_enabled = off) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 971 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 972 +commit +-- +STMT: TransactionStmt +== 973 +begin +-- +STMT: TransactionStmt +== 974 +alter table alterlock set (autovacuum_enabled = off) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 975 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 976 +commit +-- +STMT: TransactionStmt +== 977 +begin +-- +STMT: TransactionStmt +== 978 +alter table alterlock alter column f2 set (n_distinct = 1) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 979 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 980 +rollback +-- +STMT: TransactionStmt +== 981 +-- test that mixing options with different lock levels works as expected +begin +-- +STMT: TransactionStmt +== 982 +alter table alterlock set (autovacuum_enabled = off, fillfactor = 80) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 983 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 984 +commit +-- +STMT: TransactionStmt +== 985 +begin +-- +STMT: TransactionStmt +== 986 +alter table alterlock alter column f2 set storage extended +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 987 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 988 +rollback +-- +STMT: TransactionStmt +== 989 +begin +-- +STMT: TransactionStmt +== 990 +alter table alterlock alter column f2 set default 'x' +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +== 991 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 992 +rollback +-- +STMT: TransactionStmt +== 993 +begin +-- +STMT: TransactionStmt +== 994 +create trigger ttdummy + before delete or update on alterlock + for each row + execute procedure + ttdummy (1, 1) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: CreateTrigStmt +== 995 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 996 +rollback +-- +STMT: TransactionStmt +== 997 +begin +-- +STMT: TransactionStmt +== 998 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 999 +alter table alterlock2 add foreign key (f1) references alterlock (f1) +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: AlterTableStmt +== 1000 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 1001 +rollback +-- +STMT: TransactionStmt +== 1002 +begin +-- +STMT: TransactionStmt +== 1003 +alter table alterlock2 +add constraint alterlock2nv foreign key (f1) references alterlock (f1) NOT VALID +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: AlterTableStmt +== 1004 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 1005 +commit +-- +STMT: TransactionStmt +== 1006 +begin +-- +STMT: TransactionStmt +== 1007 +alter table alterlock2 validate constraint alterlock2nv +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: AlterTableStmt +== 1008 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 1009 +rollback +-- +STMT: TransactionStmt +== 1010 +create or replace view my_locks as +select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode +from pg_locks l join pg_class c on l.relation = c.oid +where virtualtransaction = ( + select virtualtransaction + from pg_locks + where transactionid = pg_current_xact_id()::xid) +and locktype = 'relation' +and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog') +and c.relname = 'my_locks' +group by c.relname +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="" column="virtualtransaction" +FILTER: schema="" table="" column="transactionid" +FILTER: schema="" table="" column="nspname" +STMT: ViewStmt +STMT: SelectStmt +== 1011 +-- raise exception +alter table my_locks set (autovacuum_enabled = false) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1012 +alter view my_locks set (autovacuum_enabled = false) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1013 +alter table my_locks reset (autovacuum_enabled) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1014 +alter view my_locks reset (autovacuum_enabled) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1015 +begin +-- +STMT: TransactionStmt +== 1016 +alter view my_locks set (security_barrier=off) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1017 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 1018 +alter view my_locks reset (security_barrier) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1019 +rollback +-- +STMT: TransactionStmt +== 1020 +-- this test intentionally applies the ALTER TABLE command against a view, but +-- uses a view option so we expect this to succeed. This form of SQL is +-- accepted for historical reasons, as shown in the docs for ALTER VIEW +begin +-- +STMT: TransactionStmt +== 1021 +alter table my_locks set (security_barrier=off) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1022 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +== 1023 +alter table my_locks reset (security_barrier) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +== 1024 +rollback +-- +STMT: TransactionStmt +== 1025 +-- cleanup +drop table alterlock2 +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: DropStmt +== 1026 +drop table alterlock +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: DropStmt +== 1027 +drop view my_locks +-- +STMT: DropStmt +== 1028 +drop type lockmodes +-- +STMT: DropStmt +== 1029 +|-- +-- alter function +|-- +create function test_strict(text) returns text as + 'select coalesce($1, ''got passed a null'');' + language sql returns null on null input +-- +FUNCTION: name="test_strict" function="test_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1030 +select test_strict(NULL) +-- +FUNCTION: name="test_strict" function="test_strict" schema="" ctx=Call +STMT: SelectStmt +== 1031 +alter function test_strict(text) called on null input +-- +STMT: AlterFunctionStmt +== 1032 +select test_strict(NULL) +-- +FUNCTION: name="test_strict" function="test_strict" schema="" ctx=Call +STMT: SelectStmt +== 1033 +create function non_strict(text) returns text as + 'select coalesce($1, ''got passed a null'');' + language sql called on null input +-- +FUNCTION: name="non_strict" function="non_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1034 +select non_strict(NULL) +-- +FUNCTION: name="non_strict" function="non_strict" schema="" ctx=Call +STMT: SelectStmt +== 1035 +alter function non_strict(text) returns null on null input +-- +STMT: AlterFunctionStmt +== 1036 +select non_strict(NULL) +-- +FUNCTION: name="non_strict" function="non_strict" schema="" ctx=Call +STMT: SelectStmt +== 1037 +|-- +-- alter object set schema +|-- + +create schema alter1 +-- +STMT: CreateSchemaStmt +== 1038 +create schema alter2 +-- +STMT: CreateSchemaStmt +== 1039 +create table alter1.t1(f1 serial primary key, f2 int check (f2 > 0)) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DDL +STMT: CreateStmt +== 1040 +create view alter1.v1 as select * from alter1.t1 +-- +TABLE: name="alter1.v1" schema="alter1" table="v1" ctx=DDL +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 1041 +create function alter1.plus1(int) returns int as 'select $1+1' language sql +-- +FUNCTION: name="alter1.plus1" function="plus1" schema="alter1" ctx=DDL +STMT: CreateFunctionStmt +== 1042 +create domain alter1.posint integer check (value > 0) +-- +STMT: CreateDomainStmt +== 1043 +create type alter1.ctype as (f1 int, f2 text) +-- +STMT: CompositeTypeStmt +== 1044 +create function alter1.same(alter1.ctype, alter1.ctype) returns boolean language sql +as 'select $1.f1 is not distinct from $2.f1 and $1.f2 is not distinct from $2.f2' +-- +FUNCTION: name="alter1.same" function="same" schema="alter1" ctx=DDL +STMT: CreateFunctionStmt +== 1045 +create operator alter1.=(procedure = alter1.same, leftarg = alter1.ctype, rightarg = alter1.ctype) +-- +STMT: DefineStmt +== 1046 +create operator class alter1.ctype_hash_ops default for type alter1.ctype using hash as + operator 1 alter1.=(alter1.ctype, alter1.ctype) +-- +STMT: CreateOpClassStmt +== 1047 +create conversion alter1.latin1_to_utf8 for 'latin1' to 'utf8' from iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 1048 +create text search parser alter1.prs(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +== 1049 +create text search configuration alter1.cfg(parser = alter1.prs) +-- +STMT: DefineStmt +== 1050 +create text search template alter1.tmpl(init = dsimple_init, lexize = dsimple_lexize) +-- +STMT: DefineStmt +== 1051 +create text search dictionary alter1.dict(template = alter1.tmpl) +-- +STMT: DefineStmt +== 1052 +insert into alter1.t1(f2) values(11) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1053 +insert into alter1.t1(f2) values(12) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1054 +alter table alter1.t1 set schema alter1 +-- +STMT: AlterObjectSchemaStmt +== 1055 +-- no-op, same schema +alter table alter1.t1 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1056 +alter table alter1.v1 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1057 +alter function alter1.plus1(int) set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1058 +alter domain alter1.posint set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1059 +alter operator class alter1.ctype_hash_ops using hash set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1060 +alter operator family alter1.ctype_hash_ops using hash set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1061 +alter operator alter1.=(alter1.ctype, alter1.ctype) set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1062 +alter function alter1.same(alter1.ctype, alter1.ctype) set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1063 +alter type alter1.ctype set schema alter1 +-- +STMT: AlterObjectSchemaStmt +== 1064 +-- no-op, same schema +alter type alter1.ctype set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1065 +alter conversion alter1.latin1_to_utf8 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1066 +alter text search parser alter1.prs set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1067 +alter text search configuration alter1.cfg set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1068 +alter text search template alter1.tmpl set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1069 +alter text search dictionary alter1.dict set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1070 +-- this should succeed because nothing is left in alter1 +drop schema alter1 +-- +STMT: DropStmt +== 1071 +insert into alter2.t1(f2) values(13) +-- +TABLE: name="alter2.t1" schema="alter2" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1072 +insert into alter2.t1(f2) values(14) +-- +TABLE: name="alter2.t1" schema="alter2" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1073 +select * from alter2.t1 +-- +TABLE: name="alter2.t1" schema="alter2" table="t1" ctx=Select +STMT: SelectStmt +== 1074 +select * from alter2.v1 +-- +TABLE: name="alter2.v1" schema="alter2" table="v1" ctx=Select +STMT: SelectStmt +== 1075 +select alter2.plus1(41) +-- +FUNCTION: name="alter2.plus1" function="plus1" schema="alter2" ctx=Call +STMT: SelectStmt +== 1076 +-- clean up +drop schema alter2 cascade +-- +STMT: DropStmt +== 1077 +|-- +-- composite types +|-- + +CREATE TYPE test_type AS (a int) +-- +STMT: CompositeTypeStmt +== 1078 +ALTER TYPE nosuchtype ADD ATTRIBUTE b text +-- +TABLE: name="nosuchtype" schema="" table="nosuchtype" ctx=DDL +STMT: AlterTableStmt +== 1079 +-- fails + +ALTER TYPE test_type ADD ATTRIBUTE b text +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1080 +ALTER TYPE test_type ADD ATTRIBUTE b text +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1081 +-- fails + +ALTER TYPE test_type ALTER ATTRIBUTE b SET DATA TYPE varchar +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1082 +ALTER TYPE test_type ALTER ATTRIBUTE b SET DATA TYPE integer +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1083 +ALTER TYPE test_type DROP ATTRIBUTE b +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1084 +ALTER TYPE test_type DROP ATTRIBUTE c +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1085 +-- fails + +ALTER TYPE test_type DROP ATTRIBUTE IF EXISTS c +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1086 +ALTER TYPE test_type DROP ATTRIBUTE a, ADD ATTRIBUTE d boolean +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +== 1087 +ALTER TYPE test_type RENAME ATTRIBUTE a TO aa +-- +STMT: RenameStmt +== 1088 +ALTER TYPE test_type RENAME ATTRIBUTE d TO dd +-- +STMT: RenameStmt +== 1089 +DROP TYPE test_type +-- +STMT: DropStmt +== 1090 +CREATE TYPE test_type1 AS (a int, b text) +-- +STMT: CompositeTypeStmt +== 1091 +CREATE TABLE test_tbl1 (x int, y test_type1) +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: CreateStmt +== 1092 +ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar +-- +TABLE: name="test_type1" schema="" table="test_type1" ctx=DDL +STMT: AlterTableStmt +== 1093 +-- fails + +DROP TABLE test_tbl1 +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: DropStmt +== 1094 +CREATE TABLE test_tbl1 (x int, y text) +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: CreateStmt +== 1095 +CREATE INDEX test_tbl1_idx ON test_tbl1((row(x,y)::test_type1)) +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: IndexStmt +== 1096 +ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar +-- +TABLE: name="test_type1" schema="" table="test_type1" ctx=DDL +STMT: AlterTableStmt +== 1097 +-- fails + +DROP TABLE test_tbl1 +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: DropStmt +== 1098 +DROP TYPE test_type1 +-- +STMT: DropStmt +== 1099 +CREATE TYPE test_type2 AS (a int, b text) +-- +STMT: CompositeTypeStmt +== 1100 +CREATE TABLE test_tbl2 OF test_type2 +-- +TABLE: name="test_tbl2" schema="" table="test_tbl2" ctx=DDL +STMT: CreateStmt +== 1101 +CREATE TABLE test_tbl2_subclass () INHERITS (test_tbl2) +-- +TABLE: name="test_tbl2_subclass" schema="" table="test_tbl2_subclass" ctx=DDL +STMT: CreateStmt +== 1102 +ALTER TYPE test_type2 ADD ATTRIBUTE c text +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +== 1103 +-- fails +ALTER TYPE test_type2 ADD ATTRIBUTE c text CASCADE +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +== 1104 +ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +== 1105 +-- fails +ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar CASCADE +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +== 1106 +ALTER TYPE test_type2 DROP ATTRIBUTE b +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +== 1107 +-- fails +ALTER TYPE test_type2 DROP ATTRIBUTE b CASCADE +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +== 1108 +ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa +-- +STMT: RenameStmt +== 1109 +-- fails +ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa CASCADE +-- +STMT: RenameStmt +== 1110 +DROP TABLE test_tbl2_subclass, test_tbl2 +-- +TABLE: name="test_tbl2_subclass" schema="" table="test_tbl2_subclass" ctx=DDL +TABLE: name="test_tbl2" schema="" table="test_tbl2" ctx=DDL +STMT: DropStmt +== 1111 +DROP TYPE test_type2 +-- +STMT: DropStmt +== 1112 +CREATE TYPE test_typex AS (a int, b text) +-- +STMT: CompositeTypeStmt +== 1113 +CREATE TABLE test_tblx (x int, y test_typex check ((y).a > 0)) +-- +TABLE: name="test_tblx" schema="" table="test_tblx" ctx=DDL +STMT: CreateStmt +== 1114 +ALTER TYPE test_typex DROP ATTRIBUTE a +-- +TABLE: name="test_typex" schema="" table="test_typex" ctx=DDL +STMT: AlterTableStmt +== 1115 +-- fails +ALTER TYPE test_typex DROP ATTRIBUTE a CASCADE +-- +TABLE: name="test_typex" schema="" table="test_typex" ctx=DDL +STMT: AlterTableStmt +== 1116 +DROP TABLE test_tblx +-- +TABLE: name="test_tblx" schema="" table="test_tblx" ctx=DDL +STMT: DropStmt +== 1117 +DROP TYPE test_typex +-- +STMT: DropStmt +== 1118 +-- This test isn't that interesting on its own, but the purpose is to leave +-- behind a table to test pg_upgrade with. The table has a composite type +-- column in it, and the composite type has a dropped attribute. +CREATE TYPE test_type3 AS (a int) +-- +STMT: CompositeTypeStmt +== 1119 +CREATE TABLE test_tbl3 (c) AS SELECT '(1)'::test_type3 +-- +TABLE: name="test_tbl3" schema="" table="test_tbl3" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 1120 +ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int +-- +TABLE: name="test_type3" schema="" table="test_type3" ctx=DDL +STMT: AlterTableStmt +== 1121 +CREATE TYPE test_type_empty AS () +-- +STMT: CompositeTypeStmt +== 1122 +DROP TYPE test_type_empty +-- +STMT: DropStmt +== 1123 +|-- +-- typed tables: OF / NOT OF +|-- + +CREATE TYPE tt_t0 AS (z inet, x int, y numeric(8,2)) +-- +STMT: CompositeTypeStmt +== 1124 +ALTER TYPE tt_t0 DROP ATTRIBUTE z +-- +TABLE: name="tt_t0" schema="" table="tt_t0" ctx=DDL +STMT: AlterTableStmt +== 1125 +CREATE TABLE tt0 (x int NOT NULL, y numeric(8,2)) +-- +TABLE: name="tt0" schema="" table="tt0" ctx=DDL +STMT: CreateStmt +== 1126 +-- OK +CREATE TABLE tt1 (x int, y bigint) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +== 1127 +-- wrong base type +CREATE TABLE tt2 (x int, y numeric(9,2)) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +== 1128 +-- wrong typmod +CREATE TABLE tt3 (y numeric(8,2), x int) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +== 1129 +-- wrong column order +CREATE TABLE tt4 (x int) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: CreateStmt +== 1130 +-- too few columns +CREATE TABLE tt5 (x int, y numeric(8,2), z int) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: CreateStmt +== 1131 +-- too few columns +CREATE TABLE tt6 () INHERITS (tt0) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: CreateStmt +== 1132 +-- can't have a parent +CREATE TABLE tt7 (x int, q text, y numeric(8,2)) +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: CreateStmt +== 1133 +ALTER TABLE tt7 DROP q +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 1134 +-- OK + +ALTER TABLE tt0 OF tt_t0 +-- +TABLE: name="tt0" schema="" table="tt0" ctx=DDL +STMT: AlterTableStmt +== 1135 +ALTER TABLE tt1 OF tt_t0 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: AlterTableStmt +== 1136 +ALTER TABLE tt2 OF tt_t0 +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +== 1137 +ALTER TABLE tt3 OF tt_t0 +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: AlterTableStmt +== 1138 +ALTER TABLE tt4 OF tt_t0 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: AlterTableStmt +== 1139 +ALTER TABLE tt5 OF tt_t0 +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +== 1140 +ALTER TABLE tt6 OF tt_t0 +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: AlterTableStmt +== 1141 +ALTER TABLE tt7 OF tt_t0 +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 1142 +CREATE TYPE tt_t1 AS (x int, y numeric(8,2)) +-- +STMT: CompositeTypeStmt +== 1143 +ALTER TABLE tt7 OF tt_t1 +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 1144 +-- reassign an already-typed table +ALTER TABLE tt7 NOT OF +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 1145 +-- make sure we can drop a constraint on the parent but it remains on the child +CREATE TABLE test_drop_constr_parent (c text CHECK (c IS NOT NULL)) +-- +TABLE: name="test_drop_constr_parent" schema="" table="test_drop_constr_parent" ctx=DDL +STMT: CreateStmt +== 1146 +CREATE TABLE test_drop_constr_child () INHERITS (test_drop_constr_parent) +-- +TABLE: name="test_drop_constr_child" schema="" table="test_drop_constr_child" ctx=DDL +STMT: CreateStmt +== 1147 +ALTER TABLE ONLY test_drop_constr_parent DROP CONSTRAINT "test_drop_constr_parent_c_check" +-- +TABLE: name="test_drop_constr_parent" schema="" table="test_drop_constr_parent" ctx=DDL +STMT: AlterTableStmt +== 1148 +-- should fail +INSERT INTO test_drop_constr_child (c) VALUES (NULL) +-- +TABLE: name="test_drop_constr_child" schema="" table="test_drop_constr_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1149 +DROP TABLE test_drop_constr_parent CASCADE +-- +TABLE: name="test_drop_constr_parent" schema="" table="test_drop_constr_parent" ctx=DDL +STMT: DropStmt +== 1150 +|-- +-- IF EXISTS test +|-- +ALTER TABLE IF EXISTS tt8 ADD COLUMN f int +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1151 +ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY(f) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1152 +ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1153 +ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0 +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1154 +ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1 +-- +STMT: RenameStmt +== 1155 +ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2 +-- +STMT: AlterObjectSchemaStmt +== 1156 +CREATE TABLE tt8(a int) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: CreateStmt +== 1157 +CREATE SCHEMA alter2 +-- +STMT: CreateSchemaStmt +== 1158 +ALTER TABLE IF EXISTS tt8 ADD COLUMN f int +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1159 +ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY(f) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1160 +ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1161 +ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0 +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 1162 +ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1 +-- +STMT: RenameStmt +== 1163 +ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2 +-- +STMT: AlterObjectSchemaStmt +== 1164 +DROP TABLE alter2.tt8 +-- +TABLE: name="alter2.tt8" schema="alter2" table="tt8" ctx=DDL +STMT: DropStmt +== 1165 +DROP SCHEMA alter2 +-- +STMT: DropStmt +== 1166 +|-- +-- Check conflicts between index and CHECK constraint names +|-- +CREATE TABLE tt9(c integer) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: CreateStmt +== 1167 +ALTER TABLE tt9 ADD CHECK(c > 1) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1168 +ALTER TABLE tt9 ADD CHECK(c > 2) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1169 +-- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 3) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1170 +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 4) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1171 +-- fail, dup name +ALTER TABLE tt9 ADD UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1172 +ALTER TABLE tt9 ADD UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1173 +-- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1174 +-- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT foo UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1175 +-- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key CHECK(c > 5) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1176 +-- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key2 CHECK(c > 6) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1177 +ALTER TABLE tt9 ADD UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 1178 +-- picks nonconflicting name +DROP TABLE tt9 +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: DropStmt +== 1179 +-- Check that comments on constraints and indexes are not lost at ALTER TABLE. +CREATE TABLE comment_test ( + id int, + positive_col int CHECK (positive_col > 0), + indexed_col int, + CONSTRAINT comment_test_pk PRIMARY KEY (id)) +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: CreateStmt +== 1180 +CREATE INDEX comment_test_index ON comment_test(indexed_col) +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: IndexStmt +== 1181 +COMMENT ON COLUMN comment_test.id IS 'Column ''id'' on comment_test' +-- +STMT: CommentStmt +== 1182 +COMMENT ON INDEX comment_test_index IS 'Simple index on comment_test' +-- +STMT: CommentStmt +== 1183 +COMMENT ON CONSTRAINT comment_test_positive_col_check ON comment_test IS 'CHECK constraint on comment_test.positive_col' +-- +STMT: CommentStmt +== 1184 +COMMENT ON CONSTRAINT comment_test_pk ON comment_test IS 'PRIMARY KEY constraint of comment_test' +-- +STMT: CommentStmt +== 1185 +COMMENT ON INDEX comment_test_pk IS 'Index backing the PRIMARY KEY of comment_test' +-- +STMT: CommentStmt +== 1186 +SELECT col_description('comment_test'::regclass, 1) as comment +-- +FUNCTION: name="col_description" function="col_description" schema="" ctx=Call +STMT: SelectStmt +== 1187 +SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 1188 +SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 1189 +-- Change the datatype of all the columns. ALTER TABLE is optimized to not +-- rebuild an index if the new data type is binary compatible with the old +-- one. Check do a dummy ALTER TABLE that doesn't change the datatype +-- first, to test that no-op codepath, and another one that does. +ALTER TABLE comment_test ALTER COLUMN indexed_col SET DATA TYPE int +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1190 +ALTER TABLE comment_test ALTER COLUMN indexed_col SET DATA TYPE text +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1191 +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1192 +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE text +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1193 +ALTER TABLE comment_test ALTER COLUMN positive_col SET DATA TYPE int +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1194 +ALTER TABLE comment_test ALTER COLUMN positive_col SET DATA TYPE bigint +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1195 +-- Check that the comments are intact. +SELECT col_description('comment_test'::regclass, 1) as comment +-- +FUNCTION: name="col_description" function="col_description" schema="" ctx=Call +STMT: SelectStmt +== 1196 +SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 1197 +SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 1198 +-- Check compatibility for foreign keys and comments. This is done +-- separately as rebuilding the column type of the parent leads +-- to an error and would reduce the test scope. +CREATE TABLE comment_test_child ( + id text CONSTRAINT comment_test_child_fk REFERENCES comment_test) +-- +TABLE: name="comment_test_child" schema="" table="comment_test_child" ctx=DDL +STMT: CreateStmt +== 1199 +CREATE INDEX comment_test_child_fk ON comment_test_child(id) +-- +TABLE: name="comment_test_child" schema="" table="comment_test_child" ctx=DDL +STMT: IndexStmt +== 1200 +COMMENT ON COLUMN comment_test_child.id IS 'Column ''id'' on comment_test_child' +-- +STMT: CommentStmt +== 1201 +COMMENT ON INDEX comment_test_child_fk IS 'Index backing the FOREIGN KEY of comment_test_child' +-- +STMT: CommentStmt +== 1202 +COMMENT ON CONSTRAINT comment_test_child_fk ON comment_test_child IS 'FOREIGN KEY constraint of comment_test_child' +-- +STMT: CommentStmt +== 1203 +-- Change column type of parent +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE text +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1204 +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int USING id::integer +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +== 1205 +-- Comments should be intact +SELECT col_description('comment_test_child'::regclass, 1) as comment +-- +FUNCTION: name="col_description" function="col_description" schema="" ctx=Call +STMT: SelectStmt +== 1206 +SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test_child'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 1207 +SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test_child'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 1208 +-- Check that we map relation oids to filenodes and back correctly. Only +-- display bad mappings so the test output doesn't change all the time. A +-- filenode function call can return NULL for a relation dropped concurrently +-- with the call's surrounding query, so ignore a NULL mapped_oid for +-- relations that no longer exist after all calls finish. +-- Temporary relations are ignored, as not supported by pg_filenode_relation(). +CREATE TEMP TABLE filenode_mapping AS +SELECT + oid, mapped_oid, reltablespace, relfilenode, relname +FROM pg_class, + pg_filenode_relation(reltablespace, pg_relation_filenode(oid)) AS mapped_oid +WHERE relkind IN ('r', 'i', 'S', 't', 'm') + AND relpersistence != 't' + AND mapped_oid IS DISTINCT FROM oid +-- +TABLE: name="filenode_mapping" schema="" table="filenode_mapping" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_filenode_relation" function="pg_filenode_relation" schema="" ctx=Call +FUNCTION: name="pg_relation_filenode" function="pg_relation_filenode" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relpersistence" +FILTER: schema="" table="" column="mapped_oid" +FILTER: schema="" table="" column="oid" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 1209 +SELECT m.* FROM filenode_mapping m LEFT JOIN pg_class c ON c.oid = m.oid +WHERE c.oid IS NOT NULL OR m.mapped_oid IS NOT NULL +-- +TABLE: name="filenode_mapping" schema="" table="filenode_mapping" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "m"="filenode_mapping" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="m" column="mapped_oid" +STMT: SelectStmt +== 1210 +-- Checks on creating and manipulation of user defined relations in +-- pg_catalog. + +SHOW allow_system_table_mods +-- +STMT: VariableShowStmt +== 1211 +-- disallowed because of search_path issues with pg_dump +CREATE TABLE pg_catalog.new_system_table() +-- +TABLE: name="pg_catalog.new_system_table" schema="pg_catalog" table="new_system_table" ctx=DDL +STMT: CreateStmt +== 1212 +-- instead create in public first, move to catalog +CREATE TABLE new_system_table(id serial primary key, othercol text) +-- +TABLE: name="new_system_table" schema="" table="new_system_table" ctx=DDL +STMT: CreateStmt +== 1213 +ALTER TABLE new_system_table SET SCHEMA pg_catalog +-- +STMT: AlterObjectSchemaStmt +== 1214 +ALTER TABLE new_system_table SET SCHEMA public +-- +STMT: AlterObjectSchemaStmt +== 1215 +ALTER TABLE new_system_table SET SCHEMA pg_catalog +-- +STMT: AlterObjectSchemaStmt +== 1216 +-- will be ignored -- already there: +ALTER TABLE new_system_table SET SCHEMA pg_catalog +-- +STMT: AlterObjectSchemaStmt +== 1217 +ALTER TABLE new_system_table RENAME TO old_system_table +-- +TABLE: name="new_system_table" schema="" table="new_system_table" ctx=DDL +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: RenameStmt +== 1218 +CREATE INDEX old_system_table__othercol ON old_system_table (othercol) +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: IndexStmt +== 1219 +INSERT INTO old_system_table(othercol) VALUES ('somedata'), ('otherdata') +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1220 +UPDATE old_system_table SET id = -id +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DML +STMT: UpdateStmt +== 1221 +DELETE FROM old_system_table WHERE othercol = 'somedata' +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DML +STMT: DeleteStmt +== 1222 +TRUNCATE old_system_table +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: TruncateStmt +== 1223 +ALTER TABLE old_system_table DROP CONSTRAINT new_system_table_pkey +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: AlterTableStmt +== 1224 +ALTER TABLE old_system_table DROP COLUMN othercol +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: AlterTableStmt +== 1225 +DROP TABLE old_system_table +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: DropStmt +== 1226 +-- set logged +CREATE UNLOGGED TABLE unlogged1(f1 SERIAL PRIMARY KEY, f2 TEXT) +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: CreateStmt +== 1227 +-- has sequence, toast +-- check relpersistence of an unlogged table +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^unlogged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +== 1228 +CREATE UNLOGGED TABLE unlogged2(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES unlogged1) +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: CreateStmt +== 1229 +-- foreign key +CREATE UNLOGGED TABLE unlogged3(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES unlogged3) +-- +TABLE: name="unlogged3" schema="" table="unlogged3" ctx=DDL +STMT: CreateStmt +== 1230 +-- self-referencing foreign key +ALTER TABLE unlogged3 SET LOGGED +-- +TABLE: name="unlogged3" schema="" table="unlogged3" ctx=DDL +STMT: AlterTableStmt +== 1231 +-- skip self-referencing foreign key +ALTER TABLE unlogged2 SET LOGGED +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: AlterTableStmt +== 1232 +-- fails because a foreign key to an unlogged table exists +ALTER TABLE unlogged1 SET LOGGED +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: AlterTableStmt +== 1233 +-- check relpersistence of an unlogged table after changing to permanent +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^unlogged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +== 1234 +ALTER TABLE unlogged1 SET LOGGED +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: AlterTableStmt +== 1235 +-- silently do nothing +DROP TABLE unlogged3 +-- +TABLE: name="unlogged3" schema="" table="unlogged3" ctx=DDL +STMT: DropStmt +== 1236 +DROP TABLE unlogged2 +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: DropStmt +== 1237 +DROP TABLE unlogged1 +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: DropStmt +== 1238 +-- set unlogged +CREATE TABLE logged1(f1 SERIAL PRIMARY KEY, f2 TEXT) +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: CreateStmt +== 1239 +-- has sequence, toast +-- check relpersistence of a permanent table +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^logged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^logged1' +UNION ALL +SELECT r.relname ||' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^logged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +== 1240 +CREATE TABLE logged2(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES logged1) +-- +TABLE: name="logged2" schema="" table="logged2" ctx=DDL +STMT: CreateStmt +== 1241 +-- foreign key +CREATE TABLE logged3(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES logged3) +-- +TABLE: name="logged3" schema="" table="logged3" ctx=DDL +STMT: CreateStmt +== 1242 +-- self-referencing foreign key +ALTER TABLE logged1 SET UNLOGGED +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: AlterTableStmt +== 1243 +-- fails because a foreign key from a permanent table exists +ALTER TABLE logged3 SET UNLOGGED +-- +TABLE: name="logged3" schema="" table="logged3" ctx=DDL +STMT: AlterTableStmt +== 1244 +-- skip self-referencing foreign key +ALTER TABLE logged2 SET UNLOGGED +-- +TABLE: name="logged2" schema="" table="logged2" ctx=DDL +STMT: AlterTableStmt +== 1245 +ALTER TABLE logged1 SET UNLOGGED +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: AlterTableStmt +== 1246 +-- check relpersistence of a permanent table after changing to unlogged +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^logged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^logged1' +UNION ALL +SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^logged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +== 1247 +ALTER TABLE logged1 SET UNLOGGED +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: AlterTableStmt +== 1248 +-- silently do nothing +DROP TABLE logged3 +-- +TABLE: name="logged3" schema="" table="logged3" ctx=DDL +STMT: DropStmt +== 1249 +DROP TABLE logged2 +-- +TABLE: name="logged2" schema="" table="logged2" ctx=DDL +STMT: DropStmt +== 1250 +DROP TABLE logged1 +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: DropStmt +== 1251 +-- test ADD COLUMN IF NOT EXISTS +CREATE TABLE test_add_column(c1 integer) +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: CreateStmt +== 1252 +ALTER TABLE test_add_column + ADD COLUMN c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1253 +ALTER TABLE test_add_column + ADD COLUMN c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1254 +-- fail because c2 already exists +ALTER TABLE ONLY test_add_column + ADD COLUMN c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1255 +-- fail because c2 already exists +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1256 +-- skipping because c2 already exists +ALTER TABLE ONLY test_add_column + ADD COLUMN IF NOT EXISTS c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1257 +-- skipping because c2 already exists +ALTER TABLE test_add_column + ADD COLUMN c2 integer, -- fail because c2 already exists + ADD COLUMN c3 integer primary key +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1258 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists + ADD COLUMN c3 integer primary key +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1259 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists + ADD COLUMN IF NOT EXISTS c3 integer primary key +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1260 +-- skipping because c3 already exists +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists + ADD COLUMN IF NOT EXISTS c3 integer, -- skipping because c3 already exists + ADD COLUMN c4 integer REFERENCES test_add_column +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1261 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c4 integer REFERENCES test_add_column +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1262 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c5 SERIAL CHECK (c5 > 8) +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1263 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c5 SERIAL CHECK (c5 > 10) +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +== 1264 +DROP TABLE test_add_column +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: DropStmt +== 1265 +-- assorted cases with multiple ALTER TABLE steps +CREATE TABLE ataddindex(f1 INT) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +== 1266 +INSERT INTO ataddindex VALUES (42), (43) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1267 +CREATE UNIQUE INDEX ataddindexi0 ON ataddindex(f1) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: IndexStmt +== 1268 +ALTER TABLE ataddindex + ADD PRIMARY KEY USING INDEX ataddindexi0, + ALTER f1 TYPE BIGINT +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +== 1269 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +== 1270 +CREATE TABLE ataddindex(f1 VARCHAR(10)) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +== 1271 +INSERT INTO ataddindex(f1) VALUES ('foo'), ('a') +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1272 +ALTER TABLE ataddindex + ALTER f1 SET DATA TYPE TEXT, + ADD EXCLUDE ((f1 LIKE 'a') WITH =) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +== 1273 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +== 1274 +CREATE TABLE ataddindex(id int, ref_id int) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +== 1275 +ALTER TABLE ataddindex + ADD PRIMARY KEY (id), + ADD FOREIGN KEY (ref_id) REFERENCES ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +== 1276 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +== 1277 +CREATE TABLE ataddindex(id int, ref_id int) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +== 1278 +ALTER TABLE ataddindex + ADD UNIQUE (id), + ADD FOREIGN KEY (ref_id) REFERENCES ataddindex (id) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +== 1279 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +== 1280 +CREATE TABLE atnotnull1 () +-- +TABLE: name="atnotnull1" schema="" table="atnotnull1" ctx=DDL +STMT: CreateStmt +== 1281 +ALTER TABLE atnotnull1 + ADD COLUMN a INT, + ALTER a SET NOT NULL +-- +TABLE: name="atnotnull1" schema="" table="atnotnull1" ctx=DDL +STMT: AlterTableStmt +== 1282 +ALTER TABLE atnotnull1 + ADD COLUMN c INT, + ADD PRIMARY KEY (c) +-- +TABLE: name="atnotnull1" schema="" table="atnotnull1" ctx=DDL +STMT: AlterTableStmt +== 1283 +-- cannot drop column that is part of the partition key +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (a, (a+b+1)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 1284 +ALTER TABLE partitioned DROP COLUMN a +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 1285 +ALTER TABLE partitioned ALTER COLUMN a TYPE char(5) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 1286 +ALTER TABLE partitioned DROP COLUMN b +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 1287 +ALTER TABLE partitioned ALTER COLUMN b TYPE char(5) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 1288 +-- specifying storage parameters for partitioned tables is not supported +ALTER TABLE partitioned SET (fillfactor=100) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 1289 +-- partitioned table cannot participate in regular inheritance +CREATE TABLE nonpartitioned ( + a int, + b int +) +-- +TABLE: name="nonpartitioned" schema="" table="nonpartitioned" ctx=DDL +STMT: CreateStmt +== 1290 +ALTER TABLE partitioned INHERIT nonpartitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 1291 +ALTER TABLE nonpartitioned INHERIT partitioned +-- +TABLE: name="nonpartitioned" schema="" table="nonpartitioned" ctx=DDL +STMT: AlterTableStmt +== 1292 +-- cannot add NO INHERIT constraint to partitioned tables +ALTER TABLE partitioned ADD CONSTRAINT chk_a CHECK (a > 0) NO INHERIT +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 1293 +DROP TABLE partitioned, nonpartitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +TABLE: name="nonpartitioned" schema="" table="nonpartitioned" ctx=DDL +STMT: DropStmt +== 1294 +|-- +-- ATTACH PARTITION +|-- + +-- check that target table is partitioned +CREATE TABLE unparted ( + a int +) +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: CreateStmt +== 1295 +CREATE TABLE fail_part (like unparted) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1296 +ALTER TABLE unparted ATTACH PARTITION fail_part FOR VALUES IN ('a') +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: AlterTableStmt +== 1297 +DROP TABLE unparted, fail_part +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1298 +-- check that partition bound is compatible +CREATE TABLE list_parted ( + a int NOT NULL, + b char(2) COLLATE "C", + CONSTRAINT check_a CHECK (a > 0) +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +== 1299 +CREATE TABLE fail_part (LIKE list_parted) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1300 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES FROM (1) TO (10) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1301 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1302 +-- check that the table being attached exists +ALTER TABLE list_parted ATTACH PARTITION nonexistent FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1303 +-- check ownership of the source table +CREATE ROLE regress_test_me +-- +STMT: CreateRoleStmt +== 1304 +CREATE ROLE regress_test_not_me +-- +STMT: CreateRoleStmt +== 1305 +CREATE TABLE not_owned_by_me (LIKE list_parted) +-- +TABLE: name="not_owned_by_me" schema="" table="not_owned_by_me" ctx=DDL +STMT: CreateStmt +== 1306 +ALTER TABLE not_owned_by_me OWNER TO regress_test_not_me +-- +TABLE: name="not_owned_by_me" schema="" table="not_owned_by_me" ctx=DDL +STMT: AlterTableStmt +== 1307 +SET SESSION AUTHORIZATION regress_test_me +-- +STMT: VariableSetStmt +== 1308 +CREATE TABLE owned_by_me ( + a int +) PARTITION BY LIST (a) +-- +TABLE: name="owned_by_me" schema="" table="owned_by_me" ctx=DDL +STMT: CreateStmt +== 1309 +ALTER TABLE owned_by_me ATTACH PARTITION not_owned_by_me FOR VALUES IN (1) +-- +TABLE: name="owned_by_me" schema="" table="owned_by_me" ctx=DDL +STMT: AlterTableStmt +== 1310 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 1311 +DROP TABLE owned_by_me, not_owned_by_me +-- +TABLE: name="owned_by_me" schema="" table="owned_by_me" ctx=DDL +TABLE: name="not_owned_by_me" schema="" table="not_owned_by_me" ctx=DDL +STMT: DropStmt +== 1312 +DROP ROLE regress_test_not_me +-- +STMT: DropRoleStmt +== 1313 +DROP ROLE regress_test_me +-- +STMT: DropRoleStmt +== 1314 +-- check that the table being attached is not part of regular inheritance +CREATE TABLE parent (LIKE list_parted) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 1315 +CREATE TABLE child () INHERITS (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 1316 +ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1317 +ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1318 +DROP TABLE child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 1319 +-- now it should work, with a little tweak +ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 1320 +ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1321 +-- test insert/update, per bug #18550 +INSERT INTO parent VALUES (1) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1322 +UPDATE parent SET a = 2 WHERE a = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +== 1323 +DROP TABLE parent CASCADE +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 1324 +-- check any TEMP-ness +CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +== 1325 +CREATE TABLE perm_part (a int) +-- +TABLE: name="perm_part" schema="" table="perm_part" ctx=DDL +STMT: CreateStmt +== 1326 +ALTER TABLE temp_parted ATTACH PARTITION perm_part FOR VALUES IN (1) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: AlterTableStmt +== 1327 +DROP TABLE temp_parted, perm_part +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +TABLE: name="perm_part" schema="" table="perm_part" ctx=DDL +STMT: DropStmt +== 1328 +-- check that the table being attached is not a typed table +CREATE TYPE mytype AS (a int) +-- +STMT: CompositeTypeStmt +== 1329 +CREATE TABLE fail_part OF mytype +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1330 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1331 +DROP TYPE mytype CASCADE +-- +STMT: DropStmt +== 1332 +-- check that the table being attached has only columns present in the parent +CREATE TABLE fail_part (like list_parted, c int) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1333 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1334 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1335 +-- check that the table being attached has every column of the parent +CREATE TABLE fail_part (a int NOT NULL) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1336 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1337 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1338 +-- check that columns match in type, collation and NOT NULL status +CREATE TABLE fail_part ( + b char(3), + a int NOT NULL +) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1339 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1340 +ALTER TABLE fail_part ALTER b TYPE char (2) COLLATE "POSIX" +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: AlterTableStmt +== 1341 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1342 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1343 +-- check that the table being attached has all constraints of the parent +CREATE TABLE fail_part ( + b char(2) COLLATE "C", + a int NOT NULL +) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1344 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1345 +-- check that the constraint matches in definition with parent's constraint +ALTER TABLE fail_part ADD CONSTRAINT check_a CHECK (a >= 0) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: AlterTableStmt +== 1346 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1347 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1348 +-- check the attributes and constraints after partition is attached +CREATE TABLE part_1 ( + a int NOT NULL, + b char(2) COLLATE "C", + CONSTRAINT check_a CHECK (a > 0) +) +-- +TABLE: name="part_1" schema="" table="part_1" ctx=DDL +STMT: CreateStmt +== 1349 +ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1350 +-- attislocal and conislocal are always false for merged attributes and constraints respectively. +SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attnum > 0 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 1351 +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_1'::regclass AND conname = 'check_a' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 1352 +-- check that the new partition won't overlap with an existing partition +CREATE TABLE fail_part (LIKE part_1 INCLUDING CONSTRAINTS) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1353 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1354 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1355 +-- check that an existing table can be attached as a default partition +CREATE TABLE def_part (LIKE list_parted INCLUDING CONSTRAINTS) +-- +TABLE: name="def_part" schema="" table="def_part" ctx=DDL +STMT: CreateStmt +== 1356 +ALTER TABLE list_parted ATTACH PARTITION def_part DEFAULT +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1357 +-- check attaching default partition fails if a default partition already +-- exists +CREATE TABLE fail_def_part (LIKE part_1 INCLUDING CONSTRAINTS) +-- +TABLE: name="fail_def_part" schema="" table="fail_def_part" ctx=DDL +STMT: CreateStmt +== 1358 +ALTER TABLE list_parted ATTACH PARTITION fail_def_part DEFAULT +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1359 +-- check validation when attaching list partitions +CREATE TABLE list_parted2 ( + a int, + b char +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: CreateStmt +== 1360 +-- check that violating rows are correctly reported +CREATE TABLE part_2 (LIKE list_parted2) +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: CreateStmt +== 1361 +INSERT INTO part_2 VALUES (3, 'a') +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1362 +ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1363 +-- should be ok after deleting the bad row +DELETE FROM part_2 +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DML +STMT: DeleteStmt +== 1364 +ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1365 +-- check partition cannot be attached if default has some row for its values +CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DDL +STMT: CreateStmt +== 1366 +INSERT INTO list_parted2_def VALUES (11, 'z') +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1367 +CREATE TABLE part_3 (LIKE list_parted2) +-- +TABLE: name="part_3" schema="" table="part_3" ctx=DDL +STMT: CreateStmt +== 1368 +ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1369 +-- should be ok after deleting the bad row +DELETE FROM list_parted2_def WHERE a = 11 +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DML +STMT: DeleteStmt +== 1370 +ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1371 +-- adding constraints that describe the desired partition constraint +-- (or more restrictive) will help skip the validation scan +CREATE TABLE part_3_4 ( + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IN (3)) +) +-- +TABLE: name="part_3_4" schema="" table="part_3_4" ctx=DDL +STMT: CreateStmt +== 1372 +-- however, if a list partition does not accept nulls, there should be +-- an explicit NOT NULL constraint on the partition key column for the +-- validation scan to be skipped; +ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1373 +-- adding a NOT NULL constraint will cause the scan to be skipped +ALTER TABLE list_parted2 DETACH PARTITION part_3_4 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1374 +ALTER TABLE part_3_4 ALTER a SET NOT NULL +-- +TABLE: name="part_3_4" schema="" table="part_3_4" ctx=DDL +STMT: AlterTableStmt +== 1375 +ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1376 +-- check if default partition scan skipped +ALTER TABLE list_parted2_def ADD CONSTRAINT check_a CHECK (a IN (5, 6)) +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DDL +STMT: AlterTableStmt +== 1377 +CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66) +-- +TABLE: name="part_55_66" schema="" table="part_55_66" ctx=DDL +STMT: CreateStmt +== 1378 +-- check validation when attaching range partitions +CREATE TABLE range_parted ( + a int, + b int +) PARTITION BY RANGE (a, b) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +== 1379 +-- check that violating rows are correctly reported +CREATE TABLE part1 ( + a int NOT NULL CHECK (a = 1), + b int NOT NULL CHECK (b >= 1 AND b <= 10) +) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +== 1380 +INSERT INTO part1 VALUES (1, 10) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1381 +-- Remember the TO bound is exclusive +ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 1382 +-- should be ok after deleting the bad row +DELETE FROM part1 +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: DeleteStmt +== 1383 +ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 1384 +-- adding constraints that describe the desired partition constraint +-- (or more restrictive) will help skip the validation scan +CREATE TABLE part2 ( + a int NOT NULL CHECK (a = 1), + b int NOT NULL CHECK (b >= 10 AND b < 18) +) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +== 1385 +ALTER TABLE range_parted ATTACH PARTITION part2 FOR VALUES FROM (1, 10) TO (1, 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 1386 +-- Create default partition +CREATE TABLE partr_def1 PARTITION OF range_parted DEFAULT +-- +TABLE: name="partr_def1" schema="" table="partr_def1" ctx=DDL +STMT: CreateStmt +== 1387 +-- Only one default partition is allowed, hence, following should give error +CREATE TABLE partr_def2 (LIKE part1 INCLUDING CONSTRAINTS) +-- +TABLE: name="partr_def2" schema="" table="partr_def2" ctx=DDL +STMT: CreateStmt +== 1388 +ALTER TABLE range_parted ATTACH PARTITION partr_def2 DEFAULT +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 1389 +-- Overlapping partitions cannot be attached, hence, following should give error +INSERT INTO partr_def1 VALUES (2, 10) +-- +TABLE: name="partr_def1" schema="" table="partr_def1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1390 +CREATE TABLE part3 (LIKE range_parted) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +== 1391 +ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (2, 10) TO (2, 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 1392 +-- Attaching partitions should be successful when there are no overlapping rows +ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (3, 10) TO (3, 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 1393 +-- check that leaf partitions are scanned when attaching a partitioned +-- table +CREATE TABLE part_5 ( + LIKE list_parted2 +) PARTITION BY LIST (b) +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: CreateStmt +== 1394 +-- check that violating rows are correctly reported +CREATE TABLE part_5_a PARTITION OF part_5 FOR VALUES IN ('a') +-- +TABLE: name="part_5_a" schema="" table="part_5_a" ctx=DDL +STMT: CreateStmt +== 1395 +INSERT INTO part_5_a (a, b) VALUES (6, 'a') +-- +TABLE: name="part_5_a" schema="" table="part_5_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1396 +ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1397 +-- delete the faulting row and also add a constraint to skip the scan +DELETE FROM part_5_a WHERE a NOT IN (3) +-- +TABLE: name="part_5_a" schema="" table="part_5_a" ctx=DML +STMT: DeleteStmt +== 1398 +ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5) +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +== 1399 +ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1400 +ALTER TABLE list_parted2 DETACH PARTITION part_5 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1401 +ALTER TABLE part_5 DROP CONSTRAINT check_a +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +== 1402 +-- scan should again be skipped, even though NOT NULL is now a column property +ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), ALTER a SET NOT NULL +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +== 1403 +ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1404 +-- Check the case where attnos of the partitioning columns in the table being +-- attached differs from the parent. It should not affect the constraint- +-- checking logic that allows to skip the scan. +CREATE TABLE part_6 ( + c int, + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 6) +) +-- +TABLE: name="part_6" schema="" table="part_6" ctx=DDL +STMT: CreateStmt +== 1405 +ALTER TABLE part_6 DROP c +-- +TABLE: name="part_6" schema="" table="part_6" ctx=DDL +STMT: AlterTableStmt +== 1406 +ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1407 +-- Similar to above, but the table being attached is a partitioned table +-- whose partition has still different attnos for the root partitioning +-- columns. +CREATE TABLE part_7 ( + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7) +) PARTITION BY LIST (b) +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DDL +STMT: CreateStmt +== 1408 +CREATE TABLE part_7_a_null ( + c int, + d int, + e int, + LIKE list_parted2, -- 'a' will have attnum = 4 + CONSTRAINT check_b CHECK (b IS NULL OR b = 'a'), + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7) +) +-- +TABLE: name="part_7_a_null" schema="" table="part_7_a_null" ctx=DDL +STMT: CreateStmt +== 1409 +ALTER TABLE part_7_a_null DROP c, DROP d, DROP e +-- +TABLE: name="part_7_a_null" schema="" table="part_7_a_null" ctx=DDL +STMT: AlterTableStmt +== 1410 +ALTER TABLE part_7 ATTACH PARTITION part_7_a_null FOR VALUES IN ('a', null) +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DDL +STMT: AlterTableStmt +== 1411 +ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1412 +-- Same example, but check this time that the constraint correctly detects +-- violating rows +ALTER TABLE list_parted2 DETACH PARTITION part_7 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1413 +ALTER TABLE part_7 DROP CONSTRAINT check_a +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DDL +STMT: AlterTableStmt +== 1414 +-- thusly, scan won't be skipped +INSERT INTO part_7 (a, b) VALUES (8, null), (9, 'a') +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1415 +SELECT tableoid::regclass, a, b FROM part_7 order by a +-- +TABLE: name="part_7" schema="" table="part_7" ctx=Select +STMT: SelectStmt +== 1416 +ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1417 +-- check that leaf partitions of default partition are scanned when +-- attaching a partitioned table. +ALTER TABLE part_5 DROP CONSTRAINT check_a +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +== 1418 +CREATE TABLE part5_def PARTITION OF part_5 DEFAULT PARTITION BY LIST(a) +-- +TABLE: name="part5_def" schema="" table="part5_def" ctx=DDL +STMT: CreateStmt +== 1419 +CREATE TABLE part5_def_p1 PARTITION OF part5_def FOR VALUES IN (5) +-- +TABLE: name="part5_def_p1" schema="" table="part5_def_p1" ctx=DDL +STMT: CreateStmt +== 1420 +INSERT INTO part5_def_p1 VALUES (5, 'y') +-- +TABLE: name="part5_def_p1" schema="" table="part5_def_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1421 +CREATE TABLE part5_p1 (LIKE part_5) +-- +TABLE: name="part5_p1" schema="" table="part5_p1" ctx=DDL +STMT: CreateStmt +== 1422 +ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y') +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +== 1423 +-- should be ok after deleting the bad row +DELETE FROM part5_def_p1 WHERE b = 'y' +-- +TABLE: name="part5_def_p1" schema="" table="part5_def_p1" ctx=DML +STMT: DeleteStmt +== 1424 +ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y') +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +== 1425 +-- check that the table being attached is not already a partition +ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1426 +-- check that circular inheritance is not allowed +ALTER TABLE part_5 ATTACH PARTITION list_parted2 FOR VALUES IN ('b') +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +== 1427 +ALTER TABLE list_parted2 ATTACH PARTITION list_parted2 FOR VALUES IN (0) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1428 +-- If a partitioned table being created or an existing table being attached +-- as a partition does not have a constraint that would allow validation scan +-- to be skipped, but an individual partition does, then the partition's +-- validation scan is skipped. +CREATE TABLE quuux (a int, b text) PARTITION BY LIST (a) +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: CreateStmt +== 1429 +CREATE TABLE quuux_default PARTITION OF quuux DEFAULT PARTITION BY LIST (b) +-- +TABLE: name="quuux_default" schema="" table="quuux_default" ctx=DDL +STMT: CreateStmt +== 1430 +CREATE TABLE quuux_default1 PARTITION OF quuux_default ( + CONSTRAINT check_1 CHECK (a IS NOT NULL AND a = 1) +) FOR VALUES IN ('b') +-- +TABLE: name="quuux_default1" schema="" table="quuux_default1" ctx=DDL +STMT: CreateStmt +== 1431 +CREATE TABLE quuux1 (a int, b text) +-- +TABLE: name="quuux1" schema="" table="quuux1" ctx=DDL +STMT: CreateStmt +== 1432 +ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1) +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: AlterTableStmt +== 1433 +-- validate! +CREATE TABLE quuux2 (a int, b text) +-- +TABLE: name="quuux2" schema="" table="quuux2" ctx=DDL +STMT: CreateStmt +== 1434 +ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2) +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: AlterTableStmt +== 1435 +-- skip validation +DROP TABLE quuux1, quuux2 +-- +TABLE: name="quuux1" schema="" table="quuux1" ctx=DDL +TABLE: name="quuux2" schema="" table="quuux2" ctx=DDL +STMT: DropStmt +== 1436 +-- should validate for quuux1, but not for quuux2 +CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1) +-- +TABLE: name="quuux1" schema="" table="quuux1" ctx=DDL +STMT: CreateStmt +== 1437 +CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2) +-- +TABLE: name="quuux2" schema="" table="quuux2" ctx=DDL +STMT: CreateStmt +== 1438 +DROP TABLE quuux +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: DropStmt +== 1439 +-- check validation when attaching hash partitions + +-- Use hand-rolled hash functions and operator class to get predictable result +-- on different machines. part_test_int4_ops is defined in test_setup.sql. + +-- check that the new partition won't overlap with an existing partition +CREATE TABLE hash_parted ( + a int, + b int +) PARTITION BY HASH (a part_test_int4_ops) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +== 1440 +CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 0) +-- +TABLE: name="hpart_1" schema="" table="hpart_1" ctx=DDL +STMT: CreateStmt +== 1441 +CREATE TABLE fail_part (LIKE hpart_1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1442 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 4) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1443 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 0) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1444 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1445 +-- check validation when attaching hash partitions + +-- check that violating rows are correctly reported +CREATE TABLE hpart_2 (LIKE hash_parted) +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DDL +STMT: CreateStmt +== 1446 +INSERT INTO hpart_2 VALUES (3, 0) +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1447 +ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1448 +-- should be ok after deleting the bad row +DELETE FROM hpart_2 +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DML +STMT: DeleteStmt +== 1449 +ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1450 +-- check that leaf partitions are scanned when attaching a partitioned +-- table +CREATE TABLE hpart_5 ( + LIKE hash_parted +) PARTITION BY LIST (b) +-- +TABLE: name="hpart_5" schema="" table="hpart_5" ctx=DDL +STMT: CreateStmt +== 1451 +-- check that violating rows are correctly reported +CREATE TABLE hpart_5_a PARTITION OF hpart_5 FOR VALUES IN ('1', '2', '3') +-- +TABLE: name="hpart_5_a" schema="" table="hpart_5_a" ctx=DDL +STMT: CreateStmt +== 1452 +INSERT INTO hpart_5_a (a, b) VALUES (7, 1) +-- +TABLE: name="hpart_5_a" schema="" table="hpart_5_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1453 +ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1454 +-- should be ok after deleting the bad row +DELETE FROM hpart_5_a +-- +TABLE: name="hpart_5_a" schema="" table="hpart_5_a" ctx=DML +STMT: DeleteStmt +== 1455 +ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1456 +-- check that the table being attach is with valid modulus and remainder value +CREATE TABLE fail_part(LIKE hash_parted) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 1457 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 0, REMAINDER 1) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1458 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 8) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1459 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1460 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +== 1461 +|-- +-- DETACH PARTITION +|-- + +-- check that the table is partitioned at all +CREATE TABLE regular_table (a int) +-- +TABLE: name="regular_table" schema="" table="regular_table" ctx=DDL +STMT: CreateStmt +== 1462 +ALTER TABLE regular_table DETACH PARTITION any_name +-- +TABLE: name="regular_table" schema="" table="regular_table" ctx=DDL +STMT: AlterTableStmt +== 1463 +DROP TABLE regular_table +-- +TABLE: name="regular_table" schema="" table="regular_table" ctx=DDL +STMT: DropStmt +== 1464 +-- check that the partition being detached exists at all +ALTER TABLE list_parted2 DETACH PARTITION part_4 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1465 +ALTER TABLE hash_parted DETACH PARTITION hpart_4 +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1466 +-- check that the partition being detached is actually a partition of the parent +CREATE TABLE not_a_part (a int) +-- +TABLE: name="not_a_part" schema="" table="not_a_part" ctx=DDL +STMT: CreateStmt +== 1467 +ALTER TABLE list_parted2 DETACH PARTITION not_a_part +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1468 +ALTER TABLE list_parted2 DETACH PARTITION part_1 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1469 +ALTER TABLE hash_parted DETACH PARTITION not_a_part +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +== 1470 +DROP TABLE not_a_part +-- +TABLE: name="not_a_part" schema="" table="not_a_part" ctx=DDL +STMT: DropStmt +== 1471 +-- check that, after being detached, attinhcount/coninhcount is dropped to 0 and +-- attislocal/conislocal is set to true +ALTER TABLE list_parted2 DETACH PARTITION part_3_4 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1472 +SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::regclass AND attnum > 0 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 1473 +SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::regclass AND conname = 'check_a' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 1474 +DROP TABLE part_3_4 +-- +TABLE: name="part_3_4" schema="" table="part_3_4" ctx=DDL +STMT: DropStmt +== 1475 +-- check that a detached partition is not dropped on dropping a partitioned table +CREATE TABLE range_parted2 ( + a int +) PARTITION BY RANGE(a) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +== 1476 +CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100) +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=DDL +STMT: CreateStmt +== 1477 +ALTER TABLE range_parted2 DETACH PARTITION part_rp +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +== 1478 +DROP TABLE range_parted2 +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: DropStmt +== 1479 +SELECT * from part_rp +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=Select +STMT: SelectStmt +== 1480 +DROP TABLE part_rp +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=DDL +STMT: DropStmt +== 1481 +-- concurrent detach +CREATE TABLE range_parted2 ( + a int +) PARTITION BY RANGE(a) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +== 1482 +CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100) +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=DDL +STMT: CreateStmt +== 1483 +BEGIN +-- +STMT: TransactionStmt +== 1484 +-- doesn't work in a partition block +ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +== 1485 +COMMIT +-- +STMT: TransactionStmt +== 1486 +CREATE TABLE part_rpd PARTITION OF range_parted2 DEFAULT +-- +TABLE: name="part_rpd" schema="" table="part_rpd" ctx=DDL +STMT: CreateStmt +== 1487 +-- doesn't work if there's a default partition +ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +== 1488 +-- doesn't work for the default partition +ALTER TABLE range_parted2 DETACH PARTITION part_rpd CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +== 1489 +DROP TABLE part_rpd +-- +TABLE: name="part_rpd" schema="" table="part_rpd" ctx=DDL +STMT: DropStmt +== 1490 +-- works fine +ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +== 1491 +-- constraint should be created +CREATE TABLE part_rp100 PARTITION OF range_parted2 (CHECK (a>=123 AND a<133 AND a IS NOT NULL)) FOR VALUES FROM (100) to (200) +-- +TABLE: name="part_rp100" schema="" table="part_rp100" ctx=DDL +STMT: CreateStmt +== 1492 +ALTER TABLE range_parted2 DETACH PARTITION part_rp100 CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +== 1493 +-- redundant constraint should not be created +DROP TABLE range_parted2 +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: DropStmt +== 1494 +-- Test that hash partitions continue to work after they're concurrently +-- detached (bugs #18371, #19070) +CREATE TABLE hash_parted2 (a int) PARTITION BY HASH(a) +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: CreateStmt +== 1495 +CREATE TABLE part_hp PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="part_hp" schema="" table="part_hp" ctx=DDL +STMT: CreateStmt +== 1496 +ALTER TABLE hash_parted2 DETACH PARTITION part_hp CONCURRENTLY +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: AlterTableStmt +== 1497 +DROP TABLE hash_parted2 +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: DropStmt +== 1498 +INSERT INTO part_hp VALUES (1) +-- +TABLE: name="part_hp" schema="" table="part_hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1499 +DROP TABLE part_hp +-- +TABLE: name="part_hp" schema="" table="part_hp" ctx=DDL +STMT: DropStmt +== 1500 +-- Check ALTER TABLE commands for partitioned tables and partitions + +-- cannot add/drop column to/from *only* the parent +ALTER TABLE ONLY list_parted2 ADD COLUMN c int +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1501 +ALTER TABLE ONLY list_parted2 DROP COLUMN b +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1502 +-- cannot add a column to partition or drop an inherited one +ALTER TABLE part_2 ADD COLUMN c text +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +== 1503 +ALTER TABLE part_2 DROP COLUMN b +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +== 1504 +-- Nor rename, alter type +ALTER TABLE part_2 RENAME COLUMN b to c +-- +STMT: RenameStmt +== 1505 +ALTER TABLE part_2 ALTER COLUMN b TYPE text +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +== 1506 +-- cannot add/drop NOT NULL or check constraints to *only* the parent, when +-- partitions exist +ALTER TABLE ONLY list_parted2 ALTER b SET NOT NULL +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1507 +ALTER TABLE ONLY list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz') +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1508 +ALTER TABLE list_parted2 ALTER b SET NOT NULL +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1509 +ALTER TABLE ONLY list_parted2 ALTER b DROP NOT NULL +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1510 +ALTER TABLE list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz') +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1511 +ALTER TABLE ONLY list_parted2 DROP CONSTRAINT check_b +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1512 +-- It's alright though, if no partitions are yet created +CREATE TABLE parted_no_parts (a int) PARTITION BY LIST (a) +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: CreateStmt +== 1513 +ALTER TABLE ONLY parted_no_parts ALTER a SET NOT NULL +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +== 1514 +ALTER TABLE ONLY parted_no_parts ADD CONSTRAINT check_a CHECK (a > 0) +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +== 1515 +ALTER TABLE ONLY parted_no_parts ALTER a DROP NOT NULL +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +== 1516 +ALTER TABLE ONLY parted_no_parts DROP CONSTRAINT check_a +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +== 1517 +DROP TABLE parted_no_parts +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: DropStmt +== 1518 +-- cannot drop inherited NOT NULL or check constraints from partition +ALTER TABLE list_parted2 ALTER b SET NOT NULL, ADD CONSTRAINT check_a2 CHECK (a > 0) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1519 +ALTER TABLE part_2 ALTER b DROP NOT NULL +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +== 1520 +ALTER TABLE part_2 DROP CONSTRAINT check_a2 +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +== 1521 +-- Doesn't make sense to add NO INHERIT constraints on partitioned tables +ALTER TABLE list_parted2 add constraint check_b2 check (b <> 'zz') NO INHERIT +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1522 +-- check that a partition cannot participate in regular inheritance +CREATE TABLE inh_test () INHERITS (part_2) +-- +TABLE: name="inh_test" schema="" table="inh_test" ctx=DDL +STMT: CreateStmt +== 1523 +CREATE TABLE inh_test (LIKE part_2) +-- +TABLE: name="inh_test" schema="" table="inh_test" ctx=DDL +STMT: CreateStmt +== 1524 +ALTER TABLE inh_test INHERIT part_2 +-- +TABLE: name="inh_test" schema="" table="inh_test" ctx=DDL +STMT: AlterTableStmt +== 1525 +ALTER TABLE part_2 INHERIT inh_test +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +== 1526 +-- cannot drop or alter type of partition key columns of lower level +-- partitioned tables; for example, part_5, which is list_parted2's +-- partition, is partitioned on b; +ALTER TABLE list_parted2 DROP COLUMN b +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1527 +ALTER TABLE list_parted2 ALTER COLUMN b TYPE text +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +== 1528 +-- dropping non-partition key columns should be allowed on the parent table. +ALTER TABLE list_parted DROP COLUMN b +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 1529 +SELECT * FROM list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 1530 +-- cleanup +DROP TABLE list_parted, list_parted2, range_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 1531 +DROP TABLE fail_def_part +-- +TABLE: name="fail_def_part" schema="" table="fail_def_part" ctx=DDL +STMT: DropStmt +== 1532 +DROP TABLE hash_parted +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: DropStmt +== 1533 +-- more tests for certain multi-level partitioning scenarios +create table p (a int, b int) partition by range (a, b) +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: CreateStmt +== 1534 +create table p1 (b int, a int not null) partition by range (b) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 1535 +create table p11 (like p1) +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: CreateStmt +== 1536 +alter table p11 drop a +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +== 1537 +alter table p11 add a int +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +== 1538 +alter table p11 drop a +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +== 1539 +alter table p11 add a int not null +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +== 1540 +-- attnum for key attribute 'a' is different in p, p1, and p11 +select attrelid::regclass, attname, attnum +from pg_attribute +where attname = 'a' + and (attrelid = 'p'::regclass + or attrelid = 'p1'::regclass + or attrelid = 'p11'::regclass) +order by attrelid::regclass::text +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attname" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +== 1541 +alter table p1 attach partition p11 for values from (2) to (5) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 1542 +insert into p1 (a, b) values (2, 3) +-- +TABLE: name="p1" schema="" table="p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1543 +-- check that partition validation scan correctly detects violating rows +alter table p attach partition p1 for values from (1, 2) to (1, 10) +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: AlterTableStmt +== 1544 +-- cleanup +drop table p +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: DropStmt +== 1545 +drop table p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 1546 +-- validate constraint on partitioned tables should only scan leaf partitions +create table parted_validate_test (a int) partition by list (a) +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: CreateStmt +== 1547 +create table parted_validate_test_1 partition of parted_validate_test for values in (0, 1) +-- +TABLE: name="parted_validate_test_1" schema="" table="parted_validate_test_1" ctx=DDL +STMT: CreateStmt +== 1548 +alter table parted_validate_test add constraint parted_validate_test_chka check (a > 0) not valid +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: AlterTableStmt +== 1549 +alter table parted_validate_test validate constraint parted_validate_test_chka +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: AlterTableStmt +== 1550 +drop table parted_validate_test +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: DropStmt +== 1551 +-- test alter column options +CREATE TABLE attmp(i integer) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +== 1552 +INSERT INTO attmp VALUES (1) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1553 +ALTER TABLE attmp ALTER COLUMN i SET (n_distinct = 1, n_distinct_inherited = 2) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 1554 +ALTER TABLE attmp ALTER COLUMN i RESET (n_distinct_inherited) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +== 1555 +ANALYZE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: VacuumStmt +== 1556 +DROP TABLE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: DropStmt +== 1557 +DROP USER regress_alter_table_user1 +-- +STMT: DropRoleStmt +== 1558 +-- check that violating rows are correctly reported when attaching as the +-- default partition +create table defpart_attach_test (a int) partition by list (a) +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: CreateStmt +== 1559 +create table defpart_attach_test1 partition of defpart_attach_test for values in (1) +-- +TABLE: name="defpart_attach_test1" schema="" table="defpart_attach_test1" ctx=DDL +STMT: CreateStmt +== 1560 +create table defpart_attach_test_d (b int, a int) +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DDL +STMT: CreateStmt +== 1561 +alter table defpart_attach_test_d drop b +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DDL +STMT: AlterTableStmt +== 1562 +insert into defpart_attach_test_d values (1), (2) +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1563 +-- error because its constraint as the default partition would be violated +-- by the row containing 1 +alter table defpart_attach_test attach partition defpart_attach_test_d default +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: AlterTableStmt +== 1564 +delete from defpart_attach_test_d where a = 1 +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DML +STMT: DeleteStmt +== 1565 +alter table defpart_attach_test_d add check (a > 1) +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DDL +STMT: AlterTableStmt +== 1566 +-- should be attached successfully and without needing to be scanned +alter table defpart_attach_test attach partition defpart_attach_test_d default +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: AlterTableStmt +== 1567 +-- check that attaching a partition correctly reports any rows in the default +-- partition that should not be there for the new partition to be attached +-- successfully +create table defpart_attach_test_2 (like defpart_attach_test_d) +-- +TABLE: name="defpart_attach_test_2" schema="" table="defpart_attach_test_2" ctx=DDL +STMT: CreateStmt +== 1568 +alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2) +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: AlterTableStmt +== 1569 +drop table defpart_attach_test +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: DropStmt +== 1570 +-- check combinations of temporary and permanent relations when attaching +-- partitions. +create table perm_part_parent (a int) partition by list (a) +-- +TABLE: name="perm_part_parent" schema="" table="perm_part_parent" ctx=DDL +STMT: CreateStmt +== 1571 +create temp table temp_part_parent (a int) partition by list (a) +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: CreateStmt +== 1572 +create table perm_part_child (a int) +-- +TABLE: name="perm_part_child" schema="" table="perm_part_child" ctx=DDL +STMT: CreateStmt +== 1573 +create temp table temp_part_child (a int) +-- +TABLE: name="temp_part_child" schema="" table="temp_part_child" ctx=DDL +STMT: CreateStmt +== 1574 +alter table temp_part_parent attach partition perm_part_child default +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: AlterTableStmt +== 1575 +-- error +alter table perm_part_parent attach partition temp_part_child default +-- +TABLE: name="perm_part_parent" schema="" table="perm_part_parent" ctx=DDL +STMT: AlterTableStmt +== 1576 +-- error +alter table temp_part_parent attach partition temp_part_child default +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: AlterTableStmt +== 1577 +-- ok +drop table perm_part_parent cascade +-- +TABLE: name="perm_part_parent" schema="" table="perm_part_parent" ctx=DDL +STMT: DropStmt +== 1578 +drop table temp_part_parent cascade +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: DropStmt +== 1579 +-- check that attaching partitions to a table while it is being used is +-- prevented +create table tab_part_attach (a int) partition by list (a) +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DDL +STMT: CreateStmt +== 1580 +create or replace function func_part_attach() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_attach_1 (a int)'; + execute 'alter table tab_part_attach attach partition tab_part_attach_1 for values in (1)'; + return null; + end $$ +-- +FUNCTION: name="func_part_attach" function="func_part_attach" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1581 +create trigger trig_part_attach before insert on tab_part_attach + for each statement execute procedure func_part_attach() +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DDL +STMT: CreateTrigStmt +== 1582 +insert into tab_part_attach values (1) +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1583 +drop table tab_part_attach +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DDL +STMT: DropStmt +== 1584 +drop function func_part_attach() +-- +FUNCTION: name="func_part_attach" function="func_part_attach" schema="" ctx=DDL +STMT: DropStmt +== 1585 +-- test case where the partitioning operator is a SQL function whose +-- evaluation results in the table's relcache being rebuilt partway through +-- the execution of an ATTACH PARTITION command +create function at_test_sql_partop (int4, int4) returns int language sql +as $$ select case when $1 = $2 then 0 when $1 > $2 then 1 else -1 end; $$ +-- +FUNCTION: name="at_test_sql_partop" function="at_test_sql_partop" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1586 +create operator class at_test_sql_partop for type int4 using btree as + operator 1 < (int4, int4), operator 2 <= (int4, int4), + operator 3 = (int4, int4), operator 4 >= (int4, int4), + operator 5 > (int4, int4), function 1 at_test_sql_partop(int4, int4) +-- +STMT: CreateOpClassStmt +== 1587 +create table at_test_sql_partop (a int) partition by range (a at_test_sql_partop) +-- +TABLE: name="at_test_sql_partop" schema="" table="at_test_sql_partop" ctx=DDL +STMT: CreateStmt +== 1588 +create table at_test_sql_partop_1 (a int) +-- +TABLE: name="at_test_sql_partop_1" schema="" table="at_test_sql_partop_1" ctx=DDL +STMT: CreateStmt +== 1589 +alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values from (0) to (10) +-- +TABLE: name="at_test_sql_partop" schema="" table="at_test_sql_partop" ctx=DDL +STMT: AlterTableStmt +== 1590 +drop table at_test_sql_partop +-- +TABLE: name="at_test_sql_partop" schema="" table="at_test_sql_partop" ctx=DDL +STMT: DropStmt +== 1591 +drop operator class at_test_sql_partop using btree +-- +STMT: DropStmt +== 1592 +drop function at_test_sql_partop +-- +FUNCTION: name="at_test_sql_partop" function="at_test_sql_partop" schema="" ctx=DDL +STMT: DropStmt +== 1593 +/* Test case for bug #16242 */ + +-- We create a parent and child where the child has missing +-- non-null attribute values, and arrange to pass them through +-- tuple conversion from the child to the parent tupdesc +create table bar1 (a integer, b integer not null default 1) + partition by range (a) +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DDL +STMT: CreateStmt +== 1594 +create table bar2 (a integer) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DDL +STMT: CreateStmt +== 1595 +insert into bar2 values (1) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1596 +alter table bar2 add column b integer not null default 1 +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DDL +STMT: AlterTableStmt +== 1597 +-- (at this point bar2 contains tuple with natts=1) +alter table bar1 attach partition bar2 default +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DDL +STMT: AlterTableStmt +== 1598 +-- this works: +select * from bar1 +-- +TABLE: name="bar1" schema="" table="bar1" ctx=Select +STMT: SelectStmt +== 1599 +-- this exercises tuple conversion: +create function xtrig() + returns trigger language plpgsql +as $$ + declare + r record; + begin + for r in select * from old loop + raise info 'a=%, b=%', r.a, r.b; + end loop; + return NULL; + end; +$$ +-- +FUNCTION: name="xtrig" function="xtrig" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1600 +create trigger xtrig + after update on bar1 + referencing old table as old + for each statement execute procedure xtrig() +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DDL +STMT: CreateTrigStmt +== 1601 +update bar1 set a = a + 1 +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DML +STMT: UpdateStmt +== 1602 +/* End test case for bug #16242 */ + +/* Test case for bug #17409 */ + +create table attbl (p1 int constraint pk_attbl primary key) +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: CreateStmt +== 1603 +create table atref (c1 int references attbl(p1)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: CreateStmt +== 1604 +cluster attbl using pk_attbl +-- +STMT: ClusterStmt +== 1605 +alter table attbl alter column p1 set data type bigint +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +== 1606 +alter table atref alter column c1 set data type bigint +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: AlterTableStmt +== 1607 +drop table attbl, atref +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: DropStmt +== 1608 +create table attbl (p1 int constraint pk_attbl primary key) +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: CreateStmt +== 1609 +alter table attbl replica identity using index pk_attbl +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +== 1610 +create table atref (c1 int references attbl(p1)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: CreateStmt +== 1611 +alter table attbl alter column p1 set data type bigint +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +== 1612 +alter table atref alter column c1 set data type bigint +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: AlterTableStmt +== 1613 +drop table attbl, atref +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: DropStmt +== 1614 +/* End test case for bug #17409 */ + +/* Test case for bug #18970 */ + +create table attbl(a int) +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: CreateStmt +== 1615 +create table atref(b attbl check ((b).a is not null)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: CreateStmt +== 1616 +alter table attbl alter column a type numeric +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +== 1617 +-- someday this should work +alter table atref drop constraint atref_b_check +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: AlterTableStmt +== 1618 +create statistics atref_stat on ((b).a is not null) from atref +-- +STMT: CreateStatsStmt +== 1619 +alter table attbl alter column a type numeric +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +== 1620 +-- someday this should work +drop statistics atref_stat +-- +STMT: DropStmt +== 1621 +create index atref_idx on atref (((b).a)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: IndexStmt +== 1622 +alter table attbl alter column a type numeric +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +== 1623 +-- someday this should work +drop table attbl, atref +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: DropStmt +== 1624 +/* End test case for bug #18970 */ + +-- Test that ALTER TABLE rewrite preserves a clustered index +-- for normal indexes and indexes on constraints. +create table alttype_cluster (a int) +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: CreateStmt +== 1625 +alter table alttype_cluster add primary key (a) +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +== 1626 +create index alttype_cluster_ind on alttype_cluster (a) +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: IndexStmt +== 1627 +alter table alttype_cluster cluster on alttype_cluster_ind +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +== 1628 +-- Normal index remains clustered. +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 1629 +alter table alttype_cluster alter a type bigint +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +== 1630 +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 1631 +-- Constraint index remains clustered. +alter table alttype_cluster cluster on alttype_cluster_pkey +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +== 1632 +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 1633 +alter table alttype_cluster alter a type int +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +== 1634 +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 1635 +drop table alttype_cluster +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: DropStmt +== 1636 +|-- +-- Check that attaching or detaching a partitioned partition correctly leads +-- to its partitions' constraint being updated to reflect the parent's +-- newly added/removed constraint +create table target_parted (a int, b int) partition by list (a) +-- +TABLE: name="target_parted" schema="" table="target_parted" ctx=DDL +STMT: CreateStmt +== 1637 +create table attach_parted (a int, b int) partition by list (b) +-- +TABLE: name="attach_parted" schema="" table="attach_parted" ctx=DDL +STMT: CreateStmt +== 1638 +create table attach_parted_part1 partition of attach_parted for values in (1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DDL +STMT: CreateStmt +== 1639 +-- insert a row directly into the leaf partition so that its partition +-- constraint is built and stored in the relcache +insert into attach_parted_part1 values (1, 1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1640 +-- the following better invalidate the partition constraint of the leaf +-- partition too... +alter table target_parted attach partition attach_parted for values in (1) +-- +TABLE: name="target_parted" schema="" table="target_parted" ctx=DDL +STMT: AlterTableStmt +== 1641 +-- ...such that the following insert fails +insert into attach_parted_part1 values (2, 1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1642 +-- ...and doesn't when the partition is detached along with its own partition +alter table target_parted detach partition attach_parted +-- +TABLE: name="target_parted" schema="" table="target_parted" ctx=DDL +STMT: AlterTableStmt +== 1643 +insert into attach_parted_part1 values (2, 1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1644 +-- Test altering table having publication +create schema alter1 +-- +STMT: CreateSchemaStmt +== 1645 +create schema alter2 +-- +STMT: CreateSchemaStmt +== 1646 +create table alter1.t1 (a int) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DDL +STMT: CreateStmt +== 1647 +set client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 1648 +create publication pub1 for table alter1.t1, tables in schema alter2 +-- +STMT: CreatePublicationStmt +== 1649 +reset client_min_messages +-- +STMT: VariableSetStmt +== 1650 +alter table alter1.t1 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +== 1651 +drop publication pub1 +-- +STMT: DropStmt +== 1652 +drop schema alter1 cascade +-- +STMT: DropStmt +== 1653 +drop schema alter2 cascade +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/amutils.metadata.json b/parser/testdata/summary/postgres_regress/amutils.metadata.json new file mode 100644 index 0000000..92b8f9e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/amutils.metadata.json @@ -0,0 +1,14 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010" + ] +} diff --git a/parser/testdata/summary/postgres_regress/amutils.test b/parser/testdata/summary/postgres_regress/amutils.test new file mode 100644 index 0000000..a8c5b0c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/amutils.test @@ -0,0 +1,161 @@ +== 001 +|-- +-- Test index AM property-reporting functions +|-- + +select prop, + pg_indexam_has_property(a.oid, prop) as "AM", + pg_index_has_property('onek_hundred'::regclass, prop) as "Index", + pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as "Column" + from pg_am a, + unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'can_order', 'can_unique', 'can_multi_col', + 'can_exclude', 'can_include', + 'bogus']::text[]) + with ordinality as u(prop,ord) + where a.amname = 'btree' + order by ord +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +FUNCTION: name="pg_indexam_has_property" function="pg_indexam_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="amname" +STMT: SelectStmt +== 002 +select prop, + pg_indexam_has_property(a.oid, prop) as "AM", + pg_index_has_property('gcircleind'::regclass, prop) as "Index", + pg_index_column_has_property('gcircleind'::regclass, 1, prop) as "Column" + from pg_am a, + unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'can_order', 'can_unique', 'can_multi_col', + 'can_exclude', 'can_include', + 'bogus']::text[]) + with ordinality as u(prop,ord) + where a.amname = 'gist' + order by ord +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +FUNCTION: name="pg_indexam_has_property" function="pg_indexam_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="amname" +STMT: SelectStmt +== 003 +select prop, + pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as btree, + pg_index_column_has_property('hash_i4_index'::regclass, 1, prop) as hash, + pg_index_column_has_property('gcircleind'::regclass, 1, prop) as gist, + pg_index_column_has_property('sp_radix_ind'::regclass, 1, prop) as spgist_radix, + pg_index_column_has_property('sp_quad_ind'::regclass, 1, prop) as spgist_quad, + pg_index_column_has_property('botharrayidx'::regclass, 1, prop) as gin, + pg_index_column_has_property('brinidx'::regclass, 1, prop) as brin + from unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'bogus']::text[]) + with ordinality as u(prop,ord) + order by ord +-- +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 004 +select prop, + pg_index_has_property('onek_hundred'::regclass, prop) as btree, + pg_index_has_property('hash_i4_index'::regclass, prop) as hash, + pg_index_has_property('gcircleind'::regclass, prop) as gist, + pg_index_has_property('sp_radix_ind'::regclass, prop) as spgist, + pg_index_has_property('botharrayidx'::regclass, prop) as gin, + pg_index_has_property('brinidx'::regclass, prop) as brin + from unnest(array['clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'bogus']::text[]) + with ordinality as u(prop,ord) + order by ord +-- +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 005 +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', + 'can_exclude', 'can_include', 'bogus']::text[]) + with ordinality as u(prop,ord) + where amtype = 'i' + order by amname, ord +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +FUNCTION: name="pg_indexam_has_property" function="pg_indexam_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="amtype" +STMT: SelectStmt +== 006 +|-- +-- additional checks for pg_index_column_has_property +|-- +CREATE TEMP TABLE foo (f1 int, f2 int, f3 int, f4 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 007 +CREATE INDEX fooindex ON foo (f1 desc, f2 asc, f3 nulls first, f4 nulls last) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +== 008 +select col, prop, pg_index_column_has_property(o, col, prop) + from (values ('fooindex'::regclass)) v1(o), + (values (1,'orderable'),(2,'asc'),(3,'desc'), + (4,'nulls_first'),(5,'nulls_last'), + (6, 'bogus')) v2(idx,prop), + generate_series(1,4) col + order by col, idx +-- +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 009 +CREATE INDEX foocover ON foo (f1) INCLUDE (f2,f3) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +== 010 +select col, prop, pg_index_column_has_property(o, col, prop) + from (values ('foocover'::regclass)) v1(o), + (values (1,'orderable'),(2,'asc'),(3,'desc'), + (4,'nulls_first'),(5,'nulls_last'), + (6,'distance_orderable'),(7,'returnable'), + (8, 'bogus')) v2(idx,prop), + generate_series(1,3) col + order by col, idx +-- +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/arrays.metadata.json b/parser/testdata/summary/postgres_regress/arrays.metadata.json new file mode 100644 index 0000000..a8dc578 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/arrays.metadata.json @@ -0,0 +1,488 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484" + ] +} diff --git a/parser/testdata/summary/postgres_regress/arrays.test b/parser/testdata/summary/postgres_regress/arrays.test new file mode 100644 index 0000000..2fc9d59 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/arrays.test @@ -0,0 +1,2785 @@ +== 001 +|-- +-- ARRAYS +|-- + +-- directory paths are passed to us in environment variables + +CREATE TABLE arrtest ( + a int2[], + b int4[][][], + c name[], + d text[][], + e float8[], + f char(5)[], + g varchar(5)[] +) +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE array_op_test ( + seqno int4, + i int4[], + t text[] +) +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=DDL +STMT: CreateStmt +== 003 +COPY array_op_test FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +ANALYZE array_op_test +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=DDL +STMT: VacuumStmt +== 005 +|-- +-- only the 'e' array is 0-based, the others are 1-based. +|-- + +INSERT INTO arrtest (a[1:5], b[1:1][1:2][1:2], c, d, f, g) + VALUES ('{1,2,3,4,5}', '{{{0,0},{1,2}}}', '{}', '{}', '{}', '{}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +UPDATE arrtest SET e[0] = '1.1' +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +== 007 +UPDATE arrtest SET e[1] = '2.2' +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +== 008 +INSERT INTO arrtest (f) + VALUES ('{"too long"}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO arrtest (a, b[1:2][1:2], c, d, e, f, g) + VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}', + '{{"elt1", "elt2"}}', '{"3.4", "6.7"}', + '{"abc","abcde"}', '{"abc","abcde"}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO arrtest (a, b[1:2], c, d[1:2]) + VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO arrtest (b[2]) VALUES(now()) +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 012 +-- error, type mismatch + +INSERT INTO arrtest (b[1:2]) VALUES(now()) +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 013 +-- error, type mismatch + +SELECT * FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 014 +SELECT arrtest.a[1], + arrtest.b[1][1][1], + arrtest.c[1], + arrtest.d[1][1], + arrtest.e[0] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 015 +SELECT a[1], b[1][1][1], c[1], d[1][1], e[0] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 016 +SELECT a[1:3], + b[1:1][1:2][1:2], + c[1:2], + d[1:1][1:2] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 017 +SELECT array_ndims(a) AS a,array_ndims(b) AS b,array_ndims(c) AS c + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT array_dims(a) AS a,array_dims(b) AS b,array_dims(c) AS c + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- returns nothing +SELECT * + FROM arrtest + WHERE a[1] < 5 and + c = '{"foobar"}'::_name +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="c" +STMT: SelectStmt +== 020 +UPDATE arrtest + SET a[1:2] = '{16,25}' + WHERE NOT a = '{}'::_int2 +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +== 021 +UPDATE arrtest + SET b[1:1][1:1][1:2] = '{113, 117}', + b[1:1][1:2][2:2] = '{142, 147}' + WHERE array_dims(b) = '[1:1][1:2][1:2]' +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +== 022 +UPDATE arrtest + SET c[2:2] = '{"new_word"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +== 023 +SELECT a,b,c FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 024 +SELECT a[1:3], + b[1:1][1:2][1:2], + c[1:2], + d[1:1][2:2] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 025 +SELECT b[1:1][2][2], + d[1:1][2] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 026 +INSERT INTO arrtest(a) VALUES('{1,null,3}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +SELECT a FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 028 +UPDATE arrtest SET a[4] = NULL WHERE a[2] IS NULL +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +== 029 +SELECT a FROM arrtest WHERE a[2] IS NULL +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 030 +DELETE FROM arrtest WHERE a[2] IS NULL AND b IS NULL +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: DeleteStmt +== 031 +SELECT a,b,c FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +== 032 +-- test non-error-throwing API +SELECT pg_input_is_valid('{1,2,3}', 'integer[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT pg_input_is_valid('{1,2', 'integer[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT pg_input_is_valid('{1,zed}', 'integer[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT * FROM pg_input_error_info('{1,zed}', 'integer[]') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- test mixed slice/scalar subscripting +select '{{1,2,3},{4,5,6},{7,8,9}}'::int[] +-- +STMT: SelectStmt +== 037 +select ('{{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2] +-- +STMT: SelectStmt +== 038 +select '[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[] +-- +STMT: SelectStmt +== 039 +select ('[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2] +-- +STMT: SelectStmt +== 040 +|-- +-- check subscription corner cases +|-- +-- More subscripts than MAXDIM (6) +SELECT ('{}'::int[])[1][2][3][4][5][6][7] +-- +STMT: SelectStmt +== 041 +-- NULL index yields NULL when selecting +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL][1] +-- +STMT: SelectStmt +== 042 +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL:1][1] +-- +STMT: SelectStmt +== 043 +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][1:NULL][1] +-- +STMT: SelectStmt +== 044 +-- NULL index in assignment is an error +UPDATE arrtest + SET c[NULL] = '{"can''t assign"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +== 045 +UPDATE arrtest + SET c[NULL:1] = '{"can''t assign"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +== 046 +UPDATE arrtest + SET c[1:NULL] = '{"can''t assign"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +== 047 +-- Un-subscriptable type +SELECT (now())[1] +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 048 +-- test slices with empty lower and/or upper index +CREATE TEMP TABLE arrtest_s ( + a int2[], + b int2[][] +) +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DDL +STMT: CreateStmt +== 049 +INSERT INTO arrtest_s VALUES ('{1,2,3,4,5}', '{{1,2,3}, {4,5,6}, {7,8,9}}') +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO arrtest_s VALUES ('[0:4]={1,2,3,4,5}', '[0:2][0:2]={{1,2,3}, {4,5,6}, {7,8,9}}') +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +== 052 +SELECT a[:3], b[:2][:2] FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +== 053 +SELECT a[2:], b[2:][2:] FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +== 054 +SELECT a[:], b[:] FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +== 055 +-- updates +UPDATE arrtest_s SET a[:3] = '{11, 12, 13}', b[:2][:2] = '{{11,12}, {14,15}}' + WHERE array_lower(a,1) = 1 +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +STMT: UpdateStmt +== 056 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +== 057 +UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{25,26}, {28,29}}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +== 058 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +== 059 +UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +== 060 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +== 061 +UPDATE arrtest_s SET a[:] = '{23, 24, 25}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +== 062 +-- fail, too small +INSERT INTO arrtest_s VALUES(NULL, NULL) +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +== 064 +-- fail, no good with null + +-- we want to work with a point_tbl that includes a null +CREATE TEMP TABLE point_tbl AS SELECT * FROM public.point_tbl +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +TABLE: name="public.point_tbl" schema="public" table="point_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 065 +INSERT INTO POINT_TBL(f1) VALUES (NULL) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 066 +-- check with fixed-length-array type, such as point +SELECT f1[0:1] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 067 +SELECT f1[0:] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 068 +SELECT f1[:1] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 069 +SELECT f1[:] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 070 +-- subscript assignments to fixed-width result in NULL if previous value is NULL +UPDATE point_tbl SET f1[0] = 10 WHERE f1 IS NULL RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +== 071 +INSERT INTO point_tbl(f1[0]) VALUES(0) RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +-- NULL assignments get ignored +UPDATE point_tbl SET f1[0] = NULL WHERE f1::text = '(10,10)'::point::text RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +== 073 +-- but non-NULL subscript assignments work +UPDATE point_tbl SET f1[0] = -10, f1[1] = -10 WHERE f1::text = '(10,10)'::point::text RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +== 074 +-- but not to expand the range +UPDATE point_tbl SET f1[3] = 10 WHERE f1::text = '(-10,-10)'::point::text RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +== 075 +|-- +-- test array extension +|-- +CREATE TEMP TABLE arrtest1 (i int[], t text[]) +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DDL +STMT: CreateStmt +== 076 +insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']) +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 078 +update arrtest1 set i[2] = 22, t[2] = 'twenty-two' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 079 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 080 +update arrtest1 set i[5] = 5, t[5] = 'five' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 081 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 082 +update arrtest1 set i[8] = 8, t[8] = 'eight' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 083 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 084 +update arrtest1 set i[0] = 0, t[0] = 'zero' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 085 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 086 +update arrtest1 set i[-3] = -3, t[-3] = 'minus-three' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 087 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 088 +update arrtest1 set i[0:2] = array[10,11,12], t[0:2] = array['ten','eleven','twelve'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 089 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 090 +update arrtest1 set i[8:10] = array[18,null,20], t[8:10] = array['p18',null,'p20'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 091 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 092 +update arrtest1 set i[11:12] = array[null,22], t[11:12] = array[null,'p22'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 093 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 094 +update arrtest1 set i[15:16] = array[null,26], t[15:16] = array[null,'p26'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 095 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 096 +update arrtest1 set i[-5:-3] = array[-15,-14,-13], t[-5:-3] = array['m15','m14','m13'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 097 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 098 +update arrtest1 set i[-7:-6] = array[-17,null], t[-7:-6] = array['m17',null] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 099 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 100 +update arrtest1 set i[-12:-10] = array[-22,null,-20], t[-12:-10] = array['m22',null,'m20'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 101 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 102 +delete from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: DeleteStmt +== 103 +insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']) +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 105 +update arrtest1 set i[0:5] = array[0,1,2,null,4,5], t[0:5] = array['z','p1','p2',null,'p4','p5'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +== 106 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +== 107 +|-- +-- array expressions and operators +|-- + +-- table creation and INSERTs +CREATE TEMP TABLE arrtest2 (i integer ARRAY[4], f float8[], n numeric[], t text[], d timestamp[]) +-- +TABLE: name="arrtest2" schema="" table="arrtest2" ctx=DDL +STMT: CreateStmt +== 108 +INSERT INTO arrtest2 VALUES( + ARRAY[[[113,142],[1,147]]], + ARRAY[1.1,1.2,1.3]::float8[], + ARRAY[1.1,1.2,1.3], + ARRAY[[['aaa','aab'],['aba','abb'],['aca','acb']],[['baa','bab'],['bba','bbb'],['bca','bcb']]], + ARRAY['19620326','19931223','19970117']::timestamp[] +) +-- +TABLE: name="arrtest2" schema="" table="arrtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +-- some more test data +CREATE TEMP TABLE arrtest_f (f0 int, f1 text, f2 float8) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DDL +STMT: CreateStmt +== 110 +insert into arrtest_f values(1,'cat1',1.21) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +insert into arrtest_f values(2,'cat1',1.24) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +insert into arrtest_f values(3,'cat1',1.18) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 113 +insert into arrtest_f values(4,'cat1',1.26) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 114 +insert into arrtest_f values(5,'cat1',1.15) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +insert into arrtest_f values(6,'cat2',1.15) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +insert into arrtest_f values(7,'cat2',1.26) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +insert into arrtest_f values(8,'cat2',1.32) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +insert into arrtest_f values(9,'cat2',1.30) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +CREATE TEMP TABLE arrtest_i (f0 int, f1 text, f2 int) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DDL +STMT: CreateStmt +== 120 +insert into arrtest_i values(1,'cat1',21) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +insert into arrtest_i values(2,'cat1',24) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +insert into arrtest_i values(3,'cat1',18) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +insert into arrtest_i values(4,'cat1',26) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 124 +insert into arrtest_i values(5,'cat1',15) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +insert into arrtest_i values(6,'cat2',15) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 126 +insert into arrtest_i values(7,'cat2',26) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +insert into arrtest_i values(8,'cat2',32) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 128 +insert into arrtest_i values(9,'cat2',30) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +-- expressions +SELECT t.f[1][3][1] AS "131", t.f[2][2][1] AS "221" FROM ( + SELECT ARRAY[[[111,112],[121,122],[131,132]],[[211,212],[221,122],[231,232]]] AS f +) AS t +-- +STMT: SelectStmt +== 130 +SELECT ARRAY[[[[[['hello'],['world']]]]]] +-- +STMT: SelectStmt +== 131 +SELECT ARRAY[ARRAY['hello'],ARRAY['world']] +-- +STMT: SelectStmt +== 132 +SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY" +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=Select +STMT: SelectStmt +== 133 +-- with nulls +SELECT '{1,null,3}'::int[] +-- +STMT: SelectStmt +== 134 +SELECT ARRAY[1,NULL,3] +-- +STMT: SelectStmt +== 135 +-- functions +SELECT array_append(array[42], 6) AS "{42,6}" +-- +FUNCTION: name="array_append" function="array_append" schema="" ctx=Call +STMT: SelectStmt +== 136 +SELECT array_prepend(6, array[42]) AS "{6,42}" +-- +FUNCTION: name="array_prepend" function="array_prepend" schema="" ctx=Call +STMT: SelectStmt +== 137 +SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}" +-- +FUNCTION: name="array_cat" function="array_cat" schema="" ctx=Call +STMT: SelectStmt +== 138 +SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}" +-- +FUNCTION: name="array_cat" function="array_cat" schema="" ctx=Call +STMT: SelectStmt +== 139 +SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}" +-- +FUNCTION: name="array_cat" function="array_cat" schema="" ctx=Call +STMT: SelectStmt +== 140 +SELECT array_position(ARRAY[1,2,3,4,5], 4) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT array_position(ARRAY[5,3,4,2,1], 4) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 142 +SELECT array_position(ARRAY[[1,2],[3,4]], 3) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 143 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon') +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 144 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'sat') +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 145 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], NULL) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 146 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], NULL) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 147 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], 'sat') +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 148 +SELECT array_positions(NULL, 10) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 149 +SELECT array_positions(NULL, NULL::int) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 150 +SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], 4) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 151 +SELECT array_positions(ARRAY[[1,2],[3,4]], 4) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 152 +SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], NULL) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 153 +SELECT array_positions(ARRAY[1,2,3,NULL,5,6,1,2,3,NULL,5,6], NULL) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 154 +SELECT array_length(array_positions(ARRAY(SELECT 'AAAAAAAAAAAAAAAAAAAAAAAAA'::text || i % 10 + FROM generate_series(1,100) g(i)), + 'AAAAAAAAAAAAAAAAAAAAAAAAA5'), 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 155 +DO $$ +DECLARE + o int; + a int[] := ARRAY[1,2,3,2,3,1,2]; +BEGIN + o := array_position(a, 2); + WHILE o IS NOT NULL + LOOP + RAISE NOTICE '%', o; + o := array_position(a, 2, o + 1); + END LOOP; +END +$$ LANGUAGE plpgsql +-- +STMT: DoStmt +== 156 +SELECT array_position('[2:4]={1,2,3}'::int[], 1) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +== 157 +SELECT array_positions('[2:4]={1,2,3}'::int[], 1) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 158 +SELECT + array_position(ids, (1, 1)), + array_positions(ids, (1, 1)) + FROM +(VALUES + (ARRAY[(0, 0), (1, 1)]), + (ARRAY[(1, 1)]) +) AS f (ids) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +== 159 +-- operators +SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]] +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 160 +SELECT NOT ARRAY[1.1,1.2,1.3] = ARRAY[1.1,1.2,1.3] AS "FALSE" +-- +STMT: SelectStmt +== 161 +SELECT ARRAY[1,2] || 3 AS "{1,2,3}" +-- +STMT: SelectStmt +== 162 +SELECT 0 || ARRAY[1,2] AS "{0,1,2}" +-- +STMT: SelectStmt +== 163 +SELECT ARRAY[1,2] || ARRAY[3,4] AS "{1,2,3,4}" +-- +STMT: SelectStmt +== 164 +SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY" +-- +STMT: SelectStmt +== 165 +SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}" +-- +STMT: SelectStmt +== 166 +SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}" +-- +STMT: SelectStmt +== 167 +SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}" +-- +STMT: SelectStmt +== 168 +SELECT ARRAY[1.1] || ARRAY[2,3,4] +-- +STMT: SelectStmt +== 169 +SELECT array_agg(x) || array_agg(x) FROM (VALUES (ROW(1,2)), (ROW(3,4))) v(x) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 170 +SELECT ROW(1,2) || array_agg(x) FROM (VALUES (ROW(3,4)), (ROW(5,6))) v(x) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 171 +SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 172 +SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 173 +SELECT * FROM array_op_test WHERE i @> '{17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 174 +SELECT * FROM array_op_test WHERE i && '{17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 175 +SELECT * FROM array_op_test WHERE i @> '{32,17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 176 +SELECT * FROM array_op_test WHERE i && '{32,17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 177 +SELECT * FROM array_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 178 +SELECT * FROM array_op_test WHERE i = '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 179 +SELECT * FROM array_op_test WHERE i @> '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 180 +SELECT * FROM array_op_test WHERE i && '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 181 +SELECT * FROM array_op_test WHERE i <@ '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 182 +SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 183 +SELECT * FROM array_op_test WHERE i @> '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 184 +SELECT * FROM array_op_test WHERE i && '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 185 +SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 186 +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 187 +SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 188 +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 189 +SELECT * FROM array_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 190 +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 191 +SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 192 +SELECT * FROM array_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 193 +SELECT * FROM array_op_test WHERE t = '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 194 +SELECT * FROM array_op_test WHERE t @> '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 195 +SELECT * FROM array_op_test WHERE t && '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 196 +SELECT * FROM array_op_test WHERE t <@ '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 197 +-- array casts +SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}" +-- +STMT: SelectStmt +== 198 +SELECT pg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[]) AS "double precision[]" +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 199 +SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}" +-- +STMT: SelectStmt +== 200 +SELECT pg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]) AS "character varying[]" +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 201 +SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}" +-- +STMT: SelectStmt +== 202 +SELECT NULL::text[]::int[] AS "NULL" +-- +STMT: SelectStmt +== 203 +-- scalar op any/all (array) +select 33 = any ('{1,2,3}') +-- +STMT: SelectStmt +== 204 +select 33 = any ('{1,2,33}') +-- +STMT: SelectStmt +== 205 +select 33 = all ('{1,2,33}') +-- +STMT: SelectStmt +== 206 +select 33 >= all ('{1,2,33}') +-- +STMT: SelectStmt +== 207 +-- boundary cases +select null::int >= all ('{1,2,33}') +-- +STMT: SelectStmt +== 208 +select null::int >= all ('{}') +-- +STMT: SelectStmt +== 209 +select null::int >= any ('{}') +-- +STMT: SelectStmt +== 210 +-- cross-datatype +select 33.4 = any (array[1,2,3]) +-- +STMT: SelectStmt +== 211 +select 33.4 > all (array[1,2,3]) +-- +STMT: SelectStmt +== 212 +-- errors +select 33 * any ('{1,2,3}') +-- +STMT: SelectStmt +== 213 +select 33 * any (44) +-- +STMT: SelectStmt +== 214 +-- nulls +select 33 = any (null::int[]) +-- +STMT: SelectStmt +== 215 +select null::int = any ('{1,2,3}') +-- +STMT: SelectStmt +== 216 +select 33 = any ('{1,null,3}') +-- +STMT: SelectStmt +== 217 +select 33 = any ('{1,null,33}') +-- +STMT: SelectStmt +== 218 +select 33 = all (null::int[]) +-- +STMT: SelectStmt +== 219 +select null::int = all ('{1,2,3}') +-- +STMT: SelectStmt +== 220 +select 33 = all ('{1,null,3}') +-- +STMT: SelectStmt +== 221 +select 33 = all ('{33,null,33}') +-- +STMT: SelectStmt +== 222 +-- nulls later in the bitmap +SELECT -1 != ALL(ARRAY(SELECT NULLIF(g.i, 900) FROM generate_series(1,1000) g(i))) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 223 +-- test indexes on arrays +create temp table arr_tbl (f1 int[] unique) +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DDL +STMT: CreateStmt +== 224 +insert into arr_tbl values ('{1,2,3}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +insert into arr_tbl values ('{1,2}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 226 +-- failure expected: +insert into arr_tbl values ('{1,2,3}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 227 +insert into arr_tbl values ('{2,3,4}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 228 +insert into arr_tbl values ('{1,5,3}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 229 +insert into arr_tbl values ('{1,2,10}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +set enable_seqscan to off +-- +STMT: VariableSetStmt +== 231 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +== 232 +select * from arr_tbl where f1 > '{1,2,3}' and f1 <= '{1,5,3}' +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 233 +select * from arr_tbl where f1 >= '{1,2,3}' and f1 < '{1,5,3}' +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 234 +-- test ON CONFLICT DO UPDATE with arrays +create temp table arr_pk_tbl (pk int4 primary key, f1 int[]) +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DDL +STMT: CreateStmt +== 235 +insert into arr_pk_tbl values (1, '{1,2,3}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 236 +insert into arr_pk_tbl values (1, '{3,4,5}') on conflict (pk) + do update set f1[1] = excluded.f1[1], f1[3] = excluded.f1[3] + returning pk, f1 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 237 +insert into arr_pk_tbl(pk, f1[1:2]) values (1, '{6,7,8}') on conflict (pk) + do update set f1[1] = excluded.f1[1], + f1[2] = excluded.f1[2], + f1[3] = excluded.f1[3] + returning pk, f1 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 238 +-- note: if above selects don't produce the expected tuple order, +-- then you didn't get an indexscan plan, and something is busted. +reset enable_seqscan +-- +STMT: VariableSetStmt +== 239 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 240 +-- test subscript overflow detection + +-- The normal error message includes a platform-dependent limit, +-- so suppress it to avoid needing multiple expected-files. + +insert into arr_pk_tbl values(10, '[-2147483648:-2147483647]={1,2}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 241 +update arr_pk_tbl set f1[2147483647] = 42 where pk = 10 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: UpdateStmt +== 242 +update arr_pk_tbl set f1[2147483646:2147483647] = array[4,2] where pk = 10 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: UpdateStmt +== 243 +insert into arr_pk_tbl(pk, f1[0:2147483647]) values (2, '{}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +insert into arr_pk_tbl(pk, f1[-2147483648:2147483647]) values (2, '{}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +-- also exercise the expanded-array case +do $$ declare a int[]; +begin + a := '[-2147483648:-2147483647]={1,2}'::int[]; + a[2147483647] := 42; +end $$ +-- +STMT: DoStmt +== 246 +-- test [not] (like|ilike) (any|all) (...) +select 'foo' like any (array['%a', '%o']) +-- +STMT: SelectStmt +== 247 +-- t +select 'foo' like any (array['%a', '%b']) +-- +STMT: SelectStmt +== 248 +-- f +select 'foo' like all (array['f%', '%o']) +-- +STMT: SelectStmt +== 249 +-- t +select 'foo' like all (array['f%', '%b']) +-- +STMT: SelectStmt +== 250 +-- f +select 'foo' not like any (array['%a', '%b']) +-- +STMT: SelectStmt +== 251 +-- t +select 'foo' not like all (array['%a', '%o']) +-- +STMT: SelectStmt +== 252 +-- f +select 'foo' ilike any (array['%A', '%O']) +-- +STMT: SelectStmt +== 253 +-- t +select 'foo' ilike all (array['F%', '%O']) +-- +STMT: SelectStmt +== 254 +-- t + +|-- +-- General array parser tests +|-- + +-- none of the following should be accepted +select '{{1,{2}},{2,3}}'::text[] +-- +STMT: SelectStmt +== 255 +select E'{{1,2},\\{2,3}}'::text[] +-- +STMT: SelectStmt +== 256 +select '{"a"b}'::text[] +-- +STMT: SelectStmt +== 257 +select '{a"b"}'::text[] +-- +STMT: SelectStmt +== 258 +select '{"a""b"}'::text[] +-- +STMT: SelectStmt +== 259 +select '{{"1 2" x},{3}}'::text[] +-- +STMT: SelectStmt +== 260 +select '{{"1 2"} x,{3}}'::text[] +-- +STMT: SelectStmt +== 261 +select '{}}'::text[] +-- +STMT: SelectStmt +== 262 +select '{ }}'::text[] +-- +STMT: SelectStmt +== 263 +select '}{'::text[] +-- +STMT: SelectStmt +== 264 +select '{foo{}}'::text[] +-- +STMT: SelectStmt +== 265 +select '{"foo"{}}'::text[] +-- +STMT: SelectStmt +== 266 +select '{foo,,bar}'::text[] +-- +STMT: SelectStmt +== 267 +select '{{1},{{2}}}'::text[] +-- +STMT: SelectStmt +== 268 +select '{{{1}},{2}}'::text[] +-- +STMT: SelectStmt +== 269 +select '{{},{{}}}'::text[] +-- +STMT: SelectStmt +== 270 +select '{{{}},{}}'::text[] +-- +STMT: SelectStmt +== 271 +select '{{1},{}}'::text[] +-- +STMT: SelectStmt +== 272 +select '{{},{1}}'::text[] +-- +STMT: SelectStmt +== 273 +select '[1:0]={}'::int[] +-- +STMT: SelectStmt +== 274 +select '[2147483646:2147483647]={1,2}'::int[] +-- +STMT: SelectStmt +== 275 +select '[1:-1]={}'::int[] +-- +STMT: SelectStmt +== 276 +select '[2]={1}'::int[] +-- +STMT: SelectStmt +== 277 +select '[1:]={1}'::int[] +-- +STMT: SelectStmt +== 278 +select '[:1]={1}'::int[] +-- +STMT: SelectStmt +== 279 +select array[] +-- +STMT: SelectStmt +== 280 +select '{{1,},{1},}'::text[] +-- +STMT: SelectStmt +== 281 +select '{{1,},{1}}'::text[] +-- +STMT: SelectStmt +== 282 +select '{{1,}}'::text[] +-- +STMT: SelectStmt +== 283 +select '{1,}'::text[] +-- +STMT: SelectStmt +== 284 +select '[21474836488:21474836489]={1,2}'::int[] +-- +STMT: SelectStmt +== 285 +select '[-2147483649:-2147483648]={1,2}'::int[] +-- +STMT: SelectStmt +== 286 +-- none of the above should be accepted + +-- all of the following should be accepted +select '{}'::text[] +-- +STMT: SelectStmt +== 287 +select '{{},{}}'::text[] +-- +STMT: SelectStmt +== 288 +select '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[] +-- +STMT: SelectStmt +== 289 +select '{null,n\ull,"null"}'::text[] +-- +STMT: SelectStmt +== 290 +select '{ ab\c , "ab\"c" }'::text[] +-- +STMT: SelectStmt +== 291 +select '{0 second ,0 second}'::interval[] +-- +STMT: SelectStmt +== 292 +select '{ { "," } , { 3 } }'::text[] +-- +STMT: SelectStmt +== 293 +select ' { { " 0 second " , 0 second } }'::text[] +-- +STMT: SelectStmt +== 294 +select '{ + 0 second, + @ 1 hour @ 42 minutes @ 20 seconds + }'::interval[] +-- +STMT: SelectStmt +== 295 +select array[]::text[] +-- +STMT: SelectStmt +== 296 +select '[2]={1,7}'::int[] +-- +STMT: SelectStmt +== 297 +select '[0:1]={1.1,2.2}'::float8[] +-- +STMT: SelectStmt +== 298 +select '[2147483646:2147483646]={1}'::int[] +-- +STMT: SelectStmt +== 299 +select '[-2147483648:-2147483647]={1,2}'::int[] +-- +STMT: SelectStmt +== 300 +-- all of the above should be accepted + +-- tests for array aggregates +CREATE TEMP TABLE arraggtest ( f1 INT[], f2 TEXT[][], f3 FLOAT[]) +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DDL +STMT: CreateStmt +== 301 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{1,2,3,4}','{{grey,red},{blue,blue}}','{1.6, 0.0}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 302 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{1,2,3}','{{grey,red},{grey,blue}}','{1.6}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 303 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 304 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{3,3,2,4,5,6}','{{white,yellow},{pink,orange}}','{2.1,3.3,1.8,1.7,1.6}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 305 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 306 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{2}','{{black,red},{green,orange}}','{1.6,2.2,2.6,0.4}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 307 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 308 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{4,2,6,7,8,1}','{{red},{black},{purple},{blue},{blue}}',NULL) +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 309 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 310 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{}','{{pink,white,blue,red,grey,orange}}','{2.1,1.87,1.4,2.2}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 311 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 312 +-- A few simple tests for arrays of composite types + +create type comptype as (f1 int, f2 text) +-- +STMT: CompositeTypeStmt +== 313 +create table comptable (c1 comptype, c2 comptype[]) +-- +TABLE: name="comptable" schema="" table="comptable" ctx=DDL +STMT: CreateStmt +== 314 +-- XXX would like to not have to specify row() construct types here ... +insert into comptable + values (row(1,'foo'), array[row(2,'bar')::comptype, row(3,'baz')::comptype]) +-- +TABLE: name="comptable" schema="" table="comptable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 315 +-- check that implicitly named array type _comptype isn't a problem +create type _comptype as enum('fooey') +-- +STMT: CreateEnumStmt +== 316 +select * from comptable +-- +TABLE: name="comptable" schema="" table="comptable" ctx=Select +STMT: SelectStmt +== 317 +select c2[2].f2 from comptable +-- +TABLE: name="comptable" schema="" table="comptable" ctx=Select +STMT: SelectStmt +== 318 +drop type _comptype +-- +STMT: DropStmt +== 319 +drop table comptable +-- +TABLE: name="comptable" schema="" table="comptable" ctx=DDL +STMT: DropStmt +== 320 +drop type comptype +-- +STMT: DropStmt +== 321 +create or replace function unnest1(anyarray) +returns setof anyelement as $$ +select $1[s] from generate_subscripts($1,1) g(s); +$$ language sql immutable +-- +FUNCTION: name="unnest1" function="unnest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 322 +create or replace function unnest2(anyarray) +returns setof anyelement as $$ +select $1[s1][s2] from generate_subscripts($1,1) g1(s1), + generate_subscripts($1,2) g2(s2); +$$ language sql immutable +-- +FUNCTION: name="unnest2" function="unnest2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 323 +select * from unnest1(array[1,2,3]) +-- +FUNCTION: name="unnest1" function="unnest1" schema="" ctx=Call +STMT: SelectStmt +== 324 +select * from unnest2(array[[1,2,3],[4,5,6]]) +-- +FUNCTION: name="unnest2" function="unnest2" schema="" ctx=Call +STMT: SelectStmt +== 325 +drop function unnest1(anyarray) +-- +FUNCTION: name="unnest1" function="unnest1" schema="" ctx=DDL +STMT: DropStmt +== 326 +drop function unnest2(anyarray) +-- +FUNCTION: name="unnest2" function="unnest2" schema="" ctx=DDL +STMT: DropStmt +== 327 +select array_fill(null::integer, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 328 +select array_fill(null::integer, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 329 +select array_fill(null::text, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 330 +select array_fill(null::text, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 331 +select array_fill(7, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 332 +select array_fill(7, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 333 +select array_fill('juhu'::text, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 334 +select array_fill('juhu'::text, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 335 +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, array[0]) as a) ss +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 336 +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, '{}') as a) ss +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 337 +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, '{}', '{}') as a) ss +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 338 +-- raise exception +select array_fill(1, null, array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 339 +select array_fill(1, array[2,2], null) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 340 +select array_fill(1, array[2,2], '{}') +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 341 +select array_fill(1, array[3,3], array[1,1,1]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 342 +select array_fill(1, array[1,2,null]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 343 +select array_fill(1, array[[1,2],[3,4]]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +== 344 +select string_to_array('1|2|3', '|') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 345 +select string_to_array('1|2|3|', '|') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 346 +select string_to_array('1||2|3||', '||') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 347 +select string_to_array('1|2|3', '') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 348 +select string_to_array('', '|') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 349 +select string_to_array('1|2|3', NULL) +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 350 +select string_to_array(NULL, '|') IS NULL +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 351 +select string_to_array('abc', '') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 352 +select string_to_array('abc', '', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 353 +select string_to_array('abc', ',') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 354 +select string_to_array('abc', ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 355 +select string_to_array('1,2,3,4,,6', ',') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 356 +select string_to_array('1,2,3,4,,6', ',', '') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 357 +select string_to_array('1,2,3,4,*,6', ',', '*') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 358 +select v, v is null as "is null" from string_to_table('1|2|3', '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 359 +select v, v is null as "is null" from string_to_table('1|2|3|', '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 360 +select v, v is null as "is null" from string_to_table('1||2|3||', '||') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 361 +select v, v is null as "is null" from string_to_table('1|2|3', '') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 362 +select v, v is null as "is null" from string_to_table('', '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 363 +select v, v is null as "is null" from string_to_table('1|2|3', NULL) g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 364 +select v, v is null as "is null" from string_to_table(NULL, '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 365 +select v, v is null as "is null" from string_to_table('abc', '') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 366 +select v, v is null as "is null" from string_to_table('abc', '', 'abc') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 367 +select v, v is null as "is null" from string_to_table('abc', ',') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 368 +select v, v is null as "is null" from string_to_table('abc', ',', 'abc') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 369 +select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 370 +select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',', '') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 371 +select v, v is null as "is null" from string_to_table('1,2,3,4,*,6', ',', '*') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +== 372 +select array_to_string(NULL::int4[], ',') IS NULL +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +== 373 +select array_to_string('{}'::int4[], ',') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +== 374 +select array_to_string(array[1,2,3,4,NULL,6], ',') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +== 375 +select array_to_string(array[1,2,3,4,NULL,6], ',', '*') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +== 376 +select array_to_string(array[1,2,3,4,NULL,6], NULL) +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +== 377 +select array_to_string(array[1,2,3,4,NULL,6], ',', NULL) +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +== 378 +select array_to_string(string_to_array('1|2|3', '|'), '|') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 379 +select array_length(array[1,2,3], 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +== 380 +select array_length(array[[1,2,3], [4,5,6]], 0) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +== 381 +select array_length(array[[1,2,3], [4,5,6]], 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +== 382 +select array_length(array[[1,2,3], [4,5,6]], 2) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +== 383 +select array_length(array[[1,2,3], [4,5,6]], 3) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +== 384 +select cardinality(NULL::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +== 385 +select cardinality('{}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +== 386 +select cardinality(array[1,2,3]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +== 387 +select cardinality('[2:4]={5,6,7}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +== 388 +select cardinality('{{1,2}}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +== 389 +select cardinality('{{1,2},{3,4},{5,6}}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +== 390 +select cardinality('{{{1,9},{5,6}},{{2,3},{3,4}}}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +== 391 +-- array_agg(anynonarray) +select array_agg(unique1) from (select unique1 from tenk1 where unique1 < 15 order by unique1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 392 +select array_agg(ten) from (select ten from tenk1 where unique1 < 15 order by unique1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 393 +select array_agg(nullif(ten, 4)) from (select ten from tenk1 where unique1 < 15 order by unique1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 394 +select array_agg(unique1) from tenk1 where unique1 < -15 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 395 +-- array_agg(anyarray) +select array_agg(ar) + from (values ('{1,2}'::int[]), ('{3,4}'::int[])) v(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 396 +select array_agg(distinct ar order by ar desc) + from (select array[i / 2] from generate_series(1,10) a(i)) b(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 397 +select array_agg(ar) + from (select array_agg(array[i, i+1, i-1]) + from generate_series(1,2) a(i)) b(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 398 +select array_agg(array[i+1.2, i+1.3, i+1.4]) from generate_series(1,3) g(i) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 399 +select array_agg(array['Hello', i::text]) from generate_series(9,11) g(i) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 400 +select array_agg(array[i, nullif(i, 3), i+1]) from generate_series(1,4) g(i) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 401 +-- errors +select array_agg('{}'::int[]) from generate_series(1,2) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 402 +select array_agg(null::int[]) from generate_series(1,2) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 403 +select array_agg(ar) + from (values ('{1,2}'::int[]), ('{3}'::int[])) v(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 404 +select unnest(array[1,2,3]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 405 +select * from unnest(array[1,2,3]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 406 +select unnest(array[1,2,3,4.5]::float8[]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 407 +select unnest(array[1,2,3,4.5]::numeric[]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 408 +select unnest(array[1,2,3,null,4,null,null,5,6]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 409 +select unnest(array[1,2,3,null,4,null,null,5,6]::text[]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 410 +select abs(unnest(array[1,2,null,-3])) +-- +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 411 +select array_remove(array[1,2,2,3], 2) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +== 412 +select array_remove(array[1,2,2,3], 5) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +== 413 +select array_remove(array[1,NULL,NULL,3], NULL) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +== 414 +select array_remove(array['A','CC','D','C','RR'], 'RR') +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +== 415 +select array_remove(array[1.0, 2.1, 3.3], 1) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +== 416 +select array_remove('{{1,2,2},{1,4,3}}', 2) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +== 417 +-- not allowed +select array_remove(array['X','X','X'], 'X') = '{}' +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +== 418 +select array_replace(array[1,2,5,4],5,3) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +== 419 +select array_replace(array[1,2,5,4],5,NULL) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +== 420 +select array_replace(array[1,2,NULL,4,NULL],NULL,5) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +== 421 +select array_replace(array['A','B','DD','B'],'B','CC') +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +== 422 +select array_replace(array[1,NULL,3],NULL,NULL) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +== 423 +select array_replace(array['AB',NULL,'CDE'],NULL,'12') +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +== 424 +-- array(select array-value ...) +select array(select array[i,i/2] from generate_series(1,5) i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 425 +select array(select array['Hello', i::text] from generate_series(9,11) i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 426 +-- int2vector and oidvector should be treated as scalar types for this purpose +select pg_typeof(array(select '11 22 33'::int2vector from generate_series(1,5))) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 427 +select array(select '11 22 33'::int2vector from generate_series(1,5)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 428 +select unnest(array(select '11 22 33'::int2vector from generate_series(1,5))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 429 +select pg_typeof(array(select '11 22 33'::oidvector from generate_series(1,5))) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 430 +select array(select '11 22 33'::oidvector from generate_series(1,5)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 431 +select unnest(array(select '11 22 33'::oidvector from generate_series(1,5))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 432 +-- array[] should do the same +select pg_typeof(array['11 22 33'::int2vector]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 433 +select array['11 22 33'::int2vector] +-- +STMT: SelectStmt +== 434 +select pg_typeof(unnest(array['11 22 33'::int2vector])) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 435 +select unnest(array['11 22 33'::int2vector]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 436 +select pg_typeof(unnest('11 22 33'::int2vector)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 437 +select unnest('11 22 33'::int2vector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 438 +select pg_typeof(array['11 22 33'::oidvector]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 439 +select array['11 22 33'::oidvector] +-- +STMT: SelectStmt +== 440 +select pg_typeof(unnest(array['11 22 33'::oidvector])) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 441 +select unnest(array['11 22 33'::oidvector]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 442 +select pg_typeof(unnest('11 22 33'::oidvector)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 443 +select unnest('11 22 33'::oidvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 444 +-- Insert/update on a column that is array of composite + +create temp table t1 (f1 int8_tbl[]) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 445 +insert into t1 (f1[5].q1) values(42) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 446 +select * from t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 447 +update t1 set f1[5].q2 = 43 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: UpdateStmt +== 448 +select * from t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 449 +-- Check that arrays of composites are safely detoasted when needed + +create temp table src (f1 text) +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: CreateStmt +== 450 +insert into src + select string_agg(random()::text,'') from generate_series(1,10000) +-- +TABLE: name="src" schema="" table="src" ctx=DML +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 451 +create type textandtext as (c1 text, c2 text) +-- +STMT: CompositeTypeStmt +== 452 +create temp table dest (f1 textandtext[]) +-- +TABLE: name="dest" schema="" table="dest" ctx=DDL +STMT: CreateStmt +== 453 +insert into dest select array[row(f1,f1)::textandtext] from src +-- +TABLE: name="dest" schema="" table="dest" ctx=DML +TABLE: name="src" schema="" table="src" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 454 +select length(fipshash((f1[1]).c2)) from dest +-- +TABLE: name="dest" schema="" table="dest" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: SelectStmt +== 455 +delete from src +-- +TABLE: name="src" schema="" table="src" ctx=DML +STMT: DeleteStmt +== 456 +select length(fipshash((f1[1]).c2)) from dest +-- +TABLE: name="dest" schema="" table="dest" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: SelectStmt +== 457 +truncate table src +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: TruncateStmt +== 458 +drop table src +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: DropStmt +== 459 +select length(fipshash((f1[1]).c2)) from dest +-- +TABLE: name="dest" schema="" table="dest" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: SelectStmt +== 460 +drop table dest +-- +TABLE: name="dest" schema="" table="dest" ctx=DDL +STMT: DropStmt +== 461 +drop type textandtext +-- +STMT: DropStmt +== 462 +-- Tests for polymorphic-array form of width_bucket() + +-- this exercises the varwidth and float8 code paths +SELECT + op, + width_bucket(op::numeric, ARRAY[1, 3, 5, 10.0]::numeric[]) AS wb_n1, + width_bucket(op::numeric, ARRAY[0, 5.5, 9.99]::numeric[]) AS wb_n2, + width_bucket(op::numeric, ARRAY[-6, -5, 2.0]::numeric[]) AS wb_n3, + width_bucket(op::float8, ARRAY[1, 3, 5, 10.0]::float8[]) AS wb_f1, + width_bucket(op::float8, ARRAY[0, 5.5, 9.99]::float8[]) AS wb_f2, + width_bucket(op::float8, ARRAY[-6, -5, 2.0]::float8[]) AS wb_f3 +FROM (VALUES + (-5.2), + (-0.0000000001), + (0.000000000001), + (1), + (1.99999999999999), + (2), + (2.00000000000001), + (3), + (4), + (4.5), + (5), + (5.5), + (6), + (7), + (8), + (9), + (9.99999999999999), + (10), + (10.0000000000001) +) v(op) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 463 +-- ensure float8 path handles NaN properly +SELECT + op, + width_bucket(op, ARRAY[1, 3, 9, 'NaN', 'NaN']::float8[]) AS wb +FROM (VALUES + (-5.2::float8), + (4::float8), + (77::float8), + ('NaN'::float8) +) v(op) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 464 +-- these exercise the generic fixed-width code path +SELECT + op, + width_bucket(op, ARRAY[1, 3, 5, 10]) AS wb_1 +FROM generate_series(0,11) as op +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 465 +SELECT width_bucket(now(), + array['yesterday', 'today', 'tomorrow']::timestamptz[]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 466 +-- corner cases +SELECT width_bucket(5, ARRAY[3]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 467 +SELECT width_bucket(5, '{}') +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 468 +-- error cases +SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 469 +SELECT width_bucket(5, ARRAY[3, 4, NULL]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 470 +SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 471 +-- trim_array + +SELECT arr, trim_array(arr, 2) +FROM +(VALUES ('{1,2,3,4,5,6}'::bigint[]), + ('{1,2}'), + ('[10:16]={1,2,3,4,5,6,7}'), + ('[-15:-10]={1,2,3,4,5,6}'), + ('{{1,10},{2,20},{3,30},{4,40}}')) v(arr) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +== 472 +SELECT trim_array(ARRAY[1, 2, 3], -1) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +== 473 +-- fail +SELECT trim_array(ARRAY[1, 2, 3], 10) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +== 474 +-- fail +SELECT trim_array(ARRAY[]::int[], 1) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +== 475 +-- fail + +-- array_shuffle +SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) <@ '{1,2,3,4,5,6}' +-- +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +== 476 +SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) @> '{1,2,3,4,5,6}' +-- +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +== 477 +SELECT array_dims(array_shuffle('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[])) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +== 478 +SELECT array_dims(array_shuffle('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[])) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +== 479 +-- array_sample +SELECT array_sample('{1,2,3,4,5,6}'::int[], 3) <@ '{1,2,3,4,5,6}' +-- +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +== 480 +SELECT array_length(array_sample('{1,2,3,4,5,6}'::int[], 3), 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +== 481 +SELECT array_dims(array_sample('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[], 3)) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +== 482 +SELECT array_dims(array_sample('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[], 2)) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +== 483 +SELECT array_sample('{1,2,3,4,5,6}'::int[], -1) +-- +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +== 484 +-- fail +SELECT array_sample('{1,2,3,4,5,6}'::int[], 7) +-- +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/async.metadata.json b/parser/testdata/summary/postgres_regress/async.metadata.json new file mode 100644 index 0000000..4739b17 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/async.metadata.json @@ -0,0 +1,15 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011" + ] +} diff --git a/parser/testdata/summary/postgres_regress/async.test b/parser/testdata/summary/postgres_regress/async.test new file mode 100644 index 0000000..b7cb31d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/async.test @@ -0,0 +1,60 @@ +== 001 +|-- +-- ASYNC +|-- + +--Should work. Send a valid message via a valid channel name +SELECT pg_notify('notify_async1','sample message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +== 002 +SELECT pg_notify('notify_async1','') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +== 003 +SELECT pg_notify('notify_async1',NULL) +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +== 004 +-- Should fail. Send a valid message via an invalid channel name +SELECT pg_notify('','sample message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT pg_notify(NULL,'sample message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT pg_notify('notify_async_channel_name_too_long______________________________','sample_message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +== 007 +--Should work. Valid NOTIFY/LISTEN/UNLISTEN commands +NOTIFY notify_async2 +-- +STMT: NotifyStmt +== 008 +LISTEN notify_async2 +-- +STMT: ListenStmt +== 009 +UNLISTEN notify_async2 +-- +STMT: UnlistenStmt +== 010 +UNLISTEN * +-- +STMT: UnlistenStmt +== 011 +-- Should return zero while there are no pending notifications. +-- src/test/isolation/specs/async-notify.spec tests for actual usage. +SELECT pg_notification_queue_usage() +-- +FUNCTION: name="pg_notification_queue_usage" function="pg_notification_queue_usage" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/bit.metadata.json b/parser/testdata/summary/postgres_regress/bit.metadata.json new file mode 100644 index 0000000..0b25d44 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/bit.metadata.json @@ -0,0 +1,136 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132" + ] +} diff --git a/parser/testdata/summary/postgres_regress/bit.test b/parser/testdata/summary/postgres_regress/bit.test new file mode 100644 index 0000000..b14f4da --- /dev/null +++ b/parser/testdata/summary/postgres_regress/bit.test @@ -0,0 +1,813 @@ +== 001 +|-- +-- BIT types +|-- + +|-- +-- Build tables for testing +|-- + +CREATE TABLE BIT_TABLE(b BIT(11)) +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO BIT_TABLE VALUES (B'10') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +-- too short +INSERT INTO BIT_TABLE VALUES (B'00000000000') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO BIT_TABLE VALUES (B'11011000000') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO BIT_TABLE VALUES (B'01010101010') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO BIT_TABLE VALUES (B'101011111010') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- too long +--INSERT INTO BIT_TABLE VALUES ('X554'); +--INSERT INTO BIT_TABLE VALUES ('X555'); + +SELECT * FROM BIT_TABLE +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +== 008 +CREATE TABLE VARBIT_TABLE(v BIT VARYING(11)) +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: CreateStmt +== 009 +INSERT INTO VARBIT_TABLE VALUES (B'') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO VARBIT_TABLE VALUES (B'0') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO VARBIT_TABLE VALUES (B'010101') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO VARBIT_TABLE VALUES (B'01010101010') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO VARBIT_TABLE VALUES (B'101011111010') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +-- too long +--INSERT INTO VARBIT_TABLE VALUES ('X554'); +--INSERT INTO VARBIT_TABLE VALUES ('X555'); +SELECT * FROM VARBIT_TABLE +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +== 015 +-- Literals with syntax errors +SELECT b' 0' +-- +STMT: SelectStmt +== 016 +SELECT b'0 ' +-- +STMT: SelectStmt +== 017 +SELECT x' 0' +-- +STMT: SelectStmt +== 018 +SELECT x'0 ' +-- +STMT: SelectStmt +== 019 +-- Concatenation +SELECT v, b, (v || b) AS concat + FROM BIT_TABLE, VARBIT_TABLE + ORDER BY 3 +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +== 020 +-- Length +SELECT b, length(b) AS lb + FROM BIT_TABLE +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT v, length(v) AS lv + FROM VARBIT_TABLE +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- 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 +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 023 +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 +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 024 +-- test overflow cases +SELECT SUBSTRING('01010101'::bit(8) FROM 2 FOR 2147483646) AS "1010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 025 +SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR 2147483646) AS "01010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 026 +SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR -2147483646) AS "error" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 027 +SELECT SUBSTRING('01010101'::varbit FROM 2 FOR 2147483646) AS "1010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 028 +SELECT SUBSTRING('01010101'::varbit FROM -10 FOR 2147483646) AS "01010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 029 +SELECT SUBSTRING('01010101'::varbit FROM -10 FOR -2147483646) AS "error" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 030 +--- Bit operations +DROP TABLE varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: DropStmt +== 031 +CREATE TABLE varbit_table (a BIT VARYING(16), b BIT VARYING(16)) +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: CreateStmt +== 032 +COPY varbit_table FROM stdin +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: CopyStmt +== 033 +SELECT a, b, ~a AS "~ a", a & b AS "a & b", + a | b AS "a | b", a # b AS "a # b" FROM varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +== 034 +SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +== 035 +SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +== 036 +DROP TABLE varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: DropStmt +== 037 +--- Bit operations +DROP TABLE bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: DropStmt +== 038 +CREATE TABLE bit_table (a BIT(16), b BIT(16)) +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: CreateStmt +== 039 +COPY bit_table FROM stdin +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: CopyStmt +== 040 +SELECT a,b,~a AS "~ a",a & b AS "a & b", + a|b AS "a | b", a # b AS "a # b" FROM bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +== 041 +SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +== 042 +SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +== 043 +DROP TABLE bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: DropStmt +== 044 +-- The following should fail +select B'001' & B'10' +-- +STMT: SelectStmt +== 045 +select B'0111' | B'011' +-- +STMT: SelectStmt +== 046 +select B'0010' # B'011101' +-- +STMT: SelectStmt +== 047 +-- More position tests, checking all the boundary cases +SELECT POSITION(B'1010' IN B'0000101') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 048 +-- 0 +SELECT POSITION(B'1010' IN B'00001010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 049 +-- 5 +SELECT POSITION(B'1010' IN B'00000101') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 050 +-- 0 +SELECT POSITION(B'1010' IN B'000001010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 051 +-- 6 + +SELECT POSITION(B'' IN B'00001010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 052 +-- 1 +SELECT POSITION(B'0' IN B'') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 053 +-- 0 +SELECT POSITION(B'' IN B'') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 054 +-- 0 +SELECT POSITION(B'101101' IN B'001011011011011000') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 055 +-- 3 +SELECT POSITION(B'10110110' IN B'001011011011010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 056 +-- 3 +SELECT POSITION(B'1011011011011' IN B'001011011011011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 057 +-- 3 +SELECT POSITION(B'1011011011011' IN B'00001011011011011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 058 +-- 5 + +SELECT POSITION(B'11101011' IN B'11101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 059 +-- 1 +SELECT POSITION(B'11101011' IN B'011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 060 +-- 2 +SELECT POSITION(B'11101011' IN B'00011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 061 +-- 4 +SELECT POSITION(B'11101011' IN B'0000011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 062 +-- 6 + +SELECT POSITION(B'111010110' IN B'111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 063 +-- 1 +SELECT POSITION(B'111010110' IN B'0111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 064 +-- 2 +SELECT POSITION(B'111010110' IN B'000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 065 +-- 4 +SELECT POSITION(B'111010110' IN B'00000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 066 +-- 6 + +SELECT POSITION(B'111010110' IN B'11101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 067 +-- 0 +SELECT POSITION(B'111010110' IN B'011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 068 +-- 0 +SELECT POSITION(B'111010110' IN B'00011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 069 +-- 0 +SELECT POSITION(B'111010110' IN B'0000011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 070 +-- 0 + +SELECT POSITION(B'111010110' IN B'111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 071 +-- 1 +SELECT POSITION(B'111010110' IN B'0111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 072 +-- 2 +SELECT POSITION(B'111010110' IN B'000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 073 +-- 4 +SELECT POSITION(B'111010110' IN B'00000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 074 +-- 6 + +SELECT POSITION(B'111010110' IN B'000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 075 +-- 0 +SELECT POSITION(B'111010110' IN B'0000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 076 +-- 0 +SELECT POSITION(B'111010110' IN B'000000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 077 +-- 0 +SELECT POSITION(B'111010110' IN B'00000000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 078 +-- 0 + +SELECT POSITION(B'111010110' IN B'0000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 079 +-- 14 +SELECT POSITION(B'111010110' IN B'00000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 080 +-- 15 +SELECT POSITION(B'111010110' IN B'0000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 081 +-- 17 +SELECT POSITION(B'111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 082 +-- 19 + +SELECT POSITION(B'000000000011101011111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 083 +-- 1 +SELECT POSITION(B'00000000011101011111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 084 +-- 2 +SELECT POSITION(B'0000000000011101011111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 085 +-- 0 + + +-- Shifting + +CREATE TABLE BIT_SHIFT_TABLE(b BIT(16)) +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DDL +STMT: CreateStmt +== 086 +INSERT INTO BIT_SHIFT_TABLE VALUES (B'1101100000000000') +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>1 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 088 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>2 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 089 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>4 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 090 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>8 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 091 +SELECT POSITION(B'1101' IN b), + POSITION(B'11011' IN b), + b + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 092 +SELECT b, b >> 1 AS bsr, b << 1 AS bsl + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +== 093 +SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8 + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +== 094 +SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +== 095 +SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8 + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +== 096 +CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20)) +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DDL +STMT: CreateStmt +== 097 +INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011') +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0' AS BIT VARYING(6)) >>1 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 099 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00' AS BIT VARYING(8)) >>2 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 100 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0000' AS BIT VARYING(12)) >>4 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 101 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00000000' AS BIT VARYING(20)) >>8 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 102 +SELECT POSITION(B'1101' IN v), + POSITION(B'11011' IN v), + v + FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 103 +SELECT v, v >> 1 AS vsr, v << 1 AS vsl + FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: SelectStmt +== 104 +SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8 + FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: SelectStmt +== 105 +DROP TABLE BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DDL +STMT: DropStmt +== 106 +DROP TABLE VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DDL +STMT: DropStmt +== 107 +-- Get/Set bit +SELECT get_bit(B'0101011000100', 10) +-- +FUNCTION: name="get_bit" function="get_bit" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT set_bit(B'0101011000100100', 15, 1) +-- +FUNCTION: name="set_bit" function="set_bit" schema="" ctx=Call +STMT: SelectStmt +== 109 +SELECT set_bit(B'0101011000100100', 16, 1) +-- +FUNCTION: name="set_bit" function="set_bit" schema="" ctx=Call +STMT: SelectStmt +== 110 +-- fail + +-- Overlay +SELECT overlay(B'0101011100' placing '001' from 2 for 3) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 111 +SELECT overlay(B'0101011100' placing '101' from 6) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 112 +SELECT overlay(B'0101011100' placing '001' from 11) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 113 +SELECT overlay(B'0101011100' placing '001' from 20) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 114 +-- bit_count +SELECT bit_count(B'0101011100'::bit(10)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +STMT: SelectStmt +== 115 +SELECT bit_count(B'1111111111'::bit(10)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +STMT: SelectStmt +== 116 +SELECT bit_count(repeat('0', 100)::bit(100)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 117 +SELECT bit_count(repeat('1', 100)::bit(100)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 118 +SELECT bit_count(repeat('01', 500)::bit(1000)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 119 +SELECT bit_count(repeat('10101', 200)::bit(1000)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 120 +-- 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' +) +-- +TABLE: name="bit_defaults" schema="" table="bit_defaults" ctx=DDL +STMT: CreateStmt +== 121 +INSERT INTO bit_defaults DEFAULT VALUES +-- +TABLE: name="bit_defaults" schema="" table="bit_defaults" ctx=DML +STMT: InsertStmt +== 122 +TABLE bit_defaults +-- +TABLE: name="bit_defaults" schema="" table="bit_defaults" ctx=Select +STMT: SelectStmt +== 123 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('01010001', 'bit(10)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 124 +SELECT * FROM pg_input_error_info('01010001', 'bit(10)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 125 +SELECT pg_input_is_valid('01010Z01', 'bit(8)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 126 +SELECT * FROM pg_input_error_info('01010Z01', 'bit(8)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 127 +SELECT pg_input_is_valid('x01010Z01', 'bit(32)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 128 +SELECT * FROM pg_input_error_info('x01010Z01', 'bit(32)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 129 +SELECT pg_input_is_valid('01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 130 +SELECT * FROM pg_input_error_info('01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 131 +SELECT pg_input_is_valid('x01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 132 +SELECT * FROM pg_input_error_info('x01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/bitmapops.metadata.json b/parser/testdata/summary/postgres_regress/bitmapops.metadata.json new file mode 100644 index 0000000..92b8f9e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/bitmapops.metadata.json @@ -0,0 +1,14 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010" + ] +} diff --git a/parser/testdata/summary/postgres_regress/bitmapops.test b/parser/testdata/summary/postgres_regress/bitmapops.test new file mode 100644 index 0000000..45dc777 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/bitmapops.test @@ -0,0 +1,77 @@ +== 001 +-- Test bitmap AND and OR + + +-- Generate enough data that we can test the lossy bitmaps. + +-- There's 55 tuples per page in the table. 53 is just +-- below 55, so that an index scan with qual a = constant +-- will return at least one hit per page. 59 is just above +-- 55, so that an index scan with qual b = constant will return +-- hits on most but not all pages. 53 and 59 are prime, so that +-- there's a maximum number of a,b combinations in the table. +-- That allows us to test all the different combinations of +-- lossy and non-lossy pages with the minimum amount of data + +CREATE TABLE bmscantest (a int, b int, t text) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO bmscantest + SELECT (r%53), (r%59), 'foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' + FROM generate_series(1,70000) r +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +CREATE INDEX i_bmtest_a ON bmscantest(a) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: IndexStmt +== 004 +CREATE INDEX i_bmtest_b ON bmscantest(b) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: IndexStmt +== 005 +-- We want to use bitmapscans. With default settings, the planner currently +-- chooses a bitmap scan for the queries below anyway, but let's make sure. +set enable_indexscan=false +-- +STMT: VariableSetStmt +== 006 +set enable_seqscan=false +-- +STMT: VariableSetStmt +== 007 +-- Lower work_mem to trigger use of lossy bitmaps +set work_mem = 64 +-- +STMT: VariableSetStmt +== 008 +-- Test bitmap-and. +SELECT count(*) FROM bmscantest WHERE a = 1 AND b = 1 +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 009 +-- Test bitmap-or. +SELECT count(*) FROM bmscantest WHERE a = 1 OR b = 1 +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 010 +-- clean up +DROP TABLE bmscantest +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/boolean.metadata.json b/parser/testdata/summary/postgres_regress/boolean.metadata.json new file mode 100644 index 0000000..463f4d4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/boolean.metadata.json @@ -0,0 +1,102 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098" + ] +} diff --git a/parser/testdata/summary/postgres_regress/boolean.test b/parser/testdata/summary/postgres_regress/boolean.test new file mode 100644 index 0000000..75cf072 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/boolean.test @@ -0,0 +1,579 @@ +== 001 +|-- +-- BOOLEAN +|-- + +|-- +-- sanity check - if this fails go insane! +|-- +SELECT 1 AS one +-- +STMT: SelectStmt +== 002 +-- ******************testing built-in type bool******************** + +-- check bool input syntax + +SELECT true AS true +-- +STMT: SelectStmt +== 003 +SELECT false AS false +-- +STMT: SelectStmt +== 004 +SELECT bool 't' AS true +-- +STMT: SelectStmt +== 005 +SELECT bool ' f ' AS false +-- +STMT: SelectStmt +== 006 +SELECT bool 'true' AS true +-- +STMT: SelectStmt +== 007 +SELECT bool 'test' AS error +-- +STMT: SelectStmt +== 008 +SELECT bool 'false' AS false +-- +STMT: SelectStmt +== 009 +SELECT bool 'foo' AS error +-- +STMT: SelectStmt +== 010 +SELECT bool 'y' AS true +-- +STMT: SelectStmt +== 011 +SELECT bool 'yes' AS true +-- +STMT: SelectStmt +== 012 +SELECT bool 'yeah' AS error +-- +STMT: SelectStmt +== 013 +SELECT bool 'n' AS false +-- +STMT: SelectStmt +== 014 +SELECT bool 'no' AS false +-- +STMT: SelectStmt +== 015 +SELECT bool 'nay' AS error +-- +STMT: SelectStmt +== 016 +SELECT bool 'on' AS true +-- +STMT: SelectStmt +== 017 +SELECT bool 'off' AS false +-- +STMT: SelectStmt +== 018 +SELECT bool 'of' AS false +-- +STMT: SelectStmt +== 019 +SELECT bool 'o' AS error +-- +STMT: SelectStmt +== 020 +SELECT bool 'on_' AS error +-- +STMT: SelectStmt +== 021 +SELECT bool 'off_' AS error +-- +STMT: SelectStmt +== 022 +SELECT bool '1' AS true +-- +STMT: SelectStmt +== 023 +SELECT bool '11' AS error +-- +STMT: SelectStmt +== 024 +SELECT bool '0' AS false +-- +STMT: SelectStmt +== 025 +SELECT bool '000' AS error +-- +STMT: SelectStmt +== 026 +SELECT bool '' AS error +-- +STMT: SelectStmt +== 027 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('true', 'bool') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT pg_input_is_valid('asdf', 'bool') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT * FROM pg_input_error_info('junk', 'bool') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 030 +-- and, or, not in qualifications + +SELECT bool 't' or bool 'f' AS true +-- +STMT: SelectStmt +== 031 +SELECT bool 't' and bool 'f' AS false +-- +STMT: SelectStmt +== 032 +SELECT not bool 'f' AS true +-- +STMT: SelectStmt +== 033 +SELECT bool 't' = bool 'f' AS false +-- +STMT: SelectStmt +== 034 +SELECT bool 't' <> bool 'f' AS true +-- +STMT: SelectStmt +== 035 +SELECT bool 't' > bool 'f' AS true +-- +STMT: SelectStmt +== 036 +SELECT bool 't' >= bool 'f' AS true +-- +STMT: SelectStmt +== 037 +SELECT bool 'f' < bool 't' AS true +-- +STMT: SelectStmt +== 038 +SELECT bool 'f' <= bool 't' AS true +-- +STMT: SelectStmt +== 039 +-- explicit casts to/from text +SELECT 'TrUe'::text::boolean AS true, 'fAlse'::text::boolean AS false +-- +STMT: SelectStmt +== 040 +SELECT ' true '::text::boolean AS true, + ' FALSE'::text::boolean AS false +-- +STMT: SelectStmt +== 041 +SELECT true::boolean::text AS true, false::boolean::text AS false +-- +STMT: SelectStmt +== 042 +SELECT ' tru e '::text::boolean AS invalid +-- +STMT: SelectStmt +== 043 +-- error +SELECT ''::text::boolean AS invalid +-- +STMT: SelectStmt +== 044 +-- error + +CREATE TABLE BOOLTBL1 (f1 bool) +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DDL +STMT: CreateStmt +== 045 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 't') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'True') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'true') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +-- BOOLTBL1 should be full of true's at this point +SELECT BOOLTBL1.* FROM BOOLTBL1 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +STMT: SelectStmt +== 049 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 = bool 'true' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 050 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 <> bool 'false' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 051 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE booleq(bool 'false', f1) +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FUNCTION: name="booleq" function="booleq" schema="" ctx=Call +FUNCTION: name="booleq" function="booleq" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 052 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'f') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 = bool 'false' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 054 +CREATE TABLE BOOLTBL2 (f1 bool) +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DDL +STMT: CreateStmt +== 055 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'f') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'false') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'False') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'FALSE') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +-- This is now an invalid expression +-- For pre-v6.3 this evaluated to false - thomas 1997-10-23 +INSERT INTO BOOLTBL2 (f1) + VALUES (bool 'XXX') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +-- BOOLTBL2 should be full of false's at this point +SELECT BOOLTBL2.* FROM BOOLTBL2 +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +STMT: SelectStmt +== 061 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 <> BOOLTBL1.f1 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +== 062 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE boolne(BOOLTBL2.f1,BOOLTBL1.f1) +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FUNCTION: name="boolne" function="boolne" schema="" ctx=Call +FUNCTION: name="boolne" function="boolne" schema="" ctx=Call +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +== 063 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 = BOOLTBL1.f1 and BOOLTBL1.f1 = bool 'false' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +== 064 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 = BOOLTBL1.f1 or BOOLTBL1.f1 = bool 'true' + ORDER BY BOOLTBL1.f1, BOOLTBL2.f1 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +== 065 +|-- +-- SQL syntax +-- Try all combinations to ensure that we get nothing when we expect nothing +-- - thomas 2000-01-04 +|-- + +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS TRUE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 066 +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS NOT FALSE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 067 +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS FALSE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 068 +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS NOT TRUE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 069 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS TRUE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 070 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS NOT FALSE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 071 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS FALSE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 072 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS NOT TRUE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 073 +|-- +-- Tests for BooleanTest +|-- +CREATE TABLE BOOLTBL3 (d text, b bool, o int) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DDL +STMT: CreateStmt +== 074 +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('true', true, 1) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('false', false, 2) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('null', null, 3) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +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 +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=Select +STMT: SelectStmt +== 078 +-- Test to make sure short-circuiting and NULL handling is +-- correct. Use a table as source to prevent constant simplification +-- from interfering. +CREATE TABLE booltbl4(isfalse bool, istrue bool, isnul bool) +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=DDL +STMT: CreateStmt +== 079 +INSERT INTO booltbl4 VALUES (false, true, null) +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +-- 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 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 081 +SELECT istrue AND istrue AND isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 082 +SELECT isnul AND istrue AND istrue FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 083 +SELECT isfalse AND isnul AND istrue FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 084 +SELECT istrue AND isfalse AND isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 085 +SELECT isnul AND istrue AND isfalse FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 086 +-- 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 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 087 +SELECT isfalse OR isfalse OR isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 088 +SELECT isnul OR isfalse OR isfalse FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 089 +SELECT isfalse OR isnul OR istrue FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 090 +SELECT istrue OR isfalse OR isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 091 +SELECT isnul OR istrue OR isfalse FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +== 092 +-- Casts +SELECT 0::boolean +-- +STMT: SelectStmt +== 093 +SELECT 1::boolean +-- +STMT: SelectStmt +== 094 +SELECT 2::boolean +-- +STMT: SelectStmt +== 095 +|-- +-- 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 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DDL +STMT: DropStmt +== 096 +DROP TABLE BOOLTBL2 +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DDL +STMT: DropStmt +== 097 +DROP TABLE BOOLTBL3 +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DDL +STMT: DropStmt +== 098 +DROP TABLE BOOLTBL4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/box.metadata.json b/parser/testdata/summary/postgres_regress/box.metadata.json new file mode 100644 index 0000000..8b15b4c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/box.metadata.json @@ -0,0 +1,105 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101" + ] +} diff --git a/parser/testdata/summary/postgres_regress/box.test b/parser/testdata/summary/postgres_regress/box.test new file mode 100644 index 0000000..b35f833 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/box.test @@ -0,0 +1,764 @@ +== 001 +|-- +-- BOX +|-- + +|-- +-- box logic +-- o +-- 3 o--|X +-- | o| +-- 2 +-+-+ | +-- | | | | +-- 1 | o-+-o +-- | | +-- 0 +---+ +|-- +-- 0 1 2 3 +|-- + +-- boxes are specified by two points, given by four floats x1,y1,x2,y2 + + +CREATE TABLE BOX_TBL (f1 box) +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO BOX_TBL (f1) VALUES ('((-8, 2), (-2, -10))') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +-- degenerate cases where the box is a line or a point +-- note that lines and points boxes all have zero area +INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO BOX_TBL (f1) VALUES ('(3.0, 3.0,3.0,3.0)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- badly formatted box inputs +INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +SELECT * FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +STMT: SelectStmt +== 013 +SELECT b.*, area(b.f1) as barea + FROM BOX_TBL b +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FUNCTION: name="area" function="area" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- overlap +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 && box '(2.5,2.5,1.0,1.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 015 +-- left-or-overlap (x only) +SELECT b1.* + FROM BOX_TBL b1 + WHERE b1.f1 &< box '(2.0,2.0,2.5,2.5)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +FILTER: schema="" table="b1" column="f1" +STMT: SelectStmt +== 016 +-- right-or-overlap (x only) +SELECT b1.* + FROM BOX_TBL b1 + WHERE b1.f1 &> box '(2.0,2.0,2.5,2.5)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +FILTER: schema="" table="b1" column="f1" +STMT: SelectStmt +== 017 +-- left of +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 << box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 018 +-- area <= +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 <= box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 019 +-- area < +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 < box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 020 +-- area = +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 = box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 021 +-- area > +SELECT b.f1 + FROM BOX_TBL b -- zero area + WHERE b.f1 > box '(3.5,3.0,4.5,3.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 022 +-- area >= +SELECT b.f1 + FROM BOX_TBL b -- zero area + WHERE b.f1 >= box '(3.5,3.0,4.5,3.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 023 +-- right of +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(3.0,3.0,5.0,5.0)' >> b.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 024 +-- contained in +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 <@ box '(0,0,3,3)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 025 +-- contains +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(0,0,3,3)' @> b.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 026 +-- box equality +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(1,1,3,3)' ~= b.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 027 +-- center of box, left unary operator +SELECT @@(b1.f1) AS p + FROM BOX_TBL b1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +STMT: SelectStmt +== 028 +-- wholly-contained +SELECT b1.*, b2.* + FROM BOX_TBL b1, BOX_TBL b2 + WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +FILTER: schema="" table="b1" column="f1" +FILTER: schema="" table="b2" column="f1" +FILTER: schema="" table="b1" column="f1" +FILTER: schema="" table="b2" column="f1" +STMT: SelectStmt +== 029 +SELECT height(f1), width(f1) FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="height" function="height" schema="" ctx=Call +FUNCTION: name="width" function="width" schema="" ctx=Call +STMT: SelectStmt +== 030 +|-- +-- Test the SP-GiST index +|-- + +CREATE TEMPORARY TABLE box_temp (f1 box) +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DDL +STMT: CreateStmt +== 031 +INSERT INTO box_temp + SELECT box(point(i, i), point(i * 2, i * 2)) + FROM generate_series(1, 50) AS i +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 032 +CREATE INDEX box_spgist ON box_temp USING spgist (f1) +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DDL +STMT: IndexStmt +== 033 +INSERT INTO box_temp + VALUES (NULL), + ('(0,0)(0,100)'), + ('(-3,4.3333333333)(40,1)'), + ('(0,100)(0,infinity)'), + ('(-infinity,0)(0,infinity)'), + ('(-infinity,-infinity)(infinity,infinity)') +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +SET enable_seqscan = false +-- +STMT: VariableSetStmt +== 035 +SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 036 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 037 +SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 038 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 040 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 041 +SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 042 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 044 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 045 +SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 046 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 047 +SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 048 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 049 +SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 050 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 051 +SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 052 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 053 +SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 054 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 055 +SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 056 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 057 +SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 058 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 059 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 060 +DROP INDEX box_spgist +-- +STMT: DropStmt +== 061 +|-- +-- Test the SP-GiST index on the larger volume of data +|-- +CREATE TABLE quad_box_tbl (id int, b box) +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DDL +STMT: CreateStmt +== 062 +INSERT INTO quad_box_tbl + SELECT (x - 1) * 100 + y, box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 063 +-- insert repeating data to test allTheSame +INSERT INTO quad_box_tbl + SELECT i, '((200, 300),(210, 310))' + FROM generate_series(10001, 11000) AS i +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 064 +INSERT INTO quad_box_tbl +VALUES + (11001, NULL), + (11002, NULL), + (11003, '((-infinity,-infinity),(infinity,infinity))'), + (11004, '((-infinity,100),(-infinity,500))'), + (11005, '((-infinity,-infinity),(700,infinity))') +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b) +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DDL +STMT: IndexStmt +== 066 +-- get reference results for ORDER BY distance from seq scan +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +== 067 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 068 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 069 +CREATE TABLE quad_box_tbl_ord_seq1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl +-- +TABLE: name="quad_box_tbl_ord_seq1" schema="" table="quad_box_tbl_ord_seq1" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 070 +CREATE TABLE quad_box_tbl_ord_seq2 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))' +-- +TABLE: name="quad_box_tbl_ord_seq2" schema="" table="quad_box_tbl_ord_seq2" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 071 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 072 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 073 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +== 074 +SELECT count(*) FROM quad_box_tbl WHERE b << box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 075 +SELECT count(*) FROM quad_box_tbl WHERE b &< box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 076 +SELECT count(*) FROM quad_box_tbl WHERE b && box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 077 +SELECT count(*) FROM quad_box_tbl WHERE b &> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 078 +SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 079 +SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 080 +SELECT count(*) FROM quad_box_tbl WHERE b <<| box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 081 +SELECT count(*) FROM quad_box_tbl WHERE b &<| box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 082 +SELECT count(*) FROM quad_box_tbl WHERE b |&> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 083 +SELECT count(*) FROM quad_box_tbl WHERE b |>> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 084 +SELECT count(*) FROM quad_box_tbl WHERE b @> box '((201,301),(202,303))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 085 +SELECT count(*) FROM quad_box_tbl WHERE b <@ box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 086 +SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 087 +-- test ORDER BY distance +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 088 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 089 +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 090 +CREATE TEMP TABLE quad_box_tbl_ord_idx1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl +-- +TABLE: name="quad_box_tbl_ord_idx1" schema="" table="quad_box_tbl_ord_idx1" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 091 +SELECT * +FROM quad_box_tbl_ord_seq1 seq FULL JOIN quad_box_tbl_ord_idx1 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 +-- +TABLE: name="quad_box_tbl_ord_seq1" schema="" table="quad_box_tbl_ord_seq1" ctx=Select +TABLE: name="quad_box_tbl_ord_idx1" schema="" table="quad_box_tbl_ord_idx1" ctx=Select +ALIAS: "idx"="quad_box_tbl_ord_idx1" +ALIAS: "seq"="quad_box_tbl_ord_seq1" +FILTER: schema="" table="seq" column="id" +FILTER: schema="" table="idx" column="id" +STMT: SelectStmt +== 092 +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))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 093 +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))' +-- +TABLE: name="quad_box_tbl_ord_idx2" schema="" table="quad_box_tbl_ord_idx2" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 094 +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 +-- +TABLE: name="quad_box_tbl_ord_seq2" schema="" table="quad_box_tbl_ord_seq2" ctx=Select +TABLE: name="quad_box_tbl_ord_idx2" schema="" table="quad_box_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="quad_box_tbl_ord_idx2" +ALIAS: "seq"="quad_box_tbl_ord_seq2" +FILTER: schema="" table="seq" column="id" +FILTER: schema="" table="idx" column="id" +STMT: SelectStmt +== 095 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 096 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 097 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 098 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('200', 'box') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 099 +SELECT * FROM pg_input_error_info('200', 'box') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 100 +SELECT pg_input_is_valid('((200,300),(500, xyz))', 'box') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 101 +SELECT * FROM pg_input_error_info('((200,300),(500, xyz))', 'box') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/brin.metadata.json b/parser/testdata/summary/postgres_regress/brin.metadata.json new file mode 100644 index 0000000..af46f65 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/brin.metadata.json @@ -0,0 +1,72 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068" + ] +} diff --git a/parser/testdata/summary/postgres_regress/brin.test b/parser/testdata/summary/postgres_regress/brin.test new file mode 100644 index 0000000..e2fab7b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/brin.test @@ -0,0 +1,849 @@ +== 001 +CREATE TABLE brintest (byteacol bytea, + charcol "char", + namecol name, + int8col bigint, + int2col smallint, + int4col integer, + textcol text, + oidcol oid, + tidcol tid, + float4col real, + float8col double precision, + macaddrcol macaddr, + inetcol inet, + cidrcol cidr, + bpcharcol character, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + bitcol bit(10), + varbitcol bit varying(16), + numericcol numeric, + uuidcol uuid, + int4rangecol int4range, + lsncol pg_lsn, + boxcol box +) WITH (fillfactor=10, autovacuum_enabled=off) +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO brintest SELECT + repeat(stringu1, 8)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 8), + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + thousand::bit(10), + tenthous::bit(16)::varbit, + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) +FROM tenk1 ORDER BY unique2 LIMIT 100 +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +-- throw in some NULL's and different values +INSERT INTO brintest (inetcol, cidrcol, int4rangecol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous, + 'empty'::int4range +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25 +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 004 +CREATE INDEX brinidx ON brintest USING brin ( + byteacol, + charcol, + namecol, + int8col, + int2col, + int4col, + textcol, + oidcol, + tidcol, + float4col, + float8col, + macaddrcol, + inetcol inet_inclusion_ops, + inetcol inet_minmax_ops, + cidrcol inet_inclusion_ops, + cidrcol inet_minmax_ops, + bpcharcol, + datecol, + timecol, + timestampcol, + timestamptzcol, + intervalcol, + timetzcol, + bitcol, + varbitcol, + numericcol, + uuidcol, + int4rangecol, + lsncol, + boxcol +) with (pages_per_range = 1) +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DDL +STMT: IndexStmt +== 005 +CREATE TABLE brinopers (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))) +-- +TABLE: name="brinopers" schema="" table="brinopers" ctx=DDL +STMT: CreateStmt +== 006 +INSERT INTO brinopers VALUES + ('byteacol', 'bytea', + '{>, >=, =, <=, <}', + '{AAAAAA, AAAAAA, BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA, ZZZZZZ, ZZZZZZ}', + '{100, 100, 1, 100, 100}'), + ('charcol', '"char"', + '{>, >=, =, <=, <}', + '{A, A, M, Z, Z}', + '{97, 100, 6, 100, 98}'), + ('namecol', 'name', + '{>, >=, =, <=, <}', + '{AAAAAA, AAAAAA, MAAAAA, ZZAAAA, ZZAAAA}', + '{100, 100, 2, 100, 100}'), + ('int2col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int8col', 'int2', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int4', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 1257141600, 1428427143, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('textcol', 'text', + '{>, >=, =, <=, <}', + '{ABABAB, ABABAB, BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA, ZZAAAA, ZZAAAA}', + '{100, 100, 1, 100, 100}'), + ('oidcol', 'oid', + '{>, >=, =, <=, <}', + '{0, 0, 8800, 9999, 9999}', + '{100, 100, 1, 100, 100}'), + ('tidcol', 'tid', + '{>, >=, =, <=, <}', + '{"(0,0)", "(0,0)", "(8800,0)", "(9999,19)", "(9999,19)"}', + '{100, 100, 1, 100, 100}'), + ('float4col', 'float4', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float4col', 'float8', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float8col', 'float4', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('float8col', 'float8', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('macaddrcol', 'macaddr', + '{>, >=, =, <=, <}', + '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}', + '{99, 100, 2, 100, 100}'), + ('inetcol', 'inet', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}', + '{100, 1, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('inetcol', 'inet', + '{&&, >>=, <<=, =}', + '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('inetcol', 'cidr', + '{&&, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}', + '{100, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('inetcol', 'cidr', + '{&&, >>=, <<=, =}', + '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('cidrcol', 'inet', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}', + '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('cidrcol', 'inet', + '{&&, >>=, <<=, =}', + '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('cidrcol', 'cidr', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}', + '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('cidrcol', 'cidr', + '{&&, >>=, <<=, =}', + '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('bpcharcol', 'bpchar', + '{>, >=, =, <=, <}', + '{A, A, W, Z, Z}', + '{97, 100, 6, 100, 98}'), + ('datecol', 'date', + '{>, >=, =, <=, <}', + '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}', + '{100, 100, 1, 100, 100}'), + ('timecol', 'time', + '{>, >=, =, <=, <}', + '{01:20:30, 01:20:30, 02:28:57, 06:28:31.5, 06:28:31.5}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamp', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestamptzcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-19 09:00:00-07, 1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03}', + '{100, 100, 1, 100, 100}'), + ('intervalcol', 'interval', + '{>, >=, =, <=, <}', + '{00:00:00, 00:00:00, 1 mons 13 days 12:24, 2 mons 23 days 07:48:00, 1 year}', + '{100, 100, 1, 100, 100}'), + ('timetzcol', 'timetz', + '{>, >=, =, <=, <}', + '{01:30:20+02, 01:30:20+02, 01:35:50+02, 23:55:05+02, 23:55:05+02}', + '{99, 100, 2, 100, 100}'), + ('bitcol', 'bit(10)', + '{>, >=, =, <=, <}', + '{0000000010, 0000000010, 0011011110, 1111111000, 1111111000}', + '{100, 100, 1, 100, 100}'), + ('varbitcol', 'varbit(16)', + '{>, >=, =, <=, <}', + '{0000000000000100, 0000000000000100, 0001010001100110, 1111111111111000, 1111111111111000}', + '{100, 100, 1, 100, 100}'), + ('numericcol', 'numeric', + '{>, >=, =, <=, <}', + '{0.00, 0.01, 2268164.347826086956521739130434782609, 99470151.9, 99470151.9}', + '{100, 100, 1, 100, 100}'), + ('uuidcol', 'uuid', + '{>, >=, =, <=, <}', + '{00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 52225222-5222-5222-5222-522252225222, 99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998}', + '{100, 100, 1, 100, 100}'), + ('int4rangecol', 'int4range', + '{<<, &<, &&, &>, >>, @>, <@, =, <, <=, >, >=}', + '{"[10000,)","[10000,)","(,]","[3,4)","[36,44)","(1500,1501]","[3,4)","[222,1222)","[36,44)","[43,1043)","[367,4466)","[519,)"}', + '{53, 53, 53, 53, 50, 22, 72, 1, 74, 75, 34, 21}'), + ('int4rangecol', 'int4range', + '{@>, <@, =, <=, >, >=}', + '{empty, empty, empty, empty, empty, empty}', + '{125, 72, 72, 72, 53, 125}'), + ('int4rangecol', 'int4', + '{@>}', + '{1500}', + '{22}'), + ('lsncol', 'pg_lsn', + '{>, >=, =, <=, <, IS, IS NOT}', + '{0/1200, 0/1200, 44/455222, 198/1999799, 198/1999799, NULL, NULL}', + '{100, 100, 1, 100, 100, 25, 100}'), + ('boxcol', 'point', + '{@>}', + '{"(500,43)"}', + '{11}'), + ('boxcol', 'box', + '{<<, &<, &&, &>, >>, <<|, &<|, |&>, |>>, @>, <@, ~=}', + '{"((1000,2000),(3000,4000))","((1,2),(3000,4000))","((1,2),(3000,4000))","((1,2),(3000,4000))","((1,2),(3,4))","((1000,2000),(3000,4000))","((1,2000),(3,4000))","((1000,2),(3000,4))","((1,2),(3,4))","((1,2),(300,400))","((1,2),(3000,4000))","((222,1222),(44,45))"}', + '{100, 100, 100, 99, 96, 100, 100, 99, 96, 1, 99, 1}') +-- +TABLE: name="brinopers" schema="" table="brinopers" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$ +-- +STMT: DoStmt +== 008 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 009 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 010 +INSERT INTO brintest SELECT + repeat(stringu1, 42)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 42), + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + thousand::bit(10), + tenthous::bit(16)::varbit, + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5 +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 011 +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 012 +VACUUM brintest +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DDL +STMT: VacuumStmt +== 013 +-- force a summarization cycle in brinidx + +UPDATE brintest SET int8col = int8col * int4col +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +STMT: UpdateStmt +== 014 +UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +STMT: UpdateStmt +== 015 +-- Tests for brin_summarize_new_values +SELECT brin_summarize_new_values('brintest') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- error, not an index +SELECT brin_summarize_new_values('tenk1_unique1') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- error, not a BRIN index +SELECT brin_summarize_new_values('brinidx') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- ok, no change expected + +-- Tests for brin_desummarize_range +SELECT brin_desummarize_range('brinidx', -1) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- error, invalid range +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT brin_desummarize_range('brinidx', 100000000) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- Test brin_summarize_range +CREATE TABLE brin_summarize ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false) +-- +TABLE: name="brin_summarize" schema="" table="brin_summarize" ctx=DDL +STMT: CreateStmt +== 023 +CREATE INDEX brin_summarize_idx ON brin_summarize USING brin (value) WITH (pages_per_range=2) +-- +TABLE: name="brin_summarize" schema="" table="brin_summarize" ctx=DDL +STMT: IndexStmt +== 024 +-- Fill a few pages +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 025 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_idx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 026 +-- nothing: already summarized +SELECT brin_summarize_range('brin_summarize_idx', 1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 027 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_idx', 2) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 028 +-- nothing: page doesn't exist in table +SELECT brin_summarize_range('brin_summarize_idx', 4294967295) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 029 +-- invalid block number values +SELECT brin_summarize_range('brin_summarize_idx', -1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT brin_summarize_range('brin_summarize_idx', 4294967296) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- test value merging in add_value +CREATE TABLE brintest_2 (n numrange) +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DDL +STMT: CreateStmt +== 032 +CREATE INDEX brinidx_2 ON brintest_2 USING brin (n) +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DDL +STMT: IndexStmt +== 033 +INSERT INTO brintest_2 VALUES ('empty') +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO brintest_2 VALUES (numrange(0, 2^1000::numeric)) +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO brintest_2 VALUES ('(-1, 0)') +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT brin_summarize_range('brinidx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 038 +DROP TABLE brintest_2 +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DDL +STMT: DropStmt +== 039 +-- test brin cost estimates behave sanely based on correlation of values +CREATE TABLE brin_test (a INT, b INT) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: CreateStmt +== 040 +INSERT INTO brin_test SELECT x/100,x%100 FROM generate_series(1,10000) x(x) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 041 +CREATE INDEX brin_test_a_idx ON brin_test USING brin (a) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: IndexStmt +== 042 +CREATE INDEX brin_test_b_idx ON brin_test USING brin (b) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: IndexStmt +== 043 +VACUUM ANALYZE brin_test +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: VacuumStmt +== 044 +-- Ensure brin index is used when columns are perfectly correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test WHERE a = 1 +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 045 +-- Ensure brin index is not used when values are not correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test WHERE b = 1 +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +-- make sure data are properly de-toasted in BRIN index +CREATE TABLE brintest_3 (a text, b text, c text, d text) +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: CreateStmt +== 047 +-- long random strings (~2000 chars each, so ~6kB for min/max on two +-- columns) to trigger toasting +WITH rand_value AS (SELECT string_agg(fipshash(i::text),'') AS val FROM generate_series(1,60) s(i)) +INSERT INTO brintest_3 +SELECT val, val, val, val FROM rand_value +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DML +CTE: "rand_value" +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 048 +CREATE INDEX brin_test_toast_idx ON brintest_3 USING brin (b, c) +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: IndexStmt +== 049 +DELETE FROM brintest_3 +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DML +STMT: DeleteStmt +== 050 +-- We need to wait a bit for all transactions to complete, so that the +-- vacuum actually removes the TOAST rows. Creating an index concurrently +-- is a one way to achieve that, because it does exactly such wait. +CREATE INDEX CONCURRENTLY brin_test_temp_idx ON brintest_3(a) +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: IndexStmt +== 051 +DROP INDEX brin_test_temp_idx +-- +STMT: DropStmt +== 052 +-- vacuum the table, to discard TOAST data +VACUUM brintest_3 +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: VacuumStmt +== 053 +-- retry insert with a different random-looking (but deterministic) value +-- the value is different, and so should replace either min or max in the +-- brin summary +WITH rand_value AS (SELECT string_agg(fipshash((-i)::text),'') AS val FROM generate_series(1,60) s(i)) +INSERT INTO brintest_3 +SELECT val, val, val, val FROM rand_value +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DML +CTE: "rand_value" +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 054 +-- now try some queries, accessing the brin index +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 055 +EXPLAIN (COSTS OFF) +SELECT * FROM brintest_3 WHERE b < '0' +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 056 +SELECT * FROM brintest_3 WHERE b < '0' +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 057 +DROP TABLE brintest_3 +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: DropStmt +== 058 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 059 +-- test an unlogged table, mostly to get coverage of brinbuildempty +CREATE UNLOGGED TABLE brintest_unlogged (n numrange) +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DDL +STMT: CreateStmt +== 060 +CREATE INDEX brinidx_unlogged ON brintest_unlogged USING brin (n) +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DDL +STMT: IndexStmt +== 061 +INSERT INTO brintest_unlogged VALUES (numrange(0, 2^1000::numeric)) +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 062 +DROP TABLE brintest_unlogged +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DDL +STMT: DropStmt +== 063 +-- test that the insert optimization works if no rows end up inserted +CREATE TABLE brin_insert_optimization (a int) +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DDL +STMT: CreateStmt +== 064 +INSERT INTO brin_insert_optimization VALUES (1) +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +CREATE INDEX brin_insert_optimization_idx ON brin_insert_optimization USING brin (a) +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DDL +STMT: IndexStmt +== 066 +UPDATE brin_insert_optimization SET a = a +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DML +STMT: UpdateStmt +== 067 +REINDEX INDEX CONCURRENTLY brin_insert_optimization_idx +-- +STMT: ReindexStmt +== 068 +DROP TABLE brin_insert_optimization +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/brin_bloom.metadata.json b/parser/testdata/summary/postgres_regress/brin_bloom.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/brin_bloom.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary/postgres_regress/brin_bloom.test b/parser/testdata/summary/postgres_regress/brin_bloom.test new file mode 100644 index 0000000..6774d89 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/brin_bloom.test @@ -0,0 +1,574 @@ +== 001 +CREATE TABLE brintest_bloom (byteacol bytea, + charcol "char", + namecol name, + int8col bigint, + int2col smallint, + int4col integer, + textcol text, + oidcol oid, + float4col real, + float8col double precision, + macaddrcol macaddr, + inetcol inet, + cidrcol cidr, + bpcharcol character, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + numericcol numeric, + uuidcol uuid, + lsncol pg_lsn +) WITH (fillfactor=10) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO brintest_bloom SELECT + repeat(stringu1, 8)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 8), + unique1::oid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 100 +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +-- throw in some NULL's and different values +INSERT INTO brintest_bloom (inetcol, cidrcol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25 +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 004 +-- test bloom specific index options +-- ndistinct must be >= -1.0 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(n_distinct_per_range = -1.1) +) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +== 005 +-- false_positive_rate must be between 0.0001 and 0.25 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(false_positive_rate = 0.00009) +) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +== 006 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(false_positive_rate = 0.26) +) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +== 007 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops, + charcol char_bloom_ops, + namecol name_bloom_ops, + int8col int8_bloom_ops, + int2col int2_bloom_ops, + int4col int4_bloom_ops, + textcol text_bloom_ops, + oidcol oid_bloom_ops, + float4col float4_bloom_ops, + float8col float8_bloom_ops, + macaddrcol macaddr_bloom_ops, + inetcol inet_bloom_ops, + cidrcol inet_bloom_ops, + bpcharcol bpchar_bloom_ops, + datecol date_bloom_ops, + timecol time_bloom_ops, + timestampcol timestamp_bloom_ops, + timestamptzcol timestamptz_bloom_ops, + intervalcol interval_bloom_ops, + timetzcol timetz_bloom_ops, + numericcol numeric_bloom_ops, + uuidcol uuid_bloom_ops, + lsncol pg_lsn_bloom_ops +) with (pages_per_range = 1) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +== 008 +CREATE TABLE brinopers_bloom (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))) +-- +TABLE: name="brinopers_bloom" schema="" table="brinopers_bloom" ctx=DDL +STMT: CreateStmt +== 009 +INSERT INTO brinopers_bloom VALUES + ('byteacol', 'bytea', + '{=}', + '{BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA}', + '{1}'), + ('charcol', '"char"', + '{=}', + '{M}', + '{6}'), + ('namecol', 'name', + '{=}', + '{MAAAAA}', + '{2}'), + ('int2col', 'int2', + '{=}', + '{800}', + '{1}'), + ('int4col', 'int4', + '{=}', + '{800}', + '{1}'), + ('int8col', 'int8', + '{=}', + '{1257141600}', + '{1}'), + ('textcol', 'text', + '{=}', + '{BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA}', + '{1}'), + ('oidcol', 'oid', + '{=}', + '{8800}', + '{1}'), + ('float4col', 'float4', + '{=}', + '{1}', + '{4}'), + ('float8col', 'float8', + '{=}', + '{0}', + '{1}'), + ('macaddrcol', 'macaddr', + '{=}', + '{2c:00:2d:00:16:00}', + '{2}'), + ('inetcol', 'inet', + '{=}', + '{10.2.14.231/24}', + '{1}'), + ('inetcol', 'cidr', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('cidrcol', 'inet', + '{=}', + '{10.2.14/24}', + '{2}'), + ('cidrcol', 'inet', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('cidrcol', 'cidr', + '{=}', + '{10.2.14/24}', + '{2}'), + ('cidrcol', 'cidr', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('bpcharcol', 'bpchar', + '{=}', + '{W}', + '{6}'), + ('datecol', 'date', + '{=}', + '{2009-12-01}', + '{1}'), + ('timecol', 'time', + '{=}', + '{02:28:57}', + '{1}'), + ('timestampcol', 'timestamp', + '{=}', + '{1964-03-24 19:26:45}', + '{1}'), + ('timestamptzcol', 'timestamptz', + '{=}', + '{1972-10-19 09:00:00-07}', + '{1}'), + ('intervalcol', 'interval', + '{=}', + '{1 mons 13 days 12:24}', + '{1}'), + ('timetzcol', 'timetz', + '{=}', + '{01:35:50+02}', + '{2}'), + ('numericcol', 'numeric', + '{=}', + '{2268164.347826086956521739130434782609}', + '{1}'), + ('uuidcol', 'uuid', + '{=}', + '{52225222-5222-5222-5222-522252225222}', + '{1}'), + ('lsncol', 'pg_lsn', + '{=, IS, IS NOT}', + '{44/455222, NULL, NULL}', + '{1, 25, 100}') +-- +TABLE: name="brinopers_bloom" schema="" table="brinopers_bloom" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers_bloom, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest_bloom%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest_bloom%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_bloom WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_bloom WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$ +-- +STMT: DoStmt +== 011 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 012 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 013 +INSERT INTO brintest_bloom SELECT + repeat(stringu1, 42)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 42), + unique1::oid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5 +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 014 +SELECT brin_desummarize_range('brinidx_bloom', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 015 +VACUUM brintest_bloom +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: VacuumStmt +== 016 +-- force a summarization cycle in brinidx + +UPDATE brintest_bloom SET int8col = int8col * int4col +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +STMT: UpdateStmt +== 017 +UPDATE brintest_bloom SET textcol = '' WHERE textcol IS NOT NULL +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +STMT: UpdateStmt +== 018 +-- Tests for brin_summarize_new_values +SELECT brin_summarize_new_values('brintest_bloom') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- error, not an index +SELECT brin_summarize_new_values('tenk1_unique1') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- error, not a BRIN index +SELECT brin_summarize_new_values('brinidx_bloom') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- ok, no change expected + +-- Tests for brin_desummarize_range +SELECT brin_desummarize_range('brinidx_bloom', -1) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- error, invalid range +SELECT brin_desummarize_range('brinidx_bloom', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT brin_desummarize_range('brinidx_bloom', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT brin_desummarize_range('brinidx_bloom', 100000000) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 025 +-- Test brin_summarize_range +CREATE TABLE brin_summarize_bloom ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false) +-- +TABLE: name="brin_summarize_bloom" schema="" table="brin_summarize_bloom" ctx=DDL +STMT: CreateStmt +== 026 +CREATE INDEX brin_summarize_bloom_idx ON brin_summarize_bloom USING brin (value) WITH (pages_per_range=2) +-- +TABLE: name="brin_summarize_bloom" schema="" table="brin_summarize_bloom" ctx=DDL +STMT: IndexStmt +== 027 +-- Fill a few pages +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize_bloom VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 028 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_bloom_idx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 029 +-- nothing: already summarized +SELECT brin_summarize_range('brin_summarize_bloom_idx', 1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 030 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_bloom_idx', 2) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- nothing: page doesn't exist in table +SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967295) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 032 +-- invalid block number values +SELECT brin_summarize_range('brin_summarize_bloom_idx', -1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967296) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 034 +-- test brin cost estimates behave sanely based on correlation of values +CREATE TABLE brin_test_bloom (a INT, b INT) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: CreateStmt +== 035 +INSERT INTO brin_test_bloom SELECT x/100,x%100 FROM generate_series(1,10000) x(x) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 036 +CREATE INDEX brin_test_bloom_a_idx ON brin_test_bloom USING brin (a) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: IndexStmt +== 037 +CREATE INDEX brin_test_bloom_b_idx ON brin_test_bloom USING brin (b) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: IndexStmt +== 038 +VACUUM ANALYZE brin_test_bloom +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: VacuumStmt +== 039 +-- Ensure brin index is used when columns are perfectly correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_bloom WHERE a = 1 +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 040 +-- Ensure brin index is not used when values are not correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_bloom WHERE b = 1 +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/brin_multi.metadata.json b/parser/testdata/summary/postgres_regress/brin_multi.metadata.json new file mode 100644 index 0000000..643d115 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/brin_multi.metadata.json @@ -0,0 +1,176 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172" + ] +} diff --git a/parser/testdata/summary/postgres_regress/brin_multi.test b/parser/testdata/summary/postgres_regress/brin_multi.test new file mode 100644 index 0000000..eeb0457 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/brin_multi.test @@ -0,0 +1,1466 @@ +== 001 +CREATE TABLE brintest_multi ( + int8col bigint, + int2col smallint, + int4col integer, + oidcol oid, + tidcol tid, + float4col real, + float8col double precision, + macaddrcol macaddr, + macaddr8col macaddr8, + inetcol inet, + cidrcol cidr, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + numericcol numeric, + uuidcol uuid, + lsncol pg_lsn +) WITH (fillfactor=10) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO brintest_multi SELECT + 142857 * tenthous, + thousand, + twothousand, + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + substr(fipshash(unique1::text), 1, 16)::macaddr8, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 100 +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +-- throw in some NULL's and different values +INSERT INTO brintest_multi (inetcol, cidrcol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25 +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 004 +-- test minmax-multi specific index options +-- number of values must be >= 16 +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops(values_per_range = 7) +) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +== 005 +-- number of values must be <= 256 +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops(values_per_range = 257) +) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +== 006 +-- first create an index with a single page range, to force compaction +-- due to exceeding the number of values per summary +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops, + int2col int2_minmax_multi_ops, + int4col int4_minmax_multi_ops, + oidcol oid_minmax_multi_ops, + tidcol tid_minmax_multi_ops, + float4col float4_minmax_multi_ops, + float8col float8_minmax_multi_ops, + macaddrcol macaddr_minmax_multi_ops, + macaddr8col macaddr8_minmax_multi_ops, + inetcol inet_minmax_multi_ops, + cidrcol inet_minmax_multi_ops, + datecol date_minmax_multi_ops, + timecol time_minmax_multi_ops, + timestampcol timestamp_minmax_multi_ops, + timestamptzcol timestamptz_minmax_multi_ops, + intervalcol interval_minmax_multi_ops, + timetzcol timetz_minmax_multi_ops, + numericcol numeric_minmax_multi_ops, + uuidcol uuid_minmax_multi_ops, + lsncol pg_lsn_minmax_multi_ops +) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +== 007 +DROP INDEX brinidx_multi +-- +STMT: DropStmt +== 008 +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops, + int2col int2_minmax_multi_ops, + int4col int4_minmax_multi_ops, + oidcol oid_minmax_multi_ops, + tidcol tid_minmax_multi_ops, + float4col float4_minmax_multi_ops, + float8col float8_minmax_multi_ops, + macaddrcol macaddr_minmax_multi_ops, + macaddr8col macaddr8_minmax_multi_ops, + inetcol inet_minmax_multi_ops, + cidrcol inet_minmax_multi_ops, + datecol date_minmax_multi_ops, + timecol time_minmax_multi_ops, + timestampcol timestamp_minmax_multi_ops, + timestamptzcol timestamptz_minmax_multi_ops, + intervalcol interval_minmax_multi_ops, + timetzcol timetz_minmax_multi_ops, + numericcol numeric_minmax_multi_ops, + uuidcol uuid_minmax_multi_ops, + lsncol pg_lsn_minmax_multi_ops +) with (pages_per_range = 1) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +== 009 +CREATE TABLE brinopers_multi (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))) +-- +TABLE: name="brinopers_multi" schema="" table="brinopers_multi" ctx=DDL +STMT: CreateStmt +== 010 +INSERT INTO brinopers_multi VALUES + ('int2col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int8col', 'int2', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int4', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 1257141600, 1428427143, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('oidcol', 'oid', + '{>, >=, =, <=, <}', + '{0, 0, 8800, 9999, 9999}', + '{100, 100, 1, 100, 100}'), + ('tidcol', 'tid', + '{>, >=, =, <=, <}', + '{"(0,0)", "(0,0)", "(8800,0)", "(9999,19)", "(9999,19)"}', + '{100, 100, 1, 100, 100}'), + ('float4col', 'float4', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float4col', 'float8', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float8col', 'float4', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('float8col', 'float8', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('macaddrcol', 'macaddr', + '{>, >=, =, <=, <}', + '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}', + '{99, 100, 2, 100, 100}'), + ('macaddr8col', 'macaddr8', + '{>, >=, =, <=, <}', + '{b1:d1:0e:7b:af:a4:42:12, d9:35:91:bd:f7:86:0e:1e, 72:8f:20:6c:2a:01:bf:57, 23:e8:46:63:86:07:ad:cb, 13:16:8e:6a:2e:6c:84:b4}', + '{31, 17, 1, 11, 4}'), + ('inetcol', 'inet', + '{=, <, <=, >, >=}', + '{10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{1, 100, 100, 125, 125}'), + ('inetcol', 'cidr', + '{<, <=, >, >=}', + '{255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{100, 100, 125, 125}'), + ('cidrcol', 'inet', + '{=, <, <=, >, >=}', + '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{2, 100, 100, 125, 125}'), + ('cidrcol', 'cidr', + '{=, <, <=, >, >=}', + '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{2, 100, 100, 125, 125}'), + ('datecol', 'date', + '{>, >=, =, <=, <}', + '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}', + '{100, 100, 1, 100, 100}'), + ('timecol', 'time', + '{>, >=, =, <=, <}', + '{01:20:30, 01:20:30, 02:28:57, 06:28:31.5, 06:28:31.5}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamp', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestamptzcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-19 09:00:00-07, 1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03}', + '{100, 100, 1, 100, 100}'), + ('intervalcol', 'interval', + '{>, >=, =, <=, <}', + '{00:00:00, 00:00:00, 1 mons 13 days 12:24, 2 mons 23 days 07:48:00, 1 year}', + '{100, 100, 1, 100, 100}'), + ('timetzcol', 'timetz', + '{>, >=, =, <=, <}', + '{01:30:20+02, 01:30:20+02, 01:35:50+02, 23:55:05+02, 23:55:05+02}', + '{99, 100, 2, 100, 100}'), + ('numericcol', 'numeric', + '{>, >=, =, <=, <}', + '{0.00, 0.01, 2268164.347826086956521739130434782609, 99470151.9, 99470151.9}', + '{100, 100, 1, 100, 100}'), + ('uuidcol', 'uuid', + '{>, >=, =, <=, <}', + '{00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 52225222-5222-5222-5222-522252225222, 99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998}', + '{100, 100, 1, 100, 100}'), + ('lsncol', 'pg_lsn', + '{>, >=, =, <=, <, IS, IS NOT}', + '{0/1200, 0/1200, 44/455222, 198/1999799, 198/1999799, NULL, NULL}', + '{100, 100, 1, 100, 100, 25, 100}') +-- +TABLE: name="brinopers_multi" schema="" table="brinopers_multi" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers_multi, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest_multi%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest_multi%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$ +-- +STMT: DoStmt +== 012 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 013 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 014 +INSERT INTO brintest_multi SELECT + 142857 * tenthous, + thousand, + twothousand, + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + substr(fipshash(unique1::text), 1, 16)::macaddr8, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5 +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 015 +SELECT brin_desummarize_range('brinidx_multi', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 016 +VACUUM brintest_multi +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: VacuumStmt +== 017 +-- force a summarization cycle in brinidx + +-- Try inserting a values with NaN, to test distance calculation. +insert into public.brintest_multi (float4col) values (real 'nan') +-- +TABLE: name="public.brintest_multi" schema="public" table="brintest_multi" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +insert into public.brintest_multi (float8col) values (real 'nan') +-- +TABLE: name="public.brintest_multi" schema="public" table="brintest_multi" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +UPDATE brintest_multi SET int8col = int8col * int4col +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +STMT: UpdateStmt +== 020 +-- Test handling of inet netmasks with inet_minmax_multi_ops +CREATE TABLE brin_test_inet (a inet) +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DDL +STMT: CreateStmt +== 021 +CREATE INDEX ON brin_test_inet USING brin (a inet_minmax_multi_ops) +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DDL +STMT: IndexStmt +== 022 +INSERT INTO brin_test_inet VALUES ('127.0.0.1/0') +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO brin_test_inet VALUES ('0.0.0.0/12') +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +DROP TABLE brin_test_inet +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DDL +STMT: DropStmt +== 025 +-- Tests for brin_summarize_new_values +SELECT brin_summarize_new_values('brintest_multi') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 026 +-- error, not an index +SELECT brin_summarize_new_values('tenk1_unique1') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 027 +-- error, not a BRIN index +SELECT brin_summarize_new_values('brinidx_multi') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +== 028 +-- ok, no change expected + +-- Tests for brin_desummarize_range +SELECT brin_desummarize_range('brinidx_multi', -1) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 029 +-- error, invalid range +SELECT brin_desummarize_range('brinidx_multi', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT brin_desummarize_range('brinidx_multi', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT brin_desummarize_range('brinidx_multi', 100000000) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +== 032 +-- test building an index with many values, to force compaction of the buffer +CREATE TABLE brin_large_range (a int4) +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DDL +STMT: CreateStmt +== 033 +INSERT INTO brin_large_range SELECT i FROM generate_series(1,10000) s(i) +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 034 +CREATE INDEX brin_large_range_idx ON brin_large_range USING brin (a int4_minmax_multi_ops) +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DDL +STMT: IndexStmt +== 035 +DROP TABLE brin_large_range +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DDL +STMT: DropStmt +== 036 +-- Test brin_summarize_range +CREATE TABLE brin_summarize_multi ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false) +-- +TABLE: name="brin_summarize_multi" schema="" table="brin_summarize_multi" ctx=DDL +STMT: CreateStmt +== 037 +CREATE INDEX brin_summarize_multi_idx ON brin_summarize_multi USING brin (value) WITH (pages_per_range=2) +-- +TABLE: name="brin_summarize_multi" schema="" table="brin_summarize_multi" ctx=DDL +STMT: IndexStmt +== 038 +-- Fill a few pages +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize_multi VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 039 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_multi_idx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 040 +-- nothing: already summarized +SELECT brin_summarize_range('brin_summarize_multi_idx', 1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_multi_idx', 2) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- nothing: page doesn't exist in table +SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967295) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 043 +-- invalid block number values +SELECT brin_summarize_range('brin_summarize_multi_idx', -1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967296) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- test brin cost estimates behave sanely based on correlation of values +CREATE TABLE brin_test_multi (a INT, b INT) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: CreateStmt +== 046 +INSERT INTO brin_test_multi SELECT x/100,x%100 FROM generate_series(1,10000) x(x) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 047 +CREATE INDEX brin_test_multi_a_idx ON brin_test_multi USING brin (a) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: IndexStmt +== 048 +CREATE INDEX brin_test_multi_b_idx ON brin_test_multi USING brin (b) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: IndexStmt +== 049 +VACUUM ANALYZE brin_test_multi +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: VacuumStmt +== 050 +-- Ensure brin index is used when columns are perfectly correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE a = 1 +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 051 +-- Ensure brin index is not used when values are not correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE b = 1 +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +-- do some inequality tests +CREATE TABLE brin_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: CreateStmt +== 053 +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 054 +CREATE INDEX brin_test_multi_1_idx_1 ON brin_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=5) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: IndexStmt +== 055 +CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=5) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: IndexStmt +== 056 +SET enable_seqscan=off +-- +STMT: VariableSetStmt +== 057 +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 058 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 059 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 060 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 061 +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 062 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 063 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 064 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 065 +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 066 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 067 +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 068 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 069 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 070 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 071 +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 072 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 073 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 074 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 075 +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 076 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 077 +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges +TRUNCATE brin_test_multi_1 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: TruncateStmt +== 078 +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 079 +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 080 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 081 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 082 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 083 +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 084 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 085 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 086 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 087 +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 088 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 089 +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 090 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 091 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 092 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 093 +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 094 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 095 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 096 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 097 +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 098 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 099 +DROP TABLE brin_test_multi_1 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: DropStmt +== 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 101 +-- do some inequality tests for varlena data types +CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10) +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: CreateStmt +== 102 +INSERT INTO brin_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random() +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DML +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 103 +CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5) +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: IndexStmt +== 104 +SET enable_seqscan=off +-- +STMT: VariableSetStmt +== 105 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 106 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 107 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 108 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 109 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 110 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 111 +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges + +TRUNCATE brin_test_multi_2 +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: TruncateStmt +== 112 +INSERT INTO brin_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random() +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DML +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 113 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 114 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 115 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 116 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 117 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 118 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 119 +DROP TABLE brin_test_multi_2 +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: DropStmt +== 120 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 121 +-- test overflows during CREATE INDEX with extreme timestamp values +CREATE TABLE brin_timestamp_test(a TIMESTAMPTZ) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: CreateStmt +== 122 +SET datestyle TO iso +-- +STMT: VariableSetStmt +== 123 +-- values close to timestamp minimum +INSERT INTO brin_timestamp_test +SELECT '4713-01-01 00:00:01 BC'::timestamptz + (i || ' seconds')::interval + FROM generate_series(1,30) s(i) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 124 +-- values close to timestamp maximum +INSERT INTO brin_timestamp_test +SELECT '294276-12-01 00:00:01'::timestamptz + (i || ' seconds')::interval + FROM generate_series(1,30) s(i) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 125 +CREATE INDEX ON brin_timestamp_test USING brin (a timestamptz_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: IndexStmt +== 126 +DROP TABLE brin_timestamp_test +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: DropStmt +== 127 +-- test overflows during CREATE INDEX with extreme date values +CREATE TABLE brin_date_test(a DATE) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: CreateStmt +== 128 +-- insert values close to date minimum +INSERT INTO brin_date_test SELECT '4713-01-01 BC'::date + i FROM generate_series(1, 30) s(i) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 129 +-- insert values close to date minimum +INSERT INTO brin_date_test SELECT '5874897-12-01'::date + i FROM generate_series(1, 30) s(i) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 130 +CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: IndexStmt +== 131 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 132 +-- make sure the ranges were built correctly and 2023-01-01 eliminates all +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 133 +DROP TABLE brin_date_test +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: DropStmt +== 134 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 135 +-- test handling of infinite timestamp values +CREATE TABLE brin_timestamp_test(a TIMESTAMP) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: CreateStmt +== 136 +INSERT INTO brin_timestamp_test VALUES ('-infinity'), ('infinity') +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +INSERT INTO brin_timestamp_test +SELECT i FROM generate_series('2000-01-01'::timestamp, '2000-02-09'::timestamp, '1 day'::interval) s(i) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 138 +CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: IndexStmt +== 139 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 140 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 141 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 142 +DROP TABLE brin_timestamp_test +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: DropStmt +== 143 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 144 +-- test handling of infinite date values +CREATE TABLE brin_date_test(a DATE) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: CreateStmt +== 145 +INSERT INTO brin_date_test VALUES ('-infinity'), ('infinity') +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +INSERT INTO brin_date_test SELECT '2000-01-01'::date + i FROM generate_series(1, 40) s(i) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 147 +CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: IndexStmt +== 148 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 149 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 150 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 151 +DROP TABLE brin_date_test +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: DropStmt +== 152 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 153 +RESET datestyle +-- +STMT: VariableSetStmt +== 154 +-- test handling of overflow for interval values +CREATE TABLE brin_interval_test(a INTERVAL) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: CreateStmt +== 155 +INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series(-178000000, -177999980) s(i) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 156 +INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series( 177999980, 178000000) s(i) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 157 +CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: IndexStmt +== 158 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 159 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 160 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 161 +DROP TABLE brin_interval_test +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: DropStmt +== 162 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 163 +-- test handling of infinite interval values +CREATE TABLE brin_interval_test(a INTERVAL) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: CreateStmt +== 164 +INSERT INTO brin_interval_test VALUES ('-infinity'), ('infinity') +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +INSERT INTO brin_interval_test SELECT (i || ' days')::interval FROM generate_series(100, 140) s(i) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 166 +CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: IndexStmt +== 167 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 168 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 169 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 170 +DROP TABLE brin_interval_test +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: DropStmt +== 171 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 172 +RESET datestyle +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/btree_index.metadata.json b/parser/testdata/summary/postgres_regress/btree_index.metadata.json new file mode 100644 index 0000000..11ed4d1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/btree_index.metadata.json @@ -0,0 +1,100 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096" + ] +} diff --git a/parser/testdata/summary/postgres_regress/btree_index.test b/parser/testdata/summary/postgres_regress/btree_index.test new file mode 100644 index 0000000..18d65c7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/btree_index.test @@ -0,0 +1,695 @@ +== 001 +|-- +-- BTREE_INDEX +|-- + +-- directory paths are passed to us in environment variables + +CREATE TABLE bt_i4_heap ( + seqno int4, + random int4 +) +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE bt_name_heap ( + seqno name, + random int4 +) +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE bt_txt_heap ( + seqno text, + random int4 +) +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE bt_f8_heap ( + seqno float8, + random int4 +) +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=DDL +STMT: CreateStmt +== 005 +COPY bt_i4_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +COPY bt_name_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +COPY bt_txt_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +COPY bt_f8_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +ANALYZE bt_i4_heap +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=DDL +STMT: VacuumStmt +== 010 +ANALYZE bt_name_heap +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=DDL +STMT: VacuumStmt +== 011 +ANALYZE bt_txt_heap +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=DDL +STMT: VacuumStmt +== 012 +ANALYZE bt_f8_heap +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=DDL +STMT: VacuumStmt +== 013 +|-- +-- BTREE ascending/descending cases +|-- +-- we load int4/text from pure descending data (each key is a new +-- low key) and name/f8 from pure ascending data (each key is a new +-- high key). we had a bug where new low keys would sometimes be +-- "lost". +|-- +CREATE INDEX bt_i4_index ON bt_i4_heap USING btree (seqno int4_ops) +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=DDL +STMT: IndexStmt +== 014 +CREATE INDEX bt_name_index ON bt_name_heap USING btree (seqno name_ops) +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=DDL +STMT: IndexStmt +== 015 +CREATE INDEX bt_txt_index ON bt_txt_heap USING btree (seqno text_ops) +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=DDL +STMT: IndexStmt +== 016 +CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops) +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=DDL +STMT: IndexStmt +== 017 +|-- +-- test retrieval of min/max keys for each index +|-- + +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno < 1 +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=Select +ALIAS: "b"="bt_i4_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 018 +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno >= 9999 +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=Select +ALIAS: "b"="bt_i4_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 019 +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno = 4500 +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=Select +ALIAS: "b"="bt_i4_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 020 +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno < '1'::name +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=Select +ALIAS: "b"="bt_name_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 021 +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno >= '9999'::name +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=Select +ALIAS: "b"="bt_name_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 022 +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno = '4500'::name +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=Select +ALIAS: "b"="bt_name_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 023 +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno < '1'::text +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=Select +ALIAS: "b"="bt_txt_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 024 +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno >= '9999'::text +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=Select +ALIAS: "b"="bt_txt_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 025 +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno = '4500'::text +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=Select +ALIAS: "b"="bt_txt_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 026 +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno < '1'::float8 +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=Select +ALIAS: "b"="bt_f8_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 027 +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno >= '9999'::float8 +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=Select +ALIAS: "b"="bt_f8_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 028 +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno = '4500'::float8 +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=Select +ALIAS: "b"="bt_f8_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +== 029 +|-- +-- Add coverage for optimization of backwards scan index descents +|-- +-- Here we expect _bt_search to descend straight to a leaf page containing a +-- non-pivot tuple with the value '47', which comes last (after 11 similar +-- non-pivot tuples). Query execution should only need to visit a single +-- leaf page here. +|-- +-- Test case relies on tenk1_hundred index having a leaf page whose high key +-- is '(48, -inf)'. We use a low cardinality index to make our test case less +-- sensitive to implementation details that may change in the future. +set enable_seqscan to false +-- +STMT: VariableSetStmt +== 030 +set enable_indexscan to true +-- +STMT: VariableSetStmt +== 031 +set enable_bitmapscan to false +-- +STMT: VariableSetStmt +== 032 +explain (costs off) +select hundred, twenty from tenk1 where hundred < 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 033 +select hundred, twenty from tenk1 where hundred < 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 034 +-- This variant of the query need only return a single tuple located to the immediate +-- right of the '(48, -inf)' high key. It also only needs to scan one single +-- leaf page (the right sibling of the page scanned by the last test case): +explain (costs off) +select hundred, twenty from tenk1 where hundred <= 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 035 +select hundred, twenty from tenk1 where hundred <= 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 036 +|-- +-- Add coverage for ScalarArrayOp btree quals with pivot tuple constants +|-- +explain (costs off) +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 037 +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 038 +explain (costs off) +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) order by hundred desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) order by hundred desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 040 +explain (costs off) +select thousand from tenk1 where thousand in (364, 366,380) and tenthous = 200000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 041 +select thousand from tenk1 where thousand in (364, 366,380) and tenthous = 200000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 042 +|-- +-- Check correct optimization of LIKE (special index operator support) +-- for both indexscan and bitmapscan cases +|-- + +set enable_seqscan to false +-- +STMT: VariableSetStmt +== 043 +set enable_indexscan to true +-- +STMT: VariableSetStmt +== 044 +set enable_bitmapscan to false +-- +STMT: VariableSetStmt +== 045 +explain (costs off) +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +== 047 +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +== 048 +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +== 049 +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +set enable_indexscan to false +-- +STMT: VariableSetStmt +== 051 +set enable_bitmapscan to true +-- +STMT: VariableSetStmt +== 052 +explain (costs off) +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +== 053 +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +== 054 +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +== 055 +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +== 056 +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +== 057 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 058 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 059 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 060 +-- Also check LIKE optimization with binary-compatible cases + +create temp table btree_bpchar (f1 text collate "C") +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DDL +STMT: CreateStmt +== 061 +create index on btree_bpchar(f1 bpchar_ops) WITH (deduplicate_items=on) +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DDL +STMT: IndexStmt +== 062 +insert into btree_bpchar values ('foo'), ('fool'), ('bar'), ('quux') +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +-- doesn't match index: +explain (costs off) +select * from btree_bpchar where f1 like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 064 +select * from btree_bpchar where f1 like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 065 +explain (costs off) +select * from btree_bpchar where f1 like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 066 +select * from btree_bpchar where f1 like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 067 +-- these do match the index: +explain (costs off) +select * from btree_bpchar where f1::bpchar like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 068 +select * from btree_bpchar where f1::bpchar like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 069 +explain (costs off) +select * from btree_bpchar where f1::bpchar like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 070 +select * from btree_bpchar where f1::bpchar like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 071 +-- get test coverage for "single value" deduplication strategy: +insert into btree_bpchar select 'foo' from generate_series(1,1500) +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 072 +|-- +-- Perform unique checking, with and without the use of deduplication +|-- +CREATE TABLE dedup_unique_test_table (a int) WITH (autovacuum_enabled=false) +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DDL +STMT: CreateStmt +== 073 +CREATE UNIQUE INDEX dedup_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=on) +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DDL +STMT: IndexStmt +== 074 +CREATE UNIQUE INDEX plain_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=off) +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DDL +STMT: IndexStmt +== 075 +-- 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$$ +-- +STMT: DoStmt +== 076 +-- 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 +-- +STMT: DropStmt +== 077 +DELETE FROM dedup_unique_test_table WHERE a = 1 +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DML +STMT: DeleteStmt +== 078 +INSERT INTO dedup_unique_test_table SELECT i FROM generate_series(0,450) i +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 079 +|-- +-- 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) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: CreateStmt +== 080 +alter table btree_tall_tbl alter COLUMN t set storage plain +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: AlterTableStmt +== 081 +create index btree_tall_idx on btree_tall_tbl (t, id) with (fillfactor = 10) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: IndexStmt +== 082 +insert into btree_tall_tbl select g, repeat('x', 250) +from generate_series(1, 130) g +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 083 +|-- +-- Test for multilevel page deletion +|-- +CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint) +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DDL +STMT: CreateStmt +== 084 +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 085 +ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d) +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DDL +STMT: AlterTableStmt +== 086 +-- Delete most entries, and vacuum, deleting internal pages and creating "fast +-- root" +DELETE FROM delete_test_table WHERE a < 79990 +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DML +STMT: DeleteStmt +== 087 +VACUUM delete_test_table +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DDL +STMT: VacuumStmt +== 088 +|-- +-- 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 +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 089 +-- Test unsupported btree opclass parameters +create index on btree_tall_tbl (id int4_ops(foo=1)) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: IndexStmt +== 090 +-- 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) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: IndexStmt +== 091 +ALTER INDEX btree_tall_idx2 ALTER COLUMN id SET (n_distinct=100) +-- +STMT: AlterTableStmt +== 092 +DROP INDEX btree_tall_idx2 +-- +STMT: DropStmt +== 093 +-- Partitioned index +CREATE TABLE btree_part (id int4) PARTITION BY RANGE (id) +-- +TABLE: name="btree_part" schema="" table="btree_part" ctx=DDL +STMT: CreateStmt +== 094 +CREATE INDEX btree_part_idx ON btree_part(id) +-- +TABLE: name="btree_part" schema="" table="btree_part" ctx=DDL +STMT: IndexStmt +== 095 +ALTER INDEX btree_part_idx ALTER COLUMN id SET (n_distinct=100) +-- +STMT: AlterTableStmt +== 096 +DROP TABLE btree_part +-- +TABLE: name="btree_part" schema="" table="btree_part" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/case.metadata.json b/parser/testdata/summary/postgres_regress/case.metadata.json new file mode 100644 index 0000000..f47f175 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/case.metadata.json @@ -0,0 +1,68 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064" + ] +} diff --git a/parser/testdata/summary/postgres_regress/case.test b/parser/testdata/summary/postgres_regress/case.test new file mode 100644 index 0000000..4402a85 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/case.test @@ -0,0 +1,490 @@ +== 001 +|-- +-- CASE +-- Test the case statement +|-- + +CREATE TABLE CASE_TBL ( + i integer, + f double precision +) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE CASE2_TBL ( + i integer, + j integer +) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO CASE_TBL VALUES (1, 10.1) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO CASE_TBL VALUES (2, 20.2) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO CASE_TBL VALUES (3, -30.3) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO CASE_TBL VALUES (4, NULL) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO CASE2_TBL VALUES (1, -1) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO CASE2_TBL VALUES (2, -2) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO CASE2_TBL VALUES (3, -3) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO CASE2_TBL VALUES (2, -4) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO CASE2_TBL VALUES (1, NULL) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO CASE2_TBL VALUES (NULL, -6) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +|-- +-- Simplest examples without tables +|-- + +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + END AS "Simple WHEN" +-- +STMT: SelectStmt +== 014 +SELECT '' AS "One", + CASE + WHEN 1 > 2 THEN 3 + END AS "Simple default" +-- +STMT: SelectStmt +== 015 +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + ELSE 4 + END AS "Simple ELSE" +-- +STMT: SelectStmt +== 016 +SELECT '4' AS "One", + CASE + WHEN 1 > 2 THEN 3 + ELSE 4 + END AS "ELSE default" +-- +STMT: SelectStmt +== 017 +SELECT '6' AS "One", + CASE + WHEN 1 > 2 THEN 3 + WHEN 4 < 5 THEN 6 + ELSE 7 + END AS "Two WHEN with default" +-- +STMT: SelectStmt +== 018 +SELECT '7' AS "None", + CASE WHEN random() < 0 THEN 1 + END AS "NULL on no matches" +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- Constant-expression folding shouldn't evaluate unreachable subexpressions +SELECT CASE WHEN 1=0 THEN 1/0 WHEN 1=1 THEN 1 ELSE 2/0 END +-- +STMT: SelectStmt +== 020 +SELECT CASE 1 WHEN 0 THEN 1/0 WHEN 1 THEN 1 ELSE 2/0 END +-- +STMT: SelectStmt +== 021 +-- However we do not currently suppress folding of potentially +-- reachable subexpressions +SELECT CASE WHEN i > 100 THEN 1/0 ELSE 0 END FROM case_tbl +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 022 +-- Test for cases involving untyped literals in test expression +SELECT CASE 'a' WHEN 'a' THEN 1 ELSE 2 END +-- +STMT: SelectStmt +== 023 +|-- +-- Examples of targets involving tables +|-- + +SELECT + CASE + WHEN i >= 3 THEN i + END AS ">= 3 or Null" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 024 +SELECT + CASE WHEN i >= 3 THEN (i + i) + ELSE i + END AS "Simplest Math" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 025 +SELECT i AS "Value", + CASE WHEN (i < 0) THEN 'small' + WHEN (i = 0) THEN 'zero' + WHEN (i = 1) THEN 'one' + WHEN (i = 2) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 026 +SELECT + CASE WHEN ((i < 0) or (i < 0)) THEN 'small' + WHEN ((i = 0) or (i = 0)) THEN 'zero' + WHEN ((i = 1) or (i = 1)) THEN 'one' + WHEN ((i = 2) or (i = 2)) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 027 +|-- +-- Examples of qualifications involving tables +|-- + +|-- +-- NULLIF() and COALESCE() +-- Shorthand forms for typical CASE constructs +-- defined in the SQL standard. +|-- + +SELECT * FROM CASE_TBL WHERE COALESCE(f,i) = 4 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +FILTER: schema="" table="" column="f" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 028 +SELECT * FROM CASE_TBL WHERE NULLIF(f,i) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +FILTER: schema="" table="" column="f" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 029 +SELECT COALESCE(a.f, b.i, b.j) + FROM CASE_TBL a, CASE2_TBL b +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +STMT: SelectStmt +== 030 +SELECT * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(a.f, b.i, b.j) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +FILTER: schema="" table="a" column="f" +FILTER: schema="" table="b" column="i" +FILTER: schema="" table="b" column="j" +STMT: SelectStmt +== 031 +SELECT NULLIF(a.i,b.i) AS "NULLIF(a.i,b.i)", + NULLIF(b.i, 4) AS "NULLIF(b.i,4)" + FROM CASE_TBL a, CASE2_TBL b +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +STMT: SelectStmt +== 032 +SELECT * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(f,b.i) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +FILTER: schema="" table="" column="f" +FILTER: schema="" table="b" column="i" +STMT: SelectStmt +== 033 +-- Tests for constant subexpression simplification + +explain (costs off) +SELECT * FROM CASE_TBL WHERE NULLIF(1, 2) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 034 +explain (costs off) +SELECT * FROM CASE_TBL WHERE NULLIF(1, 1) IS NOT NULL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 035 +explain (costs off) +SELECT * FROM CASE_TBL WHERE NULLIF(1, null) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 036 +|-- +-- Examples of updates involving tables +|-- + +UPDATE CASE_TBL + SET i = CASE WHEN i >= 3 THEN (- i) + ELSE (2 * i) END +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: UpdateStmt +== 037 +SELECT * FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 038 +UPDATE CASE_TBL + SET i = CASE WHEN i >= 2 THEN (2 * i) + ELSE (3 * i) END +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: UpdateStmt +== 039 +SELECT * FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 040 +UPDATE CASE_TBL + SET i = CASE WHEN b.i >= 2 THEN (2 * j) + ELSE (3 * j) END + FROM CASE2_TBL b + WHERE j = -CASE_TBL.i +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "b"="case2_tbl" +STMT: UpdateStmt +== 041 +SELECT * FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +== 042 +|-- +-- Nested CASE expressions +|-- + +-- This test exercises a bug caused by aliasing econtext->caseValue_isNull +-- with the isNull argument of the inner CASE's CaseExpr evaluation. After +-- evaluating the vol(null) expression in the inner CASE's second WHEN-clause, +-- the isNull flag for the case test value incorrectly became true, causing +-- the third WHEN-clause not to match. The volatile function calls are needed +-- to prevent constant-folding in the planner, which would hide the bug. + +-- Wrap this in a single transaction so the transient '=' operator doesn't +-- cause problems in concurrent sessions +BEGIN +-- +STMT: TransactionStmt +== 043 +CREATE FUNCTION vol(text) returns text as + 'begin return $1; end' language plpgsql volatile +-- +FUNCTION: name="vol" function="vol" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 044 +SELECT CASE + (CASE vol('bar') + WHEN 'foo' THEN 'it was foo!' + WHEN vol(null) THEN 'null input' + WHEN 'bar' THEN 'it was bar!' END + ) + WHEN 'it was foo!' THEN 'foo recognized' + WHEN 'it was bar!' THEN 'bar recognized' + ELSE 'unrecognized' END +-- +FUNCTION: name="vol" function="vol" schema="" ctx=Call +FUNCTION: name="vol" function="vol" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- In this case, we can't inline the SQL function without confusing things. +CREATE DOMAIN foodomain AS text +-- +STMT: CreateDomainStmt +== 046 +CREATE FUNCTION volfoo(text) returns foodomain as + 'begin return $1::foodomain; end' language plpgsql volatile +-- +FUNCTION: name="volfoo" function="volfoo" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 047 +CREATE FUNCTION inline_eq(foodomain, foodomain) returns boolean as + 'SELECT CASE $2::text WHEN $1::text THEN true ELSE false END' language sql +-- +FUNCTION: name="inline_eq" function="inline_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 048 +CREATE OPERATOR = (procedure = inline_eq, + leftarg = foodomain, rightarg = foodomain) +-- +STMT: DefineStmt +== 049 +SELECT CASE volfoo('bar') WHEN 'foo'::foodomain THEN 'is foo' ELSE 'is not foo' END +-- +FUNCTION: name="volfoo" function="volfoo" schema="" ctx=Call +STMT: SelectStmt +== 050 +ROLLBACK +-- +STMT: TransactionStmt +== 051 +-- Test multiple evaluation of a CASE arg that is a read/write object (#14472) +-- Wrap this in a single transaction so the transient '=' operator doesn't +-- cause problems in concurrent sessions +BEGIN +-- +STMT: TransactionStmt +== 052 +CREATE DOMAIN arrdomain AS int[] +-- +STMT: CreateDomainStmt +== 053 +CREATE FUNCTION make_ad(int,int) returns arrdomain as + 'declare x arrdomain; + begin + x := array[$1,$2]; + return x; + end' language plpgsql volatile +-- +FUNCTION: name="make_ad" function="make_ad" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 054 +CREATE FUNCTION ad_eq(arrdomain, arrdomain) returns boolean as + 'begin return array_eq($1, $2); end' language plpgsql +-- +FUNCTION: name="ad_eq" function="ad_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 055 +CREATE OPERATOR = (procedure = ad_eq, + leftarg = arrdomain, rightarg = arrdomain) +-- +STMT: DefineStmt +== 056 +SELECT CASE make_ad(1,2) + WHEN array[2,4]::arrdomain THEN 'wrong' + WHEN array[2,5]::arrdomain THEN 'still wrong' + WHEN array[1,2]::arrdomain THEN 'right' + END +-- +FUNCTION: name="make_ad" function="make_ad" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- While we're here, also test handling of a NULLIF arg that is a read/write +-- object (bug #18722) + +SELECT NULLIF(make_ad(1,2), array[2,3]::arrdomain) +-- +FUNCTION: name="make_ad" function="make_ad" schema="" ctx=Call +STMT: SelectStmt +== 058 +ROLLBACK +-- +STMT: TransactionStmt +== 059 +-- Test interaction of CASE with ArrayCoerceExpr (bug #15471) +BEGIN +-- +STMT: TransactionStmt +== 060 +CREATE TYPE casetestenum AS ENUM ('e', 'f', 'g') +-- +STMT: CreateEnumStmt +== 061 +SELECT + CASE 'foo'::text + WHEN 'foo' THEN ARRAY['a', 'b', 'c', 'd'] || enum_range(NULL::casetestenum)::text[] + ELSE ARRAY['x', 'y'] + END +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 062 +ROLLBACK +-- +STMT: TransactionStmt +== 063 +|-- +-- Clean up +|-- + +DROP TABLE CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DDL +STMT: DropStmt +== 064 +DROP TABLE CASE2_TBL +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/char.metadata.json b/parser/testdata/summary/postgres_regress/char.metadata.json new file mode 100644 index 0000000..efb3a10 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/char.metadata.json @@ -0,0 +1,36 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032" + ] +} diff --git a/parser/testdata/summary/postgres_regress/char.test b/parser/testdata/summary/postgres_regress/char.test new file mode 100644 index 0000000..b743663 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/char.test @@ -0,0 +1,212 @@ +== 001 +|-- +-- CHAR +|-- + +-- Per SQL standard, CHAR means character(1), that is a varlena type +-- with a constraint restricting it to one character (not byte) + +SELECT char 'c' = char 'c' AS true +-- +STMT: SelectStmt +== 002 +|-- +-- Build a table for testing +-- (This temporarily hides the table created in test_setup.sql) +|-- + +CREATE TEMP TABLE CHAR_TBL(f1 char) +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO CHAR_TBL (f1) VALUES ('a') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO CHAR_TBL (f1) VALUES ('A') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +-- any of the following three input formats are acceptable +INSERT INTO CHAR_TBL (f1) VALUES ('1') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO CHAR_TBL (f1) VALUES (2) +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO CHAR_TBL (f1) VALUES ('3') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- zero-length char +INSERT INTO CHAR_TBL (f1) VALUES ('') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- try char's of greater than 1 length +INSERT INTO CHAR_TBL (f1) VALUES ('cd') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO CHAR_TBL (f1) VALUES ('c ') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +SELECT * FROM CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +== 012 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 <> 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 013 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 = 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 014 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 < 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 015 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 <= 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 016 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 > 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 017 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 >= 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 018 +DROP TABLE CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: DropStmt +== 019 +|-- +-- Now test longer arrays of char +|-- +-- This char_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. +|-- + +INSERT INTO CHAR_TBL (f1) VALUES ('abcde') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +SELECT * FROM CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +== 021 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('abcd ', 'char(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT pg_input_is_valid('abcde', 'char(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT * FROM pg_input_error_info('abcde', 'char(4)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 024 +|-- +-- Also test "char", which is an ad-hoc one-byte type. It can only +-- really store ASCII characters, but we allow high-bit-set characters +-- to be accessed via bytea-like escapes. +|-- + +SELECT 'a'::"char" +-- +STMT: SelectStmt +== 025 +SELECT '\101'::"char" +-- +STMT: SelectStmt +== 026 +SELECT '\377'::"char" +-- +STMT: SelectStmt +== 027 +SELECT 'a'::"char"::text +-- +STMT: SelectStmt +== 028 +SELECT '\377'::"char"::text +-- +STMT: SelectStmt +== 029 +SELECT '\000'::"char"::text +-- +STMT: SelectStmt +== 030 +SELECT 'a'::text::"char" +-- +STMT: SelectStmt +== 031 +SELECT '\377'::text::"char" +-- +STMT: SelectStmt +== 032 +SELECT ''::text::"char" +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/circle.metadata.json b/parser/testdata/summary/postgres_regress/circle.metadata.json new file mode 100644 index 0000000..edb706f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/circle.metadata.json @@ -0,0 +1,26 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022" + ] +} diff --git a/parser/testdata/summary/postgres_regress/circle.test b/parser/testdata/summary/postgres_regress/circle.test new file mode 100644 index 0000000..a408bee --- /dev/null +++ b/parser/testdata/summary/postgres_regress/circle.test @@ -0,0 +1,158 @@ +== 001 +|-- +-- CIRCLE +|-- + +-- Back off displayed precision a little bit to reduce platform-to-platform +-- variation in results. +SET extra_float_digits = -1 +-- +STMT: VariableSetStmt +== 002 +CREATE TABLE CIRCLE_TBL (f1 circle) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO CIRCLE_TBL VALUES ('((1,2),100)') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO CIRCLE_TBL VALUES (' 1 , 3 , 5 ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO CIRCLE_TBL VALUES (' ( ( 1 , 2 ) , 3 ) ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO CIRCLE_TBL VALUES (' ( 100 , 200 ) , 10 ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO CIRCLE_TBL VALUES (' < ( 100 , 1 ) , 115 > ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),0>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +-- Zero radius + +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),NaN>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +-- NaN radius + +-- bad values + +INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10> x') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO CIRCLE_TBL VALUES ('(3,(1,2),3)') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +SELECT * FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +STMT: SelectStmt +== 017 +SELECT center(f1) AS center + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="center" function="center" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT radius(f1) AS radius + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT diameter(f1) AS diameter + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="diameter" function="diameter" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT f1 FROM CIRCLE_TBL WHERE radius(f1) < 5 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="radius" function="radius" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 021 +SELECT f1 FROM CIRCLE_TBL WHERE diameter(f1) >= 10 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="diameter" function="diameter" schema="" ctx=Call +FUNCTION: name="diameter" function="diameter" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 022 +SELECT c1.f1 AS one, c2.f1 AS two, (c1.f1 <-> c2.f1) AS distance + FROM CIRCLE_TBL c1, CIRCLE_TBL c2 + WHERE (c1.f1 < c2.f1) AND ((c1.f1 <-> c2.f1) > 0) + ORDER BY distance, area(c1.f1), area(c2.f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FUNCTION: name="area" function="area" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/cluster.metadata.json b/parser/testdata/summary/postgres_regress/cluster.metadata.json new file mode 100644 index 0000000..479ae3b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/cluster.metadata.json @@ -0,0 +1,208 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204" + ] +} diff --git a/parser/testdata/summary/postgres_regress/cluster.test b/parser/testdata/summary/postgres_regress/cluster.test new file mode 100644 index 0000000..3c8d187 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/cluster.test @@ -0,0 +1,1236 @@ +== 001 +|-- +-- CLUSTER +|-- + +CREATE TABLE clstr_tst_s (rf_a SERIAL PRIMARY KEY, + b INT) +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE clstr_tst (a SERIAL PRIMARY KEY, + b INT, + c TEXT, + d TEXT, + CONSTRAINT clstr_tst_con FOREIGN KEY (b) REFERENCES clstr_tst_s) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: CreateStmt +== 003 +CREATE INDEX clstr_tst_b ON clstr_tst (b) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +== 004 +CREATE INDEX clstr_tst_c ON clstr_tst (c) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +== 005 +CREATE INDEX clstr_tst_c_b ON clstr_tst (c,b) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +== 006 +CREATE INDEX clstr_tst_b_c ON clstr_tst (b,c) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +== 007 +INSERT INTO clstr_tst_s (b) VALUES (0) +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 013 +CREATE TABLE clstr_tst_inh () INHERITS (clstr_tst) +-- +TABLE: name="clstr_tst_inh" schema="" table="clstr_tst_inh" ctx=DDL +STMT: CreateStmt +== 014 +INSERT INTO clstr_tst (b, c) VALUES (11, 'once') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO clstr_tst (b, c) VALUES (10, 'diez') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO clstr_tst (b, c) VALUES (31, 'treinta y uno') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO clstr_tst (b, c) VALUES (22, 'veintidos') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO clstr_tst (b, c) VALUES (3, 'tres') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO clstr_tst (b, c) VALUES (20, 'veinte') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO clstr_tst (b, c) VALUES (23, 'veintitres') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO clstr_tst (b, c) VALUES (21, 'veintiuno') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO clstr_tst (b, c) VALUES (4, 'cuatro') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO clstr_tst (b, c) VALUES (14, 'catorce') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO clstr_tst (b, c) VALUES (2, 'dos') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO clstr_tst (b, c) VALUES (18, 'dieciocho') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO clstr_tst (b, c) VALUES (27, 'veintisiete') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO clstr_tst (b, c) VALUES (25, 'veinticinco') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO clstr_tst (b, c) VALUES (13, 'trece') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO clstr_tst (b, c) VALUES (28, 'veintiocho') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO clstr_tst (b, c) VALUES (32, 'treinta y dos') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO clstr_tst (b, c) VALUES (5, 'cinco') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO clstr_tst (b, c) VALUES (29, 'veintinueve') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO clstr_tst (b, c) VALUES (1, 'uno') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO clstr_tst (b, c) VALUES (24, 'veinticuatro') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO clstr_tst (b, c) VALUES (30, 'treinta') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO clstr_tst (b, c) VALUES (12, 'doce') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO clstr_tst (b, c) VALUES (17, 'diecisiete') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO clstr_tst (b, c) VALUES (9, 'nueve') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO clstr_tst (b, c) VALUES (19, 'diecinueve') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO clstr_tst (b, c) VALUES (26, 'veintiseis') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO clstr_tst (b, c) VALUES (15, 'quince') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO clstr_tst (b, c) VALUES (7, 'siete') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO clstr_tst (b, c) VALUES (16, 'dieciseis') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO clstr_tst (b, c) VALUES (8, 'ocho') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +-- This entry is needed to test that TOASTED values are copied correctly. +INSERT INTO clstr_tst (b, c, d) VALUES (6, 'seis', repeat('xyzzy', 100000)) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 046 +CLUSTER clstr_tst_c ON clstr_tst +-- +STMT: ClusterStmt +== 047 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY a +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 049 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY b +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY c +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 051 +-- Verify that inheritance link still works +INSERT INTO clstr_tst_inh VALUES (0, 100, 'in child table') +-- +TABLE: name="clstr_tst_inh" schema="" table="clstr_tst_inh" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 053 +-- Verify that foreign key link still works +INSERT INTO clstr_tst (b, c) VALUES (1111, 'this should fail') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +SELECT conname FROM pg_constraint WHERE conrelid = 'clstr_tst'::regclass +ORDER BY 1 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 055 +SELECT relname, relkind, + EXISTS(SELECT 1 FROM pg_class WHERE oid = c.reltoastrelid) AS hastoast +FROM pg_class c WHERE relname LIKE 'clstr_tst%' ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="c" column="reltoastrelid" +STMT: SelectStmt +== 056 +-- Verify that indisclustered is correctly set +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pg_class_2"="pg_class" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="pg_class_2" column="oid" +FILTER: schema="" table="pg_class_2" column="relname" +FILTER: schema="" table="" column="indisclustered" +STMT: SelectStmt +== 057 +-- Try changing indisclustered +ALTER TABLE clstr_tst CLUSTER ON clstr_tst_b_c +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: AlterTableStmt +== 058 +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pg_class_2"="pg_class" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="pg_class_2" column="oid" +FILTER: schema="" table="pg_class_2" column="relname" +FILTER: schema="" table="" column="indisclustered" +STMT: SelectStmt +== 059 +-- Try turning off all clustering +ALTER TABLE clstr_tst SET WITHOUT CLUSTER +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: AlterTableStmt +== 060 +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pg_class_2"="pg_class" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="pg_class_2" column="oid" +FILTER: schema="" table="pg_class_2" column="relname" +FILTER: schema="" table="" column="indisclustered" +STMT: SelectStmt +== 061 +-- Verify that toast tables are clusterable +CLUSTER pg_toast.pg_toast_826 USING pg_toast_826_index +-- +STMT: ClusterStmt +== 062 +-- Verify that clustering all tables does in fact cluster the right ones +CREATE USER regress_clstr_user +-- +STMT: CreateRoleStmt +== 063 +CREATE TABLE clstr_1 (a INT PRIMARY KEY) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DDL +STMT: CreateStmt +== 064 +CREATE TABLE clstr_2 (a INT PRIMARY KEY) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DDL +STMT: CreateStmt +== 065 +CREATE TABLE clstr_3 (a INT PRIMARY KEY) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DDL +STMT: CreateStmt +== 066 +ALTER TABLE clstr_1 OWNER TO regress_clstr_user +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DDL +STMT: AlterTableStmt +== 067 +ALTER TABLE clstr_3 OWNER TO regress_clstr_user +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DDL +STMT: AlterTableStmt +== 068 +GRANT SELECT ON clstr_2 TO regress_clstr_user +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DDL +STMT: GrantStmt +== 069 +INSERT INTO clstr_1 VALUES (2) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +INSERT INTO clstr_1 VALUES (1) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +INSERT INTO clstr_2 VALUES (2) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +INSERT INTO clstr_2 VALUES (1) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +INSERT INTO clstr_3 VALUES (2) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 074 +INSERT INTO clstr_3 VALUES (1) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +-- "CLUSTER " on a table that hasn't been clustered +CLUSTER clstr_2 +-- +STMT: ClusterStmt +== 076 +CLUSTER clstr_1_pkey ON clstr_1 +-- +STMT: ClusterStmt +== 077 +CLUSTER clstr_2 USING clstr_2_pkey +-- +STMT: ClusterStmt +== 078 +SELECT * FROM clstr_1 UNION ALL + SELECT * FROM clstr_2 UNION ALL + SELECT * FROM clstr_3 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=Select +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=Select +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=Select +STMT: SelectStmt +== 079 +-- revert to the original state +DELETE FROM clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: DeleteStmt +== 080 +DELETE FROM clstr_2 +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: DeleteStmt +== 081 +DELETE FROM clstr_3 +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: DeleteStmt +== 082 +INSERT INTO clstr_1 VALUES (2) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +INSERT INTO clstr_1 VALUES (1) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 084 +INSERT INTO clstr_2 VALUES (2) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 085 +INSERT INTO clstr_2 VALUES (1) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 086 +INSERT INTO clstr_3 VALUES (2) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +INSERT INTO clstr_3 VALUES (1) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +-- this user can only cluster clstr_1 and clstr_3, but the latter +-- has not been clustered +SET SESSION AUTHORIZATION regress_clstr_user +-- +STMT: VariableSetStmt +== 089 +SET client_min_messages = ERROR +-- +STMT: VariableSetStmt +== 090 +-- order of "skipping" warnings may vary +CLUSTER +-- +STMT: ClusterStmt +== 091 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 092 +SELECT * FROM clstr_1 UNION ALL + SELECT * FROM clstr_2 UNION ALL + SELECT * FROM clstr_3 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=Select +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=Select +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=Select +STMT: SelectStmt +== 093 +-- cluster a single table using the indisclustered bit previously set +DELETE FROM clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: DeleteStmt +== 094 +INSERT INTO clstr_1 VALUES (2) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +INSERT INTO clstr_1 VALUES (1) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +CLUSTER clstr_1 +-- +STMT: ClusterStmt +== 097 +SELECT * FROM clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=Select +STMT: SelectStmt +== 098 +-- Test MVCC-safety of cluster. There isn't much we can do to verify the +-- results with a single backend... + +CREATE TABLE clustertest (key int PRIMARY KEY) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: CreateStmt +== 099 +INSERT INTO clustertest VALUES (10) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 100 +INSERT INTO clustertest VALUES (20) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +INSERT INTO clustertest VALUES (30) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 102 +INSERT INTO clustertest VALUES (40) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +INSERT INTO clustertest VALUES (50) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +-- Use a transaction so that updates are not committed when CLUSTER sees 'em +BEGIN +-- +STMT: TransactionStmt +== 105 +-- Test update where the old row version is found first in the scan +UPDATE clustertest SET key = 100 WHERE key = 10 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +== 106 +-- Test update where the new row version is found first in the scan +UPDATE clustertest SET key = 35 WHERE key = 40 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +== 107 +-- Test longer update chain +UPDATE clustertest SET key = 60 WHERE key = 50 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +== 108 +UPDATE clustertest SET key = 70 WHERE key = 60 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +== 109 +UPDATE clustertest SET key = 80 WHERE key = 70 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +== 110 +SELECT * FROM clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=Select +STMT: SelectStmt +== 111 +CLUSTER clustertest_pkey ON clustertest +-- +STMT: ClusterStmt +== 112 +SELECT * FROM clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=Select +STMT: SelectStmt +== 113 +COMMIT +-- +STMT: TransactionStmt +== 114 +SELECT * FROM clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=Select +STMT: SelectStmt +== 115 +-- check that temp tables can be clustered +create temp table clstr_temp (col1 int primary key, col2 text) +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=DDL +STMT: CreateStmt +== 116 +insert into clstr_temp values (2, 'two'), (1, 'one') +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +cluster clstr_temp using clstr_temp_pkey +-- +STMT: ClusterStmt +== 118 +select * from clstr_temp +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=Select +STMT: SelectStmt +== 119 +drop table clstr_temp +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=DDL +STMT: DropStmt +== 120 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 121 +-- check clustering an empty table +DROP TABLE clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: DropStmt +== 122 +CREATE TABLE clustertest (f1 int PRIMARY KEY) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: CreateStmt +== 123 +CLUSTER clustertest USING clustertest_pkey +-- +STMT: ClusterStmt +== 124 +CLUSTER clustertest +-- +STMT: ClusterStmt +== 125 +-- Check that partitioned tables can be clustered +CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: CreateStmt +== 126 +CREATE TABLE clstrpart1 PARTITION OF clstrpart FOR VALUES FROM (1) TO (10) PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart1" schema="" table="clstrpart1" ctx=DDL +STMT: CreateStmt +== 127 +CREATE TABLE clstrpart11 PARTITION OF clstrpart1 FOR VALUES FROM (1) TO (5) +-- +TABLE: name="clstrpart11" schema="" table="clstrpart11" ctx=DDL +STMT: CreateStmt +== 128 +CREATE TABLE clstrpart12 PARTITION OF clstrpart1 FOR VALUES FROM (5) TO (10) PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart12" schema="" table="clstrpart12" ctx=DDL +STMT: CreateStmt +== 129 +CREATE TABLE clstrpart2 PARTITION OF clstrpart FOR VALUES FROM (10) TO (20) +-- +TABLE: name="clstrpart2" schema="" table="clstrpart2" ctx=DDL +STMT: CreateStmt +== 130 +CREATE TABLE clstrpart3 PARTITION OF clstrpart DEFAULT PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart3" schema="" table="clstrpart3" ctx=DDL +STMT: CreateStmt +== 131 +CREATE TABLE clstrpart33 PARTITION OF clstrpart3 DEFAULT +-- +TABLE: name="clstrpart33" schema="" table="clstrpart33" ctx=DDL +STMT: CreateStmt +== 132 +CREATE INDEX clstrpart_only_idx ON ONLY clstrpart (a) +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: IndexStmt +== 133 +CLUSTER clstrpart USING clstrpart_only_idx +-- +STMT: ClusterStmt +== 134 +-- fails +DROP INDEX clstrpart_only_idx +-- +STMT: DropStmt +== 135 +CREATE INDEX clstrpart_idx ON clstrpart (a) +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: IndexStmt +== 136 +-- Check that clustering sets new relfilenodes: +CREATE TEMP TABLE old_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid +-- +TABLE: name="old_cluster_info" schema="" table="old_cluster_info" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 137 +CLUSTER clstrpart USING clstrpart_idx +-- +STMT: ClusterStmt +== 138 +CREATE TEMP TABLE new_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid +-- +TABLE: name="new_cluster_info" schema="" table="new_cluster_info" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 139 +SELECT relname, old.level, old.relkind, old.relfilenode = new.relfilenode FROM old_cluster_info AS old JOIN new_cluster_info AS new USING (relname) ORDER BY relname COLLATE "C" +-- +TABLE: name="old_cluster_info" schema="" table="old_cluster_info" ctx=Select +TABLE: name="new_cluster_info" schema="" table="new_cluster_info" ctx=Select +ALIAS: "new"="new_cluster_info" +ALIAS: "old"="old_cluster_info" +STMT: SelectStmt +== 140 +-- Partitioned indexes aren't and can't be marked un/clustered: +CLUSTER clstrpart +-- +STMT: ClusterStmt +== 141 +ALTER TABLE clstrpart SET WITHOUT CLUSTER +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: AlterTableStmt +== 142 +ALTER TABLE clstrpart CLUSTER ON clstrpart_idx +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: AlterTableStmt +== 143 +DROP TABLE clstrpart +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: DropStmt +== 144 +-- Ownership of partitions is checked +CREATE TABLE ptnowner(i int unique) PARTITION BY LIST (i) +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: CreateStmt +== 145 +CREATE INDEX ptnowner_i_idx ON ptnowner(i) +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: IndexStmt +== 146 +CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1) +-- +TABLE: name="ptnowner1" schema="" table="ptnowner1" ctx=DDL +STMT: CreateStmt +== 147 +CREATE ROLE regress_ptnowner +-- +STMT: CreateRoleStmt +== 148 +CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2) +-- +TABLE: name="ptnowner2" schema="" table="ptnowner2" ctx=DDL +STMT: CreateStmt +== 149 +ALTER TABLE ptnowner1 OWNER TO regress_ptnowner +-- +TABLE: name="ptnowner1" schema="" table="ptnowner1" ctx=DDL +STMT: AlterTableStmt +== 150 +SET SESSION AUTHORIZATION regress_ptnowner +-- +STMT: VariableSetStmt +== 151 +CLUSTER ptnowner USING ptnowner_i_idx +-- +STMT: ClusterStmt +== 152 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 153 +ALTER TABLE ptnowner OWNER TO regress_ptnowner +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: AlterTableStmt +== 154 +CREATE TEMP TABLE ptnowner_oldnodes AS + SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree + JOIN pg_class AS c ON c.oid=tree.relid +-- +TABLE: name="ptnowner_oldnodes" schema="" table="ptnowner_oldnodes" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 155 +SET SESSION AUTHORIZATION regress_ptnowner +-- +STMT: VariableSetStmt +== 156 +CLUSTER ptnowner USING ptnowner_i_idx +-- +STMT: ClusterStmt +== 157 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 158 +SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a + JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="ptnowner_oldnodes" schema="" table="ptnowner_oldnodes" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="ptnowner_oldnodes" +STMT: SelectStmt +== 159 +DROP TABLE ptnowner +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: DropStmt +== 160 +DROP ROLE regress_ptnowner +-- +STMT: DropRoleStmt +== 161 +-- Test CLUSTER with external tuplesorting + +create table clstr_4 as select * from tenk1 +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 162 +create index cluster_sort on clstr_4 (hundred, thousand, tenthous) +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=DDL +STMT: IndexStmt +== 163 +-- ensure we don't use the index in CLUSTER nor the checking SELECTs +set enable_indexscan = off +-- +STMT: VariableSetStmt +== 164 +-- Use external sort: +set maintenance_work_mem = '1MB' +-- +STMT: VariableSetStmt +== 165 +cluster clstr_4 using cluster_sort +-- +STMT: ClusterStmt +== 166 +select * from +(select hundred, lag(hundred) over () as lhundred, + thousand, lag(thousand) over () as lthousand, + tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss +where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous) +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="lhundred" +FILTER: schema="" table="" column="lthousand" +FILTER: schema="" table="" column="ltenthous" +STMT: SelectStmt +== 167 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 168 +reset maintenance_work_mem +-- +STMT: VariableSetStmt +== 169 +-- test CLUSTER on expression index +CREATE TABLE clstr_expression(id serial primary key, a int, b text COLLATE "C") +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +STMT: CreateStmt +== 170 +INSERT INTO clstr_expression(a, b) SELECT g.i % 42, 'prefix'||g.i FROM generate_series(1, 133) g(i) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 171 +CREATE INDEX clstr_expression_minus_a ON clstr_expression ((-a), b) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +STMT: IndexStmt +== 172 +CREATE INDEX clstr_expression_upper_b ON clstr_expression ((upper(b))) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: IndexStmt +== 173 +-- verify indexes work before cluster +BEGIN +-- +STMT: TransactionStmt +== 174 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +== 175 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 176 +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 177 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 178 +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 179 +COMMIT +-- +STMT: TransactionStmt +== 180 +-- and after clustering on clstr_expression_minus_a +CLUSTER clstr_expression USING clstr_expression_minus_a +-- +STMT: ClusterStmt +== 181 +WITH rows AS + (SELECT ctid, lag(a) OVER (ORDER BY ctid) AS la, a FROM clstr_expression) +SELECT * FROM rows WHERE la < a +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +CTE: "rows" +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="la" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 182 +BEGIN +-- +STMT: TransactionStmt +== 183 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +== 184 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 185 +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 186 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 187 +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 188 +COMMIT +-- +STMT: TransactionStmt +== 189 +-- and after clustering on clstr_expression_upper_b +CLUSTER clstr_expression USING clstr_expression_upper_b +-- +STMT: ClusterStmt +== 190 +WITH rows AS + (SELECT ctid, lag(b) OVER (ORDER BY ctid) AS lb, b FROM clstr_expression) +SELECT * FROM rows WHERE upper(lb) > upper(b) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +CTE: "rows" +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="lb" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 191 +BEGIN +-- +STMT: TransactionStmt +== 192 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +== 193 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 194 +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 195 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 196 +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 197 +COMMIT +-- +STMT: TransactionStmt +== 198 +-- clean up +DROP TABLE clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: DropStmt +== 199 +DROP TABLE clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DDL +STMT: DropStmt +== 200 +DROP TABLE clstr_2 +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DDL +STMT: DropStmt +== 201 +DROP TABLE clstr_3 +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DDL +STMT: DropStmt +== 202 +DROP TABLE clstr_4 +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=DDL +STMT: DropStmt +== 203 +DROP TABLE clstr_expression +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +STMT: DropStmt +== 204 +DROP USER regress_clstr_user +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json b/parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json new file mode 100644 index 0000000..faccb98 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json @@ -0,0 +1,505 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501" + ] +} diff --git a/parser/testdata/summary/postgres_regress/collate.icu.utf8.test b/parser/testdata/summary/postgres_regress/collate.icu.utf8.test new file mode 100644 index 0000000..0525cf2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.icu.utf8.test @@ -0,0 +1,2980 @@ +== 001 +/* + * This test is for ICU collations. + */ + +/* skip test if not UTF8 server encoding or no ICU collations installed */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collprovider = 'i' AND collname <> 'unicode') = 0 + AS skip_test +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="collprovider" +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 002 +SET client_encoding TO UTF8 +-- +STMT: VariableSetStmt +== 003 +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +== 004 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +== 005 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en-x-icu" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +== 006 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp-x-icu" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 007 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo-x-icu" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE collate_test_fail ( + a int COLLATE "en-x-icu", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 009 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +== 010 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv-x-icu" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +== 011 +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +) +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DDL +STMT: CreateStmt +== 012 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO collate_test3 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 015 +SELECT * FROM collate_test1 WHERE b >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 016 +SELECT * FROM collate_test2 WHERE b >= 'bbc' +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 017 +SELECT * FROM collate_test3 WHERE b >= 'bbc' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 018 +SELECT * FROM collate_test3 WHERE b >= 'BBC' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 019 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 020 +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 021 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 022 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en-x-icu" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 023 +CREATE DOMAIN testdomain_sv AS text COLLATE "sv-x-icu" +-- +STMT: CreateDomainStmt +== 024 +CREATE DOMAIN testdomain_i AS int COLLATE "sv-x-icu" +-- +STMT: CreateDomainStmt +== 025 +-- fails +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +== 026 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 027 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +== 028 +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en-x-icu" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +== 029 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 030 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +== 031 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 032 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 033 +SELECT a, b FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 034 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 035 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 036 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 037 +SELECT * FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 038 +-- constant expression folding +SELECT 'bbc' COLLATE "en-x-icu" > 'äbc' COLLATE "en-x-icu" AS "true" +-- +STMT: SelectStmt +== 039 +SELECT 'bbc' COLLATE "sv-x-icu" > 'äbc' COLLATE "sv-x-icu" AS "false" +-- +STMT: SelectStmt +== 040 +-- upper/lower + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "en-x-icu", + y text COLLATE "tr-x-icu" +) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DDL +STMT: CreateStmt +== 041 +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ') +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- LIKE/ILIKE + +SELECT * FROM collate_test1 WHERE b LIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 046 +SELECT * FROM collate_test1 WHERE b LIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 047 +SELECT * FROM collate_test1 WHERE b LIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 048 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 049 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 050 +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 051 +SELECT 'Türkiye' COLLATE "en-x-icu" ILIKE '%KI%' AS "true" +-- +STMT: SelectStmt +== 052 +SELECT 'Türkiye' COLLATE "tr-x-icu" ILIKE '%KI%' AS "false" +-- +STMT: SelectStmt +== 053 +SELECT 'bıt' ILIKE 'BIT' COLLATE "en-x-icu" AS "false" +-- +STMT: SelectStmt +== 054 +SELECT 'bıt' ILIKE 'BIT' COLLATE "tr-x-icu" AS "true" +-- +STMT: SelectStmt +== 055 +-- The following actually exercises the selectivity estimation for ILIKE. +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 056 +-- regular expressions + +SELECT * FROM collate_test1 WHERE b ~ '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 057 +SELECT * FROM collate_test1 WHERE b ~ '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 058 +SELECT * FROM collate_test1 WHERE b ~ 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 059 +SELECT * FROM collate_test1 WHERE b ~* '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 060 +SELECT * FROM collate_test1 WHERE b ~* '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 061 +SELECT * FROM collate_test1 WHERE b ~* 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 062 +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en-x-icu" +) +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DDL +STMT: CreateStmt +== 063 +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, 'äbç'), (10, 'ÄBÇ') +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +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 +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=Select +STMT: SelectStmt +== 065 +SELECT 'Türkiye' COLLATE "en-x-icu" ~* 'KI' AS "true" +-- +STMT: SelectStmt +== 066 +SELECT 'Türkiye' COLLATE "tr-x-icu" ~* 'KI' AS "true" +-- +STMT: SelectStmt +== 067 +-- true with ICU + +SELECT 'bıt' ~* 'BIT' COLLATE "en-x-icu" AS "false" +-- +STMT: SelectStmt +== 068 +SELECT 'bıt' ~* 'BIT' COLLATE "tr-x-icu" AS "false" +-- +STMT: SelectStmt +== 069 +-- false with ICU + +-- The following actually exercises the selectivity estimation for ~*. +SELECT relname FROM pg_class WHERE relname ~* '^abc' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 070 +/* 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' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 071 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 072 +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10 +-- +TABLE: name="collview3" schema="" table="collview3" ctx=DDL +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 073 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 074 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 075 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 076 +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 077 +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 079 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 080 +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 081 +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 083 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 084 +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 085 +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 087 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 088 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 089 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +== 090 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 091 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 092 +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 093 +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 094 +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 095 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 096 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 097 +SELECT min(b), max(b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 098 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 099 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 100 +SELECT array_agg(b ORDER BY b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 101 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 102 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 103 +SELECT a, b FROM collate_test3 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 104 +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 105 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 106 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 107 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 108 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 109 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 110 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 111 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 112 +-- fail + +-- ideally this would be a parse-time error, but for now it must be run-time: +select x < y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 113 +-- fail +select x || y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 114 +-- ok, because || is not collation aware +select x, y from collate_test10 order by x || y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 115 +-- not so ok + +-- 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 +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 116 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 117 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 118 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 119 +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 120 +-- 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 $$ +-- +FUNCTION: name="mylt" function="mylt" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 121 +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$ +-- +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 122 +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$ +-- +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 123 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +== 124 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +== 125 +-- 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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 126 +SELECT mylt2('a', 'B' collate "en-x-icu") as t, mylt2('a', 'B' collate "C") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 127 +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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 128 +SELECT mylt2('a', 'B') as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 129 +SELECT mylt2('a', 'B' collate "C") as fail +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 130 +-- conflicting collations +SELECT mylt2('a', 'B' collate "POSIX") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 131 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 132 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 133 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 134 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 135 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 136 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 137 +SELECT a, dup(b) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 138 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 139 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 140 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 141 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 142 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 143 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 144 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 145 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 146 +explain (costs off) +select * from collate_test1 where b ilike 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 147 +select * from collate_test1 where b ilike 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 148 +explain (costs off) +select * from collate_test1 where b ilike 'ABC' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 149 +select * from collate_test1 where b ilike 'ABC' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 150 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 151 +-- schema manipulation commands + +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +== 152 +CREATE SCHEMA test_schema +-- +STMT: CreateSchemaStmt +== 153 +-- We need to do this this way to cope with varying names for encodings: +SET client_min_messages TO WARNING +-- +STMT: VariableSetStmt +== 154 +SET icu_validation_level = disabled +-- +STMT: VariableSetStmt +== 155 +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' || + quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +== 156 +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +== 157 +-- fail, duplicate name +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' || + quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +== 158 +RESET icu_validation_level +-- +STMT: VariableSetStmt +== 159 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 160 +CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8') +-- +STMT: DefineStmt +== 161 +-- fail, needs "locale" +SET icu_validation_level = ERROR +-- +STMT: VariableSetStmt +== 162 +CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere') +-- +STMT: DefineStmt +== 163 +-- fails +CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes') +-- +STMT: DefineStmt +== 164 +-- fails +RESET icu_validation_level +-- +STMT: VariableSetStmt +== 165 +CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes') +-- +STMT: DefineStmt +== 166 +DROP COLLATION testx +-- +STMT: DropStmt +== 167 +CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere') +-- +STMT: DefineStmt +== 168 +DROP COLLATION testx +-- +STMT: DropStmt +== 169 +CREATE COLLATION test4 FROM nonsense +-- +STMT: DefineStmt +== 170 +CREATE COLLATION test5 FROM test0 +-- +STMT: DefineStmt +== 171 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 172 +ALTER COLLATION test1 RENAME TO test11 +-- +STMT: RenameStmt +== 173 +ALTER COLLATION test0 RENAME TO test11 +-- +STMT: RenameStmt +== 174 +-- fail +ALTER COLLATION test1 RENAME TO test22 +-- +STMT: RenameStmt +== 175 +-- fail + +ALTER COLLATION test11 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 176 +ALTER COLLATION test11 OWNER TO nonsense +-- +STMT: AlterOwnerStmt +== 177 +ALTER COLLATION test11 SET SCHEMA test_schema +-- +STMT: AlterObjectSchemaStmt +== 178 +COMMENT ON COLLATION test0 IS 'US English' +-- +STMT: CommentStmt +== 179 +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 180 +DROP COLLATION test0, test_schema.test11, test5 +-- +STMT: DropStmt +== 181 +DROP COLLATION test0 +-- +STMT: DropStmt +== 182 +-- fail +DROP COLLATION IF EXISTS test0 +-- +STMT: DropStmt +== 183 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 184 +DROP SCHEMA test_schema +-- +STMT: DropStmt +== 185 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +== 186 +-- ALTER + +ALTER COLLATION "en-x-icu" REFRESH VERSION +-- +STMT: AlterCollationStmt +== 187 +-- also test for database while we are here +SELECT current_database() AS datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +== 188 +ALTER DATABASE :"datname" REFRESH COLLATION VERSION +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 189 +-- dependencies + +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +== 190 +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0) +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +STMT: CreateStmt +== 191 +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0 +-- +STMT: CreateDomainStmt +== 192 +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0) +-- +STMT: CompositeTypeStmt +== 193 +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo +-- +TABLE: name="collate_dep_test3" schema="" table="collate_dep_test3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 194 +CREATE TABLE collate_dep_test4t (a int, b text) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: CreateStmt +== 195 +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: IndexStmt +== 196 +DROP COLLATION test0 RESTRICT +-- +STMT: DropStmt +== 197 +-- fail +DROP COLLATION test0 CASCADE +-- +STMT: DropStmt +== 198 +DROP TABLE collate_dep_test1, collate_dep_test4t +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: DropStmt +== 199 +DROP TYPE collate_dep_test2 +-- +STMT: DropStmt +== 200 +-- test range types and collations + +create type textrange_c as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +== 201 +create type textrange_en_us as range(subtype=text, collation="en-x-icu") +-- +STMT: CreateRangeStmt +== 202 +select textrange_c('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_c" function="textrange_c" schema="" ctx=Call +STMT: SelectStmt +== 203 +select textrange_en_us('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_en_us" function="textrange_en_us" schema="" ctx=Call +STMT: SelectStmt +== 204 +drop type textrange_c +-- +STMT: DropStmt +== 205 +drop type textrange_en_us +-- +STMT: DropStmt +== 206 +-- standard collations + +SELECT * FROM collate_test2 ORDER BY b COLLATE UCS_BASIC +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 207 +SELECT * FROM collate_test2 ORDER BY b COLLATE UNICODE +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 208 +-- test ICU collation customization + +-- test the attributes handled by icu_set_collation_attributes() + +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +== 209 +CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes') +-- +STMT: DefineStmt +== 210 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 211 +SELECT 'aaá' > 'AAA' COLLATE "und-x-icu", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents +-- +STMT: SelectStmt +== 212 +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +== 213 +CREATE COLLATION testcoll_backwards (provider = icu, locale = '@colBackwards=yes') +-- +STMT: DefineStmt +== 214 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 215 +SELECT 'coté' < 'côte' COLLATE "und-x-icu", 'coté' > 'côte' COLLATE testcoll_backwards +-- +STMT: SelectStmt +== 216 +CREATE COLLATION testcoll_lower_first (provider = icu, locale = '@colCaseFirst=lower') +-- +STMT: DefineStmt +== 217 +CREATE COLLATION testcoll_upper_first (provider = icu, locale = '@colCaseFirst=upper') +-- +STMT: DefineStmt +== 218 +SELECT 'aaa' < 'AAA' COLLATE testcoll_lower_first, 'aaa' > 'AAA' COLLATE testcoll_upper_first +-- +STMT: SelectStmt +== 219 +CREATE COLLATION testcoll_shifted (provider = icu, locale = '@colAlternate=shifted') +-- +STMT: DefineStmt +== 220 +SELECT 'de-luge' < 'deanza' COLLATE "und-x-icu", 'de-luge' > 'deanza' COLLATE testcoll_shifted +-- +STMT: SelectStmt +== 221 +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +== 222 +CREATE COLLATION testcoll_numeric (provider = icu, locale = '@colNumeric=yes') +-- +STMT: DefineStmt +== 223 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 224 +SELECT 'A-21' > 'A-123' COLLATE "und-x-icu", 'A-21' < 'A-123' COLLATE testcoll_numeric +-- +STMT: SelectStmt +== 225 +CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower') +-- +STMT: DefineStmt +== 226 +-- test that attributes not handled by icu_set_collation_attributes() +-- (handled by ucol_open() directly) also work +CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook') +-- +STMT: DefineStmt +== 227 +SELECT 'Goldmann' < 'Götz' COLLATE "de-x-icu", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook +-- +STMT: SelectStmt +== 228 +-- rules + +CREATE COLLATION testcoll_rules1 (provider = icu, locale = '', rules = '&a < g') +-- +STMT: DefineStmt +== 229 +CREATE TABLE test7 (a text) +-- +TABLE: name="test7" schema="" table="test7" ctx=DDL +STMT: CreateStmt +== 230 +-- example from https://unicode-org.github.io/icu/userguide/collation/customization/#syntax +INSERT INTO test7 VALUES ('Abernathy'), ('apple'), ('bird'), ('Boston'), ('Graham'), ('green') +-- +TABLE: name="test7" schema="" table="test7" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 231 +SELECT * FROM test7 ORDER BY a COLLATE "en-x-icu" +-- +TABLE: name="test7" schema="" table="test7" ctx=Select +STMT: SelectStmt +== 232 +SELECT * FROM test7 ORDER BY a COLLATE testcoll_rules1 +-- +TABLE: name="test7" schema="" table="test7" ctx=Select +STMT: SelectStmt +== 233 +DROP TABLE test7 +-- +TABLE: name="test7" schema="" table="test7" ctx=DDL +STMT: DropStmt +== 234 +CREATE COLLATION testcoll_rulesx (provider = icu, locale = '', rules = '!!wrong!!') +-- +STMT: DefineStmt +== 235 +-- nondeterministic collations + +CREATE COLLATION ctest_det (provider = icu, locale = '', deterministic = true) +-- +STMT: DefineStmt +== 236 +CREATE COLLATION ctest_nondet (provider = icu, locale = '', deterministic = false) +-- +STMT: DefineStmt +== 237 +CREATE TABLE test6 (a int, b text) +-- +TABLE: name="test6" schema="" table="test6" ctx=DDL +STMT: CreateStmt +== 238 +-- same string in different normal forms +INSERT INTO test6 VALUES (1, U&'\00E4bc') +-- +TABLE: name="test6" schema="" table="test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 239 +INSERT INTO test6 VALUES (2, U&'\0061\0308bc') +-- +TABLE: name="test6" schema="" table="test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +SELECT * FROM test6 +-- +TABLE: name="test6" schema="" table="test6" ctx=Select +STMT: SelectStmt +== 241 +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_det +-- +TABLE: name="test6" schema="" table="test6" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 242 +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_nondet +-- +TABLE: name="test6" schema="" table="test6" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 243 +-- same with arrays +CREATE TABLE test6a (a int, b text[]) +-- +TABLE: name="test6a" schema="" table="test6a" ctx=DDL +STMT: CreateStmt +== 244 +INSERT INTO test6a VALUES (1, ARRAY[U&'\00E4bc']) +-- +TABLE: name="test6a" schema="" table="test6a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +INSERT INTO test6a VALUES (2, ARRAY[U&'\0061\0308bc']) +-- +TABLE: name="test6a" schema="" table="test6a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 246 +SELECT * FROM test6a +-- +TABLE: name="test6a" schema="" table="test6a" ctx=Select +STMT: SelectStmt +== 247 +SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_det +-- +TABLE: name="test6a" schema="" table="test6a" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 248 +SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_nondet +-- +TABLE: name="test6a" schema="" table="test6a" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 249 +CREATE COLLATION case_sensitive (provider = icu, locale = '') +-- +STMT: DefineStmt +== 250 +CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', deterministic = false) +-- +STMT: DefineStmt +== 251 +SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive +-- +STMT: SelectStmt +== 252 +SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive +-- +STMT: SelectStmt +== 253 +-- test language tags +CREATE COLLATION lt_insensitive (provider = icu, locale = 'en-u-ks-level1', deterministic = false) +-- +STMT: DefineStmt +== 254 +SELECT 'aBcD' COLLATE lt_insensitive = 'AbCd' COLLATE lt_insensitive +-- +STMT: SelectStmt +== 255 +CREATE COLLATION lt_upperfirst (provider = icu, locale = 'und-u-kf-upper') +-- +STMT: DefineStmt +== 256 +SELECT 'Z' COLLATE lt_upperfirst < 'z' COLLATE lt_upperfirst +-- +STMT: SelectStmt +== 257 +CREATE TABLE test1cs (x text COLLATE case_sensitive) +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DDL +STMT: CreateStmt +== 258 +CREATE TABLE test2cs (x text COLLATE case_sensitive) +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=DDL +STMT: CreateStmt +== 259 +CREATE TABLE test3cs (x text COLLATE case_sensitive) +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=DDL +STMT: CreateStmt +== 260 +INSERT INTO test1cs VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 261 +INSERT INTO test2cs VALUES ('ABC'), ('ghi') +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 262 +INSERT INTO test3cs VALUES ('abc'), ('ABC'), ('def'), ('ghi') +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 263 +SELECT x FROM test3cs WHERE x = 'abc' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 264 +SELECT x FROM test3cs WHERE x <> 'abc' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 265 +SELECT x FROM test3cs WHERE x LIKE 'a%' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 266 +SELECT x FROM test3cs WHERE x ILIKE 'a%' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 267 +SELECT x FROM test3cs WHERE x SIMILAR TO 'a%' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 268 +SELECT x FROM test3cs WHERE x ~ 'a' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 269 +SET enable_hashagg TO off +-- +STMT: VariableSetStmt +== 270 +SELECT x FROM test1cs UNION SELECT x FROM test2cs ORDER BY x +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +STMT: SelectStmt +== 271 +SELECT x FROM test2cs UNION SELECT x FROM test1cs ORDER BY x +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +STMT: SelectStmt +== 272 +SELECT x FROM test1cs INTERSECT SELECT x FROM test2cs +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +STMT: SelectStmt +== 273 +SELECT x FROM test2cs INTERSECT SELECT x FROM test1cs +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +STMT: SelectStmt +== 274 +SELECT x FROM test1cs EXCEPT SELECT x FROM test2cs +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +STMT: SelectStmt +== 275 +SELECT x FROM test2cs EXCEPT SELECT x FROM test1cs +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +STMT: SelectStmt +== 276 +SELECT DISTINCT x FROM test3cs ORDER BY x +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +STMT: SelectStmt +== 277 +RESET enable_hashagg +-- +STMT: VariableSetStmt +== 278 +SELECT count(DISTINCT x) FROM test3cs +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 279 +SELECT x, count(*) FROM test3cs GROUP BY x ORDER BY x +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 280 +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3cs ORDER BY x +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 281 +CREATE UNIQUE INDEX ON test1cs (x) +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DDL +STMT: IndexStmt +== 282 +-- ok +INSERT INTO test1cs VALUES ('ABC') +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +-- ok +CREATE UNIQUE INDEX ON test3cs (x) +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=DDL +STMT: IndexStmt +== 284 +-- ok +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_sensitive, ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 285 +SELECT string_to_array('ABCDEFGHI' COLLATE case_sensitive, NULL, 'b') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 286 +CREATE TABLE test1ci (x text COLLATE case_insensitive) +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DDL +STMT: CreateStmt +== 287 +CREATE TABLE test2ci (x text COLLATE case_insensitive) +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=DDL +STMT: CreateStmt +== 288 +CREATE TABLE test3ci (x text COLLATE case_insensitive) +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DDL +STMT: CreateStmt +== 289 +CREATE INDEX ON test3ci (x text_pattern_ops) +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DDL +STMT: IndexStmt +== 290 +-- error +INSERT INTO test1ci VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 291 +INSERT INTO test2ci VALUES ('ABC'), ('ghi') +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 292 +INSERT INTO test3ci VALUES ('abc'), ('ABC'), ('def'), ('ghi') +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +SELECT x FROM test3ci WHERE x = 'abc' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 294 +SELECT x FROM test3ci WHERE x <> 'abc' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 295 +SELECT x FROM test3ci WHERE x LIKE 'a%' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 296 +SELECT x FROM test3ci WHERE x ILIKE 'a%' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 297 +SELECT x FROM test3ci WHERE x SIMILAR TO 'a%' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 298 +SELECT x FROM test3ci WHERE x ~ 'a' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 299 +SELECT x FROM test1ci UNION SELECT x FROM test2ci ORDER BY x +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +STMT: SelectStmt +== 300 +SELECT x FROM test2ci UNION SELECT x FROM test1ci ORDER BY x +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +STMT: SelectStmt +== 301 +SELECT x FROM test1ci INTERSECT SELECT x FROM test2ci ORDER BY x +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +STMT: SelectStmt +== 302 +SELECT x FROM test2ci INTERSECT SELECT x FROM test1ci ORDER BY x +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +STMT: SelectStmt +== 303 +SELECT x FROM test1ci EXCEPT SELECT x FROM test2ci +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +STMT: SelectStmt +== 304 +SELECT x FROM test2ci EXCEPT SELECT x FROM test1ci +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +STMT: SelectStmt +== 305 +SELECT DISTINCT x FROM test3ci ORDER BY x +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +STMT: SelectStmt +== 306 +SELECT count(DISTINCT x) FROM test3ci +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 307 +SELECT x, count(*) FROM test3ci GROUP BY x ORDER BY x +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 308 +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3ci ORDER BY x +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 309 +CREATE UNIQUE INDEX ON test1ci (x) +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DDL +STMT: IndexStmt +== 310 +-- ok +INSERT INTO test1ci VALUES ('ABC') +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 311 +-- error +CREATE UNIQUE INDEX ON test3ci (x) +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DDL +STMT: IndexStmt +== 312 +-- error +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 313 +SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 314 +-- bpchar +CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive) +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DDL +STMT: CreateStmt +== 315 +CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive) +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=DDL +STMT: CreateStmt +== 316 +CREATE TABLE test3bpci (x char(3) COLLATE case_insensitive) +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DDL +STMT: CreateStmt +== 317 +CREATE INDEX ON test3bpci (x bpchar_pattern_ops) +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DDL +STMT: IndexStmt +== 318 +-- error +INSERT INTO test1bpci VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 319 +INSERT INTO test2bpci VALUES ('ABC'), ('ghi') +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 320 +INSERT INTO test3bpci VALUES ('abc'), ('ABC'), ('def'), ('ghi') +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 321 +SELECT x FROM test3bpci WHERE x = 'abc' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 322 +SELECT x FROM test3bpci WHERE x <> 'abc' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 323 +SELECT x FROM test3bpci WHERE x LIKE 'a%' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 324 +SELECT x FROM test3bpci WHERE x ILIKE 'a%' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 325 +SELECT x FROM test3bpci WHERE x SIMILAR TO 'a%' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 326 +SELECT x FROM test3bpci WHERE x ~ 'a' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 327 +SELECT x FROM test1bpci UNION SELECT x FROM test2bpci ORDER BY x +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +STMT: SelectStmt +== 328 +SELECT x FROM test2bpci UNION SELECT x FROM test1bpci ORDER BY x +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +STMT: SelectStmt +== 329 +SELECT x FROM test1bpci INTERSECT SELECT x FROM test2bpci ORDER BY x +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +STMT: SelectStmt +== 330 +SELECT x FROM test2bpci INTERSECT SELECT x FROM test1bpci ORDER BY x +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +STMT: SelectStmt +== 331 +SELECT x FROM test1bpci EXCEPT SELECT x FROM test2bpci +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +STMT: SelectStmt +== 332 +SELECT x FROM test2bpci EXCEPT SELECT x FROM test1bpci +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +STMT: SelectStmt +== 333 +SELECT DISTINCT x FROM test3bpci ORDER BY x +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +STMT: SelectStmt +== 334 +SELECT count(DISTINCT x) FROM test3bpci +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 335 +SELECT x, count(*) FROM test3bpci GROUP BY x ORDER BY x +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 336 +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3bpci ORDER BY x +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 337 +CREATE UNIQUE INDEX ON test1bpci (x) +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DDL +STMT: IndexStmt +== 338 +-- ok +INSERT INTO test1bpci VALUES ('ABC') +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 339 +-- error +CREATE UNIQUE INDEX ON test3bpci (x) +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DDL +STMT: IndexStmt +== 340 +-- error +SELECT string_to_array('ABC,DEF,GHI'::char(11) COLLATE case_insensitive, ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 341 +SELECT string_to_array('ABCDEFGHI'::char(9) COLLATE case_insensitive, NULL, 'b') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +== 342 +-- This tests the issue described in match_pattern_prefix(). In the +-- absence of that check, the case_insensitive tests below would +-- return no rows where they should logically return one. +CREATE TABLE test4c (x text COLLATE "C") +-- +TABLE: name="test4c" schema="" table="test4c" ctx=DDL +STMT: CreateStmt +== 343 +INSERT INTO test4c VALUES ('abc') +-- +TABLE: name="test4c" schema="" table="test4c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 344 +CREATE INDEX ON test4c (x) +-- +TABLE: name="test4c" schema="" table="test4c" ctx=DDL +STMT: IndexStmt +== 345 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 346 +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_sensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 347 +-- ok, no rows +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_sensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 348 +-- ok, no rows +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_insensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 349 +-- error +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_insensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 350 +-- error +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 351 +-- Unicode special case: different variants of Greek lower case sigma. +-- A naive implementation like citext that just does lower(x) = +-- lower(y) will do the wrong thing here, because lower('Σ') is 'σ' +-- but upper('ς') is 'Σ'. +SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_sensitive +-- +STMT: SelectStmt +== 352 +SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_insensitive +-- +STMT: SelectStmt +== 353 +-- name vs. text comparison operators +SELECT relname FROM pg_class WHERE relname = 'PG_CLASS'::text COLLATE case_insensitive +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 354 +SELECT relname FROM pg_class WHERE 'PG_CLASS'::text = relname COLLATE case_insensitive +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 355 +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND typname <> 'INT2'::text + COLLATE case_insensitive ORDER BY typname +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 356 +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND 'INT2'::text <> typname + COLLATE case_insensitive ORDER BY typname +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 357 +-- test case adapted from subselect.sql +CREATE TEMP TABLE outer_text (f1 text COLLATE case_insensitive, f2 text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DDL +STMT: CreateStmt +== 358 +INSERT INTO outer_text VALUES ('a', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 359 +INSERT INTO outer_text VALUES ('b', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +INSERT INTO outer_text VALUES ('A', NULL) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 361 +INSERT INTO outer_text VALUES ('B', NULL) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 362 +CREATE TEMP TABLE inner_text (c1 text COLLATE case_insensitive, c2 text) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DDL +STMT: CreateStmt +== 363 +INSERT INTO inner_text VALUES ('a', NULL) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 364 +SELECT * FROM outer_text WHERE (f1, f2) NOT IN (SELECT * FROM inner_text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 365 +-- accents +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +== 366 +CREATE COLLATION ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes', deterministic = false) +-- +STMT: DefineStmt +== 367 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 368 +CREATE TABLE test4 (a int, b text) +-- +TABLE: name="test4" schema="" table="test4" ctx=DDL +STMT: CreateStmt +== 369 +INSERT INTO test4 VALUES (1, 'cote'), (2, 'côte'), (3, 'coté'), (4, 'côté') +-- +TABLE: name="test4" schema="" table="test4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 370 +SELECT * FROM test4 WHERE b = 'cote' +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 371 +SELECT * FROM test4 WHERE b = 'cote' COLLATE ignore_accents +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 372 +SELECT * FROM test4 WHERE b = 'Cote' COLLATE ignore_accents +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 373 +-- still case-sensitive +SELECT * FROM test4 WHERE b = 'Cote' COLLATE case_insensitive +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 374 +-- foreign keys (should use collation of primary key) + +-- PK is case-sensitive, FK is case-insensitive +CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY) +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=DDL +STMT: CreateStmt +== 375 +INSERT INTO test10pk VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 376 +CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE) +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DDL +STMT: CreateStmt +== 377 +INSERT INTO test10fk VALUES ('abc') +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 378 +-- ok +INSERT INTO test10fk VALUES ('ABC') +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 379 +-- error +INSERT INTO test10fk VALUES ('xyz') +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 380 +-- error +SELECT * FROM test10pk +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=Select +STMT: SelectStmt +== 381 +SELECT * FROM test10fk +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=Select +STMT: SelectStmt +== 382 +-- restrict update even though the values are "equal" in the FK table +UPDATE test10fk SET x = 'ABC' WHERE x = 'abc' +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: UpdateStmt +== 383 +-- error +SELECT * FROM test10fk +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=Select +STMT: SelectStmt +== 384 +DELETE FROM test10pk WHERE x = 'abc' +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=DML +STMT: DeleteStmt +== 385 +SELECT * FROM test10pk +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=Select +STMT: SelectStmt +== 386 +SELECT * FROM test10fk +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=Select +STMT: SelectStmt +== 387 +-- PK is case-insensitive, FK is case-sensitive +CREATE TABLE test11pk (x text COLLATE case_insensitive PRIMARY KEY) +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DDL +STMT: CreateStmt +== 388 +INSERT INTO test11pk VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 389 +CREATE TABLE test11fk (x text COLLATE case_sensitive REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE) +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DDL +STMT: CreateStmt +== 390 +INSERT INTO test11fk VALUES ('abc') +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 391 +-- ok +INSERT INTO test11fk VALUES ('ABC') +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 392 +-- ok +INSERT INTO test11fk VALUES ('xyz') +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 393 +-- error +SELECT * FROM test11pk +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=Select +STMT: SelectStmt +== 394 +SELECT * FROM test11fk +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=Select +STMT: SelectStmt +== 395 +-- cascade update even though the values are "equal" in the PK table +UPDATE test11pk SET x = 'ABC' WHERE x = 'abc' +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DML +STMT: UpdateStmt +== 396 +SELECT * FROM test11fk +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=Select +STMT: SelectStmt +== 397 +DELETE FROM test11pk WHERE x = 'abc' +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DML +STMT: DeleteStmt +== 398 +SELECT * FROM test11pk +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=Select +STMT: SelectStmt +== 399 +SELECT * FROM test11fk +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=Select +STMT: SelectStmt +== 400 +-- partitioning +CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b) +-- +TABLE: name="test20" schema="" table="test20" ctx=DDL +STMT: CreateStmt +== 401 +CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc') +-- +TABLE: name="test20_1" schema="" table="test20_1" ctx=DDL +STMT: CreateStmt +== 402 +INSERT INTO test20 VALUES (1, 'abc') +-- +TABLE: name="test20" schema="" table="test20" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 403 +INSERT INTO test20 VALUES (2, 'ABC') +-- +TABLE: name="test20" schema="" table="test20" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 404 +SELECT * FROM test20_1 +-- +TABLE: name="test20_1" schema="" table="test20_1" ctx=Select +STMT: SelectStmt +== 405 +CREATE TABLE test21 (a int, b text COLLATE case_insensitive) PARTITION BY RANGE (b) +-- +TABLE: name="test21" schema="" table="test21" ctx=DDL +STMT: CreateStmt +== 406 +CREATE TABLE test21_1 PARTITION OF test21 FOR VALUES FROM ('ABC') TO ('DEF') +-- +TABLE: name="test21_1" schema="" table="test21_1" ctx=DDL +STMT: CreateStmt +== 407 +INSERT INTO test21 VALUES (1, 'abc') +-- +TABLE: name="test21" schema="" table="test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 408 +INSERT INTO test21 VALUES (2, 'ABC') +-- +TABLE: name="test21" schema="" table="test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 409 +SELECT * FROM test21_1 +-- +TABLE: name="test21_1" schema="" table="test21_1" ctx=Select +STMT: SelectStmt +== 410 +CREATE TABLE test22 (a int, b text COLLATE case_sensitive) PARTITION BY HASH (b) +-- +TABLE: name="test22" schema="" table="test22" ctx=DDL +STMT: CreateStmt +== 411 +CREATE TABLE test22_0 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test22_0" schema="" table="test22_0" ctx=DDL +STMT: CreateStmt +== 412 +CREATE TABLE test22_1 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test22_1" schema="" table="test22_1" ctx=DDL +STMT: CreateStmt +== 413 +INSERT INTO test22 VALUES (1, 'def') +-- +TABLE: name="test22" schema="" table="test22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 414 +INSERT INTO test22 VALUES (2, 'DEF') +-- +TABLE: name="test22" schema="" table="test22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 415 +-- they end up in different partitions +SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1) +-- +TABLE: name="test22_0" schema="" table="test22_0" ctx=Select +TABLE: name="test22_1" schema="" table="test22_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 416 +-- same with arrays +CREATE TABLE test22a (a int, b text[] COLLATE case_sensitive) PARTITION BY HASH (b) +-- +TABLE: name="test22a" schema="" table="test22a" ctx=DDL +STMT: CreateStmt +== 417 +CREATE TABLE test22a_0 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test22a_0" schema="" table="test22a_0" ctx=DDL +STMT: CreateStmt +== 418 +CREATE TABLE test22a_1 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test22a_1" schema="" table="test22a_1" ctx=DDL +STMT: CreateStmt +== 419 +INSERT INTO test22a VALUES (1, ARRAY['def']) +-- +TABLE: name="test22a" schema="" table="test22a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 420 +INSERT INTO test22a VALUES (2, ARRAY['DEF']) +-- +TABLE: name="test22a" schema="" table="test22a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 421 +-- they end up in different partitions +SELECT (SELECT count(*) FROM test22a_0) = (SELECT count(*) FROM test22a_1) +-- +TABLE: name="test22a_0" schema="" table="test22a_0" ctx=Select +TABLE: name="test22a_1" schema="" table="test22a_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 422 +CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b) +-- +TABLE: name="test23" schema="" table="test23" ctx=DDL +STMT: CreateStmt +== 423 +CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test23_0" schema="" table="test23_0" ctx=DDL +STMT: CreateStmt +== 424 +CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test23_1" schema="" table="test23_1" ctx=DDL +STMT: CreateStmt +== 425 +INSERT INTO test23 VALUES (1, 'def') +-- +TABLE: name="test23" schema="" table="test23" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 426 +INSERT INTO test23 VALUES (2, 'DEF') +-- +TABLE: name="test23" schema="" table="test23" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 427 +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1) +-- +TABLE: name="test23_0" schema="" table="test23_0" ctx=Select +TABLE: name="test23_1" schema="" table="test23_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 428 +-- same with arrays +CREATE TABLE test23a (a int, b text[] COLLATE case_insensitive) PARTITION BY HASH (b) +-- +TABLE: name="test23a" schema="" table="test23a" ctx=DDL +STMT: CreateStmt +== 429 +CREATE TABLE test23a_0 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test23a_0" schema="" table="test23a_0" ctx=DDL +STMT: CreateStmt +== 430 +CREATE TABLE test23a_1 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test23a_1" schema="" table="test23a_1" ctx=DDL +STMT: CreateStmt +== 431 +INSERT INTO test23a VALUES (1, ARRAY['def']) +-- +TABLE: name="test23a" schema="" table="test23a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 432 +INSERT INTO test23a VALUES (2, ARRAY['DEF']) +-- +TABLE: name="test23a" schema="" table="test23a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 433 +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test23a_0) <> (SELECT count(*) FROM test23a_1) +-- +TABLE: name="test23a_0" schema="" table="test23a_0" ctx=Select +TABLE: name="test23a_1" schema="" table="test23a_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 434 +CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b) +-- +TABLE: name="test30" schema="" table="test30" ctx=DDL +STMT: CreateStmt +== 435 +CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc') +-- +TABLE: name="test30_1" schema="" table="test30_1" ctx=DDL +STMT: CreateStmt +== 436 +INSERT INTO test30 VALUES (1, 'abc') +-- +TABLE: name="test30" schema="" table="test30" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 437 +INSERT INTO test30 VALUES (2, 'ABC') +-- +TABLE: name="test30" schema="" table="test30" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 438 +SELECT * FROM test30_1 +-- +TABLE: name="test30_1" schema="" table="test30_1" ctx=Select +STMT: SelectStmt +== 439 +CREATE TABLE test31 (a int, b char(3) COLLATE case_insensitive) PARTITION BY RANGE (b) +-- +TABLE: name="test31" schema="" table="test31" ctx=DDL +STMT: CreateStmt +== 440 +CREATE TABLE test31_1 PARTITION OF test31 FOR VALUES FROM ('ABC') TO ('DEF') +-- +TABLE: name="test31_1" schema="" table="test31_1" ctx=DDL +STMT: CreateStmt +== 441 +INSERT INTO test31 VALUES (1, 'abc') +-- +TABLE: name="test31" schema="" table="test31" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 442 +INSERT INTO test31 VALUES (2, 'ABC') +-- +TABLE: name="test31" schema="" table="test31" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 443 +SELECT * FROM test31_1 +-- +TABLE: name="test31_1" schema="" table="test31_1" ctx=Select +STMT: SelectStmt +== 444 +CREATE TABLE test32 (a int, b char(3) COLLATE case_sensitive) PARTITION BY HASH (b) +-- +TABLE: name="test32" schema="" table="test32" ctx=DDL +STMT: CreateStmt +== 445 +CREATE TABLE test32_0 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test32_0" schema="" table="test32_0" ctx=DDL +STMT: CreateStmt +== 446 +CREATE TABLE test32_1 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test32_1" schema="" table="test32_1" ctx=DDL +STMT: CreateStmt +== 447 +INSERT INTO test32 VALUES (1, 'def') +-- +TABLE: name="test32" schema="" table="test32" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 448 +INSERT INTO test32 VALUES (2, 'DEF') +-- +TABLE: name="test32" schema="" table="test32" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 449 +-- they end up in different partitions +SELECT (SELECT count(*) FROM test32_0) = (SELECT count(*) FROM test32_1) +-- +TABLE: name="test32_0" schema="" table="test32_0" ctx=Select +TABLE: name="test32_1" schema="" table="test32_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 450 +CREATE TABLE test33 (a int, b char(3) COLLATE case_insensitive) PARTITION BY HASH (b) +-- +TABLE: name="test33" schema="" table="test33" ctx=DDL +STMT: CreateStmt +== 451 +CREATE TABLE test33_0 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test33_0" schema="" table="test33_0" ctx=DDL +STMT: CreateStmt +== 452 +CREATE TABLE test33_1 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test33_1" schema="" table="test33_1" ctx=DDL +STMT: CreateStmt +== 453 +INSERT INTO test33 VALUES (1, 'def') +-- +TABLE: name="test33" schema="" table="test33" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 454 +INSERT INTO test33 VALUES (2, 'DEF') +-- +TABLE: name="test33" schema="" table="test33" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 455 +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test33_0) <> (SELECT count(*) FROM test33_1) +-- +TABLE: name="test33_0" schema="" table="test33_0" ctx=Select +TABLE: name="test33_1" schema="" table="test33_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 456 +|-- +-- Bug #18568 +|-- +-- Partitionwise aggregate (full or partial) should not be used when a +-- partition key's collation doesn't match that of the GROUP BY column it is +-- matched with. +SET max_parallel_workers_per_gather TO 0 +-- +STMT: VariableSetStmt +== 457 +SET enable_incremental_sort TO off +-- +STMT: VariableSetStmt +== 458 +CREATE TABLE pagg_tab3 (a text, c text collate case_insensitive) PARTITION BY LIST(c collate "C") +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DDL +STMT: CreateStmt +== 459 +CREATE TABLE pagg_tab3_p1 PARTITION OF pagg_tab3 FOR VALUES IN ('a', 'b') +-- +TABLE: name="pagg_tab3_p1" schema="" table="pagg_tab3_p1" ctx=DDL +STMT: CreateStmt +== 460 +CREATE TABLE pagg_tab3_p2 PARTITION OF pagg_tab3 FOR VALUES IN ('B', 'A') +-- +TABLE: name="pagg_tab3_p2" schema="" table="pagg_tab3_p2" ctx=DDL +STMT: CreateStmt +== 461 +INSERT INTO pagg_tab3 SELECT i % 4 + 1, substr('abAB', (i % 4) + 1 , 1) FROM generate_series(0, 19) i +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DML +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 462 +ANALYZE pagg_tab3 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DDL +STMT: VacuumStmt +== 463 +SET enable_partitionwise_aggregate TO false +-- +STMT: VariableSetStmt +== 464 +EXPLAIN (COSTS OFF) +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 465 +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 466 +-- No "full" partitionwise aggregation allowed, though "partial" is allowed. +SET enable_partitionwise_aggregate TO true +-- +STMT: VariableSetStmt +== 467 +EXPLAIN (COSTS OFF) +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 468 +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 469 +-- OK to use full partitionwise aggregate after changing the GROUP BY column's +-- collation to be the same as that of the partition key. +EXPLAIN (COSTS OFF) +SELECT c collate "C", count(c) FROM pagg_tab3 GROUP BY c collate "C" ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 470 +SELECT c collate "C", count(c) FROM pagg_tab3 GROUP BY c collate "C" ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 471 +-- Partitionwise join should not be allowed too when the collation used by the +-- join keys doesn't match the partition key collation. +SET enable_partitionwise_join TO false +-- +STMT: VariableSetStmt +== 472 +EXPLAIN (COSTS OFF) +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 473 +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 474 +SET enable_partitionwise_join TO true +-- +STMT: VariableSetStmt +== 475 +EXPLAIN (COSTS OFF) +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 476 +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 477 +-- OK when the join clause uses the same collation as the partition key. +EXPLAIN (COSTS OFF) +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 478 +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 479 +SET enable_partitionwise_join TO false +-- +STMT: VariableSetStmt +== 480 +EXPLAIN (COSTS OFF) +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 481 +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 482 +DROP TABLE pagg_tab3 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DDL +STMT: DropStmt +== 483 +RESET enable_partitionwise_aggregate +-- +STMT: VariableSetStmt +== 484 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +== 485 +RESET enable_incremental_sort +-- +STMT: VariableSetStmt +== 486 +-- Check that DEFAULT expressions in SQL/JSON functions use the same collation +-- as the RETURNING type. Mismatched collations should raise an error. +CREATE DOMAIN d1 AS text COLLATE case_insensitive +-- +STMT: CreateDomainStmt +== 487 +CREATE DOMAIN d2 AS text COLLATE "C" +-- +STMT: CreateDomainStmt +== 488 +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT ('C' COLLATE "C") COLLATE case_insensitive ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 489 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT 'C' ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 490 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT 'C'::d2 ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 491 +-- error +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT 'C' COLLATE "C" ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 492 +-- error +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A' ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 493 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A' COLLATE case_insensitive ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 494 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A'::d2 ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 495 +-- error +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A' COLLATE "C" ON EMPTY) = 'a' +-- +STMT: SelectStmt +== 496 +-- error +DROP DOMAIN d1, d2 +-- +STMT: DropStmt +== 497 +-- cleanup +RESET search_path +-- +STMT: VariableSetStmt +== 498 +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +== 499 +DROP SCHEMA collate_tests CASCADE +-- +STMT: DropStmt +== 500 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 501 +-- leave a collation for pg_upgrade test +CREATE COLLATION coll_icu_upgrade FROM "und-x-icu" +-- +STMT: DefineStmt diff --git a/parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json b/parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json new file mode 100644 index 0000000..648a6d3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json @@ -0,0 +1,207 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203" + ] +} diff --git a/parser/testdata/summary/postgres_regress/collate.linux.utf8.test b/parser/testdata/summary/postgres_regress/collate.linux.utf8.test new file mode 100644 index 0000000..239c3ed --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.linux.utf8.test @@ -0,0 +1,1269 @@ +== 001 +/* + * This test is for Linux/glibc systems and assumes that a full set of + * locales is installed. It must be run in a database with UTF-8 encoding, + * because other encodings don't support all the characters used. + */ + +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR + version() !~ 'linux-gnu' + AS skip_test +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +FILTER: schema="" table="" column="collencoding" +STMT: SelectStmt +== 002 +SET client_encoding TO UTF8 +-- +STMT: VariableSetStmt +== 003 +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +== 004 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +== 005 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en_US" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +== 006 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 007 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE collate_test_fail ( + a int COLLATE "en_US", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 009 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +== 010 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv_SE" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +== 011 +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +) +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DDL +STMT: CreateStmt +== 012 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO collate_test3 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 015 +SELECT * FROM collate_test1 WHERE b >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 016 +SELECT * FROM collate_test2 WHERE b >= 'bbc' +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 017 +SELECT * FROM collate_test3 WHERE b >= 'bbc' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 018 +SELECT * FROM collate_test3 WHERE b >= 'BBC' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 019 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 020 +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 021 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 022 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en_US" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 023 +CREATE DOMAIN testdomain_sv AS text COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +== 024 +CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +== 025 +-- fails +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +== 026 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 027 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +== 028 +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en_US" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +== 029 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 030 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +== 031 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 032 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 033 +SELECT a, b FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 034 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 035 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 036 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 037 +SELECT * FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 038 +-- constant expression folding +SELECT 'bbc' COLLATE "en_US" > 'äbc' COLLATE "en_US" AS "true" +-- +STMT: SelectStmt +== 039 +SELECT 'bbc' COLLATE "sv_SE" > 'äbc' COLLATE "sv_SE" AS "false" +-- +STMT: SelectStmt +== 040 +-- upper/lower + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "en_US", + y text COLLATE "tr_TR" +) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DDL +STMT: CreateStmt +== 041 +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ') +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- LIKE/ILIKE + +SELECT * FROM collate_test1 WHERE b LIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 046 +SELECT * FROM collate_test1 WHERE b LIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 047 +SELECT * FROM collate_test1 WHERE b LIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 048 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 049 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 050 +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 051 +SELECT 'Türkiye' COLLATE "en_US" ILIKE '%KI%' AS "true" +-- +STMT: SelectStmt +== 052 +SELECT 'Türkiye' COLLATE "tr_TR" ILIKE '%KI%' AS "false" +-- +STMT: SelectStmt +== 053 +SELECT 'bıt' ILIKE 'BIT' COLLATE "en_US" AS "false" +-- +STMT: SelectStmt +== 054 +SELECT 'bıt' ILIKE 'BIT' COLLATE "tr_TR" AS "true" +-- +STMT: SelectStmt +== 055 +-- The following actually exercises the selectivity estimation for ILIKE. +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 056 +-- regular expressions + +SELECT * FROM collate_test1 WHERE b ~ '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 057 +SELECT * FROM collate_test1 WHERE b ~ '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 058 +SELECT * FROM collate_test1 WHERE b ~ 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 059 +SELECT * FROM collate_test1 WHERE b ~* '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 060 +SELECT * FROM collate_test1 WHERE b ~* '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 061 +SELECT * FROM collate_test1 WHERE b ~* 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 062 +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en_US" +) +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DDL +STMT: CreateStmt +== 063 +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, 'äbç'), (10, 'ÄBÇ') +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +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 +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=Select +STMT: SelectStmt +== 065 +SELECT 'Türkiye' COLLATE "en_US" ~* 'KI' AS "true" +-- +STMT: SelectStmt +== 066 +SELECT 'Türkiye' COLLATE "tr_TR" ~* 'KI' AS "false" +-- +STMT: SelectStmt +== 067 +SELECT 'bıt' ~* 'BIT' COLLATE "en_US" AS "false" +-- +STMT: SelectStmt +== 068 +SELECT 'bıt' ~* 'BIT' COLLATE "tr_TR" AS "true" +-- +STMT: SelectStmt +== 069 +-- The following actually exercises the selectivity estimation for ~*. +SELECT relname FROM pg_class WHERE relname ~* '^abc' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 070 +-- to_char + +SET lc_time TO 'tr_TR' +-- +STMT: VariableSetStmt +== 071 +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY' COLLATE "tr_TR") +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 073 +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY' COLLATE "tr_TR") +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 075 +-- to_date + +SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT to_date('01 Şub 2010', 'DD TMMON YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 077 +SELECT to_date('1234567890ab 2010', 'TMMONTH YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 078 +-- fail + + +-- backwards parsing + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 079 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 080 +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10 +-- +TABLE: name="collview3" schema="" table="collview3" ctx=DDL +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 081 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 082 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 083 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 084 +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 085 +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 087 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 088 +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 089 +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 090 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 091 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 092 +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 093 +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 094 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 095 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 096 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 097 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +== 098 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 099 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 100 +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 101 +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 102 +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 103 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 104 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 105 +SELECT min(b), max(b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 106 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 107 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT array_agg(b ORDER BY b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 109 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 110 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 111 +SELECT a, b FROM collate_test3 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 112 +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 113 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 114 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 115 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 116 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 117 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 118 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 119 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 120 +-- fail + +-- ideally this would be a parse-time error, but for now it must be run-time: +select x < y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 121 +-- fail +select x || y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 122 +-- ok, because || is not collation aware +select x, y from collate_test10 order by x || y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 123 +-- not so ok + +-- collation mismatch between recursive and non-recursive term +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "en_US"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "de_DE" FROM foo WHERE length(x) < 10) +SELECT * FROM foo +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 124 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 125 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 126 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 127 +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 128 +-- 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 $$ +-- +FUNCTION: name="mylt" function="mylt" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 129 +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$ +-- +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 130 +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$ +-- +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 131 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +== 132 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +== 133 +-- 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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 134 +SELECT mylt2('a', 'B' collate "en_US") as t, mylt2('a', 'B' collate "C") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 135 +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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 136 +SELECT mylt2('a', 'B') as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 137 +SELECT mylt2('a', 'B' collate "C") as fail +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 138 +-- conflicting collations +SELECT mylt2('a', 'B' collate "POSIX") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 139 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 140 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 142 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 143 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 144 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 145 +SELECT a, dup(b) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 146 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 147 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 148 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 149 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 150 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 151 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 152 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 153 +-- schema manipulation commands + +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +== 154 +CREATE SCHEMA test_schema +-- +STMT: CreateSchemaStmt +== 155 +-- We need to do this this way to cope with varying names for encodings: +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (locale = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +== 156 +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +== 157 +-- fail, duplicate name +CREATE COLLATION IF NOT EXISTS test0 FROM "C" +-- +STMT: DefineStmt +== 158 +-- ok, skipped +CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo') +-- +STMT: DefineStmt +== 159 +-- ok, skipped +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (lc_collate = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || + ', lc_ctype = ' || + quote_literal((SELECT datctype FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +== 160 +CREATE COLLATION test3 (lc_collate = 'en_US.utf8') +-- +STMT: DefineStmt +== 161 +-- fail, need lc_ctype +CREATE COLLATION testx (locale = 'nonsense') +-- +STMT: DefineStmt +== 162 +-- fail + +CREATE COLLATION test4 FROM nonsense +-- +STMT: DefineStmt +== 163 +CREATE COLLATION test5 FROM test0 +-- +STMT: DefineStmt +== 164 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 165 +ALTER COLLATION test1 RENAME TO test11 +-- +STMT: RenameStmt +== 166 +ALTER COLLATION test0 RENAME TO test11 +-- +STMT: RenameStmt +== 167 +-- fail +ALTER COLLATION test1 RENAME TO test22 +-- +STMT: RenameStmt +== 168 +-- fail + +ALTER COLLATION test11 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 169 +ALTER COLLATION test11 OWNER TO nonsense +-- +STMT: AlterOwnerStmt +== 170 +ALTER COLLATION test11 SET SCHEMA test_schema +-- +STMT: AlterObjectSchemaStmt +== 171 +COMMENT ON COLLATION test0 IS 'US English' +-- +STMT: CommentStmt +== 172 +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 173 +DROP COLLATION test0, test_schema.test11, test5 +-- +STMT: DropStmt +== 174 +DROP COLLATION test0 +-- +STMT: DropStmt +== 175 +-- fail +DROP COLLATION IF EXISTS test0 +-- +STMT: DropStmt +== 176 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 177 +DROP SCHEMA test_schema +-- +STMT: DropStmt +== 178 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +== 179 +-- ALTER + +ALTER COLLATION "en_US" REFRESH VERSION +-- +STMT: AlterCollationStmt +== 180 +-- also test for database while we are here +SELECT current_database() AS datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +== 181 +ALTER DATABASE :"datname" REFRESH COLLATION VERSION +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 182 +-- dependencies + +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +== 183 +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0) +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +STMT: CreateStmt +== 184 +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0 +-- +STMT: CreateDomainStmt +== 185 +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0) +-- +STMT: CompositeTypeStmt +== 186 +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo +-- +TABLE: name="collate_dep_test3" schema="" table="collate_dep_test3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 187 +CREATE TABLE collate_dep_test4t (a int, b text) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: CreateStmt +== 188 +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: IndexStmt +== 189 +DROP COLLATION test0 RESTRICT +-- +STMT: DropStmt +== 190 +-- fail +DROP COLLATION test0 CASCADE +-- +STMT: DropStmt +== 191 +DROP TABLE collate_dep_test1, collate_dep_test4t +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: DropStmt +== 192 +DROP TYPE collate_dep_test2 +-- +STMT: DropStmt +== 193 +-- test range types and collations + +create type textrange_c as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +== 194 +create type textrange_en_us as range(subtype=text, collation="en_US") +-- +STMT: CreateRangeStmt +== 195 +select textrange_c('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_c" function="textrange_c" schema="" ctx=Call +STMT: SelectStmt +== 196 +select textrange_en_us('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_en_us" function="textrange_en_us" schema="" ctx=Call +STMT: SelectStmt +== 197 +drop type textrange_c +-- +STMT: DropStmt +== 198 +drop type textrange_en_us +-- +STMT: DropStmt +== 199 +-- standard collations + +SELECT * FROM collate_test2 ORDER BY b COLLATE UCS_BASIC +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 200 +-- nondeterministic collations +-- (not supported with libc provider) + +CREATE COLLATION ctest_det (locale = 'en_US.utf8', deterministic = true) +-- +STMT: DefineStmt +== 201 +CREATE COLLATION ctest_nondet (locale = 'en_US.utf8', deterministic = false) +-- +STMT: DefineStmt +== 202 +-- cleanup +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +== 203 +DROP SCHEMA collate_tests CASCADE +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/collate.metadata.json b/parser/testdata/summary/postgres_regress/collate.metadata.json new file mode 100644 index 0000000..267f283 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.metadata.json @@ -0,0 +1,148 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144" + ] +} diff --git a/parser/testdata/summary/postgres_regress/collate.test b/parser/testdata/summary/postgres_regress/collate.test new file mode 100644 index 0000000..3f21c91 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.test @@ -0,0 +1,911 @@ +== 001 +/* + * This test is intended to pass on all platforms supported by Postgres. + * We can therefore only assume that the default, C, and POSIX collations + * are available --- and since the regression tests are often run in a + * C-locale database, these may well all have the same behavior. But + * fortunately, the system doesn't know that and will treat them as + * incompatible collations. It is therefore at least possible to test + * parser behaviors such as collation conflict resolution. This test will, + * however, be more revealing when run in a database with non-C locale, + * since any departure from C sorting behavior will show as a failure. + */ + +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +== 002 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +== 003 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "C" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE collate_test_fail ( + a int COLLATE "C", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 005 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +== 006 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "POSIX" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +== 007 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'Abc'), (3, 'bbc'), (4, 'ABD') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 009 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 010 +SELECT * FROM collate_test1 WHERE b >= 'abc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 011 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 012 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "POSIX" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 013 +-- fail + +CREATE DOMAIN testdomain_p AS text COLLATE "POSIX" +-- +STMT: CreateDomainStmt +== 014 +CREATE DOMAIN testdomain_i AS int COLLATE "POSIX" +-- +STMT: CreateDomainStmt +== 015 +-- fail +CREATE TABLE collate_test4 ( + a int, + b testdomain_p +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +== 016 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 017 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +== 018 +CREATE TABLE collate_test5 ( + a int, + b testdomain_p COLLATE "C" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +== 019 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 020 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +== 021 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 022 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 023 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 024 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 025 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 026 +-- constant expression folding +SELECT 'bbc' COLLATE "C" > 'Abc' COLLATE "C" AS "true" +-- +STMT: SelectStmt +== 027 +SELECT 'bbc' COLLATE "POSIX" < 'Abc' COLLATE "POSIX" AS "false" +-- +STMT: SelectStmt +== 028 +-- upper/lower + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "C", + y text COLLATE "POSIX" +) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DDL +STMT: CreateStmt +== 029 +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ') +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 033 +-- backwards parsing + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 034 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 035 +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collview3" schema="" table="collview3" ctx=DDL +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 036 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 037 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 038 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 039 +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 041 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 042 +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 044 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 045 +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 046 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 047 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 048 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +== 049 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 050 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 051 +SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 052 +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 053 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 054 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 055 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 056 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- In aggregates, ORDER BY expressions don't affect aggregate's collation +SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +== 058 +-- fail +SELECT array_agg(x COLLATE "C" ORDER BY y COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT array_agg(a ORDER BY x COLLATE "C", y COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT array_agg(a ORDER BY x||y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 061 +-- fail + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 062 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 063 +SELECT a, b FROM collate_test2 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 064 +SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 065 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 066 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 067 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 068 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 069 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 070 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 071 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 072 +-- fail + +-- ideally this would be a parse-time error, but for now it must be run-time: +select x < y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 073 +-- fail +select x || y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 074 +-- ok, because || is not collation aware +select x, y from collate_test10 order by x || y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +== 075 +-- not so ok + +-- collation mismatch between recursive and non-recursive term +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "POSIX" FROM foo WHERE length(x) < 10) +SELECT * FROM foo +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 076 +SELECT a, b, a < b as lt FROM + (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b) +-- +STMT: SelectStmt +== 077 +-- collation mismatch in subselects +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y, x FROM collate_test10) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +== 078 +-- now it works with overrides +SELECT * FROM collate_test10 WHERE (x COLLATE "POSIX", y COLLATE "C") NOT IN (SELECT y, x FROM collate_test10) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +== 079 +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y COLLATE "C", x COLLATE "POSIX" FROM collate_test10) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +== 080 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 081 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 082 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 083 +-- result of a SQL function + +CREATE FUNCTION vc (text) RETURNS text LANGUAGE sql + AS 'select $1::varchar' +-- +FUNCTION: name="vc" function="vc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 084 +SELECT a, b FROM collate_test1 ORDER BY a, vc(b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="vc" function="vc" schema="" ctx=Call +STMT: SelectStmt +== 085 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 087 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 088 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 089 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 090 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 091 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "POSIX") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 092 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 093 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 094 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 095 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 096 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 097 +-- foreign keys + +-- force indexes and mergejoins to be used for FK checking queries, +-- else they might not exercise collation-dependent operators +SET enable_seqscan TO 0 +-- +STMT: VariableSetStmt +== 098 +SET enable_hashjoin TO 0 +-- +STMT: VariableSetStmt +== 099 +SET enable_nestloop TO 0 +-- +STMT: VariableSetStmt +== 100 +CREATE TABLE collate_test20 (f1 text COLLATE "C" PRIMARY KEY) +-- +TABLE: name="collate_test20" schema="" table="collate_test20" ctx=DDL +STMT: CreateStmt +== 101 +INSERT INTO collate_test20 VALUES ('foo'), ('bar') +-- +TABLE: name="collate_test20" schema="" table="collate_test20" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 102 +CREATE TABLE collate_test21 (f2 text COLLATE "POSIX" REFERENCES collate_test20) +-- +TABLE: name="collate_test21" schema="" table="collate_test21" ctx=DDL +STMT: CreateStmt +== 103 +INSERT INTO collate_test21 VALUES ('foo'), ('bar') +-- +TABLE: name="collate_test21" schema="" table="collate_test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +INSERT INTO collate_test21 VALUES ('baz') +-- +TABLE: name="collate_test21" schema="" table="collate_test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +-- fail +CREATE TABLE collate_test22 (f2 text COLLATE "POSIX") +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DDL +STMT: CreateStmt +== 106 +INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz') +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20 +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DDL +STMT: AlterTableStmt +== 108 +-- fail +DELETE FROM collate_test22 WHERE f2 = 'baz' +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DML +STMT: DeleteStmt +== 109 +ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20 +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DDL +STMT: AlterTableStmt +== 110 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 111 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 112 +RESET enable_nestloop +-- +STMT: VariableSetStmt +== 113 +-- EXPLAIN + +EXPLAIN (COSTS OFF) + SELECT * FROM collate_test10 ORDER BY x, y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 114 +EXPLAIN (COSTS OFF) + SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE "C" ASC NULLS FIRST +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 115 +-- CREATE/DROP COLLATION + +CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" ) +-- +STMT: DefineStmt +== 116 +SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 117 +CREATE COLLATION builtin2 ( PROVIDER = builtin ) +-- +STMT: DefineStmt +== 118 +-- fails +CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ) +-- +STMT: DefineStmt +== 119 +-- fails +CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ) +-- +STMT: DefineStmt +== 120 +-- fails + +CREATE COLLATION mycoll1 FROM "C" +-- +STMT: DefineStmt +== 121 +CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" ) +-- +STMT: DefineStmt +== 122 +CREATE COLLATION mycoll3 FROM "default" +-- +STMT: DefineStmt +== 123 +-- intentionally unsupported + +DROP COLLATION mycoll1 +-- +STMT: DropStmt +== 124 +CREATE TABLE collate_test23 (f1 text collate mycoll2) +-- +TABLE: name="collate_test23" schema="" table="collate_test23" ctx=DDL +STMT: CreateStmt +== 125 +DROP COLLATION mycoll2 +-- +STMT: DropStmt +== 126 +-- fail + +-- invalid: non-lowercase quoted identifiers +CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctype" = "POSIX") +-- +STMT: DefineStmt +== 127 +-- 9.1 bug with useless COLLATE in an expression subject to length coercion + +CREATE TEMP TABLE vctable (f1 varchar(25)) +-- +TABLE: name="vctable" schema="" table="vctable" ctx=DDL +STMT: CreateStmt +== 128 +INSERT INTO vctable VALUES ('foo' COLLATE "C") +-- +TABLE: name="vctable" schema="" table="vctable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +SELECT collation for ('foo') +-- +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 130 +-- unknown type - null +SELECT collation for ('foo'::text) +-- +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 131 +SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 132 +-- non-collatable type - error +SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 133 +-- 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 +-- +TABLE: name="collate_on_int" schema="" table="collate_on_int" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 134 +-- Check conflicting or redundant options in CREATE COLLATION +-- LC_COLLATE +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_COLLATE = "NONSENSE", LC_CTYPE = "POSIX") +-- +STMT: DefineStmt +== 135 +-- LC_CTYPE +CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LC_CTYPE = "NONSENSE", LC_COLLATE = "POSIX") +-- +STMT: DefineStmt +== 136 +-- PROVIDER +CREATE COLLATION coll_dup_chk (PROVIDER = icu, PROVIDER = NONSENSE, LC_COLLATE = "POSIX", LC_CTYPE = "POSIX") +-- +STMT: DefineStmt +== 137 +-- LOCALE +CREATE COLLATION case_sensitive (LOCALE = '', LOCALE = "NONSENSE") +-- +STMT: DefineStmt +== 138 +-- DETERMINISTIC +CREATE COLLATION coll_dup_chk (DETERMINISTIC = TRUE, DETERMINISTIC = NONSENSE, LOCALE = '') +-- +STMT: DefineStmt +== 139 +-- VERSION +CREATE COLLATION coll_dup_chk (VERSION = '1', VERSION = "NONSENSE", LOCALE = '') +-- +STMT: DefineStmt +== 140 +-- LOCALE conflicts with LC_COLLATE and LC_CTYPE +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_CTYPE = "POSIX", LOCALE = '') +-- +STMT: DefineStmt +== 141 +-- LOCALE conflicts with LC_COLLATE +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LOCALE = '') +-- +STMT: DefineStmt +== 142 +-- LOCALE conflicts with LC_CTYPE +CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LOCALE = '') +-- +STMT: DefineStmt +== 143 +-- FROM conflicts with any other option +CREATE COLLATION coll_dup_chk (FROM = "C", VERSION = "1") +-- +STMT: DefineStmt +== 144 +|-- +-- 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 +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/collate.utf8.metadata.json b/parser/testdata/summary/postgres_regress/collate.utf8.metadata.json new file mode 100644 index 0000000..5d34ab7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.utf8.metadata.json @@ -0,0 +1,28 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024" + ] +} diff --git a/parser/testdata/summary/postgres_regress/collate.utf8.test b/parser/testdata/summary/postgres_regress/collate.utf8.test new file mode 100644 index 0000000..00e00c2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.utf8.test @@ -0,0 +1,155 @@ +== 001 +/* + * This test is for collations and character operations when using the + * builtin provider with the C.UTF-8 locale. + */ + +/* skip test if not UTF8 server encoding */ +SELECT getdatabaseencoding() <> 'UTF8' AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +== 002 +SET client_encoding TO UTF8 +-- +STMT: VariableSetStmt +== 003 +|-- +-- Test PG_C_UTF8 +|-- + +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C_UTF8') +-- +STMT: DefineStmt +== 004 +-- fails +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C.UTF8') +-- +STMT: DefineStmt +== 005 +DROP COLLATION regress_pg_c_utf8 +-- +STMT: DropStmt +== 006 +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C.UTF-8') +-- +STMT: DefineStmt +== 007 +CREATE TABLE test_pg_c_utf8 ( + t TEXT COLLATE PG_C_UTF8 +) +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=DDL +STMT: CreateStmt +== 008 +INSERT INTO test_pg_c_utf8 VALUES + ('abc DEF 123abc'), + ('ábc sßs ßss DÉF'), + ('DŽxxDŽ džxxDž Džxxdž'), + ('ȺȺȺ'), + ('ⱥⱥⱥ'), + ('ⱥȺ') +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +SELECT + t, lower(t), initcap(t), upper(t), + length(convert_to(t, 'UTF8')) AS t_bytes, + length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes, + length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes, + length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes + FROM test_pg_c_utf8 +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +== 010 +DROP TABLE test_pg_c_utf8 +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=DDL +STMT: DropStmt +== 011 +-- negative test: Final_Sigma not used for builtin locale C.UTF-8 +SELECT lower('ΑΣ' COLLATE PG_C_UTF8) +-- +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8) +-- +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8) +-- +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- properties + +SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 015 +SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 016 +SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 017 +SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 018 +-- symbols are punctuation in posix +SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 019 +SELECT '൧' !~ '\d' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 020 +-- only 0-9 considered digits in posix + +-- case mapping + +SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 021 +SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 022 +SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 023 +SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +== 024 +SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json b/parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json new file mode 100644 index 0000000..a4f4300 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json @@ -0,0 +1,177 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173" + ] +} diff --git a/parser/testdata/summary/postgres_regress/collate.windows.win1252.test b/parser/testdata/summary/postgres_regress/collate.windows.win1252.test new file mode 100644 index 0000000..085c590 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/collate.windows.win1252.test @@ -0,0 +1,1095 @@ +== 001 +/* + * This test is meant to run on Windows systems that has successfully + * run pg_import_system_collations(). Also, the database must have + * WIN1252 encoding, because of the locales' own encodings. Because + * of this, some test are lost from UTF-8 version, such as Turkish + * dotted and undotted 'i'. + */ +SELECT getdatabaseencoding() <> 'WIN1252' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE') AND collencoding = pg_char_to_encoding('WIN1252')) <> 3 OR + (version() !~ 'Visual C\+\+' AND version() !~ 'mingw32' AND version() !~ 'windows') + AS skip_test +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +FILTER: schema="" table="" column="collencoding" +STMT: SelectStmt +== 002 +SET client_encoding TO WIN1252 +-- +STMT: VariableSetStmt +== 003 +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +== 004 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +== 005 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en_US" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +== 006 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 007 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE collate_test_fail ( + a int COLLATE "en_US", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +== 009 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +== 010 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv_SE" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +== 011 +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +) +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DDL +STMT: CreateStmt +== 012 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, '�bc'), (3, 'bbc'), (4, 'ABC') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO collate_test3 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 015 +SELECT * FROM collate_test1 WHERE b >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 016 +SELECT * FROM collate_test2 WHERE b >= 'bbc' +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 017 +SELECT * FROM collate_test3 WHERE b >= 'bbc' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 018 +SELECT * FROM collate_test3 WHERE b >= 'BBC' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 019 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 020 +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 021 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 022 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en_US" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 023 +CREATE DOMAIN testdomain_sv AS text COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +== 024 +CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +== 025 +-- fails +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +== 026 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 027 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +== 028 +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en_US" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +== 029 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 030 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +== 031 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 032 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 033 +SELECT a, b FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 034 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 035 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 036 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 037 +SELECT * FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 038 +-- constant expression folding +SELECT 'bbc' COLLATE "en_US" > '�bc' COLLATE "en_US" AS "true" +-- +STMT: SelectStmt +== 039 +SELECT 'bbc' COLLATE "sv_SE" > '�bc' COLLATE "sv_SE" AS "false" +-- +STMT: SelectStmt +== 040 +-- LIKE/ILIKE + +SELECT * FROM collate_test1 WHERE b LIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 041 +SELECT * FROM collate_test1 WHERE b LIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 042 +SELECT * FROM collate_test1 WHERE b LIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 043 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 044 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 045 +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 046 +-- The following actually exercises the selectivity estimation for ILIKE. +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 047 +-- regular expressions + +SELECT * FROM collate_test1 WHERE b ~ '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 048 +SELECT * FROM collate_test1 WHERE b ~ '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 049 +SELECT * FROM collate_test1 WHERE b ~ 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 050 +SELECT * FROM collate_test1 WHERE b ~* '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 051 +SELECT * FROM collate_test1 WHERE b ~* '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 052 +SELECT * FROM collate_test1 WHERE b ~* 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 053 +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en_US" +) +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DDL +STMT: CreateStmt +== 054 +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, '�b�'), (10, '�B�') +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +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 +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=Select +STMT: SelectStmt +== 056 +-- The following actually exercises the selectivity estimation for ~*. +SELECT relname FROM pg_class WHERE relname ~* '^abc' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 057 +-- backwards parsing + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 058 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 059 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 060 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 061 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 062 +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 063 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 064 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 065 +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 066 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 067 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 068 +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 069 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 070 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 071 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 072 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +== 073 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 074 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 075 +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 076 +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 077 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 079 +SELECT min(b), max(b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 080 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 081 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT array_agg(b ORDER BY b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 084 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 085 +SELECT a, b FROM collate_test3 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 086 +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 087 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 088 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 089 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 090 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 091 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 092 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 093 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 094 +-- fail + +-- collation mismatch between recursive and non-recursive term +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "en_US"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "de_DE" FROM foo WHERE length(x) < 10) +SELECT * FROM foo +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 095 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 096 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +== 097 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +== 098 +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +== 099 +-- 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 $$ +-- +FUNCTION: name="mylt" function="mylt" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 100 +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$ +-- +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 101 +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$ +-- +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 102 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +== 103 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +== 104 +-- 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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 105 +SELECT mylt2('a', 'B' collate "en_US") as t, mylt2('a', 'B' collate "C") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 106 +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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 107 +SELECT mylt2('a', 'B') as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT mylt2('a', 'B' collate "C") as fail +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 109 +-- conflicting collations +SELECT mylt2('a', 'B' collate "POSIX") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +== 110 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 111 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 112 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 113 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 114 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 115 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 116 +SELECT a, dup(b) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 117 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 118 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 119 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 120 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 121 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 122 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +== 123 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 124 +-- schema manipulation commands + +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +== 125 +CREATE SCHEMA test_schema +-- +STMT: CreateSchemaStmt +== 126 +-- We need to do this this way to cope with varying names for encodings: +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (locale = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +== 127 +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +== 128 +-- fail, duplicate name +CREATE COLLATION IF NOT EXISTS test0 FROM "C" +-- +STMT: DefineStmt +== 129 +-- ok, skipped +CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo') +-- +STMT: DefineStmt +== 130 +-- ok, skipped +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (lc_collate = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || + ', lc_ctype = ' || + quote_literal((SELECT datctype FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +== 131 +CREATE COLLATION test3 (lc_collate = 'en_US.utf8') +-- +STMT: DefineStmt +== 132 +-- fail, need lc_ctype +CREATE COLLATION testx (locale = 'nonsense') +-- +STMT: DefineStmt +== 133 +-- fail + +CREATE COLLATION test4 FROM nonsense +-- +STMT: DefineStmt +== 134 +CREATE COLLATION test5 FROM test0 +-- +STMT: DefineStmt +== 135 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 136 +ALTER COLLATION test1 RENAME TO test11 +-- +STMT: RenameStmt +== 137 +ALTER COLLATION test0 RENAME TO test11 +-- +STMT: RenameStmt +== 138 +-- fail +ALTER COLLATION test1 RENAME TO test22 +-- +STMT: RenameStmt +== 139 +-- fail + +ALTER COLLATION test11 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 140 +ALTER COLLATION test11 OWNER TO nonsense +-- +STMT: AlterOwnerStmt +== 141 +ALTER COLLATION test11 SET SCHEMA test_schema +-- +STMT: AlterObjectSchemaStmt +== 142 +COMMENT ON COLLATION test0 IS 'US English' +-- +STMT: CommentStmt +== 143 +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 144 +DROP COLLATION test0, test_schema.test11, test5 +-- +STMT: DropStmt +== 145 +DROP COLLATION test0 +-- +STMT: DropStmt +== 146 +-- fail +DROP COLLATION IF EXISTS test0 +-- +STMT: DropStmt +== 147 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 148 +DROP SCHEMA test_schema +-- +STMT: DropStmt +== 149 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +== 150 +-- ALTER + +ALTER COLLATION "en_US" REFRESH VERSION +-- +STMT: AlterCollationStmt +== 151 +-- also test for database while we are here +SELECT current_database() AS datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +== 152 +ALTER DATABASE :"datname" REFRESH COLLATION VERSION +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 153 +-- dependencies + +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +== 154 +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0) +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +STMT: CreateStmt +== 155 +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0 +-- +STMT: CreateDomainStmt +== 156 +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0) +-- +STMT: CompositeTypeStmt +== 157 +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo +-- +TABLE: name="collate_dep_test3" schema="" table="collate_dep_test3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 158 +CREATE TABLE collate_dep_test4t (a int, b text) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: CreateStmt +== 159 +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: IndexStmt +== 160 +DROP COLLATION test0 RESTRICT +-- +STMT: DropStmt +== 161 +-- fail +DROP COLLATION test0 CASCADE +-- +STMT: DropStmt +== 162 +DROP TABLE collate_dep_test1, collate_dep_test4t +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: DropStmt +== 163 +DROP TYPE collate_dep_test2 +-- +STMT: DropStmt +== 164 +-- test range types and collations + +create type textrange_c as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +== 165 +create type textrange_en_us as range(subtype=text, collation="en_US") +-- +STMT: CreateRangeStmt +== 166 +select textrange_c('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_c" function="textrange_c" schema="" ctx=Call +STMT: SelectStmt +== 167 +select textrange_en_us('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_en_us" function="textrange_en_us" schema="" ctx=Call +STMT: SelectStmt +== 168 +drop type textrange_c +-- +STMT: DropStmt +== 169 +drop type textrange_en_us +-- +STMT: DropStmt +== 170 +-- nondeterministic collations +-- (not supported with libc provider) +do $$ +BEGIN + EXECUTE 'CREATE COLLATION ctest_det (locale = ' || + quote_literal((SELECT collcollate FROM pg_collation WHERE + collname = 'en_US')) || ', deterministic = true);'; + END +$$ +-- +STMT: DoStmt +== 171 +CREATE COLLATION ctest_nondet (locale = 'en_US', deterministic = false) +-- +STMT: DefineStmt +== 172 +-- cleanup +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +== 173 +DROP SCHEMA collate_tests CASCADE +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/combocid.metadata.json b/parser/testdata/summary/postgres_regress/combocid.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/combocid.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary/postgres_regress/combocid.test b/parser/testdata/summary/postgres_regress/combocid.test new file mode 100644 index 0000000..0f857c3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/combocid.test @@ -0,0 +1,339 @@ +== 001 +|-- +-- Tests for some likely failure cases with combo cmin/cmax mechanism +|-- +CREATE TEMP TABLE combocidtest (foobar int) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DDL +STMT: CreateStmt +== 002 +BEGIN +-- +STMT: TransactionStmt +== 003 +-- a few dummy ops to push up the CommandId counter +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO combocidtest VALUES (1) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO combocidtest VALUES (2) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 016 +SAVEPOINT s1 +-- +STMT: TransactionStmt +== 017 +UPDATE combocidtest SET foobar = foobar + 10 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: UpdateStmt +== 018 +-- here we should see only updated tuples +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 019 +ROLLBACK TO s1 +-- +STMT: TransactionStmt +== 020 +-- now we should see old tuples, but with combo CIDs starting at 0 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 021 +COMMIT +-- +STMT: TransactionStmt +== 022 +-- combo data is not there anymore, but should still see tuples +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 023 +-- Test combo CIDs with portals +BEGIN +-- +STMT: TransactionStmt +== 024 +INSERT INTO combocidtest VALUES (333) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +DECLARE c CURSOR FOR SELECT ctid,cmin,* FROM combocidtest +-- +STMT: DeclareCursorStmt +== 026 +DELETE FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: DeleteStmt +== 027 +FETCH ALL FROM c +-- +STMT: FetchStmt +== 028 +ROLLBACK +-- +STMT: TransactionStmt +== 029 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 030 +-- check behavior with locked tuples +BEGIN +-- +STMT: TransactionStmt +== 031 +-- a few dummy ops to push up the CommandId counter +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO combocidtest VALUES (444) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 043 +SAVEPOINT s1 +-- +STMT: TransactionStmt +== 044 +-- this doesn't affect cmin +SELECT ctid,cmin,* FROM combocidtest FOR UPDATE +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 045 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 046 +-- but this does +UPDATE combocidtest SET foobar = foobar + 10 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: UpdateStmt +== 047 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 048 +ROLLBACK TO s1 +-- +STMT: TransactionStmt +== 049 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 050 +COMMIT +-- +STMT: TransactionStmt +== 051 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +== 052 +-- test for bug reported in +-- CABRT9RC81YUf1=jsmWopcKJEro=VoeG2ou6sPwyOUTx_qteRsg@mail.gmail.com +CREATE TABLE IF NOT EXISTS testcase( + id int PRIMARY KEY, + balance numeric +) +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DDL +STMT: CreateStmt +== 053 +INSERT INTO testcase VALUES (1, 0) +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +BEGIN +-- +STMT: TransactionStmt +== 055 +SELECT * FROM testcase WHERE testcase.id = 1 FOR UPDATE +-- +TABLE: name="testcase" schema="" table="testcase" ctx=Select +FILTER: schema="" table="testcase" column="id" +STMT: SelectStmt +== 056 +UPDATE testcase SET balance = balance + 400 WHERE id=1 +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DML +STMT: UpdateStmt +== 057 +SAVEPOINT subxact +-- +STMT: TransactionStmt +== 058 +UPDATE testcase SET balance = balance - 100 WHERE id=1 +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DML +STMT: UpdateStmt +== 059 +ROLLBACK TO SAVEPOINT subxact +-- +STMT: TransactionStmt +== 060 +-- should return one tuple +SELECT * FROM testcase WHERE id = 1 FOR UPDATE +-- +TABLE: name="testcase" schema="" table="testcase" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 061 +ROLLBACK +-- +STMT: TransactionStmt +== 062 +DROP TABLE testcase +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/comments.metadata.json b/parser/testdata/summary/postgres_regress/comments.metadata.json new file mode 100644 index 0000000..980156f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/comments.metadata.json @@ -0,0 +1,10 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006" + ] +} diff --git a/parser/testdata/summary/postgres_regress/comments.test b/parser/testdata/summary/postgres_regress/comments.test new file mode 100644 index 0000000..c544ef6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/comments.test @@ -0,0 +1,59 @@ +== 001 +|-- +-- COMMENTS +|-- + +SELECT 'trailing' AS first +-- +STMT: SelectStmt +== 002 +-- trailing single line +SELECT /* embedded single line */ 'embedded' AS second +-- +STMT: SelectStmt +== 003 +SELECT /* both embedded and trailing single line */ 'both' AS third +-- +STMT: SelectStmt +== 004 +-- trailing single line + +SELECT 'before multi-line' AS fourth +-- +STMT: SelectStmt +== 005 +/* This is an example of SQL which should not execute: + * select 'multi-line'; + */ +SELECT 'after multi-line' AS fifth +-- +STMT: SelectStmt +== 006 +|-- +-- Nested comments +|-- + +/* +SELECT 'trailing' as x1; -- inside block comment +*/ + +/* This block comment surrounds a query which itself has a block comment... +SELECT /* embedded single line */ 'embedded' AS x2; +*/ + +SELECT -- continued after the following block comments... +/* Deeply nested comment. + This includes a single apostrophe to make sure we aren't decoding this part as a string. +SELECT 'deep nest' AS n1; +/* Second level of nesting... +SELECT 'deeper nest' as n2; +/* Third level of nesting... +SELECT 'deepest nest' as n3; +*/ +Hoo boy. Still two deep... +*/ +Now just one deep... +*/ +'deeply nested example' AS sixth +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/compression.metadata.json b/parser/testdata/summary/postgres_regress/compression.metadata.json new file mode 100644 index 0000000..8e8d1f7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/compression.metadata.json @@ -0,0 +1,91 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087" + ] +} diff --git a/parser/testdata/summary/postgres_regress/compression.test b/parser/testdata/summary/postgres_regress/compression.test new file mode 100644 index 0000000..931506a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/compression.test @@ -0,0 +1,524 @@ +== 001 +-- ensure we get stable results regardless of installation's default +SET default_toast_compression = 'pglz' +-- +STMT: VariableSetStmt +== 002 +-- test creating table with compression method +CREATE TABLE cmdata(f1 text COMPRESSION pglz) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: CreateStmt +== 003 +CREATE INDEX idx ON cmdata(f1) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: IndexStmt +== 004 +INSERT INTO cmdata VALUES(repeat('1234567890', 1000)) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 005 +CREATE TABLE cmdata1(f1 TEXT COMPRESSION lz4) +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=DDL +STMT: CreateStmt +== 006 +INSERT INTO cmdata1 VALUES(repeat('1234567890', 1004)) +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- verify stored compression method in the data +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT pg_column_compression(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- decompress data slice +SELECT SUBSTR(f1, 200, 5) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT SUBSTR(f1, 2000, 50) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +== 011 +-- copy with table creation +SELECT * INTO cmmove1 FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +TABLE: name="cmmove1" schema="" table="cmmove1" ctx=DDL +STMT: SelectStmt +== 012 +SELECT pg_column_compression(f1) FROM cmmove1 +-- +TABLE: name="cmmove1" schema="" table="cmmove1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- copy to existing table +CREATE TABLE cmmove3(f1 text COMPRESSION pglz) +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=DDL +STMT: CreateStmt +== 014 +INSERT INTO cmmove3 SELECT * FROM cmdata +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=DML +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO cmmove3 SELECT * FROM cmdata1 +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=DML +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 016 +SELECT pg_column_compression(f1) FROM cmmove3 +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- test LIKE INCLUDING COMPRESSION +CREATE TABLE cmdata2 (LIKE cmdata1 INCLUDING COMPRESSION) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +== 018 +DROP TABLE cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: DropStmt +== 019 +-- try setting compression for incompressible data type +CREATE TABLE cmdata2 (f1 int COMPRESSION pglz) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +== 020 +-- update using datum from different table +CREATE TABLE cmmove2(f1 text COMPRESSION pglz) +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=DDL +STMT: CreateStmt +== 021 +INSERT INTO cmmove2 VALUES (repeat('1234567890', 1004)) +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 022 +SELECT pg_column_compression(f1) FROM cmmove2 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 023 +UPDATE cmmove2 SET f1 = cmdata1.f1 FROM cmdata1 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=DML +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +STMT: UpdateStmt +== 024 +SELECT pg_column_compression(f1) FROM cmmove2 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 025 +-- test externally stored compressed data +CREATE OR REPLACE FUNCTION large_val() RETURNS TEXT LANGUAGE SQL AS +'select array_agg(fipshash(g::text))::text from generate_series(1, 256) g' +-- +FUNCTION: name="large_val" function="large_val" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 026 +CREATE TABLE cmdata2 (f1 text COMPRESSION pglz) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +== 027 +INSERT INTO cmdata2 SELECT large_val() || repeat('a', 4000) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DML +FUNCTION: name="large_val" function="large_val" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 028 +SELECT pg_column_compression(f1) FROM cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 029 +INSERT INTO cmdata1 SELECT large_val() || repeat('a', 4000) +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=DML +FUNCTION: name="large_val" function="large_val" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 030 +SELECT pg_column_compression(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT SUBSTR(f1, 200, 5) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT SUBSTR(f1, 200, 5) FROM cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +== 033 +DROP TABLE cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: DropStmt +== 034 +--test column type update varlena/non-varlena +CREATE TABLE cmdata2 (f1 int) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +== 035 +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +== 036 +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +== 037 +--changing column storage should not impact the compression method +--but the data should not be compressed +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +== 038 +ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION pglz +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +== 039 +ALTER TABLE cmdata2 ALTER COLUMN f1 SET STORAGE plain +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +== 040 +INSERT INTO cmdata2 VALUES (repeat('123456789', 800)) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 041 +SELECT pg_column_compression(f1) FROM cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- test compression with materialized view +CREATE MATERIALIZED VIEW compressmv(x) AS SELECT * FROM cmdata1 +-- +TABLE: name="compressmv" schema="" table="compressmv" ctx=DDL +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 043 +SELECT pg_column_compression(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT pg_column_compression(x) FROM compressmv +-- +TABLE: name="compressmv" schema="" table="compressmv" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- test compression with partition +CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DDL +STMT: CreateStmt +== 046 +CREATE TABLE cmpart1 PARTITION OF cmpart FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=DDL +STMT: CreateStmt +== 047 +CREATE TABLE cmpart2(f1 text COMPRESSION pglz) +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=DDL +STMT: CreateStmt +== 048 +ALTER TABLE cmpart ATTACH PARTITION cmpart2 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DDL +STMT: AlterTableStmt +== 049 +INSERT INTO cmpart VALUES (repeat('123456789', 1004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO cmpart VALUES (repeat('123456789', 4004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 051 +SELECT pg_column_compression(f1) FROM cmpart1 +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 052 +SELECT pg_column_compression(f1) FROM cmpart2 +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 053 +-- test compression with inheritance +CREATE TABLE cminh() INHERITS(cmdata, cmdata1) +-- +TABLE: name="cminh" schema="" table="cminh" ctx=DDL +STMT: CreateStmt +== 054 +-- error +CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata) +-- +TABLE: name="cminh" schema="" table="cminh" ctx=DDL +STMT: CreateStmt +== 055 +-- error +CREATE TABLE cmdata3(f1 text) +-- +TABLE: name="cmdata3" schema="" table="cmdata3" ctx=DDL +STMT: CreateStmt +== 056 +CREATE TABLE cminh() INHERITS (cmdata, cmdata3) +-- +TABLE: name="cminh" schema="" table="cminh" ctx=DDL +STMT: CreateStmt +== 057 +-- test default_toast_compression GUC +SET default_toast_compression = '' +-- +STMT: VariableSetStmt +== 058 +SET default_toast_compression = 'I do not exist compression' +-- +STMT: VariableSetStmt +== 059 +SET default_toast_compression = 'lz4' +-- +STMT: VariableSetStmt +== 060 +SET default_toast_compression = 'pglz' +-- +STMT: VariableSetStmt +== 061 +-- test alter compression method +ALTER TABLE cmdata ALTER COLUMN f1 SET COMPRESSION lz4 +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: AlterTableStmt +== 062 +INSERT INTO cmdata VALUES (repeat('123456789', 4004)) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 063 +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 064 +ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION default +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +== 065 +-- test alter compression method for materialized views +ALTER MATERIALIZED VIEW compressmv ALTER COLUMN x SET COMPRESSION lz4 +-- +TABLE: name="compressmv" schema="" table="compressmv" ctx=DDL +STMT: AlterTableStmt +== 066 +-- test alter compression method for partitioned tables +ALTER TABLE cmpart1 ALTER COLUMN f1 SET COMPRESSION pglz +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=DDL +STMT: AlterTableStmt +== 067 +ALTER TABLE cmpart2 ALTER COLUMN f1 SET COMPRESSION lz4 +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=DDL +STMT: AlterTableStmt +== 068 +-- new data should be compressed with the current compression method +INSERT INTO cmpart VALUES (repeat('123456789', 1004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 069 +INSERT INTO cmpart VALUES (repeat('123456789', 4004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 070 +SELECT pg_column_compression(f1) FROM cmpart1 +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT pg_column_compression(f1) FROM cmpart2 +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 072 +-- VACUUM FULL does not recompress +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 073 +VACUUM FULL cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: VacuumStmt +== 074 +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +== 075 +-- test expression index +DROP TABLE cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: DropStmt +== 076 +CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +== 077 +CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2)) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: IndexStmt +== 078 +INSERT INTO cmdata2 VALUES((SELECT array_agg(fipshash(g::TEXT))::TEXT FROM +generate_series(1, 50) g), VERSION()) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DML +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 079 +-- check data is ok +SELECT length(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 080 +SELECT length(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 081 +SELECT length(f1) FROM cmmove1 +-- +TABLE: name="cmmove1" schema="" table="cmmove1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT length(f1) FROM cmmove2 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT length(f1) FROM cmmove3 +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 084 +CREATE TABLE badcompresstbl (a text COMPRESSION I_Do_Not_Exist_Compression) +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: CreateStmt +== 085 +-- fails +CREATE TABLE badcompresstbl (a text) +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: CreateStmt +== 086 +ALTER TABLE badcompresstbl ALTER a SET COMPRESSION I_Do_Not_Exist_Compression +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: AlterTableStmt +== 087 +-- fails +DROP TABLE badcompresstbl +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/constraints.metadata.json b/parser/testdata/summary/postgres_regress/constraints.metadata.json new file mode 100644 index 0000000..60d70f4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/constraints.metadata.json @@ -0,0 +1,323 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319" + ] +} diff --git a/parser/testdata/summary/postgres_regress/constraints.test b/parser/testdata/summary/postgres_regress/constraints.test new file mode 100644 index 0000000..f82197b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/constraints.test @@ -0,0 +1,1887 @@ +== 001 +|-- +-- CONSTRAINTS +-- Constraints can be specified with: +-- - DEFAULT clause +-- - CHECK clauses +-- - PRIMARY KEY clauses +-- - UNIQUE clauses +-- - EXCLUDE clauses +|-- + +-- directory paths are passed to us in environment variables + +|-- +-- DEFAULT syntax +|-- + +CREATE TABLE DEFAULT_TBL (i int DEFAULT 100, + x text DEFAULT 'vadim', f float8 DEFAULT 123.456) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO DEFAULT_TBL VALUES (1, 'thomas', 57.0613) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO DEFAULT_TBL VALUES (1, 'bruce') +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO DEFAULT_TBL (i, f) VALUES (2, 987.654) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO DEFAULT_TBL (x) VALUES ('marc') +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO DEFAULT_TBL VALUES (3, null, 1.0) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +SELECT * FROM DEFAULT_TBL +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=Select +STMT: SelectStmt +== 008 +CREATE SEQUENCE DEFAULT_SEQ +-- +STMT: CreateSeqStmt +== 009 +CREATE TABLE DEFAULTEXPR_TBL (i1 int DEFAULT 100 + (200-199) * 2, + i2 int DEFAULT nextval('default_seq')) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DDL +STMT: CreateStmt +== 010 +INSERT INTO DEFAULTEXPR_TBL VALUES (-1, -2) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO DEFAULTEXPR_TBL (i1) VALUES (-3) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (-4) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (NULL) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +SELECT * FROM DEFAULTEXPR_TBL +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=Select +STMT: SelectStmt +== 015 +-- syntax errors +-- test for extraneous comma +CREATE TABLE error_tbl (i int DEFAULT (100, )) +-- +ERROR: syntax error at or near ")" +CURSORPOS: 92 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 016 +-- this will fail because gram.y uses b_expr not a_expr for defaults, +-- to avoid a shift/reduce conflict that arises from NOT NULL being +-- part of the column definition syntax: +CREATE TABLE error_tbl (b1 bool DEFAULT 1 IN (1, 2)) +-- +ERROR: syntax error at or near "IN" +CURSORPOS: 225 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 017 +-- this should work, however: +CREATE TABLE error_tbl (b1 bool DEFAULT (1 IN (1, 2))) +-- +TABLE: name="error_tbl" schema="" table="error_tbl" ctx=DDL +STMT: CreateStmt +== 018 +DROP TABLE error_tbl +-- +TABLE: name="error_tbl" schema="" table="error_tbl" ctx=DDL +STMT: DropStmt +== 019 +|-- +-- CHECK syntax +|-- + +CREATE TABLE CHECK_TBL (x int, + CONSTRAINT CHECK_CON CHECK (x > 3)) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DDL +STMT: CreateStmt +== 020 +INSERT INTO CHECK_TBL VALUES (5) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO CHECK_TBL VALUES (4) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO CHECK_TBL VALUES (3) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO CHECK_TBL VALUES (2) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO CHECK_TBL VALUES (6) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO CHECK_TBL VALUES (1) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +SELECT * FROM CHECK_TBL +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=Select +STMT: SelectStmt +== 027 +CREATE SEQUENCE CHECK_SEQ +-- +STMT: CreateSeqStmt +== 028 +CREATE TABLE CHECK2_TBL (x int, y text, z int, + CONSTRAINT SEQUENCE_CON + CHECK (x > 3 and y <> 'check failed' and z < 8)) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DDL +STMT: CreateStmt +== 029 +INSERT INTO CHECK2_TBL VALUES (4, 'check ok', -2) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO CHECK2_TBL VALUES (1, 'x check failed', -2) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO CHECK2_TBL VALUES (5, 'z check failed', 10) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO CHECK2_TBL VALUES (0, 'check failed', -2) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO CHECK2_TBL VALUES (6, 'check failed', 11) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO CHECK2_TBL VALUES (7, 'check ok', 7) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +SELECT * from CHECK2_TBL +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=Select +STMT: SelectStmt +== 036 +|-- +-- Check constraints on INSERT +|-- + +CREATE SEQUENCE INSERT_SEQ +-- +STMT: CreateSeqStmt +== 037 +CREATE TABLE INSERT_TBL (x INT DEFAULT nextval('insert_seq'), + y TEXT DEFAULT '-NULL-', + z INT DEFAULT -1 * currval('insert_seq'), + CONSTRAINT INSERT_TBL_CON CHECK (x >= 3 AND y <> 'check failed' AND x < 8), + CHECK (x + z = 0)) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DDL +STMT: CreateStmt +== 038 +INSERT INTO INSERT_TBL(x,z) VALUES (2, -2) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +== 040 +SELECT 'one' AS one, nextval('insert_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 041 +INSERT INTO INSERT_TBL(y) VALUES ('Y') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO INSERT_TBL(y) VALUES ('Y') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO INSERT_TBL(x,z) VALUES (1, -2) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO INSERT_TBL(z,x) VALUES (-7, 7) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO INSERT_TBL VALUES (5, 'check failed', -5) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO INSERT_TBL VALUES (7, '!check failed', -7) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +== 049 +INSERT INTO INSERT_TBL(y,z) VALUES ('check failed', 4) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO INSERT_TBL(x,y) VALUES (5, 'check failed') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +INSERT INTO INSERT_TBL(x,y) VALUES (5, '!check failed') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +== 054 +SELECT 'seven' AS one, nextval('insert_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 055 +INSERT INTO INSERT_TBL(y) VALUES ('Y') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +SELECT 'eight' AS one, currval('insert_seq') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- According to SQL, it is OK to insert a record that gives rise to NULL +-- constraint-condition results. Postgres used to reject this, but it +-- was wrong: +INSERT INTO INSERT_TBL VALUES (null, null, null) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +== 059 +|-- +-- Check constraints on system columns +|-- + +CREATE TABLE SYS_COL_CHECK_TBL (city text, state text, is_capital bool, + altitude int, + CHECK (NOT (is_capital AND tableoid::regclass::text = 'sys_col_check_tbl'))) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DDL +STMT: CreateStmt +== 060 +INSERT INTO SYS_COL_CHECK_TBL VALUES ('Seattle', 'Washington', false, 100) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +INSERT INTO SYS_COL_CHECK_TBL VALUES ('Olympia', 'Washington', true, 100) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +SELECT *, tableoid::regclass::text FROM SYS_COL_CHECK_TBL +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=Select +STMT: SelectStmt +== 063 +DROP TABLE SYS_COL_CHECK_TBL +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DDL +STMT: DropStmt +== 064 +|-- +-- Check constraints on system columns other then TableOid should return error +|-- +CREATE TABLE SYS_COL_CHECK_TBL (city text, state text, is_capital bool, + altitude int, + CHECK (NOT (is_capital AND ctid::text = 'sys_col_check_tbl'))) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DDL +STMT: CreateStmt +== 065 +|-- +-- Check inheritance of defaults and constraints +|-- + +CREATE TABLE INSERT_CHILD (cx INT default 42, + cy INT CHECK (cy > x)) + INHERITS (INSERT_TBL) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DDL +STMT: CreateStmt +== 066 +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,11) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,6) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 068 +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (6,-7,7) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +INSERT INTO INSERT_CHILD(x,y,z,cy) VALUES (6,'check failed',-6,7) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +SELECT * FROM INSERT_CHILD +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=Select +STMT: SelectStmt +== 071 +DROP TABLE INSERT_CHILD +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DDL +STMT: DropStmt +== 072 +|-- +-- Check NO INHERIT type of constraints and inheritance +|-- + +CREATE TABLE ATACC1 (TEST INT + CHECK (TEST > 0) NO INHERIT) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 073 +CREATE TABLE ATACC2 (TEST2 INT) INHERITS (ATACC1) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +== 074 +-- check constraint is not there on child +INSERT INTO ATACC2 (TEST) VALUES (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +-- check constraint is there on parent +INSERT INTO ATACC1 (TEST) VALUES (-3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +DROP TABLE ATACC1 CASCADE +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 077 +CREATE TABLE ATACC1 (TEST INT, TEST2 INT + CHECK (TEST > 0), CHECK (TEST2 > 10) NO INHERIT) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +== 078 +CREATE TABLE ATACC2 () INHERITS (ATACC1) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +== 079 +-- check constraint is there on child +INSERT INTO ATACC2 (TEST) VALUES (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +-- check constraint is there on parent +INSERT INTO ATACC1 (TEST) VALUES (-3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +-- check constraint is not there on child +INSERT INTO ATACC2 (TEST2) VALUES (3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +-- check constraint is there on parent +INSERT INTO ATACC1 (TEST2) VALUES (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +DROP TABLE ATACC1 CASCADE +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +== 084 +|-- +-- Check constraints on INSERT INTO +|-- + +DELETE FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: DeleteStmt +== 085 +ALTER SEQUENCE INSERT_SEQ RESTART WITH 4 +-- +STMT: AlterSeqStmt +== 086 +CREATE TEMP TABLE tmp (xd INT, yd TEXT, zd INT) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: CreateStmt +== 087 +INSERT INTO tmp VALUES (null, 'Y', null) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +INSERT INTO tmp VALUES (5, '!check failed', null) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +INSERT INTO tmp VALUES (null, 'try again', null) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +INSERT INTO INSERT_TBL(y) select yd from tmp +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 091 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +== 092 +INSERT INTO INSERT_TBL SELECT * FROM tmp WHERE yd = 'try again' +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +FILTER: schema="" table="" column="yd" +STMT: InsertStmt +STMT: SelectStmt +== 093 +INSERT INTO INSERT_TBL(y,z) SELECT yd, -7 FROM tmp WHERE yd = 'try again' +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +FILTER: schema="" table="" column="yd" +STMT: InsertStmt +STMT: SelectStmt +== 094 +INSERT INTO INSERT_TBL(y,z) SELECT yd, -8 FROM tmp WHERE yd = 'try again' +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +FILTER: schema="" table="" column="yd" +STMT: InsertStmt +STMT: SelectStmt +== 095 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +== 096 +DROP TABLE tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: DropStmt +== 097 +|-- +-- Check constraints on UPDATE +|-- + +UPDATE INSERT_TBL SET x = NULL WHERE x = 5 +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +== 098 +UPDATE INSERT_TBL SET x = 6 WHERE x = 6 +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +== 099 +UPDATE INSERT_TBL SET x = -z, z = -x +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +== 100 +UPDATE INSERT_TBL SET x = z, z = x +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +== 101 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +== 102 +-- DROP TABLE INSERT_TBL; + +|-- +-- Check constraints on COPY FROM +|-- + +CREATE TABLE COPY_TBL (x INT, y TEXT, z INT, + CONSTRAINT COPY_CON + CHECK (x > 3 AND y <> 'check failed' AND x < 7 )) +-- +TABLE: name="copy_tbl" schema="" table="copy_tbl" ctx=DDL +STMT: CreateStmt +== 103 +COPY COPY_TBL FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 104 +SELECT * FROM COPY_TBL +-- +TABLE: name="copy_tbl" schema="" table="copy_tbl" ctx=Select +STMT: SelectStmt +== 105 +COPY COPY_TBL FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 106 +SELECT * FROM COPY_TBL +-- +TABLE: name="copy_tbl" schema="" table="copy_tbl" ctx=Select +STMT: SelectStmt +== 107 +|-- +-- Primary keys +|-- + +CREATE TABLE PRIMARY_TBL (i int PRIMARY KEY, t text) +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: CreateStmt +== 108 +INSERT INTO PRIMARY_TBL VALUES (1, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +INSERT INTO PRIMARY_TBL VALUES (2, 'two') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +INSERT INTO PRIMARY_TBL VALUES (1, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +INSERT INTO PRIMARY_TBL VALUES (4, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +INSERT INTO PRIMARY_TBL VALUES (5, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 113 +INSERT INTO PRIMARY_TBL (t) VALUES ('six') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 114 +SELECT * FROM PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=Select +STMT: SelectStmt +== 115 +DROP TABLE PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: DropStmt +== 116 +CREATE TABLE PRIMARY_TBL (i int, t text, + PRIMARY KEY(i,t)) +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: CreateStmt +== 117 +INSERT INTO PRIMARY_TBL VALUES (1, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +INSERT INTO PRIMARY_TBL VALUES (2, 'two') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +INSERT INTO PRIMARY_TBL VALUES (1, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 120 +INSERT INTO PRIMARY_TBL VALUES (4, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +INSERT INTO PRIMARY_TBL VALUES (5, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +INSERT INTO PRIMARY_TBL (t) VALUES ('six') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +SELECT * FROM PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=Select +STMT: SelectStmt +== 124 +DROP TABLE PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: DropStmt +== 125 +|-- +-- Unique keys +|-- + +CREATE TABLE UNIQUE_TBL (i int UNIQUE, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +== 126 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +INSERT INTO UNIQUE_TBL VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 128 +INSERT INTO UNIQUE_TBL VALUES (1, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +INSERT INTO UNIQUE_TBL VALUES (4, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 130 +INSERT INTO UNIQUE_TBL VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 131 +INSERT INTO UNIQUE_TBL (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 132 +INSERT INTO UNIQUE_TBL (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +INSERT INTO UNIQUE_TBL VALUES (5, 'five-upsert-insert') ON CONFLICT (i) DO UPDATE SET t = 'five-upsert-update' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 134 +INSERT INTO UNIQUE_TBL VALUES (6, 'six-upsert-insert') ON CONFLICT (i) DO UPDATE SET t = 'six-upsert-update' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 135 +-- should fail +INSERT INTO UNIQUE_TBL VALUES (1, 'a'), (2, 'b'), (2, 'b') ON CONFLICT (i) DO UPDATE SET t = 'fails' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +SELECT * FROM UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 137 +DROP TABLE UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +== 138 +CREATE TABLE UNIQUE_TBL (i int UNIQUE NULLS NOT DISTINCT, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +== 139 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 140 +INSERT INTO UNIQUE_TBL VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +INSERT INTO UNIQUE_TBL VALUES (1, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +-- fail +INSERT INTO UNIQUE_TBL VALUES (4, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +INSERT INTO UNIQUE_TBL VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +INSERT INTO UNIQUE_TBL (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 145 +INSERT INTO UNIQUE_TBL (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +-- fail +INSERT INTO UNIQUE_TBL (t) VALUES ('eight') ON CONFLICT DO NOTHING +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +-- no-op + +SELECT * FROM UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 148 +DROP TABLE UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +== 149 +CREATE TABLE UNIQUE_TBL (i int, t text, + UNIQUE(i,t)) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +== 150 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +INSERT INTO UNIQUE_TBL VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +INSERT INTO UNIQUE_TBL VALUES (1, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 153 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +INSERT INTO UNIQUE_TBL VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +INSERT INTO UNIQUE_TBL (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +SELECT * FROM UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 157 +DROP TABLE UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +== 158 +|-- +-- Deferrable unique constraints +|-- + +CREATE TABLE unique_tbl (i int UNIQUE DEFERRABLE, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +== 159 +INSERT INTO unique_tbl VALUES (0, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +INSERT INTO unique_tbl VALUES (1, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 161 +INSERT INTO unique_tbl VALUES (2, 'tree') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +INSERT INTO unique_tbl VALUES (3, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +INSERT INTO unique_tbl VALUES (4, 'five') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +BEGIN +-- +STMT: TransactionStmt +== 165 +-- default is immediate so this should fail right away +UPDATE unique_tbl SET i = 1 WHERE i = 0 +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +== 166 +ROLLBACK +-- +STMT: TransactionStmt +== 167 +-- check is done at end of statement, so this should succeed +UPDATE unique_tbl SET i = i+1 +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +== 168 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 169 +-- explicitly defer the constraint +BEGIN +-- +STMT: TransactionStmt +== 170 +SET CONSTRAINTS unique_tbl_i_key DEFERRED +-- +STMT: ConstraintsSetStmt +== 171 +INSERT INTO unique_tbl VALUES (3, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +DELETE FROM unique_tbl WHERE t = 'tree' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +== 173 +-- makes constraint valid again + +COMMIT +-- +STMT: TransactionStmt +== 174 +-- should succeed + +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 175 +-- try adding an initially deferred constraint +ALTER TABLE unique_tbl DROP CONSTRAINT unique_tbl_i_key +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: AlterTableStmt +== 176 +ALTER TABLE unique_tbl ADD CONSTRAINT unique_tbl_i_key + UNIQUE (i) DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: AlterTableStmt +== 177 +BEGIN +-- +STMT: TransactionStmt +== 178 +INSERT INTO unique_tbl VALUES (1, 'five') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 179 +INSERT INTO unique_tbl VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 180 +UPDATE unique_tbl SET i = 4 WHERE i = 2 +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +== 181 +UPDATE unique_tbl SET i = 2 WHERE i = 4 AND t = 'four' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +== 182 +DELETE FROM unique_tbl WHERE i = 1 AND t = 'one' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +== 183 +DELETE FROM unique_tbl WHERE i = 5 AND t = 'five' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +== 184 +COMMIT +-- +STMT: TransactionStmt +== 185 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 186 +-- should fail at commit-time +BEGIN +-- +STMT: TransactionStmt +== 187 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +-- should succeed for now +COMMIT +-- +STMT: TransactionStmt +== 189 +-- should fail + +-- make constraint check immediate +BEGIN +-- +STMT: TransactionStmt +== 190 +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +== 191 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 192 +-- should fail + +COMMIT +-- +STMT: TransactionStmt +== 193 +-- forced check when SET CONSTRAINTS is called +BEGIN +-- +STMT: TransactionStmt +== 194 +SET CONSTRAINTS ALL DEFERRED +-- +STMT: ConstraintsSetStmt +== 195 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +-- should succeed for now + +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +== 197 +-- should fail + +COMMIT +-- +STMT: TransactionStmt +== 198 +-- test deferrable UNIQUE with a partitioned table +CREATE TABLE parted_uniq_tbl (i int UNIQUE DEFERRABLE) partition by range (i) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DDL +STMT: CreateStmt +== 199 +CREATE TABLE parted_uniq_tbl_1 PARTITION OF parted_uniq_tbl FOR VALUES FROM (0) TO (10) +-- +TABLE: name="parted_uniq_tbl_1" schema="" table="parted_uniq_tbl_1" ctx=DDL +STMT: CreateStmt +== 200 +CREATE TABLE parted_uniq_tbl_2 PARTITION OF parted_uniq_tbl FOR VALUES FROM (20) TO (30) +-- +TABLE: name="parted_uniq_tbl_2" schema="" table="parted_uniq_tbl_2" ctx=DDL +STMT: CreateStmt +== 201 +SELECT conname, conrelid::regclass FROM pg_constraint + WHERE conname LIKE 'parted_uniq%' ORDER BY conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 202 +BEGIN +-- +STMT: TransactionStmt +== 203 +INSERT INTO parted_uniq_tbl VALUES (1) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 204 +SAVEPOINT f +-- +STMT: TransactionStmt +== 205 +INSERT INTO parted_uniq_tbl VALUES (1) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 206 +-- unique violation +ROLLBACK TO f +-- +STMT: TransactionStmt +== 207 +SET CONSTRAINTS parted_uniq_tbl_i_key DEFERRED +-- +STMT: ConstraintsSetStmt +== 208 +INSERT INTO parted_uniq_tbl VALUES (1) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 209 +-- OK now, fail at commit +COMMIT +-- +STMT: TransactionStmt +== 210 +DROP TABLE parted_uniq_tbl +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DDL +STMT: DropStmt +== 211 +-- test naming a constraint in a partition when a conflict exists +CREATE TABLE parted_fk_naming ( + id bigint NOT NULL default 1, + id_abc bigint, + CONSTRAINT dummy_constr FOREIGN KEY (id_abc) + REFERENCES parted_fk_naming (id), + PRIMARY KEY (id) +) +PARTITION BY LIST (id) +-- +TABLE: name="parted_fk_naming" schema="" table="parted_fk_naming" ctx=DDL +STMT: CreateStmt +== 212 +CREATE TABLE parted_fk_naming_1 ( + id bigint NOT NULL default 1, + id_abc bigint, + PRIMARY KEY (id), + CONSTRAINT dummy_constr CHECK (true) +) +-- +TABLE: name="parted_fk_naming_1" schema="" table="parted_fk_naming_1" ctx=DDL +STMT: CreateStmt +== 213 +ALTER TABLE parted_fk_naming ATTACH PARTITION parted_fk_naming_1 FOR VALUES IN ('1') +-- +TABLE: name="parted_fk_naming" schema="" table="parted_fk_naming" ctx=DDL +STMT: AlterTableStmt +== 214 +SELECT conname FROM pg_constraint WHERE conrelid = 'parted_fk_naming_1'::regclass AND contype = 'f' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="contype" +STMT: SelectStmt +== 215 +DROP TABLE parted_fk_naming +-- +TABLE: name="parted_fk_naming" schema="" table="parted_fk_naming" ctx=DDL +STMT: DropStmt +== 216 +|-- +-- Test various ways to create primary keys on partitions, linked to unique +-- indexes (without constraints) on the partitioned table. Ideally these should +-- fail, but we don't dare change released behavior, so instead cope with it at +-- DETACH time. +CREATE TEMP TABLE t (a integer, b integer) PARTITION BY HASH (a, b) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 217 +CREATE TEMP TABLE tp (a integer, b integer, PRIMARY KEY (a, b), UNIQUE (b, a)) +-- +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: CreateStmt +== 218 +ALTER TABLE t ATTACH PARTITION tp FOR VALUES WITH (MODULUS 1, REMAINDER 0) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 219 +CREATE UNIQUE INDEX t_a_idx ON t (a, b) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +== 220 +CREATE UNIQUE INDEX t_b_idx ON t (b, a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +== 221 +ALTER INDEX t_a_idx ATTACH PARTITION tp_pkey +-- +STMT: AlterTableStmt +== 222 +ALTER INDEX t_b_idx ATTACH PARTITION tp_b_a_key +-- +STMT: AlterTableStmt +== 223 +SELECT conname, conparentid, conislocal, coninhcount + FROM pg_constraint WHERE conname IN ('tp_pkey', 'tp_b_a_key') + ORDER BY conname DESC +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 224 +ALTER TABLE t DETACH PARTITION tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 225 +DROP TABLE t, tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: DropStmt +== 226 +CREATE TEMP TABLE t (a integer) PARTITION BY LIST (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 227 +CREATE TEMP TABLE tp (a integer PRIMARY KEY) +-- +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: CreateStmt +== 228 +CREATE UNIQUE INDEX t_a_idx ON t (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +== 229 +ALTER TABLE t ATTACH PARTITION tp FOR VALUES IN (1) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 230 +ALTER TABLE t DETACH PARTITION tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 231 +DROP TABLE t, tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: DropStmt +== 232 +CREATE TEMP TABLE t (a integer) PARTITION BY LIST (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 233 +CREATE TEMP TABLE tp (a integer PRIMARY KEY) +-- +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: CreateStmt +== 234 +CREATE UNIQUE INDEX t_a_idx ON ONLY t (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +== 235 +ALTER TABLE t ATTACH PARTITION tp FOR VALUES IN (1) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 236 +ALTER TABLE t DETACH PARTITION tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 237 +DROP TABLE t, tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: DropStmt +== 238 +CREATE TABLE regress_constr_partitioned (a integer) PARTITION BY LIST (a) +-- +TABLE: name="regress_constr_partitioned" schema="" table="regress_constr_partitioned" ctx=DDL +STMT: CreateStmt +== 239 +CREATE TABLE regress_constr_partition1 PARTITION OF regress_constr_partitioned FOR VALUES IN (1) +-- +TABLE: name="regress_constr_partition1" schema="" table="regress_constr_partition1" ctx=DDL +STMT: CreateStmt +== 240 +ALTER TABLE regress_constr_partition1 ADD PRIMARY KEY (a) +-- +TABLE: name="regress_constr_partition1" schema="" table="regress_constr_partition1" ctx=DDL +STMT: AlterTableStmt +== 241 +CREATE UNIQUE INDEX ON regress_constr_partitioned (a) +-- +TABLE: name="regress_constr_partitioned" schema="" table="regress_constr_partitioned" ctx=DDL +STMT: IndexStmt +== 242 +BEGIN +-- +STMT: TransactionStmt +== 243 +ALTER TABLE regress_constr_partitioned DETACH PARTITION regress_constr_partition1 +-- +TABLE: name="regress_constr_partitioned" schema="" table="regress_constr_partitioned" ctx=DDL +STMT: AlterTableStmt +== 244 +ROLLBACK +-- +STMT: TransactionStmt +== 245 +-- Leave this one in funny state for pg_upgrade testing + +-- test a HOT update that invalidates the conflicting tuple. +-- the trigger should still fire and catch the violation + +BEGIN +-- +STMT: TransactionStmt +== 246 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 247 +-- should succeed for now +UPDATE unique_tbl SET t = 'THREE' WHERE i = 3 AND t = 'Three' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +== 248 +COMMIT +-- +STMT: TransactionStmt +== 249 +-- should fail + +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 250 +-- test a HOT update that modifies the newly inserted tuple, +-- but should succeed because we then remove the other conflicting tuple. + +BEGIN +-- +STMT: TransactionStmt +== 251 +INSERT INTO unique_tbl VALUES(3, 'tree') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 252 +-- should succeed for now +UPDATE unique_tbl SET t = 'threex' WHERE t = 'tree' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +== 253 +DELETE FROM unique_tbl WHERE t = 'three' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +== 254 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 255 +COMMIT +-- +STMT: TransactionStmt +== 256 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +== 257 +DROP TABLE unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +== 258 +|-- +-- EXCLUDE constraints +|-- + +CREATE TABLE circles ( + c1 CIRCLE, + c2 TEXT, + EXCLUDE USING gist + (c1 WITH &&, (c2::circle) WITH &&) + WHERE (circle_center(c1) <> '(0,0)') +) +-- +TABLE: name="circles" schema="" table="circles" ctx=DDL +STMT: CreateStmt +== 259 +-- these should succeed because they don't match the index predicate +INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 260 +INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 4>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 261 +-- succeed +INSERT INTO circles VALUES('<(10,10), 10>', '<(0,0), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 262 +-- fail, overlaps +INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 263 +-- succeed, because violation is ignored +INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>') + ON CONFLICT ON CONSTRAINT circles_c1_c2_excl DO NOTHING +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 264 +-- fail, because DO UPDATE variant requires unique index +INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>') + ON CONFLICT ON CONSTRAINT circles_c1_c2_excl DO UPDATE SET c2 = EXCLUDED.c2 +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 265 +-- succeed because c1 doesn't overlap +INSERT INTO circles VALUES('<(20,20), 1>', '<(0,0), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 266 +-- succeed because c2 doesn't overlap +INSERT INTO circles VALUES('<(20,20), 10>', '<(10,10), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 267 +-- should fail on existing data without the WHERE clause +ALTER TABLE circles ADD EXCLUDE USING gist + (c1 WITH &&, (c2::circle) WITH &&) +-- +TABLE: name="circles" schema="" table="circles" ctx=DDL +STMT: AlterTableStmt +== 268 +-- try reindexing an existing constraint +REINDEX INDEX circles_c1_c2_excl +-- +STMT: ReindexStmt +== 269 +DROP TABLE circles +-- +TABLE: name="circles" schema="" table="circles" ctx=DDL +STMT: DropStmt +== 270 +-- Check deferred exclusion constraint + +CREATE TABLE deferred_excl ( + f1 int, + f2 int, + CONSTRAINT deferred_excl_con EXCLUDE (f1 WITH =) INITIALLY DEFERRED +) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: CreateStmt +== 271 +INSERT INTO deferred_excl VALUES(1) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 272 +INSERT INTO deferred_excl VALUES(2) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 273 +INSERT INTO deferred_excl VALUES(1) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 274 +-- fail +INSERT INTO deferred_excl VALUES(1) ON CONFLICT ON CONSTRAINT deferred_excl_con DO NOTHING +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 275 +-- fail +BEGIN +-- +STMT: TransactionStmt +== 276 +INSERT INTO deferred_excl VALUES(2) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 277 +-- no fail here +COMMIT +-- +STMT: TransactionStmt +== 278 +-- should fail here +BEGIN +-- +STMT: TransactionStmt +== 279 +INSERT INTO deferred_excl VALUES(3) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +INSERT INTO deferred_excl VALUES(3) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 281 +-- no fail here +COMMIT +-- +STMT: TransactionStmt +== 282 +-- should fail here + +-- bug #13148: deferred constraint versus HOT update +BEGIN +-- +STMT: TransactionStmt +== 283 +INSERT INTO deferred_excl VALUES(2, 1) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 284 +-- no fail here +DELETE FROM deferred_excl WHERE f1 = 2 AND f2 IS NULL +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: DeleteStmt +== 285 +-- remove old row +UPDATE deferred_excl SET f2 = 2 WHERE f1 = 2 +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: UpdateStmt +== 286 +COMMIT +-- +STMT: TransactionStmt +== 287 +-- should not fail + +SELECT * FROM deferred_excl +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=Select +STMT: SelectStmt +== 288 +ALTER TABLE deferred_excl DROP CONSTRAINT deferred_excl_con +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: AlterTableStmt +== 289 +-- This should fail, but worth testing because of HOT updates +UPDATE deferred_excl SET f1 = 3 +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: UpdateStmt +== 290 +ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: AlterTableStmt +== 291 +DROP TABLE deferred_excl +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: DropStmt +== 292 +-- Comments +-- Setup a low-level role to enforce non-superuser checks. +CREATE ROLE regress_constraint_comments +-- +STMT: CreateRoleStmt +== 293 +SET SESSION AUTHORIZATION regress_constraint_comments +-- +STMT: VariableSetStmt +== 294 +CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0)) +-- +TABLE: name="constraint_comments_tbl" schema="" table="constraint_comments_tbl" ctx=DDL +STMT: CreateStmt +== 295 +CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0) +-- +STMT: CreateDomainStmt +== 296 +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'yes, the comment' +-- +STMT: CommentStmt +== 297 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment' +-- +STMT: CommentStmt +== 298 +-- no such constraint +COMMENT ON CONSTRAINT no_constraint ON constraint_comments_tbl IS 'yes, the comment' +-- +STMT: CommentStmt +== 299 +COMMENT ON CONSTRAINT no_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment' +-- +STMT: CommentStmt +== 300 +-- no such table/domain +COMMENT ON CONSTRAINT the_constraint ON no_comments_tbl IS 'bad comment' +-- +STMT: CommentStmt +== 301 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad comment' +-- +STMT: CommentStmt +== 302 +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL +-- +STMT: CommentStmt +== 303 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL +-- +STMT: CommentStmt +== 304 +-- unauthorized user +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 305 +CREATE ROLE regress_constraint_comments_noaccess +-- +STMT: CreateRoleStmt +== 306 +SET SESSION AUTHORIZATION regress_constraint_comments_noaccess +-- +STMT: VariableSetStmt +== 307 +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'no, the comment' +-- +STMT: CommentStmt +== 308 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'no, another comment' +-- +STMT: CommentStmt +== 309 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 310 +DROP TABLE constraint_comments_tbl +-- +TABLE: name="constraint_comments_tbl" schema="" table="constraint_comments_tbl" ctx=DDL +STMT: DropStmt +== 311 +DROP DOMAIN constraint_comments_dom +-- +STMT: DropStmt +== 312 +DROP ROLE regress_constraint_comments +-- +STMT: DropRoleStmt +== 313 +DROP ROLE regress_constraint_comments_noaccess +-- +STMT: DropRoleStmt +== 314 +-- Leave some constraints for the pg_upgrade test to pick up +CREATE DOMAIN constraint_comments_dom AS int +-- +STMT: CreateDomainStmt +== 315 +ALTER DOMAIN constraint_comments_dom ADD CONSTRAINT inv_ck CHECK (value > 0) NOT VALID +-- +STMT: AlterDomainStmt +== 316 +COMMENT ON CONSTRAINT inv_ck ON DOMAIN constraint_comments_dom IS 'comment on invalid constraint' +-- +STMT: CommentStmt +== 317 +-- Create a table that exercises pg_upgrade +CREATE TABLE regress_notnull1 (a integer) +-- +TABLE: name="regress_notnull1" schema="" table="regress_notnull1" ctx=DDL +STMT: CreateStmt +== 318 +CREATE TABLE regress_notnull2 () INHERITS (regress_notnull1) +-- +TABLE: name="regress_notnull2" schema="" table="regress_notnull2" ctx=DDL +STMT: CreateStmt +== 319 +ALTER TABLE ONLY regress_notnull2 ALTER COLUMN a SET NOT NULL +-- +TABLE: name="regress_notnull2" schema="" table="regress_notnull2" ctx=DDL +STMT: AlterTableStmt diff --git a/parser/testdata/summary/postgres_regress/conversion.metadata.json b/parser/testdata/summary/postgres_regress/conversion.metadata.json new file mode 100644 index 0000000..8836c0c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/conversion.metadata.json @@ -0,0 +1,69 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065" + ] +} diff --git a/parser/testdata/summary/postgres_regress/conversion.test b/parser/testdata/summary/postgres_regress/conversion.test new file mode 100644 index 0000000..6e44b8f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/conversion.test @@ -0,0 +1,677 @@ +== 001 +|-- +-- create user defined conversion +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION test_enc_setup() RETURNS void + AS :'regresslib', 'test_enc_setup' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 171 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +SELECT FROM test_enc_setup() +-- +FUNCTION: name="test_enc_setup" function="test_enc_setup" schema="" ctx=Call +STMT: SelectStmt +== 003 +CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea) + AS :'regresslib', 'test_enc_conversion' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 105 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +CREATE USER regress_conversion_user WITH NOCREATEDB NOCREATEROLE +-- +STMT: CreateRoleStmt +== 005 +SET SESSION AUTHORIZATION regress_conversion_user +-- +STMT: VariableSetStmt +== 006 +CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 007 +|-- +-- cannot make same name conversion in same schema +|-- +CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 008 +|-- +-- create default conversion with qualified name +|-- +CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 009 +|-- +-- cannot make default conversion with same schema/for_encoding/to_encoding +|-- +CREATE DEFAULT CONVERSION public.mydef2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 010 +-- test comments +COMMENT ON CONVERSION myconv_bad IS 'foo' +-- +STMT: CommentStmt +== 011 +COMMENT ON CONVERSION myconv IS 'bar' +-- +STMT: CommentStmt +== 012 +COMMENT ON CONVERSION myconv IS NULL +-- +STMT: CommentStmt +== 013 +|-- +-- drop user defined conversion +|-- +DROP CONVERSION myconv +-- +STMT: DropStmt +== 014 +DROP CONVERSION mydef +-- +STMT: DropStmt +== 015 +|-- +-- Note: the built-in conversions are exercised in opr_sanity.sql, +-- so there's no need to do that here. +|-- +|-- +-- return to the superuser +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 016 +DROP USER regress_conversion_user +-- +STMT: DropRoleStmt +== 017 +|-- +-- Test built-in conversion functions. +|-- + +-- Helper function to test a conversion. Uses the test_enc_conversion function +-- that was created in the create_function_0 test. +create or replace function test_conv( + input IN bytea, + src_encoding IN text, + dst_encoding IN text, + + result OUT bytea, + errorat OUT bytea, + error OUT text) +language plpgsql as +$$ +declare + validlen int; +begin + -- First try to perform the conversion with noError = false. If that errors out, + -- capture the error message, and try again with noError = true. The second call + -- should succeed and return the position of the error, return that too. + begin + select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, false); + errorat = NULL; + error := NULL; + exception when others then + error := sqlerrm; + select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, true); + errorat = substr(input, validlen + 1); + end; + return; +end; +$$ +-- +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 018 +|-- +-- UTF-8 +|-- +-- The description column must be unique. +CREATE TABLE utf8_verification_inputs (inbytes bytea, description text PRIMARY KEY) +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=DDL +STMT: CreateStmt +== 019 +insert into utf8_verification_inputs values + ('\x66006f', 'NUL byte'), + ('\xaf', 'bare continuation'), + ('\xc5', 'missing second byte in 2-byte char'), + ('\xc080', 'smallest 2-byte overlong'), + ('\xc1bf', 'largest 2-byte overlong'), + ('\xc280', 'next 2-byte after overlongs'), + ('\xdfbf', 'largest 2-byte'), + ('\xe9af', 'missing third byte in 3-byte char'), + ('\xe08080', 'smallest 3-byte overlong'), + ('\xe09fbf', 'largest 3-byte overlong'), + ('\xe0a080', 'next 3-byte after overlong'), + ('\xed9fbf', 'last before surrogates'), + ('\xeda080', 'smallest surrogate'), + ('\xedbfbf', 'largest surrogate'), + ('\xee8080', 'next after surrogates'), + ('\xefbfbf', 'largest 3-byte'), + ('\xf1afbf', 'missing fourth byte in 4-byte char'), + ('\xf0808080', 'smallest 4-byte overlong'), + ('\xf08fbfbf', 'largest 4-byte overlong'), + ('\xf0908080', 'next 4-byte after overlong'), + ('\xf48fbfbf', 'largest 4-byte'), + ('\xf4908080', 'smallest too large'), + ('\xfa9a9a8a8a', '5-byte') +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +-- Test UTF-8 verification slow path +select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_verification_inputs +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- Test UTF-8 verification with ASCII padding appended to provide +-- coverage for algorithms that work on multiple bytes at a time. +-- The error message for a sequence starting with a 4-byte lead +-- will contain all 4 bytes if they are present, so various +-- expressions below add 3 ASCII bytes to the end to ensure +-- consistent error messages. +-- The number 64 below needs to be at least the value of STRIDE_LENGTH in wchar.c. + +-- Test multibyte verification in fast path +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +== 022 +-- Test ASCII verification in fast path where incomplete +-- UTF-8 sequences fall at the end of the preceding chunk. +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +== 023 +-- Test cases where UTF-8 sequences within short text +-- come after the fast path returns. +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64)::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +== 024 +-- Test cases where incomplete UTF-8 sequences fall at the +-- end of the part checked by the fast path. +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +== 025 +CREATE TABLE utf8_inputs (inbytes bytea, description text) +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=DDL +STMT: CreateStmt +== 026 +insert into utf8_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\xc3a4c3b6', 'valid, extra latin chars'), + ('\xd184d0bed0be', 'valid, cyrillic'), + ('\x666f6fe8b1a1', 'valid, kanji/Chinese'), + ('\xe382abe3829a', 'valid, two chars that combine to one in EUC_JIS_2004'), + ('\xe382ab', 'only first half of combined char in EUC_JIS_2004'), + ('\xe382abe382', 'incomplete combination when converted EUC_JIS_2004'), + ('\xecbd94eb81bceba6ac', 'valid, Hangul, Korean'), + ('\x666f6fefa8aa', 'valid, needs mapping function to convert to GB18030'), + ('\x66e8b1ff6f6f', 'invalid byte sequence'), + ('\x66006f', 'invalid, NUL byte'), + ('\x666f6fe8b100', 'invalid, NUL byte'), + ('\x666f6fe8b1', 'incomplete character at end') +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +-- Test UTF-8 verification +select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 028 +-- Test conversions from UTF-8 +select description, inbytes, (test_conv(inbytes, 'utf8', 'euc_jis_2004')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 029 +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin1')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 030 +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin2')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 031 +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin5')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 032 +select description, inbytes, (test_conv(inbytes, 'utf8', 'koi8r')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 033 +select description, inbytes, (test_conv(inbytes, 'utf8', 'gb18030')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 034 +|-- +-- EUC_JIS_2004 +|-- +CREATE TABLE euc_jis_2004_inputs (inbytes bytea, description text) +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=DDL +STMT: CreateStmt +== 035 +insert into euc_jis_2004_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fbedd', 'valid'), + ('\xa5f7', 'valid, translates to two UTF-8 chars '), + ('\xbeddbe', 'incomplete char '), + ('\x666f6f00bedd', 'invalid, NUL byte'), + ('\x666f6fbe00dd', 'invalid, NUL byte'), + ('\x666f6fbedd00', 'invalid, NUL byte'), + ('\xbe04', 'invalid byte sequence') +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +-- Test EUC_JIS_2004 verification +select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'euc_jis_2004')).* from euc_jis_2004_inputs +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- Test conversions from EUC_JIS_2004 +select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'utf8')).* from euc_jis_2004_inputs +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 038 +|-- +-- SHIFT-JIS-2004 +|-- +CREATE TABLE shiftjis2004_inputs (inbytes bytea, description text) +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=DDL +STMT: CreateStmt +== 039 +insert into shiftjis2004_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6f8fdb', 'valid'), + ('\x666f6f81c0', 'valid, no translation to UTF-8'), + ('\x666f6f82f5', 'valid, translates to two UTF-8 chars '), + ('\x666f6f8fdb8f', 'incomplete char '), + ('\x666f6f820a', 'incomplete char, followed by newline '), + ('\x666f6f008fdb', 'invalid, NUL byte'), + ('\x666f6f8f00db', 'invalid, NUL byte'), + ('\x666f6f8fdb00', 'invalid, NUL byte') +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +-- Test SHIFT-JIS-2004 verification +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'shiftjis2004')).* from shiftjis2004_inputs +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- Test conversions from SHIFT-JIS-2004 +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'utf8')).* from shiftjis2004_inputs +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 042 +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'euc_jis_2004')).* from shiftjis2004_inputs +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 043 +|-- +-- GB18030 +|-- +CREATE TABLE gb18030_inputs (inbytes bytea, description text) +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=DDL +STMT: CreateStmt +== 044 +insert into gb18030_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fcff3', 'valid'), + ('\x666f6f8431a530', 'valid, no translation to UTF-8'), + ('\x666f6f84309c38', 'valid, translates to UTF-8 by mapping function'), + ('\x666f6f84309c', 'incomplete char '), + ('\x666f6f84309c0a', 'incomplete char, followed by newline '), + ('\x666f6f84', 'incomplete char at end'), + ('\x666f6f84309c3800', 'invalid, NUL byte'), + ('\x666f6f84309c0038', 'invalid, NUL byte') +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +-- Test GB18030 verification. Round-trip through text so the backing of the +-- bytea values is palloc, not shared_buffers. This lets Valgrind detect +-- reads past the end. +select description, inbytes, (test_conv(inbytes::text::bytea, 'gb18030', 'gb18030')).* from gb18030_inputs +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 046 +-- Test conversions from GB18030 +select description, inbytes, (test_conv(inbytes, 'gb18030', 'utf8')).* from gb18030_inputs +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 047 +|-- +-- ISO-8859-5 +|-- +CREATE TABLE iso8859_5_inputs (inbytes bytea, description text) +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=DDL +STMT: CreateStmt +== 048 +insert into iso8859_5_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\xe4dede', 'valid'), + ('\x00', 'invalid, NUL byte'), + ('\xe400dede', 'invalid, NUL byte'), + ('\xe4dede00', 'invalid, NUL byte') +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +-- Test ISO-8859-5 verification +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'iso8859-5')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 050 +-- Test conversions from ISO-8859-5 +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'utf8')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 051 +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'koi8r')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 052 +select description, inbytes, (test_conv(inbytes, 'iso8859_5', 'mule_internal')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 053 +|-- +-- Big5 +|-- +CREATE TABLE big5_inputs (inbytes bytea, description text) +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=DDL +STMT: CreateStmt +== 054 +insert into big5_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fb648', 'valid'), + ('\x666f6fa27f', 'valid, no translation to UTF-8'), + ('\x666f6fb60048', 'invalid, NUL byte'), + ('\x666f6fb64800', 'invalid, NUL byte') +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +-- Test Big5 verification +select description, inbytes, (test_conv(inbytes, 'big5', 'big5')).* from big5_inputs +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- Test conversions from Big5 +select description, inbytes, (test_conv(inbytes, 'big5', 'utf8')).* from big5_inputs +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 057 +select description, inbytes, (test_conv(inbytes, 'big5', 'mule_internal')).* from big5_inputs +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 058 +|-- +-- MULE_INTERNAL +|-- +CREATE TABLE mic_inputs (inbytes bytea, description text) +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=DDL +STMT: CreateStmt +== 059 +insert into mic_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x8bc68bcf8bcf', 'valid (in KOI8R)'), + ('\x8bc68bcf8b', 'invalid,incomplete char'), + ('\x92bedd', 'valid (in SHIFT_JIS)'), + ('\x92be', 'invalid, incomplete char)'), + ('\x666f6f95a3c1', 'valid (in Big5)'), + ('\x666f6f95a3', 'invalid, incomplete char'), + ('\x9200bedd', 'invalid, NUL byte'), + ('\x92bedd00', 'invalid, NUL byte'), + ('\x8b00c68bcf8bcf', 'invalid, NUL byte') +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +-- Test MULE_INTERNAL verification +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'mule_internal')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 061 +-- Test conversions from MULE_INTERNAL +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'koi8r')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 062 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'iso8859-5')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 063 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'sjis')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 064 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'big5')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +== 065 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'euc_jp')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/copy.metadata.json b/parser/testdata/summary/postgres_regress/copy.metadata.json new file mode 100644 index 0000000..8e8d1f7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copy.metadata.json @@ -0,0 +1,91 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087" + ] +} diff --git a/parser/testdata/summary/postgres_regress/copy.test b/parser/testdata/summary/postgres_regress/copy.test new file mode 100644 index 0000000..49d4dd6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copy.test @@ -0,0 +1,595 @@ +== 001 +|-- +-- COPY +|-- + +-- directory paths are passed to us in environment variables + +--- test copying in CSV mode with various styles +--- of embedded line ending characters + +create temp table copytest ( + style text, + test text, + filler int) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DDL +STMT: CreateStmt +== 002 +insert into copytest values('DOS',E'abc\r\ndef',1) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +insert into copytest values('Unix',E'abc\ndef',2) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +insert into copytest values('Mac',E'abc\rdef',3) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +insert into copytest values(E'esc\\ape',E'a\\r\\\r\\\n\\nb',4) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +copy copytest to :'filename' csv +-- +ERROR: syntax error at or near ":" +CURSORPOS: 18 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +create temp table copytest2 (like copytest) +-- +TABLE: name="copytest2" schema="" table="copytest2" ctx=DDL +STMT: CreateStmt +== 008 +copy copytest2 from :'filename' csv +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +select * from copytest except select * from copytest2 +-- +TABLE: name="copytest" schema="" table="copytest" ctx=Select +TABLE: name="copytest2" schema="" table="copytest2" ctx=Select +STMT: SelectStmt +== 010 +truncate copytest2 +-- +TABLE: name="copytest2" schema="" table="copytest2" ctx=DDL +STMT: TruncateStmt +== 011 +--- same test but with an escape char different from quote char + +copy copytest to :'filename' csv quote '''' escape E'\\' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 83 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +copy copytest2 from :'filename' csv quote '''' escape E'\\' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 013 +select * from copytest except select * from copytest2 +-- +TABLE: name="copytest" schema="" table="copytest" ctx=Select +TABLE: name="copytest2" schema="" table="copytest2" ctx=Select +STMT: SelectStmt +== 014 +-- test header line feature + +create temp table copytest3 ( + c1 int, + "col with , comma" text, + "col with "" quote" int) +-- +TABLE: name="copytest3" schema="" table="copytest3" ctx=DDL +STMT: CreateStmt +== 015 +copy copytest3 from stdin csv header +-- +TABLE: name="copytest3" schema="" table="copytest3" ctx=Select +STMT: CopyStmt +== 016 +copy copytest3 to stdout csv header +-- +TABLE: name="copytest3" schema="" table="copytest3" ctx=Select +STMT: CopyStmt +== 017 +create temp table copytest4 ( + c1 int, + "colname with tab: " text) +-- +TABLE: name="copytest4" schema="" table="copytest4" ctx=DDL +STMT: CreateStmt +== 018 +copy copytest4 from stdin (header) +-- +TABLE: name="copytest4" schema="" table="copytest4" ctx=Select +STMT: CopyStmt +== 019 +copy copytest4 to stdout (header) +-- +TABLE: name="copytest4" schema="" table="copytest4" ctx=Select +STMT: CopyStmt +== 020 +-- test copy from with a partitioned table +create table parted_copytest ( + a int, + b int, + c text +) partition by list (b) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: CreateStmt +== 021 +create table parted_copytest_a1 (c text, b int, a int) +-- +TABLE: name="parted_copytest_a1" schema="" table="parted_copytest_a1" ctx=DDL +STMT: CreateStmt +== 022 +create table parted_copytest_a2 (a int, c text, b int) +-- +TABLE: name="parted_copytest_a2" schema="" table="parted_copytest_a2" ctx=DDL +STMT: CreateStmt +== 023 +alter table parted_copytest attach partition parted_copytest_a1 for values in(1) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: AlterTableStmt +== 024 +alter table parted_copytest attach partition parted_copytest_a2 for values in(2) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: AlterTableStmt +== 025 +-- We must insert enough rows to trigger multi-inserts. These are only +-- enabled adaptively when there are few enough partition changes. +insert into parted_copytest select x,1,'One' from generate_series(1,1000) x +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 026 +insert into parted_copytest select x,2,'Two' from generate_series(1001,1010) x +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 027 +insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 028 +copy (select * from parted_copytest order by a) to :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 52 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +truncate parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +== 030 +copy parted_copytest from :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 031 +-- Ensure COPY FREEZE errors for partitioned tables. +begin +-- +STMT: TransactionStmt +== 032 +truncate parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +== 033 +copy parted_copytest from :'filename' (freeze) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 034 +rollback +-- +STMT: TransactionStmt +== 035 +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 036 +truncate parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +== 037 +-- create before insert row trigger on parted_copytest_a2 +create function part_ins_func() returns trigger language plpgsql as $$ +begin + return new; +end; +$$ +-- +FUNCTION: name="part_ins_func" function="part_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 038 +create trigger part_ins_trig + before insert on parted_copytest_a2 + for each row + execute procedure part_ins_func() +-- +TABLE: name="parted_copytest_a2" schema="" table="parted_copytest_a2" ctx=DDL +STMT: CreateTrigStmt +== 039 +copy parted_copytest from :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 040 +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 041 +truncate table parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +== 042 +create index on parted_copytest (b) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: IndexStmt +== 043 +drop trigger part_ins_trig on parted_copytest_a2 +-- +TABLE: name="parted_copytest_a2" schema="" table="parted_copytest_a2" ctx=DDL +STMT: DropStmt +== 044 +copy parted_copytest from stdin +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +STMT: CopyStmt +== 045 +-- Ensure index entries were properly added during the copy. +select * from parted_copytest where b = 1 +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 046 +select * from parted_copytest where b = 2 +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 047 +drop table parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: DropStmt +== 048 +|-- +-- Progress reporting for COPY +|-- +create table tab_progress_reporting ( + name text, + age int4, + location point, + salary int4, + manager name +) +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: CreateStmt +== 049 +-- Add a trigger to catch and print the contents of the catalog view +-- pg_stat_progress_copy during data insertion. This allows to test +-- the validation of some progress reports for COPY FROM where the trigger +-- would fire. +create function notice_after_tab_progress_reporting() returns trigger AS +$$ +declare report record; +begin + -- The fields ignored here are the ones that may not remain + -- consistent across multiple runs. The sizes reported may differ + -- across platforms, so just check if these are strictly positive. + with progress_data as ( + select + relid::regclass::text as relname, + command, + type, + bytes_processed > 0 as has_bytes_processed, + bytes_total > 0 as has_bytes_total, + tuples_processed, + tuples_excluded + from pg_stat_progress_copy + where pid = pg_backend_pid()) + select into report (to_jsonb(r)) as value + from progress_data r; + + raise info 'progress: %', report.value::text; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="notice_after_tab_progress_reporting" function="notice_after_tab_progress_reporting" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 050 +create trigger check_after_tab_progress_reporting + after insert on tab_progress_reporting + for each statement + execute function notice_after_tab_progress_reporting() +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: CreateTrigStmt +== 051 +-- Generate COPY FROM report with PIPE. +copy tab_progress_reporting from stdin +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=Select +STMT: CopyStmt +== 052 +-- Generate COPY FROM report with FILE, with some excluded tuples. +truncate tab_progress_reporting +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: TruncateStmt +== 053 +copy tab_progress_reporting from :'filename' + where (salary < 2000) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 054 +drop trigger check_after_tab_progress_reporting on tab_progress_reporting +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: DropStmt +== 055 +drop function notice_after_tab_progress_reporting() +-- +FUNCTION: name="notice_after_tab_progress_reporting" function="notice_after_tab_progress_reporting" schema="" ctx=DDL +STMT: DropStmt +== 056 +drop table tab_progress_reporting +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: DropStmt +== 057 +-- Test header matching feature +create table header_copytest ( + a int, + b int, + c text +) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: CreateStmt +== 058 +-- Make sure it works with dropped columns +alter table header_copytest drop column c +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: AlterTableStmt +== 059 +alter table header_copytest add column c text +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: AlterTableStmt +== 060 +copy header_copytest to stdout with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 061 +copy header_copytest from stdin with (header wrong_choice) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 062 +copy header_copytest (c, a, b) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 063 +copy header_copytest from stdin with (header match, format csv) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 064 +-- errors +copy header_copytest (c, b, a) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 065 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 066 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 067 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 068 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 069 +SELECT * FROM header_copytest ORDER BY a +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: SelectStmt +== 070 +-- Drop an extra column, in the middle of the existing set. +alter table header_copytest drop column b +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: AlterTableStmt +== 071 +-- works +copy header_copytest (c, a) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 072 +copy header_copytest (a, c) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 073 +-- errors +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 074 +copy header_copytest (a, c) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +== 075 +SELECT * FROM header_copytest ORDER BY a +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: SelectStmt +== 076 +drop table header_copytest +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: DropStmt +== 077 +-- test COPY with overlong column defaults +create temp table oversized_column_default ( + col1 varchar(5) DEFAULT 'more than 5 chars', + col2 varchar(5)) +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=DDL +STMT: CreateStmt +== 078 +-- normal COPY should work +copy oversized_column_default from stdin +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=Select +STMT: CopyStmt +== 079 +-- error if the column is excluded +copy oversized_column_default (col2) from stdin +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=Select +STMT: CopyStmt +== 080 +-- error if the DEFAULT option is given +copy oversized_column_default from stdin (default '') +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=Select +STMT: CopyStmt +== 081 +drop table oversized_column_default +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=DDL +STMT: DropStmt +== 082 +|-- +-- Create partitioned table that does not allow bulk insertions, to test bugs +-- related to the reuse of BulkInsertState across partitions (only done when +-- not using bulk insert). Switching between partitions often makes it more +-- likely to encounter these bugs, so we just switch on roughly every insert +-- by having an even/odd number partition and inserting evenly distributed +-- data. +|-- +CREATE TABLE parted_si ( + id int not null, + data text not null, + -- prevent use of bulk insert by having a volatile function + rand float8 not null default random() +) +PARTITION BY LIST((id % 2)) +-- +TABLE: name="parted_si" schema="" table="parted_si" ctx=DDL +STMT: CreateStmt +== 083 +CREATE TABLE parted_si_p_even PARTITION OF parted_si FOR VALUES IN (0) +-- +TABLE: name="parted_si_p_even" schema="" table="parted_si_p_even" ctx=DDL +STMT: CreateStmt +== 084 +CREATE TABLE parted_si_p_odd PARTITION OF parted_si FOR VALUES IN (1) +-- +TABLE: name="parted_si_p_odd" schema="" table="parted_si_p_odd" ctx=DDL +STMT: CreateStmt +== 085 +-- Test that bulk relation extension handles reusing a single BulkInsertState +-- across partitions. Without the fix applied, this reliably reproduces +-- #18130 unless shared_buffers is extremely small (preventing any use of bulk +-- relation extension). See +-- https://postgr.es/m/18130-7a86a7356a75209d%40postgresql.org +-- https://postgr.es/m/257696.1695670946%40sss.pgh.pa.us +COPY parted_si(id, data) FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 409 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 086 +-- An earlier bug (see commit b1ecb9b3fcf) could end up using a buffer from +-- the wrong partition. This test is *not* guaranteed to trigger that bug, but +-- does so when shared_buffers is small enough. To test if we encountered the +-- bug, check that the partition condition isn't violated. +SELECT tableoid::regclass, id % 2 = 0 is_even, count(*) from parted_si GROUP BY 1, 2 ORDER BY 1 +-- +TABLE: name="parted_si" schema="" table="parted_si" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 087 +DROP TABLE parted_si +-- +TABLE: name="parted_si" schema="" table="parted_si" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/copy2.metadata.json b/parser/testdata/summary/postgres_regress/copy2.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copy2.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary/postgres_regress/copy2.test b/parser/testdata/summary/postgres_regress/copy2.test new file mode 100644 index 0000000..fd127c4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copy2.test @@ -0,0 +1,373 @@ +== 001 +CREATE TEMP TABLE x ( + a serial, + b int, + c text not null default 'stuff', + d text, + e text +) ; + +CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS ' + BEGIN + NEW.e := ''before trigger fired''::text; + return NEW; + END; +' LANGUAGE plpgsql; + +CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS ' + BEGIN + UPDATE x set e=''after trigger fired'' where c=''stuff''; + return NULL; + END; +' LANGUAGE plpgsql; + +CREATE TRIGGER trg_x_after AFTER INSERT ON x +FOR EACH ROW EXECUTE PROCEDURE fn_x_after(); + +CREATE TRIGGER trg_x_before BEFORE INSERT ON x +FOR EACH ROW EXECUTE PROCEDURE fn_x_before(); + +COPY x (a, b, c, d, e) from stdin; + +COPY x (b, d) from stdin; + +COPY x (b, d) from stdin; + +COPY x (a, b, c, d, e) from stdin; + +-- non-existent column in column list: should fail +COPY x (xyz) from stdin; +COPY x from stdin; +COPY x from stdin; + +-- extra data: should fail +COPY x from stdin; + +-- various COPY options: delimiters, oids, NULL string, encoding +COPY x (b, c, d, e) from stdin delimiter ',' null 'x'; + +COPY x from stdin WITH DELIMITER AS ';' NULL AS ''; + +COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii'; + +COPY x TO stdout WHERE a = 1; +COPY x from stdin WHERE a = 50004; + +COPY x from stdin WHERE a > 60003; + +COPY x from stdin WHERE f > 60003; + +-- test end of copy marker +CREATE TEMP TABLE testeoc (a text); + +COPY testeoc FROM stdin CSV; + +COPY testeoc TO stdout CSV; + +-- test handling of nonstandard null marker that violates escaping rules + +CREATE TEMP TABLE testnull(a int, b text); +INSERT INTO testnull VALUES (1, E'\\0'), (NULL, NULL); + +COPY testnull TO stdout WITH NULL AS E'\\0'; + +COPY testnull FROM stdin WITH NULL AS E'\\0'; + +SELECT * FROM testnull; + +BEGIN; +CREATE TABLE vistest (LIKE testeoc); +COPY vistest FROM stdin CSV; +COMMIT; +SELECT * FROM vistest; +BEGIN; +TRUNCATE vistest; +COPY vistest FROM stdin CSV; +SELECT * FROM vistest; +SAVEPOINT s1; +TRUNCATE vistest; +COPY vistest FROM stdin CSV; +SELECT * FROM vistest; +COMMIT; +SELECT * FROM vistest; + +BEGIN; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +SAVEPOINT s1; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +COMMIT; +SELECT * FROM vistest; + +BEGIN; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +COMMIT; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +BEGIN; +TRUNCATE vistest; +SAVEPOINT s1; +COPY vistest FROM stdin CSV FREEZE; +COMMIT; +BEGIN; +INSERT INTO vistest VALUES ('z'); +SAVEPOINT s1; +TRUNCATE vistest; +ROLLBACK TO SAVEPOINT s1; +COPY vistest FROM stdin CSV FREEZE; +COMMIT; +CREATE FUNCTION truncate_in_subxact() RETURNS VOID AS +$$ +BEGIN + TRUNCATE vistest; +EXCEPTION + WHEN OTHERS THEN + INSERT INTO vistest VALUES ('subxact failure'); +END; +$$ language plpgsql; +BEGIN; +INSERT INTO vistest VALUES ('z'); +SELECT truncate_in_subxact(); +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +COMMIT; +SELECT * FROM vistest; +-- Test FORCE_NOT_NULL and FORCE_NULL options +CREATE TEMP TABLE forcetest ( + a INT NOT NULL, + b TEXT NOT NULL, + c TEXT, + d TEXT, + e TEXT +); +-- should succeed with no effect ("b" remains an empty string, "c" remains NULL) +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b), FORCE_NULL(c)); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 1; +-- should succeed, FORCE_NULL and FORCE_NOT_NULL can be both specified +BEGIN; +COPY forcetest (a, b, c, d) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(c,d), FORCE_NULL(c,d)); +COMMIT; +SELECT c, d FROM forcetest WHERE a = 2; +-- should fail with not-null constraint violation +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b), FORCE_NOT_NULL(c)); +ROLLBACK; +-- should fail with "not referenced by COPY" error +BEGIN; +COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b)); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 4; +-- should succeed with effect ("b" remains an empty string) +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL *); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 5; +-- should succeed with effect ("c" remains NULL) +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL *); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 6; +-- should fail with "conflicting or redundant options" error +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL *, FORCE_NOT_NULL(b)); +copy check_con_tbl from stdin; +select * from check_con_tbl; + +-- test with RLS enabled. +CREATE ROLE regress_rls_copy_user; +CREATE ROLE regress_rls_copy_user_colperms; +CREATE TABLE rls_t1 (a int, b int, c int); + +COPY rls_t1 (a, b, c) from stdin; + +CREATE POLICY p1 ON rls_t1 FOR SELECT USING (a % 2 = 0); +ALTER TABLE rls_t1 ENABLE ROW LEVEL SECURITY; +ALTER TABLE rls_t1 FORCE ROW LEVEL SECURITY; + +GRANT SELECT ON TABLE rls_t1 TO regress_rls_copy_user; +GRANT SELECT (a, b) ON TABLE rls_t1 TO regress_rls_copy_user_colperms; + +-- all columns +COPY rls_t1 TO stdout; +COPY rls_t1 (a, b, c) TO stdout; + +-- subset of columns +COPY rls_t1 (a) TO stdout; +COPY rls_t1 (a, b) TO stdout; + +-- column reordering +COPY rls_t1 (b, a) TO stdout; + +SET SESSION AUTHORIZATION regress_rls_copy_user; + +-- all columns +COPY rls_t1 TO stdout; +COPY rls_t1 (a, b, c) TO stdout; + +-- subset of columns +COPY rls_t1 (a) TO stdout; +COPY rls_t1 (a, b) TO stdout; + +-- column reordering +COPY rls_t1 (b, a) TO stdout; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_rls_copy_user_colperms; + +-- attempt all columns (should fail) +COPY rls_t1 TO stdout; +COPY rls_t1 (a, b, c) TO stdout; + +-- try to copy column with no privileges (should fail) +COPY rls_t1 (c) TO stdout; + +-- subset of columns (should succeed) +COPY rls_t1 (a) TO stdout; +COPY rls_t1 (a, b) TO stdout; + +RESET SESSION AUTHORIZATION; + +-- test with INSTEAD OF INSERT trigger on a view +CREATE TABLE instead_of_insert_tbl(id serial, name text); +CREATE VIEW instead_of_insert_tbl_view AS SELECT ''::text AS str; + +COPY instead_of_insert_tbl_view FROM stdin; -- fail +test1 + +CREATE FUNCTION fun_instead_of_insert_tbl() RETURNS trigger AS $$ +BEGIN + INSERT INTO instead_of_insert_tbl (name) VALUES (NEW.str); + +SELECT * FROM instead_of_insert_tbl; + +-- Test of COPY optimization with view using INSTEAD OF INSERT +-- trigger when relation is created in the same transaction as +-- when COPY is executed. +BEGIN; +CREATE VIEW instead_of_insert_tbl_view_2 as select ''::text as str; +CREATE TRIGGER trig_instead_of_insert_tbl_view_2 + INSTEAD OF INSERT ON instead_of_insert_tbl_view_2 + FOR EACH ROW EXECUTE PROCEDURE fun_instead_of_insert_tbl(); + +COPY instead_of_insert_tbl_view_2 FROM stdin; + +SELECT * FROM instead_of_insert_tbl; +COMMIT; + +-- tests for on_error option +CREATE TABLE check_ign_err (n int, m int[], k int); +COPY check_ign_err FROM STDIN WITH (on_error stop); + +-- want context for notices + +COPY check_ign_err FROM STDIN WITH (on_error ignore, log_verbosity verbose); + +-- tests for on_error option with log_verbosity and null constraint via domain +CREATE DOMAIN dcheck_ign_err2 varchar(15) NOT NULL; +CREATE TABLE check_ign_err2 (n int, m int[], k int, l dcheck_ign_err2); +COPY check_ign_err2 FROM STDIN WITH (on_error ignore, log_verbosity verbose); + +-- reset context choice + +SELECT * FROM check_ign_err; + +SELECT * FROM check_ign_err2; + +-- test datatype error that can't be handled as soft: should fail +CREATE TABLE hard_err(foo widget); +COPY hard_err FROM STDIN WITH (on_error ignore); + +-- test missing data: should fail +COPY check_ign_err FROM STDIN WITH (on_error ignore); + +-- test extra data: should fail +COPY check_ign_err FROM STDIN WITH (on_error ignore); + +-- clean up +DROP TABLE forcetest; +DROP TABLE vistest; +DROP FUNCTION truncate_in_subxact(); +DROP TABLE x, y; +DROP TABLE rls_t1 CASCADE; +DROP ROLE regress_rls_copy_user; +DROP ROLE regress_rls_copy_user_colperms; +DROP FUNCTION fn_x_before(); +DROP FUNCTION fn_x_after(); +DROP TABLE instead_of_insert_tbl; +DROP VIEW instead_of_insert_tbl_view; +DROP VIEW instead_of_insert_tbl_view_2; +DROP FUNCTION fun_instead_of_insert_tbl(); +DROP TABLE check_ign_err; +DROP TABLE check_ign_err2; +DROP DOMAIN dcheck_ign_err2; +DROP TABLE hard_err; + +|-- +-- COPY FROM ... DEFAULT +|-- + +create temp table copy_default ( + id integer primary key, + text_value text not null default 'test', + ts_value timestamp without time zone not null default '2022-07-05' +); + +-- if DEFAULT is not specified, then the marker will be regular data +copy copy_default from stdin; + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +copy copy_default from stdin with (format csv); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +-- DEFAULT cannot be used in binary mode +copy copy_default from stdin with (format binary, default '\D'); + +copy copy_default from stdin with (format csv, default '\D'); + +-- The DEFAULT marker must be unquoted and unescaped or it's not recognized +copy copy_default from stdin with (default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +copy copy_default from stdin with (format csv, default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +-- successful usage of DEFAULT option in COPY +copy copy_default from stdin with (default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +copy copy_default from stdin with (format csv, default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +-- DEFAULT cannot be used in COPY TO +copy (select 1 as test) TO stdout with (default '\D'); +-- +ERROR: WHERE clause not allowed with COPY TO +CURSORPOS: 1145 +FILENAME: gram.y +FUNCNAME: base_yyparse diff --git a/parser/testdata/summary/postgres_regress/copydml.metadata.json b/parser/testdata/summary/postgres_regress/copydml.metadata.json new file mode 100644 index 0000000..f53b7f4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copydml.metadata.json @@ -0,0 +1,63 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059" + ] +} diff --git a/parser/testdata/summary/postgres_regress/copydml.test b/parser/testdata/summary/postgres_regress/copydml.test new file mode 100644 index 0000000..156d8f5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copydml.test @@ -0,0 +1,324 @@ +== 001 +|-- +-- Test cases for COPY (INSERT/UPDATE/DELETE) TO +|-- +create table copydml_test (id serial, t text) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: CreateStmt +== 002 +insert into copydml_test (t) values ('a') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +insert into copydml_test (t) values ('b') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +insert into copydml_test (t) values ('c') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +insert into copydml_test (t) values ('d') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +insert into copydml_test (t) values ('e') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +|-- +-- Test COPY (insert/update/delete ...) +|-- +copy (insert into copydml_test (t) values ('f') returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 008 +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 009 +copy (delete from copydml_test where t = 'g' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 010 +|-- +-- Test \copy (insert/update/delete ...) +|-- + +-- Error cases +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 011 +copy (update copydml_test set t = 'g') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 012 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 013 +create rule qqq as on insert to copydml_test do instead nothing +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 014 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 015 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 016 +create rule qqq as on insert to copydml_test do also delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 017 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 018 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 019 +create rule qqq as on insert to copydml_test do instead (delete from copydml_test; delete from copydml_test) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 020 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 021 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 022 +create rule qqq as on insert to copydml_test where new.t <> 'f' do instead delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 023 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 024 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 025 +create rule qqq as on update to copydml_test do instead nothing +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 026 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 027 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 028 +create rule qqq as on update to copydml_test do also delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 029 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 030 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 031 +create rule qqq as on update to copydml_test do instead (delete from copydml_test; delete from copydml_test) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 032 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 033 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 034 +create rule qqq as on update to copydml_test where new.t <> 'f' do instead delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 035 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 036 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 037 +create rule qqq as on delete to copydml_test do instead nothing +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 038 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 039 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 040 +create rule qqq as on delete to copydml_test do also insert into copydml_test default values +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 041 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 042 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 043 +create rule qqq as on delete to copydml_test do instead (insert into copydml_test default values; insert into copydml_test default values) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 044 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 045 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 046 +create rule qqq as on delete to copydml_test where old.t <> 'f' do instead insert into copydml_test default values +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 047 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 048 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 049 +create rule qqq as on insert to copydml_test do instead notify copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +== 050 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 051 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 052 +-- triggers +create function qqq_trig() returns trigger as $$ +begin +if tg_op in ('INSERT', 'UPDATE') then + raise notice '% % %', tg_when, tg_op, new.id; + return new; +else + raise notice '% % %', tg_when, tg_op, old.id; + return old; +end if; +end +$$ language plpgsql +-- +FUNCTION: name="qqq_trig" function="qqq_trig" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 053 +create trigger qqqbef before insert or update or delete on copydml_test + for each row execute procedure qqq_trig() +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: CreateTrigStmt +== 054 +create trigger qqqaf after insert or update or delete on copydml_test + for each row execute procedure qqq_trig() +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: CreateTrigStmt +== 055 +copy (insert into copydml_test (t) values ('f') returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 056 +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 057 +copy (delete from copydml_test where t = 'g' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +== 058 +drop table copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +== 059 +drop function qqq_trig() +-- +FUNCTION: name="qqq_trig" function="qqq_trig" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/copyselect.metadata.json b/parser/testdata/summary/postgres_regress/copyselect.metadata.json new file mode 100644 index 0000000..56098cb --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copyselect.metadata.json @@ -0,0 +1,25 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021" + ] +} diff --git a/parser/testdata/summary/postgres_regress/copyselect.test b/parser/testdata/summary/postgres_regress/copyselect.test new file mode 100644 index 0000000..eb112ca --- /dev/null +++ b/parser/testdata/summary/postgres_regress/copyselect.test @@ -0,0 +1,148 @@ +== 001 +|-- +-- Test cases for COPY (select) TO +|-- +create table test1 (id serial, t text) +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: CreateStmt +== 002 +insert into test1 (t) values ('a') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +insert into test1 (t) values ('b') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +insert into test1 (t) values ('c') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +insert into test1 (t) values ('d') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +insert into test1 (t) values ('e') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +create table test2 (id serial, t text) +-- +TABLE: name="test2" schema="" table="test2" ctx=DDL +STMT: CreateStmt +== 008 +insert into test2 (t) values ('A') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +insert into test2 (t) values ('B') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +insert into test2 (t) values ('C') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +insert into test2 (t) values ('D') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +insert into test2 (t) values ('E') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +create view v_test1 +as select 'v_'||t from test1 +-- +TABLE: name="v_test1" schema="" table="v_test1" ctx=DDL +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 014 +|-- +-- Test COPY table TO +|-- +copy test1 to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: CopyStmt +== 015 +|-- +-- This should fail +|-- +copy v_test1 to stdout +-- +TABLE: name="v_test1" schema="" table="v_test1" ctx=Select +STMT: CopyStmt +== 016 +|-- +-- Test COPY (select) TO +|-- +copy (select t from test1 where id=1) to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +FILTER: schema="" table="" column="id" +STMT: CopyStmt +== 017 +|-- +-- Test COPY (select for update) TO +|-- +copy (select t from test1 where id=3 for update) to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +FILTER: schema="" table="" column="id" +STMT: CopyStmt +== 018 +|-- +-- This should fail +|-- +copy (select t into temp test3 from test1 where id=3) to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +TABLE: name="test3" schema="" table="test3" ctx=DDL +FILTER: schema="" table="" column="id" +STMT: CopyStmt +== 019 +|-- +-- This should fail +|-- +copy (select * from test1) from stdin +-- +ERROR: syntax error at or near "from" +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 020 +2 +select * from test3 +-- +ERROR: syntax error at or near "2" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 021 +drop table test3 +-- +TABLE: name="test3" schema="" table="test3" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/create_aggregate.metadata.json b/parser/testdata/summary/postgres_regress/create_aggregate.metadata.json new file mode 100644 index 0000000..f53b7f4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_aggregate.metadata.json @@ -0,0 +1,63 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_aggregate.test b/parser/testdata/summary/postgres_regress/create_aggregate.test new file mode 100644 index 0000000..3665eeb --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_aggregate.test @@ -0,0 +1,476 @@ +== 001 +|-- +-- CREATE_AGGREGATE +|-- + +-- all functions CREATEd +CREATE AGGREGATE newavg ( + sfunc = int4_avg_accum, basetype = int4, stype = _int8, + finalfunc = int8_avg, + initcond1 = '{0,0}' +) +-- +STMT: DefineStmt +== 002 +-- test comments +COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment' +-- +STMT: CommentStmt +== 003 +COMMENT ON AGGREGATE newavg (int4) IS 'an agg comment' +-- +STMT: CommentStmt +== 004 +COMMENT ON AGGREGATE newavg (int4) IS NULL +-- +STMT: CommentStmt +== 005 +-- without finalfunc; test obsolete spellings 'sfunc1' etc +CREATE AGGREGATE newsum ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, + initcond1 = '0' +) +-- +STMT: DefineStmt +== 006 +-- zero-argument aggregate +CREATE AGGREGATE newcnt (*) ( + sfunc = int8inc, stype = int8, + initcond = '0', parallel = safe +) +-- +STMT: DefineStmt +== 007 +-- old-style spelling of same (except without parallel-safe; that's too new) +CREATE AGGREGATE oldcnt ( + sfunc = int8inc, basetype = 'ANY', stype = int8, + initcond = '0' +) +-- +STMT: DefineStmt +== 008 +-- aggregate that only cares about null/nonnull input +CREATE AGGREGATE newcnt ("any") ( + sfunc = int8inc_any, stype = int8, + initcond = '0' +) +-- +STMT: DefineStmt +== 009 +COMMENT ON AGGREGATE nosuchagg (*) IS 'should fail' +-- +STMT: CommentStmt +== 010 +COMMENT ON AGGREGATE newcnt (*) IS 'an agg(*) comment' +-- +STMT: CommentStmt +== 011 +COMMENT ON AGGREGATE newcnt ("any") IS 'an agg(any) comment' +-- +STMT: CommentStmt +== 012 +-- multi-argument aggregate +create function sum3(int8,int8,int8) returns int8 as +'select $1 + $2 + $3' language sql strict immutable +-- +FUNCTION: name="sum3" function="sum3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 013 +create aggregate sum2(int8,int8) ( + sfunc = sum3, stype = int8, + initcond = '0' +) +-- +STMT: DefineStmt +== 014 +-- multi-argument aggregates sensitive to distinct/order, strict/nonstrict +create type aggtype as (a integer, b integer, c text) +-- +STMT: CompositeTypeStmt +== 015 +create function aggf_trans(aggtype[],integer,integer,text) returns aggtype[] +as 'select array_append($1,ROW($2,$3,$4)::aggtype)' +language sql strict immutable +-- +FUNCTION: name="aggf_trans" function="aggf_trans" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +create function aggfns_trans(aggtype[],integer,integer,text) returns aggtype[] +as 'select array_append($1,ROW($2,$3,$4)::aggtype)' +language sql immutable +-- +FUNCTION: name="aggfns_trans" function="aggfns_trans" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +create aggregate aggfstr(integer,integer,text) ( + sfunc = aggf_trans, stype = aggtype[], + initcond = '{}' +) +-- +STMT: DefineStmt +== 018 +create aggregate aggfns(integer,integer,text) ( + sfunc = aggfns_trans, stype = aggtype[], sspace = 10000, + initcond = '{}' +) +-- +STMT: DefineStmt +== 019 +-- check error cases that would require run-time type coercion +create function least_accum(int8, int8) returns int8 language sql as + 'select least($1, $2)' +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 020 +create aggregate least_agg(int4) ( + stype = int8, sfunc = least_accum +) +-- +STMT: DefineStmt +== 021 +-- fails + +drop function least_accum(int8, int8) +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: DropStmt +== 022 +create function least_accum(anycompatible, anycompatible) +returns anycompatible language sql as + 'select least($1, $2)' +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 023 +create aggregate least_agg(int4) ( + stype = int8, sfunc = least_accum +) +-- +STMT: DefineStmt +== 024 +-- fails + +create aggregate least_agg(int8) ( + stype = int8, sfunc = least_accum +) +-- +STMT: DefineStmt +== 025 +drop function least_accum(anycompatible, anycompatible) cascade +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: DropStmt +== 026 +-- variadic aggregates +create function least_accum(anyelement, variadic anyarray) +returns anyelement language sql as + 'select least($1, min($2[i])) from generate_subscripts($2,1) g(i)' +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 027 +create aggregate least_agg(variadic items anyarray) ( + stype = anyelement, sfunc = least_accum +) +-- +STMT: DefineStmt +== 028 +create function cleast_accum(anycompatible, variadic anycompatiblearray) +returns anycompatible language sql as + 'select least($1, min($2[i])) from generate_subscripts($2,1) g(i)' +-- +FUNCTION: name="cleast_accum" function="cleast_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +create aggregate cleast_agg(variadic items anycompatiblearray) ( + stype = anycompatible, sfunc = cleast_accum +) +-- +STMT: DefineStmt +== 030 +-- test ordered-set aggs using built-in support functions +create aggregate my_percentile_disc(float8 ORDER BY anyelement) ( + stype = internal, + sfunc = ordered_set_transition, + finalfunc = percentile_disc_final, + finalfunc_extra = true, + finalfunc_modify = read_write +) +-- +STMT: DefineStmt +== 031 +create aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") ( + stype = internal, + sfunc = ordered_set_transition_multi, + finalfunc = rank_final, + finalfunc_extra = true, + hypothetical +) +-- +STMT: DefineStmt +== 032 +alter aggregate my_percentile_disc(float8 ORDER BY anyelement) + rename to test_percentile_disc +-- +STMT: RenameStmt +== 033 +alter aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") + rename to test_rank +-- +STMT: RenameStmt +== 034 +-- moving-aggregate options + +CREATE AGGREGATE sumdouble (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi +) +-- +STMT: DefineStmt +== 035 +-- aggregate combine and serialization functions + +-- can't specify just one of serialfunc and deserialfunc +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize +) +-- +STMT: DefineStmt +== 036 +-- serialfunc must have correct parameters +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_deserialize, + deserialfunc = numeric_avg_deserialize +) +-- +STMT: DefineStmt +== 037 +-- deserialfunc must have correct parameters +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_serialize +) +-- +STMT: DefineStmt +== 038 +-- ensure combine function parameters are checked +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = int4larger +) +-- +STMT: DefineStmt +== 039 +-- ensure create aggregate works. +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +) +-- +STMT: DefineStmt +== 040 +-- Ensure all these functions made it into the catalog +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggfnoid" +STMT: SelectStmt +== 041 +DROP AGGREGATE myavg (numeric) +-- +STMT: DropStmt +== 042 +-- create or replace aggregate +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg +) +-- +STMT: DefineStmt +== 043 +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +) +-- +STMT: DefineStmt +== 044 +-- Ensure all these functions made it into the catalog again +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggfnoid" +STMT: SelectStmt +== 045 +-- can change stype: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add +) +-- +STMT: DefineStmt +== 046 +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggfnoid" +STMT: SelectStmt +== 047 +-- can't change return type: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add, + finalfunc = numeric_out +) +-- +STMT: DefineStmt +== 048 +-- can't change to a different kind: +CREATE OR REPLACE AGGREGATE myavg (order by numeric) +( + stype = numeric, + sfunc = numeric_add +) +-- +STMT: DefineStmt +== 049 +-- can't change plain function to aggregate: +create function sum4(int8,int8,int8,int8) returns int8 as +'select $1 + $2 + $3 + $4' language sql strict immutable +-- +FUNCTION: name="sum4" function="sum4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 050 +CREATE OR REPLACE AGGREGATE sum3 (int8,int8,int8) +( + stype = int8, + sfunc = sum4 +) +-- +STMT: DefineStmt +== 051 +drop function sum4(int8,int8,int8,int8) +-- +FUNCTION: name="sum4" function="sum4" schema="" ctx=DDL +STMT: DropStmt +== 052 +DROP AGGREGATE myavg (numeric) +-- +STMT: DropStmt +== 053 +-- invalid: bad parallel-safety marking +CREATE AGGREGATE mysum (int) +( + stype = int, + sfunc = int4pl, + parallel = pear +) +-- +STMT: DefineStmt +== 054 +-- invalid: nonstrict inverse with strict forward function + +CREATE FUNCTION float8mi_n(float8, float8) RETURNS float8 AS +$$ SELECT $1 - $2; $$ +LANGUAGE SQL +-- +FUNCTION: name="float8mi_n" function="float8mi_n" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 055 +CREATE AGGREGATE invalidsumdouble (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi_n +) +-- +STMT: DefineStmt +== 056 +-- invalid: non-matching result types + +CREATE FUNCTION float8mi_int(float8, float8) RETURNS int AS +$$ SELECT CAST($1 - $2 AS INT); $$ +LANGUAGE SQL +-- +FUNCTION: name="float8mi_int" function="float8mi_int" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 057 +CREATE AGGREGATE wrongreturntype (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi_int +) +-- +STMT: DefineStmt +== 058 +-- invalid: non-lowercase quoted identifiers + +CREATE AGGREGATE case_agg ( -- old syntax + "Sfunc1" = int4pl, + "Basetype" = int4, + "Stype1" = int4, + "Initcond1" = '0', + "Parallel" = safe +) +-- +STMT: DefineStmt +== 059 +CREATE AGGREGATE case_agg(float8) +( + "Stype" = internal, + "Sfunc" = ordered_set_transition, + "Finalfunc" = percentile_disc_final, + "Finalfunc_extra" = true, + "Finalfunc_modify" = read_write, + "Parallel" = safe +) +-- +STMT: DefineStmt diff --git a/parser/testdata/summary/postgres_regress/create_am.metadata.json b/parser/testdata/summary/postgres_regress/create_am.metadata.json new file mode 100644 index 0000000..83b3df4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_am.metadata.json @@ -0,0 +1,146 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_am.test b/parser/testdata/summary/postgres_regress/create_am.test new file mode 100644 index 0000000..4bbe8d3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_am.test @@ -0,0 +1,1019 @@ +== 001 +|-- +-- Create access method tests +|-- + +-- Make gist2 over gisthandler. In fact, it would be a synonym to gist. +CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler +-- +STMT: CreateAmStmt +== 002 +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER int4in +-- +STMT: CreateAmStmt +== 003 +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER heap_tableam_handler +-- +STMT: CreateAmStmt +== 004 +-- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist +CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: IndexStmt +== 005 +-- Make operator class for boxes using gist2 +CREATE OPERATOR CLASS box_ops DEFAULT + FOR TYPE box USING gist2 AS + OPERATOR 1 <<, + OPERATOR 2 &<, + OPERATOR 3 &&, + OPERATOR 4 &>, + OPERATOR 5 >>, + OPERATOR 6 ~=, + OPERATOR 7 @>, + OPERATOR 8 <@, + OPERATOR 9 &<|, + OPERATOR 10 <<|, + OPERATOR 11 |>>, + OPERATOR 12 |&>, + FUNCTION 1 gist_box_consistent(internal, box, smallint, oid, internal), + FUNCTION 2 gist_box_union(internal, internal), + -- don't need compress, decompress, or fetch functions + FUNCTION 5 gist_box_penalty(internal, internal, internal), + FUNCTION 6 gist_box_picksplit(internal, internal), + FUNCTION 7 gist_box_same(box, box, internal) +-- +STMT: CreateOpClassStmt +== 006 +-- Create gist2 index on fast_emp4000 +CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: IndexStmt +== 007 +-- Now check the results from plain indexscan; temporarily drop existing +-- index grect2ind to ensure it doesn't capture the plan +BEGIN +-- +STMT: TransactionStmt +== 008 +DROP INDEX grect2ind +-- +STMT: DropStmt +== 009 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 010 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 011 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 012 +EXPLAIN (COSTS OFF) +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +== 013 +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 014 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +== 015 +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 016 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +== 017 +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 018 +ROLLBACK +-- +STMT: TransactionStmt +== 019 +-- Try to drop access method: fail because of dependent objects +DROP ACCESS METHOD gist2 +-- +STMT: DropStmt +== 020 +-- Drop access method cascade +-- To prevent a (rare) deadlock against autovacuum, +-- we must lock the table that owns the index that will be dropped +BEGIN +-- +STMT: TransactionStmt +== 021 +LOCK TABLE fast_emp4000 +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: LockStmt +== 022 +DROP ACCESS METHOD gist2 CASCADE +-- +STMT: DropStmt +== 023 +COMMIT +-- +STMT: TransactionStmt +== 024 +|-- +-- Test table access methods +|-- + +-- prevent empty values +SET default_table_access_method = '' +-- +STMT: VariableSetStmt +== 025 +-- prevent nonexistent values +SET default_table_access_method = 'I do not exist AM' +-- +STMT: VariableSetStmt +== 026 +-- prevent setting it to an index AM +SET default_table_access_method = 'btree' +-- +STMT: VariableSetStmt +== 027 +-- Create a heap2 table am handler with heapam handler +CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler +-- +STMT: CreateAmStmt +== 028 +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER int4in +-- +STMT: CreateAmStmt +== 029 +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER bthandler +-- +STMT: CreateAmStmt +== 030 +SELECT amname, amhandler, amtype FROM pg_am where amtype = 't' ORDER BY 1, 2 +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FILTER: schema="" table="" column="amtype" +STMT: SelectStmt +== 031 +-- First create tables employing the new AM using USING + +-- plain CREATE TABLE +CREATE TABLE tableam_tbl_heap2(f1 int) USING heap2 +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=DDL +STMT: CreateStmt +== 032 +INSERT INTO tableam_tbl_heap2 VALUES(1) +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1 +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: SelectStmt +== 034 +-- CREATE TABLE AS +CREATE TABLE tableam_tblas_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2 +-- +TABLE: name="tableam_tblas_heap2" schema="" table="tableam_tblas_heap2" ctx=DDL +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 035 +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1 +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: SelectStmt +== 036 +-- SELECT INTO doesn't support USING +SELECT INTO tableam_tblselectinto_heap2 USING heap2 FROM tableam_tbl_heap2 +-- +ERROR: syntax error at or near "USING" +CURSORPOS: 78 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 037 +-- CREATE VIEW doesn't support USING +CREATE VIEW tableam_view_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2 +-- +ERROR: syntax error at or near "USING" +CURSORPOS: 69 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +-- CREATE SEQUENCE doesn't support USING +CREATE SEQUENCE tableam_seq_heap2 USING heap2 +-- +ERROR: syntax error at or near "USING" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +-- CREATE MATERIALIZED VIEW does support USING +CREATE MATERIALIZED VIEW tableam_tblmv_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2 +-- +TABLE: name="tableam_tblmv_heap2" schema="" table="tableam_tblmv_heap2" ctx=DDL +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 040 +SELECT f1 FROM tableam_tblmv_heap2 ORDER BY f1 +-- +TABLE: name="tableam_tblmv_heap2" schema="" table="tableam_tblmv_heap2" ctx=Select +STMT: SelectStmt +== 041 +-- CREATE TABLE .. PARTITION BY supports USING. +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a) USING heap2 +-- +TABLE: name="tableam_parted_heap2" schema="" table="tableam_parted_heap2" ctx=DDL +STMT: CreateStmt +== 042 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'tableam_parted_heap2' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +== 043 +DROP TABLE tableam_parted_heap2 +-- +TABLE: name="tableam_parted_heap2" schema="" table="tableam_parted_heap2" ctx=DDL +STMT: DropStmt +== 044 +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a) +-- +TABLE: name="tableam_parted_heap2" schema="" table="tableam_parted_heap2" ctx=DDL +STMT: CreateStmt +== 045 +-- new partitions will inherit from the current default, rather the partition root +SET default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +== 046 +CREATE TABLE tableam_parted_a_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('a') +-- +TABLE: name="tableam_parted_a_heap2" schema="" table="tableam_parted_a_heap2" ctx=DDL +STMT: CreateStmt +== 047 +SET default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +== 048 +CREATE TABLE tableam_parted_b_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('b') +-- +TABLE: name="tableam_parted_b_heap2" schema="" table="tableam_parted_b_heap2" ctx=DDL +STMT: CreateStmt +== 049 +RESET default_table_access_method +-- +STMT: VariableSetStmt +== 050 +-- but the method can be explicitly specified +CREATE TABLE tableam_parted_c_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('c') USING heap +-- +TABLE: name="tableam_parted_c_heap2" schema="" table="tableam_parted_c_heap2" ctx=DDL +STMT: CreateStmt +== 051 +CREATE TABLE tableam_parted_d_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('d') USING heap2 +-- +TABLE: name="tableam_parted_d_heap2" schema="" table="tableam_parted_d_heap2" ctx=DDL +STMT: CreateStmt +== 052 +-- List all objects in AM +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc, + pg_am AS pa +WHERE pa.oid = pc.relam + AND pa.amname = 'heap2' +ORDER BY 3, 1, 2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +ALIAS: "pcm"="pg_class" +FILTER: schema="" table="pa" column="oid" +FILTER: schema="" table="pc" column="relam" +FILTER: schema="" table="pa" column="amname" +FILTER: schema="" table="pcm" column="reltoastrelid" +FILTER: schema="" table="pc" column="oid" +STMT: SelectStmt +== 053 +-- Show dependencies onto AM - there shouldn't be any for toast +SELECT pg_describe_object(classid,objid,objsubid) AS obj +FROM pg_depend, pg_am +WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_am.amname = 'heap2' +ORDER BY classid, objid, objsubid +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_am" column="amname" +STMT: SelectStmt +== 054 +-- ALTER TABLE SET ACCESS METHOD +CREATE TABLE heaptable USING heap AS + SELECT a, repeat(a::text, 100) FROM generate_series(1,9) AS a +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 055 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +== 056 +-- Switching to heap2 adds new dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +== 057 +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 = 'heaptable'::regclass + ORDER BY 1, 2 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 058 +-- Switching to heap should not have a dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +== 059 +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 = 'heaptable'::regclass + ORDER BY 1, 2 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 060 +ALTER TABLE heaptable SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +== 061 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +== 062 +SELECT COUNT(a), COUNT(1) FILTER(WHERE a=1) FROM heaptable +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 063 +-- DEFAULT access method +BEGIN +-- +STMT: TransactionStmt +== 064 +SET LOCAL default_table_access_method TO heap2 +-- +STMT: VariableSetStmt +== 065 +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +== 066 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +== 067 +SET LOCAL default_table_access_method TO heap +-- +STMT: VariableSetStmt +== 068 +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +== 069 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +== 070 +ROLLBACK +-- +STMT: TransactionStmt +== 071 +-- ALTER MATERIALIZED VIEW SET ACCESS METHOD +CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT * FROM heaptable +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +TABLE: name="heaptable" schema="" table="heaptable" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 072 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +== 073 +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2 +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: AlterTableStmt +== 074 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +== 075 +SELECT COUNT(a), COUNT(1) FILTER(WHERE a=1) FROM heapmv +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 076 +-- No support for multiple subcommands +ALTER TABLE heaptable SET ACCESS METHOD heap, SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +== 077 +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT, SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +== 078 +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2 +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: AlterTableStmt +== 079 +DROP MATERIALIZED VIEW heapmv +-- +STMT: DropStmt +== 080 +DROP TABLE heaptable +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: DropStmt +== 081 +-- Partitioned table with USING +CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) USING heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: CreateStmt +== 082 +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +== 083 +DROP TABLE am_partitioned +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: DropStmt +== 084 +-- Partition hierarchies with access methods +BEGIN +-- +STMT: TransactionStmt +== 085 +SET LOCAL default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +== 086 +CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: CreateStmt +== 087 +-- pg_class.relam is 0, no dependency recorded between the AM and the +-- partitioned table. +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 088 +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +== 089 +-- New default is set, with dependency added. +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 090 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +== 091 +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +== 092 +-- Default is set, with dependency updated. +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +== 093 +ALTER TABLE am_partitioned SET ACCESS METHOD heap +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 094 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +== 095 +-- Dependency pinned, hence removed. +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +== 096 +-- Default and AM set in the clause are the same, relam should be set. +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +== 097 +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 098 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +== 099 +-- Reset to default +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 100 +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 101 +-- Upon ALTER TABLE SET ACCESS METHOD on a partitioned table, new partitions +-- will inherit the AM set. Existing partitioned are unchanged. +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 102 +SET LOCAL default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +== 103 +CREATE TABLE am_partitioned_0 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 0) +-- +TABLE: name="am_partitioned_0" schema="" table="am_partitioned_0" ctx=DDL +STMT: CreateStmt +== 104 +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +== 105 +CREATE TABLE am_partitioned_1 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="am_partitioned_1" schema="" table="am_partitioned_1" ctx=DDL +STMT: CreateStmt +== 106 +SET LOCAL default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +== 107 +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 108 +CREATE TABLE am_partitioned_2 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 2) +-- +TABLE: name="am_partitioned_2" schema="" table="am_partitioned_2" ctx=DDL +STMT: CreateStmt +== 109 +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 110 +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 111 +CREATE TABLE am_partitioned_3 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 3) +-- +TABLE: name="am_partitioned_3" schema="" table="am_partitioned_3" ctx=DDL +STMT: CreateStmt +== 112 +-- Partitioned table with relam at 0 +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 113 +CREATE TABLE am_partitioned_5p PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 5) PARTITION BY hash(y) +-- +TABLE: name="am_partitioned_5p" schema="" table="am_partitioned_5p" ctx=DDL +STMT: CreateStmt +== 114 +-- Partitions of this partitioned table inherit default AM at creation +-- time. +CREATE TABLE am_partitioned_5p1 PARTITION OF am_partitioned_5p + FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="am_partitioned_5p1" schema="" table="am_partitioned_5p1" ctx=DDL +STMT: CreateStmt +== 115 +-- Partitioned table with relam set. +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +== 116 +CREATE TABLE am_partitioned_6p PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 6) PARTITION BY hash(y) +-- +TABLE: name="am_partitioned_6p" schema="" table="am_partitioned_6p" ctx=DDL +STMT: CreateStmt +== 117 +-- Partitions of this partitioned table inherit its AM. +CREATE TABLE am_partitioned_6p1 PARTITION OF am_partitioned_6p + FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="am_partitioned_6p1" schema="" table="am_partitioned_6p1" ctx=DDL +STMT: CreateStmt +== 118 +SELECT c.relname, a.amname FROM pg_class c, pg_am a + WHERE c.relam = a.oid AND + c.relname LIKE 'am_partitioned%' +UNION ALL +SELECT c.relname, 'default' FROM pg_class c + WHERE c.relam = 0 + AND c.relname LIKE 'am_partitioned%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 119 +DROP TABLE am_partitioned +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: DropStmt +== 120 +COMMIT +-- +STMT: TransactionStmt +== 121 +-- Second, create objects in the new AM by changing the default AM +BEGIN +-- +STMT: TransactionStmt +== 122 +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +== 123 +-- following tests should all respect the default AM +CREATE TABLE tableam_tbl_heapx(f1 int) +-- +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=DDL +STMT: CreateStmt +== 124 +CREATE TABLE tableam_tblas_heapx AS SELECT * FROM tableam_tbl_heapx +-- +TABLE: name="tableam_tblas_heapx" schema="" table="tableam_tblas_heapx" ctx=DDL +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 125 +SELECT INTO tableam_tblselectinto_heapx FROM tableam_tbl_heapx +-- +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +TABLE: name="tableam_tblselectinto_heapx" schema="" table="tableam_tblselectinto_heapx" ctx=DDL +STMT: SelectStmt +== 126 +CREATE MATERIALIZED VIEW tableam_tblmv_heapx USING heap2 AS SELECT * FROM tableam_tbl_heapx +-- +TABLE: name="tableam_tblmv_heapx" schema="" table="tableam_tblmv_heapx" ctx=DDL +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 127 +CREATE TABLE tableam_parted_heapx (a text, b int) PARTITION BY list (a) +-- +TABLE: name="tableam_parted_heapx" schema="" table="tableam_parted_heapx" ctx=DDL +STMT: CreateStmt +== 128 +CREATE TABLE tableam_parted_1_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('a', 'b') +-- +TABLE: name="tableam_parted_1_heapx" schema="" table="tableam_parted_1_heapx" ctx=DDL +STMT: CreateStmt +== 129 +-- but an explicitly set AM overrides it +CREATE TABLE tableam_parted_2_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('c', 'd') USING heap +-- +TABLE: name="tableam_parted_2_heapx" schema="" table="tableam_parted_2_heapx" ctx=DDL +STMT: CreateStmt +== 130 +-- sequences, views and foreign servers shouldn't have an AM +CREATE VIEW tableam_view_heapx AS SELECT * FROM tableam_tbl_heapx +-- +TABLE: name="tableam_view_heapx" schema="" table="tableam_view_heapx" ctx=DDL +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 131 +CREATE SEQUENCE tableam_seq_heapx +-- +STMT: CreateSeqStmt +== 132 +CREATE FOREIGN DATA WRAPPER fdw_heap2 VALIDATOR postgresql_fdw_validator +-- +STMT: CreateFdwStmt +== 133 +CREATE SERVER fs_heap2 FOREIGN DATA WRAPPER fdw_heap2 +-- +STMT: CreateForeignServerStmt +== 134 +CREATE FOREIGN table tableam_fdw_heapx () SERVER fs_heap2 +-- +STMT: CreateForeignTableStmt +== 135 +-- Verify that new AM was used for tables, matviews, but not for sequences, views and fdws +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc + LEFT JOIN pg_am AS pa ON (pa.oid = pc.relam) +WHERE pc.relname LIKE 'tableam_%_heapx' +ORDER BY 3, 1, 2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +ALIAS: "pcm"="pg_class" +FILTER: schema="" table="pc" column="relname" +FILTER: schema="" table="pcm" column="reltoastrelid" +FILTER: schema="" table="pc" column="oid" +STMT: SelectStmt +== 136 +-- don't want to keep those tables, nor the default +ROLLBACK +-- +STMT: TransactionStmt +== 137 +-- Third, check that we can neither create a table using a nonexistent +-- AM, nor using an index AM +CREATE TABLE i_am_a_failure() USING "notempty" +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +== 138 +CREATE TABLE i_am_a_failure() USING i_do_not_exist_am +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +== 139 +CREATE TABLE i_am_a_failure() USING "I do not exist AM" +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +== 140 +CREATE TABLE i_am_a_failure() USING "btree" +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +== 141 +-- Other weird invalid cases that cause problems +CREATE FOREIGN TABLE fp PARTITION OF tableam_parted_a_heap2 DEFAULT SERVER x +-- +STMT: CreateForeignTableStmt +== 142 +-- Drop table access method, which fails as objects depends on it +DROP ACCESS METHOD heap2 +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/create_cast.metadata.json b/parser/testdata/summary/postgres_regress/create_cast.metadata.json new file mode 100644 index 0000000..5d34ab7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_cast.metadata.json @@ -0,0 +1,28 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_cast.test b/parser/testdata/summary/postgres_regress/create_cast.test new file mode 100644 index 0000000..65bc7cc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_cast.test @@ -0,0 +1,166 @@ +== 001 +|-- +-- CREATE_CAST +|-- + +-- Create some types to test with +CREATE TYPE casttesttype +-- +STMT: DefineStmt +== 002 +CREATE FUNCTION casttesttype_in(cstring) + RETURNS casttesttype + AS 'textin' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="casttesttype_in" function="casttesttype_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +CREATE FUNCTION casttesttype_out(casttesttype) + RETURNS cstring + AS 'textout' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="casttesttype_out" function="casttesttype_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 004 +CREATE TYPE casttesttype ( + internallength = variable, + input = casttesttype_in, + output = casttesttype_out, + alignment = int4 +) +-- +STMT: DefineStmt +== 005 +-- a dummy function to test with +CREATE FUNCTION casttestfunc(casttesttype) RETURNS int4 LANGUAGE SQL AS +$$ SELECT 1; $$ +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +SELECT casttestfunc('foo'::text) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- fails, as there's no cast + +-- Try binary coercion cast +CREATE CAST (text AS casttesttype) WITHOUT FUNCTION +-- +STMT: CreateCastStmt +== 008 +SELECT casttestfunc('foo'::text) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- doesn't work, as the cast is explicit +SELECT casttestfunc('foo'::text::casttesttype) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +== 010 +-- should work +DROP CAST (text AS casttesttype) +-- +STMT: DropStmt +== 011 +-- cleanup + +-- Try IMPLICIT binary coercion cast +CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT +-- +STMT: CreateCastStmt +== 012 +SELECT casttestfunc('foo'::text) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- Should work now + +-- Try I/O conversion cast. +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +== 014 +-- No cast yet, should fail + +CREATE CAST (int4 AS casttesttype) WITH INOUT +-- +STMT: CreateCastStmt +== 015 +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +== 016 +-- Should work now + +DROP CAST (int4 AS casttesttype) +-- +STMT: DropStmt +== 017 +-- Try cast with a function + +CREATE FUNCTION int4_casttesttype(int4) RETURNS casttesttype LANGUAGE SQL AS +$$ SELECT ('foo'::text || $1::text)::casttesttype; $$ +-- +FUNCTION: name="int4_casttesttype" function="int4_casttesttype" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 018 +CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT +-- +STMT: CreateCastStmt +== 019 +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +== 020 +-- Should work now + +DROP FUNCTION int4_casttesttype(int4) CASCADE +-- +FUNCTION: name="int4_casttesttype" function="int4_casttesttype" schema="" ctx=DDL +STMT: DropStmt +== 021 +-- Try it with a function that requires an implicit cast + +CREATE FUNCTION bar_int4_text(int4) RETURNS text LANGUAGE SQL AS +$$ SELECT ('bar'::text || $1::text); $$ +-- +FUNCTION: name="bar_int4_text" function="bar_int4_text" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 022 +CREATE CAST (int4 AS casttesttype) WITH FUNCTION bar_int4_text(int4) AS IMPLICIT +-- +STMT: CreateCastStmt +== 023 +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +== 024 +-- Should work now + +-- check dependencies generated for that +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype +FROM pg_depend +WHERE classid = 'pg_cast'::regclass AND + objid = (SELECT oid FROM pg_cast + WHERE castsource = 'int4'::regtype + AND casttarget = 'casttesttype'::regtype) +ORDER BY refclassid +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/create_function_c.metadata.json b/parser/testdata/summary/postgres_regress/create_function_c.metadata.json new file mode 100644 index 0000000..e8e06a4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_function_c.metadata.json @@ -0,0 +1,9 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_function_c.test b/parser/testdata/summary/postgres_regress/create_function_c.test new file mode 100644 index 0000000..8826f11 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_function_c.test @@ -0,0 +1,53 @@ +== 001 +|-- +-- CREATE_FUNCTION_C +|-- +-- This script used to create C functions for other scripts to use. +-- But to get rid of the ordering dependencies that caused, such +-- functions are now made either in test_setup.sql or in the specific +-- test script that needs them. All that remains here is error cases. + +-- directory path and dlsuffix are passed to us in environment variables + + +|-- +-- Check LOAD command. (The alternative of implicitly loading the library +-- is checked in many other test scripts.) +|-- +LOAD :'regresslib' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 507 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- Things that shouldn't work: + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS 'nosuchfile' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +-- To produce stable regression test output, we have to filter the name +-- of the regresslib file out of the error message in this test. +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS :'regresslib', 'nosuchsymbol' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 196 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +SELECT regexp_replace(:'LAST_ERROR_MESSAGE', 'file ".*"', 'file "..."') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal + AS 'nosuch' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt diff --git a/parser/testdata/summary/postgres_regress/create_function_sql.metadata.json b/parser/testdata/summary/postgres_regress/create_function_sql.metadata.json new file mode 100644 index 0000000..643249b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_function_sql.metadata.json @@ -0,0 +1,159 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_function_sql.test b/parser/testdata/summary/postgres_regress/create_function_sql.test new file mode 100644 index 0000000..daeb174 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_function_sql.test @@ -0,0 +1,985 @@ +== 001 +|-- +-- CREATE_FUNCTION_SQL +|-- +-- Assorted tests using SQL-language functions +|-- + +-- All objects made in this test are in temp_func_test schema + +CREATE USER regress_unpriv_user +-- +STMT: CreateRoleStmt +== 002 +CREATE SCHEMA temp_func_test +-- +STMT: CreateSchemaStmt +== 003 +GRANT ALL ON SCHEMA temp_func_test TO public +-- +STMT: GrantStmt +== 004 +SET search_path TO temp_func_test, public +-- +STMT: VariableSetStmt +== 005 +|-- +-- Make sanity checks on the pg_proc entries created by CREATE FUNCTION +|-- + +|-- +-- ARGUMENT and RETURN TYPES +|-- +CREATE FUNCTION functest_A_1(text, date) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 = ''abcd'' AND $2 > ''2001-01-01''' +-- +FUNCTION: name="functest_a_1" function="functest_a_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +CREATE FUNCTION functest_A_2(text[]) RETURNS int LANGUAGE 'sql' + AS 'SELECT $1[1]::int' +-- +FUNCTION: name="functest_a_2" function="functest_a_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +CREATE FUNCTION functest_A_3() RETURNS bool LANGUAGE 'sql' + AS 'SELECT false' +-- +FUNCTION: name="functest_a_3" function="functest_a_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 008 +SELECT proname, prorettype::regtype, proargtypes::regtype[] FROM pg_proc + WHERE oid in ('functest_A_1'::regproc, + 'functest_A_2'::regproc, + 'functest_A_3'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 009 +SELECT functest_A_1('abcd', '2020-01-01') +-- +FUNCTION: name="functest_a_1" function="functest_a_1" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT functest_A_2(ARRAY['1', '2', '3']) +-- +FUNCTION: name="functest_a_2" function="functest_a_2" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT functest_A_3() +-- +FUNCTION: name="functest_a_3" function="functest_a_3" schema="" ctx=Call +STMT: SelectStmt +== 012 +|-- +-- IMMUTABLE | STABLE | VOLATILE +|-- +CREATE FUNCTION functest_B_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_b_1" function="functest_b_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 013 +CREATE FUNCTION functest_B_2(int) RETURNS bool LANGUAGE 'sql' + IMMUTABLE AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_b_2" function="functest_b_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 014 +CREATE FUNCTION functest_B_3(int) RETURNS bool LANGUAGE 'sql' + STABLE AS 'SELECT $1 = 0' +-- +FUNCTION: name="functest_b_3" function="functest_b_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 015 +CREATE FUNCTION functest_B_4(int) RETURNS bool LANGUAGE 'sql' + VOLATILE AS 'SELECT $1 < 0' +-- +FUNCTION: name="functest_b_4" function="functest_b_4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +SELECT proname, provolatile FROM pg_proc + WHERE oid in ('functest_B_1'::regproc, + 'functest_B_2'::regproc, + 'functest_B_3'::regproc, + 'functest_B_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 017 +ALTER FUNCTION functest_B_2(int) VOLATILE +-- +STMT: AlterFunctionStmt +== 018 +ALTER FUNCTION functest_B_3(int) COST 100 +-- +STMT: AlterFunctionStmt +== 019 +-- unrelated change, no effect +SELECT proname, provolatile FROM pg_proc + WHERE oid in ('functest_B_1'::regproc, + 'functest_B_2'::regproc, + 'functest_B_3'::regproc, + 'functest_B_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 020 +|-- +-- SECURITY DEFINER | INVOKER +|-- +CREATE FUNCTION functest_C_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_c_1" function="functest_c_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 021 +CREATE FUNCTION functest_C_2(int) RETURNS bool LANGUAGE 'sql' + SECURITY DEFINER AS 'SELECT $1 = 0' +-- +FUNCTION: name="functest_c_2" function="functest_c_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 022 +CREATE FUNCTION functest_C_3(int) RETURNS bool LANGUAGE 'sql' + SECURITY INVOKER AS 'SELECT $1 < 0' +-- +FUNCTION: name="functest_c_3" function="functest_c_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 023 +SELECT proname, prosecdef FROM pg_proc + WHERE oid in ('functest_C_1'::regproc, + 'functest_C_2'::regproc, + 'functest_C_3'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 024 +ALTER FUNCTION functest_C_1(int) IMMUTABLE +-- +STMT: AlterFunctionStmt +== 025 +-- unrelated change, no effect +ALTER FUNCTION functest_C_2(int) SECURITY INVOKER +-- +STMT: AlterFunctionStmt +== 026 +ALTER FUNCTION functest_C_3(int) SECURITY DEFINER +-- +STMT: AlterFunctionStmt +== 027 +SELECT proname, prosecdef FROM pg_proc + WHERE oid in ('functest_C_1'::regproc, + 'functest_C_2'::regproc, + 'functest_C_3'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 028 +|-- +-- LEAKPROOF +|-- +CREATE FUNCTION functest_E_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 100' +-- +FUNCTION: name="functest_e_1" function="functest_e_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +CREATE FUNCTION functest_E_2(int) RETURNS bool LANGUAGE 'sql' + LEAKPROOF AS 'SELECT $1 > 100' +-- +FUNCTION: name="functest_e_2" function="functest_e_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 030 +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 031 +ALTER FUNCTION functest_E_1(int) LEAKPROOF +-- +STMT: AlterFunctionStmt +== 032 +ALTER FUNCTION functest_E_2(int) STABLE +-- +STMT: AlterFunctionStmt +== 033 +-- unrelated change, no effect +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 034 +ALTER FUNCTION functest_E_2(int) NOT LEAKPROOF +-- +STMT: AlterFunctionStmt +== 035 +-- remove leakproof attribute +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 036 +-- it takes superuser privilege to turn on leakproof, but not to turn off +ALTER FUNCTION functest_E_1(int) OWNER TO regress_unpriv_user +-- +STMT: AlterOwnerStmt +== 037 +ALTER FUNCTION functest_E_2(int) OWNER TO regress_unpriv_user +-- +STMT: AlterOwnerStmt +== 038 +SET SESSION AUTHORIZATION regress_unpriv_user +-- +STMT: VariableSetStmt +== 039 +SET search_path TO temp_func_test, public +-- +STMT: VariableSetStmt +== 040 +ALTER FUNCTION functest_E_1(int) NOT LEAKPROOF +-- +STMT: AlterFunctionStmt +== 041 +ALTER FUNCTION functest_E_2(int) LEAKPROOF +-- +STMT: AlterFunctionStmt +== 042 +CREATE FUNCTION functest_E_3(int) RETURNS bool LANGUAGE 'sql' + LEAKPROOF AS 'SELECT $1 < 200' +-- +FUNCTION: name="functest_e_3" function="functest_e_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 043 +-- fail + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 044 +|-- +-- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT +|-- +CREATE FUNCTION functest_F_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 50' +-- +FUNCTION: name="functest_f_1" function="functest_f_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 045 +CREATE FUNCTION functest_F_2(int) RETURNS bool LANGUAGE 'sql' + CALLED ON NULL INPUT AS 'SELECT $1 = 50' +-- +FUNCTION: name="functest_f_2" function="functest_f_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 046 +CREATE FUNCTION functest_F_3(int) RETURNS bool LANGUAGE 'sql' + RETURNS NULL ON NULL INPUT AS 'SELECT $1 < 50' +-- +FUNCTION: name="functest_f_3" function="functest_f_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 047 +CREATE FUNCTION functest_F_4(int) RETURNS bool LANGUAGE 'sql' + STRICT AS 'SELECT $1 = 50' +-- +FUNCTION: name="functest_f_4" function="functest_f_4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 048 +SELECT proname, proisstrict FROM pg_proc + WHERE oid in ('functest_F_1'::regproc, + 'functest_F_2'::regproc, + 'functest_F_3'::regproc, + 'functest_F_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 049 +ALTER FUNCTION functest_F_1(int) IMMUTABLE +-- +STMT: AlterFunctionStmt +== 050 +-- unrelated change, no effect +ALTER FUNCTION functest_F_2(int) STRICT +-- +STMT: AlterFunctionStmt +== 051 +ALTER FUNCTION functest_F_3(int) CALLED ON NULL INPUT +-- +STMT: AlterFunctionStmt +== 052 +SELECT proname, proisstrict FROM pg_proc + WHERE oid in ('functest_F_1'::regproc, + 'functest_F_2'::regproc, + 'functest_F_3'::regproc, + 'functest_F_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 053 +-- pg_get_functiondef tests + +SELECT pg_get_functiondef('functest_A_1'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 054 +SELECT pg_get_functiondef('functest_B_3'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 055 +SELECT pg_get_functiondef('functest_C_3'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 056 +SELECT pg_get_functiondef('functest_F_2'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 057 +|-- +-- SQL-standard body +|-- +CREATE FUNCTION functest_S_1(a text, b date) RETURNS boolean + LANGUAGE SQL + RETURN a = 'abcd' AND b > '2001-01-01' +-- +FUNCTION: name="functest_s_1" function="functest_s_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 058 +CREATE FUNCTION functest_S_2(a text[]) RETURNS int + RETURN a[1]::int +-- +FUNCTION: name="functest_s_2" function="functest_s_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 059 +CREATE FUNCTION functest_S_3() RETURNS boolean + RETURN false +-- +FUNCTION: name="functest_s_3" function="functest_s_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 060 +CREATE FUNCTION functest_S_3a() RETURNS boolean + BEGIN ATOMIC +-- +ERROR: syntax error at end of input +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 061 +RETURN false +-- +ERROR: syntax error at or near "RETURN" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 062 +END +-- +STMT: TransactionStmt +== 063 +CREATE FUNCTION functest_S_10(a text, b date) RETURNS boolean + LANGUAGE SQL + BEGIN ATOMIC + SELECT a = 'abcd' AND b > '2001-01-01' +-- +ERROR: syntax error at end of input +CURSORPOS: 143 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 064 +END +-- +STMT: TransactionStmt +== 065 +CREATE FUNCTION functest_S_13() RETURNS boolean + BEGIN ATOMIC + SELECT 1 +-- +ERROR: syntax error at end of input +CURSORPOS: 82 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 066 +SELECT false +-- +STMT: SelectStmt +== 067 +END +-- +STMT: TransactionStmt +== 068 +-- check display of function arguments in sub-SELECT +CREATE TABLE functest1 (i int) +-- +TABLE: name="functest1" schema="" table="functest1" ctx=DDL +STMT: CreateStmt +== 069 +CREATE FUNCTION functest_S_16(a int, b int) RETURNS void + LANGUAGE SQL + BEGIN ATOMIC + INSERT INTO functest1 SELECT a + $2 +-- +ERROR: syntax error at end of input +CURSORPOS: 135 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 070 +END +-- +STMT: TransactionStmt +== 071 +-- error: duplicate function body +CREATE FUNCTION functest_S_xxx(x int) RETURNS int + LANGUAGE SQL + AS $$ SELECT x * 2 $$ + RETURN x * 3 +-- +FUNCTION: name="functest_s_xxx" function="functest_s_xxx" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 072 +-- polymorphic arguments not allowed in this form +CREATE FUNCTION functest_S_xx(x anyarray) RETURNS anyelement + LANGUAGE SQL + RETURN x[1] +-- +FUNCTION: name="functest_s_xx" function="functest_s_xx" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 073 +-- check reporting of parse-analysis errors +CREATE FUNCTION functest_S_xx(x date) RETURNS boolean + LANGUAGE SQL + RETURN x > 1 +-- +FUNCTION: name="functest_s_xx" function="functest_s_xx" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 074 +-- tricky parsing +CREATE FUNCTION functest_S_15(x int) RETURNS boolean +LANGUAGE SQL +BEGIN ATOMIC + select case when x % 2 = 0 then true else false end +-- +ERROR: syntax error at end of input +CURSORPOS: 153 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +END +-- +STMT: TransactionStmt +== 076 +SELECT functest_S_1('abcd', '2020-01-01') +-- +FUNCTION: name="functest_s_1" function="functest_s_1" schema="" ctx=Call +STMT: SelectStmt +== 077 +SELECT functest_S_2(ARRAY['1', '2', '3']) +-- +FUNCTION: name="functest_s_2" function="functest_s_2" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT functest_S_3() +-- +FUNCTION: name="functest_s_3" function="functest_s_3" schema="" ctx=Call +STMT: SelectStmt +== 079 +SELECT functest_S_10('abcd', '2020-01-01') +-- +FUNCTION: name="functest_s_10" function="functest_s_10" schema="" ctx=Call +STMT: SelectStmt +== 080 +SELECT functest_S_13() +-- +FUNCTION: name="functest_s_13" function="functest_s_13" schema="" ctx=Call +STMT: SelectStmt +== 081 +SELECT pg_get_functiondef('functest_S_1'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT pg_get_functiondef('functest_S_2'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT pg_get_functiondef('functest_S_3'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 084 +SELECT pg_get_functiondef('functest_S_3a'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT pg_get_functiondef('functest_S_10'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT pg_get_functiondef('functest_S_13'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 087 +SELECT pg_get_functiondef('functest_S_15'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 088 +SELECT pg_get_functiondef('functest_S_16'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 089 +DROP TABLE functest1 CASCADE +-- +TABLE: name="functest1" schema="" table="functest1" ctx=DDL +STMT: DropStmt +== 090 +-- test with views +CREATE TABLE functest3 (a int) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: CreateStmt +== 091 +INSERT INTO functest3 VALUES (1), (2) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +CREATE VIEW functestv3 AS SELECT * FROM functest3 +-- +TABLE: name="functestv3" schema="" table="functestv3" ctx=DDL +TABLE: name="functest3" schema="" table="functest3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 093 +CREATE FUNCTION functest_S_14() RETURNS bigint + RETURN (SELECT count(*) FROM functestv3) +-- +FUNCTION: name="functest_s_14" function="functest_s_14" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 094 +SELECT functest_S_14() +-- +FUNCTION: name="functest_s_14" function="functest_s_14" schema="" ctx=Call +STMT: SelectStmt +== 095 +DROP TABLE functest3 CASCADE +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: DropStmt +== 096 +-- information_schema tests + +CREATE FUNCTION functest_IS_1(a int, b int default 1, c text default 'foo') + RETURNS int + LANGUAGE SQL + AS 'SELECT $1 + $2' +-- +FUNCTION: name="functest_is_1" function="functest_is_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 097 +CREATE FUNCTION functest_IS_2(out a int, b int default 1) + RETURNS int + LANGUAGE SQL + AS 'SELECT $1' +-- +FUNCTION: name="functest_is_2" function="functest_is_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 098 +CREATE FUNCTION functest_IS_3(a int default 1, out b int) + RETURNS int + LANGUAGE SQL + AS 'SELECT $1' +-- +FUNCTION: name="functest_is_3" function="functest_is_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 099 +SELECT routine_name, ordinal_position, parameter_name, parameter_default + FROM information_schema.parameters JOIN information_schema.routines USING (specific_schema, specific_name) + WHERE routine_schema = 'temp_func_test' AND routine_name ~ '^functest_is_' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.parameters" schema="information_schema" table="parameters" ctx=Select +TABLE: name="information_schema.routines" schema="information_schema" table="routines" ctx=Select +FILTER: schema="" table="" column="routine_schema" +FILTER: schema="" table="" column="routine_name" +STMT: SelectStmt +== 100 +DROP FUNCTION functest_IS_1(int, int, text), functest_IS_2(int), functest_IS_3(int) +-- +FUNCTION: name="functest_is_1" function="functest_is_1" schema="" ctx=DDL +STMT: DropStmt +== 101 +-- routine usage views + +CREATE FUNCTION functest_IS_4a() RETURNS int LANGUAGE SQL AS 'SELECT 1' +-- +FUNCTION: name="functest_is_4a" function="functest_is_4a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 102 +CREATE FUNCTION functest_IS_4b(x int DEFAULT functest_IS_4a()) RETURNS int LANGUAGE SQL AS 'SELECT x' +-- +FUNCTION: name="functest_is_4b" function="functest_is_4b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 103 +CREATE SEQUENCE functest1 +-- +STMT: CreateSeqStmt +== 104 +CREATE FUNCTION functest_IS_5(x int DEFAULT nextval('functest1')) + RETURNS int + LANGUAGE SQL + AS 'SELECT x' +-- +FUNCTION: name="functest_is_5" function="functest_is_5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 105 +CREATE FUNCTION functest_IS_6() + RETURNS int + LANGUAGE SQL + RETURN nextval('functest1') +-- +FUNCTION: name="functest_is_6" function="functest_is_6" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 106 +CREATE TABLE functest2 (a int, b int) +-- +TABLE: name="functest2" schema="" table="functest2" ctx=DDL +STMT: CreateStmt +== 107 +CREATE FUNCTION functest_IS_7() + RETURNS int + LANGUAGE SQL + RETURN (SELECT count(a) FROM functest2) +-- +FUNCTION: name="functest_is_7" function="functest_is_7" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 108 +SELECT r0.routine_name, r1.routine_name + FROM information_schema.routine_routine_usage rru + JOIN information_schema.routines r0 ON r0.specific_name = rru.specific_name + JOIN information_schema.routines r1 ON r1.specific_name = rru.routine_name + WHERE r0.routine_schema = 'temp_func_test' AND + r1.routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_routine_usage" schema="information_schema" table="routine_routine_usage" ctx=Select +TABLE: name="information_schema.routines" schema="information_schema" table="routines" ctx=Select +TABLE: name="information_schema.routines" schema="information_schema" table="routines" ctx=Select +ALIAS: "r0"="information_schema.routines" +ALIAS: "r1"="information_schema.routines" +ALIAS: "rru"="information_schema.routine_routine_usage" +FILTER: schema="" table="r0" column="routine_schema" +FILTER: schema="" table="r1" column="routine_schema" +STMT: SelectStmt +== 109 +SELECT routine_name, sequence_name FROM information_schema.routine_sequence_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_sequence_usage" schema="information_schema" table="routine_sequence_usage" ctx=Select +FILTER: schema="" table="" column="routine_schema" +STMT: SelectStmt +== 110 +SELECT routine_name, table_name, column_name FROM information_schema.routine_column_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_column_usage" schema="information_schema" table="routine_column_usage" ctx=Select +FILTER: schema="" table="" column="routine_schema" +STMT: SelectStmt +== 111 +SELECT routine_name, table_name FROM information_schema.routine_table_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_table_usage" schema="information_schema" table="routine_table_usage" ctx=Select +FILTER: schema="" table="" column="routine_schema" +STMT: SelectStmt +== 112 +DROP FUNCTION functest_IS_4a CASCADE +-- +FUNCTION: name="functest_is_4a" function="functest_is_4a" schema="" ctx=DDL +STMT: DropStmt +== 113 +DROP SEQUENCE functest1 CASCADE +-- +STMT: DropStmt +== 114 +DROP TABLE functest2 CASCADE +-- +TABLE: name="functest2" schema="" table="functest2" ctx=DDL +STMT: DropStmt +== 115 +-- overload +CREATE FUNCTION functest_B_2(bigint) RETURNS bool LANGUAGE 'sql' + IMMUTABLE AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_b_2" function="functest_b_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 116 +DROP FUNCTION functest_b_1 +-- +FUNCTION: name="functest_b_1" function="functest_b_1" schema="" ctx=DDL +STMT: DropStmt +== 117 +DROP FUNCTION functest_b_1 +-- +FUNCTION: name="functest_b_1" function="functest_b_1" schema="" ctx=DDL +STMT: DropStmt +== 118 +-- error, not found +DROP FUNCTION functest_b_2 +-- +FUNCTION: name="functest_b_2" function="functest_b_2" schema="" ctx=DDL +STMT: DropStmt +== 119 +-- error, ambiguous + + +-- CREATE OR REPLACE tests + +CREATE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL AS 'SELECT $1' +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 120 +CREATE OR REPLACE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL WINDOW AS 'SELECT $1' +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 121 +CREATE OR REPLACE PROCEDURE functest1(a int) LANGUAGE SQL AS 'SELECT $1' +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 122 +DROP FUNCTION functest1(a int) +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: DropStmt +== 123 +-- inlining of set-returning functions + +CREATE TABLE functest3 (a int) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: CreateStmt +== 124 +INSERT INTO functest3 VALUES (1), (2), (3) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +CREATE FUNCTION functest_sri1() RETURNS SETOF int +LANGUAGE SQL +STABLE +AS ' + SELECT * FROM functest3; +' +-- +FUNCTION: name="functest_sri1" function="functest_sri1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 126 +SELECT * FROM functest_sri1() +-- +FUNCTION: name="functest_sri1" function="functest_sri1" schema="" ctx=Call +STMT: SelectStmt +== 127 +EXPLAIN (verbose, costs off) SELECT * FROM functest_sri1() +-- +FUNCTION: name="functest_sri1" function="functest_sri1" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 128 +CREATE FUNCTION functest_sri2() RETURNS SETOF int +LANGUAGE SQL +STABLE +BEGIN ATOMIC + SELECT * FROM functest3 +-- +ERROR: syntax error at end of input +CURSORPOS: 111 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 129 +END +-- +STMT: TransactionStmt +== 130 +SELECT * FROM functest_sri2() +-- +FUNCTION: name="functest_sri2" function="functest_sri2" schema="" ctx=Call +STMT: SelectStmt +== 131 +EXPLAIN (verbose, costs off) SELECT * FROM functest_sri2() +-- +FUNCTION: name="functest_sri2" function="functest_sri2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 132 +DROP TABLE functest3 CASCADE +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: DropStmt +== 133 +-- Check behavior of VOID-returning SQL functions + +CREATE FUNCTION voidtest1(a int) RETURNS VOID LANGUAGE SQL AS +$$ SELECT a + 1 $$ +-- +FUNCTION: name="voidtest1" function="voidtest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 134 +SELECT voidtest1(42) +-- +FUNCTION: name="voidtest1" function="voidtest1" schema="" ctx=Call +STMT: SelectStmt +== 135 +CREATE FUNCTION voidtest2(a int, b int) RETURNS VOID LANGUAGE SQL AS +$$ SELECT voidtest1(a + b) $$ +-- +FUNCTION: name="voidtest2" function="voidtest2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 136 +SELECT voidtest2(11,22) +-- +FUNCTION: name="voidtest2" function="voidtest2" schema="" ctx=Call +STMT: SelectStmt +== 137 +-- currently, we can inline voidtest2 but not voidtest1 +EXPLAIN (verbose, costs off) SELECT voidtest2(11,22) +-- +FUNCTION: name="voidtest2" function="voidtest2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 138 +CREATE TEMP TABLE sometable(f1 int) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DDL +STMT: CreateStmt +== 139 +CREATE FUNCTION voidtest3(a int) RETURNS VOID LANGUAGE SQL AS +$$ INSERT INTO sometable VALUES(a + 1) $$ +-- +FUNCTION: name="voidtest3" function="voidtest3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 140 +SELECT voidtest3(17) +-- +FUNCTION: name="voidtest3" function="voidtest3" schema="" ctx=Call +STMT: SelectStmt +== 141 +CREATE FUNCTION voidtest4(a int) RETURNS VOID LANGUAGE SQL AS +$$ INSERT INTO sometable VALUES(a - 1) RETURNING f1 $$ +-- +FUNCTION: name="voidtest4" function="voidtest4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 142 +SELECT voidtest4(39) +-- +FUNCTION: name="voidtest4" function="voidtest4" schema="" ctx=Call +STMT: SelectStmt +== 143 +TABLE sometable +-- +TABLE: name="sometable" schema="" table="sometable" ctx=Select +STMT: SelectStmt +== 144 +CREATE FUNCTION voidtest5(a int) RETURNS SETOF VOID LANGUAGE SQL AS +$$ SELECT generate_series(1, a) $$ STABLE +-- +FUNCTION: name="voidtest5" function="voidtest5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 145 +SELECT * FROM voidtest5(3) +-- +FUNCTION: name="voidtest5" function="voidtest5" schema="" ctx=Call +STMT: SelectStmt +== 146 +-- Regression tests for bugs: + +-- Check that arguments that are R/W expanded datums aren't corrupted by +-- multiple uses. This test knows that array_append() returns a R/W datum +-- and will modify a R/W array input in-place. We use SETOF to prevent +-- inlining of the SQL function. +CREATE FUNCTION double_append(anyarray, anyelement) RETURNS SETOF anyarray +LANGUAGE SQL IMMUTABLE AS +$$ SELECT array_append($1, $2) || array_append($1, $2) $$ +-- +FUNCTION: name="double_append" function="double_append" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 147 +SELECT double_append(array_append(ARRAY[q1], q2), q3) + FROM (VALUES(1,2,3), (4,5,6)) v(q1,q2,q3) +-- +FUNCTION: name="double_append" function="double_append" schema="" ctx=Call +FUNCTION: name="array_append" function="array_append" schema="" ctx=Call +STMT: SelectStmt +== 148 +-- Things that shouldn't work: + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT ''not an integer'';' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 149 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'not even SQL' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 150 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT 1, 2, 3;' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 151 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT $2;' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 152 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'a', 'b' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 153 +-- Cleanup +DROP SCHEMA temp_func_test CASCADE +-- +STMT: DropStmt +== 154 +DROP USER regress_unpriv_user +-- +STMT: DropRoleStmt +== 155 +RESET search_path +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/create_index.metadata.json b/parser/testdata/summary/postgres_regress/create_index.metadata.json new file mode 100644 index 0000000..528c575 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_index.metadata.json @@ -0,0 +1,615 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_index.test b/parser/testdata/summary/postgres_regress/create_index.test new file mode 100644 index 0000000..995fef5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_index.test @@ -0,0 +1,3911 @@ +== 001 +|-- +-- CREATE_INDEX +-- Create ancillary data structures (i.e. indices) +|-- + +-- directory paths are passed to us in environment variables + +|-- +-- BTREE +|-- +CREATE INDEX onek_unique1 ON onek USING btree(unique1 int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +== 002 +CREATE INDEX IF NOT EXISTS onek_unique1 ON onek USING btree(unique1 int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +== 003 +CREATE INDEX IF NOT EXISTS ON onek USING btree(unique1 int4_ops) +-- +ERROR: syntax error at or near "ON" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +CREATE INDEX onek_unique2 ON onek USING btree(unique2 int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +== 005 +CREATE INDEX onek_hundred ON onek USING btree(hundred int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +== 006 +CREATE INDEX onek_stringu1 ON onek USING btree(stringu1 name_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +== 007 +CREATE INDEX tenk1_unique1 ON tenk1 USING btree(unique1 int4_ops) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +== 008 +CREATE INDEX tenk1_unique2 ON tenk1 USING btree(unique2 int4_ops) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +== 009 +CREATE INDEX tenk1_hundred ON tenk1 USING btree(hundred int4_ops) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +== 010 +CREATE INDEX tenk1_thous_tenthous ON tenk1 (thousand, tenthous) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +== 011 +CREATE INDEX tenk2_unique1 ON tenk2 USING btree(unique1 int4_ops) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: IndexStmt +== 012 +CREATE INDEX tenk2_unique2 ON tenk2 USING btree(unique2 int4_ops) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: IndexStmt +== 013 +CREATE INDEX tenk2_hundred ON tenk2 USING btree(hundred int4_ops) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: IndexStmt +== 014 +CREATE INDEX rix ON road USING btree (name text_ops) +-- +TABLE: name="road" schema="" table="road" ctx=DDL +STMT: IndexStmt +== 015 +CREATE INDEX iix ON ihighway USING btree (name text_ops) +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DDL +STMT: IndexStmt +== 016 +CREATE INDEX six ON shighway USING btree (name text_ops) +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DDL +STMT: IndexStmt +== 017 +-- test comments +COMMENT ON INDEX six_wrong IS 'bad index' +-- +STMT: CommentStmt +== 018 +COMMENT ON INDEX six IS 'good index' +-- +STMT: CommentStmt +== 019 +COMMENT ON INDEX six IS NULL +-- +STMT: CommentStmt +== 020 +|-- +-- BTREE partial indices +|-- +CREATE INDEX onek2_u1_prtl ON onek2 USING btree(unique1 int4_ops) + where unique1 < 20 or unique1 > 980 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: IndexStmt +== 021 +CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops) + where stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: IndexStmt +== 022 +CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops) + where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: IndexStmt +== 023 +|-- +-- GiST (rtree-equivalent opclasses only) +|-- + +CREATE TABLE slow_emp4000 ( + home_base box +) +-- +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=DDL +STMT: CreateStmt +== 024 +CREATE TABLE fast_emp4000 ( + home_base box +) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: CreateStmt +== 025 +COPY slow_emp4000 FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +INSERT INTO fast_emp4000 SELECT * FROM slow_emp4000 +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DML +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 027 +ANALYZE slow_emp4000 +-- +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=DDL +STMT: VacuumStmt +== 028 +ANALYZE fast_emp4000 +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: VacuumStmt +== 029 +CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: IndexStmt +== 030 +-- we want to work with a point_tbl that includes a null +CREATE TEMP TABLE point_tbl AS SELECT * FROM public.point_tbl +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +TABLE: name="public.point_tbl" schema="public" table="point_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 031 +INSERT INTO POINT_TBL(f1) VALUES (NULL) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +CREATE INDEX gpointind ON point_tbl USING gist (f1) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +STMT: IndexStmt +== 033 +CREATE TEMP TABLE gpolygon_tbl AS + SELECT polygon(home_base) AS f1 FROM slow_emp4000 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DDL +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 034 +INSERT INTO gpolygon_tbl VALUES ( '(1000,0,0,1000)' ) +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO gpolygon_tbl VALUES ( '(0,1000,1000,1000)' ) +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +CREATE TEMP TABLE gcircle_tbl AS + SELECT circle(home_base) AS f1 FROM slow_emp4000 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=DDL +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 037 +CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1) +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DDL +STMT: IndexStmt +== 038 +CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1) +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=DDL +STMT: IndexStmt +== 039 +|-- +-- Test GiST indexes +|-- + +-- get non-indexed results for comparison purposes + +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +== 040 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 041 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 042 +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 043 +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 044 +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 045 +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 046 +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 047 +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 048 +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 049 +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 050 +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 051 +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 052 +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 053 +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 054 +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 055 +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 056 +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 057 +SELECT * FROM point_tbl WHERE f1 IS NULL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 058 +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 059 +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 060 +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +STMT: SelectStmt +== 061 +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="circle_center" function="circle_center" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: SelectStmt +== 062 +-- Now check the results from plain indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 063 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 064 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 065 +EXPLAIN (COSTS OFF) +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +== 066 +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 067 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +== 068 +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 069 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +== 070 +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +== 071 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 072 +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 073 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 074 +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 075 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 076 +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 077 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 078 +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 079 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 080 +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 081 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 082 +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 083 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 084 +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 085 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 086 +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 087 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 088 +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 089 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 090 +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 091 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 092 +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 093 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 094 +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 095 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 IS NULL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 096 +SELECT * FROM point_tbl WHERE f1 IS NULL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 097 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 098 +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 099 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 100 +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 101 +EXPLAIN (COSTS OFF) +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 102 +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +STMT: SelectStmt +== 103 +EXPLAIN (COSTS OFF) +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="circle_center" function="circle_center" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 104 +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="circle_center" function="circle_center" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: SelectStmt +== 105 +EXPLAIN (COSTS OFF) +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 106 +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 107 +-- Now check the results from bitmap indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 108 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 109 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +== 110 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 111 +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 112 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 113 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 114 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 115 +|-- +-- GIN over int[] and text[] +|-- +-- Note: GIN currently supports only bitmap scans, not plain indexscans +|-- + +CREATE TABLE array_index_op_test ( + seqno int4, + i int4[], + t text[] +) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: CreateStmt +== 116 +COPY array_index_op_test FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 31 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 117 +ANALYZE array_index_op_test +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: VacuumStmt +== 118 +SELECT * FROM array_index_op_test WHERE i = '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 119 +SELECT * FROM array_index_op_test WHERE i @> '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 120 +SELECT * FROM array_index_op_test WHERE i && '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 121 +SELECT * FROM array_index_op_test WHERE i <@ '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 122 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 123 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 124 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +== 125 +CREATE INDEX intarrayidx ON array_index_op_test USING gin (i) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +== 126 +explain (costs off) +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 127 +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 128 +SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 129 +SELECT * FROM array_index_op_test WHERE i @> '{17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 130 +SELECT * FROM array_index_op_test WHERE i && '{17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 131 +SELECT * FROM array_index_op_test WHERE i @> '{32,17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 132 +SELECT * FROM array_index_op_test WHERE i && '{32,17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 133 +SELECT * FROM array_index_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 134 +SELECT * FROM array_index_op_test WHERE i = '{47,77}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 135 +SELECT * FROM array_index_op_test WHERE i = '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 136 +SELECT * FROM array_index_op_test WHERE i @> '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 137 +SELECT * FROM array_index_op_test WHERE i && '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 138 +SELECT * FROM array_index_op_test WHERE i <@ '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 139 +CREATE INDEX textarrayidx ON array_index_op_test USING gin (t) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +== 140 +explain (costs off) +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 141 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 142 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 143 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 144 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 145 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 146 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 147 +SELECT * FROM array_index_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 148 +SELECT * FROM array_index_op_test WHERE t = '{AAAAAAAAAA646,A87088}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 149 +SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 150 +SELECT * FROM array_index_op_test WHERE t @> '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 151 +SELECT * FROM array_index_op_test WHERE t && '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 152 +SELECT * FROM array_index_op_test WHERE t <@ '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 153 +-- And try it with a multicolumn GIN index + +DROP INDEX intarrayidx, textarrayidx +-- +STMT: DropStmt +== 154 +CREATE INDEX botharrayidx ON array_index_op_test USING gin (i, t) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +== 155 +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 156 +SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 157 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 158 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 159 +SELECT * FROM array_index_op_test WHERE i @> '{32}' AND t && '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 160 +SELECT * FROM array_index_op_test WHERE i && '{32}' AND t @> '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 161 +SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 162 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 163 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 164 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 165 +|-- +-- 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[]) +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DDL +STMT: CreateStmt +== 166 +INSERT INTO array_gin_test SELECT ARRAY[1, g%5, g] FROM generate_series(1, 10000) g +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 167 +CREATE INDEX array_gin_test_idx ON array_gin_test USING gin (a) +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DDL +STMT: IndexStmt +== 168 +SELECT COUNT(*) FROM array_gin_test WHERE a @> '{2}' +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 169 +DROP TABLE array_gin_test +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DDL +STMT: DropStmt +== 170 +|-- +-- 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) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +== 171 +|-- +-- HASH +|-- +CREATE UNLOGGED TABLE unlogged_hash_table (id int4) +-- +TABLE: name="unlogged_hash_table" schema="" table="unlogged_hash_table" ctx=DDL +STMT: CreateStmt +== 172 +CREATE INDEX unlogged_hash_index ON unlogged_hash_table USING hash (id int4_ops) +-- +TABLE: name="unlogged_hash_table" schema="" table="unlogged_hash_table" ctx=DDL +STMT: IndexStmt +== 173 +DROP TABLE unlogged_hash_table +-- +TABLE: name="unlogged_hash_table" schema="" table="unlogged_hash_table" ctx=DDL +STMT: DropStmt +== 174 +-- 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' +-- +STMT: VariableSetStmt +== 175 +CREATE INDEX hash_tuplesort_idx ON tenk1 USING hash (stringu1 name_ops) WITH (fillfactor = 10) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +== 176 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 177 +SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 178 +DROP INDEX hash_tuplesort_idx +-- +STMT: DropStmt +== 179 +RESET maintenance_work_mem +-- +STMT: VariableSetStmt +== 180 +|-- +-- Test unique null behavior +|-- +CREATE TABLE unique_tbl (i int, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +== 181 +CREATE UNIQUE INDEX unique_idx1 ON unique_tbl (i) NULLS DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +== 182 +CREATE UNIQUE INDEX unique_idx2 ON unique_tbl (i) NULLS NOT DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +== 183 +INSERT INTO unique_tbl VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 184 +INSERT INTO unique_tbl VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +INSERT INTO unique_tbl VALUES (3, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +INSERT INTO unique_tbl VALUES (4, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +INSERT INTO unique_tbl VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +INSERT INTO unique_tbl (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +INSERT INTO unique_tbl (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +-- error from unique_idx2 + +DROP INDEX unique_idx1, unique_idx2 +-- +STMT: DropStmt +== 191 +INSERT INTO unique_tbl (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 192 +-- build indexes on filled table +CREATE UNIQUE INDEX unique_idx3 ON unique_tbl (i) NULLS DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +== 193 +-- ok +CREATE UNIQUE INDEX unique_idx4 ON unique_tbl (i) NULLS NOT DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +== 194 +-- error + +DELETE FROM unique_tbl WHERE t = 'seven' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +== 195 +CREATE UNIQUE INDEX unique_idx4 ON unique_tbl (i) NULLS NOT DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +== 196 +-- ok now + +SELECT pg_get_indexdef('unique_idx3'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 197 +SELECT pg_get_indexdef('unique_idx4'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 198 +DROP TABLE unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +== 199 +|-- +-- Test functional index +|-- +CREATE TABLE func_index_heap (f1 text, f2 text) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: CreateStmt +== 200 +CREATE UNIQUE INDEX func_index_index on func_index_heap (textcat(f1,f2)) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +FUNCTION: name="textcat" function="textcat" schema="" ctx=Call +STMT: IndexStmt +== 201 +INSERT INTO func_index_heap VALUES('ABC','DEF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +INSERT INTO func_index_heap VALUES('AB','CDEFG') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +INSERT INTO func_index_heap VALUES('QWE','RTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 204 +-- this should fail because of unique index: +INSERT INTO func_index_heap VALUES('ABCD', 'EF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 205 +-- but this shouldn't: +INSERT INTO func_index_heap VALUES('QWERTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 206 +-- while we're here, see that the metadata looks sane + + +|-- +-- Same test, expressional index +|-- +DROP TABLE func_index_heap +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: DropStmt +== 207 +CREATE TABLE func_index_heap (f1 text, f2 text) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: CreateStmt +== 208 +CREATE UNIQUE INDEX func_index_index on func_index_heap ((f1 || f2) text_ops) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: IndexStmt +== 209 +INSERT INTO func_index_heap VALUES('ABC','DEF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 210 +INSERT INTO func_index_heap VALUES('AB','CDEFG') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 211 +INSERT INTO func_index_heap VALUES('QWE','RTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 212 +-- this should fail because of unique index: +INSERT INTO func_index_heap VALUES('ABCD', 'EF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 213 +-- but this shouldn't: +INSERT INTO func_index_heap VALUES('QWERTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 214 +-- while we're here, see that the metadata looks sane + +-- this should fail because of unsafe column type (anonymous record) +create index on func_index_heap ((f1 || f2), (row(f1, f2))) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: IndexStmt +== 215 +|-- +-- Test unique index with included columns +|-- +CREATE TABLE covering_index_heap (f1 int, f2 int, f3 text) +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: CreateStmt +== 216 +CREATE UNIQUE INDEX covering_index_index on covering_index_heap (f1,f2) INCLUDE(f3) +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: IndexStmt +== 217 +INSERT INTO covering_index_heap VALUES(1,1,'AAA') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 218 +INSERT INTO covering_index_heap VALUES(1,2,'AAA') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 219 +-- this should fail because of unique index on f1,f2: +INSERT INTO covering_index_heap VALUES(1,2,'BBB') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 220 +-- and this shouldn't: +INSERT INTO covering_index_heap VALUES(1,4,'AAA') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 221 +-- Try to build index on table that already contains data +CREATE UNIQUE INDEX covering_pkey on covering_index_heap (f1,f2) INCLUDE(f3) +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: IndexStmt +== 222 +-- Try to use existing covering index as primary key +ALTER TABLE covering_index_heap ADD CONSTRAINT covering_pkey PRIMARY KEY USING INDEX +covering_pkey +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: AlterTableStmt +== 223 +DROP TABLE covering_index_heap +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: DropStmt +== 224 +|-- +-- 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) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: CreateStmt +== 225 +-- empty table +CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap(f2,f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 226 +CREATE INDEX CONCURRENTLY IF NOT EXISTS concur_index1 ON concur_heap(f2,f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 227 +INSERT INTO concur_heap VALUES ('a','b') +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 228 +INSERT INTO concur_heap VALUES ('b','b') +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 229 +-- unique index +CREATE UNIQUE INDEX CONCURRENTLY concur_index2 ON concur_heap(f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 230 +CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS concur_index2 ON concur_heap(f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 231 +-- check if constraint is set up properly to be enforced +INSERT INTO concur_heap VALUES ('b','x') +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 232 +-- check if constraint is enforced properly at build time +CREATE UNIQUE INDEX CONCURRENTLY concur_index3 ON concur_heap(f2) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 233 +-- test that expression indexes and partial indexes work concurrently +CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a' +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 234 +CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x' +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 235 +-- here we also check that you can default the index name +CREATE INDEX CONCURRENTLY on concur_heap((f2||f1)) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 236 +-- You can't do a concurrent index build in a transaction +BEGIN +-- +STMT: TransactionStmt +== 237 +CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap(f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 238 +COMMIT +-- +STMT: TransactionStmt +== 239 +-- 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; $$ +-- +FUNCTION: name="predicate_stable" function="predicate_stable" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 240 +CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap (f1) + WHERE predicate_stable() +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +FUNCTION: name="predicate_stable" function="predicate_stable" schema="" ctx=Call +STMT: IndexStmt +== 241 +DROP INDEX concur_index8 +-- +STMT: DropStmt +== 242 +DROP FUNCTION predicate_stable() +-- +FUNCTION: name="predicate_stable" function="predicate_stable" schema="" ctx=DDL +STMT: DropStmt +== 243 +-- But you can do a regular index build in a transaction +BEGIN +-- +STMT: TransactionStmt +== 244 +CREATE INDEX std_index on concur_heap(f2) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +== 245 +COMMIT +-- +STMT: TransactionStmt +== 246 +-- Failed builds are left invalid by VACUUM FULL, fixed by REINDEX +VACUUM FULL concur_heap +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: VacuumStmt +== 247 +REINDEX TABLE concur_heap +-- +STMT: ReindexStmt +== 248 +DELETE FROM concur_heap WHERE f1 = 'b' +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: DeleteStmt +== 249 +VACUUM FULL concur_heap +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: VacuumStmt +== 250 +REINDEX TABLE concur_heap +-- +STMT: ReindexStmt +== 251 +-- 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 +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: CreateStmt +== 252 +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1) +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: IndexStmt +== 254 +DROP INDEX CONCURRENTLY concur_temp_ind +-- +STMT: DropStmt +== 255 +DROP TABLE concur_temp +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: DropStmt +== 256 +-- ON COMMIT DROP +BEGIN +-- +STMT: TransactionStmt +== 257 +CREATE TEMP TABLE concur_temp (f1 int, f2 text) + ON COMMIT DROP +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: CreateStmt +== 258 +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 259 +-- Fails when running in a transaction. +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1) +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: IndexStmt +== 260 +COMMIT +-- +STMT: TransactionStmt +== 261 +-- ON COMMIT DELETE ROWS +CREATE TEMP TABLE concur_temp (f1 int, f2 text) + ON COMMIT DELETE ROWS +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: CreateStmt +== 262 +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 263 +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1) +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: IndexStmt +== 264 +DROP INDEX CONCURRENTLY concur_temp_ind +-- +STMT: DropStmt +== 265 +DROP TABLE concur_temp +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: DropStmt +== 266 +|-- +-- Try some concurrent index drops +|-- +DROP INDEX CONCURRENTLY "concur_index2" +-- +STMT: DropStmt +== 267 +-- works +DROP INDEX CONCURRENTLY IF EXISTS "concur_index2" +-- +STMT: DropStmt +== 268 +-- notice + +-- failures +DROP INDEX CONCURRENTLY "concur_index2", "concur_index3" +-- +STMT: DropStmt +== 269 +BEGIN +-- +STMT: TransactionStmt +== 270 +DROP INDEX CONCURRENTLY "concur_index5" +-- +STMT: DropStmt +== 271 +ROLLBACK +-- +STMT: TransactionStmt +== 272 +-- successes +DROP INDEX CONCURRENTLY IF EXISTS "concur_index3" +-- +STMT: DropStmt +== 273 +DROP INDEX CONCURRENTLY "concur_index4" +-- +STMT: DropStmt +== 274 +DROP INDEX CONCURRENTLY "concur_index5" +-- +STMT: DropStmt +== 275 +DROP INDEX CONCURRENTLY "concur_index1" +-- +STMT: DropStmt +== 276 +DROP INDEX CONCURRENTLY "concur_heap_expr_idx" +-- +STMT: DropStmt +== 277 +DROP TABLE concur_heap +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: DropStmt +== 278 +|-- +-- Test ADD CONSTRAINT USING INDEX +|-- + +CREATE TABLE cwi_test( a int , b varchar(10), c char) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: CreateStmt +== 279 +-- add some data so that all tests have something to work with. + +INSERT INTO cwi_test VALUES(1, 2), (3, 4), (5, 6) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +CREATE UNIQUE INDEX cwi_uniq_idx ON cwi_test(a , b) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +== 281 +ALTER TABLE cwi_test ADD primary key USING INDEX cwi_uniq_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +== 282 +CREATE UNIQUE INDEX cwi_uniq2_idx ON cwi_test(b , a) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +== 283 +ALTER TABLE cwi_test DROP CONSTRAINT cwi_uniq_idx, + ADD CONSTRAINT cwi_replaced_pkey PRIMARY KEY + USING INDEX cwi_uniq2_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +== 284 +DROP INDEX cwi_replaced_pkey +-- +STMT: DropStmt +== 285 +-- Should fail; a constraint depends on it + +-- Check that non-default index options are rejected +CREATE UNIQUE INDEX cwi_uniq3_idx ON cwi_test(a desc) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +== 286 +ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq3_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +== 287 +-- fail +CREATE UNIQUE INDEX cwi_uniq4_idx ON cwi_test(b collate "POSIX") +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +== 288 +ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq4_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +== 289 +-- fail + +DROP TABLE cwi_test +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: DropStmt +== 290 +-- ADD CONSTRAINT USING INDEX is forbidden on partitioned tables +CREATE TABLE cwi_test(a int) PARTITION BY hash (a) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: CreateStmt +== 291 +create unique index on cwi_test (a) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +== 292 +alter table cwi_test add primary key using index cwi_test_a_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +== 293 +DROP TABLE cwi_test +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: DropStmt +== 294 +-- PRIMARY KEY constraint cannot be backed by a NULLS NOT DISTINCT index +CREATE TABLE cwi_test(a int, b int) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: CreateStmt +== 295 +CREATE UNIQUE INDEX cwi_a_nnd ON cwi_test (a) NULLS NOT DISTINCT +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +== 296 +ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_a_nnd +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +== 297 +DROP TABLE cwi_test +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: DropStmt +== 298 +|-- +-- Check handling of indexes on system columns +|-- +CREATE TABLE syscol_table (a INT) +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: CreateStmt +== 299 +-- System columns cannot be indexed +CREATE INDEX ON syscol_table (ctid) +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: IndexStmt +== 300 +-- nor used in expressions +CREATE INDEX ON syscol_table ((ctid >= '(1000,0)')) +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: IndexStmt +== 301 +-- nor used in predicates +CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)' +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: IndexStmt +== 302 +DROP TABLE syscol_table +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: DropStmt +== 303 +|-- +-- Tests for IS NULL/IS NOT NULL with b-tree indexes +|-- + +CREATE TABLE onek_with_null AS SELECT unique1, unique2 FROM onek +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 304 +INSERT INTO onek_with_null (unique1,unique2) VALUES (NULL, -1), (NULL, NULL) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 305 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +== 306 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 307 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 308 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +== 309 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 310 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 311 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 312 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 313 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 314 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 315 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +== 316 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +== 317 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 318 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 319 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 320 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 321 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 322 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 323 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IN (-1, 0, 1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 324 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +== 325 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc nulls last,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +== 326 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 327 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 328 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 329 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 330 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 331 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 332 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +== 333 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 nulls first,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +== 334 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 335 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 336 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 337 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 338 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 339 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 340 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +== 341 +-- Check initial-positioning logic too + +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +== 342 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 343 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 344 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 345 +SELECT unique1, unique2 FROM onek_with_null + ORDER BY unique2 LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +STMT: SelectStmt +== 346 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 + ORDER BY unique2 LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 347 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= 0 + ORDER BY unique2 LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 348 +SELECT unique1, unique2 FROM onek_with_null + ORDER BY unique2 DESC LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +STMT: SelectStmt +== 349 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 + ORDER BY unique2 DESC LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 350 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 < 999 + ORDER BY unique2 DESC LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 351 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 352 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 353 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 354 +DROP TABLE onek_with_null +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: DropStmt +== 355 +|-- +-- Check bitmap index path planning +|-- + +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 356 +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 357 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 358 +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 359 +|-- +-- Check behavior with duplicate index column contents +|-- + +CREATE TABLE dupindexcols AS + SELECT unique1 as id, stringu2::text as f1 FROM tenk1 +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 360 +CREATE INDEX dupindexcols_i ON dupindexcols (f1, id, f1 text_pattern_ops) +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=DDL +STMT: IndexStmt +== 361 +ANALYZE dupindexcols +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=DDL +STMT: VacuumStmt +== 362 +EXPLAIN (COSTS OFF) + SELECT count(*) FROM dupindexcols + WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX' +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 363 +SELECT count(*) FROM dupindexcols + WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX' +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 364 +|-- +-- Check that index scans with =ANY indexquals return rows in index order +|-- + +explain (costs off) +SELECT unique1 FROM tenk1 +WHERE unique1 IN (1,42,7) +ORDER BY unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 365 +SELECT unique1 FROM tenk1 +WHERE unique1 IN (1,42,7) +ORDER BY unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 366 +-- Non-required array scan key on "tenthous": +explain (costs off) +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 367 +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 368 +-- Non-required array scan key on "tenthous", backward scan: +explain (costs off) +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand DESC, tenthous DESC +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 369 +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand DESC, tenthous DESC +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 370 +|-- +-- Check elimination of redundant and contradictory index quals +|-- +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = ANY('{7, 8, 9}') +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 371 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = ANY('{7, 8, 9}') +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 372 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') and unique1 = ANY('{33, 44}'::bigint[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 373 +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') and unique1 = ANY('{33, 44}'::bigint[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 374 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 375 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 376 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 12345 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 377 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 12345 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 378 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 >= 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 379 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 >= 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 380 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 381 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 382 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 > 9996 and unique1 >= 9999 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 383 +SELECT unique1 FROM tenk1 WHERE unique1 > 9996 and unique1 >= 9999 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 384 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 <= 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 385 +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 <= 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 386 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 387 +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 388 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 389 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 390 +|-- +-- Check elimination of constant-NULL subexpressions +|-- + +explain (costs off) + select * from tenk1 where (thousand, tenthous) in ((1,1001), (null,null)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 391 +|-- +-- 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) +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=DDL +STMT: CreateStmt +== 392 +explain (costs off) + select * from boolindex order by b, i limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 393 +explain (costs off) + select * from boolindex where b order by i limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 394 +explain (costs off) + select * from boolindex where b = true order by i desc limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 395 +explain (costs off) + select * from boolindex where not b order by i limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 396 +explain (costs off) + select * from boolindex where b is true order by i desc limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 397 +explain (costs off) + select * from boolindex where b is false order by i desc limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 398 +|-- +-- REINDEX (VERBOSE) +|-- +CREATE TABLE reindex_verbose(id integer primary key) +-- +TABLE: name="reindex_verbose" schema="" table="reindex_verbose" ctx=DDL +STMT: CreateStmt +== 399 +REINDEX (VERBOSE) TABLE reindex_verbose +-- +STMT: ReindexStmt +== 400 +DROP TABLE reindex_verbose +-- +TABLE: name="reindex_verbose" schema="" table="reindex_verbose" ctx=DDL +STMT: DropStmt +== 401 +|-- +-- REINDEX CONCURRENTLY +|-- +CREATE TABLE concur_reindex_tab (c1 int) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: CreateStmt +== 402 +-- REINDEX +REINDEX TABLE concur_reindex_tab +-- +STMT: ReindexStmt +== 403 +-- notice +REINDEX (CONCURRENTLY) TABLE concur_reindex_tab +-- +STMT: ReindexStmt +== 404 +-- notice +ALTER TABLE concur_reindex_tab ADD COLUMN c2 text +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: AlterTableStmt +== 405 +-- add toast index +-- Normal index with integer column +CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +== 406 +-- Normal index with text column +CREATE INDEX concur_reindex_ind2 ON concur_reindex_tab(c2) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +== 407 +-- UNIQUE index with expression +CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab(abs(c1)) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 408 +-- Duplicate column names +CREATE INDEX concur_reindex_ind4 ON concur_reindex_tab(c1, c1, c2) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +== 409 +-- 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 +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: AlterTableStmt +== 410 +CREATE TABLE concur_reindex_tab2 (c1 int REFERENCES concur_reindex_tab) +-- +TABLE: name="concur_reindex_tab2" schema="" table="concur_reindex_tab2" ctx=DDL +STMT: CreateStmt +== 411 +INSERT INTO concur_reindex_tab VALUES (1, 'a') +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 412 +INSERT INTO concur_reindex_tab VALUES (2, 'a') +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 413 +-- Reindex concurrently of exclusion constraint currently not supported +CREATE TABLE concur_reindex_tab3 (c1 int, c2 int4range, EXCLUDE USING gist (c2 WITH &&)) +-- +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DDL +STMT: CreateStmt +== 414 +INSERT INTO concur_reindex_tab3 VALUES (3, '[1,2]') +-- +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 415 +REINDEX INDEX CONCURRENTLY concur_reindex_tab3_c2_excl +-- +STMT: ReindexStmt +== 416 +-- error +REINDEX TABLE CONCURRENTLY concur_reindex_tab3 +-- +STMT: ReindexStmt +== 417 +-- succeeds with warning +INSERT INTO concur_reindex_tab3 VALUES (4, '[2,4]') +-- +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 418 +-- Check materialized views +CREATE MATERIALIZED VIEW concur_reindex_matview AS SELECT * FROM concur_reindex_tab +-- +TABLE: name="concur_reindex_matview" schema="" table="concur_reindex_matview" ctx=DDL +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 419 +-- 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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 420 +REINDEX INDEX CONCURRENTLY concur_reindex_ind1 +-- +STMT: ReindexStmt +== 421 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +== 422 +REINDEX TABLE CONCURRENTLY concur_reindex_matview +-- +STMT: ReindexStmt +== 423 +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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 424 +-- Check that comments are preserved +CREATE TABLE testcomment (i int) +-- +TABLE: name="testcomment" schema="" table="testcomment" ctx=DDL +STMT: CreateStmt +== 425 +CREATE INDEX testcomment_idx1 ON testcomment (i) +-- +TABLE: name="testcomment" schema="" table="testcomment" ctx=DDL +STMT: IndexStmt +== 426 +COMMENT ON INDEX testcomment_idx1 IS 'test comment' +-- +STMT: CommentStmt +== 427 +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +== 428 +REINDEX TABLE testcomment +-- +STMT: ReindexStmt +== 429 +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +== 430 +REINDEX TABLE CONCURRENTLY testcomment +-- +STMT: ReindexStmt +== 431 +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +== 432 +DROP TABLE testcomment +-- +TABLE: name="testcomment" schema="" table="testcomment" ctx=DDL +STMT: DropStmt +== 433 +-- Check that indisclustered updates are preserved +CREATE TABLE concur_clustered(i int) +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: CreateStmt +== 434 +CREATE INDEX concur_clustered_i_idx ON concur_clustered(i) +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: IndexStmt +== 435 +ALTER TABLE concur_clustered CLUSTER ON concur_clustered_i_idx +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: AlterTableStmt +== 436 +REINDEX TABLE CONCURRENTLY concur_clustered +-- +STMT: ReindexStmt +== 437 +SELECT indexrelid::regclass, indisclustered FROM pg_index + WHERE indrelid = 'concur_clustered'::regclass +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 438 +DROP TABLE concur_clustered +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: DropStmt +== 439 +-- Check that indisreplident updates are preserved. +CREATE TABLE concur_replident(i int NOT NULL) +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: CreateStmt +== 440 +CREATE UNIQUE INDEX concur_replident_i_idx ON concur_replident(i) +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: IndexStmt +== 441 +ALTER TABLE concur_replident REPLICA IDENTITY + USING INDEX concur_replident_i_idx +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: AlterTableStmt +== 442 +SELECT indexrelid::regclass, indisreplident FROM pg_index + WHERE indrelid = 'concur_replident'::regclass +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 443 +REINDEX TABLE CONCURRENTLY concur_replident +-- +STMT: ReindexStmt +== 444 +SELECT indexrelid::regclass, indisreplident FROM pg_index + WHERE indrelid = 'concur_replident'::regclass +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 445 +DROP TABLE concur_replident +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: DropStmt +== 446 +-- Check that opclass parameters are preserved +CREATE TABLE concur_appclass_tab(i tsvector, j tsvector, k tsvector) +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: CreateStmt +== 447 +CREATE INDEX concur_appclass_ind on concur_appclass_tab + USING gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500')) +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: IndexStmt +== 448 +CREATE INDEX concur_appclass_ind_2 on concur_appclass_tab + USING gist (k tsvector_ops (siglen='300'), j tsvector_ops) +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: IndexStmt +== 449 +REINDEX TABLE CONCURRENTLY concur_appclass_tab +-- +STMT: ReindexStmt +== 450 +DROP TABLE concur_appclass_tab +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: DropStmt +== 451 +-- Partitions +-- Create some partitioned tables +CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: CreateStmt +== 452 +CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2) +-- +TABLE: name="concur_reindex_part_0" schema="" table="concur_reindex_part_0" ctx=DDL +STMT: CreateStmt +== 453 +CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (1) +-- +TABLE: name="concur_reindex_part_0_1" schema="" table="concur_reindex_part_0_1" ctx=DDL +STMT: CreateStmt +== 454 +CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (2) +-- +TABLE: name="concur_reindex_part_0_2" schema="" table="concur_reindex_part_0_2" ctx=DDL +STMT: CreateStmt +== 455 +-- 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) +-- +TABLE: name="concur_reindex_part_10" schema="" table="concur_reindex_part_10" ctx=DDL +STMT: CreateStmt +== 456 +-- Create some partitioned indexes +CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: IndexStmt +== 457 +CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1) +-- +TABLE: name="concur_reindex_part_0" schema="" table="concur_reindex_part_0" ctx=DDL +STMT: IndexStmt +== 458 +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0 +-- +STMT: AlterTableStmt +== 459 +-- This partitioned index will have no partitions. +CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1) +-- +TABLE: name="concur_reindex_part_10" schema="" table="concur_reindex_part_10" ctx=DDL +STMT: IndexStmt +== 460 +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10 +-- +STMT: AlterTableStmt +== 461 +CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1) +-- +TABLE: name="concur_reindex_part_0_1" schema="" table="concur_reindex_part_0_1" ctx=DDL +STMT: IndexStmt +== 462 +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1 +-- +STMT: AlterTableStmt +== 463 +CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1) +-- +TABLE: name="concur_reindex_part_0_2" schema="" table="concur_reindex_part_0_2" ctx=DDL +STMT: IndexStmt +== 464 +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2 +-- +STMT: AlterTableStmt +== 465 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 466 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 467 +-- 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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 468 +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1 +-- +STMT: ReindexStmt +== 469 +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2 +-- +STMT: ReindexStmt +== 470 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 471 +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1 +-- +STMT: ReindexStmt +== 472 +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2 +-- +STMT: ReindexStmt +== 473 +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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +== 474 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 475 +-- REINDEX for partitioned indexes +-- REINDEX TABLE fails for partitioned indexes +-- Top-most parent index +REINDEX TABLE concur_reindex_part_index +-- +STMT: ReindexStmt +== 476 +-- error +REINDEX TABLE CONCURRENTLY concur_reindex_part_index +-- +STMT: ReindexStmt +== 477 +-- error +-- Partitioned index with no leaves +REINDEX TABLE concur_reindex_part_index_10 +-- +STMT: ReindexStmt +== 478 +-- error +REINDEX TABLE CONCURRENTLY concur_reindex_part_index_10 +-- +STMT: ReindexStmt +== 479 +-- error +-- Cannot run in a transaction block +BEGIN +-- +STMT: TransactionStmt +== 480 +REINDEX INDEX concur_reindex_part_index +-- +STMT: ReindexStmt +== 481 +ROLLBACK +-- +STMT: TransactionStmt +== 482 +-- Helper functions to track changes of relfilenodes in a partition tree. +-- Create a table tracking the relfilenode state. +CREATE OR REPLACE FUNCTION create_relfilenode_part(relname text, indname text) + RETURNS VOID AS + $func$ + BEGIN + EXECUTE format(' + CREATE TABLE %I AS + SELECT oid, relname, relfilenode, relkind, reltoastrelid + FROM pg_class + WHERE oid IN + (SELECT relid FROM pg_partition_tree(''%I''));', + relname, indname); + END + $func$ LANGUAGE plpgsql +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 483 +CREATE OR REPLACE FUNCTION compare_relfilenode_part(tabname text) + RETURNS TABLE (relname name, relkind "char", state text) AS + $func$ + BEGIN + RETURN QUERY EXECUTE + format( + 'SELECT b.relname, + b.relkind, + CASE WHEN a.relfilenode = b.relfilenode THEN ''relfilenode is unchanged'' + ELSE ''relfilenode has changed'' END + -- Do not join with OID here as CONCURRENTLY changes it. + FROM %I b JOIN pg_class a ON b.relname = a.relname + ORDER BY 1;', tabname); + END + $func$ LANGUAGE plpgsql +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 484 +-- Check that expected relfilenodes are changed, non-concurrent case. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 485 +REINDEX INDEX concur_reindex_part_index +-- +STMT: ReindexStmt +== 486 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 487 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +== 488 +-- concurrent case. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 489 +REINDEX INDEX CONCURRENTLY concur_reindex_part_index +-- +STMT: ReindexStmt +== 490 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 491 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +== 492 +-- REINDEX for partitioned tables +-- REINDEX INDEX fails for partitioned tables +-- Top-most parent +REINDEX INDEX concur_reindex_part +-- +STMT: ReindexStmt +== 493 +-- error +REINDEX INDEX CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +== 494 +-- error +-- Partitioned with no leaves +REINDEX INDEX concur_reindex_part_10 +-- +STMT: ReindexStmt +== 495 +-- error +REINDEX INDEX CONCURRENTLY concur_reindex_part_10 +-- +STMT: ReindexStmt +== 496 +-- error +-- Cannot run in a transaction block +BEGIN +-- +STMT: TransactionStmt +== 497 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +== 498 +ROLLBACK +-- +STMT: TransactionStmt +== 499 +-- Check that expected relfilenodes are changed, non-concurrent case. +-- Note that the partition tree changes of the *indexes* need to be checked. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 500 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +== 501 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 502 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +== 503 +-- concurrent case. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 504 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +== 505 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +== 506 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +== 507 +DROP FUNCTION create_relfilenode_part +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=DDL +STMT: DropStmt +== 508 +DROP FUNCTION compare_relfilenode_part +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=DDL +STMT: DropStmt +== 509 +-- Cleanup of partition tree used for REINDEX test. +DROP TABLE concur_reindex_part +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: DropStmt +== 510 +-- Check errors +-- Cannot run inside a transaction block +BEGIN +-- +STMT: TransactionStmt +== 511 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +== 512 +COMMIT +-- +STMT: TransactionStmt +== 513 +REINDEX TABLE CONCURRENTLY pg_class +-- +STMT: ReindexStmt +== 514 +-- no catalog relation +REINDEX INDEX CONCURRENTLY pg_class_oid_index +-- +STMT: ReindexStmt +== 515 +-- no catalog index +-- These are the toast table and index of pg_authid. +REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +== 516 +-- no catalog toast table +REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +== 517 +-- no catalog toast index +REINDEX SYSTEM CONCURRENTLY postgres +-- +STMT: ReindexStmt +== 518 +-- not allowed for SYSTEM +REINDEX (CONCURRENTLY) SYSTEM postgres +-- +STMT: ReindexStmt +== 519 +-- ditto +REINDEX (CONCURRENTLY) SYSTEM +-- +STMT: ReindexStmt +== 520 +-- ditto +-- Warns about catalog relations +REINDEX SCHEMA CONCURRENTLY pg_catalog +-- +STMT: ReindexStmt +== 521 +-- Not the current database +REINDEX DATABASE not_current_database +-- +STMT: ReindexStmt +== 522 +-- Check the relation status, there should not be invalid indexes +DROP MATERIALIZED VIEW concur_reindex_matview +-- +STMT: DropStmt +== 523 +DROP TABLE concur_reindex_tab, concur_reindex_tab2, concur_reindex_tab3 +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +TABLE: name="concur_reindex_tab2" schema="" table="concur_reindex_tab2" ctx=DDL +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DDL +STMT: DropStmt +== 524 +-- Check handling of invalid indexes +CREATE TABLE concur_reindex_tab4 (c1 int) +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DDL +STMT: CreateStmt +== 525 +INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2) +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 526 +-- This trick creates an invalid index. +CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1) +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DDL +STMT: IndexStmt +== 527 +-- 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 +-- +STMT: ReindexStmt +== 528 +DROP INDEX concur_reindex_ind5_ccnew +-- +STMT: DropStmt +== 529 +-- This makes the previous failure go away, so the index can become valid. +DELETE FROM concur_reindex_tab4 WHERE c1 = 1 +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DML +STMT: DeleteStmt +== 530 +-- The invalid index is not processed when running REINDEX TABLE. +REINDEX TABLE CONCURRENTLY concur_reindex_tab4 +-- +STMT: ReindexStmt +== 531 +-- But it is fixed with REINDEX INDEX. +REINDEX INDEX CONCURRENTLY concur_reindex_ind5 +-- +STMT: ReindexStmt +== 532 +DROP TABLE concur_reindex_tab4 +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DDL +STMT: DropStmt +== 533 +-- 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) +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: CreateStmt +== 534 +INSERT INTO concur_exprs_tab (c1, c2) VALUES (1369652450, FALSE), + (414515746, TRUE), + (897778963, FALSE) +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 535 +CREATE UNIQUE INDEX concur_exprs_index_expr + ON concur_exprs_tab ((c1::text COLLATE "C")) +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: IndexStmt +== 536 +CREATE UNIQUE INDEX concur_exprs_index_pred ON concur_exprs_tab (c1) + WHERE (c1::text > 500000000::text COLLATE "C") +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: IndexStmt +== 537 +CREATE UNIQUE INDEX concur_exprs_index_pred_2 + ON concur_exprs_tab ((1 / c1)) + WHERE ('-H') >= (c2::TEXT) COLLATE "C" +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: IndexStmt +== 538 +ALTER INDEX concur_exprs_index_expr ALTER COLUMN 1 SET STATISTICS 100 +-- +STMT: AlterTableStmt +== 539 +ANALYZE concur_exprs_tab +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: VacuumStmt +== 540 +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 +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="starelid" +STMT: SelectStmt +== 541 +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 542 +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 543 +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 544 +REINDEX TABLE CONCURRENTLY concur_exprs_tab +-- +STMT: ReindexStmt +== 545 +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 546 +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 547 +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 548 +-- ALTER TABLE recreates the indexes, which should keep their collations. +ALTER TABLE concur_exprs_tab ALTER c2 TYPE TEXT +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: AlterTableStmt +== 549 +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 550 +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 551 +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 552 +-- 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 +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="starelid" +STMT: SelectStmt +== 553 +-- 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 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +== 554 +DROP TABLE concur_exprs_tab +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: DropStmt +== 555 +-- 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 +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DDL +STMT: CreateStmt +== 556 +INSERT INTO concur_temp_tab_1 VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 557 +CREATE INDEX concur_temp_ind_1 ON concur_temp_tab_1(c2) +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DDL +STMT: IndexStmt +== 558 +REINDEX TABLE CONCURRENTLY concur_temp_tab_1 +-- +STMT: ReindexStmt +== 559 +REINDEX INDEX CONCURRENTLY concur_temp_ind_1 +-- +STMT: ReindexStmt +== 560 +-- Still fails in transaction blocks +BEGIN +-- +STMT: TransactionStmt +== 561 +REINDEX INDEX CONCURRENTLY concur_temp_ind_1 +-- +STMT: ReindexStmt +== 562 +COMMIT +-- +STMT: TransactionStmt +== 563 +-- ON COMMIT DELETE ROWS +CREATE TEMP TABLE concur_temp_tab_2 (c1 int, c2 text) + ON COMMIT DELETE ROWS +-- +TABLE: name="concur_temp_tab_2" schema="" table="concur_temp_tab_2" ctx=DDL +STMT: CreateStmt +== 564 +CREATE INDEX concur_temp_ind_2 ON concur_temp_tab_2(c2) +-- +TABLE: name="concur_temp_tab_2" schema="" table="concur_temp_tab_2" ctx=DDL +STMT: IndexStmt +== 565 +REINDEX TABLE CONCURRENTLY concur_temp_tab_2 +-- +STMT: ReindexStmt +== 566 +REINDEX INDEX CONCURRENTLY concur_temp_ind_2 +-- +STMT: ReindexStmt +== 567 +-- ON COMMIT DROP +BEGIN +-- +STMT: TransactionStmt +== 568 +CREATE TEMP TABLE concur_temp_tab_3 (c1 int, c2 text) + ON COMMIT PRESERVE ROWS +-- +TABLE: name="concur_temp_tab_3" schema="" table="concur_temp_tab_3" ctx=DDL +STMT: CreateStmt +== 569 +INSERT INTO concur_temp_tab_3 VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp_tab_3" schema="" table="concur_temp_tab_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 570 +CREATE INDEX concur_temp_ind_3 ON concur_temp_tab_3(c2) +-- +TABLE: name="concur_temp_tab_3" schema="" table="concur_temp_tab_3" ctx=DDL +STMT: IndexStmt +== 571 +-- Fails when running in a transaction +REINDEX INDEX CONCURRENTLY concur_temp_ind_3 +-- +STMT: ReindexStmt +== 572 +COMMIT +-- +STMT: TransactionStmt +== 573 +-- 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') +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 574 +SELECT pg_my_temp_schema()::regnamespace as temp_schema_name +-- +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +STMT: SelectStmt +== 575 +REINDEX SCHEMA CONCURRENTLY :temp_schema_name +-- +ERROR: syntax error at or near ":" +CURSORPOS: 29 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 576 +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 +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="reindex_temp_before" +STMT: SelectStmt +== 577 +DROP TABLE concur_temp_tab_1, concur_temp_tab_2, reindex_temp_before +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DDL +TABLE: name="concur_temp_tab_2" schema="" table="concur_temp_tab_2" ctx=DDL +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=DDL +STMT: DropStmt +== 578 +|-- +-- REINDEX SCHEMA +|-- +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +== 579 +-- failure, schema does not exist +CREATE SCHEMA schema_to_reindex +-- +STMT: CreateSchemaStmt +== 580 +SET search_path = 'schema_to_reindex' +-- +STMT: VariableSetStmt +== 581 +CREATE TABLE table1(col1 SERIAL PRIMARY KEY) +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: CreateStmt +== 582 +INSERT INTO table1 SELECT generate_series(1,400) +-- +TABLE: name="table1" schema="" table="table1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 583 +CREATE TABLE table2(col1 SERIAL PRIMARY KEY, col2 TEXT NOT NULL) +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: CreateStmt +== 584 +INSERT INTO table2 SELECT generate_series(1,400), 'abc' +-- +TABLE: name="table2" schema="" table="table2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 585 +CREATE INDEX ON table2(col2) +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: IndexStmt +== 586 +CREATE MATERIALIZED VIEW matview AS SELECT col1 FROM table2 +-- +TABLE: name="matview" schema="" table="matview" ctx=DDL +TABLE: name="table2" schema="" table="table2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 587 +CREATE INDEX ON matview(col1) +-- +TABLE: name="matview" schema="" table="matview" ctx=DDL +STMT: IndexStmt +== 588 +CREATE VIEW view AS SELECT col2 FROM table2 +-- +TABLE: name="view" schema="" table="view" ctx=DDL +TABLE: name="table2" schema="" table="table2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 589 +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') +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 590 +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) +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=DML +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="reltoastrelid" +STMT: InsertStmt +STMT: SelectStmt +== 591 +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)) +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=DML +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="reltoastrelid" +STMT: InsertStmt +STMT: SelectStmt +== 592 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +== 593 +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') +-- +TABLE: name="reindex_after" schema="" table="reindex_after" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 594 +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 +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="reindex_before" +STMT: SelectStmt +== 595 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +== 596 +BEGIN +-- +STMT: TransactionStmt +== 597 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +== 598 +-- failure, cannot run in a transaction +END +-- +STMT: TransactionStmt +== 599 +-- concurrently +REINDEX SCHEMA CONCURRENTLY schema_to_reindex +-- +STMT: ReindexStmt +== 600 +-- Failure for unauthorized user +CREATE ROLE regress_reindexuser NOLOGIN +-- +STMT: CreateRoleStmt +== 601 +SET SESSION ROLE regress_reindexuser +-- +STMT: VariableSetStmt +== 602 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +== 603 +-- Permission failures with toast tables and indexes (pg_authid here) +RESET ROLE +-- +STMT: VariableSetStmt +== 604 +GRANT USAGE ON SCHEMA pg_toast TO regress_reindexuser +-- +STMT: GrantStmt +== 605 +SET SESSION ROLE regress_reindexuser +-- +STMT: VariableSetStmt +== 606 +REINDEX TABLE pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +== 607 +REINDEX INDEX pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +== 608 +-- Clean up +RESET ROLE +-- +STMT: VariableSetStmt +== 609 +REVOKE USAGE ON SCHEMA pg_toast FROM regress_reindexuser +-- +STMT: GrantStmt +== 610 +DROP ROLE regress_reindexuser +-- +STMT: DropRoleStmt +== 611 +DROP SCHEMA schema_to_reindex CASCADE +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json b/parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json new file mode 100644 index 0000000..18fb3ca --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json @@ -0,0 +1,206 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_index_spgist.test b/parser/testdata/summary/postgres_regress/create_index_spgist.test new file mode 100644 index 0000000..5640897 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_index_spgist.test @@ -0,0 +1,1585 @@ +== 001 +|-- +-- SP-GiST index tests +|-- + +CREATE TABLE quad_point_tbl AS + SELECT point(unique1,unique2) AS p FROM tenk1 +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 002 +INSERT INTO quad_point_tbl + SELECT '(333.0,400.0)'::point FROM generate_series(1,1000) +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL) +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p) +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DDL +STMT: IndexStmt +== 005 +CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 006 +CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops) +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=DDL +STMT: IndexStmt +== 007 +CREATE TABLE radix_text_tbl AS + SELECT name AS t FROM road WHERE name !~ '^[0-9]' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DDL +TABLE: name="road" schema="" table="road" ctx=Select +FILTER: schema="" table="" column="name" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 008 +INSERT INTO radix_text_tbl + SELECT 'P0123456789abcdef' FROM generate_series(1,1000) +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO radix_text_tbl VALUES ('P0123456789abcde') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t) +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DDL +STMT: IndexStmt +== 012 +-- get non-indexed results for comparison purposes + +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +== 013 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 014 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 015 +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 016 +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 017 +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 019 +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 020 +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 021 +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 022 +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 023 +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 024 +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 025 +CREATE TEMP TABLE quad_point_tbl_ord_seq1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 026 +CREATE TEMP TABLE quad_point_tbl_ord_seq2 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)' +-- +TABLE: name="quad_point_tbl_ord_seq2" schema="" table="quad_point_tbl_ord_seq2" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 027 +CREATE TEMP TABLE quad_point_tbl_ord_seq3 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 +-- +TABLE: name="quad_point_tbl_ord_seq3" schema="" table="quad_point_tbl_ord_seq3" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 028 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 029 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 030 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 031 +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 032 +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 033 +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 034 +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 035 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 036 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 037 +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 038 +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 039 +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 040 +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 041 +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 042 +-- Now check the results from plain indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 043 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 044 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 045 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 047 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 048 +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 049 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 050 +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 051 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 053 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 054 +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 055 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 056 +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 057 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 058 +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 059 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 060 +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 061 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 062 +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 063 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 064 +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 065 +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 066 +CREATE TEMP TABLE quad_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl_ord_idx1" schema="" table="quad_point_tbl_ord_idx1" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 067 +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 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +TABLE: name="quad_point_tbl_ord_idx1" schema="" table="quad_point_tbl_ord_idx1" ctx=Select +ALIAS: "idx"="quad_point_tbl_ord_idx1" +ALIAS: "seq"="quad_point_tbl_ord_seq1" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +== 068 +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)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 069 +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)' +-- +TABLE: name="quad_point_tbl_ord_idx2" schema="" table="quad_point_tbl_ord_idx2" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 070 +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 +-- +TABLE: name="quad_point_tbl_ord_seq2" schema="" table="quad_point_tbl_ord_seq2" ctx=Select +TABLE: name="quad_point_tbl_ord_idx2" schema="" table="quad_point_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="quad_point_tbl_ord_idx2" +ALIAS: "seq"="quad_point_tbl_ord_seq2" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +== 071 +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 +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 072 +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 +-- +TABLE: name="quad_point_tbl_ord_idx3" schema="" table="quad_point_tbl_ord_idx3" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 073 +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 +-- +TABLE: name="quad_point_tbl_ord_seq3" schema="" table="quad_point_tbl_ord_seq3" ctx=Select +TABLE: name="quad_point_tbl_ord_idx3" schema="" table="quad_point_tbl_ord_idx3" ctx=Select +ALIAS: "idx"="quad_point_tbl_ord_idx3" +ALIAS: "seq"="quad_point_tbl_ord_seq3" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +== 074 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 075 +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 076 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 077 +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 078 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 079 +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 080 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 081 +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 082 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 083 +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 084 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 085 +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 086 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 087 +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 088 +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 089 +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 +-- +TABLE: name="kd_point_tbl_ord_idx1" schema="" table="kd_point_tbl_ord_idx1" ctx=DDL +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 090 +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 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +TABLE: name="kd_point_tbl_ord_idx1" schema="" table="kd_point_tbl_ord_idx1" ctx=Select +ALIAS: "idx"="kd_point_tbl_ord_idx1" +ALIAS: "seq"="quad_point_tbl_ord_seq1" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +== 091 +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)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 092 +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)' +-- +TABLE: name="kd_point_tbl_ord_idx2" schema="" table="kd_point_tbl_ord_idx2" ctx=DDL +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 093 +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 +-- +TABLE: name="quad_point_tbl_ord_seq2" schema="" table="quad_point_tbl_ord_seq2" ctx=Select +TABLE: name="kd_point_tbl_ord_idx2" schema="" table="kd_point_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="kd_point_tbl_ord_idx2" +ALIAS: "seq"="quad_point_tbl_ord_seq2" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +== 094 +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 +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 095 +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 +-- +TABLE: name="kd_point_tbl_ord_idx3" schema="" table="kd_point_tbl_ord_idx3" ctx=DDL +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 096 +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 +-- +TABLE: name="quad_point_tbl_ord_seq3" schema="" table="quad_point_tbl_ord_seq3" ctx=Select +TABLE: name="kd_point_tbl_ord_idx3" schema="" table="kd_point_tbl_ord_idx3" ctx=Select +ALIAS: "idx"="kd_point_tbl_ord_idx3" +ALIAS: "seq"="quad_point_tbl_ord_seq3" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +== 097 +-- test KNN scan with included columns +-- the distance numbers are not exactly the same across platforms +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +== 098 +CREATE INDEX ON quad_point_tbl_ord_seq1 USING spgist(p) INCLUDE(dist) +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=DDL +STMT: IndexStmt +== 099 +EXPLAIN (COSTS OFF) +SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 100 +SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +STMT: SelectStmt +== 101 +RESET extra_float_digits +-- +STMT: VariableSetStmt +== 102 +-- 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) +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +STMT: SelectStmt +== 103 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 104 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 105 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 106 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 107 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 108 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 109 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 110 +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 111 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 112 +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 113 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 114 +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 115 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 116 +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 117 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 118 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 119 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 120 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 121 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 122 +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 123 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 124 +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 125 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 126 +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 127 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 128 +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 129 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 130 +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 131 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 132 +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 133 +-- Now check the results from bitmap indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 134 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 135 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +== 136 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 137 +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 138 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 139 +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 140 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 141 +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 142 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 143 +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 144 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 145 +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 146 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 147 +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 148 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 149 +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 150 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 151 +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 152 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 153 +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 154 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 155 +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 156 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 157 +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 158 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 159 +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 160 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 161 +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 162 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 163 +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 164 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 165 +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 166 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 167 +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 168 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 169 +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 170 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 171 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 172 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 173 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 174 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 175 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 176 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 177 +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 178 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 179 +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 180 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 181 +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 182 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 183 +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 184 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 185 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 186 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 187 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 188 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 189 +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 190 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 191 +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 192 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 193 +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 194 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 195 +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 196 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 197 +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 198 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 199 +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 200 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 201 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 202 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/create_misc.metadata.json b/parser/testdata/summary/postgres_regress/create_misc.metadata.json new file mode 100644 index 0000000..aa15346 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_misc.metadata.json @@ -0,0 +1,92 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_misc.test b/parser/testdata/summary/postgres_regress/create_misc.test new file mode 100644 index 0000000..1d02053 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_misc.test @@ -0,0 +1,588 @@ +== 001 +|-- +-- CREATE_MISC +|-- + +|-- +-- a is the type root +-- b and c inherit from a (one-level single inheritance) +-- d inherits from b and c (two-level multiple inheritance) +-- e inherits from c (two-level single inheritance) +-- f inherits from e (three-level single inheritance) +|-- +CREATE TABLE a_star ( + class char, + a int4 +) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE b_star ( + b text +) INHERITS (a_star) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE c_star ( + c name +) INHERITS (a_star) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE d_star ( + d float8 +) INHERITS (b_star, c_star) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: CreateStmt +== 005 +CREATE TABLE e_star ( + e int2 +) INHERITS (c_star) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: CreateStmt +== 006 +CREATE TABLE f_star ( + f polygon +) INHERITS (e_star) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: CreateStmt +== 007 +INSERT INTO a_star (class, a) VALUES ('a', 1) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO a_star (class, a) VALUES ('a', 2) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO a_star (class) VALUES ('a') +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO b_star (class, a, b) VALUES ('b', 3, 'mumble'::text) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO b_star (class, a) VALUES ('b', 4) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO b_star (class, b) VALUES ('b', 'bumble'::text) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO b_star (class) VALUES ('b') +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO c_star (class, a, c) VALUES ('c', 5, 'hi mom'::name) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO c_star (class, a) VALUES ('c', 6) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO c_star (class, c) VALUES ('c', 'hi paul'::name) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO c_star (class) VALUES ('c') +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO d_star (class, a, b, c, d) + VALUES ('d', 7, 'grumble'::text, 'hi sunita'::name, '0.0'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO d_star (class, a, b, c) + VALUES ('d', 8, 'stumble'::text, 'hi koko'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO d_star (class, a, b, d) + VALUES ('d', 9, 'rumble'::text, '1.1'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO d_star (class, a, c, d) + VALUES ('d', 10, 'hi kristin'::name, '10.01'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO d_star (class, b, c, d) + VALUES ('d', 'crumble'::text, 'hi boris'::name, '100.001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO d_star (class, a, b) + VALUES ('d', 11, 'fumble'::text) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO d_star (class, a, c) + VALUES ('d', 12, 'hi avi'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO d_star (class, a, d) + VALUES ('d', 13, '1000.0001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO d_star (class, b, c) + VALUES ('d', 'tumble'::text, 'hi andrew'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO d_star (class, b, d) + VALUES ('d', 'humble'::text, '10000.00001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO d_star (class, c, d) + VALUES ('d', 'hi ginger'::name, '100000.000001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO d_star (class, a) VALUES ('d', 14) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO d_star (class, b) VALUES ('d', 'jumble'::text) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO d_star (class, c) VALUES ('d', 'hi jolly'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO d_star (class, d) VALUES ('d', '1000000.0000001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO d_star (class) VALUES ('d') +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO e_star (class, a, c, e) + VALUES ('e', 15, 'hi carol'::name, '-1'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO e_star (class, a, c) + VALUES ('e', 16, 'hi bob'::name) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO e_star (class, a, e) + VALUES ('e', 17, '-2'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO e_star (class, c, e) + VALUES ('e', 'hi michelle'::name, '-3'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO e_star (class, a) + VALUES ('e', 18) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO e_star (class, c) + VALUES ('e', 'hi elisa'::name) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO e_star (class, e) + VALUES ('e', '-4'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO f_star (class, a, c, e, f) + VALUES ('f', 19, 'hi claire'::name, '-5'::int2, '(1,3),(2,4)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO f_star (class, a, c, e) + VALUES ('f', 20, 'hi mike'::name, '-6'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO f_star (class, a, c, f) + VALUES ('f', 21, 'hi marcel'::name, '(11,44),(22,55),(33,66)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO f_star (class, a, e, f) + VALUES ('f', 22, '-7'::int2, '(111,555),(222,666),(333,777),(444,888)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO f_star (class, c, e, f) + VALUES ('f', 'hi keith'::name, '-8'::int2, + '(1111,3333),(2222,4444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO f_star (class, a, c) + VALUES ('f', 24, 'hi marc'::name) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO f_star (class, a, e) + VALUES ('f', 25, '-9'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO f_star (class, a, f) + VALUES ('f', 26, '(11111,33333),(22222,44444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO f_star (class, c, e) + VALUES ('f', 'hi allison'::name, '-10'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO f_star (class, c, f) + VALUES ('f', 'hi jeff'::name, + '(111111,333333),(222222,444444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +INSERT INTO f_star (class, e, f) + VALUES ('f', '-11'::int2, '(1111111,3333333),(2222222,4444444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO f_star (class, a) VALUES ('f', 27) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO f_star (class, c) VALUES ('f', 'hi carl'::name) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +INSERT INTO f_star (class, e) VALUES ('f', '-12'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +INSERT INTO f_star (class, f) + VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +INSERT INTO f_star (class) VALUES ('f') +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +-- Analyze the X_star tables for better plan stability in later tests +ANALYZE a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: VacuumStmt +== 058 +ANALYZE b_star +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: VacuumStmt +== 059 +ANALYZE c_star +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: VacuumStmt +== 060 +ANALYZE d_star +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: VacuumStmt +== 061 +ANALYZE e_star +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: VacuumStmt +== 062 +ANALYZE f_star +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: VacuumStmt +== 063 +|-- +-- inheritance stress test +|-- +SELECT * FROM a_star* +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +STMT: SelectStmt +== 064 +SELECT * + FROM b_star* x + WHERE x.b = text 'bumble' or x.a < 3 +-- +TABLE: name="b_star" schema="" table="b_star" ctx=Select +ALIAS: "x"="b_star" +FILTER: schema="" table="x" column="b" +FILTER: schema="" table="x" column="a" +STMT: SelectStmt +== 065 +SELECT class, a + FROM c_star* x + WHERE x.c ~ text 'hi' +-- +TABLE: name="c_star" schema="" table="c_star" ctx=Select +ALIAS: "x"="c_star" +FILTER: schema="" table="x" column="c" +STMT: SelectStmt +== 066 +SELECT class, b, c + FROM d_star* x + WHERE x.a < 100 +-- +TABLE: name="d_star" schema="" table="d_star" ctx=Select +ALIAS: "x"="d_star" +FILTER: schema="" table="x" column="a" +STMT: SelectStmt +== 067 +SELECT class, c FROM e_star* x WHERE x.c NOTNULL +-- +TABLE: name="e_star" schema="" table="e_star" ctx=Select +ALIAS: "x"="e_star" +FILTER: schema="" table="x" column="c" +STMT: SelectStmt +== 068 +SELECT * FROM f_star* x WHERE x.c ISNULL +-- +TABLE: name="f_star" schema="" table="f_star" ctx=Select +ALIAS: "x"="f_star" +FILTER: schema="" table="x" column="c" +STMT: SelectStmt +== 069 +-- grouping and aggregation on inherited sets have been busted in the past... + +SELECT sum(a) FROM a_star* +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT class, sum(a) FROM a_star* GROUP BY class ORDER BY class +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 071 +ALTER TABLE f_star RENAME COLUMN f TO ff +-- +STMT: RenameStmt +== 072 +ALTER TABLE e_star* RENAME COLUMN e TO ee +-- +STMT: RenameStmt +== 073 +ALTER TABLE d_star* RENAME COLUMN d TO dd +-- +STMT: RenameStmt +== 074 +ALTER TABLE c_star* RENAME COLUMN c TO cc +-- +STMT: RenameStmt +== 075 +ALTER TABLE b_star* RENAME COLUMN b TO bb +-- +STMT: RenameStmt +== 076 +ALTER TABLE a_star* RENAME COLUMN a TO aa +-- +STMT: RenameStmt +== 077 +SELECT class, aa + FROM a_star* x + WHERE aa ISNULL +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "x"="a_star" +FILTER: schema="" table="" column="aa" +STMT: SelectStmt +== 078 +-- As of Postgres 7.1, ALTER implicitly recurses, +-- so this should be same as ALTER a_star* + +ALTER TABLE a_star RENAME COLUMN aa TO foo +-- +STMT: RenameStmt +== 079 +SELECT class, foo + FROM a_star* x + WHERE x.foo >= 2 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "x"="a_star" +FILTER: schema="" table="x" column="foo" +STMT: SelectStmt +== 080 +ALTER TABLE a_star RENAME COLUMN foo TO aa +-- +STMT: RenameStmt +== 081 +SELECT * + from a_star* + WHERE aa < 1000 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FILTER: schema="" table="" column="aa" +STMT: SelectStmt +== 082 +ALTER TABLE f_star ADD COLUMN f int4 +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: AlterTableStmt +== 083 +UPDATE f_star SET f = 10 +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: UpdateStmt +== 084 +ALTER TABLE e_star* ADD COLUMN e int4 +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: AlterTableStmt +== 085 +--UPDATE e_star* SET e = 42; + +SELECT * FROM e_star* +-- +TABLE: name="e_star" schema="" table="e_star" ctx=Select +STMT: SelectStmt +== 086 +ALTER TABLE a_star* ADD COLUMN a text +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: AlterTableStmt +== 087 +-- That ALTER TABLE should have added TOAST tables. +SELECT relname, reltoastrelid <> 0 AS has_toast_table + FROM pg_class + WHERE oid::regclass IN ('a_star', 'c_star') + ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 088 +--UPDATE b_star* +-- SET a = text 'gazpacho' +-- WHERE aa > 4; + +SELECT class, aa, a FROM a_star* +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/create_operator.metadata.json b/parser/testdata/summary/postgres_regress/create_operator.metadata.json new file mode 100644 index 0000000..44e163a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_operator.metadata.json @@ -0,0 +1,94 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_operator.test b/parser/testdata/summary/postgres_regress/create_operator.test new file mode 100644 index 0000000..0969ac1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_operator.test @@ -0,0 +1,530 @@ +== 001 +|-- +-- CREATE_OPERATOR +|-- + +CREATE OPERATOR ## ( + leftarg = path, + rightarg = path, + function = path_inter, + commutator = ## +) +-- +STMT: DefineStmt +== 002 +CREATE OPERATOR @#@ ( + rightarg = int8, -- prefix + procedure = factorial +) +-- +STMT: DefineStmt +== 003 +CREATE OPERATOR #%# ( + leftarg = int8, -- fail, postfix is no longer supported + procedure = factorial +) +-- +STMT: DefineStmt +== 004 +-- Test operator created above +SELECT @#@ 24 +-- +STMT: SelectStmt +== 005 +-- Test comments +COMMENT ON OPERATOR ###### (NONE, int4) IS 'bad prefix' +-- +STMT: CommentStmt +== 006 +COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad postfix' +-- +STMT: CommentStmt +== 007 +COMMENT ON OPERATOR ###### (int4, int8) IS 'bad infix' +-- +STMT: CommentStmt +== 008 +-- Check that DROP on a nonexistent op behaves sanely, too +DROP OPERATOR ###### (NONE, int4) +-- +STMT: DropStmt +== 009 +DROP OPERATOR ###### (int4, NONE) +-- +STMT: DropStmt +== 010 +DROP OPERATOR ###### (int4, int8) +-- +STMT: DropStmt +== 011 +-- => is disallowed as an operator name now +CREATE OPERATOR => ( + rightarg = int8, + procedure = factorial +) +-- +ERROR: syntax error at or near "=>" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- lexing of <=, >=, <>, != has a number of edge cases +-- (=> is tested elsewhere) + +-- this is legal because ! is not allowed in sql ops +CREATE OPERATOR !=- ( + rightarg = int8, + procedure = factorial +) +-- +STMT: DefineStmt +== 013 +SELECT !=- 10 +-- +STMT: SelectStmt +== 014 +-- postfix operators don't work anymore +SELECT 10 !=- +-- +ERROR: syntax error at end of input +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 015 +-- make sure lexer returns != as <> even in edge cases +SELECT 2 !=/**/ 1, 2 !=/**/ 2 +-- +STMT: SelectStmt +== 016 +SELECT 2 !=-- comment to be removed by psql + 1 +-- +STMT: SelectStmt +== 017 +DO $$ -- use DO to protect -- from psql + declare r boolean; + begin + execute $e$ select 2 !=-- comment + 1 $e$ into r; + raise info 'r = %', r; + end; +$$ +-- +STMT: DoStmt +== 018 +-- check that <= etc. followed by more operator characters are returned +-- as the correct token with correct precedence +SELECT true<>-1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +== 019 +-- BETWEEN has prec. above <> but below Op +SELECT false<>/**/1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +== 020 +SELECT false<=-1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +== 021 +SELECT false>=-1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +== 022 +SELECT 2<=/**/3, 3>=/**/2, 2<>/**/3 +-- +STMT: SelectStmt +== 023 +SELECT 3<=/**/2, 2>=/**/3, 2<>/**/2 +-- +STMT: SelectStmt +== 024 +-- Should fail. CREATE OPERATOR requires USAGE on SCHEMA +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 025 +CREATE ROLE regress_rol_op1 +-- +STMT: CreateRoleStmt +== 026 +CREATE SCHEMA schema_op1 +-- +STMT: CreateSchemaStmt +== 027 +GRANT USAGE ON SCHEMA schema_op1 TO PUBLIC +-- +STMT: GrantStmt +== 028 +REVOKE USAGE ON SCHEMA schema_op1 FROM regress_rol_op1 +-- +STMT: GrantStmt +== 029 +SET ROLE regress_rol_op1 +-- +STMT: VariableSetStmt +== 030 +CREATE OPERATOR schema_op1.#*# ( + rightarg = int8, + procedure = factorial +) +-- +STMT: DefineStmt +== 031 +ROLLBACK +-- +STMT: TransactionStmt +== 032 +-- Should fail. SETOF type functions not allowed as argument (testing leftarg) +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 033 +CREATE OPERATOR #*# ( + leftarg = SETOF int8, + procedure = factorial +) +-- +STMT: DefineStmt +== 034 +ROLLBACK +-- +STMT: TransactionStmt +== 035 +-- Should fail. SETOF type functions not allowed as argument (testing rightarg) +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 036 +CREATE OPERATOR #*# ( + rightarg = SETOF int8, + procedure = factorial +) +-- +STMT: DefineStmt +== 037 +ROLLBACK +-- +STMT: TransactionStmt +== 038 +-- Should work. Sample text-book case +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 039 +CREATE OR REPLACE FUNCTION fn_op2(boolean, boolean) +RETURNS boolean AS $$ + SELECT NULL::BOOLEAN; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op2" function="fn_op2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 040 +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = boolean, + PROCEDURE = fn_op2, + COMMUTATOR = ===, + NEGATOR = !==, + RESTRICT = contsel, + JOIN = contjoinsel, + SORT1, SORT2, LTCMP, GTCMP, HASHES, MERGES +) +-- +STMT: DefineStmt +== 041 +ROLLBACK +-- +STMT: TransactionStmt +== 042 +-- Should fail. Invalid attribute +CREATE OPERATOR #@%# ( + rightarg = int8, + procedure = factorial, + invalid_att = int8 +) +-- +STMT: DefineStmt +== 043 +-- Should fail. At least rightarg should be mandatorily specified +CREATE OPERATOR #@%# ( + procedure = factorial +) +-- +STMT: DefineStmt +== 044 +-- Should fail. Procedure should be mandatorily specified +CREATE OPERATOR #@%# ( + rightarg = int8 +) +-- +STMT: DefineStmt +== 045 +-- Should fail. CREATE OPERATOR requires USAGE on TYPE +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 046 +CREATE ROLE regress_rol_op3 +-- +STMT: CreateRoleStmt +== 047 +CREATE TYPE type_op3 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +== 048 +CREATE FUNCTION fn_op3(type_op3, int8) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op3" function="fn_op3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 049 +REVOKE USAGE ON TYPE type_op3 FROM regress_rol_op3 +-- +STMT: GrantStmt +== 050 +REVOKE USAGE ON TYPE type_op3 FROM PUBLIC +-- +STMT: GrantStmt +== 051 +-- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC +SET ROLE regress_rol_op3 +-- +STMT: VariableSetStmt +== 052 +CREATE OPERATOR #*# ( + leftarg = type_op3, + rightarg = int8, + procedure = fn_op3 +) +-- +STMT: DefineStmt +== 053 +ROLLBACK +-- +STMT: TransactionStmt +== 054 +-- Should fail. CREATE OPERATOR requires USAGE on TYPE (need to check separately for rightarg) +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 055 +CREATE ROLE regress_rol_op4 +-- +STMT: CreateRoleStmt +== 056 +CREATE TYPE type_op4 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +== 057 +CREATE FUNCTION fn_op4(int8, type_op4) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op4" function="fn_op4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 058 +REVOKE USAGE ON TYPE type_op4 FROM regress_rol_op4 +-- +STMT: GrantStmt +== 059 +REVOKE USAGE ON TYPE type_op4 FROM PUBLIC +-- +STMT: GrantStmt +== 060 +-- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC +SET ROLE regress_rol_op4 +-- +STMT: VariableSetStmt +== 061 +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = type_op4, + procedure = fn_op4 +) +-- +STMT: DefineStmt +== 062 +ROLLBACK +-- +STMT: TransactionStmt +== 063 +-- Should fail. CREATE OPERATOR requires EXECUTE on function +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 064 +CREATE ROLE regress_rol_op5 +-- +STMT: CreateRoleStmt +== 065 +CREATE TYPE type_op5 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +== 066 +CREATE FUNCTION fn_op5(int8, int8) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op5" function="fn_op5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 067 +REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM regress_rol_op5 +-- +FUNCTION: name="fn_op5" function="fn_op5" schema="" ctx=DDL +STMT: GrantStmt +== 068 +REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM PUBLIC +-- +FUNCTION: name="fn_op5" function="fn_op5" schema="" ctx=DDL +STMT: GrantStmt +== 069 +-- Need to do this so that regress_rol_op3 is not allowed EXECUTE via PUBLIC +SET ROLE regress_rol_op5 +-- +STMT: VariableSetStmt +== 070 +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = int8, + procedure = fn_op5 +) +-- +STMT: DefineStmt +== 071 +ROLLBACK +-- +STMT: TransactionStmt +== 072 +-- Should fail. CREATE OPERATOR requires USAGE on return TYPE +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 073 +CREATE ROLE regress_rol_op6 +-- +STMT: CreateRoleStmt +== 074 +CREATE TYPE type_op6 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +== 075 +CREATE FUNCTION fn_op6(int8, int8) +RETURNS type_op6 AS $$ + SELECT NULL::type_op6; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op6" function="fn_op6" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 076 +REVOKE USAGE ON TYPE type_op6 FROM regress_rol_op6 +-- +STMT: GrantStmt +== 077 +REVOKE USAGE ON TYPE type_op6 FROM PUBLIC +-- +STMT: GrantStmt +== 078 +-- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC +SET ROLE regress_rol_op6 +-- +STMT: VariableSetStmt +== 079 +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = int8, + procedure = fn_op6 +) +-- +STMT: DefineStmt +== 080 +ROLLBACK +-- +STMT: TransactionStmt +== 081 +-- Should fail. An operator cannot be its own negator. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 082 +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + negator = === +) +-- +STMT: DefineStmt +== 083 +ROLLBACK +-- +STMT: TransactionStmt +== 084 +-- Should fail. An operator cannot be its own negator. Here we check that +-- this error is detected when replacing a shell operator. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 085 +-- create a shell operator for ===!!! by referencing it as a commutator +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + commutator = ===!!! +) +-- +STMT: DefineStmt +== 086 +CREATE OPERATOR ===!!! ( + leftarg = integer, + rightarg = integer, + procedure = int4ne, + negator = ===!!! +) +-- +STMT: DefineStmt +== 087 +ROLLBACK +-- +STMT: TransactionStmt +== 088 +-- test that we can't use part of an existing commutator or negator pair +-- as a commutator or negator +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + commutator = = +) +-- +STMT: DefineStmt +== 089 +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + negator = <> +) +-- +STMT: DefineStmt +== 090 +-- invalid: non-lowercase quoted identifiers +CREATE OPERATOR === +( + "Leftarg" = box, + "Rightarg" = box, + "Procedure" = area_equal_function, + "Commutator" = ===, + "Negator" = !==, + "Restrict" = area_restriction_function, + "Join" = area_join_function, + "Hashes", + "Merges" +) +-- +STMT: DefineStmt diff --git a/parser/testdata/summary/postgres_regress/create_procedure.metadata.json b/parser/testdata/summary/postgres_regress/create_procedure.metadata.json new file mode 100644 index 0000000..c169184 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_procedure.metadata.json @@ -0,0 +1,113 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_procedure.test b/parser/testdata/summary/postgres_regress/create_procedure.test new file mode 100644 index 0000000..b74f207 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_procedure.test @@ -0,0 +1,654 @@ +== 001 +CALL nonexistent() +-- +FUNCTION: name="nonexistent" function="nonexistent" schema="" ctx=Call +STMT: CallStmt +== 002 +-- error +CALL random() +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: CallStmt +== 003 +-- error + +CREATE FUNCTION cp_testfunc1(a int) RETURNS int LANGUAGE SQL AS $$ SELECT a $$ +-- +FUNCTION: name="cp_testfunc1" function="cp_testfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 004 +CREATE TABLE cp_test (a int, b text) +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: CreateStmt +== 005 +CREATE PROCEDURE ptest1(x text) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES (1, x); +$$ +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +SELECT pg_get_functiondef('ptest1'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- show only normal functions + +-- show only procedures + +SELECT ptest1('x') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- error +CALL ptest1('a') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +== 009 +-- ok +CALL ptest1('xy' || 'zzy') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +== 010 +-- ok, constant-folded arg +CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1)) +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +FUNCTION: name="substring" function="substring" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: CallStmt +== 011 +-- ok, volatile arg + +SELECT * FROM cp_test ORDER BY b COLLATE "C" +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +== 012 +-- SQL-standard body +CREATE PROCEDURE ptest1s(x text) +LANGUAGE SQL +BEGIN ATOMIC + INSERT INTO cp_test VALUES (1, x) +-- +ERROR: syntax error at end of input +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 013 +END +-- +STMT: TransactionStmt +== 014 +SELECT pg_get_functiondef('ptest1s'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 015 +CALL ptest1s('b') +-- +FUNCTION: name="ptest1s" function="ptest1s" schema="" ctx=Call +STMT: CallStmt +== 016 +SELECT * FROM cp_test ORDER BY b COLLATE "C" +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +== 017 +-- utility functions currently not supported here +CREATE PROCEDURE ptestx() +LANGUAGE SQL +BEGIN ATOMIC + CREATE TABLE x (a int) +-- +ERROR: syntax error at end of input +CURSORPOS: 127 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 018 +END +-- +STMT: TransactionStmt +== 019 +CREATE PROCEDURE ptest2() +LANGUAGE SQL +AS $$ +SELECT 5; +$$ +-- +FUNCTION: name="ptest2" function="ptest2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 020 +CALL ptest2() +-- +FUNCTION: name="ptest2" function="ptest2" schema="" ctx=Call +STMT: CallStmt +== 021 +-- nested CALL +TRUNCATE cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: TruncateStmt +== 022 +CREATE PROCEDURE ptest3(y text) +LANGUAGE SQL +AS $$ +CALL ptest1(y); +CALL ptest1($1); +$$ +-- +FUNCTION: name="ptest3" function="ptest3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 023 +CALL ptest3('b') +-- +FUNCTION: name="ptest3" function="ptest3" schema="" ctx=Call +STMT: CallStmt +== 024 +SELECT * FROM cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +== 025 +-- output arguments + +CREATE PROCEDURE ptest4a(INOUT a int, INOUT b int) +LANGUAGE SQL +AS $$ +SELECT 1, 2; +$$ +-- +FUNCTION: name="ptest4a" function="ptest4a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 026 +CALL ptest4a(NULL, NULL) +-- +FUNCTION: name="ptest4a" function="ptest4a" schema="" ctx=Call +STMT: CallStmt +== 027 +CREATE PROCEDURE ptest4b(INOUT b int, INOUT a int) +LANGUAGE SQL +AS $$ +CALL ptest4a(a, b); -- error, not supported +$$ +-- +FUNCTION: name="ptest4b" function="ptest4b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 028 +-- we used to get confused by a single output argument that is composite +CREATE PROCEDURE ptest4c(INOUT comp int8_tbl) +LANGUAGE SQL +AS $$ +SELECT ROW(1, 2); +$$ +-- +FUNCTION: name="ptest4c" function="ptest4c" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +CALL ptest4c(NULL) +-- +FUNCTION: name="ptest4c" function="ptest4c" schema="" ctx=Call +STMT: CallStmt +== 030 +DROP PROCEDURE ptest4a, ptest4c +-- +STMT: DropStmt +== 031 +-- named and default parameters + +CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int default 100) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES(a, b); +INSERT INTO cp_test VALUES(c, b); +$$ +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +TRUNCATE cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: TruncateStmt +== 033 +CALL ptest5(10, 'Hello', 20) +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +== 034 +CALL ptest5(10, 'Hello') +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +== 035 +CALL ptest5(10, b => 'Hello') +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +== 036 +CALL ptest5(b => 'Hello', a => 10) +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +== 037 +SELECT * FROM cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +== 038 +-- polymorphic types + +CREATE PROCEDURE ptest6(a int, b anyelement) +LANGUAGE SQL +AS $$ +SELECT NULL::int; +$$ +-- +FUNCTION: name="ptest6" function="ptest6" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 039 +CALL ptest6(1, 2) +-- +FUNCTION: name="ptest6" function="ptest6" schema="" ctx=Call +STMT: CallStmt +== 040 +CREATE PROCEDURE ptest6a(inout a anyelement, out b anyelement) +LANGUAGE SQL +AS $$ +SELECT $1, $1; +$$ +-- +FUNCTION: name="ptest6a" function="ptest6a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 041 +CALL ptest6a(1, null) +-- +FUNCTION: name="ptest6a" function="ptest6a" schema="" ctx=Call +STMT: CallStmt +== 042 +CALL ptest6a(1.1, null) +-- +FUNCTION: name="ptest6a" function="ptest6a" schema="" ctx=Call +STMT: CallStmt +== 043 +CREATE PROCEDURE ptest6b(a anyelement, out b anyelement, out c anyarray) +LANGUAGE SQL +AS $$ +SELECT $1, array[$1]; +$$ +-- +FUNCTION: name="ptest6b" function="ptest6b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 044 +CALL ptest6b(1, null, null) +-- +FUNCTION: name="ptest6b" function="ptest6b" schema="" ctx=Call +STMT: CallStmt +== 045 +CALL ptest6b(1.1, null, null) +-- +FUNCTION: name="ptest6b" function="ptest6b" schema="" ctx=Call +STMT: CallStmt +== 046 +CREATE PROCEDURE ptest6c(inout a anyelement, inout b anyelement) +LANGUAGE SQL +AS $$ +SELECT $1, 1; +$$ +-- +FUNCTION: name="ptest6c" function="ptest6c" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 047 +CALL ptest6c(1, null) +-- +FUNCTION: name="ptest6c" function="ptest6c" schema="" ctx=Call +STMT: CallStmt +== 048 +CALL ptest6c(1.1, null) +-- +FUNCTION: name="ptest6c" function="ptest6c" schema="" ctx=Call +STMT: CallStmt +== 049 +-- fails before v13 + + +-- collation assignment + +CREATE PROCEDURE ptest7(a text, b text) +LANGUAGE SQL +AS $$ +SELECT a = b; +$$ +-- +FUNCTION: name="ptest7" function="ptest7" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 050 +CALL ptest7(least('a', 'b'), 'a') +-- +FUNCTION: name="ptest7" function="ptest7" schema="" ctx=Call +STMT: CallStmt +== 051 +-- empty body +CREATE PROCEDURE ptest8(x text) +BEGIN ATOMIC +END +-- +FUNCTION: name="ptest8" function="ptest8" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 052 +SELECT pg_get_functiondef('ptest8'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 053 +CALL ptest8('') +-- +FUNCTION: name="ptest8" function="ptest8" schema="" ctx=Call +STMT: CallStmt +== 054 +-- OUT parameters + +CREATE PROCEDURE ptest9(OUT a int) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES (1, 'a'); +SELECT 1; +$$ +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 055 +-- standard way to do a call: +CALL ptest9(NULL) +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=Call +STMT: CallStmt +== 056 +-- you can write an expression, but it's not evaluated +CALL ptest9(1/0) +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=Call +STMT: CallStmt +== 057 +-- no error +-- ... and it had better match the type of the parameter +CALL ptest9(1./0.) +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=Call +STMT: CallStmt +== 058 +-- error + +-- check named-parameter matching +CREATE PROCEDURE ptest10(OUT a int, IN b int, IN c int) +LANGUAGE SQL AS $$ SELECT b - c $$ +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 059 +CALL ptest10(null, 7, 4) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +== 060 +CALL ptest10(a => null, b => 8, c => 2) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +== 061 +CALL ptest10(null, 7, c => 2) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +== 062 +CALL ptest10(null, c => 4, b => 11) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +== 063 +CALL ptest10(b => 8, c => 2, a => 0) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +== 064 +CREATE PROCEDURE ptest11(a OUT int, VARIADIC b int[]) LANGUAGE SQL + AS $$ SELECT b[1] + b[2] $$ +-- +FUNCTION: name="ptest11" function="ptest11" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 065 +CALL ptest11(null, 11, 12, 13) +-- +FUNCTION: name="ptest11" function="ptest11" schema="" ctx=Call +STMT: CallStmt +== 066 +-- check resolution of ambiguous DROP commands + +CREATE PROCEDURE ptest10(IN a int, IN b int, IN c int) +LANGUAGE SQL AS $$ SELECT a + b - c $$ +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 067 +drop procedure ptest10 +-- +STMT: DropStmt +== 068 +-- fail +drop procedure ptest10(int, int, int) +-- +STMT: DropStmt +== 069 +-- fail +begin +-- +STMT: TransactionStmt +== 070 +drop procedure ptest10(out int, int, int) +-- +STMT: DropStmt +== 071 +drop procedure ptest10(int, int, int) +-- +STMT: DropStmt +== 072 +-- now this would work +rollback +-- +STMT: TransactionStmt +== 073 +begin +-- +STMT: TransactionStmt +== 074 +drop procedure ptest10(in int, int, int) +-- +STMT: DropStmt +== 075 +drop procedure ptest10(int, int, int) +-- +STMT: DropStmt +== 076 +-- now this would work +rollback +-- +STMT: TransactionStmt +== 077 +-- various error cases + +CALL version() +-- +FUNCTION: name="version" function="version" schema="" ctx=Call +STMT: CallStmt +== 078 +-- error: not a procedure +CALL sum(1) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CallStmt +== 079 +-- error: not a procedure + +CREATE PROCEDURE ptestx() LANGUAGE SQL WINDOW AS $$ INSERT INTO cp_test VALUES (1, 'a') $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 080 +CREATE PROCEDURE ptestx() LANGUAGE SQL STRICT AS $$ INSERT INTO cp_test VALUES (1, 'a') $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 081 +CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAGE SQL + AS $$ SELECT a[1] $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 082 +CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAGE SQL + AS $$ SELECT a $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 083 +ALTER PROCEDURE ptest1(text) STRICT +-- +STMT: AlterFunctionStmt +== 084 +ALTER FUNCTION ptest1(text) VOLATILE +-- +STMT: AlterFunctionStmt +== 085 +-- error: not a function +ALTER PROCEDURE cp_testfunc1(int) VOLATILE +-- +STMT: AlterFunctionStmt +== 086 +-- error: not a procedure +ALTER PROCEDURE nonexistent() VOLATILE +-- +STMT: AlterFunctionStmt +== 087 +DROP FUNCTION ptest1(text) +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: DropStmt +== 088 +-- error: not a function +DROP PROCEDURE cp_testfunc1(int) +-- +STMT: DropStmt +== 089 +-- error: not a procedure +DROP PROCEDURE nonexistent() +-- +STMT: DropStmt +== 090 +-- privileges + +CREATE USER regress_cp_user1 +-- +STMT: CreateRoleStmt +== 091 +GRANT INSERT ON cp_test TO regress_cp_user1 +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: GrantStmt +== 092 +REVOKE EXECUTE ON PROCEDURE ptest1(text) FROM PUBLIC +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: GrantStmt +== 093 +SET ROLE regress_cp_user1 +-- +STMT: VariableSetStmt +== 094 +CALL ptest1('a') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +== 095 +-- error +RESET ROLE +-- +STMT: VariableSetStmt +== 096 +GRANT EXECUTE ON PROCEDURE ptest1(text) TO regress_cp_user1 +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: GrantStmt +== 097 +SET ROLE regress_cp_user1 +-- +STMT: VariableSetStmt +== 098 +CALL ptest1('a') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +== 099 +-- ok +RESET ROLE +-- +STMT: VariableSetStmt +== 100 +-- ROUTINE syntax + +ALTER ROUTINE cp_testfunc1(int) RENAME TO cp_testfunc1a +-- +FUNCTION: name="cp_testfunc1" function="cp_testfunc1" schema="" ctx=DDL +FUNCTION: name="cp_testfunc1a" function="cp_testfunc1a" schema="" ctx=DDL +STMT: RenameStmt +== 101 +ALTER ROUTINE cp_testfunc1a RENAME TO cp_testfunc1 +-- +FUNCTION: name="cp_testfunc1a" function="cp_testfunc1a" schema="" ctx=DDL +FUNCTION: name="cp_testfunc1" function="cp_testfunc1" schema="" ctx=DDL +STMT: RenameStmt +== 102 +ALTER ROUTINE ptest1(text) RENAME TO ptest1a +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +FUNCTION: name="ptest1a" function="ptest1a" schema="" ctx=DDL +STMT: RenameStmt +== 103 +ALTER ROUTINE ptest1a RENAME TO ptest1 +-- +FUNCTION: name="ptest1a" function="ptest1a" schema="" ctx=DDL +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: RenameStmt +== 104 +DROP ROUTINE cp_testfunc1(int) +-- +STMT: DropStmt +== 105 +-- cleanup + +DROP PROCEDURE ptest1 +-- +STMT: DropStmt +== 106 +DROP PROCEDURE ptest1s +-- +STMT: DropStmt +== 107 +DROP PROCEDURE ptest2 +-- +STMT: DropStmt +== 108 +DROP TABLE cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: DropStmt +== 109 +DROP USER regress_cp_user1 +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/create_role.metadata.json b/parser/testdata/summary/postgres_regress/create_role.metadata.json new file mode 100644 index 0000000..6835d4b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_role.metadata.json @@ -0,0 +1,141 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_role.test b/parser/testdata/summary/postgres_regress/create_role.test new file mode 100644 index 0000000..5438158 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_role.test @@ -0,0 +1,609 @@ +== 001 +-- ok, superuser can create users with any set of privileges +CREATE ROLE regress_role_super SUPERUSER +-- +STMT: CreateRoleStmt +== 002 +CREATE ROLE regress_role_admin CREATEDB CREATEROLE REPLICATION BYPASSRLS +-- +STMT: CreateRoleStmt +== 003 +GRANT CREATE ON DATABASE regression TO regress_role_admin WITH GRANT OPTION +-- +STMT: GrantStmt +== 004 +CREATE ROLE regress_role_limited_admin CREATEROLE +-- +STMT: CreateRoleStmt +== 005 +CREATE ROLE regress_role_normal +-- +STMT: CreateRoleStmt +== 006 +-- fail, CREATEROLE user can't give away role attributes without having them +SET SESSION AUTHORIZATION regress_role_limited_admin +-- +STMT: VariableSetStmt +== 007 +CREATE ROLE regress_nosuch_superuser SUPERUSER +-- +STMT: CreateRoleStmt +== 008 +CREATE ROLE regress_nosuch_replication_bypassrls REPLICATION BYPASSRLS +-- +STMT: CreateRoleStmt +== 009 +CREATE ROLE regress_nosuch_replication REPLICATION +-- +STMT: CreateRoleStmt +== 010 +CREATE ROLE regress_nosuch_bypassrls BYPASSRLS +-- +STMT: CreateRoleStmt +== 011 +CREATE ROLE regress_nosuch_createdb CREATEDB +-- +STMT: CreateRoleStmt +== 012 +-- ok, can create a role without any special attributes +CREATE ROLE regress_role_limited +-- +STMT: CreateRoleStmt +== 013 +-- fail, can't give it in any of the restricted attributes +ALTER ROLE regress_role_limited SUPERUSER +-- +STMT: AlterRoleStmt +== 014 +ALTER ROLE regress_role_limited REPLICATION +-- +STMT: AlterRoleStmt +== 015 +ALTER ROLE regress_role_limited CREATEDB +-- +STMT: AlterRoleStmt +== 016 +ALTER ROLE regress_role_limited BYPASSRLS +-- +STMT: AlterRoleStmt +== 017 +DROP ROLE regress_role_limited +-- +STMT: DropRoleStmt +== 018 +-- ok, can give away these role attributes if you have them +SET SESSION AUTHORIZATION regress_role_admin +-- +STMT: VariableSetStmt +== 019 +CREATE ROLE regress_replication_bypassrls REPLICATION BYPASSRLS +-- +STMT: CreateRoleStmt +== 020 +CREATE ROLE regress_replication REPLICATION +-- +STMT: CreateRoleStmt +== 021 +CREATE ROLE regress_bypassrls BYPASSRLS +-- +STMT: CreateRoleStmt +== 022 +CREATE ROLE regress_createdb CREATEDB +-- +STMT: CreateRoleStmt +== 023 +-- ok, can toggle these role attributes off and on if you have them +ALTER ROLE regress_replication NOREPLICATION +-- +STMT: AlterRoleStmt +== 024 +ALTER ROLE regress_replication REPLICATION +-- +STMT: AlterRoleStmt +== 025 +ALTER ROLE regress_bypassrls NOBYPASSRLS +-- +STMT: AlterRoleStmt +== 026 +ALTER ROLE regress_bypassrls BYPASSRLS +-- +STMT: AlterRoleStmt +== 027 +ALTER ROLE regress_createdb NOCREATEDB +-- +STMT: AlterRoleStmt +== 028 +ALTER ROLE regress_createdb CREATEDB +-- +STMT: AlterRoleStmt +== 029 +-- fail, can't toggle SUPERUSER +ALTER ROLE regress_createdb SUPERUSER +-- +STMT: AlterRoleStmt +== 030 +ALTER ROLE regress_createdb NOSUPERUSER +-- +STMT: AlterRoleStmt +== 031 +-- ok, having CREATEROLE is enough to create users with these privileges +CREATE ROLE regress_createrole CREATEROLE NOINHERIT +-- +STMT: CreateRoleStmt +== 032 +GRANT CREATE ON DATABASE regression TO regress_createrole WITH GRANT OPTION +-- +STMT: GrantStmt +== 033 +CREATE ROLE regress_login LOGIN +-- +STMT: CreateRoleStmt +== 034 +CREATE ROLE regress_inherit INHERIT +-- +STMT: CreateRoleStmt +== 035 +CREATE ROLE regress_connection_limit CONNECTION LIMIT 5 +-- +STMT: CreateRoleStmt +== 036 +CREATE ROLE regress_encrypted_password ENCRYPTED PASSWORD 'foo' +-- +STMT: CreateRoleStmt +== 037 +CREATE ROLE regress_password_null PASSWORD NULL +-- +STMT: CreateRoleStmt +== 038 +-- ok, backwards compatible noise words should be ignored +CREATE ROLE regress_noiseword SYSID 12345 +-- +STMT: CreateRoleStmt +== 039 +-- fail, cannot grant membership in superuser role +CREATE ROLE regress_nosuch_super IN ROLE regress_role_super +-- +STMT: CreateRoleStmt +== 040 +-- fail, database owner cannot have members +CREATE ROLE regress_nosuch_dbowner IN ROLE pg_database_owner +-- +STMT: CreateRoleStmt +== 041 +-- ok, can grant other users into a role +CREATE ROLE regress_inroles ROLE + regress_role_super, regress_createdb, regress_createrole, regress_login, + regress_inherit, regress_connection_limit, regress_encrypted_password, regress_password_null +-- +STMT: CreateRoleStmt +== 042 +-- fail, cannot grant a role into itself +CREATE ROLE regress_nosuch_recursive ROLE regress_nosuch_recursive +-- +STMT: CreateRoleStmt +== 043 +-- ok, can grant other users into a role with admin option +CREATE ROLE regress_adminroles ADMIN + regress_role_super, regress_createdb, regress_createrole, regress_login, + regress_inherit, regress_connection_limit, regress_encrypted_password, regress_password_null +-- +STMT: CreateRoleStmt +== 044 +-- fail, cannot grant a role into itself with admin option +CREATE ROLE regress_nosuch_admin_recursive ADMIN regress_nosuch_admin_recursive +-- +STMT: CreateRoleStmt +== 045 +-- fail, regress_createrole does not have CREATEDB privilege +SET SESSION AUTHORIZATION regress_createrole +-- +STMT: VariableSetStmt +== 046 +CREATE DATABASE regress_nosuch_db +-- +STMT: CreatedbStmt +== 047 +-- ok, regress_createrole can create new roles +CREATE ROLE regress_plainrole +-- +STMT: CreateRoleStmt +== 048 +-- ok, roles with CREATEROLE can create new roles with it +CREATE ROLE regress_rolecreator CREATEROLE +-- +STMT: CreateRoleStmt +== 049 +-- ok, roles with CREATEROLE can create new roles with different role +-- attributes, including CREATEROLE +CREATE ROLE regress_hasprivs CREATEROLE LOGIN INHERIT CONNECTION LIMIT 5 +-- +STMT: CreateRoleStmt +== 050 +-- ok, we should be able to modify a role we created +COMMENT ON ROLE regress_hasprivs IS 'some comment' +-- +STMT: CommentStmt +== 051 +ALTER ROLE regress_hasprivs RENAME TO regress_tenant +-- +STMT: RenameStmt +== 052 +ALTER ROLE regress_tenant NOINHERIT NOLOGIN CONNECTION LIMIT 7 +-- +STMT: AlterRoleStmt +== 053 +-- fail, we should be unable to modify a role we did not create +COMMENT ON ROLE regress_role_normal IS 'some comment' +-- +STMT: CommentStmt +== 054 +ALTER ROLE regress_role_normal RENAME TO regress_role_abnormal +-- +STMT: RenameStmt +== 055 +ALTER ROLE regress_role_normal NOINHERIT NOLOGIN CONNECTION LIMIT 7 +-- +STMT: AlterRoleStmt +== 056 +-- ok, regress_tenant can create objects within the database +SET SESSION AUTHORIZATION regress_tenant +-- +STMT: VariableSetStmt +== 057 +CREATE TABLE tenant_table (i integer) +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: CreateStmt +== 058 +CREATE INDEX tenant_idx ON tenant_table(i) +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: IndexStmt +== 059 +CREATE VIEW tenant_view AS SELECT * FROM pg_catalog.pg_class +-- +TABLE: name="tenant_view" schema="" table="tenant_view" ctx=DDL +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 060 +REVOKE ALL PRIVILEGES ON tenant_table FROM PUBLIC +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: GrantStmt +== 061 +-- fail, these objects belonging to regress_tenant +SET SESSION AUTHORIZATION regress_createrole +-- +STMT: VariableSetStmt +== 062 +DROP INDEX tenant_idx +-- +STMT: DropStmt +== 063 +ALTER TABLE tenant_table ADD COLUMN t text +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: AlterTableStmt +== 064 +DROP TABLE tenant_table +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: DropStmt +== 065 +ALTER VIEW tenant_view OWNER TO regress_role_admin +-- +TABLE: name="tenant_view" schema="" table="tenant_view" ctx=DDL +STMT: AlterTableStmt +== 066 +DROP VIEW tenant_view +-- +STMT: DropStmt +== 067 +-- fail, can't create objects owned as regress_tenant +CREATE SCHEMA regress_tenant_schema AUTHORIZATION regress_tenant +-- +STMT: CreateSchemaStmt +== 068 +-- fail, we don't inherit permissions from regress_tenant +REASSIGN OWNED BY regress_tenant TO regress_createrole +-- +STMT: ReassignOwnedStmt +== 069 +-- ok, create a role with a value for createrole_self_grant +SET createrole_self_grant = 'set, inherit' +-- +STMT: VariableSetStmt +== 070 +CREATE ROLE regress_tenant2 +-- +STMT: CreateRoleStmt +== 071 +GRANT CREATE ON DATABASE regression TO regress_tenant2 +-- +STMT: GrantStmt +== 072 +-- ok, regress_tenant2 can create objects within the database +SET SESSION AUTHORIZATION regress_tenant2 +-- +STMT: VariableSetStmt +== 073 +CREATE TABLE tenant2_table (i integer) +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: CreateStmt +== 074 +REVOKE ALL PRIVILEGES ON tenant2_table FROM PUBLIC +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: GrantStmt +== 075 +-- ok, because we have SET and INHERIT on regress_tenant2 +SET SESSION AUTHORIZATION regress_createrole +-- +STMT: VariableSetStmt +== 076 +CREATE SCHEMA regress_tenant2_schema AUTHORIZATION regress_tenant2 +-- +STMT: CreateSchemaStmt +== 077 +ALTER SCHEMA regress_tenant2_schema OWNER TO regress_createrole +-- +STMT: AlterOwnerStmt +== 078 +ALTER TABLE tenant2_table OWNER TO regress_createrole +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +== 079 +ALTER TABLE tenant2_table OWNER TO regress_tenant2 +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +== 080 +-- with SET but not INHERIT, we can give away objects but not take them +REVOKE INHERIT OPTION FOR regress_tenant2 FROM regress_createrole +-- +STMT: GrantRoleStmt +== 081 +ALTER SCHEMA regress_tenant2_schema OWNER TO regress_tenant2 +-- +STMT: AlterOwnerStmt +== 082 +ALTER TABLE tenant2_table OWNER TO regress_createrole +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +== 083 +-- with INHERIT but not SET, we can take objects but not give them away +GRANT regress_tenant2 TO regress_createrole WITH INHERIT TRUE, SET FALSE +-- +STMT: GrantRoleStmt +== 084 +ALTER TABLE tenant2_table OWNER TO regress_createrole +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +== 085 +ALTER TABLE tenant2_table OWNER TO regress_tenant2 +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +== 086 +DROP TABLE tenant2_table +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: DropStmt +== 087 +-- fail, CREATEROLE is not enough to create roles in privileged roles +CREATE ROLE regress_read_all_data IN ROLE pg_read_all_data +-- +STMT: CreateRoleStmt +== 088 +CREATE ROLE regress_write_all_data IN ROLE pg_write_all_data +-- +STMT: CreateRoleStmt +== 089 +CREATE ROLE regress_monitor IN ROLE pg_monitor +-- +STMT: CreateRoleStmt +== 090 +CREATE ROLE regress_read_all_settings IN ROLE pg_read_all_settings +-- +STMT: CreateRoleStmt +== 091 +CREATE ROLE regress_read_all_stats IN ROLE pg_read_all_stats +-- +STMT: CreateRoleStmt +== 092 +CREATE ROLE regress_stat_scan_tables IN ROLE pg_stat_scan_tables +-- +STMT: CreateRoleStmt +== 093 +CREATE ROLE regress_read_server_files IN ROLE pg_read_server_files +-- +STMT: CreateRoleStmt +== 094 +CREATE ROLE regress_write_server_files IN ROLE pg_write_server_files +-- +STMT: CreateRoleStmt +== 095 +CREATE ROLE regress_execute_server_program IN ROLE pg_execute_server_program +-- +STMT: CreateRoleStmt +== 096 +CREATE ROLE regress_signal_backend IN ROLE pg_signal_backend +-- +STMT: CreateRoleStmt +== 097 +-- fail, role still owns database objects +DROP ROLE regress_tenant +-- +STMT: DropRoleStmt +== 098 +-- fail, creation of these roles failed above so they do not now exist +SET SESSION AUTHORIZATION regress_role_admin +-- +STMT: VariableSetStmt +== 099 +DROP ROLE regress_nosuch_superuser +-- +STMT: DropRoleStmt +== 100 +DROP ROLE regress_nosuch_replication_bypassrls +-- +STMT: DropRoleStmt +== 101 +DROP ROLE regress_nosuch_replication +-- +STMT: DropRoleStmt +== 102 +DROP ROLE regress_nosuch_bypassrls +-- +STMT: DropRoleStmt +== 103 +DROP ROLE regress_nosuch_super +-- +STMT: DropRoleStmt +== 104 +DROP ROLE regress_nosuch_dbowner +-- +STMT: DropRoleStmt +== 105 +DROP ROLE regress_nosuch_recursive +-- +STMT: DropRoleStmt +== 106 +DROP ROLE regress_nosuch_admin_recursive +-- +STMT: DropRoleStmt +== 107 +DROP ROLE regress_plainrole +-- +STMT: DropRoleStmt +== 108 +-- must revoke privileges before dropping role +REVOKE CREATE ON DATABASE regression FROM regress_createrole CASCADE +-- +STMT: GrantStmt +== 109 +-- ok, should be able to drop non-superuser roles we created +DROP ROLE regress_replication_bypassrls +-- +STMT: DropRoleStmt +== 110 +DROP ROLE regress_replication +-- +STMT: DropRoleStmt +== 111 +DROP ROLE regress_bypassrls +-- +STMT: DropRoleStmt +== 112 +DROP ROLE regress_createdb +-- +STMT: DropRoleStmt +== 113 +DROP ROLE regress_createrole +-- +STMT: DropRoleStmt +== 114 +DROP ROLE regress_login +-- +STMT: DropRoleStmt +== 115 +DROP ROLE regress_inherit +-- +STMT: DropRoleStmt +== 116 +DROP ROLE regress_connection_limit +-- +STMT: DropRoleStmt +== 117 +DROP ROLE regress_encrypted_password +-- +STMT: DropRoleStmt +== 118 +DROP ROLE regress_password_null +-- +STMT: DropRoleStmt +== 119 +DROP ROLE regress_noiseword +-- +STMT: DropRoleStmt +== 120 +DROP ROLE regress_inroles +-- +STMT: DropRoleStmt +== 121 +DROP ROLE regress_adminroles +-- +STMT: DropRoleStmt +== 122 +-- fail, cannot drop ourself, nor superusers or roles we lack ADMIN for +DROP ROLE regress_role_super +-- +STMT: DropRoleStmt +== 123 +DROP ROLE regress_role_admin +-- +STMT: DropRoleStmt +== 124 +DROP ROLE regress_rolecreator +-- +STMT: DropRoleStmt +== 125 +-- ok +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 126 +REVOKE CREATE ON DATABASE regression FROM regress_role_admin CASCADE +-- +STMT: GrantStmt +== 127 +DROP INDEX tenant_idx +-- +STMT: DropStmt +== 128 +DROP TABLE tenant_table +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: DropStmt +== 129 +DROP VIEW tenant_view +-- +STMT: DropStmt +== 130 +DROP SCHEMA regress_tenant2_schema +-- +STMT: DropStmt +== 131 +-- check for duplicated drop +DROP ROLE regress_tenant, regress_tenant +-- +STMT: DropRoleStmt +== 132 +DROP ROLE regress_tenant2 +-- +STMT: DropRoleStmt +== 133 +DROP ROLE regress_rolecreator +-- +STMT: DropRoleStmt +== 134 +DROP ROLE regress_role_admin +-- +STMT: DropRoleStmt +== 135 +DROP ROLE regress_role_limited_admin +-- +STMT: DropRoleStmt +== 136 +DROP ROLE regress_role_super +-- +STMT: DropRoleStmt +== 137 +DROP ROLE regress_role_normal +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/create_schema.metadata.json b/parser/testdata/summary/postgres_regress/create_schema.metadata.json new file mode 100644 index 0000000..7249d3a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_schema.metadata.json @@ -0,0 +1,31 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_schema.test b/parser/testdata/summary/postgres_regress/create_schema.test new file mode 100644 index 0000000..334bdba --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_schema.test @@ -0,0 +1,145 @@ +== 001 +|-- +-- CREATE_SCHEMA +|-- + +-- Schema creation with elements. + +CREATE ROLE regress_create_schema_role SUPERUSER +-- +STMT: CreateRoleStmt +== 002 +-- Cases where schema creation fails as objects are qualified with a schema +-- that does not match with what's expected. +-- This checks all the object types that include schema qualifications. +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE SEQUENCE schema_not_existing.seq +-- +STMT: CreateSchemaStmt +== 003 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE TABLE schema_not_existing.tab (id int) +-- +STMT: CreateSchemaStmt +== 004 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE VIEW schema_not_existing.view AS SELECT 1 +-- +STMT: CreateSchemaStmt +== 005 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE INDEX ON schema_not_existing.tab (id) +-- +STMT: CreateSchemaStmt +== 006 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func() +-- +STMT: CreateSchemaStmt +== 007 +-- Again, with a role specification and no schema names. +SET ROLE regress_create_schema_role +-- +STMT: VariableSetStmt +== 008 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE SEQUENCE schema_not_existing.seq +-- +STMT: CreateSchemaStmt +== 009 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE TABLE schema_not_existing.tab (id int) +-- +STMT: CreateSchemaStmt +== 010 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE VIEW schema_not_existing.view AS SELECT 1 +-- +STMT: CreateSchemaStmt +== 011 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE INDEX ON schema_not_existing.tab (id) +-- +STMT: CreateSchemaStmt +== 012 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func() +-- +STMT: CreateSchemaStmt +== 013 +-- Again, with a schema name and a role specification. +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE SEQUENCE schema_not_existing.seq +-- +STMT: CreateSchemaStmt +== 014 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE TABLE schema_not_existing.tab (id int) +-- +STMT: CreateSchemaStmt +== 015 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE VIEW schema_not_existing.view AS SELECT 1 +-- +STMT: CreateSchemaStmt +== 016 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE INDEX ON schema_not_existing.tab (id) +-- +STMT: CreateSchemaStmt +== 017 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func() +-- +STMT: CreateSchemaStmt +== 018 +RESET ROLE +-- +STMT: VariableSetStmt +== 019 +-- Cases where the schema creation succeeds. +-- The schema created matches the role name. +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE TABLE regress_create_schema_role.tab (id int) +-- +STMT: CreateSchemaStmt +== 020 +DROP SCHEMA regress_create_schema_role CASCADE +-- +STMT: DropStmt +== 021 +-- Again, with a different role specification and no schema names. +SET ROLE regress_create_schema_role +-- +STMT: VariableSetStmt +== 022 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE TABLE regress_create_schema_role.tab (id int) +-- +STMT: CreateSchemaStmt +== 023 +DROP SCHEMA regress_create_schema_role CASCADE +-- +STMT: DropStmt +== 024 +-- Again, with a schema name and a role specification. +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE TABLE regress_schema_1.tab (id int) +-- +STMT: CreateSchemaStmt +== 025 +DROP SCHEMA regress_schema_1 CASCADE +-- +STMT: DropStmt +== 026 +RESET ROLE +-- +STMT: VariableSetStmt +== 027 +-- Clean up +DROP ROLE regress_create_schema_role +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/create_table.metadata.json b/parser/testdata/summary/postgres_regress/create_table.metadata.json new file mode 100644 index 0000000..f382372 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_table.metadata.json @@ -0,0 +1,330 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_table.test b/parser/testdata/summary/postgres_regress/create_table.test new file mode 100644 index 0000000..f93e160 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_table.test @@ -0,0 +1,1980 @@ +== 001 +|-- +-- CREATE_TABLE +|-- + +-- Error cases +CREATE TABLE unknowntab ( + u unknown -- fail +) +-- +TABLE: name="unknowntab" schema="" table="unknowntab" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TYPE unknown_comptype AS ( + u unknown -- fail +) +-- +STMT: CompositeTypeStmt +== 003 +-- invalid: non-lowercase quoted reloptions identifiers +CREATE TABLE tas_case WITH ("Fillfactor" = 10) AS SELECT 1 a +-- +TABLE: name="tas_case" schema="" table="tas_case" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 004 +CREATE UNLOGGED TABLE unlogged1 (a int primary key) +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: CreateStmt +== 005 +-- OK +CREATE TEMPORARY TABLE unlogged2 (a int primary key) +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: CreateStmt +== 006 +-- OK +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 007 +REINDEX INDEX unlogged1_pkey +-- +STMT: ReindexStmt +== 008 +REINDEX INDEX unlogged2_pkey +-- +STMT: ReindexStmt +== 009 +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 010 +DROP TABLE unlogged2 +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: DropStmt +== 011 +INSERT INTO unlogged1 VALUES (42) +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +CREATE UNLOGGED TABLE public.unlogged2 (a int primary key) +-- +TABLE: name="public.unlogged2" schema="public" table="unlogged2" ctx=DDL +STMT: CreateStmt +== 013 +-- also OK +CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int primary key) +-- +TABLE: name="pg_temp.unlogged3" schema="pg_temp" table="unlogged3" ctx=DDL +STMT: CreateStmt +== 014 +-- not OK +CREATE TABLE pg_temp.implicitly_temp (a int primary key) +-- +TABLE: name="pg_temp.implicitly_temp" schema="pg_temp" table="implicitly_temp" ctx=DDL +STMT: CreateStmt +== 015 +-- OK +CREATE TEMP TABLE explicitly_temp (a int primary key) +-- +TABLE: name="explicitly_temp" schema="" table="explicitly_temp" ctx=DDL +STMT: CreateStmt +== 016 +-- also OK +CREATE TEMP TABLE pg_temp.doubly_temp (a int primary key) +-- +TABLE: name="pg_temp.doubly_temp" schema="pg_temp" table="doubly_temp" ctx=DDL +STMT: CreateStmt +== 017 +-- also OK +CREATE TEMP TABLE public.temp_to_perm (a int primary key) +-- +TABLE: name="public.temp_to_perm" schema="public" table="temp_to_perm" ctx=DDL +STMT: CreateStmt +== 018 +-- not OK +DROP TABLE unlogged1, public.unlogged2 +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +TABLE: name="public.unlogged2" schema="public" table="unlogged2" ctx=DDL +STMT: DropStmt +== 019 +CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r' +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 020 +CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r' +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 021 +CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r' +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 022 +DROP TABLE as_select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: DropStmt +== 023 +PREPARE select1 AS SELECT 1 as a +-- +STMT: PrepareStmt +STMT: SelectStmt +== 024 +CREATE TABLE as_select1 AS EXECUTE select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 025 +CREATE TABLE as_select1 AS EXECUTE select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 026 +SELECT * FROM as_select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=Select +STMT: SelectStmt +== 027 +CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 028 +DROP TABLE as_select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: DropStmt +== 029 +DEALLOCATE select1 +-- +STMT: DeallocateStmt +== 030 +-- create an extra wide table to test for issues related to that +-- (temporarily hide query, to avoid the long CREATE TABLE stmt) +SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);' +FROM generate_series(1, 1100) g(i) +INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col') +-- +ERROR: syntax error at or near "INSERT" +CURSORPOS: 287 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 031 +SELECT firstc, lastc FROM extra_wide_table +-- +TABLE: name="extra_wide_table" schema="" table="extra_wide_table" ctx=Select +STMT: SelectStmt +== 032 +-- check that tables with oids cannot be created anymore +CREATE TABLE withoid() WITH OIDS +-- +ERROR: syntax error at or near "OIDS" +CURSORPOS: 86 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 033 +CREATE TABLE withoid() WITH (oids) +-- +TABLE: name="withoid" schema="" table="withoid" ctx=DDL +STMT: CreateStmt +== 034 +CREATE TABLE withoid() WITH (oids = true) +-- +TABLE: name="withoid" schema="" table="withoid" ctx=DDL +STMT: CreateStmt +== 035 +-- but explicitly not adding oids is still supported +CREATE TEMP TABLE withoutoid() WITHOUT OIDS +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: CreateStmt +== 036 +DROP TABLE withoutoid +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: DropStmt +== 037 +CREATE TEMP TABLE withoutoid() WITH (oids = false) +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: CreateStmt +== 038 +DROP TABLE withoutoid +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: DropStmt +== 039 +-- temporary tables are ignored by pg_filenode_relation(). +CREATE TEMP TABLE relation_filenode_check(c1 int) +-- +TABLE: name="relation_filenode_check" schema="" table="relation_filenode_check" ctx=DDL +STMT: CreateStmt +== 040 +SELECT relpersistence, + pg_filenode_relation (reltablespace, pg_relation_filenode(oid)) + FROM pg_class + WHERE relname = 'relation_filenode_check' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_filenode_relation" function="pg_filenode_relation" schema="" ctx=Call +FUNCTION: name="pg_relation_filenode" function="pg_relation_filenode" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 041 +DROP TABLE relation_filenode_check +-- +TABLE: name="relation_filenode_check" schema="" table="relation_filenode_check" ctx=DDL +STMT: DropStmt +== 042 +-- check restriction with default expressions +-- invalid use of column reference in default expressions +CREATE TABLE default_expr_column (id int DEFAULT (id)) +-- +TABLE: name="default_expr_column" schema="" table="default_expr_column" ctx=DDL +STMT: CreateStmt +== 043 +CREATE TABLE default_expr_column (id int DEFAULT (bar.id)) +-- +TABLE: name="default_expr_column" schema="" table="default_expr_column" ctx=DDL +STMT: CreateStmt +== 044 +CREATE TABLE default_expr_agg_column (id int DEFAULT (avg(id))) +-- +TABLE: name="default_expr_agg_column" schema="" table="default_expr_agg_column" ctx=DDL +STMT: CreateStmt +== 045 +-- invalid column definition +CREATE TABLE default_expr_non_column (a int DEFAULT (avg(non_existent))) +-- +TABLE: name="default_expr_non_column" schema="" table="default_expr_non_column" ctx=DDL +STMT: CreateStmt +== 046 +-- invalid use of aggregate +CREATE TABLE default_expr_agg (a int DEFAULT (avg(1))) +-- +TABLE: name="default_expr_agg" schema="" table="default_expr_agg" ctx=DDL +STMT: CreateStmt +== 047 +-- invalid use of subquery +CREATE TABLE default_expr_agg (a int DEFAULT (select 1)) +-- +TABLE: name="default_expr_agg" schema="" table="default_expr_agg" ctx=DDL +STMT: CreateStmt +== 048 +-- invalid use of set-returning function +CREATE TABLE default_expr_agg (a int DEFAULT (generate_series(1,3))) +-- +TABLE: name="default_expr_agg" schema="" table="default_expr_agg" ctx=DDL +STMT: CreateStmt +== 049 +-- Verify that subtransaction rollback restores rd_createSubid. +BEGIN +-- +STMT: TransactionStmt +== 050 +CREATE TABLE remember_create_subid (c int) +-- +TABLE: name="remember_create_subid" schema="" table="remember_create_subid" ctx=DDL +STMT: CreateStmt +== 051 +SAVEPOINT q +-- +STMT: TransactionStmt +== 052 +DROP TABLE remember_create_subid +-- +TABLE: name="remember_create_subid" schema="" table="remember_create_subid" ctx=DDL +STMT: DropStmt +== 053 +ROLLBACK TO q +-- +STMT: TransactionStmt +== 054 +COMMIT +-- +STMT: TransactionStmt +== 055 +DROP TABLE remember_create_subid +-- +TABLE: name="remember_create_subid" schema="" table="remember_create_subid" ctx=DDL +STMT: DropStmt +== 056 +-- Verify that subtransaction rollback restores rd_firstRelfilenodeSubid. +CREATE TABLE remember_node_subid (c int) +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: CreateStmt +== 057 +BEGIN +-- +STMT: TransactionStmt +== 058 +ALTER TABLE remember_node_subid ALTER c TYPE bigint +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: AlterTableStmt +== 059 +SAVEPOINT q +-- +STMT: TransactionStmt +== 060 +DROP TABLE remember_node_subid +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: DropStmt +== 061 +ROLLBACK TO q +-- +STMT: TransactionStmt +== 062 +COMMIT +-- +STMT: TransactionStmt +== 063 +DROP TABLE remember_node_subid +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: DropStmt +== 064 +|-- +-- Partitioned tables +|-- + +-- cannot combine INHERITS and PARTITION BY (although grammar allows) +CREATE TABLE partitioned ( + a int +) INHERITS (some_table) PARTITION BY LIST (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 065 +-- cannot use more than 1 column as partition key for list partitioned table +CREATE TABLE partitioned ( + a1 int, + a2 int +) PARTITION BY LIST (a1, a2) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 066 +-- fail + +-- prevent using prohibited expressions in the key +CREATE FUNCTION retset (a int) RETURNS SETOF int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="retset" function="retset" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 067 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (retset(a)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 068 +DROP FUNCTION retset(int) +-- +FUNCTION: name="retset" function="retset" schema="" ctx=DDL +STMT: DropStmt +== 069 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE ((avg(a))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 070 +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 071 +CREATE TABLE partitioned ( + a int +) PARTITION BY LIST ((a LIKE (SELECT 1))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 072 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE ((42)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 073 +CREATE FUNCTION const_func () RETURNS int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="const_func" function="const_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 074 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (const_func()) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 075 +DROP FUNCTION const_func() +-- +FUNCTION: name="const_func" function="const_func" schema="" ctx=DDL +STMT: DropStmt +== 076 +-- only accept valid partitioning strategy +CREATE TABLE partitioned ( + a int +) PARTITION BY MAGIC (a) +-- +ERROR: unrecognized partitioning strategy "magic" +FILENAME: gram.y +FUNCNAME: parsePartitionStrategy +== 077 +-- specified column must be present in the table +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (b) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 078 +-- cannot use system columns in partition key +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (xmin) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 079 +-- cannot use pseudotypes +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (((a, b))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 080 +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (a, ('unknown')) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 081 +-- functions in key must be immutable +CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL +-- +FUNCTION: name="immut_func" function="immut_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 082 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (immut_func(a)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 083 +DROP FUNCTION immut_func(int) +-- +FUNCTION: name="immut_func" function="immut_func" schema="" ctx=DDL +STMT: DropStmt +== 084 +-- prevent using columns of unsupported types in key (type must have a btree operator class) +CREATE TABLE partitioned ( + a point +) PARTITION BY LIST (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 085 +CREATE TABLE partitioned ( + a point +) PARTITION BY LIST (a point_ops) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 086 +CREATE TABLE partitioned ( + a point +) PARTITION BY RANGE (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 087 +CREATE TABLE partitioned ( + a point +) PARTITION BY RANGE (a point_ops) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 088 +-- cannot add NO INHERIT constraints to partitioned tables +CREATE TABLE partitioned ( + a int, + CONSTRAINT check_a CHECK (a > 0) NO INHERIT +) PARTITION BY RANGE (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 089 +-- some checks after successful creation of a partitioned table +CREATE FUNCTION plusone(a int) RETURNS INT AS $$ SELECT a+1; $$ LANGUAGE SQL +-- +FUNCTION: name="plusone" function="plusone" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 090 +CREATE TABLE partitioned ( + a int, + b int, + c text, + d text +) PARTITION BY RANGE (a oid_ops, plusone(b), c collate "default", d collate "C") +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 091 +-- check relkind +SELECT relkind FROM pg_class WHERE relname = 'partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 092 +-- prevent a function referenced in partition key from being dropped +DROP FUNCTION plusone(int) +-- +FUNCTION: name="plusone" function="plusone" schema="" ctx=DDL +STMT: DropStmt +== 093 +-- partitioned table cannot participate in regular inheritance +CREATE TABLE partitioned2 ( + a int, + b text +) PARTITION BY RANGE ((a+1), substr(b, 1, 5)) +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: CreateStmt +== 094 +CREATE TABLE fail () INHERITS (partitioned2) +-- +TABLE: name="fail" schema="" table="fail" ctx=DDL +STMT: CreateStmt +== 095 +-- Partition key in describe output + +INSERT INTO partitioned2 VALUES (1, 'hello') +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc') +-- +TABLE: name="part2_1" schema="" table="part2_1" ctx=DDL +STMT: CreateStmt +== 097 +DROP TABLE partitioned, partitioned2 +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: DropStmt +== 098 +-- check reference to partitioned table's rowtype in partition descriptor +create table partitioned (a int, b int) + partition by list ((row(a, b)::partitioned)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 099 +create table partitioned1 + partition of partitioned for values in ('(1,2)'::partitioned) +-- +TABLE: name="partitioned1" schema="" table="partitioned1" ctx=DDL +STMT: CreateStmt +== 100 +create table partitioned2 + partition of partitioned for values in ('(2,4)'::partitioned) +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: CreateStmt +== 101 +explain (costs off) +select * from partitioned where row(a,b)::partitioned = '(1,2)'::partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 102 +drop table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: DropStmt +== 103 +-- whole-row Var in partition key works too +create table partitioned (a int, b int) + partition by list ((partitioned)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 104 +create table partitioned1 + partition of partitioned for values in ('(1,2)') +-- +TABLE: name="partitioned1" schema="" table="partitioned1" ctx=DDL +STMT: CreateStmt +== 105 +create table partitioned2 + partition of partitioned for values in ('(2,4)') +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: CreateStmt +== 106 +explain (costs off) +select * from partitioned where partitioned = '(1,2)'::partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +FILTER: schema="" table="" column="partitioned" +STMT: ExplainStmt +STMT: SelectStmt +== 107 +drop table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: DropStmt +== 108 +-- check that dependencies of partition columns are handled correctly +create domain intdom1 as int +-- +STMT: CreateDomainStmt +== 109 +create table partitioned ( + a intdom1, + b text +) partition by range (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 110 +alter table partitioned drop column a +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 111 +-- fail + +drop domain intdom1 +-- +STMT: DropStmt +== 112 +-- fail, requires cascade + +drop domain intdom1 cascade +-- +STMT: DropStmt +== 113 +table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +STMT: SelectStmt +== 114 +-- gone + +-- likewise for columns used in partition expressions +create domain intdom1 as int +-- +STMT: CreateDomainStmt +== 115 +create table partitioned ( + a intdom1, + b text +) partition by range (plusone(a)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +== 116 +alter table partitioned drop column a +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +== 117 +-- fail + +drop domain intdom1 +-- +STMT: DropStmt +== 118 +-- fail, requires cascade + +drop domain intdom1 cascade +-- +STMT: DropStmt +== 119 +table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +STMT: SelectStmt +== 120 +-- gone + + +|-- +-- Partitions +|-- + +-- check partition bound syntax + +CREATE TABLE list_parted ( + a int +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +== 121 +CREATE TABLE part_p1 PARTITION OF list_parted FOR VALUES IN ('1') +-- +TABLE: name="part_p1" schema="" table="part_p1" ctx=DDL +STMT: CreateStmt +== 122 +CREATE TABLE part_p2 PARTITION OF list_parted FOR VALUES IN (2) +-- +TABLE: name="part_p2" schema="" table="part_p2" ctx=DDL +STMT: CreateStmt +== 123 +CREATE TABLE part_p3 PARTITION OF list_parted FOR VALUES IN ((2+1)) +-- +TABLE: name="part_p3" schema="" table="part_p3" ctx=DDL +STMT: CreateStmt +== 124 +CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (null) +-- +TABLE: name="part_null" schema="" table="part_null" ctx=DDL +STMT: CreateStmt +== 125 +-- forbidden expressions for partition bound with list partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 126 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename.somename) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 127 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (a) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 128 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(a)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 129 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(somename)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 130 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(1)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 131 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((select 1)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 132 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (generate_series(4, 6)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 133 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((1+1) collate "POSIX") +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 134 +-- syntax does not allow empty list of values for list partitions +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN () +-- +ERROR: syntax error at or near ")" +CURSORPOS: 130 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 135 +-- trying to specify range for list partitioned table +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES FROM (1) TO (2) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 136 +-- trying to specify modulus and remainder for list partitioned table +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 137 +-- check default partition cannot be created more than once +CREATE TABLE part_default PARTITION OF list_parted DEFAULT +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +== 138 +CREATE TABLE fail_default_part PARTITION OF list_parted DEFAULT +-- +TABLE: name="fail_default_part" schema="" table="fail_default_part" ctx=DDL +STMT: CreateStmt +== 139 +-- specified literal can't be cast to the partition column data type +CREATE TABLE bools ( + a bool +) PARTITION BY LIST (a) +-- +TABLE: name="bools" schema="" table="bools" ctx=DDL +STMT: CreateStmt +== 140 +CREATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1) +-- +TABLE: name="bools_true" schema="" table="bools_true" ctx=DDL +STMT: CreateStmt +== 141 +DROP TABLE bools +-- +TABLE: name="bools" schema="" table="bools" ctx=DDL +STMT: DropStmt +== 142 +-- specified literal can be cast, and the cast might not be immutable +CREATE TABLE moneyp ( + a money +) PARTITION BY LIST (a) +-- +TABLE: name="moneyp" schema="" table="moneyp" ctx=DDL +STMT: CreateStmt +== 143 +CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10) +-- +TABLE: name="moneyp_10" schema="" table="moneyp_10" ctx=DDL +STMT: CreateStmt +== 144 +CREATE TABLE moneyp_11 PARTITION OF moneyp FOR VALUES IN ('11') +-- +TABLE: name="moneyp_11" schema="" table="moneyp_11" ctx=DDL +STMT: CreateStmt +== 145 +CREATE TABLE moneyp_12 PARTITION OF moneyp FOR VALUES IN (to_char(12, '99')::int) +-- +TABLE: name="moneyp_12" schema="" table="moneyp_12" ctx=DDL +STMT: CreateStmt +== 146 +DROP TABLE moneyp +-- +TABLE: name="moneyp" schema="" table="moneyp" ctx=DDL +STMT: DropStmt +== 147 +-- cast is immutable +CREATE TABLE bigintp ( + a bigint +) PARTITION BY LIST (a) +-- +TABLE: name="bigintp" schema="" table="bigintp" ctx=DDL +STMT: CreateStmt +== 148 +CREATE TABLE bigintp_10 PARTITION OF bigintp FOR VALUES IN (10) +-- +TABLE: name="bigintp_10" schema="" table="bigintp_10" ctx=DDL +STMT: CreateStmt +== 149 +-- fails due to overlap: +CREATE TABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10') +-- +TABLE: name="bigintp_10_2" schema="" table="bigintp_10_2" ctx=DDL +STMT: CreateStmt +== 150 +DROP TABLE bigintp +-- +TABLE: name="bigintp" schema="" table="bigintp" ctx=DDL +STMT: DropStmt +== 151 +CREATE TABLE range_parted ( + a date +) PARTITION BY RANGE (a) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +== 152 +-- forbidden expressions for partition bounds with range partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 153 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename.somename) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 154 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (a) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 155 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(a)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 156 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(somename)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 157 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max('2019-02-01'::date)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 158 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM ((select 1)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 159 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (generate_series(1, 3)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +== 160 +-- trying to specify list for range partitioned table +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES IN ('a') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 161 +-- trying to specify modulus and remainder for range partitioned table +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 162 +-- each of start and end bounds must have same number of values as the +-- length of the partition key +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('z') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 163 +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a') TO ('z', 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 164 +-- cannot specify null values in range bounds +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (maxvalue) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 165 +-- trying to specify modulus and remainder for range partitioned table +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 166 +-- check partition bound syntax for the hash partition +CREATE TABLE hash_parted ( + a int +) PARTITION BY HASH (a) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +== 167 +CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 0) +-- +TABLE: name="hpart_1" schema="" table="hpart_1" ctx=DDL +STMT: CreateStmt +== 168 +CREATE TABLE hpart_2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 50, REMAINDER 1) +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DDL +STMT: CreateStmt +== 169 +CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200, REMAINDER 2) +-- +TABLE: name="hpart_3" schema="" table="hpart_3" ctx=DDL +STMT: CreateStmt +== 170 +CREATE TABLE hpart_4 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 3) +-- +TABLE: name="hpart_4" schema="" table="hpart_4" ctx=DDL +STMT: CreateStmt +== 171 +-- modulus 25 is factor of modulus of 50 but 10 is not a factor of 25. +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 25, REMAINDER 3) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 172 +-- previous modulus 50 is factor of 150 but this modulus is not a factor of next modulus 200. +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 173 +-- overlapping remainders +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 100, REMAINDER 3) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 174 +-- trying to specify range for the hash partitioned table +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES FROM ('a', 1) TO ('z') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 175 +-- trying to specify list value for the hash partitioned table +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES IN (1000) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 176 +-- trying to create default partition for the hash partitioned table +CREATE TABLE fail_default_part PARTITION OF hash_parted DEFAULT +-- +TABLE: name="fail_default_part" schema="" table="fail_default_part" ctx=DDL +STMT: CreateStmt +== 177 +-- check if compatible with the specified parent + +-- cannot create as partition of a non-partitioned table +CREATE TABLE unparted ( + a int +) +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: CreateStmt +== 178 +CREATE TABLE fail_part PARTITION OF unparted FOR VALUES IN ('a') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 179 +CREATE TABLE fail_part PARTITION OF unparted FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 180 +DROP TABLE unparted +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: DropStmt +== 181 +-- cannot create a permanent rel as partition of a temp rel +CREATE TEMP TABLE temp_parted ( + a int +) PARTITION BY LIST (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +== 182 +CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 183 +DROP TABLE temp_parted +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: DropStmt +== 184 +-- check for partition bound overlap and other invalid specifications + +CREATE TABLE list_parted2 ( + a varchar +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: CreateStmt +== 185 +CREATE TABLE part_null_z PARTITION OF list_parted2 FOR VALUES IN (null, 'z') +-- +TABLE: name="part_null_z" schema="" table="part_null_z" ctx=DDL +STMT: CreateStmt +== 186 +CREATE TABLE part_ab PARTITION OF list_parted2 FOR VALUES IN ('a', 'b') +-- +TABLE: name="part_ab" schema="" table="part_ab" ctx=DDL +STMT: CreateStmt +== 187 +CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DDL +STMT: CreateStmt +== 188 +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN (null) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 189 +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 190 +-- check default partition overlap +INSERT INTO list_parted2 VALUES('X') +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('W', 'X', 'Y') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 192 +CREATE TABLE range_parted2 ( + a int +) PARTITION BY RANGE (a) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +== 193 +-- trying to create range partition with empty range +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 194 +-- note that the range '[1, 1)' has no elements +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 195 +CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1) +-- +TABLE: name="part0" schema="" table="part0" ctx=DDL +STMT: CreateStmt +== 196 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 197 +CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +== 198 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (-1) TO (1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 199 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 200 +CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +== 201 +CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +== 202 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 203 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 204 +-- Create a default partition for range partitioned table +CREATE TABLE range2_default PARTITION OF range_parted2 DEFAULT +-- +TABLE: name="range2_default" schema="" table="range2_default" ctx=DDL +STMT: CreateStmt +== 205 +-- More than one default partition is not allowed, so this should give error +CREATE TABLE fail_default_part PARTITION OF range_parted2 DEFAULT +-- +TABLE: name="fail_default_part" schema="" table="fail_default_part" ctx=DDL +STMT: CreateStmt +== 206 +-- Check if the range for default partitions overlap +INSERT INTO range_parted2 VALUES (85) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 207 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (80) TO (90) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 208 +CREATE TABLE part4 PARTITION OF range_parted2 FOR VALUES FROM (90) TO (100) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +== 209 +-- now check for multi-column range partition key +CREATE TABLE range_parted3 ( + a int, + b int +) PARTITION BY RANGE (a, (b+1)) +-- +TABLE: name="range_parted3" schema="" table="range_parted3" ctx=DDL +STMT: CreateStmt +== 210 +CREATE TABLE part00 PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, maxvalue) +-- +TABLE: name="part00" schema="" table="part00" ctx=DDL +STMT: CreateStmt +== 211 +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 212 +CREATE TABLE part10 PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, 1) +-- +TABLE: name="part10" schema="" table="part10" ctx=DDL +STMT: CreateStmt +== 213 +CREATE TABLE part11 PARTITION OF range_parted3 FOR VALUES FROM (1, 1) TO (1, 10) +-- +TABLE: name="part11" schema="" table="part11" ctx=DDL +STMT: CreateStmt +== 214 +CREATE TABLE part12 PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, maxvalue) +-- +TABLE: name="part12" schema="" table="part12" ctx=DDL +STMT: CreateStmt +== 215 +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, 20) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 216 +CREATE TABLE range3_default PARTITION OF range_parted3 DEFAULT +-- +TABLE: name="range3_default" schema="" table="range3_default" ctx=DDL +STMT: CreateStmt +== 217 +-- cannot create a partition that says column b is allowed to range +-- from -infinity to +infinity, while there exist partitions that have +-- more specific ranges +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, maxvalue) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 218 +-- check for partition bound overlap and other invalid specifications for the hash partition +CREATE TABLE hash_parted2 ( + a varchar +) PARTITION BY HASH (a) +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: CreateStmt +== 219 +CREATE TABLE h2part_1 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 4, REMAINDER 2) +-- +TABLE: name="h2part_1" schema="" table="h2part_1" ctx=DDL +STMT: CreateStmt +== 220 +CREATE TABLE h2part_2 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 0) +-- +TABLE: name="h2part_2" schema="" table="h2part_2" ctx=DDL +STMT: CreateStmt +== 221 +CREATE TABLE h2part_3 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 4) +-- +TABLE: name="h2part_3" schema="" table="h2part_3" ctx=DDL +STMT: CreateStmt +== 222 +CREATE TABLE h2part_4 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 5) +-- +TABLE: name="h2part_4" schema="" table="h2part_4" ctx=DDL +STMT: CreateStmt +== 223 +-- overlap with part_4 +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 224 +-- modulus must be greater than zero +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 0, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 225 +-- remainder must be greater than or equal to zero and less than modulus +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 8) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +== 226 +-- check schema propagation from parent + +CREATE TABLE parted ( + a text, + b int NOT NULL DEFAULT 0, + CONSTRAINT check_a CHECK (length(a) > 0) +) PARTITION BY LIST (a) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateStmt +== 227 +CREATE TABLE part_a PARTITION OF parted FOR VALUES IN ('a') +-- +TABLE: name="part_a" schema="" table="part_a" ctx=DDL +STMT: CreateStmt +== 228 +-- only inherited attributes (never local ones) +SELECT attname, attislocal, attinhcount FROM pg_attribute + WHERE attrelid = 'part_a'::regclass and attnum > 0 + ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 229 +-- able to specify column default, column constraint, and table constraint + +-- first check the "column specified more than once" error +CREATE TABLE part_b PARTITION OF parted ( + b NOT NULL, + b DEFAULT 1, + b CHECK (b >= 0), + CONSTRAINT check_a CHECK (length(a) > 0) +) FOR VALUES IN ('b') +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: CreateStmt +== 230 +CREATE TABLE part_b PARTITION OF parted ( + b NOT NULL DEFAULT 1, + CONSTRAINT check_a CHECK (length(a) > 0), + CONSTRAINT check_b CHECK (b >= 0) +) FOR VALUES IN ('b') +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: CreateStmt +== 231 +-- conislocal should be false for any merged constraints, true otherwise +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 232 +-- Once check_b is added to the parent, it should be made non-local for part_b +ALTER TABLE parted ADD CONSTRAINT check_b CHECK (b >= 0) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: AlterTableStmt +== 233 +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 234 +-- Neither check_a nor check_b are droppable from part_b +ALTER TABLE part_b DROP CONSTRAINT check_a +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: AlterTableStmt +== 235 +ALTER TABLE part_b DROP CONSTRAINT check_b +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: AlterTableStmt +== 236 +-- And dropping it from parted should leave no trace of them on part_b, unlike +-- traditional inheritance where they will be left behind, because they would +-- be local constraints. +ALTER TABLE parted DROP CONSTRAINT check_a, DROP CONSTRAINT check_b +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: AlterTableStmt +== 237 +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 238 +-- specify PARTITION BY for a partition +CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c) +-- +TABLE: name="fail_part_col_not_found" schema="" table="fail_part_col_not_found" ctx=DDL +STMT: CreateStmt +== 239 +CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b)) +-- +TABLE: name="part_c" schema="" table="part_c" ctx=DDL +STMT: CreateStmt +== 240 +-- create a level-2 partition +CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10) +-- +TABLE: name="part_c_1_10" schema="" table="part_c_1_10" ctx=DDL +STMT: CreateStmt +== 241 +-- check that NOT NULL and default value are inherited correctly +create table parted_notnull_inh_test (a int default 1, b int not null default 0) partition by list (a) +-- +TABLE: name="parted_notnull_inh_test" schema="" table="parted_notnull_inh_test" ctx=DDL +STMT: CreateStmt +== 242 +create table parted_notnull_inh_test1 partition of parted_notnull_inh_test (a not null, b default 1) for values in (1) +-- +TABLE: name="parted_notnull_inh_test1" schema="" table="parted_notnull_inh_test1" ctx=DDL +STMT: CreateStmt +== 243 +insert into parted_notnull_inh_test (b) values (null) +-- +TABLE: name="parted_notnull_inh_test" schema="" table="parted_notnull_inh_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +-- note that while b's default is overridden, a's default is preserved +drop table parted_notnull_inh_test +-- +TABLE: name="parted_notnull_inh_test" schema="" table="parted_notnull_inh_test" ctx=DDL +STMT: DropStmt +== 245 +-- check that collations are assigned in partition bound expressions +create table parted_boolean_col (a bool, b text) partition by list(a) +-- +TABLE: name="parted_boolean_col" schema="" table="parted_boolean_col" ctx=DDL +STMT: CreateStmt +== 246 +create table parted_boolean_less partition of parted_boolean_col + for values in ('foo' < 'bar') +-- +TABLE: name="parted_boolean_less" schema="" table="parted_boolean_less" ctx=DDL +STMT: CreateStmt +== 247 +create table parted_boolean_greater partition of parted_boolean_col + for values in ('foo' > 'bar') +-- +TABLE: name="parted_boolean_greater" schema="" table="parted_boolean_greater" ctx=DDL +STMT: CreateStmt +== 248 +drop table parted_boolean_col +-- +TABLE: name="parted_boolean_col" schema="" table="parted_boolean_col" ctx=DDL +STMT: DropStmt +== 249 +-- check for a conflicting COLLATE clause +create table parted_collate_must_match (a text collate "C", b text collate "C") + partition by range (a) +-- +TABLE: name="parted_collate_must_match" schema="" table="parted_collate_must_match" ctx=DDL +STMT: CreateStmt +== 250 +-- on the partition key +create table parted_collate_must_match1 partition of parted_collate_must_match + (a collate "POSIX") for values from ('a') to ('m') +-- +TABLE: name="parted_collate_must_match1" schema="" table="parted_collate_must_match1" ctx=DDL +STMT: CreateStmt +== 251 +-- on another column +create table parted_collate_must_match2 partition of parted_collate_must_match + (b collate "POSIX") for values from ('m') to ('z') +-- +TABLE: name="parted_collate_must_match2" schema="" table="parted_collate_must_match2" ctx=DDL +STMT: CreateStmt +== 252 +drop table parted_collate_must_match +-- +TABLE: name="parted_collate_must_match" schema="" table="parted_collate_must_match" ctx=DDL +STMT: DropStmt +== 253 +-- check that non-matching collations for partition bound +-- expressions are coerced to the right collation + +create table test_part_coll_posix (a text) partition by range (a collate "POSIX") +-- +TABLE: name="test_part_coll_posix" schema="" table="test_part_coll_posix" ctx=DDL +STMT: CreateStmt +== 254 +-- ok, collation is implicitly coerced +create table test_part_coll partition of test_part_coll_posix for values from ('a' collate "C") to ('g') +-- +TABLE: name="test_part_coll" schema="" table="test_part_coll" ctx=DDL +STMT: CreateStmt +== 255 +-- ok +create table test_part_coll2 partition of test_part_coll_posix for values from ('g') to ('m') +-- +TABLE: name="test_part_coll2" schema="" table="test_part_coll2" ctx=DDL +STMT: CreateStmt +== 256 +-- ok, collation is implicitly coerced +create table test_part_coll_cast partition of test_part_coll_posix for values from (name 'm' collate "C") to ('s') +-- +TABLE: name="test_part_coll_cast" schema="" table="test_part_coll_cast" ctx=DDL +STMT: CreateStmt +== 257 +-- ok; partition collation silently overrides the default collation of type 'name' +create table test_part_coll_cast2 partition of test_part_coll_posix for values from (name 's') to ('z') +-- +TABLE: name="test_part_coll_cast2" schema="" table="test_part_coll_cast2" ctx=DDL +STMT: CreateStmt +== 258 +drop table test_part_coll_posix +-- +TABLE: name="test_part_coll_posix" schema="" table="test_part_coll_posix" ctx=DDL +STMT: DropStmt +== 259 +-- Partition bound in describe output + +-- Both partition bound and partition key in describe output + +-- a level-2 partition's constraint will include the parent's expressions + +-- Show partition count in the parent's describe output +-- Tempted to include \d+ output listing partitions with bound info but +-- output could vary depending on the order in which partition oids are +-- returned. + +-- check that we get the expected partition constraints +CREATE TABLE range_parted4 (a int, b int, c int) PARTITION BY RANGE (abs(a), abs(b), c) +-- +TABLE: name="range_parted4" schema="" table="range_parted4" ctx=DDL +STMT: CreateStmt +== 260 +CREATE TABLE unbounded_range_part PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, MINVALUE, MINVALUE) TO (MAXVALUE, MAXVALUE, MAXVALUE) +-- +TABLE: name="unbounded_range_part" schema="" table="unbounded_range_part" ctx=DDL +STMT: CreateStmt +== 261 +DROP TABLE unbounded_range_part +-- +TABLE: name="unbounded_range_part" schema="" table="unbounded_range_part" ctx=DDL +STMT: DropStmt +== 262 +CREATE TABLE range_parted4_1 PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, MINVALUE, MINVALUE) TO (1, MAXVALUE, MAXVALUE) +-- +TABLE: name="range_parted4_1" schema="" table="range_parted4_1" ctx=DDL +STMT: CreateStmt +== 263 +CREATE TABLE range_parted4_2 PARTITION OF range_parted4 FOR VALUES FROM (3, 4, 5) TO (6, 7, MAXVALUE) +-- +TABLE: name="range_parted4_2" schema="" table="range_parted4_2" ctx=DDL +STMT: CreateStmt +== 264 +CREATE TABLE range_parted4_3 PARTITION OF range_parted4 FOR VALUES FROM (6, 8, MINVALUE) TO (9, MAXVALUE, MAXVALUE) +-- +TABLE: name="range_parted4_3" schema="" table="range_parted4_3" ctx=DDL +STMT: CreateStmt +== 265 +DROP TABLE range_parted4 +-- +TABLE: name="range_parted4" schema="" table="range_parted4" ctx=DDL +STMT: DropStmt +== 266 +-- user-defined operator class in partition key +CREATE FUNCTION my_int4_sort(int4,int4) RETURNS int LANGUAGE sql + AS $$ SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$ +-- +FUNCTION: name="my_int4_sort" function="my_int4_sort" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 267 +CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4,int4), OPERATOR 2 <= (int4,int4), + OPERATOR 3 = (int4,int4), OPERATOR 4 >= (int4,int4), + OPERATOR 5 > (int4,int4), FUNCTION 1 my_int4_sort(int4,int4) +-- +STMT: CreateOpClassStmt +== 268 +CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops) +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DDL +STMT: CreateStmt +== 269 +CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="partkey_t_1" schema="" table="partkey_t_1" ctx=DDL +STMT: CreateStmt +== 270 +INSERT INTO partkey_t VALUES (100) +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 271 +INSERT INTO partkey_t VALUES (200) +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 272 +-- cleanup +DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3 +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +TABLE: name="range_parted3" schema="" table="range_parted3" ctx=DDL +STMT: DropStmt +== 273 +DROP TABLE partkey_t, hash_parted, hash_parted2 +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DDL +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: DropStmt +== 274 +DROP OPERATOR CLASS test_int4_ops USING btree +-- +STMT: DropStmt +== 275 +DROP FUNCTION my_int4_sort(int4,int4) +-- +FUNCTION: name="my_int4_sort" function="my_int4_sort" schema="" ctx=DDL +STMT: DropStmt +== 276 +-- comments on partitioned tables columns +CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a) +-- +TABLE: name="parted_col_comment" schema="" table="parted_col_comment" ctx=DDL +STMT: CreateStmt +== 277 +COMMENT ON TABLE parted_col_comment IS 'Am partitioned table' +-- +STMT: CommentStmt +== 278 +COMMENT ON COLUMN parted_col_comment.a IS 'Partition key' +-- +STMT: CommentStmt +== 279 +SELECT obj_description('parted_col_comment'::regclass) +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +== 280 +DROP TABLE parted_col_comment +-- +TABLE: name="parted_col_comment" schema="" table="parted_col_comment" ctx=DDL +STMT: DropStmt +== 281 +-- specifying storage parameters for partitioned tables is not supported +CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a) WITH (fillfactor=100) +-- +TABLE: name="parted_col_comment" schema="" table="parted_col_comment" ctx=DDL +STMT: CreateStmt +== 282 +-- list partitioning on array type column +CREATE TABLE arrlp (a int[]) PARTITION BY LIST (a) +-- +TABLE: name="arrlp" schema="" table="arrlp" ctx=DDL +STMT: CreateStmt +== 283 +CREATE TABLE arrlp12 PARTITION OF arrlp FOR VALUES IN ('{1}', '{2}') +-- +TABLE: name="arrlp12" schema="" table="arrlp12" ctx=DDL +STMT: CreateStmt +== 284 +DROP TABLE arrlp +-- +TABLE: name="arrlp" schema="" table="arrlp" ctx=DDL +STMT: DropStmt +== 285 +-- partition on boolean column +create table boolspart (a bool) partition by list (a) +-- +TABLE: name="boolspart" schema="" table="boolspart" ctx=DDL +STMT: CreateStmt +== 286 +create table boolspart_t partition of boolspart for values in (true) +-- +TABLE: name="boolspart_t" schema="" table="boolspart_t" ctx=DDL +STMT: CreateStmt +== 287 +create table boolspart_f partition of boolspart for values in (false) +-- +TABLE: name="boolspart_f" schema="" table="boolspart_f" ctx=DDL +STMT: CreateStmt +== 288 +drop table boolspart +-- +TABLE: name="boolspart" schema="" table="boolspart" ctx=DDL +STMT: DropStmt +== 289 +-- partitions mixing temporary and permanent relations +create table perm_parted (a int) partition by list (a) +-- +TABLE: name="perm_parted" schema="" table="perm_parted" ctx=DDL +STMT: CreateStmt +== 290 +create temporary table temp_parted (a int) partition by list (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +== 291 +create table perm_part partition of temp_parted default +-- +TABLE: name="perm_part" schema="" table="perm_part" ctx=DDL +STMT: CreateStmt +== 292 +-- error +create temp table temp_part partition of perm_parted default +-- +TABLE: name="temp_part" schema="" table="temp_part" ctx=DDL +STMT: CreateStmt +== 293 +-- error +create temp table temp_part partition of temp_parted default +-- +TABLE: name="temp_part" schema="" table="temp_part" ctx=DDL +STMT: CreateStmt +== 294 +-- ok +drop table perm_parted cascade +-- +TABLE: name="perm_parted" schema="" table="perm_parted" ctx=DDL +STMT: DropStmt +== 295 +drop table temp_parted cascade +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: DropStmt +== 296 +-- check that adding partitions to a table while it is being used is prevented +create table tab_part_create (a int) partition by list (a) +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DDL +STMT: CreateStmt +== 297 +create or replace function func_part_create() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_create_1 partition of tab_part_create for values in (1)'; + return null; + end $$ +-- +FUNCTION: name="func_part_create" function="func_part_create" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 298 +create trigger trig_part_create before insert on tab_part_create + for each statement execute procedure func_part_create() +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DDL +STMT: CreateTrigStmt +== 299 +insert into tab_part_create values (1) +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 300 +drop table tab_part_create +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DDL +STMT: DropStmt +== 301 +drop function func_part_create() +-- +FUNCTION: name="func_part_create" function="func_part_create" schema="" ctx=DDL +STMT: DropStmt +== 302 +-- test using a volatile expression as partition bound +create table volatile_partbound_test (partkey timestamp) partition by range (partkey) +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=DDL +STMT: CreateStmt +== 303 +create table volatile_partbound_test1 partition of volatile_partbound_test for values from (minvalue) to (current_timestamp) +-- +TABLE: name="volatile_partbound_test1" schema="" table="volatile_partbound_test1" ctx=DDL +STMT: CreateStmt +== 304 +create table volatile_partbound_test2 partition of volatile_partbound_test for values from (current_timestamp) to (maxvalue) +-- +TABLE: name="volatile_partbound_test2" schema="" table="volatile_partbound_test2" ctx=DDL +STMT: CreateStmt +== 305 +-- this should go into the partition volatile_partbound_test2 +insert into volatile_partbound_test values (current_timestamp) +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +select tableoid::regclass from volatile_partbound_test +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=Select +STMT: SelectStmt +== 307 +drop table volatile_partbound_test +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=DDL +STMT: DropStmt +== 308 +-- test the case where a check constraint on default partition allows +-- to avoid scanning it when adding a new partition +create table defcheck (a int, b int) partition by list (b) +-- +TABLE: name="defcheck" schema="" table="defcheck" ctx=DDL +STMT: CreateStmt +== 309 +create table defcheck_def (a int, c int, b int) +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DDL +STMT: CreateStmt +== 310 +alter table defcheck_def drop c +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DDL +STMT: AlterTableStmt +== 311 +alter table defcheck attach partition defcheck_def default +-- +TABLE: name="defcheck" schema="" table="defcheck" ctx=DDL +STMT: AlterTableStmt +== 312 +alter table defcheck_def add check (b <= 0 and b is not null) +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DDL +STMT: AlterTableStmt +== 313 +create table defcheck_1 partition of defcheck for values in (1, null) +-- +TABLE: name="defcheck_1" schema="" table="defcheck_1" ctx=DDL +STMT: CreateStmt +== 314 +-- test that complex default partition constraints are enforced correctly +insert into defcheck_def values (0, 0) +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 315 +create table defcheck_0 partition of defcheck for values in (0) +-- +TABLE: name="defcheck_0" schema="" table="defcheck_0" ctx=DDL +STMT: CreateStmt +== 316 +drop table defcheck +-- +TABLE: name="defcheck" schema="" table="defcheck" ctx=DDL +STMT: DropStmt +== 317 +-- tests of column drop with partition tables and indexes using +-- predicates and expressions. +create table part_column_drop ( + useless_1 int, + id int, + useless_2 int, + d int, + b int, + useless_3 int +) partition by range (id) +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: CreateStmt +== 318 +alter table part_column_drop drop column useless_1 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: AlterTableStmt +== 319 +alter table part_column_drop drop column useless_2 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: AlterTableStmt +== 320 +alter table part_column_drop drop column useless_3 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: AlterTableStmt +== 321 +create index part_column_drop_b_pred on part_column_drop(b) where b = 1 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +== 322 +create index part_column_drop_b_expr on part_column_drop((b = 1)) +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +== 323 +create index part_column_drop_d_pred on part_column_drop(d) where d = 2 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +== 324 +create index part_column_drop_d_expr on part_column_drop((d = 2)) +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +== 325 +create table part_column_drop_1_10 partition of + part_column_drop for values from (1) to (10) +-- +TABLE: name="part_column_drop_1_10" schema="" table="part_column_drop_1_10" ctx=DDL +STMT: CreateStmt +== 326 +drop table part_column_drop +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/create_table_like.metadata.json b/parser/testdata/summary/postgres_regress/create_table_like.metadata.json new file mode 100644 index 0000000..267f283 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_table_like.metadata.json @@ -0,0 +1,148 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_table_like.test b/parser/testdata/summary/postgres_regress/create_table_like.test new file mode 100644 index 0000000..e38a6b9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_table_like.test @@ -0,0 +1,822 @@ +== 001 +/* Test inheritance of structure (LIKE) */ +CREATE TABLE inhx (xx text DEFAULT 'text') +-- +TABLE: name="inhx" schema="" table="inhx" ctx=DDL +STMT: CreateStmt +== 002 +/* + * Test double inheritance + * + * Ensure that defaults are NOT included unless + * INCLUDING DEFAULTS is specified + */ +CREATE TABLE ctla (aa TEXT) +-- +TABLE: name="ctla" schema="" table="ctla" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE ctlb (bb TEXT) INHERITS (ctla) +-- +TABLE: name="ctlb" schema="" table="ctlb" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE foo (LIKE nonexistent) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 005 +CREATE TABLE inhe (ee text, LIKE inhx) inherits (ctlb) +-- +TABLE: name="inhe" schema="" table="inhe" ctx=DDL +STMT: CreateStmt +== 006 +INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4') +-- +TABLE: name="inhe" schema="" table="inhe" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +SELECT * FROM inhe +-- +TABLE: name="inhe" schema="" table="inhe" ctx=Select +STMT: SelectStmt +== 008 +/* Columns aa, bb, xx value NULL, ee */ +SELECT * FROM inhx +-- +TABLE: name="inhx" schema="" table="inhx" ctx=Select +STMT: SelectStmt +== 009 +/* Empty set since LIKE inherits structure only */ +SELECT * FROM ctlb +-- +TABLE: name="ctlb" schema="" table="ctlb" ctx=Select +STMT: SelectStmt +== 010 +/* Has ee entry */ +SELECT * FROM ctla +-- +TABLE: name="ctla" schema="" table="ctla" ctx=Select +STMT: SelectStmt +== 011 +/* Has ee entry */ + +CREATE TABLE inhf (LIKE inhx, LIKE inhx) +-- +TABLE: name="inhf" schema="" table="inhf" ctx=DDL +STMT: CreateStmt +== 012 +/* Throw error */ + +CREATE TABLE inhf (LIKE inhx INCLUDING DEFAULTS INCLUDING CONSTRAINTS) +-- +TABLE: name="inhf" schema="" table="inhf" ctx=DDL +STMT: CreateStmt +== 013 +INSERT INTO inhf DEFAULT VALUES +-- +TABLE: name="inhf" schema="" table="inhf" ctx=DML +STMT: InsertStmt +== 014 +SELECT * FROM inhf +-- +TABLE: name="inhf" schema="" table="inhf" ctx=Select +STMT: SelectStmt +== 015 +/* Single entry with value 'text' */ + +ALTER TABLE inhx add constraint foo CHECK (xx = 'text') +-- +TABLE: name="inhx" schema="" table="inhx" ctx=DDL +STMT: AlterTableStmt +== 016 +ALTER TABLE inhx ADD PRIMARY KEY (xx) +-- +TABLE: name="inhx" schema="" table="inhx" ctx=DDL +STMT: AlterTableStmt +== 017 +CREATE TABLE inhg (LIKE inhx) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +== 018 +/* Doesn't copy constraint */ +INSERT INTO inhg VALUES ('foo') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +== 020 +CREATE TABLE inhg (x text, LIKE inhx INCLUDING CONSTRAINTS, y text) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +== 021 +/* Copies constraints */ +INSERT INTO inhg VALUES ('x', 'text', 'y') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +/* Succeeds */ +INSERT INTO inhg VALUES ('x', 'text', 'y') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +/* Succeeds -- Unique constraints not copied */ +INSERT INTO inhg VALUES ('x', 'foo', 'y') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +/* fails due to constraint */ +SELECT * FROM inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=Select +STMT: SelectStmt +== 025 +/* Two records with three columns in order x=x, xx=text, y=y */ +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +== 026 +CREATE TABLE test_like_id_1 (a bigint GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=DDL +STMT: CreateStmt +== 027 +INSERT INTO test_like_id_1 (b) VALUES ('b1') +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +SELECT * FROM test_like_id_1 +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=Select +STMT: SelectStmt +== 029 +CREATE TABLE test_like_id_2 (LIKE test_like_id_1) +-- +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=DDL +STMT: CreateStmt +== 030 +INSERT INTO test_like_id_2 (b) VALUES ('b2') +-- +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +SELECT * FROM test_like_id_2 +-- +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=Select +STMT: SelectStmt +== 032 +-- identity was not copied +CREATE TABLE test_like_id_3 (LIKE test_like_id_1 INCLUDING IDENTITY) +-- +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=DDL +STMT: CreateStmt +== 033 +INSERT INTO test_like_id_3 (b) VALUES ('b3') +-- +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +SELECT * FROM test_like_id_3 +-- +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=Select +STMT: SelectStmt +== 035 +-- identity was copied and applied +DROP TABLE test_like_id_1, test_like_id_2, test_like_id_3 +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=DDL +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=DDL +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=DDL +STMT: DropStmt +== 036 +CREATE TABLE test_like_gen_1 (a int, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=DDL +STMT: CreateStmt +== 037 +INSERT INTO test_like_gen_1 (a) VALUES (1) +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +SELECT * FROM test_like_gen_1 +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=Select +STMT: SelectStmt +== 039 +CREATE TABLE test_like_gen_2 (LIKE test_like_gen_1) +-- +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=DDL +STMT: CreateStmt +== 040 +INSERT INTO test_like_gen_2 (a) VALUES (1) +-- +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +SELECT * FROM test_like_gen_2 +-- +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=Select +STMT: SelectStmt +== 042 +CREATE TABLE test_like_gen_3 (LIKE test_like_gen_1 INCLUDING GENERATED) +-- +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=DDL +STMT: CreateStmt +== 043 +INSERT INTO test_like_gen_3 (a) VALUES (1) +-- +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +SELECT * FROM test_like_gen_3 +-- +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=Select +STMT: SelectStmt +== 045 +DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3 +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=DDL +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=DDL +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=DDL +STMT: DropStmt +== 046 +-- also test generated column with a "forward" reference (bug #16342) +CREATE TABLE test_like_4 (b int DEFAULT 42, + c int GENERATED ALWAYS AS (a * 2) STORED, + a int CHECK (a > 0)) +-- +TABLE: name="test_like_4" schema="" table="test_like_4" ctx=DDL +STMT: CreateStmt +== 047 +CREATE TABLE test_like_4a (LIKE test_like_4) +-- +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=DDL +STMT: CreateStmt +== 048 +CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS) +-- +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=DDL +STMT: CreateStmt +== 049 +CREATE TABLE test_like_4c (LIKE test_like_4 INCLUDING GENERATED) +-- +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=DDL +STMT: CreateStmt +== 050 +CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERATED) +-- +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=DDL +STMT: CreateStmt +== 051 +INSERT INTO test_like_4a (a) VALUES(11) +-- +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +SELECT a, b, c FROM test_like_4a +-- +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=Select +STMT: SelectStmt +== 053 +INSERT INTO test_like_4b (a) VALUES(11) +-- +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +SELECT a, b, c FROM test_like_4b +-- +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=Select +STMT: SelectStmt +== 055 +INSERT INTO test_like_4c (a) VALUES(11) +-- +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +SELECT a, b, c FROM test_like_4c +-- +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=Select +STMT: SelectStmt +== 057 +INSERT INTO test_like_4d (a) VALUES(11) +-- +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +SELECT a, b, c FROM test_like_4d +-- +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=Select +STMT: SelectStmt +== 059 +-- Test renumbering of Vars when combining LIKE with inheritance +CREATE TABLE test_like_5 (x point, y point, z point) +-- +TABLE: name="test_like_5" schema="" table="test_like_5" ctx=DDL +STMT: CreateStmt +== 060 +CREATE TABLE test_like_5x (p int CHECK (p > 0), + q int GENERATED ALWAYS AS (p * 2) STORED) +-- +TABLE: name="test_like_5x" schema="" table="test_like_5x" ctx=DDL +STMT: CreateStmt +== 061 +CREATE TABLE test_like_5c (LIKE test_like_4 INCLUDING ALL) + INHERITS (test_like_5, test_like_5x) +-- +TABLE: name="test_like_5c" schema="" table="test_like_5c" ctx=DDL +STMT: CreateStmt +== 062 +-- Test updating of column numbers in statistics expressions (bug #18468) +CREATE TABLE test_like_6 (a int, c text, b text) +-- +TABLE: name="test_like_6" schema="" table="test_like_6" ctx=DDL +STMT: CreateStmt +== 063 +CREATE STATISTICS ext_stat ON (a || b) FROM test_like_6 +-- +STMT: CreateStatsStmt +== 064 +ALTER TABLE test_like_6 DROP COLUMN c +-- +TABLE: name="test_like_6" schema="" table="test_like_6" ctx=DDL +STMT: AlterTableStmt +== 065 +CREATE TABLE test_like_6c (LIKE test_like_6 INCLUDING ALL) +-- +TABLE: name="test_like_6c" schema="" table="test_like_6c" ctx=DDL +STMT: CreateStmt +== 066 +DROP TABLE test_like_4, test_like_4a, test_like_4b, test_like_4c, test_like_4d +-- +TABLE: name="test_like_4" schema="" table="test_like_4" ctx=DDL +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=DDL +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=DDL +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=DDL +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=DDL +STMT: DropStmt +== 067 +DROP TABLE test_like_5, test_like_5x, test_like_5c +-- +TABLE: name="test_like_5" schema="" table="test_like_5" ctx=DDL +TABLE: name="test_like_5x" schema="" table="test_like_5x" ctx=DDL +TABLE: name="test_like_5c" schema="" table="test_like_5c" ctx=DDL +STMT: DropStmt +== 068 +DROP TABLE test_like_6, test_like_6c +-- +TABLE: name="test_like_6" schema="" table="test_like_6" ctx=DDL +TABLE: name="test_like_6c" schema="" table="test_like_6c" ctx=DDL +STMT: DropStmt +== 069 +CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +== 070 +/* copies indexes */ +INSERT INTO inhg VALUES (5, 10) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +INSERT INTO inhg VALUES (20, 10) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +-- should fail +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +== 073 +/* Multiple primary keys creation should fail */ +CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, PRIMARY KEY(x)) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +== 074 +/* fails */ +CREATE TABLE inhz (xx text DEFAULT 'text', yy int UNIQUE) +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: CreateStmt +== 075 +CREATE UNIQUE INDEX inhz_xx_idx on inhz (xx) WHERE xx <> 'test' +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: IndexStmt +== 076 +/* Ok to create multiple unique indexes */ +CREATE TABLE inhg (x text UNIQUE, LIKE inhz INCLUDING INDEXES) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +== 077 +INSERT INTO inhg (xx, yy, x) VALUES ('test', 5, 10) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +INSERT INTO inhg (xx, yy, x) VALUES ('test', 10, 15) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO inhg (xx, yy, x) VALUES ('foo', 10, 15) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +-- should fail +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +== 081 +DROP TABLE inhz +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: DropStmt +== 082 +/* Use primary key imported by LIKE for self-referential FK constraint */ +CREATE TABLE inhz (x text REFERENCES inhz, LIKE inhx INCLUDING INDEXES) +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: CreateStmt +== 083 +DROP TABLE inhz +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: DropStmt +== 084 +-- including storage and comments +CREATE TABLE ctlt1 (a text CHECK (length(a) > 2) PRIMARY KEY, b text) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: CreateStmt +== 085 +CREATE INDEX ctlt1_b_key ON ctlt1 (b) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: IndexStmt +== 086 +CREATE INDEX ctlt1_fnidx ON ctlt1 ((a || b)) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: IndexStmt +== 087 +CREATE STATISTICS ctlt1_a_b_stat ON a,b FROM ctlt1 +-- +STMT: CreateStatsStmt +== 088 +CREATE STATISTICS ctlt1_expr_stat ON (a || b) FROM ctlt1 +-- +STMT: CreateStatsStmt +== 089 +COMMENT ON STATISTICS ctlt1_a_b_stat IS 'ab stats' +-- +STMT: CommentStmt +== 090 +COMMENT ON STATISTICS ctlt1_expr_stat IS 'ab expr stats' +-- +STMT: CommentStmt +== 091 +COMMENT ON COLUMN ctlt1.a IS 'A' +-- +STMT: CommentStmt +== 092 +COMMENT ON COLUMN ctlt1.b IS 'B' +-- +STMT: CommentStmt +== 093 +COMMENT ON CONSTRAINT ctlt1_a_check ON ctlt1 IS 't1_a_check' +-- +STMT: CommentStmt +== 094 +COMMENT ON INDEX ctlt1_pkey IS 'index pkey' +-- +STMT: CommentStmt +== 095 +COMMENT ON INDEX ctlt1_b_key IS 'index b_key' +-- +STMT: CommentStmt +== 096 +ALTER TABLE ctlt1 ALTER COLUMN a SET STORAGE MAIN +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: AlterTableStmt +== 097 +CREATE TABLE ctlt2 (c text) +-- +TABLE: name="ctlt2" schema="" table="ctlt2" ctx=DDL +STMT: CreateStmt +== 098 +ALTER TABLE ctlt2 ALTER COLUMN c SET STORAGE EXTERNAL +-- +TABLE: name="ctlt2" schema="" table="ctlt2" ctx=DDL +STMT: AlterTableStmt +== 099 +COMMENT ON COLUMN ctlt2.c IS 'C' +-- +STMT: CommentStmt +== 100 +CREATE TABLE ctlt3 (a text CHECK (length(a) < 5), c text CHECK (length(c) < 7)) +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: CreateStmt +== 101 +ALTER TABLE ctlt3 ALTER COLUMN c SET STORAGE EXTERNAL +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: AlterTableStmt +== 102 +ALTER TABLE ctlt3 ALTER COLUMN a SET STORAGE MAIN +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: AlterTableStmt +== 103 +CREATE INDEX ctlt3_fnidx ON ctlt3 ((a || c)) +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: IndexStmt +== 104 +COMMENT ON COLUMN ctlt3.a IS 'A3' +-- +STMT: CommentStmt +== 105 +COMMENT ON COLUMN ctlt3.c IS 'C' +-- +STMT: CommentStmt +== 106 +COMMENT ON CONSTRAINT ctlt3_a_check ON ctlt3 IS 't3_a_check' +-- +STMT: CommentStmt +== 107 +CREATE TABLE ctlt4 (a text, c text) +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +STMT: CreateStmt +== 108 +ALTER TABLE ctlt4 ALTER COLUMN c SET STORAGE EXTERNAL +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +STMT: AlterTableStmt +== 109 +CREATE TABLE ctlt12_storage (LIKE ctlt1 INCLUDING STORAGE, LIKE ctlt2 INCLUDING STORAGE) +-- +TABLE: name="ctlt12_storage" schema="" table="ctlt12_storage" ctx=DDL +STMT: CreateStmt +== 110 +CREATE TABLE ctlt12_comments (LIKE ctlt1 INCLUDING COMMENTS, LIKE ctlt2 INCLUDING COMMENTS) +-- +TABLE: name="ctlt12_comments" schema="" table="ctlt12_comments" ctx=DDL +STMT: CreateStmt +== 111 +CREATE TABLE ctlt1_inh (LIKE ctlt1 INCLUDING CONSTRAINTS INCLUDING COMMENTS) INHERITS (ctlt1) +-- +TABLE: name="ctlt1_inh" schema="" table="ctlt1_inh" ctx=DDL +STMT: CreateStmt +== 112 +SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt1_inh'::regclass +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_constraint" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="c" column="conrelid" +STMT: SelectStmt +== 113 +CREATE TABLE ctlt13_inh () INHERITS (ctlt1, ctlt3) +-- +TABLE: name="ctlt13_inh" schema="" table="ctlt13_inh" ctx=DDL +STMT: CreateStmt +== 114 +CREATE TABLE ctlt13_like (LIKE ctlt3 INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING COMMENTS INCLUDING STORAGE) INHERITS (ctlt1) +-- +TABLE: name="ctlt13_like" schema="" table="ctlt13_like" ctx=DDL +STMT: CreateStmt +== 115 +SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt13_like'::regclass +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_constraint" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="c" column="conrelid" +STMT: SelectStmt +== 116 +CREATE TABLE ctlt_all (LIKE ctlt1 INCLUDING ALL) +-- +TABLE: name="ctlt_all" schema="" table="ctlt_all" ctx=DDL +STMT: CreateStmt +== 117 +SELECT c.relname, objsubid, description FROM pg_description, pg_index i, pg_class c WHERE classoid = 'pg_class'::regclass AND objoid = i.indexrelid AND c.oid = i.indexrelid AND i.indrelid = 'ctlt_all'::regclass ORDER BY c.relname, objsubid +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="i" column="indexrelid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="i" column="indexrelid" +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +== 118 +SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s WHERE classoid = 'pg_statistic_ext'::regclass AND objoid = s.oid AND s.stxrelid = 'ctlt_all'::regclass ORDER BY s.stxname, objsubid +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="stxrelid" +STMT: SelectStmt +== 119 +CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4) +-- +TABLE: name="inh_error1" schema="" table="inh_error1" ctx=DDL +STMT: CreateStmt +== 120 +CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1) +-- +TABLE: name="inh_error2" schema="" table="inh_error2" ctx=DDL +STMT: CreateStmt +== 121 +-- Check that LIKE isn't confused by a system catalog of the same name +CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL) +-- +TABLE: name="pg_attrdef" schema="" table="pg_attrdef" ctx=DDL +STMT: CreateStmt +== 122 +DROP TABLE public.pg_attrdef +-- +TABLE: name="public.pg_attrdef" schema="public" table="pg_attrdef" ctx=DDL +STMT: DropStmt +== 123 +-- Check that LIKE isn't confused when new table masks the old, either +BEGIN +-- +STMT: TransactionStmt +== 124 +CREATE SCHEMA ctl_schema +-- +STMT: CreateSchemaStmt +== 125 +SET LOCAL search_path = ctl_schema, public +-- +STMT: VariableSetStmt +== 126 +CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: CreateStmt +== 127 +ROLLBACK +-- +STMT: TransactionStmt +== 128 +DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +TABLE: name="ctlt2" schema="" table="ctlt2" ctx=DDL +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +TABLE: name="ctlt12_storage" schema="" table="ctlt12_storage" ctx=DDL +TABLE: name="ctlt12_comments" schema="" table="ctlt12_comments" ctx=DDL +TABLE: name="ctlt1_inh" schema="" table="ctlt1_inh" ctx=DDL +TABLE: name="ctlt13_inh" schema="" table="ctlt13_inh" ctx=DDL +TABLE: name="ctlt13_like" schema="" table="ctlt13_like" ctx=DDL +TABLE: name="ctlt_all" schema="" table="ctlt_all" ctx=DDL +TABLE: name="ctla" schema="" table="ctla" ctx=DDL +TABLE: name="ctlb" schema="" table="ctlb" ctx=DDL +STMT: DropStmt +== 129 +-- LIKE must respect NO INHERIT property of constraints +CREATE TABLE noinh_con_copy (a int CHECK (a > 0) NO INHERIT) +-- +TABLE: name="noinh_con_copy" schema="" table="noinh_con_copy" ctx=DDL +STMT: CreateStmt +== 130 +CREATE TABLE noinh_con_copy1 (LIKE noinh_con_copy INCLUDING CONSTRAINTS) +-- +TABLE: name="noinh_con_copy1" schema="" table="noinh_con_copy1" ctx=DDL +STMT: CreateStmt +== 131 +-- fail, as partitioned tables don't allow NO INHERIT constraints +CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL) + PARTITION BY LIST (a) +-- +TABLE: name="noinh_con_copy1_parted" schema="" table="noinh_con_copy1_parted" ctx=DDL +STMT: CreateStmt +== 132 +DROP TABLE noinh_con_copy, noinh_con_copy1 +-- +TABLE: name="noinh_con_copy" schema="" table="noinh_con_copy" ctx=DDL +TABLE: name="noinh_con_copy1" schema="" table="noinh_con_copy1" ctx=DDL +STMT: DropStmt +== 133 +/* LIKE with other relation kinds */ + +CREATE TABLE ctlt4 (a int, b text) +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +STMT: CreateStmt +== 134 +CREATE SEQUENCE ctlseq1 +-- +STMT: CreateSeqStmt +== 135 +CREATE TABLE ctlt10 (LIKE ctlseq1) +-- +TABLE: name="ctlt10" schema="" table="ctlt10" ctx=DDL +STMT: CreateStmt +== 136 +-- fail + +CREATE VIEW ctlv1 AS SELECT * FROM ctlt4 +-- +TABLE: name="ctlv1" schema="" table="ctlv1" ctx=DDL +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 137 +CREATE TABLE ctlt11 (LIKE ctlv1) +-- +TABLE: name="ctlt11" schema="" table="ctlt11" ctx=DDL +STMT: CreateStmt +== 138 +CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL) +-- +TABLE: name="ctlt11a" schema="" table="ctlt11a" ctx=DDL +STMT: CreateStmt +== 139 +CREATE TYPE ctlty1 AS (a int, b text) +-- +STMT: CompositeTypeStmt +== 140 +CREATE TABLE ctlt12 (LIKE ctlty1) +-- +TABLE: name="ctlt12" schema="" table="ctlt12" ctx=DDL +STMT: CreateStmt +== 141 +DROP SEQUENCE ctlseq1 +-- +STMT: DropStmt +== 142 +DROP TYPE ctlty1 +-- +STMT: DropStmt +== 143 +DROP VIEW ctlv1 +-- +STMT: DropStmt +== 144 +DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12 +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +TABLE: name="ctlt10" schema="" table="ctlt10" ctx=DDL +TABLE: name="ctlt11" schema="" table="ctlt11" ctx=DDL +TABLE: name="ctlt11a" schema="" table="ctlt11a" ctx=DDL +TABLE: name="ctlt12" schema="" table="ctlt12" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/create_type.metadata.json b/parser/testdata/summary/postgres_regress/create_type.metadata.json new file mode 100644 index 0000000..b064cb7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_type.metadata.json @@ -0,0 +1,89 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_type.test b/parser/testdata/summary/postgres_regress/create_type.test new file mode 100644 index 0000000..01de685 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_type.test @@ -0,0 +1,578 @@ +== 001 +|-- +-- CREATE_TYPE +|-- + +-- directory path and dlsuffix are passed to us in environment variables + + +|-- +-- Test the "old style" approach of making the I/O functions first, +-- with no explicit shell type creation. +|-- +CREATE FUNCTION widget_in(cstring) + RETURNS widget + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 272 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +CREATE FUNCTION widget_out(widget) + RETURNS cstring + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +CREATE FUNCTION int44in(cstring) + RETURNS city_budget + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +CREATE FUNCTION int44out(city_budget) + RETURNS cstring + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 64 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +CREATE TYPE widget ( + internallength = 24, + input = widget_in, + output = widget_out, + typmod_in = numerictypmodin, + typmod_out = numerictypmodout, + alignment = double +) +-- +STMT: DefineStmt +== 006 +CREATE TYPE city_budget ( + internallength = 16, + input = int44in, + output = int44out, + element = int4, + category = 'x', -- just to verify the system will take it + preferred = true -- ditto +) +-- +STMT: DefineStmt +== 007 +-- Test creation and destruction of shell types +CREATE TYPE shell +-- +STMT: DefineStmt +== 008 +CREATE TYPE shell +-- +STMT: DefineStmt +== 009 +-- fail, type already present +DROP TYPE shell +-- +STMT: DropStmt +== 010 +DROP TYPE shell +-- +STMT: DropStmt +== 011 +-- fail, type not exist + +-- also, let's leave one around for purposes of pg_dump testing +CREATE TYPE myshell +-- +STMT: DefineStmt +== 012 +|-- +-- Test type-related default values (broken in releases before PG 7.2) +|-- +-- This part of the test also exercises the "new style" approach of making +-- a shell type and then filling it in. +|-- +CREATE TYPE int42 +-- +STMT: DefineStmt +== 013 +CREATE TYPE text_w_default +-- +STMT: DefineStmt +== 014 +-- Make dummy I/O routines using the existing internal support for int4, text +CREATE FUNCTION int42_in(cstring) + RETURNS int42 + AS 'int4in' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="int42_in" function="int42_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 015 +CREATE FUNCTION int42_out(int42) + RETURNS cstring + AS 'int4out' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="int42_out" function="int42_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 016 +CREATE FUNCTION text_w_default_in(cstring) + RETURNS text_w_default + AS 'textin' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="text_w_default_in" function="text_w_default_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +CREATE FUNCTION text_w_default_out(text_w_default) + RETURNS cstring + AS 'textout' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="text_w_default_out" function="text_w_default_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 018 +CREATE TYPE int42 ( + internallength = 4, + input = int42_in, + output = int42_out, + alignment = int4, + default = 42, + passedbyvalue +) +-- +STMT: DefineStmt +== 019 +CREATE TYPE text_w_default ( + internallength = variable, + input = text_w_default_in, + output = text_w_default_out, + alignment = int4, + default = 'zippo' +) +-- +STMT: DefineStmt +== 020 +CREATE TABLE default_test (f1 text_w_default, f2 int42) +-- +TABLE: name="default_test" schema="" table="default_test" ctx=DDL +STMT: CreateStmt +== 021 +INSERT INTO default_test DEFAULT VALUES +-- +TABLE: name="default_test" schema="" table="default_test" ctx=DML +STMT: InsertStmt +== 022 +SELECT * FROM default_test +-- +TABLE: name="default_test" schema="" table="default_test" ctx=Select +STMT: SelectStmt +== 023 +-- We need a shell type to test some CREATE TYPE failure cases with +CREATE TYPE bogus_type +-- +STMT: DefineStmt +== 024 +-- invalid: non-lowercase quoted identifiers +CREATE TYPE bogus_type ( + "Internallength" = 4, + "Input" = int42_in, + "Output" = int42_out, + "Alignment" = int4, + "Default" = 42, + "Passedbyvalue" +) +-- +STMT: DefineStmt +== 025 +-- invalid: input/output function incompatibility +CREATE TYPE bogus_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32) +-- +STMT: DefineStmt +== 026 +DROP TYPE bogus_type +-- +STMT: DropStmt +== 027 +-- It no longer is possible to issue CREATE TYPE without making a shell first +CREATE TYPE bogus_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32) +-- +STMT: DefineStmt +== 028 +-- Test stand-alone composite type + +CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42) +-- +STMT: CompositeTypeStmt +== 029 +CREATE FUNCTION get_default_test() RETURNS SETOF default_test_row AS ' + SELECT * FROM default_test; +' LANGUAGE SQL +-- +FUNCTION: name="get_default_test" function="get_default_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 030 +SELECT * FROM get_default_test() +-- +FUNCTION: name="get_default_test" function="get_default_test" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- Test comments +COMMENT ON TYPE bad IS 'bad comment' +-- +STMT: CommentStmt +== 032 +COMMENT ON TYPE default_test_row IS 'good comment' +-- +STMT: CommentStmt +== 033 +COMMENT ON TYPE default_test_row IS NULL +-- +STMT: CommentStmt +== 034 +COMMENT ON COLUMN default_test_row.nope IS 'bad comment' +-- +STMT: CommentStmt +== 035 +COMMENT ON COLUMN default_test_row.f1 IS 'good comment' +-- +STMT: CommentStmt +== 036 +COMMENT ON COLUMN default_test_row.f1 IS NULL +-- +STMT: CommentStmt +== 037 +-- Check shell type create for existing types +CREATE TYPE text_w_default +-- +STMT: DefineStmt +== 038 +-- should fail + +DROP TYPE default_test_row CASCADE +-- +STMT: DropStmt +== 039 +DROP TABLE default_test +-- +TABLE: name="default_test" schema="" table="default_test" ctx=DDL +STMT: DropStmt +== 040 +-- Check dependencies are established when creating a new type +CREATE TYPE base_type +-- +STMT: DefineStmt +== 041 +CREATE FUNCTION base_fn_in(cstring) RETURNS base_type AS 'boolin' + LANGUAGE internal IMMUTABLE STRICT +-- +FUNCTION: name="base_fn_in" function="base_fn_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 042 +CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'boolout' + LANGUAGE internal IMMUTABLE STRICT +-- +FUNCTION: name="base_fn_out" function="base_fn_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 043 +CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out) +-- +STMT: DefineStmt +== 044 +DROP FUNCTION base_fn_in(cstring) +-- +FUNCTION: name="base_fn_in" function="base_fn_in" schema="" ctx=DDL +STMT: DropStmt +== 045 +-- error +DROP FUNCTION base_fn_out(base_type) +-- +FUNCTION: name="base_fn_out" function="base_fn_out" schema="" ctx=DDL +STMT: DropStmt +== 046 +-- error +DROP TYPE base_type +-- +STMT: DropStmt +== 047 +-- error +DROP TYPE base_type CASCADE +-- +STMT: DropStmt +== 048 +-- Check usage of typmod with a user-defined type +-- (we have borrowed numeric's typmod functions) + +CREATE TEMP TABLE mytab (foo widget(42,13,7)) +-- +TABLE: name="mytab" schema="" table="mytab" ctx=DDL +STMT: CreateStmt +== 049 +-- should fail +CREATE TEMP TABLE mytab (foo widget(42,13)) +-- +TABLE: name="mytab" schema="" table="mytab" ctx=DDL +STMT: CreateStmt +== 050 +SELECT format_type(atttypid,atttypmod) FROM pg_attribute +WHERE attrelid = 'mytab'::regclass AND attnum > 0 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 051 +-- might as well exercise the widget type while we're here +INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)') +-- +TABLE: name="mytab" schema="" table="mytab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +TABLE mytab +-- +TABLE: name="mytab" schema="" table="mytab" ctx=Select +STMT: SelectStmt +== 053 +-- and test format_type() a bit more, too +select format_type('varchar'::regtype, 42) +-- +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +STMT: SelectStmt +== 054 +select format_type('bpchar'::regtype, null) +-- +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +STMT: SelectStmt +== 055 +-- this behavior difference is intentional +select format_type('bpchar'::regtype, -1) +-- +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- Test non-error-throwing APIs using widget, which still throws errors +SELECT pg_input_is_valid('(1,2,3)', 'widget') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 057 +SELECT pg_input_is_valid('(1,2)', 'widget') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 058 +-- hard error expected +SELECT pg_input_is_valid('{"(1,2,3)"}', 'widget[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT pg_input_is_valid('{"(1,2)"}', 'widget[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 060 +-- hard error expected +SELECT pg_input_is_valid('("(1,2,3)")', 'mytab') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT pg_input_is_valid('("(1,2)")', 'mytab') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 062 +-- hard error expected + +-- Test creation of an operator over a user-defined type + +CREATE FUNCTION pt_in_widget(point, widget) + RETURNS bool + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 149 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 063 +CREATE OPERATOR <% ( + leftarg = point, + rightarg = widget, + procedure = pt_in_widget, + commutator = >% , + negator = >=% +) +-- +STMT: DefineStmt +== 064 +SELECT point '(1,2)' <% widget '(0,0,3)' AS t, + point '(1,2)' <% widget '(0,0,1)' AS f +-- +STMT: SelectStmt +== 065 +-- exercise city_budget type +CREATE TABLE city ( + name name, + location box, + budget city_budget +) +-- +TABLE: name="city" schema="" table="city" ctx=DDL +STMT: CreateStmt +== 066 +INSERT INTO city VALUES +('Podunk', '(1,2),(3,4)', '100,127,1000'), +('Gotham', '(1000,34),(1100,334)', '123456,127,-1000,6789') +-- +TABLE: name="city" schema="" table="city" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +TABLE city +-- +TABLE: name="city" schema="" table="city" ctx=Select +STMT: SelectStmt +== 068 +|-- +-- Test CREATE/ALTER TYPE using a type that's compatible with varchar, +-- so we can re-use those support functions +|-- +CREATE TYPE myvarchar +-- +STMT: DefineStmt +== 069 +CREATE FUNCTION myvarcharin(cstring, oid, integer) RETURNS myvarchar +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharin' +-- +FUNCTION: name="myvarcharin" function="myvarcharin" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 070 +CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout' +-- +FUNCTION: name="myvarcharout" function="myvarcharout" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 071 +CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea +LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharsend' +-- +FUNCTION: name="myvarcharsend" function="myvarcharsend" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 072 +CREATE FUNCTION myvarcharrecv(internal, oid, integer) RETURNS myvarchar +LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv' +-- +FUNCTION: name="myvarcharrecv" function="myvarcharrecv" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 073 +-- fail, it's still a shell: +ALTER TYPE myvarchar SET (storage = extended) +-- +STMT: AlterTypeStmt +== 074 +CREATE TYPE myvarchar ( + input = myvarcharin, + output = myvarcharout, + alignment = integer, + storage = main +) +-- +STMT: DefineStmt +== 075 +-- want to check updating of a domain over the target type, too +CREATE DOMAIN myvarchardom AS myvarchar +-- +STMT: CreateDomainStmt +== 076 +ALTER TYPE myvarchar SET (storage = plain) +-- +STMT: AlterTypeStmt +== 077 +-- not allowed + +ALTER TYPE myvarchar SET (storage = extended) +-- +STMT: AlterTypeStmt +== 078 +ALTER TYPE myvarchar SET ( + send = myvarcharsend, + receive = myvarcharrecv, + typmod_in = varchartypmodin, + typmod_out = varchartypmodout, + -- these are bogus, but it's safe as long as we don't use the type: + analyze = ts_typanalyze, + subscript = raw_array_subscript_handler +) +-- +STMT: AlterTypeStmt +== 079 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = 'myvarchar' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 080 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = '_myvarchar' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 081 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = 'myvarchardom' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 082 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = '_myvarchardom' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 083 +-- ensure dependencies are straight +DROP FUNCTION myvarcharsend(myvarchar) +-- +FUNCTION: name="myvarcharsend" function="myvarcharsend" schema="" ctx=DDL +STMT: DropStmt +== 084 +-- fail +DROP TYPE myvarchar +-- +STMT: DropStmt +== 085 +-- fail + +DROP TYPE myvarchar CASCADE +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/create_view.metadata.json b/parser/testdata/summary/postgres_regress/create_view.metadata.json new file mode 100644 index 0000000..5d2a46c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_view.metadata.json @@ -0,0 +1,311 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307" + ] +} diff --git a/parser/testdata/summary/postgres_regress/create_view.test b/parser/testdata/summary/postgres_regress/create_view.test new file mode 100644 index 0000000..2824838 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/create_view.test @@ -0,0 +1,2312 @@ +== 001 +|-- +-- CREATE_VIEW +-- Virtual class definitions +-- (this also tests the query rewrite system) +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION interpt_pp(path, path) + RETURNS point + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 238 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +CREATE TABLE real_city ( + pop int4, + cname text, + outline path +) +-- +TABLE: name="real_city" schema="" table="real_city" ctx=DDL +STMT: CreateStmt +== 003 +COPY real_city FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +ANALYZE real_city +-- +TABLE: name="real_city" schema="" table="real_city" ctx=DDL +STMT: VacuumStmt +== 005 +SELECT * + INTO TABLE ramp + FROM ONLY road + WHERE name ~ '.*Ramp' +-- +TABLE: name="road" schema="" table="road" ctx=Select +TABLE: name="ramp" schema="" table="ramp" ctx=DDL +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 006 +CREATE VIEW street AS + SELECT r.name, r.thepath, c.cname AS cname + FROM ONLY road r, real_city c + WHERE c.outline ?# r.thepath +-- +TABLE: name="street" schema="" table="street" ctx=DDL +TABLE: name="road" schema="" table="road" ctx=Select +TABLE: name="real_city" schema="" table="real_city" ctx=Select +ALIAS: "c"="real_city" +ALIAS: "r"="road" +FILTER: schema="" table="c" column="outline" +FILTER: schema="" table="r" column="thepath" +STMT: ViewStmt +STMT: SelectStmt +== 007 +CREATE VIEW iexit AS + SELECT ih.name, ih.thepath, + interpt_pp(ih.thepath, r.thepath) AS exit + FROM ihighway ih, ramp r + WHERE ih.thepath ?# r.thepath +-- +TABLE: name="iexit" schema="" table="iexit" ctx=DDL +TABLE: name="ihighway" schema="" table="ihighway" ctx=Select +TABLE: name="ramp" schema="" table="ramp" ctx=Select +ALIAS: "ih"="ihighway" +ALIAS: "r"="ramp" +FUNCTION: name="interpt_pp" function="interpt_pp" schema="" ctx=Call +FILTER: schema="" table="ih" column="thepath" +FILTER: schema="" table="r" column="thepath" +STMT: ViewStmt +STMT: SelectStmt +== 008 +CREATE VIEW toyemp AS + SELECT name, age, location, 12*salary AS annualsal + FROM emp +-- +TABLE: name="toyemp" schema="" table="toyemp" ctx=DDL +TABLE: name="emp" schema="" table="emp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 009 +-- Test comments +COMMENT ON VIEW noview IS 'no view' +-- +STMT: CommentStmt +== 010 +COMMENT ON VIEW toyemp IS 'is a view' +-- +STMT: CommentStmt +== 011 +COMMENT ON VIEW toyemp IS NULL +-- +STMT: CommentStmt +== 012 +-- These views are left around mainly to exercise special cases in pg_dump. + +CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20)) +-- +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=DDL +STMT: CreateStmt +== 013 +CREATE VIEW key_dependent_view AS + SELECT * FROM view_base_table GROUP BY key +-- +TABLE: name="key_dependent_view" schema="" table="key_dependent_view" ctx=DDL +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 014 +ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey +-- +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=DDL +STMT: AlterTableStmt +== 015 +-- fails + +CREATE VIEW key_dependent_view_no_cols AS + SELECT FROM view_base_table GROUP BY key HAVING length(data) > 0 +-- +TABLE: name="key_dependent_view_no_cols" schema="" table="key_dependent_view_no_cols" ctx=DDL +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 016 +|-- +-- CREATE OR REPLACE VIEW +|-- + +CREATE TABLE viewtest_tbl (a int, b int, c numeric(10,1), d text COLLATE "C") +-- +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=DDL +STMT: CreateStmt +== 017 +COPY viewtest_tbl FROM stdin +-- +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: CopyStmt +== 018 +CREATE OR REPLACE VIEW viewtest AS + SELECT * FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 019 +CREATE OR REPLACE VIEW viewtest AS + SELECT * FROM viewtest_tbl WHERE a > 10 +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 020 +SELECT * FROM viewtest +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=Select +STMT: SelectStmt +== 021 +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 022 +SELECT * FROM viewtest +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=Select +STMT: SelectStmt +== 023 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a FROM viewtest_tbl WHERE a <> 20 +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 024 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT 1, * FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 025 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b::numeric, c, d FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 026 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c::numeric(10,2), d FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 027 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d COLLATE "POSIX" FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 028 +-- should work +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d, 0 AS e FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 029 +DROP VIEW viewtest +-- +STMT: DropStmt +== 030 +DROP TABLE viewtest_tbl +-- +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=DDL +STMT: DropStmt +== 031 +-- tests for temporary views + +CREATE SCHEMA temp_view_test + CREATE TABLE base_table (a int, id int) + CREATE TABLE base_table2 (a int, id int) +-- +STMT: CreateSchemaStmt +== 032 +SET search_path TO temp_view_test, public +-- +STMT: VariableSetStmt +== 033 +CREATE TEMPORARY TABLE temp_table (a int, id int) +-- +TABLE: name="temp_table" schema="" table="temp_table" ctx=DDL +STMT: CreateStmt +== 034 +-- should be created in temp_view_test schema +CREATE VIEW v1 AS SELECT * FROM base_table +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 035 +-- should be created in temp object schema +CREATE VIEW v1_temp AS SELECT * FROM temp_table +-- +TABLE: name="v1_temp" schema="" table="v1_temp" ctx=DDL +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 036 +-- should be created in temp object schema +CREATE TEMP VIEW v2_temp AS SELECT * FROM base_table +-- +TABLE: name="v2_temp" schema="" table="v2_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 037 +-- should be created in temp_views schema +CREATE VIEW temp_view_test.v2 AS SELECT * FROM base_table +-- +TABLE: name="temp_view_test.v2" schema="temp_view_test" table="v2" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 038 +-- should fail +CREATE VIEW temp_view_test.v3_temp AS SELECT * FROM temp_table +-- +TABLE: name="temp_view_test.v3_temp" schema="temp_view_test" table="v3_temp" ctx=DDL +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 039 +-- should fail +CREATE SCHEMA test_view_schema + CREATE TEMP VIEW testview AS SELECT 1 +-- +STMT: CreateSchemaStmt +== 040 +-- joins: if any of the join relations are temporary, the view +-- should also be temporary + +-- should be non-temp +CREATE VIEW v3 AS + SELECT t1.a AS t1_a, t2.a AS t2_a + FROM base_table t1, base_table2 t2 + WHERE t1.id = t2.id +-- +TABLE: name="v3" schema="" table="v3" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="base_table2" +FILTER: schema="" table="t1" column="id" +FILTER: schema="" table="t2" column="id" +STMT: ViewStmt +STMT: SelectStmt +== 041 +-- should be temp (one join rel is temp) +CREATE VIEW v4_temp AS + SELECT t1.a AS t1_a, t2.a AS t2_a + FROM base_table t1, temp_table t2 + WHERE t1.id = t2.id +-- +TABLE: name="v4_temp" schema="" table="v4_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="temp_table" +FILTER: schema="" table="t1" column="id" +FILTER: schema="" table="t2" column="id" +STMT: ViewStmt +STMT: SelectStmt +== 042 +-- should be temp +CREATE VIEW v5_temp AS + SELECT t1.a AS t1_a, t2.a AS t2_a, t3.a AS t3_a + FROM base_table t1, base_table2 t2, temp_table t3 + WHERE t1.id = t2.id and t2.id = t3.id +-- +TABLE: name="v5_temp" schema="" table="v5_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="base_table2" +ALIAS: "t3"="temp_table" +FILTER: schema="" table="t1" column="id" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t3" column="id" +STMT: ViewStmt +STMT: SelectStmt +== 043 +-- subqueries +CREATE VIEW v4 AS SELECT * FROM base_table WHERE id IN (SELECT id FROM base_table2) +-- +TABLE: name="v4" schema="" table="v4" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +FILTER: schema="" table="" column="id" +STMT: ViewStmt +STMT: SelectStmt +== 044 +CREATE VIEW v5 AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM base_table2) t2 +-- +TABLE: name="v5" schema="" table="v5" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +ALIAS: "t1"="base_table" +STMT: ViewStmt +STMT: SelectStmt +== 045 +CREATE VIEW v6 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM base_table2) +-- +TABLE: name="v6" schema="" table="v6" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 046 +CREATE VIEW v7 AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM base_table2) +-- +TABLE: name="v7" schema="" table="v7" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 047 +CREATE VIEW v8 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1) +-- +TABLE: name="v8" schema="" table="v8" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 048 +CREATE VIEW v6_temp AS SELECT * FROM base_table WHERE id IN (SELECT id FROM temp_table) +-- +TABLE: name="v6_temp" schema="" table="v6_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +FILTER: schema="" table="" column="id" +STMT: ViewStmt +STMT: SelectStmt +== 049 +CREATE VIEW v7_temp AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM temp_table) t2 +-- +TABLE: name="v7_temp" schema="" table="v7_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +ALIAS: "t1"="base_table" +STMT: ViewStmt +STMT: SelectStmt +== 050 +CREATE VIEW v8_temp AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM temp_table) +-- +TABLE: name="v8_temp" schema="" table="v8_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 051 +CREATE VIEW v9_temp AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM temp_table) +-- +TABLE: name="v9_temp" schema="" table="v9_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 052 +-- a view should also be temporary if it references a temporary view +CREATE VIEW v10_temp AS SELECT * FROM v7_temp +-- +TABLE: name="v10_temp" schema="" table="v10_temp" ctx=DDL +TABLE: name="v7_temp" schema="" table="v7_temp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 053 +CREATE VIEW v11_temp AS SELECT t1.id, t2.a FROM base_table t1, v10_temp t2 +-- +TABLE: name="v11_temp" schema="" table="v11_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="v10_temp" schema="" table="v10_temp" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="v10_temp" +STMT: ViewStmt +STMT: SelectStmt +== 054 +CREATE VIEW v12_temp AS SELECT true FROM v11_temp +-- +TABLE: name="v12_temp" schema="" table="v12_temp" ctx=DDL +TABLE: name="v11_temp" schema="" table="v11_temp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 055 +-- a view should also be temporary if it references a temporary sequence +CREATE SEQUENCE seq1 +-- +STMT: CreateSeqStmt +== 056 +CREATE TEMPORARY SEQUENCE seq1_temp +-- +STMT: CreateSeqStmt +== 057 +CREATE VIEW v9 AS SELECT seq1.is_called FROM seq1 +-- +TABLE: name="v9" schema="" table="v9" ctx=DDL +TABLE: name="seq1" schema="" table="seq1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 058 +CREATE VIEW v13_temp AS SELECT seq1_temp.is_called FROM seq1_temp +-- +TABLE: name="v13_temp" schema="" table="v13_temp" ctx=DDL +TABLE: name="seq1_temp" schema="" table="seq1_temp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 059 +SELECT relname FROM pg_class + WHERE relname LIKE 'v_' + AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'temp_view_test') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 060 +SELECT relname FROM pg_class + WHERE relname LIKE 'v%' + AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp%') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 061 +CREATE SCHEMA testviewschm2 +-- +STMT: CreateSchemaStmt +== 062 +SET search_path TO testviewschm2, public +-- +STMT: VariableSetStmt +== 063 +CREATE TABLE t1 (num int, name text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 064 +CREATE TABLE t2 (num2 int, value text) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 065 +CREATE TEMP TABLE tt (num2 int, value text) +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: CreateStmt +== 066 +CREATE VIEW nontemp1 AS SELECT * FROM t1 CROSS JOIN t2 +-- +TABLE: name="nontemp1" schema="" table="nontemp1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 067 +CREATE VIEW temporal1 AS SELECT * FROM t1 CROSS JOIN tt +-- +TABLE: name="temporal1" schema="" table="temporal1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 068 +CREATE VIEW nontemp2 AS SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num2 +-- +TABLE: name="nontemp2" schema="" table="nontemp2" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 069 +CREATE VIEW temporal2 AS SELECT * FROM t1 INNER JOIN tt ON t1.num = tt.num2 +-- +TABLE: name="temporal2" schema="" table="temporal2" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 070 +CREATE VIEW nontemp3 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2 +-- +TABLE: name="nontemp3" schema="" table="nontemp3" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 071 +CREATE VIEW temporal3 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2 +-- +TABLE: name="temporal3" schema="" table="temporal3" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 072 +CREATE VIEW nontemp4 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2 AND t2.value = 'xxx' +-- +TABLE: name="nontemp4" schema="" table="nontemp4" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 073 +CREATE VIEW temporal4 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2 AND tt.value = 'xxx' +-- +TABLE: name="temporal4" schema="" table="temporal4" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 074 +SELECT relname FROM pg_class + WHERE relname LIKE 'nontemp%' + AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'testviewschm2') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 075 +SELECT relname FROM pg_class + WHERE relname LIKE 'temporal%' + AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp%') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 076 +CREATE TABLE tbl1 ( a int, b int) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DDL +STMT: CreateStmt +== 077 +CREATE TABLE tbl2 (c int, d int) +-- +TABLE: name="tbl2" schema="" table="tbl2" ctx=DDL +STMT: CreateStmt +== 078 +CREATE TABLE tbl3 (e int, f int) +-- +TABLE: name="tbl3" schema="" table="tbl3" ctx=DDL +STMT: CreateStmt +== 079 +CREATE TABLE tbl4 (g int, h int) +-- +TABLE: name="tbl4" schema="" table="tbl4" ctx=DDL +STMT: CreateStmt +== 080 +CREATE TEMP TABLE tmptbl (i int, j int) +-- +TABLE: name="tmptbl" schema="" table="tmptbl" ctx=DDL +STMT: CreateStmt +== 081 +--Should be in testviewschm2 +CREATE VIEW pubview AS SELECT * FROM tbl1 WHERE tbl1.a +BETWEEN (SELECT d FROM tbl2 WHERE c = 1) AND (SELECT e FROM tbl3 WHERE f = 2) +AND EXISTS (SELECT g FROM tbl4 LEFT JOIN tbl3 ON tbl4.h = tbl3.f) +-- +TABLE: name="pubview" schema="" table="pubview" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl2" schema="" table="tbl2" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +FILTER: schema="" table="tbl1" column="a" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="f" +STMT: ViewStmt +STMT: SelectStmt +== 082 +SELECT count(*) FROM pg_class where relname = 'pubview' +AND relnamespace IN (SELECT OID FROM pg_namespace WHERE nspname = 'testviewschm2') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 083 +--Should be in temp object schema +CREATE VIEW mytempview AS SELECT * FROM tbl1 WHERE tbl1.a +BETWEEN (SELECT d FROM tbl2 WHERE c = 1) AND (SELECT e FROM tbl3 WHERE f = 2) +AND EXISTS (SELECT g FROM tbl4 LEFT JOIN tbl3 ON tbl4.h = tbl3.f) +AND NOT EXISTS (SELECT g FROM tbl4 LEFT JOIN tmptbl ON tbl4.h = tmptbl.j) +-- +TABLE: name="mytempview" schema="" table="mytempview" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl2" schema="" table="tbl2" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tmptbl" schema="" table="tmptbl" ctx=Select +FILTER: schema="" table="tbl1" column="a" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="f" +STMT: ViewStmt +STMT: SelectStmt +== 084 +SELECT count(*) FROM pg_class where relname LIKE 'mytempview' +And relnamespace IN (SELECT OID FROM pg_namespace WHERE nspname LIKE 'pg_temp%') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 085 +|-- +-- CREATE VIEW and WITH(...) clause +|-- +CREATE VIEW mysecview1 + AS SELECT * FROM tbl1 WHERE a = 0 +-- +TABLE: name="mysecview1" schema="" table="mysecview1" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 086 +CREATE VIEW mysecview2 WITH (security_barrier=true) + AS SELECT * FROM tbl1 WHERE a > 0 +-- +TABLE: name="mysecview2" schema="" table="mysecview2" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 087 +CREATE VIEW mysecview3 WITH (security_barrier=false) + AS SELECT * FROM tbl1 WHERE a < 0 +-- +TABLE: name="mysecview3" schema="" table="mysecview3" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 088 +CREATE VIEW mysecview4 WITH (security_barrier) + AS SELECT * FROM tbl1 WHERE a <> 0 +-- +TABLE: name="mysecview4" schema="" table="mysecview4" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 089 +CREATE VIEW mysecview5 WITH (security_barrier=100) -- Error + AS SELECT * FROM tbl1 WHERE a > 100 +-- +TABLE: name="mysecview5" schema="" table="mysecview5" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 090 +CREATE VIEW mysecview6 WITH (invalid_option) -- Error + AS SELECT * FROM tbl1 WHERE a < 100 +-- +TABLE: name="mysecview6" schema="" table="mysecview6" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 091 +CREATE VIEW mysecview7 WITH (security_invoker=true) + AS SELECT * FROM tbl1 WHERE a = 100 +-- +TABLE: name="mysecview7" schema="" table="mysecview7" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 092 +CREATE VIEW mysecview8 WITH (security_invoker=false, security_barrier=true) + AS SELECT * FROM tbl1 WHERE a > 100 +-- +TABLE: name="mysecview8" schema="" table="mysecview8" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 093 +CREATE VIEW mysecview9 WITH (security_invoker) + AS SELECT * FROM tbl1 WHERE a < 100 +-- +TABLE: name="mysecview9" schema="" table="mysecview9" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 094 +CREATE VIEW mysecview10 WITH (security_invoker=100) -- Error + AS SELECT * FROM tbl1 WHERE a <> 100 +-- +TABLE: name="mysecview10" schema="" table="mysecview10" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 095 +SELECT relname, relkind, reloptions FROM pg_class + WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, + 'mysecview3'::regclass, 'mysecview4'::regclass, + 'mysecview7'::regclass, 'mysecview8'::regclass, + 'mysecview9'::regclass) + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 096 +CREATE OR REPLACE VIEW mysecview1 + AS SELECT * FROM tbl1 WHERE a = 256 +-- +TABLE: name="mysecview1" schema="" table="mysecview1" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 097 +CREATE OR REPLACE VIEW mysecview2 + AS SELECT * FROM tbl1 WHERE a > 256 +-- +TABLE: name="mysecview2" schema="" table="mysecview2" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 098 +CREATE OR REPLACE VIEW mysecview3 WITH (security_barrier=true) + AS SELECT * FROM tbl1 WHERE a < 256 +-- +TABLE: name="mysecview3" schema="" table="mysecview3" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 099 +CREATE OR REPLACE VIEW mysecview4 WITH (security_barrier=false) + AS SELECT * FROM tbl1 WHERE a <> 256 +-- +TABLE: name="mysecview4" schema="" table="mysecview4" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 100 +CREATE OR REPLACE VIEW mysecview7 + AS SELECT * FROM tbl1 WHERE a > 256 +-- +TABLE: name="mysecview7" schema="" table="mysecview7" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 101 +CREATE OR REPLACE VIEW mysecview8 WITH (security_invoker=true) + AS SELECT * FROM tbl1 WHERE a < 256 +-- +TABLE: name="mysecview8" schema="" table="mysecview8" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 102 +CREATE OR REPLACE VIEW mysecview9 WITH (security_invoker=false, security_barrier=true) + AS SELECT * FROM tbl1 WHERE a <> 256 +-- +TABLE: name="mysecview9" schema="" table="mysecview9" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 103 +SELECT relname, relkind, reloptions FROM pg_class + WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, + 'mysecview3'::regclass, 'mysecview4'::regclass, + 'mysecview7'::regclass, 'mysecview8'::regclass, + 'mysecview9'::regclass) + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 104 +-- Check that unknown literals are converted to "text" in CREATE VIEW, +-- so that we don't end up with unknown-type columns. + +CREATE VIEW unspecified_types AS + SELECT 42 as i, 42.5 as num, 'foo' as u, 'foo'::unknown as u2, null as n +-- +TABLE: name="unspecified_types" schema="" table="unspecified_types" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 105 +SELECT * FROM unspecified_types +-- +TABLE: name="unspecified_types" schema="" table="unspecified_types" ctx=Select +STMT: SelectStmt +== 106 +-- This test checks that proper typmods are assigned in a multi-row VALUES + +CREATE VIEW tt1 AS + SELECT * FROM ( + VALUES + ('abc'::varchar(3), '0123456789', 42, 'abcd'::varchar(4)), + ('0123456789', 'abc'::varchar(3), 42.12, 'abc'::varchar(4)) + ) vv(a,b,c,d) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 107 +SELECT * FROM tt1 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: SelectStmt +== 108 +SELECT a::varchar(3) FROM tt1 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: SelectStmt +== 109 +DROP VIEW tt1 +-- +STMT: DropStmt +== 110 +-- Test view decompilation in the face of relation renaming conflicts + +CREATE TABLE tt1 (f1 int, f2 int, f3 text) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +== 111 +CREATE TABLE tx1 (x1 int, x2 int, x3 text) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +== 112 +CREATE TABLE temp_view_test.tt1 (y1 int, f2 int, f3 text) +-- +TABLE: name="temp_view_test.tt1" schema="temp_view_test" table="tt1" ctx=DDL +STMT: CreateStmt +== 113 +CREATE VIEW aliased_view_1 AS + select * from tt1 + where exists (select 1 from tx1 where tt1.f1 = tx1.x1) +-- +TABLE: name="aliased_view_1" schema="" table="aliased_view_1" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tx1" schema="" table="tx1" ctx=Select +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="tx1" column="x1" +STMT: ViewStmt +STMT: SelectStmt +== 114 +CREATE VIEW aliased_view_2 AS + select * from tt1 a1 + where exists (select 1 from tx1 where a1.f1 = tx1.x1) +-- +TABLE: name="aliased_view_2" schema="" table="aliased_view_2" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tx1" schema="" table="tx1" ctx=Select +ALIAS: "a1"="tt1" +FILTER: schema="" table="a1" column="f1" +FILTER: schema="" table="tx1" column="x1" +STMT: ViewStmt +STMT: SelectStmt +== 115 +CREATE VIEW aliased_view_3 AS + select * from tt1 + where exists (select 1 from tx1 a2 where tt1.f1 = a2.x1) +-- +TABLE: name="aliased_view_3" schema="" table="aliased_view_3" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tx1" schema="" table="tx1" ctx=Select +ALIAS: "a2"="tx1" +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="a2" column="x1" +STMT: ViewStmt +STMT: SelectStmt +== 116 +CREATE VIEW aliased_view_4 AS + select * from temp_view_test.tt1 + where exists (select 1 from tt1 where temp_view_test.tt1.y1 = tt1.f1) +-- +TABLE: name="aliased_view_4" schema="" table="aliased_view_4" ctx=DDL +TABLE: name="temp_view_test.tt1" schema="temp_view_test" table="tt1" ctx=Select +TABLE: name="tt1" schema="" table="tt1" ctx=Select +FILTER: schema="temp_view_test" table="tt1" column="y1" +FILTER: schema="" table="tt1" column="f1" +STMT: ViewStmt +STMT: SelectStmt +== 117 +ALTER TABLE tx1 RENAME TO a1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +TABLE: name="a1" schema="" table="a1" ctx=DDL +STMT: RenameStmt +== 118 +ALTER TABLE tt1 RENAME TO a2 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +TABLE: name="a2" schema="" table="a2" ctx=DDL +STMT: RenameStmt +== 119 +ALTER TABLE a1 RENAME TO tt1 +-- +TABLE: name="a1" schema="" table="a1" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: RenameStmt +== 120 +ALTER TABLE a2 RENAME TO tx1 +-- +TABLE: name="a2" schema="" table="a2" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: RenameStmt +== 121 +ALTER TABLE tx1 SET SCHEMA temp_view_test +-- +STMT: AlterObjectSchemaStmt +== 122 +ALTER TABLE temp_view_test.tt1 RENAME TO tmp1 +-- +TABLE: name="temp_view_test.tt1" schema="temp_view_test" table="tt1" ctx=DDL +TABLE: name="temp_view_test.tmp1" schema="temp_view_test" table="tmp1" ctx=DDL +STMT: RenameStmt +== 123 +ALTER TABLE temp_view_test.tmp1 SET SCHEMA testviewschm2 +-- +STMT: AlterObjectSchemaStmt +== 124 +ALTER TABLE tmp1 RENAME TO tx1 +-- +TABLE: name="tmp1" schema="" table="tmp1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: RenameStmt +== 125 +-- Test correct deparsing of ORDER BY when there is an output name conflict + +create view aliased_order_by as +select x1 as x2, x2 as x1, x3 from tt1 + order by x2 +-- +TABLE: name="aliased_order_by" schema="" table="aliased_order_by" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 126 +-- this is interpreted per SQL92, so really ordering by x1 + + +alter view aliased_order_by rename column x1 to x0 +-- +STMT: RenameStmt +== 127 +alter view aliased_order_by rename column x3 to x1 +-- +STMT: RenameStmt +== 128 +-- Test aliasing of joins + +create view view_of_joins as +select * from + (select * from (tbl1 cross join tbl2) same) ss, + (tbl3 cross join tbl4) same +-- +TABLE: name="view_of_joins" schema="" table="view_of_joins" ctx=DDL +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl2" schema="" table="tbl2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 129 +create table tbl1a (a int, c int) +-- +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=DDL +STMT: CreateStmt +== 130 +create view view_of_joins_2a as select * from tbl1 join tbl1a using (a) +-- +TABLE: name="view_of_joins_2a" schema="" table="view_of_joins_2a" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 131 +create view view_of_joins_2b as select * from tbl1 join tbl1a using (a) as x +-- +TABLE: name="view_of_joins_2b" schema="" table="view_of_joins_2b" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 132 +create view view_of_joins_2c as select * from (tbl1 join tbl1a using (a)) as y +-- +TABLE: name="view_of_joins_2c" schema="" table="view_of_joins_2c" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 133 +create view view_of_joins_2d as select * from (tbl1 join tbl1a using (a) as x) as y +-- +TABLE: name="view_of_joins_2d" schema="" table="view_of_joins_2d" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 134 +select pg_get_viewdef('view_of_joins_2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 135 +select pg_get_viewdef('view_of_joins_2b', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 136 +select pg_get_viewdef('view_of_joins_2c', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 137 +select pg_get_viewdef('view_of_joins_2d', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 138 +-- Test view decompilation in the face of column addition/deletion/renaming + +create table tt2 (a int, b int, c int) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +== 139 +create table tt3 (ax int8, b int2, c numeric) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +== 140 +create table tt4 (ay int, b int, q int) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: CreateStmt +== 141 +create view v1 as select * from tt2 natural join tt3 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 142 +create view v1a as select * from (tt2 natural join tt3) j +-- +TABLE: name="v1a" schema="" table="v1a" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 143 +create view v2 as select * from tt2 join tt3 using (b,c) join tt4 using (b) +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt4" schema="" table="tt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 144 +create view v2a as select * from (tt2 join tt3 using (b,c) join tt4 using (b)) j +-- +TABLE: name="v2a" schema="" table="v2a" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt4" schema="" table="tt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 145 +create view v3 as select * from tt2 join tt3 using (b,c) full join tt4 using (b) +-- +TABLE: name="v3" schema="" table="v3" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt4" schema="" table="tt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 146 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 147 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 148 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 149 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 150 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 151 +alter table tt2 add column d int +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +== 152 +alter table tt2 add column e int +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +== 153 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 154 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 155 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 156 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 157 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 158 +alter table tt3 rename c to d +-- +STMT: RenameStmt +== 159 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 160 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 161 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 162 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 163 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 164 +alter table tt3 add column c int +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: AlterTableStmt +== 165 +alter table tt3 add column e int +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: AlterTableStmt +== 166 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 167 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 168 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 169 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 170 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 171 +alter table tt2 drop column d +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +== 172 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 173 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 174 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 175 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 176 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 177 +create table tt5 (a int, b int) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: CreateStmt +== 178 +create table tt6 (c int, d int) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: CreateStmt +== 179 +create view vv1 as select * from (tt5 cross join tt6) j(aa,bb,cc,dd) +-- +TABLE: name="vv1" schema="" table="vv1" ctx=DDL +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 180 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 181 +alter table tt5 add column c int +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +== 182 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 183 +alter table tt5 add column cc int +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +== 184 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 185 +alter table tt5 drop column c +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +== 186 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 187 +create view v4 as select * from v1 +-- +TABLE: name="v4" schema="" table="v4" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 188 +alter view v1 rename column a to x +-- +STMT: RenameStmt +== 189 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 190 +select pg_get_viewdef('v4', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 191 +-- Unnamed FULL JOIN USING is lots of fun too + +create table tt7 (x int, xx int, y int) +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: CreateStmt +== 192 +alter table tt7 drop column xx +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 193 +create table tt8 (x int, z int) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: CreateStmt +== 194 +create view vv2 as +select * from (values(1,2,3,4,5)) v(a,b,c,d,e) +union all +select * from tt7 full join tt8 using (x), tt8 tt8x +-- +TABLE: name="vv2" schema="" table="vv2" ctx=DDL +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +ALIAS: "tt8x"="tt8" +STMT: ViewStmt +STMT: SelectStmt +== 195 +select pg_get_viewdef('vv2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 196 +create view vv3 as +select * from (values(1,2,3,4,5,6)) v(a,b,c,x,e,f) +union all +select * from + tt7 full join tt8 using (x), + tt7 tt7x full join tt8 tt8x using (x) +-- +TABLE: name="vv3" schema="" table="vv3" ctx=DDL +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +ALIAS: "tt7x"="tt7" +ALIAS: "tt8x"="tt8" +STMT: ViewStmt +STMT: SelectStmt +== 197 +select pg_get_viewdef('vv3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 198 +create view vv4 as +select * from (values(1,2,3,4,5,6,7)) v(a,b,c,x,e,f,g) +union all +select * from + tt7 full join tt8 using (x), + tt7 tt7x full join tt8 tt8x using (x) full join tt8 tt8y using (x) +-- +TABLE: name="vv4" schema="" table="vv4" ctx=DDL +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +ALIAS: "tt7x"="tt7" +ALIAS: "tt8x"="tt8" +ALIAS: "tt8y"="tt8" +STMT: ViewStmt +STMT: SelectStmt +== 199 +select pg_get_viewdef('vv4', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 200 +alter table tt7 add column zz int +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 201 +alter table tt7 add column z int +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 202 +alter table tt7 drop column zz +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +== 203 +alter table tt8 add column z2 int +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +== 204 +select pg_get_viewdef('vv2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 205 +select pg_get_viewdef('vv3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 206 +select pg_get_viewdef('vv4', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 207 +-- Implicit coercions in a JOIN USING create issues similar to FULL JOIN + +create table tt7a (x date, xx int, y int) +-- +TABLE: name="tt7a" schema="" table="tt7a" ctx=DDL +STMT: CreateStmt +== 208 +alter table tt7a drop column xx +-- +TABLE: name="tt7a" schema="" table="tt7a" ctx=DDL +STMT: AlterTableStmt +== 209 +create table tt8a (x timestamptz, z int) +-- +TABLE: name="tt8a" schema="" table="tt8a" ctx=DDL +STMT: CreateStmt +== 210 +create view vv2a as +select * from (values(now(),2,3,now(),5)) v(a,b,c,d,e) +union all +select * from tt7a left join tt8a using (x), tt8a tt8ax +-- +TABLE: name="vv2a" schema="" table="vv2a" ctx=DDL +TABLE: name="tt7a" schema="" table="tt7a" ctx=Select +TABLE: name="tt8a" schema="" table="tt8a" ctx=Select +TABLE: name="tt8a" schema="" table="tt8a" ctx=Select +ALIAS: "tt8ax"="tt8a" +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 211 +select pg_get_viewdef('vv2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 212 +|-- +-- Also check dropping a column that existed when the view was made +|-- + +create table tt9 (x int, xx int, y int) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: CreateStmt +== 213 +create table tt10 (x int, z int) +-- +TABLE: name="tt10" schema="" table="tt10" ctx=DDL +STMT: CreateStmt +== 214 +create view vv5 as select x,y,z from tt9 join tt10 using(x) +-- +TABLE: name="vv5" schema="" table="vv5" ctx=DDL +TABLE: name="tt9" schema="" table="tt9" ctx=Select +TABLE: name="tt10" schema="" table="tt10" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 215 +select pg_get_viewdef('vv5', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 216 +alter table tt9 drop column xx +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +== 217 +select pg_get_viewdef('vv5', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 218 +|-- +-- Another corner case is that we might add a column to a table below a +-- JOIN USING, and thereby make the USING column name ambiguous +|-- + +create table tt11 (x int, y int) +-- +TABLE: name="tt11" schema="" table="tt11" ctx=DDL +STMT: CreateStmt +== 219 +create table tt12 (x int, z int) +-- +TABLE: name="tt12" schema="" table="tt12" ctx=DDL +STMT: CreateStmt +== 220 +create table tt13 (z int, q int) +-- +TABLE: name="tt13" schema="" table="tt13" ctx=DDL +STMT: CreateStmt +== 221 +create view vv6 as select x,y,z,q from + (tt11 join tt12 using(x)) join tt13 using(z) +-- +TABLE: name="vv6" schema="" table="vv6" ctx=DDL +TABLE: name="tt11" schema="" table="tt11" ctx=Select +TABLE: name="tt12" schema="" table="tt12" ctx=Select +TABLE: name="tt13" schema="" table="tt13" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 222 +select pg_get_viewdef('vv6', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 223 +alter table tt11 add column z int +-- +TABLE: name="tt11" schema="" table="tt11" ctx=DDL +STMT: AlterTableStmt +== 224 +select pg_get_viewdef('vv6', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 225 +|-- +-- Check cases involving dropped/altered columns in a function's rowtype result +|-- + +create table tt14t (f1 text, f2 text, f3 text, f4 text) +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: CreateStmt +== 226 +insert into tt14t values('foo', 'bar', 'baz', '42') +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 227 +alter table tt14t drop column f2 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +== 228 +create function tt14f() returns setof tt14t as +$$ +declare + rec1 record; +begin + for rec1 in select * from tt14t + loop + return next rec1; + end loop; +end; +$$ +language plpgsql +-- +FUNCTION: name="tt14f" function="tt14f" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 229 +create view tt14v as select t.* from tt14f() t +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=DDL +FUNCTION: name="tt14f" function="tt14f" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 230 +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 231 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +== 232 +alter table tt14t drop column f3 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +== 233 +-- fail, view has explicit reference to f3 + +-- We used to have a bug that would allow the above to succeed, posing +-- hazards for later execution of the view. Check that the internal +-- defenses for those hazards haven't bit-rotted, in case some other +-- bug with similar symptoms emerges. +begin +-- +STMT: TransactionStmt +== 234 +-- destroy the dependency entry that prevents the DROP: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'tt14v'::regclass and rulename = '_RETURN') + and refobjsubid = 3 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +== 235 +-- this will now succeed: +alter table tt14t drop column f3 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +== 236 +-- column f3 is still in the view, sort of ... +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 237 +-- ... and you can even EXPLAIN it ... +explain (verbose, costs off) select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 238 +-- but it will fail at execution +select f1, f4 from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +== 239 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +== 240 +rollback +-- +STMT: TransactionStmt +== 241 +-- likewise, altering a referenced column's type is prohibited ... +alter table tt14t alter column f4 type integer using f4::integer +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +== 242 +-- fail + +-- ... but some bug might let it happen, so check defenses +begin +-- +STMT: TransactionStmt +== 243 +-- destroy the dependency entry that prevents the ALTER: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'tt14v'::regclass and rulename = '_RETURN') + and refobjsubid = 4 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +== 244 +-- this will now succeed: +alter table tt14t alter column f4 type integer using f4::integer +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +== 245 +-- f4 is still in the view ... +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 246 +-- but will fail at execution +select f1, f3 from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +== 247 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +== 248 +rollback +-- +STMT: TransactionStmt +== 249 +drop view tt14v +-- +STMT: DropStmt +== 250 +create view tt14v as select t.f1, t.f4 from tt14f() t +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=DDL +FUNCTION: name="tt14f" function="tt14f" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 251 +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 252 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +== 253 +alter table tt14t drop column f3 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +== 254 +-- ok + +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 255 +explain (verbose, costs off) select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 256 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +== 257 +-- check display of whole-row variables in some corner cases + +create type nestedcomposite as (x int8_tbl) +-- +STMT: CompositeTypeStmt +== 258 +create view tt15v as select row(i)::nestedcomposite from int8_tbl i +-- +TABLE: name="tt15v" schema="" table="tt15v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: ViewStmt +STMT: SelectStmt +== 259 +select * from tt15v +-- +TABLE: name="tt15v" schema="" table="tt15v" ctx=Select +STMT: SelectStmt +== 260 +select pg_get_viewdef('tt15v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 261 +select row(i.*::int8_tbl)::nestedcomposite from int8_tbl i +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: SelectStmt +== 262 +create view tt16v as select * from int8_tbl i, lateral(values(i)) ss +-- +TABLE: name="tt16v" schema="" table="tt16v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: ViewStmt +STMT: SelectStmt +== 263 +select * from tt16v +-- +TABLE: name="tt16v" schema="" table="tt16v" ctx=Select +STMT: SelectStmt +== 264 +select pg_get_viewdef('tt16v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 265 +select * from int8_tbl i, lateral(values(i.*::int8_tbl)) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: SelectStmt +== 266 +create view tt17v as select * from int8_tbl i where i in (values(i)) +-- +TABLE: name="tt17v" schema="" table="tt17v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +FILTER: schema="" table="" column="i" +STMT: ViewStmt +STMT: SelectStmt +== 267 +select * from tt17v +-- +TABLE: name="tt17v" schema="" table="tt17v" ctx=Select +STMT: SelectStmt +== 268 +select pg_get_viewdef('tt17v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 269 +select * from int8_tbl i where i.* in (values(i.*::int8_tbl)) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: SelectStmt +== 270 +create table tt15v_log(o tt15v, n tt15v, incr bool) +-- +TABLE: name="tt15v_log" schema="" table="tt15v_log" ctx=DDL +STMT: CreateStmt +== 271 +create rule updlog as on update to tt15v do also + insert into tt15v_log values(old, new, row(old,old) < row(new,new)) +-- +TABLE: name="tt15v" schema="" table="tt15v" ctx=DDL +STMT: RuleStmt +== 272 +-- check unique-ification of overlength names + +create view tt18v as + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy + union all + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz +-- +TABLE: name="tt18v" schema="" table="tt18v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"="int8_tbl" +STMT: ViewStmt +STMT: SelectStmt +== 273 +select pg_get_viewdef('tt18v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 274 +explain (costs off) select * from tt18v +-- +TABLE: name="tt18v" schema="" table="tt18v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 275 +-- check display of ScalarArrayOp with a sub-select + +select 'foo'::text = any(array['abc','def','foo']::text[]) +-- +STMT: SelectStmt +== 276 +select 'foo'::text = any((select array['abc','def','foo']::text[])) +-- +STMT: SelectStmt +== 277 +-- fail +select 'foo'::text = any((select array['abc','def','foo']::text[])::text[]) +-- +STMT: SelectStmt +== 278 +create view tt19v as +select 'foo'::text = any(array['abc','def','foo']::text[]) c1, + 'foo'::text = any((select array['abc','def','foo']::text[])::text[]) c2 +-- +TABLE: name="tt19v" schema="" table="tt19v" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 279 +select pg_get_viewdef('tt19v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 280 +-- check display of assorted RTE_FUNCTION expressions + +create view tt20v as +select * from + coalesce(1,2) as c, + collation for ('x'::text) col, + current_date as d, + localtimestamp(3) as t, + cast(1+2 as int4) as i4, + cast(1+2 as int8) as i8 +-- +TABLE: name="tt20v" schema="" table="tt20v" ctx=DDL +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 281 +select pg_get_viewdef('tt20v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 282 +-- reverse-listing of various special function syntaxes required by SQL + +create view tt201v as +select + ('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz, + extract(day from now()) as extr, + (now(), '1 day'::interval) overlaps + (current_timestamp(2), '1 day'::interval) as o, + 'foo' is normalized isn, + 'foo' is nfkc normalized isnn, + normalize('foo') as n, + normalize('foo', nfkd) as nfkd, + overlay('foo' placing 'bar' from 2) as ovl, + overlay('foo' placing 'bar' from 2 for 3) as ovl2, + position('foo' in 'foobar') as p, + substring('foo' from 2 for 3) as s, + substring('foo' similar 'f' escape '#') as ss, + substring('foo' from 'oo') as ssf, -- historically-permitted abuse + trim(' ' from ' foo ') as bt, + trim(leading ' ' from ' foo ') as lt, + trim(trailing ' foo ') as rt, + trim(E'\\000'::bytea from E'\\000Tom\\000'::bytea) as btb, + trim(leading E'\\000'::bytea from E'\\000Tom\\000'::bytea) as ltb, + trim(trailing E'\\000'::bytea from E'\\000Tom\\000'::bytea) as rtb, + CURRENT_DATE as cd, + (select * from CURRENT_DATE) as cd2, + CURRENT_TIME as ct, + (select * from CURRENT_TIME) as ct2, + CURRENT_TIME (1) as ct3, + (select * from CURRENT_TIME (1)) as ct4, + CURRENT_TIMESTAMP as ct5, + (select * from CURRENT_TIMESTAMP) as ct6, + CURRENT_TIMESTAMP (1) as ct7, + (select * from CURRENT_TIMESTAMP (1)) as ct8, + LOCALTIME as lt1, + (select * from LOCALTIME) as lt2, + LOCALTIME (1) as lt3, + (select * from LOCALTIME (1)) as lt4, + LOCALTIMESTAMP as lt5, + (select * from LOCALTIMESTAMP) as lt6, + LOCALTIMESTAMP (1) as lt7, + (select * from LOCALTIMESTAMP (1)) as lt8, + CURRENT_CATALOG as ca, + (select * from CURRENT_CATALOG) as ca2, + CURRENT_ROLE as cr, + (select * from CURRENT_ROLE) as cr2, + CURRENT_SCHEMA as cs, + (select * from CURRENT_SCHEMA) as cs2, + CURRENT_USER as cu, + (select * from CURRENT_USER) as cu2, + USER as us, + (select * from USER) as us2, + SESSION_USER seu, + (select * from SESSION_USER) as seu2, + SYSTEM_USER as su, + (select * from SYSTEM_USER) as su2 +-- +TABLE: name="tt201v" schema="" table="tt201v" ctx=DDL +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.btrim" function="btrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.ltrim" function="ltrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.rtrim" function="rtrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.btrim" function="btrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.ltrim" function="ltrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.rtrim" function="rtrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.system_user" function="system_user" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.system_user" function="system_user" schema="pg_catalog" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 283 +select pg_get_viewdef('tt201v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 284 +-- corner cases with empty join conditions + +create view tt21v as +select * from tt5 natural inner join tt6 +-- +TABLE: name="tt21v" schema="" table="tt21v" ctx=DDL +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 285 +select pg_get_viewdef('tt21v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 286 +create view tt22v as +select * from tt5 natural left join tt6 +-- +TABLE: name="tt22v" schema="" table="tt22v" ctx=DDL +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 287 +select pg_get_viewdef('tt22v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 288 +-- check handling of views with immediately-renamed columns + +create view tt23v (col_a, col_b) as +select q1 as other_name1, q2 as other_name2 from int8_tbl +union +select 42, 43 +-- +TABLE: name="tt23v" schema="" table="tt23v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 289 +select pg_get_viewdef('tt23v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 290 +select pg_get_ruledef(oid, true) from pg_rewrite + where ev_class = 'tt23v'::regclass and ev_type = '1' +-- +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_get_ruledef" function="pg_get_ruledef" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="ev_type" +STMT: SelectStmt +== 291 +-- test extraction of FieldSelect field names (get_name_for_var_field) + +create view tt24v as +with cte as materialized (select r from (values(1,2),(3,4)) r) +select (r).column2 as col_a, (rr).column2 as col_b from + cte join (select rr from (values(1,7),(3,8)) rr limit 2) ss + on (r).column1 = (rr).column1 +-- +TABLE: name="tt24v" schema="" table="tt24v" ctx=DDL +CTE: "cte" +STMT: ViewStmt +STMT: SelectStmt +== 292 +select pg_get_viewdef('tt24v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 293 +create view tt25v as +with cte as materialized (select pg_get_keywords() k) +select (k).word from cte +-- +TABLE: name="tt25v" schema="" table="tt25v" ctx=DDL +CTE: "cte" +FUNCTION: name="pg_get_keywords" function="pg_get_keywords" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 294 +select pg_get_viewdef('tt25v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 295 +-- also check cases seen only in EXPLAIN +explain (verbose, costs off) +select * from tt24v +-- +TABLE: name="tt24v" schema="" table="tt24v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 296 +explain (verbose, costs off) +select (r).column2 from (select r from (values(1,2),(3,4)) r limit 1) ss +-- +STMT: ExplainStmt +STMT: SelectStmt +== 297 +-- test pretty-print parenthesization rules, and SubLink deparsing + +create view tt26v as +select x + y + z as c1, + (x * y) + z as c2, + x + (y * z) as c3, + (x + y) * z as c4, + x * (y + z) as c5, + x + (y + z) as c6, + x + (y # z) as c7, + (x > y) AND (y > z OR x > z) as c8, + (x > y) OR (y > z AND NOT (x > z)) as c9, + (x,y) <> ALL (values(1,2),(3,4)) as c10, + (x,y) <= ANY (values(1,2),(3,4)) as c11 +from (values(1,2,3)) v(x,y,z) +-- +TABLE: name="tt26v" schema="" table="tt26v" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 298 +select pg_get_viewdef('tt26v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 299 +-- test restriction on non-system view expansion. +create table tt27v_tbl (a int) +-- +TABLE: name="tt27v_tbl" schema="" table="tt27v_tbl" ctx=DDL +STMT: CreateStmt +== 300 +create view tt27v as select a from tt27v_tbl +-- +TABLE: name="tt27v" schema="" table="tt27v" ctx=DDL +TABLE: name="tt27v_tbl" schema="" table="tt27v_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 301 +set restrict_nonsystem_relation_kind to 'view' +-- +STMT: VariableSetStmt +== 302 +select a from tt27v where a > 0 +-- +TABLE: name="tt27v" schema="" table="tt27v" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 303 +-- Error +insert into tt27v values (1) +-- +TABLE: name="tt27v" schema="" table="tt27v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 304 +-- Error +select viewname from pg_views where viewname = 'tt27v' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +== 305 +-- Ok to access a system view. +reset restrict_nonsystem_relation_kind +-- +STMT: VariableSetStmt +== 306 +-- clean up all the random objects we made above +DROP SCHEMA temp_view_test CASCADE +-- +STMT: DropStmt +== 307 +DROP SCHEMA testviewschm2 CASCADE +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/database.metadata.json b/parser/testdata/summary/postgres_regress/database.metadata.json new file mode 100644 index 0000000..e71b2c2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/database.metadata.json @@ -0,0 +1,20 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016" + ] +} diff --git a/parser/testdata/summary/postgres_regress/database.test b/parser/testdata/summary/postgres_regress/database.test new file mode 100644 index 0000000..8049198 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/database.test @@ -0,0 +1,72 @@ +== 001 +CREATE DATABASE regression_tbd + ENCODING utf8 LC_COLLATE "C" LC_CTYPE "C" TEMPLATE template0 +-- +STMT: CreatedbStmt +== 002 +ALTER DATABASE regression_tbd RENAME TO regression_utf8 +-- +STMT: RenameStmt +== 003 +ALTER DATABASE regression_utf8 SET TABLESPACE regress_tblspace +-- +STMT: AlterDatabaseStmt +== 004 +ALTER DATABASE regression_utf8 RESET TABLESPACE +-- +STMT: AlterDatabaseSetStmt +== 005 +ALTER DATABASE regression_utf8 CONNECTION_LIMIT 123 +-- +STMT: AlterDatabaseStmt +== 006 +-- Test PgDatabaseToastTable. Doing this with GRANT would be slow. +BEGIN +-- +STMT: TransactionStmt +== 007 +UPDATE pg_database +SET datacl = array_fill(makeaclitem(10, 10, 'USAGE', false), ARRAY[5e5::int]) +WHERE datname = 'regression_utf8' +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=DML +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +FUNCTION: name="makeaclitem" function="makeaclitem" schema="" ctx=Call +STMT: UpdateStmt +== 008 +-- load catcache entry, if nothing else does +ALTER DATABASE regression_utf8 RESET TABLESPACE +-- +STMT: AlterDatabaseSetStmt +== 009 +ROLLBACK +-- +STMT: TransactionStmt +== 010 +CREATE ROLE regress_datdba_before +-- +STMT: CreateRoleStmt +== 011 +CREATE ROLE regress_datdba_after +-- +STMT: CreateRoleStmt +== 012 +ALTER DATABASE regression_utf8 OWNER TO regress_datdba_before +-- +STMT: AlterOwnerStmt +== 013 +REASSIGN OWNED BY regress_datdba_before TO regress_datdba_after +-- +STMT: ReassignOwnedStmt +== 014 +DROP DATABASE regression_utf8 +-- +STMT: DropdbStmt +== 015 +DROP ROLE regress_datdba_before +-- +STMT: DropRoleStmt +== 016 +DROP ROLE regress_datdba_after +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/date.metadata.json b/parser/testdata/summary/postgres_regress/date.metadata.json new file mode 100644 index 0000000..a6ce2f7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/date.metadata.json @@ -0,0 +1,274 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270" + ] +} diff --git a/parser/testdata/summary/postgres_regress/date.test b/parser/testdata/summary/postgres_regress/date.test new file mode 100644 index 0000000..6829170 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/date.test @@ -0,0 +1,1362 @@ +== 001 +|-- +-- DATE +|-- + +CREATE TABLE DATE_TBL (f1 date) +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO DATE_TBL VALUES ('1957-04-09') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO DATE_TBL VALUES ('1957-06-13') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO DATE_TBL VALUES ('1996-02-28') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO DATE_TBL VALUES ('1996-02-29') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO DATE_TBL VALUES ('1996-03-01') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO DATE_TBL VALUES ('1996-03-02') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO DATE_TBL VALUES ('1997-02-28') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO DATE_TBL VALUES ('1997-02-29') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO DATE_TBL VALUES ('1997-03-01') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO DATE_TBL VALUES ('1997-03-02') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO DATE_TBL VALUES ('2000-04-01') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO DATE_TBL VALUES ('2000-04-02') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO DATE_TBL VALUES ('2000-04-03') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO DATE_TBL VALUES ('2038-04-08') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO DATE_TBL VALUES ('2039-04-09') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO DATE_TBL VALUES ('2040-04-10') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO DATE_TBL VALUES ('2040-04-10 BC') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +SELECT f1 FROM DATE_TBL +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +STMT: SelectStmt +== 020 +SELECT f1 FROM DATE_TBL WHERE f1 < '2000-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 021 +SELECT f1 FROM DATE_TBL + WHERE f1 BETWEEN '2000-01-01' AND '2001-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 022 +|-- +-- Check all the documented input formats +|-- +SET datestyle TO iso +-- +STMT: VariableSetStmt +== 023 +-- display results in ISO + +SET datestyle TO ymd +-- +STMT: VariableSetStmt +== 024 +SELECT date 'January 8, 1999' +-- +STMT: SelectStmt +== 025 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +== 026 +SELECT date '1999-01-18' +-- +STMT: SelectStmt +== 027 +SELECT date '1/8/1999' +-- +STMT: SelectStmt +== 028 +SELECT date '1/18/1999' +-- +STMT: SelectStmt +== 029 +SELECT date '18/1/1999' +-- +STMT: SelectStmt +== 030 +SELECT date '01/02/03' +-- +STMT: SelectStmt +== 031 +SELECT date '19990108' +-- +STMT: SelectStmt +== 032 +SELECT date '990108' +-- +STMT: SelectStmt +== 033 +SELECT date '1999.008' +-- +STMT: SelectStmt +== 034 +SELECT date 'J2451187' +-- +STMT: SelectStmt +== 035 +SELECT date 'January 8, 99 BC' +-- +STMT: SelectStmt +== 036 +SELECT date '99-Jan-08' +-- +STMT: SelectStmt +== 037 +SELECT date '1999-Jan-08' +-- +STMT: SelectStmt +== 038 +SELECT date '08-Jan-99' +-- +STMT: SelectStmt +== 039 +SELECT date '08-Jan-1999' +-- +STMT: SelectStmt +== 040 +SELECT date 'Jan-08-99' +-- +STMT: SelectStmt +== 041 +SELECT date 'Jan-08-1999' +-- +STMT: SelectStmt +== 042 +SELECT date '99-08-Jan' +-- +STMT: SelectStmt +== 043 +SELECT date '1999-08-Jan' +-- +STMT: SelectStmt +== 044 +SELECT date '99 Jan 08' +-- +STMT: SelectStmt +== 045 +SELECT date '1999 Jan 08' +-- +STMT: SelectStmt +== 046 +SELECT date '08 Jan 99' +-- +STMT: SelectStmt +== 047 +SELECT date '08 Jan 1999' +-- +STMT: SelectStmt +== 048 +SELECT date 'Jan 08 99' +-- +STMT: SelectStmt +== 049 +SELECT date 'Jan 08 1999' +-- +STMT: SelectStmt +== 050 +SELECT date '99 08 Jan' +-- +STMT: SelectStmt +== 051 +SELECT date '1999 08 Jan' +-- +STMT: SelectStmt +== 052 +SELECT date '99-01-08' +-- +STMT: SelectStmt +== 053 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +== 054 +SELECT date '08-01-99' +-- +STMT: SelectStmt +== 055 +SELECT date '08-01-1999' +-- +STMT: SelectStmt +== 056 +SELECT date '01-08-99' +-- +STMT: SelectStmt +== 057 +SELECT date '01-08-1999' +-- +STMT: SelectStmt +== 058 +SELECT date '99-08-01' +-- +STMT: SelectStmt +== 059 +SELECT date '1999-08-01' +-- +STMT: SelectStmt +== 060 +SELECT date '99 01 08' +-- +STMT: SelectStmt +== 061 +SELECT date '1999 01 08' +-- +STMT: SelectStmt +== 062 +SELECT date '08 01 99' +-- +STMT: SelectStmt +== 063 +SELECT date '08 01 1999' +-- +STMT: SelectStmt +== 064 +SELECT date '01 08 99' +-- +STMT: SelectStmt +== 065 +SELECT date '01 08 1999' +-- +STMT: SelectStmt +== 066 +SELECT date '99 08 01' +-- +STMT: SelectStmt +== 067 +SELECT date '1999 08 01' +-- +STMT: SelectStmt +== 068 +SET datestyle TO dmy +-- +STMT: VariableSetStmt +== 069 +SELECT date 'January 8, 1999' +-- +STMT: SelectStmt +== 070 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +== 071 +SELECT date '1999-01-18' +-- +STMT: SelectStmt +== 072 +SELECT date '1/8/1999' +-- +STMT: SelectStmt +== 073 +SELECT date '1/18/1999' +-- +STMT: SelectStmt +== 074 +SELECT date '18/1/1999' +-- +STMT: SelectStmt +== 075 +SELECT date '01/02/03' +-- +STMT: SelectStmt +== 076 +SELECT date '19990108' +-- +STMT: SelectStmt +== 077 +SELECT date '990108' +-- +STMT: SelectStmt +== 078 +SELECT date '1999.008' +-- +STMT: SelectStmt +== 079 +SELECT date 'J2451187' +-- +STMT: SelectStmt +== 080 +SELECT date 'January 8, 99 BC' +-- +STMT: SelectStmt +== 081 +SELECT date '99-Jan-08' +-- +STMT: SelectStmt +== 082 +SELECT date '1999-Jan-08' +-- +STMT: SelectStmt +== 083 +SELECT date '08-Jan-99' +-- +STMT: SelectStmt +== 084 +SELECT date '08-Jan-1999' +-- +STMT: SelectStmt +== 085 +SELECT date 'Jan-08-99' +-- +STMT: SelectStmt +== 086 +SELECT date 'Jan-08-1999' +-- +STMT: SelectStmt +== 087 +SELECT date '99-08-Jan' +-- +STMT: SelectStmt +== 088 +SELECT date '1999-08-Jan' +-- +STMT: SelectStmt +== 089 +SELECT date '99 Jan 08' +-- +STMT: SelectStmt +== 090 +SELECT date '1999 Jan 08' +-- +STMT: SelectStmt +== 091 +SELECT date '08 Jan 99' +-- +STMT: SelectStmt +== 092 +SELECT date '08 Jan 1999' +-- +STMT: SelectStmt +== 093 +SELECT date 'Jan 08 99' +-- +STMT: SelectStmt +== 094 +SELECT date 'Jan 08 1999' +-- +STMT: SelectStmt +== 095 +SELECT date '99 08 Jan' +-- +STMT: SelectStmt +== 096 +SELECT date '1999 08 Jan' +-- +STMT: SelectStmt +== 097 +SELECT date '99-01-08' +-- +STMT: SelectStmt +== 098 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +== 099 +SELECT date '08-01-99' +-- +STMT: SelectStmt +== 100 +SELECT date '08-01-1999' +-- +STMT: SelectStmt +== 101 +SELECT date '01-08-99' +-- +STMT: SelectStmt +== 102 +SELECT date '01-08-1999' +-- +STMT: SelectStmt +== 103 +SELECT date '99-08-01' +-- +STMT: SelectStmt +== 104 +SELECT date '1999-08-01' +-- +STMT: SelectStmt +== 105 +SELECT date '99 01 08' +-- +STMT: SelectStmt +== 106 +SELECT date '1999 01 08' +-- +STMT: SelectStmt +== 107 +SELECT date '08 01 99' +-- +STMT: SelectStmt +== 108 +SELECT date '08 01 1999' +-- +STMT: SelectStmt +== 109 +SELECT date '01 08 99' +-- +STMT: SelectStmt +== 110 +SELECT date '01 08 1999' +-- +STMT: SelectStmt +== 111 +SELECT date '99 08 01' +-- +STMT: SelectStmt +== 112 +SELECT date '1999 08 01' +-- +STMT: SelectStmt +== 113 +SET datestyle TO mdy +-- +STMT: VariableSetStmt +== 114 +SELECT date 'January 8, 1999' +-- +STMT: SelectStmt +== 115 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +== 116 +SELECT date '1999-01-18' +-- +STMT: SelectStmt +== 117 +SELECT date '1/8/1999' +-- +STMT: SelectStmt +== 118 +SELECT date '1/18/1999' +-- +STMT: SelectStmt +== 119 +SELECT date '18/1/1999' +-- +STMT: SelectStmt +== 120 +SELECT date '01/02/03' +-- +STMT: SelectStmt +== 121 +SELECT date '19990108' +-- +STMT: SelectStmt +== 122 +SELECT date '990108' +-- +STMT: SelectStmt +== 123 +SELECT date '1999.008' +-- +STMT: SelectStmt +== 124 +SELECT date 'J2451187' +-- +STMT: SelectStmt +== 125 +SELECT date 'January 8, 99 BC' +-- +STMT: SelectStmt +== 126 +SELECT date '99-Jan-08' +-- +STMT: SelectStmt +== 127 +SELECT date '1999-Jan-08' +-- +STMT: SelectStmt +== 128 +SELECT date '08-Jan-99' +-- +STMT: SelectStmt +== 129 +SELECT date '08-Jan-1999' +-- +STMT: SelectStmt +== 130 +SELECT date 'Jan-08-99' +-- +STMT: SelectStmt +== 131 +SELECT date 'Jan-08-1999' +-- +STMT: SelectStmt +== 132 +SELECT date '99-08-Jan' +-- +STMT: SelectStmt +== 133 +SELECT date '1999-08-Jan' +-- +STMT: SelectStmt +== 134 +SELECT date '99 Jan 08' +-- +STMT: SelectStmt +== 135 +SELECT date '1999 Jan 08' +-- +STMT: SelectStmt +== 136 +SELECT date '08 Jan 99' +-- +STMT: SelectStmt +== 137 +SELECT date '08 Jan 1999' +-- +STMT: SelectStmt +== 138 +SELECT date 'Jan 08 99' +-- +STMT: SelectStmt +== 139 +SELECT date 'Jan 08 1999' +-- +STMT: SelectStmt +== 140 +SELECT date '99 08 Jan' +-- +STMT: SelectStmt +== 141 +SELECT date '1999 08 Jan' +-- +STMT: SelectStmt +== 142 +SELECT date '99-01-08' +-- +STMT: SelectStmt +== 143 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +== 144 +SELECT date '08-01-99' +-- +STMT: SelectStmt +== 145 +SELECT date '08-01-1999' +-- +STMT: SelectStmt +== 146 +SELECT date '01-08-99' +-- +STMT: SelectStmt +== 147 +SELECT date '01-08-1999' +-- +STMT: SelectStmt +== 148 +SELECT date '99-08-01' +-- +STMT: SelectStmt +== 149 +SELECT date '1999-08-01' +-- +STMT: SelectStmt +== 150 +SELECT date '99 01 08' +-- +STMT: SelectStmt +== 151 +SELECT date '1999 01 08' +-- +STMT: SelectStmt +== 152 +SELECT date '08 01 99' +-- +STMT: SelectStmt +== 153 +SELECT date '08 01 1999' +-- +STMT: SelectStmt +== 154 +SELECT date '01 08 99' +-- +STMT: SelectStmt +== 155 +SELECT date '01 08 1999' +-- +STMT: SelectStmt +== 156 +SELECT date '99 08 01' +-- +STMT: SelectStmt +== 157 +SELECT date '1999 08 01' +-- +STMT: SelectStmt +== 158 +-- Check upper and lower limits of date range +SELECT date '4714-11-24 BC' +-- +STMT: SelectStmt +== 159 +SELECT date '4714-11-23 BC' +-- +STMT: SelectStmt +== 160 +-- out of range +SELECT date '5874897-12-31' +-- +STMT: SelectStmt +== 161 +SELECT date '5874898-01-01' +-- +STMT: SelectStmt +== 162 +-- out of range + +-- Test non-error-throwing API +SELECT pg_input_is_valid('now', 'date') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 163 +SELECT pg_input_is_valid('garbage', 'date') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 164 +SELECT pg_input_is_valid('6874898-01-01', 'date') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 165 +SELECT * FROM pg_input_error_info('garbage', 'date') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 166 +SELECT * FROM pg_input_error_info('6874898-01-01', 'date') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 167 +RESET datestyle +-- +STMT: VariableSetStmt +== 168 +|-- +-- Simple math +-- Leave most of it for the horology tests +|-- + +SELECT f1 - date '2000-01-01' AS "Days From 2K" FROM DATE_TBL +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +STMT: SelectStmt +== 169 +SELECT f1 - date 'epoch' AS "Days From Epoch" FROM DATE_TBL +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +STMT: SelectStmt +== 170 +SELECT date 'yesterday' - date 'today' AS "One day" +-- +STMT: SelectStmt +== 171 +SELECT date 'today' - date 'tomorrow' AS "One day" +-- +STMT: SelectStmt +== 172 +SELECT date 'yesterday' - date 'tomorrow' AS "Two days" +-- +STMT: SelectStmt +== 173 +SELECT date 'tomorrow' - date 'today' AS "One day" +-- +STMT: SelectStmt +== 174 +SELECT date 'today' - date 'yesterday' AS "One day" +-- +STMT: SelectStmt +== 175 +SELECT date 'tomorrow' - date 'yesterday' AS "Two days" +-- +STMT: SelectStmt +== 176 +|-- +-- test extract! +|-- +SELECT f1 as "date", + date_part('year', f1) AS year, + date_part('month', f1) AS month, + date_part('day', f1) AS day, + date_part('quarter', f1) AS quarter, + date_part('decade', f1) AS decade, + date_part('century', f1) AS century, + date_part('millennium', f1) AS millennium, + date_part('isoyear', f1) AS isoyear, + date_part('week', f1) AS week, + date_part('dow', f1) AS dow, + date_part('isodow', f1) AS isodow, + date_part('doy', f1) AS doy, + date_part('julian', f1) AS julian, + date_part('epoch', f1) AS epoch + FROM date_tbl +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 177 +|-- +-- epoch +|-- +SELECT EXTRACT(EPOCH FROM DATE '1970-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 178 +-- 0 +|-- +-- century +|-- +SELECT EXTRACT(CENTURY FROM DATE '0101-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 179 +-- -2 +SELECT EXTRACT(CENTURY FROM DATE '0100-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 180 +-- -1 +SELECT EXTRACT(CENTURY FROM DATE '0001-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 181 +-- -1 +SELECT EXTRACT(CENTURY FROM DATE '0001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 182 +-- 1 +SELECT EXTRACT(CENTURY FROM DATE '0001-01-01 AD') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 183 +-- 1 +SELECT EXTRACT(CENTURY FROM DATE '1900-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 184 +-- 19 +SELECT EXTRACT(CENTURY FROM DATE '1901-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 185 +-- 20 +SELECT EXTRACT(CENTURY FROM DATE '2000-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 186 +-- 20 +SELECT EXTRACT(CENTURY FROM DATE '2001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 187 +-- 21 +SELECT EXTRACT(CENTURY FROM CURRENT_DATE)>=21 AS True +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 188 +-- true +|-- +-- millennium +|-- +SELECT EXTRACT(MILLENNIUM FROM DATE '0001-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 189 +-- -1 +SELECT EXTRACT(MILLENNIUM FROM DATE '0001-01-01 AD') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 190 +-- 1 +SELECT EXTRACT(MILLENNIUM FROM DATE '1000-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 191 +-- 1 +SELECT EXTRACT(MILLENNIUM FROM DATE '1001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 192 +-- 2 +SELECT EXTRACT(MILLENNIUM FROM DATE '2000-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 193 +-- 2 +SELECT EXTRACT(MILLENNIUM FROM DATE '2001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 194 +-- 3 +-- next test to be fixed on the turn of the next millennium;-) +SELECT EXTRACT(MILLENNIUM FROM CURRENT_DATE) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 195 +-- 3 +|-- +-- decade +|-- +SELECT EXTRACT(DECADE FROM DATE '1994-12-25') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 196 +-- 199 +SELECT EXTRACT(DECADE FROM DATE '0010-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 197 +-- 1 +SELECT EXTRACT(DECADE FROM DATE '0009-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 198 +-- 0 +SELECT EXTRACT(DECADE FROM DATE '0001-01-01 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 199 +-- 0 +SELECT EXTRACT(DECADE FROM DATE '0002-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 200 +-- -1 +SELECT EXTRACT(DECADE FROM DATE '0011-01-01 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 201 +-- -1 +SELECT EXTRACT(DECADE FROM DATE '0012-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 202 +-- -2 +|-- +-- all possible fields +|-- +SELECT EXTRACT(MICROSECONDS FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 203 +SELECT EXTRACT(MILLISECONDS FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 204 +SELECT EXTRACT(SECOND FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 205 +SELECT EXTRACT(MINUTE FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 206 +SELECT EXTRACT(HOUR FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 207 +SELECT EXTRACT(DAY FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 208 +SELECT EXTRACT(MONTH FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 209 +SELECT EXTRACT(YEAR FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 210 +SELECT EXTRACT(YEAR FROM DATE '2020-08-11 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 211 +SELECT EXTRACT(DECADE FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 212 +SELECT EXTRACT(CENTURY FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 213 +SELECT EXTRACT(MILLENNIUM FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 214 +SELECT EXTRACT(ISOYEAR FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 215 +SELECT EXTRACT(ISOYEAR FROM DATE '2020-08-11 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 216 +SELECT EXTRACT(QUARTER FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 217 +SELECT EXTRACT(WEEK FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 218 +SELECT EXTRACT(DOW FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 219 +SELECT EXTRACT(DOW FROM DATE '2020-08-16') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 220 +SELECT EXTRACT(ISODOW FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 221 +SELECT EXTRACT(ISODOW FROM DATE '2020-08-16') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 222 +SELECT EXTRACT(DOY FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 223 +SELECT EXTRACT(TIMEZONE FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 224 +SELECT EXTRACT(TIMEZONE_M FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 225 +SELECT EXTRACT(TIMEZONE_H FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 226 +SELECT EXTRACT(EPOCH FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 227 +SELECT EXTRACT(JULIAN FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 228 +|-- +-- test trunc function! +|-- +SELECT DATE_TRUNC('MILLENNIUM', TIMESTAMP '1970-03-20 04:30:00.00000') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 229 +-- 1001 +SELECT DATE_TRUNC('MILLENNIUM', DATE '1970-03-20') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 230 +-- 1001-01-01 +SELECT DATE_TRUNC('CENTURY', TIMESTAMP '1970-03-20 04:30:00.00000') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 231 +-- 1901 +SELECT DATE_TRUNC('CENTURY', DATE '1970-03-20') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 232 +-- 1901 +SELECT DATE_TRUNC('CENTURY', DATE '2004-08-10') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 233 +-- 2001-01-01 +SELECT DATE_TRUNC('CENTURY', DATE '0002-02-04') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 234 +-- 0001-01-01 +SELECT DATE_TRUNC('CENTURY', DATE '0055-08-10 BC') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 235 +-- 0100-01-01 BC +SELECT DATE_TRUNC('DECADE', DATE '1993-12-25') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 236 +-- 1990-01-01 +SELECT DATE_TRUNC('DECADE', DATE '0004-12-25') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 237 +-- 0001-01-01 BC +SELECT DATE_TRUNC('DECADE', DATE '0002-12-31 BC') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 238 +-- 0011-01-01 BC +|-- +-- test infinity +|-- +select 'infinity'::date, '-infinity'::date +-- +STMT: SelectStmt +== 239 +select 'infinity'::date > 'today'::date as t +-- +STMT: SelectStmt +== 240 +select '-infinity'::date < 'today'::date as t +-- +STMT: SelectStmt +== 241 +select isfinite('infinity'::date), isfinite('-infinity'::date), isfinite('today'::date) +-- +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +STMT: SelectStmt +== 242 +select 'infinity'::date = '+infinity'::date as t +-- +STMT: SelectStmt +== 243 +|-- +-- oscillating fields from non-finite date: +|-- +SELECT EXTRACT(DAY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 244 +-- NULL +SELECT EXTRACT(DAY FROM DATE '-infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 245 +-- NULL +-- all supported fields +SELECT EXTRACT(DAY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 246 +-- NULL +SELECT EXTRACT(MONTH FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 247 +-- NULL +SELECT EXTRACT(QUARTER FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 248 +-- NULL +SELECT EXTRACT(WEEK FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 249 +-- NULL +SELECT EXTRACT(DOW FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 250 +-- NULL +SELECT EXTRACT(ISODOW FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 251 +-- NULL +SELECT EXTRACT(DOY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 252 +-- NULL +|-- +-- monotonic fields from non-finite date: +|-- +SELECT EXTRACT(EPOCH FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 253 +-- Infinity +SELECT EXTRACT(EPOCH FROM DATE '-infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 254 +-- -Infinity +-- all supported fields +SELECT EXTRACT(YEAR FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 255 +-- Infinity +SELECT EXTRACT(DECADE FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 256 +-- Infinity +SELECT EXTRACT(CENTURY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 257 +-- Infinity +SELECT EXTRACT(MILLENNIUM FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 258 +-- Infinity +SELECT EXTRACT(JULIAN FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 259 +-- Infinity +SELECT EXTRACT(ISOYEAR FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 260 +-- Infinity +SELECT EXTRACT(EPOCH FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 261 +-- Infinity +|-- +-- wrong fields from non-finite date: +|-- +SELECT EXTRACT(MICROSEC FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 262 +-- error + +-- test constructors +select make_date(2013, 7, 15) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +== 263 +select make_date(-44, 3, 15) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +== 264 +select make_time(8, 20, 0.0) +-- +FUNCTION: name="make_time" function="make_time" schema="" ctx=Call +STMT: SelectStmt +== 265 +-- should fail +select make_date(0, 7, 15) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +== 266 +select make_date(2013, 2, 30) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +== 267 +select make_date(2013, 13, 1) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +== 268 +select make_date(2013, 11, -1) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +== 269 +select make_time(10, 55, 100.1) +-- +FUNCTION: name="make_time" function="make_time" schema="" ctx=Call +STMT: SelectStmt +== 270 +select make_time(24, 0, 2.1) +-- +FUNCTION: name="make_time" function="make_time" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/dbsize.metadata.json b/parser/testdata/summary/postgres_regress/dbsize.metadata.json new file mode 100644 index 0000000..253273e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/dbsize.metadata.json @@ -0,0 +1,29 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025" + ] +} diff --git a/parser/testdata/summary/postgres_regress/dbsize.test b/parser/testdata/summary/postgres_regress/dbsize.test new file mode 100644 index 0000000..9dfd064 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/dbsize.test @@ -0,0 +1,167 @@ +== 001 +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10::bigint), (1000::bigint), (1000000::bigint), + (1000000000::bigint), (1000000000000::bigint), + (1000000000000000::bigint)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +== 002 +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10::numeric), (1000::numeric), (1000000::numeric), + (1000000000::numeric), (1000000000000::numeric), + (1000000000000000::numeric), + (10.5::numeric), (1000.5::numeric), (1000000.5::numeric), + (1000000000.5::numeric), (1000000000000.5::numeric), + (1000000000000000.5::numeric)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- test where units change up +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::bigint), (10240::bigint), + (10485247::bigint), (10485248::bigint), + (10736893951::bigint), (10736893952::bigint), + (10994579406847::bigint), (10994579406848::bigint), + (11258449312612351::bigint), (11258449312612352::bigint)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::numeric), (10240::numeric), + (10485247::numeric), (10485248::numeric), + (10736893951::numeric), (10736893952::numeric), + (10994579406847::numeric), (10994579406848::numeric), + (11258449312612351::numeric), (11258449312612352::numeric), + (11528652096115048447::numeric), (11528652096115048448::numeric)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +== 005 +-- Ensure we get the expected results when passing the extremities of bigint +SELECT pg_size_pretty('-9223372036854775808'::bigint), + pg_size_pretty('9223372036854775807'::bigint) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +== 006 +-- pg_size_bytes() tests +SELECT size, pg_size_bytes(size) FROM + (VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '), + ('1TB'), ('3000 TB'), ('1e6 MB'), ('99 PB')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- case-insensitive units are supported +SELECT size, pg_size_bytes(size) FROM + (VALUES ('1'), ('123bYteS'), ('1kb'), ('1mb'), (' 1 Gb'), ('1.5 gB '), + ('1tb'), ('3000 tb'), ('1e6 mb'), ('99 pb')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- negative numbers are supported +SELECT size, pg_size_bytes(size) FROM + (VALUES ('-1'), ('-123bytes'), ('-1kb'), ('-1mb'), (' -1 Gb'), ('-1.5 gB '), + ('-1tb'), ('-3000 TB'), ('-10e-1 MB'), ('-99 PB')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- different cases with allowed points +SELECT size, pg_size_bytes(size) FROM + (VALUES ('-1.'), ('-1.kb'), ('-1. kb'), ('-0. gb'), + ('-.1'), ('-.1kb'), ('-.1 kb'), ('-.0 gb')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 010 +-- invalid inputs +SELECT pg_size_bytes('1 AB') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT pg_size_bytes('1 AB A') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT pg_size_bytes('1 AB A ') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT pg_size_bytes('9223372036854775807.9') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT pg_size_bytes('1e100') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT pg_size_bytes('1e1000000000000000000') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT pg_size_bytes('1 byte') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- the singular "byte" is not supported +SELECT pg_size_bytes('') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT pg_size_bytes('kb') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT pg_size_bytes('..') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT pg_size_bytes('-.') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT pg_size_bytes('-.kb') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT pg_size_bytes('-. kb') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT pg_size_bytes('.+912') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT pg_size_bytes('+912+ kB') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT pg_size_bytes('++123 kB') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/delete.metadata.json b/parser/testdata/summary/postgres_regress/delete.metadata.json new file mode 100644 index 0000000..92b8f9e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/delete.metadata.json @@ -0,0 +1,14 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010" + ] +} diff --git a/parser/testdata/summary/postgres_regress/delete.test b/parser/testdata/summary/postgres_regress/delete.test new file mode 100644 index 0000000..922c437 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/delete.test @@ -0,0 +1,66 @@ +== 001 +CREATE TABLE delete_test ( + id SERIAL PRIMARY KEY, + a INT, + b text +) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO delete_test (a) VALUES (10) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO delete_test (a) VALUES (100) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +-- allow an alias to be specified for DELETE's target table +DELETE FROM delete_test AS dt WHERE dt.a > 75 +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +ALIAS: "dt"="delete_test" +STMT: DeleteStmt +== 006 +-- if an alias is specified, don't allow the original table name +-- to be referenced +DELETE FROM delete_test dt WHERE delete_test.a > 25 +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +ALIAS: "dt"="delete_test" +STMT: DeleteStmt +== 007 +SELECT id, a, char_length(b) FROM delete_test +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- delete a row with a TOASTed value +DELETE FROM delete_test WHERE a > 25 +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +STMT: DeleteStmt +== 009 +SELECT id, a, char_length(b) FROM delete_test +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +== 010 +DROP TABLE delete_test +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/dependency.metadata.json b/parser/testdata/summary/postgres_regress/dependency.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/dependency.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary/postgres_regress/dependency.test b/parser/testdata/summary/postgres_regress/dependency.test new file mode 100644 index 0000000..a99ed80 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/dependency.test @@ -0,0 +1,302 @@ +== 001 +|-- +-- DEPENDENCIES +|-- + +CREATE USER regress_dep_user +-- +STMT: CreateRoleStmt +== 002 +CREATE USER regress_dep_user2 +-- +STMT: CreateRoleStmt +== 003 +CREATE USER regress_dep_user3 +-- +STMT: CreateRoleStmt +== 004 +CREATE GROUP regress_dep_group +-- +STMT: CreateRoleStmt +== 005 +CREATE TABLE deptest (f1 serial primary key, f2 text) +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: CreateStmt +== 006 +GRANT SELECT ON TABLE deptest TO GROUP regress_dep_group +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +== 007 +GRANT ALL ON TABLE deptest TO regress_dep_user, regress_dep_user2 +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +== 008 +-- can't drop neither because they have privileges somewhere +DROP USER regress_dep_user +-- +STMT: DropRoleStmt +== 009 +DROP GROUP regress_dep_group +-- +STMT: DropRoleStmt +== 010 +-- if we revoke the privileges we can drop the group +REVOKE SELECT ON deptest FROM GROUP regress_dep_group +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +== 011 +DROP GROUP regress_dep_group +-- +STMT: DropRoleStmt +== 012 +-- can't drop the user if we revoke the privileges partially +REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, MAINTAIN ON deptest FROM regress_dep_user +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +== 013 +DROP USER regress_dep_user +-- +STMT: DropRoleStmt +== 014 +-- now we are OK to drop him +REVOKE TRIGGER ON deptest FROM regress_dep_user +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +== 015 +DROP USER regress_dep_user +-- +STMT: DropRoleStmt +== 016 +-- we are OK too if we drop the privileges all at once +REVOKE ALL ON deptest FROM regress_dep_user2 +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +== 017 +DROP USER regress_dep_user2 +-- +STMT: DropRoleStmt +== 018 +-- can't drop the owner of an object +-- the error message detail here would include a pg_toast_nnn name that +-- is not constant, so suppress it +ALTER TABLE deptest OWNER TO regress_dep_user3 +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: AlterTableStmt +== 019 +DROP USER regress_dep_user3 +-- +STMT: DropRoleStmt +== 020 +-- if we drop the object, we can drop the user too +DROP TABLE deptest +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: DropStmt +== 021 +DROP USER regress_dep_user3 +-- +STMT: DropRoleStmt +== 022 +-- Test DROP OWNED +CREATE USER regress_dep_user0 +-- +STMT: CreateRoleStmt +== 023 +CREATE USER regress_dep_user1 +-- +STMT: CreateRoleStmt +== 024 +CREATE USER regress_dep_user2 +-- +STMT: CreateRoleStmt +== 025 +SET SESSION AUTHORIZATION regress_dep_user0 +-- +STMT: VariableSetStmt +== 026 +-- permission denied +DROP OWNED BY regress_dep_user1 +-- +STMT: DropOwnedStmt +== 027 +DROP OWNED BY regress_dep_user0, regress_dep_user2 +-- +STMT: DropOwnedStmt +== 028 +REASSIGN OWNED BY regress_dep_user0 TO regress_dep_user1 +-- +STMT: ReassignOwnedStmt +== 029 +REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user0 +-- +STMT: ReassignOwnedStmt +== 030 +-- this one is allowed +DROP OWNED BY regress_dep_user0 +-- +STMT: DropOwnedStmt +== 031 +CREATE TABLE deptest1 (f1 int unique) +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: CreateStmt +== 032 +GRANT ALL ON deptest1 TO regress_dep_user1 WITH GRANT OPTION +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: GrantStmt +== 033 +SET SESSION AUTHORIZATION regress_dep_user1 +-- +STMT: VariableSetStmt +== 034 +CREATE TABLE deptest (a serial primary key, b text) +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: CreateStmt +== 035 +GRANT ALL ON deptest1 TO regress_dep_user2 +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: GrantStmt +== 036 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 037 +DROP OWNED BY regress_dep_user1 +-- +STMT: DropOwnedStmt +== 038 +-- all grants revoked +-- table was dropped + +-- Test REASSIGN OWNED +GRANT ALL ON deptest1 TO regress_dep_user1 +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: GrantStmt +== 039 +GRANT CREATE ON DATABASE regression TO regress_dep_user1 +-- +STMT: GrantStmt +== 040 +SET SESSION AUTHORIZATION regress_dep_user1 +-- +STMT: VariableSetStmt +== 041 +CREATE SCHEMA deptest +-- +STMT: CreateSchemaStmt +== 042 +CREATE TABLE deptest (a serial primary key, b text) +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: CreateStmt +== 043 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_dep_user1 IN SCHEMA deptest + GRANT ALL ON TABLES TO regress_dep_user2 +-- +STMT: AlterDefaultPrivilegesStmt +== 044 +CREATE FUNCTION deptest_func() RETURNS void LANGUAGE plpgsql + AS $$ BEGIN END; $$ +-- +FUNCTION: name="deptest_func" function="deptest_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 045 +CREATE TYPE deptest_enum AS ENUM ('red') +-- +STMT: CreateEnumStmt +== 046 +CREATE TYPE deptest_range AS RANGE (SUBTYPE = int4) +-- +STMT: CreateRangeStmt +== 047 +CREATE TABLE deptest2 (f1 int) +-- +TABLE: name="deptest2" schema="" table="deptest2" ctx=DDL +STMT: CreateStmt +== 048 +-- make a serial column the hard way +CREATE SEQUENCE ss1 +-- +STMT: CreateSeqStmt +== 049 +ALTER TABLE deptest2 ALTER f1 SET DEFAULT nextval('ss1') +-- +TABLE: name="deptest2" schema="" table="deptest2" ctx=DDL +STMT: AlterTableStmt +== 050 +ALTER SEQUENCE ss1 OWNED BY deptest2.f1 +-- +STMT: AlterSeqStmt +== 051 +-- When reassigning ownership of a composite type, its pg_class entry +-- should match +CREATE TYPE deptest_t AS (a int) +-- +STMT: CompositeTypeStmt +== 052 +SELECT typowner = relowner +FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 053 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 054 +REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user2 +-- +STMT: ReassignOwnedStmt +== 055 +SELECT typowner = relowner +FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 056 +-- doesn't work: grant still exists +DROP USER regress_dep_user1 +-- +STMT: DropRoleStmt +== 057 +DROP OWNED BY regress_dep_user1 +-- +STMT: DropOwnedStmt +== 058 +DROP USER regress_dep_user1 +-- +STMT: DropRoleStmt +== 059 +DROP USER regress_dep_user2 +-- +STMT: DropRoleStmt +== 060 +DROP OWNED BY regress_dep_user2, regress_dep_user0 +-- +STMT: DropOwnedStmt +== 061 +DROP USER regress_dep_user2 +-- +STMT: DropRoleStmt +== 062 +DROP USER regress_dep_user0 +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/domain.metadata.json b/parser/testdata/summary/postgres_regress/domain.metadata.json new file mode 100644 index 0000000..60d70f4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/domain.metadata.json @@ -0,0 +1,323 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319" + ] +} diff --git a/parser/testdata/summary/postgres_regress/domain.test b/parser/testdata/summary/postgres_regress/domain.test new file mode 100644 index 0000000..88c24c5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/domain.test @@ -0,0 +1,1789 @@ +== 001 +|-- +-- Test domains. +|-- + +-- Test Comment / Drop +create domain domaindroptest int4 +-- +STMT: CreateDomainStmt +== 002 +comment on domain domaindroptest is 'About to drop this..' +-- +STMT: CommentStmt +== 003 +create domain dependenttypetest domaindroptest +-- +STMT: CreateDomainStmt +== 004 +-- fail because of dependent type +drop domain domaindroptest +-- +STMT: DropStmt +== 005 +drop domain domaindroptest cascade +-- +STMT: DropStmt +== 006 +-- this should fail because already gone +drop domain domaindroptest cascade +-- +STMT: DropStmt +== 007 +-- Test domain input. + +-- Note: the point of checking both INSERT and COPY FROM is that INSERT +-- exercises CoerceToDomain while COPY exercises domain_in. + +create domain domainvarchar varchar(5) +-- +STMT: CreateDomainStmt +== 008 +create domain domainnumeric numeric(8,2) +-- +STMT: CreateDomainStmt +== 009 +create domain domainint4 int4 +-- +STMT: CreateDomainStmt +== 010 +create domain domaintext text +-- +STMT: CreateDomainStmt +== 011 +-- Test explicit coercions --- these should succeed (and truncate) +SELECT cast('123456' as domainvarchar) +-- +STMT: SelectStmt +== 012 +SELECT cast('12345' as domainvarchar) +-- +STMT: SelectStmt +== 013 +-- Test tables using domains +create table basictest + ( testint4 domainint4 + , testtext domaintext + , testvarchar domainvarchar + , testnumeric domainnumeric + ) +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DDL +STMT: CreateStmt +== 014 +INSERT INTO basictest values ('88', 'haha', 'short', '123.12') +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +-- Good +INSERT INTO basictest values ('88', 'haha', 'short text', '123.12') +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +-- Bad varchar +INSERT INTO basictest values ('88', 'haha', 'short', '123.1212') +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +-- Truncate numeric + +-- Test copy +COPY basictest (testvarchar) FROM stdin +-- +TABLE: name="basictest" schema="" table="basictest" ctx=Select +STMT: CopyStmt +== 018 +-- fail +notsoshorttext + +COPY basictest (testvarchar) FROM stdin +-- +ERROR: syntax error at or near "notsoshorttext" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 019 +select * from basictest +-- +TABLE: name="basictest" schema="" table="basictest" ctx=Select +STMT: SelectStmt +== 020 +-- check that domains inherit operations from base types +select testtext || testvarchar as concat, testnumeric + 42 as sum +from basictest +-- +TABLE: name="basictest" schema="" table="basictest" ctx=Select +STMT: SelectStmt +== 021 +-- check that union/case/coalesce type resolution handles domains properly +select pg_typeof(coalesce(4::domainint4, 7)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 022 +select pg_typeof(coalesce(4::domainint4, 7::domainint4)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 023 +drop table basictest +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DDL +STMT: DropStmt +== 024 +drop domain domainvarchar restrict +-- +STMT: DropStmt +== 025 +drop domain domainnumeric restrict +-- +STMT: DropStmt +== 026 +drop domain domainint4 restrict +-- +STMT: DropStmt +== 027 +drop domain domaintext +-- +STMT: DropStmt +== 028 +-- Test non-error-throwing input + +create domain positiveint int4 check(value > 0) +-- +STMT: CreateDomainStmt +== 029 +create domain weirdfloat float8 check((1 / value) < 10) +-- +STMT: CreateDomainStmt +== 030 +select pg_input_is_valid('1', 'positiveint') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 031 +select pg_input_is_valid('junk', 'positiveint') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 032 +select pg_input_is_valid('-1', 'positiveint') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 033 +select * from pg_input_error_info('junk', 'positiveint') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 034 +select * from pg_input_error_info('-1', 'positiveint') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 035 +select * from pg_input_error_info('junk', 'weirdfloat') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 036 +select * from pg_input_error_info('0.01', 'weirdfloat') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- We currently can't trap errors raised in the CHECK expression itself +select * from pg_input_error_info('0', 'weirdfloat') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 038 +drop domain positiveint +-- +STMT: DropStmt +== 039 +drop domain weirdfloat +-- +STMT: DropStmt +== 040 +-- Test domains over array types + +create domain domainint4arr int4[1] +-- +STMT: CreateDomainStmt +== 041 +create domain domainchar4arr varchar(4)[2][3] +-- +STMT: CreateDomainStmt +== 042 +create table domarrtest + ( testint4arr domainint4arr + , testchar4arr domainchar4arr + ) +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DDL +STMT: CreateStmt +== 043 +INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO domarrtest values (NULL, '{{"toolong","b","c"},{"d","e","f"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO domarrtest (testint4arr[1], testint4arr[3]) values (11,22) +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +select * from domarrtest +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: SelectStmt +== 051 +select testint4arr[1], testchar4arr[2:2] from domarrtest +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: SelectStmt +== 052 +select array_dims(testint4arr), array_dims(testchar4arr) from domarrtest +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: SelectStmt +== 053 +COPY domarrtest FROM stdin +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: CopyStmt +== 054 +COPY domarrtest FROM stdin +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: CopyStmt +== 055 +-- fail +{3,4} {qwerty,w,e} + +select * from domarrtest +-- +ERROR: syntax error at or near "{" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 056 +COPY nulltest FROM stdin +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=Select +STMT: CopyStmt +== 057 +--fail +a b c d \N + +-- Last row is bad +COPY nulltest FROM stdin +-- +ERROR: syntax error at or near "a" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 058 +select * from nulltest +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=Select +STMT: SelectStmt +== 059 +-- Test out coerced (casted) constraints +SELECT cast('1' as dnotnull) +-- +STMT: SelectStmt +== 060 +SELECT cast(NULL as dnotnull) +-- +STMT: SelectStmt +== 061 +-- fail +SELECT cast(cast(NULL as dnull) as dnotnull) +-- +STMT: SelectStmt +== 062 +-- fail +SELECT cast(col4 as dnotnull) from nulltest +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=Select +STMT: SelectStmt +== 063 +-- fail + +-- cleanup +drop table nulltest +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=DDL +STMT: DropStmt +== 064 +drop domain dnotnull restrict +-- +STMT: DropStmt +== 065 +drop domain dnull restrict +-- +STMT: DropStmt +== 066 +drop domain dcheck restrict +-- +STMT: DropStmt +== 067 +create domain ddef1 int4 DEFAULT 3 +-- +STMT: CreateDomainStmt +== 068 +create domain ddef2 oid DEFAULT '12' +-- +STMT: CreateDomainStmt +== 069 +-- Type mixing, function returns int8 +create domain ddef3 text DEFAULT 5 +-- +STMT: CreateDomainStmt +== 070 +create sequence ddef4_seq +-- +STMT: CreateSeqStmt +== 071 +create domain ddef4 int4 DEFAULT nextval('ddef4_seq') +-- +STMT: CreateDomainStmt +== 072 +create domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12' +-- +STMT: CreateDomainStmt +== 073 +create table defaulttest + ( col1 ddef1 + , col2 ddef2 + , col3 ddef3 + , col4 ddef4 PRIMARY KEY + , col5 ddef1 NOT NULL DEFAULT NULL + , col6 ddef2 DEFAULT '88' + , col7 ddef4 DEFAULT 8000 + , col8 ddef5 + ) +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: CreateStmt +== 074 +insert into defaulttest(col4) values(0) +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +-- fails, col5 defaults to null +alter table defaulttest alter column col5 drop default +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: AlterTableStmt +== 076 +insert into defaulttest default values +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +== 077 +-- succeeds, inserts domain default +-- We used to treat SET DEFAULT NULL as equivalent to DROP DEFAULT; wrong +alter table defaulttest alter column col5 set default null +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: AlterTableStmt +== 078 +insert into defaulttest(col4) values(0) +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +-- fails +alter table defaulttest alter column col5 drop default +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: AlterTableStmt +== 080 +insert into defaulttest default values +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +== 081 +insert into defaulttest default values +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +== 082 +-- Test defaults with copy +COPY defaulttest(col5) FROM stdin +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=Select +STMT: CopyStmt +== 083 +select * from defaulttest +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=Select +STMT: SelectStmt +== 084 +drop table defaulttest cascade +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: DropStmt +== 085 +-- Test ALTER DOMAIN .. NOT NULL +create domain dnotnulltest integer +-- +STMT: CreateDomainStmt +== 086 +create table domnotnull +( col1 dnotnulltest +, col2 dnotnulltest +) +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DDL +STMT: CreateStmt +== 087 +insert into domnotnull default values +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: InsertStmt +== 088 +alter domain dnotnulltest set not null +-- +STMT: AlterDomainStmt +== 089 +-- fails + +update domnotnull set col1 = 5 +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +== 090 +alter domain dnotnulltest set not null +-- +STMT: AlterDomainStmt +== 091 +-- fails + +update domnotnull set col2 = 6 +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +== 092 +alter domain dnotnulltest set not null +-- +STMT: AlterDomainStmt +== 093 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +== 094 +-- fails + +alter domain dnotnulltest drop not null +-- +STMT: AlterDomainStmt +== 095 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +== 096 +update domnotnull set col1 = 5 +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +== 097 +-- these constraints can also be added and removed by name +alter domain dnotnulltest add constraint dnotnulltest_notnull not null +-- +STMT: AlterDomainStmt +== 098 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +== 099 +-- fails +select conname, pg_get_constraintdef(oid) from pg_constraint + where contypid = 'dnotnulltest'::regtype +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="contypid" +STMT: SelectStmt +== 100 +alter domain dnotnulltest drop constraint dnotnulltest_notnull +-- +STMT: AlterDomainStmt +== 101 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +== 102 +drop domain dnotnulltest cascade +-- +STMT: DropStmt +== 103 +-- Test ALTER DOMAIN .. DEFAULT .. +create table domdeftest (col1 ddef1) +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DDL +STMT: CreateStmt +== 104 +insert into domdeftest default values +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DML +STMT: InsertStmt +== 105 +select * from domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=Select +STMT: SelectStmt +== 106 +alter domain ddef1 set default '42' +-- +STMT: AlterDomainStmt +== 107 +insert into domdeftest default values +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DML +STMT: InsertStmt +== 108 +select * from domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=Select +STMT: SelectStmt +== 109 +alter domain ddef1 drop default +-- +STMT: AlterDomainStmt +== 110 +insert into domdeftest default values +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DML +STMT: InsertStmt +== 111 +select * from domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=Select +STMT: SelectStmt +== 112 +drop table domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DDL +STMT: DropStmt +== 113 +-- Test ALTER DOMAIN .. CONSTRAINT .. +create domain con as integer +-- +STMT: CreateDomainStmt +== 114 +create table domcontest (col1 con) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DDL +STMT: CreateStmt +== 115 +insert into domcontest values (1) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +insert into domcontest values (2) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +alter domain con add constraint t check (VALUE < 1) +-- +STMT: AlterDomainStmt +== 118 +-- fails + +alter domain con add constraint t check (VALUE < 34) +-- +STMT: AlterDomainStmt +== 119 +alter domain con add check (VALUE > 0) +-- +STMT: AlterDomainStmt +== 120 +insert into domcontest values (-5) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +-- fails +insert into domcontest values (42) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +-- fails +insert into domcontest values (5) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +alter domain con drop constraint t +-- +STMT: AlterDomainStmt +== 124 +insert into domcontest values (-5) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +--fails +insert into domcontest values (42) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 126 +alter domain con drop constraint nonexistent +-- +STMT: AlterDomainStmt +== 127 +alter domain con drop constraint if exists nonexistent +-- +STMT: AlterDomainStmt +== 128 +-- not-null constraints +create domain connotnull integer +-- +STMT: CreateDomainStmt +== 129 +create table domconnotnulltest +( col1 connotnull +, col2 connotnull +) +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DDL +STMT: CreateStmt +== 130 +insert into domconnotnulltest default values +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: InsertStmt +== 131 +alter domain connotnull add not null +-- +STMT: AlterDomainStmt +== 132 +-- fails + +update domconnotnulltest set col1 = 5 +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +== 133 +alter domain connotnull add not null +-- +STMT: AlterDomainStmt +== 134 +-- fails + +update domconnotnulltest set col2 = 6 +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +== 135 +alter domain connotnull add constraint constr1 not null +-- +STMT: AlterDomainStmt +== 136 +select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="contypid" +FILTER: schema="" table="" column="contype" +STMT: SelectStmt +== 137 +alter domain connotnull add constraint constr1bis not null +-- +STMT: AlterDomainStmt +== 138 +-- redundant +select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="contypid" +FILTER: schema="" table="" column="contype" +STMT: SelectStmt +== 139 +update domconnotnulltest set col1 = null +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +== 140 +-- fails + +alter domain connotnull drop constraint constr1 +-- +STMT: AlterDomainStmt +== 141 +update domconnotnulltest set col1 = null +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +== 142 +drop domain connotnull cascade +-- +STMT: DropStmt +== 143 +drop table domconnotnulltest +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DDL +STMT: DropStmt +== 144 +-- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID +create domain things AS INT +-- +STMT: CreateDomainStmt +== 145 +CREATE TABLE thethings (stuff things) +-- +TABLE: name="thethings" schema="" table="thethings" ctx=DDL +STMT: CreateStmt +== 146 +INSERT INTO thethings (stuff) VALUES (55) +-- +TABLE: name="thethings" schema="" table="thethings" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11) +-- +STMT: AlterDomainStmt +== 148 +ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11) NOT VALID +-- +STMT: AlterDomainStmt +== 149 +ALTER DOMAIN things VALIDATE CONSTRAINT meow +-- +STMT: AlterDomainStmt +== 150 +UPDATE thethings SET stuff = 10 +-- +TABLE: name="thethings" schema="" table="thethings" ctx=DML +STMT: UpdateStmt +== 151 +ALTER DOMAIN things VALIDATE CONSTRAINT meow +-- +STMT: AlterDomainStmt +== 152 +-- Confirm ALTER DOMAIN with RULES. +create table domtab (col1 integer) +-- +TABLE: name="domtab" schema="" table="domtab" ctx=DDL +STMT: CreateStmt +== 153 +create domain dom as integer +-- +STMT: CreateDomainStmt +== 154 +create view domview as select cast(col1 as dom) from domtab +-- +TABLE: name="domview" schema="" table="domview" ctx=DDL +TABLE: name="domtab" schema="" table="domtab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 155 +insert into domtab (col1) values (null) +-- +TABLE: name="domtab" schema="" table="domtab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +insert into domtab (col1) values (5) +-- +TABLE: name="domtab" schema="" table="domtab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 157 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +== 158 +alter domain dom set not null +-- +STMT: AlterDomainStmt +== 159 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +== 160 +-- fail + +alter domain dom drop not null +-- +STMT: AlterDomainStmt +== 161 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +== 162 +alter domain dom add constraint domchkgt6 check(value > 6) +-- +STMT: AlterDomainStmt +== 163 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +== 164 +--fail + +alter domain dom drop constraint domchkgt6 restrict +-- +STMT: AlterDomainStmt +== 165 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +== 166 +-- cleanup +drop domain ddef1 restrict +-- +STMT: DropStmt +== 167 +drop domain ddef2 restrict +-- +STMT: DropStmt +== 168 +drop domain ddef3 restrict +-- +STMT: DropStmt +== 169 +drop domain ddef4 restrict +-- +STMT: DropStmt +== 170 +drop domain ddef5 restrict +-- +STMT: DropStmt +== 171 +drop sequence ddef4_seq +-- +STMT: DropStmt +== 172 +-- Test domains over domains +create domain vchar4 varchar(4) +-- +STMT: CreateDomainStmt +== 173 +create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x') +-- +STMT: CreateDomainStmt +== 174 +create domain dtop dinter check (substring(VALUE, 2, 1) = '1') +-- +STMT: CreateDomainStmt +== 175 +select 'x123'::dtop +-- +STMT: SelectStmt +== 176 +select 'x1234'::dtop +-- +STMT: SelectStmt +== 177 +-- explicit coercion should truncate +select 'y1234'::dtop +-- +STMT: SelectStmt +== 178 +-- fail +select 'y123'::dtop +-- +STMT: SelectStmt +== 179 +-- fail +select 'yz23'::dtop +-- +STMT: SelectStmt +== 180 +-- fail +select 'xz23'::dtop +-- +STMT: SelectStmt +== 181 +-- fail + +create temp table dtest(f1 dtop) +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DDL +STMT: CreateStmt +== 182 +insert into dtest values('x123') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 183 +insert into dtest values('x1234') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 184 +-- fail, implicit coercion +insert into dtest values('y1234') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +-- fail, implicit coercion +insert into dtest values('y123') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +-- fail +insert into dtest values('yz23') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +-- fail +insert into dtest values('xz23') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +-- fail + +drop table dtest +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DDL +STMT: DropStmt +== 189 +drop domain vchar4 cascade +-- +STMT: DropStmt +== 190 +-- Make sure that constraints of newly-added domain columns are +-- enforced correctly, even if there's no default value for the new +-- column. Per bug #1433 +create domain str_domain as text not null +-- +STMT: CreateDomainStmt +== 191 +create table domain_test (a int, b int) +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DDL +STMT: CreateStmt +== 192 +insert into domain_test values (1, 2) +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +insert into domain_test values (1, 2) +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 194 +-- should fail +alter table domain_test add column c str_domain +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DDL +STMT: AlterTableStmt +== 195 +create domain str_domain2 as text check (value <> 'foo') default 'foo' +-- +STMT: CreateDomainStmt +== 196 +-- should fail +alter table domain_test add column d str_domain2 +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DDL +STMT: AlterTableStmt +== 197 +-- Check that domain constraints on prepared statement parameters of +-- unknown type are enforced correctly. +create domain pos_int as int4 check (value > 0) not null +-- +STMT: CreateDomainStmt +== 198 +prepare s1 as select $1::pos_int = 10 as "is_ten" +-- +STMT: PrepareStmt +STMT: SelectStmt +== 199 +execute s1(10) +-- +STMT: ExecuteStmt +== 200 +execute s1(0) +-- +STMT: ExecuteStmt +== 201 +-- should fail +execute s1(NULL) +-- +STMT: ExecuteStmt +== 202 +-- should fail + +-- Check that domain constraints on plpgsql function parameters, results, +-- and local variables are enforced correctly. + +create function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int; +begin + return p1; +end$$ language plpgsql +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 203 +select doubledecrement(3) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +== 204 +-- fail because of implicit null assignment + +create or replace function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int := 0; +begin + return p1; +end$$ language plpgsql +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 205 +select doubledecrement(3) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +== 206 +-- fail at initialization assignment + +create or replace function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int := 1; +begin + v := p1 - 1; + return v - 1; +end$$ language plpgsql +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 207 +select doubledecrement(null) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +== 208 +-- fail before call +select doubledecrement(0) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +== 209 +-- fail before call +select doubledecrement(1) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +== 210 +-- fail at assignment to v +select doubledecrement(2) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +== 211 +-- fail at return +select doubledecrement(3) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +== 212 +-- good + +-- Check that ALTER DOMAIN tests columns of derived types + +create domain posint as int4 +-- +STMT: CreateDomainStmt +== 213 +-- Currently, this doesn't work for composite types, but verify it complains +create type ddtest1 as (f1 posint) +-- +STMT: CompositeTypeStmt +== 214 +create table ddtest2(f1 ddtest1) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +== 215 +insert into ddtest2 values(row(-1)) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +== 217 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +== 218 +-- Likewise for domains within arrays of composite +create table ddtest2(f1 ddtest1[]) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +== 219 +insert into ddtest2 values('{(-1)}') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 220 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +== 221 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +== 222 +-- Likewise for domains within domains over composite +create domain ddtest1d as ddtest1 +-- +STMT: CreateDomainStmt +== 223 +create table ddtest2(f1 ddtest1d) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +== 224 +insert into ddtest2 values('(-1)') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +== 226 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +== 227 +drop domain ddtest1d +-- +STMT: DropStmt +== 228 +-- Likewise for domains within domains over array of composite +create domain ddtest1d as ddtest1[] +-- +STMT: CreateDomainStmt +== 229 +create table ddtest2(f1 ddtest1d) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +== 230 +insert into ddtest2 values('{(-1)}') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 231 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +== 232 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +== 233 +drop domain ddtest1d +-- +STMT: DropStmt +== 234 +-- Doesn't work for ranges, either +create type rposint as range (subtype = posint) +-- +STMT: CreateRangeStmt +== 235 +create table ddtest2(f1 rposint) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +== 236 +insert into ddtest2 values('(-1,3]') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 237 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +== 238 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +== 239 +drop type rposint +-- +STMT: DropStmt +== 240 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +== 241 +create domain posint2 as posint check (value % 2 = 0) +-- +STMT: CreateDomainStmt +== 242 +create table ddtest2(f1 posint2) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +== 243 +insert into ddtest2 values(11) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +-- fail +insert into ddtest2 values(-2) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +-- fail +insert into ddtest2 values(2) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 246 +alter domain posint add constraint c2 check(value >= 10) +-- +STMT: AlterDomainStmt +== 247 +-- fail +alter domain posint add constraint c2 check(value > 0) +-- +STMT: AlterDomainStmt +== 248 +-- OK + +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +== 249 +drop type ddtest1 +-- +STMT: DropStmt +== 250 +drop domain posint cascade +-- +STMT: DropStmt +== 251 +|-- +-- Check enforcement of domain-related typmod in plpgsql (bug #5717) +|-- + +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x numeric(4,2)[1]; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 252 +select array_elem_check(121.00) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 253 +select array_elem_check(1.23456) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 254 +create domain mynums as numeric(4,2)[1] +-- +STMT: CreateDomainStmt +== 255 +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x mynums; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 256 +select array_elem_check(121.00) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 257 +select array_elem_check(1.23456) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 258 +create domain mynums2 as mynums +-- +STMT: CreateDomainStmt +== 259 +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x mynums2; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 260 +select array_elem_check(121.00) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 261 +select array_elem_check(1.23456) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 262 +drop function array_elem_check(numeric) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: DropStmt +== 263 +|-- +-- Check enforcement of array-level domain constraints +|-- + +create domain orderedpair as int[2] check (value[1] < value[2]) +-- +STMT: CreateDomainStmt +== 264 +select array[1,2]::orderedpair +-- +STMT: SelectStmt +== 265 +select array[2,1]::orderedpair +-- +STMT: SelectStmt +== 266 +-- fail + +create temp table op (f1 orderedpair) +-- +TABLE: name="op" schema="" table="op" ctx=DDL +STMT: CreateStmt +== 267 +insert into op values (array[1,2]) +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +insert into op values (array[2,1]) +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +-- fail + +update op set f1[2] = 3 +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: UpdateStmt +== 270 +update op set f1[2] = 0 +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: UpdateStmt +== 271 +-- fail +select * from op +-- +TABLE: name="op" schema="" table="op" ctx=Select +STMT: SelectStmt +== 272 +create or replace function array_elem_check(int) returns int as $$ +declare + x orderedpair := '{1,2}'; +begin + x[2] := $1; + return x[2]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 273 +select array_elem_check(3) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 274 +select array_elem_check(-1) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +== 275 +drop function array_elem_check(int) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: DropStmt +== 276 +|-- +-- Check enforcement of changing constraints in plpgsql +|-- + +create domain di as int +-- +STMT: CreateDomainStmt +== 277 +create function dom_check(int) returns di as $$ +declare d di; +begin + d := $1::di; + return d; +end +$$ language plpgsql immutable +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 278 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +== 279 +alter domain di add constraint pos check (value > 0) +-- +STMT: AlterDomainStmt +== 280 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +== 281 +-- fail + +alter domain di drop constraint pos +-- +STMT: AlterDomainStmt +== 282 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +== 283 +-- implicit cast during assignment is a separate code path, test that too + +create or replace function dom_check(int) returns di as $$ +declare d di; +begin + d := $1; + return d; +end +$$ language plpgsql immutable +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 284 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +== 285 +alter domain di add constraint pos check (value > 0) +-- +STMT: AlterDomainStmt +== 286 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +== 287 +-- fail + +alter domain di drop constraint pos +-- +STMT: AlterDomainStmt +== 288 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +== 289 +drop function dom_check(int) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=DDL +STMT: DropStmt +== 290 +drop domain di +-- +STMT: DropStmt +== 291 +|-- +-- Check use of a (non-inline-able) SQL function in a domain constraint; +-- this has caused issues in the past +|-- + +create function sql_is_distinct_from(anyelement, anyelement) +returns boolean language sql +as 'select $1 is distinct from $2 limit 1' +-- +FUNCTION: name="sql_is_distinct_from" function="sql_is_distinct_from" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 292 +create domain inotnull int + check (sql_is_distinct_from(value, null)) +-- +STMT: CreateDomainStmt +== 293 +select 1::inotnull +-- +STMT: SelectStmt +== 294 +select null::inotnull +-- +STMT: SelectStmt +== 295 +create table dom_table (x inotnull) +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DDL +STMT: CreateStmt +== 296 +insert into dom_table values ('1') +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 297 +insert into dom_table values (1) +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 298 +insert into dom_table values (null) +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 299 +drop table dom_table +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DDL +STMT: DropStmt +== 300 +drop domain inotnull +-- +STMT: DropStmt +== 301 +drop function sql_is_distinct_from(anyelement, anyelement) +-- +FUNCTION: name="sql_is_distinct_from" function="sql_is_distinct_from" schema="" ctx=DDL +STMT: DropStmt +== 302 +|-- +-- Renaming +|-- + +create domain testdomain1 as int +-- +STMT: CreateDomainStmt +== 303 +alter domain testdomain1 rename to testdomain2 +-- +STMT: RenameStmt +== 304 +alter type testdomain2 rename to testdomain3 +-- +STMT: RenameStmt +== 305 +-- alter type also works +drop domain testdomain3 +-- +STMT: DropStmt +== 306 +|-- +-- Renaming domain constraints +|-- + +create domain testdomain1 as int constraint unsigned check (value > 0) +-- +STMT: CreateDomainStmt +== 307 +alter domain testdomain1 rename constraint unsigned to unsigned_foo +-- +STMT: RenameStmt +== 308 +alter domain testdomain1 drop constraint unsigned_foo +-- +STMT: AlterDomainStmt +== 309 +drop domain testdomain1 +-- +STMT: DropStmt +== 310 +|-- +-- Get the base type of a domain +|-- +create domain mytext as text +-- +STMT: CreateDomainStmt +== 311 +create domain mytext_child_1 as mytext +-- +STMT: CreateDomainStmt +== 312 +select pg_basetype('mytext'::regtype) +-- +FUNCTION: name="pg_basetype" function="pg_basetype" schema="" ctx=Call +STMT: SelectStmt +== 313 +select pg_basetype('mytext_child_1'::regtype) +-- +FUNCTION: name="pg_basetype" function="pg_basetype" schema="" ctx=Call +STMT: SelectStmt +== 314 +select pg_basetype(1) +-- +FUNCTION: name="pg_basetype" function="pg_basetype" schema="" ctx=Call +STMT: SelectStmt +== 315 +-- expect NULL not error + +drop domain mytext cascade +-- +STMT: DropStmt +== 316 +|-- +-- Information schema +|-- + +SELECT * FROM information_schema.column_domain_usage + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY domain_name +-- +TABLE: name="information_schema.column_domain_usage" schema="information_schema" table="column_domain_usage" ctx=Select +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt +== 317 +SELECT * FROM information_schema.domain_constraints + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY constraint_name +-- +TABLE: name="information_schema.domain_constraints" schema="information_schema" table="domain_constraints" ctx=Select +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt +== 318 +SELECT * FROM information_schema.domains + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY domain_name +-- +TABLE: name="information_schema.domains" schema="information_schema" table="domains" ctx=Select +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt +== 319 +SELECT * FROM information_schema.check_constraints + WHERE (constraint_schema, constraint_name) + IN (SELECT constraint_schema, constraint_name + FROM information_schema.domain_constraints + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things')) + ORDER BY constraint_name +-- +TABLE: name="information_schema.check_constraints" schema="information_schema" table="check_constraints" ctx=Select +TABLE: name="information_schema.domain_constraints" schema="information_schema" table="domain_constraints" ctx=Select +FILTER: schema="" table="" column="constraint_schema" +FILTER: schema="" table="" column="constraint_name" +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json b/parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json new file mode 100644 index 0000000..3b3c7f2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json @@ -0,0 +1,165 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161" + ] +} diff --git a/parser/testdata/summary/postgres_regress/drop_if_exists.test b/parser/testdata/summary/postgres_regress/drop_if_exists.test new file mode 100644 index 0000000..30104d6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/drop_if_exists.test @@ -0,0 +1,750 @@ +== 001 +|-- +-- IF EXISTS tests +|-- + +-- table (will be really dropped at the end) + +DROP TABLE test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 002 +DROP TABLE IF EXISTS test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 003 +CREATE TABLE test_exists (a int, b text) +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: CreateStmt +== 004 +-- view + +DROP VIEW test_view_exists +-- +STMT: DropStmt +== 005 +DROP VIEW IF EXISTS test_view_exists +-- +STMT: DropStmt +== 006 +CREATE VIEW test_view_exists AS select * from test_exists +-- +TABLE: name="test_view_exists" schema="" table="test_view_exists" ctx=DDL +TABLE: name="test_exists" schema="" table="test_exists" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 007 +DROP VIEW IF EXISTS test_view_exists +-- +STMT: DropStmt +== 008 +DROP VIEW test_view_exists +-- +STMT: DropStmt +== 009 +-- index + +DROP INDEX test_index_exists +-- +STMT: DropStmt +== 010 +DROP INDEX IF EXISTS test_index_exists +-- +STMT: DropStmt +== 011 +CREATE INDEX test_index_exists on test_exists(a) +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: IndexStmt +== 012 +DROP INDEX IF EXISTS test_index_exists +-- +STMT: DropStmt +== 013 +DROP INDEX test_index_exists +-- +STMT: DropStmt +== 014 +-- sequence + +DROP SEQUENCE test_sequence_exists +-- +STMT: DropStmt +== 015 +DROP SEQUENCE IF EXISTS test_sequence_exists +-- +STMT: DropStmt +== 016 +CREATE SEQUENCE test_sequence_exists +-- +STMT: CreateSeqStmt +== 017 +DROP SEQUENCE IF EXISTS test_sequence_exists +-- +STMT: DropStmt +== 018 +DROP SEQUENCE test_sequence_exists +-- +STMT: DropStmt +== 019 +-- schema + +DROP SCHEMA test_schema_exists +-- +STMT: DropStmt +== 020 +DROP SCHEMA IF EXISTS test_schema_exists +-- +STMT: DropStmt +== 021 +CREATE SCHEMA test_schema_exists +-- +STMT: CreateSchemaStmt +== 022 +DROP SCHEMA IF EXISTS test_schema_exists +-- +STMT: DropStmt +== 023 +DROP SCHEMA test_schema_exists +-- +STMT: DropStmt +== 024 +-- type + +DROP TYPE test_type_exists +-- +STMT: DropStmt +== 025 +DROP TYPE IF EXISTS test_type_exists +-- +STMT: DropStmt +== 026 +CREATE type test_type_exists as (a int, b text) +-- +STMT: CompositeTypeStmt +== 027 +DROP TYPE IF EXISTS test_type_exists +-- +STMT: DropStmt +== 028 +DROP TYPE test_type_exists +-- +STMT: DropStmt +== 029 +-- domain + +DROP DOMAIN test_domain_exists +-- +STMT: DropStmt +== 030 +DROP DOMAIN IF EXISTS test_domain_exists +-- +STMT: DropStmt +== 031 +CREATE domain test_domain_exists as int not null check (value > 0) +-- +STMT: CreateDomainStmt +== 032 +DROP DOMAIN IF EXISTS test_domain_exists +-- +STMT: DropStmt +== 033 +DROP DOMAIN test_domain_exists +-- +STMT: DropStmt +== 034 +--- +--- role/user/group +--- + +CREATE USER regress_test_u1 +-- +STMT: CreateRoleStmt +== 035 +CREATE ROLE regress_test_r1 +-- +STMT: CreateRoleStmt +== 036 +CREATE GROUP regress_test_g1 +-- +STMT: CreateRoleStmt +== 037 +DROP USER regress_test_u2 +-- +STMT: DropRoleStmt +== 038 +DROP USER IF EXISTS regress_test_u1, regress_test_u2 +-- +STMT: DropRoleStmt +== 039 +DROP USER regress_test_u1 +-- +STMT: DropRoleStmt +== 040 +DROP ROLE regress_test_r2 +-- +STMT: DropRoleStmt +== 041 +DROP ROLE IF EXISTS regress_test_r1, regress_test_r2 +-- +STMT: DropRoleStmt +== 042 +DROP ROLE regress_test_r1 +-- +STMT: DropRoleStmt +== 043 +DROP GROUP regress_test_g2 +-- +STMT: DropRoleStmt +== 044 +DROP GROUP IF EXISTS regress_test_g1, regress_test_g2 +-- +STMT: DropRoleStmt +== 045 +DROP GROUP regress_test_g1 +-- +STMT: DropRoleStmt +== 046 +-- collation +DROP COLLATION IF EXISTS test_collation_exists +-- +STMT: DropStmt +== 047 +-- conversion +DROP CONVERSION test_conversion_exists +-- +STMT: DropStmt +== 048 +DROP CONVERSION IF EXISTS test_conversion_exists +-- +STMT: DropStmt +== 049 +CREATE CONVERSION test_conversion_exists + FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +== 050 +DROP CONVERSION test_conversion_exists +-- +STMT: DropStmt +== 051 +-- text search parser +DROP TEXT SEARCH PARSER test_tsparser_exists +-- +STMT: DropStmt +== 052 +DROP TEXT SEARCH PARSER IF EXISTS test_tsparser_exists +-- +STMT: DropStmt +== 053 +-- text search dictionary +DROP TEXT SEARCH DICTIONARY test_tsdict_exists +-- +STMT: DropStmt +== 054 +DROP TEXT SEARCH DICTIONARY IF EXISTS test_tsdict_exists +-- +STMT: DropStmt +== 055 +CREATE TEXT SEARCH DICTIONARY test_tsdict_exists ( + Template=ispell, + DictFile=ispell_sample, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +== 056 +DROP TEXT SEARCH DICTIONARY test_tsdict_exists +-- +STMT: DropStmt +== 057 +-- test search template +DROP TEXT SEARCH TEMPLATE test_tstemplate_exists +-- +STMT: DropStmt +== 058 +DROP TEXT SEARCH TEMPLATE IF EXISTS test_tstemplate_exists +-- +STMT: DropStmt +== 059 +-- text search configuration +DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists +-- +STMT: DropStmt +== 060 +DROP TEXT SEARCH CONFIGURATION IF EXISTS test_tsconfig_exists +-- +STMT: DropStmt +== 061 +CREATE TEXT SEARCH CONFIGURATION test_tsconfig_exists (COPY=english) +-- +STMT: DefineStmt +== 062 +DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists +-- +STMT: DropStmt +== 063 +-- extension +DROP EXTENSION test_extension_exists +-- +STMT: DropStmt +== 064 +DROP EXTENSION IF EXISTS test_extension_exists +-- +STMT: DropStmt +== 065 +-- functions +DROP FUNCTION test_function_exists() +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +== 066 +DROP FUNCTION IF EXISTS test_function_exists() +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +== 067 +DROP FUNCTION test_function_exists(int, text, int[]) +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +== 068 +DROP FUNCTION IF EXISTS test_function_exists(int, text, int[]) +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +== 069 +-- aggregate +DROP AGGREGATE test_aggregate_exists(*) +-- +STMT: DropStmt +== 070 +DROP AGGREGATE IF EXISTS test_aggregate_exists(*) +-- +STMT: DropStmt +== 071 +DROP AGGREGATE test_aggregate_exists(int) +-- +STMT: DropStmt +== 072 +DROP AGGREGATE IF EXISTS test_aggregate_exists(int) +-- +STMT: DropStmt +== 073 +-- operator +DROP OPERATOR @#@ (int, int) +-- +STMT: DropStmt +== 074 +DROP OPERATOR IF EXISTS @#@ (int, int) +-- +STMT: DropStmt +== 075 +CREATE OPERATOR @#@ + (leftarg = int8, rightarg = int8, procedure = int8xor) +-- +STMT: DefineStmt +== 076 +DROP OPERATOR @#@ (int8, int8) +-- +STMT: DropStmt +== 077 +-- language +DROP LANGUAGE test_language_exists +-- +STMT: DropStmt +== 078 +DROP LANGUAGE IF EXISTS test_language_exists +-- +STMT: DropStmt +== 079 +-- cast +DROP CAST (text AS text) +-- +STMT: DropStmt +== 080 +DROP CAST IF EXISTS (text AS text) +-- +STMT: DropStmt +== 081 +-- trigger +DROP TRIGGER test_trigger_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 082 +DROP TRIGGER IF EXISTS test_trigger_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 083 +DROP TRIGGER test_trigger_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +== 084 +DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +== 085 +DROP TRIGGER test_trigger_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +== 086 +DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +== 087 +CREATE TRIGGER test_trigger_exists + BEFORE UPDATE ON test_exists + FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger() +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: CreateTrigStmt +== 088 +DROP TRIGGER test_trigger_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 089 +-- rule +DROP RULE test_rule_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 090 +DROP RULE IF EXISTS test_rule_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 091 +DROP RULE test_rule_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +== 092 +DROP RULE IF EXISTS test_rule_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +== 093 +DROP RULE test_rule_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +== 094 +DROP RULE IF EXISTS test_rule_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +== 095 +CREATE RULE test_rule_exists AS ON INSERT TO test_exists + DO INSTEAD + INSERT INTO test_exists VALUES (NEW.a, NEW.b || NEW.a::text) +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: RuleStmt +== 096 +DROP RULE test_rule_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 097 +-- foreign data wrapper +DROP FOREIGN DATA WRAPPER test_fdw_exists +-- +STMT: DropStmt +== 098 +DROP FOREIGN DATA WRAPPER IF EXISTS test_fdw_exists +-- +STMT: DropStmt +== 099 +-- foreign server +DROP SERVER test_server_exists +-- +STMT: DropStmt +== 100 +DROP SERVER IF EXISTS test_server_exists +-- +STMT: DropStmt +== 101 +-- operator class +DROP OPERATOR CLASS test_operator_class USING btree +-- +STMT: DropStmt +== 102 +DROP OPERATOR CLASS IF EXISTS test_operator_class USING btree +-- +STMT: DropStmt +== 103 +DROP OPERATOR CLASS test_operator_class USING no_such_am +-- +STMT: DropStmt +== 104 +DROP OPERATOR CLASS IF EXISTS test_operator_class USING no_such_am +-- +STMT: DropStmt +== 105 +-- operator family +DROP OPERATOR FAMILY test_operator_family USING btree +-- +STMT: DropStmt +== 106 +DROP OPERATOR FAMILY IF EXISTS test_operator_family USING btree +-- +STMT: DropStmt +== 107 +DROP OPERATOR FAMILY test_operator_family USING no_such_am +-- +STMT: DropStmt +== 108 +DROP OPERATOR FAMILY IF EXISTS test_operator_family USING no_such_am +-- +STMT: DropStmt +== 109 +-- access method +DROP ACCESS METHOD no_such_am +-- +STMT: DropStmt +== 110 +DROP ACCESS METHOD IF EXISTS no_such_am +-- +STMT: DropStmt +== 111 +-- drop the table + +DROP TABLE IF EXISTS test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 112 +DROP TABLE test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +== 113 +-- be tolerant with missing schemas, types, etc + +DROP AGGREGATE IF EXISTS no_such_schema.foo(int) +-- +STMT: DropStmt +== 114 +DROP AGGREGATE IF EXISTS foo(no_such_type) +-- +STMT: DropStmt +== 115 +DROP AGGREGATE IF EXISTS foo(no_such_schema.no_such_type) +-- +STMT: DropStmt +== 116 +DROP CAST IF EXISTS (INTEGER AS no_such_type2) +-- +STMT: DropStmt +== 117 +DROP CAST IF EXISTS (no_such_type1 AS INTEGER) +-- +STMT: DropStmt +== 118 +DROP CAST IF EXISTS (INTEGER AS no_such_schema.bar) +-- +STMT: DropStmt +== 119 +DROP CAST IF EXISTS (no_such_schema.foo AS INTEGER) +-- +STMT: DropStmt +== 120 +DROP COLLATION IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 121 +DROP CONVERSION IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 122 +DROP DOMAIN IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 123 +DROP FOREIGN TABLE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 124 +DROP FUNCTION IF EXISTS no_such_schema.foo() +-- +FUNCTION: name="no_such_schema.foo" function="foo" schema="no_such_schema" ctx=DDL +STMT: DropStmt +== 125 +DROP FUNCTION IF EXISTS foo(no_such_type) +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: DropStmt +== 126 +DROP FUNCTION IF EXISTS foo(no_such_schema.no_such_type) +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: DropStmt +== 127 +DROP INDEX IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 128 +DROP MATERIALIZED VIEW IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 129 +DROP OPERATOR IF EXISTS no_such_schema.+ (int, int) +-- +STMT: DropStmt +== 130 +DROP OPERATOR IF EXISTS + (no_such_type, no_such_type) +-- +STMT: DropStmt +== 131 +DROP OPERATOR IF EXISTS + (no_such_schema.no_such_type, no_such_schema.no_such_type) +-- +STMT: DropStmt +== 132 +DROP OPERATOR IF EXISTS # (NONE, no_such_schema.no_such_type) +-- +STMT: DropStmt +== 133 +DROP OPERATOR CLASS IF EXISTS no_such_schema.widget_ops USING btree +-- +STMT: DropStmt +== 134 +DROP OPERATOR FAMILY IF EXISTS no_such_schema.float_ops USING btree +-- +STMT: DropStmt +== 135 +DROP RULE IF EXISTS foo ON no_such_schema.bar +-- +TABLE: name="no_such_schema.bar" schema="no_such_schema" table="bar" ctx=DDL +STMT: DropStmt +== 136 +DROP SEQUENCE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 137 +DROP TABLE IF EXISTS no_such_schema.foo +-- +TABLE: name="no_such_schema.foo" schema="no_such_schema" table="foo" ctx=DDL +STMT: DropStmt +== 138 +DROP TEXT SEARCH CONFIGURATION IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 139 +DROP TEXT SEARCH DICTIONARY IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 140 +DROP TEXT SEARCH PARSER IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 141 +DROP TEXT SEARCH TEMPLATE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 142 +DROP TRIGGER IF EXISTS foo ON no_such_schema.bar +-- +TABLE: name="no_such_schema.bar" schema="no_such_schema" table="bar" ctx=DDL +STMT: DropStmt +== 143 +DROP TYPE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 144 +DROP VIEW IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +== 145 +-- Check we receive an ambiguous function error when there are +-- multiple matching functions. +CREATE FUNCTION test_ambiguous_funcname(int) returns int as $$ select $1; $$ language sql +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 146 +CREATE FUNCTION test_ambiguous_funcname(text) returns text as $$ select $1; $$ language sql +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 147 +DROP FUNCTION test_ambiguous_funcname +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +== 148 +DROP FUNCTION IF EXISTS test_ambiguous_funcname +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +== 149 +-- cleanup +DROP FUNCTION test_ambiguous_funcname(int) +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +== 150 +DROP FUNCTION test_ambiguous_funcname(text) +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +== 151 +-- Likewise for procedures. +CREATE PROCEDURE test_ambiguous_procname(int) as $$ begin end; $$ language plpgsql +-- +FUNCTION: name="test_ambiguous_procname" function="test_ambiguous_procname" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 152 +CREATE PROCEDURE test_ambiguous_procname(text) as $$ begin end; $$ language plpgsql +-- +FUNCTION: name="test_ambiguous_procname" function="test_ambiguous_procname" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 153 +DROP PROCEDURE test_ambiguous_procname +-- +STMT: DropStmt +== 154 +DROP PROCEDURE IF EXISTS test_ambiguous_procname +-- +STMT: DropStmt +== 155 +-- Check we get a similar error if we use ROUTINE instead of PROCEDURE. +DROP ROUTINE IF EXISTS test_ambiguous_procname +-- +STMT: DropStmt +== 156 +-- cleanup +DROP PROCEDURE test_ambiguous_procname(int) +-- +STMT: DropStmt +== 157 +DROP PROCEDURE test_ambiguous_procname(text) +-- +STMT: DropStmt +== 158 +-- This test checks both the functionality of 'if exists' and the syntax +-- of the drop database command. +drop database test_database_exists (force) +-- +STMT: DropdbStmt +== 159 +drop database test_database_exists with (force) +-- +STMT: DropdbStmt +== 160 +drop database if exists test_database_exists (force) +-- +STMT: DropdbStmt +== 161 +drop database if exists test_database_exists with (force) +-- +STMT: DropdbStmt diff --git a/parser/testdata/summary/postgres_regress/drop_operator.metadata.json b/parser/testdata/summary/postgres_regress/drop_operator.metadata.json new file mode 100644 index 0000000..bf73c3a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/drop_operator.metadata.json @@ -0,0 +1,16 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012" + ] +} diff --git a/parser/testdata/summary/postgres_regress/drop_operator.test b/parser/testdata/summary/postgres_regress/drop_operator.test new file mode 100644 index 0000000..48629ea --- /dev/null +++ b/parser/testdata/summary/postgres_regress/drop_operator.test @@ -0,0 +1,109 @@ +== 001 +CREATE OPERATOR === ( + PROCEDURE = int8eq, + LEFTARG = bigint, + RIGHTARG = bigint, + COMMUTATOR = === +) +-- +STMT: DefineStmt +== 002 +CREATE OPERATOR !== ( + PROCEDURE = int8ne, + LEFTARG = bigint, + RIGHTARG = bigint, + NEGATOR = ===, + COMMUTATOR = !== +) +-- +STMT: DefineStmt +== 003 +DROP OPERATOR !==(bigint, bigint) +-- +STMT: DropStmt +== 004 +SELECT ctid, oprcom +FROM pg_catalog.pg_operator fk +WHERE oprcom != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprcom" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprcom" +STMT: SelectStmt +== 005 +SELECT ctid, oprnegate +FROM pg_catalog.pg_operator fk +WHERE oprnegate != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprnegate" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprnegate" +STMT: SelectStmt +== 006 +DROP OPERATOR ===(bigint, bigint) +-- +STMT: DropStmt +== 007 +CREATE OPERATOR <| ( + PROCEDURE = int8lt, + LEFTARG = bigint, + RIGHTARG = bigint +) +-- +STMT: DefineStmt +== 008 +CREATE OPERATOR |> ( + PROCEDURE = int8gt, + LEFTARG = bigint, + RIGHTARG = bigint, + NEGATOR = <|, + COMMUTATOR = <| +) +-- +STMT: DefineStmt +== 009 +DROP OPERATOR |>(bigint, bigint) +-- +STMT: DropStmt +== 010 +SELECT ctid, oprcom +FROM pg_catalog.pg_operator fk +WHERE oprcom != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprcom" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprcom" +STMT: SelectStmt +== 011 +SELECT ctid, oprnegate +FROM pg_catalog.pg_operator fk +WHERE oprnegate != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprnegate" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprnegate" +STMT: SelectStmt +== 012 +DROP OPERATOR <|(bigint, bigint) +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/enum.metadata.json b/parser/testdata/summary/postgres_regress/enum.metadata.json new file mode 100644 index 0000000..6f770d9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/enum.metadata.json @@ -0,0 +1,174 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170" + ] +} diff --git a/parser/testdata/summary/postgres_regress/enum.test b/parser/testdata/summary/postgres_regress/enum.test new file mode 100644 index 0000000..ba153dc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/enum.test @@ -0,0 +1,927 @@ +== 001 +|-- +-- Enum tests +|-- + +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple') +-- +STMT: CreateEnumStmt +== 002 +|-- +-- Did it create the right number of rows? +|-- +SELECT COUNT(*) FROM pg_enum WHERE enumtypid = 'rainbow'::regtype +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 003 +|-- +-- I/O functions +|-- +SELECT 'red'::rainbow +-- +STMT: SelectStmt +== 004 +SELECT 'mauve'::rainbow +-- +STMT: SelectStmt +== 005 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('red', 'rainbow') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT pg_input_is_valid('mauve', 'rainbow') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT * FROM pg_input_error_info('mauve', 'rainbow') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT * FROM pg_input_error_info(repeat('too_long', 32), 'rainbow') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 009 +|-- +-- adding new values +|-- + +CREATE TYPE planets AS ENUM ( 'venus', 'earth', 'mars' ) +-- +STMT: CreateEnumStmt +== 010 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 011 +ALTER TYPE planets ADD VALUE 'uranus' +-- +STMT: AlterEnumStmt +== 012 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 013 +ALTER TYPE planets ADD VALUE 'mercury' BEFORE 'venus' +-- +STMT: AlterEnumStmt +== 014 +ALTER TYPE planets ADD VALUE 'saturn' BEFORE 'uranus' +-- +STMT: AlterEnumStmt +== 015 +ALTER TYPE planets ADD VALUE 'jupiter' AFTER 'mars' +-- +STMT: AlterEnumStmt +== 016 +ALTER TYPE planets ADD VALUE 'neptune' AFTER 'uranus' +-- +STMT: AlterEnumStmt +== 017 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 018 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY enumlabel::planets +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 019 +-- errors for adding labels +ALTER TYPE planets ADD VALUE + 'plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto' +-- +STMT: AlterEnumStmt +== 020 +ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus' +-- +STMT: AlterEnumStmt +== 021 +-- if not exists tests + +-- existing value gives error +ALTER TYPE planets ADD VALUE 'mercury' +-- +STMT: AlterEnumStmt +== 022 +-- unless IF NOT EXISTS is specified +ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury' +-- +STMT: AlterEnumStmt +== 023 +-- should be neptune, not mercury +SELECT enum_last(NULL::planets) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +== 024 +ALTER TYPE planets ADD VALUE IF NOT EXISTS 'pluto' +-- +STMT: AlterEnumStmt +== 025 +-- should be pluto, i.e. the new value +SELECT enum_last(NULL::planets) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +== 026 +|-- +-- Test inserting so many values that we have to renumber +|-- + +create type insenum as enum ('L1', 'L2') +-- +STMT: CreateEnumStmt +== 027 +alter type insenum add value 'i1' before 'L2' +-- +STMT: AlterEnumStmt +== 028 +alter type insenum add value 'i2' before 'L2' +-- +STMT: AlterEnumStmt +== 029 +alter type insenum add value 'i3' before 'L2' +-- +STMT: AlterEnumStmt +== 030 +alter type insenum add value 'i4' before 'L2' +-- +STMT: AlterEnumStmt +== 031 +alter type insenum add value 'i5' before 'L2' +-- +STMT: AlterEnumStmt +== 032 +alter type insenum add value 'i6' before 'L2' +-- +STMT: AlterEnumStmt +== 033 +alter type insenum add value 'i7' before 'L2' +-- +STMT: AlterEnumStmt +== 034 +alter type insenum add value 'i8' before 'L2' +-- +STMT: AlterEnumStmt +== 035 +alter type insenum add value 'i9' before 'L2' +-- +STMT: AlterEnumStmt +== 036 +alter type insenum add value 'i10' before 'L2' +-- +STMT: AlterEnumStmt +== 037 +alter type insenum add value 'i11' before 'L2' +-- +STMT: AlterEnumStmt +== 038 +alter type insenum add value 'i12' before 'L2' +-- +STMT: AlterEnumStmt +== 039 +alter type insenum add value 'i13' before 'L2' +-- +STMT: AlterEnumStmt +== 040 +alter type insenum add value 'i14' before 'L2' +-- +STMT: AlterEnumStmt +== 041 +alter type insenum add value 'i15' before 'L2' +-- +STMT: AlterEnumStmt +== 042 +alter type insenum add value 'i16' before 'L2' +-- +STMT: AlterEnumStmt +== 043 +alter type insenum add value 'i17' before 'L2' +-- +STMT: AlterEnumStmt +== 044 +alter type insenum add value 'i18' before 'L2' +-- +STMT: AlterEnumStmt +== 045 +alter type insenum add value 'i19' before 'L2' +-- +STMT: AlterEnumStmt +== 046 +alter type insenum add value 'i20' before 'L2' +-- +STMT: AlterEnumStmt +== 047 +alter type insenum add value 'i21' before 'L2' +-- +STMT: AlterEnumStmt +== 048 +alter type insenum add value 'i22' before 'L2' +-- +STMT: AlterEnumStmt +== 049 +alter type insenum add value 'i23' before 'L2' +-- +STMT: AlterEnumStmt +== 050 +alter type insenum add value 'i24' before 'L2' +-- +STMT: AlterEnumStmt +== 051 +alter type insenum add value 'i25' before 'L2' +-- +STMT: AlterEnumStmt +== 052 +alter type insenum add value 'i26' before 'L2' +-- +STMT: AlterEnumStmt +== 053 +alter type insenum add value 'i27' before 'L2' +-- +STMT: AlterEnumStmt +== 054 +alter type insenum add value 'i28' before 'L2' +-- +STMT: AlterEnumStmt +== 055 +alter type insenum add value 'i29' before 'L2' +-- +STMT: AlterEnumStmt +== 056 +alter type insenum add value 'i30' before 'L2' +-- +STMT: AlterEnumStmt +== 057 +-- The exact values of enumsortorder will now depend on the local properties +-- of float4, but in any reasonable implementation we should get at least +-- 20 splits before having to renumber; so only hide values > 20. + +SELECT enumlabel, + case when enumsortorder > 20 then null else enumsortorder end as so +FROM pg_enum +WHERE enumtypid = 'insenum'::regtype +ORDER BY enumsortorder +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 058 +|-- +-- Basic table creation, row selection +|-- +CREATE TABLE enumtest (col rainbow) +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: CreateStmt +== 059 +INSERT INTO enumtest values ('red'), ('orange'), ('yellow'), ('green') +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +COPY enumtest FROM stdin +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +STMT: CopyStmt +== 061 +SELECT * FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +STMT: SelectStmt +== 062 +|-- +-- Operators, no index +|-- +SELECT * FROM enumtest WHERE col = 'orange' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 063 +SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 064 +SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 065 +SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 066 +SELECT * FROM enumtest WHERE col < 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 067 +SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 068 +|-- +-- Cast to/from text +|-- +SELECT 'red'::rainbow::text || 'hithere' +-- +STMT: SelectStmt +== 069 +SELECT 'red'::text::rainbow = 'red'::rainbow +-- +STMT: SelectStmt +== 070 +|-- +-- Aggregates +|-- +SELECT min(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT max(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT max(col) FROM enumtest WHERE col < 'green' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 073 +|-- +-- Index tests, force use of index +|-- +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 074 +SET enable_bitmapscan = off +-- +STMT: VariableSetStmt +== 075 +|-- +-- Btree index / opclass with the various operators +|-- +CREATE UNIQUE INDEX enumtest_btree ON enumtest USING btree (col) +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: IndexStmt +== 076 +SELECT * FROM enumtest WHERE col = 'orange' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 077 +SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 078 +SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 079 +SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 080 +SELECT * FROM enumtest WHERE col < 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 081 +SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 082 +SELECT min(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT max(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 084 +SELECT max(col) FROM enumtest WHERE col < 'green' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 085 +DROP INDEX enumtest_btree +-- +STMT: DropStmt +== 086 +|-- +-- Hash index / opclass with the = operator +|-- +CREATE INDEX enumtest_hash ON enumtest USING hash (col) +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: IndexStmt +== 087 +SELECT * FROM enumtest WHERE col = 'orange' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +== 088 +DROP INDEX enumtest_hash +-- +STMT: DropStmt +== 089 +|-- +-- End index tests +|-- +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 090 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 091 +|-- +-- Domains over enums +|-- +CREATE DOMAIN rgb AS rainbow CHECK (VALUE IN ('red', 'green', 'blue')) +-- +STMT: CreateDomainStmt +== 092 +SELECT 'red'::rgb +-- +STMT: SelectStmt +== 093 +SELECT 'purple'::rgb +-- +STMT: SelectStmt +== 094 +SELECT 'purple'::rainbow::rgb +-- +STMT: SelectStmt +== 095 +DROP DOMAIN rgb +-- +STMT: DropStmt +== 096 +|-- +-- Arrays +|-- +SELECT '{red,green,blue}'::rainbow[] +-- +STMT: SelectStmt +== 097 +SELECT ('{red,green,blue}'::rainbow[])[2] +-- +STMT: SelectStmt +== 098 +SELECT 'red' = ANY ('{red,green,blue}'::rainbow[]) +-- +STMT: SelectStmt +== 099 +SELECT 'yellow' = ANY ('{red,green,blue}'::rainbow[]) +-- +STMT: SelectStmt +== 100 +SELECT 'red' = ALL ('{red,green,blue}'::rainbow[]) +-- +STMT: SelectStmt +== 101 +SELECT 'red' = ALL ('{red,red}'::rainbow[]) +-- +STMT: SelectStmt +== 102 +|-- +-- Support functions +|-- +SELECT enum_first(NULL::rainbow) +-- +FUNCTION: name="enum_first" function="enum_first" schema="" ctx=Call +STMT: SelectStmt +== 103 +SELECT enum_last('green'::rainbow) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +== 104 +SELECT enum_range(NULL::rainbow) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 105 +SELECT enum_range('orange'::rainbow, 'green'::rainbow) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 106 +SELECT enum_range(NULL, 'green'::rainbow) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 107 +SELECT enum_range('orange'::rainbow, NULL) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT enum_range(NULL::rainbow, NULL) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 109 +|-- +-- User functions, can't test perl/python etc here since may not be compiled. +|-- +CREATE FUNCTION echo_me(anyenum) RETURNS text AS $$ +BEGIN +RETURN $1::text || 'omg'; +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 110 +SELECT echo_me('red'::rainbow) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=Call +STMT: SelectStmt +== 111 +|-- +-- Concrete function should override generic one +|-- +CREATE FUNCTION echo_me(rainbow) RETURNS text AS $$ +BEGIN +RETURN $1::text || 'wtf'; +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 112 +SELECT echo_me('red'::rainbow) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=Call +STMT: SelectStmt +== 113 +|-- +-- If we drop the original generic one, we don't have to qualify the type +-- anymore, since there's only one match +|-- +DROP FUNCTION echo_me(anyenum) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: DropStmt +== 114 +SELECT echo_me('red') +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=Call +STMT: SelectStmt +== 115 +DROP FUNCTION echo_me(rainbow) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: DropStmt +== 116 +|-- +-- RI triggers on enum types +|-- +CREATE TABLE enumtest_parent (id rainbow PRIMARY KEY) +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DDL +STMT: CreateStmt +== 117 +CREATE TABLE enumtest_child (parent rainbow REFERENCES enumtest_parent) +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DDL +STMT: CreateStmt +== 118 +INSERT INTO enumtest_parent VALUES ('red') +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +INSERT INTO enumtest_child VALUES ('red') +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 120 +INSERT INTO enumtest_child VALUES ('blue') +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +-- fail +DELETE FROM enumtest_parent +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DML +STMT: DeleteStmt +== 122 +-- fail +|-- +-- cross-type RI should fail +|-- +CREATE TYPE bogus AS ENUM('good', 'bad', 'ugly') +-- +STMT: CreateEnumStmt +== 123 +CREATE TABLE enumtest_bogus_child(parent bogus REFERENCES enumtest_parent) +-- +TABLE: name="enumtest_bogus_child" schema="" table="enumtest_bogus_child" ctx=DDL +STMT: CreateStmt +== 124 +DROP TYPE bogus +-- +STMT: DropStmt +== 125 +-- check renaming a value +ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson' +-- +STMT: AlterEnumStmt +== 126 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'rainbow'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 127 +-- check that renaming a non-existent value fails +ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson' +-- +STMT: AlterEnumStmt +== 128 +-- check that renaming to an existent value fails +ALTER TYPE rainbow RENAME VALUE 'blue' TO 'green' +-- +STMT: AlterEnumStmt +== 129 +|-- +-- check transactional behaviour of ALTER TYPE ... ADD VALUE +|-- +CREATE TYPE bogus AS ENUM('good') +-- +STMT: CreateEnumStmt +== 130 +-- check that we can add new values to existing enums in a transaction +-- but we can't use them +BEGIN +-- +STMT: TransactionStmt +== 131 +ALTER TYPE bogus ADD VALUE 'new' +-- +STMT: AlterEnumStmt +== 132 +SAVEPOINT x +-- +STMT: TransactionStmt +== 133 +SELECT 'new'::bogus +-- +STMT: SelectStmt +== 134 +-- unsafe +ROLLBACK TO x +-- +STMT: TransactionStmt +== 135 +SELECT enum_first(null::bogus) +-- +FUNCTION: name="enum_first" function="enum_first" schema="" ctx=Call +STMT: SelectStmt +== 136 +-- safe +SELECT enum_last(null::bogus) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +== 137 +-- unsafe +ROLLBACK TO x +-- +STMT: TransactionStmt +== 138 +SELECT enum_range(null::bogus) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 139 +-- unsafe +ROLLBACK TO x +-- +STMT: TransactionStmt +== 140 +COMMIT +-- +STMT: TransactionStmt +== 141 +SELECT 'new'::bogus +-- +STMT: SelectStmt +== 142 +-- now safe +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'bogus'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +== 143 +-- check that we recognize the case where the enum already existed but was +-- modified in the current txn; this should not be considered safe +BEGIN +-- +STMT: TransactionStmt +== 144 +ALTER TYPE bogus RENAME TO bogon +-- +STMT: RenameStmt +== 145 +ALTER TYPE bogon ADD VALUE 'bad' +-- +STMT: AlterEnumStmt +== 146 +SELECT 'bad'::bogon +-- +STMT: SelectStmt +== 147 +ROLLBACK +-- +STMT: TransactionStmt +== 148 +-- but a renamed value is safe to use later in same transaction +BEGIN +-- +STMT: TransactionStmt +== 149 +ALTER TYPE bogus RENAME VALUE 'good' to 'bad' +-- +STMT: AlterEnumStmt +== 150 +SELECT 'bad'::bogus +-- +STMT: SelectStmt +== 151 +ROLLBACK +-- +STMT: TransactionStmt +== 152 +DROP TYPE bogus +-- +STMT: DropStmt +== 153 +-- check that values created during CREATE TYPE can be used in any case +BEGIN +-- +STMT: TransactionStmt +== 154 +CREATE TYPE bogus AS ENUM('good','bad','ugly') +-- +STMT: CreateEnumStmt +== 155 +ALTER TYPE bogus RENAME TO bogon +-- +STMT: RenameStmt +== 156 +select enum_range(null::bogon) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 157 +ROLLBACK +-- +STMT: TransactionStmt +== 158 +-- we must allow this usage to support pg_dump in binary upgrade mode +BEGIN +-- +STMT: TransactionStmt +== 159 +CREATE TYPE bogus AS ENUM('good') +-- +STMT: CreateEnumStmt +== 160 +ALTER TYPE bogus RENAME TO bogon +-- +STMT: RenameStmt +== 161 +ALTER TYPE bogon ADD VALUE 'bad' +-- +STMT: AlterEnumStmt +== 162 +ALTER TYPE bogon ADD VALUE 'ugly' +-- +STMT: AlterEnumStmt +== 163 +select enum_range(null::bogon) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +== 164 +ROLLBACK +-- +STMT: TransactionStmt +== 165 +|-- +-- Cleanup +|-- +DROP TABLE enumtest_child +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DDL +STMT: DropStmt +== 166 +DROP TABLE enumtest_parent +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DDL +STMT: DropStmt +== 167 +DROP TABLE enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: DropStmt +== 168 +DROP TYPE rainbow +-- +STMT: DropStmt +== 169 +|-- +-- Verify properly cleaned up +|-- +SELECT COUNT(*) FROM pg_type WHERE typname = 'rainbow' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +== 170 +SELECT * FROM pg_enum WHERE NOT EXISTS + (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid) +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="pg_type" column="oid" +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/equivclass.metadata.json b/parser/testdata/summary/postgres_regress/equivclass.metadata.json new file mode 100644 index 0000000..364fcc5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/equivclass.metadata.json @@ -0,0 +1,83 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079" + ] +} diff --git a/parser/testdata/summary/postgres_regress/equivclass.test b/parser/testdata/summary/postgres_regress/equivclass.test new file mode 100644 index 0000000..f1e0b15 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/equivclass.test @@ -0,0 +1,640 @@ +== 001 +|-- +-- Tests for the planner's "equivalence class" mechanism +|-- + +-- One thing that's not tested well during normal querying is the logic +-- for handling "broken" ECs. This is because an EC can only become broken +-- if its underlying btree operator family doesn't include a complete set +-- of cross-type equality operators. There are not (and should not be) +-- any such families built into Postgres; so we have to hack things up +-- to create one. We do this by making two alias types that are really +-- int8 (so we need no new C code) and adding only some operators for them +-- into the standard integer_ops opfamily. + +create type int8alias1 +-- +STMT: DefineStmt +== 002 +create function int8alias1in(cstring) returns int8alias1 + strict immutable language internal as 'int8in' +-- +FUNCTION: name="int8alias1in" function="int8alias1in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +create function int8alias1out(int8alias1) returns cstring + strict immutable language internal as 'int8out' +-- +FUNCTION: name="int8alias1out" function="int8alias1out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 004 +create type int8alias1 ( + input = int8alias1in, + output = int8alias1out, + like = int8 +) +-- +STMT: DefineStmt +== 005 +create type int8alias2 +-- +STMT: DefineStmt +== 006 +create function int8alias2in(cstring) returns int8alias2 + strict immutable language internal as 'int8in' +-- +FUNCTION: name="int8alias2in" function="int8alias2in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +create function int8alias2out(int8alias2) returns cstring + strict immutable language internal as 'int8out' +-- +FUNCTION: name="int8alias2out" function="int8alias2out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 008 +create type int8alias2 ( + input = int8alias2in, + output = int8alias2out, + like = int8 +) +-- +STMT: DefineStmt +== 009 +create cast (int8 as int8alias1) without function +-- +STMT: CreateCastStmt +== 010 +create cast (int8 as int8alias2) without function +-- +STMT: CreateCastStmt +== 011 +create cast (int8alias1 as int8) without function +-- +STMT: CreateCastStmt +== 012 +create cast (int8alias2 as int8) without function +-- +STMT: CreateCastStmt +== 013 +create function int8alias1eq(int8alias1, int8alias1) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias1eq" function="int8alias1eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 014 +create operator = ( + procedure = int8alias1eq, + leftarg = int8alias1, rightarg = int8alias1, + commutator = =, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +== 015 +alter operator family integer_ops using btree add + operator 3 = (int8alias1, int8alias1) +-- +STMT: AlterOpFamilyStmt +== 016 +create function int8alias2eq(int8alias2, int8alias2) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias2eq" function="int8alias2eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +create operator = ( + procedure = int8alias2eq, + leftarg = int8alias2, rightarg = int8alias2, + commutator = =, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +== 018 +alter operator family integer_ops using btree add + operator 3 = (int8alias2, int8alias2) +-- +STMT: AlterOpFamilyStmt +== 019 +create function int8alias1eq(int8, int8alias1) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias1eq" function="int8alias1eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 020 +create operator = ( + procedure = int8alias1eq, + leftarg = int8, rightarg = int8alias1, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +== 021 +alter operator family integer_ops using btree add + operator 3 = (int8, int8alias1) +-- +STMT: AlterOpFamilyStmt +== 022 +create function int8alias1eq(int8alias1, int8alias2) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias1eq" function="int8alias1eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 023 +create operator = ( + procedure = int8alias1eq, + leftarg = int8alias1, rightarg = int8alias2, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +== 024 +alter operator family integer_ops using btree add + operator 3 = (int8alias1, int8alias2) +-- +STMT: AlterOpFamilyStmt +== 025 +create function int8alias1lt(int8alias1, int8alias1) returns bool + strict immutable language internal as 'int8lt' +-- +FUNCTION: name="int8alias1lt" function="int8alias1lt" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 026 +create operator < ( + procedure = int8alias1lt, + leftarg = int8alias1, rightarg = int8alias1 +) +-- +STMT: DefineStmt +== 027 +alter operator family integer_ops using btree add + operator 1 < (int8alias1, int8alias1) +-- +STMT: AlterOpFamilyStmt +== 028 +create function int8alias1cmp(int8, int8alias1) returns int + strict immutable language internal as 'btint8cmp' +-- +FUNCTION: name="int8alias1cmp" function="int8alias1cmp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +alter operator family integer_ops using btree add + function 1 int8alias1cmp (int8, int8alias1) +-- +STMT: AlterOpFamilyStmt +== 030 +create table ec0 (ff int8 primary key, f1 int8, f2 int8) +-- +TABLE: name="ec0" schema="" table="ec0" ctx=DDL +STMT: CreateStmt +== 031 +create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: CreateStmt +== 032 +create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2) +-- +TABLE: name="ec2" schema="" table="ec2" ctx=DDL +STMT: CreateStmt +== 033 +-- for the moment we only want to look at nestloop plans +set enable_hashjoin = off +-- +STMT: VariableSetStmt +== 034 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 035 +|-- +-- Note that for cases where there's a missing operator, we don't care so +-- much whether the plan is ideal as that we don't fail or generate an +-- outright incorrect plan. +|-- + +explain (costs off) + select * from ec0 where ff = f1 and f1 = '42'::int8 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 036 +explain (costs off) + select * from ec0 where ff = f1 and f1 = '42'::int8alias1 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 037 +explain (costs off) + select * from ec1 where ff = f1 and f1 = '42'::int8alias1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 038 +explain (costs off) + select * from ec1 where ff = f1 and f1 = '42'::int8alias2 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +explain (costs off) + select * from ec1, ec2 where ff = x1 and ff = '42'::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 040 +explain (costs off) + select * from ec1, ec2 where ff = x1 and ff = '42'::int8alias1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 041 +explain (costs off) + select * from ec1, ec2 where ff = x1 and '42'::int8 = x1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x1" +STMT: ExplainStmt +STMT: SelectStmt +== 042 +explain (costs off) + select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x1" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +explain (costs off) + select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias2 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x1" +STMT: ExplainStmt +STMT: SelectStmt +== 044 +create unique index ec1_expr1 on ec1((ff + 1)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +== 045 +create unique index ec1_expr2 on ec1((ff + 2 + 1)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +== 046 +create unique index ec1_expr3 on ec1((ff + 3 + 1)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +== 047 +create unique index ec1_expr4 on ec1((ff + 4)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +== 048 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 049 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 and ec1.ff = ec1.f1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +FILTER: schema="" table="ec1" column="ff" +FILTER: schema="" table="ec1" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss2 + where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ss2" column="x" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 051 +-- let's try that as a mergejoin +set enable_mergejoin = on +-- +STMT: VariableSetStmt +== 052 +set enable_nestloop = off +-- +STMT: VariableSetStmt +== 053 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss2 + where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ss2" column="x" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 054 +-- check partially indexed scan +set enable_nestloop = on +-- +STMT: VariableSetStmt +== 055 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 056 +drop index ec1_expr3 +-- +STMT: DropStmt +== 057 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 058 +-- let's try that as a mergejoin +set enable_mergejoin = on +-- +STMT: VariableSetStmt +== 059 +set enable_nestloop = off +-- +STMT: VariableSetStmt +== 060 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 061 +-- check effects of row-level security +set enable_nestloop = on +-- +STMT: VariableSetStmt +== 062 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 063 +alter table ec1 enable row level security +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: AlterTableStmt +== 064 +create policy p1 on ec1 using (f1 < '5'::int8alias1) +-- +STMT: CreatePolicyStmt +== 065 +create user regress_user_ectest +-- +STMT: CreateRoleStmt +== 066 +grant select on ec0 to regress_user_ectest +-- +TABLE: name="ec0" schema="" table="ec0" ctx=DDL +STMT: GrantStmt +== 067 +grant select on ec1 to regress_user_ectest +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: GrantStmt +== 068 +-- without any RLS, we'll treat {a.ff, b.ff, 43} as an EquivalenceClass +explain (costs off) + select * from ec0 a, ec1 b + where a.ff = b.ff and a.ff = 43::bigint::int8alias1 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +ALIAS: "a"="ec0" +ALIAS: "b"="ec1" +FILTER: schema="" table="a" column="ff" +FILTER: schema="" table="b" column="ff" +FILTER: schema="" table="a" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 069 +set session authorization regress_user_ectest +-- +STMT: VariableSetStmt +== 070 +-- with RLS active, the non-leakproof a.ff = 43 clause is not treated +-- as a suitable source for an EquivalenceClass; currently, this is true +-- even though the RLS clause has nothing to do directly with the EC +explain (costs off) + select * from ec0 a, ec1 b + where a.ff = b.ff and a.ff = 43::bigint::int8alias1 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +ALIAS: "a"="ec0" +ALIAS: "b"="ec1" +FILTER: schema="" table="a" column="ff" +FILTER: schema="" table="b" column="ff" +FILTER: schema="" table="a" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +== 071 +reset session authorization +-- +STMT: VariableSetStmt +== 072 +revoke select on ec0 from regress_user_ectest +-- +TABLE: name="ec0" schema="" table="ec0" ctx=DDL +STMT: GrantStmt +== 073 +revoke select on ec1 from regress_user_ectest +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: GrantStmt +== 074 +drop user regress_user_ectest +-- +STMT: DropRoleStmt +== 075 +-- check that X=X is converted to X IS NOT NULL when appropriate +explain (costs off) + select * from tenk1 where unique1 = unique1 and unique2 = unique2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 076 +-- this could be converted, but isn't at present +explain (costs off) + select * from tenk1 where unique1 = unique1 or unique2 = unique2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 077 +-- check that we recognize equivalence with dummy domains in the way +create temp table undername (f1 name, f2 int) +-- +TABLE: name="undername" schema="" table="undername" ctx=DDL +STMT: CreateStmt +== 078 +create temp view overview as + select f1::information_schema.sql_identifier as sqli, f2 from undername +-- +TABLE: name="overview" schema="" table="overview" ctx=DDL +TABLE: name="undername" schema="" table="undername" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 079 +explain (costs off) -- this should not require a sort + select * from overview where sqli = 'foo' order by sqli +-- +TABLE: name="overview" schema="" table="overview" ctx=Select +FILTER: schema="" table="" column="sqli" +STMT: ExplainStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/errors.metadata.json b/parser/testdata/summary/postgres_regress/errors.metadata.json new file mode 100644 index 0000000..b064cb7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/errors.metadata.json @@ -0,0 +1,89 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085" + ] +} diff --git a/parser/testdata/summary/postgres_regress/errors.test b/parser/testdata/summary/postgres_regress/errors.test new file mode 100644 index 0000000..5cdae13 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/errors.test @@ -0,0 +1,666 @@ +== 001 +|-- +-- ERRORS +|-- + +-- bad in postquel, but ok in PostgreSQL +select 1 +-- +STMT: SelectStmt +== 002 +|-- +-- UNSUPPORTED STUFF + +-- doesn't work +-- notify pg_class +|-- + +|-- +-- SELECT + +-- this used to be a syntax error, but now we allow an empty target list +select +-- +STMT: SelectStmt +== 003 +-- no such relation +select * from nonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=Select +STMT: SelectStmt +== 004 +-- bad name in target list +select nonesuch from pg_database +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +== 005 +-- empty distinct list isn't OK +select distinct from pg_database +-- +ERROR: syntax error at or near "from" +CURSORPOS: 49 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- bad attribute name on lhs of operator +select * from pg_database where nonesuch = pg_database.datname +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FILTER: schema="" table="" column="nonesuch" +FILTER: schema="" table="pg_database" column="datname" +STMT: SelectStmt +== 007 +-- bad attribute name on rhs of operator +select * from pg_database where pg_database.datname = nonesuch +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FILTER: schema="" table="pg_database" column="datname" +FILTER: schema="" table="" column="nonesuch" +STMT: SelectStmt +== 008 +-- bad attribute name in select distinct on +select distinct on (foobar) * from pg_database +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +== 009 +-- grouping with FOR UPDATE +select null from pg_database group by datname for update +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +== 010 +select null from pg_database group by grouping sets (()) for update +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +== 011 +|-- +-- DELETE + +-- missing relation name (this had better not wildcard!) +delete from +-- +ERROR: syntax error at end of input +CURSORPOS: 83 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- no such relation +delete from nonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DML +STMT: DeleteStmt +== 013 +|-- +-- DROP + +-- missing relation name (this had better not wildcard!) +drop table +-- +ERROR: syntax error at end of input +CURSORPOS: 80 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 014 +-- no such relation +drop table nonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DDL +STMT: DropStmt +== 015 +|-- +-- ALTER TABLE + +-- relation renaming + +-- missing relation name +alter table rename +-- +ERROR: syntax error at end of input +CURSORPOS: 85 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 016 +-- no such relation +alter table nonesuch rename to newnonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DDL +TABLE: name="newnonesuch" schema="" table="newnonesuch" ctx=DDL +STMT: RenameStmt +== 017 +-- no such relation +alter table nonesuch rename to stud_emp +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DDL +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: RenameStmt +== 018 +-- conflict +alter table stud_emp rename to student +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +TABLE: name="student" schema="" table="student" ctx=DDL +STMT: RenameStmt +== 019 +-- self-conflict +alter table stud_emp rename to stud_emp +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: RenameStmt +== 020 +-- attribute renaming + +-- no such relation +alter table nonesuchrel rename column nonesuchatt to newnonesuchatt +-- +STMT: RenameStmt +== 021 +-- no such attribute +alter table emp rename column nonesuchatt to newnonesuchatt +-- +STMT: RenameStmt +== 022 +-- conflict +alter table emp rename column salary to manager +-- +STMT: RenameStmt +== 023 +-- conflict +alter table emp rename column salary to ctid +-- +STMT: RenameStmt +== 024 +|-- +-- TRANSACTION STUFF + +-- not in a xact +abort +-- +STMT: TransactionStmt +== 025 +-- not in a xact +end +-- +STMT: TransactionStmt +== 026 +|-- +-- CREATE AGGREGATE + +-- sfunc/finalfunc type disagreement +create aggregate newavg2 (sfunc = int4pl, + basetype = int4, + stype = int4, + finalfunc = int2um, + initcond = '0') +-- +STMT: DefineStmt +== 027 +-- left out basetype +create aggregate newcnt1 (sfunc = int4inc, + stype = int4, + initcond = '0') +-- +STMT: DefineStmt +== 028 +|-- +-- DROP INDEX + +-- missing index name +drop index +-- +ERROR: syntax error at end of input +CURSORPOS: 51 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +-- bad index name +drop index 314159 +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 030 +-- no such index +drop index nonesuch +-- +STMT: DropStmt +== 031 +|-- +-- DROP AGGREGATE + +-- missing aggregate name +drop aggregate +-- +ERROR: syntax error at end of input +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 032 +-- missing aggregate type +drop aggregate newcnt1 +-- +ERROR: syntax error at end of input +CURSORPOS: 49 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 033 +-- bad aggregate name +drop aggregate 314159 (int) +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 034 +-- bad aggregate type +drop aggregate newcnt (nonesuch) +-- +STMT: DropStmt +== 035 +-- no such aggregate +drop aggregate nonesuch (int4) +-- +STMT: DropStmt +== 036 +-- no such aggregate for type +drop aggregate newcnt (float4) +-- +STMT: DropStmt +== 037 +|-- +-- DROP FUNCTION + +-- missing function name +drop function () +-- +ERROR: syntax error at or near "(" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +-- bad function name +drop function 314159() +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +-- no such function +drop function nonesuch() +-- +FUNCTION: name="nonesuch" function="nonesuch" schema="" ctx=DDL +STMT: DropStmt +== 040 +|-- +-- DROP TYPE + +-- missing type name +drop type +-- +ERROR: syntax error at end of input +CURSORPOS: 48 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 041 +-- bad type name +drop type 314159 +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 042 +-- no such type +drop type nonesuch +-- +STMT: DropStmt +== 043 +|-- +-- DROP OPERATOR + +-- missing everything +drop operator +-- +ERROR: syntax error at end of input +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 044 +-- bad operator name +drop operator equals +-- +ERROR: syntax error at end of input +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 045 +-- missing type list +drop operator === +-- +ERROR: syntax error at end of input +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 046 +-- missing parentheses +drop operator int4, int4 +-- +ERROR: syntax error at or near "," +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 047 +-- missing operator name +drop operator (int4, int4) +-- +ERROR: syntax error at or near "(" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 048 +-- missing type list contents +drop operator === () +-- +ERROR: syntax error at or near ")" +CURSORPOS: 50 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 049 +-- no such operator +drop operator === (int4) +-- +ERROR: missing argument +CURSORPOS: 44 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 050 +-- no such operator by that name +drop operator === (int4, int4) +-- +STMT: DropStmt +== 051 +-- no such type1 +drop operator = (nonesuch) +-- +ERROR: missing argument +CURSORPOS: 43 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 052 +-- no such type1 +drop operator = ( , int4) +-- +ERROR: syntax error at or near "," +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 053 +-- no such type1 +drop operator = (nonesuch, int4) +-- +STMT: DropStmt +== 054 +-- no such type2 +drop operator = (int4, nonesuch) +-- +STMT: DropStmt +== 055 +-- no such type2 +drop operator = (int4, ) +-- +ERROR: syntax error at or near ")" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 056 +|-- +-- DROP RULE + +-- missing rule name +drop rule +-- +ERROR: syntax error at end of input +CURSORPOS: 48 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 057 +-- bad rule name +drop rule 314159 +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 058 +-- no such rule +drop rule nonesuch on noplace +-- +TABLE: name="noplace" schema="" table="noplace" ctx=DDL +STMT: DropStmt +== 059 +-- these postquel variants are no longer supported +drop tuple rule nonesuch +-- +ERROR: syntax error at or near "tuple" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 060 +drop instance rule nonesuch on noplace +-- +ERROR: syntax error at or near "instance" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 061 +drop rewrite rule nonesuch +-- +ERROR: syntax error at or near "rewrite" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 062 +|-- +-- Check that division-by-zero is properly caught. +|-- + +select 1/0 +-- +STMT: SelectStmt +== 063 +select 1::int8/0 +-- +STMT: SelectStmt +== 064 +select 1/0::int8 +-- +STMT: SelectStmt +== 065 +select 1::int2/0 +-- +STMT: SelectStmt +== 066 +select 1/0::int2 +-- +STMT: SelectStmt +== 067 +select 1::numeric/0 +-- +STMT: SelectStmt +== 068 +select 1/0::numeric +-- +STMT: SelectStmt +== 069 +select 1::float8/0 +-- +STMT: SelectStmt +== 070 +select 1/0::float8 +-- +STMT: SelectStmt +== 071 +select 1::float4/0 +-- +STMT: SelectStmt +== 072 +select 1/0::float4 +-- +STMT: SelectStmt +== 073 +CREATE foo +-- +ERROR: syntax error at or near "foo" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 074 +CREATE TABLE +-- +ERROR: syntax error at end of input +CURSORPOS: 13 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +CREATE TABLE + +INSERT INTO foo VALUES(123) foo +-- +ERROR: syntax error at or near "INTO" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 076 +INSERT INTO 123 +VALUES(123) +-- +ERROR: syntax error at or near "123" +CURSORPOS: 13 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +INSERT INTO foo +VALUES(123) 123 +-- +ERROR: syntax error at or near "123" +CURSORPOS: 29 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 078 +-- with a tab +CREATE TABLE foo + (id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, + id3 INTEGER NOT NUL, + id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 108 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 079 +-- long line to be truncated on the left +CREATE TABLE foo(id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, +id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 080 +-- long line to be truncated on the right +CREATE TABLE foo( +id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 77 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 081 +-- long line to be truncated both ways +CREATE TABLE foo(id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 129 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 082 +-- long line to be truncated on the left, many lines +CREATE +TEMPORARY +TABLE +foo(id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, +id4 INT4 +UNIQUE +NOT +NULL, +id5 TEXT +UNIQUE +NOT +NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 153 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 083 +-- long line to be truncated on the right, many lines +CREATE +TEMPORARY +TABLE +foo( +id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 99 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 084 +-- long line to be truncated both ways, many lines +CREATE +TEMPORARY +TABLE +foo +(id +INT4 +UNIQUE NOT NULL, idx INT4 UNIQUE NOT NULL, idy INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, +idz INT4 UNIQUE NOT NULL, +idv INT4 UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 204 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 085 +-- more than 10 lines... +CREATE +TEMPORARY +TABLE +foo +(id +INT4 +UNIQUE +NOT +NULL +, +idm +INT4 +UNIQUE +NOT +NULL, +idx INT4 UNIQUE NOT NULL, idy INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, +idz INT4 UNIQUE NOT NULL, +idv +INT4 +UNIQUE +NOT +NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 205 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary/postgres_regress/event_trigger.metadata.json b/parser/testdata/summary/postgres_regress/event_trigger.metadata.json new file mode 100644 index 0000000..21e7df0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/event_trigger.metadata.json @@ -0,0 +1,234 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230" + ] +} diff --git a/parser/testdata/summary/postgres_regress/event_trigger.test b/parser/testdata/summary/postgres_regress/event_trigger.test new file mode 100644 index 0000000..74d9f8f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/event_trigger.test @@ -0,0 +1,1367 @@ +== 001 +-- should fail, return type mismatch +create event trigger regress_event_trigger + on ddl_command_start + execute procedure pg_backend_pid() +-- +STMT: CreateEventTrigStmt +== 002 +-- OK +create function test_event_trigger() returns event_trigger as $$ +BEGIN + RAISE NOTICE 'test_event_trigger: % %', tg_event, tg_tag; +END +$$ language plpgsql +-- +FUNCTION: name="test_event_trigger" function="test_event_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +-- should fail, can't call it as a plain function +SELECT test_event_trigger() +-- +FUNCTION: name="test_event_trigger" function="test_event_trigger" schema="" ctx=Call +STMT: SelectStmt +== 004 +-- should fail, event triggers cannot have declared arguments +create function test_event_trigger_arg(name text) +returns event_trigger as $$ BEGIN RETURN 1; END $$ language plpgsql +-- +FUNCTION: name="test_event_trigger_arg" function="test_event_trigger_arg" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 005 +-- should fail, SQL functions cannot be event triggers +create function test_event_trigger_sql() returns event_trigger as $$ +SELECT 1 $$ language sql +-- +FUNCTION: name="test_event_trigger_sql" function="test_event_trigger_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +-- should fail, no elephant_bootstrap entry point +create event trigger regress_event_trigger on elephant_bootstrap + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 007 +-- OK +create event trigger regress_event_trigger on ddl_command_start + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 008 +-- OK +create event trigger regress_event_trigger_end on ddl_command_end + execute function test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 009 +-- should fail, food is not a valid filter variable +create event trigger regress_event_trigger2 on ddl_command_start + when food in ('sandwich') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 010 +-- should fail, sandwich is not a valid command tag +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('sandwich') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 011 +-- should fail, create skunkcabbage is not a valid command tag +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table', 'create skunkcabbage') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 012 +-- should fail, can't have event triggers on event triggers +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('DROP EVENT TRIGGER') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 013 +-- should fail, can't have event triggers on global objects +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE ROLE') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 014 +-- should fail, can't have event triggers on global objects +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE DATABASE') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 015 +-- should fail, can't have event triggers on global objects +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE TABLESPACE') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 016 +-- should fail, can't have same filter variable twice +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table') and tag in ('CREATE FUNCTION') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 017 +-- should fail, can't have arguments +create event trigger regress_event_trigger2 on ddl_command_start + execute procedure test_event_trigger('argument not allowed') +-- +ERROR: syntax error at or near "'argument not allowed'" +CURSORPOS: 143 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 018 +-- OK +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table', 'CREATE FUNCTION') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 019 +-- OK +comment on event trigger regress_event_trigger is 'test comment' +-- +STMT: CommentStmt +== 020 +-- drop as non-superuser should fail +create role regress_evt_user +-- +STMT: CreateRoleStmt +== 021 +set role regress_evt_user +-- +STMT: VariableSetStmt +== 022 +create event trigger regress_event_trigger_noperms on ddl_command_start + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +== 023 +reset role +-- +STMT: VariableSetStmt +== 024 +-- test enabling and disabling +alter event trigger regress_event_trigger disable +-- +STMT: AlterEventTrigStmt +== 025 +-- fires _trigger2 and _trigger_end should fire, but not _trigger +create table event_trigger_fire1 (a int) +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: CreateStmt +== 026 +alter event trigger regress_event_trigger enable +-- +STMT: AlterEventTrigStmt +== 027 +set session_replication_role = replica +-- +STMT: VariableSetStmt +== 028 +-- fires nothing +create table event_trigger_fire2 (a int) +-- +TABLE: name="event_trigger_fire2" schema="" table="event_trigger_fire2" ctx=DDL +STMT: CreateStmt +== 029 +alter event trigger regress_event_trigger enable replica +-- +STMT: AlterEventTrigStmt +== 030 +-- fires only _trigger +create table event_trigger_fire3 (a int) +-- +TABLE: name="event_trigger_fire3" schema="" table="event_trigger_fire3" ctx=DDL +STMT: CreateStmt +== 031 +alter event trigger regress_event_trigger enable always +-- +STMT: AlterEventTrigStmt +== 032 +-- fires only _trigger +create table event_trigger_fire4 (a int) +-- +TABLE: name="event_trigger_fire4" schema="" table="event_trigger_fire4" ctx=DDL +STMT: CreateStmt +== 033 +reset session_replication_role +-- +STMT: VariableSetStmt +== 034 +-- fires all three +create table event_trigger_fire5 (a int) +-- +TABLE: name="event_trigger_fire5" schema="" table="event_trigger_fire5" ctx=DDL +STMT: CreateStmt +== 035 +-- non-top-level command +create function f1() returns int +language plpgsql +as $$ +begin + create table event_trigger_fire6 (a int); + return 0; +end $$ +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +select f1() +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- non-top-level command +create procedure p1() +language plpgsql +as $$ +begin + create table event_trigger_fire7 (a int); +end $$ +-- +FUNCTION: name="p1" function="p1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 038 +call p1() +-- +FUNCTION: name="p1" function="p1" schema="" ctx=Call +STMT: CallStmt +== 039 +-- clean up +alter event trigger regress_event_trigger disable +-- +STMT: AlterEventTrigStmt +== 040 +drop table event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5, event_trigger_fire6, event_trigger_fire7 +-- +TABLE: name="event_trigger_fire2" schema="" table="event_trigger_fire2" ctx=DDL +TABLE: name="event_trigger_fire3" schema="" table="event_trigger_fire3" ctx=DDL +TABLE: name="event_trigger_fire4" schema="" table="event_trigger_fire4" ctx=DDL +TABLE: name="event_trigger_fire5" schema="" table="event_trigger_fire5" ctx=DDL +TABLE: name="event_trigger_fire6" schema="" table="event_trigger_fire6" ctx=DDL +TABLE: name="event_trigger_fire7" schema="" table="event_trigger_fire7" ctx=DDL +STMT: DropStmt +== 041 +drop routine f1(), p1() +-- +STMT: DropStmt +== 042 +-- regress_event_trigger_end should fire on these commands +grant all on table event_trigger_fire1 to public +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: GrantStmt +== 043 +comment on table event_trigger_fire1 is 'here is a comment' +-- +STMT: CommentStmt +== 044 +revoke all on table event_trigger_fire1 from public +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: GrantStmt +== 045 +drop table event_trigger_fire1 +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: DropStmt +== 046 +create foreign data wrapper useless +-- +STMT: CreateFdwStmt +== 047 +create server useless_server foreign data wrapper useless +-- +STMT: CreateForeignServerStmt +== 048 +create user mapping for regress_evt_user server useless_server +-- +STMT: CreateUserMappingStmt +== 049 +alter default privileges for role regress_evt_user + revoke delete on tables from regress_evt_user +-- +STMT: AlterDefaultPrivilegesStmt +== 050 +-- alter owner to non-superuser should fail +alter event trigger regress_event_trigger owner to regress_evt_user +-- +STMT: AlterOwnerStmt +== 051 +-- alter owner to superuser should work +alter role regress_evt_user superuser +-- +STMT: AlterRoleStmt +== 052 +alter event trigger regress_event_trigger owner to regress_evt_user +-- +STMT: AlterOwnerStmt +== 053 +-- should fail, name collision +alter event trigger regress_event_trigger rename to regress_event_trigger2 +-- +STMT: RenameStmt +== 054 +-- OK +alter event trigger regress_event_trigger rename to regress_event_trigger3 +-- +STMT: RenameStmt +== 055 +-- should fail, doesn't exist any more +drop event trigger regress_event_trigger +-- +STMT: DropStmt +== 056 +-- should fail, regress_evt_user owns some objects +drop role regress_evt_user +-- +STMT: DropRoleStmt +== 057 +-- cleanup before next test +-- these are all OK; the second one should emit a NOTICE +drop event trigger if exists regress_event_trigger2 +-- +STMT: DropStmt +== 058 +drop event trigger if exists regress_event_trigger2 +-- +STMT: DropStmt +== 059 +drop event trigger regress_event_trigger3 +-- +STMT: DropStmt +== 060 +drop event trigger regress_event_trigger_end +-- +STMT: DropStmt +== 061 +-- test support for dropped objects +CREATE SCHEMA schema_one authorization regress_evt_user +-- +STMT: CreateSchemaStmt +== 062 +CREATE SCHEMA schema_two authorization regress_evt_user +-- +STMT: CreateSchemaStmt +== 063 +CREATE SCHEMA audit_tbls authorization regress_evt_user +-- +STMT: CreateSchemaStmt +== 064 +CREATE TEMP TABLE a_temp_tbl () +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: CreateStmt +== 065 +SET SESSION AUTHORIZATION regress_evt_user +-- +STMT: VariableSetStmt +== 066 +CREATE TABLE schema_one.table_one(a int) +-- +TABLE: name="schema_one.table_one" schema="schema_one" table="table_one" ctx=DDL +STMT: CreateStmt +== 067 +CREATE TABLE schema_one."table two"(a int) +-- +TABLE: name="schema_one.\"table two\"" schema="schema_one" table="table two" ctx=DDL +STMT: CreateStmt +== 068 +CREATE TABLE schema_one.table_three(a int) +-- +TABLE: name="schema_one.table_three" schema="schema_one" table="table_three" ctx=DDL +STMT: CreateStmt +== 069 +CREATE TABLE audit_tbls.schema_one_table_two(the_value text) +-- +TABLE: name="audit_tbls.schema_one_table_two" schema="audit_tbls" table="schema_one_table_two" ctx=DDL +STMT: CreateStmt +== 070 +CREATE TABLE schema_two.table_two(a int) +-- +TABLE: name="schema_two.table_two" schema="schema_two" table="table_two" ctx=DDL +STMT: CreateStmt +== 071 +CREATE TABLE schema_two.table_three(a int, b text) +-- +TABLE: name="schema_two.table_three" schema="schema_two" table="table_three" ctx=DDL +STMT: CreateStmt +== 072 +CREATE TABLE audit_tbls.schema_two_table_three(the_value text) +-- +TABLE: name="audit_tbls.schema_two_table_three" schema="audit_tbls" table="schema_two_table_three" ctx=DDL +STMT: CreateStmt +== 073 +CREATE OR REPLACE FUNCTION schema_two.add(int, int) RETURNS int LANGUAGE plpgsql + CALLED ON NULL INPUT + AS $$ BEGIN RETURN coalesce($1,0) + coalesce($2,0); END; $$ +-- +FUNCTION: name="schema_two.add" function="add" schema="schema_two" ctx=DDL +STMT: CreateFunctionStmt +== 074 +CREATE AGGREGATE schema_two.newton + (BASETYPE = int, SFUNC = schema_two.add, STYPE = int) +-- +STMT: DefineStmt +== 075 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 076 +CREATE TABLE undroppable_objs ( + object_type text, + object_identity text +) +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DDL +STMT: CreateStmt +== 077 +INSERT INTO undroppable_objs VALUES +('table', 'schema_one.table_three'), +('table', 'audit_tbls.schema_two_table_three') +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +CREATE TABLE dropped_objects ( + object_type text, + schema_name text, + object_name text, + object_identity text, + address_names text[], + address_args text[], + is_temporary bool, + original bool, + normal bool +) +-- +TABLE: name="dropped_objects" schema="" table="dropped_objects" ctx=DDL +STMT: CreateStmt +== 079 +-- This tests errors raised within event triggers; the one in audit_tbls +-- uses 2nd-level recursive invocation via test_evtrig_dropped_objects(). +CREATE OR REPLACE FUNCTION undroppable() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + PERFORM 1 FROM pg_tables WHERE tablename = 'undroppable_objs'; + IF NOT FOUND THEN + RAISE NOTICE 'table undroppable_objs not found, skipping'; + RETURN; + END IF; + FOR obj IN + SELECT * FROM pg_event_trigger_dropped_objects() JOIN + undroppable_objs USING (object_type, object_identity) + LOOP + RAISE EXCEPTION 'object % of type % cannot be dropped', + obj.object_identity, obj.object_type; + END LOOP; +END; +$$ +-- +FUNCTION: name="undroppable" function="undroppable" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 080 +CREATE EVENT TRIGGER undroppable ON sql_drop + EXECUTE PROCEDURE undroppable() +-- +STMT: CreateEventTrigStmt +== 081 +CREATE OR REPLACE FUNCTION test_evtrig_dropped_objects() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + IF obj.object_type = 'table' THEN + EXECUTE format('DROP TABLE IF EXISTS audit_tbls.%I', + format('%s_%s', obj.schema_name, obj.object_name)); + END IF; + + INSERT INTO dropped_objects + (object_type, schema_name, object_name, + object_identity, address_names, address_args, + is_temporary, original, normal) VALUES + (obj.object_type, obj.schema_name, obj.object_name, + obj.object_identity, obj.address_names, obj.address_args, + obj.is_temporary, obj.original, obj.normal); + END LOOP; +END +$$ +-- +FUNCTION: name="test_evtrig_dropped_objects" function="test_evtrig_dropped_objects" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 082 +CREATE EVENT TRIGGER regress_event_trigger_drop_objects ON sql_drop + WHEN TAG IN ('drop table', 'drop function', 'drop view', + 'drop owned', 'drop schema', 'alter table') + EXECUTE PROCEDURE test_evtrig_dropped_objects() +-- +STMT: CreateEventTrigStmt +== 083 +ALTER TABLE schema_one.table_one DROP COLUMN a +-- +TABLE: name="schema_one.table_one" schema="schema_one" table="table_one" ctx=DDL +STMT: AlterTableStmt +== 084 +DROP SCHEMA schema_one, schema_two CASCADE +-- +STMT: DropStmt +== 085 +DELETE FROM undroppable_objs WHERE object_identity = 'audit_tbls.schema_two_table_three' +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DML +STMT: DeleteStmt +== 086 +DROP SCHEMA schema_one, schema_two CASCADE +-- +STMT: DropStmt +== 087 +DELETE FROM undroppable_objs WHERE object_identity = 'schema_one.table_three' +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DML +STMT: DeleteStmt +== 088 +DROP SCHEMA schema_one, schema_two CASCADE +-- +STMT: DropStmt +== 089 +-- exclude TOAST objects because they have unstable names +SELECT * FROM dropped_objects + WHERE schema_name IS NULL OR schema_name <> 'pg_toast' +-- +TABLE: name="dropped_objects" schema="" table="dropped_objects" ctx=Select +FILTER: schema="" table="" column="schema_name" +FILTER: schema="" table="" column="schema_name" +STMT: SelectStmt +== 090 +DROP OWNED BY regress_evt_user +-- +STMT: DropOwnedStmt +== 091 +SELECT * FROM dropped_objects WHERE object_type = 'schema' +-- +TABLE: name="dropped_objects" schema="" table="dropped_objects" ctx=Select +FILTER: schema="" table="" column="object_type" +STMT: SelectStmt +== 092 +DROP ROLE regress_evt_user +-- +STMT: DropRoleStmt +== 093 +DROP EVENT TRIGGER regress_event_trigger_drop_objects +-- +STMT: DropStmt +== 094 +DROP EVENT TRIGGER undroppable +-- +STMT: DropStmt +== 095 +-- Event triggers on relations. +CREATE OR REPLACE FUNCTION event_trigger_report_dropped() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r record; +BEGIN + FOR r IN SELECT * from pg_event_trigger_dropped_objects() + LOOP + IF NOT r.normal AND NOT r.original THEN + CONTINUE; + END IF; + RAISE NOTICE 'NORMAL: orig=% normal=% istemp=% type=% identity=% schema=% name=% addr=% args=%', + r.original, r.normal, r.is_temporary, r.object_type, + r.object_identity, r.schema_name, r.object_name, + r.address_names, r.address_args; + END LOOP; +END; $$ +-- +FUNCTION: name="event_trigger_report_dropped" function="event_trigger_report_dropped" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 096 +CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop + EXECUTE PROCEDURE event_trigger_report_dropped() +-- +STMT: CreateEventTrigStmt +== 097 +CREATE OR REPLACE FUNCTION event_trigger_report_end() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + RAISE NOTICE 'END: command_tag=% type=% identity=%', + r.command_tag, r.object_type, r.object_identity; + END LOOP; +END; $$ +-- +FUNCTION: name="event_trigger_report_end" function="event_trigger_report_end" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 098 +CREATE EVENT TRIGGER regress_event_trigger_report_end ON ddl_command_end + EXECUTE PROCEDURE event_trigger_report_end() +-- +STMT: CreateEventTrigStmt +== 099 +CREATE SCHEMA evttrig + CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL) + CREATE INDEX one_idx ON one (col_b) + CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42) + CREATE TABLE id (col_d int NOT NULL GENERATED ALWAYS AS IDENTITY) +-- +STMT: CreateSchemaStmt +== 100 +-- Partitioned tables with a partitioned index +CREATE TABLE evttrig.parted ( + id int PRIMARY KEY) + PARTITION BY RANGE (id) +-- +TABLE: name="evttrig.parted" schema="evttrig" table="parted" ctx=DDL +STMT: CreateStmt +== 101 +CREATE TABLE evttrig.part_1_10 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (1) TO (10) +-- +TABLE: name="evttrig.part_1_10" schema="evttrig" table="part_1_10" ctx=DDL +STMT: CreateStmt +== 102 +CREATE TABLE evttrig.part_10_20 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (10) TO (20) PARTITION BY RANGE (id) +-- +TABLE: name="evttrig.part_10_20" schema="evttrig" table="part_10_20" ctx=DDL +STMT: CreateStmt +== 103 +CREATE TABLE evttrig.part_10_15 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (10) TO (15) +-- +TABLE: name="evttrig.part_10_15" schema="evttrig" table="part_10_15" ctx=DDL +STMT: CreateStmt +== 104 +CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (15) TO (20) +-- +TABLE: name="evttrig.part_15_20" schema="evttrig" table="part_15_20" ctx=DDL +STMT: CreateStmt +== 105 +ALTER TABLE evttrig.two DROP COLUMN col_c +-- +TABLE: name="evttrig.two" schema="evttrig" table="two" ctx=DDL +STMT: AlterTableStmt +== 106 +ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT +-- +TABLE: name="evttrig.one" schema="evttrig" table="one" ctx=DDL +STMT: AlterTableStmt +== 107 +ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey +-- +TABLE: name="evttrig.one" schema="evttrig" table="one" ctx=DDL +STMT: AlterTableStmt +== 108 +ALTER TABLE evttrig.one DROP COLUMN col_c +-- +TABLE: name="evttrig.one" schema="evttrig" table="one" ctx=DDL +STMT: AlterTableStmt +== 109 +ALTER TABLE evttrig.id ALTER COLUMN col_d SET DATA TYPE bigint +-- +TABLE: name="evttrig.id" schema="evttrig" table="id" ctx=DDL +STMT: AlterTableStmt +== 110 +ALTER TABLE evttrig.id ALTER COLUMN col_d DROP IDENTITY, + ALTER COLUMN col_d SET DATA TYPE int +-- +TABLE: name="evttrig.id" schema="evttrig" table="id" ctx=DDL +STMT: AlterTableStmt +== 111 +DROP INDEX evttrig.one_idx +-- +STMT: DropStmt +== 112 +DROP SCHEMA evttrig CASCADE +-- +STMT: DropStmt +== 113 +DROP TABLE a_temp_tbl +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: DropStmt +== 114 +-- check unfiltered results, too +CREATE OR REPLACE FUNCTION event_trigger_report_dropped() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r record; +BEGIN + FOR r IN SELECT * from pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE 'DROP: orig=% normal=% istemp=% type=% identity=% schema=% name=% addr=% args=%', + r.original, r.normal, r.is_temporary, r.object_type, + r.object_identity, r.schema_name, r.object_name, + r.address_names, r.address_args; + END LOOP; +END; $$ +-- +FUNCTION: name="event_trigger_report_dropped" function="event_trigger_report_dropped" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 115 +CREATE FUNCTION event_trigger_dummy_trigger() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + RETURN new; +END; $$ +-- +FUNCTION: name="event_trigger_dummy_trigger" function="event_trigger_dummy_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 116 +CREATE TABLE evtrg_nontemp_table (f1 int primary key, f2 int default 42) +-- +TABLE: name="evtrg_nontemp_table" schema="" table="evtrg_nontemp_table" ctx=DDL +STMT: CreateStmt +== 117 +CREATE TRIGGER evtrg_nontemp_trig + BEFORE INSERT ON evtrg_nontemp_table + EXECUTE FUNCTION event_trigger_dummy_trigger() +-- +TABLE: name="evtrg_nontemp_table" schema="" table="evtrg_nontemp_table" ctx=DDL +STMT: CreateTrigStmt +== 118 +CREATE POLICY evtrg_nontemp_pol ON evtrg_nontemp_table USING (f2 > 0) +-- +STMT: CreatePolicyStmt +== 119 +DROP TABLE evtrg_nontemp_table +-- +TABLE: name="evtrg_nontemp_table" schema="" table="evtrg_nontemp_table" ctx=DDL +STMT: DropStmt +== 120 +CREATE TEMP TABLE a_temp_tbl (f1 int primary key, f2 int default 42) +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: CreateStmt +== 121 +CREATE TRIGGER a_temp_trig + BEFORE INSERT ON a_temp_tbl + EXECUTE FUNCTION event_trigger_dummy_trigger() +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: CreateTrigStmt +== 122 +CREATE POLICY a_temp_pol ON a_temp_tbl USING (f2 > 0) +-- +STMT: CreatePolicyStmt +== 123 +DROP TABLE a_temp_tbl +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: DropStmt +== 124 +DROP FUNCTION event_trigger_dummy_trigger() +-- +FUNCTION: name="event_trigger_dummy_trigger" function="event_trigger_dummy_trigger" schema="" ctx=DDL +STMT: DropStmt +== 125 +-- CREATE OPERATOR CLASS without FAMILY clause should report +-- both CREATE OPERATOR FAMILY and CREATE OPERATOR CLASS +CREATE OPERATOR CLASS evttrigopclass FOR TYPE int USING btree AS STORAGE int +-- +STMT: CreateOpClassStmt +== 126 +DROP EVENT TRIGGER regress_event_trigger_report_dropped +-- +STMT: DropStmt +== 127 +DROP EVENT TRIGGER regress_event_trigger_report_end +-- +STMT: DropStmt +== 128 +-- only allowed from within an event trigger function, should fail +select pg_event_trigger_table_rewrite_oid() +-- +FUNCTION: name="pg_event_trigger_table_rewrite_oid" function="pg_event_trigger_table_rewrite_oid" schema="" ctx=Call +STMT: SelectStmt +== 129 +-- test Table Rewrite Event Trigger +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE EXCEPTION 'rewrites not allowed'; +END; +$$ +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 130 +create event trigger no_rewrite_allowed on table_rewrite + execute procedure test_evtrig_no_rewrite() +-- +STMT: CreateEventTrigStmt +== 131 +create table rewriteme (id serial primary key, foo float, bar timestamptz) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: CreateStmt +== 132 +insert into rewriteme + select x * 1.001 from generate_series(1, 500) as t(x) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 133 +alter table rewriteme alter column foo type numeric +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +== 134 +alter table rewriteme add column baz int default 0 +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +== 135 +-- test with more than one reason to rewrite a single table +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'Table ''%'' is being rewritten (reason = %)', + pg_event_trigger_table_rewrite_oid()::regclass, + pg_event_trigger_table_rewrite_reason(); +END; +$$ +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 136 +alter table rewriteme + add column onemore int default 0, + add column another int default -1, + alter column foo type numeric(10,4) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +== 137 +-- matview rewrite when changing access method +CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT 1 AS a +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 138 +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2 +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: AlterTableStmt +== 139 +DROP MATERIALIZED VIEW heapmv +-- +STMT: DropStmt +== 140 +-- shouldn't trigger a table_rewrite event +alter table rewriteme alter column foo type numeric(12,4) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +== 141 +begin +-- +STMT: TransactionStmt +== 142 +set timezone to 'UTC' +-- +STMT: VariableSetStmt +== 143 +alter table rewriteme alter column bar type timestamp +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +== 144 +set timezone to '0' +-- +STMT: VariableSetStmt +== 145 +alter table rewriteme alter column bar type timestamptz +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +== 146 +set timezone to 'Europe/London' +-- +STMT: VariableSetStmt +== 147 +alter table rewriteme alter column bar type timestamp +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +== 148 +-- does rewrite +rollback +-- +STMT: TransactionStmt +== 149 +-- typed tables are rewritten when their type changes. Don't emit table +-- name, because firing order is not stable. +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'Table is being rewritten (reason = %)', + pg_event_trigger_table_rewrite_reason(); +END; +$$ +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 150 +create type rewritetype as (a int) +-- +STMT: CompositeTypeStmt +== 151 +create table rewritemetoo1 of rewritetype +-- +TABLE: name="rewritemetoo1" schema="" table="rewritemetoo1" ctx=DDL +STMT: CreateStmt +== 152 +create table rewritemetoo2 of rewritetype +-- +TABLE: name="rewritemetoo2" schema="" table="rewritemetoo2" ctx=DDL +STMT: CreateStmt +== 153 +alter type rewritetype alter attribute a type text cascade +-- +TABLE: name="rewritetype" schema="" table="rewritetype" ctx=DDL +STMT: AlterTableStmt +== 154 +-- but this doesn't work +create table rewritemetoo3 (a rewritetype) +-- +TABLE: name="rewritemetoo3" schema="" table="rewritemetoo3" ctx=DDL +STMT: CreateStmt +== 155 +alter type rewritetype alter attribute a type varchar cascade +-- +TABLE: name="rewritetype" schema="" table="rewritetype" ctx=DDL +STMT: AlterTableStmt +== 156 +drop table rewriteme +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: DropStmt +== 157 +drop event trigger no_rewrite_allowed +-- +STMT: DropStmt +== 158 +drop function test_evtrig_no_rewrite() +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: DropStmt +== 159 +-- Tests for REINDEX +CREATE OR REPLACE FUNCTION reindex_start_command() +RETURNS event_trigger AS $$ +BEGIN + RAISE NOTICE 'REINDEX START: % %', tg_event, tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="reindex_start_command" function="reindex_start_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 160 +CREATE EVENT TRIGGER regress_reindex_start ON ddl_command_start + WHEN TAG IN ('REINDEX') + EXECUTE PROCEDURE reindex_start_command() +-- +STMT: CreateEventTrigStmt +== 161 +CREATE FUNCTION reindex_end_command() +RETURNS event_trigger AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + RAISE NOTICE 'REINDEX END: command_tag=% type=% identity=%', + obj.command_tag, obj.object_type, obj.object_identity; + END LOOP; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="reindex_end_command" function="reindex_end_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 162 +CREATE EVENT TRIGGER regress_reindex_end ON ddl_command_end + WHEN TAG IN ('REINDEX') + EXECUTE PROCEDURE reindex_end_command() +-- +STMT: CreateEventTrigStmt +== 163 +-- Extra event to force the use of a snapshot. +CREATE FUNCTION reindex_end_command_snap() RETURNS EVENT_TRIGGER + AS $$ BEGIN PERFORM 1; END $$ LANGUAGE plpgsql +-- +FUNCTION: name="reindex_end_command_snap" function="reindex_end_command_snap" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 164 +CREATE EVENT TRIGGER regress_reindex_end_snap ON ddl_command_end + EXECUTE FUNCTION reindex_end_command_snap() +-- +STMT: CreateEventTrigStmt +== 165 +-- With simple relation +CREATE TABLE concur_reindex_tab (c1 int) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: CreateStmt +== 166 +CREATE INDEX concur_reindex_ind ON concur_reindex_tab (c1) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +== 167 +-- Both start and end triggers enabled. +REINDEX INDEX concur_reindex_ind +-- +STMT: ReindexStmt +== 168 +REINDEX TABLE concur_reindex_tab +-- +STMT: ReindexStmt +== 169 +REINDEX INDEX CONCURRENTLY concur_reindex_ind +-- +STMT: ReindexStmt +== 170 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +== 171 +-- with start trigger disabled. +ALTER EVENT TRIGGER regress_reindex_start DISABLE +-- +STMT: AlterEventTrigStmt +== 172 +REINDEX INDEX concur_reindex_ind +-- +STMT: ReindexStmt +== 173 +REINDEX INDEX CONCURRENTLY concur_reindex_ind +-- +STMT: ReindexStmt +== 174 +-- without an index +DROP INDEX concur_reindex_ind +-- +STMT: DropStmt +== 175 +REINDEX TABLE concur_reindex_tab +-- +STMT: ReindexStmt +== 176 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +== 177 +-- With a Schema +CREATE SCHEMA concur_reindex_schema +-- +STMT: CreateSchemaStmt +== 178 +-- No indexes +REINDEX SCHEMA concur_reindex_schema +-- +STMT: ReindexStmt +== 179 +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema +-- +STMT: ReindexStmt +== 180 +CREATE TABLE concur_reindex_schema.tab (a int) +-- +TABLE: name="concur_reindex_schema.tab" schema="concur_reindex_schema" table="tab" ctx=DDL +STMT: CreateStmt +== 181 +CREATE INDEX ind ON concur_reindex_schema.tab (a) +-- +TABLE: name="concur_reindex_schema.tab" schema="concur_reindex_schema" table="tab" ctx=DDL +STMT: IndexStmt +== 182 +-- One index reported +REINDEX SCHEMA concur_reindex_schema +-- +STMT: ReindexStmt +== 183 +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema +-- +STMT: ReindexStmt +== 184 +-- One table on schema but no indexes +DROP INDEX concur_reindex_schema.ind +-- +STMT: DropStmt +== 185 +REINDEX SCHEMA concur_reindex_schema +-- +STMT: ReindexStmt +== 186 +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema +-- +STMT: ReindexStmt +== 187 +DROP SCHEMA concur_reindex_schema CASCADE +-- +STMT: DropStmt +== 188 +-- With a partitioned table, and nothing else. +CREATE TABLE concur_reindex_part (id int) PARTITION BY RANGE (id) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: CreateStmt +== 189 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +== 190 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +== 191 +-- Partition that would be reindexed, still nothing. +CREATE TABLE concur_reindex_child PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10) +-- +TABLE: name="concur_reindex_child" schema="" table="concur_reindex_child" ctx=DDL +STMT: CreateStmt +== 192 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +== 193 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +== 194 +-- Now add some indexes. +CREATE INDEX concur_reindex_partidx ON concur_reindex_part (id) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: IndexStmt +== 195 +REINDEX INDEX concur_reindex_partidx +-- +STMT: ReindexStmt +== 196 +REINDEX INDEX CONCURRENTLY concur_reindex_partidx +-- +STMT: ReindexStmt +== 197 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +== 198 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +== 199 +DROP TABLE concur_reindex_part +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: DropStmt +== 200 +-- Clean up +DROP EVENT TRIGGER regress_reindex_start +-- +STMT: DropStmt +== 201 +DROP EVENT TRIGGER regress_reindex_end +-- +STMT: DropStmt +== 202 +DROP EVENT TRIGGER regress_reindex_end_snap +-- +STMT: DropStmt +== 203 +DROP FUNCTION reindex_end_command() +-- +FUNCTION: name="reindex_end_command" function="reindex_end_command" schema="" ctx=DDL +STMT: DropStmt +== 204 +DROP FUNCTION reindex_end_command_snap() +-- +FUNCTION: name="reindex_end_command_snap" function="reindex_end_command_snap" schema="" ctx=DDL +STMT: DropStmt +== 205 +DROP FUNCTION reindex_start_command() +-- +FUNCTION: name="reindex_start_command" function="reindex_start_command" schema="" ctx=DDL +STMT: DropStmt +== 206 +DROP TABLE concur_reindex_tab +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: DropStmt +== 207 +-- test Row Security Event Trigger +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 208 +CREATE TABLE event_trigger_test (a integer, b text) +-- +TABLE: name="event_trigger_test" schema="" table="event_trigger_test" ctx=DDL +STMT: CreateStmt +== 209 +CREATE OR REPLACE FUNCTION start_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - ddl_command_start', tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="start_command" function="start_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 210 +CREATE OR REPLACE FUNCTION end_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - ddl_command_end', tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="end_command" function="end_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 211 +CREATE OR REPLACE FUNCTION drop_sql_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - sql_drop', tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="drop_sql_command" function="drop_sql_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 212 +CREATE EVENT TRIGGER start_rls_command ON ddl_command_start + WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE start_command() +-- +STMT: CreateEventTrigStmt +== 213 +CREATE EVENT TRIGGER end_rls_command ON ddl_command_end + WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE end_command() +-- +STMT: CreateEventTrigStmt +== 214 +CREATE EVENT TRIGGER sql_drop_command ON sql_drop + WHEN TAG IN ('DROP POLICY') EXECUTE PROCEDURE drop_sql_command() +-- +STMT: CreateEventTrigStmt +== 215 +CREATE POLICY p1 ON event_trigger_test USING (FALSE) +-- +STMT: CreatePolicyStmt +== 216 +ALTER POLICY p1 ON event_trigger_test USING (TRUE) +-- +STMT: AlterPolicyStmt +== 217 +ALTER POLICY p1 ON event_trigger_test RENAME TO p2 +-- +STMT: RenameStmt +== 218 +DROP POLICY p2 ON event_trigger_test +-- +STMT: DropStmt +== 219 +-- Check the object addresses of all the event triggers. +SELECT + e.evtname, + pg_describe_object('pg_event_trigger'::regclass, e.oid, 0) as descr, + b.type, b.object_names, b.object_args, + pg_identify_object(a.classid, a.objid, a.objsubid) as ident + FROM pg_event_trigger as e, + LATERAL pg_identify_object_as_address('pg_event_trigger'::regclass, e.oid, 0) as b, + LATERAL pg_get_object_address(b.type, b.object_names, b.object_args) as a + ORDER BY e.evtname +-- +TABLE: name="pg_event_trigger" schema="" table="pg_event_trigger" ctx=Select +ALIAS: "e"="pg_event_trigger" +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object_as_address" function="pg_identify_object_as_address" schema="" ctx=Call +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 220 +DROP EVENT TRIGGER start_rls_command +-- +STMT: DropStmt +== 221 +DROP EVENT TRIGGER end_rls_command +-- +STMT: DropStmt +== 222 +DROP EVENT TRIGGER sql_drop_command +-- +STMT: DropStmt +== 223 +-- Check the GUC for disabling event triggers +CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE '% dropped %', tg_tag, obj.object_type; + END LOOP; +END; +$$ +-- +FUNCTION: name="test_event_trigger_guc" function="test_event_trigger_guc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 224 +CREATE EVENT TRIGGER test_event_trigger_guc + ON sql_drop + WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc() +-- +STMT: CreateEventTrigStmt +== 225 +SET event_triggers = 'on' +-- +STMT: VariableSetStmt +== 226 +CREATE POLICY pguc ON event_trigger_test USING (FALSE) +-- +STMT: CreatePolicyStmt +== 227 +DROP POLICY pguc ON event_trigger_test +-- +STMT: DropStmt +== 228 +CREATE POLICY pguc ON event_trigger_test USING (FALSE) +-- +STMT: CreatePolicyStmt +== 229 +SET event_triggers = 'off' +-- +STMT: VariableSetStmt +== 230 +DROP POLICY pguc ON event_trigger_test +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json b/parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json new file mode 100644 index 0000000..4739b17 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json @@ -0,0 +1,15 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011" + ] +} diff --git a/parser/testdata/summary/postgres_regress/event_trigger_login.test b/parser/testdata/summary/postgres_regress/event_trigger_login.test new file mode 100644 index 0000000..dafce96 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/event_trigger_login.test @@ -0,0 +1,64 @@ +== 001 +-- Login event triggers +CREATE TABLE user_logins(id serial, who text) +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=DDL +STMT: CreateStmt +== 002 +GRANT SELECT ON user_logins TO public +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=DDL +STMT: GrantStmt +== 003 +CREATE FUNCTION on_login_proc() RETURNS event_trigger AS $$ +BEGIN + INSERT INTO user_logins (who) VALUES (SESSION_USER); + RAISE NOTICE 'You are welcome!'; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="on_login_proc" function="on_login_proc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 004 +CREATE EVENT TRIGGER on_login_trigger ON login EXECUTE PROCEDURE on_login_proc() +-- +STMT: CreateEventTrigStmt +== 005 +ALTER EVENT TRIGGER on_login_trigger ENABLE ALWAYS +-- +STMT: AlterEventTrigStmt +== 006 +SELECT COUNT(*) FROM user_logins +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT COUNT(*) FROM user_logins +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- Check dathasloginevt in system catalog +SELECT dathasloginevt FROM pg_database WHERE datname= :'DBNAME' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 97 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- Cleanup +DROP TABLE user_logins +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=DDL +STMT: DropStmt +== 010 +DROP EVENT TRIGGER on_login_trigger +-- +STMT: DropStmt +== 011 +DROP FUNCTION on_login_proc() +-- +FUNCTION: name="on_login_proc" function="on_login_proc" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/explain.metadata.json b/parser/testdata/summary/postgres_regress/explain.metadata.json new file mode 100644 index 0000000..fbb3e40 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/explain.metadata.json @@ -0,0 +1,55 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051" + ] +} diff --git a/parser/testdata/summary/postgres_regress/explain.test b/parser/testdata/summary/postgres_regress/explain.test new file mode 100644 index 0000000..67e4d53 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/explain.test @@ -0,0 +1,348 @@ +== 001 +|-- +-- EXPLAIN +|-- +-- There are many test cases elsewhere that use EXPLAIN as a vehicle for +-- checking something else (usually planner behavior). This file is +-- concerned with testing EXPLAIN in its own right. +|-- + +-- To produce stable regression test output, it's usually necessary to +-- ignore details such as exact costs or row counts. These filter +-- functions replace changeable output details with fixed strings. + +create function explain_filter(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in execute $1 + loop + -- Replace any numeric word with just 'N' + ln := regexp_replace(ln, '-?\m\d+\M', 'N', 'g'); + -- In sort output, the above won't match units-suffixed numbers + ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g'); + -- Ignore text-mode buffers output because it varies depending + -- on the system state + CONTINUE WHEN (ln ~ ' +Buffers: .*'); + -- Ignore text-mode "Planning:" line because whether it's output + -- varies depending on the system state + CONTINUE WHEN (ln = 'Planning:'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +-- To produce valid JSON output, replace numbers with "0" or "0.0" not "N" +create function explain_filter_to_json(text) returns jsonb +language plpgsql as +$$ +declare + data text := ''; + ln text; +begin + for ln in execute $1 + loop + -- Replace any numeric word with just '0' + ln := regexp_replace(ln, '\m\d+\M', '0', 'g'); + data := data || ln; + end loop; + return data::jsonb; +end; +$$ +-- +FUNCTION: name="explain_filter_to_json" function="explain_filter_to_json" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 003 +-- Disable JIT, or we'll get different output on machines where that's been +-- forced on +set jit = off +-- +STMT: VariableSetStmt +== 004 +-- Similarly, disable track_io_timing, to avoid output differences when +-- enabled. +set track_io_timing = off +-- +STMT: VariableSetStmt +== 005 +-- Simple cases + +select explain_filter('explain select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 006 +select explain_filter('explain (analyze) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 007 +select explain_filter('explain (analyze, verbose) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 008 +select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 009 +select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 010 +select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 011 +select explain_filter('explain (buffers, format text) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 012 +select explain_filter('explain (buffers, format json) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- Check output including I/O timings. These fields are conditional +-- but always set in JSON format, so check them only in this case. +set track_io_timing = on +-- +STMT: VariableSetStmt +== 014 +select explain_filter('explain (analyze, buffers, format json) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 015 +set track_io_timing = off +-- +STMT: VariableSetStmt +== 016 +-- SETTINGS option +-- We have to ignore other settings that might be imposed by the environment, +-- so printing the whole Settings field unfortunately won't do. + +begin +-- +STMT: TransactionStmt +== 017 +set local plan_cache_mode = force_generic_plan +-- +STMT: VariableSetStmt +== 018 +select true as "OK" + from explain_filter('explain (settings) select * from int8_tbl i8') ln + where ln ~ '^ *Settings: .*plan_cache_mode = ''force_generic_plan''' +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +FILTER: schema="" table="" column="ln" +STMT: SelectStmt +== 019 +select explain_filter_to_json('explain (settings, format json) select * from int8_tbl i8') #> '{0,Settings,plan_cache_mode}' +-- +FUNCTION: name="explain_filter_to_json" function="explain_filter_to_json" schema="" ctx=Call +STMT: SelectStmt +== 020 +rollback +-- +STMT: TransactionStmt +== 021 +-- GENERIC_PLAN option + +select explain_filter('explain (generic_plan) select unique1 from tenk1 where thousand = $1') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- should fail +select explain_filter('explain (analyze, generic_plan) select unique1 from tenk1 where thousand = $1') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 023 +-- MEMORY option +select explain_filter('explain (memory) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 024 +select explain_filter('explain (memory, analyze) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 025 +select explain_filter('explain (memory, summary, format yaml) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 026 +select explain_filter('explain (memory, analyze, format json) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 027 +prepare int8_query as select * from int8_tbl i8 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +STMT: PrepareStmt +STMT: SelectStmt +== 028 +select explain_filter('explain (memory) execute int8_query') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 029 +-- Test EXPLAIN (GENERIC_PLAN) with partition pruning +-- partitions should be pruned at plan time, based on constants, +-- but there should be no pruning based on parameter placeholders +create table gen_part ( + key1 integer not null, + key2 integer not null +) partition by list (key1) +-- +TABLE: name="gen_part" schema="" table="gen_part" ctx=DDL +STMT: CreateStmt +== 030 +create table gen_part_1 + partition of gen_part for values in (1) + partition by range (key2) +-- +TABLE: name="gen_part_1" schema="" table="gen_part_1" ctx=DDL +STMT: CreateStmt +== 031 +create table gen_part_1_1 + partition of gen_part_1 for values from (1) to (2) +-- +TABLE: name="gen_part_1_1" schema="" table="gen_part_1_1" ctx=DDL +STMT: CreateStmt +== 032 +create table gen_part_1_2 + partition of gen_part_1 for values from (2) to (3) +-- +TABLE: name="gen_part_1_2" schema="" table="gen_part_1_2" ctx=DDL +STMT: CreateStmt +== 033 +create table gen_part_2 + partition of gen_part for values in (2) +-- +TABLE: name="gen_part_2" schema="" table="gen_part_2" ctx=DDL +STMT: CreateStmt +== 034 +-- should scan gen_part_1_1 and gen_part_1_2, but not gen_part_2 +select explain_filter('explain (generic_plan) select key1, key2 from gen_part where key1 = 1 and key2 = $1') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 035 +drop table gen_part +-- +TABLE: name="gen_part" schema="" table="gen_part" ctx=DDL +STMT: DropStmt +== 036 +|-- +-- Test production of per-worker data +|-- +-- Unfortunately, because we don't know how many worker processes we'll +-- actually get (maybe none at all), we can't examine the "Workers" output +-- in any detail. We can check that it parses correctly as JSON, and then +-- remove it from the displayed results. + +begin +-- +STMT: TransactionStmt +== 037 +-- encourage use of parallel plans +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +== 038 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +== 039 +set min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +== 040 +set max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +== 041 +select jsonb_pretty( + explain_filter_to_json('explain (analyze, verbose, buffers, format json) + select * from tenk1 order by tenthous') + -- remove "Workers" node of the Seq Scan plan node + #- '{0,Plan,Plans,0,Plans,0,Workers}' + -- remove "Workers" node of the Sort plan node + #- '{0,Plan,Plans,0,Workers}' + -- Also remove its sort-type fields, as those aren't 100% stable + #- '{0,Plan,Plans,0,Sort Method}' + #- '{0,Plan,Plans,0,Sort Space Type}' +) +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +FUNCTION: name="explain_filter_to_json" function="explain_filter_to_json" schema="" ctx=Call +STMT: SelectStmt +== 042 +rollback +-- +STMT: TransactionStmt +== 043 +-- Test display of temporary objects +create temp table t1(f1 float8) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 044 +create function pg_temp.mysin(float8) returns float8 language plpgsql +as 'begin return sin($1); end' +-- +FUNCTION: name="pg_temp.mysin" function="mysin" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +== 045 +select explain_filter('explain (verbose) select * from t1 where pg_temp.mysin(f1) < 0.5') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 046 +-- Test compute_query_id +set compute_query_id = on +-- +STMT: VariableSetStmt +== 047 +select explain_filter('explain (verbose) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 048 +-- Test SERIALIZE option +select explain_filter('explain (analyze,serialize) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 049 +select explain_filter('explain (analyze,serialize text,buffers,timing off) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 050 +select explain_filter('explain (analyze,serialize binary,buffers,timing) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +== 051 +-- this tests an edge case where we have no data to return +select explain_filter('explain (analyze,serialize) create temp table explain_temp as select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/expressions.metadata.json b/parser/testdata/summary/postgres_regress/expressions.metadata.json new file mode 100644 index 0000000..fb72ee9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/expressions.metadata.json @@ -0,0 +1,75 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071" + ] +} diff --git a/parser/testdata/summary/postgres_regress/expressions.test b/parser/testdata/summary/postgres_regress/expressions.test new file mode 100644 index 0000000..fb4afa8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/expressions.test @@ -0,0 +1,452 @@ +== 001 +|-- +-- expression evaluation tests that don't fit into a more specific file +|-- + +|-- +-- Tests for SQLValueFunction +|-- + + +-- current_date (always matches because of transactional behaviour) +SELECT date(now())::text = current_date::text +-- +FUNCTION: name="date" function="date" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 002 +-- current_time / localtime +SELECT now()::timetz::text = current_time::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 003 +SELECT now()::timetz(4)::text = current_time(4)::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT now()::time::text = localtime::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT now()::time(3)::text = localtime(3)::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 006 +-- current_time[stamp]/ localtime[stamp] (always matches because of transactional behaviour) +SELECT current_timestamp = NOW() +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- precision +SELECT length(current_timestamp::text) >= length(current_timestamp(0)::text) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- localtimestamp +SELECT now()::timestamp::text = localtimestamp::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- precision overflow +SELECT current_time = current_time(7) +-- +STMT: SelectStmt +== 010 +SELECT current_timestamp = current_timestamp(7) +-- +STMT: SelectStmt +== 011 +SELECT localtime = localtime(7) +-- +STMT: SelectStmt +== 012 +SELECT localtimestamp = localtimestamp(7) +-- +STMT: SelectStmt +== 013 +-- current_role/user/user is tested in rolenames.sql + +-- current database / catalog +SELECT current_catalog = current_database() +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- current_schema +SELECT current_schema +-- +STMT: SelectStmt +== 015 +SET search_path = 'notme' +-- +STMT: VariableSetStmt +== 016 +SELECT current_schema +-- +STMT: SelectStmt +== 017 +SET search_path = 'pg_catalog' +-- +STMT: VariableSetStmt +== 018 +SELECT current_schema +-- +STMT: SelectStmt +== 019 +RESET search_path +-- +STMT: VariableSetStmt +== 020 +|-- +-- Test parsing of a no-op cast to a type with unspecified typmod +|-- +begin +-- +STMT: TransactionStmt +== 021 +create table numeric_tbl (f1 numeric(18,3), f2 numeric) +-- +TABLE: name="numeric_tbl" schema="" table="numeric_tbl" ctx=DDL +STMT: CreateStmt +== 022 +create view numeric_view as + select + f1, f1::numeric(16,4) as f1164, f1::numeric as f1n, + f2, f2::numeric(16,4) as f2164, f2::numeric as f2n + from numeric_tbl +-- +TABLE: name="numeric_view" schema="" table="numeric_view" ctx=DDL +TABLE: name="numeric_tbl" schema="" table="numeric_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 023 +explain (verbose, costs off) select * from numeric_view +-- +TABLE: name="numeric_view" schema="" table="numeric_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 024 +-- bpchar, lacking planner support for its length coercion function, +-- could behave differently + +create table bpchar_tbl (f1 character(16) unique, f2 bpchar) +-- +TABLE: name="bpchar_tbl" schema="" table="bpchar_tbl" ctx=DDL +STMT: CreateStmt +== 025 +create view bpchar_view as + select + f1, f1::character(14) as f114, f1::bpchar as f1n, + f2, f2::character(14) as f214, f2::bpchar as f2n + from bpchar_tbl +-- +TABLE: name="bpchar_view" schema="" table="bpchar_view" ctx=DDL +TABLE: name="bpchar_tbl" schema="" table="bpchar_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 026 +explain (verbose, costs off) select * from bpchar_view + where f1::bpchar = 'foo' +-- +TABLE: name="bpchar_view" schema="" table="bpchar_view" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 027 +rollback +-- +STMT: TransactionStmt +== 028 +|-- +-- Ordinarily, IN/NOT IN can be converted to a ScalarArrayOpExpr +-- with a suitably-chosen array type. +|-- +explain (verbose, costs off) +select random() IN (1, 4, 8.0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 029 +explain (verbose, costs off) +select random()::int IN (1, 4, 8.0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 030 +-- However, if there's not a common supertype for the IN elements, +-- we should instead try to produce "x = v1 OR x = v2 OR ...". +-- In most cases that'll fail for lack of all the requisite = operators, +-- but it can succeed sometimes. So this should complain about lack of +-- an = operator, not about cast failure. +select '(0,0)'::point in ('(0,0,0,0)'::box, point(0,0)) +-- +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 031 +|-- +-- Tests for ScalarArrayOpExpr with a hashfn +|-- + +-- create a stable function so that the tests below are not +-- evaluated using the planner's constant folding. +begin +-- +STMT: TransactionStmt +== 032 +create function return_int_input(int) returns int as $$ +begin + return $1; +end; +$$ language plpgsql stable +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 033 +create function return_text_input(text) returns text as $$ +begin + return $1; +end; +$$ language plpgsql stable +-- +FUNCTION: name="return_text_input" function="return_text_input" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 034 +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 035 +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 036 +select return_int_input(1) in (null, null, null, null, null, null, null, null, null, null, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 037 +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 038 +select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 039 +select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 040 +select return_text_input('a') in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j') +-- +FUNCTION: name="return_text_input" function="return_text_input" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- NOT IN +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 042 +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 0) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 043 +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 2, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 044 +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 045 +select return_int_input(1) not in (null, null, null, null, null, null, null, null, null, null, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 046 +select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 047 +select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +== 048 +select return_text_input('a') not in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j') +-- +FUNCTION: name="return_text_input" function="return_text_input" schema="" ctx=Call +STMT: SelectStmt +== 049 +rollback +-- +STMT: TransactionStmt +== 050 +-- Test with non-strict equality function. +-- We need to create our own type for this. + +begin +-- +STMT: TransactionStmt +== 051 +create type myint +-- +STMT: DefineStmt +== 052 +create function myintin(cstring) returns myint strict immutable language + internal as 'int4in' +-- +FUNCTION: name="myintin" function="myintin" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 053 +create function myintout(myint) returns cstring strict immutable language + internal as 'int4out' +-- +FUNCTION: name="myintout" function="myintout" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 054 +create function myinthash(myint) returns integer strict immutable language + internal as 'hashint4' +-- +FUNCTION: name="myinthash" function="myinthash" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 055 +create type myint (input = myintin, output = myintout, like = int4) +-- +STMT: DefineStmt +== 056 +create cast (int4 as myint) without function +-- +STMT: CreateCastStmt +== 057 +create cast (myint as int4) without function +-- +STMT: CreateCastStmt +== 058 +create function myinteq(myint, myint) returns bool as $$ +begin + if $1 is null and $2 is null then + return true; + else + return $1::int = $2::int; + end if; +end; +$$ language plpgsql immutable +-- +FUNCTION: name="myinteq" function="myinteq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 059 +create function myintne(myint, myint) returns bool as $$ +begin + return not myinteq($1, $2); +end; +$$ language plpgsql immutable +-- +FUNCTION: name="myintne" function="myintne" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 060 +create operator = ( + leftarg = myint, + rightarg = myint, + commutator = =, + negator = <>, + procedure = myinteq, + restrict = eqsel, + join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +== 061 +create operator <> ( + leftarg = myint, + rightarg = myint, + commutator = <>, + negator = =, + procedure = myintne, + restrict = eqsel, + join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +== 062 +create operator class myint_ops +default for type myint using hash as + operator 1 = (myint, myint), + function 1 myinthash(myint) +-- +STMT: CreateOpClassStmt +== 063 +create table inttest (a myint) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=DDL +STMT: CreateStmt +== 064 +insert into inttest values(1::myint),(null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +-- try an array with enough elements to cause hashing +select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 066 +select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 067 +select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 068 +-- ensure the result matched with the non-hashed version. We simply remove +-- some array elements so that we don't reach the hashing threshold. +select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 069 +select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 070 +select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 071 +rollback +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/fast_default.metadata.json b/parser/testdata/summary/postgres_regress/fast_default.metadata.json new file mode 100644 index 0000000..354a8d0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/fast_default.metadata.json @@ -0,0 +1,273 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269" + ] +} diff --git a/parser/testdata/summary/postgres_regress/fast_default.test b/parser/testdata/summary/postgres_regress/fast_default.test new file mode 100644 index 0000000..3489d36 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/fast_default.test @@ -0,0 +1,1617 @@ +== 001 +|-- +-- ALTER TABLE ADD COLUMN DEFAULT test +|-- + +SET search_path = fast_default +-- +STMT: VariableSetStmt +== 002 +CREATE SCHEMA fast_default +-- +STMT: CreateSchemaStmt +== 003 +CREATE TABLE m(id OID) +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: CreateStmt +== 004 +INSERT INTO m VALUES (NULL::OID) +-- +TABLE: name="m" schema="" table="m" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +CREATE FUNCTION set(tabname name) RETURNS VOID +AS $$ +BEGIN + UPDATE m + SET id = (SELECT c.relfilenode + FROM pg_class AS c, pg_namespace AS s + WHERE c.relname = tabname + AND c.relnamespace = s.oid + AND s.nspname = 'fast_default'); +END; +$$ LANGUAGE 'plpgsql' +-- +FUNCTION: name="set" function="set" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +CREATE FUNCTION comp() RETURNS TEXT +AS $$ +BEGIN + RETURN (SELECT CASE + WHEN m.id = c.relfilenode THEN 'Unchanged' + ELSE 'Rewritten' + END + FROM m, pg_class AS c, pg_namespace AS s + WHERE c.relname = 't' + AND c.relnamespace = s.oid + AND s.nspname = 'fast_default'); +END; +$$ LANGUAGE 'plpgsql' +-- +FUNCTION: name="comp" function="comp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +CREATE FUNCTION log_rewrite() RETURNS event_trigger +LANGUAGE plpgsql as +$func$ + +declare + this_schema text; +begin + select into this_schema relnamespace::regnamespace::text + from pg_class + where oid = pg_event_trigger_table_rewrite_oid(); + if this_schema = 'fast_default' + then + RAISE NOTICE 'rewriting table % for reason %', + pg_event_trigger_table_rewrite_oid()::regclass, + pg_event_trigger_table_rewrite_reason(); + end if; +end; +$func$ +-- +FUNCTION: name="log_rewrite" function="log_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 008 +CREATE TABLE has_volatile AS +SELECT * FROM generate_series(1,10) id +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 009 +CREATE EVENT TRIGGER has_volatile_rewrite + ON table_rewrite + EXECUTE PROCEDURE log_rewrite() +-- +STMT: CreateEventTrigStmt +== 010 +-- only the last of these should trigger a rewrite +ALTER TABLE has_volatile ADD col1 int +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +== 011 +ALTER TABLE has_volatile ADD col2 int DEFAULT 1 +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +== 012 +ALTER TABLE has_volatile ADD col3 timestamptz DEFAULT current_timestamp +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +== 013 +ALTER TABLE has_volatile ADD col4 int DEFAULT (random() * 10000)::int +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +== 014 +-- Test a large sample of different datatypes +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT 1) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 015 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +== 016 +INSERT INTO T VALUES (1), (2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT 'hello', + ALTER COLUMN c_int SET DEFAULT 2 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 018 +INSERT INTO T VALUES (3), (4) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'world', + ALTER COLUMN c_bpchar SET DEFAULT 'dog' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 020 +INSERT INTO T VALUES (5), (6) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +ALTER TABLE T ADD COLUMN c_date DATE DEFAULT '2016-06-02', + ALTER COLUMN c_text SET DEFAULT 'cat' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 022 +INSERT INTO T VALUES (7), (8) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP DEFAULT '2016-09-01 12:00:00', + ADD COLUMN c_timestamp_null TIMESTAMP, + ALTER COLUMN c_date SET DEFAULT '2010-01-01' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 024 +INSERT INTO T VALUES (9), (10) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +ALTER TABLE T ADD COLUMN c_array TEXT[] + DEFAULT '{"This", "is", "the", "real", "world"}', + ALTER COLUMN c_timestamp SET DEFAULT '1970-12-31 11:12:13', + ALTER COLUMN c_timestamp_null SET DEFAULT '2016-09-29 12:00:00' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 026 +INSERT INTO T VALUES (11), (12) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +ALTER TABLE T ADD COLUMN c_small SMALLINT DEFAULT -5, + ADD COLUMN c_small_null SMALLINT, + ALTER COLUMN c_array + SET DEFAULT '{"This", "is", "no", "fantasy"}' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 028 +INSERT INTO T VALUES (13), (14) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +ALTER TABLE T ADD COLUMN c_big BIGINT DEFAULT 180000000000018, + ALTER COLUMN c_small SET DEFAULT 9, + ALTER COLUMN c_small_null SET DEFAULT 13 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 030 +INSERT INTO T VALUES (15), (16) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +ALTER TABLE T ADD COLUMN c_num NUMERIC DEFAULT 1.00000000001, + ALTER COLUMN c_big SET DEFAULT -9999999999999999 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 032 +INSERT INTO T VALUES (17), (18) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +ALTER TABLE T ADD COLUMN c_time TIME DEFAULT '12:00:00', + ALTER COLUMN c_num SET DEFAULT 2.000000000000002 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 034 +INSERT INTO T VALUES (19), (20) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +ALTER TABLE T ADD COLUMN c_interval INTERVAL DEFAULT '1 day', + ALTER COLUMN c_time SET DEFAULT '23:59:59' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 036 +INSERT INTO T VALUES (21), (22) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +ALTER TABLE T ADD COLUMN c_hugetext TEXT DEFAULT repeat('abcdefg',1000), + ALTER COLUMN c_interval SET DEFAULT '3 hours' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 038 +INSERT INTO T VALUES (23), (24) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +ALTER TABLE T ALTER COLUMN c_interval DROP DEFAULT, + ALTER COLUMN c_hugetext SET DEFAULT repeat('poiuyt', 1000) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 040 +INSERT INTO T VALUES (25), (26) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT, + ALTER COLUMN c_date DROP DEFAULT, + ALTER COLUMN c_text DROP DEFAULT, + ALTER COLUMN c_timestamp DROP DEFAULT, + ALTER COLUMN c_array DROP DEFAULT, + ALTER COLUMN c_small DROP DEFAULT, + ALTER COLUMN c_big DROP DEFAULT, + ALTER COLUMN c_num DROP DEFAULT, + ALTER COLUMN c_time DROP DEFAULT, + ALTER COLUMN c_hugetext DROP DEFAULT +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 042 +INSERT INTO T VALUES (27), (28) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +SELECT pk, c_int, c_bpchar, c_text, c_date, c_timestamp, + c_timestamp_null, c_array, c_small, c_small_null, + c_big, c_num, c_time, c_interval, + c_hugetext = repeat('abcdefg',1000) as c_hugetext_origdef, + c_hugetext = repeat('poiuyt', 1000) as c_hugetext_newdef +FROM T ORDER BY pk +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +== 045 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 046 +-- Test expressions in the defaults +CREATE OR REPLACE FUNCTION foo(a INT) RETURNS TEXT AS $$ +DECLARE res TEXT := ''; + i INT; +BEGIN + i := 0; + WHILE (i < a) LOOP + res := res || chr(ascii('a') + i); + i := i + 1; + END LOOP; + RETURN res; +END; $$ LANGUAGE PLPGSQL STABLE +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 047 +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT LENGTH(foo(6))) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 048 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +== 049 +INSERT INTO T VALUES (1), (2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT foo(4), + ALTER COLUMN c_int SET DEFAULT LENGTH(foo(8)) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 051 +INSERT INTO T VALUES (3), (4) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT foo(6), + ALTER COLUMN c_bpchar SET DEFAULT foo(3) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 053 +INSERT INTO T VALUES (5), (6) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +ALTER TABLE T ADD COLUMN c_date DATE + DEFAULT '2016-06-02'::DATE + LENGTH(foo(10)), + ALTER COLUMN c_text SET DEFAULT foo(12) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 055 +INSERT INTO T VALUES (7), (8) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP + DEFAULT '2016-09-01'::DATE + LENGTH(foo(10)), + ALTER COLUMN c_date + SET DEFAULT '2010-01-01'::DATE - LENGTH(foo(4)) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 057 +INSERT INTO T VALUES (9), (10) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +ALTER TABLE T ADD COLUMN c_array TEXT[] + DEFAULT ('{"This", "is", "' || foo(4) || + '","the", "real", "world"}')::TEXT[], + ALTER COLUMN c_timestamp + SET DEFAULT '1970-12-31'::DATE + LENGTH(foo(30)) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 059 +INSERT INTO T VALUES (11), (12) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +ALTER TABLE T ALTER COLUMN c_int DROP DEFAULT, + ALTER COLUMN c_array + SET DEFAULT ('{"This", "is", "' || foo(1) || + '", "fantasy"}')::text[] +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 061 +INSERT INTO T VALUES (13), (14) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT, + ALTER COLUMN c_date DROP DEFAULT, + ALTER COLUMN c_text DROP DEFAULT, + ALTER COLUMN c_timestamp DROP DEFAULT, + ALTER COLUMN c_array DROP DEFAULT +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 063 +INSERT INTO T VALUES (15), (16) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +SELECT * FROM T +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 065 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +== 066 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 067 +-- Test domains with default value for table rewrite. +CREATE DOMAIN domain1 AS int DEFAULT 11 +-- +STMT: CreateDomainStmt +== 068 +-- constant +CREATE DOMAIN domain2 AS int DEFAULT random(min=>10, max=>100) +-- +STMT: CreateDomainStmt +== 069 +-- volatile +CREATE DOMAIN domain3 AS text DEFAULT foo(4) +-- +STMT: CreateDomainStmt +== 070 +-- stable +CREATE DOMAIN domain4 AS text[] + DEFAULT ('{"This", "is", "' || foo(4) || '","the", "real", "world"}')::TEXT[] +-- +STMT: CreateDomainStmt +== 071 +CREATE TABLE t2 (a domain1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 072 +INSERT INTO t2 VALUES (1),(2) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +-- no table rewrite +ALTER TABLE t2 ADD COLUMN b domain1 default 3 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +== 074 +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +== 075 +-- table rewrite should happen +ALTER TABLE t2 ADD COLUMN c domain3 default left(random()::text,3) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +== 076 +-- no table rewrite +ALTER TABLE t2 ADD COLUMN d domain4 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +== 077 +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +== 078 +-- table rewrite should happen +ALTER TABLE t2 ADD COLUMN e domain2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +== 079 +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +== 080 +SELECT a, b, length(c) = 3 as c_ok, d, e >= 10 as e_ok FROM t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 081 +DROP TABLE t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +== 082 +DROP DOMAIN domain1 +-- +STMT: DropStmt +== 083 +DROP DOMAIN domain2 +-- +STMT: DropStmt +== 084 +DROP DOMAIN domain3 +-- +STMT: DropStmt +== 085 +DROP DOMAIN domain4 +-- +STMT: DropStmt +== 086 +DROP FUNCTION foo(INT) +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: DropStmt +== 087 +-- Fall back to full rewrite for volatile expressions +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 088 +INSERT INTO T VALUES (1) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +== 090 +-- now() is stable, because it returns the transaction timestamp +ALTER TABLE T ADD COLUMN c1 TIMESTAMP DEFAULT now() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 091 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +== 092 +-- clock_timestamp() is volatile +ALTER TABLE T ADD COLUMN c2 TIMESTAMP DEFAULT clock_timestamp() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 093 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +== 094 +-- check that we notice insertion of a volatile default argument +CREATE FUNCTION foolme(timestamptz DEFAULT clock_timestamp()) + RETURNS timestamptz + IMMUTABLE AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="foolme" function="foolme" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 095 +ALTER TABLE T ADD COLUMN c3 timestamptz DEFAULT foolme() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 096 +SELECT attname, atthasmissing, attmissingval FROM pg_attribute + WHERE attrelid = 't'::regclass AND attnum > 0 + ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 097 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 098 +DROP FUNCTION foolme(timestamptz) +-- +FUNCTION: name="foolme" function="foolme" schema="" ctx=DDL +STMT: DropStmt +== 099 +-- Simple querie +CREATE TABLE T (pk INT NOT NULL PRIMARY KEY) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 100 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +== 101 +INSERT INTO T SELECT * FROM generate_series(1, 10) a +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 102 +ALTER TABLE T ADD COLUMN c_bigint BIGINT NOT NULL DEFAULT -1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 103 +INSERT INTO T SELECT b, b - 10 FROM generate_series(11, 20) a(b) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 104 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'hello' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 105 +INSERT INTO T SELECT b, b - 10, (b + 10)::text FROM generate_series(21, 30) a(b) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 106 +-- WHERE clause +SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: SelectStmt +== 107 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: ExplainStmt +STMT: SelectStmt +== 108 +SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_text" +STMT: SelectStmt +== 109 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_text" +STMT: ExplainStmt +STMT: SelectStmt +== 110 +-- COALESCE +SELECT COALESCE(c_bigint, pk), COALESCE(c_text, pk::text) +FROM T +ORDER BY pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 111 +-- Aggregate function +SELECT SUM(c_bigint), MAX(c_text COLLATE "C" ), MIN(c_text COLLATE "C") FROM T +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 112 +-- ORDER BY +SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 113 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 114 +-- LIMIT +SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: SelectStmt +== 115 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: ExplainStmt +STMT: SelectStmt +== 116 +-- DELETE with RETURNING +DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING * +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +== 117 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING * +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 118 +-- UPDATE +UPDATE T SET c_text = '"' || c_text || '"' WHERE pk < 10 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 119 +SELECT * FROM T WHERE c_text LIKE '"%"' ORDER BY PK +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_text" +STMT: SelectStmt +== 120 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +== 121 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 122 +-- Combine with other DDL +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 123 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +== 124 +INSERT INTO T VALUES (1), (2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +ALTER TABLE T ADD COLUMN c_int INT NOT NULL DEFAULT -1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 126 +INSERT INTO T VALUES (3), (4) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'Hello' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 128 +INSERT INTO T VALUES (5), (6) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +ALTER TABLE T ALTER COLUMN c_text SET DEFAULT 'world', + ALTER COLUMN c_int SET DEFAULT 1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 130 +INSERT INTO T VALUES (7), (8) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 131 +SELECT * FROM T ORDER BY pk +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 132 +-- Add an index +CREATE INDEX i ON T(c_int, c_text) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +== 133 +SELECT c_text FROM T WHERE c_int = -1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_int" +STMT: SelectStmt +== 134 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +== 135 +-- query to exercise expand_tuple function +CREATE TABLE t1 AS +SELECT 1::int AS a , 2::int AS b +FROM generate_series(1,20) q +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 136 +ALTER TABLE t1 ADD COLUMN c text +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +== 137 +SELECT a, + stddev(cast((SELECT sum(1) FROM generate_series(1,20) x) AS float4)) + OVER (PARTITION BY a,b,c ORDER BY b) + AS z +FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 138 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 139 +-- test that we account for missing columns without defaults correctly +-- in expand_tuple, and that rows are correctly expanded for triggers + +CREATE FUNCTION test_trigger() +RETURNS trigger +LANGUAGE plpgsql +AS $$ + +begin + raise notice 'old tuple: %', to_json(OLD)::text; + if TG_OP = 'DELETE' + then + return OLD; + else + return NEW; + end if; +end; + +$$ +-- +FUNCTION: name="test_trigger" function="test_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 140 +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 141 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 143 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 144 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 145 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 146 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 147 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 148 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 149 +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 150 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 152 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 153 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 154 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 155 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 156 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 157 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 158 +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 159 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 161 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 162 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 163 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 164 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 165 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 166 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 167 +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 168 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 170 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 171 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 172 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 173 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 174 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 175 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 176 +-- same as last 4 tests but here the last original column has a NULL value +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 177 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 179 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 180 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 181 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 182 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 183 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 184 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 185 +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 186 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 188 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 189 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 190 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 191 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 192 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 193 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 194 +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 195 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 197 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 198 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 199 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 200 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 201 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 202 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 203 +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 204 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 205 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 206 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 207 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +== 208 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 209 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 210 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 211 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 212 +-- make sure expanded tuple has correct self pointer +-- it will be required by the RI trigger doing the cascading delete + +CREATE TABLE leader (a int PRIMARY KEY, b int) +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: CreateStmt +== 213 +CREATE TABLE follower (a int REFERENCES leader ON DELETE CASCADE, b int) +-- +TABLE: name="follower" schema="" table="follower" ctx=DDL +STMT: CreateStmt +== 214 +INSERT INTO leader VALUES (1, 1), (2, 2) +-- +TABLE: name="leader" schema="" table="leader" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +ALTER TABLE leader ADD c int +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: AlterTableStmt +== 216 +ALTER TABLE leader DROP c +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: AlterTableStmt +== 217 +DELETE FROM leader +-- +TABLE: name="leader" schema="" table="leader" ctx=DML +STMT: DeleteStmt +== 218 +-- check that ALTER TABLE ... ALTER TYPE does the right thing + +CREATE TABLE vtype( a integer) +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: CreateStmt +== 219 +INSERT INTO vtype VALUES (1) +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 220 +ALTER TABLE vtype ADD COLUMN b DOUBLE PRECISION DEFAULT 0.2 +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: AlterTableStmt +== 221 +ALTER TABLE vtype ADD COLUMN c BOOLEAN DEFAULT true +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: AlterTableStmt +== 222 +SELECT * FROM vtype +-- +TABLE: name="vtype" schema="" table="vtype" ctx=Select +STMT: SelectStmt +== 223 +ALTER TABLE vtype + ALTER b TYPE text USING b::text, + ALTER c TYPE text USING c::text +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: AlterTableStmt +== 224 +SELECT * FROM vtype +-- +TABLE: name="vtype" schema="" table="vtype" ctx=Select +STMT: SelectStmt +== 225 +-- also check the case that doesn't rewrite the table + +CREATE TABLE vtype2 (a int) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: CreateStmt +== 226 +INSERT INTO vtype2 VALUES (1) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 227 +ALTER TABLE vtype2 ADD COLUMN b varchar(10) DEFAULT 'xxx' +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: AlterTableStmt +== 228 +ALTER TABLE vtype2 ALTER COLUMN b SET DEFAULT 'yyy' +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: AlterTableStmt +== 229 +INSERT INTO vtype2 VALUES (2) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: AlterTableStmt +== 231 +SELECT * FROM vtype2 +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=Select +STMT: SelectStmt +== 232 +-- Ensure that defaults are checked when evaluating whether HOT update +-- is possible, this was broken for a while: +-- https://postgr.es/m/20190202133521.ylauh3ckqa7colzj%40alap3.anarazel.de +BEGIN +-- +STMT: TransactionStmt +== 233 +CREATE TABLE t() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 234 +INSERT INTO t DEFAULT VALUES +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +== 235 +ALTER TABLE t ADD COLUMN a int DEFAULT 1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +== 236 +CREATE INDEX ON t(a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +== 237 +-- set column with a default 1 to NULL, due to a bug that wasn't +-- noticed has heap_getattr buggily returned NULL for default columns +UPDATE t SET a = NULL +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +== 238 +-- verify that index and non-index scans show the same result +SET LOCAL enable_seqscan = true +-- +STMT: VariableSetStmt +== 239 +SELECT * FROM t WHERE a IS NULL +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 240 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +== 241 +SELECT * FROM t WHERE a IS NULL +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 242 +ROLLBACK +-- +STMT: TransactionStmt +== 243 +-- verify that a default set on a non-plain table doesn't set a missing +-- value on the attribute +CREATE FOREIGN DATA WRAPPER dummy +-- +STMT: CreateFdwStmt +== 244 +CREATE SERVER s0 FOREIGN DATA WRAPPER dummy +-- +STMT: CreateForeignServerStmt +== 245 +CREATE FOREIGN TABLE ft1 (c1 integer NOT NULL) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 246 +ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer DEFAULT 0 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 247 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 248 +SELECT count(*) + FROM pg_attribute + WHERE attrelid = 'ft1'::regclass AND + (attmissingval IS NOT NULL OR atthasmissing) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attmissingval" +FILTER: schema="" table="" column="atthasmissing" +STMT: SelectStmt +== 249 +-- cleanup +DROP FOREIGN TABLE ft1 +-- +STMT: DropStmt +== 250 +DROP SERVER s0 +-- +STMT: DropStmt +== 251 +DROP FOREIGN DATA WRAPPER dummy +-- +STMT: DropStmt +== 252 +DROP TABLE vtype +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: DropStmt +== 253 +DROP TABLE vtype2 +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: DropStmt +== 254 +DROP TABLE follower +-- +TABLE: name="follower" schema="" table="follower" ctx=DDL +STMT: DropStmt +== 255 +DROP TABLE leader +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: DropStmt +== 256 +DROP FUNCTION test_trigger() +-- +FUNCTION: name="test_trigger" function="test_trigger" schema="" ctx=DDL +STMT: DropStmt +== 257 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 258 +DROP FUNCTION set(name) +-- +FUNCTION: name="set" function="set" schema="" ctx=DDL +STMT: DropStmt +== 259 +DROP FUNCTION comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=DDL +STMT: DropStmt +== 260 +DROP TABLE m +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: DropStmt +== 261 +DROP TABLE has_volatile +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: DropStmt +== 262 +DROP EVENT TRIGGER has_volatile_rewrite +-- +STMT: DropStmt +== 263 +DROP FUNCTION log_rewrite +-- +FUNCTION: name="log_rewrite" function="log_rewrite" schema="" ctx=DDL +STMT: DropStmt +== 264 +DROP SCHEMA fast_default +-- +STMT: DropStmt +== 265 +-- Leave a table with an active fast default in place, for pg_upgrade testing +set search_path = public +-- +STMT: VariableSetStmt +== 266 +create table has_fast_default(f1 int) +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=DDL +STMT: CreateStmt +== 267 +insert into has_fast_default values(1) +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +alter table has_fast_default add column f2 int default 42 +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=DDL +STMT: AlterTableStmt +== 269 +table has_fast_default +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=Select +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/float4.metadata.json b/parser/testdata/summary/postgres_regress/float4.metadata.json new file mode 100644 index 0000000..a864d8e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/float4.metadata.json @@ -0,0 +1,104 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100" + ] +} diff --git a/parser/testdata/summary/postgres_regress/float4.test b/parser/testdata/summary/postgres_regress/float4.test new file mode 100644 index 0000000..9ed277a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/float4.test @@ -0,0 +1,747 @@ +== 001 +|-- +-- FLOAT4 +|-- + +CREATE TABLE FLOAT4_TBL (f1 float4) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO FLOAT4_TBL(f1) VALUES (' 0.0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30 ') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 ') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- test for over and under flow +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +-- bad input +INSERT INTO FLOAT4_TBL(f1) VALUES ('') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO FLOAT4_TBL(f1) VALUES (' ') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34.5', 'float4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT pg_input_is_valid('xyz', 'float4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT pg_input_is_valid('1e400', 'float4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT * FROM pg_input_error_info('1e400', 'float4') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- special inputs +SELECT 'NaN'::float4 +-- +STMT: SelectStmt +== 032 +SELECT 'nan'::float4 +-- +STMT: SelectStmt +== 033 +SELECT ' NAN '::float4 +-- +STMT: SelectStmt +== 034 +SELECT 'infinity'::float4 +-- +STMT: SelectStmt +== 035 +SELECT ' -INFINiTY '::float4 +-- +STMT: SelectStmt +== 036 +-- bad special inputs +SELECT 'N A N'::float4 +-- +STMT: SelectStmt +== 037 +SELECT 'NaN x'::float4 +-- +STMT: SelectStmt +== 038 +SELECT ' INFINITY x'::float4 +-- +STMT: SelectStmt +== 039 +SELECT 'Infinity'::float4 + 100.0 +-- +STMT: SelectStmt +== 040 +SELECT 'Infinity'::float4 / 'Infinity'::float4 +-- +STMT: SelectStmt +== 041 +SELECT '42'::float4 / 'Infinity'::float4 +-- +STMT: SelectStmt +== 042 +SELECT 'nan'::float4 / 'nan'::float4 +-- +STMT: SelectStmt +== 043 +SELECT 'nan'::float4 / '0'::float4 +-- +STMT: SelectStmt +== 044 +SELECT 'nan'::numeric::float4 +-- +STMT: SelectStmt +== 045 +SELECT * FROM FLOAT4_TBL +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +STMT: SelectStmt +== 046 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 047 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 048 +SELECT f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1 +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 049 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 050 +SELECT f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1 +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 051 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 052 +SELECT f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 053 +SELECT f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 054 +SELECT f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 055 +SELECT f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 056 +-- test divide by zero +SELECT f.f1 / '0.0' from FLOAT4_TBL f +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +STMT: SelectStmt +== 057 +SELECT * FROM FLOAT4_TBL +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +STMT: SelectStmt +== 058 +-- test the unary float4abs operator +SELECT f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +STMT: SelectStmt +== 059 +UPDATE FLOAT4_TBL + SET f1 = FLOAT4_TBL.f1 * '-1' + WHERE FLOAT4_TBL.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: UpdateStmt +== 060 +SELECT * FROM FLOAT4_TBL +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +STMT: SelectStmt +== 061 +-- test edge-case coercions to integer +SELECT '32767.4'::float4::int2 +-- +STMT: SelectStmt +== 062 +SELECT '32767.6'::float4::int2 +-- +STMT: SelectStmt +== 063 +SELECT '-32768.4'::float4::int2 +-- +STMT: SelectStmt +== 064 +SELECT '-32768.6'::float4::int2 +-- +STMT: SelectStmt +== 065 +SELECT '2147483520'::float4::int4 +-- +STMT: SelectStmt +== 066 +SELECT '2147483647'::float4::int4 +-- +STMT: SelectStmt +== 067 +SELECT '-2147483648.5'::float4::int4 +-- +STMT: SelectStmt +== 068 +SELECT '-2147483900'::float4::int4 +-- +STMT: SelectStmt +== 069 +SELECT '9223369837831520256'::float4::int8 +-- +STMT: SelectStmt +== 070 +SELECT '9223372036854775807'::float4::int8 +-- +STMT: SelectStmt +== 071 +SELECT '-9223372036854775808.5'::float4::int8 +-- +STMT: SelectStmt +== 072 +SELECT '-9223380000000000000'::float4::int8 +-- +STMT: SelectStmt +== 073 +-- Test for correct input rounding in edge cases. +-- These lists are from Paxson 1991, excluding subnormals and +-- inputs of over 9 sig. digits. + +SELECT float4send('5e-20'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT float4send('67e14'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 075 +SELECT float4send('985e15'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT float4send('55895e-16'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 077 +SELECT float4send('7038531e-32'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT float4send('702990899e-20'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 079 +SELECT float4send('3e-23'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 080 +SELECT float4send('57e18'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 081 +SELECT float4send('789e-35'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT float4send('2539e-18'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT float4send('76173e28'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 084 +SELECT float4send('887745e-11'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT float4send('5382571e-37'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT float4send('82381273e-35'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 087 +SELECT float4send('750486563e-38'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 088 +-- Test that the smallest possible normalized input value inputs +-- correctly, either in 9-significant-digit or shortest-decimal +-- format. +|-- +-- exact val is 1.1754943508... +-- shortest val is 1.1754944000 +-- midpoint to next val is 1.1754944208... + +SELECT float4send('1.17549435e-38'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 089 +SELECT float4send('1.1754944e-38'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 090 +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). + +create type xfloat4 +-- +STMT: DefineStmt +== 091 +create function xfloat4in(cstring) returns xfloat4 immutable strict + language internal as 'int4in' +-- +FUNCTION: name="xfloat4in" function="xfloat4in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 092 +create function xfloat4out(xfloat4) returns cstring immutable strict + language internal as 'int4out' +-- +FUNCTION: name="xfloat4out" function="xfloat4out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 093 +create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4) +-- +STMT: DefineStmt +== 094 +create cast (xfloat4 as float4) without function +-- +STMT: CreateCastStmt +== 095 +create cast (float4 as xfloat4) without function +-- +STMT: CreateCastStmt +== 096 +create cast (xfloat4 as integer) without function +-- +STMT: CreateCastStmt +== 097 +create cast (integer as xfloat4) without function +-- +STMT: CreateCastStmt +== 098 +-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm + +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. + +with testdata(bits) as (values + -- small subnormals + (x'00000001'), + (x'00000002'), (x'00000003'), + (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'), + (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'), + -- stress values + (x'0053c4f4'), -- 7693e-42 + (x'006c85c4'), -- 996622e-44 + (x'0041ca76'), -- 60419369e-46 + (x'004b7678'), -- 6930161142e-48 + -- taken from upstream testsuite + (x'00000007'), + (x'00424fe2'), + -- borderline between subnormal and normal + (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff')) +select float4send(flt) as ibits, + flt + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 099 +with testdata(bits) as (values + (x'00000000'), + -- smallest normal values + (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'), + (x'00800006'), + -- small normal values chosen for short vs. long output + (x'008002f1'), (x'008002f2'), (x'008002f3'), + (x'00800e17'), (x'00800e18'), (x'00800e19'), + -- assorted values (random mantissae) + (x'01000001'), (x'01102843'), (x'01a52c98'), + (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'), + (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'), + (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'), + (x'1f850283'), (x'2874a9d6'), + -- values around 5e-08 + (x'3356bf94'), (x'3356bf95'), (x'3356bf96'), + -- around 1e-07 + (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'), + -- around 3e-07 .. 1e-04 + (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'), + (x'350637bc'), (x'350637bd'), (x'350637be'), + (x'35719786'), (x'35719787'), (x'35719788'), + (x'358637bc'), (x'358637bd'), (x'358637be'), + (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'), + (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'), + -- format crossover at 1e-04 + (x'38d1b714'), (x'38d1b715'), (x'38d1b716'), + (x'38d1b717'), (x'38d1b718'), (x'38d1b719'), + (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'), + (x'38d1b71d'), + -- + (x'38dffffe'), (x'38dfffff'), (x'38e00000'), + (x'38efffff'), (x'38f00000'), (x'38f00001'), + (x'3a83126e'), (x'3a83126f'), (x'3a831270'), + (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'), + (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'), + -- chosen to need 9 digits for 3dcccd70 + (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'), + -- + (x'3effffff'), (x'3f000000'), (x'3f000001'), + (x'3f333332'), (x'3f333333'), (x'3f333334'), + -- approach 1.0 with increasing numbers of 9s + (x'3f666665'), (x'3f666666'), (x'3f666667'), + (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'), + (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'), + (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'), + (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'), + (x'3f7fffee'), (x'3f7fffef'), + -- values very close to 1 + (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'), + (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'), + (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'), + (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'), + (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'), + (x'3f7fffff'), + (x'3f800000'), + (x'3f800001'), (x'3f800002'), (x'3f800003'), + (x'3f800004'), (x'3f800005'), (x'3f800006'), + (x'3f800007'), (x'3f800008'), (x'3f800009'), + -- values 1 to 1.1 + (x'3f80000f'), (x'3f800010'), (x'3f800011'), + (x'3f800012'), (x'3f800013'), (x'3f800014'), + (x'3f800017'), (x'3f800018'), (x'3f800019'), + (x'3f80001a'), (x'3f80001b'), (x'3f80001c'), + (x'3f800029'), (x'3f80002a'), (x'3f80002b'), + (x'3f800053'), (x'3f800054'), (x'3f800055'), + (x'3f800346'), (x'3f800347'), (x'3f800348'), + (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'), + (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'), + (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'), + -- + (x'3fc90fdb'), -- pi/2 + (x'402df854'), -- e + (x'40490fdb'), -- pi + -- + (x'409fffff'), (x'40a00000'), (x'40a00001'), + (x'40afffff'), (x'40b00000'), (x'40b00001'), + (x'411fffff'), (x'41200000'), (x'41200001'), + (x'42c7ffff'), (x'42c80000'), (x'42c80001'), + (x'4479ffff'), (x'447a0000'), (x'447a0001'), + (x'461c3fff'), (x'461c4000'), (x'461c4001'), + (x'47c34fff'), (x'47c35000'), (x'47c35001'), + (x'497423ff'), (x'49742400'), (x'49742401'), + (x'4b18967f'), (x'4b189680'), (x'4b189681'), + (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'), + (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'), + (x'501502f8'), (x'501502f9'), (x'501502fa'), + (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'), + -- stress values + (x'1f6c1e4a'), -- 5e-20 + (x'59be6cea'), -- 67e14 + (x'5d5ab6c4'), -- 985e15 + (x'2cc4a9bd'), -- 55895e-16 + (x'15ae43fd'), -- 7038531e-32 + (x'2cf757ca'), -- 702990899e-20 + (x'665ba998'), -- 25933168707e13 + (x'743c3324'), -- 596428896559e20 + -- exercise fixed-point memmoves + (x'47f1205a'), + (x'4640e6ae'), + (x'449a5225'), + (x'42f6e9d5'), + (x'414587dd'), + (x'3f9e064b'), + -- these cases come from the upstream's testsuite + -- BoundaryRoundEven + (x'4c000004'), + (x'50061c46'), + (x'510006a8'), + -- ExactValueRoundEven + (x'48951f84'), + (x'45fd1840'), + -- LotsOfTrailingZeros + (x'39800000'), + (x'3b200000'), + (x'3b900000'), + (x'3bd00000'), + -- Regression + (x'63800000'), + (x'4b000000'), + (x'4b800000'), + (x'4c000001'), + (x'4c800b0d'), + (x'00d24584'), + (x'00d90b88'), + (x'45803f34'), + (x'4f9f24f7'), + (x'3a8722c3'), + (x'5c800041'), + (x'15ae43fd'), + (x'5d4cccfb'), + (x'4c800001'), + (x'57800ed8'), + (x'5f000000'), + (x'700000f0'), + (x'5f23e9ac'), + (x'5e9502f9'), + (x'5e8012b1'), + (x'3c000028'), + (x'60cde861'), + (x'03aa2a50'), + (x'43480000'), + (x'4c000000'), + -- LooksLikePow5 + (x'5D1502F9'), + (x'5D9502F9'), + (x'5E1502F9'), + -- OutputLength + (x'3f99999a'), + (x'3f9d70a4'), + (x'3f9df3b6'), + (x'3f9e0419'), + (x'3f9e0610'), + (x'3f9e064b'), + (x'3f9e0651'), + (x'03d20cfe') +) +select float4send(flt) as ibits, + flt, + flt::text::float4 as r_flt, + float4send(flt::text::float4) as obits, + float4send(flt::text::float4) = float4send(flt) as correct + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +== 100 +-- clean up, lest opr_sanity complain +drop type xfloat4 cascade +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/float8.metadata.json b/parser/testdata/summary/postgres_regress/float8.metadata.json new file mode 100644 index 0000000..194b55b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/float8.metadata.json @@ -0,0 +1,173 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169" + ] +} diff --git a/parser/testdata/summary/postgres_regress/float8.test b/parser/testdata/summary/postgres_regress/float8.test new file mode 100644 index 0000000..5d8f908 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/float8.test @@ -0,0 +1,1173 @@ +== 001 +|-- +-- FLOAT8 +|-- + +|-- +-- Build a table for testing +-- (This temporarily hides the table created in test_setup.sql) +|-- + +CREATE TEMP TABLE FLOAT8_TBL(f1 float8) +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 ') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 ') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- test for underflow and overflow handling +SELECT '10e400'::float8 +-- +STMT: SelectStmt +== 008 +SELECT '-10e400'::float8 +-- +STMT: SelectStmt +== 009 +SELECT '10e-400'::float8 +-- +STMT: SelectStmt +== 010 +SELECT '-10e-400'::float8 +-- +STMT: SelectStmt +== 011 +-- test smallest normalized input +SELECT float8send('2.2250738585072014E-308'::float8) +-- +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- bad input +INSERT INTO FLOAT8_TBL(f1) VALUES ('') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO FLOAT8_TBL(f1) VALUES (' ') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34.5', 'float8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT pg_input_is_valid('xyz', 'float8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT pg_input_is_valid('1e4000', 'float8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT * FROM pg_input_error_info('1e4000', 'float8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 024 +-- special inputs +SELECT 'NaN'::float8 +-- +STMT: SelectStmt +== 025 +SELECT 'nan'::float8 +-- +STMT: SelectStmt +== 026 +SELECT ' NAN '::float8 +-- +STMT: SelectStmt +== 027 +SELECT 'infinity'::float8 +-- +STMT: SelectStmt +== 028 +SELECT ' -INFINiTY '::float8 +-- +STMT: SelectStmt +== 029 +-- bad special inputs +SELECT 'N A N'::float8 +-- +STMT: SelectStmt +== 030 +SELECT 'NaN x'::float8 +-- +STMT: SelectStmt +== 031 +SELECT ' INFINITY x'::float8 +-- +STMT: SelectStmt +== 032 +SELECT 'Infinity'::float8 + 100.0 +-- +STMT: SelectStmt +== 033 +SELECT 'Infinity'::float8 / 'Infinity'::float8 +-- +STMT: SelectStmt +== 034 +SELECT '42'::float8 / 'Infinity'::float8 +-- +STMT: SelectStmt +== 035 +SELECT 'nan'::float8 / 'nan'::float8 +-- +STMT: SelectStmt +== 036 +SELECT 'nan'::float8 / '0'::float8 +-- +STMT: SelectStmt +== 037 +SELECT 'nan'::numeric::float8 +-- +STMT: SelectStmt +== 038 +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +== 039 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 040 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 041 +SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 042 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 043 +SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 044 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 045 +SELECT f.f1, f.f1 * '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 046 +SELECT f.f1, f.f1 + '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 047 +SELECT f.f1, f.f1 / '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 048 +SELECT f.f1, f.f1 - '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 049 +SELECT f.f1 ^ '2.0' AS square_f1 + FROM FLOAT8_TBL f where f.f1 = '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 050 +-- absolute value +SELECT f.f1, @f.f1 AS abs_f1 + FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +== 051 +-- truncate +SELECT f.f1, trunc(f.f1) AS trunc_f1 + FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 052 +-- round +SELECT f.f1, round(f.f1) AS round_f1 + FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 053 +-- ceil / ceiling +select ceil(f1) as ceil_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ceil" function="ceil" schema="" ctx=Call +STMT: SelectStmt +== 054 +select ceiling(f1) as ceiling_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ceiling" function="ceiling" schema="" ctx=Call +STMT: SelectStmt +== 055 +-- floor +select floor(f1) as floor_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="floor" function="floor" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- sign +select sign(f1) as sign_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="sign" function="sign" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +== 058 +-- square root +SELECT sqrt(float8 '64') AS eight +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT |/ float8 '64' AS eight +-- +STMT: SelectStmt +== 060 +SELECT f.f1, |/f.f1 AS sqrt_f1 + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 061 +-- power +SELECT power(float8 '144', float8 '0.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 062 +SELECT power(float8 'NaN', float8 '0.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT power(float8 '144', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT power(float8 'NaN', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT power(float8 '-1', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT power(float8 '1', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT power(float8 'NaN', float8 '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT power(float8 'inf', float8 '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT power(float8 '-inf', float8 '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT power(float8 '0', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT power(float8 '0', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT power(float8 '1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 073 +SELECT power(float8 '1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT power(float8 '-1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 075 +SELECT power(float8 '-1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT power(float8 '0.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 077 +SELECT power(float8 '-0.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT power(float8 '1.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 079 +SELECT power(float8 '-1.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 080 +SELECT power(float8 '0.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 081 +SELECT power(float8 '-0.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT power(float8 '1.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT power(float8 '-1.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 084 +SELECT power(float8 'inf', float8 '-2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT power(float8 'inf', float8 '2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT power(float8 'inf', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 087 +SELECT power(float8 'inf', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 088 +-- Intel's icc misoptimizes the code that controls the sign of this result, +-- even with -mp1. Pending a fix for that, only test for "is it zero". +SELECT power(float8 '-inf', float8 '-2') = '0' +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 089 +SELECT power(float8 '-inf', float8 '-3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 090 +SELECT power(float8 '-inf', float8 '2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 091 +SELECT power(float8 '-inf', float8 '3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 092 +SELECT power(float8 '-inf', float8 '3.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 093 +SELECT power(float8 '-inf', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 094 +SELECT power(float8 '-inf', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 095 +-- take exp of ln(f.f1) +SELECT f.f1, exp(ln(f.f1)) AS exp_ln_f1 + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 096 +-- check edge cases for exp +SELECT exp('inf'::float8), exp('-inf'::float8), exp('nan'::float8) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 097 +-- cube root +SELECT ||/ float8 '27' AS three +-- +STMT: SelectStmt +== 098 +SELECT f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +== 099 +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +== 100 +UPDATE FLOAT8_TBL + SET f1 = FLOAT8_TBL.f1 * '-1' + WHERE FLOAT8_TBL.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: UpdateStmt +== 101 +SELECT f.f1 * '1e200' from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +== 102 +SELECT f.f1 ^ '1e200' from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +== 103 +SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5 +-- +STMT: SelectStmt +== 104 +SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 105 +SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +== 106 +SELECT exp(f.f1) from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 107 +SELECT f.f1 / '0.0' from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +== 108 +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +== 109 +-- hyperbolic functions +-- we run these with extra_float_digits = 0 too, since different platforms +-- tend to produce results that vary in the last place. +SELECT sinh(float8 '1') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +== 110 +SELECT cosh(float8 '1') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +== 111 +SELECT tanh(float8 '1') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +== 112 +SELECT asinh(float8 '1') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +== 113 +SELECT acosh(float8 '2') +-- +FUNCTION: name="acosh" function="acosh" schema="" ctx=Call +STMT: SelectStmt +== 114 +SELECT atanh(float8 '0.5') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +== 115 +-- test Inf/NaN cases for hyperbolic functions +SELECT sinh(float8 'infinity') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +== 116 +SELECT sinh(float8 '-infinity') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +== 117 +SELECT sinh(float8 'nan') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +== 118 +SELECT cosh(float8 'infinity') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +== 119 +SELECT cosh(float8 '-infinity') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +== 120 +SELECT cosh(float8 'nan') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +== 121 +SELECT tanh(float8 'infinity') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +== 122 +SELECT tanh(float8 '-infinity') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +== 123 +SELECT tanh(float8 'nan') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +== 124 +SELECT asinh(float8 'infinity') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +== 125 +SELECT asinh(float8 '-infinity') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +== 126 +SELECT asinh(float8 'nan') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +== 127 +-- acosh(Inf) should be Inf, but some mingw versions produce NaN, so skip test +-- SELECT acosh(float8 'infinity'); +SELECT acosh(float8 '-infinity') +-- +FUNCTION: name="acosh" function="acosh" schema="" ctx=Call +STMT: SelectStmt +== 128 +SELECT acosh(float8 'nan') +-- +FUNCTION: name="acosh" function="acosh" schema="" ctx=Call +STMT: SelectStmt +== 129 +SELECT atanh(float8 'infinity') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +== 130 +SELECT atanh(float8 '-infinity') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +== 131 +SELECT atanh(float8 'nan') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +== 132 +-- error functions +-- we run these with extra_float_digits = -1, to get consistently rounded +-- results on all platforms. +SET extra_float_digits = -1 +-- +STMT: VariableSetStmt +== 133 +SELECT x, + erf(x), + erfc(x) +FROM (VALUES (float8 '-infinity'), + (-28), (-6), (-3.4), (-2.1), (-1.1), (-0.45), + (-1.2e-9), (-2.3e-13), (-1.2e-17), (0), + (1.2e-17), (2.3e-13), (1.2e-9), + (0.45), (1.1), (2.1), (3.4), (6), (28), + (float8 'infinity'), (float8 'nan')) AS t(x) +-- +FUNCTION: name="erf" function="erf" schema="" ctx=Call +FUNCTION: name="erfc" function="erfc" schema="" ctx=Call +STMT: SelectStmt +== 134 +RESET extra_float_digits +-- +STMT: VariableSetStmt +== 135 +-- test for over- and underflow +INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +DROP TABLE FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: DropStmt +== 140 +-- Check the float8 values exported for use by other tests + +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +== 141 +-- test edge-case coercions to integer +SELECT '32767.4'::float8::int2 +-- +STMT: SelectStmt +== 142 +SELECT '32767.6'::float8::int2 +-- +STMT: SelectStmt +== 143 +SELECT '-32768.4'::float8::int2 +-- +STMT: SelectStmt +== 144 +SELECT '-32768.6'::float8::int2 +-- +STMT: SelectStmt +== 145 +SELECT '2147483647.4'::float8::int4 +-- +STMT: SelectStmt +== 146 +SELECT '2147483647.6'::float8::int4 +-- +STMT: SelectStmt +== 147 +SELECT '-2147483648.4'::float8::int4 +-- +STMT: SelectStmt +== 148 +SELECT '-2147483648.6'::float8::int4 +-- +STMT: SelectStmt +== 149 +SELECT '9223372036854773760'::float8::int8 +-- +STMT: SelectStmt +== 150 +SELECT '9223372036854775807'::float8::int8 +-- +STMT: SelectStmt +== 151 +SELECT '-9223372036854775808.5'::float8::int8 +-- +STMT: SelectStmt +== 152 +SELECT '-9223372036854780000'::float8::int8 +-- +STMT: SelectStmt +== 153 +-- test exact cases for trigonometric functions in degrees + +SELECT x, + sind(x), + sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact +FROM (VALUES (0), (30), (90), (150), (180), + (210), (270), (330), (360)) AS t(x) +-- +FUNCTION: name="sind" function="sind" schema="" ctx=Call +FUNCTION: name="sind" function="sind" schema="" ctx=Call +STMT: SelectStmt +== 154 +SELECT x, + cosd(x), + cosd(x) IN (-1,-0.5,0,0.5,1) AS cosd_exact +FROM (VALUES (0), (60), (90), (120), (180), + (240), (270), (300), (360)) AS t(x) +-- +FUNCTION: name="cosd" function="cosd" schema="" ctx=Call +FUNCTION: name="cosd" function="cosd" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT x, + tand(x), + tand(x) IN ('-Infinity'::float8,-1,0, + 1,'Infinity'::float8) AS tand_exact, + cotd(x), + cotd(x) IN ('-Infinity'::float8,-1,0, + 1,'Infinity'::float8) AS cotd_exact +FROM (VALUES (0), (45), (90), (135), (180), + (225), (270), (315), (360)) AS t(x) +-- +FUNCTION: name="tand" function="tand" schema="" ctx=Call +FUNCTION: name="tand" function="tand" schema="" ctx=Call +FUNCTION: name="cotd" function="cotd" schema="" ctx=Call +FUNCTION: name="cotd" function="cotd" schema="" ctx=Call +STMT: SelectStmt +== 156 +SELECT x, + asind(x), + asind(x) IN (-90,-30,0,30,90) AS asind_exact, + acosd(x), + acosd(x) IN (0,60,90,120,180) AS acosd_exact +FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x) +-- +FUNCTION: name="asind" function="asind" schema="" ctx=Call +FUNCTION: name="asind" function="asind" schema="" ctx=Call +FUNCTION: name="acosd" function="acosd" schema="" ctx=Call +FUNCTION: name="acosd" function="acosd" schema="" ctx=Call +STMT: SelectStmt +== 157 +SELECT x, + atand(x), + atand(x) IN (-90,-45,0,45,90) AS atand_exact +FROM (VALUES ('-Infinity'::float8), (-1), (0), (1), + ('Infinity'::float8)) AS t(x) +-- +FUNCTION: name="atand" function="atand" schema="" ctx=Call +FUNCTION: name="atand" function="atand" schema="" ctx=Call +STMT: SelectStmt +== 158 +SELECT x, y, + atan2d(y, x), + atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact +FROM (SELECT 10*cosd(a), 10*sind(a) + FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y) +-- +FUNCTION: name="atan2d" function="atan2d" schema="" ctx=Call +FUNCTION: name="atan2d" function="atan2d" schema="" ctx=Call +FUNCTION: name="cosd" function="cosd" schema="" ctx=Call +FUNCTION: name="sind" function="sind" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 159 +|-- +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). + +create type xfloat8 +-- +STMT: DefineStmt +== 160 +create function xfloat8in(cstring) returns xfloat8 immutable strict + language internal as 'int8in' +-- +FUNCTION: name="xfloat8in" function="xfloat8in" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 161 +create function xfloat8out(xfloat8) returns cstring immutable strict + language internal as 'int8out' +-- +FUNCTION: name="xfloat8out" function="xfloat8out" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 162 +create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8) +-- +STMT: DefineStmt +== 163 +create cast (xfloat8 as float8) without function +-- +STMT: CreateCastStmt +== 164 +create cast (float8 as xfloat8) without function +-- +STMT: CreateCastStmt +== 165 +create cast (xfloat8 as bigint) without function +-- +STMT: CreateCastStmt +== 166 +create cast (bigint as xfloat8) without function +-- +STMT: CreateCastStmt +== 167 +-- float8: seeeeeee eeeeeeee eeeeeeee mmmmmmmm mmmmmmmm(x4) + +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. + +with testdata(bits) as (values + -- small subnormals + (x'0000000000000001'), + (x'0000000000000002'), (x'0000000000000003'), + (x'0000000000001000'), (x'0000000100000000'), + (x'0000010000000000'), (x'0000010100000000'), + (x'0000400000000000'), (x'0000400100000000'), + (x'0000800000000000'), (x'0000800000000001'), + -- these values taken from upstream testsuite + (x'00000000000f4240'), + (x'00000000016e3600'), + (x'0000008cdcdea440'), + -- borderline between subnormal and normal + (x'000ffffffffffff0'), (x'000ffffffffffff1'), + (x'000ffffffffffffe'), (x'000fffffffffffff')) +select float8send(flt) as ibits, + flt + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +STMT: SelectStmt +== 168 +-- round-trip tests + +with testdata(bits) as (values + (x'0000000000000000'), + -- smallest normal values + (x'0010000000000000'), (x'0010000000000001'), + (x'0010000000000002'), (x'0018000000000000'), + -- + (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'), + (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'), + (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'), + (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'), + (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'), + (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'), + (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'), + (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'), + (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'), + (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'), + -- values very close to 1 + (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'), + (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'), + (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'), + (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'), + (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'), + (x'3fefffffffffffff'), + (x'3ff0000000000000'), + (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'), + (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'), + (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'), + -- + (x'3ff921fb54442d18'), + (x'4005bf0a8b14576a'), + (x'400921fb54442d18'), + -- + (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'), + (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'), + (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'), + (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'), + (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'), + (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'), + (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'), + (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'), + (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'), + (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'), + (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'), + (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'), + (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'), + (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'), + (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'), + (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'), + (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'), + (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'), + (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'), + (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'), + (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'), + (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'), + (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'), + (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'), + (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'), + -- + (x'7feffffffffffffe'), (x'7fefffffffffffff'), + -- round to even tests (+ve) + (x'4350000000000002'), + (x'4350000000002e06'), + (x'4352000000000003'), + (x'4352000000000004'), + (x'4358000000000003'), + (x'4358000000000004'), + (x'435f000000000020'), + -- round to even tests (-ve) + (x'c350000000000002'), + (x'c350000000002e06'), + (x'c352000000000003'), + (x'c352000000000004'), + (x'c358000000000003'), + (x'c358000000000004'), + (x'c35f000000000020'), + -- exercise fixed-point memmoves + (x'42dc12218377de66'), + (x'42a674e79c5fe51f'), + (x'4271f71fb04cb74c'), + (x'423cbe991a145879'), + (x'4206fee0e1a9e061'), + (x'41d26580b487e6b4'), + (x'419d6f34540ca453'), + (x'41678c29dcd6e9dc'), + (x'4132d687e3df217d'), + (x'40fe240c9fcb68c8'), + (x'40c81cd6e63c53d3'), + (x'40934a4584fd0fdc'), + (x'405edd3c07fb4c93'), + (x'4028b0fcd32f7076'), + (x'3ff3c0ca428c59f8'), + -- these cases come from the upstream's testsuite + -- LotsOfTrailingZeros) + (x'3e60000000000000'), + -- Regression + (x'c352bd2668e077c4'), + (x'434018601510c000'), + (x'43d055dc36f24000'), + (x'43e052961c6f8000'), + (x'3ff3c0ca2a5b1d5d'), + -- LooksLikePow5 + (x'4830f0cf064dd592'), + (x'4840f0cf064dd592'), + (x'4850f0cf064dd592'), + -- OutputLength + (x'3ff3333333333333'), + (x'3ff3ae147ae147ae'), + (x'3ff3be76c8b43958'), + (x'3ff3c083126e978d'), + (x'3ff3c0c1fc8f3238'), + (x'3ff3c0c9539b8887'), + (x'3ff3c0ca2a5b1d5d'), + (x'3ff3c0ca4283de1b'), + (x'3ff3c0ca43db770a'), + (x'3ff3c0ca428abd53'), + (x'3ff3c0ca428c1d2b'), + (x'3ff3c0ca428c51f2'), + (x'3ff3c0ca428c58fc'), + (x'3ff3c0ca428c59dd'), + (x'3ff3c0ca428c59f8'), + (x'3ff3c0ca428c59fb'), + -- 32-bit chunking + (x'40112e0be8047a7d'), + (x'40112e0be815a889'), + (x'40112e0be826d695'), + (x'40112e0be83804a1'), + (x'40112e0be84932ad'), + -- MinMaxShift + (x'0040000000000000'), + (x'007fffffffffffff'), + (x'0290000000000000'), + (x'029fffffffffffff'), + (x'4350000000000000'), + (x'435fffffffffffff'), + (x'1330000000000000'), + (x'133fffffffffffff'), + (x'3a6fa7161a4d6e0c') +) +select float8send(flt) as ibits, + flt, + flt::text::float8 as r_flt, + float8send(flt::text::float8) as obits, + float8send(flt::text::float8) = float8send(flt) as correct + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +STMT: SelectStmt +== 169 +-- clean up, lest opr_sanity complain +drop type xfloat8 cascade +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/foreign_data.metadata.json b/parser/testdata/summary/postgres_regress/foreign_data.metadata.json new file mode 100644 index 0000000..efde331 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/foreign_data.metadata.json @@ -0,0 +1,534 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530" + ] +} diff --git a/parser/testdata/summary/postgres_regress/foreign_data.test b/parser/testdata/summary/postgres_regress/foreign_data.test new file mode 100644 index 0000000..39f95aa --- /dev/null +++ b/parser/testdata/summary/postgres_regress/foreign_data.test @@ -0,0 +1,2652 @@ +== 001 +|-- +-- Test foreign-data wrapper and server management. +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION test_fdw_handler() + RETURNS fdw_handler + AS :'regresslib', 'test_fdw_handler' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 202 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- Clean up in case a prior regression run failed + +-- Suppress NOTICE messages when roles don't exist +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +== 003 +DROP ROLE IF EXISTS regress_foreign_data_user, regress_test_role, regress_test_role2, regress_test_role_super, regress_test_indirect, regress_unprivileged_role +-- +STMT: DropRoleStmt +== 004 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 005 +CREATE ROLE regress_foreign_data_user LOGIN SUPERUSER +-- +STMT: CreateRoleStmt +== 006 +SET SESSION AUTHORIZATION 'regress_foreign_data_user' +-- +STMT: VariableSetStmt +== 007 +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +== 008 +CREATE ROLE regress_test_role2 +-- +STMT: CreateRoleStmt +== 009 +CREATE ROLE regress_test_role_super SUPERUSER +-- +STMT: CreateRoleStmt +== 010 +CREATE ROLE regress_test_indirect +-- +STMT: CreateRoleStmt +== 011 +CREATE ROLE regress_unprivileged_role +-- +STMT: CreateRoleStmt +== 012 +CREATE FOREIGN DATA WRAPPER dummy +-- +STMT: CreateFdwStmt +== 013 +COMMENT ON FOREIGN DATA WRAPPER dummy IS 'useless' +-- +STMT: CommentStmt +== 014 +CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator +-- +STMT: CreateFdwStmt +== 015 +-- At this point we should have 2 built-in wrappers and no servers. +SELECT fdwname, fdwhandler::regproc, fdwvalidator::regproc, fdwoptions FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3 +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +STMT: SelectStmt +== 016 +SELECT srvname, srvoptions FROM pg_foreign_server +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +STMT: SelectStmt +== 017 +SELECT * FROM pg_user_mapping +-- +TABLE: name="pg_user_mapping" schema="" table="pg_user_mapping" ctx=Select +STMT: SelectStmt +== 018 +-- CREATE FOREIGN DATA WRAPPER +CREATE FOREIGN DATA WRAPPER foo VALIDATOR bar +-- +STMT: CreateFdwStmt +== 019 +-- ERROR +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +== 020 +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +== 021 +-- duplicate +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +== 022 +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1') +-- +STMT: CreateFdwStmt +== 023 +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +== 024 +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', testing '2') +-- +STMT: CreateFdwStmt +== 025 +-- ERROR +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', another '2') +-- +STMT: CreateFdwStmt +== 026 +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +== 027 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 028 +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +== 029 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 030 +CREATE FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator +-- +STMT: CreateFdwStmt +== 031 +-- HANDLER related checks +CREATE FUNCTION invalid_fdw_handler() RETURNS int LANGUAGE SQL AS 'SELECT 1;' +-- +FUNCTION: name="invalid_fdw_handler" function="invalid_fdw_handler" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER invalid_fdw_handler +-- +STMT: CreateFdwStmt +== 033 +-- ERROR +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER invalid_fdw_handler +-- +STMT: CreateFdwStmt +== 034 +-- ERROR +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler +-- +STMT: CreateFdwStmt +== 035 +DROP FOREIGN DATA WRAPPER test_fdw +-- +STMT: DropStmt +== 036 +-- ALTER FOREIGN DATA WRAPPER +ALTER FOREIGN DATA WRAPPER foo OPTIONS (nonexistent 'fdw') +-- +STMT: AlterFdwStmt +== 037 +-- ERROR + +ALTER FOREIGN DATA WRAPPER foo +-- +ERROR: syntax error at end of input +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo VALIDATOR bar +-- +STMT: AlterFdwStmt +== 039 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo NO VALIDATOR +-- +STMT: AlterFdwStmt +== 040 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2') +-- +STMT: AlterFdwStmt +== 041 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (SET c '4') +-- +STMT: AlterFdwStmt +== 042 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP c) +-- +STMT: AlterFdwStmt +== 043 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD x '1', DROP x) +-- +STMT: AlterFdwStmt +== 044 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP a, SET b '3', ADD c '4') +-- +STMT: AlterFdwStmt +== 045 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '2') +-- +STMT: AlterFdwStmt +== 046 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (b '4') +-- +STMT: AlterFdwStmt +== 047 +-- ERROR + +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 048 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5') +-- +STMT: AlterFdwStmt +== 049 +-- ERROR +SET ROLE regress_test_role_super +-- +STMT: VariableSetStmt +== 050 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5') +-- +STMT: AlterFdwStmt +== 051 +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 052 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role_super +-- +STMT: AlterOwnerStmt +== 053 +ALTER ROLE regress_test_role_super NOSUPERUSER +-- +STMT: AlterRoleStmt +== 054 +SET ROLE regress_test_role_super +-- +STMT: VariableSetStmt +== 055 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD e '6') +-- +STMT: AlterFdwStmt +== 056 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 057 +ALTER FOREIGN DATA WRAPPER foo RENAME TO foo1 +-- +STMT: RenameStmt +== 058 +ALTER FOREIGN DATA WRAPPER foo1 RENAME TO foo +-- +STMT: RenameStmt +== 059 +-- HANDLER related checks +ALTER FOREIGN DATA WRAPPER foo HANDLER invalid_fdw_handler +-- +STMT: AlterFdwStmt +== 060 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler HANDLER anything +-- +STMT: AlterFdwStmt +== 061 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler +-- +STMT: AlterFdwStmt +== 062 +DROP FUNCTION invalid_fdw_handler() +-- +FUNCTION: name="invalid_fdw_handler" function="invalid_fdw_handler" schema="" ctx=DDL +STMT: DropStmt +== 063 +-- DROP FOREIGN DATA WRAPPER +DROP FOREIGN DATA WRAPPER nonexistent +-- +STMT: DropStmt +== 064 +-- ERROR +DROP FOREIGN DATA WRAPPER IF EXISTS nonexistent +-- +STMT: DropStmt +== 065 +DROP ROLE regress_test_role_super +-- +STMT: DropRoleStmt +== 066 +-- ERROR +SET ROLE regress_test_role_super +-- +STMT: VariableSetStmt +== 067 +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +== 068 +RESET ROLE +-- +STMT: VariableSetStmt +== 069 +DROP ROLE regress_test_role_super +-- +STMT: DropRoleStmt +== 070 +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +== 071 +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 072 +COMMENT ON SERVER s1 IS 'foreign server' +-- +STMT: CommentStmt +== 073 +CREATE USER MAPPING FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +== 074 +CREATE USER MAPPING FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +== 075 +-- ERROR +CREATE USER MAPPING IF NOT EXISTS FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +== 076 +-- NOTICE +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +== 077 +-- ERROR +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 078 +DROP FOREIGN DATA WRAPPER foo CASCADE +-- +STMT: DropStmt +== 079 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 080 +DROP FOREIGN DATA WRAPPER foo CASCADE +-- +STMT: DropStmt +== 081 +-- exercise CREATE SERVER +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 082 +-- ERROR +CREATE FOREIGN DATA WRAPPER foo OPTIONS ("test wrapper" 'true') +-- +STMT: CreateFdwStmt +== 083 +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 084 +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 085 +-- ERROR +CREATE SERVER IF NOT EXISTS s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 086 +-- No ERROR, just NOTICE +CREATE SERVER s2 FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +== 087 +CREATE SERVER s3 TYPE 'oracle' FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 088 +CREATE SERVER s4 TYPE 'oracle' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +== 089 +CREATE SERVER s5 VERSION '15.0' FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 090 +CREATE SERVER s6 VERSION '16.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +== 091 +CREATE SERVER s7 TYPE 'oracle' VERSION '17.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +== 092 +CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (foo '1') +-- +STMT: CreateForeignServerStmt +== 093 +-- ERROR +CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (host 'localhost', dbname 's8db') +-- +STMT: CreateForeignServerStmt +== 094 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 095 +CREATE SERVER t1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 096 +-- ERROR: no usage on FDW +RESET ROLE +-- +STMT: VariableSetStmt +== 097 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +== 098 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 099 +CREATE SERVER t1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 100 +RESET ROLE +-- +STMT: VariableSetStmt +== 101 +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_test_role +-- +STMT: GrantStmt +== 102 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_indirect +-- +STMT: GrantStmt +== 103 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 104 +CREATE SERVER t2 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 105 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 106 +GRANT regress_test_indirect TO regress_test_role +-- +STMT: GrantRoleStmt +== 107 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 108 +CREATE SERVER t2 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 109 +RESET ROLE +-- +STMT: VariableSetStmt +== 110 +REVOKE regress_test_indirect FROM regress_test_role +-- +STMT: GrantRoleStmt +== 111 +-- ALTER SERVER +ALTER SERVER s0 +-- +ERROR: syntax error at end of input +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 112 +-- ERROR +ALTER SERVER s0 OPTIONS (a '1') +-- +STMT: AlterForeignServerStmt +== 113 +-- ERROR +ALTER SERVER s1 VERSION '1.0' OPTIONS (servername 's1') +-- +STMT: AlterForeignServerStmt +== 114 +ALTER SERVER s2 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +== 115 +ALTER SERVER s3 OPTIONS ("tns name" 'orcl', port '1521') +-- +STMT: AlterForeignServerStmt +== 116 +GRANT USAGE ON FOREIGN SERVER s1 TO regress_test_role +-- +STMT: GrantStmt +== 117 +GRANT USAGE ON FOREIGN SERVER s6 TO regress_test_role2 WITH GRANT OPTION +-- +STMT: GrantStmt +== 118 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 119 +ALTER SERVER s1 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +== 120 +-- ERROR +ALTER SERVER s1 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 121 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 122 +ALTER SERVER s1 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 123 +GRANT regress_test_role2 TO regress_test_role +-- +STMT: GrantRoleStmt +== 124 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 125 +ALTER SERVER s1 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +== 126 +ALTER SERVER s1 OWNER TO regress_test_role2 +-- +STMT: AlterOwnerStmt +== 127 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 128 +ALTER SERVER s8 OPTIONS (foo '1') +-- +STMT: AlterForeignServerStmt +== 129 +-- ERROR option validation +ALTER SERVER s8 OPTIONS (connect_timeout '30', SET dbname 'db1', DROP host) +-- +STMT: AlterForeignServerStmt +== 130 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 131 +ALTER SERVER s1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +== 132 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 133 +GRANT regress_test_indirect TO regress_test_role +-- +STMT: GrantRoleStmt +== 134 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 135 +ALTER SERVER s1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +== 136 +RESET ROLE +-- +STMT: VariableSetStmt +== 137 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_indirect +-- +STMT: GrantStmt +== 138 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 139 +ALTER SERVER s1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +== 140 +RESET ROLE +-- +STMT: VariableSetStmt +== 141 +DROP ROLE regress_test_indirect +-- +STMT: DropRoleStmt +== 142 +-- ERROR + +ALTER SERVER s8 RENAME to s8new +-- +STMT: RenameStmt +== 143 +ALTER SERVER s8new RENAME to s8 +-- +STMT: RenameStmt +== 144 +-- DROP SERVER +DROP SERVER nonexistent +-- +STMT: DropStmt +== 145 +-- ERROR +DROP SERVER IF EXISTS nonexistent +-- +STMT: DropStmt +== 146 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 147 +DROP SERVER s2 +-- +STMT: DropStmt +== 148 +-- ERROR +DROP SERVER s1 +-- +STMT: DropStmt +== 149 +RESET ROLE +-- +STMT: VariableSetStmt +== 150 +ALTER SERVER s2 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 151 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 152 +DROP SERVER s2 +-- +STMT: DropStmt +== 153 +RESET ROLE +-- +STMT: VariableSetStmt +== 154 +CREATE USER MAPPING FOR current_user SERVER s3 +-- +STMT: CreateUserMappingStmt +== 155 +DROP SERVER s3 +-- +STMT: DropStmt +== 156 +-- ERROR +DROP SERVER s3 CASCADE +-- +STMT: DropStmt +== 157 +-- CREATE USER MAPPING +CREATE USER MAPPING FOR regress_test_missing_role SERVER s1 +-- +STMT: CreateUserMappingStmt +== 158 +-- ERROR +CREATE USER MAPPING FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +== 159 +-- ERROR +CREATE USER MAPPING FOR current_user SERVER s4 +-- +STMT: CreateUserMappingStmt +== 160 +CREATE USER MAPPING FOR user SERVER s4 +-- +STMT: CreateUserMappingStmt +== 161 +-- ERROR duplicate +CREATE USER MAPPING FOR public SERVER s4 OPTIONS ("this mapping" 'is public') +-- +STMT: CreateUserMappingStmt +== 162 +CREATE USER MAPPING FOR user SERVER s8 OPTIONS (username 'test', password 'secret') +-- +STMT: CreateUserMappingStmt +== 163 +-- ERROR +CREATE USER MAPPING FOR user SERVER s8 OPTIONS (user 'test', password 'secret') +-- +STMT: CreateUserMappingStmt +== 164 +ALTER SERVER s5 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +== 165 +ALTER SERVER s6 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +== 166 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 167 +CREATE USER MAPPING FOR current_user SERVER s5 +-- +STMT: CreateUserMappingStmt +== 168 +CREATE USER MAPPING FOR current_user SERVER s6 OPTIONS (username 'test') +-- +STMT: CreateUserMappingStmt +== 169 +CREATE USER MAPPING FOR current_user SERVER s7 +-- +STMT: CreateUserMappingStmt +== 170 +-- ERROR +CREATE USER MAPPING FOR public SERVER s8 +-- +STMT: CreateUserMappingStmt +== 171 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 172 +ALTER SERVER t1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +== 173 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 174 +CREATE USER MAPPING FOR current_user SERVER t1 OPTIONS (username 'bob', password 'boo') +-- +STMT: CreateUserMappingStmt +== 175 +CREATE USER MAPPING FOR public SERVER t1 +-- +STMT: CreateUserMappingStmt +== 176 +RESET ROLE +-- +STMT: VariableSetStmt +== 177 +-- ALTER USER MAPPING +ALTER USER MAPPING FOR regress_test_missing_role SERVER s4 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +== 178 +-- ERROR +ALTER USER MAPPING FOR user SERVER ss4 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +== 179 +-- ERROR +ALTER USER MAPPING FOR public SERVER s5 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +== 180 +-- ERROR +ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (username 'test') +-- +STMT: AlterUserMappingStmt +== 181 +-- ERROR +ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (DROP user, SET password 'public') +-- +STMT: AlterUserMappingStmt +== 182 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 183 +ALTER USER MAPPING FOR current_user SERVER s5 OPTIONS (ADD modified '1') +-- +STMT: AlterUserMappingStmt +== 184 +ALTER USER MAPPING FOR public SERVER s4 OPTIONS (ADD modified '1') +-- +STMT: AlterUserMappingStmt +== 185 +-- ERROR +ALTER USER MAPPING FOR public SERVER t1 OPTIONS (ADD modified '1') +-- +STMT: AlterUserMappingStmt +== 186 +RESET ROLE +-- +STMT: VariableSetStmt +== 187 +-- DROP USER MAPPING +DROP USER MAPPING FOR regress_test_missing_role SERVER s4 +-- +STMT: DropUserMappingStmt +== 188 +-- ERROR +DROP USER MAPPING FOR user SERVER ss4 +-- +STMT: DropUserMappingStmt +== 189 +DROP USER MAPPING FOR public SERVER s7 +-- +STMT: DropUserMappingStmt +== 190 +-- ERROR +DROP USER MAPPING IF EXISTS FOR regress_test_missing_role SERVER s4 +-- +STMT: DropUserMappingStmt +== 191 +DROP USER MAPPING IF EXISTS FOR user SERVER ss4 +-- +STMT: DropUserMappingStmt +== 192 +DROP USER MAPPING IF EXISTS FOR public SERVER s7 +-- +STMT: DropUserMappingStmt +== 193 +CREATE USER MAPPING FOR public SERVER s8 +-- +STMT: CreateUserMappingStmt +== 194 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 195 +DROP USER MAPPING FOR public SERVER s8 +-- +STMT: DropUserMappingStmt +== 196 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 197 +DROP SERVER s7 +-- +STMT: DropStmt +== 198 +-- CREATE FOREIGN TABLE +CREATE SCHEMA foreign_schema +-- +STMT: CreateSchemaStmt +== 199 +CREATE SERVER s0 FOREIGN DATA WRAPPER dummy +-- +STMT: CreateForeignServerStmt +== 200 +CREATE FOREIGN TABLE ft1 () +-- +ERROR: syntax error at end of input +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 201 +-- ERROR +CREATE FOREIGN TABLE ft1 () SERVER no_server +-- +STMT: CreateForeignTableStmt +== 202 +-- ERROR +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') PRIMARY KEY, + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 203 +-- ERROR +CREATE TABLE ref_table (id integer PRIMARY KEY) +-- +TABLE: name="ref_table" schema="" table="ref_table" ctx=DDL +STMT: CreateStmt +== 204 +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') REFERENCES ref_table (id), + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 205 +-- ERROR +DROP TABLE ref_table +-- +TABLE: name="ref_table" schema="" table="ref_table" ctx=DDL +STMT: DropStmt +== 206 +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') NOT NULL, + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date, + UNIQUE (c3) +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 207 +-- ERROR +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') NOT NULL, + c2 text OPTIONS (param2 'val2', param3 'val3') CHECK (c2 <> ''), + c3 date, + CHECK (c3 BETWEEN '1994-01-01'::date AND '1994-01-31'::date) +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 208 +COMMENT ON FOREIGN TABLE ft1 IS 'ft1' +-- +STMT: CommentStmt +== 209 +COMMENT ON COLUMN ft1.c1 IS 'ft1.c1' +-- +STMT: CommentStmt +== 210 +CREATE INDEX id_ft1_c2 ON ft1 (c2) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: IndexStmt +== 211 +-- ERROR +SELECT * FROM ft1 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=Select +STMT: SelectStmt +== 212 +-- ERROR +EXPLAIN SELECT * FROM ft1 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 213 +-- ERROR + +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: CreateStmt +== 214 +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 215 +CREATE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +== 216 +-- skips partition +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +== 217 +-- ERROR +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +== 218 +-- ERROR +DROP TABLE lt1 +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: DropStmt +== 219 +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: CreateStmt +== 220 +CREATE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +== 221 +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 222 +CREATE FOREIGN TABLE ft_part2 (a INT) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 223 +ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +== 224 +DROP FOREIGN TABLE ft_part1, ft_part2 +-- +STMT: DropStmt +== 225 +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +== 226 +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +== 227 +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 228 +-- ERROR +CREATE FOREIGN TABLE ft_part2 (a INT NOT NULL) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 229 +ALTER TABLE lt1 ATTACH PARTITION ft_part2 + FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +== 230 +-- ERROR +DROP TABLE lt1 +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: DropStmt +== 231 +DROP FOREIGN TABLE ft_part2 +-- +STMT: DropStmt +== 232 +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: CreateStmt +== 233 +CREATE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +== 234 +CREATE TABLE lt1_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) + PARTITION BY RANGE (a) +-- +TABLE: name="lt1_part1" schema="" table="lt1_part1" ctx=DDL +STMT: CreateStmt +== 235 +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 236 +CREATE FOREIGN TABLE ft_part_1_2 (a INT) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 237 +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="lt1_part1" schema="" table="lt1_part1" ctx=DDL +STMT: AlterTableStmt +== 238 +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +== 239 +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +== 240 +DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2 +-- +STMT: DropStmt +== 241 +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +== 242 +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +== 243 +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 244 +CREATE FOREIGN TABLE ft_part_1_2 (a INT NOT NULL) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 245 +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="lt1_part1" schema="" table="lt1_part1" ctx=DDL +STMT: AlterTableStmt +== 246 +DROP TABLE lt1 +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: DropStmt +== 247 +DROP FOREIGN TABLE ft_part_1_2 +-- +STMT: DropStmt +== 248 +-- ALTER FOREIGN TABLE +COMMENT ON FOREIGN TABLE ft1 IS 'foreign table' +-- +STMT: CommentStmt +== 249 +COMMENT ON FOREIGN TABLE ft1 IS NULL +-- +STMT: CommentStmt +== 250 +COMMENT ON COLUMN ft1.c1 IS 'foreign column' +-- +STMT: CommentStmt +== 251 +COMMENT ON COLUMN ft1.c1 IS NULL +-- +STMT: CommentStmt +== 252 +ALTER FOREIGN TABLE ft1 ADD COLUMN c4 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 253 +ALTER FOREIGN TABLE ft1 ADD COLUMN c5 integer DEFAULT 0 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 254 +ALTER FOREIGN TABLE ft1 ADD COLUMN c6 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 255 +ALTER FOREIGN TABLE ft1 ADD COLUMN c7 integer NOT NULL +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 256 +ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 257 +ALTER FOREIGN TABLE ft1 ADD COLUMN c9 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 258 +ALTER FOREIGN TABLE ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 259 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 260 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 261 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c6 SET NOT NULL +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 262 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 DROP NOT NULL +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 263 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) USING '0' +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 264 +-- ERROR +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 265 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET DATA TYPE text +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 266 +ALTER FOREIGN TABLE ft1 ALTER COLUMN xmin OPTIONS (ADD p1 'v1') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 267 +-- ERROR +ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2'), + ALTER COLUMN c8 OPTIONS (ADD p1 'v1', ADD p2 'v2') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 268 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 269 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET STATISTICS 10000 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 270 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET (n_distinct = 100) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 271 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STATISTICS -1 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 272 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STORAGE PLAIN +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 273 +-- can't change the column type if it's used elsewhere +CREATE TABLE use_ft1_column_type (x ft1) +-- +TABLE: name="use_ft1_column_type" schema="" table="use_ft1_column_type" ctx=DDL +STMT: CreateStmt +== 274 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET DATA TYPE integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 275 +-- ERROR +DROP TABLE use_ft1_column_type +-- +TABLE: name="use_ft1_column_type" schema="" table="use_ft1_column_type" ctx=DDL +STMT: DropStmt +== 276 +ALTER FOREIGN TABLE ft1 ADD PRIMARY KEY (c7) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 277 +-- ERROR +ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c9_check CHECK (c9 < 0) NOT VALID +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 278 +ALTER FOREIGN TABLE ft1 ALTER CONSTRAINT ft1_c9_check DEFERRABLE +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 279 +-- ERROR +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c9_check +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 280 +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 281 +-- ERROR +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 282 +ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 283 +ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 284 +ALTER FOREIGN TABLE ft1 DROP COLUMN no_column +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 285 +-- ERROR +ALTER FOREIGN TABLE ft1 DROP COLUMN IF EXISTS no_column +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 286 +ALTER FOREIGN TABLE ft1 DROP COLUMN c9 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 287 +ALTER FOREIGN TABLE ft1 ADD COLUMN c11 serial +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 288 +ALTER FOREIGN TABLE ft1 SET SCHEMA foreign_schema +-- +STMT: AlterObjectSchemaStmt +== 289 +ALTER FOREIGN TABLE ft1 SET TABLESPACE ts +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +== 290 +-- ERROR +ALTER SEQUENCE foreign_schema.ft1_c11_seq SET SCHEMA public +-- +STMT: AlterObjectSchemaStmt +== 291 +-- ERROR +ALTER FOREIGN TABLE foreign_schema.ft1 RENAME c1 TO foreign_column_1 +-- +STMT: RenameStmt +== 292 +ALTER FOREIGN TABLE foreign_schema.ft1 RENAME TO foreign_table_1 +-- +STMT: RenameStmt +== 293 +-- alter noexisting table +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c4 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 294 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c6 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 295 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c7 integer NOT NULL +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 296 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c8 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 297 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c9 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 298 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1') +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 299 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c6 SET NOT NULL +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 300 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 DROP NOT NULL +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 301 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 302 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 SET DATA TYPE text +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 303 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2'), + ALTER COLUMN c8 OPTIONS (ADD p1 'v1', ADD p2 'v2') +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 304 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1) +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 305 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT IF EXISTS no_const +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 306 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT ft1_c1_check +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 307 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OWNER TO regress_test_role +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 308 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@') +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 309 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP COLUMN IF EXISTS no_column +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 310 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP COLUMN c9 +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +== 311 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 SET SCHEMA foreign_schema +-- +STMT: AlterObjectSchemaStmt +== 312 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME c1 TO foreign_column_1 +-- +STMT: RenameStmt +== 313 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME TO foreign_table_1 +-- +STMT: RenameStmt +== 314 +-- Information schema + +SELECT * FROM information_schema.foreign_data_wrappers ORDER BY 1, 2 +-- +TABLE: name="information_schema.foreign_data_wrappers" schema="information_schema" table="foreign_data_wrappers" ctx=Select +STMT: SelectStmt +== 315 +SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_data_wrapper_options" schema="information_schema" table="foreign_data_wrapper_options" ctx=Select +STMT: SelectStmt +== 316 +SELECT * FROM information_schema.foreign_servers ORDER BY 1, 2 +-- +TABLE: name="information_schema.foreign_servers" schema="information_schema" table="foreign_servers" ctx=Select +STMT: SelectStmt +== 317 +SELECT * FROM information_schema.foreign_server_options ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_server_options" schema="information_schema" table="foreign_server_options" ctx=Select +STMT: SelectStmt +== 318 +SELECT * FROM information_schema.user_mappings ORDER BY lower(authorization_identifier), 2, 3 +-- +TABLE: name="information_schema.user_mappings" schema="information_schema" table="user_mappings" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 319 +SELECT * FROM information_schema.user_mapping_options ORDER BY lower(authorization_identifier), 2, 3, 4 +-- +TABLE: name="information_schema.user_mapping_options" schema="information_schema" table="user_mapping_options" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 320 +SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.usage_privileges" schema="information_schema" table="usage_privileges" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +== 321 +SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.role_usage_grants" schema="information_schema" table="role_usage_grants" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +== 322 +SELECT * FROM information_schema.foreign_tables ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_tables" schema="information_schema" table="foreign_tables" ctx=Select +STMT: SelectStmt +== 323 +SELECT * FROM information_schema.foreign_table_options ORDER BY 1, 2, 3, 4 +-- +TABLE: name="information_schema.foreign_table_options" schema="information_schema" table="foreign_table_options" ctx=Select +STMT: SelectStmt +== 324 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 325 +SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4 +-- +TABLE: name="information_schema.user_mapping_options" schema="information_schema" table="user_mapping_options" ctx=Select +STMT: SelectStmt +== 326 +SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.usage_privileges" schema="information_schema" table="usage_privileges" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +== 327 +SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.role_usage_grants" schema="information_schema" table="role_usage_grants" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +== 328 +DROP USER MAPPING FOR current_user SERVER t1 +-- +STMT: DropUserMappingStmt +== 329 +SET ROLE regress_test_role2 +-- +STMT: VariableSetStmt +== 330 +SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4 +-- +TABLE: name="information_schema.user_mapping_options" schema="information_schema" table="user_mapping_options" ctx=Select +STMT: SelectStmt +== 331 +RESET ROLE +-- +STMT: VariableSetStmt +== 332 +-- has_foreign_data_wrapper_privilege +SELECT has_foreign_data_wrapper_privilege('regress_test_role', + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE') +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +== 333 +SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE') +-- +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +STMT: SelectStmt +== 334 +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +== 335 +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE') +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +== 336 +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), 'foo', 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 337 +SELECT has_foreign_data_wrapper_privilege('foo', 'USAGE') +-- +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +STMT: SelectStmt +== 338 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +== 339 +SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE') +-- +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +STMT: SelectStmt +== 340 +-- has_server_privilege +SELECT has_server_privilege('regress_test_role', + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE') +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +== 341 +SELECT has_server_privilege('regress_test_role', 's8', 'USAGE') +-- +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +STMT: SelectStmt +== 342 +SELECT has_server_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +== 343 +SELECT has_server_privilege( + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE') +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +== 344 +SELECT has_server_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), 's8', 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 345 +SELECT has_server_privilege('s8', 'USAGE') +-- +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +STMT: SelectStmt +== 346 +GRANT USAGE ON FOREIGN SERVER s8 TO regress_test_role +-- +STMT: GrantStmt +== 347 +SELECT has_server_privilege('regress_test_role', 's8', 'USAGE') +-- +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +STMT: SelectStmt +== 348 +REVOKE USAGE ON FOREIGN SERVER s8 FROM regress_test_role +-- +STMT: GrantStmt +== 349 +GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role +-- +STMT: GrantStmt +== 350 +DROP USER MAPPING FOR public SERVER s4 +-- +STMT: DropUserMappingStmt +== 351 +ALTER SERVER s6 OPTIONS (DROP host, DROP dbname) +-- +STMT: AlterForeignServerStmt +== 352 +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username) +-- +STMT: AlterUserMappingStmt +== 353 +ALTER FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator +-- +STMT: AlterFdwStmt +== 354 +-- Privileges +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +== 355 +CREATE FOREIGN DATA WRAPPER foobar +-- +STMT: CreateFdwStmt +== 356 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true') +-- +STMT: AlterFdwStmt +== 357 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_unprivileged_role +-- +STMT: AlterOwnerStmt +== 358 +-- ERROR +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +== 359 +-- ERROR +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +== 360 +-- ERROR +CREATE SERVER s9 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 361 +-- ERROR +ALTER SERVER s4 VERSION '0.5' +-- +STMT: AlterForeignServerStmt +== 362 +-- ERROR +ALTER SERVER s4 OWNER TO regress_unprivileged_role +-- +STMT: AlterOwnerStmt +== 363 +-- ERROR +DROP SERVER s4 +-- +STMT: DropStmt +== 364 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role +-- +STMT: GrantStmt +== 365 +-- ERROR +CREATE USER MAPPING FOR public SERVER s4 +-- +STMT: CreateUserMappingStmt +== 366 +-- ERROR +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +== 367 +-- ERROR +DROP USER MAPPING FOR regress_test_role SERVER s6 +-- +STMT: DropUserMappingStmt +== 368 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 369 +GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_unprivileged_role +-- +STMT: GrantStmt +== 370 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_unprivileged_role WITH GRANT OPTION +-- +STMT: GrantStmt +== 371 +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +== 372 +CREATE FOREIGN DATA WRAPPER foobar +-- +STMT: CreateFdwStmt +== 373 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true') +-- +STMT: AlterFdwStmt +== 374 +-- ERROR +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +== 375 +-- ERROR +GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_test_role +-- +STMT: GrantStmt +== 376 +-- WARNING +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +== 377 +CREATE SERVER s9 FOREIGN DATA WRAPPER postgresql +-- +STMT: CreateForeignServerStmt +== 378 +ALTER SERVER s6 VERSION '0.5' +-- +STMT: AlterForeignServerStmt +== 379 +-- ERROR +DROP SERVER s6 +-- +STMT: DropStmt +== 380 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s6 TO regress_test_role +-- +STMT: GrantStmt +== 381 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role +-- +STMT: GrantStmt +== 382 +CREATE USER MAPPING FOR public SERVER s6 +-- +STMT: CreateUserMappingStmt +== 383 +-- ERROR +CREATE USER MAPPING FOR public SERVER s9 +-- +STMT: CreateUserMappingStmt +== 384 +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +== 385 +-- ERROR +DROP USER MAPPING FOR regress_test_role SERVER s6 +-- +STMT: DropUserMappingStmt +== 386 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +== 387 +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role +-- +STMT: GrantStmt +== 388 +-- ERROR +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role CASCADE +-- +STMT: GrantStmt +== 389 +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +== 390 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +== 391 +-- ERROR +CREATE SERVER s10 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 392 +-- ERROR +ALTER SERVER s9 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +== 393 +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role +-- +STMT: GrantStmt +== 394 +CREATE USER MAPPING FOR current_user SERVER s9 +-- +STMT: CreateUserMappingStmt +== 395 +DROP SERVER s9 CASCADE +-- +STMT: DropStmt +== 396 +RESET ROLE +-- +STMT: VariableSetStmt +== 397 +CREATE SERVER s9 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 398 +GRANT USAGE ON FOREIGN SERVER s9 TO regress_unprivileged_role +-- +STMT: GrantStmt +== 399 +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +== 400 +ALTER SERVER s9 VERSION '1.2' +-- +STMT: AlterForeignServerStmt +== 401 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role +-- +STMT: GrantStmt +== 402 +-- WARNING +CREATE USER MAPPING FOR current_user SERVER s9 +-- +STMT: CreateUserMappingStmt +== 403 +DROP SERVER s9 CASCADE +-- +STMT: DropStmt +== 404 +-- ERROR + +-- Check visibility of user mapping data +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +== 405 +CREATE SERVER s10 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +== 406 +CREATE USER MAPPING FOR public SERVER s10 OPTIONS (user 'secret') +-- +STMT: CreateUserMappingStmt +== 407 +CREATE USER MAPPING FOR regress_unprivileged_role SERVER s10 OPTIONS (user 'secret') +-- +STMT: CreateUserMappingStmt +== 408 +-- owner of server can see some option fields +RESET ROLE +-- +STMT: VariableSetStmt +== 409 +-- superuser can see all option fields +-- unprivileged user cannot see any option field +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +== 410 +RESET ROLE +-- +STMT: VariableSetStmt +== 411 +DROP SERVER s10 CASCADE +-- +STMT: DropStmt +== 412 +-- Triggers +CREATE FUNCTION dummy_trigger() RETURNS TRIGGER AS $$ + BEGIN + RETURN NULL; + END +$$ language plpgsql +-- +FUNCTION: name="dummy_trigger" function="dummy_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 413 +CREATE TRIGGER trigtest_before_stmt BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +== 414 +CREATE TRIGGER trigtest_after_stmt AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +== 415 +CREATE TRIGGER trigtest_after_stmt_tt AFTER INSERT OR UPDATE OR DELETE -- ERROR +ON foreign_schema.foreign_table_1 +REFERENCING NEW TABLE AS new_table +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +== 416 +CREATE TRIGGER trigtest_before_row BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +== 417 +CREATE TRIGGER trigtest_after_row AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +== 418 +CREATE CONSTRAINT TRIGGER trigtest_constraint AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +== 419 +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + DISABLE TRIGGER trigtest_before_stmt +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: AlterTableStmt +== 420 +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + ENABLE TRIGGER trigtest_before_stmt +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: AlterTableStmt +== 421 +DROP TRIGGER trigtest_before_stmt ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +== 422 +DROP TRIGGER trigtest_before_row ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +== 423 +DROP TRIGGER trigtest_after_stmt ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +== 424 +DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +== 425 +DROP FUNCTION dummy_trigger() +-- +FUNCTION: name="dummy_trigger" function="dummy_trigger" schema="" ctx=DDL +STMT: DropStmt +== 426 +-- Table inheritance +CREATE TABLE fd_pt1 ( + c1 integer NOT NULL, + c2 text, + c3 date +) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: CreateStmt +== 427 +CREATE FOREIGN TABLE ft2 () INHERITS (fd_pt1) + SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 428 +DROP FOREIGN TABLE ft2 +-- +STMT: DropStmt +== 429 +CREATE FOREIGN TABLE ft2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 430 +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1 +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +== 431 +CREATE TABLE ct3() INHERITS(ft2) +-- +TABLE: name="ct3" schema="" table="ct3" ctx=DDL +STMT: CreateStmt +== 432 +CREATE FOREIGN TABLE ft3 ( + c1 integer NOT NULL, + c2 text, + c3 date +) INHERITS(ft2) + SERVER s0 +-- +STMT: CreateForeignTableStmt +== 433 +-- add attributes recursively +ALTER TABLE fd_pt1 ADD COLUMN c4 integer +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 434 +ALTER TABLE fd_pt1 ADD COLUMN c5 integer DEFAULT 0 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 435 +ALTER TABLE fd_pt1 ADD COLUMN c6 integer +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 436 +ALTER TABLE fd_pt1 ADD COLUMN c7 integer NOT NULL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 437 +ALTER TABLE fd_pt1 ADD COLUMN c8 integer +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 438 +-- alter attributes recursively +ALTER TABLE fd_pt1 ALTER COLUMN c4 SET DEFAULT 0 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 439 +ALTER TABLE fd_pt1 ALTER COLUMN c5 DROP DEFAULT +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 440 +ALTER TABLE fd_pt1 ALTER COLUMN c6 SET NOT NULL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 441 +ALTER TABLE fd_pt1 ALTER COLUMN c7 DROP NOT NULL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 442 +ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) USING '0' +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 443 +-- ERROR +ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 444 +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET DATA TYPE text +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 445 +ALTER TABLE fd_pt1 ALTER COLUMN c1 SET STATISTICS 10000 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 446 +ALTER TABLE fd_pt1 ALTER COLUMN c1 SET (n_distinct = 100) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 447 +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STATISTICS -1 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 448 +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STORAGE EXTERNAL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 449 +-- drop attributes recursively +ALTER TABLE fd_pt1 DROP COLUMN c4 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 450 +ALTER TABLE fd_pt1 DROP COLUMN c5 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 451 +ALTER TABLE fd_pt1 DROP COLUMN c6 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 452 +ALTER TABLE fd_pt1 DROP COLUMN c7 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 453 +ALTER TABLE fd_pt1 DROP COLUMN c8 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 454 +-- add constraints recursively +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk1 CHECK (c1 > 0) NO INHERIT +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 455 +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '') +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 456 +-- connoinherit should be true for NO INHERIT constraint +SELECT relname, conname, contype, conislocal, coninhcount, connoinherit + FROM pg_class AS pc JOIN pg_constraint AS pgc ON (conrelid = pc.oid) + WHERE pc.relname = 'fd_pt1' + ORDER BY 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 457 +-- child does not inherit NO INHERIT constraints +DROP FOREIGN TABLE ft2 +-- +STMT: DropStmt +== 458 +-- ERROR +DROP FOREIGN TABLE ft2 CASCADE +-- +STMT: DropStmt +== 459 +CREATE FOREIGN TABLE ft2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 460 +-- child must have parent's INHERIT constraints +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1 +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +== 461 +-- ERROR +ALTER FOREIGN TABLE ft2 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '') +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +== 462 +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1 +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +== 463 +-- child does not inherit NO INHERIT constraints + +-- drop constraints recursively +ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk1 CASCADE +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 464 +ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk2 CASCADE +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 465 +-- NOT VALID case +INSERT INTO fd_pt1 VALUES (1, 'fd_pt1'::text, '1994-01-01'::date) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 466 +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk3 CHECK (c2 <> '') NOT VALID +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 467 +-- VALIDATE CONSTRAINT need do nothing on foreign tables +ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +== 468 +-- changes name of an attribute recursively +ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1 +-- +STMT: RenameStmt +== 469 +ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2 +-- +STMT: RenameStmt +== 470 +ALTER TABLE fd_pt1 RENAME COLUMN c3 TO f3 +-- +STMT: RenameStmt +== 471 +-- changes name of a constraint recursively +ALTER TABLE fd_pt1 RENAME CONSTRAINT fd_pt1chk3 TO f2_check +-- +STMT: RenameStmt +== 472 +DROP TABLE fd_pt1 CASCADE +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: DropStmt +== 473 +-- IMPORT FOREIGN SCHEMA +IMPORT FOREIGN SCHEMA s1 FROM SERVER s9 INTO public +-- +STMT: ImportForeignSchemaStmt +== 474 +-- ERROR +IMPORT FOREIGN SCHEMA s1 LIMIT TO (t1) FROM SERVER s9 INTO public +-- +STMT: ImportForeignSchemaStmt +== 475 +--ERROR +IMPORT FOREIGN SCHEMA s1 EXCEPT (t1) FROM SERVER s9 INTO public +-- +STMT: ImportForeignSchemaStmt +== 476 +-- ERROR +IMPORT FOREIGN SCHEMA s1 EXCEPT (t1, t2) FROM SERVER s9 INTO public +OPTIONS (option1 'value1', option2 'value2') +-- +STMT: ImportForeignSchemaStmt +== 477 +-- ERROR + +-- DROP FOREIGN TABLE +DROP FOREIGN TABLE no_table +-- +STMT: DropStmt +== 478 +-- ERROR +DROP FOREIGN TABLE IF EXISTS no_table +-- +STMT: DropStmt +== 479 +DROP FOREIGN TABLE foreign_schema.foreign_table_1 +-- +STMT: DropStmt +== 480 +-- REASSIGN OWNED/DROP OWNED of foreign objects +REASSIGN OWNED BY regress_test_role TO regress_test_role2 +-- +STMT: ReassignOwnedStmt +== 481 +DROP OWNED BY regress_test_role2 +-- +STMT: DropOwnedStmt +== 482 +DROP OWNED BY regress_test_role2 CASCADE +-- +STMT: DropOwnedStmt +== 483 +-- Foreign partition DDL stuff +CREATE TABLE fd_pt2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) PARTITION BY LIST (c1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: CreateStmt +== 484 +CREATE FOREIGN TABLE fd_pt2_1 PARTITION OF fd_pt2 FOR VALUES IN (1) + SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 485 +-- partition cannot have additional columns +DROP FOREIGN TABLE fd_pt2_1 +-- +STMT: DropStmt +== 486 +CREATE FOREIGN TABLE fd_pt2_1 ( + c1 integer NOT NULL, + c2 text, + c3 date, + c4 char +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 487 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 488 +-- ERROR + +DROP FOREIGN TABLE fd_pt2_1 +-- +STMT: DropStmt +== 489 +CREATE FOREIGN TABLE fd_pt2_1 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +== 490 +-- no attach partition validation occurs for foreign tables +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 491 +-- cannot add column to a partition +ALTER TABLE fd_pt2_1 ADD c4 char +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +== 492 +-- ok to have a partition's own constraints though +ALTER TABLE fd_pt2_1 ALTER c3 SET NOT NULL +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +== 493 +ALTER TABLE fd_pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> '') +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +== 494 +-- cannot drop inherited NOT NULL constraint from a partition +ALTER TABLE fd_pt2_1 ALTER c1 DROP NOT NULL +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +== 495 +-- partition must have parent's constraints +ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1 +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 496 +ALTER TABLE fd_pt2 ALTER c2 SET NOT NULL +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 497 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 498 +-- ERROR +ALTER FOREIGN TABLE fd_pt2_1 ALTER c2 SET NOT NULL +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +== 499 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 500 +ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1 +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 501 +ALTER TABLE fd_pt2 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 502 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 503 +-- ERROR +ALTER FOREIGN TABLE fd_pt2_1 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0) +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +== 504 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +== 505 +DROP FOREIGN TABLE fd_pt2_1 +-- +STMT: DropStmt +== 506 +DROP TABLE fd_pt2 +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: DropStmt +== 507 +-- foreign table cannot be part of partition tree made of temporary +-- relations. +CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +== 508 +CREATE FOREIGN TABLE foreign_part PARTITION OF temp_parted DEFAULT + SERVER s0 +-- +STMT: CreateForeignTableStmt +== 509 +-- ERROR +CREATE FOREIGN TABLE foreign_part (a int) SERVER s0 +-- +STMT: CreateForeignTableStmt +== 510 +ALTER TABLE temp_parted ATTACH PARTITION foreign_part DEFAULT +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: AlterTableStmt +== 511 +-- ERROR +DROP FOREIGN TABLE foreign_part +-- +STMT: DropStmt +== 512 +DROP TABLE temp_parted +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: DropStmt +== 513 +-- Cleanup +DROP SCHEMA foreign_schema CASCADE +-- +STMT: DropStmt +== 514 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +== 515 +-- ERROR +DROP SERVER t1 CASCADE +-- +STMT: DropStmt +== 516 +DROP USER MAPPING FOR regress_test_role SERVER s6 +-- +STMT: DropUserMappingStmt +== 517 +DROP FOREIGN DATA WRAPPER foo CASCADE +-- +STMT: DropStmt +== 518 +DROP SERVER s8 CASCADE +-- +STMT: DropStmt +== 519 +DROP ROLE regress_test_indirect +-- +STMT: DropRoleStmt +== 520 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +== 521 +DROP ROLE regress_unprivileged_role +-- +STMT: DropRoleStmt +== 522 +-- ERROR +REVOKE ALL ON FOREIGN DATA WRAPPER postgresql FROM regress_unprivileged_role +-- +STMT: GrantStmt +== 523 +DROP ROLE regress_unprivileged_role +-- +STMT: DropRoleStmt +== 524 +DROP ROLE regress_test_role2 +-- +STMT: DropRoleStmt +== 525 +DROP FOREIGN DATA WRAPPER postgresql CASCADE +-- +STMT: DropStmt +== 526 +DROP FOREIGN DATA WRAPPER dummy CASCADE +-- +STMT: DropStmt +== 527 +DROP ROLE regress_foreign_data_user +-- +STMT: DropRoleStmt +== 528 +-- At this point we should have no wrappers, no servers, and no mappings. +SELECT fdwname, fdwhandler, fdwvalidator, fdwoptions FROM pg_foreign_data_wrapper +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +STMT: SelectStmt +== 529 +SELECT srvname, srvoptions FROM pg_foreign_server +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +STMT: SelectStmt +== 530 +SELECT * FROM pg_user_mapping +-- +TABLE: name="pg_user_mapping" schema="" table="pg_user_mapping" ctx=Select +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/foreign_key.metadata.json b/parser/testdata/summary/postgres_regress/foreign_key.metadata.json new file mode 100644 index 0000000..0d39ce9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/foreign_key.metadata.json @@ -0,0 +1,1158 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "1060", + "1061", + "1062", + "1063", + "1064", + "1065", + "1066", + "1067", + "1068", + "1069", + "107", + "1070", + "1071", + "1072", + "1073", + "1074", + "1075", + "1076", + "1077", + "1078", + "1079", + "108", + "1080", + "1081", + "1082", + "1083", + "1084", + "1085", + "1086", + "1087", + "1088", + "1089", + "109", + "1090", + "1091", + "1092", + "1093", + "1094", + "1095", + "1096", + "1097", + "1098", + "1099", + "110", + "1100", + "1101", + "1102", + "1103", + "1104", + "1105", + "1106", + "1107", + "1108", + "1109", + "111", + "1110", + "1111", + "1112", + "1113", + "1114", + "1115", + "1116", + "1117", + "1118", + "1119", + "112", + "1120", + "1121", + "1122", + "1123", + "1124", + "1125", + "1126", + "1127", + "1128", + "1129", + "113", + "1130", + "1131", + "1132", + "1133", + "1134", + "1135", + "1136", + "1137", + "1138", + "1139", + "114", + "1140", + "1141", + "1142", + "1143", + "1144", + "1145", + "1146", + "1147", + "1148", + "1149", + "115", + "1150", + "1151", + "1152", + "1153", + "1154", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary/postgres_regress/foreign_key.test b/parser/testdata/summary/postgres_regress/foreign_key.test new file mode 100644 index 0000000..412f612 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/foreign_key.test @@ -0,0 +1,6735 @@ +== 001 +|-- +-- FOREIGN KEY +|-- + +-- MATCH FULL +|-- +-- First test, check and cascade +|-- +CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE FKTABLE ( ftest1 int REFERENCES PKTABLE MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, ftest2 int ) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 003 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO PKTABLE VALUES (2, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO PKTABLE VALUES (3, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO PKTABLE VALUES (4, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO PKTABLE VALUES (5, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO FKTABLE VALUES (2, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO FKTABLE VALUES (3, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO FKTABLE VALUES (NULL, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +-- Insert a failed row into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 014 +-- Delete a row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 015 +-- Check FKTABLE for removal of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 016 +-- Update a row from PK TABLE +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 017 +-- Check FKTABLE for update of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 018 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 019 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 020 +|-- +-- check set NULL and table constraint on multiple columns +|-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 021 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, CONSTRAINT constrname FOREIGN KEY(ftest1, ftest2) + REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 022 +-- Test comments +COMMENT ON CONSTRAINT constrname_wrong ON FKTABLE IS 'fk constraint comment' +-- +STMT: CommentStmt +== 023 +COMMENT ON CONSTRAINT constrname ON FKTABLE IS 'fk constraint comment' +-- +STMT: CommentStmt +== 024 +COMMENT ON CONSTRAINT constrname ON FKTABLE IS NULL +-- +STMT: CommentStmt +== 025 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 2, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO PKTABLE VALUES (1, 3, 'Test1-2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO PKTABLE VALUES (2, 4, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO PKTABLE VALUES (3, 6, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO PKTABLE VALUES (4, 8, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO PKTABLE VALUES (5, 10, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO FKTABLE VALUES (1, 3, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO FKTABLE VALUES (2, 4, 8) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO FKTABLE VALUES (3, 6, 12) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO FKTABLE VALUES (NULL, NULL, 0) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +-- Insert failed rows into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO FKTABLE VALUES (2, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO FKTABLE VALUES (NULL, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO FKTABLE VALUES (1, NULL, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 041 +-- Delete a row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=1 and ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 042 +-- Check FKTABLE for removal of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 043 +-- Delete another row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=5 and ptest2=10 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 044 +-- Check FKTABLE (should be no change) +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 045 +-- Update a row from PK TABLE +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 046 +-- Check FKTABLE for update of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 047 +-- Check update with part of key null +UPDATE FKTABLE SET ftest1 = NULL WHERE ftest1 = 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 048 +-- Check update with old and new key values equal +UPDATE FKTABLE SET ftest1 = 1 WHERE ftest1 = 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 049 +-- Try altering the column type where foreign keys are involved +ALTER TABLE PKTABLE ALTER COLUMN ptest1 TYPE bigint +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: AlterTableStmt +== 050 +ALTER TABLE FKTABLE ALTER COLUMN ftest1 TYPE bigint +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 051 +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 052 +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 053 +DROP TABLE PKTABLE CASCADE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 054 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 055 +|-- +-- check set default and table constraint on multiple columns +|-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 056 +CREATE TABLE FKTABLE ( ftest1 int DEFAULT -1, ftest2 int DEFAULT -2, ftest3 int, CONSTRAINT constrname2 FOREIGN KEY(ftest1, ftest2) + REFERENCES PKTABLE MATCH FULL ON DELETE SET DEFAULT ON UPDATE SET DEFAULT) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 057 +-- Insert a value in PKTABLE for default +INSERT INTO PKTABLE VALUES (-1, -2, 'The Default!') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 2, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +INSERT INTO PKTABLE VALUES (1, 3, 'Test1-2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +INSERT INTO PKTABLE VALUES (2, 4, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +INSERT INTO PKTABLE VALUES (3, 6, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +INSERT INTO PKTABLE VALUES (4, 8, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +INSERT INTO PKTABLE VALUES (5, 10, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +INSERT INTO FKTABLE VALUES (1, 3, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 066 +INSERT INTO FKTABLE VALUES (2, 4, 8) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +INSERT INTO FKTABLE VALUES (3, 6, 12) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 068 +INSERT INTO FKTABLE VALUES (NULL, NULL, 0) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +-- Insert failed rows into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +INSERT INTO FKTABLE VALUES (2, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +INSERT INTO FKTABLE VALUES (NULL, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +INSERT INTO FKTABLE VALUES (1, NULL, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 074 +-- Delete a row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=1 and ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 075 +-- Check FKTABLE to check for removal +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 076 +-- Delete another row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=5 and ptest2=10 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 077 +-- Check FKTABLE (should be no change) +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 078 +-- Update a row from PK TABLE +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 079 +-- Check FKTABLE for update of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 080 +-- this should fail for lack of CASCADE +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 081 +DROP TABLE PKTABLE CASCADE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 082 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 083 +|-- +-- First test, check with no on delete or on update +|-- +CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 084 +CREATE TABLE FKTABLE ( ftest1 int REFERENCES PKTABLE MATCH FULL, ftest2 int ) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 085 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 086 +INSERT INTO PKTABLE VALUES (2, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +INSERT INTO PKTABLE VALUES (3, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +INSERT INTO PKTABLE VALUES (4, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +INSERT INTO PKTABLE VALUES (5, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 091 +INSERT INTO FKTABLE VALUES (2, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +INSERT INTO FKTABLE VALUES (3, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +INSERT INTO FKTABLE VALUES (NULL, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +-- Insert a failed row into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 096 +-- Check PKTABLE +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 097 +-- Delete a row from PK TABLE (should fail) +DELETE FROM PKTABLE WHERE ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 098 +-- Delete a row from PK TABLE (should succeed) +DELETE FROM PKTABLE WHERE ptest1=5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 099 +-- Check PKTABLE for deletes +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 100 +-- Update a row from PK TABLE (should fail) +UPDATE PKTABLE SET ptest1=0 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 101 +-- Update a row from PK TABLE (should succeed) +UPDATE PKTABLE SET ptest1=0 WHERE ptest1=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 102 +-- Check PKTABLE for updates +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 103 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 104 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 105 +|-- +-- Check initial check upon ALTER TABLE +|-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, PRIMARY KEY(ptest1, ptest2) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 106 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int ) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 107 +INSERT INTO PKTABLE VALUES (1, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +INSERT INTO FKTABLE VALUES (1, NULL) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) REFERENCES PKTABLE MATCH FULL +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 110 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 111 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 112 +-- MATCH SIMPLE + +-- Base test restricting update/delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 113 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 114 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 120 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 124 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 125 +-- Try to update something that should fail +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 126 +-- Try to update something that should succeed +UPDATE PKTABLE set ptest1=1 WHERE ptest2=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 127 +-- Try to delete something that should fail +DELETE FROM PKTABLE where ptest1=1 and ptest2=2 and ptest3=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 128 +-- Try to delete something that should work +DELETE FROM PKTABLE where ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 129 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 130 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 131 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 132 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 133 +-- restrict with null values +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, UNIQUE(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 134 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE (ptest1, ptest2, ptest3)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 135 +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +INSERT INTO PKTABLE VALUES (1, 3, NULL, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +INSERT INTO PKTABLE VALUES (2, NULL, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +DELETE FROM PKTABLE WHERE ptest1 = 2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 140 +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 141 +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 142 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 143 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 144 +-- cascade update/delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 145 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE CASCADE ON UPDATE CASCADE) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 146 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 149 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 153 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 157 +-- Try to update something that will cascade +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 158 +-- Try to update something that should not cascade +UPDATE PKTABLE set ptest1=1 WHERE ptest2=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 159 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 160 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 161 +-- Try to delete something that should cascade +DELETE FROM PKTABLE where ptest1=1 and ptest2=5 and ptest3=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 162 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 163 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 164 +-- Try to delete something that should not have a cascade +DELETE FROM PKTABLE where ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 165 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 166 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 167 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 168 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 169 +-- set null update / set default delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 170 +CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE SET DEFAULT ON UPDATE SET NULL) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 171 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 174 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 175 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 176 +INSERT INTO FKTABLE VALUES (2, 3, 4, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 177 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 179 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 180 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 181 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 182 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 183 +-- Try to update something that will set null +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 184 +-- Try to update something that should not set null +UPDATE PKTABLE set ptest2=2 WHERE ptest2=3 and ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 185 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 186 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 187 +-- Try to delete something that should set default +DELETE FROM PKTABLE where ptest1=2 and ptest2=3 and ptest3=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 188 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 189 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 190 +-- Try to delete something that should not set default +DELETE FROM PKTABLE where ptest2=5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 191 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 192 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 193 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 194 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 195 +-- set default update / set null delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 196 +CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int DEFAULT -1, ftest3 int DEFAULT -2, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE SET NULL ON UPDATE SET DEFAULT) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 197 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 198 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 199 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 200 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +INSERT INTO PKTABLE VALUES (2, -1, 5, 'test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +INSERT INTO FKTABLE VALUES (2, 3, 4, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 204 +INSERT INTO FKTABLE VALUES (2, 4, 5, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 205 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 206 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 207 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 208 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 209 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 210 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 211 +-- Try to update something that will fail +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 212 +-- Try to update something that will set default +UPDATE PKTABLE set ptest1=0, ptest2=-1, ptest3=-2 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 213 +UPDATE PKTABLE set ptest2=10 where ptest2=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 214 +-- Try to update something that should not set default +UPDATE PKTABLE set ptest2=2 WHERE ptest2=3 and ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 215 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 216 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 217 +-- Try to delete something that should set null +DELETE FROM PKTABLE where ptest1=2 and ptest2=3 and ptest3=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 218 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 219 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 220 +-- Try to delete something that should not set null +DELETE FROM PKTABLE where ptest2=-1 and ptest3=5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 221 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +== 222 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 223 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 224 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 225 +-- Test for ON DELETE SET NULL/DEFAULT (column_list); +CREATE TABLE PKTABLE (tid int, id int, PRIMARY KEY (tid, id)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 226 +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES PKTABLE ON DELETE SET NULL (bar)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 227 +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES PKTABLE ON DELETE SET NULL (foo)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 228 +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, foo) REFERENCES PKTABLE ON UPDATE SET NULL (foo)) +-- +ERROR: a column list with SET NULL is only supported for ON DELETE actions +CURSORPOS: 91 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 229 +CREATE TABLE FKTABLE ( + tid int, id int, + fk_id_del_set_null int, + fk_id_del_set_default int DEFAULT 0, + FOREIGN KEY (tid, fk_id_del_set_null) REFERENCES PKTABLE ON DELETE SET NULL (fk_id_del_set_null), + -- this tests handling of duplicate entries in SET DEFAULT column list + FOREIGN KEY (tid, fk_id_del_set_default) REFERENCES PKTABLE ON DELETE SET DEFAULT (fk_id_del_set_default, fk_id_del_set_default) +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 230 +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'fktable'::regclass::oid ORDER BY oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 231 +INSERT INTO PKTABLE VALUES (1, 0), (1, 1), (1, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 232 +INSERT INTO FKTABLE VALUES + (1, 1, 1, NULL), + (1, 2, NULL, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 233 +DELETE FROM PKTABLE WHERE id = 1 OR id = 2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 234 +SELECT * FROM FKTABLE ORDER BY id +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +== 235 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 236 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 237 +-- Test some invalid FK definitions +CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY, someoid oid) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 238 +CREATE TABLE FKTABLE_FAIL1 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest2) REFERENCES PKTABLE) +-- +TABLE: name="fktable_fail1" schema="" table="fktable_fail1" ctx=DDL +STMT: CreateStmt +== 239 +CREATE TABLE FKTABLE_FAIL2 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES PKTABLE(ptest2)) +-- +TABLE: name="fktable_fail2" schema="" table="fktable_fail2" ctx=DDL +STMT: CreateStmt +== 240 +CREATE TABLE FKTABLE_FAIL3 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (tableoid) REFERENCES PKTABLE(someoid)) +-- +TABLE: name="fktable_fail3" schema="" table="fktable_fail3" ctx=DDL +STMT: CreateStmt +== 241 +CREATE TABLE FKTABLE_FAIL4 ( ftest1 oid, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES PKTABLE(tableoid)) +-- +TABLE: name="fktable_fail4" schema="" table="fktable_fail4" ctx=DDL +STMT: CreateStmt +== 242 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 243 +-- Test for referencing column number smaller than referenced constraint +CREATE TABLE PKTABLE (ptest1 int, ptest2 int, UNIQUE(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 244 +CREATE TABLE FKTABLE_FAIL1 (ftest1 int REFERENCES pktable(ptest1)) +-- +TABLE: name="fktable_fail1" schema="" table="fktable_fail1" ctx=DDL +STMT: CreateStmt +== 245 +DROP TABLE FKTABLE_FAIL1 +-- +TABLE: name="fktable_fail1" schema="" table="fktable_fail1" ctx=DDL +STMT: DropStmt +== 246 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 247 +|-- +-- Tests for mismatched types +|-- +-- Basic one column, two table setup +CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 248 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 249 +-- This next should fail, because int=inet does not exist +CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 250 +-- This should also fail for the same reason, but here we +-- give the column name +CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable(ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 251 +-- This should succeed, even though they are different types, +-- because int=int8 exists and is a member of the integer opfamily +CREATE TABLE FKTABLE (ftest1 int8 REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 252 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +-- should fail +UPDATE FKTABLE SET ftest1 = ftest1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 255 +-- should succeed +UPDATE FKTABLE SET ftest1 = ftest1 + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 256 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 257 +-- This should fail, because we'd have to cast numeric to int which is +-- not an implicit coercion (or use numeric=numeric, but that's not part +-- of the integer opfamily) +CREATE TABLE FKTABLE (ftest1 numeric REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 258 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 259 +-- On the other hand, this should work because int implicitly promotes to +-- numeric, and we allow promotion on the FK side +CREATE TABLE PKTABLE (ptest1 numeric PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 260 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 261 +CREATE TABLE FKTABLE (ftest1 int REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 262 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 263 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 264 +-- should fail +UPDATE FKTABLE SET ftest1 = ftest1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 265 +-- should succeed +UPDATE FKTABLE SET ftest1 = ftest1 + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 266 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 267 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 268 +-- Two columns, two tables +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 269 +-- This should fail, because we just chose really odd types +CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 270 +-- Again, so should this... +CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 271 +-- This fails because we mixed up the column ordering +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 272 +-- As does this... +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 273 +-- And again.. +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 274 +-- This works... +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 275 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 276 +-- As does this +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 277 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 278 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 279 +-- Two columns, same table +-- Make sure this still works... +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 280 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 281 +-- And this, +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 282 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 283 +-- This shouldn't (mixed up columns) +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable(ptest2, ptest1)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 284 +-- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, +ptest3) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 285 +-- Not this one either... Same as the last one except we didn't defined the columns being referenced. +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, +ptest3) REFERENCES pktable) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 286 +|-- +-- Now some cases with inheritance +-- Basic 2 table case: 1 column of matching types. +create table pktable_base (base1 int not null) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +== 287 +create table pktable (ptest1 int, primary key(base1), unique(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 288 +create table fktable (ftest1 int references pktable(base1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 289 +-- now some ins, upd, del +insert into pktable(base1) values (1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 290 +insert into pktable(base1) values (2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 291 +-- let's insert a non-existent fktable value +insert into fktable(ftest1) values (3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 292 +-- let's make a valid row for that +insert into pktable(base1) values (3) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +insert into fktable(ftest1) values (3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 294 +-- let's try removing a row that should fail from pktable +delete from pktable where base1>2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 295 +-- okay, let's try updating all of the base1 values to *4 +-- which should fail. +update pktable set base1=base1*4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 296 +-- okay, let's try an update that should work. +update pktable set base1=base1*4 where base1<3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 297 +-- and a delete that should work +delete from pktable where base1>3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 298 +-- cleanup +drop table fktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 299 +delete from pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 300 +-- Now 2 columns 2 tables, matching types +create table fktable (ftest1 int, ftest2 int, foreign key(ftest1, ftest2) references pktable(base1, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 301 +-- now some ins, upd, del +insert into pktable(base1, ptest1) values (1, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 302 +insert into pktable(base1, ptest1) values (2, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 303 +-- let's insert a non-existent fktable value +insert into fktable(ftest1, ftest2) values (3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 304 +-- let's make a valid row for that +insert into pktable(base1,ptest1) values (3, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 305 +insert into fktable(ftest1, ftest2) values (3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +-- let's try removing a row that should fail from pktable +delete from pktable where base1>2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 307 +-- okay, let's try updating all of the base1 values to *4 +-- which should fail. +update pktable set base1=base1*4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 308 +-- okay, let's try an update that should work. +update pktable set base1=base1*4 where base1<3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 309 +-- and a delete that should work +delete from pktable where base1>3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 310 +-- cleanup +drop table fktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 311 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 312 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +== 313 +-- Now we'll do one all in 1 table with 2 columns of matching types +create table pktable_base(base1 int not null, base2 int) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +== 314 +create table pktable(ptest1 int, ptest2 int, primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 315 +insert into pktable (base1, ptest1, base2, ptest2) values (1, 1, 1, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 316 +insert into pktable (base1, ptest1, base2, ptest2) values (2, 1, 1, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 317 +insert into pktable (base1, ptest1, base2, ptest2) values (2, 2, 2, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 318 +insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 319 +-- fails (3,2) isn't in base1, ptest1 +insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 320 +-- fails (2,2) is being referenced +delete from pktable where base1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 321 +-- fails (1,1) is being referenced (twice) +update pktable set base1=3 where base1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 322 +-- this sequence of two deletes will work, since after the first there will be no (2,*) references +delete from pktable where base2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 323 +delete from pktable where base1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +== 324 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 325 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +== 326 +-- 2 columns (2 tables), mismatched types +create table pktable_base(base1 int not null) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +== 327 +create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 328 +-- just generally bad types (with and without column references on the referenced table) +create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 329 +create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 330 +-- let's mix up which columns reference which +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 331 +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 332 +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 333 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 334 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +== 335 +-- 2 columns (1 table), mismatched types +create table pktable_base(base1 int not null, base2 int) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +== 336 +create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 337 +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(ptest1, base1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 338 +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 339 +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 340 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 341 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +== 342 +|-- +-- Deferrable constraints +|-- + +-- deferrable, explicitly deferred +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 343 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 344 +-- default to immediate: should fail +INSERT INTO fktable VALUES (5, 10) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 345 +-- explicitly defer the constraint +BEGIN +-- +STMT: TransactionStmt +== 346 +SET CONSTRAINTS ALL DEFERRED +-- +STMT: ConstraintsSetStmt +== 347 +INSERT INTO fktable VALUES (10, 15) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 348 +INSERT INTO pktable VALUES (15, 0) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 349 +-- make the FK insert valid + +COMMIT +-- +STMT: TransactionStmt +== 350 +DROP TABLE fktable, pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 351 +-- deferrable, initially deferred +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 352 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 353 +-- default to deferred, should succeed +BEGIN +-- +STMT: TransactionStmt +== 354 +INSERT INTO fktable VALUES (100, 200) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 355 +INSERT INTO pktable VALUES (200, 500) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 356 +-- make the FK insert valid + +COMMIT +-- +STMT: TransactionStmt +== 357 +-- default to deferred, explicitly make immediate +BEGIN +-- +STMT: TransactionStmt +== 358 +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +== 359 +-- should fail +INSERT INTO fktable VALUES (500, 1000) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +COMMIT +-- +STMT: TransactionStmt +== 361 +DROP TABLE fktable, pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 362 +-- tricky behavior: according to SQL99, if a deferred constraint is set +-- to 'immediate' mode, it should be checked for validity *immediately*, +-- not when the current transaction commits (i.e. the mode change applies +-- retroactively) +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 363 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 364 +BEGIN +-- +STMT: TransactionStmt +== 365 +SET CONSTRAINTS ALL DEFERRED +-- +STMT: ConstraintsSetStmt +== 366 +-- should succeed, for now +INSERT INTO fktable VALUES (1000, 2000) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 367 +-- should cause transaction abort, due to preceding error +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +== 368 +INSERT INTO pktable VALUES (2000, 3) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 369 +-- too late + +COMMIT +-- +STMT: TransactionStmt +== 370 +DROP TABLE fktable, pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +== 371 +-- deferrable, initially deferred +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 372 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 373 +BEGIN +-- +STMT: TransactionStmt +== 374 +-- no error here +INSERT INTO fktable VALUES (100, 200) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 375 +-- error here on commit +COMMIT +-- +STMT: TransactionStmt +== 376 +DROP TABLE pktable, fktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 377 +-- test notice about expensive referential integrity checks, +-- where the index cannot be used because of type incompatibilities. + +CREATE TEMP TABLE pktable ( + id1 INT4 PRIMARY KEY, + id2 VARCHAR(4) UNIQUE, + id3 REAL UNIQUE, + UNIQUE(id1, id2, id3) +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 378 +CREATE TEMP TABLE fktable ( + x1 INT4 REFERENCES pktable(id1), + x2 VARCHAR(4) REFERENCES pktable(id2), + x3 REAL REFERENCES pktable(id3), + x4 TEXT, + x5 INT2 +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 379 +-- check individual constraints with alter table. + +-- should fail + +-- varchar does not promote to real +ALTER TABLE fktable ADD CONSTRAINT fk_2_3 +FOREIGN KEY (x2) REFERENCES pktable(id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 380 +-- nor to int4 +ALTER TABLE fktable ADD CONSTRAINT fk_2_1 +FOREIGN KEY (x2) REFERENCES pktable(id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 381 +-- real does not promote to int4 +ALTER TABLE fktable ADD CONSTRAINT fk_3_1 +FOREIGN KEY (x3) REFERENCES pktable(id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 382 +-- int4 does not promote to text +ALTER TABLE fktable ADD CONSTRAINT fk_1_2 +FOREIGN KEY (x1) REFERENCES pktable(id2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 383 +-- should succeed + +-- int4 promotes to real +ALTER TABLE fktable ADD CONSTRAINT fk_1_3 +FOREIGN KEY (x1) REFERENCES pktable(id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 384 +-- text is compatible with varchar +ALTER TABLE fktable ADD CONSTRAINT fk_4_2 +FOREIGN KEY (x4) REFERENCES pktable(id2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 385 +-- int2 is part of integer opfamily as of 8.0 +ALTER TABLE fktable ADD CONSTRAINT fk_5_1 +FOREIGN KEY (x5) REFERENCES pktable(id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 386 +-- check multikey cases, especially out-of-order column lists + +-- these should work + +ALTER TABLE fktable ADD CONSTRAINT fk_123_123 +FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id1,id2,id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 387 +ALTER TABLE fktable ADD CONSTRAINT fk_213_213 +FOREIGN KEY (x2,x1,x3) REFERENCES pktable(id2,id1,id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 388 +ALTER TABLE fktable ADD CONSTRAINT fk_253_213 +FOREIGN KEY (x2,x5,x3) REFERENCES pktable(id2,id1,id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 389 +-- these should fail + +ALTER TABLE fktable ADD CONSTRAINT fk_123_231 +FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id2,id3,id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 390 +ALTER TABLE fktable ADD CONSTRAINT fk_241_132 +FOREIGN KEY (x2,x4,x1) REFERENCES pktable(id1,id3,id2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 391 +DROP TABLE pktable, fktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +== 392 +-- test a tricky case: we can elide firing the FK check trigger during +-- an UPDATE if the UPDATE did not change the foreign key +-- field. However, we can't do this if our transaction was the one that +-- created the updated row and the trigger is deferred, since our UPDATE +-- will have invalidated the original newly-inserted tuple, and therefore +-- cause the on-INSERT RI trigger not to be fired. + +CREATE TEMP TABLE pktable ( + id int primary key, + other int +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +== 393 +CREATE TEMP TABLE fktable ( + id int primary key, + fk int references pktable deferrable initially deferred +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +== 394 +INSERT INTO pktable VALUES (5, 10) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 395 +BEGIN +-- +STMT: TransactionStmt +== 396 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 397 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 398 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +== 399 +-- check same case when insert is in a different subtransaction than update + +BEGIN +-- +STMT: TransactionStmt +== 400 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 401 +-- UPDATE will be in a subxact +SAVEPOINT savept1 +-- +STMT: TransactionStmt +== 402 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 403 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +== 404 +BEGIN +-- +STMT: TransactionStmt +== 405 +-- INSERT will be in a subxact +SAVEPOINT savept1 +-- +STMT: TransactionStmt +== 406 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 407 +RELEASE SAVEPOINT savept1 +-- +STMT: TransactionStmt +== 408 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 409 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +== 410 +BEGIN +-- +STMT: TransactionStmt +== 411 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 412 +-- UPDATE will be in a subxact +SAVEPOINT savept1 +-- +STMT: TransactionStmt +== 413 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +== 414 +-- Roll back the UPDATE +ROLLBACK TO savept1 +-- +STMT: TransactionStmt +== 415 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +== 416 +|-- +-- check ALTER CONSTRAINT +|-- + +INSERT INTO fktable VALUES (1, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 417 +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 418 +BEGIN +-- +STMT: TransactionStmt +== 419 +-- doesn't match FK, should throw error now +UPDATE pktable SET id = 10 WHERE id = 5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +== 420 +COMMIT +-- +STMT: TransactionStmt +== 421 +BEGIN +-- +STMT: TransactionStmt +== 422 +-- doesn't match PK, should throw error now +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 423 +COMMIT +-- +STMT: TransactionStmt +== 424 +-- try additional syntax +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +== 425 +-- illegal options +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT DEFERRABLE INITIALLY DEFERRED +-- +ERROR: constraint declared INITIALLY DEFERRED must be DEFERRABLE +CURSORPOS: 88 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 426 +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NO INHERIT +-- +ERROR: FOREIGN KEY constraints cannot be marked NO INHERIT +FILENAME: gram.y +FUNCNAME: processCASbits +== 427 +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT VALID +-- +ERROR: FOREIGN KEY constraints cannot be marked NOT VALID +FILENAME: gram.y +FUNCNAME: processCASbits +== 428 +-- test order of firing of FK triggers when several RI-induced changes need to +-- be made to the same row. This was broken by subtransaction-related +-- changes in 8.0. + +CREATE TEMP TABLE users ( + id INT PRIMARY KEY, + name VARCHAR NOT NULL +) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +== 429 +INSERT INTO users VALUES (1, 'Jozko') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 430 +INSERT INTO users VALUES (2, 'Ferko') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 431 +INSERT INTO users VALUES (3, 'Samko') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 432 +CREATE TEMP TABLE tasks ( + id INT PRIMARY KEY, + owner INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, + worker INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, + checked_by INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL +) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DDL +STMT: CreateStmt +== 433 +INSERT INTO tasks VALUES (1,1,NULL,NULL) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 434 +INSERT INTO tasks VALUES (2,2,2,NULL) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 435 +INSERT INTO tasks VALUES (3,3,3,3) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 436 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +== 437 +UPDATE users SET id = 4 WHERE id = 3 +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: UpdateStmt +== 438 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +== 439 +DELETE FROM users WHERE id = 4 +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: DeleteStmt +== 440 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +== 441 +-- could fail with only 2 changes to make, if row was already updated +BEGIN +-- +STMT: TransactionStmt +== 442 +UPDATE tasks set id=id WHERE id=2 +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: UpdateStmt +== 443 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +== 444 +DELETE FROM users WHERE id = 2 +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: DeleteStmt +== 445 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +== 446 +COMMIT +-- +STMT: TransactionStmt +== 447 +|-- +-- Test self-referential FK with CASCADE (bug #6268) +|-- +create temp table selfref ( + a int primary key, + b int, + foreign key (b) references selfref (a) + on update cascade on delete cascade +) +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DDL +STMT: CreateStmt +== 448 +insert into selfref (a, b) +values + (0, 0), + (1, 1) +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 449 +begin +-- +STMT: TransactionStmt +== 450 +update selfref set a = 123 where a = 0 +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DML +STMT: UpdateStmt +== 451 +select a, b from selfref +-- +TABLE: name="selfref" schema="" table="selfref" ctx=Select +STMT: SelectStmt +== 452 +update selfref set a = 456 where a = 123 +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DML +STMT: UpdateStmt +== 453 +select a, b from selfref +-- +TABLE: name="selfref" schema="" table="selfref" ctx=Select +STMT: SelectStmt +== 454 +commit +-- +STMT: TransactionStmt +== 455 +|-- +-- Test that SET DEFAULT actions recognize updates to default values +|-- +create temp table defp (f1 int primary key) +-- +TABLE: name="defp" schema="" table="defp" ctx=DDL +STMT: CreateStmt +== 456 +create temp table defc (f1 int default 0 + references defp on delete set default) +-- +TABLE: name="defc" schema="" table="defc" ctx=DDL +STMT: CreateStmt +== 457 +insert into defp values (0), (1), (2) +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 458 +insert into defc values (2) +-- +TABLE: name="defc" schema="" table="defc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 459 +select * from defc +-- +TABLE: name="defc" schema="" table="defc" ctx=Select +STMT: SelectStmt +== 460 +delete from defp where f1 = 2 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +== 461 +select * from defc +-- +TABLE: name="defc" schema="" table="defc" ctx=Select +STMT: SelectStmt +== 462 +delete from defp where f1 = 0 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +== 463 +-- fail +alter table defc alter column f1 set default 1 +-- +TABLE: name="defc" schema="" table="defc" ctx=DDL +STMT: AlterTableStmt +== 464 +delete from defp where f1 = 0 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +== 465 +select * from defc +-- +TABLE: name="defc" schema="" table="defc" ctx=Select +STMT: SelectStmt +== 466 +delete from defp where f1 = 1 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +== 467 +-- fail + +|-- +-- Test the difference between NO ACTION and RESTRICT +|-- +create temp table pp (f1 int primary key) +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +STMT: CreateStmt +== 468 +create temp table cc (f1 int references pp on update no action on delete no action) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +== 469 +insert into pp values(12) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 470 +insert into pp values(11) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 471 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +== 472 +insert into cc values(13) +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 473 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +== 474 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +== 475 +-- fail +delete from pp where f1 = 13 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: DeleteStmt +== 476 +-- fail +drop table pp, cc +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: DropStmt +== 477 +create temp table pp (f1 int primary key) +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +STMT: CreateStmt +== 478 +create temp table cc (f1 int references pp on update restrict on delete restrict) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +== 479 +insert into pp values(12) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 480 +insert into pp values(11) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 481 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +== 482 +insert into cc values(13) +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 483 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +== 484 +-- fail +delete from pp where f1 = 13 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: DeleteStmt +== 485 +-- fail +drop table pp, cc +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: DropStmt +== 486 +|-- +-- Test interaction of foreign-key optimization with rules (bug #14219) +|-- +create temp table t1 (a integer primary key, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 487 +create temp table t2 (a integer primary key, b integer references t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 488 +create rule r1 as on delete to t1 do delete from t2 where t2.b = old.a +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +== 489 +explain (costs off) delete from t1 where a = 1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 490 +delete from t1 where a = 1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: DeleteStmt +== 491 +-- Test a primary key with attributes located in later attnum positions +-- compared to the fk attributes. +create table pktable2 (a int, b int, c int, d int, e int, primary key (d, e)) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +== 492 +create table fktable2 (d int, e int, foreign key (d, e) references pktable2) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +== 493 +insert into pktable2 values (1, 2, 3, 4, 5) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 494 +insert into fktable2 values (4, 5) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 495 +delete from pktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: DeleteStmt +== 496 +update pktable2 set d = 5 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: UpdateStmt +== 497 +drop table pktable2, fktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +== 498 +-- Test truncation of long foreign key names +create table pktable1 (a int primary key) +-- +TABLE: name="pktable1" schema="" table="pktable1" ctx=DDL +STMT: CreateStmt +== 499 +create table pktable2 (a int, b int, primary key (a, b)) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +== 500 +create table fktable2 ( + a int, + b int, + very_very_long_column_name_to_exceed_63_characters int, + foreign key (very_very_long_column_name_to_exceed_63_characters) references pktable1, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2 +) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +== 501 +select conname from pg_constraint where conrelid = 'fktable2'::regclass order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 502 +drop table pktable1, pktable2, fktable2 +-- +TABLE: name="pktable1" schema="" table="pktable1" ctx=DDL +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +== 503 +|-- +-- Test deferred FK check on a tuple deleted by a rolled-back subtransaction +|-- +create table pktable2(f1 int primary key) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +== 504 +create table fktable2(f1 int references pktable2 deferrable initially deferred) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +== 505 +insert into pktable2 values(1) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 506 +begin +-- +STMT: TransactionStmt +== 507 +insert into fktable2 values(1) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 508 +savepoint x +-- +STMT: TransactionStmt +== 509 +delete from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: DeleteStmt +== 510 +rollback to x +-- +STMT: TransactionStmt +== 511 +commit +-- +STMT: TransactionStmt +== 512 +begin +-- +STMT: TransactionStmt +== 513 +insert into fktable2 values(2) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 514 +savepoint x +-- +STMT: TransactionStmt +== 515 +delete from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: DeleteStmt +== 516 +rollback to x +-- +STMT: TransactionStmt +== 517 +commit +-- +STMT: TransactionStmt +== 518 +-- fail + +|-- +-- Test that we prevent dropping FK constraint with pending trigger events +|-- +begin +-- +STMT: TransactionStmt +== 519 +insert into fktable2 values(2) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 520 +alter table fktable2 drop constraint fktable2_f1_fkey +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: AlterTableStmt +== 521 +commit +-- +STMT: TransactionStmt +== 522 +begin +-- +STMT: TransactionStmt +== 523 +delete from pktable2 where f1 = 1 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: DeleteStmt +== 524 +alter table fktable2 drop constraint fktable2_f1_fkey +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: AlterTableStmt +== 525 +commit +-- +STMT: TransactionStmt +== 526 +drop table pktable2, fktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +== 527 +|-- +-- Test keys that "look" different but compare as equal +|-- +create table pktable2 (a float8, b float8, primary key (a, b)) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +== 528 +create table fktable2 (x float8, y float8, foreign key (x, y) references pktable2 (a, b) on update cascade) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +== 529 +insert into pktable2 values ('-0', '-0') +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 530 +insert into fktable2 values ('-0', '-0') +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 531 +select * from pktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=Select +STMT: SelectStmt +== 532 +select * from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=Select +STMT: SelectStmt +== 533 +update pktable2 set a = '0' where a = '-0' +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: UpdateStmt +== 534 +select * from pktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=Select +STMT: SelectStmt +== 535 +-- should have updated fktable2.x +select * from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=Select +STMT: SelectStmt +== 536 +drop table pktable2, fktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +== 537 +|-- +-- Foreign keys and partitioned tables +|-- + +-- Creation of a partitioned hierarchy with irregular definitions +CREATE TABLE fk_notpartitioned_pk (fdrop1 int, a int, fdrop2 int, b int, + PRIMARY KEY (a, b)) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: CreateStmt +== 538 +ALTER TABLE fk_notpartitioned_pk DROP COLUMN fdrop1, DROP COLUMN fdrop2 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: AlterTableStmt +== 539 +CREATE TABLE fk_partitioned_fk (b int, fdrop1 int, a int) PARTITION BY RANGE (a, b) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: CreateStmt +== 540 +ALTER TABLE fk_partitioned_fk DROP COLUMN fdrop1 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 541 +CREATE TABLE fk_partitioned_fk_1 (fdrop1 int, fdrop2 int, a int, fdrop3 int, b int) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +== 542 +ALTER TABLE fk_partitioned_fk_1 DROP COLUMN fdrop1, DROP COLUMN fdrop2, DROP COLUMN fdrop3 +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: AlterTableStmt +== 543 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR VALUES FROM (0,0) TO (1000,1000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 544 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 545 +CREATE TABLE fk_partitioned_fk_2 (b int, fdrop1 int, fdrop2 int, a int) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +== 546 +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN fdrop1, DROP COLUMN fdrop2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: AlterTableStmt +== 547 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FROM (1000,1000) TO (2000,2000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 548 +CREATE TABLE fk_partitioned_fk_3 (fdrop1 int, fdrop2 int, fdrop3 int, fdrop4 int, b int, a int) + PARTITION BY HASH (a) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DDL +STMT: CreateStmt +== 549 +ALTER TABLE fk_partitioned_fk_3 DROP COLUMN fdrop1, DROP COLUMN fdrop2, + DROP COLUMN fdrop3, DROP COLUMN fdrop4 +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DDL +STMT: AlterTableStmt +== 550 +CREATE TABLE fk_partitioned_fk_3_0 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, REMAINDER 0) +-- +TABLE: name="fk_partitioned_fk_3_0" schema="" table="fk_partitioned_fk_3_0" ctx=DDL +STMT: CreateStmt +== 551 +CREATE TABLE fk_partitioned_fk_3_1 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, REMAINDER 1) +-- +TABLE: name="fk_partitioned_fk_3_1" schema="" table="fk_partitioned_fk_3_1" ctx=DDL +STMT: CreateStmt +== 552 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 + FOR VALUES FROM (2000,2000) TO (3000,3000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 553 +-- Creating a foreign key with ONLY on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE ONLY fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 554 +-- Adding a NOT VALID foreign key on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk NOT VALID +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 555 +-- these inserts, targeting both the partition directly as well as the +-- partitioned table, should all fail +INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 556 +INSERT INTO fk_partitioned_fk_1 (a,b) VALUES (500, 501) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 557 +INSERT INTO fk_partitioned_fk (a,b) VALUES (1500, 1501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 558 +INSERT INTO fk_partitioned_fk_2 (a,b) VALUES (1500, 1501) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 559 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 560 +INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2500, 2502) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 561 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 562 +INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2501, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 563 +-- but if we insert the values that make them valid, then they work +INSERT INTO fk_notpartitioned_pk VALUES (500, 501), (1500, 1501), + (2500, 2502), (2501, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 564 +INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 565 +INSERT INTO fk_partitioned_fk (a,b) VALUES (1500, 1501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 566 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 567 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 568 +-- this update fails because there is no referenced row +UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: UpdateStmt +== 569 +-- but we can fix it thusly: +INSERT INTO fk_notpartitioned_pk (a,b) VALUES (2502, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 570 +UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: UpdateStmt +== 571 +-- these updates would leave lingering rows in the referencing table; disallow +UPDATE fk_notpartitioned_pk SET b = 502 WHERE a = 500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +== 572 +UPDATE fk_notpartitioned_pk SET b = 1502 WHERE a = 1500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +== 573 +UPDATE fk_notpartitioned_pk SET b = 2504 WHERE a = 2500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +== 574 +-- check psql behavior +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 575 +-- done. +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: DropStmt +== 576 +-- Altering a type referenced by a foreign key needs to drop/recreate the FK. +-- Ensure that works. +CREATE TABLE fk_notpartitioned_pk (a INT, PRIMARY KEY(a), CHECK (a > 0)) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: CreateStmt +== 577 +CREATE TABLE fk_partitioned_fk (a INT REFERENCES fk_notpartitioned_pk(a) PRIMARY KEY) PARTITION BY RANGE(a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: CreateStmt +== 578 +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES FROM (MINVALUE) TO (MAXVALUE) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +== 579 +INSERT INTO fk_notpartitioned_pk VALUES (1) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 580 +INSERT INTO fk_partitioned_fk VALUES (1) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 581 +ALTER TABLE fk_notpartitioned_pk ALTER COLUMN a TYPE bigint +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: AlterTableStmt +== 582 +DELETE FROM fk_notpartitioned_pk WHERE a = 1 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +== 583 +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: DropStmt +== 584 +-- Test some other exotic foreign key features: MATCH SIMPLE, ON UPDATE/DELETE +-- actions +CREATE TABLE fk_notpartitioned_pk (a int, b int, primary key (a, b)) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: CreateStmt +== 585 +CREATE TABLE fk_partitioned_fk (a int default 2501, b int default 142857) PARTITION BY LIST (a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: CreateStmt +== 586 +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES IN (NULL,500,501,502) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +== 587 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk MATCH SIMPLE + ON DELETE SET NULL ON UPDATE SET NULL +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 588 +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +== 589 +CREATE TABLE fk_partitioned_fk_3 (a int, b int) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DDL +STMT: CreateStmt +== 590 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES IN (2500,2501,2502,2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 591 +-- this insert fails +INSERT INTO fk_partitioned_fk (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 592 +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 593 +-- but since the FK is MATCH SIMPLE, this one doesn't +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, NULL) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 594 +-- now create the referenced row ... +INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 595 +--- and now the same insert work +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 596 +-- this always works +INSERT INTO fk_partitioned_fk (a,b) VALUES (NULL, NULL) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 597 +-- MATCH FULL +INSERT INTO fk_notpartitioned_pk VALUES (1, 2) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 598 +CREATE TABLE fk_partitioned_fk_full (x int, y int) PARTITION BY RANGE (x) +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: CreateStmt +== 599 +CREATE TABLE fk_partitioned_fk_full_1 PARTITION OF fk_partitioned_fk_full DEFAULT +-- +TABLE: name="fk_partitioned_fk_full_1" schema="" table="fk_partitioned_fk_full_1" ctx=DDL +STMT: CreateStmt +== 600 +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL) +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 601 +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: AlterTableStmt +== 602 +-- fails +TRUNCATE fk_partitioned_fk_full +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: TruncateStmt +== 603 +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: AlterTableStmt +== 604 +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL) +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 605 +-- fails +DROP TABLE fk_partitioned_fk_full +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: DropStmt +== 606 +-- ON UPDATE SET NULL +SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 607 +UPDATE fk_notpartitioned_pk SET a = a + 1 WHERE a = 2502 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +== 608 +SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 609 +-- ON DELETE SET NULL +INSERT INTO fk_partitioned_fk VALUES (2503, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 610 +SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 611 +DELETE FROM fk_notpartitioned_pk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +== 612 +SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 613 +-- ON UPDATE/DELETE SET DEFAULT +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 614 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET DEFAULT ON UPDATE SET DEFAULT +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 615 +INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 616 +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 617 +-- this fails, because the defaults for the referencing table are not present +-- in the referenced table: +UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +== 618 +-- but inserting the row we can make it work: +INSERT INTO fk_notpartitioned_pk VALUES (2501, 142857) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 619 +UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +== 620 +SELECT * FROM fk_partitioned_fk WHERE b = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 621 +-- ON DELETE SET NULL column_list +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 622 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET NULL (a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 623 +BEGIN +-- +STMT: TransactionStmt +== 624 +DELETE FROM fk_notpartitioned_pk WHERE b = 142857 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +== 625 +SELECT * FROM fk_partitioned_fk WHERE a IS NOT NULL OR b IS NOT NULL ORDER BY a NULLS LAST +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 626 +ROLLBACK +-- +STMT: TransactionStmt +== 627 +-- ON DELETE SET DEFAULT column_list +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 628 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET DEFAULT (a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 629 +BEGIN +-- +STMT: TransactionStmt +== 630 +DELETE FROM fk_partitioned_fk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: DeleteStmt +== 631 +DELETE FROM fk_notpartitioned_pk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +== 632 +INSERT INTO fk_notpartitioned_pk VALUES (500, 100000), (2501, 100000) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 633 +INSERT INTO fk_partitioned_fk VALUES (500, 100000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 634 +DELETE FROM fk_notpartitioned_pk WHERE a = 500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +== 635 +SELECT * FROM fk_partitioned_fk ORDER BY a +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +STMT: SelectStmt +== 636 +ROLLBACK +-- +STMT: TransactionStmt +== 637 +-- ON UPDATE/DELETE CASCADE +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 638 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE CASCADE ON UPDATE CASCADE +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 639 +UPDATE fk_notpartitioned_pk SET a = 2502 WHERE a = 2501 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +== 640 +SELECT * FROM fk_partitioned_fk WHERE b = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 641 +-- Now you see it ... +SELECT * FROM fk_partitioned_fk WHERE b = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 642 +DELETE FROM fk_notpartitioned_pk WHERE b = 142857 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +== 643 +-- now you don't. +SELECT * FROM fk_partitioned_fk WHERE a = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 644 +-- verify that DROP works +DROP TABLE fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: DropStmt +== 645 +-- Test behavior of the constraint together with attaching and detaching +-- partitions. +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +== 646 +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 647 +BEGIN +-- +STMT: TransactionStmt +== 648 +DROP TABLE fk_partitioned_fk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: DropStmt +== 649 +-- constraint should still be there +ROLLBACK +-- +STMT: TransactionStmt +== 650 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 651 +DROP TABLE fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: DropStmt +== 652 +CREATE TABLE fk_partitioned_fk_2 (b int, c text, a int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE CASCADE ON DELETE CASCADE) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +== 653 +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN c +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: AlterTableStmt +== 654 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 655 +-- should have only one constraint +DROP TABLE fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: DropStmt +== 656 +CREATE TABLE fk_partitioned_fk_4 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE) PARTITION BY RANGE (b, a) +-- +TABLE: name="fk_partitioned_fk_4" schema="" table="fk_partitioned_fk_4" ctx=DDL +STMT: CreateStmt +== 657 +CREATE TABLE fk_partitioned_fk_4_1 PARTITION OF fk_partitioned_fk_4 FOR VALUES FROM (1,1) TO (100,100) +-- +TABLE: name="fk_partitioned_fk_4_1" schema="" table="fk_partitioned_fk_4_1" ctx=DDL +STMT: CreateStmt +== 658 +CREATE TABLE fk_partitioned_fk_4_2 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE SET NULL) +-- +TABLE: name="fk_partitioned_fk_4_2" schema="" table="fk_partitioned_fk_4_2" ctx=DDL +STMT: CreateStmt +== 659 +ALTER TABLE fk_partitioned_fk_4 ATTACH PARTITION fk_partitioned_fk_4_2 FOR VALUES FROM (100,100) TO (1000,1000) +-- +TABLE: name="fk_partitioned_fk_4" schema="" table="fk_partitioned_fk_4" ctx=DDL +STMT: AlterTableStmt +== 660 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 661 +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_4 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 662 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 663 +-- should only have one constraint +-- this one has an FK with mismatched properties + +CREATE TABLE fk_partitioned_fk_5 (a int, b int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE) + PARTITION BY RANGE (a) +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: CreateStmt +== 664 +CREATE TABLE fk_partitioned_fk_5_1 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk) +-- +TABLE: name="fk_partitioned_fk_5_1" schema="" table="fk_partitioned_fk_5_1" ctx=DDL +STMT: CreateStmt +== 665 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 666 +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: AlterTableStmt +== 667 +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_5 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 668 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 669 +-- this one has two constraints, similar but not quite the one in the parent, +-- so it gets a new one +-- verify that it works to reattaching a child with multiple candidate +-- constraints +ALTER TABLE fk_partitioned_fk_5 DETACH PARTITION fk_partitioned_fk_5_1 +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: AlterTableStmt +== 670 +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: AlterTableStmt +== 671 +-- verify that attaching a table checks that the existing data satisfies the +-- constraint +CREATE TABLE fk_partitioned_fk_2 (a int, b int) PARTITION BY RANGE (b) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +== 672 +CREATE TABLE fk_partitioned_fk_2_1 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="fk_partitioned_fk_2_1" schema="" table="fk_partitioned_fk_2_1" ctx=DDL +STMT: CreateStmt +== 673 +CREATE TABLE fk_partitioned_fk_2_2 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="fk_partitioned_fk_2_2" schema="" table="fk_partitioned_fk_2_2" ctx=DDL +STMT: CreateStmt +== 674 +INSERT INTO fk_partitioned_fk_2 VALUES (1600, 601), (1600, 1601) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 675 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 + FOR VALUES IN (1600) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 676 +INSERT INTO fk_notpartitioned_pk VALUES (1600, 601), (1600, 1601) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 677 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 + FOR VALUES IN (1600) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 678 +-- leave these tables around intentionally + +-- Verify that attaching a table that's referenced by an existing FK +-- in the parent throws an error +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +STMT: CreateStmt +== 679 +CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITION BY LIST (a) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: CreateStmt +== 680 +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: AlterTableStmt +== 681 +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6 +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: DropStmt +== 682 +-- This case is similar to above, but the referenced relation is one level +-- lower in the hierarchy. This one fails in a different way as the above, +-- because we don't bother to protect against this case explicitly. If the +-- current error stops happening, we'll need to add a better protection. +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) PARTITION BY list (a) +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +STMT: CreateStmt +== 683 +CREATE TABLE fk_partitioned_pk_61 PARTITION OF fk_partitioned_pk_6 FOR VALUES IN (1) +-- +TABLE: name="fk_partitioned_pk_61" schema="" table="fk_partitioned_pk_61" ctx=DDL +STMT: CreateStmt +== 684 +CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_61) PARTITION BY LIST (a) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: CreateStmt +== 685 +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: AlterTableStmt +== 686 +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6 +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: DropStmt +== 687 +-- test the case when the referenced table is owned by a different user +create role regress_other_partitioned_fk_owner +-- +STMT: CreateRoleStmt +== 688 +grant references on fk_notpartitioned_pk to regress_other_partitioned_fk_owner +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: GrantStmt +== 689 +set role regress_other_partitioned_fk_owner +-- +STMT: VariableSetStmt +== 690 +create table other_partitioned_fk(a int, b int) partition by list (a) +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: CreateStmt +== 691 +create table other_partitioned_fk_1 partition of other_partitioned_fk + for values in (2048) +-- +TABLE: name="other_partitioned_fk_1" schema="" table="other_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +== 692 +insert into other_partitioned_fk + select 2048, x from generate_series(1,10) x +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 693 +-- this should fail +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b) +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 694 +-- add the missing keys and retry +reset role +-- +STMT: VariableSetStmt +== 695 +insert into fk_notpartitioned_pk (a, b) + select 2048, x from generate_series(1,10) x +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 696 +set role regress_other_partitioned_fk_owner +-- +STMT: VariableSetStmt +== 697 +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b) +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +== 698 +-- clean up +drop table other_partitioned_fk +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: DropStmt +== 699 +reset role +-- +STMT: VariableSetStmt +== 700 +revoke all on fk_notpartitioned_pk from regress_other_partitioned_fk_owner +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: GrantStmt +== 701 +drop role regress_other_partitioned_fk_owner +-- +STMT: DropRoleStmt +== 702 +|-- +-- Test self-referencing foreign key with partition. +-- This should create only one fk constraint per partition +|-- +CREATE TABLE parted_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint, + FOREIGN KEY (id_abc) REFERENCES parted_self_fk(id) +) +PARTITION BY RANGE (id) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: CreateStmt +== 703 +CREATE TABLE part1_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +) +-- +TABLE: name="part1_self_fk" schema="" table="part1_self_fk" ctx=DDL +STMT: CreateStmt +== 704 +ALTER TABLE parted_self_fk ATTACH PARTITION part1_self_fk FOR VALUES FROM (0) TO (10) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 705 +CREATE TABLE part2_self_fk PARTITION OF parted_self_fk FOR VALUES FROM (10) TO (20) +-- +TABLE: name="part2_self_fk" schema="" table="part2_self_fk" ctx=DDL +STMT: CreateStmt +== 706 +CREATE TABLE part3_self_fk ( -- a partitioned partition + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +) PARTITION BY RANGE (id) +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: CreateStmt +== 707 +CREATE TABLE part32_self_fk PARTITION OF part3_self_fk FOR VALUES FROM (20) TO (30) +-- +TABLE: name="part32_self_fk" schema="" table="part32_self_fk" ctx=DDL +STMT: CreateStmt +== 708 +ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (20) TO (40) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 709 +CREATE TABLE part33_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +) +-- +TABLE: name="part33_self_fk" schema="" table="part33_self_fk" ctx=DDL +STMT: CreateStmt +== 710 +ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40) +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: AlterTableStmt +== 711 +-- verify that this constraint works +INSERT INTO parted_self_fk VALUES (1, NULL), (2, NULL), (3, NULL) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 712 +INSERT INTO parted_self_fk VALUES (10, 1), (11, 2), (12, 3) RETURNING tableoid::regclass +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 713 +INSERT INTO parted_self_fk VALUES (4, 5) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 714 +-- error: referenced doesn't exist +DELETE FROM parted_self_fk WHERE id = 1 RETURNING * +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: DeleteStmt +== 715 +-- error: reference remains + +SELECT cr.relname, co.conname, co.convalidated, + p.conname AS conparent, p.convalidated, cf.relname AS foreignrel +FROM pg_constraint co +JOIN pg_class cr ON cr.oid = co.conrelid +LEFT JOIN pg_class cf ON cf.oid = co.confrelid +LEFT JOIN pg_constraint p ON p.oid = co.conparentid +WHERE co.contype = 'f' AND + cr.oid IN (SELECT relid FROM pg_partition_tree('parted_self_fk')) +ORDER BY cr.relname, co.conname, p.conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "cf"="pg_class" +ALIAS: "co"="pg_constraint" +ALIAS: "cr"="pg_class" +ALIAS: "p"="pg_constraint" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="co" column="contype" +FILTER: schema="" table="cr" column="oid" +STMT: SelectStmt +== 716 +-- detach and re-attach multiple times just to ensure everything is kosher +ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 717 +INSERT INTO part2_self_fk VALUES (16, 9) +-- +TABLE: name="part2_self_fk" schema="" table="part2_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 718 +-- error: referenced doesn't exist +DELETE FROM parted_self_fk WHERE id = 2 RETURNING * +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: DeleteStmt +== 719 +-- error: reference remains + +ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 720 +INSERT INTO parted_self_fk VALUES (16, 9) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 721 +-- error: referenced doesn't exist +DELETE FROM parted_self_fk WHERE id = 3 RETURNING * +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: DeleteStmt +== 722 +-- error: reference remains + +ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 723 +ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 724 +ALTER TABLE parted_self_fk DETACH PARTITION part3_self_fk +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 725 +ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (30) TO (40) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +== 726 +ALTER TABLE part3_self_fk DETACH PARTITION part33_self_fk +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: AlterTableStmt +== 727 +ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40) +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: AlterTableStmt +== 728 +SELECT cr.relname, co.conname, co.convalidated, + p.conname AS conparent, p.convalidated, cf.relname AS foreignrel +FROM pg_constraint co +JOIN pg_class cr ON cr.oid = co.conrelid +LEFT JOIN pg_class cf ON cf.oid = co.confrelid +LEFT JOIN pg_constraint p ON p.oid = co.conparentid +WHERE co.contype = 'f' AND + cr.oid IN (SELECT relid FROM pg_partition_tree('parted_self_fk')) +ORDER BY cr.relname, co.conname, p.conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "cf"="pg_class" +ALIAS: "co"="pg_constraint" +ALIAS: "cr"="pg_class" +ALIAS: "p"="pg_constraint" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="co" column="contype" +FILTER: schema="" table="cr" column="oid" +STMT: SelectStmt +== 729 +-- Leave this table around, for pg_upgrade/pg_dump tests + + +-- Test creating a constraint at the parent that already exists in partitions. +-- There should be no duplicated constraints, and attempts to drop the +-- constraint in partitions should raise appropriate errors. +create schema fkpart0 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (1) + create table fk_part_23 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (2, 3) + partition by list (a) + create table fk_part_23_2 partition of fk_part_23 for values in (2) +-- +STMT: CreateSchemaStmt +== 730 +alter table fkpart0.fk_part add foreign key (a) references fkpart0.pkey +-- +TABLE: name="fkpart0.fk_part" schema="fkpart0" table="fk_part" ctx=DDL +STMT: AlterTableStmt +== 731 +alter table fkpart0.fk_part_1 drop constraint fk_part_1_a_fkey +-- +TABLE: name="fkpart0.fk_part_1" schema="fkpart0" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +== 732 +alter table fkpart0.fk_part_23 drop constraint fk_part_23_a_fkey +-- +TABLE: name="fkpart0.fk_part_23" schema="fkpart0" table="fk_part_23" ctx=DDL +STMT: AlterTableStmt +== 733 +alter table fkpart0.fk_part_23_2 drop constraint fk_part_23_a_fkey +-- +TABLE: name="fkpart0.fk_part_23_2" schema="fkpart0" table="fk_part_23_2" ctx=DDL +STMT: AlterTableStmt +== 734 +create table fkpart0.fk_part_4 partition of fkpart0.fk_part for values in (4) +-- +TABLE: name="fkpart0.fk_part_4" schema="fkpart0" table="fk_part_4" ctx=DDL +STMT: CreateStmt +== 735 +alter table fkpart0.fk_part_4 drop constraint fk_part_a_fkey +-- +TABLE: name="fkpart0.fk_part_4" schema="fkpart0" table="fk_part_4" ctx=DDL +STMT: AlterTableStmt +== 736 +create table fkpart0.fk_part_56 partition of fkpart0.fk_part + for values in (5,6) partition by list (a) +-- +TABLE: name="fkpart0.fk_part_56" schema="fkpart0" table="fk_part_56" ctx=DDL +STMT: CreateStmt +== 737 +create table fkpart0.fk_part_56_5 partition of fkpart0.fk_part_56 + for values in (5) +-- +TABLE: name="fkpart0.fk_part_56_5" schema="fkpart0" table="fk_part_56_5" ctx=DDL +STMT: CreateStmt +== 738 +alter table fkpart0.fk_part_56 drop constraint fk_part_a_fkey +-- +TABLE: name="fkpart0.fk_part_56" schema="fkpart0" table="fk_part_56" ctx=DDL +STMT: AlterTableStmt +== 739 +alter table fkpart0.fk_part_56_5 drop constraint fk_part_a_fkey +-- +TABLE: name="fkpart0.fk_part_56_5" schema="fkpart0" table="fk_part_56_5" ctx=DDL +STMT: AlterTableStmt +== 740 +-- verify that attaching and detaching partitions maintains the right set of +-- triggers +create schema fkpart1 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part for values in (1) partition by list (a) + create table fk_part_1_1 partition of fk_part_1 for values in (1) +-- +STMT: CreateSchemaStmt +== 741 +alter table fkpart1.fk_part add foreign key (a) references fkpart1.pkey +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DDL +STMT: AlterTableStmt +== 742 +insert into fkpart1.fk_part values (1) +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 743 +-- should fail +insert into fkpart1.pkey values (1) +-- +TABLE: name="fkpart1.pkey" schema="fkpart1" table="pkey" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 744 +insert into fkpart1.fk_part values (1) +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 745 +delete from fkpart1.pkey where a = 1 +-- +TABLE: name="fkpart1.pkey" schema="fkpart1" table="pkey" ctx=DML +STMT: DeleteStmt +== 746 +-- should fail +alter table fkpart1.fk_part detach partition fkpart1.fk_part_1 +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DDL +STMT: AlterTableStmt +== 747 +create table fkpart1.fk_part_1_2 partition of fkpart1.fk_part_1 for values in (2) +-- +TABLE: name="fkpart1.fk_part_1_2" schema="fkpart1" table="fk_part_1_2" ctx=DDL +STMT: CreateStmt +== 748 +insert into fkpart1.fk_part_1 values (2) +-- +TABLE: name="fkpart1.fk_part_1" schema="fkpart1" table="fk_part_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 749 +-- should fail +delete from fkpart1.pkey where a = 1 +-- +TABLE: name="fkpart1.pkey" schema="fkpart1" table="pkey" ctx=DML +STMT: DeleteStmt +== 750 +-- verify that attaching and detaching partitions manipulates the inheritance +-- properties of their FK constraints correctly +create schema fkpart2 + create table pkey (a int primary key) + create table fk_part (a int, constraint fkey foreign key (a) references fkpart2.pkey) partition by list (a) + create table fk_part_1 partition of fkpart2.fk_part for values in (1) partition by list (a) + create table fk_part_1_1 (a int, constraint my_fkey foreign key (a) references fkpart2.pkey) +-- +STMT: CreateSchemaStmt +== 751 +alter table fkpart2.fk_part_1 attach partition fkpart2.fk_part_1_1 for values in (1) +-- +TABLE: name="fkpart2.fk_part_1" schema="fkpart2" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +== 752 +alter table fkpart2.fk_part_1 drop constraint fkey +-- +TABLE: name="fkpart2.fk_part_1" schema="fkpart2" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +== 753 +-- should fail +alter table fkpart2.fk_part_1_1 drop constraint my_fkey +-- +TABLE: name="fkpart2.fk_part_1_1" schema="fkpart2" table="fk_part_1_1" ctx=DDL +STMT: AlterTableStmt +== 754 +-- should fail +alter table fkpart2.fk_part detach partition fkpart2.fk_part_1 +-- +TABLE: name="fkpart2.fk_part" schema="fkpart2" table="fk_part" ctx=DDL +STMT: AlterTableStmt +== 755 +alter table fkpart2.fk_part_1 drop constraint fkey +-- +TABLE: name="fkpart2.fk_part_1" schema="fkpart2" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +== 756 +-- ok +alter table fkpart2.fk_part_1_1 drop constraint my_fkey +-- +TABLE: name="fkpart2.fk_part_1_1" schema="fkpart2" table="fk_part_1_1" ctx=DDL +STMT: AlterTableStmt +== 757 +-- doesn't exist + +-- verify constraint deferrability +create schema fkpart3 + create table pkey (a int primary key) + create table fk_part (a int, constraint fkey foreign key (a) references fkpart3.pkey deferrable initially immediate) partition by list (a) + create table fk_part_1 partition of fkpart3.fk_part for values in (1) partition by list (a) + create table fk_part_1_1 partition of fkpart3.fk_part_1 for values in (1) + create table fk_part_2 partition of fkpart3.fk_part for values in (2) +-- +STMT: CreateSchemaStmt +== 758 +begin +-- +STMT: TransactionStmt +== 759 +set constraints fkpart3.fkey deferred +-- +STMT: ConstraintsSetStmt +== 760 +insert into fkpart3.fk_part values (1) +-- +TABLE: name="fkpart3.fk_part" schema="fkpart3" table="fk_part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 761 +insert into fkpart3.pkey values (1) +-- +TABLE: name="fkpart3.pkey" schema="fkpart3" table="pkey" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 762 +commit +-- +STMT: TransactionStmt +== 763 +begin +-- +STMT: TransactionStmt +== 764 +set constraints fkpart3.fkey deferred +-- +STMT: ConstraintsSetStmt +== 765 +delete from fkpart3.pkey +-- +TABLE: name="fkpart3.pkey" schema="fkpart3" table="pkey" ctx=DML +STMT: DeleteStmt +== 766 +delete from fkpart3.fk_part +-- +TABLE: name="fkpart3.fk_part" schema="fkpart3" table="fk_part" ctx=DML +STMT: DeleteStmt +== 767 +commit +-- +STMT: TransactionStmt +== 768 +drop schema fkpart0, fkpart1, fkpart2, fkpart3 cascade +-- +STMT: DropStmt +== 769 +-- Test a partitioned table as referenced table. + +-- Verify basic functionality with a regular partition creation and a partition +-- with a different column layout, as well as partitions added (created and +-- attached) after creating the foreign key. +CREATE SCHEMA fkpart3 +-- +STMT: CreateSchemaStmt +== 770 +SET search_path TO fkpart3 +-- +STMT: VariableSetStmt +== 771 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +== 772 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +== 773 +CREATE TABLE pk2 (b int, a int) +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: CreateStmt +== 774 +ALTER TABLE pk2 DROP COLUMN b +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +== 775 +ALTER TABLE pk2 ALTER a SET NOT NULL +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +== 776 +ALTER TABLE pk ATTACH PARTITION pk2 FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +== 777 +CREATE TABLE fk (a int) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +== 778 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (0) TO (750) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +== 779 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 780 +CREATE TABLE fk2 (b int, a int) +-- +TABLE: name="fk2" schema="" table="fk2" ctx=DDL +STMT: CreateStmt +== 781 +ALTER TABLE fk2 DROP COLUMN b +-- +TABLE: name="fk2" schema="" table="fk2" ctx=DDL +STMT: AlterTableStmt +== 782 +ALTER TABLE fk ATTACH PARTITION fk2 FOR VALUES FROM (750) TO (3500) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 783 +CREATE TABLE pk3 PARTITION OF pk FOR VALUES FROM (2000) TO (3000) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +== 784 +CREATE TABLE pk4 (LIKE pk) +-- +TABLE: name="pk4" schema="" table="pk4" ctx=DDL +STMT: CreateStmt +== 785 +ALTER TABLE pk ATTACH PARTITION pk4 FOR VALUES FROM (3000) TO (4000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +== 786 +CREATE TABLE pk5 (c int, b int, a int NOT NULL) PARTITION BY RANGE (a) +-- +TABLE: name="pk5" schema="" table="pk5" ctx=DDL +STMT: CreateStmt +== 787 +ALTER TABLE pk5 DROP COLUMN b, DROP COLUMN c +-- +TABLE: name="pk5" schema="" table="pk5" ctx=DDL +STMT: AlterTableStmt +== 788 +CREATE TABLE pk51 PARTITION OF pk5 FOR VALUES FROM (4000) TO (4500) +-- +TABLE: name="pk51" schema="" table="pk51" ctx=DDL +STMT: CreateStmt +== 789 +CREATE TABLE pk52 PARTITION OF pk5 FOR VALUES FROM (4500) TO (5000) +-- +TABLE: name="pk52" schema="" table="pk52" ctx=DDL +STMT: CreateStmt +== 790 +ALTER TABLE pk ATTACH PARTITION pk5 FOR VALUES FROM (4000) TO (5000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +== 791 +CREATE TABLE fk3 PARTITION OF fk FOR VALUES FROM (3500) TO (5000) +-- +TABLE: name="fk3" schema="" table="fk3" ctx=DDL +STMT: CreateStmt +== 792 +-- these should fail: referenced value not present +INSERT into fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 793 +INSERT into fk VALUES (1000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 794 +INSERT into fk VALUES (2000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 795 +INSERT into fk VALUES (3000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 796 +INSERT into fk VALUES (4000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 797 +INSERT into fk VALUES (4500) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 798 +-- insert into the referenced table, now they should work +INSERT into pk VALUES (1), (1000), (2000), (3000), (4000), (4500) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 799 +INSERT into fk VALUES (1), (1000), (2000), (3000), (4000), (4500) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 800 +-- should fail: referencing value present +DELETE FROM pk WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 801 +DELETE FROM pk WHERE a = 1000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 802 +DELETE FROM pk WHERE a = 2000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 803 +DELETE FROM pk WHERE a = 3000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 804 +DELETE FROM pk WHERE a = 4000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 805 +DELETE FROM pk WHERE a = 4500 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 806 +UPDATE pk SET a = 2 WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 807 +UPDATE pk SET a = 1002 WHERE a = 1000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 808 +UPDATE pk SET a = 2002 WHERE a = 2000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 809 +UPDATE pk SET a = 3002 WHERE a = 3000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 810 +UPDATE pk SET a = 4002 WHERE a = 4000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 811 +UPDATE pk SET a = 4502 WHERE a = 4500 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 812 +-- now they should work +DELETE FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: DeleteStmt +== 813 +UPDATE pk SET a = 2 WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 814 +DELETE FROM pk WHERE a = 2 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 815 +UPDATE pk SET a = 1002 WHERE a = 1000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 816 +DELETE FROM pk WHERE a = 1002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 817 +UPDATE pk SET a = 2002 WHERE a = 2000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 818 +DELETE FROM pk WHERE a = 2002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 819 +UPDATE pk SET a = 3002 WHERE a = 3000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 820 +DELETE FROM pk WHERE a = 3002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 821 +UPDATE pk SET a = 4002 WHERE a = 4000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 822 +DELETE FROM pk WHERE a = 4002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 823 +UPDATE pk SET a = 4502 WHERE a = 4500 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 824 +DELETE FROM pk WHERE a = 4502 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 825 +-- Also, detaching a partition that has the FK itself should work +-- https://postgr.es/m/CAAJ_b97GuPh6wQPbxQS-Zpy16Oh+0aMv-w64QcGrLhCOZZ6p+g@mail.gmail.com +CREATE TABLE ffk (a int, b int REFERENCES pk) PARTITION BY list (a) +-- +TABLE: name="ffk" schema="" table="ffk" ctx=DDL +STMT: CreateStmt +== 826 +CREATE TABLE ffk1 PARTITION OF ffk FOR VALUES IN (1) +-- +TABLE: name="ffk1" schema="" table="ffk1" ctx=DDL +STMT: CreateStmt +== 827 +ALTER TABLE ffk1 ADD FOREIGN KEY (a) REFERENCES pk +-- +TABLE: name="ffk1" schema="" table="ffk1" ctx=DDL +STMT: AlterTableStmt +== 828 +ALTER TABLE ffk DETACH PARTITION ffk1 +-- +TABLE: name="ffk" schema="" table="ffk" ctx=DDL +STMT: AlterTableStmt +== 829 +DROP TABLE ffk, ffk1 +-- +TABLE: name="ffk" schema="" table="ffk" ctx=DDL +TABLE: name="ffk1" schema="" table="ffk1" ctx=DDL +STMT: DropStmt +== 830 +CREATE SCHEMA fkpart4 +-- +STMT: CreateSchemaStmt +== 831 +SET search_path TO fkpart4 +-- +STMT: VariableSetStmt +== 832 +-- dropping/detaching PARTITIONs is prevented if that would break +-- a foreign key's existing data +CREATE TABLE droppk (a int PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: CreateStmt +== 833 +CREATE TABLE droppk1 PARTITION OF droppk FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="droppk1" schema="" table="droppk1" ctx=DDL +STMT: CreateStmt +== 834 +CREATE TABLE droppk_d PARTITION OF droppk DEFAULT +-- +TABLE: name="droppk_d" schema="" table="droppk_d" ctx=DDL +STMT: CreateStmt +== 835 +CREATE TABLE droppk2 PARTITION OF droppk FOR VALUES FROM (1000) TO (2000) + PARTITION BY RANGE (a) +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: CreateStmt +== 836 +CREATE TABLE droppk21 PARTITION OF droppk2 FOR VALUES FROM (1000) TO (1400) +-- +TABLE: name="droppk21" schema="" table="droppk21" ctx=DDL +STMT: CreateStmt +== 837 +CREATE TABLE droppk2_d PARTITION OF droppk2 DEFAULT +-- +TABLE: name="droppk2_d" schema="" table="droppk2_d" ctx=DDL +STMT: CreateStmt +== 838 +INSERT into droppk VALUES (1), (1000), (1500), (2000) +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 839 +CREATE TABLE dropfk (a int REFERENCES droppk) +-- +TABLE: name="dropfk" schema="" table="dropfk" ctx=DDL +STMT: CreateStmt +== 840 +INSERT into dropfk VALUES (1), (1000), (1500), (2000) +-- +TABLE: name="dropfk" schema="" table="dropfk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 841 +-- these should all fail +ALTER TABLE droppk DETACH PARTITION droppk_d +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: AlterTableStmt +== 842 +ALTER TABLE droppk2 DETACH PARTITION droppk2_d +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: AlterTableStmt +== 843 +ALTER TABLE droppk DETACH PARTITION droppk1 +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: AlterTableStmt +== 844 +ALTER TABLE droppk DETACH PARTITION droppk2 +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: AlterTableStmt +== 845 +ALTER TABLE droppk2 DETACH PARTITION droppk21 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: AlterTableStmt +== 846 +-- dropping partitions is disallowed +DROP TABLE droppk_d +-- +TABLE: name="droppk_d" schema="" table="droppk_d" ctx=DDL +STMT: DropStmt +== 847 +DROP TABLE droppk2_d +-- +TABLE: name="droppk2_d" schema="" table="droppk2_d" ctx=DDL +STMT: DropStmt +== 848 +DROP TABLE droppk1 +-- +TABLE: name="droppk1" schema="" table="droppk1" ctx=DDL +STMT: DropStmt +== 849 +DROP TABLE droppk2 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: DropStmt +== 850 +DROP TABLE droppk21 +-- +TABLE: name="droppk21" schema="" table="droppk21" ctx=DDL +STMT: DropStmt +== 851 +DELETE FROM dropfk +-- +TABLE: name="dropfk" schema="" table="dropfk" ctx=DML +STMT: DeleteStmt +== 852 +-- dropping partitions is disallowed, even when no referencing values +DROP TABLE droppk_d +-- +TABLE: name="droppk_d" schema="" table="droppk_d" ctx=DDL +STMT: DropStmt +== 853 +DROP TABLE droppk2_d +-- +TABLE: name="droppk2_d" schema="" table="droppk2_d" ctx=DDL +STMT: DropStmt +== 854 +DROP TABLE droppk1 +-- +TABLE: name="droppk1" schema="" table="droppk1" ctx=DDL +STMT: DropStmt +== 855 +-- but DETACH is allowed, and DROP afterwards works +ALTER TABLE droppk2 DETACH PARTITION droppk21 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: AlterTableStmt +== 856 +DROP TABLE droppk2 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: DropStmt +== 857 +-- Verify that initial constraint creation and cloning behave correctly +CREATE SCHEMA fkpart5 +-- +STMT: CreateSchemaStmt +== 858 +SET search_path TO fkpart5 +-- +STMT: VariableSetStmt +== 859 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +== 860 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1) PARTITION BY LIST (a) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +== 861 +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1) +-- +TABLE: name="pk11" schema="" table="pk11" ctx=DDL +STMT: CreateStmt +== 862 +CREATE TABLE fk (a int) PARTITION BY LIST (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +== 863 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES IN (1) PARTITION BY LIST (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +== 864 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES IN (1) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +== 865 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 866 +CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (2) +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: CreateStmt +== 867 +CREATE TABLE pk3 (a int NOT NULL) PARTITION BY LIST (a) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +== 868 +CREATE TABLE pk31 PARTITION OF pk3 FOR VALUES IN (31) +-- +TABLE: name="pk31" schema="" table="pk31" ctx=DDL +STMT: CreateStmt +== 869 +CREATE TABLE pk32 (b int, a int NOT NULL) +-- +TABLE: name="pk32" schema="" table="pk32" ctx=DDL +STMT: CreateStmt +== 870 +ALTER TABLE pk32 DROP COLUMN b +-- +TABLE: name="pk32" schema="" table="pk32" ctx=DDL +STMT: AlterTableStmt +== 871 +ALTER TABLE pk3 ATTACH PARTITION pk32 FOR VALUES IN (32) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: AlterTableStmt +== 872 +ALTER TABLE pk ATTACH PARTITION pk3 FOR VALUES IN (31, 32) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +== 873 +CREATE TABLE fk2 PARTITION OF fk FOR VALUES IN (2) +-- +TABLE: name="fk2" schema="" table="fk2" ctx=DDL +STMT: CreateStmt +== 874 +CREATE TABLE fk3 (b int, a int) +-- +TABLE: name="fk3" schema="" table="fk3" ctx=DDL +STMT: CreateStmt +== 875 +ALTER TABLE fk3 DROP COLUMN b +-- +TABLE: name="fk3" schema="" table="fk3" ctx=DDL +STMT: AlterTableStmt +== 876 +ALTER TABLE fk ATTACH PARTITION fk3 FOR VALUES IN (3) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 877 +SELECT pg_describe_object('pg_constraint'::regclass, oid, 0), confrelid::regclass, + CASE WHEN conparentid <> 0 THEN pg_describe_object('pg_constraint'::regclass, conparentid, 0) ELSE 'TOP' END +FROM pg_catalog.pg_constraint +WHERE conrelid IN (SELECT relid FROM pg_partition_tree('fk')) +ORDER BY conrelid::regclass::text, conname +-- +TABLE: name="pg_catalog.pg_constraint" schema="pg_catalog" table="pg_constraint" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 878 +CREATE TABLE fk4 (LIKE fk) +-- +TABLE: name="fk4" schema="" table="fk4" ctx=DDL +STMT: CreateStmt +== 879 +INSERT INTO fk4 VALUES (50) +-- +TABLE: name="fk4" schema="" table="fk4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 880 +ALTER TABLE fk ATTACH PARTITION fk4 FOR VALUES IN (50) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 881 +-- Verify constraint deferrability +CREATE SCHEMA fkpart9 +-- +STMT: CreateSchemaStmt +== 882 +SET search_path TO fkpart9 +-- +STMT: VariableSetStmt +== 883 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +== 884 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1, 2) PARTITION BY LIST (a) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +== 885 +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1) +-- +TABLE: name="pk11" schema="" table="pk11" ctx=DDL +STMT: CreateStmt +== 886 +CREATE TABLE pk3 PARTITION OF pk FOR VALUES IN (3) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +== 887 +CREATE TABLE fk (a int REFERENCES pk DEFERRABLE INITIALLY IMMEDIATE) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +== 888 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 889 +-- should fail +BEGIN +-- +STMT: TransactionStmt +== 890 +SET CONSTRAINTS fk_a_fkey DEFERRED +-- +STMT: ConstraintsSetStmt +== 891 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 892 +COMMIT +-- +STMT: TransactionStmt +== 893 +-- should fail +BEGIN +-- +STMT: TransactionStmt +== 894 +SET CONSTRAINTS fk_a_fkey DEFERRED +-- +STMT: ConstraintsSetStmt +== 895 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 896 +INSERT INTO pk VALUES (1) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 897 +COMMIT +-- +STMT: TransactionStmt +== 898 +-- OK +BEGIN +-- +STMT: TransactionStmt +== 899 +SET CONSTRAINTS fk_a_fkey DEFERRED +-- +STMT: ConstraintsSetStmt +== 900 +DELETE FROM pk WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 901 +DELETE FROM fk WHERE a = 1 +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: DeleteStmt +== 902 +COMMIT +-- +STMT: TransactionStmt +== 903 +-- OK + +-- Verify constraint deferrability when changed by ALTER +-- Partitioned table at referencing end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +== 904 +CREATE TABLE ref(f1 int, f2 int, f3 int) + PARTITION BY list(f1) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +== 905 +CREATE TABLE ref1 PARTITION OF ref FOR VALUES IN (1) +-- +TABLE: name="ref1" schema="" table="ref1" ctx=DDL +STMT: CreateStmt +== 906 +CREATE TABLE ref2 PARTITION OF ref FOR VALUES in (2) +-- +TABLE: name="ref2" schema="" table="ref2" ctx=DDL +STMT: CreateStmt +== 907 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 908 +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 909 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 910 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 911 +BEGIN +-- +STMT: TransactionStmt +== 912 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +== 913 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +== 914 +ABORT +-- +STMT: TransactionStmt +== 915 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +== 916 +-- Multi-level partitioning at referencing end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +== 917 +CREATE TABLE ref(f1 int, f2 int, f3 int) + PARTITION BY list(f1) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +== 918 +CREATE TABLE ref1_2 PARTITION OF ref FOR VALUES IN (1, 2) PARTITION BY list (f2) +-- +TABLE: name="ref1_2" schema="" table="ref1_2" ctx=DDL +STMT: CreateStmt +== 919 +CREATE TABLE ref1 PARTITION OF ref1_2 FOR VALUES IN (1) +-- +TABLE: name="ref1" schema="" table="ref1" ctx=DDL +STMT: CreateStmt +== 920 +CREATE TABLE ref2 PARTITION OF ref1_2 FOR VALUES IN (2) PARTITION BY list (f2) +-- +TABLE: name="ref2" schema="" table="ref2" ctx=DDL +STMT: CreateStmt +== 921 +CREATE TABLE ref22 PARTITION OF ref2 FOR VALUES IN (2) +-- +TABLE: name="ref22" schema="" table="ref22" ctx=DDL +STMT: CreateStmt +== 922 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 923 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 924 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 925 +ALTER TABLE ref22 ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="ref22" schema="" table="ref22" ctx=DDL +STMT: AlterTableStmt +== 926 +-- fails +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 927 +BEGIN +-- +STMT: TransactionStmt +== 928 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +== 929 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +== 930 +ABORT +-- +STMT: TransactionStmt +== 931 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +== 932 +-- Partitioned table at referenced end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) + PARTITION BY LIST(f1) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +== 933 +CREATE TABLE pt1 PARTITION OF pt FOR VALUES IN (1) +-- +TABLE: name="pt1" schema="" table="pt1" ctx=DDL +STMT: CreateStmt +== 934 +CREATE TABLE pt2 PARTITION OF pt FOR VALUES IN (2) +-- +TABLE: name="pt2" schema="" table="pt2" ctx=DDL +STMT: CreateStmt +== 935 +CREATE TABLE ref(f1 int, f2 int, f3 int) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +== 936 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 937 +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 938 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 939 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 940 +BEGIN +-- +STMT: TransactionStmt +== 941 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +== 942 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +== 943 +ABORT +-- +STMT: TransactionStmt +== 944 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +== 945 +-- Multi-level partitioning at referenced end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) + PARTITION BY LIST(f1) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +== 946 +CREATE TABLE pt1_2 PARTITION OF pt FOR VALUES IN (1, 2) PARTITION BY LIST (f1) +-- +TABLE: name="pt1_2" schema="" table="pt1_2" ctx=DDL +STMT: CreateStmt +== 947 +CREATE TABLE pt1 PARTITION OF pt1_2 FOR VALUES IN (1) +-- +TABLE: name="pt1" schema="" table="pt1" ctx=DDL +STMT: CreateStmt +== 948 +CREATE TABLE pt2 PARTITION OF pt1_2 FOR VALUES IN (2) +-- +TABLE: name="pt2" schema="" table="pt2" ctx=DDL +STMT: CreateStmt +== 949 +CREATE TABLE ref(f1 int, f2 int, f3 int) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +== 950 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 951 +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey1 + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 952 +-- fails +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +== 953 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 954 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 955 +BEGIN +-- +STMT: TransactionStmt +== 956 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +== 957 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +== 958 +ABORT +-- +STMT: TransactionStmt +== 959 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +== 960 +DROP SCHEMA fkpart9 CASCADE +-- +STMT: DropStmt +== 961 +-- Verify ON UPDATE/DELETE behavior +CREATE SCHEMA fkpart6 +-- +STMT: CreateSchemaStmt +== 962 +SET search_path TO fkpart6 +-- +STMT: VariableSetStmt +== 963 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +== 964 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +== 965 +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (1) TO (50) +-- +TABLE: name="pk11" schema="" table="pk11" ctx=DDL +STMT: CreateStmt +== 966 +CREATE TABLE pk12 PARTITION OF pk1 FOR VALUES FROM (50) TO (100) +-- +TABLE: name="pk12" schema="" table="pk12" ctx=DDL +STMT: CreateStmt +== 967 +CREATE TABLE fk (a int) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +== 968 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +== 969 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +== 970 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +== 971 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE CASCADE ON DELETE CASCADE +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 972 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +== 973 +INSERT INTO pk VALUES (1) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 974 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 975 +UPDATE pk SET a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 976 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +== 977 +DELETE FROM pk WHERE a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 978 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +== 979 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +== 980 +TRUNCATE TABLE pk +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: TruncateStmt +== 981 +INSERT INTO pk VALUES (20), (50) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 982 +CREATE TABLE fk (a int) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +== 983 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +== 984 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +== 985 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +== 986 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET NULL ON DELETE SET NULL +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 987 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +== 988 +INSERT INTO fk VALUES (20), (50) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 989 +UPDATE pk SET a = 21 WHERE a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 990 +DELETE FROM pk WHERE a = 50 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 991 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +== 992 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +== 993 +TRUNCATE TABLE pk +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: TruncateStmt +== 994 +INSERT INTO pk VALUES (20), (30), (50) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 995 +CREATE TABLE fk (id int, a int DEFAULT 50) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +== 996 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +== 997 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +== 998 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +== 999 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET DEFAULT ON DELETE SET DEFAULT +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 1000 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +== 1001 +INSERT INTO fk VALUES (1, 20), (2, 30) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1002 +DELETE FROM pk WHERE a = 20 RETURNING * +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 1003 +UPDATE pk SET a = 90 WHERE a = 30 RETURNING * +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 1004 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +== 1005 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +== 1006 +TRUNCATE TABLE pk +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: TruncateStmt +== 1007 +INSERT INTO pk VALUES (20), (30) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1008 +CREATE TABLE fk (a int DEFAULT 50) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +== 1009 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +== 1010 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +== 1011 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +== 1012 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE RESTRICT ON DELETE RESTRICT +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +== 1013 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +== 1014 +INSERT INTO fk VALUES (20), (30) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1015 +DELETE FROM pk WHERE a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +== 1016 +UPDATE pk SET a = 90 WHERE a = 30 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +== 1017 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +== 1018 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +== 1019 +-- test for reported bug: relispartition not set +-- https://postgr.es/m/CA+HiwqHMsRtRYRWYTWavKJ8x14AFsv7bmAV46mYwnfD3vy8goQ@mail.gmail.com +CREATE SCHEMA fkpart7 + CREATE TABLE pkpart (a int) PARTITION BY LIST (a) + CREATE TABLE pkpart1 PARTITION OF pkpart FOR VALUES IN (1) +-- +STMT: CreateSchemaStmt +== 1020 +ALTER TABLE fkpart7.pkpart1 ADD PRIMARY KEY (a) +-- +TABLE: name="fkpart7.pkpart1" schema="fkpart7" table="pkpart1" ctx=DDL +STMT: AlterTableStmt +== 1021 +ALTER TABLE fkpart7.pkpart ADD PRIMARY KEY (a) +-- +TABLE: name="fkpart7.pkpart" schema="fkpart7" table="pkpart" ctx=DDL +STMT: AlterTableStmt +== 1022 +CREATE TABLE fkpart7.fk (a int REFERENCES fkpart7.pkpart) +-- +TABLE: name="fkpart7.fk" schema="fkpart7" table="fk" ctx=DDL +STMT: CreateStmt +== 1023 +DROP SCHEMA fkpart7 CASCADE +-- +STMT: DropStmt +== 1024 +-- ensure we check partitions are "not used" when dropping constraints +CREATE SCHEMA fkpart8 + CREATE TABLE tbl1(f1 int PRIMARY KEY) + CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) PARTITION BY RANGE(f1) + CREATE TABLE tbl2_p1 PARTITION OF tbl2 FOR VALUES FROM (minvalue) TO (maxvalue) +-- +STMT: CreateSchemaStmt +== 1025 +INSERT INTO fkpart8.tbl1 VALUES(1) +-- +TABLE: name="fkpart8.tbl1" schema="fkpart8" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1026 +BEGIN +-- +STMT: TransactionStmt +== 1027 +INSERT INTO fkpart8.tbl2 VALUES(1) +-- +TABLE: name="fkpart8.tbl2" schema="fkpart8" table="tbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1028 +ALTER TABLE fkpart8.tbl2 DROP CONSTRAINT tbl2_f1_fkey +-- +TABLE: name="fkpart8.tbl2" schema="fkpart8" table="tbl2" ctx=DDL +STMT: AlterTableStmt +== 1029 +COMMIT +-- +STMT: TransactionStmt +== 1030 +DROP SCHEMA fkpart8 CASCADE +-- +STMT: DropStmt +== 1031 +-- ensure FK referencing a multi-level partitioned table are +-- enforce reference to sub-children. +CREATE SCHEMA fkpart9 + CREATE TABLE pk (a INT PRIMARY KEY) PARTITION BY RANGE (a) + CREATE TABLE fk ( + fk_a INT REFERENCES pk(a) ON DELETE CASCADE + ) + CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (30) TO (50) PARTITION BY RANGE (a) + CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (30) TO (40) +-- +STMT: CreateSchemaStmt +== 1032 +INSERT INTO fkpart9.pk VALUES (35) +-- +TABLE: name="fkpart9.pk" schema="fkpart9" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1033 +INSERT INTO fkpart9.fk VALUES (35) +-- +TABLE: name="fkpart9.fk" schema="fkpart9" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1034 +DELETE FROM fkpart9.pk WHERE a=35 +-- +TABLE: name="fkpart9.pk" schema="fkpart9" table="pk" ctx=DML +STMT: DeleteStmt +== 1035 +SELECT * FROM fkpart9.pk +-- +TABLE: name="fkpart9.pk" schema="fkpart9" table="pk" ctx=Select +STMT: SelectStmt +== 1036 +SELECT * FROM fkpart9.fk +-- +TABLE: name="fkpart9.fk" schema="fkpart9" table="fk" ctx=Select +STMT: SelectStmt +== 1037 +DROP SCHEMA fkpart9 CASCADE +-- +STMT: DropStmt +== 1038 +-- test that ri_Check_Pk_Match() scans the correct partition for a deferred +-- ON DELETE/UPDATE NO ACTION constraint +CREATE SCHEMA fkpart10 + CREATE TABLE tbl1(f1 int PRIMARY KEY) PARTITION BY RANGE(f1) + CREATE TABLE tbl1_p1 PARTITION OF tbl1 FOR VALUES FROM (minvalue) TO (1) + CREATE TABLE tbl1_p2 PARTITION OF tbl1 FOR VALUES FROM (1) TO (maxvalue) + CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) + CREATE TABLE tbl3(f1 int PRIMARY KEY) PARTITION BY RANGE(f1) + CREATE TABLE tbl3_p1 PARTITION OF tbl3 FOR VALUES FROM (minvalue) TO (1) + CREATE TABLE tbl3_p2 PARTITION OF tbl3 FOR VALUES FROM (1) TO (maxvalue) + CREATE TABLE tbl4(f1 int REFERENCES tbl3 DEFERRABLE INITIALLY DEFERRED) +-- +STMT: CreateSchemaStmt +== 1039 +INSERT INTO fkpart10.tbl1 VALUES (0), (1) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1040 +INSERT INTO fkpart10.tbl2 VALUES (0), (1) +-- +TABLE: name="fkpart10.tbl2" schema="fkpart10" table="tbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1041 +INSERT INTO fkpart10.tbl3 VALUES (-2), (-1), (0) +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1042 +INSERT INTO fkpart10.tbl4 VALUES (-2), (-1) +-- +TABLE: name="fkpart10.tbl4" schema="fkpart10" table="tbl4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1043 +BEGIN +-- +STMT: TransactionStmt +== 1044 +DELETE FROM fkpart10.tbl1 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: DeleteStmt +== 1045 +UPDATE fkpart10.tbl1 SET f1 = 2 WHERE f1 = 1 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +== 1046 +INSERT INTO fkpart10.tbl1 VALUES (0), (1) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1047 +COMMIT +-- +STMT: TransactionStmt +== 1048 +-- test that cross-partition updates correctly enforces the foreign key +-- restriction (specifically testing INITIALLY DEFERRED) +BEGIN +-- +STMT: TransactionStmt +== 1049 +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +== 1050 +UPDATE fkpart10.tbl3 SET f1 = f1 * -1 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +== 1051 +INSERT INTO fkpart10.tbl1 VALUES (4) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1052 +COMMIT +-- +STMT: TransactionStmt +== 1053 +BEGIN +-- +STMT: TransactionStmt +== 1054 +UPDATE fkpart10.tbl3 SET f1 = f1 * -1 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +== 1055 +UPDATE fkpart10.tbl3 SET f1 = f1 + 3 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +== 1056 +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +== 1057 +INSERT INTO fkpart10.tbl1 VALUES (0) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1058 +COMMIT +-- +STMT: TransactionStmt +== 1059 +BEGIN +-- +STMT: TransactionStmt +== 1060 +UPDATE fkpart10.tbl3 SET f1 = f1 * -1 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +== 1061 +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +== 1062 +INSERT INTO fkpart10.tbl1 VALUES (0) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1063 +INSERT INTO fkpart10.tbl3 VALUES (-2), (-1) +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1064 +COMMIT +-- +STMT: TransactionStmt +== 1065 +-- test where the updated table now has both an IMMEDIATE and a DEFERRED +-- constraint pointing into it +CREATE TABLE fkpart10.tbl5(f1 int REFERENCES fkpart10.tbl3) +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DDL +STMT: CreateStmt +== 1066 +INSERT INTO fkpart10.tbl5 VALUES (-2), (-1) +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1067 +BEGIN +-- +STMT: TransactionStmt +== 1068 +UPDATE fkpart10.tbl3 SET f1 = f1 * -3 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +== 1069 +COMMIT +-- +STMT: TransactionStmt +== 1070 +-- Now test where the row referenced from the table with an IMMEDIATE +-- constraint stays in place, while those referenced from the table with a +-- DEFERRED constraint don't. +DELETE FROM fkpart10.tbl5 +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DML +STMT: DeleteStmt +== 1071 +INSERT INTO fkpart10.tbl5 VALUES (0) +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1072 +BEGIN +-- +STMT: TransactionStmt +== 1073 +UPDATE fkpart10.tbl3 SET f1 = f1 * -3 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +== 1074 +COMMIT +-- +STMT: TransactionStmt +== 1075 +DROP SCHEMA fkpart10 CASCADE +-- +STMT: DropStmt +== 1076 +-- verify foreign keys are enforced during cross-partition updates, +-- especially on the PK side +CREATE SCHEMA fkpart11 + CREATE TABLE pk (a INT PRIMARY KEY, b text) PARTITION BY LIST (a) + CREATE TABLE fk ( + a INT, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES pk(a) ON UPDATE CASCADE ON DELETE CASCADE + ) + CREATE TABLE fk_parted ( + a INT PRIMARY KEY, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES pk(a) ON UPDATE CASCADE ON DELETE CASCADE + ) PARTITION BY LIST (a) + CREATE TABLE fk_another ( + a INT, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fk_parted (a) ON UPDATE CASCADE ON DELETE CASCADE + ) + CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1, 2) PARTITION BY LIST (a) + CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (3) + CREATE TABLE pk3 PARTITION OF pk FOR VALUES IN (4) + CREATE TABLE fk1 PARTITION OF fk_parted FOR VALUES IN (1, 2) + CREATE TABLE fk2 PARTITION OF fk_parted FOR VALUES IN (3) + CREATE TABLE fk3 PARTITION OF fk_parted FOR VALUES IN (4) +-- +STMT: CreateSchemaStmt +== 1077 +CREATE TABLE fkpart11.pk11 (b text, a int NOT NULL) +-- +TABLE: name="fkpart11.pk11" schema="fkpart11" table="pk11" ctx=DDL +STMT: CreateStmt +== 1078 +ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk11 FOR VALUES IN (1) +-- +TABLE: name="fkpart11.pk1" schema="fkpart11" table="pk1" ctx=DDL +STMT: AlterTableStmt +== 1079 +CREATE TABLE fkpart11.pk12 (b text, c int, a int NOT NULL) +-- +TABLE: name="fkpart11.pk12" schema="fkpart11" table="pk12" ctx=DDL +STMT: CreateStmt +== 1080 +ALTER TABLE fkpart11.pk12 DROP c +-- +TABLE: name="fkpart11.pk12" schema="fkpart11" table="pk12" ctx=DDL +STMT: AlterTableStmt +== 1081 +ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk12 FOR VALUES IN (2) +-- +TABLE: name="fkpart11.pk1" schema="fkpart11" table="pk1" ctx=DDL +STMT: AlterTableStmt +== 1082 +INSERT INTO fkpart11.pk VALUES (1, 'xxx'), (3, 'yyy') +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1083 +INSERT INTO fkpart11.fk VALUES (1), (3) +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1084 +INSERT INTO fkpart11.fk_parted VALUES (1), (3) +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1085 +INSERT INTO fkpart11.fk_another VALUES (1), (3) +-- +TABLE: name="fkpart11.fk_another" schema="fkpart11" table="fk_another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1086 +-- moves 2 rows from one leaf partition to another, with both updates being +-- cascaded to fk and fk_parted. Updates of fk_parted, of which one is +-- cross-partition (3 -> 4), are further cascaded to fk_another. +UPDATE fkpart11.pk SET a = a + 1 RETURNING tableoid::pg_catalog.regclass, * +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +== 1087 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=Select +STMT: SelectStmt +== 1088 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=Select +STMT: SelectStmt +== 1089 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another +-- +TABLE: name="fkpart11.fk_another" schema="fkpart11" table="fk_another" ctx=Select +STMT: SelectStmt +== 1090 +-- let's try with the foreign key pointing at tables in the partition tree +-- that are not the same as the query's target table + +-- 1. foreign key pointing into a non-root ancestor +|-- +-- A cross-partition update on the root table will fail, because we currently +-- can't enforce the foreign keys pointing into a non-leaf partition +ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +== 1091 +DELETE FROM fkpart11.fk WHERE a = 4 +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DML +STMT: DeleteStmt +== 1092 +ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk1 (a) ON UPDATE CASCADE ON DELETE CASCADE +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +== 1093 +UPDATE fkpart11.pk SET a = a - 1 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +== 1094 +-- it's okay though if the non-leaf partition is updated directly +UPDATE fkpart11.pk1 SET a = a - 1 +-- +TABLE: name="fkpart11.pk1" schema="fkpart11" table="pk1" ctx=DML +STMT: UpdateStmt +== 1095 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.pk +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=Select +STMT: SelectStmt +== 1096 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=Select +STMT: SelectStmt +== 1097 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=Select +STMT: SelectStmt +== 1098 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another +-- +TABLE: name="fkpart11.fk_another" schema="fkpart11" table="fk_another" ctx=Select +STMT: SelectStmt +== 1099 +-- 2. foreign key pointing into a single leaf partition +|-- +-- A cross-partition update that deletes from the pointed-to leaf partition +-- is allowed to succeed +ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +== 1100 +ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk11 (a) ON UPDATE CASCADE ON DELETE CASCADE +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +== 1101 +-- will delete (1) from p11 which is cascaded to fk +UPDATE fkpart11.pk SET a = a + 1 WHERE a = 1 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +== 1102 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=Select +STMT: SelectStmt +== 1103 +DROP TABLE fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: DropStmt +== 1104 +-- check that regular and deferrable AR triggers on the PK tables +-- still work as expected +CREATE FUNCTION fkpart11.print_row () RETURNS TRIGGER LANGUAGE plpgsql AS $$ + BEGIN + RAISE NOTICE 'TABLE: %, OP: %, OLD: %, NEW: %', TG_RELNAME, TG_OP, OLD, NEW; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="fkpart11.print_row" function="print_row" schema="fkpart11" ctx=DDL +STMT: CreateFunctionStmt +== 1105 +CREATE TRIGGER trig_upd_pk AFTER UPDATE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DDL +STMT: CreateTrigStmt +== 1106 +CREATE TRIGGER trig_del_pk AFTER DELETE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DDL +STMT: CreateTrigStmt +== 1107 +CREATE TRIGGER trig_ins_pk AFTER INSERT ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DDL +STMT: CreateTrigStmt +== 1108 +CREATE CONSTRAINT TRIGGER trig_upd_fk_parted AFTER UPDATE ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DDL +STMT: CreateTrigStmt +== 1109 +CREATE CONSTRAINT TRIGGER trig_del_fk_parted AFTER DELETE ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DDL +STMT: CreateTrigStmt +== 1110 +CREATE CONSTRAINT TRIGGER trig_ins_fk_parted AFTER INSERT ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DDL +STMT: CreateTrigStmt +== 1111 +UPDATE fkpart11.pk SET a = 3 WHERE a = 4 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +== 1112 +UPDATE fkpart11.pk SET a = 1 WHERE a = 2 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +== 1113 +DROP SCHEMA fkpart11 CASCADE +-- +STMT: DropStmt +== 1114 +-- When a table is attached as partition to a partitioned table that has +-- a foreign key to another partitioned table, it acquires a clone of the +-- FK. Upon detach, this clone is not removed, but instead becomes an +-- independent FK. If it then attaches to the partitioned table again, +-- the FK from the parent "takes over" ownership of the independent FK rather +-- than creating a separate one. +CREATE SCHEMA fkpart12 + CREATE TABLE fk_p ( id int, jd int, PRIMARY KEY(id, jd)) PARTITION BY list (id) + CREATE TABLE fk_p_1 PARTITION OF fk_p FOR VALUES IN (1) PARTITION BY list (jd) + CREATE TABLE fk_p_1_1 PARTITION OF fk_p_1 FOR VALUES IN (1) + CREATE TABLE fk_p_1_2 (x int, y int, jd int NOT NULL, id int NOT NULL) + CREATE TABLE fk_p_2 PARTITION OF fk_p FOR VALUES IN (2) PARTITION BY list (jd) + CREATE TABLE fk_p_2_1 PARTITION OF fk_p_2 FOR VALUES IN (1) + CREATE TABLE fk_p_2_2 PARTITION OF fk_p_2 FOR VALUES IN (2) + CREATE TABLE fk_r_1 ( p_jd int NOT NULL, x int, id int PRIMARY KEY, p_id int NOT NULL) + CREATE TABLE fk_r_2 ( id int PRIMARY KEY, p_id int NOT NULL, p_jd int NOT NULL) PARTITION BY list (id) + CREATE TABLE fk_r_2_1 PARTITION OF fk_r_2 FOR VALUES IN (2, 1) + CREATE TABLE fk_r ( id int PRIMARY KEY, p_id int NOT NULL, p_jd int NOT NULL, + FOREIGN KEY (p_id, p_jd) REFERENCES fk_p (id, jd) + ) PARTITION BY list (id) +-- +STMT: CreateSchemaStmt +== 1115 +SET search_path TO fkpart12 +-- +STMT: VariableSetStmt +== 1116 +ALTER TABLE fk_p_1_2 DROP COLUMN x, DROP COLUMN y +-- +TABLE: name="fk_p_1_2" schema="" table="fk_p_1_2" ctx=DDL +STMT: AlterTableStmt +== 1117 +ALTER TABLE fk_p_1 ATTACH PARTITION fk_p_1_2 FOR VALUES IN (2) +-- +TABLE: name="fk_p_1" schema="" table="fk_p_1" ctx=DDL +STMT: AlterTableStmt +== 1118 +ALTER TABLE fk_r_1 DROP COLUMN x +-- +TABLE: name="fk_r_1" schema="" table="fk_r_1" ctx=DDL +STMT: AlterTableStmt +== 1119 +INSERT INTO fk_p VALUES (1, 1) +-- +TABLE: name="fk_p" schema="" table="fk_p" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1120 +ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +== 1121 +ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +== 1122 +INSERT INTO fk_r VALUES (1, 1, 1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1123 +INSERT INTO fk_r VALUES (2, 2, 1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1124 +ALTER TABLE fk_r DETACH PARTITION fk_r_1 +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +== 1125 +ALTER TABLE fk_r DETACH PARTITION fk_r_2 +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +== 1126 +INSERT INTO fk_r_1 (id, p_id, p_jd) VALUES (2, 1, 2) +-- +TABLE: name="fk_r_1" schema="" table="fk_r_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1127 +-- should fail +DELETE FROM fk_p +-- +TABLE: name="fk_p" schema="" table="fk_p" ctx=DML +STMT: DeleteStmt +== 1128 +-- should fail + +ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +== 1129 +ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +== 1130 +DELETE FROM fk_p +-- +TABLE: name="fk_p" schema="" table="fk_p" ctx=DML +STMT: DeleteStmt +== 1131 +-- should fail + +-- these should all fail +ALTER TABLE fk_r_1 DROP CONSTRAINT fk_r_p_id_p_jd_fkey +-- +TABLE: name="fk_r_1" schema="" table="fk_r_1" ctx=DDL +STMT: AlterTableStmt +== 1132 +ALTER TABLE fk_r DROP CONSTRAINT fk_r_p_id_p_jd_fkey1 +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +== 1133 +ALTER TABLE fk_r_2 DROP CONSTRAINT fk_r_p_id_p_jd_fkey +-- +TABLE: name="fk_r_2" schema="" table="fk_r_2" ctx=DDL +STMT: AlterTableStmt +== 1134 +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +== 1135 +DROP SCHEMA fkpart12 CASCADE +-- +STMT: DropStmt +== 1136 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 1137 +RESET search_path +-- +STMT: VariableSetStmt +== 1138 +-- Exercise the column mapping code with foreign keys. In this test we'll +-- create a partitioned table which has a partition with a dropped column and +-- check to ensure that an UPDATE cascades the changes correctly to the +-- partitioned table. +CREATE SCHEMA fkpart13 +-- +STMT: CreateSchemaStmt +== 1139 +SET search_path TO fkpart13 +-- +STMT: VariableSetStmt +== 1140 +CREATE TABLE fkpart13_t1 (a int PRIMARY KEY) +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DDL +STMT: CreateStmt +== 1141 +CREATE TABLE fkpart13_t2 ( + part_id int PRIMARY KEY, + column_to_drop int, + FOREIGN KEY (part_id) REFERENCES fkpart13_t1 ON UPDATE CASCADE ON DELETE CASCADE +) PARTITION BY LIST (part_id) +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=DDL +STMT: CreateStmt +== 1142 +CREATE TABLE fkpart13_t2_p1 PARTITION OF fkpart13_t2 FOR VALUES IN (1) +-- +TABLE: name="fkpart13_t2_p1" schema="" table="fkpart13_t2_p1" ctx=DDL +STMT: CreateStmt +== 1143 +-- drop the column +ALTER TABLE fkpart13_t2 DROP COLUMN column_to_drop +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=DDL +STMT: AlterTableStmt +== 1144 +-- create a new partition without the dropped column +CREATE TABLE fkpart13_t2_p2 PARTITION OF fkpart13_t2 FOR VALUES IN (2) +-- +TABLE: name="fkpart13_t2_p2" schema="" table="fkpart13_t2_p2" ctx=DDL +STMT: CreateStmt +== 1145 +CREATE TABLE fkpart13_t3 ( + a int NOT NULL, + FOREIGN KEY (a) + REFERENCES fkpart13_t2 + ON UPDATE CASCADE ON DELETE CASCADE +) +-- +TABLE: name="fkpart13_t3" schema="" table="fkpart13_t3" ctx=DDL +STMT: CreateStmt +== 1146 +INSERT INTO fkpart13_t1 (a) VALUES (1) +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1147 +INSERT INTO fkpart13_t2 (part_id) VALUES (1) +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1148 +INSERT INTO fkpart13_t3 (a) VALUES (1) +-- +TABLE: name="fkpart13_t3" schema="" table="fkpart13_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1149 +-- Test a cascading update works correctly with with the dropped column +UPDATE fkpart13_t1 SET a = 2 WHERE a = 1 +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DML +STMT: UpdateStmt +== 1150 +SELECT tableoid::regclass,* FROM fkpart13_t2 +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=Select +STMT: SelectStmt +== 1151 +SELECT tableoid::regclass,* FROM fkpart13_t3 +-- +TABLE: name="fkpart13_t3" schema="" table="fkpart13_t3" ctx=Select +STMT: SelectStmt +== 1152 +-- Exercise code in ExecGetTriggerResultRel() as there's been previous issues +-- with ResultRelInfos being returned with the incorrect ri_RootResultRelInfo +WITH cte AS ( + UPDATE fkpart13_t2_p1 SET part_id = part_id +) UPDATE fkpart13_t1 SET a = 2 WHERE a = 1 +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DML +TABLE: name="fkpart13_t2_p1" schema="" table="fkpart13_t2_p1" ctx=DML +CTE: "cte" +STMT: UpdateStmt +== 1153 +DROP SCHEMA fkpart13 CASCADE +-- +STMT: DropStmt +== 1154 +RESET search_path +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/functional_deps.metadata.json b/parser/testdata/summary/postgres_regress/functional_deps.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/functional_deps.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary/postgres_regress/functional_deps.test b/parser/testdata/summary/postgres_regress/functional_deps.test new file mode 100644 index 0000000..0fc9705 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/functional_deps.test @@ -0,0 +1,395 @@ +== 001 +-- from http://www.depesz.com/index.php/2010/04/19/getting-unique-elements/ + +CREATE TEMP TABLE articles ( + id int CONSTRAINT articles_pkey PRIMARY KEY, + keywords text, + title text UNIQUE NOT NULL, + body text UNIQUE, + created date +) +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TEMP TABLE articles_in_category ( + article_id int, + category_id int, + changed date, + PRIMARY KEY (article_id, category_id) +) +-- +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=DDL +STMT: CreateStmt +== 003 +-- test functional dependencies based on primary keys/unique constraints + +-- base tables + +-- group by primary key (OK) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +== 004 +-- group by unique not null (fail/todo) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY title +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +== 005 +-- group by unique nullable (fail) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY body +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +== 006 +-- group by something else (fail) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY keywords +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +== 007 +-- multiple tables + +-- group by primary key (OK) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a, articles_in_category AS aic +WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138) +GROUP BY a.id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="aic" column="article_id" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +== 008 +-- group by something else (fail) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a, articles_in_category AS aic +WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id, aic.category_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="aic" column="article_id" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +== 009 +-- JOIN syntax + +-- group by left table's primary key (OK) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY a.id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +== 010 +-- group by something else (fail) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id, aic.category_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +== 011 +-- group by right table's (composite) primary key (OK) +SELECT aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.category_id, aic.article_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +== 012 +-- group by right table's partial primary key (fail) +SELECT aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +== 013 +-- example from documentation + +CREATE TEMP TABLE products (product_id int, name text, price numeric) +-- +TABLE: name="products" schema="" table="products" ctx=DDL +STMT: CreateStmt +== 014 +CREATE TEMP TABLE sales (product_id int, units int) +-- +TABLE: name="sales" schema="" table="sales" ctx=DDL +STMT: CreateStmt +== 015 +-- OK +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id, p.name, p.price +-- +TABLE: name="products" schema="" table="products" ctx=Select +TABLE: name="sales" schema="" table="sales" ctx=Select +ALIAS: "p"="products" +ALIAS: "s"="sales" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- fail +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id +-- +TABLE: name="products" schema="" table="products" ctx=Select +TABLE: name="sales" schema="" table="sales" ctx=Select +ALIAS: "p"="products" +ALIAS: "s"="sales" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 017 +ALTER TABLE products ADD PRIMARY KEY (product_id) +-- +TABLE: name="products" schema="" table="products" ctx=DDL +STMT: AlterTableStmt +== 018 +-- OK now +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id +-- +TABLE: name="products" schema="" table="products" ctx=Select +TABLE: name="sales" schema="" table="sales" ctx=Select +ALIAS: "p"="products" +ALIAS: "s"="sales" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- Drupal example, http://drupal.org/node/555530 + +CREATE TEMP TABLE node ( + nid SERIAL, + vid integer NOT NULL default '0', + type varchar(32) NOT NULL default '', + title varchar(128) NOT NULL default '', + uid integer NOT NULL default '0', + status integer NOT NULL default '1', + created integer NOT NULL default '0', + -- snip + PRIMARY KEY (nid, vid) +) +-- +TABLE: name="node" schema="" table="node" ctx=DDL +STMT: CreateStmt +== 020 +CREATE TEMP TABLE users ( + uid integer NOT NULL default '0', + name varchar(60) NOT NULL default '', + pass varchar(32) NOT NULL default '', + -- snip + PRIMARY KEY (uid), + UNIQUE (name) +) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +== 021 +-- OK +SELECT u.uid, u.name FROM node n +INNER JOIN users u ON u.uid = n.uid +WHERE n.type = 'blog' AND n.status = 1 +GROUP BY u.uid, u.name +-- +TABLE: name="node" schema="" table="node" ctx=Select +TABLE: name="users" schema="" table="users" ctx=Select +ALIAS: "n"="node" +ALIAS: "u"="users" +FILTER: schema="" table="n" column="type" +FILTER: schema="" table="n" column="status" +STMT: SelectStmt +== 022 +-- OK +SELECT u.uid, u.name FROM node n +INNER JOIN users u ON u.uid = n.uid +WHERE n.type = 'blog' AND n.status = 1 +GROUP BY u.uid +-- +TABLE: name="node" schema="" table="node" ctx=Select +TABLE: name="users" schema="" table="users" ctx=Select +ALIAS: "n"="node" +ALIAS: "u"="users" +FILTER: schema="" table="n" column="type" +FILTER: schema="" table="n" column="status" +STMT: SelectStmt +== 023 +-- Check views and dependencies + +-- fail +CREATE TEMP VIEW fdv1 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY body +-- +TABLE: name="fdv1" schema="" table="fdv1" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 024 +-- OK +CREATE TEMP VIEW fdv1 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +-- +TABLE: name="fdv1" schema="" table="fdv1" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 025 +-- fail +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +== 026 +DROP VIEW fdv1 +-- +STMT: DropStmt +== 027 +-- multiple dependencies +CREATE TEMP VIEW fdv2 AS +SELECT a.id, a.keywords, a.title, aic.category_id, aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY a.id, aic.category_id, aic.article_id +-- +TABLE: name="fdv2" schema="" table="fdv2" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: ViewStmt +STMT: SelectStmt +== 028 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +== 029 +-- fail +ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey RESTRICT +-- +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=DDL +STMT: AlterTableStmt +== 030 +--fail + +DROP VIEW fdv2 +-- +STMT: DropStmt +== 031 +-- nested queries + +CREATE TEMP VIEW fdv3 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +UNION +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +-- +TABLE: name="fdv3" schema="" table="fdv3" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 032 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +== 033 +-- fail + +DROP VIEW fdv3 +-- +STMT: DropStmt +== 034 +CREATE TEMP VIEW fdv4 AS +SELECT * FROM articles WHERE title IN (SELECT title FROM articles GROUP BY id) +-- +TABLE: name="fdv4" schema="" table="fdv4" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles" schema="" table="articles" ctx=Select +FILTER: schema="" table="" column="title" +STMT: ViewStmt +STMT: SelectStmt +== 035 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +== 036 +-- fail + +DROP VIEW fdv4 +-- +STMT: DropStmt +== 037 +-- prepared query plans: this results in failure on reuse + +PREPARE foo AS + SELECT id, keywords, title, body, created + FROM articles + GROUP BY id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +== 038 +EXECUTE foo +-- +STMT: ExecuteStmt +== 039 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +== 040 +EXECUTE foo +-- +STMT: ExecuteStmt diff --git a/parser/testdata/summary/postgres_regress/generated.metadata.json b/parser/testdata/summary/postgres_regress/generated.metadata.json new file mode 100644 index 0000000..b6ecb7b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/generated.metadata.json @@ -0,0 +1,123 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119" + ] +} diff --git a/parser/testdata/summary/postgres_regress/generated.test b/parser/testdata/summary/postgres_regress/generated.test new file mode 100644 index 0000000..dc40d55 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/generated.test @@ -0,0 +1,699 @@ +== 001 +-- sanity check of system catalog +SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's') +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attgenerated" +STMT: SelectStmt +== 002 +CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED) +-- +TABLE: name="gtest0" schema="" table="gtest0" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DDL +STMT: CreateStmt +== 004 +SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_name LIKE 'gtest_' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 005 +SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.column_column_usage" schema="information_schema" table="column_column_usage" ctx=Select +STMT: SelectStmt +== 006 +-- duplicate generated +CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED) +-- +TABLE: name="gtest_err_1" schema="" table="gtest_err_1" ctx=DDL +STMT: CreateStmt +== 007 +-- references to other generated columns, including self-references +CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED) +-- +TABLE: name="gtest_err_2a" schema="" table="gtest_err_2a" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED) +-- +TABLE: name="gtest_err_2b" schema="" table="gtest_err_2b" ctx=DDL +STMT: CreateStmt +== 009 +-- a whole-row var is a self-reference on steroids, so disallow that too +CREATE TABLE gtest_err_2c (a int PRIMARY KEY, + b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STORED) +-- +TABLE: name="gtest_err_2c" schema="" table="gtest_err_2c" ctx=DDL +STMT: CreateStmt +== 010 +-- invalid reference +CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED) +-- +TABLE: name="gtest_err_3" schema="" table="gtest_err_3" ctx=DDL +STMT: CreateStmt +== 011 +-- generation expression must be immutable +CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED) +-- +TABLE: name="gtest_err_4" schema="" table="gtest_err_4" ctx=DDL +STMT: CreateStmt +== 012 +-- ... but be sure that the immutability test is accurate +CREATE TABLE gtest2 (a int, b text GENERATED ALWAYS AS (a || ' sec') STORED) +-- +TABLE: name="gtest2" schema="" table="gtest2" ctx=DDL +STMT: CreateStmt +== 013 +DROP TABLE gtest2 +-- +TABLE: name="gtest2" schema="" table="gtest2" ctx=DDL +STMT: DropStmt +== 014 +-- cannot have default/identity and generated +CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest_err_5a" schema="" table="gtest_err_5a" ctx=DDL +STMT: CreateStmt +== 015 +CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest_err_5b" schema="" table="gtest_err_5b" ctx=DDL +STMT: CreateStmt +== 016 +-- reference to system column not allowed in generated column +-- (except tableoid, which we test below) +CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED) +-- +TABLE: name="gtest_err_6a" schema="" table="gtest_err_6a" ctx=DDL +STMT: CreateStmt +== 017 +-- various prohibited constructs +CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED) +-- +TABLE: name="gtest_err_7a" schema="" table="gtest_err_7a" ctx=DDL +STMT: CreateStmt +== 018 +CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED) +-- +TABLE: name="gtest_err_7b" schema="" table="gtest_err_7b" ctx=DDL +STMT: CreateStmt +== 019 +CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED) +-- +TABLE: name="gtest_err_7c" schema="" table="gtest_err_7c" ctx=DDL +STMT: CreateStmt +== 020 +CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED) +-- +TABLE: name="gtest_err_7d" schema="" table="gtest_err_7d" ctx=DDL +STMT: CreateStmt +== 021 +-- GENERATED BY DEFAULT not allowed +CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED) +-- +ERROR: for a generated column, GENERATED ALWAYS must be specified +CURSORPOS: 98 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 022 +INSERT INTO gtest1 VALUES (1) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO gtest1 VALUES (2, DEFAULT) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +-- ok +INSERT INTO gtest1 VALUES (3, 33) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +-- error +INSERT INTO gtest1 VALUES (3, 33), (4, 44) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +-- error +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, 44) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +-- error +INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +-- error +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +-- ok + +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 030 +DELETE FROM gtest1 WHERE a >= 3 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: DeleteStmt +== 031 +UPDATE gtest1 SET b = DEFAULT WHERE a = 1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: UpdateStmt +== 032 +UPDATE gtest1 SET b = 11 WHERE a = 1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: UpdateStmt +== 033 +-- error + +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 034 +SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 035 +SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 036 +-- test that overflow error happens on write +INSERT INTO gtest1 VALUES (2000000000) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +SELECT * FROM gtest1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 038 +DELETE FROM gtest1 WHERE a = 2000000000 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: DeleteStmt +== 039 +-- test with joins +CREATE TABLE gtestx (x int, y int) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +== 040 +INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=Select +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +FILTER: schema="" table="gtestx" column="y" +FILTER: schema="" table="gtest1" column="a" +STMT: SelectStmt +== 042 +DROP TABLE gtestx +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: DropStmt +== 043 +-- test UPDATE/DELETE quals +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 044 +UPDATE gtest1 SET a = 3 WHERE b = 4 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: UpdateStmt +== 045 +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 046 +DELETE FROM gtest1 WHERE b = 2 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: DeleteStmt +== 047 +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 048 +-- test MERGE +CREATE TABLE gtestm ( + id int PRIMARY KEY, + f1 int, + f2 int, + f3 int GENERATED ALWAYS AS (f1 * 2) STORED, + f4 int GENERATED ALWAYS AS (f2 * 2) STORED +) +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DDL +STMT: CreateStmt +== 049 +INSERT INTO gtestm VALUES (1, 5, 100) +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +MERGE INTO gtestm t USING (VALUES (1, 10), (2, 20)) v(id, f1) ON t.id = v.id + WHEN MATCHED THEN UPDATE SET f1 = v.f1 + WHEN NOT MATCHED THEN INSERT VALUES (v.id, v.f1, 200) +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DML +ALIAS: "t"="gtestm" +STMT: MergeStmt +STMT: SelectStmt +== 051 +SELECT * FROM gtestm ORDER BY id +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=Select +STMT: SelectStmt +== 052 +DROP TABLE gtestm +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DDL +STMT: DropStmt +== 053 +-- views +CREATE VIEW gtest1v AS SELECT * FROM gtest1 +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DDL +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 054 +SELECT * FROM gtest1v +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=Select +STMT: SelectStmt +== 055 +INSERT INTO gtest1v VALUES (4, 8) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +-- error +INSERT INTO gtest1v VALUES (5, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +-- ok +INSERT INTO gtest1v VALUES (6, 66), (7, 77) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +-- error +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, 77) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +-- error +INSERT INTO gtest1v VALUES (6, 66), (7, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +-- error +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +-- ok + +ALTER VIEW gtest1v ALTER COLUMN b SET DEFAULT 100 +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DDL +STMT: AlterTableStmt +== 062 +INSERT INTO gtest1v VALUES (8, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +-- error +INSERT INTO gtest1v VALUES (8, DEFAULT), (9, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +-- error + +SELECT * FROM gtest1v +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=Select +STMT: SelectStmt +== 065 +DELETE FROM gtest1v WHERE a >= 5 +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: DeleteStmt +== 066 +DROP VIEW gtest1v +-- +STMT: DropStmt +== 067 +-- CTEs +WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +CTE: "foo" +STMT: SelectStmt +== 068 +-- inheritance +CREATE TABLE gtest1_1 () INHERITS (gtest1) +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=DDL +STMT: CreateStmt +== 069 +SELECT * FROM gtest1_1 +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=Select +STMT: SelectStmt +== 070 +INSERT INTO gtest1_1 VALUES (4) +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +SELECT * FROM gtest1_1 +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=Select +STMT: SelectStmt +== 072 +SELECT * FROM gtest1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +== 073 +-- can't have generated column that is a child of normal column +CREATE TABLE gtest_normal (a int, b int) +-- +TABLE: name="gtest_normal" schema="" table="gtest_normal" ctx=DDL +STMT: CreateStmt +== 074 +CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) INHERITS (gtest_normal) +-- +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: CreateStmt +== 075 +-- error +CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: CreateStmt +== 076 +ALTER TABLE gtest_normal_child INHERIT gtest_normal +-- +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: AlterTableStmt +== 077 +-- error +DROP TABLE gtest_normal, gtest_normal_child +-- +TABLE: name="gtest_normal" schema="" table="gtest_normal" ctx=DDL +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: DropStmt +== 078 +-- test inheritance mismatches between parent and child +CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +== 079 +-- error +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +== 080 +-- error +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +== 081 +-- ok, overrides parent + +CREATE TABLE gtestxx_1 (a int NOT NULL, b int) +-- +TABLE: name="gtestxx_1" schema="" table="gtestxx_1" ctx=DDL +STMT: CreateStmt +== 082 +ALTER TABLE gtestxx_1 INHERIT gtest1 +-- +TABLE: name="gtestxx_1" schema="" table="gtestxx_1" ctx=DDL +STMT: AlterTableStmt +== 083 +-- error +CREATE TABLE gtestxx_3 (a int NOT NULL, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtestxx_3" schema="" table="gtestxx_3" ctx=DDL +STMT: CreateStmt +== 084 +ALTER TABLE gtestxx_3 INHERIT gtest1 +-- +TABLE: name="gtestxx_3" schema="" table="gtestxx_3" ctx=DDL +STMT: AlterTableStmt +== 085 +-- ok +CREATE TABLE gtestxx_4 (b int GENERATED ALWAYS AS (a * 2) STORED, a int NOT NULL) +-- +TABLE: name="gtestxx_4" schema="" table="gtestxx_4" ctx=DDL +STMT: CreateStmt +== 086 +ALTER TABLE gtestxx_4 INHERIT gtest1 +-- +TABLE: name="gtestxx_4" schema="" table="gtestxx_4" ctx=DDL +STMT: AlterTableStmt +== 087 +-- ok + +-- test multiple inheritance mismatches +CREATE TABLE gtesty (x int, b int DEFAULT 55) +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: CreateStmt +== 088 +CREATE TABLE gtest1_y () INHERITS (gtest0, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +== 089 +-- error +DROP TABLE gtesty +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: DropStmt +== 090 +CREATE TABLE gtesty (x int, b int) +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: CreateStmt +== 091 +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +== 092 +-- error +DROP TABLE gtesty +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: DropStmt +== 093 +CREATE TABLE gtesty (x int, b int GENERATED ALWAYS AS (x * 22) STORED) +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: CreateStmt +== 094 +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +== 095 +-- error +CREATE TABLE gtest1_y (b int GENERATED ALWAYS AS (x + 1) STORED) INHERITS (gtest1, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +== 096 +-- ok + +-- test correct handling of GENERATED column that's only in child +CREATE TABLE gtestp (f1 int) +-- +TABLE: name="gtestp" schema="" table="gtestp" ctx=DDL +STMT: CreateStmt +== 097 +CREATE TABLE gtestc (f2 int GENERATED ALWAYS AS (f1+1) STORED) INHERITS(gtestp) +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=DDL +STMT: CreateStmt +== 098 +INSERT INTO gtestc values(42) +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +TABLE gtestc +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=Select +STMT: SelectStmt +== 100 +UPDATE gtestp SET f1 = f1 * 10 +-- +TABLE: name="gtestp" schema="" table="gtestp" ctx=DML +STMT: UpdateStmt +== 101 +TABLE gtestc +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=Select +STMT: SelectStmt +== 102 +DROP TABLE gtestp CASCADE +-- +TABLE: name="gtestp" schema="" table="gtestp" ctx=DDL +STMT: DropStmt +== 103 +-- test stored update +CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED) +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=DDL +STMT: CreateStmt +== 104 +INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL) +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +SELECT * FROM gtest3 ORDER BY a +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=Select +STMT: SelectStmt +== 106 +UPDATE gtest3 SET a = 22 WHERE a = 2 +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=DML +STMT: UpdateStmt +== 107 +SELECT * FROM gtest3 ORDER BY a +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=Select +STMT: SelectStmt +== 108 +CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS (a || '+' || a) STORED) +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=DDL +STMT: CreateStmt +== 109 +INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL) +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +SELECT * FROM gtest3a ORDER BY a +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=Select +STMT: SelectStmt +== 111 +UPDATE gtest3a SET a = 'bb' WHERE a = 'b' +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=DML +STMT: UpdateStmt +== 112 +SELECT * FROM gtest3a ORDER BY a +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=Select +STMT: SelectStmt +== 113 +-- COPY +TRUNCATE gtest1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DDL +STMT: TruncateStmt +== 114 +INSERT INTO gtest1 (a) VALUES (1), (2) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +COPY gtest1 TO stdout +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +== 116 +COPY gtest1 (a, b) TO stdout +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +== 117 +COPY gtest1 FROM stdin +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +== 118 +COPY gtest1 (a, b) FROM stdin +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +== 119 +COPY gtest3 (a, b) FROM stdin +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=Select +STMT: CopyStmt diff --git a/parser/testdata/summary/postgres_regress/geometry.metadata.json b/parser/testdata/summary/postgres_regress/geometry.metadata.json new file mode 100644 index 0000000..4e31a92 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/geometry.metadata.json @@ -0,0 +1,166 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162" + ] +} diff --git a/parser/testdata/summary/postgres_regress/geometry.test b/parser/testdata/summary/postgres_regress/geometry.test new file mode 100644 index 0000000..0535464 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/geometry.test @@ -0,0 +1,1570 @@ +== 001 +|-- +-- GEOMETRY +|-- + +-- Back off displayed precision a little bit to reduce platform-to-platform +-- variation in results. +SET extra_float_digits TO -3 +-- +STMT: VariableSetStmt +== 002 +|-- +-- Points +|-- + +SELECT center(f1) AS center + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="center" function="center" schema="" ctx=Call +STMT: SelectStmt +== 003 +SELECT (@@ f1) AS center + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +STMT: SelectStmt +== 004 +SELECT point(f1) AS center + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT (@@ f1) AS center + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +STMT: SelectStmt +== 006 +SELECT (@@ f1) AS center + FROM POLYGON_TBL + WHERE (# f1) > 2 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 007 +-- "is horizontal" function +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE ishorizontal(p1.f1, point '(0,0)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FUNCTION: name="ishorizontal" function="ishorizontal" schema="" ctx=Call +FUNCTION: name="ishorizontal" function="ishorizontal" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 008 +-- "is horizontal" operator +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE p1.f1 ?- point '(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 009 +-- "is vertical" function +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE isvertical(p1.f1, point '(5.1,34.5)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FUNCTION: name="isvertical" function="isvertical" schema="" ctx=Call +FUNCTION: name="isvertical" function="isvertical" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 010 +-- "is vertical" operator +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE p1.f1 ?| point '(5.1,34.5)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 011 +-- Slope +SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FUNCTION: name="slope" function="slope" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- Add point +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +STMT: SelectStmt +== 013 +-- Subtract point +SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +STMT: SelectStmt +== 014 +-- Multiply with point +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 015 +-- Underflow error +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] < 1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 016 +-- Divide by point +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 017 +-- Overflow error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] > 1000 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 018 +-- Division by 0 error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1 ~= '(0,0)'::point +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 019 +-- Distance to line +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TBL p, LINE_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 020 +-- Distance to line segment +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TBL p, LSEG_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 021 +-- Distance to box +SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT_TBL p, BOX_TBL b +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 022 +-- Distance to path +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp FROM POINT_TBL p, PATH_TBL p1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "p1"="path_tbl" +STMT: SelectStmt +== 023 +-- Distance to polygon +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp FROM POINT_TBL p, POLYGON_TBL p1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "p1"="polygon_tbl" +STMT: SelectStmt +== 024 +-- Construct line through two points +SELECT p1.f1, p2.f1, line(p1.f1, p2.f1) + FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1 <> p2.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FUNCTION: name="line" function="line" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 025 +-- Closest point to line +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 026 +-- Closest point to line segment +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 027 +-- Closest point to box +SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 028 +-- On line +SELECT p.f1, l.s FROM POINT_TBL p, LINE_TBL l WHERE p.f1 <@ l.s +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +FILTER: schema="" table="l" column="s" +STMT: SelectStmt +== 029 +-- On line segment +SELECT p.f1, l.s FROM POINT_TBL p, LSEG_TBL l WHERE p.f1 <@ l.s +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +FILTER: schema="" table="l" column="s" +STMT: SelectStmt +== 030 +-- On path +SELECT p.f1, p1.f1 FROM POINT_TBL p, PATH_TBL p1 WHERE p.f1 <@ p1.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "p1"="path_tbl" +FILTER: schema="" table="p" column="f1" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 031 +|-- +-- Lines +|-- + +-- Vertical +SELECT s FROM LINE_TBL WHERE ?| s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +== 032 +-- Horizontal +SELECT s FROM LINE_TBL WHERE ?- s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +== 033 +-- Same as line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s = l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 034 +-- Parallel to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?|| l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 035 +-- Perpendicular to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?-| l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 036 +-- Distance to line +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +STMT: SelectStmt +== 037 +-- Intersect with line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 038 +-- Intersect with box +SELECT l.s, b.f1 FROM LINE_TBL l, BOX_TBL b WHERE l.s ?# b.f1 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="line_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 039 +-- Intersection point with line +SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +STMT: SelectStmt +== 040 +-- Closest point to line segment +SELECT l.s, l1.s, l.s ## l1.s FROM LINE_TBL l, LSEG_TBL l1 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "l1"="lseg_tbl" +STMT: SelectStmt +== 041 +|-- +-- Line segments +|-- + +-- intersection +SELECT p.f1, l.s, l.s # p.f1 AS intersection + FROM LSEG_TBL l, POINT_TBL p +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 042 +-- Length +SELECT s, @-@ s FROM LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +== 043 +-- Vertical +SELECT s FROM LSEG_TBL WHERE ?| s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +== 044 +-- Horizontal +SELECT s FROM LSEG_TBL WHERE ?- s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +== 045 +-- Center +SELECT s, @@ s FROM LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +== 046 +-- To point +SELECT s, s::point FROM LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +== 047 +-- Has points less than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s < l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 048 +-- Has points less than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s <= l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 049 +-- Has points equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s = l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 050 +-- Has points greater than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s >= l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 051 +-- Has points greater than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s > l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 052 +-- Has points not equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s != l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 053 +-- Parallel with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?|| l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 054 +-- Perpendicular with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?-| l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +== 055 +-- Distance to line +SELECT l.s, l1.s, l.s <-> l1.s AS dist_sl, l1.s <-> l.s AS dist_ls FROM LSEG_TBL l, LINE_TBL l1 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "l1"="line_tbl" +STMT: SelectStmt +== 056 +-- Distance to line segment +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LSEG_TBL l1, LSEG_TBL l2 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +STMT: SelectStmt +== 057 +-- Distance to box +SELECT l.s, b.f1, l.s <-> b.f1 AS dist_sb, b.f1 <-> l.s AS dist_bs FROM LSEG_TBL l, BOX_TBL b +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +STMT: SelectStmt +== 058 +-- Intersect with line segment +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s ?# l1.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "l1"="line_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="l1" column="s" +STMT: SelectStmt +== 059 +-- Intersect with box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s ?# b.f1 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 060 +-- Intersection point with line segment +SELECT l1.s, l2.s, l1.s # l2.s FROM LSEG_TBL l1, LSEG_TBL l2 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +STMT: SelectStmt +== 061 +-- Closest point to line segment +SELECT l1.s, l2.s, l1.s ## l2.s FROM LSEG_TBL l1, LSEG_TBL l2 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +STMT: SelectStmt +== 062 +-- Closest point to box +SELECT l.s, b.f1, l.s ## b.f1 FROM LSEG_TBL l, BOX_TBL b +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +STMT: SelectStmt +== 063 +-- On line +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s <@ l1.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "l1"="line_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="l1" column="s" +STMT: SelectStmt +== 064 +-- On box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s <@ b.f1 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +== 065 +|-- +-- Boxes +|-- + +SELECT box(f1) AS box FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +STMT: SelectStmt +== 066 +-- translation +SELECT b.f1 + p.f1 AS translation + FROM BOX_TBL b, POINT_TBL p +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 067 +SELECT b.f1 - p.f1 AS translation + FROM BOX_TBL b, POINT_TBL p +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 068 +-- Multiply with point +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 069 +-- Overflow error +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] > 1000 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 070 +-- Divide by point +SELECT b.f1, p.f1, b.f1 / p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 071 +-- To box +SELECT f1::box + FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 072 +SELECT bound_box(a.f1, b.f1) + FROM BOX_TBL a, BOX_TBL b +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "a"="box_tbl" +ALIAS: "b"="box_tbl" +FUNCTION: name="bound_box" function="bound_box" schema="" ctx=Call +STMT: SelectStmt +== 073 +-- Below box +SELECT b1.f1, b2.f1, b1.f1 <^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +== 074 +-- Above box +SELECT b1.f1, b2.f1, b1.f1 >^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +== 075 +-- Intersection point with box +SELECT b1.f1, b2.f1, b1.f1 # b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +== 076 +-- Diagonal +SELECT f1, diagonal(f1) FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="diagonal" function="diagonal" schema="" ctx=Call +STMT: SelectStmt +== 077 +-- Distance to box +SELECT b1.f1, b2.f1, b1.f1 <-> b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +== 078 +|-- +-- Paths +|-- + +-- Points +SELECT f1, npoints(f1) FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="npoints" function="npoints" schema="" ctx=Call +STMT: SelectStmt +== 079 +-- Area +SELECT f1, area(f1) FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="area" function="area" schema="" ctx=Call +STMT: SelectStmt +== 080 +-- Length +SELECT f1, @-@ f1 FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +STMT: SelectStmt +== 081 +-- To polygon +SELECT f1, f1::polygon FROM PATH_TBL WHERE isclosed(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 082 +-- Open path cannot be converted to polygon error +SELECT f1, f1::polygon FROM PATH_TBL WHERE isopen(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 083 +-- Has points less than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 < p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 084 +-- Has points less than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 <= p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 085 +-- Has points equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 = p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 086 +-- Has points greater than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 >= p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 087 +-- Has points greater than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 > p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 088 +-- Add path +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM PATH_TBL p1, PATH_TBL p2 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +STMT: SelectStmt +== 089 +-- Add point +SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +STMT: SelectStmt +== 090 +-- Subtract point +SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +STMT: SelectStmt +== 091 +-- Multiply with point +SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +STMT: SelectStmt +== 092 +-- Divide by point +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 093 +-- Division by 0 error +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1 ~= '(0,0)'::point +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +== 094 +-- Distance to path +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM PATH_TBL p1, PATH_TBL p2 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +STMT: SelectStmt +== 095 +|-- +-- Polygons +|-- + +-- containment +SELECT p.f1, poly.f1, poly.f1 @> p.f1 AS contains + FROM POLYGON_TBL poly, POINT_TBL p +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "poly"="polygon_tbl" +STMT: SelectStmt +== 096 +SELECT p.f1, poly.f1, p.f1 <@ poly.f1 AS contained + FROM POLYGON_TBL poly, POINT_TBL p +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "poly"="polygon_tbl" +STMT: SelectStmt +== 097 +SELECT npoints(f1) AS npoints, f1 AS polygon + FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="npoints" function="npoints" schema="" ctx=Call +STMT: SelectStmt +== 098 +SELECT polygon(f1) + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +STMT: SelectStmt +== 099 +SELECT polygon(f1) + FROM PATH_TBL WHERE isclosed(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 100 +SELECT f1 AS open_path, polygon( pclose(f1)) AS polygon + FROM PATH_TBL + WHERE isopen(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FUNCTION: name="pclose" function="pclose" schema="" ctx=Call +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 101 +-- To box +SELECT f1, f1::box FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +STMT: SelectStmt +== 102 +-- To path +SELECT f1, f1::path FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +STMT: SelectStmt +== 103 +-- Same as polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 ~= p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 104 +-- Contained by polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <@ p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 105 +-- Contains polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 @> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 106 +-- Overlap with polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 && p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 107 +-- Left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 << p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 108 +-- Overlap of left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &< p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 109 +-- Right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 >> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 110 +-- Overlap of right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 111 +-- Below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <<| p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 112 +-- Overlap or below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &<| p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 113 +-- Above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |>> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 114 +-- Overlap or above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |&> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 115 +-- Distance to polygon +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +STMT: SelectStmt +== 116 +|-- +-- Circles +|-- + +SELECT circle(f1, 50.0) + FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: SelectStmt +== 117 +SELECT circle(f1) + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: SelectStmt +== 118 +SELECT circle(f1) + FROM POLYGON_TBL + WHERE (# f1) >= 3 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 119 +SELECT c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS distance + FROM CIRCLE_TBL c1, POINT_TBL p1 + WHERE (p1.f1 <-> c1.f1) > 0 + ORDER BY distance, area(c1.f1), p1.f1[0] +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "p1"="point_tbl" +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="c1" column="f1" +STMT: SelectStmt +== 120 +-- To polygon +SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 121 +-- To polygon with less points +SELECT f1, polygon(8, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 122 +-- Error for insufficient number of points +SELECT f1, polygon(1, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 123 +-- Zero radius error +SELECT f1, polygon(10, f1) FROM CIRCLE_TBL WHERE f1 < '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 124 +-- Same as circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 ~= c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 125 +-- Overlap with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 && c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 126 +-- Overlap or left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &< c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 127 +-- Left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 << c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 128 +-- Right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 129 +-- Overlap or right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 130 +-- Contained by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <@ c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 131 +-- Contain by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 @> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 132 +-- Below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <<| c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 133 +-- Above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |>> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 134 +-- Overlap or below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &<| c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 135 +-- Overlap or above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |&> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 136 +-- Area equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 = c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 137 +-- Area not equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 != c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 138 +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 139 +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 > c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 140 +-- Area less than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <= c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 141 +-- Area greater than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >= c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 142 +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 143 +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +== 144 +-- Add point +SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 145 +-- Subtract point +SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 146 +-- Multiply with point +SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 147 +-- 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 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 148 +-- Overflow error +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] > 1000 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 149 +-- 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 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 150 +-- Distance to polygon +SELECT c.f1, p.f1, c.f1 <-> p.f1 FROM CIRCLE_TBL c, POLYGON_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="polygon_tbl" +STMT: SelectStmt +== 151 +-- Check index behavior for circles + +CREATE INDEX gcircleind ON circle_tbl USING gist (f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DDL +STMT: IndexStmt +== 152 +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 153 +EXPLAIN (COSTS OFF) +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 154 +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 155 +-- Check index behavior for polygons + +CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1) +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DDL +STMT: IndexStmt +== 156 +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0] +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="poly_center" function="poly_center" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 157 +EXPLAIN (COSTS OFF) +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0] +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="poly_center" function="poly_center" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 158 +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0] +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="poly_center" function="poly_center" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 159 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('(1', 'circle') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 160 +SELECT * FROM pg_input_error_info('1,', 'circle') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 161 +SELECT pg_input_is_valid('(1,2),-1', 'circle') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 162 +SELECT * FROM pg_input_error_info('(1,2),-1', 'circle') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/gin.metadata.json b/parser/testdata/summary/postgres_regress/gin.metadata.json new file mode 100644 index 0000000..f53b7f4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/gin.metadata.json @@ -0,0 +1,63 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059" + ] +} diff --git a/parser/testdata/summary/postgres_regress/gin.test b/parser/testdata/summary/postgres_regress/gin.test new file mode 100644 index 0000000..f2ecfca --- /dev/null +++ b/parser/testdata/summary/postgres_regress/gin.test @@ -0,0 +1,438 @@ +== 001 +|-- +-- Test GIN indexes. +|-- +-- There are other tests to test different GIN opclasses. This is for testing +-- GIN itself. + +-- Create and populate a test table with a GIN index. +create table gin_test_tbl(i int4[]) with (autovacuum_enabled = off) +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: CreateStmt +== 002 +create index gin_test_idx on gin_test_tbl using gin (i) + with (fastupdate = on, gin_pending_list_limit = 4096) +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: IndexStmt +== 003 +insert into gin_test_tbl select array[1, 2, g] from generate_series(1, 20000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 004 +insert into gin_test_tbl select array[1, 3, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 005 +select gin_clean_pending_list('gin_test_idx')>10 as many +-- +FUNCTION: name="gin_clean_pending_list" function="gin_clean_pending_list" schema="" ctx=Call +STMT: SelectStmt +== 006 +-- flush the fastupdate buffers + +insert into gin_test_tbl select array[3, 1, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 007 +vacuum gin_test_tbl +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: VacuumStmt +== 008 +-- flush the fastupdate buffers + +select gin_clean_pending_list('gin_test_idx') +-- +FUNCTION: name="gin_clean_pending_list" function="gin_clean_pending_list" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- nothing to flush + +-- Test vacuuming +delete from gin_test_tbl where i @> array[2] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +STMT: DeleteStmt +== 010 +vacuum gin_test_tbl +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: VacuumStmt +== 011 +-- Disable fastupdate, and do more insertions. With fastupdate enabled, most +-- insertions (by flushing the list pages) cause page splits. Without +-- fastupdate, we get more churn in the GIN data leaf pages, and exercise the +-- recompression codepaths. +alter index gin_test_idx set (fastupdate = off) +-- +STMT: AlterTableStmt +== 012 +insert into gin_test_tbl select array[1, 2, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 013 +insert into gin_test_tbl select array[1, 3, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 014 +delete from gin_test_tbl where i @> array[2] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +STMT: DeleteStmt +== 015 +vacuum gin_test_tbl +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: VacuumStmt +== 016 +-- Test for "rare && frequent" searches +explain (costs off) +select count(*) from gin_test_tbl where i @> array[1, 999] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 017 +select count(*) from gin_test_tbl where i @> array[1, 999] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 018 +-- Very weak test for gin_fuzzy_search_limit +set gin_fuzzy_search_limit = 1000 +-- +STMT: VariableSetStmt +== 019 +explain (costs off) +select count(*) > 0 as ok from gin_test_tbl where i @> array[1] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 020 +select count(*) > 0 as ok from gin_test_tbl where i @> array[1] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 021 +reset gin_fuzzy_search_limit +-- +STMT: VariableSetStmt +== 022 +-- Test optimization of empty queries +create temp table t_gin_test_tbl(i int4[], j int4[]) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: CreateStmt +== 023 +create index on t_gin_test_tbl using gin (i, j) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: IndexStmt +== 024 +insert into t_gin_test_tbl +values + (null, null), + ('{}', null), + ('{1}', null), + ('{1,2}', null), + (null, '{}'), + (null, '{10}'), + ('{1,2}', '{10}'), + ('{2}', '{10}'), + ('{1,3}', '{}'), + ('{1,1}', '{10}') +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 026 +explain (costs off) +select * from t_gin_test_tbl where array[0] <@ i +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 027 +select * from t_gin_test_tbl where array[0] <@ i +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 028 +select * from t_gin_test_tbl where array[0] <@ i and '{}'::int4[] <@ j +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 029 +explain (costs off) +select * from t_gin_test_tbl where i @> '{}' +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 030 +select * from t_gin_test_tbl where i @> '{}' +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 031 +create function explain_query_json(query_sql text) +returns table (explain_line json) +language plpgsql as +$$ +begin + set enable_seqscan = off; + set enable_bitmapscan = on; + return query execute 'EXPLAIN (ANALYZE, FORMAT json) ' || query_sql; +end; +$$ +-- +FUNCTION: name="explain_query_json" function="explain_query_json" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +create function execute_text_query_index(query_sql text) +returns setof text +language plpgsql +as +$$ +begin + set enable_seqscan = off; + set enable_bitmapscan = on; + return query execute query_sql; +end; +$$ +-- +FUNCTION: name="execute_text_query_index" function="execute_text_query_index" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 033 +create function execute_text_query_heap(query_sql text) +returns setof text +language plpgsql +as +$$ +begin + set enable_seqscan = on; + set enable_bitmapscan = off; + return query execute query_sql; +end; +$$ +-- +FUNCTION: name="execute_text_query_heap" function="execute_text_query_heap" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 034 +-- check number of rows returned by index and removed by recheck +select + query, + js->0->'Plan'->'Plans'->0->'Actual Rows' as "return by index", + js->0->'Plan'->'Rows Removed by Index Recheck' as "removed by recheck", + (res_index = res_heap) as "match" +from + (values + ($$ i @> '{}' $$), + ($$ j @> '{}' $$), + ($$ i @> '{}' and j @> '{}' $$), + ($$ i @> '{1}' $$), + ($$ i @> '{1}' and j @> '{}' $$), + ($$ i @> '{1}' and i @> '{}' and j @> '{}' $$), + ($$ j @> '{10}' $$), + ($$ j @> '{10}' and i @> '{}' $$), + ($$ j @> '{10}' and j @> '{}' and i @> '{}' $$), + ($$ i @> '{1}' and j @> '{10}' $$) + ) q(query), + 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 +-- +FUNCTION: name="explain_query_json" function="explain_query_json" schema="" ctx=Call +FUNCTION: name="execute_text_query_index" function="execute_text_query_index" schema="" ctx=Call +FUNCTION: name="execute_text_query_heap" function="execute_text_query_heap" schema="" ctx=Call +STMT: SelectStmt +== 035 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 036 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 037 +-- 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 +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 038 +select gin_clean_pending_list('t_gin_test_tbl_i_j_idx') is not null +-- +FUNCTION: name="gin_clean_pending_list" function="gin_clean_pending_list" schema="" ctx=Call +STMT: SelectStmt +== 039 +analyze t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: VacuumStmt +== 040 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 041 +set enable_bitmapscan = on +-- +STMT: VariableSetStmt +== 042 +explain (costs off) +select count(*) from t_gin_test_tbl where j @> array[50] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +select count(*) from t_gin_test_tbl where j @> array[50] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 044 +explain (costs off) +select count(*) from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +== 045 +select count(*) from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 046 +explain (costs off) +select count(*) from t_gin_test_tbl where j @> '{}'::int[] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +== 047 +select count(*) from t_gin_test_tbl where j @> '{}'::int[] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 048 +-- test vacuuming of posting trees +delete from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +STMT: DeleteStmt +== 049 +vacuum t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: VacuumStmt +== 050 +select count(*) from t_gin_test_tbl where j @> array[50] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 051 +select count(*) from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 052 +select count(*) from t_gin_test_tbl where j @> '{}'::int[] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 053 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 054 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 055 +drop table t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: DropStmt +== 056 +-- test an unlogged table, mostly to get coverage of ginbuildempty +create unlogged table t_gin_test_tbl(i int4[], j int4[]) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: CreateStmt +== 057 +create index on t_gin_test_tbl using gin (i, j) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: IndexStmt +== 058 +insert into t_gin_test_tbl +values + (null, null), + ('{}', null), + ('{1}', '{2,3}') +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +drop table t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/gist.metadata.json b/parser/testdata/summary/postgres_regress/gist.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/gist.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary/postgres_regress/gist.test b/parser/testdata/summary/postgres_regress/gist.test new file mode 100644 index 0000000..6d1c097 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/gist.test @@ -0,0 +1,584 @@ +== 001 +|-- +-- Test GiST indexes. +|-- +-- There are other tests to test different GiST opclasses. This is for +-- testing GiST code itself. Vacuuming in particular. + +create table gist_point_tbl(id int4, p point) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: CreateStmt +== 002 +create index gist_pointidx on gist_point_tbl using gist(p) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +== 003 +-- Verify the fillfactor and buffering options +create index gist_pointidx2 on gist_point_tbl using gist(p) with (buffering = on, fillfactor=50) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +== 004 +create index gist_pointidx3 on gist_point_tbl using gist(p) with (buffering = off) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +== 005 +create index gist_pointidx4 on gist_point_tbl using gist(p) with (buffering = auto) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +== 006 +drop index gist_pointidx2, gist_pointidx3, gist_pointidx4 +-- +STMT: DropStmt +== 007 +-- Make sure bad values are refused +create index gist_pointidx5 on gist_point_tbl using gist(p) with (buffering = invalid_value) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +== 008 +create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=9) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +== 009 +create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=101) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +== 010 +-- Insert enough data to create a tree that's a couple of levels deep. +insert into gist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10000) g +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 011 +insert into gist_point_tbl (id, p) +select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 012 +-- To test vacuum, delete some entries from all over the index. +delete from gist_point_tbl where id % 2 = 1 +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +STMT: DeleteStmt +== 013 +-- And also delete some concentration of values. +delete from gist_point_tbl where id > 5000 +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +STMT: DeleteStmt +== 014 +vacuum analyze gist_point_tbl +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: VacuumStmt +== 015 +-- rebuild the index with a different fillfactor +alter index gist_pointidx SET (fillfactor = 40) +-- +STMT: AlterTableStmt +== 016 +reindex index gist_pointidx +-- +STMT: ReindexStmt +== 017 +|-- +-- Test Index-only plans on GiST indexes +|-- + +create table gist_tbl (b box, p point, c circle) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: CreateStmt +== 018 +insert into gist_tbl +select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), + point(0.05*i, 0.05*i), + circle(point(0.05*i, 0.05*i), 1.0) +from generate_series(0,10000) as i +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 019 +vacuum analyze gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: VacuumStmt +== 020 +set enable_seqscan=off +-- +STMT: VariableSetStmt +== 021 +set enable_bitmapscan=off +-- +STMT: VariableSetStmt +== 022 +set enable_indexonlyscan=on +-- +STMT: VariableSetStmt +== 023 +-- Test index-only scan with point opclass +create index gist_tbl_point_index on gist_tbl using gist (p) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +== 024 +-- check that the planner chooses an index-only scan +explain (costs off) +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 025 +-- execute the same +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 026 +-- Also test an index-only knn-search +explain (costs off) +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by p <-> point(0.201, 0.201) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 027 +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by p <-> point(0.201, 0.201) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 028 +-- Check commuted case as well +explain (costs off) +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by point(0.101, 0.101) <-> p +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 029 +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by point(0.101, 0.101) <-> p +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 030 +-- Check case with multiple rescans (bug #14641) +explain (costs off) +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +FILTER: schema="" table="" column="bb" +STMT: ExplainStmt +STMT: SelectStmt +== 031 +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +FILTER: schema="" table="" column="bb" +STMT: SelectStmt +== 032 +drop index gist_tbl_point_index +-- +STMT: DropStmt +== 033 +-- Test index-only scan with box opclass +create index gist_tbl_box_index on gist_tbl using gist (b) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +== 034 +-- check that the planner chooses an index-only scan +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 035 +-- execute the same +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 036 +-- Also test an index-only knn-search +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 037 +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 038 +-- Check commuted case as well +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 040 +drop index gist_tbl_box_index +-- +STMT: DropStmt +== 041 +-- Test that an index-only scan is not chosen, when the query involves the +-- circle column (the circle opclass does not support index-only scans). +create index gist_tbl_multi_index on gist_tbl using gist (p, c) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +== 042 +explain (costs off) +select p, c from gist_tbl +where p <@ box(point(5,5), point(6, 6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +-- execute the same +select b, p from gist_tbl +where b <@ box(point(4.5, 4.5), point(5.5, 5.5)) +and p <@ box(point(5,5), point(6, 6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 044 +drop index gist_tbl_multi_index +-- +STMT: DropStmt +== 045 +-- Test that we don't try to return the value of a non-returnable +-- column in an index-only scan. (This isn't GIST-specific, but +-- it only applies to index AMs that can return some columns and not +-- others, so GIST with appropriate opclasses is a convenient test case.) +create index gist_tbl_multi_index on gist_tbl using gist (circle(p,1), p) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: IndexStmt +== 046 +explain (verbose, costs off) +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 047 +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 048 +-- Similarly, test that index rechecks involving a non-returnable column +-- are done correctly. +explain (verbose, costs off) +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 049 +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 050 +-- Also check that use_physical_tlist doesn't trigger in such cases. +explain (verbose, costs off) +select count(*) from gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 051 +select count(*) from gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 052 +-- This case isn't supported, but it should at least EXPLAIN correctly. +explain (verbose, costs off) +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1 +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 053 +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1 +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 054 +-- Force an index build using buffering. +create index gist_tbl_box_index_forcing_buffering on gist_tbl using gist (p) + with (buffering=on, fillfactor=50) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +== 055 +-- Clean up +reset enable_seqscan +-- +STMT: VariableSetStmt +== 056 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 057 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +== 058 +drop table gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: DropStmt +== 059 +-- test an unlogged table, mostly to get coverage of gistbuildempty +create unlogged table gist_tbl (b box) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: CreateStmt +== 060 +create index gist_tbl_box_index on gist_tbl using gist (b) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +== 061 +insert into gist_tbl + select box(point(0.05*i, 0.05*i)) from generate_series(0,10) as i +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 062 +drop table gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/groupingsets.metadata.json b/parser/testdata/summary/postgres_regress/groupingsets.metadata.json new file mode 100644 index 0000000..643d115 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/groupingsets.metadata.json @@ -0,0 +1,176 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172" + ] +} diff --git a/parser/testdata/summary/postgres_regress/groupingsets.test b/parser/testdata/summary/postgres_regress/groupingsets.test new file mode 100644 index 0000000..95a6d2a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/groupingsets.test @@ -0,0 +1,1405 @@ +== 001 +|-- +-- grouping sets +|-- + +-- test data sources + +create temp view gstest1(a,b,v) + as 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) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 002 +create temp table gstest2 (a integer, b integer, c integer, d integer, + e integer, f integer, g integer, h integer) +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=DDL +STMT: CreateStmt +== 003 +copy gstest2 from stdin +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +STMT: CopyStmt +== 004 +create temp table gstest3 (a integer, b integer, c integer, d integer) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=DDL +STMT: CreateStmt +== 005 +copy gstest3 from stdin +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: CopyStmt +== 006 +alter table gstest3 add primary key (a) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=DDL +STMT: AlterTableStmt +== 007 +create temp table gstest4(id integer, v integer, + unhashable_col bit(4), unsortable_col xid) +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=DDL +STMT: CreateStmt +== 008 +insert into gstest4 +values (1,1,b'0000','1'), (2,2,b'0001','1'), + (3,4,b'0010','2'), (4,8,b'0011','2'), + (5,16,b'0000','2'), (6,32,b'0001','2'), + (7,64,b'0010','1'), (8,128,b'0011','1') +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +create temp table gstest_empty (a integer, b integer, v integer) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=DDL +STMT: CreateStmt +== 010 +create function gstest_data(v integer, out a integer, out b integer) + returns setof record + as $f$ + begin + return query select v, i from generate_series(1,3) i; + end; + $f$ language plpgsql +-- +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 011 +-- basic functionality + +set enable_hashagg = false +-- +STMT: VariableSetStmt +== 012 +-- test hashing explicitly later + +-- simple rollup with multiple plain aggregates, with and without ordering +-- (and with ordering differing from grouping) + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 013 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by a,b +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 014 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by b desc, a +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 015 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by coalesce(a,0)+coalesce(b,0) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- various types of ordered aggs +select a, b, grouping(a,b), + array_agg(v order by v), + string_agg(v::text, ':' order by v desc), + percentile_disc(0.5) within group (order by v), + rank(1,2,12) within group (order by a,b,v) + from gstest1 group by rollup (a,b) order by a,b +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- test usage of grouped columns in direct args of aggs +select grouping(a), a, array_agg(b), + rank(a) within group (order by b nulls first), + rank(a) within group (order by b nulls last) + from (values (1,1),(1,4),(1,5),(3,1),(3,2)) v(a,b) + group by rollup (a) order by a +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- nesting with window functions +select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum + from gstest2 group by rollup (a,b) order by rsum, a, b +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- nesting with grouping sets +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(()))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 020 +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(((a, b))))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 021 +select sum(c) from gstest2 + group by grouping sets(grouping sets(rollup(c), grouping sets(cube(c)))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 022 +select sum(c) from gstest2 + group by grouping sets(a, grouping sets(a, cube(b))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 023 +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, (b)))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 024 +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, b))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 025 +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a), a)) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 026 +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a, grouping sets(a), ((a)), a, grouping sets(a), (a)), a)) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 027 +select sum(c) from gstest2 + group by grouping sets((a,(a,b)), grouping sets((a,(a,b)),a)) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 028 +-- 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) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 029 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 030 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 031 +select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 032 +-- 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),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +ALIAS: "t1"="gstest_empty" +ALIAS: "t2"="gstest_empty" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 033 +-- 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), ()) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +ALIAS: "t1"="gstest1" +ALIAS: "t2"="gstest2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 034 +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), ()) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +ALIAS: "t1"="gstest1" +ALIAS: "t2"="gstest2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 035 +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), ()) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +ALIAS: "t1"="gstest1" +ALIAS: "t2"="gstest2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- 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)) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: SelectStmt +== 037 +-- 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) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 038 +select g as alias1, g as alias2 + from generate_series(1,3) g + group by alias1, rollup(alias2) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 039 +-- 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' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +== 040 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +== 041 +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) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 042 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: SelectStmt +== 043 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 044 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 045 +-- check handling of pulled-up SubPlan in GROUPING() argument (bug #17479) +explain (verbose, costs off) +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: SelectStmt +== 047 +explain (verbose, costs off) +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 048 +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: SelectStmt +== 049 +-- simple rescan tests + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by rollup (a,b) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +== 050 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +== 051 +-- min max optimization should still work with GROUP BY () +explain (costs off) + select min(unique1) from tenk1 GROUP BY () +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 052 +-- 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)) +-- +TABLE: name="gstest_view" schema="" table="gstest_view" ctx=DDL +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 053 +select pg_get_viewdef('gstest_view'::regclass, true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 054 +-- 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) +-- +STMT: SelectStmt +== 055 +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) +-- +STMT: SelectStmt +== 056 +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) +-- +STMT: SelectStmt +== 057 +-- Combinations of operations +select a, b, c, d from gstest2 group by rollup(a,b),grouping sets(c,d) +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +STMT: SelectStmt +== 058 +select a, b from (values (1,2),(2,3)) v(a,b) group by a,b, grouping sets(a) +-- +STMT: SelectStmt +== 059 +-- 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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 060 +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)) +-- +STMT: SelectStmt +== 061 +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) +-- +STMT: SelectStmt +== 062 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 063 +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) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 064 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +== 065 +-- Test reordering of grouping sets +explain (costs off) +select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 066 +-- Agg level check. This query should error out. +select (select grouping(a,b) from gstest2) from gstest2 group by a,b +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +STMT: SelectStmt +== 067 +--Nested queries +select a, b, sum(c), count(*) from gstest2 group by grouping sets (rollup(a,b),a) +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 068 +-- 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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +== 069 +-- Tests around pushdown of HAVING clauses, partially testing against previous bugs +select a,count(*) from gstest2 group by rollup(a) order by a +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 070 +select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 071 +explain (costs off) + select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 072 +select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 073 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 074 +-- HAVING with GROUPING queries +select ten, grouping(ten) from onek +group by grouping sets(ten) having grouping(ten) >= 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 075 +select ten, grouping(ten) from onek +group by grouping sets(ten, four) having grouping(ten) > 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 076 +select ten, grouping(ten) from onek +group by rollup(ten) having grouping(ten) > 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 077 +select ten, grouping(ten) from onek +group by cube(ten) having grouping(ten) > 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 078 +select ten, grouping(ten) from onek +group by (ten) having grouping(ten) >= 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 079 +-- FILTER queries +select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +group by rollup(ten) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 080 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 081 +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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 082 +-- Grouping on text columns +select sum(ten) from onek group by two, rollup(four::text) order by 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 083 +select sum(ten) from onek group by rollup(four::text), two order by 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 084 +-- hashing support + +set enable_hashagg = true +-- +STMT: VariableSetStmt +== 085 +-- failure cases + +select count(*) from gstest4 group by rollup(unhashable_col,unsortable_col) +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 086 +select array_agg(v order by v) from gstest4 group by grouping sets ((id,unsortable_col),(id)) +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 087 +-- 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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 088 +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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 089 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by cube(a,b) order by 3,1,2 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 090 +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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 091 +-- 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) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 092 +-- unsortable cases +select unsortable_col, count(*) + from gstest4 group by grouping sets ((unsortable_col),(unsortable_col)) + order by unsortable_col::text +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 093 +-- 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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 094 +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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 095 +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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 096 +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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 097 +-- 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) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 098 +explain (costs off) + select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 099 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 100 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 101 +explain (costs off) + select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 102 +select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 103 +explain (costs off) + select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 104 +-- 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)) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: SelectStmt +== 105 +explain (costs off) + select a, d, grouping(a,b,c) + from gstest3 + group by grouping sets ((a,b), (a,c)) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 106 +-- 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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +== 107 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 108 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +== 109 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 110 +-- 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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 111 +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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 112 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 113 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 114 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +== 115 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 116 +-- 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 +-- +STMT: TransactionStmt +== 117 +SET LOCAL enable_hashagg = false +-- +STMT: VariableSetStmt +== 118 +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 119 +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 120 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +== 121 +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 122 +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 123 +COMMIT +-- +STMT: TransactionStmt +== 124 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 125 +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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 126 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 127 +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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 128 +-- test the knapsack + +set enable_indexscan = false +-- +STMT: VariableSetStmt +== 129 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 130 +set work_mem = '64kB' +-- +STMT: VariableSetStmt +== 131 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 132 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 133 +set work_mem = '384kB' +-- +STMT: VariableSetStmt +== 134 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 135 +-- 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 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 136 +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 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 137 +-- Bug #16784 +create table bug_16784(i int, j int) +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DDL +STMT: CreateStmt +== 138 +analyze bug_16784 +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DDL +STMT: VacuumStmt +== 139 +alter table bug_16784 set (autovacuum_enabled = 'false') +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DDL +STMT: AlterTableStmt +== 140 +update pg_class set reltuples = 10 where relname='bug_16784' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +STMT: UpdateStmt +== 141 +insert into bug_16784 select g/10, g from generate_series(1,40) g +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 142 +set work_mem='64kB' +-- +STMT: VariableSetStmt +== 143 +set enable_sort = false +-- +STMT: VariableSetStmt +== 144 +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 +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 145 +|-- +-- 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 +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 146 +analyze gs_data_1 +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=DDL +STMT: VacuumStmt +== 147 +alter table gs_data_1 set (autovacuum_enabled = 'false') +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=DDL +STMT: AlterTableStmt +== 148 +update pg_class set reltuples = 10 where relname='gs_data_1' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +STMT: UpdateStmt +== 149 +set work_mem='64kB' +-- +STMT: VariableSetStmt +== 150 +-- Produce results with sorting. + +set enable_sort = true +-- +STMT: VariableSetStmt +== 151 +set enable_hashagg = false +-- +STMT: VariableSetStmt +== 152 +set jit_above_cost = 0 +-- +STMT: VariableSetStmt +== 153 +explain (costs off) +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10) +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 154 +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) +-- +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=DDL +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 155 +-- Produce results with hash aggregation. + +set enable_hashagg = true +-- +STMT: VariableSetStmt +== 156 +set enable_sort = false +-- +STMT: VariableSetStmt +== 157 +explain (costs off) +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10) +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 158 +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) +-- +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=DDL +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 159 +set enable_sort = true +-- +STMT: VariableSetStmt +== 160 +set work_mem to default +-- +STMT: VariableSetStmt +== 161 +set hash_mem_multiplier to default +-- +STMT: VariableSetStmt +== 162 +-- 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) +-- +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=Select +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=Select +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=Select +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=Select +STMT: SelectStmt +== 163 +drop table gs_group_1 +-- +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=DDL +STMT: DropStmt +== 164 +drop table gs_hash_1 +-- +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=DDL +STMT: DropStmt +== 165 +-- GROUP BY DISTINCT + +-- "normal" behavior... +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by all rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +== 166 +-- ...which is also the default +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +== 167 +-- "group by distinct" behavior... +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by distinct rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +== 168 +-- ...which is not the same as "select distinct" +select distinct a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +== 169 +-- test handling of outer GroupingFunc within subqueries +explain (costs off) +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 170 +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1) +-- +STMT: SelectStmt +== 171 +explain (costs off) +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1 +-- +STMT: ExplainStmt +STMT: SelectStmt +== 172 +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1 +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/guc.metadata.json b/parser/testdata/summary/postgres_regress/guc.metadata.json new file mode 100644 index 0000000..8f8fab6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/guc.metadata.json @@ -0,0 +1,218 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214" + ] +} diff --git a/parser/testdata/summary/postgres_regress/guc.test b/parser/testdata/summary/postgres_regress/guc.test new file mode 100644 index 0000000..12ffa58 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/guc.test @@ -0,0 +1,1034 @@ +== 001 +-- pg_regress should ensure that this default value applies; however +-- we can't rely on any specific default value of vacuum_cost_delay +SHOW datestyle +-- +STMT: VariableShowStmt +== 002 +-- SET to some nondefault value +SET vacuum_cost_delay TO 40 +-- +STMT: VariableSetStmt +== 003 +SET datestyle = 'ISO, YMD' +-- +STMT: VariableSetStmt +== 004 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 005 +SHOW datestyle +-- +STMT: VariableShowStmt +== 006 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 007 +-- SET LOCAL has no effect outside of a transaction +SET LOCAL vacuum_cost_delay TO 50 +-- +STMT: VariableSetStmt +== 008 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 009 +SET LOCAL datestyle = 'SQL' +-- +STMT: VariableSetStmt +== 010 +SHOW datestyle +-- +STMT: VariableShowStmt +== 011 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 012 +-- SET LOCAL within a transaction that commits +BEGIN +-- +STMT: TransactionStmt +== 013 +SET LOCAL vacuum_cost_delay TO 50 +-- +STMT: VariableSetStmt +== 014 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 015 +SET LOCAL datestyle = 'SQL' +-- +STMT: VariableSetStmt +== 016 +SHOW datestyle +-- +STMT: VariableShowStmt +== 017 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 018 +COMMIT +-- +STMT: TransactionStmt +== 019 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 020 +SHOW datestyle +-- +STMT: VariableShowStmt +== 021 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 022 +-- SET should be reverted after ROLLBACK +BEGIN +-- +STMT: TransactionStmt +== 023 +SET vacuum_cost_delay TO 60 +-- +STMT: VariableSetStmt +== 024 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 025 +SET datestyle = 'German' +-- +STMT: VariableSetStmt +== 026 +SHOW datestyle +-- +STMT: VariableShowStmt +== 027 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 028 +ROLLBACK +-- +STMT: TransactionStmt +== 029 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 030 +SHOW datestyle +-- +STMT: VariableShowStmt +== 031 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 032 +-- Some tests with subtransactions +BEGIN +-- +STMT: TransactionStmt +== 033 +SET vacuum_cost_delay TO 70 +-- +STMT: VariableSetStmt +== 034 +SET datestyle = 'MDY' +-- +STMT: VariableSetStmt +== 035 +SHOW datestyle +-- +STMT: VariableShowStmt +== 036 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 037 +SAVEPOINT first_sp +-- +STMT: TransactionStmt +== 038 +SET vacuum_cost_delay TO 80.1 +-- +STMT: VariableSetStmt +== 039 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 040 +SET datestyle = 'German, DMY' +-- +STMT: VariableSetStmt +== 041 +SHOW datestyle +-- +STMT: VariableShowStmt +== 042 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 043 +ROLLBACK TO first_sp +-- +STMT: TransactionStmt +== 044 +SHOW datestyle +-- +STMT: VariableShowStmt +== 045 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 046 +SAVEPOINT second_sp +-- +STMT: TransactionStmt +== 047 +SET vacuum_cost_delay TO '900us' +-- +STMT: VariableSetStmt +== 048 +SET datestyle = 'SQL, YMD' +-- +STMT: VariableSetStmt +== 049 +SHOW datestyle +-- +STMT: VariableShowStmt +== 050 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 051 +SAVEPOINT third_sp +-- +STMT: TransactionStmt +== 052 +SET vacuum_cost_delay TO 100 +-- +STMT: VariableSetStmt +== 053 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 054 +SET datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +== 055 +SHOW datestyle +-- +STMT: VariableShowStmt +== 056 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 057 +ROLLBACK TO third_sp +-- +STMT: TransactionStmt +== 058 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 059 +SHOW datestyle +-- +STMT: VariableShowStmt +== 060 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 061 +ROLLBACK TO second_sp +-- +STMT: TransactionStmt +== 062 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 063 +SHOW datestyle +-- +STMT: VariableShowStmt +== 064 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 065 +ROLLBACK +-- +STMT: TransactionStmt +== 066 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 067 +SHOW datestyle +-- +STMT: VariableShowStmt +== 068 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 069 +-- SET LOCAL with Savepoints +BEGIN +-- +STMT: TransactionStmt +== 070 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 071 +SHOW datestyle +-- +STMT: VariableShowStmt +== 072 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 073 +SAVEPOINT sp +-- +STMT: TransactionStmt +== 074 +SET LOCAL vacuum_cost_delay TO 30 +-- +STMT: VariableSetStmt +== 075 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 076 +SET LOCAL datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +== 077 +SHOW datestyle +-- +STMT: VariableShowStmt +== 078 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 079 +ROLLBACK TO sp +-- +STMT: TransactionStmt +== 080 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 081 +SHOW datestyle +-- +STMT: VariableShowStmt +== 082 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 083 +ROLLBACK +-- +STMT: TransactionStmt +== 084 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 085 +SHOW datestyle +-- +STMT: VariableShowStmt +== 086 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 087 +-- SET LOCAL persists through RELEASE (which was not true in 8.0-8.2) +BEGIN +-- +STMT: TransactionStmt +== 088 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 089 +SHOW datestyle +-- +STMT: VariableShowStmt +== 090 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 091 +SAVEPOINT sp +-- +STMT: TransactionStmt +== 092 +SET LOCAL vacuum_cost_delay TO 30 +-- +STMT: VariableSetStmt +== 093 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 094 +SET LOCAL datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +== 095 +SHOW datestyle +-- +STMT: VariableShowStmt +== 096 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 097 +RELEASE SAVEPOINT sp +-- +STMT: TransactionStmt +== 098 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 099 +SHOW datestyle +-- +STMT: VariableShowStmt +== 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 101 +ROLLBACK +-- +STMT: TransactionStmt +== 102 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 103 +SHOW datestyle +-- +STMT: VariableShowStmt +== 104 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 105 +-- SET followed by SET LOCAL +BEGIN +-- +STMT: TransactionStmt +== 106 +SET vacuum_cost_delay TO 40 +-- +STMT: VariableSetStmt +== 107 +SET LOCAL vacuum_cost_delay TO 50 +-- +STMT: VariableSetStmt +== 108 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 109 +SET datestyle = 'ISO, DMY' +-- +STMT: VariableSetStmt +== 110 +SET LOCAL datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +== 111 +SHOW datestyle +-- +STMT: VariableShowStmt +== 112 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 113 +COMMIT +-- +STMT: TransactionStmt +== 114 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 115 +SHOW datestyle +-- +STMT: VariableShowStmt +== 116 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 117 +|-- +-- Test RESET. We use datestyle because the reset value is forced by +-- pg_regress, so it doesn't depend on the installation's configuration. +|-- +SET datestyle = iso, ymd +-- +STMT: VariableSetStmt +== 118 +SHOW datestyle +-- +STMT: VariableShowStmt +== 119 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 120 +RESET datestyle +-- +STMT: VariableSetStmt +== 121 +SHOW datestyle +-- +STMT: VariableShowStmt +== 122 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +== 123 +-- Test some simple error cases +SET seq_page_cost TO 'NaN' +-- +STMT: VariableSetStmt +== 124 +SET vacuum_cost_delay TO '10s' +-- +STMT: VariableSetStmt +== 125 +SET no_such_variable TO 42 +-- +STMT: VariableSetStmt +== 126 +-- Test "custom" GUCs created on the fly (which aren't really an +-- intended feature, but many people use them). +SHOW custom.my_guc +-- +STMT: VariableShowStmt +== 127 +-- error, not known yet +SET custom.my_guc = 42 +-- +STMT: VariableSetStmt +== 128 +SHOW custom.my_guc +-- +STMT: VariableShowStmt +== 129 +RESET custom.my_guc +-- +STMT: VariableSetStmt +== 130 +-- this makes it go to empty, not become unknown again +SHOW custom.my_guc +-- +STMT: VariableShowStmt +== 131 +SET custom.my.qualified.guc = 'foo' +-- +STMT: VariableSetStmt +== 132 +SHOW custom.my.qualified.guc +-- +STMT: VariableShowStmt +== 133 +SET custom."bad-guc" = 42 +-- +STMT: VariableSetStmt +== 134 +-- disallowed because -c cannot set this name +SHOW custom."bad-guc" +-- +STMT: VariableShowStmt +== 135 +SET special."weird name" = 'foo' +-- +STMT: VariableSetStmt +== 136 +-- could be allowed, but we choose not to +SHOW special."weird name" +-- +STMT: VariableShowStmt +== 137 +-- Check what happens when you try to set a "custom" GUC within the +-- namespace of an extension. +SET plpgsql.extra_foo_warnings = true +-- +STMT: VariableSetStmt +== 138 +-- allowed if plpgsql is not loaded yet +LOAD 'plpgsql' +-- +STMT: LoadStmt +== 139 +-- this will throw a warning and delete the variable +SET plpgsql.extra_foo_warnings = true +-- +STMT: VariableSetStmt +== 140 +-- now, it's an error +SHOW plpgsql.extra_foo_warnings +-- +STMT: VariableShowStmt +== 141 +|-- +-- Test DISCARD TEMP +|-- +CREATE TEMP TABLE reset_test ( data text ) ON COMMIT DELETE ROWS +-- +TABLE: name="reset_test" schema="" table="reset_test" ctx=DDL +STMT: CreateStmt +== 142 +SELECT relname FROM pg_class WHERE relname = 'reset_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 143 +DISCARD TEMP +-- +STMT: DiscardStmt +== 144 +SELECT relname FROM pg_class WHERE relname = 'reset_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 145 +|-- +-- Test DISCARD ALL +|-- + +-- do changes +DECLARE foo CURSOR WITH HOLD FOR SELECT 1 +-- +STMT: DeclareCursorStmt +== 146 +PREPARE foo AS SELECT 1 +-- +STMT: PrepareStmt +STMT: SelectStmt +== 147 +LISTEN foo_event +-- +STMT: ListenStmt +== 148 +SET vacuum_cost_delay = 13 +-- +STMT: VariableSetStmt +== 149 +CREATE TEMP TABLE tmp_foo (data text) ON COMMIT DELETE ROWS +-- +TABLE: name="tmp_foo" schema="" table="tmp_foo" ctx=DDL +STMT: CreateStmt +== 150 +CREATE ROLE regress_guc_user +-- +STMT: CreateRoleStmt +== 151 +SET SESSION AUTHORIZATION regress_guc_user +-- +STMT: VariableSetStmt +== 152 +-- look changes +SELECT pg_listening_channels() +-- +FUNCTION: name="pg_listening_channels" function="pg_listening_channels" schema="" ctx=Call +STMT: SelectStmt +== 153 +SELECT name FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +== 154 +SELECT name FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 155 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 156 +SELECT relname from pg_class where relname = 'tmp_foo' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 157 +SELECT current_user = 'regress_guc_user' +-- +STMT: SelectStmt +== 158 +-- discard everything +DISCARD ALL +-- +STMT: DiscardStmt +== 159 +-- look again +SELECT pg_listening_channels() +-- +FUNCTION: name="pg_listening_channels" function="pg_listening_channels" schema="" ctx=Call +STMT: SelectStmt +== 160 +SELECT name FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +== 161 +SELECT name FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +== 162 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +== 163 +SELECT relname from pg_class where relname = 'tmp_foo' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 164 +SELECT current_user = 'regress_guc_user' +-- +STMT: SelectStmt +== 165 +DROP ROLE regress_guc_user +-- +STMT: DropRoleStmt +== 166 +|-- +-- search_path should react to changes in pg_namespace +|-- + +set search_path = foo, public, not_there_initially +-- +STMT: VariableSetStmt +== 167 +select current_schemas(false) +-- +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +STMT: SelectStmt +== 168 +create schema not_there_initially +-- +STMT: CreateSchemaStmt +== 169 +select current_schemas(false) +-- +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +STMT: SelectStmt +== 170 +drop schema not_there_initially +-- +STMT: DropStmt +== 171 +select current_schemas(false) +-- +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +STMT: SelectStmt +== 172 +reset search_path +-- +STMT: VariableSetStmt +== 173 +|-- +-- Tests for function-local GUC settings +|-- + +set work_mem = '3MB' +-- +STMT: VariableSetStmt +== 174 +create function report_guc(text) returns text as +$$ select current_setting($1) $$ language sql +set work_mem = '1MB' +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 175 +select report_guc('work_mem'), current_setting('work_mem') +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 176 +alter function report_guc(text) set work_mem = '2MB' +-- +STMT: AlterFunctionStmt +== 177 +select report_guc('work_mem'), current_setting('work_mem') +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 178 +alter function report_guc(text) reset all +-- +STMT: AlterFunctionStmt +== 179 +select report_guc('work_mem'), current_setting('work_mem') +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 180 +-- SET LOCAL is restricted by a function SET option +create or replace function myfunc(int) returns text as $$ +begin + set local work_mem = '2MB'; + return current_setting('work_mem'); +end $$ +language plpgsql +set work_mem = '1MB' +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 181 +select myfunc(0), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 182 +alter function myfunc(int) reset all +-- +STMT: AlterFunctionStmt +== 183 +select myfunc(0), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 184 +set work_mem = '3MB' +-- +STMT: VariableSetStmt +== 185 +-- but SET isn't +create or replace function myfunc(int) returns text as $$ +begin + set work_mem = '2MB'; + return current_setting('work_mem'); +end $$ +language plpgsql +set work_mem = '1MB' +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 186 +select myfunc(0), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 187 +set work_mem = '3MB' +-- +STMT: VariableSetStmt +== 188 +-- it should roll back on error, though +create or replace function myfunc(int) returns text as $$ +begin + set work_mem = '2MB'; + perform 1/$1; + return current_setting('work_mem'); +end $$ +language plpgsql +set work_mem = '1MB' +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 189 +select myfunc(0) +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +STMT: SelectStmt +== 190 +select current_setting('work_mem') +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 191 +select myfunc(1), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 192 +-- check current_setting()'s behavior with invalid setting name + +select current_setting('nosuch.setting') +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 193 +-- FAIL +select current_setting('nosuch.setting', false) +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 194 +-- FAIL +select current_setting('nosuch.setting', true) is null +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 195 +-- after this, all three cases should yield 'nada' +set nosuch.setting = 'nada' +-- +STMT: VariableSetStmt +== 196 +select current_setting('nosuch.setting') +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 197 +select current_setting('nosuch.setting', false) +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 198 +select current_setting('nosuch.setting', true) +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 199 +-- Normally, CREATE FUNCTION should complain about invalid values in +-- function SET options; but not if check_function_bodies is off, +-- because that creates ordering hazards for pg_dump + +create function func_with_bad_set() returns int as $$ select 1 $$ +language sql +set default_text_search_config = no_such_config +-- +FUNCTION: name="func_with_bad_set" function="func_with_bad_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 200 +set check_function_bodies = off +-- +STMT: VariableSetStmt +== 201 +create function func_with_bad_set() returns int as $$ select 1 $$ +language sql +set default_text_search_config = no_such_config +-- +FUNCTION: name="func_with_bad_set" function="func_with_bad_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 202 +select func_with_bad_set() +-- +FUNCTION: name="func_with_bad_set" function="func_with_bad_set" schema="" ctx=Call +STMT: SelectStmt +== 203 +reset check_function_bodies +-- +STMT: VariableSetStmt +== 204 +set default_with_oids to f +-- +STMT: VariableSetStmt +== 205 +-- Should not allow to set it to true. +set default_with_oids to t +-- +STMT: VariableSetStmt +== 206 +-- Test GUC categories and flag patterns +SELECT pg_settings_get_flags(NULL) +-- +FUNCTION: name="pg_settings_get_flags" function="pg_settings_get_flags" schema="" ctx=Call +STMT: SelectStmt +== 207 +SELECT pg_settings_get_flags('does_not_exist') +-- +FUNCTION: name="pg_settings_get_flags" function="pg_settings_get_flags" schema="" ctx=Call +STMT: SelectStmt +== 208 +CREATE TABLE tab_settings_flags AS SELECT name, category, + 'EXPLAIN' = ANY(flags) AS explain, + 'NO_RESET' = ANY(flags) AS no_reset, + 'NO_RESET_ALL' = ANY(flags) AS no_reset_all, + 'NOT_IN_SAMPLE' = ANY(flags) AS not_in_sample, + 'RUNTIME_COMPUTED' = ANY(flags) AS runtime_computed + FROM pg_show_all_settings() AS psas, + pg_settings_get_flags(psas.name) AS flags +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=DDL +FUNCTION: name="pg_show_all_settings" function="pg_show_all_settings" schema="" ctx=Call +FUNCTION: name="pg_settings_get_flags" function="pg_settings_get_flags" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 209 +-- Developer GUCs should be flagged with GUC_NOT_IN_SAMPLE: +SELECT name FROM tab_settings_flags + WHERE category = 'Developer Options' AND NOT not_in_sample + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="not_in_sample" +STMT: SelectStmt +== 210 +-- Most query-tuning GUCs are flagged as valid for EXPLAIN. +-- default_statistics_target is an exception. +SELECT name FROM tab_settings_flags + WHERE category ~ '^Query Tuning' AND NOT explain + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="explain" +STMT: SelectStmt +== 211 +-- Runtime-computed GUCs should be part of the preset category. +SELECT name FROM tab_settings_flags + WHERE NOT category = 'Preset Options' AND runtime_computed + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="runtime_computed" +STMT: SelectStmt +== 212 +-- Preset GUCs are flagged as NOT_IN_SAMPLE. +SELECT name FROM tab_settings_flags + WHERE category = 'Preset Options' AND NOT not_in_sample + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="not_in_sample" +STMT: SelectStmt +== 213 +-- NO_RESET implies NO_RESET_ALL. +SELECT name FROM tab_settings_flags + WHERE no_reset AND NOT no_reset_all + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="no_reset" +FILTER: schema="" table="" column="no_reset_all" +STMT: SelectStmt +== 214 +DROP TABLE tab_settings_flags +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/hash_func.metadata.json b/parser/testdata/summary/postgres_regress/hash_func.metadata.json new file mode 100644 index 0000000..e74143a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/hash_func.metadata.json @@ -0,0 +1,47 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043" + ] +} diff --git a/parser/testdata/summary/postgres_regress/hash_func.test b/parser/testdata/summary/postgres_regress/hash_func.test new file mode 100644 index 0000000..0fdc843 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/hash_func.test @@ -0,0 +1,803 @@ +== 001 +|-- +-- Test hash functions +|-- +-- When the salt is 0, the extended hash function should produce a result +-- whose low 32 bits match the standard hash function. When the salt is +-- not 0, we should get a different result. +|-- + +SELECT v as value, hashint2(v)::bit(32) as standard, + hashint2extended(v, 0)::bit(32) as extended0, + hashint2extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0::int2), (1::int2), (17::int2), (42::int2)) x(v) +WHERE hashint2(v)::bit(32) != hashint2extended(v, 0)::bit(32) + OR hashint2(v)::bit(32) = hashint2extended(v, 1)::bit(32) +-- +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 002 +SELECT v as value, hashint4(v)::bit(32) as standard, + hashint4extended(v, 0)::bit(32) as extended0, + hashint4extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashint4(v)::bit(32) != hashint4extended(v, 0)::bit(32) + OR hashint4(v)::bit(32) = hashint4extended(v, 1)::bit(32) +-- +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 003 +SELECT v as value, hashint8(v)::bit(32) as standard, + hashint8extended(v, 0)::bit(32) as extended0, + hashint8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashint8(v)::bit(32) != hashint8extended(v, 0)::bit(32) + OR hashint8(v)::bit(32) = hashint8extended(v, 1)::bit(32) +-- +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 004 +SELECT v as value, hashfloat4(v)::bit(32) as standard, + hashfloat4extended(v, 0)::bit(32) as extended0, + hashfloat4extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashfloat4(v)::bit(32) != hashfloat4extended(v, 0)::bit(32) + OR hashfloat4(v)::bit(32) = hashfloat4extended(v, 1)::bit(32) +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 005 +SELECT v as value, hashfloat8(v)::bit(32) as standard, + hashfloat8extended(v, 0)::bit(32) as extended0, + hashfloat8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashfloat8(v)::bit(32) != hashfloat8extended(v, 0)::bit(32) + OR hashfloat8(v)::bit(32) = hashfloat8extended(v, 1)::bit(32) +-- +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 006 +SELECT v as value, hashoid(v)::bit(32) as standard, + hashoidextended(v, 0)::bit(32) as extended0, + hashoidextended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashoid(v)::bit(32) != hashoidextended(v, 0)::bit(32) + OR hashoid(v)::bit(32) = hashoidextended(v, 1)::bit(32) +-- +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 007 +SELECT v as value, hashchar(v)::bit(32) as standard, + hashcharextended(v, 0)::bit(32) as extended0, + hashcharextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::"char"), ('1'), ('x'), ('X'), ('p'), ('N')) x(v) +WHERE hashchar(v)::bit(32) != hashcharextended(v, 0)::bit(32) + OR hashchar(v)::bit(32) = hashcharextended(v, 1)::bit(32) +-- +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 008 +SELECT v as value, hashname(v)::bit(32) as standard, + hashnameextended(v, 0)::bit(32) as extended0, + hashnameextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashname(v)::bit(32) != hashnameextended(v, 0)::bit(32) + OR hashname(v)::bit(32) = hashnameextended(v, 1)::bit(32) +-- +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 009 +SELECT v as value, hashtext(v)::bit(32) as standard, + hashtextextended(v, 0)::bit(32) as extended0, + hashtextextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashtext(v)::bit(32) != hashtextextended(v, 0)::bit(32) + OR hashtext(v)::bit(32) = hashtextextended(v, 1)::bit(32) +-- +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 010 +SELECT v as value, hashoidvector(v)::bit(32) as standard, + hashoidvectorextended(v, 0)::bit(32) as extended0, + hashoidvectorextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::oidvector), ('0 1 2 3 4'), ('17 18 19 20'), + ('42 43 42 45'), ('550273 550273 570274'), + ('207112489 207112499 21512 2155 372325 1363252')) x(v) +WHERE hashoidvector(v)::bit(32) != hashoidvectorextended(v, 0)::bit(32) + OR hashoidvector(v)::bit(32) = hashoidvectorextended(v, 1)::bit(32) +-- +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 011 +SELECT v as value, hash_aclitem(v)::bit(32) as standard, + hash_aclitem_extended(v, 0)::bit(32) as extended0, + hash_aclitem_extended(v, 1)::bit(32) as extended1 +FROM (SELECT DISTINCT(relacl[1]) FROM pg_class LIMIT 10) x(v) +WHERE hash_aclitem(v)::bit(32) != hash_aclitem_extended(v, 0)::bit(32) + OR hash_aclitem(v)::bit(32) = hash_aclitem_extended(v, 1)::bit(32) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 012 +SELECT v as value, hashmacaddr(v)::bit(32) as standard, + hashmacaddrextended(v, 0)::bit(32) as extended0, + hashmacaddrextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::macaddr), ('08:00:2b:01:02:04'), ('08:00:2b:01:02:04'), + ('e2:7f:51:3e:70:49'), ('d6:a9:4a:78:1c:d5'), + ('ea:29:b1:5e:1f:a5')) x(v) +WHERE hashmacaddr(v)::bit(32) != hashmacaddrextended(v, 0)::bit(32) + OR hashmacaddr(v)::bit(32) = hashmacaddrextended(v, 1)::bit(32) +-- +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 013 +SELECT v as value, hashinet(v)::bit(32) as standard, + hashinetextended(v, 0)::bit(32) as extended0, + hashinetextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::inet), ('192.168.100.128/25'), ('192.168.100.0/8'), + ('172.168.10.126/16'), ('172.18.103.126/24'), ('192.188.13.16/32')) x(v) +WHERE hashinet(v)::bit(32) != hashinetextended(v, 0)::bit(32) + OR hashinet(v)::bit(32) = hashinetextended(v, 1)::bit(32) +-- +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 014 +SELECT v as value, hash_numeric(v)::bit(32) as standard, + hash_numeric_extended(v, 0)::bit(32) as extended0, + hash_numeric_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1.149484958), (17.149484958), (42.149484958), + (149484958.550273), (2071124898672)) x(v) +WHERE hash_numeric(v)::bit(32) != hash_numeric_extended(v, 0)::bit(32) + OR hash_numeric(v)::bit(32) = hash_numeric_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 015 +SELECT v as value, hashmacaddr8(v)::bit(32) as standard, + hashmacaddr8extended(v, 0)::bit(32) as extended0, + hashmacaddr8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::macaddr8), ('08:00:2b:01:02:04:36:49'), + ('08:00:2b:01:02:04:f0:e8'), ('e2:7f:51:3e:70:49:16:29'), + ('d6:a9:4a:78:1c:d5:47:32'), ('ea:29:b1:5e:1f:a5')) x(v) +WHERE hashmacaddr8(v)::bit(32) != hashmacaddr8extended(v, 0)::bit(32) + OR hashmacaddr8(v)::bit(32) = hashmacaddr8extended(v, 1)::bit(32) +-- +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 016 +SELECT v as value, hash_array(v)::bit(32) as standard, + hash_array_extended(v, 0)::bit(32) as extended0, + hash_array_extended(v, 1)::bit(32) as extended1 +FROM (VALUES ('{0}'::int4[]), ('{0,1,2,3,4}'), ('{17,18,19,20}'), + ('{42,34,65,98}'), ('{550273,590027, 870273}'), + ('{207112489, 807112489}')) x(v) +WHERE hash_array(v)::bit(32) != hash_array_extended(v, 0)::bit(32) + OR hash_array(v)::bit(32) = hash_array_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 017 +-- array hashing with non-hashable element type +SELECT v as value, hash_array(v)::bit(32) as standard +FROM (VALUES ('{101}'::varbit[])) x(v) +-- +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT v as value, hash_array_extended(v, 0)::bit(32) as extended0 +FROM (VALUES ('{101}'::varbit[])) x(v) +-- +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT v as value, hashbpchar(v)::bit(32) as standard, + hashbpcharextended(v, 0)::bit(32) as extended0, + hashbpcharextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashbpchar(v)::bit(32) != hashbpcharextended(v, 0)::bit(32) + OR hashbpchar(v)::bit(32) = hashbpcharextended(v, 1)::bit(32) +-- +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 020 +SELECT v as value, time_hash(v)::bit(32) as standard, + time_hash_extended(v, 0)::bit(32) as extended0, + time_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::time), ('11:09:59'), ('1:09:59'), ('11:59:59'), + ('7:9:59'), ('5:15:59')) x(v) +WHERE time_hash(v)::bit(32) != time_hash_extended(v, 0)::bit(32) + OR time_hash(v)::bit(32) = time_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 021 +SELECT v as value, timetz_hash(v)::bit(32) as standard, + timetz_hash_extended(v, 0)::bit(32) as extended0, + timetz_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::timetz), ('00:11:52.518762-07'), ('00:11:52.51762-08'), + ('00:11:52.62-01'), ('00:11:52.62+01'), ('11:59:59+04')) x(v) +WHERE timetz_hash(v)::bit(32) != timetz_hash_extended(v, 0)::bit(32) + OR timetz_hash(v)::bit(32) = timetz_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 022 +SELECT v as value, interval_hash(v)::bit(32) as standard, + interval_hash_extended(v, 0)::bit(32) as extended0, + interval_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::interval), + ('5 month 7 day 46 minutes'), ('1 year 7 day 46 minutes'), + ('1 year 7 month 20 day 46 minutes'), ('5 month'), + ('17 year 11 month 7 day 9 hours 46 minutes 5 seconds')) x(v) +WHERE interval_hash(v)::bit(32) != interval_hash_extended(v, 0)::bit(32) + OR interval_hash(v)::bit(32) = interval_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 023 +SELECT v as value, timestamp_hash(v)::bit(32) as standard, + timestamp_hash_extended(v, 0)::bit(32) as extended0, + timestamp_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::timestamp), ('2017-08-22 00:09:59.518762'), + ('2015-08-20 00:11:52.51762-08'), + ('2017-05-22 00:11:52.62-01'), + ('2013-08-22 00:11:52.62+01'), ('2013-08-22 11:59:59+04')) x(v) +WHERE timestamp_hash(v)::bit(32) != timestamp_hash_extended(v, 0)::bit(32) + OR timestamp_hash(v)::bit(32) = timestamp_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 024 +SELECT v as value, uuid_hash(v)::bit(32) as standard, + uuid_hash_extended(v, 0)::bit(32) as extended0, + uuid_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::uuid), ('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'), + ('5a9ba4ac-8d6f-11e7-bb31-be2e44b06b34'), + ('99c6705c-d939-461c-a3c9-1690ad64ed7b'), + ('7deed3ca-8d6f-11e7-bb31-be2e44b06b34'), + ('9ad46d4f-6f2a-4edd-aadb-745993928e1e')) x(v) +WHERE uuid_hash(v)::bit(32) != uuid_hash_extended(v, 0)::bit(32) + OR uuid_hash(v)::bit(32) = uuid_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 025 +SELECT v as value, pg_lsn_hash(v)::bit(32) as standard, + pg_lsn_hash_extended(v, 0)::bit(32) as extended0, + pg_lsn_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::pg_lsn), ('16/B374D84'), ('30/B374D84'), + ('255/B374D84'), ('25/B379D90'), ('900/F37FD90')) x(v) +WHERE pg_lsn_hash(v)::bit(32) != pg_lsn_hash_extended(v, 0)::bit(32) + OR pg_lsn_hash(v)::bit(32) = pg_lsn_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 026 +CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy') +-- +STMT: CreateEnumStmt +== 027 +SELECT v as value, hashenum(v)::bit(32) as standard, + hashenumextended(v, 0)::bit(32) as extended0, + hashenumextended(v, 1)::bit(32) as extended1 +FROM (VALUES ('sad'::mood), ('ok'), ('happy')) x(v) +WHERE hashenum(v)::bit(32) != hashenumextended(v, 0)::bit(32) + OR hashenum(v)::bit(32) = hashenumextended(v, 1)::bit(32) +-- +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 028 +DROP TYPE mood +-- +STMT: DropStmt +== 029 +SELECT v as value, jsonb_hash(v)::bit(32) as standard, + jsonb_hash_extended(v, 0)::bit(32) as extended0, + jsonb_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::jsonb), + ('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'), + ('{"foo": [true, "bar"], "tags": {"e": 1, "f": null}}'), + ('{"g": {"h": "value"}}')) x(v) +WHERE jsonb_hash(v)::bit(32) != jsonb_hash_extended(v, 0)::bit(32) + OR jsonb_hash(v)::bit(32) = jsonb_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 030 +SELECT v as value, hash_range(v)::bit(32) as standard, + hash_range_extended(v, 0)::bit(32) as extended0, + hash_range_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (int4range(10, 20)), (int4range(23, 43)), + (int4range(5675, 550273)), + (int4range(550274, 1550274)), (int4range(1550275, 208112489))) x(v) +WHERE hash_range(v)::bit(32) != hash_range_extended(v, 0)::bit(32) + OR hash_range(v)::bit(32) = hash_range_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 031 +SELECT v as value, hash_multirange(v)::bit(32) as standard, + hash_multirange_extended(v, 0)::bit(32) as extended0, + hash_multirange_extended(v, 1)::bit(32) as extended1 +FROM (VALUES ('{[10,20)}'::int4multirange), ('{[23, 43]}'::int4multirange), + ('{[5675, 550273)}'::int4multirange), + ('{[550274, 1550274)}'::int4multirange), + ('{[1550275, 208112489)}'::int4multirange)) x(v) +WHERE hash_multirange(v)::bit(32) != hash_multirange_extended(v, 0)::bit(32) + OR hash_multirange(v)::bit(32) = hash_multirange_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 032 +CREATE TYPE hash_test_t1 AS (a int, b text) +-- +STMT: CompositeTypeStmt +== 033 +SELECT v as value, hash_record(v)::bit(32) as standard, + hash_record_extended(v, 0)::bit(32) as extended0, + hash_record_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (row(1, 'aaa')::hash_test_t1, row(2, 'bbb'), row(-1, 'ccc'))) x(v) +WHERE hash_record(v)::bit(32) != hash_record_extended(v, 0)::bit(32) + OR hash_record(v)::bit(32) = hash_record_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +== 034 +DROP TYPE hash_test_t1 +-- +STMT: DropStmt +== 035 +-- record hashing with non-hashable field type +CREATE TYPE hash_test_t2 AS (a varbit, b text) +-- +STMT: CompositeTypeStmt +== 036 +SELECT v as value, hash_record(v)::bit(32) as standard +FROM (VALUES (row('10'::varbit, 'aaa')::hash_test_t2)) x(v) +-- +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT v as value, hash_record_extended(v, 0)::bit(32) as extended0 +FROM (VALUES (row('11'::varbit, 'aaa')::hash_test_t2)) x(v) +-- +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +STMT: SelectStmt +== 038 +DROP TYPE hash_test_t2 +-- +STMT: DropStmt +== 039 +|-- +-- Check special cases for specific data types +|-- +SELECT hashfloat4('0'::float4) = hashfloat4('-0'::float4) AS t +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT hashfloat4('NaN'::float4) = hashfloat4(-'NaN'::float4) AS t +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT hashfloat8('0'::float8) = hashfloat8('-0'::float8) AS t +-- +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +STMT: SelectStmt +== 042 +SELECT hashfloat8('NaN'::float8) = hashfloat8(-'NaN'::float8) AS t +-- +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT hashfloat4('NaN'::float4) = hashfloat8('NaN'::float8) AS t +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/hash_index.metadata.json b/parser/testdata/summary/postgres_regress/hash_index.metadata.json new file mode 100644 index 0000000..ba349a5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/hash_index.metadata.json @@ -0,0 +1,101 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097" + ] +} diff --git a/parser/testdata/summary/postgres_regress/hash_index.test b/parser/testdata/summary/postgres_regress/hash_index.test new file mode 100644 index 0000000..fbb61bc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/hash_index.test @@ -0,0 +1,688 @@ +== 001 +|-- +-- HASH_INDEX +|-- + +-- directory paths are passed to us in environment variables + +CREATE TABLE hash_i4_heap ( + seqno int4, + random int4 +) +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE hash_name_heap ( + seqno int4, + random name +) +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE hash_txt_heap ( + seqno int4, + random text +) +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE hash_f8_heap ( + seqno int4, + random float8 +) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: CreateStmt +== 005 +COPY hash_i4_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +COPY hash_name_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 26 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +COPY hash_txt_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +COPY hash_f8_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- the data in this file has a lot of duplicates in the index key +-- fields, leading to long bucket chains and lots of table expansion. +-- this is therefore a stress test of the bucket overflow code (unlike +-- the data in hash.data, which has unique index keys). +|-- +-- \set filename :abs_srcdir '/data/hashovfl.data' +-- COPY hash_ovfl_heap FROM :'filename'; + +ANALYZE hash_i4_heap +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DDL +STMT: VacuumStmt +== 010 +ANALYZE hash_name_heap +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DDL +STMT: VacuumStmt +== 011 +ANALYZE hash_txt_heap +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DDL +STMT: VacuumStmt +== 012 +ANALYZE hash_f8_heap +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: VacuumStmt +== 013 +CREATE INDEX hash_i4_index ON hash_i4_heap USING hash (random int4_ops) +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DDL +STMT: IndexStmt +== 014 +CREATE INDEX hash_name_index ON hash_name_heap USING hash (random name_ops) +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DDL +STMT: IndexStmt +== 015 +CREATE INDEX hash_txt_index ON hash_txt_heap USING hash (random text_ops) +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DDL +STMT: IndexStmt +== 016 +CREATE INDEX hash_f8_index ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=60) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +== 017 +|-- +-- 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)) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 018 +create unique index hash_f8_index_2 on hash_f8_heap((seqno + 1), random) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +== 019 +create unique index hash_f8_index_3 on hash_f8_heap(random) where seqno > 1000 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +== 020 +|-- +-- hash index +-- grep 843938989 hash.data +|-- +SELECT * FROM hash_i4_heap + WHERE hash_i4_heap.random = 843938989 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +FILTER: schema="" table="hash_i4_heap" column="random" +STMT: SelectStmt +== 021 +|-- +-- hash index +-- grep 66766766 hash.data +|-- +SELECT * FROM hash_i4_heap + WHERE hash_i4_heap.random = 66766766 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +FILTER: schema="" table="hash_i4_heap" column="random" +STMT: SelectStmt +== 022 +|-- +-- hash index +-- grep 1505703298 hash.data +|-- +SELECT * FROM hash_name_heap + WHERE hash_name_heap.random = '1505703298'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +FILTER: schema="" table="hash_name_heap" column="random" +STMT: SelectStmt +== 023 +|-- +-- hash index +-- grep 7777777 hash.data +|-- +SELECT * FROM hash_name_heap + WHERE hash_name_heap.random = '7777777'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +FILTER: schema="" table="hash_name_heap" column="random" +STMT: SelectStmt +== 024 +|-- +-- hash index +-- grep 1351610853 hash.data +|-- +SELECT * FROM hash_txt_heap + WHERE hash_txt_heap.random = '1351610853'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +FILTER: schema="" table="hash_txt_heap" column="random" +STMT: SelectStmt +== 025 +|-- +-- hash index +-- grep 111111112222222233333333 hash.data +|-- +SELECT * FROM hash_txt_heap + WHERE hash_txt_heap.random = '111111112222222233333333'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +FILTER: schema="" table="hash_txt_heap" column="random" +STMT: SelectStmt +== 026 +|-- +-- hash index +-- grep 444705537 hash.data +|-- +SELECT * FROM hash_f8_heap + WHERE hash_f8_heap.random = '444705537'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +FILTER: schema="" table="hash_f8_heap" column="random" +STMT: SelectStmt +== 027 +|-- +-- hash index +-- grep 88888888 hash.data +|-- +SELECT * FROM hash_f8_heap + WHERE hash_f8_heap.random = '88888888'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +FILTER: schema="" table="hash_f8_heap" column="random" +STMT: SelectStmt +== 028 +|-- +-- hash index +-- grep '^90[^0-9]' hashovfl.data +|-- +-- SELECT count(*) AS i988 FROM hash_ovfl_heap +-- WHERE x = 90; + +|-- +-- hash index +-- grep '^1000[^0-9]' hashovfl.data +|-- +-- SELECT count(*) AS i0 FROM hash_ovfl_heap +-- WHERE x = 1000; + +|-- +-- HASH +|-- +UPDATE hash_i4_heap + SET random = 1 + WHERE hash_i4_heap.seqno = 1492 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DML +STMT: UpdateStmt +== 029 +SELECT h.seqno AS i1492, h.random AS i1 + FROM hash_i4_heap h + WHERE h.random = 1 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +ALIAS: "h"="hash_i4_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 030 +UPDATE hash_i4_heap + SET seqno = 20000 + WHERE hash_i4_heap.random = 1492795354 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DML +STMT: UpdateStmt +== 031 +SELECT h.seqno AS i20000 + FROM hash_i4_heap h + WHERE h.random = 1492795354 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +ALIAS: "h"="hash_i4_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 032 +UPDATE hash_name_heap + SET random = '0123456789abcdef'::name + WHERE hash_name_heap.seqno = 6543 +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DML +STMT: UpdateStmt +== 033 +SELECT h.seqno AS i6543, h.random AS c0_to_f + FROM hash_name_heap h + WHERE h.random = '0123456789abcdef'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +ALIAS: "h"="hash_name_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 034 +UPDATE hash_name_heap + SET seqno = 20000 + WHERE hash_name_heap.random = '76652222'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DML +STMT: UpdateStmt +== 035 +|-- +-- this is the row we just replaced; index scan should return zero rows +|-- +SELECT h.seqno AS emptyset + FROM hash_name_heap h + WHERE h.random = '76652222'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +ALIAS: "h"="hash_name_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 036 +UPDATE hash_txt_heap + SET random = '0123456789abcdefghijklmnop'::text + WHERE hash_txt_heap.seqno = 4002 +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DML +STMT: UpdateStmt +== 037 +SELECT h.seqno AS i4002, h.random AS c0_to_p + FROM hash_txt_heap h + WHERE h.random = '0123456789abcdefghijklmnop'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +ALIAS: "h"="hash_txt_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 038 +UPDATE hash_txt_heap + SET seqno = 20000 + WHERE hash_txt_heap.random = '959363399'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DML +STMT: UpdateStmt +== 039 +SELECT h.seqno AS t20000 + FROM hash_txt_heap h + WHERE h.random = '959363399'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +ALIAS: "h"="hash_txt_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 040 +UPDATE hash_f8_heap + SET random = '-1234.1234'::float8 + WHERE hash_f8_heap.seqno = 8906 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DML +STMT: UpdateStmt +== 041 +SELECT h.seqno AS i8096, h.random AS f1234_1234 + FROM hash_f8_heap h + WHERE h.random = '-1234.1234'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +ALIAS: "h"="hash_f8_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 042 +UPDATE hash_f8_heap + SET seqno = 20000 + WHERE hash_f8_heap.random = '488912369'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DML +STMT: UpdateStmt +== 043 +SELECT h.seqno AS f20000 + FROM hash_f8_heap h + WHERE h.random = '488912369'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +ALIAS: "h"="hash_f8_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +== 044 +-- UPDATE hash_ovfl_heap +-- SET x = 1000 +-- WHERE x = 90; + +-- this vacuums the index as well +-- VACUUM hash_ovfl_heap; + +-- SELECT count(*) AS i0 FROM hash_ovfl_heap +-- WHERE x = 90; + +-- SELECT count(*) AS i988 FROM hash_ovfl_heap +-- WHERE x = 1000; + +|-- +-- Cause some overflow insert and splits. +|-- +CREATE TABLE hash_split_heap (keycol INT) +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: CreateStmt +== 045 +INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 500) a +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 046 +CREATE INDEX hash_split_index on hash_split_heap USING HASH (keycol) +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: IndexStmt +== 047 +INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 5000) a +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 048 +-- Let's do a backward scan. +BEGIN +-- +STMT: TransactionStmt +== 049 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 050 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 051 +DECLARE c CURSOR FOR SELECT * from hash_split_heap WHERE keycol = 1 +-- +STMT: DeclareCursorStmt +== 052 +MOVE FORWARD ALL FROM c +-- +STMT: FetchStmt +== 053 +MOVE BACKWARD 10000 FROM c +-- +STMT: FetchStmt +== 054 +MOVE BACKWARD ALL FROM c +-- +STMT: FetchStmt +== 055 +CLOSE c +-- +STMT: ClosePortalStmt +== 056 +END +-- +STMT: TransactionStmt +== 057 +-- DELETE, INSERT, VACUUM. +DELETE FROM hash_split_heap WHERE keycol = 1 +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +STMT: DeleteStmt +== 058 +INSERT INTO hash_split_heap SELECT a/2 FROM generate_series(1, 25000) a +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 059 +VACUUM hash_split_heap +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: VacuumStmt +== 060 +-- Rebuild the index using a different fillfactor +ALTER INDEX hash_split_index SET (fillfactor = 10) +-- +STMT: AlterTableStmt +== 061 +REINDEX INDEX hash_split_index +-- +STMT: ReindexStmt +== 062 +-- Clean up. +DROP TABLE hash_split_heap +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: DropStmt +== 063 +-- Testcases for removing overflow pages. +CREATE TABLE hash_cleanup_heap(keycol INT) +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: CreateStmt +== 064 +CREATE INDEX hash_cleanup_index on hash_cleanup_heap USING HASH (keycol) +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: IndexStmt +== 065 +-- Insert tuples to both the primary bucket page and overflow pages. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 066 +-- Fill overflow pages by "dead" tuples. +BEGIN +-- +STMT: TransactionStmt +== 067 +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1000) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 068 +ROLLBACK +-- +STMT: TransactionStmt +== 069 +-- Checkpoint will ensure that all hash buffers are cleaned before we try +-- to remove overflow pages. +CHECKPOINT +-- +STMT: CheckPointStmt +== 070 +-- This will squeeze the bucket and remove overflow pages. +VACUUM hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: VacuumStmt +== 071 +TRUNCATE hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: TruncateStmt +== 072 +-- Insert a few tuples so that the primary bucket page doesn't get full and +-- tuples can be moved to it. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 073 +-- Fill overflow pages by "dead" tuples. +BEGIN +-- +STMT: TransactionStmt +== 074 +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 075 +ROLLBACK +-- +STMT: TransactionStmt +== 076 +-- And insert some tuples again. During squeeze operation, these will be moved +-- to the primary bucket allowing to test freeing intermediate overflow pages. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 077 +CHECKPOINT +-- +STMT: CheckPointStmt +== 078 +VACUUM hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: VacuumStmt +== 079 +TRUNCATE hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: TruncateStmt +== 080 +-- Insert tuples to both the primary bucket page and overflow pages. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 081 +-- Fill overflow pages by "dead" tuples. +BEGIN +-- +STMT: TransactionStmt +== 082 +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 083 +ROLLBACK +-- +STMT: TransactionStmt +== 084 +-- And insert some tuples again. During squeeze operation, these will be moved +-- to other overflow pages and also allow overflow pages filled by dead tuples +-- to be freed. Note the main purpose of this test is to test the case where +-- we don't need to move any tuple from the overflow page being freed. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 085 +CHECKPOINT +-- +STMT: CheckPointStmt +== 086 +VACUUM hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: VacuumStmt +== 087 +-- Clean up. +DROP TABLE hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: DropStmt +== 088 +-- Index on temp table. +CREATE TEMP TABLE hash_temp_heap (x int, y int) +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DDL +STMT: CreateStmt +== 089 +INSERT INTO hash_temp_heap VALUES (1,1) +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +CREATE INDEX hash_idx ON hash_temp_heap USING hash (x) +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DDL +STMT: IndexStmt +== 091 +DROP TABLE hash_temp_heap CASCADE +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DDL +STMT: DropStmt +== 092 +-- Float4 type. +CREATE TABLE hash_heap_float4 (x float4, y int) +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DDL +STMT: CreateStmt +== 093 +INSERT INTO hash_heap_float4 VALUES (1.1,1) +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +CREATE INDEX hash_idx ON hash_heap_float4 USING hash (x) +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DDL +STMT: IndexStmt +== 095 +DROP TABLE hash_heap_float4 CASCADE +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DDL +STMT: DropStmt +== 096 +-- Test out-of-range fillfactor values +CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=9) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +== 097 +CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=101) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt diff --git a/parser/testdata/summary/postgres_regress/hash_part.metadata.json b/parser/testdata/summary/postgres_regress/hash_part.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/hash_part.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary/postgres_regress/hash_part.test b/parser/testdata/summary/postgres_regress/hash_part.test new file mode 100644 index 0000000..f82e3f4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/hash_part.test @@ -0,0 +1,184 @@ +== 001 +|-- +-- Hash partitioning. +|-- + +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different machines. See the definitions of +-- part_test_int4_ops and part_test_text_ops in test_setup.sql. + +CREATE TABLE mchash (a int, b text, c jsonb) + PARTITION BY HASH (a part_test_int4_ops, b part_test_text_ops) +-- +TABLE: name="mchash" schema="" table="mchash" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE mchash1 + PARTITION OF mchash FOR VALUES WITH (MODULUS 4, REMAINDER 0) +-- +TABLE: name="mchash1" schema="" table="mchash1" ctx=DDL +STMT: CreateStmt +== 003 +-- invalid OID, no such table +SELECT satisfies_hash_partition(0, 4, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 004 +-- not partitioned +SELECT satisfies_hash_partition('tenk1'::regclass, 4, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 005 +-- partition rather than the parent +SELECT satisfies_hash_partition('mchash1'::regclass, 4, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 006 +-- invalid modulus +SELECT satisfies_hash_partition('mchash'::regclass, 0, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- remainder too small +SELECT satisfies_hash_partition('mchash'::regclass, 1, -1, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- remainder too large +SELECT satisfies_hash_partition('mchash'::regclass, 1, 1, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- modulus is null +SELECT satisfies_hash_partition('mchash'::regclass, NULL, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 010 +-- remainder is null +SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 011 +-- too many arguments +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, NULL::int, NULL::text, NULL::json) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- too few arguments +SELECT satisfies_hash_partition('mchash'::regclass, 3, 1, NULL::int) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- wrong argument type +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, NULL::int, NULL::int) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- ok, should be false +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 0, ''::text) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 015 +-- ok, should be true +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 2, ''::text) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- argument via variadic syntax, should fail because not all partitioning +-- columns are of the correct type +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, + variadic array[1,2]::int[]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- multiple partitioning columns of the same type +CREATE TABLE mcinthash (a int, b int, c jsonb) + PARTITION BY HASH (a part_test_int4_ops, b part_test_int4_ops) +-- +TABLE: name="mcinthash" schema="" table="mcinthash" ctx=DDL +STMT: CreateStmt +== 018 +-- now variadic should work, should be false +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[0, 0]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- should be true +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[0, 1]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- wrong length +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[]::int[]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- wrong type +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[now(), now()]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- check satisfies_hash_partition passes correct collation +create table text_hashp (a text) partition by hash (a) +-- +TABLE: name="text_hashp" schema="" table="text_hashp" ctx=DDL +STMT: CreateStmt +== 023 +create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0) +-- +TABLE: name="text_hashp0" schema="" table="text_hashp0" ctx=DDL +STMT: CreateStmt +== 024 +create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1) +-- +TABLE: name="text_hashp1" schema="" table="text_hashp1" ctx=DDL +STMT: CreateStmt +== 025 +-- The result here should always be true, because 'xxx' must belong to +-- one of the two defined partitions +select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR + satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +== 026 +-- cleanup +DROP TABLE mchash +-- +TABLE: name="mchash" schema="" table="mchash" ctx=DDL +STMT: DropStmt +== 027 +DROP TABLE mcinthash +-- +TABLE: name="mcinthash" schema="" table="mcinthash" ctx=DDL +STMT: DropStmt +== 028 +DROP TABLE text_hashp +-- +TABLE: name="text_hashp" schema="" table="text_hashp" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/horology.metadata.json b/parser/testdata/summary/postgres_regress/horology.metadata.json new file mode 100644 index 0000000..820fe8a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/horology.metadata.json @@ -0,0 +1,392 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388" + ] +} diff --git a/parser/testdata/summary/postgres_regress/horology.test b/parser/testdata/summary/postgres_regress/horology.test new file mode 100644 index 0000000..ec11b1b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/horology.test @@ -0,0 +1,1995 @@ +== 001 +|-- +-- HOROLOGY +|-- + +SHOW TimeZone +-- +STMT: VariableShowStmt +== 002 +-- Many of these tests depend on the prevailing settings +SHOW DateStyle +-- +STMT: VariableShowStmt +== 003 +|-- +-- Test various input formats +|-- +SELECT timestamp with time zone '20011227 040506+08' +-- +STMT: SelectStmt +== 004 +SELECT timestamp with time zone '20011227 040506-08' +-- +STMT: SelectStmt +== 005 +SELECT timestamp with time zone '20011227 040506.789+08' +-- +STMT: SelectStmt +== 006 +SELECT timestamp with time zone '20011227 040506.789-08' +-- +STMT: SelectStmt +== 007 +SELECT timestamp with time zone '20011227T040506+08' +-- +STMT: SelectStmt +== 008 +SELECT timestamp with time zone '20011227T040506-08' +-- +STMT: SelectStmt +== 009 +SELECT timestamp with time zone '20011227T040506.789+08' +-- +STMT: SelectStmt +== 010 +SELECT timestamp with time zone '20011227T040506.789-08' +-- +STMT: SelectStmt +== 011 +SELECT timestamp with time zone '2001-12-27 04:05:06.789-08' +-- +STMT: SelectStmt +== 012 +SELECT timestamp with time zone '2001.12.27 04:05:06.789-08' +-- +STMT: SelectStmt +== 013 +SELECT timestamp with time zone '2001/12/27 04:05:06.789-08' +-- +STMT: SelectStmt +== 014 +SELECT timestamp with time zone '12/27/2001 04:05:06.789-08' +-- +STMT: SelectStmt +== 015 +SELECT timestamp with time zone '2001-12-27 04:05:06.789 MET DST' +-- +STMT: SelectStmt +== 016 +SELECT timestamp with time zone '2001-12-27 allballs' +-- +STMT: SelectStmt +== 017 +-- should fail in mdy mode: +SELECT timestamp with time zone '27/12/2001 04:05:06.789-08' +-- +STMT: SelectStmt +== 018 +set datestyle to dmy +-- +STMT: VariableSetStmt +== 019 +SELECT timestamp with time zone '27/12/2001 04:05:06.789-08' +-- +STMT: SelectStmt +== 020 +reset datestyle +-- +STMT: VariableSetStmt +== 021 +SELECT timestamp with time zone 'J2452271+08' +-- +STMT: SelectStmt +== 022 +SELECT timestamp with time zone 'J2452271-08' +-- +STMT: SelectStmt +== 023 +SELECT timestamp with time zone 'J2452271.5+08' +-- +STMT: SelectStmt +== 024 +SELECT timestamp with time zone 'J2452271.5-08' +-- +STMT: SelectStmt +== 025 +SELECT timestamp with time zone 'J2452271 04:05:06+08' +-- +STMT: SelectStmt +== 026 +SELECT timestamp with time zone 'J2452271 04:05:06-08' +-- +STMT: SelectStmt +== 027 +SELECT timestamp with time zone 'J2452271T040506+08' +-- +STMT: SelectStmt +== 028 +SELECT timestamp with time zone 'J2452271T040506-08' +-- +STMT: SelectStmt +== 029 +SELECT timestamp with time zone 'J2452271T040506.789+08' +-- +STMT: SelectStmt +== 030 +SELECT timestamp with time zone 'J2452271T040506.789-08' +-- +STMT: SelectStmt +== 031 +-- German/European-style dates with periods as delimiters +SELECT timestamp with time zone '12.27.2001 04:05:06.789+08' +-- +STMT: SelectStmt +== 032 +SELECT timestamp with time zone '12.27.2001 04:05:06.789-08' +-- +STMT: SelectStmt +== 033 +SET DateStyle = 'German' +-- +STMT: VariableSetStmt +== 034 +SELECT timestamp with time zone '27.12.2001 04:05:06.789+08' +-- +STMT: SelectStmt +== 035 +SELECT timestamp with time zone '27.12.2001 04:05:06.789-08' +-- +STMT: SelectStmt +== 036 +SET DateStyle = 'ISO' +-- +STMT: VariableSetStmt +== 037 +-- As of 7.4, allow time without time zone having a time zone specified +SELECT time without time zone '040506.789+08' +-- +STMT: SelectStmt +== 038 +SELECT time without time zone '040506.789-08' +-- +STMT: SelectStmt +== 039 +SELECT time without time zone 'T040506.789+08' +-- +STMT: SelectStmt +== 040 +SELECT time without time zone 'T040506.789-08' +-- +STMT: SelectStmt +== 041 +SELECT time with time zone '040506.789+08' +-- +STMT: SelectStmt +== 042 +SELECT time with time zone '040506.789-08' +-- +STMT: SelectStmt +== 043 +SELECT time with time zone 'T040506.789+08' +-- +STMT: SelectStmt +== 044 +SELECT time with time zone 'T040506.789-08' +-- +STMT: SelectStmt +== 045 +SELECT time with time zone 'T040506.789 +08' +-- +STMT: SelectStmt +== 046 +SELECT time with time zone 'T040506.789 -08' +-- +STMT: SelectStmt +== 047 +-- time with time zone should accept a date for DST resolution purposes +SELECT time with time zone 'T040506.789 America/Los_Angeles' +-- +STMT: SelectStmt +== 048 +SELECT time with time zone '2001-12-27 T040506.789 America/Los_Angeles' +-- +STMT: SelectStmt +== 049 +SELECT time with time zone 'J2452271 T040506.789 America/Los_Angeles' +-- +STMT: SelectStmt +== 050 +-- Check time formats required by ISO 8601 +SELECT time without time zone '040506.07' +-- +STMT: SelectStmt +== 051 +SELECT time without time zone '04:05:06.07' +-- +STMT: SelectStmt +== 052 +SELECT time without time zone '040506' +-- +STMT: SelectStmt +== 053 +SELECT time without time zone '04:05:06' +-- +STMT: SelectStmt +== 054 +SELECT time without time zone '0405' +-- +STMT: SelectStmt +== 055 +SELECT time without time zone '04:05' +-- +STMT: SelectStmt +== 056 +SELECT time without time zone 'T040506.07' +-- +STMT: SelectStmt +== 057 +SELECT time without time zone 'T04:05:06.07' +-- +STMT: SelectStmt +== 058 +SELECT time without time zone 'T040506' +-- +STMT: SelectStmt +== 059 +SELECT time without time zone 'T04:05:06' +-- +STMT: SelectStmt +== 060 +SELECT time without time zone 'T0405' +-- +STMT: SelectStmt +== 061 +SELECT time without time zone 'T04:05' +-- +STMT: SelectStmt +== 062 +-- 8601 says "Thh" is allowed, but we intentionally reject it as too vague +SELECT time without time zone 'T04' +-- +STMT: SelectStmt +== 063 +SELECT time with time zone '040506.07+08' +-- +STMT: SelectStmt +== 064 +SELECT time with time zone '04:05:06.07+08' +-- +STMT: SelectStmt +== 065 +SELECT time with time zone '040506+08' +-- +STMT: SelectStmt +== 066 +SELECT time with time zone '04:05:06+08' +-- +STMT: SelectStmt +== 067 +SELECT time with time zone '0405+08' +-- +STMT: SelectStmt +== 068 +SELECT time with time zone '04:05+08' +-- +STMT: SelectStmt +== 069 +SELECT time with time zone 'T040506.07+08' +-- +STMT: SelectStmt +== 070 +SELECT time with time zone 'T04:05:06.07+08' +-- +STMT: SelectStmt +== 071 +SELECT time with time zone 'T040506+08' +-- +STMT: SelectStmt +== 072 +SELECT time with time zone 'T04:05:06+08' +-- +STMT: SelectStmt +== 073 +SELECT time with time zone 'T0405+08' +-- +STMT: SelectStmt +== 074 +SELECT time with time zone 'T04:05+08' +-- +STMT: SelectStmt +== 075 +-- 8601 says "Thh" is allowed, but we intentionally reject it as too vague +SELECT time with time zone 'T04+08' +-- +STMT: SelectStmt +== 076 +SET DateStyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +== 077 +-- Check Julian dates BC +SELECT date 'J1520447' AS "Confucius' Birthday" +-- +STMT: SelectStmt +== 078 +SELECT date 'J0' AS "Julian Epoch" +-- +STMT: SelectStmt +== 079 +-- test error on dangling Julian units +SELECT date '1995-08-06 J J J' +-- +STMT: SelectStmt +== 080 +SELECT date 'J J 1520447' +-- +STMT: SelectStmt +== 081 +-- We used to accept this input style, but it was based on a misreading +-- of ISO8601, and it was never documented anyway +SELECT timestamp with time zone 'Y2001M12D27H04M05S06.789+08' +-- +STMT: SelectStmt +== 082 +SELECT timestamp with time zone 'Y2001M12D27H04MM05S06.789-08' +-- +STMT: SelectStmt +== 083 +-- conflicting fields should throw errors +SELECT date '1995-08-06 epoch' +-- +STMT: SelectStmt +== 084 +SELECT date '1995-08-06 infinity' +-- +STMT: SelectStmt +== 085 +SELECT date '1995-08-06 -infinity' +-- +STMT: SelectStmt +== 086 +SELECT date 'today infinity' +-- +STMT: SelectStmt +== 087 +SELECT date '-infinity infinity' +-- +STMT: SelectStmt +== 088 +SELECT timestamp '1995-08-06 epoch' +-- +STMT: SelectStmt +== 089 +SELECT timestamp '1995-08-06 infinity' +-- +STMT: SelectStmt +== 090 +SELECT timestamp '1995-08-06 -infinity' +-- +STMT: SelectStmt +== 091 +SELECT timestamp 'epoch 01:01:01' +-- +STMT: SelectStmt +== 092 +SELECT timestamp 'infinity 01:01:01' +-- +STMT: SelectStmt +== 093 +SELECT timestamp '-infinity 01:01:01' +-- +STMT: SelectStmt +== 094 +SELECT timestamp 'now epoch' +-- +STMT: SelectStmt +== 095 +SELECT timestamp '-infinity infinity' +-- +STMT: SelectStmt +== 096 +SELECT timestamptz '1995-08-06 epoch' +-- +STMT: SelectStmt +== 097 +SELECT timestamptz '1995-08-06 infinity' +-- +STMT: SelectStmt +== 098 +SELECT timestamptz '1995-08-06 -infinity' +-- +STMT: SelectStmt +== 099 +SELECT timestamptz 'epoch 01:01:01' +-- +STMT: SelectStmt +== 100 +SELECT timestamptz 'infinity 01:01:01' +-- +STMT: SelectStmt +== 101 +SELECT timestamptz '-infinity 01:01:01' +-- +STMT: SelectStmt +== 102 +SELECT timestamptz 'now epoch' +-- +STMT: SelectStmt +== 103 +SELECT timestamptz '-infinity infinity' +-- +STMT: SelectStmt +== 104 +|-- +-- date, time arithmetic +|-- + +SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time" +-- +STMT: SelectStmt +== 105 +SELECT date '1991-02-03' + time with time zone '04:05:06 PST' AS "Date + Time PST" +-- +STMT: SelectStmt +== 106 +SELECT date '2001-02-03' + time with time zone '04:05:06 UTC' AS "Date + Time UTC" +-- +STMT: SelectStmt +== 107 +SELECT date '1991-02-03' + interval '2 years' AS "Add Two Years" +-- +STMT: SelectStmt +== 108 +SELECT date '2001-12-13' - interval '2 years' AS "Subtract Two Years" +-- +STMT: SelectStmt +== 109 +-- subtract time from date should not make sense; use interval instead +SELECT date '1991-02-03' - time '04:05:06' AS "Subtract Time" +-- +STMT: SelectStmt +== 110 +SELECT date '1991-02-03' - time with time zone '04:05:06 UTC' AS "Subtract Time UTC" +-- +STMT: SelectStmt +== 111 +|-- +-- timestamp, interval arithmetic +|-- + +SELECT timestamp without time zone '1996-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +== 112 +SELECT timestamp without time zone '1999-03-01' - interval '1 second' AS "Feb 28" +-- +STMT: SelectStmt +== 113 +SELECT timestamp without time zone '2000-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +== 114 +SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31" +-- +STMT: SelectStmt +== 115 +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506" +-- +STMT: SelectStmt +== 116 +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244" +-- +STMT: SelectStmt +== 117 +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276" +-- +STMT: SelectStmt +== 118 +SELECT timestamp without time zone '2000-01-01' - interval '2483590 days' AS "out of range" +-- +STMT: SelectStmt +== 119 +SELECT timestamp without time zone '294276-12-31 23:59:59' + interval '9223372036854775807 microseconds' AS "out of range" +-- +STMT: SelectStmt +== 120 +SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days" +-- +STMT: SelectStmt +== 121 +-- Shorthand values +-- Not directly usable for regression testing since these are not constants. +-- So, just try to test parser and hope for the best - thomas 97/04/26 +SELECT (timestamp without time zone 'today' = (timestamp without time zone 'yesterday' + interval '1 day')) as "True" +-- +STMT: SelectStmt +== 122 +SELECT (timestamp without time zone 'today' = (timestamp without time zone 'tomorrow' - interval '1 day')) as "True" +-- +STMT: SelectStmt +== 123 +SELECT (timestamp without time zone 'today 10:30' = (timestamp without time zone 'yesterday' + interval '1 day 10 hr 30 min')) as "True" +-- +STMT: SelectStmt +== 124 +SELECT (timestamp without time zone '10:30 today' = (timestamp without time zone 'yesterday' + interval '1 day 10 hr 30 min')) as "True" +-- +STMT: SelectStmt +== 125 +SELECT (timestamp without time zone 'tomorrow' = (timestamp without time zone 'yesterday' + interval '2 days')) as "True" +-- +STMT: SelectStmt +== 126 +SELECT (timestamp without time zone 'tomorrow 16:00:00' = (timestamp without time zone 'today' + interval '1 day 16 hours')) as "True" +-- +STMT: SelectStmt +== 127 +SELECT (timestamp without time zone '16:00:00 tomorrow' = (timestamp without time zone 'today' + interval '1 day 16 hours')) as "True" +-- +STMT: SelectStmt +== 128 +SELECT (timestamp without time zone 'yesterday 12:34:56' = (timestamp without time zone 'tomorrow' - interval '2 days - 12:34:56')) as "True" +-- +STMT: SelectStmt +== 129 +SELECT (timestamp without time zone '12:34:56 yesterday' = (timestamp without time zone 'tomorrow' - interval '2 days - 12:34:56')) as "True" +-- +STMT: SelectStmt +== 130 +SELECT (timestamp without time zone 'tomorrow' > 'now') as "True" +-- +STMT: SelectStmt +== 131 +-- Convert from date and time to timestamp +-- This test used to be timestamp(date,time) but no longer allowed by grammar +-- to enable support for SQL99 timestamp type syntax. +SELECT date '1994-01-01' + time '11:00' AS "Jan_01_1994_11am" +-- +STMT: SelectStmt +== 132 +SELECT date '1994-01-01' + time '10:00' AS "Jan_01_1994_10am" +-- +STMT: SelectStmt +== 133 +SELECT date '1994-01-01' + timetz '11:00-5' AS "Jan_01_1994_8am" +-- +STMT: SelectStmt +== 134 +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 135 +SELECT d1 + interval '1 year' AS one_year FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 136 +SELECT d1 - interval '1 year' AS one_year FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 137 +SELECT timestamp with time zone '1996-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +== 138 +SELECT timestamp with time zone '1999-03-01' - interval '1 second' AS "Feb 28" +-- +STMT: SelectStmt +== 139 +SELECT timestamp with time zone '2000-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +== 140 +SELECT timestamp with time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31" +-- +STMT: SelectStmt +== 141 +SELECT timestamp with time zone '2000-01-01' - interval '2483590 days' AS "out of range" +-- +STMT: SelectStmt +== 142 +SELECT timestamp with time zone '294276-12-31 23:59:59 UTC' + interval '9223372036854775807 microseconds' AS "out of range" +-- +STMT: SelectStmt +== 143 +SELECT (timestamp with time zone 'today' = (timestamp with time zone 'yesterday' + interval '1 day')) as "True" +-- +STMT: SelectStmt +== 144 +SELECT (timestamp with time zone 'today' = (timestamp with time zone 'tomorrow' - interval '1 day')) as "True" +-- +STMT: SelectStmt +== 145 +SELECT (timestamp with time zone 'tomorrow' = (timestamp with time zone 'yesterday' + interval '2 days')) as "True" +-- +STMT: SelectStmt +== 146 +SELECT (timestamp with time zone 'tomorrow' > 'now') as "True" +-- +STMT: SelectStmt +== 147 +-- timestamp with time zone, interval arithmetic around DST change +-- (just for fun, let's use an intentionally nonstandard POSIX zone spec) +SET TIME ZONE 'CST7CDT,M4.1.0,M10.5.0' +-- +STMT: VariableSetStmt +== 148 +SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' as "Apr 3, 12:00" +-- +STMT: SelectStmt +== 149 +SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '24 hours' as "Apr 3, 13:00" +-- +STMT: SelectStmt +== 150 +SELECT timestamp with time zone '2005-04-03 12:00-06' - interval '1 day' as "Apr 2, 12:00" +-- +STMT: SelectStmt +== 151 +SELECT timestamp with time zone '2005-04-03 12:00-06' - interval '24 hours' as "Apr 2, 11:00" +-- +STMT: SelectStmt +== 152 +RESET TIME ZONE +-- +STMT: VariableSetStmt +== 153 +SELECT timestamptz(date '1994-01-01', time '11:00') AS "Jan_01_1994_10am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 154 +SELECT timestamptz(date '1994-01-01', time '10:00') AS "Jan_01_1994_9am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-8') AS "Jan_01_1994_11am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 156 +SELECT timestamptz(date '1994-01-01', time with time zone '10:00-8') AS "Jan_01_1994_10am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 157 +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 158 +SELECT d1 + interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +STMT: SelectStmt +== 159 +SELECT d1 - interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +STMT: SelectStmt +== 160 +|-- +-- time, interval arithmetic +|-- + +SELECT CAST(time '01:02' AS interval) AS "+01:02" +-- +STMT: SelectStmt +== 161 +SELECT CAST(interval '02:03' AS time) AS "02:03:00" +-- +STMT: SelectStmt +== 162 +SELECT CAST(interval '-02:03' AS time) AS "21:57:00" +-- +STMT: SelectStmt +== 163 +SELECT CAST(interval '-9223372022400000000 us' AS time) AS "00:00:00" +-- +STMT: SelectStmt +== 164 +SELECT time '01:30' + interval '02:01' AS "03:31:00" +-- +STMT: SelectStmt +== 165 +SELECT time '01:30' - interval '02:01' AS "23:29:00" +-- +STMT: SelectStmt +== 166 +SELECT time '02:30' + interval '36:01' AS "14:31:00" +-- +STMT: SelectStmt +== 167 +SELECT time '03:30' + interval '1 month 04:01' AS "07:31:00" +-- +STMT: SelectStmt +== 168 +SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01" +-- +STMT: SelectStmt +== 169 +SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08" +-- +STMT: SelectStmt +== 170 +SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08" +-- +STMT: SelectStmt +== 171 +SELECT time with time zone '02:30-08' + interval '36:01' AS "14:31:00-08" +-- +STMT: SelectStmt +== 172 +-- These two tests cannot be used because they default to current timezone, +-- which may be either -08 or -07 depending on the time of year. +-- SELECT time with time zone '01:30' + interval '02:01' AS "03:31:00-08"; +-- SELECT time with time zone '03:30' + interval '1 month 04:01' AS "07:31:00-08"; +-- Try the following two tests instead, as a poor substitute + +SELECT CAST(CAST(date 'today' + time with time zone '05:30' + + interval '02:01' AS time with time zone) AS time) AS "07:31:00" +-- +STMT: SelectStmt +== 173 +SELECT CAST(cast(date 'today' + time with time zone '03:30' + + interval '1 month 04:01' as timestamp without time zone) AS time) AS "07:31:00" +-- +STMT: SelectStmt +== 174 +SELECT t.d1 AS t, i.f1 AS i, t.d1 + i.f1 AS "add", t.d1 - i.f1 AS "subtract" + FROM TIMESTAMP_TBL t, INTERVAL_TBL i + WHERE t.d1 BETWEEN '1990-01-01' AND '2001-01-01' + AND i.f1 BETWEEN '00:00' AND '23:00' + ORDER BY 1,2 +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "i"="interval_tbl" +ALIAS: "t"="timestamp_tbl" +FILTER: schema="" table="t" column="d1" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 175 +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 + WHERE isfinite(i.f1) + ORDER BY 1,2 +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "i"="interval_tbl" +ALIAS: "t"="time_tbl" +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 176 +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 + WHERE isfinite(i.f1) + ORDER BY 1,2 +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "i"="interval_tbl" +ALIAS: "t"="timetz_tbl" +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 177 +-- 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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 178 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 179 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 180 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 181 +SELECT (timestamp with time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp with time zone '2000-11-27', interval '12 hours') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 182 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 183 +-- 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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 184 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 185 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 186 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 187 +SELECT (timestamp without time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp without time zone '2000-11-27', interval '12 hours') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 188 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 189 +-- test time and interval +SELECT (time '00:00', time '01:00') + OVERLAPS (time '00:30', time '01:30') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 190 +SELECT (time '00:00', interval '1 hour') + OVERLAPS (time '00:30', interval '1 hour') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 191 +SELECT (time '00:00', interval '1 hour') + OVERLAPS (time '01:30', interval '1 hour') AS "False" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 192 +-- 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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 193 +CREATE TABLE TEMP_TIMESTAMP (f1 timestamp with time zone) +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=DDL +STMT: CreateStmt +== 194 +-- 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' +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=DML +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +FILTER: schema="" table="" column="d1" +STMT: InsertStmt +STMT: SelectStmt +== 195 +SELECT f1 AS "timestamp" + FROM TEMP_TIMESTAMP + ORDER BY "timestamp" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +STMT: SelectStmt +== 196 +SELECT 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" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "d"="temp_timestamp" +ALIAS: "t"="interval_tbl" +STMT: SelectStmt +== 197 +SELECT d.f1 AS "timestamp", t.f1 AS "interval", d.f1 - t.f1 AS minus + FROM TEMP_TIMESTAMP d, INTERVAL_TBL t + ORDER BY minus, "timestamp", "interval" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "d"="temp_timestamp" +ALIAS: "t"="interval_tbl" +STMT: SelectStmt +== 198 +SELECT 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 +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +ALIAS: "d"="temp_timestamp" +STMT: SelectStmt +== 199 +SELECT 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 +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +ALIAS: "d1"="temp_timestamp" +ALIAS: "d2"="temp_timestamp" +STMT: SelectStmt +== 200 +|-- +-- Conversions +|-- + +SELECT f1 AS "timestamp", date(f1) AS date + FROM TEMP_TIMESTAMP + WHERE f1 <> timestamp 'now' + ORDER BY date, "timestamp" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +FUNCTION: name="date" function="date" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 201 +DROP TABLE TEMP_TIMESTAMP +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=DDL +STMT: DropStmt +== 202 +|-- +-- Comparisons between datetime types, especially overflow cases +--- + +SELECT '2202020-10-05'::date::timestamp +-- +STMT: SelectStmt +== 203 +-- fail +SELECT '2202020-10-05'::date > '2020-10-05'::timestamp as t +-- +STMT: SelectStmt +== 204 +SELECT '2020-10-05'::timestamp > '2202020-10-05'::date as f +-- +STMT: SelectStmt +== 205 +SELECT '2202020-10-05'::date::timestamptz +-- +STMT: SelectStmt +== 206 +-- fail +SELECT '2202020-10-05'::date > '2020-10-05'::timestamptz as t +-- +STMT: SelectStmt +== 207 +SELECT '2020-10-05'::timestamptz > '2202020-10-05'::date as f +-- +STMT: SelectStmt +== 208 +-- This conversion may work depending on timezone +SELECT '4714-11-24 BC'::date::timestamptz +-- +STMT: SelectStmt +== 209 +SET TimeZone = 'UTC-2' +-- +STMT: VariableSetStmt +== 210 +SELECT '4714-11-24 BC'::date::timestamptz +-- +STMT: SelectStmt +== 211 +-- fail + +SELECT '4714-11-24 BC'::date < '2020-10-05'::timestamptz as t +-- +STMT: SelectStmt +== 212 +SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::date as t +-- +STMT: SelectStmt +== 213 +SELECT '4714-11-24 BC'::timestamp < '2020-10-05'::timestamptz as t +-- +STMT: SelectStmt +== 214 +SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::timestamp as t +-- +STMT: SelectStmt +== 215 +RESET TimeZone +-- +STMT: VariableSetStmt +== 216 +|-- +-- Tests for BETWEEN +|-- + +explain (costs off) +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 217 +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 218 +explain (costs off) +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 219 +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 220 +explain (costs off) +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 221 +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 222 +explain (costs off) +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 223 +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 224 +|-- +-- Formats +|-- + +SET DateStyle TO 'US,Postgres' +-- +STMT: VariableSetStmt +== 225 +SHOW DateStyle +-- +STMT: VariableShowStmt +== 226 +SELECT d1 AS us_postgres FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 227 +SET DateStyle TO 'US,ISO' +-- +STMT: VariableSetStmt +== 228 +SELECT d1 AS us_iso FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 229 +SET DateStyle TO 'US,SQL' +-- +STMT: VariableSetStmt +== 230 +SHOW DateStyle +-- +STMT: VariableShowStmt +== 231 +SELECT d1 AS us_sql FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 232 +SET DateStyle TO 'European,Postgres' +-- +STMT: VariableSetStmt +== 233 +SHOW DateStyle +-- +STMT: VariableShowStmt +== 234 +INSERT INTO TIMESTAMP_TBL VALUES('13/06/1957') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 235 +SELECT count(*) as one FROM TIMESTAMP_TBL WHERE d1 = 'Jun 13 1957' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 236 +SELECT d1 AS european_postgres FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 237 +SET DateStyle TO 'European,ISO' +-- +STMT: VariableSetStmt +== 238 +SHOW DateStyle +-- +STMT: VariableShowStmt +== 239 +SELECT d1 AS european_iso FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 240 +SET DateStyle TO 'European,SQL' +-- +STMT: VariableSetStmt +== 241 +SHOW DateStyle +-- +STMT: VariableShowStmt +== 242 +SELECT d1 AS european_sql FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 243 +RESET DateStyle +-- +STMT: VariableSetStmt +== 244 +|-- +-- to_timestamp() +|-- + +SELECT to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 245 +SELECT to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 246 +SELECT to_timestamp('2011$03!18 23_38_15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 247 +SELECT to_timestamp('1985 January 12', 'YYYY FMMonth DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 248 +SELECT to_timestamp('1985 FMMonth 12', 'YYYY "FMMonth" DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 249 +SELECT to_timestamp('1985 \ 12', 'YYYY \\ DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 250 +SELECT to_timestamp('My birthday-> Year: 1976, Month: May, Day: 16', + '"My birthday-> Year:" YYYY, "Month:" FMMonth, "Day:" DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 251 +SELECT to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 252 +SELECT to_timestamp('15 "text between quote marks" 98 54 45', + E'HH24 "\\"text between quote marks\\"" YY MI SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 253 +SELECT to_timestamp('05121445482000', 'MMDDHH24MISSYYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 254 +SELECT to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 255 +SELECT to_timestamp('97/Feb/16', 'YYMonDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 256 +SELECT to_timestamp('97/Feb/16', 'YY:Mon:DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 257 +SELECT to_timestamp('97/Feb/16', 'FXYY:Mon:DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 258 +SELECT to_timestamp('97/Feb/16', 'FXYY/Mon/DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 259 +SELECT to_timestamp('19971116', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 260 +SELECT to_timestamp('20000-1116', 'YYYY-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 261 +SELECT to_timestamp('1997 AD 11 16', 'YYYY BC MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 262 +SELECT to_timestamp('1997 BC 11 16', 'YYYY BC MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 263 +SELECT to_timestamp('1997 A.D. 11 16', 'YYYY B.C. MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 264 +SELECT to_timestamp('1997 B.C. 11 16', 'YYYY B.C. MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 265 +SELECT to_timestamp('9-1116', 'Y-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 266 +SELECT to_timestamp('95-1116', 'YY-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 267 +SELECT to_timestamp('995-1116', 'YYY-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 268 +SELECT to_timestamp('2005426', 'YYYYWWD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 269 +SELECT to_timestamp('2005300', 'YYYYDDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 270 +SELECT to_timestamp('2005527', 'IYYYIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 271 +SELECT to_timestamp('005527', 'IYYIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 272 +SELECT to_timestamp('05527', 'IYIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 273 +SELECT to_timestamp('5527', 'IIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 274 +SELECT to_timestamp('2005364', 'IYYYIDDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 275 +SELECT to_timestamp('20050302', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 276 +SELECT to_timestamp('2005 03 02', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 277 +SELECT to_timestamp(' 2005 03 02', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 278 +SELECT to_timestamp(' 20050302', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 279 +SELECT to_timestamp('2011-12-18 11:38 AM', 'YYYY-MM-DD HH12:MI PM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 280 +SELECT to_timestamp('2011-12-18 11:38 PM', 'YYYY-MM-DD HH12:MI PM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 281 +SELECT to_timestamp('2011-12-18 11:38 A.M.', 'YYYY-MM-DD HH12:MI P.M.') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 282 +SELECT to_timestamp('2011-12-18 11:38 P.M.', 'YYYY-MM-DD HH12:MI P.M.') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 283 +SELECT to_timestamp('2011-12-18 11:38 +05', 'YYYY-MM-DD HH12:MI TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 284 +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 285 +SELECT to_timestamp('2011-12-18 11:38 +05:20', 'YYYY-MM-DD HH12:MI TZH:TZM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 286 +SELECT to_timestamp('2011-12-18 11:38 -05:20', 'YYYY-MM-DD HH12:MI TZH:TZM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 287 +SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 288 +SELECT to_timestamp('2011-12-18 11:38 EST', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 289 +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 290 +SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 291 +SELECT to_timestamp('2011-12-18 11:38 MSK', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 292 +-- dyntz +SELECT to_timestamp('2011-12-18 11:38ESTFOO24', 'YYYY-MM-DD HH12:MITZFOOSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 293 +SELECT to_timestamp('2011-12-18 11:38-05FOO24', 'YYYY-MM-DD HH12:MITZFOOSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 294 +SELECT to_timestamp('2011-12-18 11:38 JUNK', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 295 +-- error +SELECT to_timestamp('2011-12-18 11:38 ...', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 296 +-- error + +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 297 +SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 298 +SELECT to_timestamp('2011-12-18 11:38 +xyz', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 299 +-- error +SELECT to_timestamp('2011-12-18 11:38 +01:xyz', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 300 +-- error + +SELECT to_timestamp('2018-11-02 12:34:56.025', 'YYYY-MM-DD HH24:MI:SS.MS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 301 +SELECT i, to_timestamp('2018-11-02 12:34:56', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 302 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 303 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 304 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 305 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 306 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 307 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 308 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 309 +SELECT i, to_timestamp('20181102123456123456', 'YYYYMMDDHH24MISSFF' || i) FROM generate_series(1, 6) i +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 310 +SELECT to_date('1 4 1902', 'Q MM YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 311 +-- Q is ignored +SELECT to_date('3 4 21 01', 'W MM CC YY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 312 +SELECT to_date('2458872', 'J') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 313 +|-- +-- Check handling of BC dates +|-- + +SELECT to_date('44-02-01 BC','YYYY-MM-DD BC') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 314 +SELECT to_date('-44-02-01','YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 315 +SELECT to_date('-44-02-01 BC','YYYY-MM-DD BC') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 316 +SELECT to_timestamp('44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 317 +SELECT to_timestamp('-44-02-01 11:12:13','YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 318 +SELECT to_timestamp('-44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 319 +|-- +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 320 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 321 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 322 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 323 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 324 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 325 +SELECT to_timestamp('2000+ JUN', 'YYYY/MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 326 +SELECT to_timestamp(' 2000 +JUN', 'YYYY/MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 327 +SELECT to_timestamp(' 2000 +JUN', 'YYYY//MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 328 +SELECT to_timestamp('2000 +JUN', 'YYYY//MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 329 +SELECT to_timestamp('2000 + JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 330 +SELECT to_timestamp('2000 ++ JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 331 +SELECT to_timestamp('2000 + + JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 332 +SELECT to_timestamp('2000 + + JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 333 +SELECT to_timestamp('2000 -10', 'YYYY TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 334 +SELECT to_timestamp('2000 -10', 'YYYY TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 335 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 336 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 337 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 338 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 339 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 340 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 341 +SELECT to_date('2011 12 18', 'YYYYxMMxDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 342 +SELECT to_date('2011x 12x 18', 'YYYYxMMxDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 343 +SELECT to_date('2011 x12 x18', 'YYYYxMMxDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 344 +|-- +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 345 +-- Insufficient characters in the source string: +SELECT to_timestamp('19971', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 346 +-- Insufficient digit characters for a single node: +SELECT to_timestamp('19971)24', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 347 +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 348 +SELECT to_timestamp('Fri 1-January-1999', 'DY DD MON YYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 349 +SELECT to_timestamp('Fri 1-Jan-1999', 'DY DD MON YYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 350 +-- ok + +-- Value clobbering: +SELECT to_timestamp('1997-11-Jan-16', 'YYYY-MM-Mon-DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 351 +-- Non-numeric input: +SELECT to_timestamp('199711xy', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 352 +-- Input that doesn't fit in an int: +SELECT to_timestamp('10000000000', 'FMYYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 353 +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 354 +SELECT to_timestamp('2016-06-13 15:60:00', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 355 +SELECT to_timestamp('2016-06-13 15:50:60', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 356 +SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 357 +-- ok +SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 358 +SELECT to_timestamp('2016-13-01 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 359 +SELECT to_timestamp('2016-02-30 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 360 +SELECT to_timestamp('2016-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 361 +-- ok +SELECT to_timestamp('2015-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 362 +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 363 +-- ok +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 364 +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 365 +-- ok +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 366 +SELECT to_date('2016-13-10', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 367 +SELECT to_date('2016-02-30', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 368 +SELECT to_date('2016-02-29', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 369 +-- ok +SELECT to_date('2015-02-29', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 370 +SELECT to_date('2015 365', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 371 +-- ok +SELECT to_date('2015 366', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 372 +SELECT to_date('2016 365', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 373 +-- ok +SELECT to_date('2016 366', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 374 +-- ok +SELECT to_date('2016 367', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 375 +SELECT to_date('0000-02-01','YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 376 +-- allowed, though it shouldn't be + +-- to_char's TZ format code produces zone abbrev if known +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 377 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS tz') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 378 +|-- +-- Check behavior with SQL-style fixed-GMT-offset time zone (cf bug #8572) +|-- + +SET TIME ZONE 'America/New_York' +-- +STMT: VariableSetStmt +== 379 +SET TIME ZONE '-1.5' +-- +STMT: VariableSetStmt +== 380 +SHOW TIME ZONE +-- +STMT: VariableShowStmt +== 381 +SELECT '2012-12-12 12:00'::timestamptz +-- +STMT: SelectStmt +== 382 +SELECT '2012-12-12 12:00 America/New_York'::timestamptz +-- +STMT: SelectStmt +== 383 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 384 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSS') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 385 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSSS') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 386 +SET TIME ZONE '+2' +-- +STMT: VariableSetStmt +== 387 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 388 +RESET TIME ZONE +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/identity.metadata.json b/parser/testdata/summary/postgres_regress/identity.metadata.json new file mode 100644 index 0000000..a6ce2f7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/identity.metadata.json @@ -0,0 +1,274 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270" + ] +} diff --git a/parser/testdata/summary/postgres_regress/identity.test b/parser/testdata/summary/postgres_regress/identity.test new file mode 100644 index 0000000..57a15d4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/identity.test @@ -0,0 +1,1600 @@ +== 001 +-- sanity check of system catalog +SELECT attrelid, attname, attidentity FROM pg_attribute WHERE attidentity NOT IN ('', 'a', 'd') +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attidentity" +STMT: SelectStmt +== 002 +CREATE TABLE itest1 (a int generated by default as identity, b text) +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE itest2 (a bigint generated always as identity, b text) +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE itest3 (a smallint generated by default as identity (start with 7 increment by 5), b text) +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: CreateStmt +== 005 +ALTER TABLE itest3 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +== 006 +-- error + +SELECT table_name, column_name, column_default, is_nullable, is_identity, identity_generation, identity_start, identity_increment, identity_maximum, identity_minimum, identity_cycle FROM information_schema.columns WHERE table_name LIKE 'itest_' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 007 +-- internal sequences should not be shown here +SELECT sequence_name FROM information_schema.sequences WHERE sequence_name LIKE 'itest%' +-- +TABLE: name="information_schema.sequences" schema="information_schema" table="sequences" ctx=Select +FILTER: schema="" table="" column="sequence_name" +STMT: SelectStmt +== 008 +SELECT pg_get_serial_sequence('itest1', 'a') +-- +FUNCTION: name="pg_get_serial_sequence" function="pg_get_serial_sequence" schema="" ctx=Call +STMT: SelectStmt +== 009 +CREATE TABLE itest4 (a int, b text) +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: CreateStmt +== 010 +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 011 +-- error, requires NOT NULL +ALTER TABLE itest4 ALTER COLUMN a SET NOT NULL +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 012 +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 013 +-- ok +ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 014 +-- error, disallowed +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 015 +-- error, already set +ALTER TABLE itest4 ALTER COLUMN b ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 016 +-- error, wrong data type + +-- for later +ALTER TABLE itest4 ALTER COLUMN b SET DEFAULT '' +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 017 +-- invalid column type +CREATE TABLE itest_err_1 (a text generated by default as identity) +-- +TABLE: name="itest_err_1" schema="" table="itest_err_1" ctx=DDL +STMT: CreateStmt +== 018 +-- duplicate identity +CREATE TABLE itest_err_2 (a int generated always as identity generated by default as identity) +-- +TABLE: name="itest_err_2" schema="" table="itest_err_2" ctx=DDL +STMT: CreateStmt +== 019 +-- cannot have default and identity +CREATE TABLE itest_err_3 (a int default 5 generated by default as identity) +-- +TABLE: name="itest_err_3" schema="" table="itest_err_3" ctx=DDL +STMT: CreateStmt +== 020 +-- cannot combine serial and identity +CREATE TABLE itest_err_4 (a serial generated by default as identity) +-- +TABLE: name="itest_err_4" schema="" table="itest_err_4" ctx=DDL +STMT: CreateStmt +== 021 +INSERT INTO itest1 DEFAULT VALUES +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +== 022 +INSERT INTO itest1 DEFAULT VALUES +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +== 023 +INSERT INTO itest2 DEFAULT VALUES +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +== 024 +INSERT INTO itest2 DEFAULT VALUES +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +== 025 +INSERT INTO itest3 DEFAULT VALUES +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +== 026 +INSERT INTO itest3 DEFAULT VALUES +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +== 027 +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +== 028 +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +== 029 +SELECT * FROM itest1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=Select +STMT: SelectStmt +== 030 +SELECT * FROM itest2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=Select +STMT: SelectStmt +== 031 +SELECT * FROM itest3 +-- +TABLE: name="itest3" schema="" table="itest3" ctx=Select +STMT: SelectStmt +== 032 +SELECT * FROM itest4 +-- +TABLE: name="itest4" schema="" table="itest4" ctx=Select +STMT: SelectStmt +== 033 +-- VALUES RTEs + +CREATE TABLE itest5 (a int generated always as identity, b text) +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: CreateStmt +== 034 +INSERT INTO itest5 VALUES (1, 'a') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +-- error +INSERT INTO itest5 VALUES (DEFAULT, 'a') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +-- ok +INSERT INTO itest5 VALUES (2, 'b'), (3, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +-- error +INSERT INTO itest5 VALUES (DEFAULT, 'b'), (3, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +-- error +INSERT INTO itest5 VALUES (2, 'b'), (DEFAULT, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +-- error +INSERT INTO itest5 VALUES (DEFAULT, 'b'), (DEFAULT, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +-- ok + +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-1, 'aa') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-2, 'bb'), (-3, 'cc') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'dd'), (-4, 'ee') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-5, 'ff'), (DEFAULT, 'gg') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'hh'), (DEFAULT, 'ii') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-1, 'aaa') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-2, 'bbb'), (-3, 'ccc') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'ddd'), (-4, 'eee') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-5, 'fff'), (DEFAULT, 'ggg') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'hhh'), (DEFAULT, 'iii') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +SELECT * FROM itest5 +-- +TABLE: name="itest5" schema="" table="itest5" ctx=Select +STMT: SelectStmt +== 051 +DROP TABLE itest5 +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: DropStmt +== 052 +INSERT INTO itest3 VALUES (DEFAULT, 'a') +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c') +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +SELECT * FROM itest3 +-- +TABLE: name="itest3" schema="" table="itest3" ctx=Select +STMT: SelectStmt +== 055 +-- OVERRIDING tests + +-- GENERATED BY DEFAULT + +-- This inserts the row as presented: +INSERT INTO itest1 VALUES (10, 'xyz') +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +-- With GENERATED BY DEFAULT, OVERRIDING SYSTEM VALUE is not allowed +-- by the standard, but we allow it as a no-op, since it is of use if +-- there are multiple identity columns in a table, which is also an +-- extension. +INSERT INTO itest1 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz') +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +-- This ignores the 30 and uses the sequence value instead: +INSERT INTO itest1 OVERRIDING USER VALUE VALUES (30, 'xyz') +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +SELECT * FROM itest1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=Select +STMT: SelectStmt +== 059 +-- GENERATED ALWAYS + +-- This is an error: +INSERT INTO itest2 VALUES (10, 'xyz') +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +-- This inserts the row as presented: +INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz') +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +-- This ignores the 30 and uses the sequence value instead: +INSERT INTO itest2 OVERRIDING USER VALUE VALUES (30, 'xyz') +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +SELECT * FROM itest2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=Select +STMT: SelectStmt +== 063 +-- UPDATE tests + +-- GENERATED BY DEFAULT is not restricted. +UPDATE itest1 SET a = 101 WHERE a = 1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: UpdateStmt +== 064 +UPDATE itest1 SET a = DEFAULT WHERE a = 2 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: UpdateStmt +== 065 +SELECT * FROM itest1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=Select +STMT: SelectStmt +== 066 +-- GENERATED ALWAYS allows only DEFAULT. +UPDATE itest2 SET a = 101 WHERE a = 1 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: UpdateStmt +== 067 +-- error +UPDATE itest2 SET a = DEFAULT WHERE a = 2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: UpdateStmt +== 068 +-- ok +SELECT * FROM itest2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=Select +STMT: SelectStmt +== 069 +-- COPY tests + +CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint) +-- +TABLE: name="itest9" schema="" table="itest9" ctx=DDL +STMT: CreateStmt +== 070 +COPY itest9 FROM stdin +-- +TABLE: name="itest9" schema="" table="itest9" ctx=Select +STMT: CopyStmt +== 071 +COPY itest9 (b, c) FROM stdin +-- +TABLE: name="itest9" schema="" table="itest9" ctx=Select +STMT: CopyStmt +== 072 +SELECT * FROM itest9 ORDER BY c +-- +TABLE: name="itest9" schema="" table="itest9" ctx=Select +STMT: SelectStmt +== 073 +-- DROP IDENTITY tests + +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 074 +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 075 +-- error +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY IF EXISTS +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 076 +-- noop + +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +== 077 +-- fails because NOT NULL is not dropped +ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +== 078 +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +== 079 +SELECT * FROM itest4 +-- +TABLE: name="itest4" schema="" table="itest4" ctx=Select +STMT: SelectStmt +== 080 +-- check that sequence is removed +SELECT sequence_name FROM itest4_a_seq +-- +TABLE: name="itest4_a_seq" schema="" table="itest4_a_seq" ctx=Select +STMT: SelectStmt +== 081 +-- test views + +CREATE TABLE itest10 (a int generated by default as identity, b text) +-- +TABLE: name="itest10" schema="" table="itest10" ctx=DDL +STMT: CreateStmt +== 082 +CREATE TABLE itest11 (a int generated always as identity, b text) +-- +TABLE: name="itest11" schema="" table="itest11" ctx=DDL +STMT: CreateStmt +== 083 +CREATE VIEW itestv10 AS SELECT * FROM itest10 +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DDL +TABLE: name="itest10" schema="" table="itest10" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 084 +CREATE VIEW itestv11 AS SELECT * FROM itest11 +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DDL +TABLE: name="itest11" schema="" table="itest11" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 085 +INSERT INTO itestv10 DEFAULT VALUES +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +== 086 +INSERT INTO itestv10 DEFAULT VALUES +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +== 087 +INSERT INTO itestv11 DEFAULT VALUES +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +== 088 +INSERT INTO itestv11 DEFAULT VALUES +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +== 089 +SELECT * FROM itestv10 +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=Select +STMT: SelectStmt +== 090 +SELECT * FROM itestv11 +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=Select +STMT: SelectStmt +== 091 +INSERT INTO itestv10 VALUES (10, 'xyz') +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +INSERT INTO itestv10 OVERRIDING USER VALUE VALUES (11, 'xyz') +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +SELECT * FROM itestv10 +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=Select +STMT: SelectStmt +== 094 +INSERT INTO itestv11 VALUES (10, 'xyz') +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +INSERT INTO itestv11 OVERRIDING SYSTEM VALUE VALUES (11, 'xyz') +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +SELECT * FROM itestv11 +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=Select +STMT: SelectStmt +== 097 +DROP VIEW itestv10, itestv11 +-- +STMT: DropStmt +== 098 +-- ADD COLUMN + +CREATE TABLE itest13 (a int) +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DDL +STMT: CreateStmt +== 099 +-- add column to empty table +ALTER TABLE itest13 ADD COLUMN b int GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DDL +STMT: AlterTableStmt +== 100 +INSERT INTO itest13 VALUES (1), (2), (3) +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +-- add column to populated table +ALTER TABLE itest13 ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DDL +STMT: AlterTableStmt +== 102 +SELECT * FROM itest13 +-- +TABLE: name="itest13" schema="" table="itest13" ctx=Select +STMT: SelectStmt +== 103 +-- various ALTER COLUMN tests + +-- fail, not allowed for identity columns +ALTER TABLE itest1 ALTER COLUMN a SET DEFAULT 1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DDL +STMT: AlterTableStmt +== 104 +-- fail, not allowed, already has a default +CREATE TABLE itest5 (a serial, b text) +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: CreateStmt +== 105 +ALTER TABLE itest5 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: AlterTableStmt +== 106 +ALTER TABLE itest3 ALTER COLUMN a TYPE int +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +== 107 +SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regclass +-- +TABLE: name="pg_sequence" schema="" table="pg_sequence" ctx=Select +FILTER: schema="" table="" column="seqrelid" +STMT: SelectStmt +== 108 +ALTER TABLE itest3 ALTER COLUMN a TYPE text +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +== 109 +-- error + +-- check that unlogged propagates to sequence +CREATE UNLOGGED TABLE itest17 (a int NOT NULL, b text) +-- +TABLE: name="itest17" schema="" table="itest17" ctx=DDL +STMT: CreateStmt +== 110 +ALTER TABLE itest17 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest17" schema="" table="itest17" ctx=DDL +STMT: AlterTableStmt +== 111 +ALTER TABLE itest17 ADD COLUMN c int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest17" schema="" table="itest17" ctx=DDL +STMT: AlterTableStmt +== 112 +CREATE TABLE itest18 (a int NOT NULL, b text) +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: CreateStmt +== 113 +ALTER TABLE itest18 SET UNLOGGED, ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: AlterTableStmt +== 114 +ALTER TABLE itest18 SET LOGGED +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: AlterTableStmt +== 115 +ALTER TABLE itest18 SET UNLOGGED +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: AlterTableStmt +== 116 +-- kinda silly to change property in the same command, but it should work +ALTER TABLE itest3 + ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY, + ALTER COLUMN c SET GENERATED ALWAYS +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +== 117 +-- ALTER COLUMN ... SET + +CREATE TABLE itest6 (a int GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DDL +STMT: CreateStmt +== 118 +INSERT INTO itest6 DEFAULT VALUES +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DML +STMT: InsertStmt +== 119 +ALTER TABLE itest6 ALTER COLUMN a SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 100 RESTART +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DDL +STMT: AlterTableStmt +== 120 +INSERT INTO itest6 DEFAULT VALUES +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DML +STMT: InsertStmt +== 121 +INSERT INTO itest6 DEFAULT VALUES +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DML +STMT: InsertStmt +== 122 +SELECT * FROM itest6 +-- +TABLE: name="itest6" schema="" table="itest6" ctx=Select +STMT: SelectStmt +== 123 +SELECT table_name, column_name, is_identity, identity_generation FROM information_schema.columns WHERE table_name = 'itest6' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 124 +ALTER TABLE itest6 ALTER COLUMN b SET INCREMENT BY 2 +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DDL +STMT: AlterTableStmt +== 125 +-- fail, not identity + + +-- prohibited direct modification of sequence + +ALTER SEQUENCE itest6_a_seq OWNED BY NONE +-- +STMT: AlterSeqStmt +== 126 +-- inheritance + +CREATE TABLE itest7 (a int GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: CreateStmt +== 127 +INSERT INTO itest7 DEFAULT VALUES +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DML +STMT: InsertStmt +== 128 +SELECT * FROM itest7 +-- +TABLE: name="itest7" schema="" table="itest7" ctx=Select +STMT: SelectStmt +== 129 +-- identity property is not inherited +CREATE TABLE itest7a (b text) INHERITS (itest7) +-- +TABLE: name="itest7a" schema="" table="itest7a" ctx=DDL +STMT: CreateStmt +== 130 +-- make column identity in child table +CREATE TABLE itest7b (a int) +-- +TABLE: name="itest7b" schema="" table="itest7b" ctx=DDL +STMT: CreateStmt +== 131 +CREATE TABLE itest7c (a int GENERATED ALWAYS AS IDENTITY) INHERITS (itest7b) +-- +TABLE: name="itest7c" schema="" table="itest7c" ctx=DDL +STMT: CreateStmt +== 132 +INSERT INTO itest7c DEFAULT VALUES +-- +TABLE: name="itest7c" schema="" table="itest7c" ctx=DML +STMT: InsertStmt +== 133 +SELECT * FROM itest7c +-- +TABLE: name="itest7c" schema="" table="itest7c" ctx=Select +STMT: SelectStmt +== 134 +CREATE TABLE itest7d (a int not null) +-- +TABLE: name="itest7d" schema="" table="itest7d" ctx=DDL +STMT: CreateStmt +== 135 +CREATE TABLE itest7e () INHERITS (itest7d) +-- +TABLE: name="itest7e" schema="" table="itest7e" ctx=DDL +STMT: CreateStmt +== 136 +ALTER TABLE itest7d ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest7d" schema="" table="itest7d" ctx=DDL +STMT: AlterTableStmt +== 137 +ALTER TABLE itest7d ADD COLUMN b int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest7d" schema="" table="itest7d" ctx=DDL +STMT: AlterTableStmt +== 138 +-- error + +SELECT table_name, column_name, is_nullable, is_identity, identity_generation FROM information_schema.columns WHERE table_name LIKE 'itest7%' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 139 +-- These ALTER TABLE variants will not recurse. +ALTER TABLE itest7 ALTER COLUMN a SET GENERATED BY DEFAULT +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: AlterTableStmt +== 140 +ALTER TABLE itest7 ALTER COLUMN a RESTART +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: AlterTableStmt +== 141 +ALTER TABLE itest7 ALTER COLUMN a DROP IDENTITY +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: AlterTableStmt +== 142 +-- privileges +CREATE USER regress_identity_user1 +-- +STMT: CreateRoleStmt +== 143 +CREATE TABLE itest8 (a int GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: CreateStmt +== 144 +GRANT SELECT, INSERT ON itest8 TO regress_identity_user1 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: GrantStmt +== 145 +SET ROLE regress_identity_user1 +-- +STMT: VariableSetStmt +== 146 +INSERT INTO itest8 DEFAULT VALUES +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DML +STMT: InsertStmt +== 147 +SELECT * FROM itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=Select +STMT: SelectStmt +== 148 +RESET ROLE +-- +STMT: VariableSetStmt +== 149 +DROP TABLE itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: DropStmt +== 150 +DROP USER regress_identity_user1 +-- +STMT: DropRoleStmt +== 151 +-- multiple steps in ALTER TABLE +CREATE TABLE itest8 (f1 int) +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: CreateStmt +== 152 +ALTER TABLE itest8 + ADD COLUMN f2 int NOT NULL, + ALTER COLUMN f2 ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +== 153 +ALTER TABLE itest8 + ADD COLUMN f3 int NOT NULL, + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY, + ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT 10 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +== 154 +ALTER TABLE itest8 + ADD COLUMN f4 int +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +== 155 +ALTER TABLE itest8 + ALTER COLUMN f4 SET NOT NULL, + ALTER COLUMN f4 ADD GENERATED ALWAYS AS IDENTITY, + ALTER COLUMN f4 SET DATA TYPE bigint +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +== 156 +ALTER TABLE itest8 + ADD COLUMN f5 int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +== 157 +ALTER TABLE itest8 + ALTER COLUMN f5 DROP IDENTITY, + ALTER COLUMN f5 DROP NOT NULL, + ALTER COLUMN f5 SET DATA TYPE bigint +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +== 158 +INSERT INTO itest8 VALUES(0), (1) +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +-- This does not work when the table isn't empty. That's intentional, +-- since ADD GENERATED should only affect later insertions: +ALTER TABLE itest8 + ADD COLUMN f22 int NOT NULL, + ALTER COLUMN f22 ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +== 160 +TABLE itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=Select +STMT: SelectStmt +== 161 +DROP TABLE itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: DropStmt +== 162 +-- typed tables (currently not supported) + +CREATE TYPE itest_type AS (f1 integer, f2 text, f3 bigint) +-- +STMT: CompositeTypeStmt +== 163 +CREATE TABLE itest12 OF itest_type (f1 WITH OPTIONS GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest12" schema="" table="itest12" ctx=DDL +STMT: CreateStmt +== 164 +-- error +DROP TYPE itest_type CASCADE +-- +STMT: DropStmt +== 165 +-- table partitions + +-- partitions inherit identity column and share sequence +CREATE TABLE pitest1 (f1 date NOT NULL, f2 text, f3 bigint generated always as identity) PARTITION BY RANGE (f1) +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: CreateStmt +== 166 +-- new partition +CREATE TABLE pitest1_p1 PARTITION OF pitest1 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest1_p1" schema="" table="pitest1_p1" ctx=DDL +STMT: CreateStmt +== 167 +INSERT into pitest1(f1, f2) VALUES ('2016-07-2', 'from pitest1') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +INSERT into pitest1_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest1_p1') +-- +TABLE: name="pitest1_p1" schema="" table="pitest1_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +-- attached partition +CREATE TABLE pitest1_p2 (f3 bigint, f2 text, f1 date NOT NULL) +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: CreateStmt +== 170 +INSERT INTO pitest1_p2 (f1, f2, f3) VALUES ('2016-08-2', 'before attaching', 100) +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 171 +ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +== 172 +-- requires NOT NULL constraint +ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET NOT NULL +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: AlterTableStmt +== 173 +ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +== 174 +INSERT INTO pitest1_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest1_p2') +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 175 +INSERT INTO pitest1 (f1, f2) VALUES ('2016-08-4', 'from pitest1') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 176 +-- LIKE INCLUDING on partition +CREATE TABLE pitest1_p1_like (LIKE pitest1_p1 INCLUDING IDENTITY) +-- +TABLE: name="pitest1_p1_like" schema="" table="pitest1_p1_like" ctx=DDL +STMT: CreateStmt +== 177 +INSERT into pitest1_p1_like(f1, f2) VALUES ('2016-07-2', 'from pitest1_p1_like') +-- +TABLE: name="pitest1_p1_like" schema="" table="pitest1_p1_like" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest1 +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=Select +STMT: SelectStmt +== 179 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest1_p1_like +-- +TABLE: name="pitest1_p1_like" schema="" table="pitest1_p1_like" ctx=Select +STMT: SelectStmt +== 180 +ALTER TABLE pitest1 ALTER COLUMN f3 SET DATA TYPE bigint +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +== 181 +SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1 +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=Select +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 182 +SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1_p2 +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=Select +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 183 +-- add identity column +CREATE TABLE pitest2 (f1 date NOT NULL, f2 text) PARTITION BY RANGE (f1) +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: CreateStmt +== 184 +CREATE TABLE pitest2_p1 PARTITION OF pitest2 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: CreateStmt +== 185 +CREATE TABLE pitest2_p2 PARTITION OF pitest2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01') +-- +TABLE: name="pitest2_p2" schema="" table="pitest2_p2" ctx=DDL +STMT: CreateStmt +== 186 +INSERT into pitest2(f1, f2) VALUES ('2016-07-2', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-2', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +ALTER TABLE pitest2 ADD COLUMN f3 int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +== 189 +INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest2_p1') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +INSERT INTO pitest2_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest2_p2') +-- +TABLE: name="pitest2_p2" schema="" table="pitest2_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +INSERT into pitest2(f1, f2) VALUES ('2016-07-4', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 192 +INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-4', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=Select +STMT: SelectStmt +== 194 +-- SET identity column +ALTER TABLE pitest2_p1 ALTER COLUMN f3 SET GENERATED BY DEFAULT +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: AlterTableStmt +== 195 +-- fails +ALTER TABLE pitest2_p1 ALTER COLUMN f3 SET INCREMENT BY 2 +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: AlterTableStmt +== 196 +-- fails +ALTER TABLE ONLY pitest2 ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 1000 RESTART +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +== 197 +-- fails +ALTER TABLE pitest2 ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 1000 RESTART +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +== 198 +INSERT into pitest2(f1, f2, f3) VALUES ('2016-07-5', 'from pitest2', 200) +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 199 +INSERT INTO pitest2(f1, f2) VALUES ('2016-08-5', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 200 +INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-6', 'from pitest2_p1') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +INSERT INTO pitest2_p2 (f1, f2, f3) VALUES ('2016-08-6', 'from pitest2_p2', 300) +-- +TABLE: name="pitest2_p2" schema="" table="pitest2_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=Select +STMT: SelectStmt +== 203 +-- detaching a partition removes identity property +ALTER TABLE pitest2 DETACH PARTITION pitest2_p1 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +== 204 +INSERT into pitest2(f1, f2) VALUES ('2016-08-7', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 205 +INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-7', 'from pitest2_p1') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 206 +-- error +INSERT into pitest2_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest2_p1', 2000) +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 207 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=Select +STMT: SelectStmt +== 208 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2_p1 +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=Select +STMT: SelectStmt +== 209 +DROP TABLE pitest2_p1 +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: DropStmt +== 210 +-- changing a regular column to identity column in a partitioned table +CREATE TABLE pitest3 (f1 date NOT NULL, f2 text, f3 int) PARTITION BY RANGE (f1) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: CreateStmt +== 211 +CREATE TABLE pitest3_p1 PARTITION OF pitest3 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: CreateStmt +== 212 +INSERT into pitest3 VALUES ('2016-07-2', 'from pitest3', 1) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 213 +INSERT into pitest3_p1 VALUES ('2016-07-3', 'from pitest3_p1', 2) +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 214 +-- fails, changing only a partition not allowed +ALTER TABLE pitest3_p1 + ALTER COLUMN f3 SET NOT NULL, + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3) +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: AlterTableStmt +== 215 +-- fails, changing only the partitioned table not allowed +BEGIN +-- +STMT: TransactionStmt +== 216 +ALTER TABLE pitest3_p1 ALTER COLUMN f3 SET NOT NULL +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: AlterTableStmt +== 217 +ALTER TABLE ONLY pitest3 + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +== 218 +ROLLBACK +-- +STMT: TransactionStmt +== 219 +ALTER TABLE pitest3 + ALTER COLUMN f3 SET NOT NULL, + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +== 220 +INSERT into pitest3(f1, f2) VALUES ('2016-07-4', 'from pitest3') +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 221 +INSERT into pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1') +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 222 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest3 +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=Select +STMT: SelectStmt +== 223 +-- changing an identity column to a non-identity column in a partitioned table +ALTER TABLE pitest3_p1 ALTER COLUMN f3 DROP IDENTITY +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: AlterTableStmt +== 224 +-- fails +ALTER TABLE ONLY pitest3 ALTER COLUMN f3 DROP IDENTITY +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +== 225 +-- fails +ALTER TABLE pitest3 ALTER COLUMN f3 DROP IDENTITY +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +== 226 +INSERT into pitest3(f1, f2) VALUES ('2016-07-4', 'from pitest3') +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 227 +-- fails +INSERT into pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1') +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 228 +-- fails +INSERT into pitest3(f1, f2, f3) VALUES ('2016-07-6', 'from pitest3', 5) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 229 +INSERT into pitest3_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest3_p1', 6) +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest3 +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=Select +STMT: SelectStmt +== 231 +-- Changing NOT NULL constraint of identity columns is not allowed +ALTER TABLE pitest1_p1 ALTER COLUMN f3 DROP NOT NULL +-- +TABLE: name="pitest1_p1" schema="" table="pitest1_p1" ctx=DDL +STMT: AlterTableStmt +== 232 +ALTER TABLE pitest1 ALTER COLUMN f3 DROP NOT NULL +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +== 233 +-- Identity columns have their own default +ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET DEFAULT 10000 +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: AlterTableStmt +== 234 +ALTER TABLE pitest1 ALTER COLUMN f3 SET DEFAULT 10000 +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +== 235 +-- Adding identity to an identity column is not allowed +ALTER TABLE pitest1_p2 ALTER COLUMN f3 ADD GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: AlterTableStmt +== 236 +ALTER TABLE pitest1 ALTER COLUMN f3 ADD GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +== 237 +-- partitions with their own identity columns are not allowed, even if the +-- partitioned table does not have an identity column. +CREATE TABLE pitest1_pfail PARTITION OF pitest1 ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY +) FOR VALUES FROM ('2016-11-01') TO ('2016-12-01') +-- +TABLE: name="pitest1_pfail" schema="" table="pitest1_pfail" ctx=DDL +STMT: CreateStmt +== 238 +CREATE TABLE pitest_pfail PARTITION OF pitest3 ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY +) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest_pfail" schema="" table="pitest_pfail" ctx=DDL +STMT: CreateStmt +== 239 +CREATE TABLE pitest1_pfail (f1 date NOT NULL, f2 text, f3 bigint GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="pitest1_pfail" schema="" table="pitest1_pfail" ctx=DDL +STMT: CreateStmt +== 240 +ALTER TABLE pitest1 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +== 241 +ALTER TABLE pitest3 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01') +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +== 242 +DROP TABLE pitest1_pfail +-- +TABLE: name="pitest1_pfail" schema="" table="pitest1_pfail" ctx=DDL +STMT: DropStmt +== 243 +DROP TABLE pitest3 +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: DropStmt +== 244 +-- test that sequence of half-dropped serial column is properly ignored + +CREATE TABLE itest14 (id serial) +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DDL +STMT: CreateStmt +== 245 +ALTER TABLE itest14 ALTER id DROP DEFAULT +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DDL +STMT: AlterTableStmt +== 246 +ALTER TABLE itest14 ALTER id ADD GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DDL +STMT: AlterTableStmt +== 247 +INSERT INTO itest14 (id) VALUES (DEFAULT) +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +-- Identity columns must be NOT NULL (cf bug #16913) + +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NULL) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +== 249 +-- fail +CREATE TABLE itest15 (id integer NULL GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +== 250 +-- fail +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NOT NULL) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +== 251 +DROP TABLE itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: DropStmt +== 252 +CREATE TABLE itest15 (id integer NOT NULL GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +== 253 +DROP TABLE itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: DropStmt +== 254 +-- MERGE tests +CREATE TABLE itest15 (a int GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +== 255 +CREATE TABLE itest16 (a int GENERATED BY DEFAULT AS IDENTITY, b text) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DDL +STMT: CreateStmt +== 256 +MERGE INTO itest15 t +USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DML +ALIAS: "t"="itest15" +STMT: MergeStmt +STMT: SelectStmt +== 257 +-- Used to fail, but now it works and ignores the user supplied value +MERGE INTO itest15 t +USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DML +ALIAS: "t"="itest15" +STMT: MergeStmt +STMT: SelectStmt +== 258 +MERGE INTO itest15 t +USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DML +ALIAS: "t"="itest15" +STMT: MergeStmt +STMT: SelectStmt +== 259 +MERGE INTO itest16 t +USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DML +ALIAS: "t"="itest16" +STMT: MergeStmt +STMT: SelectStmt +== 260 +MERGE INTO itest16 t +USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DML +ALIAS: "t"="itest16" +STMT: MergeStmt +STMT: SelectStmt +== 261 +MERGE INTO itest16 t +USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DML +ALIAS: "t"="itest16" +STMT: MergeStmt +STMT: SelectStmt +== 262 +SELECT * FROM itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=Select +STMT: SelectStmt +== 263 +SELECT * FROM itest16 +-- +TABLE: name="itest16" schema="" table="itest16" ctx=Select +STMT: SelectStmt +== 264 +DROP TABLE itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: DropStmt +== 265 +DROP TABLE itest16 +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DDL +STMT: DropStmt +== 266 +-- For testing of pg_dump and pg_upgrade, leave behind some identity +-- sequences whose logged-ness doesn't match their owning table's. +CREATE TABLE identity_dump_logged (a INT GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="identity_dump_logged" schema="" table="identity_dump_logged" ctx=DDL +STMT: CreateStmt +== 267 +ALTER SEQUENCE identity_dump_logged_a_seq SET UNLOGGED +-- +TABLE: name="identity_dump_logged_a_seq" schema="" table="identity_dump_logged_a_seq" ctx=DDL +STMT: AlterTableStmt +== 268 +CREATE UNLOGGED TABLE identity_dump_unlogged (a INT GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="identity_dump_unlogged" schema="" table="identity_dump_unlogged" ctx=DDL +STMT: CreateStmt +== 269 +ALTER SEQUENCE identity_dump_unlogged_a_seq SET LOGGED +-- +TABLE: name="identity_dump_unlogged_a_seq" schema="" table="identity_dump_unlogged_a_seq" ctx=DDL +STMT: AlterTableStmt +== 270 +SELECT relname, relpersistence FROM pg_class + WHERE relname ~ '^identity_dump_' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/incremental_sort.metadata.json b/parser/testdata/summary/postgres_regress/incremental_sort.metadata.json new file mode 100644 index 0000000..b6ecb7b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/incremental_sort.metadata.json @@ -0,0 +1,123 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119" + ] +} diff --git a/parser/testdata/summary/postgres_regress/incremental_sort.test b/parser/testdata/summary/postgres_regress/incremental_sort.test new file mode 100644 index 0000000..72f355c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/incremental_sort.test @@ -0,0 +1,803 @@ +== 001 +-- When there is a LIMIT clause, incremental sort is beneficial because +-- it only has to sort some of the groups, and not the entire table. +explain (costs off) +select * from (select * from tenk1 order by four) t order by four, ten +limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 002 +-- When work_mem is not enough to sort the entire table, incremental sort +-- may be faster if individual groups still fit into work_mem. +set work_mem to '2MB' +-- +STMT: VariableSetStmt +== 003 +explain (costs off) +select * from (select * from tenk1 order by four) t order by four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 004 +reset work_mem +-- +STMT: VariableSetStmt +== 005 +create table t(a integer, b integer) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 006 +create or replace function explain_analyze_without_memory(query text) +returns table (out_line text) language plpgsql +as +$$ +declare + line text; +begin + for line in + execute 'explain (analyze, costs off, summary off, timing off) ' || query + loop + out_line := regexp_replace(line, '\d+kB', 'NNkB', 'g'); + return next; + end loop; +end; +$$ +-- +FUNCTION: name="explain_analyze_without_memory" function="explain_analyze_without_memory" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +create or replace function explain_analyze_inc_sort_nodes(query text) +returns jsonb language plpgsql +as +$$ +declare + elements jsonb; + element jsonb; + matching_nodes jsonb := '[]'::jsonb; +begin + execute 'explain (analyze, costs off, summary off, timing off, format ''json'') ' || query into strict elements; + while jsonb_array_length(elements) > 0 loop + element := elements->0; + elements := elements - 0; + case jsonb_typeof(element) + when 'array' then + if jsonb_array_length(element) > 0 then + elements := elements || element; + end if; + when 'object' then + if element ? 'Plan' then + elements := elements || jsonb_build_array(element->'Plan'); + element := element - 'Plan'; + else + if element ? 'Plans' then + elements := elements || jsonb_build_array(element->'Plans'); + element := element - 'Plans'; + end if; + if (element->>'Node Type')::text = 'Incremental Sort' then + matching_nodes := matching_nodes || element; + end if; + end if; + end case; + end loop; + return matching_nodes; +end; +$$ +-- +FUNCTION: name="explain_analyze_inc_sort_nodes" function="explain_analyze_inc_sort_nodes" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 008 +create or replace function explain_analyze_inc_sort_nodes_without_memory(query text) +returns jsonb language plpgsql +as +$$ +declare + nodes jsonb := '[]'::jsonb; + node jsonb; + group_key text; + space_key text; +begin + for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop + for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop + for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop + node := jsonb_set(node, array[group_key, space_key, 'Average Sort Space Used'], '"NN"', false); + node := jsonb_set(node, array[group_key, space_key, 'Peak Sort Space Used'], '"NN"', false); + end loop; + end loop; + nodes := nodes || node; + end loop; + return nodes; +end; +$$ +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_without_memory" function="explain_analyze_inc_sort_nodes_without_memory" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 009 +create or replace function explain_analyze_inc_sort_nodes_verify_invariants(query text) +returns bool language plpgsql +as +$$ +declare + node jsonb; + group_stats jsonb; + group_key text; + space_key text; +begin + for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop + for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop + group_stats := node->group_key; + for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop + if (group_stats->space_key->'Peak Sort Space Used')::bigint < (group_stats->space_key->'Peak Sort Space Used')::bigint then + raise exception '% has invalid max space < average space', group_key; + end if; + end loop; + end loop; + end loop; + return true; +end; +$$ +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_verify_invariants" function="explain_analyze_inc_sort_nodes_verify_invariants" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 010 +-- A single large group tested around each mode transition point. +insert into t(a, b) select i/100 + 1, i + 1 from generate_series(0, 999) n(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 011 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +== 012 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 013 +select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 014 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 015 +select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 016 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 017 +select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 018 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 019 +select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 020 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 021 +select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 022 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +== 023 +-- An initial large group followed by a small group. +insert into t(a, b) select i/50 + 1, i + 1 from generate_series(0, 999) n(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 024 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +== 025 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 55 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 026 +select * from (select * from t order by a) s order by a, b limit 55 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 027 +-- Test EXPLAIN ANALYZE with only a fullsort group. +select explain_analyze_without_memory('select * from (select * from t order by a) s order by a, b limit 55') +-- +FUNCTION: name="explain_analyze_without_memory" function="explain_analyze_without_memory" schema="" ctx=Call +STMT: SelectStmt +== 028 +select jsonb_pretty(explain_analyze_inc_sort_nodes_without_memory('select * from (select * from t order by a) s order by a, b limit 55')) +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +FUNCTION: name="explain_analyze_inc_sort_nodes_without_memory" function="explain_analyze_inc_sort_nodes_without_memory" schema="" ctx=Call +STMT: SelectStmt +== 029 +select explain_analyze_inc_sort_nodes_verify_invariants('select * from (select * from t order by a) s order by a, b limit 55') +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_verify_invariants" function="explain_analyze_inc_sort_nodes_verify_invariants" schema="" ctx=Call +STMT: SelectStmt +== 030 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +== 031 +-- An initial small group followed by a large group. +insert into t(a, b) select (case when i < 5 then i else 9 end), i from generate_series(1, 1000) n(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 032 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +== 033 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 70 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 034 +select * from (select * from t order by a) s order by a, b limit 70 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 035 +-- Checks case where we hit a group boundary at the last tuple of a batch. +-- Because the full sort state is bounded, we scan 64 tuples (the mode +-- transition point) but only retain 5. Thus when we transition modes, all +-- tuples in the full sort state have different prefix keys. +explain (costs off) select * from (select * from t order by a) s order by a, b limit 5 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 036 +select * from (select * from t order by a) s order by a, b limit 5 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 037 +-- Test rescan. +begin +-- +STMT: TransactionStmt +== 038 +-- We force the planner to choose a plan with incremental sort on the right side +-- of a nested loop join node. That way we trigger the rescan code path. +set local enable_hashjoin = off +-- +STMT: VariableSetStmt +== 039 +set local enable_mergejoin = off +-- +STMT: VariableSetStmt +== 040 +set local enable_material = off +-- +STMT: VariableSetStmt +== 041 +set local enable_sort = off +-- +STMT: VariableSetStmt +== 042 +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) +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="t" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +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) +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="t" column="a" +STMT: SelectStmt +== 044 +rollback +-- +STMT: TransactionStmt +== 045 +-- 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') +-- +FUNCTION: name="explain_analyze_without_memory" function="explain_analyze_without_memory" schema="" ctx=Call +STMT: SelectStmt +== 046 +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')) +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +FUNCTION: name="explain_analyze_inc_sort_nodes_without_memory" function="explain_analyze_inc_sort_nodes_without_memory" schema="" ctx=Call +STMT: SelectStmt +== 047 +select explain_analyze_inc_sort_nodes_verify_invariants('select * from (select * from t order by a) s order by a, b limit 70') +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_verify_invariants" function="explain_analyze_inc_sort_nodes_verify_invariants" schema="" ctx=Call +STMT: SelectStmt +== 048 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +== 049 +-- 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) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 050 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +== 051 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 052 +select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 053 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 054 +select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 055 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 056 +select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 057 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 058 +select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 059 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 060 +select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 061 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +== 062 +-- 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) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 063 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +== 064 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 065 +select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 066 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 067 +select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 068 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 069 +select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 070 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 071 +select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 072 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 073 +select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +== 074 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +== 075 +drop table t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 076 +-- Incremental sort vs. parallel queries +set min_parallel_table_scan_size = '1kB' +-- +STMT: VariableSetStmt +== 077 +set min_parallel_index_scan_size = '1kB' +-- +STMT: VariableSetStmt +== 078 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 079 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 080 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 081 +create table t (a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 082 +insert into t select mod(i,10),mod(i,10),i from generate_series(1,10000) s(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 083 +create index on t (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +== 084 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +== 085 +set enable_incremental_sort = off +-- +STMT: VariableSetStmt +== 086 +explain (costs off) select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 087 +set enable_incremental_sort = on +-- +STMT: VariableSetStmt +== 088 +explain (costs off) select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 089 +-- Incremental sort vs. set operations with varno 0 +set enable_hashagg to off +-- +STMT: VariableSetStmt +== 090 +explain (costs off) select * from t union select * from t order by 1,3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 091 +-- 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 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 092 +drop table t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +== 093 +-- 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 +-- +STMT: VariableSetStmt +== 094 +set enable_seqscan=off +-- +STMT: VariableSetStmt +== 095 +set enable_incremental_sort = off +-- +STMT: VariableSetStmt +== 096 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +== 097 +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +== 098 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 099 +set min_parallel_index_scan_size = 0 +-- +STMT: VariableSetStmt +== 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 101 +explain (costs off) select sub.unique1, stringu1 +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub +order by 1, 2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 102 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="md5" function="md5" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 103 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="md5" function="md5" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 104 +-- 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(*) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 105 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t"="tenk1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="t" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 106 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t"="tenk1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="t" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 107 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 108 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 109 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 110 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 111 +reset enable_incremental_sort +-- +STMT: VariableSetStmt +== 112 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +== 113 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +== 114 +reset min_parallel_table_scan_size +-- +STMT: VariableSetStmt +== 115 +reset min_parallel_index_scan_size +-- +STMT: VariableSetStmt +== 116 +-- Ensure incremental sorts work for amcanorderbyop type indexes +create table point_table (a point, b int) +-- +TABLE: name="point_table" schema="" table="point_table" ctx=DDL +STMT: CreateStmt +== 117 +create index point_table_a_idx on point_table using gist(a) +-- +TABLE: name="point_table" schema="" table="point_table" ctx=DDL +STMT: IndexStmt +== 118 +-- Ensure we get an incremental sort plan for both of the following queries +explain (costs off) select a, b, a <-> point(5, 5) dist from point_table order by dist, b limit 1 +-- +TABLE: name="point_table" schema="" table="point_table" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 119 +explain (costs off) select a, b, a <-> point(5, 5) dist from point_table order by dist, b desc limit 1 +-- +TABLE: name="point_table" schema="" table="point_table" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/index_including.metadata.json b/parser/testdata/summary/postgres_regress/index_including.metadata.json new file mode 100644 index 0000000..e6f6795 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/index_including.metadata.json @@ -0,0 +1,139 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135" + ] +} diff --git a/parser/testdata/summary/postgres_regress/index_including.test b/parser/testdata/summary/postgres_regress/index_including.test new file mode 100644 index 0000000..4cb4bc0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/index_including.test @@ -0,0 +1,862 @@ +== 001 +/* + * 1.test CREATE INDEX + * + * Deliberately avoid dropping objects in this section, to get some pg_dump + * coverage. + */ + +-- Regular index with included columns +CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO tbl_include_reg SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +CREATE INDEX tbl_include_reg_idx ON tbl_include_reg (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DDL +STMT: IndexStmt +== 004 +-- duplicate column is pretty pointless, but we allow it anyway +CREATE INDEX ON tbl_include_reg (c1, c2) INCLUDE (c1, c3) +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DDL +STMT: IndexStmt +== 005 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +== 006 +-- Unique index and unique constraint +CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: CreateStmt +== 007 +INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 008 +CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 using btree (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: IndexStmt +== 009 +ALTER TABLE tbl_include_unique1 add UNIQUE USING INDEX tbl_include_unique1_idx_unique +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: AlterTableStmt +== 010 +ALTER TABLE tbl_include_unique1 add UNIQUE (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: AlterTableStmt +== 011 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_unique1'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +== 012 +-- Unique index and unique constraint. Both must fail. +CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DDL +STMT: CreateStmt +== 013 +INSERT INTO tbl_include_unique2 SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 014 +CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 using btree (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DDL +STMT: IndexStmt +== 015 +ALTER TABLE tbl_include_unique2 add UNIQUE (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DDL +STMT: AlterTableStmt +== 016 +-- PK constraint +CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_pk" schema="" table="tbl_include_pk" ctx=DDL +STMT: CreateStmt +== 017 +INSERT INTO tbl_include_pk SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_pk" schema="" table="tbl_include_pk" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 018 +ALTER TABLE tbl_include_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_pk" schema="" table="tbl_include_pk" ctx=DDL +STMT: AlterTableStmt +== 019 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_pk'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +== 020 +CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DDL +STMT: CreateStmt +== 021 +INSERT INTO tbl_include_box SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 022 +CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box using btree (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DDL +STMT: IndexStmt +== 023 +ALTER TABLE tbl_include_box add PRIMARY KEY USING INDEX tbl_include_box_idx_unique +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DDL +STMT: AlterTableStmt +== 024 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_box'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +== 025 +-- PK constraint. Must fail. +CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_box_pk" schema="" table="tbl_include_box_pk" ctx=DDL +STMT: CreateStmt +== 026 +INSERT INTO tbl_include_box_pk SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_box_pk" schema="" table="tbl_include_box_pk" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 027 +ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_box_pk" schema="" table="tbl_include_box_pk" ctx=DDL +STMT: AlterTableStmt +== 028 +/* + * 2. Test CREATE TABLE with constraint + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + CONSTRAINT covering UNIQUE(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 029 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 030 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 031 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 032 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 033 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + CONSTRAINT covering PRIMARY KEY(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 034 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 035 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 036 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,300) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 039 +explain (costs off) +select * from tbl where (c1,c2,c3) < (2,5,1) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: ExplainStmt +STMT: SelectStmt +== 040 +select * from tbl where (c1,c2,c3) < (2,5,1) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: SelectStmt +== 041 +-- row comparison that compares high key at page boundary +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 042 +explain (costs off) +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: SelectStmt +== 044 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 045 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 046 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + UNIQUE(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 047 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 048 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 049 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 050 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 051 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + PRIMARY KEY(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 052 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 053 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 054 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 055 +INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 056 +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 057 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 058 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + EXCLUDE USING btree (c1 WITH =) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 059 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 060 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 061 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 062 +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 063 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 064 +/* + * 3.0 Test ALTER TABLE DROP COLUMN. + * Any column deletion leads to index deletion. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 int) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 065 +CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2, c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 066 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 067 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 068 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 069 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 070 +/* + * 3.1 Test ALTER TABLE DROP COLUMN. + * Included column deletion leads to the index deletion, + * AS well AS key columns deletion. It's explained in documentation. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 071 +CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDE(c3,c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 072 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 073 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 074 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 075 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 076 +/* + * 3.2 Test ALTER TABLE DROP COLUMN. + * Included column deletion leads to the index deletion. + * AS well AS key columns deletion. It's explained in documentation. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 077 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 078 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 079 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 080 +ALTER TABLE tbl DROP COLUMN c1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 081 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 082 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 083 +/* + * 3.3 Test ALTER TABLE SET STATISTICS + */ +CREATE TABLE tbl (c1 int, c2 int) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 084 +CREATE INDEX tbl_idx ON tbl (c1, (c1+0)) INCLUDE (c2) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 085 +ALTER INDEX tbl_idx ALTER COLUMN 1 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 086 +ALTER INDEX tbl_idx ALTER COLUMN 2 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 087 +ALTER INDEX tbl_idx ALTER COLUMN 3 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 088 +ALTER INDEX tbl_idx ALTER COLUMN 4 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +== 089 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 090 +/* + * 4. CREATE INDEX CONCURRENTLY + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 091 +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,1000) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 092 +CREATE UNIQUE INDEX CONCURRENTLY on tbl (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 093 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 094 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 095 +/* + * 5. REINDEX + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 096 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 097 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 098 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 099 +REINDEX INDEX tbl_c1_c2_c3_c4_key +-- +STMT: ReindexStmt +== 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 101 +ALTER TABLE tbl DROP COLUMN c1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 102 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 103 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 104 +/* + * 7. Check various AMs. All but btree, gist and spgist must fail. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 box, c4 box) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 105 +CREATE INDEX on tbl USING brin(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 106 +CREATE INDEX on tbl USING gist(c3) INCLUDE (c1, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 107 +CREATE INDEX on tbl USING spgist(c3) INCLUDE (c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 108 +CREATE INDEX on tbl USING gin(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 109 +CREATE INDEX on tbl USING hash(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 110 +CREATE INDEX on tbl USING rtree(c3) INCLUDE (c1, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 111 +CREATE INDEX on tbl USING btree(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 112 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 113 +/* + * 8. Update, delete values in indexed table. + */ +CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 114 +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 115 +CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDE (c3,c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +== 116 +UPDATE tbl SET c1 = 100 WHERE c1 = 2 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +== 117 +UPDATE tbl SET c1 = 1 WHERE c1 = 3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +== 118 +-- should fail +UPDATE tbl SET c2 = 2 WHERE c1 = 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +== 119 +UPDATE tbl SET c3 = 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +== 120 +DELETE FROM tbl WHERE c1 = 5 OR c3 = 12 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: DeleteStmt +== 121 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 122 +/* + * 9. Alter column type. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +== 123 +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 124 +ALTER TABLE tbl ALTER c1 TYPE bigint +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 125 +ALTER TABLE tbl ALTER c3 TYPE bigint +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 126 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +== 127 +/* + * 10. Test coverage for names stored as cstrings in indexes + */ +CREATE TABLE nametbl (c1 int, c2 name, c3 float) +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: CreateStmt +== 128 +CREATE INDEX nametbl_c1_c2_idx ON nametbl (c2, c1) INCLUDE (c3) +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: IndexStmt +== 129 +INSERT INTO nametbl VALUES(1, 'two', 3.0) +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 130 +VACUUM nametbl +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: VacuumStmt +== 131 +SET enable_seqscan = 0 +-- +STMT: VariableSetStmt +== 132 +-- Ensure we get an index only scan plan +EXPLAIN (COSTS OFF) SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1 +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=Select +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c1" +STMT: ExplainStmt +STMT: SelectStmt +== 133 +-- Validate the results look sane +SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1 +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=Select +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c1" +STMT: SelectStmt +== 134 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 135 +DROP TABLE nametbl +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/index_including_gist.metadata.json b/parser/testdata/summary/postgres_regress/index_including_gist.metadata.json new file mode 100644 index 0000000..147070d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/index_including_gist.metadata.json @@ -0,0 +1,54 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050" + ] +} diff --git a/parser/testdata/summary/postgres_regress/index_including_gist.test b/parser/testdata/summary/postgres_regress/index_including_gist.test new file mode 100644 index 0000000..5c4536b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/index_including_gist.test @@ -0,0 +1,368 @@ +== 001 +/* + * 1.1. test CREATE INDEX with buffered build + */ + +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +== 002 +-- size is chosen to exceed page size and trigger actual truncation +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +== 004 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +== 005 +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: SelectStmt +== 006 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 007 +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: ExplainStmt +STMT: SelectStmt +== 008 +SET enable_bitmapscan TO default +-- +STMT: VariableSetStmt +== 009 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +== 010 +/* + * 1.2. test CREATE INDEX with inserts + */ + +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +== 011 +-- size is chosen to exceed page size and trigger actual truncation +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +== 012 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 013 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +== 014 +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: SelectStmt +== 015 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 016 +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: ExplainStmt +STMT: SelectStmt +== 017 +SET enable_bitmapscan TO default +-- +STMT: VariableSetStmt +== 018 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +== 019 +/* + * 2. CREATE INDEX CONCURRENTLY + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +== 020 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 021 +CREATE INDEX CONCURRENTLY tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +== 022 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 023 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +== 024 +/* + * 3. REINDEX + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +== 025 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 026 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +== 027 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 028 +REINDEX INDEX tbl_gist_idx +-- +STMT: ReindexStmt +== 029 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 030 +ALTER TABLE tbl_gist DROP COLUMN c1 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: AlterTableStmt +== 031 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 032 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +== 033 +/* + * 4. Update, delete values in indexed table. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +== 034 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 035 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +== 036 +UPDATE tbl_gist SET c1 = 100 WHERE c1 = 2 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +STMT: UpdateStmt +== 037 +UPDATE tbl_gist SET c1 = 1 WHERE c1 = 3 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +STMT: UpdateStmt +== 038 +DELETE FROM tbl_gist WHERE c1 = 5 OR c3 = 12 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +STMT: DeleteStmt +== 039 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +== 040 +/* + * 5. Alter column type. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +== 041 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 042 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +== 043 +ALTER TABLE tbl_gist ALTER c1 TYPE bigint +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: AlterTableStmt +== 044 +ALTER TABLE tbl_gist ALTER c3 TYPE bigint +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: AlterTableStmt +== 045 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +== 046 +/* + * 6. EXCLUDE constraint. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box, EXCLUDE USING gist (c4 WITH &&) INCLUDE (c1, c2, c3)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +== 047 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(3*x,2*x),point(3*x+1,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 049 +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/indexing.metadata.json b/parser/testdata/summary/postgres_regress/indexing.metadata.json new file mode 100644 index 0000000..44a2d56 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/indexing.metadata.json @@ -0,0 +1,564 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560" + ] +} diff --git a/parser/testdata/summary/postgres_regress/indexing.test b/parser/testdata/summary/postgres_regress/indexing.test new file mode 100644 index 0000000..a92df17 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/indexing.test @@ -0,0 +1,3228 @@ +== 001 +-- Creating an index on a partitioned table makes the partitions +-- automatically get the index +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 002 +-- relhassubclass of a partitioned index is false before creating any partition. +-- It will be set after the first partition is created. +create index idxpart_idx on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 003 +select relhassubclass from pg_class where relname = 'idxpart_idx' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 004 +-- Check that partitioned indexes are present in pg_indexes. +select indexdef from pg_indexes where indexname like 'idxpart_idx%' +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="indexname" +STMT: SelectStmt +== 005 +drop index idxpart_idx +-- +STMT: DropStmt +== 006 +create table idxpart1 partition of idxpart for values from (0) to (10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 007 +create table idxpart2 partition of idxpart for values from (10) to (100) + partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 008 +create table idxpart21 partition of idxpart2 for values from (0) to (100) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +== 009 +-- Even with partitions, relhassubclass should not be set if a partitioned +-- index is created only on the parent. +create index idxpart_idx on only idxpart(a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 010 +select relhassubclass from pg_class where relname = 'idxpart_idx' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 011 +drop index idxpart_idx +-- +STMT: DropStmt +== 012 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 013 +select relname, relkind, relhassubclass, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 014 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 015 +-- Some unsupported features +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 016 +create table idxpart1 partition of idxpart for values from (0) to (10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 017 +create index concurrently on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 018 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 019 +-- Verify bugfix with query on indexed partitioned table with no partitions +-- https://postgr.es/m/20180124162006.pmapfiznhgngwtjf@alvherre.pgsql +CREATE TABLE idxpart (col1 INT) PARTITION BY RANGE (col1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 020 +CREATE INDEX ON idxpart (col1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 021 +CREATE TABLE idxpart_two (col2 INT) +-- +TABLE: name="idxpart_two" schema="" table="idxpart_two" ctx=DDL +STMT: CreateStmt +== 022 +SELECT col2 FROM idxpart_two fk LEFT OUTER JOIN idxpart pk ON (col1 = col2) +-- +TABLE: name="idxpart_two" schema="" table="idxpart_two" ctx=Select +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +ALIAS: "fk"="idxpart_two" +ALIAS: "pk"="idxpart" +STMT: SelectStmt +== 023 +DROP table idxpart, idxpart_two +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart_two" schema="" table="idxpart_two" ctx=DDL +STMT: DropStmt +== 024 +-- Verify bugfix with index rewrite on ALTER TABLE / SET DATA TYPE +-- https://postgr.es/m/CAKcux6mxNCGsgATwf5CGMF8g4WSupCXicCVMeKUTuWbyxHOMsQ@mail.gmail.com +CREATE TABLE idxpart (a INT, b TEXT, c INT) PARTITION BY RANGE(a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 025 +CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (MINVALUE) TO (MAXVALUE) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 026 +CREATE INDEX partidx_abc_idx ON idxpart (a, b, c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 027 +INSERT INTO idxpart (a, b, c) SELECT i, i, i FROM generate_series(1, 50) i +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 028 +ALTER TABLE idxpart ALTER COLUMN c TYPE numeric +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 029 +DROP TABLE idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 030 +-- If a table without index is attached as partition to a table with +-- an index, the index is automatically created +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 031 +create index idxparti on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 032 +create index idxparti2 on idxpart (b, c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 033 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 034 +alter table idxpart attach partition idxpart1 for values from (0) to (10) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 035 +-- Forbid ALTER TABLE when attaching or detaching an index to a partition. +create index idxpart_c on only idxpart (c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 036 +create index idxpart1_c on idxpart1 (c) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 037 +alter table idxpart_c attach partition idxpart1_c for values from (10) to (20) +-- +TABLE: name="idxpart_c" schema="" table="idxpart_c" ctx=DDL +STMT: AlterTableStmt +== 038 +alter index idxpart_c attach partition idxpart1_c +-- +STMT: AlterTableStmt +== 039 +select relname, relpartbound from pg_class + where relname in ('idxpart_c', 'idxpart1_c') + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 040 +alter table idxpart_c detach partition idxpart1_c +-- +TABLE: name="idxpart_c" schema="" table="idxpart_c" ctx=DDL +STMT: AlterTableStmt +== 041 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 042 +-- If a partition already has an index, don't create a duplicative one +create table idxpart (a int, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 043 +create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 044 +create index on idxpart1 (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 045 +create index on idxpart (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 046 +select relname, relkind, relhassubclass, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 047 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 048 +-- DROP behavior for partitioned indexes +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 049 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 050 +create table idxpart1 partition of idxpart for values from (0) to (10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 051 +drop index idxpart1_a_idx +-- +STMT: DropStmt +== 052 +-- no way +drop index concurrently idxpart_a_idx +-- +STMT: DropStmt +== 053 +-- unsupported +drop index idxpart_a_idx +-- +STMT: DropStmt +== 054 +-- both indexes go away +select relname, relkind from pg_class + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 055 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 056 +drop table idxpart1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: DropStmt +== 057 +-- the index on partition goes away too +select relname, relkind from pg_class + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 058 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 059 +-- DROP behavior with temporary partitioned indexes +create temp table idxpart_temp (a int) partition by range (a) +-- +TABLE: name="idxpart_temp" schema="" table="idxpart_temp" ctx=DDL +STMT: CreateStmt +== 060 +create index on idxpart_temp(a) +-- +TABLE: name="idxpart_temp" schema="" table="idxpart_temp" ctx=DDL +STMT: IndexStmt +== 061 +create temp table idxpart1_temp partition of idxpart_temp + for values from (0) to (10) +-- +TABLE: name="idxpart1_temp" schema="" table="idxpart1_temp" ctx=DDL +STMT: CreateStmt +== 062 +drop index idxpart1_temp_a_idx +-- +STMT: DropStmt +== 063 +-- error +-- non-concurrent drop is enforced here, so it is a valid case. +drop index concurrently idxpart_temp_a_idx +-- +STMT: DropStmt +== 064 +select relname, relkind from pg_class + where relname like 'idxpart_temp%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 065 +drop table idxpart_temp +-- +TABLE: name="idxpart_temp" schema="" table="idxpart_temp" ctx=DDL +STMT: DropStmt +== 066 +-- ALTER INDEX .. ATTACH, error cases +create table idxpart (a int, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 067 +create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 068 +create index idxpart_a_b_idx on only idxpart (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 069 +create index idxpart1_a_b_idx on idxpart1 (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 070 +create index idxpart1_tst1 on idxpart1 (b, a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 071 +create index idxpart1_tst2 on idxpart1 using hash (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 072 +create index idxpart1_tst3 on idxpart1 (a, b) where a > 10 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 073 +alter index idxpart attach partition idxpart1 +-- +STMT: AlterTableStmt +== 074 +alter index idxpart_a_b_idx attach partition idxpart1 +-- +STMT: AlterTableStmt +== 075 +alter index idxpart_a_b_idx attach partition idxpart_a_b_idx +-- +STMT: AlterTableStmt +== 076 +alter index idxpart_a_b_idx attach partition idxpart1_b_idx +-- +STMT: AlterTableStmt +== 077 +alter index idxpart_a_b_idx attach partition idxpart1_tst1 +-- +STMT: AlterTableStmt +== 078 +alter index idxpart_a_b_idx attach partition idxpart1_tst2 +-- +STMT: AlterTableStmt +== 079 +alter index idxpart_a_b_idx attach partition idxpart1_tst3 +-- +STMT: AlterTableStmt +== 080 +-- OK +alter index idxpart_a_b_idx attach partition idxpart1_a_b_idx +-- +STMT: AlterTableStmt +== 081 +alter index idxpart_a_b_idx attach partition idxpart1_a_b_idx +-- +STMT: AlterTableStmt +== 082 +-- quiet + +-- reject dupe +create index idxpart1_2_a_b on idxpart1 (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 083 +alter index idxpart_a_b_idx attach partition idxpart1_2_a_b +-- +STMT: AlterTableStmt +== 084 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 085 +-- make sure everything's gone +select indexrelid::regclass, indrelid::regclass + from pg_index where indexrelid::regclass::text like 'idxpart%' +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 086 +-- Don't auto-attach incompatible indexes +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 087 +create table idxpart1 (a int, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 088 +create index on idxpart1 using hash (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 089 +create index on idxpart1 (a) where b > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 090 +create index on idxpart1 ((a + 0)) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 091 +create index on idxpart1 (a, a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 092 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 093 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 094 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 095 +-- If CREATE INDEX ONLY, don't create indexes on partitions; and existing +-- indexes on partitions don't change parent. ALTER INDEX ATTACH can change +-- the parent after the fact. +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 096 +create table idxpart1 partition of idxpart for values from (0) to (100) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 097 +create table idxpart2 partition of idxpart for values from (100) to (1000) + partition by range (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 098 +create table idxpart21 partition of idxpart2 for values from (100) to (200) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +== 099 +create table idxpart22 partition of idxpart2 for values from (200) to (300) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: CreateStmt +== 100 +create index on idxpart22 (a) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: IndexStmt +== 101 +create index on only idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 102 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 103 +-- Here we expect that idxpart1 and idxpart2 have a new index, but idxpart21 +-- does not; also, idxpart22 is not attached. +select indexrelid::regclass, indrelid::regclass, inhparent::regclass + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) +where indexrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 104 +alter index idxpart2_a_idx attach partition idxpart22_a_idx +-- +STMT: AlterTableStmt +== 105 +select indexrelid::regclass, indrelid::regclass, inhparent::regclass + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) +where indexrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 106 +-- attaching idxpart22 is not enough to set idxpart22_a_idx valid ... +alter index idxpart2_a_idx attach partition idxpart22_a_idx +-- +STMT: AlterTableStmt +== 107 +-- ... but this one is. +create index on idxpart21 (a) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: IndexStmt +== 108 +alter index idxpart2_a_idx attach partition idxpart21_a_idx +-- +STMT: AlterTableStmt +== 109 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 110 +-- When a table is attached a partition and it already has an index, a +-- duplicate index should not get created, but rather the index becomes +-- attached to the parent's index. +create table idxpart (a int, b int, c text, d bool) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 111 +create index idxparti on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 112 +create index idxparti2 on idxpart (b, c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 113 +create table idxpart1 (like idxpart including indexes) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 114 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 115 +alter table idxpart attach partition idxpart1 for values from (0) to (10) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 116 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 117 +-- While here, also check matching when creating an index after the fact. +create index on idxpart1 ((a+b)) where d = true +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 118 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 119 +create index idxparti3 on idxpart ((a+b)) where d = true +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 120 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 121 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 122 +-- Verify that attaching an invalid index does not mark the parent index valid. +-- On the other hand, attaching a valid index marks not only its direct +-- ancestor valid, but also any indirect ancestor that was only missing the one +-- that was just made valid +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 123 +create table idxpart1 partition of idxpart for values from (1) to (1000) partition by range (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 124 +create table idxpart11 partition of idxpart1 for values from (1) to (100) +-- +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: CreateStmt +== 125 +create index on only idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 126 +create index on only idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 127 +-- this results in two invalid indexes: +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 128 +-- idxpart1_a_idx is not valid, so idxpart_a_idx should not become valid: +alter index idxpart_a_idx attach partition idxpart1_a_idx +-- +STMT: AlterTableStmt +== 129 +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 130 +-- after creating and attaching this, both idxpart1_a_idx and idxpart_a_idx +-- should become valid +create index on idxpart11 (a) +-- +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: IndexStmt +== 131 +alter index idxpart1_a_idx attach partition idxpart11_a_idx +-- +STMT: AlterTableStmt +== 132 +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 133 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 134 +-- verify dependency handling during ALTER TABLE DETACH PARTITION +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 135 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 136 +create index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 137 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 138 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 139 +alter table idxpart attach partition idxpart1 for values from (0000) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 140 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 141 +create table idxpart3 partition of idxpart for values from (2000) to (3000) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +== 142 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 143 +-- a) after detaching partitions, the indexes can be dropped independently +alter table idxpart detach partition idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 144 +alter table idxpart detach partition idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 145 +alter table idxpart detach partition idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 146 +drop index idxpart1_a_idx +-- +STMT: DropStmt +== 147 +drop index idxpart2_a_idx +-- +STMT: DropStmt +== 148 +drop index idxpart3_a_idx +-- +STMT: DropStmt +== 149 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 150 +drop table idxpart, idxpart1, idxpart2, idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: DropStmt +== 151 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 152 +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 153 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 154 +create index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 155 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 156 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 157 +alter table idxpart attach partition idxpart1 for values from (0000) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 158 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 159 +create table idxpart3 partition of idxpart for values from (2000) to (3000) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +== 160 +-- b) after detaching, dropping the index on parent does not remove the others +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 161 +alter table idxpart detach partition idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 162 +alter table idxpart detach partition idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 163 +alter table idxpart detach partition idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 164 +drop index idxpart_a_idx +-- +STMT: DropStmt +== 165 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 166 +drop table idxpart, idxpart1, idxpart2, idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: DropStmt +== 167 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 168 +create table idxpart (a int, b int, c int) partition by range(a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 169 +create index on idxpart(c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 170 +create table idxpart1 partition of idxpart for values from (0) to (250) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 171 +create table idxpart2 partition of idxpart for values from (250) to (500) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 172 +alter table idxpart detach partition idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 173 +alter table idxpart2 drop column c +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +== 174 +drop table idxpart, idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: DropStmt +== 175 +-- Verify that expression indexes inherit correctly +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 176 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 177 +create index on idxpart1 ((a + b)) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 178 +create index on idxpart ((a + b)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 179 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 180 +alter table idxpart attach partition idxpart1 for values from (0000) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 181 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 182 +create table idxpart3 partition of idxpart for values from (2000) to (3000) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +== 183 +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 184 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 185 +-- Verify behavior for collation (mis)matches +create table idxpart (a text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 186 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 187 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 188 +create index on idxpart2 (a collate "POSIX") +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 189 +create index on idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 190 +create index on idxpart2 (a collate "C") +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 191 +alter table idxpart attach partition idxpart1 for values from ('aaa') to ('bbb') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 192 +alter table idxpart attach partition idxpart2 for values from ('bbb') to ('ccc') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 193 +create table idxpart3 partition of idxpart for values from ('ccc') to ('ddd') +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +== 194 +create index on idxpart (a collate "C") +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 195 +create table idxpart4 partition of idxpart for values from ('ddd') to ('eee') +-- +TABLE: name="idxpart4" schema="" table="idxpart4" ctx=DDL +STMT: CreateStmt +== 196 +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 197 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 198 +-- Verify behavior for opclass (mis)matches +create table idxpart (a text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 199 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 200 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 201 +create index on idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 202 +alter table idxpart attach partition idxpart1 for values from ('aaa') to ('bbb') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 203 +alter table idxpart attach partition idxpart2 for values from ('bbb') to ('ccc') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 204 +create table idxpart3 partition of idxpart for values from ('ccc') to ('ddd') +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +== 205 +create index on idxpart (a text_pattern_ops) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 206 +create table idxpart4 partition of idxpart for values from ('ddd') to ('eee') +-- +TABLE: name="idxpart4" schema="" table="idxpart4" ctx=DDL +STMT: CreateStmt +== 207 +-- must *not* have attached the index we created on idxpart2 +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 208 +drop index idxpart_a_idx +-- +STMT: DropStmt +== 209 +create index on only idxpart (a text_pattern_ops) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 210 +-- must reject +alter index idxpart_a_idx attach partition idxpart2_a_idx +-- +STMT: AlterTableStmt +== 211 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 212 +-- Verify that attaching indexes maps attribute numbers correctly +create table idxpart (col1 int, a int, col2 int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 213 +create table idxpart1 (b int, col1 int, col2 int, col3 int, a int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 214 +alter table idxpart drop column col1, drop column col2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 215 +alter table idxpart1 drop column col1, drop column col2, drop column col3 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 216 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 217 +create index idxpart_1_idx on only idxpart (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 218 +create index idxpart1_1_idx on idxpart1 (b, a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 219 +create index idxpart1_1b_idx on idxpart1 (b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 220 +-- test expressions and partial-index predicate, too +create index idxpart_2_idx on only idxpart ((b + a)) where a > 1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 221 +create index idxpart1_2_idx on idxpart1 ((b + a)) where a > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 222 +create index idxpart1_2b_idx on idxpart1 ((a + b)) where a > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 223 +create index idxpart1_2c_idx on idxpart1 ((b + a)) where b > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 224 +alter index idxpart_1_idx attach partition idxpart1_1b_idx +-- +STMT: AlterTableStmt +== 225 +-- fail +alter index idxpart_1_idx attach partition idxpart1_1_idx +-- +STMT: AlterTableStmt +== 226 +alter index idxpart_2_idx attach partition idxpart1_2b_idx +-- +STMT: AlterTableStmt +== 227 +-- fail +alter index idxpart_2_idx attach partition idxpart1_2c_idx +-- +STMT: AlterTableStmt +== 228 +-- fail +alter index idxpart_2_idx attach partition idxpart1_2_idx +-- +STMT: AlterTableStmt +== 229 +-- ok +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 230 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 231 +-- Make sure the partition columns are mapped correctly +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 232 +create index idxparti on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 233 +create index idxparti2 on idxpart (c, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 234 +create table idxpart1 (c text, a int, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 235 +alter table idxpart attach partition idxpart1 for values from (0) to (10) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 236 +create table idxpart2 (c text, a int, b int) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 237 +create index on idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 238 +create index on idxpart2 (c, b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 239 +alter table idxpart attach partition idxpart2 for values from (10) to (20) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 240 +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 241 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 242 +-- Verify that columns are mapped correctly in expression indexes +create table idxpart (col1 int, col2 int, a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 243 +create table idxpart1 (col2 int, b int, col1 int, a int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 244 +create table idxpart2 (col1 int, col2 int, b int, a int) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 245 +alter table idxpart drop column col1, drop column col2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 246 +alter table idxpart1 drop column col1, drop column col2 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 247 +alter table idxpart2 drop column col1, drop column col2 +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +== 248 +create index on idxpart2 (abs(b)) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 249 +alter table idxpart attach partition idxpart2 for values from (0) to (1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 250 +create index on idxpart (abs(b)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 251 +create index on idxpart ((b + 1)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 252 +alter table idxpart attach partition idxpart1 for values from (1) to (2) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 253 +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 254 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 255 +-- Verify that columns are mapped correctly for WHERE in a partial index +create table idxpart (col1 int, a int, col3 int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 256 +alter table idxpart drop column col1, drop column col3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 257 +create table idxpart1 (col1 int, col2 int, col3 int, col4 int, b int, a int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 258 +alter table idxpart1 drop column col1, drop column col2, drop column col3, drop column col4 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 259 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 260 +create table idxpart2 (col1 int, col2 int, b int, a int) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 261 +create index on idxpart2 (a) where b > 1000 +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 262 +alter table idxpart2 drop column col1, drop column col2 +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +== 263 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 264 +create index on idxpart (a) where b > 1000 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 265 +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 266 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 267 +-- Column number mapping: dropped columns in the partition +create table idxpart1 (drop_1 int, drop_2 int, col_keep int, drop_3 int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 268 +alter table idxpart1 drop column drop_1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 269 +alter table idxpart1 drop column drop_2 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 270 +alter table idxpart1 drop column drop_3 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 271 +create index on idxpart1 (col_keep) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 272 +create table idxpart (col_keep int) partition by range (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 273 +create index on idxpart (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 274 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 275 +select attrelid::regclass, attname, attnum from pg_attribute + where attrelid::regclass::text like 'idxpart%' and attnum > 0 + order by attrelid::regclass, attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 276 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 277 +-- Column number mapping: dropped columns in the parent table +create table idxpart(drop_1 int, drop_2 int, col_keep int, drop_3 int) partition by range (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 278 +alter table idxpart drop column drop_1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 279 +alter table idxpart drop column drop_2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 280 +alter table idxpart drop column drop_3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 281 +create table idxpart1 (col_keep int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 282 +create index on idxpart1 (col_keep) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 283 +create index on idxpart (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 284 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 285 +select attrelid::regclass, attname, attnum from pg_attribute + where attrelid::regclass::text like 'idxpart%' and attnum > 0 + order by attrelid::regclass, attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 286 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 287 +|-- +-- Constraint-related indexes +|-- + +-- Verify that it works to add primary key / unique to partitioned tables +create table idxpart (a int primary key, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 288 +-- multiple primary key on child should fail +create table failpart partition of idxpart (b primary key) for values from (0) to (100) +-- +TABLE: name="failpart" schema="" table="failpart" ctx=DDL +STMT: CreateStmt +== 289 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 290 +-- primary key on child is okay if there's no PK in the parent, though +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 291 +create table idxpart1pk partition of idxpart (a primary key) for values from (0) to (100) +-- +TABLE: name="idxpart1pk" schema="" table="idxpart1pk" ctx=DDL +STMT: CreateStmt +== 292 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 293 +-- Failing to use the full partition key is not allowed +create table idxpart (a int unique, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 294 +create table idxpart (a int, b int unique) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 295 +create table idxpart (a int primary key, b int) partition by range (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 296 +create table idxpart (a int, b int primary key) partition by range (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 297 +-- OK if you use them in some other order +create table idxpart (a int, b int, c text, primary key (a, b, c)) partition by range (b, c, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 298 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 299 +-- OK to add an exclusion constraint if partitioning by its equal column +create table idxpart (a int4range, exclude USING GIST (a with = )) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 300 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 301 +-- OK more than one equal column +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with =)) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 302 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 303 +-- OK with more than one equal column: constraint is a proper superset of partition key +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with =)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 304 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 305 +-- Not OK more than one equal column: partition keys are a proper superset of constraint +create table idxpart (a int4range, b int4range, exclude USING GIST (a with = )) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 306 +-- Not OK with just -|- +create table idxpart (a int4range, exclude USING GIST (a with -|- )) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 307 +-- OK with equals and &&, and equals is the partition key +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with &&)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 308 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 309 +-- Not OK with equals and &&, and equals is not the partition key +create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (b with =, c with &&)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 310 +-- OK more than one equal column and a && column +create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (a with =, b with =, c with &&)) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 311 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 312 +-- no expressions in partition key for PK/UNIQUE +create table idxpart (a int primary key, b int) partition by range ((b + a)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 313 +create table idxpart (a int unique, b int) partition by range ((b + a)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 314 +-- use ALTER TABLE to add a primary key +create table idxpart (a int, b int, c text) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 315 +alter table idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 316 +-- not an incomplete one though +alter table idxpart add primary key (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 317 +-- this works +create table idxpart1 partition of idxpart for values from (0, 0) to (1000, 1000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 318 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 319 +-- use ALTER TABLE to add a unique constraint +create table idxpart (a int, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 320 +alter table idxpart add unique (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 321 +-- not an incomplete one though +alter table idxpart add unique (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 322 +-- this works +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 323 +-- Exclusion constraints can be added if partitioning by their equal column +create table idxpart (a int4range, b int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 324 +alter table idxpart add exclude USING GIST (a with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 325 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 326 +-- OK more than one equal column +create table idxpart (a int4range, b int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 327 +alter table idxpart add exclude USING GIST (a with =, b with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 328 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 329 +-- OK with more than one equal column: constraint is a proper superset of partition key +create table idxpart (a int4range, b int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 330 +alter table idxpart add exclude USING GIST (a with =, b with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 331 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 332 +-- Not OK more than one equal column: partition keys are a proper superset of constraint +create table idxpart (a int4range, b int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 333 +alter table idxpart add exclude USING GIST (a with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 334 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 335 +-- Not OK with just -|- +create table idxpart (a int4range, b int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 336 +alter table idxpart add exclude USING GIST (a with -|-) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 337 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 338 +-- OK with equals and &&, and equals is the partition key +create table idxpart (a int4range, b int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 339 +alter table idxpart add exclude USING GIST (a with =, b with &&) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 340 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 341 +-- Not OK with equals and &&, and equals is not the partition key +create table idxpart (a int4range, b int4range, c int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 342 +alter table idxpart add exclude USING GIST (b with =, c with &&) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 343 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 344 +-- OK more than one equal column and a && column +create table idxpart (a int4range, b int4range, c int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 345 +alter table idxpart add exclude USING GIST (a with =, b with =, c with &&) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 346 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 347 +-- When (sub)partitions are created, they also contain the constraint +create table idxpart (a int, b int, primary key (a, b)) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 348 +create table idxpart1 partition of idxpart for values from (1, 1) to (10, 10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 349 +create table idxpart2 partition of idxpart for values from (10, 10) to (20, 20) + partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 350 +create table idxpart21 partition of idxpart2 for values from (10) to (15) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +== 351 +create table idxpart22 partition of idxpart2 for values from (15) to (20) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: CreateStmt +== 352 +create table idxpart3 (b int not null, a int not null) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +== 353 +alter table idxpart attach partition idxpart3 for values from (20, 20) to (30, 30) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 354 +select conname, contype, conrelid::regclass, conindid::regclass, conkey + from pg_constraint where conrelid::regclass::text like 'idxpart%' + order by conrelid::regclass::text, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 355 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 356 +-- Verify that multi-layer partitioning honors the requirement that all +-- columns in the partition key must appear in primary/unique key +create table idxpart (a int, b int, primary key (a)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 357 +create table idxpart2 partition of idxpart +for values from (0) to (1000) partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 358 +-- fail +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 359 +-- Ditto for the ATTACH PARTITION case +create table idxpart (a int unique, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 360 +create table idxpart1 (a int not null, b int, unique (a, b)) + partition by range (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 361 +alter table idxpart attach partition idxpart1 for values from (1) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 362 +DROP TABLE idxpart, idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: DropStmt +== 363 +-- Multi-layer partitioning works correctly in this case: +create table idxpart (a int, b int, primary key (a, b)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 364 +create table idxpart2 partition of idxpart for values from (0) to (1000) partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 365 +create table idxpart21 partition of idxpart2 for values from (0) to (1000) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +== 366 +select conname, contype, conrelid::regclass, conindid::regclass, conkey + from pg_constraint where conrelid::regclass::text like 'idxpart%' + order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +== 367 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 368 +-- If a partitioned table has a unique/PK constraint, then it's not possible +-- to drop the corresponding constraint in the children; nor it's possible +-- to drop the indexes individually. Dropping the constraint in the parent +-- gets rid of the lot. +create table idxpart (i int) partition by hash (i) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 369 +create table idxpart0 partition of idxpart (i) for values with (modulus 2, remainder 0) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: CreateStmt +== 370 +create table idxpart1 partition of idxpart (i) for values with (modulus 2, remainder 1) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 371 +alter table idxpart0 add primary key(i) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +== 372 +alter table idxpart add primary key(i) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 373 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 374 +drop index idxpart0_pkey +-- +STMT: DropStmt +== 375 +-- fail +drop index idxpart1_pkey +-- +STMT: DropStmt +== 376 +-- fail +alter table idxpart0 drop constraint idxpart0_pkey +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +== 377 +-- fail +alter table idxpart1 drop constraint idxpart1_pkey +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 378 +-- fail +alter table idxpart drop constraint idxpart_pkey +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 379 +-- ok +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 380 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 381 +-- If the partition to be attached already has a primary key, fail if +-- it doesn't match the parent's PK. +CREATE TABLE idxpart (c1 INT PRIMARY KEY, c2 INT, c3 VARCHAR(10)) PARTITION BY RANGE(c1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 382 +CREATE TABLE idxpart1 (LIKE idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 383 +ALTER TABLE idxpart1 ADD PRIMARY KEY (c1, c2) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 384 +ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 385 +DROP TABLE idxpart, idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: DropStmt +== 386 +-- Ditto if there is some distance between the PKs (subpartitioning) +create table idxpart (a int, b int, primary key (a)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 387 +create table idxpart1 (a int not null, b int) partition by range (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 388 +create table idxpart11 (a int not null, b int primary key) +-- +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: CreateStmt +== 389 +alter table idxpart1 attach partition idxpart11 for values from (0) to (1000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +== 390 +alter table idxpart attach partition idxpart1 for values from (0) to (10000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 391 +drop table idxpart, idxpart1, idxpart11 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: DropStmt +== 392 +-- If a partitioned table has a constraint whose index is not valid, +-- attaching a missing partition makes it valid. +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 393 +create table idxpart0 (like idxpart) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: CreateStmt +== 394 +alter table idxpart0 add primary key (a) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +== 395 +alter table idxpart attach partition idxpart0 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 396 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 397 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 398 +alter index idxpart_pkey attach partition idxpart0_pkey +-- +STMT: AlterTableStmt +== 399 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 400 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 401 +-- Related to the above scenario: ADD PRIMARY KEY on the parent mustn't +-- automatically propagate NOT NULL to child columns. +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 402 +create table idxpart0 (like idxpart) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: CreateStmt +== 403 +alter table idxpart0 add unique (a) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +== 404 +alter table idxpart attach partition idxpart0 default +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 405 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 406 +-- fail, no not-null constraint +alter table idxpart0 alter column a set not null +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +== 407 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 408 +-- now it works +alter index idxpart_pkey attach partition idxpart0_a_key +-- +STMT: AlterTableStmt +== 409 +alter table idxpart0 alter column a drop not null +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +== 410 +-- fail, pkey needs it +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 411 +-- if a partition has a unique index without a constraint, does not attach +-- automatically; creates a new index instead. +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 412 +create table idxpart1 (a int not null, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 413 +create unique index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 414 +alter table idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 415 +alter table idxpart attach partition idxpart1 for values from (1) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 416 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 417 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 418 +-- Can't attach an index without a corresponding constraint +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 419 +create table idxpart1 (a int not null, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 420 +create unique index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +== 421 +alter table idxpart attach partition idxpart1 for values from (1) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 422 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 423 +alter index idxpart_pkey attach partition idxpart1_a_idx +-- +STMT: AlterTableStmt +== 424 +-- fail +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 425 +-- Test that unique constraints are working +create table idxpart (a int, b text, primary key (a, b)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 426 +create table idxpart1 partition of idxpart for values from (0) to (100000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 427 +create table idxpart2 (c int, like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 428 +insert into idxpart2 (c, a, b) values (42, 572814, 'inserted first') +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 429 +alter table idxpart2 drop column c +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +== 430 +create unique index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 431 +alter table idxpart attach partition idxpart2 for values from (100000) to (1000000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 432 +insert into idxpart values (0, 'zero'), (42, 'life'), (2^16, 'sixteen') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 433 +insert into idxpart select 2^g, format('two to power of %s', g) from generate_series(15, 17) g +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 434 +insert into idxpart values (16, 'sixteen') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 435 +insert into idxpart (b, a) values ('one', 142857), ('two', 285714) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 436 +insert into idxpart select a * 2, b || b from idxpart where a between 2^16 and 2^19 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 437 +insert into idxpart values (572814, 'five') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 438 +insert into idxpart values (857142, 'six') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 439 +select tableoid::regclass, * from idxpart order by a +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +STMT: SelectStmt +== 440 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 441 +-- Test some other non-btree index types +create table idxpart (a int, b text, c int[]) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 442 +create table idxpart1 partition of idxpart for values from (0) to (100000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 443 +set enable_seqscan to off +-- +STMT: VariableSetStmt +== 444 +create index idxpart_brin on idxpart using brin(b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 445 +explain (costs off) select * from idxpart where b = 'abcd' +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 446 +drop index idxpart_brin +-- +STMT: DropStmt +== 447 +create index idxpart_spgist on idxpart using spgist(b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 448 +explain (costs off) select * from idxpart where b = 'abcd' +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 449 +drop index idxpart_spgist +-- +STMT: DropStmt +== 450 +create index idxpart_gin on idxpart using gin(c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 451 +explain (costs off) select * from idxpart where c @> array[42] +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 452 +drop index idxpart_gin +-- +STMT: DropStmt +== 453 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 454 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +== 455 +-- intentionally leave some objects around +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +== 456 +create table idxpart1 partition of idxpart for values from (0) to (100) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +== 457 +create table idxpart2 partition of idxpart for values from (100) to (1000) + partition by range (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +== 458 +create table idxpart21 partition of idxpart2 for values from (100) to (200) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +== 459 +create table idxpart22 partition of idxpart2 for values from (200) to (300) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: CreateStmt +== 460 +create index on idxpart22 (a) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: IndexStmt +== 461 +create index on only idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +== 462 +alter index idxpart2_a_idx attach partition idxpart22_a_idx +-- +STMT: AlterTableStmt +== 463 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +== 464 +create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a) +-- +TABLE: name="idxpart_another" schema="" table="idxpart_another" ctx=DDL +STMT: CreateStmt +== 465 +create table idxpart_another_1 partition of idxpart_another for values from (0) to (100) +-- +TABLE: name="idxpart_another_1" schema="" table="idxpart_another_1" ctx=DDL +STMT: CreateStmt +== 466 +create table idxpart3 (c int, b int, a int) partition by range (a) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +== 467 +alter table idxpart3 drop column b, drop column c +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: AlterTableStmt +== 468 +create table idxpart31 partition of idxpart3 for values from (1000) to (1200) +-- +TABLE: name="idxpart31" schema="" table="idxpart31" ctx=DDL +STMT: CreateStmt +== 469 +create table idxpart32 partition of idxpart3 for values from (1200) to (1400) +-- +TABLE: name="idxpart32" schema="" table="idxpart32" ctx=DDL +STMT: CreateStmt +== 470 +alter table idxpart attach partition idxpart3 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +== 471 +-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade +-- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql +create schema regress_indexing +-- +STMT: CreateSchemaStmt +== 472 +set search_path to regress_indexing +-- +STMT: VariableSetStmt +== 473 +create table pk (a int primary key) partition by range (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +== 474 +create table pk1 partition of pk for values from (0) to (1000) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +== 475 +create table pk2 (b int, a int) +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: CreateStmt +== 476 +alter table pk2 drop column b +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +== 477 +alter table pk2 alter a set not null +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +== 478 +alter table pk attach partition pk2 for values from (1000) to (2000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +== 479 +create table pk3 partition of pk for values from (2000) to (3000) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +== 480 +create table pk4 (like pk) +-- +TABLE: name="pk4" schema="" table="pk4" ctx=DDL +STMT: CreateStmt +== 481 +alter table pk attach partition pk4 for values from (3000) to (4000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +== 482 +create table pk5 (like pk) partition by range (a) +-- +TABLE: name="pk5" schema="" table="pk5" ctx=DDL +STMT: CreateStmt +== 483 +create table pk51 partition of pk5 for values from (4000) to (4500) +-- +TABLE: name="pk51" schema="" table="pk51" ctx=DDL +STMT: CreateStmt +== 484 +create table pk52 partition of pk5 for values from (4500) to (5000) +-- +TABLE: name="pk52" schema="" table="pk52" ctx=DDL +STMT: CreateStmt +== 485 +alter table pk attach partition pk5 for values from (4000) to (5000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +== 486 +reset search_path +-- +STMT: VariableSetStmt +== 487 +-- Test that covering partitioned indexes work in various cases +create table covidxpart (a int, b int) partition by list (a) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: CreateStmt +== 488 +create unique index on covidxpart (a) include (b) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: IndexStmt +== 489 +create table covidxpart1 partition of covidxpart for values in (1) +-- +TABLE: name="covidxpart1" schema="" table="covidxpart1" ctx=DDL +STMT: CreateStmt +== 490 +create table covidxpart2 partition of covidxpart for values in (2) +-- +TABLE: name="covidxpart2" schema="" table="covidxpart2" ctx=DDL +STMT: CreateStmt +== 491 +insert into covidxpart values (1, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 492 +insert into covidxpart values (1, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 493 +create table covidxpart3 (b int, c int, a int) +-- +TABLE: name="covidxpart3" schema="" table="covidxpart3" ctx=DDL +STMT: CreateStmt +== 494 +alter table covidxpart3 drop c +-- +TABLE: name="covidxpart3" schema="" table="covidxpart3" ctx=DDL +STMT: AlterTableStmt +== 495 +alter table covidxpart attach partition covidxpart3 for values in (3) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: AlterTableStmt +== 496 +insert into covidxpart values (3, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 497 +insert into covidxpart values (3, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 498 +create table covidxpart4 (b int, a int) +-- +TABLE: name="covidxpart4" schema="" table="covidxpart4" ctx=DDL +STMT: CreateStmt +== 499 +create unique index on covidxpart4 (a) include (b) +-- +TABLE: name="covidxpart4" schema="" table="covidxpart4" ctx=DDL +STMT: IndexStmt +== 500 +create unique index on covidxpart4 (a) +-- +TABLE: name="covidxpart4" schema="" table="covidxpart4" ctx=DDL +STMT: IndexStmt +== 501 +alter table covidxpart attach partition covidxpart4 for values in (4) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: AlterTableStmt +== 502 +insert into covidxpart values (4, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 503 +insert into covidxpart values (4, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 504 +create unique index on covidxpart (b) include (a) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: IndexStmt +== 505 +-- should fail + +-- check that detaching a partition also detaches the primary key constraint +create table parted_pk_detach_test (a int primary key) partition by list (a) +-- +TABLE: name="parted_pk_detach_test" schema="" table="parted_pk_detach_test" ctx=DDL +STMT: CreateStmt +== 506 +create table parted_pk_detach_test1 partition of parted_pk_detach_test for values in (1) +-- +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: CreateStmt +== 507 +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey +-- +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: AlterTableStmt +== 508 +-- should fail +alter table parted_pk_detach_test detach partition parted_pk_detach_test1 +-- +TABLE: name="parted_pk_detach_test" schema="" table="parted_pk_detach_test" ctx=DDL +STMT: AlterTableStmt +== 509 +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey +-- +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: AlterTableStmt +== 510 +drop table parted_pk_detach_test, parted_pk_detach_test1 +-- +TABLE: name="parted_pk_detach_test" schema="" table="parted_pk_detach_test" ctx=DDL +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: DropStmt +== 511 +create table parted_uniq_detach_test (a int unique) partition by list (a) +-- +TABLE: name="parted_uniq_detach_test" schema="" table="parted_uniq_detach_test" ctx=DDL +STMT: CreateStmt +== 512 +create table parted_uniq_detach_test1 partition of parted_uniq_detach_test for values in (1) +-- +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: CreateStmt +== 513 +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key +-- +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: AlterTableStmt +== 514 +-- should fail +alter table parted_uniq_detach_test detach partition parted_uniq_detach_test1 +-- +TABLE: name="parted_uniq_detach_test" schema="" table="parted_uniq_detach_test" ctx=DDL +STMT: AlterTableStmt +== 515 +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key +-- +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: AlterTableStmt +== 516 +drop table parted_uniq_detach_test, parted_uniq_detach_test1 +-- +TABLE: name="parted_uniq_detach_test" schema="" table="parted_uniq_detach_test" ctx=DDL +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: DropStmt +== 517 +-- check that dropping a column takes with it any partitioned indexes +-- depending on it. +create table parted_index_col_drop(a int, b int, c int) + partition by list (a) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: CreateStmt +== 518 +create table parted_index_col_drop1 partition of parted_index_col_drop + for values in (1) partition by list (a) +-- +TABLE: name="parted_index_col_drop1" schema="" table="parted_index_col_drop1" ctx=DDL +STMT: CreateStmt +== 519 +-- leave this partition without children. +create table parted_index_col_drop2 partition of parted_index_col_drop + for values in (2) partition by list (a) +-- +TABLE: name="parted_index_col_drop2" schema="" table="parted_index_col_drop2" ctx=DDL +STMT: CreateStmt +== 520 +create table parted_index_col_drop11 partition of parted_index_col_drop1 + for values in (1) +-- +TABLE: name="parted_index_col_drop11" schema="" table="parted_index_col_drop11" ctx=DDL +STMT: CreateStmt +== 521 +create index on parted_index_col_drop (b) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: IndexStmt +== 522 +create index on parted_index_col_drop (c) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: IndexStmt +== 523 +create index on parted_index_col_drop (b, c) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: IndexStmt +== 524 +alter table parted_index_col_drop drop column c +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: AlterTableStmt +== 525 +drop table parted_index_col_drop +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: DropStmt +== 526 +-- Check that invalid indexes are not selected when attaching a partition. +create table parted_inval_tab (a int) partition by range (a) +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: CreateStmt +== 527 +create index parted_inval_idx on parted_inval_tab (a) +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: IndexStmt +== 528 +create table parted_inval_tab_1 (a int) partition by range (a) +-- +TABLE: name="parted_inval_tab_1" schema="" table="parted_inval_tab_1" ctx=DDL +STMT: CreateStmt +== 529 +create table parted_inval_tab_1_1 partition of parted_inval_tab_1 + for values from (0) to (10) +-- +TABLE: name="parted_inval_tab_1_1" schema="" table="parted_inval_tab_1_1" ctx=DDL +STMT: CreateStmt +== 530 +create table parted_inval_tab_1_2 partition of parted_inval_tab_1 + for values from (10) to (20) +-- +TABLE: name="parted_inval_tab_1_2" schema="" table="parted_inval_tab_1_2" ctx=DDL +STMT: CreateStmt +== 531 +-- this creates an invalid index. +create index parted_inval_ixd_1 on only parted_inval_tab_1 (a) +-- +TABLE: name="parted_inval_tab_1" schema="" table="parted_inval_tab_1" ctx=DDL +STMT: IndexStmt +== 532 +-- this creates new indexes for all the partitions of parted_inval_tab_1, +-- discarding the invalid index created previously as what is chosen. +alter table parted_inval_tab attach partition parted_inval_tab_1 + for values from (1) to (100) +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: AlterTableStmt +== 533 +select indexrelid::regclass, indisvalid, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_inval%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 534 +drop table parted_inval_tab +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: DropStmt +== 535 +-- Check setup of indisvalid across a complex partition tree on index +-- creation. If one index in a partition index is invalid, so should its +-- partitioned index. +create table parted_isvalid_tab (a int, b int) partition by range (a) +-- +TABLE: name="parted_isvalid_tab" schema="" table="parted_isvalid_tab" ctx=DDL +STMT: CreateStmt +== 536 +create table parted_isvalid_tab_1 partition of parted_isvalid_tab + for values from (1) to (10) partition by range (a) +-- +TABLE: name="parted_isvalid_tab_1" schema="" table="parted_isvalid_tab_1" ctx=DDL +STMT: CreateStmt +== 537 +create table parted_isvalid_tab_2 partition of parted_isvalid_tab + for values from (10) to (20) partition by range (a) +-- +TABLE: name="parted_isvalid_tab_2" schema="" table="parted_isvalid_tab_2" ctx=DDL +STMT: CreateStmt +== 538 +create table parted_isvalid_tab_11 partition of parted_isvalid_tab_1 + for values from (1) to (5) +-- +TABLE: name="parted_isvalid_tab_11" schema="" table="parted_isvalid_tab_11" ctx=DDL +STMT: CreateStmt +== 539 +create table parted_isvalid_tab_12 partition of parted_isvalid_tab_1 + for values from (5) to (10) +-- +TABLE: name="parted_isvalid_tab_12" schema="" table="parted_isvalid_tab_12" ctx=DDL +STMT: CreateStmt +== 540 +-- create an invalid index on one of the partitions. +insert into parted_isvalid_tab_11 values (1, 0) +-- +TABLE: name="parted_isvalid_tab_11" schema="" table="parted_isvalid_tab_11" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 541 +create index concurrently parted_isvalid_idx_11 on parted_isvalid_tab_11 ((a/b)) +-- +TABLE: name="parted_isvalid_tab_11" schema="" table="parted_isvalid_tab_11" ctx=DDL +STMT: IndexStmt +== 542 +-- The previous invalid index is selected, invalidating all the indexes up to +-- the top-most parent. +create index parted_isvalid_idx on parted_isvalid_tab ((a/b)) +-- +TABLE: name="parted_isvalid_tab" schema="" table="parted_isvalid_tab" ctx=DDL +STMT: IndexStmt +== 543 +select indexrelid::regclass, indisvalid, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_isvalid%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 544 +drop table parted_isvalid_tab +-- +TABLE: name="parted_isvalid_tab" schema="" table="parted_isvalid_tab" ctx=DDL +STMT: DropStmt +== 545 +-- Check state of replica indexes when attaching a partition. +begin +-- +STMT: TransactionStmt +== 546 +create table parted_replica_tab (id int not null) partition by range (id) +-- +TABLE: name="parted_replica_tab" schema="" table="parted_replica_tab" ctx=DDL +STMT: CreateStmt +== 547 +create table parted_replica_tab_1 partition of parted_replica_tab + for values from (1) to (10) partition by range (id) +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: CreateStmt +== 548 +create table parted_replica_tab_11 partition of parted_replica_tab_1 + for values from (1) to (5) +-- +TABLE: name="parted_replica_tab_11" schema="" table="parted_replica_tab_11" ctx=DDL +STMT: CreateStmt +== 549 +create unique index parted_replica_idx + on only parted_replica_tab using btree (id) +-- +TABLE: name="parted_replica_tab" schema="" table="parted_replica_tab" ctx=DDL +STMT: IndexStmt +== 550 +create unique index parted_replica_idx_1 + on only parted_replica_tab_1 using btree (id) +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: IndexStmt +== 551 +-- This triggers an update of pg_index.indisreplident for parted_replica_idx. +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1 +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: AlterTableStmt +== 552 +create unique index parted_replica_idx_11 on parted_replica_tab_11 USING btree (id) +-- +TABLE: name="parted_replica_tab_11" schema="" table="parted_replica_tab_11" ctx=DDL +STMT: IndexStmt +== 553 +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 554 +-- parted_replica_idx is not valid yet here, because parted_replica_idx_1 +-- is not valid. +alter index parted_replica_idx ATTACH PARTITION parted_replica_idx_1 +-- +STMT: AlterTableStmt +== 555 +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 556 +-- parted_replica_idx becomes valid here. +alter index parted_replica_idx_1 ATTACH PARTITION parted_replica_idx_11 +-- +STMT: AlterTableStmt +== 557 +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1 +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: AlterTableStmt +== 558 +commit +-- +STMT: TransactionStmt +== 559 +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +== 560 +drop table parted_replica_tab +-- +TABLE: name="parted_replica_tab" schema="" table="parted_replica_tab" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/indirect_toast.metadata.json b/parser/testdata/summary/postgres_regress/indirect_toast.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/indirect_toast.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary/postgres_regress/indirect_toast.test b/parser/testdata/summary/postgres_regress/indirect_toast.test new file mode 100644 index 0000000..de2edd3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/indirect_toast.test @@ -0,0 +1,198 @@ +== 001 +|-- +-- Tests for external toast datums +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION make_tuple_indirect (record) + RETURNS record + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 198 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- Other compression algorithms may cause the compressed data to be stored +-- inline. pglz guarantees that the data is externalized, so stick to it. +SET default_toast_compression = 'pglz' +-- +STMT: VariableSetStmt +== 003 +CREATE TABLE indtoasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: CreateStmt +== 004 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- check whether indirect tuples works on the most basic level +SELECT descr, substring(make_tuple_indirect(indtoasttest)::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +FUNCTION: name="make_tuple_indirect" function="make_tuple_indirect" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- modification without changing varlenas +UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 010 +-- modification without modifying assigned value +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 011 +-- modification modifying, but effectively not changing +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 012 +UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 013 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- check we didn't screw with main/toast tuple visibility +VACUUM FREEZE indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: VacuumStmt +== 015 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- now create a trigger that forces all Datums to be indirect ones +CREATE FUNCTION update_using_indirect() + RETURNS trigger + LANGUAGE plpgsql AS $$ +BEGIN + NEW := make_tuple_indirect(NEW); + RETURN NEW; +END$$ +-- +FUNCTION: name="update_using_indirect" function="update_using_indirect" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +CREATE TRIGGER indtoasttest_update_indirect + BEFORE INSERT OR UPDATE + ON indtoasttest + FOR EACH ROW + EXECUTE PROCEDURE update_using_indirect() +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: CreateTrigStmt +== 018 +-- modification without changing varlenas +UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 019 +-- modification without modifying assigned value +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 020 +-- modification modifying, but effectively not changing +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 021 +UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +== 022 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 023 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +== 024 +-- check we didn't screw with main/toast tuple visibility +VACUUM FREEZE indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: VacuumStmt +== 025 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +== 026 +DROP TABLE indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: DropStmt +== 027 +DROP FUNCTION update_using_indirect() +-- +FUNCTION: name="update_using_indirect" function="update_using_indirect" schema="" ctx=DDL +STMT: DropStmt +== 028 +RESET default_toast_compression +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/inet.metadata.json b/parser/testdata/summary/postgres_regress/inet.metadata.json new file mode 100644 index 0000000..1211f6e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/inet.metadata.json @@ -0,0 +1,115 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111" + ] +} diff --git a/parser/testdata/summary/postgres_regress/inet.test b/parser/testdata/summary/postgres_regress/inet.test new file mode 100644 index 0000000..748bbb1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/inet.test @@ -0,0 +1,759 @@ +== 001 +|-- +-- INET +|-- + +-- prepare the table... + +DROP TABLE INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: DropStmt +== 002 +CREATE TABLE INET_TBL (c cidr, i inet) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.226/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.0/26', '192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.0/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.0/25') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.255/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.255/25') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO INET_TBL (c, i) VALUES ('10', '10.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO INET_TBL (c, i) VALUES ('10.0.0.0', '10.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO INET_TBL (c, i) VALUES ('10.1.2.3', '10.1.2.3/32') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO INET_TBL (c, i) VALUES ('10.1.2', '10.1.2.3/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO INET_TBL (c, i) VALUES ('10.1', '10.1.2.3/16') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO INET_TBL (c, i) VALUES ('10', '10.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO INET_TBL (c, i) VALUES ('10', '11.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO INET_TBL (c, i) VALUES ('10:23::f1', '10:23::f1/64') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO INET_TBL (c, i) VALUES ('10:23::8000/113', '10:23::ffff') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO INET_TBL (c, i) VALUES ('::ffff:1.2.3.4', '::4.3.2.1/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +-- check that CIDR rejects invalid input: +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/30', '192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO INET_TBL (c, i) VALUES ('1234::1234::1234', '::1.2.3.4') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +-- check that CIDR rejects invalid input when converting from text: +INSERT INTO INET_TBL (c, i) VALUES (cidr('192.168.1.2/30'), '192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +FUNCTION: name="cidr" function="cidr" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO INET_TBL (c, i) VALUES (cidr('ffff:ffff:ffff:ffff::/24'), '::192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +FUNCTION: name="cidr" function="cidr" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 024 +SELECT c AS cidr, i AS inet FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 025 +-- now test some support functions + +SELECT i AS inet, host(i), text(i), family(i) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="host" function="host" schema="" ctx=Call +FUNCTION: name="text" function="text" schema="" ctx=Call +FUNCTION: name="family" function="family" schema="" ctx=Call +STMT: SelectStmt +== 026 +SELECT c AS cidr, abbrev(c) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="abbrev" function="abbrev" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT c AS cidr, broadcast(c), + i AS inet, broadcast(i) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="broadcast" function="broadcast" schema="" ctx=Call +FUNCTION: name="broadcast" function="broadcast" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT c AS cidr, network(c) AS "network(cidr)", + i AS inet, network(i) AS "network(inet)" FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="network" function="network" schema="" ctx=Call +FUNCTION: name="network" function="network" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT c AS cidr, masklen(c) AS "masklen(cidr)", + i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT c AS cidr, masklen(c) AS "masklen(cidr)", + i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL + WHERE masklen(c) <= 8 +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +== 031 +SELECT c AS cidr, i AS inet FROM INET_TBL + WHERE c = i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 032 +SELECT i, c, + i < c AS lt, i <= c AS le, i = c AS eq, + i >= c AS ge, i > c AS gt, i <> c AS ne, + i << c AS sb, i <<= c AS sbe, + i >> c AS sup, i >>= c AS spe, + i && c AS ovr + FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 033 +SELECT max(i) AS max, min(i) AS min FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT max(c) AS max, min(c) AS min FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 035 +-- check the conversion to/from text and set_netmask +SELECT set_masklen(inet(text(i)), 24) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="set_masklen" function="set_masklen" schema="" ctx=Call +FUNCTION: name="inet" function="inet" schema="" ctx=Call +FUNCTION: name="text" function="text" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- check that btree index works correctly +CREATE INDEX inet_idx1 ON inet_tbl(i) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: IndexStmt +== 037 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +== 038 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 040 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 041 +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 042 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 044 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 045 +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 046 +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +== 047 +DROP INDEX inet_idx1 +-- +STMT: DropStmt +== 048 +-- check that gist index works correctly +CREATE INDEX inet_idx2 ON inet_tbl using gist (i inet_ops) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: IndexStmt +== 049 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +== 050 +SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 051 +SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 052 +SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 053 +SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 054 +SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 055 +SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 056 +SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 057 +SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 058 +SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 059 +SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 060 +SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 061 +-- test index-only scans +EXPLAIN (COSTS OFF) +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 062 +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 063 +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +== 064 +DROP INDEX inet_idx2 +-- +STMT: DropStmt +== 065 +-- check that spgist index works correctly +CREATE INDEX inet_idx3 ON inet_tbl using spgist (i) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: IndexStmt +== 066 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +== 067 +SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 068 +SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 069 +SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 070 +SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 071 +SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 072 +SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 073 +SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 074 +SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 075 +SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 076 +SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 077 +SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 078 +-- test index-only scans +EXPLAIN (COSTS OFF) +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 079 +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 080 +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +== 081 +DROP INDEX inet_idx3 +-- +STMT: DropStmt +== 082 +-- simple tests of inet boolean and arithmetic operators +SELECT i, ~i AS "~i" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 083 +SELECT i, c, i & c AS "and" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 084 +SELECT i, c, i | c AS "or" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 085 +SELECT i, i + 500 AS "i+500" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 086 +SELECT i, i - 500 AS "i-500" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 087 +SELECT i, c, i - c AS "minus" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +== 088 +SELECT '127.0.0.1'::inet + 257 +-- +STMT: SelectStmt +== 089 +SELECT ('127.0.0.1'::inet + 257) - 257 +-- +STMT: SelectStmt +== 090 +SELECT '127::1'::inet + 257 +-- +STMT: SelectStmt +== 091 +SELECT ('127::1'::inet + 257) - 257 +-- +STMT: SelectStmt +== 092 +SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet + 500) +-- +STMT: SelectStmt +== 093 +SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet - 500) +-- +STMT: SelectStmt +== 094 +SELECT '127::2'::inet - ('127::2'::inet + 500) +-- +STMT: SelectStmt +== 095 +SELECT '127::2'::inet - ('127::2'::inet - 500) +-- +STMT: SelectStmt +== 096 +-- these should give overflow errors: +SELECT '127.0.0.1'::inet + 10000000000 +-- +STMT: SelectStmt +== 097 +SELECT '127.0.0.1'::inet - 10000000000 +-- +STMT: SelectStmt +== 098 +SELECT '126::1'::inet - '127::2'::inet +-- +STMT: SelectStmt +== 099 +SELECT '127::1'::inet - '126::2'::inet +-- +STMT: SelectStmt +== 100 +-- but not these +SELECT '127::1'::inet + 10000000000 +-- +STMT: SelectStmt +== 101 +SELECT '127::1'::inet - '127::2'::inet +-- +STMT: SelectStmt +== 102 +-- insert one more row with addressed from different families +INSERT INTO INET_TBL (c, i) VALUES ('10', '10::/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +-- now, this one should fail +SELECT inet_merge(c, i) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="inet_merge" function="inet_merge" schema="" ctx=Call +STMT: SelectStmt +== 104 +-- fix it by inet_same_family() condition +SELECT inet_merge(c, i) FROM INET_TBL WHERE inet_same_family(c, i) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="inet_same_family" function="inet_same_family" schema="" ctx=Call +FUNCTION: name="inet_merge" function="inet_merge" schema="" ctx=Call +FUNCTION: name="inet_same_family" function="inet_same_family" schema="" ctx=Call +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 105 +-- Test inet sortsupport with a variety of boundary inputs: +SELECT a FROM (VALUES + ('0.0.0.0/0'::inet), + ('0.0.0.0/1'::inet), + ('0.0.0.0/32'::inet), + ('0.0.0.1/0'::inet), + ('0.0.0.1/1'::inet), + ('127.126.127.127/0'::inet), + ('127.127.127.127/0'::inet), + ('127.128.127.127/0'::inet), + ('192.168.1.0/24'::inet), + ('192.168.1.0/25'::inet), + ('192.168.1.1/23'::inet), + ('192.168.1.1/5'::inet), + ('192.168.1.1/6'::inet), + ('192.168.1.1/25'::inet), + ('192.168.1.2/25'::inet), + ('192.168.1.1/26'::inet), + ('192.168.1.2/26'::inet), + ('192.168.1.2/23'::inet), + ('192.168.1.255/5'::inet), + ('192.168.1.255/6'::inet), + ('192.168.1.3/1'::inet), + ('192.168.1.3/23'::inet), + ('192.168.1.4/0'::inet), + ('192.168.1.5/0'::inet), + ('255.0.0.0/0'::inet), + ('255.1.0.0/0'::inet), + ('255.2.0.0/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/15'::inet), + ('255.255.000.000/16'::inet), + ('255.255.255.254/32'::inet), + ('255.255.255.000/32'::inet), + ('255.255.255.001/31'::inet), + ('255.255.255.002/31'::inet), + ('255.255.255.003/31'::inet), + ('255.255.255.003/32'::inet), + ('255.255.255.001/32'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/1'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/31'::inet), + ('255.255.255.255/32'::inet), + ('255.255.255.253/32'::inet), + ('255.255.255.252/32'::inet), + ('255.3.0.0/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/128'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0001/128'::inet), + ('10:23::f1/64'::inet), + ('10:23::f1/65'::inet), + ('10:23::ffff'::inet), + ('127::1'::inet), + ('127::2'::inet), + ('8000:0000:0000:0000:0000:0000:0000:0000/1'::inet), + ('::1:ffff:ffff:ffff:ffff/128'::inet), + ('::2:ffff:ffff:ffff:ffff/128'::inet), + ('::4:3:2:0/24'::inet), + ('::4:3:2:1/24'::inet), + ('::4:3:2:2/24'::inet), + ('ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70'::inet), + ('ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44'::inet), + ('ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69'::inet), + ('ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73'::inet), + ('ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89'::inet), + ('ffff:8dd0:646:694c:7c16:7e35:6a26:171/104'::inet), + ('ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121'::inet), + ('ffff:90e7:e744:664:a93:8efe:1f25:7663/122'::inet), + ('ffff:9597:c69c:8b24:57a:8639:ec78:6026/111'::inet), + ('ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88'::inet), + ('ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23'::inet), + ('ffff:fffa:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffb:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffc:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffd:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffe:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffa:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffb:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffc:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffd::/128'::inet), + ('ffff:ffff:ffff:fffd:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffe::/128'::inet), + ('ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:0/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:1/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:2/24'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet) +) AS i(a) ORDER BY a +-- +STMT: SelectStmt +== 106 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('1234', 'cidr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 107 +SELECT * FROM pg_input_error_info('1234', 'cidr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT pg_input_is_valid('192.168.198.200/24', 'cidr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 109 +SELECT * FROM pg_input_error_info('192.168.198.200/24', 'cidr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 110 +SELECT pg_input_is_valid('1234', 'inet') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 111 +SELECT * FROM pg_input_error_info('1234', 'inet') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json b/parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json new file mode 100644 index 0000000..3e33966 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json @@ -0,0 +1,7 @@ +{ + "todo": [ + "001", + "002", + "003" + ] +} diff --git a/parser/testdata/summary/postgres_regress/infinite_recurse.test b/parser/testdata/summary/postgres_regress/infinite_recurse.test new file mode 100644 index 0000000..4a951eb --- /dev/null +++ b/parser/testdata/summary/postgres_regress/infinite_recurse.test @@ -0,0 +1,33 @@ +== 001 +-- Check that stack depth detection mechanism works and +-- max_stack_depth is not set too high. + +create function infinite_recurse() returns int as +'select infinite_recurse()' language sql +-- +FUNCTION: name="infinite_recurse" function="infinite_recurse" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +-- Unfortunately, up till mid 2020 the Linux kernel had a bug in PPC64 +-- signal handling that would cause this test to crash if it happened +-- to receive an sinval catchup interrupt while the stack is deep: +-- https://bugzilla.kernel.org/show_bug.cgi?id=205183 +-- It is likely to be many years before that bug disappears from all +-- production kernels, so disable this test on such platforms. +-- (We still create the function, so as not to have a cross-platform +-- difference in the end state of the regression database.) + +SELECT version() ~ 'powerpc64[^,]*-linux-gnu' + AS skip_test +-- +FUNCTION: name="version" function="version" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- The full error report is not very stable, so we show only SQLSTATE +-- and primary error message. + + +select infinite_recurse() +-- +FUNCTION: name="infinite_recurse" function="infinite_recurse" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/inherit.metadata.json b/parser/testdata/summary/postgres_regress/inherit.metadata.json new file mode 100644 index 0000000..53ffb30 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/inherit.metadata.json @@ -0,0 +1,681 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677" + ] +} diff --git a/parser/testdata/summary/postgres_regress/inherit.test b/parser/testdata/summary/postgres_regress/inherit.test new file mode 100644 index 0000000..1093161 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/inherit.test @@ -0,0 +1,4183 @@ +== 001 +|-- +-- Test inheritance features +|-- +CREATE TABLE a (aa TEXT) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE b (bb TEXT) INHERITS (a) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE c (cc TEXT) INHERITS (a) +-- +TABLE: name="c" schema="" table="c" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE d (dd TEXT) INHERITS (b,c,a) +-- +TABLE: name="d" schema="" table="d" ctx=DDL +STMT: CreateStmt +== 005 +INSERT INTO a(aa) VALUES('aaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO a(aa) VALUES('aaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO a(aa) VALUES('aaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO a(aa) VALUES('aaaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO a(aa) VALUES('aaaaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO a(aa) VALUES('aaaaaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO b(aa) VALUES('bbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO b(aa) VALUES('bbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO b(aa) VALUES('bbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO b(aa) VALUES('bbbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO b(aa) VALUES('bbbbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO b(aa) VALUES('bbbbbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO c(aa) VALUES('ccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO c(aa) VALUES('cccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO c(aa) VALUES('ccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO c(aa) VALUES('cccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO c(aa) VALUES('ccccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO c(aa) VALUES('cccccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO d(aa) VALUES('ddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO d(aa) VALUES('dddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO d(aa) VALUES('ddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO d(aa) VALUES('dddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO d(aa) VALUES('ddddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO d(aa) VALUES('dddddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 030 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 031 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 032 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 033 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 034 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 035 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 036 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 037 +UPDATE a SET aa='zzzz' WHERE aa='aaaa' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +== 038 +UPDATE ONLY a SET aa='zzzzz' WHERE aa='aaaaa' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +== 039 +UPDATE b SET aa='zzz' WHERE aa='aaa' +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: UpdateStmt +== 040 +UPDATE ONLY b SET aa='zzz' WHERE aa='aaa' +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: UpdateStmt +== 041 +UPDATE a SET aa='zzzzzz' WHERE aa LIKE 'aaa%' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +== 042 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 043 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 044 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 045 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 046 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 047 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 048 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 049 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 050 +UPDATE b SET aa='new' +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: UpdateStmt +== 051 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 052 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 053 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 054 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 055 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 056 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 057 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 058 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 059 +UPDATE a SET aa='new' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +== 060 +DELETE FROM ONLY c WHERE aa='new' +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: DeleteStmt +== 061 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 062 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 063 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 064 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 065 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 066 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 067 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 068 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 069 +DELETE FROM a +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: DeleteStmt +== 070 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 071 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 072 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 073 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 074 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 075 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 076 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 077 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +== 078 +-- Confirm PRIMARY KEY adds NOT NULL constraint to child table +CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a) +-- +TABLE: name="z" schema="" table="z" ctx=DDL +STMT: CreateStmt +== 079 +INSERT INTO z VALUES (NULL, 'text') +-- +TABLE: name="z" schema="" table="z" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +-- should fail + +-- Check inherited UPDATE with first child excluded +create table some_tab (f1 int, f2 int, f3 int, check (f1 < 10) no inherit) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateStmt +== 081 +create table some_tab_child () inherits(some_tab) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: CreateStmt +== 082 +insert into some_tab_child select i, i+1, 0 from generate_series(1,1000) i +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 083 +create index on some_tab_child(f1, f2) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: IndexStmt +== 084 +-- while at it, also check that statement-level triggers fire +create function some_tab_stmt_trig_func() returns trigger as +$$begin raise notice 'updating some_tab'; return NULL; end;$$ +language plpgsql +-- +FUNCTION: name="some_tab_stmt_trig_func" function="some_tab_stmt_trig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 085 +create trigger some_tab_stmt_trig + before update on some_tab execute function some_tab_stmt_trig_func() +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateTrigStmt +== 086 +explain (costs off) +update some_tab set f3 = 11 where f1 = 12 and f2 = 13 +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 087 +update some_tab set f3 = 11 where f1 = 12 and f2 = 13 +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: UpdateStmt +== 088 +drop table some_tab cascade +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: DropStmt +== 089 +drop function some_tab_stmt_trig_func() +-- +FUNCTION: name="some_tab_stmt_trig_func" function="some_tab_stmt_trig_func" schema="" ctx=DDL +STMT: DropStmt +== 090 +-- Check inherited UPDATE with all children excluded +create table some_tab (a int, b int) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateStmt +== 091 +create table some_tab_child () inherits (some_tab) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: CreateStmt +== 092 +insert into some_tab_child values(1,2) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +explain (verbose, costs off) +update some_tab set a = a + 1 where false +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 094 +update some_tab set a = a + 1 where false +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: UpdateStmt +== 095 +explain (verbose, costs off) +update some_tab set a = a + 1 where false returning b, a +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 096 +update some_tab set a = a + 1 where false returning b, a +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: UpdateStmt +== 097 +table some_tab +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +STMT: SelectStmt +== 098 +drop table some_tab cascade +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: DropStmt +== 099 +-- Check UPDATE with inherited target and an inherited source table +create temp table foo(f1 int, f2 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 100 +create temp table foo2(f3 int) inherits (foo) +-- +TABLE: name="foo2" schema="" table="foo2" ctx=DDL +STMT: CreateStmt +== 101 +create temp table bar(f1 int, f2 int) +-- +TABLE: name="bar" schema="" table="bar" ctx=DDL +STMT: CreateStmt +== 102 +create temp table bar2(f3 int) inherits (bar) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DDL +STMT: CreateStmt +== 103 +insert into foo values(1,1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +insert into foo values(3,3) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +insert into foo2 values(2,2,2) +-- +TABLE: name="foo2" schema="" table="foo2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 106 +insert into foo2 values(3,3,3) +-- +TABLE: name="foo2" schema="" table="foo2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +insert into bar values(1,1) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +insert into bar values(2,2) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +insert into bar values(3,3) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +insert into bar values(4,4) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +insert into bar2 values(1,1,1) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +insert into bar2 values(2,2,2) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 113 +insert into bar2 values(3,3,3) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 114 +insert into bar2 values(4,4,4) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +update bar set f2 = f2 + 100 where f1 in (select f1 from foo) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +== 116 +select tableoid::regclass::text as relname, bar.* from bar order by 1,2 +-- +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: SelectStmt +== 117 +-- Check UPDATE with inherited target and an appendrel subquery +update bar set f2 = f2 + 100 +from + ( select f1 from foo union all select f1+3 from foo ) ss +where bar.f1 = ss.f1 +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +== 118 +select tableoid::regclass::text as relname, bar.* from bar order by 1,2 +-- +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: SelectStmt +== 119 +-- Check UPDATE with *partitioned* inherited target and an appendrel subquery +create table some_tab (a int) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateStmt +== 120 +insert into some_tab values (0) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +create table some_tab_child () inherits (some_tab) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: CreateStmt +== 122 +insert into some_tab_child values (1) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +create table parted_tab (a int, b char) partition by list (a) +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DDL +STMT: CreateStmt +== 124 +create table parted_tab_part1 partition of parted_tab for values in (1) +-- +TABLE: name="parted_tab_part1" schema="" table="parted_tab_part1" ctx=DDL +STMT: CreateStmt +== 125 +create table parted_tab_part2 partition of parted_tab for values in (2) +-- +TABLE: name="parted_tab_part2" schema="" table="parted_tab_part2" ctx=DDL +STMT: CreateStmt +== 126 +create table parted_tab_part3 partition of parted_tab for values in (3) +-- +TABLE: name="parted_tab_part3" schema="" table="parted_tab_part3" ctx=DDL +STMT: CreateStmt +== 127 +insert into parted_tab values (1, 'a'), (2, 'a'), (3, 'a') +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 128 +update parted_tab set b = 'b' +from + (select a from some_tab union all select a+1 from some_tab) ss (a) +where parted_tab.a = ss.a +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +== 129 +select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2 +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +STMT: SelectStmt +== 130 +truncate parted_tab +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DDL +STMT: TruncateStmt +== 131 +insert into parted_tab values (1, 'a'), (2, 'a'), (3, 'a') +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 132 +update parted_tab set b = 'b' +from + (select 0 from parted_tab union all select 1 from parted_tab) ss (a) +where parted_tab.a = ss.a +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +== 133 +select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2 +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +STMT: SelectStmt +== 134 +-- modifies partition key, but no rows will actually be updated +explain update parted_tab set a = 2 where false +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 135 +drop table parted_tab +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DDL +STMT: DropStmt +== 136 +-- Check UPDATE with multi-level partitioned inherited target +create table mlparted_tab (a int, b char, c text) partition by list (a) +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DDL +STMT: CreateStmt +== 137 +create table mlparted_tab_part1 partition of mlparted_tab for values in (1) +-- +TABLE: name="mlparted_tab_part1" schema="" table="mlparted_tab_part1" ctx=DDL +STMT: CreateStmt +== 138 +create table mlparted_tab_part2 partition of mlparted_tab for values in (2) partition by list (b) +-- +TABLE: name="mlparted_tab_part2" schema="" table="mlparted_tab_part2" ctx=DDL +STMT: CreateStmt +== 139 +create table mlparted_tab_part3 partition of mlparted_tab for values in (3) +-- +TABLE: name="mlparted_tab_part3" schema="" table="mlparted_tab_part3" ctx=DDL +STMT: CreateStmt +== 140 +create table mlparted_tab_part2a partition of mlparted_tab_part2 for values in ('a') +-- +TABLE: name="mlparted_tab_part2a" schema="" table="mlparted_tab_part2a" ctx=DDL +STMT: CreateStmt +== 141 +create table mlparted_tab_part2b partition of mlparted_tab_part2 for values in ('b') +-- +TABLE: name="mlparted_tab_part2b" schema="" table="mlparted_tab_part2b" ctx=DDL +STMT: CreateStmt +== 142 +insert into mlparted_tab values (1, 'a'), (2, 'a'), (2, 'b'), (3, 'a') +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +update mlparted_tab mlp set c = 'xxx' +from + (select a from some_tab union all select a+1 from some_tab) ss (a) +where (mlp.a = ss.a and mlp.b = 'b') or mlp.a = 3 +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DML +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +ALIAS: "mlp"="mlparted_tab" +STMT: UpdateStmt +STMT: SelectStmt +== 144 +select tableoid::regclass::text as relname, mlparted_tab.* from mlparted_tab order by 1,2 +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=Select +STMT: SelectStmt +== 145 +drop table mlparted_tab +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DDL +STMT: DropStmt +== 146 +drop table some_tab cascade +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: DropStmt +== 147 +/* Test multiple inheritance of column defaults */ + +CREATE TABLE firstparent (tomorrow date default now()::date + 1) +-- +TABLE: name="firstparent" schema="" table="firstparent" ctx=DDL +STMT: CreateStmt +== 148 +CREATE TABLE secondparent (tomorrow date default now() :: date + 1) +-- +TABLE: name="secondparent" schema="" table="secondparent" ctx=DDL +STMT: CreateStmt +== 149 +CREATE TABLE jointchild () INHERITS (firstparent, secondparent) +-- +TABLE: name="jointchild" schema="" table="jointchild" ctx=DDL +STMT: CreateStmt +== 150 +-- ok +CREATE TABLE thirdparent (tomorrow date default now()::date - 1) +-- +TABLE: name="thirdparent" schema="" table="thirdparent" ctx=DDL +STMT: CreateStmt +== 151 +CREATE TABLE otherchild () INHERITS (firstparent, thirdparent) +-- +TABLE: name="otherchild" schema="" table="otherchild" ctx=DDL +STMT: CreateStmt +== 152 +-- not ok +CREATE TABLE otherchild (tomorrow date default now()) + INHERITS (firstparent, thirdparent) +-- +TABLE: name="otherchild" schema="" table="otherchild" ctx=DDL +STMT: CreateStmt +== 153 +-- ok, child resolves ambiguous default + +DROP TABLE firstparent, secondparent, jointchild, thirdparent, otherchild +-- +TABLE: name="firstparent" schema="" table="firstparent" ctx=DDL +TABLE: name="secondparent" schema="" table="secondparent" ctx=DDL +TABLE: name="jointchild" schema="" table="jointchild" ctx=DDL +TABLE: name="thirdparent" schema="" table="thirdparent" ctx=DDL +TABLE: name="otherchild" schema="" table="otherchild" ctx=DDL +STMT: DropStmt +== 154 +-- Test changing the type of inherited columns +insert into d values('test','one','two','three') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +alter table a alter column aa type integer using bit_length(aa) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: AlterTableStmt +== 156 +select * from d +-- +TABLE: name="d" schema="" table="d" ctx=Select +STMT: SelectStmt +== 157 +-- The above verified that we can change the type of a multiply-inherited +-- column; but we should reject that if any definition was inherited from +-- an unrelated parent. +create temp table parent1(f1 int, f2 int) +-- +TABLE: name="parent1" schema="" table="parent1" ctx=DDL +STMT: CreateStmt +== 158 +create temp table parent2(f1 int, f3 bigint) +-- +TABLE: name="parent2" schema="" table="parent2" ctx=DDL +STMT: CreateStmt +== 159 +create temp table childtab(f4 int) inherits(parent1, parent2) +-- +TABLE: name="childtab" schema="" table="childtab" ctx=DDL +STMT: CreateStmt +== 160 +alter table parent1 alter column f1 type bigint +-- +TABLE: name="parent1" schema="" table="parent1" ctx=DDL +STMT: AlterTableStmt +== 161 +-- fail, conflict w/parent2 +alter table parent1 alter column f2 type bigint +-- +TABLE: name="parent1" schema="" table="parent1" ctx=DDL +STMT: AlterTableStmt +== 162 +-- ok + +-- Test non-inheritable parent constraints +create table p1(ff1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 163 +alter table p1 add constraint p1chk check (ff1 > 0) no inherit +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 164 +alter table p1 add constraint p2chk check (ff1 > 10) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 165 +-- connoinherit should be true for NO INHERIT constraint +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.connoinherit from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname = 'p1' order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 166 +-- Test that child does not inherit NO INHERIT constraints +create table c1 () inherits (p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 167 +-- Test that child does not override inheritable constraints of the parent +create table c2 (constraint p2chk check (ff1 > 10) no inherit) inherits (p1) +-- +TABLE: name="c2" schema="" table="c2" ctx=DDL +STMT: CreateStmt +== 168 +--fails + +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 169 +-- Tests for casting between the rowtypes of parent and child +-- tables. See the pgsql-hackers thread beginning Dec. 4/04 +create table base (i integer) +-- +TABLE: name="base" schema="" table="base" ctx=DDL +STMT: CreateStmt +== 170 +create table derived () inherits (base) +-- +TABLE: name="derived" schema="" table="derived" ctx=DDL +STMT: CreateStmt +== 171 +create table more_derived (like derived, b int) inherits (derived) +-- +TABLE: name="more_derived" schema="" table="more_derived" ctx=DDL +STMT: CreateStmt +== 172 +insert into derived (i) values (0) +-- +TABLE: name="derived" schema="" table="derived" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +select derived::base from derived +-- +TABLE: name="derived" schema="" table="derived" ctx=Select +STMT: SelectStmt +== 174 +select NULL::derived::base +-- +STMT: SelectStmt +== 175 +-- remove redundant conversions. +explain (verbose on, costs off) select row(i, b)::more_derived::derived::base from more_derived +-- +TABLE: name="more_derived" schema="" table="more_derived" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 176 +explain (verbose on, costs off) select (1, 2)::more_derived::derived::base +-- +STMT: ExplainStmt +STMT: SelectStmt +== 177 +drop table more_derived +-- +TABLE: name="more_derived" schema="" table="more_derived" ctx=DDL +STMT: DropStmt +== 178 +drop table derived +-- +TABLE: name="derived" schema="" table="derived" ctx=DDL +STMT: DropStmt +== 179 +drop table base +-- +TABLE: name="base" schema="" table="base" ctx=DDL +STMT: DropStmt +== 180 +create table p1(ff1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 181 +create table p2(f1 text) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +== 182 +create function p2text(p2) returns text as 'select $1.f1' language sql +-- +FUNCTION: name="p2text" function="p2text" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 183 +create table c1(f3 int) inherits(p1,p2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 184 +insert into c1 values(123456789, 'hi', 42) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +select p2text(c1.*) from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +FUNCTION: name="p2text" function="p2text" schema="" ctx=Call +STMT: SelectStmt +== 186 +drop function p2text(p2) +-- +FUNCTION: name="p2text" function="p2text" schema="" ctx=DDL +STMT: DropStmt +== 187 +drop table c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: DropStmt +== 188 +drop table p2 +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +== 189 +drop table p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 190 +CREATE TABLE ac (aa TEXT) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: CreateStmt +== 191 +alter table ac add constraint ac_check check (aa is not null) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +== 192 +CREATE TABLE bc (bb TEXT) INHERITS (ac) +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: CreateStmt +== 193 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 194 +insert into ac (aa) values (NULL) +-- +TABLE: name="ac" schema="" table="ac" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 195 +insert into bc (aa) values (NULL) +-- +TABLE: name="bc" schema="" table="bc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +alter table bc drop constraint ac_check +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +== 197 +-- fail, disallowed +alter table ac drop constraint ac_check +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +== 198 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 199 +-- try the unnamed-constraint case +alter table ac add check (aa is not null) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +== 200 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 201 +insert into ac (aa) values (NULL) +-- +TABLE: name="ac" schema="" table="ac" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +insert into bc (aa) values (NULL) +-- +TABLE: name="bc" schema="" table="bc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +alter table bc drop constraint ac_aa_check +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +== 204 +-- fail, disallowed +alter table ac drop constraint ac_aa_check +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +== 205 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 206 +alter table ac add constraint ac_check check (aa is not null) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +== 207 +alter table bc no inherit ac +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +== 208 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 209 +alter table bc drop constraint ac_check +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +== 210 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 211 +alter table ac drop constraint ac_check +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +== 212 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 213 +drop table bc +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: DropStmt +== 214 +drop table ac +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: DropStmt +== 215 +create table ac (a int constraint check_a check (a <> 0)) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: CreateStmt +== 216 +create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac) +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: CreateStmt +== 217 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 218 +drop table bc +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: DropStmt +== 219 +drop table ac +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: DropStmt +== 220 +create table ac (a int constraint check_a check (a <> 0)) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: CreateStmt +== 221 +create table bc (b int constraint check_b check (b <> 0)) +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: CreateStmt +== 222 +create table cc (c int constraint check_c check (c <> 0)) inherits (ac, bc) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +== 223 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 224 +alter table cc no inherit bc +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: AlterTableStmt +== 225 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +== 226 +drop table cc +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: DropStmt +== 227 +drop table bc +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: DropStmt +== 228 +drop table ac +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: DropStmt +== 229 +create table p1(f1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 230 +create table p2(f2 int) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +== 231 +create table c1(f3 int) inherits(p1,p2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +== 232 +insert into c1 values(1,-1,2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 233 +alter table p2 add constraint cc check (f2>0) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +== 234 +-- fail +alter table p2 add check (f2>0) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +== 235 +-- check it without a name, too +delete from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: DeleteStmt +== 236 +insert into c1 values(1,1,2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 237 +alter table p2 add check (f2>0) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +== 238 +insert into c1 values(1,-1,2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 239 +-- fail +create table c2(f3 int) inherits(p1,p2) +-- +TABLE: name="c2" schema="" table="c2" ctx=DDL +STMT: CreateStmt +== 240 +create table c3 (f4 int) inherits(c1,c2) +-- +TABLE: name="c3" schema="" table="c3" ctx=DDL +STMT: CreateStmt +== 241 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 242 +drop table p2 cascade +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +== 243 +create table pp1 (f1 int) +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: CreateStmt +== 244 +create table cc1 (f2 text, f3 int) inherits (pp1) +-- +TABLE: name="cc1" schema="" table="cc1" ctx=DDL +STMT: CreateStmt +== 245 +alter table pp1 add column a1 int check (a1 > 0) +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: AlterTableStmt +== 246 +create table cc2(f4 float) inherits(pp1,cc1) +-- +TABLE: name="cc2" schema="" table="cc2" ctx=DDL +STMT: CreateStmt +== 247 +alter table pp1 add column a2 int check (a2 > 0) +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: AlterTableStmt +== 248 +drop table pp1 cascade +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: DropStmt +== 249 +-- Test for renaming in simple multiple inheritance +CREATE TABLE inht1 (a int, b int) +-- +TABLE: name="inht1" schema="" table="inht1" ctx=DDL +STMT: CreateStmt +== 250 +CREATE TABLE inhs1 (b int, c int) +-- +TABLE: name="inhs1" schema="" table="inhs1" ctx=DDL +STMT: CreateStmt +== 251 +CREATE TABLE inhts (d int) INHERITS (inht1, inhs1) +-- +TABLE: name="inhts" schema="" table="inhts" ctx=DDL +STMT: CreateStmt +== 252 +ALTER TABLE inht1 RENAME a TO aa +-- +STMT: RenameStmt +== 253 +ALTER TABLE inht1 RENAME b TO bb +-- +STMT: RenameStmt +== 254 +-- to be failed +ALTER TABLE inhts RENAME aa TO aaa +-- +STMT: RenameStmt +== 255 +-- to be failed +ALTER TABLE inhts RENAME d TO dd +-- +STMT: RenameStmt +== 256 +DROP TABLE inhts +-- +TABLE: name="inhts" schema="" table="inhts" ctx=DDL +STMT: DropStmt +== 257 +-- Test for adding a column to a parent table with complex inheritance +CREATE TABLE inhta () +-- +TABLE: name="inhta" schema="" table="inhta" ctx=DDL +STMT: CreateStmt +== 258 +CREATE TABLE inhtb () INHERITS (inhta) +-- +TABLE: name="inhtb" schema="" table="inhtb" ctx=DDL +STMT: CreateStmt +== 259 +CREATE TABLE inhtc () INHERITS (inhtb) +-- +TABLE: name="inhtc" schema="" table="inhtc" ctx=DDL +STMT: CreateStmt +== 260 +CREATE TABLE inhtd () INHERITS (inhta, inhtb, inhtc) +-- +TABLE: name="inhtd" schema="" table="inhtd" ctx=DDL +STMT: CreateStmt +== 261 +ALTER TABLE inhta ADD COLUMN i int, ADD COLUMN j bigint DEFAULT 1 +-- +TABLE: name="inhta" schema="" table="inhta" ctx=DDL +STMT: AlterTableStmt +== 262 +DROP TABLE inhta, inhtb, inhtc, inhtd +-- +TABLE: name="inhta" schema="" table="inhta" ctx=DDL +TABLE: name="inhtb" schema="" table="inhtb" ctx=DDL +TABLE: name="inhtc" schema="" table="inhtc" ctx=DDL +TABLE: name="inhtd" schema="" table="inhtd" ctx=DDL +STMT: DropStmt +== 263 +-- Test for renaming in diamond inheritance +CREATE TABLE inht2 (x int) INHERITS (inht1) +-- +TABLE: name="inht2" schema="" table="inht2" ctx=DDL +STMT: CreateStmt +== 264 +CREATE TABLE inht3 (y int) INHERITS (inht1) +-- +TABLE: name="inht3" schema="" table="inht3" ctx=DDL +STMT: CreateStmt +== 265 +CREATE TABLE inht4 (z int) INHERITS (inht2, inht3) +-- +TABLE: name="inht4" schema="" table="inht4" ctx=DDL +STMT: CreateStmt +== 266 +ALTER TABLE inht1 RENAME aa TO aaa +-- +STMT: RenameStmt +== 267 +CREATE TABLE inhts (d int) INHERITS (inht2, inhs1) +-- +TABLE: name="inhts" schema="" table="inhts" ctx=DDL +STMT: CreateStmt +== 268 +ALTER TABLE inht1 RENAME aaa TO aaaa +-- +STMT: RenameStmt +== 269 +ALTER TABLE inht1 RENAME b TO bb +-- +STMT: RenameStmt +== 270 +-- to be failed + +WITH RECURSIVE r AS ( + SELECT 'inht1'::regclass AS inhrelid +UNION ALL + SELECT c.inhrelid FROM pg_inherits c, r WHERE r.inhrelid = c.inhparent +) +SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected + FROM (SELECT inhrelid, count(*) AS expected FROM pg_inherits + WHERE inhparent IN (SELECT inhrelid FROM r) GROUP BY inhrelid) e + JOIN pg_attribute a ON e.inhrelid = a.attrelid WHERE NOT attislocal + ORDER BY a.attrelid::regclass::name, a.attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_inherits" +CTE: "r" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="attislocal" +FILTER: schema="" table="" column="inhparent" +FILTER: schema="" table="r" column="inhrelid" +FILTER: schema="" table="c" column="inhparent" +STMT: SelectStmt +== 271 +DROP TABLE inht1, inhs1 CASCADE +-- +TABLE: name="inht1" schema="" table="inht1" ctx=DDL +TABLE: name="inhs1" schema="" table="inhs1" ctx=DDL +STMT: DropStmt +== 272 +-- Test non-inheritable indices [UNIQUE, EXCLUDE] constraints +CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE(val1, val2)) +-- +TABLE: name="test_constraints" schema="" table="test_constraints" ctx=DDL +STMT: CreateStmt +== 273 +CREATE TABLE test_constraints_inh () INHERITS (test_constraints) +-- +TABLE: name="test_constraints_inh" schema="" table="test_constraints_inh" ctx=DDL +STMT: CreateStmt +== 274 +ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key +-- +TABLE: name="test_constraints" schema="" table="test_constraints" ctx=DDL +STMT: AlterTableStmt +== 275 +DROP TABLE test_constraints_inh +-- +TABLE: name="test_constraints_inh" schema="" table="test_constraints_inh" ctx=DDL +STMT: DropStmt +== 276 +DROP TABLE test_constraints +-- +TABLE: name="test_constraints" schema="" table="test_constraints" ctx=DDL +STMT: DropStmt +== 277 +CREATE TABLE test_ex_constraints ( + c circle, + EXCLUDE USING gist (c WITH &&) +) +-- +TABLE: name="test_ex_constraints" schema="" table="test_ex_constraints" ctx=DDL +STMT: CreateStmt +== 278 +CREATE TABLE test_ex_constraints_inh () INHERITS (test_ex_constraints) +-- +TABLE: name="test_ex_constraints_inh" schema="" table="test_ex_constraints_inh" ctx=DDL +STMT: CreateStmt +== 279 +ALTER TABLE test_ex_constraints DROP CONSTRAINT test_ex_constraints_c_excl +-- +TABLE: name="test_ex_constraints" schema="" table="test_ex_constraints" ctx=DDL +STMT: AlterTableStmt +== 280 +DROP TABLE test_ex_constraints_inh +-- +TABLE: name="test_ex_constraints_inh" schema="" table="test_ex_constraints_inh" ctx=DDL +STMT: DropStmt +== 281 +DROP TABLE test_ex_constraints +-- +TABLE: name="test_ex_constraints" schema="" table="test_ex_constraints" ctx=DDL +STMT: DropStmt +== 282 +-- Test non-inheritable foreign key constraints +CREATE TABLE test_primary_constraints(id int PRIMARY KEY) +-- +TABLE: name="test_primary_constraints" schema="" table="test_primary_constraints" ctx=DDL +STMT: CreateStmt +== 283 +CREATE TABLE test_foreign_constraints(id1 int REFERENCES test_primary_constraints(id)) +-- +TABLE: name="test_foreign_constraints" schema="" table="test_foreign_constraints" ctx=DDL +STMT: CreateStmt +== 284 +CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints) +-- +TABLE: name="test_foreign_constraints_inh" schema="" table="test_foreign_constraints_inh" ctx=DDL +STMT: CreateStmt +== 285 +ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey +-- +TABLE: name="test_foreign_constraints" schema="" table="test_foreign_constraints" ctx=DDL +STMT: AlterTableStmt +== 286 +DROP TABLE test_foreign_constraints_inh +-- +TABLE: name="test_foreign_constraints_inh" schema="" table="test_foreign_constraints_inh" ctx=DDL +STMT: DropStmt +== 287 +DROP TABLE test_foreign_constraints +-- +TABLE: name="test_foreign_constraints" schema="" table="test_foreign_constraints" ctx=DDL +STMT: DropStmt +== 288 +DROP TABLE test_primary_constraints +-- +TABLE: name="test_primary_constraints" schema="" table="test_primary_constraints" ctx=DDL +STMT: DropStmt +== 289 +-- Test foreign key behavior +create table inh_fk_1 (a int primary key) +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DDL +STMT: CreateStmt +== 290 +insert into inh_fk_1 values (1), (2), (3) +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 291 +create table inh_fk_2 (x int primary key, y int references inh_fk_1 on delete cascade) +-- +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=DDL +STMT: CreateStmt +== 292 +insert into inh_fk_2 values (11, 1), (22, 2), (33, 3) +-- +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +create table inh_fk_2_child () inherits (inh_fk_2) +-- +TABLE: name="inh_fk_2_child" schema="" table="inh_fk_2_child" ctx=DDL +STMT: CreateStmt +== 294 +insert into inh_fk_2_child values (111, 1), (222, 2) +-- +TABLE: name="inh_fk_2_child" schema="" table="inh_fk_2_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 295 +delete from inh_fk_1 where a = 1 +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DML +STMT: DeleteStmt +== 296 +select * from inh_fk_1 order by 1 +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=Select +STMT: SelectStmt +== 297 +select * from inh_fk_2 order by 1, 2 +-- +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=Select +STMT: SelectStmt +== 298 +drop table inh_fk_1, inh_fk_2, inh_fk_2_child +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DDL +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=DDL +TABLE: name="inh_fk_2_child" schema="" table="inh_fk_2_child" ctx=DDL +STMT: DropStmt +== 299 +-- Test that parent and child CHECK constraints can be created in either order +create table p1(f1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 300 +create table p1_c1() inherits(p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +== 301 +alter table p1 add constraint inh_check_constraint1 check (f1 > 0) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 302 +alter table p1_c1 add constraint inh_check_constraint1 check (f1 > 0) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: AlterTableStmt +== 303 +alter table p1_c1 add constraint inh_check_constraint2 check (f1 < 10) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: AlterTableStmt +== 304 +alter table p1 add constraint inh_check_constraint2 check (f1 < 10) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 305 +select conrelid::regclass::text as relname, conname, conislocal, coninhcount +from pg_constraint where conname like 'inh\_check\_constraint%' +order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 306 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 307 +|-- +-- Test DROP behavior of multiply-defined CHECK constraints +|-- +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 308 +create table p1_c1 (f1 int constraint f1_pos CHECK (f1 > 0)) inherits (p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +== 309 +alter table p1_c1 drop constraint f1_pos +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: AlterTableStmt +== 310 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 311 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 312 +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 313 +create table p2(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +== 314 +create table p1p2_c1 (f1 int) inherits (p1, p2) +-- +TABLE: name="p1p2_c1" schema="" table="p1p2_c1" ctx=DDL +STMT: CreateStmt +== 315 +create table p1p2_c2 (f1 int constraint f1_pos CHECK (f1 > 0)) inherits (p1, p2) +-- +TABLE: name="p1p2_c2" schema="" table="p1p2_c2" ctx=DDL +STMT: CreateStmt +== 316 +alter table p2 drop constraint f1_pos +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +== 317 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 318 +drop table p1, p2 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +== 319 +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 320 +create table p1_c1() inherits (p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +== 321 +create table p1_c2() inherits (p1) +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: CreateStmt +== 322 +create table p1_c1c2() inherits (p1_c1, p1_c2) +-- +TABLE: name="p1_c1c2" schema="" table="p1_c1c2" ctx=DDL +STMT: CreateStmt +== 323 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 324 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 325 +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 326 +create table p1_c1() inherits (p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +== 327 +create table p1_c2(constraint f1_pos CHECK (f1 > 0)) inherits (p1) +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: CreateStmt +== 328 +create table p1_c1c2() inherits (p1_c1, p1_c2, p1) +-- +TABLE: name="p1_c1c2" schema="" table="p1_c1c2" ctx=DDL +STMT: CreateStmt +== 329 +alter table p1_c2 drop constraint f1_pos +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: AlterTableStmt +== 330 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +== 331 +alter table p1_c1c2 drop constraint f1_pos +-- +TABLE: name="p1_c1c2" schema="" table="p1_c1c2" ctx=DDL +STMT: AlterTableStmt +== 332 +alter table p1_c2 drop constraint f1_pos +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: AlterTableStmt +== 333 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +== 334 +-- Test that a valid child can have not-valid parent, but not vice versa +create table invalid_check_con(f1 int) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DDL +STMT: CreateStmt +== 335 +create table invalid_check_con_child() inherits(invalid_check_con) +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: CreateStmt +== 336 +alter table invalid_check_con_child add constraint inh_check_constraint check(f1 > 0) not valid +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: AlterTableStmt +== 337 +alter table invalid_check_con add constraint inh_check_constraint check(f1 > 0) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DDL +STMT: AlterTableStmt +== 338 +-- fail +alter table invalid_check_con_child drop constraint inh_check_constraint +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: AlterTableStmt +== 339 +insert into invalid_check_con values(0) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 340 +alter table invalid_check_con_child add constraint inh_check_constraint check(f1 > 0) +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: AlterTableStmt +== 341 +alter table invalid_check_con add constraint inh_check_constraint check(f1 > 0) not valid +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DDL +STMT: AlterTableStmt +== 342 +insert into invalid_check_con values(0) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 343 +-- fail +insert into invalid_check_con_child values(0) +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 344 +-- fail + +select conrelid::regclass::text as relname, conname, + convalidated, conislocal, coninhcount, connoinherit +from pg_constraint where conname like 'inh\_check\_constraint%' +order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +== 345 +-- We don't drop the invalid_check_con* tables, to test dump/reload with + +|-- +-- Test parameterized append plans for inheritance trees +|-- + +create temp table patest0 (id, x) as + select x, x from generate_series(0,1000) x +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 346 +create temp table patest1() inherits (patest0) +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DDL +STMT: CreateStmt +== 347 +insert into patest1 + select x, x from generate_series(0,1000) x +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 348 +create temp table patest2() inherits (patest0) +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DDL +STMT: CreateStmt +== 349 +insert into patest2 + select x, x from generate_series(0,1000) x +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 350 +create index patest0i on patest0(id) +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +STMT: IndexStmt +== 351 +create index patest1i on patest1(id) +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DDL +STMT: IndexStmt +== 352 +create index patest2i on patest2(id) +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DDL +STMT: IndexStmt +== 353 +analyze patest0 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +STMT: VacuumStmt +== 354 +analyze patest1 +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DDL +STMT: VacuumStmt +== 355 +analyze patest2 +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DDL +STMT: VacuumStmt +== 356 +explain (costs off) +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 357 +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 358 +drop index patest2i +-- +STMT: DropStmt +== 359 +explain (costs off) +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 360 +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 361 +drop table patest0 cascade +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +STMT: DropStmt +== 362 +|-- +-- Test merge-append plans for inheritance trees +|-- + +create table matest0 (id serial primary key, name text) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: CreateStmt +== 363 +create table matest1 (id integer primary key) inherits (matest0) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: CreateStmt +== 364 +create table matest2 (id integer primary key) inherits (matest0) +-- +TABLE: name="matest2" schema="" table="matest2" ctx=DDL +STMT: CreateStmt +== 365 +create table matest3 (id integer primary key) inherits (matest0) +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DDL +STMT: CreateStmt +== 366 +create index matest0i on matest0 ((1-id)) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: IndexStmt +== 367 +create index matest1i on matest1 ((1-id)) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: IndexStmt +== 368 +-- create index matest2i on matest2 ((1-id)); -- intentionally missing +create index matest3i on matest3 ((1-id)) +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DDL +STMT: IndexStmt +== 369 +insert into matest1 (name) values ('Test 1') +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 370 +insert into matest1 (name) values ('Test 2') +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 371 +insert into matest2 (name) values ('Test 3') +-- +TABLE: name="matest2" schema="" table="matest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 372 +insert into matest2 (name) values ('Test 4') +-- +TABLE: name="matest2" schema="" table="matest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 373 +insert into matest3 (name) values ('Test 5') +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 374 +insert into matest3 (name) values ('Test 6') +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 375 +set enable_indexscan = off +-- +STMT: VariableSetStmt +== 376 +-- force use of seqscan/sort, so no merge +explain (verbose, costs off) select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 377 +select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: SelectStmt +== 378 +explain (verbose, costs off) select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 379 +select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 380 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 381 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 382 +-- plan with fewest seqscans should be merge +set enable_parallel_append = off +-- +STMT: VariableSetStmt +== 383 +-- Don't let parallel-append interfere +explain (verbose, costs off) select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 384 +select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: SelectStmt +== 385 +explain (verbose, costs off) select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 386 +select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 387 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 388 +reset enable_parallel_append +-- +STMT: VariableSetStmt +== 389 +explain (verbose, costs off) -- bug #18652 +select 1 - id as c from +(select id from matest3 t1 union all select id * 2 from matest3 t2) ss +order by c +-- +TABLE: name="matest3" schema="" table="matest3" ctx=Select +TABLE: name="matest3" schema="" table="matest3" ctx=Select +ALIAS: "t1"="matest3" +ALIAS: "t2"="matest3" +STMT: ExplainStmt +STMT: SelectStmt +== 390 +select 1 - id as c from +(select id from matest3 t1 union all select id * 2 from matest3 t2) ss +order by c +-- +TABLE: name="matest3" schema="" table="matest3" ctx=Select +TABLE: name="matest3" schema="" table="matest3" ctx=Select +ALIAS: "t1"="matest3" +ALIAS: "t2"="matest3" +STMT: SelectStmt +== 391 +drop table matest0 cascade +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: DropStmt +== 392 +|-- +-- 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) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: CreateStmt +== 393 +create table matest1 () inherits(matest0) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: CreateStmt +== 394 +create index matest0i on matest0 (b, c) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: IndexStmt +== 395 +create index matest1i on matest1 (b, c) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: IndexStmt +== 396 +set enable_nestloop = off +-- +STMT: VariableSetStmt +== 397 +-- 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 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +TABLE: name="matest0" schema="" table="matest0" ctx=Select +ALIAS: "t1"="matest0" +ALIAS: "t2"="matest0" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t2" column="d" +STMT: ExplainStmt +STMT: SelectStmt +== 398 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 399 +drop table matest0 cascade +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: DropStmt +== 400 +-- Test a MergeAppend plan where one child requires a sort +create table matest0(a int primary key) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: CreateStmt +== 401 +create table matest1() inherits (matest0) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: CreateStmt +== 402 +insert into matest0 select generate_series(1, 400) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 403 +insert into matest1 select generate_series(1, 200) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 404 +analyze matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: VacuumStmt +== 405 +analyze matest1 +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: VacuumStmt +== 406 +explain (costs off) +select * from matest0 where a < 100 order by a +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 407 +drop table matest0 cascade +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: DropStmt +== 408 +|-- +-- Test merge-append for UNION ALL append relations +|-- + +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 409 +set enable_indexscan = on +-- +STMT: VariableSetStmt +== 410 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +== 411 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 412 +explain (costs off) +SELECT thousand, tenthous, thousand+tenthous AS x FROM tenk1 +UNION ALL +SELECT 42, 42, hundred FROM tenk1 +ORDER BY thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 413 +explain (costs off) +SELECT thousand, tenthous FROM tenk1 +UNION ALL +SELECT thousand, random()::integer FROM tenk1 +ORDER BY thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 414 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 415 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 416 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 417 +-- 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) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 418 +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) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 419 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 420 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 421 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 422 +|-- +-- Check handling of MULTIEXPR SubPlans in inherited updates +|-- +create table inhpar(f1 int, f2 name) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: CreateStmt +== 423 +create table inhcld(f2 name, f1 int) +-- +TABLE: name="inhcld" schema="" table="inhcld" ctx=DDL +STMT: CreateStmt +== 424 +alter table inhcld inherit inhpar +-- +TABLE: name="inhcld" schema="" table="inhcld" ctx=DDL +STMT: AlterTableStmt +== 425 +insert into inhpar select x, x::text from generate_series(1,5) x +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 426 +insert into inhcld select x::text, x from generate_series(6,10) x +-- +TABLE: name="inhcld" schema="" table="inhcld" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 427 +explain (verbose, costs off) +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +== 428 +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: UpdateStmt +STMT: SelectStmt +== 429 +select * from inhpar +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=Select +STMT: SelectStmt +== 430 +drop table inhpar cascade +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: DropStmt +== 431 +|-- +-- And the same for partitioned cases +|-- +create table inhpar(f1 int primary key, f2 name) partition by range (f1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: CreateStmt +== 432 +create table inhcld1(f2 name, f1 int primary key) +-- +TABLE: name="inhcld1" schema="" table="inhcld1" ctx=DDL +STMT: CreateStmt +== 433 +create table inhcld2(f1 int primary key, f2 name) +-- +TABLE: name="inhcld2" schema="" table="inhcld2" ctx=DDL +STMT: CreateStmt +== 434 +alter table inhpar attach partition inhcld1 for values from (1) to (5) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: AlterTableStmt +== 435 +alter table inhpar attach partition inhcld2 for values from (5) to (100) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: AlterTableStmt +== 436 +insert into inhpar select x, x::text from generate_series(1,10) x +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 437 +explain (verbose, costs off) +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +== 438 +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: UpdateStmt +STMT: SelectStmt +== 439 +select * from inhpar +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=Select +STMT: SelectStmt +== 440 +-- Also check ON CONFLICT +insert into inhpar as i values (3), (7) on conflict (f1) + do update set (f1, f2) = (select i.f1, i.f2 || '+') +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +ALIAS: "i"="inhpar" +STMT: InsertStmt +STMT: SelectStmt +== 441 +select * from inhpar order by f1 +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=Select +STMT: SelectStmt +== 442 +-- tuple order might be unstable here + +drop table inhpar cascade +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: DropStmt +== 443 +|-- +-- Check handling of a constant-null CHECK constraint +|-- +create table cnullparent (f1 int) +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=DDL +STMT: CreateStmt +== 444 +create table cnullchild (check (f1 = 1 or f1 = null)) inherits(cnullparent) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DDL +STMT: CreateStmt +== 445 +insert into cnullchild values(1) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 446 +insert into cnullchild values(2) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 447 +insert into cnullchild values(null) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 448 +select * from cnullparent +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=Select +STMT: SelectStmt +== 449 +select * from cnullparent where f1 = 2 +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 450 +drop table cnullparent cascade +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=DDL +STMT: DropStmt +== 451 +|-- +-- Mixed ownership inheritance tree +|-- +create role regress_alice +-- +STMT: CreateRoleStmt +== 452 +create role regress_bob +-- +STMT: CreateRoleStmt +== 453 +grant all on schema public to regress_alice, regress_bob +-- +STMT: GrantStmt +== 454 +grant regress_alice to regress_bob +-- +STMT: GrantRoleStmt +== 455 +set session authorization regress_alice +-- +STMT: VariableSetStmt +== 456 +create table inh_parent (a int not null) +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +STMT: CreateStmt +== 457 +set session authorization regress_bob +-- +STMT: VariableSetStmt +== 458 +create table inh_child () inherits (inh_parent) +-- +TABLE: name="inh_child" schema="" table="inh_child" ctx=DDL +STMT: CreateStmt +== 459 +set session authorization regress_alice +-- +STMT: VariableSetStmt +== 460 +-- alice can't do this: she doesn't own inh_child +alter table inh_parent alter a drop not null +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +STMT: AlterTableStmt +== 461 +set session authorization regress_bob +-- +STMT: VariableSetStmt +== 462 +alter table inh_parent alter a drop not null +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +STMT: AlterTableStmt +== 463 +reset session authorization +-- +STMT: VariableSetStmt +== 464 +drop table inh_parent, inh_child +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +TABLE: name="inh_child" schema="" table="inh_child" ctx=DDL +STMT: DropStmt +== 465 +revoke all on schema public from regress_alice, regress_bob +-- +STMT: GrantStmt +== 466 +drop role regress_alice, regress_bob +-- +STMT: DropRoleStmt +== 467 +|-- +-- Check use of temporary tables with inheritance trees +|-- +create table inh_perm_parent (a1 int) +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=DDL +STMT: CreateStmt +== 468 +create temp table inh_temp_parent (a1 int) +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=DDL +STMT: CreateStmt +== 469 +create temp table inh_temp_child () inherits (inh_perm_parent) +-- +TABLE: name="inh_temp_child" schema="" table="inh_temp_child" ctx=DDL +STMT: CreateStmt +== 470 +-- ok +create table inh_perm_child () inherits (inh_temp_parent) +-- +TABLE: name="inh_perm_child" schema="" table="inh_perm_child" ctx=DDL +STMT: CreateStmt +== 471 +-- error +create temp table inh_temp_child_2 () inherits (inh_temp_parent) +-- +TABLE: name="inh_temp_child_2" schema="" table="inh_temp_child_2" ctx=DDL +STMT: CreateStmt +== 472 +-- ok +insert into inh_perm_parent values (1) +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 473 +insert into inh_temp_parent values (2) +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 474 +insert into inh_temp_child values (3) +-- +TABLE: name="inh_temp_child" schema="" table="inh_temp_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 475 +insert into inh_temp_child_2 values (4) +-- +TABLE: name="inh_temp_child_2" schema="" table="inh_temp_child_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 476 +select tableoid::regclass, a1 from inh_perm_parent +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=Select +STMT: SelectStmt +== 477 +select tableoid::regclass, a1 from inh_temp_parent +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=Select +STMT: SelectStmt +== 478 +drop table inh_perm_parent cascade +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=DDL +STMT: DropStmt +== 479 +drop table inh_temp_parent cascade +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=DDL +STMT: DropStmt +== 480 +|-- +-- 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) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +== 481 +create table part_ab_cd partition of list_parted for values in ('ab', 'cd') +-- +TABLE: name="part_ab_cd" schema="" table="part_ab_cd" ctx=DDL +STMT: CreateStmt +== 482 +create table part_ef_gh partition of list_parted for values in ('ef', 'gh') +-- +TABLE: name="part_ef_gh" schema="" table="part_ef_gh" ctx=DDL +STMT: CreateStmt +== 483 +create table part_null_xy partition of list_parted for values in (null, 'xy') +-- +TABLE: name="part_null_xy" schema="" table="part_null_xy" ctx=DDL +STMT: CreateStmt +== 484 +explain (costs off) select * from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 485 +explain (costs off) select * from list_parted where a is null +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 486 +explain (costs off) select * from list_parted where a is not null +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 487 +explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 488 +explain (costs off) select * from list_parted where a = 'ab' or a in (null, 'cd') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 489 +explain (costs off) select * from list_parted where a = 'ab' +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 490 +create table range_list_parted ( + a int, + b char(2) +) partition by range (a) +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=DDL +STMT: CreateStmt +== 491 +create table part_1_10 partition of range_list_parted for values from (1) to (10) partition by list (b) +-- +TABLE: name="part_1_10" schema="" table="part_1_10" ctx=DDL +STMT: CreateStmt +== 492 +create table part_1_10_ab partition of part_1_10 for values in ('ab') +-- +TABLE: name="part_1_10_ab" schema="" table="part_1_10_ab" ctx=DDL +STMT: CreateStmt +== 493 +create table part_1_10_cd partition of part_1_10 for values in ('cd') +-- +TABLE: name="part_1_10_cd" schema="" table="part_1_10_cd" ctx=DDL +STMT: CreateStmt +== 494 +create table part_10_20 partition of range_list_parted for values from (10) to (20) partition by list (b) +-- +TABLE: name="part_10_20" schema="" table="part_10_20" ctx=DDL +STMT: CreateStmt +== 495 +create table part_10_20_ab partition of part_10_20 for values in ('ab') +-- +TABLE: name="part_10_20_ab" schema="" table="part_10_20_ab" ctx=DDL +STMT: CreateStmt +== 496 +create table part_10_20_cd partition of part_10_20 for values in ('cd') +-- +TABLE: name="part_10_20_cd" schema="" table="part_10_20_cd" ctx=DDL +STMT: CreateStmt +== 497 +create table part_21_30 partition of range_list_parted for values from (21) to (30) partition by list (b) +-- +TABLE: name="part_21_30" schema="" table="part_21_30" ctx=DDL +STMT: CreateStmt +== 498 +create table part_21_30_ab partition of part_21_30 for values in ('ab') +-- +TABLE: name="part_21_30_ab" schema="" table="part_21_30_ab" ctx=DDL +STMT: CreateStmt +== 499 +create table part_21_30_cd partition of part_21_30 for values in ('cd') +-- +TABLE: name="part_21_30_cd" schema="" table="part_21_30_cd" ctx=DDL +STMT: CreateStmt +== 500 +create table part_40_inf partition of range_list_parted for values from (40) to (maxvalue) partition by list (b) +-- +TABLE: name="part_40_inf" schema="" table="part_40_inf" ctx=DDL +STMT: CreateStmt +== 501 +create table part_40_inf_ab partition of part_40_inf for values in ('ab') +-- +TABLE: name="part_40_inf_ab" schema="" table="part_40_inf_ab" ctx=DDL +STMT: CreateStmt +== 502 +create table part_40_inf_cd partition of part_40_inf for values in ('cd') +-- +TABLE: name="part_40_inf_cd" schema="" table="part_40_inf_cd" ctx=DDL +STMT: CreateStmt +== 503 +create table part_40_inf_null partition of part_40_inf for values in (null) +-- +TABLE: name="part_40_inf_null" schema="" table="part_40_inf_null" ctx=DDL +STMT: CreateStmt +== 504 +explain (costs off) select * from range_list_parted +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 505 +explain (costs off) select * from range_list_parted where a = 5 +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 506 +explain (costs off) select * from range_list_parted where b = 'ab' +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 507 +explain (costs off) select * from range_list_parted where a between 3 and 23 and b in ('ab') +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 508 +/* Should select no rows because range partition key cannot be null */ +explain (costs off) select * from range_list_parted where a is null +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 509 +/* Should only select rows from the null-accepting partition */ +explain (costs off) select * from range_list_parted where b is null +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 510 +explain (costs off) select * from range_list_parted where a is not null and a < 67 +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 511 +explain (costs off) select * from range_list_parted where a >= 30 +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 512 +drop table list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +== 513 +drop table range_list_parted +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=DDL +STMT: DropStmt +== 514 +-- 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) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: CreateStmt +== 515 +create table mcrparted_def partition of mcrparted default +-- +TABLE: name="mcrparted_def" schema="" table="mcrparted_def" ctx=DDL +STMT: CreateStmt +== 516 +create table mcrparted0 partition of mcrparted for values from (minvalue, minvalue, minvalue) to (1, 1, 1) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DDL +STMT: CreateStmt +== 517 +create table mcrparted1 partition of mcrparted for values from (1, 1, 1) to (10, 5, 10) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DDL +STMT: CreateStmt +== 518 +create table mcrparted2 partition of mcrparted for values from (10, 5, 10) to (10, 10, 10) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +STMT: CreateStmt +== 519 +create table mcrparted3 partition of mcrparted for values from (11, 1, 1) to (20, 10, 10) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DDL +STMT: CreateStmt +== 520 +create table mcrparted4 partition of mcrparted for values from (20, 10, 10) to (20, 20, 20) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +STMT: CreateStmt +== 521 +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: CreateStmt +== 522 +explain (costs off) select * from mcrparted where a = 0 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 523 +-- scans mcrparted0, mcrparted_def +explain (costs off) select * from mcrparted where a = 10 and abs(b) < 5 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 524 +-- scans mcrparted1, mcrparted_def +explain (costs off) select * from mcrparted where a = 10 and abs(b) = 5 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 525 +-- scans mcrparted1, mcrparted2, mcrparted_def +explain (costs off) select * from mcrparted where abs(b) = 5 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 526 +-- scans all partitions +explain (costs off) select * from mcrparted where a > -1 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 527 +-- scans all partitions +explain (costs off) select * from mcrparted where a = 20 and abs(b) = 10 and c > 10 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 528 +-- scans mcrparted4 +explain (costs off) select * from mcrparted where a = 20 and c > 20 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 529 +-- scans mcrparted3, mcrparte4, mcrparte5, mcrparted_def + +-- check that partitioned table Appends cope with being referenced in +-- subplans +create table parted_minmax (a int, b varchar(16)) partition by range (a) +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=DDL +STMT: CreateStmt +== 530 +create table parted_minmax1 partition of parted_minmax for values from (1) to (10) +-- +TABLE: name="parted_minmax1" schema="" table="parted_minmax1" ctx=DDL +STMT: CreateStmt +== 531 +create index parted_minmax1i on parted_minmax1 (a, b) +-- +TABLE: name="parted_minmax1" schema="" table="parted_minmax1" ctx=DDL +STMT: IndexStmt +== 532 +insert into parted_minmax values (1,'12345') +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 533 +explain (costs off) select min(a), max(a) from parted_minmax where b = '12345' +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 534 +select min(a), max(a) from parted_minmax where b = '12345' +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 535 +drop table parted_minmax +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=DDL +STMT: DropStmt +== 536 +-- 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) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 537 +-- MergeAppend must be used when a default partition exists +explain (costs off) select * from mcrparted order by a, abs(b), c +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 538 +drop table mcrparted_def +-- +TABLE: name="mcrparted_def" schema="" table="mcrparted_def" ctx=DDL +STMT: DropStmt +== 539 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 540 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 541 +-- check that Append plan is used containing a MergeAppend for sub-partitions +-- that are unordered. +drop table mcrparted5 +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: DropStmt +== 542 +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) partition by list (a) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: CreateStmt +== 543 +create table mcrparted5a partition of mcrparted5 for values in(20) +-- +TABLE: name="mcrparted5a" schema="" table="mcrparted5a" ctx=DDL +STMT: CreateStmt +== 544 +create table mcrparted5_def partition of mcrparted5 default +-- +TABLE: name="mcrparted5_def" schema="" table="mcrparted5_def" ctx=DDL +STMT: CreateStmt +== 545 +explain (costs off) select * from mcrparted order by a, abs(b), c +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 546 +drop table mcrparted5_def +-- +TABLE: name="mcrparted5_def" schema="" table="mcrparted5_def" ctx=DDL +STMT: DropStmt +== 547 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 548 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 549 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +== 550 +set enable_sort to off +-- +STMT: VariableSetStmt +== 551 +create table mclparted (a int) partition by list(a) +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=DDL +STMT: CreateStmt +== 552 +create table mclparted1 partition of mclparted for values in(1) +-- +TABLE: name="mclparted1" schema="" table="mclparted1" ctx=DDL +STMT: CreateStmt +== 553 +create table mclparted2 partition of mclparted for values in(2) +-- +TABLE: name="mclparted2" schema="" table="mclparted2" ctx=DDL +STMT: CreateStmt +== 554 +create index on mclparted (a) +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=DDL +STMT: IndexStmt +== 555 +-- Ensure an Append is used for a list partition with an order by. +explain (costs off) select * from mclparted order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 556 +-- 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) +-- +TABLE: name="mclparted3_5" schema="" table="mclparted3_5" ctx=DDL +STMT: CreateStmt +== 557 +create table mclparted4 partition of mclparted for values in(4) +-- +TABLE: name="mclparted4" schema="" table="mclparted4" ctx=DDL +STMT: CreateStmt +== 558 +explain (costs off) select * from mclparted order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 559 +explain (costs off) select * from mclparted where a in(3,4,5) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 560 +-- Introduce a NULL and DEFAULT partition so we can test more complex cases +create table mclparted_null partition of mclparted for values in(null) +-- +TABLE: name="mclparted_null" schema="" table="mclparted_null" ctx=DDL +STMT: CreateStmt +== 561 +create table mclparted_def partition of mclparted default +-- +TABLE: name="mclparted_def" schema="" table="mclparted_def" ctx=DDL +STMT: CreateStmt +== 562 +-- Append can be used providing we don't scan the interleaved partition +explain (costs off) select * from mclparted where a in(1,2,4) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 563 +explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 564 +-- Test a more complex case where the NULL partition allows some other value +drop table mclparted_null +-- +TABLE: name="mclparted_null" schema="" table="mclparted_null" ctx=DDL +STMT: DropStmt +== 565 +create table mclparted_0_null partition of mclparted for values in(0,null) +-- +TABLE: name="mclparted_0_null" schema="" table="mclparted_0_null" ctx=DDL +STMT: CreateStmt +== 566 +-- Ensure MergeAppend is used since 0 and NULLs are in the same partition. +explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 567 +explain (costs off) select * from mclparted where a in(0,1,2,4) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 568 +-- Ensure Append is used when the null partition is pruned +explain (costs off) select * from mclparted where a in(1,2,4) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 569 +-- Ensure MergeAppend is used when the default partition is not pruned +explain (costs off) select * from mclparted where a in(1,2,4,100) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 570 +drop table mclparted +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=DDL +STMT: DropStmt +== 571 +reset enable_sort +-- +STMT: VariableSetStmt +== 572 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 573 +-- Ensure subplans which don't have a path with the correct pathkeys get +-- sorted correctly. +drop index mcrparted_a_abs_c_idx +-- +STMT: DropStmt +== 574 +create index on mcrparted1 (a, abs(b), c) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 575 +create index on mcrparted2 (a, abs(b), c) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 576 +create index on mcrparted3 (a, abs(b), c) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 577 +create index on mcrparted4 (a, abs(b), c) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 578 +explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c limit 1 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 579 +set enable_bitmapscan = 0 +-- +STMT: VariableSetStmt +== 580 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 581 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 582 +drop table mcrparted +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: DropStmt +== 583 +-- Ensure LIST partitions allow an Append to be used instead of a MergeAppend +create table bool_lp (b bool) partition by list(b) +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=DDL +STMT: CreateStmt +== 584 +create table bool_lp_true partition of bool_lp for values in(true) +-- +TABLE: name="bool_lp_true" schema="" table="bool_lp_true" ctx=DDL +STMT: CreateStmt +== 585 +create table bool_lp_false partition of bool_lp for values in(false) +-- +TABLE: name="bool_lp_false" schema="" table="bool_lp_false" ctx=DDL +STMT: CreateStmt +== 586 +create index on bool_lp (b) +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=DDL +STMT: IndexStmt +== 587 +explain (costs off) select * from bool_lp order by b +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 588 +drop table bool_lp +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=DDL +STMT: DropStmt +== 589 +-- Ensure const bool quals can be properly detected as redundant +create table bool_rp (b bool, a int) partition by range(b,a) +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=DDL +STMT: CreateStmt +== 590 +create table bool_rp_false_1k partition of bool_rp for values from (false,0) to (false,1000) +-- +TABLE: name="bool_rp_false_1k" schema="" table="bool_rp_false_1k" ctx=DDL +STMT: CreateStmt +== 591 +create table bool_rp_true_1k partition of bool_rp for values from (true,0) to (true,1000) +-- +TABLE: name="bool_rp_true_1k" schema="" table="bool_rp_true_1k" ctx=DDL +STMT: CreateStmt +== 592 +create table bool_rp_false_2k partition of bool_rp for values from (false,1000) to (false,2000) +-- +TABLE: name="bool_rp_false_2k" schema="" table="bool_rp_false_2k" ctx=DDL +STMT: CreateStmt +== 593 +create table bool_rp_true_2k partition of bool_rp for values from (true,1000) to (true,2000) +-- +TABLE: name="bool_rp_true_2k" schema="" table="bool_rp_true_2k" ctx=DDL +STMT: CreateStmt +== 594 +create index on bool_rp (b,a) +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=DDL +STMT: IndexStmt +== 595 +explain (costs off) select * from bool_rp where b = true order by b,a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 596 +explain (costs off) select * from bool_rp where b = false order by b,a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 597 +explain (costs off) select * from bool_rp where b = true order by a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 598 +explain (costs off) select * from bool_rp where b = false order by a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 599 +drop table bool_rp +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=DDL +STMT: DropStmt +== 600 +-- 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) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +== 601 +create table range_parted1 partition of range_parted for values from (0,0) to (10,10) +-- +TABLE: name="range_parted1" schema="" table="range_parted1" ctx=DDL +STMT: CreateStmt +== 602 +create table range_parted2 partition of range_parted for values from (10,10) to (20,20) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +== 603 +create index on range_parted (a,b,c) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: IndexStmt +== 604 +explain (costs off) select * from range_parted order by a,b,c +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 605 +explain (costs off) select * from range_parted order by a desc,b desc,c desc +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 606 +drop table range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 607 +-- 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) +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: CreateStmt +== 608 +create table permtest_child (b text, c text, a int) partition by list (b) +-- +TABLE: name="permtest_child" schema="" table="permtest_child" ctx=DDL +STMT: CreateStmt +== 609 +create table permtest_grandchild (c text, b text, a int) +-- +TABLE: name="permtest_grandchild" schema="" table="permtest_grandchild" ctx=DDL +STMT: CreateStmt +== 610 +alter table permtest_child attach partition permtest_grandchild for values in ('a') +-- +TABLE: name="permtest_child" schema="" table="permtest_child" ctx=DDL +STMT: AlterTableStmt +== 611 +alter table permtest_parent attach partition permtest_child for values in (1) +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: AlterTableStmt +== 612 +create index on permtest_parent (left(c, 3)) +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +FUNCTION: name="left" function="left" schema="" ctx=Call +STMT: IndexStmt +== 613 +insert into permtest_parent + select 1, 'a', left(fipshash(i::text), 5) from generate_series(0, 100) i +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DML +FUNCTION: name="left" function="left" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 614 +analyze permtest_parent +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: VacuumStmt +== 615 +create role regress_no_child_access +-- +STMT: CreateRoleStmt +== 616 +revoke all on permtest_grandchild from regress_no_child_access +-- +TABLE: name="permtest_grandchild" schema="" table="permtest_grandchild" ctx=DDL +STMT: GrantStmt +== 617 +grant select on permtest_parent to regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +== 618 +set session authorization regress_no_child_access +-- +STMT: VariableSetStmt +== 619 +-- 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$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +STMT: ExplainStmt +STMT: SelectStmt +== 620 +explain (costs off) + select * from permtest_parent p1 inner join permtest_parent p2 + on p1.a = p2.a and left(p1.c, 3) ~ 'a1$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +FUNCTION: name="left" function="left" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 621 +reset session authorization +-- +STMT: VariableSetStmt +== 622 +revoke all on permtest_parent from regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +== 623 +grant select(a,c) on permtest_parent to regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +== 624 +set session authorization regress_no_child_access +-- +STMT: VariableSetStmt +== 625 +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$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +STMT: ExplainStmt +STMT: SelectStmt +== 626 +-- 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$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +FUNCTION: name="left" function="left" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 627 +reset session authorization +-- +STMT: VariableSetStmt +== 628 +revoke all on permtest_parent from regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +== 629 +drop role regress_no_child_access +-- +STMT: DropRoleStmt +== 630 +drop table permtest_parent +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: DropStmt +== 631 +-- 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) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: CreateStmt +== 632 +-- 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) +) +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DDL +STMT: CreateStmt +== 633 +-- 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) +) +-- +TABLE: name="errtst_child_plaindef" schema="" table="errtst_child_plaindef" ctx=DDL +STMT: CreateStmt +== 634 +-- 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) +) +-- +TABLE: name="errtst_child_reorder" schema="" table="errtst_child_reorder" ctx=DDL +STMT: CreateStmt +== 635 +ALTER TABLE errtst_child_fastdef ADD COLUMN data int NOT NULL DEFAULT 0 +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DDL +STMT: AlterTableStmt +== 636 +ALTER TABLE errtst_child_fastdef ADD CONSTRAINT errtest_child_fastdef_data_check CHECK (data < 10) +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DDL +STMT: AlterTableStmt +== 637 +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_fastdef FOR VALUES FROM (0) TO (10) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: AlterTableStmt +== 638 +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_plaindef FOR VALUES FROM (10) TO (20) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: AlterTableStmt +== 639 +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_reorder FOR VALUES FROM (20) TO (30) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: AlterTableStmt +== 640 +-- insert without child check constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 641 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 642 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 643 +-- insert with child check constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '10') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 644 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '10') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 645 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '10') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 646 +-- insert with child not null constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', NULL) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 647 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', NULL) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 648 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', NULL) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 649 +-- insert with shared check constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '5', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 650 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '5', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 651 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '5', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 652 +-- within partition update without child check constraint violation +BEGIN +-- +STMT: TransactionStmt +== 653 +UPDATE errtst_parent SET data = data + 1 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 654 +UPDATE errtst_parent SET data = data + 1 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 655 +UPDATE errtst_parent SET data = data + 1 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 656 +ROLLBACK +-- +STMT: TransactionStmt +== 657 +-- within partition update with child check constraint violation +UPDATE errtst_parent SET data = data + 10 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 658 +UPDATE errtst_parent SET data = data + 10 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 659 +UPDATE errtst_parent SET data = data + 10 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 660 +-- direct leaf partition update, without partition id violation +BEGIN +-- +STMT: TransactionStmt +== 661 +UPDATE errtst_child_fastdef SET partid = 1 WHERE partid = 0 +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DML +STMT: UpdateStmt +== 662 +UPDATE errtst_child_plaindef SET partid = 11 WHERE partid = 10 +-- +TABLE: name="errtst_child_plaindef" schema="" table="errtst_child_plaindef" ctx=DML +STMT: UpdateStmt +== 663 +UPDATE errtst_child_reorder SET partid = 21 WHERE partid = 20 +-- +TABLE: name="errtst_child_reorder" schema="" table="errtst_child_reorder" ctx=DML +STMT: UpdateStmt +== 664 +ROLLBACK +-- +STMT: TransactionStmt +== 665 +-- direct leaf partition update, with partition id violation +UPDATE errtst_child_fastdef SET partid = partid + 10 WHERE partid = 0 +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DML +STMT: UpdateStmt +== 666 +UPDATE errtst_child_plaindef SET partid = partid + 10 WHERE partid = 10 +-- +TABLE: name="errtst_child_plaindef" schema="" table="errtst_child_plaindef" ctx=DML +STMT: UpdateStmt +== 667 +UPDATE errtst_child_reorder SET partid = partid + 10 WHERE partid = 20 +-- +TABLE: name="errtst_child_reorder" schema="" table="errtst_child_reorder" ctx=DML +STMT: UpdateStmt +== 668 +-- partition move, without child check constraint violation +BEGIN +-- +STMT: TransactionStmt +== 669 +UPDATE errtst_parent SET partid = 10, data = data + 1 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 670 +UPDATE errtst_parent SET partid = 20, data = data + 1 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 671 +UPDATE errtst_parent SET partid = 0, data = data + 1 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 672 +ROLLBACK +-- +STMT: TransactionStmt +== 673 +-- partition move, with child check constraint violation +UPDATE errtst_parent SET partid = 10, data = data + 10 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 674 +UPDATE errtst_parent SET partid = 20, data = data + 10 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 675 +UPDATE errtst_parent SET partid = 0, data = data + 10 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 676 +-- partition move, without target partition +UPDATE errtst_parent SET partid = 30, data = data + 10 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +== 677 +DROP TABLE errtst_parent +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/init_privs.metadata.json b/parser/testdata/summary/postgres_regress/init_privs.metadata.json new file mode 100644 index 0000000..f1ffe06 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/init_privs.metadata.json @@ -0,0 +1,8 @@ +{ + "todo": [ + "001", + "002", + "003", + "004" + ] +} diff --git a/parser/testdata/summary/postgres_regress/init_privs.test b/parser/testdata/summary/postgres_regress/init_privs.test new file mode 100644 index 0000000..8710663 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/init_privs.test @@ -0,0 +1,25 @@ +== 001 +-- Test initial privileges + +-- There should always be some initial privileges, set up by initdb +SELECT count(*) > 0 FROM pg_init_privs +-- +TABLE: name="pg_init_privs" schema="" table="pg_init_privs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 002 +-- Intentionally include some non-initial privs for pg_dump to dump out +GRANT SELECT ON pg_proc TO CURRENT_USER +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=DDL +STMT: GrantStmt +== 003 +GRANT SELECT (prosrc) ON pg_proc TO CURRENT_USER +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=DDL +STMT: GrantStmt +== 004 +GRANT SELECT (rolname, rolsuper) ON pg_authid TO CURRENT_USER +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=DDL +STMT: GrantStmt diff --git a/parser/testdata/summary/postgres_regress/insert.metadata.json b/parser/testdata/summary/postgres_regress/insert.metadata.json new file mode 100644 index 0000000..1751d7d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/insert.metadata.json @@ -0,0 +1,391 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387" + ] +} diff --git a/parser/testdata/summary/postgres_regress/insert.test b/parser/testdata/summary/postgres_regress/insert.test new file mode 100644 index 0000000..a27379a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/insert.test @@ -0,0 +1,2298 @@ +== 001 +|-- +-- insert with DEFAULT in the target_list +|-- +create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: CreateStmt +== 002 +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +insert into inserttest (col2, col3) values (3, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +insert into inserttest values (DEFAULT, 5, 'test') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +insert into inserttest values (DEFAULT, 7) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +== 008 +|-- +-- insert with similar expression / target_list values (all fail) +|-- +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +insert into inserttest (col1, col2, col3) values (1, 2) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +insert into inserttest (col1) values (1, 2) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +insert into inserttest (col1) values (DEFAULT, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +== 013 +|-- +-- VALUES test +|-- +insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT), + ((select 2), (select i from (values(3)) as foo (i)), 'values are fun!') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +== 015 +|-- +-- TOASTed value test +|-- +insert into inserttest values(30, 50, repeat('x', 10000)) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 016 +select col1, col2, char_length(col3) from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +== 017 +drop table inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: DropStmt +== 018 +|-- +-- tuple larger than fillfactor +|-- +CREATE TABLE large_tuple_test (a int, b text) WITH (fillfactor = 10) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DDL +STMT: CreateStmt +== 019 +ALTER TABLE large_tuple_test ALTER COLUMN b SET STORAGE plain +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DDL +STMT: AlterTableStmt +== 020 +-- create page w/ free space in range [nearlyEmptyFreeSpace, MaxHeapTupleSize) +INSERT INTO large_tuple_test (select 1, NULL) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +-- should still fit on the page +INSERT INTO large_tuple_test (select 2, repeat('a', 1000)) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 022 +SELECT pg_size_pretty(pg_relation_size('large_tuple_test'::regclass, 'main')) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +== 023 +-- add small record to the second page +INSERT INTO large_tuple_test (select 3, NULL) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +-- now this tuple won't fit on the second page, but the insert should +-- still succeed by extending the relation +INSERT INTO large_tuple_test (select 4, repeat('a', 8126)) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 025 +DROP TABLE large_tuple_test +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DDL +STMT: DropStmt +== 026 +|-- +-- check indirection (field/array assignment), cf bug #14265 +|-- +-- these tests are aware that transformInsertStmt has 3 separate code paths +|-- + +create type insert_test_type as (if1 int, if2 text[]) +-- +STMT: CompositeTypeStmt +== 027 +create table inserttest (f1 int, f2 int[], + f3 insert_test_type, f4 insert_test_type[]) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: CreateStmt +== 028 +insert into inserttest (f2[1], f2[2]) values (1,2) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +insert into inserttest (f2[1], f2[2]) values (3,4), (5,6) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +insert into inserttest (f2[1], f2[2]) select 7,8 +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +insert into inserttest (f2[1], f2[2]) values (1,default) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +-- not supported + +insert into inserttest (f3.if1, f3.if2) values (1,array['foo']) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +insert into inserttest (f3.if1, f3.if2) values (1,'{foo}'), (2,'{bar}') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +insert into inserttest (f3.if1, f3.if2) select 3, '{baz,quux}' +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +insert into inserttest (f3.if1, f3.if2) values (1,default) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +-- not supported + +insert into inserttest (f3.if2[1], f3.if2[2]) values ('foo', 'bar') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +insert into inserttest (f3.if2[1], f3.if2[2]) values ('foo', 'bar'), ('baz', 'quux') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +insert into inserttest (f3.if2[1], f3.if2[2]) select 'bear', 'beer' +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) values ('foo', 'bar') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) values ('foo', 'bar'), ('baz', 'quux') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) select 'bear', 'beer' +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +== 043 +-- also check reverse-listing +create table inserttest2 (f1 bigint, f2 text) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: CreateStmt +== 044 +create rule irule1 as on insert to inserttest2 do also + insert into inserttest (f3.if2[1], f3.if2[2]) + values (new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +== 045 +create rule irule2 as on insert to inserttest2 do also + insert into inserttest (f4[1].if1, f4[1].if2[2]) + values (1,'fool'),(new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +== 046 +create rule irule3 as on insert to inserttest2 do also + insert into inserttest (f4[1].if1, f4[1].if2[2]) + select new.f1, new.f2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +== 047 +drop table inserttest2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: DropStmt +== 048 +drop table inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: DropStmt +== 049 +-- Make the same tests with domains over the array and composite fields + +create domain insert_pos_ints as int[] check (value[1] > 0) +-- +STMT: CreateDomainStmt +== 050 +create domain insert_test_domain as insert_test_type + check ((value).if2[1] is not null) +-- +STMT: CreateDomainStmt +== 051 +create table inserttesta (f1 int, f2 insert_pos_ints) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: CreateStmt +== 052 +create table inserttestb (f3 insert_test_domain, f4 insert_test_domain[]) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: CreateStmt +== 053 +insert into inserttesta (f2[1], f2[2]) values (1,2) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +insert into inserttesta (f2[1], f2[2]) values (3,4), (5,6) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +insert into inserttesta (f2[1], f2[2]) select 7,8 +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +insert into inserttesta (f2[1], f2[2]) values (1,default) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +-- not supported +insert into inserttesta (f2[1], f2[2]) values (0,2) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +insert into inserttesta (f2[1], f2[2]) values (3,4), (0,6) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +insert into inserttesta (f2[1], f2[2]) select 0,8 +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +insert into inserttestb (f3.if1, f3.if2) values (1,array['foo']) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +insert into inserttestb (f3.if1, f3.if2) values (1,'{foo}'), (2,'{bar}') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +insert into inserttestb (f3.if1, f3.if2) select 3, '{baz,quux}' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +insert into inserttestb (f3.if1, f3.if2) values (1,default) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +-- not supported +insert into inserttestb (f3.if1, f3.if2) values (1,array[null]) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +insert into inserttestb (f3.if1, f3.if2) values (1,'{null}'), (2,'{bar}') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 066 +insert into inserttestb (f3.if1, f3.if2) select 3, '{null,quux}' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +insert into inserttestb (f3.if2[1], f3.if2[2]) values ('foo', 'bar') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 068 +insert into inserttestb (f3.if2[1], f3.if2[2]) values ('foo', 'bar'), ('baz', 'quux') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +insert into inserttestb (f3.if2[1], f3.if2[2]) select 'bear', 'beer' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) values (row(1,'{x}'), 'foo', 'bar') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) values (row(1,'{x}'), 'foo', 'bar'), (row(2,'{y}'), 'baz', 'quux') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) select row(1,'{x}')::insert_test_domain, 'bear', 'beer' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +select * from inserttesta +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=Select +STMT: SelectStmt +== 074 +select * from inserttestb +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=Select +STMT: SelectStmt +== 075 +-- also check reverse-listing +create table inserttest2 (f1 bigint, f2 text) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: CreateStmt +== 076 +create rule irule1 as on insert to inserttest2 do also + insert into inserttestb (f3.if2[1], f3.if2[2]) + values (new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +== 077 +create rule irule2 as on insert to inserttest2 do also + insert into inserttestb (f4[1].if1, f4[1].if2[2]) + values (1,'fool'),(new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +== 078 +create rule irule3 as on insert to inserttest2 do also + insert into inserttestb (f4[1].if1, f4[1].if2[2]) + select new.f1, new.f2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +== 079 +drop table inserttest2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: DropStmt +== 080 +drop table inserttesta +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: DropStmt +== 081 +drop table inserttestb +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: DropStmt +== 082 +drop domain insert_pos_ints +-- +STMT: DropStmt +== 083 +drop domain insert_test_domain +-- +STMT: DropStmt +== 084 +-- Verify that multiple inserts to subfields of a domain-over-container +-- check the domain constraints only on the finished value + +create domain insert_nnarray as int[] + check (value[1] is not null and value[2] is not null) +-- +STMT: CreateDomainStmt +== 085 +create domain insert_test_domain as insert_test_type + check ((value).if1 is not null and (value).if2 is not null) +-- +STMT: CreateDomainStmt +== 086 +create table inserttesta (f1 insert_nnarray) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: CreateStmt +== 087 +insert into inserttesta (f1[1]) values (1) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +-- fail +insert into inserttesta (f1[1], f1[2]) values (1, 2) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +create table inserttestb (f1 insert_test_domain) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: CreateStmt +== 090 +insert into inserttestb (f1.if1) values (1) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 091 +-- fail +insert into inserttestb (f1.if1, f1.if2) values (1, '{foo}') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +drop table inserttesta +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: DropStmt +== 093 +drop table inserttestb +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: DropStmt +== 094 +drop domain insert_nnarray +-- +STMT: DropStmt +== 095 +drop type insert_test_type cascade +-- +STMT: DropStmt +== 096 +-- direct partition inserts should check partition bound constraint +create table range_parted ( + a text, + b int +) partition by range (a, (b+0)) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +== 097 +-- no partitions, so fail +insert into range_parted values ('a', 11) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +create table part1 partition of range_parted for values from ('a', 1) to ('a', 10) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +== 099 +create table part2 partition of range_parted for values from ('a', 10) to ('a', 20) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +== 100 +create table part3 partition of range_parted for values from ('b', 1) to ('b', 10) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +== 101 +create table part4 partition of range_parted for values from ('b', 10) to ('b', 20) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +== 102 +-- fail +insert into part1 values ('a', 11) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +insert into part1 values ('b', 1) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +-- ok +insert into part1 values ('a', 1) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +-- fail +insert into part4 values ('b', 21) +-- +TABLE: name="part4" schema="" table="part4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 106 +insert into part4 values ('a', 10) +-- +TABLE: name="part4" schema="" table="part4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +-- ok +insert into part4 values ('b', 10) +-- +TABLE: name="part4" schema="" table="part4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +-- fail (partition key a has a NOT NULL constraint) +insert into part1 values (null) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +-- fail (expression key (b+0) cannot be null either) +insert into part1 values (1) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +create table list_parted ( + a text, + b int +) partition by list (lower(a)) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +== 111 +create table part_aa_bb partition of list_parted FOR VALUES IN ('aa', 'bb') +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DDL +STMT: CreateStmt +== 112 +create table part_cc_dd partition of list_parted FOR VALUES IN ('cc', 'dd') +-- +TABLE: name="part_cc_dd" schema="" table="part_cc_dd" ctx=DDL +STMT: CreateStmt +== 113 +create table part_null partition of list_parted FOR VALUES IN (null) +-- +TABLE: name="part_null" schema="" table="part_null" ctx=DDL +STMT: CreateStmt +== 114 +-- fail +insert into part_aa_bb values ('cc', 1) +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +insert into part_aa_bb values ('AAa', 1) +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +insert into part_aa_bb values (null) +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +-- ok +insert into part_cc_dd values ('cC', 1) +-- +TABLE: name="part_cc_dd" schema="" table="part_cc_dd" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +insert into part_null values (null, 0) +-- +TABLE: name="part_null" schema="" table="part_null" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +-- check in case of multi-level partitioned table +create table part_ee_ff partition of list_parted for values in ('ee', 'ff') partition by range (b) +-- +TABLE: name="part_ee_ff" schema="" table="part_ee_ff" ctx=DDL +STMT: CreateStmt +== 120 +create table part_ee_ff1 partition of part_ee_ff for values from (1) to (10) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DDL +STMT: CreateStmt +== 121 +create table part_ee_ff2 partition of part_ee_ff for values from (10) to (20) +-- +TABLE: name="part_ee_ff2" schema="" table="part_ee_ff2" ctx=DDL +STMT: CreateStmt +== 122 +-- test default partition +create table part_default partition of list_parted default +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +== 123 +-- Negative test: a row, which would fit in other partition, does not fit +-- default partition, even when inserted directly +insert into part_default values ('aa', 2) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 124 +insert into part_default values (null, 2) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +-- ok +insert into part_default values ('Zz', 2) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 126 +-- test if default partition works as expected for multi-level partitioned +-- table as well as when default partition itself is further partitioned +drop table part_default +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: DropStmt +== 127 +create table part_xx_yy partition of list_parted for values in ('xx', 'yy') partition by list (a) +-- +TABLE: name="part_xx_yy" schema="" table="part_xx_yy" ctx=DDL +STMT: CreateStmt +== 128 +create table part_xx_yy_p1 partition of part_xx_yy for values in ('xx') +-- +TABLE: name="part_xx_yy_p1" schema="" table="part_xx_yy_p1" ctx=DDL +STMT: CreateStmt +== 129 +create table part_xx_yy_defpart partition of part_xx_yy default +-- +TABLE: name="part_xx_yy_defpart" schema="" table="part_xx_yy_defpart" ctx=DDL +STMT: CreateStmt +== 130 +create table part_default partition of list_parted default partition by range(b) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +== 131 +create table part_default_p1 partition of part_default for values from (20) to (30) +-- +TABLE: name="part_default_p1" schema="" table="part_default_p1" ctx=DDL +STMT: CreateStmt +== 132 +create table part_default_p2 partition of part_default for values from (30) to (40) +-- +TABLE: name="part_default_p2" schema="" table="part_default_p2" ctx=DDL +STMT: CreateStmt +== 133 +-- fail +insert into part_ee_ff1 values ('EE', 11) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 134 +insert into part_default_p2 values ('gg', 43) +-- +TABLE: name="part_default_p2" schema="" table="part_default_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 135 +-- fail (even the parent's, ie, part_ee_ff's partition constraint applies) +insert into part_ee_ff1 values ('cc', 1) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +insert into part_default values ('gg', 43) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +-- ok +insert into part_ee_ff1 values ('ff', 1) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +insert into part_ee_ff2 values ('ff', 11) +-- +TABLE: name="part_ee_ff2" schema="" table="part_ee_ff2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +insert into part_default_p1 values ('cd', 25) +-- +TABLE: name="part_default_p1" schema="" table="part_default_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 140 +insert into part_default_p2 values ('de', 35) +-- +TABLE: name="part_default_p2" schema="" table="part_default_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +insert into list_parted values ('ab', 21) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +insert into list_parted values ('xx', 1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +insert into list_parted values ('yy', 2) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +select tableoid::regclass, * from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 145 +-- Check tuple routing for partitioned tables + +-- fail +insert into range_parted values ('a', 0) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +-- ok +insert into range_parted values ('a', 1) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +insert into range_parted values ('a', 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +-- fail +insert into range_parted values ('a', 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 149 +-- ok +insert into range_parted values ('b', 1) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +insert into range_parted values ('b', 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +-- fail (partition key (b+0) is null) +insert into range_parted values ('a') +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +-- Check default partition +create table part_def partition of range_parted default +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DDL +STMT: CreateStmt +== 153 +-- fail +insert into part_def values ('b', 10) +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +-- ok +insert into part_def values ('c', 10) +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +insert into range_parted values (null, null) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +insert into range_parted values ('a', null) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 157 +insert into range_parted values (null, 19) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 158 +insert into range_parted values ('b', 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +select tableoid::regclass, * from range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +STMT: SelectStmt +== 160 +-- ok +insert into list_parted values (null, 1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 161 +insert into list_parted (a) values ('aA') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +-- fail (partition of part_ee_ff not found in both cases) +insert into list_parted values ('EE', 0) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +insert into part_ee_ff values ('EE', 0) +-- +TABLE: name="part_ee_ff" schema="" table="part_ee_ff" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +-- ok +insert into list_parted values ('EE', 1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +insert into part_ee_ff values ('EE', 10) +-- +TABLE: name="part_ee_ff" schema="" table="part_ee_ff" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +select tableoid::regclass, * from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 167 +-- some more tests to exercise tuple-routing with multi-level partitioning +create table part_gg partition of list_parted for values in ('gg') partition by range (b) +-- +TABLE: name="part_gg" schema="" table="part_gg" ctx=DDL +STMT: CreateStmt +== 168 +create table part_gg1 partition of part_gg for values from (minvalue) to (1) +-- +TABLE: name="part_gg1" schema="" table="part_gg1" ctx=DDL +STMT: CreateStmt +== 169 +create table part_gg2 partition of part_gg for values from (1) to (10) partition by range (b) +-- +TABLE: name="part_gg2" schema="" table="part_gg2" ctx=DDL +STMT: CreateStmt +== 170 +create table part_gg2_1 partition of part_gg2 for values from (1) to (5) +-- +TABLE: name="part_gg2_1" schema="" table="part_gg2_1" ctx=DDL +STMT: CreateStmt +== 171 +create table part_gg2_2 partition of part_gg2 for values from (5) to (10) +-- +TABLE: name="part_gg2_2" schema="" table="part_gg2_2" ctx=DDL +STMT: CreateStmt +== 172 +create table part_ee_ff3 partition of part_ee_ff for values from (20) to (30) partition by range (b) +-- +TABLE: name="part_ee_ff3" schema="" table="part_ee_ff3" ctx=DDL +STMT: CreateStmt +== 173 +create table part_ee_ff3_1 partition of part_ee_ff3 for values from (20) to (25) +-- +TABLE: name="part_ee_ff3_1" schema="" table="part_ee_ff3_1" ctx=DDL +STMT: CreateStmt +== 174 +create table part_ee_ff3_2 partition of part_ee_ff3 for values from (25) to (30) +-- +TABLE: name="part_ee_ff3_2" schema="" table="part_ee_ff3_2" ctx=DDL +STMT: CreateStmt +== 175 +truncate list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: TruncateStmt +== 176 +insert into list_parted values ('aa'), ('cc') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 177 +insert into list_parted select 'Ff', s.a from generate_series(1, 29) s(a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 178 +insert into list_parted select 'gg', s.a from generate_series(1, 9) s(a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 179 +insert into list_parted (b) values (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 180 +select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_parted group by 1, 2 order by 1 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 181 +-- direct partition inserts should check hash partition bound constraint + +create table hash_parted ( + a int +) partition by hash (a part_test_int4_ops) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +== 182 +create table hpart0 partition of hash_parted for values with (modulus 4, remainder 0) +-- +TABLE: name="hpart0" schema="" table="hpart0" ctx=DDL +STMT: CreateStmt +== 183 +create table hpart1 partition of hash_parted for values with (modulus 4, remainder 1) +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DDL +STMT: CreateStmt +== 184 +create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2) +-- +TABLE: name="hpart2" schema="" table="hpart2" ctx=DDL +STMT: CreateStmt +== 185 +create table hpart3 partition of hash_parted for values with (modulus 4, remainder 3) +-- +TABLE: name="hpart3" schema="" table="hpart3" ctx=DDL +STMT: CreateStmt +== 186 +insert into hash_parted values(generate_series(1,10)) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 187 +-- direct insert of values divisible by 4 - ok; +insert into hpart0 values(12),(16) +-- +TABLE: name="hpart0" schema="" table="hpart0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +-- fail; +insert into hpart0 values(11) +-- +TABLE: name="hpart0" schema="" table="hpart0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +-- 11 % 4 -> 3 remainder i.e. valid data for hpart3 partition +insert into hpart3 values(11) +-- +TABLE: name="hpart3" schema="" table="hpart3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +-- view data +select tableoid::regclass as part, a, a%4 as "remainder = a % 4" +from hash_parted order by part +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=Select +STMT: SelectStmt +== 191 +-- test \d+ output on a table which has both partitioned and unpartitioned +-- partitions + +-- cleanup +drop table range_parted, list_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +== 192 +drop table hash_parted +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: DropStmt +== 193 +-- test that a default partition added as the first partition accepts any value +-- including null +create table list_parted (a int) partition by list (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +== 194 +create table part_default partition of list_parted default +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +== 195 +insert into part_default values (null) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +insert into part_default values (1) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 197 +insert into part_default values (-1) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 198 +select tableoid::regclass, a from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 199 +-- cleanup +drop table list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +== 200 +-- more tests for certain multi-level partitioning scenarios +create table mlparted (a int, b int) partition by range (a, b) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: CreateStmt +== 201 +create table mlparted1 (b int not null, a int not null) partition by range ((b+0)) +-- +TABLE: name="mlparted1" schema="" table="mlparted1" ctx=DDL +STMT: CreateStmt +== 202 +create table mlparted11 (like mlparted1) +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: CreateStmt +== 203 +alter table mlparted11 drop a +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +== 204 +alter table mlparted11 add a int +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +== 205 +alter table mlparted11 drop a +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +== 206 +alter table mlparted11 add a int not null +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +== 207 +-- attnum for key attribute 'a' is different in mlparted, mlparted1, and mlparted11 +select attrelid::regclass, attname, attnum +from pg_attribute +where attname = 'a' + and (attrelid = 'mlparted'::regclass + or attrelid = 'mlparted1'::regclass + or attrelid = 'mlparted11'::regclass) +order by attrelid::regclass::text +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attname" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +== 208 +alter table mlparted1 attach partition mlparted11 for values from (2) to (5) +-- +TABLE: name="mlparted1" schema="" table="mlparted1" ctx=DDL +STMT: AlterTableStmt +== 209 +alter table mlparted attach partition mlparted1 for values from (1, 2) to (1, 10) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 210 +-- check that "(1, 2)" is correctly routed to mlparted11. +insert into mlparted values (1, 2) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 211 +select tableoid::regclass, * from mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=Select +STMT: SelectStmt +== 212 +-- check that proper message is shown after failure to route through mlparted1 +insert into mlparted (a, b) values (1, 5) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 213 +truncate mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: TruncateStmt +== 214 +alter table mlparted add constraint check_b check (b = 3) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 215 +-- have a BR trigger modify the row such that the check_b is violated +create function mlparted11_trig_fn() +returns trigger AS +$$ +begin + NEW.b := 4; + return NEW; +end; +$$ +language plpgsql +-- +FUNCTION: name="mlparted11_trig_fn" function="mlparted11_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 216 +create trigger mlparted11_trig before insert ON mlparted11 + for each row execute procedure mlparted11_trig_fn() +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: CreateTrigStmt +== 217 +-- check that the correct row is shown when constraint check_b fails after +-- "(1, 2)" is routed to mlparted11 (actually "(1, 4)" would be shown due +-- to the BR trigger mlparted11_trig_fn) +insert into mlparted values (1, 2) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 218 +drop trigger mlparted11_trig on mlparted11 +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: DropStmt +== 219 +drop function mlparted11_trig_fn() +-- +FUNCTION: name="mlparted11_trig_fn" function="mlparted11_trig_fn" schema="" ctx=DDL +STMT: DropStmt +== 220 +-- check that inserting into an internal partition successfully results in +-- checking its partition constraint before inserting into the leaf partition +-- selected by tuple-routing +insert into mlparted1 (a, b) values (2, 3) +-- +TABLE: name="mlparted1" schema="" table="mlparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 221 +-- check routing error through a list partitioned table when the key is null +create table lparted_nonullpart (a int, b char) partition by list (b) +-- +TABLE: name="lparted_nonullpart" schema="" table="lparted_nonullpart" ctx=DDL +STMT: CreateStmt +== 222 +create table lparted_nonullpart_a partition of lparted_nonullpart for values in ('a') +-- +TABLE: name="lparted_nonullpart_a" schema="" table="lparted_nonullpart_a" ctx=DDL +STMT: CreateStmt +== 223 +insert into lparted_nonullpart values (1) +-- +TABLE: name="lparted_nonullpart" schema="" table="lparted_nonullpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 224 +drop table lparted_nonullpart +-- +TABLE: name="lparted_nonullpart" schema="" table="lparted_nonullpart" ctx=DDL +STMT: DropStmt +== 225 +-- check that RETURNING works correctly with tuple-routing +alter table mlparted drop constraint check_b +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 226 +create table mlparted12 partition of mlparted1 for values from (5) to (10) +-- +TABLE: name="mlparted12" schema="" table="mlparted12" ctx=DDL +STMT: CreateStmt +== 227 +create table mlparted2 (b int not null, a int not null) +-- +TABLE: name="mlparted2" schema="" table="mlparted2" ctx=DDL +STMT: CreateStmt +== 228 +alter table mlparted attach partition mlparted2 for values from (1, 10) to (1, 20) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 229 +create table mlparted3 partition of mlparted for values from (1, 20) to (1, 30) +-- +TABLE: name="mlparted3" schema="" table="mlparted3" ctx=DDL +STMT: CreateStmt +== 230 +create table mlparted4 (like mlparted) +-- +TABLE: name="mlparted4" schema="" table="mlparted4" ctx=DDL +STMT: CreateStmt +== 231 +alter table mlparted4 drop a +-- +TABLE: name="mlparted4" schema="" table="mlparted4" ctx=DDL +STMT: AlterTableStmt +== 232 +alter table mlparted4 add a int not null +-- +TABLE: name="mlparted4" schema="" table="mlparted4" ctx=DDL +STMT: AlterTableStmt +== 233 +alter table mlparted attach partition mlparted4 for values from (1, 30) to (1, 40) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 234 +with ins (a, b, c) as + (insert into mlparted (b, a) select s.a, 1 from generate_series(2, 39) s(a) returning tableoid::regclass, *) + select a, b, min(c), max(c) from ins group by a, b order by 1 +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +CTE: "ins" +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +STMT: InsertStmt +== 235 +alter table mlparted add c text +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 236 +create table mlparted5 (c text, a int not null, b int not null) partition by list (c) +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: CreateStmt +== 237 +create table mlparted5a (a int not null, c text, b int not null) +-- +TABLE: name="mlparted5a" schema="" table="mlparted5a" ctx=DDL +STMT: CreateStmt +== 238 +alter table mlparted5 attach partition mlparted5a for values in ('a') +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: AlterTableStmt +== 239 +alter table mlparted attach partition mlparted5 for values from (1, 40) to (1, 50) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 240 +alter table mlparted add constraint check_b check (a = 1 and b < 45) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 241 +insert into mlparted values (1, 45, 'a') +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 242 +create function mlparted5abrtrig_func() returns trigger as $$ begin new.c = 'b'; return new; end; $$ language plpgsql +-- +FUNCTION: name="mlparted5abrtrig_func" function="mlparted5abrtrig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 243 +create trigger mlparted5abrtrig before insert on mlparted5a for each row execute procedure mlparted5abrtrig_func() +-- +TABLE: name="mlparted5a" schema="" table="mlparted5a" ctx=DDL +STMT: CreateTrigStmt +== 244 +insert into mlparted5 (a, b, c) values (1, 40, 'a') +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +drop table mlparted5 +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: DropStmt +== 246 +alter table mlparted drop constraint check_b +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 247 +-- Check multi-level default partition +create table mlparted_def partition of mlparted default partition by range(a) +-- +TABLE: name="mlparted_def" schema="" table="mlparted_def" ctx=DDL +STMT: CreateStmt +== 248 +create table mlparted_def1 partition of mlparted_def for values from (40) to (50) +-- +TABLE: name="mlparted_def1" schema="" table="mlparted_def1" ctx=DDL +STMT: CreateStmt +== 249 +create table mlparted_def2 partition of mlparted_def for values from (50) to (60) +-- +TABLE: name="mlparted_def2" schema="" table="mlparted_def2" ctx=DDL +STMT: CreateStmt +== 250 +insert into mlparted values (40, 100) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 251 +insert into mlparted_def1 values (42, 100) +-- +TABLE: name="mlparted_def1" schema="" table="mlparted_def1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 252 +insert into mlparted_def2 values (54, 50) +-- +TABLE: name="mlparted_def2" schema="" table="mlparted_def2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +-- fail +insert into mlparted values (70, 100) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +insert into mlparted_def1 values (52, 50) +-- +TABLE: name="mlparted_def1" schema="" table="mlparted_def1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 255 +insert into mlparted_def2 values (34, 50) +-- +TABLE: name="mlparted_def2" schema="" table="mlparted_def2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 256 +-- ok +create table mlparted_defd partition of mlparted_def default +-- +TABLE: name="mlparted_defd" schema="" table="mlparted_defd" ctx=DDL +STMT: CreateStmt +== 257 +insert into mlparted values (70, 100) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 258 +select tableoid::regclass, * from mlparted_def +-- +TABLE: name="mlparted_def" schema="" table="mlparted_def" ctx=Select +STMT: SelectStmt +== 259 +-- Check multi-level tuple routing with attributes dropped from the +-- top-most parent. First remove the last attribute. +alter table mlparted add d int, add e int +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 260 +alter table mlparted drop e +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 261 +create table mlparted5 partition of mlparted + for values from (1, 40) to (1, 50) partition by range (c) +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: CreateStmt +== 262 +create table mlparted5_ab partition of mlparted5 + for values from ('a') to ('c') partition by list (c) +-- +TABLE: name="mlparted5_ab" schema="" table="mlparted5_ab" ctx=DDL +STMT: CreateStmt +== 263 +-- This partitioned table should remain with no partitions. +create table mlparted5_cd partition of mlparted5 + for values from ('c') to ('e') partition by list (c) +-- +TABLE: name="mlparted5_cd" schema="" table="mlparted5_cd" ctx=DDL +STMT: CreateStmt +== 264 +create table mlparted5_a partition of mlparted5_ab for values in ('a') +-- +TABLE: name="mlparted5_a" schema="" table="mlparted5_a" ctx=DDL +STMT: CreateStmt +== 265 +create table mlparted5_b (d int, b int, c text, a int) +-- +TABLE: name="mlparted5_b" schema="" table="mlparted5_b" ctx=DDL +STMT: CreateStmt +== 266 +alter table mlparted5_ab attach partition mlparted5_b for values in ('b') +-- +TABLE: name="mlparted5_ab" schema="" table="mlparted5_ab" ctx=DDL +STMT: AlterTableStmt +== 267 +truncate mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: TruncateStmt +== 268 +insert into mlparted values (1, 2, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +insert into mlparted values (1, 40, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 270 +-- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 271 +-- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 272 +-- goes to mlparted5_cd, fails +insert into mlparted values (1, 45, 'f', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 273 +-- goes to mlparted5, fails +select tableoid::regclass, * from mlparted order by a, b, c, d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=Select +STMT: SelectStmt +== 274 +alter table mlparted drop d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 275 +truncate mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: TruncateStmt +== 276 +-- Remove the before last attribute. +alter table mlparted add e int, add d int +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 277 +alter table mlparted drop e +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 278 +insert into mlparted values (1, 2, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 279 +insert into mlparted values (1, 40, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +-- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 281 +-- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 282 +-- goes to mlparted5_cd, fails +insert into mlparted values (1, 45, 'f', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +-- goes to mlparted5, fails +select tableoid::regclass, * from mlparted order by a, b, c, d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=Select +STMT: SelectStmt +== 284 +alter table mlparted drop d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +== 285 +drop table mlparted5 +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: DropStmt +== 286 +-- check that message shown after failure to find a partition shows the +-- appropriate key description (or none) in various situations +create table key_desc (a int, b int) partition by list ((a+0)) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +STMT: CreateStmt +== 287 +create table key_desc_1 partition of key_desc for values in (1) partition by range (b) +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: CreateStmt +== 288 +create user regress_insert_other_user +-- +STMT: CreateRoleStmt +== 289 +grant select (a) on key_desc_1 to regress_insert_other_user +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: GrantStmt +== 290 +grant insert on key_desc to regress_insert_other_user +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +STMT: GrantStmt +== 291 +set role regress_insert_other_user +-- +STMT: VariableSetStmt +== 292 +-- no key description is shown +insert into key_desc values (1, 1) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +reset role +-- +STMT: VariableSetStmt +== 294 +grant select (b) on key_desc_1 to regress_insert_other_user +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: GrantStmt +== 295 +set role regress_insert_other_user +-- +STMT: VariableSetStmt +== 296 +-- key description (b)=(1) is now shown +insert into key_desc values (1, 1) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 297 +-- key description is not shown if key contains expression +insert into key_desc values (2, 1) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 298 +reset role +-- +STMT: VariableSetStmt +== 299 +revoke all on key_desc from regress_insert_other_user +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +STMT: GrantStmt +== 300 +revoke all on key_desc_1 from regress_insert_other_user +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: GrantStmt +== 301 +drop role regress_insert_other_user +-- +STMT: DropRoleStmt +== 302 +drop table key_desc, key_desc_1 +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: DropStmt +== 303 +-- test minvalue/maxvalue restrictions +create table mcrparted (a int, b int, c int) partition by range (a, abs(b), c) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: CreateStmt +== 304 +create table mcrparted0 partition of mcrparted for values from (minvalue, 0, 0) to (1, maxvalue, maxvalue) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DDL +STMT: CreateStmt +== 305 +create table mcrparted2 partition of mcrparted for values from (10, 6, minvalue) to (10, maxvalue, minvalue) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +STMT: CreateStmt +== 306 +create table mcrparted4 partition of mcrparted for values from (21, minvalue, 0) to (30, 20, minvalue) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +STMT: CreateStmt +== 307 +-- check multi-column range partitioning expression enforces the same +-- constraint as what tuple-routing would determine it to be +create table mcrparted0 partition of mcrparted for values from (minvalue, minvalue, minvalue) to (1, maxvalue, maxvalue) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DDL +STMT: CreateStmt +== 308 +create table mcrparted1 partition of mcrparted for values from (2, 1, minvalue) to (10, 5, 10) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DDL +STMT: CreateStmt +== 309 +create table mcrparted2 partition of mcrparted for values from (10, 6, minvalue) to (10, maxvalue, maxvalue) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +STMT: CreateStmt +== 310 +create table mcrparted3 partition of mcrparted for values from (11, 1, 1) to (20, 10, 10) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DDL +STMT: CreateStmt +== 311 +create table mcrparted4 partition of mcrparted for values from (21, minvalue, minvalue) to (30, 20, maxvalue) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +STMT: CreateStmt +== 312 +create table mcrparted5 partition of mcrparted for values from (30, 21, 20) to (maxvalue, maxvalue, maxvalue) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: CreateStmt +== 313 +-- null not allowed in range partition +insert into mcrparted values (null, null, null) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 314 +-- routed to mcrparted0 +insert into mcrparted values (0, 1, 1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 315 +insert into mcrparted0 values (0, 1, 1) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 316 +-- routed to mcparted1 +insert into mcrparted values (9, 1000, 1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 317 +insert into mcrparted1 values (9, 1000, 1) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 318 +insert into mcrparted values (10, 5, -1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 319 +insert into mcrparted1 values (10, 5, -1) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 320 +insert into mcrparted values (2, 1, 0) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 321 +insert into mcrparted1 values (2, 1, 0) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 322 +-- routed to mcparted2 +insert into mcrparted values (10, 6, 1000) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 323 +insert into mcrparted2 values (10, 6, 1000) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 324 +insert into mcrparted values (10, 1000, 1000) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 325 +insert into mcrparted2 values (10, 1000, 1000) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 326 +-- no partition exists, nor does mcrparted3 accept it +insert into mcrparted values (11, 1, -1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 327 +insert into mcrparted3 values (11, 1, -1) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 328 +-- routed to mcrparted5 +insert into mcrparted values (30, 21, 20) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 329 +insert into mcrparted5 values (30, 21, 20) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 330 +insert into mcrparted4 values (30, 21, 20) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 331 +-- error + +-- check rows +select tableoid::regclass::text, * from mcrparted order by 1 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +STMT: SelectStmt +== 332 +-- cleanup +drop table mcrparted +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: DropStmt +== 333 +-- check that a BR constraint can't make partition contain violating rows +create table brtrigpartcon (a int, b text) partition by list (a) +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: CreateStmt +== 334 +create table brtrigpartcon1 partition of brtrigpartcon for values in (1) +-- +TABLE: name="brtrigpartcon1" schema="" table="brtrigpartcon1" ctx=DDL +STMT: CreateStmt +== 335 +create or replace function brtrigpartcon1trigf() returns trigger as $$begin new.a := 2; return new; end$$ language plpgsql +-- +FUNCTION: name="brtrigpartcon1trigf" function="brtrigpartcon1trigf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 336 +create trigger brtrigpartcon1trig before insert on brtrigpartcon1 for each row execute procedure brtrigpartcon1trigf() +-- +TABLE: name="brtrigpartcon1" schema="" table="brtrigpartcon1" ctx=DDL +STMT: CreateTrigStmt +== 337 +insert into brtrigpartcon values (1, 'hi there') +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 338 +insert into brtrigpartcon1 values (1, 'hi there') +-- +TABLE: name="brtrigpartcon1" schema="" table="brtrigpartcon1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 339 +-- check that the message shows the appropriate column description in a +-- situation where the partitioned table is not the primary ModifyTable node +create table inserttest3 (f1 text default 'foo', f2 text default 'bar', f3 int) +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: CreateStmt +== 340 +create role regress_coldesc_role +-- +STMT: CreateRoleStmt +== 341 +grant insert on inserttest3 to regress_coldesc_role +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: GrantStmt +== 342 +grant insert on brtrigpartcon to regress_coldesc_role +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: GrantStmt +== 343 +revoke select on brtrigpartcon from regress_coldesc_role +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: GrantStmt +== 344 +set role regress_coldesc_role +-- +STMT: VariableSetStmt +== 345 +with result as (insert into brtrigpartcon values (1, 'hi there') returning 1) + insert into inserttest3 (f3) select * from result +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DML +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DML +CTE: "result" +STMT: InsertStmt +STMT: SelectStmt +== 346 +reset role +-- +STMT: VariableSetStmt +== 347 +-- cleanup +revoke all on inserttest3 from regress_coldesc_role +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: GrantStmt +== 348 +revoke all on brtrigpartcon from regress_coldesc_role +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: GrantStmt +== 349 +drop role regress_coldesc_role +-- +STMT: DropRoleStmt +== 350 +drop table inserttest3 +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: DropStmt +== 351 +drop table brtrigpartcon +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: DropStmt +== 352 +drop function brtrigpartcon1trigf() +-- +FUNCTION: name="brtrigpartcon1trigf" function="brtrigpartcon1trigf" schema="" ctx=DDL +STMT: DropStmt +== 353 +-- check that "do nothing" BR triggers work with tuple-routing +create table donothingbrtrig_test (a int, b text) partition by list (a) +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: CreateStmt +== 354 +create table donothingbrtrig_test1 (b text, a int) +-- +TABLE: name="donothingbrtrig_test1" schema="" table="donothingbrtrig_test1" ctx=DDL +STMT: CreateStmt +== 355 +create table donothingbrtrig_test2 (c text, b text, a int) +-- +TABLE: name="donothingbrtrig_test2" schema="" table="donothingbrtrig_test2" ctx=DDL +STMT: CreateStmt +== 356 +alter table donothingbrtrig_test2 drop column c +-- +TABLE: name="donothingbrtrig_test2" schema="" table="donothingbrtrig_test2" ctx=DDL +STMT: AlterTableStmt +== 357 +create or replace function donothingbrtrig_func() returns trigger as $$begin raise notice 'b: %', new.b; return NULL; end$$ language plpgsql +-- +FUNCTION: name="donothingbrtrig_func" function="donothingbrtrig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 358 +create trigger donothingbrtrig1 before insert on donothingbrtrig_test1 for each row execute procedure donothingbrtrig_func() +-- +TABLE: name="donothingbrtrig_test1" schema="" table="donothingbrtrig_test1" ctx=DDL +STMT: CreateTrigStmt +== 359 +create trigger donothingbrtrig2 before insert on donothingbrtrig_test2 for each row execute procedure donothingbrtrig_func() +-- +TABLE: name="donothingbrtrig_test2" schema="" table="donothingbrtrig_test2" ctx=DDL +STMT: CreateTrigStmt +== 360 +alter table donothingbrtrig_test attach partition donothingbrtrig_test1 for values in (1) +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: AlterTableStmt +== 361 +alter table donothingbrtrig_test attach partition donothingbrtrig_test2 for values in (2) +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: AlterTableStmt +== 362 +insert into donothingbrtrig_test values (1, 'foo'), (2, 'bar') +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 363 +copy donothingbrtrig_test from stdout +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=Select +STMT: CopyStmt +== 364 +1 baz +2 qux +select tableoid::regclass, * from donothingbrtrig_test +-- +ERROR: syntax error at or near "1" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 365 +-- cleanup +drop table donothingbrtrig_test +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: DropStmt +== 366 +drop function donothingbrtrig_func() +-- +FUNCTION: name="donothingbrtrig_func" function="donothingbrtrig_func" schema="" ctx=DDL +STMT: DropStmt +== 367 +-- check multi-column range partitioning with minvalue/maxvalue constraints +create table mcrparted (a text, b int) partition by range(a, b) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: CreateStmt +== 368 +create table mcrparted1_lt_b partition of mcrparted for values from (minvalue, minvalue) to ('b', minvalue) +-- +TABLE: name="mcrparted1_lt_b" schema="" table="mcrparted1_lt_b" ctx=DDL +STMT: CreateStmt +== 369 +create table mcrparted2_b partition of mcrparted for values from ('b', minvalue) to ('c', minvalue) +-- +TABLE: name="mcrparted2_b" schema="" table="mcrparted2_b" ctx=DDL +STMT: CreateStmt +== 370 +create table mcrparted3_c_to_common partition of mcrparted for values from ('c', minvalue) to ('common', minvalue) +-- +TABLE: name="mcrparted3_c_to_common" schema="" table="mcrparted3_c_to_common" ctx=DDL +STMT: CreateStmt +== 371 +create table mcrparted4_common_lt_0 partition of mcrparted for values from ('common', minvalue) to ('common', 0) +-- +TABLE: name="mcrparted4_common_lt_0" schema="" table="mcrparted4_common_lt_0" ctx=DDL +STMT: CreateStmt +== 372 +create table mcrparted5_common_0_to_10 partition of mcrparted for values from ('common', 0) to ('common', 10) +-- +TABLE: name="mcrparted5_common_0_to_10" schema="" table="mcrparted5_common_0_to_10" ctx=DDL +STMT: CreateStmt +== 373 +create table mcrparted6_common_ge_10 partition of mcrparted for values from ('common', 10) to ('common', maxvalue) +-- +TABLE: name="mcrparted6_common_ge_10" schema="" table="mcrparted6_common_ge_10" ctx=DDL +STMT: CreateStmt +== 374 +create table mcrparted7_gt_common_lt_d partition of mcrparted for values from ('common', maxvalue) to ('d', minvalue) +-- +TABLE: name="mcrparted7_gt_common_lt_d" schema="" table="mcrparted7_gt_common_lt_d" ctx=DDL +STMT: CreateStmt +== 375 +create table mcrparted8_ge_d partition of mcrparted for values from ('d', minvalue) to (maxvalue, maxvalue) +-- +TABLE: name="mcrparted8_ge_d" schema="" table="mcrparted8_ge_d" ctx=DDL +STMT: CreateStmt +== 376 +insert into mcrparted values ('aaa', 0), ('b', 0), ('bz', 10), ('c', -10), + ('comm', -10), ('common', -10), ('common', 0), ('common', 10), + ('commons', 0), ('d', -10), ('e', 0) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 377 +select tableoid::regclass, * from mcrparted order by a, b +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +STMT: SelectStmt +== 378 +drop table mcrparted +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: DropStmt +== 379 +-- check that wholerow vars in the RETURNING list work with partitioned tables +create table returningwrtest (a int) partition by list (a) +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: CreateStmt +== 380 +create table returningwrtest1 partition of returningwrtest for values in (1) +-- +TABLE: name="returningwrtest1" schema="" table="returningwrtest1" ctx=DDL +STMT: CreateStmt +== 381 +insert into returningwrtest values (1) returning returningwrtest +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 382 +-- check also that the wholerow vars in RETURNING list are converted as needed +alter table returningwrtest add b text +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: AlterTableStmt +== 383 +create table returningwrtest2 (b text, c int, a int) +-- +TABLE: name="returningwrtest2" schema="" table="returningwrtest2" ctx=DDL +STMT: CreateStmt +== 384 +alter table returningwrtest2 drop c +-- +TABLE: name="returningwrtest2" schema="" table="returningwrtest2" ctx=DDL +STMT: AlterTableStmt +== 385 +alter table returningwrtest attach partition returningwrtest2 for values in (2) +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: AlterTableStmt +== 386 +insert into returningwrtest values (2, 'foo') returning returningwrtest +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 387 +drop table returningwrtest +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/insert_conflict.metadata.json b/parser/testdata/summary/postgres_regress/insert_conflict.metadata.json new file mode 100644 index 0000000..1b73a29 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/insert_conflict.metadata.json @@ -0,0 +1,261 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257" + ] +} diff --git a/parser/testdata/summary/postgres_regress/insert_conflict.test b/parser/testdata/summary/postgres_regress/insert_conflict.test new file mode 100644 index 0000000..0486ff3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/insert_conflict.test @@ -0,0 +1,1691 @@ +== 001 +|-- +-- insert...on conflict do unique index inference +|-- +create table insertconflicttest(key int4, fruit text) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: CreateStmt +== 002 +-- These things should work through a view, as well +create view insertconflictview as select * from insertconflicttest +-- +TABLE: name="insertconflictview" schema="" table="insertconflictview" ctx=DDL +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 003 +|-- +-- Test unique index inference with operator class specifications and +-- named collations +|-- +create unique index op_index_key on insertconflicttest(key, fruit text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 004 +create unique index collation_index_key on insertconflicttest(key, fruit collate "C") +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 005 +create unique index both_index_key on insertconflicttest(key, fruit collate "C" text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 006 +create unique index both_index_expr_key on insertconflicttest(key, lower(fruit) collate "C" text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +== 007 +-- fails +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 008 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- succeeds +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 010 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 011 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 012 +explain (costs off) insert into insertconflictview values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing +-- +TABLE: name="insertconflictview" schema="" table="insertconflictview" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 013 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do update set fruit = excluded.fruit + where exists (select 1 from insertconflicttest ii where ii.key = excluded.key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=Select +ALIAS: "ii"="insertconflicttest" +FILTER: schema="" table="ii" column="key" +FILTER: schema="" table="excluded" column="key" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 014 +-- Neither collation nor operator class specifications are required -- +-- supplying them merely *limits* matches to indexes with matching opclasses +-- used for relevant indexes +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit text_pattern_ops) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 015 +-- Okay, arbitrates using both index where text_pattern_ops opclass does and +-- does not appear. +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit collate "C") do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 016 +-- Okay, but only accepts the single index where both opclass and collation are +-- specified +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit collate "C" text_pattern_ops, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 017 +-- Okay, but only accepts the single index where both opclass and collation are +-- specified (plus expression variant) +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C", key, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 018 +-- Attribute appears twice, while not all attributes/expressions on attributes +-- appearing within index definition match in terms of both opclass and +-- collation. +|-- +-- Works because every attribute in inference specification needs to be +-- satisfied once or more by cataloged index attribute, and as always when an +-- attribute in the cataloged definition has a non-default opclass/collation, +-- it still satisfied some inference attribute lacking any particular +-- opclass/collation specification. +|-- +-- The implementation is liberal in accepting inference specifications on the +-- assumption that multiple inferred unique indexes will prevent problematic +-- cases. It rolls with unique indexes where attributes redundantly appear +-- multiple times, too (which is not tested here). +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit text_pattern_ops, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 019 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C" text_pattern_ops, key, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 020 +drop index op_index_key +-- +STMT: DropStmt +== 021 +drop index collation_index_key +-- +STMT: DropStmt +== 022 +drop index both_index_key +-- +STMT: DropStmt +== 023 +drop index both_index_expr_key +-- +STMT: DropStmt +== 024 +|-- +-- Make sure that cross matching of attribute opclass/collation does not occur +|-- +create unique index cross_match on insertconflicttest(lower(fruit) collate "C", upper(fruit) text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: IndexStmt +== 025 +-- fails: +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) text_pattern_ops, upper(fruit) collate "C") do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 026 +-- works: +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C", upper(fruit) text_pattern_ops) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 027 +drop index cross_match +-- +STMT: DropStmt +== 028 +|-- +-- Single key tests +|-- +create unique index key_index on insertconflicttest(key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 029 +|-- +-- Explain tests +|-- +explain (costs off) insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 030 +-- Should display qual actually attributable to internal sequential scan: +explain (costs off) insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Cawesh' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 031 +-- With EXCLUDED.* expression in scan node: +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key) do update set fruit = excluded.fruit where excluded.fruit != 'Elderberry' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 032 +-- Does the same, but JSON format shows "Conflict Arbiter Index" as JSON array: +explain (costs off, format json) insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Lime' returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 033 +-- Fails (no unique index inference specification, required for do update variant): +insert into insertconflicttest values (1, 'Apple') on conflict do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +-- inference succeeds: +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +insert into insertconflicttest values (2, 'Orange') on conflict (key, key, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +-- Succeed, since multi-assignment does not involve subquery: +insert into insertconflicttest +values (1, 'Apple'), (2, 'Orange') +on conflict (key) do update set (fruit, key) = (excluded.fruit, excluded.key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +-- Give good diagnostic message when EXCLUDED.* spuriously referenced from +-- RETURNING: +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit RETURNING excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +-- Only suggest .* column when inference element misspelled: +insert into insertconflicttest values (1, 'Apple') on conflict (keyy) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +-- Have useful HINT for EXCLUDED.* RTE within UPDATE: +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruitt +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +-- inference fails: +insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +insert into insertconflicttest values (4, 'Mango') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +insert into insertconflicttest values (5, 'Lemon') on conflict (fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +insert into insertconflicttest values (6, 'Passionfruit') on conflict (lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 044 +-- Check the target relation can be aliased +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "ict"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 045 +-- ok, no reference to target table +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = ict.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "ict"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 046 +-- ok, alias +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = insertconflicttest.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "ict"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 047 +-- error, references aliased away name + +-- Check helpful hint when qualifying set column with target table +insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set insertconflicttest.fruit = 'Mango' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +drop index key_index +-- +STMT: DropStmt +== 049 +|-- +-- Composite key tests +|-- +create unique index comp_key_index on insertconflicttest(key, fruit) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 050 +-- inference succeeds: +insert into insertconflicttest values (7, 'Raspberry') on conflict (key, fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +insert into insertconflicttest values (8, 'Lime') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +-- inference fails: +insert into insertconflicttest values (9, 'Banana') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +insert into insertconflicttest values (10, 'Blueberry') on conflict (key, key, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +insert into insertconflicttest values (11, 'Cherry') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 055 +insert into insertconflicttest values (12, 'Date') on conflict (lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 056 +drop index comp_key_index +-- +STMT: DropStmt +== 057 +|-- +-- Partial index tests, no inference predicate specified +|-- +create unique index part_comp_key_index on insertconflicttest(key, fruit) where key < 5 +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 058 +create unique index expr_part_comp_key_index on insertconflicttest(key, lower(fruit)) where key < 5 +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +== 059 +-- inference fails: +insert into insertconflicttest values (13, 'Grape') on conflict (key, fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +insert into insertconflicttest values (14, 'Raisin') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +insert into insertconflicttest values (15, 'Cranberry') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +insert into insertconflicttest values (16, 'Melon') on conflict (key, key, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +insert into insertconflicttest values (17, 'Mulberry') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 064 +insert into insertconflicttest values (18, 'Pineapple') on conflict (lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 065 +drop index part_comp_key_index +-- +STMT: DropStmt +== 066 +drop index expr_part_comp_key_index +-- +STMT: DropStmt +== 067 +|-- +-- Expression index tests +|-- +create unique index expr_key_index on insertconflicttest(lower(fruit)) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +== 068 +-- inference succeeds: +insert into insertconflicttest values (20, 'Quince') on conflict (lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 069 +insert into insertconflicttest values (21, 'Pomegranate') on conflict (lower(fruit), lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 070 +-- inference fails: +insert into insertconflicttest values (22, 'Apricot') on conflict (upper(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 071 +insert into insertconflicttest values (23, 'Blackberry') on conflict (fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +drop index expr_key_index +-- +STMT: DropStmt +== 073 +|-- +-- Expression index tests (with regular column) +|-- +create unique index expr_comp_key_index on insertconflicttest(key, lower(fruit)) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +== 074 +create unique index tricky_expr_comp_key_index on insertconflicttest(key, lower(fruit), upper(fruit)) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: IndexStmt +== 075 +-- inference succeeds: +insert into insertconflicttest values (24, 'Plum') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 076 +insert into insertconflicttest values (25, 'Peach') on conflict (lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 077 +-- Should not infer "tricky_expr_comp_key_index" index: +explain (costs off) insert into insertconflicttest values (26, 'Fig') on conflict (lower(fruit), key, lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 078 +-- inference fails: +insert into insertconflicttest values (27, 'Prune') on conflict (key, upper(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 079 +insert into insertconflicttest values (28, 'Redcurrant') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +insert into insertconflicttest values (29, 'Nectarine') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +drop index expr_comp_key_index +-- +STMT: DropStmt +== 082 +drop index tricky_expr_comp_key_index +-- +STMT: DropStmt +== 083 +|-- +-- Non-spurious duplicate violation tests +|-- +create unique index key_index on insertconflicttest(key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 084 +create unique index fruit_index on insertconflicttest(fruit) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 085 +-- succeeds, since UPDATE happens to update "fruit" to existing value: +insert into insertconflicttest values (26, 'Fig') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 086 +-- fails, since UPDATE is to row with key value 26, and we're updating "fruit" +-- to a value that happens to exist in another row ('peach'): +insert into insertconflicttest values (26, 'Peach') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +-- succeeds, since "key" isn't repeated/referenced in UPDATE, and "fruit" +-- arbitrates that statement updates existing "Fig" row: +insert into insertconflicttest values (25, 'Fig') on conflict (fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +drop index key_index +-- +STMT: DropStmt +== 089 +drop index fruit_index +-- +STMT: DropStmt +== 090 +|-- +-- Test partial unique index inference +|-- +create unique index partial_key_index on insertconflicttest(key) where fruit like '%berry' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 091 +-- Succeeds +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like '%berry' do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +insert into insertconflicttest as t values (23, 'Blackberry') on conflict (key) where fruit like '%berry' and t.fruit = 'inconsequential' do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "t"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 093 +insert into insertconflictview as t values (23, 'Blackberry') on conflict (key) where fruit like '%berry' and t.fruit = 'inconsequential' do nothing +-- +TABLE: name="insertconflictview" schema="" table="insertconflictview" ctx=DML +ALIAS: "t"="insertconflictview" +STMT: InsertStmt +STMT: SelectStmt +== 094 +-- fails +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like '%berry' or fruit = 'consequential' do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +insert into insertconflicttest values (23, 'Blackberry') on conflict (fruit) where fruit like '%berry' do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +drop index partial_key_index +-- +STMT: DropStmt +== 098 +|-- +-- Test that wholerow references to ON CONFLICT's EXCLUDED work +|-- +create unique index plain on insertconflicttest(key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +== 099 +-- Succeeds, updates existing row: +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* != excluded.* returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 100 +-- No update this time, though: +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* != excluded.* returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 101 +-- Predicate changed to require match rather than non-match, so updates once more: +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* = excluded.* returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 102 +-- Assign: +insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text + returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +== 103 +-- deparse whole row var in WHERE and SET clauses: +explain (costs off) insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.fruit where excluded.* is null +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 104 +explain (costs off) insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 105 +drop index plain +-- +STMT: DropStmt +== 106 +-- Cleanup +drop view insertconflictview +-- +STMT: DropStmt +== 107 +drop table insertconflicttest +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: DropStmt +== 108 +|-- +-- Verify that EXCLUDED does not allow system column references. These +-- do not make sense because EXCLUDED isn't an already stored tuple +-- (and thus doesn't have a ctid etc). +|-- +create table syscolconflicttest(key int4, data text) +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DDL +STMT: CreateStmt +== 109 +insert into syscolconflicttest values (1) +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.ctid::text +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +drop table syscolconflicttest +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DDL +STMT: DropStmt +== 112 +|-- +-- Previous tests all managed to not test any expressions requiring +-- planner preprocessing ... +|-- +create table insertconflict (a bigint, b bigint) +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: CreateStmt +== 113 +create unique index insertconflicti1 on insertconflict(coalesce(a, 0)) +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: IndexStmt +== 114 +create unique index insertconflicti2 on insertconflict(b) + where coalesce(a, 1) > 0 +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: IndexStmt +== 115 +insert into insertconflict values (1, 2) +on conflict (coalesce(a, 0)) do nothing +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 0 do nothing +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 1 do nothing +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +drop table insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: DropStmt +== 119 +|-- +-- test insertion through view +|-- + +create table insertconflict (f1 int primary key, f2 text) +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: CreateStmt +== 120 +create view insertconflictv as + select * from insertconflict with cascaded check option +-- +TABLE: name="insertconflictv" schema="" table="insertconflictv" ctx=DDL +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 121 +insert into insertconflictv values (1,'foo') + on conflict (f1) do update set f2 = excluded.f2 +-- +TABLE: name="insertconflictv" schema="" table="insertconflictv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +select * from insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=Select +STMT: SelectStmt +== 123 +insert into insertconflictv values (1,'bar') + on conflict (f1) do update set f2 = excluded.f2 +-- +TABLE: name="insertconflictv" schema="" table="insertconflictv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 124 +select * from insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=Select +STMT: SelectStmt +== 125 +drop view insertconflictv +-- +STMT: DropStmt +== 126 +drop table insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: DropStmt +== 127 +-- ****************************************************************** +-- * * +-- * Test inheritance (example taken from tutorial) * +-- * * +-- ****************************************************************** +create table cities ( + name text, + population float8, + altitude int -- (in ft) +) +-- +TABLE: name="cities" schema="" table="cities" ctx=DDL +STMT: CreateStmt +== 128 +create table capitals ( + state char(2) +) inherits (cities) +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DDL +STMT: CreateStmt +== 129 +-- Create unique indexes. Due to a general limitation of inheritance, +-- uniqueness is only enforced per-relation. Unique index inference +-- specification will do the right thing, though. +create unique index cities_names_unique on cities (name) +-- +TABLE: name="cities" schema="" table="cities" ctx=DDL +STMT: IndexStmt +== 130 +create unique index capitals_names_unique on capitals (name) +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DDL +STMT: IndexStmt +== 131 +-- prepopulate the tables. +insert into cities values ('San Francisco', 7.24E+5, 63) +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 132 +insert into cities values ('Las Vegas', 2.583E+5, 2174) +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +insert into cities values ('Mariposa', 1200, 1953) +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 134 +insert into capitals values ('Sacramento', 3.694E+5, 30, 'CA') +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 135 +insert into capitals values ('Madison', 1.913E+5, 845, 'WI') +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +-- Tests proper for inheritance: +select * from capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=Select +STMT: SelectStmt +== 137 +-- Succeeds: +insert into cities values ('Las Vegas', 2.583E+5, 2174) on conflict do nothing +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +insert into capitals values ('Sacramento', 4664.E+5, 30, 'CA') on conflict (name) do update set population = excluded.population +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +-- Wrong "Sacramento", so do nothing: +insert into capitals values ('Sacramento', 50, 2267, 'NE') on conflict (name) do nothing +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 140 +select * from capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=Select +STMT: SelectStmt +== 141 +insert into cities values ('Las Vegas', 5.83E+5, 2001) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +select tableoid::regclass, * from cities +-- +TABLE: name="cities" schema="" table="cities" ctx=Select +STMT: SelectStmt +== 143 +insert into capitals values ('Las Vegas', 5.83E+5, 2222, 'NV') on conflict (name) do update set population = excluded.population +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +-- Capitals will contain new capital, Las Vegas: +select * from capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=Select +STMT: SelectStmt +== 145 +-- Cities contains two instances of "Las Vegas", since unique constraints don't +-- work across inheritance: +select tableoid::regclass, * from cities +-- +TABLE: name="cities" schema="" table="cities" ctx=Select +STMT: SelectStmt +== 146 +-- This only affects "cities" version of "Las Vegas": +insert into cities values ('Las Vegas', 5.86E+5, 2223) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +select tableoid::regclass, * from cities +-- +TABLE: name="cities" schema="" table="cities" ctx=Select +STMT: SelectStmt +== 148 +-- clean up +drop table capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DDL +STMT: DropStmt +== 149 +drop table cities +-- +TABLE: name="cities" schema="" table="cities" ctx=DDL +STMT: DropStmt +== 150 +-- Make sure a table named excluded is handled properly +create table excluded(key int primary key, data text) +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DDL +STMT: CreateStmt +== 151 +insert into excluded values(1, '1') +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +-- error, ambiguous +insert into excluded values(1, '2') on conflict (key) do update set data = excluded.data RETURNING * +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 153 +-- ok, aliased +insert into excluded AS target values(1, '2') on conflict (key) do update set data = excluded.data RETURNING * +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +ALIAS: "target"="excluded" +STMT: InsertStmt +STMT: SelectStmt +== 154 +-- ok, aliased +insert into excluded AS target values(1, '2') on conflict (key) do update set data = target.data RETURNING * +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +ALIAS: "target"="excluded" +STMT: InsertStmt +STMT: SelectStmt +== 155 +-- make sure excluded isn't a problem in returning clause +insert into excluded values(1, '2') on conflict (key) do update set data = 3 RETURNING excluded.* +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +-- clean up +drop table excluded +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DDL +STMT: DropStmt +== 157 +-- check that references to columns after dropped columns are handled correctly +create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float) +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DDL +STMT: CreateStmt +== 158 +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1) +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +-- set using excluded +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 2, '2', '2', 2) on conflict(key) + do update set drop1 = excluded.drop1, keep1 = excluded.keep1, drop2 = excluded.drop2, keep2 = excluded.keep2 + where excluded.drop1 is not null and excluded.keep1 is not null and excluded.drop2 is not null and excluded.keep2 is not null + and dropcol.drop1 is not null and dropcol.keep1 is not null and dropcol.drop2 is not null and dropcol.keep2 is not null + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +-- set using existing table +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 3, '3', '3', 3) on conflict(key) + do update set drop1 = dropcol.drop1, keep1 = dropcol.keep1, drop2 = dropcol.drop2, keep2 = dropcol.keep2 + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 161 +alter table dropcol drop column drop1, drop column drop2 +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DDL +STMT: AlterTableStmt +== 162 +-- set using excluded +insert into dropcol(key, keep1, keep2) values(1, '4', 4) on conflict(key) + do update set keep1 = excluded.keep1, keep2 = excluded.keep2 + where excluded.keep1 is not null and excluded.keep2 is not null + and dropcol.keep1 is not null and dropcol.keep2 is not null + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +-- set using existing table +insert into dropcol(key, keep1, keep2) values(1, '5', 5) on conflict(key) + do update set keep1 = dropcol.keep1, keep2 = dropcol.keep2 + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +DROP TABLE dropcol +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DDL +STMT: DropStmt +== 165 +-- check handling of regular btree constraint along with gist constraint + +create table twoconstraints (f1 int unique, f2 box, + exclude using gist(f2 with &&)) +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DDL +STMT: CreateStmt +== 166 +insert into twoconstraints values(1, '((0,0),(1,1))') +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 167 +insert into twoconstraints values(1, '((2,2),(3,3))') +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +-- fail on f1 +insert into twoconstraints values(2, '((0,0),(1,2))') +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +-- fail on f2 +insert into twoconstraints values(2, '((0,0),(1,2))') + on conflict on constraint twoconstraints_f1_key do nothing +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 170 +-- fail on f2 +insert into twoconstraints values(2, '((0,0),(1,2))') + on conflict on constraint twoconstraints_f2_excl do nothing +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 171 +-- do nothing +select * from twoconstraints +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=Select +STMT: SelectStmt +== 172 +drop table twoconstraints +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DDL +STMT: DropStmt +== 173 +-- check handling of self-conflicts at various isolation levels + +create table selfconflict (f1 int primary key, f2 int) +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DDL +STMT: CreateStmt +== 174 +begin transaction isolation level read committed +-- +STMT: TransactionStmt +== 175 +insert into selfconflict values (1,1), (1,2) on conflict do nothing +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 176 +commit +-- +STMT: TransactionStmt +== 177 +begin transaction isolation level repeatable read +-- +STMT: TransactionStmt +== 178 +insert into selfconflict values (2,1), (2,2) on conflict do nothing +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 179 +commit +-- +STMT: TransactionStmt +== 180 +begin transaction isolation level serializable +-- +STMT: TransactionStmt +== 181 +insert into selfconflict values (3,1), (3,2) on conflict do nothing +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 182 +commit +-- +STMT: TransactionStmt +== 183 +begin transaction isolation level read committed +-- +STMT: TransactionStmt +== 184 +insert into selfconflict values (4,1), (4,2) on conflict(f1) do update set f2 = 0 +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +commit +-- +STMT: TransactionStmt +== 186 +begin transaction isolation level repeatable read +-- +STMT: TransactionStmt +== 187 +insert into selfconflict values (5,1), (5,2) on conflict(f1) do update set f2 = 0 +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +commit +-- +STMT: TransactionStmt +== 189 +begin transaction isolation level serializable +-- +STMT: TransactionStmt +== 190 +insert into selfconflict values (6,1), (6,2) on conflict(f1) do update set f2 = 0 +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +commit +-- +STMT: TransactionStmt +== 192 +select * from selfconflict +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=Select +STMT: SelectStmt +== 193 +drop table selfconflict +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DDL +STMT: DropStmt +== 194 +-- check ON CONFLICT handling with partitioned tables +create table parted_conflict_test (a int unique, b char) partition by list (a) +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: CreateStmt +== 195 +create table parted_conflict_test_1 partition of parted_conflict_test (b unique) for values in (1, 2) +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DDL +STMT: CreateStmt +== 196 +-- no indexes required here +insert into parted_conflict_test values (1, 'a') on conflict do nothing +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 197 +-- index on a required, which does exist in parent +insert into parted_conflict_test values (1, 'a') on conflict (a) do nothing +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 198 +insert into parted_conflict_test values (1, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 199 +-- targeting partition directly will work +insert into parted_conflict_test_1 values (1, 'a') on conflict (a) do nothing +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 200 +insert into parted_conflict_test_1 values (1, 'b') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +-- index on b required, which doesn't exist in parent +insert into parted_conflict_test values (2, 'b') on conflict (b) do update set a = excluded.a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +-- targeting partition directly will work +insert into parted_conflict_test_1 values (2, 'b') on conflict (b) do update set a = excluded.a +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +-- should see (2, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +== 204 +-- now check that DO UPDATE works correctly for target partition with +-- different attribute numbers +create table parted_conflict_test_2 (b char, a int unique) +-- +TABLE: name="parted_conflict_test_2" schema="" table="parted_conflict_test_2" ctx=DDL +STMT: CreateStmt +== 205 +alter table parted_conflict_test attach partition parted_conflict_test_2 for values in (3) +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: AlterTableStmt +== 206 +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +== 207 +insert into parted_conflict_test values (3, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 208 +insert into parted_conflict_test values (3, 'b') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 209 +-- should see (3, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +== 210 +-- case where parent will have a dropped column, but the partition won't +alter table parted_conflict_test drop b, add b char +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: AlterTableStmt +== 211 +create table parted_conflict_test_3 partition of parted_conflict_test for values in (4) +-- +TABLE: name="parted_conflict_test_3" schema="" table="parted_conflict_test_3" ctx=DDL +STMT: CreateStmt +== 212 +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +== 213 +insert into parted_conflict_test (a, b) values (4, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 214 +insert into parted_conflict_test (a, b) values (4, 'b') on conflict (a) do update set b = excluded.b where parted_conflict_test.b = 'a' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +-- should see (4, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +== 216 +-- case with multi-level partitioning +create table parted_conflict_test_4 partition of parted_conflict_test for values in (5) partition by list (a) +-- +TABLE: name="parted_conflict_test_4" schema="" table="parted_conflict_test_4" ctx=DDL +STMT: CreateStmt +== 217 +create table parted_conflict_test_4_1 partition of parted_conflict_test_4 for values in (5) +-- +TABLE: name="parted_conflict_test_4_1" schema="" table="parted_conflict_test_4_1" ctx=DDL +STMT: CreateStmt +== 218 +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +== 219 +insert into parted_conflict_test (a, b) values (5, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 220 +insert into parted_conflict_test (a, b) values (5, 'b') on conflict (a) do update set b = excluded.b where parted_conflict_test.b = 'a' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 221 +-- should see (5, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +== 222 +-- test with multiple rows +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +== 223 +insert into parted_conflict_test (a, b) values (1, 'a'), (2, 'a'), (4, 'a') on conflict (a) do update set b = excluded.b where excluded.b = 'b' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 224 +insert into parted_conflict_test (a, b) values (1, 'b'), (2, 'c'), (4, 'b') on conflict (a) do update set b = excluded.b where excluded.b = 'b' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +-- should see (1, 'b'), (2, 'a'), (4, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +== 226 +drop table parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: DropStmt +== 227 +-- test behavior of inserting a conflicting tuple into an intermediate +-- partitioning level +create table parted_conflict (a int primary key, b text) partition by range (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateStmt +== 228 +create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: CreateStmt +== 229 +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500) +-- +TABLE: name="parted_conflict_1_1" schema="" table="parted_conflict_1_1" ctx=DDL +STMT: CreateStmt +== 230 +insert into parted_conflict values (40, 'forty') +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 231 +insert into parted_conflict_1 values (40, 'cuarenta') + on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 232 +drop table parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: DropStmt +== 233 +-- same thing, but this time try to use an index that's created not in the +-- partition +create table parted_conflict (a int, b text) partition by range (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateStmt +== 234 +create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: CreateStmt +== 235 +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500) +-- +TABLE: name="parted_conflict_1_1" schema="" table="parted_conflict_1_1" ctx=DDL +STMT: CreateStmt +== 236 +create unique index on only parted_conflict_1 (a) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: IndexStmt +== 237 +create unique index on only parted_conflict (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: IndexStmt +== 238 +alter index parted_conflict_a_idx attach partition parted_conflict_1_a_idx +-- +STMT: AlterTableStmt +== 239 +insert into parted_conflict values (40, 'forty') +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +insert into parted_conflict_1 values (40, 'cuarenta') + on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 241 +drop table parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: DropStmt +== 242 +-- test whole-row Vars in ON CONFLICT expressions +create table parted_conflict (a int, b text, c int) partition by range (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateStmt +== 243 +create table parted_conflict_1 (drp text, c int, a int, b text) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: CreateStmt +== 244 +alter table parted_conflict_1 drop column drp +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: AlterTableStmt +== 245 +create unique index on parted_conflict (a, b) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: IndexStmt +== 246 +alter table parted_conflict attach partition parted_conflict_1 for values from (0) to (1000) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: AlterTableStmt +== 247 +truncate parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: TruncateStmt +== 248 +insert into parted_conflict values (50, 'cincuenta', 1) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 249 +insert into parted_conflict values (50, 'cincuenta', 2) + on conflict (a, b) do update set (a, b, c) = row(excluded.*) + where parted_conflict = (50, text 'cincuenta', 1) and + excluded = (50, text 'cincuenta', 2) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 250 +-- should see (50, 'cincuenta', 2) +select * from parted_conflict order by a +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=Select +STMT: SelectStmt +== 251 +-- test with statement level triggers +create or replace function parted_conflict_update_func() returns trigger as $$ +declare + r record; +begin + for r in select * from inserted loop + raise notice 'a = %, b = %, c = %', r.a, r.b, r.c; + end loop; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="parted_conflict_update_func" function="parted_conflict_update_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 252 +create trigger parted_conflict_update + after update on parted_conflict + referencing new table as inserted + for each statement + execute procedure parted_conflict_update_func() +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateTrigStmt +== 253 +truncate parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: TruncateStmt +== 254 +insert into parted_conflict values (0, 'cero', 1) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 255 +insert into parted_conflict values(0, 'cero', 1) + on conflict (a,b) do update set c = parted_conflict.c + 1 +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 256 +drop table parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: DropStmt +== 257 +drop function parted_conflict_update_func() +-- +FUNCTION: name="parted_conflict_update_func" function="parted_conflict_update_func" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/int2.metadata.json b/parser/testdata/summary/postgres_regress/int2.metadata.json new file mode 100644 index 0000000..f476ef8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/int2.metadata.json @@ -0,0 +1,80 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076" + ] +} diff --git a/parser/testdata/summary/postgres_regress/int2.test b/parser/testdata/summary/postgres_regress/int2.test new file mode 100644 index 0000000..8cab4b8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/int2.test @@ -0,0 +1,438 @@ +== 001 +|-- +-- INT2 +|-- + +-- int2_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO INT2_TBL(f1) VALUES ('34.5') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 002 +INSERT INTO INT2_TBL(f1) VALUES ('100000') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO INT2_TBL(f1) VALUES ('asdf') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO INT2_TBL(f1) VALUES (' ') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO INT2_TBL(f1) VALUES ('- 1234') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO INT2_TBL(f1) VALUES ('4 444') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO INT2_TBL(f1) VALUES ('123 dt') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO INT2_TBL(f1) VALUES ('') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +SELECT * FROM INT2_TBL +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +STMT: SelectStmt +== 010 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34', 'int2') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT pg_input_is_valid('asdf', 'int2') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT pg_input_is_valid('50000', 'int2') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT * FROM pg_input_error_info('50000', 'int2') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- While we're here, check int2vector as well +SELECT pg_input_is_valid(' 1 3 5 ', 'int2vector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT * FROM pg_input_error_info('1 asdf', 'int2vector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT * FROM pg_input_error_info('50000', 'int2vector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT * FROM INT2_TBL AS f(a, b) +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "f"="int2_tbl" +STMT: SelectStmt +== 018 +SELECT * FROM (TABLE int2_tbl) AS s (a, b) +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +STMT: SelectStmt +== 019 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <> int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 020 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <> int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 021 +SELECT i.* FROM INT2_TBL i WHERE i.f1 = int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 022 +SELECT i.* FROM INT2_TBL i WHERE i.f1 = int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 023 +SELECT i.* FROM INT2_TBL i WHERE i.f1 < int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 024 +SELECT i.* FROM INT2_TBL i WHERE i.f1 < int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 025 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <= int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 026 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <= int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 027 +SELECT i.* FROM INT2_TBL i WHERE i.f1 > int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 028 +SELECT i.* FROM INT2_TBL i WHERE i.f1 > int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 029 +SELECT i.* FROM INT2_TBL i WHERE i.f1 >= int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 030 +SELECT i.* FROM INT2_TBL i WHERE i.f1 >= int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 031 +-- positive odds +SELECT i.* FROM INT2_TBL i WHERE (i.f1 % int2 '2') = int2 '1' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 032 +-- any evens +SELECT i.* FROM INT2_TBL i WHERE (i.f1 % int4 '2') = int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 033 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 034 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i +WHERE abs(f1) < 16384 +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 035 +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 036 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 037 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i +WHERE f1 < 32766 +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 038 +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 039 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 040 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i +WHERE f1 > -32767 +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 041 +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 042 +SELECT i.f1, i.f1 / int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 043 +SELECT i.f1, i.f1 / int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +== 044 +-- corner cases +SELECT (-1::int2<<15)::text +-- +STMT: SelectStmt +== 045 +SELECT ((-1::int2<<15)+1::int2)::text +-- +STMT: SelectStmt +== 046 +-- check sane handling of INT16_MIN overflow cases +SELECT (-32768)::int2 * (-1)::int2 +-- +STMT: SelectStmt +== 047 +SELECT (-32768)::int2 / (-1)::int2 +-- +STMT: SelectStmt +== 048 +SELECT (-32768)::int2 % (-1)::int2 +-- +STMT: SelectStmt +== 049 +-- check rounding when casting from float +SELECT x, x::int2 AS int2_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x) +-- +STMT: SelectStmt +== 050 +-- check rounding when casting from numeric +SELECT x, x::int2 AS int2_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x) +-- +STMT: SelectStmt +== 051 +-- non-decimal literals + +SELECT int2 '0b100101' +-- +STMT: SelectStmt +== 052 +SELECT int2 '0o273' +-- +STMT: SelectStmt +== 053 +SELECT int2 '0x42F' +-- +STMT: SelectStmt +== 054 +SELECT int2 '0b' +-- +STMT: SelectStmt +== 055 +SELECT int2 '0o' +-- +STMT: SelectStmt +== 056 +SELECT int2 '0x' +-- +STMT: SelectStmt +== 057 +-- cases near overflow +SELECT int2 '0b111111111111111' +-- +STMT: SelectStmt +== 058 +SELECT int2 '0b1000000000000000' +-- +STMT: SelectStmt +== 059 +SELECT int2 '0o77777' +-- +STMT: SelectStmt +== 060 +SELECT int2 '0o100000' +-- +STMT: SelectStmt +== 061 +SELECT int2 '0x7FFF' +-- +STMT: SelectStmt +== 062 +SELECT int2 '0x8000' +-- +STMT: SelectStmt +== 063 +SELECT int2 '-0b1000000000000000' +-- +STMT: SelectStmt +== 064 +SELECT int2 '-0b1000000000000001' +-- +STMT: SelectStmt +== 065 +SELECT int2 '-0o100000' +-- +STMT: SelectStmt +== 066 +SELECT int2 '-0o100001' +-- +STMT: SelectStmt +== 067 +SELECT int2 '-0x8000' +-- +STMT: SelectStmt +== 068 +SELECT int2 '-0x8001' +-- +STMT: SelectStmt +== 069 +-- underscores + +SELECT int2 '1_000' +-- +STMT: SelectStmt +== 070 +SELECT int2 '1_2_3' +-- +STMT: SelectStmt +== 071 +SELECT int2 '0xE_FF' +-- +STMT: SelectStmt +== 072 +SELECT int2 '0o2_73' +-- +STMT: SelectStmt +== 073 +SELECT int2 '0b_10_0101' +-- +STMT: SelectStmt +== 074 +-- error cases +SELECT int2 '_100' +-- +STMT: SelectStmt +== 075 +SELECT int2 '100_' +-- +STMT: SelectStmt +== 076 +SELECT int2 '10__000' +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/int4.metadata.json b/parser/testdata/summary/postgres_regress/int4.metadata.json new file mode 100644 index 0000000..da94530 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/int4.metadata.json @@ -0,0 +1,98 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094" + ] +} diff --git a/parser/testdata/summary/postgres_regress/int4.test b/parser/testdata/summary/postgres_regress/int4.test new file mode 100644 index 0000000..e1f39ce --- /dev/null +++ b/parser/testdata/summary/postgres_regress/int4.test @@ -0,0 +1,556 @@ +== 001 +|-- +-- INT4 +|-- + +-- int4_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO INT4_TBL(f1) VALUES ('34.5') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 002 +INSERT INTO INT4_TBL(f1) VALUES ('1000000000000') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO INT4_TBL(f1) VALUES ('asdf') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO INT4_TBL(f1) VALUES (' ') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO INT4_TBL(f1) VALUES (' asdf ') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO INT4_TBL(f1) VALUES ('- 1234') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO INT4_TBL(f1) VALUES ('123 5') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO INT4_TBL(f1) VALUES ('') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +SELECT * FROM INT4_TBL +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 010 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34', 'int4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT pg_input_is_valid('asdf', 'int4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT pg_input_is_valid('1000000000000', 'int4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT * FROM pg_input_error_info('1000000000000', 'int4') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 015 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 016 +SELECT i.* FROM INT4_TBL i WHERE i.f1 = int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 017 +SELECT i.* FROM INT4_TBL i WHERE i.f1 = int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 018 +SELECT i.* FROM INT4_TBL i WHERE i.f1 < int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 019 +SELECT i.* FROM INT4_TBL i WHERE i.f1 < int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 020 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <= int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 021 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <= int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 022 +SELECT i.* FROM INT4_TBL i WHERE i.f1 > int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 023 +SELECT i.* FROM INT4_TBL i WHERE i.f1 > int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 024 +SELECT i.* FROM INT4_TBL i WHERE i.f1 >= int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 025 +SELECT i.* FROM INT4_TBL i WHERE i.f1 >= int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 026 +-- positive odds +SELECT i.* FROM INT4_TBL i WHERE (i.f1 % int2 '2') = int2 '1' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 027 +-- any evens +SELECT i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +== 028 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 029 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i +WHERE abs(f1) < 1073741824 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 030 +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 031 +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i +WHERE abs(f1) < 1073741824 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 032 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 033 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i +WHERE f1 < 2147483646 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 034 +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 035 +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i +WHERE f1 < 2147483646 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 036 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 037 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i +WHERE f1 > -2147483647 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 038 +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 039 +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i +WHERE f1 > -2147483647 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 040 +SELECT i.f1, i.f1 / int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 041 +SELECT i.f1, i.f1 / int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +== 042 +|-- +-- more complex expressions +|-- + +-- variations on unary minus parsing +SELECT -2+3 AS one +-- +STMT: SelectStmt +== 043 +SELECT 4-2 AS two +-- +STMT: SelectStmt +== 044 +SELECT 2- -1 AS three +-- +STMT: SelectStmt +== 045 +SELECT 2 - -2 AS four +-- +STMT: SelectStmt +== 046 +SELECT int2 '2' * int2 '2' = int2 '16' / int2 '4' AS true +-- +STMT: SelectStmt +== 047 +SELECT int4 '2' * int2 '2' = int2 '16' / int4 '4' AS true +-- +STMT: SelectStmt +== 048 +SELECT int2 '2' * int4 '2' = int4 '16' / int2 '4' AS true +-- +STMT: SelectStmt +== 049 +SELECT int4 '1000' < int4 '999' AS false +-- +STMT: SelectStmt +== 050 +SELECT 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 AS ten +-- +STMT: SelectStmt +== 051 +SELECT 2 + 2 / 2 AS three +-- +STMT: SelectStmt +== 052 +SELECT (2 + 2) / 2 AS two +-- +STMT: SelectStmt +== 053 +-- corner case +SELECT (-1::int4<<31)::text +-- +STMT: SelectStmt +== 054 +SELECT ((-1::int4<<31)+1)::text +-- +STMT: SelectStmt +== 055 +-- check sane handling of INT_MIN overflow cases +SELECT (-2147483648)::int4 * (-1)::int4 +-- +STMT: SelectStmt +== 056 +SELECT (-2147483648)::int4 / (-1)::int4 +-- +STMT: SelectStmt +== 057 +SELECT (-2147483648)::int4 % (-1)::int4 +-- +STMT: SelectStmt +== 058 +SELECT (-2147483648)::int4 * (-1)::int2 +-- +STMT: SelectStmt +== 059 +SELECT (-2147483648)::int4 / (-1)::int2 +-- +STMT: SelectStmt +== 060 +SELECT (-2147483648)::int4 % (-1)::int2 +-- +STMT: SelectStmt +== 061 +-- check rounding when casting from float +SELECT x, x::int4 AS int4_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x) +-- +STMT: SelectStmt +== 062 +-- check rounding when casting from numeric +SELECT x, x::int4 AS int4_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x) +-- +STMT: SelectStmt +== 063 +-- test gcd() +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(b, a), gcd(-b, a) +FROM (VALUES (0::int4, 0::int4), + (0::int4, 6410818::int4), + (61866666::int4, 6410818::int4), + (-61866666::int4, 6410818::int4), + ((-2147483648)::int4, 1::int4), + ((-2147483648)::int4, 2147483647::int4), + ((-2147483648)::int4, 1073741824::int4)) AS v(a, b) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT gcd((-2147483648)::int4, 0::int4) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +== 065 +-- overflow +SELECT gcd((-2147483648)::int4, (-2147483648)::int4) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +== 066 +-- overflow + +-- test lcm() +SELECT a, b, lcm(a, b), lcm(a, -b), lcm(b, a), lcm(-b, a) +FROM (VALUES (0::int4, 0::int4), + (0::int4, 42::int4), + (42::int4, 42::int4), + (330::int4, 462::int4), + (-330::int4, 462::int4), + ((-2147483648)::int4, 0::int4)) AS v(a, b) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT lcm((-2147483648)::int4, 1::int4) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 068 +-- overflow +SELECT lcm(2147483647::int4, 2147483646::int4) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 069 +-- overflow + + +-- non-decimal literals + +SELECT int4 '0b100101' +-- +STMT: SelectStmt +== 070 +SELECT int4 '0o273' +-- +STMT: SelectStmt +== 071 +SELECT int4 '0x42F' +-- +STMT: SelectStmt +== 072 +SELECT int4 '0b' +-- +STMT: SelectStmt +== 073 +SELECT int4 '0o' +-- +STMT: SelectStmt +== 074 +SELECT int4 '0x' +-- +STMT: SelectStmt +== 075 +-- cases near overflow +SELECT int4 '0b1111111111111111111111111111111' +-- +STMT: SelectStmt +== 076 +SELECT int4 '0b10000000000000000000000000000000' +-- +STMT: SelectStmt +== 077 +SELECT int4 '0o17777777777' +-- +STMT: SelectStmt +== 078 +SELECT int4 '0o20000000000' +-- +STMT: SelectStmt +== 079 +SELECT int4 '0x7FFFFFFF' +-- +STMT: SelectStmt +== 080 +SELECT int4 '0x80000000' +-- +STMT: SelectStmt +== 081 +SELECT int4 '-0b10000000000000000000000000000000' +-- +STMT: SelectStmt +== 082 +SELECT int4 '-0b10000000000000000000000000000001' +-- +STMT: SelectStmt +== 083 +SELECT int4 '-0o20000000000' +-- +STMT: SelectStmt +== 084 +SELECT int4 '-0o20000000001' +-- +STMT: SelectStmt +== 085 +SELECT int4 '-0x80000000' +-- +STMT: SelectStmt +== 086 +SELECT int4 '-0x80000001' +-- +STMT: SelectStmt +== 087 +-- underscores + +SELECT int4 '1_000_000' +-- +STMT: SelectStmt +== 088 +SELECT int4 '1_2_3' +-- +STMT: SelectStmt +== 089 +SELECT int4 '0x1EEE_FFFF' +-- +STMT: SelectStmt +== 090 +SELECT int4 '0o2_73' +-- +STMT: SelectStmt +== 091 +SELECT int4 '0b_10_0101' +-- +STMT: SelectStmt +== 092 +-- error cases +SELECT int4 '_100' +-- +STMT: SelectStmt +== 093 +SELECT int4 '100_' +-- +STMT: SelectStmt +== 094 +SELECT int4 '100__000' +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/int8.metadata.json b/parser/testdata/summary/postgres_regress/int8.metadata.json new file mode 100644 index 0000000..6eafe87 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/int8.metadata.json @@ -0,0 +1,171 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167" + ] +} diff --git a/parser/testdata/summary/postgres_regress/int8.test b/parser/testdata/summary/postgres_regress/int8.test new file mode 100644 index 0000000..e2c8a3d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/int8.test @@ -0,0 +1,921 @@ +== 001 +|-- +-- INT8 +-- Test int8 64-bit integers. +|-- + +-- int8_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO INT8_TBL(q1) VALUES (' ') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 002 +INSERT INTO INT8_TBL(q1) VALUES ('xxx') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO INT8_TBL(q1) VALUES ('- 123') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO INT8_TBL(q1) VALUES (' 345 5') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO INT8_TBL(q1) VALUES ('') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +SELECT * FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 009 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34', 'int8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT pg_input_is_valid('asdf', 'int8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT pg_input_is_valid('10000000000000000000', 'int8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT * FROM pg_input_error_info('10000000000000000000', 'int8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- int8/int8 cmp +SELECT * FROM INT8_TBL WHERE q2 = 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 014 +SELECT * FROM INT8_TBL WHERE q2 <> 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 015 +SELECT * FROM INT8_TBL WHERE q2 < 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 016 +SELECT * FROM INT8_TBL WHERE q2 > 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 017 +SELECT * FROM INT8_TBL WHERE q2 <= 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 018 +SELECT * FROM INT8_TBL WHERE q2 >= 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 019 +-- int8/int4 cmp +SELECT * FROM INT8_TBL WHERE q2 = 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 020 +SELECT * FROM INT8_TBL WHERE q2 <> 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 021 +SELECT * FROM INT8_TBL WHERE q2 < 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 022 +SELECT * FROM INT8_TBL WHERE q2 > 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 023 +SELECT * FROM INT8_TBL WHERE q2 <= 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 024 +SELECT * FROM INT8_TBL WHERE q2 >= 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 025 +-- int4/int8 cmp +SELECT * FROM INT8_TBL WHERE 123 = q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 026 +SELECT * FROM INT8_TBL WHERE 123 <> q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 027 +SELECT * FROM INT8_TBL WHERE 123 < q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 028 +SELECT * FROM INT8_TBL WHERE 123 > q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 029 +SELECT * FROM INT8_TBL WHERE 123 <= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 030 +SELECT * FROM INT8_TBL WHERE 123 >= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 031 +-- int8/int2 cmp +SELECT * FROM INT8_TBL WHERE q2 = '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 032 +SELECT * FROM INT8_TBL WHERE q2 <> '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 033 +SELECT * FROM INT8_TBL WHERE q2 < '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 034 +SELECT * FROM INT8_TBL WHERE q2 > '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 035 +SELECT * FROM INT8_TBL WHERE q2 <= '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 036 +SELECT * FROM INT8_TBL WHERE q2 >= '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 037 +-- int2/int8 cmp +SELECT * FROM INT8_TBL WHERE '123'::int2 = q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 038 +SELECT * FROM INT8_TBL WHERE '123'::int2 <> q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 039 +SELECT * FROM INT8_TBL WHERE '123'::int2 < q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 040 +SELECT * FROM INT8_TBL WHERE '123'::int2 > q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 041 +SELECT * FROM INT8_TBL WHERE '123'::int2 <= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 042 +SELECT * FROM INT8_TBL WHERE '123'::int2 >= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 043 +SELECT q1 AS plus, -q1 AS minus FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 044 +SELECT q1, q2, q1 + q2 AS plus FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 045 +SELECT q1, q2, q1 - q2 AS minus FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 046 +SELECT q1, q2, q1 * q2 AS multiply FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 047 +SELECT q1, q2, q1 * q2 AS multiply FROM INT8_TBL + WHERE q1 < 1000 or (q2 > 0 and q2 < 1000) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 048 +SELECT q1, q2, q1 / q2 AS divide, q1 % q2 AS mod FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 049 +SELECT q1, float8(q1) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="float8" function="float8" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT q2, float8(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="float8" function="float8" schema="" ctx=Call +STMT: SelectStmt +== 051 +SELECT 37 + q1 AS plus4 FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 052 +SELECT 37 - q1 AS minus4 FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 053 +SELECT 2 * q1 AS "twice int4" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 054 +SELECT q1 * 2 AS "twice int4" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 055 +-- int8 op int4 +SELECT q1 + 42::int4 AS "8plus4", q1 - 42::int4 AS "8minus4", q1 * 42::int4 AS "8mul4", q1 / 42::int4 AS "8div4" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 056 +-- int4 op int8 +SELECT 246::int4 + q1 AS "4plus8", 246::int4 - q1 AS "4minus8", 246::int4 * q1 AS "4mul8", 246::int4 / q1 AS "4div8" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 057 +-- int8 op int2 +SELECT q1 + 42::int2 AS "8plus2", q1 - 42::int2 AS "8minus2", q1 * 42::int2 AS "8mul2", q1 / 42::int2 AS "8div2" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 058 +-- int2 op int8 +SELECT 246::int2 + q1 AS "2plus8", 246::int2 - q1 AS "2minus8", 246::int2 * q1 AS "2mul8", 246::int2 / q1 AS "2div8" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 059 +SELECT q2, abs(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT min(q1), min(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT max(q1), max(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 062 +-- TO_CHAR() +|-- +SELECT to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT to_char(q2, 'MI9999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT to_char(q2, 'FMS9999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT to_char(q2, 'SG9999999999999999th') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT to_char(q2, '0999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT to_char(q2, 'S0999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT to_char(q2, 'FM0999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 073 +SELECT to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT to_char(q2, 'L9999999999999999.000') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 075 +SELECT to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 077 +SELECT to_char(q2, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT to_char(q2, '999999SG9999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 079 +-- check min/max values and overflow behavior + +select '-9223372036854775808'::int8 +-- +STMT: SelectStmt +== 080 +select '-9223372036854775809'::int8 +-- +STMT: SelectStmt +== 081 +select '9223372036854775807'::int8 +-- +STMT: SelectStmt +== 082 +select '9223372036854775808'::int8 +-- +STMT: SelectStmt +== 083 +select -('-9223372036854775807'::int8) +-- +STMT: SelectStmt +== 084 +select -('-9223372036854775808'::int8) +-- +STMT: SelectStmt +== 085 +select 0::int8 - '-9223372036854775808'::int8 +-- +STMT: SelectStmt +== 086 +select '9223372036854775800'::int8 + '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 087 +select '-9223372036854775800'::int8 + '-9223372036854775800'::int8 +-- +STMT: SelectStmt +== 088 +select '9223372036854775800'::int8 - '-9223372036854775800'::int8 +-- +STMT: SelectStmt +== 089 +select '-9223372036854775800'::int8 - '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 090 +select '9223372036854775800'::int8 * '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 091 +select '9223372036854775800'::int8 / '0'::int8 +-- +STMT: SelectStmt +== 092 +select '9223372036854775800'::int8 % '0'::int8 +-- +STMT: SelectStmt +== 093 +select abs('-9223372036854775808'::int8) +-- +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: SelectStmt +== 094 +select '9223372036854775800'::int8 + '100'::int4 +-- +STMT: SelectStmt +== 095 +select '-9223372036854775800'::int8 - '100'::int4 +-- +STMT: SelectStmt +== 096 +select '9223372036854775800'::int8 * '100'::int4 +-- +STMT: SelectStmt +== 097 +select '100'::int4 + '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 098 +select '-100'::int4 - '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 099 +select '100'::int4 * '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 100 +select '9223372036854775800'::int8 + '100'::int2 +-- +STMT: SelectStmt +== 101 +select '-9223372036854775800'::int8 - '100'::int2 +-- +STMT: SelectStmt +== 102 +select '9223372036854775800'::int8 * '100'::int2 +-- +STMT: SelectStmt +== 103 +select '-9223372036854775808'::int8 / '0'::int2 +-- +STMT: SelectStmt +== 104 +select '100'::int2 + '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 105 +select '-100'::int2 - '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 106 +select '100'::int2 * '9223372036854775800'::int8 +-- +STMT: SelectStmt +== 107 +select '100'::int2 / '0'::int8 +-- +STMT: SelectStmt +== 108 +SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 = 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 109 +SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 <> 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 110 +SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 = 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 111 +SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 <> 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 112 +SELECT CAST('42'::int2 AS int8), CAST('-37'::int2 AS int8) +-- +STMT: SelectStmt +== 113 +SELECT CAST(q1 AS float4), CAST(q2 AS float8) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 114 +SELECT CAST('36854775807.0'::float4 AS int8) +-- +STMT: SelectStmt +== 115 +SELECT CAST('922337203685477580700.0'::float8 AS int8) +-- +STMT: SelectStmt +== 116 +SELECT CAST(q1 AS oid) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 117 +SELECT oid::int8 FROM pg_class WHERE relname = 'pg_class' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 118 +-- bit operations + +SELECT q1, q2, q1 & q2 AS "and", q1 | q2 AS "or", q1 # q2 AS "xor", ~q1 AS "not" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 119 +SELECT q1, q1 << 2 AS "shl", q1 >> 3 AS "shr" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 120 +-- generate_series + +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 121 +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 0) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 122 +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 2) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 123 +-- corner case +SELECT (-1::int8<<63)::text +-- +STMT: SelectStmt +== 124 +SELECT ((-1::int8<<63)+1)::text +-- +STMT: SelectStmt +== 125 +-- check sane handling of INT64_MIN overflow cases +SELECT (-9223372036854775808)::int8 * (-1)::int8 +-- +STMT: SelectStmt +== 126 +SELECT (-9223372036854775808)::int8 / (-1)::int8 +-- +STMT: SelectStmt +== 127 +SELECT (-9223372036854775808)::int8 % (-1)::int8 +-- +STMT: SelectStmt +== 128 +SELECT (-9223372036854775808)::int8 * (-1)::int4 +-- +STMT: SelectStmt +== 129 +SELECT (-9223372036854775808)::int8 / (-1)::int4 +-- +STMT: SelectStmt +== 130 +SELECT (-9223372036854775808)::int8 % (-1)::int4 +-- +STMT: SelectStmt +== 131 +SELECT (-9223372036854775808)::int8 * (-1)::int2 +-- +STMT: SelectStmt +== 132 +SELECT (-9223372036854775808)::int8 / (-1)::int2 +-- +STMT: SelectStmt +== 133 +SELECT (-9223372036854775808)::int8 % (-1)::int2 +-- +STMT: SelectStmt +== 134 +-- check rounding when casting from float +SELECT x, x::int8 AS int8_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x) +-- +STMT: SelectStmt +== 135 +-- check rounding when casting from numeric +SELECT x, x::int8 AS int8_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x) +-- +STMT: SelectStmt +== 136 +-- test gcd() +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(b, a), gcd(-b, a) +FROM (VALUES (0::int8, 0::int8), + (0::int8, 29893644334::int8), + (288484263558::int8, 29893644334::int8), + (-288484263558::int8, 29893644334::int8), + ((-9223372036854775808)::int8, 1::int8), + ((-9223372036854775808)::int8, 9223372036854775807::int8), + ((-9223372036854775808)::int8, 4611686018427387904::int8)) AS v(a, b) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +== 137 +SELECT gcd((-9223372036854775808)::int8, 0::int8) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +== 138 +-- overflow +SELECT gcd((-9223372036854775808)::int8, (-9223372036854775808)::int8) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +== 139 +-- overflow + +-- test lcm() +SELECT a, b, lcm(a, b), lcm(a, -b), lcm(b, a), lcm(-b, a) +FROM (VALUES (0::int8, 0::int8), + (0::int8, 29893644334::int8), + (29893644334::int8, 29893644334::int8), + (288484263558::int8, 29893644334::int8), + (-288484263558::int8, 29893644334::int8), + ((-9223372036854775808)::int8, 0::int8)) AS v(a, b) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 140 +SELECT lcm((-9223372036854775808)::int8, 1::int8) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 141 +-- overflow +SELECT lcm(9223372036854775807::int8, 9223372036854775806::int8) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 142 +-- overflow + + +-- non-decimal literals + +SELECT int8 '0b100101' +-- +STMT: SelectStmt +== 143 +SELECT int8 '0o273' +-- +STMT: SelectStmt +== 144 +SELECT int8 '0x42F' +-- +STMT: SelectStmt +== 145 +SELECT int8 '0b' +-- +STMT: SelectStmt +== 146 +SELECT int8 '0o' +-- +STMT: SelectStmt +== 147 +SELECT int8 '0x' +-- +STMT: SelectStmt +== 148 +-- cases near overflow +SELECT int8 '0b111111111111111111111111111111111111111111111111111111111111111' +-- +STMT: SelectStmt +== 149 +SELECT int8 '0b1000000000000000000000000000000000000000000000000000000000000000' +-- +STMT: SelectStmt +== 150 +SELECT int8 '0o777777777777777777777' +-- +STMT: SelectStmt +== 151 +SELECT int8 '0o1000000000000000000000' +-- +STMT: SelectStmt +== 152 +SELECT int8 '0x7FFFFFFFFFFFFFFF' +-- +STMT: SelectStmt +== 153 +SELECT int8 '0x8000000000000000' +-- +STMT: SelectStmt +== 154 +SELECT int8 '-0b1000000000000000000000000000000000000000000000000000000000000000' +-- +STMT: SelectStmt +== 155 +SELECT int8 '-0b1000000000000000000000000000000000000000000000000000000000000001' +-- +STMT: SelectStmt +== 156 +SELECT int8 '-0o1000000000000000000000' +-- +STMT: SelectStmt +== 157 +SELECT int8 '-0o1000000000000000000001' +-- +STMT: SelectStmt +== 158 +SELECT int8 '-0x8000000000000000' +-- +STMT: SelectStmt +== 159 +SELECT int8 '-0x8000000000000001' +-- +STMT: SelectStmt +== 160 +-- underscores + +SELECT int8 '1_000_000' +-- +STMT: SelectStmt +== 161 +SELECT int8 '1_2_3' +-- +STMT: SelectStmt +== 162 +SELECT int8 '0x1EEE_FFFF' +-- +STMT: SelectStmt +== 163 +SELECT int8 '0o2_73' +-- +STMT: SelectStmt +== 164 +SELECT int8 '0b_10_0101' +-- +STMT: SelectStmt +== 165 +-- error cases +SELECT int8 '_100' +-- +STMT: SelectStmt +== 166 +SELECT int8 '100_' +-- +STMT: SelectStmt +== 167 +SELECT int8 '100__000' +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/interval.metadata.json b/parser/testdata/summary/postgres_regress/interval.metadata.json new file mode 100644 index 0000000..df238f5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/interval.metadata.json @@ -0,0 +1,447 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443" + ] +} diff --git a/parser/testdata/summary/postgres_regress/interval.test b/parser/testdata/summary/postgres_regress/interval.test new file mode 100644 index 0000000..d0d0cfa --- /dev/null +++ b/parser/testdata/summary/postgres_regress/interval.test @@ -0,0 +1,2252 @@ +== 001 +|-- +-- INTERVAL +|-- + +SET DATESTYLE = 'ISO' +-- +STMT: VariableSetStmt +== 002 +SET IntervalStyle to postgres +-- +STMT: VariableSetStmt +== 003 +-- check acceptance of "time zone style" +SELECT INTERVAL '01:00' AS "One hour" +-- +STMT: SelectStmt +== 004 +SELECT INTERVAL '+02:00' AS "Two hours" +-- +STMT: SelectStmt +== 005 +SELECT INTERVAL '-08:00' AS "Eight hours" +-- +STMT: SelectStmt +== 006 +SELECT INTERVAL '-1 +02:03' AS "22 hours ago..." +-- +STMT: SelectStmt +== 007 +SELECT INTERVAL '-1 days +02:03' AS "22 hours ago..." +-- +STMT: SelectStmt +== 008 +SELECT INTERVAL '1.5 weeks' AS "Ten days twelve hours" +-- +STMT: SelectStmt +== 009 +SELECT INTERVAL '1.5 months' AS "One month 15 days" +-- +STMT: SelectStmt +== 010 +SELECT INTERVAL '10 years -11 month -12 days +13:14' AS "9 years..." +-- +STMT: SelectStmt +== 011 +SELECT INTERVAL 'infinity' AS "eternity" +-- +STMT: SelectStmt +== 012 +SELECT INTERVAL '-infinity' AS "beginning of time" +-- +STMT: SelectStmt +== 013 +CREATE TABLE INTERVAL_TBL (f1 interval) +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DDL +STMT: CreateStmt +== 014 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 1 minute') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 5 hour') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 10 day') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 34 year') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 3 months') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 14 seconds ago') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO INTERVAL_TBL (f1) VALUES ('1 day 2 hours 3 minutes 4 seconds') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO INTERVAL_TBL (f1) VALUES ('6 years') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO INTERVAL_TBL (f1) VALUES ('5 months') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO INTERVAL_TBL (f1) VALUES ('5 months 12 hours') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO INTERVAL_TBL (f1) VALUES ('infinity') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO INTERVAL_TBL (f1) VALUES ('-infinity') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +-- badly formatted interval +INSERT INTO INTERVAL_TBL (f1) VALUES ('badly formatted interval') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 30 eons ago') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +-- Test non-error-throwing API +SELECT pg_input_is_valid('1.5 weeks', 'interval') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT pg_input_is_valid('garbage', 'interval') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT pg_input_is_valid('@ 30 eons ago', 'interval') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT * FROM pg_input_error_info('garbage', 'interval') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT * FROM pg_input_error_info('@ 30 eons ago', 'interval') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 033 +-- test interval operators + +SELECT * FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +== 034 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 <> interval '@ 10 days' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +== 035 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 <= interval '@ 5 hours' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +== 036 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 < interval '@ 1 day' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +== 037 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 = interval '@ 34 years' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +== 038 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 >= interval '@ 1 month' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +== 039 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 > interval '@ 3 seconds ago' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +== 040 +SELECT r1.*, r2.* + FROM INTERVAL_TBL r1, INTERVAL_TBL r2 + WHERE r1.f1 > r2.f1 + ORDER BY r1.f1, r2.f1 +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "r1"="interval_tbl" +ALIAS: "r2"="interval_tbl" +FILTER: schema="" table="r1" column="f1" +FILTER: schema="" table="r2" column="f1" +STMT: SelectStmt +== 041 +-- test unary minus + +SELECT f1, -f1 FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +== 042 +SELECT -('-2147483648 months'::interval) +-- +STMT: SelectStmt +== 043 +-- should fail +SELECT -('-2147483647 months'::interval) +-- +STMT: SelectStmt +== 044 +-- ok +SELECT -('-2147483648 days'::interval) +-- +STMT: SelectStmt +== 045 +-- should fail +SELECT -('-2147483647 days'::interval) +-- +STMT: SelectStmt +== 046 +-- ok +SELECT -('-9223372036854775808 us'::interval) +-- +STMT: SelectStmt +== 047 +-- should fail +SELECT -('-9223372036854775807 us'::interval) +-- +STMT: SelectStmt +== 048 +-- ok +SELECT -('-2147483647 months -2147483647 days -9223372036854775807 us'::interval) +-- +STMT: SelectStmt +== 049 +-- should fail + +-- Test intervals that are large enough to overflow 64 bits in comparisons +CREATE TEMP TABLE INTERVAL_TBL_OF (f1 interval) +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DDL +STMT: CreateStmt +== 050 +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') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +-- these should fail as out-of-range +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483648 days') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483649 days') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483647 years') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483648 years') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +-- Test edge-case overflow detection in interval multiplication +select extract(epoch from '256 microseconds'::interval * (2^55)::float8) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 056 +SELECT r1.*, r2.* + FROM INTERVAL_TBL_OF r1, INTERVAL_TBL_OF r2 + WHERE r1.f1 > r2.f1 + ORDER BY r1.f1, r2.f1 +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +ALIAS: "r1"="interval_tbl_of" +ALIAS: "r2"="interval_tbl_of" +FILTER: schema="" table="r1" column="f1" +FILTER: schema="" table="r2" column="f1" +STMT: SelectStmt +== 057 +CREATE INDEX ON INTERVAL_TBL_OF USING btree (f1) +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DDL +STMT: IndexStmt +== 058 +SET enable_seqscan TO false +-- +STMT: VariableSetStmt +== 059 +EXPLAIN (COSTS OFF) +SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1 +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +ALIAS: "r1"="interval_tbl_of" +STMT: ExplainStmt +STMT: SelectStmt +== 060 +SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1 +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +ALIAS: "r1"="interval_tbl_of" +STMT: SelectStmt +== 061 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 062 +-- subtracting about-to-overflow values should result in 0 +SELECT f1 - f1 FROM INTERVAL_TBL_OF +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +STMT: SelectStmt +== 063 +DROP TABLE INTERVAL_TBL_OF +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DDL +STMT: DropStmt +== 064 +-- 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) +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=DDL +STMT: CreateStmt +== 065 +COPY INTERVAL_MULDIV_TBL FROM STDIN +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: CopyStmt +== 066 +SELECT span * 0.3 AS product +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +== 067 +SELECT span * 8.2 AS product +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +== 068 +SELECT span / 10 AS quotient +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +== 069 +SELECT span / 100 AS quotient +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +== 070 +DROP TABLE INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=DDL +STMT: DropStmt +== 071 +SET DATESTYLE = 'postgres' +-- +STMT: VariableSetStmt +== 072 +SET IntervalStyle to postgres_verbose +-- +STMT: VariableSetStmt +== 073 +SELECT * FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +== 074 +-- multiplication and division overflow test cases +SELECT '3000000 months'::interval * 1000 +-- +STMT: SelectStmt +== 075 +SELECT '3000000 months'::interval / 0.001 +-- +STMT: SelectStmt +== 076 +SELECT '3000000 days'::interval * 1000 +-- +STMT: SelectStmt +== 077 +SELECT '3000000 days'::interval / 0.001 +-- +STMT: SelectStmt +== 078 +SELECT '1 month 2146410 days'::interval * 1000.5002 +-- +STMT: SelectStmt +== 079 +SELECT '4611686018427387904 usec'::interval / 0.1 +-- +STMT: SelectStmt +== 080 +-- 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 where isfinite(f1) +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 081 +-- test long interval input +select '4 millenniums 5 centuries 4 decades 1 year 4 months 4 days 17 minutes 31 seconds'::interval +-- +STMT: SelectStmt +== 082 +-- 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 +-- +STMT: SelectStmt +== 083 +-- 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" +-- +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +STMT: SelectStmt +== 084 +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" +-- +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT justify_hours(interval '2147483647 days 24 hrs') +-- +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT justify_days(interval '2147483647 months 30 days') +-- +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +STMT: SelectStmt +== 087 +-- test justify_interval() + +SELECT justify_interval(interval '1 month -1 hour') as "1 month -1 hour" +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 088 +SELECT justify_interval(interval '2147483647 days 24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 089 +SELECT justify_interval(interval '-2147483648 days -24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 090 +SELECT justify_interval(interval '2147483647 months 30 days') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 091 +SELECT justify_interval(interval '-2147483648 months -30 days') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 092 +SELECT justify_interval(interval '2147483647 months 30 days -24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 093 +SELECT justify_interval(interval '-2147483648 months -30 days 24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 094 +SELECT justify_interval(interval '2147483647 months -30 days 1440 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 095 +SELECT justify_interval(interval '-2147483648 months 30 days -1440 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +== 096 +-- test fractional second input, and detection of duplicate units +SET DATESTYLE = 'ISO' +-- +STMT: VariableSetStmt +== 097 +SET IntervalStyle TO postgres +-- +STMT: VariableSetStmt +== 098 +SELECT '1 millisecond'::interval, '1 microsecond'::interval, + '500 seconds 99 milliseconds 51 microseconds'::interval +-- +STMT: SelectStmt +== 099 +SELECT '3 days 5 milliseconds'::interval +-- +STMT: SelectStmt +== 100 +SELECT '1 second 2 seconds'::interval +-- +STMT: SelectStmt +== 101 +-- error +SELECT '10 milliseconds 20 milliseconds'::interval +-- +STMT: SelectStmt +== 102 +-- error +SELECT '5.5 seconds 3 milliseconds'::interval +-- +STMT: SelectStmt +== 103 +-- error +SELECT '1:20:05 5 microseconds'::interval +-- +STMT: SelectStmt +== 104 +-- error +SELECT '1 day 1 day'::interval +-- +STMT: SelectStmt +== 105 +-- error +SELECT interval '1-2' +-- +STMT: SelectStmt +== 106 +-- SQL year-month literal +SELECT interval '999' second +-- +STMT: SelectStmt +== 107 +-- oversize leading field is ok +SELECT interval '999' minute +-- +STMT: SelectStmt +== 108 +SELECT interval '999' hour +-- +STMT: SelectStmt +== 109 +SELECT interval '999' day +-- +STMT: SelectStmt +== 110 +SELECT interval '999' month +-- +STMT: SelectStmt +== 111 +-- test SQL-spec syntaxes for restricted field sets +SELECT interval '1' year +-- +STMT: SelectStmt +== 112 +SELECT interval '2' month +-- +STMT: SelectStmt +== 113 +SELECT interval '3' day +-- +STMT: SelectStmt +== 114 +SELECT interval '4' hour +-- +STMT: SelectStmt +== 115 +SELECT interval '5' minute +-- +STMT: SelectStmt +== 116 +SELECT interval '6' second +-- +STMT: SelectStmt +== 117 +SELECT interval '1' year to month +-- +STMT: SelectStmt +== 118 +SELECT interval '1-2' year to month +-- +STMT: SelectStmt +== 119 +SELECT interval '1 2' day to hour +-- +STMT: SelectStmt +== 120 +SELECT interval '1 2:03' day to hour +-- +STMT: SelectStmt +== 121 +SELECT interval '1 2:03:04' day to hour +-- +STMT: SelectStmt +== 122 +SELECT interval '1 2' day to minute +-- +STMT: SelectStmt +== 123 +SELECT interval '1 2:03' day to minute +-- +STMT: SelectStmt +== 124 +SELECT interval '1 2:03:04' day to minute +-- +STMT: SelectStmt +== 125 +SELECT interval '1 2' day to second +-- +STMT: SelectStmt +== 126 +SELECT interval '1 2:03' day to second +-- +STMT: SelectStmt +== 127 +SELECT interval '1 2:03:04' day to second +-- +STMT: SelectStmt +== 128 +SELECT interval '1 2' hour to minute +-- +STMT: SelectStmt +== 129 +SELECT interval '1 2:03' hour to minute +-- +STMT: SelectStmt +== 130 +SELECT interval '1 2:03:04' hour to minute +-- +STMT: SelectStmt +== 131 +SELECT interval '1 2' hour to second +-- +STMT: SelectStmt +== 132 +SELECT interval '1 2:03' hour to second +-- +STMT: SelectStmt +== 133 +SELECT interval '1 2:03:04' hour to second +-- +STMT: SelectStmt +== 134 +SELECT interval '1 2' minute to second +-- +STMT: SelectStmt +== 135 +SELECT interval '1 2:03' minute to second +-- +STMT: SelectStmt +== 136 +SELECT interval '1 2:03:04' minute to second +-- +STMT: SelectStmt +== 137 +SELECT interval '1 +2:03' minute to second +-- +STMT: SelectStmt +== 138 +SELECT interval '1 +2:03:04' minute to second +-- +STMT: SelectStmt +== 139 +SELECT interval '1 -2:03' minute to second +-- +STMT: SelectStmt +== 140 +SELECT interval '1 -2:03:04' minute to second +-- +STMT: SelectStmt +== 141 +SELECT interval '123 11' day to hour +-- +STMT: SelectStmt +== 142 +-- ok +SELECT interval '123 11' day +-- +STMT: SelectStmt +== 143 +-- not ok +SELECT interval '123 11' +-- +STMT: SelectStmt +== 144 +-- not ok, too ambiguous +SELECT interval '123 2:03 -2:04' +-- +STMT: SelectStmt +== 145 +-- not ok, redundant hh:mm fields + +-- test syntaxes for restricted precision +SELECT interval(0) '1 day 01:23:45.6789' +-- +STMT: SelectStmt +== 146 +SELECT interval(2) '1 day 01:23:45.6789' +-- +STMT: SelectStmt +== 147 +SELECT interval '12:34.5678' minute to second(2) +-- +STMT: SelectStmt +== 148 +-- per SQL spec +SELECT interval '1.234' second +-- +STMT: SelectStmt +== 149 +SELECT interval '1.234' second(2) +-- +STMT: SelectStmt +== 150 +SELECT interval '1 2.345' day to second(2) +-- +STMT: SelectStmt +== 151 +SELECT interval '1 2:03' day to second(2) +-- +STMT: SelectStmt +== 152 +SELECT interval '1 2:03.4567' day to second(2) +-- +STMT: SelectStmt +== 153 +SELECT interval '1 2:03:04.5678' day to second(2) +-- +STMT: SelectStmt +== 154 +SELECT interval '1 2.345' hour to second(2) +-- +STMT: SelectStmt +== 155 +SELECT interval '1 2:03.45678' hour to second(2) +-- +STMT: SelectStmt +== 156 +SELECT interval '1 2:03:04.5678' hour to second(2) +-- +STMT: SelectStmt +== 157 +SELECT interval '1 2.3456' minute to second(2) +-- +STMT: SelectStmt +== 158 +SELECT interval '1 2:03.5678' minute to second(2) +-- +STMT: SelectStmt +== 159 +SELECT interval '1 2:03:04.5678' minute to second(2) +-- +STMT: SelectStmt +== 160 +SELECT interval '2562047788:00:54.775807' second(2) +-- +STMT: SelectStmt +== 161 +-- out of range +SELECT interval '-2562047788:00:54.775807' second(2) +-- +STMT: SelectStmt +== 162 +-- out of range + +-- 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 +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +== 163 +-- test inputting and outputting SQL standard interval literals +SET IntervalStyle TO sql_standard +-- +STMT: VariableSetStmt +== 164 +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" +-- +STMT: SelectStmt +== 165 +-- test input of some not-quite-standard interval values in the sql style +SET IntervalStyle TO postgres +-- +STMT: VariableSetStmt +== 166 +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' +-- +STMT: SelectStmt +== 167 +-- cases that trigger sign-matching rules in the sql style +SELECT interval '-23 hours 45 min 12.34 sec', + interval '-1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min +12.34 sec' +-- +STMT: SelectStmt +== 168 +-- test output of couple non-standard interval values in the sql style +SET IntervalStyle TO sql_standard +-- +STMT: VariableSetStmt +== 169 +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' +-- +STMT: SelectStmt +== 170 +-- cases that trigger sign-matching rules in the sql style +SELECT interval '-23 hours 45 min 12.34 sec', + interval '-1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min +12.34 sec' +-- +STMT: SelectStmt +== 171 +-- edge case for sign-matching rules +SELECT interval '' +-- +STMT: SelectStmt +== 172 +-- error + +-- test outputting iso8601 intervals +SET IntervalStyle to iso_8601 +-- +STMT: VariableSetStmt +== 173 +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" +-- +STMT: SelectStmt +== 174 +-- test inputting ISO 8601 4.4.2.1 "Format With Time Unit Designators" +SET IntervalStyle to sql_standard +-- +STMT: VariableSetStmt +== 175 +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" +-- +STMT: SelectStmt +== 176 +-- test inputting ISO 8601 4.4.2.2 "Alternative Format" +SET IntervalStyle to postgres +-- +STMT: VariableSetStmt +== 177 +select interval 'P00021015T103020' AS "ISO8601 Basic Format", + interval 'P0002-10-15T10:30:20' AS "ISO8601 Extended Format" +-- +STMT: SelectStmt +== 178 +-- 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" +-- +STMT: SelectStmt +== 179 +-- Check handling of fractional fields in ISO8601 format. +select interval 'P1Y0M3DT4H5M6S' +-- +STMT: SelectStmt +== 180 +select interval 'P1.0Y0M3DT4H5M6S' +-- +STMT: SelectStmt +== 181 +select interval 'P1.1Y0M3DT4H5M6S' +-- +STMT: SelectStmt +== 182 +select interval 'P1.Y0M3DT4H5M6S' +-- +STMT: SelectStmt +== 183 +select interval 'P.1Y0M3DT4H5M6S' +-- +STMT: SelectStmt +== 184 +select interval 'P10.5e4Y' +-- +STMT: SelectStmt +== 185 +-- not per spec, but we've historically taken it +select interval 'P.Y0M3DT4H5M6S' +-- +STMT: SelectStmt +== 186 +-- error + +-- test a couple rounding cases that changed since 8.3 w/ HAVE_INT64_TIMESTAMP. +SET IntervalStyle to postgres_verbose +-- +STMT: VariableSetStmt +== 187 +select interval '-10 mons -3 days +03:55:06.70' +-- +STMT: SelectStmt +== 188 +select interval '1 year 2 mons 3 days 04:05:06.699999' +-- +STMT: SelectStmt +== 189 +select interval '0:0:0.7', interval '@ 0.70 secs', interval '0.7 seconds' +-- +STMT: SelectStmt +== 190 +-- test time fields using entire 64 bit microseconds range +select interval '2562047788.01521550194 hours' +-- +STMT: SelectStmt +== 191 +select interval '-2562047788.01521550222 hours' +-- +STMT: SelectStmt +== 192 +select interval '153722867280.912930117 minutes' +-- +STMT: SelectStmt +== 193 +select interval '-153722867280.912930133 minutes' +-- +STMT: SelectStmt +== 194 +select interval '9223372036854.775807 seconds' +-- +STMT: SelectStmt +== 195 +select interval '-9223372036854.775808 seconds' +-- +STMT: SelectStmt +== 196 +select interval '9223372036854775.807 milliseconds' +-- +STMT: SelectStmt +== 197 +select interval '-9223372036854775.808 milliseconds' +-- +STMT: SelectStmt +== 198 +select interval '9223372036854775807 microseconds' +-- +STMT: SelectStmt +== 199 +select interval '-9223372036854775808 microseconds' +-- +STMT: SelectStmt +== 200 +select interval 'PT2562047788H54.775807S' +-- +STMT: SelectStmt +== 201 +select interval 'PT-2562047788H-54.775808S' +-- +STMT: SelectStmt +== 202 +select interval 'PT2562047788:00:54.775807' +-- +STMT: SelectStmt +== 203 +select interval 'PT2562047788.0152155019444' +-- +STMT: SelectStmt +== 204 +select interval 'PT-2562047788.0152155022222' +-- +STMT: SelectStmt +== 205 +-- overflow each date/time field +select interval '2147483648 years' +-- +STMT: SelectStmt +== 206 +select interval '-2147483649 years' +-- +STMT: SelectStmt +== 207 +select interval '2147483648 months' +-- +STMT: SelectStmt +== 208 +select interval '-2147483649 months' +-- +STMT: SelectStmt +== 209 +select interval '2147483648 days' +-- +STMT: SelectStmt +== 210 +select interval '-2147483649 days' +-- +STMT: SelectStmt +== 211 +select interval '2562047789 hours' +-- +STMT: SelectStmt +== 212 +select interval '-2562047789 hours' +-- +STMT: SelectStmt +== 213 +select interval '153722867281 minutes' +-- +STMT: SelectStmt +== 214 +select interval '-153722867281 minutes' +-- +STMT: SelectStmt +== 215 +select interval '9223372036855 seconds' +-- +STMT: SelectStmt +== 216 +select interval '-9223372036855 seconds' +-- +STMT: SelectStmt +== 217 +select interval '9223372036854777 millisecond' +-- +STMT: SelectStmt +== 218 +select interval '-9223372036854777 millisecond' +-- +STMT: SelectStmt +== 219 +select interval '9223372036854775808 microsecond' +-- +STMT: SelectStmt +== 220 +select interval '-9223372036854775809 microsecond' +-- +STMT: SelectStmt +== 221 +select interval 'P2147483648' +-- +STMT: SelectStmt +== 222 +select interval 'P-2147483649' +-- +STMT: SelectStmt +== 223 +select interval 'P1-2147483647-2147483647' +-- +STMT: SelectStmt +== 224 +select interval 'PT2562047789' +-- +STMT: SelectStmt +== 225 +select interval 'PT-2562047789' +-- +STMT: SelectStmt +== 226 +-- overflow with date/time unit aliases +select interval '2147483647 weeks' +-- +STMT: SelectStmt +== 227 +select interval '-2147483648 weeks' +-- +STMT: SelectStmt +== 228 +select interval '2147483647 decades' +-- +STMT: SelectStmt +== 229 +select interval '-2147483648 decades' +-- +STMT: SelectStmt +== 230 +select interval '2147483647 centuries' +-- +STMT: SelectStmt +== 231 +select interval '-2147483648 centuries' +-- +STMT: SelectStmt +== 232 +select interval '2147483647 millennium' +-- +STMT: SelectStmt +== 233 +select interval '-2147483648 millennium' +-- +STMT: SelectStmt +== 234 +select interval '1 week 2147483647 days' +-- +STMT: SelectStmt +== 235 +select interval '-1 week -2147483648 days' +-- +STMT: SelectStmt +== 236 +select interval '2147483647 days 1 week' +-- +STMT: SelectStmt +== 237 +select interval '-2147483648 days -1 week' +-- +STMT: SelectStmt +== 238 +select interval 'P1W2147483647D' +-- +STMT: SelectStmt +== 239 +select interval 'P-1W-2147483648D' +-- +STMT: SelectStmt +== 240 +select interval 'P2147483647D1W' +-- +STMT: SelectStmt +== 241 +select interval 'P-2147483648D-1W' +-- +STMT: SelectStmt +== 242 +select interval '1 decade 2147483647 years' +-- +STMT: SelectStmt +== 243 +select interval '1 century 2147483647 years' +-- +STMT: SelectStmt +== 244 +select interval '1 millennium 2147483647 years' +-- +STMT: SelectStmt +== 245 +select interval '-1 decade -2147483648 years' +-- +STMT: SelectStmt +== 246 +select interval '-1 century -2147483648 years' +-- +STMT: SelectStmt +== 247 +select interval '-1 millennium -2147483648 years' +-- +STMT: SelectStmt +== 248 +select interval '2147483647 years 1 decade' +-- +STMT: SelectStmt +== 249 +select interval '2147483647 years 1 century' +-- +STMT: SelectStmt +== 250 +select interval '2147483647 years 1 millennium' +-- +STMT: SelectStmt +== 251 +select interval '-2147483648 years -1 decade' +-- +STMT: SelectStmt +== 252 +select interval '-2147483648 years -1 century' +-- +STMT: SelectStmt +== 253 +select interval '-2147483648 years -1 millennium' +-- +STMT: SelectStmt +== 254 +-- overflowing with fractional fields - postgres format +select interval '0.1 millennium 2147483647 months' +-- +STMT: SelectStmt +== 255 +select interval '0.1 centuries 2147483647 months' +-- +STMT: SelectStmt +== 256 +select interval '0.1 decades 2147483647 months' +-- +STMT: SelectStmt +== 257 +select interval '0.1 yrs 2147483647 months' +-- +STMT: SelectStmt +== 258 +select interval '-0.1 millennium -2147483648 months' +-- +STMT: SelectStmt +== 259 +select interval '-0.1 centuries -2147483648 months' +-- +STMT: SelectStmt +== 260 +select interval '-0.1 decades -2147483648 months' +-- +STMT: SelectStmt +== 261 +select interval '-0.1 yrs -2147483648 months' +-- +STMT: SelectStmt +== 262 +select interval '2147483647 months 0.1 millennium' +-- +STMT: SelectStmt +== 263 +select interval '2147483647 months 0.1 centuries' +-- +STMT: SelectStmt +== 264 +select interval '2147483647 months 0.1 decades' +-- +STMT: SelectStmt +== 265 +select interval '2147483647 months 0.1 yrs' +-- +STMT: SelectStmt +== 266 +select interval '-2147483648 months -0.1 millennium' +-- +STMT: SelectStmt +== 267 +select interval '-2147483648 months -0.1 centuries' +-- +STMT: SelectStmt +== 268 +select interval '-2147483648 months -0.1 decades' +-- +STMT: SelectStmt +== 269 +select interval '-2147483648 months -0.1 yrs' +-- +STMT: SelectStmt +== 270 +select interval '0.1 months 2147483647 days' +-- +STMT: SelectStmt +== 271 +select interval '-0.1 months -2147483648 days' +-- +STMT: SelectStmt +== 272 +select interval '2147483647 days 0.1 months' +-- +STMT: SelectStmt +== 273 +select interval '-2147483648 days -0.1 months' +-- +STMT: SelectStmt +== 274 +select interval '0.5 weeks 2147483647 days' +-- +STMT: SelectStmt +== 275 +select interval '-0.5 weeks -2147483648 days' +-- +STMT: SelectStmt +== 276 +select interval '2147483647 days 0.5 weeks' +-- +STMT: SelectStmt +== 277 +select interval '-2147483648 days -0.5 weeks' +-- +STMT: SelectStmt +== 278 +select interval '0.01 months 9223372036854775807 microseconds' +-- +STMT: SelectStmt +== 279 +select interval '-0.01 months -9223372036854775808 microseconds' +-- +STMT: SelectStmt +== 280 +select interval '9223372036854775807 microseconds 0.01 months' +-- +STMT: SelectStmt +== 281 +select interval '-9223372036854775808 microseconds -0.01 months' +-- +STMT: SelectStmt +== 282 +select interval '0.1 weeks 9223372036854775807 microseconds' +-- +STMT: SelectStmt +== 283 +select interval '-0.1 weeks -9223372036854775808 microseconds' +-- +STMT: SelectStmt +== 284 +select interval '9223372036854775807 microseconds 0.1 weeks' +-- +STMT: SelectStmt +== 285 +select interval '-9223372036854775808 microseconds -0.1 weeks' +-- +STMT: SelectStmt +== 286 +select interval '0.1 days 9223372036854775807 microseconds' +-- +STMT: SelectStmt +== 287 +select interval '-0.1 days -9223372036854775808 microseconds' +-- +STMT: SelectStmt +== 288 +select interval '9223372036854775807 microseconds 0.1 days' +-- +STMT: SelectStmt +== 289 +select interval '-9223372036854775808 microseconds -0.1 days' +-- +STMT: SelectStmt +== 290 +-- overflowing with fractional fields - ISO8601 format +select interval 'P0.1Y2147483647M' +-- +STMT: SelectStmt +== 291 +select interval 'P-0.1Y-2147483648M' +-- +STMT: SelectStmt +== 292 +select interval 'P2147483647M0.1Y' +-- +STMT: SelectStmt +== 293 +select interval 'P-2147483648M-0.1Y' +-- +STMT: SelectStmt +== 294 +select interval 'P0.1M2147483647D' +-- +STMT: SelectStmt +== 295 +select interval 'P-0.1M-2147483648D' +-- +STMT: SelectStmt +== 296 +select interval 'P2147483647D0.1M' +-- +STMT: SelectStmt +== 297 +select interval 'P-2147483648D-0.1M' +-- +STMT: SelectStmt +== 298 +select interval 'P0.5W2147483647D' +-- +STMT: SelectStmt +== 299 +select interval 'P-0.5W-2147483648D' +-- +STMT: SelectStmt +== 300 +select interval 'P2147483647D0.5W' +-- +STMT: SelectStmt +== 301 +select interval 'P-2147483648D-0.5W' +-- +STMT: SelectStmt +== 302 +select interval 'P0.01MT2562047788H54.775807S' +-- +STMT: SelectStmt +== 303 +select interval 'P-0.01MT-2562047788H-54.775808S' +-- +STMT: SelectStmt +== 304 +select interval 'P0.1DT2562047788H54.775807S' +-- +STMT: SelectStmt +== 305 +select interval 'P-0.1DT-2562047788H-54.775808S' +-- +STMT: SelectStmt +== 306 +select interval 'PT2562047788.1H54.775807S' +-- +STMT: SelectStmt +== 307 +select interval 'PT-2562047788.1H-54.775808S' +-- +STMT: SelectStmt +== 308 +select interval 'PT2562047788H0.1M54.775807S' +-- +STMT: SelectStmt +== 309 +select interval 'PT-2562047788H-0.1M-54.775808S' +-- +STMT: SelectStmt +== 310 +-- overflowing with fractional fields - ISO8601 alternative format +select interval 'P0.1-2147483647-00' +-- +STMT: SelectStmt +== 311 +select interval 'P00-0.1-2147483647' +-- +STMT: SelectStmt +== 312 +select interval 'P00-0.01-00T2562047788:00:54.775807' +-- +STMT: SelectStmt +== 313 +select interval 'P00-00-0.1T2562047788:00:54.775807' +-- +STMT: SelectStmt +== 314 +select interval 'PT2562047788.1:00:54.775807' +-- +STMT: SelectStmt +== 315 +select interval 'PT2562047788:01.:54.775807' +-- +STMT: SelectStmt +== 316 +-- overflowing with fractional fields - SQL standard format +select interval '0.1 2562047788:0:54.775807' +-- +STMT: SelectStmt +== 317 +select interval '0.1 2562047788:0:54.775808 ago' +-- +STMT: SelectStmt +== 318 +select interval '2562047788.1:0:54.775807' +-- +STMT: SelectStmt +== 319 +select interval '2562047788.1:0:54.775808 ago' +-- +STMT: SelectStmt +== 320 +select interval '2562047788:0.1:54.775807' +-- +STMT: SelectStmt +== 321 +select interval '2562047788:0.1:54.775808 ago' +-- +STMT: SelectStmt +== 322 +-- overflowing using AGO with INT_MIN +select interval '-2147483648 months ago' +-- +STMT: SelectStmt +== 323 +select interval '-2147483648 days ago' +-- +STMT: SelectStmt +== 324 +select interval '-9223372036854775808 microseconds ago' +-- +STMT: SelectStmt +== 325 +select interval '-2147483648 months -2147483648 days -9223372036854775808 microseconds ago' +-- +STMT: SelectStmt +== 326 +-- overflowing using make_interval +select make_interval(years := 178956971) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 327 +select make_interval(years := -178956971) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 328 +select make_interval(years := 1, months := 2147483647) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 329 +select make_interval(years := -1, months := -2147483648) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 330 +select make_interval(weeks := 306783379) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 331 +select make_interval(weeks := -306783379) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 332 +select make_interval(weeks := 1, days := 2147483647) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 333 +select make_interval(weeks := -1, days := -2147483648) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 334 +select make_interval(secs := 1e308) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 335 +select make_interval(secs := 1e18) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 336 +select make_interval(secs := -1e18) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 337 +select make_interval(mins := 1, secs := 9223372036800.0) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 338 +select make_interval(mins := -1, secs := -9223372036800.0) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 339 +-- test that INT_MIN number is formatted properly +SET IntervalStyle to postgres +-- +STMT: VariableSetStmt +== 340 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +== 341 +SET IntervalStyle to sql_standard +-- +STMT: VariableSetStmt +== 342 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +== 343 +SET IntervalStyle to iso_8601 +-- +STMT: VariableSetStmt +== 344 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +== 345 +SET IntervalStyle to postgres_verbose +-- +STMT: VariableSetStmt +== 346 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +== 347 +-- check that '30 days' equals '1 month' according to the hash function +select '30 days'::interval = '1 month'::interval as t +-- +STMT: SelectStmt +== 348 +select interval_hash('30 days'::interval) = interval_hash('1 month'::interval) as t +-- +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +STMT: SelectStmt +== 349 +-- numeric constructor +select make_interval(years := 2) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 350 +select make_interval(years := 1, months := 6) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 351 +select make_interval(years := 1, months := -1, weeks := 5, days := -7, hours := 25, mins := -180) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 352 +select make_interval() = make_interval(years := 0, months := 0, weeks := 0, days := 0, mins := 0, secs := 0.0) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 353 +select make_interval(hours := -2, mins := -10, secs := -25.3) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 354 +select make_interval(years := 'inf'::float::int) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 355 +select make_interval(months := 'NaN'::float::int) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 356 +select make_interval(secs := 'inf') +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 357 +select make_interval(secs := 'NaN') +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 358 +select make_interval(secs := 7e12) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +== 359 +|-- +-- test EXTRACT +|-- +SELECT f1, + EXTRACT(MICROSECOND FROM f1) AS MICROSECOND, + EXTRACT(MILLISECOND FROM f1) AS MILLISECOND, + EXTRACT(SECOND FROM f1) AS SECOND, + EXTRACT(MINUTE FROM f1) AS MINUTE, + EXTRACT(HOUR FROM f1) AS HOUR, + EXTRACT(DAY FROM f1) AS DAY, + EXTRACT(MONTH FROM f1) AS MONTH, + EXTRACT(QUARTER FROM f1) AS QUARTER, + EXTRACT(YEAR FROM f1) AS YEAR, + EXTRACT(DECADE FROM f1) AS DECADE, + EXTRACT(CENTURY FROM f1) AS CENTURY, + EXTRACT(MILLENNIUM FROM f1) AS MILLENNIUM, + EXTRACT(EPOCH FROM f1) AS EPOCH + FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 360 +SELECT EXTRACT(FORTNIGHT FROM INTERVAL '2 days') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 361 +-- error +SELECT EXTRACT(TIMEZONE FROM INTERVAL '2 days') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 362 +-- error + +SELECT EXTRACT(DECADE FROM INTERVAL '100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 363 +SELECT EXTRACT(DECADE FROM INTERVAL '99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 364 +SELECT EXTRACT(DECADE FROM INTERVAL '-99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 365 +SELECT EXTRACT(DECADE FROM INTERVAL '-100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 366 +SELECT EXTRACT(CENTURY FROM INTERVAL '100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 367 +SELECT EXTRACT(CENTURY FROM INTERVAL '99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 368 +SELECT EXTRACT(CENTURY FROM INTERVAL '-99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 369 +SELECT EXTRACT(CENTURY FROM INTERVAL '-100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 370 +-- date_part implementation is mostly the same as extract, so only +-- test a few cases for additional coverage. +SELECT f1, + date_part('microsecond', f1) AS microsecond, + date_part('millisecond', f1) AS millisecond, + date_part('second', f1) AS second, + date_part('epoch', f1) AS epoch + FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 371 +-- internal overflow test case +SELECT extract(epoch from interval '1000000000 days') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 372 +|-- +-- test infinite intervals +|-- + +-- largest finite intervals +SELECT interval '-2147483648 months -2147483648 days -9223372036854775807 us' +-- +STMT: SelectStmt +== 373 +SELECT interval '2147483647 months 2147483647 days 9223372036854775806 us' +-- +STMT: SelectStmt +== 374 +-- infinite intervals +SELECT interval '-2147483648 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +== 375 +SELECT interval '2147483647 months 2147483647 days 9223372036854775807 us' +-- +STMT: SelectStmt +== 376 +CREATE TABLE INFINITE_INTERVAL_TBL (i interval) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=DDL +STMT: CreateStmt +== 377 +INSERT INTO INFINITE_INTERVAL_TBL VALUES ('infinity'), ('-infinity'), ('1 year 2 days 3 hours') +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 378 +SELECT i, isfinite(i) FROM INFINITE_INTERVAL_TBL +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +STMT: SelectStmt +== 379 +-- test basic arithmetic +CREATE FUNCTION eval(expr text) +RETURNS text AS +$$ +DECLARE + result text; +BEGIN + EXECUTE 'select '||expr INTO result; + RETURN result; +EXCEPTION WHEN OTHERS THEN + RETURN SQLERRM; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="eval" function="eval" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 380 +SELECT d AS date, i AS interval, + eval(format('date %L + interval %L', d, i)) AS plus, + eval(format('date %L - interval %L', d, i)) AS minus +FROM (VALUES (date '-infinity'), + (date '1995-08-06'), + (date 'infinity')) AS t1(d), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i) +-- +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 381 +SELECT i1 AS interval1, i2 AS interval2, + eval(format('interval %L + interval %L', i1, i2)) AS plus, + eval(format('interval %L - interval %L', i1, i2)) AS minus +FROM (VALUES (interval '-infinity'), + (interval '2 months'), + (interval 'infinity')) AS t1(i1), + (VALUES (interval '-infinity'), + (interval '10 days'), + (interval 'infinity')) AS t2(i2) +-- +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 382 +SELECT interval '2147483646 months 2147483646 days 9223372036854775806 us' + interval '1 month 1 day 1 us' +-- +STMT: SelectStmt +== 383 +SELECT interval '-2147483647 months -2147483647 days -9223372036854775807 us' + interval '-1 month -1 day -1 us' +-- +STMT: SelectStmt +== 384 +SELECT interval '2147483646 months 2147483646 days 9223372036854775806 us' - interval '-1 month -1 day -1 us' +-- +STMT: SelectStmt +== 385 +SELECT interval '-2147483647 months -2147483647 days -9223372036854775807 us' - interval '1 month 1 day 1 us' +-- +STMT: SelectStmt +== 386 +SELECT t AS timestamp, i AS interval, + eval(format('timestamp %L + interval %L', t, i)) AS plus, + eval(format('timestamp %L - interval %L', t, i)) AS minus +FROM (VALUES (timestamp '-infinity'), + (timestamp '1995-08-06 12:30:15'), + (timestamp 'infinity')) AS t1(t), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i) +-- +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 387 +SELECT t AT TIME ZONE 'GMT' AS timestamptz, i AS interval, + eval(format('timestamptz %L + interval %L', t, i)) AS plus, + eval(format('timestamptz %L - interval %L', t, i)) AS minus +FROM (VALUES (timestamptz '-infinity'), + (timestamptz '1995-08-06 12:30:15 GMT'), + (timestamptz 'infinity')) AS t1(t), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 388 +-- time +/- infinite interval not supported +SELECT time '11:27:42' + interval 'infinity' +-- +STMT: SelectStmt +== 389 +SELECT time '11:27:42' + interval '-infinity' +-- +STMT: SelectStmt +== 390 +SELECT time '11:27:42' - interval 'infinity' +-- +STMT: SelectStmt +== 391 +SELECT time '11:27:42' - interval '-infinity' +-- +STMT: SelectStmt +== 392 +SELECT timetz '11:27:42' + interval 'infinity' +-- +STMT: SelectStmt +== 393 +SELECT timetz '11:27:42' + interval '-infinity' +-- +STMT: SelectStmt +== 394 +SELECT timetz '11:27:42' - interval 'infinity' +-- +STMT: SelectStmt +== 395 +SELECT timetz '11:27:42' - interval '-infinity' +-- +STMT: SelectStmt +== 396 +SELECT lhst.i lhs, + rhst.i rhs, + lhst.i < rhst.i AS lt, + lhst.i <= rhst.i AS le, + lhst.i = rhst.i AS eq, + lhst.i > rhst.i AS gt, + lhst.i >= rhst.i AS ge, + lhst.i <> rhst.i AS ne + FROM INFINITE_INTERVAL_TBL lhst CROSS JOIN INFINITE_INTERVAL_TBL rhst + WHERE NOT isfinite(lhst.i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +ALIAS: "lhst"="infinite_interval_tbl" +ALIAS: "rhst"="infinite_interval_tbl" +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="lhst" column="i" +STMT: SelectStmt +== 397 +SELECT i AS interval, + -i AS um, + i * 2.0 AS mul, + i * -2.0 AS mul_neg, + i * 'infinity' AS mul_inf, + i * '-infinity' AS mul_inf_neg, + i / 3.0 AS div, + i / -3.0 AS div_neg + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 398 +SELECT -interval '-2147483647 months -2147483647 days -9223372036854775807 us' +-- +STMT: SelectStmt +== 399 +SELECT interval 'infinity' * 'nan' +-- +STMT: SelectStmt +== 400 +SELECT interval '-infinity' * 'nan' +-- +STMT: SelectStmt +== 401 +SELECT interval '-1073741824 months -1073741824 days -4611686018427387904 us' * 2 +-- +STMT: SelectStmt +== 402 +SELECT interval 'infinity' * 0 +-- +STMT: SelectStmt +== 403 +SELECT interval '-infinity' * 0 +-- +STMT: SelectStmt +== 404 +SELECT interval '0 days' * 'infinity'::float +-- +STMT: SelectStmt +== 405 +SELECT interval '0 days' * '-infinity'::float +-- +STMT: SelectStmt +== 406 +SELECT interval '5 days' * 'infinity'::float +-- +STMT: SelectStmt +== 407 +SELECT interval '5 days' * '-infinity'::float +-- +STMT: SelectStmt +== 408 +SELECT interval 'infinity' / 'infinity' +-- +STMT: SelectStmt +== 409 +SELECT interval 'infinity' / '-infinity' +-- +STMT: SelectStmt +== 410 +SELECT interval 'infinity' / 'nan' +-- +STMT: SelectStmt +== 411 +SELECT interval '-infinity' / 'infinity' +-- +STMT: SelectStmt +== 412 +SELECT interval '-infinity' / '-infinity' +-- +STMT: SelectStmt +== 413 +SELECT interval '-infinity' / 'nan' +-- +STMT: SelectStmt +== 414 +SELECT interval '-1073741824 months -1073741824 days -4611686018427387904 us' / 0.5 +-- +STMT: SelectStmt +== 415 +SELECT date_bin('infinity', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 416 +SELECT date_bin('-infinity', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 417 +SELECT i AS interval, date_trunc('hour', i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 418 +SELECT i AS interval, justify_days(i), justify_hours(i), justify_interval(i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 419 +SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamp) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 420 +SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamp) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 421 +SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamptz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 422 +SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamptz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 423 +SELECT timezone('infinity'::interval, '12:12:12'::time) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 424 +SELECT timezone('-infinity'::interval, '12:12:12'::time) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 425 +SELECT timezone('infinity'::interval, '12:12:12'::timetz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 426 +SELECT timezone('-infinity'::interval, '12:12:12'::timetz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +== 427 +SELECT 'infinity'::interval::time +-- +STMT: SelectStmt +== 428 +SELECT '-infinity'::interval::time +-- +STMT: SelectStmt +== 429 +SELECT to_char('infinity'::interval, 'YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 430 +SELECT to_char('-infinity'::interval, 'YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 431 +-- "ago" can only appear once at the end of an interval. +SELECT INTERVAL '42 days 2 seconds ago ago' +-- +STMT: SelectStmt +== 432 +SELECT INTERVAL '2 minutes ago 5 days' +-- +STMT: SelectStmt +== 433 +-- consecutive and dangling units are not allowed. +SELECT INTERVAL 'hour 5 months' +-- +STMT: SelectStmt +== 434 +SELECT INTERVAL '1 year months days 5 hours' +-- +STMT: SelectStmt +== 435 +-- unacceptable reserved words in interval. Only "infinity", "+infinity" and +-- "-infinity" are allowed. +SELECT INTERVAL 'now' +-- +STMT: SelectStmt +== 436 +SELECT INTERVAL 'today' +-- +STMT: SelectStmt +== 437 +SELECT INTERVAL 'tomorrow' +-- +STMT: SelectStmt +== 438 +SELECT INTERVAL 'allballs' +-- +STMT: SelectStmt +== 439 +SELECT INTERVAL 'epoch' +-- +STMT: SelectStmt +== 440 +SELECT INTERVAL 'yesterday' +-- +STMT: SelectStmt +== 441 +-- infinity specification should be the only thing +SELECT INTERVAL 'infinity years' +-- +STMT: SelectStmt +== 442 +SELECT INTERVAL 'infinity ago' +-- +STMT: SelectStmt +== 443 +SELECT INTERVAL '+infinity -infinity' +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/join.metadata.json b/parser/testdata/summary/postgres_regress/join.metadata.json new file mode 100644 index 0000000..3b007a6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/join.metadata.json @@ -0,0 +1,719 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715" + ] +} diff --git a/parser/testdata/summary/postgres_regress/join.test b/parser/testdata/summary/postgres_regress/join.test new file mode 100644 index 0000000..d4ea86a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/join.test @@ -0,0 +1,7366 @@ +== 001 +|-- +-- JOIN +-- Test JOIN clauses +|-- + +CREATE TABLE J1_TBL ( + i integer, + j integer, + t text +) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE J2_TBL ( + i integer, + k integer +) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO J1_TBL VALUES (1, 4, 'one') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO J1_TBL VALUES (2, 3, 'two') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO J1_TBL VALUES (3, 2, 'three') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO J1_TBL VALUES (4, 1, 'four') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO J1_TBL VALUES (5, 0, 'five') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO J1_TBL VALUES (6, 6, 'six') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO J1_TBL VALUES (7, 7, 'seven') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO J1_TBL VALUES (8, 8, 'eight') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO J1_TBL VALUES (0, NULL, 'zero') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO J1_TBL VALUES (NULL, NULL, 'null') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO J1_TBL VALUES (NULL, 0, 'zero') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO J2_TBL VALUES (1, -1) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO J2_TBL VALUES (2, 2) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO J2_TBL VALUES (3, -3) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO J2_TBL VALUES (2, 4) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO J2_TBL VALUES (5, -5) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO J2_TBL VALUES (5, -5) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO J2_TBL VALUES (0, NULL) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO J2_TBL VALUES (NULL, NULL) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO J2_TBL VALUES (NULL, 0) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +-- useful in some tests below +create temp table onerow() +-- +TABLE: name="onerow" schema="" table="onerow" ctx=DDL +STMT: CreateStmt +== 024 +insert into onerow default values +-- +TABLE: name="onerow" schema="" table="onerow" ctx=DML +STMT: InsertStmt +== 025 +analyze onerow +-- +TABLE: name="onerow" schema="" table="onerow" ctx=DDL +STMT: VacuumStmt +== 026 +|-- +-- CORRELATION NAMES +-- Make sure that table/column aliases are supported +-- before diving into more complex join syntax. +|-- + +SELECT * + FROM J1_TBL AS tx +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "tx"="j1_tbl" +STMT: SelectStmt +== 027 +SELECT * + FROM J1_TBL tx +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "tx"="j1_tbl" +STMT: SelectStmt +== 028 +SELECT * + FROM J1_TBL AS t1 (a, b, c) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +STMT: SelectStmt +== 029 +SELECT * + FROM J1_TBL t1 (a, b, c) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +STMT: SelectStmt +== 030 +SELECT * + FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 031 +SELECT t1.a, t2.e + FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e) + WHERE t1.a = t2.d +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="d" +STMT: SelectStmt +== 032 +|-- +-- CROSS JOIN +-- Qualifications are not allowed on cross joins, +-- which degenerate into a standard unqualified inner join. +|-- + +SELECT * + FROM J1_TBL CROSS JOIN J2_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 033 +-- ambiguous column +SELECT i, k, t + FROM J1_TBL CROSS JOIN J2_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 034 +-- resolve previous ambiguity by specifying the table name +SELECT t1.i, k, t + FROM J1_TBL t1 CROSS JOIN J2_TBL t2 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 035 +SELECT ii, tt, kk + FROM (J1_TBL CROSS JOIN J2_TBL) + AS tx (ii, jj, tt, ii2, kk) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 036 +SELECT tx.ii, tx.jj, tx.kk + FROM (J1_TBL t1 (a, b, c) CROSS JOIN J2_TBL t2 (d, e)) + AS tx (ii, jj, tt, ii2, kk) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 037 +SELECT * + FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "a"="j2_tbl" +ALIAS: "b"="j2_tbl" +STMT: SelectStmt +== 038 +|-- +|-- +-- 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 * + FROM J1_TBL INNER JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 039 +-- Same as above, slightly different syntax +SELECT * + FROM J1_TBL JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 040 +SELECT * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a) + ORDER BY a, d +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 041 +SELECT * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) + ORDER BY b, t1.a +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 042 +-- test join using aliases +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +== 043 +-- ok +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +== 044 +-- ok +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +== 045 +-- error +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.i = 1 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="x" column="i" +STMT: SelectStmt +== 046 +-- ok +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="x" column="t" +STMT: SelectStmt +== 047 +-- error +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="x" column="i" +STMT: SelectStmt +== 048 +-- error (XXX could use better hint) +SELECT * FROM J1_TBL a1 JOIN J2_TBL a2 USING (i) AS a1 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "a1"="j1_tbl" +ALIAS: "a2"="j2_tbl" +STMT: SelectStmt +== 049 +-- error +SELECT x.* FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +== 050 +SELECT ROW(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +== 051 +SELECT row_to_json(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +== 052 +|-- +-- NATURAL JOIN +-- Inner equi-join on all columns with the same name +|-- + +SELECT * + FROM J1_TBL NATURAL JOIN J2_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 053 +SELECT * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 054 +SELECT * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 055 +-- mismatch number of columns +-- currently, Postgres will fill in with underlying names +SELECT * + FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +== 056 +|-- +-- Inner joins (equi-joins) +|-- + +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 057 +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 058 +|-- +-- Non-equi-joins +|-- + +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 059 +|-- +-- Outer joins +-- Note that OUTER is a noise word +|-- + +SELECT * + FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 060 +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 061 +SELECT * + FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 062 +SELECT * + FROM J1_TBL RIGHT JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 063 +SELECT * + FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 064 +SELECT * + FROM J1_TBL FULL JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 065 +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +== 066 +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 067 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "i4"="int4_tbl" +FILTER: schema="" table="a" column="twothousand" +FILTER: schema="" table="b" column="twothousand" +FILTER: schema="" table="a" column="fivethous" +FILTER: schema="" table="b" column="fivethous" +STMT: ExplainStmt +STMT: SelectStmt +== 068 +|-- +-- More complicated constructs +|-- + +|-- +-- Multiway full join +|-- + +CREATE TABLE t1 (name TEXT, n INTEGER) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 069 +CREATE TABLE t2 (name TEXT, n INTEGER) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 070 +CREATE TABLE t3 (name TEXT, n INTEGER) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +== 071 +INSERT INTO t1 VALUES ( 'bb', 11 ) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +INSERT INTO t2 VALUES ( 'bb', 12 ) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +INSERT INTO t2 VALUES ( 'cc', 22 ) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 074 +INSERT INTO t2 VALUES ( 'ee', 42 ) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +INSERT INTO t3 VALUES ( 'bb', 13 ) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +INSERT INTO t3 VALUES ( 'cc', 23 ) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +INSERT INTO t3 VALUES ( 'dd', 33 ) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 079 +|-- +-- 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) +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 080 +SELECT * FROM +(SELECT * FROM t2) as s2 +LEFT JOIN +(SELECT * FROM t3) s3 +USING (name) +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 081 +SELECT * FROM +(SELECT * FROM t2) as s2 +FULL JOIN +(SELECT * FROM t3) s3 +USING (name) +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 082 +-- 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 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 083 +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 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 084 +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 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 085 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 086 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 087 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 088 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 089 +-- 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) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 090 +-- Test for propagation of nullability constraints into sub-joins + +create temp table x (x1 int, x2 int) +-- +TABLE: name="x" schema="" table="x" ctx=DDL +STMT: CreateStmt +== 091 +insert into x values (1,11) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +insert into x values (2,22) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +insert into x values (3,null) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +insert into x values (4,44) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +insert into x values (5,null) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +create temp table y (y1 int, y2 int) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateStmt +== 097 +insert into y values (1,111) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +insert into y values (2,222) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +insert into y values (3,333) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 100 +insert into y values (4,null) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +select * from x +-- +TABLE: name="x" schema="" table="x" ctx=Select +STMT: SelectStmt +== 102 +select * from y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 103 +select * from x left join y on (x1 = y1 and x2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 104 +select * from x left join y on (x1 = y1 and y2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 105 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +== 106 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and x2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +== 107 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and y2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +== 108 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and xx2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +== 109 +-- 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) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +FILTER: schema="" table="" column="x2" +STMT: SelectStmt +== 110 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (y2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +FILTER: schema="" table="" column="y2" +STMT: SelectStmt +== 111 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (xx2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +FILTER: schema="" table="" column="xx2" +STMT: SelectStmt +== 112 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +== 113 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "aa"="int4_tbl" +ALIAS: "b"="float8_tbl" +ALIAS: "bb"="float8_tbl" +ALIAS: "x"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="unique1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="aa" column="f1" +FILTER: schema="" table="bb" column="f1" +STMT: SelectStmt +== 114 +-- try that with GEQO too +begin +-- +STMT: TransactionStmt +== 115 +set geqo = on +-- +STMT: VariableSetStmt +== 116 +set geqo_threshold = 2 +-- +STMT: VariableSetStmt +== 117 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "aa"="int4_tbl" +ALIAS: "b"="float8_tbl" +ALIAS: "bb"="float8_tbl" +ALIAS: "x"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="unique1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="aa" column="f1" +FILTER: schema="" table="bb" column="f1" +STMT: SelectStmt +== 118 +rollback +-- +STMT: TransactionStmt +== 119 +|-- +-- regression test: be sure we cope with proven-dummy append rels +|-- +explain (costs off) +select aa, bb, unique1, unique1 + from tenk1 right join b_star on aa = unique1 + where bb < bb and bb is null +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="b_star" schema="" table="b_star" ctx=Select +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +STMT: ExplainStmt +STMT: SelectStmt +== 120 +select aa, bb, unique1, unique1 + from tenk1 right join b_star on aa = unique1 + where bb < bb and bb is null +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="b_star" schema="" table="b_star" ctx=Select +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +STMT: SelectStmt +== 121 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +ALIAS: "i2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 122 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +ALIAS: "i2"="int8_tbl" +STMT: SelectStmt +== 123 +|-- +-- regression test: check a case where join_clause_is_movable_into() +-- used to give 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +ALIAS: "t4"="tenk1" +ALIAS: "t5"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t4" column="thousand" +FILTER: schema="" table="t5" column="unique1" +FILTER: schema="" table="ss" column="x1" +FILTER: schema="" table="t4" column="tenthous" +FILTER: schema="" table="ss" column="x2" +FILTER: schema="" table="t5" column="stringu1" +STMT: SelectStmt +== 124 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4a"="int4_tbl" +ALIAS: "i4b"="int4_tbl" +ALIAS: "t"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="thousand" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 125 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4a"="int4_tbl" +ALIAS: "i4b"="int4_tbl" +ALIAS: "t"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="thousand" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="tenthous" +STMT: SelectStmt +== 126 +|-- +-- checks for correct handling of quals in multiway outer joins +|-- +explain (costs off) +select t1.f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on t3.f1 > 0 + left join int4_tbl t4 on t3.f1 > 1 +where t4.f1 is null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +FILTER: schema="" table="t4" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 127 +select t1.f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on t3.f1 > 0 + left join int4_tbl t4 on t3.f1 > 1 +where t4.f1 is null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +FILTER: schema="" table="t4" column="f1" +STMT: SelectStmt +== 128 +explain (costs off) +select * +from int4_tbl t1 left join int4_tbl t2 on true + left join int4_tbl t3 on t2.f1 > 0 + left join int4_tbl t4 on t3.f1 > 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 129 +explain (costs off) +select * from onek t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join onek t3 on t2.unique1 != t3.unique1 + left join onek t4 on t3.unique1 = t4.unique1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="onek" +ALIAS: "t3"="onek" +ALIAS: "t4"="onek" +STMT: ExplainStmt +STMT: SelectStmt +== 130 +explain (costs off) +select * from int4_tbl t1 + left join (select now() from int4_tbl t2 + left join int4_tbl t3 on t2.f1 = t3.f1 + left join int4_tbl t4 on t3.f1 = t4.f1) s on true + inner join int4_tbl t5 on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int4_tbl" +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 131 +explain (costs off) +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on true + left join int4_tbl t4 on t2.f1 = t3.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 132 +explain (costs off) +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on t2.f1 = t3.f1 + left join int4_tbl t4 on t3.f1 != t4.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 133 +explain (costs off) +select * from int4_tbl t1 + left join (int4_tbl t2 left join int4_tbl t3 on t2.f1 > 0) on t2.f1 > 1 + left join int4_tbl t4 on t2.f1 > 2 and t3.f1 > 3 +where t1.f1 = coalesce(t2.f1, 1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="t2" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 134 +explain (costs off) +select * from int4_tbl t1 + left join ((select t2.f1 from int4_tbl t2 + left join int4_tbl t3 on t2.f1 > 0 + where t3.f1 is null) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = t1.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="tenk1" +FILTER: schema="" table="t3" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 135 +explain (costs off) +select * from int4_tbl t1 + left join ((select t2.f1 from int4_tbl t2 + left join int4_tbl t3 on t2.f1 > 0 + where t2.f1 <> coalesce(t3.f1, -1)) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = t1.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="tenk1" +FILTER: schema="" table="t2" column="f1" +FILTER: schema="" table="t3" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 136 +explain (costs off) +select * from onek t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join onek t3 on t2.unique1 = t3.unique1 + left join onek t4 on t3.unique1 = t4.unique1 and t2.unique2 = t4.unique2 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="onek" +ALIAS: "t3"="onek" +ALIAS: "t4"="onek" +STMT: ExplainStmt +STMT: SelectStmt +== 137 +explain (costs off) +select * from int8_tbl t1 left join + (int8_tbl t2 left join int8_tbl t3 full join int8_tbl t4 on false on false) + left join int8_tbl t5 on t2.q1 = t5.q1 +on t2.q2 = 123 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +ALIAS: "t5"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 138 +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from int8_tbl t3 where t3.q1 = t2.q1 offset 0) s + on t2.q1 = 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="t3" column="q1" +FILTER: schema="" table="t2" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 139 +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from generate_series(t2.q1, 100)) s + on t2.q1 = 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 140 +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select t2.q1 from int8_tbl t3) s + on t2.q1 = 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 141 +explain (costs off) +select * from onek t1 + left join onek t2 on true + left join lateral + (select * from onek t3 where t3.two = t2.two offset 0) s + on t2.unique1 = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="onek" +ALIAS: "t3"="onek" +FILTER: schema="" table="t3" column="two" +FILTER: schema="" table="t2" column="two" +STMT: ExplainStmt +STMT: SelectStmt +== 142 +|-- +-- 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 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 143 +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 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +== 144 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="tenk1" +ALIAS: "y"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 145 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="tenk1" +ALIAS: "y"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 146 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +== 147 +set enable_nestloop = 0 +-- +STMT: VariableSetStmt +== 148 +set enable_hashagg = 0 +-- +STMT: VariableSetStmt +== 149 +|-- +-- Check that we use the pathkeys from a prefix of the group by / order by +-- clause for the join pathkeys when that prefix covers all join quals. We +-- expect this to lead to an incremental sort for the group by / order by. +|-- +explain (costs off) +select x.thousand, x.twothousand, count(*) +from tenk1 x inner join tenk1 y on x.thousand = y.thousand +group by x.thousand, x.twothousand +order by x.thousand desc, x.twothousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="tenk1" +ALIAS: "y"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 150 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 151 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 152 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 153 +|-- +-- Clean up +|-- + +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 154 +DROP TABLE t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +== 155 +DROP TABLE t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: DropStmt +== 156 +DROP TABLE J1_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DDL +STMT: DropStmt +== 157 +DROP TABLE J2_TBL +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DDL +STMT: DropStmt +== 158 +-- 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) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 159 +CREATE TEMP TABLE t2 (a int, b int) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 160 +CREATE TEMP TABLE t3 (x int, y int) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +== 161 +INSERT INTO t1 VALUES (5, 10) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +INSERT INTO t1 VALUES (15, 20) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +INSERT INTO t1 VALUES (100, 100) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +INSERT INTO t1 VALUES (200, 1000) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +INSERT INTO t2 VALUES (200, 2000) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +INSERT INTO t3 VALUES (5, 20) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 167 +INSERT INTO t3 VALUES (6, 7) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +INSERT INTO t3 VALUES (7, 8) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +INSERT INTO t3 VALUES (500, 100) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 170 +DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "table1"="t1" +STMT: DeleteStmt +== 171 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 172 +DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: DeleteStmt +== 173 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 174 +DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "t3_other"="t3" +STMT: DeleteStmt +== 175 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 176 +-- Test join against inheritance tree + +create temp table t2a () inherits (t2) +-- +TABLE: name="t2a" schema="" table="t2a" ctx=DDL +STMT: CreateStmt +== 177 +insert into t2a values (200, 2001) +-- +TABLE: name="t2a" schema="" table="t2a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +select * from t1 left join t2 on (t1.a = t2.a) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 179 +-- Test matching of column name with wrong alias + +select t1.x from t1 join t3 on (t1.a = t3.x) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 180 +-- Test matching of locking clause with wrong alias + +select t1.*, t2.*, unnamed_join.* from + t1 join t2 on (t1.a = t2.a), t3 as unnamed_join + for update of unnamed_join +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +== 181 +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of unnamed_join +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +== 182 +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of foo +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +== 183 +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of foo +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +== 184 +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of bar +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +== 185 +|-- +-- regression test for 8.1 merge right join bug +|-- + +CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +== 186 +INSERT INTO tt1 VALUES (1, 11) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +INSERT INTO tt1 VALUES (2, NULL) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +== 189 +INSERT INTO tt2 VALUES (21, 11) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +INSERT INTO tt2 VALUES (22, 11) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +set enable_hashjoin to off +-- +STMT: VariableSetStmt +== 192 +set enable_nestloop to off +-- +STMT: VariableSetStmt +== 193 +-- these should give the same results + +select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tt2" schema="" table="tt2" ctx=Select +STMT: SelectStmt +== 194 +select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol +-- +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: SelectStmt +== 195 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 196 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 197 +|-- +-- regression test for bug #18522 (merge-right-anti-join in inner_unique cases) +|-- + +create temp table tbl_ra(a int unique, b int) +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DDL +STMT: CreateStmt +== 198 +insert into tbl_ra select i, i%100 from generate_series(1,1000)i +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 199 +create index on tbl_ra (b) +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DDL +STMT: IndexStmt +== 200 +analyze tbl_ra +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DDL +STMT: VacuumStmt +== 201 +set enable_hashjoin to off +-- +STMT: VariableSetStmt +== 202 +set enable_nestloop to off +-- +STMT: VariableSetStmt +== 203 +-- ensure we get a merge right anti join +explain (costs off) +select * from tbl_ra t1 +where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2 +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +ALIAS: "t1"="tbl_ra" +ALIAS: "t2"="tbl_ra" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 204 +-- and check we get the expected results +select * from tbl_ra t1 +where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2 +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +ALIAS: "t1"="tbl_ra" +ALIAS: "t2"="tbl_ra" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +STMT: SelectStmt +== 205 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 206 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 207 +|-- +-- regression test for bug #13908 (hash join with skew tuples & nbatch increase) +|-- + +set work_mem to '64kB' +-- +STMT: VariableSetStmt +== 208 +set enable_mergejoin to off +-- +STMT: VariableSetStmt +== 209 +set enable_memoize to off +-- +STMT: VariableSetStmt +== 210 +explain (costs off) +select count(*) from tenk1 a, tenk1 b + where a.hundred = b.thousand and (b.fivethous % 10) < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="hundred" +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="b" column="fivethous" +STMT: ExplainStmt +STMT: SelectStmt +== 211 +select count(*) from tenk1 a, tenk1 b + where a.hundred = b.thousand and (b.fivethous % 10) < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="hundred" +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="b" column="fivethous" +STMT: SelectStmt +== 212 +reset work_mem +-- +STMT: VariableSetStmt +== 213 +reset enable_mergejoin +-- +STMT: VariableSetStmt +== 214 +reset enable_memoize +-- +STMT: VariableSetStmt +== 215 +|-- +-- regression test for 8.2 bug with improper re-ordering of left joins +|-- + +create temp table tt3(f1 int, f2 text) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +== 216 +insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 217 +analyze tt3 +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: VacuumStmt +== 218 +create temp table tt4(f1 int) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: CreateStmt +== 219 +insert into tt4 values (0),(1),(9999) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 220 +analyze tt4 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: VacuumStmt +== 221 +set enable_nestloop to off +-- +STMT: VariableSetStmt +== 222 +EXPLAIN (COSTS OFF) +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE COALESCE(c.f1, 0) = 0 +) AS d ON (a.f1 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +ALIAS: "a"="tt4" +ALIAS: "b"="tt3" +ALIAS: "c"="tt3" +FILTER: schema="" table="d" column="f1" +FILTER: schema="" table="c" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 223 +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE COALESCE(c.f1, 0) = 0 +) AS d ON (a.f1 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +ALIAS: "a"="tt4" +ALIAS: "b"="tt3" +ALIAS: "c"="tt3" +FILTER: schema="" table="d" column="f1" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 224 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 225 +|-- +-- basic semijoin and antijoin recognition tests +|-- + +explain (costs off) +select a.* from tenk1 a +where unique1 in (select unique2 from tenk1 b) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 226 +-- sadly, this is not an antijoin +explain (costs off) +select a.* from tenk1 a +where unique1 not in (select unique2 from tenk1 b) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 227 +explain (costs off) +select a.* from tenk1 a +where exists (select 1 from tenk1 b where a.unique1 = b.unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 228 +explain (costs off) +select a.* from tenk1 a +where not exists (select 1 from tenk1 b where a.unique1 = b.unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 229 +explain (costs off) +select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2 +where b.unique2 is null +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 230 +|-- +-- regression test for proper handling of outer joins within antijoins +|-- + +create temp table tt4x(c1 int, c2 int, c3 int) +-- +TABLE: name="tt4x" schema="" table="tt4x" ctx=DDL +STMT: CreateStmt +== 231 +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 +) +-- +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +ALIAS: "t1"="tt4x" +ALIAS: "t2"="tt4x" +ALIAS: "t3"="tt4x" +ALIAS: "t4"="tt4x" +ALIAS: "t5"="tt4x" +FILTER: schema="" table="t1" column="c1" +FILTER: schema="" table="t2" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +== 232 +|-- +-- regression test for problems of the sort depicted in bug #3494 +|-- + +create temp table tt5(f1 int, f2 int) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: CreateStmt +== 233 +create temp table tt6(f1 int, f2 int) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: CreateStmt +== 234 +insert into tt5 values(1, 10) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 235 +insert into tt5 values(1, 11) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 236 +insert into tt6 values(1, 9) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 237 +insert into tt6 values(1, 2) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 238 +insert into tt6 values(2, 9) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 239 +select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2 +-- +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +FILTER: schema="" table="tt5" column="f1" +FILTER: schema="" table="tt6" column="f1" +FILTER: schema="" table="tt5" column="f1" +FILTER: schema="" table="tt5" column="f2" +FILTER: schema="" table="tt6" column="f2" +STMT: SelectStmt +== 240 +|-- +-- regression test for problems of the sort depicted in bug #3588 +|-- + +create temp table xx (pkxx int) +-- +TABLE: name="xx" schema="" table="xx" ctx=DDL +STMT: CreateStmt +== 241 +create temp table yy (pkyy int, pkxx int) +-- +TABLE: name="yy" schema="" table="yy" ctx=DDL +STMT: CreateStmt +== 242 +insert into xx values (1) +-- +TABLE: name="xx" schema="" table="xx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 243 +insert into xx values (2) +-- +TABLE: name="xx" schema="" table="xx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +insert into xx values (3) +-- +TABLE: name="xx" schema="" table="xx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +insert into yy values (101, 1) +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 246 +insert into yy values (201, 2) +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 247 +insert into yy values (301, NULL) +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +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 +-- +TABLE: name="yy" schema="" table="yy" ctx=Select +TABLE: name="xx" schema="" table="xx" ctx=Select +TABLE: name="xx" schema="" table="xx" ctx=Select +TABLE: name="yy" schema="" table="yy" ctx=Select +ALIAS: "xxa"="xx" +ALIAS: "xxb"="xx" +FILTER: schema="" table="" column="pkyy" +STMT: SelectStmt +== 249 +|-- +-- 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) +-- +TABLE: name="zt1" schema="" table="zt1" ctx=DDL +STMT: CreateStmt +== 250 +create temp table zt2 (f2 int primary key) +-- +TABLE: name="zt2" schema="" table="zt2" ctx=DDL +STMT: CreateStmt +== 251 +create temp table zt3 (f3 int primary key) +-- +TABLE: name="zt3" schema="" table="zt3" ctx=DDL +STMT: CreateStmt +== 252 +insert into zt1 values(53) +-- +TABLE: name="zt1" schema="" table="zt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +insert into zt2 values(53) +-- +TABLE: name="zt2" schema="" table="zt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +select * from + zt2 left join zt3 on (f2 = f3) + left join zt1 on (f3 = f1) +where f2 = 53 +-- +TABLE: name="zt2" schema="" table="zt2" ctx=Select +TABLE: name="zt3" schema="" table="zt3" ctx=Select +TABLE: name="zt1" schema="" table="zt1" ctx=Select +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 255 +create temp view zv1 as select *,'dummy'::text AS junk from zt1 +-- +TABLE: name="zv1" schema="" table="zv1" ctx=DDL +TABLE: name="zt1" schema="" table="zt1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 256 +select * from + zt2 left join zt3 on (f2 = f3) + left join zv1 on (f3 = f1) +where f2 = 53 +-- +TABLE: name="zt2" schema="" table="zt2" ctx=Select +TABLE: name="zt3" schema="" table="zt3" ctx=Select +TABLE: name="zv1" schema="" table="zv1" ctx=Select +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 257 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +FILTER: schema="" table="a" column="ten" +FILTER: schema="" table="b" column="hundred" +STMT: SelectStmt +== 258 +|-- +-- 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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="c" column="thousand" +FILTER: schema="" table="b" column="unique2" +STMT: PrepareStmt +STMT: SelectStmt +== 259 +execute foo(true) +-- +STMT: ExecuteStmt +== 260 +execute foo(false) +-- +STMT: ExecuteStmt +== 261 +|-- +-- test for sane behavior with noncanonical merge clauses, per bug #4926 +|-- + +begin +-- +STMT: TransactionStmt +== 262 +set enable_mergejoin = 1 +-- +STMT: VariableSetStmt +== 263 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +== 264 +set enable_nestloop = 0 +-- +STMT: VariableSetStmt +== 265 +create temp table a (i integer) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +== 266 +create temp table b (x integer, y integer) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +== 267 +select * from a left join b on i = x and i = y and x = i +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: SelectStmt +== 268 +rollback +-- +STMT: TransactionStmt +== 269 +|-- +-- test handling of merge clauses using record_ops +|-- +begin +-- +STMT: TransactionStmt +== 270 +create type mycomptype as (id int, v bigint) +-- +STMT: CompositeTypeStmt +== 271 +create temp table tidv (idv mycomptype) +-- +TABLE: name="tidv" schema="" table="tidv" ctx=DDL +STMT: CreateStmt +== 272 +create index on tidv (idv) +-- +TABLE: name="tidv" schema="" table="tidv" ctx=DDL +STMT: IndexStmt +== 273 +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv +-- +TABLE: name="tidv" schema="" table="tidv" ctx=Select +TABLE: name="tidv" schema="" table="tidv" ctx=Select +ALIAS: "a"="tidv" +ALIAS: "b"="tidv" +FILTER: schema="" table="a" column="idv" +FILTER: schema="" table="b" column="idv" +STMT: ExplainStmt +STMT: SelectStmt +== 274 +set enable_mergejoin = 0 +-- +STMT: VariableSetStmt +== 275 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +== 276 +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv +-- +TABLE: name="tidv" schema="" table="tidv" ctx=Select +TABLE: name="tidv" schema="" table="tidv" ctx=Select +ALIAS: "a"="tidv" +ALIAS: "b"="tidv" +FILTER: schema="" table="a" column="idv" +FILTER: schema="" table="b" column="idv" +STMT: ExplainStmt +STMT: SelectStmt +== 277 +rollback +-- +STMT: TransactionStmt +== 278 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 279 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 280 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 281 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 282 +|-- +-- test incorrect failure to NULL pulled-up subexpressions +|-- +begin +-- +STMT: TransactionStmt +== 283 +create temp table a ( + code char not null, + constraint a_pk primary key (code) +) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +== 284 +create temp table b ( + a char not null, + num integer not null, + constraint b_pk primary key (a, num) +) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +== 285 +create temp table c ( + name char not null, + a char, + constraint c_pk primary key (name) +) +-- +TABLE: name="c" schema="" table="c" ctx=DDL +STMT: CreateStmt +== 286 +insert into a (code) values ('p') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 287 +insert into a (code) values ('q') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 288 +insert into b (a, num) values ('p', 1) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 289 +insert into b (a, num) values ('p', 2) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 290 +insert into c (name, a) values ('A', 'p') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 291 +insert into c (name, a) values ('B', 'q') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 292 +insert into c (name, a) values ('C', null) +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +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 +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 294 +rollback +-- +STMT: TransactionStmt +== 295 +|-- +-- 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 +-- +STMT: SelectStmt +== 296 +-- 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 +-- +STMT: SelectStmt +== 297 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 298 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="tenk1" +STMT: SelectStmt +== 299 +|-- +-- nested nestloops can require nested PlaceHolderVars +|-- + +create temp table nt1 ( + id int primary key, + a1 boolean, + a2 boolean +) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DDL +STMT: CreateStmt +== 300 +create temp table nt2 ( + id int primary key, + nt1_id int, + b1 boolean, + b2 boolean, + foreign key (nt1_id) references nt1(id) +) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DDL +STMT: CreateStmt +== 301 +create temp table nt3 ( + id int primary key, + nt2_id int, + c1 boolean, + foreign key (nt2_id) references nt2(id) +) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DDL +STMT: CreateStmt +== 302 +insert into nt1 values (1,true,true) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 303 +insert into nt1 values (2,true,false) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 304 +insert into nt1 values (3,false,false) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 305 +insert into nt2 values (1,1,true,true) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +insert into nt2 values (2,2,true,false) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 307 +insert into nt2 values (3,3,false,false) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 308 +insert into nt3 values (1,1,true) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 309 +insert into nt3 values (2,2,false) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 310 +insert into nt3 values (3,3,true) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 311 +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 +-- +TABLE: name="nt3" schema="" table="nt3" ctx=Select +TABLE: name="nt2" schema="" table="nt2" ctx=Select +TABLE: name="nt1" schema="" table="nt1" ctx=Select +ALIAS: "nt2"="nt2" +ALIAS: "nt3"="nt3" +FILTER: schema="" table="nt3" column="id" +FILTER: schema="" table="ss2" column="b3" +STMT: ExplainStmt +STMT: SelectStmt +== 312 +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 +-- +TABLE: name="nt3" schema="" table="nt3" ctx=Select +TABLE: name="nt2" schema="" table="nt2" ctx=Select +TABLE: name="nt1" schema="" table="nt1" ctx=Select +ALIAS: "nt2"="nt2" +ALIAS: "nt3"="nt3" +FILTER: schema="" table="nt3" column="id" +FILTER: schema="" table="ss2" column="b3" +STMT: SelectStmt +== 313 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="ss" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 314 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="ss" column="y" +STMT: SelectStmt +== 315 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i81"="int8_tbl" +FILTER: schema="" table="i41" column="f1" +FILTER: schema="" table="ss1" column="loc" +FILTER: schema="" table="ss1" column="lat" +STMT: ExplainStmt +STMT: SelectStmt +== 316 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i81"="int8_tbl" +FILTER: schema="" table="i41" column="f1" +FILTER: schema="" table="ss1" column="loc" +FILTER: schema="" table="ss1" column="lat" +STMT: SelectStmt +== 317 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +STMT: SelectStmt +== 318 +select * from int4_tbl a full join int4_tbl b on false +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +STMT: SelectStmt +== 319 +|-- +-- test for ability to use a cartesian join when necessary +|-- + +create temp table q1 as select 1 as q1 +-- +TABLE: name="q1" schema="" table="q1" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 320 +create temp table q2 as select 0 as q2 +-- +TABLE: name="q2" schema="" table="q2" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 321 +analyze q1 +-- +TABLE: name="q1" schema="" table="q1" ctx=DDL +STMT: VacuumStmt +== 322 +analyze q2 +-- +TABLE: name="q2" schema="" table="q2" ctx=DDL +STMT: VacuumStmt +== 323 +explain (costs off) +select * from + tenk1 join int4_tbl on f1 = twothousand, + q1, q2 +where q1 = thousand or q2 = thousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +TABLE: name="q2" schema="" table="q2" ctx=Select +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 324 +explain (costs off) +select * from + tenk1 join int4_tbl on f1 = twothousand, + q1, q2 +where thousand = (q1 + q2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +TABLE: name="q2" schema="" table="q2" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 325 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="a" column="q1" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="b" column="q1" +FILTER: schema="" table="a" column="q2" +FILTER: schema="" table="b" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 326 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: ExplainStmt +STMT: SelectStmt +== 327 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: SelectStmt +== 328 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="i4" column="f1" +FILTER: schema="" table="t3" column="fivethous" +STMT: SelectStmt +== 329 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: ExplainStmt +STMT: SelectStmt +== 330 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: SelectStmt +== 331 +-- 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 +-- +STMT: ExplainStmt +STMT: SelectStmt +== 332 +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 +-- +STMT: SelectStmt +== 333 +-- 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 +-- +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 334 +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 +-- +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 335 +-- Test PHV in a semijoin qual, which confused useless-RTE removal (bug #17700) +explain (verbose, costs off) +with ctetable as not materialized ( select 1 as f1 ) +select * from ctetable c1 +where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ) +-- +ALIAS: "c1"="ctetable" +ALIAS: "c2"="ctetable" +ALIAS: "c3"="ctetable" +CTE: "ctetable" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 336 +with ctetable as not materialized ( select 1 as f1 ) +select * from ctetable c1 +where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ) +-- +ALIAS: "c1"="ctetable" +ALIAS: "c2"="ctetable" +ALIAS: "c3"="ctetable" +CTE: "ctetable" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 337 +-- Test PHV that winds up in a Result node, despite having nonempty nullingrels +explain (verbose, costs off) +select table_catalog, table_name +from int4_tbl t1 + inner join (int8_tbl t2 + left join information_schema.column_udt_usage on null) + on null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="information_schema.column_udt_usage" schema="information_schema" table="column_udt_usage" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 338 +-- Test handling of qual pushdown to appendrel members with non-Var outputs +explain (verbose, costs off) +select * from int4_tbl left join ( + select text 'foo' union all select text 'bar' +) ss(x) on true +where ss.x is null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="ss" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 339 +|-- +-- test inlining of immutable functions +|-- +create function f_immutable_int4(i integer) returns integer as +$$ begin return i; end; $$ language plpgsql immutable +-- +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 340 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 341 +explain (verbose, costs off) +select unique1, x.* +from tenk1, (select *, random() from f_immutable_int4(1) x) x +where x = unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 342 +explain (costs off) +select unique1 from tenk1, f_immutable_int4(1) x where x = unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 343 +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 344 +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 345 +explain (costs off) +select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 346 +explain (costs off) +select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 347 +explain (costs off) +select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 348 +explain (costs off) +select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 349 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 350 +-- 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 +-- +TABLE: name="nt3" schema="" table="nt3" ctx=Select +TABLE: name="nt2" schema="" table="nt2" ctx=Select +ALIAS: "nt2"="nt2" +ALIAS: "nt3"="nt3" +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="nt3" column="id" +FILTER: schema="" table="ss2" column="b3" +STMT: ExplainStmt +STMT: SelectStmt +== 351 +drop function f_immutable_int4(int) +-- +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=DDL +STMT: DropStmt +== 352 +-- test inlining when function returns composite + +create function mki8(bigint, bigint) returns int8_tbl as +$$select row($1,$2)::int8_tbl$$ language sql +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 353 +create function mki4(int) returns int4_tbl as +$$select row($1)::int4_tbl$$ language sql +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 354 +explain (verbose, costs off) +select * from mki8(1,2) +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 355 +select * from mki8(1,2) +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=Call +STMT: SelectStmt +== 356 +explain (verbose, costs off) +select * from mki4(42) +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 357 +select * from mki4(42) +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=Call +STMT: SelectStmt +== 358 +drop function mki8(bigint, bigint) +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=DDL +STMT: DropStmt +== 359 +drop function mki4(int) +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=DDL +STMT: DropStmt +== 360 +-- test const-folding of a whole-row Var into a per-field Var +-- (need to inline a function to reach this case, else parser does it) +create function f_field_select(t onek) returns int4 as +$$ select t.unique2; $$ language sql immutable +-- +FUNCTION: name="f_field_select" function="f_field_select" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 361 +explain (verbose, costs off) +select (t2.*).unique1, f_field_select(t2) from tenk1 t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join int8_tbl t3 on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="onek" +ALIAS: "t3"="int8_tbl" +FUNCTION: name="f_field_select" function="f_field_select" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 362 +drop function f_field_select(t onek) +-- +FUNCTION: name="f_field_select" function="f_field_select" schema="" ctx=DDL +STMT: DropStmt +== 363 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 364 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 365 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 366 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FILTER: schema="" table="t1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 367 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FILTER: schema="" table="t1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 368 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 369 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 370 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 371 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int4_tbl" +STMT: SelectStmt +== 372 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fault" +STMT: ExplainStmt +STMT: SelectStmt +== 373 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fault" +STMT: SelectStmt +== 374 +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 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 375 +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 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 376 +|-- +-- 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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 377 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 378 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 379 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 380 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FILTER: schema="" table="a" column="unique2" +FILTER: schema="" table="b" column="twothousand" +FILTER: schema="" table="a" column="twothousand" +STMT: ExplainStmt +STMT: SelectStmt +== 381 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FILTER: schema="" table="a" column="unique2" +FILTER: schema="" table="b" column="twothousand" +FILTER: schema="" table="a" column="twothousand" +STMT: SelectStmt +== 382 +-- related case + +explain (costs off) +select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, + lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="t2" column="q1" +FILTER: schema="" table="t2" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 383 +select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, + lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="t2" column="q1" +FILTER: schema="" table="t2" column="q2" +STMT: SelectStmt +== 384 +|-- +-- 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) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 385 +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) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="tenk1" +STMT: SelectStmt +== 386 +|-- +-- check handling of a variable-free join alias +|-- +explain (verbose, costs off) +select * from +int4_tbl i0 left join +( (select *, 123 as x from int4_tbl i1) ss1 + left join + (select *, q2 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on (i0.f1 = ss0.f1) +order by i0.f1, x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i0"="int4_tbl" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 387 +select * from +int4_tbl i0 left join +( (select *, 123 as x from int4_tbl i1) ss1 + left join + (select *, q2 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on (i0.f1 = ss0.f1) +order by i0.f1, x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i0"="int4_tbl" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int8_tbl" +STMT: SelectStmt +== 388 +|-- +-- 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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 389 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: SelectStmt +== 390 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 391 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: SelectStmt +== 392 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 393 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 394 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 395 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +STMT: SelectStmt +== 396 +-- check handling of a variable-free qual for a non-commutable outer join +explain (costs off) +select nspname +from (select 1 as x) ss1 +left join +( select n.nspname, c.relname + from pg_class c left join pg_namespace n on n.oid = c.relnamespace + where c.relkind = 'r' +) ss2 on false +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "n"="pg_namespace" +FILTER: schema="" table="c" column="relkind" +STMT: ExplainStmt +STMT: SelectStmt +== 397 +-- check handling of apparently-commutable outer joins with non-commutable +-- joins between them +explain (costs off) +select 1 from + int4_tbl i4 + left join int8_tbl i8 on i4.f1 is not null + left join (select 1 as a) ss1 on null + join int4_tbl i42 on ss1.a is null or i8.q1 <> i8.q2 + right join (select 2 as b) ss2 + on ss2.b < i4.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 398 +|-- +-- 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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 399 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss" column="f1" +STMT: SelectStmt +== 400 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +ALIAS: "t3"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss2" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 401 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +ALIAS: "t3"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss2" column="f1" +STMT: SelectStmt +== 402 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "tt1"="text_tbl" +ALIAS: "tt2"="text_tbl" +ALIAS: "tt3"="text_tbl" +ALIAS: "tt4"="text_tbl" +ALIAS: "tt5"="text_tbl" +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="ss1" column="c0" +STMT: ExplainStmt +STMT: SelectStmt +== 403 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "tt1"="text_tbl" +ALIAS: "tt2"="text_tbl" +ALIAS: "tt3"="text_tbl" +ALIAS: "tt4"="text_tbl" +ALIAS: "tt5"="text_tbl" +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="ss1" column="c0" +STMT: SelectStmt +== 404 +explain (verbose, costs off) +select 1 from + int4_tbl as i4 + inner join + ((select 42 as n from int4_tbl x1 left join int8_tbl x2 on f1 = q1) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "x1"="int4_tbl" +ALIAS: "x2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 405 +select 1 from + int4_tbl as i4 + inner join + ((select 42 as n from int4_tbl x1 left join int8_tbl x2 on f1 = q1) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "x1"="int4_tbl" +ALIAS: "x2"="int8_tbl" +STMT: SelectStmt +== 406 +|-- +-- check a case where we formerly generated invalid parameterized paths +|-- + +begin +-- +STMT: TransactionStmt +== 407 +create temp table t (a int unique) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 408 +explain (costs off) +select 1 from t t1 + join lateral (select t1.a from (select 1) foo offset 0) as s1 on true + join + (select 1 from t t2 + inner join (t t3 + left join (t t4 left join t t5 on t4.a = 1) + on t3.a = t4.a) + on false + where t3.a = coalesce(t5.a,1)) as s2 + on true +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +ALIAS: "t5"="t" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t5" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 409 +rollback +-- +STMT: TransactionStmt +== 410 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="ss1" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +== 411 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="ss1" column="c2" +STMT: SelectStmt +== 412 +|-- +-- 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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a1"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 413 +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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a1"="tenk1" +STMT: SelectStmt +== 414 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 415 +explain (costs off) + select * from tenk1 a full join tenk1 b using(unique2) where unique2 = 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 416 +|-- +-- 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 +-- +STMT: VariableSetStmt +== 417 +set enable_nestloop to off +-- +STMT: VariableSetStmt +== 418 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="b" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 419 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="b" column="q1" +STMT: SelectStmt +== 420 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 421 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 422 +|-- +-- test join strength reduction with a SubPlan providing the proof +|-- + +explain (costs off) +select a.unique1, b.unique2 + from onek a left join onek b on a.unique1 = b.unique2 + where (b.unique2, random() > 0) = any (select q1, random() > 0 from int8_tbl c where c.q1 < b.unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +ALIAS: "c"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="b" column="unique2" +FILTER: schema="" table="c" column="q1" +FILTER: schema="" table="b" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 423 +select a.unique1, b.unique2 + from onek a left join onek b on a.unique1 = b.unique2 + where (b.unique2, random() > 0) = any (select q1, random() > 0 from int8_tbl c where c.q1 < b.unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +ALIAS: "c"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="b" column="unique2" +FILTER: schema="" table="c" column="q1" +FILTER: schema="" table="b" column="unique1" +STMT: SelectStmt +== 424 +|-- +-- test full-join strength reduction +|-- + +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 425 +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +STMT: SelectStmt +== 426 +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 427 +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +== 428 +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 and b.unique2 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 429 +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 and b.unique2 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +== 430 +|-- +-- test result-RTE removal underneath a full join +|-- + +explain (costs off) +select * from + (select * from int8_tbl i81 join (values(123,2)) v(v1,v2) on q2=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on q2=v1) ss2 +on true +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 431 +select * from + (select * from int8_tbl i81 join (values(123,2)) v(v1,v2) on q2=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on q2=v1) ss2 +on true +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +STMT: SelectStmt +== 432 +|-- +-- test join removal +|-- + +begin +-- +STMT: TransactionStmt +== 433 +CREATE TEMP TABLE a (id int PRIMARY KEY, b_id int) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +== 434 +CREATE TEMP TABLE b (id int PRIMARY KEY, c_id int) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +== 435 +CREATE TEMP TABLE c (id int PRIMARY KEY) +-- +TABLE: name="c" schema="" table="c" ctx=DDL +STMT: CreateStmt +== 436 +CREATE TEMP TABLE d (a int, b int) +-- +TABLE: name="d" schema="" table="d" ctx=DDL +STMT: CreateStmt +== 437 +INSERT INTO a VALUES (0, 0), (1, NULL) +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 438 +INSERT INTO b VALUES (0, 0), (1, NULL) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 439 +INSERT INTO c VALUES (0), (1) +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 440 +INSERT INTO d VALUES (1,3), (2,2), (3,1) +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 441 +-- 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 +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 442 +explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="c" schema="" table="c" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 443 +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) +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="c" schema="" table="c" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 444 +-- 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 +) +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="c" schema="" table="c" ctx=Select +FILTER: schema="" table="" column="id" +STMT: ExplainStmt +STMT: SelectStmt +== 445 +-- check optimization with oddly-nested outer joins +explain (costs off) +select a1.id from + (a a1 left join a a2 on true) + left join + (a a3 left join a a4 on a3.id = a4.id) + on a2.id = a3.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "a1"="a" +ALIAS: "a2"="a" +ALIAS: "a3"="a" +ALIAS: "a4"="a" +STMT: ExplainStmt +STMT: SelectStmt +== 446 +explain (costs off) +select a1.id from + (a a1 left join a a2 on a1.id = a2.id) + left join + (a a3 left join a a4 on a3.id = a4.id) + on a2.id = a3.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "a1"="a" +ALIAS: "a2"="a" +ALIAS: "a3"="a" +ALIAS: "a4"="a" +STMT: ExplainStmt +STMT: SelectStmt +== 447 +explain (costs off) +select 1 from a t1 + left join a t2 on true + inner join a t3 on true + left join a t4 on t2.id = t4.id and t2.id = t3.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "t1"="a" +ALIAS: "t2"="a" +ALIAS: "t3"="a" +ALIAS: "t4"="a" +STMT: ExplainStmt +STMT: SelectStmt +== 448 +-- another example (bug #17781) +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select null as f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int8_tbl" +ALIAS: "t6"="int4_tbl" +ALIAS: "t7"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 449 +-- variant with Var rather than PHV coming from t6 +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int8_tbl" +ALIAS: "t6"="int4_tbl" +ALIAS: "t7"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 450 +-- per further discussion of bug #17781 +explain (costs off) +select ss1.x +from (select f1/2 as x from int4_tbl i4 left join a on a.id = i4.f1) ss1 + right join int8_tbl i8 on true +where current_user is not null +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 451 +-- this is to add a Result node + +-- and further discussion of bug #17781 +explain (costs off) +select * +from int8_tbl t1 + left join (int8_tbl t2 left join onek t3 on t2.q1 > t3.unique1) + on t1.q2 = t2.q2 + left join onek t4 + on t2.q2 < t3.unique2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="onek" +ALIAS: "t4"="onek" +STMT: ExplainStmt +STMT: SelectStmt +== 452 +-- More tests of correct placement of pseudoconstant quals + +-- simple constant-false condition +explain (costs off) +select * from int8_tbl t1 left join + (int8_tbl t2 inner join int8_tbl t3 on false + left join int8_tbl t4 on t2.q2 = t4.q2) +on t1.q1 = t2.q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 453 +-- deduce constant-false from an EquivalenceClass +explain (costs off) +select * from int8_tbl t1 left join + (int8_tbl t2 inner join int8_tbl t3 on (t2.q1-t3.q2) = 0 and (t2.q1-t3.q2) = 1 + left join int8_tbl t4 on t2.q2 = t4.q2) +on t1.q1 = t2.q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 454 +-- pseudoconstant based on an outer-level Param +explain (costs off) +select exists( + select * from int8_tbl t1 left join + (int8_tbl t2 inner join int8_tbl t3 on x0.f1 = 1 + left join int8_tbl t4 on t2.q2 = t4.q2) + on t1.q1 = t2.q1 +) from int4_tbl x0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +ALIAS: "x0"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 455 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 456 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 457 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 458 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 459 +-- join removal is not possible here +explain (costs off) +select 1 from a t1 + left join (a t2 left join a t3 on t2.id = 1) on t2.id = 1 +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "t1"="a" +ALIAS: "t2"="a" +ALIAS: "t3"="a" +STMT: ExplainStmt +STMT: SelectStmt +== 460 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 461 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 462 +-- 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 +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="q" column="id" +FILTER: schema="" table="gs" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 463 +-- check join removal within RHS of an outer join +explain (costs off) +select c.id, ss.a from c + left join (select d.a from onerow, d left join b on d.a = b.id) ss + on c.id = ss.a +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 464 +CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id) +-- +TABLE: name="parted_b" schema="" table="parted_b" ctx=DDL +STMT: CreateStmt +== 465 +CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10) +-- +TABLE: name="parted_b1" schema="" table="parted_b1" ctx=DDL +STMT: CreateStmt +== 466 +-- test join removals on a partitioned table +explain (costs off) +select a.* from a left join parted_b pb on a.b_id = pb.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="parted_b" schema="" table="parted_b" ctx=Select +ALIAS: "pb"="parted_b" +STMT: ExplainStmt +STMT: SelectStmt +== 467 +rollback +-- +STMT: TransactionStmt +== 468 +create temp table parent (k int primary key, pd int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 469 +create temp table child (k int unique, cd int) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 470 +insert into parent values (1, 10), (2, 20), (3, 30) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 471 +insert into child values (1, 100), (4, 400) +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 472 +-- this case is optimizable +select p.* from parent p left join child c on (p.k = c.k) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: SelectStmt +== 473 +explain (costs off) + select p.* from parent p left join child c on (p.k = c.k) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: ExplainStmt +STMT: SelectStmt +== 474 +-- 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) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: SelectStmt +== 475 +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) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: ExplainStmt +STMT: SelectStmt +== 476 +-- 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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: SelectStmt +== 477 +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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: ExplainStmt +STMT: SelectStmt +== 478 +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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +TABLE: name="parent" schema="" table="parent" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +ALIAS: "x"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: SelectStmt +== 479 +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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +TABLE: name="parent" schema="" table="parent" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +ALIAS: "x"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: ExplainStmt +STMT: SelectStmt +== 480 +-- bug 5255: this is not optimizable by join removal +begin +-- +STMT: TransactionStmt +== 481 +CREATE TEMP TABLE a (id int PRIMARY KEY) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +== 482 +CREATE TEMP TABLE b (id int PRIMARY KEY, a_id int) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +== 483 +INSERT INTO a VALUES (0), (1) +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 484 +INSERT INTO b VALUES (0, 0), (1, NULL) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 485 +SELECT * FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0) +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="a" column="id" +STMT: SelectStmt +== 486 +SELECT b.* FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0) +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="a" column="id" +STMT: SelectStmt +== 487 +rollback +-- +STMT: TransactionStmt +== 488 +-- another join removal bug: this is not optimizable, either +begin +-- +STMT: TransactionStmt +== 489 +create temp table innertab (id int8 primary key, dat1 int8) +-- +TABLE: name="innertab" schema="" table="innertab" ctx=DDL +STMT: CreateStmt +== 490 +insert into innertab values(123, 42) +-- +TABLE: name="innertab" schema="" table="innertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 491 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +STMT: SelectStmt +== 492 +-- join removal bug #17769: can't remove if there's a pushed-down reference +EXPLAIN (COSTS OFF) +SELECT q2 FROM + (SELECT * + FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss + WHERE COALESCE(dat1, 0) = q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +FILTER: schema="" table="" column="dat1" +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 493 +-- join removal bug #17773: otherwise-removable PHV appears in a qual condition +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q2 FROM + (SELECT q2, 'constant'::text AS x + FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss + RIGHT JOIN int4_tbl ON NULL + WHERE x >= x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 494 +-- join removal bug #17786: check that OR conditions are cleaned up +EXPLAIN (COSTS OFF) +SELECT f1, x +FROM int4_tbl + JOIN ((SELECT 42 AS x FROM int8_tbl LEFT JOIN innertab ON q1 = id) AS ss1 + RIGHT JOIN tenk1 ON NULL) + ON tenk1.unique1 = ss1.x OR tenk1.unique2 = ss1.x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 495 +rollback +-- +STMT: TransactionStmt +== 496 +-- another join removal bug: we must clean up correctly when removing a PHV +begin +-- +STMT: TransactionStmt +== 497 +create temp table uniquetbl (f1 text unique) +-- +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=DDL +STMT: CreateStmt +== 498 +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 +-- +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +ALIAS: "t1"="uniquetbl" +ALIAS: "t3"="uniquetbl" +STMT: ExplainStmt +STMT: SelectStmt +== 499 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "t0"="text_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "u1"="uniquetbl" +FILTER: schema="" table="ss" column="stringu2" +FILTER: schema="" table="ss" column="case1" +STMT: ExplainStmt +STMT: SelectStmt +== 500 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "t0"="text_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "u1"="uniquetbl" +FILTER: schema="" table="ss" column="stringu2" +FILTER: schema="" table="ss" column="case1" +STMT: SelectStmt +== 501 +rollback +-- +STMT: TransactionStmt +== 502 +-- another join removal bug: we must clean up EquivalenceClasses too +begin +-- +STMT: TransactionStmt +== 503 +create temp table t (a int unique) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 504 +insert into t values (1) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 505 +explain (costs off) +select 1 +from t t1 + left join (select 2 as c + from t t2 left join t t3 on t2.a = t3.a) s + on true +where t1.a = s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 506 +select 1 +from t t1 + left join (select 2 as c + from t t2 left join t t3 on t2.a = t3.a) s + on true +where t1.a = s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="s" column="c" +STMT: SelectStmt +== 507 +rollback +-- +STMT: TransactionStmt +== 508 +-- test cases where we can remove a join, but not a PHV computed at it +begin +-- +STMT: TransactionStmt +== 509 +create temp table t (a int unique, b int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 510 +insert into t values (1,1), (2,2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 511 +explain (costs off) +select 1 +from t t1 + left join (select t2.a, 1 as c + from t t2 left join t t3 on t2.a = t3.a) s + on true + left join t t4 on true +where s.a < s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 512 +explain (costs off) +select t1.a, s.* +from t t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from t t2 left join t t3 on t2.a = t3.a) s + on true + left join t t4 on true +where s.a < s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 513 +select t1.a, s.* +from t t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from t t2 left join t t3 on t2.a = t3.a) s + on true + left join t t4 on true +where s.a < s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="c" +STMT: SelectStmt +== 514 +rollback +-- +STMT: TransactionStmt +== 515 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="tenk1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 516 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="tenk1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 517 +-- 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) +-- +TABLE: name="parttbl" schema="" table="parttbl" ctx=DDL +STMT: CreateStmt +== 518 +create temp table parttbl1 partition of parttbl for values from (1) to (100) +-- +TABLE: name="parttbl1" schema="" table="parttbl1" ctx=DDL +STMT: CreateStmt +== 519 +insert into parttbl values (11), (12) +-- +TABLE: name="parttbl" schema="" table="parttbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 520 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="parttbl" schema="" table="parttbl" ctx=Select +FILTER: schema="" table="ss" column="a" +FILTER: schema="" table="ss" column="phv" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 521 +select * from + (select *, 12 as phv from parttbl) as ss + right join int4_tbl on true +where ss.a = ss.phv and f1 = 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="parttbl" schema="" table="parttbl" ctx=Select +FILTER: schema="" table="ss" column="a" +FILTER: schema="" table="ss" column="phv" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 522 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +== 523 +-- error +select * from + int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +== 524 +-- error +select * from + int8_tbl x join (int4_tbl x cross join int4_tbl y(ff)) j on q1 = f1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +== 525 +-- ok + +|-- +-- Test hints given on incorrect column references are useful +|-- + +select t1.uunique1 from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +== 526 +-- error, prefer "t1" suggestion +select t2.uunique1 from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +== 527 +-- error, prefer "t2" suggestion +select uunique1 from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +== 528 +-- error, suggest both at once +select ctid from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +== 529 +-- error, need qualification + +|-- +-- 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' +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "i"="pg_index" +ALIAS: "s"="pg_stats" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +== 530 +-- Test bug in rangetable flattening +explain (verbose, costs off) +select 1 from + (select * from int8_tbl where q1 <> (select 42) offset 0) ss +where false +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 531 +|-- +-- Test LATERAL +|-- + +select unique2, x.* +from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="a" column="unique1" +STMT: SelectStmt +== 532 +explain (costs off) + select unique2, x.* + from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="a" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 533 +select unique2, x.* +from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 534 +explain (costs off) + select unique2, x.* + from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 535 +explain (costs off) + select unique2, x.* + from int4_tbl x cross join lateral (select unique2 from tenk1 where f1 = unique1) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 536 +select unique2, x.* +from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 537 +explain (costs off) + select unique2, x.* + from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 538 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 539 +select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 540 +-- lateral with function in FROM +select count(*) from tenk1 a, lateral generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 541 +explain (costs off) + select count(*) from tenk1 a, lateral generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 542 +explain (costs off) + select count(*) from tenk1 a cross join lateral generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 543 +-- don't need the explicit LATERAL keyword for functions +explain (costs off) + select count(*) from tenk1 a, generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 544 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 545 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 546 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 547 +select count(*) from tenk1 a, + tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 548 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 549 +select count(*) from tenk1 a, + tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 550 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "x"="int8_tbl" +ALIAS: "y"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 551 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "x"="int8_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +== 552 +-- 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) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +STMT: SelectStmt +== 553 +select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, + lateral (values(x)) ss2(y) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +STMT: SelectStmt +== 554 +select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, + lateral (select x) ss2(y) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +STMT: SelectStmt +== 555 +-- lateral references requiring pullup +select * from (values(1)) x(lb), + lateral generate_series(lb,4) x4 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 556 +select * from (select f1/1000000000 from int4_tbl) x(lb), + lateral generate_series(lb,4) x4 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 557 +select * from (values(1)) x(lb), + lateral (values(lb)) y(lbcopy) +-- +STMT: SelectStmt +== 558 +select * from (values(1)) x(lb), + lateral (select lb from int4_tbl) y(lbcopy) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 559 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +STMT: SelectStmt +== 560 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +STMT: SelectStmt +== 561 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +STMT: SelectStmt +== 562 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +ALIAS: "z"="int4_tbl" +STMT: SelectStmt +== 563 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +ALIAS: "z"="int4_tbl" +STMT: SelectStmt +== 564 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +ALIAS: "x"="int8_tbl" +ALIAS: "z"="int4_tbl" +STMT: SelectStmt +== 565 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 566 +select * from + int8_tbl a left join + lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: SelectStmt +== 567 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 568 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: SelectStmt +== 569 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 570 +select * from int4_tbl i left join + lateral (select * from int2_tbl j where i.f1 = j.f1) k on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: SelectStmt +== 571 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 572 +select * from int4_tbl i left join + lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: SelectStmt +== 573 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +ALIAS: "c"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 574 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +ALIAS: "c"="int8_tbl" +STMT: SelectStmt +== 575 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 576 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="int8_tbl" +STMT: SelectStmt +== 577 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="int8_tbl" +ALIAS: "d"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 578 +-- another case requiring nested PlaceHolderVars +explain (verbose, costs off) +select * from + (select 0 as val0) as ss0 + left join (select 1 as val) as ss1 on true + left join lateral (select ss1.val as val_filtered where false) as ss2 on true +-- +STMT: ExplainStmt +STMT: SelectStmt +== 579 +select * from + (select 0 as val0) as ss0 + left join (select 1 as val) as ss1 on true + left join lateral (select ss1.val as val_filtered where false) as ss2 on true +-- +STMT: SelectStmt +== 580 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "b2"="int4_tbl" +ALIAS: "c"="int8_tbl" +ALIAS: "d"="int8_tbl" +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="ss2" column="y" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 581 +-- 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 +-- +FILTER: schema="" table="z" column="z" +FILTER: schema="" table="x" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 582 +-- a new postponed-quals issue (bug #17768) +explain (costs off) +select * from int4_tbl t1, + lateral (select * from int4_tbl t2 inner join int4_tbl t3 on t1.f1 = 1 + inner join (int4_tbl t4 left join int4_tbl t5 on true) on true) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 583 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 584 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 585 +-- 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 +-- +STMT: SelectStmt +== 586 +-- check the number of columns specified +SELECT * FROM (int8_tbl i cross join int4_tbl j) ss(a,b,c,d) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +ALIAS: "j"="int4_tbl" +STMT: SelectStmt +== 587 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="v" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 588 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="v" column="x" +STMT: SelectStmt +== 589 +-- 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, random() > 0) = any (select q2, random() > 0 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="t1" column="q1" +FILTER: schema="" table="ss" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 590 +select * from (values (0), (1)) v(id), +lateral (select * from int8_tbl t1, + lateral (select * from + (select * from int8_tbl t2 + where (q1, random() > 0) = any (select q2, random() > 0 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="t1" column="q1" +FILTER: schema="" table="ss" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 591 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +== 592 +select f1,g from int4_tbl a, (select a.f1 as g) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +== 593 +select f1,g from int4_tbl a cross join (select f1 as g) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +== 594 +select f1,g from int4_tbl a cross join (select a.f1 as g) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +== 595 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 596 +select f1,g from int4_tbl a full join lateral generate_series(0, a.f1) g on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 597 +-- check we complain about ambiguous table references +select * from + int8_tbl x cross join (int4_tbl x cross join lateral (select x.f1) ss) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +STMT: SelectStmt +== 598 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="int4_tbl" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 599 +-- check behavior of LATERAL in UPDATE/DELETE + +create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DDL +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 600 +-- error, can't do this: +update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +== 601 +update xx1 set x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="xx1" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +== 602 +-- can't do it even with LATERAL: +update xx1 set x2 = f1 from lateral (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +== 603 +-- 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 +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="xx1" schema="" table="xx1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +== 604 +-- also errors: +delete from xx1 using (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: DeleteStmt +STMT: SelectStmt +== 605 +delete from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="xx1" column="x1" +STMT: DeleteStmt +STMT: SelectStmt +== 606 +delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: DeleteStmt +STMT: SelectStmt +== 607 +|-- +-- 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) +-- +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=DDL +STMT: CreateStmt +== 608 +create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b) +-- +TABLE: name="join_pt1p1" schema="" table="join_pt1p1" ctx=DDL +STMT: CreateStmt +== 609 +create table join_pt1p2 partition of join_pt1 for values from (100) to (200) +-- +TABLE: name="join_pt1p2" schema="" table="join_pt1p2" ctx=DDL +STMT: CreateStmt +== 610 +create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100) +-- +TABLE: name="join_pt1p1p1" schema="" table="join_pt1p1p1" ctx=DDL +STMT: CreateStmt +== 611 +insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y') +-- +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 612 +create table join_ut1 (a int, b int, c varchar) +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=DDL +STMT: CreateStmt +== 613 +insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z') +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 614 +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 +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=Select +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +ALIAS: "t1"="join_ut1" +ALIAS: "t2"="join_pt1" +ALIAS: "t3"="join_ut1" +STMT: ExplainStmt +STMT: SelectStmt +== 615 +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 +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=Select +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +ALIAS: "t1"="join_ut1" +ALIAS: "t2"="join_pt1" +ALIAS: "t3"="join_ut1" +STMT: SelectStmt +== 616 +drop table join_pt1 +-- +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=DDL +STMT: DropStmt +== 617 +drop table join_ut1 +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=DDL +STMT: DropStmt +== 618 +|-- +-- test estimation behavior with multi-column foreign key and constant qual +|-- + +begin +-- +STMT: TransactionStmt +== 619 +create table fkest (x integer, x10 integer, x10b integer, x100 integer) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: CreateStmt +== 620 +insert into fkest select x, x/10, x/10, x/100 from generate_series(1,1000) x +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 621 +create unique index on fkest(x, x10, x100) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: IndexStmt +== 622 +analyze fkest +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: VacuumStmt +== 623 +explain (costs off) +select * from fkest f1 + join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) + join fkest f3 on f1.x = f3.x + where f1.x100 = 2 +-- +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +ALIAS: "f1"="fkest" +ALIAS: "f2"="fkest" +ALIAS: "f3"="fkest" +FILTER: schema="" table="f1" column="x100" +STMT: ExplainStmt +STMT: SelectStmt +== 624 +alter table fkest add constraint fk + foreign key (x, x10b, x100) references fkest (x, x10, x100) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: AlterTableStmt +== 625 +explain (costs off) +select * from fkest f1 + join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) + join fkest f3 on f1.x = f3.x + where f1.x100 = 2 +-- +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +ALIAS: "f1"="fkest" +ALIAS: "f2"="fkest" +ALIAS: "f3"="fkest" +FILTER: schema="" table="f1" column="x100" +STMT: ExplainStmt +STMT: SelectStmt +== 626 +rollback +-- +STMT: TransactionStmt +== 627 +|-- +-- test that foreign key join estimation performs sanely for outer joins +|-- + +begin +-- +STMT: TransactionStmt +== 628 +create table fkest (a int, b int, c int unique, primary key(a,b)) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: CreateStmt +== 629 +create table fkest1 (a int, b int, primary key(a,b)) +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DDL +STMT: CreateStmt +== 630 +insert into fkest select x/10, x%10, x from generate_series(1,1000) x +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 631 +insert into fkest1 select x/10, x%10 from generate_series(1,1000) x +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 632 +alter table fkest1 + add constraint fkest1_a_b_fkey foreign key (a,b) references fkest +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DDL +STMT: AlterTableStmt +== 633 +analyze fkest +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: VacuumStmt +== 634 +analyze fkest1 +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DDL +STMT: VacuumStmt +== 635 +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 +-- +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest1" schema="" table="fkest1" ctx=Select +TABLE: name="fkest1" schema="" table="fkest1" ctx=Select +TABLE: name="fkest1" schema="" table="fkest1" ctx=Select +ALIAS: "f"="fkest" +ALIAS: "f1"="fkest1" +ALIAS: "f2"="fkest1" +ALIAS: "f3"="fkest1" +FILTER: schema="" table="f" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 636 +rollback +-- +STMT: TransactionStmt +== 637 +|-- +-- test planner's ability to mark joins as unique +|-- + +create table j1 (id int primary key) +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: CreateStmt +== 638 +create table j2 (id int primary key) +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: CreateStmt +== 639 +create table j3 (id int) +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: CreateStmt +== 640 +insert into j1 values(1),(2),(3) +-- +TABLE: name="j1" schema="" table="j1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 641 +insert into j2 values(1),(2),(3) +-- +TABLE: name="j2" schema="" table="j2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 642 +insert into j3 values(1),(1) +-- +TABLE: name="j3" schema="" table="j3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 643 +analyze j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: VacuumStmt +== 644 +analyze j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: VacuumStmt +== 645 +analyze j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: VacuumStmt +== 646 +-- ensure join is properly marked as unique +explain (verbose, costs off) +select * from j1 inner join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 647 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 648 +-- ensure non-unique rel is not chosen as inner +explain (verbose, costs off) +select * from j1 inner join j3 on j1.id = j3.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 649 +-- ensure left join is marked as unique +explain (verbose, costs off) +select * from j1 left join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 650 +-- ensure right join is marked as unique +explain (verbose, costs off) +select * from j1 right join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 651 +-- ensure full join is marked as unique +explain (verbose, costs off) +select * from j1 full join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 652 +-- a clauseless (cross) join can't be unique +explain (verbose, costs off) +select * from j1 cross join j2 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 653 +-- ensure a natural join is marked as unique +explain (verbose, costs off) +select * from j1 natural join j2 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 654 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 655 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 656 +drop table j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: DropStmt +== 657 +drop table j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: DropStmt +== 658 +drop table j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: DropStmt +== 659 +-- test more complex permutations of unique joins + +create table j1 (id1 int, id2 int, primary key(id1,id2)) +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: CreateStmt +== 660 +create table j2 (id1 int, id2 int, primary key(id1,id2)) +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: CreateStmt +== 661 +create table j3 (id1 int, id2 int, primary key(id1,id2)) +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: CreateStmt +== 662 +insert into j1 values(1,1),(1,2) +-- +TABLE: name="j1" schema="" table="j1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 663 +insert into j2 values(1,1) +-- +TABLE: name="j2" schema="" table="j2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 664 +insert into j3 values(1,1) +-- +TABLE: name="j3" schema="" table="j3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 665 +analyze j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: VacuumStmt +== 666 +analyze j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: VacuumStmt +== 667 +analyze j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: VacuumStmt +== 668 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 669 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 670 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id2" +STMT: ExplainStmt +STMT: SelectStmt +== 671 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id2" +STMT: ExplainStmt +STMT: SelectStmt +== 672 +create unique index j1_id2_idx on j1(id2) where id2 is not null +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: IndexStmt +== 673 +-- ensure we don't use a partial unique index as unique proofs +explain (verbose, costs off) +select * from j1 +inner join j2 on j1.id2 = j2.id2 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 674 +drop index j1_id2_idx +-- +STMT: DropStmt +== 675 +-- 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 +-- +STMT: VariableSetStmt +== 676 +set enable_hashjoin to 0 +-- +STMT: VariableSetStmt +== 677 +set enable_sort to 0 +-- +STMT: VariableSetStmt +== 678 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: IndexStmt +== 679 +create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: IndexStmt +== 680 +-- need an additional row in j2, if we want j2_id1_idx to be preferred +insert into j2 values(1,2) +-- +TABLE: name="j2" schema="" table="j2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 681 +analyze j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: VacuumStmt +== 682 +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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: ExplainStmt +STMT: SelectStmt +== 683 +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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: SelectStmt +== 684 +-- 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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: ExplainStmt +STMT: SelectStmt +== 685 +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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: SelectStmt +== 686 +-- 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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: ExplainStmt +STMT: SelectStmt +== 687 +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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: SelectStmt +== 688 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 689 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 690 +reset enable_sort +-- +STMT: VariableSetStmt +== 691 +drop table j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: DropStmt +== 692 +drop table j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: DropStmt +== 693 +drop table j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: DropStmt +== 694 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FILTER: schema="" table="t3" column="thousand" +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t3" column="tenthous" +FILTER: schema="" table="t2" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 695 +-- ... unless it actually is unique +create table j3 as select unique1, tenthous from onek +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 696 +vacuum analyze j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: VacuumStmt +== 697 +create unique index on j3(unique1, tenthous) +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: IndexStmt +== 698 +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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="j3" column="unique1" +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="j3" column="tenthous" +FILTER: schema="" table="t2" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 699 +drop table j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: DropStmt +== 700 +-- Exercise the "skip fetch" Bitmap Heap Scan optimization when candidate +-- tuples are discarded. This may occur when: +-- 1. A join doesn't require all inner tuples to be scanned for each outer +-- tuple, and +-- 2. The inner side is scanned using a bitmap heap scan, and +-- 3. The bitmap heap scan is eligible for the "skip fetch" optimization. +-- This optimization is usable when no data from the underlying table is +-- needed. Use a temp table so it is only visible to this backend and +-- vacuum may reliably mark all blocks in the table all visible in the +-- visibility map. +CREATE TEMP TABLE skip_fetch (a INT, b INT) WITH (fillfactor=10) +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DDL +STMT: CreateStmt +== 701 +INSERT INTO skip_fetch SELECT i % 3, i FROM generate_series(0,30) i +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 702 +CREATE INDEX ON skip_fetch(a) +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DDL +STMT: IndexStmt +== 703 +VACUUM (ANALYZE) skip_fetch +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DDL +STMT: VacuumStmt +== 704 +SET enable_indexonlyscan = off +-- +STMT: VariableSetStmt +== 705 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 706 +EXPLAIN (COSTS OFF) +SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS NULL +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +ALIAS: "t1"="skip_fetch" +ALIAS: "t2"="skip_fetch" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 707 +SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS NULL +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +ALIAS: "t1"="skip_fetch" +ALIAS: "t2"="skip_fetch" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +== 708 +RESET enable_indexonlyscan +-- +STMT: VariableSetStmt +== 709 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 710 +-- Test that we do not account for nullingrels when looking up statistics +CREATE TABLE group_tbl (a INT, b INT) +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DDL +STMT: CreateStmt +== 711 +INSERT INTO group_tbl SELECT 1, 1 +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 712 +CREATE STATISTICS group_tbl_stat (ndistinct) ON a, b FROM group_tbl +-- +STMT: CreateStatsStmt +== 713 +ANALYZE group_tbl +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DDL +STMT: VacuumStmt +== 714 +EXPLAIN (COSTS OFF) +SELECT 1 FROM group_tbl t1 + LEFT JOIN (SELECT a c1, COALESCE(a) c2 FROM group_tbl t2) s ON TRUE +GROUP BY s.c1, s.c2 +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=Select +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=Select +ALIAS: "t1"="group_tbl" +ALIAS: "t2"="group_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 715 +DROP TABLE group_tbl +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/join_hash.metadata.json b/parser/testdata/summary/postgres_regress/join_hash.metadata.json new file mode 100644 index 0000000..5bababc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/join_hash.metadata.json @@ -0,0 +1,283 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279" + ] +} diff --git a/parser/testdata/summary/postgres_regress/join_hash.test b/parser/testdata/summary/postgres_regress/join_hash.test new file mode 100644 index 0000000..6bab601 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/join_hash.test @@ -0,0 +1,1812 @@ +== 001 +|-- +-- exercises for the hash join code +|-- + +begin +-- +STMT: TransactionStmt +== 002 +set local min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 003 +set local parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 004 +set local enable_hashjoin = on +-- +STMT: VariableSetStmt +== 005 +-- Extract bucket and batch counts from an explain analyze plan. In +-- general we can't make assertions about how many batches (or +-- buckets) will be required because it can vary, but we can in some +-- special cases and we can check for growth. +create or replace function find_hash(node json) +returns json language plpgsql +as +$$ +declare + x json; + child json; +begin + if node->>'Node Type' = 'Hash' then + return node; + else + for child in select json_array_elements(node->'Plans') + loop + x := find_hash(child); + if x is not null then + return x; + end if; + end loop; + return null; + end if; +end; +$$ +-- +FUNCTION: name="find_hash" function="find_hash" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +create or replace function hash_join_batches(query text) +returns table (original int, final int) language plpgsql +as +$$ +declare + whole_plan json; + hash_node json; +begin + for whole_plan in + execute 'explain (analyze, format ''json'') ' || query + loop + hash_node := find_hash(json_extract_path(whole_plan, '0', 'Plan')); + original := hash_node->>'Original Hash Batches'; + final := hash_node->>'Hash Batches'; + return next; + end loop; +end; +$$ +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +-- Make a simple relation with well distributed keys and correctly +-- estimated size. +create table simple as + select generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +-- +TABLE: name="simple" schema="" table="simple" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 008 +alter table simple set (parallel_workers = 2) +-- +TABLE: name="simple" schema="" table="simple" ctx=DDL +STMT: AlterTableStmt +== 009 +analyze simple +-- +TABLE: name="simple" schema="" table="simple" ctx=DDL +STMT: VacuumStmt +== 010 +-- Make a relation whose size we will under-estimate. We want stats +-- to say 1000 rows, but actually there are 20,000 rows. +create table bigger_than_it_looks as + select generate_series(1, 20000) as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 011 +alter table bigger_than_it_looks set (autovacuum_enabled = 'false') +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +STMT: AlterTableStmt +== 012 +alter table bigger_than_it_looks set (parallel_workers = 2) +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +STMT: AlterTableStmt +== 013 +analyze bigger_than_it_looks +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +STMT: VacuumStmt +== 014 +update pg_class set reltuples = 1000 where relname = 'bigger_than_it_looks' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +STMT: UpdateStmt +== 015 +-- Make a relation whose size we underestimate and that also has a +-- kind of skew that breaks our batching scheme. We want stats to say +-- 2 rows, but actually there are 20,000 rows with the same key. +create table extremely_skewed (id int, t text) +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: CreateStmt +== 016 +alter table extremely_skewed set (autovacuum_enabled = 'false') +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: AlterTableStmt +== 017 +alter table extremely_skewed set (parallel_workers = 2) +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: AlterTableStmt +== 018 +analyze extremely_skewed +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: VacuumStmt +== 019 +insert into extremely_skewed + select 42 as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + from generate_series(1, 20000) +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 020 +update pg_class + set reltuples = 2, relpages = pg_relation_size('extremely_skewed') / 8192 + where relname = 'extremely_skewed' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: UpdateStmt +== 021 +-- Make a relation with a couple of enormous tuples. +create table wide as select generate_series(1, 2) as id, rpad('', 320000, 'x') as t +-- +TABLE: name="wide" schema="" table="wide" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="rpad" function="rpad" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 022 +alter table wide set (parallel_workers = 2) +-- +TABLE: name="wide" schema="" table="wide" ctx=DDL +STMT: AlterTableStmt +== 023 +-- The "optimal" case: the hash table fits in memory; we plan for 1 +-- batch, we stick to that number, and peak memory usage stays within +-- our work_mem budget + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +== 024 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 025 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +== 026 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 027 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 028 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 029 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 030 +rollback to settings +-- +STMT: TransactionStmt +== 031 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +== 032 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 033 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +== 034 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 035 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 036 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 037 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 038 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 039 +rollback to settings +-- +STMT: TransactionStmt +== 040 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +== 041 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 042 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +== 043 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 044 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 045 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 046 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 047 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 048 +rollback to settings +-- +STMT: TransactionStmt +== 049 +-- The "good" case: batches required, but we plan the right number; we +-- plan for some number of batches, and we stick to that number, and +-- peak memory usage says within our work_mem budget + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +== 050 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 051 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +== 052 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 053 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 054 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 055 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 056 +rollback to settings +-- +STMT: TransactionStmt +== 057 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +== 058 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 059 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +== 060 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 061 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 062 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 063 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 064 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 065 +rollback to settings +-- +STMT: TransactionStmt +== 066 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +== 067 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 068 +set local work_mem = '192kB' +-- +STMT: VariableSetStmt +== 069 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 070 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 071 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 072 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 073 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 074 +-- parallel full multi-batch hash join +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 075 +rollback to settings +-- +STMT: TransactionStmt +== 076 +-- The "bad" case: during execution we need to increase number of +-- batches; in this case we plan for 1 batch, and increase at least a +-- couple of times, and peak memory usage stays within our work_mem +-- budget + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +== 077 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 078 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +== 079 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 080 +explain (costs off) + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 081 +select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 082 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 083 +rollback to settings +-- +STMT: TransactionStmt +== 084 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +== 085 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 086 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +== 087 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 088 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 089 +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 090 +select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 091 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 092 +rollback to settings +-- +STMT: TransactionStmt +== 093 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +== 094 +set local max_parallel_workers_per_gather = 1 +-- +STMT: VariableSetStmt +== 095 +set local work_mem = '192kB' +-- +STMT: VariableSetStmt +== 096 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 097 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 098 +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 099 +select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 101 +rollback to settings +-- +STMT: TransactionStmt +== 102 +-- The "ugly" case: increasing the number of batches during execution +-- doesn't help, so stop trying to fit in work_mem and hope for the +-- best; in this case we plan for 1 batch, increases just once and +-- then stop increasing because that didn't help at all, so we blow +-- right through the work_mem budget and hope for the best... + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +== 103 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 104 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +== 105 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 106 +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 107 +select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 108 +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 109 +rollback to settings +-- +STMT: TransactionStmt +== 110 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +== 111 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 112 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +== 113 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 114 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 115 +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 116 +select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 117 +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 118 +rollback to settings +-- +STMT: TransactionStmt +== 119 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +== 120 +set local max_parallel_workers_per_gather = 1 +-- +STMT: VariableSetStmt +== 121 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +== 122 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 123 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 124 +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 125 +select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 126 +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 127 +rollback to settings +-- +STMT: TransactionStmt +== 128 +-- A couple of other hash join tests unrelated to work_mem management. + +-- Check that EXPLAIN ANALYZE has data even if the leader doesn't participate +savepoint settings +-- +STMT: TransactionStmt +== 129 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 130 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +== 131 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 132 +set local parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 133 +select * from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 134 +rollback to settings +-- +STMT: TransactionStmt +== 135 +-- Exercise rescans. We'll turn off parallel_leader_participation so +-- that we can check that instrumentation comes back correctly. + +create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 136 +alter table join_foo set (parallel_workers = 0) +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=DDL +STMT: AlterTableStmt +== 137 +create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t +-- +TABLE: name="join_bar" schema="" table="join_bar" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 138 +alter table join_bar set (parallel_workers = 2) +-- +TABLE: name="join_bar" schema="" table="join_bar" ctx=DDL +STMT: AlterTableStmt +== 139 +-- multi-batch with rescan, parallel-oblivious +savepoint settings +-- +STMT: TransactionStmt +== 140 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 141 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 142 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 143 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 144 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 145 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 146 +set enable_material = off +-- +STMT: VariableSetStmt +== 147 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 148 +set work_mem = '64kB' +-- +STMT: VariableSetStmt +== 149 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 150 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 151 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 152 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 153 +rollback to settings +-- +STMT: TransactionStmt +== 154 +-- single-batch with rescan, parallel-oblivious +savepoint settings +-- +STMT: TransactionStmt +== 155 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 156 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 157 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 158 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 159 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 160 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 161 +set enable_material = off +-- +STMT: VariableSetStmt +== 162 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 163 +set work_mem = '4MB' +-- +STMT: VariableSetStmt +== 164 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 165 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 166 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 167 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 168 +rollback to settings +-- +STMT: TransactionStmt +== 169 +-- multi-batch with rescan, parallel-aware +savepoint settings +-- +STMT: TransactionStmt +== 170 +set enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 171 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 172 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 173 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 174 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 175 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 176 +set enable_material = off +-- +STMT: VariableSetStmt +== 177 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 178 +set work_mem = '64kB' +-- +STMT: VariableSetStmt +== 179 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 180 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 181 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 182 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 183 +rollback to settings +-- +STMT: TransactionStmt +== 184 +-- single-batch with rescan, parallel-aware +savepoint settings +-- +STMT: TransactionStmt +== 185 +set enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 186 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 187 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 188 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 189 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 190 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 191 +set enable_material = off +-- +STMT: VariableSetStmt +== 192 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 193 +set work_mem = '4MB' +-- +STMT: VariableSetStmt +== 194 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 195 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 196 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 197 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 198 +rollback to settings +-- +STMT: TransactionStmt +== 199 +-- A full outer join where every record is matched. + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +== 200 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 201 +explain (costs off) + select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 202 +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 203 +rollback to settings +-- +STMT: TransactionStmt +== 204 +-- parallelism not possible with parallel-oblivious full hash join +savepoint settings +-- +STMT: TransactionStmt +== 205 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 206 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 207 +explain (costs off) + select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 208 +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 209 +rollback to settings +-- +STMT: TransactionStmt +== 210 +-- parallelism is possible with parallel-aware full hash join +savepoint settings +-- +STMT: TransactionStmt +== 211 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 212 +explain (costs off) + select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 213 +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 214 +rollback to settings +-- +STMT: TransactionStmt +== 215 +-- A full outer join where every record is not matched. + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +== 216 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 217 +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 218 +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 219 +rollback to settings +-- +STMT: TransactionStmt +== 220 +-- parallelism not possible with parallel-oblivious full hash join +savepoint settings +-- +STMT: TransactionStmt +== 221 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 222 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 223 +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 224 +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 225 +rollback to settings +-- +STMT: TransactionStmt +== 226 +-- parallelism is possible with parallel-aware full hash join +savepoint settings +-- +STMT: TransactionStmt +== 227 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 228 +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 229 +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 230 +rollback to settings +-- +STMT: TransactionStmt +== 231 +-- 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 +-- +STMT: TransactionStmt +== 232 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 233 +set enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 234 +set work_mem = '128kB' +-- +STMT: VariableSetStmt +== 235 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +== 236 +explain (costs off) + select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id) +-- +TABLE: name="wide" schema="" table="wide" ctx=Select +TABLE: name="wide" schema="" table="wide" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 237 +select length(max(s.t)) +from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id) +-- +TABLE: name="wide" schema="" table="wide" ctx=Select +TABLE: name="wide" schema="" table="wide" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 238 +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); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +== 239 +rollback to settings +-- +STMT: TransactionStmt +== 240 +-- Hash join reuses the HOT status bit to indicate match status. This can only +-- be guaranteed to produce correct results if all the hash join tuple match +-- bits are reset before reuse. This is done upon loading them into the +-- hashtable. +SAVEPOINT settings +-- +STMT: TransactionStmt +== 241 +SET enable_parallel_hash = on +-- +STMT: VariableSetStmt +== 242 +SET min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 243 +SET parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 244 +SET parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 245 +CREATE TABLE hjtest_matchbits_t1(id int) +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=DDL +STMT: CreateStmt +== 246 +CREATE TABLE hjtest_matchbits_t2(id int) +-- +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=DDL +STMT: CreateStmt +== 247 +INSERT INTO hjtest_matchbits_t1 VALUES (1) +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +INSERT INTO hjtest_matchbits_t2 VALUES (2) +-- +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 249 +-- Update should create a HOT tuple. If this status bit isn't cleared, we won't +-- correctly emit the NULL-extended unmatching tuple in full hash join. +UPDATE hjtest_matchbits_t2 set id = 2 +-- +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=DML +STMT: UpdateStmt +== 250 +SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id + ORDER BY t1.id +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=Select +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=Select +ALIAS: "t1"="hjtest_matchbits_t1" +ALIAS: "t2"="hjtest_matchbits_t2" +STMT: SelectStmt +== 251 +-- Test serial full hash join. +-- Resetting parallel_setup_cost should force a serial plan. +-- Just to be safe, however, set enable_parallel_hash to off, as parallel full +-- hash joins are only supported with shared hashtables. +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +== 252 +SET enable_parallel_hash = off +-- +STMT: VariableSetStmt +== 253 +SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=Select +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=Select +ALIAS: "t1"="hjtest_matchbits_t1" +ALIAS: "t2"="hjtest_matchbits_t2" +STMT: SelectStmt +== 254 +ROLLBACK TO settings +-- +STMT: TransactionStmt +== 255 +rollback +-- +STMT: TransactionStmt +== 256 +-- 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 +-- +STMT: TransactionStmt +== 257 +SET LOCAL enable_sort = OFF +-- +STMT: VariableSetStmt +== 258 +-- avoid mergejoins +SET LOCAL from_collapse_limit = 1 +-- +STMT: VariableSetStmt +== 259 +-- allows easy changing of join order + +CREATE TABLE hjtest_1 (a text, b int, id int, c bool) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DDL +STMT: CreateStmt +== 260 +CREATE TABLE hjtest_2 (a bool, id int, b text, c int) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DDL +STMT: CreateStmt +== 261 +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 2, 1, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 262 +-- matches +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 2, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 263 +-- fails id join condition +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 20, 1, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 264 +-- fails < 50 +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 1, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 265 +-- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 2) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 266 +-- matches +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 3, 'another', 7) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 267 +-- fails id join condition +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 90) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +-- fails < 55 +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 3) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +-- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'text', 1) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 270 +-- 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 +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: ExplainStmt +STMT: SelectStmt +== 271 +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 +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: SelectStmt +== 272 +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 +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: ExplainStmt +STMT: SelectStmt +== 273 +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 +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: SelectStmt +== 274 +ROLLBACK +-- +STMT: TransactionStmt +== 275 +-- Verify that we behave sanely when the inner hash keys contain parameters +-- (that is, outer or lateral references). This situation has to defeat +-- re-use of the inner hash table across rescans. +begin +-- +STMT: TransactionStmt +== 276 +set local enable_hashjoin = on +-- +STMT: VariableSetStmt +== 277 +explain (costs off) +select i8.q2, ss.* from +int8_tbl i8, +lateral (select t1.fivethous, i4.f1 from tenk1 t1 join int4_tbl i4 + on t1.fivethous = i4.f1+i8.q2 order by 1,2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +== 278 +select i8.q2, ss.* from +int8_tbl i8, +lateral (select t1.fivethous, i4.f1 from tenk1 t1 join int4_tbl i4 + on t1.fivethous = i4.f1+i8.q2 order by 1,2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="tenk1" +STMT: SelectStmt +== 279 +rollback +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/json.metadata.json b/parser/testdata/summary/postgres_regress/json.metadata.json new file mode 100644 index 0000000..15b4f09 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/json.metadata.json @@ -0,0 +1,464 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460" + ] +} diff --git a/parser/testdata/summary/postgres_regress/json.test b/parser/testdata/summary/postgres_regress/json.test new file mode 100644 index 0000000..7951a7c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/json.test @@ -0,0 +1,2566 @@ +== 001 +-- Strings. +SELECT '""'::json +-- +STMT: SelectStmt +== 002 +-- OK. +SELECT $$''$$::json +-- +STMT: SelectStmt +== 003 +-- ERROR, single quotes are not allowed +SELECT '"abc"'::json +-- +STMT: SelectStmt +== 004 +-- OK +SELECT '"abc'::json +-- +STMT: SelectStmt +== 005 +-- ERROR, quotes not closed +SELECT '"abc +def"'::json +-- +STMT: SelectStmt +== 006 +-- ERROR, unescaped newline in string constant +SELECT '"\n\"\\"'::json +-- +STMT: SelectStmt +== 007 +-- OK, legal escapes +SELECT '"\v"'::json +-- +STMT: SelectStmt +== 008 +-- ERROR, not a valid JSON escape + +-- Check fast path for longer strings (at least 16 bytes long) +SELECT ('"'||repeat('.', 12)||'abc"')::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- OK +SELECT ('"'||repeat('.', 12)||'abc\n"')::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 010 +-- OK, legal escapes + +-- see json_encoding test for input with unicode escapes + +-- Numbers. +SELECT '1'::json +-- +STMT: SelectStmt +== 011 +-- OK +SELECT '0'::json +-- +STMT: SelectStmt +== 012 +-- OK +SELECT '01'::json +-- +STMT: SelectStmt +== 013 +-- ERROR, not valid according to JSON spec +SELECT '0.1'::json +-- +STMT: SelectStmt +== 014 +-- OK +SELECT '9223372036854775808'::json +-- +STMT: SelectStmt +== 015 +-- OK, even though it's too large for int8 +SELECT '1e100'::json +-- +STMT: SelectStmt +== 016 +-- OK +SELECT '1.3e100'::json +-- +STMT: SelectStmt +== 017 +-- OK +SELECT '1f2'::json +-- +STMT: SelectStmt +== 018 +-- ERROR +SELECT '0.x1'::json +-- +STMT: SelectStmt +== 019 +-- ERROR +SELECT '1.3ex100'::json +-- +STMT: SelectStmt +== 020 +-- ERROR + +-- Arrays. +SELECT '[]'::json +-- +STMT: SelectStmt +== 021 +-- OK +SELECT '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'::json +-- +STMT: SelectStmt +== 022 +-- OK +SELECT '[1,2]'::json +-- +STMT: SelectStmt +== 023 +-- OK +SELECT '[1,2,]'::json +-- +STMT: SelectStmt +== 024 +-- ERROR, trailing comma +SELECT '[1,2'::json +-- +STMT: SelectStmt +== 025 +-- ERROR, no closing bracket +SELECT '[1,[2]'::json +-- +STMT: SelectStmt +== 026 +-- ERROR, no closing bracket + +-- Objects. +SELECT '{}'::json +-- +STMT: SelectStmt +== 027 +-- OK +SELECT '{"abc"}'::json +-- +STMT: SelectStmt +== 028 +-- ERROR, no value +SELECT '{"abc":1}'::json +-- +STMT: SelectStmt +== 029 +-- OK +SELECT '{1:"abc"}'::json +-- +STMT: SelectStmt +== 030 +-- ERROR, keys must be strings +SELECT '{"abc",1}'::json +-- +STMT: SelectStmt +== 031 +-- ERROR, wrong separator +SELECT '{"abc"=1}'::json +-- +STMT: SelectStmt +== 032 +-- ERROR, totally wrong separator +SELECT '{"abc"::1}'::json +-- +STMT: SelectStmt +== 033 +-- ERROR, another wrong separator +SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::json +-- +STMT: SelectStmt +== 034 +-- OK +SELECT '{"abc":1:2}'::json +-- +STMT: SelectStmt +== 035 +-- ERROR, colon in wrong spot +SELECT '{"abc":1,3}'::json +-- +STMT: SelectStmt +== 036 +-- ERROR, no value + +-- Recursion. +SET max_stack_depth = '100kB' +-- +STMT: VariableSetStmt +== 037 +SELECT repeat('[', 10000)::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT repeat('{"a":', 10000)::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 039 +RESET max_stack_depth +-- +STMT: VariableSetStmt +== 040 +-- Miscellaneous stuff. +SELECT 'true'::json +-- +STMT: SelectStmt +== 041 +-- OK +SELECT 'false'::json +-- +STMT: SelectStmt +== 042 +-- OK +SELECT 'null'::json +-- +STMT: SelectStmt +== 043 +-- OK +SELECT ' true '::json +-- +STMT: SelectStmt +== 044 +-- OK, even with extra whitespace +SELECT 'true false'::json +-- +STMT: SelectStmt +== 045 +-- ERROR, too many values +SELECT 'true, false'::json +-- +STMT: SelectStmt +== 046 +-- ERROR, too many values +SELECT 'truf'::json +-- +STMT: SelectStmt +== 047 +-- ERROR, not a keyword +SELECT 'trues'::json +-- +STMT: SelectStmt +== 048 +-- ERROR, not a keyword +SELECT ''::json +-- +STMT: SelectStmt +== 049 +-- ERROR, no value +SELECT ' '::json +-- +STMT: SelectStmt +== 050 +-- ERROR, no value + +-- Multi-line JSON input to check ERROR reporting +SELECT '{ + "one": 1, + "two":"two", + "three": + true}'::json +-- +STMT: SelectStmt +== 051 +-- OK +SELECT '{ + "one": 1, + "two":,"two", -- ERROR extraneous comma before field "two" + "three": + true}'::json +-- +STMT: SelectStmt +== 052 +SELECT '{ + "one": 1, + "two":"two", + "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::json +-- +STMT: SelectStmt +== 053 +-- ERROR missing value for last field + +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'json') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 054 +select pg_input_is_valid('{"a":true', 'json') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 055 +select * from pg_input_error_info('{"a":true', 'json') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 056 +--constructors +-- array_to_json + +SELECT array_to_json(array(select 1 as a)) +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +STMT: SelectStmt +== 057 +SELECT array_to_json(array_agg(q),false) from (select x as b, x * 2 as c from generate_series(1,3) x) q +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 058 +SELECT array_to_json(array_agg(q),true) from (select x as b, x * 2 as c from generate_series(1,3) x) q +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT array_to_json(array_agg(q),false) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT array_to_json(array_agg(x),false) from generate_series(5,10) x +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT array_to_json('{{1,5},{99,100}}'::int[]) +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +STMT: SelectStmt +== 062 +-- row_to_json +SELECT row_to_json(row(1,'foo')) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT row_to_json(q) +FROM (SELECT $$a$$ || x AS b, + y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT row_to_json(q,true) +FROM (SELECT $$a$$ || x AS b, + y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 065 +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 066 +SELECT row_to_json(q,true) +FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),false) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 068 +-- anyarray column + +analyze rows +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +STMT: VacuumStmt +== 069 +select attname, to_json(histogram_bounds) histogram_bounds +from pg_stats +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1 +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FILTER: schema="" table="" column="tablename" +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +== 070 +-- to_json, timestamps + +select to_json(timestamp '2014-05-28 12:22:35.614298') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 071 +BEGIN +-- +STMT: TransactionStmt +== 072 +SET LOCAL TIME ZONE 10.5 +-- +STMT: VariableSetStmt +== 073 +select to_json(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 074 +SET LOCAL TIME ZONE -8 +-- +STMT: VariableSetStmt +== 075 +select to_json(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 076 +COMMIT +-- +STMT: TransactionStmt +== 077 +select to_json(date '2014-05-28') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 078 +select to_json(date 'Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 079 +select to_json(date '-Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 080 +select to_json(timestamp 'Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 081 +select to_json(timestamp '-Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 082 +select to_json(timestamptz 'Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 083 +select to_json(timestamptz '-Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 084 +--json_agg + +SELECT json_agg(q) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="json_agg" function="json_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT json_agg(q ORDER BY x, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="json_agg" function="json_agg" schema="" ctx=Call +STMT: SelectStmt +== 086 +UPDATE rows SET x = NULL WHERE x = 1 +-- +TABLE: name="rows" schema="" table="rows" ctx=DML +STMT: UpdateStmt +== 087 +SELECT json_agg(q ORDER BY x NULLS FIRST, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="json_agg" function="json_agg" schema="" ctx=Call +STMT: SelectStmt +== 088 +-- non-numeric output +SELECT row_to_json(q) +FROM (SELECT 'NaN'::float8 AS "float8field") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 089 +SELECT row_to_json(q) +FROM (SELECT 'Infinity'::float8 AS "float8field") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 090 +SELECT row_to_json(q) +FROM (SELECT '-Infinity'::float8 AS "float8field") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 091 +-- json input +SELECT row_to_json(q) +FROM (SELECT '{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::json AS "jsonfield") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 092 +-- json extraction functions + +CREATE TEMP TABLE test_json ( + json_type text, + test_json json +) +-- +TABLE: name="test_json" schema="" table="test_json" ctx=DDL +STMT: CreateStmt +== 093 +INSERT INTO test_json VALUES +('scalar','"a scalar"'), +('array','["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}]'), +('object','{"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}}') +-- +TABLE: name="test_json" schema="" table="test_json" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'scalar' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 095 +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 096 +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 097 +SELECT test_json->'field2' +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 098 +SELECT test_json->>'field2' +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 099 +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'scalar' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 100 +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 101 +SELECT test_json -> -1 +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 102 +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 103 +SELECT test_json->>2 +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 104 +SELECT test_json ->> 6 FROM test_json WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 105 +SELECT test_json ->> 7 FROM test_json WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 106 +SELECT test_json ->> 'field4' FROM test_json WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 107 +SELECT test_json ->> 'field5' FROM test_json WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 108 +SELECT test_json ->> 'field6' FROM test_json WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 109 +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'scalar' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 110 +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 111 +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 112 +-- test extending object_keys resultset - initial resultset size is 256 + +select count(*) from + (select json_object_keys(json_object(array_agg(g))) + from (select unnest(array['f'||n,n::text])as g + from generate_series(1,300) as n) x ) y +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 113 +-- nulls + +select (test_json->'field3') is null as expect_false +from test_json +where json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 114 +select (test_json->>'field3') is null as expect_true +from test_json +where json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 115 +select (test_json->3) is null as expect_false +from test_json +where json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 116 +select (test_json->>3) is null as expect_true +from test_json +where json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 117 +-- corner cases + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::text +-- +STMT: SelectStmt +== 118 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::int +-- +STMT: SelectStmt +== 119 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 1 +-- +STMT: SelectStmt +== 120 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> -1 +-- +STMT: SelectStmt +== 121 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 'z' +-- +STMT: SelectStmt +== 122 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> '' +-- +STMT: SelectStmt +== 123 +select '[{"b": "c"}, {"b": "cc"}]'::json -> 1 +-- +STMT: SelectStmt +== 124 +select '[{"b": "c"}, {"b": "cc"}]'::json -> 3 +-- +STMT: SelectStmt +== 125 +select '[{"b": "c"}, {"b": "cc"}]'::json -> 'z' +-- +STMT: SelectStmt +== 126 +select '{"a": "c", "b": null}'::json -> 'b' +-- +STMT: SelectStmt +== 127 +select '"foo"'::json -> 1 +-- +STMT: SelectStmt +== 128 +select '"foo"'::json -> 'z' +-- +STMT: SelectStmt +== 129 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::text +-- +STMT: SelectStmt +== 130 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::int +-- +STMT: SelectStmt +== 131 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 1 +-- +STMT: SelectStmt +== 132 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 'z' +-- +STMT: SelectStmt +== 133 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> '' +-- +STMT: SelectStmt +== 134 +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 1 +-- +STMT: SelectStmt +== 135 +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 3 +-- +STMT: SelectStmt +== 136 +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 'z' +-- +STMT: SelectStmt +== 137 +select '{"a": "c", "b": null}'::json ->> 'b' +-- +STMT: SelectStmt +== 138 +select '"foo"'::json ->> 1 +-- +STMT: SelectStmt +== 139 +select '"foo"'::json ->> 'z' +-- +STMT: SelectStmt +== 140 +-- array length + +SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT json_array_length('[]') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +== 142 +SELECT json_array_length('{"f1":1,"f2":[5,6]}') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +== 143 +SELECT json_array_length('4') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +== 144 +-- each + +select json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null}') +-- +FUNCTION: name="json_each" function="json_each" schema="" ctx=Call +STMT: SelectStmt +== 145 +select * from json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="json_each" function="json_each" schema="" ctx=Call +STMT: SelectStmt +== 146 +select json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}') +-- +FUNCTION: name="json_each_text" function="json_each_text" schema="" ctx=Call +STMT: SelectStmt +== 147 +select * from json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="json_each_text" function="json_each_text" schema="" ctx=Call +STMT: SelectStmt +== 148 +-- extract_path, extract_path_as_text + +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 149 +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 150 +select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 151 +select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 152 +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 153 +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 154 +select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 155 +select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 156 +-- extract_path nulls + +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_false +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 157 +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_true +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 158 +select json_extract_path('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_false +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 159 +select json_extract_path_text('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_true +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 160 +-- extract_path operators + +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f4','f6'] +-- +STMT: SelectStmt +== 161 +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2'] +-- +STMT: SelectStmt +== 162 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','0'] +-- +STMT: SelectStmt +== 163 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','1'] +-- +STMT: SelectStmt +== 164 +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f4','f6'] +-- +STMT: SelectStmt +== 165 +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2'] +-- +STMT: SelectStmt +== 166 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','0'] +-- +STMT: SelectStmt +== 167 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','1'] +-- +STMT: SelectStmt +== 168 +-- corner cases for same +select '{"a": {"b":{"c": "foo"}}}'::json #> '{}' +-- +STMT: SelectStmt +== 169 +select '[1,2,3]'::json #> '{}' +-- +STMT: SelectStmt +== 170 +select '"foo"'::json #> '{}' +-- +STMT: SelectStmt +== 171 +select '42'::json #> '{}' +-- +STMT: SelectStmt +== 172 +select 'null'::json #> '{}' +-- +STMT: SelectStmt +== 173 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a'] +-- +STMT: SelectStmt +== 174 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', null] +-- +STMT: SelectStmt +== 175 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', ''] +-- +STMT: SelectStmt +== 176 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b'] +-- +STMT: SelectStmt +== 177 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c'] +-- +STMT: SelectStmt +== 178 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c','d'] +-- +STMT: SelectStmt +== 179 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','z','c'] +-- +STMT: SelectStmt +== 180 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','1','b'] +-- +STMT: SelectStmt +== 181 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','z','b'] +-- +STMT: SelectStmt +== 182 +select '[{"b": "c"}, {"b": "cc"}]'::json #> array['1','b'] +-- +STMT: SelectStmt +== 183 +select '[{"b": "c"}, {"b": "cc"}]'::json #> array['z','b'] +-- +STMT: SelectStmt +== 184 +select '[{"b": "c"}, {"b": null}]'::json #> array['1','b'] +-- +STMT: SelectStmt +== 185 +select '"foo"'::json #> array['z'] +-- +STMT: SelectStmt +== 186 +select '42'::json #> array['f2'] +-- +STMT: SelectStmt +== 187 +select '42'::json #> array['0'] +-- +STMT: SelectStmt +== 188 +select '{"a": {"b":{"c": "foo"}}}'::json #>> '{}' +-- +STMT: SelectStmt +== 189 +select '[1,2,3]'::json #>> '{}' +-- +STMT: SelectStmt +== 190 +select '"foo"'::json #>> '{}' +-- +STMT: SelectStmt +== 191 +select '42'::json #>> '{}' +-- +STMT: SelectStmt +== 192 +select 'null'::json #>> '{}' +-- +STMT: SelectStmt +== 193 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a'] +-- +STMT: SelectStmt +== 194 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', null] +-- +STMT: SelectStmt +== 195 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', ''] +-- +STMT: SelectStmt +== 196 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b'] +-- +STMT: SelectStmt +== 197 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c'] +-- +STMT: SelectStmt +== 198 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c','d'] +-- +STMT: SelectStmt +== 199 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','z','c'] +-- +STMT: SelectStmt +== 200 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','1','b'] +-- +STMT: SelectStmt +== 201 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','z','b'] +-- +STMT: SelectStmt +== 202 +select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['1','b'] +-- +STMT: SelectStmt +== 203 +select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['z','b'] +-- +STMT: SelectStmt +== 204 +select '[{"b": "c"}, {"b": null}]'::json #>> array['1','b'] +-- +STMT: SelectStmt +== 205 +select '"foo"'::json #>> array['z'] +-- +STMT: SelectStmt +== 206 +select '42'::json #>> array['f2'] +-- +STMT: SelectStmt +== 207 +select '42'::json #>> array['0'] +-- +STMT: SelectStmt +== 208 +-- array_elements + +select json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') +-- +FUNCTION: name="json_array_elements" function="json_array_elements" schema="" ctx=Call +STMT: SelectStmt +== 209 +select * from json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q +-- +FUNCTION: name="json_array_elements" function="json_array_elements" schema="" ctx=Call +STMT: SelectStmt +== 210 +select json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') +-- +FUNCTION: name="json_array_elements_text" function="json_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +== 211 +select * from json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q +-- +FUNCTION: name="json_array_elements_text" function="json_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +== 212 +-- populate_record +create type jpop as (a text, b int, c timestamp) +-- +STMT: CompositeTypeStmt +== 213 +CREATE DOMAIN js_int_not_null AS int NOT NULL +-- +STMT: CreateDomainStmt +== 214 +CREATE DOMAIN js_int_array_1d AS int[] CHECK(array_length(VALUE, 1) = 3) +-- +STMT: CreateDomainStmt +== 215 +CREATE DOMAIN js_int_array_2d AS int[][] CHECK(array_length(VALUE, 2) = 3) +-- +STMT: CreateDomainStmt +== 216 +create type j_unordered_pair as (x int, y int) +-- +STMT: CompositeTypeStmt +== 217 +create domain j_ordered_pair as j_unordered_pair check((value).x <= (value).y) +-- +STMT: CreateDomainStmt +== 218 +CREATE TYPE jsrec AS ( + i int, + ia _int4, + ia1 int[], + ia2 int[][], + ia3 int[][][], + ia1d js_int_array_1d, + ia2d js_int_array_2d, + t text, + ta text[], + c char(10), + ca char(10)[], + ts timestamp, + js json, + jsb jsonb, + jsa json[], + rec jpop, + reca jpop[] +) +-- +STMT: CompositeTypeStmt +== 219 +CREATE TYPE jsrec_i_not_null AS ( + i js_int_not_null +) +-- +STMT: CompositeTypeStmt +== 220 +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 221 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 222 +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 223 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 224 +select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 225 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 226 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 227 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 228 +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"x": 43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 229 +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"i": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"i": 12345}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 232 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 233 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 234 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1, 2], [3, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 235 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], 2]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 236 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], [2, 3]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 237 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": "{1,2,3}"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 238 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 239 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 240 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 241 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": [[1, 2, 3]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 242 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 243 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 244 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 245 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": [1, "2", null]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 246 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 247 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 248 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[], []]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 249 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], [3]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 250 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], 3, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 251 +SELECT ia2d FROM json_populate_record(NULL::jsrec, '{"ia2d": [[1, "2"], [null, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 252 +SELECT ia2d FROM json_populate_record(NULL::jsrec, '{"ia2d": [[1, "2", 3], [null, 5, 6]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 253 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 254 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 255 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[], []], [[], []], [[], []] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 256 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2]], [[3, 4]] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 257 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 258 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 259 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 260 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 261 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 262 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 263 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 264 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaa"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 265 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaaaaaaaaa"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 266 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaaaaaaaaaaaa"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 267 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 268 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 269 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 270 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 271 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 272 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 273 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": true}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 274 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": 123.45}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 275 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": "123.45"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 276 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": "abc"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 277 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 278 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 279 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 280 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": true}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 281 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": 123.45}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 282 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": "123.45"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 283 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": "abc"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 284 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 285 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 286 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 287 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 288 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 289 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": ["aaa", null, [1, 2, "3", {}], { "k" : "v" }]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 290 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 291 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": [1, 2]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 292 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 293 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": "(abc,42,01.02.2003)"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 294 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 295 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": [1, 2]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 296 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 297 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": ["(abc,42,01.02.2003)"]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 298 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": "{\"(abc,42,01.02.2003)\"}"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 299 +SELECT rec FROM json_populate_record( + row(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + row('x',3,'2012-12-31 15:30:56')::jpop,NULL)::jsrec, + '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}' +) q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 300 +-- anonymous record type +SELECT json_populate_record(null::record, '{"x": 0, "y": 1}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 301 +SELECT json_populate_record(row(1,2), '{"f1": 0, "f2": 1}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 302 +SELECT * FROM + json_populate_record(null::record, '{"x": 776}') AS (x int, y int) +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 303 +-- composite domain +SELECT json_populate_record(null::j_ordered_pair, '{"x": 0, "y": 1}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 304 +SELECT json_populate_record(row(1,2)::j_ordered_pair, '{"x": 0}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 305 +SELECT json_populate_record(row(1,2)::j_ordered_pair, '{"x": 1, "y": 0}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 306 +-- populate_recordset + +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 307 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 308 +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 309 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 310 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 311 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 312 +create type jpop2 as (a int, b json, c int, d int) +-- +STMT: CompositeTypeStmt +== 313 +select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 314 +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 315 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 316 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 317 +-- anonymous record type +SELECT json_populate_recordset(null::record, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 318 +SELECT json_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 319 +SELECT i, json_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 320 +SELECT * FROM + json_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 321 +-- empty array is a corner case +SELECT json_populate_recordset(null::record, '[]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 322 +SELECT json_populate_recordset(row(1,2), '[]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 323 +SELECT * FROM json_populate_recordset(NULL::jpop,'[]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 324 +SELECT * FROM + json_populate_recordset(null::record, '[]') AS (x int, y int) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 325 +-- composite domain +SELECT json_populate_recordset(null::j_ordered_pair, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 326 +SELECT json_populate_recordset(row(1,2)::j_ordered_pair, '[{"x": 0}, {"y": 3}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 327 +SELECT json_populate_recordset(row(1,2)::j_ordered_pair, '[{"x": 1, "y": 0}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 328 +-- negative cases where the wrong record type is supplied +select * from json_populate_recordset(row(0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 329 +select * from json_populate_recordset(row(0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 330 +select * from json_populate_recordset(row(0::int,0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 331 +select * from json_populate_recordset(row(1000000000::int,50::int),'[{"b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 332 +-- test type info caching in json_populate_record() +CREATE TEMP TABLE jspoptest (js json) +-- +TABLE: name="jspoptest" schema="" table="jspoptest" ctx=DDL +STMT: CreateStmt +== 333 +INSERT INTO jspoptest +SELECT '{ + "jsa": [1, "2", null, 4], + "rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}, + "reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}] +}'::json +FROM generate_series(1, 3) +-- +TABLE: name="jspoptest" schema="" table="jspoptest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 334 +SELECT (json_populate_record(NULL::jsrec, js)).* FROM jspoptest +-- +TABLE: name="jspoptest" schema="" table="jspoptest" ctx=Select +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 335 +DROP TYPE jsrec +-- +STMT: DropStmt +== 336 +DROP TYPE jsrec_i_not_null +-- +STMT: DropStmt +== 337 +DROP DOMAIN js_int_not_null +-- +STMT: DropStmt +== 338 +DROP DOMAIN js_int_array_1d +-- +STMT: DropStmt +== 339 +DROP DOMAIN js_int_array_2d +-- +STMT: DropStmt +== 340 +DROP DOMAIN j_ordered_pair +-- +STMT: DropStmt +== 341 +DROP TYPE j_unordered_pair +-- +STMT: DropStmt +== 342 +--json_typeof() function +select value, json_typeof(value) + from (values (json '123.4'), + (json '-1'), + (json '"foo"'), + (json 'true'), + (json 'false'), + (json 'null'), + (json '[1, 2, 3]'), + (json '[]'), + (json '{"x":"foo", "y":123}'), + (json '{}'), + (NULL::json)) + as data(value) +-- +FUNCTION: name="json_typeof" function="json_typeof" schema="" ctx=Call +STMT: SelectStmt +== 343 +-- json_build_array, json_build_object, json_object_agg + +SELECT json_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 344 +SELECT json_build_array('a', NULL) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 345 +-- ok +SELECT json_build_array(VARIADIC NULL::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 346 +-- ok +SELECT json_build_array(VARIADIC '{}'::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 347 +-- ok +SELECT json_build_array(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 348 +-- ok +SELECT json_build_array(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 349 +-- ok +SELECT json_build_array(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 350 +-- ok +SELECT json_build_array(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 351 +-- ok +SELECT json_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 352 +-- ok + +SELECT json_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 353 +SELECT json_build_object( + 'a', json_build_object('b',false,'c',99), + 'd', json_build_object('e',array[9,8,7]::int[], + 'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r))) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 354 +SELECT json_build_object('{a,b,c}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 355 +-- error +SELECT json_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 356 +-- error, key cannot be array +SELECT json_build_object('a', 'b', 'c') +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 357 +-- error +SELECT json_build_object(NULL, 'a') +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 358 +-- error, key cannot be NULL +SELECT json_build_object('a', NULL) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 359 +-- ok +SELECT json_build_object(VARIADIC NULL::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 360 +-- ok +SELECT json_build_object(VARIADIC '{}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 361 +-- ok +SELECT json_build_object(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 362 +-- error +SELECT json_build_object(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 363 +-- ok +SELECT json_build_object(VARIADIC ARRAY[NULL, 'a']::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 364 +-- error, key cannot be NULL +SELECT json_build_object(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 365 +-- ok +SELECT json_build_object(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 366 +-- ok +SELECT json_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 367 +-- ok + +-- empty objects/arrays +SELECT json_build_array() +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +== 368 +SELECT json_build_object() +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 369 +-- make sure keys are quoted +SELECT json_build_object(1,2) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 370 +-- keys must be scalar and not null +SELECT json_build_object(null,2) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 371 +SELECT json_build_object(r,2) FROM (SELECT 1 AS a, 2 AS b) r +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 372 +SELECT json_build_object(json '{"a":1,"b":2}', 3) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 373 +SELECT json_build_object('{1,2,3}'::int[], 3) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 374 +CREATE TEMP TABLE foo (serial_num int, name text, type text) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 375 +INSERT INTO foo VALUES (847001,'t15','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 376 +INSERT INTO foo VALUES (847002,'t16','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 377 +INSERT INTO foo VALUES (847003,'sub-alpha','GESS90') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 378 +SELECT json_build_object('turbines',json_object_agg(serial_num,json_build_object('name',name,'type',type))) +FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="json_object_agg" function="json_object_agg" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +== 379 +SELECT json_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="json_object_agg" function="json_object_agg" schema="" ctx=Call +STMT: SelectStmt +== 380 +INSERT INTO foo VALUES (999999, NULL, 'bar') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 381 +SELECT json_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="json_object_agg" function="json_object_agg" schema="" ctx=Call +STMT: SelectStmt +== 382 +-- json_object + +-- empty object, one dimension +SELECT json_object('{}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 383 +-- empty object, two dimensions +SELECT json_object('{}', '{}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 384 +-- one dimension +SELECT json_object('{a,1,b,2,3,NULL,"d e f","a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 385 +-- same but with two dimensions +SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 386 +-- odd number error +SELECT json_object('{a,b,c}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 387 +-- one column error +SELECT json_object('{{a},{b}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 388 +-- too many columns error +SELECT json_object('{{a,b,c},{b,c,d}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 389 +-- too many dimensions error +SELECT json_object('{{{a,b},{c,d}},{{b,c},{d,e}}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 390 +--two argument form of json_object + +select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 391 +-- too many dimensions +SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}', '{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 392 +-- mismatched dimensions + +select json_object('{a,b,c,"d e f",g}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 393 +select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c",g}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 394 +-- null key error + +select json_object('{a,b,NULL,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 395 +-- empty key is allowed + +select json_object('{a,b,"","d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 396 +-- json_object_agg_unique requires unique keys +select json_object_agg_unique(mod(i,100), i) from generate_series(0, 199) i +-- +FUNCTION: name="json_object_agg_unique" function="json_object_agg_unique" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 397 +-- json_to_record and json_to_recordset + +select * from json_to_record('{"a":1,"b":"foo","c":"bar"}') + as x(a int, b text, d text) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 398 +select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') + as x(a int, b text, c boolean) +-- +FUNCTION: name="json_to_recordset" function="json_to_recordset" schema="" ctx=Call +STMT: SelectStmt +== 399 +select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]') + as x(a int, b json, c boolean) +-- +FUNCTION: name="json_to_recordset" function="json_to_recordset" schema="" ctx=Call +STMT: SelectStmt +== 400 +select *, c is null as c_is_null +from json_to_record('{"a":1, "b":{"c":16, "d":2}, "x":8, "ca": ["1 2", 3], "ia": [[1,2],[3,4]], "r": {"a": "aaa", "b": 123}}'::json) + as t(a int, b json, c text, x int, ca char(5)[], ia int[][], r jpop) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 401 +select *, c is null as c_is_null +from json_to_recordset('[{"a":1, "b":{"c":16, "d":2}, "x":8}]'::json) + as t(a int, b json, c text, x int) +-- +FUNCTION: name="json_to_recordset" function="json_to_recordset" schema="" ctx=Call +STMT: SelectStmt +== 402 +select * from json_to_record('{"ia": null}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 403 +select * from json_to_record('{"ia": 123}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 404 +select * from json_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 405 +select * from json_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 406 +select * from json_to_record('{"ia": [[1], 2]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 407 +select * from json_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 408 +select * from json_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 409 +select * from json_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 410 +select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 411 +select * from json_to_record('{"out": {"key": 1}}') as x(out json) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 412 +select * from json_to_record('{"out": [{"key": 1}]}') as x(out json) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 413 +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out json) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 414 +select * from json_to_record('{"out": {"key": 1}}') as x(out jsonb) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 415 +select * from json_to_record('{"out": [{"key": 1}]}') as x(out jsonb) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 416 +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +== 417 +-- json_strip_nulls + +select json_strip_nulls(null) +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 418 +select json_strip_nulls('1') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 419 +select json_strip_nulls('"a string"') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 420 +select json_strip_nulls('null') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 421 +select json_strip_nulls('[1,2,null,3,4]') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 422 +select json_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 423 +select json_strip_nulls('[1,{"a":1,"b":null,"c":2},3]') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 424 +-- an empty object is not null and should not be stripped +select json_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 425 +-- json to tsvector +select to_tsvector('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 426 +-- json to tsvector with config +select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 427 +-- json to tsvector with stop words +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 428 +-- json to tsvector with numeric values +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 429 +-- json_to_tsvector +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 430 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 431 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 432 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 433 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 434 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 435 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 436 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 437 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 438 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 439 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 440 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 441 +-- to_tsvector corner cases +select to_tsvector('""'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 442 +select to_tsvector('{}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 443 +select to_tsvector('[]'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 444 +select to_tsvector('null'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 445 +-- json_to_tsvector corner cases +select json_to_tsvector('""'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 446 +select json_to_tsvector('{}'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 447 +select json_to_tsvector('[]'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 448 +select json_to_tsvector('null'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 449 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '""') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 450 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '{}') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 451 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '[]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 452 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, 'null') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 453 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["all", null]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 454 +-- ts_headline for json +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 455 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 456 +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 457 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 458 +-- corner cases for ts_headline with json +select ts_headline('null'::json, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 459 +select ts_headline('{}'::json, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 460 +select ts_headline('[]'::json, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/json_encoding.metadata.json b/parser/testdata/summary/postgres_regress/json_encoding.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/json_encoding.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary/postgres_regress/json_encoding.test b/parser/testdata/summary/postgres_regress/json_encoding.test new file mode 100644 index 0000000..9618e7b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/json_encoding.test @@ -0,0 +1,231 @@ +== 001 +|-- +-- encoding-sensitive tests for json and jsonb +|-- + +-- We provide expected-results files for UTF8 (json_encoding.out) +-- and for SQL_ASCII (json_encoding_1.out). Skip otherwise. +SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') + AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +== 002 +SELECT getdatabaseencoding() +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- just to label the results files + +-- first json + +-- basic unicode input +SELECT '"\u"'::json +-- +STMT: SelectStmt +== 004 +-- ERROR, incomplete escape +SELECT '"\u00"'::json +-- +STMT: SelectStmt +== 005 +-- ERROR, incomplete escape +SELECT '"\u000g"'::json +-- +STMT: SelectStmt +== 006 +-- ERROR, g is not a hex digit +SELECT '"\u0000"'::json +-- +STMT: SelectStmt +== 007 +-- OK, legal escape +SELECT '"\uaBcD"'::json +-- +STMT: SelectStmt +== 008 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs + +select json '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8 +-- +STMT: SelectStmt +== 009 +select json '{ "a": "\ud83d\ud83d" }' -> 'a' +-- +STMT: SelectStmt +== 010 +-- 2 high surrogates in a row +select json '{ "a": "\ude04\ud83d" }' -> 'a' +-- +STMT: SelectStmt +== 011 +-- surrogates in wrong order +select json '{ "a": "\ud83dX" }' -> 'a' +-- +STMT: SelectStmt +== 012 +-- orphan high surrogate +select json '{ "a": "\ude04X" }' -> 'a' +-- +STMT: SelectStmt +== 013 +-- orphan low surrogate + +--handling of simple unicode escapes + +select json '{ "a": "the Copyright \u00a9 sign" }' as correct_in_utf8 +-- +STMT: SelectStmt +== 014 +select json '{ "a": "dollar \u0024 character" }' as correct_everywhere +-- +STMT: SelectStmt +== 015 +select json '{ "a": "dollar \\u0024 character" }' as not_an_escape +-- +STMT: SelectStmt +== 016 +select json '{ "a": "null \u0000 escape" }' as not_unescaped +-- +STMT: SelectStmt +== 017 +select json '{ "a": "null \\u0000 escape" }' as not_an_escape +-- +STMT: SelectStmt +== 018 +select json '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8 +-- +STMT: SelectStmt +== 019 +select json '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere +-- +STMT: SelectStmt +== 020 +select json '{ "a": "dollar \\u0024 character" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +== 021 +select json '{ "a": "null \u0000 escape" }' ->> 'a' as fails +-- +STMT: SelectStmt +== 022 +select json '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +== 023 +-- then jsonb + +-- basic unicode input +SELECT '"\u"'::jsonb +-- +STMT: SelectStmt +== 024 +-- ERROR, incomplete escape +SELECT '"\u00"'::jsonb +-- +STMT: SelectStmt +== 025 +-- ERROR, incomplete escape +SELECT '"\u000g"'::jsonb +-- +STMT: SelectStmt +== 026 +-- ERROR, g is not a hex digit +SELECT '"\u0045"'::jsonb +-- +STMT: SelectStmt +== 027 +-- OK, legal escape +SELECT '"\u0000"'::jsonb +-- +STMT: SelectStmt +== 028 +-- ERROR, we don't support U+0000 +-- use octet_length here so we don't get an odd unicode char in the +-- output +SELECT octet_length('"\uaBcD"'::jsonb::text) +-- +FUNCTION: name="octet_length" function="octet_length" schema="" ctx=Call +STMT: SelectStmt +== 029 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs + +SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8 +-- +FUNCTION: name="octet_length" function="octet_length" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT jsonb '{ "a": "\ud83d\ud83d" }' -> 'a' +-- +STMT: SelectStmt +== 031 +-- 2 high surrogates in a row +SELECT jsonb '{ "a": "\ude04\ud83d" }' -> 'a' +-- +STMT: SelectStmt +== 032 +-- surrogates in wrong order +SELECT jsonb '{ "a": "\ud83dX" }' -> 'a' +-- +STMT: SelectStmt +== 033 +-- orphan high surrogate +SELECT jsonb '{ "a": "\ude04X" }' -> 'a' +-- +STMT: SelectStmt +== 034 +-- orphan low surrogate + +-- handling of simple unicode escapes + +SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' as correct_in_utf8 +-- +STMT: SelectStmt +== 035 +SELECT jsonb '{ "a": "dollar \u0024 character" }' as correct_everywhere +-- +STMT: SelectStmt +== 036 +SELECT jsonb '{ "a": "dollar \\u0024 character" }' as not_an_escape +-- +STMT: SelectStmt +== 037 +SELECT jsonb '{ "a": "null \u0000 escape" }' as fails +-- +STMT: SelectStmt +== 038 +SELECT jsonb '{ "a": "null \\u0000 escape" }' as not_an_escape +-- +STMT: SelectStmt +== 039 +SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8 +-- +STMT: SelectStmt +== 040 +SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere +-- +STMT: SelectStmt +== 041 +SELECT jsonb '{ "a": "dollar \\u0024 character" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +== 042 +SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' as fails +-- +STMT: SelectStmt +== 043 +SELECT jsonb '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +== 044 +-- soft error for input-time failure + +select * from pg_input_error_info('{ "a": "\ud83d\ude04\ud83d\udc36" }', 'jsonb') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/jsonb.metadata.json b/parser/testdata/summary/postgres_regress/jsonb.metadata.json new file mode 100644 index 0000000..4c380dc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonb.metadata.json @@ -0,0 +1,1063 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary/postgres_regress/jsonb.test b/parser/testdata/summary/postgres_regress/jsonb.test new file mode 100644 index 0000000..3bef236 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonb.test @@ -0,0 +1,5586 @@ +== 001 +-- directory paths are passed to us in environment variables + +CREATE TABLE testjsonb ( + j jsonb +) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: CreateStmt +== 002 +COPY testjsonb FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +-- Strings. +SELECT '""'::jsonb +-- +STMT: SelectStmt +== 004 +-- OK. +SELECT $$''$$::jsonb +-- +STMT: SelectStmt +== 005 +-- ERROR, single quotes are not allowed +SELECT '"abc"'::jsonb +-- +STMT: SelectStmt +== 006 +-- OK +SELECT '"abc'::jsonb +-- +STMT: SelectStmt +== 007 +-- ERROR, quotes not closed +SELECT '"abc +def"'::jsonb +-- +STMT: SelectStmt +== 008 +-- ERROR, unescaped newline in string constant +SELECT '"\n\"\\"'::jsonb +-- +STMT: SelectStmt +== 009 +-- OK, legal escapes +SELECT '"\v"'::jsonb +-- +STMT: SelectStmt +== 010 +-- ERROR, not a valid JSON escape +-- see json_encoding test for input with unicode escapes + +-- Numbers. +SELECT '1'::jsonb +-- +STMT: SelectStmt +== 011 +-- OK +SELECT '0'::jsonb +-- +STMT: SelectStmt +== 012 +-- OK +SELECT '01'::jsonb +-- +STMT: SelectStmt +== 013 +-- ERROR, not valid according to JSON spec +SELECT '0.1'::jsonb +-- +STMT: SelectStmt +== 014 +-- OK +SELECT '9223372036854775808'::jsonb +-- +STMT: SelectStmt +== 015 +-- OK, even though it's too large for int8 +SELECT '1e100'::jsonb +-- +STMT: SelectStmt +== 016 +-- OK +SELECT '1.3e100'::jsonb +-- +STMT: SelectStmt +== 017 +-- OK +SELECT '1f2'::jsonb +-- +STMT: SelectStmt +== 018 +-- ERROR +SELECT '0.x1'::jsonb +-- +STMT: SelectStmt +== 019 +-- ERROR +SELECT '1.3ex100'::jsonb +-- +STMT: SelectStmt +== 020 +-- ERROR + +-- Arrays. +SELECT '[]'::jsonb +-- +STMT: SelectStmt +== 021 +-- OK +SELECT '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'::jsonb +-- +STMT: SelectStmt +== 022 +-- OK +SELECT '[1,2]'::jsonb +-- +STMT: SelectStmt +== 023 +-- OK +SELECT '[1,2,]'::jsonb +-- +STMT: SelectStmt +== 024 +-- ERROR, trailing comma +SELECT '[1,2'::jsonb +-- +STMT: SelectStmt +== 025 +-- ERROR, no closing bracket +SELECT '[1,[2]'::jsonb +-- +STMT: SelectStmt +== 026 +-- ERROR, no closing bracket + +-- Objects. +SELECT '{}'::jsonb +-- +STMT: SelectStmt +== 027 +-- OK +SELECT '{"abc"}'::jsonb +-- +STMT: SelectStmt +== 028 +-- ERROR, no value +SELECT '{"abc":1}'::jsonb +-- +STMT: SelectStmt +== 029 +-- OK +SELECT '{1:"abc"}'::jsonb +-- +STMT: SelectStmt +== 030 +-- ERROR, keys must be strings +SELECT '{"abc",1}'::jsonb +-- +STMT: SelectStmt +== 031 +-- ERROR, wrong separator +SELECT '{"abc"=1}'::jsonb +-- +STMT: SelectStmt +== 032 +-- ERROR, totally wrong separator +SELECT '{"abc"::1}'::jsonb +-- +STMT: SelectStmt +== 033 +-- ERROR, another wrong separator +SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::jsonb +-- +STMT: SelectStmt +== 034 +-- OK +SELECT '{"abc":1:2}'::jsonb +-- +STMT: SelectStmt +== 035 +-- ERROR, colon in wrong spot +SELECT '{"abc":1,3}'::jsonb +-- +STMT: SelectStmt +== 036 +-- ERROR, no value + +-- Recursion. +SET max_stack_depth = '100kB' +-- +STMT: VariableSetStmt +== 037 +SELECT repeat('[', 10000)::jsonb +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT repeat('{"a":', 10000)::jsonb +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 039 +RESET max_stack_depth +-- +STMT: VariableSetStmt +== 040 +-- Miscellaneous stuff. +SELECT 'true'::jsonb +-- +STMT: SelectStmt +== 041 +-- OK +SELECT 'false'::jsonb +-- +STMT: SelectStmt +== 042 +-- OK +SELECT 'null'::jsonb +-- +STMT: SelectStmt +== 043 +-- OK +SELECT ' true '::jsonb +-- +STMT: SelectStmt +== 044 +-- OK, even with extra whitespace +SELECT 'true false'::jsonb +-- +STMT: SelectStmt +== 045 +-- ERROR, too many values +SELECT 'true, false'::jsonb +-- +STMT: SelectStmt +== 046 +-- ERROR, too many values +SELECT 'truf'::jsonb +-- +STMT: SelectStmt +== 047 +-- ERROR, not a keyword +SELECT 'trues'::jsonb +-- +STMT: SelectStmt +== 048 +-- ERROR, not a keyword +SELECT ''::jsonb +-- +STMT: SelectStmt +== 049 +-- ERROR, no value +SELECT ' '::jsonb +-- +STMT: SelectStmt +== 050 +-- ERROR, no value + +-- Multi-line JSON input to check ERROR reporting +SELECT '{ + "one": 1, + "two":"two", + "three": + true}'::jsonb +-- +STMT: SelectStmt +== 051 +-- OK +SELECT '{ + "one": 1, + "two":,"two", -- ERROR extraneous comma before field "two" + "three": + true}'::jsonb +-- +STMT: SelectStmt +== 052 +SELECT '{ + "one": 1, + "two":"two", + "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::jsonb +-- +STMT: SelectStmt +== 053 +-- ERROR missing value for last field + +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'jsonb') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 054 +select pg_input_is_valid('{"a":true', 'jsonb') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 055 +select * from pg_input_error_info('{"a":true', 'jsonb') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 056 +select * from pg_input_error_info('{"a":1e1000000}', 'jsonb') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- make sure jsonb is passed through json generators without being escaped +SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']) +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +STMT: SelectStmt +== 058 +-- anyarray column + +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 059 +analyze rows +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +STMT: VacuumStmt +== 060 +select attname, to_jsonb(histogram_bounds) histogram_bounds +from pg_stats +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1 +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FILTER: schema="" table="" column="tablename" +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +== 061 +-- to_jsonb, timestamps + +select to_jsonb(timestamp '2014-05-28 12:22:35.614298') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 062 +BEGIN +-- +STMT: TransactionStmt +== 063 +SET LOCAL TIME ZONE 10.5 +-- +STMT: VariableSetStmt +== 064 +select to_jsonb(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 065 +SET LOCAL TIME ZONE -8 +-- +STMT: VariableSetStmt +== 066 +select to_jsonb(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 067 +COMMIT +-- +STMT: TransactionStmt +== 068 +select to_jsonb(date '2014-05-28') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 069 +select to_jsonb(date 'Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 070 +select to_jsonb(date '-Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 071 +select to_jsonb(timestamp 'Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 072 +select to_jsonb(timestamp '-Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 073 +select to_jsonb(timestamptz 'Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 074 +select to_jsonb(timestamptz '-Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +== 075 +--jsonb_agg + +SELECT jsonb_agg(q) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="jsonb_agg" function="jsonb_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT jsonb_agg(q ORDER BY x, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="jsonb_agg" function="jsonb_agg" schema="" ctx=Call +STMT: SelectStmt +== 077 +UPDATE rows SET x = NULL WHERE x = 1 +-- +TABLE: name="rows" schema="" table="rows" ctx=DML +STMT: UpdateStmt +== 078 +SELECT jsonb_agg(q ORDER BY x NULLS FIRST, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="jsonb_agg" function="jsonb_agg" schema="" ctx=Call +STMT: SelectStmt +== 079 +-- jsonb extraction functions +CREATE TEMP TABLE test_jsonb ( + json_type text, + test_json jsonb +) +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=DDL +STMT: CreateStmt +== 080 +INSERT INTO test_jsonb VALUES +('scalar','"a scalar"'), +('array','["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}]'), +('object','{"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}}') +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 082 +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 083 +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 084 +SELECT test_json -> 'field2' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 085 +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 086 +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 087 +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 088 +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 089 +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 090 +SELECT test_json -> 9 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 091 +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 092 +SELECT test_json ->> 6 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 093 +SELECT test_json ->> 7 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 094 +SELECT test_json ->> 'field4' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 095 +SELECT test_json ->> 'field5' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 096 +SELECT test_json ->> 'field6' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 097 +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 098 +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 099 +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 100 +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FUNCTION: name="jsonb_object_keys" function="jsonb_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 101 +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FUNCTION: name="jsonb_object_keys" function="jsonb_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 102 +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FUNCTION: name="jsonb_object_keys" function="jsonb_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 103 +-- nulls +SELECT (test_json->'field3') IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 104 +SELECT (test_json->>'field3') IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 105 +SELECT (test_json->3) IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 106 +SELECT (test_json->>3) IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +== 107 +-- corner cases +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> null::text +-- +STMT: SelectStmt +== 108 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> null::int +-- +STMT: SelectStmt +== 109 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> 1 +-- +STMT: SelectStmt +== 110 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> 'z' +-- +STMT: SelectStmt +== 111 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> '' +-- +STMT: SelectStmt +== 112 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 1 +-- +STMT: SelectStmt +== 113 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 3 +-- +STMT: SelectStmt +== 114 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 'z' +-- +STMT: SelectStmt +== 115 +select '{"a": "c", "b": null}'::jsonb -> 'b' +-- +STMT: SelectStmt +== 116 +select '"foo"'::jsonb -> 1 +-- +STMT: SelectStmt +== 117 +select '"foo"'::jsonb -> 'z' +-- +STMT: SelectStmt +== 118 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> null::text +-- +STMT: SelectStmt +== 119 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> null::int +-- +STMT: SelectStmt +== 120 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> 1 +-- +STMT: SelectStmt +== 121 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> 'z' +-- +STMT: SelectStmt +== 122 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> '' +-- +STMT: SelectStmt +== 123 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 1 +-- +STMT: SelectStmt +== 124 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 3 +-- +STMT: SelectStmt +== 125 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 'z' +-- +STMT: SelectStmt +== 126 +select '{"a": "c", "b": null}'::jsonb ->> 'b' +-- +STMT: SelectStmt +== 127 +select '"foo"'::jsonb ->> 1 +-- +STMT: SelectStmt +== 128 +select '"foo"'::jsonb ->> 'z' +-- +STMT: SelectStmt +== 129 +-- equality and inequality +SELECT '{"x":"y"}'::jsonb = '{"x":"y"}'::jsonb +-- +STMT: SelectStmt +== 130 +SELECT '{"x":"y"}'::jsonb = '{"x":"z"}'::jsonb +-- +STMT: SelectStmt +== 131 +SELECT '{"x":"y"}'::jsonb <> '{"x":"y"}'::jsonb +-- +STMT: SelectStmt +== 132 +SELECT '{"x":"y"}'::jsonb <> '{"x":"z"}'::jsonb +-- +STMT: SelectStmt +== 133 +-- containment +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +== 134 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "c":null}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +== 135 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "g":null}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +== 136 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"g":null}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +== 137 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"c"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +== 138 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +== 139 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "c":"q"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +== 140 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b"}' +-- +STMT: SelectStmt +== 141 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "c":null}' +-- +STMT: SelectStmt +== 142 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "g":null}' +-- +STMT: SelectStmt +== 143 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"g":null}' +-- +STMT: SelectStmt +== 144 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"c"}' +-- +STMT: SelectStmt +== 145 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b"}' +-- +STMT: SelectStmt +== 146 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "c":"q"}' +-- +STMT: SelectStmt +== 147 +SELECT '[1,2]'::jsonb @> '[1,2,2]'::jsonb +-- +STMT: SelectStmt +== 148 +SELECT '[1,1,2]'::jsonb @> '[1,2,2]'::jsonb +-- +STMT: SelectStmt +== 149 +SELECT '[[1,2]]'::jsonb @> '[[1,2,2]]'::jsonb +-- +STMT: SelectStmt +== 150 +SELECT '[1,2,2]'::jsonb <@ '[1,2]'::jsonb +-- +STMT: SelectStmt +== 151 +SELECT '[1,2,2]'::jsonb <@ '[1,1,2]'::jsonb +-- +STMT: SelectStmt +== 152 +SELECT '[[1,2,2]]'::jsonb <@ '[[1,2]]'::jsonb +-- +STMT: SelectStmt +== 153 +SELECT jsonb_contained('{"a":"b"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +== 154 +SELECT jsonb_contained('{"a":"b", "c":null}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT jsonb_contained('{"a":"b", "g":null}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +== 156 +SELECT jsonb_contained('{"g":null}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +== 157 +SELECT jsonb_contained('{"a":"c"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +== 158 +SELECT jsonb_contained('{"a":"b"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +== 159 +SELECT jsonb_contained('{"a":"b", "c":"q"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +== 160 +SELECT '{"a":"b"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +== 161 +SELECT '{"a":"b", "c":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +== 162 +SELECT '{"a":"b", "g":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +== 163 +SELECT '{"g":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +== 164 +SELECT '{"a":"c"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +== 165 +SELECT '{"a":"b"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +== 166 +SELECT '{"a":"b", "c":"q"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +== 167 +-- Raw scalar may contain another raw scalar, array may contain a raw scalar +SELECT '[5]'::jsonb @> '[5]' +-- +STMT: SelectStmt +== 168 +SELECT '5'::jsonb @> '5' +-- +STMT: SelectStmt +== 169 +SELECT '[5]'::jsonb @> '5' +-- +STMT: SelectStmt +== 170 +-- But a raw scalar cannot contain an array +SELECT '5'::jsonb @> '[5]' +-- +STMT: SelectStmt +== 171 +-- In general, one thing should always contain itself. Test array containment: +SELECT '["9", ["7", "3"], 1]'::jsonb @> '["9", ["7", "3"], 1]'::jsonb +-- +STMT: SelectStmt +== 172 +SELECT '["9", ["7", "3"], ["1"]]'::jsonb @> '["9", ["7", "3"], ["1"]]'::jsonb +-- +STMT: SelectStmt +== 173 +-- array containment string matching confusion bug +SELECT '{ "name": "Bob", "tags": [ "enim", "qui"]}'::jsonb @> '{"tags":["qu"]}' +-- +STMT: SelectStmt +== 174 +-- array length +SELECT jsonb_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +== 175 +SELECT jsonb_array_length('[]') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +== 176 +SELECT jsonb_array_length('{"f1":1,"f2":[5,6]}') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +== 177 +SELECT jsonb_array_length('4') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +== 178 +-- each +SELECT jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null}') +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +== 179 +SELECT jsonb_each('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +== 180 +SELECT * FROM jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +== 181 +SELECT * FROM jsonb_each('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +== 182 +SELECT jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}') +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +== 183 +SELECT jsonb_each_text('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +== 184 +SELECT * FROM jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +== 185 +SELECT * FROM jsonb_each_text('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +== 186 +-- exists +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'a') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +== 187 +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'b') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +== 188 +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'c') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +== 189 +SELECT jsonb_exists('{"a":"null", "b":"qq"}', 'a') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +== 190 +SELECT jsonb '{"a":null, "b":"qq"}' ? 'a' +-- +STMT: SelectStmt +== 191 +SELECT jsonb '{"a":null, "b":"qq"}' ? 'b' +-- +STMT: SelectStmt +== 192 +SELECT jsonb '{"a":null, "b":"qq"}' ? 'c' +-- +STMT: SelectStmt +== 193 +SELECT jsonb '{"a":"null", "b":"qq"}' ? 'a' +-- +STMT: SelectStmt +== 194 +-- array exists - array elements should behave as keys +SELECT count(*) from testjsonb WHERE j->'array' ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 195 +-- type sensitive array exists - should return no rows (since "exists" only +-- matches strings that are either object keys or array elements) +SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 196 +-- However, a raw scalar is *contained* within the array +SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 197 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['a','b']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +== 198 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['b','a']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +== 199 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['c','a']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +== 200 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['c','d']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +== 201 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', '{}'::text[]) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +== 202 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['a','b'] +-- +STMT: SelectStmt +== 203 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['b','a'] +-- +STMT: SelectStmt +== 204 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['c','a'] +-- +STMT: SelectStmt +== 205 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['c','d'] +-- +STMT: SelectStmt +== 206 +SELECT jsonb '{"a":null, "b":"qq"}' ?| '{}'::text[] +-- +STMT: SelectStmt +== 207 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['a','b']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +== 208 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['b','a']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +== 209 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['c','a']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +== 210 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['c','d']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +== 211 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', '{}'::text[]) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +== 212 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['a','b'] +-- +STMT: SelectStmt +== 213 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['b','a'] +-- +STMT: SelectStmt +== 214 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['c','a'] +-- +STMT: SelectStmt +== 215 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['c','d'] +-- +STMT: SelectStmt +== 216 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['a','a', 'b', 'b', 'b'] +-- +STMT: SelectStmt +== 217 +SELECT jsonb '{"a":null, "b":"qq"}' ?& '{}'::text[] +-- +STMT: SelectStmt +== 218 +-- typeof +SELECT jsonb_typeof('{}') AS object +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 219 +SELECT jsonb_typeof('{"c":3,"p":"o"}') AS object +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 220 +SELECT jsonb_typeof('[]') AS array +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 221 +SELECT jsonb_typeof('["a", 1]') AS array +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 222 +SELECT jsonb_typeof('null') AS "null" +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 223 +SELECT jsonb_typeof('1') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 224 +SELECT jsonb_typeof('-1') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 225 +SELECT jsonb_typeof('1.0') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 226 +SELECT jsonb_typeof('1e2') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 227 +SELECT jsonb_typeof('-1.0') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 228 +SELECT jsonb_typeof('true') AS boolean +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 229 +SELECT jsonb_typeof('false') AS boolean +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT jsonb_typeof('"hello"') AS string +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT jsonb_typeof('"true"') AS string +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 232 +SELECT jsonb_typeof('"1.0"') AS string +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +== 233 +-- jsonb_build_array, jsonb_build_object, jsonb_object_agg + +SELECT jsonb_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 234 +SELECT jsonb_build_array('a', NULL) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 235 +-- ok +SELECT jsonb_build_array(VARIADIC NULL::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 236 +-- ok +SELECT jsonb_build_array(VARIADIC '{}'::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 237 +-- ok +SELECT jsonb_build_array(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 238 +-- ok +SELECT jsonb_build_array(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 239 +-- ok +SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 240 +-- ok +SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 241 +-- ok +SELECT jsonb_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 242 +-- ok + +SELECT jsonb_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 243 +SELECT jsonb_build_object( + 'a', jsonb_build_object('b',false,'c',99), + 'd', jsonb_build_object('e',array[9,8,7]::int[], + 'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r))) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 244 +SELECT jsonb_build_object('{a,b,c}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 245 +-- error +SELECT jsonb_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 246 +-- error, key cannot be array +SELECT jsonb_build_object('a', 'b', 'c') +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 247 +-- error +SELECT jsonb_build_object(NULL, 'a') +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 248 +-- error, key cannot be NULL +SELECT jsonb_build_object('a', NULL) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 249 +-- ok +SELECT jsonb_build_object(VARIADIC NULL::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 250 +-- ok +SELECT jsonb_build_object(VARIADIC '{}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 251 +-- ok +SELECT jsonb_build_object(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 252 +-- error +SELECT jsonb_build_object(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 253 +-- ok +SELECT jsonb_build_object(VARIADIC ARRAY[NULL, 'a']::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 254 +-- error, key cannot be NULL +SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 255 +-- ok +SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 256 +-- ok +SELECT jsonb_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 257 +-- ok + +-- empty objects/arrays +SELECT jsonb_build_array() +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +== 258 +SELECT jsonb_build_object() +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 259 +-- make sure keys are quoted +SELECT jsonb_build_object(1,2) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 260 +-- keys must be scalar and not null +SELECT jsonb_build_object(null,2) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 261 +SELECT jsonb_build_object(r,2) FROM (SELECT 1 AS a, 2 AS b) r +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 262 +SELECT jsonb_build_object(json '{"a":1,"b":2}', 3) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 263 +SELECT jsonb_build_object('{1,2,3}'::int[], 3) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 264 +-- handling of NULL values +SELECT jsonb_object_agg(1, NULL::jsonb) +-- +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +== 265 +SELECT jsonb_object_agg(NULL, '{"a":1}') +-- +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +== 266 +CREATE TEMP TABLE foo (serial_num int, name text, type text) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 267 +INSERT INTO foo VALUES (847001,'t15','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +INSERT INTO foo VALUES (847002,'t16','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +INSERT INTO foo VALUES (847003,'sub-alpha','GESS90') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 270 +SELECT jsonb_build_object('turbines',jsonb_object_agg(serial_num,jsonb_build_object('name',name,'type',type))) +FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 271 +SELECT jsonb_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +== 272 +INSERT INTO foo VALUES (999999, NULL, 'bar') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 273 +SELECT jsonb_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +== 274 +-- edge case for parser +SELECT jsonb_object_agg(DISTINCT 'a', 'abc') +-- +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +== 275 +-- jsonb_object + +-- empty object, one dimension +SELECT jsonb_object('{}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 276 +-- empty object, two dimensions +SELECT jsonb_object('{}', '{}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 277 +-- one dimension +SELECT jsonb_object('{a,1,b,2,3,NULL,"d e f","a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 278 +-- same but with two dimensions +SELECT jsonb_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 279 +-- odd number error +SELECT jsonb_object('{a,b,c}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 280 +-- one column error +SELECT jsonb_object('{{a},{b}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 281 +-- too many columns error +SELECT jsonb_object('{{a,b,c},{b,c,d}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 282 +-- too many dimensions error +SELECT jsonb_object('{{{a,b},{c,d}},{{b,c},{d,e}}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 283 +--two argument form of jsonb_object + +select jsonb_object('{a,b,c,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 284 +-- too many dimensions +SELECT jsonb_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}', '{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 285 +-- mismatched dimensions + +select jsonb_object('{a,b,c,"d e f",g}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 286 +select jsonb_object('{a,b,c,"d e f"}','{1,2,3,"a b c",g}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 287 +-- null key error + +select jsonb_object('{a,b,NULL,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 288 +-- empty key is allowed + +select jsonb_object('{a,b,"","d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +== 289 +-- extract_path, extract_path_as_text +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 290 +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 291 +SELECT jsonb_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 292 +SELECT jsonb_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 293 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 294 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 295 +SELECT jsonb_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 296 +SELECT jsonb_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 297 +-- extract_path nulls +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') IS NULL AS expect_false +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 298 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') IS NULL AS expect_true +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 299 +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') IS NULL AS expect_false +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +== 300 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') IS NULL AS expect_true +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +== 301 +-- extract_path operators +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f4','f6'] +-- +STMT: SelectStmt +== 302 +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2'] +-- +STMT: SelectStmt +== 303 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2','0'] +-- +STMT: SelectStmt +== 304 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2','1'] +-- +STMT: SelectStmt +== 305 +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f4','f6'] +-- +STMT: SelectStmt +== 306 +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2'] +-- +STMT: SelectStmt +== 307 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2','0'] +-- +STMT: SelectStmt +== 308 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2','1'] +-- +STMT: SelectStmt +== 309 +-- corner cases for same +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> '{}' +-- +STMT: SelectStmt +== 310 +select '[1,2,3]'::jsonb #> '{}' +-- +STMT: SelectStmt +== 311 +select '"foo"'::jsonb #> '{}' +-- +STMT: SelectStmt +== 312 +select '42'::jsonb #> '{}' +-- +STMT: SelectStmt +== 313 +select 'null'::jsonb #> '{}' +-- +STMT: SelectStmt +== 314 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a'] +-- +STMT: SelectStmt +== 315 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a', null] +-- +STMT: SelectStmt +== 316 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a', ''] +-- +STMT: SelectStmt +== 317 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b'] +-- +STMT: SelectStmt +== 318 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b','c'] +-- +STMT: SelectStmt +== 319 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b','c','d'] +-- +STMT: SelectStmt +== 320 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','z','c'] +-- +STMT: SelectStmt +== 321 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #> array['a','1','b'] +-- +STMT: SelectStmt +== 322 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #> array['a','z','b'] +-- +STMT: SelectStmt +== 323 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #> array['1','b'] +-- +STMT: SelectStmt +== 324 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #> array['z','b'] +-- +STMT: SelectStmt +== 325 +select '[{"b": "c"}, {"b": null}]'::jsonb #> array['1','b'] +-- +STMT: SelectStmt +== 326 +select '"foo"'::jsonb #> array['z'] +-- +STMT: SelectStmt +== 327 +select '42'::jsonb #> array['f2'] +-- +STMT: SelectStmt +== 328 +select '42'::jsonb #> array['0'] +-- +STMT: SelectStmt +== 329 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> '{}' +-- +STMT: SelectStmt +== 330 +select '[1,2,3]'::jsonb #>> '{}' +-- +STMT: SelectStmt +== 331 +select '"foo"'::jsonb #>> '{}' +-- +STMT: SelectStmt +== 332 +select '42'::jsonb #>> '{}' +-- +STMT: SelectStmt +== 333 +select 'null'::jsonb #>> '{}' +-- +STMT: SelectStmt +== 334 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a'] +-- +STMT: SelectStmt +== 335 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a', null] +-- +STMT: SelectStmt +== 336 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a', ''] +-- +STMT: SelectStmt +== 337 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b'] +-- +STMT: SelectStmt +== 338 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b','c'] +-- +STMT: SelectStmt +== 339 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b','c','d'] +-- +STMT: SelectStmt +== 340 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','z','c'] +-- +STMT: SelectStmt +== 341 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #>> array['a','1','b'] +-- +STMT: SelectStmt +== 342 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #>> array['a','z','b'] +-- +STMT: SelectStmt +== 343 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #>> array['1','b'] +-- +STMT: SelectStmt +== 344 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #>> array['z','b'] +-- +STMT: SelectStmt +== 345 +select '[{"b": "c"}, {"b": null}]'::jsonb #>> array['1','b'] +-- +STMT: SelectStmt +== 346 +select '"foo"'::jsonb #>> array['z'] +-- +STMT: SelectStmt +== 347 +select '42'::jsonb #>> array['f2'] +-- +STMT: SelectStmt +== 348 +select '42'::jsonb #>> array['0'] +-- +STMT: SelectStmt +== 349 +-- array_elements +SELECT jsonb_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false]') +-- +FUNCTION: name="jsonb_array_elements" function="jsonb_array_elements" schema="" ctx=Call +STMT: SelectStmt +== 350 +SELECT * FROM jsonb_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false]') q +-- +FUNCTION: name="jsonb_array_elements" function="jsonb_array_elements" schema="" ctx=Call +STMT: SelectStmt +== 351 +SELECT jsonb_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') +-- +FUNCTION: name="jsonb_array_elements_text" function="jsonb_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +== 352 +SELECT * FROM jsonb_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q +-- +FUNCTION: name="jsonb_array_elements_text" function="jsonb_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +== 353 +-- populate_record +CREATE TYPE jbpop AS (a text, b int, c timestamp) +-- +STMT: CompositeTypeStmt +== 354 +CREATE DOMAIN jsb_int_not_null AS int NOT NULL +-- +STMT: CreateDomainStmt +== 355 +CREATE DOMAIN jsb_int_array_1d AS int[] CHECK(array_length(VALUE, 1) = 3) +-- +STMT: CreateDomainStmt +== 356 +CREATE DOMAIN jsb_int_array_2d AS int[][] CHECK(array_length(VALUE, 2) = 3) +-- +STMT: CreateDomainStmt +== 357 +create type jb_unordered_pair as (x int, y int) +-- +STMT: CompositeTypeStmt +== 358 +create domain jb_ordered_pair as jb_unordered_pair check((value).x <= (value).y) +-- +STMT: CreateDomainStmt +== 359 +CREATE TYPE jsbrec AS ( + i int, + ia _int4, + ia1 int[], + ia2 int[][], + ia3 int[][][], + ia1d jsb_int_array_1d, + ia2d jsb_int_array_2d, + t text, + ta text[], + c char(10), + ca char(10)[], + ts timestamp, + js json, + jsb jsonb, + jsa json[], + rec jbpop, + reca jbpop[] +) +-- +STMT: CompositeTypeStmt +== 360 +CREATE TYPE jsbrec_i_not_null AS ( + i jsb_int_not_null +) +-- +STMT: CompositeTypeStmt +== 361 +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 362 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 363 +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 364 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 365 +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 366 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 367 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 368 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop, '{}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 369 +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"x": 43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 370 +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"i": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 371 +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"i": 12345}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 372 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 373 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 374 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 375 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1, 2], [3, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 376 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 377 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], [2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 378 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": "{1,2,3}"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 379 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 380 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 381 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 382 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": [[1, 2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 383 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 384 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 385 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 386 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": [1, "2", null]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 387 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 388 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 389 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[], []]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 390 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], [3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 391 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], 3, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 392 +SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{"ia2d": [[1, "2"], [null, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 393 +SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{"ia2d": [[1, "2", 3], [null, 5, 6]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 394 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 395 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 396 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[], []], [[], []], [[], []] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 397 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2]], [[3, 4]] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 398 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 399 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 400 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 401 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 402 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 403 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 404 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 405 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 406 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaaaaaaaaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 407 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaaaaaaaaaaaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 408 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 409 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 410 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 411 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 412 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 413 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 414 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": true}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 415 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": 123.45}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 416 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": "123.45"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 417 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": "abc"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 418 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 419 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 420 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 421 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": true}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 422 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": 123.45}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 423 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": "123.45"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 424 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": "abc"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 425 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 426 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 427 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 428 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 429 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 430 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": ["aaa", null, [1, 2, "3", {}], { "k" : "v" }]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 431 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 432 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": [1, 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 433 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 434 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": "(abc,42,01.02.2003)"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 435 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 436 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": [1, 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 437 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 438 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": ["(abc,42,01.02.2003)"]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 439 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": "{\"(abc,42,01.02.2003)\"}"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 440 +SELECT rec FROM jsonb_populate_record( + row(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + row('x',3,'2012-12-31 15:30:56')::jbpop,NULL)::jsbrec, + '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}' +) q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 441 +-- Tests to check soft-error support for populate_record_field() + +-- populate_scalar() +create type jsb_char2 as (a char(2)) +-- +STMT: CompositeTypeStmt +== 442 +select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aaa"}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 443 +select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 444 +select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aa"}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 445 +select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 446 +-- populate_array() +create type jsb_ia as (a int[]) +-- +STMT: CompositeTypeStmt +== 447 +create type jsb_ia2 as (a int[][]) +-- +STMT: CompositeTypeStmt +== 448 +select jsonb_populate_record_valid(NULL::jsb_ia, '{"a": 43.2}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 449 +select * from jsonb_populate_record(NULL::jsb_ia, '{"a": 43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 450 +select jsonb_populate_record_valid(NULL::jsb_ia, '{"a": [1, 2]}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 451 +select * from jsonb_populate_record(NULL::jsb_ia, '{"a": [1, 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 452 +select jsonb_populate_record_valid(NULL::jsb_ia2, '{"a": [[1], [2, 3]]}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 453 +select * from jsonb_populate_record(NULL::jsb_ia2, '{"a": [[1], [2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 454 +select jsonb_populate_record_valid(NULL::jsb_ia2, '{"a": [[1, 0], [2, 3]]}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 455 +select * from jsonb_populate_record(NULL::jsb_ia2, '{"a": [[1, 0], [2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 456 +-- populate_domain() +create domain jsb_i_not_null as int not null +-- +STMT: CreateDomainStmt +== 457 +create domain jsb_i_gt_1 as int check (value > 1) +-- +STMT: CreateDomainStmt +== 458 +create type jsb_i_not_null_rec as (a jsb_i_not_null) +-- +STMT: CompositeTypeStmt +== 459 +create type jsb_i_gt_1_rec as (a jsb_i_gt_1) +-- +STMT: CompositeTypeStmt +== 460 +select jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{"a": null}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 461 +select * from jsonb_populate_record(NULL::jsb_i_not_null_rec, '{"a": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 462 +select jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{"a": 1}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 463 +select * from jsonb_populate_record(NULL::jsb_i_not_null_rec, '{"a": 1}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 464 +select jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{"a": 1}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 465 +select * from jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{"a": 1}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 466 +select jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{"a": 2}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +== 467 +select * from jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{"a": 2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 468 +drop type jsb_ia, jsb_ia2, jsb_char2, jsb_i_not_null_rec, jsb_i_gt_1_rec +-- +STMT: DropStmt +== 469 +drop domain jsb_i_not_null, jsb_i_gt_1 +-- +STMT: DropStmt +== 470 +-- anonymous record type +SELECT jsonb_populate_record(null::record, '{"x": 0, "y": 1}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 471 +SELECT jsonb_populate_record(row(1,2), '{"f1": 0, "f2": 1}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 472 +SELECT * FROM + jsonb_populate_record(null::record, '{"x": 776}') AS (x int, y int) +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 473 +-- composite domain +SELECT jsonb_populate_record(null::jb_ordered_pair, '{"x": 0, "y": 1}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 474 +SELECT jsonb_populate_record(row(1,2)::jb_ordered_pair, '{"x": 0}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 475 +SELECT jsonb_populate_record(row(1,2)::jb_ordered_pair, '{"x": 1, "y": 0}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 476 +-- populate_recordset +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 477 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 478 +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 479 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 480 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 481 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 482 +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 483 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 484 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 485 +-- anonymous record type +SELECT jsonb_populate_recordset(null::record, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 486 +SELECT jsonb_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 487 +SELECT i, jsonb_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 488 +SELECT * FROM + jsonb_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 489 +-- empty array is a corner case +SELECT jsonb_populate_recordset(null::record, '[]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 490 +SELECT jsonb_populate_recordset(row(1,2), '[]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 491 +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 492 +SELECT * FROM + jsonb_populate_recordset(null::record, '[]') AS (x int, y int) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 493 +-- composite domain +SELECT jsonb_populate_recordset(null::jb_ordered_pair, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 494 +SELECT jsonb_populate_recordset(row(1,2)::jb_ordered_pair, '[{"x": 0}, {"y": 3}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 495 +SELECT jsonb_populate_recordset(row(1,2)::jb_ordered_pair, '[{"x": 1, "y": 0}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 496 +-- negative cases where the wrong record type is supplied +select * from jsonb_populate_recordset(row(0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 497 +select * from jsonb_populate_recordset(row(0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 498 +select * from jsonb_populate_recordset(row(0::int,0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 499 +select * from jsonb_populate_recordset(row(1000000000::int,50::int),'[{"b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +== 500 +-- jsonb_to_record and jsonb_to_recordset + +select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}') + as x(a int, b text, d text) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 501 +select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') + as x(a int, b text, c boolean) +-- +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: SelectStmt +== 502 +select *, c is null as c_is_null +from jsonb_to_record('{"a":1, "b":{"c":16, "d":2}, "x":8, "ca": ["1 2", 3], "ia": [[1,2],[3,4]], "r": {"a": "aaa", "b": 123}}'::jsonb) + as t(a int, b jsonb, c text, x int, ca char(5)[], ia int[][], r jbpop) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 503 +select *, c is null as c_is_null +from jsonb_to_recordset('[{"a":1, "b":{"c":16, "d":2}, "x":8}]'::jsonb) + as t(a int, b jsonb, c text, x int) +-- +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: SelectStmt +== 504 +select * from jsonb_to_record('{"ia": null}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 505 +select * from jsonb_to_record('{"ia": 123}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 506 +select * from jsonb_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 507 +select * from jsonb_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 508 +select * from jsonb_to_record('{"ia": [[1], 2]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 509 +select * from jsonb_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 510 +select * from jsonb_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 511 +select * from jsonb_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 512 +select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 513 +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out json) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 514 +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out json) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 515 +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out json) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 516 +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out jsonb) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 517 +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out jsonb) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 518 +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +== 519 +-- test type info caching in jsonb_populate_record() +CREATE TEMP TABLE jsbpoptest (js jsonb) +-- +TABLE: name="jsbpoptest" schema="" table="jsbpoptest" ctx=DDL +STMT: CreateStmt +== 520 +INSERT INTO jsbpoptest +SELECT '{ + "jsa": [1, "2", null, 4], + "rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}, + "reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}] +}'::jsonb +FROM generate_series(1, 3) +-- +TABLE: name="jsbpoptest" schema="" table="jsbpoptest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 521 +SELECT (jsonb_populate_record(NULL::jsbrec, js)).* FROM jsbpoptest +-- +TABLE: name="jsbpoptest" schema="" table="jsbpoptest" ctx=Select +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +== 522 +DROP TYPE jsbrec +-- +STMT: DropStmt +== 523 +DROP TYPE jsbrec_i_not_null +-- +STMT: DropStmt +== 524 +DROP DOMAIN jsb_int_not_null +-- +STMT: DropStmt +== 525 +DROP DOMAIN jsb_int_array_1d +-- +STMT: DropStmt +== 526 +DROP DOMAIN jsb_int_array_2d +-- +STMT: DropStmt +== 527 +DROP DOMAIN jb_ordered_pair +-- +STMT: DropStmt +== 528 +DROP TYPE jb_unordered_pair +-- +STMT: DropStmt +== 529 +-- indexing +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 530 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 531 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 532 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 533 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 534 +SELECT count(*) FROM testjsonb WHERE j ? 'public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 535 +SELECT count(*) FROM testjsonb WHERE j ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 536 +SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 537 +SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 538 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 539 +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 540 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 541 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 542 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 543 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 544 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 545 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 546 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 547 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 548 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 549 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 550 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 551 +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 552 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 553 +SELECT count(*) FROM testjsonb WHERE j @? '$' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 554 +SELECT count(*) FROM testjsonb WHERE j @? '$.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 555 +SELECT count(*) FROM testjsonb WHERE j @? '$.bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 556 +CREATE INDEX jidx ON testjsonb USING gin (j) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +== 557 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 558 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 559 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 560 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 561 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 562 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 563 +SELECT count(*) FROM testjsonb WHERE j @> '{"array":["foo"]}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 564 +SELECT count(*) FROM testjsonb WHERE j @> '{"array":["bar"]}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 565 +-- exercise GIN_SEARCH_MODE_ALL +SELECT count(*) FROM testjsonb WHERE j @> '{}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 566 +SELECT count(*) FROM testjsonb WHERE j ? 'public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 567 +SELECT count(*) FROM testjsonb WHERE j ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 568 +SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 569 +SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 570 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +== 571 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 572 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 573 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 574 +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 575 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 576 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 577 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 578 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 579 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 580 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 581 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 582 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 583 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 584 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 585 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 586 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 587 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 588 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +== 589 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 590 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 591 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 592 +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 593 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 594 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 595 +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 596 +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 597 +SELECT count(*) FROM testjsonb WHERE j @? '$' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 598 +SELECT count(*) FROM testjsonb WHERE j @? '$.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 599 +SELECT count(*) FROM testjsonb WHERE j @? '$.bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 600 +-- array exists - array elements should behave as keys (for GIN index scans too) +CREATE INDEX jidx_array ON testjsonb USING gin((j->'array')) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +== 601 +SELECT count(*) from testjsonb WHERE j->'array' ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 602 +-- type sensitive array exists - should return no rows (since "exists" only +-- matches strings that are either object keys or array elements) +SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 603 +-- However, a raw scalar is *contained* within the array +SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 604 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 605 +SELECT count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +== 606 +SELECT key, count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow GROUP BY key ORDER BY count DESC, key +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +== 607 +-- sort/hash +SELECT count(distinct j) FROM testjsonb +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 608 +SET enable_hashagg = off +-- +STMT: VariableSetStmt +== 609 +SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2 +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 610 +SET enable_hashagg = on +-- +STMT: VariableSetStmt +== 611 +SET enable_sort = off +-- +STMT: VariableSetStmt +== 612 +SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2 +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 613 +SELECT distinct * FROM (values (jsonb '{}' || ''::text),('{}')) v(j) +-- +STMT: SelectStmt +== 614 +SET enable_sort = on +-- +STMT: VariableSetStmt +== 615 +RESET enable_hashagg +-- +STMT: VariableSetStmt +== 616 +RESET enable_sort +-- +STMT: VariableSetStmt +== 617 +DROP INDEX jidx +-- +STMT: DropStmt +== 618 +DROP INDEX jidx_array +-- +STMT: DropStmt +== 619 +-- btree +CREATE INDEX jidx ON testjsonb USING btree (j) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +== 620 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 621 +SELECT count(*) FROM testjsonb WHERE j > '{"p":1}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 622 +SELECT count(*) FROM testjsonb WHERE j = '{"pos":98, "line":371, "node":"CBA", "indexed":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 623 +--gin path opclass +DROP INDEX jidx +-- +STMT: DropStmt +== 624 +CREATE INDEX jidx ON testjsonb USING gin (j jsonb_path_ops) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +== 625 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 626 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 627 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 628 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 629 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 630 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 631 +-- exercise GIN_SEARCH_MODE_ALL +SELECT count(*) FROM testjsonb WHERE j @> '{}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 632 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 633 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 634 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 635 +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 636 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 637 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 638 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 639 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 640 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 641 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 642 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 643 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 644 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 645 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +== 646 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 647 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 648 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 649 +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 650 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 651 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 652 +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 653 +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 654 +SELECT count(*) FROM testjsonb WHERE j @? '$' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 655 +SELECT count(*) FROM testjsonb WHERE j @? '$.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 656 +SELECT count(*) FROM testjsonb WHERE j @? '$.bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 657 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 658 +DROP INDEX jidx +-- +STMT: DropStmt +== 659 +-- nested tests +SELECT '{"ff":{"a":12,"b":16}}'::jsonb +-- +STMT: SelectStmt +== 660 +SELECT '{"ff":{"a":12,"b":16},"qq":123}'::jsonb +-- +STMT: SelectStmt +== 661 +SELECT '{"aa":["a","aaa"],"qq":{"a":12,"b":16,"c":["c1","c2"],"d":{"d1":"d1","d2":"d2","d1":"d3"}}}'::jsonb +-- +STMT: SelectStmt +== 662 +SELECT '{"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2"],"d":{"d1":"d1","d2":"d2"}}}'::jsonb +-- +STMT: SelectStmt +== 663 +SELECT '{"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2",["c3"],{"c4":4}],"d":{"d1":"d1","d2":"d2"}}}'::jsonb +-- +STMT: SelectStmt +== 664 +SELECT '{"ff":["a","aaa"]}'::jsonb +-- +STMT: SelectStmt +== 665 +SELECT + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'ff', + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'qq', + ('{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'Y') IS NULL AS f, + ('{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb ->> 'Y') IS NULL AS t, + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'x' +-- +STMT: SelectStmt +== 666 +-- nested containment +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +== 667 +SELECT '{"a":[2,1],"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +== 668 +SELECT '{"a":{"1":2},"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +== 669 +SELECT '{"a":{"2":1},"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +== 670 +SELECT '{"a":{"1":2},"c":"b"}'::jsonb @> '{"a":{"1":2}}' +-- +STMT: SelectStmt +== 671 +SELECT '{"a":{"2":1},"c":"b"}'::jsonb @> '{"a":{"1":2}}' +-- +STMT: SelectStmt +== 672 +SELECT '["a","b"]'::jsonb @> '["a","b","c","b"]' +-- +STMT: SelectStmt +== 673 +SELECT '["a","b","c","b"]'::jsonb @> '["a","b"]' +-- +STMT: SelectStmt +== 674 +SELECT '["a","b","c",[1,2]]'::jsonb @> '["a",[1,2]]' +-- +STMT: SelectStmt +== 675 +SELECT '["a","b","c",[1,2]]'::jsonb @> '["b",[1,2]]' +-- +STMT: SelectStmt +== 676 +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[1]}' +-- +STMT: SelectStmt +== 677 +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[2]}' +-- +STMT: SelectStmt +== 678 +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[3]}' +-- +STMT: SelectStmt +== 679 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"c":3}]}' +-- +STMT: SelectStmt +== 680 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4}]}' +-- +STMT: SelectStmt +== 681 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},3]}' +-- +STMT: SelectStmt +== 682 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},1]}' +-- +STMT: SelectStmt +== 683 +-- check some corner cases for indexed nested containment (bug #13756) +create temp table nestjsonb (j jsonb) +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DDL +STMT: CreateStmt +== 684 +insert into nestjsonb (j) values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}') +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 685 +insert into nestjsonb (j) values ('[[14,2,3]]') +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 686 +insert into nestjsonb (j) values ('[1,[14,2,3]]') +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 687 +create index on nestjsonb using gin(j jsonb_path_ops) +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DDL +STMT: IndexStmt +== 688 +set enable_seqscan = on +-- +STMT: VariableSetStmt +== 689 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +== 690 +select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 691 +select * from nestjsonb where j @> '{"c":3}' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 692 +select * from nestjsonb where j @> '[[14]]' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 693 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 694 +set enable_bitmapscan = on +-- +STMT: VariableSetStmt +== 695 +select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 696 +select * from nestjsonb where j @> '{"c":3}' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 697 +select * from nestjsonb where j @> '[[14]]' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 698 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 699 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 700 +-- nested object field / array index lookup +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'n' +-- +STMT: SelectStmt +== 701 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'a' +-- +STMT: SelectStmt +== 702 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'b' +-- +STMT: SelectStmt +== 703 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'c' +-- +STMT: SelectStmt +== 704 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'd' +-- +STMT: SelectStmt +== 705 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'd' -> '1' +-- +STMT: SelectStmt +== 706 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'e' +-- +STMT: SelectStmt +== 707 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 0 +-- +STMT: SelectStmt +== 708 +--expecting error + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 0 +-- +STMT: SelectStmt +== 709 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 1 +-- +STMT: SelectStmt +== 710 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 2 +-- +STMT: SelectStmt +== 711 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 3 +-- +STMT: SelectStmt +== 712 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 3 -> 1 +-- +STMT: SelectStmt +== 713 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 4 +-- +STMT: SelectStmt +== 714 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 5 +-- +STMT: SelectStmt +== 715 +SELECT '["a","b","c",[1,2],null]'::jsonb -> -1 +-- +STMT: SelectStmt +== 716 +SELECT '["a","b","c",[1,2],null]'::jsonb -> -5 +-- +STMT: SelectStmt +== 717 +SELECT '["a","b","c",[1,2],null]'::jsonb -> -6 +-- +STMT: SelectStmt +== 718 +--nested path extraction +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{0}' +-- +STMT: SelectStmt +== 719 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{a}' +-- +STMT: SelectStmt +== 720 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c}' +-- +STMT: SelectStmt +== 721 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,0}' +-- +STMT: SelectStmt +== 722 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,1}' +-- +STMT: SelectStmt +== 723 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,2}' +-- +STMT: SelectStmt +== 724 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,3}' +-- +STMT: SelectStmt +== 725 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-1}' +-- +STMT: SelectStmt +== 726 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-3}' +-- +STMT: SelectStmt +== 727 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-4}' +-- +STMT: SelectStmt +== 728 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{0}' +-- +STMT: SelectStmt +== 729 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{3}' +-- +STMT: SelectStmt +== 730 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{4}' +-- +STMT: SelectStmt +== 731 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{4,5}' +-- +STMT: SelectStmt +== 732 +--nested exists +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'n' +-- +STMT: SelectStmt +== 733 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'a' +-- +STMT: SelectStmt +== 734 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'b' +-- +STMT: SelectStmt +== 735 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'c' +-- +STMT: SelectStmt +== 736 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'd' +-- +STMT: SelectStmt +== 737 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'e' +-- +STMT: SelectStmt +== 738 +-- jsonb_strip_nulls + +select jsonb_strip_nulls(null) +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 739 +select jsonb_strip_nulls('1') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 740 +select jsonb_strip_nulls('"a string"') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 741 +select jsonb_strip_nulls('null') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 742 +select jsonb_strip_nulls('[1,2,null,3,4]') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 743 +select jsonb_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 744 +select jsonb_strip_nulls('[1,{"a":1,"b":null,"c":2},3]') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 745 +-- an empty object is not null and should not be stripped +select jsonb_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +== 746 +select jsonb_pretty('{"a": "test", "b": [1, 2, 3], "c": "test3", "d":{"dd": "test4", "dd2":{"ddd": "test5"}}}') +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +STMT: SelectStmt +== 747 +select jsonb_pretty('[{"f1":1,"f2":null},2,null,[[{"x":true},6,7],8],3]') +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +STMT: SelectStmt +== 748 +select jsonb_pretty('{"a":["b", "c"], "d": {"e":"f"}}') +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +STMT: SelectStmt +== 749 +select jsonb_concat('{"d": "test", "a": [1, 2]}', '{"g": "test2", "c": {"c1":1, "c2":2}}') +-- +FUNCTION: name="jsonb_concat" function="jsonb_concat" schema="" ctx=Call +STMT: SelectStmt +== 750 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"cq":"l", "b":"g", "fg":false}' +-- +STMT: SelectStmt +== 751 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"aq":"l"}' +-- +STMT: SelectStmt +== 752 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"aa":"l"}' +-- +STMT: SelectStmt +== 753 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{}' +-- +STMT: SelectStmt +== 754 +select '["a", "b"]'::jsonb || '["c"]' +-- +STMT: SelectStmt +== 755 +select '["a", "b"]'::jsonb || '["c", "d"]' +-- +STMT: SelectStmt +== 756 +select '["c"]' || '["a", "b"]'::jsonb +-- +STMT: SelectStmt +== 757 +select '["a", "b"]'::jsonb || '"c"' +-- +STMT: SelectStmt +== 758 +select '"c"' || '["a", "b"]'::jsonb +-- +STMT: SelectStmt +== 759 +select '[]'::jsonb || '["a"]'::jsonb +-- +STMT: SelectStmt +== 760 +select '[]'::jsonb || '"a"'::jsonb +-- +STMT: SelectStmt +== 761 +select '"b"'::jsonb || '"a"'::jsonb +-- +STMT: SelectStmt +== 762 +select '{}'::jsonb || '{"a":"b"}'::jsonb +-- +STMT: SelectStmt +== 763 +select '[]'::jsonb || '{"a":"b"}'::jsonb +-- +STMT: SelectStmt +== 764 +select '{"a":"b"}'::jsonb || '[]'::jsonb +-- +STMT: SelectStmt +== 765 +select '"a"'::jsonb || '{"a":1}' +-- +STMT: SelectStmt +== 766 +select '{"a":1}' || '"a"'::jsonb +-- +STMT: SelectStmt +== 767 +select '[3]'::jsonb || '{}'::jsonb +-- +STMT: SelectStmt +== 768 +select '3'::jsonb || '[]'::jsonb +-- +STMT: SelectStmt +== 769 +select '3'::jsonb || '4'::jsonb +-- +STMT: SelectStmt +== 770 +select '3'::jsonb || '{}'::jsonb +-- +STMT: SelectStmt +== 771 +select '["a", "b"]'::jsonb || '{"c":1}' +-- +STMT: SelectStmt +== 772 +select '{"c": 1}'::jsonb || '["a", "b"]' +-- +STMT: SelectStmt +== 773 +select '{}'::jsonb || '{"cq":"l", "b":"g", "fg":false}' +-- +STMT: SelectStmt +== 774 +select pg_column_size('{}'::jsonb || '{}'::jsonb) = pg_column_size('{}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +== 775 +select pg_column_size('{"aa":1}'::jsonb || '{"b":2}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +== 776 +select pg_column_size('{"aa":1, "b":2}'::jsonb || '{}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +== 777 +select pg_column_size('{}'::jsonb || '{"aa":1, "b":2}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +== 778 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'a') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +== 779 +select jsonb_delete('{"a":null , "b":2, "c":3}'::jsonb, 'a') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +== 780 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'b') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +== 781 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'c') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +== 782 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'd') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +== 783 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'a' +-- +STMT: SelectStmt +== 784 +select '{"a":null , "b":2, "c":3}'::jsonb - 'a' +-- +STMT: SelectStmt +== 785 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'b' +-- +STMT: SelectStmt +== 786 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'c' +-- +STMT: SelectStmt +== 787 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'd' +-- +STMT: SelectStmt +== 788 +select pg_column_size('{"a":1 , "b":2, "c":3}'::jsonb - 'b') = pg_column_size('{"a":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +== 789 +select '["a","b","c"]'::jsonb - 3 +-- +STMT: SelectStmt +== 790 +select '["a","b","c"]'::jsonb - 2 +-- +STMT: SelectStmt +== 791 +select '["a","b","c"]'::jsonb - 1 +-- +STMT: SelectStmt +== 792 +select '["a","b","c"]'::jsonb - 0 +-- +STMT: SelectStmt +== 793 +select '["a","b","c"]'::jsonb - -1 +-- +STMT: SelectStmt +== 794 +select '["a","b","c"]'::jsonb - -2 +-- +STMT: SelectStmt +== 795 +select '["a","b","c"]'::jsonb - -3 +-- +STMT: SelectStmt +== 796 +select '["a","b","c"]'::jsonb - -4 +-- +STMT: SelectStmt +== 797 +select '{"a":1 , "b":2, "c":3}'::jsonb - '{b}'::text[] +-- +STMT: SelectStmt +== 798 +select '{"a":1 , "b":2, "c":3}'::jsonb - '{c,b}'::text[] +-- +STMT: SelectStmt +== 799 +select '{"a":1 , "b":2, "c":3}'::jsonb - '{}'::text[] +-- +STMT: SelectStmt +== 800 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 801 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 802 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,1,0}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 803 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 804 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 805 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 806 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,1,0}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 807 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 808 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '"test"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 809 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '{"f": "test"}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 810 +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{n}') +-- +FUNCTION: name="jsonb_delete_path" function="jsonb_delete_path" schema="" ctx=Call +STMT: SelectStmt +== 811 +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{b,-1}') +-- +FUNCTION: name="jsonb_delete_path" function="jsonb_delete_path" schema="" ctx=Call +STMT: SelectStmt +== 812 +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{d,1,0}') +-- +FUNCTION: name="jsonb_delete_path" function="jsonb_delete_path" schema="" ctx=Call +STMT: SelectStmt +== 813 +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{n}' +-- +STMT: SelectStmt +== 814 +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1}' +-- +STMT: SelectStmt +== 815 +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1e}' +-- +STMT: SelectStmt +== 816 +-- invalid array subscript +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{d,1,0}' +-- +STMT: SelectStmt +== 817 +-- empty structure and error conditions for delete and replace + +select '"a"'::jsonb - 'a' +-- +STMT: SelectStmt +== 818 +-- error +select '{}'::jsonb - 'a' +-- +STMT: SelectStmt +== 819 +select '[]'::jsonb - 'a' +-- +STMT: SelectStmt +== 820 +select '"a"'::jsonb - 1 +-- +STMT: SelectStmt +== 821 +-- error +select '{}'::jsonb - 1 +-- +STMT: SelectStmt +== 822 +-- error +select '[]'::jsonb - 1 +-- +STMT: SelectStmt +== 823 +select '"a"'::jsonb #- '{a}' +-- +STMT: SelectStmt +== 824 +-- error +select '{}'::jsonb #- '{a}' +-- +STMT: SelectStmt +== 825 +select '[]'::jsonb #- '{a}' +-- +STMT: SelectStmt +== 826 +select jsonb_set('"a"','{a}','"b"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 827 +--error +select jsonb_set('{}','{a}','"b"', false) +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 828 +select jsonb_set('[]','{1}','"b"', false) +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 829 +select jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0}','[2,3,4]', false) +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 830 +-- jsonb_set adding instead of replacing + +-- prepend to array +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{b,-33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 831 +-- append to array +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{b,33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 832 +-- check nesting levels addition +select jsonb_set('{"a":1,"b":[4,5,[0,1,2],6,7],"c":{"d":4}}','{b,2,33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 833 +-- add new key +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{c,e}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 834 +-- adding doesn't do anything if elements before last aren't present +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{x,-33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 835 +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{x,y}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 836 +-- add to empty object +select jsonb_set('{}','{x}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 837 +--add to empty array +select jsonb_set('[]','{0}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 838 +select jsonb_set('[]','{99}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 839 +select jsonb_set('[]','{-99}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 840 +select jsonb_set('{"a": [1, 2, 3]}', '{a, non_integer}', '"new_value"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 841 +select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, non_integer}', '"new_value"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 842 +select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, NULL}', '"new_value"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +== 843 +-- jsonb_set_lax + + +-- pass though non nulls to jsonb_set +select jsonb_set_lax('{"a":1,"b":2}','{b}','5') +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 844 +select jsonb_set_lax('{"a":1,"b":2}','{d}','6', true) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 845 +-- using the default treatment +select jsonb_set_lax('{"a":1,"b":2}','{b}',null) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 846 +select jsonb_set_lax('{"a":1,"b":2}','{d}',null,true) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 847 +-- errors +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, true, null) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 848 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, true, 'no_such_treatment') +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 849 +-- explicit treatments +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'raise_exception') as raise_exception +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 850 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'return_target') as return_target +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 851 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'delete_key') as delete_key +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 852 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'use_json_null') as use_json_null +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +== 853 +-- jsonb_insert +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 854 +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 855 +select jsonb_insert('{"a": {"b": {"c": [0, 1, "test1", "test2"]}}}', '{a, b, c, 2}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 856 +select jsonb_insert('{"a": {"b": {"c": [0, 1, "test1", "test2"]}}}', '{a, b, c, 2}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 857 +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '{"b": "value"}') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 858 +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '["value1", "value2"]') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 859 +-- edge cases +select jsonb_insert('{"a": [0,1,2]}', '{a, 0}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 860 +select jsonb_insert('{"a": [0,1,2]}', '{a, 0}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 861 +select jsonb_insert('{"a": [0,1,2]}', '{a, 2}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 862 +select jsonb_insert('{"a": [0,1,2]}', '{a, 2}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 863 +select jsonb_insert('{"a": [0,1,2]}', '{a, -1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 864 +select jsonb_insert('{"a": [0,1,2]}', '{a, -1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 865 +select jsonb_insert('[]', '{1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 866 +select jsonb_insert('[]', '{1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 867 +select jsonb_insert('{"a": []}', '{a, 1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 868 +select jsonb_insert('{"a": []}', '{a, 1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 869 +select jsonb_insert('{"a": [0,1,2]}', '{a, 10}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 870 +select jsonb_insert('{"a": [0,1,2]}', '{a, -10}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 871 +-- jsonb_insert should be able to insert new value for objects, but not to replace +select jsonb_insert('{"a": {"b": "value"}}', '{a, c}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 872 +select jsonb_insert('{"a": {"b": "value"}}', '{a, c}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 873 +select jsonb_insert('{"a": {"b": "value"}}', '{a, b}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 874 +select jsonb_insert('{"a": {"b": "value"}}', '{a, b}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +== 875 +-- jsonb subscript +select ('123'::jsonb)['a'] +-- +STMT: SelectStmt +== 876 +select ('123'::jsonb)[0] +-- +STMT: SelectStmt +== 877 +select ('123'::jsonb)[NULL] +-- +STMT: SelectStmt +== 878 +select ('{"a": 1}'::jsonb)['a'] +-- +STMT: SelectStmt +== 879 +select ('{"a": 1}'::jsonb)[0] +-- +STMT: SelectStmt +== 880 +select ('{"a": 1}'::jsonb)['not_exist'] +-- +STMT: SelectStmt +== 881 +select ('{"a": 1}'::jsonb)[NULL] +-- +STMT: SelectStmt +== 882 +select ('[1, "2", null]'::jsonb)['a'] +-- +STMT: SelectStmt +== 883 +select ('[1, "2", null]'::jsonb)[0] +-- +STMT: SelectStmt +== 884 +select ('[1, "2", null]'::jsonb)['1'] +-- +STMT: SelectStmt +== 885 +select ('[1, "2", null]'::jsonb)[1.0] +-- +STMT: SelectStmt +== 886 +select ('[1, "2", null]'::jsonb)[2] +-- +STMT: SelectStmt +== 887 +select ('[1, "2", null]'::jsonb)[3] +-- +STMT: SelectStmt +== 888 +select ('[1, "2", null]'::jsonb)[-2] +-- +STMT: SelectStmt +== 889 +select ('[1, "2", null]'::jsonb)[1]['a'] +-- +STMT: SelectStmt +== 890 +select ('[1, "2", null]'::jsonb)[1][0] +-- +STMT: SelectStmt +== 891 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['b'] +-- +STMT: SelectStmt +== 892 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d'] +-- +STMT: SelectStmt +== 893 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d'][1] +-- +STMT: SelectStmt +== 894 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d']['a'] +-- +STMT: SelectStmt +== 895 +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1'] +-- +STMT: SelectStmt +== 896 +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1']['a2'] +-- +STMT: SelectStmt +== 897 +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1']['a2']['a3'] +-- +STMT: SelectStmt +== 898 +select ('{"a": ["a1", {"b1": ["aaa", "bbb", "ccc"]}], "b": "bb"}'::jsonb)['a'][1]['b1'] +-- +STMT: SelectStmt +== 899 +select ('{"a": ["a1", {"b1": ["aaa", "bbb", "ccc"]}], "b": "bb"}'::jsonb)['a'][1]['b1'][2] +-- +STMT: SelectStmt +== 900 +-- slices are not supported +select ('{"a": 1}'::jsonb)['a':'b'] +-- +STMT: SelectStmt +== 901 +select ('[1, "2", null]'::jsonb)[1:2] +-- +STMT: SelectStmt +== 902 +select ('[1, "2", null]'::jsonb)[:2] +-- +STMT: SelectStmt +== 903 +select ('[1, "2", null]'::jsonb)[1:] +-- +STMT: SelectStmt +== 904 +select ('[1, "2", null]'::jsonb)[:] +-- +STMT: SelectStmt +== 905 +create TEMP TABLE test_jsonb_subscript ( + id int, + test_json jsonb +) +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DDL +STMT: CreateStmt +== 906 +insert into test_jsonb_subscript values +(1, '{}'), -- empty jsonb +(2, '{"key": "value"}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 907 +-- jsonb with data + +-- update empty jsonb +update test_jsonb_subscript set test_json['a'] = '1' where id = 1 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 908 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 909 +-- update jsonb with some data +update test_jsonb_subscript set test_json['a'] = '1' where id = 2 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 910 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 911 +-- replace jsonb +update test_jsonb_subscript set test_json['a'] = '"test"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 912 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 913 +-- replace by object +update test_jsonb_subscript set test_json['a'] = '{"b": 1}'::jsonb +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 914 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 915 +-- replace by array +update test_jsonb_subscript set test_json['a'] = '[1, 2, 3]'::jsonb +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 916 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 917 +-- use jsonb subscription in where clause +select * from test_jsonb_subscript where test_json['key'] = '"value"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FILTER: schema="" table="" column="test_json" +STMT: SelectStmt +== 918 +select * from test_jsonb_subscript where test_json['key_doesnt_exists'] = '"value"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FILTER: schema="" table="" column="test_json" +STMT: SelectStmt +== 919 +select * from test_jsonb_subscript where test_json['key'] = '"wrong_value"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FILTER: schema="" table="" column="test_json" +STMT: SelectStmt +== 920 +-- NULL +update test_jsonb_subscript set test_json[NULL] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 921 +update test_jsonb_subscript set test_json['another_key'] = NULL +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 922 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 923 +-- NULL as jsonb source +insert into test_jsonb_subscript values (3, NULL) +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 924 +update test_jsonb_subscript set test_json['a'] = '1' where id = 3 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 925 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 926 +update test_jsonb_subscript set test_json = NULL where id = 3 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 927 +update test_jsonb_subscript set test_json[0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 928 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 929 +-- Fill the gaps logic +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 930 +insert into test_jsonb_subscript values (1, '[0]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 931 +update test_jsonb_subscript set test_json[5] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 932 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 933 +update test_jsonb_subscript set test_json[-4] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 934 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 935 +update test_jsonb_subscript set test_json[-8] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 936 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 937 +-- keep consistent values position +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 938 +insert into test_jsonb_subscript values (1, '[]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 939 +update test_jsonb_subscript set test_json[5] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 940 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 941 +-- create the whole path +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 942 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 943 +update test_jsonb_subscript set test_json['a'][0]['b'][0]['c'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 944 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 945 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 946 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 947 +update test_jsonb_subscript set test_json['a'][2]['b'][2]['c'][2] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 948 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 949 +-- create the whole path with already existing keys +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 950 +insert into test_jsonb_subscript values (1, '{"b": 1}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 951 +update test_jsonb_subscript set test_json['a'][0] = '2' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 952 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 953 +-- the start jsonb is an object, first subscript is treated as a key +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 954 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 955 +update test_jsonb_subscript set test_json[0]['a'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 956 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 957 +-- the start jsonb is an array +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 958 +insert into test_jsonb_subscript values (1, '[]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 959 +update test_jsonb_subscript set test_json[0]['a'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 960 +update test_jsonb_subscript set test_json[2]['b'] = '2' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 961 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 962 +-- overwriting an existing path +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 963 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 964 +update test_jsonb_subscript set test_json['a']['b'][1] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 965 +update test_jsonb_subscript set test_json['a']['b'][10] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 966 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 967 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 968 +insert into test_jsonb_subscript values (1, '[]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 969 +update test_jsonb_subscript set test_json[0][0][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 970 +update test_jsonb_subscript set test_json[0][0][1] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 971 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 972 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 973 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 974 +update test_jsonb_subscript set test_json['a']['b'][10] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 975 +update test_jsonb_subscript set test_json['a'][10][10] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 976 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 977 +-- an empty sub element + +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 978 +insert into test_jsonb_subscript values (1, '{"a": {}}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 979 +update test_jsonb_subscript set test_json['a']['b']['c'][2] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 980 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 981 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 982 +insert into test_jsonb_subscript values (1, '{"a": []}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 983 +update test_jsonb_subscript set test_json['a'][1]['c'][2] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 984 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 985 +-- trying replace assuming a composite object, but it's an element or a value + +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 986 +insert into test_jsonb_subscript values (1, '{"a": 1}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 987 +update test_jsonb_subscript set test_json['a']['b'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 988 +update test_jsonb_subscript set test_json['a']['b']['c'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 989 +update test_jsonb_subscript set test_json['a'][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 990 +update test_jsonb_subscript set test_json['a'][0]['c'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 991 +update test_jsonb_subscript set test_json['a'][0][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 992 +-- trying replace assuming a composite object, but it's a raw scalar + +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +== 993 +insert into test_jsonb_subscript values (1, 'null') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 994 +update test_jsonb_subscript set test_json[0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 995 +update test_jsonb_subscript set test_json[0][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 996 +-- try some things with short-header and toasted subscript values + +drop table test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DDL +STMT: DropStmt +== 997 +create temp table test_jsonb_subscript ( + id text, + test_json jsonb +) +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DDL +STMT: CreateStmt +== 998 +insert into test_jsonb_subscript values('foo', '{"foo": "bar"}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 999 +insert into test_jsonb_subscript + select s, ('{"' || s || '": "bar"}')::jsonb from repeat('xyzzy', 500) s +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 1000 +select length(id), test_json[id] from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 1001 +update test_jsonb_subscript set test_json[id] = '"baz"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +== 1002 +select length(id), test_json[id] from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 1003 +table test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +== 1004 +-- jsonb to tsvector +select to_tsvector('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1005 +-- jsonb to tsvector with config +select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1006 +-- jsonb to tsvector with stop words +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1007 +-- jsonb to tsvector with numeric values +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1008 +-- jsonb_to_tsvector +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1009 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1010 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1011 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1012 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1013 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1014 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1015 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1016 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1017 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1018 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1019 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1020 +-- to_tsvector corner cases +select to_tsvector('""'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1021 +select to_tsvector('{}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1022 +select to_tsvector('[]'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1023 +select to_tsvector('null'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1024 +-- jsonb_to_tsvector corner cases +select jsonb_to_tsvector('""'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1025 +select jsonb_to_tsvector('{}'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1026 +select jsonb_to_tsvector('[]'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1027 +select jsonb_to_tsvector('null'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1028 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '""') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1029 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '{}') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1030 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '[]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1031 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, 'null') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1032 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["all", null]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 1033 +-- ts_headline for jsonb +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 1034 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 1035 +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 1036 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 1037 +-- corner cases for ts_headline with jsonb +select ts_headline('null'::jsonb, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 1038 +select ts_headline('{}'::jsonb, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 1039 +select ts_headline('[]'::jsonb, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +== 1040 +-- casts +select 'true'::jsonb::bool +-- +STMT: SelectStmt +== 1041 +select '[]'::jsonb::bool +-- +STMT: SelectStmt +== 1042 +select '1.0'::jsonb::float +-- +STMT: SelectStmt +== 1043 +select '[1.0]'::jsonb::float +-- +STMT: SelectStmt +== 1044 +select '12345'::jsonb::int4 +-- +STMT: SelectStmt +== 1045 +select '"hello"'::jsonb::int4 +-- +STMT: SelectStmt +== 1046 +select '12345'::jsonb::numeric +-- +STMT: SelectStmt +== 1047 +select '{}'::jsonb::numeric +-- +STMT: SelectStmt +== 1048 +select '12345.05'::jsonb::numeric +-- +STMT: SelectStmt +== 1049 +select '12345.05'::jsonb::float4 +-- +STMT: SelectStmt +== 1050 +select '12345.05'::jsonb::float8 +-- +STMT: SelectStmt +== 1051 +select '12345.05'::jsonb::int2 +-- +STMT: SelectStmt +== 1052 +select '12345.05'::jsonb::int4 +-- +STMT: SelectStmt +== 1053 +select '12345.05'::jsonb::int8 +-- +STMT: SelectStmt +== 1054 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::numeric +-- +STMT: SelectStmt +== 1055 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::float4 +-- +STMT: SelectStmt +== 1056 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::float8 +-- +STMT: SelectStmt +== 1057 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int2 +-- +STMT: SelectStmt +== 1058 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int4 +-- +STMT: SelectStmt +== 1059 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int8 +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json b/parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json new file mode 100644 index 0000000..b53b6f2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json @@ -0,0 +1,825 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821" + ] +} diff --git a/parser/testdata/summary/postgres_regress/jsonb_jsonpath.test b/parser/testdata/summary/postgres_regress/jsonb_jsonpath.test new file mode 100644 index 0000000..52d6fb1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonb_jsonpath.test @@ -0,0 +1,4255 @@ +== 001 +select jsonb '{"a": 12}' @? '$' +-- +STMT: SelectStmt +== 002 +select jsonb '{"a": 12}' @? '1' +-- +STMT: SelectStmt +== 003 +select jsonb '{"a": 12}' @? '$.a.b' +-- +STMT: SelectStmt +== 004 +select jsonb '{"a": 12}' @? '$.b' +-- +STMT: SelectStmt +== 005 +select jsonb '{"a": 12}' @? '$.a + 2' +-- +STMT: SelectStmt +== 006 +select jsonb '{"a": 12}' @? '$.b + 2' +-- +STMT: SelectStmt +== 007 +select jsonb '{"a": {"a": 12}}' @? '$.a.a' +-- +STMT: SelectStmt +== 008 +select jsonb '{"a": {"a": 12}}' @? '$.*.a' +-- +STMT: SelectStmt +== 009 +select jsonb '{"b": {"a": 12}}' @? '$.*.a' +-- +STMT: SelectStmt +== 010 +select jsonb '{"b": {"a": 12}}' @? '$.*.b' +-- +STMT: SelectStmt +== 011 +select jsonb '{"b": {"a": 12}}' @? 'strict $.*.b' +-- +STMT: SelectStmt +== 012 +select jsonb '{}' @? '$.*' +-- +STMT: SelectStmt +== 013 +select jsonb '{"a": 1}' @? '$.*' +-- +STMT: SelectStmt +== 014 +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{1}' +-- +STMT: SelectStmt +== 015 +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{2}' +-- +STMT: SelectStmt +== 016 +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{3}' +-- +STMT: SelectStmt +== 017 +select jsonb '[]' @? '$[*]' +-- +STMT: SelectStmt +== 018 +select jsonb '[1]' @? '$[*]' +-- +STMT: SelectStmt +== 019 +select jsonb '[1]' @? '$[1]' +-- +STMT: SelectStmt +== 020 +select jsonb '[1]' @? 'strict $[1]' +-- +STMT: SelectStmt +== 021 +select jsonb_path_query('[1]', 'strict $[1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 022 +select jsonb_path_query('[1]', 'strict $[1]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 023 +select jsonb '[1]' @? 'lax $[10000000000000000]' +-- +STMT: SelectStmt +== 024 +select jsonb '[1]' @? 'strict $[10000000000000000]' +-- +STMT: SelectStmt +== 025 +select jsonb_path_query('[1]', 'lax $[10000000000000000]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 026 +select jsonb_path_query('[1]', 'strict $[10000000000000000]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 027 +select jsonb '[1]' @? '$[0]' +-- +STMT: SelectStmt +== 028 +select jsonb '[1]' @? '$[0.3]' +-- +STMT: SelectStmt +== 029 +select jsonb '[1]' @? '$[0.5]' +-- +STMT: SelectStmt +== 030 +select jsonb '[1]' @? '$[0.9]' +-- +STMT: SelectStmt +== 031 +select jsonb '[1]' @? '$[1.2]' +-- +STMT: SelectStmt +== 032 +select jsonb '[1]' @? 'strict $[1.2]' +-- +STMT: SelectStmt +== 033 +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] > @.b[*])' +-- +STMT: SelectStmt +== 034 +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +== 035 +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? '$ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +== 036 +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? 'strict $ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +== 037 +select jsonb '{"a": [1,2,3], "b": [3,4,null]}' @? '$ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +== 038 +select jsonb '1' @? '$ ? ((@ == "1") is unknown)' +-- +STMT: SelectStmt +== 039 +select jsonb '1' @? '$ ? ((@ == 1) is unknown)' +-- +STMT: SelectStmt +== 040 +select jsonb '[{"a": 1}, {"a": 2}]' @? '$[0 to 1] ? (@.a > 1)' +-- +STMT: SelectStmt +== 041 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => false) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 042 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 043 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => false) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 044 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 045 +select jsonb_path_query('1', 'lax $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 046 +select jsonb_path_query('1', 'strict $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 047 +select jsonb_path_query('1', 'strict $.*') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 048 +select jsonb_path_query('1', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 049 +select jsonb_path_query('1', 'strict $.*', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 050 +select jsonb_path_query('[]', 'lax $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 051 +select jsonb_path_query('[]', 'strict $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 052 +select jsonb_path_query('[]', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 053 +select jsonb_path_query('{}', 'lax $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 054 +select jsonb_path_query('{}', 'strict $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 055 +select jsonb_path_query('{}', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 056 +select jsonb_path_query('1', 'strict $[1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 057 +select jsonb_path_query('1', 'strict $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 058 +select jsonb_path_query('[]', 'strict $[1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 059 +select jsonb_path_query('[]', 'strict $["a"]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 060 +select jsonb_path_query('1', 'strict $[1]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 061 +select jsonb_path_query('1', 'strict $[*]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 062 +select jsonb_path_query('[]', 'strict $[1]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 063 +select jsonb_path_query('[]', 'strict $["a"]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 064 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 065 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.b') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 066 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.*') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 067 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', 'lax $.*.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 068 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 069 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].*') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 070 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 071 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[1].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 072 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[2].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 073 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0,1].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 074 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 075 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10 / 0].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 076 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}, "ccc", true]', '$[2.5 - 1 to $.size() - 2]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 077 +select jsonb_path_query('1', 'lax $[0]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 078 +select jsonb_path_query('1', 'lax $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 079 +select jsonb_path_query('[1]', 'lax $[0]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 080 +select jsonb_path_query('[1]', 'lax $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 081 +select jsonb_path_query('[1,2,3]', 'lax $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 082 +select jsonb_path_query('[1,2,3]', 'strict $[*].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 083 +select jsonb_path_query('[1,2,3]', 'strict $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 084 +select jsonb_path_query('[]', '$[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 085 +select jsonb_path_query('[]', '$[last ? (exists(last))]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 086 +select jsonb_path_query('[]', 'strict $[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 087 +select jsonb_path_query('[]', 'strict $[last]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 088 +select jsonb_path_query('[1]', '$[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 089 +select jsonb_path_query('[1,2,3]', '$[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 090 +select jsonb_path_query('[1,2,3]', '$[last - 1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 091 +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "number")]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 092 +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 093 +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 094 +select * from jsonb_path_query('{"a": 10}', '$') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 095 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 096 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 097 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '[{"value" : 13}]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 098 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 13}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 099 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 8}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 100 +select * from jsonb_path_query('{"a": 10}', '$.a ? (@ < $value)', '{"value" : 13}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 101 +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[*] ? (@ < $value)', '{"value" : 13}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 102 +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0,1] ? (@ < $x.value)', '{"x": {"value" : 13}}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 103 +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0 to 2] ? (@ < $value)', '{"value" : 15}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 104 +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == "1")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 105 +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : "1"}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 106 +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : null}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 107 +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ != null)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 108 +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ == null)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 109 +select * from jsonb_path_query('{}', '$ ? (@ == @)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 110 +select * from jsonb_path_query('[]', 'strict $ ? (@ == @)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 111 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 112 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 113 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 114 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 115 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 116 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 117 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 118 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{3 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 119 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 120 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 121 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 122 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 123 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 124 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 125 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to 2}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 126 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 127 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 128 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 129 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 130 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 131 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to 2}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 132 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{2 to 3}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 133 +select jsonb '{"a": {"b": 1}}' @? '$.**.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 134 +select jsonb '{"a": {"b": 1}}' @? '$.**{0}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 135 +select jsonb '{"a": {"b": 1}}' @? '$.**{1}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 136 +select jsonb '{"a": {"b": 1}}' @? '$.**{0 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 137 +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 138 +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to 2}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 139 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 140 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 141 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 142 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 143 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 144 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to 2}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 145 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2 to 3}.b ? ( @ > 0)' +-- +STMT: SelectStmt +== 146 +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 147 +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.y))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 148 +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x ? (@ >= 2) ))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 149 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 150 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x + "3"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 151 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? ((exists (@.x + "3")) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 152 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? (exists (@.x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 153 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? ((exists (@.x)) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 154 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? (exists (@[*].x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 155 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? ((exists (@[*].x)) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 156 +--test ternary logic +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true && $y == true) || + @ == false && !($x == true && $y == true) || + @ == null && ($x == true && $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x && y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 157 +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true || $y == true) || + @ == false && !($x == true || $y == true) || + @ == null && ($x == true || $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x || y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +== 158 +select jsonb '{"a": 1, "b":1}' @? '$ ? (@.a == @.b)' +-- +STMT: SelectStmt +== 159 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$ ? (@.a == @.b)' +-- +STMT: SelectStmt +== 160 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? (@.a == @.b)' +-- +STMT: SelectStmt +== 161 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? ($.c.a == @.b)' +-- +STMT: SelectStmt +== 162 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.* ? (@.a == @.b)' +-- +STMT: SelectStmt +== 163 +select jsonb '{"a": 1, "b":1}' @? '$.** ? (@.a == @.b)' +-- +STMT: SelectStmt +== 164 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.** ? (@.a == @.b)' +-- +STMT: SelectStmt +== 165 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == 1 + 1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 166 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (1 + 1))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 167 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == @.b + 1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 168 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (@.b + 1))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 169 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - 1)' +-- +STMT: SelectStmt +== 170 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -1)' +-- +STMT: SelectStmt +== 171 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -@.b)' +-- +STMT: SelectStmt +== 172 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - @.b)' +-- +STMT: SelectStmt +== 173 +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - @.b)' +-- +STMT: SelectStmt +== 174 +select jsonb '{"c": {"a": 2, "b":1}}' @? '$.** ? (@.a == 1 - - @.b)' +-- +STMT: SelectStmt +== 175 +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - +@.b)' +-- +STMT: SelectStmt +== 176 +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +2)' +-- +STMT: SelectStmt +== 177 +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +3)' +-- +STMT: SelectStmt +== 178 +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -2)' +-- +STMT: SelectStmt +== 179 +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -3)' +-- +STMT: SelectStmt +== 180 +select jsonb '1' @? '$ ? ($ > 0)' +-- +STMT: SelectStmt +== 181 +-- arithmetic errors +select jsonb_path_query('[1,2,0,3]', '$[*] ? (2 / @ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 182 +select jsonb_path_query('[1,2,0,3]', '$[*] ? ((2 / @ > 0) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 183 +select jsonb_path_query('0', '1 / $') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 184 +select jsonb_path_query('0', '1 / $ + 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 185 +select jsonb_path_query('0', '-(3 + 1 % $)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 186 +select jsonb_path_query('1', '$ + "2"') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 187 +select jsonb_path_query('[1, 2]', '3 * $') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 188 +select jsonb_path_query('"a"', '-$') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 189 +select jsonb_path_query('[1,"2",3]', '+$') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 190 +select jsonb_path_query('1', '$ + "2"', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 191 +select jsonb_path_query('[1, 2]', '3 * $', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 192 +select jsonb_path_query('"a"', '-$', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 193 +select jsonb_path_query('[1,"2",3]', '+$', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 194 +select jsonb '["1",2,0,3]' @? '-$[*]' +-- +STMT: SelectStmt +== 195 +select jsonb '[1,"2",0,3]' @? '-$[*]' +-- +STMT: SelectStmt +== 196 +select jsonb '["1",2,0,3]' @? 'strict -$[*]' +-- +STMT: SelectStmt +== 197 +select jsonb '[1,"2",0,3]' @? 'strict -$[*]' +-- +STMT: SelectStmt +== 198 +-- unwrapping of operator arguments in lax mode +select jsonb_path_query('{"a": [2]}', 'lax $.a * 3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 199 +select jsonb_path_query('{"a": [2]}', 'lax $.a + 3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 200 +select jsonb_path_query('{"a": [2, 3, 4]}', 'lax -$.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 201 +-- should fail +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 202 +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 203 +-- extension: boolean expressions +select jsonb_path_query('2', '$ > 1') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 204 +select jsonb_path_query('2', '$ <= 1') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 205 +select jsonb_path_query('2', '$ == "2"') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 206 +select jsonb '2' @? '$ == "2"' +-- +STMT: SelectStmt +== 207 +select jsonb '2' @@ '$ > 1' +-- +STMT: SelectStmt +== 208 +select jsonb '2' @@ '$ <= 1' +-- +STMT: SelectStmt +== 209 +select jsonb '2' @@ '$ == "2"' +-- +STMT: SelectStmt +== 210 +select jsonb '2' @@ '1' +-- +STMT: SelectStmt +== 211 +select jsonb '{}' @@ '$' +-- +STMT: SelectStmt +== 212 +select jsonb '[]' @@ '$' +-- +STMT: SelectStmt +== 213 +select jsonb '[1,2,3]' @@ '$[*]' +-- +STMT: SelectStmt +== 214 +select jsonb '[]' @@ '$[*]' +-- +STMT: SelectStmt +== 215 +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 216 +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 217 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 218 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 219 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 220 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 221 +select jsonb_path_query('[null,1,true,"a",[],{}]', '$.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 222 +select jsonb_path_query('[null,1,true,"a",[],{}]', 'lax $.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 223 +select jsonb_path_query('[null,1,true,"a",[],{}]', '$[*].type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 224 +select jsonb_path_query('null', 'null.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 225 +select jsonb_path_query('null', 'true.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 226 +select jsonb_path_query('null', '(123).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 227 +select jsonb_path_query('null', '"123".type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 228 +select jsonb_path_query('{"a": 2}', '($.a - 5).abs() + 10') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 229 +select jsonb_path_query('{"a": 2.5}', '-($.a * $.a).floor() % 4.3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 230 +select jsonb_path_query('[1, 2, 3]', '($[*] > 2) ? (@ == true)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 231 +select jsonb_path_query('[1, 2, 3]', '($[*] > 3).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 232 +select jsonb_path_query('[1, 2, 3]', '($[*].a > 3).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 233 +select jsonb_path_query('[1, 2, 3]', 'strict ($[*].a > 3).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 234 +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 235 +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 236 +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'lax $[*].size()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 237 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].abs()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 238 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].floor()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 239 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 240 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 241 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 242 +select jsonb_path_query('[{},1]', '$[*].keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 243 +select jsonb_path_query('[{},1]', '$[*].keyvalue()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 244 +select jsonb_path_query('{}', '$.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 245 +select jsonb_path_query('{"a": 1, "b": [1, 2], "c": {"a": "bbb"}}', '$.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 246 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', '$[*].keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 247 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 248 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'lax $.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 249 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue().a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 250 +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue()' +-- +STMT: SelectStmt +== 251 +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue().key' +-- +STMT: SelectStmt +== 252 +select jsonb_path_query('null', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 253 +select jsonb_path_query('true', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 254 +select jsonb_path_query('null', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 255 +select jsonb_path_query('true', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 256 +select jsonb_path_query('[]', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 257 +select jsonb_path_query('[]', 'strict $.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 258 +select jsonb_path_query('{}', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 259 +select jsonb_path_query('[]', 'strict $.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 260 +select jsonb_path_query('{}', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 261 +select jsonb_path_query('1.23', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 262 +select jsonb_path_query('"1.23"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 263 +select jsonb_path_query('"1.23aaa"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 264 +select jsonb_path_query('1e1000', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 265 +select jsonb_path_query('"nan"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 266 +select jsonb_path_query('"NaN"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 267 +select jsonb_path_query('"inf"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 268 +select jsonb_path_query('"-inf"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 269 +select jsonb_path_query('"inf"', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 270 +select jsonb_path_query('"-inf"', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 271 +select jsonb_path_query('{}', '$.abs()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 272 +select jsonb_path_query('true', '$.floor()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 273 +select jsonb_path_query('"1.2"', '$.ceiling()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 274 +select jsonb_path_query('{}', '$.abs()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 275 +select jsonb_path_query('true', '$.floor()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 276 +select jsonb_path_query('"1.2"', '$.ceiling()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 277 +select jsonb_path_query('["", "a", "abc", "abcabc"]', '$[*] ? (@ starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 278 +select jsonb_path_query('["", "a", "abc", "abcabc"]', 'strict $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 279 +select jsonb_path_query('["", "a", "abd", "abdabc"]', 'strict $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 280 +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 281 +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? ((@[*] starts with "abc") is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 282 +select jsonb_path_query('[[null, 1, "abc", "abcabc"]]', 'lax $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 283 +select jsonb_path_query('[[null, 1, "abd", "abdabc"]]', 'lax $ ? ((@[*] starts with "abc") is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 284 +select jsonb_path_query('[null, 1, "abd", "abdabc"]', 'lax $[*] ? ((@ starts with "abc") is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 285 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 286 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "i")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 287 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "m")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 288 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "s")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 289 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 290 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 291 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 292 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 293 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 294 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 295 +select jsonb_path_query('null', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 296 +select jsonb_path_query('true', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 297 +select jsonb_path_query('1', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 298 +select jsonb_path_query('[]', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 299 +select jsonb_path_query('[]', 'strict $.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 300 +select jsonb_path_query('{}', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 301 +select jsonb_path_query('"bogus"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 302 +select jsonb_path_query('"12:34"', '$.datetime("aaa")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 303 +select jsonb_path_query('"aaaa"', '$.datetime("HH24")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 304 +select jsonb '"10-03-2017"' @? '$.datetime("dd-mm-yyyy")' +-- +STMT: SelectStmt +== 305 +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 306 +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 307 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 308 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 309 +select jsonb_path_query('"10-03-2017 12:34"', ' $.datetime("dd-mm-yyyy HH24:MI").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 310 +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 311 +select jsonb_path_query('"12:34:56"', '$.datetime("HH24:MI:SS").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 312 +select jsonb_path_query('"12:34:56 +05:20"', '$.datetime("HH24:MI:SS TZH:TZM").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 313 +select jsonb_path_query('"10-03-2017T12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 314 +select jsonb_path_query('"10-03-2017t12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 315 +select jsonb_path_query('"10-03-2017 12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 316 +-- Test .bigint() +select jsonb_path_query('null', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 317 +select jsonb_path_query('true', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 318 +select jsonb_path_query('null', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 319 +select jsonb_path_query('true', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 320 +select jsonb_path_query('[]', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 321 +select jsonb_path_query('[]', 'strict $.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 322 +select jsonb_path_query('{}', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 323 +select jsonb_path_query('[]', 'strict $.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 324 +select jsonb_path_query('{}', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 325 +select jsonb_path_query('"1.23"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 326 +select jsonb_path_query('"1.23aaa"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 327 +select jsonb_path_query('1e1000', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 328 +select jsonb_path_query('"nan"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 329 +select jsonb_path_query('"NaN"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 330 +select jsonb_path_query('"inf"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 331 +select jsonb_path_query('"-inf"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 332 +select jsonb_path_query('"inf"', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 333 +select jsonb_path_query('"-inf"', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 334 +select jsonb_path_query('123', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 335 +select jsonb_path_query('"123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 336 +select jsonb_path_query('1.23', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 337 +select jsonb_path_query('1.83', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 338 +select jsonb_path_query('1234567890123', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 339 +select jsonb_path_query('"1234567890123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 340 +select jsonb_path_query('12345678901234567890', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 341 +select jsonb_path_query('"12345678901234567890"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 342 +select jsonb_path_query('"+123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 343 +select jsonb_path_query('-123', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 344 +select jsonb_path_query('"-123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 345 +select jsonb_path_query('123', '$.bigint() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 346 +-- Test .boolean() +select jsonb_path_query('null', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 347 +select jsonb_path_query('null', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 348 +select jsonb_path_query('[]', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 349 +select jsonb_path_query('[]', 'strict $.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 350 +select jsonb_path_query('{}', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 351 +select jsonb_path_query('[]', 'strict $.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 352 +select jsonb_path_query('{}', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 353 +select jsonb_path_query('1.23', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 354 +select jsonb_path_query('"1.23"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 355 +select jsonb_path_query('"1.23aaa"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 356 +select jsonb_path_query('1e1000', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 357 +select jsonb_path_query('"nan"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 358 +select jsonb_path_query('"NaN"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 359 +select jsonb_path_query('"inf"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 360 +select jsonb_path_query('"-inf"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 361 +select jsonb_path_query('"inf"', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 362 +select jsonb_path_query('"-inf"', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 363 +select jsonb_path_query('"100"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 364 +select jsonb_path_query('true', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 365 +select jsonb_path_query('false', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 366 +select jsonb_path_query('1', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 367 +select jsonb_path_query('0', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 368 +select jsonb_path_query('-1', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 369 +select jsonb_path_query('100', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 370 +select jsonb_path_query('"1"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 371 +select jsonb_path_query('"0"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 372 +select jsonb_path_query('"true"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 373 +select jsonb_path_query('"false"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 374 +select jsonb_path_query('"TRUE"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 375 +select jsonb_path_query('"FALSE"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 376 +select jsonb_path_query('"yes"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 377 +select jsonb_path_query('"NO"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 378 +select jsonb_path_query('"T"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 379 +select jsonb_path_query('"f"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 380 +select jsonb_path_query('"y"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 381 +select jsonb_path_query('"N"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 382 +select jsonb_path_query('true', '$.boolean().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 383 +select jsonb_path_query('123', '$.boolean().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 384 +select jsonb_path_query('"Yes"', '$.boolean().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 385 +select jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 386 +-- Test .date() +select jsonb_path_query('null', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 387 +select jsonb_path_query('true', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 388 +select jsonb_path_query('1', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 389 +select jsonb_path_query('[]', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 390 +select jsonb_path_query('[]', 'strict $.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 391 +select jsonb_path_query('{}', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 392 +select jsonb_path_query('"bogus"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 393 +select jsonb '"2023-08-15"' @? '$.date()' +-- +STMT: SelectStmt +== 394 +select jsonb_path_query('"2023-08-15"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 395 +select jsonb_path_query('"2023-08-15"', '$.date().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 396 +select jsonb_path_query('"12:34:56"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 397 +select jsonb_path_query('"12:34:56 +05:30"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 398 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 399 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 400 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.date()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 401 +-- should work + +select jsonb_path_query('"2023-08-15"', '$.date(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 402 +-- Test .decimal() +select jsonb_path_query('null', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 403 +select jsonb_path_query('true', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 404 +select jsonb_path_query('null', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 405 +select jsonb_path_query('true', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 406 +select jsonb_path_query('[]', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 407 +select jsonb_path_query('[]', 'strict $.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 408 +select jsonb_path_query('{}', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 409 +select jsonb_path_query('[]', 'strict $.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 410 +select jsonb_path_query('{}', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 411 +select jsonb_path_query('1.23', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 412 +select jsonb_path_query('"1.23"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 413 +select jsonb_path_query('"1.23aaa"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 414 +select jsonb_path_query('1e1000', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 415 +select jsonb_path_query('"nan"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 416 +select jsonb_path_query('"NaN"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 417 +select jsonb_path_query('"inf"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 418 +select jsonb_path_query('"-inf"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 419 +select jsonb_path_query('"inf"', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 420 +select jsonb_path_query('"-inf"', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 421 +select jsonb_path_query('123', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 422 +select jsonb_path_query('"123"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 423 +select jsonb_path_query('12345678901234567890', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 424 +select jsonb_path_query('"12345678901234567890"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 425 +select jsonb_path_query('"+12.3"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 426 +select jsonb_path_query('-12.3', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 427 +select jsonb_path_query('"-12.3"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 428 +select jsonb_path_query('12.3', '$.decimal() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 429 +select jsonb_path_query('12345.678', '$.decimal(6, 1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 430 +select jsonb_path_query('12345.678', '$.decimal(6, 2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 431 +select jsonb_path_query('1234.5678', '$.decimal(6, 2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 432 +select jsonb_path_query('12345.678', '$.decimal(4, 6)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 433 +select jsonb_path_query('12345.678', '$.decimal(0, 6)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 434 +select jsonb_path_query('12345.678', '$.decimal(1001, 6)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 435 +select jsonb_path_query('1234.5678', '$.decimal(+6, +2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 436 +select jsonb_path_query('1234.5678', '$.decimal(+6, -2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 437 +select jsonb_path_query('1234.5678', '$.decimal(-6, +2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 438 +select jsonb_path_query('1234.5678', '$.decimal(6, -1001)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 439 +select jsonb_path_query('1234.5678', '$.decimal(6, 1001)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 440 +select jsonb_path_query('-1234.5678', '$.decimal(+6, -2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 441 +select jsonb_path_query('0.0123456', '$.decimal(1,2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 442 +select jsonb_path_query('0.0012345', '$.decimal(2,4)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 443 +select jsonb_path_query('-0.00123456', '$.decimal(2,-4)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 444 +select jsonb_path_query('12.3', '$.decimal(12345678901,1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 445 +select jsonb_path_query('12.3', '$.decimal(1,12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 446 +-- Test .integer() +select jsonb_path_query('null', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 447 +select jsonb_path_query('true', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 448 +select jsonb_path_query('null', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 449 +select jsonb_path_query('true', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 450 +select jsonb_path_query('[]', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 451 +select jsonb_path_query('[]', 'strict $.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 452 +select jsonb_path_query('{}', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 453 +select jsonb_path_query('[]', 'strict $.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 454 +select jsonb_path_query('{}', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 455 +select jsonb_path_query('"1.23"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 456 +select jsonb_path_query('"1.23aaa"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 457 +select jsonb_path_query('1e1000', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 458 +select jsonb_path_query('"nan"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 459 +select jsonb_path_query('"NaN"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 460 +select jsonb_path_query('"inf"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 461 +select jsonb_path_query('"-inf"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 462 +select jsonb_path_query('"inf"', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 463 +select jsonb_path_query('"-inf"', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 464 +select jsonb_path_query('123', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 465 +select jsonb_path_query('"123"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 466 +select jsonb_path_query('1.23', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 467 +select jsonb_path_query('1.83', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 468 +select jsonb_path_query('12345678901', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 469 +select jsonb_path_query('"12345678901"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 470 +select jsonb_path_query('"+123"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 471 +select jsonb_path_query('-123', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 472 +select jsonb_path_query('"-123"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 473 +select jsonb_path_query('123', '$.integer() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 474 +-- Test .number() +select jsonb_path_query('null', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 475 +select jsonb_path_query('true', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 476 +select jsonb_path_query('null', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 477 +select jsonb_path_query('true', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 478 +select jsonb_path_query('[]', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 479 +select jsonb_path_query('[]', 'strict $.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 480 +select jsonb_path_query('{}', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 481 +select jsonb_path_query('[]', 'strict $.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 482 +select jsonb_path_query('{}', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 483 +select jsonb_path_query('1.23', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 484 +select jsonb_path_query('"1.23"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 485 +select jsonb_path_query('"1.23aaa"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 486 +select jsonb_path_query('1e1000', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 487 +select jsonb_path_query('"nan"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 488 +select jsonb_path_query('"NaN"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 489 +select jsonb_path_query('"inf"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 490 +select jsonb_path_query('"-inf"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 491 +select jsonb_path_query('"inf"', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 492 +select jsonb_path_query('"-inf"', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 493 +select jsonb_path_query('123', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 494 +select jsonb_path_query('"123"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 495 +select jsonb_path_query('12345678901234567890', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 496 +select jsonb_path_query('"12345678901234567890"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 497 +select jsonb_path_query('"+12.3"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 498 +select jsonb_path_query('-12.3', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 499 +select jsonb_path_query('"-12.3"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 500 +select jsonb_path_query('12.3', '$.number() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 501 +-- Test .string() +select jsonb_path_query('null', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 502 +select jsonb_path_query('null', '$.string()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 503 +select jsonb_path_query('[]', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 504 +select jsonb_path_query('[]', 'strict $.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 505 +select jsonb_path_query('{}', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 506 +select jsonb_path_query('[]', 'strict $.string()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 507 +select jsonb_path_query('{}', '$.string()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 508 +select jsonb_path_query('1.23', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 509 +select jsonb_path_query('"1.23"', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 510 +select jsonb_path_query('"1.23aaa"', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 511 +select jsonb_path_query('1234', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 512 +select jsonb_path_query('true', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 513 +select jsonb_path_query('1234', '$.string().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 514 +select jsonb_path_query('[2, true]', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 515 +select jsonb_path_query_array('[1.23, "yes", false]', '$[*].string()') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 516 +select jsonb_path_query_array('[1.23, "yes", false]', '$[*].string().type()') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 517 +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 518 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 519 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 520 +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 521 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 522 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 523 +select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 524 +-- this timetz usage will absorb the UTC offset of the current timezone setting +begin +-- +STMT: TransactionStmt +== 525 +set local timezone = 'UTC-10' +-- +STMT: VariableSetStmt +== 526 +select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 527 +rollback +-- +STMT: TransactionStmt +== 528 +select jsonb_path_query('"12:34:56"', '$.time().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 529 +select jsonb_path_query('"2023-08-15"', '$.date().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 530 +-- .string() does not react to timezone or datestyle +begin +-- +STMT: TransactionStmt +== 531 +set local timezone = 'UTC' +-- +STMT: VariableSetStmt +== 532 +set local datestyle = 'German' +-- +STMT: VariableSetStmt +== 533 +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 534 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 535 +rollback +-- +STMT: TransactionStmt +== 536 +-- Test .time() +select jsonb_path_query('null', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 537 +select jsonb_path_query('true', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 538 +select jsonb_path_query('1', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 539 +select jsonb_path_query('[]', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 540 +select jsonb_path_query('[]', 'strict $.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 541 +select jsonb_path_query('{}', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 542 +select jsonb_path_query('"bogus"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 543 +select jsonb '"12:34:56"' @? '$.time()' +-- +STMT: SelectStmt +== 544 +select jsonb_path_query('"12:34:56"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 545 +select jsonb_path_query('"12:34:56"', '$.time().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 546 +select jsonb_path_query('"2023-08-15"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 547 +select jsonb_path_query('"12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 548 +select jsonb_path_query_tz('"12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 549 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 550 +select jsonb_path_query('"12:34:56.789"', '$.time(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 551 +select jsonb_path_query('"12:34:56.789"', '$.time(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 552 +select jsonb_path_query('"12:34:56.789"', '$.time(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 553 +select jsonb_path_query('"12:34:56.789"', '$.time(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 554 +select jsonb_path_query('"12:34:56.789"', '$.time(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 555 +select jsonb_path_query('"12:34:56.789"', '$.time(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 556 +select jsonb_path_query('"12:34:56.789"', '$.time(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 557 +select jsonb_path_query('"12:34:56.789012"', '$.time(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 558 +-- Test .time_tz() +select jsonb_path_query('null', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 559 +select jsonb_path_query('true', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 560 +select jsonb_path_query('1', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 561 +select jsonb_path_query('[]', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 562 +select jsonb_path_query('[]', 'strict $.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 563 +select jsonb_path_query('{}', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 564 +select jsonb_path_query('"bogus"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 565 +select jsonb '"12:34:56 +05:30"' @? '$.time_tz()' +-- +STMT: SelectStmt +== 566 +select jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 567 +select jsonb_path_query('"12:34:56 +05:30"', '$.time_tz().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 568 +select jsonb_path_query('"2023-08-15"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 569 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 570 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 571 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 572 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 573 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 574 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 575 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 576 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 577 +select jsonb_path_query('"12:34:56.789012 +05:30"', '$.time_tz(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 578 +-- Test .timestamp() +select jsonb_path_query('null', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 579 +select jsonb_path_query('true', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 580 +select jsonb_path_query('1', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 581 +select jsonb_path_query('[]', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 582 +select jsonb_path_query('[]', 'strict $.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 583 +select jsonb_path_query('{}', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 584 +select jsonb_path_query('"bogus"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 585 +select jsonb '"2023-08-15 12:34:56"' @? '$.timestamp()' +-- +STMT: SelectStmt +== 586 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 587 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 588 +select jsonb_path_query('"2023-08-15"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 589 +select jsonb_path_query('"12:34:56"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 590 +select jsonb_path_query('"12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 591 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 592 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 593 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 594 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 595 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 596 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 597 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 598 +select jsonb_path_query('"2023-08-15 12:34:56.789012"', '$.timestamp(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 599 +-- Test .timestamp_tz() +select jsonb_path_query('null', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 600 +select jsonb_path_query('true', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 601 +select jsonb_path_query('1', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 602 +select jsonb_path_query('[]', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 603 +select jsonb_path_query('[]', 'strict $.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 604 +select jsonb_path_query('{}', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 605 +select jsonb_path_query('"bogus"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 606 +select jsonb '"2023-08-15 12:34:56 +05:30"' @? '$.timestamp_tz()' +-- +STMT: SelectStmt +== 607 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 608 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 609 +select jsonb_path_query('"2023-08-15"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 610 +select jsonb_path_query_tz('"2023-08-15"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 611 +-- should work +select jsonb_path_query('"12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 612 +select jsonb_path_query('"12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 613 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 614 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 615 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 616 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 617 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 618 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 619 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 620 +select jsonb_path_query('"2023-08-15 12:34:56.789012 +05:30"', '$.timestamp_tz(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 621 +set time zone '+00' +-- +STMT: VariableSetStmt +== 622 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 623 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 624 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 625 +select jsonb_path_query('"12:34:56"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 626 +select jsonb_path_query_tz('"12:34:56"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 627 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 628 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 629 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 630 +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 631 +-- should work + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 632 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 633 +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 634 +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 635 +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 636 +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 637 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 638 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 639 +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 640 +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 641 +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 642 +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 643 +set time zone '+10' +-- +STMT: VariableSetStmt +== 644 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 645 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 646 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 647 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 648 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 649 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 650 +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 651 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 652 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 653 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 654 +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 655 +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 656 +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 657 +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 658 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 659 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 660 +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 661 +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 662 +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 663 +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 664 +set time zone default +-- +STMT: VariableSetStmt +== 665 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 666 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 667 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 668 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 669 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 670 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 671 +select jsonb_path_query('"2017-03-10"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 672 +select jsonb_path_query('"2017-03-10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 673 +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 674 +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 675 +select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 676 +select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 677 +select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 678 +select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 679 +select jsonb_path_query('"2017-03-10T12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 680 +select jsonb_path_query('"2017-03-10t12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 681 +select jsonb_path_query('"2017-03-10 12:34:56.789+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 682 +select jsonb_path_query('"2017-03-10T12:34:56.789+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 683 +select jsonb_path_query('"2017-03-10t12:34:56.789+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 684 +select jsonb_path_query('"2017-03-10T12:34:56.789EST"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 685 +select jsonb_path_query('"2017-03-10T12:34:56.789Z"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 686 +select jsonb_path_query('"12:34:56"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 687 +select jsonb_path_query('"12:34:56"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 688 +select jsonb_path_query('"12:34:56+3"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 689 +select jsonb_path_query('"12:34:56+3"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 690 +select jsonb_path_query('"12:34:56+3:10"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 691 +select jsonb_path_query('"12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 692 +set time zone '+00' +-- +STMT: VariableSetStmt +== 693 +-- date comparison +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 694 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 695 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 696 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 697 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 698 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 699 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 700 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 701 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 702 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ == "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 703 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ >= "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 704 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ < "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 705 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ == "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 706 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ >= "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 707 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ < "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 708 +-- time comparison +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 709 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 710 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 711 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 712 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 713 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 714 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 715 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 716 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 717 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ == "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 718 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ >= "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 719 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ < "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 720 +select jsonb_path_query( + '["12:34:00.123", "12:35:00.123", "12:36:00.1123", "12:35:00.1123+00", "12:35:00.123+01", "13:35:00.123+01", "2017-03-10 12:35:00.1", "2017-03-10 12:35:00.123+01"]', + '$[*].time(2) ? (@ >= "12:35:00.123".time(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 721 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ == "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 722 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ >= "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 723 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ < "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 724 +select jsonb_path_query_tz( + '["12:34:00.123", "12:35:00.123", "12:36:00.1123", "12:35:00.1123+00", "12:35:00.123+01", "13:35:00.123+01", "2017-03-10 12:35:00.1", "2017-03-10 12:35:00.123+01"]', + '$[*].time(2) ? (@ >= "12:35:00.123".time(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 725 +-- timetz comparison +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 726 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 727 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 728 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 729 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 730 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 731 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 732 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 733 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 734 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ == "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 735 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ >= "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 736 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ < "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 737 +select jsonb_path_query( + '["12:34:00.123+01", "12:35:00.123+01", "12:36:00.1123+01", "12:35:00.1123+02", "12:35:00.123-02", "10:35:00.123", "11:35:00.1", "12:35:00.123", "2017-03-10 12:35:00.123 +1"]', + '$[*].time_tz(2) ? (@ >= "12:35:00.123 +1".time_tz(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 738 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ == "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 739 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ >= "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 740 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ < "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 741 +select jsonb_path_query_tz( + '["12:34:00.123+01", "12:35:00.123+01", "12:36:00.1123+01", "12:35:00.1123+02", "12:35:00.123-02", "10:35:00.123", "11:35:00.1", "12:35:00.123", "2017-03-10 12:35:00.123 +1"]', + '$[*].time_tz(2) ? (@ >= "12:35:00.123 +1".time_tz(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 742 +-- timestamp comparison +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 743 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 744 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 745 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 746 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 747 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 748 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ == "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 749 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ >= "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 750 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ < "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 751 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ == "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 752 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ >= "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 753 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ < "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 754 +select jsonb_path_query( + '["2017-03-10 12:34:00.123", "2017-03-10 12:35:00.123", "2017-03-10 12:36:00.1123", "2017-03-10 12:35:00.1123+01", "2017-03-10 13:35:00.123+01", "2017-03-10 12:35:00.1-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp(2) ? (@ >= "2017-03-10 12:35:00.123".timestamp(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 755 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ == "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 756 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ >= "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 757 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ < "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 758 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00.123", "2017-03-10 12:35:00.123", "2017-03-10 12:36:00.1123", "2017-03-10 12:35:00.1123+01", "2017-03-10 13:35:00.123+01", "2017-03-10 12:35:00.1-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp(2) ? (@ >= "2017-03-10 12:35:00.123".timestamp(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 759 +-- timestamptz comparison +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 760 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 761 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 762 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 763 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 764 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 765 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 766 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 767 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 768 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 769 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 770 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 771 +select jsonb_path_query( + '["2017-03-10 12:34:00.123+01", "2017-03-10 12:35:00.123+01", "2017-03-10 12:36:00.1123+01", "2017-03-10 12:35:00.1123+02", "2017-03-10 12:35:00.123-02", "2017-03-10 10:35:00.123", "2017-03-10 11:35:00.1", "2017-03-10 12:35:00.123", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz(2) ? (@ >= "2017-03-10 12:35:00.123 +1".timestamp_tz(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 772 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 773 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 774 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 775 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00.123+01", "2017-03-10 12:35:00.123+01", "2017-03-10 12:36:00.1123+01", "2017-03-10 12:35:00.1123+02", "2017-03-10 12:35:00.123-02", "2017-03-10 10:35:00.123", "2017-03-10 11:35:00.1", "2017-03-10 12:35:00.123", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz(2) ? (@ >= "2017-03-10 12:35:00.123 +1".timestamp_tz(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +== 776 +-- overflow during comparison +select jsonb_path_query('"1000000-01-01"', '$.datetime() > "2020-01-01 12:00:00".datetime()'::jsonpath) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 777 +set time zone default +-- +STMT: VariableSetStmt +== 778 +-- jsonpath operators + +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 779 +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 780 +SELECT jsonb_path_query('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 781 +SELECT jsonb_path_query('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +== 782 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 783 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 784 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 785 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 786 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 787 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +== 788 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 789 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 790 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 791 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 792 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 793 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 794 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 795 +SELECT jsonb_path_query_first('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 796 +SELECT jsonb_path_query_first('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +== 797 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)' +-- +STMT: SelectStmt +== 798 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*] ? (@.a > 2)' +-- +STMT: SelectStmt +== 799 +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 1)') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 800 +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 1, "max": 4}') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 801 +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 3, "max": 4}') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 802 +SELECT jsonb_path_exists('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 803 +SELECT jsonb_path_exists('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +== 804 +SELECT jsonb_path_match('true', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 805 +SELECT jsonb_path_match('false', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 806 +SELECT jsonb_path_match('null', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 807 +SELECT jsonb_path_match('1', '$', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 808 +SELECT jsonb_path_match('1', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 809 +SELECT jsonb_path_match('"a"', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 810 +SELECT jsonb_path_match('{}', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 811 +SELECT jsonb_path_match('[true]', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 812 +SELECT jsonb_path_match('{}', 'lax $.a', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 813 +SELECT jsonb_path_match('{}', 'strict $.a', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 814 +SELECT jsonb_path_match('{}', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 815 +SELECT jsonb_path_match('[true, true]', '$[*]', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 816 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1' +-- +STMT: SelectStmt +== 817 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 2' +-- +STMT: SelectStmt +== 818 +SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 819 +SELECT jsonb_path_match('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 820 +SELECT jsonb_path_match('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +== 821 +-- test string comparison (Unicode codepoint collation) +WITH str(j, num) AS +( + SELECT jsonb_build_object('s', s), num + FROM unnest('{"", "a", "ab", "abc", "abcd", "b", "A", "AB", "ABC", "ABc", "ABcD", "B"}'::text[]) WITH ORDINALITY AS a(s, num) +) +SELECT + s1.j, s2.j, + jsonb_path_query_first(s1.j, '$.s < $s', vars => s2.j) lt, + jsonb_path_query_first(s1.j, '$.s <= $s', vars => s2.j) le, + jsonb_path_query_first(s1.j, '$.s == $s', vars => s2.j) eq, + jsonb_path_query_first(s1.j, '$.s >= $s', vars => s2.j) ge, + jsonb_path_query_first(s1.j, '$.s > $s', vars => s2.j) gt +FROM str s1, str s2 +ORDER BY s1.num, s2.num +-- +ALIAS: "s1"="str" +ALIAS: "s2"="str" +CTE: "str" +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/jsonpath.metadata.json b/parser/testdata/summary/postgres_regress/jsonpath.metadata.json new file mode 100644 index 0000000..402e8ee --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonpath.metadata.json @@ -0,0 +1,228 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224" + ] +} diff --git a/parser/testdata/summary/postgres_regress/jsonpath.test b/parser/testdata/summary/postgres_regress/jsonpath.test new file mode 100644 index 0000000..a67af69 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonpath.test @@ -0,0 +1,923 @@ +== 001 +--jsonpath io + +select ''::jsonpath +-- +STMT: SelectStmt +== 002 +select '$'::jsonpath +-- +STMT: SelectStmt +== 003 +select 'strict $'::jsonpath +-- +STMT: SelectStmt +== 004 +select 'lax $'::jsonpath +-- +STMT: SelectStmt +== 005 +select '$.a'::jsonpath +-- +STMT: SelectStmt +== 006 +select '$.a.v'::jsonpath +-- +STMT: SelectStmt +== 007 +select '$.a.*'::jsonpath +-- +STMT: SelectStmt +== 008 +select '$.*[*]'::jsonpath +-- +STMT: SelectStmt +== 009 +select '$.a[*]'::jsonpath +-- +STMT: SelectStmt +== 010 +select '$.a[*][*]'::jsonpath +-- +STMT: SelectStmt +== 011 +select '$[*]'::jsonpath +-- +STMT: SelectStmt +== 012 +select '$[0]'::jsonpath +-- +STMT: SelectStmt +== 013 +select '$[*][0]'::jsonpath +-- +STMT: SelectStmt +== 014 +select '$[*].a'::jsonpath +-- +STMT: SelectStmt +== 015 +select '$[*][0].a.b'::jsonpath +-- +STMT: SelectStmt +== 016 +select '$.a.**.b'::jsonpath +-- +STMT: SelectStmt +== 017 +select '$.a.**{2}.b'::jsonpath +-- +STMT: SelectStmt +== 018 +select '$.a.**{2 to 2}.b'::jsonpath +-- +STMT: SelectStmt +== 019 +select '$.a.**{2 to 5}.b'::jsonpath +-- +STMT: SelectStmt +== 020 +select '$.a.**{0 to 5}.b'::jsonpath +-- +STMT: SelectStmt +== 021 +select '$.a.**{5 to last}.b'::jsonpath +-- +STMT: SelectStmt +== 022 +select '$.a.**{last}.b'::jsonpath +-- +STMT: SelectStmt +== 023 +select '$.a.**{last to 5}.b'::jsonpath +-- +STMT: SelectStmt +== 024 +select '$+1'::jsonpath +-- +STMT: SelectStmt +== 025 +select '$-1'::jsonpath +-- +STMT: SelectStmt +== 026 +select '$--+1'::jsonpath +-- +STMT: SelectStmt +== 027 +select '$.a/+-1'::jsonpath +-- +STMT: SelectStmt +== 028 +select '1 * 2 + 4 % -3 != false'::jsonpath +-- +STMT: SelectStmt +== 029 +select '"\b\f\r\n\t\v\"\''\\"'::jsonpath +-- +STMT: SelectStmt +== 030 +select '"\x50\u0067\u{53}\u{051}\u{00004C}"'::jsonpath +-- +STMT: SelectStmt +== 031 +select '$.foo\x50\u0067\u{53}\u{051}\u{00004C}\t\"bar'::jsonpath +-- +STMT: SelectStmt +== 032 +select '"\z"'::jsonpath +-- +STMT: SelectStmt +== 033 +-- unrecognized escape is just the literal char + +select '$.g ? ($.a == 1)'::jsonpath +-- +STMT: SelectStmt +== 034 +select '$.g ? (@ == 1)'::jsonpath +-- +STMT: SelectStmt +== 035 +select '$.g ? (@.a == 1)'::jsonpath +-- +STMT: SelectStmt +== 036 +select '$.g ? (@.a == 1 || @.a == 4)'::jsonpath +-- +STMT: SelectStmt +== 037 +select '$.g ? (@.a == 1 && @.a == 4)'::jsonpath +-- +STMT: SelectStmt +== 038 +select '$.g ? (@.a == 1 || @.a == 4 && @.b == 7)'::jsonpath +-- +STMT: SelectStmt +== 039 +select '$.g ? (@.a == 1 || !(@.a == 4) && @.b == 7)'::jsonpath +-- +STMT: SelectStmt +== 040 +select '$.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7)'::jsonpath +-- +STMT: SelectStmt +== 041 +select '$.g ? (@.x >= @[*]?(@.a > "abc"))'::jsonpath +-- +STMT: SelectStmt +== 042 +select '$.g ? ((@.x >= 123 || @.a == 4) is unknown)'::jsonpath +-- +STMT: SelectStmt +== 043 +select '$.g ? (exists (@.x))'::jsonpath +-- +STMT: SelectStmt +== 044 +select '$.g ? (exists (@.x ? (@ == 14)))'::jsonpath +-- +STMT: SelectStmt +== 045 +select '$.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14)))'::jsonpath +-- +STMT: SelectStmt +== 046 +select '$.g ? (+@.x >= +-(+@.a + 2))'::jsonpath +-- +STMT: SelectStmt +== 047 +select '$a'::jsonpath +-- +STMT: SelectStmt +== 048 +select '$a.b'::jsonpath +-- +STMT: SelectStmt +== 049 +select '$a[*]'::jsonpath +-- +STMT: SelectStmt +== 050 +select '$.g ? (@.zip == $zip)'::jsonpath +-- +STMT: SelectStmt +== 051 +select '$.a[1,2, 3 to 16]'::jsonpath +-- +STMT: SelectStmt +== 052 +select '$.a[$a + 1, ($b[*]) to -($[0] * 2)]'::jsonpath +-- +STMT: SelectStmt +== 053 +select '$.a[$.a.size() - 3]'::jsonpath +-- +STMT: SelectStmt +== 054 +select 'last'::jsonpath +-- +STMT: SelectStmt +== 055 +select '"last"'::jsonpath +-- +STMT: SelectStmt +== 056 +select '$.last'::jsonpath +-- +STMT: SelectStmt +== 057 +select '$ ? (last > 0)'::jsonpath +-- +STMT: SelectStmt +== 058 +select '$[last]'::jsonpath +-- +STMT: SelectStmt +== 059 +select '$[$[0] ? (last > 0)]'::jsonpath +-- +STMT: SelectStmt +== 060 +select 'null.type()'::jsonpath +-- +STMT: SelectStmt +== 061 +select '1.type()'::jsonpath +-- +STMT: SelectStmt +== 062 +select '(1).type()'::jsonpath +-- +STMT: SelectStmt +== 063 +select '1.2.type()'::jsonpath +-- +STMT: SelectStmt +== 064 +select '"aaa".type()'::jsonpath +-- +STMT: SelectStmt +== 065 +select 'true.type()'::jsonpath +-- +STMT: SelectStmt +== 066 +select '$.double().floor().ceiling().abs()'::jsonpath +-- +STMT: SelectStmt +== 067 +select '$.keyvalue().key'::jsonpath +-- +STMT: SelectStmt +== 068 +select '$.datetime()'::jsonpath +-- +STMT: SelectStmt +== 069 +select '$.datetime("datetime template")'::jsonpath +-- +STMT: SelectStmt +== 070 +select '$.bigint().integer().number().decimal()'::jsonpath +-- +STMT: SelectStmt +== 071 +select '$.boolean()'::jsonpath +-- +STMT: SelectStmt +== 072 +select '$.date()'::jsonpath +-- +STMT: SelectStmt +== 073 +select '$.decimal(4,2)'::jsonpath +-- +STMT: SelectStmt +== 074 +select '$.string()'::jsonpath +-- +STMT: SelectStmt +== 075 +select '$.time()'::jsonpath +-- +STMT: SelectStmt +== 076 +select '$.time(6)'::jsonpath +-- +STMT: SelectStmt +== 077 +select '$.time_tz()'::jsonpath +-- +STMT: SelectStmt +== 078 +select '$.time_tz(4)'::jsonpath +-- +STMT: SelectStmt +== 079 +select '$.timestamp()'::jsonpath +-- +STMT: SelectStmt +== 080 +select '$.timestamp(2)'::jsonpath +-- +STMT: SelectStmt +== 081 +select '$.timestamp_tz()'::jsonpath +-- +STMT: SelectStmt +== 082 +select '$.timestamp_tz(0)'::jsonpath +-- +STMT: SelectStmt +== 083 +select '$ ? (@ starts with "abc")'::jsonpath +-- +STMT: SelectStmt +== 084 +select '$ ? (@ starts with $var)'::jsonpath +-- +STMT: SelectStmt +== 085 +select '$ ? (@ like_regex "(invalid pattern")'::jsonpath +-- +STMT: SelectStmt +== 086 +select '$ ? (@ like_regex "pattern")'::jsonpath +-- +STMT: SelectStmt +== 087 +select '$ ? (@ like_regex "pattern" flag "")'::jsonpath +-- +STMT: SelectStmt +== 088 +select '$ ? (@ like_regex "pattern" flag "i")'::jsonpath +-- +STMT: SelectStmt +== 089 +select '$ ? (@ like_regex "pattern" flag "is")'::jsonpath +-- +STMT: SelectStmt +== 090 +select '$ ? (@ like_regex "pattern" flag "isim")'::jsonpath +-- +STMT: SelectStmt +== 091 +select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath +-- +STMT: SelectStmt +== 092 +select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath +-- +STMT: SelectStmt +== 093 +select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath +-- +STMT: SelectStmt +== 094 +select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath +-- +STMT: SelectStmt +== 095 +select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath +-- +STMT: SelectStmt +== 096 +select '$ < 1'::jsonpath +-- +STMT: SelectStmt +== 097 +select '($ < 1) || $.a.b <= $x'::jsonpath +-- +STMT: SelectStmt +== 098 +select '@ + 1'::jsonpath +-- +STMT: SelectStmt +== 099 +select '($).a.b'::jsonpath +-- +STMT: SelectStmt +== 100 +select '($.a.b).c.d'::jsonpath +-- +STMT: SelectStmt +== 101 +select '($.a.b + -$.x.y).c.d'::jsonpath +-- +STMT: SelectStmt +== 102 +select '(-+$.a.b).c.d'::jsonpath +-- +STMT: SelectStmt +== 103 +select '1 + ($.a.b + 2).c.d'::jsonpath +-- +STMT: SelectStmt +== 104 +select '1 + ($.a.b > 2).c.d'::jsonpath +-- +STMT: SelectStmt +== 105 +select '($)'::jsonpath +-- +STMT: SelectStmt +== 106 +select '(($))'::jsonpath +-- +STMT: SelectStmt +== 107 +select '((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c)))))'::jsonpath +-- +STMT: SelectStmt +== 108 +select '$ ? (@.a < 1)'::jsonpath +-- +STMT: SelectStmt +== 109 +select '$ ? (@.a < -1)'::jsonpath +-- +STMT: SelectStmt +== 110 +select '$ ? (@.a < +1)'::jsonpath +-- +STMT: SelectStmt +== 111 +select '$ ? (@.a < .1)'::jsonpath +-- +STMT: SelectStmt +== 112 +select '$ ? (@.a < -.1)'::jsonpath +-- +STMT: SelectStmt +== 113 +select '$ ? (@.a < +.1)'::jsonpath +-- +STMT: SelectStmt +== 114 +select '$ ? (@.a < 0.1)'::jsonpath +-- +STMT: SelectStmt +== 115 +select '$ ? (@.a < -0.1)'::jsonpath +-- +STMT: SelectStmt +== 116 +select '$ ? (@.a < +0.1)'::jsonpath +-- +STMT: SelectStmt +== 117 +select '$ ? (@.a < 10.1)'::jsonpath +-- +STMT: SelectStmt +== 118 +select '$ ? (@.a < -10.1)'::jsonpath +-- +STMT: SelectStmt +== 119 +select '$ ? (@.a < +10.1)'::jsonpath +-- +STMT: SelectStmt +== 120 +select '$ ? (@.a < 1e1)'::jsonpath +-- +STMT: SelectStmt +== 121 +select '$ ? (@.a < -1e1)'::jsonpath +-- +STMT: SelectStmt +== 122 +select '$ ? (@.a < +1e1)'::jsonpath +-- +STMT: SelectStmt +== 123 +select '$ ? (@.a < .1e1)'::jsonpath +-- +STMT: SelectStmt +== 124 +select '$ ? (@.a < -.1e1)'::jsonpath +-- +STMT: SelectStmt +== 125 +select '$ ? (@.a < +.1e1)'::jsonpath +-- +STMT: SelectStmt +== 126 +select '$ ? (@.a < 0.1e1)'::jsonpath +-- +STMT: SelectStmt +== 127 +select '$ ? (@.a < -0.1e1)'::jsonpath +-- +STMT: SelectStmt +== 128 +select '$ ? (@.a < +0.1e1)'::jsonpath +-- +STMT: SelectStmt +== 129 +select '$ ? (@.a < 10.1e1)'::jsonpath +-- +STMT: SelectStmt +== 130 +select '$ ? (@.a < -10.1e1)'::jsonpath +-- +STMT: SelectStmt +== 131 +select '$ ? (@.a < +10.1e1)'::jsonpath +-- +STMT: SelectStmt +== 132 +select '$ ? (@.a < 1e-1)'::jsonpath +-- +STMT: SelectStmt +== 133 +select '$ ? (@.a < -1e-1)'::jsonpath +-- +STMT: SelectStmt +== 134 +select '$ ? (@.a < +1e-1)'::jsonpath +-- +STMT: SelectStmt +== 135 +select '$ ? (@.a < .1e-1)'::jsonpath +-- +STMT: SelectStmt +== 136 +select '$ ? (@.a < -.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 137 +select '$ ? (@.a < +.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 138 +select '$ ? (@.a < 0.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 139 +select '$ ? (@.a < -0.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 140 +select '$ ? (@.a < +0.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 141 +select '$ ? (@.a < 10.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 142 +select '$ ? (@.a < -10.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 143 +select '$ ? (@.a < +10.1e-1)'::jsonpath +-- +STMT: SelectStmt +== 144 +select '$ ? (@.a < 1e+1)'::jsonpath +-- +STMT: SelectStmt +== 145 +select '$ ? (@.a < -1e+1)'::jsonpath +-- +STMT: SelectStmt +== 146 +select '$ ? (@.a < +1e+1)'::jsonpath +-- +STMT: SelectStmt +== 147 +select '$ ? (@.a < .1e+1)'::jsonpath +-- +STMT: SelectStmt +== 148 +select '$ ? (@.a < -.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 149 +select '$ ? (@.a < +.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 150 +select '$ ? (@.a < 0.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 151 +select '$ ? (@.a < -0.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 152 +select '$ ? (@.a < +0.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 153 +select '$ ? (@.a < 10.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 154 +select '$ ? (@.a < -10.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 155 +select '$ ? (@.a < +10.1e+1)'::jsonpath +-- +STMT: SelectStmt +== 156 +-- numeric literals + +select '0'::jsonpath +-- +STMT: SelectStmt +== 157 +select '00'::jsonpath +-- +STMT: SelectStmt +== 158 +select '0755'::jsonpath +-- +STMT: SelectStmt +== 159 +select '0.0'::jsonpath +-- +STMT: SelectStmt +== 160 +select '0.000'::jsonpath +-- +STMT: SelectStmt +== 161 +select '0.000e1'::jsonpath +-- +STMT: SelectStmt +== 162 +select '0.000e2'::jsonpath +-- +STMT: SelectStmt +== 163 +select '0.000e3'::jsonpath +-- +STMT: SelectStmt +== 164 +select '0.0010'::jsonpath +-- +STMT: SelectStmt +== 165 +select '0.0010e-1'::jsonpath +-- +STMT: SelectStmt +== 166 +select '0.0010e+1'::jsonpath +-- +STMT: SelectStmt +== 167 +select '0.0010e+2'::jsonpath +-- +STMT: SelectStmt +== 168 +select '.001'::jsonpath +-- +STMT: SelectStmt +== 169 +select '.001e1'::jsonpath +-- +STMT: SelectStmt +== 170 +select '1.'::jsonpath +-- +STMT: SelectStmt +== 171 +select '1.e1'::jsonpath +-- +STMT: SelectStmt +== 172 +select '1a'::jsonpath +-- +STMT: SelectStmt +== 173 +select '1e'::jsonpath +-- +STMT: SelectStmt +== 174 +select '1.e'::jsonpath +-- +STMT: SelectStmt +== 175 +select '1.2a'::jsonpath +-- +STMT: SelectStmt +== 176 +select '1.2e'::jsonpath +-- +STMT: SelectStmt +== 177 +select '1.2.e'::jsonpath +-- +STMT: SelectStmt +== 178 +select '(1.2).e'::jsonpath +-- +STMT: SelectStmt +== 179 +select '1e3'::jsonpath +-- +STMT: SelectStmt +== 180 +select '1.e3'::jsonpath +-- +STMT: SelectStmt +== 181 +select '1.e3.e'::jsonpath +-- +STMT: SelectStmt +== 182 +select '1.e3.e4'::jsonpath +-- +STMT: SelectStmt +== 183 +select '1.2e3'::jsonpath +-- +STMT: SelectStmt +== 184 +select '1.2e3a'::jsonpath +-- +STMT: SelectStmt +== 185 +select '1.2.e3'::jsonpath +-- +STMT: SelectStmt +== 186 +select '(1.2).e3'::jsonpath +-- +STMT: SelectStmt +== 187 +select '1..e'::jsonpath +-- +STMT: SelectStmt +== 188 +select '1..e3'::jsonpath +-- +STMT: SelectStmt +== 189 +select '(1.).e'::jsonpath +-- +STMT: SelectStmt +== 190 +select '(1.).e3'::jsonpath +-- +STMT: SelectStmt +== 191 +select '1?(2>3)'::jsonpath +-- +STMT: SelectStmt +== 192 +-- nondecimal +select '0b100101'::jsonpath +-- +STMT: SelectStmt +== 193 +select '0o273'::jsonpath +-- +STMT: SelectStmt +== 194 +select '0x42F'::jsonpath +-- +STMT: SelectStmt +== 195 +-- error cases +select '0b'::jsonpath +-- +STMT: SelectStmt +== 196 +select '1b'::jsonpath +-- +STMT: SelectStmt +== 197 +select '0b0x'::jsonpath +-- +STMT: SelectStmt +== 198 +select '0o'::jsonpath +-- +STMT: SelectStmt +== 199 +select '1o'::jsonpath +-- +STMT: SelectStmt +== 200 +select '0o0x'::jsonpath +-- +STMT: SelectStmt +== 201 +select '0x'::jsonpath +-- +STMT: SelectStmt +== 202 +select '1x'::jsonpath +-- +STMT: SelectStmt +== 203 +select '0x0y'::jsonpath +-- +STMT: SelectStmt +== 204 +-- underscores +select '1_000_000'::jsonpath +-- +STMT: SelectStmt +== 205 +select '1_2_3'::jsonpath +-- +STMT: SelectStmt +== 206 +select '0x1EEE_FFFF'::jsonpath +-- +STMT: SelectStmt +== 207 +select '0o2_73'::jsonpath +-- +STMT: SelectStmt +== 208 +select '0b10_0101'::jsonpath +-- +STMT: SelectStmt +== 209 +select '1_000.000_005'::jsonpath +-- +STMT: SelectStmt +== 210 +select '1_000.'::jsonpath +-- +STMT: SelectStmt +== 211 +select '.000_005'::jsonpath +-- +STMT: SelectStmt +== 212 +select '1_000.5e0_1'::jsonpath +-- +STMT: SelectStmt +== 213 +-- error cases +select '_100'::jsonpath +-- +STMT: SelectStmt +== 214 +select '100_'::jsonpath +-- +STMT: SelectStmt +== 215 +select '100__000'::jsonpath +-- +STMT: SelectStmt +== 216 +select '_1_000.5'::jsonpath +-- +STMT: SelectStmt +== 217 +select '1_000_.5'::jsonpath +-- +STMT: SelectStmt +== 218 +select '1_000._5'::jsonpath +-- +STMT: SelectStmt +== 219 +select '1_000.5_'::jsonpath +-- +STMT: SelectStmt +== 220 +select '1_000.5e_1'::jsonpath +-- +STMT: SelectStmt +== 221 +-- underscore after prefix not allowed in JavaScript (but allowed in SQL) +select '0b_10_0101'::jsonpath +-- +STMT: SelectStmt +== 222 +select '0o_273'::jsonpath +-- +STMT: SelectStmt +== 223 +select '0x_42F'::jsonpath +-- +STMT: SelectStmt +== 224 +-- test non-error-throwing API + +SELECT str as jsonpath, + pg_input_is_valid(str,'jsonpath') as ok, + errinfo.sql_error_code, + errinfo.message, + errinfo.detail, + errinfo.hint +FROM unnest(ARRAY['$ ? (@ like_regex "pattern" flag "smixq")'::text, + '$ ? (@ like_regex "pattern" flag "a")', + '@ + 1', + '00', + '1a']) str, + LATERAL pg_input_error_info(str, 'jsonpath') as errinfo +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json b/parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json new file mode 100644 index 0000000..efb3a10 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json @@ -0,0 +1,36 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032" + ] +} diff --git a/parser/testdata/summary/postgres_regress/jsonpath_encoding.test b/parser/testdata/summary/postgres_regress/jsonpath_encoding.test new file mode 100644 index 0000000..40034d2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/jsonpath_encoding.test @@ -0,0 +1,171 @@ +== 001 +|-- +-- encoding-sensitive tests for jsonpath +|-- + +-- We provide expected-results files for UTF8 (jsonpath_encoding.out) +-- and for SQL_ASCII (jsonpath_encoding_1.out). Skip otherwise. +SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') + AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +== 002 +SELECT getdatabaseencoding() +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- just to label the results files + +-- checks for double-quoted values + +-- basic unicode input +SELECT '"\u"'::jsonpath +-- +STMT: SelectStmt +== 004 +-- ERROR, incomplete escape +SELECT '"\u00"'::jsonpath +-- +STMT: SelectStmt +== 005 +-- ERROR, incomplete escape +SELECT '"\u000g"'::jsonpath +-- +STMT: SelectStmt +== 006 +-- ERROR, g is not a hex digit +SELECT '"\u0000"'::jsonpath +-- +STMT: SelectStmt +== 007 +-- OK, legal escape +SELECT '"\uaBcD"'::jsonpath +-- +STMT: SelectStmt +== 008 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs +select '"\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +== 009 +select '"\ud83d\ud83d"'::jsonpath +-- +STMT: SelectStmt +== 010 +-- 2 high surrogates in a row +select '"\ude04\ud83d"'::jsonpath +-- +STMT: SelectStmt +== 011 +-- surrogates in wrong order +select '"\ud83dX"'::jsonpath +-- +STMT: SelectStmt +== 012 +-- orphan high surrogate +select '"\ude04X"'::jsonpath +-- +STMT: SelectStmt +== 013 +-- orphan low surrogate + +--handling of simple unicode escapes +select '"the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +== 014 +select '"dollar \u0024 character"'::jsonpath as correct_everywhere +-- +STMT: SelectStmt +== 015 +select '"dollar \\u0024 character"'::jsonpath as not_an_escape +-- +STMT: SelectStmt +== 016 +select '"null \u0000 escape"'::jsonpath as not_unescaped +-- +STMT: SelectStmt +== 017 +select '"null \\u0000 escape"'::jsonpath as not_an_escape +-- +STMT: SelectStmt +== 018 +-- checks for quoted key names + +-- basic unicode input +SELECT '$."\u"'::jsonpath +-- +STMT: SelectStmt +== 019 +-- ERROR, incomplete escape +SELECT '$."\u00"'::jsonpath +-- +STMT: SelectStmt +== 020 +-- ERROR, incomplete escape +SELECT '$."\u000g"'::jsonpath +-- +STMT: SelectStmt +== 021 +-- ERROR, g is not a hex digit +SELECT '$."\u0000"'::jsonpath +-- +STMT: SelectStmt +== 022 +-- OK, legal escape +SELECT '$."\uaBcD"'::jsonpath +-- +STMT: SelectStmt +== 023 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs +select '$."\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +== 024 +select '$."\ud83d\ud83d"'::jsonpath +-- +STMT: SelectStmt +== 025 +-- 2 high surrogates in a row +select '$."\ude04\ud83d"'::jsonpath +-- +STMT: SelectStmt +== 026 +-- surrogates in wrong order +select '$."\ud83dX"'::jsonpath +-- +STMT: SelectStmt +== 027 +-- orphan high surrogate +select '$."\ude04X"'::jsonpath +-- +STMT: SelectStmt +== 028 +-- orphan low surrogate + +--handling of simple unicode escapes +select '$."the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +== 029 +select '$."dollar \u0024 character"'::jsonpath as correct_everywhere +-- +STMT: SelectStmt +== 030 +select '$."dollar \\u0024 character"'::jsonpath as not_an_escape +-- +STMT: SelectStmt +== 031 +select '$."null \u0000 escape"'::jsonpath as not_unescaped +-- +STMT: SelectStmt +== 032 +select '$."null \\u0000 escape"'::jsonpath as not_an_escape +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/largeobject.metadata.json b/parser/testdata/summary/postgres_regress/largeobject.metadata.json new file mode 100644 index 0000000..48ba122 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/largeobject.metadata.json @@ -0,0 +1,128 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124" + ] +} diff --git a/parser/testdata/summary/postgres_regress/largeobject.test b/parser/testdata/summary/postgres_regress/largeobject.test new file mode 100644 index 0000000..5e4aa24 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/largeobject.test @@ -0,0 +1,764 @@ +== 001 +|-- +-- Test large object support +|-- + +-- directory paths are passed to us in environment variables + +-- ensure consistent test output regardless of the default bytea format +SET bytea_output TO escape +-- +STMT: VariableSetStmt +== 002 +-- Test ALTER LARGE OBJECT OWNER +CREATE ROLE regress_lo_user +-- +STMT: CreateRoleStmt +== 003 +SELECT lo_create(42) +-- +FUNCTION: name="lo_create" function="lo_create" schema="" ctx=Call +STMT: SelectStmt +== 004 +ALTER LARGE OBJECT 42 OWNER TO regress_lo_user +-- +STMT: AlterOwnerStmt +== 005 +-- Test GRANT, COMMENT as non-superuser +SET SESSION AUTHORIZATION regress_lo_user +-- +STMT: VariableSetStmt +== 006 +GRANT SELECT ON LARGE OBJECT 42 TO public +-- +STMT: GrantStmt +== 007 +COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer' +-- +STMT: CommentStmt +== 008 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 009 +-- Test psql's \lo_list et al (we assume no other LOs exist yet) + +-- Load a file +CREATE TABLE lotest_stash_values (loid oid, fd integer) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: CreateStmt +== 010 +-- lo_creat(mode integer) returns oid +-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times +-- returns the large object id +INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_creat" function="lo_creat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 011 +-- NOTE: large objects require transactions +BEGIN +-- +STMT: TransactionStmt +== 012 +-- lo_open(lobjId oid, mode integer) returns integer +-- The mode parameter to lo_open uses two constants: +-- INV_WRITE = 0x20000 +-- INV_READ = 0x40000 +-- The return value is a file descriptor-like value which remains valid for the +-- transaction. +UPDATE lotest_stash_values SET fd = lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +== 013 +-- loread/lowrite names are wonky, different from other functions which are lo_* +-- lowrite(fd integer, data bytea) returns integer +-- the integer is the number of bytes written +SELECT lowrite(fd, ' +I wandered lonely as a cloud +That floats on high o''er vales and hills, +When all at once I saw a crowd, +A host, of golden daffodils; +Beside the lake, beneath the trees, +Fluttering and dancing in the breeze. + +Continuous as the stars that shine +And twinkle on the milky way, +They stretched in never-ending line +Along the margin of a bay: +Ten thousand saw I at a glance, +Tossing their heads in sprightly dance. + +The waves beside them danced; but they +Out-did the sparkling waves in glee: +A poet could not but be gay, +In such a jocund company: +I gazed--and gazed--but little thought +What wealth the show to me had brought: + +For oft, when on my couch I lie +In vacant or in pensive mood, +They flash upon that inward eye +Which is the bliss of solitude; +And then my heart with pleasure fills, +And dances with the daffodils. + + -- William Wordsworth +') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- lo_close(fd integer) returns integer +-- return value is 0 for success, or <0 for error (actually only -1, but...) +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +== 015 +END +-- +STMT: TransactionStmt +== 016 +-- Copy to another large object. +-- Note: we intentionally don't remove the object created here; +-- it's left behind to help test pg_dump. + +SELECT lo_from_bytea(0, lo_get(loid)) AS newloid FROM lotest_stash_values + +-- Add a comment to it, as well, for pg_dump/pg_upgrade testing. +COMMENT ON LARGE OBJECT :newloid IS 'I Wandered Lonely as a Cloud' +-- +ERROR: syntax error at or near "ON" +CURSORPOS: 289 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 017 +-- Read out a portion +BEGIN +-- +STMT: TransactionStmt +== 018 +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +== 019 +-- lo_lseek(fd integer, offset integer, whence integer) returns integer +-- offset is in bytes, whence is one of three values: +-- SEEK_SET (= 0) meaning relative to beginning +-- SEEK_CUR (= 1) meaning relative to current position +-- SEEK_END (= 2) meaning relative to end (offset better be negative) +-- returns current position in file +SELECT lo_lseek(fd, 104, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- loread/lowrite names are wonky, different from other functions which are lo_* +-- loread(fd integer, len integer) returns bytea +SELECT loread(fd, 28) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT lowrite(fd, 'n') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT lo_lseek(fd, -744, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT loread(fd, 28) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +== 026 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +== 027 +END +-- +STMT: TransactionStmt +== 028 +-- Test resource management +BEGIN +-- +STMT: TransactionStmt +== 029 +SELECT lo_open(loid, x'40000'::int) from lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: SelectStmt +== 030 +ABORT +-- +STMT: TransactionStmt +== 031 +DO :'dobody' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 4 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 032 +-- Test truncation. +BEGIN +-- +STMT: TransactionStmt +== 033 +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +== 034 +SELECT lo_truncate(fd, 11) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT loread(fd, 15) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT lo_truncate(fd, 10000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT loread(fd, 10) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT lo_truncate(fd, 5000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 042 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +== 044 +END +-- +STMT: TransactionStmt +== 045 +-- Test 64-bit large object functions. +BEGIN +-- +STMT: TransactionStmt +== 046 +UPDATE lotest_stash_values SET fd = lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +== 047 +SELECT lo_lseek64(fd, 4294967296, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT lowrite(fd, 'offset:4GB') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +== 049 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT lo_lseek64(fd, -10, 1) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +== 051 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +== 052 +SELECT loread(fd, 10) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +== 053 +SELECT lo_truncate64(fd, 5000000000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate64" function="lo_truncate64" schema="" ctx=Call +STMT: SelectStmt +== 054 +SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +== 055 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +== 056 +SELECT lo_truncate64(fd, 3000000000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate64" function="lo_truncate64" schema="" ctx=Call +STMT: SelectStmt +== 057 +SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +== 058 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +== 060 +END +-- +STMT: TransactionStmt +== 061 +-- lo_unlink(lobjId oid) returns integer +-- return value appears to always be 1 +SELECT lo_unlink(loid) from lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +STMT: SelectStmt +== 062 +TRUNCATE lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: TruncateStmt +== 063 +INSERT INTO lotest_stash_values (loid) SELECT lo_import(:'filename') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 064 +BEGIN +-- +STMT: TransactionStmt +== 065 +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +== 066 +-- verify length of large object +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 067 +-- with the default BLCKSZ, LOBLKSIZE = 2048, so this positions us for a block +-- edge case +SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 068 +-- this should get half of the value from page 0 and half from page 1 of the +-- large object +SELECT loread(fd, 36) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +== 073 +SELECT loread(fd, 36) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +== 075 +END +-- +STMT: TransactionStmt +== 076 +SELECT lo_export(loid, :'filename') FROM lotest_stash_values +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +-- just make sure \lo_export does not barf + +-- This is a hack to test that export/import are reversible +-- This uses knowledge about the inner workings of large object mechanism +-- which should not be used outside it. This makes it a HACK +SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values) +EXCEPT +SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 393 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 078 +SELECT lo_unlink(loid) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +STMT: SelectStmt +== 079 +TRUNCATE lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: TruncateStmt +== 080 +SELECT lo_from_bytea(0, lo_get(:newloid_1)) AS newloid_2 + +SELECT fipshash(lo_get(:newloid_1)) = fipshash(lo_get(:newloid_2)) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 081 +SELECT lo_get(:newloid_1, 0, 20) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 082 +SELECT lo_get(:newloid_1, 10, 20) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 083 +SELECT lo_put(:newloid_1, 5, decode('afafafaf', 'hex')) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 084 +SELECT lo_get(:newloid_1, 0, 20) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 085 +SELECT lo_put(:newloid_1, 4294967310, 'foo') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 086 +SELECT lo_get(:newloid_1) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 087 +SELECT lo_get(:newloid_1, 4294967294, 100) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 088 +-- This object is left in the database for pg_dump test purposes +SELECT lo_from_bytea(0, E'\\xdeadbeef') AS newloid + +SET bytea_output TO hex +-- +ERROR: syntax error at or near "SET" +CURSORPOS: 118 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 089 +SELECT lo_get(:newloid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 090 +-- Create one more object that we leave behind for testing pg_dump/pg_upgrade; +-- this one intentionally has an OID in the system range +SELECT lo_create(2121) +-- +FUNCTION: name="lo_create" function="lo_create" schema="" ctx=Call +STMT: SelectStmt +== 091 +COMMENT ON LARGE OBJECT 2121 IS 'testing comments' +-- +STMT: CommentStmt +== 092 +-- Test writes on large objects in read-only transactions +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 093 +-- INV_READ ... ok +SELECT lo_open(2121, x'40000'::int) +-- +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: SelectStmt +== 094 +-- INV_WRITE ... error +SELECT lo_open(2121, x'20000'::int) +-- +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: SelectStmt +== 095 +ROLLBACK +-- +STMT: TransactionStmt +== 096 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 097 +SELECT lo_create(42) +-- +FUNCTION: name="lo_create" function="lo_create" schema="" ctx=Call +STMT: SelectStmt +== 098 +ROLLBACK +-- +STMT: TransactionStmt +== 099 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 100 +SELECT lo_creat(42) +-- +FUNCTION: name="lo_creat" function="lo_creat" schema="" ctx=Call +STMT: SelectStmt +== 101 +ROLLBACK +-- +STMT: TransactionStmt +== 102 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 103 +SELECT lo_unlink(42) +-- +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +STMT: SelectStmt +== 104 +ROLLBACK +-- +STMT: TransactionStmt +== 105 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 106 +SELECT lowrite(42, 'x') +-- +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +== 107 +ROLLBACK +-- +STMT: TransactionStmt +== 108 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 109 +SELECT lo_import(:'filename') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 18 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 110 +ROLLBACK +-- +STMT: TransactionStmt +== 111 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 112 +SELECT lo_truncate(42, 0) +-- +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +== 113 +ROLLBACK +-- +STMT: TransactionStmt +== 114 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 115 +SELECT lo_truncate64(42, 0) +-- +FUNCTION: name="lo_truncate64" function="lo_truncate64" schema="" ctx=Call +STMT: SelectStmt +== 116 +ROLLBACK +-- +STMT: TransactionStmt +== 117 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 118 +SELECT lo_from_bytea(0, 'x') +-- +FUNCTION: name="lo_from_bytea" function="lo_from_bytea" schema="" ctx=Call +STMT: SelectStmt +== 119 +ROLLBACK +-- +STMT: TransactionStmt +== 120 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 121 +SELECT lo_put(42, 0, 'x') +-- +FUNCTION: name="lo_put" function="lo_put" schema="" ctx=Call +STMT: SelectStmt +== 122 +ROLLBACK +-- +STMT: TransactionStmt +== 123 +-- Clean up +DROP TABLE lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: DropStmt +== 124 +DROP ROLE regress_lo_user +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/limit.metadata.json b/parser/testdata/summary/postgres_regress/limit.metadata.json new file mode 100644 index 0000000..fb87925 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/limit.metadata.json @@ -0,0 +1,84 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080" + ] +} diff --git a/parser/testdata/summary/postgres_regress/limit.test b/parser/testdata/summary/postgres_regress/limit.test new file mode 100644 index 0000000..00b1b34 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/limit.test @@ -0,0 +1,509 @@ +== 001 +|-- +-- LIMIT +-- Check the LIMIT/OFFSET feature of SELECT +|-- + +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 50 + ORDER BY unique1 LIMIT 2 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 002 +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 60 + ORDER BY unique1 LIMIT 5 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 003 +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 60 AND unique1 < 63 + ORDER BY unique1 LIMIT 5 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 004 +SELECT ''::text AS three, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 100 + ORDER BY unique1 LIMIT 3 OFFSET 20 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 005 +SELECT ''::text AS zero, unique1, unique2, stringu1 + FROM onek WHERE unique1 < 50 + ORDER BY unique1 DESC LIMIT 8 OFFSET 99 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 006 +SELECT ''::text AS eleven, unique1, unique2, stringu1 + FROM onek WHERE unique1 < 50 + ORDER BY unique1 DESC LIMIT 20 OFFSET 39 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 007 +SELECT ''::text AS ten, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 OFFSET 990 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 008 +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 OFFSET 990 LIMIT 5 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 009 +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 LIMIT 5 OFFSET 900 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 010 +-- Test null limit and offset. The planner would discard a simple null +-- constant, so to ensure executor is exercised, do this: +select * from int8_tbl limit (case when random() < 0.5 then null::bigint end) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 011 +select * from int8_tbl offset (case when random() < 0.5 then null::bigint end) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- Test assorted cases involving backwards fetch from a LIMIT plan node +begin +-- +STMT: TransactionStmt +== 013 +declare c1 cursor for select * from int8_tbl limit 10 +-- +STMT: DeclareCursorStmt +== 014 +fetch all in c1 +-- +STMT: FetchStmt +== 015 +fetch 1 in c1 +-- +STMT: FetchStmt +== 016 +fetch backward 1 in c1 +-- +STMT: FetchStmt +== 017 +fetch backward all in c1 +-- +STMT: FetchStmt +== 018 +fetch backward 1 in c1 +-- +STMT: FetchStmt +== 019 +fetch all in c1 +-- +STMT: FetchStmt +== 020 +declare c2 cursor for select * from int8_tbl limit 3 +-- +STMT: DeclareCursorStmt +== 021 +fetch all in c2 +-- +STMT: FetchStmt +== 022 +fetch 1 in c2 +-- +STMT: FetchStmt +== 023 +fetch backward 1 in c2 +-- +STMT: FetchStmt +== 024 +fetch backward all in c2 +-- +STMT: FetchStmt +== 025 +fetch backward 1 in c2 +-- +STMT: FetchStmt +== 026 +fetch all in c2 +-- +STMT: FetchStmt +== 027 +declare c3 cursor for select * from int8_tbl offset 3 +-- +STMT: DeclareCursorStmt +== 028 +fetch all in c3 +-- +STMT: FetchStmt +== 029 +fetch 1 in c3 +-- +STMT: FetchStmt +== 030 +fetch backward 1 in c3 +-- +STMT: FetchStmt +== 031 +fetch backward all in c3 +-- +STMT: FetchStmt +== 032 +fetch backward 1 in c3 +-- +STMT: FetchStmt +== 033 +fetch all in c3 +-- +STMT: FetchStmt +== 034 +declare c4 cursor for select * from int8_tbl offset 10 +-- +STMT: DeclareCursorStmt +== 035 +fetch all in c4 +-- +STMT: FetchStmt +== 036 +fetch 1 in c4 +-- +STMT: FetchStmt +== 037 +fetch backward 1 in c4 +-- +STMT: FetchStmt +== 038 +fetch backward all in c4 +-- +STMT: FetchStmt +== 039 +fetch backward 1 in c4 +-- +STMT: FetchStmt +== 040 +fetch all in c4 +-- +STMT: FetchStmt +== 041 +declare c5 cursor for select * from int8_tbl order by q1 fetch first 2 rows with ties +-- +STMT: DeclareCursorStmt +== 042 +fetch all in c5 +-- +STMT: FetchStmt +== 043 +fetch 1 in c5 +-- +STMT: FetchStmt +== 044 +fetch backward 1 in c5 +-- +STMT: FetchStmt +== 045 +fetch backward 1 in c5 +-- +STMT: FetchStmt +== 046 +fetch all in c5 +-- +STMT: FetchStmt +== 047 +fetch backward all in c5 +-- +STMT: FetchStmt +== 048 +fetch all in c5 +-- +STMT: FetchStmt +== 049 +fetch backward all in c5 +-- +STMT: FetchStmt +== 050 +rollback +-- +STMT: TransactionStmt +== 051 +-- Stress test for variable LIMIT in conjunction with bounded-heap sorting + +SELECT + (SELECT n + FROM (VALUES (1)) AS x, + (SELECT n FROM generate_series(1,10) AS n + ORDER BY n LIMIT 1 OFFSET s-1) AS y) AS z + FROM generate_series(1,10) AS s +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 052 +|-- +-- Test behavior of volatile and set-returning functions in conjunction +-- with ORDER BY and LIMIT. +|-- + +create temp sequence testseq +-- +STMT: CreateSeqStmt +== 053 +explain (verbose, costs off) +select unique1, unique2, nextval('testseq') + from tenk1 order by unique2 limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 054 +select unique1, unique2, nextval('testseq') + from tenk1 order by unique2 limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 055 +select currval('testseq') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 056 +explain (verbose, costs off) +select unique1, unique2, nextval('testseq') + from tenk1 order by tenthous limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 057 +select unique1, unique2, nextval('testseq') + from tenk1 order by tenthous limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 058 +select currval('testseq') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 059 +explain (verbose, costs off) +select unique1, unique2, generate_series(1,10) + from tenk1 order by unique2 limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 060 +select unique1, unique2, generate_series(1,10) + from tenk1 order by unique2 limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 061 +explain (verbose, costs off) +select unique1, unique2, generate_series(1,10) + from tenk1 order by tenthous limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 062 +select unique1, unique2, generate_series(1,10) + from tenk1 order by tenthous limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 063 +-- use of random() is to keep planner from folding the expressions together +explain (verbose, costs off) +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 064 +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 065 +explain (verbose, costs off) +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +order by s2 desc +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 066 +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +order by s2 desc +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 067 +-- test for failure to set all aggregates' aggtranstype +explain (verbose, costs off) +select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2 + from tenk1 group by thousand order by thousand limit 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 068 +select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2 + from tenk1 group by thousand order by thousand limit 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 069 +|-- +-- FETCH FIRST +-- Check the WITH TIES clause +|-- + +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 2 ROW WITH TIES +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 070 +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST ROWS WITH TIES +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 071 +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 1 ROW WITH TIES +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 072 +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 2 ROW ONLY +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 073 +-- SKIP LOCKED and WITH TIES are incompatible +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 1 ROW WITH TIES FOR UPDATE SKIP LOCKED +-- +ERROR: SKIP LOCKED and WITH TIES options cannot be used together +FILENAME: gram.y +FUNCNAME: insertSelectOptions +== 074 +-- should fail +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 50 + FETCH FIRST 2 ROW WITH TIES +-- +ERROR: WITH TIES cannot be specified without ORDER BY clause +FILENAME: gram.y +FUNCNAME: insertSelectOptions +== 075 +-- test ruleutils +CREATE VIEW limit_thousand_v_1 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST 5 ROWS WITH TIES OFFSET 10 +-- +TABLE: name="limit_thousand_v_1" schema="" table="limit_thousand_v_1" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +== 076 +CREATE VIEW limit_thousand_v_2 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand OFFSET 10 FETCH FIRST 5 ROWS ONLY +-- +TABLE: name="limit_thousand_v_2" schema="" table="limit_thousand_v_2" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +== 077 +CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST NULL ROWS WITH TIES +-- +TABLE: name="limit_thousand_v_3" schema="" table="limit_thousand_v_3" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +== 078 +-- fails +CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST (NULL+1) ROWS WITH TIES +-- +TABLE: name="limit_thousand_v_3" schema="" table="limit_thousand_v_3" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +== 079 +CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST (5::bigint) ROWS WITH TIES +-- +TABLE: name="limit_thousand_v_4" schema="" table="limit_thousand_v_4" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +== 080 +CREATE VIEW limit_thousand_v_5 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST NULL ROWS ONLY +-- +TABLE: name="limit_thousand_v_5" schema="" table="limit_thousand_v_5" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/line.metadata.json b/parser/testdata/summary/postgres_regress/line.metadata.json new file mode 100644 index 0000000..bfeb57a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/line.metadata.json @@ -0,0 +1,39 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035" + ] +} diff --git a/parser/testdata/summary/postgres_regress/line.test b/parser/testdata/summary/postgres_regress/line.test new file mode 100644 index 0000000..00f1f3d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/line.test @@ -0,0 +1,212 @@ +== 001 +|-- +-- LINE +-- Infinite lines +|-- + +--DROP TABLE LINE_TBL; +CREATE TABLE LINE_TBL (s line) +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO LINE_TBL VALUES ('{0,-1,5}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +-- A == 0 +INSERT INTO LINE_TBL VALUES ('{1,0,5}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +-- B == 0 +INSERT INTO LINE_TBL VALUES ('{0,3,0}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +-- A == C == 0 +INSERT INTO LINE_TBL VALUES (' (0,0), (6,6)') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO LINE_TBL VALUES ('10,-10 ,-5,-4') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO LINE_TBL VALUES ('[-1e6,2e2,3e5, -4e1]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO LINE_TBL VALUES ('{3,NaN,5}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO LINE_TBL VALUES ('{NaN,NaN,NaN}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +-- horizontal +INSERT INTO LINE_TBL VALUES ('[(1,3),(2,3)]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +-- vertical +INSERT INTO LINE_TBL VALUES (line(point '(3,1)', point '(3,2)')) +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +FUNCTION: name="line" function="line" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 012 +-- bad values for parser testing +INSERT INTO LINE_TBL VALUES ('{}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO LINE_TBL VALUES ('{0') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO LINE_TBL VALUES ('{0,0}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO LINE_TBL VALUES ('{0,0,1') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO LINE_TBL VALUES ('{0,0,1}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO LINE_TBL VALUES ('{0,0,1} x') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO LINE_TBL VALUES ('[1,2,3, 4') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO LINE_TBL VALUES ('[(,2),(3,4)]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO LINE_TBL VALUES ('[(1,2),(1,2)]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO LINE_TBL VALUES (line(point '(1,0)', point '(1,0)')) +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +FUNCTION: name="line" function="line" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 024 +select * from LINE_TBL +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +STMT: SelectStmt +== 025 +select '{nan, 1, nan}'::line = '{nan, 1, nan}'::line as true, + '{nan, 1, nan}'::line = '{nan, 2, nan}'::line as false +-- +STMT: SelectStmt +== 026 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('{1, 1}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT * FROM pg_input_error_info('{1, 1}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT pg_input_is_valid('{0, 0, 0}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT * FROM pg_input_error_info('{0, 0, 0}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT pg_input_is_valid('{1, 1, a}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT * FROM pg_input_error_info('{1, 1, a}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT pg_input_is_valid('{1, 1, 1e400}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT * FROM pg_input_error_info('{1, 1, 1e400}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT * FROM pg_input_error_info('(1, 1), (1, 1e400)', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/lock.metadata.json b/parser/testdata/summary/postgres_regress/lock.metadata.json new file mode 100644 index 0000000..507be8d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/lock.metadata.json @@ -0,0 +1,135 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131" + ] +} diff --git a/parser/testdata/summary/postgres_regress/lock.test b/parser/testdata/summary/postgres_regress/lock.test new file mode 100644 index 0000000..db41453 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/lock.test @@ -0,0 +1,725 @@ +== 001 +|-- +-- Test the LOCK statement +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +-- Setup +CREATE SCHEMA lock_schema1 +-- +STMT: CreateSchemaStmt +== 002 +SET search_path = lock_schema1 +-- +STMT: VariableSetStmt +== 003 +CREATE TABLE lock_tbl1 (a BIGINT) +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE lock_tbl1a (a BIGINT) +-- +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=DDL +STMT: CreateStmt +== 005 +CREATE VIEW lock_view1 AS SELECT * FROM lock_tbl1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 006 +CREATE VIEW lock_view2(a,b) AS SELECT * FROM lock_tbl1, lock_tbl1a +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 007 +CREATE VIEW lock_view3 AS SELECT * from lock_view2 +-- +TABLE: name="lock_view3" schema="" table="lock_view3" ctx=DDL +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 008 +CREATE VIEW lock_view4 AS SELECT (select a from lock_tbl1a limit 1) from lock_tbl1 +-- +TABLE: name="lock_view4" schema="" table="lock_view4" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 009 +CREATE VIEW lock_view5 AS SELECT * from lock_tbl1 where a in (select * from lock_tbl1a) +-- +TABLE: name="lock_view5" schema="" table="lock_view5" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 010 +CREATE VIEW lock_view6 AS SELECT * from (select * from lock_tbl1) sub +-- +TABLE: name="lock_view6" schema="" table="lock_view6" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 011 +CREATE ROLE regress_rol_lock1 +-- +STMT: CreateRoleStmt +== 012 +ALTER ROLE regress_rol_lock1 SET search_path = lock_schema1 +-- +STMT: AlterRoleSetStmt +== 013 +GRANT USAGE ON SCHEMA lock_schema1 TO regress_rol_lock1 +-- +STMT: GrantStmt +== 014 +-- Try all valid lock options; also try omitting the optional TABLE keyword. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 015 +LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 016 +LOCK lock_tbl1 IN ROW SHARE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 017 +LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 018 +LOCK TABLE lock_tbl1 IN SHARE UPDATE EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 019 +LOCK TABLE lock_tbl1 IN SHARE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 020 +LOCK lock_tbl1 IN SHARE ROW EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 021 +LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 022 +LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 023 +ROLLBACK +-- +STMT: TransactionStmt +== 024 +-- Try using NOWAIT along with valid options. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 025 +LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 026 +LOCK TABLE lock_tbl1 IN ROW SHARE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 027 +LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 028 +LOCK TABLE lock_tbl1 IN SHARE UPDATE EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 029 +LOCK TABLE lock_tbl1 IN SHARE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 030 +LOCK TABLE lock_tbl1 IN SHARE ROW EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 031 +LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 032 +LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 033 +ROLLBACK +-- +STMT: TransactionStmt +== 034 +-- Verify that we can lock views. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 035 +LOCK TABLE lock_view1 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: LockStmt +== 036 +-- lock_view1 and lock_tbl1 are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 037 +ROLLBACK +-- +STMT: TransactionStmt +== 038 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 039 +LOCK TABLE lock_view2 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +STMT: LockStmt +== 040 +-- lock_view1, lock_tbl1, and lock_tbl1a are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 041 +ROLLBACK +-- +STMT: TransactionStmt +== 042 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 043 +LOCK TABLE lock_view3 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view3" schema="" table="lock_view3" ctx=DDL +STMT: LockStmt +== 044 +-- lock_view3, lock_view2, lock_tbl1, and lock_tbl1a are locked recursively. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 045 +ROLLBACK +-- +STMT: TransactionStmt +== 046 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 047 +LOCK TABLE lock_view4 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view4" schema="" table="lock_view4" ctx=DDL +STMT: LockStmt +== 048 +-- lock_view4, lock_tbl1, and lock_tbl1a are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 049 +ROLLBACK +-- +STMT: TransactionStmt +== 050 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 051 +LOCK TABLE lock_view5 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view5" schema="" table="lock_view5" ctx=DDL +STMT: LockStmt +== 052 +-- lock_view5, lock_tbl1, and lock_tbl1a are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 053 +ROLLBACK +-- +STMT: TransactionStmt +== 054 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 055 +LOCK TABLE lock_view6 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view6" schema="" table="lock_view6" ctx=DDL +STMT: LockStmt +== 056 +-- lock_view6 an lock_tbl1 are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 057 +ROLLBACK +-- +STMT: TransactionStmt +== 058 +-- Verify that we cope with infinite recursion in view definitions. +CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3 +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +TABLE: name="lock_view3" schema="" table="lock_view3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 059 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 060 +LOCK TABLE lock_view2 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +STMT: LockStmt +== 061 +ROLLBACK +-- +STMT: TransactionStmt +== 062 +CREATE VIEW lock_view7 AS SELECT * from lock_view2 +-- +TABLE: name="lock_view7" schema="" table="lock_view7" ctx=DDL +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 063 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 064 +LOCK TABLE lock_view7 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view7" schema="" table="lock_view7" ctx=DDL +STMT: LockStmt +== 065 +ROLLBACK +-- +STMT: TransactionStmt +== 066 +-- Verify that we can lock a table with inheritance children. +CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1) +-- +TABLE: name="lock_tbl2" schema="" table="lock_tbl2" ctx=DDL +STMT: CreateStmt +== 067 +CREATE TABLE lock_tbl3 () INHERITS (lock_tbl2) +-- +TABLE: name="lock_tbl3" schema="" table="lock_tbl3" ctx=DDL +STMT: CreateStmt +== 068 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 069 +LOCK TABLE lock_tbl1 * IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 070 +ROLLBACK +-- +STMT: TransactionStmt +== 071 +-- Child tables are locked without granting explicit permission to do so as +-- long as we have permission to lock the parent. +GRANT UPDATE ON TABLE lock_tbl1 TO regress_rol_lock1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: GrantStmt +== 072 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +== 073 +-- fail when child locked directly +BEGIN +-- +STMT: TransactionStmt +== 074 +LOCK TABLE lock_tbl2 +-- +TABLE: name="lock_tbl2" schema="" table="lock_tbl2" ctx=DDL +STMT: LockStmt +== 075 +ROLLBACK +-- +STMT: TransactionStmt +== 076 +BEGIN +-- +STMT: TransactionStmt +== 077 +LOCK TABLE lock_tbl1 * IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 078 +ROLLBACK +-- +STMT: TransactionStmt +== 079 +BEGIN +-- +STMT: TransactionStmt +== 080 +LOCK TABLE ONLY lock_tbl1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +== 081 +ROLLBACK +-- +STMT: TransactionStmt +== 082 +RESET ROLE +-- +STMT: VariableSetStmt +== 083 +REVOKE UPDATE ON TABLE lock_tbl1 FROM regress_rol_lock1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: GrantStmt +== 084 +-- Tables referred to by views are locked without explicit permission to do so +-- as long as we have permission to lock the view itself. +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +== 085 +-- fail without permissions on the view +BEGIN +-- +STMT: TransactionStmt +== 086 +LOCK TABLE lock_view1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: LockStmt +== 087 +ROLLBACK +-- +STMT: TransactionStmt +== 088 +RESET ROLE +-- +STMT: VariableSetStmt +== 089 +GRANT UPDATE ON TABLE lock_view1 TO regress_rol_lock1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: GrantStmt +== 090 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +== 091 +BEGIN +-- +STMT: TransactionStmt +== 092 +LOCK TABLE lock_view1 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: LockStmt +== 093 +-- lock_view1 and lock_tbl1 (plus children lock_tbl2 and lock_tbl3) are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'AccessExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 094 +ROLLBACK +-- +STMT: TransactionStmt +== 095 +RESET ROLE +-- +STMT: VariableSetStmt +== 096 +REVOKE UPDATE ON TABLE lock_view1 FROM regress_rol_lock1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: GrantStmt +== 097 +-- Tables referred to by security invoker views require explicit permission to +-- be locked. +CREATE VIEW lock_view8 WITH (security_invoker) AS SELECT * FROM lock_tbl1 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 098 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +== 099 +-- fail without permissions on the view +BEGIN +-- +STMT: TransactionStmt +== 100 +LOCK TABLE lock_view8 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: LockStmt +== 101 +ROLLBACK +-- +STMT: TransactionStmt +== 102 +RESET ROLE +-- +STMT: VariableSetStmt +== 103 +GRANT UPDATE ON TABLE lock_view8 TO regress_rol_lock1 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: GrantStmt +== 104 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +== 105 +-- fail without permissions on the table referenced by the view +BEGIN +-- +STMT: TransactionStmt +== 106 +LOCK TABLE lock_view8 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: LockStmt +== 107 +ROLLBACK +-- +STMT: TransactionStmt +== 108 +RESET ROLE +-- +STMT: VariableSetStmt +== 109 +GRANT UPDATE ON TABLE lock_tbl1 TO regress_rol_lock1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: GrantStmt +== 110 +BEGIN +-- +STMT: TransactionStmt +== 111 +LOCK TABLE lock_view8 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: LockStmt +== 112 +-- lock_view8 and lock_tbl1 (plus children lock_tbl2 and lock_tbl3) are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'AccessExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 113 +ROLLBACK +-- +STMT: TransactionStmt +== 114 +RESET ROLE +-- +STMT: VariableSetStmt +== 115 +REVOKE UPDATE ON TABLE lock_view8 FROM regress_rol_lock1 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: GrantStmt +== 116 +|-- +-- Clean up +|-- +DROP VIEW lock_view8 +-- +STMT: DropStmt +== 117 +DROP VIEW lock_view7 +-- +STMT: DropStmt +== 118 +DROP VIEW lock_view6 +-- +STMT: DropStmt +== 119 +DROP VIEW lock_view5 +-- +STMT: DropStmt +== 120 +DROP VIEW lock_view4 +-- +STMT: DropStmt +== 121 +DROP VIEW lock_view3 CASCADE +-- +STMT: DropStmt +== 122 +DROP VIEW lock_view1 +-- +STMT: DropStmt +== 123 +DROP TABLE lock_tbl3 +-- +TABLE: name="lock_tbl3" schema="" table="lock_tbl3" ctx=DDL +STMT: DropStmt +== 124 +DROP TABLE lock_tbl2 +-- +TABLE: name="lock_tbl2" schema="" table="lock_tbl2" ctx=DDL +STMT: DropStmt +== 125 +DROP TABLE lock_tbl1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: DropStmt +== 126 +DROP TABLE lock_tbl1a +-- +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=DDL +STMT: DropStmt +== 127 +DROP SCHEMA lock_schema1 CASCADE +-- +STMT: DropStmt +== 128 +DROP ROLE regress_rol_lock1 +-- +STMT: DropRoleStmt +== 129 +-- atomic ops tests +RESET search_path +-- +STMT: VariableSetStmt +== 130 +CREATE FUNCTION test_atomic_ops() + RETURNS bool + AS :'regresslib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 59 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 131 +SELECT test_atomic_ops() +-- +FUNCTION: name="test_atomic_ops" function="test_atomic_ops" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/lseg.metadata.json b/parser/testdata/summary/postgres_regress/lseg.metadata.json new file mode 100644 index 0000000..e71b2c2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/lseg.metadata.json @@ -0,0 +1,20 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016" + ] +} diff --git a/parser/testdata/summary/postgres_regress/lseg.test b/parser/testdata/summary/postgres_regress/lseg.test new file mode 100644 index 0000000..125ee1f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/lseg.test @@ -0,0 +1,107 @@ +== 001 +|-- +-- LSEG +-- Line segments +|-- + +--DROP TABLE LSEG_TBL; +CREATE TABLE LSEG_TBL (s lseg) +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO LSEG_TBL VALUES ('(0,0),(6,6)') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO LSEG_TBL VALUES ('10,-10 ,-3,-4') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO LSEG_TBL VALUES ('[-1e6,2e2,3e5, -4e1]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO LSEG_TBL VALUES (lseg(point(11, 22), point(33,44))) +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +FUNCTION: name="lseg" function="lseg" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO LSEG_TBL VALUES ('[(-10,2),(-10,3)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- vertical +INSERT INTO LSEG_TBL VALUES ('[(0,-20),(30,-20)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- horizontal +INSERT INTO LSEG_TBL VALUES ('[(NaN,1),(NaN,90)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +-- NaN + +-- bad values for parser testing +INSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO LSEG_TBL VALUES ('[1,2,3, 4') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO LSEG_TBL VALUES ('[(,2),(3,4)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +select * from LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +== 015 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('[(1,2),(3)]', 'lseg') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'lseg') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/macaddr.metadata.json b/parser/testdata/summary/postgres_regress/macaddr.metadata.json new file mode 100644 index 0000000..bfeb57a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/macaddr.metadata.json @@ -0,0 +1,39 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035" + ] +} diff --git a/parser/testdata/summary/postgres_regress/macaddr.test b/parser/testdata/summary/postgres_regress/macaddr.test new file mode 100644 index 0000000..0f9c01f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/macaddr.test @@ -0,0 +1,215 @@ +== 001 +|-- +-- macaddr +|-- + +CREATE TABLE macaddr_data (a int, b macaddr) +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO macaddr_data VALUES (1, '08:00:2b:01:02:03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO macaddr_data VALUES (2, '08-00-2b-01-02-03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO macaddr_data VALUES (3, '08002b:010203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO macaddr_data VALUES (4, '08002b-010203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO macaddr_data VALUES (5, '0800.2b01.0203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO macaddr_data VALUES (6, '0800-2b01-0203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO macaddr_data VALUES (7, '08002b010203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO macaddr_data VALUES (8, '0800:2b01:0203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +-- invalid +INSERT INTO macaddr_data VALUES (9, 'not even close') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +-- invalid + +INSERT INTO macaddr_data VALUES (10, '08:00:2b:01:02:04') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO macaddr_data VALUES (11, '08:00:2b:01:02:02') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO macaddr_data VALUES (12, '08:00:2a:01:02:03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO macaddr_data VALUES (13, '08:00:2c:01:02:03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO macaddr_data VALUES (14, '08:00:2a:01:02:04') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +SELECT * FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +== 017 +CREATE INDEX macaddr_data_btree ON macaddr_data USING btree (b) +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: IndexStmt +== 018 +CREATE INDEX macaddr_data_hash ON macaddr_data USING hash (b) +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: IndexStmt +== 019 +SELECT a, b, trunc(b) FROM macaddr_data ORDER BY 2, 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT b < '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 021 +-- true +SELECT b > '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 022 +-- false +SELECT b > '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 023 +-- false +SELECT b <= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 024 +-- true +SELECT b >= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 025 +-- false +SELECT b = '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 026 +-- true +SELECT b <> '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 027 +-- true +SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 028 +-- false + +SELECT ~b FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +== 029 +SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +== 030 +SELECT b | '01:02:03:04:05:06' FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +== 031 +DROP TABLE macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: DropStmt +== 032 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('08:00:2b:01:02:ZZ', 'macaddr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:ZZ', 'macaddr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT pg_input_is_valid('08:00:2b:01:02:', 'macaddr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:', 'macaddr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/macaddr8.metadata.json b/parser/testdata/summary/postgres_regress/macaddr8.metadata.json new file mode 100644 index 0000000..fb72ee9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/macaddr8.metadata.json @@ -0,0 +1,75 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071" + ] +} diff --git a/parser/testdata/summary/postgres_regress/macaddr8.test b/parser/testdata/summary/postgres_regress/macaddr8.test new file mode 100644 index 0000000..b934bdc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/macaddr8.test @@ -0,0 +1,418 @@ +== 001 +|-- +-- macaddr8 +|-- + +-- test various cases of valid and invalid input +-- valid +SELECT '08:00:2b:01:02:03 '::macaddr8 +-- +STMT: SelectStmt +== 002 +SELECT ' 08:00:2b:01:02:03 '::macaddr8 +-- +STMT: SelectStmt +== 003 +SELECT ' 08:00:2b:01:02:03'::macaddr8 +-- +STMT: SelectStmt +== 004 +SELECT '08:00:2b:01:02:03:04:05 '::macaddr8 +-- +STMT: SelectStmt +== 005 +SELECT ' 08:00:2b:01:02:03:04:05 '::macaddr8 +-- +STMT: SelectStmt +== 006 +SELECT ' 08:00:2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +== 007 +SELECT '123 08:00:2b:01:02:03'::macaddr8 +-- +STMT: SelectStmt +== 008 +-- invalid +SELECT '08:00:2b:01:02:03 123'::macaddr8 +-- +STMT: SelectStmt +== 009 +-- invalid +SELECT '123 08:00:2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +== 010 +-- invalid +SELECT '08:00:2b:01:02:03:04:05 123'::macaddr8 +-- +STMT: SelectStmt +== 011 +-- invalid +SELECT '08:00:2b:01:02:03:04:05:06:07'::macaddr8 +-- +STMT: SelectStmt +== 012 +-- invalid +SELECT '08-00-2b-01-02-03-04-05-06-07'::macaddr8 +-- +STMT: SelectStmt +== 013 +-- invalid +SELECT '08002b:01020304050607'::macaddr8 +-- +STMT: SelectStmt +== 014 +-- invalid +SELECT '08002b01020304050607'::macaddr8 +-- +STMT: SelectStmt +== 015 +-- invalid +SELECT '0z002b0102030405'::macaddr8 +-- +STMT: SelectStmt +== 016 +-- invalid +SELECT '08002b010203xyza'::macaddr8 +-- +STMT: SelectStmt +== 017 +-- invalid + +SELECT '08:00-2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +== 018 +-- invalid +SELECT '08:00-2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +== 019 +-- invalid +SELECT '08:00:2b:01.02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +== 020 +-- invalid +SELECT '08:00:2b:01.02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +== 021 +-- invalid + +-- test converting a MAC address to modified EUI-64 for inclusion +-- in an ipv6 address +SELECT macaddr8_set7bit('00:08:2b:01:02:03'::macaddr8) +-- +FUNCTION: name="macaddr8_set7bit" function="macaddr8_set7bit" schema="" ctx=Call +STMT: SelectStmt +== 022 +CREATE TABLE macaddr8_data (a int, b macaddr8) +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: CreateStmt +== 023 +INSERT INTO macaddr8_data VALUES (1, '08:00:2b:01:02:03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO macaddr8_data VALUES (2, '08-00-2b-01-02-03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO macaddr8_data VALUES (3, '08002b:010203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO macaddr8_data VALUES (4, '08002b-010203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO macaddr8_data VALUES (5, '0800.2b01.0203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO macaddr8_data VALUES (6, '0800-2b01-0203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO macaddr8_data VALUES (7, '08002b010203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO macaddr8_data VALUES (8, '0800:2b01:0203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO macaddr8_data VALUES (9, 'not even close') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +-- invalid + +INSERT INTO macaddr8_data VALUES (10, '08:00:2b:01:02:04') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO macaddr8_data VALUES (11, '08:00:2b:01:02:02') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO macaddr8_data VALUES (12, '08:00:2a:01:02:03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO macaddr8_data VALUES (13, '08:00:2c:01:02:03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO macaddr8_data VALUES (14, '08:00:2a:01:02:04') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO macaddr8_data VALUES (15, '08:00:2b:01:02:03:04:05') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO macaddr8_data VALUES (16, '08-00-2b-01-02-03-04-05') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO macaddr8_data VALUES (17, '08002b:0102030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO macaddr8_data VALUES (18, '08002b-0102030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO macaddr8_data VALUES (19, '0800.2b01.0203.0405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO macaddr8_data VALUES (20, '08002b01:02030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO macaddr8_data VALUES (21, '08002b0102030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +SELECT * FROM macaddr8_data ORDER BY 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +== 045 +CREATE INDEX macaddr8_data_btree ON macaddr8_data USING btree (b) +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: IndexStmt +== 046 +CREATE INDEX macaddr8_data_hash ON macaddr8_data USING hash (b) +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: IndexStmt +== 047 +SELECT a, b, trunc(b) FROM macaddr8_data ORDER BY 2, 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT b < '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 049 +-- true +SELECT b > '08:00:2b:ff:fe:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 050 +-- false +SELECT b > '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 051 +-- false +SELECT b::macaddr <= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 052 +-- true +SELECT b::macaddr >= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 053 +-- false +SELECT b = '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 054 +-- true +SELECT b::macaddr <> '08:00:2b:01:02:04'::macaddr FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 055 +-- true +SELECT b::macaddr <> '08:00:2b:01:02:03'::macaddr FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 056 +-- false + +SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 057 +-- true +SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 058 +-- false +SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 059 +-- false +SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 060 +-- true +SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 061 +-- false +SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 062 +-- true +SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 063 +-- true +SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 064 +-- false + +SELECT ~b FROM macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +== 065 +SELECT b & '00:00:00:ff:ff:ff' FROM macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +== 066 +SELECT b | '01:02:03:04:05:06' FROM macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +== 067 +DROP TABLE macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: DropStmt +== 068 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:ZZ', 'macaddr8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:', 'macaddr8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/maintain_every.metadata.json b/parser/testdata/summary/postgres_regress/maintain_every.metadata.json new file mode 100644 index 0000000..e71b2c2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/maintain_every.metadata.json @@ -0,0 +1,20 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016" + ] +} diff --git a/parser/testdata/summary/postgres_regress/maintain_every.test b/parser/testdata/summary/postgres_regress/maintain_every.test new file mode 100644 index 0000000..cfadc3e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/maintain_every.test @@ -0,0 +1,86 @@ +== 001 +-- Test maintenance commands that visit every eligible relation. Run as a +-- non-superuser, to skip other users' tables. + +CREATE ROLE regress_maintain +-- +STMT: CreateRoleStmt +== 002 +SET ROLE regress_maintain +-- +STMT: VariableSetStmt +== 003 +-- Test database-wide ANALYZE ("use_own_xacts" mode) setting relhassubclass=f +-- for non-partitioning inheritance, w/ ON COMMIT DELETE ROWS building an +-- empty index. +CREATE TEMP TABLE past_inh_db_other () +-- +TABLE: name="past_inh_db_other" schema="" table="past_inh_db_other" ctx=DDL +STMT: CreateStmt +== 004 +-- need 2 tables for "use_own_xacts" +CREATE TEMP TABLE past_inh_db_parent () ON COMMIT DELETE ROWS +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +STMT: CreateStmt +== 005 +CREATE TEMP TABLE past_inh_db_child () INHERITS (past_inh_db_parent) +-- +TABLE: name="past_inh_db_child" schema="" table="past_inh_db_child" ctx=DDL +STMT: CreateStmt +== 006 +CREATE INDEX ON past_inh_db_parent ((1)) +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +STMT: IndexStmt +== 007 +ANALYZE past_inh_db_parent +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +STMT: VacuumStmt +== 008 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 009 +DROP TABLE past_inh_db_child +-- +TABLE: name="past_inh_db_child" schema="" table="past_inh_db_child" ctx=DDL +STMT: DropStmt +== 010 +SET client_min_messages = error +-- +STMT: VariableSetStmt +== 011 +-- hide WARNINGs for other users' tables +ANALYZE +-- +STMT: VacuumStmt +== 012 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 013 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 014 +DROP TABLE past_inh_db_parent, past_inh_db_other +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +TABLE: name="past_inh_db_other" schema="" table="past_inh_db_other" ctx=DDL +STMT: DropStmt +== 015 +RESET ROLE +-- +STMT: VariableSetStmt +== 016 +DROP ROLE regress_maintain +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/matview.metadata.json b/parser/testdata/summary/postgres_regress/matview.metadata.json new file mode 100644 index 0000000..784b93c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/matview.metadata.json @@ -0,0 +1,183 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179" + ] +} diff --git a/parser/testdata/summary/postgres_regress/matview.test b/parser/testdata/summary/postgres_regress/matview.test new file mode 100644 index 0000000..ca20cee --- /dev/null +++ b/parser/testdata/summary/postgres_regress/matview.test @@ -0,0 +1,1116 @@ +== 001 +-- create a table to use as a basis for views and materialized views in various combinations +CREATE TABLE mvtest_t (id int NOT NULL PRIMARY KEY, type text NOT NULL, amt numeric NOT NULL) +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO mvtest_t VALUES + (1, 'x', 2), + (2, 'x', 3), + (3, 'y', 5), + (4, 'y', 7), + (5, 'z', 11) +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +-- we want a view based on the table, too, since views present additional challenges +CREATE VIEW mvtest_tv AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type +-- +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=DDL +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 004 +SELECT * FROM mvtest_tv ORDER BY type +-- +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +STMT: SelectStmt +== 005 +-- create a materialized view with no data, and confirm correct behavior +EXPLAIN (costs off) + CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type WITH NO DATA +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 006 +CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type WITH NO DATA +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 007 +SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 008 +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +== 009 +REFRESH MATERIALIZED VIEW mvtest_tm +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +STMT: RefreshMatViewStmt +== 010 +SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 011 +CREATE UNIQUE INDEX mvtest_tm_type ON mvtest_tm (type) +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +STMT: IndexStmt +== 012 +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +== 013 +-- create various views +EXPLAIN (costs off) + CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=DDL +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 014 +CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=DDL +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 015 +SELECT * FROM mvtest_tvm +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +STMT: SelectStmt +== 016 +CREATE MATERIALIZED VIEW mvtest_tmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=DDL +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 017 +CREATE MATERIALIZED VIEW mvtest_tvmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tvm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 018 +CREATE UNIQUE INDEX mvtest_tvmm_expr ON mvtest_tvmm ((grandtot > 0)) +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: IndexStmt +== 019 +CREATE UNIQUE INDEX mvtest_tvmm_pred ON mvtest_tvmm (grandtot) WHERE grandtot < 0 +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: IndexStmt +== 020 +CREATE VIEW mvtest_tvv AS SELECT sum(totamt) AS grandtot FROM mvtest_tv +-- +TABLE: name="mvtest_tvv" schema="" table="mvtest_tvv" ctx=DDL +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 021 +EXPLAIN (costs off) + CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=DDL +TABLE: name="mvtest_tvv" schema="" table="mvtest_tvv" ctx=Select +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 022 +CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=DDL +TABLE: name="mvtest_tvv" schema="" table="mvtest_tvv" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 023 +CREATE VIEW mvtest_tvvmv AS SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvmv" schema="" table="mvtest_tvvmv" ctx=DDL +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 024 +CREATE MATERIALIZED VIEW mvtest_bb AS SELECT * FROM mvtest_tvvmv +-- +TABLE: name="mvtest_bb" schema="" table="mvtest_bb" ctx=DDL +TABLE: name="mvtest_tvvmv" schema="" table="mvtest_tvvmv" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 025 +CREATE INDEX mvtest_aa ON mvtest_bb (grandtot) +-- +TABLE: name="mvtest_bb" schema="" table="mvtest_bb" ctx=DDL +STMT: IndexStmt +== 026 +-- check that plans seem reasonable + +-- test schema behavior +CREATE SCHEMA mvtest_mvschema +-- +STMT: CreateSchemaStmt +== 027 +ALTER MATERIALIZED VIEW mvtest_tvm SET SCHEMA mvtest_mvschema +-- +STMT: AlterObjectSchemaStmt +== 028 +SET search_path = mvtest_mvschema, public +-- +STMT: VariableSetStmt +== 029 +-- modify the underlying table data +INSERT INTO mvtest_t VALUES (6, 'z', 13) +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +-- confirm pre- and post-refresh contents of fairly simple materialized views +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +== 031 +SELECT * FROM mvtest_tvm ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +STMT: SelectStmt +== 032 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tm +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +STMT: RefreshMatViewStmt +== 033 +REFRESH MATERIALIZED VIEW mvtest_tvm +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=DDL +STMT: RefreshMatViewStmt +== 034 +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +== 035 +SELECT * FROM mvtest_tvm ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +STMT: SelectStmt +== 036 +RESET search_path +-- +STMT: VariableSetStmt +== 037 +-- confirm pre- and post-refresh contents of nested materialized views +EXPLAIN (costs off) + SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 038 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 039 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 040 +SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: SelectStmt +== 041 +SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: SelectStmt +== 042 +SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: SelectStmt +== 043 +REFRESH MATERIALIZED VIEW mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=DDL +STMT: RefreshMatViewStmt +== 044 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: RefreshMatViewStmt +== 045 +REFRESH MATERIALIZED VIEW mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: RefreshMatViewStmt +== 046 +REFRESH MATERIALIZED VIEW mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=DDL +STMT: RefreshMatViewStmt +== 047 +EXPLAIN (costs off) + SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 048 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 049 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 050 +SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: SelectStmt +== 051 +SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: SelectStmt +== 052 +SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: SelectStmt +== 053 +-- test diemv when the mv does not exist +DROP MATERIALIZED VIEW IF EXISTS no_such_mv +-- +STMT: DropStmt +== 054 +-- make sure invalid combination of options is prohibited +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm WITH NO DATA +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: RefreshMatViewStmt +== 055 +-- no tuple locks on materialized views +SELECT * FROM mvtest_tvvm FOR SHARE +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: SelectStmt +== 056 +-- test join of mv and view +SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM mvtest_tm m LEFT JOIN mvtest_tv v USING (type) ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +ALIAS: "m"="mvtest_tm" +ALIAS: "v"="mvtest_tv" +STMT: SelectStmt +== 057 +-- make sure that dependencies are reported properly when they block the drop +DROP TABLE mvtest_t +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DDL +STMT: DropStmt +== 058 +-- make sure dependencies are dropped and reported +-- and make sure that transactional behavior is correct on rollback +-- incidentally leaving some interesting materialized views for pg_dump testing +BEGIN +-- +STMT: TransactionStmt +== 059 +DROP TABLE mvtest_t CASCADE +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DDL +STMT: DropStmt +== 060 +ROLLBACK +-- +STMT: TransactionStmt +== 061 +-- some additional tests not using base tables +CREATE VIEW mvtest_vt1 AS SELECT 1 moo +-- +TABLE: name="mvtest_vt1" schema="" table="mvtest_vt1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 062 +CREATE VIEW mvtest_vt2 AS SELECT moo, 2*moo FROM mvtest_vt1 UNION ALL SELECT moo, 3*moo FROM mvtest_vt1 +-- +TABLE: name="mvtest_vt2" schema="" table="mvtest_vt2" ctx=DDL +TABLE: name="mvtest_vt1" schema="" table="mvtest_vt1" ctx=Select +TABLE: name="mvtest_vt1" schema="" table="mvtest_vt1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 063 +CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM mvtest_vt2 UNION ALL SELECT moo, 3*moo FROM mvtest_vt2 +-- +TABLE: name="mv_test2" schema="" table="mv_test2" ctx=DDL +TABLE: name="mvtest_vt2" schema="" table="mvtest_vt2" ctx=Select +TABLE: name="mvtest_vt2" schema="" table="mvtest_vt2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 064 +CREATE MATERIALIZED VIEW mv_test3 AS SELECT * FROM mv_test2 WHERE moo = 12345 +-- +TABLE: name="mv_test3" schema="" table="mv_test3" ctx=DDL +TABLE: name="mv_test2" schema="" table="mv_test2" ctx=Select +FILTER: schema="" table="" column="moo" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 065 +SELECT relispopulated FROM pg_class WHERE oid = 'mv_test3'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 066 +DROP VIEW mvtest_vt1 CASCADE +-- +STMT: DropStmt +== 067 +-- test that duplicate values on unique index prevent refresh +CREATE TABLE mvtest_foo(a, b) AS VALUES(1, 10) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 068 +CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_foo +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 069 +CREATE UNIQUE INDEX ON mvtest_mv(a) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +== 070 +INSERT INTO mvtest_foo SELECT * FROM mvtest_foo +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DML +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 071 +REFRESH MATERIALIZED VIEW mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +== 072 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +== 073 +DROP TABLE mvtest_foo CASCADE +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: DropStmt +== 074 +-- make sure that all columns covered by unique indexes works +CREATE TABLE mvtest_foo(a, b, c) AS VALUES(1, 2, 3) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 075 +CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_foo +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 076 +CREATE UNIQUE INDEX ON mvtest_mv (a) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +== 077 +CREATE UNIQUE INDEX ON mvtest_mv (b) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +== 078 +CREATE UNIQUE INDEX on mvtest_mv (c) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +== 079 +INSERT INTO mvtest_foo VALUES(2, 3, 4) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO mvtest_foo VALUES(3, 4, 5) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +REFRESH MATERIALIZED VIEW mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +== 082 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +== 083 +DROP TABLE mvtest_foo CASCADE +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: DropStmt +== 084 +-- allow subquery to reference unpopulated matview if WITH NO DATA is specified +CREATE MATERIALIZED VIEW mvtest_mv1 AS SELECT 1 AS col1 WITH NO DATA +-- +TABLE: name="mvtest_mv1" schema="" table="mvtest_mv1" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 085 +CREATE MATERIALIZED VIEW mvtest_mv2 AS SELECT * FROM mvtest_mv1 + WHERE col1 = (SELECT LEAST(col1) FROM mvtest_mv1) WITH NO DATA +-- +TABLE: name="mvtest_mv2" schema="" table="mvtest_mv2" ctx=DDL +TABLE: name="mvtest_mv1" schema="" table="mvtest_mv1" ctx=Select +TABLE: name="mvtest_mv1" schema="" table="mvtest_mv1" ctx=Select +FILTER: schema="" table="" column="col1" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 086 +DROP MATERIALIZED VIEW mvtest_mv1 CASCADE +-- +STMT: DropStmt +== 087 +-- make sure that types with unusual equality tests work +CREATE TABLE mvtest_boxes (id serial primary key, b box) +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DDL +STMT: CreateStmt +== 088 +INSERT INTO mvtest_boxes (b) VALUES + ('(32,32),(31,31)'), + ('(2.0000004,2.0000004),(1,1)'), + ('(1.9999996,1.9999996),(1,1)') +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +CREATE MATERIALIZED VIEW mvtest_boxmv AS SELECT * FROM mvtest_boxes +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=DDL +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 090 +CREATE UNIQUE INDEX mvtest_boxmv_id ON mvtest_boxmv (id) +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=DDL +STMT: IndexStmt +== 091 +UPDATE mvtest_boxes SET b = '(2,2),(1,1)' WHERE id = 2 +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DML +STMT: UpdateStmt +== 092 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_boxmv +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=DDL +STMT: RefreshMatViewStmt +== 093 +SELECT * FROM mvtest_boxmv ORDER BY id +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=Select +STMT: SelectStmt +== 094 +DROP TABLE mvtest_boxes CASCADE +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DDL +STMT: DropStmt +== 095 +-- make sure that column names are handled correctly +CREATE TABLE mvtest_v (i int, j int) +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +STMT: CreateStmt +== 096 +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj, kk) AS SELECT i, j FROM mvtest_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 097 +-- error +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj) AS SELECT i, j FROM mvtest_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 098 +-- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_2 (ii) AS SELECT i, j FROM mvtest_v +-- +TABLE: name="mvtest_mv_v_2" schema="" table="mvtest_mv_v_2" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 099 +-- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj, kk) AS SELECT i, j FROM mvtest_v WITH NO DATA +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 100 +-- error +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj) AS SELECT i, j FROM mvtest_v WITH NO DATA +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 101 +-- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_4 (ii) AS SELECT i, j FROM mvtest_v WITH NO DATA +-- +TABLE: name="mvtest_mv_v_4" schema="" table="mvtest_mv_v_4" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 102 +-- ok +ALTER TABLE mvtest_v RENAME COLUMN i TO x +-- +STMT: RenameStmt +== 103 +INSERT INTO mvtest_v values (1, 2) +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +CREATE UNIQUE INDEX mvtest_mv_v_ii ON mvtest_mv_v (ii) +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +STMT: IndexStmt +== 105 +REFRESH MATERIALIZED VIEW mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +STMT: RefreshMatViewStmt +== 106 +UPDATE mvtest_v SET j = 3 WHERE x = 1 +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DML +STMT: UpdateStmt +== 107 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +STMT: RefreshMatViewStmt +== 108 +REFRESH MATERIALIZED VIEW mvtest_mv_v_2 +-- +TABLE: name="mvtest_mv_v_2" schema="" table="mvtest_mv_v_2" ctx=DDL +STMT: RefreshMatViewStmt +== 109 +REFRESH MATERIALIZED VIEW mvtest_mv_v_3 +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=DDL +STMT: RefreshMatViewStmt +== 110 +REFRESH MATERIALIZED VIEW mvtest_mv_v_4 +-- +TABLE: name="mvtest_mv_v_4" schema="" table="mvtest_mv_v_4" ctx=DDL +STMT: RefreshMatViewStmt +== 111 +SELECT * FROM mvtest_v +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: SelectStmt +== 112 +SELECT * FROM mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=Select +STMT: SelectStmt +== 113 +SELECT * FROM mvtest_mv_v_2 +-- +TABLE: name="mvtest_mv_v_2" schema="" table="mvtest_mv_v_2" ctx=Select +STMT: SelectStmt +== 114 +SELECT * FROM mvtest_mv_v_3 +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=Select +STMT: SelectStmt +== 115 +SELECT * FROM mvtest_mv_v_4 +-- +TABLE: name="mvtest_mv_v_4" schema="" table="mvtest_mv_v_4" ctx=Select +STMT: SelectStmt +== 116 +DROP TABLE mvtest_v CASCADE +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +STMT: DropStmt +== 117 +-- Check that unknown literals are converted to "text" in CREATE MATVIEW, +-- so that we don't end up with unknown-type columns. +CREATE MATERIALIZED VIEW mv_unspecified_types AS + SELECT 42 as i, 42.5 as num, 'foo' as u, 'foo'::unknown as u2, null as n +-- +TABLE: name="mv_unspecified_types" schema="" table="mv_unspecified_types" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 118 +SELECT * FROM mv_unspecified_types +-- +TABLE: name="mv_unspecified_types" schema="" table="mv_unspecified_types" ctx=Select +STMT: SelectStmt +== 119 +DROP MATERIALIZED VIEW mv_unspecified_types +-- +STMT: DropStmt +== 120 +-- make sure that create WITH NO DATA does not plan the query (bug #13907) +create materialized view mvtest_error as select 1/0 as x +-- +TABLE: name="mvtest_error" schema="" table="mvtest_error" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 121 +-- fail +create materialized view mvtest_error as select 1/0 as x with no data +-- +TABLE: name="mvtest_error" schema="" table="mvtest_error" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 122 +refresh materialized view mvtest_error +-- +TABLE: name="mvtest_error" schema="" table="mvtest_error" ctx=DDL +STMT: RefreshMatViewStmt +== 123 +-- fail here +drop materialized view mvtest_error +-- +STMT: DropStmt +== 124 +-- make sure that matview rows can be referenced as source rows (bug #9398) +CREATE TABLE mvtest_v AS SELECT generate_series(1,10) AS a +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 125 +CREATE MATERIALIZED VIEW mvtest_mv_v AS SELECT a FROM mvtest_v WHERE a <= 5 +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +FILTER: schema="" table="" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 126 +DELETE FROM mvtest_v WHERE EXISTS ( SELECT * FROM mvtest_mv_v WHERE mvtest_mv_v.a = mvtest_v.a ) +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DML +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=Select +FILTER: schema="" table="mvtest_mv_v" column="a" +FILTER: schema="" table="mvtest_v" column="a" +STMT: DeleteStmt +STMT: SelectStmt +== 127 +SELECT * FROM mvtest_v +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: SelectStmt +== 128 +SELECT * FROM mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=Select +STMT: SelectStmt +== 129 +DROP TABLE mvtest_v CASCADE +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +STMT: DropStmt +== 130 +-- make sure running as superuser works when MV owned by another role (bug #11208) +CREATE ROLE regress_user_mvtest +-- +STMT: CreateRoleStmt +== 131 +SET ROLE regress_user_mvtest +-- +STMT: VariableSetStmt +== 132 +-- this test case also checks for ambiguity in the queries issued by +-- refresh_by_match_merge(), by choosing column names that intentionally +-- duplicate all the aliases used in those queries +CREATE TABLE mvtest_foo_data AS SELECT i, + i+1 AS tid, + fipshash(random()::text) AS mv, + fipshash(random()::text) AS newdata, + fipshash(random()::text) AS newdata2, + fipshash(random()::text) AS diff + FROM generate_series(1, 10) i +-- +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=DDL +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 133 +CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 134 +CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 135 +CREATE MATERIALIZED VIEW IF NOT EXISTS mvtest_mv_foo AS SELECT * FROM mvtest_foo_data +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 136 +CREATE UNIQUE INDEX ON mvtest_mv_foo (i) +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +STMT: IndexStmt +== 137 +RESET ROLE +-- +STMT: VariableSetStmt +== 138 +REFRESH MATERIALIZED VIEW mvtest_mv_foo +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +STMT: RefreshMatViewStmt +== 139 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_foo +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +STMT: RefreshMatViewStmt +== 140 +DROP OWNED BY regress_user_mvtest CASCADE +-- +STMT: DropOwnedStmt +== 141 +DROP ROLE regress_user_mvtest +-- +STMT: DropRoleStmt +== 142 +-- Concurrent refresh requires a unique index on the materialized +-- view. Test what happens if it's dropped during the refresh. +SET search_path = mvtest_mvschema, public +-- +STMT: VariableSetStmt +== 143 +CREATE OR REPLACE FUNCTION mvtest_drop_the_index() + RETURNS bool AS $$ +BEGIN + EXECUTE 'DROP INDEX IF EXISTS mvtest_mvschema.mvtest_drop_idx'; + RETURN true; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="mvtest_drop_the_index" function="mvtest_drop_the_index" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 144 +CREATE MATERIALIZED VIEW drop_idx_matview AS + SELECT 1 as i WHERE mvtest_drop_the_index() +-- +TABLE: name="drop_idx_matview" schema="" table="drop_idx_matview" ctx=DDL +FUNCTION: name="mvtest_drop_the_index" function="mvtest_drop_the_index" schema="" ctx=Call +FUNCTION: name="mvtest_drop_the_index" function="mvtest_drop_the_index" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 145 +CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i) +-- +TABLE: name="drop_idx_matview" schema="" table="drop_idx_matview" ctx=DDL +STMT: IndexStmt +== 146 +REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview +-- +TABLE: name="drop_idx_matview" schema="" table="drop_idx_matview" ctx=DDL +STMT: RefreshMatViewStmt +== 147 +DROP MATERIALIZED VIEW drop_idx_matview +-- +STMT: DropStmt +== 148 +-- clean up +RESET search_path +-- +STMT: VariableSetStmt +== 149 +-- make sure that create WITH NO DATA works via SPI +BEGIN +-- +STMT: TransactionStmt +== 150 +CREATE FUNCTION mvtest_func() + RETURNS void AS $$ +BEGIN + CREATE MATERIALIZED VIEW mvtest1 AS SELECT 1 AS x; + CREATE MATERIALIZED VIEW mvtest2 AS SELECT 1 AS x WITH NO DATA; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="mvtest_func" function="mvtest_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 151 +SELECT mvtest_func() +-- +FUNCTION: name="mvtest_func" function="mvtest_func" schema="" ctx=Call +STMT: SelectStmt +== 152 +SELECT * FROM mvtest1 +-- +TABLE: name="mvtest1" schema="" table="mvtest1" ctx=Select +STMT: SelectStmt +== 153 +SELECT * FROM mvtest2 +-- +TABLE: name="mvtest2" schema="" table="mvtest2" ctx=Select +STMT: SelectStmt +== 154 +ROLLBACK +-- +STMT: TransactionStmt +== 155 +-- INSERT privileges if relation owner is not allowed to insert. +CREATE SCHEMA matview_schema +-- +STMT: CreateSchemaStmt +== 156 +CREATE USER regress_matview_user +-- +STMT: CreateRoleStmt +== 157 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_matview_user + REVOKE INSERT ON TABLES FROM regress_matview_user +-- +STMT: AlterDefaultPrivilegesStmt +== 158 +GRANT ALL ON SCHEMA matview_schema TO public +-- +STMT: GrantStmt +== 159 +SET SESSION AUTHORIZATION regress_matview_user +-- +STMT: VariableSetStmt +== 160 +CREATE MATERIALIZED VIEW matview_schema.mv_withdata1 (a) AS + SELECT generate_series(1, 10) WITH DATA +-- +TABLE: name="matview_schema.mv_withdata1" schema="matview_schema" table="mv_withdata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 161 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_schema.mv_withdata2 (a) AS + SELECT generate_series(1, 10) WITH DATA +-- +TABLE: name="matview_schema.mv_withdata2" schema="matview_schema" table="mv_withdata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 162 +REFRESH MATERIALIZED VIEW matview_schema.mv_withdata2 +-- +TABLE: name="matview_schema.mv_withdata2" schema="matview_schema" table="mv_withdata2" ctx=DDL +STMT: RefreshMatViewStmt +== 163 +CREATE MATERIALIZED VIEW matview_schema.mv_nodata1 (a) AS + SELECT generate_series(1, 10) WITH NO DATA +-- +TABLE: name="matview_schema.mv_nodata1" schema="matview_schema" table="mv_nodata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 164 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_schema.mv_nodata2 (a) AS + SELECT generate_series(1, 10) WITH NO DATA +-- +TABLE: name="matview_schema.mv_nodata2" schema="matview_schema" table="mv_nodata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 165 +REFRESH MATERIALIZED VIEW matview_schema.mv_nodata2 +-- +TABLE: name="matview_schema.mv_nodata2" schema="matview_schema" table="mv_nodata2" ctx=DDL +STMT: RefreshMatViewStmt +== 166 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 167 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_matview_user + GRANT INSERT ON TABLES TO regress_matview_user +-- +STMT: AlterDefaultPrivilegesStmt +== 168 +DROP SCHEMA matview_schema CASCADE +-- +STMT: DropStmt +== 169 +DROP USER regress_matview_user +-- +STMT: DropRoleStmt +== 170 +-- CREATE MATERIALIZED VIEW ... IF NOT EXISTS +CREATE MATERIALIZED VIEW matview_ine_tab AS SELECT 1 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 171 +CREATE MATERIALIZED VIEW matview_ine_tab AS SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 172 +-- error +CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 173 +-- ok +CREATE MATERIALIZED VIEW matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 174 +-- error +CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 175 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_ine_tab AS + SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 176 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 177 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 178 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 179 +-- ok +DROP MATERIALIZED VIEW matview_ine_tab +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/md5.metadata.json b/parser/testdata/summary/postgres_regress/md5.metadata.json new file mode 100644 index 0000000..5a08d01 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/md5.metadata.json @@ -0,0 +1,18 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014" + ] +} diff --git a/parser/testdata/summary/postgres_regress/md5.test b/parser/testdata/summary/postgres_regress/md5.test new file mode 100644 index 0000000..b2adffc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/md5.test @@ -0,0 +1,79 @@ +== 001 +|-- +-- MD5 test suite - from IETF RFC 1321 +-- (see: https://www.rfc-editor.org/rfc/rfc1321) +|-- + +-- (The md5() function will error in OpenSSL FIPS mode. By keeping +-- this test in a separate file, it is easier to manage variant +-- results.) + +select md5('') = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 002 +select md5('a') = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 003 +select md5('abc') = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 004 +select md5('message digest') = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 005 +select md5('abcdefghijklmnopqrstuvwxyz') = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 006 +select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 007 +select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 008 +select md5(''::bytea) = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 009 +select md5('a'::bytea) = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 010 +select md5('abc'::bytea) = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 011 +select md5('message digest'::bytea) = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 012 +select md5('abcdefghijklmnopqrstuvwxyz'::bytea) = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 013 +select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'::bytea) = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +== 014 +select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890'::bytea) = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/memoize.metadata.json b/parser/testdata/summary/postgres_regress/memoize.metadata.json new file mode 100644 index 0000000..abfc1a2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/memoize.metadata.json @@ -0,0 +1,73 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069" + ] +} diff --git a/parser/testdata/summary/postgres_regress/memoize.test b/parser/testdata/summary/postgres_regress/memoize.test new file mode 100644 index 0000000..b1fa272 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/memoize.test @@ -0,0 +1,510 @@ +== 001 +-- Perform tests on the Memoize node. + +-- The cache hits/misses/evictions from the Memoize node can vary between +-- machines. Let's just replace the number with an 'N'. In order to allow us +-- to perform validation when the measure was zero, we replace a zero value +-- with "Zero". All other numbers are replaced with 'N'. +create function explain_memoize(query text, hide_hitmiss bool) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + query) + loop + if hide_hitmiss = true then + ln := regexp_replace(ln, 'Hits: 0', 'Hits: Zero'); + ln := regexp_replace(ln, 'Hits: \d+', 'Hits: N'); + ln := regexp_replace(ln, 'Misses: 0', 'Misses: Zero'); + ln := regexp_replace(ln, 'Misses: \d+', 'Misses: N'); + end if; + ln := regexp_replace(ln, 'Evictions: 0', 'Evictions: Zero'); + ln := regexp_replace(ln, 'Evictions: \d+', 'Evictions: N'); + ln := regexp_replace(ln, 'Memory Usage: \d+', 'Memory Usage: N'); + ln := regexp_replace(ln, 'Heap Fetches: \d+', 'Heap Fetches: N'); + ln := regexp_replace(ln, 'loops=\d+', 'loops=N'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +-- Ensure we get a memoize node on the inner side of the nested loop +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +== 003 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 004 +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.twenty +WHERE t2.unique1 < 1000;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 005 +-- And check we get the expected results. +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.twenty +WHERE t2.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +== 006 +-- Try with LATERAL joins +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 + WHERE t1.twenty = t2.unique1 OFFSET 0) t2 +WHERE t1.unique1 < 1000;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- And check we get the expected results. +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 + WHERE t1.twenty = t2.unique1 OFFSET 0) t2 +WHERE t1.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +== 008 +-- Try with LATERAL joins +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t2.t1two) FROM tenk1 t1 LEFT JOIN +LATERAL ( + SELECT t1.two as t1two, * FROM tenk1 t2 WHERE t2.unique1 < 4 OFFSET 0 +) t2 +ON t1.two = t2.two +WHERE t1.unique1 < 10;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- And check we get the expected results. +SELECT COUNT(*),AVG(t2.t1two) FROM tenk1 t1 LEFT JOIN +LATERAL ( + SELECT t1.two as t1two, * FROM tenk1 t2 WHERE t2.unique1 < 4 OFFSET 0 +) t2 +ON t1.two = t2.two +WHERE t1.unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +== 010 +SET enable_mergejoin TO off +-- +STMT: VariableSetStmt +== 011 +-- Test for varlena datatype with expr evaluation +CREATE TABLE expr_key (x numeric, t text) +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: CreateStmt +== 012 +INSERT INTO expr_key (x, t) +SELECT d1::numeric, d1::text FROM ( + SELECT round((d / pi())::numeric, 7) AS d1 FROM generate_series(1, 20) AS d +) t +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DML +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="pi" function="pi" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 013 +-- duplicate rows so we get some cache hits +INSERT INTO expr_key SELECT * FROM expr_key +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DML +TABLE: name="expr_key" schema="" table="expr_key" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 014 +CREATE INDEX expr_key_idx_x_t ON expr_key (x, t) +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: IndexStmt +== 015 +VACUUM ANALYZE expr_key +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: VacuumStmt +== 016 +-- Ensure we get we get a cache miss and hit for each of the 20 distinct values +SELECT explain_memoize(' +SELECT * FROM expr_key t1 INNER JOIN expr_key t2 +ON t1.x = t2.t::numeric AND t1.t::numeric = t2.x;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 017 +DROP TABLE expr_key +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: DropStmt +== 018 +-- Reduce work_mem and hash_mem_multiplier so that we see some cache evictions +SET work_mem TO '64kB' +-- +STMT: VariableSetStmt +== 019 +SET hash_mem_multiplier TO 1.0 +-- +STMT: VariableSetStmt +== 020 +-- Ensure we get some evictions. We're unable to validate the hits and misses +-- here as the number of entries that fit in the cache at once will vary +-- between different machines. +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.thousand +WHERE t2.unique1 < 1200;', true) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 021 +CREATE TABLE flt (f float) +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: CreateStmt +== 022 +CREATE INDEX flt_f_idx ON flt (f) +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: IndexStmt +== 023 +INSERT INTO flt VALUES('-0.0'::float),('+0.0'::float) +-- +TABLE: name="flt" schema="" table="flt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +ANALYZE flt +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: VacuumStmt +== 025 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +== 026 +-- Ensure memoize operates in logical mode +SELECT explain_memoize(' +SELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f = f2.f;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 027 +-- Ensure memoize operates in binary mode +SELECT explain_memoize(' +SELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f >= f2.f;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 028 +DROP TABLE flt +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: DropStmt +== 029 +-- Exercise Memoize in binary mode with a large fixed width type and a +-- varlena type. +CREATE TABLE strtest (n name, t text) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: CreateStmt +== 030 +CREATE INDEX strtest_n_idx ON strtest (n) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: IndexStmt +== 031 +CREATE INDEX strtest_t_idx ON strtest (t) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: IndexStmt +== 032 +INSERT INTO strtest VALUES('one','one'),('two','two'),('three',repeat(fipshash('three'),100)) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 033 +-- duplicate rows so we get some cache hits +INSERT INTO strtest SELECT * FROM strtest +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DML +TABLE: name="strtest" schema="" table="strtest" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 034 +ANALYZE strtest +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: VacuumStmt +== 035 +-- Ensure we get 3 hits and 3 misses +SELECT explain_memoize(' +SELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.n >= s2.n;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- Ensure we get 3 hits and 3 misses +SELECT explain_memoize(' +SELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.t >= s2.t;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 037 +DROP TABLE strtest +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: DropStmt +== 038 +-- Ensure memoize works with partitionwise join +SET enable_partitionwise_join TO on +-- +STMT: VariableSetStmt +== 039 +CREATE TABLE prt (a int) PARTITION BY RANGE(a) +-- +TABLE: name="prt" schema="" table="prt" ctx=DDL +STMT: CreateStmt +== 040 +CREATE TABLE prt_p1 PARTITION OF prt FOR VALUES FROM (0) TO (10) +-- +TABLE: name="prt_p1" schema="" table="prt_p1" ctx=DDL +STMT: CreateStmt +== 041 +CREATE TABLE prt_p2 PARTITION OF prt FOR VALUES FROM (10) TO (20) +-- +TABLE: name="prt_p2" schema="" table="prt_p2" ctx=DDL +STMT: CreateStmt +== 042 +INSERT INTO prt VALUES (0), (0), (0), (0) +-- +TABLE: name="prt" schema="" table="prt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO prt VALUES (10), (10), (10), (10) +-- +TABLE: name="prt" schema="" table="prt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +CREATE INDEX iprt_p1_a ON prt_p1 (a) +-- +TABLE: name="prt_p1" schema="" table="prt_p1" ctx=DDL +STMT: IndexStmt +== 045 +CREATE INDEX iprt_p2_a ON prt_p2 (a) +-- +TABLE: name="prt_p2" schema="" table="prt_p2" ctx=DDL +STMT: IndexStmt +== 046 +ANALYZE prt +-- +TABLE: name="prt" schema="" table="prt" ctx=DDL +STMT: VacuumStmt +== 047 +SELECT explain_memoize(' +SELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 048 +-- Ensure memoize works with parameterized union-all Append path +SET enable_partitionwise_join TO off +-- +STMT: VariableSetStmt +== 049 +SELECT explain_memoize(' +SELECT * FROM prt_p1 t1 INNER JOIN +(SELECT * FROM prt_p1 UNION ALL SELECT * FROM prt_p2) t2 +ON t1.a = t2.a;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +== 050 +DROP TABLE prt +-- +TABLE: name="prt" schema="" table="prt" ctx=DDL +STMT: DropStmt +== 051 +RESET enable_partitionwise_join +-- +STMT: VariableSetStmt +== 052 +-- Exercise Memoize code that flushes the cache when a parameter changes which +-- is not part of the cache key. + +-- Ensure we get a Memoize plan +EXPLAIN (COSTS OFF) +SELECT unique1 FROM tenk1 t0 +WHERE unique1 < 3 + AND EXISTS ( + SELECT 1 FROM tenk1 t1 + INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred + WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t0"="tenk1" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="t0" column="ten" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t0" column="two" +FILTER: schema="" table="t2" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 053 +-- Ensure the above query returns the correct result +SELECT unique1 FROM tenk1 t0 +WHERE unique1 < 3 + AND EXISTS ( + SELECT 1 FROM tenk1 t1 + INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred + WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t0"="tenk1" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="t0" column="ten" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t0" column="two" +FILTER: schema="" table="t2" column="four" +STMT: SelectStmt +== 054 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 055 +RESET enable_mergejoin +-- +STMT: VariableSetStmt +== 056 +RESET work_mem +-- +STMT: VariableSetStmt +== 057 +RESET hash_mem_multiplier +-- +STMT: VariableSetStmt +== 058 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 059 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 060 +-- Test parallel plans with Memoize +SET min_parallel_table_scan_size TO 0 +-- +STMT: VariableSetStmt +== 061 +SET parallel_setup_cost TO 0 +-- +STMT: VariableSetStmt +== 062 +SET parallel_tuple_cost TO 0 +-- +STMT: VariableSetStmt +== 063 +SET max_parallel_workers_per_gather TO 2 +-- +STMT: VariableSetStmt +== 064 +-- Ensure we get a parallel plan. +EXPLAIN (COSTS OFF) +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 WHERE t1.twenty = t2.unique1) t2 +WHERE t1.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t2" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 065 +-- And ensure the parallel plan gives us the correct results. +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 WHERE t1.twenty = t2.unique1) t2 +WHERE t1.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +== 066 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +== 067 +RESET parallel_tuple_cost +-- +STMT: VariableSetStmt +== 068 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +== 069 +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/merge.metadata.json b/parser/testdata/summary/postgres_regress/merge.metadata.json new file mode 100644 index 0000000..168c3f9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/merge.metadata.json @@ -0,0 +1,576 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572" + ] +} diff --git a/parser/testdata/summary/postgres_regress/merge.test b/parser/testdata/summary/postgres_regress/merge.test new file mode 100644 index 0000000..15bb434 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/merge.test @@ -0,0 +1,4075 @@ +== 001 +|-- +-- MERGE +|-- + +CREATE USER regress_merge_privs +-- +STMT: CreateRoleStmt +== 002 +CREATE USER regress_merge_no_privs +-- +STMT: CreateRoleStmt +== 003 +CREATE USER regress_merge_none +-- +STMT: CreateRoleStmt +== 004 +DROP TABLE IF EXISTS target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: DropStmt +== 005 +DROP TABLE IF EXISTS source +-- +TABLE: name="source" schema="" table="source" ctx=DDL +STMT: DropStmt +== 006 +CREATE TABLE target (tid integer, balance integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateStmt +== 007 +CREATE TABLE source (sid integer, delta integer) -- no index + WITH (autovacuum_enabled=off) +-- +TABLE: name="source" schema="" table="source" ctx=DDL +STMT: CreateStmt +== 008 +INSERT INTO target VALUES (1, 10) +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO target VALUES (2, 20) +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO target VALUES (3, 30) +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +SELECT t.ctid is not null as matched, t.*, s.* FROM source s FULL OUTER JOIN target t ON s.sid = t.tid ORDER BY t.tid, s.sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +TABLE: name="target" schema="" table="target" ctx=Select +ALIAS: "s"="source" +ALIAS: "t"="target" +STMT: SelectStmt +== 012 +ALTER TABLE target OWNER TO regress_merge_privs +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +== 013 +ALTER TABLE source OWNER TO regress_merge_privs +-- +TABLE: name="source" schema="" table="source" ctx=DDL +STMT: AlterTableStmt +== 014 +CREATE TABLE target2 (tid integer, balance integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: CreateStmt +== 015 +CREATE TABLE source2 (sid integer, delta integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="source2" schema="" table="source2" ctx=DDL +STMT: CreateStmt +== 016 +ALTER TABLE target2 OWNER TO regress_merge_no_privs +-- +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: AlterTableStmt +== 017 +ALTER TABLE source2 OWNER TO regress_merge_no_privs +-- +TABLE: name="source2" schema="" table="source2" ctx=DDL +STMT: AlterTableStmt +== 018 +GRANT INSERT ON target TO regress_merge_no_privs +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: GrantStmt +== 019 +SET SESSION AUTHORIZATION regress_merge_privs +-- +STMT: VariableSetStmt +== 020 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +== 021 +|-- +-- Errors +|-- +MERGE INTO target t RANDOMWORD +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +ERROR: syntax error at or near "RANDOMWORD" +CURSORPOS: 37 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 022 +-- MATCHED/INSERT error +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + INSERT DEFAULT VALUES +-- +ERROR: syntax error at or near "INSERT" +CURSORPOS: 99 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 023 +-- NOT MATCHED BY SOURCE/INSERT error +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE THEN + INSERT DEFAULT VALUES +-- +ERROR: syntax error at or near "INSERT" +CURSORPOS: 127 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +-- incorrectly specifying INTO target +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT INTO target DEFAULT VALUES +-- +ERROR: syntax error at or near "INTO" +CURSORPOS: 124 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 025 +-- Multiple VALUES clause +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (1,1), (2,2) +-- +ERROR: syntax error at or near "," +CURSORPOS: 124 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +-- SELECT query for INSERT +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT SELECT (1, 1) +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 113 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 027 +-- NOT MATCHED/UPDATE +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + UPDATE SET balance = 0 +-- +ERROR: syntax error at or near "UPDATE" +CURSORPOS: 101 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 028 +-- NOT MATCHED BY TARGET/UPDATE +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED BY TARGET THEN + UPDATE SET balance = 0 +-- +ERROR: syntax error at or near "UPDATE" +CURSORPOS: 121 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +-- UPDATE tablename +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE target SET balance = 0 +-- +ERROR: syntax error at or near "target" +CURSORPOS: 102 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 030 +-- source and target names the same +MERGE INTO target +USING target +ON tid = tid +WHEN MATCHED THEN DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +== 031 +-- used in a CTE without RETURNING +WITH foo AS ( + MERGE INTO target USING source ON (true) + WHEN MATCHED THEN DELETE +) SELECT * FROM foo +-- +TABLE: name="target" schema="" table="target" ctx=DML +CTE: "foo" +STMT: SelectStmt +STMT: MergeStmt +== 032 +-- used in COPY without RETURNING +COPY ( + MERGE INTO target USING source ON (true) + WHEN MATCHED THEN DELETE +) TO stdout +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: CopyStmt +== 033 +-- unsupported relation types +-- materialized view +CREATE MATERIALIZED VIEW mv AS SELECT * FROM target +-- +TABLE: name="mv" schema="" table="mv" ctx=DDL +TABLE: name="target" schema="" table="target" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 034 +MERGE INTO mv t +USING source s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="mv" schema="" table="mv" ctx=DML +ALIAS: "t"="mv" +STMT: MergeStmt +== 035 +DROP MATERIALIZED VIEW mv +-- +STMT: DropStmt +== 036 +-- permissions + +SET SESSION AUTHORIZATION regress_merge_none +-- +STMT: VariableSetStmt +== 037 +MERGE INTO target +USING (SELECT 1) +ON true +WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +STMT: SelectStmt +== 038 +SET SESSION AUTHORIZATION regress_merge_privs +-- +STMT: VariableSetStmt +== 039 +MERGE INTO target +USING source2 +ON target.tid = source2.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +== 040 +GRANT INSERT ON target TO regress_merge_no_privs +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: GrantStmt +== 041 +SET SESSION AUTHORIZATION regress_merge_no_privs +-- +STMT: VariableSetStmt +== 042 +MERGE INTO target +USING source2 +ON target.tid = source2.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +== 043 +GRANT UPDATE ON target2 TO regress_merge_privs +-- +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: GrantStmt +== 044 +SET SESSION AUTHORIZATION regress_merge_privs +-- +STMT: VariableSetStmt +== 045 +MERGE INTO target2 +USING source +ON target2.tid = source.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target2" schema="" table="target2" ctx=DML +STMT: MergeStmt +== 046 +MERGE INTO target2 +USING source +ON target2.tid = source.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target2" schema="" table="target2" ctx=DML +STMT: MergeStmt +== 047 +-- check if the target can be accessed from source relation subquery; we should +-- not be able to do so +MERGE INTO target t +USING (SELECT * FROM source WHERE t.tid > sid) s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="t" column="tid" +FILTER: schema="" table="" column="sid" +STMT: MergeStmt +STMT: SelectStmt +== 048 +|-- +-- initial tests +|-- +-- zero rows in source has no effect +MERGE INTO target +USING source +ON target.tid = source.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +== 049 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 050 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 051 +BEGIN +-- +STMT: TransactionStmt +== 052 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 053 +ROLLBACK +-- +STMT: TransactionStmt +== 054 +-- insert some non-matching source rows to work from +INSERT INTO source VALUES (4, 40) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +== 056 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 057 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 058 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 059 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 060 +BEGIN +-- +STMT: TransactionStmt +== 061 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 062 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 063 +ROLLBACK +-- +STMT: TransactionStmt +== 064 +-- DELETE/INSERT not matched by source/target +BEGIN +-- +STMT: TransactionStmt +== 065 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE THEN + DELETE +WHEN NOT MATCHED BY TARGET THEN + INSERT VALUES (s.sid, s.delta) +RETURNING merge_action(), t.* +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 066 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 067 +ROLLBACK +-- +STMT: TransactionStmt +== 068 +-- index plans +INSERT INTO target SELECT generate_series(1000,2500), 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 069 +ALTER TABLE target ADD PRIMARY KEY (tid) +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +== 070 +ANALYZE target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: VacuumStmt +== 071 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +== 072 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +== 073 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, NULL) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +== 074 +DELETE FROM target WHERE tid > 100 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: DeleteStmt +== 075 +ANALYZE target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: VacuumStmt +== 076 +-- insert some matching source rows to work from +INSERT INTO source VALUES (2, 5) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +INSERT INTO source VALUES (3, 20) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +== 079 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 080 +-- equivalent of an UPDATE join +BEGIN +-- +STMT: TransactionStmt +== 081 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 082 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 083 +ROLLBACK +-- +STMT: TransactionStmt +== 084 +-- equivalent of a DELETE join +BEGIN +-- +STMT: TransactionStmt +== 085 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 086 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 087 +ROLLBACK +-- +STMT: TransactionStmt +== 088 +BEGIN +-- +STMT: TransactionStmt +== 089 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 090 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 091 +ROLLBACK +-- +STMT: TransactionStmt +== 092 +BEGIN +-- +STMT: TransactionStmt +== 093 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, NULL) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 094 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 095 +ROLLBACK +-- +STMT: TransactionStmt +== 096 +-- duplicate source row causes multiple target row update ERROR +INSERT INTO source VALUES (2, 5) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +== 098 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 099 +BEGIN +-- +STMT: TransactionStmt +== 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 101 +ROLLBACK +-- +STMT: TransactionStmt +== 102 +BEGIN +-- +STMT: TransactionStmt +== 103 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 104 +ROLLBACK +-- +STMT: TransactionStmt +== 105 +-- remove duplicate MATCHED data from source data +DELETE FROM source WHERE sid = 2 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +== 106 +INSERT INTO source VALUES (2, 5) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +== 108 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 109 +-- duplicate source row on INSERT should fail because of target_pkey +INSERT INTO source VALUES (4, 40) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +BEGIN +-- +STMT: TransactionStmt +== 111 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, NULL) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 112 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 113 +ROLLBACK +-- +STMT: TransactionStmt +== 114 +-- remove duplicate NOT MATCHED data from source data +DELETE FROM source WHERE sid = 4 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +== 115 +INSERT INTO source VALUES (4, 40) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +== 117 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 118 +-- remove constraints +alter table target drop CONSTRAINT target_pkey +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +== 119 +alter table target alter column tid drop not null +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +== 120 +-- multiple actions +BEGIN +-- +STMT: TransactionStmt +== 121 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, 4) +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 122 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 123 +ROLLBACK +-- +STMT: TransactionStmt +== 124 +-- should be equivalent +BEGIN +-- +STMT: TransactionStmt +== 125 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +WHEN NOT MATCHED THEN + INSERT VALUES (4, 4) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 126 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 127 +ROLLBACK +-- +STMT: TransactionStmt +== 128 +-- column references +-- do a simple equivalent of an UPDATE join +BEGIN +-- +STMT: TransactionStmt +== 129 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = t.balance + s.delta +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 130 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 131 +ROLLBACK +-- +STMT: TransactionStmt +== 132 +-- do a simple equivalent of an INSERT SELECT +BEGIN +-- +STMT: TransactionStmt +== 133 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 134 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 135 +ROLLBACK +-- +STMT: TransactionStmt +== 136 +-- and again with duplicate source rows +INSERT INTO source VALUES (5, 50) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +INSERT INTO source VALUES (5, 50) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +-- do a simple equivalent of an INSERT SELECT +BEGIN +-- +STMT: TransactionStmt +== 139 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 140 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 141 +ROLLBACK +-- +STMT: TransactionStmt +== 142 +-- removing duplicate source rows +DELETE FROM source WHERE sid = 5 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +== 143 +-- and again with explicitly identified column list +BEGIN +-- +STMT: TransactionStmt +== 144 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 145 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 146 +ROLLBACK +-- +STMT: TransactionStmt +== 147 +-- and again with a subtle error: referring to non-existent target row for NOT MATCHED +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (t.tid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 148 +-- and again with a constant ON clause +BEGIN +-- +STMT: TransactionStmt +== 149 +MERGE INTO target t +USING source AS s +ON (SELECT true) +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (t.tid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +STMT: SelectStmt +== 150 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 151 +ROLLBACK +-- +STMT: TransactionStmt +== 152 +-- now the classic UPSERT +BEGIN +-- +STMT: TransactionStmt +== 153 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = t.balance + s.delta +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 154 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 155 +ROLLBACK +-- +STMT: TransactionStmt +== 156 +-- unreachable WHEN clause should ERROR +BEGIN +-- +STMT: TransactionStmt +== 157 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN /* Terminal WHEN clause for MATCHED */ + DELETE +WHEN MATCHED THEN + UPDATE SET balance = t.balance - s.delta +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 158 +ROLLBACK +-- +STMT: TransactionStmt +== 159 +-- conditional WHEN clause +CREATE TABLE wq_target (tid integer not null, balance integer DEFAULT -1) + WITH (autovacuum_enabled=off) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DDL +STMT: CreateStmt +== 160 +CREATE TABLE wq_source (balance integer, sid integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="wq_source" schema="" table="wq_source" ctx=DDL +STMT: CreateStmt +== 161 +INSERT INTO wq_source (sid, balance) VALUES (1, 100) +-- +TABLE: name="wq_source" schema="" table="wq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +BEGIN +-- +STMT: TransactionStmt +== 163 +-- try a simple INSERT with default values first +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 164 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 165 +ROLLBACK +-- +STMT: TransactionStmt +== 166 +-- this time with a FALSE condition +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND FALSE THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 167 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 168 +-- this time with an actual condition which returns false +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND s.balance <> 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 169 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 170 +BEGIN +-- +STMT: TransactionStmt +== 171 +-- and now with a condition which returns true +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND s.balance = 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 172 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 173 +ROLLBACK +-- +STMT: TransactionStmt +== 174 +-- conditions in the NOT MATCHED clause can only refer to source columns +BEGIN +-- +STMT: TransactionStmt +== 175 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND t.balance = 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 176 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 177 +ROLLBACK +-- +STMT: TransactionStmt +== 178 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND s.balance = 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 179 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 180 +-- conditions in NOT MATCHED BY SOURCE clause can only refer to target columns +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE AND s.balance = 100 THEN + DELETE +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 181 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE AND t.balance = 100 THEN + DELETE +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 182 +-- conditions in MATCHED clause can refer to both source and target +SELECT * FROM wq_source +-- +TABLE: name="wq_source" schema="" table="wq_source" ctx=Select +STMT: SelectStmt +== 183 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND s.balance = 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 184 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 185 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 186 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 187 +-- check if AND works +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 99 AND s.balance > 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 188 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 189 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 99 AND s.balance = 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 190 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 191 +-- check if OR works +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 99 OR s.balance > 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 192 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 193 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 199 OR s.balance > 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 194 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 195 +-- check source-side whole-row references +BEGIN +-- +STMT: TransactionStmt +== 196 +MERGE INTO wq_target t +USING wq_source s ON (t.tid = s.sid) +WHEN matched and t = s or t.tid = s.sid THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 197 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 198 +ROLLBACK +-- +STMT: TransactionStmt +== 199 +-- check if subqueries work in the conditions? +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance > (SELECT max(balance) FROM target) THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +TABLE: name="target" schema="" table="target" ctx=Select +ALIAS: "t"="wq_target" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 200 +-- check if we can access system columns in the conditions +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.xmin = t.xmax THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 201 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.tableoid >= 0 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +== 202 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +== 203 +DROP TABLE wq_target, wq_source +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DDL +TABLE: name="wq_source" schema="" table="wq_source" ctx=DDL +STMT: DropStmt +== 204 +-- test triggers +create or replace function merge_trigfunc () returns trigger +language plpgsql as +$$ +DECLARE + line text; +BEGIN + SELECT INTO line format('%s %s %s trigger%s', + TG_WHEN, TG_OP, TG_LEVEL, CASE + WHEN TG_OP = 'INSERT' AND TG_LEVEL = 'ROW' + THEN format(' row: %s', NEW) + WHEN TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW' + THEN format(' row: %s -> %s', OLD, NEW) + WHEN TG_OP = 'DELETE' AND TG_LEVEL = 'ROW' + THEN format(' row: %s', OLD) + END); + + RAISE NOTICE '%', line; + IF (TG_WHEN = 'BEFORE' AND TG_LEVEL = 'ROW') THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + ELSE + RETURN NULL; + END IF; +END; +$$ +-- +FUNCTION: name="merge_trigfunc" function="merge_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 205 +CREATE TRIGGER merge_bsi BEFORE INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 206 +CREATE TRIGGER merge_bsu BEFORE UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 207 +CREATE TRIGGER merge_bsd BEFORE DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 208 +CREATE TRIGGER merge_asi AFTER INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 209 +CREATE TRIGGER merge_asu AFTER UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 210 +CREATE TRIGGER merge_asd AFTER DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 211 +CREATE TRIGGER merge_bri BEFORE INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 212 +CREATE TRIGGER merge_bru BEFORE UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 213 +CREATE TRIGGER merge_brd BEFORE DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 214 +CREATE TRIGGER merge_ari AFTER INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 215 +CREATE TRIGGER merge_aru AFTER UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 216 +CREATE TRIGGER merge_ard AFTER DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 217 +-- now the classic UPSERT, with a DELETE +BEGIN +-- +STMT: TransactionStmt +== 218 +UPDATE target SET balance = 0 WHERE tid = 3 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: UpdateStmt +== 219 +--EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND t.balance > s.delta THEN + UPDATE SET balance = t.balance - s.delta +WHEN MATCHED THEN + DELETE +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 220 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 221 +ROLLBACK +-- +STMT: TransactionStmt +== 222 +-- UPSERT with UPDATE/DELETE when not matched by source +BEGIN +-- +STMT: TransactionStmt +== 223 +DELETE FROM SOURCE WHERE sid = 2 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +== 224 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND t.balance > s.delta THEN + UPDATE SET balance = t.balance - s.delta +WHEN MATCHED THEN + UPDATE SET balance = 0 +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +WHEN NOT MATCHED BY SOURCE AND tid = 1 THEN + UPDATE SET balance = 0 +WHEN NOT MATCHED BY SOURCE THEN + DELETE +RETURNING merge_action(), t.* +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +== 225 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 226 +ROLLBACK +-- +STMT: TransactionStmt +== 227 +-- Test behavior of triggers that turn UPDATE/DELETE into no-ops +create or replace function skip_merge_op() returns trigger +language plpgsql as +$$ +BEGIN + RETURN NULL; +END; +$$ +-- +FUNCTION: name="skip_merge_op" function="skip_merge_op" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 228 +SELECT * FROM target full outer join source on (sid = tid) +-- +TABLE: name="target" schema="" table="target" ctx=Select +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +== 229 +create trigger merge_skip BEFORE INSERT OR UPDATE or DELETE + ON target FOR EACH ROW EXECUTE FUNCTION skip_merge_op() +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +== 230 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND s.sid = 3 THEN UPDATE SET balance = t.balance + s.delta +WHEN MATCHED THEN DELETE +WHEN NOT MATCHED THEN INSERT VALUES (sid, delta); +IF FOUND THEN + RAISE NOTICE 'Found'; +ELSE + RAISE NOTICE 'Not found'; +END IF; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +== 231 +SELECT * FROM target FULL OUTER JOIN source ON (sid = tid) +-- +TABLE: name="target" schema="" table="target" ctx=Select +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +== 232 +DROP TRIGGER merge_skip ON target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: DropStmt +== 233 +DROP FUNCTION skip_merge_op() +-- +FUNCTION: name="skip_merge_op" function="skip_merge_op" schema="" ctx=DDL +STMT: DropStmt +== 234 +-- test from PL/pgSQL +-- make sure MERGE INTO isn't interpreted to mean returning variables like SELECT INTO +BEGIN +-- +STMT: TransactionStmt +== 235 +DO LANGUAGE plpgsql $$ +BEGIN +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND t.balance > s.delta THEN + UPDATE SET balance = t.balance - s.delta; +END; +$$ +-- +STMT: DoStmt +== 236 +ROLLBACK +-- +STMT: TransactionStmt +== 237 +--source constants +BEGIN +-- +STMT: TransactionStmt +== 238 +MERGE INTO target t +USING (SELECT 9 AS sid, 57 AS delta) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +STMT: SelectStmt +== 239 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 240 +ROLLBACK +-- +STMT: TransactionStmt +== 241 +--source query +BEGIN +-- +STMT: TransactionStmt +== 242 +MERGE INTO target t +USING (SELECT sid, delta FROM source WHERE delta > 0) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="" column="delta" +STMT: MergeStmt +STMT: SelectStmt +== 243 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 244 +ROLLBACK +-- +STMT: TransactionStmt +== 245 +BEGIN +-- +STMT: TransactionStmt +== 246 +MERGE INTO target t +USING (SELECT sid, delta as newname FROM source WHERE delta > 0) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.newname) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="" column="delta" +STMT: MergeStmt +STMT: SelectStmt +== 247 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 248 +ROLLBACK +-- +STMT: TransactionStmt +== 249 +--self-merge +BEGIN +-- +STMT: TransactionStmt +== 250 +MERGE INTO target t1 +USING target t2 +ON t1.tid = t2.tid +WHEN MATCHED THEN + UPDATE SET balance = t1.balance + t2.balance +WHEN NOT MATCHED THEN + INSERT VALUES (t2.tid, t2.balance) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t1"="target" +STMT: MergeStmt +== 251 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 252 +ROLLBACK +-- +STMT: TransactionStmt +== 253 +BEGIN +-- +STMT: TransactionStmt +== 254 +MERGE INTO target t +USING (SELECT tid as sid, balance as delta FROM target WHERE balance > 0) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="target" schema="" table="target" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="" column="balance" +STMT: MergeStmt +STMT: SelectStmt +== 255 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 256 +ROLLBACK +-- +STMT: TransactionStmt +== 257 +BEGIN +-- +STMT: TransactionStmt +== 258 +MERGE INTO target t +USING +(SELECT sid, max(delta) AS delta + FROM source + GROUP BY sid + HAVING count(*) = 1 + ORDER BY sid ASC) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 259 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 260 +ROLLBACK +-- +STMT: TransactionStmt +== 261 +-- plpgsql parameters and results +BEGIN +-- +STMT: TransactionStmt +== 262 +CREATE FUNCTION merge_func (p_id integer, p_bal integer) +RETURNS INTEGER +LANGUAGE plpgsql +AS $$ +DECLARE + result integer; +BEGIN +MERGE INTO target t +USING (SELECT p_id AS sid) AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = t.balance - p_bal; +IF FOUND THEN + GET DIAGNOSTICS result := ROW_COUNT; +END IF; +RETURN result; +END; +$$ +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 263 +SELECT merge_func(3, 4) +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=Call +STMT: SelectStmt +== 264 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 265 +ROLLBACK +-- +STMT: TransactionStmt +== 266 +-- PREPARE +BEGIN +-- +STMT: TransactionStmt +== 267 +prepare foom as merge into target t using (select 1 as sid) s on (t.tid = s.sid) when matched then update set balance = 1 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: PrepareStmt +STMT: MergeStmt +STMT: SelectStmt +== 268 +execute foom +-- +STMT: ExecuteStmt +== 269 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 270 +ROLLBACK +-- +STMT: TransactionStmt +== 271 +BEGIN +-- +STMT: TransactionStmt +== 272 +PREPARE foom2 (integer, integer) AS +MERGE INTO target t +USING (SELECT 1) s +ON t.tid = $1 +WHEN MATCHED THEN +UPDATE SET balance = $2 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: PrepareStmt +STMT: MergeStmt +STMT: SelectStmt +== 273 +--EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) +execute foom2 (1, 1) +-- +STMT: ExecuteStmt +== 274 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +== 275 +ROLLBACK +-- +STMT: TransactionStmt +== 276 +-- subqueries in source relation + +CREATE TABLE sq_target (tid integer NOT NULL, balance integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DDL +STMT: CreateStmt +== 277 +CREATE TABLE sq_source (delta integer, sid integer, balance integer DEFAULT 0) + WITH (autovacuum_enabled=off) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DDL +STMT: CreateStmt +== 278 +INSERT INTO sq_target(tid, balance) VALUES (1,100), (2,200), (3,300) +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 279 +INSERT INTO sq_source(sid, delta) VALUES (1,10), (2,20), (4,40) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +BEGIN +-- +STMT: TransactionStmt +== 281 +MERGE INTO sq_target t +USING (SELECT * FROM sq_source) s +ON tid = sid +WHEN MATCHED AND t.balance > delta THEN + UPDATE SET balance = t.balance + delta +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_source" schema="" table="sq_source" ctx=Select +ALIAS: "t"="sq_target" +STMT: MergeStmt +STMT: SelectStmt +== 282 +SELECT * FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +== 283 +ROLLBACK +-- +STMT: TransactionStmt +== 284 +-- try a view +CREATE VIEW v AS SELECT * FROM sq_source WHERE sid < 2 +-- +TABLE: name="v" schema="" table="v" ctx=DDL +TABLE: name="sq_source" schema="" table="sq_source" ctx=Select +FILTER: schema="" table="" column="sid" +STMT: ViewStmt +STMT: SelectStmt +== 285 +BEGIN +-- +STMT: TransactionStmt +== 286 +MERGE INTO sq_target +USING v +ON tid = sid +WHEN MATCHED THEN + UPDATE SET balance = v.balance + delta +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: MergeStmt +== 287 +SELECT * FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +== 288 +ROLLBACK +-- +STMT: TransactionStmt +== 289 +-- ambiguous reference to a column +BEGIN +-- +STMT: TransactionStmt +== 290 +MERGE INTO sq_target +USING v +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: MergeStmt +== 291 +ROLLBACK +-- +STMT: TransactionStmt +== 292 +BEGIN +-- +STMT: TransactionStmt +== 293 +INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 294 +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +ALIAS: "t"="sq_target" +STMT: MergeStmt +== 295 +SELECT * FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +== 296 +ROLLBACK +-- +STMT: TransactionStmt +== 297 +-- CTEs +BEGIN +-- +STMT: TransactionStmt +== 298 +INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 299 +WITH targq AS ( + SELECT * FROM v +) +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="v" schema="" table="v" ctx=Select +ALIAS: "t"="sq_target" +CTE: "targq" +STMT: MergeStmt +STMT: SelectStmt +== 300 +ROLLBACK +-- +STMT: TransactionStmt +== 301 +-- RETURNING +SELECT * FROM sq_source ORDER BY sid +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=Select +STMT: SelectStmt +== 302 +SELECT * FROM sq_target ORDER BY tid +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +== 303 +BEGIN +-- +STMT: TransactionStmt +== 304 +CREATE TABLE merge_actions(action text, abbrev text) +-- +TABLE: name="merge_actions" schema="" table="merge_actions" ctx=DDL +STMT: CreateStmt +== 305 +INSERT INTO merge_actions VALUES ('INSERT', 'ins'), ('UPDATE', 'upd'), ('DELETE', 'del') +-- +TABLE: name="merge_actions" schema="" table="merge_actions" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +MERGE INTO sq_target t +USING sq_source s +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +RETURNING (SELECT abbrev FROM merge_actions + WHERE action = merge_action()) AS action, + t.*, + CASE merge_action() + WHEN 'INSERT' THEN 'Inserted '||t + WHEN 'UPDATE' THEN 'Added '||delta||' to balance' + WHEN 'DELETE' THEN 'Removed '||t + END AS description +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="merge_actions" schema="" table="merge_actions" ctx=Select +ALIAS: "t"="sq_target" +FILTER: schema="" table="" column="action" +STMT: MergeStmt +STMT: SelectStmt +== 307 +ROLLBACK +-- +STMT: TransactionStmt +== 308 +-- error when using merge_action() outside MERGE +SELECT merge_action() FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +== 309 +UPDATE sq_target SET balance = balance + 1 RETURNING merge_action() +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: UpdateStmt +== 310 +-- RETURNING in CTEs +CREATE TABLE sq_target_merge_log (tid integer NOT NULL, last_change text) +-- +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DDL +STMT: CreateStmt +== 311 +INSERT INTO sq_target_merge_log VALUES (1, 'Original value') +-- +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 312 +BEGIN +-- +STMT: TransactionStmt +== 313 +WITH m AS ( + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action() AS action, t.*, + CASE merge_action() + WHEN 'INSERT' THEN 'Inserted '||t + WHEN 'UPDATE' THEN 'Added '||delta||' to balance' + WHEN 'DELETE' THEN 'Removed '||t + END AS description +), m2 AS ( + MERGE INTO sq_target_merge_log l + USING m + ON l.tid = m.tid + WHEN MATCHED THEN + UPDATE SET last_change = description + WHEN NOT MATCHED THEN + INSERT VALUES (m.tid, description) + RETURNING action, merge_action() AS log_action, l.* +) +SELECT * FROM m2 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DML +ALIAS: "l"="sq_target_merge_log" +ALIAS: "t"="sq_target" +CTE: "m" +CTE: "m2" +STMT: SelectStmt +STMT: MergeStmt +== 314 +SELECT * FROM sq_target_merge_log ORDER BY tid +-- +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=Select +STMT: SelectStmt +== 315 +ROLLBACK +-- +STMT: TransactionStmt +== 316 +-- COPY (MERGE ... RETURNING) TO ... +BEGIN +-- +STMT: TransactionStmt +== 317 +COPY ( + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.* +) TO stdout +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +ALIAS: "t"="sq_target" +STMT: CopyStmt +== 318 +ROLLBACK +-- +STMT: TransactionStmt +== 319 +-- SQL function with MERGE ... RETURNING +BEGIN +-- +STMT: TransactionStmt +== 320 +CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, + OUT action text, OUT tid int, OUT new_balance int) +LANGUAGE sql AS +$$ + MERGE INTO sq_target t + USING (VALUES ($1, $2, $3)) AS v(sid, balance, delta) + ON tid = v.sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + v.delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (v.balance + v.delta, v.sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.*; +$$ +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 321 +SELECT m.* +FROM (VALUES (1, 0, 0), (3, 0, 20), (4, 100, 10)) AS v(sid, balance, delta), +LATERAL (SELECT action, tid, new_balance FROM merge_into_sq_target(sid, balance, delta)) m +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=Call +STMT: SelectStmt +== 322 +ROLLBACK +-- +STMT: TransactionStmt +== 323 +-- SQL SRF with MERGE ... RETURNING +BEGIN +-- +STMT: TransactionStmt +== 324 +CREATE FUNCTION merge_sq_source_into_sq_target() +RETURNS TABLE (action text, tid int, balance int) +LANGUAGE sql AS +$$ + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.*; +$$ +-- +FUNCTION: name="merge_sq_source_into_sq_target" function="merge_sq_source_into_sq_target" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 325 +SELECT * FROM merge_sq_source_into_sq_target() +-- +FUNCTION: name="merge_sq_source_into_sq_target" function="merge_sq_source_into_sq_target" schema="" ctx=Call +STMT: SelectStmt +== 326 +ROLLBACK +-- +STMT: TransactionStmt +== 327 +-- PL/pgSQL function with MERGE ... RETURNING ... INTO +BEGIN +-- +STMT: TransactionStmt +== 328 +CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, + OUT r_action text, OUT r_tid int, OUT r_balance int) +LANGUAGE plpgsql AS +$$ +BEGIN + MERGE INTO sq_target t + USING (VALUES ($1, $2, $3)) AS v(sid, balance, delta) + ON tid = v.sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + v.delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (v.balance + v.delta, v.sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.* INTO r_action, r_tid, r_balance; +END; +$$ +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 329 +SELECT m.* +FROM (VALUES (1, 0, 0), (3, 0, 20), (4, 100, 10)) AS v(sid, balance, delta), +LATERAL (SELECT r_action, r_tid, r_balance FROM merge_into_sq_target(sid, balance, delta)) m +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=Call +STMT: SelectStmt +== 330 +ROLLBACK +-- +STMT: TransactionStmt +== 331 +-- EXPLAIN +CREATE TABLE ex_mtarget (a int, b int) + WITH (autovacuum_enabled=off) +-- +TABLE: name="ex_mtarget" schema="" table="ex_mtarget" ctx=DDL +STMT: CreateStmt +== 332 +CREATE TABLE ex_msource (a int, b int) + WITH (autovacuum_enabled=off) +-- +TABLE: name="ex_msource" schema="" table="ex_msource" ctx=DDL +STMT: CreateStmt +== 333 +INSERT INTO ex_mtarget SELECT i, i*10 FROM generate_series(1,100,2) i +-- +TABLE: name="ex_mtarget" schema="" table="ex_mtarget" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 334 +INSERT INTO ex_msource SELECT i, i*10 FROM generate_series(1,100,1) i +-- +TABLE: name="ex_msource" schema="" table="ex_msource" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 335 +CREATE FUNCTION explain_merge(query text) RETURNS SETOF text +LANGUAGE plpgsql AS +$$ +DECLARE ln text; +BEGIN + FOR ln IN + EXECUTE 'explain (analyze, timing off, summary off, costs off) ' || + query + LOOP + ln := regexp_replace(ln, '(Memory( Usage)?|Buckets|Batches): \S*', '\1: xxx', 'g'); + RETURN NEXT ln; + END LOOP; +END; +$$ +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 336 +-- only updates +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED THEN + UPDATE SET b = t.b + 1') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 337 +-- only updates to selected tuples +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 338 +-- updates + deletes +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1 +WHEN MATCHED AND t.a >= 10 AND t.a <= 20 THEN + DELETE') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 339 +-- only inserts +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED AND s.a < 10 THEN + INSERT VALUES (a, b)') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 340 +-- all three +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1 +WHEN MATCHED AND t.a >= 30 AND t.a <= 40 THEN + DELETE +WHEN NOT MATCHED AND s.a < 20 THEN + INSERT VALUES (a, b)') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 341 +-- not matched by source +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED BY SOURCE and t.a < 10 THEN + DELETE') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 342 +-- not matched by source and target +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED BY SOURCE AND t.a < 10 THEN + DELETE +WHEN NOT MATCHED BY TARGET AND s.a < 20 THEN + INSERT VALUES (a, b)') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 343 +-- nothing +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a AND t.a < -1000 +WHEN MATCHED AND t.a < 10 THEN + DO NOTHING') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +== 344 +DROP TABLE ex_msource, ex_mtarget +-- +TABLE: name="ex_msource" schema="" table="ex_msource" ctx=DDL +TABLE: name="ex_mtarget" schema="" table="ex_mtarget" ctx=DDL +STMT: DropStmt +== 345 +DROP FUNCTION explain_merge(text) +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=DDL +STMT: DropStmt +== 346 +-- EXPLAIN SubPlans and InitPlans +CREATE TABLE src (a int, b int, c int, d int) +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: CreateStmt +== 347 +CREATE TABLE tgt (a int, b int, c int, d int) +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +STMT: CreateStmt +== 348 +CREATE TABLE ref (ab int, cd int) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +== 349 +EXPLAIN (verbose, costs off) +MERGE INTO tgt t +USING (SELECT *, (SELECT count(*) FROM ref r + WHERE r.ab = s.a + s.b + AND r.cd = s.c - s.d) cnt + FROM src s) s +ON t.a = s.a AND t.b < s.cnt +WHEN MATCHED AND t.c > s.cnt THEN + UPDATE SET (b, c) = (SELECT s.b, s.cnt) +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DML +TABLE: name="src" schema="" table="src" ctx=Select +TABLE: name="ref" schema="" table="ref" ctx=Select +ALIAS: "r"="ref" +ALIAS: "s"="src" +ALIAS: "t"="tgt" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="r" column="ab" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="r" column="cd" +FILTER: schema="" table="s" column="c" +FILTER: schema="" table="s" column="d" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 350 +DROP TABLE src, tgt, ref +-- +TABLE: name="src" schema="" table="src" ctx=DDL +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +== 351 +-- Subqueries +BEGIN +-- +STMT: TransactionStmt +== 352 +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED THEN + UPDATE SET balance = (SELECT count(*) FROM sq_target) +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +ALIAS: "t"="sq_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 353 +SELECT * FROM sq_target WHERE tid = 1 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +FILTER: schema="" table="" column="tid" +STMT: SelectStmt +== 354 +ROLLBACK +-- +STMT: TransactionStmt +== 355 +BEGIN +-- +STMT: TransactionStmt +== 356 +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED AND (SELECT count(*) > 0 FROM sq_target) THEN + UPDATE SET balance = 42 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +ALIAS: "t"="sq_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 357 +SELECT * FROM sq_target WHERE tid = 1 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +FILTER: schema="" table="" column="tid" +STMT: SelectStmt +== 358 +ROLLBACK +-- +STMT: TransactionStmt +== 359 +BEGIN +-- +STMT: TransactionStmt +== 360 +MERGE INTO sq_target t +USING v +ON tid = sid AND (SELECT count(*) > 0 FROM sq_target) +WHEN MATCHED THEN + UPDATE SET balance = 42 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +ALIAS: "t"="sq_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 361 +SELECT * FROM sq_target WHERE tid = 1 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +FILTER: schema="" table="" column="tid" +STMT: SelectStmt +== 362 +ROLLBACK +-- +STMT: TransactionStmt +== 363 +DROP TABLE sq_target, sq_target_merge_log, sq_source CASCADE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DDL +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DDL +TABLE: name="sq_source" schema="" table="sq_source" ctx=DDL +STMT: DropStmt +== 364 +CREATE TABLE pa_target (tid integer, balance float, val text) + PARTITION BY LIST (tid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +== 365 +CREATE TABLE part1 PARTITION OF pa_target FOR VALUES IN (1,4) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +== 366 +CREATE TABLE part2 PARTITION OF pa_target FOR VALUES IN (2,5,6) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +== 367 +CREATE TABLE part3 PARTITION OF pa_target FOR VALUES IN (3,8,9) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +== 368 +CREATE TABLE part4 PARTITION OF pa_target DEFAULT + WITH (autovacuum_enabled=off) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +== 369 +CREATE TABLE pa_source (sid integer, delta float) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: CreateStmt +== 370 +-- insert many rows to the source table +INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 371 +-- insert a few rows in the target table (odd numbered tid) +INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,15,2) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 372 +-- try simple MERGE +BEGIN +-- +STMT: TransactionStmt +== 373 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source' +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +== 374 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 375 +ROLLBACK +-- +STMT: TransactionStmt +== 376 +-- same with a constant qual +BEGIN +-- +STMT: TransactionStmt +== 377 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND tid = 1 + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source' +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +== 378 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 379 +ROLLBACK +-- +STMT: TransactionStmt +== 380 +-- try updating the partition key column +BEGIN +-- +STMT: TransactionStmt +== 381 +CREATE FUNCTION merge_func() RETURNS integer LANGUAGE plpgsql AS $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET tid = 1, val = val || ' not matched by source'; +IF FOUND THEN + GET DIAGNOSTICS result := ROW_COUNT; +END IF; +RETURN result; +END; +$$ +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 382 +SELECT merge_func() +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=Call +STMT: SelectStmt +== 383 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 384 +ROLLBACK +-- +STMT: TransactionStmt +== 385 +-- update partition key to partition not initially scanned +BEGIN +-- +STMT: TransactionStmt +== 386 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND t.tid = 1 + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + RETURNING merge_action(), t.* +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +== 387 +SELECT * FROM pa_target ORDER BY tid +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 388 +ROLLBACK +-- +STMT: TransactionStmt +== 389 +-- bug #18871: ExecInitPartitionInfo()'s handling of DO NOTHING actions +BEGIN +-- +STMT: TransactionStmt +== 390 +TRUNCATE pa_target +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: TruncateStmt +== 391 +MERGE INTO pa_target t + USING (VALUES (10, 100)) AS s(sid, delta) + ON t.tid = s.sid + WHEN NOT MATCHED THEN + INSERT VALUES (1, 10, 'inserted by merge') + WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +STMT: SelectStmt +== 392 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 393 +ROLLBACK +-- +STMT: TransactionStmt +== 394 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +== 395 +-- The target table is partitioned in the same way, but this time by attaching +-- partitions which have columns in different order, dropped columns etc. +CREATE TABLE pa_target (tid integer, balance float, val text) + PARTITION BY LIST (tid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +== 396 +CREATE TABLE part1 (tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +== 397 +CREATE TABLE part2 (balance float, tid integer, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +== 398 +CREATE TABLE part3 (tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +== 399 +CREATE TABLE part4 (extraid text, tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +== 400 +ALTER TABLE part4 DROP COLUMN extraid +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: AlterTableStmt +== 401 +ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +== 402 +ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +== 403 +ALTER TABLE pa_target ATTACH PARTITION part3 FOR VALUES IN (3,8,9) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +== 404 +ALTER TABLE pa_target ATTACH PARTITION part4 DEFAULT +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +== 405 +-- insert a few rows in the target table (odd numbered tid) +INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,15,2) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 406 +-- try simple MERGE +BEGIN +-- +STMT: TransactionStmt +== 407 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +== 408 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 409 +ROLLBACK +-- +STMT: TransactionStmt +== 410 +-- same with a constant qual +BEGIN +-- +STMT: TransactionStmt +== 411 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND tid IN (1, 5) + WHEN MATCHED AND tid % 5 = 0 THEN DELETE + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source' +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +== 412 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 413 +ROLLBACK +-- +STMT: TransactionStmt +== 414 +-- try updating the partition key column +BEGIN +-- +STMT: TransactionStmt +== 415 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET tid = 1, val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +== 416 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 417 +ROLLBACK +-- +STMT: TransactionStmt +== 418 +-- as above, but blocked by BEFORE DELETE ROW trigger +BEGIN +-- +STMT: TransactionStmt +== 419 +CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS + $$ BEGIN RETURN NULL; END; $$ +-- +FUNCTION: name="trig_fn" function="trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 420 +CREATE TRIGGER del_trig BEFORE DELETE ON pa_target + FOR EACH ROW EXECUTE PROCEDURE trig_fn() +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateTrigStmt +== 421 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +== 422 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 423 +ROLLBACK +-- +STMT: TransactionStmt +== 424 +-- as above, but blocked by BEFORE INSERT ROW trigger +BEGIN +-- +STMT: TransactionStmt +== 425 +CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS + $$ BEGIN RETURN NULL; END; $$ +-- +FUNCTION: name="trig_fn" function="trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 426 +CREATE TRIGGER ins_trig BEFORE INSERT ON pa_target + FOR EACH ROW EXECUTE PROCEDURE trig_fn() +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateTrigStmt +== 427 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +== 428 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 429 +ROLLBACK +-- +STMT: TransactionStmt +== 430 +-- test RLS enforcement +BEGIN +-- +STMT: TransactionStmt +== 431 +ALTER TABLE pa_target ENABLE ROW LEVEL SECURITY +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +== 432 +ALTER TABLE pa_target FORCE ROW LEVEL SECURITY +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +== 433 +CREATE POLICY pa_target_pol ON pa_target USING (tid != 0) +-- +STMT: CreatePolicyStmt +== 434 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND t.tid IN (1,2,3,4) + WHEN MATCHED THEN + UPDATE SET tid = tid - 1 +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +== 435 +ROLLBACK +-- +STMT: TransactionStmt +== 436 +DROP TABLE pa_source +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: DropStmt +== 437 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +== 438 +-- Sub-partitioning +CREATE TABLE pa_target (logts timestamp, tid integer, balance float, val text) + PARTITION BY RANGE (logts) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +== 439 +CREATE TABLE part_m01 PARTITION OF pa_target + FOR VALUES FROM ('2017-01-01') TO ('2017-02-01') + PARTITION BY LIST (tid) +-- +TABLE: name="part_m01" schema="" table="part_m01" ctx=DDL +STMT: CreateStmt +== 440 +CREATE TABLE part_m01_odd PARTITION OF part_m01 + FOR VALUES IN (1,3,5,7,9) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m01_odd" schema="" table="part_m01_odd" ctx=DDL +STMT: CreateStmt +== 441 +CREATE TABLE part_m01_even PARTITION OF part_m01 + FOR VALUES IN (2,4,6,8) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m01_even" schema="" table="part_m01_even" ctx=DDL +STMT: CreateStmt +== 442 +CREATE TABLE part_m02 PARTITION OF pa_target + FOR VALUES FROM ('2017-02-01') TO ('2017-03-01') + PARTITION BY LIST (tid) +-- +TABLE: name="part_m02" schema="" table="part_m02" ctx=DDL +STMT: CreateStmt +== 443 +CREATE TABLE part_m02_odd PARTITION OF part_m02 + FOR VALUES IN (1,3,5,7,9) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m02_odd" schema="" table="part_m02_odd" ctx=DDL +STMT: CreateStmt +== 444 +CREATE TABLE part_m02_even PARTITION OF part_m02 + FOR VALUES IN (2,4,6,8) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m02_even" schema="" table="part_m02_even" ctx=DDL +STMT: CreateStmt +== 445 +CREATE TABLE pa_source (sid integer, delta float) + WITH (autovacuum_enabled=off) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: CreateStmt +== 446 +-- insert many rows to the source table +INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 447 +-- insert a few rows in the target table (odd numbered tid) +INSERT INTO pa_target SELECT '2017-01-31', id, id * 100, 'initial' FROM generate_series(1,9,3) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 448 +INSERT INTO pa_target SELECT '2017-02-28', id, id * 100, 'initial' FROM generate_series(2,9,3) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 449 +-- try simple MERGE +BEGIN +-- +STMT: TransactionStmt +== 450 +MERGE INTO pa_target t + USING (SELECT '2017-01-15' AS slogts, * FROM pa_source WHERE sid < 10) s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (slogts::timestamp, sid, delta, 'inserted by merge') + RETURNING merge_action(), t.* +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +TABLE: name="pa_source" schema="" table="pa_source" ctx=Select +ALIAS: "t"="pa_target" +FILTER: schema="" table="" column="sid" +STMT: MergeStmt +STMT: SelectStmt +== 451 +SELECT * FROM pa_target ORDER BY tid +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 452 +ROLLBACK +-- +STMT: TransactionStmt +== 453 +DROP TABLE pa_source +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: DropStmt +== 454 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +== 455 +-- Partitioned table with primary key + +CREATE TABLE pa_target (tid integer PRIMARY KEY) PARTITION BY LIST (tid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +== 456 +CREATE TABLE pa_targetp PARTITION OF pa_target DEFAULT +-- +TABLE: name="pa_targetp" schema="" table="pa_targetp" ctx=DDL +STMT: CreateStmt +== 457 +CREATE TABLE pa_source (sid integer) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: CreateStmt +== 458 +INSERT INTO pa_source VALUES (1), (2) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 459 +EXPLAIN (VERBOSE, COSTS OFF) +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: ExplainStmt +STMT: MergeStmt +== 460 +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +== 461 +TABLE pa_target +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +== 462 +-- Partition-less partitioned table +-- (the bug we are checking for appeared only if table had partitions before) + +DROP TABLE pa_targetp +-- +TABLE: name="pa_targetp" schema="" table="pa_targetp" ctx=DDL +STMT: DropStmt +== 463 +EXPLAIN (VERBOSE, COSTS OFF) +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: ExplainStmt +STMT: MergeStmt +== 464 +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +== 465 +DROP TABLE pa_source +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: DropStmt +== 466 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +== 467 +-- some complex joins on the source side + +CREATE TABLE cj_target (tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DDL +STMT: CreateStmt +== 468 +CREATE TABLE cj_source1 (sid1 integer, scat integer, delta integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DDL +STMT: CreateStmt +== 469 +CREATE TABLE cj_source2 (sid2 integer, sval text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DDL +STMT: CreateStmt +== 470 +INSERT INTO cj_source1 VALUES (1, 10, 100) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 471 +INSERT INTO cj_source1 VALUES (1, 20, 200) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 472 +INSERT INTO cj_source1 VALUES (2, 20, 300) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 473 +INSERT INTO cj_source1 VALUES (3, 10, 400) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 474 +INSERT INTO cj_source2 VALUES (1, 'initial source2') +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 475 +INSERT INTO cj_source2 VALUES (2, 'initial source2') +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 476 +INSERT INTO cj_source2 VALUES (3, 'initial source2') +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 477 +-- source relation is an unaliased join +MERGE INTO cj_target t +USING cj_source1 s1 + INNER JOIN cj_source2 s2 ON sid1 = sid2 +ON t.tid = sid1 +WHEN NOT MATCHED THEN + INSERT VALUES (sid1, delta, sval) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +== 478 +-- try accessing columns from either side of the source join +MERGE INTO cj_target t +USING cj_source2 s2 + INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 +ON t.tid = sid1 +WHEN NOT MATCHED THEN + INSERT VALUES (sid2, delta, sval) +WHEN MATCHED THEN + DELETE +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +== 479 +-- some simple expressions in INSERT targetlist +MERGE INTO cj_target t +USING cj_source2 s2 + INNER JOIN cj_source1 s1 ON sid1 = sid2 +ON t.tid = sid1 +WHEN NOT MATCHED THEN + INSERT VALUES (sid2, delta + scat, sval) +WHEN MATCHED THEN + UPDATE SET val = val || ' updated by merge' +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +== 480 +MERGE INTO cj_target t +USING cj_source2 s2 + INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 +ON t.tid = sid1 +WHEN MATCHED THEN + UPDATE SET val = val || ' ' || delta::text +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +== 481 +SELECT * FROM cj_target +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=Select +STMT: SelectStmt +== 482 +-- try it with an outer join and PlaceHolderVar +MERGE INTO cj_target t +USING (SELECT *, 'join input'::text AS phv FROM cj_source1) fj + FULL JOIN cj_source2 fj2 ON fj.scat = fj2.sid2 * 10 +ON t.tid = fj.scat +WHEN NOT MATCHED THEN + INSERT (tid, balance, val) VALUES (fj.scat, fj.delta, fj.phv) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=Select +ALIAS: "t"="cj_target" +STMT: MergeStmt +STMT: SelectStmt +== 483 +SELECT * FROM cj_target +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=Select +STMT: SelectStmt +== 484 +ALTER TABLE cj_source1 RENAME COLUMN sid1 TO sid +-- +STMT: RenameStmt +== 485 +ALTER TABLE cj_source2 RENAME COLUMN sid2 TO sid +-- +STMT: RenameStmt +== 486 +TRUNCATE cj_target +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DDL +STMT: TruncateStmt +== 487 +MERGE INTO cj_target t +USING cj_source1 s1 + INNER JOIN cj_source2 s2 ON s1.sid = s2.sid +ON t.tid = s1.sid +WHEN NOT MATCHED THEN + INSERT VALUES (s2.sid, delta, sval) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +== 488 +DROP TABLE cj_source2, cj_source1, cj_target +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DDL +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DDL +TABLE: name="cj_target" schema="" table="cj_target" ctx=DDL +STMT: DropStmt +== 489 +-- Function scans +CREATE TABLE fs_target (a int, b int, c text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DDL +STMT: CreateStmt +== 490 +MERGE INTO fs_target t +USING generate_series(1,100,1) AS id +ON t.a = id +WHEN MATCHED THEN + UPDATE SET b = b + id +WHEN NOT MATCHED THEN + INSERT VALUES (id, -1) +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DML +ALIAS: "t"="fs_target" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +== 491 +MERGE INTO fs_target t +USING generate_series(1,100,2) AS id +ON t.a = id +WHEN MATCHED THEN + UPDATE SET b = b + id, c = 'updated '|| id.*::text +WHEN NOT MATCHED THEN + INSERT VALUES (id, -1, 'inserted ' || id.*::text) +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DML +ALIAS: "t"="fs_target" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +== 492 +SELECT count(*) FROM fs_target +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 493 +DROP TABLE fs_target +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DDL +STMT: DropStmt +== 494 +-- SERIALIZABLE test +-- handled in isolation tests + +-- Inheritance-based partitioning +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: CreateStmt +== 495 +CREATE TABLE measurement_y2006m02 ( + CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' ) +) INHERITS (measurement) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement_y2006m02" schema="" table="measurement_y2006m02" ctx=DDL +STMT: CreateStmt +== 496 +CREATE TABLE measurement_y2006m03 ( + CHECK ( logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' ) +) INHERITS (measurement) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement_y2006m03" schema="" table="measurement_y2006m03" ctx=DDL +STMT: CreateStmt +== 497 +CREATE TABLE measurement_y2007m01 ( + filler text, + peaktemp int, + logdate date not null, + city_id int not null, + unitsales int + CHECK ( logdate >= DATE '2007-01-01' AND logdate < DATE '2007-02-01') +) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement_y2007m01" schema="" table="measurement_y2007m01" ctx=DDL +STMT: CreateStmt +== 498 +ALTER TABLE measurement_y2007m01 DROP COLUMN filler +-- +TABLE: name="measurement_y2007m01" schema="" table="measurement_y2007m01" ctx=DDL +STMT: AlterTableStmt +== 499 +ALTER TABLE measurement_y2007m01 INHERIT measurement +-- +TABLE: name="measurement_y2007m01" schema="" table="measurement_y2007m01" ctx=DDL +STMT: AlterTableStmt +== 500 +INSERT INTO measurement VALUES (0, '2005-07-21', 5, 15) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 501 +CREATE OR REPLACE FUNCTION measurement_insert_trigger() +RETURNS TRIGGER AS $$ +BEGIN + IF ( NEW.logdate >= DATE '2006-02-01' AND + NEW.logdate < DATE '2006-03-01' ) THEN + INSERT INTO measurement_y2006m02 VALUES (NEW.*); + ELSIF ( NEW.logdate >= DATE '2006-03-01' AND + NEW.logdate < DATE '2006-04-01' ) THEN + INSERT INTO measurement_y2006m03 VALUES (NEW.*); + ELSIF ( NEW.logdate >= DATE '2007-01-01' AND + NEW.logdate < DATE '2007-02-01' ) THEN + INSERT INTO measurement_y2007m01 (city_id, logdate, peaktemp, unitsales) + VALUES (NEW.*); + ELSE + RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!'; + END IF; + RETURN NULL; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="measurement_insert_trigger" function="measurement_insert_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 502 +CREATE TRIGGER insert_measurement_trigger + BEFORE INSERT ON measurement + FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger() +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: CreateTrigStmt +== 503 +INSERT INTO measurement VALUES (1, '2006-02-10', 35, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 504 +INSERT INTO measurement VALUES (1, '2006-02-16', 45, 20) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 505 +INSERT INTO measurement VALUES (1, '2006-03-17', 25, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 506 +INSERT INTO measurement VALUES (1, '2006-03-27', 15, 40) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 507 +INSERT INTO measurement VALUES (1, '2007-01-15', 10, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 508 +INSERT INTO measurement VALUES (1, '2007-01-17', 10, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 509 +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +== 510 +CREATE TABLE new_measurement (LIKE measurement) WITH (autovacuum_enabled=off) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DDL +STMT: CreateStmt +== 511 +INSERT INTO new_measurement VALUES (0, '2005-07-21', 25, 20) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 512 +INSERT INTO new_measurement VALUES (1, '2006-03-01', 20, 10) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 513 +INSERT INTO new_measurement VALUES (1, '2006-02-16', 50, 10) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 514 +INSERT INTO new_measurement VALUES (2, '2006-02-10', 20, 20) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 515 +INSERT INTO new_measurement VALUES (1, '2006-03-27', NULL, NULL) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 516 +INSERT INTO new_measurement VALUES (1, '2007-01-17', NULL, NULL) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 517 +INSERT INTO new_measurement VALUES (1, '2007-01-15', 5, NULL) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 518 +INSERT INTO new_measurement VALUES (1, '2007-01-16', 10, 10) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 519 +BEGIN +-- +STMT: TransactionStmt +== 520 +MERGE INTO ONLY measurement m + USING new_measurement nm ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE +WHEN MATCHED THEN UPDATE + SET peaktemp = greatest(m.peaktemp, nm.peaktemp), + unitsales = m.unitsales + coalesce(nm.unitsales, 0) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id, logdate, peaktemp, unitsales) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +== 521 +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate, peaktemp +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +== 522 +ROLLBACK +-- +STMT: TransactionStmt +== 523 +MERGE into measurement m + USING new_measurement nm ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE +WHEN MATCHED THEN UPDATE + SET peaktemp = greatest(m.peaktemp, nm.peaktemp), + unitsales = m.unitsales + coalesce(nm.unitsales, 0) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id, logdate, peaktemp, unitsales) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +== 524 +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +== 525 +BEGIN +-- +STMT: TransactionStmt +== 526 +MERGE INTO new_measurement nm + USING ONLY measurement m ON + (nm.city_id = m.city_id and nm.logdate=m.logdate) +WHEN MATCHED THEN DELETE +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +ALIAS: "nm"="new_measurement" +STMT: MergeStmt +== 527 +SELECT * FROM new_measurement ORDER BY city_id, logdate +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=Select +STMT: SelectStmt +== 528 +ROLLBACK +-- +STMT: TransactionStmt +== 529 +MERGE INTO new_measurement nm + USING measurement m ON + (nm.city_id = m.city_id and nm.logdate=m.logdate) +WHEN MATCHED THEN DELETE +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +ALIAS: "nm"="new_measurement" +STMT: MergeStmt +== 530 +SELECT * FROM new_measurement ORDER BY city_id, logdate +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=Select +STMT: SelectStmt +== 531 +-- MERGE into inheritance root table +DROP TRIGGER insert_measurement_trigger ON measurement +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: DropStmt +== 532 +ALTER TABLE measurement ADD CONSTRAINT mcheck CHECK (city_id = 0) NO INHERIT +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: AlterTableStmt +== 533 +EXPLAIN (COSTS OFF) +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 534 +BEGIN +-- +STMT: TransactionStmt +== 535 +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +== 536 +SELECT * FROM ONLY measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +== 537 +ROLLBACK +-- +STMT: TransactionStmt +== 538 +ALTER TABLE measurement ENABLE ROW LEVEL SECURITY +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: AlterTableStmt +== 539 +ALTER TABLE measurement FORCE ROW LEVEL SECURITY +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: AlterTableStmt +== 540 +CREATE POLICY measurement_p ON measurement USING (peaktemp IS NOT NULL) +-- +STMT: CreatePolicyStmt +== 541 +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, NULL, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +== 542 +-- should fail + +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +== 543 +-- ok +SELECT * FROM ONLY measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +== 544 +MERGE INTO measurement m + USING (VALUES (1, '01-18-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 200) +RETURNING merge_action(), m.* +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +== 545 +DROP TABLE measurement, new_measurement CASCADE +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DDL +STMT: DropStmt +== 546 +DROP FUNCTION measurement_insert_trigger() +-- +FUNCTION: name="measurement_insert_trigger" function="measurement_insert_trigger" schema="" ctx=DDL +STMT: DropStmt +== 547 +|-- +-- test non-strict join clause +|-- +CREATE TABLE src (a int, b text) +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: CreateStmt +== 548 +INSERT INTO src VALUES (1, 'src row') +-- +TABLE: name="src" schema="" table="src" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 549 +CREATE TABLE tgt (a int, b text) +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +STMT: CreateStmt +== 550 +INSERT INTO tgt VALUES (NULL, 'tgt row') +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 551 +MERGE INTO tgt USING src ON tgt.a IS NOT DISTINCT FROM src.a + WHEN MATCHED THEN UPDATE SET a = src.a, b = src.b + WHEN NOT MATCHED BY SOURCE THEN DELETE + RETURNING merge_action(), src.*, tgt.* +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DML +STMT: MergeStmt +== 552 +SELECT * FROM tgt +-- +TABLE: name="tgt" schema="" table="tgt" ctx=Select +STMT: SelectStmt +== 553 +DROP TABLE src, tgt +-- +TABLE: name="src" schema="" table="src" ctx=DDL +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +STMT: DropStmt +== 554 +|-- +-- test for bug #18634 (wrong varnullingrels error) +|-- +CREATE TABLE bug18634t (a int, b int, c text) +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=DDL +STMT: CreateStmt +== 555 +INSERT INTO bug18634t VALUES(1, 10, 'tgt1'), (2, 20, 'tgt2') +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 556 +CREATE VIEW bug18634v AS + SELECT * FROM bug18634t WHERE EXISTS (SELECT 1 FROM bug18634t) +-- +TABLE: name="bug18634v" schema="" table="bug18634v" ctx=DDL +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=Select +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 557 +CREATE TABLE bug18634s (a int, b int, c text) +-- +TABLE: name="bug18634s" schema="" table="bug18634s" ctx=DDL +STMT: CreateStmt +== 558 +INSERT INTO bug18634s VALUES (1, 2, 'src1') +-- +TABLE: name="bug18634s" schema="" table="bug18634s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 559 +MERGE INTO bug18634v t USING bug18634s s ON s.a = t.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED BY SOURCE THEN DELETE + RETURNING merge_action(), s.c, t.* +-- +TABLE: name="bug18634v" schema="" table="bug18634v" ctx=DML +ALIAS: "t"="bug18634v" +STMT: MergeStmt +== 560 +SELECT * FROM bug18634t +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=Select +STMT: SelectStmt +== 561 +DROP TABLE bug18634t CASCADE +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=DDL +STMT: DropStmt +== 562 +DROP TABLE bug18634s +-- +TABLE: name="bug18634s" schema="" table="bug18634s" ctx=DDL +STMT: DropStmt +== 563 +-- prepare + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 564 +-- try a system catalog +MERGE INTO pg_class c +USING (SELECT 'pg_depend'::regclass AS oid) AS j +ON j.oid = c.oid +WHEN MATCHED THEN + UPDATE SET reltuples = reltuples + 1 +RETURNING j.oid +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +ALIAS: "c"="pg_class" +STMT: MergeStmt +STMT: SelectStmt +== 565 +CREATE VIEW classv AS SELECT * FROM pg_class +-- +TABLE: name="classv" schema="" table="classv" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 566 +MERGE INTO classv c +USING pg_namespace n +ON n.oid = c.relnamespace +WHEN MATCHED AND c.oid = 'pg_depend'::regclass THEN + UPDATE SET reltuples = reltuples - 1 +RETURNING c.oid +-- +TABLE: name="classv" schema="" table="classv" ctx=DML +ALIAS: "c"="classv" +STMT: MergeStmt +== 567 +DROP TABLE target, target2 +-- +TABLE: name="target" schema="" table="target" ctx=DDL +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: DropStmt +== 568 +DROP TABLE source, source2 +-- +TABLE: name="source" schema="" table="source" ctx=DDL +TABLE: name="source2" schema="" table="source2" ctx=DDL +STMT: DropStmt +== 569 +DROP FUNCTION merge_trigfunc() +-- +FUNCTION: name="merge_trigfunc" function="merge_trigfunc" schema="" ctx=DDL +STMT: DropStmt +== 570 +DROP USER regress_merge_privs +-- +STMT: DropRoleStmt +== 571 +DROP USER regress_merge_no_privs +-- +STMT: DropRoleStmt +== 572 +DROP USER regress_merge_none +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/misc.metadata.json b/parser/testdata/summary/postgres_regress/misc.metadata.json new file mode 100644 index 0000000..6a71114 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/misc.metadata.json @@ -0,0 +1,65 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061" + ] +} diff --git a/parser/testdata/summary/postgres_regress/misc.test b/parser/testdata/summary/postgres_regress/misc.test new file mode 100644 index 0000000..c562203 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/misc.test @@ -0,0 +1,520 @@ +== 001 +|-- +-- MISC +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION overpaid(emp) + RETURNS bool + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 144 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +CREATE FUNCTION reverse_name(name) + RETURNS name + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 58 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +|-- +-- BTREE +|-- +UPDATE onek + SET unique1 = onek.unique1 + 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=DML +STMT: UpdateStmt +== 004 +UPDATE onek + SET unique1 = onek.unique1 - 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=DML +STMT: UpdateStmt +== 005 +|-- +-- BTREE partial +|-- +-- UPDATE onek2 +-- SET unique1 = onek2.unique1 + 1; + +--UPDATE onek2 +-- SET unique1 = onek2.unique1 - 1; + +|-- +-- BTREE shutting out non-functional updates +|-- +-- the following two tests seem to take a long time on some +-- systems. This non-func update stuff needs to be examined +-- more closely. - jolly (2/22/96) +|-- +SELECT two, stringu1, ten, string4 + INTO TABLE tmp + FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: SelectStmt +== 006 +UPDATE tmp + SET stringu1 = reverse_name(onek.stringu1) + FROM onek + WHERE onek.stringu1 = 'JBAAAA' and + onek.stringu1 = tmp.stringu1 +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="reverse_name" function="reverse_name" schema="" ctx=Call +STMT: UpdateStmt +== 007 +UPDATE tmp + SET stringu1 = reverse_name(onek2.stringu1) + FROM onek2 + WHERE onek2.stringu1 = 'JCAAAA' and + onek2.stringu1 = tmp.stringu1 +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FUNCTION: name="reverse_name" function="reverse_name" schema="" ctx=Call +STMT: UpdateStmt +== 008 +DROP TABLE tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: DropStmt +== 009 +--UPDATE person* +-- SET age = age + 1; + +--UPDATE person* +-- SET age = age + 3 +-- WHERE name = 'linda'; + +|-- +-- copy +|-- +COPY onek TO :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 138 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 010 +CREATE TEMP TABLE onek_copy (LIKE onek) +-- +TABLE: name="onek_copy" schema="" table="onek_copy" ctx=DDL +STMT: CreateStmt +== 011 +COPY onek_copy FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +SELECT * FROM onek EXCEPT ALL SELECT * FROM onek_copy +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek_copy" schema="" table="onek_copy" ctx=Select +STMT: SelectStmt +== 013 +SELECT * FROM onek_copy EXCEPT ALL SELECT * FROM onek +-- +TABLE: name="onek_copy" schema="" table="onek_copy" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 014 +COPY BINARY stud_emp TO :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 015 +CREATE TEMP TABLE stud_emp_copy (LIKE stud_emp) +-- +TABLE: name="stud_emp_copy" schema="" table="stud_emp_copy" ctx=DDL +STMT: CreateStmt +== 016 +COPY BINARY stud_emp_copy FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 017 +SELECT * FROM stud_emp_copy +-- +TABLE: name="stud_emp_copy" schema="" table="stud_emp_copy" ctx=Select +STMT: SelectStmt +== 018 +|-- +-- test data for postquel functions +|-- + +CREATE TABLE hobbies_r ( + name text, + person text +) +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DDL +STMT: CreateStmt +== 019 +CREATE TABLE equipment_r ( + name text, + hobby text +) +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DDL +STMT: CreateStmt +== 020 +INSERT INTO hobbies_r (name, person) + SELECT 'posthacking', p.name + FROM person* p + WHERE p.name = 'mike' or p.name = 'jeff' +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DML +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FILTER: schema="" table="p" column="name" +FILTER: schema="" table="p" column="name" +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO hobbies_r (name, person) + SELECT 'basketball', p.name + FROM person p + WHERE p.name = 'joe' or p.name = 'sally' +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DML +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FILTER: schema="" table="p" column="name" +FILTER: schema="" table="p" column="name" +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO hobbies_r (name) VALUES ('skywalking') +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO equipment_r (name, hobby) VALUES ('advil', 'posthacking') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO equipment_r (name, hobby) VALUES ('peet''s coffee', 'posthacking') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO equipment_r (name, hobby) VALUES ('hightops', 'basketball') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO equipment_r (name, hobby) VALUES ('guts', 'skywalking') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +|-- +-- postquel functions +|-- + +CREATE FUNCTION hobbies(person) + RETURNS setof hobbies_r + AS 'select * from hobbies_r where person = $1.name' + LANGUAGE SQL +-- +FUNCTION: name="hobbies" function="hobbies" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 028 +CREATE FUNCTION hobby_construct(text, text) + RETURNS hobbies_r + AS 'select $1 as name, $2 as hobby' + LANGUAGE SQL +-- +FUNCTION: name="hobby_construct" function="hobby_construct" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +CREATE FUNCTION hobby_construct_named(name text, hobby text) + RETURNS hobbies_r + AS 'select name, hobby' + LANGUAGE SQL +-- +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 030 +CREATE FUNCTION hobbies_by_name(hobbies_r.name%TYPE) + RETURNS hobbies_r.person%TYPE + AS 'select person from hobbies_r where name = $1' + LANGUAGE SQL +-- +FUNCTION: name="hobbies_by_name" function="hobbies_by_name" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 031 +CREATE FUNCTION equipment(hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = $1.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment" function="equipment" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +CREATE FUNCTION equipment_named(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = equipment_named.hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named" function="equipment_named" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 033 +CREATE FUNCTION equipment_named_ambiguous_1a(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = equipment_named_ambiguous_1a.hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_1a" function="equipment_named_ambiguous_1a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 034 +CREATE FUNCTION equipment_named_ambiguous_1b(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_1b" function="equipment_named_ambiguous_1b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 035 +CREATE FUNCTION equipment_named_ambiguous_1c(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_1c" function="equipment_named_ambiguous_1c" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +CREATE FUNCTION equipment_named_ambiguous_2a(hobby text) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = equipment_named_ambiguous_2a.hobby' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_2a" function="equipment_named_ambiguous_2a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 037 +CREATE FUNCTION equipment_named_ambiguous_2b(hobby text) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = hobby' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_2b" function="equipment_named_ambiguous_2b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 038 +|-- +-- mike does post_hacking, +-- joe and sally play basketball, and +-- everyone else does nothing. +|-- +SELECT p.name, name(p.hobbies) FROM ONLY person p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +== 039 +|-- +-- as above, but jeff also does post_hacking. +|-- +SELECT p.name, name(p.hobbies) FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +== 040 +|-- +-- the next two queries demonstrate how functions generate bogus duplicates. +-- this is a "feature" .. +|-- +SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r + ORDER BY 1,2 +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +STMT: SelectStmt +== 042 +|-- +-- mike needs advil and peet's coffee, +-- joe and sally need hightops, and +-- everyone else is fine. +|-- +SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +== 043 +|-- +-- 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 +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +== 044 +|-- +-- 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 +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +== 045 +SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +== 046 +SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +== 047 +SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="hobby_construct" function="hobby_construct" schema="" ctx=Call +STMT: SelectStmt +== 049 +SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named" function="equipment_named" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +== 051 +SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_1a" function="equipment_named_ambiguous_1a" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +== 052 +SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_1b" function="equipment_named_ambiguous_1b" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +== 053 +SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_1c" function="equipment_named_ambiguous_1c" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +== 054 +SELECT name(equipment_named_ambiguous_2a(text 'skywalking')) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_2a" function="equipment_named_ambiguous_2a" schema="" ctx=Call +STMT: SelectStmt +== 055 +SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_2b" function="equipment_named_ambiguous_2b" schema="" ctx=Call +STMT: SelectStmt +== 056 +SELECT hobbies_by_name('basketball') +-- +FUNCTION: name="hobbies_by_name" function="hobbies_by_name" schema="" ctx=Call +STMT: SelectStmt +== 057 +SELECT name, overpaid(emp.*) FROM emp +-- +TABLE: name="emp" schema="" table="emp" ctx=Select +FUNCTION: name="overpaid" function="overpaid" schema="" ctx=Call +STMT: SelectStmt +== 058 +|-- +-- Try a few cases with SQL-spec row constructor expressions +|-- +SELECT * FROM equipment(ROW('skywalking', 'mer')) +-- +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT name(equipment(ROW('skywalking', 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT *, name(equipment(h.*)) FROM hobbies_r h +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +ALIAS: "h"="hobbies_r" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +ALIAS: "h"="hobbies_r" +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/misc_functions.metadata.json b/parser/testdata/summary/postgres_regress/misc_functions.metadata.json new file mode 100644 index 0000000..b6ecb7b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/misc_functions.metadata.json @@ -0,0 +1,123 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119" + ] +} diff --git a/parser/testdata/summary/postgres_regress/misc_functions.test b/parser/testdata/summary/postgres_regress/misc_functions.test new file mode 100644 index 0000000..0b20686 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/misc_functions.test @@ -0,0 +1,781 @@ +== 001 +-- directory paths and dlsuffix are passed to us in environment variables + + +|-- +-- num_nulls() +|-- + +SELECT num_nonnulls(NULL) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 002 +SELECT num_nonnulls('1') +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 003 +SELECT num_nonnulls(NULL::text) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT num_nonnulls(NULL::text, NULL::int) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT num_nonnulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT num_nonnulls(VARIADIC '{1,2,NULL,3}'::int[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT num_nonnulls(VARIADIC '{"1","2","3","4"}'::text[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT num_nonnulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i)) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 009 +SELECT num_nulls(NULL) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT num_nulls('1') +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT num_nulls(NULL::text) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT num_nulls(NULL::text, NULL::int) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT num_nulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT num_nulls(VARIADIC '{1,2,NULL,3}'::int[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT num_nulls(VARIADIC '{"1","2","3","4"}'::text[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT num_nulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i)) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- special cases +SELECT num_nonnulls(VARIADIC NULL::text[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT num_nonnulls(VARIADIC '{}'::int[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT num_nulls(VARIADIC NULL::text[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT num_nulls(VARIADIC '{}'::int[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- should fail, one or more arguments is required +SELECT num_nonnulls() +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT num_nulls() +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +== 023 +|-- +-- canonicalize_path() +|-- + +CREATE FUNCTION test_canonicalize_path(text) + RETURNS text + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 98 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +SELECT test_canonicalize_path('/') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT test_canonicalize_path('/./abc/def/') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 026 +SELECT test_canonicalize_path('/./../abc/def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT test_canonicalize_path('/./../../abc/def/') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT test_canonicalize_path('/abc/.././def/ghi') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT test_canonicalize_path('/abc/./../def/ghi//') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT test_canonicalize_path('/abc/def/../..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT test_canonicalize_path('/abc/def/../../..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT test_canonicalize_path('/abc/def/../../../../ghi/jkl') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT test_canonicalize_path('.') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT test_canonicalize_path('./') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT test_canonicalize_path('./abc/..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT test_canonicalize_path('abc/../') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT test_canonicalize_path('abc/../def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT test_canonicalize_path('..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT test_canonicalize_path('../abc/def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT test_canonicalize_path('../abc/..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT test_canonicalize_path('../abc/../def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 042 +SELECT test_canonicalize_path('../abc/../../def/ghi') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT test_canonicalize_path('./abc/./def/.') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT test_canonicalize_path('./abc/././def/.') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 045 +SELECT test_canonicalize_path('./abc/./def/.././ghi/../../../jkl/mno') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +== 046 +|-- +-- pg_log_backend_memory_contexts() +|-- +-- Memory contexts are logged and they are not returned to the function. +-- Furthermore, their contents can vary depending on the timing. However, +-- we can at least verify that the code doesn't fail, and that the +-- permissions are set properly. +|-- + +SELECT pg_log_backend_memory_contexts(pg_backend_pid()) +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +STMT: SelectStmt +== 047 +SELECT pg_log_backend_memory_contexts(pid) FROM pg_stat_activity + WHERE backend_type = 'checkpointer' +-- +TABLE: name="pg_stat_activity" schema="" table="pg_stat_activity" ctx=Select +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=Call +FILTER: schema="" table="" column="backend_type" +STMT: SelectStmt +== 048 +CREATE ROLE regress_log_memory +-- +STMT: CreateRoleStmt +== 049 +SELECT has_function_privilege('regress_log_memory', + 'pg_log_backend_memory_contexts(integer)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 050 +-- no + +GRANT EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) + TO regress_log_memory +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=DDL +STMT: GrantStmt +== 051 +SELECT has_function_privilege('regress_log_memory', + 'pg_log_backend_memory_contexts(integer)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 052 +-- yes + +SET ROLE regress_log_memory +-- +STMT: VariableSetStmt +== 053 +SELECT pg_log_backend_memory_contexts(pg_backend_pid()) +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +STMT: SelectStmt +== 054 +RESET ROLE +-- +STMT: VariableSetStmt +== 055 +REVOKE EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) + FROM regress_log_memory +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=DDL +STMT: GrantStmt +== 056 +DROP ROLE regress_log_memory +-- +STMT: DropRoleStmt +== 057 +|-- +-- Test some built-in SRFs +|-- +-- The outputs of these are variable, so we can't just print their results +-- directly, but we can at least verify that the code doesn't fail. +|-- +select setting as segsize +from pg_settings where name = 'wal_segment_size' + +select count(*) > 0 as ok from pg_ls_waldir() +-- +ERROR: syntax error at or near "select" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 058 +-- Test ProjectSet as well as FunctionScan +select count(*) > 0 as ok from (select pg_ls_waldir()) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_waldir" function="pg_ls_waldir" schema="" ctx=Call +STMT: SelectStmt +== 059 +-- Test not-run-to-completion cases. +select * from pg_ls_waldir() limit 0 +-- +FUNCTION: name="pg_ls_waldir" function="pg_ls_waldir" schema="" ctx=Call +STMT: SelectStmt +== 060 +select count(*) > 0 as ok from (select * from pg_ls_waldir() limit 1) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_waldir" function="pg_ls_waldir" schema="" ctx=Call +STMT: SelectStmt +== 061 +select (w).size = :segsize as ok +from (select pg_ls_waldir() w) ss where length((w).name) = 24 limit 1 +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 062 +select count(*) >= 0 as ok from pg_ls_archive_statusdir() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_archive_statusdir" function="pg_ls_archive_statusdir" schema="" ctx=Call +STMT: SelectStmt +== 063 +-- pg_read_file() +select length(pg_read_file('postmaster.pid')) > 20 +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +== 064 +select length(pg_read_file('postmaster.pid', 1, 20)) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +== 065 +-- Test missing_ok +select pg_read_file('does not exist') +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +== 066 +-- error +select pg_read_file('does not exist', true) IS NULL +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +== 067 +-- ok +-- Test invalid argument +select pg_read_file('does not exist', 0, -1) +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +== 068 +-- error +select pg_read_file('does not exist', 0, -1, true) +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +== 069 +-- error + +-- pg_read_binary_file() +select length(pg_read_binary_file('postmaster.pid')) > 20 +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +== 070 +select length(pg_read_binary_file('postmaster.pid', 1, 20)) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +== 071 +-- Test missing_ok +select pg_read_binary_file('does not exist') +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +== 072 +-- error +select pg_read_binary_file('does not exist', true) IS NULL +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +== 073 +-- ok +-- Test invalid argument +select pg_read_binary_file('does not exist', 0, -1) +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +== 074 +-- error +select pg_read_binary_file('does not exist', 0, -1, true) +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +== 075 +-- error + +-- pg_stat_file() +select size > 20, isdir from pg_stat_file('postmaster.pid') +-- +FUNCTION: name="pg_stat_file" function="pg_stat_file" schema="" ctx=Call +STMT: SelectStmt +== 076 +-- pg_ls_dir() +select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1 +-- +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 077 +-- Test missing_ok (second argument) +select pg_ls_dir('does not exist', false, false) +-- +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +STMT: SelectStmt +== 078 +-- error +select pg_ls_dir('does not exist', true, false) +-- +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +STMT: SelectStmt +== 079 +-- ok +-- Test include_dot_dirs (third argument) +select count(*) = 1 as dot_found + from pg_ls_dir('.', false, true) as ls where ls = '.' +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +FILTER: schema="" table="" column="ls" +STMT: SelectStmt +== 080 +select count(*) = 1 as dot_found + from pg_ls_dir('.', false, false) as ls where ls = '.' +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +FILTER: schema="" table="" column="ls" +STMT: SelectStmt +== 081 +-- pg_timezone_names() +select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1 +-- +FUNCTION: name="pg_timezone_names" function="pg_timezone_names" schema="" ctx=Call +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 082 +-- pg_tablespace_databases() +select count(*) > 0 from + (select pg_tablespace_databases(oid) as pts from pg_tablespace + where spcname = 'pg_default') pts + join pg_database db on pts.pts = db.oid +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "db"="pg_database" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_tablespace_databases" function="pg_tablespace_databases" schema="" ctx=Call +FILTER: schema="" table="" column="spcname" +STMT: SelectStmt +== 083 +|-- +-- Test replication slot directory functions +|-- +CREATE ROLE regress_slot_dir_funcs +-- +STMT: CreateRoleStmt +== 084 +-- Not available by default. +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalsnapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalmapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 086 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_replslotdir(text)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 087 +GRANT pg_monitor TO regress_slot_dir_funcs +-- +STMT: GrantRoleStmt +== 088 +-- Role is now part of pg_monitor, so these are available. +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalsnapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 089 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalmapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 090 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_replslotdir(text)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 091 +DROP ROLE regress_slot_dir_funcs +-- +STMT: DropRoleStmt +== 092 +|-- +-- Test adding a support function to a subject function +|-- + +CREATE FUNCTION my_int_eq(int, int) RETURNS bool + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$int4eq$$ +-- +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 093 +-- By default, planner does not think that's selective +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FILTER: schema="" table="a" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 094 +-- With support function that knows it's int4eq, we get a different plan +CREATE FUNCTION test_support_func(internal) + RETURNS internal + AS :'regresslib', 'test_support_func' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 146 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 095 +ALTER FUNCTION my_int_eq(int, int) SUPPORT test_support_func +-- +STMT: AlterFunctionStmt +== 096 +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FILTER: schema="" table="a" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 097 +-- Also test non-default rowcount estimate +CREATE FUNCTION my_gen_series(int, int) RETURNS SETOF integer + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$generate_series_int4$$ + SUPPORT test_support_func +-- +FUNCTION: name="my_gen_series" function="my_gen_series" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 098 +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,1000) g ON a.unique1 = g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="my_gen_series" function="my_gen_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 099 +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="my_gen_series" function="my_gen_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 100 +-- Test functions for control data +SELECT count(*) > 0 AS ok FROM pg_control_checkpoint() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_checkpoint" function="pg_control_checkpoint" schema="" ctx=Call +STMT: SelectStmt +== 101 +SELECT count(*) > 0 AS ok FROM pg_control_init() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_init" function="pg_control_init" schema="" ctx=Call +STMT: SelectStmt +== 102 +SELECT count(*) > 0 AS ok FROM pg_control_recovery() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_recovery" function="pg_control_recovery" schema="" ctx=Call +STMT: SelectStmt +== 103 +SELECT count(*) > 0 AS ok FROM pg_control_system() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_system" function="pg_control_system" schema="" ctx=Call +STMT: SelectStmt +== 104 +-- pg_split_walfile_name, pg_walfile_name & pg_walfile_name_offset +SELECT * FROM pg_split_walfile_name(NULL) +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +== 105 +SELECT * FROM pg_split_walfile_name('invalid') +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +== 106 +SELECT segment_number > 0 AS ok_segment_number, timeline_id + FROM pg_split_walfile_name('000000010000000100000000') +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +== 107 +SELECT segment_number > 0 AS ok_segment_number, timeline_id + FROM pg_split_walfile_name('ffffffFF00000001000000af') +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT setting::int8 AS segment_size +FROM pg_settings +WHERE name = 'wal_segment_size' +SELECT segment_number, file_offset +FROM pg_walfile_name_offset('0/0'::pg_lsn + :segment_size), + pg_split_walfile_name(file_name) +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 87 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 109 +SELECT segment_number, file_offset +FROM pg_walfile_name_offset('0/0'::pg_lsn + :segment_size + 1), + pg_split_walfile_name(file_name) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 80 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 110 +SELECT segment_number, file_offset = :segment_size - 1 +FROM pg_walfile_name_offset('0/0'::pg_lsn + :segment_size - 1), + pg_split_walfile_name(file_name) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 111 +-- pg_current_logfile +CREATE ROLE regress_current_logfile +-- +STMT: CreateRoleStmt +== 112 +-- not available by default +SELECT has_function_privilege('regress_current_logfile', + 'pg_current_logfile()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 113 +GRANT pg_monitor TO regress_current_logfile +-- +STMT: GrantRoleStmt +== 114 +-- role has privileges of pg_monitor and can execute the function +SELECT has_function_privilege('regress_current_logfile', + 'pg_current_logfile()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +== 115 +DROP ROLE regress_current_logfile +-- +STMT: DropRoleStmt +== 116 +-- pg_column_toast_chunk_id +CREATE TABLE test_chunk_id (a TEXT, b TEXT STORAGE EXTERNAL) +-- +TABLE: name="test_chunk_id" schema="" table="test_chunk_id" ctx=DDL +STMT: CreateStmt +== 117 +INSERT INTO test_chunk_id VALUES ('x', repeat('x', 8192)) +-- +TABLE: name="test_chunk_id" schema="" table="test_chunk_id" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 118 +SELECT t.relname AS toastrel FROM pg_class c + LEFT JOIN pg_class t ON c.reltoastrelid = t.oid + WHERE c.relname = 'test_chunk_id' +SELECT pg_column_toast_chunk_id(a) IS NULL, + pg_column_toast_chunk_id(b) IN (SELECT chunk_id FROM pg_toast.:toastrel) + FROM test_chunk_id +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 132 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 119 +DROP TABLE test_chunk_id +-- +TABLE: name="test_chunk_id" schema="" table="test_chunk_id" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/misc_sanity.metadata.json b/parser/testdata/summary/postgres_regress/misc_sanity.metadata.json new file mode 100644 index 0000000..e8e06a4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/misc_sanity.metadata.json @@ -0,0 +1,9 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005" + ] +} diff --git a/parser/testdata/summary/postgres_regress/misc_sanity.test b/parser/testdata/summary/postgres_regress/misc_sanity.test new file mode 100644 index 0000000..15ef1c6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/misc_sanity.test @@ -0,0 +1,118 @@ +== 001 +|-- +-- MISC_SANITY +-- Sanity checks for common errors in making system tables that don't fit +-- comfortably into either opr_sanity or type_sanity. +|-- +-- Every test failure in this file should be closely inspected. +-- The description of the failing test should be read carefully before +-- adjusting the expected output. In most cases, the queries should +-- not find *any* matching entries. +|-- +-- NB: run this test early, because some later tests create bogus entries. + + +-- **************** pg_depend **************** + +-- Look for illegal values in pg_depend fields. + +SELECT * +FROM pg_depend as d1 +WHERE refclassid = 0 OR refobjid = 0 OR + classid = 0 OR objid = 0 OR + deptype NOT IN ('a', 'e', 'i', 'n', 'x', 'P', 'S') +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +ALIAS: "d1"="pg_depend" +FILTER: schema="" table="" column="refclassid" +FILTER: schema="" table="" column="refobjid" +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +FILTER: schema="" table="" column="deptype" +STMT: SelectStmt +== 002 +-- **************** pg_shdepend **************** + +-- Look for illegal values in pg_shdepend fields. + +SELECT * +FROM pg_shdepend as d1 +WHERE refclassid = 0 OR refobjid = 0 OR + classid = 0 OR objid = 0 OR + deptype NOT IN ('a', 'i', 'o', 'r', 't') +-- +TABLE: name="pg_shdepend" schema="" table="pg_shdepend" ctx=Select +ALIAS: "d1"="pg_shdepend" +FILTER: schema="" table="" column="refclassid" +FILTER: schema="" table="" column="refobjid" +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +FILTER: schema="" table="" column="deptype" +STMT: SelectStmt +== 003 +-- **************** pg_class **************** + +-- Look for system tables with varlena columns but no toast table. All +-- system tables with toastable columns should have toast tables, with +-- the following exceptions: +-- 1. pg_class, pg_attribute, and pg_index, due to fear of recursive +-- dependencies as toast tables depend on them. +-- 2. pg_largeobject and pg_largeobject_metadata. Large object catalogs +-- and toast tables are mutually exclusive and large object data is handled +-- as user data by pg_upgrade, which would cause failures. + +SELECT relname, attname, atttypid::regtype +FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid +WHERE c.oid < 16384 AND + reltoastrelid = 0 AND + relkind = 'r' AND + attstorage != 'p' +ORDER BY 1, 2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="reltoastrelid" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="attstorage" +STMT: SelectStmt +== 004 +-- system catalogs without primary keys +|-- +-- Current exceptions: +-- * pg_depend, pg_shdepend don't have a unique key +SELECT relname +FROM pg_class +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'r' + AND pg_class.oid NOT IN (SELECT indrelid FROM pg_index WHERE indisprimary) +ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indisprimary" +STMT: SelectStmt +== 005 +-- system catalog unique indexes not wrapped in a constraint +-- (There should be none.) +SELECT relname +FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'i' + AND i.indisunique + AND c.oid NOT IN (SELECT conindid FROM pg_constraint) +ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="i" column="indisunique" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/money.metadata.json b/parser/testdata/summary/postgres_regress/money.metadata.json new file mode 100644 index 0000000..c169184 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/money.metadata.json @@ -0,0 +1,113 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109" + ] +} diff --git a/parser/testdata/summary/postgres_regress/money.test b/parser/testdata/summary/postgres_regress/money.test new file mode 100644 index 0000000..bf8b4fa --- /dev/null +++ b/parser/testdata/summary/postgres_regress/money.test @@ -0,0 +1,525 @@ +== 001 +|-- +-- MONEY +|-- +-- Note that we assume lc_monetary has been set to C. +|-- + +CREATE TABLE money_data (m money) +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO money_data VALUES ('123') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 004 +SELECT m + '123' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 005 +SELECT m + '123.45' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 006 +SELECT m - '123.45' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 007 +SELECT m / '2'::money FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 008 +SELECT m * 2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 009 +SELECT 2 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 010 +SELECT m / 2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 011 +SELECT m * 2::int2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 012 +SELECT 2::int2 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 013 +SELECT m / 2::int2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 014 +SELECT m * 2::int8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 015 +SELECT 2::int8 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 016 +SELECT m / 2::int8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 017 +SELECT m * 2::float8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 018 +SELECT 2::float8 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 019 +SELECT m / 2::float8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 020 +SELECT m * 2::float4 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 021 +SELECT 2::float4 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 022 +SELECT m / 2::float4 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 023 +-- All true +SELECT m = '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 024 +SELECT m != '$124.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 025 +SELECT m <= '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 026 +SELECT m >= '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 027 +SELECT m < '$124.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 028 +SELECT m > '$122.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 029 +-- All false +SELECT m = '$123.01' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 030 +SELECT m != '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 031 +SELECT m <= '$122.99' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 032 +SELECT m >= '$123.01' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 033 +SELECT m > '$124.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 034 +SELECT m < '$122.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 035 +SELECT cashlarger(m, '$124.00') FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cashlarger" function="cashlarger" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT cashsmaller(m, '$124.00') FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cashsmaller" function="cashsmaller" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT cash_words(m) FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cash_words" function="cash_words" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT cash_words(m + '1.23') FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cash_words" function="cash_words" schema="" ctx=Call +STMT: SelectStmt +== 039 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +== 040 +INSERT INTO money_data VALUES ('$123.45') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 042 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +== 043 +INSERT INTO money_data VALUES ('$123.451') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 045 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +== 046 +INSERT INTO money_data VALUES ('$123.454') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 048 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +== 049 +INSERT INTO money_data VALUES ('$123.455') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 051 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +== 052 +INSERT INTO money_data VALUES ('$123.456') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 054 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +== 055 +INSERT INTO money_data VALUES ('$123.459') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +== 057 +-- input checks +SELECT '1234567890'::money +-- +STMT: SelectStmt +== 058 +SELECT '12345678901234567'::money +-- +STMT: SelectStmt +== 059 +SELECT '123456789012345678'::money +-- +STMT: SelectStmt +== 060 +SELECT '9223372036854775807'::money +-- +STMT: SelectStmt +== 061 +SELECT '-12345'::money +-- +STMT: SelectStmt +== 062 +SELECT '-1234567890'::money +-- +STMT: SelectStmt +== 063 +SELECT '-12345678901234567'::money +-- +STMT: SelectStmt +== 064 +SELECT '-123456789012345678'::money +-- +STMT: SelectStmt +== 065 +SELECT '-9223372036854775808'::money +-- +STMT: SelectStmt +== 066 +-- special characters +SELECT '(1)'::money +-- +STMT: SelectStmt +== 067 +SELECT '($123,456.78)'::money +-- +STMT: SelectStmt +== 068 +-- test non-error-throwing API +SELECT pg_input_is_valid('\x0001', 'money') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT * FROM pg_input_error_info('\x0001', 'money') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT pg_input_is_valid('192233720368547758.07', 'money') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT * FROM pg_input_error_info('192233720368547758.07', 'money') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 072 +-- documented minimums and maximums +SELECT '-92233720368547758.08'::money +-- +STMT: SelectStmt +== 073 +SELECT '92233720368547758.07'::money +-- +STMT: SelectStmt +== 074 +SELECT '-92233720368547758.09'::money +-- +STMT: SelectStmt +== 075 +SELECT '92233720368547758.08'::money +-- +STMT: SelectStmt +== 076 +-- rounding +SELECT '-92233720368547758.085'::money +-- +STMT: SelectStmt +== 077 +SELECT '92233720368547758.075'::money +-- +STMT: SelectStmt +== 078 +-- rounding vs. truncation in division +SELECT '878.08'::money / 11::float8 +-- +STMT: SelectStmt +== 079 +SELECT '878.08'::money / 11::float4 +-- +STMT: SelectStmt +== 080 +SELECT '878.08'::money / 11::bigint +-- +STMT: SelectStmt +== 081 +SELECT '878.08'::money / 11::int +-- +STMT: SelectStmt +== 082 +SELECT '878.08'::money / 11::smallint +-- +STMT: SelectStmt +== 083 +-- check for precision loss in division +SELECT '90000000000000099.00'::money / 10::bigint +-- +STMT: SelectStmt +== 084 +SELECT '90000000000000099.00'::money / 10::int +-- +STMT: SelectStmt +== 085 +SELECT '90000000000000099.00'::money / 10::smallint +-- +STMT: SelectStmt +== 086 +-- Cast int4/int8/numeric to money +SELECT 1234567890::money +-- +STMT: SelectStmt +== 087 +SELECT 12345678901234567::money +-- +STMT: SelectStmt +== 088 +SELECT (-12345)::money +-- +STMT: SelectStmt +== 089 +SELECT (-1234567890)::money +-- +STMT: SelectStmt +== 090 +SELECT (-12345678901234567)::money +-- +STMT: SelectStmt +== 091 +SELECT 1234567890::int4::money +-- +STMT: SelectStmt +== 092 +SELECT 12345678901234567::int8::money +-- +STMT: SelectStmt +== 093 +SELECT 12345678901234567::numeric::money +-- +STMT: SelectStmt +== 094 +SELECT (-1234567890)::int4::money +-- +STMT: SelectStmt +== 095 +SELECT (-12345678901234567)::int8::money +-- +STMT: SelectStmt +== 096 +SELECT (-12345678901234567)::numeric::money +-- +STMT: SelectStmt +== 097 +-- Cast from money to numeric +SELECT '12345678901234567'::money::numeric +-- +STMT: SelectStmt +== 098 +SELECT '-12345678901234567'::money::numeric +-- +STMT: SelectStmt +== 099 +SELECT '92233720368547758.07'::money::numeric +-- +STMT: SelectStmt +== 100 +SELECT '-92233720368547758.08'::money::numeric +-- +STMT: SelectStmt +== 101 +-- overflow checks +SELECT '92233720368547758.07'::money + '0.01'::money +-- +STMT: SelectStmt +== 102 +SELECT '-92233720368547758.08'::money - '0.01'::money +-- +STMT: SelectStmt +== 103 +SELECT '92233720368547758.07'::money * 2::float8 +-- +STMT: SelectStmt +== 104 +SELECT '-1'::money / 1.175494e-38::float4 +-- +STMT: SelectStmt +== 105 +SELECT '92233720368547758.07'::money * 2::int4 +-- +STMT: SelectStmt +== 106 +SELECT '1'::money / 0::int2 +-- +STMT: SelectStmt +== 107 +SELECT '42'::money * 'inf'::float8 +-- +STMT: SelectStmt +== 108 +SELECT '42'::money * '-inf'::float8 +-- +STMT: SelectStmt +== 109 +SELECT '42'::money * 'nan'::float4 +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/multirangetypes.metadata.json b/parser/testdata/summary/postgres_regress/multirangetypes.metadata.json new file mode 100644 index 0000000..6769ac6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/multirangetypes.metadata.json @@ -0,0 +1,609 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605" + ] +} diff --git a/parser/testdata/summary/postgres_regress/multirangetypes.test b/parser/testdata/summary/postgres_regress/multirangetypes.test new file mode 100644 index 0000000..75b19b6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/multirangetypes.test @@ -0,0 +1,4086 @@ +== 001 +-- Tests for multirange data types. + +|-- +-- test input parser +|-- + +-- negative tests; should fail +select ''::textmultirange +-- +STMT: SelectStmt +== 002 +select '{,}'::textmultirange +-- +STMT: SelectStmt +== 003 +select '{(,)}.'::textmultirange +-- +STMT: SelectStmt +== 004 +select '{[a,c),}'::textmultirange +-- +STMT: SelectStmt +== 005 +select '{,[a,c)}'::textmultirange +-- +STMT: SelectStmt +== 006 +select '{-[a,z)}'::textmultirange +-- +STMT: SelectStmt +== 007 +select '{[a,z) - }'::textmultirange +-- +STMT: SelectStmt +== 008 +select '{(",a)}'::textmultirange +-- +STMT: SelectStmt +== 009 +select '{(,,a)}'::textmultirange +-- +STMT: SelectStmt +== 010 +select '{(),a)}'::textmultirange +-- +STMT: SelectStmt +== 011 +select '{(a,))}'::textmultirange +-- +STMT: SelectStmt +== 012 +select '{(],a)}'::textmultirange +-- +STMT: SelectStmt +== 013 +select '{(a,])}'::textmultirange +-- +STMT: SelectStmt +== 014 +select '{[z,a]}'::textmultirange +-- +STMT: SelectStmt +== 015 +-- should succeed +select '{}'::textmultirange +-- +STMT: SelectStmt +== 016 +select ' {} '::textmultirange +-- +STMT: SelectStmt +== 017 +select ' { empty, empty } '::textmultirange +-- +STMT: SelectStmt +== 018 +select ' {( " a " " a ", " z " " z " ) }'::textmultirange +-- +STMT: SelectStmt +== 019 +select textrange('\\\\', repeat('a', 200))::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 020 +select '{(,z)}'::textmultirange +-- +STMT: SelectStmt +== 021 +select '{(a,)}'::textmultirange +-- +STMT: SelectStmt +== 022 +select '{[,z]}'::textmultirange +-- +STMT: SelectStmt +== 023 +select '{[a,]}'::textmultirange +-- +STMT: SelectStmt +== 024 +select '{(,)}'::textmultirange +-- +STMT: SelectStmt +== 025 +select '{[ , ]}'::textmultirange +-- +STMT: SelectStmt +== 026 +select '{["",""]}'::textmultirange +-- +STMT: SelectStmt +== 027 +select '{[",",","]}'::textmultirange +-- +STMT: SelectStmt +== 028 +select '{["\\","\\"]}'::textmultirange +-- +STMT: SelectStmt +== 029 +select '{["""","\""]}'::textmultirange +-- +STMT: SelectStmt +== 030 +select '{(\\,a)}'::textmultirange +-- +STMT: SelectStmt +== 031 +select '{((,z)}'::textmultirange +-- +STMT: SelectStmt +== 032 +select '{([,z)}'::textmultirange +-- +STMT: SelectStmt +== 033 +select '{(!,()}'::textmultirange +-- +STMT: SelectStmt +== 034 +select '{(!,[)}'::textmultirange +-- +STMT: SelectStmt +== 035 +select '{[a,a]}'::textmultirange +-- +STMT: SelectStmt +== 036 +select '{[a,a],[a,b]}'::textmultirange +-- +STMT: SelectStmt +== 037 +select '{[a,b), [b,e]}'::textmultirange +-- +STMT: SelectStmt +== 038 +select '{[a,d), [b,f]}'::textmultirange +-- +STMT: SelectStmt +== 039 +select '{[a,a],[b,b]}'::textmultirange +-- +STMT: SelectStmt +== 040 +-- without canonicalization, we can't join these: +select '{[a,a], [b,b]}'::textmultirange +-- +STMT: SelectStmt +== 041 +-- with canonicalization, we can join these: +select '{[1,2], [3,4]}'::int4multirange +-- +STMT: SelectStmt +== 042 +select '{[a,a], [b,b], [c,c]}'::textmultirange +-- +STMT: SelectStmt +== 043 +select '{[a,d], [b,e]}'::textmultirange +-- +STMT: SelectStmt +== 044 +select '{[a,d), [d,e)}'::textmultirange +-- +STMT: SelectStmt +== 045 +-- these are allowed but normalize to empty: +select '{[a,a)}'::textmultirange +-- +STMT: SelectStmt +== 046 +select '{(a,a]}'::textmultirange +-- +STMT: SelectStmt +== 047 +select '{(a,a)}'::textmultirange +-- +STMT: SelectStmt +== 048 +-- Also try it with non-error-throwing API +select pg_input_is_valid('{[1,2], [4,5]}', 'int4multirange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 049 +select pg_input_is_valid('{[1,2], [4,5]', 'int4multirange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 050 +select * from pg_input_error_info('{[1,2], [4,5]', 'int4multirange') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 051 +select pg_input_is_valid('{[1,2], [4,zed]}', 'int4multirange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 052 +select * from pg_input_error_info('{[1,2], [4,zed]}', 'int4multirange') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 053 +|-- +-- test the constructor +--- +select textmultirange() +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +STMT: SelectStmt +== 054 +select textmultirange(textrange('a', 'c')) +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 055 +select textmultirange(textrange('a', 'c'), textrange('f', 'g')) +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 056 +select textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd')) +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 057 +|-- +-- test casts, both a built-in range type and a user-defined one: +|-- +select 'empty'::int4range::int4multirange +-- +STMT: SelectStmt +== 058 +select int4range(1, 3)::int4multirange +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 059 +select int4range(1, null)::int4multirange +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 060 +select int4range(null, null)::int4multirange +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 061 +select 'empty'::textrange::textmultirange +-- +STMT: SelectStmt +== 062 +select textrange('a', 'c')::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 063 +select textrange('a', null)::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 064 +select textrange(null, null)::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 065 +|-- +-- test unnest(multirange) function +|-- +select unnest(int4multirange(int4range('5', '6'), int4range('1', '2'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 066 +select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 067 +select unnest(textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 068 +|-- +-- create some test data and test the operators +|-- + +CREATE TABLE nummultirange_test (nmr NUMMULTIRANGE) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DDL +STMT: CreateStmt +== 069 +CREATE INDEX nummultirange_test_btree ON nummultirange_test(nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DDL +STMT: IndexStmt +== 070 +INSERT INTO nummultirange_test VALUES('{}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +INSERT INTO nummultirange_test VALUES('{[,)}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +INSERT INTO nummultirange_test VALUES('{[3,]}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +INSERT INTO nummultirange_test VALUES('{[,), [3,]}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 074 +INSERT INTO nummultirange_test VALUES('{[, 5)}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +INSERT INTO nummultirange_test VALUES(nummultirange()) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 076 +INSERT INTO nummultirange_test VALUES(nummultirange(variadic '{}'::numrange[])) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 077 +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.1, 2.2))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 078 +INSERT INTO nummultirange_test VALUES('{empty}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 081 +SELECT nmr, isempty(nmr), lower(nmr), upper(nmr) FROM nummultirange_test ORDER BY nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="isempty" function="isempty" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT nmr, lower_inc(nmr), lower_inf(nmr), upper_inc(nmr), upper_inf(nmr) FROM nummultirange_test ORDER BY nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="lower_inc" function="lower_inc" schema="" ctx=Call +FUNCTION: name="lower_inf" function="lower_inf" schema="" ctx=Call +FUNCTION: name="upper_inc" function="upper_inc" schema="" ctx=Call +FUNCTION: name="upper_inf" function="upper_inf" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT * FROM nummultirange_test WHERE nmr = '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 084 +SELECT * FROM nummultirange_test WHERE nmr = '{(,5)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 085 +SELECT * FROM nummultirange_test WHERE nmr = '{[3,)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 086 +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 087 +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7],[1.9,2.1)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 088 +SELECT * FROM nummultirange_test WHERE nmr < '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 089 +SELECT * FROM nummultirange_test WHERE nmr < '{[-1000.0, -1000.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 090 +SELECT * FROM nummultirange_test WHERE nmr < '{[0.0, 1.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 091 +SELECT * FROM nummultirange_test WHERE nmr < '{[1000.0, 1001.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 092 +SELECT * FROM nummultirange_test WHERE nmr <= '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 093 +SELECT * FROM nummultirange_test WHERE nmr <= '{[3,)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 094 +SELECT * FROM nummultirange_test WHERE nmr >= '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 095 +SELECT * FROM nummultirange_test WHERE nmr >= '{[3,)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 096 +SELECT * FROM nummultirange_test WHERE nmr > '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 097 +SELECT * FROM nummultirange_test WHERE nmr > '{[-1000.0, -1000.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 098 +SELECT * FROM nummultirange_test WHERE nmr > '{[0.0, 1.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 099 +SELECT * FROM nummultirange_test WHERE nmr > '{[1000.0, 1001.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 100 +SELECT * FROM nummultirange_test WHERE nmr <> '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 101 +SELECT * FROM nummultirange_test WHERE nmr <> '{(,5)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 102 +select nummultirange(numrange(2.0, 1.0)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 103 +select nummultirange(numrange(5.0, 6.0), numrange(1.0, 2.0)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 104 +analyze nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DDL +STMT: VacuumStmt +== 105 +-- overlaps +SELECT * FROM nummultirange_test WHERE range_overlaps_multirange(numrange(4.0, 4.2), nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_overlaps_multirange" function="range_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_overlaps_multirange" function="range_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 106 +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) && nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 107 +SELECT * FROM nummultirange_test WHERE multirange_overlaps_range(nmr, numrange(4.0, 4.2)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_overlaps_range" function="multirange_overlaps_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange_overlaps_range" function="multirange_overlaps_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 108 +SELECT * FROM nummultirange_test WHERE nmr && numrange(4.0, 4.2) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 109 +SELECT * FROM nummultirange_test WHERE multirange_overlaps_multirange(nmr, nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_overlaps_multirange" function="multirange_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange_overlaps_multirange" function="multirange_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 110 +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 111 +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 112 +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0), numrange(8.0, 9.0)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 113 +-- mr contains x +SELECT * FROM nummultirange_test WHERE multirange_contains_elem(nmr, 4.0) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contains_elem" function="multirange_contains_elem" schema="" ctx=Call +FUNCTION: name="multirange_contains_elem" function="multirange_contains_elem" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 114 +SELECT * FROM nummultirange_test WHERE nmr @> 4.0 +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 115 +SELECT * FROM nummultirange_test WHERE multirange_contains_range(nmr, numrange(4.0, 4.2)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contains_range" function="multirange_contains_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange_contains_range" function="multirange_contains_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 116 +SELECT * FROM nummultirange_test WHERE nmr @> numrange(4.0, 4.2) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 117 +SELECT * FROM nummultirange_test WHERE multirange_contains_multirange(nmr, '{[4.0,4.2), [6.0, 8.0)}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contains_multirange" function="multirange_contains_multirange" schema="" ctx=Call +FUNCTION: name="multirange_contains_multirange" function="multirange_contains_multirange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 118 +SELECT * FROM nummultirange_test WHERE nmr @> '{[4.0,4.2), [6.0, 8.0)}'::nummultirange +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 119 +-- x is contained by mr +SELECT * FROM nummultirange_test WHERE elem_contained_by_multirange(4.0, nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="elem_contained_by_multirange" function="elem_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="elem_contained_by_multirange" function="elem_contained_by_multirange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 120 +SELECT * FROM nummultirange_test WHERE 4.0 <@ nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 121 +SELECT * FROM nummultirange_test WHERE range_contained_by_multirange(numrange(4.0, 4.2), nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_contained_by_multirange" function="range_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_contained_by_multirange" function="range_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 122 +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) <@ nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 123 +SELECT * FROM nummultirange_test WHERE multirange_contained_by_multirange('{[4.0,4.2), [6.0, 8.0)}', nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contained_by_multirange" function="multirange_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="multirange_contained_by_multirange" function="multirange_contained_by_multirange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 124 +SELECT * FROM nummultirange_test WHERE '{[4.0,4.2), [6.0, 8.0)}'::nummultirange <@ nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 125 +-- overlaps +SELECT 'empty'::numrange && nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 126 +SELECT 'empty'::numrange && nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 127 +SELECT nummultirange() && 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 128 +SELECT nummultirange(numrange(1,2)) && 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 129 +SELECT nummultirange() && nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 130 +SELECT nummultirange() && nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 131 +SELECT nummultirange(numrange(1,2)) && nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 132 +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(7,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 133 +SELECT nummultirange(numrange(1,2), numrange(7,8)) && nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 134 +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(3.5,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 135 +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 136 +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 137 +select '{(10,20),(30,40),(50,60)}'::nummultirange && '(42,92)'::numrange +-- +STMT: SelectStmt +== 138 +-- contains +SELECT nummultirange() @> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 139 +SELECT nummultirange() @> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 140 +SELECT nummultirange(numrange(null,null)) @> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT nummultirange(numrange(null,null)) @> numrange(null,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 142 +SELECT nummultirange(numrange(null,null)) @> numrange(2,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 143 +SELECT nummultirange(numrange(null,5)) @> numrange(null,3) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 144 +SELECT nummultirange(numrange(null,5)) @> numrange(null,8) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 145 +SELECT nummultirange(numrange(5,null)) @> numrange(8,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 146 +SELECT nummultirange(numrange(5,null)) @> numrange(3,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 147 +SELECT nummultirange(numrange(1,5)) @> numrange(8,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 148 +SELECT nummultirange(numrange(1,5)) @> numrange(3,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 149 +SELECT nummultirange(numrange(1,5)) @> numrange(1,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 150 +SELECT nummultirange(numrange(1,5)) @> numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 151 +SELECT nummultirange(numrange(-4,-2), numrange(1,5)) @> numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 152 +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 153 +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(6,7) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 154 +SELECT nummultirange(numrange(1,5), numrange(6,9)) @> numrange(6,7) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT '{[1,5)}'::nummultirange @> '{[1,5)}' +-- +STMT: SelectStmt +== 156 +SELECT '{[-4,-2), [1,5)}'::nummultirange @> '{[1,5)}' +-- +STMT: SelectStmt +== 157 +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[1,5)}' +-- +STMT: SelectStmt +== 158 +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[6,7)}' +-- +STMT: SelectStmt +== 159 +SELECT '{[1,5), [6,9)}'::nummultirange @> '{[6,7)}' +-- +STMT: SelectStmt +== 160 +select '{(10,20),(30,40),(50,60)}'::nummultirange @> '(52,56)'::numrange +-- +STMT: SelectStmt +== 161 +SELECT numrange(null,null) @> nummultirange(numrange(1,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 162 +SELECT numrange(null,null) @> nummultirange(numrange(null,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 163 +SELECT numrange(null,null) @> nummultirange(numrange(2,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 164 +SELECT numrange(null,5) @> nummultirange(numrange(null,3)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 165 +SELECT numrange(null,5) @> nummultirange(numrange(null,8)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 166 +SELECT numrange(5,null) @> nummultirange(numrange(8,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 167 +SELECT numrange(5,null) @> nummultirange(numrange(3,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 168 +SELECT numrange(1,5) @> nummultirange(numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 169 +SELECT numrange(1,5) @> nummultirange(numrange(3,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 170 +SELECT numrange(1,5) @> nummultirange(numrange(1,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 171 +SELECT numrange(1,5) @> nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 172 +SELECT numrange(1,9) @> nummultirange(numrange(-4,-2), numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 173 +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 174 +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 175 +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,10)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 176 +SELECT '{[1,9)}' @> '{[1,5)}'::nummultirange +-- +STMT: SelectStmt +== 177 +SELECT '{[1,9)}' @> '{[-4,-2), [1,5)}'::nummultirange +-- +STMT: SelectStmt +== 178 +SELECT '{[1,9)}' @> '{[1,5), [8,9)}'::nummultirange +-- +STMT: SelectStmt +== 179 +SELECT '{[1,9)}' @> '{[1,5), [6,9)}'::nummultirange +-- +STMT: SelectStmt +== 180 +SELECT '{[1,9)}' @> '{[1,5), [6,10)}'::nummultirange +-- +STMT: SelectStmt +== 181 +-- is contained by +SELECT nummultirange() <@ nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 182 +SELECT 'empty'::numrange <@ nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 183 +SELECT numrange(1,2) <@ nummultirange(numrange(null,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 184 +SELECT numrange(null,2) <@ nummultirange(numrange(null,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 185 +SELECT numrange(2,null) <@ nummultirange(numrange(null,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 186 +SELECT numrange(null,3) <@ nummultirange(numrange(null,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 187 +SELECT numrange(null,8) <@ nummultirange(numrange(null,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 188 +SELECT numrange(8,null) <@ nummultirange(numrange(5,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 189 +SELECT numrange(3,null) <@ nummultirange(numrange(5,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 190 +SELECT numrange(8,9) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 191 +SELECT numrange(3,9) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 192 +SELECT numrange(1,4) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 193 +SELECT numrange(1,5) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 194 +SELECT numrange(1,5) <@ nummultirange(numrange(-4,-2), numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 195 +SELECT numrange(1,5) <@ nummultirange(numrange(1,5), numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 196 +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 197 +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(6,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 198 +SELECT '{[1,5)}' <@ '{[1,5)}'::nummultirange +-- +STMT: SelectStmt +== 199 +SELECT '{[1,5)}' <@ '{[-4,-2), [1,5)}'::nummultirange +-- +STMT: SelectStmt +== 200 +SELECT '{[1,5)}' <@ '{[1,5), [8,9)}'::nummultirange +-- +STMT: SelectStmt +== 201 +SELECT '{[6,7)}' <@ '{[1,5), [8,9)}'::nummultirange +-- +STMT: SelectStmt +== 202 +SELECT '{[6,7)}' <@ '{[1,5), [6,9)}'::nummultirange +-- +STMT: SelectStmt +== 203 +SELECT nummultirange(numrange(1,2)) <@ numrange(null,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 204 +SELECT nummultirange(numrange(null,2)) <@ numrange(null,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 205 +SELECT nummultirange(numrange(2,null)) <@ numrange(null,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 206 +SELECT nummultirange(numrange(null,3)) <@ numrange(null,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 207 +SELECT nummultirange(numrange(null,8)) <@ numrange(null,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 208 +SELECT nummultirange(numrange(8,null)) <@ numrange(5,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 209 +SELECT nummultirange(numrange(3,null)) <@ numrange(5,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 210 +SELECT nummultirange(numrange(8,9)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 211 +SELECT nummultirange(numrange(3,9)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 212 +SELECT nummultirange(numrange(1,4)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 213 +SELECT nummultirange(numrange(1,5)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 214 +SELECT nummultirange(numrange(-4,-2), numrange(1,5)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 215 +SELECT nummultirange(numrange(1,5), numrange(8,9)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 216 +SELECT nummultirange(numrange(1,5), numrange(6,9)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 217 +SELECT nummultirange(numrange(1,5), numrange(6,10)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 218 +SELECT '{[1,5)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +== 219 +SELECT '{[-4,-2), [1,5)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +== 220 +SELECT '{[1,5), [8,9)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +== 221 +SELECT '{[1,5), [6,9)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +== 222 +SELECT '{[1,5), [6,10)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +== 223 +-- overleft +SELECT 'empty'::numrange &< nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 224 +SELECT 'empty'::numrange &< nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 225 +SELECT nummultirange() &< 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 226 +SELECT nummultirange(numrange(1,2)) &< 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 227 +SELECT nummultirange() &< nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 228 +SELECT nummultirange(numrange(1,2)) &< nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 229 +SELECT nummultirange() &< nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT numrange(6,7) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT numrange(1,2) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 232 +SELECT numrange(1,4) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 233 +SELECT numrange(1,6) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 234 +SELECT numrange(3.5,6) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 235 +SELECT nummultirange(numrange(6,7)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 236 +SELECT nummultirange(numrange(1,2)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 237 +SELECT nummultirange(numrange(1,4)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 238 +SELECT nummultirange(numrange(1,6)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 239 +SELECT nummultirange(numrange(3.5,6)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 240 +SELECT nummultirange(numrange(6,7)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 241 +SELECT nummultirange(numrange(1,2)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 242 +SELECT nummultirange(numrange(1,4)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 243 +SELECT nummultirange(numrange(1,6)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 244 +SELECT nummultirange(numrange(3.5,6)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 245 +-- overright +SELECT nummultirange() &> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 246 +SELECT nummultirange(numrange(1,2)) &> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 247 +SELECT 'empty'::numrange &> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 248 +SELECT 'empty'::numrange &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 249 +SELECT nummultirange() &> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 250 +SELECT nummultirange() &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 251 +SELECT nummultirange(numrange(1,2)) &> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 252 +SELECT nummultirange(numrange(3,4)) &> numrange(6,7) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 253 +SELECT nummultirange(numrange(3,4)) &> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 254 +SELECT nummultirange(numrange(3,4)) &> numrange(1,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 255 +SELECT nummultirange(numrange(3,4)) &> numrange(1,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 256 +SELECT nummultirange(numrange(3,4)) &> numrange(3.5,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 257 +SELECT numrange(3,4) &> nummultirange(numrange(6,7)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 258 +SELECT numrange(3,4) &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 259 +SELECT numrange(3,4) &> nummultirange(numrange(1,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 260 +SELECT numrange(3,4) &> nummultirange(numrange(1,6)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 261 +SELECT numrange(3,4) &> nummultirange(numrange(3.5,6)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 262 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(6,7)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 263 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 264 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 265 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,6)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 266 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(3.5,6)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 267 +-- meets +SELECT 'empty'::numrange -|- nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 268 +SELECT 'empty'::numrange -|- nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 269 +SELECT nummultirange() -|- 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 270 +SELECT nummultirange(numrange(1,2)) -|- 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 271 +SELECT nummultirange() -|- nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 272 +SELECT nummultirange(numrange(1,2)) -|- nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 273 +SELECT nummultirange() -|- nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 274 +SELECT numrange(1,2) -|- nummultirange(numrange(2,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 275 +SELECT numrange(1,2) -|- nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 276 +SELECT nummultirange(numrange(1,2)) -|- numrange(2,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 277 +SELECT nummultirange(numrange(1,2)) -|- numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 278 +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 279 +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 280 +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 281 +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(6,7)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 282 +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(8,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 283 +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4), numrange(6,7)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 284 +-- strictly left +select 'empty'::numrange << nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 285 +select numrange(1,2) << nummultirange() +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 286 +select numrange(1,2) << nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 287 +select numrange(1,2) << nummultirange(numrange(0,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 288 +select numrange(1,2) << nummultirange(numrange(0,4), numrange(7,8)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 289 +select nummultirange() << 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 290 +select nummultirange() << numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 291 +select nummultirange(numrange(3,4)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 292 +select nummultirange(numrange(0,2)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 293 +select nummultirange(numrange(0,2), numrange(7,8)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 294 +select nummultirange(numrange(-4,-2), numrange(0,2)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 295 +select nummultirange() << nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 296 +select nummultirange() << nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 297 +select nummultirange(numrange(1,2)) << nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 298 +select nummultirange(numrange(1,2)) << nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 299 +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 300 +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4), numrange(7,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 301 +select nummultirange(numrange(1,2), numrange(4,5)) << nummultirange(numrange(3,4), numrange(7,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 302 +-- strictly right +select nummultirange() >> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 303 +select nummultirange() >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 304 +select nummultirange(numrange(3,4)) >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 305 +select nummultirange(numrange(0,4)) >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 306 +select nummultirange(numrange(0,4), numrange(7,8)) >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 307 +select 'empty'::numrange >> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 308 +select numrange(1,2) >> nummultirange() +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 309 +select numrange(3,6) >> nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 310 +select numrange(3,6) >> nummultirange(numrange(0,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 311 +select numrange(3,6) >> nummultirange(numrange(0,2), numrange(7,8)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 312 +select numrange(3,6) >> nummultirange(numrange(-4,-2), numrange(0,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 313 +select nummultirange() >> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 314 +select nummultirange(numrange(1,2)) >> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 315 +select nummultirange() >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 316 +select nummultirange(numrange(1,2)) >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 317 +select nummultirange(numrange(3,4)) >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 318 +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 319 +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2), numrange(4,5)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 320 +-- union +SELECT nummultirange() + nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 321 +SELECT nummultirange() + nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 322 +SELECT nummultirange(numrange(1,2)) + nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 323 +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 324 +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 325 +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 326 +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 327 +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 328 +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(0,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 329 +-- merge +SELECT range_merge(nummultirange()) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 330 +SELECT range_merge(nummultirange(numrange(1,2))) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 331 +SELECT range_merge(nummultirange(numrange(1,2), numrange(7,8))) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 332 +-- minus +SELECT nummultirange() - nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 333 +SELECT nummultirange() - nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 334 +SELECT nummultirange(numrange(1,2)) - nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 335 +SELECT nummultirange(numrange(1,2), numrange(3,4)) - nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 336 +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 337 +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 338 +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 339 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 340 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(2,3)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 341 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 342 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 343 +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(0,2), numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 344 +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(2,3), numrange(5,null)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 345 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 346 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 347 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(3,5)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 348 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(0,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 349 +SELECT nummultirange(numrange(1,3), numrange(4,5)) - nummultirange(numrange(2,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 350 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(8,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 351 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0), numrange(8,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 352 +-- intersection +SELECT nummultirange() * nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 353 +SELECT nummultirange() * nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 354 +SELECT nummultirange(numrange(1,2)) * nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +== 355 +SELECT '{[1,3)}'::nummultirange * '{[1,5)}'::nummultirange +-- +STMT: SelectStmt +== 356 +SELECT '{[1,3)}'::nummultirange * '{[0,5)}'::nummultirange +-- +STMT: SelectStmt +== 357 +SELECT '{[1,3)}'::nummultirange * '{[0,2)}'::nummultirange +-- +STMT: SelectStmt +== 358 +SELECT '{[1,3)}'::nummultirange * '{[2,5)}'::nummultirange +-- +STMT: SelectStmt +== 359 +SELECT '{[1,4)}'::nummultirange * '{[2,3)}'::nummultirange +-- +STMT: SelectStmt +== 360 +SELECT '{[1,4)}'::nummultirange * '{[0,2), [3,5)}'::nummultirange +-- +STMT: SelectStmt +== 361 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,8), [9,12)}'::nummultirange +-- +STMT: SelectStmt +== 362 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[9,12)}'::nummultirange +-- +STMT: SelectStmt +== 363 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[-5,-4), [5,6), [9,12)}'::nummultirange +-- +STMT: SelectStmt +== 364 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange +-- +STMT: SelectStmt +== 365 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange +-- +STMT: SelectStmt +== 366 +-- test GiST index +create table test_multirange_gist(mr int4multirange) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: CreateStmt +== 367 +insert into test_multirange_gist select int4multirange(int4range(g, g+10),int4range(g+20, g+30),int4range(g+40, g+50)) from generate_series(1,2000) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 368 +insert into test_multirange_gist select '{}'::int4multirange from generate_series(1,500) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 369 +insert into test_multirange_gist select int4multirange(int4range(g, g+10000)) from generate_series(1,1000) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 370 +insert into test_multirange_gist select int4multirange(int4range(NULL, g*10, '(]'), int4range(g*10, g*20, '(]')) from generate_series(1,100) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 371 +insert into test_multirange_gist select int4multirange(int4range(g*10, g*20, '(]'), int4range(g*20, NULL, '(]')) from generate_series(1,100) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 372 +create index test_mulrirange_gist_idx on test_multirange_gist using gist (mr) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: IndexStmt +== 373 +-- test statistics and selectivity estimation as well +|-- +-- We don't check the accuracy of selectivity estimation, but at least check +-- it doesn't fall. +analyze test_multirange_gist +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: VacuumStmt +== 374 +-- first, verify non-indexed results +SET enable_seqscan = t +-- +STMT: VariableSetStmt +== 375 +SET enable_indexscan = f +-- +STMT: VariableSetStmt +== 376 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +== 377 +select count(*) from test_multirange_gist where mr = '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 378 +select count(*) from test_multirange_gist where mr @> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 379 +select count(*) from test_multirange_gist where mr && 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 380 +select count(*) from test_multirange_gist where mr <@ 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 381 +select count(*) from test_multirange_gist where mr << 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 382 +select count(*) from test_multirange_gist where mr >> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 383 +select count(*) from test_multirange_gist where mr &< 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 384 +select count(*) from test_multirange_gist where mr &> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 385 +select count(*) from test_multirange_gist where mr -|- 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 386 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 387 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 388 +select count(*) from test_multirange_gist where mr && '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 389 +select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 390 +select count(*) from test_multirange_gist where mr << '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 391 +select count(*) from test_multirange_gist where mr >> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 392 +select count(*) from test_multirange_gist where mr &< '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 393 +select count(*) from test_multirange_gist where mr &> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 394 +select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 395 +select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 396 +select count(*) from test_multirange_gist where mr @> 10 +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 397 +select count(*) from test_multirange_gist where mr @> int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 398 +select count(*) from test_multirange_gist where mr && int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 399 +select count(*) from test_multirange_gist where mr <@ int4range(10,50) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 400 +select count(*) from test_multirange_gist where mr << int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 401 +select count(*) from test_multirange_gist where mr >> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 402 +select count(*) from test_multirange_gist where mr &< int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 403 +select count(*) from test_multirange_gist where mr &> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 404 +select count(*) from test_multirange_gist where mr -|- int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 405 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 406 +select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 407 +select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 408 +select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 409 +select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 410 +select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 411 +select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 412 +select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 413 +select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 414 +-- now check same queries using index +SET enable_seqscan = f +-- +STMT: VariableSetStmt +== 415 +SET enable_indexscan = t +-- +STMT: VariableSetStmt +== 416 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +== 417 +select count(*) from test_multirange_gist where mr = '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 418 +select count(*) from test_multirange_gist where mr @> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 419 +select count(*) from test_multirange_gist where mr && 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 420 +select count(*) from test_multirange_gist where mr <@ 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 421 +select count(*) from test_multirange_gist where mr << 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 422 +select count(*) from test_multirange_gist where mr >> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 423 +select count(*) from test_multirange_gist where mr &< 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 424 +select count(*) from test_multirange_gist where mr &> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 425 +select count(*) from test_multirange_gist where mr -|- 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 426 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 427 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 428 +select count(*) from test_multirange_gist where mr && '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 429 +select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 430 +select count(*) from test_multirange_gist where mr << '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 431 +select count(*) from test_multirange_gist where mr >> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 432 +select count(*) from test_multirange_gist where mr &< '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 433 +select count(*) from test_multirange_gist where mr &> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 434 +select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 435 +select count(*) from test_multirange_gist where mr @> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 436 +select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 437 +select count(*) from test_multirange_gist where mr @> 10 +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 438 +select count(*) from test_multirange_gist where mr @> int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 439 +select count(*) from test_multirange_gist where mr && int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 440 +select count(*) from test_multirange_gist where mr <@ int4range(10,50) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 441 +select count(*) from test_multirange_gist where mr << int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 442 +select count(*) from test_multirange_gist where mr >> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 443 +select count(*) from test_multirange_gist where mr &< int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 444 +select count(*) from test_multirange_gist where mr &> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 445 +select count(*) from test_multirange_gist where mr -|- int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 446 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 447 +select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 448 +select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 449 +select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 450 +select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 451 +select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 452 +select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 453 +select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 454 +select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +== 455 +drop table test_multirange_gist +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: DropStmt +== 456 +|-- +-- range_agg function +|-- +create table reservations ( room_id integer not null, booked_during daterange ) +-- +TABLE: name="reservations" schema="" table="reservations" ctx=DDL +STMT: CreateStmt +== 457 +insert into reservations values +-- 1: has a meets and a gap +(1, daterange('2018-07-01', '2018-07-07')), +(1, daterange('2018-07-07', '2018-07-14')), +(1, daterange('2018-07-20', '2018-07-22')), +-- 2: just a single row +(2, daterange('2018-07-01', '2018-07-03')), +-- 3: one null range +(3, NULL), +-- 4: two null ranges +(4, NULL), +(4, NULL), +-- 5: a null range and a non-null range +(5, NULL), +(5, daterange('2018-07-01', '2018-07-03')), +-- 6: has overlap +(6, daterange('2018-07-01', '2018-07-07')), +(6, daterange('2018-07-05', '2018-07-10')), +-- 7: two ranges that meet: no gap or overlap +(7, daterange('2018-07-01', '2018-07-07')), +(7, daterange('2018-07-07', '2018-07-14')), +-- 8: an empty range +(8, 'empty'::daterange) +-- +TABLE: name="reservations" schema="" table="reservations" ctx=DML +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 458 +SELECT room_id, range_agg(booked_during) +FROM reservations +GROUP BY room_id +ORDER BY room_id +-- +TABLE: name="reservations" schema="" table="reservations" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 459 +-- range_agg on a custom range type too +SELECT range_agg(r) +FROM (VALUES + ('[a,c]'::textrange), + ('[b,b]'::textrange), + ('[c,f]'::textrange), + ('[g,h)'::textrange), + ('[h,j)'::textrange) + ) t(r) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 460 +-- range_agg with multirange inputs +select range_agg(nmr) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 461 +select range_agg(nmr) from nummultirange_test where false +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 462 +select range_agg(null::nummultirange) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 463 +select range_agg(nmr) from (values ('{}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 464 +select range_agg(nmr) from (values ('{}'::nummultirange), ('{}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 465 +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 466 +select range_agg(nmr) from (values ('{[1,2], [5,6]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 467 +select range_agg(nmr) from (values ('{[1,2], [2,3]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 468 +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[5,6]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 469 +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[2,3]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +== 470 +|-- +-- range_intersect_agg function +|-- +select range_intersect_agg(nmr) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 471 +select range_intersect_agg(nmr) from nummultirange_test where false +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 472 +select range_intersect_agg(null::nummultirange) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 473 +select range_intersect_agg(nmr) from (values ('{[1,3]}'::nummultirange), ('{[6,12]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 474 +select range_intersect_agg(nmr) from (values ('{[1,6]}'::nummultirange), ('{[3,12]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 475 +select range_intersect_agg(nmr) from (values ('{[1,6], [10,12]}'::nummultirange), ('{[4,14]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 476 +-- test with just one input: +select range_intersect_agg(nmr) from (values ('{}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 477 +select range_intersect_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 478 +select range_intersect_agg(nmr) from (values ('{[1,6], [10,12]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 479 +select range_intersect_agg(nmr) from nummultirange_test where nmr @> 4.0 +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 480 +create table nummultirange_test2(nmr nummultirange) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DDL +STMT: CreateStmt +== 481 +create index nummultirange_test2_hash_idx on nummultirange_test2 using hash (nmr) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DDL +STMT: IndexStmt +== 482 +INSERT INTO nummultirange_test2 VALUES('{[, 5)}') +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 483 +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 484 +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 485 +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2,'()'))) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 486 +INSERT INTO nummultirange_test2 VALUES('{}') +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 487 +select * from nummultirange_test2 where nmr = '{}' +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 488 +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.2)) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 489 +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.3)) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +== 490 +set enable_nestloop=t +-- +STMT: VariableSetStmt +== 491 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +== 492 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +== 493 +select * from nummultirange_test natural join nummultirange_test2 order by nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +STMT: SelectStmt +== 494 +set enable_nestloop=f +-- +STMT: VariableSetStmt +== 495 +set enable_hashjoin=t +-- +STMT: VariableSetStmt +== 496 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +== 497 +select * from nummultirange_test natural join nummultirange_test2 order by nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +STMT: SelectStmt +== 498 +set enable_nestloop=f +-- +STMT: VariableSetStmt +== 499 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +== 500 +set enable_mergejoin=t +-- +STMT: VariableSetStmt +== 501 +select * from nummultirange_test natural join nummultirange_test2 order by nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +STMT: SelectStmt +== 502 +set enable_nestloop to default +-- +STMT: VariableSetStmt +== 503 +set enable_hashjoin to default +-- +STMT: VariableSetStmt +== 504 +set enable_mergejoin to default +-- +STMT: VariableSetStmt +== 505 +DROP TABLE nummultirange_test2 +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DDL +STMT: DropStmt +== 506 +|-- +-- Test user-defined multirange of floats +|-- + +select '{[123.001, 5.e9)}'::float8multirange @> 888.882::float8 +-- +STMT: SelectStmt +== 507 +create table float8multirange_test(f8mr float8multirange, i int) +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=DDL +STMT: CreateStmt +== 508 +insert into float8multirange_test values(float8multirange(float8range(-100.00007, '1.111113e9')), 42) +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=DML +FUNCTION: name="float8multirange" function="float8multirange" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 509 +select * from float8multirange_test +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=Select +STMT: SelectStmt +== 510 +drop table float8multirange_test +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=DDL +STMT: DropStmt +== 511 +|-- +-- Test multirange types over domains +|-- + +create domain mydomain as int4 +-- +STMT: CreateDomainStmt +== 512 +create type mydomainrange as range(subtype=mydomain) +-- +STMT: CreateRangeStmt +== 513 +select '{[4,50)}'::mydomainmultirange @> 7::mydomain +-- +STMT: SelectStmt +== 514 +drop domain mydomain cascade +-- +STMT: DropStmt +== 515 +|-- +-- Test domains over multirange types +|-- + +create domain restrictedmultirange as int4multirange check (upper(value) < 10) +-- +STMT: CreateDomainStmt +== 516 +select '{[4,5)}'::restrictedmultirange @> 7 +-- +STMT: SelectStmt +== 517 +select '{[4,50)}'::restrictedmultirange @> 7 +-- +STMT: SelectStmt +== 518 +-- should fail +drop domain restrictedmultirange +-- +STMT: DropStmt +== 519 +--- +-- Check automatic naming of multiranges +--- + +create type intr as range(subtype=int) +-- +STMT: CreateRangeStmt +== 520 +select intr_multirange(intr(1,10)) +-- +FUNCTION: name="intr_multirange" function="intr_multirange" schema="" ctx=Call +FUNCTION: name="intr" function="intr" schema="" ctx=Call +STMT: SelectStmt +== 521 +drop type intr +-- +STMT: DropStmt +== 522 +create type intmultirange as (x int, y int) +-- +STMT: CompositeTypeStmt +== 523 +create type intrange as range(subtype=int) +-- +STMT: CreateRangeStmt +== 524 +-- should fail +drop type intmultirange +-- +STMT: DropStmt +== 525 +create type intr_multirange as (x int, y int) +-- +STMT: CompositeTypeStmt +== 526 +create type intr as range(subtype=int) +-- +STMT: CreateRangeStmt +== 527 +-- should fail +drop type intr_multirange +-- +STMT: DropStmt +== 528 +|-- +-- Test multiple multirange types over the same subtype and manual naming of +-- the multirange type. +|-- + +-- should fail +create type textrange1 as range(subtype=text, multirange_type_name=int, collation="C") +-- +STMT: CreateRangeStmt +== 529 +-- should pass +create type textrange1 as range(subtype=text, multirange_type_name=multirange_of_text, collation="C") +-- +STMT: CreateRangeStmt +== 530 +-- should pass, because existing _textrange1 is automatically renamed +create type textrange2 as range(subtype=text, multirange_type_name=_textrange1, collation="C") +-- +STMT: CreateRangeStmt +== 531 +select multirange_of_text(textrange2('a','Z')) +-- +FUNCTION: name="multirange_of_text" function="multirange_of_text" schema="" ctx=Call +FUNCTION: name="textrange2" function="textrange2" schema="" ctx=Call +STMT: SelectStmt +== 532 +-- should fail +select multirange_of_text(textrange1('a','Z')) @> 'b'::text +-- +FUNCTION: name="multirange_of_text" function="multirange_of_text" schema="" ctx=Call +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +STMT: SelectStmt +== 533 +select unnest(multirange_of_text(textrange1('a','b'), textrange1('d','e'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="multirange_of_text" function="multirange_of_text" schema="" ctx=Call +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +STMT: SelectStmt +== 534 +select _textrange1(textrange2('a','z')) @> 'b'::text +-- +FUNCTION: name="_textrange1" function="_textrange1" schema="" ctx=Call +FUNCTION: name="textrange2" function="textrange2" schema="" ctx=Call +STMT: SelectStmt +== 535 +drop type textrange1 +-- +STMT: DropStmt +== 536 +drop type textrange2 +-- +STMT: DropStmt +== 537 +|-- +-- Multiranges don't have their own ownership or permissions. +|-- +create type textrange1 as range(subtype=text, multirange_type_name=multitextrange1, collation="C") +-- +STMT: CreateRangeStmt +== 538 +create role regress_multirange_owner +-- +STMT: CreateRoleStmt +== 539 +alter type multitextrange1 owner to regress_multirange_owner +-- +STMT: AlterOwnerStmt +== 540 +-- fail +alter type textrange1 owner to regress_multirange_owner +-- +STMT: AlterOwnerStmt +== 541 +set role regress_multirange_owner +-- +STMT: VariableSetStmt +== 542 +revoke usage on type multitextrange1 from public +-- +STMT: GrantStmt +== 543 +-- fail +revoke usage on type textrange1 from public +-- +STMT: GrantStmt +== 544 +create temp table test1(f1 multitextrange1[]) +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: CreateStmt +== 545 +revoke usage on type textrange1 from regress_multirange_owner +-- +STMT: GrantStmt +== 546 +create temp table test2(f1 multitextrange1[]) +-- +TABLE: name="test2" schema="" table="test2" ctx=DDL +STMT: CreateStmt +== 547 +-- fail + +drop table test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: DropStmt +== 548 +drop type textrange1 +-- +STMT: DropStmt +== 549 +reset role +-- +STMT: VariableSetStmt +== 550 +drop role regress_multirange_owner +-- +STMT: DropRoleStmt +== 551 +|-- +-- Test polymorphic type system +|-- + +create function anyarray_anymultirange_func(a anyarray, r anymultirange) + returns anyelement as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 552 +select anyarray_anymultirange_func(ARRAY[1,2], int4multirange(int4range(10,20))) +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 553 +-- should fail +select anyarray_anymultirange_func(ARRAY[1,2], nummultirange(numrange(10,20))) +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 554 +drop function anyarray_anymultirange_func(anyarray, anymultirange) +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=DDL +STMT: DropStmt +== 555 +-- should fail +create function bogus_func(anyelement) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 556 +-- should fail +create function bogus_func(int) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 557 +create function range_add_bounds(anymultirange) + returns anyelement as 'select lower($1) + upper($1)' language sql +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 558 +select range_add_bounds(int4multirange(int4range(1, 17))) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 559 +select range_add_bounds(nummultirange(numrange(1.0001, 123.123))) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 560 +create function multirangetypes_sql(q anymultirange, b anyarray, out c anyelement) + as $$ select upper($1) + $2[1] $$ + language sql +-- +FUNCTION: name="multirangetypes_sql" function="multirangetypes_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 561 +select multirangetypes_sql(int4multirange(int4range(1,10)), ARRAY[2,20]) +-- +FUNCTION: name="multirangetypes_sql" function="multirangetypes_sql" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 562 +select multirangetypes_sql(nummultirange(numrange(1,10)), ARRAY[2,20]) +-- +FUNCTION: name="multirangetypes_sql" function="multirangetypes_sql" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 563 +-- match failure + +create function anycompatiblearray_anycompatiblemultirange_func(a anycompatiblearray, mr anycompatiblemultirange) + returns anycompatible as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 564 +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 565 +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(numrange(10,20))) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 566 +-- should fail +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1.1,2], multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 567 +drop function anycompatiblearray_anycompatiblemultirange_func(anycompatiblearray, anycompatiblemultirange) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: DropStmt +== 568 +create function anycompatiblerange_anycompatiblemultirange_func(r anycompatiblerange, mr anycompatiblemultirange) + returns anycompatible as 'select lower($1) + lower($2);' language sql +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 569 +select anycompatiblerange_anycompatiblemultirange_func(int4range(1,2), multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 570 +-- should fail +select anycompatiblerange_anycompatiblemultirange_func(numrange(1,2), multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 571 +drop function anycompatiblerange_anycompatiblemultirange_func(anycompatiblerange, anycompatiblemultirange) +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: DropStmt +== 572 +-- should fail +create function bogus_func(anycompatible) + returns anycompatiblerange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 573 +|-- +-- Arrays of multiranges +|-- + +select ARRAY[nummultirange(numrange(1.1, 1.2)), nummultirange(numrange(12.3, 155.5))] +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 574 +create table i8mr_array (f1 int, f2 int8multirange[]) +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=DDL +STMT: CreateStmt +== 575 +insert into i8mr_array values (42, array[int8multirange(int8range(1,10)), int8multirange(int8range(2,20))]) +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=DML +FUNCTION: name="int8multirange" function="int8multirange" schema="" ctx=Call +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +FUNCTION: name="int8multirange" function="int8multirange" schema="" ctx=Call +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 576 +select * from i8mr_array +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=Select +STMT: SelectStmt +== 577 +drop table i8mr_array +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=DDL +STMT: DropStmt +== 578 +|-- +-- Multiranges of arrays +|-- + +select arraymultirange(arrayrange(ARRAY[1,2], ARRAY[2,1])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 579 +select arraymultirange(arrayrange(ARRAY[2,1], ARRAY[1,2])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 580 +-- fail + +select array[1,1] <@ arraymultirange(arrayrange(array[1,2], array[2,1])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 581 +select array[1,3] <@ arraymultirange(arrayrange(array[1,2], array[2,1])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 582 +|-- +-- Ranges of composites +|-- + +create type two_ints as (a int, b int) +-- +STMT: CompositeTypeStmt +== 583 +create type two_ints_range as range (subtype = two_ints) +-- +STMT: CreateRangeStmt +== 584 +-- with debug_parallel_query on, this exercises tqueue.c's range remapping +select *, row_to_json(upper(t)) as u from + (values (two_ints_multirange(two_ints_range(row(1,2), row(3,4)))), + (two_ints_multirange(two_ints_range(row(5,6), row(7,8))))) v(t) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="two_ints_multirange" function="two_ints_multirange" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +FUNCTION: name="two_ints_multirange" function="two_ints_multirange" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +STMT: SelectStmt +== 585 +drop type two_ints cascade +-- +STMT: DropStmt +== 586 +|-- +-- Check behavior when subtype lacks a hash function +|-- + +set enable_sort = off +-- +STMT: VariableSetStmt +== 587 +-- try to make it pick a hash setop implementation + +select '{(01,10)}'::varbitmultirange except select '{(10,11)}'::varbitmultirange +-- +STMT: SelectStmt +== 588 +reset enable_sort +-- +STMT: VariableSetStmt +== 589 +|-- +-- OUT/INOUT/TABLE functions +|-- + +-- infer anymultirange from anymultirange +create function mr_outparam_succeed(i anymultirange, out r anymultirange, out t text) + as $$ select $1, 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed" function="mr_outparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 590 +select * from mr_outparam_succeed(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_outparam_succeed" function="mr_outparam_succeed" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 591 +-- infer anyarray from anymultirange +create function mr_outparam_succeed2(i anymultirange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed2" function="mr_outparam_succeed2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 592 +select * from mr_outparam_succeed2(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_outparam_succeed2" function="mr_outparam_succeed2" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 593 +-- infer anyrange from anymultirange +create function mr_outparam_succeed3(i anymultirange, out r anyrange, out t text) + as $$ select range_merge($1), 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed3" function="mr_outparam_succeed3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 594 +select * from mr_outparam_succeed3(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_outparam_succeed3" function="mr_outparam_succeed3" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 595 +-- infer anymultirange from anyrange +create function mr_outparam_succeed4(i anyrange, out r anymultirange, out t text) + as $$ select multirange($1), 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed4" function="mr_outparam_succeed4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 596 +select * from mr_outparam_succeed4(int4range(1,2)) +-- +FUNCTION: name="mr_outparam_succeed4" function="mr_outparam_succeed4" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 597 +-- infer anyelement from anymultirange +create function mr_inoutparam_succeed(out i anyelement, inout r anymultirange) + as $$ select upper($1), $1 $$ language sql +-- +FUNCTION: name="mr_inoutparam_succeed" function="mr_inoutparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 598 +select * from mr_inoutparam_succeed(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_inoutparam_succeed" function="mr_inoutparam_succeed" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 599 +-- infer anyelement+anymultirange from anyelement+anymultirange +create function mr_table_succeed(i anyelement, r anymultirange) returns table(i anyelement, r anymultirange) + as $$ select $1, $2 $$ language sql +-- +FUNCTION: name="mr_table_succeed" function="mr_table_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 600 +select * from mr_table_succeed(123, int4multirange(int4range(1,11))) +-- +FUNCTION: name="mr_table_succeed" function="mr_table_succeed" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 601 +-- use anymultirange in plpgsql +create function mr_polymorphic(i anyrange) returns anymultirange + as $$ begin return multirange($1); end; $$ language plpgsql +-- +FUNCTION: name="mr_polymorphic" function="mr_polymorphic" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 602 +select mr_polymorphic(int4range(1, 4)) +-- +FUNCTION: name="mr_polymorphic" function="mr_polymorphic" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 603 +-- should fail +create function mr_outparam_fail(i anyelement, out r anymultirange, out t text) + as $$ select '[1,10]', 'foo' $$ language sql +-- +FUNCTION: name="mr_outparam_fail" function="mr_outparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 604 +--should fail +create function mr_inoutparam_fail(inout i anyelement, out r anymultirange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="mr_inoutparam_fail" function="mr_inoutparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 605 +--should fail +create function mr_table_fail(i anyelement) returns table(i anyelement, r anymultirange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="mr_table_fail" function="mr_table_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt diff --git a/parser/testdata/summary/postgres_regress/mvcc.metadata.json b/parser/testdata/summary/postgres_regress/mvcc.metadata.json new file mode 100644 index 0000000..4739b17 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/mvcc.metadata.json @@ -0,0 +1,15 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011" + ] +} diff --git a/parser/testdata/summary/postgres_regress/mvcc.test b/parser/testdata/summary/postgres_regress/mvcc.test new file mode 100644 index 0000000..8b175a5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/mvcc.test @@ -0,0 +1,79 @@ +== 001 +|-- +-- Verify that index scans encountering dead rows produced by an +-- aborted subtransaction of the current transaction can utilize the +-- kill_prior_tuple optimization +|-- +-- NB: The table size is currently *not* expected to stay the same, we +-- don't have logic to trigger opportunistic pruning in cases like +-- this. +BEGIN +-- +STMT: TransactionStmt +== 002 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +== 003 +SET LOCAL enable_indexonlyscan = false +-- +STMT: VariableSetStmt +== 004 +SET LOCAL enable_bitmapscan = false +-- +STMT: VariableSetStmt +== 005 +-- Can't easily use a unique index, since dead tuples can be found +-- independent of the kill_prior_tuples optimization. +CREATE TABLE clean_aborted_self(key int, data text) +-- +TABLE: name="clean_aborted_self" schema="" table="clean_aborted_self" ctx=DDL +STMT: CreateStmt +== 006 +CREATE INDEX clean_aborted_self_key ON clean_aborted_self(key) +-- +TABLE: name="clean_aborted_self" schema="" table="clean_aborted_self" ctx=DDL +STMT: IndexStmt +== 007 +INSERT INTO clean_aborted_self (key, data) VALUES (-1, 'just to allocate metapage') +-- +TABLE: name="clean_aborted_self" schema="" table="clean_aborted_self" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- save index size from before the changes, for comparison +SELECT pg_relation_size('clean_aborted_self_key') AS clean_aborted_self_key_before +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +== 009 +DO $$ +BEGIN + -- iterate often enough to see index growth even on larger-than-default page sizes + FOR i IN 1..100 LOOP + BEGIN + -- perform index scan over all the inserted keys to get them to be seen as dead + IF EXISTS(SELECT * FROM clean_aborted_self WHERE key > 0 AND key < 100) THEN + RAISE data_corrupted USING MESSAGE = 'these rows should not exist'; + END IF; + INSERT INTO clean_aborted_self SELECT g.i, 'rolling back in a sec' FROM generate_series(1, 100) g(i); + -- just some error that's not normally thrown + RAISE reading_sql_data_not_permitted USING MESSAGE = 'round and round again'; + EXCEPTION WHEN reading_sql_data_not_permitted THEN END; + END LOOP; +END;$$ +-- +STMT: DoStmt +== 010 +-- show sizes only if they differ +SELECT :clean_aborted_self_key_before AS size_before, pg_relation_size('clean_aborted_self_key') size_after +WHERE :clean_aborted_self_key_before != pg_relation_size('clean_aborted_self_key') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 011 +ROLLBACK +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/name.metadata.json b/parser/testdata/summary/postgres_regress/name.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/name.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary/postgres_regress/name.test b/parser/testdata/summary/postgres_regress/name.test new file mode 100644 index 0000000..eef1459 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/name.test @@ -0,0 +1,250 @@ +== 001 +|-- +-- NAME +-- all inputs are silently truncated at NAMEDATALEN-1 (63) characters +|-- + +-- fixed-length by reference +SELECT name 'name string' = name 'name string' AS "True" +-- +STMT: SelectStmt +== 002 +SELECT name 'name string' = name 'name string ' AS "False" +-- +STMT: SelectStmt +== 003 +|-- +|-- +|-- + +CREATE TABLE NAME_TBL(f1 name) +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DDL +STMT: CreateStmt +== 004 +INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO NAME_TBL(f1) VALUES ('1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO NAME_TBL(f1) VALUES ('asdfghjkl;') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO NAME_TBL(f1) VALUES ('343f%2a') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO NAME_TBL(f1) VALUES ('d34aaasdf') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO NAME_TBL(f1) VALUES ('') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +SELECT * FROM NAME_TBL +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +STMT: SelectStmt +== 012 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 <> '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 013 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 014 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 < '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 015 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 <= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 016 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 > '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 017 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 >= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 018 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 019 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 !~ '.*' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 020 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '[0-9]' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 021 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*asdf.*' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 022 +DROP TABLE NAME_TBL +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DDL +STMT: DropStmt +== 023 +DO $$ +DECLARE r text[]; +BEGIN + r := parse_ident('Schemax.Tabley'); + RAISE NOTICE '%', format('%I.%I', r[1], r[2]); + r := parse_ident('"SchemaX"."TableY"'); + RAISE NOTICE '%', format('%I.%I', r[1], r[2]); +END; +$$ +-- +STMT: DoStmt +== 024 +SELECT parse_ident('foo.boo') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT parse_ident('foo.boo[]') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 026 +-- should fail +SELECT parse_ident('foo.boo[]', strict => false) +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 027 +-- ok + +-- should fail +SELECT parse_ident(' ') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT parse_ident(' .aaa') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT parse_ident(' aaa . ') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT parse_ident('aaa.a%b') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT parse_ident(E'X\rXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT length(a[1]), length(a[2]) from parse_ident('"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy') as a +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT parse_ident(' first . " second " ." third ". " ' || repeat('x',66) || '"') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT parse_ident(' first . " second " ." third ". " ' || repeat('x',66) || '"')::name[] +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT parse_ident(E'"c".X XXXX\002XXXXXX') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT parse_ident('1020') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT parse_ident('10.20') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT parse_ident('.') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT parse_ident('.1020') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT parse_ident('xxx.1020') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/namespace.metadata.json b/parser/testdata/summary/postgres_regress/namespace.metadata.json new file mode 100644 index 0000000..6e8763d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/namespace.metadata.json @@ -0,0 +1,46 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042" + ] +} diff --git a/parser/testdata/summary/postgres_regress/namespace.test b/parser/testdata/summary/postgres_regress/namespace.test new file mode 100644 index 0000000..a42220e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/namespace.test @@ -0,0 +1,249 @@ +== 001 +|-- +-- Regression tests for schemas (namespaces) +|-- + +-- set the whitespace-only search_path to test that the +-- GUC list syntax is preserved during a schema creation +SELECT pg_catalog.set_config('search_path', ' ', false) +-- +FUNCTION: name="pg_catalog.set_config" function="set_config" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 002 +CREATE SCHEMA test_ns_schema_1 + CREATE UNIQUE INDEX abc_a_idx ON abc (a) + + CREATE VIEW abc_view AS + SELECT a+1 AS a, b+1 AS b FROM abc + + CREATE TABLE abc ( + a serial, + b int UNIQUE + ) +-- +STMT: CreateSchemaStmt +== 003 +-- verify that the correct search_path restored on abort +SET search_path to public +-- +STMT: VariableSetStmt +== 004 +BEGIN +-- +STMT: TransactionStmt +== 005 +SET search_path to public, test_ns_schema_1 +-- +STMT: VariableSetStmt +== 006 +CREATE SCHEMA test_ns_schema_2 + CREATE VIEW abc_view AS SELECT c FROM abc +-- +STMT: CreateSchemaStmt +== 007 +COMMIT +-- +STMT: TransactionStmt +== 008 +SHOW search_path +-- +STMT: VariableShowStmt +== 009 +-- verify that the correct search_path preserved +-- after creating the schema and on commit +BEGIN +-- +STMT: TransactionStmt +== 010 +SET search_path to public, test_ns_schema_1 +-- +STMT: VariableSetStmt +== 011 +CREATE SCHEMA test_ns_schema_2 + CREATE VIEW abc_view AS SELECT a FROM abc +-- +STMT: CreateSchemaStmt +== 012 +SHOW search_path +-- +STMT: VariableShowStmt +== 013 +COMMIT +-- +STMT: TransactionStmt +== 014 +SHOW search_path +-- +STMT: VariableShowStmt +== 015 +DROP SCHEMA test_ns_schema_2 CASCADE +-- +STMT: DropStmt +== 016 +-- verify that the objects were created +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 017 +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=DML +STMT: InsertStmt +== 018 +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=DML +STMT: InsertStmt +== 019 +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=DML +STMT: InsertStmt +== 020 +SELECT * FROM test_ns_schema_1.abc +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=Select +STMT: SelectStmt +== 021 +SELECT * FROM test_ns_schema_1.abc_view +-- +TABLE: name="test_ns_schema_1.abc_view" schema="test_ns_schema_1" table="abc_view" ctx=Select +STMT: SelectStmt +== 022 +ALTER SCHEMA test_ns_schema_1 RENAME TO test_ns_schema_renamed +-- +STMT: RenameStmt +== 023 +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 024 +-- test IF NOT EXISTS cases +CREATE SCHEMA test_ns_schema_renamed +-- +STMT: CreateSchemaStmt +== 025 +-- fail, already exists +CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed +-- +STMT: CreateSchemaStmt +== 026 +-- ok with notice +CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed -- fail, disallowed + CREATE TABLE abc ( + a serial, + b int UNIQUE + ) +-- +ERROR: CREATE SCHEMA IF NOT EXISTS cannot include schema elements +CURSORPOS: 97 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 027 +DROP SCHEMA test_ns_schema_renamed CASCADE +-- +STMT: DropStmt +== 028 +-- verify that the objects were dropped +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_renamed') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 029 +|-- +-- Verify that search_path is set to a safe value during maintenance +-- commands. +|-- + +CREATE SCHEMA test_maint_search_path +-- +STMT: CreateSchemaStmt +== 030 +SET search_path = test_maint_search_path +-- +STMT: VariableSetStmt +== 031 +CREATE FUNCTION fn(INT) RETURNS INT IMMUTABLE LANGUAGE plpgsql AS $$ + BEGIN + RAISE NOTICE 'current search_path: %', current_setting('search_path'); + RETURN $1; + END; +$$ +-- +FUNCTION: name="fn" function="fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +CREATE TABLE test_maint(i INT) +-- +TABLE: name="test_maint" schema="" table="test_maint" ctx=DDL +STMT: CreateStmt +== 033 +INSERT INTO test_maint VALUES (1), (2) +-- +TABLE: name="test_maint" schema="" table="test_maint" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +CREATE MATERIALIZED VIEW test_maint_mv AS SELECT fn(i) FROM test_maint +-- +TABLE: name="test_maint_mv" schema="" table="test_maint_mv" ctx=DDL +TABLE: name="test_maint" schema="" table="test_maint" ctx=Select +FUNCTION: name="fn" function="fn" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 035 +-- the following commands should see search_path as pg_catalog, pg_temp + +CREATE INDEX test_maint_idx ON test_maint_search_path.test_maint (fn(i)) +-- +TABLE: name="test_maint_search_path.test_maint" schema="test_maint_search_path" table="test_maint" ctx=DDL +FUNCTION: name="fn" function="fn" schema="" ctx=Call +STMT: IndexStmt +== 036 +REINDEX TABLE test_maint_search_path.test_maint +-- +STMT: ReindexStmt +== 037 +ANALYZE test_maint_search_path.test_maint +-- +TABLE: name="test_maint_search_path.test_maint" schema="test_maint_search_path" table="test_maint" ctx=DDL +STMT: VacuumStmt +== 038 +VACUUM FULL test_maint_search_path.test_maint +-- +TABLE: name="test_maint_search_path.test_maint" schema="test_maint_search_path" table="test_maint" ctx=DDL +STMT: VacuumStmt +== 039 +CLUSTER test_maint_search_path.test_maint USING test_maint_idx +-- +STMT: ClusterStmt +== 040 +REFRESH MATERIALIZED VIEW test_maint_search_path.test_maint_mv +-- +TABLE: name="test_maint_search_path.test_maint_mv" schema="test_maint_search_path" table="test_maint_mv" ctx=DDL +STMT: RefreshMatViewStmt +== 041 +RESET search_path +-- +STMT: VariableSetStmt +== 042 +DROP SCHEMA test_maint_search_path CASCADE +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/numeric.metadata.json b/parser/testdata/summary/postgres_regress/numeric.metadata.json new file mode 100644 index 0000000..e7297cf --- /dev/null +++ b/parser/testdata/summary/postgres_regress/numeric.metadata.json @@ -0,0 +1,1022 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary/postgres_regress/numeric.test b/parser/testdata/summary/postgres_regress/numeric.test new file mode 100644 index 0000000..f6dcf07 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/numeric.test @@ -0,0 +1,6239 @@ +== 001 +|-- +-- NUMERIC +|-- + +CREATE TABLE num_data (id int4, val numeric(210,10)) +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: CreateStmt +== 005 +CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: CreateStmt +== 006 +CREATE TABLE num_exp_sqrt (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: CreateStmt +== 007 +CREATE TABLE num_exp_ln (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE num_exp_log10 (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: CreateStmt +== 009 +CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: CreateStmt +== 010 +CREATE TABLE num_result (id1 int4, id2 int4, result numeric(210,10)) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DDL +STMT: CreateStmt +== 011 +-- ****************************** +-- * The following EXPECTED results are computed by bc(1) +-- * with a scale of 200 +-- ****************************** + +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 012 +INSERT INTO num_exp_add VALUES (0,0,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO num_exp_sub VALUES (0,0,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO num_exp_mul VALUES (0,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO num_exp_div VALUES (0,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO num_exp_add VALUES (0,1,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO num_exp_sub VALUES (0,1,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO num_exp_mul VALUES (0,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO num_exp_div VALUES (0,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO num_exp_add VALUES (0,2,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO num_exp_sub VALUES (0,2,'34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO num_exp_mul VALUES (0,2,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO num_exp_div VALUES (0,2,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO num_exp_add VALUES (0,3,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO num_exp_sub VALUES (0,3,'-4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO num_exp_mul VALUES (0,3,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO num_exp_div VALUES (0,3,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO num_exp_add VALUES (0,4,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO num_exp_sub VALUES (0,4,'-7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO num_exp_mul VALUES (0,4,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO num_exp_div VALUES (0,4,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO num_exp_add VALUES (0,5,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO num_exp_sub VALUES (0,5,'-16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO num_exp_mul VALUES (0,5,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO num_exp_div VALUES (0,5,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO num_exp_add VALUES (0,6,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO num_exp_sub VALUES (0,6,'-93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO num_exp_mul VALUES (0,6,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO num_exp_div VALUES (0,6,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO num_exp_add VALUES (0,7,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO num_exp_sub VALUES (0,7,'83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO num_exp_mul VALUES (0,7,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO num_exp_div VALUES (0,7,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO num_exp_add VALUES (0,8,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO num_exp_sub VALUES (0,8,'-74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO num_exp_mul VALUES (0,8,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO num_exp_div VALUES (0,8,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO num_exp_add VALUES (0,9,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO num_exp_sub VALUES (0,9,'24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO num_exp_mul VALUES (0,9,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +INSERT INTO num_exp_div VALUES (0,9,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO num_exp_add VALUES (1,0,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO num_exp_sub VALUES (1,0,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +INSERT INTO num_exp_mul VALUES (1,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +INSERT INTO num_exp_div VALUES (1,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +INSERT INTO num_exp_add VALUES (1,1,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +INSERT INTO num_exp_sub VALUES (1,1,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +INSERT INTO num_exp_mul VALUES (1,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +INSERT INTO num_exp_div VALUES (1,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +INSERT INTO num_exp_add VALUES (1,2,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +INSERT INTO num_exp_sub VALUES (1,2,'34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +INSERT INTO num_exp_mul VALUES (1,2,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +INSERT INTO num_exp_div VALUES (1,2,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +INSERT INTO num_exp_add VALUES (1,3,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +INSERT INTO num_exp_sub VALUES (1,3,'-4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 066 +INSERT INTO num_exp_mul VALUES (1,3,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +INSERT INTO num_exp_div VALUES (1,3,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 068 +INSERT INTO num_exp_add VALUES (1,4,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +INSERT INTO num_exp_sub VALUES (1,4,'-7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +INSERT INTO num_exp_mul VALUES (1,4,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +INSERT INTO num_exp_div VALUES (1,4,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +INSERT INTO num_exp_add VALUES (1,5,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +INSERT INTO num_exp_sub VALUES (1,5,'-16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 074 +INSERT INTO num_exp_mul VALUES (1,5,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +INSERT INTO num_exp_div VALUES (1,5,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +INSERT INTO num_exp_add VALUES (1,6,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +INSERT INTO num_exp_sub VALUES (1,6,'-93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +INSERT INTO num_exp_mul VALUES (1,6,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO num_exp_div VALUES (1,6,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO num_exp_add VALUES (1,7,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +INSERT INTO num_exp_sub VALUES (1,7,'83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +INSERT INTO num_exp_mul VALUES (1,7,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +INSERT INTO num_exp_div VALUES (1,7,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 084 +INSERT INTO num_exp_add VALUES (1,8,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 085 +INSERT INTO num_exp_sub VALUES (1,8,'-74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 086 +INSERT INTO num_exp_mul VALUES (1,8,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +INSERT INTO num_exp_div VALUES (1,8,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +INSERT INTO num_exp_add VALUES (1,9,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +INSERT INTO num_exp_sub VALUES (1,9,'24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +INSERT INTO num_exp_mul VALUES (1,9,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 091 +INSERT INTO num_exp_div VALUES (1,9,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +INSERT INTO num_exp_add VALUES (2,0,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +INSERT INTO num_exp_sub VALUES (2,0,'-34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +INSERT INTO num_exp_mul VALUES (2,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +INSERT INTO num_exp_div VALUES (2,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +INSERT INTO num_exp_add VALUES (2,1,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +INSERT INTO num_exp_sub VALUES (2,1,'-34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +INSERT INTO num_exp_mul VALUES (2,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +INSERT INTO num_exp_div VALUES (2,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 100 +INSERT INTO num_exp_add VALUES (2,2,'-68676984.430794094') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +INSERT INTO num_exp_sub VALUES (2,2,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 102 +INSERT INTO num_exp_mul VALUES (2,2,'1179132047626883.596862135856320209') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +INSERT INTO num_exp_div VALUES (2,2,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +INSERT INTO num_exp_add VALUES (2,3,'-34338487.905397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +INSERT INTO num_exp_sub VALUES (2,3,'-34338496.525397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 106 +INSERT INTO num_exp_mul VALUES (2,3,'-147998901.44836127257') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +INSERT INTO num_exp_div VALUES (2,3,'-7967167.56737750510440835266') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +INSERT INTO num_exp_add VALUES (2,4,'-26539030.803497047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +INSERT INTO num_exp_sub VALUES (2,4,'-42137953.627297047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +INSERT INTO num_exp_mul VALUES (2,4,'-267821744976817.8111137106593') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +INSERT INTO num_exp_div VALUES (2,4,'-4.40267480046830116685') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +INSERT INTO num_exp_add VALUES (2,5,'-34322095.176906047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 113 +INSERT INTO num_exp_sub VALUES (2,5,'-34354889.253888047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 114 +INSERT INTO num_exp_mul VALUES (2,5,'-563049578578.769242506736077') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +INSERT INTO num_exp_div VALUES (2,5,'-2094.18866914563535496429') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +INSERT INTO num_exp_add VALUES (2,6,'-34244590.637766787') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +INSERT INTO num_exp_sub VALUES (2,6,'-34432393.793027307') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +INSERT INTO num_exp_mul VALUES (2,6,'-3224438592470.18449811926184222') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +INSERT INTO num_exp_div VALUES (2,6,'-365.68599891479766440940') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 120 +INSERT INTO num_exp_add VALUES (2,7,'-117366977.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +INSERT INTO num_exp_sub VALUES (2,7,'48689992.784602953') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +INSERT INTO num_exp_mul VALUES (2,7,'2851072985828710.485883795') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +INSERT INTO num_exp_div VALUES (2,7,'.41357483778485235518') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 124 +INSERT INTO num_exp_add VALUES (2,8,'-34263611.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +INSERT INTO num_exp_sub VALUES (2,8,'-34413373.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 126 +INSERT INTO num_exp_mul VALUES (2,8,'-2571300635581.146276407') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +INSERT INTO num_exp_div VALUES (2,8,'-458.57416721727870888476') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 128 +INSERT INTO num_exp_add VALUES (2,9,'-59265296.260444467') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +INSERT INTO num_exp_sub VALUES (2,9,'-9411688.170349627') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 130 +INSERT INTO num_exp_mul VALUES (2,9,'855948866655588.453741509242968740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 131 +INSERT INTO num_exp_div VALUES (2,9,'1.37757299946438931811') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 132 +INSERT INTO num_exp_add VALUES (3,0,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +INSERT INTO num_exp_sub VALUES (3,0,'4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 134 +INSERT INTO num_exp_mul VALUES (3,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 135 +INSERT INTO num_exp_div VALUES (3,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +INSERT INTO num_exp_add VALUES (3,1,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +INSERT INTO num_exp_sub VALUES (3,1,'4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +INSERT INTO num_exp_mul VALUES (3,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +INSERT INTO num_exp_div VALUES (3,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 140 +INSERT INTO num_exp_add VALUES (3,2,'-34338487.905397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +INSERT INTO num_exp_sub VALUES (3,2,'34338496.525397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +INSERT INTO num_exp_mul VALUES (3,2,'-147998901.44836127257') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +INSERT INTO num_exp_div VALUES (3,2,'-.00000012551512084352') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +INSERT INTO num_exp_add VALUES (3,3,'8.62') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 145 +INSERT INTO num_exp_sub VALUES (3,3,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +INSERT INTO num_exp_mul VALUES (3,3,'18.5761') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +INSERT INTO num_exp_div VALUES (3,3,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +INSERT INTO num_exp_add VALUES (3,4,'7799465.7219') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 149 +INSERT INTO num_exp_sub VALUES (3,4,'-7799457.1019') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +INSERT INTO num_exp_mul VALUES (3,4,'33615678.685289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +INSERT INTO num_exp_div VALUES (3,4,'.00000055260225961552') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +INSERT INTO num_exp_add VALUES (3,5,'16401.348491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 153 +INSERT INTO num_exp_sub VALUES (3,5,'-16392.728491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +INSERT INTO num_exp_mul VALUES (3,5,'70671.23589621') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +INSERT INTO num_exp_div VALUES (3,5,'.00026285234387695504') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +INSERT INTO num_exp_add VALUES (3,6,'93905.88763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 157 +INSERT INTO num_exp_sub VALUES (3,6,'-93897.26763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 158 +INSERT INTO num_exp_mul VALUES (3,6,'404715.7995864206') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +INSERT INTO num_exp_div VALUES (3,6,'.00004589912234457595') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +INSERT INTO num_exp_add VALUES (3,7,'-83028480.69') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 161 +INSERT INTO num_exp_sub VALUES (3,7,'83028489.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +INSERT INTO num_exp_mul VALUES (3,7,'-357852770.35') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +INSERT INTO num_exp_div VALUES (3,7,'-.00000005190989574240') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +INSERT INTO num_exp_add VALUES (3,8,'74885.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +INSERT INTO num_exp_sub VALUES (3,8,'-74876.69') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +INSERT INTO num_exp_mul VALUES (3,8,'322737.11') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 167 +INSERT INTO num_exp_div VALUES (3,8,'.00005755799201399553') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +INSERT INTO num_exp_add VALUES (3,9,'-24926799.735047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +INSERT INTO num_exp_sub VALUES (3,9,'24926808.355047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 170 +INSERT INTO num_exp_mul VALUES (3,9,'-107434525.43415438020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 171 +INSERT INTO num_exp_div VALUES (3,9,'-.00000017290624149854') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +INSERT INTO num_exp_add VALUES (4,0,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +INSERT INTO num_exp_sub VALUES (4,0,'7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 174 +INSERT INTO num_exp_mul VALUES (4,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 175 +INSERT INTO num_exp_div VALUES (4,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 176 +INSERT INTO num_exp_add VALUES (4,1,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 177 +INSERT INTO num_exp_sub VALUES (4,1,'7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +INSERT INTO num_exp_mul VALUES (4,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 179 +INSERT INTO num_exp_div VALUES (4,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 180 +INSERT INTO num_exp_add VALUES (4,2,'-26539030.803497047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 181 +INSERT INTO num_exp_sub VALUES (4,2,'42137953.627297047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 182 +INSERT INTO num_exp_mul VALUES (4,2,'-267821744976817.8111137106593') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 183 +INSERT INTO num_exp_div VALUES (4,2,'-.22713465002993920385') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 184 +INSERT INTO num_exp_add VALUES (4,3,'7799465.7219') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +INSERT INTO num_exp_sub VALUES (4,3,'7799457.1019') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +INSERT INTO num_exp_mul VALUES (4,3,'33615678.685289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +INSERT INTO num_exp_div VALUES (4,3,'1809619.81714617169373549883') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +INSERT INTO num_exp_add VALUES (4,4,'15598922.8238') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +INSERT INTO num_exp_sub VALUES (4,4,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +INSERT INTO num_exp_mul VALUES (4,4,'60831598315717.14146161') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +INSERT INTO num_exp_div VALUES (4,4,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 192 +INSERT INTO num_exp_add VALUES (4,5,'7815858.450391') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +INSERT INTO num_exp_sub VALUES (4,5,'7783064.373409') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 194 +INSERT INTO num_exp_mul VALUES (4,5,'127888068979.9935054429') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 195 +INSERT INTO num_exp_div VALUES (4,5,'475.66281046305802686061') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +INSERT INTO num_exp_add VALUES (4,6,'7893362.98953026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 197 +INSERT INTO num_exp_sub VALUES (4,6,'7705559.83426974') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 198 +INSERT INTO num_exp_mul VALUES (4,6,'732381731243.745115764094') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 199 +INSERT INTO num_exp_div VALUES (4,6,'83.05996138436129499606') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 200 +INSERT INTO num_exp_add VALUES (4,7,'-75229023.5881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +INSERT INTO num_exp_sub VALUES (4,7,'90827946.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +INSERT INTO num_exp_mul VALUES (4,7,'-647577464846017.9715') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +INSERT INTO num_exp_div VALUES (4,7,'-.09393717604145131637') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 204 +INSERT INTO num_exp_add VALUES (4,8,'7874342.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 205 +INSERT INTO num_exp_sub VALUES (4,8,'7724580.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 206 +INSERT INTO num_exp_mul VALUES (4,8,'584031469984.4839') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 207 +INSERT INTO num_exp_div VALUES (4,8,'104.15808298366741897143') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 208 +INSERT INTO num_exp_add VALUES (4,9,'-17127342.633147420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 209 +INSERT INTO num_exp_sub VALUES (4,9,'32726265.456947420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 210 +INSERT INTO num_exp_mul VALUES (4,9,'-194415646271340.1815956522980') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 211 +INSERT INTO num_exp_div VALUES (4,9,'-.31289456112403769409') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 212 +INSERT INTO num_exp_add VALUES (5,0,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 213 +INSERT INTO num_exp_sub VALUES (5,0,'16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 214 +INSERT INTO num_exp_mul VALUES (5,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +INSERT INTO num_exp_div VALUES (5,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +INSERT INTO num_exp_add VALUES (5,1,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 217 +INSERT INTO num_exp_sub VALUES (5,1,'16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 218 +INSERT INTO num_exp_mul VALUES (5,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 219 +INSERT INTO num_exp_div VALUES (5,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 220 +INSERT INTO num_exp_add VALUES (5,2,'-34322095.176906047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 221 +INSERT INTO num_exp_sub VALUES (5,2,'34354889.253888047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 222 +INSERT INTO num_exp_mul VALUES (5,2,'-563049578578.769242506736077') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 223 +INSERT INTO num_exp_div VALUES (5,2,'-.00047751189505192446') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 224 +INSERT INTO num_exp_add VALUES (5,3,'16401.348491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +INSERT INTO num_exp_sub VALUES (5,3,'16392.728491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 226 +INSERT INTO num_exp_mul VALUES (5,3,'70671.23589621') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 227 +INSERT INTO num_exp_div VALUES (5,3,'3804.41728329466357308584') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 228 +INSERT INTO num_exp_add VALUES (5,4,'7815858.450391') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 229 +INSERT INTO num_exp_sub VALUES (5,4,'-7783064.373409') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +INSERT INTO num_exp_mul VALUES (5,4,'127888068979.9935054429') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 231 +INSERT INTO num_exp_div VALUES (5,4,'.00210232958726897192') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 232 +INSERT INTO num_exp_add VALUES (5,5,'32794.076982') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 233 +INSERT INTO num_exp_sub VALUES (5,5,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 234 +INSERT INTO num_exp_mul VALUES (5,5,'268862871.275335557081') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 235 +INSERT INTO num_exp_div VALUES (5,5,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 236 +INSERT INTO num_exp_add VALUES (5,6,'110298.61612126') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 237 +INSERT INTO num_exp_sub VALUES (5,6,'-77504.53913926') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 238 +INSERT INTO num_exp_mul VALUES (5,6,'1539707782.76899778633766') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 239 +INSERT INTO num_exp_div VALUES (5,6,'.17461941433576102689') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +INSERT INTO num_exp_add VALUES (5,7,'-83012087.961509') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 241 +INSERT INTO num_exp_sub VALUES (5,7,'83044882.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 242 +INSERT INTO num_exp_mul VALUES (5,7,'-1361421264394.416135') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 243 +INSERT INTO num_exp_div VALUES (5,7,'-.00019748690453643710') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +INSERT INTO num_exp_add VALUES (5,8,'91278.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +INSERT INTO num_exp_sub VALUES (5,8,'-58483.961509') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 246 +INSERT INTO num_exp_mul VALUES (5,8,'1227826639.244571') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 247 +INSERT INTO num_exp_div VALUES (5,8,'.21897461960978085228') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +INSERT INTO num_exp_add VALUES (5,9,'-24910407.006556420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 249 +INSERT INTO num_exp_sub VALUES (5,9,'24943201.083538420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 250 +INSERT INTO num_exp_mul VALUES (5,9,'-408725765384.257043660243220') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 251 +INSERT INTO num_exp_div VALUES (5,9,'-.00065780749354660427') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 252 +INSERT INTO num_exp_add VALUES (6,0,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +INSERT INTO num_exp_sub VALUES (6,0,'93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +INSERT INTO num_exp_mul VALUES (6,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 255 +INSERT INTO num_exp_div VALUES (6,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 256 +INSERT INTO num_exp_add VALUES (6,1,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 257 +INSERT INTO num_exp_sub VALUES (6,1,'93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 258 +INSERT INTO num_exp_mul VALUES (6,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 259 +INSERT INTO num_exp_div VALUES (6,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 260 +INSERT INTO num_exp_add VALUES (6,2,'-34244590.637766787') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 261 +INSERT INTO num_exp_sub VALUES (6,2,'34432393.793027307') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 262 +INSERT INTO num_exp_mul VALUES (6,2,'-3224438592470.18449811926184222') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 263 +INSERT INTO num_exp_div VALUES (6,2,'-.00273458651128995823') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 264 +INSERT INTO num_exp_add VALUES (6,3,'93905.88763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 265 +INSERT INTO num_exp_sub VALUES (6,3,'93897.26763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 266 +INSERT INTO num_exp_mul VALUES (6,3,'404715.7995864206') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 267 +INSERT INTO num_exp_div VALUES (6,3,'21786.90896293735498839907') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +INSERT INTO num_exp_add VALUES (6,4,'7893362.98953026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +INSERT INTO num_exp_sub VALUES (6,4,'-7705559.83426974') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 270 +INSERT INTO num_exp_mul VALUES (6,4,'732381731243.745115764094') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 271 +INSERT INTO num_exp_div VALUES (6,4,'.01203949512295682469') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 272 +INSERT INTO num_exp_add VALUES (6,5,'110298.61612126') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 273 +INSERT INTO num_exp_sub VALUES (6,5,'77504.53913926') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 274 +INSERT INTO num_exp_mul VALUES (6,5,'1539707782.76899778633766') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 275 +INSERT INTO num_exp_div VALUES (6,5,'5.72674008674192359679') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 276 +INSERT INTO num_exp_add VALUES (6,6,'187803.15526052') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 277 +INSERT INTO num_exp_sub VALUES (6,6,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 278 +INSERT INTO num_exp_mul VALUES (6,6,'8817506281.4517452372676676') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 279 +INSERT INTO num_exp_div VALUES (6,6,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +INSERT INTO num_exp_add VALUES (6,7,'-82934583.42236974') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 281 +INSERT INTO num_exp_sub VALUES (6,7,'83122386.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 282 +INSERT INTO num_exp_mul VALUES (6,7,'-7796505729750.37795610') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +INSERT INTO num_exp_div VALUES (6,7,'-.00113095617281538980') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 284 +INSERT INTO num_exp_add VALUES (6,8,'168782.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 285 +INSERT INTO num_exp_sub VALUES (6,8,'19020.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 286 +INSERT INTO num_exp_mul VALUES (6,8,'7031444034.53149906') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 287 +INSERT INTO num_exp_div VALUES (6,8,'1.25401073209839612184') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 288 +INSERT INTO num_exp_add VALUES (6,9,'-24832902.467417160') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 289 +INSERT INTO num_exp_sub VALUES (6,9,'25020705.622677680') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 290 +INSERT INTO num_exp_mul VALUES (6,9,'-2340666225110.29929521292692920') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 291 +INSERT INTO num_exp_div VALUES (6,9,'-.00376709254265256789') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 292 +INSERT INTO num_exp_add VALUES (7,0,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +INSERT INTO num_exp_sub VALUES (7,0,'-83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 294 +INSERT INTO num_exp_mul VALUES (7,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 295 +INSERT INTO num_exp_div VALUES (7,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 296 +INSERT INTO num_exp_add VALUES (7,1,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 297 +INSERT INTO num_exp_sub VALUES (7,1,'-83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 298 +INSERT INTO num_exp_mul VALUES (7,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 299 +INSERT INTO num_exp_div VALUES (7,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 300 +INSERT INTO num_exp_add VALUES (7,2,'-117366977.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 301 +INSERT INTO num_exp_sub VALUES (7,2,'-48689992.784602953') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 302 +INSERT INTO num_exp_mul VALUES (7,2,'2851072985828710.485883795') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 303 +INSERT INTO num_exp_div VALUES (7,2,'2.41794207151503385700') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 304 +INSERT INTO num_exp_add VALUES (7,3,'-83028480.69') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 305 +INSERT INTO num_exp_sub VALUES (7,3,'-83028489.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +INSERT INTO num_exp_mul VALUES (7,3,'-357852770.35') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 307 +INSERT INTO num_exp_div VALUES (7,3,'-19264149.65197215777262180974') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 308 +INSERT INTO num_exp_add VALUES (7,4,'-75229023.5881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 309 +INSERT INTO num_exp_sub VALUES (7,4,'-90827946.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 310 +INSERT INTO num_exp_mul VALUES (7,4,'-647577464846017.9715') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 311 +INSERT INTO num_exp_div VALUES (7,4,'-10.64541262725136247686') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 312 +INSERT INTO num_exp_add VALUES (7,5,'-83012087.961509') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 313 +INSERT INTO num_exp_sub VALUES (7,5,'-83044882.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 314 +INSERT INTO num_exp_mul VALUES (7,5,'-1361421264394.416135') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 315 +INSERT INTO num_exp_div VALUES (7,5,'-5063.62688881730941836574') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 316 +INSERT INTO num_exp_add VALUES (7,6,'-82934583.42236974') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 317 +INSERT INTO num_exp_sub VALUES (7,6,'-83122386.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 318 +INSERT INTO num_exp_mul VALUES (7,6,'-7796505729750.37795610') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 319 +INSERT INTO num_exp_div VALUES (7,6,'-884.20756174009028770294') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 320 +INSERT INTO num_exp_add VALUES (7,7,'-166056970') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 321 +INSERT INTO num_exp_sub VALUES (7,7,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 322 +INSERT INTO num_exp_mul VALUES (7,7,'6893729321395225') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 323 +INSERT INTO num_exp_div VALUES (7,7,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 324 +INSERT INTO num_exp_add VALUES (7,8,'-82953604') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 325 +INSERT INTO num_exp_sub VALUES (7,8,'-83103366') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 326 +INSERT INTO num_exp_mul VALUES (7,8,'-6217255985285') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 327 +INSERT INTO num_exp_div VALUES (7,8,'-1108.80577182462841041118') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 328 +INSERT INTO num_exp_add VALUES (7,9,'-107955289.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 329 +INSERT INTO num_exp_sub VALUES (7,9,'-58101680.954952580') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 330 +INSERT INTO num_exp_mul VALUES (7,9,'2069634775752159.035758700') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 331 +INSERT INTO num_exp_div VALUES (7,9,'3.33089171198810413382') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 332 +INSERT INTO num_exp_add VALUES (8,0,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 333 +INSERT INTO num_exp_sub VALUES (8,0,'74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 334 +INSERT INTO num_exp_mul VALUES (8,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 335 +INSERT INTO num_exp_div VALUES (8,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 336 +INSERT INTO num_exp_add VALUES (8,1,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 337 +INSERT INTO num_exp_sub VALUES (8,1,'74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 338 +INSERT INTO num_exp_mul VALUES (8,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 339 +INSERT INTO num_exp_div VALUES (8,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 340 +INSERT INTO num_exp_add VALUES (8,2,'-34263611.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 341 +INSERT INTO num_exp_sub VALUES (8,2,'34413373.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 342 +INSERT INTO num_exp_mul VALUES (8,2,'-2571300635581.146276407') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 343 +INSERT INTO num_exp_div VALUES (8,2,'-.00218067233500788615') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 344 +INSERT INTO num_exp_add VALUES (8,3,'74885.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 345 +INSERT INTO num_exp_sub VALUES (8,3,'74876.69') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 346 +INSERT INTO num_exp_mul VALUES (8,3,'322737.11') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 347 +INSERT INTO num_exp_div VALUES (8,3,'17373.78190255220417633410') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 348 +INSERT INTO num_exp_add VALUES (8,4,'7874342.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 349 +INSERT INTO num_exp_sub VALUES (8,4,'-7724580.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 350 +INSERT INTO num_exp_mul VALUES (8,4,'584031469984.4839') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 351 +INSERT INTO num_exp_div VALUES (8,4,'.00960079113741758956') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 352 +INSERT INTO num_exp_add VALUES (8,5,'91278.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 353 +INSERT INTO num_exp_sub VALUES (8,5,'58483.961509') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 354 +INSERT INTO num_exp_mul VALUES (8,5,'1227826639.244571') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 355 +INSERT INTO num_exp_div VALUES (8,5,'4.56673929509287019456') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 356 +INSERT INTO num_exp_add VALUES (8,6,'168782.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 357 +INSERT INTO num_exp_sub VALUES (8,6,'-19020.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 358 +INSERT INTO num_exp_mul VALUES (8,6,'7031444034.53149906') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 359 +INSERT INTO num_exp_div VALUES (8,6,'.79744134113322314424') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +INSERT INTO num_exp_add VALUES (8,7,'-82953604') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 361 +INSERT INTO num_exp_sub VALUES (8,7,'83103366') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 362 +INSERT INTO num_exp_mul VALUES (8,7,'-6217255985285') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 363 +INSERT INTO num_exp_div VALUES (8,7,'-.00090187120721280172') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 364 +INSERT INTO num_exp_add VALUES (8,8,'149762') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 365 +INSERT INTO num_exp_sub VALUES (8,8,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 366 +INSERT INTO num_exp_mul VALUES (8,8,'5607164161') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 367 +INSERT INTO num_exp_div VALUES (8,8,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 368 +INSERT INTO num_exp_add VALUES (8,9,'-24851923.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 369 +INSERT INTO num_exp_sub VALUES (8,9,'25001685.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 370 +INSERT INTO num_exp_mul VALUES (8,9,'-1866544013697.195857020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 371 +INSERT INTO num_exp_div VALUES (8,9,'-.00300403532938582735') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 372 +INSERT INTO num_exp_add VALUES (9,0,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 373 +INSERT INTO num_exp_sub VALUES (9,0,'-24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 374 +INSERT INTO num_exp_mul VALUES (9,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 375 +INSERT INTO num_exp_div VALUES (9,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 376 +INSERT INTO num_exp_add VALUES (9,1,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 377 +INSERT INTO num_exp_sub VALUES (9,1,'-24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 378 +INSERT INTO num_exp_mul VALUES (9,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 379 +INSERT INTO num_exp_div VALUES (9,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 380 +INSERT INTO num_exp_add VALUES (9,2,'-59265296.260444467') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 381 +INSERT INTO num_exp_sub VALUES (9,2,'9411688.170349627') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 382 +INSERT INTO num_exp_mul VALUES (9,2,'855948866655588.453741509242968740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 383 +INSERT INTO num_exp_div VALUES (9,2,'.72591434384152961526') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 384 +INSERT INTO num_exp_add VALUES (9,3,'-24926799.735047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 385 +INSERT INTO num_exp_sub VALUES (9,3,'-24926808.355047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 386 +INSERT INTO num_exp_mul VALUES (9,3,'-107434525.43415438020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 387 +INSERT INTO num_exp_div VALUES (9,3,'-5783481.21694835730858468677') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 388 +INSERT INTO num_exp_add VALUES (9,4,'-17127342.633147420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 389 +INSERT INTO num_exp_sub VALUES (9,4,'-32726265.456947420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 390 +INSERT INTO num_exp_mul VALUES (9,4,'-194415646271340.1815956522980') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 391 +INSERT INTO num_exp_div VALUES (9,4,'-3.19596478892958416484') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 392 +INSERT INTO num_exp_add VALUES (9,5,'-24910407.006556420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 393 +INSERT INTO num_exp_sub VALUES (9,5,'-24943201.083538420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 394 +INSERT INTO num_exp_mul VALUES (9,5,'-408725765384.257043660243220') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 395 +INSERT INTO num_exp_div VALUES (9,5,'-1520.20159364322004505807') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 396 +INSERT INTO num_exp_add VALUES (9,6,'-24832902.467417160') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 397 +INSERT INTO num_exp_sub VALUES (9,6,'-25020705.622677680') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 398 +INSERT INTO num_exp_mul VALUES (9,6,'-2340666225110.29929521292692920') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 399 +INSERT INTO num_exp_div VALUES (9,6,'-265.45671195426965751280') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 400 +INSERT INTO num_exp_add VALUES (9,7,'-107955289.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 401 +INSERT INTO num_exp_sub VALUES (9,7,'58101680.954952580') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 402 +INSERT INTO num_exp_mul VALUES (9,7,'2069634775752159.035758700') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 403 +INSERT INTO num_exp_div VALUES (9,7,'.30021990699995814689') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 404 +INSERT INTO num_exp_add VALUES (9,8,'-24851923.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 405 +INSERT INTO num_exp_sub VALUES (9,8,'-25001685.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 406 +INSERT INTO num_exp_mul VALUES (9,8,'-1866544013697.195857020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 407 +INSERT INTO num_exp_div VALUES (9,8,'-332.88556569820675471748') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 408 +INSERT INTO num_exp_add VALUES (9,9,'-49853608.090094840') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 409 +INSERT INTO num_exp_sub VALUES (9,9,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 410 +INSERT INTO num_exp_mul VALUES (9,9,'621345559900192.420120630048656400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 411 +INSERT INTO num_exp_div VALUES (9,9,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 412 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 413 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 414 +INSERT INTO num_exp_sqrt VALUES (0,'0') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 415 +INSERT INTO num_exp_sqrt VALUES (1,'0') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 416 +INSERT INTO num_exp_sqrt VALUES (2,'5859.90547836712524903505') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 417 +INSERT INTO num_exp_sqrt VALUES (3,'2.07605394920266944396') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 418 +INSERT INTO num_exp_sqrt VALUES (4,'2792.75158435189147418923') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 419 +INSERT INTO num_exp_sqrt VALUES (5,'128.05092147657509145473') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 420 +INSERT INTO num_exp_sqrt VALUES (6,'306.43364311096782703406') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 421 +INSERT INTO num_exp_sqrt VALUES (7,'9111.99676251039939975230') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 422 +INSERT INTO num_exp_sqrt VALUES (8,'273.64392922189960397542') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 423 +INSERT INTO num_exp_sqrt VALUES (9,'4992.67503899937593364766') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 424 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 425 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 426 +INSERT INTO num_exp_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 427 +INSERT INTO num_exp_ln VALUES (1,'NaN') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 428 +INSERT INTO num_exp_ln VALUES (2,'17.35177750493897715514') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 429 +INSERT INTO num_exp_ln VALUES (3,'1.46093790411565641971') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 430 +INSERT INTO num_exp_ln VALUES (4,'15.86956523951936572464') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 431 +INSERT INTO num_exp_ln VALUES (5,'9.70485601768871834038') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 432 +INSERT INTO num_exp_ln VALUES (6,'11.45000246622944403127') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 433 +INSERT INTO num_exp_ln VALUES (7,'18.23469429965478772991') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 434 +INSERT INTO num_exp_ln VALUES (8,'11.22365546576315513668') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 435 +INSERT INTO num_exp_ln VALUES (9,'17.03145425013166006962') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 436 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 437 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 438 +INSERT INTO num_exp_log10 VALUES (0,'NaN') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 439 +INSERT INTO num_exp_log10 VALUES (1,'NaN') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 440 +INSERT INTO num_exp_log10 VALUES (2,'7.53578122160797276459') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 441 +INSERT INTO num_exp_log10 VALUES (3,'.63447727016073160075') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 442 +INSERT INTO num_exp_log10 VALUES (4,'6.89206461372691743345') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 443 +INSERT INTO num_exp_log10 VALUES (5,'4.21476541614777768626') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 444 +INSERT INTO num_exp_log10 VALUES (6,'4.97267288886207207671') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 445 +INSERT INTO num_exp_log10 VALUES (7,'7.91922711353275546914') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 446 +INSERT INTO num_exp_log10 VALUES (8,'4.87437163556421004138') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 447 +INSERT INTO num_exp_log10 VALUES (9,'7.39666659961986567059') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 448 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 449 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 450 +INSERT INTO num_exp_power_10_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 451 +INSERT INTO num_exp_power_10_ln VALUES (1,'NaN') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 452 +INSERT INTO num_exp_power_10_ln VALUES (2,'224790267919917955.13261618583642653184') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 453 +INSERT INTO num_exp_power_10_ln VALUES (3,'28.90266599445155957393') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 454 +INSERT INTO num_exp_power_10_ln VALUES (4,'7405685069594999.07733999469386277636') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 455 +INSERT INTO num_exp_power_10_ln VALUES (5,'5068226527.32127265408584640098') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 456 +INSERT INTO num_exp_power_10_ln VALUES (6,'281839893606.99372343357047819067') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 457 +INSERT INTO num_exp_power_10_ln VALUES (7,'1716699575118597095.42330819910640247627') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 458 +INSERT INTO num_exp_power_10_ln VALUES (8,'167361463828.07491320069016125952') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 459 +INSERT INTO num_exp_power_10_ln VALUES (9,'107511333880052007.04141124673540337457') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 460 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 461 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 462 +INSERT INTO num_data VALUES (0, '0') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 463 +INSERT INTO num_data VALUES (1, '0') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 464 +INSERT INTO num_data VALUES (2, '-34338492.215397047') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 465 +INSERT INTO num_data VALUES (3, '4.31') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 466 +INSERT INTO num_data VALUES (4, '7799461.4119') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 467 +INSERT INTO num_data VALUES (5, '16397.038491') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 468 +INSERT INTO num_data VALUES (6, '93901.57763026') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 469 +INSERT INTO num_data VALUES (7, '-83028485') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 470 +INSERT INTO num_data VALUES (8, '74881') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 471 +INSERT INTO num_data VALUES (9, '-24926804.045047420') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 472 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 473 +-- ****************************** +-- * Create indices for faster checks +-- ****************************** + +CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add (id1, id2) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: IndexStmt +== 474 +CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub (id1, id2) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: IndexStmt +== 475 +CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div (id1, id2) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: IndexStmt +== 476 +CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul (id1, id2) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: IndexStmt +== 477 +CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt (id) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: IndexStmt +== 478 +CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln (id) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: IndexStmt +== 479 +CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 (id) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: IndexStmt +== 480 +CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln (id) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: IndexStmt +== 481 +VACUUM ANALYZE num_exp_add +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: VacuumStmt +== 482 +VACUUM ANALYZE num_exp_sub +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: VacuumStmt +== 483 +VACUUM ANALYZE num_exp_div +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: VacuumStmt +== 484 +VACUUM ANALYZE num_exp_mul +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: VacuumStmt +== 485 +VACUUM ANALYZE num_exp_sqrt +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: VacuumStmt +== 486 +VACUUM ANALYZE num_exp_ln +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: VacuumStmt +== 487 +VACUUM ANALYZE num_exp_log10 +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: VacuumStmt +== 488 +VACUUM ANALYZE num_exp_power_10_ln +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: VacuumStmt +== 489 +-- ****************************** +-- * Now check the behaviour of the NUMERIC type +-- ****************************** + +-- ****************************** +-- * Addition check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 490 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +== 491 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 492 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 493 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 494 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 10) as expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 10) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 495 +-- ****************************** +-- * Subtraction check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 496 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +== 497 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 498 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 499 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 500 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 40) + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 40) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 501 +-- ****************************** +-- * Multiply check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 502 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +== 503 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 504 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 505 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 506 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 30) as expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 30) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 507 +-- ****************************** +-- * Division check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 508 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val / t2.val + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 509 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 510 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 511 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val / t2.val, 80) + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 512 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 80) as expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 80) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 513 +-- ****************************** +-- * Square root check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 514 +INSERT INTO num_result SELECT id, 0, SQRT(ABS(val)) + FROM num_data +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 515 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_sqrt t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sqrt" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 516 +-- ****************************** +-- * Natural logarithm check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 517 +INSERT INTO num_result SELECT id, 0, LN(ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 518 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 519 +-- ****************************** +-- * Logarithm base 10 check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 520 +INSERT INTO num_result SELECT id, 0, LOG(numeric '10', ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 521 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_log10 t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_log10" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 522 +-- ****************************** +-- * POWER(10, LN(value)) check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 523 +INSERT INTO num_result SELECT id, 0, POWER(numeric '10', LN(ABS(round(val,200)))) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="power" function="power" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 524 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_power_10_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_power_10_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 525 +-- ****************************** +-- * Check behavior with Inf and NaN inputs. It's easiest to handle these +-- * separately from the num_data framework used above, because some input +-- * combinations will throw errors. +-- ****************************** + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('inf'),('-inf'),('nan')) +SELECT x1, x2, + x1 + x2 AS sum, + x1 - x2 AS diff, + x1 * x2 AS prod +FROM v AS v1(x1), v AS v2(x2) +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +STMT: SelectStmt +== 526 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('inf'),('-inf'),('nan')) +SELECT x1, x2, + x1 / x2 AS quot, + x1 % x2 AS mod, + div(x1, x2) AS div +FROM v AS v1(x1), v AS v2(x2) WHERE x2 != 0 +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +FUNCTION: name="div" function="div" schema="" ctx=Call +FILTER: schema="" table="" column="x2" +STMT: SelectStmt +== 527 +SELECT 'inf'::numeric / '0' +-- +STMT: SelectStmt +== 528 +SELECT '-inf'::numeric / '0' +-- +STMT: SelectStmt +== 529 +SELECT 'nan'::numeric / '0' +-- +STMT: SelectStmt +== 530 +SELECT '0'::numeric / '0' +-- +STMT: SelectStmt +== 531 +SELECT 'inf'::numeric % '0' +-- +STMT: SelectStmt +== 532 +SELECT '-inf'::numeric % '0' +-- +STMT: SelectStmt +== 533 +SELECT 'nan'::numeric % '0' +-- +STMT: SelectStmt +== 534 +SELECT '0'::numeric % '0' +-- +STMT: SelectStmt +== 535 +SELECT div('inf'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 536 +SELECT div('-inf'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 537 +SELECT div('nan'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 538 +SELECT div('0'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 539 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('inf'),('-inf'),('nan')) +SELECT x, -x as minusx, abs(x), floor(x), ceil(x), sign(x), numeric_inc(x) as inc +FROM v +-- +CTE: "v" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="floor" function="floor" schema="" ctx=Call +FUNCTION: name="ceil" function="ceil" schema="" ctx=Call +FUNCTION: name="sign" function="sign" schema="" ctx=Call +FUNCTION: name="numeric_inc" function="numeric_inc" schema="" ctx=Call +STMT: SelectStmt +== 540 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('inf'),('-inf'),('nan')) +SELECT x, round(x), round(x,1) as round1, trunc(x), trunc(x,1) as trunc1 +FROM v +-- +CTE: "v" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 541 +-- the large values fall into the numeric abbreviation code's maximal classes +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('1e340'),('-1e340'), + ('inf'),('-inf'),('nan'), + ('inf'),('-inf'),('nan')) +SELECT substring(x::text, 1, 32) +FROM v ORDER BY x +-- +CTE: "v" +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +== 542 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('4.2'),('inf'),('nan')) +SELECT x, sqrt(x) +FROM v +-- +CTE: "v" +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 543 +SELECT sqrt('-1'::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 544 +SELECT sqrt('-inf'::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 545 +WITH v(x) AS + (VALUES('1'::numeric),('4.2'),('inf'),('nan')) +SELECT x, + log(x), + log10(x), + ln(x) +FROM v +-- +CTE: "v" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log10" function="log10" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 546 +SELECT ln('0'::numeric) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 547 +SELECT ln('-1'::numeric) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 548 +SELECT ln('-inf'::numeric) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 549 +WITH v(x) AS + (VALUES('2'::numeric),('4.2'),('inf'),('nan')) +SELECT x1, x2, + log(x1, x2) +FROM v AS v1(x1), v AS v2(x2) +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 550 +SELECT log('0'::numeric, '10') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 551 +SELECT log('10'::numeric, '0') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 552 +SELECT log('-inf'::numeric, '10') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 553 +SELECT log('10'::numeric, '-inf') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 554 +SELECT log('inf'::numeric, '0') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 555 +SELECT log('inf'::numeric, '-inf') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 556 +SELECT log('-inf'::numeric, 'inf') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 557 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('2'),('4.2'),('inf'),('nan')) +SELECT x1, x2, + power(x1, x2) +FROM v AS v1(x1), v AS v2(x2) WHERE x1 != 0 OR x2 >= 0 +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +FUNCTION: name="power" function="power" schema="" ctx=Call +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x2" +STMT: SelectStmt +== 558 +SELECT power('0'::numeric, '-1') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 559 +SELECT power('0'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 560 +SELECT power('-1'::numeric, 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 561 +SELECT power('-2'::numeric, '3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 562 +SELECT power('-2'::numeric, '3.3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 563 +SELECT power('-2'::numeric, '-1') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 564 +SELECT power('-2'::numeric, '-1.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 565 +SELECT power('-2'::numeric, 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 566 +SELECT power('-2'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 567 +SELECT power('inf'::numeric, '-2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 568 +SELECT power('inf'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 569 +SELECT power('-inf'::numeric, '2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 570 +SELECT power('-inf'::numeric, '3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 571 +SELECT power('-inf'::numeric, '4.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 572 +SELECT power('-inf'::numeric, '-2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 573 +SELECT power('-inf'::numeric, '-3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 574 +SELECT power('-inf'::numeric, '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 575 +SELECT power('-inf'::numeric, 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 576 +SELECT power('-inf'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +== 577 +-- ****************************** +-- * miscellaneous checks for things that have been broken in the past... +-- ****************************** +-- numeric AVG used to fail on some platforms +SELECT AVG(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 578 +SELECT MAX(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 579 +SELECT MIN(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 580 +SELECT STDDEV(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +== 581 +SELECT VARIANCE(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 582 +-- Check for appropriate rounding and overflow +CREATE TABLE fract_only (id int, val numeric(4,4)) +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DDL +STMT: CreateStmt +== 583 +INSERT INTO fract_only VALUES (1, '0.0') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 584 +INSERT INTO fract_only VALUES (2, '0.1') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 585 +INSERT INTO fract_only VALUES (3, '1.0') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 586 +-- should fail +INSERT INTO fract_only VALUES (4, '-0.9999') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 587 +INSERT INTO fract_only VALUES (5, '0.99994') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 588 +INSERT INTO fract_only VALUES (6, '0.99995') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 589 +-- should fail +INSERT INTO fract_only VALUES (7, '0.00001') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 590 +INSERT INTO fract_only VALUES (8, '0.00017') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 591 +INSERT INTO fract_only VALUES (9, 'NaN') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 592 +INSERT INTO fract_only VALUES (10, 'Inf') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 593 +-- should fail +INSERT INTO fract_only VALUES (11, '-Inf') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 594 +-- should fail +SELECT * FROM fract_only +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=Select +STMT: SelectStmt +== 595 +DROP TABLE fract_only +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DDL +STMT: DropStmt +== 596 +-- Check conversion to integers +SELECT (-9223372036854775808.5)::int8 +-- +STMT: SelectStmt +== 597 +-- should fail +SELECT (-9223372036854775808.4)::int8 +-- +STMT: SelectStmt +== 598 +-- ok +SELECT 9223372036854775807.4::int8 +-- +STMT: SelectStmt +== 599 +-- ok +SELECT 9223372036854775807.5::int8 +-- +STMT: SelectStmt +== 600 +-- should fail +SELECT (-2147483648.5)::int4 +-- +STMT: SelectStmt +== 601 +-- should fail +SELECT (-2147483648.4)::int4 +-- +STMT: SelectStmt +== 602 +-- ok +SELECT 2147483647.4::int4 +-- +STMT: SelectStmt +== 603 +-- ok +SELECT 2147483647.5::int4 +-- +STMT: SelectStmt +== 604 +-- should fail +SELECT (-32768.5)::int2 +-- +STMT: SelectStmt +== 605 +-- should fail +SELECT (-32768.4)::int2 +-- +STMT: SelectStmt +== 606 +-- ok +SELECT 32767.4::int2 +-- +STMT: SelectStmt +== 607 +-- ok +SELECT 32767.5::int2 +-- +STMT: SelectStmt +== 608 +-- should fail + +-- Check inf/nan conversion behavior +SELECT 'NaN'::float8::numeric +-- +STMT: SelectStmt +== 609 +SELECT 'Infinity'::float8::numeric +-- +STMT: SelectStmt +== 610 +SELECT '-Infinity'::float8::numeric +-- +STMT: SelectStmt +== 611 +SELECT 'NaN'::numeric::float8 +-- +STMT: SelectStmt +== 612 +SELECT 'Infinity'::numeric::float8 +-- +STMT: SelectStmt +== 613 +SELECT '-Infinity'::numeric::float8 +-- +STMT: SelectStmt +== 614 +SELECT 'NaN'::float4::numeric +-- +STMT: SelectStmt +== 615 +SELECT 'Infinity'::float4::numeric +-- +STMT: SelectStmt +== 616 +SELECT '-Infinity'::float4::numeric +-- +STMT: SelectStmt +== 617 +SELECT 'NaN'::numeric::float4 +-- +STMT: SelectStmt +== 618 +SELECT 'Infinity'::numeric::float4 +-- +STMT: SelectStmt +== 619 +SELECT '-Infinity'::numeric::float4 +-- +STMT: SelectStmt +== 620 +SELECT '42'::int2::numeric +-- +STMT: SelectStmt +== 621 +SELECT 'NaN'::numeric::int2 +-- +STMT: SelectStmt +== 622 +SELECT 'Infinity'::numeric::int2 +-- +STMT: SelectStmt +== 623 +SELECT '-Infinity'::numeric::int2 +-- +STMT: SelectStmt +== 624 +SELECT 'NaN'::numeric::int4 +-- +STMT: SelectStmt +== 625 +SELECT 'Infinity'::numeric::int4 +-- +STMT: SelectStmt +== 626 +SELECT '-Infinity'::numeric::int4 +-- +STMT: SelectStmt +== 627 +SELECT 'NaN'::numeric::int8 +-- +STMT: SelectStmt +== 628 +SELECT 'Infinity'::numeric::int8 +-- +STMT: SelectStmt +== 629 +SELECT '-Infinity'::numeric::int8 +-- +STMT: SelectStmt +== 630 +-- Simple check that ceil(), floor(), and round() work correctly +CREATE TABLE ceil_floor_round (a numeric) +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DDL +STMT: CreateStmt +== 631 +INSERT INTO ceil_floor_round VALUES ('-5.5') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 632 +INSERT INTO ceil_floor_round VALUES ('-5.499999') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 633 +INSERT INTO ceil_floor_round VALUES ('9.5') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 634 +INSERT INTO ceil_floor_round VALUES ('9.4999999') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 635 +INSERT INTO ceil_floor_round VALUES ('0.0') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 636 +INSERT INTO ceil_floor_round VALUES ('0.0000001') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 637 +INSERT INTO ceil_floor_round VALUES ('-0.000001') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 638 +SELECT a, ceil(a), ceiling(a), floor(a), round(a) FROM ceil_floor_round +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=Select +FUNCTION: name="ceil" function="ceil" schema="" ctx=Call +FUNCTION: name="ceiling" function="ceiling" schema="" ctx=Call +FUNCTION: name="floor" function="floor" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 639 +DROP TABLE ceil_floor_round +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DDL +STMT: DropStmt +== 640 +-- Check rounding, it should round ties away from zero. +SELECT i as pow, + round((-2.5 * 10 ^ i)::numeric, -i), + round((-1.5 * 10 ^ i)::numeric, -i), + round((-0.5 * 10 ^ i)::numeric, -i), + round((0.5 * 10 ^ i)::numeric, -i), + round((1.5 * 10 ^ i)::numeric, -i), + round((2.5 * 10 ^ i)::numeric, -i) +FROM generate_series(-5,5) AS t(i) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 641 +-- Check limits of rounding before the decimal point +SELECT round(4.4e131071, -131071) = 4e131071 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 642 +SELECT round(4.5e131071, -131071) = 5e131071 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 643 +SELECT round(4.5e131071, -131072) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 644 +-- loses all digits +SELECT round(5.5e131071, -131072) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 645 +-- rounds up and overflows +SELECT round(5.5e131071, -131073) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 646 +-- loses all digits +SELECT round(5.5e131071, -1000000) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 647 +-- loses all digits + +-- Check limits of rounding after the decimal point +SELECT round(5e-16383, 1000000) = 5e-16383 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 648 +SELECT round(5e-16383, 16383) = 5e-16383 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 649 +SELECT round(5e-16383, 16382) = 1e-16382 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 650 +SELECT round(5e-16383, 16381) = 0 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 651 +-- Check limits of trunc() before the decimal point +SELECT trunc(9.9e131071, -131071) = 9e131071 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 652 +SELECT trunc(9.9e131071, -131072) +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 653 +-- loses all digits +SELECT trunc(9.9e131071, -131073) +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 654 +-- loses all digits +SELECT trunc(9.9e131071, -1000000) +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 655 +-- loses all digits + +-- Check limits of trunc() after the decimal point +SELECT trunc(5e-16383, 1000000) = 5e-16383 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 656 +SELECT trunc(5e-16383, 16383) = 5e-16383 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 657 +SELECT trunc(5e-16383, 16382) = 0 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +== 658 +-- Testing for width_bucket(). For convenience, we test both the +-- numeric and float8 versions of the function in this file. + +-- errors +SELECT width_bucket(5.0, 3.0, 4.0, 0) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 659 +SELECT width_bucket(5.0, 3.0, 4.0, -5) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 660 +SELECT width_bucket(3.5, 3.0, 3.0, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 661 +SELECT width_bucket(5.0::float8, 3.0::float8, 4.0::float8, 0) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 662 +SELECT width_bucket(5.0::float8, 3.0::float8, 4.0::float8, -5) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 663 +SELECT width_bucket(3.5::float8, 3.0::float8, 3.0::float8, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 664 +SELECT width_bucket('NaN', 3.0, 4.0, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 665 +SELECT width_bucket(0::float8, 'NaN', 4.0::float8, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 666 +SELECT width_bucket(2.0, 3.0, '-inf', 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 667 +SELECT width_bucket(0::float8, '-inf', 4.0::float8, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 668 +-- normal operation +CREATE TABLE width_bucket_test (operand_num numeric, operand_f8 float8) +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=DDL +STMT: CreateStmt +== 669 +COPY width_bucket_test (operand_num) FROM stdin +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=Select +STMT: CopyStmt +== 670 +UPDATE width_bucket_test SET operand_f8 = operand_num::float8 +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=DML +STMT: UpdateStmt +== 671 +SELECT + operand_num, + width_bucket(operand_num, 0, 10, 5) AS wb_1, + width_bucket(operand_f8, 0, 10, 5) AS wb_1f, + width_bucket(operand_num, 10, 0, 5) AS wb_2, + width_bucket(operand_f8, 10, 0, 5) AS wb_2f, + width_bucket(operand_num, 2, 8, 4) AS wb_3, + width_bucket(operand_f8, 2, 8, 4) AS wb_3f, + width_bucket(operand_num, 5.0, 5.5, 20) AS wb_4, + width_bucket(operand_f8, 5.0, 5.5, 20) AS wb_4f, + width_bucket(operand_num, -25, 25, 10) AS wb_5, + width_bucket(operand_f8, -25, 25, 10) AS wb_5f + FROM width_bucket_test +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=Select +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 672 +-- Check positive and negative infinity: we require +-- finite bucket bounds, but allow an infinite operand +SELECT width_bucket(0.0::numeric, 'Infinity'::numeric, 5, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 673 +-- error +SELECT width_bucket(0.0::numeric, 5, '-Infinity'::numeric, 20) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 674 +-- error +SELECT width_bucket('Infinity'::numeric, 1, 10, 10), + width_bucket('-Infinity'::numeric, 1, 10, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 675 +SELECT width_bucket(0.0::float8, 'Infinity'::float8, 5, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 676 +-- error +SELECT width_bucket(0.0::float8, 5, '-Infinity'::float8, 20) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 677 +-- error +SELECT width_bucket('Infinity'::float8, 1, 10, 10), + width_bucket('-Infinity'::float8, 1, 10, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 678 +DROP TABLE width_bucket_test +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=DDL +STMT: DropStmt +== 679 +-- Simple test for roundoff error when results should be exact +SELECT x, width_bucket(x::float8, 10, 100, 9) as flt, + width_bucket(x::numeric, 10, 100, 9) as num +FROM generate_series(0, 110, 10) x +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 680 +SELECT x, width_bucket(x::float8, 100, 10, 9) as flt, + width_bucket(x::numeric, 100, 10, 9) as num +FROM generate_series(0, 110, 10) x +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 681 +-- Another roundoff-error hazard +SELECT width_bucket(0, -1e100::numeric, 1, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 682 +SELECT width_bucket(0, -1e100::float8, 1, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 683 +SELECT width_bucket(1, 1e100::numeric, 0, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 684 +SELECT width_bucket(1, 1e100::float8, 0, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 685 +-- Check cases that could trigger overflow or underflow within the calculation +SELECT oper, low, high, cnt, width_bucket(oper, low, high, cnt) +FROM + (SELECT 1.797e+308::float8 AS big, 5e-324::float8 AS tiny) as v, + LATERAL (VALUES + (10.5::float8, -big, big, 1), + (10.5::float8, -big, big, 2), + (10.5::float8, -big, big, 3), + (big / 4, -big / 2, big / 2, 10), + (10.5::float8, big, -big, 1), + (10.5::float8, big, -big, 2), + (10.5::float8, big, -big, 3), + (big / 4, big / 2, -big / 2, 10), + (0, 0, tiny, 4), + (tiny, 0, tiny, 4), + (0, 0, 1, 2147483647), + (1, 1, 0, 2147483647) + ) as sample(oper, low, high, cnt) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 686 +-- These fail because the result would be out of int32 range: +SELECT width_bucket(1::float8, 0, 1, 2147483647) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 687 +SELECT width_bucket(0::float8, 1, 0, 2147483647) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +== 688 +|-- +-- TO_CHAR() +|-- +SELECT to_char(val, '9G999G999G999G999G999') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 689 +SELECT to_char(val, '9G999G999G999G999G999D999G999G999G999G999') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 690 +SELECT to_char(val, '9999999999999999.999999999999999PR') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 691 +SELECT to_char(val, '9999999999999999.999999999999999S') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 692 +SELECT to_char(val, 'MI9999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 693 +SELECT to_char(val, 'FMS9999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 694 +SELECT to_char(val, 'FM9999999999999999.999999999999999THPR') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 695 +SELECT to_char(val, 'SG9999999999999999.999999999999999th') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 696 +SELECT to_char(val, '0999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 697 +SELECT to_char(val, 'S0999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 698 +SELECT to_char(val, 'FM0999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 699 +SELECT to_char(val, 'FM9999999999999999.099999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 700 +SELECT to_char(val, 'FM9999999999990999.990999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 701 +SELECT to_char(val, 'FM0999999999999999.999909999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 702 +SELECT to_char(val, 'FM9999999990999999.099999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 703 +SELECT to_char(val, 'L9999999999999999.099999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 704 +SELECT to_char(val, 'FM9999999999999999.99999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 705 +SELECT to_char(val, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 706 +SELECT to_char(val, 'FMS 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 707 +SELECT to_char(val, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 708 +SELECT to_char(val, '999999SG9999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 709 +SELECT to_char(val, 'FM9999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 710 +SELECT to_char(val, '9.999EEEE') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 711 +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, '9.999EEEE') as numeric, + to_char(val::float8, '9.999EEEE') as float8, + to_char(val::float4, '9.999EEEE') as float4 +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 712 +WITH v(exp) AS + (VALUES(-16379),(-16378),(-1234),(-789),(-45),(-5),(-4),(-3),(-2),(-1),(0), + (1),(2),(3),(4),(5),(38),(275),(2345),(45678),(131070),(131071)) +SELECT exp, + to_char(('1.2345e'||exp)::numeric, '9.999EEEE') as numeric +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 713 +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, 'MI9999999999.99') as numeric, + to_char(val::float8, 'MI9999999999.99') as float8, + to_char(val::float4, 'MI9999999999.99') as float4 +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 714 +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, 'MI99.99') as numeric, + to_char(val::float8, 'MI99.99') as float8, + to_char(val::float4, 'MI99.99') as float4 +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 715 +SELECT to_char('100'::numeric, 'FM999.9') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 716 +SELECT to_char('100'::numeric, 'FM999.') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 717 +SELECT to_char('100'::numeric, 'FM999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 718 +SELECT to_char('12345678901'::float8, 'FM9999999999D9999900000000000000000') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 719 +-- Check parsing of literal text in a format string +SELECT to_char('100'::numeric, 'foo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 720 +SELECT to_char('100'::numeric, 'f\oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 721 +SELECT to_char('100'::numeric, 'f\\oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 722 +SELECT to_char('100'::numeric, 'f\"oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 723 +SELECT to_char('100'::numeric, 'f\\"oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 724 +SELECT to_char('100'::numeric, 'f"ool"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 725 +SELECT to_char('100'::numeric, 'f"\ool"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 726 +SELECT to_char('100'::numeric, 'f"\\ool"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 727 +SELECT to_char('100'::numeric, 'f"ool\"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 728 +SELECT to_char('100'::numeric, 'f"ool\\"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 729 +-- TO_NUMBER() +|-- +SET lc_numeric = 'C' +-- +STMT: VariableSetStmt +== 730 +SELECT to_number('-34,338,492', '99G999G999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 731 +SELECT to_number('-34,338,492.654,878', '99G999G999D999G999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 732 +SELECT to_number('<564646.654564>', '999999.999999PR') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 733 +SELECT to_number('0.00001-', '9.999999S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 734 +SELECT to_number('5.01-', 'FM9.999999S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 735 +SELECT to_number('5.01-', 'FM9.999999MI') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 736 +SELECT to_number('5 4 4 4 4 8 . 7 8', '9 9 9 9 9 9 . 9 9') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 737 +SELECT to_number('.01', 'FM9.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 738 +SELECT to_number('.0', '99999999.99999999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 739 +SELECT to_number('0', '99.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 740 +SELECT to_number('.-01', 'S99.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 741 +SELECT to_number('.01-', '99.99S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 742 +SELECT to_number(' . 0 1-', ' 9 9 . 9 9 S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 743 +SELECT to_number('34,50','999,99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 744 +SELECT to_number('123,000','999G') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 745 +SELECT to_number('123456','999G999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 746 +SELECT to_number('$1234.56','L9,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 747 +SELECT to_number('$1234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 748 +SELECT to_number('$1,234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 749 +SELECT to_number('1234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 750 +SELECT to_number('1,234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 751 +SELECT to_number('42nd', '99th') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +== 752 +RESET lc_numeric +-- +STMT: VariableSetStmt +== 753 +|-- +-- Input syntax +|-- + +CREATE TABLE num_input_test (n1 numeric) +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DDL +STMT: CreateStmt +== 754 +-- good inputs +INSERT INTO num_input_test(n1) VALUES (' 123') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 755 +INSERT INTO num_input_test(n1) VALUES (' 3245874 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 756 +INSERT INTO num_input_test(n1) VALUES (' -93853') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 757 +INSERT INTO num_input_test(n1) VALUES ('555.50') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 758 +INSERT INTO num_input_test(n1) VALUES ('-555.50') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 759 +INSERT INTO num_input_test(n1) VALUES ('NaN ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 760 +INSERT INTO num_input_test(n1) VALUES (' nan') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 761 +INSERT INTO num_input_test(n1) VALUES (' inf ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 762 +INSERT INTO num_input_test(n1) VALUES (' +inf ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 763 +INSERT INTO num_input_test(n1) VALUES (' -inf ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 764 +INSERT INTO num_input_test(n1) VALUES (' Infinity ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 765 +INSERT INTO num_input_test(n1) VALUES (' +inFinity ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 766 +INSERT INTO num_input_test(n1) VALUES (' -INFINITY ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 767 +INSERT INTO num_input_test(n1) VALUES ('12_000_000_000') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 768 +INSERT INTO num_input_test(n1) VALUES ('12_000.123_456') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 769 +INSERT INTO num_input_test(n1) VALUES ('23_000_000_000e-1_0') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 770 +INSERT INTO num_input_test(n1) VALUES ('.000_000_000_123e1_0') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 771 +INSERT INTO num_input_test(n1) VALUES ('.000_000_000_123e+1_1') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 772 +INSERT INTO num_input_test(n1) VALUES ('0b10001110111100111100001001010') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 773 +INSERT INTO num_input_test(n1) VALUES (' -0B_1010_1011_0101_0100_1010_1001_1000_1100_1110_1011_0001_1111_0000_1010_1101_0010 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 774 +INSERT INTO num_input_test(n1) VALUES (' +0o112402761777 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 775 +INSERT INTO num_input_test(n1) VALUES ('-0O0012_5524_5230_6334_3167_0261') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 776 +INSERT INTO num_input_test(n1) VALUES ('-0x0000000000000000000000000deadbeef') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 777 +INSERT INTO num_input_test(n1) VALUES (' 0X_30b1_F33a_6DF0_bD4E_64DF_9BdA_7D15 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 778 +-- bad inputs +INSERT INTO num_input_test(n1) VALUES (' ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 779 +INSERT INTO num_input_test(n1) VALUES (' 1234 %') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 780 +INSERT INTO num_input_test(n1) VALUES ('xyz') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 781 +INSERT INTO num_input_test(n1) VALUES ('- 1234') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 782 +INSERT INTO num_input_test(n1) VALUES ('5 . 0') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 783 +INSERT INTO num_input_test(n1) VALUES ('5. 0 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 784 +INSERT INTO num_input_test(n1) VALUES ('') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 785 +INSERT INTO num_input_test(n1) VALUES (' N aN ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 786 +INSERT INTO num_input_test(n1) VALUES ('+NaN') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 787 +INSERT INTO num_input_test(n1) VALUES ('-NaN') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 788 +INSERT INTO num_input_test(n1) VALUES ('+ infinity') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 789 +INSERT INTO num_input_test(n1) VALUES ('_123') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 790 +INSERT INTO num_input_test(n1) VALUES ('123_') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 791 +INSERT INTO num_input_test(n1) VALUES ('12__34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 792 +INSERT INTO num_input_test(n1) VALUES ('123_.456') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 793 +INSERT INTO num_input_test(n1) VALUES ('123._456') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 794 +INSERT INTO num_input_test(n1) VALUES ('1.2e_34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 795 +INSERT INTO num_input_test(n1) VALUES ('1.2e34_') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 796 +INSERT INTO num_input_test(n1) VALUES ('1.2e3__4') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 797 +INSERT INTO num_input_test(n1) VALUES ('0b1112') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 798 +INSERT INTO num_input_test(n1) VALUES ('0c1112') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 799 +INSERT INTO num_input_test(n1) VALUES ('0o12345678') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 800 +INSERT INTO num_input_test(n1) VALUES ('0x1eg') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 801 +INSERT INTO num_input_test(n1) VALUES ('0x12.34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 802 +INSERT INTO num_input_test(n1) VALUES ('0x__1234') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 803 +INSERT INTO num_input_test(n1) VALUES ('0x1234_') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 804 +INSERT INTO num_input_test(n1) VALUES ('0x12__34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 805 +SELECT * FROM num_input_test +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=Select +STMT: SelectStmt +== 806 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34.5', 'numeric') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 807 +SELECT pg_input_is_valid('34xyz', 'numeric') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 808 +SELECT pg_input_is_valid('1e400000', 'numeric') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 809 +SELECT * FROM pg_input_error_info('1e400000', 'numeric') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 810 +SELECT pg_input_is_valid('1234.567', 'numeric(8,4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 811 +SELECT pg_input_is_valid('1234.567', 'numeric(7,4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 812 +SELECT * FROM pg_input_error_info('1234.567', 'numeric(7,4)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 813 +SELECT * FROM pg_input_error_info('0x1234.567', 'numeric') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 814 +|-- +-- Test precision and scale typemods +|-- + +CREATE TABLE num_typemod_test ( + millions numeric(3, -6), + thousands numeric(3, -3), + units numeric(3, 0), + thousandths numeric(3, 3), + millionths numeric(3, 6) +) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DDL +STMT: CreateStmt +== 815 +-- rounding of valid inputs +INSERT INTO num_typemod_test VALUES (123456, 123, 0.123, 0.000123, 0.000000123) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 816 +INSERT INTO num_typemod_test VALUES (654321, 654, 0.654, 0.000654, 0.000000654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 817 +INSERT INTO num_typemod_test VALUES (2345678, 2345, 2.345, 0.002345, 0.000002345) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 818 +INSERT INTO num_typemod_test VALUES (7654321, 7654, 7.654, 0.007654, 0.000007654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 819 +INSERT INTO num_typemod_test VALUES (12345678, 12345, 12.345, 0.012345, 0.000012345) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 820 +INSERT INTO num_typemod_test VALUES (87654321, 87654, 87.654, 0.087654, 0.000087654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 821 +INSERT INTO num_typemod_test VALUES (123456789, 123456, 123.456, 0.123456, 0.000123456) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 822 +INSERT INTO num_typemod_test VALUES (987654321, 987654, 987.654, 0.987654, 0.000987654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 823 +INSERT INTO num_typemod_test VALUES ('NaN', 'NaN', 'NaN', 'NaN', 'NaN') +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 824 +SELECT scale(millions), * FROM num_typemod_test ORDER BY millions +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=Select +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 825 +-- invalid inputs +INSERT INTO num_typemod_test (millions) VALUES ('inf') +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 826 +INSERT INTO num_typemod_test (millions) VALUES (999500000) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 827 +INSERT INTO num_typemod_test (thousands) VALUES (999500) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 828 +INSERT INTO num_typemod_test (units) VALUES (999.5) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 829 +INSERT INTO num_typemod_test (thousandths) VALUES (0.9995) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 830 +INSERT INTO num_typemod_test (millionths) VALUES (0.0009995) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 831 +|-- +-- Test some corner cases for multiplication +|-- + +select 4790999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +== 832 +select 4789999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +== 833 +select 4770999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +== 834 +select 4769999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +== 835 +select trim_scale((0.1 - 2e-16383) * (0.1 - 3e-16383)) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 836 +|-- +-- Test some corner cases for division +|-- + +select 999999999999999999999::numeric/1000000000000000000000 +-- +STMT: SelectStmt +== 837 +select div(999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 838 +select mod(999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +== 839 +select div(-9999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 840 +select mod(-9999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +== 841 +select div(-9999999999999999999999::numeric,1000000000000000000000)*1000000000000000000000 + mod(-9999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +== 842 +select mod (70.0,70) +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +== 843 +select div (70.0,70) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 844 +select 70.0 / 70 +-- +STMT: SelectStmt +== 845 +select 12345678901234567890 % 123 +-- +STMT: SelectStmt +== 846 +select 12345678901234567890 / 123 +-- +STMT: SelectStmt +== 847 +select div(12345678901234567890, 123) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 848 +select div(12345678901234567890, 123) * 123 + 12345678901234567890 % 123 +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +== 849 +|-- +-- Test some corner cases for square root +|-- + +select sqrt(1.000000000000003::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 850 +select sqrt(1.000000000000004::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 851 +select sqrt(96627521408608.56340355805::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 852 +select sqrt(96627521408608.56340355806::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 853 +select sqrt(515549506212297735.073688290367::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 854 +select sqrt(515549506212297735.073688290368::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 855 +select sqrt(8015491789940783531003294973900306::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 856 +select sqrt(8015491789940783531003294973900307::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +== 857 +|-- +-- Test code path for raising to integer powers +|-- + +select 10.0 ^ -2147483648 as rounds_to_zero +-- +STMT: SelectStmt +== 858 +select 10.0 ^ -2147483647 as rounds_to_zero +-- +STMT: SelectStmt +== 859 +select 10.0 ^ 2147483647 as overflows +-- +STMT: SelectStmt +== 860 +select 117743296169.0 ^ 1000000000 as overflows +-- +STMT: SelectStmt +== 861 +-- cases that used to return inaccurate results +select 3.789 ^ 21.0000000000000000 +-- +STMT: SelectStmt +== 862 +select 3.789 ^ 35.0000000000000000 +-- +STMT: SelectStmt +== 863 +select 1.2 ^ 345 +-- +STMT: SelectStmt +== 864 +select 0.12 ^ (-20) +-- +STMT: SelectStmt +== 865 +select 1.000000000123 ^ (-2147483648) +-- +STMT: SelectStmt +== 866 +select coalesce(nullif(0.9999999999 ^ 23300000000000, 0), 0) as rounds_to_zero +-- +STMT: SelectStmt +== 867 +select round(((1 - 1.500012345678e-1000) ^ 1.45e1003) * 1e1000) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +== 868 +-- cases that used to error out +select 0.12 ^ (-25) +-- +STMT: SelectStmt +== 869 +select 0.5678 ^ (-85) +-- +STMT: SelectStmt +== 870 +select coalesce(nullif(0.9999999999 ^ 70000000000000, 0), 0) as underflows +-- +STMT: SelectStmt +== 871 +-- negative base to integer powers +select (-1.0) ^ 2147483646 +-- +STMT: SelectStmt +== 872 +select (-1.0) ^ 2147483647 +-- +STMT: SelectStmt +== 873 +select (-1.0) ^ 2147483648 +-- +STMT: SelectStmt +== 874 +select (-1.0) ^ 1000000000000000 +-- +STMT: SelectStmt +== 875 +select (-1.0) ^ 1000000000000001 +-- +STMT: SelectStmt +== 876 +-- integer powers of 10 +select n, 10.0 ^ n as "10^n", (10.0 ^ n) * (10.0 ^ (-n)) = 1 as ok +from generate_series(-20, 20) n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 877 +|-- +-- Tests for raising to non-integer powers +|-- + +-- special cases +select 0.0 ^ 0.0 +-- +STMT: SelectStmt +== 878 +select (-12.34) ^ 0.0 +-- +STMT: SelectStmt +== 879 +select 12.34 ^ 0.0 +-- +STMT: SelectStmt +== 880 +select 0.0 ^ 12.34 +-- +STMT: SelectStmt +== 881 +-- NaNs +select 'NaN'::numeric ^ 'NaN'::numeric +-- +STMT: SelectStmt +== 882 +select 'NaN'::numeric ^ 0 +-- +STMT: SelectStmt +== 883 +select 'NaN'::numeric ^ 1 +-- +STMT: SelectStmt +== 884 +select 0 ^ 'NaN'::numeric +-- +STMT: SelectStmt +== 885 +select 1 ^ 'NaN'::numeric +-- +STMT: SelectStmt +== 886 +-- invalid inputs +select 0.0 ^ (-12.34) +-- +STMT: SelectStmt +== 887 +select (-12.34) ^ 1.2 +-- +STMT: SelectStmt +== 888 +-- cases that used to generate inaccurate results +select 32.1 ^ 9.8 +-- +STMT: SelectStmt +== 889 +select 32.1 ^ (-9.8) +-- +STMT: SelectStmt +== 890 +select 12.3 ^ 45.6 +-- +STMT: SelectStmt +== 891 +select 12.3 ^ (-45.6) +-- +STMT: SelectStmt +== 892 +-- big test +select 1.234 ^ 5678 +-- +STMT: SelectStmt +== 893 +|-- +-- Tests for EXP() +|-- + +-- special cases +select exp(0.0) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 894 +select exp(1.0) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 895 +select exp(1.0::numeric(71,70)) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 896 +select exp('nan'::numeric) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 897 +select exp('inf'::numeric) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 898 +select exp('-inf'::numeric) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 899 +select coalesce(nullif(exp(-5000::numeric), 0), 0) as rounds_to_zero +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 900 +select coalesce(nullif(exp(-10000::numeric), 0), 0) as underflows +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 901 +-- cases that used to generate inaccurate results +select exp(32.999) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 902 +select exp(-32.999) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 903 +select exp(123.456) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 904 +select exp(-123.456) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 905 +-- big test +select exp(1234.5678) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 906 +|-- +-- Tests for generate_series +|-- +select * from generate_series(0.0::numeric, 4.0::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 907 +select * from generate_series(0.1::numeric, 4.0::numeric, 1.3::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 908 +select * from generate_series(4.0::numeric, -1.5::numeric, -2.2::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 909 +-- Trigger errors +select * from generate_series(-100::numeric, 100::numeric, 0::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 910 +select * from generate_series(-100::numeric, 100::numeric, 'nan'::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 911 +select * from generate_series('nan'::numeric, 100::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 912 +select * from generate_series(0::numeric, 'nan'::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 913 +select * from generate_series('inf'::numeric, 'inf'::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 914 +select * from generate_series(0::numeric, 'inf'::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 915 +select * from generate_series(0::numeric, '42'::numeric, '-inf'::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 916 +-- Checks maximum, output is truncated +select (i / (10::numeric ^ 131071))::numeric(1,0) + from generate_series(6 * (10::numeric ^ 131071), + 9 * (10::numeric ^ 131071), + 10::numeric ^ 131071) as a(i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 917 +-- Check usage with variables +select * from generate_series(1::numeric, 3::numeric) i, generate_series(i,3) j +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 918 +select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,i) j +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 919 +select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,5,i) j +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 920 +|-- +-- Tests for LN() +|-- + +-- Invalid inputs +select ln(-12.34) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 921 +select ln(0.0) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 922 +-- Some random tests +select ln(1.2345678e-28) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 923 +select ln(0.0456789) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 924 +select ln(0.349873948359354029493948309745709580730482050975) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 925 +select ln(0.99949452) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 926 +select ln(1.00049687395) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 927 +select ln(1234.567890123456789) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 928 +select ln(5.80397490724e5) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 929 +select ln(9.342536355e34) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 930 +|-- +-- Tests for LOG() (base 10) +|-- + +-- invalid inputs +select log(-12.34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 931 +select log(0.0) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 932 +-- some random tests +select log(1.234567e-89) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 933 +select log(3.4634998359873254962349856073435545) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 934 +select log(9.999999999999999999) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 935 +select log(10.00000000000000000) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 936 +select log(10.00000000000000001) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 937 +select log(590489.45235237) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 938 +|-- +-- Tests for LOG() (arbitrary base) +|-- + +-- invalid inputs +select log(-12.34, 56.78) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 939 +select log(-12.34, -56.78) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 940 +select log(12.34, -56.78) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 941 +select log(0.0, 12.34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 942 +select log(12.34, 0.0) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 943 +select log(1.0, 12.34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 944 +-- some random tests +select log(1.23e-89, 6.4689e45) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 945 +select log(0.99923, 4.58934e34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 946 +select log(1.000016, 8.452010e18) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 947 +select log(3.1954752e47, 9.4792021e-73) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 948 +|-- +-- Tests for scale() +|-- + +select scale(numeric 'NaN') +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 949 +select scale(numeric 'inf') +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 950 +select scale(NULL::numeric) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 951 +select scale(1.12) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 952 +select scale(0) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 953 +select scale(0.00) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 954 +select scale(1.12345) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 955 +select scale(110123.12475871856128) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 956 +select scale(-1123.12471856128) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 957 +select scale(-13.000000000000000) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +== 958 +|-- +-- Tests for min_scale() +|-- + +select min_scale(numeric 'NaN') is NULL +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 959 +-- should be true +select min_scale(numeric 'inf') is NULL +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 960 +-- should be true +select min_scale(0) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 961 +-- no digits +select min_scale(0.00) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 962 +-- no digits again +select min_scale(1.0) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 963 +-- no scale +select min_scale(1.1) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 964 +-- scale 1 +select min_scale(1.12) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 965 +-- scale 2 +select min_scale(1.123) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 966 +-- scale 3 +select min_scale(1.1234) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 967 +-- scale 4, filled digit +select min_scale(1.12345) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 968 +-- scale 5, 2 NDIGITS +select min_scale(1.1000) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 969 +-- 1 pos in NDIGITS +select min_scale(1e100) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +== 970 +-- very big number + +|-- +-- Tests for trim_scale() +|-- + +select trim_scale(numeric 'NaN') +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 971 +select trim_scale(numeric 'inf') +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 972 +select trim_scale(1.120) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 973 +select trim_scale(0) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 974 +select trim_scale(0.00) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 975 +select trim_scale(1.1234500) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 976 +select trim_scale(110123.12475871856128000) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 977 +select trim_scale(-1123.124718561280000000) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 978 +select trim_scale(-13.00000000000000000000) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 979 +select trim_scale(1e100) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +== 980 +|-- +-- Tests for SUM() +|-- + +-- cases that need carry propagation +SELECT SUM(9999::numeric) FROM generate_series(1, 100000) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 981 +SELECT SUM((-9999)::numeric) FROM generate_series(1, 100000) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 982 +|-- +-- Tests for VARIANCE() +|-- +CREATE TABLE num_variance (a numeric) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: CreateStmt +== 983 +INSERT INTO num_variance VALUES (0) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 984 +INSERT INTO num_variance VALUES (3e-500) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 985 +INSERT INTO num_variance VALUES (-3e-500) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 986 +INSERT INTO num_variance VALUES (4e-500 - 1e-16383) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 987 +INSERT INTO num_variance VALUES (-4e-500 + 1e-16383) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 988 +-- variance is just under 12.5e-1000 and so should round down to 12e-1000 +SELECT trim_scale(variance(a) * 1e1000) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 989 +-- check that parallel execution produces the same result +BEGIN +-- +STMT: TransactionStmt +== 990 +ALTER TABLE num_variance SET (parallel_workers = 4) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: AlterTableStmt +== 991 +SET LOCAL parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 992 +SET LOCAL max_parallel_workers_per_gather = 4 +-- +STMT: VariableSetStmt +== 993 +SELECT trim_scale(variance(a) * 1e1000) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 994 +ROLLBACK +-- +STMT: TransactionStmt +== 995 +-- case where sum of squares would overflow but variance does not +DELETE FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: DeleteStmt +== 996 +INSERT INTO num_variance SELECT 9e131071 + x FROM generate_series(1, 5) x +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 997 +SELECT variance(a) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 998 +-- check that parallel execution produces the same result +BEGIN +-- +STMT: TransactionStmt +== 999 +ALTER TABLE num_variance SET (parallel_workers = 4) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: AlterTableStmt +== 1000 +SET LOCAL parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 1001 +SET LOCAL max_parallel_workers_per_gather = 4 +-- +STMT: VariableSetStmt +== 1002 +SELECT variance(a) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 1003 +ROLLBACK +-- +STMT: TransactionStmt +== 1004 +DROP TABLE num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: DropStmt +== 1005 +|-- +-- Tests for GCD() +|-- +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(-b, a), gcd(-b, -a) +FROM (VALUES (0::numeric, 0::numeric), + (0::numeric, numeric 'NaN'), + (0::numeric, 46375::numeric), + (433125::numeric, 46375::numeric), + (43312.5::numeric, 4637.5::numeric), + (4331.250::numeric, 463.75000::numeric), + ('inf', '0'), + ('inf', '42'), + ('inf', 'inf') + ) AS v(a, b) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +== 1006 +|-- +-- Tests for LCM() +|-- +SELECT a,b, lcm(a, b), lcm(a, -b), lcm(-b, a), lcm(-b, -a) +FROM (VALUES (0::numeric, 0::numeric), + (0::numeric, numeric 'NaN'), + (0::numeric, 13272::numeric), + (13272::numeric, 13272::numeric), + (423282::numeric, 13272::numeric), + (42328.2::numeric, 1327.2::numeric), + (4232.820::numeric, 132.72000::numeric), + ('inf', '0'), + ('inf', '42'), + ('inf', 'inf') + ) AS v(a, b) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 1007 +SELECT lcm(9999 * (10::numeric)^131068 + (10::numeric^131068 - 1), 2) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +== 1008 +-- overflow + +|-- +-- Tests for factorial +|-- +SELECT factorial(4) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +== 1009 +SELECT factorial(15) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +== 1010 +SELECT factorial(100000) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +== 1011 +SELECT factorial(0) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +== 1012 +SELECT factorial(-4) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +== 1013 +|-- +-- Tests for pg_lsn() +|-- +SELECT pg_lsn(23783416::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +== 1014 +SELECT pg_lsn(0::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +== 1015 +SELECT pg_lsn(18446744073709551615::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +== 1016 +SELECT pg_lsn(-1::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +== 1017 +SELECT pg_lsn(18446744073709551616::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +== 1018 +SELECT pg_lsn('NaN'::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/numeric_big.metadata.json b/parser/testdata/summary/postgres_regress/numeric_big.metadata.json new file mode 100644 index 0000000..05e97cf --- /dev/null +++ b/parser/testdata/summary/postgres_regress/numeric_big.metadata.json @@ -0,0 +1,556 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552" + ] +} diff --git a/parser/testdata/summary/postgres_regress/numeric_big.test b/parser/testdata/summary/postgres_regress/numeric_big.test new file mode 100644 index 0000000..1e5f8b3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/numeric_big.test @@ -0,0 +1,4180 @@ +== 001 +-- ****************************** +-- * Test suite for the Postgres NUMERIC data type +-- ****************************** + +-- Must drop tables created by short numeric test. +DROP TABLE num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DDL +STMT: DropStmt +== 002 +DROP TABLE num_exp_add +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: DropStmt +== 003 +DROP TABLE num_exp_sub +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: DropStmt +== 004 +DROP TABLE num_exp_div +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: DropStmt +== 005 +DROP TABLE num_exp_mul +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: DropStmt +== 006 +DROP TABLE num_exp_sqrt +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: DropStmt +== 007 +DROP TABLE num_exp_ln +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: DropStmt +== 008 +DROP TABLE num_exp_log10 +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: DropStmt +== 009 +DROP TABLE num_exp_power_10_ln +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: DropStmt +== 010 +DROP TABLE num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DDL +STMT: DropStmt +== 011 +CREATE TABLE num_data (id int4, val numeric(1000,800)) +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DDL +STMT: CreateStmt +== 012 +CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: CreateStmt +== 013 +CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: CreateStmt +== 014 +CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: CreateStmt +== 015 +CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: CreateStmt +== 016 +CREATE TABLE num_exp_sqrt (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: CreateStmt +== 017 +CREATE TABLE num_exp_ln (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: CreateStmt +== 018 +CREATE TABLE num_exp_log10 (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: CreateStmt +== 019 +CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: CreateStmt +== 020 +CREATE TABLE num_result (id1 int4, id2 int4, result numeric(1000,800)) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DDL +STMT: CreateStmt +== 021 +-- ****************************** +-- * The following EXPECTED results are computed by bc(1) +-- * with a scale of 1000 +-- ****************************** + +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 022 +INSERT INTO num_exp_add VALUES (0,0,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO num_exp_sub VALUES (0,0,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO num_exp_mul VALUES (0,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO num_exp_div VALUES (0,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO num_exp_add VALUES (0,1,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO num_exp_sub VALUES (0,1,'-85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO num_exp_mul VALUES (0,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO num_exp_div VALUES (0,1,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO num_exp_add VALUES (0,2,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO num_exp_sub VALUES (0,2,'994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO num_exp_mul VALUES (0,2,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO num_exp_div VALUES (0,2,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO num_exp_add VALUES (0,3,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO num_exp_sub VALUES (0,3,'60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO num_exp_mul VALUES (0,3,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO num_exp_div VALUES (0,3,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO num_exp_add VALUES (0,4,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO num_exp_sub VALUES (0,4,'-5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO num_exp_mul VALUES (0,4,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO num_exp_div VALUES (0,4,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO num_exp_add VALUES (0,5,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO num_exp_sub VALUES (0,5,'652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO num_exp_mul VALUES (0,5,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO num_exp_div VALUES (0,5,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO num_exp_add VALUES (0,6,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO num_exp_sub VALUES (0,6,'-.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO num_exp_mul VALUES (0,6,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO num_exp_div VALUES (0,6,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO num_exp_add VALUES (0,7,'-818934540071845742') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +INSERT INTO num_exp_sub VALUES (0,7,'818934540071845742') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO num_exp_mul VALUES (0,7,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO num_exp_div VALUES (0,7,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +INSERT INTO num_exp_add VALUES (0,8,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +INSERT INTO num_exp_sub VALUES (0,8,'-8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +INSERT INTO num_exp_mul VALUES (0,8,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +INSERT INTO num_exp_div VALUES (0,8,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +INSERT INTO num_exp_add VALUES (0,9,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +INSERT INTO num_exp_sub VALUES (0,9,'-54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +INSERT INTO num_exp_mul VALUES (0,9,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +INSERT INTO num_exp_div VALUES (0,9,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +INSERT INTO num_exp_add VALUES (1,0,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +INSERT INTO num_exp_sub VALUES (1,0,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +INSERT INTO num_exp_mul VALUES (1,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +INSERT INTO num_exp_div VALUES (1,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 066 +INSERT INTO num_exp_add VALUES (1,1,'170486.79080049955252152479695727201571965474311716541919780029226071455736587237347615553466832461907447637054203186991790701615551214692555785671028648640897898741246882118067609728317430043806625387779037980513762118868084887015059202190301421555269486602797852927777567694581746398790609996101506730430853942556475840126871131898407356048450541232591147357021858041662012293323494543567675306406079659294204054863522259037763051870433216859794083051717080761509518250300466106939998045710070') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +INSERT INTO num_exp_sub VALUES (1,1,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 068 +INSERT INTO num_exp_mul VALUES (1,1,'7266436459.363324713115467666113895787027372854351303425444968800459979742082292257107107767894843498525848597439323325297125474674300428669958003640228730876886174255457103020291514229439701871032118057857763809224712818579091741996335014138185389554630910658876423205103697147288306070059640369158894028731728589073730895396494400175420670713113234800826523252075036892246807434088405522834549449664122407363485486902219500109237667016524913027290777216477989904700729228025571098410870506256758678625928245828210775042611512394316804583459576285681159178280400209217948833631961377519855502763611693070238579591463373484424582723121059964236704135695706864890193388054537703767833595331866551990460050750959493829603581882430597105627056085260296454181999581594565113210481151487049158699087454047624433576922179904629') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +INSERT INTO num_exp_div VALUES (1,1,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +INSERT INTO num_exp_add VALUES (1,2,'-994877526002806872754342148663997.64812998474240514147207095573950146764154822009863493316394610578375247334825932838513167168342610420582834742950389452212867974756590355021495169819086060202117180229196935525386766373096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +INSERT INTO num_exp_sub VALUES (1,2,'994877526002806872754342148834484.43893048429492666626902822775522112238466538551783273345620682034111834572173548391979999630250058057637037929942180153828419189449146140692523818459983958943364062347264545253704196416903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +INSERT INTO num_exp_mul VALUES (1,2,'-84806738323879544552397401815149740513.8505875535743013876823142649666132764556588225959336097903898464616542203793600590311980154402068027051522932586050753865288419084437796768749509032177577451738712965496693249429231838833655025794915864261585848007162358912070811805298210095333433397862313304655108809804359760907473898420016370058274978588765092161529583480924554820756527238472641797198545539410039895140087686344382628317530286295498797849942258314364503000942821309916954725689781458590617068629906894951122301020797266469357701283289275708774593896770378558232444454118891917258610753077932026885574920166837998049508644891327208474213193224700658584824407382455480657734911543930195324144216374573825') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +INSERT INTO num_exp_div VALUES (1,2,'-.000000000000000000000000000085682300757901809257711279577127388124986344391495296640171942990079130291883279872719240502687189411421655284515420074848478500192127657883342858267913417679786356766341637336955924836847768457039175660279784295612167899455618405343686908907695358239088351870495830739180518509859269437015797489301844593920484927630172344269378248455657186218762679357609204333669024237648538465053048724383898528808961206696787294681884412485427843796696788390072124570957047672341581447744981862017791206857428430183366004980966398716823512288330174863890117558744630102020144500158878244146399686532935435591262767487823942606452349972401012308378888947381934278131785907155692007064636085000405504866631011593239041758448995933095907216863744502344014999804306234830774259496097549717476344048') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 074 +INSERT INTO num_exp_add VALUES (1,3,'-60302029489319384367663884408085672236.83687099063256754698860828386302509843815398979402006244388708674093244201278399438376682321121138429850885935540924586964982855913223221441591310211730902799041126800414795030815514254713522692405212716783388698431088814919226444677188004928663343696636297536500970117716818423689175692808344185016908913828066250587407384563498516598672584120143890364303296142744031320345312431817858545326010704685255237541162931904446804064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +INSERT INTO num_exp_sub VALUES (1,3,'60302029489319384367663884408085842723.62767149018508907178556555587874475318127115521321786273614780129829831438626014991843514783028586066905089122532715288580534070605779007112619958852628801540288008918482404759132944298520148080184250697297150817299173701934285646867489426483932830299434150464278537812298564822479785688909850915447762856384542090714278516461905872647123125352735037721325154184406043613668806975385533851732090363979459292404685190942209855935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +INSERT INTO num_exp_mul VALUES (1,3,'-5140349743195574373979577554212527512597024.162480344833040409158673429491690439298506850052285119390701002577176786023622062742050099464897084793357329597395417632908812044304066963549928478520702505283307379218587635434673128958824348493758429380623577527186462464399974242800361134191519694694139153279582776168995426125926314513926640766117733774558011741611075336271613675760116784769700605008122422944290652448956922432960815546502965310676913079866511016221573557684245901002643719965652152439520727383305120298495304784052489867651462175349450610643411043707261107569691076730261762793560088893354750383257372118118753366377402045596735023445172252225346164608897913115394905485106225627590643805003075069931177395059698550161546962768768895596088478488887530518018212441345360153523733317120037436403475909117998647781920105313938836144009539683') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +INSERT INTO num_exp_div VALUES (1,3,'-.000000000000000000000000000000001413607404628860353773457807436398753936801768769045711604884548436548520368932184112069166807060840219636509423284498981041814526856251281381511288768719259120481595036745286884246627534964287523188738499223075292690431699417313258943941279343383979626641848305343592679057491670166887054819766294147341982669243114259272404203080347707713358471397866402657818267495050115642987782080912962056565478445923456884713049272637646637760989004917643369240372476411912794578381690666695711891846833983534126217706309741885844723208036219144146342212915129560758201609824034610223907791643110990898577049488934294259106725414517181607988173722432655731491050637087261030314548853334338835938120502930424813699221083197863303458179445322810087784892821862085562891180364134284641396475') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +INSERT INTO num_exp_add VALUES (1,4,'5329378275943663322300488.64471790965256505869684245785528331091076155554650629138833809683459634328609777839510066435612911583108717191216693735823717997111970662575497378762952496582183738308720094529950793570383580785385569873278068217936841324404119828637880370718028782103860007754579779716996004352284614661690063919125301052941328989181561787543541920734755989452320799185700078241880935083616978140555713297241612718277766918005268951861880490889884082730841740604517529391011862694381726143520658746305661338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO num_exp_sub VALUES (1,4,'-5329378275943663322130001.85391741010004353389988518583956365616764439012730849109607738227723047091262162286043233973705463946054514004224903034208166782419414876904468730122054597840936856190652484801633363526576955397606531892764306099068756437389060626447578949162759295501062154826802212022414257953494004665588557188694447110384853149054690655645134564686305448219729651828678220200218922790293483596988037990835533058983562863141746692824117439019450865871047657552800448629502344444081260036580660700595591338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO num_exp_mul VALUES (1,4,'454294299613767152878025320780.534199313974295807138790763501115780294529340799108297697573066187975311338382917022391830256203305238757334106943821060545424417350991354829668286194840925251162479496893943917530660694097932059166013476064988623431110002057735318529554555260199417935495388243829261809007709919225000608711536928171687251088217591210419208480251102484043683131687013687838713055660405381318396419588727500715930145098362997142075433472039319292466570912777345841400769387321465602989947078951135489852486382469990409873227894248208197179481868230244584527040573428134962626267135732247029762468417273891700661832893497067151409134724061246612631376075173287264787886064622106855886785805818642123776489793586531950438285720668411465570116161790343538663297713926678759640594912243360541590368666922379919514826022141331900181') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +INSERT INTO num_exp_div VALUES (1,4,'.000000000000000000015994998100440878014888861029956505927201309704413242103407885948184870841766875212766910686894450511886242468216220470061916924303252919423028993720180330014505454865704155281502763018913215741264982350384245753394656021401865680441649920273268554396350483440173848850052788410943178207336328451359951614056237100465802151856198860908371340425459435127133071447273887829397881221098443685586506647314622864702873235212396755866459409263439958011711379929751157260020133239574261188528305921244365838405372320186907437842180388704854605498842516581811515413843298370501194935797268161171428747542997504369133579105180311662221854071962295818264211400101689450830279979372422749150894553349570063000769685274875561760334738424509532610467832951796852051505383374693614022043010735004494395190') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +INSERT INTO num_exp_add VALUES (1,5,'-652670387.03916046850422757312745971450663862747133703839829692066597367760104802542475264601221776157515632293978442027199108085723617181683235487266149426304575903892721468296143475297345699313102262188759506518376019936160961709578829069446312051432780603656651983414612264636232727512091101057374054475214114364113300402823059519499217878746766275164739724770556122895799337810694888119810524986616938847385753562624139431982468828696587199570410008890188532132652095915565323400735066310142303225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +INSERT INTO num_exp_sub VALUES (1,5,'652840873.82996096805674909792441698652235828221445420381749472095823439215841389779822880154688608619423079931032645214190898787339168396375791272937178074945473802633968350414211085025663129356908887576538544498889782055029046596593888271636613472988050090259449836342389832330814473910881711053475561205644968306669776242949930651397625234795216816397330872127577980937461350104018382663378200293023018506679957617487661691020231880567020416430204091941905612894161614165865789507675064355852373225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 084 +INSERT INTO num_exp_mul VALUES (1,5,'-55643106304872.575994253221940844841058071061962511162776681458310912066379595519265546225338405882027547140476045378015935579066580347282075024392379464189067155567624835346798806677988850250198082355055954078446421075165109896091047534711081616362392995575466807084807876544560268050611445006601394735810211678919646667455478469014906335433468365011768049600750224822391684377238242162320161552720449713229523135506671063115436813348612986916614320012995541575293478341408982118538094438068036422562665160411591652618670802973618768526197813319204816293073794413317669922144705633308090832805914096147659820167569140291210526520361556881576175809360614782817717579318298657744021133210954279487777567785280633309576696708168342539425395482429923273623865667723482418178781573723597156804085501875735112311466228778929147929') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 085 +INSERT INTO num_exp_div VALUES (1,5,'-.000130590057635351941758745900947472461593749814351229292370661147301124533787181489468804246182606762727711479707901680546780430454163647774077629503207962424213266902732555945190365467801995495570282501722505521485829885605904543846887348545254658726343578684749830307120625129857380290225370772763609458975555029415082569247186899112975387051141777417911244576134390940441209829852154391377911942082738699481875795620569383196133124499983396562167632007454221121465745085962247988140942672429187053671899537331280701003778040796615094903602095098880716919238394057384949891444700347825726273725378453454782330181608182747900774711384845635284701538541452235224216112380245660177463043471814071809869894647262285332580556739424040615194137651616350340752691170045698234853734471923738591898290468792787543896') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 086 +INSERT INTO num_exp_add VALUES (1,6,'85243.44233732197133191329295927531563604777955507322414928382967007765263923984471408038635831036097817458527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +INSERT INTO num_exp_sub VALUES (1,6,'85243.34846317758118961150399799670008360696356209219504851646259063690472663252876207514831001425809630178527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +INSERT INTO num_exp_mul VALUES (1,6,'4001.075404054519813215296429095020391062109905613738157927030437221793757373268325953178030040276107574363822832168160758728653712686313134828282109532831190239521843808940611025488601517574653932032236616573457735900045655665690517797280666732780030171712864961531623060353548802466577910774711998056232872212688464691036260746751992072745518373073825852119460094113694393273456369345499434994672730920070410547163082189385645712866100999708173472360864669110044660667614583576570496399103026286828660558854973376227247132815728164629722965145778698957093136175449225024685874279280018547740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +INSERT INTO num_exp_div VALUES (1,6,'1816120.848909727306817960620941575637231136442992819290405125420545200026620306446043740992108329883383706060582482495616151605111275635501481354526017831484915013545483361715432312183101964395505340188909970344423950565285639911521082834494088840596716495422427543520536844348040681236845850482165744696068209384509064196671206362539077218412355776790921130042376467606683622970728503408501481791356294886150690067651815776445750760428874351556866105285911902433352126498951242195408782804314174041618879250740246352525074791310920062276490422853700893340860452528740673590486626464460321410814395342850270921486724297414692313177440726749004398703147904603937755702369682956482832074779404350351752662820773690162594400557957241676636030332988289683112176900913522668426137377289536793838959751008646843014106876005') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +INSERT INTO num_exp_add VALUES (1,7,'-818934540071760498.60459975022373923760152136399214017262844141729040109985386964272131706381326192223266583769046276181472898406504104649192224392653722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 091 +INSERT INTO num_exp_sub VALUES (1,7,'818934540071930985.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +INSERT INTO num_exp_mul VALUES (1,7,'-69808760806266041400340.70700818693892852138813934414383886494691670042143650609934777814995087699409404201920249076407981012095999320858479644760715204999741683528746097757549835956359129287002171391961763797857794730120426599135099619822532290339000466211195776337667123320942107370731349851576864242697412616810236323676004067839744992733887503405311090677026008324895177587064547630828026123718296429295638934384446325302964896473296829265805737112709269803814942537657996725913938408781715328945194948010970') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +INSERT INTO num_exp_div VALUES (1,7,'-.000000000000104090609479936344103210175655521317012597986331111866307697262848964666360492361638117930801818899121383806224630563676018240181412174154250663423230239912527388431901852952893943812666142740182651125508583527237123596541789628675379232473721293630968882045044077795828674268595016625198802475186587918019739056755398151182369187670251750080227679555002307777300392769289647975058449905106584837938556260801229545589323224752038795423164214112897202147313792076165011373139219134850954217300915326944185918762838321705825423789073869940092569940135329697980600082436317664012683589681419530904283106912171330819469065141821685734295058255484933744156717782754922568796985634397878149984177882018261742637463462647452140104146195353696596211873925359508622779658904411330975862442989437933211964821') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +INSERT INTO num_exp_add VALUES (1,8,'8497071467.03603749330791582407836434318377133169438097066269854720538319012928851657498035372443556191720308219530866834905045144302106406146277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +INSERT INTO num_exp_sub VALUES (1,8,'-8496900980.24523699375539429928140707116805167695126380524350074691312247557192264420150419818976723729812860582476663647913254442686555191453722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +INSERT INTO num_exp_mul VALUES (1,8,'724311956372274.0135050255361637906710330203036651743488213007179039756514944640108625580172737414192938789413338554327986697518463087452612658955180411327002900979574347739956600177846996063741787205122007268468674386396156638261992679442768654367111433834151087792255469957061758837789341439211010331332174981459471333376067541234901538285101103690622656631026001337239036711179989456674399137008584021283568040818388709554256523118702728176420022080138548890713013682480239784198421500241995499841675772793497485550923152267616622892846304530712344886979674416990935007952941652591352603797627920865960622077762568060903908151958000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +INSERT INTO num_exp_div VALUES (1,8,'.000010032191786198542900505683562217892317481076466949299850809276743457759270150820565375820388277409258249926696079166209409657808406245382887790534127749833677458375931047385994887406206232330491317602830654688957983804698568410728278089250379255157030886262396950539100566975000094268415749476738358914633948867977798590927055566888255636132486899287919515638902721543629183577900872078173883974905921239149419877613723476347774771230668479296621531969573505480695490386225866950545725121902534610730154727385072738079149623798073810167706094070842646222833137345669922898403368997676634709281456818189049718956207208697021706186341405575300648248555331280690778367620868775005181264547924615247991795542738868003191757946979714250339430363902549866892041102771965653407197094250270379367437342632741280710') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +INSERT INTO num_exp_add VALUES (1,9,'54948723.74225051983134098996071145685528795757427462111901537365053896571438476055974853245403475510333627298551845046116291696445177112567064282766115207407461565363967417615506303416694032848457927390574251904212425813072768882213388082765916956736282110801611726537663292922699021333445658549608928179155685881583228490235606377831724593358583903616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +INSERT INTO num_exp_sub VALUES (1,9,'-54778236.95145002027881946516375418483956830283115745569981757335827825115701888818627237691936643048426179661497641859124500994829625897874508497095086558766563666622720535497438693688376602804651302002795213923698663694204683995198328880575615535181012624198813873609885725228117274934655048553507421448724831939026752650108735245933317237310133362383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 100 +INSERT INTO num_exp_mul VALUES (1,9,'4676749348240.390309875431213992853550297086049749814750492488995108783145961719774217441193547534210468967573344456866203963659951312519988497979489304488948342258375915152429008993288817366720647491166024151209542534474867042837694499222928509320280684557676243780452100132238968233413333851595648146954975713386711764268506890884764704949969602122157394714663532141060559896359465918874990769222345665160127552795532197771168442486088776803398878354288847069602460071745966589164282641033852314335279121191855487126430176047553895892632834940595958394834437871886013513058514896870683979585091413977173250824451205330441299000850618134248917380244749589254309567551846327349592529960432446947239714236828401206843011440433362544797025114476612133622499094287321570559088587999417440664282418005102546343020409520421747216') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +INSERT INTO num_exp_div VALUES (1,9,'.001553736563217204408368240901181555234014339476186598647410198373122572205209277343865051610898136462487966496673511261433286284257044548634547569923035899634327495195510767312478861719221916387940027268721306540663743713345337497285507595251328382906111997524508729275471287648008479480805967901972481289402930660848950039779707354469389216931774094174326513465502460315792834278614886136688161679443873815113442220055827192996984074129528034845339130162104547166079591654852164993577408422015514100323825529286511720963047269483211930770803479398243069649400360625259869765138545866815758888670363356947311319523139395191102286838888146829667276592755438606664644975648828848738708349790766370694194763606850690923803984129157519048493985198591771429264967247245289970213262206709011468289046840862597010969') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 102 +INSERT INTO num_exp_add VALUES (2,0,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +INSERT INTO num_exp_sub VALUES (2,0,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +INSERT INTO num_exp_mul VALUES (2,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +INSERT INTO num_exp_div VALUES (2,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 106 +INSERT INTO num_exp_add VALUES (2,1,'-994877526002806872754342148663997.64812998474240514147207095573950146764154822009863493316394610578375247334825932838513167168342610420582834742950389452212867974756590355021495169819086060202117180229196935525386766373096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +INSERT INTO num_exp_sub VALUES (2,1,'-994877526002806872754342148834484.43893048429492666626902822775522112238466538551783273345620682034111834572173548391979999630250058057637037929942180153828419189449146140692523818459983958943364062347264545253704196416903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +INSERT INTO num_exp_mul VALUES (2,1,'-84806738323879544552397401815149740513.8505875535743013876823142649666132764556588225959336097903898464616542203793600590311980154402068027051522932586050753865288419084437796768749509032177577451738712965496693249429231838833655025794915864261585848007162358912070811805298210095333433397862313304655108809804359760907473898420016370058274978588765092161529583480924554820756527238472641797198545539410039895140087686344382628317530286295498797849942258314364503000942821309916954725689781458590617068629906894951122301020797266469357701283289275708774593896770378558232444454118891917258610753077932026885574920166837998049508644891327208474213193224700658584824407382455480657734911543930195324144216374573825') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +INSERT INTO num_exp_div VALUES (2,1,'-11671021799770914903865020509.301561107153561058074179843542446420696517132461554451075945807420674211966679216615407057626541711186781735967334896541890595771915856783008831770988426637435694856170266346306640678577376310547806764332837625966429200996250687908930748245035578756314083608655163891041399241377675534416837659335561005203219889972336214863417948542956735403991871098341470996860469878038840964359144637726669728240650066795729910649523281308716277906908340457162235831526838308777581569974551673352306004330423694524256415657620427590352277556907586751621496248973165690360552007637570957980230685679819820147036159174977086193494572117089582758015847544798464543446227632367713941117001423437766840744488426025388612316819120660814681298624293065972395923651314350558006567251033289878238407790871784676348196394482477767774') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +INSERT INTO num_exp_add VALUES (2,2,'-1989755052005613745508684297498482.08706046903733180774109918349472259002621360561646766662015292612487081906999481230493166798592668478219872672892569606041287164205736495714018988279070019145481242576461480779090962790') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +INSERT INTO num_exp_sub VALUES (2,2,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +INSERT INTO num_exp_mul VALUES (2,2,'989781291745465665243281323944996915810556285052564220274237162526.1617859904902612197894543199389468971679632139059029459520163585971122643624316475417489000981872666677202334180945949860058384424993911721081868337499377890298636260338063268639283065887210924895929155083478140340889209440025415565915964293989840603863813531303253038823629712989041722072693449251635519992922148998556112923060331794396659338057474019846675262291146025') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 113 +INSERT INTO num_exp_div VALUES (2,2,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 114 +INSERT INTO num_exp_add VALUES (2,3,'-60303024366845387174536638750234506721.2758014749274942132576365116182462208228193753118527959000939070820507877345194783035668195137119648748792386548310474079340204536236936213411512867171486174240518914767934028451971067161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +INSERT INTO num_exp_sub VALUES (2,3,'60301034611793381560791130065937008239.1887410058901624055165373281235236307966057696953851292799409809571799686645246659986351515277852800926805119259053513475211488115663286642009614039264484259692394657121785950542874788161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +INSERT INTO num_exp_mul VALUES (2,3,'59993133911282372667149627097418449223835595194300848703012380022306762.154418449236691515146061305380465061074531890529497774836941002526095632166401249277270674802626154774328055399254982998368191676630276960361274433270795772477146870294928855773172789856196219950097157391050424577381777627004101100872747943673762087675405200265837631665464736842180920496158545887039337399558993437594084473932658319914390365451919627956823980800124880375978662052111797881386060353490432427832058851094210488804887183034572364751639107535041308434932952695103493677600969712634416241541391613699710826602011076372592299807609658979777598672141389319098817824624950794758296679318319299142035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +INSERT INTO num_exp_div VALUES (2,3,'.000016498242835741013709859217005931279826178662180173096568520102488480129191427472581644597420895622947234184547373944996197105916093347103336318249582032230903680989710242610024298937774441533502282949127537125997753002819456724709929935850697744632904111143787011103837624936502324835260843148595669524694347566421203164808527739207590986975750648112133699756328511947175496694080071202064255118777680958612315513441989609682655431197367166056616661045712867189326408877133865572680407329449150282415810958772293869902662884761202424695742898573841869524376684740249281181605067345203479719345061595919652192297531638467223956758315591610733251562492794891852151639643060692698365496208796638230566761231611376199140556503620471090364900792180618741355091923808605890415081571900697282725022629812561702118') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +INSERT INTO num_exp_add VALUES (2,4,'-994877520673428596810678826533995.79421257464236160757218576989993781147390382997132644206786872350652200243563770552469933194637146474528320738725486418004701192337175478117026439697031462361180324038544450723753402846519731908503949116978812841497201119103409772457270340059605961197538918709309004130294868847110690336360689446090125918336908930881873778405661757289469281163974774492810850778950071063044769131228124355961427111369335109426492177657001035045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +INSERT INTO num_exp_sub VALUES (2,4,'-994877531332185148698005470964486.29284789439497020016891341359478477855230977564514122455228420261834881663435710678023233603955522003691551934167083188036585971868561017596992548582038556784300918537917030055337559943480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 120 +INSERT INTO num_exp_mul VALUES (2,4,'-5302078674303935968062773235453828254014583744527466365136.236414807326868572353809920518232561005161225922028750078608989965741402418802255050636954800114792425419735155504035469350521800895164087027043476055514245942961100610551646034472084954313670284875310691807937254054948742125729353864014122131419164449567115006621212424805182687707372956385102095255735458593389920872596796806885847543910224476727171570873698525606016990229936284811067826588349092841322512643043008589065847223683467371925773023109720951609815041012521485326120380123169545818055967455575736140138663815073081494226676896278654189873597341203197903408668523514375373841493189836809506003729379742035629498519683885268256481104619815130659628225053833297766479068686119691010593208135616363994230674606991733148502293102108193522604968743948323130517040609601859735899914987426089053869350663') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +INSERT INTO num_exp_div VALUES (2,4,'-186677971.517539861245390308778107722315862721823627804195528485535806132067679059453022306691281662574091826898288146790399178357754908901382135796783067563944022498807930452234032896817601590728156392188660701355670595952594500812333935362955625137944589981298793332621503315902294100258945995827423279442031218510259915311555745581797315793010762585658196457363672908315687720174516274528662385172326028870945153551774300419158584379602045442200523311437013776079979639415633358878239012925000523542907592866797199229858272764668664323316251874027468128770456766875866492004650352654523634716923150212263912760225390093339729495231675627059805624175587380165509763048913150826017167286786277908970769297060278191518730887417202276531151575412404467497036737825989088867451153485938272367300939127313445244028528055624') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +INSERT INTO num_exp_add VALUES (2,5,'-994877526002806872754342801504871.47809095279915423939648794226185974985600242391612965412218049794216637114648812993201775787765690351615479957141288239552036371132381627958673244764559862836085530643408020551049895730005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +INSERT INTO num_exp_sub VALUES (2,5,'-994877526002806872754341495993610.60896951623817756834461124123286284017021118170033801249797242818270444792350668237291391010826978126604392715751281366489250793073354867755345743514510156309395711933053460228041067059994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 124 +INSERT INTO num_exp_mul VALUES (2,5,'649411906691138274293985410502516861224852.2323455192714410716272307781034189160865613770320102043319541634113746032638191509585045862973333645830298922352816245477556264222094036953195419857712804755170632292914187367964994214922001758104594052499795564860466055599417895782179851297585155129541589802249540436678824225950907268084876110445460948679383611117263673106597132046331719468816839434908155684738864149955129235751738204036443603521478609787295079710078973503970964790273461142497259987849074597264522099648376356902360358310245001183020992360260836105404118742418040965190000718736837422434593694808973939805954329718232693154128543253581495885789333274488461716809104532693754070810202831113003978085636579574171344721710232931261731022478029314435363413498991740750878099825781577297965642009156858479681236085226911858782115') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +INSERT INTO num_exp_div VALUES (2,5,'1524119409495532727030986.638577103454261465522025182901477334004986357902177024959076085490119358611626688213654669281670407680244740174673394111775678935383154847014211641601227316639834450258566053805263858706381900273201146454036688771735398324537667996974210741719621449948660517037619359095556637235980122706739013220201060795557114248610410815988952748489854367480813823114296393315170621979351958306734282429929421779129764262568942699813166237466796852578307944635545174715298176546980314973426586923195248536376403319094417073026382024413817222396402299695717290716014320518777088811749776114378145110676170242861393274018655137797545194817703831240390631723050378397773341835222892981773205967439339460305257986693600088957772328044922955990976285151896366292514128607363007421484320868718566256882080399264346243272770200676') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 126 +INSERT INTO num_exp_add VALUES (2,6,'-994877526002806872754342148749240.99659316232359475297606895243958507460511031229368344962653674268847910587702140353344168594152240599109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +INSERT INTO num_exp_sub VALUES (2,6,'-994877526002806872754342148749241.09046730671373705476503023105513751542110329332278421699361618343639171319297340877148998204440427879109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 128 +INSERT INTO num_exp_mul VALUES (2,6,'-46696638263247522384986521136500.479312417066793299922708112595886608370451213741279484136907754744903470430131032928908162742687359367826808123516519335458861613010646992354378739165872253762686683966945711430182491860196341344982195078000259063231136011430995647812149294224699587849791008794261026932467933475782780') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +INSERT INTO num_exp_div VALUES (2,6,'-21195986018643887410662481595901800.342199657994285865579781485758715114242459388977583220756870314514884887803267837816669111279417861218648323488364513921592045485003563036021370174294475403630933854767386355037781881144701319212711655881277140183173924089814927297045029394618083349813549439341772734606115369911736164723942330187830605893993276674913563980890459604886172701331890746621222114280438198802989678877404376001410627722336243835841751052795437979198996482216031399073597399901975686733315751292369326904428230195579137225651689857057115970784985439417129044974524632220457594191305254649113470116960582543784928547885740020507755033347968928034294570497118410435615856155184563329718831512839630769097935523279881940380220955993456451396417879773380305142918906742431812580562496634831735169817705720949712410595406012323294829461') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 130 +INSERT INTO num_exp_add VALUES (2,7,'-994877526002807691688882220594983.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 131 +INSERT INTO num_exp_sub VALUES (2,7,'-994877526002806053819802076903499.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 132 +INSERT INTO num_exp_mul VALUES (2,7,'814739569184924399102711674444306584731316176345067.39834031417849342571224916231092924046722938910652929295271097903377854123984307101079073134405782275535446337229706620713104545454319555885847481531722101704765783025789147453570970090') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +INSERT INTO num_exp_div VALUES (2,7,'1214843772391778.127361407585140553741220126410637250571020684739034685508176000812180032686291124045768750332493129822580347351032145964983629059968936201592138368806173099130176852606440296388856520582890650384142745607345709716826703676313341953999327129144154152914234659001555055379537780751567782847296067128932113870102563522810980359433259696591977617184951677390423898232135100000764121508662830515405980450892222598485287609657612482190264517684867291774820716746063133066053446257163185646067618679478975882247893469409405379034723543061767846895135644429012095930584952053545016706315299076691015196261253199176743281648949731423486208098120903720124071047872917636988241710583721537777321338769039241700203546247947405745989053846970910400831817998342969657501678430211657755864160072525313889413731419647001970593') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 134 +INSERT INTO num_exp_add VALUES (2,8,'-994877526002806872754333651763017.40289299098701084219066388457144979069028441485513418625082363021182982914675513019536443438529749838106171095037135009526312783302868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 135 +INSERT INTO num_exp_sub VALUES (2,8,'-994877526002806872754350645735464.68416747805032096555043529892327279933592919076133348036932929591304098992323968210956723360062918640113701577855434596514974380902868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +INSERT INTO num_exp_mul VALUES (2,8,'-8453460632655529853033389979024265783461224.3195241893307807116624750282852146303290708492834695194274289713076935297734670940696121761483641291930931061232942894577813178566088927221374036301485916497770984757492912292002695944367308880163698595015497307574177176409203214324418237020500352652934909632442547242092296504047310806151851207329042221920888326000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +INSERT INTO num_exp_div VALUES (2,8,'-117085929036205907700251.219065234073336548829793284434494573185718678644093751558890746941383215425734761534822966779511801033216479269605150574332107020180872343673157350081102818832254463561564431056604957702984438484261858890324442581609284935850435611342611117035589511568432559140282381526487115307554496353616929034919886387903446436924514812698404129456069856633480965357915969548215985452939172313964007318881987188665231550330515412104367728617802960792164260429920719961650164518261501571220901151359208484337831586551714193024143212288426326740373893030225940355268499071669300664200888186064836443459131985786957267268845966279576380786883200277187591448294590370986026461176853573555996139940001165172158855197070946665074838360933025833716166930231164328918316437195201546383664484983447934244744303265471044295601062898') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +INSERT INTO num_exp_add VALUES (2,9,'-994877526002806872754342093885760.69667996446358567630831677089993316481039076439881735980566785462673358516198695146576524119916430759085192883825888457383242076882081857926408611052522393579396644731758241837010163568445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +INSERT INTO num_exp_sub VALUES (2,9,'-994877526002806872754342203612721.39038050457374613143278241259478942521582284121765030681448507149813723390800786083916642678676237719134679789066681148658045087323654637787610377226547625566084597844703238942080799221554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 140 +INSERT INTO num_exp_mul VALUES (2,9,'-54582443595378013373024060492546032003692.4875677735896411267274323339692558458420972958075073392126734000341372096298914875892612108329218081214550050039133117695428196702128258481789017059073444323729583900855712795086447886053552786449313809589992185978097430132940882612817775035217244553616977182049775786664446683332098226841743818600819221587510039430478859412452506872131851471967577741190323481953867845129745440745526578327709351120432530702446916035797432129052518980799424635406993848916727957825620638983706180841278402925286540375225365057191075559133035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +INSERT INTO num_exp_div VALUES (2,9,'-18133693300409132895168796.074616314168631402221003009151140409826855230810646429042722071403306917323628118792142878282108022292754325022530103525285999179488507720688317761243448898240836430183645778132937666952111134601563043980164547020295727057908447220163534134835130866457657964382363853570827467081988390359191484798677813656413640874450449802233520570178139244957518604566383671867773821069602665918688868868894979351219381089954104823746091972754649316823714354000113723793845707472924569647945844436702275724514171940901057842455729977729388911537391920702753167125695758365521631000334183494148229356487592577177344247694925635113222720411958290166668659311154664393442690740373285505786584987609789805525300762074682544164213490532272590665630428583216403362629445153016404037983825555019274338559686335405719430737559715778') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +INSERT INTO num_exp_add VALUES (3,0,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +INSERT INTO num_exp_sub VALUES (3,0,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +INSERT INTO num_exp_mul VALUES (3,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 145 +INSERT INTO num_exp_div VALUES (3,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +INSERT INTO num_exp_add VALUES (3,1,'-60302029489319384367663884408085672236.83687099063256754698860828386302509843815398979402006244388708674093244201278399438376682321121138429850885935540924586964982855913223221441591310211730902799041126800414795030815514254713522692405212716783388698431088814919226444677188004928663343696636297536500970117716818423689175692808344185016908913828066250587407384563498516598672584120143890364303296142744031320345312431817858545326010704685255237541162931904446804064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +INSERT INTO num_exp_sub VALUES (3,1,'-60302029489319384367663884408085842723.62767149018508907178556555587874475318127115521321786273614780129829831438626014991843514783028586066905089122532715288580534070605779007112619958852628801540288008918482404759132944298520148080184250697297150817299173701934285646867489426483932830299434150464278537812298564822479785688909850915447762856384542090714278516461905872647123125352735037721325154184406043613668806975385533851732090363979459292404685190942209855935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +INSERT INTO num_exp_mul VALUES (3,1,'-5140349743195574373979577554212527512597024.162480344833040409158673429491690439298506850052285119390701002577176786023622062742050099464897084793357329597395417632908812044304066963549928478520702505283307379218587635434673128958824348493758429380623577527186462464399974242800361134191519694694139153279582776168995426125926314513926640766117733774558011741611075336271613675760116784769700605008122422944290652448956922432960815546502965310676913079866511016221573557684245901002643719965652152439520727383305120298495304784052489867651462175349450610643411043707261107569691076730261762793560088893354750383257372118118753366377402045596735023445172252225346164608897913115394905485106225627590643805003075069931177395059698550161546962768768895596088478488887530518018212441345360153523733317120037436403475909117998647781920105313938836144009539683') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 149 +INSERT INTO num_exp_div VALUES (3,1,'-707409990019504668223608170643582.082425157530076679823177950190511141917761066423266390864536360056345386873500583953954967225431526056199231768143978526582904071798714789552447782850723926323452633811653766838064983821149041415149067433978085927687765773012158659685363079191901396502099956189371719135315616249471739677995520904113581848295732911534266040260836644379296158092198514963023001686666281725991605685524015227112003429486755206848316731257322742428352116058878710728614841247581716185886403744830796740424927494009978599974431617064012221450054532987372285996679180090592706458366967534834069977644215413076082570497451654516268857039718730203921980307096740864747006176117071983875364434497517026142488015705391255750729200497229031250705777282987863242056223584453312226818451807347197583925624299372040413470456696588043062815') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +INSERT INTO num_exp_add VALUES (3,2,'-60303024366845387174536638750234506721.2758014749274942132576365116182462208228193753118527959000939070820507877345194783035668195137119648748792386548310474079340204536236936213411512867171486174240518914767934028451971067161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +INSERT INTO num_exp_sub VALUES (3,2,'-60301034611793381560791130065937008239.1887410058901624055165373281235236307966057696953851292799409809571799686645246659986351515277852800926805119259053513475211488115663286642009614039264484259692394657121785950542874788161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +INSERT INTO num_exp_mul VALUES (3,2,'59993133911282372667149627097418449223835595194300848703012380022306762.154418449236691515146061305380465061074531890529497774836941002526095632166401249277270674802626154774328055399254982998368191676630276960361274433270795772477146870294928855773172789856196219950097157391050424577381777627004101100872747943673762087675405200265837631665464736842180920496158545887039337399558993437594084473932658319914390365451919627956823980800124880375978662052111797881386060353490432427832058851094210488804887183034572364751639107535041308434932952695103493677600969712634416241541391613699710826602011076372592299807609658979777598672141389319098817824624950794758296679318319299142035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 153 +INSERT INTO num_exp_div VALUES (3,2,'60612.515523995516156897729403721504966784736064970538891936016753206905080265887046037910122269129293912171105589512464185386239562077778499936203155976336284324712221812806801062157592930664021782540155687632208890794166119782594464410498356083266087045927038416810562596141871858142749062925965665039981381277808608946877852933015970874447235220989360704166270479475802673572039541121473138382812420076284458769543418652217394352637294823914346726065145538710933281768776286965107974980550163605068693568717671571780028113969794125200592691656568731359981803586296135840575095063824258761205175762907549288801963550628589530419118771779395037240198270853609924445368393952404606326559485235840170339343865253618184271158932135392539396160392488927771488269959497352568205940636180870805982484030168838833607478593') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +INSERT INTO num_exp_add VALUES (3,3,'-120604058978638768735327768816171514960.4645424808176566187741738397417698516194251450072379251800348880392307563990441443022019710414972449675597505807363987554551692651900222855421126906435970433932913571889719978994845855323367077258946341408053951573026251685351209154467743141259617399607044800077950793001538324616896138171819510046467177021260834130168590102540438924579570947287892808562845032715007493401411940720339239705810106866471452994584812284665666') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +INSERT INTO num_exp_sub VALUES (3,3,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +INSERT INTO num_exp_mul VALUES (3,3,'3636334760530744652235488357607657374520053530993537920755375319352615385278.023608692512217812784472508939511216316773023870624171279878340621219698109986095090336065266376220109007718694455520948311677863167090936408887147442375455695868593092154861636486745490748828207939155392396090682312136290864359484540126174821846208064763823279315343506148025281475729723686566174395516982893064510403581479746673749128344955124070957545815390178764940816628194640888255387443237798761377617383817511745005525149990207764725040109364671749403389999498572538135588695345112358160274671918953118753964073105250116426665508214894805722798842017943220605600452911496071424281587802689830031742105619630787641205011894680546049982654601956546154572720177337696285354350903475239411654436042931409507429892682706228354459580412759920815932840348933425754970917910500027837428631661182510071352138858') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 157 +INSERT INTO num_exp_div VALUES (3,3,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 158 +INSERT INTO num_exp_add VALUES (3,4,'-60302029489314054989387940744763542234.98295358053252401308872309802346144227050959966671157134780970446370197110016237152333448347415674483796371931316021552756816073493808344537122580089676304958104270609762310229182150728136567294798680824019082599362332377530165818229609055765904048195574142709698758095302560470195171027219786996322461803443213101532716728918363951912367135900414238535625075942525108530051828834829820554490477645701692374399416239080329365045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +INSERT INTO num_exp_sub VALUES (3,4,'-60302029489324713745939828071407972725.48158890028513260568545074171830840934891554534052635383222518357552878529888177277886748756734050012959603126757618322788700853025193884017088688974683399381224865109134889560766307825097103477790782590061456916367930139323346273315068375646692125800496305291080749834712822775973790354498408104142209966769395239768969172107040437333428573572464689550003374384624966403962290572373571842567623422963022155546431883766327294954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +INSERT INTO num_exp_mul VALUES (3,4,'-321372325955692885069615337209737469749246561535004445508427591.072860243358366933071485495726715620133686420023451450292996945184959542770492705998350644739298629407567812798540119555932604687814429669592481327761428042980782672136901602006622227365754036664912989085940235439697789102358431343119457114603363936544931303133371137532006899162833369543279729021228901466728220729625107362063321334489394782322741444425117731922691457341543446841167138481424319752111748042440994701571955325673470021626946676976482516292402239416632497972073915818846704053624707839813514171497746804751780741682011937606462260710753056669269928580460921188286249923152921382198282201761171043384698319895970192114563900025573490442674225227682235790590616707857188385274186584856872573669591460447105688151281208238908470285147895678001948902280493477604361481216667716971590499226735103039') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 161 +INSERT INTO num_exp_div VALUES (3,4,'-11315021446594.877643290091276308982961654569173523687151347727612592478433578066762912541361898899908505997444632820107356713116459078630334224890355872486337973552333755378190316811715776951317058334754704988120078733912131691682869448731717816749620336196719541702138949084375907248656748314375183301372633028246109596775255074617515860012417935744433243071057057560464360663978361945666099558526069794464437818864063206829678640156992474597480916575712563493776637239091589972373682399519931569163592317107392231951775499293572134702843085474656152913351183535194499521618027894129537558509428098859715020703897463518891082573242502356303078754574312965093639182648263511466558336912294702019648266054331227425119096294871153811412169351624751542166779635702042223762951850816568617453355571302500885410532963789364822647') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +INSERT INTO num_exp_add VALUES (3,5,'-60302029489319384367663884408738513110.66683195868931664491302527038538338065260819361151478340212147889934633981101279593065290940544218360883531149731823374304151252289014494378769385157204705433009477214625880056478643611622410268943757215673170753460135411513114716313801477916713433956086133878890802448531292334570886746283905390661877220497842493537338035961123751393889400517474762491881277080205381424363695095196058838349029211365212855028824622924678684631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +INSERT INTO num_exp_sub VALUES (3,5,'-60302029489319384367663884407433001849.79771052212833997386114856935638647096681695139572314177791340913988441658803134837154906163605506135872443908341816501241365674229987734175441883907154998906319658504271319733469814941611260503645706198407368762270127105340397375230875953495882740039984314121888705481484090911598074635434289709802794549714765847764347865064280637851906308955404165593747173246944693509650424312007333558709071857299501674917023499921977975368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +INSERT INTO num_exp_mul VALUES (3,5,'39362489275784146262776411377472433635883331946.794473520543457442955620133347015506556162839462623905489255080102447195050109095701660164272430316804466254467810714209179752718730906325952685817112992943656292503112803950215110778476301809440329937774061163668461957943313261962261081942055908935814323069621279128270849852239727888939033546870208376394878842958202403235309372240005941467570230067124830916866857395233038346727879951123599893174252558078732888910139309038957525961212820831321973219557165558911222848692996406741318948607549825343491479728117062814094258484536263158005174429922237853707635743736923521032098496725445243775790161216159399180889906705265012270270348146530113428221072591696851818281866095288773371414866822270689959827332258348570976075184933893434327278299820594014788148344260948638847457822697682605612771344335201258128') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +INSERT INTO num_exp_div VALUES (3,5,'92380711368470856513514428781.033155715252174277753317877861994356621252232374386687048394529670637693505779282500567256835271428113529026462111032257747830329068594622091282098767000694818101994264352932243278144124687156236926607422077479412495979777588932692081795130282128890441931602671468684153168580234070246201722180460130467506344034452687371838907269162119534950946217165384250603250357360223255177692065141037447374172264943732616165429783010079281851748804739433821308362193703012671569249508710820679009084891198169587484117171861141580870066764275087111843275285564262902405980617569581840831518012986031156042600391943605532635833608358301306456966765206853910579231447150839538731157206153540873916893579943906851149770881336811951119112558311734171557608362620988555075663589827484854016702489324791126228380209309587206299') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +INSERT INTO num_exp_add VALUES (3,6,'-60302029489319384367663884408085757480.1853341682137571584926062805631087054017160819890685789064777236456590745415460695320768374693076860837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 167 +INSERT INTO num_exp_sub VALUES (3,6,'-60302029489319384367663884408085757480.2792083126038994602815675591786611462177090630181693462735571643935716818574980747701251335721895588837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +INSERT INTO num_exp_mul VALUES (3,6,'-2830400711649493468815157129316992649.40542786074520931471973065281957756940496588853021620372179463538053123396140685749478530925306163968207226329985017644835203709485594362663495728106061878665324856417118064730721101615473194292620972173690618491026470353143141125614124440035267592258385099934706896692953497971326605145704135723011753705907329979207428661473172503098296622281647255008204864404416199384701720347319806375450632245634238172654086373193251877533131784268854289406126119630708578053354762596511353053106459297339360827562281168219966099848212') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +INSERT INTO num_exp_div VALUES (3,6,'-1284742031601444539630782308463065726620.121021225455596762466053504195700643301310745151565435123335541550963124666304408503436412726848834604336377169205828654564329888653766451656774534718709065521243637375270687684572524302099749018591530352756390467862377335526634920857924031482455373589053524922608255779040656019538392173139295812160325688504210040741075388404155144782519528791757450256668977268409265390016721724966592135644698341754332845002439113523127047593325646484654291494607100188094186116001064043796216982681807318598789324900462932294782971663150070521334398542559480877366424630693734132836518604260869235580641521264976411493166969530737254118968281271908306432918913600567757535151861421384835424322504855607676315840963696944683182767935565256136130185809101891760917733694553800748568697830680328155128016670099315391685422333') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 170 +INSERT INTO num_exp_add VALUES (3,7,'-60302029489319384368482818948157603222.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 171 +INSERT INTO num_exp_sub VALUES (3,7,'-60302029489319384366844949868013911738.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +INSERT INTO num_exp_mul VALUES (3,7,'49383414785234649002982046297226894664526726187218771083.0993243619030008310875293647868815940421844461627295157812843657782639833900543200310573708100000958929315945039020410482966753145208427035917753919085618457760620513481628641658765820294863970581642745379331727722585319163262763708386199720411053619449096019862596221607526610103408936214184850115071874430846697061554769773328338028749631552202705583855831155461651414320570061181212214810086436100771547030013079997847086') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +INSERT INTO num_exp_div VALUES (3,7,'73634737013325927185.787791148221519354461791539553527545166847382784629235192342551464898036004011575416717008403527685470842765455409054592207142526523023201841973047779202013398235864494503216973882479116841765663948294836180515686647139678530220909072497288527276378202532400736141014848907023234659020093073127450778982904578906877634654521825977382116752537063128793631412296206704078569268566614023846282524151679028060869175439188773864994186109445961525301841201265289707928211114515861536069733921800160245586536759625418951427346236213019358749196674633237197452976517130405065120577692737021174118093373953642724512531935525024447977867020930500433287279183436509990047372809400167546185096048971157700858970777301410692908939206693154161335335755844997198191427289546263182822280127912118140820265025555165337881999926') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 174 +INSERT INTO num_exp_add VALUES (3,8,'-60302029489319384367663884399588771256.5916339968771732477072012126949734214868901845505193155307646111690097978112797961939995859130827784737422228762767014427842766445950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 175 +INSERT INTO num_exp_sub VALUES (3,8,'-60302029489319384367663884416582743703.8729084839404833710669726270467964301325349604567186096492702768702209585877643481082023851284144664938175277044596973126708926205950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 176 +INSERT INTO num_exp_mul VALUES (3,8,'-512385513828318260570283740065493064477880918352.732624553690077857674083796435724202494963885926573907185100543184828131859183999195040110586155435203949963570735841632689374488877298209082579317039061893012560130258753218955057387206477423088065663401594359617882154814262843273526859406265633827109554791772242178864873774889091687515990672487380368975556580539271333144212685871370972163560839446696514092637412587953506052848750866803569213269271165856310101244342151576488190595936869490659700946174362872797854591188391982770203203644172999264143929484089237665313698600170041324566984832357000400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 177 +INSERT INTO num_exp_div VALUES (3,8,'-7096872691348467943606706217.907270287823269424282176534343841939501231816905820949045946136373255017076943323578903040918266385724756894003692978391468202345397178445216069294845721607024056189567609414049207292919519881725733381453217071918292453682942046440563446278374996563501512335133749731529362537349288419883140401056747081065947774593869673146309163791076953204291951821124894409171722911526435445719071769008713367057971351892550570642991097981458696464929009464411568672010548002196406312721789582428747564855324072212842315229302959908665089850886951261233852165624100634055045684536311382452553544676139507899503993644452161529145849579200003677255968757773363970434791501820320494192909660871475590637419913907191608957830524390049664686282439567943053924245852983990958276537000732363895444894582579142752920882750130052682') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +INSERT INTO num_exp_add VALUES (3,9,'-60302029489319384367663884408030893999.8854209703537480818248540990234567956069965340942024890856088355839135538265116174644003927269495876835324407641642359213535695803871472434650475144516723617632059130297610134243891145006222068960999879308472500422640481972089756410157246974765071949782242392661524488959954348903412713930092273629207697480131360047867213863018127928853922173643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 179 +INSERT INTO num_exp_sub VALUES (3,9,'-60302029489319384367663884408140620960.5791215104639085369493197407183130560124286109130354360944260524553172025725325268378015783145476572840273098165721628341015996848028750420770651761919246816300854441592109844750954710317145008297946462099581451150385769713261452744310496166494545449824802407416426304041583975713483424241727236417259479541129474082301376239522310995725648773643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 180 +INSERT INTO num_exp_mul VALUES (3,9,'-3308379209762459471107480259839508279070920437.883503980178028214343751083865562028455061662673132221930429904398963590401793045470444301883103141901787466923883803951815572606105617157736442670792467625964359169270739534412932791178258858918086886061702512427989129732248215348301444245772127142869263635282888226326427510486246184233225114523636171202034558843515894542952126988613018789833835507734620046994907453602573865012044120483116345444810078666601100257620969379968264504287700045822481492526688635364586344704730579892342786173395802035361824932075736340405960099542224953439044947229246847140957298841482874444906129049023002897135347878048572628834749795298712449864571996898774444932083319581439741625832405434317985988163261591679157437224404970927012111196724239860528859217322132733404472897289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 181 +INSERT INTO num_exp_div VALUES (3,9,'-1099128766678422054524173986658.839339966689456265703816212189145237878729886466041806078542573981227645802109969871638687985985845489422516004202630099080709709893022100481258818112345013009059633421290241583864468453396484606925071369550998772875840640325758308835852391176503689677263605949075815552026731067384737231681068134099746550363063940273625924224721503126912810251607546172009765059506591787282558727077669973711491157840340631805422942099954647016059576777054339588421998882440726473698513560202030309804089250300097589174314677765341104767702983421063649104691583044460507666600260994707192787133590502137391691330098102374713996115782701417107878938473243874299874872852713499024851414757892169376458916467621226859152075901273014182163212783658933754507272478777304254191033562324994395916168496097385872331012258027431094381') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 182 +INSERT INTO num_exp_add VALUES (4,0,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 183 +INSERT INTO num_exp_sub VALUES (4,0,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 184 +INSERT INTO num_exp_mul VALUES (4,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +INSERT INTO num_exp_div VALUES (4,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +INSERT INTO num_exp_add VALUES (4,1,'5329378275943663322300488.64471790965256505869684245785528331091076155554650629138833809683459634328609777839510066435612911583108717191216693735823717997111970662575497378762952496582183738308720094529950793570383580785385569873278068217936841324404119828637880370718028782103860007754579779716996004352284614661690063919125301052941328989181561787543541920734755989452320799185700078241880935083616978140555713297241612718277766918005268951861880490889884082730841740604517529391011862694381726143520658746305661338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +INSERT INTO num_exp_sub VALUES (4,1,'5329378275943663322130001.85391741010004353389988518583956365616764439012730849109607738227723047091262162286043233973705463946054514004224903034208166782419414876904468730122054597840936856190652484801633363526576955397606531892764306099068756437389060626447578949162759295501062154826802212022414257953494004665588557188694447110384853149054690655645134564686305448219729651828678220200218922790293483596988037990835533058983562863141746692824117439019450865871047657552800448629502344444081260036580660700595591338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +INSERT INTO num_exp_mul VALUES (4,1,'454294299613767152878025320780.534199313974295807138790763501115780294529340799108297697573066187975311338382917022391830256203305238757334106943821060545424417350991354829668286194840925251162479496893943917530660694097932059166013476064988623431110002057735318529554555260199417935495388243829261809007709919225000608711536928171687251088217591210419208480251102484043683131687013687838713055660405381318396419588727500715930145098362997142075433472039319292466570912777345841400769387321465602989947078951135489852486382469990409873227894248208197179481868230244584527040573428134962626267135732247029762468417273891700661832893497067151409134724061246612631376075173287264787886064622106855886785805818642123776489793586531950438285720668411465570116161790343538663297713926678759640594912243360541590368666922379919514826022141331900181') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +INSERT INTO num_exp_div VALUES (4,1,'62519544780217042176.800424689664850775296526267109332647921183817056683200043718160298562843864918741523494444361916531159341418970534833628106062976341639276761669219281771109561175175033739624472497927501467465456946098280878993371659461957361369508794842102784763955539708800574418468150309301129490186416766691183270872711413796386178009615777589066235359283212636467980113350635181915492452697347977967985810294150853782607014649150457138118264698071689065469752702524632313088938504181640435324554007553994564705401249228914199354821595855823113730697333390936834057091883654016371107974899726642500486005445063301647520527084320363513388355471718583708935211830796440056542408492723718088396437530207347815505844074508948817594746824098278470533148171941442049323578854023683167934569551595335539887777638716651319134577441') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +INSERT INTO num_exp_add VALUES (4,2,'-994877520673428596810678826533995.79421257464236160757218576989993781147390382997132644206786872350652200243563770552469933194637146474528320738725486418004701192337175478117026439697031462361180324038544450723753402846519731908503949116978812841497201119103409772457270340059605961197538918709309004130294868847110690336360689446090125918336908930881873778405661757289469281163974774492810850778950071063044769131228124355961427111369335109426492177657001035045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +INSERT INTO num_exp_sub VALUES (4,2,'994877531332185148698005470964486.29284789439497020016891341359478477855230977564514122455228420261834881663435710678023233603955522003691551934167083188036585971868561017596992548582038556784300918537917030055337559943480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 192 +INSERT INTO num_exp_mul VALUES (4,2,'-5302078674303935968062773235453828254014583744527466365136.236414807326868572353809920518232561005161225922028750078608989965741402418802255050636954800114792425419735155504035469350521800895164087027043476055514245942961100610551646034472084954313670284875310691807937254054948742125729353864014122131419164449567115006621212424805182687707372956385102095255735458593389920872596796806885847543910224476727171570873698525606016990229936284811067826588349092841322512643043008589065847223683467371925773023109720951609815041012521485326120380123169545818055967455575736140138663815073081494226676896278654189873597341203197903408668523514375373841493189836809506003729379742035629498519683885268256481104619815130659628225053833297766479068686119691010593208135616363994230674606991733148502293102108193522604968743948323130517040609601859735899914987426089053869350663') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +INSERT INTO num_exp_div VALUES (4,2,'-.000000005356818439105666775800262590702859770599410113087721172791624002387236505438218124867814437523686300450045582100868990117124343222534568799037421944272316277130975314766456260710406160143182498931595199129228915695802952695510723443157825968340043198200740606202264287904755124946591110599335909404657109057432686191440989434662797205973563889238804413861126260401987949920244286377128599413927273444061572120561496904543200956508673923547626768641271397088562966176629018606103663605145666976048261236691866387601532424530473754175270500777679603569715192364542901360534980926452487443629100484491344001509360344122933911316486556042277769848194790964257060927912344609376571637126617813506411190014141992988288983968823792971270853369317867326071952900448455162898476163801382836761898292684175721846') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 194 +INSERT INTO num_exp_add VALUES (4,3,'-60302029489314054989387940744763542234.98295358053252401308872309802346144227050959966671157134780970446370197110016237152333448347415674483796371931316021552756816073493808344537122580089676304958104270609762310229182150728136567294798680824019082599362332377530165818229609055765904048195574142709698758095302560470195171027219786996322461803443213101532716728918363951912367135900414238535625075942525108530051828834829820554490477645701692374399416239080329365045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 195 +INSERT INTO num_exp_sub VALUES (4,3,'60302029489324713745939828071407972725.48158890028513260568545074171830840934891554534052635383222518357552878529888177277886748756734050012959603126757618322788700853025193884017088688974683399381224865109134889560766307825097103477790782590061456916367930139323346273315068375646692125800496305291080749834712822775973790354498408104142209966769395239768969172107040437333428573572464689550003374384624966403962290572373571842567623422963022155546431883766327294954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +INSERT INTO num_exp_mul VALUES (4,3,'-321372325955692885069615337209737469749246561535004445508427591.072860243358366933071485495726715620133686420023451450292996945184959542770492705998350644739298629407567812798540119555932604687814429669592481327761428042980782672136901602006622227365754036664912989085940235439697789102358431343119457114603363936544931303133371137532006899162833369543279729021228901466728220729625107362063321334489394782322741444425117731922691457341543446841167138481424319752111748042440994701571955325673470021626946676976482516292402239416632497972073915818846704053624707839813514171497746804751780741682011937606462260710753056669269928580460921188286249923152921382198282201761171043384698319895970192114563900025573490442674225227682235790590616707857188385274186584856872573669591460447105688151281208238908470285147895678001948902280493477604361481216667716971590499226735103039') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 197 +INSERT INTO num_exp_div VALUES (4,3,'-.000000000000088378091435340426596348183959201660680284222502095357746364378698792730669202270228092348823133529449019715406417264278615046537007844589547485282959556860316942508808911542109265489435572674031608663747132688980867386885961271358592278360097086532747883342438036287136994589308551796702164612609710942175900921197001888540314760352113821737014875886635147123114456910985089625906448913621495025509697742196814421833448856595853403450682101743559369637786458968714240975228615283970739279506239628546165569688434254286341567486905374255702980370754235630955328837646999003123103831262789115646588779721625156078607919060762857866951417867378220773543985422722165221371084387943737083254760594128718841665355053236168688218864433967871311858292181233490194833547273501436630325295640020916257836404') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 198 +INSERT INTO num_exp_add VALUES (4,4,'10658756551887326644430490.49863531975260859259672764369484696707840594567381478248441547911182681419871940125553300409318375529163231195441596770031884779531385539479966108885007094423120594499372579331584157096960536182992101766042374317005597761793180455085459319880788077604922162581381991739410262305778619327278621107819748163326182138236252443188676485421061437672050451014378298442099857873910461737543751288077145777261329781147015644685997929909334948601889398157317978020514207138462986180101319446901252677846098070081948065342276861225678086539994965165526535072979009589652953672647099592770056310833870145919866630936137861378128966356409101651457894504881209406948099561100916885616958192984693820003384717017236405797029790907178714') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 199 +INSERT INTO num_exp_sub VALUES (4,4,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 200 +INSERT INTO num_exp_mul VALUES (4,4,'28402272808100253242547006276715304015308580784958.804614276533085644370816876160290159450291717634111299841065255625515058118012211808741402904995080624675460593676923639082981788732031193774047612589113654423166826140872334380708795266307037944059108148612979119729408762532396036043629484049508789880964586236575769826806092391573178899640321403656891487586452524427223891405519836671312830183895761747460911777623703557946796784873885800089025388390522992806365773290733075927321101736155663727528284512100509273076328103465333687228713897893434161293693971954442699482857938492961830350598789444266860160794913830991304996676299650460125000959751177037694425217989910261807246272771711816326991282202653917488360776928533800529297474279497910326579608191975246060946079639658615178160271122713225105861574160788280907842327681375920919676063500116492292319') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +INSERT INTO num_exp_div VALUES (4,4,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +INSERT INTO num_exp_add VALUES (4,5,'5329378275943662669459614.81475694159581596077242547133292502869630735172901157043010370467618244548786897684821457816189831652076071977025794948484549600736179389638319303817478693948215387894509009504287664213474693208847025374388286162907794727810231557001266897729978691844410171412189947386181530441402903608214502713480332746271552746231631136145916685939539173054989927058122097304419584979598595477177513004218594211597809300517607260841648610322863666300637648662611916496850248528515936635845594390453288113296413254893687029540384176335735114863908372780241463999450547422213639667099644505472777149095004849805371205203850993689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +INSERT INTO num_exp_sub VALUES (4,5,'5329378275943663974970875.68387837815679263182430217236192193838209859394480321205431177443564436871085042440731842593128543877087159218415801821547335178795206149841646805067528400474905206604863569827296492883485842974145076391654088154097803033982948898084192422150809385760511991169192044353228731864375715719064118394339415417054629392004621307042759799481522264617060523956256201137680272894311866260366238283858551565663520480629408383844349319586471282301251749494706061523663958609947049544255725056447964564549684815188261035801892684889942971676086592385285071073528462167439314005547455087297279161738865296114495425732286867689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 204 +INSERT INTO num_exp_mul VALUES (4,5,'-3478781676337858247983014311182511.567538638808357215203593479841446379226774481291286361639429856698999485760647422501864626078375852610019829111004807806660731243672830787729048847342063218718651165150612717759770504648306347926061960607388621011846314969634048226452709389995594961695723139571002939804473057725442880410434039783304583526414509590532906062732322732569475349107437896717416548237633532805602064623969799081086996320156575550896200848758685986331692388099427314008504506503745527468550106879602399030419569897808150076298414568875477195447656904373310322813412927463518325927626891046356679526447117311923853482118502868148386882363449163182892615259995945992014431502761210899772725227648729095696228388558331052524469604046072203605897109629560683446827492904111565278516043939137760721315953500281379039771826554155511347152') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 205 +INSERT INTO num_exp_div VALUES (4,5,'-8164430956184510.184223536017248184022252663660196916321116266103608317725855237211273642694947892658721606226082017525816544904635887836163201565923338826779819876742736219975639586566502584026349778499211535661173597356253186281116862244165796632756909578140184577853088376334255860281874385669242675881761388233070861374295536603371778669602656670852115614651462552069294889723058758969660566508798011830996965570446030123780674316363670374970480994905368006454513642480180066435609577311074332150098288374616437489163254821095377348025470309665651059603665062887597814064136313866690824972464351274062540825405003954064175728198182815347642172934453828192850870808373638597839434504241236228591053696481146252072190903430582534862988719805163692697482513169856291048966811374872266165034373412719593685881972700171726777938') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 206 +INSERT INTO num_exp_add VALUES (4,6,'5329378275943663322215245.29625473207137544719284446115519970394719946335145777492574745992986971075733570324679065009803281404581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 207 +INSERT INTO num_exp_sub VALUES (4,6,'5329378275943663322215245.20238058768123314540388318253964726313120648232235700755866801918195710344138369800874235399515094124581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 208 +INSERT INTO num_exp_mul VALUES (4,6,'250145412892811547138949.592621291590152419206270097656346630226508074074623894951308487425470437268130465956063593951784820669318897182831355375451719125809800516979013437732298382708070979871283132689492336823087794373113039154669229889503700598930220858275174342776478898670277868700384853696009897221747924643343353942154528501454689084608965009561564638167714973711022212547096732831847202912862290958304510651828842182545311077713664465815992616213663619529378061133917572474298028065850515876361609671565914027186063801852554353160801534696062207299890867876199323530337336273950892723090754719547285920090419070001019943385293110663922226230169381423410428577990604776655422105400452217085311617728003688836185608912367677734364834577573255789160419371322775733777518997638403409000055707558465286469808848200141192627396502735') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 209 +INSERT INTO num_exp_div VALUES (4,6,'113543048739697485358574290.758354267447744932153707340542459183720907885610125346262898114677742971240785031722334497858930434531517077525413654346644836353208132641713415396062580605566225794048569430676355036264762949452090151450855446984773994337170590068740235544320694721909983307239491151139099779296496785240814600627140543144068640768857707110930453204162312973998304574796413938461971472337040811785231390930046688391955000749644938061585377150632133417156866197053052425576957646564943278156977176976876921235395711611898108821587442609611001702344783440618040704066809035404237786023075676374788819144406909313755996914145273176359246052899650387182222905558751208368173052381982668563471143298720677965028880626152749773712037769548408324298835212547215352657271696665387200792785056233953536347605130973626194099064678842085') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 210 +INSERT INTO num_exp_add VALUES (4,7,'5329377457009123250369503.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 211 +INSERT INTO num_exp_sub VALUES (4,7,'5329379094878203394060987.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 212 +INSERT INTO num_exp_mul VALUES (4,7,'-4364411947278810125327066890819882483326918.05664098958260550284395870948992407314161088028674246708928421994893923699743452802989464864039994566042797942433140378990308345483670828497915478397481687305406460330009319949623844175096007381662809083363069100235985794575399268709260901964834244796150883807308976949196661411035264619638771824190014274817662519438658481432363824187693821267613212631153175155634316128036152465184903927860719447693468054624663668062006049759837326188252927823612718163916100588143128358998656306593393889422386501730237442526450419990376323903182669190482615734972147533221144682538647497701130447816148459762464395194383090936159579764712919396391813914821973715879062992249315474841639591907249142779103650773383644785606333916967894') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 213 +INSERT INTO num_exp_div VALUES (4,7,'-6507697.520580964829176145824902679560705744817573189143227837387224410616222039115571544850095278317993922427931439719549137387753697989249394347047436951117850128104928719365703899136632100669607126357491484781141296021264049762417528697619931558728863308905257358126654378784709213859234056696519305650316810797382293500878834933984458810656133463638442959750083607649924453935287420620424368291770694630751828333903156364366745210911640207075765008558904788350844410055253643515389003711759818446776538393914018427075074171758415188027562645239606914126802490579848138218395145734902830046359100742374008993296019987093605275289913663224324033923096998194326249508491872193747944673057257521552387923218450155737056841633810711295424578984452176016198348344913655301417872189073133147510027427530833694019910340299') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 214 +INSERT INTO num_exp_add VALUES (4,8,'5329378275943671819201468.88995490340795935797824952902333498786202536079000703830146057240651898748760197658486790165425772165585380839129948178510273188565692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +INSERT INTO num_exp_sub VALUES (4,8,'5329378275943654825229021.60868041634464923461847811467151197921638058488380774418295490670530782671111742467066510243892603363577850356311648591521611590965692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +INSERT INTO num_exp_mul VALUES (4,8,'45283653791262997781451381354094822.762732909505051438036873220502792213670540454778361182993875916509061144859281577740137081988678361247725064336120451090222456518107029158304937620179032477664627949959143233370320432203497828243297406462513350790251761540074946469824444452248386782451723637769289822576372357189700319768797708375563651655860093365309717823602754924352327588945034832436331911584742966378275504545736896430718939807674966738116698454215555860047859161126694019895490767779791933882712567492115664113775047192011252893773389940988533801360010782816196288710063568554147458866942816721046004257953642508395867837127678980002737669139369781058046396738606563716339660654364541530532834806205571191828994250708412638796240377704994928921528330863683630622922959130920715261879547446054261914770022377059156125037157979236658010950') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 217 +INSERT INTO num_exp_div VALUES (4,8,'627208063620965.397582272040628872773601055303353339700043792111288801181637510303989399395425313995651311362368773096988861977687484912995632130587762386590996099363383976320342247076516604162469063709298438133327434461462906199160715395064249299615054970359309619951777972710299484596875999967582794277241285253106817446259313281064844416249524876385699646393555435017820686376877981018047574348711991428666249794623006175739581915209218834701034964043360823844816042368184094857692062884223864639972005010863342567608351008172649209459933114800143792514183138995700133608613158857147417653998048890116531052767737435620558349226865105888201598712435680481803901906613772821370519525404423549161696526405320391828194356063547089626322474164332505209233143121068245585662919687001395119229263995765376465304715643388771609446') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 218 +INSERT INTO num_exp_add VALUES (4,9,'5329378275943663377078725.59616792993138452386059664269485161374191901124632386474661634799161523147237015531446709484039091244606359050341194730653343894986479159670583937529516163204904273806158788218327396375034882788180783796976731912141525319602448709213495905899041406302673881364465504945113279286939663215197485367850132991968081639290297033476859158044889351836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 219 +INSERT INTO num_exp_sub VALUES (4,9,'5329378275943663267351764.90246738982122406873613100099999535333648693442749091773779913112021158272634924594106590925279284284556872145100402039378540884544906379809382171355490931218216320693213791113256760721925653394811317969065642404864072442190731745871963413981746671302248281216916486794296983018838956112081135739969615171358100498945955409711817327376172085836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 220 +INSERT INTO num_exp_mul VALUES (4,9,'292388240303165948041827159734686.255558469787242316676287235194652580157149226950109397295920730296960145548003120827363226435916209781396711693581454960342091452830648929118261388933297036933167543189308061917640517578583521401267417187854611829815212778183983326568586118831109538377828156118900313778053576483381085207892754728937946691892849474364477434665960112125254104966566712906532318984871145605839506991591027939136026602051635433295687547552796828217859648186757719639965988287173297286034098497871707197092627676226053609131138590878743560287292934815277894463305001278326023708395571840850120055316276256138004565442099731931051413153564744766098053176049414330146267604802971221161572130161432525297614616942172815141372973870720928125699420370428856022295499447755488148545048400795053604349570217878099721865670458104653570360') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 221 +INSERT INTO num_exp_div VALUES (4,9,'97138902640718538.241246716463110895614166618530828908023040947887095196830690221211560526562522274118188963051412359798837957512805692731972838989047910709158995922699598619854907969493232150042212406549916252602794415099066259707018021422154933830674786488990033885447289593742424717170197810316367637885248684134204152352748803532396210051700193575105804898183523770153431536054848843504020390623875664696278263569145547515663340450903772852615789980257449146000410036925975898331113013857953289990299253584950458042598491897496393582249411290555264437893099880371008957017323366523688894303458743415715114628052487518110654201696604914159777300997374156315186315524817636714210119873791848535246674326877611945112249137224923201544452904111118569299934059002046318394345055859769572070097973298522564724884895879226870720839') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 222 +INSERT INTO num_exp_add VALUES (5,0,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 223 +INSERT INTO num_exp_sub VALUES (5,0,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 224 +INSERT INTO num_exp_mul VALUES (5,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +INSERT INTO num_exp_div VALUES (5,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 226 +INSERT INTO num_exp_add VALUES (5,1,'-652670387.03916046850422757312745971450663862747133703839829692066597367760104802542475264601221776157515632293978442027199108085723617181683235487266149426304575903892721468296143475297345699313102262188759506518376019936160961709578829069446312051432780603656651983414612264636232727512091101057374054475214114364113300402823059519499217878746766275164739724770556122895799337810694888119810524986616938847385753562624139431982468828696587199570410008890188532132652095915565323400735066310142303225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 227 +INSERT INTO num_exp_sub VALUES (5,1,'-652840873.82996096805674909792441698652235828221445420381749472095823439215841389779822880154688608619423079931032645214190898787339168396375791272937178074945473802633968350414211085025663129356908887576538544498889782055029046596593888271636613472988050090259449836342389832330814473910881711053475561205644968306669776242949930651397625234795216816397330872127577980937461350104018382663378200293023018506679957617487661691020231880567020416430204091941905612894161614165865789507675064355852373225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 228 +INSERT INTO num_exp_mul VALUES (5,1,'-55643106304872.575994253221940844841058071061962511162776681458310912066379595519265546225338405882027547140476045378015935579066580347282075024392379464189067155567624835346798806677988850250198082355055954078446421075165109896091047534711081616362392995575466807084807876544560268050611445006601394735810211678919646667455478469014906335433468365011768049600750224822391684377238242162320161552720449713229523135506671063115436813348612986916614320012995541575293478341408982118538094438068036422562665160411591652618670802973618768526197813319204816293073794413317669922144705633308090832805914096147659820167569140291210526520361556881576175809360614782817717579318298657744021133210954279487777567785280633309576696708168342539425395482429923273623865667723482418178781573723597156804085501875735112311466228778929147929') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 229 +INSERT INTO num_exp_div VALUES (5,1,'-7657.550797567691019915353529993301413746369700087741672762343206271266232635965032053368224472333368713006346867984576168784127503674579531243603836945595880917241997606783133673324236134063757452734295148763280059050480246827193380861494669624151921824660313516974440913733511526807313019192263170823268678149435664224184903925632177789052038092611394447709922076676981043877747276056677801802695466205531230350209787298926245402046182150996849906836743231861317120171583577624262765589605263477198809166390259128339127005924586833372241946051704497188891325715185091060185547236923494393813210904033520844572880475265306843414506359253445517738473745552980984097762509546161690823646176501838559393690565709795724159196133663168004773260451322595899506776323262195323943138344537866088159583331807728944620284996') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +INSERT INTO num_exp_add VALUES (5,2,'-994877526002806872754342801504871.47809095279915423939648794226185974985600242391612965412218049794216637114648812993201775787765690351615479957141288239552036371132381627958673244764559862836085530643408020551049895730005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 231 +INSERT INTO num_exp_sub VALUES (5,2,'994877526002806872754341495993610.60896951623817756834461124123286284017021118170033801249797242818270444792350668237291391010826978126604392715751281366489250793073354867755345743514510156309395711933053460228041067059994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 232 +INSERT INTO num_exp_mul VALUES (5,2,'649411906691138274293985410502516861224852.2323455192714410716272307781034189160865613770320102043319541634113746032638191509585045862973333645830298922352816245477556264222094036953195419857712804755170632292914187367964994214922001758104594052499795564860466055599417895782179851297585155129541589802249540436678824225950907268084876110445460948679383611117263673106597132046331719468816839434908155684738864149955129235751738204036443603521478609787295079710078973503970964790273461142497259987849074597264522099648376356902360358310245001183020992360260836105404118742418040965190000718736837422434593694808973939805954329718232693154128543253581495885789333274488461716809104532693754070810202831113003978085636579574171344721710232931261731022478029314435363413498991740750878099825781577297965642009156858479681236085226911858782115') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 233 +INSERT INTO num_exp_div VALUES (5,2,'.000000000000000000000000656116570506105776235076334177868550033347254561166417969910286926369599900073757929714260350320362090452092025380232792749476245042480546813848702351830607516880397305138543526307608094143028291193163613755680419049060162928958489964834941920423432354996040147818253087783193280640282263490705632002572757216731766513434035163528102590524432221718194164133959630768718395847710529339782880381264265894322494716854757290930538739000043383104085867828258790010654331660516512156519838978751447311068903958136482041673109857552178367614498426226323001399275980281507353231821022591045797658991388304873240910526149138339658220844723880158150606035181559877351791752701872877147074033569061408920725522180134133183999181370354585872214368766629114773129541658653693832843354053701079334077') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 234 +INSERT INTO num_exp_add VALUES (5,3,'-60302029489319384367663884408738513110.66683195868931664491302527038538338065260819361151478340212147889934633981101279593065290940544218360883531149731823374304151252289014494378769385157204705433009477214625880056478643611622410268943757215673170753460135411513114716313801477916713433956086133878890802448531292334570886746283905390661877220497842493537338035961123751393889400517474762491881277080205381424363695095196058838349029211365212855028824622924678684631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 235 +INSERT INTO num_exp_sub VALUES (5,3,'60302029489319384367663884407433001849.79771052212833997386114856935638647096681695139572314177791340913988441658803134837154906163605506135872443908341816501241365674229987734175441883907154998906319658504271319733469814941611260503645706198407368762270127105340397375230875953495882740039984314121888705481484090911598074635434289709802794549714765847764347865064280637851906308955404165593747173246944693509650424312007333558709071857299501674917023499921977975368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 236 +INSERT INTO num_exp_mul VALUES (5,3,'39362489275784146262776411377472433635883331946.794473520543457442955620133347015506556162839462623905489255080102447195050109095701660164272430316804466254467810714209179752718730906325952685817112992943656292503112803950215110778476301809440329937774061163668461957943313261962261081942055908935814323069621279128270849852239727888939033546870208376394878842958202403235309372240005941467570230067124830916866857395233038346727879951123599893174252558078732888910139309038957525961212820831321973219557165558911222848692996406741318948607549825343491479728117062814094258484536263158005174429922237853707635743736923521032098496725445243775790161216159399180889906705265012270270348146530113428221072591696851818281866095288773371414866822270689959827332258348570976075184933893434327278299820594014788148344260948638847457822697682605612771344335201258128') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 237 +INSERT INTO num_exp_div VALUES (5,3,'.000000000000000000000000000010824770508763323320533297369674519056450544793568147911931789010432012750062661590994728968589403602468229106206242395792957238667714358401601098858606386995096923432407249369639633268143022787987190106724545750803196130511146323174462918572423414631798141263222875752767731279138952850500369328934959764805948568471324562210715908420467881411844098258193571194910997918428786213948547748701831331312040839544355427357749520227124858111324859160114175254197992204974033767300989488517391063188153561391320190653403747521648794370679322504188364455328709488846777004202196382575648619395139553279192346251133156445942281048959845827006761160755031086836046398020850814350246219929303018051720203943879538087954853996826539712240458022307680912400297508925714946398031304516583939283') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 238 +INSERT INTO num_exp_add VALUES (5,4,'5329378275943662669459614.81475694159581596077242547133292502869630735172901157043010370467618244548786897684821457816189831652076071977025794948484549600736179389638319303817478693948215387894509009504287664213474693208847025374388286162907794727810231557001266897729978691844410171412189947386181530441402903608214502713480332746271552746231631136145916685939539173054989927058122097304419584979598595477177513004218594211597809300517607260841648610322863666300637648662611916496850248528515936635845594390453288113296413254893687029540384176335735114863908372780241463999450547422213639667099644505472777149095004849805371205203850993689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 239 +INSERT INTO num_exp_sub VALUES (5,4,'-5329378275943663974970875.68387837815679263182430217236192193838209859394480321205431177443564436871085042440731842593128543877087159218415801821547335178795206149841646805067528400474905206604863569827296492883485842974145076391654088154097803033982948898084192422150809385760511991169192044353228731864375715719064118394339415417054629392004621307042759799481522264617060523956256201137680272894311866260366238283858551565663520480629408383844349319586471282301251749494706061523663958609947049544255725056447964564549684815188261035801892684889942971676086592385285071073528462167439314005547455087297279161738865296114495425732286867689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +INSERT INTO num_exp_mul VALUES (5,4,'-3478781676337858247983014311182511.567538638808357215203593479841446379226774481291286361639429856698999485760647422501864626078375852610019829111004807806660731243672830787729048847342063218718651165150612717759770504648306347926061960607388621011846314969634048226452709389995594961695723139571002939804473057725442880410434039783304583526414509590532906062732322732569475349107437896717416548237633532805602064623969799081086996320156575550896200848758685986331692388099427314008504506503745527468550106879602399030419569897808150076298414568875477195447656904373310322813412927463518325927626891046356679526447117311923853482118502868148386882363449163182892615259995945992014431502761210899772725227648729095696228388558331052524469604046072203605897109629560683446827492904111565278516043939137760721315953500281379039771826554155511347152') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 241 +INSERT INTO num_exp_div VALUES (5,4,'-.000000000000000122482510461124748279475400009367345900846466958806966807399903713411658400733717078392550780910604704603123670767210550800752620037863340961255721285160854785449315208955654408132775022766783343331151895973970395232686910362226184006990485313002943710214511418310741271074710741339586430026286272098156531835438969774325517509155992092194349661122678547097423264670055720422496527272118788005921590521726691666219504214087867030003203385360001614199656989667055583749577099440092378355805901262289841168751608673297446473709956390142112843400255748161809121986096092991616144443486023218404881798896685413932215981950393130292001833627899480153863300557853617312991880655905907971211246077450786084079040513198340644157868678782195341316027563717617074364438885981635394382733697473265872796207') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 242 +INSERT INTO num_exp_add VALUES (5,5,'-1305511260.86912143656097667105187670102899690968579124221579164162420806975946192322298144755910384776938712225011087241390006873062785578059026760203327501250049706526689818710354560323008828670011149765298051017265801991190008306172717341082925524420830693916101819757002096967047201422972812110849615680859082670783076645772990170896843113541983091562070596898134103833260687914713270783188725279639957354065711180111801123002700709263607616000614100832094145026813710081431112908410130665994676451253271560294574006261508508554207856812178219605043607074077914745225674338447810581824502012643860446309124220528435874') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 243 +INSERT INTO num_exp_sub VALUES (5,5,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +INSERT INTO num_exp_mul VALUES (5,5,'426089913064020811.057708378200224487694731586862745370027417544052374884336177893807736467646454486029424673621605232432043672119510371547153895504456723242262639262542904151307250842477327375961936454637964429999741717244285121019840463692418987118402683746281993192269229200465080358289645050337976214115902915692028162689089167194843185708212911364017271332623359100711545479273675423617018342297822477514128997410642005300368966199980354369928371655155437291469427189561877718971914040675572136507472590254222870537216617260612835805368361975725573009455402822669103118872235140158440342063571894152305875004532651814592458133460160514384171804043127771746596286988679698684698755896736275307574630777027620558428909546664763675431701332632828281070572045822129984625797185173815273651376003614106277727279230096226977335510') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +INSERT INTO num_exp_div VALUES (5,5,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 246 +INSERT INTO num_exp_add VALUES (5,6,'-652755630.38762364608541718463145771120672223443489913059334543712856431450577465795351472116052777583325262472505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 247 +INSERT INTO num_exp_sub VALUES (5,6,'-652755630.48149779047555948642041898982227467525089211162244620449564375525368726526946672639857607193613449752505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +INSERT INTO num_exp_mul VALUES (5,6,'-30638438.151446159804025029882398388155309149089870990062944469684482366692824338098201222171115395923414887930224163525189097571163687285244255335505387733673499447610577050114902372990462064696637481657064525319516004273769831260452832960893174173254560250804003884280384718123289136453955482855362019158401218620018346500189769819687260476334734259702665316562988639223597110627626759216850014150105605927773639897638043177685498804811787888811168524202700283461266793154726325540776914500415140842975457394524215869103737379109516024460317825645645301237375972914247141703084877141866316168268901439172491577729880760950895760711857112463508064820414904611059588717092145484656103798852859978690742216940980929562068') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 249 +INSERT INTO num_exp_div VALUES (5,6,'-13907037655.047994416383638650569341223199042786813441967582376077478024677494832069402897226848055043557486983268019376307288565911231748501636517992289743940159005664424461285010295150828744259113760652210086696250085454819340987566229400805422509198052317518991183515696724846560872057916862620762789778660622787735923967096950195583369113574365386627110408307941105082873469072519133330718161987781080307947247163619814890462416622144825161521790673339279047700672881113718394727610096366361422482794458375587355933614201638489194194834709433413694420512869179976485096875057742460003147602405353823942488343056906912173170809084207937229591627643451380735179767199816663168139837088183577975769442341678933576388936845704303859241320794255052627716474860113993958556604381707826493168941926878481079724185426298004604') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 250 +INSERT INTO num_exp_add VALUES (5,7,'-818934540724601372.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 251 +INSERT INTO num_exp_sub VALUES (5,7,'818934539419090111.56543928171951166447406164948550154515710437889210417918789596512026903838850927622044807611530643887494456379304996563468607210970486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 252 +INSERT INTO num_exp_mul VALUES (5,7,'534564131989234694540350103.27821462973515555648644772098605028371173048154132108733819196629002548296868548691993248746628993380136454426833349407578676005545111508293942736555269938962058196496152360848131645787941032968937794930046928523006455386861100809286408671908320322523368135203881520526880998279355848280412933152306299256343179622513731096363088094541514890135766460631462465021694553063366717467560655272004461368865264059368514271105464855575429914212085797297268595943955105608543373940035636033207568676745293499106348500559628723682588033431457023964317090780615020801564861497990103549650624438425421690193862533733474254') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +INSERT INTO num_exp_div VALUES (5,7,'.000000000797079129642393611556079160915147221153735075943759104977169600937534508973732991117540626046659124172765761873705978811124901421049332579161931652390647472911517923131800238903184679028518657818755558526885018755394697157094867449047655737107085020874974955627907737126958129710597811740696534189608639914753884882702680512272194316887744972931453458445314561564591875764930680945589486999586667912816485821717403892703364322658245615895415781719033810595358092343690359557942948213374234065052300866661453767599465059289920067095083062096458980564265691295895672503728815182981118876144075942348853666085714846210822847053889733510154276933759200630639642310562242207518883342516103725757482864105340008709446643820864294556778969997115586027866760708448174502158738150605938364482719960251612464993') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +INSERT INTO num_exp_add VALUES (5,8,'7844230593.20607652525116672615394735666141304947992676684520382624714879797087461877675155217754947572297228288498221620714146356962938009770486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 255 +INSERT INTO num_exp_sub VALUES (5,8,'-9149741854.07519796181214339720582405769040995916571800906099546787135686773033654199973299973665332349235940513509308862104153230025723587829513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 256 +INSERT INTO num_exp_mul VALUES (5,8,'-5546455599206321494.0676583421119904300307105296377723816472192007866147764761501865875232824814135783697976183493106885436876081315217834621720906478074798596116645640251460842350553806256223963023430631066024389364515688765194373161385579258482225808660340732705687558150699172147896486727530192499184101617379930846663835628510376484675411350654979679181852179924386290069790336316958202582966248703889464308649631486542724072047294216362186036638115240070658004553260251510288423749333873893917690832829128021808383128393431810674177390352413548658782609064839524756041501835115152819802758773711821322162752064589750295542985780512921839490040396053737870038534216948323935020460307350020911362024271167085905714873548388570602799432705061561572854498075600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 257 +INSERT INTO num_exp_div VALUES (5,8,'-.076822018213756690975099471985461347542955923191183223634407380481978143225129486622351714276452369661632980197282261508936298649901018470846144321441236073683990324039849865750139470288565622579952182053792815638469841531577235191276257498209844422440366423136595067535337374223115507557306455001792362506235886189722508617024948653046102060677266555476719102193278190540414934812073355995577639986512222998268934000209944414236509139290657402937840986061987219441410741189615344050459067454369371094189930607834375561948483494321255500497786795636801854613881105643003358210407867114145806225724880370339074242480071595684502491827709175732777776915682786771730423733673667248186336046898260378049328204094804755195626798951644386924178161926128482002518979482630732440619051262620098544265763306253807191182') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 258 +INSERT INTO num_exp_add VALUES (5,9,'-597892150.08771044822540810796370552966707032464017958269847934730769542644402913723848026909285133109089452632480800168074607090893991283808726990171062867538012237270000932798704781608969096508450960185964292594677356241956277714380500188870696516251767979457838109804726539408115452577436052503866633026489282425086547752714324273565900641436632912781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 259 +INSERT INTO num_exp_sub VALUES (5,9,'-707619110.78141098833556856308817117136192658504561165951731229431651264331543278598450117846625251667849259592530287073315399782168794294250299770032264633712037469256688885911649778714039732161560189579333758422588445749233730591792217152212229008169062714458263709952275557558931748845536759606982982654369800245696528893058665897330942472105350178781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 260 +INSERT INTO num_exp_mul VALUES (5,9,'-35812445701642379.972368737320206275515144213236752803936806738624588812089615098329765811617509505790110909629109400553415312470540217508070421816878544125783329593128638405659896184248784794258084116406472768709113030915308410565617764394827427154923321461158387012978726512246146545834669665093228316853342805604075936530371665576147966721599968786161939347726656168798065647411457701453987215491345496003650288850096338695703984042549594979897253521041581573388369367579323607093487743440894765114619634001789457486407909224339065748496715380572175183589195611952939575073075140094901024063428239223964510824958346570603142906309198033196987949067156046076497974760641964978711558209708743776024313916111738542765749928287600981397080809041007714387564206594515733287925008053261840295560398311905155157989225181164097547541') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 261 +INSERT INTO num_exp_div VALUES (5,9,'-11.897816658873986795664687519069203701902563457968097729876034796143085813450454323128600602495745166997629078984618283588337379184733369491549230343315369634754204412939757136108898254582353378508832611703989221079986765793923635928759179573599208612516427628403686659479459867527627014558600521732194240404211484706621458983727740143568799713006127585168144158660566534382037451913967363675002134687952374080694449905223371627606557311710348820900963340884001770733452314715448053233208783321215998063958966729954113843581448912079950334969908657535514847005768455377990262943747367245613296497099716892292154137652893990339292671106003657659470243633112063075297194691349631518467702876183897580432003030164590920118726657290102377710611324297862045849839571689192181090062958059281673245670440852080202548743') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 262 +INSERT INTO num_exp_add VALUES (6,0,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 263 +INSERT INTO num_exp_sub VALUES (6,0,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 264 +INSERT INTO num_exp_mul VALUES (6,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 265 +INSERT INTO num_exp_div VALUES (6,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 266 +INSERT INTO num_exp_add VALUES (6,1,'85243.44233732197133191329295927531563604777955507322414928382967007765263923984471408038635831036097817458527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 267 +INSERT INTO num_exp_sub VALUES (6,1,'-85243.34846317758118961150399799670008360696356209219504851646259063690472663252876207514831001425809630178527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +INSERT INTO num_exp_mul VALUES (6,1,'4001.075404054519813215296429095020391062109905613738157927030437221793757373268325953178030040276107574363822832168160758728653712686313134828282109532831190239521843808940611025488601517574653932032236616573457735900045655665690517797280666732780030171712864961531623060353548802466577910774711998056232872212688464691036260746751992072745518373073825852119460094113694393273456369345499434994672730920070410547163082189385645712866100999708173472360864669110044660667614583576570496399103026286828660558854973376227247132815728164629722965145778698957093136175449225024685874279280018547740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +INSERT INTO num_exp_div VALUES (6,1,'.000000550624150700285432940805295709861455424264970126953321538967550091614148982212874391026630805836518138806917934859138493583812313778188030836027246840794439412443826640206464415527687555214009725107630387889854278497875708390050387195108441635824296563108288712340902423706104029452615686971019125750530034798026103476074158922893374911891438688457439945897348811702908216883650280617098402133628688982793791562476980709924382381505517834196446365877784931355599480881104446907801805570471686295270927836995181422963320376948188855989986414581755633425437161760674162177776773597848142496583128607548351599750592863590334617838124741567654525843413232313914310487355539260264225486180000012813397807525203822863232682089295055713257835007742845010741137213301116647610033909062369843750685396196342928455') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 270 +INSERT INTO num_exp_add VALUES (6,2,'-994877526002806872754342148749240.99659316232359475297606895243958507460511031229368344962653674268847910587702140353344168594152240599109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 271 +INSERT INTO num_exp_sub VALUES (6,2,'994877526002806872754342148749241.09046730671373705476503023105513751542110329332278421699361618343639171319297340877148998204440427879109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 272 +INSERT INTO num_exp_mul VALUES (6,2,'-46696638263247522384986521136500.479312417066793299922708112595886608370451213741279484136907754744903470430131032928908162742687359367826808123516519335458861613010646992354378739165872253762686683966945711430182491860196341344982195078000259063231136011430995647812149294224699587849791008794261026932467933475782780') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 273 +INSERT INTO num_exp_div VALUES (6,2,'-.000000000000000000000000000000000047178744084866106587600962473825168237820701199970144691815329658682341685812472535816245052671243808078367856957579485152424914481414614360809698177236664771558713606961423658442962083541733004775309314926918118528217478256885324362912426275407382550929085958089798861918760121727491366034496581249711153289495601712583077918760003840368008056353090552282274780428335438032908213783490070198414584291402513547386013689752310173492320159738977752795528725029134841933604057954874523842273790958618375118974623107241366036640538085329921129023905888674299774726871808862832797230915933851225308164365269753526489223540580759951230801125605963901491073619448437890841032149898629231552019804656219062534881074125995130202820302133432951999011667568746004715268323913437054078537') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 274 +INSERT INTO num_exp_add VALUES (6,3,'-60302029489319384367663884408085757480.1853341682137571584926062805631087054017160819890685789064777236456590745415460695320768374693076860837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 275 +INSERT INTO num_exp_sub VALUES (6,3,'60302029489319384367663884408085757480.2792083126038994602815675591786611462177090630181693462735571643935716818574980747701251335721895588837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 276 +INSERT INTO num_exp_mul VALUES (6,3,'-2830400711649493468815157129316992649.40542786074520931471973065281957756940496588853021620372179463538053123396140685749478530925306163968207226329985017644835203709485594362663495728106061878665324856417118064730721101615473194292620972173690618491026470353143141125614124440035267592258385099934706896692953497971326605145704135723011753705907329979207428661473172503098296622281647255008204864404416199384701720347319806375450632245634238172654086373193251877533131784268854289406126119630708578053354762596511353053106459297339360827562281168219966099848212') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 277 +INSERT INTO num_exp_div VALUES (6,3,'-.000000000000000000000000000000000000000778366376597400971124059102619954214055884926284646546105035591052258074563706355894551049631537984053410850060739107742208523938741961208742831871056600773325053133977559789796700130019975964192371715826863472981072974742704091801166438465082519558956925444635729210849210496466189037623555622901738570979273502405907969114110345815802999687171113749364073269902319653450479463404003706147915064100959774312307195946966281098140229199529866429134937742584938255441169541436021827079647129394362379406256722903991353136733939395366152312959281905058592776286736536360235356737359904478313225848562436632109470589310799000750518904145312512621838935796912993778920622238202744037977772169066929474233952081158212174549695244127987299282384885288897893503991509410567351494') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 278 +INSERT INTO num_exp_add VALUES (6,4,'5329378275943663322215245.29625473207137544719284446115519970394719946335145777492574745992986971075733570324679065009803281404581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 279 +INSERT INTO num_exp_sub VALUES (6,4,'-5329378275943663322215245.20238058768123314540388318253964726313120648232235700755866801918195710344138369800874235399515094124581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +INSERT INTO num_exp_mul VALUES (6,4,'250145412892811547138949.592621291590152419206270097656346630226508074074623894951308487425470437268130465956063593951784820669318897182831355375451719125809800516979013437732298382708070979871283132689492336823087794373113039154669229889503700598930220858275174342776478898670277868700384853696009897221747924643343353942154528501454689084608965009561564638167714973711022212547096732831847202912862290958304510651828842182545311077713664465815992616213663619529378061133917572474298028065850515876361609671565914027186063801852554353160801534696062207299890867876199323530337336273950892723090754719547285920090419070001019943385293110663922226230169381423410428577990604776655422105400452217085311617728003688836185608912367677734364834577573255789160419371322775733777518997638403409000055707558465286469808848200141192627396502735') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 281 +INSERT INTO num_exp_div VALUES (6,4,'.000000000000000000000000008807232244507937251856465017967626593430084223212999583902527587737263981869382895220711835510154989851222501080395520249593128253795609198666884523792646863341248402687314509176781281863891589925961900674092953408613128961234166906173266411035009516545964362406728942021813644419154548354247112601793685146960840364604115937119024575638240439041250900118977183124605578660115160551830946251713350556181960983267689939549506518185340972020820080460565392359379680036788592213479105831301723237102710863182596413567756605711230290883888612188805367801369264231165178487334557824054205160222371548005742602736713668548450400926514169967213301919971189065307721110805424950794015852531342286935114651278691214233054575660712537044810163930633456573860895791198853393107188289695511873068') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 282 +INSERT INTO num_exp_add VALUES (6,5,'-652755630.38762364608541718463145771120672223443489913059334543712856431450577465795351472116052777583325262472505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +INSERT INTO num_exp_sub VALUES (6,5,'652755630.48149779047555948642041898982227467525089211162244620449564375525368726526946672639857607193613449752505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 284 +INSERT INTO num_exp_mul VALUES (6,5,'-30638438.151446159804025029882398388155309149089870990062944469684482366692824338098201222171115395923414887930224163525189097571163687285244255335505387733673499447610577050114902372990462064696637481657064525319516004273769831260452832960893174173254560250804003884280384718123289136453955482855362019158401218620018346500189769819687260476334734259702665316562988639223597110627626759216850014150105605927773639897638043177685498804811787888811168524202700283461266793154726325540776914500415140842975457394524215869103737379109516024460317825645645301237375972914247141703084877141866316168268901439172491577729880760950895760711857112463508064820414904611059588717092145484656103798852859978690742216940980929562068') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 285 +INSERT INTO num_exp_div VALUES (6,5,'-.000000000071906039575366987930696117572143566208825430801491864851999044659045681114433294052065377679745375399878664822361548237094424148992770296383642432040129230180142339557437679166815114510467763288057917694948929009212876391059413439647163295629904270262780935228234994930653489111444964446097124407804311494588517082748514970905563707392765567625639455978464081409330528324962333492925267647686759704415549221137291475247571296491073010175087298752769122449499990102435819414671847617062560524758344361194566796343756743243766853291113852464023843527189221162680613675369708907935197867458588904367993736363321133720345058432019986643353417257503619558797249295232894674255060861358071309619524800424087896023710729815248847792174290644245138831518072176198607255346603270853333176255533974364728342822') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 286 +INSERT INTO num_exp_add VALUES (6,6,'.0938741443901423017889612786155524408159929810291007673670794407479126073159520052380482961028818728') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 287 +INSERT INTO num_exp_sub VALUES (6,6,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 288 +INSERT INTO num_exp_mul VALUES (6,6,'.00220308874624532134736695825088747995945783791378828770826401323533973395137378460250799184832278118133622563295093909508983301127615815865216895482784469538070133388154961402881325731054433770884496') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 289 +INSERT INTO num_exp_div VALUES (6,6,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 290 +INSERT INTO num_exp_add VALUES (6,7,'-818934540071845741.9530629278049288491055193606922237795920035094854496163164602796260436963420239973809758519485590636') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 291 +INSERT INTO num_exp_sub VALUES (6,7,'818934540071845742.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 292 +INSERT INTO num_exp_mul VALUES (6,7,'-38438389630389612.0042045464692275627184627672063157323631169405883031379129843031477339360597564128205768842448328088') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +INSERT INTO num_exp_div VALUES (6,7,'-.000000000000000000057314803440765029050667129936880528769333499793237773980613524885506515999851858649385968476426313207429914995755091541422893944525222307473169425244462149015717526718376299808423552027796204632286454853167559026787019718806449038446612978917236245943248168920696452018925986743620392955122431521581268518101342690974749463089739042586011924590503136498488946387508310209984849243014542648765897536338824721211252335866349509669538308454367849024503312249951727948786393404944555844863805495937835281927012430439403132382055464307180153473189842433614777883826783689904293115204700185380661601223693428304020047393499702811581067120117405280772944184877279069842269329959037186324135435468322336398566440055479142909170224780318371473684868152271947368867666706912563225912012901437076773416') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 294 +INSERT INTO num_exp_add VALUES (6,8,'8496986223.68757431572672621257436634648368772473081887846765003074279255322456188404621827857612554765910678041003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 295 +INSERT INTO num_exp_sub VALUES (6,8,'-8496986223.59370017133658391078540506786813528391482589743854926337571311247664927673026627333807725155622490761003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 296 +INSERT INTO num_exp_mul VALUES (6,8,'398823655.819545574205652791249227663407026876411660299394659390409794761643751582473390322547798567169668246138880832642141417531427935520467563318363116897177899262525720710134129529640376020947774470933902793259531840625444267816319963200') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 297 +INSERT INTO num_exp_div VALUES (6,8,'.000000000005523967081937952184172713994498918048454262874017009201501812494019618863622631634736130436187167745347383745890248619882896153083428308074678908731005176810208100004498415662458272149380846809398637385270265351808328466537502823071145089961996689711299405627596294988646826454676198092260759424935699382655736524042353938814268760468122584678267125994645166955751211397353140569987758938572953312303398024147927938612934833827734142292697389251052485981023756760420972614486278837214553818521196182883489483756785207650821722660455451660719560529693418375773124813290305501923899840247103166971466167032437598057958226806335324315214908788839919408525748236713611579486768218564733151121028172253396652755590051310396973181595992981076269789287489208817712754098019817792758730835341151711523474207') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 298 +INSERT INTO num_exp_add VALUES (6,9,'54863480.39378734225015137845671346015520435061071252892396685718794832880965812803098645730572474084523997120024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 299 +INSERT INTO num_exp_sub VALUES (6,9,'-54863480.29991319786000907666775218153965190979471954789486608982086888806174552071503445206767644474235809840024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 300 +INSERT INTO num_exp_mul VALUES (6,9,'2575131.137912978352131546639620215541477987701194164886305951830806120142596646541302305984776928560906754259789485960991272272782091464270104432109904222200473616116525297615725803495463468272171161659654385929185160689572943852767523792651123455283534072794326647404332228203001469884016996499768656263775233430922446983838511590562929268821678518640501686017030536100955531423152839988008496919169395159653034847677470665418765966542111749439412') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 301 +INSERT INTO num_exp_div VALUES (6,9,'.000000000855524875533453524582534418967571681572635027972658867593464437484123442242521660317156546196609749230372398872487667521984251509483676665788527375343148382604836976332389890799079878151841905152004537926201190193814594954194044560537664560344224646197027029681984683465852110060077865421064400958821808374370779297676624123638191407441015008434084079839721156870032377372497814037418047056438760664237367081226979226606227037631073946209105678283624370820396871058367779887709720661001099338250009251834581804647326512873792849059661525874160414378459696930831877643599421297749483849526695657467708603491876916749718079725746259119898269814551222336219537198318796277931946529242436502235147453584237994498566122973953203597470078105606906752099294162422474758048436539653041606499637623370030079916') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 302 +INSERT INTO num_exp_add VALUES (7,0,'-818934540071845742') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 303 +INSERT INTO num_exp_sub VALUES (7,0,'-818934540071845742') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 304 +INSERT INTO num_exp_mul VALUES (7,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 305 +INSERT INTO num_exp_div VALUES (7,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +INSERT INTO num_exp_add VALUES (7,1,'-818934540071760498.60459975022373923760152136399214017262844141729040109985386964272131706381326192223266583769046276181472898406504104649192224392653722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 307 +INSERT INTO num_exp_sub VALUES (7,1,'-818934540071930985.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 308 +INSERT INTO num_exp_mul VALUES (7,1,'-69808760806266041400340.70700818693892852138813934414383886494691670042143650609934777814995087699409404201920249076407981012095999320858479644760715204999741683528746097757549835956359129287002171391961763797857794730120426599135099619822532290339000466211195776337667123320942107370731349851576864242697412616810236323676004067839744992733887503405311090677026008324895177587064547630828026123718296429295638934384446325302964896473296829265805737112709269803814942537657996725913938408781715328945194948010970') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 309 +INSERT INTO num_exp_div VALUES (7,1,'-9607014551997.140858001442365669993007297071681832468350855627077185145567261170534005832165603932891201648027598773639089125980996652005412450490063683624648655909636499261774535015914730479401090227915382926027949990128880284298688443593909017437720828163877690126019616194376778317148693270900349151496295698078575648169637635898560612738481294674167553369445426793073304518646116539082953755973571046622684332425840412198776081251646424875405772676893185726872613804612566569794177506268399878105117763696990094108960076591684779180089885283939385808214239337829666227427148603057941899878123459708920227867371285837642561064461118016739395972994827327543594846953341750907541716807985738518071480209106185726125017342997283356926976052909493074301401955202616191210810331245427141945840542129607439703255628683506772979') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 310 +INSERT INTO num_exp_add VALUES (7,2,'-994877526002807691688882220594983.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 311 +INSERT INTO num_exp_sub VALUES (7,2,'994877526002806053819802076903499.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 312 +INSERT INTO num_exp_mul VALUES (7,2,'814739569184924399102711674444306584731316176345067.39834031417849342571224916231092924046722938910652929295271097903377854123984307101079073134405782275535446337229706620713104545454319555885847481531722101704765783025789147453570970090') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 313 +INSERT INTO num_exp_div VALUES (7,2,'.000000000000000823151110229758332661330617426417726331211894330147399760458555778324097596176117291103184653828305857999638466183347321835058943563347767579219763002258622507889760416640758842509635599414768344140175277742935564567127659688612699366182158030839083982896107176174766408199870924563237827899202849733606842856491701660599599211106794572237923985121475458446997860253437578966578617985764298513928307852082168209458400544457824307270777530312648199364084272310536024283945598340590403612752287693234647719354745060851129534452514828239800716088248915975054881011343555492596002595181046121935660176097475159074973635534016835214952415720717896518544064238656360099884889450237541254761746029507300068198731306211736696956568648033834554273602524147075895460874922913883751452403825099444642503437') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 314 +INSERT INTO num_exp_add VALUES (7,3,'-60302029489319384368482818948157603222.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 315 +INSERT INTO num_exp_sub VALUES (7,3,'60302029489319384366844949868013911738.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 316 +INSERT INTO num_exp_mul VALUES (7,3,'49383414785234649002982046297226894664526726187218771083.0993243619030008310875293647868815940421844461627295157812843657782639833900543200310573708100000958929315945039020410482966753145208427035917753919085618457760620513481628641658765820294863970581642745379331727722585319163262763708386199720411053619449096019862596221607526610103408936214184850115071874430846697061554769773328338028749631552202705583855831155461651414320570061181212214810086436100771547030013079997847086') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 317 +INSERT INTO num_exp_div VALUES (7,3,'.000000000000000000013580546907080371873577430837141172674171921610919544849037647398734065712983603204704663262116138799357430947986241590690589753181299773842880079777640016786921825609617596862828930939366173224366864448436461306602680780407912534492687474933386043505172346330210659476505435994582446405414027199938970759003336829722057241708213838318628292667946636226143164221380503228191376939596663443230082698085439531600756771639601022064620204571458766303985028143400866776954225590745596639602613498355332049777798367675438365442468743270334407716567057368347458892075084694158566383133325959042076573734408841629149903649365079563374278550978052491499304166424686842598833319515705663176855033865872333988551611996194856472662292344160194821687681312501127516922809221030420253714666026321243515830') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 318 +INSERT INTO num_exp_add VALUES (7,4,'5329377457009123250369503.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 319 +INSERT INTO num_exp_sub VALUES (7,4,'-5329379094878203394060987.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 320 +INSERT INTO num_exp_mul VALUES (7,4,'-4364411947278810125327066890819882483326918.05664098958260550284395870948992407314161088028674246708928421994893923699743452802989464864039994566042797942433140378990308345483670828497915478397481687305406460330009319949623844175096007381662809083363069100235985794575399268709260901964834244796150883807308976949196661411035264619638771824190014274817662519438658481432363824187693821267613212631153175155634316128036152465184903927860719447693468054624663668062006049759837326188252927823612718163916100588143128358998656306593393889422386501730237442526450419990376323903182669190482615734972147533221144682538647497701130447816148459762464395194383090936159579764712919396391813914821973715879062992249315474841639591907249142779103650773383644785606333916967894') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 321 +INSERT INTO num_exp_div VALUES (7,4,'-.000000153664179510102140733858340480800294287837601105047285453457000254577644933901525444082336054243749405512900867540483190494113677173628646221933766421338612376123824684592850465460156248403574333545090544920568230979754949827013129083778435107488003838746926270955224758508832133483591156567868631938590248213604979638895901933775098150684618378235712437137852195098700137765601802898366867034641606131280434771339920637353140131159441790904703083143627590062236537714415872864218260252838432414759890832271190606933534662897006726154587341385852258168335058931957995901987808602365467861573344491265289043037273815504867254228957776127752540924854546837197432384563153608878864912196453587628891285275067452280357349897203095502806923463147414086919014592380804424300739713935051357374227246098303140106') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 322 +INSERT INTO num_exp_add VALUES (7,5,'-818934540724601372.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 323 +INSERT INTO num_exp_sub VALUES (7,5,'-818934539419090111.56543928171951166447406164948550154515710437889210417918789596512026903838850927622044807611530643887494456379304996563468607210970486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 324 +INSERT INTO num_exp_mul VALUES (7,5,'534564131989234694540350103.27821462973515555648644772098605028371173048154132108733819196629002548296868548691993248746628993380136454426833349407578676005545111508293942736555269938962058196496152360848131645787941032968937794930046928523006455386861100809286408671908320322523368135203881520526880998279355848280412933152306299256343179622513731096363088094541514890135766460631462465021694553063366717467560655272004461368865264059368514271105464855575429914212085797297268595943955105608543373940035636033207568676745293499106348500559628723682588033431457023964317090780615020801564861497990103549650624438425421690193862533733474254') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 325 +INSERT INTO num_exp_div VALUES (7,5,'1254580584.048971438599349046867230181719371038956756285986415773300837165755558702217197735811549684202279755101552533605390208155708695952004683670878589028717509749282693444655857296902117478518511492735290086040573521482737598395369632843374456793385511847676556826348943588519880411018079886373631771830925920986588708409208527042927229627786932908015502292313887561198156623702404977221789649731458241770690830680067801377815840764873662400590343236662968218256211697981048576328148435241545372543075051594952109757428031762469834781538302930957095080167901199455226976113347018972534334210416375400979738414416582588689496706548495076287263281908191770792203069614447622517839588243746755480572371988630084226963919158931419126724681617069720048557166545204944250492282054791996953359013543036918134163144772567093') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 326 +INSERT INTO num_exp_add VALUES (7,6,'-818934540071845741.9530629278049288491055193606922237795920035094854496163164602796260436963420239973809758519485590636') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 327 +INSERT INTO num_exp_sub VALUES (7,6,'-818934540071845742.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 328 +INSERT INTO num_exp_mul VALUES (7,6,'-38438389630389612.0042045464692275627184627672063157323631169405883031379129843031477339360597564128205768842448328088') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 329 +INSERT INTO num_exp_div VALUES (7,6,'-17447499423661151023.558342555162228919125358089491573318627107322332520978657843895009110781773496490472817700487707134216424855867015781267287628022535529641238372370292374146871103236048507252055787621394728096799222976387108688980537900309311204203302960751747509648304056939321473462375648710590981564101023812800603438271190184064874290215309040519813024962909469701968804925443161094255632624090623433640078421818321246597728308302979223833487133268472455479442002005374793705431817866798804822885690193667521606781156962792120052947767160957903073698536973292205899421787948529970837601521657406211962967291912148632072929662185840265855612193255596825032457033402506154930851214421895488796227471490998190312007513478459049382774782886773158311656817014322925167278223360446454868236479549745612973293185989975394307678926') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 330 +INSERT INTO num_exp_add VALUES (7,7,'-1637869080143691484') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 331 +INSERT INTO num_exp_sub VALUES (7,7,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 332 +INSERT INTO num_exp_mul VALUES (7,7,'670653780922685519356619170643530564') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 333 +INSERT INTO num_exp_div VALUES (7,7,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 334 +INSERT INTO num_exp_add VALUES (7,8,'-818934531574859518.35936275646834493832011429282408849567717761204690035294074716714939441961175772404289860039233415598996234758590850206505669201200') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 335 +INSERT INTO num_exp_sub VALUES (7,8,'-818934548568831965.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 336 +INSERT INTO num_exp_mul VALUES (7,8,'-6958475505053954666339703437.48985528725312694198056665033448258303533387675711770743843194274181580881296671866212320171337132096489224277825857521033238709600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 337 +INSERT INTO num_exp_div VALUES (7,8,'-96379412.478435590945480884955616049873645089637121682284625533034225619945532704111492738646389632607594293500930307222576571876059094206480673293295865214240456906965855425738072430281475736130342229749511650392658808510082775031098547507966544723255869156056349218776847523349173551313282283869146710349521487706884633419341568648959204688757523312579312713453540395840470692533267158388401676533369105590789036132185107859069994833345453200014884023709597817280132465224778002071890368479648934317322270613208789859930618055792958996389145963056607200020526949699302565905917600478429628844015684879886549766473809801710003649193772354147104446894109928903223843036925147624639466770660174828940577089095480826473544099693433597812637069287644606693066736302793687011165899362920686114156254982709172925265118077531') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 338 +INSERT INTO num_exp_add VALUES (7,9,'-818934540016982261.65314972994491977243776717915257186979728396159058352649559139156429817562698954531329940720620096519975256547379603654362598494779213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 339 +INSERT INTO num_exp_sub VALUES (7,9,'-818934540126709222.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 340 +INSERT INTO num_exp_mul VALUES (7,9,'-44929599044588573810654775.83678007633232843418115790847152455559258007804727916986432256198687661496804050903769496933400455947645400628259699874770581538122521805603947464462448454681701547899144129061961394870320463199545502030106801911915987309444301341575451240764927967432593181449618816978119423290767783843864768557371257918447461479570164065303599994081990686') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 341 +INSERT INTO num_exp_div VALUES (7,9,'-14926769772.797708334489652004325241753714626257641081061212878627972973992233480868793527325656854681817156284203427388055525855608883067129036717726368707982450450575794623567027457808927082390474261155500697096284790656757163047499531247323702909360444831707029353441147768321257650234732286165724178549576948957405037843360446785505536809409054071975214796532504678683693402401018726571884721963641317944453797513145055081061680091585467186975354801535734149952115333241283186621720677488342266420359417174224757781125498130120775969091933838082305123652811689513300403051544682523761263183781206840940347226802620226164265210810994106136738030959199259066517106713585343004140573604437146025585149934286364795122716971496775012412420105368351774715982565252533025207453326002101655121126631180162560463548157187175671') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 342 +INSERT INTO num_exp_add VALUES (8,0,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 343 +INSERT INTO num_exp_sub VALUES (8,0,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 344 +INSERT INTO num_exp_mul VALUES (8,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 345 +INSERT INTO num_exp_div VALUES (8,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 346 +INSERT INTO num_exp_add VALUES (8,1,'8497071467.03603749330791582407836434318377133169438097066269854720538319012928851657498035372443556191720308219530866834905045144302106406146277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 347 +INSERT INTO num_exp_sub VALUES (8,1,'8496900980.24523699375539429928140707116805167695126380524350074691312247557192264420150419818976723729812860582476663647913254442686555191453722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 348 +INSERT INTO num_exp_mul VALUES (8,1,'724311956372274.0135050255361637906710330203036651743488213007179039756514944640108625580172737414192938789413338554327986697518463087452612658955180411327002900979574347739956600177846996063741787205122007268468674386396156638261992679442768654367111433834151087792255469957061758837789341439211010331332174981459471333376067541234901538285101103690622656631026001337239036711179989456674399137008584021283568040818388709554256523118702728176420022080138548890713013682480239784198421500241995499841675772793497485550923152267616622892846304530712344886979674416990935007952941652591352603797627920865960622077762568060903908151958000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 349 +INSERT INTO num_exp_div VALUES (8,1,'99679.115123747637190903598543851248555278745675862923884476564848911494649941770503156134872464666625927195645517181131678518619856156844072856993813601495176097972982587061507650426363887871820112714099226501603733968262566093655417466145183587899155614471697804006772915054739361437054029183182533671508695646413074668188590846200362324428338974890534273352188276373478524543505805545661569395314989170104140776362043880099775594658817242753124957385625811310332354760117110779649164022618274859298031549851269619167173746259018497289174255201452265070501056913033329291819570027877856677145579673495987354805150868813877928857472561883332547900866904764950837506993759536410161752469488392566682723027340638271076406246129989851281210810196699482980833204884400423019400653089825859983062096326294783573417554749') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 350 +INSERT INTO num_exp_add VALUES (8,2,'-994877526002806872754333651763017.40289299098701084219066388457144979069028441485513418625082363021182982914675513019536443438529749838106171095037135009526312783302868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 351 +INSERT INTO num_exp_sub VALUES (8,2,'994877526002806872754350645735464.68416747805032096555043529892327279933592919076133348036932929591304098992323968210956723360062918640113701577855434596514974380902868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 352 +INSERT INTO num_exp_mul VALUES (8,2,'-8453460632655529853033389979024265783461224.3195241893307807116624750282852146303290708492834695194274289713076935297734670940696121761483641291930931061232942894577813178566088927221374036301485916497770984757492912292002695944367308880163698595015497307574177176409203214324418237020500352652934909632442547242092296504047310806151851207329042221920888326000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 353 +INSERT INTO num_exp_div VALUES (8,2,'-.000000000000000000000008540735921314463871578184793632135730756619558669911183806487803411545406462244216408739432325839683804021466133071768612386706692296158696852363349481716813410857655324486448455846562309041306880675446880859847445987588059144788756984750993583865748280824370754934966494724951583311563735533173023858438364336214213295786266815116844775733072416507474834701984381586060478606371028156925222726225495235702395502085206072985373035972506738983640539009567237336002073370431753469632428303255926718930619221521257726366850472572830063284204851204189447233044832163423057501488364913539948261528280564870049935369825245920984413480757133585498984374354957754078525161296201228031555280486615145365039415418251448980923331334883673792135893857917681235883506783408111446970710546686739582471') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 354 +INSERT INTO num_exp_add VALUES (8,3,'-60302029489319384367663884399588771256.5916339968771732477072012126949734214868901845505193155307646111690097978112797961939995859130827784737422228762767014427842766445950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 355 +INSERT INTO num_exp_sub VALUES (8,3,'60302029489319384367663884416582743703.8729084839404833710669726270467964301325349604567186096492702768702209585877643481082023851284144664938175277044596973126708926205950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 356 +INSERT INTO num_exp_mul VALUES (8,3,'-512385513828318260570283740065493064477880918352.732624553690077857674083796435724202494963885926573907185100543184828131859183999195040110586155435203949963570735841632689374488877298209082579317039061893012560130258753218955057387206477423088065663401594359617882154814262843273526859406265633827109554791772242178864873774889091687515990672487380368975556580539271333144212685871370972163560839446696514092637412587953506052848750866803569213269271165856310101244342151576488190595936869490659700946174362872797854591188391982770203203644172999264143929484089237665313698600170041324566984832357000400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 357 +INSERT INTO num_exp_div VALUES (8,3,'-.000000000000000000000000000140907135225782279761112255989433531718277338909398600029580768021365259747075253760824424092983497958717844671162530550507041138147836569244869107757945370200122955794509365120853536859837243314494576053441804831018954867623755033888264275704547752628348151132333655667171970175829826792355986148522268067032057293494927558322394395160508723637192234110428953945018965078022622950949911124494740703606109543716688008516750321047603009424529696862953094999450658951089435460411028678817795100630449046993274191915359520936265372754315076684798942557329584282177053819106884196674660057281227248874819417305259132106690385871316407455034281900110779740008476645291647094776093567400422266906817555937149628005629880142615126571231411138926043531449659320501743591992888328328980526602') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 358 +INSERT INTO num_exp_add VALUES (8,4,'5329378275943671819201468.88995490340795935797824952902333498786202536079000703830146057240651898748760197658486790165425772165585380839129948178510273188565692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 359 +INSERT INTO num_exp_sub VALUES (8,4,'-5329378275943654825229021.60868041634464923461847811467151197921638058488380774418295490670530782671111742467066510243892603363577850356311648591521611590965692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +INSERT INTO num_exp_mul VALUES (8,4,'45283653791262997781451381354094822.762732909505051438036873220502792213670540454778361182993875916509061144859281577740137081988678361247725064336120451090222456518107029158304937620179032477664627949959143233370320432203497828243297406462513350790251761540074946469824444452248386782451723637769289822576372357189700319768797708375563651655860093365309717823602754924352327588945034832436331911584742966378275504545736896430718939807674966738116698454215555860047859161126694019895490767779791933882712567492115664113775047192011252893773389940988533801360010782816196288710063568554147458866942816721046004257953642508395867837127678980002737669139369781058046396738606563716339660654364541530532834806205571191828994250708412638796240377704994928921528330863683630622922959130920715261879547446054261914770022377059156125037157979236658010950') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 361 +INSERT INTO num_exp_div VALUES (8,4,'.000000000000001594367257057971052149628499448029056279649281098852958322409409919964709324200796473211884339143791758566019217634542932882694487712398244322522748736692741288668885362384266615527166964187404128216235057387796054457728789109537338988453837993084016408244895452291151218602815057669592284587317035387004942691671916981967449109983992675125005085762403043329820872839739877674121174083273716295673230993049263574856197011389828478636779342320299895806297835595427859271617831720398457416685435560152182883615601663820189195644140652141180949257192740185075408019971747810015931542757445763460947106918998459997631117642552273815713467150465548031203738878873114842844016176922502916339025283749846225376341878386377192605865913018132981323065698049618379727531925408677611856682983907951667054819') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 362 +INSERT INTO num_exp_add VALUES (8,5,'7844230593.20607652525116672615394735666141304947992676684520382624714879797087461877675155217754947572297228288498221620714146356962938009770486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 363 +INSERT INTO num_exp_sub VALUES (8,5,'9149741854.07519796181214339720582405769040995916571800906099546787135686773033654199973299973665332349235940513509308862104153230025723587829513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 364 +INSERT INTO num_exp_mul VALUES (8,5,'-5546455599206321494.0676583421119904300307105296377723816472192007866147764761501865875232824814135783697976183493106885436876081315217834621720906478074798596116645640251460842350553806256223963023430631066024389364515688765194373161385579258482225808660340732705687558150699172147896486727530192499184101617379930846663835628510376484675411350654979679181852179924386290069790336316958202582966248703889464308649631486542724072047294216362186036638115240070658004553260251510288423749333873893917690832829128021808383128393431810674177390352413548658782609064839524756041501835115152819802758773711821322162752064589750295542985780512921839490040396053737870038534216948323935020460307350020911362024271167085905714873548388570602799432705061561572854498075600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 365 +INSERT INTO num_exp_div VALUES (8,5,'-13.017101389051085341042057308965769356145255575582875626848796382322826525772114256699384710400140437710569924703769685567402446691691210934185000959063158239023412379691360587119206695513775971704926722817528818197919265145207032750407924774510773427697188520818450702875142190949766251178733262143962213111236591970766836685919581025629742334704854852196126735685421250263035895756028805974153787560164935038227108975229771590754808331856162035119882347418116049174638416621093907738608991987582465865527947015457540650512339263071898410531735438556948115098562123055444965056347091625748703503220861221718449714020622377233272042277814766996198081939221253025243417993701684007826177845003391944496774674489538520354606358872276671998045196738090133576377830721671972381371985771591052597345572374064920279182') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 366 +INSERT INTO num_exp_add VALUES (8,6,'8496986223.68757431572672621257436634648368772473081887846765003074279255322456188404621827857612554765910678041003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 367 +INSERT INTO num_exp_sub VALUES (8,6,'8496986223.59370017133658391078540506786813528391482589743854926337571311247664927673026627333807725155622490761003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 368 +INSERT INTO num_exp_mul VALUES (8,6,'398823655.819545574205652791249227663407026876411660299394659390409794761643751582473390322547798567169668246138880832642141417531427935520467563318363116897177899262525720710134129529640376020947774470933902793259531840625444267816319963200') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 369 +INSERT INTO num_exp_div VALUES (8,6,'181029319177.110996740664566780784253502559986936959009611748146099327460471609593148344991059106574612143724330935988823134137686051475120980257829276671900076859337187540608483895641504622910361858962883971613675309676443079313179200981488761707281247447120551917205792352229666049191991270809865110506639390610910481490688182068719005593641339338678014189749279508731647492051879768743158839680867283217578754666643688259810863605002821607490100820241093473083445658378988069593782353275713240897038366242558466047071334385431080003439842348547427066389352198560236731403235927478177780757802759046212921140424771887928786549573201311120885052685761195784207710933764480136690216943336587118385525047554334029388869436622866247240903231799829259264158812528305210833683370536416861544931420820452512390255774498188962903') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 370 +INSERT INTO num_exp_add VALUES (8,7,'-818934531574859518.35936275646834493832011429282408849567717761204690035294074716714939441961175772404289860039233415598996234758590850206505669201200') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 371 +INSERT INTO num_exp_sub VALUES (8,7,'818934548568831965.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 372 +INSERT INTO num_exp_mul VALUES (8,7,'-6958475505053954666339703437.48985528725312694198056665033448258303533387675711770743843194274181580881296671866212320171337132096489224277825857521033238709600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 373 +INSERT INTO num_exp_div VALUES (8,7,'-.000000010375659845651632013446652385870617923988120764298690164486716047614260682259722116360931978511176121353975789418625836899338225571166376573732227571704071000348895791547943896682585450808398324252224265156214259224488248639550967292466343168350213394398101712526534464002532408445204630441167137710565437434313424987517531891145368203998329086865151248833625645567863740298397742783405267970015165358620026813812552194344790169289440822038223606218360105618852154152168496637886434061050281055613760360200323363465925493033734895631921307644481639236601187225135325401868178006133838932915485272554505684060229409404902185944047523033315868230944723282246159741659387362889777495094736963530708159604929268812778894177095572578862150793098548829744006499229853198046828954650334595737117597239208825268') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 374 +INSERT INTO num_exp_add VALUES (8,8,'16993972447.28127448706331012335977141435182300864564477590619929411850566570121116077648455191420279921533168802007530482818299586988661597600') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 375 +INSERT INTO num_exp_sub VALUES (8,8,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 376 +INSERT INTO num_exp_mul VALUES (8,8,'72198774884738777393.8687539247642452953425155400068591498151280875559609979248583367700231031634872342122563819478919600402159024059794279536786611373504966204744811722007869415559012475160471227957857756325962941799428857291371597146319816910515366298862558849452235442246081440000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 377 +INSERT INTO num_exp_div VALUES (8,8,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 378 +INSERT INTO num_exp_add VALUES (8,9,'8551849703.98748751358673528924211852802333963452553842636251612056366144128630740476125273064380199240146487881028508694029546139131732304020786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 379 +INSERT INTO num_exp_sub VALUES (8,9,'8442122743.29378697347657483411765288632848337412010634954368317355484422441490375601523182127040080681386680920979021788788753447856929293579213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 380 +INSERT INTO num_exp_mul VALUES (8,9,'466174236688165594.9218054325256670866060556227711696100465581464881295978997280335378678072434776702952026828137140986670189756965420183565968027969700090735690246176791371115610886533930223141650377886909408268207750238603105232560663571044993507074695683027062426288270199495225881785499139012931143826099668999261931834700467395442768201666740663642498098541516326470052372008385656719236306238735524802875519713512894448940917708118676095378518264553310312628830009314653641136566040400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 381 +INSERT INTO num_exp_div VALUES (8,9,'154.875085756903716715488911525453064308758123952566428258639786597308109810869086867746263482721081985848551254298524280231489145092826397833394044637104667137816928932471315095067524966582810436282901424423215992139000153713476369887383242289102867530775908269805285313842050961754114751975054515055089553180717444020378611767296609130477264722612784088270193199394531972594028420402254831778715196248487757266330454269044609134602570688339750190391651801546906342796660819535014295618246236706572780627362908121159003488810140236665846928586992082180006454824311789091323774002510945263351862712964422865623934112293184149374573706760114682326698881257123280119140924775171374360283137569618025005229268057970275164869735173660958715166148344076027212231446680947914004346760896298312286730627916684448923824769') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 382 +INSERT INTO num_exp_add VALUES (9,0,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 383 +INSERT INTO num_exp_sub VALUES (9,0,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 384 +INSERT INTO num_exp_mul VALUES (9,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 385 +INSERT INTO num_exp_div VALUES (9,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 386 +INSERT INTO num_exp_add VALUES (9,1,'54948723.74225051983134098996071145685528795757427462111901537365053896571438476055974853245403475510333627298551845046116291696445177112567064282766115207407461565363967417615506303416694032848457927390574251904212425813072768882213388082765916956736282110801611726537663292922699021333445658549608928179155685881583228490235606377831724593358583903616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 387 +INSERT INTO num_exp_sub VALUES (9,1,'54778236.95145002027881946516375418483956830283115745569981757335827825115701888818627237691936643048426179661497641859124500994829625897874508497095086558766563666622720535497438693688376602804651302002795213923698663694204683995198328880575615535181012624198813873609885725228117274934655048553507421448724831939026752650108735245933317237310133362383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 388 +INSERT INTO num_exp_mul VALUES (9,1,'4676749348240.390309875431213992853550297086049749814750492488995108783145961719774217441193547534210468967573344456866203963659951312519988497979489304488948342258375915152429008993288817366720647491166024151209542534474867042837694499222928509320280684557676243780452100132238968233413333851595648146954975713386711764268506890884764704949969602122157394714663532141060559896359465918874990769222345665160127552795532197771168442486088776803398878354288847069602460071745966589164282641033852314335279121191855487126430176047553895892632834940595958394834437871886013513058514896870683979585091413977173250824451205330441299000850618134248917380244749589254309567551846327349592529960432446947239714236828401206843011440433362544797025114476612133622499094287321570559088587999417440664282418005102546343020409520421747216') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 389 +INSERT INTO num_exp_div VALUES (9,1,'643.609749344751131516972294140174556703217311736700045690413622699888869645595256683013323517984528456698303984909359393772036036540901870537096836621035845014213031549051156299974682317824766457362427063305495772666640279328909129870227828460705733995380145417663304348663705694070309475835826101153850359826502235923289787750107778906593010060115662191620280031872002110849782776325630424918493602259707267214006217268630948545349980430128422952869610116216278256812581821942763705098526140427280008360043829906543029486315209818099697988089748683904695870401517598840185535891464842870210715421728852789815860153472208176465166954851895457846723102438114697692610933532992841803219018495137378534010155991355251803548866919409031477821173935696065078362044927492034445482457329200246282082707380974745411383781') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 390 +INSERT INTO num_exp_add VALUES (9,2,'-994877526002806872754342093885760.69667996446358567630831677089993316481039076439881735980566785462673358516198695146576524119916430759085192883825888457383242076882081857926408611052522393579396644731758241837010163568445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 391 +INSERT INTO num_exp_sub VALUES (9,2,'994877526002806872754342203612721.39038050457374613143278241259478942521582284121765030681448507149813723390800786083916642678676237719134679789066681148658045087323654637787610377226547625566084597844703238942080799221554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 392 +INSERT INTO num_exp_mul VALUES (9,2,'-54582443595378013373024060492546032003692.4875677735896411267274323339692558458420972958075073392126734000341372096298914875892612108329218081214550050039133117695428196702128258481789017059073444323729583900855712795086447886053552786449313809589992185978097430132940882612817775035217244553616977182049775786664446683332098226841743818600819221587510039430478859412452506872131851471967577741190323481953867845129745440745526578327709351120432530702446916035797432129052518980799424635406993848916727957825620638983706180841278402925286540375225365057191075559133035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 393 +INSERT INTO num_exp_div VALUES (9,2,'-.000000000000000000000000055145964114074763360265614481666934002579974728749248345352023099030383962250681574081874554842623852433135871821620640200582985140388676650602814646133317791813938390695683843848260103199745295436998313216878337673674660966362155480524935736646623766057029148471463569162153009963312016563281545776175277904913263614668092319707343286073000287493274965714031678784835459999763925833141049057636632430975424499618419962303087175237320046300285962065818926167792812657620724550768858763098967149546312995222223400007044549870620849992226072041407997925405957501929449911416474388622107825120486594723448780503829317691081601820425151593487431389373265285594626753418140874747955925763163132984655078996173911578832035721963554569605730262976354029623260224710106409129114204296314733036') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 394 +INSERT INTO num_exp_add VALUES (9,3,'-60302029489319384367663884408030893999.8854209703537480818248540990234567956069965340942024890856088355839135538265116174644003927269495876835324407641642359213535695803871472434650475144516723617632059130297610134243891145006222068960999879308472500422640481972089756410157246974765071949782242392661524488959954348903412713930092273629207697480131360047867213863018127928853922173643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 395 +INSERT INTO num_exp_sub VALUES (9,3,'60302029489319384367663884408140620960.5791215104639085369493197407183130560124286109130354360944260524553172025725325268378015783145476572840273098165721628341015996848028750420770651761919246816300854441592109844750954710317145008297946462099581451150385769713261452744310496166494545449824802407416426304041583975713483424241727236417259479541129474082301376239522310995725648773643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 396 +INSERT INTO num_exp_mul VALUES (9,3,'-3308379209762459471107480259839508279070920437.883503980178028214343751083865562028455061662673132221930429904398963590401793045470444301883103141901787466923883803951815572606105617157736442670792467625964359169270739534412932791178258858918086886061702512427989129732248215348301444245772127142869263635282888226326427510486246184233225114523636171202034558843515894542952126988613018789833835507734620046994907453602573865012044120483116345444810078666601100257620969379968264504287700045822481492526688635364586344704730579892342786173395802035361824932075736340405960099542224953439044947229246847140957298841482874444906129049023002897135347878048572628834749795298712449864571996898774444932083319581439741625832405434317985988163261591679157437224404970927012111196724239860528859217322132733404472897289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 397 +INSERT INTO num_exp_div VALUES (9,3,'-.000000000000000000000000000000909811507365065002714756487495210579371808512079908127938523896001746219475805196061435010714649189975968123072269549018826343830061696154665503565341929634172463095299662727352635590451263034658630449260378893723785917860125051787451512267088404686342938118993621396641623525252649748977992770709930435013456855344203854749977414354164157192885125263071636468941596567220391082793700307461350484216679632552883058303710297475827456761138832914743429330069022439380297715971317819244718196187172770061156794130040674050533617155253444764036426045091327368023602807193742585178432544430741520636125146531502042579276206322507516332917325631822606079220413965396706334639331097621824106950192993127113903265025719013680733760540930122186345919977470628988674677630636632053583144327') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 398 +INSERT INTO num_exp_add VALUES (9,4,'5329378275943663377078725.59616792993138452386059664269485161374191901124632386474661634799161523147237015531446709484039091244606359050341194730653343894986479159670583937529516163204904273806158788218327396375034882788180783796976731912141525319602448709213495905899041406302673881364465504945113279286939663215197485367850132991968081639290297033476859158044889351836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 399 +INSERT INTO num_exp_sub VALUES (9,4,'-5329378275943663267351764.90246738982122406873613100099999535333648693442749091773779913112021158272634924594106590925279284284556872145100402039378540884544906379809382171355490931218216320693213791113256760721925653394811317969065642404864072442190731745871963413981746671302248281216916486794296983018838956112081135739969615171358100498945955409711817327376172085836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 400 +INSERT INTO num_exp_mul VALUES (9,4,'292388240303165948041827159734686.255558469787242316676287235194652580157149226950109397295920730296960145548003120827363226435916209781396711693581454960342091452830648929118261388933297036933167543189308061917640517578583521401267417187854611829815212778183983326568586118831109538377828156118900313778053576483381085207892754728937946691892849474364477434665960112125254104966566712906532318984871145605839506991591027939136026602051635433295687547552796828217859648186757719639965988287173297286034098497871707197092627676226053609131138590878743560287292934815277894463305001278326023708395571840850120055316276256138004565442099731931051413153564744766098053176049414330146267604802971221161572130161432525297614616942172815141372973870720928125699420370428856022295499447755488148545048400795053604349570217878099721865670458104653570360') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 401 +INSERT INTO num_exp_div VALUES (9,4,'.000000000000000010294536718194523982241053267404812827031741197656209184880073175960433631103885281961037127283726462743623757855378209281373475473018922090781553213750339001555832360656399849031527008437303091226051008068950896796359518673740801770866360774945096397034708173365378527676779736929035450380795854046109380272505550244458858231227568118355064007614608452292270378691774826689216790090661497154742954386244856792006376222923780801296832612827123778915598893970651480451509706836620045721191411824060983487064555397842027454385628620582036592315345973096405447742002746762099231557054678593446667904250189208490698468539396733604833688133512716508825505666644390119877423938820483653319376926639295680552194966870285838815705038244628263602997511842285889300557188773128635554621378148419364876651') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 402 +INSERT INTO num_exp_add VALUES (9,5,'-597892150.08771044822540810796370552966707032464017958269847934730769542644402913723848026909285133109089452632480800168074607090893991283808726990171062867538012237270000932798704781608969096508450960185964292594677356241956277714380500188870696516251767979457838109804726539408115452577436052503866633026489282425086547752714324273565900641436632912781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 403 +INSERT INTO num_exp_sub VALUES (9,5,'707619110.78141098833556856308817117136192658504561165951731229431651264331543278598450117846625251667849259592530287073315399782168794294250299770032264633712037469256688885911649778714039732161560189579333758422588445749233730591792217152212229008169062714458263709952275557558931748845536759606982982654369800245696528893058665897330942472105350178781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 404 +INSERT INTO num_exp_mul VALUES (9,5,'-35812445701642379.972368737320206275515144213236752803936806738624588812089615098329765811617509505790110909629109400553415312470540217508070421816878544125783329593128638405659896184248784794258084116406472768709113030915308410565617764394827427154923321461158387012978726512246146545834669665093228316853342805604075936530371665576147966721599968786161939347726656168798065647411457701453987215491345496003650288850096338695703984042549594979897253521041581573388369367579323607093487743440894765114619634001789457486407909224339065748496715380572175183589195611952939575073075140094901024063428239223964510824958346570603142906309198033196987949067156046076497974760641964978711558209708743776024313916111738542765749928287600981397080809041007714387564206594515733287925008053261840295560398311905155157989225181164097547541') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 405 +INSERT INTO num_exp_div VALUES (9,5,'-.084049034261605466896663277055600903951276881294745183935726262038673990196778002490449355450474227878560465916800470848046625257516764244432096856845087412397406701521972651300484716852035267197801389708234913163750232707469240634303111868882057393120649919262424619226282082184091177505826009374043368623853156698509808569378758387708910629731005691079770517679511879694426434724918004419953301426679939010592502325130576915399009756468717124460489039474155719834555522581553817856854607844133431854471292027873672356863673617090151801474016666978499651970627896504709551656249007718965259502928591648533670568214972768900993459927860068104745163979267716597907297073374689384723943955361288974065531322408839914599555769945298758102515352082822617428033648130099822033393662643586331479103933840387663729387') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 406 +INSERT INTO num_exp_add VALUES (9,6,'54863480.39378734225015137845671346015520435061071252892396685718794832880965812803098645730572474084523997120024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 407 +INSERT INTO num_exp_sub VALUES (9,6,'54863480.29991319786000907666775218153965190979471954789486608982086888806174552071503445206767644474235809840024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 408 +INSERT INTO num_exp_mul VALUES (9,6,'2575131.137912978352131546639620215541477987701194164886305951830806120142596646541302305984776928560906754259789485960991272272782091464270104432109904222200473616116525297615725803495463468272171161659654385929185160689572943852767523792651123455283534072794326647404332228203001469884016996499768656263775233430922446983838511590562929268821678518640501686017030536100955531423152839988008496919169395159653034847677470665418765966542111749439412') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 409 +INSERT INTO num_exp_div VALUES (9,6,'1168873084.346566233232746391559830634361431940000227460271861554316197556566224118756340501278103405856646766537018954185964066240457859194626558143313125824412559635129130086906976028635444060218797992547370132082916380788496584864016645155338102476357490305222392452114945853620686975383081427840791892729407194179236897452655907829255937027286698570784397487382242990326347080472574546312522326038419753951437799831430690304084087684303035538181812523230890783372773953961677974396907303758903934808035747944477277528267001070234880092255363221274303820343225415479126819937070570562654065195009839593938440374000473302075568746771126391307584779249330981594640387657042725725493800876630516005713789705652827210295338592985225924959199657729900181287069808881130884115897407246324220524401243575641227725030779990490') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 410 +INSERT INTO num_exp_add VALUES (9,7,'-818934540016982261.65314972994491977243776717915257186979728396159058352649559139156429817562698954531329940720620096519975256547379603654362598494779213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 411 +INSERT INTO num_exp_sub VALUES (9,7,'818934540126709222.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 412 +INSERT INTO num_exp_mul VALUES (9,7,'-44929599044588573810654775.83678007633232843418115790847152455559258007804727916986432256198687661496804050903769496933400455947645400628259699874770581538122521805603947464462448454681701547899144129061961394870320463199545502030106801911915987309444301341575451240764927967432593181449618816978119423290767783843864768557371257918447461479570164065303599994081990686') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 413 +INSERT INTO num_exp_div VALUES (9,7,'-.000000000066993731076524206362744068866774567920404984046399050881532938231826344009126898802592302273719505485084766150904380671495128604515800845609713368334606489445184535043833069145643553083555507533900955661105251251918425885537513359541698046533092111969478225528665278023069818968531644884466229545497943710817187632203193468836772459599856856811131193744272314519908999458320275710240994009061040198159739169960258978462113813370513611735006229733329565083659159456172425715216475781507996483885669437855000029758892126410922067202159414570164537031153818197618428471046051340835826664787585016361564969663413176434498159140395476980277574789931364078570781760777773379636490084338326576889857824344578398580499610233575273027387501809967324874264742269453420400624883982643066864175851881870402856698') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 414 +INSERT INTO num_exp_add VALUES (9,8,'8551849703.98748751358673528924211852802333963452553842636251612056366144128630740476125273064380199240146487881028508694029546139131732304020786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 415 +INSERT INTO num_exp_sub VALUES (9,8,'-8442122743.29378697347657483411765288632848337412010634954368317355484422441490375601523182127040080681386680920979021788788753447856929293579213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 416 +INSERT INTO num_exp_mul VALUES (9,8,'466174236688165594.9218054325256670866060556227711696100465581464881295978997280335378678072434776702952026828137140986670189756965420183565968027969700090735690246176791371115610886533930223141650377886909408268207750238603105232560663571044993507074695683027062426288270199495225881785499139012931143826099668999261931834700467395442768201666740663642498098541516326470052372008385656719236306238735524802875519713512894448940917708118676095378518264553310312628830009314653641136566040400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 417 +INSERT INTO num_exp_div VALUES (9,8,'.006456816440893715330247418029019114736889626790871612141686117271826070935285769018710680035004320626745647926106882508048159628931624522666638442625219959259156539178378186912871506893482633695438850964052285542425753626455183282159259999492971992739484319464700978750304962671213318202670228197968646486740006148091321740497272644910882302412140576608739962605210964504469426861972705740810533465451230811358870068391007718532021526225893542801514255726272411690175555142385382688220121052891017808391607717500701760375927811435030512071347521837090721052128992926357375527600337655573639413811262412492632491693179011503973930804928749370652038245414768103001067902012962988384812280453070895781287237746786414435546976395632454474312533482077585837153357017362048554313154580576238549196250793055676215164') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 418 +INSERT INTO num_exp_add VALUES (9,9,'109726960.69370054011016045512446564169485626040543207681883294700881721687140364874602090937340118558759806960049486905240792691274803010441572779861201766174025231986687953112944997105070635653109229393369465827911089507277452877411716963341532491917294735000425600147549018150816296268100707103116349627880517820609981140344341623765041830668717266') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 419 +INSERT INTO num_exp_sub VALUES (9,9,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 420 +INSERT INTO num_exp_mul VALUES (9,9,'3010001475769225.8286280957637941018500905354415197182850820227163907782811814730309044010416886791014702373809932926301368137684091094408663914110947072451332976891128659038142954192986392936981664792370678656287232795203974766040821110221158579481177539669363513848425151485663431478439528936592701070340012569297177488556353760756495238304538439278682066056721729656193616571456456325016960870401748115848423105783116854283646624807603476682295234280408938557209608025246638166902335016025467565869375885610813662767004038102486303756741615124814580306266901273803721191779461890468156043551004644728343579032524687612403663816107770451694666844862368101122025340182510019516924578414085461628689') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 421 +INSERT INTO num_exp_div VALUES (9,9,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 422 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 423 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 424 +INSERT INTO num_exp_sqrt VALUES (0,'0') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 425 +INSERT INTO num_exp_sqrt VALUES (1,'291.964716019333021494947753821238960905461614737525349376826064492714634914263808902604580614735501799528494357560837535773816469841426747889103714048646989532842972129124080559131220979335403729022278994440514872845756198274805589586120535745968205107562348427941379641465378272611453955517402598409789621997041856848783989993820946766177453801729783316269310186191833995557234577548740940419224137195404391193633808203715191863638616433190672511651125299379882126530500870287424768024674231651229908224729856278167033444719242144302972892419034855417126978468296581589282861879645409909873113678361180607775255758820910366926076380306290306477790931129670172989289536405788838857428768869345763784112862591549008321546447442552533919976570125718481191724503352619626562352280522949665158335559389298720990302071') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 426 +INSERT INTO num_exp_sqrt VALUES (2,'31541679188064906.712574384704440356216787857626740375004266523720148374188511622980520374202725176835435173058936870163875556102907654264048353814040480579464700545975346621546520503928314632418705230212623378642743044255181848913683862360044189531298446109955034944189751302497670367665492719604026161836224535961347218522748523360100432275693829501972749859329753224444694962089604095212784768854310289429208671271394086829270986183171968944659703708706544668326267327938226750760690620258967209626420981505237183055363540806281098871221581265173394406715458619627534396065960117454160969749739483126059760636526242783235685190739315590041294766649891987044641492234243404608847939002062827210734973778130441825067858641461599799772535304379732674727995848518807202053316225824685704785148921785964036119338754973714515974054') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 427 +INSERT INTO num_exp_sqrt VALUES (3,'7765438138915239878.949520541017683429203286303188179443533225547096446554008374834292278237558244698868300666061834105683999048386497322007336816482648302911579331582895326423063492240235074387242190187374869842856897538718280497895072291181675294000739548676781615025944675912072664211455701112700937190832332966000160156597821149428032612782336278939437593991008833233156511435294360065004167893309428565243314846456225604669764879344135321428948841659419438769652686215993544390780212859309497190065178705035652106614050448518931820975038314187040226298661787490226917902356569717171481159691409131778764973037046501816919243659681416263730519167614043077472097520207347950292377914586524327206547377189493301153212000966249655331053184913579513686655963686155890934436604123384536027235444923674128269748280097789270784333442') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 428 +INSERT INTO num_exp_sqrt VALUES (4,'2308544622905.016172868282330339228589083058636874526727829838244942341440716909466939214393597311710652963849541394758298277969240038668406494621950956862959196896847352631445328917063551082418729435554972200530109505384839391233286173517804321019323644218483570886304028175359854335870835404627608254205407525763332087823548640923282031978903399118139052814618531713327991857575390136755426466065839913887477577516426991104516201265995293600539957187007068885368699949673989051443005684755994465547159213587471972139403333249259808344536605314911144950465968669770276463111776581675944967401948957460097365849699783091843609965345747287667911324039374314413430490112443463386381631812537639503425989372084906324702158112088898424705684574998783112519152403201231176840068666882123684602080460378627639651465436618032671756') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 429 +INSERT INTO num_exp_sqrt VALUES (5,'25549.082770905117529972076915050747181125832857399138345044265535151111965091602789684342996759657333588444489085160336703294705499665424408218434077722506748278242942379566431768762487954917389137120540138359870652558814224523699917122023018717544160579704907452934297025088008618627873220397030397424422097405152321366495319708580932627092620533785271831833326130796638935296720064431288560292191928489034307645738331451165431755179025359993690642194334018457793169983249853388987495489562746304107188105521296156525984787815685365255240654972150342496329030279439124533240114879332406941960563154881888172285475336782757262639979527682925214971861707635327995621436598536743180180978457735632181738067997521785965451385630326464388080990200265186437768409003553910194212076755448477164192901658547251079126833187') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 430 +INSERT INTO num_exp_sqrt VALUES (6,'.216649653115510782473161631235601739254284877523828136703593069337209747459679979369185882839688430004369697316986054374456779366220242645866798278985273820408495361607183119980716020227424205519727777568954933592987351750339481522149106749713967143685591960510946511796062486795368200503801097611436787402191532618456991115230272084771674098613479989808680789347124789253499967359190605681912854639520917409710307182238065185749856554472717209097115325999946728168357936779767099041518574001682560265549916593333117469681763348860131760281253987626822958726920016922608371657319505153308390495179319529587670415367205193280809809356733443291197315823747505896510820272670040485083775482983378341120809542502350385555577946098824446199419354197416933858522419312733314383889554606932774046771497129486979593226') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 431 +INSERT INTO num_exp_sqrt VALUES (7,'904950020.759072496304165474991957396337281699986101765045213964054286624338102141970514306010139529492299343393832200631760194440206005974547202512275476562767685193838576516154915404389465528270010938533075930081897392863141132529694804621418663424569202655893682412466871297412964570322984865326770090075582481194532433411398133265643849129084449161396724635797324126396071308557057830046688990212282866035593809633839882468628249964862932050189148498591642162462777480125024786829078066012617362076651920045684345679767223337287825546294839320770903419463644110383560050404456170063805115223954191445548226706113970164823214416171441655706141596091717118495955441099867737827763335880891937222647408575142200256804313345924443344596462585960919126827045197885802122062165934504665811115031150357820196176799560314653') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 432 +INSERT INTO num_exp_sqrt VALUES (8,'92179.098626752893864900181023972781406074846653380680747862421481598042923358730531575438403865501429843141967819802251116774924400485954931201776260931315313253827346015775662310076094882239170765060649024538403329505426563390044695320714825481746233901773893996663258170360232639353378395244461670781152793416950717050461856097473105730100523010642696332151571372764781034028324977128554099993021459338419164426784774496292405945103200724413639660488309795423335142455569853549710795692020963174011003447023610692365550245567840477105794884132665155376243735213346877116105595296043532605899184658904822980397411096930267453332143879534914237169761039374689145860503772331147367757318826885494994339695470190886515765452545019167989882527248872835783707554463866334705735781549392895480816605355996057201589681125') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 433 +INSERT INTO num_exp_sqrt VALUES (9,'7406.988615277484686670011157489572203134420118818648711986549881046321377798441006745317356200279801348355202517703531020643333388857073977704009782384103170022716610432579974132111487533733493986910583223121269323909760573942980360508642443245341392335557152177332615977623338526935953706604224108508582338123915133189529507760875123300397933931420500010248194253078118618381590347297853307090813639981736227771834732256867579490224181748450683295253634852775448770576585177080941820456051588076218688792321741398867304684922665590162004919486643750098085197190000638539994723704724550600891137853975703823903659121582583388450687255538838161486019214242094423895463814933532217776443473765708693285683261505695170847285063013324823850724236845500162436661946026097459146424122412596018946436589967013641971183281') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 434 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 435 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 436 +INSERT INTO num_exp_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 437 +INSERT INTO num_exp_ln VALUES (1,'11.353265918833698201334218522735144514838241118349715803442713722607336732214173255618762341321138898556011520430414052782971985419141860417968593746833898952016980791997105866598425597066404919489902082738711038276194174786383758877067916049129476352925010880025206629976454341252818402788928939407784629386362069592202090897264194883276572978998896242281239126931595483958092059051047739223830394259082355969005503976135238921488192773135287876801394308064862257453262299764712613486466254696464150007113953810688169396432889052881763511661127351872408811370081346456019961324265446884877073712053408327408917588393884214304220369626106333713688792094943405258431214313197283237071070354654837081449831786573831004911008790533179001070424813584405346221388686999574752038655226138085374176702005198770598232862') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 438 +INSERT INTO num_exp_ln VALUES (2,'75.980172429959420723484178622920965327708652620924912610122049843800380131746381968266727388919414524075492921510147435877107720844487333947572033626887969846858337336557672107987074468763307953130616555202495401302128216460637786993535376622372745654109623249396257174895352222213037880060756992073605135503615371392439827458529942230210514752764526895030759481226199720092008002458654297737883219558685499445394647863430593136350562417924068100891680398878483362058595716232013516337079804607378041880078724811071904523716775991447489914128580100888252698281559809224785596795038122963619830942475652745611551345360922016753939774272970008770647516790944335173711498988149783075646985898883858697162003144539047532603946093022417842140993960433780913606807466518632121884254341907122163281927271483110212890483') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 439 +INSERT INTO num_exp_ln VALUES (3,'86.992429107491709045555322727377654177072455841678650084144967727028762699430180506209786297136121512625728883607972513154010138109866327600596617277403558404624813332464431424791338402731178416819791932126837396086742033973404980654712734845137075562739300866280737071167943367603243180515859476717635339619107593771719314284984269343476343816253634799874584843436046260962736006310389088154751401911743739429257286834178656182340416539923956100441369280015412718483971113838923221170027312390404790743389872757674342133486652087007983701950040432125562287337697971646750563062524010514537132255605131615248097901911480464339325353279118429890601202554448469387179349495284716473293965884844451619766312048304583068386805927433174443889441171878078987788018564357316138422561213329104267180509029624308926098065') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 440 +INSERT INTO num_exp_ln VALUES (4,'56.935276817066740776567329017240462885579486075188456418197311631774373422196025180114152248099799048545382060930401786002025479108787121595516444894009593031141335985913019897883627990503003577804436730367402618412514152465206336556967419434371593632864308139215157721913158949066717186782560422199668568894551013785702491365073449320535603830475158258853167712460432995074161536886421366716995573365924430692151761737886552457036412140640821310927642146210426044265504978418405684030862182425702683702307323138985481047994648222224089112998195621687911787785594701557252468626097576375468916953563766801336922479861708649876362257086586679701715813254414915314296890025577780265459584203893089574567331742100451277992780400302806430264717887468808962517029442262560742822875484362427192693300423729233467613910') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 441 +INSERT INTO num_exp_ln VALUES (5,'20.296713391219923821414834924710998522858242536565236229645868008008504475111229451635162536658197320282791428572861452713483981402773630985812066048575864982038046409484905688236579134672910905547858248343712686247795669280482288748331949478864729205285910525962001251260319741279139167559906461672936902355959755164523720443059989357054368460911050707727029320725144824995614445423492687177126412520389766864793826362309254124276325522276592246655562770110024099522184080118637524912964002223613671995639705240767929562023556724031894855094820328152633412077228479168557819219970917880393852962560319397442566813746504969336443969816954424715197797253670026862362130664772772977978222813915593329422557592316429203293264572088112274848838446633519530653849595288125585730314673691986554304725866754516304420665') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 442 +INSERT INTO num_exp_ln VALUES (6,'-3.058947463851998053084898503420969773173569760507671013593014983772013099601022840164736581595033399273677583253456908293015637115395777673836877852797643436458673662566205707359569792482081945396989472318998080581824382006377064185813936544714612287417301161454496258176319380348780934551188852900784476213986897306897793456700682073399936398243222895442594762628402487110466705108765286617060826203345783502301472192906817785365563881556293576463515218574477264521950513789471494214626744754200844840310516235570475410854073969787604451971790833680742315518808178608136598148628107328076871698598743664423452623124027059698038466681488746505289551548778131621576387262707147068500249466398507704796800459013580425992071957391417767257856002976954566094297724379688683375704613872658653366052459242767328235849') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 443 +INSERT INTO num_exp_ln VALUES (7,'41.246780548917246608934265057073076900048579756649769602488660179351587788197892095257027979113051775079905924990472069951828742350559917110289416201523653941731339141666097617614477426376799479821365070373247490598890520285155435501242427296281987676879064510605563522117334502131946383957407685328562874307957108543536378261847119286989184256009392692140821396916222386573424618796707564187152459973446833193743614720624765332006827171872712331032607870580880807058576154429597725560836582655488602546786785520452359711161305828045237044625934404295366273012300148250900116489718279757540843657039519736455668388572899273464839528462223812926410544976290646668870192676914370659142463304861500879195867873346447316374869974900582948166687948531910220128160490935170837209017355954301127162240133341813847180541') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 444 +INSERT INTO num_exp_ln VALUES (8,'22.862977375646110045361670561177818139082238721442691850491173190000619222046296383571431877856442345505931635735363450488731186880557789439424987680284612480261693386095598289519783790826332183796775862215503493910816035128476952347072320869461206895223935484838130924268616681347949695029657753251443811448783435000569829291535036468240771401957519222523032235686030017496209956550934543164421459898155836108824017735809352580723262896259290484291175350770265895317482371895188221452083719817251845416195168686335127805092334984596224320638378502008767433534450949989322562311171685891891122105437154553106840103473941148230953978989145470651955269817951560544095229079088083494695756914405635176899994279484466773598435268700064279990885608144109747858515514066444373797446449729058958270758597627587968112958') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 445 +INSERT INTO num_exp_ln VALUES (9,'17.820358481980064387183481028572263407130633079314879566896470101569251997264841660326428805413719418277889123643557369421967068805165885825106611310020187894256310674762734896979157570968168599492401269694048046876387337971177513661006711375440365724346137980004810780215236524986274043416621637509807126148966029923572853117418545426960105154053049098579812135003711132897895016476695223444397389521434633067499404903493027304737402519428197015899833229473322655155458942323004249812974150129789653469524573801259946118454333405580647485894435301530550214095993989552176497867244278699359917247910082169086524111229983698975613609318418313798992088206507831757327320958918656453341769110558376097374227592021075267882222057385413453949580066342977546145482215220982989992069525148522710254796105001938615214263') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 446 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 447 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 448 +INSERT INTO num_exp_log10 VALUES (0,'NaN') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 449 +INSERT INTO num_exp_log10 VALUES (1,'4.930660740129727276654889314296515979425461685461970306647398411855044094312185293195497201658739777714943974003690119189101973212927970410047992001003936259467465542044528955416040460487922970233600641954269411521809500203864460110903973264337093883907933081597350982496469748131390809569321256206859934619579029279954574676601709408712255490686948453752571699579252140062805776361984468580258289509013081691778727372026090522694670379557247829136504595898935235926069699309392675806881162434168418505908116911054206058735257796918687777716036307205415038158583184624809880157060625643069601549803887864772092583549388533013233603450097615537162442973385137488450178790573546382354482351187412256794374383453695483855501587939419102008302408157959291557415763034668013452188944554607063362933134950906875499201') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 450 +INSERT INTO num_exp_log10 VALUES (2,'32.997769620388965086774969704518222090258389987679691893351902336370051104718852164011301929506188893338106627980171059175447833290713847317665944354651476245003161501753612545484635275306181777040447675475670149066399611203341262105766118892586541910243351018829302798733989560900125591073082441126709911019648451232244139674063434385451279378543163944005973452562993913383659295688375546058256196254319767218634546732685705517341998116744642480938405113447415486950667007645850519659606476727681944251201236366198374488204017630268083077471516734133869728427050843306716313813724061560369884508660845630727190444623729815564381063131729592825825486515070406390371638817503915214206586939112681762984038333298146999891250107667687034785493312416966635780188163871680959873288697497561452228182734430749066579749') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 451 +INSERT INTO num_exp_log10 VALUES (3,'37.780331928743475574895606142114739140772838801045013007323050327909196792739138159615327729728110344767302636436234256468332011934881494997184865617793179255006442447189720642997935223133982347184994174261506212652322213673745795726283311685835974151422721233207287206894148660531800622455957268888702309499182978182878524951883775154983702898237404558813230370364953160102391101897560104513279410610948028599674950811462114131673380477843456965645417025376374320207504913806546872166094337441573669261285052323206348035827948287081776955945081345131570610652073053464020209215624179904586956137079321655773178387441622685682721151900601340680061607114354850640946256225260430676099781727317540719923791064452012925902993317349390523278687089530234444415688602090547516647302454865526291471706301790881694022223') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 452 +INSERT INTO num_exp_log10 VALUES (4,'24.726676547286224970759328746582840552419566534667446425423046931401641497155587075591229106937829957279943690528061985864558314570189069764367933957499905044566413640017549478921384160584906257607957223101377816440084188042395098536074479064548620374152344954289432050971466476174493306432228880930006524504974367146536665170956555486181410864034862861231267121149652317599303804477688621597163730470970207231328339082779056152481480926452142005969020950341307977091850953883445808399574256295803245530993204179747743812544604144379381347499056545148243304041538981954204310612049423688645476667184129189153715486929216331980316967699254518020077226689317148303152585009031597809279387172427408557115400021035692880631275593381822805377317270568779655383061987766693697518921188619814204902583361096973421134004') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 453 +INSERT INTO num_exp_log10 VALUES (5,'8.814750626578650238811431417807018895270298639823442501111235973209197727215795256506525221092818797578008152140054383421240180435087611869193019443372556081555311825248667278358330916098378127100899126895012782320751838528480712942601038190627182482614147263228588284866661508052724762701223357327343090598060805245853527435948381893458352744679795853650453594546267600486696643924152372736774331080527157374379043696696647158270918245668579680394279565181670004245143555617589138267976417280970718829942998800499312890580011246294669585429723974582350357991472101919333996770115834067969654217063942059882195268353998096891812525364797586486311202350700339609637274043915687880562465121559531284337603363356183320193656553931871200575467929714875483123706358278876389849119105053294688326141759401230994901405') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 454 +INSERT INTO num_exp_log10 VALUES (6,'-1.328484003982869642690619298690906747763234110040562640557173509402512757735587333095924652711056556491908059708986413635120656426593745303715671199761364516107844087845783714418487426723538440387069985879601248897538855843115404484229652166941838283489828419407478748732927617251897244190697443966424660881366993754577233476597163021768156814527570512834684713730559883782625870597080940193303268818336816535968869931456641949301731046034660616615392129109391145214470757259042172416816936479713743188047425796931722546185493217275537303458837771965375448968719169174136287532752370175863826715450565025635651343928205805494319778539652563499901671319955144823432132740582617949774638538594081514904904341299199113721131520557004571803778698005652464301037962272085633628653321081368256925971558076970172779715') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 455 +INSERT INTO num_exp_log10 VALUES (7,'17.913249188669140643510654105014358282516966474257460687880559542190804665566625978925406311113121982595279826214959603627387555578965653325278444455875162277940655989601428868642914577248262147833499137348602966573601719040813549936948178463592211685237720748377879836890106515699728652218324794927458352954247096536337594789471529493944292143186953509162522579060020018226817623648563806559917579317916242706559131476179714031602207057714677845347616752450567251644277767418397621490301286115159509360375419599968738067461569666699939732107480135216621373057421990702923042287910730395998082514702629760389192370666675364405730936537832803383367187639209534697198515928978064543150195911463663617683085348965065679311986715357338675515370634753254774665197233934933271954463040729779956682570415317734489164385') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 456 +INSERT INTO num_exp_log10 VALUES (8,'9.929264914121995501917993119394933531225401243275938207624866270551448544301376913376130982251708700134720886862945040266148728213253651323129942781577143957084726727561987639140151337848818195806259935747329665025823709044567138449084349729747202164413995795609659711723455165142329822773177102845804114214340046404641970845707372809306219463962664551623665322610139794354769767829380018857313559373283673392337954610346290037758389035140213224696023751541663171574697035012610534455189013755134090933979479069288110010954211669067225249755249337768792642303351914884187159646984708862430789018895140670365476746734456807215043628059581947593694929159076346249490593187993386780521089745819640214783614157516171005086731241769146397577246387886107367648843380733370112546792442909347322732196805316614555689762') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 457 +INSERT INTO num_exp_log10 VALUES (9,'7.739283354261751283625223433456284905560931805428759681411970457812279544250432389511382263439324085689734710188041049046660480575958686859942980599595036769090747781359217248301544587434077376812293034848418204834388504169166350770257248896025815531248627658465029806509131631454856186387892627989218208026727504548130018922325585619738185507999433763118148418722504204066578294826264005398891049629199412773138457218976050467479292777172717500219850781664314597312411301296201533610562886229900497272268364496763758868455934979903774531992886483396489868888731578355541611359130188566524240259770918423445785338175040098706500034487703124623745259139247432324145633151895802637182446905097253961951018926565652497920605819785424451050191604602898777804133717341512568151920576684198443843944721398831404081859') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 458 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 459 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 460 +INSERT INTO num_exp_power_10_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 461 +INSERT INTO num_exp_power_10_ln VALUES (1,'225561990715.277245515991117670624124484084762557459065170589803293759247930753528436379932442146759103295277479258327642314622036941865221478746258727236601688778946696303277607709407496616423493315166963938393760548678730128692212077086588682984700837334554241405763691119669847463520746595280034536307041368063462023793177898200220207765205127584303464304601759554817607633012272490650155253979182893585119965271975927569080191838676053084168631217591768468344106219831174026139608715965691941366334940196517120885214887008671956523579678156919416435031020452971977153991139145404842034138317592877675821045409772456977018293365238179815614004574330200783530118851005077771478448804470170641452481992602803877112958872108069738434946694089025321283178188028224338756015337492913115267362635647236447601252924834642796058') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 462 +INSERT INTO num_exp_power_10_ln VALUES (2,'9553718264533556311125292459627965006385666643531070061102266984368939757379.536714147420215784125170401370065894858487440153494392538261078415409784085960333028254155527328359894197540839556987826344995348426293585457768226283066583722499658006242709930685932246087653832230889613022921575445199055131152661556678809191264086381976922223866204038615136758192929883317207903579770917317641181652055458721731297347443662717939116561947785705140374908203404860090658919334137955075887697259604047657534191202566335372150375993361370075961180728155127447781364264047857624746079509591666068708743260905728661917791822925979235918475633100283148558978385583805341715868143937062092264994833222352433299015979561976964779350640064096690062929265992966564232453102431600199173711947391200249130712039686700111791790265309426741120465259677894665532560198051256215915373145226284270408649736509') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 463 +INSERT INTO num_exp_power_10_ln VALUES (3,'982718444846268846508445482774217796844461660819285525931206164100817251856409365450682.362683768066405322653747385034480250394145008573806022660379219602846285813744865438912887625784087005970975437905783802114553690522787857272953842288090141945268495451006273685577260054069522075046955466204804067271437138871789034722069934693546671607506851844248427950939791205412350536883779850165603116191193657054604569586553874805856647223849267039531773072343908345333155562072887754900969504551717514980465801806565999410206735831440712124661645970935112535081991606671600328471264697018198676317466846450405861359235297846597981143547119390922405594115478086038680663368675222949247096131378724350715530605691796680604309063173515781378545860473572389718345696107553363715518601596249508215455106779522851210398208919496668879040223859884166805448827948087400426315425231119801173387715922086154065273') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 464 +INSERT INTO num_exp_power_10_ln VALUES (4,'861542720105376650266753999919217194383259935058507531116.774511336660822591851369622743235084609149542494189385785321912210129989390054947787009383210009523204976629456268332186620016067379702483800883493431423160815760933380418976582725913410929214462739708321325884209636272001805871036779154087677637129248122540412937033791526383240502286607736226090213753913654673523613612439527815137888202973659987501649474772884055648603290154867585312925699571949539600328906295652872654314913539778815035321695215634102441494403825526533235061083947035338872599854931230001361227174477274708230470794066733245241594719912710139298949856243576688344051439047966427547889756037265151798639614843866387316916203238068277912991427278268083231579195846744438643659745041780103653332041031419793815914447232121937821142169172566753399257291244398531365781832297786941359729799400') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 465 +INSERT INTO num_exp_power_10_ln VALUES (5,'198021976607570296508.271597639984889464620426933601643322058775615235389194561064983706229795978402690473201671702614911129095149240715527556855309177671128442458698638704394974473956869419481315262823632891676087912529523219333012290621046361106033860210270638559271706082115529424772192777643046125905852037759566224116373416253787241195450409652089019290072319861181399387753223422998872180810295299831487867222464355713552301775702554189470264147325049133532522718679336524769566984150923939420759804463781082299907043016120177416779442865059261387111806785876531152192378576258351599534512031062777609734092707165605364139201322351960602280089186180302246827234844736393745487324460438448807241887783263546165171099497316415863122023114646876909575845860402164818094500541234974716577550807551946414081410743197768993152975501') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 466 +INSERT INTO num_exp_power_10_ln VALUES (6,'.000873076977206566818052116526263730226812004454463281371489634779519089200224205946321120805055212090024554381349223642352209212670470260295303361873760972918129853308169576675500721645609379420329169271088810484607337679253503247351324049221970104335289487989027621978310506220905131150125321713385148268584530413680037620544212746920563790371941626294733473967065607791756894237438288480748407449237446113996117912144587258434808327522518688617394025018756570740098795745692805352377041347367240475846033282850136270250633825482156304826383360291164928049344226886150285595932088884965511963310715773499733217615863523253012606066583814112265708693122563204149232245895551314975524172504103194858904869273185785182598234060315036187756490539352752560361560286717869643902435677448962235275054804452967413005') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 467 +INSERT INTO num_exp_power_10_ln VALUES (7,'176514565873872717825163931126806100435750.096278384530154766967061948052237623936423931849868926020451465515367348890410352640552194499619062823622476972850692557798609619250753020363520533767813563613425606228355802781302735485038377521515850536680425059519814786118919994914180918228654298075183514200191737597656810036850772127169441661576862538643715648802139886576391427423689320082366572297580054381937437005879583216745596935643579262248665490169331304003204939561361718554509909313409421397022626924406091551900222555950699170864234411017062042057683304265485826061096835531732950909546314722726990314852356462874701181085379772134121978510387397276859318242238150439474660772561390798432890789762504242822787017140808209820627435991445529404692793744568204608385843245177656436105160780897472099970336514833257055017279707999437302548655364559') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 468 +INSERT INTO num_exp_power_10_ln VALUES (8,'72941951052009383458167.300747500436981484566111756088702608000390737594784514635592222758882092500858797317505303492923829092720870826490477962201959426813271424853341826896270963213736922458746003100613943600855942721319226948714369219316345322636075285343544788982588956431405042577296229122673590336976893594798942025893296105815818487227300314490440902574022885833779324177053242170024559675073866612316965636832258283516275906085642459351367507561963945012828379111856700009391438637054015804558386733558956649061672420804826896303889067785497738203077050774825608647969196321506624991188638449047860249367840775936911749905927108478444112230174584693363226143549933224252679398881354887872642908328737917862751077365602631600279486028043329404269490375935308156815477700961014566228692743960491745353377403533037122586797765130') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 469 +INSERT INTO num_exp_power_10_ln VALUES (9,'661239032819374816.097553651299556484820492272269662685578275493609248662925676004753503494252951243895572437264999063878330704584509915845096232798927524470286655554736724913758600775591269525423912692080421094644542553026831758426157681271572808657664918053119324646138457659418857926209701677786068580819823633713337632456905824562235373422309621872998037966404189020165296080436871220718574009921789858751384547836431858428729570977259373272041837411903005303672798845573379758630607982213326716018594073712340609488043353995410508475153538231445235003980586600882223782814368245305160648543466496726973755388826656879616734762068443462618454921858705377028522664844761719759342490380417060255776725333319537746890406213693117052223545525717132695297770810635066731941724108167146710297146989770382041617889670713111888375717') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 470 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 471 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +== 472 +INSERT INTO num_data VALUES (0, '0') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 473 +INSERT INTO num_data VALUES (1, '85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 474 +INSERT INTO num_data VALUES (2, '-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 475 +INSERT INTO num_data VALUES (3, '-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 476 +INSERT INTO num_data VALUES (4, '5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 477 +INSERT INTO num_data VALUES (5, '-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 478 +INSERT INTO num_data VALUES (6, '0.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 479 +INSERT INTO num_data VALUES (7, '-818934540071845742') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 480 +INSERT INTO num_data VALUES (8, '8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 481 +INSERT INTO num_data VALUES (9, '054863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 482 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +== 483 +-- ****************************** +-- * Create indices for faster checks +-- ****************************** + +CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add (id1, id2) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: IndexStmt +== 484 +CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub (id1, id2) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: IndexStmt +== 485 +CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div (id1, id2) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: IndexStmt +== 486 +CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul (id1, id2) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: IndexStmt +== 487 +CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt (id) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: IndexStmt +== 488 +CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln (id) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: IndexStmt +== 489 +CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 (id) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: IndexStmt +== 490 +CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln (id) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: IndexStmt +== 491 +VACUUM ANALYZE num_exp_add +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: VacuumStmt +== 492 +VACUUM ANALYZE num_exp_sub +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: VacuumStmt +== 493 +VACUUM ANALYZE num_exp_div +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: VacuumStmt +== 494 +VACUUM ANALYZE num_exp_mul +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: VacuumStmt +== 495 +VACUUM ANALYZE num_exp_sqrt +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: VacuumStmt +== 496 +VACUUM ANALYZE num_exp_ln +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: VacuumStmt +== 497 +VACUUM ANALYZE num_exp_log10 +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: VacuumStmt +== 498 +VACUUM ANALYZE num_exp_power_10_ln +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: VacuumStmt +== 499 +-- ****************************** +-- * Now check the behaviour of the NUMERIC type +-- ****************************** + +-- ****************************** +-- * Addition check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 500 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +== 501 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 502 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 503 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 504 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 10) as expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 10) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 505 +-- ****************************** +-- * Subtraction check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 506 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +== 507 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 508 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 509 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 510 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 40) + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 40) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 511 +-- ****************************** +-- * Multiply check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 512 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +== 513 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 514 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 515 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 516 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 30) as expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 30) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 517 +-- ****************************** +-- * Division check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 518 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val / t2.val + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 519 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 520 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 521 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val / t2.val, 80) + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 522 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 80) as expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 80) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 523 +-- ****************************** +-- * Square root check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 524 +INSERT INTO num_result SELECT id, 0, SQRT(ABS(val)) + FROM num_data +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 525 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_sqrt t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sqrt" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 526 +-- ****************************** +-- * Natural logarithm check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 527 +INSERT INTO num_result SELECT id, 0, LN(ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 528 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 529 +-- ****************************** +-- * Logarithm base 10 check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 530 +INSERT INTO num_result SELECT id, 0, LOG('10'::numeric, ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 531 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_log10 t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_log10" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 532 +-- ****************************** +-- * POW(10, LN(value)) check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +== 533 +INSERT INTO num_result SELECT id, 0, POW(numeric '10', LN(ABS(round(val,1000)))) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="pow" function="pow" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +== 534 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_power_10_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_power_10_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +== 535 +|-- +-- Test code path for raising to integer powers +|-- + +-- base less than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for p in {-20..20} +-- do +-- b="0.084738" +-- r=$(bc -ql <<< "scale=500 ; $b^$p" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(0.084738, -20, 2744326694304960114888.785913), +(0.084738, -19, 232548755422013710215.445941), +(0.084738, -18, 19705716436950597776.236458), +(0.084738, -17, 1669822999434319754.362725), +(0.084738, -16, 141497461326065387.345189), +(0.084738, -15, 11990211877848128.792857), +(0.084738, -14, 1016026574105094.737649), +(0.084738, -13, 86096059836517.517879), +(0.084738, -12, 7295607918426.821430), +(0.084738, -11, 618215223791.651994), +(0.084738, -10, 52386321633.657007), +(0.084738, -9, 4439112122.5928274), +(0.084738, -8, 376161483.04427101), +(0.084738, -7, 31875171.750205437), +(0.084738, -6, 2701038.3037689083), +(0.084738, -5, 228880.58378476975), +(0.084738, -4, 19394.882908753819), +(0.084738, -3, 1643.4835879219811), +(0.084738, -2, 139.26551227333284), +(0.084738, -1, 11.801080979017678), +(0.084738, 0, 1), +(0.084738, 1, .084738), +(0.084738, 2, .007180528644), +(0.084738, 3, .000608463636235272), +(0.084738, 4, .00005155999160730448), +(0.084738, 5, .000004369090568819767), +(0.084738, 6, .0000003702279966206494), +(0.084738, 7, .00000003137237997764059), +(0.084738, 8, .000000002658432734545308), +(0.084738, 9, .0000000002252702730599003), +(0.084738, 10, .00000000001908895239854983), +(0.084738, 11, .000000000001617559648348316), +(0.084738, 12, .0000000000001370687694817396), +(0.084738, 13, .00000000000001161493338834365), +(0.084738, 14, .0000000000000009842262254614642), +(0.084738, 15, .00000000000000008340136189315355), +(0.084738, 16, .000000000000000007067264604102046), +(0.084738, 17, .0000000000000000005988658680223991), +(0.084738, 18, .00000000000000000005074669592448206), +(0.084738, 19, .000000000000000000004300173519248761), +(0.084738, 20, .0000000000000000000003643881036741015)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +== 536 +-- base greater than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for p in {-20..20} +-- do +-- b="37.821637" +-- r=$(bc -ql <<< "scale=500 ; $b^$p" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(37.821637, -20, .00000000000000000000000000000002787363175065101), +(37.821637, -19, .000000000000000000000000000001054226381944797), +(37.821637, -18, .00000000000000000000000000003987256753373947), +(37.821637, -17, .000000000000000000000000001508045775519079), +(37.821637, -16, .00000000000000000000000005703675990106610), +(37.821637, -15, .000000000000000000000002157223628634278), +(37.821637, -14, .00000000000000000000008158972901002847), +(37.821637, -13, .000000000000000000003085857113545666), +(37.821637, -12, .0000000000000000001167121675823920), +(37.821637, -11, .000000000000000004414245235784397), +(37.821637, -10, .0000000000000001669539809368169), +(37.821637, -9, .000000000000006314472862697207), +(37.821637, -8, .0000000000002388237004592846), +(37.821637, -7, .000000000009032703305767796), +(37.821637, -6, .0000000003416316255594496), +(37.821637, -5, .00000001292106732962942), +(37.821637, -4, .0000004886959181938034), +(37.821637, -3, .00001848327962130773), +(37.821637, -2, .0006990678924065984), +(37.821637, -1, .02643989206495742), +(37.821637, 0, 1), +(37.821637, 1, 37.821637), +(37.821637, 2, 1430.476225359769), +(37.821637, 3, 54102.952532687378), +(37.821637, 4, 2046262.2313195326), +(37.821637, 5, 77392987.319777394), +(37.821637, 6, 2927129472.7542235), +(37.821637, 7, 110708828370.511632), +(37.821637, 8, 4187189119324.792454), +(37.821637, 9, 158366346921451.985294), +(37.821637, 10, 5989674486279224.500736), +(37.821637, 11, 226539294168214309.708325), +(37.821637, 12, 8568086950266418559.993831), +(37.821637, 13, 324059074417413536066.149409), +(37.821637, 14, 12256444679171401239980.310926), +(37.821637, 15, 463558801566202198479885.206986), +(37.821637, 16, 17532552720991931019508170.100286), +(37.821637, 17, 663109844696719094948877928.067252), +(37.821637, 18, 25079899837245684700124994552.671731), +(37.821637, 19, 948562867640665366544581398598.127577), +(37.821637, 20, 35876200451584291931921101974730.690104)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +== 537 +|-- +-- Tests for raising to non-integer powers +|-- + +-- base less than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for n in {-20..20} +-- do +-- b="0.06933247" +-- p="$n.342987" +-- r=$(bc -ql <<< "scale=500 ; e($p*l($b))" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(0.06933247, -20.342987, 379149253615977128356318.39406340), +(0.06933247, -19.342987, 26287354251852125772450.59436685), +(0.06933247, -18.342987, 1822567200045909954554.65766042), +(0.06933247, -17.342987, 126363085720167050546.86216560), +(0.06933247, -16.342987, 8761064849800910427.02880469), +(0.06933247, -15.342987, 607426265866876128.15466179), +(0.06933247, -14.342987, 42114363355427213.14899924), +(0.06933247, -13.342987, 2919892833909256.59283660), +(0.06933247, -12.342987, 202443382310228.51544515), +(0.06933247, -11.342987, 14035899730722.44924025), +(0.06933247, -10.342987, 973143597003.32229028), +(0.06933247, -9.342987, 67470449244.92493259), +(0.06933247, -8.342987, 4677892898.16028054), +(0.06933247, -7.342987, 324329869.02491071), +(0.06933247, -6.342987, 22486590.914273551), +(0.06933247, -5.342987, 1559050.8899661435), +(0.06933247, -4.342987, 108092.84905705095), +(0.06933247, -3.342987, 7494.3442144625131), +(0.06933247, -2.342987, 519.60139541889576), +(0.06933247, -1.342987, 36.025248159838727), +(0.06933247, 0.342987, .40036522320023350), +(0.06933247, 1.342987, .02775830982657349), +(0.06933247, 2.342987, .001924552183301612), +(0.06933247, 3.342987, .0001334339565121935), +(0.06933247, 4.342987, .000009251305786862961), +(0.06933247, 5.342987, .0000006414158809285026), +(0.06933247, 6.342987, .00000004447094732199898), +(0.06933247, 7.342987, .000000003083280621074075), +(0.06933247, 8.342987, .0000000002137714611621997), +(0.06933247, 9.342987, .00000000001482130341788437), +(0.06933247, 10.342987, .000000000001027597574581366), +(0.06933247, 11.342987, .00000000000007124587801173530), +(0.06933247, 12.342987, .000000000000004939652699872298), +(0.06933247, 13.342987, .0000000000000003424783226243151), +(0.06933247, 14.342987, .00000000000000002374486802900065), +(0.06933247, 15.342987, .000000000000000001646290350274646), +(0.06933247, 16.342987, .0000000000000000001141413763217064), +(0.06933247, 17.342987, .000000000000000000007913703549583420), +(0.06933247, 18.342987, .0000000000000000000005486766139403860), +(0.06933247, 19.342987, .00000000000000000000003804110487572339), +(0.06933247, 20.342987, .000000000000000000000002637483762562946)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +== 538 +-- base greater than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for n in {-20..20} +-- do +-- b="27.234987" +-- p="$n.230957" +-- r=$(bc -ql <<< "scale=500 ; e($p*l($b))" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(27.234987, -20.230957, .000000000000000000000000000009247064512095633), +(27.234987, -19.230957, .0000000000000000000000000002518436817750859), +(27.234987, -18.230957, .000000000000000000000000006858959399176602), +(27.234987, -17.230957, .0000000000000000000000001868036700701026), +(27.234987, -16.230957, .000000000000000000000005087595525911532), +(27.234987, -15.230957, .0000000000000000000001385605980094587), +(27.234987, -14.230957, .000000000000000000003773696085499835), +(27.234987, -13.230957, .0000000000000000001027765638305389), +(27.234987, -12.230957, .000000000000000002799118379829397), +(27.234987, -11.230957, .00000000000000007623395268611469), +(27.234987, -10.230957, .000000000000002076230710364949), +(27.234987, -9.230957, .00000000000005654611640579014), +(27.234987, -8.230957, .000000000001540032745212181), +(27.234987, -7.230957, .00000000004194277179542807), +(27.234987, -6.230957, .000000001142310844592450), +(27.234987, -5.230957, .00000003111082100243440), +(27.234987, -4.230957, .0000008473028055606278), +(27.234987, -3.230957, .00002307628089450723), +(27.234987, -2.230957, .0006284822101702527), +(27.234987, -1.230957, .01711670482371810), +(27.234987, 0.230957, 2.1451253063142300), +(27.234987, 1.230957, 58.422459830839071), +(27.234987, 2.230957, 1591.1349340009243), +(27.234987, 3.230957, 43334.539242761031), +(27.234987, 4.230957, 1180215.6129275865), +(27.234987, 5.230957, 32143156.875279851), +(27.234987, 6.230957, 875418459.63720737), +(27.234987, 7.230957, 23842010367.779367), +(27.234987, 8.230957, 649336842420.336290), +(27.234987, 9.230957, 17684680461938.907402), +(27.234987, 10.230957, 481642042480060.137900), +(27.234987, 11.230957, 13117514765597885.614921), +(27.234987, 12.230957, 357255344113366461.949871), +(27.234987, 13.230957, 9729844652608062117.440722), +(27.234987, 14.230957, 264992192625800087863.690528), +(27.234987, 15.230957, 7217058921265161257566.469315), +(27.234987, 16.230957, 196556505898890690402726.443417), +(27.234987, 17.230957, 5353213882921711267539279.451015), +(27.234987, 18.230957, 145794710509592328389185797.837767), +(27.234987, 19.230957, 3970717045397510438979206144.696206), +(27.234987, 20.230957, 108142427112079606637962972621.121293)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +== 539 +-- Inputs close to overflow +|-- +-- bc(1) results computed with a scale of 2700 and truncated to 4 decimal +-- places. + +WITH t(b, p, bc_result) AS (VALUES +(0.12, -2829.8369, 58463948950011752465280493160293790845494328939320966633018493248607815580903065923369555885857984675501574162389726507612128133630191173383130639968378879506624785786843501848666498440326970769604109017960864573408272864266102690849952650095786874354625921641729880352858506454246180842452983243549491658464046163869265572232996388827878976066830374513768599285647145439771472435206769249126377164951470622827631950210853282324510655982757098065657709137845327135766013147354253426364240746381620690117663724329288646510198895137275207992825719846135857839292915100523542874885080351683587865157015032404901182924720371819942957083390475846809517968191151435281268695782594904484795360890092607679215675240583291240729468370895035823777914792823688291214492607109455017754453939895630226174304357121900605689015734289765672740769194115142607443713769825894380064727556869268488695795705030158832909348803019429370973064732712469794182891757241046263341655894972953512257981661670321890336672832647028099324621932563236459127918144141230217523147304565594514812518826936144181257723061181656522095236928347413997136815409159361412494284201481609684892562646522086577634100783077813105675590737823924220663206479031113753135119759722725207724879578900186075841393115040465401462266086907464970054073340036852442184414587772177753008511913377364966775792477387717262694468450099866775550614257191941835797445874557362115814601886902749237439492398087966544817154173072811937702110580330775581851211123491341435883319798273456296794954514173820352334127081705706502510709179711510240917772628308487366740741280043704807717608366220401933596364641284631036907635403895053036499618723044314773148779735006542501244942039455169872946018271985844759209768927953340447524637670938413827595013338859796135512187473850161303598087634723542727044978083220970836296653305188470017342167913572166172051819741354902582606590658382067039498769674611071582171914886494269818475850690414812481252963932223686078322390396586222238852602472958831686564971334200490182175112490433364675164900946902818404704835106260174052265784055642968397240262737313737007322288203637798365320295080314524864099419556398713380156353062937736280885716820226469419928595465390700629307079710611273715705695938635644841913194091407807776191951797748706106000922803167645881087385311847268311361092838264814899353459146959869764278464187826798546290981492648723002412475976344071283321798061003719251864595518596639432393032991023409676558943539937377229130132816883146259468718344018277257037013406135980469482324577407154032999045733141275895.3432), +(1.2, 32908.8896, 58463467728170833376633133695001863276259293590926929026251227859007891876739460057725441400966420577009060860805883032969522911803372870882799865787473726926215148161529632590083389287080925059682489116446754279752928005457087175157581627230586554364417068189211136840990661174760199073702207450133797324318403866058202372178813998850887986769280847189341565507156189065295823921162851958925352114220880236114784962150135485415106748467247897246441194126125699204912883449386043559785865023459356275014504597646990160571664166410683323036984805434677654413174177920726210827006973855410386789516533036723888687725436216478665958434776205940192130053647653715221076841771578099896259902368829351569726536927952661429685419815305418450230567773264738536471211804481206474781470237730069753206249915908804615495060673071058534441654604668770343616386612119048579369195201590008082689834456232255266932976831478404670192731621439902738547169253818323045451045749609624500171633897705543164388470746657118050314064066768449450440405619135824055131398727045420324382226572368236570500391463795989258779677208133531636928003546809249007993065200108076924439703799231711400266122025052209803513232429907231051873161206025860851056337427740362763618748092029386371493898291580557004812947013231371383576580415676519066503391905962989205397824064923920045371823949776899815750413244195402085917098964452866825666226141169411712884994564949174271056284898570445214367063763956186792886147126466387576513166370247576466566827375268334148320298849218878848928271566491769458471357076035396330179659440244425914213309776100351793665960978678576150833311810944729586040624059867137538839913141142139636023129691775489034134511666020819676247950267220131499463010350308195762769192775344260909521732256844149916046793599150786757764962585268686580124987490115873389726527572428003433405659445349155536369077209682951123806333170190998931670309088422483075609203671527331975811507450670132060984691061148836994322505371265263690017938762760088575875666254883673433331627055180154954694693433502522592907190906966067656027637884202418119121728966267936832338377284832958974299187166554160783467156478554899314000348357280306042140481751668215838656488457943830180819301102535170705017482946779698265096226184239631924271857062033454725540956591929965181603262502135610768915716020374362368495244256420143645126927013882334008435586481691725030031204304273292938132599127402133470745819213047706793887965197191137237066440328777206799072470374264316425913530947082957300047105685634407092811630672103242089966046839626911122.7149)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +== 540 +|-- +-- Tests for EXP() +|-- + +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of EXP(): +|-- +-- for n in {-20..20} +-- do +-- x="$n.29837" +-- r=$(bc -ql <<< "scale=500 ; e($x)" | head -n 1) +-- echo "($x, $r)," +-- done + +WITH t(x, bc_result) AS (VALUES +(-20.29837, .000000001529431101152222), +(-19.29837, .000000004157424770142192), +(-18.29837, .00000001130105220586304), +(-17.29837, .00000003071944485366452), +(-16.29837, .00000008350410872606600), +(-15.29837, .0000002269877013517336), +(-14.29837, .0000006170165438681061), +(-13.29837, .000001677224859055276), +(-12.29837, .000004559169856609741), +(-11.29837, .00001239310857408049), +(-10.29837, .00003368796183504298), +(-9.29837, .00009157337449401917), +(-8.29837, .0002489222398577673), +(-7.29837, .0006766408013046928), +(-6.29837, .001839300394580514), +(-5.29837, .004999736839665763), +(-4.29837, .01359069379834070), +(-3.29837, .03694333598818056), +(-2.29837, .1004223988993283), +(-1.29837, .2729763820983097), +(0.29837, 1.3476603299656679), +(1.29837, 3.6633205858807959), +(2.29837, 9.9579377804197108), +(3.29837, 27.068481317440698), +(4.29837, 73.579760889182206), +(5.29837, 200.01052696742555), +(6.29837, 543.68498095607070), +(7.29837, 1477.8890041389891), +(8.29837, 4017.3188244304487), +(9.29837, 10920.204759575742), +(10.29837, 29684.194161006717), +(11.29837, 80690.005580314652), +(12.29837, 219338.17590722828), +(13.29837, 596222.97785597218), +(14.29837, 1620702.0864156289), +(15.29837, 4405525.0308492653), +(16.29837, 11975458.636179032), +(17.29837, 32552671.598188404), +(18.29837, 88487335.673150406), +(19.29837, 240533516.60908059), +(20.29837, 653837887.33381570)) +SELECT x, bc_result, exp(x), exp(x)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +== 541 +|-- +-- Tests for LN() +|-- + +-- input very small +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(10^-$p)" | head -n 1) +-- echo "('1.0e-$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', -2.3025850929940457), +('1.0e-2', -4.6051701859880914), +('1.0e-3', -6.9077552789821371), +('1.0e-4', -9.2103403719761827), +('1.0e-5', -11.512925464970228), +('1.0e-6', -13.815510557964274), +('1.0e-7', -16.118095650958320), +('1.0e-8', -18.420680743952365), +('1.0e-9', -20.723265836946411), +('1.0e-10', -23.025850929940457), +('1.0e-11', -25.328436022934503), +('1.0e-12', -27.631021115928548), +('1.0e-13', -29.933606208922594), +('1.0e-14', -32.236191301916640), +('1.0e-15', -34.5387763949106853), +('1.0e-16', -36.84136148790473094), +('1.0e-17', -39.143946580898776628), +('1.0e-18', -41.4465316738928223123), +('1.0e-19', -43.74911676688686799634), +('1.0e-20', -46.051701859880913680360), +('1.0e-21', -48.3542869528749593643778), +('1.0e-22', -50.65687204586900504839581), +('1.0e-23', -52.959457138863050732413803), +('1.0e-24', -55.2620422318570964164317949), +('1.0e-25', -57.56462732485114210044978637), +('1.0e-26', -59.867212417845187784467777822), +('1.0e-27', -62.1697975108392334684857692765), +('1.0e-28', -64.47238260383327915250376073116), +('1.0e-29', -66.774967696827324836521752185847), +('1.0e-30', -69.0775527898213705205397436405309), +('1.0e-31', -71.38013788281541620455773509521529), +('1.0e-32', -73.682722975809461888575726549899655), +('1.0e-33', -75.9853080688035075725937180045840189), +('1.0e-34', -78.28789316179755325661170945926838306), +('1.0e-35', -80.590478254791598940629700913952747266), +('1.0e-36', -82.8930633477856446246476923686371114736), +('1.0e-37', -85.19564844077969030866568382332147568124), +('1.0e-38', -87.498233533773735992683675278005839888842), +('1.0e-39', -89.8008186267677816767016667326902040964430), +('1.0e-40', -92.10340371976182736071965818737456830404406)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 542 +-- input very close to but smaller than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1-10^-$p)" | head -n 1) +-- echo "('1.0e-$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', -.10536051565782630), +('1.0e-2', -.010050335853501441), +('1.0e-3', -.0010005003335835335), +('1.0e-4', -.00010000500033335834), +('1.0e-5', -.000010000050000333336), +('1.0e-6', -.0000010000005000003333), +('1.0e-7', -.00000010000000500000033), +('1.0e-8', -.000000010000000050000000), +('1.0e-9', -.0000000010000000005000000), +('1.0e-10', -.00000000010000000000500000), +('1.0e-11', -.000000000010000000000050000), +('1.0e-12', -.0000000000010000000000005000), +('1.0e-13', -.00000000000010000000000000500), +('1.0e-14', -.000000000000010000000000000050), +('1.0e-15', -.0000000000000010000000000000005), +('1.0e-16', -.00000000000000010000000000000001), +('1.0e-17', -.000000000000000010000000000000000), +('1.0e-18', -.0000000000000000010000000000000000), +('1.0e-19', -.00000000000000000010000000000000000), +('1.0e-20', -.000000000000000000010000000000000000), +('1.0e-21', -.0000000000000000000010000000000000000), +('1.0e-22', -.00000000000000000000010000000000000000), +('1.0e-23', -.000000000000000000000010000000000000000), +('1.0e-24', -.0000000000000000000000010000000000000000), +('1.0e-25', -.00000000000000000000000010000000000000000), +('1.0e-26', -.000000000000000000000000010000000000000000), +('1.0e-27', -.0000000000000000000000000010000000000000000), +('1.0e-28', -.00000000000000000000000000010000000000000000), +('1.0e-29', -.000000000000000000000000000010000000000000000), +('1.0e-30', -.0000000000000000000000000000010000000000000000), +('1.0e-31', -.00000000000000000000000000000010000000000000000), +('1.0e-32', -.000000000000000000000000000000010000000000000000), +('1.0e-33', -.0000000000000000000000000000000010000000000000000), +('1.0e-34', -.00000000000000000000000000000000010000000000000000), +('1.0e-35', -.000000000000000000000000000000000010000000000000000), +('1.0e-36', -.0000000000000000000000000000000000010000000000000000), +('1.0e-37', -.00000000000000000000000000000000000010000000000000000), +('1.0e-38', -.000000000000000000000000000000000000010000000000000000), +('1.0e-39', -.0000000000000000000000000000000000000010000000000000000), +('1.0e-40', -.00000000000000000000000000000000000000010000000000000000)) +SELECT '1-'||x, bc_result, ln(1.0-x::numeric), ln(1.0-x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 543 +-- input very close to but larger than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1+10^-$p)" | head -n 1) +-- echo "('1.0e-$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', .09531017980432486), +('1.0e-2', .009950330853168083), +('1.0e-3', .0009995003330835332), +('1.0e-4', .00009999500033330834), +('1.0e-5', .000009999950000333331), +('1.0e-6', .0000009999995000003333), +('1.0e-7', .00000009999999500000033), +('1.0e-8', .000000009999999950000000), +('1.0e-9', .0000000009999999995000000), +('1.0e-10', .00000000009999999999500000), +('1.0e-11', .000000000009999999999950000), +('1.0e-12', .0000000000009999999999995000), +('1.0e-13', .00000000000009999999999999500), +('1.0e-14', .000000000000009999999999999950), +('1.0e-15', .0000000000000009999999999999995), +('1.0e-16', .00000000000000010000000000000000), +('1.0e-17', .000000000000000010000000000000000), +('1.0e-18', .0000000000000000010000000000000000), +('1.0e-19', .00000000000000000010000000000000000), +('1.0e-20', .000000000000000000010000000000000000), +('1.0e-21', .0000000000000000000010000000000000000), +('1.0e-22', .00000000000000000000010000000000000000), +('1.0e-23', .000000000000000000000010000000000000000), +('1.0e-24', .0000000000000000000000010000000000000000), +('1.0e-25', .00000000000000000000000010000000000000000), +('1.0e-26', .000000000000000000000000010000000000000000), +('1.0e-27', .0000000000000000000000000010000000000000000), +('1.0e-28', .00000000000000000000000000010000000000000000), +('1.0e-29', .000000000000000000000000000010000000000000000), +('1.0e-30', .0000000000000000000000000000010000000000000000), +('1.0e-31', .00000000000000000000000000000010000000000000000), +('1.0e-32', .000000000000000000000000000000010000000000000000), +('1.0e-33', .0000000000000000000000000000000010000000000000000), +('1.0e-34', .00000000000000000000000000000000010000000000000000), +('1.0e-35', .000000000000000000000000000000000010000000000000000), +('1.0e-36', .0000000000000000000000000000000000010000000000000000), +('1.0e-37', .00000000000000000000000000000000000010000000000000000), +('1.0e-38', .000000000000000000000000000000000000010000000000000000), +('1.0e-39', .0000000000000000000000000000000000000010000000000000000), +('1.0e-40', .00000000000000000000000000000000000000010000000000000000)) +SELECT '1+'||x, bc_result, ln(1.0+x::numeric), ln(1.0+x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 544 +-- input very large +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(10^$p)" | head -n 1) +-- echo "('1.0e$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e1', 2.3025850929940457), +('1.0e2', 4.6051701859880914), +('1.0e3', 6.9077552789821371), +('1.0e4', 9.2103403719761827), +('1.0e5', 11.512925464970228), +('1.0e6', 13.815510557964274), +('1.0e7', 16.118095650958320), +('1.0e8', 18.420680743952365), +('1.0e9', 20.723265836946411), +('1.0e10', 23.025850929940457), +('1.0e11', 25.328436022934503), +('1.0e12', 27.631021115928548), +('1.0e13', 29.933606208922594), +('1.0e14', 32.236191301916640), +('1.0e15', 34.538776394910685), +('1.0e16', 36.841361487904731), +('1.0e17', 39.143946580898777), +('1.0e18', 41.446531673892822), +('1.0e19', 43.749116766886868), +('1.0e20', 46.051701859880914), +('1.0e21', 48.354286952874959), +('1.0e22', 50.656872045869005), +('1.0e23', 52.959457138863051), +('1.0e24', 55.262042231857096), +('1.0e25', 57.564627324851142), +('1.0e26', 59.867212417845188), +('1.0e27', 62.169797510839233), +('1.0e28', 64.472382603833279), +('1.0e29', 66.774967696827325), +('1.0e30', 69.077552789821371), +('1.0e31', 71.380137882815416), +('1.0e32', 73.682722975809462), +('1.0e33', 75.985308068803508), +('1.0e34', 78.287893161797553), +('1.0e35', 80.590478254791599), +('1.0e36', 82.893063347785645), +('1.0e37', 85.195648440779690), +('1.0e38', 87.498233533773736), +('1.0e39', 89.800818626767782), +('1.0e40', 92.103403719761827)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 545 +-- input huge +|-- +-- bc(1) results computed with a scale of 1000 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..10} +-- do +-- l=$(bc -ql <<< "scale=1000 ; l(10^${p}00)" | head -n 1) +-- echo "('1.0e${p}00', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e100', 230.25850929940457), +('1.0e200', 460.51701859880914), +('1.0e300', 690.77552789821371), +('1.0e400', 921.03403719761827), +('1.0e500', 1151.2925464970228), +('1.0e600', 1381.5510557964274), +('1.0e700', 1611.8095650958320), +('1.0e800', 1842.0680743952365), +('1.0e900', 2072.3265836946411), +('1.0e1000', 2302.5850929940457)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 546 +-- inputs with 1000 decimal places +|-- +-- bc(1) results computed with a scale of 2000 and rounded to 1000 decimal +-- places + +WITH t(x, bc_result) AS (VALUES +(484990182159328900690402236933516249572671683638747490717351807610531884491845416923860371219625151551889257298200816555016472471293780254009492949585031653913930735918829139712249577547959394351523545901788627247613322896296041868431769047433229466634098452564756860190085118463828382895145244362033728480588969626012192733802377468089120757046364393407262957242230928854711898925295251902007136232994524624903257456111389508582206404271734668422903183500589303866613158037169610592539145461637447957948521714058034772237111009429638870236361143304703683377693378577075353794118557951847394763531830696578809001981568860219578880229402696449243344235099860421846016326538272155937175661905904288335499593232232926636205909086901191153907183842087577811871344870731324067822883041265129394268082883745408414994.8967939438561591657171240282983703914075472645212002662497023142663831371447287624846942598424990784971781730103682951722370983277124599054059027055336437808366784501932987082321905202623642371063626378290734289114618092750984153422293450048717769065428713836637664433167768445609659527458911187829232316677137895259433038764404970599325009178297626038331436654541552998098529141205301472138026818453893127265938030066392881979113522757891639646670670272542401773230506961559808927249585675430838495658225557294666522469887436551840596777627408780618586500922973500018513068499587683746133637919751545157547095670767246977244726331271787622126889459658539988980096764323712767863722912919120929339399753431689512753214200090670880647731689804555417871258907716687575767185444541243606329768784843125926070743277339790277626515824924290352180761378846035233155198504033292692893297993698953705472933411199778880561376633444249703838589180474329586470353212010427945060694794274109764269805332803290229, + 1864.3702986939570026328504202935192533137907736189919154633800554877738455118081651650863235106905871352085850240570561347180517240105510505203972860921397909573687877993477806728098306202020229409548306695695574102950949468160529713610952021974630774784174851619325758380143625473386495586347322798415543385655090746985183329114860118551572428921774322172798724455202876781611633419444058398798142214904998877857425038669920064728855823072107227506485770367799671977282350083029452784747350395161797215115525867416898416360638482342253129160308632504217096916335590470843180746834864303790913372081974355613359678634194879425862536147988835528973291020680020540866655622823550861337486588647231688134992810403147262346312159819432914207194632564009749236609081399504118359354620598232725290537215007867979331582119891661859015726276335168158288396939655310210558566592649049602925182137256134162660116182293851038854455437841571331011002023088829768308520393956515509475418031437505751407687618234418262), +(87190145885430429849953615409019208993240447426362428988181639909267773304254748257120061524000254226856815085523676417146197197996896030672521334101413071112068202429835905642444187493717977611730127126387257253646790849384975208460867137315507010888782632024640844766297185244443116696943912406389670302370461137850160539373600494054874979342373255280815156048999900951842673141766630630919020492255966628630634124452614590400422133958133100159154995520080124736657520969784129924799670552560034302960877087853678350801769339861812435411200669026902417951572668727488315537985378304242438181615160041688723201917323705450185975141141262578884689500612295576288125956289035673242989906973367691922065122033180281670221390667818909912035903387888639331486823729897326624516015340.0330856710565117793999512551468220085711713631167607285185762046751452975325645379302403715842570486302993296501788672462090620871511446272026693318239212657949496275318383141403236705902077406660768573015707706831878445598837931116223956945944726162551477136715847593742032488181481888084716920605114101902724395659898621880016853548602514706686907951229872573180602614761229992106144727082722940736406782659562775289407005631298246624198606031298081220736931229256511054595028182057216042683060059115371651410352645266000330509331097811566633211452233019461903115970558624057877018778178814946285827512359903934291318219271464841957435711594154280905473802599888081783098187210283997106131616471807951265003903143099667366508222327805543948921694362089860577380749774036318574113007382111997454202845559941557812813566442364810680529092880773126707073967537693927177460459341763934709686530005721141046645111784404932103241501569571235364365556796422998363930810983452790309019295181282099408260156, + 1793.5767085750017553306932533574391150814202249805881581227430032600579405884415934520704053351781361105595296647510475380766428668443641914861849764330704062323054023252886955844207807229267936432730818329225450152491146839618683772020068682795388746108876393249306737841247788224204701299467519965182171772253974884845661168860422489046657965359832930382114760565628765599962013955588754803194908990025689040598990346417563277021386852342928910383706995866844541160576254266641602065102228267316550706943783591722246885978355472097314691737807509436806788803362444745551013400341861820755594413819894154786253014501454443272120342005711761286524843010157182464200556865694401941794983935172457481497909987740544409272349152397774548604845897687504977786762391359552407068124283290504752932824699865504970420939586707791994870941813718246825616335675307740641350673558328821461530563823677144691877374809441673507467507447891562257806191361453045937798278733402269265623588493124129181374135958668436774), +(93936642222690597390233191619858485419795942047468396309991947772747208870873993801669373075421461116465960407843923269693395211616591453397070258466704654943689268224479477016161636938138334729982904232438440955361656138189836032891825113139184685132178764873033678116450665758561650355252211196676137179184043639278410827092182700922151290703747496962700158844772453483316974221113826173404445159281421213715669245417896170368554410830320000019029956317336703559699859949692222685614036912057150632902650913831404804982509990655560731349634628713944739168096272097122388116038119844786988276635032016787352796502360718569977397214936366251320294621522016.6483354941025384161536675750898007896744690911429670830432784905421638721478353275821072200938900938046264210604940707974410950770029535636602548377806284157951164875821446035013896786653932045182167021839184824627082391478016195098055107001433336586881395912782883663046617432598969149948351689103230162742769845955320418573803127107923535948653168889411316007796459064267436246637115946581149511513369842911210359447262641996566147462977170742544980481275049898092152042927981394239266559286915303786701737610786594006685748456635797125029722684151298695274097006242412384086302106763844070230264910503179385988626477852818174114043927841085089058972074427820150462261941575665882880501074676800316585217150509780489224388148722603385921057007086785238310735038314861960410473809826927329368597558806004392175746233568789445929554890241140656324160187253042639339549705859147930476532359840809944163908006480881926041259363654863689570520534301207043189181147254153307163555433328278834311658232337, + 1510.4332713542154696529645934345554302578243896764921637693542962119938599884313210100957753316832762996428481801312323020427109678979117469716796746760060470871840325255146954580681101106876674367471955788143763250819168311353856748872452260808797135108102729064040463343792765872545182299889360257515315869180266759715933989413256377582681707188367254513700731642913479683031478361835565783219287780434673712341147656477670848734998849030451414278832848680301511646182446524915091598080243532068451726548537866633622180283865668708517173065893429240665300584705585310049892047293928733753369421499719516009692095913169665213597158441636480707309244604139865130782756488091268094213446272360006907802989573582755585110277620911226015342778471352130366770729972784317323917141031824334355639769512749560550167491709646539950725523461943580211843652293561678342656010571108219244870234329176123205423872844099992204896411752620881541000940129833754169391528449211839693800724450201835161044717173715867437)) +SELECT trim_scale(ln(x::numeric)-bc_result) AS diff FROM t +-- +CTE: "t" +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +== 547 +|-- +-- Tests for LOG() (base 10) +|-- + +-- input very small, exact result known +WITH t(x) AS (SELECT '1e-'||n FROM generate_series(1, 100) g(n)) +SELECT x, log(x::numeric) FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 548 +-- input very small, non-exact results +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..50..7} +-- do +-- for d in {9..1..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l($d*10^-$p) / l(10)" | head -n 1) +-- echo "('${d}.0e-$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', -.04575749056067513), +('6.0e-1', -.2218487496163564), +('3.0e-1', -.5228787452803376), +('9.0e-8', -7.045757490560675), +('6.0e-8', -7.221848749616356), +('3.0e-8', -7.522878745280338), +('9.0e-15', -14.0457574905606751), +('6.0e-15', -14.2218487496163564), +('3.0e-15', -14.5228787452803376), +('9.0e-22', -21.04575749056067512540994), +('6.0e-22', -21.22184874961635636749123), +('3.0e-22', -21.52287874528033756270497), +('9.0e-29', -28.045757490560675125409944193490), +('6.0e-29', -28.221848749616356367491233202020), +('3.0e-29', -28.522878745280337562704972096745), +('9.0e-36', -35.0457574905606751254099441934897693816), +('6.0e-36', -35.2218487496163563674912332020203916640), +('3.0e-36', -35.5228787452803375627049720967448846908), +('9.0e-43', -42.04575749056067512540994419348976938159974227), +('6.0e-43', -42.22184874961635636749123320202039166403168125), +('3.0e-43', -42.52287874528033756270497209674488469079987114), +('9.0e-50', -49.045757490560675125409944193489769381599742271618608), +('6.0e-50', -49.221848749616356367491233202020391664031681254347196), +('3.0e-50', -49.522878745280337562704972096744884690799871135809304)) +SELECT x, bc_result, log(x::numeric), log(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 549 +-- input very close to but smaller than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40..7} +-- do +-- for d in {9..1..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1-$d*10^-$p) / l(10)" | head -n 1) +-- echo "('${d}.0e-$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', -1.0000000000000000), +('6.0e-1', -.3979400086720376), +('3.0e-1', -.1549019599857432), +('9.0e-8', -.000000039086505130185422), +('6.0e-8', -.000000026057669695925208), +('3.0e-8', -.000000013028834652530076), +('9.0e-15', -.0000000000000039086503371292840), +('6.0e-15', -.0000000000000026057668914195188), +('3.0e-15', -.0000000000000013028834457097574), +('9.0e-22', -.00000000000000000000039086503371292664), +('6.0e-22', -.00000000000000000000026057668914195110), +('3.0e-22', -.00000000000000000000013028834457097555), +('9.0e-29', -.000000000000000000000000000039086503371292664), +('6.0e-29', -.000000000000000000000000000026057668914195110), +('3.0e-29', -.000000000000000000000000000013028834457097555), +('9.0e-36', -.0000000000000000000000000000000000039086503371292664), +('6.0e-36', -.0000000000000000000000000000000000026057668914195110), +('3.0e-36', -.0000000000000000000000000000000000013028834457097555)) +SELECT '1-'||x, bc_result, log(1.0-x::numeric), log(1.0-x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 550 +-- input very close to but larger than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40..7} +-- do +-- for d in {9..1..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1+$d*10^-$p) / l(10)" | head -n 1) +-- echo "('${d}.0e-$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', .2787536009528290), +('6.0e-1', .2041199826559248), +('3.0e-1', .1139433523068368), +('9.0e-8', .000000039086501612400118), +('6.0e-8', .000000026057668132465074), +('3.0e-8', .000000013028834261665042), +('9.0e-15', .0000000000000039086503371292489), +('6.0e-15', .0000000000000026057668914195031), +('3.0e-15', .0000000000000013028834457097535), +('9.0e-22', .00000000000000000000039086503371292664), +('6.0e-22', .00000000000000000000026057668914195110), +('3.0e-22', .00000000000000000000013028834457097555), +('9.0e-29', .000000000000000000000000000039086503371292664), +('6.0e-29', .000000000000000000000000000026057668914195110), +('3.0e-29', .000000000000000000000000000013028834457097555), +('9.0e-36', .0000000000000000000000000000000000039086503371292664), +('6.0e-36', .0000000000000000000000000000000000026057668914195110), +('3.0e-36', .0000000000000000000000000000000000013028834457097555)) +SELECT '1+'||x, bc_result, log(1.0+x::numeric), log(1.0+x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +== 551 +-- input very large, exact result known +WITH t(x) AS (SELECT '1e'||n FROM generate_series(1, 100) g(n)) +SELECT x, log(x::numeric) FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 552 +-- input very large, non-exact results +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {10..50..7} +-- do +-- for d in {2..9..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l($d*10^$p) / l(10)" | head -n 1) +-- echo "('${d}.0e$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('2.0e10', 10.301029995663981), +('5.0e10', 10.698970004336019), +('8.0e10', 10.903089986991944), +('2.0e17', 17.301029995663981), +('5.0e17', 17.698970004336019), +('8.0e17', 17.903089986991944), +('2.0e24', 24.301029995663981), +('5.0e24', 24.698970004336019), +('8.0e24', 24.903089986991944), +('2.0e31', 31.301029995663981), +('5.0e31', 31.698970004336019), +('8.0e31', 31.903089986991944), +('2.0e38', 38.301029995663981), +('5.0e38', 38.698970004336019), +('8.0e38', 38.903089986991944), +('2.0e45', 45.30102999566398), +('5.0e45', 45.69897000433602), +('8.0e45', 45.90308998699194)) +SELECT x, bc_result, log(x::numeric), log(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/numerology.metadata.json b/parser/testdata/summary/postgres_regress/numerology.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/numerology.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary/postgres_regress/numerology.test b/parser/testdata/summary/postgres_regress/numerology.test new file mode 100644 index 0000000..2f88268 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/numerology.test @@ -0,0 +1,200 @@ +== 001 +|-- +-- NUMEROLOGY +-- Test various combinations of numeric types and functions. +|-- + + +|-- +-- numeric literals +|-- + +SELECT 0b100101; +SELECT 0o273; +SELECT 0x42F; + +-- cases near int4 overflow +SELECT 0b1111111111111111111111111111111; +SELECT 0b10000000000000000000000000000000; +SELECT 0o17777777777; +SELECT 0o20000000000; +SELECT 0x7FFFFFFF; +SELECT 0x80000000; + +SELECT -0b10000000000000000000000000000000; +SELECT -0b10000000000000000000000000000001; +SELECT -0o20000000000; +SELECT -0o20000000001; +SELECT -0x80000000; +SELECT -0x80000001; + +-- cases near int8 overflow +SELECT 0b111111111111111111111111111111111111111111111111111111111111111; +SELECT 0b1000000000000000000000000000000000000000000000000000000000000000; +SELECT 0o777777777777777777777; +SELECT 0o1000000000000000000000; +SELECT 0x7FFFFFFFFFFFFFFF; +SELECT 0x8000000000000000; + +SELECT -0b1000000000000000000000000000000000000000000000000000000000000000; +SELECT -0b1000000000000000000000000000000000000000000000000000000000000001; +SELECT -0o1000000000000000000000; +SELECT -0o1000000000000000000001; +SELECT -0x8000000000000000; +SELECT -0x8000000000000001; + +-- error cases +SELECT 123abc; +SELECT 0x0o; +SELECT 0.a; +SELECT 0.0a; +SELECT .0a; +SELECT 0.0e1a; +SELECT 0.0e; +SELECT 0.0e+a; +PREPARE p1 AS SELECT $1a; + +SELECT 0b; +SELECT 1b; +SELECT 0b0x; + +SELECT 0o; +SELECT 1o; +SELECT 0o0x; + +SELECT 0x; +SELECT 1x; +SELECT 0x0y; + +-- underscores +SELECT 1_000_000; +SELECT 1_2_3; +SELECT 0x1EEE_FFFF; +SELECT 0o2_73; +SELECT 0b_10_0101; + +SELECT 1_000.000_005; +SELECT 1_000.; +SELECT .000_005; +SELECT 1_000.5e0_1; + +DO $$ +DECLARE + i int; +BEGIN + FOR i IN 1_001..1_003 LOOP + RAISE NOTICE 'i = %', i; + END LOOP; +END $$; + +-- error cases +SELECT _100; +SELECT 100_; +SELECT 100__000; + +SELECT _1_000.5; +SELECT 1_000_.5; +SELECT 1_000._5; +SELECT 1_000.5_; +SELECT 1_000.5e_1; + +PREPARE p1 AS SELECT $0_1; + +|-- +-- Test implicit type conversions +-- This fails for Postgres v6.1 (and earlier?) +-- so let's try explicit conversions for now - tgl 97/05/07 +|-- + +CREATE TABLE TEMP_FLOAT (f1 FLOAT8); + +INSERT INTO TEMP_FLOAT (f1) + SELECT float8(f1) FROM INT4_TBL; + +INSERT INTO TEMP_FLOAT (f1) + SELECT float8(f1) FROM INT2_TBL; + +SELECT f1 FROM TEMP_FLOAT + ORDER BY f1; + +-- int4 + +CREATE TABLE TEMP_INT4 (f1 INT4); + +INSERT INTO TEMP_INT4 (f1) + SELECT int4(f1) FROM FLOAT8_TBL + WHERE (f1 > -2147483647) AND (f1 < 2147483647); + +INSERT INTO TEMP_INT4 (f1) + SELECT int4(f1) FROM INT2_TBL; + +SELECT f1 FROM TEMP_INT4 + ORDER BY f1; + +-- int2 + +CREATE TABLE TEMP_INT2 (f1 INT2); + +INSERT INTO TEMP_INT2 (f1) + SELECT int2(f1) FROM FLOAT8_TBL + WHERE (f1 >= -32767) AND (f1 <= 32767); + +INSERT INTO TEMP_INT2 (f1) + SELECT int2(f1) FROM INT4_TBL + WHERE (f1 >= -32767) AND (f1 <= 32767); + +SELECT f1 FROM TEMP_INT2 + ORDER BY f1; + +|-- +-- Group-by combinations +|-- + +CREATE TABLE TEMP_GROUP (f1 INT4, f2 INT4, f3 FLOAT8); + +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; + +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; + +-- 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; + +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; + +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; + +DROP TABLE TEMP_INT2; + +DROP TABLE TEMP_INT4; + +DROP TABLE TEMP_FLOAT; + +DROP TABLE TEMP_GROUP; +-- +ERROR: trailing junk after numeric literal at or near "123abc" +CURSORPOS: 1124 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary/postgres_regress/object_address.metadata.json b/parser/testdata/summary/postgres_regress/object_address.metadata.json new file mode 100644 index 0000000..5c84308 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/object_address.metadata.json @@ -0,0 +1,85 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081" + ] +} diff --git a/parser/testdata/summary/postgres_regress/object_address.test b/parser/testdata/summary/postgres_regress/object_address.test new file mode 100644 index 0000000..3139b37 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/object_address.test @@ -0,0 +1,579 @@ +== 001 +|-- +-- Test for pg_get_object_address +|-- + +-- Clean up in case a prior regression run failed +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +== 002 +DROP ROLE IF EXISTS regress_addr_user +-- +STMT: DropRoleStmt +== 003 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 004 +CREATE USER regress_addr_user +-- +STMT: CreateRoleStmt +== 005 +-- Test generic object addressing/identification functions +CREATE SCHEMA addr_nsp +-- +STMT: CreateSchemaStmt +== 006 +SET search_path TO 'addr_nsp' +-- +STMT: VariableSetStmt +== 007 +CREATE FOREIGN DATA WRAPPER addr_fdw +-- +STMT: CreateFdwStmt +== 008 +CREATE SERVER addr_fserv FOREIGN DATA WRAPPER addr_fdw +-- +STMT: CreateForeignServerStmt +== 009 +CREATE TEXT SEARCH DICTIONARY addr_ts_dict (template=simple) +-- +STMT: DefineStmt +== 010 +CREATE TEXT SEARCH CONFIGURATION addr_ts_conf (copy=english) +-- +STMT: DefineStmt +== 011 +CREATE TEXT SEARCH TEMPLATE addr_ts_temp (lexize=dsimple_lexize) +-- +STMT: DefineStmt +== 012 +CREATE TEXT SEARCH PARSER addr_ts_prs + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +== 013 +CREATE TABLE addr_nsp.gentable ( + a serial primary key CONSTRAINT a_chk CHECK (a > 0), + b text DEFAULT 'hello' +) +-- +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=DDL +STMT: CreateStmt +== 014 +CREATE TABLE addr_nsp.parttable ( + a int PRIMARY KEY +) PARTITION BY RANGE (a) +-- +TABLE: name="addr_nsp.parttable" schema="addr_nsp" table="parttable" ctx=DDL +STMT: CreateStmt +== 015 +CREATE VIEW addr_nsp.genview AS SELECT * from addr_nsp.gentable +-- +TABLE: name="addr_nsp.genview" schema="addr_nsp" table="genview" ctx=DDL +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 016 +CREATE MATERIALIZED VIEW addr_nsp.genmatview AS SELECT * FROM addr_nsp.gentable +-- +TABLE: name="addr_nsp.genmatview" schema="addr_nsp" table="genmatview" ctx=DDL +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 017 +CREATE TYPE addr_nsp.gencomptype AS (a int) +-- +STMT: CompositeTypeStmt +== 018 +CREATE TYPE addr_nsp.genenum AS ENUM ('one', 'two') +-- +STMT: CreateEnumStmt +== 019 +CREATE FOREIGN TABLE addr_nsp.genftable (a int) SERVER addr_fserv +-- +STMT: CreateForeignTableStmt +== 020 +CREATE AGGREGATE addr_nsp.genaggr(int4) (sfunc = int4pl, stype = int4) +-- +STMT: DefineStmt +== 021 +CREATE DOMAIN addr_nsp.gendomain AS int4 CONSTRAINT domconstr CHECK (value > 0) +-- +STMT: CreateDomainStmt +== 022 +CREATE FUNCTION addr_nsp.trig() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN END; $$ +-- +FUNCTION: name="addr_nsp.trig" function="trig" schema="addr_nsp" ctx=DDL +STMT: CreateFunctionStmt +== 023 +CREATE TRIGGER t BEFORE INSERT ON addr_nsp.gentable FOR EACH ROW EXECUTE PROCEDURE addr_nsp.trig() +-- +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=DDL +STMT: CreateTrigStmt +== 024 +CREATE POLICY genpol ON addr_nsp.gentable +-- +STMT: CreatePolicyStmt +== 025 +CREATE PROCEDURE addr_nsp.proc(int4) LANGUAGE SQL AS $$ $$ +-- +FUNCTION: name="addr_nsp.proc" function="proc" schema="addr_nsp" ctx=DDL +STMT: CreateFunctionStmt +== 026 +CREATE SERVER "integer" FOREIGN DATA WRAPPER addr_fdw +-- +STMT: CreateForeignServerStmt +== 027 +CREATE USER MAPPING FOR regress_addr_user SERVER "integer" +-- +STMT: CreateUserMappingStmt +== 028 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user IN SCHEMA public GRANT ALL ON TABLES TO regress_addr_user +-- +STMT: AlterDefaultPrivilegesStmt +== 029 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE DELETE ON TABLES FROM regress_addr_user +-- +STMT: AlterDefaultPrivilegesStmt +== 030 +-- this transform would be quite unsafe to leave lying around, +-- except that the SQL language pays no attention to transforms: +CREATE TRANSFORM FOR int LANGUAGE SQL ( + FROM SQL WITH FUNCTION prsd_lextype(internal), + TO SQL WITH FUNCTION int4recv(internal)) +-- +STMT: CreateTransformStmt +== 031 +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 032 +CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable +-- +STMT: CreatePublicationStmt +== 033 +CREATE PUBLICATION addr_pub_schema FOR TABLES IN SCHEMA addr_nsp +-- +STMT: CreatePublicationStmt +== 034 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 035 +CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE) +-- +STMT: CreateSubscriptionStmt +== 036 +CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable +-- +STMT: CreateStatsStmt +== 037 +-- test some error cases +SELECT pg_get_object_address('stone', '{}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT pg_get_object_address('table', '{}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT pg_get_object_address('table', '{NULL}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 040 +-- unrecognized object types +DO $$ +DECLARE + objtype text; +BEGIN + FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'), + ('toast table column'), ('view column'), ('materialized view column') + LOOP + BEGIN + PERFORM pg_get_object_address(objtype, '{one}', '{}'); + EXCEPTION WHEN invalid_parameter_value THEN + RAISE WARNING 'error for %: %', objtype, sqlerrm; + END; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 041 +-- miscellaneous other errors +select * from pg_get_object_address('operator of access method', '{btree,integer_ops,1}', '{int4,bool}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 042 +select * from pg_get_object_address('operator of access method', '{btree,integer_ops,99}', '{int4,int4}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 043 +select * from pg_get_object_address('function of access method', '{btree,integer_ops,1}', '{int4,bool}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 044 +select * from pg_get_object_address('function of access method', '{btree,integer_ops,99}', '{int4,int4}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 045 +DO $$ +DECLARE + objtype text; + names text[]; + args text[]; +BEGIN + FOR objtype IN VALUES + ('table'), ('index'), ('sequence'), ('view'), + ('materialized view'), ('foreign table'), + ('table column'), ('foreign table column'), + ('aggregate'), ('function'), ('procedure'), ('type'), ('cast'), + ('table constraint'), ('domain constraint'), ('conversion'), ('default value'), + ('operator'), ('operator class'), ('operator family'), ('rule'), ('trigger'), + ('text search parser'), ('text search dictionary'), + ('text search template'), ('text search configuration'), + ('policy'), ('user mapping'), ('default acl'), ('transform'), + ('operator of access method'), ('function of access method'), + ('publication namespace'), ('publication relation') + LOOP + FOR names IN VALUES ('{eins}'), ('{addr_nsp, zwei}'), ('{eins, zwei, drei}') + LOOP + FOR args IN VALUES ('{}'), ('{integer}') + LOOP + BEGIN + PERFORM pg_get_object_address(objtype, names, args); + EXCEPTION WHEN OTHERS THEN + RAISE WARNING 'error for %,%,%: %', objtype, names, args, sqlerrm; + END; + END LOOP; + END LOOP; + END LOOP; +END; +$$ +-- +STMT: DoStmt +== 046 +-- these object types cannot be qualified names +SELECT pg_get_object_address('language', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 047 +SELECT pg_get_object_address('language', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT pg_get_object_address('large object', '{123}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 049 +SELECT pg_get_object_address('large object', '{123,456}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT pg_get_object_address('large object', '{blargh}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 051 +SELECT pg_get_object_address('schema', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 052 +SELECT pg_get_object_address('schema', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 053 +SELECT pg_get_object_address('role', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 054 +SELECT pg_get_object_address('role', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 055 +SELECT pg_get_object_address('database', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 056 +SELECT pg_get_object_address('database', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 057 +SELECT pg_get_object_address('tablespace', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 058 +SELECT pg_get_object_address('tablespace', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT pg_get_object_address('foreign-data wrapper', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT pg_get_object_address('foreign-data wrapper', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT pg_get_object_address('server', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 062 +SELECT pg_get_object_address('server', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT pg_get_object_address('extension', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT pg_get_object_address('extension', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT pg_get_object_address('event trigger', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT pg_get_object_address('event trigger', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT pg_get_object_address('access method', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT pg_get_object_address('access method', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT pg_get_object_address('publication', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT pg_get_object_address('publication', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT pg_get_object_address('subscription', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT pg_get_object_address('subscription', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 073 +-- Make sure that NULL handling is correct. + +-- Temporarily disable fancy output, so as future additions never create +-- a large amount of diffs. + +-- test successful cases +WITH objects (type, name, args) AS (VALUES + ('table', '{addr_nsp, gentable}'::text[], '{}'::text[]), + ('table', '{addr_nsp, parttable}'::text[], '{}'::text[]), + ('index', '{addr_nsp, gentable_pkey}', '{}'), + ('index', '{addr_nsp, parttable_pkey}', '{}'), + ('sequence', '{addr_nsp, gentable_a_seq}', '{}'), + -- toast table + ('view', '{addr_nsp, genview}', '{}'), + ('materialized view', '{addr_nsp, genmatview}', '{}'), + ('foreign table', '{addr_nsp, genftable}', '{}'), + ('table column', '{addr_nsp, gentable, b}', '{}'), + ('foreign table column', '{addr_nsp, genftable, a}', '{}'), + ('aggregate', '{addr_nsp, genaggr}', '{int4}'), + ('function', '{pg_catalog, pg_identify_object}', '{pg_catalog.oid, pg_catalog.oid, int4}'), + ('procedure', '{addr_nsp, proc}', '{int4}'), + ('type', '{pg_catalog._int4}', '{}'), + ('type', '{addr_nsp.gendomain}', '{}'), + ('type', '{addr_nsp.gencomptype}', '{}'), + ('type', '{addr_nsp.genenum}', '{}'), + ('cast', '{int8}', '{int4}'), + ('collation', '{default}', '{}'), + ('table constraint', '{addr_nsp, gentable, a_chk}', '{}'), + ('domain constraint', '{addr_nsp.gendomain}', '{domconstr}'), + ('conversion', '{pg_catalog, koi8_r_to_mic}', '{}'), + ('default value', '{addr_nsp, gentable, b}', '{}'), + ('language', '{plpgsql}', '{}'), + -- large object + ('operator', '{+}', '{int4, int4}'), + ('operator class', '{btree, int4_ops}', '{}'), + ('operator family', '{btree, integer_ops}', '{}'), + ('operator of access method', '{btree,integer_ops,1}', '{integer,integer}'), + ('function of access method', '{btree,integer_ops,2}', '{integer,integer}'), + ('rule', '{addr_nsp, genview, _RETURN}', '{}'), + ('trigger', '{addr_nsp, gentable, t}', '{}'), + ('schema', '{addr_nsp}', '{}'), + ('text search parser', '{addr_ts_prs}', '{}'), + ('text search dictionary', '{addr_ts_dict}', '{}'), + ('text search template', '{addr_ts_temp}', '{}'), + ('text search configuration', '{addr_ts_conf}', '{}'), + ('role', '{regress_addr_user}', '{}'), + -- database + -- tablespace + ('foreign-data wrapper', '{addr_fdw}', '{}'), + ('server', '{addr_fserv}', '{}'), + ('user mapping', '{regress_addr_user}', '{integer}'), + ('default acl', '{regress_addr_user,public}', '{r}'), + ('default acl', '{regress_addr_user}', '{r}'), + -- extension + -- event trigger + ('policy', '{addr_nsp, gentable, genpol}', '{}'), + ('transform', '{int}', '{sql}'), + ('access method', '{btree}', '{}'), + ('publication', '{addr_pub}', '{}'), + ('publication namespace', '{addr_nsp}', '{addr_pub_schema}'), + ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), + ('subscription', '{regress_addr_sub}', '{}'), + ('statistics object', '{addr_nsp, gentable_stat}', '{}') + ) +SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, + -- test roundtrip through pg_identify_object_as_address + ROW(pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)) = + ROW(pg_identify_object(addr2.classid, addr2.objid, addr2.objsubid)) AS roundtrip +FROM objects, + pg_get_object_address(type, name, args) AS addr1, + pg_identify_object_as_address(classid, objid, objsubid) AS ioa (typ, nms, args), + pg_get_object_address(typ, nms, ioa.args) AS addr2 +ORDER BY addr1.classid, addr1.objid, addr1.objsubid +-- +CTE: "objects" +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +FUNCTION: name="pg_identify_object_as_address" function="pg_identify_object_as_address" schema="" ctx=Call +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +== 074 +--- +--- Cleanup resources +--- +DROP FOREIGN DATA WRAPPER addr_fdw CASCADE +-- +STMT: DropStmt +== 075 +DROP PUBLICATION addr_pub +-- +STMT: DropStmt +== 076 +DROP PUBLICATION addr_pub_schema +-- +STMT: DropStmt +== 077 +DROP SUBSCRIPTION regress_addr_sub +-- +STMT: DropSubscriptionStmt +== 078 +DROP SCHEMA addr_nsp CASCADE +-- +STMT: DropStmt +== 079 +DROP OWNED BY regress_addr_user +-- +STMT: DropOwnedStmt +== 080 +DROP USER regress_addr_user +-- +STMT: DropRoleStmt +== 081 +|-- +-- Checks for invalid objects +|-- + +-- Keep this list in the same order as getObjectIdentityParts() +-- in objectaddress.c. +WITH objects (classid, objid, objsubid) AS (VALUES + ('pg_class'::regclass, 0, 0), -- no relation + ('pg_class'::regclass, 'pg_class'::regclass, 100), -- no column for relation + ('pg_proc'::regclass, 0, 0), -- no function + ('pg_type'::regclass, 0, 0), -- no type + ('pg_cast'::regclass, 0, 0), -- no cast + ('pg_collation'::regclass, 0, 0), -- no collation + ('pg_constraint'::regclass, 0, 0), -- no constraint + ('pg_conversion'::regclass, 0, 0), -- no conversion + ('pg_attrdef'::regclass, 0, 0), -- no default attribute + ('pg_language'::regclass, 0, 0), -- no language + ('pg_largeobject'::regclass, 0, 0), -- no large object, no error + ('pg_operator'::regclass, 0, 0), -- no operator + ('pg_opclass'::regclass, 0, 0), -- no opclass, no need to check for no access method + ('pg_opfamily'::regclass, 0, 0), -- no opfamily + ('pg_am'::regclass, 0, 0), -- no access method + ('pg_amop'::regclass, 0, 0), -- no AM operator + ('pg_amproc'::regclass, 0, 0), -- no AM proc + ('pg_rewrite'::regclass, 0, 0), -- no rewrite + ('pg_trigger'::regclass, 0, 0), -- no trigger + ('pg_namespace'::regclass, 0, 0), -- no schema + ('pg_statistic_ext'::regclass, 0, 0), -- no statistics + ('pg_ts_parser'::regclass, 0, 0), -- no TS parser + ('pg_ts_dict'::regclass, 0, 0), -- no TS dictionary + ('pg_ts_template'::regclass, 0, 0), -- no TS template + ('pg_ts_config'::regclass, 0, 0), -- no TS configuration + ('pg_authid'::regclass, 0, 0), -- no role + ('pg_auth_members'::regclass, 0, 0), -- no role membership + ('pg_database'::regclass, 0, 0), -- no database + ('pg_tablespace'::regclass, 0, 0), -- no tablespace + ('pg_foreign_data_wrapper'::regclass, 0, 0), -- no FDW + ('pg_foreign_server'::regclass, 0, 0), -- no server + ('pg_user_mapping'::regclass, 0, 0), -- no user mapping + ('pg_default_acl'::regclass, 0, 0), -- no default ACL + ('pg_extension'::regclass, 0, 0), -- no extension + ('pg_event_trigger'::regclass, 0, 0), -- no event trigger + ('pg_parameter_acl'::regclass, 0, 0), -- no parameter ACL + ('pg_policy'::regclass, 0, 0), -- no policy + ('pg_publication'::regclass, 0, 0), -- no publication + ('pg_publication_namespace'::regclass, 0, 0), -- no publication namespace + ('pg_publication_rel'::regclass, 0, 0), -- no publication relation + ('pg_subscription'::regclass, 0, 0), -- no subscription + ('pg_transform'::regclass, 0, 0) -- no transformation + ) +SELECT ROW(pg_identify_object(objects.classid, objects.objid, objects.objsubid)) + AS ident, + ROW(pg_identify_object_as_address(objects.classid, objects.objid, objects.objsubid)) + AS addr, + pg_describe_object(objects.classid, objects.objid, objects.objsubid) + AS descr +FROM objects +ORDER BY objects.classid, objects.objid, objects.objsubid +-- +CTE: "objects" +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object_as_address" function="pg_identify_object_as_address" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/oid.metadata.json b/parser/testdata/summary/postgres_regress/oid.metadata.json new file mode 100644 index 0000000..6a83420 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/oid.metadata.json @@ -0,0 +1,41 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037" + ] +} diff --git a/parser/testdata/summary/postgres_regress/oid.test b/parser/testdata/summary/postgres_regress/oid.test new file mode 100644 index 0000000..04fcabd --- /dev/null +++ b/parser/testdata/summary/postgres_regress/oid.test @@ -0,0 +1,223 @@ +== 001 +|-- +-- OID +|-- + +CREATE TABLE OID_TBL(f1 oid) +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO OID_TBL(f1) VALUES ('1234') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO OID_TBL(f1) VALUES ('1235') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO OID_TBL(f1) VALUES ('987') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO OID_TBL(f1) VALUES ('-1040') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO OID_TBL(f1) VALUES ('99999999') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO OID_TBL(f1) VALUES ('5 ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO OID_TBL(f1) VALUES (' 10 ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- leading/trailing hard tab is also allowed +INSERT INTO OID_TBL(f1) VALUES (' 15 ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +-- bad inputs +INSERT INTO OID_TBL(f1) VALUES ('') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO OID_TBL(f1) VALUES (' ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO OID_TBL(f1) VALUES ('asdfasd') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO OID_TBL(f1) VALUES ('99asdfasd') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO OID_TBL(f1) VALUES ('5 d') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO OID_TBL(f1) VALUES (' 5d') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO OID_TBL(f1) VALUES ('5 5') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO OID_TBL(f1) VALUES (' - 500') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO OID_TBL(f1) VALUES ('32958209582039852935') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +SELECT * FROM OID_TBL +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +STMT: SelectStmt +== 021 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('1234', 'oid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT pg_input_is_valid('01XYZ', 'oid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT * FROM pg_input_error_info('01XYZ', 'oid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT pg_input_is_valid('9999999999', 'oid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT * FROM pg_input_error_info('9999999999', 'oid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 026 +-- While we're here, check oidvector as well +SELECT pg_input_is_valid(' 1 2 4 ', 'oidvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT pg_input_is_valid('01 01XYZ', 'oidvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT * FROM pg_input_error_info('01 01XYZ', 'oidvector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT pg_input_is_valid('01 9999999999', 'oidvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT * FROM pg_input_error_info('01 9999999999', 'oidvector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT o.* FROM OID_TBL o WHERE o.f1 = 1234 +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +== 032 +SELECT o.* FROM OID_TBL o WHERE o.f1 <> '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +== 033 +SELECT o.* FROM OID_TBL o WHERE o.f1 <= '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +== 034 +SELECT o.* FROM OID_TBL o WHERE o.f1 < '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +== 035 +SELECT o.* FROM OID_TBL o WHERE o.f1 >= '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +== 036 +SELECT o.* FROM OID_TBL o WHERE o.f1 > '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +== 037 +DROP TABLE OID_TBL +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/oidjoins.metadata.json b/parser/testdata/summary/postgres_regress/oidjoins.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/oidjoins.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary/postgres_regress/oidjoins.test b/parser/testdata/summary/postgres_regress/oidjoins.test new file mode 100644 index 0000000..6e429e2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/oidjoins.test @@ -0,0 +1,52 @@ +== 001 +|-- +-- Verify system catalog foreign key relationships +|-- +DO $doblock$ +declare + fk record; + nkeys integer; + cmd text; + err record; +begin + for fk in select * from pg_get_catalog_foreign_keys() + loop + raise notice 'checking % % => % %', + fk.fktable, fk.fkcols, fk.pktable, fk.pkcols; + nkeys := array_length(fk.fkcols, 1); + cmd := 'SELECT ctid'; + for i in 1 .. nkeys loop + cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); + end loop; + if fk.is_array then + cmd := cmd || ' FROM (SELECT ctid'; + for i in 1 .. nkeys-1 loop + cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); + end loop; + cmd := cmd || ', unnest(' || quote_ident(fk.fkcols[nkeys]); + cmd := cmd || ') as ' || quote_ident(fk.fkcols[nkeys]); + cmd := cmd || ' FROM ' || fk.fktable::text || ') fk WHERE '; + else + cmd := cmd || ' FROM ' || fk.fktable::text || ' fk WHERE '; + end if; + if fk.is_opt then + for i in 1 .. nkeys loop + cmd := cmd || quote_ident(fk.fkcols[i]) || ' != 0 AND '; + end loop; + end if; + cmd := cmd || 'NOT EXISTS(SELECT 1 FROM ' || fk.pktable::text || ' pk WHERE '; + for i in 1 .. nkeys loop + if i > 1 then cmd := cmd || ' AND '; end if; + cmd := cmd || 'pk.' || quote_ident(fk.pkcols[i]); + cmd := cmd || ' = fk.' || quote_ident(fk.fkcols[i]); + end loop; + cmd := cmd || ')'; + -- raise notice 'cmd = %', cmd; + for err in execute cmd loop + raise warning 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err; + end loop; + end loop; +end +$doblock$ +-- +STMT: DoStmt diff --git a/parser/testdata/summary/postgres_regress/opr_sanity.metadata.json b/parser/testdata/summary/postgres_regress/opr_sanity.metadata.json new file mode 100644 index 0000000..304478c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/opr_sanity.metadata.json @@ -0,0 +1,134 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130" + ] +} diff --git a/parser/testdata/summary/postgres_regress/opr_sanity.test b/parser/testdata/summary/postgres_regress/opr_sanity.test new file mode 100644 index 0000000..13fa5b5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/opr_sanity.test @@ -0,0 +1,3189 @@ +== 001 +|-- +-- OPR_SANITY +-- Sanity checks for common errors in making operator/procedure system tables: +-- pg_operator, pg_proc, pg_cast, pg_conversion, pg_aggregate, pg_am, +-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index. +|-- +-- Every test failure in this file should be closely inspected. +-- The description of the failing test should be read carefully before +-- adjusting the expected output. In most cases, the queries should +-- not find *any* matching entries. +|-- +-- NB: we assume the oidjoins test will have caught any dangling links, +-- that is OID or REGPROC fields that are not zero and do not match some +-- row in the linked-to table. However, if we want to enforce that a link +-- field can't be 0, we have to check it here. +|-- +-- NB: run this test earlier than the create_operator test, because +-- that test creates some bogus operators... + + +-- **************** pg_proc **************** + +-- Look for illegal values in pg_proc fields. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prolang = 0 OR p1.prorettype = 0 OR + p1.pronargs < 0 OR + p1.pronargdefaults < 0 OR + p1.pronargdefaults > p1.pronargs OR + array_lower(p1.proargtypes, 1) != 0 OR + array_upper(p1.proargtypes, 1) != p1.pronargs-1 OR + 0::oid = ANY (p1.proargtypes) OR + procost <= 0 OR + CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END OR + prokind NOT IN ('f', 'a', 'w', 'p') OR + provolatile NOT IN ('i', 's', 'v') OR + proparallel NOT IN ('s', 'r', 'u') +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="pronargdefaults" +FILTER: schema="" table="p1" column="pronargdefaults" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="" column="procost" +FILTER: schema="" table="" column="proretset" +FILTER: schema="" table="" column="prorows" +FILTER: schema="" table="" column="prorows" +FILTER: schema="" table="" column="prokind" +FILTER: schema="" table="" column="provolatile" +FILTER: schema="" table="" column="proparallel" +STMT: SelectStmt +== 002 +-- prosrc should never be null; it can be empty only if prosqlbody isn't null +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prosrc IS NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prosrc" +STMT: SelectStmt +== 003 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE (prosrc = '' OR prosrc = '-') AND prosqlbody IS NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prosrc" +FILTER: schema="" table="" column="prosrc" +FILTER: schema="" table="" column="prosqlbody" +STMT: SelectStmt +== 004 +-- proretset should only be set for normal functions +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE proretset AND prokind != 'f' +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="proretset" +FILTER: schema="" table="" column="prokind" +STMT: SelectStmt +== 005 +-- currently, no built-in functions should be SECURITY DEFINER; +-- this might change in future, but there will probably never be many. +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE prosecdef +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prosecdef" +STMT: SelectStmt +== 006 +-- pronargdefaults should be 0 iff proargdefaults is null +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE (pronargdefaults <> 0) != (proargdefaults IS NOT NULL) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="pronargdefaults" +FILTER: schema="" table="" column="proargdefaults" +STMT: SelectStmt +== 007 +-- probin should be non-empty for C functions, null everywhere else +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prolang = 13 AND (probin IS NULL OR probin = '' OR probin = '-') +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prolang" +FILTER: schema="" table="" column="probin" +FILTER: schema="" table="" column="probin" +FILTER: schema="" table="" column="probin" +STMT: SelectStmt +== 008 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prolang != 13 AND probin IS NOT NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prolang" +FILTER: schema="" table="" column="probin" +STMT: SelectStmt +== 009 +-- Look for conflicting proc definitions (same names and input datatypes). +-- (This test should be dead code now that we have the unique index +-- pg_proc_proname_args_nsp_index, but I'll leave it in anyway.) + +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.proname = p2.proname AND + p1.pronargs = p2.pronargs AND + p1.proargtypes = p2.proargtypes +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="proname" +FILTER: schema="" table="p2" column="proname" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 010 +-- Considering only built-in procs (prolang = 12), look for multiple uses +-- of the same internal function (ie, matching prosrc fields). It's OK to +-- have several entries with different pronames for the same internal function, +-- but conflicts in the number of arguments and other critical items should +-- be complained of. (We don't check data types here; see next query.) +-- Note: ignore aggregate functions here, since they all point to the same +-- dummy built-in function. + +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid < p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + (p1.prokind != 'a' OR p2.prokind != 'a') AND + (p1.prolang != p2.prolang OR + p1.prokind != p2.prokind OR + p1.prosecdef != p2.prosecdef OR + p1.proleakproof != p2.proleakproof OR + p1.proisstrict != p2.proisstrict OR + p1.proretset != p2.proretset OR + p1.provolatile != p2.provolatile OR + p1.pronargs != p2.pronargs) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosecdef" +FILTER: schema="" table="p2" column="prosecdef" +FILTER: schema="" table="p1" column="proleakproof" +FILTER: schema="" table="p2" column="proleakproof" +FILTER: schema="" table="p1" column="proisstrict" +FILTER: schema="" table="p2" column="proisstrict" +FILTER: schema="" table="p1" column="proretset" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p1" column="provolatile" +FILTER: schema="" table="p2" column="provolatile" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p2" column="pronargs" +STMT: SelectStmt +== 011 +-- Look for uses of different type OIDs in the argument/result type fields +-- for different aliases of the same built-in function. +-- This indicates that the types are being presumed to be binary-equivalent, +-- or that the built-in function is prepared to deal with different types. +-- That's not wrong, necessarily, but we make lists of all the types being +-- so treated. Note that the expected output of this part of the test will +-- need to be modified whenever new pairs of types are made binary-equivalent, +-- or when new polymorphic built-in functions are added! +-- Note: ignore aggregate functions here, since they all point to the same +-- dummy built-in function. Likewise, ignore range and multirange constructor +-- functions. + +SELECT DISTINCT p1.prorettype::regtype, p2.prorettype::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.prorettype < p2.prorettype) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p2" column="prorettype" +STMT: SelectStmt +== 012 +SELECT DISTINCT p1.proargtypes[0]::regtype, p2.proargtypes[0]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.proargtypes[0] < p2.proargtypes[0]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 013 +SELECT DISTINCT p1.proargtypes[1]::regtype, p2.proargtypes[1]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.proargtypes[1] < p2.proargtypes[1]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 014 +SELECT DISTINCT p1.proargtypes[2]::regtype, p2.proargtypes[2]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[2] < p2.proargtypes[2]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 015 +SELECT DISTINCT p1.proargtypes[3]::regtype, p2.proargtypes[3]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[3] < p2.proargtypes[3]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 016 +SELECT DISTINCT p1.proargtypes[4]::regtype, p2.proargtypes[4]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[4] < p2.proargtypes[4]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 017 +SELECT DISTINCT p1.proargtypes[5]::regtype, p2.proargtypes[5]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[5] < p2.proargtypes[5]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 018 +SELECT DISTINCT p1.proargtypes[6]::regtype, p2.proargtypes[6]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[6] < p2.proargtypes[6]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 019 +SELECT DISTINCT p1.proargtypes[7]::regtype, p2.proargtypes[7]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[7] < p2.proargtypes[7]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 020 +-- Look for functions that return type "internal" and do not have any +-- "internal" argument. Such a function would be a security hole since +-- it might be used to call an internal function from an SQL command. +-- As of 7.3 this query should find only internal_in, which is safe because +-- it always throws an error when called. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'internal'::regtype AND NOT + 'internal'::regtype = ANY (p1.proargtypes) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 021 +-- Look for functions that return a polymorphic type and do not have any +-- polymorphic argument. Calls of such functions would be unresolvable +-- at parse time. As of 9.6 this query should find only some input functions +-- and GiST support functions associated with these pseudotypes. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN + ('anyelement'::regtype, 'anyarray'::regtype, 'anynonarray'::regtype, + 'anyenum'::regtype) + AND NOT + ('anyelement'::regtype = ANY (p1.proargtypes) OR + 'anyarray'::regtype = ANY (p1.proargtypes) OR + 'anynonarray'::regtype = ANY (p1.proargtypes) OR + 'anyenum'::regtype = ANY (p1.proargtypes) OR + 'anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 022 +-- anyrange and anymultirange are tighter than the rest, can only resolve +-- from each other + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN ('anyrange'::regtype, 'anymultirange'::regtype) + AND NOT + ('anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 023 +-- similarly for the anycompatible family + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN + ('anycompatible'::regtype, 'anycompatiblearray'::regtype, + 'anycompatiblenonarray'::regtype) + AND NOT + ('anycompatible'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblearray'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblenonarray'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblerange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 024 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'anycompatiblerange'::regtype + AND NOT + 'anycompatiblerange'::regtype = ANY (p1.proargtypes) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 025 +-- Look for functions that accept cstring and are neither datatype input +-- functions nor encoding conversion functions. It's almost never a good +-- idea to use cstring input for a function meant to be called from SQL; +-- text should be used instead, because cstring lacks suitable casts. +-- As of 9.6 this query should find only cstring_out and cstring_send. +-- However, we must manually exclude shell_in, which might or might not be +-- rejected by the EXISTS clause depending on whether there are currently +-- any shell types. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE 'cstring'::regtype = ANY (p1.proargtypes) + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid) + AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid) + AND p1.oid != 'shell_in(cstring)'::regprocedure +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="" column="conproc" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +== 026 +-- Likewise, look for functions that return cstring and aren't datatype output +-- functions nor typmod output functions. +-- As of 9.6 this query should find only cstring_in and cstring_recv. +-- However, we must manually exclude shell_out. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'cstring'::regtype + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid) + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid) + AND p1.oid != 'shell_out(void)'::regprocedure +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="" column="typmodout" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +== 027 +-- Check for length inconsistencies between the various argument-info arrays. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND + array_length(proallargtypes,1) < array_length(proargtypes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +== 028 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargmodes IS NOT NULL AND + array_length(proargmodes,1) < array_length(proargtypes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +== 029 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargnames IS NOT NULL AND + array_length(proargnames,1) < array_length(proargtypes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +== 030 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND proargmodes IS NOT NULL AND + array_length(proallargtypes,1) <> array_length(proargmodes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargmodes" +STMT: SelectStmt +== 031 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND proargnames IS NOT NULL AND + array_length(proallargtypes,1) <> array_length(proargnames,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargnames" +STMT: SelectStmt +== 032 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargmodes IS NOT NULL AND proargnames IS NOT NULL AND + array_length(proargmodes,1) <> array_length(proargnames,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargnames" +STMT: SelectStmt +== 033 +-- Check that proallargtypes matches proargtypes +SELECT p1.oid, p1.proname, p1.proargtypes, p1.proallargtypes, p1.proargmodes +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND + ARRAY(SELECT unnest(proargtypes)) <> + ARRAY(SELECT proallargtypes[i] + FROM generate_series(1, array_length(proallargtypes, 1)) g(i) + WHERE proargmodes IS NULL OR proargmodes[i] IN ('i', 'b', 'v')) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 034 +-- Check for type of the variadic array parameter's elements. +-- provariadic should be ANYOID if the type of the last element is ANYOID, +-- ANYELEMENTOID if the type of the last element is ANYARRAYOID, +-- ANYCOMPATIBLEOID if the type of the last element is ANYCOMPATIBLEARRAYOID, +-- and otherwise the element type corresponding to the array type. + +SELECT oid::regprocedure, provariadic::regtype, proargtypes::regtype[] +FROM pg_proc +WHERE provariadic != 0 +AND case proargtypes[array_length(proargtypes, 1)-1] + WHEN '"any"'::regtype THEN '"any"'::regtype + WHEN 'anyarray'::regtype THEN 'anyelement'::regtype + WHEN 'anycompatiblearray'::regtype THEN 'anycompatible'::regtype + ELSE (SELECT t.oid + FROM pg_type t + WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1]) + END != provariadic +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t"="pg_type" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="provariadic" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="t" column="typarray" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +== 035 +-- 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) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="provariadic" +STMT: SelectStmt +== 036 +-- Check for prosupport functions with the wrong signature +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p2.oid = p1.prosupport AND + (p2.prorettype != 'internal'::regtype OR p2.proretset OR p2.pronargs != 1 + OR p2.proargtypes[0] != 'internal'::regtype) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosupport" +FILTER: schema="" table="p2" column="prorettype" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 037 +-- Insist that all built-in pg_proc entries have descriptions +SELECT p1.oid, p1.proname +FROM pg_proc as p1 LEFT JOIN pg_description as d + ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0 +WHERE d.classoid IS NULL AND p1.oid <= 9999 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "d"="pg_description" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="d" column="classoid" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +== 038 +-- List of built-in leakproof functions +|-- +-- Leakproof functions should only be added after carefully +-- scrutinizing all possibly executed codepaths for possible +-- information leaks. Don't add functions here unless you know what a +-- leakproof function is. If unsure, don't mark it as such. + +-- temporarily disable fancy output, so catalog changes create less diff noise + +SELECT p1.oid::regprocedure +FROM pg_proc p1 JOIN pg_namespace pn + ON pronamespace = pn.oid +WHERE nspname = 'pg_catalog' AND proleakproof +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "pn"="pg_namespace" +FILTER: schema="" table="" column="nspname" +FILTER: schema="" table="" column="proleakproof" +STMT: SelectStmt +== 039 +-- restore normal output mode + +-- List of functions used by libpq's fe-lobj.c +|-- +-- If the output of this query changes, you probably broke libpq. +-- lo_initialize() assumes that there will be at most one match for +-- each listed name. +select proname, oid from pg_catalog.pg_proc +where proname in ( + 'lo_open', + 'lo_close', + 'lo_creat', + 'lo_create', + 'lo_unlink', + 'lo_lseek', + 'lo_lseek64', + 'lo_tell', + 'lo_tell64', + 'lo_truncate', + 'lo_truncate64', + 'loread', + 'lowrite') +and pronamespace = (select oid from pg_catalog.pg_namespace + where nspname = 'pg_catalog') +order by 1 +-- +TABLE: name="pg_catalog.pg_proc" schema="pg_catalog" table="pg_proc" ctx=Select +TABLE: name="pg_catalog.pg_namespace" schema="pg_catalog" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="proname" +FILTER: schema="" table="" column="pronamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +== 040 +-- Check that all immutable functions are marked parallel safe +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE provolatile = 'i' AND proparallel = 'u' +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="provolatile" +FILTER: schema="" table="" column="proparallel" +STMT: SelectStmt +== 041 +-- **************** pg_cast **************** + +-- Catch bogus values in pg_cast columns (other than cases detected by +-- oidjoins test). + +SELECT * +FROM pg_cast c +WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i') + OR castmethod NOT IN ('f', 'b' ,'i') +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +FILTER: schema="" table="" column="castcontext" +FILTER: schema="" table="" column="castmethod" +STMT: SelectStmt +== 042 +-- Check that castfunc is nonzero only for cast methods that need a function, +-- and zero otherwise + +SELECT * +FROM pg_cast c +WHERE (castmethod = 'f' AND castfunc = 0) + OR (castmethod IN ('b', 'i') AND castfunc <> 0) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +FILTER: schema="" table="" column="castmethod" +FILTER: schema="" table="" column="castfunc" +FILTER: schema="" table="" column="castmethod" +FILTER: schema="" table="" column="castfunc" +STMT: SelectStmt +== 043 +-- Look for casts to/from the same type that aren't length coercion functions. +-- (We assume they are length coercions if they take multiple arguments.) +-- Such entries are not necessarily harmful, but they are useless. + +SELECT * +FROM pg_cast c +WHERE castsource = casttarget AND castfunc = 0 +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +FILTER: schema="" table="" column="castfunc" +STMT: SelectStmt +== 044 +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="c" column="castfunc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +STMT: SelectStmt +== 045 +-- Look for cast functions that don't have the right signature. The +-- argument and result types in pg_proc must be the same as, or binary +-- compatible with, what it says in pg_cast. +-- As a special case, we allow casts from CHAR(n) that use functions +-- declared to take TEXT. This does not pass the binary-coercibility test +-- because CHAR(n)-to-TEXT normally invokes rtrim(). However, the results +-- are the same, so long as the function is one that ignores trailing blanks. + +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND + (p.pronargs < 1 OR p.pronargs > 3 + OR NOT (binary_coercible(c.castsource, p.proargtypes[0]) + OR (c.castsource = 'character'::regtype AND + p.proargtypes[0] = 'text'::regtype)) + OR NOT binary_coercible(p.prorettype, c.casttarget)) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "p"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="c" column="castfunc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="c" column="castsource" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="c" column="castsource" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="c" column="casttarget" +STMT: SelectStmt +== 046 +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND + ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR + (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype)) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="c" column="castfunc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +== 047 +-- Look for binary compatible casts that do not have the reverse +-- direction registered as well, or where the reverse direction is not +-- also binary compatible. This is legal, but usually not intended. + +-- As of 7.4, this finds the casts from text and varchar to bpchar, because +-- those are binary-compatible while the reverse way goes through rtrim(). + +-- As of 8.2, this finds the cast from cidr to inet, because that is a +-- trivial binary coercion while the other way goes through inet_to_cidr(). + +-- As of 8.3, this finds the casts from xml to text, varchar, and bpchar, +-- because those are binary-compatible while the reverse goes through +-- texttoxml(), which does an XML syntax check. + +-- As of 9.1, this finds the cast from pg_node_tree to text, which we +-- intentionally do not provide a reverse pathway for. + +SELECT castsource::regtype, casttarget::regtype, castfunc, castcontext +FROM pg_cast c +WHERE c.castmethod = 'b' AND + NOT EXISTS (SELECT 1 FROM pg_cast k + WHERE k.castmethod = 'b' AND + k.castsource = c.casttarget AND + k.casttarget = c.castsource) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "k"="pg_cast" +FILTER: schema="" table="c" column="castmethod" +FILTER: schema="" table="k" column="castmethod" +FILTER: schema="" table="k" column="castsource" +FILTER: schema="" table="c" column="casttarget" +FILTER: schema="" table="k" column="casttarget" +FILTER: schema="" table="c" column="castsource" +STMT: SelectStmt +== 048 +-- **************** pg_conversion **************** + +-- Look for illegal values in pg_conversion fields. + +SELECT c.oid, c.conname +FROM pg_conversion as c +WHERE c.conproc = 0 OR + pg_encoding_to_char(conforencoding) = '' OR + pg_encoding_to_char(contoencoding) = '' +-- +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "c"="pg_conversion" +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FILTER: schema="" table="c" column="conproc" +FILTER: schema="" table="" column="conforencoding" +FILTER: schema="" table="" column="contoencoding" +STMT: SelectStmt +== 049 +-- Look for conprocs that don't have the expected signature. + +SELECT p.oid, p.proname, c.oid, c.conname +FROM pg_proc p, pg_conversion c +WHERE p.oid = c.conproc AND + (p.prorettype != 'int4'::regtype OR p.proretset OR + p.pronargs != 6 OR + p.proargtypes[0] != 'int4'::regtype OR + p.proargtypes[1] != 'int4'::regtype OR + p.proargtypes[2] != 'cstring'::regtype OR + p.proargtypes[3] != 'internal'::regtype OR + p.proargtypes[4] != 'int4'::regtype OR + p.proargtypes[5] != 'bool'::regtype) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "c"="pg_conversion" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="c" column="conproc" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="proretset" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +== 050 +-- Check for conprocs that don't perform the specific conversion that +-- pg_conversion alleges they do, by trying to invoke each conversion +-- on some simple ASCII data. (The conproc should throw an error if +-- it doesn't accept the encodings that are passed to it.) +-- Unfortunately, we can't test non-default conprocs this way, because +-- there is no way to ask convert() to invoke them, and we cannot call +-- them directly from SQL. But there are no non-default built-in +-- conversions anyway. +-- (Similarly, this doesn't cope with any search path issues.) + +SELECT c.oid, c.conname +FROM pg_conversion as c +WHERE condefault AND + convert('ABC'::bytea, pg_encoding_to_char(conforencoding), + pg_encoding_to_char(contoencoding)) != 'ABC' +-- +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "c"="pg_conversion" +FUNCTION: name="convert" function="convert" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="convert" function="convert" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FILTER: schema="" table="" column="condefault" +FILTER: schema="" table="" column="conforencoding" +FILTER: schema="" table="" column="contoencoding" +STMT: SelectStmt +== 051 +-- **************** pg_operator **************** + +-- Look for illegal values in pg_operator fields. + +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 +WHERE (o1.oprkind != 'b' AND o1.oprkind != 'l') OR + o1.oprresult = 0 OR o1.oprcode = 0 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprcode" +STMT: SelectStmt +== 052 +-- Look for missing or unwanted operand types + +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 +WHERE (o1.oprleft = 0 and o1.oprkind != 'l') OR + (o1.oprleft != 0 and o1.oprkind = 'l') OR + o1.oprright = 0 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprright" +STMT: SelectStmt +== 053 +-- Look for conflicting operator definitions (same names and input datatypes). + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oid != o2.oid AND + o1.oprname = o2.oprname AND + o1.oprkind = o2.oprkind AND + o1.oprleft = o2.oprleft AND + o1.oprright = o2.oprright +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprname" +FILTER: schema="" table="o2" column="oprname" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o2" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o2" column="oprleft" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="o2" column="oprright" +STMT: SelectStmt +== 054 +-- Look for commutative operators that don't commute. +-- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x. +-- We expect that B will always say that B.oprcom = A as well; that's not +-- inherently essential, but it would be inefficient not to mark it so. + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprcom = o2.oid AND + (o1.oprkind != 'b' OR + o1.oprleft != o2.oprright OR + o1.oprright != o2.oprleft OR + o1.oprresult != o2.oprresult OR + o1.oid != o2.oprcom) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o2" column="oprright" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="o2" column="oprleft" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o2" column="oprresult" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oprcom" +STMT: SelectStmt +== 055 +-- Look for negatory operators that don't agree. +-- DEFINITIONAL NOTE: If A.oprnegate = B, then both A and B must yield +-- boolean results, and (x A y) == ! (x B y), or the equivalent for +-- single-operand operators. +-- We expect that B will always say that B.oprnegate = A as well; that's not +-- inherently essential, but it would be inefficient not to mark it so. +-- Also, A and B had better not be the same operator. + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprnegate = o2.oid AND + (o1.oprkind != o2.oprkind OR + o1.oprleft != o2.oprleft OR + o1.oprright != o2.oprright OR + o1.oprresult != 'bool'::regtype OR + o2.oprresult != 'bool'::regtype OR + o1.oid != o2.oprnegate OR + o1.oid = o2.oid) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprnegate" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o2" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o2" column="oprleft" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="o2" column="oprright" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o2" column="oprresult" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oprnegate" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oid" +STMT: SelectStmt +== 056 +-- Make a list of the names of operators that are claimed to be commutator +-- pairs. This list will grow over time, but before accepting a new entry +-- make sure you didn't link the wrong operators. + +SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2 +FROM pg_operator o1, pg_operator o2 +WHERE o1.oprcom = o2.oid AND o1.oprname <= o2.oprname +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprname" +FILTER: schema="" table="o2" column="oprname" +STMT: SelectStmt +== 057 +-- Likewise for negator pairs. + +SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2 +FROM pg_operator o1, pg_operator o2 +WHERE o1.oprnegate = o2.oid AND o1.oprname <= o2.oprname +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprnegate" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprname" +FILTER: schema="" table="o2" column="oprname" +STMT: SelectStmt +== 058 +-- A mergejoinable or hashjoinable operator must be binary, must return +-- boolean, and must have a commutator (itself, unless it's a cross-type +-- operator). + +SELECT o1.oid, o1.oprname FROM pg_operator AS o1 +WHERE (o1.oprcanmerge OR o1.oprcanhash) AND NOT + (o1.oprkind = 'b' AND o1.oprresult = 'bool'::regtype AND o1.oprcom != 0) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprcom" +STMT: SelectStmt +== 059 +-- What's more, the commutator had better be mergejoinable/hashjoinable too. + +SELECT o1.oid, o1.oprname, o2.oid, o2.oprname +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprcom = o2.oid AND + (o1.oprcanmerge != o2.oprcanmerge OR + o1.oprcanhash != o2.oprcanhash) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="o2" column="oprcanmerge" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="o2" column="oprcanhash" +STMT: SelectStmt +== 060 +-- Mergejoinable operators should appear as equality members of btree index +-- opfamilies. + +SELECT o1.oid, o1.oprname +FROM pg_operator AS o1 +WHERE o1.oprcanmerge AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + amopopr = o1.oid AND amopstrategy = 3) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +== 061 +-- And the converse. + +SELECT o1.oid, o1.oprname, p.amopfamily +FROM pg_operator AS o1, pg_amop p +WHERE amopopr = o1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopstrategy = 3 + AND NOT o1.oprcanmerge +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p"="pg_amop" +FILTER: schema="" table="" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +== 062 +-- Hashable operators should appear as members of hash index opfamilies. + +SELECT o1.oid, o1.oprname +FROM pg_operator AS o1 +WHERE o1.oprcanhash AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND + amopopr = o1.oid AND amopstrategy = 1) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +== 063 +-- And the converse. + +SELECT o1.oid, o1.oprname, p.amopfamily +FROM pg_operator AS o1, pg_amop p +WHERE amopopr = o1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') + AND NOT o1.oprcanhash +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p"="pg_amop" +FILTER: schema="" table="" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +== 064 +-- Check that each operator defined in pg_operator matches its oprcode entry +-- in pg_proc. Easiest to do this separately for each oprkind. + +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + o1.oprkind = 'b' AND + (p1.pronargs != 2 + OR NOT binary_coercible(p1.prorettype, o1.oprresult) + OR NOT binary_coercible(o1.oprleft, p1.proargtypes[0]) + OR NOT binary_coercible(o1.oprright, p1.proargtypes[1])) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 065 +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + o1.oprkind = 'l' AND + (p1.pronargs != 1 + OR NOT binary_coercible(p1.prorettype, o1.oprresult) + OR NOT binary_coercible(o1.oprright, p1.proargtypes[0]) + OR o1.oprleft != 0) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="o1" column="oprleft" +STMT: SelectStmt +== 066 +-- If the operator is mergejoinable or hashjoinable, its underlying function +-- should not be volatile. + +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + (o1.oprcanmerge OR o1.oprcanhash) AND + p1.provolatile = 'v' +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 067 +-- If oprrest is set, the operator must return boolean, +-- and it must link to a proc with the right signature +-- to be a restriction selectivity estimator. +-- The proc signature we want is: float8 proc(internal, oid, internal, int4) + +SELECT o1.oid, o1.oprname, p2.oid, p2.proname +FROM pg_operator AS o1, pg_proc AS p2 +WHERE o1.oprrest = p2.oid AND + (o1.oprresult != 'bool'::regtype OR + p2.prorettype != 'float8'::regtype OR p2.proretset OR + p2.pronargs != 4 OR + p2.proargtypes[0] != 'internal'::regtype OR + p2.proargtypes[1] != 'oid'::regtype OR + p2.proargtypes[2] != 'internal'::regtype OR + p2.proargtypes[3] != 'int4'::regtype) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprrest" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="p2" column="prorettype" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 068 +-- If oprjoin is set, the operator must be a binary boolean op, +-- and it must link to a proc with the right signature +-- to be a join selectivity estimator. +-- The proc signature we want is: float8 proc(internal, oid, internal, int2, internal) +-- (Note: the old signature with only 4 args is still allowed, but no core +-- estimator should be using it.) + +SELECT o1.oid, o1.oprname, p2.oid, p2.proname +FROM pg_operator AS o1, pg_proc AS p2 +WHERE o1.oprjoin = p2.oid AND + (o1.oprkind != 'b' OR o1.oprresult != 'bool'::regtype OR + p2.prorettype != 'float8'::regtype OR p2.proretset OR + p2.pronargs != 5 OR + p2.proargtypes[0] != 'internal'::regtype OR + p2.proargtypes[1] != 'oid'::regtype OR + p2.proargtypes[2] != 'internal'::regtype OR + p2.proargtypes[3] != 'int2'::regtype OR + p2.proargtypes[4] != 'internal'::regtype) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprjoin" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="p2" column="prorettype" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 069 +-- Insist that all built-in pg_operator entries have descriptions +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 LEFT JOIN pg_description as d + ON o1.tableoid = d.classoid and o1.oid = d.objoid and d.objsubid = 0 +WHERE d.classoid IS NULL AND o1.oid <= 9999 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "d"="pg_description" +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="d" column="classoid" +FILTER: schema="" table="o1" column="oid" +STMT: SelectStmt +== 070 +-- Check that operators' underlying functions have suitable comments, +-- namely 'implementation of XXX operator'. (Note: it's not necessary to +-- put such comments into pg_proc.dat; initdb will generate them as needed.) +-- In some cases involving legacy names for operators, there are multiple +-- operators referencing the same pg_proc entry, so ignore operators whose +-- comments say they are deprecated. +-- We also have a few functions that are both operator support and meant to +-- be called directly; those should have comments matching their operator. +WITH funcdescs AS ( + SELECT p.oid as p_oid, proname, o.oid as o_oid, + pd.description as prodesc, + 'implementation of ' || oprname || ' operator' as expecteddesc, + od.description as oprdesc + FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid + LEFT JOIN pg_description pd ON + (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0) + LEFT JOIN pg_description od ON + (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0) + WHERE o.oid <= 9999 +) +SELECT * FROM funcdescs + WHERE prodesc IS DISTINCT FROM expecteddesc + AND oprdesc NOT LIKE 'deprecated%' + AND prodesc IS DISTINCT FROM oprdesc +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "o"="pg_operator" +ALIAS: "od"="pg_description" +ALIAS: "p"="pg_proc" +ALIAS: "pd"="pg_description" +CTE: "funcdescs" +FILTER: schema="" table="" column="prodesc" +FILTER: schema="" table="" column="expecteddesc" +FILTER: schema="" table="" column="oprdesc" +FILTER: schema="" table="" column="prodesc" +FILTER: schema="" table="" column="oprdesc" +FILTER: schema="" table="o" column="oid" +STMT: SelectStmt +== 071 +-- Show all the operator-implementation functions that have their own +-- comments. This should happen only in cases where the function and +-- operator syntaxes are both documented at the user level. +-- This should be a pretty short list; it's mostly legacy cases. +WITH funcdescs AS ( + SELECT p.oid as p_oid, proname, o.oid as o_oid, + pd.description as prodesc, + 'implementation of ' || oprname || ' operator' as expecteddesc, + od.description as oprdesc + FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid + LEFT JOIN pg_description pd ON + (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0) + LEFT JOIN pg_description od ON + (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0) + WHERE o.oid <= 9999 +) +SELECT p_oid, proname, prodesc FROM funcdescs + WHERE prodesc IS DISTINCT FROM expecteddesc + AND oprdesc NOT LIKE 'deprecated%' +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "o"="pg_operator" +ALIAS: "od"="pg_description" +ALIAS: "p"="pg_proc" +ALIAS: "pd"="pg_description" +CTE: "funcdescs" +FILTER: schema="" table="" column="prodesc" +FILTER: schema="" table="" column="expecteddesc" +FILTER: schema="" table="" column="oprdesc" +FILTER: schema="" table="o" column="oid" +STMT: SelectStmt +== 072 +-- Operators that are commutator pairs should have identical volatility +-- and leakproofness markings on their implementation functions. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprcom = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o2" column="oprcode" +FILTER: schema="" table="p1" column="provolatile" +FILTER: schema="" table="p2" column="provolatile" +FILTER: schema="" table="p1" column="proleakproof" +FILTER: schema="" table="p2" column="proleakproof" +STMT: SelectStmt +== 073 +-- Likewise for negator pairs. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprnegate = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprnegate" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o2" column="oprcode" +FILTER: schema="" table="p1" column="provolatile" +FILTER: schema="" table="p2" column="provolatile" +FILTER: schema="" table="p1" column="proleakproof" +FILTER: schema="" table="p2" column="proleakproof" +STMT: SelectStmt +== 074 +-- Btree comparison operators' functions should have the same volatility +-- and leakproofness markings as the associated comparison support function. +SELECT pp.oid::regprocedure as proc, pp.provolatile as vp, pp.proleakproof as lp, + po.oid::regprocedure as opr, po.provolatile as vo, po.proleakproof as lo +FROM pg_proc pp, pg_proc po, pg_operator o, pg_amproc ap, pg_amop ao +WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND + ao.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + ao.amopfamily = ap.amprocfamily AND + ao.amoplefttype = ap.amproclefttype AND + ao.amoprighttype = ap.amprocrighttype AND + ap.amprocnum = 1 AND + (pp.provolatile != po.provolatile OR + pp.proleakproof != po.proleakproof) +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "ao"="pg_amop" +ALIAS: "ap"="pg_amproc" +ALIAS: "o"="pg_operator" +ALIAS: "po"="pg_proc" +ALIAS: "pp"="pg_proc" +FILTER: schema="" table="pp" column="oid" +FILTER: schema="" table="ap" column="amproc" +FILTER: schema="" table="po" column="oid" +FILTER: schema="" table="o" column="oprcode" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="ao" column="amopopr" +FILTER: schema="" table="ao" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +== 075 +-- **************** pg_aggregate **************** + +-- Look for illegal values in pg_aggregate fields. + +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggfnoid = 0 OR aggtransfn = 0 OR + aggkind NOT IN ('n', 'o', 'h') OR + aggnumdirectargs < 0 OR + (aggkind = 'n' AND aggnumdirectargs > 0) OR + aggfinalmodify NOT IN ('r', 's', 'w') OR + aggmfinalmodify NOT IN ('r', 's', 'w') OR + aggtranstype = 0 OR aggtransspace < 0 OR aggmtransspace < 0 +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +FILTER: schema="" table="" column="aggfnoid" +FILTER: schema="" table="" column="aggtransfn" +FILTER: schema="" table="" column="aggkind" +FILTER: schema="" table="" column="aggnumdirectargs" +FILTER: schema="" table="" column="aggkind" +FILTER: schema="" table="" column="aggnumdirectargs" +FILTER: schema="" table="" column="aggfinalmodify" +FILTER: schema="" table="" column="aggmfinalmodify" +FILTER: schema="" table="" column="aggtranstype" +FILTER: schema="" table="" column="aggtransspace" +FILTER: schema="" table="" column="aggmtransspace" +STMT: SelectStmt +== 076 +-- Make sure the matching pg_proc entry is sensible, too. + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + (p.prokind != 'a' OR p.proretset OR p.pronargs < a.aggnumdirectargs) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="prokind" +FILTER: schema="" table="p" column="proretset" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +STMT: SelectStmt +== 077 +-- Make sure there are no prokind = PROKIND_AGGREGATE pg_proc entries without matches. + +SELECT oid, proname +FROM pg_proc as p +WHERE p.prokind = 'a' AND + NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="p" column="prokind" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +STMT: SelectStmt +== 078 +-- If there is no finalfn then the output type must be the transtype. + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggfinalfn" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggtranstype" +STMT: SelectStmt +== 079 +-- Cross-check transfn against its entry in pg_proc. +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggtranstype) + OR NOT binary_coercible(a.aggtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + OR (p.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[3], ptr.proargtypes[4])) + -- we could carry the check further, but 4 args is enough for now + OR (p.pronargs > 4) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proretset" +FILTER: schema="" table="ptr" column="pronargs" +FILTER: schema="" table="a" column="aggkind" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="ptr" column="prorettype" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +STMT: SelectStmt +== 080 +-- Cross-check finalfn (if present) against its entry in pg_proc. + +SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn +WHERE a.aggfnoid = p.oid AND + a.aggfinalfn = pfn.oid AND + (pfn.proretset OR + NOT binary_coercible(pfn.prorettype, p.prorettype) OR + NOT binary_coercible(a.aggtranstype, pfn.proargtypes[0]) OR + CASE WHEN a.aggfinalextra THEN pfn.pronargs != p.pronargs + 1 + ELSE pfn.pronargs != a.aggnumdirectargs + 1 END + OR (pfn.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1])) + OR (pfn.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) + OR (pfn.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "pfn"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggfinalfn" +FILTER: schema="" table="pfn" column="oid" +FILTER: schema="" table="pfn" column="proretset" +FILTER: schema="" table="pfn" column="prorettype" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="a" column="aggfinalextra" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +STMT: SelectStmt +== 081 +-- If transfn is strict then either initval should be non-NULL, or +-- input type should match transtype so that the first non-null input +-- can be assigned as the state value. + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggtransfn = ptr.oid AND ptr.proisstrict AND + a.agginitval IS NULL AND + NOT binary_coercible(p.proargtypes[0], a.aggtranstype) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proisstrict" +FILTER: schema="" table="a" column="agginitval" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="a" column="aggtranstype" +STMT: SelectStmt +== 082 +-- Check for inconsistent specifications of moving-aggregate columns. + +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggmtranstype != 0 AND + (aggmtransfn = 0 OR aggminvtransfn = 0) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +FILTER: schema="" table="" column="aggmtranstype" +FILTER: schema="" table="" column="aggmtransfn" +FILTER: schema="" table="" column="aggminvtransfn" +STMT: SelectStmt +== 083 +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggmtranstype = 0 AND + (aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR + aggmtransspace != 0 OR aggminitval IS NOT NULL) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +FILTER: schema="" table="" column="aggmtranstype" +FILTER: schema="" table="" column="aggmtransfn" +FILTER: schema="" table="" column="aggminvtransfn" +FILTER: schema="" table="" column="aggmfinalfn" +FILTER: schema="" table="" column="aggmtransspace" +FILTER: schema="" table="" column="aggminitval" +STMT: SelectStmt +== 084 +-- If there is no mfinalfn then the output type must be the mtranstype. + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn != 0 AND + a.aggmfinalfn = 0 AND p.prorettype != a.aggmtranstype +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="a" column="aggmfinalfn" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +STMT: SelectStmt +== 085 +-- Cross-check mtransfn (if present) against its entry in pg_proc. +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proretset" +FILTER: schema="" table="ptr" column="pronargs" +FILTER: schema="" table="a" column="aggkind" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="ptr" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +STMT: SelectStmt +== 086 +-- Cross-check minvtransfn (if present) against its entry in pg_proc. +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggminvtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggminvtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proretset" +FILTER: schema="" table="ptr" column="pronargs" +FILTER: schema="" table="a" column="aggkind" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="ptr" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +STMT: SelectStmt +== 087 +-- Cross-check mfinalfn (if present) against its entry in pg_proc. + +SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn +WHERE a.aggfnoid = p.oid AND + a.aggmfinalfn = pfn.oid AND + (pfn.proretset OR + NOT binary_coercible(pfn.prorettype, p.prorettype) OR + NOT binary_coercible(a.aggmtranstype, pfn.proargtypes[0]) OR + CASE WHEN a.aggmfinalextra THEN pfn.pronargs != p.pronargs + 1 + ELSE pfn.pronargs != a.aggnumdirectargs + 1 END + OR (pfn.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1])) + OR (pfn.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) + OR (pfn.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "pfn"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmfinalfn" +FILTER: schema="" table="pfn" column="oid" +FILTER: schema="" table="pfn" column="proretset" +FILTER: schema="" table="pfn" column="prorettype" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="a" column="aggmfinalextra" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +STMT: SelectStmt +== 088 +-- If mtransfn is strict then either minitval should be non-NULL, or +-- input type should match mtranstype so that the first non-null input +-- can be assigned as the state value. + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND ptr.proisstrict AND + a.aggminitval IS NULL AND + NOT binary_coercible(p.proargtypes[0], a.aggmtranstype) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proisstrict" +FILTER: schema="" table="a" column="aggminitval" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="a" column="aggmtranstype" +STMT: SelectStmt +== 089 +-- mtransfn and minvtransfn should have same strictness setting. + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname, iptr.oid, iptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr, pg_proc AS iptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND + a.aggminvtransfn = iptr.oid AND + ptr.proisstrict != iptr.proisstrict +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "iptr"="pg_proc" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="a" column="aggminvtransfn" +FILTER: schema="" table="iptr" column="oid" +FILTER: schema="" table="ptr" column="proisstrict" +FILTER: schema="" table="iptr" column="proisstrict" +STMT: SelectStmt +== 090 +-- Check that all combine functions have signature +-- combine(transtype, transtype) returns transtype + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggcombinefn = p.oid AND + (p.pronargs != 2 OR + p.prorettype != p.proargtypes[0] OR + p.prorettype != p.proargtypes[1] OR + NOT binary_coercible(a.aggtranstype, p.proargtypes[0])) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggcombinefn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +== 091 +-- Check that no combine function for an INTERNAL transtype is strict. + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggcombinefn = p.oid AND + a.aggtranstype = 'internal'::regtype AND p.proisstrict +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggcombinefn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="p" column="proisstrict" +STMT: SelectStmt +== 092 +-- serialize/deserialize functions should be specified only for aggregates +-- with transtype internal and a combine function, and we should have both +-- or neither of them. + +SELECT aggfnoid, aggtranstype, aggserialfn, aggdeserialfn +FROM pg_aggregate +WHERE (aggserialfn != 0 OR aggdeserialfn != 0) + AND (aggtranstype != 'internal'::regtype OR aggcombinefn = 0 OR + aggserialfn = 0 OR aggdeserialfn = 0) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggserialfn" +FILTER: schema="" table="" column="aggdeserialfn" +FILTER: schema="" table="" column="aggtranstype" +FILTER: schema="" table="" column="aggcombinefn" +FILTER: schema="" table="" column="aggserialfn" +FILTER: schema="" table="" column="aggdeserialfn" +STMT: SelectStmt +== 093 +-- Check that all serialization functions have signature +-- serialize(internal) returns bytea +-- Also insist that they be strict; it's wasteful to run them on NULLs. + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggserialfn = p.oid AND + (p.prorettype != 'bytea'::regtype OR p.pronargs != 1 OR + p.proargtypes[0] != 'internal'::regtype OR + NOT p.proisstrict) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggserialfn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proisstrict" +STMT: SelectStmt +== 094 +-- Check that all deserialization functions have signature +-- deserialize(bytea, internal) returns internal +-- Also insist that they be strict; it's wasteful to run them on NULLs. + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggdeserialfn = p.oid AND + (p.prorettype != 'internal'::regtype OR p.pronargs != 2 OR + p.proargtypes[0] != 'bytea'::regtype OR + p.proargtypes[1] != 'internal'::regtype OR + NOT p.proisstrict) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggdeserialfn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proisstrict" +STMT: SelectStmt +== 095 +-- Check that aggregates which have the same transition function also have +-- the same combine, serialization, and deserialization functions. +-- While that isn't strictly necessary, it's fishy if they don't. + +SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn, + b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn +FROM + pg_aggregate a, pg_aggregate b +WHERE + a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND + (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn + OR a.aggdeserialfn != b.aggdeserialfn) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "b"="pg_aggregate" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="b" column="aggfnoid" +FILTER: schema="" table="a" column="aggtransfn" +FILTER: schema="" table="b" column="aggtransfn" +FILTER: schema="" table="a" column="aggcombinefn" +FILTER: schema="" table="b" column="aggcombinefn" +FILTER: schema="" table="a" column="aggserialfn" +FILTER: schema="" table="b" column="aggserialfn" +FILTER: schema="" table="a" column="aggdeserialfn" +FILTER: schema="" table="b" column="aggdeserialfn" +STMT: SelectStmt +== 096 +-- Cross-check aggsortop (if present) against pg_operator. +-- We expect to find entries for bool_and, bool_or, every, max, and min. + +SELECT DISTINCT proname, oprname +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +STMT: SelectStmt +== 097 +-- Check datatypes match + +SELECT a.aggfnoid::oid, o.oid +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + (oprkind != 'b' OR oprresult != 'boolean'::regtype + OR oprleft != p.proargtypes[0] OR oprright != p.proargtypes[0]) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="oprkind" +FILTER: schema="" table="" column="oprresult" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="" column="oprright" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +== 098 +-- Check operator is a suitable btree opfamily member + +SELECT a.aggfnoid::oid, o.oid +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + NOT EXISTS(SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopopr = o.oid + AND amoplefttype = o.oprleft + AND amoprighttype = o.oprright) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +== 099 +-- Check correspondence of btree strategies and names + +SELECT DISTINCT proname, oprname, amopstrategy +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p, + pg_amop as ao +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + amopopr = o.oid AND + amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "ao"="pg_amop" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="amopopr" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +== 100 +-- Check that there are not aggregates with the same name and different +-- numbers of arguments. While not technically wrong, we have a project policy +-- to avoid this because it opens the door for confusion in connection with +-- ORDER BY: novices frequently put the ORDER BY in the wrong place. +-- See the fate of the single-argument form of string_agg() for history. +-- (Note: we don't forbid users from creating such aggregates; the policy is +-- just to think twice before creating built-in aggregates like this.) +-- The only aggregates that should show up here are count(x) and count(*). + +SELECT p1.oid::regprocedure, p2.oid::regprocedure +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid < p2.oid AND p1.proname = p2.proname AND + p1.prokind = 'a' AND p2.prokind = 'a' AND + array_dims(p1.proargtypes) != array_dims(p2.proargtypes) +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="proname" +FILTER: schema="" table="p2" column="proname" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +== 101 +-- For the same reason, built-in aggregates with default arguments are no good. + +SELECT oid, proname +FROM pg_proc AS p +WHERE prokind = 'a' AND proargdefaults IS NOT NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p"="pg_proc" +FILTER: schema="" table="" column="prokind" +FILTER: schema="" table="" column="proargdefaults" +STMT: SelectStmt +== 102 +-- For the same reason, we avoid creating built-in variadic aggregates, except +-- that variadic ordered-set aggregates are OK (since they have special syntax +-- that is not subject to the misplaced ORDER BY issue). + +SELECT p.oid, proname +FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid +WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n' +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="" column="prokind" +FILTER: schema="" table="" column="provariadic" +FILTER: schema="" table="a" column="aggkind" +STMT: SelectStmt +== 103 +-- **************** pg_opfamily **************** + +-- Look for illegal values in pg_opfamily fields + +SELECT f.oid +FROM pg_opfamily as f +WHERE f.opfmethod = 0 OR f.opfnamespace = 0 +-- +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +ALIAS: "f"="pg_opfamily" +FILTER: schema="" table="f" column="opfmethod" +FILTER: schema="" table="f" column="opfnamespace" +STMT: SelectStmt +== 104 +-- Look for opfamilies having no opclasses. While most validation of +-- opfamilies is now handled by AM-specific amvalidate functions, that's +-- driven from pg_opclass entries below, so an empty opfamily would not +-- get noticed. + +SELECT oid, opfname FROM pg_opfamily f +WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid) +-- +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "f"="pg_opfamily" +FILTER: schema="" table="" column="opcfamily" +FILTER: schema="" table="f" column="oid" +STMT: SelectStmt +== 105 +-- **************** pg_opclass **************** + +-- Look for illegal values in pg_opclass fields + +SELECT c1.oid +FROM pg_opclass AS c1 +WHERE c1.opcmethod = 0 OR c1.opcnamespace = 0 OR c1.opcfamily = 0 + OR c1.opcintype = 0 +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "c1"="pg_opclass" +FILTER: schema="" table="c1" column="opcmethod" +FILTER: schema="" table="c1" column="opcnamespace" +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="c1" column="opcintype" +STMT: SelectStmt +== 106 +-- opcmethod must match owning opfamily's opfmethod + +SELECT c1.oid, f1.oid +FROM pg_opclass AS c1, pg_opfamily AS f1 +WHERE c1.opcfamily = f1.oid AND c1.opcmethod != f1.opfmethod +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +ALIAS: "c1"="pg_opclass" +ALIAS: "f1"="pg_opfamily" +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="f1" column="oid" +FILTER: schema="" table="c1" column="opcmethod" +FILTER: schema="" table="f1" column="opfmethod" +STMT: SelectStmt +== 107 +-- There should not be multiple entries in pg_opclass with opcdefault true +-- and the same opcmethod/opcintype combination. + +SELECT c1.oid, c2.oid +FROM pg_opclass AS c1, pg_opclass AS c2 +WHERE c1.oid != c2.oid AND + c1.opcmethod = c2.opcmethod AND c1.opcintype = c2.opcintype AND + c1.opcdefault AND c2.opcdefault +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "c1"="pg_opclass" +ALIAS: "c2"="pg_opclass" +FILTER: schema="" table="c1" column="oid" +FILTER: schema="" table="c2" column="oid" +FILTER: schema="" table="c1" column="opcmethod" +FILTER: schema="" table="c2" column="opcmethod" +FILTER: schema="" table="c1" column="opcintype" +FILTER: schema="" table="c2" column="opcintype" +FILTER: schema="" table="c1" column="opcdefault" +FILTER: schema="" table="c2" column="opcdefault" +STMT: SelectStmt +== 108 +-- Ask access methods to validate opclasses +-- (this replaces a lot of SQL-level checks that used to be done in this file) + +SELECT oid, opcname FROM pg_opclass WHERE NOT amvalidate(oid) +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +FUNCTION: name="amvalidate" function="amvalidate" schema="" ctx=Call +FUNCTION: name="amvalidate" function="amvalidate" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 109 +-- **************** pg_am **************** + +-- Look for illegal values in pg_am fields + +SELECT a1.oid, a1.amname +FROM pg_am AS a1 +WHERE a1.amhandler = 0 +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a1"="pg_am" +FILTER: schema="" table="a1" column="amhandler" +STMT: SelectStmt +== 110 +-- Check for index amhandler functions with the wrong signature + +SELECT a1.oid, a1.amname, p1.oid, p1.proname +FROM pg_am AS a1, pg_proc AS p1 +WHERE p1.oid = a1.amhandler AND a1.amtype = 'i' AND + (p1.prorettype != 'index_am_handler'::regtype + OR p1.proretset + OR p1.pronargs != 1 + OR p1.proargtypes[0] != 'internal'::regtype) +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_am" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amhandler" +FILTER: schema="" table="a1" column="amtype" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 111 +-- Check for table amhandler functions with the wrong signature + +SELECT a1.oid, a1.amname, p1.oid, p1.proname +FROM pg_am AS a1, pg_proc AS p1 +WHERE p1.oid = a1.amhandler AND a1.amtype = 't' AND + (p1.prorettype != 'table_am_handler'::regtype + OR p1.proretset + OR p1.pronargs != 1 + OR p1.proargtypes[0] != 'internal'::regtype) +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_am" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amhandler" +FILTER: schema="" table="a1" column="amtype" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 112 +-- **************** pg_amop **************** + +-- Look for illegal values in pg_amop fields + +SELECT a1.amopfamily, a1.amopstrategy +FROM pg_amop as a1 +WHERE a1.amopfamily = 0 OR a1.amoplefttype = 0 OR a1.amoprighttype = 0 + OR a1.amopopr = 0 OR a1.amopmethod = 0 OR a1.amopstrategy < 1 +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +ALIAS: "a1"="pg_amop" +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="a1" column="amoplefttype" +FILTER: schema="" table="a1" column="amoprighttype" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="a1" column="amopmethod" +FILTER: schema="" table="a1" column="amopstrategy" +STMT: SelectStmt +== 113 +SELECT a1.amopfamily, a1.amopstrategy +FROM pg_amop as a1 +WHERE NOT ((a1.amoppurpose = 's' AND a1.amopsortfamily = 0) OR + (a1.amoppurpose = 'o' AND a1.amopsortfamily <> 0)) +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +ALIAS: "a1"="pg_amop" +FILTER: schema="" table="a1" column="amoppurpose" +FILTER: schema="" table="a1" column="amopsortfamily" +FILTER: schema="" table="a1" column="amoppurpose" +FILTER: schema="" table="a1" column="amopsortfamily" +STMT: SelectStmt +== 114 +-- amopmethod must match owning opfamily's opfmethod + +SELECT a1.oid, f1.oid +FROM pg_amop AS a1, pg_opfamily AS f1 +WHERE a1.amopfamily = f1.oid AND a1.amopmethod != f1.opfmethod +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "f1"="pg_opfamily" +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="f1" column="oid" +FILTER: schema="" table="a1" column="amopmethod" +FILTER: schema="" table="f1" column="opfmethod" +STMT: SelectStmt +== 115 +-- Make a list of all the distinct operator names being used in particular +-- strategy slots. This is a bit hokey, since the list might need to change +-- in future releases, but it's an effective way of spotting mistakes such as +-- swapping two operators within a family. + +SELECT DISTINCT amopmethod, amopstrategy, oprname +FROM pg_amop a1 LEFT JOIN pg_operator o1 ON amopopr = o1.oid +ORDER BY 1, 2, 3 +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +STMT: SelectStmt +== 116 +-- Check that all opclass search operators have selectivity estimators. +-- This is not absolutely required, but it seems a reasonable thing +-- to insist on for all standard datatypes. + +SELECT a1.amopfamily, a1.amopopr, o1.oid, o1.oprname +FROM pg_amop AS a1, pg_operator AS o1 +WHERE a1.amopopr = o1.oid AND a1.amoppurpose = 's' AND + (o1.oprrest = 0 OR o1.oprjoin = 0) +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="a1" column="amoppurpose" +FILTER: schema="" table="o1" column="oprrest" +FILTER: schema="" table="o1" column="oprjoin" +STMT: SelectStmt +== 117 +-- Check that each opclass in an opfamily has associated operators, that is +-- ones whose oprleft matches opcintype (possibly by coercion). + +SELECT c1.opcname, c1.opcfamily +FROM pg_opclass AS c1 +WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS a1 + WHERE a1.amopfamily = c1.opcfamily + AND binary_coercible(c1.opcintype, a1.amoplefttype)) +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "c1"="pg_opclass" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="c1" column="opcintype" +FILTER: schema="" table="a1" column="amoplefttype" +STMT: SelectStmt +== 118 +-- Check that each operator listed in pg_amop has an associated opclass, +-- that is one whose opcintype matches oprleft (possibly by coercion). +-- Otherwise the operator is useless because it cannot be matched to an index. +-- (In principle it could be useful to list such operators in multiple-datatype +-- btree opfamilies, but in practice you'd expect there to be an opclass for +-- every datatype the family knows about.) + +SELECT a1.amopfamily, a1.amopstrategy, a1.amopopr +FROM pg_amop AS a1 +WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS c1 + WHERE c1.opcfamily = a1.amopfamily + AND binary_coercible(c1.opcintype, a1.amoplefttype)) +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "c1"="pg_opclass" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="c1" column="opcintype" +FILTER: schema="" table="a1" column="amoplefttype" +STMT: SelectStmt +== 119 +-- Operators that are primary members of opclasses must be immutable (else +-- it suggests that the index ordering isn't fixed). Operators that are +-- cross-type members need only be stable, since they are just shorthands +-- for index probe queries. + +SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc +FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1 +WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND + a1.amoplefttype = a1.amoprighttype AND + p1.provolatile != 'i' +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amoplefttype" +FILTER: schema="" table="a1" column="amoprighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 120 +SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc +FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1 +WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND + a1.amoplefttype != a1.amoprighttype AND + p1.provolatile = 'v' +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amoplefttype" +FILTER: schema="" table="a1" column="amoprighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 121 +-- **************** pg_amproc **************** + +-- Look for illegal values in pg_amproc fields + +SELECT a1.amprocfamily, a1.amprocnum +FROM pg_amproc as a1 +WHERE a1.amprocfamily = 0 OR a1.amproclefttype = 0 OR a1.amprocrighttype = 0 + OR a1.amprocnum < 0 OR a1.amproc = 0 +-- +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +ALIAS: "a1"="pg_amproc" +FILTER: schema="" table="a1" column="amprocfamily" +FILTER: schema="" table="a1" column="amproclefttype" +FILTER: schema="" table="a1" column="amprocrighttype" +FILTER: schema="" table="a1" column="amprocnum" +FILTER: schema="" table="a1" column="amproc" +STMT: SelectStmt +== 122 +-- Support routines that are primary members of opfamilies must be immutable +-- (else it suggests that the index ordering isn't fixed). But cross-type +-- members need only be stable, since they are just shorthands +-- for index probe queries. + +SELECT a1.amprocfamily, a1.amproc, p1.prosrc +FROM pg_amproc AS a1, pg_proc AS p1 +WHERE a1.amproc = p1.oid AND + a1.amproclefttype = a1.amprocrighttype AND + p1.provolatile != 'i' +-- +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amproc" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amproc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amproclefttype" +FILTER: schema="" table="a1" column="amprocrighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 123 +SELECT a1.amprocfamily, a1.amproc, p1.prosrc +FROM pg_amproc AS a1, pg_proc AS p1 +WHERE a1.amproc = p1.oid AND + a1.amproclefttype != a1.amprocrighttype AND + p1.provolatile = 'v' +-- +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amproc" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amproc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amproclefttype" +FILTER: schema="" table="a1" column="amprocrighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 124 +-- Almost all of the core distribution's Btree opclasses can use one of the +-- two generic "equalimage" functions as their support function 4. Look for +-- opclasses that don't allow deduplication unconditionally here. +|-- +-- Newly added Btree opclasses don't have to support deduplication. It will +-- usually be trivial to add support, though. Note that the expected output +-- of this part of the test will need to be updated when a new opclass cannot +-- support deduplication (by using btequalimage). +SELECT amp.amproc::regproc AS proc, opf.opfname AS opfamily_name, + opc.opcname AS opclass_name, opc.opcintype::regtype AS opcintype +FROM pg_am AS am +JOIN pg_opclass AS opc ON opc.opcmethod = am.oid +JOIN pg_opfamily AS opf ON opc.opcfamily = opf.oid +LEFT JOIN pg_amproc AS amp ON amp.amprocfamily = opf.oid AND + amp.amproclefttype = opc.opcintype AND amp.amprocnum = 4 +WHERE am.amname = 'btree' AND + amp.amproc IS DISTINCT FROM 'btequalimage'::regproc +ORDER BY 1, 2, 3 +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "amp"="pg_amproc" +ALIAS: "opc"="pg_opclass" +ALIAS: "opf"="pg_opfamily" +FILTER: schema="" table="am" column="amname" +FILTER: schema="" table="amp" column="amproc" +STMT: SelectStmt +== 125 +-- **************** pg_index **************** + +-- Look for illegal values in pg_index fields. + +SELECT indexrelid, indrelid +FROM pg_index +WHERE indexrelid = 0 OR indrelid = 0 OR + indnatts <= 0 OR indnatts > 32 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indnatts" +STMT: SelectStmt +== 126 +-- oidvector and int2vector fields should be of length indnatts. + +SELECT indexrelid, indrelid +FROM pg_index +WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR + array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR + array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR + array_lower(indoption, 1) != 0 OR array_upper(indoption, 1) != indnatts-1 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FILTER: schema="" table="" column="indkey" +FILTER: schema="" table="" column="indkey" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indclass" +FILTER: schema="" table="" column="indclass" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indcollation" +FILTER: schema="" table="" column="indcollation" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indoption" +FILTER: schema="" table="" column="indoption" +FILTER: schema="" table="" column="indnatts" +STMT: SelectStmt +== 127 +-- Check that opclasses and collations match the underlying columns. +-- (As written, this test ignores expression indexes.) + +SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname +FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index) ss, + pg_attribute a, + pg_opclass opc +WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND + (NOT binary_coercible(atttypid, opcintype) OR icoll != attcollation) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "opc"="pg_opclass" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="attrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="" column="ikey" +FILTER: schema="" table="opc" column="oid" +FILTER: schema="" table="" column="iclass" +FILTER: schema="" table="" column="atttypid" +FILTER: schema="" table="" column="opcintype" +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="attcollation" +STMT: SelectStmt +== 128 +-- For system catalogs, be even tighter: nearly all indexes should be +-- exact type matches not binary-coercible matches. At this writing +-- the only exception is an OID index on a regproc column. + +SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname +FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index + WHERE indrelid < 16384) ss, + pg_attribute a, + pg_opclass opc +WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND + (opcintype != atttypid OR icoll != attcollation) +ORDER BY 1 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "opc"="pg_opclass" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="attrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="" column="ikey" +FILTER: schema="" table="opc" column="oid" +FILTER: schema="" table="" column="iclass" +FILTER: schema="" table="" column="opcintype" +FILTER: schema="" table="" column="atttypid" +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="attcollation" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +== 129 +-- Check for system catalogs with collation-sensitive ordering. This is not +-- a representational error in pg_index, but simply wrong catalog design. +-- It's bad because we expect to be able to clone template0 and assign the +-- copy a different database collation. It would especially not work for +-- shared catalogs. + +SELECT relname, attname, attcollation +FROM pg_class c, pg_attribute a +WHERE c.oid = attrelid AND c.oid < 16384 AND + c.relkind != 'v' AND -- we don't care about columns in views + attcollation != 0 AND + attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="c" column="relkind" +FILTER: schema="" table="" column="attcollation" +FILTER: schema="" table="" column="attcollation" +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +== 130 +-- Double-check that collation-sensitive indexes have "C" collation, too. + +SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll +FROM (SELECT indexrelid, indrelid, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index + WHERE indrelid < 16384) ss +WHERE icoll != 0 AND + icoll != (SELECT oid FROM pg_collation WHERE collname = 'C') +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="collname" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json b/parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json new file mode 100644 index 0000000..e6f6795 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json @@ -0,0 +1,139 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135" + ] +} diff --git a/parser/testdata/summary/postgres_regress/partition_aggregate.test b/parser/testdata/summary/postgres_regress/partition_aggregate.test new file mode 100644 index 0000000..c273a80 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_aggregate.test @@ -0,0 +1,1132 @@ +== 001 +|-- +-- PARTITION_AGGREGATE +-- Test partitionwise aggregation on partitioned tables +|-- +-- Note: to ensure plan stability, it's a good idea to make the partitions of +-- any one partitioned table in this test all have different numbers of rows. +|-- + +-- Enable partitionwise aggregate, which by default is disabled. +SET enable_partitionwise_aggregate TO true +-- +STMT: VariableSetStmt +== 002 +-- Enable partitionwise join, which by default is disabled. +SET enable_partitionwise_join TO true +-- +STMT: VariableSetStmt +== 003 +-- Disable parallel plans. +SET max_parallel_workers_per_gather TO 0 +-- +STMT: VariableSetStmt +== 004 +-- Disable incremental sort, which can influence selected plans due to fuzz factor. +SET enable_incremental_sort TO off +-- +STMT: VariableSetStmt +== 005 +|-- +-- Tests for list partitioned tables. +|-- +CREATE TABLE pagg_tab (a int, b int, c text, d int) PARTITION BY LIST(c) +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=DDL +STMT: CreateStmt +== 006 +CREATE TABLE pagg_tab_p1 PARTITION OF pagg_tab FOR VALUES IN ('0000', '0001', '0002', '0003', '0004') +-- +TABLE: name="pagg_tab_p1" schema="" table="pagg_tab_p1" ctx=DDL +STMT: CreateStmt +== 007 +CREATE TABLE pagg_tab_p2 PARTITION OF pagg_tab FOR VALUES IN ('0005', '0006', '0007', '0008') +-- +TABLE: name="pagg_tab_p2" schema="" table="pagg_tab_p2" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE pagg_tab_p3 PARTITION OF pagg_tab FOR VALUES IN ('0009', '0010', '0011') +-- +TABLE: name="pagg_tab_p3" schema="" table="pagg_tab_p3" ctx=DDL +STMT: CreateStmt +== 009 +INSERT INTO pagg_tab SELECT i % 20, i % 30, to_char(i % 12, 'FM0000'), i % 30 FROM generate_series(0, 2999) i +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 010 +ANALYZE pagg_tab +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=DDL +STMT: VacuumStmt +== 011 +-- When GROUP BY clause matches; full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 012 +SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 014 +SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 015 +-- Check with multiple columns in GROUP BY +EXPLAIN (COSTS OFF) +SELECT a, c, count(*) FROM pagg_tab GROUP BY a, c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 016 +-- Check with multiple columns in GROUP BY, order in GROUP BY is reversed +EXPLAIN (COSTS OFF) +SELECT a, c, count(*) FROM pagg_tab GROUP BY c, a +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 017 +-- Check with multiple columns in GROUP BY, order in target-list is reversed +EXPLAIN (COSTS OFF) +SELECT c, a, count(*) FROM pagg_tab GROUP BY a, c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 018 +-- Test when input relation for grouping is dummy +EXPLAIN (COSTS OFF) +SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 019 +SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 020 +EXPLAIN (COSTS OFF) +SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 021 +SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +== 022 +-- Test GroupAggregate paths by disabling hash aggregates. +SET enable_hashagg TO false +-- +STMT: VariableSetStmt +== 023 +-- When GROUP BY clause matches full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 024 +SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 025 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 026 +SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 027 +-- Test partitionwise grouping without any aggregates +EXPLAIN (COSTS OFF) +SELECT c FROM pagg_tab GROUP BY c ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 028 +SELECT c FROM pagg_tab GROUP BY c ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +STMT: SelectStmt +== 029 +EXPLAIN (COSTS OFF) +SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 030 +SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 031 +RESET enable_hashagg +-- +STMT: VariableSetStmt +== 032 +-- ROLLUP, partitionwise aggregation does not apply +EXPLAIN (COSTS OFF) +SELECT c, sum(a) FROM pagg_tab GROUP BY rollup(c) ORDER BY 1, 2 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 033 +-- ORDERED SET within the aggregate. +-- Full aggregation; since all the rows that belong to the same group come +-- from the same partition, having an ORDER BY within the aggregate doesn't +-- make any difference. +EXPLAIN (COSTS OFF) +SELECT c, sum(b order by a) FROM pagg_tab GROUP BY c ORDER BY 1, 2 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 034 +-- Since GROUP BY clause does not match with PARTITION KEY; we need to do +-- partial aggregation. However, ORDERED SET are not partial safe and thus +-- partitionwise aggregation plan is not generated. +EXPLAIN (COSTS OFF) +SELECT a, sum(b order by a) FROM pagg_tab GROUP BY a ORDER BY 1, 2 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 035 +-- JOIN query + +CREATE TABLE pagg_tab1(x int, y int) PARTITION BY RANGE(x) +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=DDL +STMT: CreateStmt +== 036 +CREATE TABLE pagg_tab1_p1 PARTITION OF pagg_tab1 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="pagg_tab1_p1" schema="" table="pagg_tab1_p1" ctx=DDL +STMT: CreateStmt +== 037 +CREATE TABLE pagg_tab1_p2 PARTITION OF pagg_tab1 FOR VALUES FROM (10) TO (20) +-- +TABLE: name="pagg_tab1_p2" schema="" table="pagg_tab1_p2" ctx=DDL +STMT: CreateStmt +== 038 +CREATE TABLE pagg_tab1_p3 PARTITION OF pagg_tab1 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="pagg_tab1_p3" schema="" table="pagg_tab1_p3" ctx=DDL +STMT: CreateStmt +== 039 +CREATE TABLE pagg_tab2(x int, y int) PARTITION BY RANGE(y) +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=DDL +STMT: CreateStmt +== 040 +CREATE TABLE pagg_tab2_p1 PARTITION OF pagg_tab2 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="pagg_tab2_p1" schema="" table="pagg_tab2_p1" ctx=DDL +STMT: CreateStmt +== 041 +CREATE TABLE pagg_tab2_p2 PARTITION OF pagg_tab2 FOR VALUES FROM (10) TO (20) +-- +TABLE: name="pagg_tab2_p2" schema="" table="pagg_tab2_p2" ctx=DDL +STMT: CreateStmt +== 042 +CREATE TABLE pagg_tab2_p3 PARTITION OF pagg_tab2 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="pagg_tab2_p3" schema="" table="pagg_tab2_p3" ctx=DDL +STMT: CreateStmt +== 043 +INSERT INTO pagg_tab1 SELECT i % 30, i % 20 FROM generate_series(0, 299, 2) i +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO pagg_tab2 SELECT i % 20, i % 30 FROM generate_series(0, 299, 3) i +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 045 +ANALYZE pagg_tab1 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=DDL +STMT: VacuumStmt +== 046 +ANALYZE pagg_tab2 +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=DDL +STMT: VacuumStmt +== 047 +-- When GROUP BY clause matches; full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 048 +SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: SelectStmt +== 049 +-- Check with whole-row reference; partitionwise aggregation does not apply +EXPLAIN (COSTS OFF) +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: SelectStmt +== 051 +-- GROUP BY having other matching key +EXPLAIN (COSTS OFF) +SELECT t2.y, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t2.y ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +-- Also test GroupAggregate paths by disabling hash aggregates. +SET enable_hashagg TO false +-- +STMT: VariableSetStmt +== 053 +EXPLAIN (COSTS OFF) +SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 054 +SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: SelectStmt +== 055 +RESET enable_hashagg +-- +STMT: VariableSetStmt +== 056 +-- Check with LEFT/RIGHT/FULL OUTER JOINs which produces NULL values for +-- aggregation + +-- LEFT JOIN, should produce partial partitionwise aggregation plan as +-- GROUP BY is on nullable column +EXPLAIN (COSTS OFF) +SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 057 +SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 058 +-- RIGHT JOIN, should produce full partitionwise aggregation plan as +-- GROUP BY is on non-nullable column +EXPLAIN (COSTS OFF) +SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 059 +SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 060 +-- FULL JOIN, should produce partial partitionwise aggregation plan as +-- GROUP BY is on nullable column +EXPLAIN (COSTS OFF) +SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 061 +SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 062 +-- LEFT JOIN, with dummy relation on right side, ideally +-- should produce full partitionwise aggregation plan as GROUP BY is on +-- non-nullable columns. +-- But right now we are unable to do partitionwise join in this case. +EXPLAIN (COSTS OFF) +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 063 +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +== 064 +-- FULL JOIN, with dummy relations on both sides, ideally +-- should produce partial partitionwise aggregation plan as GROUP BY is on +-- nullable columns. +-- But right now we are unable to do partitionwise join in this case. +EXPLAIN (COSTS OFF) +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 065 +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +== 066 +-- Empty join relation because of empty outer side, no partitionwise agg plan +EXPLAIN (COSTS OFF) +SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +ALIAS: "b"="pagg_tab2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 067 +SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +ALIAS: "b"="pagg_tab2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 068 +-- Partition by multiple columns + +CREATE TABLE pagg_tab_m (a int, b int, c int) PARTITION BY RANGE(a, ((a+b)/2)) +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=DDL +STMT: CreateStmt +== 069 +CREATE TABLE pagg_tab_m_p1 PARTITION OF pagg_tab_m FOR VALUES FROM (0, 0) TO (12, 12) +-- +TABLE: name="pagg_tab_m_p1" schema="" table="pagg_tab_m_p1" ctx=DDL +STMT: CreateStmt +== 070 +CREATE TABLE pagg_tab_m_p2 PARTITION OF pagg_tab_m FOR VALUES FROM (12, 12) TO (22, 22) +-- +TABLE: name="pagg_tab_m_p2" schema="" table="pagg_tab_m_p2" ctx=DDL +STMT: CreateStmt +== 071 +CREATE TABLE pagg_tab_m_p3 PARTITION OF pagg_tab_m FOR VALUES FROM (22, 22) TO (30, 30) +-- +TABLE: name="pagg_tab_m_p3" schema="" table="pagg_tab_m_p3" ctx=DDL +STMT: CreateStmt +== 072 +INSERT INTO pagg_tab_m SELECT i % 30, i % 40, i % 50 FROM generate_series(0, 2999) i +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 073 +ANALYZE pagg_tab_m +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=DDL +STMT: VacuumStmt +== 074 +-- Partial aggregation as GROUP BY clause does not match with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 075 +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 076 +-- Full aggregation as GROUP BY clause matches with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 077 +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 078 +-- Full aggregation as PARTITION KEY is part of GROUP BY clause +EXPLAIN (COSTS OFF) +SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 079 +SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 080 +-- Test with multi-level partitioning scheme + +CREATE TABLE pagg_tab_ml (a int, b int, c text) PARTITION BY RANGE(a) +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DDL +STMT: CreateStmt +== 081 +CREATE TABLE pagg_tab_ml_p1 PARTITION OF pagg_tab_ml FOR VALUES FROM (0) TO (12) +-- +TABLE: name="pagg_tab_ml_p1" schema="" table="pagg_tab_ml_p1" ctx=DDL +STMT: CreateStmt +== 082 +CREATE TABLE pagg_tab_ml_p2 PARTITION OF pagg_tab_ml FOR VALUES FROM (12) TO (20) PARTITION BY LIST (c) +-- +TABLE: name="pagg_tab_ml_p2" schema="" table="pagg_tab_ml_p2" ctx=DDL +STMT: CreateStmt +== 083 +CREATE TABLE pagg_tab_ml_p2_s1 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0000', '0001', '0002') +-- +TABLE: name="pagg_tab_ml_p2_s1" schema="" table="pagg_tab_ml_p2_s1" ctx=DDL +STMT: CreateStmt +== 084 +CREATE TABLE pagg_tab_ml_p2_s2 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0003') +-- +TABLE: name="pagg_tab_ml_p2_s2" schema="" table="pagg_tab_ml_p2_s2" ctx=DDL +STMT: CreateStmt +== 085 +-- This level of partitioning has different column positions than the parent +CREATE TABLE pagg_tab_ml_p3(b int, c text, a int) PARTITION BY RANGE (b) +-- +TABLE: name="pagg_tab_ml_p3" schema="" table="pagg_tab_ml_p3" ctx=DDL +STMT: CreateStmt +== 086 +CREATE TABLE pagg_tab_ml_p3_s1(c text, a int, b int) +-- +TABLE: name="pagg_tab_ml_p3_s1" schema="" table="pagg_tab_ml_p3_s1" ctx=DDL +STMT: CreateStmt +== 087 +CREATE TABLE pagg_tab_ml_p3_s2 PARTITION OF pagg_tab_ml_p3 FOR VALUES FROM (7) TO (10) +-- +TABLE: name="pagg_tab_ml_p3_s2" schema="" table="pagg_tab_ml_p3_s2" ctx=DDL +STMT: CreateStmt +== 088 +ALTER TABLE pagg_tab_ml_p3 ATTACH PARTITION pagg_tab_ml_p3_s1 FOR VALUES FROM (0) TO (7) +-- +TABLE: name="pagg_tab_ml_p3" schema="" table="pagg_tab_ml_p3" ctx=DDL +STMT: AlterTableStmt +== 089 +ALTER TABLE pagg_tab_ml ATTACH PARTITION pagg_tab_ml_p3 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DDL +STMT: AlterTableStmt +== 090 +INSERT INTO pagg_tab_ml SELECT i % 30, i % 10, to_char(i % 4, 'FM0000') FROM generate_series(0, 29999) i +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 091 +ANALYZE pagg_tab_ml +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DDL +STMT: VacuumStmt +== 092 +-- For Parallel Append +SET max_parallel_workers_per_gather TO 2 +-- +STMT: VariableSetStmt +== 093 +SET parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 094 +-- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY +-- for level 1 only. For subpartitions, GROUP BY clause does not match with +-- PARTITION KEY, but still we do not see a partial aggregation as array_agg() +-- is not partial agg safe. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 095 +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 096 +-- Without ORDER BY clause, to test Gather at top-most path +EXPLAIN (COSTS OFF) +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 097 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +== 098 +-- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY +-- for level 1 only. For subpartitions, GROUP BY clause does not match with +-- PARTITION KEY, thus we will have a partial aggregation for them. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 099 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 100 +-- Partial aggregation at all levels as GROUP BY clause does not match with +-- PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 101 +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 102 +-- Full aggregation at all levels as GROUP BY clause matches with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 103 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 104 +-- Parallelism within partitionwise aggregates + +SET min_parallel_table_scan_size TO '8kB' +-- +STMT: VariableSetStmt +== 105 +SET parallel_setup_cost TO 0 +-- +STMT: VariableSetStmt +== 106 +-- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY +-- for level 1 only. For subpartitions, GROUP BY clause does not match with +-- PARTITION KEY, thus we will have a partial aggregation for them. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 107 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 108 +-- Partial aggregation at all levels as GROUP BY clause does not match with +-- PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 109 +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 110 +-- Full aggregation at all levels as GROUP BY clause matches with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 111 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 112 +-- Parallelism within partitionwise aggregates (single level) + +-- Add few parallel setup cost, so that we will see a plan which gathers +-- partially created paths even for full aggregation and sticks a single Gather +-- followed by finalization step. +-- Without this, the cost of doing partial aggregation + Gather + finalization +-- for each partition and then Append over it turns out to be same and this +-- wins as we add it first. This parallel_setup_cost plays a vital role in +-- costing such plans. +SET parallel_setup_cost TO 10 +-- +STMT: VariableSetStmt +== 113 +CREATE TABLE pagg_tab_para(x int, y int) PARTITION BY RANGE(x) +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: CreateStmt +== 114 +CREATE TABLE pagg_tab_para_p1 PARTITION OF pagg_tab_para FOR VALUES FROM (0) TO (12) +-- +TABLE: name="pagg_tab_para_p1" schema="" table="pagg_tab_para_p1" ctx=DDL +STMT: CreateStmt +== 115 +CREATE TABLE pagg_tab_para_p2 PARTITION OF pagg_tab_para FOR VALUES FROM (12) TO (22) +-- +TABLE: name="pagg_tab_para_p2" schema="" table="pagg_tab_para_p2" ctx=DDL +STMT: CreateStmt +== 116 +CREATE TABLE pagg_tab_para_p3 PARTITION OF pagg_tab_para FOR VALUES FROM (22) TO (30) +-- +TABLE: name="pagg_tab_para_p3" schema="" table="pagg_tab_para_p3" ctx=DDL +STMT: CreateStmt +== 117 +INSERT INTO pagg_tab_para SELECT i % 30, i % 20 FROM generate_series(0, 29999) i +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 118 +ANALYZE pagg_tab_para +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: VacuumStmt +== 119 +-- When GROUP BY clause matches; full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 120 +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 121 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 122 +SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 123 +-- Test when parent can produce parallel paths but not any (or some) of its children +-- (Use one more aggregate to tilt the cost estimates for the plan we want) +ALTER TABLE pagg_tab_para_p1 SET (parallel_workers = 0) +-- +TABLE: name="pagg_tab_para_p1" schema="" table="pagg_tab_para_p1" ctx=DDL +STMT: AlterTableStmt +== 124 +ALTER TABLE pagg_tab_para_p3 SET (parallel_workers = 0) +-- +TABLE: name="pagg_tab_para_p3" schema="" table="pagg_tab_para_p3" ctx=DDL +STMT: AlterTableStmt +== 125 +ANALYZE pagg_tab_para +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: VacuumStmt +== 126 +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 127 +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 128 +ALTER TABLE pagg_tab_para_p2 SET (parallel_workers = 0) +-- +TABLE: name="pagg_tab_para_p2" schema="" table="pagg_tab_para_p2" ctx=DDL +STMT: AlterTableStmt +== 129 +ANALYZE pagg_tab_para +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: VacuumStmt +== 130 +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 131 +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 132 +-- Reset parallelism parameters to get partitionwise aggregation plan. +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt +== 133 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +== 134 +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 135 +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/partition_info.metadata.json b/parser/testdata/summary/postgres_regress/partition_info.metadata.json new file mode 100644 index 0000000..2ff9db8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_info.metadata.json @@ -0,0 +1,77 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073" + ] +} diff --git a/parser/testdata/summary/postgres_regress/partition_info.test b/parser/testdata/summary/postgres_regress/partition_info.test new file mode 100644 index 0000000..e3c4cc8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_info.test @@ -0,0 +1,425 @@ +== 001 +|-- +-- Tests for functions providing information about partitions +|-- +SELECT * FROM pg_partition_tree(NULL) +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 002 +SELECT * FROM pg_partition_tree(0) +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 003 +SELECT * FROM pg_partition_ancestors(NULL) +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT * FROM pg_partition_ancestors(0) +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT pg_partition_root(NULL) +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT pg_partition_root(0) +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- Test table partition trees +CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a) +-- +TABLE: name="ptif_test" schema="" table="ptif_test" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE ptif_test0 PARTITION OF ptif_test + FOR VALUES FROM (minvalue) TO (0) PARTITION BY list (b) +-- +TABLE: name="ptif_test0" schema="" table="ptif_test0" ctx=DDL +STMT: CreateStmt +== 009 +CREATE TABLE ptif_test01 PARTITION OF ptif_test0 FOR VALUES IN (1) +-- +TABLE: name="ptif_test01" schema="" table="ptif_test01" ctx=DDL +STMT: CreateStmt +== 010 +CREATE TABLE ptif_test1 PARTITION OF ptif_test + FOR VALUES FROM (0) TO (100) PARTITION BY list (b) +-- +TABLE: name="ptif_test1" schema="" table="ptif_test1" ctx=DDL +STMT: CreateStmt +== 011 +CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1) +-- +TABLE: name="ptif_test11" schema="" table="ptif_test11" ctx=DDL +STMT: CreateStmt +== 012 +CREATE TABLE ptif_test2 PARTITION OF ptif_test + FOR VALUES FROM (100) TO (200) +-- +TABLE: name="ptif_test2" schema="" table="ptif_test2" ctx=DDL +STMT: CreateStmt +== 013 +-- This partitioned table should remain with no partitions. +CREATE TABLE ptif_test3 PARTITION OF ptif_test + FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b) +-- +TABLE: name="ptif_test3" schema="" table="ptif_test3" ctx=DDL +STMT: CreateStmt +== 014 +-- Test pg_partition_root for tables +SELECT pg_partition_root('ptif_test') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT pg_partition_root('ptif_test0') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT pg_partition_root('ptif_test01') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT pg_partition_root('ptif_test3') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- Test index partition tree +CREATE INDEX ptif_test_index ON ONLY ptif_test (a) +-- +TABLE: name="ptif_test" schema="" table="ptif_test" ctx=DDL +STMT: IndexStmt +== 019 +CREATE INDEX ptif_test0_index ON ONLY ptif_test0 (a) +-- +TABLE: name="ptif_test0" schema="" table="ptif_test0" ctx=DDL +STMT: IndexStmt +== 020 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test0_index +-- +STMT: AlterTableStmt +== 021 +CREATE INDEX ptif_test01_index ON ptif_test01 (a) +-- +TABLE: name="ptif_test01" schema="" table="ptif_test01" ctx=DDL +STMT: IndexStmt +== 022 +ALTER INDEX ptif_test0_index ATTACH PARTITION ptif_test01_index +-- +STMT: AlterTableStmt +== 023 +CREATE INDEX ptif_test1_index ON ONLY ptif_test1 (a) +-- +TABLE: name="ptif_test1" schema="" table="ptif_test1" ctx=DDL +STMT: IndexStmt +== 024 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test1_index +-- +STMT: AlterTableStmt +== 025 +CREATE INDEX ptif_test11_index ON ptif_test11 (a) +-- +TABLE: name="ptif_test11" schema="" table="ptif_test11" ctx=DDL +STMT: IndexStmt +== 026 +ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index +-- +STMT: AlterTableStmt +== 027 +CREATE INDEX ptif_test2_index ON ptif_test2 (a) +-- +TABLE: name="ptif_test2" schema="" table="ptif_test2" ctx=DDL +STMT: IndexStmt +== 028 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index +-- +STMT: AlterTableStmt +== 029 +CREATE INDEX ptif_test3_index ON ptif_test3 (a) +-- +TABLE: name="ptif_test3" schema="" table="ptif_test3" ctx=DDL +STMT: IndexStmt +== 030 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index +-- +STMT: AlterTableStmt +== 031 +-- Test pg_partition_root for indexes +SELECT pg_partition_root('ptif_test_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT pg_partition_root('ptif_test0_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT pg_partition_root('ptif_test01_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT pg_partition_root('ptif_test3_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 035 +-- List all tables members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- List tables from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- List from leaf table +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 038 +-- List from partitioned table with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 039 +-- List all ancestors of root and leaf tables +SELECT * FROM pg_partition_ancestors('ptif_test01') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT * FROM pg_partition_ancestors('ptif_test') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- List all members using pg_partition_root with leaf table reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01')) p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- List all indexes members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test_index') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 043 +-- List indexes from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0_index') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 044 +-- List from leaf index +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01_index') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- List from partitioned index with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3_index') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 046 +-- List all members using pg_partition_root with leaf index reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- List all ancestors of root and leaf indexes +SELECT * FROM pg_partition_ancestors('ptif_test01_index') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT * FROM pg_partition_ancestors('ptif_test_index') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 049 +DROP TABLE ptif_test +-- +TABLE: name="ptif_test" schema="" table="ptif_test" ctx=DDL +STMT: DropStmt +== 050 +-- Table that is not part of any partition tree is not listed. +CREATE TABLE ptif_normal_table(a int) +-- +TABLE: name="ptif_normal_table" schema="" table="ptif_normal_table" ctx=DDL +STMT: CreateStmt +== 051 +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_normal_table') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 052 +SELECT * FROM pg_partition_ancestors('ptif_normal_table') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 053 +SELECT pg_partition_root('ptif_normal_table') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 054 +DROP TABLE ptif_normal_table +-- +TABLE: name="ptif_normal_table" schema="" table="ptif_normal_table" ctx=DDL +STMT: DropStmt +== 055 +-- Various partitioning-related functions return empty/NULL if passed relations +-- of types that cannot be part of a partition tree; for example, views, +-- materialized views, legacy inheritance children or parents, etc. +CREATE VIEW ptif_test_view AS SELECT 1 +-- +TABLE: name="ptif_test_view" schema="" table="ptif_test_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 056 +CREATE MATERIALIZED VIEW ptif_test_matview AS SELECT 1 +-- +TABLE: name="ptif_test_matview" schema="" table="ptif_test_matview" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 057 +CREATE TABLE ptif_li_parent () +-- +TABLE: name="ptif_li_parent" schema="" table="ptif_li_parent" ctx=DDL +STMT: CreateStmt +== 058 +CREATE TABLE ptif_li_child () INHERITS (ptif_li_parent) +-- +TABLE: name="ptif_li_child" schema="" table="ptif_li_child" ctx=DDL +STMT: CreateStmt +== 059 +SELECT * FROM pg_partition_tree('ptif_test_view') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT * FROM pg_partition_tree('ptif_test_matview') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT * FROM pg_partition_tree('ptif_li_parent') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 062 +SELECT * FROM pg_partition_tree('ptif_li_child') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT * FROM pg_partition_ancestors('ptif_test_view') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT * FROM pg_partition_ancestors('ptif_test_matview') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT * FROM pg_partition_ancestors('ptif_li_parent') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT * FROM pg_partition_ancestors('ptif_li_child') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT pg_partition_root('ptif_test_view') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT pg_partition_root('ptif_test_matview') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT pg_partition_root('ptif_li_parent') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT pg_partition_root('ptif_li_child') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +== 071 +DROP VIEW ptif_test_view +-- +STMT: DropStmt +== 072 +DROP MATERIALIZED VIEW ptif_test_matview +-- +STMT: DropStmt +== 073 +DROP TABLE ptif_li_parent, ptif_li_child +-- +TABLE: name="ptif_li_parent" schema="" table="ptif_li_parent" ctx=DDL +TABLE: name="ptif_li_child" schema="" table="ptif_li_child" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/partition_join.metadata.json b/parser/testdata/summary/postgres_regress/partition_join.metadata.json new file mode 100644 index 0000000..6fa7813 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_join.metadata.json @@ -0,0 +1,604 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600" + ] +} diff --git a/parser/testdata/summary/postgres_regress/partition_join.test b/parser/testdata/summary/postgres_regress/partition_join.test new file mode 100644 index 0000000..eb24433 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_join.test @@ -0,0 +1,4915 @@ +== 001 +|-- +-- PARTITION_JOIN +-- Test partitionwise join between partitioned tables +|-- + +-- Enable partitionwise join, which by default is disabled. +SET enable_partitionwise_join to true +-- +STMT: VariableSetStmt +== 002 +|-- +-- partitioned by a single column +|-- +CREATE TABLE prt1 (a int, b int, c varchar) PARTITION BY RANGE(a) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE prt1_p1 PARTITION OF prt1 FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt1_p1" schema="" table="prt1_p1" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE prt1_p3 PARTITION OF prt1 FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt1_p3" schema="" table="prt1_p3" ctx=DDL +STMT: CreateStmt +== 005 +CREATE TABLE prt1_p2 PARTITION OF prt1 FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt1_p2" schema="" table="prt1_p2" ctx=DDL +STMT: CreateStmt +== 006 +INSERT INTO prt1 SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 2 = 0 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 007 +CREATE INDEX iprt1_p1_a on prt1_p1(a) +-- +TABLE: name="prt1_p1" schema="" table="prt1_p1" ctx=DDL +STMT: IndexStmt +== 008 +CREATE INDEX iprt1_p2_a on prt1_p2(a) +-- +TABLE: name="prt1_p2" schema="" table="prt1_p2" ctx=DDL +STMT: IndexStmt +== 009 +CREATE INDEX iprt1_p3_a on prt1_p3(a) +-- +TABLE: name="prt1_p3" schema="" table="prt1_p3" ctx=DDL +STMT: IndexStmt +== 010 +ANALYZE prt1 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: VacuumStmt +== 011 +CREATE TABLE prt2 (a int, b int, c varchar) PARTITION BY RANGE(b) +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: CreateStmt +== 012 +CREATE TABLE prt2_p1 PARTITION OF prt2 FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt2_p1" schema="" table="prt2_p1" ctx=DDL +STMT: CreateStmt +== 013 +CREATE TABLE prt2_p2 PARTITION OF prt2 FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt2_p2" schema="" table="prt2_p2" ctx=DDL +STMT: CreateStmt +== 014 +CREATE TABLE prt2_p3 PARTITION OF prt2 FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt2_p3" schema="" table="prt2_p3" ctx=DDL +STMT: CreateStmt +== 015 +INSERT INTO prt2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 3 = 0 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 016 +CREATE INDEX iprt2_p1_b on prt2_p1(b) +-- +TABLE: name="prt2_p1" schema="" table="prt2_p1" ctx=DDL +STMT: IndexStmt +== 017 +CREATE INDEX iprt2_p2_b on prt2_p2(b) +-- +TABLE: name="prt2_p2" schema="" table="prt2_p2" ctx=DDL +STMT: IndexStmt +== 018 +CREATE INDEX iprt2_p3_b on prt2_p3(b) +-- +TABLE: name="prt2_p3" schema="" table="prt2_p3" ctx=DDL +STMT: IndexStmt +== 019 +ANALYZE prt2 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: VacuumStmt +== 020 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 021 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 022 +-- left outer join, 3-way +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 023 +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 024 +-- left outer join, with whole-row reference; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 025 +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 026 +-- right outer join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 027 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +== 028 +-- full outer join, with placeholder vars +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 029 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +STMT: SelectStmt +== 030 +-- Join with pruned partitions from joining relations +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 031 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 032 +-- Currently we can't do partitioned join if nullable-side partitions are pruned +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 033 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 034 +-- Currently we can't do partitioned join if nullable-side partitions are pruned +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 035 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 036 +-- Semi-join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 037 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +== 038 +-- Anti-join with aggregates +EXPLAIN (COSTS OFF) +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 040 +-- lateral reference +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 041 +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 042 +EXPLAIN (COSTS OFF) +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="ss" column="t2b" +STMT: ExplainStmt +STMT: SelectStmt +== 043 +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="ss" column="t2b" +STMT: SelectStmt +== 044 +-- lateral reference in sample scan +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 JOIN LATERAL + (SELECT * FROM prt1 t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +STMT: ExplainStmt +STMT: SelectStmt +== 045 +-- lateral reference in scan's restriction clauses +EXPLAIN (COSTS OFF) +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: SelectStmt +== 047 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 048 +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="b" +STMT: SelectStmt +== 049 +-- bug with inadequate sort key representation +SET enable_partitionwise_aggregate TO true +-- +STMT: VariableSetStmt +== 050 +SET enable_hashjoin TO false +-- +STMT: VariableSetStmt +== 051 +EXPLAIN (COSTS OFF) +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 053 +RESET enable_partitionwise_aggregate +-- +STMT: VariableSetStmt +== 054 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 055 +-- bug in freeing the SpecialJoinInfo of a child-join +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 JOIN prt1 t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM prt1 t3) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt1" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 056 +|-- +-- partitioned by expression +|-- +CREATE TABLE prt1_e (a int, b int, c int) PARTITION BY RANGE(((a + b)/2)) +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=DDL +STMT: CreateStmt +== 057 +CREATE TABLE prt1_e_p1 PARTITION OF prt1_e FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt1_e_p1" schema="" table="prt1_e_p1" ctx=DDL +STMT: CreateStmt +== 058 +CREATE TABLE prt1_e_p2 PARTITION OF prt1_e FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt1_e_p2" schema="" table="prt1_e_p2" ctx=DDL +STMT: CreateStmt +== 059 +CREATE TABLE prt1_e_p3 PARTITION OF prt1_e FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt1_e_p3" schema="" table="prt1_e_p3" ctx=DDL +STMT: CreateStmt +== 060 +INSERT INTO prt1_e SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 061 +CREATE INDEX iprt1_e_p1_ab2 on prt1_e_p1(((a+b)/2)) +-- +TABLE: name="prt1_e_p1" schema="" table="prt1_e_p1" ctx=DDL +STMT: IndexStmt +== 062 +CREATE INDEX iprt1_e_p2_ab2 on prt1_e_p2(((a+b)/2)) +-- +TABLE: name="prt1_e_p2" schema="" table="prt1_e_p2" ctx=DDL +STMT: IndexStmt +== 063 +CREATE INDEX iprt1_e_p3_ab2 on prt1_e_p3(((a+b)/2)) +-- +TABLE: name="prt1_e_p3" schema="" table="prt1_e_p3" ctx=DDL +STMT: IndexStmt +== 064 +ANALYZE prt1_e +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=DDL +STMT: VacuumStmt +== 065 +CREATE TABLE prt2_e (a int, b int, c int) PARTITION BY RANGE(((b + a)/2)) +-- +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=DDL +STMT: CreateStmt +== 066 +CREATE TABLE prt2_e_p1 PARTITION OF prt2_e FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt2_e_p1" schema="" table="prt2_e_p1" ctx=DDL +STMT: CreateStmt +== 067 +CREATE TABLE prt2_e_p2 PARTITION OF prt2_e FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt2_e_p2" schema="" table="prt2_e_p2" ctx=DDL +STMT: CreateStmt +== 068 +CREATE TABLE prt2_e_p3 PARTITION OF prt2_e FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt2_e_p3" schema="" table="prt2_e_p3" ctx=DDL +STMT: CreateStmt +== 069 +INSERT INTO prt2_e SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i +-- +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 070 +ANALYZE prt2_e +-- +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=DDL +STMT: VacuumStmt +== 071 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=Select +ALIAS: "t1"="prt1_e" +ALIAS: "t2"="prt2_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 072 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=Select +ALIAS: "t1"="prt1_e" +ALIAS: "t2"="prt2_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +== 073 +|-- +-- N-way join +|-- +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 074 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 075 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 076 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 077 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 078 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: SelectStmt +== 079 +|-- +-- 3-way full join +|-- +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 080 +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 081 +|-- +-- 4-way full join +|-- +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +ALIAS: "p4"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 082 +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +ALIAS: "p4"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 083 +-- Cases with non-nullable expressions in subquery results; +-- make sure these go to null as expected +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t3" column="phv" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +FILTER: schema="" table="prt1_e" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 084 +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t3" column="phv" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +FILTER: schema="" table="prt1_e" column="c" +STMT: SelectStmt +== 085 +-- Semi-join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt2" +ALIAS: "t2"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 086 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt2" +ALIAS: "t2"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 087 +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 088 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +== 089 +-- test merge joins +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +== 090 +SET enable_nestloop TO off +-- +STMT: VariableSetStmt +== 091 +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 092 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +== 093 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 094 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: SelectStmt +== 095 +-- MergeAppend on nullable column +-- This should generate a partitionwise join, but currently fails to +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 096 +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 097 +-- merge join when expression with whole-row reference needs to be sorted; +-- partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="" column="t1" +FILTER: schema="" table="" column="t2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 098 +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="" column="t1" +FILTER: schema="" table="" column="t2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 099 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 100 +RESET enable_nestloop +-- +STMT: VariableSetStmt +== 101 +|-- +-- partitioned by multiple columns +|-- +CREATE TABLE prt1_m (a int, b int, c int) PARTITION BY RANGE(a, ((a + b)/2)) +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=DDL +STMT: CreateStmt +== 102 +CREATE TABLE prt1_m_p1 PARTITION OF prt1_m FOR VALUES FROM (0, 0) TO (250, 250) +-- +TABLE: name="prt1_m_p1" schema="" table="prt1_m_p1" ctx=DDL +STMT: CreateStmt +== 103 +CREATE TABLE prt1_m_p2 PARTITION OF prt1_m FOR VALUES FROM (250, 250) TO (500, 500) +-- +TABLE: name="prt1_m_p2" schema="" table="prt1_m_p2" ctx=DDL +STMT: CreateStmt +== 104 +CREATE TABLE prt1_m_p3 PARTITION OF prt1_m FOR VALUES FROM (500, 500) TO (600, 600) +-- +TABLE: name="prt1_m_p3" schema="" table="prt1_m_p3" ctx=DDL +STMT: CreateStmt +== 105 +INSERT INTO prt1_m SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 106 +ANALYZE prt1_m +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=DDL +STMT: VacuumStmt +== 107 +CREATE TABLE prt2_m (a int, b int, c int) PARTITION BY RANGE(((b + a)/2), b) +-- +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=DDL +STMT: CreateStmt +== 108 +CREATE TABLE prt2_m_p1 PARTITION OF prt2_m FOR VALUES FROM (0, 0) TO (250, 250) +-- +TABLE: name="prt2_m_p1" schema="" table="prt2_m_p1" ctx=DDL +STMT: CreateStmt +== 109 +CREATE TABLE prt2_m_p2 PARTITION OF prt2_m FOR VALUES FROM (250, 250) TO (500, 500) +-- +TABLE: name="prt2_m_p2" schema="" table="prt2_m_p2" ctx=DDL +STMT: CreateStmt +== 110 +CREATE TABLE prt2_m_p3 PARTITION OF prt2_m FOR VALUES FROM (500, 500) TO (600, 600) +-- +TABLE: name="prt2_m_p3" schema="" table="prt2_m_p3" ctx=DDL +STMT: CreateStmt +== 111 +INSERT INTO prt2_m SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i +-- +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 112 +ANALYZE prt2_m +-- +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=DDL +STMT: VacuumStmt +== 113 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +FILTER: schema="" table="prt1_m" column="c" +FILTER: schema="" table="prt2_m" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 114 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +FILTER: schema="" table="prt1_m" column="c" +FILTER: schema="" table="prt2_m" column="c" +STMT: SelectStmt +== 115 +|-- +-- tests for list partitioned tables. +|-- +CREATE TABLE plt1 (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: CreateStmt +== 116 +CREATE TABLE plt1_p1 PARTITION OF plt1 FOR VALUES IN ('0000', '0003', '0004', '0010') +-- +TABLE: name="plt1_p1" schema="" table="plt1_p1" ctx=DDL +STMT: CreateStmt +== 117 +CREATE TABLE plt1_p2 PARTITION OF plt1 FOR VALUES IN ('0001', '0005', '0002', '0009') +-- +TABLE: name="plt1_p2" schema="" table="plt1_p2" ctx=DDL +STMT: CreateStmt +== 118 +CREATE TABLE plt1_p3 PARTITION OF plt1 FOR VALUES IN ('0006', '0007', '0008', '0011') +-- +TABLE: name="plt1_p3" schema="" table="plt1_p3" ctx=DDL +STMT: CreateStmt +== 119 +INSERT INTO plt1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 120 +ANALYZE plt1 +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: VacuumStmt +== 121 +CREATE TABLE plt2 (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: CreateStmt +== 122 +CREATE TABLE plt2_p1 PARTITION OF plt2 FOR VALUES IN ('0000', '0003', '0004', '0010') +-- +TABLE: name="plt2_p1" schema="" table="plt2_p1" ctx=DDL +STMT: CreateStmt +== 123 +CREATE TABLE plt2_p2 PARTITION OF plt2 FOR VALUES IN ('0001', '0005', '0002', '0009') +-- +TABLE: name="plt2_p2" schema="" table="plt2_p2" ctx=DDL +STMT: CreateStmt +== 124 +CREATE TABLE plt2_p3 PARTITION OF plt2 FOR VALUES IN ('0006', '0007', '0008', '0011') +-- +TABLE: name="plt2_p3" schema="" table="plt2_p3" ctx=DDL +STMT: CreateStmt +== 125 +INSERT INTO plt2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 126 +ANALYZE plt2 +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: VacuumStmt +== 127 +|-- +-- list partitioned by expression +|-- +CREATE TABLE plt1_e (a int, b int, c text) PARTITION BY LIST(ltrim(c, 'A')) +-- +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=DDL +STMT: CreateStmt +== 128 +CREATE TABLE plt1_e_p1 PARTITION OF plt1_e FOR VALUES IN ('0000', '0003', '0004', '0010') +-- +TABLE: name="plt1_e_p1" schema="" table="plt1_e_p1" ctx=DDL +STMT: CreateStmt +== 129 +CREATE TABLE plt1_e_p2 PARTITION OF plt1_e FOR VALUES IN ('0001', '0005', '0002', '0009') +-- +TABLE: name="plt1_e_p2" schema="" table="plt1_e_p2" ctx=DDL +STMT: CreateStmt +== 130 +CREATE TABLE plt1_e_p3 PARTITION OF plt1_e FOR VALUES IN ('0006', '0007', '0008', '0011') +-- +TABLE: name="plt1_e_p3" schema="" table="plt1_e_p3" ctx=DDL +STMT: CreateStmt +== 131 +INSERT INTO plt1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 132 +ANALYZE plt1_e +-- +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=DDL +STMT: VacuumStmt +== 133 +-- test partition matching with N-way join +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="plt1" schema="" table="plt1" ctx=Select +TABLE: name="plt2" schema="" table="plt2" ctx=Select +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=Select +ALIAS: "t1"="plt1" +ALIAS: "t2"="plt2" +ALIAS: "t3"="plt1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 134 +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="plt1" schema="" table="plt1" ctx=Select +TABLE: name="plt2" schema="" table="plt2" ctx=Select +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=Select +ALIAS: "t1"="plt1" +ALIAS: "t2"="plt2" +ALIAS: "t3"="plt1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +== 135 +-- joins where one of the relations is proven empty +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a = 1 AND t1.a = 2 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 136 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 LEFT JOIN prt2 t2 ON t1.a = t2.b +-- +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t2"="prt2" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 137 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b, prt1 t3 WHERE t2.b = t3.a +-- +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 138 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 FULL JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t2"="prt2" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 139 +|-- +-- tests for hash partitioned tables. +|-- +CREATE TABLE pht1 (a int, b int, c text) PARTITION BY HASH(c) +-- +TABLE: name="pht1" schema="" table="pht1" ctx=DDL +STMT: CreateStmt +== 140 +CREATE TABLE pht1_p1 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 0) +-- +TABLE: name="pht1_p1" schema="" table="pht1_p1" ctx=DDL +STMT: CreateStmt +== 141 +CREATE TABLE pht1_p2 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 1) +-- +TABLE: name="pht1_p2" schema="" table="pht1_p2" ctx=DDL +STMT: CreateStmt +== 142 +CREATE TABLE pht1_p3 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="pht1_p3" schema="" table="pht1_p3" ctx=DDL +STMT: CreateStmt +== 143 +INSERT INTO pht1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="pht1" schema="" table="pht1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 144 +ANALYZE pht1 +-- +TABLE: name="pht1" schema="" table="pht1" ctx=DDL +STMT: VacuumStmt +== 145 +CREATE TABLE pht2 (a int, b int, c text) PARTITION BY HASH(c) +-- +TABLE: name="pht2" schema="" table="pht2" ctx=DDL +STMT: CreateStmt +== 146 +CREATE TABLE pht2_p1 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 0) +-- +TABLE: name="pht2_p1" schema="" table="pht2_p1" ctx=DDL +STMT: CreateStmt +== 147 +CREATE TABLE pht2_p2 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 1) +-- +TABLE: name="pht2_p2" schema="" table="pht2_p2" ctx=DDL +STMT: CreateStmt +== 148 +CREATE TABLE pht2_p3 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="pht2_p3" schema="" table="pht2_p3" ctx=DDL +STMT: CreateStmt +== 149 +INSERT INTO pht2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i +-- +TABLE: name="pht2" schema="" table="pht2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 150 +ANALYZE pht2 +-- +TABLE: name="pht2" schema="" table="pht2" ctx=DDL +STMT: VacuumStmt +== 151 +|-- +-- hash partitioned by expression +|-- +CREATE TABLE pht1_e (a int, b int, c text) PARTITION BY HASH(ltrim(c, 'A')) +-- +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=DDL +STMT: CreateStmt +== 152 +CREATE TABLE pht1_e_p1 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 0) +-- +TABLE: name="pht1_e_p1" schema="" table="pht1_e_p1" ctx=DDL +STMT: CreateStmt +== 153 +CREATE TABLE pht1_e_p2 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 1) +-- +TABLE: name="pht1_e_p2" schema="" table="pht1_e_p2" ctx=DDL +STMT: CreateStmt +== 154 +CREATE TABLE pht1_e_p3 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="pht1_e_p3" schema="" table="pht1_e_p3" ctx=DDL +STMT: CreateStmt +== 155 +INSERT INTO pht1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 299, 2) i +-- +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 156 +ANALYZE pht1_e +-- +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=DDL +STMT: VacuumStmt +== 157 +-- test partition matching with N-way join +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="pht1" schema="" table="pht1" ctx=Select +TABLE: name="pht2" schema="" table="pht2" ctx=Select +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=Select +ALIAS: "t1"="pht1" +ALIAS: "t2"="pht2" +ALIAS: "t3"="pht1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 158 +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="pht1" schema="" table="pht1" ctx=Select +TABLE: name="pht2" schema="" table="pht2" ctx=Select +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=Select +ALIAS: "t1"="pht1" +ALIAS: "t2"="pht2" +ALIAS: "t3"="pht1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +== 159 +-- test default partition behavior for range +ALTER TABLE prt1 DETACH PARTITION prt1_p3 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: AlterTableStmt +== 160 +ALTER TABLE prt1 ATTACH PARTITION prt1_p3 DEFAULT +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: AlterTableStmt +== 161 +ANALYZE prt1 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: VacuumStmt +== 162 +ALTER TABLE prt2 DETACH PARTITION prt2_p3 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: AlterTableStmt +== 163 +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 DEFAULT +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: AlterTableStmt +== 164 +ANALYZE prt2 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: VacuumStmt +== 165 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 166 +-- test default partition behavior for list +ALTER TABLE plt1 DETACH PARTITION plt1_p3 +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: AlterTableStmt +== 167 +ALTER TABLE plt1 ATTACH PARTITION plt1_p3 DEFAULT +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: AlterTableStmt +== 168 +ANALYZE plt1 +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: VacuumStmt +== 169 +ALTER TABLE plt2 DETACH PARTITION plt2_p3 +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: AlterTableStmt +== 170 +ALTER TABLE plt2 ATTACH PARTITION plt2_p3 DEFAULT +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: AlterTableStmt +== 171 +ANALYZE plt2 +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: VacuumStmt +== 172 +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), t1.c, t2.c FROM plt1 t1 RIGHT JOIN plt2 t2 ON t1.c = t2.c WHERE t1.a % 25 = 0 GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c +-- +TABLE: name="plt1" schema="" table="plt1" ctx=Select +TABLE: name="plt2" schema="" table="plt2" ctx=Select +ALIAS: "t1"="plt1" +ALIAS: "t2"="plt2" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 173 +|-- +-- multiple levels of partitioning +|-- +CREATE TABLE prt1_l (a int, b int, c varchar) PARTITION BY RANGE(a) +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DDL +STMT: CreateStmt +== 174 +CREATE TABLE prt1_l_p1 PARTITION OF prt1_l FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt1_l_p1" schema="" table="prt1_l_p1" ctx=DDL +STMT: CreateStmt +== 175 +CREATE TABLE prt1_l_p2 PARTITION OF prt1_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c) +-- +TABLE: name="prt1_l_p2" schema="" table="prt1_l_p2" ctx=DDL +STMT: CreateStmt +== 176 +CREATE TABLE prt1_l_p2_p1 PARTITION OF prt1_l_p2 FOR VALUES IN ('0000', '0001') +-- +TABLE: name="prt1_l_p2_p1" schema="" table="prt1_l_p2_p1" ctx=DDL +STMT: CreateStmt +== 177 +CREATE TABLE prt1_l_p2_p2 PARTITION OF prt1_l_p2 FOR VALUES IN ('0002', '0003') +-- +TABLE: name="prt1_l_p2_p2" schema="" table="prt1_l_p2_p2" ctx=DDL +STMT: CreateStmt +== 178 +CREATE TABLE prt1_l_p3 PARTITION OF prt1_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (b) +-- +TABLE: name="prt1_l_p3" schema="" table="prt1_l_p3" ctx=DDL +STMT: CreateStmt +== 179 +CREATE TABLE prt1_l_p3_p1 PARTITION OF prt1_l_p3 FOR VALUES FROM (0) TO (13) +-- +TABLE: name="prt1_l_p3_p1" schema="" table="prt1_l_p3_p1" ctx=DDL +STMT: CreateStmt +== 180 +CREATE TABLE prt1_l_p3_p2 PARTITION OF prt1_l_p3 FOR VALUES FROM (13) TO (25) +-- +TABLE: name="prt1_l_p3_p2" schema="" table="prt1_l_p3_p2" ctx=DDL +STMT: CreateStmt +== 181 +INSERT INTO prt1_l SELECT i, i % 25, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 182 +ANALYZE prt1_l +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DDL +STMT: VacuumStmt +== 183 +CREATE TABLE prt2_l (a int, b int, c varchar) PARTITION BY RANGE(b) +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=DDL +STMT: CreateStmt +== 184 +CREATE TABLE prt2_l_p1 PARTITION OF prt2_l FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt2_l_p1" schema="" table="prt2_l_p1" ctx=DDL +STMT: CreateStmt +== 185 +CREATE TABLE prt2_l_p2 PARTITION OF prt2_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c) +-- +TABLE: name="prt2_l_p2" schema="" table="prt2_l_p2" ctx=DDL +STMT: CreateStmt +== 186 +CREATE TABLE prt2_l_p2_p1 PARTITION OF prt2_l_p2 FOR VALUES IN ('0000', '0001') +-- +TABLE: name="prt2_l_p2_p1" schema="" table="prt2_l_p2_p1" ctx=DDL +STMT: CreateStmt +== 187 +CREATE TABLE prt2_l_p2_p2 PARTITION OF prt2_l_p2 FOR VALUES IN ('0002', '0003') +-- +TABLE: name="prt2_l_p2_p2" schema="" table="prt2_l_p2_p2" ctx=DDL +STMT: CreateStmt +== 188 +CREATE TABLE prt2_l_p3 PARTITION OF prt2_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (a) +-- +TABLE: name="prt2_l_p3" schema="" table="prt2_l_p3" ctx=DDL +STMT: CreateStmt +== 189 +CREATE TABLE prt2_l_p3_p1 PARTITION OF prt2_l_p3 FOR VALUES FROM (0) TO (13) +-- +TABLE: name="prt2_l_p3_p1" schema="" table="prt2_l_p3_p1" ctx=DDL +STMT: CreateStmt +== 190 +CREATE TABLE prt2_l_p3_p2 PARTITION OF prt2_l_p3 FOR VALUES FROM (13) TO (25) +-- +TABLE: name="prt2_l_p3_p2" schema="" table="prt2_l_p3_p2" ctx=DDL +STMT: CreateStmt +== 191 +INSERT INTO prt2_l SELECT i % 25, i, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 3) i +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 192 +ANALYZE prt2_l +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=DDL +STMT: VacuumStmt +== 193 +-- inner join, qual covering only top-level partitions +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 194 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 195 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 196 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 197 +-- right join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 198 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +== 199 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +FILTER: schema="" table="prt1_l" column="b" +FILTER: schema="" table="prt2_l" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 200 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +FILTER: schema="" table="prt1_l" column="b" +FILTER: schema="" table="prt2_l" column="a" +STMT: SelectStmt +== 201 +-- lateral partitionwise join +EXPLAIN (COSTS OFF) +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt1_l" +ALIAS: "t3"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 202 +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt1_l" +ALIAS: "t3"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 203 +-- partitionwise join with lateral reference in sample scan +EXPLAIN (COSTS OFF) +SELECT * FROM prt1_l t1 JOIN LATERAL + (SELECT * FROM prt1_l t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a AND t1.b = s.b AND t1.c = s.c +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt1_l" +STMT: ExplainStmt +STMT: SelectStmt +== 204 +-- partitionwise join with lateral reference in scan's restriction clauses +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 205 +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: SelectStmt +== 206 +-- join with one side empty +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 207 +-- Test case to verify proper handling of subqueries in a partitioned delete. +-- The weird-looking lateral join is just there to force creation of a +-- nestloop parameter within the subquery, which exposes the problem if the +-- planner fails to make multiple copies of the subquery as appropriate. +EXPLAIN (COSTS OFF) +DELETE FROM prt1_l +WHERE EXISTS ( + SELECT 1 + FROM int4_tbl, + LATERAL (SELECT int4_tbl.f1 FROM int8_tbl LIMIT 2) ss + WHERE prt1_l.c IS NULL) +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="prt1_l" column="c" +STMT: ExplainStmt +STMT: DeleteStmt +STMT: SelectStmt +== 208 +|-- +-- negative testcases +|-- +CREATE TABLE prt1_n (a int, b int, c varchar) PARTITION BY RANGE(c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=DDL +STMT: CreateStmt +== 209 +CREATE TABLE prt1_n_p1 PARTITION OF prt1_n FOR VALUES FROM ('0000') TO ('0250') +-- +TABLE: name="prt1_n_p1" schema="" table="prt1_n_p1" ctx=DDL +STMT: CreateStmt +== 210 +CREATE TABLE prt1_n_p2 PARTITION OF prt1_n FOR VALUES FROM ('0250') TO ('0500') +-- +TABLE: name="prt1_n_p2" schema="" table="prt1_n_p2" ctx=DDL +STMT: CreateStmt +== 211 +INSERT INTO prt1_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 499, 2) i +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 212 +ANALYZE prt1_n +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=DDL +STMT: VacuumStmt +== 213 +CREATE TABLE prt2_n (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DDL +STMT: CreateStmt +== 214 +CREATE TABLE prt2_n_p1 PARTITION OF prt2_n FOR VALUES IN ('0000', '0003', '0004', '0010', '0006', '0007') +-- +TABLE: name="prt2_n_p1" schema="" table="prt2_n_p1" ctx=DDL +STMT: CreateStmt +== 215 +CREATE TABLE prt2_n_p2 PARTITION OF prt2_n FOR VALUES IN ('0001', '0005', '0002', '0009', '0008', '0011') +-- +TABLE: name="prt2_n_p2" schema="" table="prt2_n_p2" ctx=DDL +STMT: CreateStmt +== 216 +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 217 +ANALYZE prt2_n +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DDL +STMT: VacuumStmt +== 218 +CREATE TABLE prt3_n (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="prt3_n" schema="" table="prt3_n" ctx=DDL +STMT: CreateStmt +== 219 +CREATE TABLE prt3_n_p1 PARTITION OF prt3_n FOR VALUES IN ('0000', '0004', '0006', '0007') +-- +TABLE: name="prt3_n_p1" schema="" table="prt3_n_p1" ctx=DDL +STMT: CreateStmt +== 220 +CREATE TABLE prt3_n_p2 PARTITION OF prt3_n FOR VALUES IN ('0001', '0002', '0008', '0010') +-- +TABLE: name="prt3_n_p2" schema="" table="prt3_n_p2" ctx=DDL +STMT: CreateStmt +== 221 +CREATE TABLE prt3_n_p3 PARTITION OF prt3_n FOR VALUES IN ('0003', '0005', '0009', '0011') +-- +TABLE: name="prt3_n_p3" schema="" table="prt3_n_p3" ctx=DDL +STMT: CreateStmt +== 222 +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 223 +ANALYZE prt3_n +-- +TABLE: name="prt3_n" schema="" table="prt3_n" ctx=DDL +STMT: VacuumStmt +== 224 +CREATE TABLE prt4_n (a int, b int, c text) PARTITION BY RANGE(a) +-- +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=DDL +STMT: CreateStmt +== 225 +CREATE TABLE prt4_n_p1 PARTITION OF prt4_n FOR VALUES FROM (0) TO (300) +-- +TABLE: name="prt4_n_p1" schema="" table="prt4_n_p1" ctx=DDL +STMT: CreateStmt +== 226 +CREATE TABLE prt4_n_p2 PARTITION OF prt4_n FOR VALUES FROM (300) TO (500) +-- +TABLE: name="prt4_n_p2" schema="" table="prt4_n_p2" ctx=DDL +STMT: CreateStmt +== 227 +CREATE TABLE prt4_n_p3 PARTITION OF prt4_n FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt4_n_p3" schema="" table="prt4_n_p3" ctx=DDL +STMT: CreateStmt +== 228 +INSERT INTO prt4_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 229 +ANALYZE prt4_n +-- +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=DDL +STMT: VacuumStmt +== 230 +-- partitionwise join can not be applied if the partition ranges differ +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2 WHERE t1.a = t2.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt4_n" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 231 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2, prt2 t3 WHERE t1.a = t2.a and t1.a = t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt4_n" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t3" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 232 +-- partitionwise join can not be applied if there are no equi-join conditions +-- between partition keys +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 LEFT JOIN prt2 t2 ON (t1.a < t2.b) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +STMT: ExplainStmt +STMT: SelectStmt +== 233 +-- equi-join with join condition on partial keys does not qualify for +-- partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1, prt2_m t2 WHERE t1.a = (t2.b + t2.a)/2 +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +ALIAS: "t1"="prt1_m" +ALIAS: "t2"="prt2_m" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 234 +-- equi-join between out-of-order partition key columns does not qualify for +-- partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.a = t2.b +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +ALIAS: "t1"="prt1_m" +ALIAS: "t2"="prt2_m" +STMT: ExplainStmt +STMT: SelectStmt +== 235 +-- equi-join between non-key columns does not qualify for partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.c = t2.c +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +ALIAS: "t1"="prt1_m" +ALIAS: "t2"="prt2_m" +STMT: ExplainStmt +STMT: SelectStmt +== 236 +-- partitionwise join can not be applied for a join between list and range +-- partitioned tables +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 LEFT JOIN prt2_n t2 ON (t1.c = t2.c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=Select +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=Select +ALIAS: "t1"="prt1_n" +ALIAS: "t2"="prt2_n" +STMT: ExplainStmt +STMT: SelectStmt +== 237 +-- partitionwise join can not be applied between tables with different +-- partition lists +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 JOIN prt2_n t2 ON (t1.c = t2.c) JOIN plt1 t3 ON (t1.c = t3.c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=Select +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=Select +TABLE: name="plt1" schema="" table="plt1" ctx=Select +ALIAS: "t1"="prt1_n" +ALIAS: "t2"="prt2_n" +ALIAS: "t3"="plt1" +STMT: ExplainStmt +STMT: SelectStmt +== 238 +-- partitionwise join can not be applied for a join between key column and +-- non-key column +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON (t1.c = t2.c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1_n" +ALIAS: "t2"="prt1" +STMT: ExplainStmt +STMT: SelectStmt +== 239 +|-- +-- Test some other plan types in a partitionwise join (unfortunately, +-- we need larger tables to get the planner to choose these plan types) +|-- +create temp table prtx1 (a integer, b integer, c integer) + partition by range (a) +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=DDL +STMT: CreateStmt +== 240 +create temp table prtx1_1 partition of prtx1 for values from (1) to (11) +-- +TABLE: name="prtx1_1" schema="" table="prtx1_1" ctx=DDL +STMT: CreateStmt +== 241 +create temp table prtx1_2 partition of prtx1 for values from (11) to (21) +-- +TABLE: name="prtx1_2" schema="" table="prtx1_2" ctx=DDL +STMT: CreateStmt +== 242 +create temp table prtx1_3 partition of prtx1 for values from (21) to (31) +-- +TABLE: name="prtx1_3" schema="" table="prtx1_3" ctx=DDL +STMT: CreateStmt +== 243 +create temp table prtx2 (a integer, b integer, c integer) + partition by range (a) +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: CreateStmt +== 244 +create temp table prtx2_1 partition of prtx2 for values from (1) to (11) +-- +TABLE: name="prtx2_1" schema="" table="prtx2_1" ctx=DDL +STMT: CreateStmt +== 245 +create temp table prtx2_2 partition of prtx2 for values from (11) to (21) +-- +TABLE: name="prtx2_2" schema="" table="prtx2_2" ctx=DDL +STMT: CreateStmt +== 246 +create temp table prtx2_3 partition of prtx2 for values from (21) to (31) +-- +TABLE: name="prtx2_3" schema="" table="prtx2_3" ctx=DDL +STMT: CreateStmt +== 247 +insert into prtx1 select 1 + i%30, i, i + from generate_series(1,1000) i +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 248 +insert into prtx2 select 1 + i%30, i, i + from generate_series(1,500) i, generate_series(1,10) j +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 249 +create index on prtx2 (b) +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: IndexStmt +== 250 +create index on prtx2 (c) +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: IndexStmt +== 251 +analyze prtx1 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=DDL +STMT: VacuumStmt +== 252 +analyze prtx2 +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: VacuumStmt +== 253 +explain (costs off) +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 254 +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: SelectStmt +== 255 +explain (costs off) +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 256 +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: SelectStmt +== 257 +|-- +-- Test advanced partition-matching algorithm for partitioned join +|-- + +-- Tests for range-partitioned tables +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: CreateStmt +== 258 +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200) +-- +TABLE: name="prt1_adv_p1" schema="" table="prt1_adv_p1" ctx=DDL +STMT: CreateStmt +== 259 +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt1_adv_p2" schema="" table="prt1_adv_p2" ctx=DDL +STMT: CreateStmt +== 260 +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: CreateStmt +== 261 +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: IndexStmt +== 262 +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 263 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +== 264 +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: CreateStmt +== 265 +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (150) +-- +TABLE: name="prt2_adv_p1" schema="" table="prt2_adv_p1" ctx=DDL +STMT: CreateStmt +== 266 +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt2_adv_p2" schema="" table="prt2_adv_p2" ctx=DDL +STMT: CreateStmt +== 267 +CREATE TABLE prt2_adv_p3 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (500) +-- +TABLE: name="prt2_adv_p3" schema="" table="prt2_adv_p3" ctx=DDL +STMT: CreateStmt +== 268 +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: IndexStmt +== 269 +INSERT INTO prt2_adv_p1 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 149) i +-- +TABLE: name="prt2_adv_p1" schema="" table="prt2_adv_p1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 270 +INSERT INTO prt2_adv_p2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(200, 299) i +-- +TABLE: name="prt2_adv_p2" schema="" table="prt2_adv_p2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 271 +INSERT INTO prt2_adv_p3 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i +-- +TABLE: name="prt2_adv_p3" schema="" table="prt2_adv_p3" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 272 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 273 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 274 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 275 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 276 +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 277 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 278 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 279 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 280 +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 281 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 282 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: SelectStmt +== 283 +-- Test cases where one side has an extra partition +CREATE TABLE prt2_adv_extra PARTITION OF prt2_adv FOR VALUES FROM (500) TO (MAXVALUE) +-- +TABLE: name="prt2_adv_extra" schema="" table="prt2_adv_extra" ctx=DDL +STMT: CreateStmt +== 284 +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(500, 599) i +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 285 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 286 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 287 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 288 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 289 +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 290 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 291 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 292 +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.b, t1.c, t2.a, t2.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 293 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 294 +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 295 +-- anti join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt1_adv t2 WHERE t1.b = t2.a) AND t1.a = 0 ORDER BY t1.b +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 296 +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 297 +-- 3-way join where not every pair of relations can do partitioned join +EXPLAIN (COSTS OFF) +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +ALIAS: "t3"="prt1_adv" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 298 +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +ALIAS: "t3"="prt1_adv" +FILTER: schema="" table="t1" column="a" +STMT: SelectStmt +== 299 +DROP TABLE prt2_adv_extra +-- +TABLE: name="prt2_adv_extra" schema="" table="prt2_adv_extra" ctx=DDL +STMT: DropStmt +== 300 +-- Test cases where a partition on one side matches multiple partitions on +-- the other side; we currently can't do partitioned join in such cases +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3 +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +== 301 +-- Split prt2_adv_p3 into two partitions so that prt1_adv_p3 matches both +CREATE TABLE prt2_adv_p3_1 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (375) +-- +TABLE: name="prt2_adv_p3_1" schema="" table="prt2_adv_p3_1" ctx=DDL +STMT: CreateStmt +== 302 +CREATE TABLE prt2_adv_p3_2 PARTITION OF prt2_adv FOR VALUES FROM (375) TO (500) +-- +TABLE: name="prt2_adv_p3_2" schema="" table="prt2_adv_p3_2" ctx=DDL +STMT: CreateStmt +== 303 +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 304 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 305 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 306 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 307 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 308 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 309 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 310 +DROP TABLE prt2_adv_p3_1 +-- +TABLE: name="prt2_adv_p3_1" schema="" table="prt2_adv_p3_1" ctx=DDL +STMT: DropStmt +== 311 +DROP TABLE prt2_adv_p3_2 +-- +TABLE: name="prt2_adv_p3_2" schema="" table="prt2_adv_p3_2" ctx=DDL +STMT: DropStmt +== 312 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 313 +-- Test default partitions +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p1 +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +== 314 +-- Change prt1_adv_p1 to the default partition +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p1 DEFAULT +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +== 315 +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p3 +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +== 316 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +== 317 +-- We can do partitioned join even if only one of relations has the default +-- partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 318 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 319 +-- Restore prt1_adv_p3 +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p3 FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +== 320 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +== 321 +-- Restore prt2_adv_p3 +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 FOR VALUES FROM (350) TO (500) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +== 322 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 323 +-- Partitioned join can't be applied because the default partition of prt1_adv +-- matches prt2_adv_p1 and prt2_adv_p3 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 324 +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3 +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +== 325 +-- Change prt2_adv_p3 to the default partition +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 DEFAULT +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +== 326 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 327 +-- Partitioned join can't be applied because the default partition of prt1_adv +-- matches prt2_adv_p1 and prt2_adv_p3 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 328 +DROP TABLE prt1_adv_p3 +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: DropStmt +== 329 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +== 330 +DROP TABLE prt2_adv_p3 +-- +TABLE: name="prt2_adv_p3" schema="" table="prt2_adv_p3" ctx=DDL +STMT: DropStmt +== 331 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 332 +CREATE TABLE prt3_adv (a int, b int, c varchar) PARTITION BY RANGE (a) +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: CreateStmt +== 333 +CREATE TABLE prt3_adv_p1 PARTITION OF prt3_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt3_adv_p1" schema="" table="prt3_adv_p1" ctx=DDL +STMT: CreateStmt +== 334 +CREATE TABLE prt3_adv_p2 PARTITION OF prt3_adv FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt3_adv_p2" schema="" table="prt3_adv_p2" ctx=DDL +STMT: CreateStmt +== 335 +CREATE INDEX prt3_adv_a_idx ON prt3_adv (a) +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: IndexStmt +== 336 +INSERT INTO prt3_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(200, 399) i +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 337 +ANALYZE prt3_adv +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: VacuumStmt +== 338 +-- 3-way join to test the default partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +ALIAS: "t3"="prt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 339 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +ALIAS: "t3"="prt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 340 +DROP TABLE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: DropStmt +== 341 +DROP TABLE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: DropStmt +== 342 +DROP TABLE prt3_adv +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: DropStmt +== 343 +-- Test interaction of partitioned join with partition pruning +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: CreateStmt +== 344 +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200) +-- +TABLE: name="prt1_adv_p1" schema="" table="prt1_adv_p1" ctx=DDL +STMT: CreateStmt +== 345 +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt1_adv_p2" schema="" table="prt1_adv_p2" ctx=DDL +STMT: CreateStmt +== 346 +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: CreateStmt +== 347 +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: IndexStmt +== 348 +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 349 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +== 350 +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: CreateStmt +== 351 +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (200) +-- +TABLE: name="prt2_adv_p1" schema="" table="prt2_adv_p1" ctx=DDL +STMT: CreateStmt +== 352 +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (400) +-- +TABLE: name="prt2_adv_p2" schema="" table="prt2_adv_p2" ctx=DDL +STMT: CreateStmt +== 353 +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: IndexStmt +== 354 +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 399) i +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 355 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 356 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 357 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 358 +DROP TABLE prt1_adv_p3 +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: DropStmt +== 359 +CREATE TABLE prt1_adv_default PARTITION OF prt1_adv DEFAULT +-- +TABLE: name="prt1_adv_default" schema="" table="prt1_adv_default" ctx=DDL +STMT: CreateStmt +== 360 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +== 361 +CREATE TABLE prt2_adv_default PARTITION OF prt2_adv DEFAULT +-- +TABLE: name="prt2_adv_default" schema="" table="prt2_adv_default" ctx=DDL +STMT: CreateStmt +== 362 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +== 363 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 364 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 365 +DROP TABLE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: DropStmt +== 366 +DROP TABLE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: DropStmt +== 367 +-- Tests for list-partitioned tables +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: CreateStmt +== 368 +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001', '0003') +-- +TABLE: name="plt1_adv_p1" schema="" table="plt1_adv_p1" ctx=DDL +STMT: CreateStmt +== 369 +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt1_adv_p2" schema="" table="plt1_adv_p2" ctx=DDL +STMT: CreateStmt +== 370 +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0008', '0009') +-- +TABLE: name="plt1_adv_p3" schema="" table="plt1_adv_p3" ctx=DDL +STMT: CreateStmt +== 371 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 372 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +== 373 +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: CreateStmt +== 374 +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002', '0003') +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: CreateStmt +== 375 +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt2_adv_p2" schema="" table="plt2_adv_p2" ctx=DDL +STMT: CreateStmt +== 376 +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0007', '0009') +-- +TABLE: name="plt2_adv_p3" schema="" table="plt2_adv_p3" ctx=DDL +STMT: CreateStmt +== 377 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 378 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 379 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 380 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 381 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 382 +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +== 383 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 384 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 385 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 386 +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +== 387 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 388 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 389 +-- Test cases where one side has an extra partition +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN ('0000') +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: CreateStmt +== 390 +INSERT INTO plt2_adv_extra VALUES (0, 0, '0000') +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 391 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 392 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 393 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 394 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 395 +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +== 396 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 397 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 398 +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt2_adv t1 LEFT JOIN plt1_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt2_adv" +ALIAS: "t2"="plt1_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 399 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 400 +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +== 401 +-- anti join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt1_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt2_adv" +ALIAS: "t2"="plt1_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 402 +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 403 +DROP TABLE plt2_adv_extra +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: DropStmt +== 404 +-- Test cases where a partition on one side matches multiple partitions on +-- the other side; we currently can't do partitioned join in such cases +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2 +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 405 +-- Split plt2_adv_p2 into two partitions so that plt1_adv_p2 matches both +CREATE TABLE plt2_adv_p2_1 PARTITION OF plt2_adv FOR VALUES IN ('0004') +-- +TABLE: name="plt2_adv_p2_1" schema="" table="plt2_adv_p2_1" ctx=DDL +STMT: CreateStmt +== 406 +CREATE TABLE plt2_adv_p2_2 PARTITION OF plt2_adv FOR VALUES IN ('0006') +-- +TABLE: name="plt2_adv_p2_2" schema="" table="plt2_adv_p2_2" ctx=DDL +STMT: CreateStmt +== 407 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 408 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 409 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 410 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 411 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 412 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 413 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 414 +DROP TABLE plt2_adv_p2_1 +-- +TABLE: name="plt2_adv_p2_1" schema="" table="plt2_adv_p2_1" ctx=DDL +STMT: DropStmt +== 415 +DROP TABLE plt2_adv_p2_2 +-- +TABLE: name="plt2_adv_p2_2" schema="" table="plt2_adv_p2_2" ctx=DDL +STMT: DropStmt +== 416 +-- Restore plt2_adv_p2 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 417 +-- Test NULL partitions +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1 +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +== 418 +-- Change plt1_adv_p1 to the NULL partition +CREATE TABLE plt1_adv_p1_null PARTITION OF plt1_adv FOR VALUES IN (NULL, '0001', '0003') +-- +TABLE: name="plt1_adv_p1_null" schema="" table="plt1_adv_p1_null" ctx=DDL +STMT: CreateStmt +== 419 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 420 +INSERT INTO plt1_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 421 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +== 422 +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p3 +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 423 +-- Change plt2_adv_p3 to the NULL partition +CREATE TABLE plt2_adv_p3_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0007', '0009') +-- +TABLE: name="plt2_adv_p3_null" schema="" table="plt2_adv_p3_null" ctx=DDL +STMT: CreateStmt +== 424 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (7, 9) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 425 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 426 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 427 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 428 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 429 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 430 +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +== 431 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 432 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 433 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 434 +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +== 435 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 436 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 437 +DROP TABLE plt1_adv_p1_null +-- +TABLE: name="plt1_adv_p1_null" schema="" table="plt1_adv_p1_null" ctx=DDL +STMT: DropStmt +== 438 +-- Restore plt1_adv_p1 +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 FOR VALUES IN ('0001', '0003') +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +== 439 +-- Add to plt1_adv the extra NULL partition containing only NULL values as the +-- key values +CREATE TABLE plt1_adv_extra PARTITION OF plt1_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt1_adv_extra" schema="" table="plt1_adv_extra" ctx=DDL +STMT: CreateStmt +== 440 +INSERT INTO plt1_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 441 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +== 442 +DROP TABLE plt2_adv_p3_null +-- +TABLE: name="plt2_adv_p3_null" schema="" table="plt2_adv_p3_null" ctx=DDL +STMT: DropStmt +== 443 +-- Restore plt2_adv_p3 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p3 FOR VALUES IN ('0007', '0009') +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 444 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 445 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 446 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 447 +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 448 +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 449 +-- Add to plt2_adv the extra NULL partition containing only NULL values as the +-- key values +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: CreateStmt +== 450 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 451 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 452 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 453 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 454 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 455 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 456 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 457 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +== 458 +-- 3-way join to test the NULL partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt1_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 459 +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt1_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 460 +DROP TABLE plt1_adv_extra +-- +TABLE: name="plt1_adv_extra" schema="" table="plt1_adv_extra" ctx=DDL +STMT: DropStmt +== 461 +DROP TABLE plt2_adv_extra +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: DropStmt +== 462 +-- Test default partitions +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1 +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +== 463 +-- Change plt1_adv_p1 to the default partition +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 DEFAULT +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +== 464 +DROP TABLE plt1_adv_p3 +-- +TABLE: name="plt1_adv_p3" schema="" table="plt1_adv_p3" ctx=DDL +STMT: DropStmt +== 465 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +== 466 +DROP TABLE plt2_adv_p3 +-- +TABLE: name="plt2_adv_p3" schema="" table="plt2_adv_p3" ctx=DDL +STMT: DropStmt +== 467 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 468 +-- We can do partitioned join even if only one of relations has the default +-- partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 469 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 470 +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2 +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 471 +-- Change plt2_adv_p2 to contain '0005' in addition to '0004' and '0006' as +-- the key values +CREATE TABLE plt2_adv_p2_ext PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005', '0006') +-- +TABLE: name="plt2_adv_p2_ext" schema="" table="plt2_adv_p2_ext" ctx=DDL +STMT: CreateStmt +== 472 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 5, 6) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 473 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 474 +-- Partitioned join can't be applied because the default partition of plt1_adv +-- matches plt2_adv_p1 and plt2_adv_p2_ext +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 475 +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2_ext +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 476 +-- Change plt2_adv_p2_ext to the default partition +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2_ext DEFAULT +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 477 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 478 +-- Partitioned join can't be applied because the default partition of plt1_adv +-- matches plt2_adv_p1 and plt2_adv_p2_ext +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 479 +DROP TABLE plt2_adv_p2_ext +-- +TABLE: name="plt2_adv_p2_ext" schema="" table="plt2_adv_p2_ext" ctx=DDL +STMT: DropStmt +== 480 +-- Restore plt2_adv_p2 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +== 481 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 482 +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: CreateStmt +== 483 +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt3_adv_p1" schema="" table="plt3_adv_p1" ctx=DDL +STMT: CreateStmt +== 484 +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0007', '0009') +-- +TABLE: name="plt3_adv_p2" schema="" table="plt3_adv_p2" ctx=DDL +STMT: CreateStmt +== 485 +INSERT INTO plt3_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6, 7, 9) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 486 +ANALYZE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: VacuumStmt +== 487 +-- 3-way join to test the default partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 488 +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 489 +-- Test cases where one side has the default partition while the other side +-- has the NULL partition +DROP TABLE plt2_adv_p1 +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: DropStmt +== 490 +-- Add the NULL partition to plt2_adv +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0001', '0003') +-- +TABLE: name="plt2_adv_p1_null" schema="" table="plt2_adv_p1_null" ctx=DDL +STMT: CreateStmt +== 491 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 492 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 493 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 494 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 495 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 496 +DROP TABLE plt2_adv_p1_null +-- +TABLE: name="plt2_adv_p1_null" schema="" table="plt2_adv_p1_null" ctx=DDL +STMT: DropStmt +== 497 +-- Add the NULL partition that contains only NULL values as the key values +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt2_adv_p1_null" schema="" table="plt2_adv_p1_null" ctx=DDL +STMT: CreateStmt +== 498 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 499 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 500 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 501 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 502 +DROP TABLE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: DropStmt +== 503 +DROP TABLE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: DropStmt +== 504 +DROP TABLE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: DropStmt +== 505 +-- Test interaction of partitioned join with partition pruning +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: CreateStmt +== 506 +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001') +-- +TABLE: name="plt1_adv_p1" schema="" table="plt1_adv_p1" ctx=DDL +STMT: CreateStmt +== 507 +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0002') +-- +TABLE: name="plt1_adv_p2" schema="" table="plt1_adv_p2" ctx=DDL +STMT: CreateStmt +== 508 +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0003') +-- +TABLE: name="plt1_adv_p3" schema="" table="plt1_adv_p3" ctx=DDL +STMT: CreateStmt +== 509 +CREATE TABLE plt1_adv_p4 PARTITION OF plt1_adv FOR VALUES IN (NULL, '0004', '0005') +-- +TABLE: name="plt1_adv_p4" schema="" table="plt1_adv_p4" ctx=DDL +STMT: CreateStmt +== 510 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 511 +INSERT INTO plt1_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 512 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +== 513 +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: CreateStmt +== 514 +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0001', '0002') +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: CreateStmt +== 515 +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt2_adv_p2" schema="" table="plt2_adv_p2" ctx=DDL +STMT: CreateStmt +== 516 +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0003') +-- +TABLE: name="plt2_adv_p3" schema="" table="plt2_adv_p3" ctx=DDL +STMT: CreateStmt +== 517 +CREATE TABLE plt2_adv_p4 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005') +-- +TABLE: name="plt2_adv_p4" schema="" table="plt2_adv_p4" ctx=DDL +STMT: CreateStmt +== 518 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 519 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 520 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 521 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 522 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 523 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 524 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 525 +CREATE TABLE plt1_adv_default PARTITION OF plt1_adv DEFAULT +-- +TABLE: name="plt1_adv_default" schema="" table="plt1_adv_default" ctx=DDL +STMT: CreateStmt +== 526 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +== 527 +CREATE TABLE plt2_adv_default PARTITION OF plt2_adv DEFAULT +-- +TABLE: name="plt2_adv_default" schema="" table="plt2_adv_default" ctx=DDL +STMT: CreateStmt +== 528 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 529 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 530 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 531 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 532 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 533 +DROP TABLE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: DropStmt +== 534 +DROP TABLE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: DropStmt +== 535 +-- Test the process_outer_partition() code path +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: CreateStmt +== 536 +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0000', '0001', '0002') +-- +TABLE: name="plt1_adv_p1" schema="" table="plt1_adv_p1" ctx=DDL +STMT: CreateStmt +== 537 +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0003', '0004') +-- +TABLE: name="plt1_adv_p2" schema="" table="plt1_adv_p2" ctx=DDL +STMT: CreateStmt +== 538 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 539 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +== 540 +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: CreateStmt +== 541 +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002') +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: CreateStmt +== 542 +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0003', '0004') +-- +TABLE: name="plt2_adv_p2" schema="" table="plt2_adv_p2" ctx=DDL +STMT: CreateStmt +== 543 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (2, 3, 4) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 544 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +== 545 +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: CreateStmt +== 546 +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0001') +-- +TABLE: name="plt3_adv_p1" schema="" table="plt3_adv_p1" ctx=DDL +STMT: CreateStmt +== 547 +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0003', '0004') +-- +TABLE: name="plt3_adv_p2" schema="" table="plt3_adv_p2" ctx=DDL +STMT: CreateStmt +== 548 +INSERT INTO plt3_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (1, 3, 4) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 549 +ANALYZE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: VacuumStmt +== 550 +-- This tests that when merging partitions from plt1_adv and plt2_adv in +-- merge_list_bounds(), process_outer_partition() returns an already-assigned +-- merged partition when re-called with plt1_adv_p1 for the second list value +-- '0001' of that partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 551 +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +STMT: SelectStmt +== 552 +DROP TABLE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: DropStmt +== 553 +DROP TABLE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: DropStmt +== 554 +DROP TABLE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: DropStmt +== 555 +-- Tests for multi-level partitioned tables +CREATE TABLE alpha (a double precision, b int, c text) PARTITION BY RANGE (a) +-- +TABLE: name="alpha" schema="" table="alpha" ctx=DDL +STMT: CreateStmt +== 556 +CREATE TABLE alpha_neg PARTITION OF alpha FOR VALUES FROM ('-Infinity') TO (0) PARTITION BY RANGE (b) +-- +TABLE: name="alpha_neg" schema="" table="alpha_neg" ctx=DDL +STMT: CreateStmt +== 557 +CREATE TABLE alpha_pos PARTITION OF alpha FOR VALUES FROM (0) TO (10.0) PARTITION BY LIST (c) +-- +TABLE: name="alpha_pos" schema="" table="alpha_pos" ctx=DDL +STMT: CreateStmt +== 558 +CREATE TABLE alpha_neg_p1 PARTITION OF alpha_neg FOR VALUES FROM (100) TO (200) +-- +TABLE: name="alpha_neg_p1" schema="" table="alpha_neg_p1" ctx=DDL +STMT: CreateStmt +== 559 +CREATE TABLE alpha_neg_p2 PARTITION OF alpha_neg FOR VALUES FROM (200) TO (300) +-- +TABLE: name="alpha_neg_p2" schema="" table="alpha_neg_p2" ctx=DDL +STMT: CreateStmt +== 560 +CREATE TABLE alpha_neg_p3 PARTITION OF alpha_neg FOR VALUES FROM (300) TO (400) +-- +TABLE: name="alpha_neg_p3" schema="" table="alpha_neg_p3" ctx=DDL +STMT: CreateStmt +== 561 +CREATE TABLE alpha_pos_p1 PARTITION OF alpha_pos FOR VALUES IN ('0001', '0003') +-- +TABLE: name="alpha_pos_p1" schema="" table="alpha_pos_p1" ctx=DDL +STMT: CreateStmt +== 562 +CREATE TABLE alpha_pos_p2 PARTITION OF alpha_pos FOR VALUES IN ('0004', '0006') +-- +TABLE: name="alpha_pos_p2" schema="" table="alpha_pos_p2" ctx=DDL +STMT: CreateStmt +== 563 +CREATE TABLE alpha_pos_p3 PARTITION OF alpha_pos FOR VALUES IN ('0008', '0009') +-- +TABLE: name="alpha_pos_p3" schema="" table="alpha_pos_p3" ctx=DDL +STMT: CreateStmt +== 564 +INSERT INTO alpha_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9) +-- +TABLE: name="alpha_neg" schema="" table="alpha_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 565 +INSERT INTO alpha_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9) +-- +TABLE: name="alpha_pos" schema="" table="alpha_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 566 +ANALYZE alpha +-- +TABLE: name="alpha" schema="" table="alpha" ctx=DDL +STMT: VacuumStmt +== 567 +CREATE TABLE beta (a double precision, b int, c text) PARTITION BY RANGE (a) +-- +TABLE: name="beta" schema="" table="beta" ctx=DDL +STMT: CreateStmt +== 568 +CREATE TABLE beta_neg PARTITION OF beta FOR VALUES FROM (-10.0) TO (0) PARTITION BY RANGE (b) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DDL +STMT: CreateStmt +== 569 +CREATE TABLE beta_pos PARTITION OF beta FOR VALUES FROM (0) TO ('Infinity') PARTITION BY LIST (c) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DDL +STMT: CreateStmt +== 570 +CREATE TABLE beta_neg_p1 PARTITION OF beta_neg FOR VALUES FROM (100) TO (150) +-- +TABLE: name="beta_neg_p1" schema="" table="beta_neg_p1" ctx=DDL +STMT: CreateStmt +== 571 +CREATE TABLE beta_neg_p2 PARTITION OF beta_neg FOR VALUES FROM (200) TO (300) +-- +TABLE: name="beta_neg_p2" schema="" table="beta_neg_p2" ctx=DDL +STMT: CreateStmt +== 572 +CREATE TABLE beta_neg_p3 PARTITION OF beta_neg FOR VALUES FROM (350) TO (500) +-- +TABLE: name="beta_neg_p3" schema="" table="beta_neg_p3" ctx=DDL +STMT: CreateStmt +== 573 +CREATE TABLE beta_pos_p1 PARTITION OF beta_pos FOR VALUES IN ('0002', '0003') +-- +TABLE: name="beta_pos_p1" schema="" table="beta_pos_p1" ctx=DDL +STMT: CreateStmt +== 574 +CREATE TABLE beta_pos_p2 PARTITION OF beta_pos FOR VALUES IN ('0004', '0006') +-- +TABLE: name="beta_pos_p2" schema="" table="beta_pos_p2" ctx=DDL +STMT: CreateStmt +== 575 +CREATE TABLE beta_pos_p3 PARTITION OF beta_pos FOR VALUES IN ('0007', '0009') +-- +TABLE: name="beta_pos_p3" schema="" table="beta_pos_p3" ctx=DDL +STMT: CreateStmt +== 576 +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 577 +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 578 +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 579 +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 580 +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 581 +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +== 582 +ANALYZE beta +-- +TABLE: name="beta" schema="" table="beta" ctx=DDL +STMT: VacuumStmt +== 583 +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 584 +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +== 585 +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 586 +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +== 587 +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 588 +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +== 589 +-- partitionwise join with fractional paths +CREATE TABLE fract_t (id BIGINT, PRIMARY KEY (id)) PARTITION BY RANGE (id) +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DDL +STMT: CreateStmt +== 590 +CREATE TABLE fract_t0 PARTITION OF fract_t FOR VALUES FROM ('0') TO ('1000') +-- +TABLE: name="fract_t0" schema="" table="fract_t0" ctx=DDL +STMT: CreateStmt +== 591 +CREATE TABLE fract_t1 PARTITION OF fract_t FOR VALUES FROM ('1000') TO ('2000') +-- +TABLE: name="fract_t1" schema="" table="fract_t1" ctx=DDL +STMT: CreateStmt +== 592 +-- insert data +INSERT INTO fract_t (id) (SELECT generate_series(0, 1999)) +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 593 +ANALYZE fract_t +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DDL +STMT: VacuumStmt +== 594 +-- verify plan; nested index only scans +SET max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +== 595 +SET enable_partitionwise_join = on +-- +STMT: VariableSetStmt +== 596 +EXPLAIN (COSTS OFF) +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id ASC LIMIT 10 +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +ALIAS: "x"="fract_t" +ALIAS: "y"="fract_t" +STMT: ExplainStmt +STMT: SelectStmt +== 597 +EXPLAIN (COSTS OFF) +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id DESC LIMIT 10 +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +ALIAS: "x"="fract_t" +ALIAS: "y"="fract_t" +STMT: ExplainStmt +STMT: SelectStmt +== 598 +-- cleanup +DROP TABLE fract_t +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DDL +STMT: DropStmt +== 599 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +== 600 +RESET enable_partitionwise_join +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/partition_prune.metadata.json b/parser/testdata/summary/postgres_regress/partition_prune.metadata.json new file mode 100644 index 0000000..6644147 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_prune.metadata.json @@ -0,0 +1,702 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698" + ] +} diff --git a/parser/testdata/summary/postgres_regress/partition_prune.test b/parser/testdata/summary/postgres_regress/partition_prune.test new file mode 100644 index 0000000..f8bcdda --- /dev/null +++ b/parser/testdata/summary/postgres_regress/partition_prune.test @@ -0,0 +1,4633 @@ +== 001 +|-- +-- Test partitioning planner code +|-- + +-- Force generic plans to be used for all prepared statements in this file. +set plan_cache_mode = force_generic_plan +-- +STMT: VariableSetStmt +== 002 +create table lp (a char) partition by list (a) +-- +TABLE: name="lp" schema="" table="lp" ctx=DDL +STMT: CreateStmt +== 003 +create table lp_default partition of lp default +-- +TABLE: name="lp_default" schema="" table="lp_default" ctx=DDL +STMT: CreateStmt +== 004 +create table lp_ef partition of lp for values in ('e', 'f') +-- +TABLE: name="lp_ef" schema="" table="lp_ef" ctx=DDL +STMT: CreateStmt +== 005 +create table lp_ad partition of lp for values in ('a', 'd') +-- +TABLE: name="lp_ad" schema="" table="lp_ad" ctx=DDL +STMT: CreateStmt +== 006 +create table lp_bc partition of lp for values in ('b', 'c') +-- +TABLE: name="lp_bc" schema="" table="lp_bc" ctx=DDL +STMT: CreateStmt +== 007 +create table lp_g partition of lp for values in ('g') +-- +TABLE: name="lp_g" schema="" table="lp_g" ctx=DDL +STMT: CreateStmt +== 008 +create table lp_null partition of lp for values in (null) +-- +TABLE: name="lp_null" schema="" table="lp_null" ctx=DDL +STMT: CreateStmt +== 009 +explain (costs off) select * from lp +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 010 +explain (costs off) select * from lp where a > 'a' and a < 'd' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 011 +explain (costs off) select * from lp where a > 'a' and a <= 'd' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 012 +explain (costs off) select * from lp where a = 'a' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 013 +explain (costs off) select * from lp where 'a' = a +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 014 +/* commuted */ +explain (costs off) select * from lp where a is not null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 015 +explain (costs off) select * from lp where a is null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 016 +explain (costs off) select * from lp where a = 'a' or a = 'c' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 017 +explain (costs off) select * from lp where a is not null and (a = 'a' or a = 'c') +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 018 +explain (costs off) select * from lp where a <> 'g' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 019 +explain (costs off) select * from lp where a <> 'a' and a <> 'd' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 020 +explain (costs off) select * from lp where a not in ('a', 'd') +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 021 +-- collation matches the partitioning collation, pruning works +create table coll_pruning (a text collate "C") partition by list (a) +-- +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=DDL +STMT: CreateStmt +== 022 +create table coll_pruning_a partition of coll_pruning for values in ('a') +-- +TABLE: name="coll_pruning_a" schema="" table="coll_pruning_a" ctx=DDL +STMT: CreateStmt +== 023 +create table coll_pruning_b partition of coll_pruning for values in ('b') +-- +TABLE: name="coll_pruning_b" schema="" table="coll_pruning_b" ctx=DDL +STMT: CreateStmt +== 024 +create table coll_pruning_def partition of coll_pruning default +-- +TABLE: name="coll_pruning_def" schema="" table="coll_pruning_def" ctx=DDL +STMT: CreateStmt +== 025 +explain (costs off) select * from coll_pruning where a collate "C" = 'a' collate "C" +-- +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 026 +-- collation doesn't match the partitioning collation, no pruning occurs +explain (costs off) select * from coll_pruning where a collate "POSIX" = 'a' collate "POSIX" +-- +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 027 +create table rlp (a int, b varchar) partition by range (a) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=DDL +STMT: CreateStmt +== 028 +create table rlp_default partition of rlp default partition by list (a) +-- +TABLE: name="rlp_default" schema="" table="rlp_default" ctx=DDL +STMT: CreateStmt +== 029 +create table rlp_default_default partition of rlp_default default +-- +TABLE: name="rlp_default_default" schema="" table="rlp_default_default" ctx=DDL +STMT: CreateStmt +== 030 +create table rlp_default_10 partition of rlp_default for values in (10) +-- +TABLE: name="rlp_default_10" schema="" table="rlp_default_10" ctx=DDL +STMT: CreateStmt +== 031 +create table rlp_default_30 partition of rlp_default for values in (30) +-- +TABLE: name="rlp_default_30" schema="" table="rlp_default_30" ctx=DDL +STMT: CreateStmt +== 032 +create table rlp_default_null partition of rlp_default for values in (null) +-- +TABLE: name="rlp_default_null" schema="" table="rlp_default_null" ctx=DDL +STMT: CreateStmt +== 033 +create table rlp1 partition of rlp for values from (minvalue) to (1) +-- +TABLE: name="rlp1" schema="" table="rlp1" ctx=DDL +STMT: CreateStmt +== 034 +create table rlp2 partition of rlp for values from (1) to (10) +-- +TABLE: name="rlp2" schema="" table="rlp2" ctx=DDL +STMT: CreateStmt +== 035 +create table rlp3 (b varchar, a int) partition by list (b varchar_ops) +-- +TABLE: name="rlp3" schema="" table="rlp3" ctx=DDL +STMT: CreateStmt +== 036 +create table rlp3_default partition of rlp3 default +-- +TABLE: name="rlp3_default" schema="" table="rlp3_default" ctx=DDL +STMT: CreateStmt +== 037 +create table rlp3abcd partition of rlp3 for values in ('ab', 'cd') +-- +TABLE: name="rlp3abcd" schema="" table="rlp3abcd" ctx=DDL +STMT: CreateStmt +== 038 +create table rlp3efgh partition of rlp3 for values in ('ef', 'gh') +-- +TABLE: name="rlp3efgh" schema="" table="rlp3efgh" ctx=DDL +STMT: CreateStmt +== 039 +create table rlp3nullxy partition of rlp3 for values in (null, 'xy') +-- +TABLE: name="rlp3nullxy" schema="" table="rlp3nullxy" ctx=DDL +STMT: CreateStmt +== 040 +alter table rlp attach partition rlp3 for values from (15) to (20) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=DDL +STMT: AlterTableStmt +== 041 +create table rlp4 partition of rlp for values from (20) to (30) partition by range (a) +-- +TABLE: name="rlp4" schema="" table="rlp4" ctx=DDL +STMT: CreateStmt +== 042 +create table rlp4_default partition of rlp4 default +-- +TABLE: name="rlp4_default" schema="" table="rlp4_default" ctx=DDL +STMT: CreateStmt +== 043 +create table rlp4_1 partition of rlp4 for values from (20) to (25) +-- +TABLE: name="rlp4_1" schema="" table="rlp4_1" ctx=DDL +STMT: CreateStmt +== 044 +create table rlp4_2 partition of rlp4 for values from (25) to (29) +-- +TABLE: name="rlp4_2" schema="" table="rlp4_2" ctx=DDL +STMT: CreateStmt +== 045 +create table rlp5 partition of rlp for values from (31) to (maxvalue) partition by range (a) +-- +TABLE: name="rlp5" schema="" table="rlp5" ctx=DDL +STMT: CreateStmt +== 046 +create table rlp5_default partition of rlp5 default +-- +TABLE: name="rlp5_default" schema="" table="rlp5_default" ctx=DDL +STMT: CreateStmt +== 047 +create table rlp5_1 partition of rlp5 for values from (31) to (40) +-- +TABLE: name="rlp5_1" schema="" table="rlp5_1" ctx=DDL +STMT: CreateStmt +== 048 +explain (costs off) select * from rlp where a < 1 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 049 +explain (costs off) select * from rlp where 1 > a +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +/* commuted */ +explain (costs off) select * from rlp where a <= 1 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 051 +explain (costs off) select * from rlp where a = 1 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +explain (costs off) select * from rlp where a = 1::bigint +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 053 +/* same as above */ +explain (costs off) select * from rlp where a = 1::numeric +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 054 +/* no pruning */ +explain (costs off) select * from rlp where a <= 10 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 055 +explain (costs off) select * from rlp where a > 10 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 056 +explain (costs off) select * from rlp where a < 15 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 057 +explain (costs off) select * from rlp where a <= 15 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 058 +explain (costs off) select * from rlp where a > 15 and b = 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 059 +explain (costs off) select * from rlp where a = 16 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 060 +explain (costs off) select * from rlp where a = 16 and b in ('not', 'in', 'here') +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 061 +explain (costs off) select * from rlp where a = 16 and b < 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 062 +explain (costs off) select * from rlp where a = 16 and b <= 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 063 +explain (costs off) select * from rlp where a = 16 and b is null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 064 +explain (costs off) select * from rlp where a = 16 and b is not null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 065 +explain (costs off) select * from rlp where a is null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 066 +explain (costs off) select * from rlp where a is not null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 067 +explain (costs off) select * from rlp where a > 30 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 068 +explain (costs off) select * from rlp where a = 30 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 069 +/* only default is scanned */ +explain (costs off) select * from rlp where a <= 31 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 070 +explain (costs off) select * from rlp where a = 1 or a = 7 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 071 +explain (costs off) select * from rlp where a = 1 or b = 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 072 +explain (costs off) select * from rlp where a > 20 and a < 27 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 073 +explain (costs off) select * from rlp where a = 29 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 074 +explain (costs off) select * from rlp where a >= 29 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 075 +explain (costs off) select * from rlp where a < 1 or (a > 20 and a < 25) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 076 +-- where clause contradicts sub-partition's constraint +explain (costs off) select * from rlp where a = 20 or a = 40 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 077 +explain (costs off) select * from rlp3 where a = 20 +-- +TABLE: name="rlp3" schema="" table="rlp3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 078 +/* empty */ + +-- redundant clauses are eliminated +explain (costs off) select * from rlp where a > 1 and a = 10 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 079 +/* only default */ +explain (costs off) select * from rlp where a > 1 and a >=15 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 080 +/* rlp3 onwards, including default */ +explain (costs off) select * from rlp where a = 1 and a = 3 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 081 +/* empty */ +explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = 15) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 082 +-- multi-column keys +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +STMT: CreateStmt +== 083 +create table mc3p_default partition of mc3p default +-- +TABLE: name="mc3p_default" schema="" table="mc3p_default" ctx=DDL +STMT: CreateStmt +== 084 +create table mc3p0 partition of mc3p for values from (minvalue, minvalue, minvalue) to (1, 1, 1) +-- +TABLE: name="mc3p0" schema="" table="mc3p0" ctx=DDL +STMT: CreateStmt +== 085 +create table mc3p1 partition of mc3p for values from (1, 1, 1) to (10, 5, 10) +-- +TABLE: name="mc3p1" schema="" table="mc3p1" ctx=DDL +STMT: CreateStmt +== 086 +create table mc3p2 partition of mc3p for values from (10, 5, 10) to (10, 10, 10) +-- +TABLE: name="mc3p2" schema="" table="mc3p2" ctx=DDL +STMT: CreateStmt +== 087 +create table mc3p3 partition of mc3p for values from (10, 10, 10) to (10, 10, 20) +-- +TABLE: name="mc3p3" schema="" table="mc3p3" ctx=DDL +STMT: CreateStmt +== 088 +create table mc3p4 partition of mc3p for values from (10, 10, 20) to (10, maxvalue, maxvalue) +-- +TABLE: name="mc3p4" schema="" table="mc3p4" ctx=DDL +STMT: CreateStmt +== 089 +create table mc3p5 partition of mc3p for values from (11, 1, 1) to (20, 10, 10) +-- +TABLE: name="mc3p5" schema="" table="mc3p5" ctx=DDL +STMT: CreateStmt +== 090 +create table mc3p6 partition of mc3p for values from (20, 10, 10) to (20, 20, 20) +-- +TABLE: name="mc3p6" schema="" table="mc3p6" ctx=DDL +STMT: CreateStmt +== 091 +create table mc3p7 partition of mc3p for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) +-- +TABLE: name="mc3p7" schema="" table="mc3p7" ctx=DDL +STMT: CreateStmt +== 092 +explain (costs off) select * from mc3p where a = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 093 +explain (costs off) select * from mc3p where a = 1 and abs(b) < 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 094 +explain (costs off) select * from mc3p where a = 1 and abs(b) = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 095 +explain (costs off) select * from mc3p where a = 1 and abs(b) = 1 and c < 8 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 096 +explain (costs off) select * from mc3p where a = 10 and abs(b) between 5 and 35 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 097 +explain (costs off) select * from mc3p where a > 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 098 +explain (costs off) select * from mc3p where a >= 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 099 +explain (costs off) select * from mc3p where a < 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 100 +explain (costs off) select * from mc3p where a <= 10 and abs(b) < 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 101 +explain (costs off) select * from mc3p where a = 11 and abs(b) = 0 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 102 +explain (costs off) select * from mc3p where a = 20 and abs(b) = 10 and c = 100 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 103 +explain (costs off) select * from mc3p where a > 20 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 104 +explain (costs off) select * from mc3p where a >= 20 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 105 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 106 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) or a < 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 107 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) or a < 1 or a = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 108 +explain (costs off) select * from mc3p where a = 1 or abs(b) = 1 or c = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 109 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1) or (a = 10 and abs(b) = 10) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 110 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1) or (a = 10 and abs(b) = 9) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 111 +-- a simpler multi-column keys case +create table mc2p (a int, b int) partition by range (a, b) +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=DDL +STMT: CreateStmt +== 112 +create table mc2p_default partition of mc2p default +-- +TABLE: name="mc2p_default" schema="" table="mc2p_default" ctx=DDL +STMT: CreateStmt +== 113 +create table mc2p0 partition of mc2p for values from (minvalue, minvalue) to (1, minvalue) +-- +TABLE: name="mc2p0" schema="" table="mc2p0" ctx=DDL +STMT: CreateStmt +== 114 +create table mc2p1 partition of mc2p for values from (1, minvalue) to (1, 1) +-- +TABLE: name="mc2p1" schema="" table="mc2p1" ctx=DDL +STMT: CreateStmt +== 115 +create table mc2p2 partition of mc2p for values from (1, 1) to (2, minvalue) +-- +TABLE: name="mc2p2" schema="" table="mc2p2" ctx=DDL +STMT: CreateStmt +== 116 +create table mc2p3 partition of mc2p for values from (2, minvalue) to (2, 1) +-- +TABLE: name="mc2p3" schema="" table="mc2p3" ctx=DDL +STMT: CreateStmt +== 117 +create table mc2p4 partition of mc2p for values from (2, 1) to (2, maxvalue) +-- +TABLE: name="mc2p4" schema="" table="mc2p4" ctx=DDL +STMT: CreateStmt +== 118 +create table mc2p5 partition of mc2p for values from (2, maxvalue) to (maxvalue, maxvalue) +-- +TABLE: name="mc2p5" schema="" table="mc2p5" ctx=DDL +STMT: CreateStmt +== 119 +explain (costs off) select * from mc2p where a < 2 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 120 +explain (costs off) select * from mc2p where a = 2 and b < 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 121 +explain (costs off) select * from mc2p where a > 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 122 +explain (costs off) select * from mc2p where a = 1 and b > 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 123 +-- all partitions but the default one should be pruned +explain (costs off) select * from mc2p where a = 1 and b is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 124 +explain (costs off) select * from mc2p where a is null and b is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 125 +explain (costs off) select * from mc2p where a is null and b = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 126 +explain (costs off) select * from mc2p where a is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 127 +explain (costs off) select * from mc2p where b is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 128 +-- boolean partitioning +create table boolpart (a bool) partition by list (a) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DDL +STMT: CreateStmt +== 129 +create table boolpart_default partition of boolpart default +-- +TABLE: name="boolpart_default" schema="" table="boolpart_default" ctx=DDL +STMT: CreateStmt +== 130 +create table boolpart_t partition of boolpart for values in ('true') +-- +TABLE: name="boolpart_t" schema="" table="boolpart_t" ctx=DDL +STMT: CreateStmt +== 131 +create table boolpart_f partition of boolpart for values in ('false') +-- +TABLE: name="boolpart_f" schema="" table="boolpart_f" ctx=DDL +STMT: CreateStmt +== 132 +insert into boolpart values (true), (false), (null) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +explain (costs off) select * from boolpart where a in (true, false) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 134 +explain (costs off) select * from boolpart where a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 135 +explain (costs off) select * from boolpart where not a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 136 +explain (costs off) select * from boolpart where a is true or a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 137 +explain (costs off) select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 138 +explain (costs off) select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 139 +explain (costs off) select * from boolpart where a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 140 +explain (costs off) select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 141 +select * from boolpart where a in (true, false) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 142 +select * from boolpart where a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 143 +select * from boolpart where not a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 144 +select * from boolpart where a is true or a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 145 +select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 146 +select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 147 +select * from boolpart where a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 148 +select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 149 +-- try some other permutations with a NULL partition instead of a DEFAULT +delete from boolpart where a is null +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DML +STMT: DeleteStmt +== 150 +create table boolpart_null partition of boolpart for values in (null) +-- +TABLE: name="boolpart_null" schema="" table="boolpart_null" ctx=DDL +STMT: CreateStmt +== 151 +insert into boolpart values(null) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +explain (costs off) select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 153 +explain (costs off) select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 154 +explain (costs off) select * from boolpart where a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 155 +explain (costs off) select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 156 +select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 157 +select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 158 +select * from boolpart where a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 159 +select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 160 +-- check that all partitions are pruned when faced with conflicting clauses +explain (costs off) select * from boolpart where a is not unknown and a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 161 +explain (costs off) select * from boolpart where a is false and a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 162 +explain (costs off) select * from boolpart where a is true and a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 163 +-- inverse boolean partitioning - a seemingly unlikely design, but we've got +-- code for it, so we'd better test it. +create table iboolpart (a bool) partition by list ((not a)) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DDL +STMT: CreateStmt +== 164 +create table iboolpart_default partition of iboolpart default +-- +TABLE: name="iboolpart_default" schema="" table="iboolpart_default" ctx=DDL +STMT: CreateStmt +== 165 +create table iboolpart_f partition of iboolpart for values in ('true') +-- +TABLE: name="iboolpart_f" schema="" table="iboolpart_f" ctx=DDL +STMT: CreateStmt +== 166 +create table iboolpart_t partition of iboolpart for values in ('false') +-- +TABLE: name="iboolpart_t" schema="" table="iboolpart_t" ctx=DDL +STMT: CreateStmt +== 167 +insert into iboolpart values (true), (false), (null) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +explain (costs off) select * from iboolpart where a in (true, false) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 169 +explain (costs off) select * from iboolpart where a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 170 +explain (costs off) select * from iboolpart where not a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 171 +explain (costs off) select * from iboolpart where a is true or a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 172 +explain (costs off) select * from iboolpart where a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 173 +explain (costs off) select * from iboolpart where a is not true and a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 174 +explain (costs off) select * from iboolpart where a is unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 175 +explain (costs off) select * from iboolpart where a is not unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 176 +select * from iboolpart where a in (true, false) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 177 +select * from iboolpart where a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 178 +select * from iboolpart where not a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 179 +select * from iboolpart where a is true or a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 180 +select * from iboolpart where a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 181 +select * from iboolpart where a is not true and a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 182 +select * from iboolpart where a is unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 183 +select * from iboolpart where a is not unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 184 +-- Try some other permutations with a NULL partition instead of a DEFAULT +delete from iboolpart where a is null +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DML +STMT: DeleteStmt +== 185 +create table iboolpart_null partition of iboolpart for values in (null) +-- +TABLE: name="iboolpart_null" schema="" table="iboolpart_null" ctx=DDL +STMT: CreateStmt +== 186 +insert into iboolpart values(null) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +-- Pruning shouldn't take place for these. Just check the result is correct +select * from iboolpart where a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 188 +select * from iboolpart where a is not true and a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 189 +select * from iboolpart where a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 190 +create table boolrangep (a bool, b bool, c int) partition by range (a,b,c) +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=DDL +STMT: CreateStmt +== 191 +create table boolrangep_tf partition of boolrangep for values from ('true', 'false', 0) to ('true', 'false', 100) +-- +TABLE: name="boolrangep_tf" schema="" table="boolrangep_tf" ctx=DDL +STMT: CreateStmt +== 192 +create table boolrangep_ft partition of boolrangep for values from ('false', 'true', 0) to ('false', 'true', 100) +-- +TABLE: name="boolrangep_ft" schema="" table="boolrangep_ft" ctx=DDL +STMT: CreateStmt +== 193 +create table boolrangep_ff1 partition of boolrangep for values from ('false', 'false', 0) to ('false', 'false', 50) +-- +TABLE: name="boolrangep_ff1" schema="" table="boolrangep_ff1" ctx=DDL +STMT: CreateStmt +== 194 +create table boolrangep_ff2 partition of boolrangep for values from ('false', 'false', 50) to ('false', 'false', 100) +-- +TABLE: name="boolrangep_ff2" schema="" table="boolrangep_ff2" ctx=DDL +STMT: CreateStmt +== 195 +create table boolrangep_null partition of boolrangep default +-- +TABLE: name="boolrangep_null" schema="" table="boolrangep_null" ctx=DDL +STMT: CreateStmt +== 196 +-- try a more complex case that's been known to trip up pruning in the past +explain (costs off) select * from boolrangep where not a and not b and c = 25 +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 197 +-- ensure we prune boolrangep_tf +explain (costs off) select * from boolrangep where a is not true and not b and c = 25 +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 198 +-- ensure we prune everything apart from boolrangep_tf and boolrangep_null +explain (costs off) select * from boolrangep where a is not false and not b and c = 25 +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 199 +-- test scalar-to-array operators +create table coercepart (a varchar) partition by list (a) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=DDL +STMT: CreateStmt +== 200 +create table coercepart_ab partition of coercepart for values in ('ab') +-- +TABLE: name="coercepart_ab" schema="" table="coercepart_ab" ctx=DDL +STMT: CreateStmt +== 201 +create table coercepart_bc partition of coercepart for values in ('bc') +-- +TABLE: name="coercepart_bc" schema="" table="coercepart_bc" ctx=DDL +STMT: CreateStmt +== 202 +create table coercepart_cd partition of coercepart for values in ('cd') +-- +TABLE: name="coercepart_cd" schema="" table="coercepart_cd" ctx=DDL +STMT: CreateStmt +== 203 +explain (costs off) select * from coercepart where a in ('ab', to_char(125, '999')) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 204 +explain (costs off) select * from coercepart where a ~ any ('{ab}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 205 +explain (costs off) select * from coercepart where a !~ all ('{ab}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 206 +explain (costs off) select * from coercepart where a ~ any ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 207 +explain (costs off) select * from coercepart where a !~ all ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 208 +explain (costs off) select * from coercepart where a = any ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 209 +explain (costs off) select * from coercepart where a = any ('{ab,null}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 210 +explain (costs off) select * from coercepart where a = any (null::text[]) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 211 +explain (costs off) select * from coercepart where a = all ('{ab}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 212 +explain (costs off) select * from coercepart where a = all ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 213 +explain (costs off) select * from coercepart where a = all ('{ab,null}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 214 +explain (costs off) select * from coercepart where a = all (null::text[]) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 215 +drop table coercepart +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=DDL +STMT: DropStmt +== 216 +CREATE TABLE part (a INT, b INT) PARTITION BY LIST (a) +-- +TABLE: name="part" schema="" table="part" ctx=DDL +STMT: CreateStmt +== 217 +CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2) +-- +TABLE: name="part_p1" schema="" table="part_p1" ctx=DDL +STMT: CreateStmt +== 218 +CREATE TABLE part_p2 PARTITION OF part DEFAULT PARTITION BY RANGE(a) +-- +TABLE: name="part_p2" schema="" table="part_p2" ctx=DDL +STMT: CreateStmt +== 219 +CREATE TABLE part_p2_p1 PARTITION OF part_p2 DEFAULT +-- +TABLE: name="part_p2_p1" schema="" table="part_p2_p1" ctx=DDL +STMT: CreateStmt +== 220 +CREATE TABLE part_rev (b INT, c INT, a INT) +-- +TABLE: name="part_rev" schema="" table="part_rev" ctx=DDL +STMT: CreateStmt +== 221 +ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3) +-- +TABLE: name="part" schema="" table="part" ctx=DDL +STMT: AlterTableStmt +== 222 +-- fail +ALTER TABLE part_rev DROP COLUMN c +-- +TABLE: name="part_rev" schema="" table="part_rev" ctx=DDL +STMT: AlterTableStmt +== 223 +ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3) +-- +TABLE: name="part" schema="" table="part" ctx=DDL +STMT: AlterTableStmt +== 224 +-- now it's ok +INSERT INTO part VALUES (-1,-1), (1,1), (2,NULL), (NULL,-2),(NULL,NULL) +-- +TABLE: name="part" schema="" table="part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +EXPLAIN (COSTS OFF) SELECT tableoid::regclass as part, a, b FROM part WHERE a IS NULL ORDER BY 1, 2, 3 +-- +TABLE: name="part" schema="" table="part" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 226 +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM part p(x) ORDER BY x +-- +TABLE: name="part" schema="" table="part" ctx=Select +ALIAS: "p"="part" +STMT: ExplainStmt +STMT: SelectStmt +== 227 +|-- +-- some more cases +|-- + +|-- +-- pruning for partitioned table appearing inside a sub-query +|-- +-- pruning won't work for mc3p, because some keys are Params +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = t1.b and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +ALIAS: "t1"="mc2p" +ALIAS: "t2"="mc3p" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 228 +-- pruning should work fine, because values for a prefix of keys (a, b) are +-- available +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.c = t1.b and abs(t2.b) = 1 and t2.a = 1) s where t1.a = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +ALIAS: "t1"="mc2p" +ALIAS: "t2"="mc3p" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 229 +-- also here, because values for all keys are provided +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = 1 and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +ALIAS: "t1"="mc2p" +ALIAS: "t2"="mc3p" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 230 +|-- +-- pruning with clauses containing <> operator +|-- + +-- doesn't prune range partitions +create table rp (a int) partition by range (a) +-- +TABLE: name="rp" schema="" table="rp" ctx=DDL +STMT: CreateStmt +== 231 +create table rp0 partition of rp for values from (minvalue) to (1) +-- +TABLE: name="rp0" schema="" table="rp0" ctx=DDL +STMT: CreateStmt +== 232 +create table rp1 partition of rp for values from (1) to (2) +-- +TABLE: name="rp1" schema="" table="rp1" ctx=DDL +STMT: CreateStmt +== 233 +create table rp2 partition of rp for values from (2) to (maxvalue) +-- +TABLE: name="rp2" schema="" table="rp2" ctx=DDL +STMT: CreateStmt +== 234 +explain (costs off) select * from rp where a <> 1 +-- +TABLE: name="rp" schema="" table="rp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 235 +explain (costs off) select * from rp where a <> 1 and a <> 2 +-- +TABLE: name="rp" schema="" table="rp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 236 +-- null partition should be eliminated due to strict <> clause. +explain (costs off) select * from lp where a <> 'a' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 237 +-- ensure we detect contradictions in clauses; a can't be NULL and NOT NULL. +explain (costs off) select * from lp where a <> 'a' and a is null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 238 +explain (costs off) select * from lp where (a <> 'a' and a <> 'd') or a is null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 239 +-- check that it also works for a partitioned table that's not root, +-- which in this case are partitions of rlp that are themselves +-- list-partitioned on b +explain (costs off) select * from rlp where a = 15 and b <> 'ab' and b <> 'cd' and b <> 'xy' and b is not null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 240 +|-- +-- different collations for different keys with same expression +|-- +create table coll_pruning_multi (a text) partition by range (substr(a, 1) collate "POSIX", substr(a, 1) collate "C") +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=DDL +STMT: CreateStmt +== 241 +create table coll_pruning_multi1 partition of coll_pruning_multi for values from ('a', 'a') to ('a', 'e') +-- +TABLE: name="coll_pruning_multi1" schema="" table="coll_pruning_multi1" ctx=DDL +STMT: CreateStmt +== 242 +create table coll_pruning_multi2 partition of coll_pruning_multi for values from ('a', 'e') to ('a', 'z') +-- +TABLE: name="coll_pruning_multi2" schema="" table="coll_pruning_multi2" ctx=DDL +STMT: CreateStmt +== 243 +create table coll_pruning_multi3 partition of coll_pruning_multi for values from ('b', 'a') to ('b', 'e') +-- +TABLE: name="coll_pruning_multi3" schema="" table="coll_pruning_multi3" ctx=DDL +STMT: CreateStmt +== 244 +-- no pruning, because no value for the leading key +explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'e' collate "C" +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 245 +-- pruning, with a value provided for the leading key +explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'a' collate "POSIX" +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 246 +-- pruning, with values provided for both keys +explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'e' collate "C" and substr(a, 1) = 'a' collate "POSIX" +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 247 +|-- +-- LIKE operators don't prune +|-- +create table like_op_noprune (a text) partition by list (a) +-- +TABLE: name="like_op_noprune" schema="" table="like_op_noprune" ctx=DDL +STMT: CreateStmt +== 248 +create table like_op_noprune1 partition of like_op_noprune for values in ('ABC') +-- +TABLE: name="like_op_noprune1" schema="" table="like_op_noprune1" ctx=DDL +STMT: CreateStmt +== 249 +create table like_op_noprune2 partition of like_op_noprune for values in ('BCD') +-- +TABLE: name="like_op_noprune2" schema="" table="like_op_noprune2" ctx=DDL +STMT: CreateStmt +== 250 +explain (costs off) select * from like_op_noprune where a like '%BC' +-- +TABLE: name="like_op_noprune" schema="" table="like_op_noprune" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 251 +|-- +-- tests wherein clause value requires a cross-type comparison function +|-- +create table lparted_by_int2 (a smallint) partition by list (a) +-- +TABLE: name="lparted_by_int2" schema="" table="lparted_by_int2" ctx=DDL +STMT: CreateStmt +== 252 +create table lparted_by_int2_1 partition of lparted_by_int2 for values in (1) +-- +TABLE: name="lparted_by_int2_1" schema="" table="lparted_by_int2_1" ctx=DDL +STMT: CreateStmt +== 253 +create table lparted_by_int2_16384 partition of lparted_by_int2 for values in (16384) +-- +TABLE: name="lparted_by_int2_16384" schema="" table="lparted_by_int2_16384" ctx=DDL +STMT: CreateStmt +== 254 +explain (costs off) select * from lparted_by_int2 where a = 100_000_000_000_000 +-- +TABLE: name="lparted_by_int2" schema="" table="lparted_by_int2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 255 +create table rparted_by_int2 (a smallint) partition by range (a) +-- +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=DDL +STMT: CreateStmt +== 256 +create table rparted_by_int2_1 partition of rparted_by_int2 for values from (1) to (10) +-- +TABLE: name="rparted_by_int2_1" schema="" table="rparted_by_int2_1" ctx=DDL +STMT: CreateStmt +== 257 +create table rparted_by_int2_16384 partition of rparted_by_int2 for values from (10) to (16384) +-- +TABLE: name="rparted_by_int2_16384" schema="" table="rparted_by_int2_16384" ctx=DDL +STMT: CreateStmt +== 258 +-- all partitions pruned +explain (costs off) select * from rparted_by_int2 where a > 100_000_000_000_000 +-- +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 259 +create table rparted_by_int2_maxvalue partition of rparted_by_int2 for values from (16384) to (maxvalue) +-- +TABLE: name="rparted_by_int2_maxvalue" schema="" table="rparted_by_int2_maxvalue" ctx=DDL +STMT: CreateStmt +== 260 +-- all partitions but rparted_by_int2_maxvalue pruned +explain (costs off) select * from rparted_by_int2 where a > 100_000_000_000_000 +-- +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 261 +drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2 +-- +TABLE: name="lp" schema="" table="lp" ctx=DDL +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=DDL +TABLE: name="rlp" schema="" table="rlp" ctx=DDL +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +TABLE: name="mc2p" schema="" table="mc2p" ctx=DDL +TABLE: name="boolpart" schema="" table="boolpart" ctx=DDL +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DDL +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=DDL +TABLE: name="rp" schema="" table="rp" ctx=DDL +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=DDL +TABLE: name="like_op_noprune" schema="" table="like_op_noprune" ctx=DDL +TABLE: name="lparted_by_int2" schema="" table="lparted_by_int2" ctx=DDL +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=DDL +STMT: DropStmt +== 262 +-- check that AlternativeSubPlan within a pruning expression gets cleaned up + +create table asptab (id int primary key) partition by range (id) +-- +TABLE: name="asptab" schema="" table="asptab" ctx=DDL +STMT: CreateStmt +== 263 +create table asptab0 partition of asptab for values from (0) to (1) +-- +TABLE: name="asptab0" schema="" table="asptab0" ctx=DDL +STMT: CreateStmt +== 264 +create table asptab1 partition of asptab for values from (1) to (2) +-- +TABLE: name="asptab1" schema="" table="asptab1" ctx=DDL +STMT: CreateStmt +== 265 +explain (costs off) +select * from + (select exists (select 1 from int4_tbl tinner where f1 = touter.f1) as b + from int4_tbl touter) ss, + asptab +where asptab.id > ss.b::int +-- +TABLE: name="asptab" schema="" table="asptab" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "tinner"="int4_tbl" +ALIAS: "touter"="int4_tbl" +FILTER: schema="" table="asptab" column="id" +FILTER: schema="" table="ss" column="b" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="touter" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 266 +drop table asptab +-- +TABLE: name="asptab" schema="" table="asptab" ctx=DDL +STMT: DropStmt +== 267 +|-- +-- Test Partition pruning for HASH partitioning +|-- +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different machines. See the definitions of +-- part_test_int4_ops and part_test_text_ops in test_setup.sql. +|-- + +create table hp (a int, b text, c int) + partition by hash (a part_test_int4_ops, b part_test_text_ops) +-- +TABLE: name="hp" schema="" table="hp" ctx=DDL +STMT: CreateStmt +== 268 +create table hp0 partition of hp for values with (modulus 4, remainder 0) +-- +TABLE: name="hp0" schema="" table="hp0" ctx=DDL +STMT: CreateStmt +== 269 +create table hp3 partition of hp for values with (modulus 4, remainder 3) +-- +TABLE: name="hp3" schema="" table="hp3" ctx=DDL +STMT: CreateStmt +== 270 +create table hp1 partition of hp for values with (modulus 4, remainder 1) +-- +TABLE: name="hp1" schema="" table="hp1" ctx=DDL +STMT: CreateStmt +== 271 +create table hp2 partition of hp for values with (modulus 4, remainder 2) +-- +TABLE: name="hp2" schema="" table="hp2" ctx=DDL +STMT: CreateStmt +== 272 +insert into hp values (null, null, 0) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 273 +insert into hp values (1, null, 1) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 274 +insert into hp values (1, 'xxx', 2) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 275 +insert into hp values (null, 'xxx', 3) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 276 +insert into hp values (2, 'xxx', 4) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 277 +insert into hp values (1, 'abcde', 5) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 278 +select tableoid::regclass, * from hp order by c +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +STMT: SelectStmt +== 279 +-- partial keys won't prune, nor would non-equality conditions +explain (costs off) select * from hp where a = 1 +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 280 +explain (costs off) select * from hp where b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 281 +explain (costs off) select * from hp where a is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 282 +explain (costs off) select * from hp where b is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 283 +explain (costs off) select * from hp where a < 1 and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 284 +explain (costs off) select * from hp where a <> 1 and b = 'yyy' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 285 +explain (costs off) select * from hp where a <> 1 and b <> 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 286 +-- pruning should work if either a value or a IS NULL clause is provided for +-- each of the keys +explain (costs off) select * from hp where a is null and b is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 287 +explain (costs off) select * from hp where a = 1 and b is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 288 +explain (costs off) select * from hp where a = 1 and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 289 +explain (costs off) select * from hp where a is null and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 290 +explain (costs off) select * from hp where a = 2 and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 291 +explain (costs off) select * from hp where a = 1 and b = 'abcde' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 292 +explain (costs off) select * from hp where (a = 1 and b = 'abcde') or (a = 2 and b = 'xxx') or (a is null and b is null) +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 293 +-- test pruning when not all the partitions exist +drop table hp1 +-- +TABLE: name="hp1" schema="" table="hp1" ctx=DDL +STMT: DropStmt +== 294 +drop table hp3 +-- +TABLE: name="hp3" schema="" table="hp3" ctx=DDL +STMT: DropStmt +== 295 +explain (costs off) select * from hp where a = 1 and b = 'abcde' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 296 +explain (costs off) select * from hp where a = 1 and b = 'abcde' and + (c = 2 or c = 3) +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 297 +drop table hp2 +-- +TABLE: name="hp2" schema="" table="hp2" ctx=DDL +STMT: DropStmt +== 298 +explain (costs off) select * from hp where a = 1 and b = 'abcde' and + (c = 2 or c = 3) +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 299 +|-- +-- Test runtime partition pruning +|-- +create table ab (a int not null, b int not null) partition by list (a) +-- +TABLE: name="ab" schema="" table="ab" ctx=DDL +STMT: CreateStmt +== 300 +create table ab_a2 partition of ab for values in(2) partition by list (b) +-- +TABLE: name="ab_a2" schema="" table="ab_a2" ctx=DDL +STMT: CreateStmt +== 301 +create table ab_a2_b1 partition of ab_a2 for values in (1) +-- +TABLE: name="ab_a2_b1" schema="" table="ab_a2_b1" ctx=DDL +STMT: CreateStmt +== 302 +create table ab_a2_b2 partition of ab_a2 for values in (2) +-- +TABLE: name="ab_a2_b2" schema="" table="ab_a2_b2" ctx=DDL +STMT: CreateStmt +== 303 +create table ab_a2_b3 partition of ab_a2 for values in (3) +-- +TABLE: name="ab_a2_b3" schema="" table="ab_a2_b3" ctx=DDL +STMT: CreateStmt +== 304 +create table ab_a1 partition of ab for values in(1) partition by list (b) +-- +TABLE: name="ab_a1" schema="" table="ab_a1" ctx=DDL +STMT: CreateStmt +== 305 +create table ab_a1_b1 partition of ab_a1 for values in (1) +-- +TABLE: name="ab_a1_b1" schema="" table="ab_a1_b1" ctx=DDL +STMT: CreateStmt +== 306 +create table ab_a1_b2 partition of ab_a1 for values in (2) +-- +TABLE: name="ab_a1_b2" schema="" table="ab_a1_b2" ctx=DDL +STMT: CreateStmt +== 307 +create table ab_a1_b3 partition of ab_a1 for values in (3) +-- +TABLE: name="ab_a1_b3" schema="" table="ab_a1_b3" ctx=DDL +STMT: CreateStmt +== 308 +create table ab_a3 partition of ab for values in(3) partition by list (b) +-- +TABLE: name="ab_a3" schema="" table="ab_a3" ctx=DDL +STMT: CreateStmt +== 309 +create table ab_a3_b1 partition of ab_a3 for values in (1) +-- +TABLE: name="ab_a3_b1" schema="" table="ab_a3_b1" ctx=DDL +STMT: CreateStmt +== 310 +create table ab_a3_b2 partition of ab_a3 for values in (2) +-- +TABLE: name="ab_a3_b2" schema="" table="ab_a3_b2" ctx=DDL +STMT: CreateStmt +== 311 +create table ab_a3_b3 partition of ab_a3 for values in (3) +-- +TABLE: name="ab_a3_b3" schema="" table="ab_a3_b3" ctx=DDL +STMT: CreateStmt +== 312 +-- Disallow index only scans as concurrent transactions may stop visibility +-- bits being set causing "Heap Fetches" to be unstable in the EXPLAIN ANALYZE +-- output. +set enable_indexonlyscan = off +-- +STMT: VariableSetStmt +== 313 +prepare ab_q1 (int, int, int) as +select * from ab where a between $1 and $2 and b <= $3 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 314 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2, 3) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 315 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (1, 2, 3) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 316 +deallocate ab_q1 +-- +STMT: DeallocateStmt +== 317 +-- Runtime pruning after optimizer pruning +prepare ab_q1 (int, int) as +select a from ab where a between $1 and $2 and b < 3 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 318 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 319 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 4) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 320 +-- Ensure a mix of PARAM_EXTERN and PARAM_EXEC Params work together at +-- different levels of partitioning. +prepare ab_q2 (int, int) as +select a from ab where a between $1 and $2 and b < (select 3) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 321 +explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 322 +-- As above, but swap the PARAM_EXEC Param to the first partition level +prepare ab_q3 (int, int) as +select a from ab where b between $1 and $2 and a < (select 3) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +== 323 +explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 324 +|-- +-- Test runtime pruning with hash partitioned tables +|-- + +-- recreate partitions dropped above +create table hp1 partition of hp for values with (modulus 4, remainder 1) +-- +TABLE: name="hp1" schema="" table="hp1" ctx=DDL +STMT: CreateStmt +== 325 +create table hp2 partition of hp for values with (modulus 4, remainder 2) +-- +TABLE: name="hp2" schema="" table="hp2" ctx=DDL +STMT: CreateStmt +== 326 +create table hp3 partition of hp for values with (modulus 4, remainder 3) +-- +TABLE: name="hp3" schema="" table="hp3" ctx=DDL +STMT: CreateStmt +== 327 +-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual +prepare hp_q1 (text) as +select * from hp where a is null and b = $1 +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 328 +explain (costs off) execute hp_q1('xxx') +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 329 +deallocate hp_q1 +-- +STMT: DeallocateStmt +== 330 +drop table hp +-- +TABLE: name="hp" schema="" table="hp" ctx=DDL +STMT: DropStmt +== 331 +-- Test a backwards Append scan +create table list_part (a int) partition by list (a) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=DDL +STMT: CreateStmt +== 332 +create table list_part1 partition of list_part for values in (1) +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DDL +STMT: CreateStmt +== 333 +create table list_part2 partition of list_part for values in (2) +-- +TABLE: name="list_part2" schema="" table="list_part2" ctx=DDL +STMT: CreateStmt +== 334 +create table list_part3 partition of list_part for values in (3) +-- +TABLE: name="list_part3" schema="" table="list_part3" ctx=DDL +STMT: CreateStmt +== 335 +create table list_part4 partition of list_part for values in (4) +-- +TABLE: name="list_part4" schema="" table="list_part4" ctx=DDL +STMT: CreateStmt +== 336 +insert into list_part select generate_series(1,4) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 337 +begin +-- +STMT: TransactionStmt +== 338 +-- Don't select an actual value out of the table as the order of the Append's +-- subnodes may not be stable. +declare cur SCROLL CURSOR for select 1 from list_part where a > (select 1) and a < (select 4) +-- +STMT: DeclareCursorStmt +== 339 +-- move beyond the final row +move 3 from cur +-- +STMT: FetchStmt +== 340 +-- Ensure we get two rows. +fetch backward all from cur +-- +STMT: FetchStmt +== 341 +commit +-- +STMT: TransactionStmt +== 342 +begin +-- +STMT: TransactionStmt +== 343 +-- Test run-time pruning using stable functions +create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable +-- +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 344 +-- Ensure pruning works using a stable function containing no Vars +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=Select +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 345 +-- Ensure pruning does not take place when the function has a Var parameter +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(a) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=Select +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 346 +-- Ensure pruning does not take place when the expression contains a Var. +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) + a +-- +TABLE: name="list_part" schema="" table="list_part" ctx=Select +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 347 +rollback +-- +STMT: TransactionStmt +== 348 +drop table list_part +-- +TABLE: name="list_part" schema="" table="list_part" ctx=DDL +STMT: DropStmt +== 349 +-- Parallel append + +-- Parallel queries won't necessarily get as many workers as the planner +-- asked for. This affects not only the "Workers Launched:" field of EXPLAIN +-- results, but also row counts and loop counts for parallel scans, Gathers, +-- and everything in between. This function filters out the values we can't +-- rely on to be stable. +-- This removes enough info that you might wonder why bother with EXPLAIN +-- ANALYZE at all. The answer is that we need to see '(never executed)' +-- notations because that's the only way to verify runtime pruning. +create function explain_parallel_append(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + $1) + loop + ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N'); + ln := regexp_replace(ln, 'actual rows=\d+ loops=\d+', 'actual rows=N loops=N'); + ln := regexp_replace(ln, 'Rows Removed by Filter: \d+', 'Rows Removed by Filter: N'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 350 +prepare ab_q4 (int, int) as +select avg(a) from ab where a between $1 and $2 and b < 4 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 351 +-- Encourage use of parallel plans +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +== 352 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +== 353 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +== 354 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +== 355 +select explain_parallel_append('execute ab_q4 (2, 2)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 356 +-- Test run-time pruning with IN lists. +prepare ab_q5 (int, int, int) as +select avg(a) from ab where a in($1,$2,$3) and b < 4 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 357 +select explain_parallel_append('execute ab_q5 (1, 1, 1)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 358 +select explain_parallel_append('execute ab_q5 (2, 3, 3)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 359 +-- Try some params whose values do not belong to any partition. +select explain_parallel_append('execute ab_q5 (33, 44, 55)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 360 +-- Test Parallel Append with PARAM_EXEC Params +select explain_parallel_append('select count(*) from ab where (a = (select 1) or a = (select 3)) and b = 2') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 361 +-- Test pruning during parallel nested loop query +create table lprt_a (a int not null) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DDL +STMT: CreateStmt +== 362 +-- Insert some values we won't find in ab +insert into lprt_a select 0 from generate_series(1,100) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 363 +-- and insert some values that we should find. +insert into lprt_a values(1),(1) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 364 +analyze lprt_a +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DDL +STMT: VacuumStmt +== 365 +create index ab_a2_b1_a_idx on ab_a2_b1 (a) +-- +TABLE: name="ab_a2_b1" schema="" table="ab_a2_b1" ctx=DDL +STMT: IndexStmt +== 366 +create index ab_a2_b2_a_idx on ab_a2_b2 (a) +-- +TABLE: name="ab_a2_b2" schema="" table="ab_a2_b2" ctx=DDL +STMT: IndexStmt +== 367 +create index ab_a2_b3_a_idx on ab_a2_b3 (a) +-- +TABLE: name="ab_a2_b3" schema="" table="ab_a2_b3" ctx=DDL +STMT: IndexStmt +== 368 +create index ab_a1_b1_a_idx on ab_a1_b1 (a) +-- +TABLE: name="ab_a1_b1" schema="" table="ab_a1_b1" ctx=DDL +STMT: IndexStmt +== 369 +create index ab_a1_b2_a_idx on ab_a1_b2 (a) +-- +TABLE: name="ab_a1_b2" schema="" table="ab_a1_b2" ctx=DDL +STMT: IndexStmt +== 370 +create index ab_a1_b3_a_idx on ab_a1_b3 (a) +-- +TABLE: name="ab_a1_b3" schema="" table="ab_a1_b3" ctx=DDL +STMT: IndexStmt +== 371 +create index ab_a3_b1_a_idx on ab_a3_b1 (a) +-- +TABLE: name="ab_a3_b1" schema="" table="ab_a3_b1" ctx=DDL +STMT: IndexStmt +== 372 +create index ab_a3_b2_a_idx on ab_a3_b2 (a) +-- +TABLE: name="ab_a3_b2" schema="" table="ab_a3_b2" ctx=DDL +STMT: IndexStmt +== 373 +create index ab_a3_b3_a_idx on ab_a3_b3 (a) +-- +TABLE: name="ab_a3_b3" schema="" table="ab_a3_b3" ctx=DDL +STMT: IndexStmt +== 374 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +== 375 +set enable_mergejoin = 0 +-- +STMT: VariableSetStmt +== 376 +set enable_memoize = 0 +-- +STMT: VariableSetStmt +== 377 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(0, 0, 1)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 378 +-- Ensure the same partitions are pruned when we make the nested loop +-- parameter an Expr rather than a plain Param. +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a + 0 where a.a in(0, 0, 1)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 379 +insert into lprt_a values(3),(3) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 380 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 3)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 381 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 382 +delete from lprt_a where a = 1 +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +STMT: DeleteStmt +== 383 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 384 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 385 +reset enable_mergejoin +-- +STMT: VariableSetStmt +== 386 +reset enable_memoize +-- +STMT: VariableSetStmt +== 387 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +== 388 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +== 389 +reset min_parallel_table_scan_size +-- +STMT: VariableSetStmt +== 390 +reset max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +== 391 +-- Test run-time partition pruning with an initplan +explain (analyze, costs off, summary off, timing off) +select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=Select +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 392 +-- Test run-time partition pruning with UNION ALL parents +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 393 +-- A case containing a UNION ALL with a non-partitioned child. +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 394 +-- Another UNION ALL test, but containing a mix of exec init and exec run-time pruning. +create table xy_1 (x int, y int) +-- +TABLE: name="xy_1" schema="" table="xy_1" ctx=DDL +STMT: CreateStmt +== 395 +insert into xy_1 values(100,-10) +-- +TABLE: name="xy_1" schema="" table="xy_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 396 +set enable_bitmapscan = 0 +-- +STMT: VariableSetStmt +== 397 +set enable_indexscan = 0 +-- +STMT: VariableSetStmt +== 398 +prepare ab_q6 as +select * from ( + select tableoid::regclass,a,b from ab +union all + select tableoid::regclass,x,y from xy_1 +union all + select tableoid::regclass,a,b from ab +) ab where a = $1 and b = (select -10) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="xy_1" schema="" table="xy_1" ctx=Select +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 399 +-- Ensure the xy_1 subplan is not pruned. +explain (analyze, costs off, summary off, timing off) execute ab_q6(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 400 +-- Ensure we see just the xy_1 row. +execute ab_q6(100) +-- +STMT: ExecuteStmt +== 401 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 402 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 403 +deallocate ab_q1 +-- +STMT: DeallocateStmt +== 404 +deallocate ab_q2 +-- +STMT: DeallocateStmt +== 405 +deallocate ab_q3 +-- +STMT: DeallocateStmt +== 406 +deallocate ab_q4 +-- +STMT: DeallocateStmt +== 407 +deallocate ab_q5 +-- +STMT: DeallocateStmt +== 408 +deallocate ab_q6 +-- +STMT: DeallocateStmt +== 409 +-- UPDATE on a partition subtree has been seen to have problems. +insert into ab values (1,2) +-- +TABLE: name="ab" schema="" table="ab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 410 +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab where ab.a = 1 and ab.a = ab_a1.a +-- +TABLE: name="ab_a1" schema="" table="ab_a1" ctx=DML +TABLE: name="ab" schema="" table="ab" ctx=Select +STMT: ExplainStmt +STMT: UpdateStmt +== 411 +table ab +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +STMT: SelectStmt +== 412 +-- Test UPDATE where source relation has run-time pruning enabled +truncate ab +-- +TABLE: name="ab" schema="" table="ab" ctx=DDL +STMT: TruncateStmt +== 413 +insert into ab values (1, 1), (1, 2), (1, 3), (2, 1) +-- +TABLE: name="ab" schema="" table="ab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 414 +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab_a2 where ab_a2.b = (select 1) +-- +TABLE: name="ab_a1" schema="" table="ab_a1" ctx=DML +TABLE: name="ab_a2" schema="" table="ab_a2" ctx=Select +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +== 415 +select tableoid::regclass, * from ab +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +STMT: SelectStmt +== 416 +drop table ab, lprt_a +-- +TABLE: name="ab" schema="" table="ab" ctx=DDL +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DDL +STMT: DropStmt +== 417 +-- Join +create table tbl1(col1 int) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DDL +STMT: CreateStmt +== 418 +insert into tbl1 values (501), (505) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 419 +-- Basic table +create table tprt (col1 int) partition by range (col1) +-- +TABLE: name="tprt" schema="" table="tprt" ctx=DDL +STMT: CreateStmt +== 420 +create table tprt_1 partition of tprt for values from (1) to (501) +-- +TABLE: name="tprt_1" schema="" table="tprt_1" ctx=DDL +STMT: CreateStmt +== 421 +create table tprt_2 partition of tprt for values from (501) to (1001) +-- +TABLE: name="tprt_2" schema="" table="tprt_2" ctx=DDL +STMT: CreateStmt +== 422 +create table tprt_3 partition of tprt for values from (1001) to (2001) +-- +TABLE: name="tprt_3" schema="" table="tprt_3" ctx=DDL +STMT: CreateStmt +== 423 +create table tprt_4 partition of tprt for values from (2001) to (3001) +-- +TABLE: name="tprt_4" schema="" table="tprt_4" ctx=DDL +STMT: CreateStmt +== 424 +create table tprt_5 partition of tprt for values from (3001) to (4001) +-- +TABLE: name="tprt_5" schema="" table="tprt_5" ctx=DDL +STMT: CreateStmt +== 425 +create table tprt_6 partition of tprt for values from (4001) to (5001) +-- +TABLE: name="tprt_6" schema="" table="tprt_6" ctx=DDL +STMT: CreateStmt +== 426 +create index tprt1_idx on tprt_1 (col1) +-- +TABLE: name="tprt_1" schema="" table="tprt_1" ctx=DDL +STMT: IndexStmt +== 427 +create index tprt2_idx on tprt_2 (col1) +-- +TABLE: name="tprt_2" schema="" table="tprt_2" ctx=DDL +STMT: IndexStmt +== 428 +create index tprt3_idx on tprt_3 (col1) +-- +TABLE: name="tprt_3" schema="" table="tprt_3" ctx=DDL +STMT: IndexStmt +== 429 +create index tprt4_idx on tprt_4 (col1) +-- +TABLE: name="tprt_4" schema="" table="tprt_4" ctx=DDL +STMT: IndexStmt +== 430 +create index tprt5_idx on tprt_5 (col1) +-- +TABLE: name="tprt_5" schema="" table="tprt_5" ctx=DDL +STMT: IndexStmt +== 431 +create index tprt6_idx on tprt_6 (col1) +-- +TABLE: name="tprt_6" schema="" table="tprt_6" ctx=DDL +STMT: IndexStmt +== 432 +insert into tprt values (10), (20), (501), (502), (505), (1001), (4500) +-- +TABLE: name="tprt" schema="" table="tprt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 433 +set enable_hashjoin = off +-- +STMT: VariableSetStmt +== 434 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +== 435 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 > tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 436 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 = tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 437 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 > tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +== 438 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +== 439 +-- Multiple partitions +insert into tbl1 values (1001), (1010), (1011) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 440 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 441 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 442 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 > tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +== 443 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +== 444 +-- Last partition +delete from tbl1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: DeleteStmt +== 445 +insert into tbl1 values (4400) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 446 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 < tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 447 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 < tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +== 448 +-- No matching partition +delete from tbl1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: DeleteStmt +== 449 +insert into tbl1 values (10000) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 450 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 = tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 451 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +== 452 +drop table tbl1, tprt +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DDL +TABLE: name="tprt" schema="" table="tprt" ctx=DDL +STMT: DropStmt +== 453 +-- Test with columns defined in varying orders between each level +create table part_abc (a int not null, b int not null, c int not null) partition by list (a) +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=DDL +STMT: CreateStmt +== 454 +create table part_bac (b int not null, a int not null, c int not null) partition by list (b) +-- +TABLE: name="part_bac" schema="" table="part_bac" ctx=DDL +STMT: CreateStmt +== 455 +create table part_cab (c int not null, a int not null, b int not null) partition by list (c) +-- +TABLE: name="part_cab" schema="" table="part_cab" ctx=DDL +STMT: CreateStmt +== 456 +create table part_abc_p1 (a int not null, b int not null, c int not null) +-- +TABLE: name="part_abc_p1" schema="" table="part_abc_p1" ctx=DDL +STMT: CreateStmt +== 457 +alter table part_abc attach partition part_bac for values in(1) +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=DDL +STMT: AlterTableStmt +== 458 +alter table part_bac attach partition part_cab for values in(2) +-- +TABLE: name="part_bac" schema="" table="part_bac" ctx=DDL +STMT: AlterTableStmt +== 459 +alter table part_cab attach partition part_abc_p1 for values in(3) +-- +TABLE: name="part_cab" schema="" table="part_cab" ctx=DDL +STMT: AlterTableStmt +== 460 +prepare part_abc_q1 (int, int, int) as +select * from part_abc where a = $1 and b = $2 and c = $3 +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: PrepareStmt +STMT: SelectStmt +== 461 +-- Single partition should be scanned. +explain (analyze, costs off, summary off, timing off) execute part_abc_q1 (1, 2, 3) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 462 +deallocate part_abc_q1 +-- +STMT: DeallocateStmt +== 463 +drop table part_abc +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=DDL +STMT: DropStmt +== 464 +-- Ensure that an Append node properly handles a sub-partitioned table +-- matching without any of its leaf partitions matching the clause. +create table listp (a int, b int) partition by list (a) +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: CreateStmt +== 465 +create table listp_1 partition of listp for values in(1) partition by list (b) +-- +TABLE: name="listp_1" schema="" table="listp_1" ctx=DDL +STMT: CreateStmt +== 466 +create table listp_1_1 partition of listp_1 for values in(1) +-- +TABLE: name="listp_1_1" schema="" table="listp_1_1" ctx=DDL +STMT: CreateStmt +== 467 +create table listp_2 partition of listp for values in(2) partition by list (b) +-- +TABLE: name="listp_2" schema="" table="listp_2" ctx=DDL +STMT: CreateStmt +== 468 +create table listp_2_1 partition of listp_2 for values in(2) +-- +TABLE: name="listp_2_1" schema="" table="listp_2_1" ctx=DDL +STMT: CreateStmt +== 469 +select * from listp where b = 1 +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 470 +-- Ensure that an Append node properly can handle selection of all first level +-- partitions before finally detecting the correct set of 2nd level partitions +-- which match the given parameter. +prepare q1 (int,int) as select * from listp where b in ($1,$2) +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 471 +explain (analyze, costs off, summary off, timing off) execute q1 (1,1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 472 +explain (analyze, costs off, summary off, timing off) execute q1 (2,2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 473 +-- Try with no matching partitions. +explain (analyze, costs off, summary off, timing off) execute q1 (0,0) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 474 +deallocate q1 +-- +STMT: DeallocateStmt +== 475 +-- Test more complex cases where a not-equal condition further eliminates partitions. +prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 476 +-- Both partitions allowed by IN clause, but one disallowed by <> clause +explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 477 +-- Both partitions allowed by IN clause, then both excluded again by <> clauses. +explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 478 +-- Ensure Params that evaluate to NULL properly prune away all partitions +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select null::int) +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 479 +drop table listp +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: DropStmt +== 480 +|-- +-- check that stable query clauses are only used in run-time pruning +|-- +create table stable_qual_pruning (a timestamp) partition by range (a) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=DDL +STMT: CreateStmt +== 481 +create table stable_qual_pruning1 partition of stable_qual_pruning + for values from ('2000-01-01') to ('2000-02-01') +-- +TABLE: name="stable_qual_pruning1" schema="" table="stable_qual_pruning1" ctx=DDL +STMT: CreateStmt +== 482 +create table stable_qual_pruning2 partition of stable_qual_pruning + for values from ('2000-02-01') to ('2000-03-01') +-- +TABLE: name="stable_qual_pruning2" schema="" table="stable_qual_pruning2" ctx=DDL +STMT: CreateStmt +== 483 +create table stable_qual_pruning3 partition of stable_qual_pruning + for values from ('3000-02-01') to ('3000-03-01') +-- +TABLE: name="stable_qual_pruning3" schema="" table="stable_qual_pruning3" ctx=DDL +STMT: CreateStmt +== 484 +-- comparison against a stable value requires run-time pruning +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < localtimestamp +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 485 +-- timestamp < timestamptz comparison is only stable, not immutable +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < '2000-02-01'::timestamptz +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 486 +-- check ScalarArrayOp cases +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamp[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 487 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamp[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 488 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', localtimestamp]::timestamp[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 489 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 490 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 491 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(null::timestamptz[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 492 +drop table stable_qual_pruning +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=DDL +STMT: DropStmt +== 493 +|-- +-- Check that pruning with composite range partitioning works correctly when +-- it must ignore clauses for trailing keys once it has seen a clause with +-- non-inclusive operator for an earlier key +|-- +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +STMT: CreateStmt +== 494 +create table mc3p0 partition of mc3p + for values from (0, 0, 0) to (0, maxvalue, maxvalue) +-- +TABLE: name="mc3p0" schema="" table="mc3p0" ctx=DDL +STMT: CreateStmt +== 495 +create table mc3p1 partition of mc3p + for values from (1, 1, 1) to (2, minvalue, minvalue) +-- +TABLE: name="mc3p1" schema="" table="mc3p1" ctx=DDL +STMT: CreateStmt +== 496 +create table mc3p2 partition of mc3p + for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue) +-- +TABLE: name="mc3p2" schema="" table="mc3p2" ctx=DDL +STMT: CreateStmt +== 497 +insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 498 +explain (analyze, costs off, summary off, timing off) +select * from mc3p where a < 3 and abs(b) = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 499 +|-- +-- Check that pruning with composite range partitioning works correctly when +-- a combination of runtime parameters is specified, not all of whose values +-- are available at the same time +|-- +prepare ps1 as + select * from mc3p where a = $1 and abs(b) < (select 3) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 500 +explain (analyze, costs off, summary off, timing off) +execute ps1(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 501 +deallocate ps1 +-- +STMT: DeallocateStmt +== 502 +prepare ps2 as + select * from mc3p where a <= $1 and abs(b) < (select 3) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 503 +explain (analyze, costs off, summary off, timing off) +execute ps2(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 504 +deallocate ps2 +-- +STMT: DeallocateStmt +== 505 +drop table mc3p +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +STMT: DropStmt +== 506 +-- Ensure runtime pruning works with initplans params with boolean types +create table boolvalues (value bool not null) +-- +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=DDL +STMT: CreateStmt +== 507 +insert into boolvalues values('t'),('f') +-- +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 508 +create table boolp (a bool) partition by list (a) +-- +TABLE: name="boolp" schema="" table="boolp" ctx=DDL +STMT: CreateStmt +== 509 +create table boolp_t partition of boolp for values in('t') +-- +TABLE: name="boolp_t" schema="" table="boolp_t" ctx=DDL +STMT: CreateStmt +== 510 +create table boolp_f partition of boolp for values in('f') +-- +TABLE: name="boolp_f" schema="" table="boolp_f" ctx=DDL +STMT: CreateStmt +== 511 +explain (analyze, costs off, summary off, timing off) +select * from boolp where a = (select value from boolvalues where value) +-- +TABLE: name="boolp" schema="" table="boolp" ctx=Select +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="value" +STMT: ExplainStmt +STMT: SelectStmt +== 512 +explain (analyze, costs off, summary off, timing off) +select * from boolp where a = (select value from boolvalues where not value) +-- +TABLE: name="boolp" schema="" table="boolp" ctx=Select +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="value" +STMT: ExplainStmt +STMT: SelectStmt +== 513 +drop table boolp +-- +TABLE: name="boolp" schema="" table="boolp" ctx=DDL +STMT: DropStmt +== 514 +|-- +-- Test run-time pruning of MergeAppend subnodes +|-- +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 515 +set enable_sort = off +-- +STMT: VariableSetStmt +== 516 +create table ma_test (a int, b int) partition by range (a) +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: CreateStmt +== 517 +create table ma_test_p1 partition of ma_test for values from (0) to (10) +-- +TABLE: name="ma_test_p1" schema="" table="ma_test_p1" ctx=DDL +STMT: CreateStmt +== 518 +create table ma_test_p2 partition of ma_test for values from (10) to (20) +-- +TABLE: name="ma_test_p2" schema="" table="ma_test_p2" ctx=DDL +STMT: CreateStmt +== 519 +create table ma_test_p3 partition of ma_test for values from (20) to (30) +-- +TABLE: name="ma_test_p3" schema="" table="ma_test_p3" ctx=DDL +STMT: CreateStmt +== 520 +insert into ma_test select x,x from generate_series(0,29) t(x) +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 521 +create index on ma_test (b) +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: IndexStmt +== 522 +analyze ma_test +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: VacuumStmt +== 523 +prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +== 524 +explain (analyze, costs off, summary off, timing off) execute mt_q1(15) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 525 +execute mt_q1(15) +-- +STMT: ExecuteStmt +== 526 +explain (analyze, costs off, summary off, timing off) execute mt_q1(25) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 527 +execute mt_q1(25) +-- +STMT: ExecuteStmt +== 528 +-- Ensure MergeAppend behaves correctly when no subplans match +explain (analyze, costs off, summary off, timing off) execute mt_q1(35) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 529 +execute mt_q1(35) +-- +STMT: ExecuteStmt +== 530 +deallocate mt_q1 +-- +STMT: DeallocateStmt +== 531 +prepare mt_q2 (int) as select * from ma_test where a >= $1 order by b limit 1 +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +== 532 +-- Ensure output list looks sane when the MergeAppend has no subplans. +explain (analyze, verbose, costs off, summary off, timing off) execute mt_q2 (35) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 533 +deallocate mt_q2 +-- +STMT: DeallocateStmt +== 534 +-- ensure initplan params properly prune partitions +explain (analyze, costs off, summary off, timing off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=Select +TABLE: name="ma_test_p2" schema="" table="ma_test_p2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 535 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 536 +reset enable_sort +-- +STMT: VariableSetStmt +== 537 +drop table ma_test +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: DropStmt +== 538 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +== 539 +|-- +-- check that pruning works properly when the partition key is of a +-- pseudotype +|-- + +-- array type list partition key +create table pp_arrpart (a int[]) partition by list (a) +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DDL +STMT: CreateStmt +== 540 +create table pp_arrpart1 partition of pp_arrpart for values in ('{1}') +-- +TABLE: name="pp_arrpart1" schema="" table="pp_arrpart1" ctx=DDL +STMT: CreateStmt +== 541 +create table pp_arrpart2 partition of pp_arrpart for values in ('{2, 3}', '{4, 5}') +-- +TABLE: name="pp_arrpart2" schema="" table="pp_arrpart2" ctx=DDL +STMT: CreateStmt +== 542 +explain (costs off) select * from pp_arrpart where a = '{1}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 543 +explain (costs off) select * from pp_arrpart where a = '{1, 2}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 544 +explain (costs off) select * from pp_arrpart where a in ('{4, 5}', '{1}') +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 545 +explain (costs off) update pp_arrpart set a = a where a = '{1}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 546 +explain (costs off) delete from pp_arrpart where a = '{1}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 547 +drop table pp_arrpart +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DDL +STMT: DropStmt +== 548 +-- array type hash partition key +create table pph_arrpart (a int[]) partition by hash (a) +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=DDL +STMT: CreateStmt +== 549 +create table pph_arrpart1 partition of pph_arrpart for values with (modulus 2, remainder 0) +-- +TABLE: name="pph_arrpart1" schema="" table="pph_arrpart1" ctx=DDL +STMT: CreateStmt +== 550 +create table pph_arrpart2 partition of pph_arrpart for values with (modulus 2, remainder 1) +-- +TABLE: name="pph_arrpart2" schema="" table="pph_arrpart2" ctx=DDL +STMT: CreateStmt +== 551 +insert into pph_arrpart values ('{1}'), ('{1, 2}'), ('{4, 5}') +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 552 +select tableoid::regclass, * from pph_arrpart order by 1 +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +STMT: SelectStmt +== 553 +explain (costs off) select * from pph_arrpart where a = '{1}' +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 554 +explain (costs off) select * from pph_arrpart where a = '{1, 2}' +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 555 +explain (costs off) select * from pph_arrpart where a in ('{4, 5}', '{1}') +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 556 +drop table pph_arrpart +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=DDL +STMT: DropStmt +== 557 +-- enum type list partition key +create type pp_colors as enum ('green', 'blue', 'black') +-- +STMT: CreateEnumStmt +== 558 +create table pp_enumpart (a pp_colors) partition by list (a) +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=DDL +STMT: CreateStmt +== 559 +create table pp_enumpart_green partition of pp_enumpart for values in ('green') +-- +TABLE: name="pp_enumpart_green" schema="" table="pp_enumpart_green" ctx=DDL +STMT: CreateStmt +== 560 +create table pp_enumpart_blue partition of pp_enumpart for values in ('blue') +-- +TABLE: name="pp_enumpart_blue" schema="" table="pp_enumpart_blue" ctx=DDL +STMT: CreateStmt +== 561 +explain (costs off) select * from pp_enumpart where a = 'blue' +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 562 +explain (costs off) select * from pp_enumpart where a = 'black' +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 563 +drop table pp_enumpart +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=DDL +STMT: DropStmt +== 564 +drop type pp_colors +-- +STMT: DropStmt +== 565 +-- record type as partition key +create type pp_rectype as (a int, b int) +-- +STMT: CompositeTypeStmt +== 566 +create table pp_recpart (a pp_rectype) partition by list (a) +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=DDL +STMT: CreateStmt +== 567 +create table pp_recpart_11 partition of pp_recpart for values in ('(1,1)') +-- +TABLE: name="pp_recpart_11" schema="" table="pp_recpart_11" ctx=DDL +STMT: CreateStmt +== 568 +create table pp_recpart_23 partition of pp_recpart for values in ('(2,3)') +-- +TABLE: name="pp_recpart_23" schema="" table="pp_recpart_23" ctx=DDL +STMT: CreateStmt +== 569 +explain (costs off) select * from pp_recpart where a = '(1,1)'::pp_rectype +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 570 +explain (costs off) select * from pp_recpart where a = '(1,2)'::pp_rectype +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 571 +drop table pp_recpart +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=DDL +STMT: DropStmt +== 572 +drop type pp_rectype +-- +STMT: DropStmt +== 573 +-- range type partition key +create table pp_intrangepart (a int4range) partition by list (a) +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=DDL +STMT: CreateStmt +== 574 +create table pp_intrangepart12 partition of pp_intrangepart for values in ('[1,2]') +-- +TABLE: name="pp_intrangepart12" schema="" table="pp_intrangepart12" ctx=DDL +STMT: CreateStmt +== 575 +create table pp_intrangepart2inf partition of pp_intrangepart for values in ('[2,)') +-- +TABLE: name="pp_intrangepart2inf" schema="" table="pp_intrangepart2inf" ctx=DDL +STMT: CreateStmt +== 576 +explain (costs off) select * from pp_intrangepart where a = '[1,2]'::int4range +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 577 +explain (costs off) select * from pp_intrangepart where a = '(1,2)'::int4range +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 578 +drop table pp_intrangepart +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=DDL +STMT: DropStmt +== 579 +|-- +-- Ensure the enable_partition_prune GUC properly disables partition pruning. +|-- + +create table pp_lp (a int, value int) partition by list (a) +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DDL +STMT: CreateStmt +== 580 +create table pp_lp1 partition of pp_lp for values in(1) +-- +TABLE: name="pp_lp1" schema="" table="pp_lp1" ctx=DDL +STMT: CreateStmt +== 581 +create table pp_lp2 partition of pp_lp for values in(2) +-- +TABLE: name="pp_lp2" schema="" table="pp_lp2" ctx=DDL +STMT: CreateStmt +== 582 +explain (costs off) select * from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 583 +explain (costs off) update pp_lp set value = 10 where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 584 +explain (costs off) delete from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 585 +set enable_partition_pruning = off +-- +STMT: VariableSetStmt +== 586 +set constraint_exclusion = 'partition' +-- +STMT: VariableSetStmt +== 587 +-- this should not affect the result. + +explain (costs off) select * from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 588 +explain (costs off) update pp_lp set value = 10 where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 589 +explain (costs off) delete from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 590 +set constraint_exclusion = 'off' +-- +STMT: VariableSetStmt +== 591 +-- this should not affect the result. + +explain (costs off) select * from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 592 +explain (costs off) update pp_lp set value = 10 where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 593 +explain (costs off) delete from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 594 +drop table pp_lp +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DDL +STMT: DropStmt +== 595 +-- Ensure enable_partition_prune does not affect non-partitioned tables. + +create table inh_lp (a int, value int) +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DDL +STMT: CreateStmt +== 596 +create table inh_lp1 (a int, value int, check(a = 1)) inherits (inh_lp) +-- +TABLE: name="inh_lp1" schema="" table="inh_lp1" ctx=DDL +STMT: CreateStmt +== 597 +create table inh_lp2 (a int, value int, check(a = 2)) inherits (inh_lp) +-- +TABLE: name="inh_lp2" schema="" table="inh_lp2" ctx=DDL +STMT: CreateStmt +== 598 +set constraint_exclusion = 'partition' +-- +STMT: VariableSetStmt +== 599 +-- inh_lp2 should be removed in the following 3 cases. +explain (costs off) select * from inh_lp where a = 1 +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 600 +explain (costs off) update inh_lp set value = 10 where a = 1 +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 601 +explain (costs off) delete from inh_lp where a = 1 +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 602 +-- Ensure we don't exclude normal relations when we only expect to exclude +-- inheritance children +explain (costs off) update inh_lp1 set value = 10 where a = 2 +-- +TABLE: name="inh_lp1" schema="" table="inh_lp1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 603 +drop table inh_lp cascade +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DDL +STMT: DropStmt +== 604 +reset enable_partition_pruning +-- +STMT: VariableSetStmt +== 605 +reset constraint_exclusion +-- +STMT: VariableSetStmt +== 606 +-- Check pruning for a partition tree containing only temporary relations +create temp table pp_temp_parent (a int) partition by list (a) +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=DDL +STMT: CreateStmt +== 607 +create temp table pp_temp_part_1 partition of pp_temp_parent for values in (1) +-- +TABLE: name="pp_temp_part_1" schema="" table="pp_temp_part_1" ctx=DDL +STMT: CreateStmt +== 608 +create temp table pp_temp_part_def partition of pp_temp_parent default +-- +TABLE: name="pp_temp_part_def" schema="" table="pp_temp_part_def" ctx=DDL +STMT: CreateStmt +== 609 +explain (costs off) select * from pp_temp_parent where true +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 610 +explain (costs off) select * from pp_temp_parent where a = 2 +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 611 +drop table pp_temp_parent +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=DDL +STMT: DropStmt +== 612 +-- Stress run-time partition pruning a bit more, per bug reports +create temp table p (a int, b int, c int) partition by list (a) +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: CreateStmt +== 613 +create temp table p1 partition of p for values in (1) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +== 614 +create temp table p2 partition of p for values in (2) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +== 615 +create temp table q (a int, b int, c int) partition by list (a) +-- +TABLE: name="q" schema="" table="q" ctx=DDL +STMT: CreateStmt +== 616 +create temp table q1 partition of q for values in (1) partition by list (b) +-- +TABLE: name="q1" schema="" table="q1" ctx=DDL +STMT: CreateStmt +== 617 +create temp table q11 partition of q1 for values in (1) partition by list (c) +-- +TABLE: name="q11" schema="" table="q11" ctx=DDL +STMT: CreateStmt +== 618 +create temp table q111 partition of q11 for values in (1) +-- +TABLE: name="q111" schema="" table="q111" ctx=DDL +STMT: CreateStmt +== 619 +create temp table q2 partition of q for values in (2) partition by list (b) +-- +TABLE: name="q2" schema="" table="q2" ctx=DDL +STMT: CreateStmt +== 620 +create temp table q21 partition of q2 for values in (1) +-- +TABLE: name="q21" schema="" table="q21" ctx=DDL +STMT: CreateStmt +== 621 +create temp table q22 partition of q2 for values in (2) +-- +TABLE: name="q22" schema="" table="q22" ctx=DDL +STMT: CreateStmt +== 622 +insert into q22 values (2, 2, 3) +-- +TABLE: name="q22" schema="" table="q22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 623 +explain (costs off) +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1) +-- +TABLE: name="p" schema="" table="p" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 624 +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1) +-- +TABLE: name="p" schema="" table="p" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="s" column="c" +STMT: SelectStmt +== 625 +prepare q (int, int) as +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = $1 and s.b = $2 and s.c = (select 1) +-- +TABLE: name="p" schema="" table="p" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="s" column="c" +STMT: PrepareStmt +STMT: SelectStmt +== 626 +explain (costs off) execute q (1, 1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 627 +execute q (1, 1) +-- +STMT: ExecuteStmt +== 628 +drop table p, q +-- +TABLE: name="p" schema="" table="p" ctx=DDL +TABLE: name="q" schema="" table="q" ctx=DDL +STMT: DropStmt +== 629 +-- Ensure run-time pruning works correctly when we match a partitioned table +-- on the first level but find no matching partitions on the second level. +create table listp (a int, b int) partition by list (a) +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: CreateStmt +== 630 +create table listp1 partition of listp for values in(1) +-- +TABLE: name="listp1" schema="" table="listp1" ctx=DDL +STMT: CreateStmt +== 631 +create table listp2 partition of listp for values in(2) partition by list(b) +-- +TABLE: name="listp2" schema="" table="listp2" ctx=DDL +STMT: CreateStmt +== 632 +create table listp2_10 partition of listp2 for values in (10) +-- +TABLE: name="listp2_10" schema="" table="listp2_10" ctx=DDL +STMT: CreateStmt +== 633 +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select 2) and b <> 10 +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 634 +|-- +-- check that a partition directly accessed in a query is excluded with +-- constraint_exclusion = on +|-- + +-- turn off partition pruning, so that it doesn't interfere +set enable_partition_pruning to off +-- +STMT: VariableSetStmt +== 635 +-- setting constraint_exclusion to 'partition' disables exclusion +set constraint_exclusion to 'partition' +-- +STMT: VariableSetStmt +== 636 +explain (costs off) select * from listp1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 637 +explain (costs off) update listp1 set a = 1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 638 +-- constraint exclusion enabled +set constraint_exclusion to 'on' +-- +STMT: VariableSetStmt +== 639 +explain (costs off) select * from listp1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 640 +explain (costs off) update listp1 set a = 1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 641 +reset constraint_exclusion +-- +STMT: VariableSetStmt +== 642 +reset enable_partition_pruning +-- +STMT: VariableSetStmt +== 643 +drop table listp +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: DropStmt +== 644 +-- Ensure run-time pruning works correctly for nested Append nodes +set parallel_setup_cost to 0 +-- +STMT: VariableSetStmt +== 645 +set parallel_tuple_cost to 0 +-- +STMT: VariableSetStmt +== 646 +create table listp (a int) partition by list(a) +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: CreateStmt +== 647 +create table listp_12 partition of listp for values in(1,2) partition by list(a) +-- +TABLE: name="listp_12" schema="" table="listp_12" ctx=DDL +STMT: CreateStmt +== 648 +create table listp_12_1 partition of listp_12 for values in(1) +-- +TABLE: name="listp_12_1" schema="" table="listp_12_1" ctx=DDL +STMT: CreateStmt +== 649 +create table listp_12_2 partition of listp_12 for values in(2) +-- +TABLE: name="listp_12_2" schema="" table="listp_12_2" ctx=DDL +STMT: CreateStmt +== 650 +-- Force the 2nd subnode of the Append to be non-parallel. This results in +-- a nested Append node because the mixed parallel / non-parallel paths cannot +-- be pulled into the top-level Append. +alter table listp_12_1 set (parallel_workers = 0) +-- +TABLE: name="listp_12_1" schema="" table="listp_12_1" ctx=DDL +STMT: AlterTableStmt +== 651 +-- Ensure that listp_12_2 is not scanned. (The nested Append is not seen in +-- the plan as it's pulled in setref.c due to having just a single subnode). +select explain_parallel_append('select * from listp where a = (select 1);') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 652 +-- Like the above but throw some more complexity at the planner by adding +-- a UNION ALL. We expect both sides of the union not to scan the +-- non-required partitions. +select explain_parallel_append( +'select * from listp where a = (select 1) + union all +select * from listp where a = (select 2);') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +== 653 +drop table listp +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: DropStmt +== 654 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +== 655 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +== 656 +-- Test case for run-time pruning with a nested Merge Append +set enable_sort to 0 +-- +STMT: VariableSetStmt +== 657 +create table rangep (a int, b int) partition by range (a) +-- +TABLE: name="rangep" schema="" table="rangep" ctx=DDL +STMT: CreateStmt +== 658 +create table rangep_0_to_100 partition of rangep for values from (0) to (100) partition by list (b) +-- +TABLE: name="rangep_0_to_100" schema="" table="rangep_0_to_100" ctx=DDL +STMT: CreateStmt +== 659 +-- We need 3 sub-partitions. 1 to validate pruning worked and another two +-- because a single remaining partition would be pulled up to the main Append. +create table rangep_0_to_100_1 partition of rangep_0_to_100 for values in(1) +-- +TABLE: name="rangep_0_to_100_1" schema="" table="rangep_0_to_100_1" ctx=DDL +STMT: CreateStmt +== 660 +create table rangep_0_to_100_2 partition of rangep_0_to_100 for values in(2) +-- +TABLE: name="rangep_0_to_100_2" schema="" table="rangep_0_to_100_2" ctx=DDL +STMT: CreateStmt +== 661 +create table rangep_0_to_100_3 partition of rangep_0_to_100 for values in(3) +-- +TABLE: name="rangep_0_to_100_3" schema="" table="rangep_0_to_100_3" ctx=DDL +STMT: CreateStmt +== 662 +create table rangep_100_to_200 partition of rangep for values from (100) to (200) +-- +TABLE: name="rangep_100_to_200" schema="" table="rangep_100_to_200" ctx=DDL +STMT: CreateStmt +== 663 +create index on rangep (a) +-- +TABLE: name="rangep" schema="" table="rangep" ctx=DDL +STMT: IndexStmt +== 664 +-- Ensure run-time pruning works on the nested Merge Append +explain (analyze on, costs off, timing off, summary off) +select * from rangep where b IN((select 1),(select 2)) order by a +-- +TABLE: name="rangep" schema="" table="rangep" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 665 +reset enable_sort +-- +STMT: VariableSetStmt +== 666 +drop table rangep +-- +TABLE: name="rangep" schema="" table="rangep" ctx=DDL +STMT: DropStmt +== 667 +|-- +-- Check that gen_prune_steps_from_opexps() works well for various cases of +-- clauses for different partition keys +|-- + +create table rp_prefix_test1 (a int, b varchar) partition by range(a, b) +-- +TABLE: name="rp_prefix_test1" schema="" table="rp_prefix_test1" ctx=DDL +STMT: CreateStmt +== 668 +create table rp_prefix_test1_p1 partition of rp_prefix_test1 for values from (1, 'a') to (1, 'b') +-- +TABLE: name="rp_prefix_test1_p1" schema="" table="rp_prefix_test1_p1" ctx=DDL +STMT: CreateStmt +== 669 +create table rp_prefix_test1_p2 partition of rp_prefix_test1 for values from (2, 'a') to (2, 'b') +-- +TABLE: name="rp_prefix_test1_p2" schema="" table="rp_prefix_test1_p2" ctx=DDL +STMT: CreateStmt +== 670 +-- Don't call get_steps_using_prefix() with the last partition key b plus +-- an empty prefix +explain (costs off) select * from rp_prefix_test1 where a <= 1 and b = 'a' +-- +TABLE: name="rp_prefix_test1" schema="" table="rp_prefix_test1" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 671 +create table rp_prefix_test2 (a int, b int, c int) partition by range(a, b, c) +-- +TABLE: name="rp_prefix_test2" schema="" table="rp_prefix_test2" ctx=DDL +STMT: CreateStmt +== 672 +create table rp_prefix_test2_p1 partition of rp_prefix_test2 for values from (1, 1, 0) to (1, 1, 10) +-- +TABLE: name="rp_prefix_test2_p1" schema="" table="rp_prefix_test2_p1" ctx=DDL +STMT: CreateStmt +== 673 +create table rp_prefix_test2_p2 partition of rp_prefix_test2 for values from (2, 2, 0) to (2, 2, 10) +-- +TABLE: name="rp_prefix_test2_p2" schema="" table="rp_prefix_test2_p2" ctx=DDL +STMT: CreateStmt +== 674 +-- Don't call get_steps_using_prefix() with the last partition key c plus +-- an invalid prefix (ie, b = 1) +explain (costs off) select * from rp_prefix_test2 where a <= 1 and b = 1 and c >= 0 +-- +TABLE: name="rp_prefix_test2" schema="" table="rp_prefix_test2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 675 +create table rp_prefix_test3 (a int, b int, c int, d int) partition by range(a, b, c, d) +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=DDL +STMT: CreateStmt +== 676 +create table rp_prefix_test3_p1 partition of rp_prefix_test3 for values from (1, 1, 1, 0) to (1, 1, 1, 10) +-- +TABLE: name="rp_prefix_test3_p1" schema="" table="rp_prefix_test3_p1" ctx=DDL +STMT: CreateStmt +== 677 +create table rp_prefix_test3_p2 partition of rp_prefix_test3 for values from (2, 2, 2, 0) to (2, 2, 2, 10) +-- +TABLE: name="rp_prefix_test3_p2" schema="" table="rp_prefix_test3_p2" ctx=DDL +STMT: CreateStmt +== 678 +-- Test that get_steps_using_prefix() handles a prefix that contains multiple +-- clauses for the partition key b (ie, b >= 1 and b >= 2) +explain (costs off) select * from rp_prefix_test3 where a >= 1 and b >= 1 and b >= 2 and c >= 2 and d >= 0 +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +== 679 +-- Test that get_steps_using_prefix() handles a prefix that contains multiple +-- clauses for the partition key b (ie, b >= 1 and b = 2) (This also tests +-- that the caller arranges clauses in that prefix in the required order) +explain (costs off) select * from rp_prefix_test3 where a >= 1 and b >= 1 and b = 2 and c = 2 and d >= 0 +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +== 680 +drop table rp_prefix_test1 +-- +TABLE: name="rp_prefix_test1" schema="" table="rp_prefix_test1" ctx=DDL +STMT: DropStmt +== 681 +drop table rp_prefix_test2 +-- +TABLE: name="rp_prefix_test2" schema="" table="rp_prefix_test2" ctx=DDL +STMT: DropStmt +== 682 +drop table rp_prefix_test3 +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=DDL +STMT: DropStmt +== 683 +|-- +-- Test that get_steps_using_prefix() handles IS NULL clauses correctly +|-- +create table hp_prefix_test (a int, b int, c int, d int) + partition by hash (a part_test_int4_ops, b part_test_int4_ops, c part_test_int4_ops, d part_test_int4_ops) +-- +TABLE: name="hp_prefix_test" schema="" table="hp_prefix_test" ctx=DDL +STMT: CreateStmt +== 684 +-- create 8 partitions +select 'create table hp_prefix_test_p' || x::text || ' partition of hp_prefix_test for values with (modulus 8, remainder ' || x::text || ');' +from generate_Series(0,7) x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 685 +-- insert 16 rows, one row for each test to perform. +insert into hp_prefix_test +select + case a when 0 then null else 1 end, + case b when 0 then null else 2 end, + case c when 0 then null else 3 end, + case d when 0 then null else 4 end +from + generate_series(0,1) a, + generate_series(0,1) b, + generate_Series(0,1) c, + generate_Series(0,1) d +-- +TABLE: name="hp_prefix_test" schema="" table="hp_prefix_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 686 +-- Ensure partition pruning works correctly for each combination of IS NULL +-- and equality quals. This may seem a little excessive, but there have been +-- a number of bugs in this area over the years. We make use of row only +-- output to reduce the size of the expected results. +select + 'explain (costs off) select tableoid::regclass,* from hp_prefix_test where ' || + string_agg(c.colname || case when g.s & (1 << c.colpos) = 0 then ' is null' else ' = ' || (colpos+1)::text end, ' and ' order by c.colpos) +from (values('a',0),('b',1),('c',2),('d',3)) c(colname, colpos), generate_Series(0,15) g(s) +group by g.s +order by g.s +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 687 +-- And ensure we get exactly 1 row from each. Again, all 16 possible combinations. +select + 'select tableoid::regclass,* from hp_prefix_test where ' || + string_agg(c.colname || case when g.s & (1 << c.colpos) = 0 then ' is null' else ' = ' || (colpos+1)::text end, ' and ' order by c.colpos) +from (values('a',0),('b',1),('c',2),('d',3)) c(colname, colpos), generate_Series(0,15) g(s) +group by g.s +order by g.s +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 688 +drop table hp_prefix_test +-- +TABLE: name="hp_prefix_test" schema="" table="hp_prefix_test" ctx=DDL +STMT: DropStmt +== 689 +|-- +-- Check that gen_partprune_steps() detects self-contradiction from clauses +-- regardless of the order of the clauses (Here we use a custom operator to +-- prevent the equivclass.c machinery from reordering the clauses) +|-- + +create operator === ( + leftarg = int4, + rightarg = int4, + procedure = int4eq, + commutator = ===, + hashes +) +-- +STMT: DefineStmt +== 690 +create operator class part_test_int4_ops2 +for type int4 +using hash as +operator 1 ===, +function 2 part_hashint4_noop(int4, int8) +-- +STMT: CreateOpClassStmt +== 691 +create table hp_contradict_test (a int, b int) partition by hash (a part_test_int4_ops2, b part_test_int4_ops2) +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=DDL +STMT: CreateStmt +== 692 +create table hp_contradict_test_p1 partition of hp_contradict_test for values with (modulus 2, remainder 0) +-- +TABLE: name="hp_contradict_test_p1" schema="" table="hp_contradict_test_p1" ctx=DDL +STMT: CreateStmt +== 693 +create table hp_contradict_test_p2 partition of hp_contradict_test for values with (modulus 2, remainder 1) +-- +TABLE: name="hp_contradict_test_p2" schema="" table="hp_contradict_test_p2" ctx=DDL +STMT: CreateStmt +== 694 +explain (costs off) select * from hp_contradict_test where a is null and a === 1 and b === 1 +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 695 +explain (costs off) select * from hp_contradict_test where a === 1 and b === 1 and a is null +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 696 +drop table hp_contradict_test +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=DDL +STMT: DropStmt +== 697 +drop operator class part_test_int4_ops2 using hash +-- +STMT: DropStmt +== 698 +drop operator ===(int4, int4) +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/password.metadata.json b/parser/testdata/summary/postgres_regress/password.metadata.json new file mode 100644 index 0000000..fbb3e40 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/password.metadata.json @@ -0,0 +1,55 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051" + ] +} diff --git a/parser/testdata/summary/postgres_regress/password.test b/parser/testdata/summary/postgres_regress/password.test new file mode 100644 index 0000000..7bd5f9d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/password.test @@ -0,0 +1,274 @@ +== 001 +|-- +-- Tests for password types +|-- + +-- Tests for GUC password_encryption +SET password_encryption = 'novalue' +-- +STMT: VariableSetStmt +== 002 +-- error +SET password_encryption = true +-- +STMT: VariableSetStmt +== 003 +-- error +SET password_encryption = 'md5' +-- +STMT: VariableSetStmt +== 004 +-- ok +SET password_encryption = 'scram-sha-256' +-- +STMT: VariableSetStmt +== 005 +-- ok + +-- consistency of password entries +SET password_encryption = 'md5' +-- +STMT: VariableSetStmt +== 006 +CREATE ROLE regress_passwd1 +-- +STMT: CreateRoleStmt +== 007 +ALTER ROLE regress_passwd1 PASSWORD 'role_pwd1' +-- +STMT: AlterRoleStmt +== 008 +CREATE ROLE regress_passwd2 +-- +STMT: CreateRoleStmt +== 009 +ALTER ROLE regress_passwd2 PASSWORD 'role_pwd2' +-- +STMT: AlterRoleStmt +== 010 +SET password_encryption = 'scram-sha-256' +-- +STMT: VariableSetStmt +== 011 +CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3' +-- +STMT: CreateRoleStmt +== 012 +CREATE ROLE regress_passwd4 PASSWORD NULL +-- +STMT: CreateRoleStmt +== 013 +-- check list of created entries +|-- +-- The scram secret will look something like: +-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo= +|-- +-- Since the salt is random, the exact value stored will be different on every test +-- run. Use a regular expression to mask the changing parts. +SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 014 +-- Rename a role +ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new +-- +STMT: RenameStmt +== 015 +-- md5 entry should have been removed +SELECT rolname, rolpassword + FROM pg_authid + WHERE rolname LIKE 'regress_passwd2_new' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 016 +ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2 +-- +STMT: RenameStmt +== 017 +-- Change passwords with ALTER USER. With plaintext or already-encrypted +-- passwords. +SET password_encryption = 'md5' +-- +STMT: VariableSetStmt +== 018 +-- encrypt with MD5 +ALTER ROLE regress_passwd2 PASSWORD 'foo' +-- +STMT: AlterRoleStmt +== 019 +-- already encrypted, use as they are +ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70' +-- +STMT: AlterRoleStmt +== 020 +ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=' +-- +STMT: AlterRoleStmt +== 021 +SET password_encryption = 'scram-sha-256' +-- +STMT: VariableSetStmt +== 022 +-- create SCRAM secret +ALTER ROLE regress_passwd4 PASSWORD 'foo' +-- +STMT: AlterRoleStmt +== 023 +-- already encrypted with MD5, use as it is +CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023' +-- +STMT: CreateRoleStmt +== 024 +-- This looks like a valid SCRAM-SHA-256 secret, but it is not +-- so it should be hashed with SCRAM-SHA-256. +CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234' +-- +STMT: CreateRoleStmt +== 025 +-- These may look like valid MD5 secrets, but they are not, so they +-- should be hashed with SCRAM-SHA-256. +-- trailing garbage at the end +CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz' +-- +STMT: CreateRoleStmt +== 026 +-- invalid length +CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz' +-- +STMT: CreateRoleStmt +== 027 +-- Changing the SCRAM iteration count +SET scram_iterations = 1024 +-- +STMT: VariableSetStmt +== 028 +CREATE ROLE regress_passwd9 PASSWORD 'alterediterationcount' +-- +STMT: CreateRoleStmt +== 029 +SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 030 +-- An empty password is not allowed, in any form +CREATE ROLE regress_passwd_empty PASSWORD '' +-- +STMT: CreateRoleStmt +== 031 +ALTER ROLE regress_passwd_empty PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a' +-- +STMT: AlterRoleStmt +== 032 +ALTER ROLE regress_passwd_empty PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27ZFKbZ2nV+vtnYM995pDh9ca6WSi120=:qVV5NeluNfUPkwm7Vqat25RjSPLkGeoZBQs6wVv+um4=' +-- +STMT: AlterRoleStmt +== 033 +SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 034 +-- Test with invalid stored and server keys. +|-- +-- The first is valid, to act as a control. The others have too long +-- stored/server keys. They will be re-hashed. +CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=' +-- +STMT: CreateRoleStmt +== 035 +CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=' +-- +STMT: CreateRoleStmt +== 036 +CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=' +-- +STMT: CreateRoleStmt +== 037 +-- Check that the invalid secrets were re-hashed. A re-hashed secret +-- should not contain the original salt. +SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed + FROM pg_authid + WHERE rolname LIKE 'regress_passwd_sha_len%' + ORDER BY rolname +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 038 +DROP ROLE regress_passwd1 +-- +STMT: DropRoleStmt +== 039 +DROP ROLE regress_passwd2 +-- +STMT: DropRoleStmt +== 040 +DROP ROLE regress_passwd3 +-- +STMT: DropRoleStmt +== 041 +DROP ROLE regress_passwd4 +-- +STMT: DropRoleStmt +== 042 +DROP ROLE regress_passwd5 +-- +STMT: DropRoleStmt +== 043 +DROP ROLE regress_passwd6 +-- +STMT: DropRoleStmt +== 044 +DROP ROLE regress_passwd7 +-- +STMT: DropRoleStmt +== 045 +DROP ROLE regress_passwd8 +-- +STMT: DropRoleStmt +== 046 +DROP ROLE regress_passwd9 +-- +STMT: DropRoleStmt +== 047 +DROP ROLE regress_passwd_empty +-- +STMT: DropRoleStmt +== 048 +DROP ROLE regress_passwd_sha_len0 +-- +STMT: DropRoleStmt +== 049 +DROP ROLE regress_passwd_sha_len1 +-- +STMT: DropRoleStmt +== 050 +DROP ROLE regress_passwd_sha_len2 +-- +STMT: DropRoleStmt +== 051 +-- all entries should have been removed +SELECT rolname, rolpassword + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/path.metadata.json b/parser/testdata/summary/postgres_regress/path.metadata.json new file mode 100644 index 0000000..880b1d2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/path.metadata.json @@ -0,0 +1,27 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023" + ] +} diff --git a/parser/testdata/summary/postgres_regress/path.test b/parser/testdata/summary/postgres_regress/path.test new file mode 100644 index 0000000..ac103ef --- /dev/null +++ b/parser/testdata/summary/postgres_regress/path.test @@ -0,0 +1,147 @@ +== 001 +|-- +-- PATH +|-- + +--DROP TABLE PATH_TBL; + +CREATE TABLE PATH_TBL (f1 path) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO PATH_TBL VALUES (' ( ( 1 , 2 ) , ( 3 , 4 ) ) ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO PATH_TBL VALUES ('[ (0,0),(3,0),(4,5),(1,6) ]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO PATH_TBL VALUES ('((1,2) ,(3,4 ))') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO PATH_TBL VALUES ('1,2 ,3,4 ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO PATH_TBL VALUES (' [1,2,3, 4] ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO PATH_TBL VALUES ('((10,20))') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- Only one point + +INSERT INTO PATH_TBL VALUES ('[ 11,12,13,14 ]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO PATH_TBL VALUES ('( 11,12,13,14) ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +-- bad values for parser testing +INSERT INTO PATH_TBL VALUES ('[]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO PATH_TBL VALUES ('(1,2,3,4') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +INSERT INTO PATH_TBL VALUES ('(1,2),(3,4)]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +SELECT f1 AS open_path FROM PATH_TBL WHERE isopen(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 017 +SELECT f1 AS closed_path FROM PATH_TBL WHERE isclosed(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 018 +SELECT pclose(f1) AS closed_path FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="pclose" function="pclose" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT popen(f1) AS open_path FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="popen" function="popen" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('[(1,2),(3)]', 'path') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'path') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT * FROM pg_input_error_info('[(1,2,6),(3,4,6)]', 'path') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/pg_lsn.metadata.json b/parser/testdata/summary/postgres_regress/pg_lsn.metadata.json new file mode 100644 index 0000000..442b788 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/pg_lsn.metadata.json @@ -0,0 +1,35 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031" + ] +} diff --git a/parser/testdata/summary/postgres_regress/pg_lsn.test b/parser/testdata/summary/postgres_regress/pg_lsn.test new file mode 100644 index 0000000..e6d64c1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/pg_lsn.test @@ -0,0 +1,181 @@ +== 001 +|-- +-- PG_LSN +|-- + +CREATE TABLE PG_LSN_TBL (f1 pg_lsn) +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DDL +STMT: CreateStmt +== 002 +-- Largest and smallest input +INSERT INTO PG_LSN_TBL VALUES ('0/0') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO PG_LSN_TBL VALUES ('FFFFFFFF/FFFFFFFF') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +-- Incorrect input +INSERT INTO PG_LSN_TBL VALUES ('G/0') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO PG_LSN_TBL VALUES ('-1/0') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO PG_LSN_TBL VALUES (' 0/12345678') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO PG_LSN_TBL VALUES ('ABCD/') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO PG_LSN_TBL VALUES ('/ABCD') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('16AE7F7', 'pg_lsn') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT * FROM pg_input_error_info('16AE7F7', 'pg_lsn') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 011 +-- Min/Max aggregation +SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 012 +DROP TABLE PG_LSN_TBL +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DDL +STMT: DropStmt +== 013 +-- Operators +SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn +-- +STMT: SelectStmt +== 014 +SELECT '0/16AE7F8'::pg_lsn != '0/16AE7F7' +-- +STMT: SelectStmt +== 015 +SELECT '0/16AE7F7' < '0/16AE7F8'::pg_lsn +-- +STMT: SelectStmt +== 016 +SELECT '0/16AE7F8' > pg_lsn '0/16AE7F7' +-- +STMT: SelectStmt +== 017 +SELECT '0/16AE7F7'::pg_lsn - '0/16AE7F8'::pg_lsn +-- +STMT: SelectStmt +== 018 +SELECT '0/16AE7F8'::pg_lsn - '0/16AE7F7'::pg_lsn +-- +STMT: SelectStmt +== 019 +SELECT '0/16AE7F7'::pg_lsn + 16::numeric +-- +STMT: SelectStmt +== 020 +SELECT 16::numeric + '0/16AE7F7'::pg_lsn +-- +STMT: SelectStmt +== 021 +SELECT '0/16AE7F7'::pg_lsn - 16::numeric +-- +STMT: SelectStmt +== 022 +SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 1::numeric +-- +STMT: SelectStmt +== 023 +SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 2::numeric +-- +STMT: SelectStmt +== 024 +-- out of range error +SELECT '0/1'::pg_lsn - 1::numeric +-- +STMT: SelectStmt +== 025 +SELECT '0/1'::pg_lsn - 2::numeric +-- +STMT: SelectStmt +== 026 +-- out of range error +SELECT '0/0'::pg_lsn + ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn) +-- +STMT: SelectStmt +== 027 +SELECT 'FFFFFFFF/FFFFFFFF'::pg_lsn - ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn) +-- +STMT: SelectStmt +== 028 +SELECT '0/16AE7F7'::pg_lsn + 'NaN'::numeric +-- +STMT: SelectStmt +== 029 +SELECT '0/16AE7F7'::pg_lsn - 'NaN'::numeric +-- +STMT: SelectStmt +== 030 +-- Check btree and hash opclasses +EXPLAIN (COSTS OFF) +SELECT DISTINCT (i || '/' || j)::pg_lsn f + FROM generate_series(1, 10) i, + generate_series(1, 10) j, + generate_series(1, 5) k + WHERE i <= 10 AND j > 0 AND j <= 10 + ORDER BY f +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +== 031 +SELECT DISTINCT (i || '/' || j)::pg_lsn f + FROM generate_series(1, 10) i, + generate_series(1, 10) j, + generate_series(1, 5) k + WHERE i <= 10 AND j > 0 AND j <= 10 + ORDER BY f +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +FILTER: schema="" table="" column="j" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/plancache.metadata.json b/parser/testdata/summary/postgres_regress/plancache.metadata.json new file mode 100644 index 0000000..ba349a5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/plancache.metadata.json @@ -0,0 +1,101 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097" + ] +} diff --git a/parser/testdata/summary/postgres_regress/plancache.test b/parser/testdata/summary/postgres_regress/plancache.test new file mode 100644 index 0000000..2bfd3de --- /dev/null +++ b/parser/testdata/summary/postgres_regress/plancache.test @@ -0,0 +1,559 @@ +== 001 +|-- +-- Tests to exercise the plan caching/invalidation mechanism +|-- + +CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 002 +-- create and use a cached plan +PREPARE prepstmt AS SELECT * FROM pcachetest +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +== 003 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +== 004 +-- and one with parameters +PREPARE prepstmt2(bigint) AS SELECT * FROM pcachetest WHERE q1 = $1 +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: PrepareStmt +STMT: SelectStmt +== 005 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +== 006 +-- invalidate the plans and see what happens +DROP TABLE pcachetest +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +STMT: DropStmt +== 007 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +== 008 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +== 009 +-- recreate the temp table (this demonstrates that the raw plan is +-- purely textual and doesn't depend on OIDs, for instance) +CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2 +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 010 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +== 011 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +== 012 +-- prepared statements should prevent change in output tupdesc, +-- since clients probably aren't expecting that to change on the fly +ALTER TABLE pcachetest ADD COLUMN q3 bigint +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +STMT: AlterTableStmt +== 013 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +== 014 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +== 015 +-- but we're nice guys and will let you undo your mistake +ALTER TABLE pcachetest DROP COLUMN q3 +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +STMT: AlterTableStmt +== 016 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +== 017 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +== 018 +-- Try it with a view, which isn't directly used in the resulting plan +-- but should trigger invalidation anyway +CREATE TEMP VIEW pcacheview AS + SELECT * FROM pcachetest +-- +TABLE: name="pcacheview" schema="" table="pcacheview" ctx=DDL +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 019 +PREPARE vprep AS SELECT * FROM pcacheview +-- +TABLE: name="pcacheview" schema="" table="pcacheview" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +== 020 +EXECUTE vprep +-- +STMT: ExecuteStmt +== 021 +CREATE OR REPLACE TEMP VIEW pcacheview AS + SELECT q1, q2/2 AS q2 FROM pcachetest +-- +TABLE: name="pcacheview" schema="" table="pcacheview" ctx=DDL +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 022 +EXECUTE vprep +-- +STMT: ExecuteStmt +== 023 +-- Check basic SPI plan invalidation + +create function cache_test(int) returns int as $$ +declare total int; +begin + create temp table t1(f1 int); + insert into t1 values($1); + insert into t1 values(11); + insert into t1 values(12); + insert into t1 values(13); + select sum(f1) into total from t1; + drop table t1; + return total; +end +$$ language plpgsql +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 024 +select cache_test(1) +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=Call +STMT: SelectStmt +== 025 +select cache_test(2) +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=Call +STMT: SelectStmt +== 026 +select cache_test(3) +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=Call +STMT: SelectStmt +== 027 +-- Check invalidation of plpgsql "simple expression" + +create temp view v1 as + select 2+2 as f1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 028 +create function cache_test_2() returns int as $$ +begin + return f1 from v1; +end$$ language plpgsql +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +select cache_test_2() +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=Call +STMT: SelectStmt +== 030 +create or replace temp view v1 as + select 2+2+4 as f1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 031 +select cache_test_2() +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=Call +STMT: SelectStmt +== 032 +create or replace temp view v1 as + select 2+2+4+(select max(unique1) from tenk1) as f1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 033 +select cache_test_2() +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=Call +STMT: SelectStmt +== 034 +--- Check that change of search_path is honored when re-using cached plan + +create schema s1 + create table abc (f1 int) +-- +STMT: CreateSchemaStmt +== 035 +create schema s2 + create table abc (f1 int) +-- +STMT: CreateSchemaStmt +== 036 +insert into s1.abc values(123) +-- +TABLE: name="s1.abc" schema="s1" table="abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +insert into s2.abc values(456) +-- +TABLE: name="s2.abc" schema="s2" table="abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +set search_path = s1 +-- +STMT: VariableSetStmt +== 039 +prepare p1 as select f1 from abc +-- +TABLE: name="abc" schema="" table="abc" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +== 040 +execute p1 +-- +STMT: ExecuteStmt +== 041 +set search_path = s2 +-- +STMT: VariableSetStmt +== 042 +select f1 from abc +-- +TABLE: name="abc" schema="" table="abc" ctx=Select +STMT: SelectStmt +== 043 +execute p1 +-- +STMT: ExecuteStmt +== 044 +alter table s1.abc add column f2 float8 +-- +TABLE: name="s1.abc" schema="s1" table="abc" ctx=DDL +STMT: AlterTableStmt +== 045 +-- force replan + +execute p1 +-- +STMT: ExecuteStmt +== 046 +drop schema s1 cascade +-- +STMT: DropStmt +== 047 +drop schema s2 cascade +-- +STMT: DropStmt +== 048 +reset search_path +-- +STMT: VariableSetStmt +== 049 +-- Check that invalidation deals with regclass constants + +create temp sequence seq +-- +STMT: CreateSeqStmt +== 050 +prepare p2 as select nextval('seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 051 +execute p2 +-- +STMT: ExecuteStmt +== 052 +drop sequence seq +-- +STMT: DropStmt +== 053 +create temp sequence seq +-- +STMT: CreateSeqStmt +== 054 +execute p2 +-- +STMT: ExecuteStmt +== 055 +-- Check DDL via SPI, immediately followed by SPI plan re-use +-- (bug in original coding) + +create function cachebug() returns void as $$ +declare r int; +begin + drop table if exists temptable cascade; + create temp table temptable as select * from generate_series(1,3) as f1; + create temp view vv as select * from temptable; + for r in select * from vv loop + raise notice '%', r; + end loop; +end$$ language plpgsql +-- +FUNCTION: name="cachebug" function="cachebug" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 056 +select cachebug() +-- +FUNCTION: name="cachebug" function="cachebug" schema="" ctx=Call +STMT: SelectStmt +== 057 +select cachebug() +-- +FUNCTION: name="cachebug" function="cachebug" schema="" ctx=Call +STMT: SelectStmt +== 058 +-- Check that addition or removal of any partition is correctly dealt with by +-- default partition table when it is being used in prepared statement. +create table pc_list_parted (a int) partition by list(a) +-- +TABLE: name="pc_list_parted" schema="" table="pc_list_parted" ctx=DDL +STMT: CreateStmt +== 059 +create table pc_list_part_null partition of pc_list_parted for values in (null) +-- +TABLE: name="pc_list_part_null" schema="" table="pc_list_part_null" ctx=DDL +STMT: CreateStmt +== 060 +create table pc_list_part_1 partition of pc_list_parted for values in (1) +-- +TABLE: name="pc_list_part_1" schema="" table="pc_list_part_1" ctx=DDL +STMT: CreateStmt +== 061 +create table pc_list_part_def partition of pc_list_parted default +-- +TABLE: name="pc_list_part_def" schema="" table="pc_list_part_def" ctx=DDL +STMT: CreateStmt +== 062 +prepare pstmt_def_insert (int) as insert into pc_list_part_def values($1) +-- +TABLE: name="pc_list_part_def" schema="" table="pc_list_part_def" ctx=DML +STMT: PrepareStmt +STMT: InsertStmt +STMT: SelectStmt +== 063 +-- should fail +execute pstmt_def_insert(null) +-- +STMT: ExecuteStmt +== 064 +execute pstmt_def_insert(1) +-- +STMT: ExecuteStmt +== 065 +create table pc_list_part_2 partition of pc_list_parted for values in (2) +-- +TABLE: name="pc_list_part_2" schema="" table="pc_list_part_2" ctx=DDL +STMT: CreateStmt +== 066 +execute pstmt_def_insert(2) +-- +STMT: ExecuteStmt +== 067 +alter table pc_list_parted detach partition pc_list_part_null +-- +TABLE: name="pc_list_parted" schema="" table="pc_list_parted" ctx=DDL +STMT: AlterTableStmt +== 068 +-- should be ok +execute pstmt_def_insert(null) +-- +STMT: ExecuteStmt +== 069 +drop table pc_list_part_1 +-- +TABLE: name="pc_list_part_1" schema="" table="pc_list_part_1" ctx=DDL +STMT: DropStmt +== 070 +-- should be ok +execute pstmt_def_insert(1) +-- +STMT: ExecuteStmt +== 071 +drop table pc_list_parted, pc_list_part_null +-- +TABLE: name="pc_list_parted" schema="" table="pc_list_parted" ctx=DDL +TABLE: name="pc_list_part_null" schema="" table="pc_list_part_null" ctx=DDL +STMT: DropStmt +== 072 +deallocate pstmt_def_insert +-- +STMT: DeallocateStmt +== 073 +-- Test plan_cache_mode + +create table test_mode (a int) +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: CreateStmt +== 074 +insert into test_mode select 1 from generate_series(1,1000) union all select 2 +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 075 +create index on test_mode (a) +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: IndexStmt +== 076 +analyze test_mode +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: VacuumStmt +== 077 +prepare test_mode_pp (int) as select count(*) from test_mode where a = $1 +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +== 078 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 079 +-- up to 5 executions, custom plan is used +set plan_cache_mode to auto +-- +STMT: VariableSetStmt +== 080 +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 081 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 082 +-- force generic plan +set plan_cache_mode to force_generic_plan +-- +STMT: VariableSetStmt +== 083 +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 084 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 085 +-- get to generic plan by 5 executions +set plan_cache_mode to auto +-- +STMT: VariableSetStmt +== 086 +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +== 087 +-- 1x +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +== 088 +-- 2x +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +== 089 +-- 3x +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +== 090 +-- 4x +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 091 +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +== 092 +-- 5x +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 093 +-- we should now get a really bad plan +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 094 +-- but we can force a custom plan +set plan_cache_mode to force_custom_plan +-- +STMT: VariableSetStmt +== 095 +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 096 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 097 +drop table test_mode +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/plpgsql.metadata.json b/parser/testdata/summary/postgres_regress/plpgsql.metadata.json new file mode 100644 index 0000000..35fd146 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/plpgsql.metadata.json @@ -0,0 +1,945 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941" + ] +} diff --git a/parser/testdata/summary/postgres_regress/plpgsql.test b/parser/testdata/summary/postgres_regress/plpgsql.test new file mode 100644 index 0000000..5161779 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/plpgsql.test @@ -0,0 +1,8012 @@ +== 001 +|-- +-- PLPGSQL +|-- +-- Scenario: +|-- +-- A building with a modern TP cable installation where any +-- of the wall connectors can be used to plug in phones, +-- ethernet interfaces or local office hubs. The backside +-- of the wall connectors is wired to one of several patch- +-- fields in the building. +|-- +-- In the patchfields, there are hubs and all the slots +-- representing the wall connectors. In addition there are +-- slots that can represent a phone line from the central +-- phone system. +|-- +-- Triggers ensure consistency of the patching information. +|-- +-- Functions are used to build up powerful views that let +-- you look behind the wall when looking at a patchfield +-- or into a room. +|-- + + +create table Room ( + roomno char(8), + comment text +) +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: CreateStmt +== 002 +create unique index Room_rno on Room using btree (roomno bpchar_ops) +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: IndexStmt +== 003 +create table WSlot ( + slotname char(20), + roomno char(8), + slotlink char(20), + backlink char(20) +) +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateStmt +== 004 +create unique index WSlot_name on WSlot using btree (slotname bpchar_ops) +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: IndexStmt +== 005 +create table PField ( + name text, + comment text +) +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: CreateStmt +== 006 +create unique index PField_name on PField using btree (name text_ops) +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: IndexStmt +== 007 +create table PSlot ( + slotname char(20), + pfname text, + slotlink char(20), + backlink char(20) +) +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateStmt +== 008 +create unique index PSlot_name on PSlot using btree (slotname bpchar_ops) +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: IndexStmt +== 009 +create table PLine ( + slotname char(20), + phonenumber char(20), + comment text, + backlink char(20) +) +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateStmt +== 010 +create unique index PLine_name on PLine using btree (slotname bpchar_ops) +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: IndexStmt +== 011 +create table Hub ( + name char(14), + comment text, + nslots integer +) +-- +TABLE: name="hub" schema="" table="hub" ctx=DDL +STMT: CreateStmt +== 012 +create unique index Hub_name on Hub using btree (name bpchar_ops) +-- +TABLE: name="hub" schema="" table="hub" ctx=DDL +STMT: IndexStmt +== 013 +create table HSlot ( + slotname char(20), + hubname char(14), + slotno integer, + slotlink char(20) +) +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateStmt +== 014 +create unique index HSlot_name on HSlot using btree (slotname bpchar_ops) +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: IndexStmt +== 015 +create index HSlot_hubname on HSlot using btree (hubname bpchar_ops) +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: IndexStmt +== 016 +create table System ( + name text, + comment text +) +-- +TABLE: name="system" schema="" table="system" ctx=DDL +STMT: CreateStmt +== 017 +create unique index System_name on System using btree (name text_ops) +-- +TABLE: name="system" schema="" table="system" ctx=DDL +STMT: IndexStmt +== 018 +create table IFace ( + slotname char(20), + sysname text, + ifname text, + slotlink char(20) +) +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateStmt +== 019 +create unique index IFace_name on IFace using btree (slotname bpchar_ops) +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: IndexStmt +== 020 +create table PHone ( + slotname char(20), + comment text, + slotlink char(20) +) +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateStmt +== 021 +create unique index PHone_name on PHone using btree (slotname bpchar_ops) +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: IndexStmt +== 022 +-- ************************************************************ +-- * +-- * Trigger procedures and functions for the patchfield +-- * test of PL/pgSQL +-- * +-- ************************************************************ + + +-- ************************************************************ +-- * AFTER UPDATE on Room +-- * - If room no changes let wall slots follow +-- ************************************************************ +create function tg_room_au() returns trigger as ' +begin + if new.roomno != old.roomno then + update WSlot set roomno = new.roomno where roomno = old.roomno; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_room_au" function="tg_room_au" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 023 +create trigger tg_room_au after update + on Room for each row execute procedure tg_room_au() +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: CreateTrigStmt +== 024 +-- ************************************************************ +-- * AFTER DELETE on Room +-- * - delete wall slots in this room +-- ************************************************************ +create function tg_room_ad() returns trigger as ' +begin + delete from WSlot where roomno = old.roomno; + return old; +end; +' language plpgsql +-- +FUNCTION: name="tg_room_ad" function="tg_room_ad" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 025 +create trigger tg_room_ad after delete + on Room for each row execute procedure tg_room_ad() +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: CreateTrigStmt +== 026 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on WSlot +-- * - Check that room exists +-- ************************************************************ +create function tg_wslot_biu() returns trigger as $$ +begin + if count(*) = 0 from Room where roomno = new.roomno then + raise exception 'Room % does not exist', new.roomno; + end if; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="tg_wslot_biu" function="tg_wslot_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 027 +create trigger tg_wslot_biu before insert or update + on WSlot for each row execute procedure tg_wslot_biu() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +== 028 +-- ************************************************************ +-- * AFTER UPDATE on PField +-- * - Let PSlots of this field follow +-- ************************************************************ +create function tg_pfield_au() returns trigger as ' +begin + if new.name != old.name then + update PSlot set pfname = new.name where pfname = old.name; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_pfield_au" function="tg_pfield_au" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 029 +create trigger tg_pfield_au after update + on PField for each row execute procedure tg_pfield_au() +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: CreateTrigStmt +== 030 +-- ************************************************************ +-- * AFTER DELETE on PField +-- * - Remove all slots of this patchfield +-- ************************************************************ +create function tg_pfield_ad() returns trigger as ' +begin + delete from PSlot where pfname = old.name; + return old; +end; +' language plpgsql +-- +FUNCTION: name="tg_pfield_ad" function="tg_pfield_ad" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 031 +create trigger tg_pfield_ad after delete + on PField for each row execute procedure tg_pfield_ad() +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: CreateTrigStmt +== 032 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on PSlot +-- * - Ensure that our patchfield does exist +-- ************************************************************ +create function tg_pslot_biu() returns trigger as $proc$ +declare + pfrec record; + ps alias for new; +begin + select into pfrec * from PField where name = ps.pfname; + if not found then + raise exception $$Patchfield "%" does not exist$$, ps.pfname; + end if; + return ps; +end; +$proc$ language plpgsql +-- +FUNCTION: name="tg_pslot_biu" function="tg_pslot_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 033 +create trigger tg_pslot_biu before insert or update + on PSlot for each row execute procedure tg_pslot_biu() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +== 034 +-- ************************************************************ +-- * AFTER UPDATE on System +-- * - If system name changes let interfaces follow +-- ************************************************************ +create function tg_system_au() returns trigger as ' +begin + if new.name != old.name then + update IFace set sysname = new.name where sysname = old.name; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_system_au" function="tg_system_au" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 035 +create trigger tg_system_au after update + on System for each row execute procedure tg_system_au() +-- +TABLE: name="system" schema="" table="system" ctx=DDL +STMT: CreateTrigStmt +== 036 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on IFace +-- * - set the slotname to IF.sysname.ifname +-- ************************************************************ +create function tg_iface_biu() returns trigger as $$ +declare + sname text; + sysrec record; +begin + select into sysrec * from system where name = new.sysname; + if not found then + raise exception $q$system "%" does not exist$q$, new.sysname; + end if; + sname := 'IF.' || new.sysname; + sname := sname || '.'; + sname := sname || new.ifname; + if length(sname) > 20 then + raise exception 'IFace slotname "%" too long (20 char max)', sname; + end if; + new.slotname := sname; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="tg_iface_biu" function="tg_iface_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 037 +create trigger tg_iface_biu before insert or update + on IFace for each row execute procedure tg_iface_biu() +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +== 038 +-- ************************************************************ +-- * AFTER INSERT or UPDATE or DELETE on Hub +-- * - insert/delete/rename slots as required +-- ************************************************************ +create function tg_hub_a() returns trigger as ' +declare + hname text; + dummy integer; +begin + if tg_op = ''INSERT'' then + dummy := tg_hub_adjustslots(new.name, 0, new.nslots); + return new; + end if; + if tg_op = ''UPDATE'' then + if new.name != old.name then + update HSlot set hubname = new.name where hubname = old.name; + end if; + dummy := tg_hub_adjustslots(new.name, old.nslots, new.nslots); + return new; + end if; + if tg_op = ''DELETE'' then + dummy := tg_hub_adjustslots(old.name, old.nslots, 0); + return old; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_hub_a" function="tg_hub_a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 039 +create trigger tg_hub_a after insert or update or delete + on Hub for each row execute procedure tg_hub_a() +-- +TABLE: name="hub" schema="" table="hub" ctx=DDL +STMT: CreateTrigStmt +== 040 +-- ************************************************************ +-- * Support function to add/remove slots of Hub +-- ************************************************************ +create function tg_hub_adjustslots(hname bpchar, + oldnslots integer, + newnslots integer) +returns integer as ' +begin + if newnslots = oldnslots then + return 0; + end if; + if newnslots < oldnslots then + delete from HSlot where hubname = hname and slotno > newnslots; + return 0; + end if; + for i in oldnslots + 1 .. newnslots loop + insert into HSlot (slotname, hubname, slotno, slotlink) + values (''HS.dummy'', hname, i, ''''); + end loop; + return 0; +end +' language plpgsql +-- +FUNCTION: name="tg_hub_adjustslots" function="tg_hub_adjustslots" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 041 +-- Test comments +COMMENT ON FUNCTION tg_hub_adjustslots_wrong(bpchar, integer, integer) IS 'function with args' +-- +STMT: CommentStmt +== 042 +COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS 'function with args' +-- +STMT: CommentStmt +== 043 +COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS NULL +-- +STMT: CommentStmt +== 044 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on HSlot +-- * - prevent from manual manipulation +-- * - set the slotname to HS.hubname.slotno +-- ************************************************************ +create function tg_hslot_biu() returns trigger as ' +declare + sname text; + xname HSlot.slotname%TYPE; + hubrec record; +begin + select into hubrec * from Hub where name = new.hubname; + if not found then + raise exception ''no manual manipulation of HSlot''; + end if; + if new.slotno < 1 or new.slotno > hubrec.nslots then + raise exception ''no manual manipulation of HSlot''; + end if; + if tg_op = ''UPDATE'' and new.hubname != old.hubname then + if count(*) > 0 from Hub where name = old.hubname then + raise exception ''no manual manipulation of HSlot''; + end if; + end if; + sname := ''HS.'' || trim(new.hubname); + sname := sname || ''.''; + sname := sname || new.slotno::text; + if length(sname) > 20 then + raise exception ''HSlot slotname "%" too long (20 char max)'', sname; + end if; + new.slotname := sname; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_hslot_biu" function="tg_hslot_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 045 +create trigger tg_hslot_biu before insert or update + on HSlot for each row execute procedure tg_hslot_biu() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +== 046 +-- ************************************************************ +-- * BEFORE DELETE on HSlot +-- * - prevent from manual manipulation +-- ************************************************************ +create function tg_hslot_bd() returns trigger as ' +declare + hubrec record; +begin + select into hubrec * from Hub where name = old.hubname; + if not found then + return old; + end if; + if old.slotno > hubrec.nslots then + return old; + end if; + raise exception ''no manual manipulation of HSlot''; +end; +' language plpgsql +-- +FUNCTION: name="tg_hslot_bd" function="tg_hslot_bd" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 047 +create trigger tg_hslot_bd before delete + on HSlot for each row execute procedure tg_hslot_bd() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +== 048 +-- ************************************************************ +-- * BEFORE INSERT on all slots +-- * - Check name prefix +-- ************************************************************ +create function tg_chkslotname() returns trigger as ' +begin + if substr(new.slotname, 1, 2) != tg_argv[0] then + raise exception ''slotname must begin with %'', tg_argv[0]; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_chkslotname" function="tg_chkslotname" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 049 +create trigger tg_chkslotname before insert + on PSlot for each row execute procedure tg_chkslotname('PS') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +== 050 +create trigger tg_chkslotname before insert + on WSlot for each row execute procedure tg_chkslotname('WS') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +== 051 +create trigger tg_chkslotname before insert + on PLine for each row execute procedure tg_chkslotname('PL') +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +== 052 +create trigger tg_chkslotname before insert + on IFace for each row execute procedure tg_chkslotname('IF') +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +== 053 +create trigger tg_chkslotname before insert + on PHone for each row execute procedure tg_chkslotname('PH') +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +== 054 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on all slots with slotlink +-- * - Set slotlink to empty string if NULL value given +-- ************************************************************ +create function tg_chkslotlink() returns trigger as ' +begin + if new.slotlink isnull then + new.slotlink := ''''; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_chkslotlink" function="tg_chkslotlink" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 055 +create trigger tg_chkslotlink before insert or update + on PSlot for each row execute procedure tg_chkslotlink() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +== 056 +create trigger tg_chkslotlink before insert or update + on WSlot for each row execute procedure tg_chkslotlink() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +== 057 +create trigger tg_chkslotlink before insert or update + on IFace for each row execute procedure tg_chkslotlink() +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +== 058 +create trigger tg_chkslotlink before insert or update + on HSlot for each row execute procedure tg_chkslotlink() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +== 059 +create trigger tg_chkslotlink before insert or update + on PHone for each row execute procedure tg_chkslotlink() +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +== 060 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on all slots with backlink +-- * - Set backlink to empty string if NULL value given +-- ************************************************************ +create function tg_chkbacklink() returns trigger as ' +begin + if new.backlink isnull then + new.backlink := ''''; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_chkbacklink" function="tg_chkbacklink" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 061 +create trigger tg_chkbacklink before insert or update + on PSlot for each row execute procedure tg_chkbacklink() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +== 062 +create trigger tg_chkbacklink before insert or update + on WSlot for each row execute procedure tg_chkbacklink() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +== 063 +create trigger tg_chkbacklink before insert or update + on PLine for each row execute procedure tg_chkbacklink() +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +== 064 +-- ************************************************************ +-- * BEFORE UPDATE on PSlot +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_pslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PSlot where slotname = old.slotname; + insert into PSlot ( + slotname, + pfname, + slotlink, + backlink + ) values ( + new.slotname, + new.pfname, + new.slotlink, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_pslot_bu" function="tg_pslot_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 065 +create trigger tg_pslot_bu before update + on PSlot for each row execute procedure tg_pslot_bu() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +== 066 +-- ************************************************************ +-- * BEFORE UPDATE on WSlot +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_wslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from WSlot where slotname = old.slotname; + insert into WSlot ( + slotname, + roomno, + slotlink, + backlink + ) values ( + new.slotname, + new.roomno, + new.slotlink, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_wslot_bu" function="tg_wslot_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 067 +create trigger tg_wslot_bu before update + on WSlot for each row execute procedure tg_Wslot_bu() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +== 068 +-- ************************************************************ +-- * BEFORE UPDATE on PLine +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_pline_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PLine where slotname = old.slotname; + insert into PLine ( + slotname, + phonenumber, + comment, + backlink + ) values ( + new.slotname, + new.phonenumber, + new.comment, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_pline_bu" function="tg_pline_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 069 +create trigger tg_pline_bu before update + on PLine for each row execute procedure tg_pline_bu() +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +== 070 +-- ************************************************************ +-- * BEFORE UPDATE on IFace +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_iface_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from IFace where slotname = old.slotname; + insert into IFace ( + slotname, + sysname, + ifname, + slotlink + ) values ( + new.slotname, + new.sysname, + new.ifname, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_iface_bu" function="tg_iface_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 071 +create trigger tg_iface_bu before update + on IFace for each row execute procedure tg_iface_bu() +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +== 072 +-- ************************************************************ +-- * BEFORE UPDATE on HSlot +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_hslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname or new.hubname != old.hubname then + delete from HSlot where slotname = old.slotname; + insert into HSlot ( + slotname, + hubname, + slotno, + slotlink + ) values ( + new.slotname, + new.hubname, + new.slotno, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_hslot_bu" function="tg_hslot_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 073 +create trigger tg_hslot_bu before update + on HSlot for each row execute procedure tg_hslot_bu() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +== 074 +-- ************************************************************ +-- * BEFORE UPDATE on PHone +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_phone_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PHone where slotname = old.slotname; + insert into PHone ( + slotname, + comment, + slotlink + ) values ( + new.slotname, + new.comment, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_phone_bu" function="tg_phone_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 075 +create trigger tg_phone_bu before update + on PHone for each row execute procedure tg_phone_bu() +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +== 076 +-- ************************************************************ +-- * AFTER INSERT or UPDATE or DELETE on slot with backlink +-- * - Ensure that the opponent correctly points back to us +-- ************************************************************ +create function tg_backlink_a() returns trigger as ' +declare + dummy integer; +begin + if tg_op = ''INSERT'' then + if new.backlink != '''' then + dummy := tg_backlink_set(new.backlink, new.slotname); + end if; + return new; + end if; + if tg_op = ''UPDATE'' then + if new.backlink != old.backlink then + if old.backlink != '''' then + dummy := tg_backlink_unset(old.backlink, old.slotname); + end if; + if new.backlink != '''' then + dummy := tg_backlink_set(new.backlink, new.slotname); + end if; + else + if new.slotname != old.slotname and new.backlink != '''' then + dummy := tg_slotlink_set(new.backlink, new.slotname); + end if; + end if; + return new; + end if; + if tg_op = ''DELETE'' then + if old.backlink != '''' then + dummy := tg_backlink_unset(old.backlink, old.slotname); + end if; + return old; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_backlink_a" function="tg_backlink_a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 077 +create trigger tg_backlink_a after insert or update or delete + on PSlot for each row execute procedure tg_backlink_a('PS') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +== 078 +create trigger tg_backlink_a after insert or update or delete + on WSlot for each row execute procedure tg_backlink_a('WS') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +== 079 +create trigger tg_backlink_a after insert or update or delete + on PLine for each row execute procedure tg_backlink_a('PL') +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +== 080 +-- ************************************************************ +-- * Support function to set the opponents backlink field +-- * if it does not already point to the requested slot +-- ************************************************************ +create function tg_backlink_set(myname bpchar, blname bpchar) +returns integer as ' +declare + mytype char(2); + link char(4); + rec record; +begin + mytype := substr(myname, 1, 2); + link := mytype || substr(blname, 1, 2); + if link = ''PLPL'' then + raise exception + ''backlink between two phone lines does not make sense''; + end if; + if link in (''PLWS'', ''WSPL'') then + raise exception + ''direct link of phone line to wall slot not permitted''; + end if; + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update PSlot set backlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update WSlot set backlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PL'' then + select into rec * from PLine where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update PLine set backlink = blname where slotname = myname; + end if; + return 0; + end if; + raise exception ''illegal backlink beginning with %'', mytype; +end; +' language plpgsql +-- +FUNCTION: name="tg_backlink_set" function="tg_backlink_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 081 +-- ************************************************************ +-- * Support function to clear out the backlink field if +-- * it still points to specific slot +-- ************************************************************ +create function tg_backlink_unset(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + rec record; +begin + mytype := substr(myname, 1, 2); + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update PSlot set backlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update WSlot set backlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PL'' then + select into rec * from PLine where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update PLine set backlink = '''' where slotname = myname; + end if; + return 0; + end if; +end +' language plpgsql +-- +FUNCTION: name="tg_backlink_unset" function="tg_backlink_unset" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 082 +-- ************************************************************ +-- * AFTER INSERT or UPDATE or DELETE on slot with slotlink +-- * - Ensure that the opponent correctly points back to us +-- ************************************************************ +create function tg_slotlink_a() returns trigger as ' +declare + dummy integer; +begin + if tg_op = ''INSERT'' then + if new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + return new; + end if; + if tg_op = ''UPDATE'' then + if new.slotlink != old.slotlink then + if old.slotlink != '''' then + dummy := tg_slotlink_unset(old.slotlink, old.slotname); + end if; + if new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + else + if new.slotname != old.slotname and new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + end if; + return new; + end if; + if tg_op = ''DELETE'' then + if old.slotlink != '''' then + dummy := tg_slotlink_unset(old.slotlink, old.slotname); + end if; + return old; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_slotlink_a" function="tg_slotlink_a" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 083 +create trigger tg_slotlink_a after insert or update or delete + on PSlot for each row execute procedure tg_slotlink_a('PS') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +== 084 +create trigger tg_slotlink_a after insert or update or delete + on WSlot for each row execute procedure tg_slotlink_a('WS') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +== 085 +create trigger tg_slotlink_a after insert or update or delete + on IFace for each row execute procedure tg_slotlink_a('IF') +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +== 086 +create trigger tg_slotlink_a after insert or update or delete + on HSlot for each row execute procedure tg_slotlink_a('HS') +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +== 087 +create trigger tg_slotlink_a after insert or update or delete + on PHone for each row execute procedure tg_slotlink_a('PH') +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +== 088 +-- ************************************************************ +-- * Support function to set the opponents slotlink field +-- * if it does not already point to the requested slot +-- ************************************************************ +create function tg_slotlink_set(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + link char(4); + rec record; +begin + mytype := substr(myname, 1, 2); + link := mytype || substr(blname, 1, 2); + if link = ''PHPH'' then + raise exception + ''slotlink between two phones does not make sense''; + end if; + if link in (''PHHS'', ''HSPH'') then + raise exception + ''link of phone to hub does not make sense''; + end if; + if link in (''PHIF'', ''IFPH'') then + raise exception + ''link of phone to hub does not make sense''; + end if; + if link in (''PSWS'', ''WSPS'') then + raise exception + ''slotlink from patchslot to wallslot not permitted''; + end if; + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update PSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update WSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''IF'' then + select into rec * from IFace where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update IFace set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''HS'' then + select into rec * from HSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update HSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PH'' then + select into rec * from PHone where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update PHone set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + raise exception ''illegal slotlink beginning with %'', mytype; +end; +' language plpgsql +-- +FUNCTION: name="tg_slotlink_set" function="tg_slotlink_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 089 +-- ************************************************************ +-- * Support function to clear out the slotlink field if +-- * it still points to specific slot +-- ************************************************************ +create function tg_slotlink_unset(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + rec record; +begin + mytype := substr(myname, 1, 2); + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update PSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update WSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''IF'' then + select into rec * from IFace where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update IFace set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''HS'' then + select into rec * from HSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update HSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PH'' then + select into rec * from PHone where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update PHone set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_slotlink_unset" function="tg_slotlink_unset" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 090 +-- ************************************************************ +-- * Describe the backside of a patchfield slot +-- ************************************************************ +create function pslot_backlink_view(bpchar) +returns text as ' +<> +declare + rec record; + bltype char(2); + retval text; +begin + select into rec * from PSlot where slotname = $1; + if not found then + return ''''; + end if; + if rec.backlink = '''' then + return ''-''; + end if; + bltype := substr(rec.backlink, 1, 2); + if bltype = ''PL'' then + declare + rec record; + begin + select into rec * from PLine where slotname = "outer".rec.backlink; + retval := ''Phone line '' || trim(rec.phonenumber); + if rec.comment != '''' then + retval := retval || '' (''; + retval := retval || rec.comment; + retval := retval || '')''; + end if; + return retval; + end; + end if; + if bltype = ''WS'' then + select into rec * from WSlot where slotname = rec.backlink; + retval := trim(rec.slotname) || '' in room ''; + retval := retval || trim(rec.roomno); + retval := retval || '' -> ''; + return retval || wslot_slotlink_view(rec.slotname); + end if; + return rec.backlink; +end; +' language plpgsql +-- +FUNCTION: name="pslot_backlink_view" function="pslot_backlink_view" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 091 +-- ************************************************************ +-- * Describe the front of a patchfield slot +-- ************************************************************ +create function pslot_slotlink_view(bpchar) +returns text as ' +declare + psrec record; + sltype char(2); + retval text; +begin + select into psrec * from PSlot where slotname = $1; + if not found then + return ''''; + end if; + if psrec.slotlink = '''' then + return ''-''; + end if; + sltype := substr(psrec.slotlink, 1, 2); + if sltype = ''PS'' then + retval := trim(psrec.slotlink) || '' -> ''; + return retval || pslot_backlink_view(psrec.slotlink); + end if; + if sltype = ''HS'' then + retval := comment from Hub H, HSlot HS + where HS.slotname = psrec.slotlink + and H.name = HS.hubname; + retval := retval || '' slot ''; + retval := retval || slotno::text from HSlot + where slotname = psrec.slotlink; + return retval; + end if; + return psrec.slotlink; +end; +' language plpgsql +-- +FUNCTION: name="pslot_slotlink_view" function="pslot_slotlink_view" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 092 +-- ************************************************************ +-- * Describe the front of a wall connector slot +-- ************************************************************ +create function wslot_slotlink_view(bpchar) +returns text as ' +declare + rec record; + sltype char(2); + retval text; +begin + select into rec * from WSlot where slotname = $1; + if not found then + return ''''; + end if; + if rec.slotlink = '''' then + return ''-''; + end if; + sltype := substr(rec.slotlink, 1, 2); + if sltype = ''PH'' then + select into rec * from PHone where slotname = rec.slotlink; + retval := ''Phone '' || trim(rec.slotname); + if rec.comment != '''' then + retval := retval || '' (''; + retval := retval || rec.comment; + retval := retval || '')''; + end if; + return retval; + end if; + if sltype = ''IF'' then + declare + syrow System%RowType; + ifrow IFace%ROWTYPE; + begin + select into ifrow * from IFace where slotname = rec.slotlink; + select into syrow * from System where name = ifrow.sysname; + retval := syrow.name || '' IF ''; + retval := retval || ifrow.ifname; + if syrow.comment != '''' then + retval := retval || '' (''; + retval := retval || syrow.comment; + retval := retval || '')''; + end if; + return retval; + end; + end if; + return rec.slotlink; +end; +' language plpgsql +-- +FUNCTION: name="wslot_slotlink_view" function="wslot_slotlink_view" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 093 +-- ************************************************************ +-- * View of a patchfield describing backside and patches +-- ************************************************************ +create view Pfield_v1 as select PF.pfname, PF.slotname, + pslot_backlink_view(PF.slotname) as backside, + pslot_slotlink_view(PF.slotname) as patch + from PSlot PF +-- +TABLE: name="pfield_v1" schema="" table="pfield_v1" ctx=DDL +TABLE: name="pslot" schema="" table="pslot" ctx=Select +ALIAS: "pf"="pslot" +FUNCTION: name="pslot_backlink_view" function="pslot_backlink_view" schema="" ctx=Call +FUNCTION: name="pslot_slotlink_view" function="pslot_slotlink_view" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 094 +|-- +-- First we build the house - so we create the rooms +|-- +insert into Room values ('001', 'Entrance') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +insert into Room values ('002', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +insert into Room values ('003', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +insert into Room values ('004', 'Technical') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +insert into Room values ('101', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +insert into Room values ('102', 'Conference') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 100 +insert into Room values ('103', 'Restroom') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +insert into Room values ('104', 'Technical') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 102 +insert into Room values ('105', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +insert into Room values ('106', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +|-- +-- Second we install the wall connectors +|-- +insert into WSlot values ('WS.001.1a', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +insert into WSlot values ('WS.001.1b', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 106 +insert into WSlot values ('WS.001.2a', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +insert into WSlot values ('WS.001.2b', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +insert into WSlot values ('WS.001.3a', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +insert into WSlot values ('WS.001.3b', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +insert into WSlot values ('WS.002.1a', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +insert into WSlot values ('WS.002.1b', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +insert into WSlot values ('WS.002.2a', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 113 +insert into WSlot values ('WS.002.2b', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 114 +insert into WSlot values ('WS.002.3a', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +insert into WSlot values ('WS.002.3b', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +insert into WSlot values ('WS.003.1a', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 117 +insert into WSlot values ('WS.003.1b', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 118 +insert into WSlot values ('WS.003.2a', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 119 +insert into WSlot values ('WS.003.2b', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 120 +insert into WSlot values ('WS.003.3a', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +insert into WSlot values ('WS.003.3b', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +insert into WSlot values ('WS.101.1a', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +insert into WSlot values ('WS.101.1b', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 124 +insert into WSlot values ('WS.101.2a', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 125 +insert into WSlot values ('WS.101.2b', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 126 +insert into WSlot values ('WS.101.3a', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +insert into WSlot values ('WS.101.3b', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 128 +insert into WSlot values ('WS.102.1a', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +insert into WSlot values ('WS.102.1b', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 130 +insert into WSlot values ('WS.102.2a', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 131 +insert into WSlot values ('WS.102.2b', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 132 +insert into WSlot values ('WS.102.3a', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +insert into WSlot values ('WS.102.3b', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 134 +insert into WSlot values ('WS.105.1a', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 135 +insert into WSlot values ('WS.105.1b', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +insert into WSlot values ('WS.105.2a', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +insert into WSlot values ('WS.105.2b', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +insert into WSlot values ('WS.105.3a', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +insert into WSlot values ('WS.105.3b', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 140 +insert into WSlot values ('WS.106.1a', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +insert into WSlot values ('WS.106.1b', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +insert into WSlot values ('WS.106.2a', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +insert into WSlot values ('WS.106.2b', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +insert into WSlot values ('WS.106.3a', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 145 +insert into WSlot values ('WS.106.3b', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +|-- +-- Now create the patch fields and their slots +|-- +insert into PField values ('PF0_1', 'Wallslots basement') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +|-- +-- The cables for these will be made later, so they are unconnected for now +|-- +insert into PSlot values ('PS.base.a1', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +insert into PSlot values ('PS.base.a2', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 149 +insert into PSlot values ('PS.base.a3', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +insert into PSlot values ('PS.base.a4', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +insert into PSlot values ('PS.base.a5', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +insert into PSlot values ('PS.base.a6', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 153 +|-- +-- These are already wired to the wall connectors +|-- +insert into PSlot values ('PS.base.b1', 'PF0_1', '', 'WS.002.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +insert into PSlot values ('PS.base.b2', 'PF0_1', '', 'WS.002.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +insert into PSlot values ('PS.base.b3', 'PF0_1', '', 'WS.002.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 156 +insert into PSlot values ('PS.base.b4', 'PF0_1', '', 'WS.002.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 157 +insert into PSlot values ('PS.base.b5', 'PF0_1', '', 'WS.002.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 158 +insert into PSlot values ('PS.base.b6', 'PF0_1', '', 'WS.002.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +insert into PSlot values ('PS.base.c1', 'PF0_1', '', 'WS.003.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +insert into PSlot values ('PS.base.c2', 'PF0_1', '', 'WS.003.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 161 +insert into PSlot values ('PS.base.c3', 'PF0_1', '', 'WS.003.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +insert into PSlot values ('PS.base.c4', 'PF0_1', '', 'WS.003.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +insert into PSlot values ('PS.base.c5', 'PF0_1', '', 'WS.003.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +insert into PSlot values ('PS.base.c6', 'PF0_1', '', 'WS.003.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +|-- +-- This patchfield will be renamed later into PF0_2 - so its +-- slots references in pfname should follow +|-- +insert into PField values ('PF0_X', 'Phonelines basement') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +insert into PSlot values ('PS.base.ta1', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 167 +insert into PSlot values ('PS.base.ta2', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +insert into PSlot values ('PS.base.ta3', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +insert into PSlot values ('PS.base.ta4', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 170 +insert into PSlot values ('PS.base.ta5', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 171 +insert into PSlot values ('PS.base.ta6', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +insert into PSlot values ('PS.base.tb1', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +insert into PSlot values ('PS.base.tb2', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 174 +insert into PSlot values ('PS.base.tb3', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 175 +insert into PSlot values ('PS.base.tb4', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 176 +insert into PSlot values ('PS.base.tb5', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 177 +insert into PSlot values ('PS.base.tb6', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +insert into PField values ('PF1_1', 'Wallslots first floor') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 179 +insert into PSlot values ('PS.first.a1', 'PF1_1', '', 'WS.101.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 180 +insert into PSlot values ('PS.first.a2', 'PF1_1', '', 'WS.101.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 181 +insert into PSlot values ('PS.first.a3', 'PF1_1', '', 'WS.101.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 182 +insert into PSlot values ('PS.first.a4', 'PF1_1', '', 'WS.101.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 183 +insert into PSlot values ('PS.first.a5', 'PF1_1', '', 'WS.101.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 184 +insert into PSlot values ('PS.first.a6', 'PF1_1', '', 'WS.101.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 185 +insert into PSlot values ('PS.first.b1', 'PF1_1', '', 'WS.102.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +insert into PSlot values ('PS.first.b2', 'PF1_1', '', 'WS.102.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +insert into PSlot values ('PS.first.b3', 'PF1_1', '', 'WS.102.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +insert into PSlot values ('PS.first.b4', 'PF1_1', '', 'WS.102.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +insert into PSlot values ('PS.first.b5', 'PF1_1', '', 'WS.102.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +insert into PSlot values ('PS.first.b6', 'PF1_1', '', 'WS.102.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +insert into PSlot values ('PS.first.c1', 'PF1_1', '', 'WS.105.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 192 +insert into PSlot values ('PS.first.c2', 'PF1_1', '', 'WS.105.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +insert into PSlot values ('PS.first.c3', 'PF1_1', '', 'WS.105.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 194 +insert into PSlot values ('PS.first.c4', 'PF1_1', '', 'WS.105.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 195 +insert into PSlot values ('PS.first.c5', 'PF1_1', '', 'WS.105.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +insert into PSlot values ('PS.first.c6', 'PF1_1', '', 'WS.105.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 197 +insert into PSlot values ('PS.first.d1', 'PF1_1', '', 'WS.106.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 198 +insert into PSlot values ('PS.first.d2', 'PF1_1', '', 'WS.106.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 199 +insert into PSlot values ('PS.first.d3', 'PF1_1', '', 'WS.106.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 200 +insert into PSlot values ('PS.first.d4', 'PF1_1', '', 'WS.106.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +insert into PSlot values ('PS.first.d5', 'PF1_1', '', 'WS.106.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +insert into PSlot values ('PS.first.d6', 'PF1_1', '', 'WS.106.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +|-- +-- Now we wire the wall connectors 1a-2a in room 001 to the +-- patchfield. In the second update we make an error, and +-- correct it after +|-- +update PSlot set backlink = 'WS.001.1a' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 204 +update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 205 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +== 206 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +== 207 +update PSlot set backlink = 'WS.001.2a' where slotname = 'PS.base.a3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 208 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +== 209 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +== 210 +update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a2' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 211 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +== 212 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +== 213 +|-- +-- Same procedure for 2b-3b but this time updating the WSlot instead +-- of the PSlot. Due to the triggers the result is the same: +-- WSlot and corresponding PSlot point to each other. +|-- +update WSlot set backlink = 'PS.base.a4' where slotname = 'WS.001.2b' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +== 214 +update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3a' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +== 215 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +== 216 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +== 217 +update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3b' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +== 218 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +== 219 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +== 220 +update WSlot set backlink = 'PS.base.a5' where slotname = 'WS.001.3a' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +== 221 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +== 222 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +== 223 +insert into PField values ('PF1_2', 'Phonelines first floor') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 224 +insert into PSlot values ('PS.first.ta1', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +insert into PSlot values ('PS.first.ta2', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 226 +insert into PSlot values ('PS.first.ta3', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 227 +insert into PSlot values ('PS.first.ta4', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 228 +insert into PSlot values ('PS.first.ta5', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 229 +insert into PSlot values ('PS.first.ta6', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +insert into PSlot values ('PS.first.tb1', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 231 +insert into PSlot values ('PS.first.tb2', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 232 +insert into PSlot values ('PS.first.tb3', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 233 +insert into PSlot values ('PS.first.tb4', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 234 +insert into PSlot values ('PS.first.tb5', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 235 +insert into PSlot values ('PS.first.tb6', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 236 +|-- +-- Fix the wrong name for patchfield PF0_2 +|-- +update PField set name = 'PF0_2' where name = 'PF0_X' +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: UpdateStmt +== 237 +select * from PSlot order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +STMT: SelectStmt +== 238 +select * from WSlot order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +STMT: SelectStmt +== 239 +|-- +-- Install the central phone system and create the phone numbers. +-- They are wired on insert to the patchfields. Again the +-- triggers automatically tell the PSlots to update their +-- backlink field. +|-- +insert into PLine values ('PL.001', '-0', 'Central call', 'PS.base.ta1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +insert into PLine values ('PL.002', '-101', '', 'PS.base.ta2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 241 +insert into PLine values ('PL.003', '-102', '', 'PS.base.ta3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 242 +insert into PLine values ('PL.004', '-103', '', 'PS.base.ta5') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 243 +insert into PLine values ('PL.005', '-104', '', 'PS.base.ta6') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +insert into PLine values ('PL.006', '-106', '', 'PS.base.tb2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +insert into PLine values ('PL.007', '-108', '', 'PS.base.tb3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 246 +insert into PLine values ('PL.008', '-109', '', 'PS.base.tb4') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 247 +insert into PLine values ('PL.009', '-121', '', 'PS.base.tb5') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +insert into PLine values ('PL.010', '-122', '', 'PS.base.tb6') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 249 +insert into PLine values ('PL.015', '-134', '', 'PS.first.ta1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 250 +insert into PLine values ('PL.016', '-137', '', 'PS.first.ta3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 251 +insert into PLine values ('PL.017', '-139', '', 'PS.first.ta4') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 252 +insert into PLine values ('PL.018', '-362', '', 'PS.first.tb1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +insert into PLine values ('PL.019', '-363', '', 'PS.first.tb2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +insert into PLine values ('PL.020', '-364', '', 'PS.first.tb3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 255 +insert into PLine values ('PL.021', '-365', '', 'PS.first.tb5') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 256 +insert into PLine values ('PL.022', '-367', '', 'PS.first.tb6') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 257 +insert into PLine values ('PL.028', '-501', 'Fax entrance', 'PS.base.ta2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 258 +insert into PLine values ('PL.029', '-502', 'Fax first floor', 'PS.first.ta1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 259 +|-- +-- Buy some phones, plug them into the wall and patch the +-- phone lines to the corresponding patchfield slots. +|-- +insert into PHone values ('PH.hc001', 'Hicom standard', 'WS.001.1a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 260 +update PSlot set slotlink = 'PS.base.ta1' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 261 +insert into PHone values ('PH.hc002', 'Hicom standard', 'WS.002.1a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 262 +update PSlot set slotlink = 'PS.base.ta5' where slotname = 'PS.base.b1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 263 +insert into PHone values ('PH.hc003', 'Hicom standard', 'WS.002.2a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 264 +update PSlot set slotlink = 'PS.base.tb2' where slotname = 'PS.base.b3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 265 +insert into PHone values ('PH.fax001', 'Canon fax', 'WS.001.2a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 266 +update PSlot set slotlink = 'PS.base.ta2' where slotname = 'PS.base.a3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 267 +|-- +-- Install a hub at one of the patchfields, plug a computers +-- ethernet interface into the wall and patch it to the hub. +|-- +insert into Hub values ('base.hub1', 'Patchfield PF0_1 hub', 16) +-- +TABLE: name="hub" schema="" table="hub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +insert into System values ('orion', 'PC') +-- +TABLE: name="system" schema="" table="system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +insert into IFace values ('IF', 'orion', 'eth0', 'WS.002.1b') +-- +TABLE: name="iface" schema="" table="iface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 270 +update PSlot set slotlink = 'HS.base.hub1.1' where slotname = 'PS.base.b2' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 271 +|-- +-- Now we take a look at the patchfield +|-- +select * from PField_v1 where pfname = 'PF0_1' order by slotname +-- +TABLE: name="pfield_v1" schema="" table="pfield_v1" ctx=Select +FILTER: schema="" table="" column="pfname" +STMT: SelectStmt +== 272 +select * from PField_v1 where pfname = 'PF0_2' order by slotname +-- +TABLE: name="pfield_v1" schema="" table="pfield_v1" ctx=Select +FILTER: schema="" table="" column="pfname" +STMT: SelectStmt +== 273 +|-- +-- Finally we want errors +|-- +insert into PField values ('PF1_1', 'should fail due to unique index') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 274 +update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 275 +update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 276 +update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 277 +update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +== 278 +insert into HSlot values ('HS', 'base.hub1', 1, '') +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 279 +insert into HSlot values ('HS', 'base.hub1', 20, '') +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +delete from HSlot +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DML +STMT: DeleteStmt +== 281 +insert into IFace values ('IF', 'notthere', 'eth0', '') +-- +TABLE: name="iface" schema="" table="iface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 282 +insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', '') +-- +TABLE: name="iface" schema="" table="iface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +|-- +-- The following tests are unrelated to the scenario outlined above; +-- they merely exercise specific parts of PL/pgSQL +|-- + +|-- +-- Test recursion, per bug report 7-Sep-01 +|-- +CREATE FUNCTION recursion_test(int,int) RETURNS text AS ' +DECLARE rslt text; +BEGIN + IF $1 <= 0 THEN + rslt = CAST($2 AS TEXT); + ELSE + rslt = CAST($1 AS TEXT) || '','' || recursion_test($1 - 1, $2); + END IF; + RETURN rslt; +END;' LANGUAGE plpgsql +-- +FUNCTION: name="recursion_test" function="recursion_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 284 +SELECT recursion_test(4,3) +-- +FUNCTION: name="recursion_test" function="recursion_test" schema="" ctx=Call +STMT: SelectStmt +== 285 +|-- +-- Test the FOUND magic variable +|-- +CREATE TABLE found_test_tbl (a int) +-- +TABLE: name="found_test_tbl" schema="" table="found_test_tbl" ctx=DDL +STMT: CreateStmt +== 286 +create function test_found() + returns boolean as ' + declare + begin + insert into found_test_tbl values (1); + if FOUND then + insert into found_test_tbl values (2); + end if; + + update found_test_tbl set a = 100 where a = 1; + if FOUND then + insert into found_test_tbl values (3); + end if; + + delete from found_test_tbl where a = 9999; -- matches no rows + if not FOUND then + insert into found_test_tbl values (4); + end if; + + for i in 1 .. 10 loop + -- no need to do anything + end loop; + if FOUND then + insert into found_test_tbl values (5); + end if; + + -- never executes the loop + for i in 2 .. 1 loop + -- no need to do anything + end loop; + if not FOUND then + insert into found_test_tbl values (6); + end if; + return true; + end;' language plpgsql +-- +FUNCTION: name="test_found" function="test_found" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 287 +select test_found() +-- +FUNCTION: name="test_found" function="test_found" schema="" ctx=Call +STMT: SelectStmt +== 288 +select * from found_test_tbl +-- +TABLE: name="found_test_tbl" schema="" table="found_test_tbl" ctx=Select +STMT: SelectStmt +== 289 +|-- +-- Test set-returning functions for PL/pgSQL +|-- + +create function test_table_func_rec() returns setof found_test_tbl as ' +DECLARE + rec RECORD; +BEGIN + FOR rec IN select * from found_test_tbl LOOP + RETURN NEXT rec; + END LOOP; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_table_func_rec" function="test_table_func_rec" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 290 +select * from test_table_func_rec() +-- +FUNCTION: name="test_table_func_rec" function="test_table_func_rec" schema="" ctx=Call +STMT: SelectStmt +== 291 +create function test_table_func_row() returns setof found_test_tbl as ' +DECLARE + row found_test_tbl%ROWTYPE; +BEGIN + FOR row IN select * from found_test_tbl LOOP + RETURN NEXT row; + END LOOP; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_table_func_row" function="test_table_func_row" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 292 +select * from test_table_func_row() +-- +FUNCTION: name="test_table_func_row" function="test_table_func_row" schema="" ctx=Call +STMT: SelectStmt +== 293 +create function test_ret_set_scalar(int,int) returns setof int as ' +DECLARE + i int; +BEGIN + FOR i IN $1 .. $2 LOOP + RETURN NEXT i + 1; + END LOOP; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_ret_set_scalar" function="test_ret_set_scalar" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 294 +select * from test_ret_set_scalar(1,10) +-- +FUNCTION: name="test_ret_set_scalar" function="test_ret_set_scalar" schema="" ctx=Call +STMT: SelectStmt +== 295 +create function test_ret_set_rec_dyn(int) returns setof record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN NEXT retval; + RETURN NEXT retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN NEXT retval; + RETURN NEXT retval; + END IF; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_ret_set_rec_dyn" function="test_ret_set_rec_dyn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 296 +SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int) +-- +FUNCTION: name="test_ret_set_rec_dyn" function="test_ret_set_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +== 297 +SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text) +-- +FUNCTION: name="test_ret_set_rec_dyn" function="test_ret_set_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +== 298 +create function test_ret_rec_dyn(int) returns record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN retval; + END IF; +END;' language plpgsql +-- +FUNCTION: name="test_ret_rec_dyn" function="test_ret_rec_dyn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 299 +SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int) +-- +FUNCTION: name="test_ret_rec_dyn" function="test_ret_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +== 300 +SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text) +-- +FUNCTION: name="test_ret_rec_dyn" function="test_ret_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +== 301 +|-- +-- Test some simple polymorphism cases. +|-- + +create function f1(x anyelement) returns anyelement as $$ +begin + return x + 1; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 302 +select f1(42) as int, f1(4.5) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 303 +select f1(point(3,4)) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 304 +-- fail for lack of + operator + +drop function f1(x anyelement) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 305 +create function f1(x anyelement) returns anyarray as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 306 +select f1(42) as int, f1(4.5) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 307 +drop function f1(x anyelement) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 308 +create function f1(x anyarray) returns anyelement as $$ +begin + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 309 +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 310 +select f1(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 311 +-- fail, can't infer element type + +drop function f1(x anyarray) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 312 +create function f1(x anyarray) returns anyarray as $$ +begin + return x; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 313 +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 314 +select f1(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 315 +-- fail, can't infer element type + +drop function f1(x anyarray) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 316 +-- fail, can't infer type: +create function f1(x anyelement) returns anyrange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 317 +create function f1(x anyrange) returns anyarray as $$ +begin + return array[lower(x), upper(x)]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 318 +select f1(int4range(42, 49)) as int, f1(float8range(4.5, 7.8)) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 319 +drop function f1(x anyrange) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 320 +create function f1(x anycompatible, y anycompatible) returns anycompatiblearray as $$ +begin + return array[x, y]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 321 +select f1(2, 4) as int, f1(2, 4.5) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 322 +drop function f1(x anycompatible, y anycompatible) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 323 +create function f1(x anycompatiblerange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ +begin + return array[lower(x), upper(x), y, z]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 324 +select f1(int4range(42, 49), 11, 2::smallint) as int, f1(float8range(4.5, 7.8), 7.8, 11::real) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 325 +select f1(int4range(42, 49), 11, 4.5) as fail +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 326 +-- range type doesn't fit + +drop function f1(x anycompatiblerange, y anycompatible, z anycompatible) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 327 +-- fail, can't infer type: +create function f1(x anycompatible) returns anycompatiblerange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 328 +create function f1(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ +begin + return x; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 329 +select f1(int4range(42, 49), array[11]) as int, f1(float8range(4.5, 7.8), array[7]) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 330 +drop function f1(x anycompatiblerange, y anycompatiblearray) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 331 +create function f1(a anyelement, b anyarray, + c anycompatible, d anycompatible, + OUT x anyarray, OUT y anycompatiblearray) +as $$ +begin + x := a || b; + y := array[c, d]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 332 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 333 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2], point(1,2), point(3,4)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 334 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, '{1,2}', point(1,2), '(3,4)') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 335 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2.2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 336 +-- fail + +drop function f1(a anyelement, b anyarray, + c anycompatible, d anycompatible) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 337 +|-- +-- Test handling of OUT parameters, including polymorphic cases. +-- Note that RETURN is optional with OUT params; we try both ways. +|-- + +-- wrong way to do it: +create function f1(in i int, out j int) returns int as $$ +begin + return i+1; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 338 +create function f1(in i int, out j int) as $$ +begin + j := i+1; + return; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 339 +select f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 340 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 341 +create or replace function f1(inout i int) as $$ +begin + i := i+1; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 342 +select f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 343 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 344 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 345 +create function f1(in i int, out j int) returns setof int as $$ +begin + j := i+1; + return next; + j := i+2; + return next; + return; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 346 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 347 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 348 +create function f1(in i int, out j int, out k text) as $$ +begin + j := i; + j := j+1; + k := 'foo'; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 349 +select f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 350 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 351 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 352 +create function f1(in i int, out j int, out k text) returns setof record as $$ +begin + j := i+1; + k := 'foo'; + return next; + j := j+1; + k := 'foot'; + return next; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 353 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +== 354 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +== 355 +create function duplic(in i anyelement, out j anyelement, out k anyarray) as $$ +begin + j := i; + k := array[j,j]; + return; +end$$ language plpgsql +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 356 +select * from duplic(42) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +STMT: SelectStmt +== 357 +select * from duplic('foo'::text) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +STMT: SelectStmt +== 358 +drop function duplic(anyelement) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: DropStmt +== 359 +create function duplic(in i anycompatiblerange, out j anycompatible, out k anycompatiblearray) as $$ +begin + j := lower(i); + k := array[lower(i),upper(i)]; + return; +end$$ language plpgsql +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 360 +select * from duplic(int4range(42,49)) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 361 +select * from duplic(textrange('aaa', 'bbb')) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 362 +drop function duplic(anycompatiblerange) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: DropStmt +== 363 +|-- +-- test PERFORM +|-- + +create table perform_test ( + a INT, + b INT +) +-- +TABLE: name="perform_test" schema="" table="perform_test" ctx=DDL +STMT: CreateStmt +== 364 +create function perform_simple_func(int) returns boolean as ' +BEGIN + IF $1 < 20 THEN + INSERT INTO perform_test VALUES ($1, $1 + 10); + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;' language plpgsql +-- +FUNCTION: name="perform_simple_func" function="perform_simple_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 365 +create function perform_test_func() returns void as ' +BEGIN + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + PERFORM perform_simple_func(5); + + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + PERFORM perform_simple_func(50); + + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + RETURN; +END;' language plpgsql +-- +FUNCTION: name="perform_test_func" function="perform_test_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 366 +SELECT perform_test_func() +-- +FUNCTION: name="perform_test_func" function="perform_test_func" schema="" ctx=Call +STMT: SelectStmt +== 367 +SELECT * FROM perform_test +-- +TABLE: name="perform_test" schema="" table="perform_test" ctx=Select +STMT: SelectStmt +== 368 +drop table perform_test +-- +TABLE: name="perform_test" schema="" table="perform_test" ctx=DDL +STMT: DropStmt +== 369 +|-- +-- Test proper snapshot handling in simple expressions +|-- + +create temp table users(login text, id serial) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +== 370 +create function sp_id_user(a_login text) returns int as $$ +declare x int; +begin + select into x id from users where login = a_login; + if found then return x; end if; + return 0; +end$$ language plpgsql stable +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 371 +insert into users values('user1') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 372 +select sp_id_user('user1') +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=Call +STMT: SelectStmt +== 373 +select sp_id_user('userx') +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=Call +STMT: SelectStmt +== 374 +create function sp_add_user(a_login text) returns int as $$ +declare my_id_user int; +begin + my_id_user = sp_id_user( a_login ); + IF my_id_user > 0 THEN + RETURN -1; -- error code for existing user + END IF; + INSERT INTO users ( login ) VALUES ( a_login ); + my_id_user = sp_id_user( a_login ); + IF my_id_user = 0 THEN + RETURN -2; -- error code for insertion failure + END IF; + RETURN my_id_user; +end$$ language plpgsql +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 375 +select sp_add_user('user1') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +== 376 +select sp_add_user('user2') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +== 377 +select sp_add_user('user2') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +== 378 +select sp_add_user('user3') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +== 379 +select sp_add_user('user3') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +== 380 +drop function sp_add_user(text) +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=DDL +STMT: DropStmt +== 381 +drop function sp_id_user(text) +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=DDL +STMT: DropStmt +== 382 +|-- +-- tests for refcursors +|-- +create table rc_test (a int, b int) +-- +TABLE: name="rc_test" schema="" table="rc_test" ctx=DDL +STMT: CreateStmt +== 383 +copy rc_test from stdin +-- +TABLE: name="rc_test" schema="" table="rc_test" ctx=Select +STMT: CopyStmt +== 384 +create function return_unnamed_refcursor() returns refcursor as $$ +declare + rc refcursor; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="return_unnamed_refcursor" function="return_unnamed_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 385 +create function use_refcursor(rc refcursor) returns int as $$ +declare + rc refcursor; + x record; +begin + rc := return_unnamed_refcursor(); + fetch next from rc into x; + return x.a; +end +$$ language plpgsql +-- +FUNCTION: name="use_refcursor" function="use_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 386 +select use_refcursor(return_unnamed_refcursor()) +-- +FUNCTION: name="use_refcursor" function="use_refcursor" schema="" ctx=Call +FUNCTION: name="return_unnamed_refcursor" function="return_unnamed_refcursor" schema="" ctx=Call +STMT: SelectStmt +== 387 +create function return_refcursor(rc refcursor) returns refcursor as $$ +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="return_refcursor" function="return_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 388 +create function refcursor_test1(refcursor) returns refcursor as $$ +begin + perform return_refcursor($1); + return $1; +end +$$ language plpgsql +-- +FUNCTION: name="refcursor_test1" function="refcursor_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 389 +begin +-- +STMT: TransactionStmt +== 390 +select refcursor_test1('test1') +-- +FUNCTION: name="refcursor_test1" function="refcursor_test1" schema="" ctx=Call +STMT: SelectStmt +== 391 +fetch next in test1 +-- +STMT: FetchStmt +== 392 +select refcursor_test1('test2') +-- +FUNCTION: name="refcursor_test1" function="refcursor_test1" schema="" ctx=Call +STMT: SelectStmt +== 393 +fetch all from test2 +-- +STMT: FetchStmt +== 394 +commit +-- +STMT: TransactionStmt +== 395 +-- should fail +fetch next from test1 +-- +STMT: FetchStmt +== 396 +create function refcursor_test2(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; + nonsense record; +begin + open c1($1, $2); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="refcursor_test2" function="refcursor_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 397 +select refcursor_test2(20000, 20000) as "Should be false", + refcursor_test2(20, 20) as "Should be true" +-- +FUNCTION: name="refcursor_test2" function="refcursor_test2" schema="" ctx=Call +FUNCTION: name="refcursor_test2" function="refcursor_test2" schema="" ctx=Call +STMT: SelectStmt +== 398 +-- should fail +create function constant_refcursor() returns refcursor as $$ +declare + rc constant refcursor; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 399 +select constant_refcursor() +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=Call +STMT: SelectStmt +== 400 +-- but it's okay like this +create or replace function constant_refcursor() returns refcursor as $$ +declare + rc constant refcursor := 'my_cursor_name'; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 401 +select constant_refcursor() +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=Call +STMT: SelectStmt +== 402 +|-- +-- tests for cursors with named parameter arguments +|-- +create function namedparmcursor_test1(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param12 int) for select * from rc_test where a > param1 and b > param12; + nonsense record; +begin + open c1(param12 := $2, param1 := $1); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test1" function="namedparmcursor_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 403 +select namedparmcursor_test1(20000, 20000) as "Should be false", + namedparmcursor_test1(20, 20) as "Should be true" +-- +FUNCTION: name="namedparmcursor_test1" function="namedparmcursor_test1" schema="" ctx=Call +FUNCTION: name="namedparmcursor_test1" function="namedparmcursor_test1" schema="" ctx=Call +STMT: SelectStmt +== 404 +-- mixing named and positional argument notations +create function namedparmcursor_test2(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; + nonsense record; +begin + open c1(param1 := $1, $2); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test2" function="namedparmcursor_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 405 +select namedparmcursor_test2(20, 20) +-- +FUNCTION: name="namedparmcursor_test2" function="namedparmcursor_test2" schema="" ctx=Call +STMT: SelectStmt +== 406 +-- mixing named and positional: param2 is given twice, once in named notation +-- and second time in positional notation. Should throw an error at parse time +create function namedparmcursor_test3() returns void as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; +begin + open c1(param2 := 20, 21); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test3" function="namedparmcursor_test3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 407 +-- mixing named and positional: same as previous test, but param1 is duplicated +create function namedparmcursor_test4() returns void as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; +begin + open c1(20, param1 := 21); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test4" function="namedparmcursor_test4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 408 +-- duplicate named parameter, should throw an error at parse time +create function namedparmcursor_test5() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77, p2 := 42); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test5" function="namedparmcursor_test5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 409 +-- not enough parameters, should throw an error at parse time +create function namedparmcursor_test6() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test6" function="namedparmcursor_test6" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 410 +-- division by zero runtime error, the context given in the error message +-- should be sensible +create function namedparmcursor_test7() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77, p1 := 42/0); +end $$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test7" function="namedparmcursor_test7" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 411 +select namedparmcursor_test7() +-- +FUNCTION: name="namedparmcursor_test7" function="namedparmcursor_test7" schema="" ctx=Call +STMT: SelectStmt +== 412 +-- check that line comments work correctly within the argument list +-- (this used to require a special hack in the code; it no longer does, +-- but let's keep the test anyway) +create function namedparmcursor_test8() returns int4 as $$ +declare + c1 cursor (p1 int, p2 int) for + select count(*) from tenk1 where thousand = p1 and tenthous = p2; + n int4; +begin + open c1 (77 -- test + , 42); + fetch c1 into n; + return n; +end $$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test8" function="namedparmcursor_test8" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 413 +select namedparmcursor_test8() +-- +FUNCTION: name="namedparmcursor_test8" function="namedparmcursor_test8" schema="" ctx=Call +STMT: SelectStmt +== 414 +-- cursor parameter name can match plpgsql variable or unreserved keyword +create function namedparmcursor_test9(p1 int) returns int4 as $$ +declare + c1 cursor (p1 int, p2 int, debug int) for + select count(*) from tenk1 where thousand = p1 and tenthous = p2 + and four = debug; + p2 int4 := 1006; + n int4; +begin + open c1 (p1 := p1, p2 := p2, debug := 2); + fetch c1 into n; + return n; +end $$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test9" function="namedparmcursor_test9" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 415 +select namedparmcursor_test9(6) +-- +FUNCTION: name="namedparmcursor_test9" function="namedparmcursor_test9" schema="" ctx=Call +STMT: SelectStmt +== 416 +|-- +-- tests for "raise" processing +|-- +create function raise_test1(int) returns int as $$ +begin + raise notice 'This message has too many parameters!', $1; + return $1; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test1" function="raise_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 417 +create function raise_test2(int) returns int as $$ +begin + raise notice 'This message has too few parameters: %, %, %', $1, $1; + return $1; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test2" function="raise_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 418 +create function raise_test3(int) returns int as $$ +begin + raise notice 'This message has no parameters (despite having %% signs in it)!'; + return $1; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test3" function="raise_test3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 419 +select raise_test3(1) +-- +FUNCTION: name="raise_test3" function="raise_test3" schema="" ctx=Call +STMT: SelectStmt +== 420 +-- Test re-RAISE inside a nested exception block. This case is allowed +-- by Oracle's PL/SQL but was handled differently by PG before 9.1. + +CREATE FUNCTION reraise_test() RETURNS void AS $$ +BEGIN + BEGIN + RAISE syntax_error; + EXCEPTION + WHEN syntax_error THEN + BEGIN + raise notice 'exception % thrown in inner block, reraising', sqlerrm; + RAISE; + EXCEPTION + WHEN OTHERS THEN + raise notice 'RIGHT - exception % caught in inner block', sqlerrm; + END; + END; +EXCEPTION + WHEN OTHERS THEN + raise notice 'WRONG - exception % caught in outer block', sqlerrm; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="reraise_test" function="reraise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 421 +SELECT reraise_test() +-- +FUNCTION: name="reraise_test" function="reraise_test" schema="" ctx=Call +STMT: SelectStmt +== 422 +|-- +-- reject function definitions that contain malformed SQL queries at +-- compile-time, where possible +|-- +create function bad_sql1() returns int as $$ +declare a int; +begin + a := 5; + Johnny Yuma; + a := 10; + return a; +end$$ language plpgsql +-- +FUNCTION: name="bad_sql1" function="bad_sql1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 423 +create function bad_sql2() returns int as $$ +declare r record; +begin + for r in select I fought the law, the law won LOOP + raise notice 'in loop'; + end loop; + return 5; +end;$$ language plpgsql +-- +FUNCTION: name="bad_sql2" function="bad_sql2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 424 +-- a RETURN expression is mandatory, except for void-returning +-- functions, where it is not allowed +create function missing_return_expr() returns int as $$ +begin + return ; +end;$$ language plpgsql +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 425 +create function void_return_expr() returns void as $$ +begin + return 5; +end;$$ language plpgsql +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 426 +-- VOID functions are allowed to omit RETURN +create function void_return_expr() returns void as $$ +begin + perform 2+2; +end;$$ language plpgsql +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 427 +select void_return_expr() +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=Call +STMT: SelectStmt +== 428 +-- but ordinary functions are not +create function missing_return_expr() returns int as $$ +begin + perform 2+2; +end;$$ language plpgsql +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 429 +select missing_return_expr() +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=Call +STMT: SelectStmt +== 430 +drop function void_return_expr() +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=DDL +STMT: DropStmt +== 431 +drop function missing_return_expr() +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=DDL +STMT: DropStmt +== 432 +|-- +-- EXECUTE ... INTO test +|-- + +create table eifoo (i integer, y integer) +-- +TABLE: name="eifoo" schema="" table="eifoo" ctx=DDL +STMT: CreateStmt +== 433 +create type eitype as (i integer, y integer) +-- +STMT: CompositeTypeStmt +== 434 +create or replace function execute_into_test(varchar) returns record as $$ +declare + _r record; + _rt eifoo%rowtype; + _v eitype; + i int; + j int; + k int; +begin + execute 'insert into '||$1||' values(10,15)'; + execute 'select (row).* from (select row(10,1)::eifoo) s' into _r; + raise notice '% %', _r.i, _r.y; + execute 'select * from '||$1||' limit 1' into _rt; + raise notice '% %', _rt.i, _rt.y; + execute 'select *, 20 from '||$1||' limit 1' into i, j, k; + raise notice '% % %', i, j, k; + execute 'select 1,2' into _v; + return _v; +end; $$ language plpgsql +-- +FUNCTION: name="execute_into_test" function="execute_into_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 435 +select execute_into_test('eifoo') +-- +FUNCTION: name="execute_into_test" function="execute_into_test" schema="" ctx=Call +STMT: SelectStmt +== 436 +drop table eifoo cascade +-- +TABLE: name="eifoo" schema="" table="eifoo" ctx=DDL +STMT: DropStmt +== 437 +drop type eitype cascade +-- +STMT: DropStmt +== 438 +|-- +-- SQLSTATE and SQLERRM test +|-- + +create function excpt_test1() returns void as $$ +begin + raise notice '% %', sqlstate, sqlerrm; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test1" function="excpt_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 439 +-- should fail: SQLSTATE and SQLERRM are only in defined EXCEPTION +-- blocks +select excpt_test1() +-- +FUNCTION: name="excpt_test1" function="excpt_test1" schema="" ctx=Call +STMT: SelectStmt +== 440 +create function excpt_test2() returns void as $$ +begin + begin + begin + raise notice '% %', sqlstate, sqlerrm; + end; + end; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test2" function="excpt_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 441 +-- should fail +select excpt_test2() +-- +FUNCTION: name="excpt_test2" function="excpt_test2" schema="" ctx=Call +STMT: SelectStmt +== 442 +create function excpt_test3() returns void as $$ +begin + begin + raise exception 'user exception'; + exception when others then + raise notice 'caught exception % %', sqlstate, sqlerrm; + begin + raise notice '% %', sqlstate, sqlerrm; + perform 10/0; + exception + when substring_error then + -- this exception handler shouldn't be invoked + raise notice 'unexpected exception: % %', sqlstate, sqlerrm; + when division_by_zero then + raise notice 'caught exception % %', sqlstate, sqlerrm; + end; + raise notice '% %', sqlstate, sqlerrm; + end; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test3" function="excpt_test3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 443 +select excpt_test3() +-- +FUNCTION: name="excpt_test3" function="excpt_test3" schema="" ctx=Call +STMT: SelectStmt +== 444 +create function excpt_test4() returns text as $$ +begin + begin perform 1/0; + exception when others then return sqlerrm; end; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test4" function="excpt_test4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 445 +select excpt_test4() +-- +FUNCTION: name="excpt_test4" function="excpt_test4" schema="" ctx=Call +STMT: SelectStmt +== 446 +drop function excpt_test1() +-- +FUNCTION: name="excpt_test1" function="excpt_test1" schema="" ctx=DDL +STMT: DropStmt +== 447 +drop function excpt_test2() +-- +FUNCTION: name="excpt_test2" function="excpt_test2" schema="" ctx=DDL +STMT: DropStmt +== 448 +drop function excpt_test3() +-- +FUNCTION: name="excpt_test3" function="excpt_test3" schema="" ctx=DDL +STMT: DropStmt +== 449 +drop function excpt_test4() +-- +FUNCTION: name="excpt_test4" function="excpt_test4" schema="" ctx=DDL +STMT: DropStmt +== 450 +-- parameters of raise stmt can be expressions +create function raise_exprs() returns void as $$ +declare + a integer[] = '{10,20,30}'; + c varchar = 'xyz'; + i integer; +begin + i := 2; + raise notice '%; %; %; %; %; %', a, a[i], c, (select c || 'abc'), row(10,'aaa',NULL,30), NULL; +end;$$ language plpgsql +-- +FUNCTION: name="raise_exprs" function="raise_exprs" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 451 +select raise_exprs() +-- +FUNCTION: name="raise_exprs" function="raise_exprs" schema="" ctx=Call +STMT: SelectStmt +== 452 +drop function raise_exprs() +-- +FUNCTION: name="raise_exprs" function="raise_exprs" schema="" ctx=DDL +STMT: DropStmt +== 453 +-- regression test: verify that multiple uses of same plpgsql datum within +-- a SQL command all get mapped to the same $n parameter. The return value +-- of the SELECT is not important, we only care that it doesn't fail with +-- a complaint about an ungrouped column reference. +create function multi_datum_use(p1 int) returns bool as $$ +declare + x int; + y int; +begin + select into x,y unique1/p1, unique1/$1 from tenk1 group by unique1/p1; + return x = y; +end$$ language plpgsql +-- +FUNCTION: name="multi_datum_use" function="multi_datum_use" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 454 +select multi_datum_use(42) +-- +FUNCTION: name="multi_datum_use" function="multi_datum_use" schema="" ctx=Call +STMT: SelectStmt +== 455 +|-- +-- Test STRICT limiter in both planned and EXECUTE invocations. +-- Note that a data-modifying query is quasi strict (disallow multi rows) +-- by default in the planned case, but not in EXECUTE. +|-- + +create temp table foo (f1 int, f2 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 456 +insert into foo values (1,2), (3,4) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 457 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + insert into foo values(5,6) returning * into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 458 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 459 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail due to implicit strict + insert into foo values(7,8),(9,10) returning * into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 460 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 461 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + execute 'insert into foo values(5,6) returning *' into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 462 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 463 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- this should work since EXECUTE isn't as picky + execute 'insert into foo values(7,8),(9,10) returning *' into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 464 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 465 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 466 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + select * from foo where f1 = 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 467 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 468 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, no rows + select * from foo where f1 = 0 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 469 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 470 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, too many rows + select * from foo where f1 > 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 471 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 472 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + execute 'select * from foo where f1 = 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 473 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 474 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, no rows + execute 'select * from foo where f1 = 0' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 475 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 476 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, too many rows + execute 'select * from foo where f1 > 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 477 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 478 +drop function stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: DropStmt +== 479 +-- test printing parameters after failure due to STRICT + +set plpgsql.print_strict_params to true +-- +STMT: VariableSetStmt +== 480 +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- no rows + select * from foo where f1 = p1 and f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 481 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 482 +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := $a$'Valame Dios!' dijo Sancho; 'no le dije yo a vuestra merced que mirase bien lo que hacia?'$a$; +begin + -- no rows + select * from foo where f1 = p1 and f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 483 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 484 +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 485 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 486 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows, no params + select * from foo where f1 > 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 487 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 488 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- no rows + execute 'select * from foo where f1 = $1 or f1::text = $2' using 0, 'foo' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 489 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 490 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows + execute 'select * from foo where f1 > $1' using 1 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 491 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 492 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows, no parameters + execute 'select * from foo where f1 > 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 493 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 494 +create or replace function stricttest() returns void as $$ +-- override the global +#print_strict_params off +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 495 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 496 +reset plpgsql.print_strict_params +-- +STMT: VariableSetStmt +== 497 +create or replace function stricttest() returns void as $$ +-- override the global +#print_strict_params on +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 498 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +== 499 +-- test warnings and errors +set plpgsql.extra_warnings to 'all' +-- +STMT: VariableSetStmt +== 500 +set plpgsql.extra_warnings to 'none' +-- +STMT: VariableSetStmt +== 501 +set plpgsql.extra_errors to 'all' +-- +STMT: VariableSetStmt +== 502 +set plpgsql.extra_errors to 'none' +-- +STMT: VariableSetStmt +== 503 +-- test warnings when shadowing a variable + +set plpgsql.extra_warnings to 'shadowed_variables' +-- +STMT: VariableSetStmt +== 504 +-- simple shadowing of input and output parameters +create or replace function shadowtest(in1 int) + returns table (out1 int) as $$ +declare +in1 int; +out1 int; +begin +end +$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 505 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +== 506 +set plpgsql.extra_warnings to 'shadowed_variables' +-- +STMT: VariableSetStmt +== 507 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +== 508 +create or replace function shadowtest(in1 int) + returns table (out1 int) as $$ +declare +in1 int; +out1 int; +begin +end +$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 509 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +== 510 +drop function shadowtest(int) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +== 511 +-- shadowing in a second DECLARE block +create or replace function shadowtest() + returns void as $$ +declare +f1 int; +begin + declare + f1 int; + begin + end; +end$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 512 +drop function shadowtest() +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +== 513 +-- several levels of shadowing +create or replace function shadowtest(in1 int) + returns void as $$ +declare +in1 int; +begin + declare + in1 int; + begin + end; +end$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 514 +drop function shadowtest(int) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +== 515 +-- shadowing in cursor definitions +create or replace function shadowtest() + returns void as $$ +declare +f1 int; +c1 cursor (f1 int) for select 1; +begin +end$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 516 +drop function shadowtest() +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +== 517 +-- test errors when shadowing a variable + +set plpgsql.extra_errors to 'shadowed_variables' +-- +STMT: VariableSetStmt +== 518 +create or replace function shadowtest(f1 int) + returns boolean as $$ +declare f1 int; begin return 1; end $$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 519 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +== 520 +reset plpgsql.extra_errors +-- +STMT: VariableSetStmt +== 521 +reset plpgsql.extra_warnings +-- +STMT: VariableSetStmt +== 522 +create or replace function shadowtest(f1 int) + returns boolean as $$ +declare f1 int; begin return 1; end $$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 523 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +== 524 +-- runtime extra checks +set plpgsql.extra_warnings to 'too_many_rows' +-- +STMT: VariableSetStmt +== 525 +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$ +-- +STMT: DoStmt +== 526 +set plpgsql.extra_errors to 'too_many_rows' +-- +STMT: VariableSetStmt +== 527 +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$ +-- +STMT: DoStmt +== 528 +reset plpgsql.extra_errors +-- +STMT: VariableSetStmt +== 529 +reset plpgsql.extra_warnings +-- +STMT: VariableSetStmt +== 530 +set plpgsql.extra_warnings to 'strict_multi_assignment' +-- +STMT: VariableSetStmt +== 531 +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$ +-- +STMT: DoStmt +== 532 +set plpgsql.extra_errors to 'strict_multi_assignment' +-- +STMT: VariableSetStmt +== 533 +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$ +-- +STMT: DoStmt +== 534 +create table test_01(a int, b int, c int) +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DDL +STMT: CreateStmt +== 535 +alter table test_01 drop column a +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DDL +STMT: AlterTableStmt +== 536 +-- the check is active only when source table is not empty +insert into test_01 values(10,20) +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 537 +do $$ +declare + x int; + y int; +begin + select * from test_01 into x, y; -- should be ok + raise notice 'ok'; + select * from test_01 into x; -- should to fail +end; +$$ +-- +STMT: DoStmt +== 538 +do $$ +declare + t test_01; +begin + select 1, 2 into t; -- should be ok + raise notice 'ok'; + select 1, 2, 3 into t; -- should fail; +end; +$$ +-- +STMT: DoStmt +== 539 +do $$ +declare + t test_01; +begin + select 1 into t; -- should fail; +end; +$$ +-- +STMT: DoStmt +== 540 +drop table test_01 +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DDL +STMT: DropStmt +== 541 +reset plpgsql.extra_errors +-- +STMT: VariableSetStmt +== 542 +reset plpgsql.extra_warnings +-- +STMT: VariableSetStmt +== 543 +-- test scrollable cursor support + +create function sc_test() returns setof integer as $$ +declare + c scroll cursor for select f1 from int4_tbl; + x integer; +begin + open c; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 544 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +== 545 +create or replace function sc_test() returns setof integer as $$ +declare + c no scroll cursor for select f1 from int4_tbl; + x integer; +begin + open c; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 546 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +== 547 +-- fails because of NO SCROLL specification + +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for select f1 from int4_tbl; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 548 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +== 549 +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for execute 'select f1 from int4_tbl'; + fetch last from c into x; + while found loop + return next x; + fetch relative -2 from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 550 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +== 551 +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for execute 'select f1 from int4_tbl'; + fetch last from c into x; + while found loop + return next x; + move backward 2 from c; + fetch relative -1 from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 552 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +== 553 +create or replace function sc_test() returns setof integer as $$ +declare + c cursor for select * from generate_series(1, 10); + x integer; +begin + open c; + loop + move relative 2 in c; + if not found then + exit; + end if; + fetch next from c into x; + if found then + return next x; + end if; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 554 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +== 555 +create or replace function sc_test() returns setof integer as $$ +declare + c cursor for select * from generate_series(1, 10); + x integer; +begin + open c; + move forward all in c; + fetch backward from c into x; + if found then + return next x; + end if; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 556 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +== 557 +drop function sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: DropStmt +== 558 +-- test qualified variable names + +create function pl_qual_names (param1 int) returns void as $$ +<> +declare + param1 int := 1; +begin + <> + declare + param1 int := 2; + begin + raise notice 'param1 = %', param1; + raise notice 'pl_qual_names.param1 = %', pl_qual_names.param1; + raise notice 'outerblock.param1 = %', outerblock.param1; + raise notice 'innerblock.param1 = %', innerblock.param1; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="pl_qual_names" function="pl_qual_names" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 559 +select pl_qual_names(42) +-- +FUNCTION: name="pl_qual_names" function="pl_qual_names" schema="" ctx=Call +STMT: SelectStmt +== 560 +drop function pl_qual_names(int) +-- +FUNCTION: name="pl_qual_names" function="pl_qual_names" schema="" ctx=DDL +STMT: DropStmt +== 561 +-- tests for RETURN QUERY +create function ret_query1(out int, out int) returns setof record as $$ +begin + $1 := -1; + $2 := -2; + return next; + return query select x + 1, x * 10 from generate_series(0, 10) s (x); + return next; +end; +$$ language plpgsql +-- +FUNCTION: name="ret_query1" function="ret_query1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 562 +select * from ret_query1() +-- +FUNCTION: name="ret_query1" function="ret_query1" schema="" ctx=Call +STMT: SelectStmt +== 563 +create type record_type as (x text, y int, z boolean) +-- +STMT: CompositeTypeStmt +== 564 +create or replace function ret_query2(lim int) returns setof record_type as $$ +begin + return query select fipshash(s.x::text), s.x, s.x > 0 + from generate_series(-8, lim) s (x) where s.x % 2 = 0; +end; +$$ language plpgsql +-- +FUNCTION: name="ret_query2" function="ret_query2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 565 +select * from ret_query2(8) +-- +FUNCTION: name="ret_query2" function="ret_query2" schema="" ctx=Call +STMT: SelectStmt +== 566 +-- test EXECUTE USING +create function exc_using(int, text) returns int as $$ +declare i int; +begin + for i in execute 'select * from generate_series(1,$1)' using $1+1 loop + raise notice '%', i; + end loop; + execute 'select $2 + $2*3 + length($1)' into i using $2,$1; + return i; +end +$$ language plpgsql +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 567 +select exc_using(5, 'foobar') +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=Call +STMT: SelectStmt +== 568 +drop function exc_using(int, text) +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: DropStmt +== 569 +create or replace function exc_using(int) returns void as $$ +declare + c refcursor; + i int; +begin + open c for execute 'select * from generate_series(1,$1)' using $1+1; + loop + fetch c into i; + exit when not found; + raise notice '%', i; + end loop; + close c; + return; +end; +$$ language plpgsql +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 570 +select exc_using(5) +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=Call +STMT: SelectStmt +== 571 +drop function exc_using(int) +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: DropStmt +== 572 +-- test FOR-over-cursor + +create or replace function forc01() returns void as $$ +declare + c cursor(r1 integer, r2 integer) + for select * from generate_series(r1,r2) i; + c2 cursor + for select * from generate_series(41,43) i; +begin + -- assign portal names to cursors to get stable output + c := 'c'; + c2 := 'c2'; + for r in c(5,7) loop + raise notice '% from %', r.i, c; + end loop; + -- again, to test if cursor was closed properly + for r in c(9,10) loop + raise notice '% from %', r.i, c; + end loop; + -- and test a parameterless cursor + for r in c2 loop + raise notice '% from %', r.i, c2; + end loop; + -- and try it with a hand-assigned name + raise notice 'after loop, c2 = %', c2; + c2 := 'special_name'; + for r in c2 loop + raise notice '% from %', r.i, c2; + end loop; + raise notice 'after loop, c2 = %', c2; + -- and try it with a generated name + -- (which we can't show in the output because it's variable) + c2 := null; + for r in c2 loop + raise notice '%', r.i; + end loop; + raise notice 'after loop, c2 = %', c2; + return; +end; +$$ language plpgsql +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 573 +select forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=Call +STMT: SelectStmt +== 574 +-- try updating the cursor's current row + +create temp table forc_test as + select n as i, n as j from generate_series(1,10) n +-- +TABLE: name="forc_test" schema="" table="forc_test" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 575 +create or replace function forc01() returns void as $$ +declare + c cursor for select * from forc_test; +begin + for r in c loop + raise notice '%, %', r.i, r.j; + update forc_test set i = i * 100, j = r.j * 2 where current of c; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 576 +select forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=Call +STMT: SelectStmt +== 577 +select * from forc_test +-- +TABLE: name="forc_test" schema="" table="forc_test" ctx=Select +STMT: SelectStmt +== 578 +-- same, with a cursor whose portal name doesn't match variable name +create or replace function forc01() returns void as $$ +declare + c refcursor := 'fooled_ya'; + r record; +begin + open c for select * from forc_test; + loop + fetch c into r; + exit when not found; + raise notice '%, %', r.i, r.j; + update forc_test set i = i * 100, j = r.j * 2 where current of c; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 579 +select forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=Call +STMT: SelectStmt +== 580 +select * from forc_test +-- +TABLE: name="forc_test" schema="" table="forc_test" ctx=Select +STMT: SelectStmt +== 581 +drop function forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: DropStmt +== 582 +-- it's okay to re-use a cursor variable name, even when bound + +do $$ +declare cnt int := 0; + c1 cursor for select * from forc_test; +begin + for r1 in c1 loop + declare c1 cursor for select * from forc_test; + begin + for r2 in c1 loop + cnt := cnt + 1; + end loop; + end; + end loop; + raise notice 'cnt = %', cnt; +end $$ +-- +STMT: DoStmt +== 583 +-- fail because cursor has no query bound to it + +create or replace function forc_bad() returns void as $$ +declare + c refcursor; +begin + for r in c loop + raise notice '%', r.i; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="forc_bad" function="forc_bad" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 584 +-- test RETURN QUERY EXECUTE + +create or replace function return_dquery() +returns setof int as $$ +begin + return query execute 'select * from (values(10),(20)) f'; + return query execute 'select * from (values($1),($2)) f' using 40,50; +end; +$$ language plpgsql +-- +FUNCTION: name="return_dquery" function="return_dquery" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 585 +select * from return_dquery() +-- +FUNCTION: name="return_dquery" function="return_dquery" schema="" ctx=Call +STMT: SelectStmt +== 586 +drop function return_dquery() +-- +FUNCTION: name="return_dquery" function="return_dquery" schema="" ctx=DDL +STMT: DropStmt +== 587 +-- test RETURN QUERY with dropped columns + +create table tabwithcols(a int, b int, c int, d int) +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: CreateStmt +== 588 +insert into tabwithcols values(10,20,30,40),(50,60,70,80) +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 589 +create or replace function returnqueryf() +returns setof tabwithcols as $$ +begin + return query select * from tabwithcols; + return query execute 'select * from tabwithcols'; +end; +$$ language plpgsql +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 590 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +== 591 +alter table tabwithcols drop column b +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: AlterTableStmt +== 592 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +== 593 +alter table tabwithcols drop column d +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: AlterTableStmt +== 594 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +== 595 +alter table tabwithcols add column d int +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: AlterTableStmt +== 596 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +== 597 +drop function returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=DDL +STMT: DropStmt +== 598 +drop table tabwithcols +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: DropStmt +== 599 +|-- +-- Tests for composite-type results +|-- + +create type compostype as (x int, y varchar) +-- +STMT: CompositeTypeStmt +== 600 +-- test: use of variable of composite type in return statement +create or replace function compos() returns compostype as $$ +declare + v compostype; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 601 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 602 +-- test: use of variable of record type in return statement +create or replace function compos() returns compostype as $$ +declare + v record; +begin + v := (1, 'hello'::varchar); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 603 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 604 +-- test: use of row expr in return statement +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello'::varchar); +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 605 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 606 +-- this does not work currently (no implicit casting) +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello'); +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 607 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 608 +-- ... but this does +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello')::compostype; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 609 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 610 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +== 611 +-- test: return a row expr as record. +create or replace function composrec() returns record as $$ +declare + v record; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 612 +select composrec() +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=Call +STMT: SelectStmt +== 613 +-- test: return row expr in return statement. +create or replace function composrec() returns record as $$ +begin + return (1, 'hello'); +end; +$$ language plpgsql +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 614 +select composrec() +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=Call +STMT: SelectStmt +== 615 +drop function composrec() +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=DDL +STMT: DropStmt +== 616 +-- test: row expr in RETURN NEXT statement. +create or replace function compos() returns setof compostype as $$ +begin + for i in 1..3 + loop + return next (1, 'hello'::varchar); + end loop; + return next null::compostype; + return next (2, 'goodbye')::compostype; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 617 +select * from compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 618 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +== 619 +-- test: use invalid expr in return statement. +create or replace function compos() returns compostype as $$ +begin + return 1 + 1; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 620 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 621 +-- RETURN variable is a different code path ... +create or replace function compos() returns compostype as $$ +declare x int := 42; +begin + return x; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 622 +select * from compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 623 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +== 624 +-- test: invalid use of composite variable in scalar-returning function +create or replace function compos() returns int as $$ +declare + v compostype; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 625 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 626 +-- test: invalid use of composite expression in scalar-returning function +create or replace function compos() returns int as $$ +begin + return (1, 'hello')::compostype; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 627 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +== 628 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +== 629 +drop type compostype +-- +STMT: DropStmt +== 630 +|-- +-- Tests for 8.4's new RAISE features +|-- + +create or replace function raise_test() returns void as $$ +begin + raise notice '% % %', 1, 2, 3 + using errcode = '55001', detail = 'some detail info', hint = 'some hint'; + raise '% % %', 1, 2, 3 + using errcode = 'division_by_zero', detail = 'some detail info'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 631 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 632 +-- Since we can't actually see the thrown SQLSTATE in default psql output, +-- test it like this; this also tests re-RAISE + +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = 'division_by_zero', detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 633 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 634 +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = '1234F', detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 635 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 636 +-- SQLSTATE specification in WHEN +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = '1234F', detail = 'some detail info'; + exception + when sqlstate '1234F' then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 637 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 638 +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 639 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 640 +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 641 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 642 +create or replace function raise_test() returns void as $$ +begin + raise sqlstate '1234F'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 643 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 644 +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using message = 'custom' || ' message'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 645 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 646 +create or replace function raise_test() returns void as $$ +begin + raise using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 647 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 648 +-- conflict on message +create or replace function raise_test() returns void as $$ +begin + raise notice 'some message' using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 649 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 650 +-- conflict on errcode +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 651 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 652 +-- nothing to re-RAISE +create or replace function raise_test() returns void as $$ +begin + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 653 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 654 +-- test access to exception data +create function zero_divide() returns int as $$ +declare v int := 0; +begin + return 10 / v; +end; +$$ language plpgsql parallel safe +-- +FUNCTION: name="zero_divide" function="zero_divide" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 655 +create or replace function raise_test() returns void as $$ +begin + raise exception 'custom exception' + using detail = 'some detail of custom exception', + hint = 'some hint related to custom exception'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 656 +create function stacked_diagnostics_test() returns void as $$ +declare _sqlstate text; + _message text; + _context text; +begin + perform zero_divide(); +exception when others then + get stacked diagnostics + _sqlstate = returned_sqlstate, + _message = message_text, + _context = pg_exception_context; + raise notice 'sqlstate: %, message: %, context: [%]', + _sqlstate, _message, replace(_context, E'\n', ' <- '); +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 657 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +== 658 +create or replace function stacked_diagnostics_test() returns void as $$ +declare _detail text; + _hint text; + _message text; +begin + perform raise_test(); +exception when others then + get stacked diagnostics + _message = message_text, + _detail = pg_exception_detail, + _hint = pg_exception_hint; + raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint; +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 659 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +== 660 +-- fail, cannot use stacked diagnostics statement outside handler +create or replace function stacked_diagnostics_test() returns void as $$ +declare _detail text; + _hint text; + _message text; +begin + get stacked diagnostics + _message = message_text, + _detail = pg_exception_detail, + _hint = pg_exception_hint; + raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint; +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 661 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +== 662 +drop function stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: DropStmt +== 663 +-- Test that an error recovery subtransaction is parallel safe + +create function error_trap_test() returns text as $$ +begin + perform zero_divide(); + return 'no error detected!'; +exception when division_by_zero then + return 'division_by_zero detected'; +end; +$$ language plpgsql parallel safe +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 664 +set debug_parallel_query to on +-- +STMT: VariableSetStmt +== 665 +explain (verbose, costs off) select error_trap_test() +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 666 +select error_trap_test() +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=Call +STMT: SelectStmt +== 667 +reset debug_parallel_query +-- +STMT: VariableSetStmt +== 668 +drop function error_trap_test() +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=DDL +STMT: DropStmt +== 669 +drop function zero_divide() +-- +FUNCTION: name="zero_divide" function="zero_divide" schema="" ctx=DDL +STMT: DropStmt +== 670 +-- check cases where implicit SQLSTATE variable could be confused with +-- SQLSTATE as a keyword, cf bug #5524 +create or replace function raise_test() returns void as $$ +begin + perform 1/0; +exception + when sqlstate '22012' then + raise notice using message = sqlstate; + raise sqlstate '22012' using message = 'substitute message'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 671 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +== 672 +drop function raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: DropStmt +== 673 +-- test passing column_name, constraint_name, datatype_name, table_name +-- and schema_name error fields + +create or replace function stacked_diagnostics_test() returns void as $$ +declare _column_name text; + _constraint_name text; + _datatype_name text; + _table_name text; + _schema_name text; +begin + raise exception using + column = '>>some column name<<', + constraint = '>>some constraint name<<', + datatype = '>>some datatype name<<', + table = '>>some table name<<', + schema = '>>some schema name<<'; +exception when others then + get stacked diagnostics + _column_name = column_name, + _constraint_name = constraint_name, + _datatype_name = pg_datatype_name, + _table_name = table_name, + _schema_name = schema_name; + raise notice 'column %, constraint %, type %, table %, schema %', + _column_name, _constraint_name, _datatype_name, _table_name, _schema_name; +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 674 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +== 675 +drop function stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: DropStmt +== 676 +-- test variadic functions + +create or replace function vari(variadic int[]) +returns void as $$ +begin + for i in array_lower($1,1)..array_upper($1,1) loop + raise notice '%', $1[i]; + end loop; end; +$$ language plpgsql +-- +FUNCTION: name="vari" function="vari" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 677 +select vari(1,2,3,4,5) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=Call +STMT: SelectStmt +== 678 +select vari(3,4,5) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=Call +STMT: SelectStmt +== 679 +select vari(variadic array[5,6,7]) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=Call +STMT: SelectStmt +== 680 +drop function vari(int[]) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=DDL +STMT: DropStmt +== 681 +-- coercion test +create or replace function pleast(variadic numeric[]) +returns numeric as $$ +declare aux numeric = $1[array_lower($1,1)]; +begin + for i in array_lower($1,1)+1..array_upper($1,1) loop + if $1[i] < aux then aux := $1[i]; end if; + end loop; + return aux; +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 682 +select pleast(10,1,2,3,-16) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +== 683 +select pleast(10.2,2.2,-1.1) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +== 684 +select pleast(10.2,10, -20) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +== 685 +select pleast(10,20, -1.0) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +== 686 +-- in case of conflict, non-variadic version is preferred +create or replace function pleast(numeric) +returns numeric as $$ +begin + raise notice 'non-variadic function called'; + return $1; +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 687 +select pleast(10) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +== 688 +drop function pleast(numeric[]) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: DropStmt +== 689 +drop function pleast(numeric) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: DropStmt +== 690 +-- test table functions + +create function tftest(int) returns table(a int, b int) as $$ +begin + return query select $1, $1+i from generate_series(1,5) g(i); +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 691 +select * from tftest(10) +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=Call +STMT: SelectStmt +== 692 +create or replace function tftest(a1 int) returns table(a int, b int) as $$ +begin + a := a1; b := a1 + 1; + return next; + a := a1 * 10; b := a1 * 10 + 1; + return next; +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 693 +select * from tftest(10) +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=Call +STMT: SelectStmt +== 694 +drop function tftest(int) +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: DropStmt +== 695 +create function rttest() +returns setof int as $$ +declare rc int; +begin + return query values(10),(20); + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query select * from (values(10),(20)) f(a) where false; + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query execute 'values(10),(20)'; + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query execute 'select * from (values(10),(20)) f(a) where false'; + get diagnostics rc = row_count; + raise notice '% %', found, rc; +end; +$$ language plpgsql +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 696 +select * from rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=Call +STMT: SelectStmt +== 697 +-- check some error cases, too + +create or replace function rttest() +returns setof int as $$ +begin + return query select 10 into no_such_table; +end; +$$ language plpgsql +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 698 +select * from rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=Call +STMT: SelectStmt +== 699 +create or replace function rttest() +returns setof int as $$ +begin + return query execute 'select 10 into no_such_table'; +end; +$$ language plpgsql +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 700 +select * from rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=Call +STMT: SelectStmt +== 701 +select * from no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=Select +STMT: SelectStmt +== 702 +drop function rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: DropStmt +== 703 +-- Test for proper cleanup at subtransaction exit. This example +-- exposed a bug in PG 8.2. + +CREATE FUNCTION leaker_1(fail BOOL) RETURNS INTEGER AS $$ +DECLARE + v_var INTEGER; +BEGIN + BEGIN + v_var := (leaker_2(fail)).error_code; + EXCEPTION + WHEN others THEN RETURN 0; + END; + RETURN 1; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 704 +CREATE FUNCTION leaker_2(fail BOOL, OUT error_code INTEGER, OUT new_id INTEGER) + RETURNS RECORD AS $$ +BEGIN + IF fail THEN + RAISE EXCEPTION 'fail ...'; + END IF; + error_code := 1; + new_id := 1; + RETURN; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="leaker_2" function="leaker_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 705 +SELECT * FROM leaker_1(false) +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=Call +STMT: SelectStmt +== 706 +SELECT * FROM leaker_1(true) +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=Call +STMT: SelectStmt +== 707 +DROP FUNCTION leaker_1(bool) +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=DDL +STMT: DropStmt +== 708 +DROP FUNCTION leaker_2(bool) +-- +FUNCTION: name="leaker_2" function="leaker_2" schema="" ctx=DDL +STMT: DropStmt +== 709 +-- Test for appropriate cleanup of non-simple expression evaluations +-- (bug in all versions prior to August 2010) + +CREATE FUNCTION nonsimple_expr_test() RETURNS text[] AS $$ +DECLARE + arr text[]; + lr text; + i integer; +BEGIN + arr := array[array['foo','bar'], array['baz', 'quux']]; + lr := 'fool'; + i := 1; + -- use sub-SELECTs to make expressions non-simple + arr[(SELECT i)][(SELECT i+1)] := (SELECT lr); + RETURN arr; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 710 +SELECT nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=Call +STMT: SelectStmt +== 711 +DROP FUNCTION nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: DropStmt +== 712 +CREATE FUNCTION nonsimple_expr_test() RETURNS integer AS $$ +declare + i integer NOT NULL := 0; +begin + begin + i := (SELECT NULL::integer); -- should throw error + exception + WHEN OTHERS THEN + i := (SELECT 1::integer); + end; + return i; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 713 +SELECT nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=Call +STMT: SelectStmt +== 714 +DROP FUNCTION nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: DropStmt +== 715 +|-- +-- Test cases involving recursion and error recovery in simple expressions +-- (bugs in all versions before October 2010). The problems are most +-- easily exposed by mutual recursion between plpgsql and sql functions. +|-- + +create function recurse(float8) returns float8 as +$$ +begin + if ($1 > 0) then + return sql_recurse($1 - 1); + else + return $1; + end if; +end; +$$ language plpgsql +-- +FUNCTION: name="recurse" function="recurse" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 716 +-- "limit" is to prevent this from being inlined +create function sql_recurse(float8) returns float8 as +$$ select recurse($1) limit 1; $$ language sql +-- +FUNCTION: name="sql_recurse" function="sql_recurse" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 717 +select recurse(10) +-- +FUNCTION: name="recurse" function="recurse" schema="" ctx=Call +STMT: SelectStmt +== 718 +create function error1(text) returns text language sql as +$$ SELECT relname::text FROM pg_class c WHERE c.oid = $1::regclass $$ +-- +FUNCTION: name="error1" function="error1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 719 +create function error2(p_name_table text) returns text language plpgsql as $$ +begin + return error1(p_name_table); +end$$ +-- +FUNCTION: name="error2" function="error2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 720 +BEGIN +-- +STMT: TransactionStmt +== 721 +create table public.stuffs (stuff text) +-- +TABLE: name="public.stuffs" schema="public" table="stuffs" ctx=DDL +STMT: CreateStmt +== 722 +SAVEPOINT a +-- +STMT: TransactionStmt +== 723 +select error2('nonexistent.stuffs') +-- +FUNCTION: name="error2" function="error2" schema="" ctx=Call +STMT: SelectStmt +== 724 +ROLLBACK TO a +-- +STMT: TransactionStmt +== 725 +select error2('public.stuffs') +-- +FUNCTION: name="error2" function="error2" schema="" ctx=Call +STMT: SelectStmt +== 726 +rollback +-- +STMT: TransactionStmt +== 727 +drop function error2(p_name_table text) +-- +FUNCTION: name="error2" function="error2" schema="" ctx=DDL +STMT: DropStmt +== 728 +drop function error1(text) +-- +FUNCTION: name="error1" function="error1" schema="" ctx=DDL +STMT: DropStmt +== 729 +-- Test for proper handling of cast-expression caching + +create function sql_to_date(integer) returns date as $$ +select $1::text::date +$$ language sql immutable strict +-- +FUNCTION: name="sql_to_date" function="sql_to_date" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 730 +create cast (integer as date) with function sql_to_date(integer) as assignment +-- +STMT: CreateCastStmt +== 731 +create function cast_invoker(integer) returns date as $$ +begin + return $1; +end$$ language plpgsql +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 732 +select cast_invoker(20150717) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 733 +select cast_invoker(20150718) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 734 +-- second call crashed in pre-release 9.5 + +begin +-- +STMT: TransactionStmt +== 735 +select cast_invoker(20150717) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 736 +select cast_invoker(20150718) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 737 +savepoint s1 +-- +STMT: TransactionStmt +== 738 +select cast_invoker(20150718) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 739 +select cast_invoker(-1) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 740 +-- fails +rollback to savepoint s1 +-- +STMT: TransactionStmt +== 741 +select cast_invoker(20150719) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 742 +select cast_invoker(20150720) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +== 743 +commit +-- +STMT: TransactionStmt +== 744 +drop function cast_invoker(integer) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=DDL +STMT: DropStmt +== 745 +drop function sql_to_date(integer) cascade +-- +FUNCTION: name="sql_to_date" function="sql_to_date" schema="" ctx=DDL +STMT: DropStmt +== 746 +-- Test handling of cast cache inside DO blocks +-- (to check the original crash case, this must be a cast not previously +-- used in this session) + +begin +-- +STMT: TransactionStmt +== 747 +do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$ +-- +STMT: DoStmt +== 748 +do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$ +-- +STMT: DoStmt +== 749 +end +-- +STMT: TransactionStmt +== 750 +-- Test for consistent reporting of error context + +create function fail() returns int language plpgsql as $$ +begin + return 1/0; +end +$$ +-- +FUNCTION: name="fail" function="fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 751 +select fail() +-- +FUNCTION: name="fail" function="fail" schema="" ctx=Call +STMT: SelectStmt +== 752 +select fail() +-- +FUNCTION: name="fail" function="fail" schema="" ctx=Call +STMT: SelectStmt +== 753 +drop function fail() +-- +FUNCTION: name="fail" function="fail" schema="" ctx=DDL +STMT: DropStmt +== 754 +-- Test handling of string literals. + +set standard_conforming_strings = off +-- +STMT: VariableSetStmt +== 755 +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz'; + return 'foo\\bar\041baz'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 756 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +== 757 +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 758 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +== 759 +set standard_conforming_strings = on +-- +STMT: VariableSetStmt +== 760 +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz\'; + return 'foo\\bar\041baz\'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 761 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +== 762 +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 763 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +== 764 +drop function strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: DropStmt +== 765 +-- Test anonymous code blocks. + +DO $$ +DECLARE r record; +BEGIN + FOR r IN SELECT rtrim(roomno) AS roomno, comment FROM Room ORDER BY roomno + LOOP + RAISE NOTICE '%, %', r.roomno, r.comment; + END LOOP; +END$$ +-- +STMT: DoStmt +== 766 +-- these are to check syntax error reporting +DO LANGUAGE plpgsql $$begin return 1; end$$ +-- +STMT: DoStmt +== 767 +DO $$ +DECLARE r record; +BEGIN + FOR r IN SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno + LOOP + RAISE NOTICE '%, %', r.roomno, r.comment; + END LOOP; +END$$ +-- +STMT: DoStmt +== 768 +-- Check handling of errors thrown from/into anonymous code blocks. +do $outer$ +begin + for i in 1..10 loop + begin + execute $ex$ + do $$ + declare x int = 0; + begin + x := 1 / x; + end; + $$; + $ex$; + exception when division_by_zero then + raise notice 'caught division by zero'; + end; + end loop; +end; +$outer$ +-- +STMT: DoStmt +== 769 +-- Check variable scoping -- a var is not available in its own or prior +-- default expressions, but it is available in later ones. + +do $$ +declare x int := x + 1; -- error +begin + raise notice 'x = %', x; +end; +$$ +-- +STMT: DoStmt +== 770 +do $$ +declare y int := x + 1; -- error + x int := 42; +begin + raise notice 'x = %, y = %', x, y; +end; +$$ +-- +STMT: DoStmt +== 771 +do $$ +declare x int := 42; + y int := x + 1; +begin + raise notice 'x = %, y = %', x, y; +end; +$$ +-- +STMT: DoStmt +== 772 +do $$ +declare x int := 42; +begin + declare y int := x + 1; + x int := x + 2; + z int := x * 10; + begin + raise notice 'x = %, y = %, z = %', x, y, z; + end; +end; +$$ +-- +STMT: DoStmt +== 773 +-- Check handling of conflicts between plpgsql vars and table columns. + +set plpgsql.variable_conflict = error +-- +STMT: VariableSetStmt +== 774 +create function conflict_test() returns setof int8_tbl as $$ +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 775 +select * from conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=Call +STMT: SelectStmt +== 776 +create or replace function conflict_test() returns setof int8_tbl as $$ +#variable_conflict use_variable +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 777 +select * from conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=Call +STMT: SelectStmt +== 778 +create or replace function conflict_test() returns setof int8_tbl as $$ +#variable_conflict use_column +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 779 +select * from conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=Call +STMT: SelectStmt +== 780 +drop function conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: DropStmt +== 781 +-- Check that an unreserved keyword can be used as a variable name + +create function unreserved_test() returns int as $$ +declare + forward int := 21; +begin + forward := forward * 2; + return forward; +end +$$ language plpgsql +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 782 +select unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=Call +STMT: SelectStmt +== 783 +create or replace function unreserved_test() returns int as $$ +declare + return int := 42; +begin + return := return + 1; + return return; +end +$$ language plpgsql +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 784 +select unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=Call +STMT: SelectStmt +== 785 +create or replace function unreserved_test() returns int as $$ +declare + comment int := 21; +begin + comment := comment * 2; + comment on function unreserved_test() is 'this is a test'; + return comment; +end +$$ language plpgsql +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 786 +select unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=Call +STMT: SelectStmt +== 787 +select obj_description('unreserved_test()'::regprocedure, 'pg_proc') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +== 788 +drop function unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: DropStmt +== 789 +|-- +-- Test FOREACH over arrays +|-- + +create function foreach_test(anyarray) +returns void as $$ +declare x int; +begin + foreach x in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 790 +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 791 +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 792 +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 793 +-- should fail +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 794 +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 795 +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int[]; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 796 +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 797 +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 798 +-- higher level of slicing +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int[]; +begin + foreach x slice 2 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 799 +-- should fail +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 800 +-- ok +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 801 +select foreach_test(ARRAY[[[1,2]],[[3,4]]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 802 +create type xy_tuple AS (x int, y int) +-- +STMT: CompositeTypeStmt +== 803 +-- iteration over array of records +create or replace function foreach_test(anyarray) +returns void as $$ +declare r record; +begin + foreach r in array $1 + loop + raise notice '%', r; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 804 +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 805 +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 806 +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int; y int; +begin + foreach x, y in array $1 + loop + raise notice 'x = %, y = %', x, y; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 807 +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 808 +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 809 +-- slicing over array of composite types +create or replace function foreach_test(anyarray) +returns void as $$ +declare x xy_tuple[]; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 810 +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 811 +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +== 812 +drop function foreach_test(anyarray) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: DropStmt +== 813 +drop type xy_tuple +-- +STMT: DropStmt +== 814 +|-- +-- Assorted tests for array subscript assignment +|-- + +create temp table rtype (id int, ar text[]) +-- +TABLE: name="rtype" schema="" table="rtype" ctx=DDL +STMT: CreateStmt +== 815 +create function arrayassign1() returns text[] language plpgsql as $$ +declare + r record; +begin + r := row(12, '{foo,bar,baz}')::rtype; + r.ar[2] := 'replace'; + return r.ar; +end$$ +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 816 +select arrayassign1() +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=Call +STMT: SelectStmt +== 817 +select arrayassign1() +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=Call +STMT: SelectStmt +== 818 +-- try again to exercise internal caching + +create domain orderedarray as int[2] + constraint sorted check (value[1] < value[2]) +-- +STMT: CreateDomainStmt +== 819 +select '{1,2}'::orderedarray +-- +STMT: SelectStmt +== 820 +select '{2,1}'::orderedarray +-- +STMT: SelectStmt +== 821 +-- fail + +create function testoa(x1 int, x2 int, x3 int) returns orderedarray +language plpgsql as $$ +declare res orderedarray; +begin + res := array[x1, x2]; + res[2] := x3; + return res; +end$$ +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 822 +select testoa(1,2,3) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +== 823 +select testoa(1,2,3) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +== 824 +-- try again to exercise internal caching +select testoa(2,1,3) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +== 825 +-- fail at initial assign +select testoa(1,2,1) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +== 826 +-- fail at update + +drop function arrayassign1() +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=DDL +STMT: DropStmt +== 827 +drop function testoa(x1 int, x2 int, x3 int) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=DDL +STMT: DropStmt +== 828 +|-- +-- Test handling of expanded arrays +|-- + +create function returns_rw_array(int) returns int[] +language plpgsql as $$ + declare r int[]; + begin r := array[$1, $1]; return r; end; +$$ stable +-- +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 829 +create function consumes_rw_array(int[]) returns int +language plpgsql as $$ + begin return $1[1]; end; +$$ stable +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 830 +select consumes_rw_array(returns_rw_array(42)) +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: SelectStmt +== 831 +-- bug #14174 +explain (verbose, costs off) +select i, a from + (select returns_rw_array(1) as a offset 0) ss, + lateral consumes_rw_array(a) i +-- +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 832 +select i, a from + (select returns_rw_array(1) as a offset 0) ss, + lateral consumes_rw_array(a) i +-- +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +STMT: SelectStmt +== 833 +explain (verbose, costs off) +select consumes_rw_array(a), a from returns_rw_array(1) a +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 834 +select consumes_rw_array(a), a from returns_rw_array(1) a +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: SelectStmt +== 835 +explain (verbose, costs off) +select consumes_rw_array(a), a from + (values (returns_rw_array(1)), (returns_rw_array(2))) v(a) +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 836 +select consumes_rw_array(a), a from + (values (returns_rw_array(1)), (returns_rw_array(2))) v(a) +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: SelectStmt +== 837 +do $$ +declare a int[] := array[1,2]; +begin + a := a || 3; + raise notice 'a = %', a; +end$$ +-- +STMT: DoStmt +== 838 +|-- +-- Test access to call stack +|-- + +create function inner_func(int) +returns int as $$ +declare _context text; +begin + get diagnostics _context = pg_context; + raise notice '***%***', _context; + -- lets do it again, just for fun.. + get diagnostics _context = pg_context; + raise notice '***%***', _context; + raise notice 'lets make sure we didnt break anything'; + return 2 * $1; +end; +$$ language plpgsql +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 839 +create or replace function outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into inner_func()'; + myresult := inner_func($1); + raise notice 'inner_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 840 +create or replace function outer_outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into outer_func()'; + myresult := outer_func($1); + raise notice 'outer_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 841 +select outer_outer_func(10) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +== 842 +-- repeated call should work +select outer_outer_func(20) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +== 843 +drop function outer_outer_func(int) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: DropStmt +== 844 +drop function outer_func(int) +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: DropStmt +== 845 +drop function inner_func(int) +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: DropStmt +== 846 +-- access to call stack from exception +create function inner_func(int) +returns int as $$ +declare + _context text; + sx int := 5; +begin + begin + perform sx / 0; + exception + when division_by_zero then + get diagnostics _context = pg_context; + raise notice '***%***', _context; + end; + + -- lets do it again, just for fun.. + get diagnostics _context = pg_context; + raise notice '***%***', _context; + raise notice 'lets make sure we didnt break anything'; + return 2 * $1; +end; +$$ language plpgsql +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 847 +create or replace function outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into inner_func()'; + myresult := inner_func($1); + raise notice 'inner_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 848 +create or replace function outer_outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into outer_func()'; + myresult := outer_func($1); + raise notice 'outer_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 849 +select outer_outer_func(10) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +== 850 +-- repeated call should work +select outer_outer_func(20) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +== 851 +drop function outer_outer_func(int) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: DropStmt +== 852 +drop function outer_func(int) +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: DropStmt +== 853 +drop function inner_func(int) +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: DropStmt +== 854 +-- Test pg_routine_oid +create function current_function(text) +returns regprocedure as $$ +declare + fn_oid regprocedure; +begin + get diagnostics fn_oid = pg_routine_oid; + return fn_oid; +end; +$$ language plpgsql +-- +FUNCTION: name="current_function" function="current_function" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 855 +select current_function('foo') +-- +FUNCTION: name="current_function" function="current_function" schema="" ctx=Call +STMT: SelectStmt +== 856 +drop function current_function(text) +-- +FUNCTION: name="current_function" function="current_function" schema="" ctx=DDL +STMT: DropStmt +== 857 +-- shouldn't fail in DO, even though there's no useful data +do $$ +declare + fn_oid oid; +begin + get diagnostics fn_oid = pg_routine_oid; + raise notice 'pg_routine_oid = %', fn_oid; +end; +$$ +-- +STMT: DoStmt +== 858 +|-- +-- Test ASSERT +|-- + +do $$ +begin + assert 1=1; -- should succeed +end; +$$ +-- +STMT: DoStmt +== 859 +do $$ +begin + assert 1=0; -- should fail +end; +$$ +-- +STMT: DoStmt +== 860 +do $$ +begin + assert NULL; -- should fail +end; +$$ +-- +STMT: DoStmt +== 861 +-- check controlling GUC +set plpgsql.check_asserts = off +-- +STMT: VariableSetStmt +== 862 +do $$ +begin + assert 1=0; -- won't be tested +end; +$$ +-- +STMT: DoStmt +== 863 +reset plpgsql.check_asserts +-- +STMT: VariableSetStmt +== 864 +-- test custom message +do $$ +declare var text := 'some value'; +begin + assert 1=0, format('assertion failed, var = "%s"', var); +end; +$$ +-- +STMT: DoStmt +== 865 +-- ensure assertions are not trapped by 'others' +do $$ +begin + assert 1=0, 'unhandled assertion'; +exception when others then + null; -- do nothing +end; +$$ +-- +STMT: DoStmt +== 866 +-- Test use of plpgsql in a domain check constraint (cf. bug #14414) + +create function plpgsql_domain_check(val int) returns boolean as $$ +begin return val > 0; end +$$ language plpgsql immutable +-- +FUNCTION: name="plpgsql_domain_check" function="plpgsql_domain_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 867 +create domain plpgsql_domain as integer check(plpgsql_domain_check(value)) +-- +STMT: CreateDomainStmt +== 868 +do $$ +declare v_test plpgsql_domain; +begin + v_test := 1; +end; +$$ +-- +STMT: DoStmt +== 869 +do $$ +declare v_test plpgsql_domain := 1; +begin + v_test := 0; -- fail +end; +$$ +-- +STMT: DoStmt +== 870 +-- Test handling of expanded array passed to a domain constraint (bug #14472) + +create function plpgsql_arr_domain_check(val int[]) returns boolean as $$ +begin return val[1] > 0; end +$$ language plpgsql immutable +-- +FUNCTION: name="plpgsql_arr_domain_check" function="plpgsql_arr_domain_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 871 +create domain plpgsql_arr_domain as int[] check(plpgsql_arr_domain_check(value)) +-- +STMT: CreateDomainStmt +== 872 +do $$ +declare v_test plpgsql_arr_domain; +begin + v_test := array[1]; + v_test := v_test || 2; +end; +$$ +-- +STMT: DoStmt +== 873 +do $$ +declare v_test plpgsql_arr_domain := array[1]; +begin + v_test := 0 || v_test; -- fail +end; +$$ +-- +STMT: DoStmt +== 874 +|-- +-- test usage of transition tables in AFTER triggers +|-- + +CREATE TABLE transition_table_base (id int PRIMARY KEY, val text) +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateStmt +== 875 +CREATE FUNCTION transition_table_base_ins_func() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +DECLARE + t text; + l text; +BEGIN + t = ''; + FOR l IN EXECUTE + $q$ + EXPLAIN (TIMING off, COSTS off, VERBOSE on) + SELECT * FROM newtable + $q$ LOOP + t = t || l || E'\n'; + END LOOP; + + RAISE INFO '%', t; + RETURN new; +END; +$$ +-- +FUNCTION: name="transition_table_base_ins_func" function="transition_table_base_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 876 +CREATE TRIGGER transition_table_base_ins_trig + AFTER INSERT ON transition_table_base + REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_ins_func() +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateTrigStmt +== 877 +CREATE TRIGGER transition_table_base_ins_trig + AFTER INSERT ON transition_table_base + REFERENCING NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_ins_func() +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateTrigStmt +== 878 +INSERT INTO transition_table_base VALUES (1, 'One'), (2, 'Two') +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 879 +INSERT INTO transition_table_base VALUES (3, 'Three'), (4, 'Four') +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 880 +CREATE OR REPLACE FUNCTION transition_table_base_upd_func() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +DECLARE + t text; + l text; +BEGIN + t = ''; + FOR l IN EXECUTE + $q$ + EXPLAIN (TIMING off, COSTS off, VERBOSE on) + SELECT * FROM oldtable ot FULL JOIN newtable nt USING (id) + $q$ LOOP + t = t || l || E'\n'; + END LOOP; + + RAISE INFO '%', t; + RETURN new; +END; +$$ +-- +FUNCTION: name="transition_table_base_upd_func" function="transition_table_base_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 881 +CREATE TRIGGER transition_table_base_upd_trig + AFTER UPDATE ON transition_table_base + REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_upd_func() +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateTrigStmt +== 882 +UPDATE transition_table_base + SET val = '*' || val || '*' + WHERE id BETWEEN 2 AND 3 +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DML +STMT: UpdateStmt +== 883 +CREATE TABLE transition_table_level1 +( + level1_no serial NOT NULL , + level1_node_name varchar(255), + PRIMARY KEY (level1_no) +) WITHOUT OIDS +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: CreateStmt +== 884 +CREATE TABLE transition_table_level2 +( + level2_no serial NOT NULL , + parent_no int NOT NULL, + level1_node_name varchar(255), + PRIMARY KEY (level2_no) +) WITHOUT OIDS +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateStmt +== 885 +CREATE TABLE transition_table_status +( + level int NOT NULL, + node_no int NOT NULL, + status int, + PRIMARY KEY (level, node_no) +) WITHOUT OIDS +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DDL +STMT: CreateStmt +== 886 +CREATE FUNCTION transition_table_level1_ri_parent_del_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + DECLARE n bigint; + BEGIN + PERFORM FROM p JOIN transition_table_level2 c ON c.parent_no = p.level1_no; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level1_ri_parent_del_func" function="transition_table_level1_ri_parent_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 887 +CREATE TRIGGER transition_table_level1_ri_parent_del_trigger + AFTER DELETE ON transition_table_level1 + REFERENCING OLD TABLE AS p + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level1_ri_parent_del_func() +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: CreateTrigStmt +== 888 +CREATE FUNCTION transition_table_level1_ri_parent_upd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + DECLARE + x int; + BEGIN + WITH p AS (SELECT level1_no, sum(delta) cnt + FROM (SELECT level1_no, 1 AS delta FROM i + UNION ALL + SELECT level1_no, -1 AS delta FROM d) w + GROUP BY level1_no + HAVING sum(delta) < 0) + SELECT level1_no + FROM p JOIN transition_table_level2 c ON c.parent_no = p.level1_no + INTO x; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level1_ri_parent_upd_func" function="transition_table_level1_ri_parent_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 889 +CREATE TRIGGER transition_table_level1_ri_parent_upd_trigger + AFTER UPDATE ON transition_table_level1 + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level1_ri_parent_upd_func() +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: CreateTrigStmt +== 890 +CREATE FUNCTION transition_table_level2_ri_child_insupd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + BEGIN + PERFORM FROM i + LEFT JOIN transition_table_level1 p + ON p.level1_no IS NOT NULL AND p.level1_no = i.parent_no + WHERE p.level1_no IS NULL; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level2_ri_child_insupd_func" function="transition_table_level2_ri_child_insupd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 891 +CREATE TRIGGER transition_table_level2_ri_child_ins_trigger + AFTER INSERT ON transition_table_level2 + REFERENCING NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_ri_child_insupd_func() +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateTrigStmt +== 892 +CREATE TRIGGER transition_table_level2_ri_child_upd_trigger + AFTER UPDATE ON transition_table_level2 + REFERENCING NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_ri_child_insupd_func() +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateTrigStmt +== 893 +-- create initial test data +INSERT INTO transition_table_level1 (level1_no) + SELECT generate_series(1,200) +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 894 +ANALYZE transition_table_level1 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: VacuumStmt +== 895 +INSERT INTO transition_table_level2 (level2_no, parent_no) + SELECT level2_no, level2_no / 50 + 1 AS parent_no + FROM generate_series(1,9999) level2_no +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 896 +ANALYZE transition_table_level2 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: VacuumStmt +== 897 +INSERT INTO transition_table_status (level, node_no, status) + SELECT 1, level1_no, 0 FROM transition_table_level1 +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DML +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 898 +INSERT INTO transition_table_status (level, node_no, status) + SELECT 2, level2_no, 0 FROM transition_table_level2 +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DML +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 899 +ANALYZE transition_table_status +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DDL +STMT: VacuumStmt +== 900 +INSERT INTO transition_table_level1(level1_no) + SELECT generate_series(201,1000) +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 901 +ANALYZE transition_table_level1 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: VacuumStmt +== 902 +-- behave reasonably if someone tries to modify a transition table +CREATE FUNCTION transition_table_level2_bad_usage_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + BEGIN + INSERT INTO dx VALUES (1000000, 1000000, 'x'); + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level2_bad_usage_func" function="transition_table_level2_bad_usage_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 903 +CREATE TRIGGER transition_table_level2_bad_usage_trigger + AFTER DELETE ON transition_table_level2 + REFERENCING OLD TABLE AS dx + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_bad_usage_func() +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateTrigStmt +== 904 +DELETE FROM transition_table_level2 + WHERE level2_no BETWEEN 301 AND 305 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: DeleteStmt +== 905 +DROP TRIGGER transition_table_level2_bad_usage_trigger + ON transition_table_level2 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: DropStmt +== 906 +-- attempt modifications which would break RI (should all fail) +DELETE FROM transition_table_level1 + WHERE level1_no = 25 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: DeleteStmt +== 907 +UPDATE transition_table_level1 SET level1_no = -1 + WHERE level1_no = 30 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: UpdateStmt +== 908 +INSERT INTO transition_table_level2 (level2_no, parent_no) + VALUES (10000, 10000) +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 909 +UPDATE transition_table_level2 SET parent_no = 2000 + WHERE level2_no = 40 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: UpdateStmt +== 910 +-- attempt modifications which would not break RI (should all succeed) +DELETE FROM transition_table_level1 + WHERE level1_no BETWEEN 201 AND 1000 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: DeleteStmt +== 911 +DELETE FROM transition_table_level1 + WHERE level1_no BETWEEN 100000000 AND 100000010 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: DeleteStmt +== 912 +SELECT count(*) FROM transition_table_level1 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 913 +DELETE FROM transition_table_level2 + WHERE level2_no BETWEEN 211 AND 220 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: DeleteStmt +== 914 +SELECT count(*) FROM transition_table_level2 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 915 +CREATE TABLE alter_table_under_transition_tables +( + id int PRIMARY KEY, + name text +) +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: CreateStmt +== 916 +CREATE FUNCTION alter_table_under_transition_tables_upd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ +BEGIN + RAISE WARNING 'old table = %, new table = %', + (SELECT string_agg(id || '=' || name, ',') FROM d), + (SELECT string_agg(id || '=' || name, ',') FROM i); + RAISE NOTICE 'one = %', (SELECT 1 FROM alter_table_under_transition_tables LIMIT 1); + RETURN NULL; +END; +$$ +-- +FUNCTION: name="alter_table_under_transition_tables_upd_func" function="alter_table_under_transition_tables_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 917 +-- should fail, TRUNCATE is not compatible with transition tables +CREATE TRIGGER alter_table_under_transition_tables_upd_trigger + AFTER TRUNCATE OR UPDATE ON alter_table_under_transition_tables + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + alter_table_under_transition_tables_upd_func() +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: CreateTrigStmt +== 918 +-- should work +CREATE TRIGGER alter_table_under_transition_tables_upd_trigger + AFTER UPDATE ON alter_table_under_transition_tables + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + alter_table_under_transition_tables_upd_func() +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: CreateTrigStmt +== 919 +INSERT INTO alter_table_under_transition_tables + VALUES (1, '1'), (2, '2'), (3, '3') +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 920 +UPDATE alter_table_under_transition_tables + SET name = name || name +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: UpdateStmt +== 921 +-- now change 'name' to an integer to see what happens... +ALTER TABLE alter_table_under_transition_tables + ALTER COLUMN name TYPE int USING name::integer +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: AlterTableStmt +== 922 +UPDATE alter_table_under_transition_tables + SET name = (name::text || name::text)::integer +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: UpdateStmt +== 923 +-- now drop column 'name' +ALTER TABLE alter_table_under_transition_tables + DROP column name +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: AlterTableStmt +== 924 +UPDATE alter_table_under_transition_tables + SET id = id +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: UpdateStmt +== 925 +|-- +-- Test multiple reference to a transition table +|-- + +CREATE TABLE multi_test (i int) +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DDL +STMT: CreateStmt +== 926 +INSERT INTO multi_test VALUES (1) +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 927 +CREATE OR REPLACE FUNCTION multi_test_trig() RETURNS trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'count = %', (SELECT COUNT(*) FROM new_test); + RAISE NOTICE 'count union = %', + (SELECT COUNT(*) + FROM (SELECT * FROM new_test UNION ALL SELECT * FROM new_test) ss); + RETURN NULL; +END$$ +-- +FUNCTION: name="multi_test_trig" function="multi_test_trig" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 928 +CREATE TRIGGER my_trigger AFTER UPDATE ON multi_test + REFERENCING NEW TABLE AS new_test OLD TABLE as old_test + FOR EACH STATEMENT EXECUTE PROCEDURE multi_test_trig() +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DDL +STMT: CreateTrigStmt +== 929 +UPDATE multi_test SET i = i +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DML +STMT: UpdateStmt +== 930 +DROP TABLE multi_test +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DDL +STMT: DropStmt +== 931 +DROP FUNCTION multi_test_trig() +-- +FUNCTION: name="multi_test_trig" function="multi_test_trig" schema="" ctx=DDL +STMT: DropStmt +== 932 +|-- +-- Check type parsing and record fetching from partitioned tables +|-- + +CREATE TABLE partitioned_table (a int, b text) PARTITION BY LIST (a) +-- +TABLE: name="partitioned_table" schema="" table="partitioned_table" ctx=DDL +STMT: CreateStmt +== 933 +CREATE TABLE pt_part1 PARTITION OF partitioned_table FOR VALUES IN (1) +-- +TABLE: name="pt_part1" schema="" table="pt_part1" ctx=DDL +STMT: CreateStmt +== 934 +CREATE TABLE pt_part2 PARTITION OF partitioned_table FOR VALUES IN (2) +-- +TABLE: name="pt_part2" schema="" table="pt_part2" ctx=DDL +STMT: CreateStmt +== 935 +INSERT INTO partitioned_table VALUES (1, 'Row 1') +-- +TABLE: name="partitioned_table" schema="" table="partitioned_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 936 +INSERT INTO partitioned_table VALUES (2, 'Row 2') +-- +TABLE: name="partitioned_table" schema="" table="partitioned_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 937 +CREATE OR REPLACE FUNCTION get_from_partitioned_table(partitioned_table.a%type) +RETURNS partitioned_table AS $$ +DECLARE + a_val partitioned_table.a%TYPE; + result partitioned_table%ROWTYPE; +BEGIN + a_val := $1; + SELECT * INTO result FROM partitioned_table WHERE a = a_val; + RETURN result; +END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="get_from_partitioned_table" function="get_from_partitioned_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 938 +SELECT * FROM get_from_partitioned_table(1) AS t +-- +FUNCTION: name="get_from_partitioned_table" function="get_from_partitioned_table" schema="" ctx=Call +STMT: SelectStmt +== 939 +CREATE OR REPLACE FUNCTION list_partitioned_table() +RETURNS SETOF public.partitioned_table.a%TYPE AS $$ +DECLARE + row public.partitioned_table%ROWTYPE; + a_val public.partitioned_table.a%TYPE; +BEGIN + FOR row IN SELECT * FROM public.partitioned_table ORDER BY a LOOP + a_val := row.a; + RETURN NEXT a_val; + END LOOP; + RETURN; +END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="list_partitioned_table" function="list_partitioned_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 940 +SELECT * FROM list_partitioned_table() AS t +-- +FUNCTION: name="list_partitioned_table" function="list_partitioned_table" schema="" ctx=Call +STMT: SelectStmt +== 941 +|-- +-- Check argument name is used instead of $n in error message +|-- +CREATE FUNCTION fx(x WSlot) RETURNS void AS $$ +BEGIN + GET DIAGNOSTICS x = ROW_COUNT; + RETURN; +END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="fx" function="fx" schema="" ctx=DDL +STMT: CreateFunctionStmt diff --git a/parser/testdata/summary/postgres_regress/point.metadata.json b/parser/testdata/summary/postgres_regress/point.metadata.json new file mode 100644 index 0000000..e74143a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/point.metadata.json @@ -0,0 +1,47 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043" + ] +} diff --git a/parser/testdata/summary/postgres_regress/point.test b/parser/testdata/summary/postgres_regress/point.test new file mode 100644 index 0000000..13512cc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/point.test @@ -0,0 +1,308 @@ +== 001 +|-- +-- POINT +|-- + +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +== 002 +-- point_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 10.0) x') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 1e+500)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- Out of range + + +SELECT * FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +== 008 +-- left of +SELECT p.* FROM POINT_TBL p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 009 +-- right of +SELECT p.* FROM POINT_TBL p WHERE '(0.0,0.0)' >> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 010 +-- above +SELECT p.* FROM POINT_TBL p WHERE '(0.0,0.0)' |>> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 011 +-- below +SELECT p.* FROM POINT_TBL p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 012 +-- equal +SELECT p.* FROM POINT_TBL p WHERE p.f1 ~= '(5.1, 34.5)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 013 +-- point in box +SELECT p.* FROM POINT_TBL p + WHERE p.f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 014 +SELECT p.* FROM POINT_TBL p + WHERE box '(0,0,100,100)' @> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 015 +SELECT p.* FROM POINT_TBL p + WHERE not p.f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 016 +SELECT p.* FROM POINT_TBL p + WHERE p.f1 <@ path '[(0,0),(-10,0),(-10,10)]' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 017 +SELECT p.* FROM POINT_TBL p + WHERE not box '(0,0,100,100)' @> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +== 018 +SELECT p.f1, p.f1 <-> point '(0,0)' AS dist + FROM POINT_TBL p + ORDER BY dist +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +STMT: SelectStmt +== 019 +SELECT 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] +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +STMT: SelectStmt +== 020 +SELECT p1.f1 AS point1, p2.f1 AS point2 + FROM POINT_TBL p1, POINT_TBL p2 + WHERE (p1.f1 <-> p2.f1) > 3 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 021 +-- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 +SELECT 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] +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 022 +-- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 +SELECT 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 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +== 023 +-- Test that GiST indexes provide same behavior as sequential scan +CREATE TEMP TABLE point_gist_tbl(f1 point) +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DDL +STMT: CreateStmt +== 024 +INSERT INTO point_gist_tbl SELECT '(0,0)' FROM generate_series(0,1000) +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 025 +CREATE INDEX point_gist_tbl_index ON point_gist_tbl USING gist (f1) +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DDL +STMT: IndexStmt +== 026 +INSERT INTO point_gist_tbl VALUES ('(0.0000009,0.0000009)') +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +SET enable_seqscan TO true +-- +STMT: VariableSetStmt +== 028 +SET enable_indexscan TO false +-- +STMT: VariableSetStmt +== 029 +SET enable_bitmapscan TO false +-- +STMT: VariableSetStmt +== 030 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 031 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 032 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 033 +SET enable_seqscan TO false +-- +STMT: VariableSetStmt +== 034 +SET enable_indexscan TO true +-- +STMT: VariableSetStmt +== 035 +SET enable_bitmapscan TO true +-- +STMT: VariableSetStmt +== 036 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 037 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 038 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 039 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 040 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 041 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 042 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('1,y', 'point') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT * FROM pg_input_error_info('1,y', 'point') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/polygon.metadata.json b/parser/testdata/summary/postgres_regress/polygon.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/polygon.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary/postgres_regress/polygon.test b/parser/testdata/summary/postgres_regress/polygon.test new file mode 100644 index 0000000..f04d37d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/polygon.test @@ -0,0 +1,444 @@ +== 001 +|-- +-- POLYGON +|-- +-- polygon logic +|-- + +CREATE TABLE POLYGON_TBL(f1 polygon) +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO POLYGON_TBL(f1) VALUES ('(2.0,0.0),(2.0,4.0),(0.0,0.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO POLYGON_TBL(f1) VALUES ('(3.0,1.0),(3.0,3.0),(1.0,0.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(3,4),(5,6),(7,8)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO POLYGON_TBL(f1) VALUES ('(7,8),(5,6),(3,4),(1,2)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +-- Reverse +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(7,8),(5,6),(3,-4)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- degenerate polygons +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,0.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,1.0),(0.0,1.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- bad polygon input strings +INSERT INTO POLYGON_TBL(f1) VALUES ('0.0') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0 0.0') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2,3') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO POLYGON_TBL(f1) VALUES ('asdf') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +SELECT * FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +STMT: SelectStmt +== 015 +|-- +-- Test the SP-GiST index +|-- + +CREATE TABLE quad_poly_tbl (id int, p polygon) +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DDL +STMT: CreateStmt +== 016 +INSERT INTO quad_poly_tbl + SELECT (x - 1) * 100 + y, polygon(circle(point(x * 10, y * 10), 1 + (x + y) % 10)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DML +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO quad_poly_tbl + SELECT i, polygon '((200, 300),(210, 310),(230, 290))' + FROM generate_series(10001, 11000) AS i +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO quad_poly_tbl + VALUES + (11001, NULL), + (11002, NULL), + (11003, NULL) +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +CREATE INDEX quad_poly_tbl_idx ON quad_poly_tbl USING spgist(p) +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DDL +STMT: IndexStmt +== 020 +-- get reference results for ORDER BY distance from seq scan +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +== 021 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 022 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 023 +CREATE TEMP TABLE quad_poly_tbl_ord_seq2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl_ord_seq2" schema="" table="quad_poly_tbl_ord_seq2" ctx=DDL +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 024 +-- check results from index scan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +== 025 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +== 026 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +== 027 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p << polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 028 +SELECT count(*) FROM quad_poly_tbl WHERE p << polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 029 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p &< polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 030 +SELECT count(*) FROM quad_poly_tbl WHERE p &< polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 031 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p && polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 032 +SELECT count(*) FROM quad_poly_tbl WHERE p && polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 033 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p &> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 034 +SELECT count(*) FROM quad_poly_tbl WHERE p &> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 035 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p >> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 036 +SELECT count(*) FROM quad_poly_tbl WHERE p >> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 037 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p <<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 038 +SELECT count(*) FROM quad_poly_tbl WHERE p <<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 039 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p &<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 040 +SELECT count(*) FROM quad_poly_tbl WHERE p &<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 041 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p |&> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 042 +SELECT count(*) FROM quad_poly_tbl WHERE p |&> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 043 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p |>> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 044 +SELECT count(*) FROM quad_poly_tbl WHERE p |>> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 045 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +SELECT count(*) FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 047 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p @> polygon '((340,550),(343,552),(341,553))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 048 +SELECT count(*) FROM quad_poly_tbl WHERE p @> polygon '((340,550),(343,552),(341,553))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 049 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +== 051 +-- test ORDER BY distance +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +== 052 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +== 053 +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +== 054 +CREATE TEMP TABLE quad_poly_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl_ord_idx2" schema="" table="quad_poly_tbl_ord_idx2" ctx=DDL +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 055 +SELECT * +FROM quad_poly_tbl_ord_seq2 seq FULL JOIN quad_poly_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 +-- +TABLE: name="quad_poly_tbl_ord_seq2" schema="" table="quad_poly_tbl_ord_seq2" ctx=Select +TABLE: name="quad_poly_tbl_ord_idx2" schema="" table="quad_poly_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="quad_poly_tbl_ord_idx2" +ALIAS: "seq"="quad_poly_tbl_ord_seq2" +FILTER: schema="" table="seq" column="id" +FILTER: schema="" table="idx" column="id" +STMT: SelectStmt +== 056 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 057 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 058 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 059 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('(2.0,0.8,0.1)', 'polygon') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT * FROM pg_input_error_info('(2.0,0.8,0.1)', 'polygon') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT pg_input_is_valid('(2.0,xyz)', 'polygon') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 062 +SELECT * FROM pg_input_error_info('(2.0,xyz)', 'polygon') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/polymorphism.metadata.json b/parser/testdata/summary/postgres_regress/polymorphism.metadata.json new file mode 100644 index 0000000..835764e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/polymorphism.metadata.json @@ -0,0 +1,427 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423" + ] +} diff --git a/parser/testdata/summary/postgres_regress/polymorphism.test b/parser/testdata/summary/postgres_regress/polymorphism.test new file mode 100644 index 0000000..5016c8b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/polymorphism.test @@ -0,0 +1,2812 @@ +== 001 +|-- +-- Tests for polymorphic SQL functions and aggregates based on them. +-- Tests for other features related to function-calling have snuck in, too. +|-- + +create function polyf(x anyelement) returns anyelement as $$ + select x + 1 +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +select polyf(42) as int, polyf(4.5) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 003 +select polyf(point(3,4)) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 004 +-- fail for lack of + operator + +drop function polyf(x anyelement) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 005 +create function polyf(x anyelement) returns anyarray as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +select polyf(42) as int, polyf(4.5) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 007 +drop function polyf(x anyelement) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 008 +create function polyf(x anyarray) returns anyelement as $$ + select x[1] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 009 +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 010 +select polyf(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 011 +-- fail, can't infer element type + +drop function polyf(x anyarray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 012 +create function polyf(x anyarray) returns anyarray as $$ + select x +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 013 +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 014 +select polyf(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 015 +-- fail, can't infer element type + +drop function polyf(x anyarray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 016 +-- fail, can't infer type: +create function polyf(x anyelement) returns anyrange as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 017 +create function polyf(x anyrange) returns anyarray as $$ + select array[lower(x), upper(x)] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 018 +select polyf(int4range(42, 49)) as int, polyf(float8range(4.5, 7.8)) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 019 +drop function polyf(x anyrange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 020 +create function polyf(x anycompatible, y anycompatible) returns anycompatiblearray as $$ + select array[x, y] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 021 +select polyf(2, 4) as int, polyf(2, 4.5) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 022 +drop function polyf(x anycompatible, y anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 023 +create function polyf(x anycompatiblerange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ + select array[lower(x), upper(x), y, z] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 024 +select polyf(int4range(42, 49), 11, 2::smallint) as int, polyf(float8range(4.5, 7.8), 7.8, 11::real) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 025 +select polyf(int4range(42, 49), 11, 4.5) as fail +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 026 +-- range type doesn't fit + +drop function polyf(x anycompatiblerange, y anycompatible, z anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 027 +create function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ + select array[lower(x), upper(x), y, z] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 028 +select polyf(multirange(int4range(42, 49)), 11, 2::smallint) as int, polyf(multirange(float8range(4.5, 7.8)), 7.8, 11::real) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 029 +select polyf(multirange(int4range(42, 49)), 11, 4.5) as fail +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 030 +-- range type doesn't fit + +drop function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 031 +-- fail, can't infer type: +create function polyf(x anycompatible) returns anycompatiblerange as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +create function polyf(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ + select x +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 033 +select polyf(int4range(42, 49), array[11]) as int, polyf(float8range(4.5, 7.8), array[7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 034 +drop function polyf(x anycompatiblerange, y anycompatiblearray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 035 +-- fail, can't infer type: +create function polyf(x anycompatible) returns anycompatiblemultirange as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +create function polyf(x anycompatiblemultirange, y anycompatiblearray) returns anycompatiblemultirange as $$ + select x +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 037 +select polyf(multirange(int4range(42, 49)), array[11]) as int, polyf(multirange(float8range(4.5, 7.8)), array[7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +== 038 +drop function polyf(x anycompatiblemultirange, y anycompatiblearray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 039 +create function polyf(a anyelement, b anyarray, + c anycompatible, d anycompatible, + OUT x anyarray, OUT y anycompatiblearray) +as $$ + select a || b, array[c, d] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 040 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 041 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2], point(1,2), point(3,4)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 042 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, '{1,2}', point(1,2), '(3,4)') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +== 043 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2.2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 044 +-- fail + +drop function polyf(a anyelement, b anyarray, + c anycompatible, d anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 045 +create function polyf(anyrange) returns anymultirange +as 'select multirange($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 046 +select polyf(int4range(1,10)) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 047 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 048 +drop function polyf(anyrange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 049 +create function polyf(anymultirange) returns anyelement +as 'select lower($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 050 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 051 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 052 +drop function polyf(anymultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 053 +create function polyf(anycompatiblerange) returns anycompatiblemultirange +as 'select multirange($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 054 +select polyf(int4range(1,10)) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 055 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 056 +drop function polyf(anycompatiblerange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 057 +create function polyf(anymultirange) returns anyrange +as 'select range_merge($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 058 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 059 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 060 +drop function polyf(anymultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 061 +create function polyf(anycompatiblemultirange) returns anycompatiblerange +as 'select range_merge($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 062 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 063 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 064 +drop function polyf(anycompatiblemultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 065 +create function polyf(anycompatiblemultirange) returns anycompatible +as 'select lower($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 066 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 067 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +== 068 +drop function polyf(anycompatiblemultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +== 069 +|-- +-- Polymorphic aggregate tests +|-- +-- Legend: +----------- +-- A = type is ANY +-- P = type is polymorphic +-- N = type is non-polymorphic +-- B = aggregate base type +-- S = aggregate state type +-- R = aggregate return type +-- 1 = arg1 of a function +-- 2 = arg2 of a function +-- ag = aggregate +-- tf = trans (state) function +-- ff = final function +-- rt = return type of a function +-- -> = implies +-- => = allowed +-- !> = not allowed +-- E = exists +-- NE = not-exists +|-- +-- Possible states: +-- ---------------- +-- B = (A || P || N) +-- when (B = A) -> (tf2 = NE) +-- S = (P || N) +-- ff = (E || NE) +-- tf1 = (P || N) +-- tf2 = (NE || P || N) +-- R = (P || N) + +-- create functions for use as tf and ff with the needed combinations of +-- argument polymorphism, but within the constraints of valid aggregate +-- functions, i.e. tf arg1 and tf return type must match + +-- polymorphic single arg transfn +CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="stfp" function="stfp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 070 +-- non-polymorphic single arg transfn +CREATE FUNCTION stfnp(int[]) RETURNS int[] AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="stfnp" function="stfnp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 071 +-- dual polymorphic transfn +CREATE FUNCTION tfp(anyarray,anyelement) RETURNS anyarray AS +'select $1 || $2' LANGUAGE SQL +-- +FUNCTION: name="tfp" function="tfp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 072 +-- dual non-polymorphic transfn +CREATE FUNCTION tfnp(int[],int) RETURNS int[] AS +'select $1 || $2' LANGUAGE SQL +-- +FUNCTION: name="tfnp" function="tfnp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 073 +-- arg1 only polymorphic transfn +CREATE FUNCTION tf1p(anyarray,int) RETURNS anyarray AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="tf1p" function="tf1p" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 074 +-- arg2 only polymorphic transfn +CREATE FUNCTION tf2p(int[],anyelement) RETURNS int[] AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="tf2p" function="tf2p" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 075 +-- multi-arg polymorphic +CREATE FUNCTION sum3(anyelement,anyelement,anyelement) returns anyelement AS +'select $1+$2+$3' language sql strict +-- +FUNCTION: name="sum3" function="sum3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 076 +-- finalfn polymorphic +CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="ffp" function="ffp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 077 +-- finalfn non-polymorphic +CREATE FUNCTION ffnp(int[]) returns int[] as +'select $1' LANGUAGE SQL +-- +FUNCTION: name="ffnp" function="ffnp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 078 +-- Try to cover all the possible states: +|-- +-- Note: in Cases 1 & 2, we are trying to return P. Therefore, if the transfn +-- is stfnp, tfnp, or tf2p, we must use ffp as finalfn, because stfnp, tfnp, +-- and tf2p do not return P. Conversely, in Cases 3 & 4, we are trying to +-- return N. Therefore, if the transfn is stfp, tfp, or tf1p, we must use ffnp +-- as finalfn, because stfp, tfp, and tf1p do not return N. +|-- +-- Case1 (R = P) && (B = A) +-- ------------------------ +-- S tf1 +-- ------- +-- N N +-- should CREATE +CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 079 +-- P N +-- should ERROR: stfnp(anyarray) not matched by stfnp(int[]) +CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 080 +-- N P +-- should CREATE +CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 081 +CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 082 +-- P P +-- should ERROR: we have no way to resolve S +CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 083 +CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +== 084 +-- Case2 (R = P) && ((B = P) || (B = N)) +-- ------------------------------------- +-- S tf1 B tf2 +-- ----------------------- +-- N N N N +-- should CREATE +CREATE AGGREGATE myaggp05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 085 +-- N N N P +-- should CREATE +CREATE AGGREGATE myaggp06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 086 +-- N N P N +-- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int) +CREATE AGGREGATE myaggp07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 087 +-- N N P P +-- should CREATE +CREATE AGGREGATE myaggp08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 088 +-- N P N N +-- should CREATE +CREATE AGGREGATE myaggp09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 089 +CREATE AGGREGATE myaggp09b(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 090 +-- N P N P +-- should CREATE +CREATE AGGREGATE myaggp10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 091 +CREATE AGGREGATE myaggp10b(BASETYPE = int, SFUNC = tfp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 092 +-- N P P N +-- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int) +CREATE AGGREGATE myaggp11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 093 +CREATE AGGREGATE myaggp11b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 094 +-- N P P P +-- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement) +CREATE AGGREGATE myaggp12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 095 +CREATE AGGREGATE myaggp12b(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 096 +-- P N N N +-- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 097 +-- P N N P +-- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 098 +-- P N P N +-- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 099 +-- P N P P +-- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggp16a(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 100 +-- P P N N +-- should ERROR: we have no way to resolve S +CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 101 +CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +== 102 +-- P P N P +-- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) +CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 103 +CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +== 104 +-- P P P N +-- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) +CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 105 +CREATE AGGREGATE myaggp19b(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +== 106 +-- P P P P +-- should CREATE +CREATE AGGREGATE myaggp20a(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +== 107 +CREATE AGGREGATE myaggp20b(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +== 108 +-- Case3 (R = N) && (B = A) +-- ------------------------ +-- S tf1 +-- ------- +-- N N +-- should CREATE +CREATE AGGREGATE myaggn01a(*) (SFUNC = stfnp, STYPE = int4[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 109 +CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 110 +-- P N +-- should ERROR: stfnp(anyarray) not matched by stfnp(int[]) +CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 111 +CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +== 112 +-- N P +-- should CREATE +CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 113 +-- P P +-- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) +CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 114 +-- Case4 (R = N) && ((B = P) || (B = N)) +-- ------------------------------------- +-- S tf1 B tf2 +-- ----------------------- +-- N N N N +-- should CREATE +CREATE AGGREGATE myaggn05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 115 +CREATE AGGREGATE myaggn05b(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 116 +-- N N N P +-- should CREATE +CREATE AGGREGATE myaggn06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 117 +CREATE AGGREGATE myaggn06b(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 118 +-- N N P N +-- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int) +CREATE AGGREGATE myaggn07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 119 +CREATE AGGREGATE myaggn07b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 120 +-- N N P P +-- should CREATE +CREATE AGGREGATE myaggn08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 121 +CREATE AGGREGATE myaggn08b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +== 122 +-- N P N N +-- should CREATE +CREATE AGGREGATE myaggn09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 123 +-- N P N P +-- should CREATE +CREATE AGGREGATE myaggn10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 124 +-- N P P N +-- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int) +CREATE AGGREGATE myaggn11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 125 +-- N P P P +-- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement) +CREATE AGGREGATE myaggn12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 126 +-- P N N N +-- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 127 +CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +== 128 +-- P N N P +-- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 129 +CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +== 130 +-- P N P N +-- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 131 +CREATE AGGREGATE myaggn15b(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +== 132 +-- P N P P +-- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggn16a(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 133 +CREATE AGGREGATE myaggn16b(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +== 134 +-- P P N N +-- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) +CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 135 +-- P P N P +-- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) +CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 136 +-- P P P N +-- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) +CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 137 +-- P P P P +-- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) +CREATE AGGREGATE myaggn20a(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +== 138 +-- multi-arg polymorphic +CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3, + STYPE = anyelement, INITCOND = '0') +-- +STMT: DefineStmt +== 139 +-- create test data for polymorphic aggregates +create temp table t(f1 int, f2 int[], f3 text) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +== 140 +insert into t values(1,array[1],'a') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +insert into t values(1,array[11],'b') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +insert into t values(1,array[111],'c') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +insert into t values(2,array[2],'a') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +insert into t values(2,array[22],'b') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 145 +insert into t values(2,array[222],'c') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +insert into t values(3,array[3],'a') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +insert into t values(3,array[3],'b') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +-- test the successfully created polymorphic aggregates +select f3, myaggp01a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp01a" function="myaggp01a" schema="" ctx=Call +STMT: SelectStmt +== 149 +select f3, myaggp03a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp03a" function="myaggp03a" schema="" ctx=Call +STMT: SelectStmt +== 150 +select f3, myaggp03b(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp03b" function="myaggp03b" schema="" ctx=Call +STMT: SelectStmt +== 151 +select f3, myaggp05a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp05a" function="myaggp05a" schema="" ctx=Call +STMT: SelectStmt +== 152 +select f3, myaggp06a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp06a" function="myaggp06a" schema="" ctx=Call +STMT: SelectStmt +== 153 +select f3, myaggp08a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp08a" function="myaggp08a" schema="" ctx=Call +STMT: SelectStmt +== 154 +select f3, myaggp09a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp09a" function="myaggp09a" schema="" ctx=Call +STMT: SelectStmt +== 155 +select f3, myaggp09b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp09b" function="myaggp09b" schema="" ctx=Call +STMT: SelectStmt +== 156 +select f3, myaggp10a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp10a" function="myaggp10a" schema="" ctx=Call +STMT: SelectStmt +== 157 +select f3, myaggp10b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp10b" function="myaggp10b" schema="" ctx=Call +STMT: SelectStmt +== 158 +select f3, myaggp20a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp20a" function="myaggp20a" schema="" ctx=Call +STMT: SelectStmt +== 159 +select f3, myaggp20b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp20b" function="myaggp20b" schema="" ctx=Call +STMT: SelectStmt +== 160 +select f3, myaggn01a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn01a" function="myaggn01a" schema="" ctx=Call +STMT: SelectStmt +== 161 +select f3, myaggn01b(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn01b" function="myaggn01b" schema="" ctx=Call +STMT: SelectStmt +== 162 +select f3, myaggn03a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn03a" function="myaggn03a" schema="" ctx=Call +STMT: SelectStmt +== 163 +select f3, myaggn05a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn05a" function="myaggn05a" schema="" ctx=Call +STMT: SelectStmt +== 164 +select f3, myaggn05b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn05b" function="myaggn05b" schema="" ctx=Call +STMT: SelectStmt +== 165 +select f3, myaggn06a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn06a" function="myaggn06a" schema="" ctx=Call +STMT: SelectStmt +== 166 +select f3, myaggn06b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn06b" function="myaggn06b" schema="" ctx=Call +STMT: SelectStmt +== 167 +select f3, myaggn08a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn08a" function="myaggn08a" schema="" ctx=Call +STMT: SelectStmt +== 168 +select f3, myaggn08b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn08b" function="myaggn08b" schema="" ctx=Call +STMT: SelectStmt +== 169 +select f3, myaggn09a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn09a" function="myaggn09a" schema="" ctx=Call +STMT: SelectStmt +== 170 +select f3, myaggn10a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn10a" function="myaggn10a" schema="" ctx=Call +STMT: SelectStmt +== 171 +select mysum2(f1, f1 + 1) from t +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="mysum2" function="mysum2" schema="" ctx=Call +STMT: SelectStmt +== 172 +-- test inlining of polymorphic SQL functions +create function bleat(int) returns int as $$ +begin + raise notice 'bleat %', $1; + return $1; +end$$ language plpgsql +-- +FUNCTION: name="bleat" function="bleat" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 173 +create function sql_if(bool, anyelement, anyelement) returns anyelement as $$ +select case when $1 then $2 else $3 end $$ language sql +-- +FUNCTION: name="sql_if" function="sql_if" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 174 +-- Note this would fail with integer overflow, never mind wrong bleat() output, +-- if the CASE expression were not successfully inlined +select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="sql_if" function="sql_if" schema="" ctx=Call +FUNCTION: name="bleat" function="bleat" schema="" ctx=Call +FUNCTION: name="bleat" function="bleat" schema="" ctx=Call +STMT: SelectStmt +== 175 +select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="sql_if" function="sql_if" schema="" ctx=Call +STMT: SelectStmt +== 176 +-- another sort of polymorphic aggregate + +CREATE AGGREGATE array_larger_accum (anyarray) +( + sfunc = array_larger, + stype = anyarray, + initcond = '{}' +) +-- +STMT: DefineStmt +== 177 +SELECT array_larger_accum(i) +FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) as t(i) +-- +FUNCTION: name="array_larger_accum" function="array_larger_accum" schema="" ctx=Call +STMT: SelectStmt +== 178 +SELECT array_larger_accum(i) +FROM (VALUES (ARRAY[row(1,2),row(3,4)]), (ARRAY[row(5,6),row(7,8)])) as t(i) +-- +FUNCTION: name="array_larger_accum" function="array_larger_accum" schema="" ctx=Call +STMT: SelectStmt +== 179 +-- another kind of polymorphic aggregate + +create function add_group(grp anyarray, ad anyelement, size integer) + returns anyarray + as $$ +begin + if grp is null then + return array[ad]; + end if; + if array_upper(grp, 1) < size then + return grp || ad; + end if; + return grp; +end; +$$ + language plpgsql immutable +-- +FUNCTION: name="add_group" function="add_group" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 180 +create aggregate build_group(anyelement, integer) ( + SFUNC = add_group, + STYPE = anyarray +) +-- +STMT: DefineStmt +== 181 +select build_group(q1,3) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="build_group" function="build_group" schema="" ctx=Call +STMT: SelectStmt +== 182 +-- this should fail because stype isn't compatible with arg +create aggregate build_group(int8, integer) ( + SFUNC = add_group, + STYPE = int2[] +) +-- +STMT: DefineStmt +== 183 +-- but we can make a non-poly agg from a poly sfunc if types are OK +create aggregate build_group(int8, integer) ( + SFUNC = add_group, + STYPE = int8[] +) +-- +STMT: DefineStmt +== 184 +-- check proper resolution of data types for polymorphic transfn/finalfn + +create function first_el_transfn(anyarray, anyelement) returns anyarray as +'select $1 || $2' language sql immutable +-- +FUNCTION: name="first_el_transfn" function="first_el_transfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 185 +create function first_el(anyarray) returns anyelement as +'select $1[1]' language sql strict immutable +-- +FUNCTION: name="first_el" function="first_el" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 186 +create aggregate first_el_agg_f8(float8) ( + SFUNC = array_append, + STYPE = float8[], + FINALFUNC = first_el +) +-- +STMT: DefineStmt +== 187 +create aggregate first_el_agg_any(anyelement) ( + SFUNC = first_el_transfn, + STYPE = anyarray, + FINALFUNC = first_el +) +-- +STMT: DefineStmt +== 188 +select first_el_agg_f8(x::float8) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_f8" function="first_el_agg_f8" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 189 +select first_el_agg_any(x) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_any" function="first_el_agg_any" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 190 +select first_el_agg_f8(x::float8) over(order by x) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_f8" function="first_el_agg_f8" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 191 +select first_el_agg_any(x) over(order by x) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_any" function="first_el_agg_any" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 192 +-- check that we can apply functions taking ANYARRAY to pg_stats +select distinct array_ndims(histogram_bounds) from pg_stats +where histogram_bounds is not null +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +FILTER: schema="" table="" column="histogram_bounds" +STMT: SelectStmt +== 193 +-- such functions must protect themselves if varying element type isn't OK +-- (WHERE clause here is to avoid possibly getting a collation error instead) +select max(histogram_bounds) from pg_stats where tablename = 'pg_am' +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 194 +-- another corner case is the input functions for polymorphic pseudotypes +select array_in('{1,2,3}','int4'::regtype,-1) +-- +FUNCTION: name="array_in" function="array_in" schema="" ctx=Call +STMT: SelectStmt +== 195 +-- this has historically worked +select * from array_in('{1,2,3}','int4'::regtype,-1) +-- +FUNCTION: name="array_in" function="array_in" schema="" ctx=Call +STMT: SelectStmt +== 196 +-- this not +select anyrange_in('[10,20)','int4range'::regtype,-1) +-- +FUNCTION: name="anyrange_in" function="anyrange_in" schema="" ctx=Call +STMT: SelectStmt +== 197 +-- test variadic polymorphic functions + +create function myleast(variadic anyarray) returns anyelement as $$ + select min($1[i]) from generate_subscripts($1,1) g(i) +$$ language sql immutable strict +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 198 +select myleast(10, 1, 20, 33) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 199 +select myleast(1.1, 0.22, 0.55) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 200 +select myleast('z'::text) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 201 +select myleast() +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 202 +-- fail + +-- test with variadic call parameter +select myleast(variadic array[1,2,3,4,-1]) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 203 +select myleast(variadic array[1.1, -5.5]) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 204 +--test with empty variadic call parameter +select myleast(variadic array[]::int[]) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 205 +-- an example with some ordinary arguments too +create function concat(text, variadic anyarray) returns text as $$ + select array_to_string($2, $1); +$$ language sql immutable strict +-- +FUNCTION: name="concat" function="concat" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 206 +select concat('%', 1, 2, 3, 4, 5) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 207 +select concat('|', 'a'::text, 'b', 'c') +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 208 +select concat('|', variadic array[1,2,33]) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 209 +select concat('|', variadic array[]::int[]) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 210 +drop function concat(text, anyarray) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=DDL +STMT: DropStmt +== 211 +-- mix variadic with anyelement +create function formarray(anyelement, variadic anyarray) returns anyarray as $$ + select array_prepend($1, $2); +$$ language sql immutable strict +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 212 +select formarray(1,2,3,4,5) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +== 213 +select formarray(1.1, variadic array[1.2,55.5]) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +== 214 +select formarray(1.1, array[1.2,55.5]) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +== 215 +-- fail without variadic +select formarray(1, 'x'::text) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +== 216 +-- fail, type mismatch +select formarray(1, variadic array['x'::text]) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +== 217 +-- fail, type mismatch + +drop function formarray(anyelement, variadic anyarray) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=DDL +STMT: DropStmt +== 218 +-- test pg_typeof() function +select pg_typeof(null) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 219 +-- unknown +select pg_typeof(0) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 220 +-- integer +select pg_typeof(0.0) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 221 +-- numeric +select pg_typeof(1+1 = 2) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 222 +-- boolean +select pg_typeof('x') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 223 +-- unknown +select pg_typeof('' || '') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 224 +-- text +select pg_typeof(pg_typeof(0)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 225 +-- regtype +select pg_typeof(array[1.2,55.5]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 226 +-- numeric[] +select pg_typeof(myleast(10, 1, 20, 33)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +== 227 +-- polymorphic input + +-- test functions with default parameters + +-- test basic functionality +create function dfunc(a int = 1, int = 2) returns int as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 228 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 229 +select dfunc(10) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 230 +select dfunc(10, 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 231 +select dfunc(10, 20, 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 232 +-- fail + +drop function dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 233 +-- fail +drop function dfunc(int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 234 +-- fail +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 235 +-- ok + +-- fail: defaults must be at end of argument list +create function dfunc(a int = 1, b int) returns int as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 236 +-- however, this should work: +create function dfunc(a int = 1, out sum int, b int = 2) as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 237 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 238 +-- verify it lists properly + +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 239 +-- check implicit coercion +create function dfunc(a int DEFAULT 1.0, int DEFAULT '-1') returns int as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 240 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 241 +create function dfunc(a text DEFAULT 'Hello', b text DEFAULT 'World') returns text as $$ + select $1 || ', ' || $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 242 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 243 +-- fail: which dfunc should be called? int or text +select dfunc('Hi') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 244 +-- ok +select dfunc('Hi', 'City') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 245 +-- ok +select dfunc(0) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 246 +-- ok +select dfunc(10, 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 247 +-- ok + +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 248 +drop function dfunc(text, text) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 249 +create function dfunc(int = 1, int = 2) returns int as $$ + select 2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 250 +create function dfunc(int = 1, int = 2, int = 3, int = 4) returns int as $$ + select 4; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 251 +-- Now, dfunc(nargs = 2) and dfunc(nargs = 4) are ambiguous when called +-- with 0 to 2 arguments. + +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 252 +-- fail +select dfunc(1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 253 +-- fail +select dfunc(1, 2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 254 +-- fail +select dfunc(1, 2, 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 255 +-- ok +select dfunc(1, 2, 3, 4) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 256 +-- ok + +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 257 +drop function dfunc(int, int, int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 258 +-- default values are not allowed for output parameters +create function dfunc(out int = 20) returns int as $$ + select 1; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 259 +-- polymorphic parameter test +create function dfunc(anyelement = 'World'::text) returns text as $$ + select 'Hello, ' || $1::text; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 260 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 261 +select dfunc(0) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 262 +select dfunc(to_date('20081215','YYYYMMDD')) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 263 +select dfunc('City'::text) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 264 +drop function dfunc(anyelement) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 265 +-- check defaults for variadics + +create function dfunc(a variadic int[]) returns int as +$$ select array_upper($1, 1) $$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 266 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 267 +-- fail +select dfunc(10) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 268 +select dfunc(10,20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 269 +create or replace function dfunc(a variadic int[] default array[]::int[]) returns int as +$$ select array_upper($1, 1) $$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 270 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 271 +-- now ok +select dfunc(10) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 272 +select dfunc(10,20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 273 +-- can't remove the default once it exists +create or replace function dfunc(a variadic int[]) returns int as +$$ select array_upper($1, 1) $$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 274 +drop function dfunc(a variadic int[]) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 275 +-- Ambiguity should be reported only if there's not a better match available + +create function dfunc(int = 1, int = 2, int = 3) returns int as $$ + select 3; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 276 +create function dfunc(int = 1, int = 2) returns int as $$ + select 2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 277 +create function dfunc(text) returns text as $$ + select $1; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 278 +-- dfunc(narg=2) and dfunc(narg=3) are ambiguous +select dfunc(1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 279 +-- fail + +-- but this works since the ambiguous functions aren't preferred anyway +select dfunc('Hi') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 280 +drop function dfunc(int, int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 281 +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 282 +drop function dfunc(text) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 283 +|-- +-- Tests for named- and mixed-notation function calling +|-- + +create function dfunc(a int, b int, c int = 0, d int = 0) + returns table (a int, b int, c int, d int) as $$ + select $1, $2, $3, $4; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 284 +select (dfunc(10,20,30)).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 285 +select (dfunc(a := 10, b := 20, c := 30)).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 286 +select * from dfunc(a := 10, b := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 287 +select * from dfunc(b := 10, a := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 288 +select * from dfunc(0) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 289 +-- fail +select * from dfunc(1,2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 290 +select * from dfunc(1,2,c := 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 291 +select * from dfunc(1,2,d := 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 292 +select * from dfunc(x := 20, b := 10, x := 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 293 +-- fail, duplicate name +select * from dfunc(10, b := 20, 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 294 +-- fail, named args must be last +select * from dfunc(x := 10, b := 20, c := 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 295 +-- fail, unknown param +select * from dfunc(10, 10, a := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 296 +-- fail, a overlaps positional parameter +select * from dfunc(1,c := 2,d := 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 297 +-- fail, no value for b + +drop function dfunc(int, int, int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 298 +-- test with different parameter types +create function dfunc(a varchar, b numeric, c date = current_date) + returns table (a varchar, b numeric, c date) as $$ + select $1, $2, $3; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 299 +select (dfunc('Hello World', 20, '2009-07-25'::date)).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 300 +select * from dfunc('Hello World', 20, '2009-07-25'::date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 301 +select * from dfunc(c := '2009-07-25'::date, a := 'Hello World', b := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 302 +select * from dfunc('Hello World', b := 20, c := '2009-07-25'::date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 303 +select * from dfunc('Hello World', c := '2009-07-25'::date, b := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 304 +select * from dfunc('Hello World', c := 20, b := '2009-07-25'::date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 305 +-- fail + +drop function dfunc(varchar, numeric, date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 306 +-- test out parameters with named params +create function dfunc(a varchar = 'def a', out _a varchar, c numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 307 +select (dfunc()).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 308 +select * from dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 309 +select * from dfunc('Hello', 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 310 +select * from dfunc(a := 'Hello', c := 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 311 +select * from dfunc(c := 100, a := 'Hello') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 312 +select * from dfunc('Hello') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 313 +select * from dfunc('Hello', c := 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 314 +select * from dfunc(c := 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 315 +-- fail, can no longer change an input parameter's name +create or replace function dfunc(a varchar = 'def a', out _a varchar, x numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 316 +create or replace function dfunc(a varchar = 'def a', out _a varchar, numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 317 +drop function dfunc(varchar, numeric) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +== 318 +--fail, named parameters are not unique +create function testpolym(a int, a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 319 +create function testpolym(int, out a int, out a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 320 +create function testpolym(out a int, inout a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 321 +create function testpolym(a int, inout a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 322 +-- valid +create function testpolym(a int, out a int) returns int as $$ select $1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 323 +select testpolym(37) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=Call +STMT: SelectStmt +== 324 +drop function testpolym(int) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: DropStmt +== 325 +create function testpolym(a int) returns table(a int) as $$ select $1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 326 +select * from testpolym(37) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=Call +STMT: SelectStmt +== 327 +drop function testpolym(int) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: DropStmt +== 328 +-- test polymorphic params and defaults +create function dfunc(a anyelement, b anyelement = null, flag bool = true) +returns anyelement as $$ + select case when $3 then $1 else $2 end; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 329 +select dfunc(1,2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 330 +select dfunc('a'::text, 'b') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 331 +-- positional notation with default + +select dfunc(a := 1, b := 2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 332 +select dfunc(a := 'a'::text, b := 'b') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 333 +select dfunc(a := 'a'::text, b := 'b', flag := false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 334 +-- named notation + +select dfunc(b := 'b'::text, a := 'a') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 335 +-- named notation with default +select dfunc(a := 'a'::text, flag := true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 336 +-- named notation with default +select dfunc(a := 'a'::text, flag := false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 337 +-- named notation with default +select dfunc(b := 'b'::text, a := 'a', flag := true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 338 +-- named notation + +select dfunc('a'::text, 'b', false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 339 +-- full positional notation +select dfunc('a'::text, 'b', flag := false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 340 +-- mixed notation +select dfunc('a'::text, 'b', true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 341 +-- full positional notation +select dfunc('a'::text, 'b', flag := true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 342 +-- mixed notation + +-- ansi/sql syntax +select dfunc(a => 1, b => 2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 343 +select dfunc(a => 'a'::text, b => 'b') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 344 +select dfunc(a => 'a'::text, b => 'b', flag => false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 345 +-- named notation + +select dfunc(b => 'b'::text, a => 'a') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 346 +-- named notation with default +select dfunc(a => 'a'::text, flag => true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 347 +-- named notation with default +select dfunc(a => 'a'::text, flag => false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 348 +-- named notation with default +select dfunc(b => 'b'::text, a => 'a', flag => true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 349 +-- named notation + +select dfunc('a'::text, 'b', false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 350 +-- full positional notation +select dfunc('a'::text, 'b', flag => false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 351 +-- mixed notation +select dfunc('a'::text, 'b', true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 352 +-- full positional notation +select dfunc('a'::text, 'b', flag => true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 353 +-- mixed notation + +-- this tests lexer edge cases around => +select dfunc(a =>-1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 354 +select dfunc(a =>+1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 355 +select dfunc(a =>/**/1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 356 +select dfunc(a =>--comment to be removed by psql + 1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +== 357 +-- need DO to protect the -- from psql +do $$ + declare r integer; + begin + select dfunc(a=>-- comment + 1) into r; + raise info 'r = %', r; + end; +$$ +-- +STMT: DoStmt +== 358 +-- check reverse-listing of named-arg calls +CREATE VIEW dfview AS + SELECT q1, q2, + dfunc(q1,q2, flag := q1>q2) as c3, + dfunc(q1, flag := q1= 1000 AND oid < 3000 ORDER BY oid +-- +TABLE: name="pg_largeobject_metadata" schema="" table="pg_largeobject_metadata" ctx=Select +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 012 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 013 +-- test proper begins here + +CREATE USER regress_priv_user1 +-- +STMT: CreateRoleStmt +== 014 +CREATE USER regress_priv_user2 +-- +STMT: CreateRoleStmt +== 015 +CREATE USER regress_priv_user3 +-- +STMT: CreateRoleStmt +== 016 +CREATE USER regress_priv_user4 +-- +STMT: CreateRoleStmt +== 017 +CREATE USER regress_priv_user5 +-- +STMT: CreateRoleStmt +== 018 +CREATE USER regress_priv_user5 +-- +STMT: CreateRoleStmt +== 019 +-- duplicate +CREATE USER regress_priv_user6 +-- +STMT: CreateRoleStmt +== 020 +CREATE USER regress_priv_user7 +-- +STMT: CreateRoleStmt +== 021 +CREATE USER regress_priv_user8 +-- +STMT: CreateRoleStmt +== 022 +CREATE USER regress_priv_user9 +-- +STMT: CreateRoleStmt +== 023 +CREATE USER regress_priv_user10 +-- +STMT: CreateRoleStmt +== 024 +CREATE ROLE regress_priv_role +-- +STMT: CreateRoleStmt +== 025 +-- circular ADMIN OPTION grants should be disallowed +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 026 +GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION GRANTED BY regress_priv_user2 +-- +STMT: GrantRoleStmt +== 027 +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION GRANTED BY regress_priv_user3 +-- +STMT: GrantRoleStmt +== 028 +-- need CASCADE to revoke grant or admin option if dependent grants exist +REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2 +-- +STMT: GrantRoleStmt +== 029 +-- fail +REVOKE regress_priv_user1 FROM regress_priv_user2 +-- +STMT: GrantRoleStmt +== 030 +-- fail +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +STMT: SelectStmt +== 031 +BEGIN +-- +STMT: TransactionStmt +== 032 +REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2 CASCADE +-- +STMT: GrantRoleStmt +== 033 +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +STMT: SelectStmt +== 034 +ROLLBACK +-- +STMT: TransactionStmt +== 035 +REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE +-- +STMT: GrantRoleStmt +== 036 +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +STMT: SelectStmt +== 037 +-- inferred grantor must be a role with ADMIN OPTION +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 038 +GRANT regress_priv_user2 TO regress_priv_user3 +-- +STMT: GrantRoleStmt +== 039 +SET ROLE regress_priv_user3 +-- +STMT: VariableSetStmt +== 040 +GRANT regress_priv_user1 TO regress_priv_user4 +-- +STMT: GrantRoleStmt +== 041 +SELECT grantor::regrole FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole and member = 'regress_priv_user4'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +FILTER: schema="" table="" column="member" +STMT: SelectStmt +== 042 +RESET ROLE +-- +STMT: VariableSetStmt +== 043 +REVOKE regress_priv_user2 FROM regress_priv_user3 +-- +STMT: GrantRoleStmt +== 044 +REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE +-- +STMT: GrantRoleStmt +== 045 +-- test GRANTED BY with DROP OWNED and REASSIGN OWNED +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 046 +GRANT regress_priv_user1 TO regress_priv_user3 GRANTED BY regress_priv_user2 +-- +STMT: GrantRoleStmt +== 047 +DROP ROLE regress_priv_user2 +-- +STMT: DropRoleStmt +== 048 +-- fail, dependency +REASSIGN OWNED BY regress_priv_user2 TO regress_priv_user4 +-- +STMT: ReassignOwnedStmt +== 049 +DROP ROLE regress_priv_user2 +-- +STMT: DropRoleStmt +== 050 +-- still fail, REASSIGN OWNED doesn't help +DROP OWNED BY regress_priv_user2 +-- +STMT: DropOwnedStmt +== 051 +DROP ROLE regress_priv_user2 +-- +STMT: DropRoleStmt +== 052 +-- ok now, DROP OWNED does the job + +-- test that removing granted role or grantee role removes dependency +GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 053 +GRANT regress_priv_user1 TO regress_priv_user4 GRANTED BY regress_priv_user3 +-- +STMT: GrantRoleStmt +== 054 +DROP ROLE regress_priv_user3 +-- +STMT: DropRoleStmt +== 055 +-- should fail, dependency +DROP ROLE regress_priv_user4 +-- +STMT: DropRoleStmt +== 056 +-- ok +DROP ROLE regress_priv_user3 +-- +STMT: DropRoleStmt +== 057 +-- ok now +GRANT regress_priv_user1 TO regress_priv_user5 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 058 +GRANT regress_priv_user1 TO regress_priv_user6 GRANTED BY regress_priv_user5 +-- +STMT: GrantRoleStmt +== 059 +DROP ROLE regress_priv_user5 +-- +STMT: DropRoleStmt +== 060 +-- should fail, dependency +DROP ROLE regress_priv_user1, regress_priv_user5 +-- +STMT: DropRoleStmt +== 061 +-- ok, despite order + +-- recreate the roles we just dropped +CREATE USER regress_priv_user1 +-- +STMT: CreateRoleStmt +== 062 +CREATE USER regress_priv_user2 +-- +STMT: CreateRoleStmt +== 063 +CREATE USER regress_priv_user3 +-- +STMT: CreateRoleStmt +== 064 +CREATE USER regress_priv_user4 +-- +STMT: CreateRoleStmt +== 065 +CREATE USER regress_priv_user5 +-- +STMT: CreateRoleStmt +== 066 +GRANT pg_read_all_data TO regress_priv_user6 +-- +STMT: GrantRoleStmt +== 067 +GRANT pg_write_all_data TO regress_priv_user7 +-- +STMT: GrantRoleStmt +== 068 +GRANT pg_read_all_settings TO regress_priv_user8 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 069 +GRANT regress_priv_user9 TO regress_priv_user8 +-- +STMT: GrantRoleStmt +== 070 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +== 071 +GRANT pg_read_all_settings TO regress_priv_user9 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 072 +SET SESSION AUTHORIZATION regress_priv_user9 +-- +STMT: VariableSetStmt +== 073 +GRANT pg_read_all_settings TO regress_priv_user10 +-- +STMT: GrantRoleStmt +== 074 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +== 075 +REVOKE pg_read_all_settings FROM regress_priv_user10 GRANTED BY regress_priv_user9 +-- +STMT: GrantRoleStmt +== 076 +REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user9 +-- +STMT: GrantRoleStmt +== 077 +REVOKE pg_read_all_settings FROM regress_priv_user9 +-- +STMT: GrantRoleStmt +== 078 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 079 +REVOKE regress_priv_user9 FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +== 080 +REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +== 081 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +== 082 +SET ROLE pg_read_all_settings +-- +STMT: VariableSetStmt +== 083 +RESET ROLE +-- +STMT: VariableSetStmt +== 084 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 085 +REVOKE SET OPTION FOR pg_read_all_settings FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +== 086 +GRANT pg_read_all_stats TO regress_priv_user8 WITH SET FALSE +-- +STMT: GrantRoleStmt +== 087 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +== 088 +SET ROLE pg_read_all_settings +-- +STMT: VariableSetStmt +== 089 +-- fail, no SET option any more +SET ROLE pg_read_all_stats +-- +STMT: VariableSetStmt +== 090 +-- fail, granted without SET option +RESET ROLE +-- +STMT: VariableSetStmt +== 091 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 092 +-- test interaction of SET SESSION AUTHORIZATION and SET ROLE, +-- as well as propagation of these settings to parallel workers +GRANT regress_priv_user9 TO regress_priv_user8 +-- +STMT: GrantRoleStmt +== 093 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +== 094 +SET ROLE regress_priv_user9 +-- +STMT: VariableSetStmt +== 095 +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +== 096 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 097 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 098 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 099 +BEGIN +-- +STMT: TransactionStmt +== 100 +SET SESSION AUTHORIZATION regress_priv_user10 +-- +STMT: VariableSetStmt +== 101 +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +== 102 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 103 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 104 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 105 +ROLLBACK +-- +STMT: TransactionStmt +== 106 +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +== 107 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 108 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 109 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 110 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 111 +-- session_user at this point is installation-dependent +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +== 112 +SELECT session_user = current_role as c_r_ok, session_user = current_user as c_u_ok, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 113 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 114 +SELECT session_user = current_role as c_r_ok, session_user = current_user as c_u_ok, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 115 +RESET debug_parallel_query +-- +STMT: VariableSetStmt +== 116 +REVOKE pg_read_all_settings FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +== 117 +DROP USER regress_priv_user10 +-- +STMT: DropRoleStmt +== 118 +DROP USER regress_priv_user9 +-- +STMT: DropRoleStmt +== 119 +DROP USER regress_priv_user8 +-- +STMT: DropRoleStmt +== 120 +CREATE GROUP regress_priv_group1 +-- +STMT: CreateRoleStmt +== 121 +CREATE GROUP regress_priv_group2 WITH ADMIN regress_priv_user1 USER regress_priv_user2 +-- +STMT: CreateRoleStmt +== 122 +ALTER GROUP regress_priv_group1 ADD USER regress_priv_user4 +-- +STMT: AlterRoleStmt +== 123 +GRANT regress_priv_group2 TO regress_priv_user2 GRANTED BY regress_priv_user1 +-- +STMT: GrantRoleStmt +== 124 +SET SESSION AUTHORIZATION regress_priv_user3 +-- +STMT: VariableSetStmt +== 125 +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2 +-- +STMT: AlterRoleStmt +== 126 +-- fail +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2 +-- +STMT: AlterRoleStmt +== 127 +-- fail +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 128 +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2 +-- +STMT: AlterRoleStmt +== 129 +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2 +-- +STMT: AlterRoleStmt +== 130 +-- duplicate +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2 +-- +STMT: AlterRoleStmt +== 131 +ALTER USER regress_priv_user2 PASSWORD 'verysecret' +-- +STMT: AlterRoleStmt +== 132 +-- not permitted +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 133 +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2 +-- +STMT: AlterRoleStmt +== 134 +REVOKE ADMIN OPTION FOR regress_priv_group2 FROM regress_priv_user1 +-- +STMT: GrantRoleStmt +== 135 +GRANT regress_priv_group2 TO regress_priv_user4 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +== 136 +-- prepare non-leakproof function for later +CREATE FUNCTION leak(integer,integer) RETURNS boolean + AS 'int4lt' + LANGUAGE internal IMMUTABLE STRICT +-- +FUNCTION: name="leak" function="leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 137 +-- but deliberately not LEAKPROOF +ALTER FUNCTION leak(integer,integer) OWNER TO regress_priv_user1 +-- +STMT: AlterOwnerStmt +== 138 +-- test owner privileges + +GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY regress_priv_role +-- +STMT: GrantRoleStmt +== 139 +-- error, doesn't have ADMIN OPTION +GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY CURRENT_ROLE +-- +STMT: GrantRoleStmt +== 140 +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY foo +-- +STMT: GrantRoleStmt +== 141 +-- error +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY regress_priv_user2 +-- +STMT: GrantRoleStmt +== 142 +-- warning, noop +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_USER +-- +STMT: GrantRoleStmt +== 143 +REVOKE regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_ROLE +-- +STMT: GrantRoleStmt +== 144 +DROP ROLE regress_priv_role +-- +STMT: DropRoleStmt +== 145 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 146 +SELECT session_user, current_user +-- +STMT: SelectStmt +== 147 +CREATE TABLE atest1 ( a int, b text ) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: CreateStmt +== 148 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +== 149 +INSERT INTO atest1 VALUES (1, 'one') +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +DELETE FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: DeleteStmt +== 151 +UPDATE atest1 SET a = 1 WHERE b = 'blech' +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: UpdateStmt +== 152 +TRUNCATE atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: TruncateStmt +== 153 +BEGIN +-- +STMT: TransactionStmt +== 154 +LOCK atest1 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: LockStmt +== 155 +COMMIT +-- +STMT: TransactionStmt +== 156 +REVOKE ALL ON atest1 FROM PUBLIC +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +== 157 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +== 158 +GRANT ALL ON atest1 TO regress_priv_user2 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +== 159 +GRANT SELECT ON atest1 TO regress_priv_user3, regress_priv_user4 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +== 160 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +== 161 +CREATE TABLE atest2 (col1 varchar(10), col2 boolean) +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: CreateStmt +== 162 +GRANT SELECT ON atest2 TO regress_priv_user2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +== 163 +GRANT UPDATE ON atest2 TO regress_priv_user3 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +== 164 +GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +== 165 +GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +== 166 +GRANT TRUNCATE ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +== 167 +-- error + + +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +== 168 +SELECT session_user, current_user +-- +STMT: SelectStmt +== 169 +-- try various combinations of queries on atest1 and atest2 + +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +== 170 +-- ok +SELECT * FROM atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: SelectStmt +== 171 +-- ok +INSERT INTO atest1 VALUES (2, 'two') +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +-- ok +INSERT INTO atest2 VALUES ('foo', true) +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +-- fail +INSERT INTO atest1 SELECT 1, b FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 174 +-- ok +UPDATE atest1 SET a = 1 WHERE a = 2 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: UpdateStmt +== 175 +-- ok +UPDATE atest2 SET col2 = NOT col2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DML +STMT: UpdateStmt +== 176 +-- fail +SELECT * FROM atest1 FOR UPDATE +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +== 177 +-- ok +SELECT * FROM atest2 FOR UPDATE +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: SelectStmt +== 178 +-- fail +DELETE FROM atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DML +STMT: DeleteStmt +== 179 +-- fail +TRUNCATE atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: TruncateStmt +== 180 +-- fail +BEGIN +-- +STMT: TransactionStmt +== 181 +LOCK atest2 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: LockStmt +== 182 +-- fail +COMMIT +-- +STMT: TransactionStmt +== 183 +COPY atest2 FROM stdin +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: CopyStmt +== 184 +-- fail +GRANT ALL ON atest1 TO PUBLIC +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +== 185 +-- fail + +-- checks in subquery, both ok +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest2" schema="" table="atest2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 186 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +== 187 +-- ok + + +-- test leaky-function protections in selfuncs + +-- regress_priv_user1 will own a table and provide views for it. +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 188 +CREATE TABLE atest12 as + SELECT x AS a, 10001 - x AS b FROM generate_series(1,10000) x +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 189 +CREATE INDEX ON atest12 (a) +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: IndexStmt +== 190 +CREATE INDEX ON atest12 (abs(a)) +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +== 191 +-- results below depend on having quite accurate stats for atest12, so... +ALTER TABLE atest12 SET (autovacuum_enabled = off) +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: AlterTableStmt +== 192 +SET default_statistics_target = 10000 +-- +STMT: VariableSetStmt +== 193 +VACUUM ANALYZE atest12 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: VacuumStmt +== 194 +RESET default_statistics_target +-- +STMT: VariableSetStmt +== 195 +CREATE OPERATOR <<< (procedure = leak, leftarg = integer, rightarg = integer, + restrict = scalarltsel) +-- +STMT: DefineStmt +== 196 +-- views with leaky operator +CREATE VIEW atest12v AS + SELECT * FROM atest12 WHERE b <<< 5 +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=DDL +TABLE: name="atest12" schema="" table="atest12" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 197 +CREATE VIEW atest12sbv WITH (security_barrier=true) AS + SELECT * FROM atest12 WHERE b <<< 5 +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=DDL +TABLE: name="atest12" schema="" table="atest12" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 198 +-- This plan should use nestloop, knowing that few rows will be selected. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 199 +-- And this one. +EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=Select +TABLE: name="atest12" schema="" table="atest12" ctx=Select +ALIAS: "x"="atest12" +ALIAS: "y"="atest12" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 200 +-- This should also be a nestloop, but the security barrier forces the inner +-- scan to be materialized +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +ALIAS: "x"="atest12sbv" +ALIAS: "y"="atest12sbv" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 201 +-- Check if regress_priv_user2 can break security. +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +== 202 +CREATE FUNCTION leak2(integer,integer) RETURNS boolean + AS $$begin raise notice 'leak % %', $1, $2; return $1 > $2; end$$ + LANGUAGE plpgsql immutable +-- +FUNCTION: name="leak2" function="leak2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 203 +CREATE OPERATOR >>> (procedure = leak2, leftarg = integer, rightarg = integer, + restrict = scalargtsel) +-- +STMT: DefineStmt +== 204 +-- These should not show any "leak" notices before failing. +EXPLAIN (COSTS OFF) SELECT * FROM atest12 WHERE a >>> 0 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 205 +EXPLAIN (COSTS OFF) SELECT * FROM atest12v WHERE a >>> 0 +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 206 +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv WHERE a >>> 0 +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 207 +-- Now regress_priv_user1 grants access to regress_priv_user2 via the views. +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 208 +GRANT SELECT ON atest12v TO PUBLIC +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=DDL +STMT: GrantStmt +== 209 +GRANT SELECT ON atest12sbv TO PUBLIC +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=DDL +STMT: GrantStmt +== 210 +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +== 211 +-- These plans should continue to use a nestloop, since they execute with the +-- privileges of the view owner. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 212 +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +ALIAS: "x"="atest12sbv" +ALIAS: "y"="atest12sbv" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 213 +-- A non-security barrier view does not guard against information leakage. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 214 +-- But a security barrier view isolates the leaky operator. +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +ALIAS: "x"="atest12sbv" +ALIAS: "y"="atest12sbv" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 215 +-- Now regress_priv_user1 grants sufficient access to regress_priv_user2. +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 216 +GRANT SELECT (a, b) ON atest12 TO PUBLIC +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: GrantStmt +== 217 +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +== 218 +-- regress_priv_user2 should continue to get a good row estimate. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 219 +-- But not for this, due to lack of table-wide permissions needed +-- to make use of the expression index's statistics. +EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=Select +TABLE: name="atest12" schema="" table="atest12" ctx=Select +ALIAS: "x"="atest12" +ALIAS: "y"="atest12" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 220 +-- clean up (regress_priv_user1's objects are all dropped later) +DROP FUNCTION leak2(integer, integer) CASCADE +-- +FUNCTION: name="leak2" function="leak2" schema="" ctx=DDL +STMT: DropStmt +== 221 +-- groups + +SET SESSION AUTHORIZATION regress_priv_user3 +-- +STMT: VariableSetStmt +== 222 +CREATE TABLE atest3 (one int, two int, three int) +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DDL +STMT: CreateStmt +== 223 +GRANT DELETE ON atest3 TO GROUP regress_priv_group2 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DDL +STMT: GrantStmt +== 224 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 225 +SELECT * FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=Select +STMT: SelectStmt +== 226 +-- fail +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +== 227 +-- ok + +BEGIN +-- +STMT: TransactionStmt +== 228 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 229 +ALTER ROLE regress_priv_user1 NOINHERIT +-- +STMT: AlterRoleStmt +== 230 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 231 +SAVEPOINT s1 +-- +STMT: TransactionStmt +== 232 +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +== 233 +-- ok because grant-level option is unchanged +ROLLBACK TO s1 +-- +STMT: TransactionStmt +== 234 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 235 +GRANT regress_priv_group2 TO regress_priv_user1 WITH INHERIT FALSE +-- +STMT: GrantRoleStmt +== 236 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 237 +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +== 238 +-- fail +ROLLBACK TO s1 +-- +STMT: TransactionStmt +== 239 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 240 +REVOKE INHERIT OPTION FOR regress_priv_group2 FROM regress_priv_user1 +-- +STMT: GrantRoleStmt +== 241 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 242 +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +== 243 +-- also fail +ROLLBACK +-- +STMT: TransactionStmt +== 244 +-- views + +SET SESSION AUTHORIZATION regress_priv_user3 +-- +STMT: VariableSetStmt +== 245 +CREATE VIEW atestv1 AS SELECT * FROM atest1 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=DDL +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 246 +-- ok +/* The next *should* fail, but it's not implemented that way yet. */ +CREATE VIEW atestv2 AS SELECT * FROM atest2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=DDL +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 247 +CREATE VIEW atestv3 AS SELECT * FROM atest3 +-- +TABLE: name="atestv3" schema="" table="atestv3" ctx=DDL +TABLE: name="atest3" schema="" table="atest3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 248 +-- ok +/* Empty view is a corner case that failed in 9.2. */ +CREATE VIEW atestv0 AS SELECT 0 as x WHERE false +-- +TABLE: name="atestv0" schema="" table="atestv0" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 249 +-- ok + +SELECT * FROM atestv1 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=Select +STMT: SelectStmt +== 250 +-- ok +SELECT * FROM atestv2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=Select +STMT: SelectStmt +== 251 +-- fail +GRANT SELECT ON atestv1, atestv3 TO regress_priv_user4 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=DDL +TABLE: name="atestv3" schema="" table="atestv3" ctx=DDL +STMT: GrantStmt +== 252 +GRANT SELECT ON atestv2 TO regress_priv_user2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=DDL +STMT: GrantStmt +== 253 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +== 254 +SELECT * FROM atestv1 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=Select +STMT: SelectStmt +== 255 +-- ok +SELECT * FROM atestv2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=Select +STMT: SelectStmt +== 256 +-- fail +SELECT * FROM atestv3 +-- +TABLE: name="atestv3" schema="" table="atestv3" ctx=Select +STMT: SelectStmt +== 257 +-- ok +SELECT * FROM atestv0 +-- +TABLE: name="atestv0" schema="" table="atestv0" ctx=Select +STMT: SelectStmt +== 258 +-- fail + +-- Appendrels excluded by constraints failed to check permissions in 8.4-9.2. +select * from + ((select a.q1 as x from int8_tbl a offset 0) + union all + (select b.q2 as x from int8_tbl b offset 0)) ss +where false +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: SelectStmt +== 259 +set constraint_exclusion = on +-- +STMT: VariableSetStmt +== 260 +select * from + ((select a.q1 as x, random() from int8_tbl a where q1 > 0) + union all + (select b.q2 as x, random() from int8_tbl b where q2 > 0)) ss +where x < 0 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 261 +reset constraint_exclusion +-- +STMT: VariableSetStmt +== 262 +CREATE VIEW atestv4 AS SELECT * FROM atestv3 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=DDL +TABLE: name="atestv3" schema="" table="atestv3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 263 +-- nested view +SELECT * FROM atestv4 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=Select +STMT: SelectStmt +== 264 +-- ok +GRANT SELECT ON atestv4 TO regress_priv_user2 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=DDL +STMT: GrantStmt +== 265 +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +== 266 +-- Two complex cases: + +SELECT * FROM atestv3 +-- +TABLE: name="atestv3" schema="" table="atestv3" ctx=Select +STMT: SelectStmt +== 267 +-- fail +SELECT * FROM atestv4 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=Select +STMT: SelectStmt +== 268 +-- ok (even though regress_priv_user2 cannot access underlying atestv3) + +SELECT * FROM atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: SelectStmt +== 269 +-- ok +SELECT * FROM atestv2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=Select +STMT: SelectStmt +== 270 +-- fail (even though regress_priv_user2 can access underlying atest2) + +-- Test column level permissions + +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 271 +CREATE TABLE atest5 (one int, two int unique, three int, four int unique) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: CreateStmt +== 272 +CREATE TABLE atest6 (one int, two int, blue int) +-- +TABLE: name="atest6" schema="" table="atest6" ctx=DDL +STMT: CreateStmt +== 273 +GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regress_priv_user4 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: GrantStmt +== 274 +GRANT ALL (one) ON atest5 TO regress_priv_user3 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: GrantStmt +== 275 +INSERT INTO atest5 VALUES (1,2,3) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 276 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +== 277 +SELECT * FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 278 +-- fail +SELECT one FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 279 +-- ok +COPY atest5 (one) TO stdout +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +== 280 +-- ok +SELECT two FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 281 +-- fail +COPY atest5 (two) TO stdout +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +== 282 +-- fail +SELECT atest5 FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 283 +-- fail +COPY atest5 (one,two) TO stdout +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +== 284 +-- fail +SELECT 1 FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 285 +-- ok +SELECT 1 FROM atest5 a JOIN atest5 b USING (one) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 286 +-- ok +SELECT 1 FROM atest5 a JOIN atest5 b USING (two) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 287 +-- fail +SELECT 1 FROM atest5 a NATURAL JOIN atest5 b +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 288 +-- fail +SELECT * FROM (atest5 a JOIN atest5 b USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 289 +-- fail +SELECT j.* FROM (atest5 a JOIN atest5 b USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 290 +-- fail +SELECT (j.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 291 +-- fail +SELECT one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 292 +-- ok +SELECT j.one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 293 +-- ok +SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 294 +-- fail +SELECT j.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 295 +-- fail +SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 296 +-- fail +SELECT j.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 297 +-- fail +SELECT * FROM (atest5 a JOIN atest5 b USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 298 +-- fail +SELECT a.* FROM (atest5 a JOIN atest5 b USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 299 +-- fail +SELECT (a.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 300 +-- fail +SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 301 +-- fail +SELECT a.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 302 +-- fail +SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 303 +-- fail +SELECT b.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 304 +-- fail +SELECT y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 305 +-- fail +SELECT b.y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 306 +-- fail +SELECT y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 307 +-- fail +SELECT b.y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +== 308 +-- fail +SELECT 1 FROM atest5 WHERE two = 2 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +FILTER: schema="" table="" column="two" +STMT: SelectStmt +== 309 +-- fail +SELECT * FROM atest1, atest5 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 310 +-- fail +SELECT atest1.* FROM atest1, atest5 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 311 +-- ok +SELECT atest1.*,atest5.one FROM atest1, atest5 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 312 +-- ok +SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.two) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 313 +-- fail +SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.one) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 314 +-- ok +SELECT one, two FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +== 315 +-- fail + +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 316 +GRANT SELECT (one,two) ON atest6 TO regress_priv_user4 +-- +TABLE: name="atest6" schema="" table="atest6" ctx=DDL +STMT: GrantStmt +== 317 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +== 318 +SELECT one, two FROM atest5 NATURAL JOIN atest6 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest6" schema="" table="atest6" ctx=Select +STMT: SelectStmt +== 319 +-- fail still + +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +== 320 +GRANT SELECT (two) ON atest5 TO regress_priv_user4 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: GrantStmt +== 321 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +== 322 +SELECT one, two FROM atest5 NATURAL JOIN atest6 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest6" schema="" table="atest6" ctx=Select +STMT: SelectStmt +== 323 +-- ok now + +-- test column-level privileges for INSERT and UPDATE +INSERT INTO atest5 (two) VALUES (3) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 324 +-- ok +COPY atest5 FROM stdin +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +== 325 +-- fail +COPY atest5 (two) FROM stdin +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +== 326 +-- ok +1 +INSERT INTO atest5 (three) VALUES (4) +-- +ERROR: syntax error at or near "1" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 327 +-- fail +INSERT INTO atest5 VALUES (5,5,5) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 328 +-- fail +UPDATE atest5 SET three = 10 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: UpdateStmt +== 329 +-- ok +UPDATE atest5 SET one = 8 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: UpdateStmt +== 330 +-- fail +UPDATE atest5 SET three = 5, one = 2 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: UpdateStmt +== 331 +-- fail +-- Check that column level privs are enforced in RETURNING +-- Ok. +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/psql.metadata.json b/parser/testdata/summary/postgres_regress/psql.metadata.json new file mode 100644 index 0000000..0612d4a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/psql.metadata.json @@ -0,0 +1,200 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196" + ] +} diff --git a/parser/testdata/summary/postgres_regress/psql.test b/parser/testdata/summary/postgres_regress/psql.test new file mode 100644 index 0000000..38494ec --- /dev/null +++ b/parser/testdata/summary/postgres_regress/psql.test @@ -0,0 +1,1032 @@ +== 001 +|-- +-- Tests for psql features that aren't closely connected to any +-- specific server features +|-- + +-- \set + +-- fail: invalid name +-- fail: invalid value for special variable +-- check handling of built-in boolean variable + +-- ; + +SELECT 1 as one, 2 as two +-- +STMT: SelectStmt +== 002 +SELECT 3 as three, 4 as four \gx + +-- \gx should work in FETCH_COUNT mode too + +SELECT 1 as one, 2 as two +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +SELECT 3 as three, 4 as four \gx + + +-- ; + +SELECT 1 as one, 2 as two \g (format=csv csv_fieldsep='\t') +SELECT 1 as one, 2 as two \gx (title='foo bar') + +-- \bind (extended query protocol) + +SELECT 1 \bind +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +SELECT $1 \bind 'foo' +-- +ERROR: syntax error at or near "\" +CURSORPOS: 11 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +SELECT $1, $2 \bind 'foo' 'bar' +-- +ERROR: syntax error at or near "\" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- errors +-- parse error +SELECT foo \bind +-- +ERROR: syntax error at or near "\" +CURSORPOS: 37 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- tcop error +SELECT 1 \ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +SELECT 2 \bind +-- +ERROR: syntax error at or near "\" +CURSORPOS: 10 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- bind error +SELECT $1, $2 \bind 'foo' +-- +ERROR: syntax error at or near "\" +CURSORPOS: 29 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 010 +-- ; + +select 10 as test01, 20 as test02, 'Hello' as test03 +-- +STMT: SelectStmt +== 011 +-- should fail: bad variable name +select 10 as "bad name" + +select 97 as "EOF", 'ok' as _foo +-- +ERROR: syntax error at or near "select" +CURSORPOS: 60 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- multiple backslash commands in one line +select 1 as x, 2 as y +-- +STMT: SelectStmt +== 013 +select 3 as x, 4 as y +-- +STMT: SelectStmt +== 014 +select 5 as x, 6 as y +-- +STMT: SelectStmt +== 015 +select 7 as x, 8 as y +-- +STMT: SelectStmt +== 016 +-- NULL should unset the variable +select 1 as var1, NULL as var2, 3 as var3 +-- +STMT: SelectStmt +== 017 +-- ; +select 10 as test01, 20 as test02 from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 018 +select 10 as test01, 20 as test02 from generate_series(1,0) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- ; +select a from generate_series(1, 10) as a where a = 11 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 020 +-- ; + +select 1 as x, 2 as y +-- +STMT: SelectStmt +== 021 +select 3 as x, 4 as y +-- +STMT: SelectStmt +== 022 +select 10 as test01, 20 as test02 from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 023 +select 10 as test01, 20 as test02 from generate_series(1,0) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 024 +-- ; + +SELECT + NULL AS zero, + 1 AS one, + 2.0 AS two, + 'three' AS three, + $1 AS four, + sin($2) as five, + 'foo'::varchar(4) as six, + CURRENT_DATE AS now + +-- should work with tuple-returning utilities, such as EXECUTE +PREPARE test AS SELECT 1 AS first, 2 AS second +-- +ERROR: syntax error at or near "PREPARE" +CURSORPOS: 239 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 025 +EXECUTE test +-- +STMT: ExecuteStmt +== 026 +EXPLAIN EXECUTE test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 027 +-- should fail cleanly - syntax error +SELECT 1 + +-- +ERROR: syntax error at end of input +CURSORPOS: 49 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 028 +-- check behavior with empty results +SELECT +-- +STMT: SelectStmt +== 029 +CREATE TABLE bububu(a int) +-- +TABLE: name="bububu" schema="" table="bububu" ctx=DDL +STMT: CreateStmt +== 030 +-- subject command should not have executed +TABLE bububu +-- +TABLE: name="bububu" schema="" table="bububu" ctx=Select +STMT: SelectStmt +== 031 +-- fail + +-- query buffer should remain unchanged +SELECT 1 AS x, 'Hello', 2 AS y, true AS "dirty\name" + +-- all on one line +SELECT 3 AS x, 'Hello', 4 AS y, true AS "dirty\name" +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 123 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 032 +-- test for server bug #17983 with empty statement in aborted transaction +set search_path = default +-- +STMT: VariableSetStmt +== 033 +begin +-- +STMT: TransactionStmt +== 034 +rollback +-- +STMT: TransactionStmt +== 035 +-- ; + +create temporary table gexec_test(a int, b text, c date, d float) +-- +TABLE: name="gexec_test" schema="" table="gexec_test" ctx=DDL +STMT: CreateStmt +== 036 +select format('create index on gexec_test(%I)', attname) +from pg_attribute +where attrelid = 'gexec_test'::regclass and attnum > 0 +order by attnum + +-- ; +-- (though the fetch limit applies to the executed queries not the meta query) + +select 'select 1 as ones', 'select x.y, x.y*2 as double from generate_series(1,4) as x(y)' +union all +select 'drop table gexec_test', NULL +union all +select 'drop table gexec_test', 'select ''2000-01-01''::date as party_over' + + +-- \setenv, \getenv + +-- ensure MYVAR isn't set +-- in which case, reading it doesn't change the target +-- now set it + +-- show all pset options + +-- test multi-line headers, wrapping, and newline indicators +-- in aligned, unaligned, and wrapped formats +prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab + +c", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a +bc" from generate_series(1,10) as n(n) group by n>1 order by n>1 +-- +ERROR: syntax error at or near "select" +CURSORPOS: 233 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 037 +execute q +-- +STMT: ExecuteStmt +== 038 +execute q +-- +STMT: ExecuteStmt +== 039 +execute q +-- +STMT: ExecuteStmt +== 040 +execute q +-- +STMT: ExecuteStmt +== 041 +execute q +-- +STMT: ExecuteStmt +== 042 +execute q +-- +STMT: ExecuteStmt +== 043 +execute q +-- +STMT: ExecuteStmt +== 044 +execute q +-- +STMT: ExecuteStmt +== 045 +execute q +-- +STMT: ExecuteStmt +== 046 +execute q +-- +STMT: ExecuteStmt +== 047 +execute q +-- +STMT: ExecuteStmt +== 048 +execute q +-- +STMT: ExecuteStmt +== 049 +execute q +-- +STMT: ExecuteStmt +== 050 +execute q +-- +STMT: ExecuteStmt +== 051 +execute q +-- +STMT: ExecuteStmt +== 052 +execute q +-- +STMT: ExecuteStmt +== 053 +execute q +-- +STMT: ExecuteStmt +== 054 +execute q +-- +STMT: ExecuteStmt +== 055 +execute q +-- +STMT: ExecuteStmt +== 056 +execute q +-- +STMT: ExecuteStmt +== 057 +execute q +-- +STMT: ExecuteStmt +== 058 +execute q +-- +STMT: ExecuteStmt +== 059 +execute q +-- +STMT: ExecuteStmt +== 060 +execute q +-- +STMT: ExecuteStmt +== 061 +execute q +-- +STMT: ExecuteStmt +== 062 +execute q +-- +STMT: ExecuteStmt +== 063 +execute q +-- +STMT: ExecuteStmt +== 064 +execute q +-- +STMT: ExecuteStmt +== 065 +execute q +-- +STMT: ExecuteStmt +== 066 +execute q +-- +STMT: ExecuteStmt +== 067 +execute q +-- +STMT: ExecuteStmt +== 068 +execute q +-- +STMT: ExecuteStmt +== 069 +execute q +-- +STMT: ExecuteStmt +== 070 +execute q +-- +STMT: ExecuteStmt +== 071 +execute q +-- +STMT: ExecuteStmt +== 072 +execute q +-- +STMT: ExecuteStmt +== 073 +deallocate q +-- +STMT: DeallocateStmt +== 074 +-- test single-line header and data +prepare q as select repeat('x',2*n) as "0123456789abcdef", repeat('y',20-2*n) as "0123456789" from generate_series(1,10) as n +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 075 +execute q +-- +STMT: ExecuteStmt +== 076 +execute q +-- +STMT: ExecuteStmt +== 077 +execute q +-- +STMT: ExecuteStmt +== 078 +execute q +-- +STMT: ExecuteStmt +== 079 +execute q +-- +STMT: ExecuteStmt +== 080 +execute q +-- +STMT: ExecuteStmt +== 081 +execute q +-- +STMT: ExecuteStmt +== 082 +execute q +-- +STMT: ExecuteStmt +== 083 +execute q +-- +STMT: ExecuteStmt +== 084 +execute q +-- +STMT: ExecuteStmt +== 085 +execute q +-- +STMT: ExecuteStmt +== 086 +execute q +-- +STMT: ExecuteStmt +== 087 +execute q +-- +STMT: ExecuteStmt +== 088 +execute q +-- +STMT: ExecuteStmt +== 089 +execute q +-- +STMT: ExecuteStmt +== 090 +execute q +-- +STMT: ExecuteStmt +== 091 +execute q +-- +STMT: ExecuteStmt +== 092 +execute q +-- +STMT: ExecuteStmt +== 093 +execute q +-- +STMT: ExecuteStmt +== 094 +execute q +-- +STMT: ExecuteStmt +== 095 +execute q +-- +STMT: ExecuteStmt +== 096 +execute q +-- +STMT: ExecuteStmt +== 097 +execute q +-- +STMT: ExecuteStmt +== 098 +execute q +-- +STMT: ExecuteStmt +== 099 +execute q +-- +STMT: ExecuteStmt +== 100 +execute q +-- +STMT: ExecuteStmt +== 101 +execute q +-- +STMT: ExecuteStmt +== 102 +execute q +-- +STMT: ExecuteStmt +== 103 +execute q +-- +STMT: ExecuteStmt +== 104 +execute q +-- +STMT: ExecuteStmt +== 105 +execute q +-- +STMT: ExecuteStmt +== 106 +execute q +-- +STMT: ExecuteStmt +== 107 +execute q +-- +STMT: ExecuteStmt +== 108 +execute q +-- +STMT: ExecuteStmt +== 109 +execute q +-- +STMT: ExecuteStmt +== 110 +execute q +-- +STMT: ExecuteStmt +== 111 +execute q +-- +STMT: ExecuteStmt +== 112 +execute q +-- +STMT: ExecuteStmt +== 113 +execute q +-- +STMT: ExecuteStmt +== 114 +execute q +-- +STMT: ExecuteStmt +== 115 +execute q +-- +STMT: ExecuteStmt +== 116 +execute q +-- +STMT: ExecuteStmt +== 117 +execute q +-- +STMT: ExecuteStmt +== 118 +execute q +-- +STMT: ExecuteStmt +== 119 +execute q +-- +STMT: ExecuteStmt +== 120 +deallocate q +-- +STMT: DeallocateStmt +== 121 +-- support table for output-format tests (useful to create a footer) + +create table psql_serial_tab (id serial) +-- +TABLE: name="psql_serial_tab" schema="" table="psql_serial_tab" ctx=DDL +STMT: CreateStmt +== 122 +-- test header/footer/tuples_only behavior in aligned/unaligned/wrapped cases + + +-- empty table is a special case for this format +select 1 where false +-- +STMT: SelectStmt +== 123 +-- check conditional am display + +CREATE SCHEMA tableam_display +-- +STMT: CreateSchemaStmt +== 124 +CREATE ROLE regress_display_role +-- +STMT: CreateRoleStmt +== 125 +ALTER SCHEMA tableam_display OWNER TO regress_display_role +-- +STMT: AlterOwnerStmt +== 126 +SET search_path TO tableam_display +-- +STMT: VariableSetStmt +== 127 +CREATE ACCESS METHOD heap_psql TYPE TABLE HANDLER heap_tableam_handler +-- +STMT: CreateAmStmt +== 128 +SET ROLE TO regress_display_role +-- +STMT: VariableSetStmt +== 129 +-- Use only relations with a physical size of zero. +CREATE TABLE tbl_heap_psql(f1 int, f2 char(100)) using heap_psql +-- +TABLE: name="tbl_heap_psql" schema="" table="tbl_heap_psql" ctx=DDL +STMT: CreateStmt +== 130 +CREATE TABLE tbl_heap(f1 int, f2 char(100)) using heap +-- +TABLE: name="tbl_heap" schema="" table="tbl_heap" ctx=DDL +STMT: CreateStmt +== 131 +CREATE VIEW view_heap_psql AS SELECT f1 from tbl_heap_psql +-- +TABLE: name="view_heap_psql" schema="" table="view_heap_psql" ctx=DDL +TABLE: name="tbl_heap_psql" schema="" table="tbl_heap_psql" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 132 +CREATE MATERIALIZED VIEW mat_view_heap_psql USING heap_psql AS SELECT f1 from tbl_heap_psql +-- +TABLE: name="mat_view_heap_psql" schema="" table="mat_view_heap_psql" ctx=DDL +TABLE: name="tbl_heap_psql" schema="" table="tbl_heap_psql" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 133 +-- AM is displayed for tables, indexes and materialized views. +-- But not for views and sequences. +RESET ROLE +-- +STMT: VariableSetStmt +== 134 +RESET search_path +-- +STMT: VariableSetStmt +== 135 +DROP SCHEMA tableam_display CASCADE +-- +STMT: DropStmt +== 136 +DROP ACCESS METHOD heap_psql +-- +STMT: DropStmt +== 137 +DROP ROLE regress_display_role +-- +STMT: DropRoleStmt +== 138 +-- test numericlocale (as best we can without control of psql's locale) + + +select n, -n as m, n * 111 as x, '1e90'::float8 as f +from generate_series(0,3) n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 139 +-- test asciidoc output format + + + +prepare q as + select 'some|text' as "a|title", ' ' as "empty ", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 140 +execute q +-- +STMT: ExecuteStmt +== 141 +execute q +-- +STMT: ExecuteStmt +== 142 +execute q +-- +STMT: ExecuteStmt +== 143 +execute q +-- +STMT: ExecuteStmt +== 144 +execute q +-- +STMT: ExecuteStmt +== 145 +execute q +-- +STMT: ExecuteStmt +== 146 +deallocate q +-- +STMT: DeallocateStmt +== 147 +-- test csv output format + + + +prepare q as + select 'some"text' as "a""title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 148 +execute q +-- +STMT: ExecuteStmt +== 149 +execute q +-- +STMT: ExecuteStmt +== 150 +deallocate q +-- +STMT: DeallocateStmt +== 151 +-- special cases +select 'comma,comma' as comma, 'semi;semi' as semi +-- +STMT: SelectStmt +== 152 +select 'comma,comma' as comma, 'semi;semi' as semi +-- +STMT: SelectStmt +== 153 +select '\.' as data +-- +STMT: SelectStmt +== 154 +select '\' as d1, '' as d2 +-- +STMT: SelectStmt +== 155 +-- illegal csv separators + + +-- test html output format + + + +prepare q as + select 'some"text' as "a&title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 156 +execute q +-- +STMT: ExecuteStmt +== 157 +execute q +-- +STMT: ExecuteStmt +== 158 +execute q +-- +STMT: ExecuteStmt +== 159 +execute q +-- +STMT: ExecuteStmt +== 160 +execute q +-- +STMT: ExecuteStmt +== 161 +execute q +-- +STMT: ExecuteStmt +== 162 +deallocate q +-- +STMT: DeallocateStmt +== 163 +-- test latex output format + + + +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 164 +execute q +-- +STMT: ExecuteStmt +== 165 +execute q +-- +STMT: ExecuteStmt +== 166 +execute q +-- +STMT: ExecuteStmt +== 167 +execute q +-- +STMT: ExecuteStmt +== 168 +execute q +-- +STMT: ExecuteStmt +== 169 +execute q +-- +STMT: ExecuteStmt +== 170 +execute q +-- +STMT: ExecuteStmt +== 171 +execute q +-- +STMT: ExecuteStmt +== 172 +deallocate q +-- +STMT: DeallocateStmt +== 173 +-- test latex-longtable output format + + + +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 174 +execute q +-- +STMT: ExecuteStmt +== 175 +execute q +-- +STMT: ExecuteStmt +== 176 +execute q +-- +STMT: ExecuteStmt +== 177 +execute q +-- +STMT: ExecuteStmt +== 178 +execute q +-- +STMT: ExecuteStmt +== 179 +execute q +-- +STMT: ExecuteStmt +== 180 +execute q +-- +STMT: ExecuteStmt +== 181 +execute q +-- +STMT: ExecuteStmt +== 182 +execute q +-- +STMT: ExecuteStmt +== 183 +execute q +-- +STMT: ExecuteStmt +== 184 +deallocate q +-- +STMT: DeallocateStmt +== 185 +-- test troff-ms output format + + + +prepare q as + select 'some\text' as "a\title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 186 +execute q +-- +STMT: ExecuteStmt +== 187 +execute q +-- +STMT: ExecuteStmt +== 188 +execute q +-- +STMT: ExecuteStmt +== 189 +execute q +-- +STMT: ExecuteStmt +== 190 +execute q +-- +STMT: ExecuteStmt +== 191 +execute q +-- +STMT: ExecuteStmt +== 192 +deallocate q +-- +STMT: DeallocateStmt +== 193 +-- check ambiguous format requests + + +-- clean up after output format tests + +drop table psql_serial_tab +-- +TABLE: name="psql_serial_tab" schema="" table="psql_serial_tab" ctx=DDL +STMT: DropStmt +== 194 +-- \echo and allied features + + + + + +-- tests for \if ... \endif + + select 'okay' +-- +STMT: SelectStmt +== 195 +select 'still okay' +-- +STMT: SelectStmt +== 196 +not okay +-- +ERROR: syntax error at or near "not" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json b/parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json new file mode 100644 index 0000000..5e6664a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json @@ -0,0 +1,12 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008" + ] +} diff --git a/parser/testdata/summary/postgres_regress/psql_crosstab.test b/parser/testdata/summary/postgres_regress/psql_crosstab.test new file mode 100644 index 0000000..4f9da1d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/psql_crosstab.test @@ -0,0 +1,145 @@ +== 001 +|-- +-- \crosstabview +|-- + +CREATE TABLE ctv_data (v, h, c, i, d) AS +VALUES + ('v1','h2','foo', 3, '2015-04-01'::date), + ('v2','h1','bar', 3, '2015-01-02'), + ('v1','h0','baz', NULL, '2015-07-12'), + ('v0','h4','qux', 4, '2015-07-15'), + ('v0','h4','dbl', -3, '2014-12-15'), + ('v0',NULL,'qux', 5, '2014-07-15'), + ('v1','h2','quux',7, '2015-04-04') +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 002 +-- make plans more stable +ANALYZE ctv_data +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DDL +STMT: VacuumStmt +== 003 +-- running \crosstabview after query uses query in buffer +SELECT v, EXTRACT(year FROM d), count(*) + FROM ctv_data + GROUP BY 1, 2 + ORDER BY 1, 2 +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 004 +-- basic usage with 3 columns + +-- ordered months in horizontal header, quoted column name +SELECT v, to_char(d, 'Mon') AS "month name", EXTRACT(month FROM d) AS num, + count(*) FROM ctv_data GROUP BY 1,2,3 ORDER BY 1 + +-- ordered months in vertical header, ordered years in horizontal header +SELECT EXTRACT(year FROM d) AS year, to_char(d,'Mon') AS """month"" name", + EXTRACT(month FROM d) AS month, + format('sum=%s avg=%s', sum(i), avg(i)::numeric(2,1)) + FROM ctv_data + GROUP BY EXTRACT(year FROM d), to_char(d,'Mon'), EXTRACT(month FROM d) +ORDER BY month + +-- combine contents vertically into the same cell (V/H duplicates) +SELECT v, h, string_agg(c, E'\n') FROM ctv_data GROUP BY v, h ORDER BY 1,2,3 + +-- horizontal ASC order from window function +SELECT v,h, string_agg(c, E'\n') AS c, row_number() OVER(ORDER BY h) AS r +FROM ctv_data GROUP BY v, h ORDER BY 1,3,2 + +-- horizontal DESC order from window function +SELECT v, h, string_agg(c, E'\n') AS c, row_number() OVER(ORDER BY h DESC) AS r +FROM ctv_data GROUP BY v, h ORDER BY 1,3,2 + +-- horizontal ASC order from window function, NULLs pushed rightmost +SELECT v,h, string_agg(c, E'\n') AS c, row_number() OVER(ORDER BY h NULLS LAST) AS r +FROM ctv_data GROUP BY v, h ORDER BY 1,3,2 + +-- only null, no column name, 2 columns: error +SELECT null,null \crosstabview + +-- only null, no column name, 3 columns: works +SELECT null,null,null \crosstabview + +-- null display +SELECT v,h, string_agg(i::text, E'\n') AS i FROM ctv_data +GROUP BY v, h ORDER BY h,v + +-- refer to columns by position +SELECT v,h,string_agg(i::text, E'\n'), string_agg(c, E'\n') +FROM ctv_data GROUP BY v, h ORDER BY h,v + +-- refer to columns by positions and names mixed +SELECT v,h, string_agg(i::text, E'\n') AS i, string_agg(c, E'\n') AS c +FROM ctv_data GROUP BY v, h ORDER BY h,v + +-- refer to columns by quoted names, check downcasing of unquoted name +SELECT 1 as "22", 2 as b, 3 as "Foo" + +-- error: bad column name +SELECT v,h,c,i FROM ctv_data + +-- error: need to quote name +SELECT 1 as "22", 2 as b, 3 as "Foo" + +-- error: need to not quote name +SELECT 1 as "22", 2 as b, 3 as "Foo" + +-- error: bad column number +SELECT v,h,i,c FROM ctv_data + +-- error: same H and V columns +SELECT v,h,i,c FROM ctv_data + +-- error: too many columns +SELECT a,a,1 FROM generate_series(1,3000) AS a + +-- error: only one column +SELECT 1 \crosstabview + +DROP TABLE ctv_data +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 291 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- check error reporting (bug #14476) +CREATE TABLE ctv_data (x int, y int, v text) +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DDL +STMT: CreateStmt +== 006 +INSERT INTO ctv_data SELECT 1, x, '*' || x FROM generate_series(1,10) x +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 007 +SELECT * FROM ctv_data \crosstabview + +INSERT INTO ctv_data VALUES (1, 10, '*') +-- +ERROR: syntax error at or near "\" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- duplicate data to cause error +SELECT * FROM ctv_data \crosstabview + +DROP TABLE ctv_data +-- +ERROR: syntax error at or near "\" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary/postgres_regress/publication.metadata.json b/parser/testdata/summary/postgres_regress/publication.metadata.json new file mode 100644 index 0000000..8cf9d31 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/publication.metadata.json @@ -0,0 +1,659 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655" + ] +} diff --git a/parser/testdata/summary/postgres_regress/publication.test b/parser/testdata/summary/postgres_regress/publication.test new file mode 100644 index 0000000..0e71b6d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/publication.test @@ -0,0 +1,3236 @@ +== 001 +|-- +-- PUBLICATION +|-- +CREATE ROLE regress_publication_user LOGIN SUPERUSER +-- +STMT: CreateRoleStmt +== 002 +CREATE ROLE regress_publication_user2 +-- +STMT: CreateRoleStmt +== 003 +CREATE ROLE regress_publication_user_dummy LOGIN NOSUPERUSER +-- +STMT: CreateRoleStmt +== 004 +SET SESSION AUTHORIZATION 'regress_publication_user' +-- +STMT: VariableSetStmt +== 005 +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 006 +CREATE PUBLICATION testpub_default +-- +STMT: CreatePublicationStmt +== 007 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 008 +COMMENT ON PUBLICATION testpub_default IS 'test publication' +-- +STMT: CommentStmt +== 009 +SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p +-- +TABLE: name="pg_publication" schema="" table="pg_publication" ctx=Select +ALIAS: "p"="pg_publication" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +== 010 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 011 +CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert) +-- +STMT: CreatePublicationStmt +== 012 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 013 +ALTER PUBLICATION testpub_default SET (publish = update) +-- +STMT: AlterPublicationStmt +== 014 +-- error cases +CREATE PUBLICATION testpub_xxx WITH (foo) +-- +STMT: CreatePublicationStmt +== 015 +CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum') +-- +STMT: CreatePublicationStmt +== 016 +CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = 'true', publish_via_partition_root = '0') +-- +STMT: CreatePublicationStmt +== 017 +ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete') +-- +STMT: AlterPublicationStmt +== 018 +--- adding tables +CREATE SCHEMA pub_test +-- +STMT: CreateSchemaStmt +== 019 +CREATE TABLE testpub_tbl1 (id serial primary key, data text) +-- +TABLE: name="testpub_tbl1" schema="" table="testpub_tbl1" ctx=DDL +STMT: CreateStmt +== 020 +CREATE TABLE pub_test.testpub_nopk (foo int, bar int) +-- +TABLE: name="pub_test.testpub_nopk" schema="pub_test" table="testpub_nopk" ctx=DDL +STMT: CreateStmt +== 021 +CREATE VIEW testpub_view AS SELECT 1 +-- +TABLE: name="testpub_view" schema="" table="testpub_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 022 +CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: CreateStmt +== 023 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 024 +CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 025 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 026 +ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update') +-- +STMT: AlterPublicationStmt +== 027 +CREATE TABLE testpub_tbl2 (id serial primary key, data text) +-- +TABLE: name="testpub_tbl2" schema="" table="testpub_tbl2" ctx=DDL +STMT: CreateStmt +== 028 +-- fail - can't add to for all tables publication +ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2 +-- +STMT: AlterPublicationStmt +== 029 +-- fail - can't drop from all tables publication +ALTER PUBLICATION testpub_foralltables DROP TABLE testpub_tbl2 +-- +STMT: AlterPublicationStmt +== 030 +-- fail - can't add to for all tables publication +ALTER PUBLICATION testpub_foralltables SET TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 031 +-- fail - can't add schema to 'FOR ALL TABLES' publication +ALTER PUBLICATION testpub_foralltables ADD TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +== 032 +-- fail - can't drop schema from 'FOR ALL TABLES' publication +ALTER PUBLICATION testpub_foralltables DROP TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +== 033 +-- fail - can't set schema to 'FOR ALL TABLES' publication +ALTER PUBLICATION testpub_foralltables SET TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +== 034 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 035 +CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1 +-- +STMT: CreatePublicationStmt +== 036 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 037 +-- should be able to add schema to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable ADD TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +== 038 +-- should be able to drop schema from 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable DROP TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +== 039 +-- should be able to set schema to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +== 040 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 041 +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test +-- +STMT: CreatePublicationStmt +== 042 +-- should be able to create publication with schema and table of the same +-- schema +CREATE PUBLICATION testpub_for_tbl_schema FOR TABLES IN SCHEMA pub_test, TABLE pub_test.testpub_nopk +-- +STMT: CreatePublicationStmt +== 043 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 044 +-- weird parser corner case +CREATE PUBLICATION testpub_parsertst FOR TABLE pub_test.testpub_nopk, CURRENT_SCHEMA +-- +ERROR: invalid table name +CURSORPOS: 99 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 045 +CREATE PUBLICATION testpub_parsertst FOR TABLES IN SCHEMA foo, test.foo +-- +ERROR: invalid schema name +CURSORPOS: 64 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 046 +-- should be able to add a table of the same schema to the schema publication +ALTER PUBLICATION testpub_forschema ADD TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 047 +-- should be able to drop the table +ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 048 +-- fail - can't drop a table from the schema publication which isn't in the +-- publication +ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 049 +-- should be able to set table to schema publication +ALTER PUBLICATION testpub_forschema SET TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 050 +SELECT pubname, puballtables FROM pg_publication WHERE pubname = 'testpub_foralltables' +-- +TABLE: name="pg_publication" schema="" table="pg_publication" ctx=Select +FILTER: schema="" table="" column="pubname" +STMT: SelectStmt +== 051 +DROP TABLE testpub_tbl2 +-- +TABLE: name="testpub_tbl2" schema="" table="testpub_tbl2" ctx=DDL +STMT: DropStmt +== 052 +DROP PUBLICATION testpub_foralltables, testpub_fortable, testpub_forschema, testpub_for_tbl_schema +-- +STMT: DropStmt +== 053 +CREATE TABLE testpub_tbl3 (a int) +-- +TABLE: name="testpub_tbl3" schema="" table="testpub_tbl3" ctx=DDL +STMT: CreateStmt +== 054 +CREATE TABLE testpub_tbl3a (b text) INHERITS (testpub_tbl3) +-- +TABLE: name="testpub_tbl3a" schema="" table="testpub_tbl3a" ctx=DDL +STMT: CreateStmt +== 055 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 056 +CREATE PUBLICATION testpub3 FOR TABLE testpub_tbl3 +-- +STMT: CreatePublicationStmt +== 057 +CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3 +-- +STMT: CreatePublicationStmt +== 058 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 059 +DROP TABLE testpub_tbl3, testpub_tbl3a +-- +TABLE: name="testpub_tbl3" schema="" table="testpub_tbl3" ctx=DDL +TABLE: name="testpub_tbl3a" schema="" table="testpub_tbl3a" ctx=DDL +STMT: DropStmt +== 060 +DROP PUBLICATION testpub3, testpub4 +-- +STMT: DropStmt +== 061 +-- Tests for partitioned tables +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 062 +CREATE PUBLICATION testpub_forparted +-- +STMT: CreatePublicationStmt +== 063 +CREATE PUBLICATION testpub_forparted1 +-- +STMT: CreatePublicationStmt +== 064 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 065 +CREATE TABLE testpub_parted1 (LIKE testpub_parted) +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DDL +STMT: CreateStmt +== 066 +CREATE TABLE testpub_parted2 (LIKE testpub_parted) +-- +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DDL +STMT: CreateStmt +== 067 +ALTER PUBLICATION testpub_forparted1 SET (publish='insert') +-- +STMT: AlterPublicationStmt +== 068 +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted1 FOR VALUES IN (1) +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: AlterTableStmt +== 069 +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted2 FOR VALUES IN (2) +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: AlterTableStmt +== 070 +-- works despite missing REPLICA IDENTITY, because updates are not replicated +UPDATE testpub_parted1 SET a = 1 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DML +STMT: UpdateStmt +== 071 +-- only parent is listed as being in publication, not the partition +ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted +-- +STMT: AlterPublicationStmt +== 072 +-- works despite missing REPLICA IDENTITY, because no actual update happened +UPDATE testpub_parted SET a = 1 WHERE false +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DML +STMT: UpdateStmt +== 073 +-- should now fail, because parent's publication replicates updates +UPDATE testpub_parted1 SET a = 1 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DML +STMT: UpdateStmt +== 074 +ALTER TABLE testpub_parted DETACH PARTITION testpub_parted1 +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: AlterTableStmt +== 075 +-- works again, because parent's publication is no longer considered +UPDATE testpub_parted1 SET a = 1 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DML +STMT: UpdateStmt +== 076 +ALTER PUBLICATION testpub_forparted SET (publish_via_partition_root = true) +-- +STMT: AlterPublicationStmt +== 077 +-- still fail, because parent's publication replicates updates +UPDATE testpub_parted2 SET a = 2 +-- +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DML +STMT: UpdateStmt +== 078 +ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted +-- +STMT: AlterPublicationStmt +== 079 +-- works again, because update is no longer replicated +UPDATE testpub_parted2 SET a = 2 +-- +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DML +STMT: UpdateStmt +== 080 +DROP TABLE testpub_parted1, testpub_parted2 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DDL +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DDL +STMT: DropStmt +== 081 +DROP PUBLICATION testpub_forparted, testpub_forparted1 +-- +STMT: DropStmt +== 082 +-- Tests for row filters +CREATE TABLE testpub_rf_tbl1 (a integer, b text) +-- +TABLE: name="testpub_rf_tbl1" schema="" table="testpub_rf_tbl1" ctx=DDL +STMT: CreateStmt +== 083 +CREATE TABLE testpub_rf_tbl2 (c text, d integer) +-- +TABLE: name="testpub_rf_tbl2" schema="" table="testpub_rf_tbl2" ctx=DDL +STMT: CreateStmt +== 084 +CREATE TABLE testpub_rf_tbl3 (e integer) +-- +TABLE: name="testpub_rf_tbl3" schema="" table="testpub_rf_tbl3" ctx=DDL +STMT: CreateStmt +== 085 +CREATE TABLE testpub_rf_tbl4 (g text) +-- +TABLE: name="testpub_rf_tbl4" schema="" table="testpub_rf_tbl4" ctx=DDL +STMT: CreateStmt +== 086 +CREATE TABLE testpub_rf_tbl5 (a xml) +-- +TABLE: name="testpub_rf_tbl5" schema="" table="testpub_rf_tbl5" ctx=DDL +STMT: CreateStmt +== 087 +CREATE SCHEMA testpub_rf_schema1 +-- +STMT: CreateSchemaStmt +== 088 +CREATE TABLE testpub_rf_schema1.testpub_rf_tbl5 (h integer) +-- +TABLE: name="testpub_rf_schema1.testpub_rf_tbl5" schema="testpub_rf_schema1" table="testpub_rf_tbl5" ctx=DDL +STMT: CreateStmt +== 089 +CREATE SCHEMA testpub_rf_schema2 +-- +STMT: CreateSchemaStmt +== 090 +CREATE TABLE testpub_rf_schema2.testpub_rf_tbl6 (i integer) +-- +TABLE: name="testpub_rf_schema2.testpub_rf_tbl6" schema="testpub_rf_schema2" table="testpub_rf_tbl6" ctx=DDL +STMT: CreateStmt +== 091 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 092 +-- Firstly, test using the option publish='insert' because the row filter +-- validation of referenced columns is less strict than for delete/update. +CREATE PUBLICATION testpub5 FOR TABLE testpub_rf_tbl1, testpub_rf_tbl2 WHERE (c <> 'test' AND d < 5) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 093 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 094 +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl3 WHERE (e > 1000 AND e < 2000) +-- +STMT: AlterPublicationStmt +== 095 +ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl2 +-- +STMT: AlterPublicationStmt +== 096 +-- remove testpub_rf_tbl1 and add testpub_rf_tbl3 again (another WHERE expression) +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e > 300 AND e < 500) +-- +STMT: AlterPublicationStmt +== 097 +-- test \d (now it displays filter information) +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 098 +CREATE PUBLICATION testpub_rf_yes FOR TABLE testpub_rf_tbl1 WHERE (a > 1) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 099 +CREATE PUBLICATION testpub_rf_no FOR TABLE testpub_rf_tbl1 +-- +STMT: CreatePublicationStmt +== 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 101 +DROP PUBLICATION testpub_rf_yes, testpub_rf_no +-- +STMT: DropStmt +== 102 +-- some more syntax tests to exercise other parser pathways +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 103 +CREATE PUBLICATION testpub_syntax1 FOR TABLE testpub_rf_tbl1, ONLY testpub_rf_tbl3 WHERE (e < 999) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 104 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 105 +DROP PUBLICATION testpub_syntax1 +-- +STMT: DropStmt +== 106 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 107 +CREATE PUBLICATION testpub_syntax2 FOR TABLE testpub_rf_tbl1, testpub_rf_schema1.testpub_rf_tbl5 WHERE (h < 999) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 108 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 109 +DROP PUBLICATION testpub_syntax2 +-- +STMT: DropStmt +== 110 +-- fail - schemas don't allow WHERE clause +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 111 +CREATE PUBLICATION testpub_syntax3 FOR TABLES IN SCHEMA testpub_rf_schema1 WHERE (a = 123) +-- +ERROR: syntax error at or near "WHERE" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 112 +CREATE PUBLICATION testpub_syntax3 FOR TABLES IN SCHEMA testpub_rf_schema1, testpub_rf_schema1 WHERE (a = 123) +-- +ERROR: WHERE clause not allowed for schema +CURSORPOS: 77 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 113 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 114 +-- fail - duplicate tables are not allowed if that table has any WHERE clause +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 115 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1 WHERE (a = 1), testpub_rf_tbl1 WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 116 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1, testpub_rf_tbl1 WHERE (a = 2) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 117 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 118 +-- fail - publication WHERE clause must be boolean +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (1234) +-- +STMT: AlterPublicationStmt +== 119 +-- fail - aggregate functions not allowed in WHERE clause +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e < AVG(e)) +-- +STMT: AlterPublicationStmt +== 120 +-- fail - user-defined operators are not allowed +CREATE FUNCTION testpub_rf_func1(integer, integer) RETURNS boolean AS $$ SELECT hashint4($1) > $2 $$ LANGUAGE SQL +-- +FUNCTION: name="testpub_rf_func1" function="testpub_rf_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 121 +CREATE OPERATOR =#> (PROCEDURE = testpub_rf_func1, LEFTARG = integer, RIGHTARG = integer) +-- +STMT: DefineStmt +== 122 +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl3 WHERE (e =#> 27) +-- +STMT: CreatePublicationStmt +== 123 +-- fail - user-defined functions are not allowed +CREATE FUNCTION testpub_rf_func2() RETURNS integer AS $$ BEGIN RETURN 123; END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="testpub_rf_func2" function="testpub_rf_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 124 +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a >= testpub_rf_func2()) +-- +STMT: AlterPublicationStmt +== 125 +-- fail - non-immutable functions are not allowed. random() is volatile. +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a < random()) +-- +STMT: AlterPublicationStmt +== 126 +-- fail - user-defined collations are not allowed +CREATE COLLATION user_collation FROM "C" +-- +STMT: DefineStmt +== 127 +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (b < '2' COLLATE user_collation) +-- +STMT: AlterPublicationStmt +== 128 +-- ok - NULLIF is allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (NULLIF(1,2) = a) +-- +STMT: AlterPublicationStmt +== 129 +-- ok - built-in operators are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS NULL) +-- +STMT: AlterPublicationStmt +== 130 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((a > 5) IS FALSE) +-- +STMT: AlterPublicationStmt +== 131 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS DISTINCT FROM 5) +-- +STMT: AlterPublicationStmt +== 132 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((a, a + 1) < (2, 3)) +-- +STMT: AlterPublicationStmt +== 133 +-- ok - built-in type coercions between two binary compatible datatypes are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (b::varchar < '2') +-- +STMT: AlterPublicationStmt +== 134 +-- ok - immutable built-in functions are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl4 WHERE (length(g) < 6) +-- +STMT: AlterPublicationStmt +== 135 +-- fail - user-defined types are not allowed +CREATE TYPE rf_bug_status AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +== 136 +CREATE TABLE rf_bug (id serial, description text, status rf_bug_status) +-- +TABLE: name="rf_bug" schema="" table="rf_bug" ctx=DDL +STMT: CreateStmt +== 137 +CREATE PUBLICATION testpub6 FOR TABLE rf_bug WHERE (status = 'open') WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 138 +DROP TABLE rf_bug +-- +TABLE: name="rf_bug" schema="" table="rf_bug" ctx=DDL +STMT: DropStmt +== 139 +DROP TYPE rf_bug_status +-- +STMT: DropStmt +== 140 +-- fail - row filter expression is not simple +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE (a IN (SELECT generate_series(1,5))) +-- +STMT: CreatePublicationStmt +== 141 +-- fail - system columns are not allowed +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE ('(0,1)'::tid = ctid) +-- +STMT: CreatePublicationStmt +== 142 +-- ok - conditional expressions are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (a IS DOCUMENT) +-- +STMT: AlterPublicationStmt +== 143 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (xmlexists('//foo[text() = ''bar'']' PASSING BY VALUE a)) +-- +STMT: AlterPublicationStmt +== 144 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (NULLIF(1, 2) = a) +-- +STMT: AlterPublicationStmt +== 145 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (CASE a WHEN 5 THEN true ELSE false END) +-- +STMT: AlterPublicationStmt +== 146 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (COALESCE(b, 'foo') = 'foo') +-- +STMT: AlterPublicationStmt +== 147 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (GREATEST(a, 10) > 10) +-- +STMT: AlterPublicationStmt +== 148 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IN (2, 4, 6)) +-- +STMT: AlterPublicationStmt +== 149 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ARRAY[a] <@ ARRAY[2, 4, 6]) +-- +STMT: AlterPublicationStmt +== 150 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ROW(a, 2) IS NULL) +-- +STMT: AlterPublicationStmt +== 151 +-- fail - WHERE not allowed in DROP +ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl1 WHERE (e < 27) +-- +STMT: AlterPublicationStmt +== 152 +-- fail - cannot ALTER SET table which is a member of a pre-existing schema +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 153 +CREATE PUBLICATION testpub6 FOR TABLES IN SCHEMA testpub_rf_schema2 +-- +STMT: CreatePublicationStmt +== 154 +-- should be able to set publication with schema and table of the same schema +ALTER PUBLICATION testpub6 SET TABLES IN SCHEMA testpub_rf_schema2, TABLE testpub_rf_schema2.testpub_rf_tbl6 WHERE (i < 99) +-- +STMT: AlterPublicationStmt +== 155 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 156 +DROP TABLE testpub_rf_tbl1 +-- +TABLE: name="testpub_rf_tbl1" schema="" table="testpub_rf_tbl1" ctx=DDL +STMT: DropStmt +== 157 +DROP TABLE testpub_rf_tbl2 +-- +TABLE: name="testpub_rf_tbl2" schema="" table="testpub_rf_tbl2" ctx=DDL +STMT: DropStmt +== 158 +DROP TABLE testpub_rf_tbl3 +-- +TABLE: name="testpub_rf_tbl3" schema="" table="testpub_rf_tbl3" ctx=DDL +STMT: DropStmt +== 159 +DROP TABLE testpub_rf_tbl4 +-- +TABLE: name="testpub_rf_tbl4" schema="" table="testpub_rf_tbl4" ctx=DDL +STMT: DropStmt +== 160 +DROP TABLE testpub_rf_tbl5 +-- +TABLE: name="testpub_rf_tbl5" schema="" table="testpub_rf_tbl5" ctx=DDL +STMT: DropStmt +== 161 +DROP TABLE testpub_rf_schema1.testpub_rf_tbl5 +-- +TABLE: name="testpub_rf_schema1.testpub_rf_tbl5" schema="testpub_rf_schema1" table="testpub_rf_tbl5" ctx=DDL +STMT: DropStmt +== 162 +DROP TABLE testpub_rf_schema2.testpub_rf_tbl6 +-- +TABLE: name="testpub_rf_schema2.testpub_rf_tbl6" schema="testpub_rf_schema2" table="testpub_rf_tbl6" ctx=DDL +STMT: DropStmt +== 163 +DROP SCHEMA testpub_rf_schema1 +-- +STMT: DropStmt +== 164 +DROP SCHEMA testpub_rf_schema2 +-- +STMT: DropStmt +== 165 +DROP PUBLICATION testpub5 +-- +STMT: DropStmt +== 166 +DROP PUBLICATION testpub6 +-- +STMT: DropStmt +== 167 +DROP OPERATOR =#>(integer, integer) +-- +STMT: DropStmt +== 168 +DROP FUNCTION testpub_rf_func1(integer, integer) +-- +FUNCTION: name="testpub_rf_func1" function="testpub_rf_func1" schema="" ctx=DDL +STMT: DropStmt +== 169 +DROP FUNCTION testpub_rf_func2() +-- +FUNCTION: name="testpub_rf_func2" function="testpub_rf_func2" schema="" ctx=DDL +STMT: DropStmt +== 170 +DROP COLLATION user_collation +-- +STMT: DropStmt +== 171 +-- ====================================================== +-- More row filter tests for validating column references +CREATE TABLE rf_tbl_abcd_nopk(a int, b int, c int, d int) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: CreateStmt +== 172 +CREATE TABLE rf_tbl_abcd_pk(a int, b int, c int, d int, PRIMARY KEY(a,b)) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: CreateStmt +== 173 +CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION by RANGE (a) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: CreateStmt +== 174 +CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY) +-- +TABLE: name="rf_tbl_abcd_part_pk_1" schema="" table="rf_tbl_abcd_part_pk_1" ctx=DDL +STMT: CreateStmt +== 175 +ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: AlterTableStmt +== 176 +-- Case 1. REPLICA IDENTITY DEFAULT (means use primary key or nothing) +-- 1a. REPLICA IDENTITY is DEFAULT and table has a PK. +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 177 +CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk WHERE (a > 99) +-- +STMT: CreatePublicationStmt +== 178 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 179 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 180 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (b > 99) +-- +STMT: AlterPublicationStmt +== 181 +-- ok - "b" is a PK col +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 182 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +== 183 +-- fail - "c" is not part of the PK +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 184 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (d > 99) +-- +STMT: AlterPublicationStmt +== 185 +-- fail - "d" is not part of the PK +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 186 +-- 1b. REPLICA IDENTITY is DEFAULT and table has no PK +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 187 +-- fail - "a" is not part of REPLICA IDENTITY +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 188 +-- Case 2. REPLICA IDENTITY FULL +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 189 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 190 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +== 191 +-- ok - "c" is in REPLICA IDENTITY now even though not in PK +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 192 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 193 +-- ok - "a" is in REPLICA IDENTITY now +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 194 +-- Case 3. REPLICA IDENTITY NOTHING +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 195 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 196 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 197 +-- fail - "a" is in PK but it is not part of REPLICA IDENTITY NOTHING +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 198 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +== 199 +-- fail - "c" is not in PK and not in REPLICA IDENTITY NOTHING +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 200 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 201 +-- fail - "a" is not in REPLICA IDENTITY NOTHING +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 202 +-- Case 4. REPLICA IDENTITY INDEX +ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 203 +CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk(c) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: IndexStmt +== 204 +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 205 +ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 206 +CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk(c) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: IndexStmt +== 207 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 208 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 209 +-- fail - "a" is in PK but it is not part of REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 210 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +== 211 +-- ok - "c" is not in PK but it is part of REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 212 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 213 +-- fail - "a" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 214 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +== 215 +-- ok - "c" is part of REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 216 +-- Tests for partitioned table + +-- set PUBLISH_VIA_PARTITION_ROOT to false and test row filter for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 217 +-- fail - cannot use row filter for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 218 +-- ok - can use row filter for partition +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 219 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 220 +-- set PUBLISH_VIA_PARTITION_ROOT to true and test row filter for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +== 221 +-- ok - can use row filter for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +== 222 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 223 +-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any row filter is +-- used for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 224 +-- remove partitioned table's row filter +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk +-- +STMT: AlterPublicationStmt +== 225 +-- ok - we don't have row filter for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 226 +-- Now change the root filter to use a column "b" +-- (which is not in the replica identity) +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99) +-- +STMT: AlterPublicationStmt +== 227 +-- ok - we don't have row filter for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 228 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 229 +-- set PUBLISH_VIA_PARTITION_ROOT to true +-- can use row filter for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +== 230 +-- ok - can use row filter for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (b > 99) +-- +STMT: AlterPublicationStmt +== 231 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 232 +DROP PUBLICATION testpub6 +-- +STMT: DropStmt +== 233 +DROP TABLE rf_tbl_abcd_pk +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: DropStmt +== 234 +DROP TABLE rf_tbl_abcd_nopk +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: DropStmt +== 235 +DROP TABLE rf_tbl_abcd_part_pk +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: DropStmt +== 236 +-- ====================================================== + +-- fail - duplicate tables are not allowed if that table has any column lists +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 237 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1 (a), testpub_tbl1 WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 238 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1, testpub_tbl1 (a) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 239 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 240 +-- test for column lists +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 241 +CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1 +-- +STMT: CreatePublicationStmt +== 242 +CREATE PUBLICATION testpub_fortable_insert WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +== 243 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 244 +CREATE TABLE testpub_tbl5 (a int PRIMARY KEY, b text, c text, + d int generated always as (a + length(b)) stored) +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: CreateStmt +== 245 +-- error: column "x" does not exist +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, x) +-- +STMT: AlterPublicationStmt +== 246 +-- error: replica identity "a" not included in the column list +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (b, c) +-- +STMT: AlterPublicationStmt +== 247 +UPDATE testpub_tbl5 SET a = 1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DML +STMT: UpdateStmt +== 248 +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5 +-- +STMT: AlterPublicationStmt +== 249 +-- error: generated column "d" can't be in list +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, d) +-- +STMT: AlterPublicationStmt +== 250 +-- error: system attributes "ctid" not allowed in column list +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, ctid) +-- +STMT: AlterPublicationStmt +== 251 +-- ok +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, c) +-- +STMT: AlterPublicationStmt +== 252 +ALTER TABLE testpub_tbl5 DROP COLUMN c +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +== 253 +-- no dice +-- ok: for insert-only publication, any column list is acceptable +ALTER PUBLICATION testpub_fortable_insert ADD TABLE testpub_tbl5 (b, c) +-- +STMT: AlterPublicationStmt +== 254 +/* not all replica identities are good enough */ +CREATE UNIQUE INDEX testpub_tbl5_b_key ON testpub_tbl5 (b, c) +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: IndexStmt +== 255 +ALTER TABLE testpub_tbl5 ALTER b SET NOT NULL, ALTER c SET NOT NULL +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +== 256 +ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +== 257 +-- error: replica identity (b,c) is not covered by column list (a, c) +UPDATE testpub_tbl5 SET a = 1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DML +STMT: UpdateStmt +== 258 +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5 +-- +STMT: AlterPublicationStmt +== 259 +-- error: change the replica identity to "b", and column list to (a, c) +-- then update fails, because (a, c) does not cover replica identity +ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +== 260 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, c) +-- +STMT: AlterPublicationStmt +== 261 +UPDATE testpub_tbl5 SET a = 1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DML +STMT: UpdateStmt +== 262 +/* But if upd/del are not published, it works OK */ +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 263 +CREATE PUBLICATION testpub_table_ins WITH (publish = 'insert, truncate') +-- +STMT: CreatePublicationStmt +== 264 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 265 +ALTER PUBLICATION testpub_table_ins ADD TABLE testpub_tbl5 (a) +-- +STMT: AlterPublicationStmt +== 266 +-- ok + +-- error: cannot work with deferrable primary keys +CREATE TABLE testpub_tbl5d (a int PRIMARY KEY DEFERRABLE) +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DDL +STMT: CreateStmt +== 267 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5d +-- +STMT: AlterPublicationStmt +== 268 +UPDATE testpub_tbl5d SET a = 1 +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DML +STMT: UpdateStmt +== 269 +/* but works fine with FULL replica identity */ +ALTER TABLE testpub_tbl5d REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DDL +STMT: AlterTableStmt +== 270 +UPDATE testpub_tbl5d SET a = 1 +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DML +STMT: UpdateStmt +== 271 +DROP TABLE testpub_tbl5d +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DDL +STMT: DropStmt +== 272 +-- tests with REPLICA IDENTITY FULL +CREATE TABLE testpub_tbl6 (a int, b text, c text) +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DDL +STMT: CreateStmt +== 273 +ALTER TABLE testpub_tbl6 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DDL +STMT: AlterTableStmt +== 274 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6 (a, b, c) +-- +STMT: AlterPublicationStmt +== 275 +UPDATE testpub_tbl6 SET a = 1 +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DML +STMT: UpdateStmt +== 276 +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl6 +-- +STMT: AlterPublicationStmt +== 277 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6 +-- +STMT: AlterPublicationStmt +== 278 +-- ok +UPDATE testpub_tbl6 SET a = 1 +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DML +STMT: UpdateStmt +== 279 +-- make sure changing the column list is propagated to the catalog +CREATE TABLE testpub_tbl7 (a int primary key, b text, c text) +-- +TABLE: name="testpub_tbl7" schema="" table="testpub_tbl7" ctx=DDL +STMT: CreateStmt +== 280 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl7 (a, b) +-- +STMT: AlterPublicationStmt +== 281 +-- ok: the column list is the same, we should skip this table (or at least not fail) +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7 (a, b) +-- +STMT: AlterPublicationStmt +== 282 +-- ok: the column list changes, make sure the catalog gets updated +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7 (a, c) +-- +STMT: AlterPublicationStmt +== 283 +-- column list for partitioned tables has to cover replica identities for +-- all child relations +CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: CreateStmt +== 284 +-- first partition has replica identity "a" +CREATE TABLE testpub_tbl8_0 PARTITION OF testpub_tbl8 FOR VALUES WITH (modulus 2, remainder 0) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: CreateStmt +== 285 +ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +== 286 +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +== 287 +-- second partition has replica identity "b" +CREATE TABLE testpub_tbl8_1 PARTITION OF testpub_tbl8 FOR VALUES WITH (modulus 2, remainder 1) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: CreateStmt +== 288 +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (b) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 289 +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 290 +-- ok: column list covers both "a" and "b" +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 291 +CREATE PUBLICATION testpub_col_list FOR TABLE testpub_tbl8 (a, b) WITH (publish_via_partition_root = 'true') +-- +STMT: CreatePublicationStmt +== 292 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 293 +-- ok: the same thing, but try plain ADD TABLE +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +== 294 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b) +-- +STMT: AlterPublicationStmt +== 295 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +== 296 +-- failure: column list does not cover replica identity for the second partition +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +== 297 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, c) +-- +STMT: AlterPublicationStmt +== 298 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +== 299 +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +== 300 +-- failure: one of the partitions has REPLICA IDENTITY FULL +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 301 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, c) +-- +STMT: AlterPublicationStmt +== 302 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +== 303 +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +== 304 +-- add table and then try changing replica identity +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 305 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b) +-- +STMT: AlterPublicationStmt +== 306 +-- failure: replica identity full can't be used with a column list +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 307 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +== 308 +-- failure: replica identity has to be covered by the column list +ALTER TABLE testpub_tbl8_1 DROP CONSTRAINT testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 309 +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 310 +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 311 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +== 312 +DROP TABLE testpub_tbl8 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: DropStmt +== 313 +-- column list for partitioned tables has to cover replica identities for +-- all child relations +CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: CreateStmt +== 314 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b) +-- +STMT: AlterPublicationStmt +== 315 +-- first partition has replica identity "a" +CREATE TABLE testpub_tbl8_0 (a int, b text, c text) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: CreateStmt +== 316 +ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +== 317 +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +== 318 +-- second partition has replica identity "b" +CREATE TABLE testpub_tbl8_1 (a int, b text, c text) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: CreateStmt +== 319 +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 320 +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +== 321 +-- ok: attaching first partition works, because (a) is in column list +ALTER TABLE testpub_tbl8 ATTACH PARTITION testpub_tbl8_0 FOR VALUES WITH (modulus 2, remainder 0) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: AlterTableStmt +== 322 +-- failure: second partition has replica identity (c), which si not in column list +ALTER TABLE testpub_tbl8 ATTACH PARTITION testpub_tbl8_1 FOR VALUES WITH (modulus 2, remainder 1) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: AlterTableStmt +== 323 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +== 324 +-- failure: changing replica identity to FULL for partition fails, because +-- of the column list on the parent +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +== 325 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +== 326 +-- test that using column list for table is disallowed if any schemas are +-- part of the publication +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 327 +-- failure - cannot use column list and schema together +CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a) +-- +STMT: CreatePublicationStmt +== 328 +-- ok - only publish schema +CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public +-- +STMT: CreatePublicationStmt +== 329 +-- failure - add a table with column list when there is already a schema in the +-- publication +ALTER PUBLICATION testpub_tbl9 ADD TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +== 330 +-- ok - only publish table with column list +ALTER PUBLICATION testpub_tbl9 SET TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +== 331 +-- failure - specify a schema when there is already a column list in the +-- publication +ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public +-- +STMT: AlterPublicationStmt +== 332 +-- failure - cannot SET column list and schema together +ALTER PUBLICATION testpub_tbl9 SET TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +== 333 +-- ok - drop table +ALTER PUBLICATION testpub_tbl9 DROP TABLE public.testpub_tbl7 +-- +STMT: AlterPublicationStmt +== 334 +-- failure - cannot ADD column list and schema together +ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +== 335 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 336 +DROP TABLE testpub_tbl5, testpub_tbl6, testpub_tbl7, testpub_tbl8, testpub_tbl8_1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DDL +TABLE: name="testpub_tbl7" schema="" table="testpub_tbl7" ctx=DDL +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: DropStmt +== 337 +DROP PUBLICATION testpub_table_ins, testpub_fortable, testpub_fortable_insert, testpub_col_list, testpub_tbl9 +-- +STMT: DropStmt +== 338 +-- ====================================================== + +-- Test combination of column list and row filter +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 339 +CREATE PUBLICATION testpub_both_filters +-- +STMT: CreatePublicationStmt +== 340 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 341 +CREATE TABLE testpub_tbl_both_filters (a int, b int, c int, PRIMARY KEY (a,c)) +-- +TABLE: name="testpub_tbl_both_filters" schema="" table="testpub_tbl_both_filters" ctx=DDL +STMT: CreateStmt +== 342 +ALTER TABLE testpub_tbl_both_filters REPLICA IDENTITY USING INDEX testpub_tbl_both_filters_pkey +-- +TABLE: name="testpub_tbl_both_filters" schema="" table="testpub_tbl_both_filters" ctx=DDL +STMT: AlterTableStmt +== 343 +ALTER PUBLICATION testpub_both_filters ADD TABLE testpub_tbl_both_filters (a,c) WHERE (c != 1) +-- +STMT: AlterPublicationStmt +== 344 +DROP TABLE testpub_tbl_both_filters +-- +TABLE: name="testpub_tbl_both_filters" schema="" table="testpub_tbl_both_filters" ctx=DDL +STMT: DropStmt +== 345 +DROP PUBLICATION testpub_both_filters +-- +STMT: DropStmt +== 346 +-- ====================================================== + +-- More column list tests for validating column references +CREATE TABLE rf_tbl_abcd_nopk(a int, b int, c int, d int) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: CreateStmt +== 347 +CREATE TABLE rf_tbl_abcd_pk(a int, b int, c int, d int, PRIMARY KEY(a,b)) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: CreateStmt +== 348 +CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION by RANGE (a) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: CreateStmt +== 349 +CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY) +-- +TABLE: name="rf_tbl_abcd_part_pk_1" schema="" table="rf_tbl_abcd_part_pk_1" ctx=DDL +STMT: CreateStmt +== 350 +ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: AlterTableStmt +== 351 +-- Case 1. REPLICA IDENTITY DEFAULT (means use primary key or nothing) + +-- 1a. REPLICA IDENTITY is DEFAULT and table has a PK. +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 352 +CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk (a, b) +-- +STMT: CreatePublicationStmt +== 353 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 354 +-- ok - (a,b) covers all PK cols +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 355 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a, b, c) +-- +STMT: AlterPublicationStmt +== 356 +-- ok - (a,b,c) covers all PK cols +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 357 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a) +-- +STMT: AlterPublicationStmt +== 358 +-- fail - "b" is missing from the column list +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 359 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (b) +-- +STMT: AlterPublicationStmt +== 360 +-- fail - "a" is missing from the column list +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 361 +-- 1b. REPLICA IDENTITY is DEFAULT and table has no PK +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a) +-- +STMT: AlterPublicationStmt +== 362 +-- ok - there's no replica identity, so any column list works +-- note: it fails anyway, just a bit later because UPDATE requires RI +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 363 +-- Case 2. REPLICA IDENTITY FULL +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 364 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 365 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (c) +-- +STMT: AlterPublicationStmt +== 366 +-- fail - with REPLICA IDENTITY FULL no column list is allowed +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 367 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a, b, c, d) +-- +STMT: AlterPublicationStmt +== 368 +-- fail - with REPLICA IDENTITY FULL no column list is allowed +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 369 +-- Case 3. REPLICA IDENTITY NOTHING +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 370 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 371 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a) +-- +STMT: AlterPublicationStmt +== 372 +-- ok - REPLICA IDENTITY NOTHING means all column lists are valid +-- it still fails later because without RI we can't replicate updates +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 373 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a, b, c, d) +-- +STMT: AlterPublicationStmt +== 374 +-- ok - REPLICA IDENTITY NOTHING means all column lists are valid +-- it still fails later because without RI we can't replicate updates +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 375 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (d) +-- +STMT: AlterPublicationStmt +== 376 +-- ok - REPLICA IDENTITY NOTHING means all column lists are valid +-- it still fails later because without RI we can't replicate updates +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 377 +-- Case 4. REPLICA IDENTITY INDEX +ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 378 +CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk(c) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: IndexStmt +== 379 +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +== 380 +ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 381 +CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk(c) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: IndexStmt +== 382 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +== 383 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a) +-- +STMT: AlterPublicationStmt +== 384 +-- fail - column list "a" does not cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 385 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (c) +-- +STMT: AlterPublicationStmt +== 386 +-- ok - column list "c" does cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +== 387 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a) +-- +STMT: AlterPublicationStmt +== 388 +-- fail - column list "a" does not cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 389 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (c) +-- +STMT: AlterPublicationStmt +== 390 +-- ok - column list "c" does cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +== 391 +-- Tests for partitioned table + +-- set PUBLISH_VIA_PARTITION_ROOT to false and test column list for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 392 +-- fail - cannot use column list for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a) +-- +STMT: AlterPublicationStmt +== 393 +-- ok - can use column list for partition +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (a) +-- +STMT: AlterPublicationStmt +== 394 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 395 +-- set PUBLISH_VIA_PARTITION_ROOT to true and test column list for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +== 396 +-- ok - can use column list for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a) +-- +STMT: AlterPublicationStmt +== 397 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 398 +-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any column list is +-- used for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 399 +-- remove partitioned table's column list +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk +-- +STMT: AlterPublicationStmt +== 400 +-- ok - we don't have column list for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 401 +-- Now change the root column list to use a column "b" +-- (which is not in the replica identity) +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (b) +-- +STMT: AlterPublicationStmt +== 402 +-- ok - we don't have column list for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +== 403 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 404 +-- set PUBLISH_VIA_PARTITION_ROOT to true +-- can use column list for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +== 405 +-- ok - can use column list for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (b) +-- +STMT: AlterPublicationStmt +== 406 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +== 407 +DROP PUBLICATION testpub6 +-- +STMT: DropStmt +== 408 +DROP TABLE rf_tbl_abcd_pk +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: DropStmt +== 409 +DROP TABLE rf_tbl_abcd_nopk +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: DropStmt +== 410 +DROP TABLE rf_tbl_abcd_part_pk +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: DropStmt +== 411 +-- ====================================================== + +-- Test cache invalidation FOR ALL TABLES publication +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 412 +CREATE TABLE testpub_tbl4(a int) +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DDL +STMT: CreateStmt +== 413 +INSERT INTO testpub_tbl4 values(1) +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 414 +UPDATE testpub_tbl4 set a = 2 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: UpdateStmt +== 415 +CREATE PUBLICATION testpub_foralltables FOR ALL TABLES +-- +STMT: CreatePublicationStmt +== 416 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 417 +-- fail missing REPLICA IDENTITY +UPDATE testpub_tbl4 set a = 3 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: UpdateStmt +== 418 +DROP PUBLICATION testpub_foralltables +-- +STMT: DropStmt +== 419 +-- should pass after dropping the publication +UPDATE testpub_tbl4 set a = 3 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: UpdateStmt +== 420 +DROP TABLE testpub_tbl4 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DDL +STMT: DropStmt +== 421 +-- fail - view +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view +-- +STMT: CreatePublicationStmt +== 422 +CREATE TEMPORARY TABLE testpub_temptbl(a int) +-- +TABLE: name="testpub_temptbl" schema="" table="testpub_temptbl" ctx=DDL +STMT: CreateStmt +== 423 +-- fail - temporary table +CREATE PUBLICATION testpub_fortemptbl FOR TABLE testpub_temptbl +-- +STMT: CreatePublicationStmt +== 424 +DROP TABLE testpub_temptbl +-- +TABLE: name="testpub_temptbl" schema="" table="testpub_temptbl" ctx=DDL +STMT: DropStmt +== 425 +CREATE UNLOGGED TABLE testpub_unloggedtbl(a int) +-- +TABLE: name="testpub_unloggedtbl" schema="" table="testpub_unloggedtbl" ctx=DDL +STMT: CreateStmt +== 426 +-- fail - unlogged table +CREATE PUBLICATION testpub_forunloggedtbl FOR TABLE testpub_unloggedtbl +-- +STMT: CreatePublicationStmt +== 427 +DROP TABLE testpub_unloggedtbl +-- +TABLE: name="testpub_unloggedtbl" schema="" table="testpub_unloggedtbl" ctx=DDL +STMT: DropStmt +== 428 +-- fail - system table +CREATE PUBLICATION testpub_forsystemtbl FOR TABLE pg_publication +-- +STMT: CreatePublicationStmt +== 429 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 430 +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1, pub_test.testpub_nopk +-- +STMT: CreatePublicationStmt +== 431 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 432 +-- fail - already added +ALTER PUBLICATION testpub_fortbl ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +== 433 +-- fail - already added +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1 +-- +STMT: CreatePublicationStmt +== 434 +-- fail - view +ALTER PUBLICATION testpub_default ADD TABLE testpub_view +-- +STMT: AlterPublicationStmt +== 435 +ALTER PUBLICATION testpub_default ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +== 436 +ALTER PUBLICATION testpub_default SET TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +== 437 +ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 438 +ALTER PUBLICATION testpib_ins_trunct ADD TABLE pub_test.testpub_nopk, testpub_tbl1 +-- +STMT: AlterPublicationStmt +== 439 +ALTER PUBLICATION testpub_default DROP TABLE testpub_tbl1, pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 440 +-- fail - nonexistent +ALTER PUBLICATION testpub_default DROP TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +== 441 +-- verify relation cache invalidation when a primary key is added using +-- an existing index +CREATE TABLE pub_test.testpub_addpk (id int not null, data int) +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: CreateStmt +== 442 +ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_addpk +-- +STMT: AlterPublicationStmt +== 443 +INSERT INTO pub_test.testpub_addpk VALUES(1, 11) +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 444 +CREATE UNIQUE INDEX testpub_addpk_id_idx ON pub_test.testpub_addpk(id) +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: IndexStmt +== 445 +-- fail: +UPDATE pub_test.testpub_addpk SET id = 2 +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DML +STMT: UpdateStmt +== 446 +ALTER TABLE pub_test.testpub_addpk ADD PRIMARY KEY USING INDEX testpub_addpk_id_idx +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: AlterTableStmt +== 447 +-- now it should work: +UPDATE pub_test.testpub_addpk SET id = 2 +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DML +STMT: UpdateStmt +== 448 +DROP TABLE pub_test.testpub_addpk +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: DropStmt +== 449 +-- permissions +SET ROLE regress_publication_user2 +-- +STMT: VariableSetStmt +== 450 +CREATE PUBLICATION testpub2 +-- +STMT: CreatePublicationStmt +== 451 +-- fail + +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +== 452 +GRANT CREATE ON DATABASE regression TO regress_publication_user2 +-- +STMT: GrantStmt +== 453 +SET ROLE regress_publication_user2 +-- +STMT: VariableSetStmt +== 454 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 455 +CREATE PUBLICATION testpub2 +-- +STMT: CreatePublicationStmt +== 456 +-- ok +CREATE PUBLICATION testpub3 FOR TABLES IN SCHEMA pub_test +-- +STMT: CreatePublicationStmt +== 457 +-- fail +CREATE PUBLICATION testpub3 +-- +STMT: CreatePublicationStmt +== 458 +-- ok +RESET client_min_messages +-- +STMT: VariableSetStmt +== 459 +ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +== 460 +-- fail +ALTER PUBLICATION testpub3 ADD TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +== 461 +-- fail + +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +== 462 +GRANT regress_publication_user TO regress_publication_user2 +-- +STMT: GrantRoleStmt +== 463 +SET ROLE regress_publication_user2 +-- +STMT: VariableSetStmt +== 464 +ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +== 465 +-- ok + +DROP PUBLICATION testpub2 +-- +STMT: DropStmt +== 466 +DROP PUBLICATION testpub3 +-- +STMT: DropStmt +== 467 +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +== 468 +CREATE ROLE regress_publication_user3 +-- +STMT: CreateRoleStmt +== 469 +GRANT regress_publication_user2 TO regress_publication_user3 +-- +STMT: GrantRoleStmt +== 470 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 471 +CREATE PUBLICATION testpub4 FOR TABLES IN SCHEMA pub_test +-- +STMT: CreatePublicationStmt +== 472 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 473 +ALTER PUBLICATION testpub4 OWNER TO regress_publication_user3 +-- +STMT: AlterOwnerStmt +== 474 +SET ROLE regress_publication_user3 +-- +STMT: VariableSetStmt +== 475 +-- fail - new owner must be superuser +ALTER PUBLICATION testpub4 owner to regress_publication_user2 +-- +STMT: AlterOwnerStmt +== 476 +-- fail +ALTER PUBLICATION testpub4 owner to regress_publication_user +-- +STMT: AlterOwnerStmt +== 477 +-- ok + +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +== 478 +DROP PUBLICATION testpub4 +-- +STMT: DropStmt +== 479 +DROP ROLE regress_publication_user3 +-- +STMT: DropRoleStmt +== 480 +REVOKE CREATE ON DATABASE regression FROM regress_publication_user2 +-- +STMT: GrantStmt +== 481 +DROP TABLE testpub_parted +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: DropStmt +== 482 +DROP TABLE testpub_tbl1 +-- +TABLE: name="testpub_tbl1" schema="" table="testpub_tbl1" ctx=DDL +STMT: DropStmt +== 483 +-- fail - must be owner of publication +SET ROLE regress_publication_user_dummy +-- +STMT: VariableSetStmt +== 484 +ALTER PUBLICATION testpub_default RENAME TO testpub_dummy +-- +STMT: RenameStmt +== 485 +RESET ROLE +-- +STMT: VariableSetStmt +== 486 +ALTER PUBLICATION testpub_default RENAME TO testpub_foo +-- +STMT: RenameStmt +== 487 +-- rename back to keep the rest simple +ALTER PUBLICATION testpub_foo RENAME TO testpub_default +-- +STMT: RenameStmt +== 488 +ALTER PUBLICATION testpub_default OWNER TO regress_publication_user2 +-- +STMT: AlterOwnerStmt +== 489 +-- adding schemas and tables +CREATE SCHEMA pub_test1 +-- +STMT: CreateSchemaStmt +== 490 +CREATE SCHEMA pub_test2 +-- +STMT: CreateSchemaStmt +== 491 +CREATE SCHEMA pub_test3 +-- +STMT: CreateSchemaStmt +== 492 +CREATE SCHEMA "CURRENT_SCHEMA" +-- +STMT: CreateSchemaStmt +== 493 +CREATE TABLE pub_test1.tbl (id int, data text) +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DDL +STMT: CreateStmt +== 494 +CREATE TABLE pub_test1.tbl1 (id serial primary key, data text) +-- +TABLE: name="pub_test1.tbl1" schema="pub_test1" table="tbl1" ctx=DDL +STMT: CreateStmt +== 495 +CREATE TABLE pub_test2.tbl1 (id serial primary key, data text) +-- +TABLE: name="pub_test2.tbl1" schema="pub_test2" table="tbl1" ctx=DDL +STMT: CreateStmt +== 496 +CREATE TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"(id int) +-- +TABLE: name="\"CURRENT_SCHEMA\".\"CURRENT_SCHEMA\"" schema="CURRENT_SCHEMA" table="CURRENT_SCHEMA" ctx=DDL +STMT: CreateStmt +== 497 +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 498 +CREATE PUBLICATION testpub1_forschema FOR TABLES IN SCHEMA pub_test1 +-- +STMT: CreatePublicationStmt +== 499 +CREATE PUBLICATION testpub2_forschema FOR TABLES IN SCHEMA pub_test1, pub_test2, pub_test3 +-- +STMT: CreatePublicationStmt +== 500 +-- check create publication on CURRENT_SCHEMA +CREATE PUBLICATION testpub3_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA +-- +STMT: CreatePublicationStmt +== 501 +CREATE PUBLICATION testpub4_forschema FOR TABLES IN SCHEMA "CURRENT_SCHEMA" +-- +STMT: CreatePublicationStmt +== 502 +CREATE PUBLICATION testpub5_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA, "CURRENT_SCHEMA" +-- +STMT: CreatePublicationStmt +== 503 +CREATE PUBLICATION testpub6_forschema FOR TABLES IN SCHEMA "CURRENT_SCHEMA", CURRENT_SCHEMA +-- +STMT: CreatePublicationStmt +== 504 +CREATE PUBLICATION testpub_fortable FOR TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA" +-- +STMT: CreatePublicationStmt +== 505 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 506 +-- check create publication on CURRENT_SCHEMA where search_path is not set +SET SEARCH_PATH='' +-- +STMT: VariableSetStmt +== 507 +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA +-- +STMT: CreatePublicationStmt +== 508 +RESET SEARCH_PATH +-- +STMT: VariableSetStmt +== 509 +-- check create publication on CURRENT_SCHEMA where TABLE/TABLES in SCHEMA +-- is not specified +CREATE PUBLICATION testpub_forschema1 FOR CURRENT_SCHEMA +-- +ERROR: invalid publication object list +CURSORPOS: 138 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 510 +-- check create publication on CURRENT_SCHEMA along with FOR TABLE +CREATE PUBLICATION testpub_forschema1 FOR TABLE CURRENT_SCHEMA +-- +ERROR: syntax error at or near "CURRENT_SCHEMA" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 511 +-- check create publication on a schema that does not exist +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA non_existent_schema +-- +STMT: CreatePublicationStmt +== 512 +-- check create publication on a system schema +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pg_catalog +-- +STMT: CreatePublicationStmt +== 513 +-- check create publication on an object which is not schema +CREATE PUBLICATION testpub1_forschema1 FOR TABLES IN SCHEMA testpub_view +-- +STMT: CreatePublicationStmt +== 514 +-- dropping the schema should reflect the change in publication +DROP SCHEMA pub_test3 +-- +STMT: DropStmt +== 515 +-- renaming the schema should reflect the change in publication +ALTER SCHEMA pub_test1 RENAME to pub_test1_renamed +-- +STMT: RenameStmt +== 516 +ALTER SCHEMA pub_test1_renamed RENAME to pub_test1 +-- +STMT: RenameStmt +== 517 +-- alter publication add schema +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test2 +-- +STMT: AlterPublicationStmt +== 518 +-- add non existent schema +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA non_existent_schema +-- +STMT: AlterPublicationStmt +== 519 +-- add a schema which is already added to the publication +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +== 520 +-- alter publication drop schema +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2 +-- +STMT: AlterPublicationStmt +== 521 +-- drop schema that is not present in the publication +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2 +-- +STMT: AlterPublicationStmt +== 522 +-- drop a schema that does not exist in the system +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA non_existent_schema +-- +STMT: AlterPublicationStmt +== 523 +-- drop all schemas +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +== 524 +-- alter publication set multiple schema +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test2 +-- +STMT: AlterPublicationStmt +== 525 +-- alter publication set non-existent schema +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA non_existent_schema +-- +STMT: AlterPublicationStmt +== 526 +-- alter publication set it duplicate schemas should set the schemas after +-- removing the duplicate schemas +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test1 +-- +STMT: AlterPublicationStmt +== 527 +-- Verify that it fails to add a schema with a column specification +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA foo (a, b) +-- +ERROR: syntax error at or near "(" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 528 +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA foo, bar (a, b) +-- +ERROR: column specification not allowed for schema +CURSORPOS: 64 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 529 +-- cleanup pub_test1 schema for invalidation tests +ALTER PUBLICATION testpub2_forschema DROP TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +== 530 +DROP PUBLICATION testpub3_forschema, testpub4_forschema, testpub5_forschema, testpub6_forschema, testpub_fortable +-- +STMT: DropStmt +== 531 +DROP SCHEMA "CURRENT_SCHEMA" CASCADE +-- +STMT: DropStmt +== 532 +-- verify relation cache invalidations through update statement for the +-- default REPLICA IDENTITY on the relation, if schema is part of the +-- publication then update will fail because relation's relreplident +-- option will be set, if schema is not part of the publication then update +-- will be successful. +INSERT INTO pub_test1.tbl VALUES(1, 'test') +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 533 +-- fail +UPDATE pub_test1.tbl SET id = 2 +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: UpdateStmt +== 534 +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +== 535 +-- success +UPDATE pub_test1.tbl SET id = 2 +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: UpdateStmt +== 536 +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +== 537 +-- fail +UPDATE pub_test1.tbl SET id = 2 +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: UpdateStmt +== 538 +-- verify invalidation of partition table having parent and child tables in +-- different schema +CREATE SCHEMA pub_testpart1 +-- +STMT: CreateSchemaStmt +== 539 +CREATE SCHEMA pub_testpart2 +-- +STMT: CreateSchemaStmt +== 540 +CREATE TABLE pub_testpart1.parent1 (a int) partition by list (a) +-- +TABLE: name="pub_testpart1.parent1" schema="pub_testpart1" table="parent1" ctx=DDL +STMT: CreateStmt +== 541 +CREATE TABLE pub_testpart2.child_parent1 partition of pub_testpart1.parent1 for values in (1) +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DDL +STMT: CreateStmt +== 542 +INSERT INTO pub_testpart2.child_parent1 values(1) +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 543 +UPDATE pub_testpart2.child_parent1 set a = 1 +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: UpdateStmt +== 544 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 545 +CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart1 +-- +STMT: CreatePublicationStmt +== 546 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 547 +-- fail +UPDATE pub_testpart1.parent1 set a = 1 +-- +TABLE: name="pub_testpart1.parent1" schema="pub_testpart1" table="parent1" ctx=DML +STMT: UpdateStmt +== 548 +UPDATE pub_testpart2.child_parent1 set a = 1 +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: UpdateStmt +== 549 +DROP PUBLICATION testpubpart_forschema +-- +STMT: DropStmt +== 550 +-- verify invalidation of partition tables for schema publication that has +-- parent and child tables of different partition hierarchies +CREATE TABLE pub_testpart2.parent2 (a int) partition by list (a) +-- +TABLE: name="pub_testpart2.parent2" schema="pub_testpart2" table="parent2" ctx=DDL +STMT: CreateStmt +== 551 +CREATE TABLE pub_testpart1.child_parent2 partition of pub_testpart2.parent2 for values in (1) +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DDL +STMT: CreateStmt +== 552 +INSERT INTO pub_testpart1.child_parent2 values(1) +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 553 +UPDATE pub_testpart1.child_parent2 set a = 1 +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DML +STMT: UpdateStmt +== 554 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 555 +CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart2 +-- +STMT: CreatePublicationStmt +== 556 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 557 +-- fail +UPDATE pub_testpart2.child_parent1 set a = 1 +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: UpdateStmt +== 558 +UPDATE pub_testpart2.parent2 set a = 1 +-- +TABLE: name="pub_testpart2.parent2" schema="pub_testpart2" table="parent2" ctx=DML +STMT: UpdateStmt +== 559 +UPDATE pub_testpart1.child_parent2 set a = 1 +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DML +STMT: UpdateStmt +== 560 +-- alter publication set 'TABLES IN SCHEMA' on an empty publication. +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 561 +CREATE PUBLICATION testpub3_forschema +-- +STMT: CreatePublicationStmt +== 562 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 563 +ALTER PUBLICATION testpub3_forschema SET TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +== 564 +-- create publication including both 'FOR TABLE' and 'FOR TABLES IN SCHEMA' +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 565 +CREATE PUBLICATION testpub_forschema_fortable FOR TABLES IN SCHEMA pub_test1, TABLE pub_test2.tbl1 +-- +STMT: CreatePublicationStmt +== 566 +CREATE PUBLICATION testpub_fortable_forschema FOR TABLE pub_test2.tbl1, TABLES IN SCHEMA pub_test1 +-- +STMT: CreatePublicationStmt +== 567 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 568 +-- fail specifying table without any of 'FOR TABLES IN SCHEMA' or +--'FOR TABLE' or 'FOR ALL TABLES' +CREATE PUBLICATION testpub_error FOR pub_test2.tbl1 +-- +ERROR: invalid publication object list +CURSORPOS: 138 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 569 +DROP VIEW testpub_view +-- +STMT: DropStmt +== 570 +DROP PUBLICATION testpub_default +-- +STMT: DropStmt +== 571 +DROP PUBLICATION testpib_ins_trunct +-- +STMT: DropStmt +== 572 +DROP PUBLICATION testpub_fortbl +-- +STMT: DropStmt +== 573 +DROP PUBLICATION testpub1_forschema +-- +STMT: DropStmt +== 574 +DROP PUBLICATION testpub2_forschema +-- +STMT: DropStmt +== 575 +DROP PUBLICATION testpub3_forschema +-- +STMT: DropStmt +== 576 +DROP PUBLICATION testpub_forschema_fortable +-- +STMT: DropStmt +== 577 +DROP PUBLICATION testpub_fortable_forschema +-- +STMT: DropStmt +== 578 +DROP PUBLICATION testpubpart_forschema +-- +STMT: DropStmt +== 579 +DROP SCHEMA pub_test CASCADE +-- +STMT: DropStmt +== 580 +DROP SCHEMA pub_test1 CASCADE +-- +STMT: DropStmt +== 581 +DROP SCHEMA pub_test2 CASCADE +-- +STMT: DropStmt +== 582 +DROP SCHEMA pub_testpart1 CASCADE +-- +STMT: DropStmt +== 583 +DROP SCHEMA pub_testpart2 CASCADE +-- +STMT: DropStmt +== 584 +-- Test the list of partitions published with or without +-- 'PUBLISH_VIA_PARTITION_ROOT' parameter +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 585 +CREATE SCHEMA sch1 +-- +STMT: CreateSchemaStmt +== 586 +CREATE SCHEMA sch2 +-- +STMT: CreateSchemaStmt +== 587 +CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a) +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: CreateStmt +== 588 +CREATE TABLE sch2.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10) +-- +TABLE: name="sch2.tbl1_part1" schema="sch2" table="tbl1_part1" ctx=DDL +STMT: CreateStmt +== 589 +-- Schema publication that does not include the schema that has the parent table +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: CreatePublicationStmt +== 590 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +== 591 +DROP PUBLICATION pub +-- +STMT: DropStmt +== 592 +-- Table publication that does not include the parent table +CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: CreatePublicationStmt +== 593 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +== 594 +-- Table publication that includes both the parent table and the child table +ALTER PUBLICATION pub ADD TABLE sch1.tbl1 +-- +STMT: AlterPublicationStmt +== 595 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +== 596 +DROP PUBLICATION pub +-- +STMT: DropStmt +== 597 +-- Schema publication that does not include the schema that has the parent table +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: CreatePublicationStmt +== 598 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +== 599 +DROP PUBLICATION pub +-- +STMT: DropStmt +== 600 +-- Table publication that does not include the parent table +CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: CreatePublicationStmt +== 601 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +== 602 +-- Table publication that includes both the parent table and the child table +ALTER PUBLICATION pub ADD TABLE sch1.tbl1 +-- +STMT: AlterPublicationStmt +== 603 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +== 604 +DROP PUBLICATION pub +-- +STMT: DropStmt +== 605 +DROP TABLE sch2.tbl1_part1 +-- +TABLE: name="sch2.tbl1_part1" schema="sch2" table="tbl1_part1" ctx=DDL +STMT: DropStmt +== 606 +DROP TABLE sch1.tbl1 +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: DropStmt +== 607 +CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a) +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: CreateStmt +== 608 +CREATE TABLE sch1.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10) +-- +TABLE: name="sch1.tbl1_part1" schema="sch1" table="tbl1_part1" ctx=DDL +STMT: CreateStmt +== 609 +CREATE TABLE sch1.tbl1_part2 PARTITION OF sch1.tbl1 FOR VALUES FROM (10) to (20) +-- +TABLE: name="sch1.tbl1_part2" schema="sch1" table="tbl1_part2" ctx=DDL +STMT: CreateStmt +== 610 +CREATE TABLE sch1.tbl1_part3 (a int) PARTITION BY RANGE(a) +-- +TABLE: name="sch1.tbl1_part3" schema="sch1" table="tbl1_part3" ctx=DDL +STMT: CreateStmt +== 611 +ALTER TABLE sch1.tbl1 ATTACH PARTITION sch1.tbl1_part3 FOR VALUES FROM (20) to (30) +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: AlterTableStmt +== 612 +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch1 WITH (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: CreatePublicationStmt +== 613 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +== 614 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 615 +DROP PUBLICATION pub +-- +STMT: DropStmt +== 616 +DROP TABLE sch1.tbl1 +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: DropStmt +== 617 +DROP SCHEMA sch1 cascade +-- +STMT: DropStmt +== 618 +DROP SCHEMA sch2 cascade +-- +STMT: DropStmt +== 619 +-- Test that the INSERT ON CONFLICT command correctly checks REPLICA IDENTITY +-- when the target table is published. +CREATE TABLE testpub_insert_onconfl_no_ri (a int unique, b int) +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DDL +STMT: CreateStmt +== 620 +CREATE TABLE testpub_insert_onconfl_parted (a int unique, b int) PARTITION by RANGE (a) +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DDL +STMT: CreateStmt +== 621 +CREATE TABLE testpub_insert_onconfl_part_no_ri PARTITION OF testpub_insert_onconfl_parted FOR VALUES FROM (1) TO (10) +-- +TABLE: name="testpub_insert_onconfl_part_no_ri" schema="" table="testpub_insert_onconfl_part_no_ri" ctx=DDL +STMT: CreateStmt +== 622 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 623 +CREATE PUBLICATION pub1 FOR ALL TABLES +-- +STMT: CreatePublicationStmt +== 624 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 625 +-- fail - missing REPLICA IDENTITY +INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2 +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 626 +-- ok - no updates +INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT DO NOTHING +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 627 +-- fail - missing REPLICA IDENTITY in partition testpub_insert_onconfl_no_ri +INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2 +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 628 +-- ok - no updates +INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT DO NOTHING +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 629 +DROP PUBLICATION pub1 +-- +STMT: DropStmt +== 630 +DROP TABLE testpub_insert_onconfl_no_ri +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DDL +STMT: DropStmt +== 631 +DROP TABLE testpub_insert_onconfl_parted +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DDL +STMT: DropStmt +== 632 +-- Test that the MERGE command correctly checks REPLICA IDENTITY when the +-- target table is published. +CREATE TABLE testpub_merge_no_ri (a int, b int) +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DDL +STMT: CreateStmt +== 633 +CREATE TABLE testpub_merge_pk (a int primary key, b int) +-- +TABLE: name="testpub_merge_pk" schema="" table="testpub_merge_pk" ctx=DDL +STMT: CreateStmt +== 634 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 635 +CREATE PUBLICATION pub1 FOR ALL TABLES +-- +STMT: CreatePublicationStmt +== 636 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 637 +-- fail - missing REPLICA IDENTITY +MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 + WHEN MATCHED THEN UPDATE SET b = s.b +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DML +STMT: MergeStmt +== 638 +-- fail - missing REPLICA IDENTITY +MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 + WHEN MATCHED THEN DELETE +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DML +STMT: MergeStmt +== 639 +-- ok - insert and do nothing are not restricted +MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN INSERT (a, b) VALUES (0, 0) +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DML +STMT: MergeStmt +== 640 +-- ok - REPLICA IDENTITY is DEFAULT and table has a PK +MERGE INTO testpub_merge_pk USING testpub_merge_no_ri s ON s.a >= 1 + WHEN MATCHED AND s.a > 0 THEN UPDATE SET b = s.b + WHEN MATCHED THEN DELETE +-- +TABLE: name="testpub_merge_pk" schema="" table="testpub_merge_pk" ctx=DML +STMT: MergeStmt +== 641 +DROP PUBLICATION pub1 +-- +STMT: DropStmt +== 642 +DROP TABLE testpub_merge_no_ri +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DDL +STMT: DropStmt +== 643 +DROP TABLE testpub_merge_pk +-- +TABLE: name="testpub_merge_pk" schema="" table="testpub_merge_pk" ctx=DDL +STMT: DropStmt +== 644 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 645 +DROP ROLE regress_publication_user, regress_publication_user2 +-- +STMT: DropRoleStmt +== 646 +DROP ROLE regress_publication_user_dummy +-- +STMT: DropRoleStmt +== 647 +-- stage objects for pg_dump tests +CREATE SCHEMA pubme CREATE TABLE t0 (c int, d int) CREATE TABLE t1 (c int) +-- +STMT: CreateSchemaStmt +== 648 +CREATE SCHEMA pubme2 CREATE TABLE t0 (c int, d int) +-- +STMT: CreateSchemaStmt +== 649 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +== 650 +CREATE PUBLICATION dump_pub_qual_1ct FOR + TABLE ONLY pubme.t0 (c, d) WHERE (c > 0) +-- +STMT: CreatePublicationStmt +== 651 +CREATE PUBLICATION dump_pub_qual_2ct FOR + TABLE ONLY pubme.t0 (c) WHERE (c > 0), + TABLE ONLY pubme.t1 (c) +-- +STMT: CreatePublicationStmt +== 652 +CREATE PUBLICATION dump_pub_nsp_1ct FOR + TABLES IN SCHEMA pubme +-- +STMT: CreatePublicationStmt +== 653 +CREATE PUBLICATION dump_pub_nsp_2ct FOR + TABLES IN SCHEMA pubme, + TABLES IN SCHEMA pubme2 +-- +STMT: CreatePublicationStmt +== 654 +CREATE PUBLICATION dump_pub_all FOR + TABLE ONLY pubme.t0, + TABLE ONLY pubme.t1 WHERE (c < 0), + TABLES IN SCHEMA pubme, + TABLES IN SCHEMA pubme2 + WITH (publish_via_partition_root = true) +-- +STMT: CreatePublicationStmt +== 655 +RESET client_min_messages +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/random.metadata.json b/parser/testdata/summary/postgres_regress/random.metadata.json new file mode 100644 index 0000000..634de79 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/random.metadata.json @@ -0,0 +1,52 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048" + ] +} diff --git a/parser/testdata/summary/postgres_regress/random.test b/parser/testdata/summary/postgres_regress/random.test new file mode 100644 index 0000000..54ec12c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/random.test @@ -0,0 +1,514 @@ +== 001 +|-- +-- RANDOM +-- Test random() and allies +|-- +-- Tests in this file may have a small probability of failure, +-- since we are dealing with randomness. Try to keep the failure +-- risk for any one test case under 1e-9. +|-- + +-- There should be no duplicates in 1000 random() values. +-- (Assuming 52 random bits in the float8 results, we could +-- take as many as 3000 values and still have less than 1e-9 chance +-- of failure, per https://en.wikipedia.org/wiki/Birthday_problem) +SELECT r, count(*) +FROM (SELECT random() r FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 002 +-- The range should be [0, 1). We can expect that at least one out of 2000 +-- random values is in the lowest or highest 1% of the range with failure +-- probability less than about 1e-9. + +SELECT count(*) FILTER (WHERE r < 0 OR r >= 1) AS out_of_range, + (count(*) FILTER (WHERE r < 0.01)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 0.99)) > 0 AS has_large +FROM (SELECT random() r FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- Check for uniform distribution using the Kolmogorov-Smirnov test. + +CREATE FUNCTION ks_test_uniform_random() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random() r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 004 +-- As written, ks_test_uniform_random() returns true about 99.9% +-- of the time. To get down to a roughly 1e-9 test failure rate, +-- just run it 3 times and accept if any one of them passes. +SELECT ks_test_uniform_random() OR + ks_test_uniform_random() OR + ks_test_uniform_random() AS uniform +-- +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=Call +STMT: SelectStmt +== 005 +-- now test random_normal() + +-- As above, there should be no duplicates in 1000 random_normal() values. +SELECT r, count(*) +FROM (SELECT random_normal() r FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 006 +-- ... unless we force the range (standard deviation) to zero. +-- This is a good place to check that the mean input does something, too. +SELECT r, count(*) +FROM (SELECT random_normal(10, 0) r FROM generate_series(1, 100)) ss +GROUP BY r +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT r, count(*) +FROM (SELECT random_normal(-10, 0) r FROM generate_series(1, 100)) ss +GROUP BY r +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- Check standard normal distribution using the Kolmogorov-Smirnov test. + +CREATE FUNCTION ks_test_normal_random() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random_normal() r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs((1+erf(r/sqrt(2)))/2 - i/n)) < c / sqrt(n) + FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 009 +-- As above, ks_test_normal_random() returns true about 99.9% +-- of the time, so try it 3 times and accept if any test passes. +SELECT ks_test_normal_random() OR + ks_test_normal_random() OR + ks_test_normal_random() AS standard_normal +-- +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=Call +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=Call +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=Call +STMT: SelectStmt +== 010 +-- Test random(min, max) + +-- invalid range bounds +SELECT random(1, 0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT random(1000000000001, 1000000000000) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT random(-2.0, -3.0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT random('NaN'::numeric, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT random('-Inf'::numeric, 0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT random(0, 'NaN'::numeric) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT random(0, 'Inf'::numeric) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- empty range is OK +SELECT random(101, 101) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT random(1000000000001, 1000000000001) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT random(3.14, 3.14) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- There should be no triple duplicates in 1000 full-range 32-bit random() +-- values. (Each of the C(1000, 3) choices of triplets from the 1000 values +-- has a probability of 1/(2^32)^2 of being a triple duplicate, so the +-- average number of triple duplicates is 1000 * 999 * 998 / 6 / 2^64, which +-- is roughly 9e-12.) +SELECT r, count(*) +FROM (SELECT random(-2147483648, 2147483647) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 2 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- There should be no duplicates in 1000 full-range 64-bit random() values. +SELECT r, count(*) +FROM (SELECT random_normal(-9223372036854775808, 9223372036854775807) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- There should be no duplicates in 1000 15-digit random() numeric values. +SELECT r, count(*) +FROM (SELECT random_normal(0, 1 - 1e-15) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 023 +-- Expect at least one out of 2000 random values to be in the lowest and +-- highest 1% of the range. +SELECT (count(*) FILTER (WHERE r < -2104533975)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 2104533974)) > 0 AS has_large +FROM (SELECT random(-2147483648, 2147483647) r FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT count(*) FILTER (WHERE r < -1500000000 OR r > 1500000000) AS out_of_range, + (count(*) FILTER (WHERE r < -1470000000)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1470000000)) > 0 AS has_large +FROM (SELECT random(-1500000000, 1500000000) r FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT (count(*) FILTER (WHERE r < -9038904596117680292)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 9038904596117680291)) > 0 AS has_large +FROM (SELECT random(-9223372036854775808, 9223372036854775807) r + FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 026 +SELECT count(*) FILTER (WHERE r < -1500000000000000 OR r > 1500000000000000) AS out_of_range, + (count(*) FILTER (WHERE r < -1470000000000000)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1470000000000000)) > 0 AS has_large +FROM (SELECT random(-1500000000000000, 1500000000000000) r + FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT count(*) FILTER (WHERE r < -1.5 OR r > 1.5) AS out_of_range, + (count(*) FILTER (WHERE r < -1.47)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1.47)) > 0 AS has_large +FROM (SELECT random(-1.500000000000000, 1.500000000000000) r + FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 028 +-- Every possible value should occur at least once in 2500 random() values +-- chosen from a range with 100 distinct values. +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(-50, 49) r FROM generate_series(1, 2500)) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(123000000000, 123000000099) r + FROM generate_series(1, 2500)) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(-0.5, 0.49) r FROM generate_series(1, 2500)) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- Check for uniform distribution using the Kolmogorov-Smirnov test. + +CREATE FUNCTION ks_test_uniform_random_int_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 999999) / 1000000.0 r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 032 +SELECT ks_test_uniform_random_int_in_range() OR + ks_test_uniform_random_int_in_range() OR + ks_test_uniform_random_int_in_range() AS uniform_int +-- +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=Call +STMT: SelectStmt +== 033 +CREATE FUNCTION ks_test_uniform_random_bigint_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 999999999999) / 1000000000000.0 r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 034 +SELECT ks_test_uniform_random_bigint_in_range() OR + ks_test_uniform_random_bigint_in_range() OR + ks_test_uniform_random_bigint_in_range() AS uniform_bigint +-- +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=Call +STMT: SelectStmt +== 035 +CREATE FUNCTION ks_test_uniform_random_numeric_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 0.999999) r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 036 +SELECT ks_test_uniform_random_numeric_in_range() OR + ks_test_uniform_random_numeric_in_range() OR + ks_test_uniform_random_numeric_in_range() AS uniform_numeric +-- +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- setseed() should produce a reproducible series of random() values. + +SELECT setseed(0.5) +-- +FUNCTION: name="setseed" function="setseed" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT random() FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 039 +-- Likewise for random_normal(); however, since its implementation relies +-- on libm functions that have different roundoff behaviors on different +-- machines, we have to round off the results a bit to get consistent output. +SET extra_float_digits = -1 +-- +STMT: VariableSetStmt +== 040 +SELECT random_normal() FROM generate_series(1, 10) +-- +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT random_normal(mean => 1, stddev => 0.1) r FROM generate_series(1, 10) +-- +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- Reproducible random(min, max) values. +SELECT random(1, 6) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT random(-2147483648, 2147483647) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT random(-9223372036854775808, 9223372036854775807) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 045 +SELECT random(-1e30, 1e30) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 046 +SELECT random(-0.4, 0.4) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 047 +SELECT random(0, 1 - 1e-30) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT n, random(0, trim_scale(abs(1 - 10.0^(-n)))) FROM generate_series(-20, 20) n +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/rangefuncs.metadata.json b/parser/testdata/summary/postgres_regress/rangefuncs.metadata.json new file mode 100644 index 0000000..526d3ef --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rangefuncs.metadata.json @@ -0,0 +1,432 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428" + ] +} diff --git a/parser/testdata/summary/postgres_regress/rangefuncs.test b/parser/testdata/summary/postgres_regress/rangefuncs.test new file mode 100644 index 0000000..ed54bac --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rangefuncs.test @@ -0,0 +1,2557 @@ +== 001 +CREATE TABLE rngfunc2(rngfuncid int, f2 int) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO rngfunc2 VALUES(1, 11) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO rngfunc2 VALUES(2, 22) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO rngfunc2 VALUES(1, 111) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +CREATE FUNCTION rngfunct(int) returns setof rngfunc2 as 'SELECT * FROM rngfunc2 WHERE rngfuncid = $1 ORDER BY f2;' LANGUAGE SQL +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +-- function with ORDINALITY +select * from rngfunct(1) with ordinality as z(a,b,ord) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: SelectStmt +== 007 +select * from rngfunct(1) with ordinality as z(a,b,ord) where b > 100 +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 008 +-- ordinal 2, not 1 +-- ordinality vs. column names and types +select a,b,ord from rngfunct(1) with ordinality as z(a,b,ord) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: SelectStmt +== 009 +select a,ord from unnest(array['a','b']) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 010 +select * from unnest(array['a','b']) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 011 +select a,ord from unnest(array[1.0::float8]) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 012 +select * from unnest(array[1.0::float8]) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 013 +select row_to_json(s.*) from generate_series(11,14) with ordinality s +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- ordinality vs. views +create temporary view vw_ord as select * from (values (1)) v(n) join rngfunct(1) with ordinality as z(a,b,ord) on (n=ord) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 015 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +== 016 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +== 017 +drop view vw_ord +-- +STMT: DropStmt +== 018 +-- multiple functions +select * from rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: SelectStmt +== 019 +create temporary view vw_ord as select * from (values (1)) v(n) join rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord) on (n=ord) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 020 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +== 021 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +== 022 +drop view vw_ord +-- +STMT: DropStmt +== 023 +-- expansions of unnest() +select * from unnest(array[10,20],array['foo','bar'],array[1.0]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 024 +select * from unnest(array[10,20],array['foo','bar'],array[1.0]) with ordinality as z(a,b,c,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 025 +select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) with ordinality as z(a,b,c,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 026 +select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(101,102)) with ordinality as z(a,b,c,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 027 +create temporary view vw_ord as select * from unnest(array[10,20],array['foo','bar'],array[1.0]) as z(a,b,c) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 028 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +== 029 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +== 030 +drop view vw_ord +-- +STMT: DropStmt +== 031 +create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) as z(a,b,c) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 032 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +== 033 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +== 034 +drop view vw_ord +-- +STMT: DropStmt +== 035 +create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(1,2)) as z(a,b,c) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 036 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +== 037 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +== 038 +drop view vw_ord +-- +STMT: DropStmt +== 039 +-- ordinality and multiple functions vs. rewind and reverse scan +begin +-- +STMT: TransactionStmt +== 040 +declare rf_cur scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o) +-- +STMT: DeclareCursorStmt +== 041 +fetch all from rf_cur +-- +STMT: FetchStmt +== 042 +fetch backward all from rf_cur +-- +STMT: FetchStmt +== 043 +fetch all from rf_cur +-- +STMT: FetchStmt +== 044 +fetch next from rf_cur +-- +STMT: FetchStmt +== 045 +fetch next from rf_cur +-- +STMT: FetchStmt +== 046 +fetch prior from rf_cur +-- +STMT: FetchStmt +== 047 +fetch absolute 1 from rf_cur +-- +STMT: FetchStmt +== 048 +fetch next from rf_cur +-- +STMT: FetchStmt +== 049 +fetch next from rf_cur +-- +STMT: FetchStmt +== 050 +fetch next from rf_cur +-- +STMT: FetchStmt +== 051 +fetch prior from rf_cur +-- +STMT: FetchStmt +== 052 +fetch prior from rf_cur +-- +STMT: FetchStmt +== 053 +fetch prior from rf_cur +-- +STMT: FetchStmt +== 054 +commit +-- +STMT: TransactionStmt +== 055 +-- function with implicit LATERAL +select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) z where rngfunc2.f2 = z.f2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="rngfunc2" column="f2" +FILTER: schema="" table="z" column="f2" +STMT: SelectStmt +== 056 +-- function with implicit LATERAL and explicit ORDINALITY +select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) with ordinality as z(rngfuncid,f2,ord) where rngfunc2.f2 = z.f2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="rngfunc2" column="f2" +FILTER: schema="" table="z" column="f2" +STMT: SelectStmt +== 057 +-- function in subselect +select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="z" column="rngfuncid" +FILTER: schema="" table="rngfunc2" column="rngfuncid" +STMT: SelectStmt +== 058 +-- function in subselect +select * from rngfunc2 where f2 in (select f2 from rngfunct(1) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="z" column="rngfuncid" +FILTER: schema="" table="rngfunc2" column="rngfuncid" +STMT: SelectStmt +== 059 +-- function in subselect +select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = 1) ORDER BY 1,2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="z" column="rngfuncid" +STMT: SelectStmt +== 060 +-- nested functions +select rngfunct.rngfuncid, rngfunct.f2 from rngfunct(sin(pi()/2)::int) ORDER BY 1,2 +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FUNCTION: name="sin" function="sin" schema="" ctx=Call +FUNCTION: name="pi" function="pi" schema="" ctx=Call +STMT: SelectStmt +== 061 +CREATE TABLE rngfunc (rngfuncid int, rngfuncsubid int, rngfuncname text, primary key(rngfuncid,rngfuncsubid)) +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DDL +STMT: CreateStmt +== 062 +INSERT INTO rngfunc VALUES(1,1,'Joe') +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +INSERT INTO rngfunc VALUES(1,2,'Ed') +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +INSERT INTO rngfunc VALUES(2,1,'Mary') +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +-- sql, proretset = f, prorettype = b +CREATE FUNCTION getrngfunc1(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 066 +SELECT * FROM getrngfunc1(1) AS t1 +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT * FROM getrngfunc1(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: SelectStmt +== 068 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 069 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 070 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 071 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) WITH ORDINALITY as t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 072 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 073 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 074 +-- sql, proretset = t, prorettype = b +CREATE FUNCTION getrngfunc2(int) RETURNS setof int AS 'SELECT rngfuncid FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 075 +SELECT * FROM getrngfunc2(1) AS t1 +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: SelectStmt +== 077 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 078 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 079 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 080 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 081 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 082 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 083 +-- sql, proretset = t, prorettype = b +CREATE FUNCTION getrngfunc3(int) RETURNS setof text AS 'SELECT rngfuncname FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 084 +SELECT * FROM getrngfunc3(1) AS t1 +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: SelectStmt +== 085 +SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: SelectStmt +== 086 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 087 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 088 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 089 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 090 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 091 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 092 +-- sql, proretset = f, prorettype = c +CREATE FUNCTION getrngfunc4(int) RETURNS rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 093 +SELECT * FROM getrngfunc4(1) AS t1 +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: SelectStmt +== 094 +SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: SelectStmt +== 095 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 096 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 097 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 098 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 099 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 101 +-- sql, proretset = t, prorettype = c +CREATE FUNCTION getrngfunc5(int) RETURNS setof rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 102 +SELECT * FROM getrngfunc5(1) AS t1 +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: SelectStmt +== 103 +SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: SelectStmt +== 104 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 105 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 106 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 107 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 108 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 109 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 110 +-- sql, proretset = f, prorettype = record +CREATE FUNCTION getrngfunc6(int) RETURNS RECORD AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 111 +SELECT * FROM getrngfunc6(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: SelectStmt +== 112 +SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: SelectStmt +== 113 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc6(1) AS +(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 114 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 115 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 116 +CREATE VIEW vw_getrngfunc AS + SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) + WITH ORDINALITY +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 117 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 118 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 119 +-- sql, proretset = t, prorettype = record +CREATE FUNCTION getrngfunc7(int) RETURNS setof record AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 120 +SELECT * FROM getrngfunc7(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: SelectStmt +== 121 +SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: SelectStmt +== 122 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc7(1) AS +(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 123 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 124 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 125 +CREATE VIEW vw_getrngfunc AS + SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) + WITH ORDINALITY +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 126 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 127 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 128 +-- plpgsql, proretset = f, prorettype = b +CREATE FUNCTION getrngfunc8(int) RETURNS int AS 'DECLARE rngfuncint int; BEGIN SELECT rngfuncid into rngfuncint FROM rngfunc WHERE rngfuncid = $1; RETURN rngfuncint; END;' LANGUAGE plpgsql +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 129 +SELECT * FROM getrngfunc8(1) AS t1 +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: SelectStmt +== 130 +SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: SelectStmt +== 131 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 132 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 133 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 134 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 135 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 136 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 137 +-- plpgsql, proretset = f, prorettype = c +CREATE FUNCTION getrngfunc9(int) RETURNS rngfunc AS 'DECLARE rngfunctup rngfunc%ROWTYPE; BEGIN SELECT * into rngfunctup FROM rngfunc WHERE rngfuncid = $1; RETURN rngfunctup; END;' LANGUAGE plpgsql +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 138 +SELECT * FROM getrngfunc9(1) AS t1 +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: SelectStmt +== 139 +SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: SelectStmt +== 140 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 141 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 142 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 143 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 144 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +== 145 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +== 146 +-- mix 'n match kinds, to exercise expandRTE and related logic + +select * from rows from(getrngfunc1(1),getrngfunc2(1),getrngfunc3(1),getrngfunc4(1),getrngfunc5(1), + getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc8(1),getrngfunc9(1)) + with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u) +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: SelectStmt +== 147 +select * from rows from(getrngfunc9(1),getrngfunc8(1), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc5(1),getrngfunc4(1),getrngfunc3(1),getrngfunc2(1),getrngfunc1(1)) + with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u) +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: SelectStmt +== 148 +create temporary view vw_rngfunc as + select * from rows from(getrngfunc9(1), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc1(1)) + with ordinality as t1(a,b,c,d,e,f,g,n) +-- +TABLE: name="vw_rngfunc" schema="" table="vw_rngfunc" ctx=DDL +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 149 +select * from vw_rngfunc +-- +TABLE: name="vw_rngfunc" schema="" table="vw_rngfunc" ctx=Select +STMT: SelectStmt +== 150 +select pg_get_viewdef('vw_rngfunc') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 151 +drop view vw_rngfunc +-- +STMT: DropStmt +== 152 +DROP FUNCTION getrngfunc1(int) +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=DDL +STMT: DropStmt +== 153 +DROP FUNCTION getrngfunc2(int) +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=DDL +STMT: DropStmt +== 154 +DROP FUNCTION getrngfunc3(int) +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=DDL +STMT: DropStmt +== 155 +DROP FUNCTION getrngfunc4(int) +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=DDL +STMT: DropStmt +== 156 +DROP FUNCTION getrngfunc5(int) +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=DDL +STMT: DropStmt +== 157 +DROP FUNCTION getrngfunc6(int) +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=DDL +STMT: DropStmt +== 158 +DROP FUNCTION getrngfunc7(int) +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=DDL +STMT: DropStmt +== 159 +DROP FUNCTION getrngfunc8(int) +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=DDL +STMT: DropStmt +== 160 +DROP FUNCTION getrngfunc9(int) +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=DDL +STMT: DropStmt +== 161 +DROP FUNCTION rngfunct(int) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=DDL +STMT: DropStmt +== 162 +DROP TABLE rngfunc2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DDL +STMT: DropStmt +== 163 +DROP TABLE rngfunc +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DDL +STMT: DropStmt +== 164 +-- Rescan tests -- +CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq1 +-- +STMT: CreateSeqStmt +== 165 +CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq2 +-- +STMT: CreateSeqStmt +== 166 +CREATE TYPE rngfunc_rescan_t AS (i integer, s bigint) +-- +STMT: CompositeTypeStmt +== 167 +CREATE FUNCTION rngfunc_sql(int,int) RETURNS setof rngfunc_rescan_t AS 'SELECT i, nextval(''rngfunc_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 168 +-- plpgsql functions use materialize mode +CREATE FUNCTION rngfunc_mat(int,int) RETURNS setof rngfunc_rescan_t AS 'begin for i in $1..$2 loop return next (i, nextval(''rngfunc_rescan_seq2'')); end loop; end;' LANGUAGE plpgsql +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 169 +--invokes ExecReScanFunctionScan - all these cases should materialize the function only once +-- LEFT JOIN on a condition that the planner can't prove to be true is used to ensure the function +-- is on the inner path of a nestloop join + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 170 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 171 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 172 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 173 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 174 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 175 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 176 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 177 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 178 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( rngfunc_sql(11,13), rngfunc_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100 +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 179 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) f(i) ON (r+i)<100 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 180 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) WITH ORDINALITY AS f(i,o) ON (r+i)<100 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 181 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) f(i) ON (r+i)<100 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 182 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) WITH ORDINALITY AS f(i,o) ON (r+i)<100 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 183 +--invokes ExecReScanFunctionScan with chgParam != NULL (using implied LATERAL) + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 184 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 185 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 186 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 187 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 188 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 189 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 190 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 191 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 192 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 193 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 194 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +== 195 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 196 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 197 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 198 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 199 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 200 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 201 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 202 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 203 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 204 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 205 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 206 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 207 +-- selective rescan of multiple functions: + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 208 +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(11,11), rngfunc_mat(10+r,13) ) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 209 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 210 +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(11,11) ) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 211 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 212 +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(10+r,13) ) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 213 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 214 +SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( rngfunc_sql(10+r1,13), rngfunc_mat(10+r2,13) ) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +== 215 +SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) f(i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 216 +SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) WITH ORDINALITY AS f(i,o) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 217 +SELECT * FROM (VALUES (1),(2),(3)) v(r), unnest(array[r*10,r*20,r*30]) f(i) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 218 +SELECT * FROM (VALUES (1),(2),(3)) v(r), unnest(array[r*10,r*20,r*30]) WITH ORDINALITY AS f(i,o) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 219 +-- deep nesting + +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(21,23) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 220 +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(20+r1,23) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 221 +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(r2,r2+3) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 222 +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(r1,2+r2/5) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 223 +-- check handling of FULL JOIN with multiple lateral references (bug #15741) + +SELECT * +FROM (VALUES (1),(2)) v1(r1) + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, v1.r1) AS gs1 + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, gs1) AS gs2 + LEFT JOIN generate_series(1, gs2) AS gs3 ON TRUE + ) AS ss1 ON TRUE + FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE + ) AS ss0 ON TRUE +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 224 +DROP FUNCTION rngfunc_sql(int,int) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=DDL +STMT: DropStmt +== 225 +DROP FUNCTION rngfunc_mat(int,int) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=DDL +STMT: DropStmt +== 226 +DROP SEQUENCE rngfunc_rescan_seq1 +-- +STMT: DropStmt +== 227 +DROP SEQUENCE rngfunc_rescan_seq2 +-- +STMT: DropStmt +== 228 +|-- +-- Test cases involving OUT parameters +|-- + +CREATE FUNCTION rngfunc(in f1 int, out f2 int) +AS 'select $1+1' LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 229 +SELECT rngfunc(42) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT * FROM rngfunc(42) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT * FROM rngfunc(42) AS p(x) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +== 232 +-- 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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 233 +-- error, wrong result type +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS float +AS 'select $1+1' LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 234 +-- 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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 235 +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) +RETURNS record +AS 'select $1+1' LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 236 +CREATE OR REPLACE FUNCTION rngfuncr(in f1 int, out f2 int, out text) +AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 237 +SELECT f1, rngfuncr(f1) FROM int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=Call +STMT: SelectStmt +== 238 +SELECT * FROM rngfuncr(42) +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=Call +STMT: SelectStmt +== 239 +SELECT * FROM rngfuncr(42) AS p(a,b) +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=Call +STMT: SelectStmt +== 240 +CREATE OR REPLACE FUNCTION rngfuncb(in f1 int, inout f2 int, out text) +AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 241 +SELECT f1, rngfuncb(f1, f1/2) FROM int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=Call +STMT: SelectStmt +== 242 +SELECT * FROM rngfuncb(42, 99) +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=Call +STMT: SelectStmt +== 243 +SELECT * FROM rngfuncb(42, 99) AS p(a,b) +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=Call +STMT: SelectStmt +== 244 +-- Can reference function with or without OUT params for DROP, etc +DROP FUNCTION rngfunc(int) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +== 245 +DROP FUNCTION rngfuncr(in f2 int, out f1 int, out text) +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=DDL +STMT: DropStmt +== 246 +DROP FUNCTION rngfuncb(in f1 int, inout f2 int) +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=DDL +STMT: DropStmt +== 247 +|-- +-- 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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 248 +SELECT dup(22) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 249 +SELECT dup('xyz') +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 250 +-- fails +SELECT dup('xyz'::text) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 251 +SELECT * FROM dup('xyz'::text) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 252 +-- 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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 253 +DROP FUNCTION dup(anyelement) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +== 254 +-- 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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 255 +SELECT dup(22) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 256 +DROP FUNCTION dup(anyelement) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +== 257 +-- 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 +-- +FUNCTION: name="bad" function="bad" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 258 +CREATE FUNCTION dup (f1 anycompatible, f2 anycompatiblearray, f3 out anycompatible, f4 out anycompatiblearray) +AS 'select $1, $2' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 259 +SELECT dup(22, array[44]) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 260 +SELECT dup(4.5, array[44]) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 261 +SELECT dup(22, array[44::bigint]) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 262 +SELECT *, pg_typeof(f3), pg_typeof(f4) FROM dup(22, array[44::bigint]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +== 263 +DROP FUNCTION dup(f1 anycompatible, f2 anycompatiblearray) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +== 264 +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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 265 +SELECT dup(int4range(4,7)) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 266 +SELECT dup(numrange(4,7)) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 267 +SELECT dup(textrange('aaa', 'bbb')) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +== 268 +DROP FUNCTION dup(f1 anycompatiblerange) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +== 269 +-- 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 +-- +FUNCTION: name="bad" function="bad" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 270 +|-- +-- table functions +|-- + +CREATE OR REPLACE FUNCTION rngfunc() +RETURNS TABLE(a int) +AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 271 +SELECT * FROM rngfunc() +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +== 272 +DROP FUNCTION rngfunc() +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +== 273 +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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 274 +SELECT * FROM rngfunc(3) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +== 275 +DROP FUNCTION rngfunc(int) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +== 276 +-- 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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 277 +SELECT * FROM rngfunc() GROUP BY 1 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +== 278 +DROP FUNCTION rngfunc() +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +== 279 +|-- +-- some tests on SQL functions with RETURNING +|-- + +create temp table tt(f1 serial, data text) +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: CreateStmt +== 280 +create function insert_tt(text) returns int as +$$ insert into tt(data) values($1) returning f1 $$ +language sql +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 281 +select insert_tt('foo') +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=Call +STMT: SelectStmt +== 282 +select insert_tt('bar') +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=Call +STMT: SelectStmt +== 283 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +== 284 +-- 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 +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 285 +select insert_tt('fool') +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=Call +STMT: SelectStmt +== 286 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +== 287 +-- 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 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 288 +select insert_tt2('foolish','barrish') +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +== 289 +select * from insert_tt2('baz','quux') +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +== 290 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +== 291 +-- limit doesn't prevent execution to completion +select insert_tt2('foolish','barrish') limit 1 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +== 292 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +== 293 +-- triggers will fire, too +create function noticetrigger() returns trigger as $$ +begin + raise notice 'noticetrigger % %', new.f1, new.data; + return null; +end $$ language plpgsql +-- +FUNCTION: name="noticetrigger" function="noticetrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 294 +create trigger tnoticetrigger after insert on tt for each row +execute procedure noticetrigger() +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: CreateTrigStmt +== 295 +select insert_tt2('foolme','barme') limit 1 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +== 296 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +== 297 +-- and rules work +create temp table tt_log(f1 int, data text) +-- +TABLE: name="tt_log" schema="" table="tt_log" ctx=DDL +STMT: CreateStmt +== 298 +create rule insert_tt_rule as on insert to tt do also + insert into tt_log values(new.*) +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: RuleStmt +== 299 +select insert_tt2('foollog','barlog') limit 1 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +== 300 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +== 301 +-- note that nextval() gets executed a second time in the rule expansion, +-- which is expected. +select * from tt_log +-- +TABLE: name="tt_log" schema="" table="tt_log" ctx=Select +STMT: SelectStmt +== 302 +-- 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 $$ +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 303 +set work_mem='64kB' +-- +STMT: VariableSetStmt +== 304 +select t.a, t, t.a from rngfunc1(10000) t limit 1 +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=Call +STMT: SelectStmt +== 305 +reset work_mem +-- +STMT: VariableSetStmt +== 306 +select t.a, t, t.a from rngfunc1(10000) t limit 1 +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=Call +STMT: SelectStmt +== 307 +drop function rngfunc1(n integer) +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=DDL +STMT: DropStmt +== 308 +-- 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 +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 309 +select array_to_set(array['one', 'two']) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 310 +select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 311 +select * from array_to_set(array['one', 'two']) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 312 +-- fail +-- 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) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 313 +-- 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) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 314 +-- 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) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 315 +-- 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 +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 316 +select array_to_set(array['one', 'two']) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 317 +select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 318 +select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 319 +select * from array_to_set(array['one', 'two']) as t(f1 point,f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +== 320 +explain (verbose, costs off) + select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 321 +create temp table rngfunc(f1 int8, f2 int8) +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DDL +STMT: CreateStmt +== 322 +create function testrngfunc() returns record as $$ + insert into rngfunc values (1,2) returning *; +$$ language sql +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 323 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 324 +select * from testrngfunc() as t(f1 int8,f2 int8) +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 325 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 326 +-- fail + +drop function testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: DropStmt +== 327 +create function testrngfunc() returns setof record as $$ + insert into rngfunc values (1,2), (3,4) returning *; +$$ language sql +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 328 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 329 +select * from testrngfunc() as t(f1 int8,f2 int8) +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 330 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 331 +-- fail + +drop function testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: DropStmt +== 332 +-- Check that typmod imposed by a composite type is honored +create type rngfunc_type as (f1 numeric(35,6), f2 numeric(35,2)) +-- +STMT: CompositeTypeStmt +== 333 +create function testrngfunc() returns rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql immutable +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 334 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 335 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 336 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 337 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 338 +create or replace function testrngfunc() returns rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql volatile +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 339 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 340 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 341 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 342 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 343 +drop function testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: DropStmt +== 344 +create function testrngfunc() returns setof rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql immutable +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 345 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 346 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 347 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 348 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 349 +create or replace function testrngfunc() returns setof rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql volatile +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 350 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 351 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 352 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 353 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 354 +create or replace function testrngfunc() returns setof rngfunc_type as $$ + select 1, 2 union select 3, 4 order by 1; +$$ language sql immutable +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 355 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 356 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 357 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 358 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 359 +-- Check a couple of error cases while we're here +select * from testrngfunc() as t(f1 int8,f2 int8) +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +== 360 +-- fail, composite result +select * from pg_get_keywords() as t(f1 int8,f2 int8) +-- +FUNCTION: name="pg_get_keywords" function="pg_get_keywords" schema="" ctx=Call +STMT: SelectStmt +== 361 +-- fail, OUT params +select * from sin(3) as t(f1 int8,f2 int8) +-- +FUNCTION: name="sin" function="sin" schema="" ctx=Call +STMT: SelectStmt +== 362 +-- fail, scalar result type + +drop type rngfunc_type cascade +-- +STMT: DropStmt +== 363 +|-- +-- 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) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +== 364 +insert into users values ('id',1,'email',true,11,true) +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 365 +insert into users values ('id2',2,'email2',true,12,true) +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 366 +alter table users drop column todrop +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +== 367 +create or replace function get_first_user() returns users as +$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$ +language sql stable +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 368 +SELECT get_first_user() +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=Call +STMT: SelectStmt +== 369 +SELECT * FROM get_first_user() +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=Call +STMT: SelectStmt +== 370 +create or replace function get_users() returns setof users as +$$ SELECT * FROM users ORDER BY userid; $$ +language sql stable +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 371 +SELECT get_users() +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +== 372 +SELECT * FROM get_users() +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +== 373 +SELECT * FROM get_users() WITH ORDINALITY +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +== 374 +-- make sure ordinality copes + +-- multiple functions vs. dropped columns +SELECT * FROM ROWS FROM(generate_series(10,11), get_users()) WITH ORDINALITY +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +== 375 +SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 376 +-- 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 +-- +TABLE: name="usersview" schema="" table="usersview" ctx=DDL +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 377 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +== 378 +alter table users add column junk text +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +== 379 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +== 380 +alter table users drop column moredrop +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +== 381 +-- fail, view has reference + +-- We used to have a bug that would allow the above to succeed, posing +-- hazards for later execution of the view. Check that the internal +-- defenses for those hazards haven't bit-rotted, in case some other +-- bug with similar symptoms emerges. +begin +-- +STMT: TransactionStmt +== 382 +-- destroy the dependency entry that prevents the DROP: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'usersview'::regclass and rulename = '_RETURN') + and refobjsubid = 5 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +== 383 +alter table users drop column moredrop +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +== 384 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +== 385 +-- expect clean failure +rollback +-- +STMT: TransactionStmt +== 386 +alter table users alter column seq type numeric +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +== 387 +-- fail, view has reference + +-- likewise, check we don't crash if the dependency goes wrong +begin +-- +STMT: TransactionStmt +== 388 +-- destroy the dependency entry that prevents the ALTER: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'usersview'::regclass and rulename = '_RETURN') + and refobjsubid = 2 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +== 389 +alter table users alter column seq type numeric +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +== 390 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +== 391 +-- expect clean failure +rollback +-- +STMT: TransactionStmt +== 392 +drop view usersview +-- +STMT: DropStmt +== 393 +drop function get_first_user() +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=DDL +STMT: DropStmt +== 394 +drop function get_users() +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=DDL +STMT: DropStmt +== 395 +drop table users +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: DropStmt +== 396 +-- 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 +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 397 +select rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +== 398 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +== 399 +-- this function is now inlinable, too: +explain (verbose, costs off) select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 400 +drop function rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: DropStmt +== 401 +-- 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 +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 402 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +== 403 +create or replace function rngfuncbar(out integer, out numeric) as +$$ select (1, 2) $$ language sql +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 404 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +== 405 +-- fail + +create or replace function rngfuncbar(out integer, out numeric) as +$$ select (1, 2.1, 3) $$ language sql +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 406 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +== 407 +-- fail + +drop function rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: DropStmt +== 408 +-- 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 +-- +FUNCTION: name="extractq2" function="extractq2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 409 +explain (verbose, costs off) +select x from int8_tbl, extractq2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2" function="extractq2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 410 +select x from int8_tbl, extractq2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2" function="extractq2" schema="" ctx=Call +STMT: SelectStmt +== 411 +create function extractq2_2(t int8_tbl) returns table(ret1 int8) as $$ + select extractq2(t) offset 0 +$$ language sql immutable +-- +FUNCTION: name="extractq2_2" function="extractq2_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 412 +explain (verbose, costs off) +select x from int8_tbl, extractq2_2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2" function="extractq2_2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 413 +select x from int8_tbl, extractq2_2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2" function="extractq2_2" schema="" ctx=Call +STMT: SelectStmt +== 414 +-- 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 +-- +FUNCTION: name="extractq2_2_opt" function="extractq2_2_opt" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 415 +explain (verbose, costs off) +select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2_opt" function="extractq2_2_opt" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 416 +select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2_opt" function="extractq2_2_opt" schema="" ctx=Call +STMT: SelectStmt +== 417 +-- check handling of nulls in SRF results (bug #7808) + +create type rngfunc2 as (a integer, b text) +-- +STMT: CompositeTypeStmt +== 418 +select *, row_to_json(u) from unnest(array[(1,'foo')::rngfunc2, null::rngfunc2]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 419 +select *, row_to_json(u) from unnest(array[null::rngfunc2, null::rngfunc2]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 420 +select *, row_to_json(u) from unnest(array[null::rngfunc2, (1,'foo')::rngfunc2, null::rngfunc2]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 421 +select *, row_to_json(u) from unnest(array[]::rngfunc2[]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 422 +drop type rngfunc2 +-- +STMT: DropStmt +== 423 +-- 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) +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 424 +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) +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: SelectStmt +== 425 +-- check detection of mismatching record types with a const-folded expression + +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int) +-- +CTE: "a" +STMT: SelectStmt +== 426 +-- fail +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int, f int, g int) +-- +CTE: "a" +STMT: SelectStmt +== 427 +-- fail +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int, f float) +-- +CTE: "a" +STMT: SelectStmt +== 428 +-- fail +select * from int8_tbl, coalesce(row(1)) as (a int, b int) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/rangetypes.metadata.json b/parser/testdata/summary/postgres_regress/rangetypes.metadata.json new file mode 100644 index 0000000..fa6f7df --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rangetypes.metadata.json @@ -0,0 +1,411 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407" + ] +} diff --git a/parser/testdata/summary/postgres_regress/rangetypes.test b/parser/testdata/summary/postgres_regress/rangetypes.test new file mode 100644 index 0000000..24d246d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rangetypes.test @@ -0,0 +1,2802 @@ +== 001 +-- Tests for range data types. + +|-- +-- test input parser +-- (type textrange was already made in test_setup.sql) +|-- + +-- negative tests; should fail +select ''::textrange +-- +STMT: SelectStmt +== 002 +select '-[a,z)'::textrange +-- +STMT: SelectStmt +== 003 +select '[a,z) - '::textrange +-- +STMT: SelectStmt +== 004 +select '(",a)'::textrange +-- +STMT: SelectStmt +== 005 +select '(,,a)'::textrange +-- +STMT: SelectStmt +== 006 +select '(),a)'::textrange +-- +STMT: SelectStmt +== 007 +select '(a,))'::textrange +-- +STMT: SelectStmt +== 008 +select '(],a)'::textrange +-- +STMT: SelectStmt +== 009 +select '(a,])'::textrange +-- +STMT: SelectStmt +== 010 +select '[z,a]'::textrange +-- +STMT: SelectStmt +== 011 +-- should succeed +select ' empty '::textrange +-- +STMT: SelectStmt +== 012 +select ' ( empty, empty ) '::textrange +-- +STMT: SelectStmt +== 013 +select ' ( " a " " a ", " z " " z " ) '::textrange +-- +STMT: SelectStmt +== 014 +select '(a,)'::textrange +-- +STMT: SelectStmt +== 015 +select '[,z]'::textrange +-- +STMT: SelectStmt +== 016 +select '[a,]'::textrange +-- +STMT: SelectStmt +== 017 +select '(,)'::textrange +-- +STMT: SelectStmt +== 018 +select '[ , ]'::textrange +-- +STMT: SelectStmt +== 019 +select '["",""]'::textrange +-- +STMT: SelectStmt +== 020 +select '[",",","]'::textrange +-- +STMT: SelectStmt +== 021 +select '["\\","\\"]'::textrange +-- +STMT: SelectStmt +== 022 +select '(\\,a)'::textrange +-- +STMT: SelectStmt +== 023 +select '((,z)'::textrange +-- +STMT: SelectStmt +== 024 +select '([,z)'::textrange +-- +STMT: SelectStmt +== 025 +select '(!,()'::textrange +-- +STMT: SelectStmt +== 026 +select '(!,[)'::textrange +-- +STMT: SelectStmt +== 027 +select '[a,a]'::textrange +-- +STMT: SelectStmt +== 028 +-- these are allowed but normalize to empty: +select '[a,a)'::textrange +-- +STMT: SelectStmt +== 029 +select '(a,a]'::textrange +-- +STMT: SelectStmt +== 030 +select '(a,a)'::textrange +-- +STMT: SelectStmt +== 031 +-- Also try it with non-error-throwing API +select pg_input_is_valid('(1,4)', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 032 +select pg_input_is_valid('(1,4', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 033 +select * from pg_input_error_info('(1,4', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 034 +select pg_input_is_valid('(4,1)', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 035 +select * from pg_input_error_info('(4,1)', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 036 +select pg_input_is_valid('(4,zed)', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 037 +select * from pg_input_error_info('(4,zed)', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 038 +select pg_input_is_valid('[1,2147483647]', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 039 +select * from pg_input_error_info('[1,2147483647]', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 040 +select pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 041 +select * from pg_input_error_info('[2000-01-01,5874897-12-31]', 'daterange') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 042 +|-- +-- create some test data and test the operators +|-- + +CREATE TABLE numrange_test (nr NUMRANGE) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DDL +STMT: CreateStmt +== 043 +create index numrange_test_btree on numrange_test(nr) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DDL +STMT: IndexStmt +== 044 +INSERT INTO numrange_test VALUES('[,)') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO numrange_test VALUES('[3,]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO numrange_test VALUES('[, 5)') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO numrange_test VALUES(numrange(1.1, 2.2)) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO numrange_test VALUES('empty') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]')) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 050 +SELECT nr, isempty(nr), lower(nr), upper(nr) FROM numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="isempty" function="isempty" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +== 051 +SELECT nr, lower_inc(nr), lower_inf(nr), upper_inc(nr), upper_inf(nr) FROM numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="lower_inc" function="lower_inc" schema="" ctx=Call +FUNCTION: name="lower_inf" function="lower_inf" schema="" ctx=Call +FUNCTION: name="upper_inc" function="upper_inc" schema="" ctx=Call +FUNCTION: name="upper_inf" function="upper_inf" schema="" ctx=Call +STMT: SelectStmt +== 052 +SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91)) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 053 +SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 054 +SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 055 +SELECT * FROM numrange_test WHERE 1.9 <@ nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 056 +select * from numrange_test where nr = 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 057 +select * from numrange_test where nr = '(1.1, 2.2)' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 058 +select * from numrange_test where nr = '[1.1, 2.2)' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 059 +select * from numrange_test where nr < 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 060 +select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 061 +select * from numrange_test where nr < numrange(0.0, 1.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 062 +select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 063 +select * from numrange_test where nr <= 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 064 +select * from numrange_test where nr >= 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 065 +select * from numrange_test where nr > 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 066 +select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 067 +select * from numrange_test where nr > numrange(0.0, 1.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 068 +select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 069 +select numrange(2.0, 1.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 070 +select numrange(2.0, 3.0) -|- numrange(3.0, 4.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 071 +select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0)) +-- +FUNCTION: name="range_adjacent" function="range_adjacent" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 072 +select range_adjacent(numrange(2.0, 3.0), numrange(3.1, null)) +-- +FUNCTION: name="range_adjacent" function="range_adjacent" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 073 +select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 074 +select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 075 +select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]')) +-- +FUNCTION: name="range_adjacent" function="range_adjacent" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 076 +select numrange(1.1, 3.3) <@ numrange(0.1,10.1) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 077 +select numrange(0.1, 10.1) <@ numrange(1.1,3.3) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 078 +select numrange(1.1, 2.2) - numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 079 +select numrange(1.1, 2.2) - numrange(2.2, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 080 +select numrange(1.1, 2.2,'[]') - numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 081 +select range_minus(numrange(10.1,12.2,'[]'), numrange(110.0,120.2,'(]')) +-- +FUNCTION: name="range_minus" function="range_minus" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 082 +select range_minus(numrange(10.1,12.2,'[]'), numrange(0.0,120.2,'(]')) +-- +FUNCTION: name="range_minus" function="range_minus" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 083 +select numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 084 +select numrange(1.0, 2.0) << numrange(3.0, 4.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 085 +select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 086 +select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 087 +select numrange(1.0, 2.0) >> numrange(3.0, 4.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 088 +select numrange(3.0, 70.0) &< numrange(6.6, 100.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 089 +select numrange(1.1, 2.2) < numrange(1.0, 200.2) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 090 +select numrange(1.1, 2.2) < numrange(1.1, 1.2) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 091 +select numrange(1.0, 2.0) + numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 092 +select numrange(1.0, 2.0) + numrange(1.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 093 +select numrange(1.0, 2.0) + numrange(2.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 094 +-- should fail + +select range_merge(numrange(1.0, 2.0), numrange(2.0, 3.0)) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 095 +select range_merge(numrange(1.0, 2.0), numrange(1.5, 3.0)) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 096 +select range_merge(numrange(1.0, 2.0), numrange(2.5, 3.0)) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 097 +-- shouldn't fail + +select numrange(1.0, 2.0) * numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 098 +select numrange(1.0, 2.0) * numrange(1.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 099 +select numrange(1.0, 2.0) * numrange(2.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 100 +select range_intersect_agg(nr) from numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 101 +select range_intersect_agg(nr) from numrange_test where false +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +== 102 +select range_intersect_agg(nr) from numrange_test where nr @> 4.0 +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 103 +analyze numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DDL +STMT: VacuumStmt +== 104 +create table numrange_test2(nr numrange) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DDL +STMT: CreateStmt +== 105 +create index numrange_test2_hash_idx on numrange_test2 using hash (nr) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DDL +STMT: IndexStmt +== 106 +INSERT INTO numrange_test2 VALUES('[, 5)') +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 108 +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 109 +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()')) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 110 +INSERT INTO numrange_test2 VALUES('empty') +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +select * from numrange_test2 where nr = 'empty'::numrange +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 112 +select * from numrange_test2 where nr = numrange(1.1, 2.2) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 113 +select * from numrange_test2 where nr = numrange(1.1, 2.3) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 114 +set enable_nestloop=t +-- +STMT: VariableSetStmt +== 115 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +== 116 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +== 117 +select * from numrange_test natural join numrange_test2 order by nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +STMT: SelectStmt +== 118 +set enable_nestloop=f +-- +STMT: VariableSetStmt +== 119 +set enable_hashjoin=t +-- +STMT: VariableSetStmt +== 120 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +== 121 +select * from numrange_test natural join numrange_test2 order by nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +STMT: SelectStmt +== 122 +set enable_nestloop=f +-- +STMT: VariableSetStmt +== 123 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +== 124 +set enable_mergejoin=t +-- +STMT: VariableSetStmt +== 125 +select * from numrange_test natural join numrange_test2 order by nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +STMT: SelectStmt +== 126 +set enable_nestloop to default +-- +STMT: VariableSetStmt +== 127 +set enable_hashjoin to default +-- +STMT: VariableSetStmt +== 128 +set enable_mergejoin to default +-- +STMT: VariableSetStmt +== 129 +-- keep numrange_test around to help exercise dump/reload +DROP TABLE numrange_test2 +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DDL +STMT: DropStmt +== 130 +|-- +-- Apply a subset of the above tests on a collatable type, too +|-- + +CREATE TABLE textrange_test (tr textrange) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DDL +STMT: CreateStmt +== 131 +create index textrange_test_btree on textrange_test(tr) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DDL +STMT: IndexStmt +== 132 +INSERT INTO textrange_test VALUES('[,)') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +INSERT INTO textrange_test VALUES('["a",]') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 134 +INSERT INTO textrange_test VALUES('[,"q")') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 135 +INSERT INTO textrange_test VALUES(textrange('b', 'g')) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 136 +INSERT INTO textrange_test VALUES('empty') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 137 +INSERT INTO textrange_test VALUES(textrange('d', 'd', '[]')) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 138 +SELECT tr, isempty(tr), lower(tr), upper(tr) FROM textrange_test +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="isempty" function="isempty" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +== 139 +SELECT tr, lower_inc(tr), lower_inf(tr), upper_inc(tr), upper_inf(tr) FROM textrange_test +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="lower_inc" function="lower_inc" schema="" ctx=Call +FUNCTION: name="lower_inf" function="lower_inf" schema="" ctx=Call +FUNCTION: name="upper_inc" function="upper_inc" schema="" ctx=Call +FUNCTION: name="upper_inf" function="upper_inf" schema="" ctx=Call +STMT: SelectStmt +== 140 +SELECT * FROM textrange_test WHERE range_contains(tr, textrange('f', 'fx')) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 141 +SELECT * FROM textrange_test WHERE tr @> textrange('a', 'z') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 142 +SELECT * FROM textrange_test WHERE range_contained_by(textrange('0','9'), tr) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 143 +SELECT * FROM textrange_test WHERE 'e'::text <@ tr +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 144 +select * from textrange_test where tr = 'empty' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 145 +select * from textrange_test where tr = '("b","g")' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 146 +select * from textrange_test where tr = '["b","g")' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 147 +select * from textrange_test where tr < 'empty' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +== 148 +-- test canonical form for int4range +select int4range(1, 10, '[]') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 149 +select int4range(1, 10, '[)') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 150 +select int4range(1, 10, '(]') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 151 +select int4range(1, 10, '()') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 152 +select int4range(1, 2, '()') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 153 +-- test canonical form for daterange +select daterange('2000-01-10'::date, '2000-01-20'::date, '[]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 154 +select daterange('2000-01-10'::date, '2000-01-20'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 155 +select daterange('2000-01-10'::date, '2000-01-20'::date, '(]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 156 +select daterange('2000-01-10'::date, '2000-01-20'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 157 +select daterange('2000-01-10'::date, '2000-01-11'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 158 +select daterange('2000-01-10'::date, '2000-01-11'::date, '(]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 159 +select daterange('-infinity'::date, '2000-01-01'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 160 +select daterange('-infinity'::date, '2000-01-01'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 161 +select daterange('2000-01-01'::date, 'infinity'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 162 +select daterange('2000-01-01'::date, 'infinity'::date, '[]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +== 163 +-- test GiST index that's been built incrementally +create table test_range_gist(ir int4range) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: CreateStmt +== 164 +create index test_range_gist_idx on test_range_gist using gist (ir) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: IndexStmt +== 165 +insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 166 +insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 167 +insert into test_range_gist select int4range(g, g+10000) from generate_series(1,1000) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 168 +insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 169 +insert into test_range_gist select int4range(NULL,g*10,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 170 +insert into test_range_gist select int4range(g*10,NULL,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 171 +insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 172 +-- test statistics and selectivity estimation as well +|-- +-- We don't check the accuracy of selectivity estimation, but at least check +-- it doesn't fall. +analyze test_range_gist +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: VacuumStmt +== 173 +-- first, verify non-indexed results +SET enable_seqscan = t +-- +STMT: VariableSetStmt +== 174 +SET enable_indexscan = f +-- +STMT: VariableSetStmt +== 175 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +== 176 +select count(*) from test_range_gist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 177 +select count(*) from test_range_gist where ir = int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 178 +select count(*) from test_range_gist where ir @> 10 +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 179 +select count(*) from test_range_gist where ir @> int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 180 +select count(*) from test_range_gist where ir && int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 181 +select count(*) from test_range_gist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 182 +select count(*) from test_range_gist where ir << int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 183 +select count(*) from test_range_gist where ir >> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 184 +select count(*) from test_range_gist where ir &< int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 185 +select count(*) from test_range_gist where ir &> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 186 +select count(*) from test_range_gist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 187 +select count(*) from test_range_gist where ir @> '{}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 188 +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 189 +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 190 +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 191 +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 192 +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 193 +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 194 +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 195 +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 196 +-- now check same queries using index +SET enable_seqscan = f +-- +STMT: VariableSetStmt +== 197 +SET enable_indexscan = t +-- +STMT: VariableSetStmt +== 198 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +== 199 +select count(*) from test_range_gist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 200 +select count(*) from test_range_gist where ir = int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 201 +select count(*) from test_range_gist where ir @> 10 +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 202 +select count(*) from test_range_gist where ir @> int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 203 +select count(*) from test_range_gist where ir && int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 204 +select count(*) from test_range_gist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 205 +select count(*) from test_range_gist where ir << int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 206 +select count(*) from test_range_gist where ir >> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 207 +select count(*) from test_range_gist where ir &< int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 208 +select count(*) from test_range_gist where ir &> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 209 +select count(*) from test_range_gist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 210 +select count(*) from test_range_gist where ir @> '{}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 211 +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 212 +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 213 +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 214 +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 215 +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 216 +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 217 +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 218 +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 219 +-- now check same queries using a bulk-loaded index +drop index test_range_gist_idx +-- +STMT: DropStmt +== 220 +create index test_range_gist_idx on test_range_gist using gist (ir) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: IndexStmt +== 221 +select count(*) from test_range_gist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 222 +select count(*) from test_range_gist where ir = int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 223 +select count(*) from test_range_gist where ir @> 10 +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 224 +select count(*) from test_range_gist where ir @> int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 225 +select count(*) from test_range_gist where ir && int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 226 +select count(*) from test_range_gist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 227 +select count(*) from test_range_gist where ir << int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 228 +select count(*) from test_range_gist where ir >> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 229 +select count(*) from test_range_gist where ir &< int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 230 +select count(*) from test_range_gist where ir &> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 231 +select count(*) from test_range_gist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 232 +select count(*) from test_range_gist where ir @> '{}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 233 +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 234 +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 235 +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 236 +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 237 +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 238 +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 239 +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 240 +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 241 +-- test SP-GiST index that's been built incrementally +create table test_range_spgist(ir int4range) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DDL +STMT: CreateStmt +== 242 +create index test_range_spgist_idx on test_range_spgist using spgist (ir) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DDL +STMT: IndexStmt +== 243 +insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 244 +insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 245 +insert into test_range_spgist select int4range(g, g+10000) from generate_series(1,1000) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 246 +insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 247 +insert into test_range_spgist select int4range(NULL,g*10,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 248 +insert into test_range_spgist select int4range(g*10,NULL,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 249 +insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 250 +-- first, verify non-indexed results +SET enable_seqscan = t +-- +STMT: VariableSetStmt +== 251 +SET enable_indexscan = f +-- +STMT: VariableSetStmt +== 252 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +== 253 +select count(*) from test_range_spgist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 254 +select count(*) from test_range_spgist where ir = int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 255 +select count(*) from test_range_spgist where ir @> 10 +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 256 +select count(*) from test_range_spgist where ir @> int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 257 +select count(*) from test_range_spgist where ir && int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 258 +select count(*) from test_range_spgist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 259 +select count(*) from test_range_spgist where ir << int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 260 +select count(*) from test_range_spgist where ir >> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 261 +select count(*) from test_range_spgist where ir &< int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 262 +select count(*) from test_range_spgist where ir &> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 263 +select count(*) from test_range_spgist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 264 +-- now check same queries using index +SET enable_seqscan = f +-- +STMT: VariableSetStmt +== 265 +SET enable_indexscan = t +-- +STMT: VariableSetStmt +== 266 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +== 267 +select count(*) from test_range_spgist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 268 +select count(*) from test_range_spgist where ir = int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 269 +select count(*) from test_range_spgist where ir @> 10 +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 270 +select count(*) from test_range_spgist where ir @> int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 271 +select count(*) from test_range_spgist where ir && int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 272 +select count(*) from test_range_spgist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 273 +select count(*) from test_range_spgist where ir << int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 274 +select count(*) from test_range_spgist where ir >> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 275 +select count(*) from test_range_spgist where ir &< int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 276 +select count(*) from test_range_spgist where ir &> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 277 +select count(*) from test_range_spgist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 278 +-- now check same queries using a bulk-loaded index +drop index test_range_spgist_idx +-- +STMT: DropStmt +== 279 +create index test_range_spgist_idx on test_range_spgist using spgist (ir) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DDL +STMT: IndexStmt +== 280 +select count(*) from test_range_spgist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 281 +select count(*) from test_range_spgist where ir = int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 282 +select count(*) from test_range_spgist where ir @> 10 +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 283 +select count(*) from test_range_spgist where ir @> int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 284 +select count(*) from test_range_spgist where ir && int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 285 +select count(*) from test_range_spgist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 286 +select count(*) from test_range_spgist where ir << int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 287 +select count(*) from test_range_spgist where ir >> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 288 +select count(*) from test_range_spgist where ir &< int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 289 +select count(*) from test_range_spgist where ir &> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 290 +select count(*) from test_range_spgist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 291 +-- test index-only scans +explain (costs off) +select ir from test_range_spgist where ir -|- int4range(10,20) order by ir +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: ExplainStmt +STMT: SelectStmt +== 292 +select ir from test_range_spgist where ir -|- int4range(10,20) order by ir +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +== 293 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 294 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 295 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 296 +-- test elem <@ range operator +create table test_range_elem(i int4) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +STMT: CreateStmt +== 297 +create index test_range_elem_idx on test_range_elem (i) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +STMT: IndexStmt +== 298 +insert into test_range_elem select i from generate_series(1,100) i +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 299 +SET enable_seqscan = f +-- +STMT: VariableSetStmt +== 300 +select count(*) from test_range_elem where i <@ int4range(10,50) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 301 +-- also test spgist index on anyrange expression +create index on test_range_elem using spgist(int4range(i,i+10)) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: IndexStmt +== 302 +explain (costs off) +select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +== 303 +select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 304 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 305 +drop table test_range_elem +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +STMT: DropStmt +== 306 +|-- +-- Btree_gist is not included by default, so to test exclusion +-- constraints with range types, use singleton int ranges for the "=" +-- portion of the constraint. +|-- + +create table test_range_excl( + room int4range, + speaker int4range, + during tsrange, + exclude using gist (room with =, during with &&), + exclude using gist (speaker with =, during with &&) +) +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DDL +STMT: CreateStmt +== 307 +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:00, 2010-01-02 11:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 308 +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(2, 2, '[]'), '[2010-01-02 11:00, 2010-01-02 12:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 309 +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 310 +insert into test_range_excl + values(int4range(124, 124, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:10)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 311 +insert into test_range_excl + values(int4range(125, 125, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 312 +-- test bigint ranges +select int8range(10000000000::int8, 20000000000::int8,'(]') +-- +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +STMT: SelectStmt +== 313 +-- test tstz ranges +set timezone to '-08' +-- +STMT: VariableSetStmt +== 314 +select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange +-- +STMT: SelectStmt +== 315 +-- should fail +select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange +-- +STMT: SelectStmt +== 316 +set timezone to default +-- +STMT: VariableSetStmt +== 317 +|-- +-- Test user-defined range of floats +-- (type float8range was already made in test_setup.sql) +|-- + +--should fail +create type bogus_float8range as range (subtype=float8, subtype_diff=float4mi) +-- +STMT: CreateRangeStmt +== 318 +select '[123.001, 5.e9)'::float8range @> 888.882::float8 +-- +STMT: SelectStmt +== 319 +create table float8range_test(f8r float8range, i int) +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=DDL +STMT: CreateStmt +== 320 +insert into float8range_test values(float8range(-100.00007, '1.111113e9'), 42) +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=DML +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 321 +select * from float8range_test +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=Select +STMT: SelectStmt +== 322 +drop table float8range_test +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=DDL +STMT: DropStmt +== 323 +|-- +-- Test range types over domains +|-- + +create domain mydomain as int4 +-- +STMT: CreateDomainStmt +== 324 +create type mydomainrange as range(subtype=mydomain) +-- +STMT: CreateRangeStmt +== 325 +select '[4,50)'::mydomainrange @> 7::mydomain +-- +STMT: SelectStmt +== 326 +drop domain mydomain +-- +STMT: DropStmt +== 327 +-- fail +drop domain mydomain cascade +-- +STMT: DropStmt +== 328 +|-- +-- Test domains over range types +|-- + +create domain restrictedrange as int4range check (upper(value) < 10) +-- +STMT: CreateDomainStmt +== 329 +select '[4,5)'::restrictedrange @> 7 +-- +STMT: SelectStmt +== 330 +select '[4,50)'::restrictedrange @> 7 +-- +STMT: SelectStmt +== 331 +-- should fail +drop domain restrictedrange +-- +STMT: DropStmt +== 332 +|-- +-- Test multiple range types over the same subtype +|-- + +create type textrange1 as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +== 333 +create type textrange2 as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +== 334 +select textrange1('a','Z') @> 'b'::text +-- +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +STMT: SelectStmt +== 335 +select textrange2('a','z') @> 'b'::text +-- +FUNCTION: name="textrange2" function="textrange2" schema="" ctx=Call +STMT: SelectStmt +== 336 +drop type textrange1 +-- +STMT: DropStmt +== 337 +drop type textrange2 +-- +STMT: DropStmt +== 338 +|-- +-- Test polymorphic type system +|-- + +create function anyarray_anyrange_func(a anyarray, r anyrange) + returns anyelement as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 339 +select anyarray_anyrange_func(ARRAY[1,2], int4range(10,20)) +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 340 +-- should fail +select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20)) +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 341 +drop function anyarray_anyrange_func(anyarray, anyrange) +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=DDL +STMT: DropStmt +== 342 +-- should fail +create function bogus_func(anyelement) + returns anyrange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 343 +-- should fail +create function bogus_func(int) + returns anyrange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 344 +create function range_add_bounds(anyrange) + returns anyelement as 'select lower($1) + upper($1)' language sql +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 345 +select range_add_bounds(int4range(1, 17)) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 346 +select range_add_bounds(numrange(1.0001, 123.123)) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 347 +create function rangetypes_sql(q anyrange, b anyarray, out c anyelement) + as $$ select upper($1) + $2[1] $$ + language sql +-- +FUNCTION: name="rangetypes_sql" function="rangetypes_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 348 +select rangetypes_sql(int4range(1,10), ARRAY[2,20]) +-- +FUNCTION: name="rangetypes_sql" function="rangetypes_sql" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 349 +select rangetypes_sql(numrange(1,10), ARRAY[2,20]) +-- +FUNCTION: name="rangetypes_sql" function="rangetypes_sql" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 350 +-- match failure + +create function anycompatiblearray_anycompatiblerange_func(a anycompatiblearray, r anycompatiblerange) + returns anycompatible as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 351 +select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], int4range(10,20)) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 352 +select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], numrange(10,20)) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 353 +-- should fail +select anycompatiblearray_anycompatiblerange_func(ARRAY[1.1,2], int4range(10,20)) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 354 +drop function anycompatiblearray_anycompatiblerange_func(anycompatiblearray, anycompatiblerange) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=DDL +STMT: DropStmt +== 355 +-- should fail +create function bogus_func(anycompatible) + returns anycompatiblerange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 356 +|-- +-- Arrays of ranges +|-- + +select ARRAY[numrange(1.1, 1.2), numrange(12.3, 155.5)] +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +== 357 +create table i8r_array (f1 int, f2 int8range[]) +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=DDL +STMT: CreateStmt +== 358 +insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]) +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=DML +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 359 +select * from i8r_array +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=Select +STMT: SelectStmt +== 360 +drop table i8r_array +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=DDL +STMT: DropStmt +== 361 +|-- +-- Ranges of arrays +|-- + +create type arrayrange as range (subtype=int4[]) +-- +STMT: CreateRangeStmt +== 362 +select arrayrange(ARRAY[1,2], ARRAY[2,1]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 363 +select arrayrange(ARRAY[2,1], ARRAY[1,2]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 364 +-- fail + +select array[1,1] <@ arrayrange(array[1,2], array[2,1]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 365 +select array[1,3] <@ arrayrange(array[1,2], array[2,1]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +== 366 +|-- +-- Ranges of composites +|-- + +create type two_ints as (a int, b int) +-- +STMT: CompositeTypeStmt +== 367 +create type two_ints_range as range (subtype = two_ints) +-- +STMT: CreateRangeStmt +== 368 +-- with debug_parallel_query on, this exercises tqueue.c's range remapping +select *, row_to_json(upper(t)) as u from + (values (two_ints_range(row(1,2), row(3,4))), + (two_ints_range(row(5,6), row(7,8)))) v(t) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +STMT: SelectStmt +== 369 +-- this must be rejected to avoid self-inclusion issues: +alter type two_ints add attribute c two_ints_range +-- +TABLE: name="two_ints" schema="" table="two_ints" ctx=DDL +STMT: AlterTableStmt +== 370 +drop type two_ints cascade +-- +STMT: DropStmt +== 371 +|-- +-- Check behavior when subtype lacks a hash function +|-- + +create type varbitrange as range (subtype = varbit) +-- +STMT: CreateRangeStmt +== 372 +set enable_sort = off +-- +STMT: VariableSetStmt +== 373 +-- try to make it pick a hash setop implementation + +select '(01,10)'::varbitrange except select '(10,11)'::varbitrange +-- +STMT: SelectStmt +== 374 +reset enable_sort +-- +STMT: VariableSetStmt +== 375 +|-- +-- OUT/INOUT/TABLE functions +|-- + +-- infer anyrange from anyrange +create function outparam_succeed(i anyrange, out r anyrange, out t text) + as $$ select $1, 'foo'::text $$ language sql +-- +FUNCTION: name="outparam_succeed" function="outparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 376 +select * from outparam_succeed(int4range(1,2)) +-- +FUNCTION: name="outparam_succeed" function="outparam_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 377 +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 +-- +FUNCTION: name="outparam2_succeed" function="outparam2_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 378 +select * from outparam2_succeed(int4range(1,11)) +-- +FUNCTION: name="outparam2_succeed" function="outparam2_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 379 +-- infer anyarray from anyrange +create function outparam_succeed2(i anyrange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql +-- +FUNCTION: name="outparam_succeed2" function="outparam_succeed2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 380 +select * from outparam_succeed2(int4range(int4range(1,2))) +-- +FUNCTION: name="outparam_succeed2" function="outparam_succeed2" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 381 +-- infer anyelement from anyrange +create function inoutparam_succeed(out i anyelement, inout r anyrange) + as $$ select upper($1), $1 $$ language sql +-- +FUNCTION: name="inoutparam_succeed" function="inoutparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 382 +select * from inoutparam_succeed(int4range(1,2)) +-- +FUNCTION: name="inoutparam_succeed" function="inoutparam_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 383 +create function table_succeed(r anyrange) + returns table(l anyelement, u anyelement) + as $$ select lower($1), upper($1) $$ + language sql +-- +FUNCTION: name="table_succeed" function="table_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 384 +select * from table_succeed(int4range(1,11)) +-- +FUNCTION: name="table_succeed" function="table_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +== 385 +-- should fail +create function outparam_fail(i anyelement, out r anyrange, out t text) + as $$ select '[1,10]', 'foo' $$ language sql +-- +FUNCTION: name="outparam_fail" function="outparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 386 +--should fail +create function inoutparam_fail(inout i anyelement, out r anyrange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="inoutparam_fail" function="inoutparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 387 +--should fail +create function table_fail(i anyelement) returns table(i anyelement, r anyrange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="table_fail" function="table_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 388 +|-- +-- Test support functions +|-- + +-- empty range +explain (verbose, costs off) +select current_date <@ daterange 'empty' +-- +STMT: ExplainStmt +STMT: SelectStmt +== 389 +-- unbounded range +explain (verbose, costs off) +select current_date <@ daterange(NULL, NULL) +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 390 +-- only lower bound present +explain (verbose, costs off) +select current_date <@ daterange('2000-01-01', NULL, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 391 +-- only upper bound present +explain (verbose, costs off) +select current_date <@ daterange(NULL, '2000-01-01', '(]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 392 +-- lower range "-Infinity" excluded +explain (verbose, costs off) +select current_date <@ daterange('-Infinity', '1997-04-10'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 393 +-- lower range "-Infinity" included +explain (verbose, costs off) +select current_date <@ daterange('-Infinity', '1997-04-10'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 394 +-- upper range "Infinity" excluded +explain (verbose, costs off) +select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 395 +-- upper range "Infinity" included +explain (verbose, costs off) +select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 396 +-- should also work if we use "@>" +explain (verbose, costs off) +select daterange('-Infinity', '1997-04-10'::date, '()') @> current_date +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 397 +explain (verbose, costs off) +select daterange('2002-09-25'::date, 'Infinity', '[]') @> current_date +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 398 +-- Check that volatile cases are not optimized +explain (verbose, costs off) +select now() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00') +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="tstzrange" function="tstzrange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 399 +explain (verbose, costs off) -- unsafe! +select clock_timestamp() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00') +-- +FUNCTION: name="clock_timestamp" function="clock_timestamp" schema="" ctx=Call +FUNCTION: name="tstzrange" function="tstzrange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 400 +explain (verbose, costs off) +select clock_timestamp() <@ tstzrange('2024-01-20 00:00', NULL) +-- +FUNCTION: name="clock_timestamp" function="clock_timestamp" schema="" ctx=Call +FUNCTION: name="tstzrange" function="tstzrange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 401 +-- test a custom range type with a non-default operator class +create type textrange_supp as range ( + subtype = text, + subtype_opclass = text_pattern_ops +) +-- +STMT: CreateRangeStmt +== 402 +create temp table text_support_test (t text collate "C") +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=DDL +STMT: CreateStmt +== 403 +insert into text_support_test values ('a'), ('c'), ('d'), ('ch') +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 404 +explain (costs off) +select * from text_support_test where t <@ textrange_supp('a', 'd') +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=Select +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 405 +select * from text_support_test where t <@ textrange_supp('a', 'd') +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=Select +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +== 406 +drop table text_support_test +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=DDL +STMT: DropStmt +== 407 +drop type textrange_supp +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/regex.metadata.json b/parser/testdata/summary/postgres_regress/regex.metadata.json new file mode 100644 index 0000000..60e76e3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/regex.metadata.json @@ -0,0 +1,109 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105" + ] +} diff --git a/parser/testdata/summary/postgres_regress/regex.test b/parser/testdata/summary/postgres_regress/regex.test new file mode 100644 index 0000000..13b7095 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/regex.test @@ -0,0 +1,527 @@ +== 001 +|-- +-- Regular expression tests +|-- + +-- Don't want to have to double backslashes in regexes +set standard_conforming_strings = on +-- +STMT: VariableSetStmt +== 002 +-- Test simple quantified backrefs +select 'bbbbb' ~ '^([bc])\1*$' as t +-- +STMT: SelectStmt +== 003 +select 'ccc' ~ '^([bc])\1*$' as t +-- +STMT: SelectStmt +== 004 +select 'xxx' ~ '^([bc])\1*$' as f +-- +STMT: SelectStmt +== 005 +select 'bbc' ~ '^([bc])\1*$' as f +-- +STMT: SelectStmt +== 006 +select 'b' ~ '^([bc])\1*$' as t +-- +STMT: SelectStmt +== 007 +-- Test quantified backref within a larger expression +select 'abc abc abc' ~ '^(\w+)( \1)+$' as t +-- +STMT: SelectStmt +== 008 +select 'abc abd abc' ~ '^(\w+)( \1)+$' as f +-- +STMT: SelectStmt +== 009 +select 'abc abc abd' ~ '^(\w+)( \1)+$' as f +-- +STMT: SelectStmt +== 010 +select 'abc abc abc' ~ '^(.+)( \1)+$' as t +-- +STMT: SelectStmt +== 011 +select 'abc abd abc' ~ '^(.+)( \1)+$' as f +-- +STMT: SelectStmt +== 012 +select 'abc abc abd' ~ '^(.+)( \1)+$' as f +-- +STMT: SelectStmt +== 013 +-- Test some cases that crashed in 9.2beta1 due to pmatch[] array overrun +select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)') +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 014 +select substring('a' from '((a))+') +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 015 +select substring('a' from '((a)+)') +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 016 +-- Test regexp_match() +select regexp_match('abc', '') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +== 017 +select regexp_match('abc', 'bc') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +== 018 +select regexp_match('abc', 'd') is null +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +== 019 +select regexp_match('abc', '(B)(c)', 'i') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +== 020 +select regexp_match('abc', 'Bd', 'ig') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- error + +-- Test lookahead constraints +select regexp_matches('ab', 'a(?=b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 022 +select regexp_matches('a', 'a(?=b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 023 +select regexp_matches('abc', 'a(?=b)b*(?=c)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 024 +select regexp_matches('ab', 'a(?=b)b*(?=c)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 025 +select regexp_matches('ab', 'a(?!b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 026 +select regexp_matches('a', 'a(?!b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 027 +select regexp_matches('b', '(?=b)b') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 028 +select regexp_matches('a', '(?=b)b') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 029 +-- Test lookbehind constraints +select regexp_matches('abb', '(?<=a)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 030 +select regexp_matches('a', 'a(?<=a)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 031 +select regexp_matches('abc', 'a(?<=a)b*(?<=b)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 032 +select regexp_matches('ab', 'a(?<=a)b*(?<=b)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +== 033 +select regexp_matches('ab', 'a*(? 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT reloptions FROM pg_class WHERE oid = + (SELECT reltoastrelid FROM pg_class + WHERE oid = 'reloptions_test'::regclass) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 038 +ALTER TABLE reloptions_test RESET (vacuum_truncate) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: AlterTableStmt +== 039 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 040 +INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +-- Do an aggressive vacuum to prevent page-skipping. +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: VacuumStmt +== 042 +SELECT pg_relation_size('reloptions_test') = 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +== 043 +-- Test toast.* options +DROP TABLE reloptions_test +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: DropStmt +== 044 +CREATE TABLE reloptions_test (s VARCHAR) + WITH (toast.autovacuum_vacuum_cost_delay = 23) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: CreateStmt +== 045 +SELECT reltoastrelid as toast_oid + FROM pg_class WHERE oid = 'reloptions_test'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 046 +SELECT reloptions FROM pg_class WHERE oid = :toast_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 45 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 047 +ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: AlterTableStmt +== 048 +SELECT reloptions FROM pg_class WHERE oid = :toast_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 45 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 049 +ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: AlterTableStmt +== 050 +SELECT reloptions FROM pg_class WHERE oid = :toast_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 45 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 051 +-- Fail on non-existent options in toast namespace +CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42) +-- +TABLE: name="reloptions_test2" schema="" table="reloptions_test2" ctx=DDL +STMT: CreateStmt +== 052 +-- Mix TOAST & heap +DROP TABLE reloptions_test +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: DropStmt +== 053 +CREATE TABLE reloptions_test (s VARCHAR) WITH + (toast.autovacuum_vacuum_cost_delay = 23, + autovacuum_vacuum_cost_delay = 24, fillfactor = 40) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: CreateStmt +== 054 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 055 +SELECT reloptions FROM pg_class WHERE oid = ( + SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 056 +|-- +-- CREATE INDEX, ALTER INDEX for btrees +|-- + +CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +== 057 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 058 +-- Fail when option and namespace do not exist +CREATE INDEX reloptions_test_idx ON reloptions_test (s) + WITH (not_existing_option=2) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +== 059 +CREATE INDEX reloptions_test_idx ON reloptions_test (s) + WITH (not_existing_ns.fillfactor=2) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +== 060 +-- Check allowed ranges +CREATE INDEX reloptions_test_idx2 ON reloptions_test (s) WITH (fillfactor=1) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +== 061 +CREATE INDEX reloptions_test_idx2 ON reloptions_test (s) WITH (fillfactor=130) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +== 062 +-- Check ALTER +ALTER INDEX reloptions_test_idx SET (fillfactor=40) +-- +STMT: AlterTableStmt +== 063 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 064 +-- Check ALTER on empty reloption list +CREATE INDEX reloptions_test_idx3 ON reloptions_test (s) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +== 065 +ALTER INDEX reloptions_test_idx3 SET (fillfactor=40) +-- +STMT: AlterTableStmt +== 066 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx3'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/replica_identity.metadata.json b/parser/testdata/summary/postgres_regress/replica_identity.metadata.json new file mode 100644 index 0000000..dc9d431 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/replica_identity.metadata.json @@ -0,0 +1,60 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056" + ] +} diff --git a/parser/testdata/summary/postgres_regress/replica_identity.test b/parser/testdata/summary/postgres_regress/replica_identity.test new file mode 100644 index 0000000..6407b70 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/replica_identity.test @@ -0,0 +1,342 @@ +== 001 +CREATE TABLE test_replica_identity ( + id serial primary key, + keya text not null, + keyb text not null, + nonkey text, + CONSTRAINT test_replica_identity_unique_defer UNIQUE (keya, keyb) DEFERRABLE, + CONSTRAINT test_replica_identity_unique_nondefer UNIQUE (keya, keyb) +) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE test_replica_identity_othertable (id serial primary key) +-- +TABLE: name="test_replica_identity_othertable" schema="" table="test_replica_identity_othertable" ctx=DDL +STMT: CreateStmt +== 003 +CREATE TABLE test_replica_identity_t3 (id serial constraint pk primary key deferrable) +-- +TABLE: name="test_replica_identity_t3" schema="" table="test_replica_identity_t3" ctx=DDL +STMT: CreateStmt +== 004 +CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +== 005 +CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity (keya, keyb) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +== 006 +CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity (keya, nonkey) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +== 007 +CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +== 008 +CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, keyb, (3)) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +== 009 +CREATE UNIQUE INDEX test_replica_identity_partial ON test_replica_identity (keya, keyb) WHERE keyb != '3' +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +== 010 +-- default is 'd'/DEFAULT for user created tables +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 011 +-- but 'none' for system tables +SELECT relreplident FROM pg_class WHERE oid = 'pg_class'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 012 +SELECT relreplident FROM pg_class WHERE oid = 'pg_constraint'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 013 +---- +-- Make sure we detect ineligible indexes +---- + +-- fail, not unique +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 014 +-- fail, not a candidate key, nullable column +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_nonkey +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 015 +-- fail, hash indexes cannot do uniqueness +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_hash +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 016 +-- fail, expression index +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_expr +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 017 +-- fail, partial index +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_partial +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 018 +-- fail, not our index +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_othertable_pkey +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 019 +-- fail, deferrable +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_defer +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 020 +-- fail, deferrable +ALTER TABLE test_replica_identity_t3 REPLICA IDENTITY USING INDEX pk +-- +TABLE: name="test_replica_identity_t3" schema="" table="test_replica_identity_t3" ctx=DDL +STMT: AlterTableStmt +== 021 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 022 +---- +-- Make sure index cases succeed +---- + +-- succeed, primary key +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_pkey +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 023 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 024 +-- succeed, nondeferrable unique constraint over nonnullable cols +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 025 +-- succeed unique index over nonnullable cols +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 026 +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 027 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 028 +SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="indisreplident" +STMT: SelectStmt +== 029 +---- +-- Make sure non index cases work +---- +ALTER TABLE test_replica_identity REPLICA IDENTITY DEFAULT +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 030 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 031 +SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="indisreplident" +STMT: SelectStmt +== 032 +ALTER TABLE test_replica_identity REPLICA IDENTITY FULL +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 033 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 034 +ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +== 035 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 036 +--- +-- Test that ALTER TABLE rewrite preserves nondefault replica identity +--- + +-- constraint variant +CREATE TABLE test_replica_identity2 (id int UNIQUE NOT NULL) +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: CreateStmt +== 037 +ALTER TABLE test_replica_identity2 REPLICA IDENTITY USING INDEX test_replica_identity2_id_key +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: AlterTableStmt +== 038 +ALTER TABLE test_replica_identity2 ALTER COLUMN id TYPE bigint +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: AlterTableStmt +== 039 +-- straight index variant +CREATE TABLE test_replica_identity3 (id int NOT NULL) +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: CreateStmt +== 040 +CREATE UNIQUE INDEX test_replica_identity3_id_key ON test_replica_identity3 (id) +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: IndexStmt +== 041 +ALTER TABLE test_replica_identity3 REPLICA IDENTITY USING INDEX test_replica_identity3_id_key +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: AlterTableStmt +== 042 +ALTER TABLE test_replica_identity3 ALTER COLUMN id TYPE bigint +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: AlterTableStmt +== 043 +-- ALTER TABLE DROP NOT NULL is not allowed for columns part of an index +-- used as replica identity. +ALTER TABLE test_replica_identity3 ALTER COLUMN id DROP NOT NULL +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: AlterTableStmt +== 044 +|-- +-- Test that replica identity can be set on an index that's not yet valid. +-- (This matches the way pg_dump will try to dump a partitioned table.) +|-- +CREATE TABLE test_replica_identity4(id integer NOT NULL) PARTITION BY LIST (id) +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: CreateStmt +== 045 +CREATE TABLE test_replica_identity4_1(id integer NOT NULL) +-- +TABLE: name="test_replica_identity4_1" schema="" table="test_replica_identity4_1" ctx=DDL +STMT: CreateStmt +== 046 +ALTER TABLE ONLY test_replica_identity4 + ATTACH PARTITION test_replica_identity4_1 FOR VALUES IN (1) +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: AlterTableStmt +== 047 +ALTER TABLE ONLY test_replica_identity4 + ADD CONSTRAINT test_replica_identity4_pkey PRIMARY KEY (id) +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: AlterTableStmt +== 048 +ALTER TABLE ONLY test_replica_identity4 + REPLICA IDENTITY USING INDEX test_replica_identity4_pkey +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: AlterTableStmt +== 049 +ALTER TABLE ONLY test_replica_identity4_1 + ADD CONSTRAINT test_replica_identity4_1_pkey PRIMARY KEY (id) +-- +TABLE: name="test_replica_identity4_1" schema="" table="test_replica_identity4_1" ctx=DDL +STMT: AlterTableStmt +== 050 +ALTER INDEX test_replica_identity4_pkey + ATTACH PARTITION test_replica_identity4_1_pkey +-- +STMT: AlterTableStmt +== 051 +DROP TABLE test_replica_identity +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: DropStmt +== 052 +DROP TABLE test_replica_identity2 +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: DropStmt +== 053 +DROP TABLE test_replica_identity3 +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: DropStmt +== 054 +DROP TABLE test_replica_identity4 +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: DropStmt +== 055 +DROP TABLE test_replica_identity_othertable +-- +TABLE: name="test_replica_identity_othertable" schema="" table="test_replica_identity_othertable" ctx=DDL +STMT: DropStmt +== 056 +DROP TABLE test_replica_identity_t3 +-- +TABLE: name="test_replica_identity_t3" schema="" table="test_replica_identity_t3" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/returning.metadata.json b/parser/testdata/summary/postgres_regress/returning.metadata.json new file mode 100644 index 0000000..2be5689 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/returning.metadata.json @@ -0,0 +1,81 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077" + ] +} diff --git a/parser/testdata/summary/postgres_regress/returning.test b/parser/testdata/summary/postgres_regress/returning.test new file mode 100644 index 0000000..cfda694 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/returning.test @@ -0,0 +1,491 @@ +== 001 +|-- +-- Test INSERT/UPDATE/DELETE RETURNING +|-- + +-- Simple cases + +CREATE TEMP TABLE foo (f1 serial, f2 text, f3 int default 42) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO foo (f2,f3) + VALUES ('test', DEFAULT), ('More', 11), (upper('more'), 7+9) + RETURNING *, f1+f3 AS sum +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 004 +UPDATE foo SET f2 = lower(f2), f3 = DEFAULT RETURNING foo.*, f1+f3 AS sum13 +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: UpdateStmt +== 005 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 006 +DELETE FROM foo WHERE f1 > 2 RETURNING f3, f2, f1, least(f1,f3) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: DeleteStmt +== 007 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 008 +-- Subplans and initplans in the RETURNING list + +INSERT INTO foo SELECT f1+10, f2, f3+99 FROM foo + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 009 +UPDATE foo SET f3 = f3 * 2 + WHERE f1 > 10 + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +== 010 +DELETE FROM foo + WHERE f1 > 10 + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: DeleteStmt +STMT: SelectStmt +== 011 +-- Joins + +UPDATE foo SET f3 = f3*2 + FROM int4_tbl i + WHERE foo.f1 + 123455 = i.f1 + RETURNING foo.*, i.f1 as "i.f1" +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: UpdateStmt +== 012 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 013 +DELETE FROM foo + USING int4_tbl i + WHERE foo.f1 + 123455 = i.f1 + RETURNING foo.*, i.f1 as "i.f1" +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: DeleteStmt +== 014 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 015 +-- Check inheritance cases + +CREATE TEMP TABLE foochild (fc int) INHERITS (foo) +-- +TABLE: name="foochild" schema="" table="foochild" ctx=DDL +STMT: CreateStmt +== 016 +INSERT INTO foochild VALUES(123,'child',999,-123) +-- +TABLE: name="foochild" schema="" table="foochild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +ALTER TABLE foo ADD COLUMN f4 int8 DEFAULT 99 +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: AlterTableStmt +== 018 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 019 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +== 020 +UPDATE foo SET f4 = f4 + f3 WHERE f4 = 99 RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: UpdateStmt +== 021 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 022 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +== 023 +UPDATE foo SET f3 = f3*2 + FROM int8_tbl i + WHERE foo.f1 = i.q2 + RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: UpdateStmt +== 024 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 025 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +== 026 +DELETE FROM foo + USING int8_tbl i + WHERE foo.f1 = i.q2 + RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: DeleteStmt +== 027 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 028 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +== 029 +DROP TABLE foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=DDL +STMT: DropStmt +== 030 +-- Rules and views + +CREATE TEMP VIEW voo AS SELECT f1, f2 FROM foo +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 031 +CREATE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +== 032 +INSERT INTO voo VALUES(11,'zit') +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +-- fails: +INSERT INTO voo VALUES(12,'zoo') RETURNING *, f1*2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +-- fails, incompatible list: +CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) RETURNING * +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +== 035 +CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) RETURNING f1, f2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +== 036 +-- should still work +INSERT INTO voo VALUES(13,'zit2') +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +-- works now +INSERT INTO voo VALUES(14,'zoo2') RETURNING * +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 039 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +== 040 +CREATE OR REPLACE RULE voo_u AS ON UPDATE TO voo DO INSTEAD + UPDATE foo SET f1 = new.f1, f2 = new.f2 WHERE f1 = old.f1 + RETURNING f1, f2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +== 041 +update voo set f1 = f1 + 1 where f2 = 'zoo2' +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: UpdateStmt +== 042 +update voo set f1 = f1 + 1 where f2 = 'zoo2' RETURNING *, f1*2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: UpdateStmt +== 043 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 044 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +== 045 +CREATE OR REPLACE RULE voo_d AS ON DELETE TO voo DO INSTEAD + DELETE FROM foo WHERE f1 = old.f1 + RETURNING f1, f2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +== 046 +DELETE FROM foo WHERE f1 = 13 +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: DeleteStmt +== 047 +DELETE FROM foo WHERE f2 = 'zit' RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: DeleteStmt +== 048 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 049 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +== 050 +-- Check use of a whole-row variable for an un-flattenable view +CREATE TEMP VIEW foo_v AS SELECT * FROM foo OFFSET 0 +-- +TABLE: name="foo_v" schema="" table="foo_v" ctx=DDL +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 051 +UPDATE foo SET f2 = foo_v.f2 FROM foo_v WHERE foo_v.f1 = foo.f1 + RETURNING foo_v +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="foo_v" schema="" table="foo_v" ctx=Select +STMT: UpdateStmt +== 052 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 053 +-- Check use of a whole-row variable for an inlined set-returning function +CREATE FUNCTION foo_f() RETURNS SETOF foo AS + $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 054 +UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 + RETURNING foo_f +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=Call +STMT: UpdateStmt +== 055 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 056 +DROP FUNCTION foo_f() +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: DropStmt +== 057 +-- As above, but SRF is defined to return a composite type +CREATE TYPE foo_t AS (f1 int, f2 text, f3 int, f4 int8) +-- +STMT: CompositeTypeStmt +== 058 +CREATE FUNCTION foo_f() RETURNS SETOF foo_t AS + $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 059 +UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 + RETURNING foo_f +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=Call +STMT: UpdateStmt +== 060 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 061 +DROP FUNCTION foo_f() +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: DropStmt +== 062 +DROP TYPE foo_t +-- +STMT: DropStmt +== 063 +-- Try a join case + +CREATE TEMP TABLE joinme (f2j text, other int) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DDL +STMT: CreateStmt +== 064 +INSERT INTO joinme VALUES('more', 12345) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +INSERT INTO joinme VALUES('zoo2', 54321) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 066 +INSERT INTO joinme VALUES('other', 0) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +CREATE TEMP VIEW joinview AS + SELECT foo.*, other FROM foo JOIN joinme ON (f2 = f2j) +-- +TABLE: name="joinview" schema="" table="joinview" ctx=DDL +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="joinme" schema="" table="joinme" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 068 +SELECT * FROM joinview +-- +TABLE: name="joinview" schema="" table="joinview" ctx=Select +STMT: SelectStmt +== 069 +CREATE RULE joinview_u AS ON UPDATE TO joinview DO INSTEAD + UPDATE foo SET f1 = new.f1, f3 = new.f3 + FROM joinme WHERE f2 = f2j AND f2 = old.f2 + RETURNING foo.*, other +-- +TABLE: name="joinview" schema="" table="joinview" ctx=DDL +STMT: RuleStmt +== 070 +UPDATE joinview SET f1 = f1 + 1 WHERE f3 = 57 RETURNING *, other + 1 +-- +TABLE: name="joinview" schema="" table="joinview" ctx=DML +STMT: UpdateStmt +== 071 +SELECT * FROM joinview +-- +TABLE: name="joinview" schema="" table="joinview" ctx=Select +STMT: SelectStmt +== 072 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 073 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +== 074 +-- Check aliased target relation +INSERT INTO foo AS bar DEFAULT VALUES RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt +== 075 +-- ok +INSERT INTO foo AS bar DEFAULT VALUES RETURNING foo.* +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt +== 076 +-- fails, wrong name +INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.* +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt +== 077 +-- ok +INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.f3 +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt diff --git a/parser/testdata/summary/postgres_regress/roleattributes.metadata.json b/parser/testdata/summary/postgres_regress/roleattributes.metadata.json new file mode 100644 index 0000000..fb87925 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/roleattributes.metadata.json @@ -0,0 +1,84 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080" + ] +} diff --git a/parser/testdata/summary/postgres_regress/roleattributes.test b/parser/testdata/summary/postgres_regress/roleattributes.test new file mode 100644 index 0000000..e294b2c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/roleattributes.test @@ -0,0 +1,393 @@ +== 001 +-- default for superuser is false +CREATE ROLE regress_test_def_superuser +-- +STMT: CreateRoleStmt +== 002 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 003 +CREATE ROLE regress_test_superuser WITH SUPERUSER +-- +STMT: CreateRoleStmt +== 004 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 005 +ALTER ROLE regress_test_superuser WITH NOSUPERUSER +-- +STMT: AlterRoleStmt +== 006 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 007 +ALTER ROLE regress_test_superuser WITH SUPERUSER +-- +STMT: AlterRoleStmt +== 008 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 009 +-- default for inherit is true +CREATE ROLE regress_test_def_inherit +-- +STMT: CreateRoleStmt +== 010 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 011 +CREATE ROLE regress_test_inherit WITH NOINHERIT +-- +STMT: CreateRoleStmt +== 012 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 013 +ALTER ROLE regress_test_inherit WITH INHERIT +-- +STMT: AlterRoleStmt +== 014 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 015 +ALTER ROLE regress_test_inherit WITH NOINHERIT +-- +STMT: AlterRoleStmt +== 016 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 017 +-- default for create role is false +CREATE ROLE regress_test_def_createrole +-- +STMT: CreateRoleStmt +== 018 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 019 +CREATE ROLE regress_test_createrole WITH CREATEROLE +-- +STMT: CreateRoleStmt +== 020 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 021 +ALTER ROLE regress_test_createrole WITH NOCREATEROLE +-- +STMT: AlterRoleStmt +== 022 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 023 +ALTER ROLE regress_test_createrole WITH CREATEROLE +-- +STMT: AlterRoleStmt +== 024 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 025 +-- default for create database is false +CREATE ROLE regress_test_def_createdb +-- +STMT: CreateRoleStmt +== 026 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 027 +CREATE ROLE regress_test_createdb WITH CREATEDB +-- +STMT: CreateRoleStmt +== 028 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 029 +ALTER ROLE regress_test_createdb WITH NOCREATEDB +-- +STMT: AlterRoleStmt +== 030 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 031 +ALTER ROLE regress_test_createdb WITH CREATEDB +-- +STMT: AlterRoleStmt +== 032 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 033 +-- default for can login is false for role +CREATE ROLE regress_test_def_role_canlogin +-- +STMT: CreateRoleStmt +== 034 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 035 +CREATE ROLE regress_test_role_canlogin WITH LOGIN +-- +STMT: CreateRoleStmt +== 036 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 037 +ALTER ROLE regress_test_role_canlogin WITH NOLOGIN +-- +STMT: AlterRoleStmt +== 038 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 039 +ALTER ROLE regress_test_role_canlogin WITH LOGIN +-- +STMT: AlterRoleStmt +== 040 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 041 +-- default for can login is true for user +CREATE USER regress_test_def_user_canlogin +-- +STMT: CreateRoleStmt +== 042 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 043 +CREATE USER regress_test_user_canlogin WITH NOLOGIN +-- +STMT: CreateRoleStmt +== 044 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 045 +ALTER USER regress_test_user_canlogin WITH LOGIN +-- +STMT: AlterRoleStmt +== 046 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 047 +ALTER USER regress_test_user_canlogin WITH NOLOGIN +-- +STMT: AlterRoleStmt +== 048 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 049 +-- default for replication is false +CREATE ROLE regress_test_def_replication +-- +STMT: CreateRoleStmt +== 050 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 051 +CREATE ROLE regress_test_replication WITH REPLICATION +-- +STMT: CreateRoleStmt +== 052 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 053 +ALTER ROLE regress_test_replication WITH NOREPLICATION +-- +STMT: AlterRoleStmt +== 054 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 055 +ALTER ROLE regress_test_replication WITH REPLICATION +-- +STMT: AlterRoleStmt +== 056 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 057 +-- default for bypassrls is false +CREATE ROLE regress_test_def_bypassrls +-- +STMT: CreateRoleStmt +== 058 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 059 +CREATE ROLE regress_test_bypassrls WITH BYPASSRLS +-- +STMT: CreateRoleStmt +== 060 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 061 +ALTER ROLE regress_test_bypassrls WITH NOBYPASSRLS +-- +STMT: AlterRoleStmt +== 062 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 063 +ALTER ROLE regress_test_bypassrls WITH BYPASSRLS +-- +STMT: AlterRoleStmt +== 064 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +== 065 +-- clean up roles +DROP ROLE regress_test_def_superuser +-- +STMT: DropRoleStmt +== 066 +DROP ROLE regress_test_superuser +-- +STMT: DropRoleStmt +== 067 +DROP ROLE regress_test_def_inherit +-- +STMT: DropRoleStmt +== 068 +DROP ROLE regress_test_inherit +-- +STMT: DropRoleStmt +== 069 +DROP ROLE regress_test_def_createrole +-- +STMT: DropRoleStmt +== 070 +DROP ROLE regress_test_createrole +-- +STMT: DropRoleStmt +== 071 +DROP ROLE regress_test_def_createdb +-- +STMT: DropRoleStmt +== 072 +DROP ROLE regress_test_createdb +-- +STMT: DropRoleStmt +== 073 +DROP ROLE regress_test_def_role_canlogin +-- +STMT: DropRoleStmt +== 074 +DROP ROLE regress_test_role_canlogin +-- +STMT: DropRoleStmt +== 075 +DROP USER regress_test_def_user_canlogin +-- +STMT: DropRoleStmt +== 076 +DROP USER regress_test_user_canlogin +-- +STMT: DropRoleStmt +== 077 +DROP ROLE regress_test_def_replication +-- +STMT: DropRoleStmt +== 078 +DROP ROLE regress_test_replication +-- +STMT: DropRoleStmt +== 079 +DROP ROLE regress_test_def_bypassrls +-- +STMT: DropRoleStmt +== 080 +DROP ROLE regress_test_bypassrls +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/rowsecurity.metadata.json b/parser/testdata/summary/postgres_regress/rowsecurity.metadata.json new file mode 100644 index 0000000..dcaa437 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rowsecurity.metadata.json @@ -0,0 +1,779 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775" + ] +} diff --git a/parser/testdata/summary/postgres_regress/rowsecurity.test b/parser/testdata/summary/postgres_regress/rowsecurity.test new file mode 100644 index 0000000..148e48e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rowsecurity.test @@ -0,0 +1,4822 @@ +== 001 +|-- +-- Test of Row-level security feature +|-- + +-- Clean up in case a prior regression run failed + +-- Suppress NOTICE messages when users/groups don't exist +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +== 002 +DROP USER IF EXISTS regress_rls_alice +-- +STMT: DropRoleStmt +== 003 +DROP USER IF EXISTS regress_rls_bob +-- +STMT: DropRoleStmt +== 004 +DROP USER IF EXISTS regress_rls_carol +-- +STMT: DropRoleStmt +== 005 +DROP USER IF EXISTS regress_rls_dave +-- +STMT: DropRoleStmt +== 006 +DROP USER IF EXISTS regress_rls_exempt_user +-- +STMT: DropRoleStmt +== 007 +DROP ROLE IF EXISTS regress_rls_group1 +-- +STMT: DropRoleStmt +== 008 +DROP ROLE IF EXISTS regress_rls_group2 +-- +STMT: DropRoleStmt +== 009 +DROP SCHEMA IF EXISTS regress_rls_schema CASCADE +-- +STMT: DropStmt +== 010 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 011 +-- initial setup +CREATE USER regress_rls_alice NOLOGIN +-- +STMT: CreateRoleStmt +== 012 +CREATE USER regress_rls_bob NOLOGIN +-- +STMT: CreateRoleStmt +== 013 +CREATE USER regress_rls_carol NOLOGIN +-- +STMT: CreateRoleStmt +== 014 +CREATE USER regress_rls_dave NOLOGIN +-- +STMT: CreateRoleStmt +== 015 +CREATE USER regress_rls_exempt_user BYPASSRLS NOLOGIN +-- +STMT: CreateRoleStmt +== 016 +CREATE ROLE regress_rls_group1 NOLOGIN +-- +STMT: CreateRoleStmt +== 017 +CREATE ROLE regress_rls_group2 NOLOGIN +-- +STMT: CreateRoleStmt +== 018 +GRANT regress_rls_group1 TO regress_rls_bob +-- +STMT: GrantRoleStmt +== 019 +GRANT regress_rls_group2 TO regress_rls_carol +-- +STMT: GrantRoleStmt +== 020 +CREATE SCHEMA regress_rls_schema +-- +STMT: CreateSchemaStmt +== 021 +GRANT ALL ON SCHEMA regress_rls_schema to public +-- +STMT: GrantStmt +== 022 +SET search_path = regress_rls_schema +-- +STMT: VariableSetStmt +== 023 +-- setup of malicious function +CREATE OR REPLACE FUNCTION f_leak(text) RETURNS bool + COST 0.0000001 LANGUAGE plpgsql + AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END' +-- +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 024 +GRANT EXECUTE ON FUNCTION f_leak(text) TO public +-- +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=DDL +STMT: GrantStmt +== 025 +-- BASIC Row-Level Security Scenario + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 026 +CREATE TABLE uaccount ( + pguser name primary key, + seclv int +) +-- +TABLE: name="uaccount" schema="" table="uaccount" ctx=DDL +STMT: CreateStmt +== 027 +GRANT SELECT ON uaccount TO public +-- +TABLE: name="uaccount" schema="" table="uaccount" ctx=DDL +STMT: GrantStmt +== 028 +INSERT INTO uaccount VALUES + ('regress_rls_alice', 99), + ('regress_rls_bob', 1), + ('regress_rls_carol', 2), + ('regress_rls_dave', 3) +-- +TABLE: name="uaccount" schema="" table="uaccount" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +CREATE TABLE category ( + cid int primary key, + cname text +) +-- +TABLE: name="category" schema="" table="category" ctx=DDL +STMT: CreateStmt +== 030 +GRANT ALL ON category TO public +-- +TABLE: name="category" schema="" table="category" ctx=DDL +STMT: GrantStmt +== 031 +INSERT INTO category VALUES + (11, 'novel'), + (22, 'science fiction'), + (33, 'technology'), + (44, 'manga') +-- +TABLE: name="category" schema="" table="category" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +CREATE TABLE document ( + did int primary key, + cid int references category(cid), + dlevel int not null, + dauthor name, + dtitle text +) +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: CreateStmt +== 033 +GRANT ALL ON document TO public +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: GrantStmt +== 034 +INSERT INTO document VALUES + ( 1, 11, 1, 'regress_rls_bob', 'my first novel'), + ( 2, 11, 2, 'regress_rls_bob', 'my second novel'), + ( 3, 22, 2, 'regress_rls_bob', 'my science fiction'), + ( 4, 44, 1, 'regress_rls_bob', 'my first manga'), + ( 5, 44, 2, 'regress_rls_bob', 'my second manga'), + ( 6, 22, 1, 'regress_rls_carol', 'great science fiction'), + ( 7, 33, 2, 'regress_rls_carol', 'great technology book'), + ( 8, 44, 1, 'regress_rls_carol', 'great manga'), + ( 9, 22, 1, 'regress_rls_dave', 'awesome science fiction'), + (10, 33, 2, 'regress_rls_dave', 'awesome technology book') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +ALTER TABLE document ENABLE ROW LEVEL SECURITY +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: AlterTableStmt +== 036 +-- user's security level must be higher than or equal to document's +CREATE POLICY p1 ON document AS PERMISSIVE + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)) +-- +STMT: CreatePolicyStmt +== 037 +-- try to create a policy of bogus type +CREATE POLICY p1 ON document AS UGLY + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)) +-- +ERROR: unrecognized row security option "ugly" +CURSORPOS: 73 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 038 +-- but Dave isn't allowed to anything at cid 50 or above +-- this is to make sure that we sort the policies by name first +-- when applying WITH CHECK, a later INSERT by Dave should fail due +-- to p1r first +CREATE POLICY p2r ON document AS RESTRICTIVE TO regress_rls_dave + USING (cid <> 44 AND cid < 50) +-- +STMT: CreatePolicyStmt +== 039 +-- and Dave isn't allowed to see manga documents +CREATE POLICY p1r ON document AS RESTRICTIVE TO regress_rls_dave + USING (cid <> 44) +-- +STMT: CreatePolicyStmt +== 040 +SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename = 'document' ORDER BY policyname +-- +TABLE: name="pg_policies" schema="" table="pg_policies" ctx=Select +FILTER: schema="" table="" column="schemaname" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 041 +-- viewpoint from regress_rls_bob +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 042 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 043 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 044 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 045 +-- try a sampled version +SELECT * FROM document TABLESAMPLE BERNOULLI(50) REPEATABLE(0) + WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 046 +-- viewpoint from regress_rls_carol +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 047 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 048 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 049 +-- try a sampled version +SELECT * FROM document TABLESAMPLE BERNOULLI(50) REPEATABLE(0) + WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 050 +EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 051 +EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +-- viewpoint from regress_rls_dave +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +== 053 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 054 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 055 +EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 056 +EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 057 +-- 44 would technically fail for both p2r and p1r, but we should get an error +-- back from p1r for this because it sorts first +INSERT INTO document VALUES (100, 44, 1, 'regress_rls_dave', 'testing sorting of policies') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +-- fail +-- Just to see a p2r error +INSERT INTO document VALUES (100, 55, 1, 'regress_rls_dave', 'testing sorting of policies') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +-- fail + +-- only owner can change policies +ALTER POLICY p1 ON document USING (true) +-- +STMT: AlterPolicyStmt +== 060 +--fail +DROP POLICY p1 ON document +-- +STMT: DropStmt +== 061 +--fail + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 062 +ALTER POLICY p1 ON document USING (dauthor = current_user) +-- +STMT: AlterPolicyStmt +== 063 +-- viewpoint from regress_rls_bob again +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 064 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 065 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER by did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 066 +-- viewpoint from rls_regres_carol again +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 067 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 068 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER by did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 069 +EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 070 +EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 071 +-- interaction of FK/PK constraints +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 072 +CREATE POLICY p2 ON category + USING (CASE WHEN current_user = 'regress_rls_bob' THEN cid IN (11, 33) + WHEN current_user = 'regress_rls_carol' THEN cid IN (22, 44) + ELSE false END) +-- +STMT: CreatePolicyStmt +== 073 +ALTER TABLE category ENABLE ROW LEVEL SECURITY +-- +TABLE: name="category" schema="" table="category" ctx=DDL +STMT: AlterTableStmt +== 074 +-- cannot delete PK referenced by invisible FK +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 075 +SELECT * FROM document d FULL OUTER JOIN category c on d.cid = c.cid ORDER BY d.did, c.cid +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "c"="category" +ALIAS: "d"="document" +STMT: SelectStmt +== 076 +DELETE FROM category WHERE cid = 33 +-- +TABLE: name="category" schema="" table="category" ctx=DML +STMT: DeleteStmt +== 077 +-- fails with FK violation + +-- can insert FK referencing invisible PK +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 078 +SELECT * FROM document d FULL OUTER JOIN category c on d.cid = c.cid ORDER BY d.did, c.cid +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "c"="category" +ALIAS: "d"="document" +STMT: SelectStmt +== 079 +INSERT INTO document VALUES (11, 33, 1, current_user, 'hoge') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +-- UNIQUE or PRIMARY KEY constraint violation DOES reveal presence of row +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 081 +INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +-- Must fail with unique violation, revealing presence of did we can't see +SELECT * FROM document WHERE did = 8 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +== 083 +-- and confirm we can't see it + +-- RLS policies are checked before constraints +INSERT INTO document VALUES (8, 44, 1, 'regress_rls_carol', 'my third manga') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 084 +-- Should fail with RLS check violation, not duplicate key violation +UPDATE document SET did = 8, dauthor = 'regress_rls_carol' WHERE did = 5 +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: UpdateStmt +== 085 +-- Should fail with RLS check violation, not duplicate key violation + +-- database superuser does bypass RLS policy when enabled +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 086 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 087 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +== 088 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +== 089 +-- database superuser does bypass RLS policy when disabled +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 090 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 091 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +== 092 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +== 093 +-- database non-superuser with bypass privilege can bypass RLS policy when disabled +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +== 094 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 095 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +== 096 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +== 097 +-- RLS policy does not apply to table owner when RLS enabled. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 098 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 099 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +== 100 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +== 101 +-- RLS policy does not apply to table owner when RLS disabled. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 102 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 103 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +== 104 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +== 105 +|-- +-- Table inheritance and RLS policy +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 106 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 107 +CREATE TABLE t1 (id int not null primary key, a int, junk1 text, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 108 +ALTER TABLE t1 DROP COLUMN junk1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +== 109 +-- just a disturbing factor +GRANT ALL ON t1 TO public +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: GrantStmt +== 110 +COPY t1 FROM stdin WITH +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: CopyStmt +== 111 +CREATE TABLE t2 (c float) INHERITS (t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 112 +GRANT ALL ON t2 TO public +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: GrantStmt +== 113 +COPY t2 FROM stdin +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: CopyStmt +== 114 +CREATE TABLE t3 (id int not null primary key, c text, b text, a int) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +== 115 +ALTER TABLE t3 INHERIT t1 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: AlterTableStmt +== 116 +GRANT ALL ON t3 TO public +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: GrantStmt +== 117 +COPY t3(id, a,b,c) FROM stdin +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: CopyStmt +== 118 +CREATE POLICY p1 ON t1 FOR ALL TO PUBLIC USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 119 +-- be even number +CREATE POLICY p2 ON t2 FOR ALL TO PUBLIC USING (a % 2 = 1) +-- +STMT: CreatePolicyStmt +== 120 +-- be odd number + +ALTER TABLE t1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +== 121 +ALTER TABLE t2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +== 122 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 123 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 124 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 125 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 126 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 127 +-- reference to system column +SELECT tableoid::regclass, * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 128 +EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 129 +-- reference to whole-row reference +SELECT *, t1 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 130 +EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 131 +-- for share/update lock +SELECT * FROM t1 FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 132 +EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 133 +SELECT * FROM t1 WHERE f_leak(b) FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 134 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 135 +-- union all query +SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 136 +EXPLAIN (COSTS OFF) SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 137 +-- superuser is allowed to bypass RLS checks +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 138 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 139 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 140 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 141 +-- non-superuser with bypass privilege can bypass RLS policy when disabled +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +== 142 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 143 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 144 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 145 +|-- +-- Partitioned Tables +|-- + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 146 +CREATE TABLE part_document ( + did int, + cid int, + dlevel int not null, + dauthor name, + dtitle text +) PARTITION BY RANGE (cid) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DDL +STMT: CreateStmt +== 147 +GRANT ALL ON part_document TO public +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DDL +STMT: GrantStmt +== 148 +-- Create partitions for document categories +CREATE TABLE part_document_fiction PARTITION OF part_document FOR VALUES FROM (11) to (12) +-- +TABLE: name="part_document_fiction" schema="" table="part_document_fiction" ctx=DDL +STMT: CreateStmt +== 149 +CREATE TABLE part_document_satire PARTITION OF part_document FOR VALUES FROM (55) to (56) +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DDL +STMT: CreateStmt +== 150 +CREATE TABLE part_document_nonfiction PARTITION OF part_document FOR VALUES FROM (99) to (100) +-- +TABLE: name="part_document_nonfiction" schema="" table="part_document_nonfiction" ctx=DDL +STMT: CreateStmt +== 151 +GRANT ALL ON part_document_fiction TO public +-- +TABLE: name="part_document_fiction" schema="" table="part_document_fiction" ctx=DDL +STMT: GrantStmt +== 152 +GRANT ALL ON part_document_satire TO public +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DDL +STMT: GrantStmt +== 153 +GRANT ALL ON part_document_nonfiction TO public +-- +TABLE: name="part_document_nonfiction" schema="" table="part_document_nonfiction" ctx=DDL +STMT: GrantStmt +== 154 +INSERT INTO part_document VALUES + ( 1, 11, 1, 'regress_rls_bob', 'my first novel'), + ( 2, 11, 2, 'regress_rls_bob', 'my second novel'), + ( 3, 99, 2, 'regress_rls_bob', 'my science textbook'), + ( 4, 55, 1, 'regress_rls_bob', 'my first satire'), + ( 5, 99, 2, 'regress_rls_bob', 'my history book'), + ( 6, 11, 1, 'regress_rls_carol', 'great science fiction'), + ( 7, 99, 2, 'regress_rls_carol', 'great technology book'), + ( 8, 55, 2, 'regress_rls_carol', 'great satire'), + ( 9, 11, 1, 'regress_rls_dave', 'awesome science fiction'), + (10, 99, 2, 'regress_rls_dave', 'awesome technology book') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +ALTER TABLE part_document ENABLE ROW LEVEL SECURITY +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DDL +STMT: AlterTableStmt +== 156 +-- Create policy on parent +-- user's security level must be higher than or equal to document's +CREATE POLICY pp1 ON part_document AS PERMISSIVE + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)) +-- +STMT: CreatePolicyStmt +== 157 +-- Dave is only allowed to see cid < 55 +CREATE POLICY pp1r ON part_document AS RESTRICTIVE TO regress_rls_dave + USING (cid < 55) +-- +STMT: CreatePolicyStmt +== 158 +SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename like '%part_document%' ORDER BY policyname +-- +TABLE: name="pg_policies" schema="" table="pg_policies" ctx=Select +FILTER: schema="" table="" column="schemaname" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 159 +-- viewpoint from regress_rls_bob +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 160 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 161 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 162 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 163 +-- viewpoint from regress_rls_carol +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 164 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 165 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 166 +-- viewpoint from regress_rls_dave +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +== 167 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 168 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 169 +-- pp1 ERROR +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_dave', 'testing pp1') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 170 +-- fail +-- pp1r ERROR +INSERT INTO part_document VALUES (100, 99, 1, 'regress_rls_dave', 'testing pp1r') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 171 +-- fail + +-- Show that RLS policy does not apply for direct inserts to children +-- This should fail with RLS POLICY pp1r violation. +INSERT INTO part_document VALUES (100, 55, 1, 'regress_rls_dave', 'testing RLS with partitions') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +-- fail +-- But this should succeed. +INSERT INTO part_document_satire VALUES (100, 55, 1, 'regress_rls_dave', 'testing RLS with partitions') +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +-- success +-- We still cannot see the row using the parent +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 174 +-- But we can if we look directly +SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 175 +-- Turn on RLS and create policy on child to show RLS is checked before constraints +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 176 +ALTER TABLE part_document_satire ENABLE ROW LEVEL SECURITY +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DDL +STMT: AlterTableStmt +== 177 +CREATE POLICY pp3 ON part_document_satire AS RESTRICTIVE + USING (cid < 55) +-- +STMT: CreatePolicyStmt +== 178 +-- This should fail with RLS violation now. +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +== 179 +INSERT INTO part_document_satire VALUES (101, 55, 1, 'regress_rls_dave', 'testing RLS with partitions') +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 180 +-- fail +-- And now we cannot see directly into the partition either, due to RLS +SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 181 +-- The parent looks same as before +-- viewpoint from regress_rls_dave +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 182 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 183 +-- viewpoint from regress_rls_carol +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 184 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 185 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 186 +-- only owner can change policies +ALTER POLICY pp1 ON part_document USING (true) +-- +STMT: AlterPolicyStmt +== 187 +--fail +DROP POLICY pp1 ON part_document +-- +STMT: DropStmt +== 188 +--fail + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 189 +ALTER POLICY pp1 ON part_document USING (dauthor = current_user) +-- +STMT: AlterPolicyStmt +== 190 +-- viewpoint from regress_rls_bob again +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 191 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 192 +-- viewpoint from rls_regres_carol again +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 193 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +== 194 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +== 195 +-- database superuser does bypass RLS policy when enabled +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 196 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 197 +SELECT * FROM part_document ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +== 198 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +== 199 +-- database non-superuser with bypass privilege can bypass RLS policy when disabled +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +== 200 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 201 +SELECT * FROM part_document ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +== 202 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +== 203 +-- RLS policy does not apply to table owner when RLS enabled. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 204 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 205 +SELECT * FROM part_document ORDER by did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +== 206 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +== 207 +-- When RLS disabled, other users get ERROR. +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +== 208 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 209 +SELECT * FROM part_document ORDER by did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +== 210 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +== 211 +-- Check behavior with a policy that uses a SubPlan not an InitPlan. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 212 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 213 +CREATE POLICY pp3 ON part_document AS RESTRICTIVE + USING ((SELECT dlevel <= seclv FROM uaccount WHERE pguser = current_user)) +-- +STMT: CreatePolicyStmt +== 214 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 215 +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_carol', 'testing pp3') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +-- fail + +----- Dependencies ----- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 217 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 218 +CREATE TABLE dependee (x integer, y integer) +-- +TABLE: name="dependee" schema="" table="dependee" ctx=DDL +STMT: CreateStmt +== 219 +CREATE TABLE dependent (x integer, y integer) +-- +TABLE: name="dependent" schema="" table="dependent" ctx=DDL +STMT: CreateStmt +== 220 +CREATE POLICY d1 ON dependent FOR ALL + TO PUBLIC + USING (x = (SELECT d.x FROM dependee d WHERE d.y = y)) +-- +STMT: CreatePolicyStmt +== 221 +DROP TABLE dependee +-- +TABLE: name="dependee" schema="" table="dependee" ctx=DDL +STMT: DropStmt +== 222 +-- Should fail without CASCADE due to dependency on row security qual? + +DROP TABLE dependee CASCADE +-- +TABLE: name="dependee" schema="" table="dependee" ctx=DDL +STMT: DropStmt +== 223 +EXPLAIN (COSTS OFF) SELECT * FROM dependent +-- +TABLE: name="dependent" schema="" table="dependent" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 224 +-- After drop, should be unqualified + +----- RECURSION ---- + +|-- +-- Simple recursion +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 225 +CREATE TABLE rec1 (x integer, y integer) +-- +TABLE: name="rec1" schema="" table="rec1" ctx=DDL +STMT: CreateStmt +== 226 +CREATE POLICY r1 ON rec1 USING (x = (SELECT r.x FROM rec1 r WHERE y = r.y)) +-- +STMT: CreatePolicyStmt +== 227 +ALTER TABLE rec1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="rec1" schema="" table="rec1" ctx=DDL +STMT: AlterTableStmt +== 228 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 229 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +== 230 +-- fail, direct recursion + +|-- +-- Mutual recursion +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 231 +CREATE TABLE rec2 (a integer, b integer) +-- +TABLE: name="rec2" schema="" table="rec2" ctx=DDL +STMT: CreateStmt +== 232 +ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2 WHERE b = y)) +-- +STMT: AlterPolicyStmt +== 233 +CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1 WHERE y = b)) +-- +STMT: CreatePolicyStmt +== 234 +ALTER TABLE rec2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="rec2" schema="" table="rec2" ctx=DDL +STMT: AlterTableStmt +== 235 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 236 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +== 237 +-- fail, mutual recursion + +|-- +-- Mutual recursion via views +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 238 +CREATE VIEW rec1v AS SELECT * FROM rec1 +-- +TABLE: name="rec1v" schema="" table="rec1v" ctx=DDL +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 239 +CREATE VIEW rec2v AS SELECT * FROM rec2 +-- +TABLE: name="rec2v" schema="" table="rec2v" ctx=DDL +TABLE: name="rec2" schema="" table="rec2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 240 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 241 +ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y)) +-- +STMT: AlterPolicyStmt +== 242 +ALTER POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b)) +-- +STMT: AlterPolicyStmt +== 243 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 244 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +== 245 +-- fail, mutual recursion via views + +|-- +-- Mutual recursion via .s.b views +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 246 +DROP VIEW rec1v, rec2v CASCADE +-- +STMT: DropStmt +== 247 +CREATE VIEW rec1v WITH (security_barrier) AS SELECT * FROM rec1 +-- +TABLE: name="rec1v" schema="" table="rec1v" ctx=DDL +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 248 +CREATE VIEW rec2v WITH (security_barrier) AS SELECT * FROM rec2 +-- +TABLE: name="rec2v" schema="" table="rec2v" ctx=DDL +TABLE: name="rec2" schema="" table="rec2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 249 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 250 +CREATE POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y)) +-- +STMT: CreatePolicyStmt +== 251 +CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b)) +-- +STMT: CreatePolicyStmt +== 252 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 253 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +== 254 +-- fail, mutual recursion via s.b. views + +|-- +-- recursive RLS and VIEWs in policy +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 255 +CREATE TABLE s1 (a int, b text) +-- +TABLE: name="s1" schema="" table="s1" ctx=DDL +STMT: CreateStmt +== 256 +INSERT INTO s1 (SELECT x, public.fipshash(x::text) FROM generate_series(-10,10) x) +-- +TABLE: name="s1" schema="" table="s1" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 257 +CREATE TABLE s2 (x int, y text) +-- +TABLE: name="s2" schema="" table="s2" ctx=DDL +STMT: CreateStmt +== 258 +INSERT INTO s2 (SELECT x, public.fipshash(x::text) FROM generate_series(-6,6) x) +-- +TABLE: name="s2" schema="" table="s2" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 259 +GRANT SELECT ON s1, s2 TO regress_rls_bob +-- +TABLE: name="s1" schema="" table="s1" ctx=DDL +TABLE: name="s2" schema="" table="s2" ctx=DDL +STMT: GrantStmt +== 260 +CREATE POLICY p1 ON s1 USING (a in (select x from s2 where y like '%2f%')) +-- +STMT: CreatePolicyStmt +== 261 +CREATE POLICY p2 ON s2 USING (x in (select a from s1 where b like '%22%')) +-- +STMT: CreatePolicyStmt +== 262 +CREATE POLICY p3 ON s1 FOR INSERT WITH CHECK (a = (SELECT a FROM s1)) +-- +STMT: CreatePolicyStmt +== 263 +ALTER TABLE s1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="s1" schema="" table="s1" ctx=DDL +STMT: AlterTableStmt +== 264 +ALTER TABLE s2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="s2" schema="" table="s2" ctx=DDL +STMT: AlterTableStmt +== 265 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 266 +CREATE VIEW v2 AS SELECT * FROM s2 WHERE y like '%af%' +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="s2" schema="" table="s2" ctx=Select +FILTER: schema="" table="" column="y" +STMT: ViewStmt +STMT: SelectStmt +== 267 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 268 +-- fail (infinite recursion) + +INSERT INTO s1 VALUES (1, 'foo') +-- +TABLE: name="s1" schema="" table="s1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 269 +-- fail (infinite recursion) + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 270 +DROP POLICY p3 on s1 +-- +STMT: DropStmt +== 271 +ALTER POLICY p2 ON s2 USING (x % 2 = 0) +-- +STMT: AlterPolicyStmt +== 272 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 273 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 274 +-- OK +EXPLAIN (COSTS OFF) SELECT * FROM only s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 275 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 276 +ALTER POLICY p1 ON s1 USING (a in (select x from v2)) +-- +STMT: AlterPolicyStmt +== 277 +-- using VIEW in RLS policy +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 278 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 279 +-- OK +EXPLAIN (COSTS OFF) SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 280 +SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%' +-- +TABLE: name="s2" schema="" table="s2" ctx=Select +TABLE: name="s1" schema="" table="s1" ctx=Select +FILTER: schema="" table="" column="y" +STMT: SelectStmt +== 281 +EXPLAIN (COSTS OFF) SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%' +-- +TABLE: name="s2" schema="" table="s2" ctx=Select +TABLE: name="s1" schema="" table="s1" ctx=Select +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 282 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 283 +ALTER POLICY p2 ON s2 USING (x in (select a from s1 where b like '%d2%')) +-- +STMT: AlterPolicyStmt +== 284 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 285 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 286 +-- fail (infinite recursion via view) + +-- prepared statement with regress_rls_alice privilege +PREPARE p1(int) AS SELECT * FROM t1 WHERE a <= $1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +== 287 +EXECUTE p1(2) +-- +STMT: ExecuteStmt +== 288 +EXPLAIN (COSTS OFF) EXECUTE p1(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 289 +-- superuser is allowed to bypass RLS checks +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 290 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 291 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 292 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 293 +-- plan cache should be invalidated +EXECUTE p1(2) +-- +STMT: ExecuteStmt +== 294 +EXPLAIN (COSTS OFF) EXECUTE p1(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 295 +PREPARE p2(int) AS SELECT * FROM t1 WHERE a = $1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +== 296 +EXECUTE p2(2) +-- +STMT: ExecuteStmt +== 297 +EXPLAIN (COSTS OFF) EXECUTE p2(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 298 +-- also, case when privilege switch from superuser +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 299 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 300 +EXECUTE p2(2) +-- +STMT: ExecuteStmt +== 301 +EXPLAIN (COSTS OFF) EXECUTE p2(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 302 +|-- +-- UPDATE / DELETE and Row-level security +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 303 +EXPLAIN (COSTS OFF) UPDATE t1 SET b = b || b WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 304 +UPDATE t1 SET b = b || b WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 305 +EXPLAIN (COSTS OFF) UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 306 +UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 307 +-- returning clause with system column +UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 308 +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING * +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 309 +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 310 +-- updates with from clause +EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t3 +WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t3" schema="" table="t3" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 311 +UPDATE t2 SET b=t2.b FROM t3 +WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t3" schema="" table="t3" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 312 +EXPLAIN (COSTS OFF) UPDATE t1 SET b=t1.b FROM t2 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 313 +UPDATE t1 SET b=t1.b FROM t2 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 314 +EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t1 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 315 +UPDATE t2 SET b=t2.b FROM t1 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 316 +-- updates with from clause self join +EXPLAIN (COSTS OFF) UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 +WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b +AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "t2_1"="t2" +ALIAS: "t2_2"="t2" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 317 +UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 +WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b +AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "t2_1"="t2" +ALIAS: "t2_2"="t2" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 318 +EXPLAIN (COSTS OFF) UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 +WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b +AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "t1_1"="t1" +ALIAS: "t1_2"="t1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 319 +UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 +WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b +AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "t1_1"="t1" +ALIAS: "t1_2"="t1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 320 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 321 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 322 +SELECT * FROM t1 ORDER BY a,b +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 323 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 324 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 325 +EXPLAIN (COSTS OFF) DELETE FROM only t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +== 326 +EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +== 327 +DELETE FROM only t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +== 328 +DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +== 329 +|-- +-- S.b. view on top of Row-level security +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 330 +CREATE TABLE b1 (a int, b text) +-- +TABLE: name="b1" schema="" table="b1" ctx=DDL +STMT: CreateStmt +== 331 +INSERT INTO b1 (SELECT x, public.fipshash(x::text) FROM generate_series(-10,10) x) +-- +TABLE: name="b1" schema="" table="b1" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 332 +CREATE POLICY p1 ON b1 USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 333 +ALTER TABLE b1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="b1" schema="" table="b1" ctx=DDL +STMT: AlterTableStmt +== 334 +GRANT ALL ON b1 TO regress_rls_bob +-- +TABLE: name="b1" schema="" table="b1" ctx=DDL +STMT: GrantStmt +== 335 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 336 +CREATE VIEW bv1 WITH (security_barrier) AS SELECT * FROM b1 WHERE a > 0 WITH CHECK OPTION +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DDL +TABLE: name="b1" schema="" table="b1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 337 +GRANT ALL ON bv1 TO regress_rls_carol +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DDL +STMT: GrantStmt +== 338 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 339 +EXPLAIN (COSTS OFF) SELECT * FROM bv1 WHERE f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 340 +SELECT * FROM bv1 WHERE f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 341 +INSERT INTO bv1 VALUES (-1, 'xxx') +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 342 +-- should fail view WCO +INSERT INTO bv1 VALUES (11, 'xxx') +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 343 +-- should fail RLS check +INSERT INTO bv1 VALUES (12, 'xxx') +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 344 +-- ok + +EXPLAIN (COSTS OFF) UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 345 +UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 346 +EXPLAIN (COSTS OFF) DELETE FROM bv1 WHERE a = 6 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +== 347 +DELETE FROM bv1 WHERE a = 6 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +== 348 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 349 +SELECT * FROM b1 +-- +TABLE: name="b1" schema="" table="b1" ctx=Select +STMT: SelectStmt +== 350 +|-- +-- INSERT ... ON CONFLICT DO UPDATE and Row-level security +|-- + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 351 +DROP POLICY p1 ON document +-- +STMT: DropStmt +== 352 +DROP POLICY p1r ON document +-- +STMT: DropStmt +== 353 +CREATE POLICY p1 ON document FOR SELECT USING (true) +-- +STMT: CreatePolicyStmt +== 354 +CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +== 355 +CREATE POLICY p3 ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +== 356 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 357 +-- Exists... +SELECT * FROM document WHERE did = 2 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +== 358 +-- ...so violates actual WITH CHECK OPTION within UPDATE (not INSERT, since +-- alternative UPDATE path happens to be taken): +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_carol', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, dauthor = EXCLUDED.dauthor +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 359 +-- Violates USING qual for UPDATE policy p3. +|-- +-- UPDATE path is taken, but UPDATE fails purely because *existing* row to be +-- updated is not a "novel"/cid 11 (row is not leaked, even though we have +-- SELECT privileges sufficient to see the row in this instance): +INSERT INTO document VALUES (33, 22, 1, 'regress_rls_bob', 'okay science fiction') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +-- preparation for next statement +INSERT INTO document VALUES (33, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'Some novel, replaces sci-fi') -- takes UPDATE path + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 361 +-- Fine (we UPDATE, since INSERT WCOs and UPDATE security barrier quals + WCOs +-- not violated): +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 362 +-- Fine (we INSERT, so "cid = 33" ("technology") isn't evaluated): +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 363 +-- Fine (same query, but we UPDATE, so "cid = 33", ("technology") is not the +-- case in respect of *existing* tuple): +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 364 +-- Same query a third time, but now fails due to existing tuple finally not +-- passing quals: +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 365 +-- Don't fail just because INSERT doesn't satisfy WITH CHECK option that +-- originated as a barrier/USING() qual from the UPDATE. Note that the UPDATE +-- path *isn't* taken, and so UPDATE-related policy does not apply: +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 366 +-- But this time, the same statement fails, because the UPDATE path is taken, +-- and updating the row just inserted falls afoul of security barrier qual +-- (enforced as WCO) -- what we might have updated target tuple to is +-- irrelevant, in fact. +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 367 +-- Test default USING qual enforced as WCO +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 368 +DROP POLICY p1 ON document +-- +STMT: DropStmt +== 369 +DROP POLICY p2 ON document +-- +STMT: DropStmt +== 370 +DROP POLICY p3 ON document +-- +STMT: DropStmt +== 371 +CREATE POLICY p3_with_default ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) +-- +STMT: CreatePolicyStmt +== 372 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 373 +-- Just because WCO-style enforcement of USING quals occurs with +-- existing/target tuple does not mean that the implementation can be allowed +-- to fail to also enforce this qual against the final tuple appended to +-- relation (since in the absence of an explicit WCO, this is also interpreted +-- as an UPDATE/ALL WCO in general). +|-- +-- UPDATE path is taken here (fails due to existing tuple). Note that this is +-- not reported as a "USING expression", because it's an RLS UPDATE check that originated as +-- a USING qual for the purposes of RLS in general, as opposed to an explicit +-- USING qual that is ordinarily a security barrier. We leave it up to the +-- UPDATE to make this fail: +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 374 +-- UPDATE path is taken here. Existing tuple passes, since its cid +-- corresponds to "novel", but default USING qual is enforced against +-- post-UPDATE tuple too (as always when updating with a policy that lacks an +-- explicit WCO), and so this fails: +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET cid = EXCLUDED.cid, dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 375 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 376 +DROP POLICY p3_with_default ON document +-- +STMT: DropStmt +== 377 +|-- +-- Test ALL policies with ON CONFLICT DO UPDATE (much the same as existing UPDATE +-- tests) +|-- +CREATE POLICY p3_with_all ON document FOR ALL + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +== 378 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 379 +-- Fails, since ALL WCO is enforced in insert path: +INSERT INTO document VALUES (80, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_carol', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 380 +-- Fails, since ALL policy USING qual is enforced (existing, target tuple is in +-- violation, since it has the "manga" cid): +INSERT INTO document VALUES (4, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 381 +-- Fails, since ALL WCO are enforced: +INSERT INTO document VALUES (1, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dauthor = 'regress_rls_carol' +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +== 382 +|-- +-- MERGE +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 383 +DROP POLICY p3_with_all ON document +-- +STMT: DropStmt +== 384 +ALTER TABLE document ADD COLUMN dnotes text DEFAULT '' +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: AlterTableStmt +== 385 +-- all documents are readable +CREATE POLICY p1 ON document FOR SELECT USING (true) +-- +STMT: CreatePolicyStmt +== 386 +-- one may insert documents only authored by them +CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +== 387 +-- one may only update documents in 'novel' category and new dlevel must be > 0 +CREATE POLICY p3 ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dlevel > 0) +-- +STMT: CreatePolicyStmt +== 388 +-- one may only delete documents in 'manga' category +CREATE POLICY p4 ON document FOR DELETE + USING (cid = (SELECT cid from category WHERE cname = 'manga')) +-- +STMT: CreatePolicyStmt +== 389 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +== 390 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 391 +-- Fails, since update violates WITH CHECK qual on dlevel +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge1 ', dlevel = 0 +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 392 +-- Should be OK since USING and WITH CHECK quals pass +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge2 ' +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 393 +-- Even when dlevel is updated explicitly, but to the existing value +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge3 ', dlevel = 1 +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 394 +-- There is a MATCH for did = 3, but UPDATE's USING qual does not allow +-- updating an item in category 'science fiction' +MERGE INTO document d +USING (SELECT 3 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 395 +-- The same thing with DELETE action, but fails again because no permissions +-- to delete items in 'science fiction' category that did 3 belongs to. +MERGE INTO document d +USING (SELECT 3 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 396 +-- Document with did 4 belongs to 'manga' category which is allowed for +-- deletion. But this fails because the UPDATE action is matched first and +-- UPDATE policy does not allow updation in the category. +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes = '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 397 +-- UPDATE action is not matched this time because of the WHEN qual. +-- DELETE still fails because role regress_rls_bob does not have SELECT +-- privileges on 'manga' category row in the category table. +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes <> '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 398 +-- OK if DELETE is replaced with DO NOTHING +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes <> '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 399 +SELECT * FROM document WHERE did = 4 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +== 400 +-- Switch to regress_rls_carol role and try the DELETE again. It should succeed +-- this time +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 401 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 402 +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes <> '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 403 +-- Switch back to regress_rls_bob role +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 404 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 405 +-- Try INSERT action. This fails because we are trying to insert +-- dauthor = regress_rls_dave and INSERT's WITH CHECK does not allow +-- that +MERGE INTO document d +USING (SELECT 12 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + DELETE +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_dave', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 406 +-- This should be fine +MERGE INTO document d +USING (SELECT 12 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + DELETE +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 407 +-- ok +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge4 ' +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 408 +-- drop and create a new SELECT policy which prevents us from reading +-- any document except with category 'novel' +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 409 +DROP POLICY p1 ON document +-- +STMT: DropStmt +== 410 +CREATE POLICY p1 ON document FOR SELECT + USING (cid = (SELECT cid from category WHERE cname = 'novel')) +-- +STMT: CreatePolicyStmt +== 411 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 412 +-- MERGE can no longer see the matching row and hence attempts the +-- NOT MATCHED action, which results in unique key violation +MERGE INTO document d +USING (SELECT 7 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge5 ' +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 413 +-- UPDATE action fails if new row is not visible +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge6 ', + cid = (SELECT cid from category WHERE cname = 'technology') +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "d"="document" +FILTER: schema="" table="" column="cname" +STMT: MergeStmt +STMT: SelectStmt +== 414 +-- but OK if new row is visible +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge7 ', + cid = (SELECT cid from category WHERE cname = 'novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "d"="document" +FILTER: schema="" table="" column="cname" +STMT: MergeStmt +STMT: SelectStmt +== 415 +-- OK to insert a new row that is not visible +MERGE INTO document d +USING (SELECT 13 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge8 ' +WHEN NOT MATCHED THEN + INSERT VALUES (13, 44, 1, 'regress_rls_bob', 'new manga') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 416 +SELECT * FROM document WHERE did = 13 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +== 417 +-- but not OK if RETURNING is used +MERGE INTO document d +USING (SELECT 14 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge9 ' +WHEN NOT MATCHED THEN + INSERT VALUES (14, 44, 1, 'regress_rls_bob', 'new manga') +RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 418 +-- but OK if new row is visible +MERGE INTO document d +USING (SELECT 14 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge10 ' +WHEN NOT MATCHED THEN + INSERT VALUES (14, 11, 1, 'regress_rls_bob', 'new novel') +RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +== 419 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 420 +-- drop the restrictive SELECT policy so that we can look at the +-- final state of the table +DROP POLICY p1 ON document +-- +STMT: DropStmt +== 421 +-- Just check everything went per plan +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +== 422 +|-- +-- ROLE/GROUP +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 423 +CREATE TABLE z1 (a int, b text) +-- +TABLE: name="z1" schema="" table="z1" ctx=DDL +STMT: CreateStmt +== 424 +CREATE TABLE z2 (a int, b text) +-- +TABLE: name="z2" schema="" table="z2" ctx=DDL +STMT: CreateStmt +== 425 +GRANT SELECT ON z1,z2 TO regress_rls_group1, regress_rls_group2, + regress_rls_bob, regress_rls_carol +-- +TABLE: name="z1" schema="" table="z1" ctx=DDL +TABLE: name="z2" schema="" table="z2" ctx=DDL +STMT: GrantStmt +== 426 +INSERT INTO z1 VALUES + (1, 'aba'), + (2, 'bbb'), + (3, 'ccc'), + (4, 'dad') +-- +TABLE: name="z1" schema="" table="z1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 427 +CREATE POLICY p1 ON z1 TO regress_rls_group1 USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 428 +CREATE POLICY p2 ON z1 TO regress_rls_group2 USING (a % 2 = 1) +-- +STMT: CreatePolicyStmt +== 429 +ALTER TABLE z1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="z1" schema="" table="z1" ctx=DDL +STMT: AlterTableStmt +== 430 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 431 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 432 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 433 +PREPARE plancache_test AS SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 434 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 435 +PREPARE plancache_test2 AS WITH q AS MATERIALIZED (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2 +-- +TABLE: name="z2" schema="" table="z2" ctx=Select +TABLE: name="z1" schema="" table="z1" ctx=Select +CTE: "q" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 436 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 437 +PREPARE plancache_test3 AS WITH q AS MATERIALIZED (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +TABLE: name="z2" schema="" table="z2" ctx=Select +CTE: "q" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="z1" column="b" +STMT: PrepareStmt +STMT: SelectStmt +== 438 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 439 +SET ROLE regress_rls_group1 +-- +STMT: VariableSetStmt +== 440 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 441 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 442 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 443 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 444 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 445 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 446 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 447 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 448 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 449 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 450 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 451 +SET ROLE regress_rls_group2 +-- +STMT: VariableSetStmt +== 452 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 453 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 454 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 455 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 456 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 457 +|-- +-- Views should follow policy for view owner. +|-- +-- View and Table owner are the same. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 458 +CREATE VIEW rls_view AS SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 459 +GRANT SELECT ON rls_view TO regress_rls_bob +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +== 460 +-- Query as role that is not owner of view or table. Should return all records. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 461 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 462 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 463 +-- Query as view/table owner. Should return all records. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 464 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 465 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 466 +DROP VIEW rls_view +-- +STMT: DropStmt +== 467 +-- View and Table owners are different. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 468 +CREATE VIEW rls_view AS SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 469 +GRANT SELECT ON rls_view TO regress_rls_alice +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +== 470 +-- Query as role that is not owner of view but is owner of table. +-- Should return records based on view owner policies. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 471 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 472 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 473 +-- Query as role that is not owner of table but is owner of view. +-- Should return records based on view owner policies. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 474 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 475 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 476 +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 477 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 478 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 479 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 480 +GRANT SELECT ON rls_view TO regress_rls_carol +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +== 481 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 482 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 483 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 484 +-- Policy requiring access to another table. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 485 +CREATE TABLE z1_blacklist (a int) +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: CreateStmt +== 486 +INSERT INTO z1_blacklist VALUES (3), (4) +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 487 +CREATE POLICY p3 ON z1 AS RESTRICTIVE USING (a NOT IN (SELECT a FROM z1_blacklist)) +-- +STMT: CreatePolicyStmt +== 488 +-- Query as role that is not owner of table but is owner of view without permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 489 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 490 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 491 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 492 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 493 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 494 +--fail - permission denied. + +-- Query as role that is not owner of table but is owner of view with permissions. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 495 +GRANT SELECT ON z1_blacklist TO regress_rls_bob +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +== 496 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 497 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 498 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 499 +-- Query as role that is not the owner of the table or view with permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 500 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 501 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 502 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 503 +REVOKE SELECT ON z1_blacklist FROM regress_rls_bob +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +== 504 +DROP POLICY p3 ON z1 +-- +STMT: DropStmt +== 505 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 506 +DROP VIEW rls_view +-- +STMT: DropStmt +== 507 +|-- +-- Security invoker views should follow policy for current user. +|-- +-- View and table owner are the same. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 508 +CREATE VIEW rls_view WITH (security_invoker) AS + SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 509 +GRANT SELECT ON rls_view TO regress_rls_bob +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +== 510 +GRANT SELECT ON rls_view TO regress_rls_carol +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +== 511 +-- Query as table owner. Should return all records. +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 512 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 513 +-- Queries as other users. +-- Should return records based on current user's policies. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 514 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 515 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 516 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 517 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 518 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 519 +-- View and table owners are different. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 520 +DROP VIEW rls_view +-- +STMT: DropStmt +== 521 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 522 +CREATE VIEW rls_view WITH (security_invoker) AS + SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 523 +GRANT SELECT ON rls_view TO regress_rls_alice +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +== 524 +GRANT SELECT ON rls_view TO regress_rls_carol +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +== 525 +-- Query as table owner. Should return all records. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 526 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 527 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 528 +-- Queries as other users. +-- Should return records based on current user's policies. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 529 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 530 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 531 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 532 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 533 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 534 +-- Policy requiring access to another table. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 535 +CREATE POLICY p3 ON z1 AS RESTRICTIVE USING (a NOT IN (SELECT a FROM z1_blacklist)) +-- +STMT: CreatePolicyStmt +== 536 +-- Query as role that is not owner of table but is owner of view without permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 537 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 538 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 539 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 540 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 541 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 542 +--fail - permission denied. + +-- Query as role that is not owner of table but is owner of view with permissions. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 543 +GRANT SELECT ON z1_blacklist TO regress_rls_bob +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +== 544 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 545 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 546 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 547 +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 548 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 549 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 550 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view with permissions. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 551 +GRANT SELECT ON z1_blacklist TO regress_rls_carol +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +== 552 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 553 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +== 554 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 555 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 556 +DROP VIEW rls_view +-- +STMT: DropStmt +== 557 +|-- +-- Command specific +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 558 +CREATE TABLE x1 (a int, b text, c text) +-- +TABLE: name="x1" schema="" table="x1" ctx=DDL +STMT: CreateStmt +== 559 +GRANT ALL ON x1 TO PUBLIC +-- +TABLE: name="x1" schema="" table="x1" ctx=DDL +STMT: GrantStmt +== 560 +INSERT INTO x1 VALUES + (1, 'abc', 'regress_rls_bob'), + (2, 'bcd', 'regress_rls_bob'), + (3, 'cde', 'regress_rls_carol'), + (4, 'def', 'regress_rls_carol'), + (5, 'efg', 'regress_rls_bob'), + (6, 'fgh', 'regress_rls_bob'), + (7, 'fgh', 'regress_rls_carol'), + (8, 'fgh', 'regress_rls_carol') +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 561 +CREATE POLICY p0 ON x1 FOR ALL USING (c = current_user) +-- +STMT: CreatePolicyStmt +== 562 +CREATE POLICY p1 ON x1 FOR SELECT USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 563 +CREATE POLICY p2 ON x1 FOR INSERT WITH CHECK (a % 2 = 1) +-- +STMT: CreatePolicyStmt +== 564 +CREATE POLICY p3 ON x1 FOR UPDATE USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 565 +CREATE POLICY p4 ON x1 FOR DELETE USING (a < 8) +-- +STMT: CreatePolicyStmt +== 566 +ALTER TABLE x1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="x1" schema="" table="x1" ctx=DDL +STMT: AlterTableStmt +== 567 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 568 +SELECT * FROM x1 WHERE f_leak(b) ORDER BY a ASC +-- +TABLE: name="x1" schema="" table="x1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 569 +UPDATE x1 SET b = b || '_updt' WHERE f_leak(b) RETURNING * +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 570 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 571 +SELECT * FROM x1 WHERE f_leak(b) ORDER BY a ASC +-- +TABLE: name="x1" schema="" table="x1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 572 +UPDATE x1 SET b = b || '_updt' WHERE f_leak(b) RETURNING * +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +== 573 +DELETE FROM x1 WHERE f_leak(b) RETURNING * +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +== 574 +|-- +-- Duplicate Policy Names +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 575 +CREATE TABLE y1 (a int, b text) +-- +TABLE: name="y1" schema="" table="y1" ctx=DDL +STMT: CreateStmt +== 576 +CREATE TABLE y2 (a int, b text) +-- +TABLE: name="y2" schema="" table="y2" ctx=DDL +STMT: CreateStmt +== 577 +GRANT ALL ON y1, y2 TO regress_rls_bob +-- +TABLE: name="y1" schema="" table="y1" ctx=DDL +TABLE: name="y2" schema="" table="y2" ctx=DDL +STMT: GrantStmt +== 578 +CREATE POLICY p1 ON y1 FOR ALL USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 579 +CREATE POLICY p2 ON y1 FOR SELECT USING (a > 2) +-- +STMT: CreatePolicyStmt +== 580 +CREATE POLICY p1 ON y1 FOR SELECT USING (a % 2 = 1) +-- +STMT: CreatePolicyStmt +== 581 +--fail +CREATE POLICY p1 ON y2 FOR ALL USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 582 +--OK + +ALTER TABLE y1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="y1" schema="" table="y1" ctx=DDL +STMT: AlterTableStmt +== 583 +ALTER TABLE y2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="y2" schema="" table="y2" ctx=DDL +STMT: AlterTableStmt +== 584 +|-- +-- Expression structure with SBV +|-- +-- Create view as table owner. RLS should NOT be applied. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 585 +CREATE VIEW rls_sbv WITH (security_barrier) AS + SELECT * FROM y1 WHERE f_leak(b) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=DDL +TABLE: name="y1" schema="" table="y1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 586 +EXPLAIN (COSTS OFF) SELECT * FROM rls_sbv WHERE (a = 1) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 587 +DROP VIEW rls_sbv +-- +STMT: DropStmt +== 588 +-- Create view as role that does not own table. RLS should be applied. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 589 +CREATE VIEW rls_sbv WITH (security_barrier) AS + SELECT * FROM y1 WHERE f_leak(b) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=DDL +TABLE: name="y1" schema="" table="y1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 590 +EXPLAIN (COSTS OFF) SELECT * FROM rls_sbv WHERE (a = 1) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 591 +DROP VIEW rls_sbv +-- +STMT: DropStmt +== 592 +|-- +-- Expression structure +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 593 +INSERT INTO y2 (SELECT x, public.fipshash(x::text) FROM generate_series(0,20) x) +-- +TABLE: name="y2" schema="" table="y2" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 594 +CREATE POLICY p2 ON y2 USING (a % 3 = 0) +-- +STMT: CreatePolicyStmt +== 595 +CREATE POLICY p3 ON y2 USING (a % 4 = 0) +-- +STMT: CreatePolicyStmt +== 596 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 597 +SELECT * FROM y2 WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 598 +EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 599 +|-- +-- Qual push-down of leaky functions, when not referring to table +|-- +SELECT * FROM y2 WHERE f_leak('abc') +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: SelectStmt +== 600 +EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak('abc') +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 601 +CREATE TABLE test_qual_pushdown ( + abc text +) +-- +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=DDL +STMT: CreateStmt +== 602 +INSERT INTO test_qual_pushdown VALUES ('abc'),('def') +-- +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 603 +SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="abc" +STMT: SelectStmt +== 604 +EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="abc" +STMT: ExplainStmt +STMT: SelectStmt +== 605 +SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 606 +EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 607 +DROP TABLE test_qual_pushdown +-- +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=DDL +STMT: DropStmt +== 608 +|-- +-- Plancache invalidate on user change. +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 609 +DROP TABLE t1 CASCADE +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 610 +CREATE TABLE t1 (a integer) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 611 +GRANT SELECT ON t1 TO regress_rls_bob, regress_rls_carol +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: GrantStmt +== 612 +CREATE POLICY p1 ON t1 TO regress_rls_bob USING ((a % 2) = 0) +-- +STMT: CreatePolicyStmt +== 613 +CREATE POLICY p2 ON t1 TO regress_rls_carol USING ((a % 4) = 0) +-- +STMT: CreatePolicyStmt +== 614 +ALTER TABLE t1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +== 615 +-- Prepare as regress_rls_bob +SET ROLE regress_rls_bob +-- +STMT: VariableSetStmt +== 616 +PREPARE role_inval AS SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +== 617 +-- Check plan +EXPLAIN (COSTS OFF) EXECUTE role_inval +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 618 +-- Change to regress_rls_carol +SET ROLE regress_rls_carol +-- +STMT: VariableSetStmt +== 619 +-- Check plan- should be different +EXPLAIN (COSTS OFF) EXECUTE role_inval +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 620 +-- Change back to regress_rls_bob +SET ROLE regress_rls_bob +-- +STMT: VariableSetStmt +== 621 +-- Check plan- should be back to original +EXPLAIN (COSTS OFF) EXECUTE role_inval +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 622 +|-- +-- CTE and RLS +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 623 +DROP TABLE t1 CASCADE +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 624 +CREATE TABLE t1 (a integer, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 625 +CREATE POLICY p1 ON t1 USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 626 +ALTER TABLE t1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +== 627 +GRANT ALL ON t1 TO regress_rls_bob +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: GrantStmt +== 628 +INSERT INTO t1 (SELECT x, public.fipshash(x::text) FROM generate_series(0,20) x) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 629 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 630 +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +CTE: "cte1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 631 +EXPLAIN (COSTS OFF) +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +CTE: "cte1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 632 +WITH cte1 AS (UPDATE t1 SET a = a + 1 RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: UpdateStmt +== 633 +--fail +WITH cte1 AS (UPDATE t1 SET a = a RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: UpdateStmt +== 634 +--ok + +WITH cte1 AS (INSERT INTO t1 VALUES (21, 'Fail') RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: InsertStmt +== 635 +--fail +WITH cte1 AS (INSERT INTO t1 VALUES (20, 'Success') RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: InsertStmt +== 636 +--ok + +|-- +-- Rename Policy +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 637 +ALTER POLICY p1 ON t1 RENAME TO p1 +-- +STMT: RenameStmt +== 638 +--fail + +SELECT polname, relname + FROM pg_policy pol + JOIN pg_class pc ON (pc.oid = pol.polrelid) + WHERE relname = 't1' +-- +TABLE: name="pg_policy" schema="" table="pg_policy" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pol"="pg_policy" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 639 +ALTER POLICY p1 ON t1 RENAME TO p2 +-- +STMT: RenameStmt +== 640 +--ok + +SELECT polname, relname + FROM pg_policy pol + JOIN pg_class pc ON (pc.oid = pol.polrelid) + WHERE relname = 't1' +-- +TABLE: name="pg_policy" schema="" table="pg_policy" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pol"="pg_policy" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 641 +|-- +-- Check INSERT SELECT +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 642 +CREATE TABLE t2 (a integer, b text) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 643 +INSERT INTO t2 (SELECT * FROM t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 644 +EXPLAIN (COSTS OFF) INSERT INTO t2 (SELECT * FROM t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 645 +SELECT * FROM t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 646 +EXPLAIN (COSTS OFF) SELECT * FROM t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 647 +CREATE TABLE t3 AS SELECT * FROM t1 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 648 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +== 649 +SELECT * INTO t4 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t4" schema="" table="t4" ctx=DDL +STMT: SelectStmt +== 650 +SELECT * FROM t4 +-- +TABLE: name="t4" schema="" table="t4" ctx=Select +STMT: SelectStmt +== 651 +|-- +-- RLS with JOIN +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 652 +CREATE TABLE blog (id integer, author text, post text) +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +STMT: CreateStmt +== 653 +CREATE TABLE comment (blog_id integer, message text) +-- +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: CreateStmt +== 654 +GRANT ALL ON blog, comment TO regress_rls_bob +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: GrantStmt +== 655 +CREATE POLICY blog_1 ON blog USING (id % 2 = 0) +-- +STMT: CreatePolicyStmt +== 656 +ALTER TABLE blog ENABLE ROW LEVEL SECURITY +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +STMT: AlterTableStmt +== 657 +INSERT INTO blog VALUES + (1, 'alice', 'blog #1'), + (2, 'bob', 'blog #1'), + (3, 'alice', 'blog #2'), + (4, 'alice', 'blog #3'), + (5, 'john', 'blog #1') +-- +TABLE: name="blog" schema="" table="blog" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 658 +INSERT INTO comment VALUES + (1, 'cool blog'), + (1, 'fun blog'), + (3, 'crazy blog'), + (5, 'what?'), + (4, 'insane!'), + (2, 'who did it?') +-- +TABLE: name="comment" schema="" table="comment" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 659 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 660 +-- Check RLS JOIN with Non-RLS. +SELECT id, author, message FROM blog JOIN comment ON id = blog_id +-- +TABLE: name="blog" schema="" table="blog" ctx=Select +TABLE: name="comment" schema="" table="comment" ctx=Select +STMT: SelectStmt +== 661 +-- Check Non-RLS JOIN with RLS. +SELECT id, author, message FROM comment JOIN blog ON id = blog_id +-- +TABLE: name="comment" schema="" table="comment" ctx=Select +TABLE: name="blog" schema="" table="blog" ctx=Select +STMT: SelectStmt +== 662 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 663 +CREATE POLICY comment_1 ON comment USING (blog_id < 4) +-- +STMT: CreatePolicyStmt +== 664 +ALTER TABLE comment ENABLE ROW LEVEL SECURITY +-- +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: AlterTableStmt +== 665 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 666 +-- Check RLS JOIN RLS +SELECT id, author, message FROM blog JOIN comment ON id = blog_id +-- +TABLE: name="blog" schema="" table="blog" ctx=Select +TABLE: name="comment" schema="" table="comment" ctx=Select +STMT: SelectStmt +== 667 +SELECT id, author, message FROM comment JOIN blog ON id = blog_id +-- +TABLE: name="comment" schema="" table="comment" ctx=Select +TABLE: name="blog" schema="" table="blog" ctx=Select +STMT: SelectStmt +== 668 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 669 +DROP TABLE blog, comment +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: DropStmt +== 670 +|-- +-- Default Deny Policy +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 671 +DROP POLICY p2 ON t1 +-- +STMT: DropStmt +== 672 +ALTER TABLE t1 OWNER TO regress_rls_alice +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +== 673 +-- Check that default deny does not apply to superuser. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 674 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 675 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 676 +-- Check that default deny does not apply to table owner. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +== 677 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 678 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 679 +-- Check that default deny applies to non-owner/non-superuser when RLS on. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 680 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 681 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 682 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 683 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 684 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 685 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 686 +|-- +-- COPY TO/FROM +|-- + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 687 +DROP TABLE copy_t CASCADE +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: DropStmt +== 688 +CREATE TABLE copy_t (a integer, b text) +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: CreateStmt +== 689 +CREATE POLICY p1 ON copy_t USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 690 +ALTER TABLE copy_t ENABLE ROW LEVEL SECURITY +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: AlterTableStmt +== 691 +GRANT ALL ON copy_t TO regress_rls_bob, regress_rls_exempt_user +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: GrantStmt +== 692 +INSERT INTO copy_t (SELECT x, public.fipshash(x::text) FROM generate_series(0,10) x) +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 693 +-- Check COPY TO as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 694 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 695 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 696 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 697 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 698 +-- Check COPY TO as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 699 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 700 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 701 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +== 702 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 703 +--ok + +-- Check COPY TO as user with permissions and BYPASSRLS +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +== 704 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 705 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 706 +--ok +SET row_security TO ON +-- +STMT: VariableSetStmt +== 707 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 708 +--ok + +-- Check COPY TO as user without permissions. SET row_security TO OFF; +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 709 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 710 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 711 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +== 712 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 713 +--fail - permission denied + +-- Check COPY relation TO; keep it just one row to avoid reordering issues +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 714 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 715 +CREATE TABLE copy_rel_to (a integer, b text) +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DDL +STMT: CreateStmt +== 716 +CREATE POLICY p1 ON copy_rel_to USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +== 717 +ALTER TABLE copy_rel_to ENABLE ROW LEVEL SECURITY +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DDL +STMT: AlterTableStmt +== 718 +GRANT ALL ON copy_rel_to TO regress_rls_bob, regress_rls_exempt_user +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DDL +STMT: GrantStmt +== 719 +INSERT INTO copy_rel_to VALUES (1, public.fipshash('1')) +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 720 +-- Check COPY TO as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 721 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 722 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 723 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 724 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 725 +-- Check COPY TO as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 726 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 727 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 728 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +== 729 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 730 +--ok + +-- Check COPY TO as user with permissions and BYPASSRLS +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +== 731 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 732 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 733 +--ok +SET row_security TO ON +-- +STMT: VariableSetStmt +== 734 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 735 +--ok + +-- Check COPY TO as user without permissions. SET row_security TO OFF; +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 736 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 737 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 738 +--fail - permission denied +SET row_security TO ON +-- +STMT: VariableSetStmt +== 739 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 740 +--fail - permission denied + +-- Check behavior with a child table. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 741 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 742 +CREATE TABLE copy_rel_to_child () INHERITS (copy_rel_to) +-- +TABLE: name="copy_rel_to_child" schema="" table="copy_rel_to_child" ctx=DDL +STMT: CreateStmt +== 743 +INSERT INTO copy_rel_to_child VALUES (1, 'one'), (2, 'two') +-- +TABLE: name="copy_rel_to_child" schema="" table="copy_rel_to_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 744 +-- Check COPY TO as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 745 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 746 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 747 +SET row_security TO ON +-- +STMT: VariableSetStmt +== 748 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 749 +-- Check COPY TO as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 750 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 751 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 752 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +== 753 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 754 +--ok + +-- Check COPY TO as user with permissions and BYPASSRLS +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +== 755 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 756 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 757 +--ok +SET row_security TO ON +-- +STMT: VariableSetStmt +== 758 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 759 +--ok + +-- Check COPY TO as user without permissions. SET row_security TO OFF; +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 760 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 761 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 762 +--fail - permission denied +SET row_security TO ON +-- +STMT: VariableSetStmt +== 763 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +== 764 +--fail - permission denied + +-- Check COPY FROM as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 765 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 766 +COPY copy_t FROM STDIN +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 767 +--ok +1 abc +2 bcd +3 cde +4 def +SET row_security TO ON +-- +ERROR: syntax error at or near "1" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 768 +-- Check COPY FROM as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +== 769 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 770 +COPY copy_t FROM STDIN +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 771 +--fail - would be affected by RLS. +SET row_security TO ON +-- +STMT: VariableSetStmt +== 772 +-- Check COPY FROM as user without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +== 773 +SET row_security TO OFF +-- +STMT: VariableSetStmt +== 774 +COPY copy_t FROM STDIN +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +== 775 +--fail - permission denied. +SET row_security TO ON +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/rowtypes.metadata.json b/parser/testdata/summary/postgres_regress/rowtypes.metadata.json new file mode 100644 index 0000000..e9da7a5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rowtypes.metadata.json @@ -0,0 +1,241 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237" + ] +} diff --git a/parser/testdata/summary/postgres_regress/rowtypes.test b/parser/testdata/summary/postgres_regress/rowtypes.test new file mode 100644 index 0000000..4c064f9 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rowtypes.test @@ -0,0 +1,1424 @@ +== 001 +|-- +-- ROWTYPES +|-- + +-- Make both a standalone composite type and a table rowtype + +create type complex as (r float8, i float8) +-- +STMT: CompositeTypeStmt +== 002 +create temp table fullname (first text, last text) +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: CreateStmt +== 003 +-- Nested composite + +create type quad as (c1 complex, c2 complex) +-- +STMT: CompositeTypeStmt +== 004 +-- Some simple tests of I/O conversions and row construction + +select (1.1,2.2)::complex, row((3.3,4.4),(5.5,null))::quad +-- +STMT: SelectStmt +== 005 +select row('Joe', 'Blow')::fullname, '(Joe,Blow)'::fullname +-- +STMT: SelectStmt +== 006 +select '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname +-- +STMT: SelectStmt +== 007 +select '(Joe,"von""Blow")'::fullname, E'(Joe,d\\\\Blow)'::fullname +-- +STMT: SelectStmt +== 008 +select '(Joe,"Blow,Jr")'::fullname +-- +STMT: SelectStmt +== 009 +select '(Joe,)'::fullname +-- +STMT: SelectStmt +== 010 +-- ok, null 2nd column +select '(Joe)'::fullname +-- +STMT: SelectStmt +== 011 +-- bad +select '(Joe,,)'::fullname +-- +STMT: SelectStmt +== 012 +-- bad +select '[]'::fullname +-- +STMT: SelectStmt +== 013 +-- bad +select ' (Joe,Blow) '::fullname +-- +STMT: SelectStmt +== 014 +-- ok, extra whitespace +select '(Joe,Blow) /'::fullname +-- +STMT: SelectStmt +== 015 +-- bad + +-- test non-error-throwing API +SELECT pg_input_is_valid('(1,2)', 'complex') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT pg_input_is_valid('(1,2', 'complex') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT pg_input_is_valid('(1,zed)', 'complex') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT * FROM pg_input_error_info('(1,zed)', 'complex') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 020 +create temp table quadtable(f1 int, q quad) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DDL +STMT: CreateStmt +== 021 +insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +insert into quadtable values (2, ((null,4.4),(5.5,6.6))) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +select * from quadtable +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +STMT: SelectStmt +== 024 +select f1, q.c1 from quadtable +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +STMT: SelectStmt +== 025 +-- fails, q is a table reference + +select f1, (q).c1, (qq.q).c1.i from quadtable qq +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +ALIAS: "qq"="quadtable" +STMT: SelectStmt +== 026 +create temp table people (fn fullname, bd date) +-- +TABLE: name="people" schema="" table="people" ctx=DDL +STMT: CreateStmt +== 027 +insert into people values ('(Joe,Blow)', '1984-01-10') +-- +TABLE: name="people" schema="" table="people" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +select * from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +STMT: SelectStmt +== 029 +-- at the moment this will not work due to ALTER TABLE inadequacy: +alter table fullname add column suffix text default '' +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: AlterTableStmt +== 030 +-- but this should work: +alter table fullname add column suffix text default null +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: AlterTableStmt +== 031 +select * from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +STMT: SelectStmt +== 032 +-- test insertion/updating of subfields +update people set fn.suffix = 'Jr' +-- +TABLE: name="people" schema="" table="people" ctx=DML +STMT: UpdateStmt +== 033 +select * from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +STMT: SelectStmt +== 034 +insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +update quadtable set q.c1.r = 12 where f1 = 2 +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: UpdateStmt +== 036 +update quadtable set q.c1 = 12 +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: UpdateStmt +== 037 +-- error, type mismatch + +select * from quadtable +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +STMT: SelectStmt +== 038 +-- The object here is to ensure that toasted references inside +-- composite values don't cause problems. The large f1 value will +-- be toasted inside pp, it must still work after being copied to people. + +create temp table pp (f1 text) +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +STMT: CreateStmt +== 039 +insert into pp values (repeat('abcdefghijkl', 100000)) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 040 +insert into people select ('Jim', f1, null)::fullname, current_date from pp +-- +TABLE: name="people" schema="" table="people" ctx=DML +TABLE: name="pp" schema="" table="pp" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 041 +select (fn).first, substr((fn).last, 1, 20), length((fn).last) from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- try an update on a toasted composite value, too +update people set fn.first = 'Jack' +-- +TABLE: name="people" schema="" table="people" ctx=DML +STMT: UpdateStmt +== 043 +select (fn).first, substr((fn).last, 1, 20), length((fn).last) from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 044 +-- Test row comparison semantics. Prior to PG 8.2 we did this in a totally +-- non-spec-compliant way. + +select ROW(1,2) < ROW(1,3) as true +-- +STMT: SelectStmt +== 045 +select ROW(1,2) < ROW(1,1) as false +-- +STMT: SelectStmt +== 046 +select ROW(1,2) < ROW(1,NULL) as null +-- +STMT: SelectStmt +== 047 +select ROW(1,2,3) < ROW(1,3,NULL) as true +-- +STMT: SelectStmt +== 048 +-- the NULL is not examined +select ROW(11,'ABC') < ROW(11,'DEF') as true +-- +STMT: SelectStmt +== 049 +select ROW(11,'ABC') > ROW(11,'DEF') as false +-- +STMT: SelectStmt +== 050 +select ROW(12,'ABC') > ROW(11,'DEF') as true +-- +STMT: SelectStmt +== 051 +-- = and <> have different NULL-behavior than < etc +select ROW(1,2,3) < ROW(1,NULL,4) as null +-- +STMT: SelectStmt +== 052 +select ROW(1,2,3) = ROW(1,NULL,4) as false +-- +STMT: SelectStmt +== 053 +select ROW(1,2,3) <> ROW(1,NULL,4) as true +-- +STMT: SelectStmt +== 054 +-- We allow operators beyond the six standard ones, if they have btree +-- operator classes. +select ROW('ABC','DEF') ~<=~ ROW('DEF','ABC') as true +-- +STMT: SelectStmt +== 055 +select ROW('ABC','DEF') ~>=~ ROW('DEF','ABC') as false +-- +STMT: SelectStmt +== 056 +select ROW('ABC','DEF') ~~ ROW('DEF','ABC') as fail +-- +STMT: SelectStmt +== 057 +-- Comparisons of ROW() expressions can cope with some type mismatches +select ROW(1,2) = ROW(1,2::int8) +-- +STMT: SelectStmt +== 058 +select ROW(1,2) in (ROW(3,4), ROW(1,2)) +-- +STMT: SelectStmt +== 059 +select ROW(1,2) in (ROW(3,4), ROW(1,2::int8)) +-- +STMT: SelectStmt +== 060 +-- Check row comparison with a subselect +select unique1, unique2 from tenk1 +where (unique1, unique2) < any (select ten, ten from tenk1 where hundred < 3) + and unique1 <= 20 +order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 061 +-- Also check row comparison with an indexable condition +explain (costs off) +select thousand, tenthous from tenk1 +where (thousand, tenthous) >= (997, 5000) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 062 +select thousand, tenthous from tenk1 +where (thousand, tenthous) >= (997, 5000) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 063 +explain (costs off) +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 064 +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="four" +STMT: SelectStmt +== 065 +explain (costs off) +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 066 +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 067 +explain (costs off) +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 068 +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 069 +-- Test case for bug #14010: indexed row comparisons fail with nulls +create temp table test_table (a text, b text) +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DDL +STMT: CreateStmt +== 070 +insert into test_table values ('a', 'b') +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +insert into test_table select 'a', null from generate_series(1,1000) +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 072 +insert into test_table values ('b', 'a') +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +create index on test_table (a,b) +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DDL +STMT: IndexStmt +== 074 +set enable_sort = off +-- +STMT: VariableSetStmt +== 075 +explain (costs off) +select a,b from test_table where (a,b) > ('a','a') order by a,b +-- +TABLE: name="test_table" schema="" table="test_table" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 076 +select a,b from test_table where (a,b) > ('a','a') order by a,b +-- +TABLE: name="test_table" schema="" table="test_table" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 077 +reset enable_sort +-- +STMT: VariableSetStmt +== 078 +-- Check row comparisons with IN +select * from int8_tbl i8 where i8 in (row(123,456)) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="" column="i8" +STMT: SelectStmt +== 079 +-- fail, type mismatch + +explain (costs off) +select * from int8_tbl i8 +where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="" column="i8" +STMT: ExplainStmt +STMT: SelectStmt +== 080 +select * from int8_tbl i8 +where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="" column="i8" +STMT: SelectStmt +== 081 +-- Check ability to select columns from an anonymous rowtype +select (row(1, 2.0)).f1 +-- +STMT: SelectStmt +== 082 +select (row(1, 2.0)).f2 +-- +STMT: SelectStmt +== 083 +select (row(1, 2.0)).nosuch +-- +STMT: SelectStmt +== 084 +-- fail +select (row(1, 2.0)).* +-- +STMT: SelectStmt +== 085 +select (r).f1 from (select row(1, 2.0) as r) ss +-- +STMT: SelectStmt +== 086 +select (r).f3 from (select row(1, 2.0) as r) ss +-- +STMT: SelectStmt +== 087 +-- fail +select (r).* from (select row(1, 2.0) as r) ss +-- +STMT: SelectStmt +== 088 +-- Check some corner cases involving empty rowtypes +select ROW() +-- +STMT: SelectStmt +== 089 +select ROW() IS NULL +-- +STMT: SelectStmt +== 090 +select ROW() = ROW() +-- +STMT: SelectStmt +== 091 +-- Check ability to create arrays of anonymous rowtypes +select array[ row(1,2), row(3,4), row(5,6) ] +-- +STMT: SelectStmt +== 092 +-- Check ability to compare an anonymous row to elements of an array +select row(1,1.1) = any (array[ row(7,7.7), row(1,1.1), row(0,0.0) ]) +-- +STMT: SelectStmt +== 093 +select row(1,1.1) = any (array[ row(7,7.7), row(1,1.0), row(0,0.0) ]) +-- +STMT: SelectStmt +== 094 +-- Check behavior with a non-comparable rowtype +create type cantcompare as (p point, r float8) +-- +STMT: CompositeTypeStmt +== 095 +create temp table cc (f1 cantcompare) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +== 096 +insert into cc values('("(1,2)",3)') +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +insert into cc values('("(4,5)",6)') +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +select * from cc order by f1 +-- +TABLE: name="cc" schema="" table="cc" ctx=Select +STMT: SelectStmt +== 099 +-- fail, but should complain about cantcompare + +|-- +-- Tests for record_{eq,cmp} +|-- + +create type testtype1 as (a int, b int) +-- +STMT: CompositeTypeStmt +== 100 +-- all true +select row(1, 2)::testtype1 < row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 101 +select row(1, 2)::testtype1 <= row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 102 +select row(1, 2)::testtype1 = row(1, 2)::testtype1 +-- +STMT: SelectStmt +== 103 +select row(1, 2)::testtype1 <> row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 104 +select row(1, 3)::testtype1 >= row(1, 2)::testtype1 +-- +STMT: SelectStmt +== 105 +select row(1, 3)::testtype1 > row(1, 2)::testtype1 +-- +STMT: SelectStmt +== 106 +-- all false +select row(1, -2)::testtype1 < row(1, -3)::testtype1 +-- +STMT: SelectStmt +== 107 +select row(1, -2)::testtype1 <= row(1, -3)::testtype1 +-- +STMT: SelectStmt +== 108 +select row(1, -2)::testtype1 = row(1, -3)::testtype1 +-- +STMT: SelectStmt +== 109 +select row(1, -2)::testtype1 <> row(1, -2)::testtype1 +-- +STMT: SelectStmt +== 110 +select row(1, -3)::testtype1 >= row(1, -2)::testtype1 +-- +STMT: SelectStmt +== 111 +select row(1, -3)::testtype1 > row(1, -2)::testtype1 +-- +STMT: SelectStmt +== 112 +-- true, but see *< below +select row(1, -2)::testtype1 < row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 113 +-- mismatches +create type testtype3 as (a int, b text) +-- +STMT: CompositeTypeStmt +== 114 +select row(1, 2)::testtype1 < row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +== 115 +select row(1, 2)::testtype1 <> row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +== 116 +create type testtype5 as (a int) +-- +STMT: CompositeTypeStmt +== 117 +select row(1, 2)::testtype1 < row(1)::testtype5 +-- +STMT: SelectStmt +== 118 +select row(1, 2)::testtype1 <> row(1)::testtype5 +-- +STMT: SelectStmt +== 119 +-- non-comparable types +create type testtype6 as (a int, b point) +-- +STMT: CompositeTypeStmt +== 120 +select row(1, '(1,2)')::testtype6 < row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +== 121 +select row(1, '(1,2)')::testtype6 <> row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +== 122 +drop type testtype1, testtype3, testtype5, testtype6 +-- +STMT: DropStmt +== 123 +|-- +-- Tests for record_image_{eq,cmp} +|-- + +create type testtype1 as (a int, b int) +-- +STMT: CompositeTypeStmt +== 124 +-- all true +select row(1, 2)::testtype1 *< row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 125 +select row(1, 2)::testtype1 *<= row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 126 +select row(1, 2)::testtype1 *= row(1, 2)::testtype1 +-- +STMT: SelectStmt +== 127 +select row(1, 2)::testtype1 *<> row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 128 +select row(1, 3)::testtype1 *>= row(1, 2)::testtype1 +-- +STMT: SelectStmt +== 129 +select row(1, 3)::testtype1 *> row(1, 2)::testtype1 +-- +STMT: SelectStmt +== 130 +-- all false +select row(1, -2)::testtype1 *< row(1, -3)::testtype1 +-- +STMT: SelectStmt +== 131 +select row(1, -2)::testtype1 *<= row(1, -3)::testtype1 +-- +STMT: SelectStmt +== 132 +select row(1, -2)::testtype1 *= row(1, -3)::testtype1 +-- +STMT: SelectStmt +== 133 +select row(1, -2)::testtype1 *<> row(1, -2)::testtype1 +-- +STMT: SelectStmt +== 134 +select row(1, -3)::testtype1 *>= row(1, -2)::testtype1 +-- +STMT: SelectStmt +== 135 +select row(1, -3)::testtype1 *> row(1, -2)::testtype1 +-- +STMT: SelectStmt +== 136 +-- This returns the "wrong" order because record_image_cmp works on +-- unsigned datums without knowing about the actual data type. +select row(1, -2)::testtype1 *< row(1, 3)::testtype1 +-- +STMT: SelectStmt +== 137 +-- other types +create type testtype2 as (a smallint, b bool) +-- +STMT: CompositeTypeStmt +== 138 +-- byval different sizes +select row(1, true)::testtype2 *< row(2, true)::testtype2 +-- +STMT: SelectStmt +== 139 +select row(-2, true)::testtype2 *< row(-1, true)::testtype2 +-- +STMT: SelectStmt +== 140 +select row(0, false)::testtype2 *< row(0, true)::testtype2 +-- +STMT: SelectStmt +== 141 +select row(0, false)::testtype2 *<> row(0, true)::testtype2 +-- +STMT: SelectStmt +== 142 +create type testtype3 as (a int, b text) +-- +STMT: CompositeTypeStmt +== 143 +-- variable length +select row(1, 'abc')::testtype3 *< row(1, 'abd')::testtype3 +-- +STMT: SelectStmt +== 144 +select row(1, 'abc')::testtype3 *< row(1, 'abcd')::testtype3 +-- +STMT: SelectStmt +== 145 +select row(1, 'abc')::testtype3 *> row(1, 'abd')::testtype3 +-- +STMT: SelectStmt +== 146 +select row(1, 'abc')::testtype3 *<> row(1, 'abd')::testtype3 +-- +STMT: SelectStmt +== 147 +create type testtype4 as (a int, b point) +-- +STMT: CompositeTypeStmt +== 148 +-- by ref, fixed length +select row(1, '(1,2)')::testtype4 *< row(1, '(1,3)')::testtype4 +-- +STMT: SelectStmt +== 149 +select row(1, '(1,2)')::testtype4 *<> row(1, '(1,3)')::testtype4 +-- +STMT: SelectStmt +== 150 +-- mismatches +select row(1, 2)::testtype1 *< row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +== 151 +select row(1, 2)::testtype1 *<> row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +== 152 +create type testtype5 as (a int) +-- +STMT: CompositeTypeStmt +== 153 +select row(1, 2)::testtype1 *< row(1)::testtype5 +-- +STMT: SelectStmt +== 154 +select row(1, 2)::testtype1 *<> row(1)::testtype5 +-- +STMT: SelectStmt +== 155 +-- non-comparable types +create type testtype6 as (a int, b point) +-- +STMT: CompositeTypeStmt +== 156 +select row(1, '(1,2)')::testtype6 *< row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +== 157 +select row(1, '(1,2)')::testtype6 *>= row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +== 158 +select row(1, '(1,2)')::testtype6 *<> row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +== 159 +-- anonymous rowtypes in coldeflists +select q.a, q.b = row(2), q.c = array[row(3)], q.d = row(row(4)) from + unnest(array[row(1, row(2), array[row(3)], row(row(4))), + row(2, row(3), array[row(4)], row(row(5)))]) + as q(a int, b record, c record[], d record) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 160 +drop type testtype1, testtype2, testtype3, testtype4, testtype5, testtype6 +-- +STMT: DropStmt +== 161 +|-- +-- Test case derived from bug #5716: check multiple uses of a rowtype result +|-- + +BEGIN +-- +STMT: TransactionStmt +== 162 +CREATE TABLE price ( + id SERIAL PRIMARY KEY, + active BOOLEAN NOT NULL, + price NUMERIC +) +-- +TABLE: name="price" schema="" table="price" ctx=DDL +STMT: CreateStmt +== 163 +CREATE TYPE price_input AS ( + id INTEGER, + price NUMERIC +) +-- +STMT: CompositeTypeStmt +== 164 +CREATE TYPE price_key AS ( + id INTEGER +) +-- +STMT: CompositeTypeStmt +== 165 +CREATE FUNCTION price_key_from_table(price) RETURNS price_key AS $$ + SELECT $1.id +$$ LANGUAGE SQL +-- +FUNCTION: name="price_key_from_table" function="price_key_from_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 166 +CREATE FUNCTION price_key_from_input(price_input) RETURNS price_key AS $$ + SELECT $1.id +$$ LANGUAGE SQL +-- +FUNCTION: name="price_key_from_input" function="price_key_from_input" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 167 +insert into price values (1,false,42), (10,false,100), (11,true,17.99) +-- +TABLE: name="price" schema="" table="price" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +UPDATE price + SET active = true, price = input_prices.price + FROM unnest(ARRAY[(10, 123.00), (11, 99.99)]::price_input[]) input_prices + WHERE price_key_from_table(price.*) = price_key_from_input(input_prices.*) +-- +TABLE: name="price" schema="" table="price" ctx=DML +FUNCTION: name="price_key_from_table" function="price_key_from_table" schema="" ctx=Call +FUNCTION: name="price_key_from_input" function="price_key_from_input" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: UpdateStmt +== 169 +select * from price +-- +TABLE: name="price" schema="" table="price" ctx=Select +STMT: SelectStmt +== 170 +rollback +-- +STMT: TransactionStmt +== 171 +|-- +-- Test case derived from bug #9085: check * qualification of composite +-- parameters for SQL functions +|-- + +create temp table compos (f1 int, f2 text) +-- +TABLE: name="compos" schema="" table="compos" ctx=DDL +STMT: CreateStmt +== 172 +create function fcompos1(v compos) returns void as $$ +insert into compos values (v); -- fail +$$ language sql +-- +FUNCTION: name="fcompos1" function="fcompos1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 173 +create function fcompos1(v compos) returns void as $$ +insert into compos values (v.*); +$$ language sql +-- +FUNCTION: name="fcompos1" function="fcompos1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 174 +create function fcompos2(v compos) returns void as $$ +select fcompos1(v); +$$ language sql +-- +FUNCTION: name="fcompos2" function="fcompos2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 175 +create function fcompos3(v compos) returns void as $$ +select fcompos1(fcompos3.v.*); +$$ language sql +-- +FUNCTION: name="fcompos3" function="fcompos3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 176 +select fcompos1(row(1,'one')) +-- +FUNCTION: name="fcompos1" function="fcompos1" schema="" ctx=Call +STMT: SelectStmt +== 177 +select fcompos2(row(2,'two')) +-- +FUNCTION: name="fcompos2" function="fcompos2" schema="" ctx=Call +STMT: SelectStmt +== 178 +select fcompos3(row(3,'three')) +-- +FUNCTION: name="fcompos3" function="fcompos3" schema="" ctx=Call +STMT: SelectStmt +== 179 +select * from compos +-- +TABLE: name="compos" schema="" table="compos" ctx=Select +STMT: SelectStmt +== 180 +|-- +-- We allow I/O conversion casts from composite types to strings to be +-- invoked via cast syntax, but not functional syntax. This is because +-- the latter is too prone to be invoked unintentionally. +|-- +select cast (fullname as text) from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +STMT: SelectStmt +== 181 +select fullname::text from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +STMT: SelectStmt +== 182 +select text(fullname) from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +FUNCTION: name="text" function="text" schema="" ctx=Call +STMT: SelectStmt +== 183 +-- error +select fullname.text from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +STMT: SelectStmt +== 184 +-- error +-- same, but RECORD instead of named composite type: +select cast (row('Jim', 'Beam') as text) +-- +STMT: SelectStmt +== 185 +select (row('Jim', 'Beam'))::text +-- +STMT: SelectStmt +== 186 +select text(row('Jim', 'Beam')) +-- +FUNCTION: name="text" function="text" schema="" ctx=Call +STMT: SelectStmt +== 187 +-- error +select (row('Jim', 'Beam')).text +-- +STMT: SelectStmt +== 188 +-- error + +|-- +-- Check the equivalence of functional and column notation +|-- +insert into fullname values ('Joe', 'Blow') +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +select f.last from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +STMT: SelectStmt +== 190 +select last(f) from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +FUNCTION: name="last" function="last" schema="" ctx=Call +STMT: SelectStmt +== 191 +create function longname(fullname) returns text language sql +as $$select $1.first || ' ' || $1.last$$ +-- +FUNCTION: name="longname" function="longname" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 192 +select f.longname from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +STMT: SelectStmt +== 193 +select longname(f) from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +FUNCTION: name="longname" function="longname" schema="" ctx=Call +STMT: SelectStmt +== 194 +-- Starting in v11, the notational form does matter if there's ambiguity +alter table fullname add column longname text +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: AlterTableStmt +== 195 +select f.longname from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +STMT: SelectStmt +== 196 +select longname(f) from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +FUNCTION: name="longname" function="longname" schema="" ctx=Call +STMT: SelectStmt +== 197 +|-- +-- Test that composite values are seen to have the correct column names +-- (bug #11210 and other reports) +|-- + +select row_to_json(i) from int8_tbl i +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 198 +-- since "i" is of type "int8_tbl", attaching aliases doesn't change anything: +select row_to_json(i) from int8_tbl i(x,y) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 199 +-- in these examples, we'll report the exposed column names of the subselect: +select row_to_json(ss) from + (select q1, q2 from int8_tbl) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 200 +select row_to_json(ss) from + (select q1, q2 from int8_tbl offset 0) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 201 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 202 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl offset 0) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 203 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl) as ss(x,y) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 204 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl offset 0) as ss(x,y) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 205 +explain (costs off) +select row_to_json(q) from + (select thousand, tenthous from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 206 +select row_to_json(q) from + (select thousand, tenthous from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 207 +select row_to_json(q) from + (select thousand as x, tenthous as y from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 208 +select row_to_json(q) from + (select thousand as x, tenthous as y from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q(a,b) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +== 209 +create temp table tt1 as select * from int8_tbl limit 2 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 210 +create temp table tt2 () inherits(tt1) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +== 211 +insert into tt2 values(0,0) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 212 +select row_to_json(r) from (select q2,q1 from tt1 offset 0) r +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 213 +-- check no-op rowtype conversions +create temp table tt3 () inherits(tt2) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +== 214 +insert into tt3 values(33,44) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +select row_to_json(tt3::tt2::tt1) from tt3 +-- +TABLE: name="tt3" schema="" table="tt3" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +== 216 +|-- +-- IS [NOT] NULL should not recurse into nested composites (bug #14235) +|-- + +explain (verbose, costs off) +select r, r is null as isnull, r is not null as isnotnull +from (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 217 +select r, r is null as isnull, r is not null as isnotnull +from (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b) +-- +STMT: SelectStmt +== 218 +explain (verbose, costs off) +with r(a,b) as materialized + (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) +select r, r is null as isnull, r is not null as isnotnull from r +-- +CTE: "r" +STMT: ExplainStmt +STMT: SelectStmt +== 219 +with r(a,b) as materialized + (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) +select r, r is null as isnull, r is not null as isnotnull from r +-- +CTE: "r" +STMT: SelectStmt +== 220 +|-- +-- Check parsing of indirect references to composite values (bug #18077) +|-- +explain (verbose, costs off) +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select * from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ExplainStmt +STMT: SelectStmt +== 221 +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select * from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: SelectStmt +== 222 +-- Also check deparsing of such cases +create view composite_v as +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select 1 as one from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null +-- +TABLE: name="composite_v" schema="" table="composite_v" ctx=DDL +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ViewStmt +STMT: SelectStmt +== 223 +select pg_get_viewdef('composite_v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 224 +drop view composite_v +-- +STMT: DropStmt +== 225 +|-- +-- Check cases where the composite comes from a proven-dummy rel (bug #18576) +|-- +explain (verbose, costs off) +select (ss.a).x, (ss.a).n from + (select information_schema._pg_expandarray(array[1,2]) AS a) ss +-- +FUNCTION: name="information_schema._pg_expandarray" function="_pg_expandarray" schema="information_schema" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 226 +explain (verbose, costs off) +select (ss.a).x, (ss.a).n from + (select information_schema._pg_expandarray(array[1,2]) AS a) ss +where false +-- +FUNCTION: name="information_schema._pg_expandarray" function="_pg_expandarray" schema="information_schema" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 227 +explain (verbose, costs off) +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select (c).f1 from cte2 as t +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ExplainStmt +STMT: SelectStmt +== 228 +explain (verbose, costs off) +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select (c).f1 from cte2 as t +where false +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ExplainStmt +STMT: SelectStmt +== 229 +|-- +-- Tests for component access / FieldSelect +|-- +CREATE TABLE compositetable(a text, b text) +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=DDL +STMT: CreateStmt +== 230 +INSERT INTO compositetable(a, b) VALUES('fa', 'fb') +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 231 +-- composite type columns can't directly be accessed (error) +SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=Select +STMT: SelectStmt +== 232 +-- but can be accessed with proper parens +SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=Select +STMT: SelectStmt +== 233 +-- system columns can't be accessed in composite types (error) +SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=Select +STMT: SelectStmt +== 234 +-- accessing non-existing column in NULL datum errors out +SELECT (NULL::compositetable).nonexistent +-- +STMT: SelectStmt +== 235 +-- existing column in a NULL composite yield NULL +SELECT (NULL::compositetable).a +-- +STMT: SelectStmt +== 236 +-- oids can't be accessed in composite types (error) +SELECT (NULL::compositetable).oid +-- +STMT: SelectStmt +== 237 +DROP TABLE compositetable +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/rules.metadata.json b/parser/testdata/summary/postgres_regress/rules.metadata.json new file mode 100644 index 0000000..75d8f0c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rules.metadata.json @@ -0,0 +1,624 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620" + ] +} diff --git a/parser/testdata/summary/postgres_regress/rules.test b/parser/testdata/summary/postgres_regress/rules.test new file mode 100644 index 0000000..8081287 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/rules.test @@ -0,0 +1,4008 @@ +== 001 +|-- +-- RULES +-- From Jan's original setup_ruletest.sql and run_ruletest.sql +-- - thomas 1998-09-13 +|-- + +|-- +-- Tables and rules for the view test +|-- +create table rtest_t1 (a int4, b int4) +-- +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=DDL +STMT: CreateStmt +== 002 +create table rtest_t2 (a int4, b int4) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DDL +STMT: CreateStmt +== 003 +create table rtest_t3 (a int4, b int4) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DDL +STMT: CreateStmt +== 004 +create view rtest_v1 as select * from rtest_t1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 005 +create rule rtest_v1_ins as on insert to rtest_v1 do instead + insert into rtest_t1 values (new.a, new.b) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +STMT: RuleStmt +== 006 +create rule rtest_v1_upd as on update to rtest_v1 do instead + update rtest_t1 set a = new.a, b = new.b + where a = old.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +STMT: RuleStmt +== 007 +create rule rtest_v1_del as on delete to rtest_v1 do instead + delete from rtest_t1 where a = old.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +STMT: RuleStmt +== 008 +-- Test comments +COMMENT ON RULE rtest_v1_bad ON rtest_v1 IS 'bad rule' +-- +STMT: CommentStmt +== 009 +COMMENT ON RULE rtest_v1_del ON rtest_v1 IS 'delete rule' +-- +STMT: CommentStmt +== 010 +COMMENT ON RULE rtest_v1_del ON rtest_v1 IS NULL +-- +STMT: CommentStmt +== 011 +|-- +-- Tables and rules for the constraint update/delete test +|-- +-- Note: +-- Now that we have multiple action rule support, we check +-- both possible syntaxes to define them (The last action +-- can but must not have a semicolon at the end). +|-- +create table rtest_system (sysname text, sysdesc text) +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DDL +STMT: CreateStmt +== 012 +create table rtest_interface (sysname text, ifname text) +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DDL +STMT: CreateStmt +== 013 +create table rtest_person (pname text, pdesc text) +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DDL +STMT: CreateStmt +== 014 +create table rtest_admin (pname text, sysname text) +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DDL +STMT: CreateStmt +== 015 +create rule rtest_sys_upd as on update to rtest_system do also ( + update rtest_interface set sysname = new.sysname + where sysname = old.sysname; + update rtest_admin set sysname = new.sysname + where sysname = old.sysname + ) +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DDL +STMT: RuleStmt +== 016 +create rule rtest_sys_del as on delete to rtest_system do also ( + delete from rtest_interface where sysname = old.sysname; + delete from rtest_admin where sysname = old.sysname; + ) +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DDL +STMT: RuleStmt +== 017 +create rule rtest_pers_upd as on update to rtest_person do also + update rtest_admin set pname = new.pname where pname = old.pname +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DDL +STMT: RuleStmt +== 018 +create rule rtest_pers_del as on delete to rtest_person do also + delete from rtest_admin where pname = old.pname +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DDL +STMT: RuleStmt +== 019 +|-- +-- Tables and rules for the logging test +|-- +create table rtest_emp (ename char(20), salary numeric) +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: CreateStmt +== 020 +create table rtest_emplog (ename char(20), who name, action char(10), newsal numeric, oldsal numeric) +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=DDL +STMT: CreateStmt +== 021 +create table rtest_empmass (ename char(20), salary numeric) +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DDL +STMT: CreateStmt +== 022 +create rule rtest_emp_ins as on insert to rtest_emp do + insert into rtest_emplog values (new.ename, current_user, + 'hired', new.salary, '0.00') +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: RuleStmt +== 023 +create rule rtest_emp_upd as on update to rtest_emp where new.salary != old.salary do + insert into rtest_emplog values (new.ename, current_user, + 'honored', new.salary, old.salary) +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: RuleStmt +== 024 +create rule rtest_emp_del as on delete to rtest_emp do + insert into rtest_emplog values (old.ename, current_user, + 'fired', '0.00', old.salary) +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: RuleStmt +== 025 +|-- +-- Tables and rules for the multiple cascaded qualified instead +-- rule test +|-- +create table rtest_t4 (a int4, b text) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DDL +STMT: CreateStmt +== 026 +create table rtest_t5 (a int4, b text) +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=DDL +STMT: CreateStmt +== 027 +create table rtest_t6 (a int4, b text) +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=DDL +STMT: CreateStmt +== 028 +create table rtest_t7 (a int4, b text) +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=DDL +STMT: CreateStmt +== 029 +create table rtest_t8 (a int4, b text) +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=DDL +STMT: CreateStmt +== 030 +create table rtest_t9 (a int4, b text) +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DDL +STMT: CreateStmt +== 031 +create rule rtest_t4_ins1 as on insert to rtest_t4 + where new.a >= 10 and new.a < 20 do instead + insert into rtest_t5 values (new.a, new.b) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DDL +STMT: RuleStmt +== 032 +create rule rtest_t4_ins2 as on insert to rtest_t4 + where new.a >= 20 and new.a < 30 do + insert into rtest_t6 values (new.a, new.b) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DDL +STMT: RuleStmt +== 033 +create rule rtest_t5_ins as on insert to rtest_t5 + where new.a > 15 do + insert into rtest_t7 values (new.a, new.b) +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=DDL +STMT: RuleStmt +== 034 +create rule rtest_t6_ins as on insert to rtest_t6 + where new.a > 25 do instead + insert into rtest_t8 values (new.a, new.b) +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=DDL +STMT: RuleStmt +== 035 +|-- +-- Tables and rules for the rule fire order test +|-- +-- As of PG 7.3, the rules should fire in order by name, regardless +-- of INSTEAD attributes or creation order. +|-- +create table rtest_order1 (a int4) +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: CreateStmt +== 036 +create table rtest_order2 (a int4, b int4, c text) +-- +TABLE: name="rtest_order2" schema="" table="rtest_order2" ctx=DDL +STMT: CreateStmt +== 037 +create sequence rtest_seq +-- +STMT: CreateSeqStmt +== 038 +create rule rtest_order_r3 as on insert to rtest_order1 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 3 - this should run 3rd') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +== 039 +create rule rtest_order_r4 as on insert to rtest_order1 + where a < 100 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 4 - this should run 4th') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +== 040 +create rule rtest_order_r2 as on insert to rtest_order1 do + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 2 - this should run 2nd') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +== 041 +create rule rtest_order_r1 as on insert to rtest_order1 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 1 - this should run 1st') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +== 042 +|-- +-- Tables and rules for the instead nothing test +|-- +create table rtest_nothn1 (a int4, b text) +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DDL +STMT: CreateStmt +== 043 +create table rtest_nothn2 (a int4, b text) +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DDL +STMT: CreateStmt +== 044 +create table rtest_nothn3 (a int4, b text) +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=DDL +STMT: CreateStmt +== 045 +create table rtest_nothn4 (a int4, b text) +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DDL +STMT: CreateStmt +== 046 +create rule rtest_nothn_r1 as on insert to rtest_nothn1 + where new.a >= 10 and new.a < 20 do instead nothing +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DDL +STMT: RuleStmt +== 047 +create rule rtest_nothn_r2 as on insert to rtest_nothn1 + where new.a >= 30 and new.a < 40 do instead nothing +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DDL +STMT: RuleStmt +== 048 +create rule rtest_nothn_r3 as on insert to rtest_nothn2 + where new.a >= 100 do instead + insert into rtest_nothn3 values (new.a, new.b) +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DDL +STMT: RuleStmt +== 049 +create rule rtest_nothn_r4 as on insert to rtest_nothn2 + do instead nothing +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DDL +STMT: RuleStmt +== 050 +|-- +-- Tests on a view that is select * of a table +-- and has insert/update/delete instead rules to +-- behave close like the real table. +|-- + +|-- +-- We need test date later +|-- +insert into rtest_t2 values (1, 21) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +insert into rtest_t2 values (2, 22) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +insert into rtest_t2 values (3, 23) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +insert into rtest_t3 values (1, 31) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +insert into rtest_t3 values (2, 32) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +insert into rtest_t3 values (3, 33) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +insert into rtest_t3 values (4, 34) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +insert into rtest_t3 values (5, 35) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +-- insert values +insert into rtest_v1 values (1, 11) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +insert into rtest_v1 values (2, 12) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 061 +-- delete with constant expression +delete from rtest_v1 where a = 1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +== 062 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 063 +insert into rtest_v1 values (1, 11) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +delete from rtest_v1 where b = 12 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +== 065 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 066 +insert into rtest_v1 values (2, 12) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +insert into rtest_v1 values (2, 13) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 068 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 069 +** Remember the delete rule on rtest_v1: It says +** DO INSTEAD DELETE FROM rtest_t1 WHERE a = old.a +** So this time both rows with a = 2 must get deleted +delete from rtest_v1 where b = 12 +-- +ERROR: syntax error at or near "**" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 070 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 071 +delete from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +== 072 +-- insert select +insert into rtest_v1 select * from rtest_t2 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 073 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 074 +delete from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +== 075 +-- same with swapped targetlist +insert into rtest_v1 (b, a) select b, a from rtest_t2 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 076 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 077 +-- now with only one target attribute +insert into rtest_v1 (a) select a from rtest_t3 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 078 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 079 +select * from rtest_v1 where b isnull +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 080 +-- let attribute a differ (must be done on rtest_t1 - see above) +update rtest_t1 set a = a + 10 where b isnull +-- +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=DML +STMT: UpdateStmt +== 081 +delete from rtest_v1 where b isnull +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +== 082 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 083 +-- now updates with constant expression +update rtest_v1 set b = 42 where a = 2 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: UpdateStmt +== 084 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 085 +update rtest_v1 set b = 99 where b = 42 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: UpdateStmt +== 086 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 087 +update rtest_v1 set b = 88 where b < 50 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: UpdateStmt +== 088 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 089 +delete from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +== 090 +insert into rtest_v1 select rtest_t2.a, rtest_t3.b + from rtest_t2, rtest_t3 + where rtest_t2.a = rtest_t3.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +FILTER: schema="" table="rtest_t2" column="a" +FILTER: schema="" table="rtest_t3" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 091 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 092 +-- updates in a mergejoin +update rtest_v1 set b = rtest_t2.b from rtest_t2 where rtest_v1.a = rtest_t2.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +STMT: UpdateStmt +== 093 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 094 +insert into rtest_v1 select * from rtest_t3 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 095 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 096 +update rtest_t1 set a = a + 10 where b > 30 +-- +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=DML +STMT: UpdateStmt +== 097 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 098 +update rtest_v1 set a = rtest_t3.a + 20 from rtest_t3 where rtest_v1.b = rtest_t3.b +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +STMT: UpdateStmt +== 099 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +== 100 +|-- +-- Test for constraint updates/deletes +|-- +insert into rtest_system values ('orion', 'Linux Jan Wieck') +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +insert into rtest_system values ('notjw', 'WinNT Jan Wieck (notebook)') +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 102 +insert into rtest_system values ('neptun', 'Fileserver') +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +insert into rtest_interface values ('orion', 'eth0') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +insert into rtest_interface values ('orion', 'eth1') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +insert into rtest_interface values ('notjw', 'eth0') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 106 +insert into rtest_interface values ('neptun', 'eth0') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +insert into rtest_person values ('jw', 'Jan Wieck') +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +insert into rtest_person values ('bm', 'Bruce Momjian') +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +insert into rtest_admin values ('jw', 'orion') +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +insert into rtest_admin values ('jw', 'notjw') +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +insert into rtest_admin values ('bm', 'neptun') +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +update rtest_system set sysname = 'pluto' where sysname = 'neptun' +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: UpdateStmt +== 113 +select * from rtest_interface +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=Select +STMT: SelectStmt +== 114 +select * from rtest_admin +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=Select +STMT: SelectStmt +== 115 +update rtest_person set pname = 'jwieck' where pdesc = 'Jan Wieck' +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DML +STMT: UpdateStmt +== 116 +-- Note: use ORDER BY here to ensure consistent output across all systems. +-- The above UPDATE affects two rows with equal keys, so they could be +-- updated in either order depending on the whim of the local qsort(). + +select * from rtest_admin order by pname, sysname +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=Select +STMT: SelectStmt +== 117 +delete from rtest_system where sysname = 'orion' +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: DeleteStmt +== 118 +select * from rtest_interface +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=Select +STMT: SelectStmt +== 119 +select * from rtest_admin +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=Select +STMT: SelectStmt +== 120 +|-- +-- Rule qualification test +|-- +insert into rtest_emp values ('wiecc', '5000.00') +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +insert into rtest_emp values ('gates', '80000.00') +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +update rtest_emp set ename = 'wiecx' where ename = 'wiecc' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: UpdateStmt +== 123 +update rtest_emp set ename = 'wieck', salary = '6000.00' where ename = 'wiecx' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: UpdateStmt +== 124 +update rtest_emp set salary = '7000.00' where ename = 'wieck' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: UpdateStmt +== 125 +delete from rtest_emp where ename = 'gates' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: DeleteStmt +== 126 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +== 127 +insert into rtest_empmass values ('meyer', '4000.00') +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 128 +insert into rtest_empmass values ('maier', '5000.00') +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +insert into rtest_empmass values ('mayr', '6000.00') +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 130 +insert into rtest_emp select * from rtest_empmass +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 131 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +== 132 +update rtest_empmass set salary = salary + '1000.00' +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: UpdateStmt +== 133 +update rtest_emp set salary = rtest_empmass.salary from rtest_empmass where rtest_emp.ename = rtest_empmass.ename +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=Select +STMT: UpdateStmt +== 134 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +== 135 +delete from rtest_emp using rtest_empmass where rtest_emp.ename = rtest_empmass.ename +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=Select +STMT: DeleteStmt +== 136 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +== 137 +|-- +-- Multiple cascaded qualified instead rule test +|-- +insert into rtest_t4 values (1, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 138 +insert into rtest_t4 values (2, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +insert into rtest_t4 values (10, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 140 +insert into rtest_t4 values (15, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +insert into rtest_t4 values (19, 'Record should go to rtest_t5 and t7') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +insert into rtest_t4 values (20, 'Record should go to rtest_t4 and t6') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +insert into rtest_t4 values (26, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +insert into rtest_t4 values (28, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 145 +insert into rtest_t4 values (30, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +insert into rtest_t4 values (40, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +== 148 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +== 149 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +== 150 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +== 151 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +== 152 +delete from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: DeleteStmt +== 153 +delete from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=DML +STMT: DeleteStmt +== 154 +delete from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=DML +STMT: DeleteStmt +== 155 +delete from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=DML +STMT: DeleteStmt +== 156 +delete from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=DML +STMT: DeleteStmt +== 157 +insert into rtest_t9 values (1, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 158 +insert into rtest_t9 values (2, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +insert into rtest_t9 values (10, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +insert into rtest_t9 values (15, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 161 +insert into rtest_t9 values (19, 'Record should go to rtest_t5 and t7') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 162 +insert into rtest_t9 values (20, 'Record should go to rtest_t4 and t6') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 163 +insert into rtest_t9 values (26, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +insert into rtest_t9 values (28, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 165 +insert into rtest_t9 values (30, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +insert into rtest_t9 values (40, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 167 +insert into rtest_t4 select * from rtest_t9 where a < 20 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 168 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +== 169 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +== 170 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +== 171 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +== 172 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +== 173 +insert into rtest_t4 select * from rtest_t9 where b ~ 'and t8' +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=Select +FILTER: schema="" table="" column="b" +STMT: InsertStmt +STMT: SelectStmt +== 174 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +== 175 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +== 176 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +== 177 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +== 178 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +== 179 +insert into rtest_t4 select a + 1, b from rtest_t9 where a in (20, 30, 40) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 180 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +== 181 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +== 182 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +== 183 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +== 184 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +== 185 +|-- +-- Check that the ordering of rules fired is correct +|-- +insert into rtest_order1 values (1) +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +select * from rtest_order2 +-- +TABLE: name="rtest_order2" schema="" table="rtest_order2" ctx=Select +STMT: SelectStmt +== 187 +|-- +-- Check if instead nothing w/without qualification works +|-- +insert into rtest_nothn1 values (1, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +insert into rtest_nothn1 values (2, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +insert into rtest_nothn1 values (10, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +insert into rtest_nothn1 values (19, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +insert into rtest_nothn1 values (20, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 192 +insert into rtest_nothn1 values (29, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +insert into rtest_nothn1 values (30, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 194 +insert into rtest_nothn1 values (39, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 195 +insert into rtest_nothn1 values (40, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +insert into rtest_nothn1 values (50, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 197 +insert into rtest_nothn1 values (60, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 198 +select * from rtest_nothn1 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=Select +STMT: SelectStmt +== 199 +insert into rtest_nothn2 values (10, 'too small') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 200 +insert into rtest_nothn2 values (50, 'too small') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +insert into rtest_nothn2 values (100, 'OK') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 202 +insert into rtest_nothn2 values (200, 'OK') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 203 +select * from rtest_nothn2 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=Select +STMT: SelectStmt +== 204 +select * from rtest_nothn3 +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=Select +STMT: SelectStmt +== 205 +delete from rtest_nothn1 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: DeleteStmt +== 206 +delete from rtest_nothn2 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: DeleteStmt +== 207 +delete from rtest_nothn3 +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=DML +STMT: DeleteStmt +== 208 +insert into rtest_nothn4 values (1, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 209 +insert into rtest_nothn4 values (2, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 210 +insert into rtest_nothn4 values (10, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 211 +insert into rtest_nothn4 values (19, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 212 +insert into rtest_nothn4 values (20, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 213 +insert into rtest_nothn4 values (29, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 214 +insert into rtest_nothn4 values (30, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +insert into rtest_nothn4 values (39, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +insert into rtest_nothn4 values (40, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 217 +insert into rtest_nothn4 values (50, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 218 +insert into rtest_nothn4 values (60, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 219 +insert into rtest_nothn1 select * from rtest_nothn4 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 220 +select * from rtest_nothn1 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=Select +STMT: SelectStmt +== 221 +delete from rtest_nothn4 +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: DeleteStmt +== 222 +insert into rtest_nothn4 values (10, 'too small') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 223 +insert into rtest_nothn4 values (50, 'too small') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 224 +insert into rtest_nothn4 values (100, 'OK') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 225 +insert into rtest_nothn4 values (200, 'OK') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 226 +insert into rtest_nothn2 select * from rtest_nothn4 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 227 +select * from rtest_nothn2 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=Select +STMT: SelectStmt +== 228 +select * from rtest_nothn3 +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=Select +STMT: SelectStmt +== 229 +create table rtest_view1 (a int4, b text, v bool) +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DDL +STMT: CreateStmt +== 230 +create table rtest_view2 (a int4) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DDL +STMT: CreateStmt +== 231 +create table rtest_view3 (a int4, b text) +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DDL +STMT: CreateStmt +== 232 +create table rtest_view4 (a int4, b text, c int4) +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DDL +STMT: CreateStmt +== 233 +create view rtest_vview1 as select a, b from rtest_view1 X + where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a) +-- +TABLE: name="rtest_vview1" schema="" table="rtest_vview1" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=Select +ALIAS: "x"="rtest_view1" +ALIAS: "y"="rtest_view2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="y" column="a" +FILTER: schema="" table="x" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 234 +create view rtest_vview2 as select a, b from rtest_view1 where v +-- +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +FILTER: schema="" table="" column="v" +STMT: ViewStmt +STMT: SelectStmt +== 235 +create view rtest_vview3 as select a, b from rtest_vview2 X + where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a) +-- +TABLE: name="rtest_vview3" schema="" table="rtest_vview3" ctx=DDL +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=Select +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=Select +ALIAS: "x"="rtest_vview2" +ALIAS: "y"="rtest_view2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="y" column="a" +FILTER: schema="" table="x" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 236 +create view rtest_vview4 as select X.a, X.b, count(Y.a) as refcount + from rtest_view1 X, rtest_view2 Y + where X.a = Y.a + group by X.a, X.b +-- +TABLE: name="rtest_vview4" schema="" table="rtest_vview4" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=Select +ALIAS: "x"="rtest_view1" +ALIAS: "y"="rtest_view2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 237 +create function rtest_viewfunc1(int4) returns int4 as + 'select count(*)::int4 from rtest_view2 where a = $1' + language sql +-- +FUNCTION: name="rtest_viewfunc1" function="rtest_viewfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 238 +create view rtest_vview5 as select a, b, rtest_viewfunc1(a) as refcount + from rtest_view1 +-- +TABLE: name="rtest_vview5" schema="" table="rtest_vview5" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +FUNCTION: name="rtest_viewfunc1" function="rtest_viewfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 239 +insert into rtest_view1 values (1, 'item 1', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +insert into rtest_view1 values (2, 'item 2', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 241 +insert into rtest_view1 values (3, 'item 3', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 242 +insert into rtest_view1 values (4, 'item 4', 'f') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 243 +insert into rtest_view1 values (5, 'item 5', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +insert into rtest_view1 values (6, 'item 6', 'f') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +insert into rtest_view1 values (7, 'item 7', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 246 +insert into rtest_view1 values (8, 'item 8', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 247 +insert into rtest_view2 values (2) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +insert into rtest_view2 values (2) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 249 +insert into rtest_view2 values (4) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 250 +insert into rtest_view2 values (5) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 251 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 252 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 255 +select * from rtest_vview1 +-- +TABLE: name="rtest_vview1" schema="" table="rtest_vview1" ctx=Select +STMT: SelectStmt +== 256 +select * from rtest_vview2 +-- +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=Select +STMT: SelectStmt +== 257 +select * from rtest_vview3 +-- +TABLE: name="rtest_vview3" schema="" table="rtest_vview3" ctx=Select +STMT: SelectStmt +== 258 +select * from rtest_vview4 order by a, b +-- +TABLE: name="rtest_vview4" schema="" table="rtest_vview4" ctx=Select +STMT: SelectStmt +== 259 +select * from rtest_vview5 +-- +TABLE: name="rtest_vview5" schema="" table="rtest_vview5" ctx=Select +STMT: SelectStmt +== 260 +insert into rtest_view3 select * from rtest_vview1 where a < 7 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +TABLE: name="rtest_vview1" schema="" table="rtest_vview1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 261 +select * from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=Select +STMT: SelectStmt +== 262 +delete from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +STMT: DeleteStmt +== 263 +insert into rtest_view3 select * from rtest_vview2 where a != 5 and b !~ '2' +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: InsertStmt +STMT: SelectStmt +== 264 +select * from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=Select +STMT: SelectStmt +== 265 +delete from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +STMT: DeleteStmt +== 266 +insert into rtest_view3 select * from rtest_vview3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +TABLE: name="rtest_vview3" schema="" table="rtest_vview3" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 267 +select * from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=Select +STMT: SelectStmt +== 268 +delete from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +STMT: DeleteStmt +== 269 +insert into rtest_view4 select * from rtest_vview4 where 3 > refcount +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +TABLE: name="rtest_vview4" schema="" table="rtest_vview4" ctx=Select +FILTER: schema="" table="" column="refcount" +STMT: InsertStmt +STMT: SelectStmt +== 270 +select * from rtest_view4 order by a, b +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=Select +STMT: SelectStmt +== 271 +delete from rtest_view4 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +STMT: DeleteStmt +== 272 +insert into rtest_view4 select * from rtest_vview5 where a > 2 and refcount = 0 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +TABLE: name="rtest_vview5" schema="" table="rtest_vview5" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="refcount" +STMT: InsertStmt +STMT: SelectStmt +== 273 +select * from rtest_view4 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=Select +STMT: SelectStmt +== 274 +delete from rtest_view4 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +STMT: DeleteStmt +== 275 +|-- +-- Test for computations in views +|-- +create table rtest_comp ( + part text, + unit char(4), + size float +) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DDL +STMT: CreateStmt +== 276 +create table rtest_unitfact ( + unit char(4), + factor float +) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DDL +STMT: CreateStmt +== 277 +create view rtest_vcomp as + select X.part, (X.size * Y.factor) as size_in_cm + from rtest_comp X, rtest_unitfact Y + where X.unit = Y.unit +-- +TABLE: name="rtest_vcomp" schema="" table="rtest_vcomp" ctx=DDL +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=Select +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=Select +ALIAS: "x"="rtest_comp" +ALIAS: "y"="rtest_unitfact" +FILTER: schema="" table="x" column="unit" +FILTER: schema="" table="y" column="unit" +STMT: ViewStmt +STMT: SelectStmt +== 278 +insert into rtest_unitfact values ('m', 100.0) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 279 +insert into rtest_unitfact values ('cm', 1.0) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 280 +insert into rtest_unitfact values ('inch', 2.54) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 281 +insert into rtest_comp values ('p1', 'm', 5.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 282 +insert into rtest_comp values ('p2', 'm', 3.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +insert into rtest_comp values ('p3', 'cm', 5.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 284 +insert into rtest_comp values ('p4', 'cm', 15.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 285 +insert into rtest_comp values ('p5', 'inch', 7.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 286 +insert into rtest_comp values ('p6', 'inch', 4.4) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 287 +select * from rtest_vcomp order by part +-- +TABLE: name="rtest_vcomp" schema="" table="rtest_vcomp" ctx=Select +STMT: SelectStmt +== 288 +select * from rtest_vcomp where size_in_cm > 10.0 order by size_in_cm using > +-- +TABLE: name="rtest_vcomp" schema="" table="rtest_vcomp" ctx=Select +FILTER: schema="" table="" column="size_in_cm" +STMT: SelectStmt +== 289 +|-- +-- In addition run the (slightly modified) queries from the +-- programmers manual section on the rule system. +|-- +CREATE TABLE shoe_data ( + shoename char(10), -- primary key + sh_avail integer, -- available # of pairs + slcolor char(10), -- preferred shoelace color + slminlen float, -- minimum shoelace length + slmaxlen float, -- maximum shoelace length + slunit char(8) -- length unit +) +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DDL +STMT: CreateStmt +== 290 +CREATE TABLE shoelace_data ( + sl_name char(10), -- primary key + sl_avail integer, -- available # of pairs + sl_color char(10), -- shoelace color + sl_len float, -- shoelace length + sl_unit char(8) -- length unit +) +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DDL +STMT: CreateStmt +== 291 +CREATE TABLE unit ( + un_name char(8), -- the primary key + un_fact float -- factor to transform to cm +) +-- +TABLE: name="unit" schema="" table="unit" ctx=DDL +STMT: CreateStmt +== 292 +CREATE VIEW shoe AS + SELECT sh.shoename, + sh.sh_avail, + sh.slcolor, + sh.slminlen, + sh.slminlen * un.un_fact AS slminlen_cm, + sh.slmaxlen, + sh.slmaxlen * un.un_fact AS slmaxlen_cm, + sh.slunit + FROM shoe_data sh, unit un + WHERE sh.slunit = un.un_name +-- +TABLE: name="shoe" schema="" table="shoe" ctx=DDL +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=Select +TABLE: name="unit" schema="" table="unit" ctx=Select +ALIAS: "sh"="shoe_data" +ALIAS: "un"="unit" +FILTER: schema="" table="sh" column="slunit" +FILTER: schema="" table="un" column="un_name" +STMT: ViewStmt +STMT: SelectStmt +== 293 +CREATE VIEW shoelace AS + SELECT s.sl_name, + s.sl_avail, + s.sl_color, + s.sl_len, + s.sl_unit, + s.sl_len * u.un_fact AS sl_len_cm + FROM shoelace_data s, unit u + WHERE s.sl_unit = u.un_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=Select +TABLE: name="unit" schema="" table="unit" ctx=Select +ALIAS: "s"="shoelace_data" +ALIAS: "u"="unit" +FILTER: schema="" table="s" column="sl_unit" +FILTER: schema="" table="u" column="un_name" +STMT: ViewStmt +STMT: SelectStmt +== 294 +CREATE VIEW shoe_ready AS + SELECT rsh.shoename, + rsh.sh_avail, + rsl.sl_name, + rsl.sl_avail, + int4smaller(rsh.sh_avail, rsl.sl_avail) AS total_avail + FROM shoe rsh, shoelace rsl + WHERE rsl.sl_color = rsh.slcolor + AND rsl.sl_len_cm >= rsh.slminlen_cm + AND rsl.sl_len_cm <= rsh.slmaxlen_cm +-- +TABLE: name="shoe_ready" schema="" table="shoe_ready" ctx=DDL +TABLE: name="shoe" schema="" table="shoe" ctx=Select +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +ALIAS: "rsh"="shoe" +ALIAS: "rsl"="shoelace" +FUNCTION: name="int4smaller" function="int4smaller" schema="" ctx=Call +FILTER: schema="" table="rsl" column="sl_color" +FILTER: schema="" table="rsh" column="slcolor" +FILTER: schema="" table="rsl" column="sl_len_cm" +FILTER: schema="" table="rsh" column="slminlen_cm" +FILTER: schema="" table="rsl" column="sl_len_cm" +FILTER: schema="" table="rsh" column="slmaxlen_cm" +STMT: ViewStmt +STMT: SelectStmt +== 295 +INSERT INTO unit VALUES ('cm', 1.0) +-- +TABLE: name="unit" schema="" table="unit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 296 +INSERT INTO unit VALUES ('m', 100.0) +-- +TABLE: name="unit" schema="" table="unit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 297 +INSERT INTO unit VALUES ('inch', 2.54) +-- +TABLE: name="unit" schema="" table="unit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 298 +INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 299 +INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 300 +INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 301 +INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 302 +INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 303 +INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 304 +INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 305 +INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 306 +INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 307 +INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 308 +INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 309 +INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 310 +-- SELECTs in doc +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +== 311 +SELECT * FROM shoe_ready WHERE total_avail >= 2 ORDER BY 1 +-- +TABLE: name="shoe_ready" schema="" table="shoe_ready" ctx=Select +FILTER: schema="" table="" column="total_avail" +STMT: SelectStmt +== 312 +CREATE TABLE shoelace_log ( + sl_name char(10), -- shoelace changed + sl_avail integer, -- new available value + log_who name, -- who did it + log_when timestamp -- when + ) +-- +TABLE: name="shoelace_log" schema="" table="shoelace_log" ctx=DDL +STMT: CreateStmt +== 313 +-- Want "log_who" to be CURRENT_USER, +-- but that is non-portable for the regression test +-- - thomas 1999-02-21 + + CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data + WHERE NEW.sl_avail != OLD.sl_avail + DO INSERT INTO shoelace_log VALUES ( + NEW.sl_name, + NEW.sl_avail, + 'Al Bundy', + 'epoch' + ) +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DDL +STMT: RuleStmt +== 314 +UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7' +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: UpdateStmt +== 315 +SELECT * FROM shoelace_log +-- +TABLE: name="shoelace_log" schema="" table="shoelace_log" ctx=Select +STMT: SelectStmt +== 316 +CREATE RULE shoelace_ins AS ON INSERT TO shoelace + DO INSTEAD + INSERT INTO shoelace_data VALUES ( + NEW.sl_name, + NEW.sl_avail, + NEW.sl_color, + NEW.sl_len, + NEW.sl_unit) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +STMT: RuleStmt +== 317 +CREATE RULE shoelace_upd AS ON UPDATE TO shoelace + DO INSTEAD + UPDATE shoelace_data SET + sl_name = NEW.sl_name, + sl_avail = NEW.sl_avail, + sl_color = NEW.sl_color, + sl_len = NEW.sl_len, + sl_unit = NEW.sl_unit + WHERE sl_name = OLD.sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +STMT: RuleStmt +== 318 +CREATE RULE shoelace_del AS ON DELETE TO shoelace + DO INSTEAD + DELETE FROM shoelace_data + WHERE sl_name = OLD.sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +STMT: RuleStmt +== 319 +CREATE TABLE shoelace_arrive ( + arr_name char(10), + arr_quant integer + ) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DDL +STMT: CreateStmt +== 320 +CREATE TABLE shoelace_ok ( + ok_name char(10), + ok_quant integer + ) +-- +TABLE: name="shoelace_ok" schema="" table="shoelace_ok" ctx=DDL +STMT: CreateStmt +== 321 +CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok + DO INSTEAD + UPDATE shoelace SET + sl_avail = sl_avail + NEW.ok_quant + WHERE sl_name = NEW.ok_name +-- +TABLE: name="shoelace_ok" schema="" table="shoelace_ok" ctx=DDL +STMT: RuleStmt +== 322 +INSERT INTO shoelace_arrive VALUES ('sl3', 10) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 323 +INSERT INTO shoelace_arrive VALUES ('sl6', 20) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 324 +INSERT INTO shoelace_arrive VALUES ('sl8', 20) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 325 +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +== 326 +insert into shoelace_ok select * from shoelace_arrive +-- +TABLE: name="shoelace_ok" schema="" table="shoelace_ok" ctx=DML +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 327 +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +== 328 +SELECT * FROM shoelace_log ORDER BY sl_name +-- +TABLE: name="shoelace_log" schema="" table="shoelace_log" ctx=Select +STMT: SelectStmt +== 329 +CREATE VIEW shoelace_obsolete AS + SELECT * FROM shoelace WHERE NOT EXISTS + (SELECT shoename FROM shoe WHERE slcolor = sl_color) +-- +TABLE: name="shoelace_obsolete" schema="" table="shoelace_obsolete" ctx=DDL +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +TABLE: name="shoe" schema="" table="shoe" ctx=Select +FILTER: schema="" table="" column="slcolor" +FILTER: schema="" table="" column="sl_color" +STMT: ViewStmt +STMT: SelectStmt +== 330 +CREATE VIEW shoelace_candelete AS + SELECT * FROM shoelace_obsolete WHERE sl_avail = 0 +-- +TABLE: name="shoelace_candelete" schema="" table="shoelace_candelete" ctx=DDL +TABLE: name="shoelace_obsolete" schema="" table="shoelace_obsolete" ctx=Select +FILTER: schema="" table="" column="sl_avail" +STMT: ViewStmt +STMT: SelectStmt +== 331 +insert into shoelace values ('sl9', 0, 'pink', 35.0, 'inch', 0.0) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 332 +insert into shoelace values ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 333 +-- Unsupported (even though a similar updatable view construct is) +insert into shoelace values ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0) + on conflict do nothing +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 334 +SELECT * FROM shoelace_obsolete ORDER BY sl_len_cm +-- +TABLE: name="shoelace_obsolete" schema="" table="shoelace_obsolete" ctx=Select +STMT: SelectStmt +== 335 +SELECT * FROM shoelace_candelete +-- +TABLE: name="shoelace_candelete" schema="" table="shoelace_candelete" ctx=Select +STMT: SelectStmt +== 336 +DELETE FROM shoelace WHERE EXISTS + (SELECT * FROM shoelace_candelete + WHERE sl_name = shoelace.sl_name) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +TABLE: name="shoelace_candelete" schema="" table="shoelace_candelete" ctx=Select +FILTER: schema="" table="" column="sl_name" +FILTER: schema="" table="shoelace" column="sl_name" +STMT: DeleteStmt +STMT: SelectStmt +== 337 +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +== 338 +SELECT * FROM shoe ORDER BY shoename +-- +TABLE: name="shoe" schema="" table="shoe" ctx=Select +STMT: SelectStmt +== 339 +SELECT count(*) FROM shoe +-- +TABLE: name="shoe" schema="" table="shoe" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 340 +|-- +-- Simple test of qualified ON INSERT ... this did not work in 7.0 ... +|-- +create table rules_foo (f1 int) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: CreateStmt +== 341 +create table rules_foo2 (f1 int) +-- +TABLE: name="rules_foo2" schema="" table="rules_foo2" ctx=DDL +STMT: CreateStmt +== 342 +create rule rules_foorule as on insert to rules_foo where f1 < 100 +do instead nothing +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: RuleStmt +== 343 +insert into rules_foo values(1) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 344 +insert into rules_foo values(1001) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 345 +select * from rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=Select +STMT: SelectStmt +== 346 +drop rule rules_foorule on rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: DropStmt +== 347 +-- this should fail because f1 is not exposed for unqualified reference: +create rule rules_foorule as on insert to rules_foo where f1 < 100 +do instead insert into rules_foo2 values (f1) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: RuleStmt +== 348 +-- this is the correct way: +create rule rules_foorule as on insert to rules_foo where f1 < 100 +do instead insert into rules_foo2 values (new.f1) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: RuleStmt +== 349 +insert into rules_foo values(2) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 350 +insert into rules_foo values(100) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 351 +select * from rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=Select +STMT: SelectStmt +== 352 +select * from rules_foo2 +-- +TABLE: name="rules_foo2" schema="" table="rules_foo2" ctx=Select +STMT: SelectStmt +== 353 +drop rule rules_foorule on rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: DropStmt +== 354 +drop table rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: DropStmt +== 355 +drop table rules_foo2 +-- +TABLE: name="rules_foo2" schema="" table="rules_foo2" ctx=DDL +STMT: DropStmt +== 356 +|-- +-- Test rules containing INSERT ... SELECT, which is a very ugly special +-- case as of 7.1. Example is based on bug report from Joel Burton. +|-- +create table pparent (pid int, txt text) +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DDL +STMT: CreateStmt +== 357 +insert into pparent values (1,'parent1') +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 358 +insert into pparent values (2,'parent2') +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 359 +create table cchild (pid int, descrip text) +-- +TABLE: name="cchild" schema="" table="cchild" ctx=DDL +STMT: CreateStmt +== 360 +insert into cchild values (1,'descrip1') +-- +TABLE: name="cchild" schema="" table="cchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 361 +create view vview as + select pparent.pid, txt, descrip from + pparent left join cchild using (pid) +-- +TABLE: name="vview" schema="" table="vview" ctx=DDL +TABLE: name="pparent" schema="" table="pparent" ctx=Select +TABLE: name="cchild" schema="" table="cchild" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 362 +create rule rrule as + on update to vview do instead +( + insert into cchild (pid, descrip) + select old.pid, new.descrip where old.descrip isnull; + update cchild set descrip = new.descrip where cchild.pid = old.pid; +) +-- +TABLE: name="vview" schema="" table="vview" ctx=DDL +STMT: RuleStmt +== 363 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +== 364 +update vview set descrip='test1' where pid=1 +-- +TABLE: name="vview" schema="" table="vview" ctx=DML +STMT: UpdateStmt +== 365 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +== 366 +update vview set descrip='test2' where pid=2 +-- +TABLE: name="vview" schema="" table="vview" ctx=DML +STMT: UpdateStmt +== 367 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +== 368 +update vview set descrip='test3' where pid=3 +-- +TABLE: name="vview" schema="" table="vview" ctx=DML +STMT: UpdateStmt +== 369 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +== 370 +select * from cchild +-- +TABLE: name="cchild" schema="" table="cchild" ctx=Select +STMT: SelectStmt +== 371 +drop rule rrule on vview +-- +TABLE: name="vview" schema="" table="vview" ctx=DDL +STMT: DropStmt +== 372 +drop view vview +-- +STMT: DropStmt +== 373 +drop table pparent +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DDL +STMT: DropStmt +== 374 +drop table cchild +-- +TABLE: name="cchild" schema="" table="cchild" ctx=DDL +STMT: DropStmt +== 375 +|-- +-- Check that ruleutils are working +|-- + +-- temporarily disable fancy output, so view changes create less diff noise + +SELECT viewname, definition FROM pg_views +WHERE schemaname = 'pg_catalog' +ORDER BY viewname +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +== 376 +SELECT tablename, rulename, definition FROM pg_rules +WHERE schemaname = 'pg_catalog' +ORDER BY tablename, rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +== 377 +-- restore normal output mode + +|-- +-- CREATE OR REPLACE RULE +|-- + +CREATE TABLE ruletest_tbl (a int, b int) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DDL +STMT: CreateStmt +== 378 +CREATE TABLE ruletest_tbl2 (a int, b int) +-- +TABLE: name="ruletest_tbl2" schema="" table="ruletest_tbl2" ctx=DDL +STMT: CreateStmt +== 379 +CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl + DO INSTEAD INSERT INTO ruletest_tbl2 VALUES (10, 10) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DDL +STMT: RuleStmt +== 380 +INSERT INTO ruletest_tbl VALUES (99, 99) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 381 +CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl + DO INSTEAD INSERT INTO ruletest_tbl2 VALUES (1000, 1000) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DDL +STMT: RuleStmt +== 382 +INSERT INTO ruletest_tbl VALUES (99, 99) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 383 +SELECT * FROM ruletest_tbl2 +-- +TABLE: name="ruletest_tbl2" schema="" table="ruletest_tbl2" ctx=Select +STMT: SelectStmt +== 384 +-- Check that rewrite rules splitting one INSERT into multiple +-- conditional statements does not disable FK checking. +create table rule_and_refint_t1 ( + id1a integer, + id1b integer, + + primary key (id1a, id1b) +) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DDL +STMT: CreateStmt +== 385 +create table rule_and_refint_t2 ( + id2a integer, + id2c integer, + + primary key (id2a, id2c) +) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DDL +STMT: CreateStmt +== 386 +create table rule_and_refint_t3 ( + id3a integer, + id3b integer, + id3c integer, + data text, + + primary key (id3a, id3b, id3c), + + foreign key (id3a, id3b) references rule_and_refint_t1 (id1a, id1b), + foreign key (id3a, id3c) references rule_and_refint_t2 (id2a, id2c) +) +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DDL +STMT: CreateStmt +== 387 +insert into rule_and_refint_t1 values (1, 11) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 388 +insert into rule_and_refint_t1 values (1, 12) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 389 +insert into rule_and_refint_t1 values (2, 21) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 390 +insert into rule_and_refint_t1 values (2, 22) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 391 +insert into rule_and_refint_t2 values (1, 11) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 392 +insert into rule_and_refint_t2 values (1, 12) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 393 +insert into rule_and_refint_t2 values (2, 21) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 394 +insert into rule_and_refint_t2 values (2, 22) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 395 +insert into rule_and_refint_t3 values (1, 11, 11, 'row1') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 396 +insert into rule_and_refint_t3 values (1, 11, 12, 'row2') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 397 +insert into rule_and_refint_t3 values (1, 12, 11, 'row3') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 398 +insert into rule_and_refint_t3 values (1, 12, 12, 'row4') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 399 +insert into rule_and_refint_t3 values (1, 11, 13, 'row5') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 400 +insert into rule_and_refint_t3 values (1, 13, 11, 'row6') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 401 +-- Ordinary table +insert into rule_and_refint_t3 values (1, 13, 11, 'row6') + on conflict do nothing +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 402 +-- rule not fired, so fk violation +insert into rule_and_refint_t3 values (1, 13, 11, 'row6') + on conflict (id3a, id3b, id3c) do update + set id3b = excluded.id3b +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 403 +-- rule fired, so unsupported +insert into shoelace values ('sl9', 0, 'pink', 35.0, 'inch', 0.0) + on conflict (sl_name) do update + set sl_avail = excluded.sl_avail +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 404 +create rule rule_and_refint_t3_ins as on insert to rule_and_refint_t3 + where (exists (select 1 from rule_and_refint_t3 + where (((rule_and_refint_t3.id3a = new.id3a) + and (rule_and_refint_t3.id3b = new.id3b)) + and (rule_and_refint_t3.id3c = new.id3c)))) + do instead update rule_and_refint_t3 set data = new.data + where (((rule_and_refint_t3.id3a = new.id3a) + and (rule_and_refint_t3.id3b = new.id3b)) + and (rule_and_refint_t3.id3c = new.id3c)) +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DDL +STMT: RuleStmt +== 405 +insert into rule_and_refint_t3 values (1, 11, 13, 'row7') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 406 +insert into rule_and_refint_t3 values (1, 13, 11, 'row8') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 407 +|-- +-- disallow dropping a view's rule (bug #5072) +|-- + +create view rules_fooview as select 'rules_foo'::text +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 408 +drop rule "_RETURN" on rules_fooview +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: DropStmt +== 409 +drop view rules_fooview +-- +STMT: DropStmt +== 410 +|-- +-- We used to allow converting a table to a view by creating a "_RETURN" +-- rule for it, but no more. +|-- + +create table rules_fooview (x int, y text) +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: CreateStmt +== 411 +create rule "_RETURN" as on select to rules_fooview do instead + select 1 as x, 'aaa'::text as y +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: RuleStmt +== 412 +drop table rules_fooview +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: DropStmt +== 413 +-- likewise, converting a partitioned table or partition to view is not allowed +create table rules_fooview (x int, y text) partition by list (x) +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: CreateStmt +== 414 +create rule "_RETURN" as on select to rules_fooview do instead + select 1 as x, 'aaa'::text as y +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: RuleStmt +== 415 +create table rules_fooview_part partition of rules_fooview for values in (1) +-- +TABLE: name="rules_fooview_part" schema="" table="rules_fooview_part" ctx=DDL +STMT: CreateStmt +== 416 +create rule "_RETURN" as on select to rules_fooview_part do instead + select 1 as x, 'aaa'::text as y +-- +TABLE: name="rules_fooview_part" schema="" table="rules_fooview_part" ctx=DDL +STMT: RuleStmt +== 417 +drop table rules_fooview +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: DropStmt +== 418 +|-- +-- check for planner problems with complex inherited UPDATES +|-- + +create table id (id serial primary key, name text) +-- +TABLE: name="id" schema="" table="id" ctx=DDL +STMT: CreateStmt +== 419 +-- currently, must respecify PKEY for each inherited subtable +create table test_1 (id integer primary key) inherits (id) +-- +TABLE: name="test_1" schema="" table="test_1" ctx=DDL +STMT: CreateStmt +== 420 +create table test_2 (id integer primary key) inherits (id) +-- +TABLE: name="test_2" schema="" table="test_2" ctx=DDL +STMT: CreateStmt +== 421 +create table test_3 (id integer primary key) inherits (id) +-- +TABLE: name="test_3" schema="" table="test_3" ctx=DDL +STMT: CreateStmt +== 422 +insert into test_1 (name) values ('Test 1') +-- +TABLE: name="test_1" schema="" table="test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 423 +insert into test_1 (name) values ('Test 2') +-- +TABLE: name="test_1" schema="" table="test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 424 +insert into test_2 (name) values ('Test 3') +-- +TABLE: name="test_2" schema="" table="test_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 425 +insert into test_2 (name) values ('Test 4') +-- +TABLE: name="test_2" schema="" table="test_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 426 +insert into test_3 (name) values ('Test 5') +-- +TABLE: name="test_3" schema="" table="test_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 427 +insert into test_3 (name) values ('Test 6') +-- +TABLE: name="test_3" schema="" table="test_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 428 +create view id_ordered as select * from id order by id +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DDL +TABLE: name="id" schema="" table="id" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 429 +create rule update_id_ordered as on update to id_ordered + do instead update id set name = new.name where id = old.id +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DDL +STMT: RuleStmt +== 430 +select * from id_ordered +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=Select +STMT: SelectStmt +== 431 +update id_ordered set name = 'update 2' where id = 2 +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DML +STMT: UpdateStmt +== 432 +update id_ordered set name = 'update 4' where id = 4 +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DML +STMT: UpdateStmt +== 433 +update id_ordered set name = 'update 5' where id = 5 +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DML +STMT: UpdateStmt +== 434 +select * from id_ordered +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=Select +STMT: SelectStmt +== 435 +drop table id cascade +-- +TABLE: name="id" schema="" table="id" ctx=DDL +STMT: DropStmt +== 436 +|-- +-- check corner case where an entirely-dummy subplan is created by +-- constraint exclusion +|-- + +create temp table t1 (a integer primary key) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 437 +create temp table t1_1 (check (a >= 0 and a < 10)) inherits (t1) +-- +TABLE: name="t1_1" schema="" table="t1_1" ctx=DDL +STMT: CreateStmt +== 438 +create temp table t1_2 (check (a >= 10 and a < 20)) inherits (t1) +-- +TABLE: name="t1_2" schema="" table="t1_2" ctx=DDL +STMT: CreateStmt +== 439 +create rule t1_ins_1 as on insert to t1 + where new.a >= 0 and new.a < 10 + do instead + insert into t1_1 values (new.a) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +== 440 +create rule t1_ins_2 as on insert to t1 + where new.a >= 10 and new.a < 20 + do instead + insert into t1_2 values (new.a) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +== 441 +create rule t1_upd_1 as on update to t1 + where old.a >= 0 and old.a < 10 + do instead + update t1_1 set a = new.a where a = old.a +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +== 442 +create rule t1_upd_2 as on update to t1 + where old.a >= 10 and old.a < 20 + do instead + update t1_2 set a = new.a where a = old.a +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +== 443 +set constraint_exclusion = on +-- +STMT: VariableSetStmt +== 444 +insert into t1 select * from generate_series(5,19,1) g +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 445 +update t1 set a = 4 where a = 5 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: UpdateStmt +== 446 +select * from only t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 447 +select * from only t1_1 +-- +TABLE: name="t1_1" schema="" table="t1_1" ctx=Select +STMT: SelectStmt +== 448 +select * from only t1_2 +-- +TABLE: name="t1_2" schema="" table="t1_2" ctx=Select +STMT: SelectStmt +== 449 +reset constraint_exclusion +-- +STMT: VariableSetStmt +== 450 +-- test FOR UPDATE in rules + +create table rules_base(f1 int, f2 int) +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: CreateStmt +== 451 +insert into rules_base values(1,2), (11,12) +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 452 +create rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 1 for update +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: RuleStmt +== 453 +update rules_base set f2 = f2 + 1 +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DML +STMT: UpdateStmt +== 454 +create or replace rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 11 for update of rules_base +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: RuleStmt +== 455 +update rules_base set f2 = f2 + 1 +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DML +STMT: UpdateStmt +== 456 +create or replace rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 11 for update of old +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: RuleStmt +== 457 +-- error +drop table rules_base +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: DropStmt +== 458 +-- test various flavors of pg_get_viewdef() + +select pg_get_viewdef('shoe'::regclass) as unpretty +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 459 +select pg_get_viewdef('shoe'::regclass,true) as pretty +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 460 +select pg_get_viewdef('shoe'::regclass,0) as prettier +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 461 +|-- +-- check multi-row VALUES in rules +|-- + +create table rules_src(f1 int, f2 int default 0) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: CreateStmt +== 462 +create table rules_log(f1 int, f2 int, tag text, id serial) +-- +TABLE: name="rules_log" schema="" table="rules_log" ctx=DDL +STMT: CreateStmt +== 463 +insert into rules_src values(1,2), (11,12) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 464 +create rule r1 as on update to rules_src do also + insert into rules_log values(old.*, 'old', default), (new.*, 'new', default) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +== 465 +update rules_src set f2 = f2 + 1 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: UpdateStmt +== 466 +update rules_src set f2 = f2 * 10 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: UpdateStmt +== 467 +select * from rules_src +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=Select +STMT: SelectStmt +== 468 +select * from rules_log +-- +TABLE: name="rules_log" schema="" table="rules_log" ctx=Select +STMT: SelectStmt +== 469 +create rule r2 as on update to rules_src do also + values(old.*, 'old'), (new.*, 'new') +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +== 470 +update rules_src set f2 = f2 / 10 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: UpdateStmt +== 471 +create rule r3 as on insert to rules_src do also + insert into rules_log values(null, null, '-', default), (new.*, 'new', default) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +== 472 +insert into rules_src values(22,23), (33,default) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 473 +select * from rules_src +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=Select +STMT: SelectStmt +== 474 +select * from rules_log +-- +TABLE: name="rules_log" schema="" table="rules_log" ctx=Select +STMT: SelectStmt +== 475 +create rule r4 as on delete to rules_src do notify rules_src_deletion +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +== 476 +|-- +-- Ensure an aliased target relation for insert is correctly deparsed. +|-- +create rule r5 as on insert to rules_src do instead insert into rules_log AS trgt SELECT NEW.* RETURNING trgt.f1, trgt.f2 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +== 477 +create rule r6 as on update to rules_src do instead UPDATE rules_log AS trgt SET tag = 'updated' WHERE trgt.f1 = new.f1 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +== 478 +|-- +-- Check deparse disambiguation of INSERT/UPDATE/DELETE targets. +|-- +create rule r7 as on delete to rules_src do instead + with wins as (insert into int4_tbl as trgt values (0) returning *), + wupd as (update int4_tbl trgt set f1 = f1+1 returning *), + wdel as (delete from int4_tbl trgt where f1 = 0 returning *) + insert into rules_log AS trgt select old.* from wins, wupd, wdel + returning trgt.f1, trgt.f2 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +== 479 +-- check display of all rules added above + +|-- +-- Also check multiassignment deparsing. +|-- +create table rule_t1(f1 int, f2 int) +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: CreateStmt +== 480 +create table rule_dest(f1 int, f2 int[], tag text) +-- +TABLE: name="rule_dest" schema="" table="rule_dest" ctx=DDL +STMT: CreateStmt +== 481 +create rule rr as on update to rule_t1 do instead UPDATE rule_dest trgt + SET (f2[1], f1, tag) = (SELECT new.f2, new.f1, 'updated'::varchar) + WHERE trgt.f1 = new.f1 RETURNING new.* +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: RuleStmt +== 482 +drop table rule_t1, rule_dest +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +TABLE: name="rule_dest" schema="" table="rule_dest" ctx=DDL +STMT: DropStmt +== 483 +|-- +-- Test implicit LATERAL references to old/new in rules +|-- +CREATE TABLE rule_t1(a int, b text DEFAULT 'xxx', c int) +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: CreateStmt +== 484 +CREATE VIEW rule_v1 AS SELECT * FROM rule_t1 +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 485 +CREATE RULE v1_ins AS ON INSERT TO rule_v1 + DO ALSO INSERT INTO rule_t1 + SELECT * FROM (SELECT a + 10 FROM rule_t1 WHERE a = NEW.a) tt +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: RuleStmt +== 486 +CREATE RULE v1_upd AS ON UPDATE TO rule_v1 + DO ALSO UPDATE rule_t1 t + SET c = tt.a * 10 + FROM (SELECT a FROM rule_t1 WHERE a = OLD.a) tt WHERE t.a = tt.a +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: RuleStmt +== 487 +INSERT INTO rule_v1 VALUES (1, 'a'), (2, 'b') +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 488 +UPDATE rule_v1 SET b = upper(b) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: UpdateStmt +== 489 +SELECT * FROM rule_t1 +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=Select +STMT: SelectStmt +== 490 +DROP TABLE rule_t1 CASCADE +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: DropStmt +== 491 +|-- +-- check alter rename rule +|-- +CREATE TABLE rule_t1 (a INT) +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: CreateStmt +== 492 +CREATE VIEW rule_v1 AS SELECT * FROM rule_t1 +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 493 +CREATE RULE InsertRule AS + ON INSERT TO rule_v1 + DO INSTEAD + INSERT INTO rule_t1 VALUES(new.a) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: RuleStmt +== 494 +ALTER RULE InsertRule ON rule_v1 RENAME to NewInsertRule +-- +STMT: RenameStmt +== 495 +INSERT INTO rule_v1 VALUES(1) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 496 +SELECT * FROM rule_v1 +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=Select +STMT: SelectStmt +== 497 +|-- +-- error conditions for alter rename rule +|-- +ALTER RULE InsertRule ON rule_v1 RENAME TO NewInsertRule +-- +STMT: RenameStmt +== 498 +-- doesn't exist +ALTER RULE NewInsertRule ON rule_v1 RENAME TO "_RETURN" +-- +STMT: RenameStmt +== 499 +-- already exists +ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc +-- +STMT: RenameStmt +== 500 +-- ON SELECT rule cannot be renamed + +DROP VIEW rule_v1 +-- +STMT: DropStmt +== 501 +DROP TABLE rule_t1 +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: DropStmt +== 502 +|-- +-- check display of VALUES in view definitions +|-- +create view rule_v1 as values(1,2) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 503 +alter table rule_v1 rename column column2 to q2 +-- +STMT: RenameStmt +== 504 +drop view rule_v1 +-- +STMT: DropStmt +== 505 +create view rule_v1(x) as values(1,2) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 506 +drop view rule_v1 +-- +STMT: DropStmt +== 507 +create view rule_v1(x) as select * from (values(1,2)) v +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 508 +drop view rule_v1 +-- +STMT: DropStmt +== 509 +create view rule_v1(x) as select * from (values(1,2)) v(q,w) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 510 +drop view rule_v1 +-- +STMT: DropStmt +== 511 +|-- +-- Check DO INSTEAD rules with ON CONFLICT +|-- +CREATE TABLE hats ( + hat_name char(10) primary key, + hat_color char(10) -- hat color +) +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: CreateStmt +== 512 +CREATE TABLE hat_data ( + hat_name char(10), + hat_color char(10) -- hat color +) +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=DDL +STMT: CreateStmt +== 513 +create unique index hat_data_unique_idx + on hat_data (hat_name COLLATE "C" bpchar_pattern_ops) +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=DDL +STMT: IndexStmt +== 514 +-- DO NOTHING with ON CONFLICT +CREATE RULE hat_nosert AS ON INSERT TO hats + DO INSTEAD + INSERT INTO hat_data VALUES ( + NEW.hat_name, + NEW.hat_color) + ON CONFLICT (hat_name COLLATE "C" bpchar_pattern_ops) WHERE hat_color = 'green' + DO NOTHING + RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: RuleStmt +== 515 +SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 516 +-- Works (projects row) +INSERT INTO hats VALUES ('h7', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 517 +-- Works (does nothing) +INSERT INTO hats VALUES ('h7', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 518 +SELECT tablename, rulename, definition FROM pg_rules + WHERE tablename = 'hats' +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 519 +DROP RULE hat_nosert ON hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +== 520 +-- DO NOTHING without ON CONFLICT +CREATE RULE hat_nosert_all AS ON INSERT TO hats + DO INSTEAD + INSERT INTO hat_data VALUES ( + NEW.hat_name, + NEW.hat_color) + ON CONFLICT + DO NOTHING + RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: RuleStmt +== 521 +SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 522 +DROP RULE hat_nosert_all ON hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +== 523 +-- Works (does nothing) +INSERT INTO hats VALUES ('h7', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 524 +-- DO UPDATE with a WHERE clause +CREATE RULE hat_upsert AS ON INSERT TO hats + DO INSTEAD + INSERT INTO hat_data VALUES ( + NEW.hat_name, + NEW.hat_color) + ON CONFLICT (hat_name) + DO UPDATE + SET hat_name = hat_data.hat_name, hat_color = excluded.hat_color + WHERE excluded.hat_color <> 'forbidden' AND hat_data.* != excluded.* + RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: RuleStmt +== 525 +SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 526 +-- Works (does upsert) +INSERT INTO hats VALUES ('h8', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 527 +SELECT * FROM hat_data WHERE hat_name = 'h8' +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +== 528 +INSERT INTO hats VALUES ('h8', 'white') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 529 +SELECT * FROM hat_data WHERE hat_name = 'h8' +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +== 530 +INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 531 +SELECT * FROM hat_data WHERE hat_name = 'h8' +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +== 532 +SELECT tablename, rulename, definition FROM pg_rules + WHERE tablename = 'hats' +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 533 +-- ensure explain works for on insert conflict rules +explain (costs off) INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 534 +-- ensure upserting into a rule, with a CTE (different offsets!) works +WITH data(hat_name, hat_color) AS MATERIALIZED ( + VALUES ('h8', 'green'), + ('h9', 'blue'), + ('h7', 'forbidden') +) +INSERT INTO hats + SELECT * FROM data +RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +CTE: "data" +STMT: InsertStmt +STMT: SelectStmt +== 535 +EXPLAIN (costs off) +WITH data(hat_name, hat_color) AS MATERIALIZED ( + VALUES ('h8', 'green'), + ('h9', 'blue'), + ('h7', 'forbidden') +) +INSERT INTO hats + SELECT * FROM data +RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +CTE: "data" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 536 +SELECT * FROM hat_data WHERE hat_name IN ('h8', 'h9', 'h7') ORDER BY hat_name +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +== 537 +DROP RULE hat_upsert ON hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +== 538 +drop table hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +== 539 +drop table hat_data +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=DDL +STMT: DropStmt +== 540 +-- test for pg_get_functiondef properly regurgitating SET parameters +-- Note that the function is kept around to stress pg_dump. +CREATE FUNCTION func_with_set_params() RETURNS integer + AS 'select 1;' + LANGUAGE SQL + SET search_path TO PG_CATALOG + SET extra_float_digits TO 2 + SET work_mem TO '4MB' + SET datestyle to iso, mdy + SET local_preload_libraries TO "Mixed/Case", 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' + IMMUTABLE STRICT +-- +FUNCTION: name="func_with_set_params" function="func_with_set_params" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 541 +SELECT pg_get_functiondef('func_with_set_params()'::regprocedure) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 542 +-- tests for pg_get_*def with invalid objects +SELECT pg_get_constraintdef(0) +-- +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +STMT: SelectStmt +== 543 +SELECT pg_get_functiondef(0) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +== 544 +SELECT pg_get_indexdef(0) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +== 545 +SELECT pg_get_ruledef(0) +-- +FUNCTION: name="pg_get_ruledef" function="pg_get_ruledef" schema="" ctx=Call +STMT: SelectStmt +== 546 +SELECT pg_get_statisticsobjdef(0) +-- +FUNCTION: name="pg_get_statisticsobjdef" function="pg_get_statisticsobjdef" schema="" ctx=Call +STMT: SelectStmt +== 547 +SELECT pg_get_triggerdef(0) +-- +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +STMT: SelectStmt +== 548 +SELECT pg_get_viewdef(0) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 549 +SELECT pg_get_function_arguments(0) +-- +FUNCTION: name="pg_get_function_arguments" function="pg_get_function_arguments" schema="" ctx=Call +STMT: SelectStmt +== 550 +SELECT pg_get_function_identity_arguments(0) +-- +FUNCTION: name="pg_get_function_identity_arguments" function="pg_get_function_identity_arguments" schema="" ctx=Call +STMT: SelectStmt +== 551 +SELECT pg_get_function_result(0) +-- +FUNCTION: name="pg_get_function_result" function="pg_get_function_result" schema="" ctx=Call +STMT: SelectStmt +== 552 +SELECT pg_get_function_arg_default(0, 0) +-- +FUNCTION: name="pg_get_function_arg_default" function="pg_get_function_arg_default" schema="" ctx=Call +STMT: SelectStmt +== 553 +SELECT pg_get_function_arg_default('pg_class'::regclass, 0) +-- +FUNCTION: name="pg_get_function_arg_default" function="pg_get_function_arg_default" schema="" ctx=Call +STMT: SelectStmt +== 554 +SELECT pg_get_partkeydef(0) +-- +FUNCTION: name="pg_get_partkeydef" function="pg_get_partkeydef" schema="" ctx=Call +STMT: SelectStmt +== 555 +-- test rename for a rule defined on a partitioned table +CREATE TABLE rules_parted_table (a int) PARTITION BY LIST (a) +-- +TABLE: name="rules_parted_table" schema="" table="rules_parted_table" ctx=DDL +STMT: CreateStmt +== 556 +CREATE TABLE rules_parted_table_1 PARTITION OF rules_parted_table FOR VALUES IN (1) +-- +TABLE: name="rules_parted_table_1" schema="" table="rules_parted_table_1" ctx=DDL +STMT: CreateStmt +== 557 +CREATE RULE rules_parted_table_insert AS ON INSERT to rules_parted_table + DO INSTEAD INSERT INTO rules_parted_table_1 VALUES (NEW.*) +-- +TABLE: name="rules_parted_table" schema="" table="rules_parted_table" ctx=DDL +STMT: RuleStmt +== 558 +ALTER RULE rules_parted_table_insert ON rules_parted_table RENAME TO rules_parted_table_insert_redirect +-- +STMT: RenameStmt +== 559 +DROP TABLE rules_parted_table +-- +TABLE: name="rules_parted_table" schema="" table="rules_parted_table" ctx=DDL +STMT: DropStmt +== 560 +|-- +-- test MERGE +|-- +CREATE TABLE rule_merge1 (a int, b text) +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: CreateStmt +== 561 +CREATE TABLE rule_merge2 (a int, b text) +-- +TABLE: name="rule_merge2" schema="" table="rule_merge2" ctx=DDL +STMT: CreateStmt +== 562 +CREATE RULE rule1 AS ON INSERT TO rule_merge1 + DO INSTEAD INSERT INTO rule_merge2 VALUES (NEW.*) +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: RuleStmt +== 563 +CREATE RULE rule2 AS ON UPDATE TO rule_merge1 + DO INSTEAD UPDATE rule_merge2 SET a = NEW.a, b = NEW.b + WHERE a = OLD.a +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: RuleStmt +== 564 +CREATE RULE rule3 AS ON DELETE TO rule_merge1 + DO INSTEAD DELETE FROM rule_merge2 WHERE a = OLD.a +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: RuleStmt +== 565 +-- MERGE not supported for table with rules +MERGE INTO rule_merge1 t USING (SELECT 1 AS a) s + ON t.a = s.a + WHEN MATCHED AND t.a < 2 THEN + UPDATE SET b = b || ' updated by merge' + WHEN MATCHED AND t.a > 2 THEN + DELETE + WHEN NOT MATCHED THEN + INSERT VALUES (s.a, '') +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DML +ALIAS: "t"="rule_merge1" +STMT: MergeStmt +STMT: SelectStmt +== 566 +-- should be ok with the other table though +MERGE INTO rule_merge2 t USING (SELECT 1 AS a) s + ON t.a = s.a + WHEN MATCHED AND t.a < 2 THEN + UPDATE SET b = b || ' updated by merge' + WHEN MATCHED AND t.a > 2 THEN + DELETE + WHEN NOT MATCHED THEN + INSERT VALUES (s.a, '') +-- +TABLE: name="rule_merge2" schema="" table="rule_merge2" ctx=DML +ALIAS: "t"="rule_merge2" +STMT: MergeStmt +STMT: SelectStmt +== 567 +-- also ok if the rules are disabled +ALTER TABLE rule_merge1 DISABLE RULE rule1 +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: AlterTableStmt +== 568 +ALTER TABLE rule_merge1 DISABLE RULE rule2 +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: AlterTableStmt +== 569 +ALTER TABLE rule_merge1 DISABLE RULE rule3 +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: AlterTableStmt +== 570 +MERGE INTO rule_merge1 t USING (SELECT 1 AS a) s + ON t.a = s.a + WHEN MATCHED AND t.a < 2 THEN + UPDATE SET b = b || ' updated by merge' + WHEN MATCHED AND t.a > 2 THEN + DELETE + WHEN NOT MATCHED THEN + INSERT VALUES (s.a, '') +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DML +ALIAS: "t"="rule_merge1" +STMT: MergeStmt +STMT: SelectStmt +== 571 +-- test deparsing +CREATE TABLE sf_target(id int, data text, filling int[]) +-- +TABLE: name="sf_target" schema="" table="sf_target" ctx=DDL +STMT: CreateStmt +== 572 +CREATE FUNCTION merge_sf_test() + RETURNS TABLE(action text, a int, b text, id int, data text, filling int[]) + LANGUAGE sql +BEGIN ATOMIC + MERGE INTO sf_target t + USING rule_merge1 s + ON (s.a = t.id) +WHEN MATCHED + AND (s.a + t.id) = 42 + THEN UPDATE SET data = repeat(t.data, s.a) || s.b, id = length(s.b) +WHEN NOT MATCHED + AND (s.b IS NOT NULL) + THEN INSERT (data, id) + VALUES (s.b, s.a) +WHEN MATCHED + AND length(s.b || t.data) > 10 + THEN UPDATE SET data = s.b +WHEN MATCHED + AND s.a > 200 + THEN UPDATE SET filling[s.a] = t.id +WHEN MATCHED + AND s.a > 100 + THEN DELETE +WHEN MATCHED + THEN DO NOTHING +WHEN NOT MATCHED + AND s.a > 200 + THEN INSERT DEFAULT VALUES +WHEN NOT MATCHED + AND s.a > 100 + THEN INSERT (id, data) OVERRIDING USER VALUE + VALUES (s.a, DEFAULT) +WHEN NOT MATCHED + AND s.a > 0 + THEN INSERT + VALUES (s.a, s.b, DEFAULT) +WHEN NOT MATCHED + THEN INSERT (filling[1], id) + VALUES (s.a, s.a) +RETURNING + merge_action() AS action, * +-- +ERROR: syntax error at end of input +CURSORPOS: 982 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 573 +END +-- +STMT: TransactionStmt +== 574 +CREATE FUNCTION merge_sf_test2() + RETURNS void + LANGUAGE sql +BEGIN ATOMIC + MERGE INTO sf_target t + USING rule_merge1 s + ON (s.a = t.id) +WHEN NOT MATCHED + THEN INSERT (data, id) + VALUES (s.a, s.a) +WHEN MATCHED + THEN UPDATE SET data = s.b +WHEN NOT MATCHED BY SOURCE + THEN DELETE +-- +ERROR: syntax error at end of input +CURSORPOS: 289 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 575 +END +-- +STMT: TransactionStmt +== 576 +DROP FUNCTION merge_sf_test +-- +FUNCTION: name="merge_sf_test" function="merge_sf_test" schema="" ctx=DDL +STMT: DropStmt +== 577 +DROP FUNCTION merge_sf_test2 +-- +FUNCTION: name="merge_sf_test2" function="merge_sf_test2" schema="" ctx=DDL +STMT: DropStmt +== 578 +DROP TABLE sf_target +-- +TABLE: name="sf_target" schema="" table="sf_target" ctx=DDL +STMT: DropStmt +== 579 +|-- +-- Test enabling/disabling +|-- +CREATE TABLE ruletest1 (a int) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: CreateStmt +== 580 +CREATE TABLE ruletest2 (b int) +-- +TABLE: name="ruletest2" schema="" table="ruletest2" ctx=DDL +STMT: CreateStmt +== 581 +CREATE RULE rule1 AS ON INSERT TO ruletest1 + DO INSTEAD INSERT INTO ruletest2 VALUES (NEW.*) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: RuleStmt +== 582 +INSERT INTO ruletest1 VALUES (1) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 583 +ALTER TABLE ruletest1 DISABLE RULE rule1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: AlterTableStmt +== 584 +INSERT INTO ruletest1 VALUES (2) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 585 +ALTER TABLE ruletest1 ENABLE RULE rule1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: AlterTableStmt +== 586 +SET session_replication_role = replica +-- +STMT: VariableSetStmt +== 587 +INSERT INTO ruletest1 VALUES (3) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 588 +ALTER TABLE ruletest1 ENABLE REPLICA RULE rule1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: AlterTableStmt +== 589 +INSERT INTO ruletest1 VALUES (4) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 590 +RESET session_replication_role +-- +STMT: VariableSetStmt +== 591 +INSERT INTO ruletest1 VALUES (5) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 592 +SELECT * FROM ruletest1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=Select +STMT: SelectStmt +== 593 +SELECT * FROM ruletest2 +-- +TABLE: name="ruletest2" schema="" table="ruletest2" ctx=Select +STMT: SelectStmt +== 594 +DROP TABLE ruletest1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: DropStmt +== 595 +DROP TABLE ruletest2 +-- +TABLE: name="ruletest2" schema="" table="ruletest2" ctx=DDL +STMT: DropStmt +== 596 +|-- +-- Test non-SELECT rule on security invoker view. +-- Should use view owner's permissions. +|-- +CREATE USER regress_rule_user1 +-- +STMT: CreateRoleStmt +== 597 +CREATE TABLE ruletest_t1 (x int) +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: CreateStmt +== 598 +CREATE TABLE ruletest_t2 (x int) +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=DDL +STMT: CreateStmt +== 599 +CREATE VIEW ruletest_v1 WITH (security_invoker=true) AS + SELECT * FROM ruletest_t1 +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DDL +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 600 +GRANT INSERT ON ruletest_v1 TO regress_rule_user1 +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DDL +STMT: GrantStmt +== 601 +CREATE RULE rule1 AS ON INSERT TO ruletest_v1 + DO INSTEAD INSERT INTO ruletest_t2 VALUES (NEW.*) +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DDL +STMT: RuleStmt +== 602 +SET SESSION AUTHORIZATION regress_rule_user1 +-- +STMT: VariableSetStmt +== 603 +INSERT INTO ruletest_v1 VALUES (1) +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 604 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 605 +-- Test that main query's relation's permissions are checked before +-- the rule action's relation's. +CREATE TABLE ruletest_t3 (x int) +-- +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=DDL +STMT: CreateStmt +== 606 +CREATE RULE rule2 AS ON UPDATE TO ruletest_t1 + DO INSTEAD INSERT INTO ruletest_t2 VALUES (OLD.*) +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: RuleStmt +== 607 +REVOKE ALL ON ruletest_t2 FROM regress_rule_user1 +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=DDL +STMT: GrantStmt +== 608 +REVOKE ALL ON ruletest_t3 FROM regress_rule_user1 +-- +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=DDL +STMT: GrantStmt +== 609 +ALTER TABLE ruletest_t1 OWNER TO regress_rule_user1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: AlterTableStmt +== 610 +SET SESSION AUTHORIZATION regress_rule_user1 +-- +STMT: VariableSetStmt +== 611 +UPDATE ruletest_t1 t1 SET x = 0 FROM ruletest_t3 t3 WHERE t1.x = t3.x +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DML +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=Select +ALIAS: "t1"="ruletest_t1" +ALIAS: "t3"="ruletest_t3" +STMT: UpdateStmt +== 612 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 613 +SELECT * FROM ruletest_t1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=Select +STMT: SelectStmt +== 614 +SELECT * FROM ruletest_t2 +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=Select +STMT: SelectStmt +== 615 +DROP VIEW ruletest_v1 +-- +STMT: DropStmt +== 616 +DROP RULE rule2 ON ruletest_t1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: DropStmt +== 617 +DROP TABLE ruletest_t3 +-- +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=DDL +STMT: DropStmt +== 618 +DROP TABLE ruletest_t2 +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=DDL +STMT: DropStmt +== 619 +DROP TABLE ruletest_t1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: DropStmt +== 620 +DROP USER regress_rule_user1 +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/sanity_check.metadata.json b/parser/testdata/summary/postgres_regress/sanity_check.metadata.json new file mode 100644 index 0000000..3e33966 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sanity_check.metadata.json @@ -0,0 +1,7 @@ +{ + "todo": [ + "001", + "002", + "003" + ] +} diff --git a/parser/testdata/summary/postgres_regress/sanity_check.test b/parser/testdata/summary/postgres_regress/sanity_check.test new file mode 100644 index 0000000..c09018f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sanity_check.test @@ -0,0 +1,49 @@ +== 001 +VACUUM +-- +STMT: VacuumStmt +== 002 +|-- +-- Sanity check: every system catalog that has OIDs should have +-- a unique index on OID. This ensures that the OIDs will be unique, +-- even after the OID counter wraps around. +-- We exclude non-system tables from the check by looking at nspname. +|-- +SELECT relname, nspname + FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a ON (attrelid = c.oid AND attname = 'oid') + WHERE relkind = 'r' and c.oid < 16384 + AND ((nspname ~ '^pg_') IS NOT FALSE) + AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid + AND indkey[0] = a.attnum AND indnatts = 1 + AND indisunique AND indimmediate) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +ALIAS: "n"="pg_namespace" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="nspname" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="indkey" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indisunique" +FILTER: schema="" table="" column="indimmediate" +STMT: SelectStmt +== 003 +-- check that relations without storage don't have relfilenode +SELECT relname, relkind + FROM pg_class + WHERE relkind IN ('v', 'c', 'f', 'p', 'I') + AND relfilenode <> 0 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relfilenode" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/security_label.metadata.json b/parser/testdata/summary/postgres_regress/security_label.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/security_label.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary/postgres_regress/security_label.test b/parser/testdata/summary/postgres_regress/security_label.test new file mode 100644 index 0000000..994f339 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/security_label.test @@ -0,0 +1,142 @@ +== 001 +|-- +-- Test for facilities of security label +|-- + +-- initial setups +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +== 002 +DROP ROLE IF EXISTS regress_seclabel_user1 +-- +STMT: DropRoleStmt +== 003 +DROP ROLE IF EXISTS regress_seclabel_user2 +-- +STMT: DropRoleStmt +== 004 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 005 +CREATE USER regress_seclabel_user1 WITH CREATEROLE +-- +STMT: CreateRoleStmt +== 006 +CREATE USER regress_seclabel_user2 +-- +STMT: CreateRoleStmt +== 007 +CREATE TABLE seclabel_tbl1 (a int, b text) +-- +TABLE: name="seclabel_tbl1" schema="" table="seclabel_tbl1" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE seclabel_tbl2 (x int, y text) +-- +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=DDL +STMT: CreateStmt +== 009 +CREATE VIEW seclabel_view1 AS SELECT * FROM seclabel_tbl2 +-- +TABLE: name="seclabel_view1" schema="" table="seclabel_view1" ctx=DDL +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 010 +CREATE FUNCTION seclabel_four() RETURNS integer AS $$SELECT 4$$ language sql +-- +FUNCTION: name="seclabel_four" function="seclabel_four" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 011 +CREATE DOMAIN seclabel_domain AS text +-- +STMT: CreateDomainStmt +== 012 +ALTER TABLE seclabel_tbl1 OWNER TO regress_seclabel_user1 +-- +TABLE: name="seclabel_tbl1" schema="" table="seclabel_tbl1" ctx=DDL +STMT: AlterTableStmt +== 013 +ALTER TABLE seclabel_tbl2 OWNER TO regress_seclabel_user2 +-- +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=DDL +STMT: AlterTableStmt +== 014 +|-- +-- Test of SECURITY LABEL statement without a plugin +|-- +SECURITY LABEL ON TABLE seclabel_tbl1 IS 'classified' +-- +STMT: SecLabelStmt +== 015 +-- fail +SECURITY LABEL FOR 'dummy' ON TABLE seclabel_tbl1 IS 'classified' +-- +STMT: SecLabelStmt +== 016 +-- fail +SECURITY LABEL ON TABLE seclabel_tbl1 IS '...invalid label...' +-- +STMT: SecLabelStmt +== 017 +-- fail +SECURITY LABEL ON TABLE seclabel_tbl3 IS 'unclassified' +-- +STMT: SecLabelStmt +== 018 +-- fail + +SECURITY LABEL ON ROLE regress_seclabel_user1 IS 'classified' +-- +STMT: SecLabelStmt +== 019 +-- fail +SECURITY LABEL FOR 'dummy' ON ROLE regress_seclabel_user1 IS 'classified' +-- +STMT: SecLabelStmt +== 020 +-- fail +SECURITY LABEL ON ROLE regress_seclabel_user1 IS '...invalid label...' +-- +STMT: SecLabelStmt +== 021 +-- fail +SECURITY LABEL ON ROLE regress_seclabel_user3 IS 'unclassified' +-- +STMT: SecLabelStmt +== 022 +-- fail + +-- clean up objects +DROP FUNCTION seclabel_four() +-- +FUNCTION: name="seclabel_four" function="seclabel_four" schema="" ctx=DDL +STMT: DropStmt +== 023 +DROP DOMAIN seclabel_domain +-- +STMT: DropStmt +== 024 +DROP VIEW seclabel_view1 +-- +STMT: DropStmt +== 025 +DROP TABLE seclabel_tbl1 +-- +TABLE: name="seclabel_tbl1" schema="" table="seclabel_tbl1" ctx=DDL +STMT: DropStmt +== 026 +DROP TABLE seclabel_tbl2 +-- +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=DDL +STMT: DropStmt +== 027 +DROP USER regress_seclabel_user1 +-- +STMT: DropRoleStmt +== 028 +DROP USER regress_seclabel_user2 +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/select.metadata.json b/parser/testdata/summary/postgres_regress/select.metadata.json new file mode 100644 index 0000000..8e8d1f7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select.metadata.json @@ -0,0 +1,91 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select.test b/parser/testdata/summary/postgres_regress/select.test new file mode 100644 index 0000000..91be8cd --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select.test @@ -0,0 +1,637 @@ +== 001 +|-- +-- SELECT +|-- + +-- btree index +-- awk '{if($1<10){print;}else{next;}}' onek.data | sort +0n -1 +|-- +SELECT * FROM onek + WHERE onek.unique1 < 10 + ORDER BY onek.unique1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 002 +|-- +-- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 +|-- +SELECT onek.unique1, onek.stringu1 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using > +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 003 +|-- +-- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 +|-- +SELECT onek.unique1, onek.stringu1 FROM onek + WHERE onek.unique1 > 980 + ORDER BY stringu1 using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 004 +|-- +-- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | +-- sort +1d -2 +0nr -1 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 > 980 + ORDER BY string4 using <, unique1 using > +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 005 +|-- +-- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | +-- sort +1dr -2 +0n -1 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 > 980 + ORDER BY string4 using >, unique1 using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 006 +|-- +-- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | +-- sort +0nr -1 +1d -2 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using >, string4 using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 007 +|-- +-- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | +-- sort +0n -1 +1dr -2 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using <, string4 using > +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 008 +|-- +-- test partial btree indexes +|-- +-- As of 7.2, planner probably won't pick an indexscan without stats, +-- so ANALYZE first. Also, we want to prevent it from picking a bitmapscan +-- followed by sort, because that could hide index ordering problems. +|-- +ANALYZE onek2 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: VacuumStmt +== 009 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +== 010 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 011 +SET enable_sort TO off +-- +STMT: VariableSetStmt +== 012 +|-- +-- awk '{if($1<10){print $0;}else{next;}}' onek.data | sort +0n -1 +|-- +SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +== 013 +|-- +-- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 +|-- +SELECT onek2.unique1, onek2.stringu1 FROM onek2 + WHERE onek2.unique1 < 20 + ORDER BY unique1 using > +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +== 014 +|-- +-- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 +|-- +SELECT onek2.unique1, onek2.stringu1 FROM onek2 + WHERE onek2.unique1 > 980 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +== 015 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 016 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 017 +RESET enable_sort +-- +STMT: VariableSetStmt +== 018 +|-- +-- awk '{print $1,$2;}' person.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - student.data | +-- awk 'BEGIN{FS=" ";}{if(NF!=2){print $4,$5;}else{print;}}' - stud_emp.data +|-- +-- SELECT name, age FROM person*; ??? check if different +SELECT p.name, p.age FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +STMT: SelectStmt +== 019 +|-- +-- awk '{print $1,$2;}' person.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - student.data | +-- awk 'BEGIN{FS=" ";}{if(NF!=1){print $4,$5;}else{print;}}' - stud_emp.data | +-- sort +1nr -2 +|-- +SELECT p.name, p.age FROM person* p ORDER BY age using >, name +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +STMT: SelectStmt +== 020 +|-- +-- Test some cases involving whole-row Var referencing a subquery +|-- +select foo from (select 1 offset 0) as foo +-- +STMT: SelectStmt +== 021 +select foo from (select null offset 0) as foo +-- +STMT: SelectStmt +== 022 +select foo from (select 'xyzzy',1,null offset 0) as foo +-- +STMT: SelectStmt +== 023 +|-- +-- Test VALUES lists +|-- +select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) + WHERE onek.unique1 = v.i and onek.stringu1 = v.j +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +FILTER: schema="" table="v" column="i" +FILTER: schema="" table="onek" column="stringu1" +FILTER: schema="" table="v" column="j" +STMT: SelectStmt +== 024 +-- a more complex case +-- looks like we're coding lisp :-) +select * from onek, + (values ((select i from + (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i) + order by i asc limit 1))) bar (i) + where onek.unique1 = bar.i +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +FILTER: schema="" table="bar" column="i" +STMT: SelectStmt +== 025 +-- try VALUES in a subquery +select * from onek + where (unique1,ten) in (values (1,1), (20,0), (99,9), (17,99)) + order by unique1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="ten" +STMT: SelectStmt +== 026 +-- VALUES is also legal as a standalone query or a set-operation member +VALUES (1,2), (3,4+4), (7,77.7) +-- +STMT: SelectStmt +== 027 +VALUES (1,2), (3,4+4), (7,77.7) +UNION ALL +SELECT 2+2, 57 +UNION ALL +TABLE int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 028 +-- corner case: VALUES with no columns +CREATE TEMP TABLE nocols() +-- +TABLE: name="nocols" schema="" table="nocols" ctx=DDL +STMT: CreateStmt +== 029 +INSERT INTO nocols DEFAULT VALUES +-- +TABLE: name="nocols" schema="" table="nocols" ctx=DML +STMT: InsertStmt +== 030 +SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v +-- +TABLE: name="nocols" schema="" table="nocols" ctx=Select +ALIAS: "n"="nocols" +STMT: SelectStmt +== 031 +|-- +-- Test ORDER BY options +|-- + +CREATE TEMP TABLE foo (f1 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 032 +INSERT INTO foo VALUES (42),(3),(10),(7),(null),(null),(1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 034 +SELECT * FROM foo ORDER BY f1 ASC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 035 +-- same thing +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 036 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 037 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 038 +-- check if indexscans do the right things +CREATE INDEX fooi ON foo (f1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +== 039 +SET enable_sort = false +-- +STMT: VariableSetStmt +== 040 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 041 +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 042 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 043 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 044 +DROP INDEX fooi +-- +STMT: DropStmt +== 045 +CREATE INDEX fooi ON foo (f1 DESC) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +== 046 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 047 +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 048 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 049 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 050 +DROP INDEX fooi +-- +STMT: DropStmt +== 051 +CREATE INDEX fooi ON foo (f1 DESC NULLS LAST) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +== 052 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 053 +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 054 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 055 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +== 056 +|-- +-- Test planning of some cases with partial indexes +|-- + +-- partial index is usable +explain (costs off) +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 057 +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 058 +-- actually run the query with an analyze to use the partial index +explain (costs off, analyze on, timing off, summary off) +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 059 +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 060 +select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 061 +-- partial index predicate implies clause, so no need for retest +explain (costs off) +select * from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 062 +select * from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 063 +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 064 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 065 +-- but if it's an update target, must retest anyway +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 066 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 067 +-- partial index is not applicable +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'C' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 068 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'C' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 069 +-- partial index implies clause, but bitmap scan must recheck predicate anyway +SET enable_indexscan TO off +-- +STMT: VariableSetStmt +== 070 +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 071 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 072 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 073 +-- check multi-index cases too +explain (costs off) +select unique1, unique2 from onek2 + where (unique2 = 11 or unique1 = 0) and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 074 +select unique1, unique2 from onek2 + where (unique2 = 11 or unique1 = 0) and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 075 +explain (costs off) +select unique1, unique2 from onek2 + where (unique2 = 11 and stringu1 < 'B') or unique1 = 0 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 076 +select unique1, unique2 from onek2 + where (unique2 = 11 and stringu1 < 'B') or unique1 = 0 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 077 +|-- +-- Test some corner cases that have been known to confuse the planner +|-- + +-- ORDER BY on a constant doesn't really need any sorting +SELECT 1 AS x ORDER BY x +-- +STMT: SelectStmt +== 078 +-- But ORDER BY on a set-valued expression does +create function sillysrf(int) returns setof int as + 'values (1),(10),(2),($1)' language sql immutable +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 079 +select sillysrf(42) +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=Call +STMT: SelectStmt +== 080 +select sillysrf(-1) order by 1 +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=Call +STMT: SelectStmt +== 081 +drop function sillysrf(int) +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=DDL +STMT: DropStmt +== 082 +-- 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 +-- +FILTER: schema="" table="" column="k" +FILTER: schema="" table="" column="k" +STMT: SelectStmt +== 083 +select * from (values (2),(null),(1)) v(k) where k = k +-- +FILTER: schema="" table="" column="k" +FILTER: schema="" table="" column="k" +STMT: SelectStmt +== 084 +-- 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) +-- +TABLE: name="list_parted_tbl" schema="" table="list_parted_tbl" ctx=DDL +STMT: CreateStmt +== 085 +create table list_parted_tbl1 partition of list_parted_tbl + for values in (1) partition by list(b) +-- +TABLE: name="list_parted_tbl1" schema="" table="list_parted_tbl1" ctx=DDL +STMT: CreateStmt +== 086 +explain (costs off) select * from list_parted_tbl +-- +TABLE: name="list_parted_tbl" schema="" table="list_parted_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 087 +drop table list_parted_tbl +-- +TABLE: name="list_parted_tbl" schema="" table="list_parted_tbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/select_distinct.metadata.json b/parser/testdata/summary/postgres_regress/select_distinct.metadata.json new file mode 100644 index 0000000..f476ef8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_distinct.metadata.json @@ -0,0 +1,80 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select_distinct.test b/parser/testdata/summary/postgres_regress/select_distinct.test new file mode 100644 index 0000000..0ee19ec --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_distinct.test @@ -0,0 +1,487 @@ +== 001 +|-- +-- SELECT_DISTINCT +|-- + +|-- +-- awk '{print $3;}' onek.data | sort -n | uniq +|-- +SELECT DISTINCT two FROM onek ORDER BY 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 002 +|-- +-- awk '{print $5;}' onek.data | sort -n | uniq +|-- +SELECT DISTINCT ten FROM onek ORDER BY 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 003 +|-- +-- awk '{print $16;}' onek.data | sort -d | uniq +|-- +SELECT DISTINCT string4 FROM onek ORDER BY 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 004 +|-- +-- awk '{print $3,$16,$5;}' onek.data | sort -d | uniq | +-- sort +0n -1 +1d -2 +2n -3 +|-- +SELECT DISTINCT two, string4, ten + FROM onek + ORDER BY two using <, string4 using <, ten using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 005 +|-- +-- awk '{print $2;}' person.data | +-- awk '{if(NF!=1){print $2;}else{print;}}' - emp.data | +-- awk '{if(NF!=1){print $2;}else{print;}}' - student.data | +-- awk 'BEGIN{FS=" ";}{if(NF!=1){print $5;}else{print;}}' - stud_emp.data | +-- sort -n -r | uniq +|-- +SELECT DISTINCT p.age FROM person* p ORDER BY age using > +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +STMT: SelectStmt +== 006 +|-- +-- Check mentioning same column more than once +|-- + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT count(*) FROM + (SELECT DISTINCT two, four, two FROM tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 007 +SELECT count(*) FROM + (SELECT DISTINCT two, four, two FROM tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 008 +|-- +-- 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' +-- +STMT: VariableSetStmt +== 009 +-- Produce results with sorting. + +SET enable_hashagg=FALSE +-- +STMT: VariableSetStmt +== 010 +SET jit_above_cost=0 +-- +STMT: VariableSetStmt +== 011 +EXPLAIN (costs off) +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 012 +CREATE TABLE distinct_group_1 AS +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 013 +SET jit_above_cost TO DEFAULT +-- +STMT: VariableSetStmt +== 014 +CREATE TABLE distinct_group_2 AS +SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g +-- +TABLE: name="distinct_group_2" schema="" table="distinct_group_2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 015 +SET enable_seqscan = 0 +-- +STMT: VariableSetStmt +== 016 +-- Check to see we get an incremental sort plan +EXPLAIN (costs off) +SELECT DISTINCT hundred, two FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 017 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 018 +SET enable_hashagg=TRUE +-- +STMT: VariableSetStmt +== 019 +-- Produce results with hash aggregation. + +SET enable_sort=FALSE +-- +STMT: VariableSetStmt +== 020 +SET jit_above_cost=0 +-- +STMT: VariableSetStmt +== 021 +EXPLAIN (costs off) +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 022 +CREATE TABLE distinct_hash_1 AS +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 023 +SET jit_above_cost TO DEFAULT +-- +STMT: VariableSetStmt +== 024 +CREATE TABLE distinct_hash_2 AS +SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g +-- +TABLE: name="distinct_hash_2" schema="" table="distinct_hash_2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 025 +SET enable_sort=TRUE +-- +STMT: VariableSetStmt +== 026 +SET work_mem TO DEFAULT +-- +STMT: VariableSetStmt +== 027 +-- 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) +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +STMT: SelectStmt +== 028 +(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) + UNION ALL +(SELECT * FROM distinct_group_1 EXCEPT SELECT * FROM distinct_hash_1) +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +STMT: SelectStmt +== 029 +DROP TABLE distinct_hash_1 +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=DDL +STMT: DropStmt +== 030 +DROP TABLE distinct_hash_2 +-- +TABLE: name="distinct_hash_2" schema="" table="distinct_hash_2" ctx=DDL +STMT: DropStmt +== 031 +DROP TABLE distinct_group_1 +-- +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=DDL +STMT: DropStmt +== 032 +DROP TABLE distinct_group_2 +-- +TABLE: name="distinct_group_2" schema="" table="distinct_group_2" ctx=DDL +STMT: DropStmt +== 033 +-- Test parallel DISTINCT +SET parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +== 034 +SET parallel_setup_cost=0 +-- +STMT: VariableSetStmt +== 035 +SET min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +== 036 +SET max_parallel_workers_per_gather=2 +-- +STMT: VariableSetStmt +== 037 +-- Ensure we get a parallel plan +EXPLAIN (costs off) +SELECT DISTINCT four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 038 +-- Ensure the parallel plan produces the correct results +SELECT DISTINCT four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +== 039 +CREATE OR REPLACE FUNCTION distinct_func(a INT) RETURNS INT AS $$ + BEGIN + RETURN a; + END; +$$ LANGUAGE plpgsql PARALLEL UNSAFE +-- +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 040 +-- Ensure we don't do parallel distinct with a parallel unsafe function +EXPLAIN (COSTS OFF) +SELECT DISTINCT distinct_func(1) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 041 +-- make the function parallel safe +CREATE OR REPLACE FUNCTION distinct_func(a INT) RETURNS INT AS $$ + BEGIN + RETURN a; + END; +$$ LANGUAGE plpgsql PARALLEL SAFE +-- +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 042 +-- Ensure we do parallel distinct now that the function is parallel safe +EXPLAIN (COSTS OFF) +SELECT DISTINCT distinct_func(1) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 043 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +== 044 +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt +== 045 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +== 046 +RESET parallel_tuple_cost +-- +STMT: VariableSetStmt +== 047 +|-- +-- Test the planner's ability to use a LIMIT 1 instead of a Unique node when +-- all of the distinct_pathkeys have been marked as redundant +|-- + +-- Ensure we get a plan with a Limit 1 +EXPLAIN (COSTS OFF) +SELECT DISTINCT four FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 048 +-- Ensure the above gives us the correct result +SELECT DISTINCT four FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: SelectStmt +== 049 +-- Ensure we get a plan with a Limit 1 +EXPLAIN (COSTS OFF) +SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="two" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +-- Ensure no rows are returned +SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="two" +STMT: SelectStmt +== 051 +-- Ensure we get a plan with a Limit 1 when the SELECT list contains constants +EXPLAIN (COSTS OFF) +SELECT DISTINCT four,1,2,3 FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +-- Ensure we only get 1 row +SELECT DISTINCT four,1,2,3 FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: SelectStmt +== 053 +SET parallel_setup_cost=0 +-- +STMT: VariableSetStmt +== 054 +SET min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +== 055 +SET max_parallel_workers_per_gather=2 +-- +STMT: VariableSetStmt +== 056 +-- Ensure we get a plan with a Limit 1 in both partial distinct and final +-- distinct +EXPLAIN (COSTS OFF) +SELECT DISTINCT four FROM tenk1 WHERE four = 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 057 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +== 058 +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt +== 059 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +== 060 +|-- +-- Also, some tests of IS DISTINCT FROM, which doesn't quite deserve its +-- very own regression file. +|-- + +CREATE TEMP TABLE disttable (f1 integer) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DDL +STMT: CreateStmt +== 061 +INSERT INTO DISTTABLE VALUES(1) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +INSERT INTO DISTTABLE VALUES(2) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +INSERT INTO DISTTABLE VALUES(3) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +INSERT INTO DISTTABLE VALUES(NULL) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +-- basic cases +SELECT f1, f1 IS DISTINCT FROM 2 as "not 2" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +== 066 +SELECT f1, f1 IS DISTINCT FROM NULL as "not null" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +== 067 +SELECT f1, f1 IS DISTINCT FROM f1 as "false" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +== 068 +SELECT f1, f1 IS DISTINCT FROM f1+1 as "not null" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +== 069 +-- check that optimizer constant-folds it properly +SELECT 1 IS DISTINCT FROM 2 as "yes" +-- +STMT: SelectStmt +== 070 +SELECT 2 IS DISTINCT FROM 2 as "no" +-- +STMT: SelectStmt +== 071 +SELECT 2 IS DISTINCT FROM null as "yes" +-- +STMT: SelectStmt +== 072 +SELECT null IS DISTINCT FROM null as "no" +-- +STMT: SelectStmt +== 073 +-- negated form +SELECT 1 IS NOT DISTINCT FROM 2 as "no" +-- +STMT: SelectStmt +== 074 +SELECT 2 IS NOT DISTINCT FROM 2 as "yes" +-- +STMT: SelectStmt +== 075 +SELECT 2 IS NOT DISTINCT FROM null as "no" +-- +STMT: SelectStmt +== 076 +SELECT null IS NOT DISTINCT FROM null as "yes" +-- +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json b/parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json new file mode 100644 index 0000000..5e6664a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json @@ -0,0 +1,12 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select_distinct_on.test b/parser/testdata/summary/postgres_regress/select_distinct_on.test new file mode 100644 index 0000000..ad84e1d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_distinct_on.test @@ -0,0 +1,78 @@ +== 001 +|-- +-- SELECT_DISTINCT_ON +|-- + +SELECT DISTINCT ON (string4) string4, two, ten + FROM onek + ORDER BY string4 using <, two using >, ten using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 002 +-- this will fail due to conflict of ordering requirements +SELECT DISTINCT ON (string4, ten) string4, two, ten + FROM onek + ORDER BY string4 using <, two using <, ten using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 003 +SELECT DISTINCT ON (string4, ten) string4, ten, two + FROM onek + ORDER BY string4 using <, ten using >, two using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +== 004 +-- bug #5049: early 8.4.x chokes on volatile DISTINCT ON clauses +select distinct on (1) floor(random()) as r, f1 from int4_tbl order by 1,2 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="floor" function="floor" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 005 +|-- +-- Test the planner's ability to use a LIMIT 1 instead of a Unique node when +-- all of the distinct_pathkeys have been marked as redundant +|-- + +-- Ensure we also get a LIMIT plan with DISTINCT ON +EXPLAIN (COSTS OFF) +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 006 +-- and check the result of the above query is correct +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: SelectStmt +== 007 +-- Ensure a Sort -> Limit is used when the ORDER BY contains additional cols +EXPLAIN (COSTS OFF) +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1,2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 008 +-- Same again but use a column that is indexed so that we get an index scan +-- then a limit +EXPLAIN (COSTS OFF) +SELECT DISTINCT ON (four) four,hundred + FROM tenk1 WHERE four = 0 ORDER BY 1,2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/select_having.metadata.json b/parser/testdata/summary/postgres_regress/select_having.metadata.json new file mode 100644 index 0000000..880b1d2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_having.metadata.json @@ -0,0 +1,27 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select_having.test b/parser/testdata/summary/postgres_regress/select_having.test new file mode 100644 index 0000000..a1c38f1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_having.test @@ -0,0 +1,166 @@ +== 001 +|-- +-- SELECT_HAVING +|-- + +-- load test data +CREATE TABLE test_having (a int, b int, c char(8), d char) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO test_having VALUES (0, 1, 'XXXX', 'A') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO test_having VALUES (1, 2, 'AAAA', 'b') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO test_having VALUES (2, 2, 'AAAA', 'c') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO test_having VALUES (3, 3, 'BBBB', 'D') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO test_having VALUES (4, 3, 'BBBB', 'e') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO test_having VALUES (5, 3, 'bbbb', 'F') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO test_having VALUES (6, 4, 'cccc', 'g') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO test_having VALUES (7, 4, 'cccc', 'h') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO test_having VALUES (8, 4, 'CCCC', 'I') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO test_having VALUES (9, 4, 'CCCC', 'j') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +SELECT b, c FROM test_having + GROUP BY b, c HAVING count(*) = 1 ORDER BY b, c +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- HAVING is effectively equivalent to WHERE in this case +SELECT b, c FROM test_having + GROUP BY b, c HAVING b = 3 ORDER BY b, c +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +== 014 +SELECT lower(c), count(c) FROM test_having + GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a) + ORDER BY lower(c) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT c, max(a) FROM test_having + GROUP BY c HAVING count(*) > 2 OR min(a) = max(a) + ORDER BY c +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- test degenerate cases involving HAVING without GROUP BY +-- Per SQL spec, these should generate 0 or 1 row, even without aggregates + +SELECT min(a), max(a) FROM test_having HAVING min(a) = max(a) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT min(a), max(a) FROM test_having HAVING min(a) < max(a) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- errors: ungrouped column references +SELECT a FROM test_having HAVING min(a) < max(a) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT 1 AS one FROM test_having HAVING a > 1 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +== 020 +-- the really degenerate case: need not scan table at all +SELECT 1 AS one FROM test_having HAVING 1 > 2 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +== 021 +SELECT 1 AS one FROM test_having HAVING 1 < 2 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +== 022 +-- and just to prove that we aren't scanning the table: +SELECT 1 AS one FROM test_having WHERE 1/a = 1 HAVING 1 < 2 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 023 +DROP TABLE test_having +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/select_implicit.metadata.json b/parser/testdata/summary/postgres_regress/select_implicit.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_implicit.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select_implicit.test b/parser/testdata/summary/postgres_regress/select_implicit.test new file mode 100644 index 0000000..a63c323 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_implicit.test @@ -0,0 +1,384 @@ +== 001 +|-- +-- SELECT_IMPLICIT +-- Test cases for queries with ordering terms missing from the target list. +-- This used to be called "junkfilter.sql". +-- The parser uses the term "resjunk" to handle these cases. +-- - thomas 1998-07-09 +|-- + +-- load test data +CREATE TABLE test_missing_target (a int, b int, c char(8), d char) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO test_missing_target VALUES (0, 1, 'XXXX', 'A') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO test_missing_target VALUES (1, 2, 'ABAB', 'b') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO test_missing_target VALUES (2, 2, 'ABAB', 'c') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO test_missing_target VALUES (3, 3, 'BBBB', 'D') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO test_missing_target VALUES (4, 3, 'BBBB', 'e') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO test_missing_target VALUES (5, 3, 'bbbb', 'F') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO test_missing_target VALUES (6, 4, 'cccc', 'g') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO test_missing_target VALUES (7, 4, 'cccc', 'h') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO test_missing_target VALUES (8, 4, 'CCCC', 'I') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO test_missing_target VALUES (9, 4, 'CCCC', 'j') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +-- w/ existing GROUP BY target +SELECT c, count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- w/o existing GROUP BY target using a relation name in GROUP BY clause +SELECT count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- w/o existing GROUP BY target and w/o existing a different ORDER BY target +-- failure expected +SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 015 +-- w/o existing GROUP BY target and w/o existing same ORDER BY target +SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- w/ existing GROUP BY target using a relation name in target +SELECT test_missing_target.b, count(*) + FROM test_missing_target GROUP BY b ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- w/o existing GROUP BY target +SELECT c FROM test_missing_target ORDER BY a +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +== 018 +-- w/o existing ORDER BY target +SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b desc +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- group using reference number +SELECT count(*) FROM test_missing_target ORDER BY 1 desc +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- order using reference number +SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 021 +-- group using reference number out of range +-- failure expected +SELECT c, count(*) FROM test_missing_target GROUP BY 3 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- group w/o existing GROUP BY and ORDER BY target under ambiguous condition +-- failure expected +SELECT count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY b ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +== 023 +-- order w/ target under ambiguous condition +-- failure NOT expected +SELECT a, a FROM test_missing_target + ORDER BY a +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +== 024 +-- order expression w/ target under ambiguous condition +-- failure NOT expected +SELECT a/2, a/2 FROM test_missing_target + ORDER BY a/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +== 025 +-- group expression w/ target under ambiguous condition +-- failure NOT expected +SELECT a/2, a/2 FROM test_missing_target + GROUP BY a/2 ORDER BY a/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +== 026 +-- group w/ existing GROUP BY target under ambiguous condition +SELECT x.b, count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +== 027 +-- group w/o existing GROUP BY target under ambiguous condition +SELECT count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +== 028 +-- group w/o existing GROUP BY target under ambiguous condition +-- into a table +CREATE TABLE test_missing_target2 AS +SELECT count(*) +FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b +-- +TABLE: name="test_missing_target2" schema="" table="test_missing_target2" ctx=DDL +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 029 +SELECT * FROM test_missing_target2 +-- +TABLE: name="test_missing_target2" schema="" table="test_missing_target2" ctx=Select +STMT: SelectStmt +== 030 +-- Functions and expressions + +-- w/ existing GROUP BY target +SELECT a%2, count(b) FROM test_missing_target +GROUP BY test_missing_target.a%2 +ORDER BY test_missing_target.a%2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- w/o existing GROUP BY target using a relation name in GROUP BY clause +SELECT count(c) FROM test_missing_target +GROUP BY lower(test_missing_target.c) +ORDER BY lower(test_missing_target.c) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 032 +-- w/o existing GROUP BY target and w/o existing a different ORDER BY target +-- failure expected +SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 033 +-- w/o existing GROUP BY target and w/o existing same ORDER BY target +SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 034 +-- w/ existing GROUP BY target using a relation name in target +SELECT lower(test_missing_target.c), count(c) + FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 035 +-- w/o existing GROUP BY target +SELECT a FROM test_missing_target ORDER BY upper(d) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- w/o existing ORDER BY target +SELECT count(b) FROM test_missing_target + GROUP BY (b + 1) / 2 ORDER BY (b + 1) / 2 desc +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- group w/o existing GROUP BY and ORDER BY target under ambiguous condition +-- failure expected +SELECT count(x.a) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY b/2 ORDER BY b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +== 038 +-- group w/ existing GROUP BY target under ambiguous condition +SELECT x.b/2, count(x.b) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 ORDER BY x.b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +== 039 +-- group w/o existing GROUP BY target under ambiguous condition +-- failure expected due to ambiguous b in count(b) +SELECT count(b) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +== 040 +-- group w/o existing GROUP BY target under ambiguous condition +-- into a table +CREATE TABLE test_missing_target3 AS +SELECT count(x.b) +FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 ORDER BY x.b/2 +-- +TABLE: name="test_missing_target3" schema="" table="test_missing_target3" ctx=DDL +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 041 +SELECT * FROM test_missing_target3 +-- +TABLE: name="test_missing_target3" schema="" table="test_missing_target3" ctx=Select +STMT: SelectStmt +== 042 +-- Cleanup +DROP TABLE test_missing_target +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DDL +STMT: DropStmt +== 043 +DROP TABLE test_missing_target2 +-- +TABLE: name="test_missing_target2" schema="" table="test_missing_target2" ctx=DDL +STMT: DropStmt +== 044 +DROP TABLE test_missing_target3 +-- +TABLE: name="test_missing_target3" schema="" table="test_missing_target3" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/select_into.metadata.json b/parser/testdata/summary/postgres_regress/select_into.metadata.json new file mode 100644 index 0000000..0a7b0c8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_into.metadata.json @@ -0,0 +1,71 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select_into.test b/parser/testdata/summary/postgres_regress/select_into.test new file mode 100644 index 0000000..c93e453 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_into.test @@ -0,0 +1,449 @@ +== 001 +|-- +-- SELECT_INTO +|-- + +SELECT * + INTO TABLE sitmp1 + FROM onek + WHERE onek.unique1 < 2 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +== 002 +DROP TABLE sitmp1 +-- +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +STMT: DropStmt +== 003 +SELECT * + INTO TABLE sitmp1 + FROM onek2 + WHERE onek2.unique1 < 2 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +== 004 +DROP TABLE sitmp1 +-- +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +STMT: DropStmt +== 005 +|-- +-- SELECT INTO and INSERT permission, if owner is not allowed to insert. +|-- +CREATE SCHEMA selinto_schema +-- +STMT: CreateSchemaStmt +== 006 +CREATE USER regress_selinto_user +-- +STMT: CreateRoleStmt +== 007 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + REVOKE INSERT ON TABLES FROM regress_selinto_user +-- +STMT: AlterDefaultPrivilegesStmt +== 008 +GRANT ALL ON SCHEMA selinto_schema TO public +-- +STMT: GrantStmt +== 009 +SET SESSION AUTHORIZATION regress_selinto_user +-- +STMT: VariableSetStmt +== 010 +-- WITH DATA, passes. +CREATE TABLE selinto_schema.tbl_withdata1 (a) + AS SELECT generate_series(1,3) WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata1" schema="selinto_schema" table="tbl_withdata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 011 +INSERT INTO selinto_schema.tbl_withdata1 VALUES (4) +-- +TABLE: name="selinto_schema.tbl_withdata1" schema="selinto_schema" table="tbl_withdata1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_withdata2 (a) AS + SELECT generate_series(1,3) WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata2" schema="selinto_schema" table="tbl_withdata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 013 +-- WITH NO DATA, passes. +CREATE TABLE selinto_schema.tbl_nodata1 (a) AS + SELECT generate_series(1,3) WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata1" schema="selinto_schema" table="tbl_nodata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 014 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_nodata2 (a) AS + SELECT generate_series(1,3) WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata2" schema="selinto_schema" table="tbl_nodata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 015 +-- EXECUTE and WITH DATA, passes. +PREPARE data_sel AS SELECT generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 016 +CREATE TABLE selinto_schema.tbl_withdata3 (a) AS + EXECUTE data_sel WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata3" schema="selinto_schema" table="tbl_withdata3" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 017 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_withdata4 (a) AS + EXECUTE data_sel WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata4" schema="selinto_schema" table="tbl_withdata4" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 018 +-- EXECUTE and WITH NO DATA, passes. +CREATE TABLE selinto_schema.tbl_nodata3 (a) AS + EXECUTE data_sel WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata3" schema="selinto_schema" table="tbl_nodata3" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 019 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_nodata4 (a) AS + EXECUTE data_sel WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata4" schema="selinto_schema" table="tbl_nodata4" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 020 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 021 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + GRANT INSERT ON TABLES TO regress_selinto_user +-- +STMT: AlterDefaultPrivilegesStmt +== 022 +SET SESSION AUTHORIZATION regress_selinto_user +-- +STMT: VariableSetStmt +== 023 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 024 +DEALLOCATE data_sel +-- +STMT: DeallocateStmt +== 025 +DROP SCHEMA selinto_schema CASCADE +-- +STMT: DropStmt +== 026 +DROP USER regress_selinto_user +-- +STMT: DropRoleStmt +== 027 +-- Tests for WITH NO DATA and column name consistency +CREATE TABLE ctas_base (i int, j int) +-- +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=DDL +STMT: CreateStmt +== 028 +INSERT INTO ctas_base VALUES (1, 2) +-- +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 030 +-- Error +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base WITH NO DATA +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 031 +-- Error +CREATE TABLE ctas_nodata (ii, jj) AS SELECT i, j FROM ctas_base +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 032 +-- OK +CREATE TABLE ctas_nodata_2 (ii, jj) AS SELECT i, j FROM ctas_base WITH NO DATA +-- +TABLE: name="ctas_nodata_2" schema="" table="ctas_nodata_2" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 033 +-- OK +CREATE TABLE ctas_nodata_3 (ii) AS SELECT i, j FROM ctas_base +-- +TABLE: name="ctas_nodata_3" schema="" table="ctas_nodata_3" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 034 +-- OK +CREATE TABLE ctas_nodata_4 (ii) AS SELECT i, j FROM ctas_base WITH NO DATA +-- +TABLE: name="ctas_nodata_4" schema="" table="ctas_nodata_4" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 035 +-- OK +SELECT * FROM ctas_nodata +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=Select +STMT: SelectStmt +== 036 +SELECT * FROM ctas_nodata_2 +-- +TABLE: name="ctas_nodata_2" schema="" table="ctas_nodata_2" ctx=Select +STMT: SelectStmt +== 037 +SELECT * FROM ctas_nodata_3 +-- +TABLE: name="ctas_nodata_3" schema="" table="ctas_nodata_3" ctx=Select +STMT: SelectStmt +== 038 +SELECT * FROM ctas_nodata_4 +-- +TABLE: name="ctas_nodata_4" schema="" table="ctas_nodata_4" ctx=Select +STMT: SelectStmt +== 039 +DROP TABLE ctas_base +-- +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=DDL +STMT: DropStmt +== 040 +DROP TABLE ctas_nodata +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +STMT: DropStmt +== 041 +DROP TABLE ctas_nodata_2 +-- +TABLE: name="ctas_nodata_2" schema="" table="ctas_nodata_2" ctx=DDL +STMT: DropStmt +== 042 +DROP TABLE ctas_nodata_3 +-- +TABLE: name="ctas_nodata_3" schema="" table="ctas_nodata_3" ctx=DDL +STMT: DropStmt +== 043 +DROP TABLE ctas_nodata_4 +-- +TABLE: name="ctas_nodata_4" schema="" table="ctas_nodata_4" ctx=DDL +STMT: DropStmt +== 044 +|-- +-- CREATE TABLE AS/SELECT INTO as last command in a SQL function +-- have been known to cause problems +|-- +CREATE FUNCTION make_table() RETURNS VOID +AS $$ + CREATE TABLE created_table AS SELECT * FROM int8_tbl; +$$ LANGUAGE SQL +-- +FUNCTION: name="make_table" function="make_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 045 +SELECT make_table() +-- +FUNCTION: name="make_table" function="make_table" schema="" ctx=Call +STMT: SelectStmt +== 046 +SELECT * FROM created_table +-- +TABLE: name="created_table" schema="" table="created_table" ctx=Select +STMT: SelectStmt +== 047 +-- Try EXPLAIN ANALYZE SELECT INTO and EXPLAIN ANALYZE CREATE TABLE AS +-- WITH NO DATA, but hide the outputs since they won't be stable. +DO $$ +BEGIN + EXECUTE 'EXPLAIN ANALYZE SELECT * INTO TABLE easi FROM int8_tbl'; + EXECUTE 'EXPLAIN ANALYZE CREATE TABLE easi2 AS SELECT * FROM int8_tbl WITH NO DATA'; +END$$ +-- +STMT: DoStmt +== 048 +DROP TABLE created_table +-- +TABLE: name="created_table" schema="" table="created_table" ctx=DDL +STMT: DropStmt +== 049 +DROP TABLE easi, easi2 +-- +TABLE: name="easi" schema="" table="easi" ctx=DDL +TABLE: name="easi2" schema="" table="easi2" ctx=DDL +STMT: DropStmt +== 050 +|-- +-- Disallowed uses of SELECT ... INTO. All should fail +|-- +DECLARE foo CURSOR FOR SELECT 1 INTO int4_tbl +-- +STMT: DeclareCursorStmt +== 051 +COPY (SELECT 1 INTO frak UNION SELECT 2) TO 'blob' +-- +TABLE: name="frak" schema="" table="frak" ctx=DDL +STMT: CopyStmt +== 052 +SELECT * FROM (SELECT 1 INTO f) bar +-- +TABLE: name="f" schema="" table="f" ctx=DDL +STMT: SelectStmt +== 053 +CREATE VIEW foo AS SELECT 1 INTO int4_tbl +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 054 +INSERT INTO int4_tbl SELECT 1 INTO f +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +TABLE: name="f" schema="" table="f" ctx=DDL +STMT: InsertStmt +STMT: SelectStmt +== 055 +-- Test CREATE TABLE AS ... IF NOT EXISTS +CREATE TABLE ctas_ine_tbl AS SELECT 1 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 056 +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 057 +-- error +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 058 +-- ok +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 059 +-- error +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 060 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 061 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 062 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 063 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 064 +-- ok +PREPARE ctas_ine_query AS SELECT 1 / 0 +-- +STMT: PrepareStmt +STMT: SelectStmt +== 065 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE ctas_ine_tbl AS EXECUTE ctas_ine_query +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 066 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS EXECUTE ctas_ine_query +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 067 +-- ok +DROP TABLE ctas_ine_tbl +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/select_parallel.metadata.json b/parser/testdata/summary/postgres_regress/select_parallel.metadata.json new file mode 100644 index 0000000..60ff1c2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_parallel.metadata.json @@ -0,0 +1,239 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select_parallel.test b/parser/testdata/summary/postgres_regress/select_parallel.test new file mode 100644 index 0000000..7ee0734 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_parallel.test @@ -0,0 +1,1540 @@ +== 001 +|-- +-- PARALLEL +|-- + +create function sp_parallel_restricted(int) returns int as + $$begin return $1; end$$ language plpgsql parallel restricted +-- +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +begin +-- +STMT: TransactionStmt +== 003 +-- encourage use of parallel plans +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +== 004 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +== 005 +set min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +== 006 +set max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +== 007 +-- Parallel Append with partial-subplans +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 008 +select round(avg(aa)), sum(aa) from a_star a1 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a1"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 009 +-- Parallel Append with both partial and non-partial subplans +alter table c_star set (parallel_workers = 0) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: AlterTableStmt +== 010 +alter table d_star set (parallel_workers = 0) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: AlterTableStmt +== 011 +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 012 +select round(avg(aa)), sum(aa) from a_star a2 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a2"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- Parallel Append with only non-partial subplans +alter table a_star set (parallel_workers = 0) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: AlterTableStmt +== 014 +alter table b_star set (parallel_workers = 0) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: AlterTableStmt +== 015 +alter table e_star set (parallel_workers = 0) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: AlterTableStmt +== 016 +alter table f_star set (parallel_workers = 0) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: AlterTableStmt +== 017 +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 018 +select round(avg(aa)), sum(aa) from a_star a3 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a3"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- Disable Parallel Append +alter table a_star reset (parallel_workers) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: AlterTableStmt +== 020 +alter table b_star reset (parallel_workers) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: AlterTableStmt +== 021 +alter table c_star reset (parallel_workers) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: AlterTableStmt +== 022 +alter table d_star reset (parallel_workers) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: AlterTableStmt +== 023 +alter table e_star reset (parallel_workers) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: AlterTableStmt +== 024 +alter table f_star reset (parallel_workers) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: AlterTableStmt +== 025 +set enable_parallel_append to off +-- +STMT: VariableSetStmt +== 026 +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 027 +select round(avg(aa)), sum(aa) from a_star a4 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a4"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 028 +reset enable_parallel_append +-- +STMT: VariableSetStmt +== 029 +-- Parallel Append that runs serially +create function sp_test_func() returns setof text as +$$ select 'foo'::varchar union all select 'bar'::varchar $$ +language sql stable +-- +FUNCTION: name="sp_test_func" function="sp_test_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 030 +select sp_test_func() order by 1 +-- +FUNCTION: name="sp_test_func" function="sp_test_func" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- Parallel Append is not to be used when the subpath depends on the outer param +create table part_pa_test(a int, b int) partition by range(a) +-- +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=DDL +STMT: CreateStmt +== 032 +create table part_pa_test_p1 partition of part_pa_test for values from (minvalue) to (0) +-- +TABLE: name="part_pa_test_p1" schema="" table="part_pa_test_p1" ctx=DDL +STMT: CreateStmt +== 033 +create table part_pa_test_p2 partition of part_pa_test for values from (0) to (maxvalue) +-- +TABLE: name="part_pa_test_p2" schema="" table="part_pa_test_p2" ctx=DDL +STMT: CreateStmt +== 034 +explain (costs off) + select (select max((select pa1.b from part_pa_test pa1 where pa1.a = pa2.a))) + from part_pa_test pa2 +-- +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=Select +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=Select +ALIAS: "pa1"="part_pa_test" +ALIAS: "pa2"="part_pa_test" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="pa1" column="a" +FILTER: schema="" table="pa2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 035 +drop table part_pa_test +-- +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=DDL +STMT: DropStmt +== 036 +-- test with leader participation disabled +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 037 +explain (costs off) + select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 038 +select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 039 +-- 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 +-- +STMT: VariableSetStmt +== 040 +explain (costs off) + select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 041 +select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +== 042 +reset max_parallel_workers +-- +STMT: VariableSetStmt +== 043 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +== 044 +-- test that parallel_restricted function doesn't run in worker +alter table tenk1 set (parallel_workers = 4) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +== 045 +explain (verbose, costs off) +select sp_parallel_restricted(unique1) from tenk1 + where stringu1 = 'GRAAAA' order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +-- test parallel plan when group by expression is in target list. +explain (costs off) + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 047 +select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 048 +explain (costs off) + select stringu1, count(*) from tenk1 group by stringu1 order by stringu1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 049 +-- 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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=Call +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 050 +-- test prepared statement +prepare tenk1_count(integer) As select count((unique1)) from tenk1 where hundred > $1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: PrepareStmt +STMT: SelectStmt +== 051 +explain (costs off) execute tenk1_count(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 052 +execute tenk1_count(1) +-- +STMT: ExecuteStmt +== 053 +deallocate tenk1_count +-- +STMT: DeallocateStmt +== 054 +-- test parallel plans for queries containing un-correlated subplans. +alter table tenk2 set (parallel_workers = 0) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 055 +explain (costs off) + select count(*) from tenk1 where (two, four) not in + (select hundred, thousand from tenk2 where thousand > 100) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="two" +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 056 +select count(*) from tenk1 where (two, four) not in + (select hundred, thousand from tenk2 where thousand > 100) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="two" +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 057 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 058 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 059 +-- test parallel plan for a query containing initplan. +set enable_indexscan = off +-- +STMT: VariableSetStmt +== 060 +set enable_indexonlyscan = off +-- +STMT: VariableSetStmt +== 061 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +== 062 +alter table tenk2 set (parallel_workers = 2) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 063 +explain (costs off) + select count(*) from tenk1 + where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 064 +select count(*) from tenk1 + where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: SelectStmt +== 065 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 066 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +== 067 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 068 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 069 +-- test parallel index scans. +set enable_seqscan to off +-- +STMT: VariableSetStmt +== 070 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +== 071 +set random_page_cost = 2 +-- +STMT: VariableSetStmt +== 072 +explain (costs off) + select count((unique1)) from tenk1 where hundred > 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 073 +select count((unique1)) from tenk1 where hundred > 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 074 +-- Parallel ScalarArrayOp index scan +explain (costs off) + select count((unique1)) from tenk1 + where hundred = any ((select array_agg(i) from generate_series(1, 100, 15) i)::int[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 075 +select count((unique1)) from tenk1 +where hundred = any ((select array_agg(i) from generate_series(1, 100, 15) i)::int[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 076 +-- test parallel index-only scans. +explain (costs off) + select count(*) from tenk1 where thousand > 95 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 077 +select count(*) from tenk1 where thousand > 95 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 078 +-- test rescan cases too +set enable_material = false +-- +STMT: VariableSetStmt +== 079 +explain (costs off) +select * from + (select count(unique1) from tenk1 where hundred > 10) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 080 +select * from + (select count(unique1) from tenk1 where hundred > 10) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +== 081 +explain (costs off) +select * from + (select count(*) from tenk1 where thousand > 99) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 082 +select * from + (select count(*) from tenk1 where thousand > 99) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +== 083 +-- test rescans for a Limit node with a parallel node beneath it. +reset enable_seqscan +-- +STMT: VariableSetStmt +== 084 +set enable_indexonlyscan to off +-- +STMT: VariableSetStmt +== 085 +set enable_indexscan to off +-- +STMT: VariableSetStmt +== 086 +alter table tenk1 set (parallel_workers = 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +== 087 +alter table tenk2 set (parallel_workers = 1) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 088 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 089 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: SelectStmt +== 090 +--reset the value of workers for each table as it was before this test. +alter table tenk1 set (parallel_workers = 4) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +== 091 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 092 +reset enable_material +-- +STMT: VariableSetStmt +== 093 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 094 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +== 095 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 096 +-- test parallel bitmap heap scan. +set enable_seqscan to off +-- +STMT: VariableSetStmt +== 097 +set enable_indexscan to off +-- +STMT: VariableSetStmt +== 098 +set enable_hashjoin to off +-- +STMT: VariableSetStmt +== 099 +set enable_mergejoin to off +-- +STMT: VariableSetStmt +== 100 +set enable_material to off +-- +STMT: VariableSetStmt +== 101 +-- test prefetching, if the platform allows it +DO $$ +BEGIN + SET effective_io_concurrency = 50; +EXCEPTION WHEN invalid_parameter_value THEN +END $$ +-- +STMT: DoStmt +== 102 +set work_mem='64kB' +-- +STMT: VariableSetStmt +== 103 +--set small work mem to force lossy pages +explain (costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="hundred" +FILTER: schema="" table="tenk2" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 104 +select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="hundred" +FILTER: schema="" table="tenk2" column="thousand" +STMT: SelectStmt +== 105 +create table bmscantest (a int, t text) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: CreateStmt +== 106 +insert into bmscantest select r, 'fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' FROM generate_series(1,100000) r +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 107 +create index i_bmtest ON bmscantest(a) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: IndexStmt +== 108 +select count(*) from bmscantest where a>1 +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 109 +-- test accumulation of stats for parallel nodes +reset enable_seqscan +-- +STMT: VariableSetStmt +== 110 +alter table tenk2 set (parallel_workers = 0) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 111 +explain (analyze, timing off, summary off, costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 + and tenk2.thousand=0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="hundred" +FILTER: schema="" table="tenk2" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +== 112 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +== 113 +reset work_mem +-- +STMT: VariableSetStmt +== 114 +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; +$$ +-- +FUNCTION: name="explain_parallel_sort_stats" function="explain_parallel_sort_stats" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 115 +select * from explain_parallel_sort_stats() +-- +FUNCTION: name="explain_parallel_sort_stats" function="explain_parallel_sort_stats" schema="" ctx=Call +STMT: SelectStmt +== 116 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 117 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 118 +reset enable_mergejoin +-- +STMT: VariableSetStmt +== 119 +reset enable_material +-- +STMT: VariableSetStmt +== 120 +reset effective_io_concurrency +-- +STMT: VariableSetStmt +== 121 +drop table bmscantest +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: DropStmt +== 122 +drop function explain_parallel_sort_stats() +-- +FUNCTION: name="explain_parallel_sort_stats" function="explain_parallel_sort_stats" schema="" ctx=DDL +STMT: DropStmt +== 123 +-- test parallel merge join path. +set enable_hashjoin to off +-- +STMT: VariableSetStmt +== 124 +set enable_nestloop to off +-- +STMT: VariableSetStmt +== 125 +explain (costs off) + select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="tenk2" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 126 +select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="tenk2" column="unique1" +STMT: SelectStmt +== 127 +reset enable_hashjoin +-- +STMT: VariableSetStmt +== 128 +reset enable_nestloop +-- +STMT: VariableSetStmt +== 129 +-- test gather merge +set enable_hashagg = false +-- +STMT: VariableSetStmt +== 130 +explain (costs off) + select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 131 +select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 132 +--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 +-- +FUNCTION: name="sp_simple_func" function="sp_simple_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 133 +explain (costs off, verbose) + select ten, sp_simple_func(ten) from tenk1 where ten < 100 order by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sp_simple_func" function="sp_simple_func" schema="" ctx=Call +FILTER: schema="" table="" column="ten" +STMT: ExplainStmt +STMT: SelectStmt +== 134 +drop function sp_simple_func(integer) +-- +FUNCTION: name="sp_simple_func" function="sp_simple_func" schema="" ctx=DDL +STMT: DropStmt +== 135 +-- test handling of SRFs in targetlist (bug in 10.0) + +explain (costs off) + select count(*), generate_series(1,2) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 136 +select count(*), generate_series(1,2) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 137 +-- test gather merge with parallel leader participation disabled +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +== 138 +explain (costs off) + select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 139 +select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 140 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +== 141 +--test rescan behavior of gather merge +set enable_material = false +-- +STMT: VariableSetStmt +== 142 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 143 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 144 +reset enable_material +-- +STMT: VariableSetStmt +== 145 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 146 +-- check parallelized int8 aggregate (bug #14897) +explain (costs off) +select avg(unique1::int8) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 147 +select avg(unique1::int8) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 148 +-- gather merge test with a LIMIT +explain (costs off) + select fivethous from tenk1 order by fivethous limit 4 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 149 +select fivethous from tenk1 order by fivethous limit 4 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +== 150 +-- gather merge test with 0 worker +set max_parallel_workers = 0 +-- +STMT: VariableSetStmt +== 151 +explain (costs off) + select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 152 +select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +== 153 +-- 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 +-- +STMT: VariableSetStmt +== 154 +explain (costs off) + select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 155 +select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +== 156 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +== 157 +reset max_parallel_workers +-- +STMT: VariableSetStmt +== 158 +create function parallel_safe_volatile(a int) returns int as + $$ begin return a; end; $$ parallel safe volatile language plpgsql +-- +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 159 +-- Test gather merge atop of a sort of a partial path +explain (costs off) +select * from tenk1 where four = 2 +order by four, hundred, parallel_safe_volatile(thousand) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=Call +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 160 +-- Test gather merge atop of an incremental sort a of partial path +set min_parallel_index_scan_size = 0 +-- +STMT: VariableSetStmt +== 161 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 162 +explain (costs off) +select * from tenk1 where four = 2 +order by four, hundred, parallel_safe_volatile(thousand) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=Call +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +== 163 +reset min_parallel_index_scan_size +-- +STMT: VariableSetStmt +== 164 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 165 +-- Test GROUP BY with a gather merge path atop of a sort of a partial path +explain (costs off) +select count(*) from tenk1 +group by twenty, parallel_safe_volatile(two) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 166 +drop function parallel_safe_volatile(int) +-- +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=DDL +STMT: DropStmt +== 167 +SAVEPOINT settings +-- +STMT: TransactionStmt +== 168 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 169 +explain (costs off) + select stringu1::int2 from tenk1 where unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 170 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +== 171 +-- 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; +$$ +-- +FUNCTION: name="make_record" function="make_record" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 172 +SAVEPOINT settings +-- +STMT: TransactionStmt +== 173 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 174 +SELECT make_record(x) FROM (SELECT generate_series(1, 5) x) ss ORDER BY x +-- +FUNCTION: name="make_record" function="make_record" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 175 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +== 176 +DROP function make_record(n int) +-- +FUNCTION: name="make_record" function="make_record" schema="" ctx=DDL +STMT: DropStmt +== 177 +-- test the sanity of parallel query after the active role is dropped. +drop role if exists regress_parallel_worker +-- +STMT: DropRoleStmt +== 178 +create role regress_parallel_worker +-- +STMT: CreateRoleStmt +== 179 +set role regress_parallel_worker +-- +STMT: VariableSetStmt +== 180 +reset session authorization +-- +STMT: VariableSetStmt +== 181 +drop role regress_parallel_worker +-- +STMT: DropRoleStmt +== 182 +set debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 183 +select count(*) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 184 +reset debug_parallel_query +-- +STMT: VariableSetStmt +== 185 +reset role +-- +STMT: VariableSetStmt +== 186 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="two" +STMT: ExplainStmt +STMT: SelectStmt +== 187 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="two" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +== 188 +-- to increase the parallel query test coverage +SAVEPOINT settings +-- +STMT: TransactionStmt +== 189 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 190 +EXPLAIN (analyze, timing off, summary off, costs off) SELECT * FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 191 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +== 192 +-- provoke error in worker +-- (make the error message long enough to require multiple bufferloads) +SAVEPOINT settings +-- +STMT: TransactionStmt +== 193 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 194 +select (stringu1 || repeat('abcd', 5000))::int2 from tenk1 where unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 195 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +== 196 +-- test interaction with set-returning functions +SAVEPOINT settings +-- +STMT: TransactionStmt +== 197 +-- multiple subqueries under a single Gather node +-- must set parallel_setup_cost > 0 to discourage multiple Gather nodes +SET LOCAL parallel_setup_cost = 10 +-- +STMT: VariableSetStmt +== 198 +EXPLAIN (COSTS OFF) +SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1 +UNION ALL +SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +== 199 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +== 200 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="fivethous" +STMT: ExplainStmt +STMT: SelectStmt +== 201 +-- test interaction with SRFs +SELECT * FROM information_schema.foreign_data_wrapper_options +ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_data_wrapper_options" schema="information_schema" table="foreign_data_wrapper_options" ctx=Select +STMT: SelectStmt +== 202 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT generate_series(1, two), array(select generate_series(1, two)) + FROM tenk1 ORDER BY tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 203 +-- must disallow pushing sort below gather when pathkey contains an SRF +EXPLAIN (VERBOSE, COSTS OFF) +SELECT unnest(ARRAY[]::integer[]) + 1 AS pathkey + FROM tenk1 t1 JOIN tenk1 t2 ON TRUE + ORDER BY pathkey +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 204 +-- 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 +-- +FUNCTION: name="make_some_array" function="make_some_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 205 +CREATE TABLE fooarr(f1 text, f2 int[], f3 text) +-- +TABLE: name="fooarr" schema="" table="fooarr" ctx=DDL +STMT: CreateStmt +== 206 +INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one') +-- +TABLE: name="fooarr" schema="" table="fooarr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 207 +PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2 +-- +TABLE: name="fooarr" schema="" table="fooarr" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: PrepareStmt +STMT: SelectStmt +== 208 +EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2)) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +== 209 +EXECUTE pstmt('1', make_some_array(1,2)) +-- +STMT: ExecuteStmt +== 210 +DEALLOCATE pstmt +-- +STMT: DeallocateStmt +== 211 +-- test interaction between subquery and partial_paths +CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1 +-- +TABLE: name="tenk1_vw_sec" schema="" table="tenk1_vw_sec" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 212 +EXPLAIN (COSTS OFF) +SELECT 1 FROM tenk1_vw_sec + WHERE (SELECT sum(f1) FROM int4_tbl WHERE f1 < unique1) < 100 +-- +TABLE: name="tenk1_vw_sec" schema="" table="tenk1_vw_sec" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 213 +rollback +-- +STMT: TransactionStmt +== 214 +-- test that function option SET ROLE works in parallel workers. +create role regress_parallel_worker +-- +STMT: CreateRoleStmt +== 215 +create function set_and_report_role() returns text as + $$ select current_setting('role') $$ language sql parallel safe + set role = regress_parallel_worker +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 216 +create function set_role_and_error(int) returns int as + $$ select 1 / $1 $$ language sql parallel safe + set role = regress_parallel_worker +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 217 +set debug_parallel_query = 0 +-- +STMT: VariableSetStmt +== 218 +select set_and_report_role() +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=Call +STMT: SelectStmt +== 219 +select set_role_and_error(0) +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=Call +STMT: SelectStmt +== 220 +set debug_parallel_query = 1 +-- +STMT: VariableSetStmt +== 221 +select set_and_report_role() +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=Call +STMT: SelectStmt +== 222 +select set_role_and_error(0) +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=Call +STMT: SelectStmt +== 223 +reset debug_parallel_query +-- +STMT: VariableSetStmt +== 224 +drop function set_and_report_role() +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=DDL +STMT: DropStmt +== 225 +drop function set_role_and_error(int) +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=DDL +STMT: DropStmt +== 226 +drop role regress_parallel_worker +-- +STMT: DropRoleStmt +== 227 +-- don't freeze in ParallelFinish while holding an LWLock +BEGIN +-- +STMT: TransactionStmt +== 228 +CREATE FUNCTION my_cmp (int4, int4) +RETURNS int LANGUAGE sql AS +$$ + SELECT + CASE WHEN $1 < $2 THEN -1 + WHEN $1 > $2 THEN 1 + ELSE 0 + END; +$$ +-- +FUNCTION: name="my_cmp" function="my_cmp" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 229 +CREATE TABLE parallel_hang (i int4) +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DDL +STMT: CreateStmt +== 230 +INSERT INTO parallel_hang + (SELECT * FROM generate_series(1, 400) gs) +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 231 +CREATE OPERATOR CLASS int4_custom_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4, int4), OPERATOR 2 <= (int4, int4), + OPERATOR 3 = (int4, int4), OPERATOR 4 >= (int4, int4), + OPERATOR 5 > (int4, int4), FUNCTION 1 my_cmp(int4, int4) +-- +STMT: CreateOpClassStmt +== 232 +CREATE UNIQUE INDEX parallel_hang_idx + ON parallel_hang + USING btree (i int4_custom_ops) +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DDL +STMT: IndexStmt +== 233 +SET debug_parallel_query = on +-- +STMT: VariableSetStmt +== 234 +DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420 +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DML +STMT: DeleteStmt +== 235 +ROLLBACK +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/select_views.metadata.json b/parser/testdata/summary/postgres_regress/select_views.metadata.json new file mode 100644 index 0000000..f37dd99 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_views.metadata.json @@ -0,0 +1,56 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052" + ] +} diff --git a/parser/testdata/summary/postgres_regress/select_views.test b/parser/testdata/summary/postgres_regress/select_views.test new file mode 100644 index 0000000..f8c677d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/select_views.test @@ -0,0 +1,449 @@ +== 001 +|-- +-- SELECT_VIEWS +-- test the views defined in CREATE_VIEWS +|-- + +SELECT * FROM street +-- +TABLE: name="street" schema="" table="street" ctx=Select +STMT: SelectStmt +== 002 +SELECT name, #thepath FROM iexit ORDER BY name COLLATE "C", 2 +-- +TABLE: name="iexit" schema="" table="iexit" ctx=Select +STMT: SelectStmt +== 003 +SELECT * FROM toyemp WHERE name = 'sharon' +-- +TABLE: name="toyemp" schema="" table="toyemp" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 004 +|-- +-- Test for Leaky view scenario +|-- +CREATE ROLE regress_alice +-- +STMT: CreateRoleStmt +== 005 +CREATE FUNCTION f_leak (text) + RETURNS bool LANGUAGE 'plpgsql' COST 0.0000001 + AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END' +-- +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 006 +CREATE TABLE customer ( + cid int primary key, + name text not null, + tel text, + passwd text +) +-- +TABLE: name="customer" schema="" table="customer" ctx=DDL +STMT: CreateStmt +== 007 +CREATE TABLE credit_card ( + cid int references customer(cid), + cnum text, + climit int +) +-- +TABLE: name="credit_card" schema="" table="credit_card" ctx=DDL +STMT: CreateStmt +== 008 +CREATE TABLE credit_usage ( + cid int references customer(cid), + ymd date, + usage int +) +-- +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=DDL +STMT: CreateStmt +== 009 +INSERT INTO customer + VALUES (101, 'regress_alice', '+81-12-3456-7890', 'passwd123'), + (102, 'regress_bob', '+01-234-567-8901', 'beafsteak'), + (103, 'regress_eve', '+49-8765-43210', 'hamburger') +-- +TABLE: name="customer" schema="" table="customer" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO credit_card + VALUES (101, '1111-2222-3333-4444', 4000), + (102, '5555-6666-7777-8888', 3000), + (103, '9801-2345-6789-0123', 2000) +-- +TABLE: name="credit_card" schema="" table="credit_card" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO credit_usage + VALUES (101, '2011-09-15', 120), + (101, '2011-10-05', 90), + (101, '2011-10-18', 110), + (101, '2011-10-21', 200), + (101, '2011-11-10', 80), + (102, '2011-09-22', 300), + (102, '2011-10-12', 120), + (102, '2011-10-28', 200), + (103, '2011-10-15', 480) +-- +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +CREATE VIEW my_property_normal AS + SELECT * FROM customer WHERE name = current_user +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +FILTER: schema="" table="" column="name" +STMT: ViewStmt +STMT: SelectStmt +== 013 +CREATE VIEW my_property_secure WITH (security_barrier) AS + SELECT * FROM customer WHERE name = current_user +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +FILTER: schema="" table="" column="name" +STMT: ViewStmt +STMT: SelectStmt +== 014 +CREATE VIEW my_credit_card_normal AS + SELECT * FROM customer l NATURAL JOIN credit_card r + WHERE l.name = current_user +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +TABLE: name="credit_card" schema="" table="credit_card" ctx=Select +ALIAS: "l"="customer" +ALIAS: "r"="credit_card" +FILTER: schema="" table="l" column="name" +STMT: ViewStmt +STMT: SelectStmt +== 015 +CREATE VIEW my_credit_card_secure WITH (security_barrier) AS + SELECT * FROM customer l NATURAL JOIN credit_card r + WHERE l.name = current_user +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +TABLE: name="credit_card" schema="" table="credit_card" ctx=Select +ALIAS: "l"="customer" +ALIAS: "r"="credit_card" +FILTER: schema="" table="l" column="name" +STMT: ViewStmt +STMT: SelectStmt +== 016 +CREATE VIEW my_credit_card_usage_normal AS + SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=DDL +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=Select +ALIAS: "l"="my_credit_card_secure" +ALIAS: "r"="credit_usage" +STMT: ViewStmt +STMT: SelectStmt +== 017 +CREATE VIEW my_credit_card_usage_secure WITH (security_barrier) AS + SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=DDL +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=Select +ALIAS: "l"="my_credit_card_secure" +ALIAS: "r"="credit_usage" +STMT: ViewStmt +STMT: SelectStmt +== 018 +GRANT SELECT ON my_property_normal TO public +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=DDL +STMT: GrantStmt +== 019 +GRANT SELECT ON my_property_secure TO public +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=DDL +STMT: GrantStmt +== 020 +GRANT SELECT ON my_credit_card_normal TO public +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=DDL +STMT: GrantStmt +== 021 +GRANT SELECT ON my_credit_card_secure TO public +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=DDL +STMT: GrantStmt +== 022 +GRANT SELECT ON my_credit_card_usage_normal TO public +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=DDL +STMT: GrantStmt +== 023 +GRANT SELECT ON my_credit_card_usage_secure TO public +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=DDL +STMT: GrantStmt +== 024 +|-- +-- Run leaky view scenarios +|-- +SET SESSION AUTHORIZATION regress_alice +-- +STMT: VariableSetStmt +== 025 +|-- +-- scenario: if a qualifier with tiny-cost is given, it shall be launched +-- prior to the security policy of the view. +|-- +SELECT * FROM my_property_normal WHERE f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +== 026 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal WHERE f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +== 027 +SELECT * FROM my_property_secure WHERE f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +== 028 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +== 029 +|-- +-- scenario: qualifiers can be pushed down if they contain leaky functions, +-- provided they aren't passed data from inside the view. +|-- +SELECT * FROM my_property_normal v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +ALIAS: "v"="my_property_normal" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +== 030 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +ALIAS: "v"="my_property_normal" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +== 031 +SELECT * FROM my_property_secure v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +ALIAS: "v"="my_property_secure" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +== 032 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +ALIAS: "v"="my_property_secure" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +== 033 +|-- +-- scenario: if a qualifier references only one-side of a particular join- +-- tree, it shall be distributed to the most deep scan plan as +-- possible as we can. +|-- +SELECT * FROM my_credit_card_normal WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: SelectStmt +== 034 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_normal WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: ExplainStmt +STMT: SelectStmt +== 035 +SELECT * FROM my_credit_card_secure WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: SelectStmt +== 036 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: ExplainStmt +STMT: SelectStmt +== 037 +|-- +-- scenario: an external qualifier can be pushed-down by in-front-of the +-- views with "security_barrier" attribute, except for operators +-- implemented with leakproof functions. +|-- +SELECT * FROM my_credit_card_usage_normal + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: SelectStmt +== 038 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_normal + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +SELECT * FROM my_credit_card_usage_secure + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: SelectStmt +== 040 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_secure + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: ExplainStmt +STMT: SelectStmt +== 041 +|-- +-- Test for the case when security_barrier gets changed between rewriter +-- and planner stage. +|-- +PREPARE p1 AS SELECT * FROM my_property_normal WHERE f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: PrepareStmt +STMT: SelectStmt +== 042 +PREPARE p2 AS SELECT * FROM my_property_secure WHERE f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: PrepareStmt +STMT: SelectStmt +== 043 +EXECUTE p1 +-- +STMT: ExecuteStmt +== 044 +EXECUTE p2 +-- +STMT: ExecuteStmt +== 045 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 046 +ALTER VIEW my_property_normal SET (security_barrier=true) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=DDL +STMT: AlterTableStmt +== 047 +ALTER VIEW my_property_secure SET (security_barrier=false) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=DDL +STMT: AlterTableStmt +== 048 +SET SESSION AUTHORIZATION regress_alice +-- +STMT: VariableSetStmt +== 049 +EXECUTE p1 +-- +STMT: ExecuteStmt +== 050 +-- To be perform as a view with security-barrier +EXECUTE p2 +-- +STMT: ExecuteStmt +== 051 +-- To be perform as a view without security-barrier + +-- Cleanup. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 052 +DROP ROLE regress_alice +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/sequence.metadata.json b/parser/testdata/summary/postgres_regress/sequence.metadata.json new file mode 100644 index 0000000..38ac4c2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sequence.metadata.json @@ -0,0 +1,264 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260" + ] +} diff --git a/parser/testdata/summary/postgres_regress/sequence.test b/parser/testdata/summary/postgres_regress/sequence.test new file mode 100644 index 0000000..7360fb5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sequence.test @@ -0,0 +1,1314 @@ +== 001 +|-- +-- CREATE SEQUENCE +|-- + +-- various error cases +CREATE SEQUENCE sequence_testx INCREMENT BY 0 +-- +STMT: CreateSeqStmt +== 002 +CREATE SEQUENCE sequence_testx INCREMENT BY -1 MINVALUE 20 +-- +STMT: CreateSeqStmt +== 003 +CREATE SEQUENCE sequence_testx INCREMENT BY 1 MAXVALUE -20 +-- +STMT: CreateSeqStmt +== 004 +CREATE SEQUENCE sequence_testx INCREMENT BY -1 START 10 +-- +STMT: CreateSeqStmt +== 005 +CREATE SEQUENCE sequence_testx INCREMENT BY 1 START -10 +-- +STMT: CreateSeqStmt +== 006 +CREATE SEQUENCE sequence_testx CACHE 0 +-- +STMT: CreateSeqStmt +== 007 +-- OWNED BY errors +CREATE SEQUENCE sequence_testx OWNED BY nobody +-- +STMT: CreateSeqStmt +== 008 +-- nonsense word +CREATE SEQUENCE sequence_testx OWNED BY pg_class_oid_index.oid +-- +STMT: CreateSeqStmt +== 009 +-- not a table +CREATE SEQUENCE sequence_testx OWNED BY pg_class.relname +-- +STMT: CreateSeqStmt +== 010 +-- not same schema +CREATE TABLE sequence_test_table (a int) +-- +TABLE: name="sequence_test_table" schema="" table="sequence_test_table" ctx=DDL +STMT: CreateStmt +== 011 +CREATE SEQUENCE sequence_testx OWNED BY sequence_test_table.b +-- +STMT: CreateSeqStmt +== 012 +-- wrong column +DROP TABLE sequence_test_table +-- +TABLE: name="sequence_test_table" schema="" table="sequence_test_table" ctx=DDL +STMT: DropStmt +== 013 +-- sequence data types +CREATE SEQUENCE sequence_test5 AS integer +-- +STMT: CreateSeqStmt +== 014 +CREATE SEQUENCE sequence_test6 AS smallint +-- +STMT: CreateSeqStmt +== 015 +CREATE SEQUENCE sequence_test7 AS bigint +-- +STMT: CreateSeqStmt +== 016 +CREATE SEQUENCE sequence_test8 AS integer MAXVALUE 100000 +-- +STMT: CreateSeqStmt +== 017 +CREATE SEQUENCE sequence_test9 AS integer INCREMENT BY -1 +-- +STMT: CreateSeqStmt +== 018 +CREATE SEQUENCE sequence_test10 AS integer MINVALUE -100000 START 1 +-- +STMT: CreateSeqStmt +== 019 +CREATE SEQUENCE sequence_test11 AS smallint +-- +STMT: CreateSeqStmt +== 020 +CREATE SEQUENCE sequence_test12 AS smallint INCREMENT -1 +-- +STMT: CreateSeqStmt +== 021 +CREATE SEQUENCE sequence_test13 AS smallint MINVALUE -32768 +-- +STMT: CreateSeqStmt +== 022 +CREATE SEQUENCE sequence_test14 AS smallint MAXVALUE 32767 INCREMENT -1 +-- +STMT: CreateSeqStmt +== 023 +CREATE SEQUENCE sequence_testx AS text +-- +STMT: CreateSeqStmt +== 024 +CREATE SEQUENCE sequence_testx AS nosuchtype +-- +STMT: CreateSeqStmt +== 025 +CREATE SEQUENCE sequence_testx AS smallint MAXVALUE 100000 +-- +STMT: CreateSeqStmt +== 026 +CREATE SEQUENCE sequence_testx AS smallint MINVALUE -100000 +-- +STMT: CreateSeqStmt +== 027 +ALTER SEQUENCE sequence_test5 AS smallint +-- +STMT: AlterSeqStmt +== 028 +-- success, max will be adjusted +ALTER SEQUENCE sequence_test8 AS smallint +-- +STMT: AlterSeqStmt +== 029 +-- fail, max has to be adjusted +ALTER SEQUENCE sequence_test8 AS smallint MAXVALUE 20000 +-- +STMT: AlterSeqStmt +== 030 +-- ok now +ALTER SEQUENCE sequence_test9 AS smallint +-- +STMT: AlterSeqStmt +== 031 +-- success, min will be adjusted +ALTER SEQUENCE sequence_test10 AS smallint +-- +STMT: AlterSeqStmt +== 032 +-- fail, min has to be adjusted +ALTER SEQUENCE sequence_test10 AS smallint MINVALUE -20000 +-- +STMT: AlterSeqStmt +== 033 +-- ok now + +ALTER SEQUENCE sequence_test11 AS int +-- +STMT: AlterSeqStmt +== 034 +-- max will be adjusted +ALTER SEQUENCE sequence_test12 AS int +-- +STMT: AlterSeqStmt +== 035 +-- min will be adjusted +ALTER SEQUENCE sequence_test13 AS int +-- +STMT: AlterSeqStmt +== 036 +-- min and max will be adjusted +ALTER SEQUENCE sequence_test14 AS int +-- +STMT: AlterSeqStmt +== 037 +-- min and max will be adjusted + +--- +--- test creation of SERIAL column +--- + +CREATE TABLE serialTest1 (f1 text, f2 serial) +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DDL +STMT: CreateStmt +== 038 +INSERT INTO serialTest1 VALUES ('foo') +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO serialTest1 VALUES ('bar') +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO serialTest1 VALUES ('force', 100) +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO serialTest1 VALUES ('wrong', NULL) +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +SELECT * FROM serialTest1 +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=Select +STMT: SelectStmt +== 043 +SELECT pg_get_serial_sequence('serialTest1', 'f2') +-- +FUNCTION: name="pg_get_serial_sequence" function="pg_get_serial_sequence" schema="" ctx=Call +STMT: SelectStmt +== 044 +-- test smallserial / bigserial +CREATE TABLE serialTest2 (f1 text, f2 serial, f3 smallserial, f4 serial2, + f5 bigserial, f6 serial8) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DDL +STMT: CreateStmt +== 045 +INSERT INTO serialTest2 (f1) + VALUES ('test_defaults') +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO serialTest2 (f1, f2, f3, f4, f5, f6) + VALUES ('test_max_vals', 2147483647, 32767, 32767, 9223372036854775807, + 9223372036854775807), + ('test_min_vals', -2147483648, -32768, -32768, -9223372036854775808, + -9223372036854775808) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +-- All these INSERTs should fail: +INSERT INTO serialTest2 (f1, f3) + VALUES ('bogus', -32769) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO serialTest2 (f1, f4) + VALUES ('bogus', -32769) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO serialTest2 (f1, f3) + VALUES ('bogus', 32768) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO serialTest2 (f1, f4) + VALUES ('bogus', 32768) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +INSERT INTO serialTest2 (f1, f5) + VALUES ('bogus', -9223372036854775809) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO serialTest2 (f1, f6) + VALUES ('bogus', -9223372036854775809) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO serialTest2 (f1, f5) + VALUES ('bogus', 9223372036854775808) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +INSERT INTO serialTest2 (f1, f6) + VALUES ('bogus', 9223372036854775808) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +SELECT * FROM serialTest2 ORDER BY f2 ASC +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=Select +STMT: SelectStmt +== 056 +SELECT nextval('serialTest2_f2_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 057 +SELECT nextval('serialTest2_f3_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 058 +SELECT nextval('serialTest2_f4_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT nextval('serialTest2_f5_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT nextval('serialTest2_f6_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 061 +-- basic sequence operations using both text and oid references +CREATE SEQUENCE sequence_test +-- +STMT: CreateSeqStmt +== 062 +CREATE SEQUENCE IF NOT EXISTS sequence_test +-- +STMT: CreateSeqStmt +== 063 +SELECT nextval('sequence_test'::text) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT nextval('sequence_test'::regclass) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT currval('sequence_test'::text) +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT currval('sequence_test'::regclass) +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT setval('sequence_test'::text, 32) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT nextval('sequence_test'::regclass) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT setval('sequence_test'::text, 99, false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT nextval('sequence_test'::regclass) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 071 +SELECT setval('sequence_test'::regclass, 32) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 072 +SELECT nextval('sequence_test'::text) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 073 +SELECT setval('sequence_test'::regclass, 99, false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT nextval('sequence_test'::text) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 075 +DISCARD SEQUENCES +-- +STMT: DiscardStmt +== 076 +SELECT currval('sequence_test'::regclass) +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 077 +DROP SEQUENCE sequence_test +-- +STMT: DropStmt +== 078 +-- renaming sequences +CREATE SEQUENCE foo_seq +-- +STMT: CreateSeqStmt +== 079 +ALTER TABLE foo_seq RENAME TO foo_seq_new +-- +TABLE: name="foo_seq" schema="" table="foo_seq" ctx=DDL +TABLE: name="foo_seq_new" schema="" table="foo_seq_new" ctx=DDL +STMT: RenameStmt +== 080 +SELECT * FROM foo_seq_new +-- +TABLE: name="foo_seq_new" schema="" table="foo_seq_new" ctx=Select +STMT: SelectStmt +== 081 +SELECT nextval('foo_seq_new') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 082 +SELECT nextval('foo_seq_new') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 083 +-- log_cnt can be higher if there is a checkpoint just at the right +-- time, so just test for the expected range +SELECT last_value, log_cnt IN (31, 32) AS log_cnt_ok, is_called FROM foo_seq_new +-- +TABLE: name="foo_seq_new" schema="" table="foo_seq_new" ctx=Select +STMT: SelectStmt +== 084 +DROP SEQUENCE foo_seq_new +-- +STMT: DropStmt +== 085 +-- renaming serial sequences +ALTER TABLE serialtest1_f2_seq RENAME TO serialtest1_f2_foo +-- +TABLE: name="serialtest1_f2_seq" schema="" table="serialtest1_f2_seq" ctx=DDL +TABLE: name="serialtest1_f2_foo" schema="" table="serialtest1_f2_foo" ctx=DDL +STMT: RenameStmt +== 086 +INSERT INTO serialTest1 VALUES ('more') +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +SELECT * FROM serialTest1 +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=Select +STMT: SelectStmt +== 088 +|-- +-- Check dependencies of serial and ordinary sequences +|-- +CREATE TEMP SEQUENCE myseq2 +-- +STMT: CreateSeqStmt +== 089 +CREATE TEMP SEQUENCE myseq3 +-- +STMT: CreateSeqStmt +== 090 +CREATE TEMP TABLE t1 ( + f1 serial, + f2 int DEFAULT nextval('myseq2'), + f3 int DEFAULT nextval('myseq3'::text) +) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 091 +-- Both drops should fail, but with different error messages: +DROP SEQUENCE t1_f1_seq +-- +STMT: DropStmt +== 092 +DROP SEQUENCE myseq2 +-- +STMT: DropStmt +== 093 +-- This however will work: +DROP SEQUENCE myseq3 +-- +STMT: DropStmt +== 094 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 095 +-- Fails because no longer existent: +DROP SEQUENCE t1_f1_seq +-- +STMT: DropStmt +== 096 +-- Now OK: +DROP SEQUENCE myseq2 +-- +STMT: DropStmt +== 097 +|-- +-- Alter sequence +|-- + +ALTER SEQUENCE IF EXISTS sequence_test2 RESTART WITH 24 + INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE +-- +STMT: AlterSeqStmt +== 098 +ALTER SEQUENCE serialTest1 CYCLE +-- +STMT: AlterSeqStmt +== 099 +-- error, not a sequence + +CREATE SEQUENCE sequence_test2 START WITH 32 +-- +STMT: CreateSeqStmt +== 100 +CREATE SEQUENCE sequence_test4 INCREMENT BY -1 +-- +STMT: CreateSeqStmt +== 101 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 102 +SELECT nextval('sequence_test4') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 103 +ALTER SEQUENCE sequence_test2 RESTART +-- +STMT: AlterSeqStmt +== 104 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 105 +ALTER SEQUENCE sequence_test2 RESTART WITH 0 +-- +STMT: AlterSeqStmt +== 106 +-- error +ALTER SEQUENCE sequence_test4 RESTART WITH 40 +-- +STMT: AlterSeqStmt +== 107 +-- error + +-- test CYCLE and NO CYCLE +ALTER SEQUENCE sequence_test2 RESTART WITH 24 + INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE +-- +STMT: AlterSeqStmt +== 108 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 109 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 110 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 111 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 112 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 113 +-- cycled + +ALTER SEQUENCE sequence_test2 RESTART WITH 24 + NO CYCLE +-- +STMT: AlterSeqStmt +== 114 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 115 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 116 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 117 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 118 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 119 +-- error + +ALTER SEQUENCE sequence_test2 RESTART WITH -24 START WITH -24 + INCREMENT BY -4 MINVALUE -36 MAXVALUE -5 CYCLE +-- +STMT: AlterSeqStmt +== 120 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 121 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 122 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 123 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 124 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 125 +-- cycled + +ALTER SEQUENCE sequence_test2 RESTART WITH -24 + NO CYCLE +-- +STMT: AlterSeqStmt +== 126 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 127 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 128 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 129 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 130 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 131 +-- error + +-- reset +ALTER SEQUENCE IF EXISTS sequence_test2 RESTART WITH 32 START WITH 32 + INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE +-- +STMT: AlterSeqStmt +== 132 +SELECT setval('sequence_test2', -100) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 133 +-- error +SELECT setval('sequence_test2', 100) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 134 +-- error +SELECT setval('sequence_test2', 5) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 135 +CREATE SEQUENCE sequence_test3 +-- +STMT: CreateSeqStmt +== 136 +-- not read from, to test is_called + + +-- Information schema +SELECT * FROM information_schema.sequences + WHERE sequence_name ~ ANY(ARRAY['sequence_test', 'serialtest']) + ORDER BY sequence_name ASC +-- +TABLE: name="information_schema.sequences" schema="information_schema" table="sequences" ctx=Select +FILTER: schema="" table="" column="sequence_name" +STMT: SelectStmt +== 137 +SELECT schemaname, sequencename, start_value, min_value, max_value, increment_by, cycle, cache_size, last_value +FROM pg_sequences +WHERE sequencename ~ ANY(ARRAY['sequence_test', 'serialtest']) + ORDER BY sequencename ASC +-- +TABLE: name="pg_sequences" schema="" table="pg_sequences" ctx=Select +FILTER: schema="" table="" column="sequencename" +STMT: SelectStmt +== 138 +SELECT * FROM pg_sequence_parameters('sequence_test4'::regclass) +-- +FUNCTION: name="pg_sequence_parameters" function="pg_sequence_parameters" schema="" ctx=Call +STMT: SelectStmt +== 139 +-- Test comments +COMMENT ON SEQUENCE asdf IS 'won''t work' +-- +STMT: CommentStmt +== 140 +COMMENT ON SEQUENCE sequence_test2 IS 'will work' +-- +STMT: CommentStmt +== 141 +COMMENT ON SEQUENCE sequence_test2 IS NULL +-- +STMT: CommentStmt +== 142 +-- Test lastval() +CREATE SEQUENCE seq +-- +STMT: CreateSeqStmt +== 143 +SELECT nextval('seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 144 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 145 +SELECT setval('seq', 99) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 146 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 147 +DISCARD SEQUENCES +-- +STMT: DiscardStmt +== 148 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 149 +CREATE SEQUENCE seq2 +-- +STMT: CreateSeqStmt +== 150 +SELECT nextval('seq2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 151 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 152 +DROP SEQUENCE seq2 +-- +STMT: DropStmt +== 153 +-- should fail +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 154 +-- unlogged sequences +-- (more tests in src/test/recovery/) +CREATE UNLOGGED SEQUENCE sequence_test_unlogged +-- +STMT: CreateSeqStmt +== 155 +ALTER SEQUENCE sequence_test_unlogged SET LOGGED +-- +TABLE: name="sequence_test_unlogged" schema="" table="sequence_test_unlogged" ctx=DDL +STMT: AlterTableStmt +== 156 +ALTER SEQUENCE sequence_test_unlogged SET UNLOGGED +-- +TABLE: name="sequence_test_unlogged" schema="" table="sequence_test_unlogged" ctx=DDL +STMT: AlterTableStmt +== 157 +DROP SEQUENCE sequence_test_unlogged +-- +STMT: DropStmt +== 158 +-- Test sequences in read-only transactions +CREATE TEMPORARY SEQUENCE sequence_test_temp1 +-- +STMT: CreateSeqStmt +== 159 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 160 +SELECT nextval('sequence_test_temp1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 161 +-- ok +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 162 +-- error +ROLLBACK +-- +STMT: TransactionStmt +== 163 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 164 +SELECT setval('sequence_test_temp1', 1) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 165 +-- ok +SELECT setval('sequence_test2', 1) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 166 +-- error +ROLLBACK +-- +STMT: TransactionStmt +== 167 +-- privileges tests + +CREATE USER regress_seq_user +-- +STMT: CreateRoleStmt +== 168 +-- nextval +BEGIN +-- +STMT: TransactionStmt +== 169 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 170 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 171 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 172 +GRANT SELECT ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 173 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 174 +ROLLBACK +-- +STMT: TransactionStmt +== 175 +BEGIN +-- +STMT: TransactionStmt +== 176 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 177 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 178 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 179 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 180 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 181 +ROLLBACK +-- +STMT: TransactionStmt +== 182 +BEGIN +-- +STMT: TransactionStmt +== 183 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 184 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 185 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 186 +GRANT USAGE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 187 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 188 +ROLLBACK +-- +STMT: TransactionStmt +== 189 +-- currval +BEGIN +-- +STMT: TransactionStmt +== 190 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 191 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 192 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 193 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 194 +GRANT SELECT ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 195 +SELECT currval('seq3') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 196 +ROLLBACK +-- +STMT: TransactionStmt +== 197 +BEGIN +-- +STMT: TransactionStmt +== 198 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 199 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 200 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 201 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 202 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 203 +SELECT currval('seq3') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 204 +ROLLBACK +-- +STMT: TransactionStmt +== 205 +BEGIN +-- +STMT: TransactionStmt +== 206 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 207 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 208 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 209 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 210 +GRANT USAGE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 211 +SELECT currval('seq3') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +== 212 +ROLLBACK +-- +STMT: TransactionStmt +== 213 +-- lastval +BEGIN +-- +STMT: TransactionStmt +== 214 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 215 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 216 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 217 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 218 +GRANT SELECT ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 219 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 220 +ROLLBACK +-- +STMT: TransactionStmt +== 221 +BEGIN +-- +STMT: TransactionStmt +== 222 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 223 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 224 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 225 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 226 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 227 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 228 +ROLLBACK +-- +STMT: TransactionStmt +== 229 +BEGIN +-- +STMT: TransactionStmt +== 230 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 231 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 232 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 233 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 234 +GRANT USAGE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 235 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +== 236 +ROLLBACK +-- +STMT: TransactionStmt +== 237 +-- setval +BEGIN +-- +STMT: TransactionStmt +== 238 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 239 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +== 240 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 241 +SAVEPOINT save +-- +STMT: TransactionStmt +== 242 +SELECT setval('seq3', 5) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 243 +ROLLBACK TO save +-- +STMT: TransactionStmt +== 244 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +== 245 +SELECT setval('seq3', 5) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +== 246 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 247 +ROLLBACK +-- +STMT: TransactionStmt +== 248 +-- ALTER SEQUENCE +BEGIN +-- +STMT: TransactionStmt +== 249 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +== 250 +ALTER SEQUENCE sequence_test2 START WITH 1 +-- +STMT: AlterSeqStmt +== 251 +ROLLBACK +-- +STMT: TransactionStmt +== 252 +-- Sequences should get wiped out as well: +DROP TABLE serialTest1, serialTest2 +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DDL +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DDL +STMT: DropStmt +== 253 +-- Make sure sequences are gone: +SELECT * FROM information_schema.sequences WHERE sequence_name IN + ('sequence_test2', 'serialtest2_f2_seq', 'serialtest2_f3_seq', + 'serialtest2_f4_seq', 'serialtest2_f5_seq', 'serialtest2_f6_seq') + ORDER BY sequence_name ASC +-- +TABLE: name="information_schema.sequences" schema="information_schema" table="sequences" ctx=Select +FILTER: schema="" table="" column="sequence_name" +STMT: SelectStmt +== 254 +DROP USER regress_seq_user +-- +STMT: DropRoleStmt +== 255 +DROP SEQUENCE seq +-- +STMT: DropStmt +== 256 +-- cache tests +CREATE SEQUENCE test_seq1 CACHE 10 +-- +STMT: CreateSeqStmt +== 257 +SELECT nextval('test_seq1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 258 +SELECT nextval('test_seq1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 259 +SELECT nextval('test_seq1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 260 +DROP SEQUENCE test_seq1 +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/spgist.metadata.json b/parser/testdata/summary/postgres_regress/spgist.metadata.json new file mode 100644 index 0000000..442b788 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/spgist.metadata.json @@ -0,0 +1,35 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031" + ] +} diff --git a/parser/testdata/summary/postgres_regress/spgist.test b/parser/testdata/summary/postgres_regress/spgist.test new file mode 100644 index 0000000..b531ca0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/spgist.test @@ -0,0 +1,239 @@ +== 001 +|-- +-- Test SP-GiST indexes. +|-- +-- There are other tests to test different SP-GiST opclasses. This is for +-- testing SP-GiST code itself. + +create table spgist_point_tbl(id int4, p point) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: CreateStmt +== 002 +create index spgist_point_idx on spgist_point_tbl using spgist(p) with (fillfactor = 75) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: IndexStmt +== 003 +-- Test vacuum-root operation. It gets invoked when the root is also a leaf, +-- i.e. the index is very small. +insert into spgist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10) g +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 004 +delete from spgist_point_tbl where id < 5 +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +STMT: DeleteStmt +== 005 +vacuum spgist_point_tbl +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: VacuumStmt +== 006 +-- Insert more data, to make the index a few levels deep. +insert into spgist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10000) g +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 007 +insert into spgist_point_tbl (id, p) +select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- To test vacuum, delete some entries from all over the index. +delete from spgist_point_tbl where id % 2 = 1 +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +STMT: DeleteStmt +== 009 +-- And also delete some concentration of values. (SP-GiST doesn't currently +-- attempt to delete pages even when they become empty, but if it did, this +-- would exercise it) +delete from spgist_point_tbl where id < 10000 +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +STMT: DeleteStmt +== 010 +vacuum spgist_point_tbl +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: VacuumStmt +== 011 +-- Test rescan paths (cf. bug #15378) +-- use box and && rather than point, so that rescan happens when the +-- traverse stack is non-empty + +create table spgist_box_tbl(id serial, b box) +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=DDL +STMT: CreateStmt +== 012 +insert into spgist_box_tbl(b) +select box(point(i,j),point(i+s,j+s)) + from generate_series(1,100,5) i, + generate_series(1,100,5) j, + generate_series(1,10) s +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 013 +create index spgist_box_idx on spgist_box_tbl using spgist (b) +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=DDL +STMT: IndexStmt +== 014 +select count(*) + from (values (point(5,5)),(point(8,8)),(point(12,12))) v(p) + where exists(select * from spgist_box_tbl b where b.b && box(v.p,v.p)) +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=Select +ALIAS: "b"="spgist_box_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FILTER: schema="" table="b" column="b" +FILTER: schema="" table="v" column="p" +FILTER: schema="" table="v" column="p" +STMT: SelectStmt +== 015 +-- The point opclass's choose method only uses the spgMatchNode action, +-- so the other actions are not tested by the above. Create an index using +-- text opclass, which uses the others actions. + +create table spgist_text_tbl(id int4, t text) +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DDL +STMT: CreateStmt +== 016 +create index spgist_text_idx on spgist_text_tbl using spgist(t) +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DDL +STMT: IndexStmt +== 017 +insert into spgist_text_tbl (id, t) +select g, 'f' || repeat('o', 100) || g from generate_series(1, 10000) g +union all +select g, 'baaaaaaaaaaaaaar' || g from generate_series(1, 1000) g +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 018 +-- Do a lot of insertions that have to split an existing node. Hopefully +-- one of these will cause the page to run out of space, causing the inner +-- tuple to be moved to another page. +insert into spgist_text_tbl (id, t) +select -g, 'f' || repeat('o', 100-g) || 'surprise' from generate_series(1, 100) g +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 019 +-- Test out-of-range fillfactor values +create index spgist_point_idx2 on spgist_point_tbl using spgist(p) with (fillfactor = 9) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: IndexStmt +== 020 +create index spgist_point_idx2 on spgist_point_tbl using spgist(p) with (fillfactor = 101) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: IndexStmt +== 021 +-- Modify fillfactor in existing index +alter index spgist_point_idx set (fillfactor = 90) +-- +STMT: AlterTableStmt +== 022 +reindex index spgist_point_idx +-- +STMT: ReindexStmt +== 023 +-- Test index over a domain +create domain spgist_text as varchar +-- +STMT: CreateDomainStmt +== 024 +create table spgist_domain_tbl (f1 spgist_text) +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=DDL +STMT: CreateStmt +== 025 +create index spgist_domain_idx on spgist_domain_tbl using spgist(f1) +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=DDL +STMT: IndexStmt +== 026 +insert into spgist_domain_tbl values('fee'), ('fi'), ('fo'), ('fum') +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +explain (costs off) +select * from spgist_domain_tbl where f1 = 'fo' +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 028 +select * from spgist_domain_tbl where f1 = 'fo' +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 029 +-- test an unlogged table, mostly to get coverage of spgistbuildempty +create unlogged table spgist_unlogged_tbl(id serial, b box) +-- +TABLE: name="spgist_unlogged_tbl" schema="" table="spgist_unlogged_tbl" ctx=DDL +STMT: CreateStmt +== 030 +create index spgist_unlogged_idx on spgist_unlogged_tbl using spgist (b) +-- +TABLE: name="spgist_unlogged_tbl" schema="" table="spgist_unlogged_tbl" ctx=DDL +STMT: IndexStmt +== 031 +insert into spgist_unlogged_tbl(b) +select box(point(i,j)) + from generate_series(1,100,5) i, + generate_series(1,10,5) j +-- +TABLE: name="spgist_unlogged_tbl" schema="" table="spgist_unlogged_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/sqljson.metadata.json b/parser/testdata/summary/postgres_regress/sqljson.metadata.json new file mode 100644 index 0000000..78efa1d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sqljson.metadata.json @@ -0,0 +1,223 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219" + ] +} diff --git a/parser/testdata/summary/postgres_regress/sqljson.test b/parser/testdata/summary/postgres_regress/sqljson.test new file mode 100644 index 0000000..6d6a9e7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sqljson.test @@ -0,0 +1,1163 @@ +== 001 +-- JSON() +SELECT JSON() +-- +ERROR: syntax error at or near ")" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +SELECT JSON(NULL) +-- +STMT: SelectStmt +== 003 +SELECT JSON('{ "a" : 1 } ') +-- +STMT: SelectStmt +== 004 +SELECT JSON('{ "a" : 1 } ' FORMAT JSON) +-- +STMT: SelectStmt +== 005 +SELECT JSON('{ "a" : 1 } ' FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 006 +SELECT JSON('{ "a" : 1 } '::bytea FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 007 +SELECT pg_typeof(JSON('{ "a" : 1 } ')) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT JSON(' 1 '::json) +-- +STMT: SelectStmt +== 009 +SELECT JSON(' 1 '::jsonb) +-- +STMT: SelectStmt +== 010 +SELECT JSON(' 1 '::json WITH UNIQUE KEYS) +-- +STMT: SelectStmt +== 011 +SELECT JSON(123) +-- +STMT: SelectStmt +== 012 +SELECT JSON('{"a": 1, "a": 2}') +-- +STMT: SelectStmt +== 013 +SELECT JSON('{"a": 1, "a": 2}' WITH UNIQUE KEYS) +-- +STMT: SelectStmt +== 014 +SELECT JSON('{"a": 1, "a": 2}' WITHOUT UNIQUE KEYS) +-- +STMT: SelectStmt +== 015 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123') +-- +STMT: ExplainStmt +STMT: SelectStmt +== 016 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' FORMAT JSON) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 017 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123'::bytea FORMAT JSON) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 018 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123'::bytea FORMAT JSON ENCODING UTF8) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 019 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITH UNIQUE KEYS) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 020 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITHOUT UNIQUE KEYS) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 021 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123') +-- +STMT: ExplainStmt +STMT: SelectStmt +== 022 +SELECT pg_typeof(JSON('123')) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 023 +-- JSON_SCALAR() +SELECT JSON_SCALAR() +-- +ERROR: syntax error at or near ")" +CURSORPOS: 37 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +SELECT JSON_SCALAR(NULL) +-- +STMT: SelectStmt +== 025 +SELECT JSON_SCALAR(NULL::int) +-- +STMT: SelectStmt +== 026 +SELECT JSON_SCALAR(123) +-- +STMT: SelectStmt +== 027 +SELECT JSON_SCALAR(123.45) +-- +STMT: SelectStmt +== 028 +SELECT JSON_SCALAR(123.45::numeric) +-- +STMT: SelectStmt +== 029 +SELECT JSON_SCALAR(true) +-- +STMT: SelectStmt +== 030 +SELECT JSON_SCALAR(false) +-- +STMT: SelectStmt +== 031 +SELECT JSON_SCALAR(' 123.45') +-- +STMT: SelectStmt +== 032 +SELECT JSON_SCALAR('2020-06-07'::date) +-- +STMT: SelectStmt +== 033 +SELECT JSON_SCALAR('2020-06-07 01:02:03'::timestamp) +-- +STMT: SelectStmt +== 034 +SELECT JSON_SCALAR('{}'::json) +-- +STMT: SelectStmt +== 035 +SELECT JSON_SCALAR('{}'::jsonb) +-- +STMT: SelectStmt +== 036 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 037 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR('123') +-- +STMT: ExplainStmt +STMT: SelectStmt +== 038 +-- JSON_SERIALIZE() +SELECT JSON_SERIALIZE() +-- +ERROR: syntax error at or near ")" +CURSORPOS: 43 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +SELECT JSON_SERIALIZE(NULL) +-- +STMT: SelectStmt +== 040 +SELECT JSON_SERIALIZE(JSON('{ "a" : 1 } ')) +-- +STMT: SelectStmt +== 041 +SELECT JSON_SERIALIZE('{ "a" : 1 } ') +-- +STMT: SelectStmt +== 042 +SELECT JSON_SERIALIZE('1') +-- +STMT: SelectStmt +== 043 +SELECT JSON_SERIALIZE('1' FORMAT JSON) +-- +STMT: SelectStmt +== 044 +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING bytea) +-- +STMT: SelectStmt +== 045 +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar) +-- +STMT: SelectStmt +== 046 +SELECT pg_typeof(JSON_SERIALIZE(NULL)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- only string types or bytea allowed +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING jsonb) +-- +STMT: SelectStmt +== 048 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}') +-- +STMT: ExplainStmt +STMT: SelectStmt +== 049 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}' RETURNING bytea) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 050 +-- JSON_OBJECT() +SELECT JSON_OBJECT() +-- +STMT: SelectStmt +== 051 +SELECT JSON_OBJECT(RETURNING json) +-- +STMT: SelectStmt +== 052 +SELECT JSON_OBJECT(RETURNING json FORMAT JSON) +-- +STMT: SelectStmt +== 053 +SELECT JSON_OBJECT(RETURNING jsonb) +-- +STMT: SelectStmt +== 054 +SELECT JSON_OBJECT(RETURNING jsonb FORMAT JSON) +-- +STMT: SelectStmt +== 055 +SELECT JSON_OBJECT(RETURNING text) +-- +STMT: SelectStmt +== 056 +SELECT JSON_OBJECT(RETURNING text FORMAT JSON) +-- +STMT: SelectStmt +== 057 +SELECT JSON_OBJECT(RETURNING text FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 058 +SELECT JSON_OBJECT(RETURNING text FORMAT JSON ENCODING INVALID_ENCODING) +-- +ERROR: unrecognized JSON encoding: invalid_encoding +FILENAME: gram.y +FUNCNAME: base_yyparse +== 059 +SELECT JSON_OBJECT(RETURNING bytea) +-- +STMT: SelectStmt +== 060 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON) +-- +STMT: SelectStmt +== 061 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 062 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF16) +-- +STMT: SelectStmt +== 063 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF32) +-- +STMT: SelectStmt +== 064 +SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON) +-- +STMT: SelectStmt +== 065 +SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 066 +SELECT JSON_OBJECT('foo': NULL::json FORMAT JSON) +-- +STMT: SelectStmt +== 067 +SELECT JSON_OBJECT('foo': NULL::json FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 068 +SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON) +-- +STMT: SelectStmt +== 069 +SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 070 +SELECT JSON_OBJECT(NULL: 1) +-- +STMT: SelectStmt +== 071 +SELECT JSON_OBJECT('a': 2 + 3) +-- +STMT: SelectStmt +== 072 +SELECT JSON_OBJECT('a' VALUE 2 + 3) +-- +STMT: SelectStmt +== 073 +--SELECT JSON_OBJECT(KEY 'a' VALUE 2 + 3); +SELECT JSON_OBJECT('a' || 2: 1) +-- +STMT: SelectStmt +== 074 +SELECT JSON_OBJECT(('a' || 2) VALUE 1) +-- +STMT: SelectStmt +== 075 +--SELECT JSON_OBJECT('a' || 2 VALUE 1); +--SELECT JSON_OBJECT(KEY 'a' || 2 VALUE 1); +SELECT JSON_OBJECT('a': 2::text) +-- +STMT: SelectStmt +== 076 +SELECT JSON_OBJECT('a' VALUE 2::text) +-- +STMT: SelectStmt +== 077 +--SELECT JSON_OBJECT(KEY 'a' VALUE 2::text); +SELECT JSON_OBJECT(1::text: 2) +-- +STMT: SelectStmt +== 078 +SELECT JSON_OBJECT((1::text) VALUE 2) +-- +STMT: SelectStmt +== 079 +--SELECT JSON_OBJECT(1::text VALUE 2); +--SELECT JSON_OBJECT(KEY 1::text VALUE 2); +SELECT JSON_OBJECT(json '[1]': 123) +-- +STMT: SelectStmt +== 080 +SELECT JSON_OBJECT(ARRAY[1,2,3]: 'aaa') +-- +STMT: SelectStmt +== 081 +SELECT JSON_OBJECT( + 'a': '123', + 1.23: 123, + 'c': json '[ 1,true,{ } ]', + 'd': jsonb '{ "x" : 123.45 }' +) +-- +STMT: SelectStmt +== 082 +SELECT JSON_OBJECT( + 'a': '123', + 1.23: 123, + 'c': json '[ 1,true,{ } ]', + 'd': jsonb '{ "x" : 123.45 }' + RETURNING jsonb +) +-- +STMT: SelectStmt +== 083 +/* +SELECT JSON_OBJECT( + 'a': '123', + KEY 1.23 VALUE 123, + 'c' VALUE json '[1, true, {}]' +); +*/ + +SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa')) +-- +STMT: SelectStmt +== 084 +SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa' RETURNING jsonb)) +-- +STMT: SelectStmt +== 085 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text)) +-- +STMT: SelectStmt +== 086 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text) FORMAT JSON) +-- +STMT: SelectStmt +== 087 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea)) +-- +STMT: SelectStmt +== 088 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea) FORMAT JSON) +-- +STMT: SelectStmt +== 089 +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2) +-- +STMT: SelectStmt +== 090 +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2 NULL ON NULL) +-- +STMT: SelectStmt +== 091 +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2 ABSENT ON NULL) +-- +STMT: SelectStmt +== 092 +SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, repeat('x', 1000): 1, 2: repeat('a', 100) WITH UNIQUE) +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 093 +SELECT JSON_OBJECT(1: 1, '1': NULL WITH UNIQUE) +-- +STMT: SelectStmt +== 094 +SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE) +-- +STMT: SelectStmt +== 095 +SELECT JSON_OBJECT(1: 1, '1': NULL NULL ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +== 096 +SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +== 097 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 NULL ON NULL WITH UNIQUE) +-- +STMT: SelectStmt +== 098 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE) +-- +STMT: SelectStmt +== 099 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITHOUT UNIQUE) +-- +STMT: SelectStmt +== 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +== 101 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITHOUT UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +== 102 +SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, 4: NULL, '5': 'a' ABSENT ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +== 103 +-- BUG: https://postgr.es/m/CADXhmgTJtJZK9A3Na_ry%2BXrq-ghjcejBRhcRMzWZvbd__QdgJA%40mail.gmail.com +-- datum_to_jsonb_internal() didn't catch keys that are casts instead of a simple scalar +CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral') +-- +STMT: CreateEnumStmt +== 104 +CREATE FUNCTION mood_to_json(mood) RETURNS json AS $$ + SELECT to_json($1::text); +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="mood_to_json" function="mood_to_json" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 105 +CREATE CAST (mood AS json) WITH FUNCTION mood_to_json(mood) AS IMPLICIT +-- +STMT: CreateCastStmt +== 106 +SELECT JSON_OBJECT('happy'::mood: '123'::jsonb) +-- +STMT: SelectStmt +== 107 +DROP CAST (mood AS json) +-- +STMT: DropStmt +== 108 +DROP FUNCTION mood_to_json +-- +FUNCTION: name="mood_to_json" function="mood_to_json" schema="" ctx=DDL +STMT: DropStmt +== 109 +DROP TYPE mood +-- +STMT: DropStmt +== 110 +-- JSON_ARRAY() +SELECT JSON_ARRAY() +-- +STMT: SelectStmt +== 111 +SELECT JSON_ARRAY(RETURNING json) +-- +STMT: SelectStmt +== 112 +SELECT JSON_ARRAY(RETURNING json FORMAT JSON) +-- +STMT: SelectStmt +== 113 +SELECT JSON_ARRAY(RETURNING jsonb) +-- +STMT: SelectStmt +== 114 +SELECT JSON_ARRAY(RETURNING jsonb FORMAT JSON) +-- +STMT: SelectStmt +== 115 +SELECT JSON_ARRAY(RETURNING text) +-- +STMT: SelectStmt +== 116 +SELECT JSON_ARRAY(RETURNING text FORMAT JSON) +-- +STMT: SelectStmt +== 117 +SELECT JSON_ARRAY(RETURNING text FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 118 +SELECT JSON_ARRAY(RETURNING text FORMAT JSON ENCODING INVALID_ENCODING) +-- +ERROR: unrecognized JSON encoding: invalid_encoding +FILENAME: gram.y +FUNCNAME: base_yyparse +== 119 +SELECT JSON_ARRAY(RETURNING bytea) +-- +STMT: SelectStmt +== 120 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON) +-- +STMT: SelectStmt +== 121 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +== 122 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF16) +-- +STMT: SelectStmt +== 123 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF32) +-- +STMT: SelectStmt +== 124 +SELECT JSON_ARRAY('aaa', 111, true, array[1,2,3], NULL, json '{"a": [1]}', jsonb '["a",3]') +-- +STMT: SelectStmt +== 125 +SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL) +-- +STMT: SelectStmt +== 126 +SELECT JSON_ARRAY('a', NULL, 'b' ABSENT ON NULL) +-- +STMT: SelectStmt +== 127 +SELECT JSON_ARRAY(NULL, NULL, 'b' ABSENT ON NULL) +-- +STMT: SelectStmt +== 128 +SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL RETURNING jsonb) +-- +STMT: SelectStmt +== 129 +SELECT JSON_ARRAY('a', NULL, 'b' ABSENT ON NULL RETURNING jsonb) +-- +STMT: SelectStmt +== 130 +SELECT JSON_ARRAY(NULL, NULL, 'b' ABSENT ON NULL RETURNING jsonb) +-- +STMT: SelectStmt +== 131 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' RETURNING text)) +-- +STMT: SelectStmt +== 132 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' FORMAT JSON RETURNING text)) +-- +STMT: SelectStmt +== 133 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' FORMAT JSON RETURNING text) FORMAT JSON) +-- +STMT: SelectStmt +== 134 +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i)) +-- +STMT: SelectStmt +== 135 +SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i)) +-- +STMT: SelectStmt +== 136 +SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i) RETURNING jsonb) +-- +STMT: SelectStmt +== 137 +--SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i) NULL ON NULL); +--SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i) NULL ON NULL RETURNING jsonb); +SELECT JSON_ARRAY(SELECT i FROM (VALUES (3), (1), (NULL), (2)) foo(i) ORDER BY i) +-- +STMT: SelectStmt +== 138 +SELECT JSON_ARRAY(WITH x AS (SELECT 1) VALUES (TRUE)) +-- +CTE: "x" +STMT: SelectStmt +== 139 +-- Should fail +SELECT JSON_ARRAY(SELECT FROM (VALUES (1)) foo(i)) +-- +STMT: SelectStmt +== 140 +SELECT JSON_ARRAY(SELECT i, i FROM (VALUES (1)) foo(i)) +-- +STMT: SelectStmt +== 141 +SELECT JSON_ARRAY(SELECT * FROM (VALUES (1, 2)) foo(i, j)) +-- +STMT: SelectStmt +== 142 +-- JSON_ARRAYAGG() +SELECT JSON_ARRAYAGG(i) IS NULL, + JSON_ARRAYAGG(i RETURNING jsonb) IS NULL +FROM generate_series(1, 0) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 143 +SELECT JSON_ARRAYAGG(i), + JSON_ARRAYAGG(i RETURNING jsonb) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 144 +SELECT JSON_ARRAYAGG(i ORDER BY i DESC) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 145 +SELECT JSON_ARRAYAGG(i::text::json) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 146 +SELECT JSON_ARRAYAGG(JSON_ARRAY(i, i + 1 RETURNING text) FORMAT JSON) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 147 +SELECT JSON_ARRAYAGG(NULL), + JSON_ARRAYAGG(NULL RETURNING jsonb) +FROM generate_series(1, 5) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 148 +SELECT JSON_ARRAYAGG(NULL NULL ON NULL), + JSON_ARRAYAGG(NULL NULL ON NULL RETURNING jsonb) +FROM generate_series(1, 5) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 149 +SELECT + JSON_ARRAYAGG(bar) as no_options, + JSON_ARRAYAGG(bar RETURNING jsonb) as returning_jsonb, + JSON_ARRAYAGG(bar ABSENT ON NULL) as absent_on_null, + JSON_ARRAYAGG(bar ABSENT ON NULL RETURNING jsonb) as absentonnull_returning_jsonb, + JSON_ARRAYAGG(bar NULL ON NULL) as null_on_null, + JSON_ARRAYAGG(bar NULL ON NULL RETURNING jsonb) as nullonnull_returning_jsonb, + JSON_ARRAYAGG(foo) as row_no_options, + JSON_ARRAYAGG(foo RETURNING jsonb) as row_returning_jsonb, + JSON_ARRAYAGG(foo ORDER BY bar) FILTER (WHERE bar > 2) as row_filtered_agg, + JSON_ARRAYAGG(foo ORDER BY bar RETURNING jsonb) FILTER (WHERE bar > 2) as row_filtered_agg_returning_jsonb +FROM + (VALUES (NULL), (3), (1), (NULL), (NULL), (5), (2), (4), (NULL)) foo(bar) +-- +STMT: SelectStmt +== 150 +SELECT + bar, JSON_ARRAYAGG(bar) FILTER (WHERE bar > 2) OVER (PARTITION BY foo.bar % 2) +FROM + (VALUES (NULL), (3), (1), (NULL), (NULL), (5), (2), (4), (NULL), (5), (4)) foo(bar) +-- +STMT: SelectStmt +== 151 +-- JSON_OBJECTAGG() +SELECT JSON_OBJECTAGG('key': 1) IS NULL, + JSON_OBJECTAGG('key': 1 RETURNING jsonb) IS NULL +WHERE FALSE +-- +STMT: SelectStmt +== 152 +SELECT JSON_OBJECTAGG(NULL: 1) +-- +STMT: SelectStmt +== 153 +SELECT JSON_OBJECTAGG(NULL: 1 RETURNING jsonb) +-- +STMT: SelectStmt +== 154 +SELECT + JSON_OBJECTAGG(i: i), +-- JSON_OBJECTAGG(i VALUE i), +-- JSON_OBJECTAGG(KEY i VALUE i), + JSON_OBJECTAGG(i: i RETURNING jsonb) +FROM + generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT + JSON_OBJECTAGG(k: v), + JSON_OBJECTAGG(k: v NULL ON NULL), + JSON_OBJECTAGG(k: v ABSENT ON NULL), + JSON_OBJECTAGG(k: v RETURNING jsonb), + JSON_OBJECTAGG(k: v NULL ON NULL RETURNING jsonb), + JSON_OBJECTAGG(k: v ABSENT ON NULL RETURNING jsonb) +FROM + (VALUES (1, 1), (1, NULL), (2, NULL), (3, 3)) foo(k, v) +-- +STMT: SelectStmt +== 156 +SELECT JSON_OBJECTAGG(k: v WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +== 157 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +== 158 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (0, NULL), (3, NULL), (2, 2), (4, NULL)) foo(k, v) +-- +STMT: SelectStmt +== 159 +SELECT JSON_OBJECTAGG(k: v WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +== 160 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +== 161 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (0, NULL),(4, null), (5, null),(6, null),(2, 2)) foo(k, v) +-- +STMT: SelectStmt +== 162 +SELECT JSON_OBJECTAGG(mod(i,100): (i)::text FORMAT JSON WITH UNIQUE) +FROM generate_series(0, 199) i +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 163 +-- Test JSON_OBJECT deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 164 +CREATE VIEW json_object_view AS +SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json) +-- +TABLE: name="json_object_view" schema="" table="json_object_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 165 +DROP VIEW json_object_view +-- +STMT: DropStmt +== 166 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v WITH UNIQUE KEYS) OVER (ORDER BY k) +FROM (VALUES (1,1), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 167 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v WITH UNIQUE KEYS) OVER (ORDER BY k) +FROM (VALUES (1,1), (1,2), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 168 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL WITH UNIQUE KEYS) + OVER (ORDER BY k) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 169 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL) +OVER (ORDER BY k) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 170 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL) +OVER (ORDER BY k RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +== 171 +-- Test JSON_ARRAY deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING json) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 172 +CREATE VIEW json_array_view AS +SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING json) +-- +TABLE: name="json_array_view" schema="" table="json_array_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 173 +DROP VIEW json_array_view +-- +STMT: DropStmt +== 174 +-- Test JSON_OBJECTAGG deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 175 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) OVER (PARTITION BY i % 2) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 176 +CREATE VIEW json_objectagg_view AS +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +TABLE: name="json_objectagg_view" schema="" table="json_objectagg_view" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 177 +DROP VIEW json_objectagg_view +-- +STMT: DropStmt +== 178 +-- Test JSON_ARRAYAGG deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 179 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) OVER (PARTITION BY i % 2) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 180 +CREATE VIEW json_arrayagg_view AS +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +TABLE: name="json_arrayagg_view" schema="" table="json_arrayagg_view" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 181 +DROP VIEW json_arrayagg_view +-- +STMT: DropStmt +== 182 +-- Test JSON_ARRAY(subquery) deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING jsonb) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 183 +CREATE VIEW json_array_subquery_view AS +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING jsonb) +-- +TABLE: name="json_array_subquery_view" schema="" table="json_array_subquery_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 184 +DROP VIEW json_array_subquery_view +-- +STMT: DropStmt +== 185 +-- IS JSON predicate +SELECT NULL IS JSON +-- +STMT: SelectStmt +== 186 +SELECT NULL IS NOT JSON +-- +STMT: SelectStmt +== 187 +SELECT NULL::json IS JSON +-- +STMT: SelectStmt +== 188 +SELECT NULL::jsonb IS JSON +-- +STMT: SelectStmt +== 189 +SELECT NULL::text IS JSON +-- +STMT: SelectStmt +== 190 +SELECT NULL::bytea IS JSON +-- +STMT: SelectStmt +== 191 +SELECT NULL::int IS JSON +-- +STMT: SelectStmt +== 192 +SELECT '' IS JSON +-- +STMT: SelectStmt +== 193 +SELECT bytea '\x00' IS JSON +-- +STMT: SelectStmt +== 194 +CREATE TABLE test_is_json (js text) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=DDL +STMT: CreateStmt +== 195 +INSERT INTO test_is_json VALUES + (NULL), + (''), + ('123'), + ('"aaa "'), + ('true'), + ('null'), + ('[]'), + ('[1, "2", {}]'), + ('{}'), + ('{ "a": 1, "b": null }'), + ('{ "a": 1, "a": null }'), + ('{ "a": 1, "b": [{ "a": 1 }, { "a": 2 }] }'), + ('{ "a": 1, "b": [{ "a": 1, "b": 0, "a": 2 }] }'), + ('aaa'), + ('{a:1}'), + ('["a",]') +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 196 +SELECT + js, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + test_is_json +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +STMT: SelectStmt +== 197 +SELECT + js, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + (SELECT js::json FROM test_is_json WHERE js IS JSON) foo(js) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +FILTER: schema="" table="" column="js" +STMT: SelectStmt +== 198 +SELECT + js0, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + (SELECT js, js::bytea FROM test_is_json WHERE js IS JSON) foo(js0, js) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +FILTER: schema="" table="" column="js" +STMT: SelectStmt +== 199 +SELECT + js, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + (SELECT js::jsonb FROM test_is_json WHERE js IS JSON) foo(js) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +FILTER: schema="" table="" column="js" +STMT: SelectStmt +== 200 +-- Test IS JSON deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT '1' IS JSON AS "any", ('1' || i) IS JSON SCALAR AS "scalar", '[]' IS NOT JSON ARRAY AS "array", '{}' IS JSON OBJECT WITH UNIQUE AS "object" FROM generate_series(1, 3) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 201 +CREATE VIEW is_json_view AS +SELECT '1' IS JSON AS "any", ('1' || i) IS JSON SCALAR AS "scalar", '[]' IS NOT JSON ARRAY AS "array", '{}' IS JSON OBJECT WITH UNIQUE AS "object" FROM generate_series(1, 3) i +-- +TABLE: name="is_json_view" schema="" table="is_json_view" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 202 +DROP VIEW is_json_view +-- +STMT: DropStmt +== 203 +-- Test implicit coercion to a fixed-length type specified in RETURNING +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar(2)) +-- +STMT: SelectStmt +== 204 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING varchar(2))) +-- +STMT: SelectStmt +== 205 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' RETURNING varchar(2))) +-- +STMT: SelectStmt +== 206 +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING varchar(2)) FROM generate_series(1,1) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 207 +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING varchar(2)) FROM generate_series(1, 1) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 208 +-- Now try domain over fixed-length type +CREATE DOMAIN sqljson_char2 AS char(2) CHECK (VALUE NOT IN ('12')) +-- +STMT: CreateDomainStmt +== 209 +SELECT JSON_SERIALIZE('123' RETURNING sqljson_char2) +-- +STMT: SelectStmt +== 210 +SELECT JSON_SERIALIZE('12' RETURNING sqljson_char2) +-- +STMT: SelectStmt +== 211 +-- Bug #18657: JsonValueExpr.raw_expr was not initialized in ExecInitExprRec() +-- causing the Aggrefs contained in it to also not be initialized, which led +-- to a crash in ExecBuildAggTrans() as mentioned in the bug report: +-- https://postgr.es/m/18657-1b90ccce2b16bdb8@postgresql.org +CREATE FUNCTION volatile_one() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql VOLATILE +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 212 +CREATE FUNCTION stable_one() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql STABLE +-- +FUNCTION: name="stable_one" function="stable_one" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 213 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': volatile_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 214 +SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': volatile_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=Call +STMT: SelectStmt +== 215 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': stable_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="stable_one" function="stable_one" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 216 +SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': stable_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="stable_one" function="stable_one" schema="" ctx=Call +STMT: SelectStmt +== 217 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 218 +SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON) +-- +STMT: SelectStmt +== 219 +DROP FUNCTION volatile_one, stable_one +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json b/parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json new file mode 100644 index 0000000..17a73dc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json @@ -0,0 +1,121 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117" + ] +} diff --git a/parser/testdata/summary/postgres_regress/sqljson_jsontable.test b/parser/testdata/summary/postgres_regress/sqljson_jsontable.test new file mode 100644 index 0000000..ee78d4b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sqljson_jsontable.test @@ -0,0 +1,913 @@ +== 001 +-- JSON_TABLE + +-- Should fail (JSON_TABLE can be used only in FROM clause) +SELECT JSON_TABLE('[]', '$') +-- +ERROR: syntax error at or near "(" +CURSORPOS: 93 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- Only allow EMPTY and ERROR for ON ERROR +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +== 003 +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') NULL ON ERROR) +-- +STMT: SelectStmt +== 004 +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') EMPTY ON ERROR) +-- +STMT: SelectStmt +== 005 +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') ERROR ON ERROR) +-- +STMT: SelectStmt +== 006 +-- Column and path names must be distinct +SELECT * FROM JSON_TABLE(jsonb'"1.23"', '$.a' as js2 COLUMNS (js2 int path '$')) +-- +STMT: SelectStmt +== 007 +-- Should fail (no columns) +SELECT * FROM JSON_TABLE(NULL, '$' COLUMNS ()) +-- +ERROR: syntax error at or near ")" +CURSORPOS: 73 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +SELECT * FROM JSON_TABLE (NULL::jsonb, '$' COLUMNS (v1 timestamp)) AS f (v1, v2) +-- +STMT: SelectStmt +== 009 +--duplicated column name +SELECT * FROM JSON_TABLE(jsonb'"1.23"', '$.a' COLUMNS (js2 int path '$', js2 int path '$')) +-- +STMT: SelectStmt +== 010 +--return composite data type. +create type comp as (a int, b int) +-- +STMT: CompositeTypeStmt +== 011 +SELECT * FROM JSON_TABLE(jsonb '{"rec": "(1,2)"}', '$' COLUMNS (id FOR ORDINALITY, comp comp path '$.rec' omit quotes)) jt +-- +STMT: SelectStmt +== 012 +drop type comp +-- +STMT: DropStmt +== 013 +-- NULL => empty table +SELECT * FROM JSON_TABLE(NULL::jsonb, '$' COLUMNS (foo int)) bar +-- +STMT: SelectStmt +== 014 +SELECT * FROM JSON_TABLE(jsonb'"1.23"', 'strict $.a' COLUMNS (js2 int PATH '$')) +-- +STMT: SelectStmt +== 015 +|-- +SELECT * FROM JSON_TABLE(jsonb '123', '$' + COLUMNS (item int PATH '$', foo int)) bar +-- +STMT: SelectStmt +== 016 +-- JSON_TABLE: basic functionality +CREATE DOMAIN jsonb_test_domain AS text CHECK (value <> 'foo') +-- +STMT: CreateDomainStmt +== 017 +CREATE TEMP TABLE json_table_test (js) AS + (VALUES + ('1'), + ('[]'), + ('{}'), + ('[1, 1.23, "2", "aaaaaaa", "foo", null, false, true, {"aaa": 123}, "[1,2]", "\"str\""]') + ) +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 018 +-- Regular "unformatted" columns +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$', + "char(4)" char(4) PATH '$', + "bool" bool PATH '$', + "numeric" numeric PATH '$', + "domain" jsonb_test_domain PATH '$', + js json PATH '$', + jb jsonb PATH '$' + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +== 019 +-- "formatted" columns +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + jst text FORMAT JSON PATH '$', + jsc char(4) FORMAT JSON PATH '$', + jsv varchar(4) FORMAT JSON PATH '$', + jsb jsonb FORMAT JSON PATH '$', + jsbq jsonb FORMAT JSON PATH '$' OMIT QUOTES + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +== 020 +-- EXISTS columns +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + exists1 bool EXISTS PATH '$.aaa', + exists2 int EXISTS PATH '$.aaa', + exists3 int EXISTS PATH 'strict $.aaa' UNKNOWN ON ERROR, + exists4 text EXISTS PATH 'strict $.aaa' FALSE ON ERROR + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +== 021 +-- Other miscellaneous checks +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + aaa int, -- "aaa" has implicit path '$."aaa"' + aaa1 int PATH '$.aaa', + js2 json PATH '$', + jsb2w jsonb PATH '$' WITH WRAPPER, + jsb2q jsonb PATH '$' OMIT QUOTES, + ia int[] PATH '$', + ta text[] PATH '$', + jba jsonb[] PATH '$' + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +== 022 +-- Test using casts in DEFAULT .. ON ERROR expression +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT '"foo1"'::jsonb::text ON EMPTY)) +-- +STMT: SelectStmt +== 023 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo'::jsonb_test_domain ON EMPTY)) +-- +STMT: SelectStmt +== 024 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo1'::jsonb_test_domain ON EMPTY)) +-- +STMT: SelectStmt +== 025 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.d1' DEFAULT 'foo2'::jsonb_test_domain ON ERROR)) +-- +STMT: SelectStmt +== 026 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' + COLUMNS (js1 oid[] PATH '$.d2' DEFAULT '{1}'::int[]::oid[] ON EMPTY)) +-- +STMT: SelectStmt +== 027 +-- JSON_TABLE: Test backward parsing + +CREATE VIEW jsonb_table_view2 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + "int" int PATH '$', + "text" text PATH '$', + "char(4)" char(4) PATH '$', + "bool" bool PATH '$', + "numeric" numeric PATH '$', + "domain" jsonb_test_domain PATH '$')) +-- +TABLE: name="jsonb_table_view2" schema="" table="jsonb_table_view2" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 028 +CREATE VIEW jsonb_table_view3 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + js json PATH '$', + jb jsonb PATH '$', + jst text FORMAT JSON PATH '$', + jsc char(4) FORMAT JSON PATH '$', + jsv varchar(4) FORMAT JSON PATH '$')) +-- +TABLE: name="jsonb_table_view3" schema="" table="jsonb_table_view3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 029 +CREATE VIEW jsonb_table_view4 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + jsb jsonb FORMAT JSON PATH '$', + jsbq jsonb FORMAT JSON PATH '$' OMIT QUOTES, + aaa int, -- implicit path '$."aaa"', + aaa1 int PATH '$.aaa')) +-- +TABLE: name="jsonb_table_view4" schema="" table="jsonb_table_view4" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 030 +CREATE VIEW jsonb_table_view5 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + exists1 bool EXISTS PATH '$.aaa', + exists2 int EXISTS PATH '$.aaa' TRUE ON ERROR, + exists3 text EXISTS PATH 'strict $.aaa' UNKNOWN ON ERROR)) +-- +TABLE: name="jsonb_table_view5" schema="" table="jsonb_table_view5" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 031 +CREATE VIEW jsonb_table_view6 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + js2 json PATH '$', + jsb2w jsonb PATH '$' WITH WRAPPER, + jsb2q jsonb PATH '$' OMIT QUOTES, + ia int[] PATH '$', + ta text[] PATH '$', + jba jsonb[] PATH '$')) +-- +TABLE: name="jsonb_table_view6" schema="" table="jsonb_table_view6" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 032 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view2 +-- +TABLE: name="jsonb_table_view2" schema="" table="jsonb_table_view2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 033 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view3 +-- +TABLE: name="jsonb_table_view3" schema="" table="jsonb_table_view3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 034 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view4 +-- +TABLE: name="jsonb_table_view4" schema="" table="jsonb_table_view4" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 035 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view5 +-- +TABLE: name="jsonb_table_view5" schema="" table="jsonb_table_view5" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 036 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view6 +-- +TABLE: name="jsonb_table_view6" schema="" table="jsonb_table_view6" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 037 +-- JSON_TABLE() with alias +EXPLAIN (COSTS OFF, VERBOSE) +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$' + )) json_table_func +-- +STMT: ExplainStmt +STMT: SelectStmt +== 038 +EXPLAIN (COSTS OFF, FORMAT JSON, VERBOSE) +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$' + )) json_table_func +-- +STMT: ExplainStmt +STMT: SelectStmt +== 039 +DROP VIEW jsonb_table_view2 +-- +STMT: DropStmt +== 040 +DROP VIEW jsonb_table_view3 +-- +STMT: DropStmt +== 041 +DROP VIEW jsonb_table_view4 +-- +STMT: DropStmt +== 042 +DROP VIEW jsonb_table_view5 +-- +STMT: DropStmt +== 043 +DROP VIEW jsonb_table_view6 +-- +STMT: DropStmt +== 044 +DROP DOMAIN jsonb_test_domain +-- +STMT: DropStmt +== 045 +-- JSON_TABLE: only one FOR ORDINALITY columns allowed +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (id FOR ORDINALITY, id2 FOR ORDINALITY, a int PATH '$.a' ERROR ON EMPTY)) jt +-- +STMT: SelectStmt +== 046 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (id FOR ORDINALITY, a int PATH '$' ERROR ON EMPTY)) jt +-- +STMT: SelectStmt +== 047 +-- JSON_TABLE: ON EMPTY/ON ERROR behavior +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js), + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$')) jt +-- +STMT: SelectStmt +== 048 +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js) + LEFT OUTER JOIN + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$' ERROR ON ERROR)) jt + ON true +-- +STMT: SelectStmt +== 049 +-- TABLE-level ERROR ON ERROR is not propagated to columns +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js) + LEFT OUTER JOIN + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$' ERROR ON ERROR)) jt + ON true +-- +STMT: SelectStmt +== 050 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH '$.a' ERROR ON EMPTY)) jt +-- +STMT: SelectStmt +== 051 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'strict $.a' ERROR ON ERROR) ERROR ON ERROR) jt +-- +STMT: SelectStmt +== 052 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'lax $.a' ERROR ON EMPTY) ERROR ON ERROR) jt +-- +STMT: SelectStmt +== 053 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH '$' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt +-- +STMT: SelectStmt +== 054 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt +-- +STMT: SelectStmt +== 055 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt +-- +STMT: SelectStmt +== 056 +-- JSON_TABLE: EXISTS PATH types +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$.a' ERROR ON ERROR)) +-- +STMT: SelectStmt +== 057 +-- ok; can cast to int4 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$' ERROR ON ERROR)) +-- +STMT: SelectStmt +== 058 +-- ok; can cast to int4 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int2 EXISTS PATH '$.a')) +-- +STMT: SelectStmt +== 059 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int8 EXISTS PATH '$.a')) +-- +STMT: SelectStmt +== 060 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a float4 EXISTS PATH '$.a')) +-- +STMT: SelectStmt +== 061 +-- Default FALSE (ON ERROR) doesn't fit char(3) +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(3) EXISTS PATH '$.a')) +-- +STMT: SelectStmt +== 062 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(3) EXISTS PATH '$.a' ERROR ON ERROR)) +-- +STMT: SelectStmt +== 063 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(5) EXISTS PATH '$.a' ERROR ON ERROR)) +-- +STMT: SelectStmt +== 064 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a json EXISTS PATH '$.a')) +-- +STMT: SelectStmt +== 065 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a jsonb EXISTS PATH '$.a')) +-- +STMT: SelectStmt +== 066 +-- EXISTS PATH domain over int +CREATE DOMAIN dint4 AS int +-- +STMT: CreateDomainStmt +== 067 +CREATE DOMAIN dint4_0 AS int CHECK (VALUE <> 0 ) +-- +STMT: CreateDomainStmt +== 068 +SELECT a, a::bool FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a dint4 EXISTS PATH '$.a' )) +-- +STMT: SelectStmt +== 069 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b')) +-- +STMT: SelectStmt +== 070 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' ERROR ON ERROR)) +-- +STMT: SelectStmt +== 071 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' FALSE ON ERROR)) +-- +STMT: SelectStmt +== 072 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' TRUE ON ERROR)) +-- +STMT: SelectStmt +== 073 +DROP DOMAIN dint4, dint4_0 +-- +STMT: DropStmt +== 074 +-- JSON_TABLE: WRAPPER/QUOTES clauses on scalar columns +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' KEEP QUOTES ON SCALAR STRING)) +-- +STMT: SelectStmt +== 075 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' OMIT QUOTES ON SCALAR STRING)) +-- +STMT: SelectStmt +== 076 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' KEEP QUOTES)) +-- +STMT: SelectStmt +== 077 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' OMIT QUOTES)) +-- +STMT: SelectStmt +== 078 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITHOUT WRAPPER KEEP QUOTES)) +-- +STMT: SelectStmt +== 079 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' WITHOUT WRAPPER OMIT QUOTES)) +-- +STMT: SelectStmt +== 080 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITH WRAPPER)) +-- +STMT: SelectStmt +== 081 +-- Error: OMIT QUOTES should not be specified when WITH WRAPPER is present +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' WITH WRAPPER OMIT QUOTES)) +-- +STMT: SelectStmt +== 082 +-- But KEEP QUOTES (the default) is fine +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITH WRAPPER KEEP QUOTES)) +-- +STMT: SelectStmt +== 083 +-- Test PASSING args +SELECT * +FROM JSON_TABLE( + jsonb '[1,2,3]', + '$[*] ? (@ < $x)' + PASSING 3 AS x + COLUMNS (y text FORMAT JSON PATH '$') + ) jt +-- +STMT: SelectStmt +== 084 +-- PASSING arguments are also passed to column paths +SELECT * +FROM JSON_TABLE( + jsonb '[1,2,3]', + '$[*] ? (@ < $x)' + PASSING 10 AS x, 3 AS y + COLUMNS (a text FORMAT JSON PATH '$ ? (@ < $y)') + ) jt +-- +STMT: SelectStmt +== 085 +-- Should fail (not supported) +SELECT * FROM JSON_TABLE(jsonb '{"a": 123}', '$' || '.' || 'a' COLUMNS (foo int)) +-- +ERROR: only string constants are supported in JSON_TABLE path specification +CURSORPOS: 77 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 086 +-- JsonPathQuery() error message mentioning column name +SELECT * FROM JSON_TABLE('{"a": [{"b": "1"}, {"b": "2"}]}', '$' COLUMNS (b json path '$.a[*].b' ERROR ON ERROR)) +-- +STMT: SelectStmt +== 087 +-- JSON_TABLE: nested paths + +-- Duplicate path names +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' AS a + COLUMNS ( + b int, + NESTED PATH '$' AS a + COLUMNS ( + c int + ) + ) +) jt +-- +STMT: SelectStmt +== 088 +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' AS a + COLUMNS ( + b int, + NESTED PATH '$' AS n_a + COLUMNS ( + c int + ) + ) +) jt +-- +STMT: SelectStmt +== 089 +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' + COLUMNS ( + b int, + NESTED PATH '$' AS b + COLUMNS ( + c int + ) + ) +) jt +-- +STMT: SelectStmt +== 090 +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' + COLUMNS ( + NESTED PATH '$' AS a + COLUMNS ( + b int + ), + NESTED PATH '$' + COLUMNS ( + NESTED PATH '$' AS a + COLUMNS ( + c int + ) + ) + ) +) jt +-- +STMT: SelectStmt +== 091 +-- JSON_TABLE: plan execution + +CREATE TEMP TABLE jsonb_table_test (js jsonb) +-- +TABLE: name="jsonb_table_test" schema="" table="jsonb_table_test" ctx=DDL +STMT: CreateStmt +== 092 +INSERT INTO jsonb_table_test +VALUES ( + '[ + {"a": 1, "b": [], "c": []}, + {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, + {"a": 3, "b": [1, 2], "c": []}, + {"x": "4", "b": [1, 2], "c": 123} + ]' +) +-- +TABLE: name="jsonb_table_test" schema="" table="jsonb_table_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +select + jt.* +from + jsonb_table_test jtt, + json_table ( + jtt.js,'strict $[*]' as p + columns ( + n for ordinality, + a int path 'lax $.a' default -1 on empty, + nested path 'strict $.b[*]' as pb columns (b_id for ordinality, b int path '$' ), + nested path 'strict $.c[*]' as pc columns (c_id for ordinality, c int path '$' ) + ) + ) jt +-- +TABLE: name="jsonb_table_test" schema="" table="jsonb_table_test" ctx=Select +ALIAS: "jtt"="jsonb_table_test" +STMT: SelectStmt +== 094 +-- PASSING arguments are passed to nested paths and their columns' paths +SELECT * +FROM + generate_series(1, 3) x, + generate_series(1, 3) y, + JSON_TABLE(jsonb + '[[1,2,3],[2,3,4,5],[3,4,5,6]]', + 'strict $[*] ? (@[*] <= $x)' + PASSING x AS x, y AS y + COLUMNS ( + y text FORMAT JSON PATH '$', + NESTED PATH 'strict $[*] ? (@ == $y)' + COLUMNS ( + z int PATH '$' + ) + ) + ) jt +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 095 +-- JSON_TABLE: Test backward parsing with nested paths + +CREATE VIEW jsonb_table_view_nested AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + NESTED PATH '$[1]' AS p1 COLUMNS ( + a1 int, + NESTED PATH '$[*]' AS "p1 1" COLUMNS ( + a11 text + ), + b1 text + ), + NESTED PATH '$[2]' AS p2 COLUMNS ( + NESTED PATH '$[*]' AS "p2:1" COLUMNS ( + a21 text + ), + NESTED PATH '$[*]' AS p22 COLUMNS ( + a22 text + ) + ) + ) + ) +-- +TABLE: name="jsonb_table_view_nested" schema="" table="jsonb_table_view_nested" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 096 +DROP VIEW jsonb_table_view_nested +-- +STMT: DropStmt +== 097 +CREATE TABLE s (js jsonb) +-- +TABLE: name="s" schema="" table="s" ctx=DDL +STMT: CreateStmt +== 098 +INSERT INTO s VALUES + ('{"a":{"za":[{"z1": [11,2222]},{"z21": [22, 234,2345]},{"z22": [32, 204,145]}]},"c": 3}'), + ('{"a":{"za":[{"z1": [21,4222]},{"z21": [32, 134,1345]}]},"c": 10}') +-- +TABLE: name="s" schema="" table="s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +-- error +SELECT sub.* FROM s, + JSON_TABLE(js, '$' PASSING 32 AS x, 13 AS y COLUMNS ( + xx int path '$.c', + NESTED PATH '$.a.za[1]' columns (NESTED PATH '$.z21[*]' COLUMNS (z21 int path '$?(@ >= $"x")' ERROR ON ERROR)) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +STMT: SelectStmt +== 100 +-- Parent columns xx1, xx appear before NESTED ones +SELECT sub.* FROM s, + (VALUES (23)) x(x), generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y COLUMNS ( + NESTED PATH '$.a.za[2]' COLUMNS ( + NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$')), + NESTED PATH '$.a.za[1]' columns (d int[] PATH '$.z21'), + NESTED PATH '$.a.za[0]' columns (NESTED PATH '$.z1[*]' as z1 COLUMNS (a int PATH '$')), + xx1 int PATH '$.c', + NESTED PATH '$.a.za[1]' columns (NESTED PATH '$.z21[*]' as z21 COLUMNS (b int PATH '$')), + xx int PATH '$.c' + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 101 +-- Test applying PASSING variables at different nesting levels +SELECT sub.* FROM s, + (VALUES (23)) x(x), generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[0].z1[*]' COLUMNS (NESTED PATH '$ ?(@ >= ($"x" -2))' COLUMNS (a int PATH '$')), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' COLUMNS (b int PATH '$')) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 102 +-- Test applying PASSING variable to paths all the levels +SELECT sub.* FROM s, + (VALUES (23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[1]' + COLUMNS (NESTED PATH '$.z21[*]' COLUMNS (b int PATH '$')), + NESTED PATH '$.a.za[1] ? (@.z21[*] >= ($"x"-1))' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" + 3))' as z22 COLUMNS (a int PATH '$ ? (@ >= ($"y" + 12))')), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (c int PATH '$ ? (@ > ($"x" +111))')) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 103 +----- test on empty behavior +SELECT sub.* FROM s, + (values(23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[2]' COLUMNS (NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$')), + NESTED PATH '$.a.za[1]' COLUMNS (d json PATH '$ ? (@.z21[*] == ($"x" -1))'), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' as z1 COLUMNS (a int PATH '$')), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (b int PATH '$ ? (@ > ($"x" +111))' DEFAULT 0 ON EMPTY)) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 104 +CREATE OR REPLACE VIEW jsonb_table_view7 AS +SELECT sub.* FROM s, + (values(23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[2]' COLUMNS (NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$' WITHOUT WRAPPER OMIT QUOTES)), + NESTED PATH '$.a.za[1]' COLUMNS (d json PATH '$ ? (@.z21[*] == ($"x" -1))' WITH WRAPPER), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' as z1 COLUMNS (a int PATH '$' KEEP QUOTES)), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (b int PATH '$ ? (@ > ($"x" +111))' DEFAULT 0 ON EMPTY)) + )) sub +-- +TABLE: name="jsonb_table_view7" schema="" table="jsonb_table_view7" ctx=DDL +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 105 +DROP VIEW jsonb_table_view7 +-- +STMT: DropStmt +== 106 +DROP TABLE s +-- +TABLE: name="s" schema="" table="s" ctx=DDL +STMT: DropStmt +== 107 +-- Prevent ON EMPTY specification on EXISTS columns +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty object on empty)) +-- +ERROR: syntax error at or near "empty" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 108 +-- Test ON ERROR / EMPTY value validity for the function and column types; +-- all fail +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int) NULL ON ERROR) +-- +STMT: SelectStmt +== 109 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int true on empty)) +-- +STMT: SelectStmt +== 110 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int omit quotes true on error)) +-- +STMT: SelectStmt +== 111 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty object on error)) +-- +STMT: SelectStmt +== 112 +-- Test JSON_TABLE() column deparsing -- don't emit default ON ERROR / EMPTY +-- behavior +CREATE VIEW json_table_view8 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$')) +-- +TABLE: name="json_table_view8" schema="" table="json_table_view8" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 113 +CREATE VIEW json_table_view9 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR) +-- +TABLE: name="json_table_view9" schema="" table="json_table_view9" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 114 +DROP VIEW json_table_view8, json_table_view9 +-- +STMT: DropStmt +== 115 +-- Test JSON_TABLE() deparsing -- don't emit default ON ERROR behavior +CREATE VIEW json_table_view8 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ON ERROR) +-- +TABLE: name="json_table_view8" schema="" table="json_table_view8" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 116 +CREATE VIEW json_table_view9 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ARRAY ON ERROR) +-- +TABLE: name="json_table_view9" schema="" table="json_table_view9" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 117 +DROP VIEW json_table_view8, json_table_view9 +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json b/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json new file mode 100644 index 0000000..b0ece40 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json @@ -0,0 +1,314 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310" + ] +} diff --git a/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.test b/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.test new file mode 100644 index 0000000..db5f97d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.test @@ -0,0 +1,1455 @@ +== 001 +-- JSON_EXISTS +SELECT JSON_EXISTS(NULL::jsonb, '$') +-- +STMT: SelectStmt +== 002 +SELECT JSON_EXISTS(jsonb '[]', '$') +-- +STMT: SelectStmt +== 003 +SELECT JSON_EXISTS(JSON_OBJECT(RETURNING jsonb), '$') +-- +STMT: SelectStmt +== 004 +SELECT JSON_EXISTS(jsonb '1', '$') +-- +STMT: SelectStmt +== 005 +SELECT JSON_EXISTS(jsonb 'null', '$') +-- +STMT: SelectStmt +== 006 +SELECT JSON_EXISTS(jsonb '[]', '$') +-- +STMT: SelectStmt +== 007 +SELECT JSON_EXISTS(jsonb '1', '$.a') +-- +STMT: SelectStmt +== 008 +SELECT JSON_EXISTS(jsonb '1', 'strict $.a') +-- +STMT: SelectStmt +== 009 +-- FALSE on error +SELECT JSON_EXISTS(jsonb '1', 'strict $.a' ERROR ON ERROR) +-- +STMT: SelectStmt +== 010 +SELECT JSON_EXISTS(jsonb 'null', '$.a') +-- +STMT: SelectStmt +== 011 +SELECT JSON_EXISTS(jsonb '[]', '$.a') +-- +STMT: SelectStmt +== 012 +SELECT JSON_EXISTS(jsonb '[1, "aaa", {"a": 1}]', 'strict $.a') +-- +STMT: SelectStmt +== 013 +-- FALSE on error +SELECT JSON_EXISTS(jsonb '[1, "aaa", {"a": 1}]', 'lax $.a') +-- +STMT: SelectStmt +== 014 +SELECT JSON_EXISTS(jsonb '{}', '$.a') +-- +STMT: SelectStmt +== 015 +SELECT JSON_EXISTS(jsonb '{"b": 1, "a": 2}', '$.a') +-- +STMT: SelectStmt +== 016 +SELECT JSON_EXISTS(jsonb '1', '$.a.b') +-- +STMT: SelectStmt +== 017 +SELECT JSON_EXISTS(jsonb '{"a": {"b": 1}}', '$.a.b') +-- +STMT: SelectStmt +== 018 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.a.b') +-- +STMT: SelectStmt +== 019 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x)' PASSING 1 AS x) +-- +STMT: SelectStmt +== 020 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x)' PASSING '1' AS x) +-- +STMT: SelectStmt +== 021 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 2 AS y) +-- +STMT: SelectStmt +== 022 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 1 AS y) +-- +STMT: SelectStmt +== 023 +-- extension: boolean expressions +SELECT JSON_EXISTS(jsonb '1', '$ > 2') +-- +STMT: SelectStmt +== 024 +SELECT JSON_EXISTS(jsonb '1', '$.a > 2' ERROR ON ERROR) +-- +STMT: SelectStmt +== 025 +-- JSON_VALUE +SELECT JSON_VALUE(NULL::jsonb, '$') +-- +STMT: SelectStmt +== 026 +SELECT JSON_VALUE(jsonb 'null', '$') +-- +STMT: SelectStmt +== 027 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING int) +-- +STMT: SelectStmt +== 028 +SELECT JSON_VALUE(jsonb 'true', '$') +-- +STMT: SelectStmt +== 029 +SELECT JSON_VALUE(jsonb 'true', '$' RETURNING bool) +-- +STMT: SelectStmt +== 030 +SELECT JSON_VALUE(jsonb '123', '$') +-- +STMT: SelectStmt +== 031 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING int) + 234 +-- +STMT: SelectStmt +== 032 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING text) +-- +STMT: SelectStmt +== 033 +/* jsonb bytea ??? */ +SELECT JSON_VALUE(jsonb '123', '$' RETURNING bytea ERROR ON ERROR) +-- +STMT: SelectStmt +== 034 +SELECT JSON_VALUE(jsonb '1.23', '$') +-- +STMT: SelectStmt +== 035 +SELECT JSON_VALUE(jsonb '1.23', '$' RETURNING int) +-- +STMT: SelectStmt +== 036 +SELECT JSON_VALUE(jsonb '"1.23"', '$' RETURNING numeric) +-- +STMT: SelectStmt +== 037 +SELECT JSON_VALUE(jsonb '"1.23"', '$' RETURNING int ERROR ON ERROR) +-- +STMT: SelectStmt +== 038 +SELECT JSON_VALUE(jsonb '"aaa"', '$') +-- +STMT: SelectStmt +== 039 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING text) +-- +STMT: SelectStmt +== 040 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(5)) +-- +STMT: SelectStmt +== 041 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2) ERROR ON ERROR) +-- +STMT: SelectStmt +== 042 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2)) +-- +STMT: SelectStmt +== 043 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR) +-- +STMT: SelectStmt +== 044 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json) +-- +STMT: SelectStmt +== 045 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING jsonb) +-- +STMT: SelectStmt +== 046 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json ERROR ON ERROR) +-- +STMT: SelectStmt +== 047 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING jsonb ERROR ON ERROR) +-- +STMT: SelectStmt +== 048 +SELECT JSON_VALUE(jsonb '"\"aaa\""', '$' RETURNING json) +-- +STMT: SelectStmt +== 049 +SELECT JSON_VALUE(jsonb '"\"aaa\""', '$' RETURNING jsonb) +-- +STMT: SelectStmt +== 050 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int) +-- +STMT: SelectStmt +== 051 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int ERROR ON ERROR) +-- +STMT: SelectStmt +== 052 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int DEFAULT 111 ON ERROR) +-- +STMT: SelectStmt +== 053 +SELECT JSON_VALUE(jsonb '"123"', '$' RETURNING int) + 234 +-- +STMT: SelectStmt +== 054 +SELECT JSON_VALUE(jsonb '"2017-02-20"', '$' RETURNING date) + 9 +-- +STMT: SelectStmt +== 055 +-- Test NULL checks execution in domain types +CREATE DOMAIN sqljsonb_int_not_null AS int NOT NULL +-- +STMT: CreateDomainStmt +== 056 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null) +-- +STMT: SelectStmt +== 057 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null ERROR ON ERROR) +-- +STMT: SelectStmt +== 058 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null DEFAULT 2 ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +== 059 +SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT 2 ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +== 060 +SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT NULL ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +== 061 +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple') +-- +STMT: CreateEnumStmt +== 062 +CREATE DOMAIN rgb AS rainbow CHECK (VALUE IN ('red', 'green', 'blue')) +-- +STMT: CreateDomainStmt +== 063 +SELECT JSON_VALUE('"purple"'::jsonb, 'lax $[*]' RETURNING rgb) +-- +STMT: SelectStmt +== 064 +SELECT JSON_VALUE('"purple"'::jsonb, 'lax $[*]' RETURNING rgb ERROR ON ERROR) +-- +STMT: SelectStmt +== 065 +SELECT JSON_VALUE(jsonb '[]', '$') +-- +STMT: SelectStmt +== 066 +SELECT JSON_VALUE(jsonb '[]', '$' ERROR ON ERROR) +-- +STMT: SelectStmt +== 067 +SELECT JSON_VALUE(jsonb '{}', '$') +-- +STMT: SelectStmt +== 068 +SELECT JSON_VALUE(jsonb '{}', '$' ERROR ON ERROR) +-- +STMT: SelectStmt +== 069 +SELECT JSON_VALUE(jsonb '1', '$.a') +-- +STMT: SelectStmt +== 070 +SELECT JSON_VALUE(jsonb '1', 'strict $.a' ERROR ON ERROR) +-- +STMT: SelectStmt +== 071 +SELECT JSON_VALUE(jsonb '1', 'strict $.a' DEFAULT 'error' ON ERROR) +-- +STMT: SelectStmt +== 072 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON ERROR) +-- +STMT: SelectStmt +== 073 +-- NULL ON EMPTY +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +== 074 +SELECT JSON_VALUE(jsonb '1', 'strict $.*' DEFAULT 2 ON ERROR) +-- +STMT: SelectStmt +== 075 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT 2 ON ERROR) +-- +STMT: SelectStmt +== 076 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY) +-- +STMT: SelectStmt +== 077 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' NULL ON EMPTY DEFAULT '2' ON ERROR) +-- +STMT: SelectStmt +== 078 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY DEFAULT '3' ON ERROR) +-- +STMT: SelectStmt +== 079 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY DEFAULT '3' ON ERROR) +-- +STMT: SelectStmt +== 080 +SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' ERROR ON ERROR) +-- +STMT: SelectStmt +== 081 +SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' DEFAULT '0' ON ERROR) +-- +STMT: SelectStmt +== 082 +SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int ERROR ON ERROR) +-- +STMT: SelectStmt +== 083 +SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR) +-- +STMT: SelectStmt +== 084 +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR) +-- +STMT: SelectStmt +== 085 +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSON) +-- +STMT: SelectStmt +== 086 +-- RETURNING FORMAT not allowed + +-- RETUGNING pseudo-types not allowed +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING record) +-- +STMT: SelectStmt +== 087 +SELECT + x, + JSON_VALUE( + jsonb '{"a": 1, "b": 2}', + '$.* ? (@ > $x)' PASSING x AS x + RETURNING int + DEFAULT -1 ON EMPTY + DEFAULT -2 ON ERROR + ) y +FROM + generate_series(0, 2) x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 088 +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a) +-- +STMT: SelectStmt +== 089 +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a RETURNING point) +-- +STMT: SelectStmt +== 090 +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a RETURNING point ERROR ON ERROR) +-- +STMT: SelectStmt +== 091 +-- Test PASSING and RETURNING date/time types +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts) +-- +STMT: SelectStmt +== 092 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamptz) +-- +STMT: SelectStmt +== 093 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamp) +-- +STMT: SelectStmt +== 094 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING date '2018-02-21 12:34:56 +10' AS ts RETURNING date) +-- +STMT: SelectStmt +== 095 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING time '2018-02-21 12:34:56 +10' AS ts RETURNING time) +-- +STMT: SelectStmt +== 096 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timetz '2018-02-21 12:34:56 +10' AS ts RETURNING timetz) +-- +STMT: SelectStmt +== 097 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamp '2018-02-21 12:34:56 +10' AS ts RETURNING timestamp) +-- +STMT: SelectStmt +== 098 +-- Also test RETURNING json[b] +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING json) +-- +STMT: SelectStmt +== 099 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING jsonb) +-- +STMT: SelectStmt +== 100 +-- Test that numeric JSON values are coerced uniformly +select json_value('{"a": 1.234}', '$.a' returning int error on error) +-- +STMT: SelectStmt +== 101 +select json_value('{"a": "1.234"}', '$.a' returning int error on error) +-- +STMT: SelectStmt +== 102 +-- JSON_QUERY + +SELECT JSON_VALUE(NULL::jsonb, '$') +-- +STMT: SelectStmt +== 103 +SELECT + JSON_QUERY(js, '$') AS "unspec", + JSON_QUERY(js, '$' WITHOUT WRAPPER) AS "without", + JSON_QUERY(js, '$' WITH CONDITIONAL WRAPPER) AS "with cond", + JSON_QUERY(js, '$' WITH UNCONDITIONAL ARRAY WRAPPER) AS "with uncond", + JSON_QUERY(js, '$' WITH ARRAY WRAPPER) AS "with" +FROM + (VALUES + (jsonb 'null'), + ('12.3'), + ('true'), + ('"aaa"'), + ('[1, null, "2"]'), + ('{"a": 1, "b": [2]}') + ) foo(js) +-- +STMT: SelectStmt +== 104 +SELECT + JSON_QUERY(js, 'strict $[*]') AS "unspec", + JSON_QUERY(js, 'strict $[*]' WITHOUT WRAPPER) AS "without", + JSON_QUERY(js, 'strict $[*]' WITH CONDITIONAL WRAPPER) AS "with cond", + JSON_QUERY(js, 'strict $[*]' WITH UNCONDITIONAL ARRAY WRAPPER) AS "with uncond", + JSON_QUERY(js, 'strict $[*]' WITH ARRAY WRAPPER) AS "with" +FROM + (VALUES + (jsonb '1'), + ('[]'), + ('[null]'), + ('[12.3]'), + ('[true]'), + ('["aaa"]'), + ('[[1, 2, 3]]'), + ('[{"a": 1, "b": [2]}]'), + ('[1, "2", null, [3]]') + ) foo(js) +-- +STMT: SelectStmt +== 105 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text) +-- +STMT: SelectStmt +== 106 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text KEEP QUOTES) +-- +STMT: SelectStmt +== 107 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text KEEP QUOTES ON SCALAR STRING) +-- +STMT: SelectStmt +== 108 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text OMIT QUOTES) +-- +STMT: SelectStmt +== 109 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text OMIT QUOTES ON SCALAR STRING) +-- +STMT: SelectStmt +== 110 +SELECT JSON_QUERY(jsonb '"aaa"', '$' OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +== 111 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING json OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +== 112 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING bytea FORMAT JSON OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +== 113 +-- Behavior when a RETURNING type has typmod != -1 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR) +-- +STMT: SelectStmt +== 114 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3)) +-- +STMT: SelectStmt +== 115 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +== 116 +SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT 'bb' ON EMPTY) +-- +STMT: SelectStmt +== 117 +SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT '"bb"'::jsonb ON EMPTY) +-- +STMT: SelectStmt +== 118 +-- OMIT QUOTES behavior should not be specified when WITH WRAPPER used: +-- Should fail +SELECT JSON_QUERY(jsonb '[1]', '$' WITH WRAPPER OMIT QUOTES) +-- +STMT: SelectStmt +== 119 +SELECT JSON_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER OMIT QUOTES) +-- +STMT: SelectStmt +== 120 +-- Should succeed +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH CONDITIONAL WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +== 121 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH UNCONDITIONAL WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +== 122 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +== 123 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITHOUT WRAPPER OMIT QUOTES) +-- +STMT: SelectStmt +== 124 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITHOUT WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +== 125 +-- test QUOTES behavior. +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] omit quotes) +-- +STMT: SelectStmt +== 126 +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] keep quotes) +-- +STMT: SelectStmt +== 127 +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] keep quotes error on error) +-- +STMT: SelectStmt +== 128 +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range omit quotes) +-- +STMT: SelectStmt +== 129 +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes) +-- +STMT: SelectStmt +== 130 +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes error on error) +-- +STMT: SelectStmt +== 131 +CREATE DOMAIN qf_char_domain AS char(1) +-- +STMT: CreateDomainStmt +== 132 +CREATE DOMAIN qf_jsonb_domain AS jsonb +-- +STMT: CreateDomainStmt +== 133 +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_char_domain OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +== 134 +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_jsonb_domain OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +== 135 +DROP DOMAIN qf_char_domain, qf_jsonb_domain +-- +STMT: DropStmt +== 136 +SELECT JSON_QUERY(jsonb '[]', '$[*]') +-- +STMT: SelectStmt +== 137 +SELECT JSON_QUERY(jsonb '[]', '$[*]' NULL ON EMPTY) +-- +STMT: SelectStmt +== 138 +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ON EMPTY) +-- +STMT: SelectStmt +== 139 +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ARRAY ON EMPTY) +-- +STMT: SelectStmt +== 140 +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY OBJECT ON EMPTY) +-- +STMT: SelectStmt +== 141 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY) +-- +STMT: SelectStmt +== 142 +SELECT JSON_QUERY(jsonb '[]', '$[*]' DEFAULT '"empty"' ON EMPTY) +-- +STMT: SelectStmt +== 143 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY NULL ON ERROR) +-- +STMT: SelectStmt +== 144 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY EMPTY ARRAY ON ERROR) +-- +STMT: SelectStmt +== 145 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 146 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +== 147 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON ERROR) +-- +STMT: SelectStmt +== 148 +-- NULL ON EMPTY + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' ERROR ON ERROR) +-- +STMT: SelectStmt +== 149 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' DEFAULT '"empty"' ON ERROR) +-- +STMT: SelectStmt +== 150 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING json) +-- +STMT: SelectStmt +== 151 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING json FORMAT JSON) +-- +STMT: SelectStmt +== 152 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb) +-- +STMT: SelectStmt +== 153 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb FORMAT JSON) +-- +STMT: SelectStmt +== 154 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text) +-- +STMT: SelectStmt +== 155 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(10)) +-- +STMT: SelectStmt +== 156 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text FORMAT JSON) +-- +STMT: SelectStmt +== 157 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea) +-- +STMT: SelectStmt +== 158 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea FORMAT JSON) +-- +STMT: SelectStmt +== 159 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING bytea EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 160 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING bytea FORMAT JSON EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 161 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING json EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 162 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING jsonb EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 163 +SELECT JSON_QUERY(jsonb '[3,4]', '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 164 +SELECT JSON_QUERY(jsonb '"[3,4]"', '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 165 +-- Coercion fails with quotes on +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int2 error on error) +-- +STMT: SelectStmt +== 166 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int4 error on error) +-- +STMT: SelectStmt +== 167 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int8 error on error) +-- +STMT: SelectStmt +== 168 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING bool error on error) +-- +STMT: SelectStmt +== 169 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING numeric error on error) +-- +STMT: SelectStmt +== 170 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING real error on error) +-- +STMT: SelectStmt +== 171 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING float8 error on error) +-- +STMT: SelectStmt +== 172 +-- Fine with OMIT QUOTES +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int2 omit quotes error on error) +-- +STMT: SelectStmt +== 173 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING float8 omit quotes error on error) +-- +STMT: SelectStmt +== 174 +-- RETUGNING pseudo-types not allowed +SELECT JSON_QUERY(jsonb '[3,4]', '$[*]' RETURNING anyarray EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +== 175 +SELECT + x, y, + JSON_QUERY( + jsonb '[1,2,3,4,5,null]', + '$[*] ? (@ >= $x && @ <= $y)' + PASSING x AS x, y AS y + WITH CONDITIONAL WRAPPER + EMPTY ARRAY ON EMPTY + ) list +FROM + generate_series(0, 4) x, + generate_series(0, 4) y +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 176 +-- record type returning with quotes behavior. +CREATE TYPE comp_abc AS (a text, b int, c timestamp) +-- +STMT: CompositeTypeStmt +== 177 +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc omit quotes) +-- +STMT: SelectStmt +== 178 +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc keep quotes) +-- +STMT: SelectStmt +== 179 +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc keep quotes error on error) +-- +STMT: SelectStmt +== 180 +DROP TYPE comp_abc +-- +STMT: DropStmt +== 181 +-- Extension: record types returning +CREATE TYPE sqljsonb_rec AS (a int, t text, js json, jb jsonb, jsa json[]) +-- +STMT: CompositeTypeStmt +== 182 +CREATE TYPE sqljsonb_reca AS (reca sqljsonb_rec[]) +-- +STMT: CompositeTypeStmt +== 183 +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec) +-- +STMT: SelectStmt +== 184 +SELECT JSON_QUERY(jsonb '[{"a": "a", "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec ERROR ON ERROR) +-- +STMT: SelectStmt +== 185 +SELECT JSON_QUERY(jsonb '[{"a": "a", "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec) +-- +STMT: SelectStmt +== 186 +SELECT * FROM unnest((JSON_QUERY(jsonb '{"jsa": [{"a": 1, "b": ["foo"]}, {"a": 2, "c": {}}, 123]}', '$' RETURNING sqljsonb_rec)).jsa) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 187 +SELECT * FROM unnest((JSON_QUERY(jsonb '{"reca": [{"a": 1, "t": ["foo", []]}, {"a": 2, "jb": [{}, true]}]}', '$' RETURNING sqljsonb_reca)).reca) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 188 +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING jsonpath) +-- +STMT: SelectStmt +== 189 +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING jsonpath ERROR ON ERROR) +-- +STMT: SelectStmt +== 190 +-- Extension: array types returning +SELECT JSON_QUERY(jsonb '[1,2,null,"3"]', '$[*]' RETURNING int[] WITH WRAPPER) +-- +STMT: SelectStmt +== 191 +SELECT JSON_QUERY(jsonb '[1,2,null,"a"]', '$[*]' RETURNING int[] WITH WRAPPER ERROR ON ERROR) +-- +STMT: SelectStmt +== 192 +SELECT JSON_QUERY(jsonb '[1,2,null,"a"]', '$[*]' RETURNING int[] WITH WRAPPER) +-- +STMT: SelectStmt +== 193 +SELECT * FROM unnest(JSON_QUERY(jsonb '[{"a": 1, "t": ["foo", []]}, {"a": 2, "jb": [{}, true]}]', '$' RETURNING sqljsonb_rec[])) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 194 +-- Extension: domain types returning +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.a' RETURNING sqljsonb_int_not_null) +-- +STMT: SelectStmt +== 195 +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.b' RETURNING sqljsonb_int_not_null) +-- +STMT: SelectStmt +== 196 +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.b' RETURNING sqljsonb_int_not_null ERROR ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +== 197 +-- Test timestamptz passing and output +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts) +-- +STMT: SelectStmt +== 198 +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING json) +-- +STMT: SelectStmt +== 199 +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING jsonb) +-- +STMT: SelectStmt +== 200 +-- Test constraints + +CREATE TABLE test_jsonb_constraints ( + js text, + i int, + x jsonb DEFAULT JSON_QUERY(jsonb '[1,2]', '$[*]' WITH WRAPPER) + CONSTRAINT test_jsonb_constraint1 + CHECK (js IS JSON) + CONSTRAINT test_jsonb_constraint2 + CHECK (JSON_EXISTS(js::jsonb, '$.a' PASSING i + 5 AS int, i::text AS "TXT", array[1,2,3] as arr)) + CONSTRAINT test_jsonb_constraint3 + CHECK (JSON_VALUE(js::jsonb, '$.a' RETURNING int DEFAULT '12' ON EMPTY ERROR ON ERROR) > i) + CONSTRAINT test_jsonb_constraint4 + CHECK (JSON_QUERY(js::jsonb, '$.a' WITH CONDITIONAL WRAPPER EMPTY OBJECT ON ERROR) = jsonb '[10]') + CONSTRAINT test_jsonb_constraint5 + CHECK (JSON_QUERY(js::jsonb, '$.a' RETURNING char(5) OMIT QUOTES EMPTY ARRAY ON EMPTY) > 'a' COLLATE "C") +) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DDL +STMT: CreateStmt +== 201 +SELECT check_clause +FROM information_schema.check_constraints +WHERE constraint_name LIKE 'test_jsonb_constraint%' +ORDER BY 1 +-- +TABLE: name="information_schema.check_constraints" schema="information_schema" table="check_constraints" ctx=Select +FILTER: schema="" table="" column="constraint_name" +STMT: SelectStmt +== 202 +SELECT pg_get_expr(adbin, adrelid) +FROM pg_attrdef +WHERE adrelid = 'test_jsonb_constraints'::regclass +ORDER BY 1 +-- +TABLE: name="pg_attrdef" schema="" table="pg_attrdef" ctx=Select +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="" column="adrelid" +STMT: SelectStmt +== 203 +INSERT INTO test_jsonb_constraints VALUES ('', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 204 +INSERT INTO test_jsonb_constraints VALUES ('1', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 205 +INSERT INTO test_jsonb_constraints VALUES ('[]') +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 206 +INSERT INTO test_jsonb_constraints VALUES ('{"b": 1}', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 207 +INSERT INTO test_jsonb_constraints VALUES ('{"a": 1}', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 208 +INSERT INTO test_jsonb_constraints VALUES ('{"a": 10}', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 209 +DROP TABLE test_jsonb_constraints +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DDL +STMT: DropStmt +== 210 +-- Test mutabilily of query functions +CREATE TABLE test_jsonb_mutability(js jsonb, b int) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: CreateStmt +== 211 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 212 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a[0]')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 213 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 214 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 215 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time_tz()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 216 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 217 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp_tz()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 218 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 219 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 220 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 221 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 222 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.timestamp_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 223 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.timestamp_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 224 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 225 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 226 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 227 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 228 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 229 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 230 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 231 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '1234'::int AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 232 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp(2) < $.timestamp(3))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 233 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 234 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@ < $.datetime())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 235 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 236 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 237 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 238 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI") < $.datetime("YY-MM-DD HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 239 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("YY-MM-DD HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 240 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $x' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 241 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $y' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 242 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 243 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '1234'::int AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 244 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() ? (@ == $x)' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 245 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("YY-MM-DD") ? (@ == $x)' PASSING '2020-07-14'::date AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 246 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 247 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, 0 to $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 248 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime("HH:MI") == $x)]' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +== 249 +CREATE INDEX ON test_jsonb_mutability (JSON_VALUE(js, '$' DEFAULT random()::int ON ERROR)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: IndexStmt +== 250 +-- DEFAULT expression +CREATE OR REPLACE FUNCTION ret_setint() RETURNS SETOF integer AS +$$ +BEGIN + RETURN QUERY EXECUTE 'select 1 union all select 1'; +END; +$$ +LANGUAGE plpgsql IMMUTABLE +-- +FUNCTION: name="ret_setint" function="ret_setint" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 251 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT ret_setint() ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +FUNCTION: name="ret_setint" function="ret_setint" schema="" ctx=Call +STMT: SelectStmt +== 252 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT b + 1 ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +STMT: SelectStmt +== 253 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT sum(1) over() ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 254 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT (SELECT 1) ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +STMT: SelectStmt +== 255 +DROP TABLE test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: DropStmt +== 256 +DROP FUNCTION ret_setint +-- +FUNCTION: name="ret_setint" function="ret_setint" schema="" ctx=DDL +STMT: DropStmt +== 257 +CREATE DOMAIN queryfuncs_test_domain AS text CHECK (value <> 'foo') +-- +STMT: CreateDomainStmt +== 258 +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo'::queryfuncs_test_domain ON EMPTY) +-- +STMT: SelectStmt +== 259 +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo1'::queryfuncs_test_domain ON EMPTY) +-- +STMT: SelectStmt +== 260 +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT '"foo1"'::jsonb::text ON EMPTY) +-- +STMT: SelectStmt +== 261 +SELECT JSON_VALUE(jsonb '{"d1": "foo"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo1'::queryfuncs_test_domain ON EMPTY) +-- +STMT: SelectStmt +== 262 +-- Check the cases where a coercion-related expression is masking an +-- unsupported expressions + +-- CoerceViaIO +SELECT JSON_QUERY('"a"', '$.a' RETURNING int DEFAULT (SELECT '"1"')::jsonb ON ERROR) +-- +STMT: SelectStmt +== 263 +-- CoerceToDomain +SELECT JSON_QUERY('"a"', '$.a' RETURNING queryfuncs_test_domain DEFAULT (select '"1"')::queryfuncs_test_domain ON ERROR) +-- +STMT: SelectStmt +== 264 +-- RelabelType +SELECT JSON_QUERY('"a"', '$.a' RETURNING int DEFAULT (SELECT 1)::oid::int ON ERROR) +-- +STMT: SelectStmt +== 265 +-- ArrayCoerceExpr +SELECT JSON_QUERY('"a"', '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::oid[]::int[] ON ERROR) +-- +STMT: SelectStmt +== 266 +-- CollateExpr +SELECT JSON_QUERY('"a"', '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::text COLLATE "C" ON ERROR) +-- +STMT: SelectStmt +== 267 +-- ConvertRowtypeExpr +CREATE TABLE someparent (a int) +-- +TABLE: name="someparent" schema="" table="someparent" ctx=DDL +STMT: CreateStmt +== 268 +CREATE TABLE somechild () INHERITS (someparent) +-- +TABLE: name="somechild" schema="" table="somechild" ctx=DDL +STMT: CreateStmt +== 269 +SELECT JSON_QUERY('"a"', '$.a' RETURNING someparent DEFAULT (SELECT '(1)')::somechild::someparent ON ERROR) +-- +STMT: SelectStmt +== 270 +DROP DOMAIN queryfuncs_test_domain +-- +STMT: DropStmt +== 271 +DROP TABLE someparent, somechild +-- +TABLE: name="someparent" schema="" table="someparent" ctx=DDL +TABLE: name="somechild" schema="" table="somechild" ctx=DDL +STMT: DropStmt +== 272 +-- Extension: non-constant JSON path +SELECT JSON_EXISTS(jsonb '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +== 273 +SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +== 274 +SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' DEFAULT 'foo' ON EMPTY) +-- +STMT: SelectStmt +== 275 +SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +== 276 +SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a' WITH WRAPPER) +-- +STMT: SelectStmt +== 277 +-- Should fail (invalid path) +SELECT JSON_QUERY(jsonb '{"a": 123}', 'error' || ' ' || 'error') +-- +STMT: SelectStmt +== 278 +-- Non-jsonb inputs automatically coerced to jsonb +SELECT JSON_EXISTS(json '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +== 279 +SELECT JSON_QUERY(NULL FORMAT JSON, '$') +-- +STMT: SelectStmt +== 280 +-- Test non-const jsonpath +CREATE TEMP TABLE jsonpaths (path) AS SELECT '$' +-- +TABLE: name="jsonpaths" schema="" table="jsonpaths" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 281 +SELECT json_value('"aaa"', path RETURNING json) FROM jsonpaths +-- +TABLE: name="jsonpaths" schema="" table="jsonpaths" ctx=Select +STMT: SelectStmt +== 282 +-- Test PASSING argument parsing +SELECT JSON_QUERY(jsonb 'null', '$xyz' PASSING 1 AS xy) +-- +STMT: SelectStmt +== 283 +SELECT JSON_QUERY(jsonb 'null', '$xy' PASSING 1 AS xyz) +-- +STMT: SelectStmt +== 284 +SELECT JSON_QUERY(jsonb 'null', '$xyz' PASSING 1 AS xyz) +-- +STMT: SelectStmt +== 285 +SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS Xyz) +-- +STMT: SelectStmt +== 286 +SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS "Xyz") +-- +STMT: SelectStmt +== 287 +SELECT JSON_QUERY(jsonb 'null', '$"Xyz"' PASSING 1 AS "Xyz") +-- +STMT: SelectStmt +== 288 +-- Test ON ERROR / EMPTY value validity for the function; all fail. +SELECT JSON_EXISTS(jsonb '1', '$' DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +== 289 +SELECT JSON_VALUE(jsonb '1', '$' EMPTY ON ERROR) +-- +STMT: SelectStmt +== 290 +SELECT JSON_QUERY(jsonb '1', '$' TRUE ON ERROR) +-- +STMT: SelectStmt +== 291 +-- Test implicit coercion to a domain over fixed-length type specified in +-- RETURNING +CREATE DOMAIN queryfuncs_char2 AS char(2) +-- +STMT: CreateDomainStmt +== 292 +CREATE DOMAIN queryfuncs_char2_chk AS char(2) CHECK (VALUE NOT IN ('12')) +-- +STMT: CreateDomainStmt +== 293 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR) +-- +STMT: SelectStmt +== 294 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT '1' ON ERROR) +-- +STMT: SelectStmt +== 295 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR) +-- +STMT: SelectStmt +== 296 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT '1' ON ERROR) +-- +STMT: SelectStmt +== 297 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR) +-- +STMT: SelectStmt +== 298 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +== 299 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR) +-- +STMT: SelectStmt +== 300 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +== 301 +DROP DOMAIN queryfuncs_char2, queryfuncs_char2_chk +-- +STMT: DropStmt +== 302 +-- Test coercion to domain over another fixed-length type of the ON ERROR / +-- EMPTY expressions. Ask user to cast the DEFAULT expression explicitly if +-- automatic casting cannot be done, for example, from int to bit(2). +CREATE DOMAIN queryfuncs_d_varbit3 AS varbit(3) CHECK (VALUE <> '01') +-- +STMT: CreateDomainStmt +== 303 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '111111' ON ERROR) +-- +STMT: SelectStmt +== 304 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '010' ON ERROR) +-- +STMT: SelectStmt +== 305 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '01' ON ERROR) +-- +STMT: SelectStmt +== 306 +SELECT JSON_VALUE(jsonb '"111"', '$' RETURNING bit(2) ERROR ON ERROR) +-- +STMT: SelectStmt +== 307 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING bit(3) DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +== 308 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING bit(3) DEFAULT 1::bit(3) ON ERROR) +-- +STMT: SelectStmt +== 309 +SELECT JSON_VALUE(jsonb '"111"', '$.a' RETURNING bit(3) DEFAULT '1111' ON EMPTY) +-- +STMT: SelectStmt +== 310 +DROP DOMAIN queryfuncs_d_varbit3 +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/stats.metadata.json b/parser/testdata/summary/postgres_regress/stats.metadata.json new file mode 100644 index 0000000..5fff658 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/stats.metadata.json @@ -0,0 +1,451 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447" + ] +} diff --git a/parser/testdata/summary/postgres_regress/stats.test b/parser/testdata/summary/postgres_regress/stats.test new file mode 100644 index 0000000..e8240f4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/stats.test @@ -0,0 +1,2782 @@ +== 001 +|-- +-- Test cumulative stats system +|-- +-- Must be run after tenk2 has been created (by create_table), +-- populated (by create_misc) and indexed (by create_index). +|-- + +-- conditio sine qua non +SHOW track_counts +-- +STMT: VariableShowStmt +== 002 +-- must be on + +-- ensure that both seqscan and indexscan plans are allowed +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +== 003 +SET enable_indexscan TO on +-- +STMT: VariableSetStmt +== 004 +-- for the moment, we don't want index-only scans here +SET enable_indexonlyscan TO off +-- +STMT: VariableSetStmt +== 005 +-- not enabled by default, but we want to test it... +SET track_functions TO 'all' +-- +STMT: VariableSetStmt +== 006 +-- record dboid for later use +SELECT oid AS dboid from pg_database where datname = current_database() +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +== 007 +-- save counters +BEGIN +-- +STMT: TransactionStmt +== 008 +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +== 009 +CREATE TABLE prevstats AS +SELECT t.seq_scan, t.seq_tup_read, t.idx_scan, t.idx_tup_fetch, + (b.heap_blks_read + b.heap_blks_hit) AS heap_blks, + (b.idx_blks_read + b.idx_blks_hit) AS idx_blks, + pg_stat_get_snapshot_timestamp() as snap_ts + FROM pg_catalog.pg_stat_user_tables AS t, + pg_catalog.pg_statio_user_tables AS b + WHERE t.relname='tenk2' AND b.relname='tenk2' +-- +TABLE: name="prevstats" schema="" table="prevstats" ctx=DDL +TABLE: name="pg_catalog.pg_stat_user_tables" schema="pg_catalog" table="pg_stat_user_tables" ctx=Select +TABLE: name="pg_catalog.pg_statio_user_tables" schema="pg_catalog" table="pg_statio_user_tables" ctx=Select +ALIAS: "b"="pg_catalog.pg_statio_user_tables" +ALIAS: "t"="pg_catalog.pg_stat_user_tables" +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +FILTER: schema="" table="t" column="relname" +FILTER: schema="" table="b" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 010 +COMMIT +-- +STMT: TransactionStmt +== 011 +-- test effects of TRUNCATE on n_live_tup/n_dead_tup counters +CREATE TABLE trunc_stats_test(id serial) +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DDL +STMT: CreateStmt +== 012 +CREATE TABLE trunc_stats_test1(id serial, stuff text) +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DDL +STMT: CreateStmt +== 013 +CREATE TABLE trunc_stats_test2(id serial) +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DDL +STMT: CreateStmt +== 014 +CREATE TABLE trunc_stats_test3(id serial, stuff text) +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DDL +STMT: CreateStmt +== 015 +CREATE TABLE trunc_stats_test4(id serial) +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DDL +STMT: CreateStmt +== 016 +-- check that n_live_tup is reset to 0 after truncate +INSERT INTO trunc_stats_test DEFAULT VALUES +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DML +STMT: InsertStmt +== 017 +INSERT INTO trunc_stats_test DEFAULT VALUES +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DML +STMT: InsertStmt +== 018 +INSERT INTO trunc_stats_test DEFAULT VALUES +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DML +STMT: InsertStmt +== 019 +TRUNCATE trunc_stats_test +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DDL +STMT: TruncateStmt +== 020 +-- test involving a truncate in a transaction; 4 ins but only 1 live +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +== 021 +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +== 022 +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +== 023 +UPDATE trunc_stats_test1 SET id = id + 10 WHERE id IN (1, 2) +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: UpdateStmt +== 024 +DELETE FROM trunc_stats_test1 WHERE id = 3 +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: DeleteStmt +== 025 +BEGIN +-- +STMT: TransactionStmt +== 026 +UPDATE trunc_stats_test1 SET id = id + 100 +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: UpdateStmt +== 027 +TRUNCATE trunc_stats_test1 +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DDL +STMT: TruncateStmt +== 028 +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +== 029 +COMMIT +-- +STMT: TransactionStmt +== 030 +-- use a savepoint: 1 insert, 1 live +BEGIN +-- +STMT: TransactionStmt +== 031 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +== 032 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +== 033 +SAVEPOINT p1 +-- +STMT: TransactionStmt +== 034 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +== 035 +TRUNCATE trunc_stats_test2 +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DDL +STMT: TruncateStmt +== 036 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +== 037 +RELEASE SAVEPOINT p1 +-- +STMT: TransactionStmt +== 038 +COMMIT +-- +STMT: TransactionStmt +== 039 +-- rollback a savepoint: this should count 4 inserts and have 2 +-- live tuples after commit (and 2 dead ones due to aborted subxact) +BEGIN +-- +STMT: TransactionStmt +== 040 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +== 041 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +== 042 +SAVEPOINT p1 +-- +STMT: TransactionStmt +== 043 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +== 044 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +== 045 +TRUNCATE trunc_stats_test3 +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DDL +STMT: TruncateStmt +== 046 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +== 047 +ROLLBACK TO SAVEPOINT p1 +-- +STMT: TransactionStmt +== 048 +COMMIT +-- +STMT: TransactionStmt +== 049 +-- rollback a truncate: this should count 2 inserts and produce 2 dead tuples +BEGIN +-- +STMT: TransactionStmt +== 050 +INSERT INTO trunc_stats_test4 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DML +STMT: InsertStmt +== 051 +INSERT INTO trunc_stats_test4 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DML +STMT: InsertStmt +== 052 +TRUNCATE trunc_stats_test4 +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DDL +STMT: TruncateStmt +== 053 +INSERT INTO trunc_stats_test4 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DML +STMT: InsertStmt +== 054 +ROLLBACK +-- +STMT: TransactionStmt +== 055 +-- do a seqscan +SELECT count(*) FROM tenk2 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- do an indexscan +-- make sure it is not a bitmap scan, which might skip fetching heap tuples +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 057 +SELECT count(*) FROM tenk2 WHERE unique1 = 1 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 058 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 059 +-- ensure pending stats are flushed +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 060 +-- check effects +BEGIN +-- +STMT: TransactionStmt +== 061 +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +== 062 +SELECT relname, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup + FROM pg_stat_user_tables + WHERE relname like 'trunc_stats_test%' order by relname +-- +TABLE: name="pg_stat_user_tables" schema="" table="pg_stat_user_tables" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 063 +SELECT st.seq_scan >= pr.seq_scan + 1, + st.seq_tup_read >= pr.seq_tup_read + cl.reltuples, + st.idx_scan >= pr.idx_scan + 1, + st.idx_tup_fetch >= pr.idx_tup_fetch + 1 + FROM pg_stat_user_tables AS st, pg_class AS cl, prevstats AS pr + WHERE st.relname='tenk2' AND cl.relname='tenk2' +-- +TABLE: name="pg_stat_user_tables" schema="" table="pg_stat_user_tables" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="prevstats" schema="" table="prevstats" ctx=Select +ALIAS: "cl"="pg_class" +ALIAS: "pr"="prevstats" +ALIAS: "st"="pg_stat_user_tables" +FILTER: schema="" table="st" column="relname" +FILTER: schema="" table="cl" column="relname" +STMT: SelectStmt +== 064 +SELECT st.heap_blks_read + st.heap_blks_hit >= pr.heap_blks + cl.relpages, + st.idx_blks_read + st.idx_blks_hit >= pr.idx_blks + 1 + FROM pg_statio_user_tables AS st, pg_class AS cl, prevstats AS pr + WHERE st.relname='tenk2' AND cl.relname='tenk2' +-- +TABLE: name="pg_statio_user_tables" schema="" table="pg_statio_user_tables" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="prevstats" schema="" table="prevstats" ctx=Select +ALIAS: "cl"="pg_class" +ALIAS: "pr"="prevstats" +ALIAS: "st"="pg_statio_user_tables" +FILTER: schema="" table="st" column="relname" +FILTER: schema="" table="cl" column="relname" +STMT: SelectStmt +== 065 +SELECT pr.snap_ts < pg_stat_get_snapshot_timestamp() as snapshot_newer +FROM prevstats AS pr +-- +TABLE: name="prevstats" schema="" table="prevstats" ctx=Select +ALIAS: "pr"="prevstats" +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 066 +COMMIT +-- +STMT: TransactionStmt +== 067 +---- +-- Basic tests for track_functions +--- +CREATE FUNCTION stats_test_func1() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$ +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 068 +SELECT 'stats_test_func1()'::regprocedure::oid AS stats_test_func1_oid +-- +STMT: SelectStmt +== 069 +CREATE FUNCTION stats_test_func2() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$ +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 070 +SELECT 'stats_test_func2()'::regprocedure::oid AS stats_test_func2_oid +-- +STMT: SelectStmt +== 071 +-- test that stats are accumulated +BEGIN +-- +STMT: TransactionStmt +== 072 +SET LOCAL stats_fetch_consistency = none +-- +STMT: VariableSetStmt +== 073 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 074 +SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +SELECT stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +SELECT stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 079 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 080 +COMMIT +-- +STMT: TransactionStmt +== 081 +-- Verify that function stats are not transactional + +-- rolled back savepoint in committing transaction +BEGIN +-- +STMT: TransactionStmt +== 082 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +== 083 +SAVEPOINT foo +-- +STMT: TransactionStmt +== 084 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +== 085 +ROLLBACK TO SAVEPOINT foo +-- +STMT: TransactionStmt +== 086 +SELECT pg_stat_get_xact_function_calls(:stats_test_func2_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 087 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +== 088 +COMMIT +-- +STMT: TransactionStmt +== 089 +-- rolled back transaction +BEGIN +-- +STMT: TransactionStmt +== 090 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +== 091 +ROLLBACK +-- +STMT: TransactionStmt +== 092 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 093 +-- check collected stats +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 92 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 094 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func2_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 095 +-- check that a rolled back drop function stats leaves stats alive +BEGIN +-- +STMT: TransactionStmt +== 096 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 097 +DROP FUNCTION stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=DDL +STMT: DropStmt +== 098 +-- shouldn't be visible via view +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 100 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 099 +-- but still via oid access +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 100 +ROLLBACK +-- +STMT: TransactionStmt +== 101 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 102 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 103 +-- check that function dropped in main transaction leaves no stats behind +BEGIN +-- +STMT: TransactionStmt +== 104 +DROP FUNCTION stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=DDL +STMT: DropStmt +== 105 +COMMIT +-- +STMT: TransactionStmt +== 106 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 107 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 108 +-- check that function dropped in a subtransaction leaves no stats behind +BEGIN +-- +STMT: TransactionStmt +== 109 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +== 110 +SAVEPOINT a +-- +STMT: TransactionStmt +== 111 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +== 112 +SAVEPOINT b +-- +STMT: TransactionStmt +== 113 +DROP FUNCTION stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=DDL +STMT: DropStmt +== 114 +COMMIT +-- +STMT: TransactionStmt +== 115 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func2_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 116 +SELECT pg_stat_get_function_calls(:stats_test_func2_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 117 +-- Check that stats for relations are dropped. For that we need to access stats +-- by oid after the DROP TABLE. Save oids. +CREATE TABLE drop_stats_test() +-- +TABLE: name="drop_stats_test" schema="" table="drop_stats_test" ctx=DDL +STMT: CreateStmt +== 118 +INSERT INTO drop_stats_test DEFAULT VALUES +-- +TABLE: name="drop_stats_test" schema="" table="drop_stats_test" ctx=DML +STMT: InsertStmt +== 119 +SELECT 'drop_stats_test'::regclass::oid AS drop_stats_test_oid +-- +STMT: SelectStmt +== 120 +CREATE TABLE drop_stats_test_xact() +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DDL +STMT: CreateStmt +== 121 +INSERT INTO drop_stats_test_xact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DML +STMT: InsertStmt +== 122 +SELECT 'drop_stats_test_xact'::regclass::oid AS drop_stats_test_xact_oid +-- +STMT: SelectStmt +== 123 +CREATE TABLE drop_stats_test_subxact() +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: CreateStmt +== 124 +INSERT INTO drop_stats_test_subxact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DML +STMT: InsertStmt +== 125 +SELECT 'drop_stats_test_subxact'::regclass::oid AS drop_stats_test_subxact_oid +-- +STMT: SelectStmt +== 126 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 127 +SELECT pg_stat_get_live_tuples(:drop_stats_test_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 128 +DROP TABLE drop_stats_test +-- +TABLE: name="drop_stats_test" schema="" table="drop_stats_test" ctx=DDL +STMT: DropStmt +== 129 +SELECT pg_stat_get_live_tuples(:drop_stats_test_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 130 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 131 +-- check that rollback protects against having stats dropped and that local +-- modifications don't pose a problem +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 146 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 132 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 133 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 134 +BEGIN +-- +STMT: TransactionStmt +== 135 +INSERT INTO drop_stats_test_xact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DML +STMT: InsertStmt +== 136 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 137 +DROP TABLE drop_stats_test_xact +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DDL +STMT: DropStmt +== 138 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 139 +ROLLBACK +-- +STMT: TransactionStmt +== 140 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 142 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 143 +-- transactional drop +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 144 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 145 +BEGIN +-- +STMT: TransactionStmt +== 146 +INSERT INTO drop_stats_test_xact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DML +STMT: InsertStmt +== 147 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 148 +DROP TABLE drop_stats_test_xact +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DDL +STMT: DropStmt +== 149 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 150 +COMMIT +-- +STMT: TransactionStmt +== 151 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 152 +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 153 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 154 +-- savepoint rollback (2 levels) +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 155 +BEGIN +-- +STMT: TransactionStmt +== 156 +INSERT INTO drop_stats_test_subxact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DML +STMT: InsertStmt +== 157 +SAVEPOINT sp1 +-- +STMT: TransactionStmt +== 158 +INSERT INTO drop_stats_test_subxact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DML +STMT: InsertStmt +== 159 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 160 +SAVEPOINT sp2 +-- +STMT: TransactionStmt +== 161 +DROP TABLE drop_stats_test_subxact +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: DropStmt +== 162 +ROLLBACK TO SAVEPOINT sp2 +-- +STMT: TransactionStmt +== 163 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 164 +COMMIT +-- +STMT: TransactionStmt +== 165 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 166 +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 167 +-- savepoint rolback (1 level) +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 168 +BEGIN +-- +STMT: TransactionStmt +== 169 +SAVEPOINT sp1 +-- +STMT: TransactionStmt +== 170 +DROP TABLE drop_stats_test_subxact +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: DropStmt +== 171 +SAVEPOINT sp2 +-- +STMT: TransactionStmt +== 172 +ROLLBACK TO SAVEPOINT sp1 +-- +STMT: TransactionStmt +== 173 +COMMIT +-- +STMT: TransactionStmt +== 174 +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 175 +-- and now actually drop +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 176 +BEGIN +-- +STMT: TransactionStmt +== 177 +SAVEPOINT sp1 +-- +STMT: TransactionStmt +== 178 +DROP TABLE drop_stats_test_subxact +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: DropStmt +== 179 +SAVEPOINT sp2 +-- +STMT: TransactionStmt +== 180 +RELEASE SAVEPOINT sp1 +-- +STMT: TransactionStmt +== 181 +COMMIT +-- +STMT: TransactionStmt +== 182 +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 183 +DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4 +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DDL +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DDL +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DDL +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DDL +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DDL +STMT: DropStmt +== 184 +DROP TABLE prevstats +-- +TABLE: name="prevstats" schema="" table="prevstats" ctx=DDL +STMT: DropStmt +== 185 +----- +-- Test that last_seq_scan, last_idx_scan are correctly maintained +|-- +-- Perform test using a temporary table. That way autovacuum etc won't +-- interfere. To be able to check that timestamps increase, we sleep for 100ms +-- between tests, assuming that there aren't systems with a coarser timestamp +-- granularity. +----- + +BEGIN +-- +STMT: TransactionStmt +== 186 +CREATE TEMPORARY TABLE test_last_scan(idx_col int primary key, noidx_col int) +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=DDL +STMT: CreateStmt +== 187 +INSERT INTO test_last_scan(idx_col, noidx_col) VALUES(1, 1) +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 189 +SELECT last_seq_scan, last_idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +== 190 +COMMIT +-- +STMT: TransactionStmt +== 191 +SELECT pg_stat_reset_single_table_counters('test_last_scan'::regclass) +-- +FUNCTION: name="pg_stat_reset_single_table_counters" function="pg_stat_reset_single_table_counters" schema="" ctx=Call +STMT: SelectStmt +== 192 +SELECT seq_scan, idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +== 193 +-- ensure we start out with exactly one index and sequential scan +BEGIN +-- +STMT: TransactionStmt +== 194 +SET LOCAL enable_seqscan TO on +-- +STMT: VariableSetStmt +== 195 +SET LOCAL enable_indexscan TO on +-- +STMT: VariableSetStmt +== 196 +SET LOCAL enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 197 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: ExplainStmt +STMT: SelectStmt +== 198 +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: SelectStmt +== 199 +SET LOCAL enable_seqscan TO off +-- +STMT: VariableSetStmt +== 200 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: ExplainStmt +STMT: SelectStmt +== 201 +SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: SelectStmt +== 202 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 203 +COMMIT +-- +STMT: TransactionStmt +== 204 +-- fetch timestamps from before the next test +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +== 205 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 206 +-- assume a minimum timestamp granularity of 100ms + +-- cause one sequential scan +BEGIN +-- +STMT: TransactionStmt +== 207 +SET LOCAL enable_seqscan TO on +-- +STMT: VariableSetStmt +== 208 +SET LOCAL enable_indexscan TO off +-- +STMT: VariableSetStmt +== 209 +SET LOCAL enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 210 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: ExplainStmt +STMT: SelectStmt +== 211 +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: SelectStmt +== 212 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 213 +COMMIT +-- +STMT: TransactionStmt +== 214 +-- check that just sequential scan stats were incremented +SELECT seq_scan, :'test_last_seq' < last_seq_scan AS seq_ok, idx_scan, :'test_last_idx' = last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +ERROR: syntax error at or near ":" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 215 +-- fetch timestamps from before the next test +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +== 216 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 217 +-- cause one index scan +BEGIN +-- +STMT: TransactionStmt +== 218 +SET LOCAL enable_seqscan TO off +-- +STMT: VariableSetStmt +== 219 +SET LOCAL enable_indexscan TO on +-- +STMT: VariableSetStmt +== 220 +SET LOCAL enable_bitmapscan TO off +-- +STMT: VariableSetStmt +== 221 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: ExplainStmt +STMT: SelectStmt +== 222 +SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: SelectStmt +== 223 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 224 +COMMIT +-- +STMT: TransactionStmt +== 225 +-- check that just index scan stats were incremented +SELECT seq_scan, :'test_last_seq' = last_seq_scan AS seq_ok, idx_scan, :'test_last_idx' < last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +ERROR: syntax error at or near ":" +CURSORPOS: 71 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 226 +-- fetch timestamps from before the next test +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +== 227 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 228 +-- cause one bitmap index scan +BEGIN +-- +STMT: TransactionStmt +== 229 +SET LOCAL enable_seqscan TO off +-- +STMT: VariableSetStmt +== 230 +SET LOCAL enable_indexscan TO off +-- +STMT: VariableSetStmt +== 231 +SET LOCAL enable_bitmapscan TO on +-- +STMT: VariableSetStmt +== 232 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: ExplainStmt +STMT: SelectStmt +== 233 +SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: SelectStmt +== 234 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 235 +COMMIT +-- +STMT: TransactionStmt +== 236 +-- check that just index scan stats were incremented +SELECT seq_scan, :'test_last_seq' = last_seq_scan AS seq_ok, idx_scan, :'test_last_idx' < last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +ERROR: syntax error at or near ":" +CURSORPOS: 71 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 237 +----- +-- Test reset of some stats for shared table +----- + +-- This updates the comment of the database currently in use in +-- pg_shdescription with a fake value, then sets it back to its +-- original value. +SELECT shobj_description(d.oid, 'pg_database') as description_before + FROM pg_database d WHERE datname = current_database() +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +ALIAS: "d"="pg_database" +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FUNCTION: name="shobj_description" function="shobj_description" schema="" ctx=Call +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +== 238 +-- force some stats in pg_shdescription. +BEGIN +-- +STMT: TransactionStmt +== 239 +SELECT current_database() as datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +== 240 +COMMENT ON DATABASE :"datname" IS 'This is a test comment' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 241 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 242 +COMMIT +-- +STMT: TransactionStmt +== 243 +-- check that the stats are reset. +SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables + WHERE relid = 'pg_shdescription'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +== 244 +SELECT pg_stat_reset_single_table_counters('pg_shdescription'::regclass) +-- +FUNCTION: name="pg_stat_reset_single_table_counters" function="pg_stat_reset_single_table_counters" schema="" ctx=Call +STMT: SelectStmt +== 245 +SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables + WHERE relid = 'pg_shdescription'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +== 246 +-- set back comment + COMMENT ON DATABASE :"datname" IS :'description_before' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 43 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 247 +COMMENT ON DATABASE :"datname" IS NULL +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 248 +----- +-- Test that various stats views are being properly populated +----- + +-- Test that sessions is incremented when a new session is started in pg_stat_database +SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +TABLE: name="pg_stat_database" schema="" table="pg_stat_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +== 249 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 250 +SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 251 +-- Test pg_stat_checkpointer checkpointer-related stats, together with pg_stat_wal +SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer +-- +TABLE: name="pg_stat_checkpointer" schema="" table="pg_stat_checkpointer" ctx=Select +STMT: SelectStmt +== 252 +-- Test pg_stat_wal (and make a temp table so our temp schema exists) +SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal +-- +TABLE: name="pg_stat_wal" schema="" table="pg_stat_wal" ctx=Select +STMT: SelectStmt +== 253 +CREATE TEMP TABLE test_stats_temp AS SELECT 17 +-- +TABLE: name="test_stats_temp" schema="" table="test_stats_temp" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 254 +DROP TABLE test_stats_temp +-- +TABLE: name="test_stats_temp" schema="" table="test_stats_temp" ctx=DDL +STMT: DropStmt +== 255 +-- Checkpoint twice: The checkpointer reports stats after reporting completion +-- of the checkpoint. But after a second checkpoint we'll see at least the +-- results of the first. +CHECKPOINT +-- +STMT: CheckPointStmt +== 256 +CHECKPOINT +-- +STMT: CheckPointStmt +== 257 +SELECT num_requested > :rqst_ckpts_before FROM pg_stat_checkpointer +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 258 +SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 259 +-- Test pg_stat_get_backend_idset() and some allied functions. +-- In particular, verify that their notion of backend ID matches +-- our temp schema index. +SELECT (current_schemas(true))[1] = ('pg_temp_' || beid::text) AS match +FROM pg_stat_get_backend_idset() beid +WHERE pg_stat_get_backend_pid(beid) = pg_backend_pid() +-- +FUNCTION: name="pg_stat_get_backend_pid" function="pg_stat_get_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +FUNCTION: name="pg_stat_get_backend_idset" function="pg_stat_get_backend_idset" schema="" ctx=Call +FUNCTION: name="pg_stat_get_backend_pid" function="pg_stat_get_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="beid" +STMT: SelectStmt +== 260 +----- +-- Test that resetting stats works for reset timestamp +----- + +-- Test that reset_slru with a specified SLRU works. +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 261 +SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'notify' +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 262 +SELECT pg_stat_reset_slru('commit_timestamp') +-- +FUNCTION: name="pg_stat_reset_slru" function="pg_stat_reset_slru" schema="" ctx=Call +STMT: SelectStmt +== 263 +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 264 +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 265 +-- Test that multiple SLRUs are reset when no specific SLRU provided to reset function +SELECT pg_stat_reset_slru() +-- +FUNCTION: name="pg_stat_reset_slru" function="pg_stat_reset_slru" schema="" ctx=Call +STMT: SelectStmt +== 266 +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 267 +SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'notify' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 268 +-- Test that reset_shared with archiver specified as the stats type works +SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver +-- +TABLE: name="pg_stat_archiver" schema="" table="pg_stat_archiver" ctx=Select +STMT: SelectStmt +== 269 +SELECT pg_stat_reset_shared('archiver') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 270 +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 271 +-- Test that reset_shared with bgwriter specified as the stats type works +SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter +-- +TABLE: name="pg_stat_bgwriter" schema="" table="pg_stat_bgwriter" ctx=Select +STMT: SelectStmt +== 272 +SELECT pg_stat_reset_shared('bgwriter') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 273 +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 274 +-- Test that reset_shared with checkpointer specified as the stats type works +SELECT stats_reset AS checkpointer_reset_ts FROM pg_stat_checkpointer +-- +TABLE: name="pg_stat_checkpointer" schema="" table="pg_stat_checkpointer" ctx=Select +STMT: SelectStmt +== 275 +SELECT pg_stat_reset_shared('checkpointer') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 276 +SELECT stats_reset > :'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpointer +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 277 +-- Test that reset_shared with recovery_prefetch specified as the stats type works +SELECT stats_reset AS recovery_prefetch_reset_ts FROM pg_stat_recovery_prefetch +-- +TABLE: name="pg_stat_recovery_prefetch" schema="" table="pg_stat_recovery_prefetch" ctx=Select +STMT: SelectStmt +== 278 +SELECT pg_stat_reset_shared('recovery_prefetch') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 279 +SELECT stats_reset > :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_recovery_prefetch +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 280 +-- Test that reset_shared with slru specified as the stats type works +SELECT max(stats_reset) AS slru_reset_ts FROM pg_stat_slru +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 281 +SELECT pg_stat_reset_shared('slru') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 282 +SELECT max(stats_reset) > :'slru_reset_ts'::timestamptz FROM pg_stat_slru +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 283 +-- Test that reset_shared with wal specified as the stats type works +SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal +-- +TABLE: name="pg_stat_wal" schema="" table="pg_stat_wal" ctx=Select +STMT: SelectStmt +== 284 +SELECT pg_stat_reset_shared('wal') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 285 +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 286 +-- Test error case for reset_shared with unknown stats type +SELECT pg_stat_reset_shared('unknown') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 287 +-- Test that reset works for pg_stat_database + +-- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to +SELECT pg_stat_reset() +-- +FUNCTION: name="pg_stat_reset" function="pg_stat_reset" schema="" ctx=Call +STMT: SelectStmt +== 288 +SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +TABLE: name="pg_stat_database" schema="" table="pg_stat_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +== 289 +SELECT pg_stat_reset() +-- +FUNCTION: name="pg_stat_reset" function="pg_stat_reset" schema="" ctx=Call +STMT: SelectStmt +== 290 +SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 291 +---- +-- pg_stat_get_snapshot_timestamp behavior +---- +BEGIN +-- +STMT: TransactionStmt +== 292 +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +== 293 +-- no snapshot yet, return NULL +SELECT pg_stat_get_snapshot_timestamp() +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 294 +-- any attempt at accessing stats will build snapshot +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +== 295 +SELECT pg_stat_get_snapshot_timestamp() >= NOW() +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 296 +-- shows NULL again after clearing +SELECT pg_stat_clear_snapshot() +-- +FUNCTION: name="pg_stat_clear_snapshot" function="pg_stat_clear_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 297 +SELECT pg_stat_get_snapshot_timestamp() +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 298 +COMMIT +-- +STMT: TransactionStmt +== 299 +---- +-- Changing stats_fetch_consistency in a transaction. +---- +BEGIN +-- +STMT: TransactionStmt +== 300 +-- Stats filled under the cache mode +SET LOCAL stats_fetch_consistency = cache +-- +STMT: VariableSetStmt +== 301 +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +== 302 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 303 +-- Success in accessing pre-existing snapshot data. +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +== 304 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 305 +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +== 306 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 307 +-- Snapshot cleared. +SET LOCAL stats_fetch_consistency = none +-- +STMT: VariableSetStmt +== 308 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 309 +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +== 310 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 311 +ROLLBACK +-- +STMT: TransactionStmt +== 312 +---- +-- pg_stat_have_stats behavior +---- +-- fixed-numbered stats exist +SELECT pg_stat_have_stats('bgwriter', 0, 0) +-- +FUNCTION: name="pg_stat_have_stats" function="pg_stat_have_stats" schema="" ctx=Call +STMT: SelectStmt +== 313 +-- unknown stats kinds error out +SELECT pg_stat_have_stats('zaphod', 0, 0) +-- +FUNCTION: name="pg_stat_have_stats" function="pg_stat_have_stats" schema="" ctx=Call +STMT: SelectStmt +== 314 +-- db stats have objoid 0 +SELECT pg_stat_have_stats('database', :dboid, 1) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 315 +SELECT pg_stat_have_stats('database', :dboid, 0) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 316 +-- pg_stat_have_stats returns true for committed index creation +CREATE table stats_test_tab1 as select generate_series(1,10) a +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 317 +CREATE index stats_test_idx1 on stats_test_tab1(a) +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +STMT: IndexStmt +== 318 +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +== 319 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +== 320 +select a from stats_test_tab1 where a = 3 +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 321 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 322 +-- pg_stat_have_stats returns false for dropped index with stats +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 104 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 323 +DROP index stats_test_idx1 +-- +STMT: DropStmt +== 324 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 325 +-- pg_stat_have_stats returns false for rolled back index creation +BEGIN +-- +STMT: TransactionStmt +== 326 +CREATE index stats_test_idx1 on stats_test_tab1(a) +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +STMT: IndexStmt +== 327 +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +== 328 +select a from stats_test_tab1 where a = 3 +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 329 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 330 +ROLLBACK +-- +STMT: TransactionStmt +== 331 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 332 +-- pg_stat_have_stats returns true for reindex CONCURRENTLY +CREATE index stats_test_idx1 on stats_test_tab1(a) +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +STMT: IndexStmt +== 333 +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +== 334 +select a from stats_test_tab1 where a = 3 +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 335 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 336 +REINDEX index CONCURRENTLY stats_test_idx1 +-- +STMT: ReindexStmt +== 337 +-- false for previous oid +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 338 +-- true for new oid +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +== 339 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 340 +-- pg_stat_have_stats returns true for a rolled back drop index with stats +BEGIN +-- +STMT: TransactionStmt +== 341 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 342 +DROP index stats_test_idx1 +-- +STMT: DropStmt +== 343 +ROLLBACK +-- +STMT: TransactionStmt +== 344 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 345 +-- put enable_seqscan back to on +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +== 346 +-- ensure that stats accessors handle NULL input correctly +SELECT pg_stat_get_replication_slot(NULL) +-- +FUNCTION: name="pg_stat_get_replication_slot" function="pg_stat_get_replication_slot" schema="" ctx=Call +STMT: SelectStmt +== 347 +SELECT pg_stat_get_subscription_stats(NULL) +-- +FUNCTION: name="pg_stat_get_subscription_stats" function="pg_stat_get_subscription_stats" schema="" ctx=Call +STMT: SelectStmt +== 348 +-- Test that the following operations are tracked in pg_stat_io: +-- - reads of target blocks into shared buffers +-- - writes of shared buffers to permanent storage +-- - extends of relations using shared buffers +-- - fsyncs done to ensure the durability of data dirtying shared buffers +-- - shared buffer hits + +-- There is no test for blocks evicted from shared buffers, because we cannot +-- be sure of the state of shared buffers at the point the test is run. + +-- Create a regular table and insert some data to generate IOCONTEXT_NORMAL +-- extends. +SELECT sum(extends) AS io_sum_shared_before_extends + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 349 +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 350 +CREATE TABLE test_io_shared(a int) +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DDL +STMT: CreateStmt +== 351 +INSERT INTO test_io_shared SELECT i FROM generate_series(1,100)i +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 352 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 353 +SELECT sum(extends) AS io_sum_shared_after_extends + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 354 +SELECT :io_sum_shared_after_extends > :io_sum_shared_before_extends +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 355 +-- After a checkpoint, there should be some additional IOCONTEXT_NORMAL writes +-- and fsyncs. +-- See comment above for rationale for two explicit CHECKPOINTs. +CHECKPOINT +-- +STMT: CheckPointStmt +== 356 +CHECKPOINT +-- +STMT: CheckPointStmt +== 357 +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 358 +SELECT :io_sum_shared_after_writes > :io_sum_shared_before_writes +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 359 +SELECT current_setting('fsync') = 'off' + OR :io_sum_shared_after_fsyncs > :io_sum_shared_before_fsyncs +-- +ERROR: syntax error at or near ":" +CURSORPOS: 46 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 360 +-- Change the tablespace so that the table is rewritten directly, then SELECT +-- from it to cause it to be read back into shared buffers. +SELECT sum(reads) AS io_sum_shared_before_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 361 +-- Do this in a transaction to prevent spurious failures due to concurrent accesses to our newly +-- rewritten table, e.g. by autovacuum. +BEGIN +-- +STMT: TransactionStmt +== 362 +ALTER TABLE test_io_shared SET TABLESPACE regress_tblspace +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DDL +STMT: AlterTableStmt +== 363 +-- SELECT from the table so that the data is read into shared buffers and +-- context 'normal', object 'relation' reads are counted. +SELECT COUNT(*) FROM test_io_shared +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 364 +COMMIT +-- +STMT: TransactionStmt +== 365 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 366 +SELECT sum(reads) AS io_sum_shared_after_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 367 +SELECT :io_sum_shared_after_reads > :io_sum_shared_before_reads +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 368 +SELECT sum(hits) AS io_sum_shared_before_hits + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 369 +-- Select from the table again to count hits. +-- Ensure we generate hits by forcing a nested loop self-join with no +-- materialize node. The outer side's buffer will stay pinned, preventing its +-- eviction, while we loop through the inner side and generate hits. +BEGIN +-- +STMT: TransactionStmt +== 370 +SET LOCAL enable_nestloop TO on +-- +STMT: VariableSetStmt +== 371 +SET LOCAL enable_mergejoin TO off +-- +STMT: VariableSetStmt +== 372 +SET LOCAL enable_hashjoin TO off +-- +STMT: VariableSetStmt +== 373 +SET LOCAL enable_material TO off +-- +STMT: VariableSetStmt +== 374 +-- ensure plan stays as we expect it to +EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM test_io_shared t1 INNER JOIN test_io_shared t2 USING (a) +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +ALIAS: "t1"="test_io_shared" +ALIAS: "t2"="test_io_shared" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 375 +SELECT COUNT(*) FROM test_io_shared t1 INNER JOIN test_io_shared t2 USING (a) +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +ALIAS: "t1"="test_io_shared" +ALIAS: "t2"="test_io_shared" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 376 +COMMIT +-- +STMT: TransactionStmt +== 377 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 378 +SELECT sum(hits) AS io_sum_shared_after_hits + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 379 +SELECT :io_sum_shared_after_hits > :io_sum_shared_before_hits +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 380 +DROP TABLE test_io_shared +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DDL +STMT: DropStmt +== 381 +-- Test that the follow IOCONTEXT_LOCAL IOOps are tracked in pg_stat_io: +-- - eviction of local buffers in order to reuse them +-- - reads of temporary table blocks into local buffers +-- - writes of local buffers to permanent storage +-- - extends of temporary tables + +-- Set temp_buffers to its minimum so that we can trigger writes with fewer +-- inserted tuples. Do so in a new session in case temporary tables have been +-- accessed by previous tests in this session. +SET temp_buffers TO 100 +-- +STMT: VariableSetStmt +== 382 +CREATE TEMPORARY TABLE test_io_local(a int, b TEXT) +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=DDL +STMT: CreateStmt +== 383 +SELECT sum(extends) AS extends, sum(evictions) AS evictions, sum(writes) AS writes + FROM pg_stat_io + WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 384 +-- Insert tuples into the temporary table, generating extends in the stats. +-- Insert enough values that we need to reuse and write out dirty local +-- buffers, generating evictions and writes. +INSERT INTO test_io_local SELECT generate_series(1, 5000) as id, repeat('a', 200) +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 385 +-- Ensure the table is large enough to exceed our temp_buffers setting. +SELECT pg_relation_size('test_io_local') / current_setting('block_size')::int8 > 100 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +== 386 +SELECT sum(reads) AS io_sum_local_before_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 387 +-- Read in evicted buffers, generating reads. +SELECT COUNT(*) FROM test_io_local +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 388 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 389 +SELECT sum(evictions) AS evictions, + sum(reads) AS reads, + sum(writes) AS writes, + sum(extends) AS extends + FROM pg_stat_io + WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 390 +SELECT :io_sum_local_after_evictions > :io_sum_local_before_evictions, + :io_sum_local_after_reads > :io_sum_local_before_reads, + :io_sum_local_after_writes > :io_sum_local_before_writes, + :io_sum_local_after_extends > :io_sum_local_before_extends +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 391 +-- Change the tablespaces so that the temporary table is rewritten to other +-- local buffers, exercising a different codepath than standard local buffer +-- writes. +ALTER TABLE test_io_local SET TABLESPACE regress_tblspace +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=DDL +STMT: AlterTableStmt +== 392 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 393 +SELECT sum(writes) AS io_sum_local_new_tblspc_writes + FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +== 394 +SELECT :io_sum_local_new_tblspc_writes > :io_sum_local_after_writes +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 395 +RESET temp_buffers +-- +STMT: VariableSetStmt +== 396 +-- Test that reuse of strategy buffers and reads of blocks into these reused +-- buffers while VACUUMing are tracked in pg_stat_io. If there is sufficient +-- demand for shared buffers from concurrent queries, some buffers may be +-- pinned by other backends before they can be reused. In such cases, the +-- backend will evict a buffer from outside the ring and add it to the +-- ring. This is considered an eviction and not a reuse. + +-- Set wal_skip_threshold smaller than the expected size of +-- test_io_vac_strategy so that, even if wal_level is minimal, VACUUM FULL will +-- fsync the newly rewritten test_io_vac_strategy instead of writing it to WAL. +-- Writing it to WAL will result in the newly written relation pages being in +-- shared buffers -- preventing us from testing BAS_VACUUM BufferAccessStrategy +-- reads. +SET wal_skip_threshold = '1 kB' +-- +STMT: VariableSetStmt +== 397 +SELECT sum(reuses) AS reuses, sum(reads) AS reads, sum(evictions) AS evictions + FROM pg_stat_io WHERE context = 'vacuum' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +== 398 +CREATE TABLE test_io_vac_strategy(a int, b int) WITH (autovacuum_enabled = 'false') +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DDL +STMT: CreateStmt +== 399 +INSERT INTO test_io_vac_strategy SELECT i, i from generate_series(1, 4500)i +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 400 +-- Ensure that the next VACUUM will need to perform IO by rewriting the table +-- first with VACUUM (FULL). +VACUUM (FULL) test_io_vac_strategy +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DDL +STMT: VacuumStmt +== 401 +-- Use the minimum BUFFER_USAGE_LIMIT to cause reuses or evictions with the +-- smallest table possible. +VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) test_io_vac_strategy +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DDL +STMT: VacuumStmt +== 402 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 403 +SELECT sum(reuses) AS reuses, sum(reads) AS reads, sum(evictions) AS evictions + FROM pg_stat_io WHERE context = 'vacuum' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +== 404 +SELECT :io_sum_vac_strategy_after_reads > :io_sum_vac_strategy_before_reads +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 405 +SELECT (:io_sum_vac_strategy_after_reuses + :io_sum_vac_strategy_after_evictions) > + (:io_sum_vac_strategy_before_reuses + :io_sum_vac_strategy_before_evictions) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 406 +RESET wal_skip_threshold +-- +STMT: VariableSetStmt +== 407 +-- Test that extends done by a CTAS, which uses a BAS_BULKWRITE +-- BufferAccessStrategy, are tracked in pg_stat_io. +SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_before + FROM pg_stat_io WHERE context = 'bulkwrite' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +== 408 +CREATE TABLE test_io_bulkwrite_strategy AS SELECT i FROM generate_series(1,100)i +-- +TABLE: name="test_io_bulkwrite_strategy" schema="" table="test_io_bulkwrite_strategy" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 409 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +== 410 +SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_after + FROM pg_stat_io WHERE context = 'bulkwrite' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +== 411 +SELECT :io_sum_bulkwrite_strategy_extends_after > :io_sum_bulkwrite_strategy_extends_before +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 412 +-- Test IO stats reset +SELECT pg_stat_have_stats('io', 0, 0) +-- +FUNCTION: name="pg_stat_have_stats" function="pg_stat_have_stats" schema="" ctx=Call +STMT: SelectStmt +== 413 +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS io_stats_pre_reset + FROM pg_stat_io +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 414 +SELECT pg_stat_reset_shared('io') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +== 415 +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS io_stats_post_reset + FROM pg_stat_io +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 416 +SELECT :io_stats_post_reset < :io_stats_pre_reset +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 417 +-- test BRIN index doesn't block HOT update +CREATE TABLE brin_hot ( + id integer PRIMARY KEY, + val integer NOT NULL +) WITH (autovacuum_enabled = off, fillfactor = 70) +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DDL +STMT: CreateStmt +== 418 +INSERT INTO brin_hot SELECT *, 0 FROM generate_series(1, 235) +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 419 +CREATE INDEX val_brin ON brin_hot using brin(val) +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DDL +STMT: IndexStmt +== 420 +CREATE FUNCTION wait_for_hot_stats() RETURNS void AS $$ +DECLARE + start_time timestamptz := clock_timestamp(); + updated bool; +BEGIN + -- we don't want to wait forever; loop will exit after 30 seconds + FOR i IN 1 .. 300 LOOP + SELECT (pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid) > 0) INTO updated; + EXIT WHEN updated; + + -- wait a little + PERFORM pg_sleep_for('100 milliseconds'); + -- reset stats snapshot so we can test again + PERFORM pg_stat_clear_snapshot(); + END LOOP; + -- report time waited in postmaster log (where it won't change test output) + RAISE log 'wait_for_hot_stats delayed % seconds', + EXTRACT(epoch FROM clock_timestamp() - start_time); +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="wait_for_hot_stats" function="wait_for_hot_stats" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 421 +UPDATE brin_hot SET val = -3 WHERE id = 42 +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DML +STMT: UpdateStmt +== 422 +-- We can't just call wait_for_hot_stats() at this point, because we only +-- transmit stats when the session goes idle, and we probably didn't +-- transmit the last couple of counts yet thanks to the rate-limiting logic +-- in pgstat_report_stat(). But instead of waiting for the rate limiter's +-- timeout to elapse, let's just start a new session. The old one will +-- then send its stats before dying. + +SELECT wait_for_hot_stats() +-- +FUNCTION: name="wait_for_hot_stats" function="wait_for_hot_stats" schema="" ctx=Call +STMT: SelectStmt +== 423 +SELECT pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid) +-- +FUNCTION: name="pg_stat_get_tuples_hot_updated" function="pg_stat_get_tuples_hot_updated" schema="" ctx=Call +STMT: SelectStmt +== 424 +DROP TABLE brin_hot +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DDL +STMT: DropStmt +== 425 +DROP FUNCTION wait_for_hot_stats() +-- +FUNCTION: name="wait_for_hot_stats" function="wait_for_hot_stats" schema="" ctx=DDL +STMT: DropStmt +== 426 +-- Test handling of index predicates - updating attributes in precicates +-- should not block HOT when summarizing indexes are involved. We update +-- a row that was not indexed due to the index predicate, and becomes +-- indexable - the HOT-updated tuple is forwarded to the BRIN index. +CREATE TABLE brin_hot_2 (a int, b int) +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DDL +STMT: CreateStmt +== 427 +INSERT INTO brin_hot_2 VALUES (1, 100) +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 428 +CREATE INDEX ON brin_hot_2 USING brin (b) WHERE a = 2 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DDL +STMT: IndexStmt +== 429 +UPDATE brin_hot_2 SET a = 2 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DML +STMT: UpdateStmt +== 430 +EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 431 +SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 432 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +== 433 +EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +== 434 +SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 435 +DROP TABLE brin_hot_2 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DDL +STMT: DropStmt +== 436 +-- Test that updates to indexed columns are still propagated to the +-- BRIN column. +-- https://postgr.es/m/05ebcb44-f383-86e3-4f31-0a97a55634cf@enterprisedb.com +CREATE TABLE brin_hot_3 (a int, filler text) WITH (fillfactor = 10) +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DDL +STMT: CreateStmt +== 437 +INSERT INTO brin_hot_3 SELECT 1, repeat(' ', 500) FROM generate_series(1, 20) +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 438 +CREATE INDEX ON brin_hot_3 USING brin (a) WITH (pages_per_range = 1) +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DDL +STMT: IndexStmt +== 439 +UPDATE brin_hot_3 SET a = 2 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DML +STMT: UpdateStmt +== 440 +EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_3 WHERE a = 2 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 441 +SELECT COUNT(*) FROM brin_hot_3 WHERE a = 2 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 442 +DROP TABLE brin_hot_3 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DDL +STMT: DropStmt +== 443 +SET enable_seqscan = on +-- +STMT: VariableSetStmt +== 444 +-- Test that estimation of relation size works with tuples wider than the +-- relation fillfactor. We create a table with wide inline attributes and +-- low fillfactor, insert rows and then see how many rows EXPLAIN shows +-- before running analyze. We disable autovacuum so that it does not +-- interfere with the test. +CREATE TABLE table_fillfactor ( + n char(1000) +) with (fillfactor=10, autovacuum_enabled=off) +-- +TABLE: name="table_fillfactor" schema="" table="table_fillfactor" ctx=DDL +STMT: CreateStmt +== 445 +INSERT INTO table_fillfactor +SELECT 'x' FROM generate_series(1,1000) +-- +TABLE: name="table_fillfactor" schema="" table="table_fillfactor" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 446 +SELECT * FROM check_estimated_rows('SELECT * FROM table_fillfactor') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 447 +DROP TABLE table_fillfactor +-- +TABLE: name="table_fillfactor" schema="" table="table_fillfactor" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/stats_ext.metadata.json b/parser/testdata/summary/postgres_regress/stats_ext.metadata.json new file mode 100644 index 0000000..b2f6706 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/stats_ext.metadata.json @@ -0,0 +1,820 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816" + ] +} diff --git a/parser/testdata/summary/postgres_regress/stats_ext.test b/parser/testdata/summary/postgres_regress/stats_ext.test new file mode 100644 index 0000000..a7ed210 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/stats_ext.test @@ -0,0 +1,4569 @@ +== 001 +-- Generic extended statistics support + +|-- +-- Note: tables for which we check estimated row counts should be created +-- with autovacuum_enabled = off, so that we don't have unstable results +-- from auto-analyze happening when we didn't expect it. +|-- + +-- check the number of estimated/actual rows in the top node +create function check_estimated_rows(text) returns table (estimated int, actual int) +language plpgsql as +$$ +declare + ln text; + tmp text[]; + first_row bool := true; +begin + for ln in + execute format('explain analyze %s', $1) + loop + if first_row then + first_row := false; + tmp := regexp_match(ln, 'rows=(\d*) .* rows=(\d*)'); + return query select tmp[1]::int, tmp[2]::int; + end if; + end loop; +end; +$$ +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 002 +-- Verify failures +CREATE TABLE ext_stats_test (x text, y int, z int) +-- +TABLE: name="ext_stats_test" schema="" table="ext_stats_test" ctx=DDL +STMT: CreateStmt +== 003 +CREATE STATISTICS tst +-- +ERROR: syntax error at end of input +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +CREATE STATISTICS tst ON a, b +-- +ERROR: syntax error at end of input +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +CREATE STATISTICS tst FROM sometab +-- +ERROR: syntax error at or near "FROM" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +CREATE STATISTICS tst ON a, b FROM nonexistent +-- +STMT: CreateStatsStmt +== 007 +CREATE STATISTICS tst ON a, b FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 008 +CREATE STATISTICS tst ON x, x, y FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 009 +CREATE STATISTICS tst ON x, x, y, x, x, y, x, x, y FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 010 +CREATE STATISTICS tst ON x, x, y, x, x, (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1) FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 011 +CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1) FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 012 +CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), y FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 013 +CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 014 +-- unsupported targets +CREATE STATISTICS tst ON a FROM (VALUES (x)) AS foo +-- +STMT: CreateStatsStmt +== 015 +CREATE STATISTICS tst ON a FROM foo NATURAL JOIN bar +-- +STMT: CreateStatsStmt +== 016 +CREATE STATISTICS tst ON a FROM (SELECT * FROM ext_stats_test) AS foo +-- +STMT: CreateStatsStmt +== 017 +CREATE STATISTICS tst ON a FROM ext_stats_test s TABLESAMPLE system (x) +-- +STMT: CreateStatsStmt +== 018 +CREATE STATISTICS tst ON a FROM XMLTABLE('foo' PASSING 'bar' COLUMNS a text) +-- +STMT: CreateStatsStmt +== 019 +CREATE STATISTICS tst ON a FROM JSON_TABLE(jsonb '123', '$' COLUMNS (item int)) +-- +STMT: CreateStatsStmt +== 020 +CREATE FUNCTION tftest(int) returns table(a int, b int) as $$ +SELECT $1, $1+i FROM generate_series(1,5) g(i); +$$ LANGUAGE sql IMMUTABLE STRICT +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 021 +CREATE STATISTICS alt_stat2 ON a FROM tftest(1) +-- +STMT: CreateStatsStmt +== 022 +DROP FUNCTION tftest +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: DropStmt +== 023 +-- incorrect expressions +CREATE STATISTICS tst ON (y) FROM ext_stats_test +-- +STMT: CreateStatsStmt +== 024 +-- single column reference +CREATE STATISTICS tst ON y + z FROM ext_stats_test +-- +ERROR: syntax error at or near "+" +CURSORPOS: 55 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 025 +-- missing parentheses +CREATE STATISTICS tst ON (x, y) FROM ext_stats_test +-- +ERROR: syntax error at or near "," +CURSORPOS: 51 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +-- tuple expression +DROP TABLE ext_stats_test +-- +TABLE: name="ext_stats_test" schema="" table="ext_stats_test" ctx=DDL +STMT: DropStmt +== 027 +-- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it +CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +== 028 +CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +== 029 +COMMENT ON STATISTICS ab1_a_b_stats IS 'new comment' +-- +STMT: CommentStmt +== 030 +CREATE ROLE regress_stats_ext +-- +STMT: CreateRoleStmt +== 031 +SET SESSION AUTHORIZATION regress_stats_ext +-- +STMT: VariableSetStmt +== 032 +COMMENT ON STATISTICS ab1_a_b_stats IS 'changed comment' +-- +STMT: CommentStmt +== 033 +DROP STATISTICS ab1_a_b_stats +-- +STMT: DropStmt +== 034 +ALTER STATISTICS ab1_a_b_stats RENAME TO ab1_a_b_stats_new +-- +STMT: RenameStmt +== 035 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 036 +DROP ROLE regress_stats_ext +-- +STMT: DropRoleStmt +== 037 +CREATE STATISTICS pg_temp.stats_ext_temp ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +== 038 +SELECT regexp_replace(pg_describe_object(tableoid, oid, 0), + 'pg_temp_[0-9]*', 'pg_temp_REDACTED') AS descr, + pg_statistics_obj_is_visible(oid) AS visible + FROM pg_statistic_ext + WHERE stxname = 'stats_ext_temp' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_statistics_obj_is_visible" function="pg_statistics_obj_is_visible" schema="" ctx=Call +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +== 039 +DROP STATISTICS stats_ext_temp +-- +STMT: DropStmt +== 040 +-- shall fail +DROP STATISTICS pg_temp.stats_ext_temp +-- +STMT: DropStmt +== 041 +CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +== 042 +DROP STATISTICS ab1_a_b_stats +-- +STMT: DropStmt +== 043 +CREATE SCHEMA regress_schema_2 +-- +STMT: CreateSchemaStmt +== 044 +CREATE STATISTICS regress_schema_2.ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +== 045 +-- Let's also verify the pg_get_statisticsobjdef output looks sane. +SELECT pg_get_statisticsobjdef(oid) FROM pg_statistic_ext WHERE stxname = 'ab1_a_b_stats' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FUNCTION: name="pg_get_statisticsobjdef" function="pg_get_statisticsobjdef" schema="" ctx=Call +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +== 046 +DROP STATISTICS regress_schema_2.ab1_a_b_stats +-- +STMT: DropStmt +== 047 +-- Ensure statistics are dropped when columns are +CREATE STATISTICS ab1_b_c_stats ON b, c FROM ab1 +-- +STMT: CreateStatsStmt +== 048 +CREATE STATISTICS ab1_a_b_c_stats ON a, b, c FROM ab1 +-- +STMT: CreateStatsStmt +== 049 +CREATE STATISTICS ab1_b_a_stats ON b, a FROM ab1 +-- +STMT: CreateStatsStmt +== 050 +ALTER TABLE ab1 DROP COLUMN a +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: AlterTableStmt +== 051 +-- Ensure statistics are dropped when table is +SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +== 052 +DROP TABLE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +== 053 +SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +== 054 +-- Ensure things work sanely with SET STATISTICS 0 +CREATE TABLE ab1 (a INTEGER, b INTEGER) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +== 055 +ALTER TABLE ab1 ALTER a SET STATISTICS 0 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: AlterTableStmt +== 056 +INSERT INTO ab1 SELECT a, a%23 FROM generate_series(1, 1000) a +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 057 +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +== 058 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +== 059 +ALTER TABLE ab1 ALTER a SET STATISTICS -1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: AlterTableStmt +== 060 +-- setting statistics target 0 skips the statistics, without printing any message, so check catalog +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0 +-- +STMT: AlterStatsStmt +== 061 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +== 062 +SELECT stxname, stxdndistinct, stxddependencies, stxdmcv, stxdinherit + FROM pg_statistic_ext s LEFT JOIN pg_statistic_ext_data d ON (d.stxoid = s.oid) + WHERE s.stxname = 'ab1_a_b_stats' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxname" +STMT: SelectStmt +== 063 +ALTER STATISTICS ab1_a_b_stats SET STATISTICS -1 +-- +STMT: AlterStatsStmt +== 064 +-- partial analyze doesn't build stats either +ANALYZE ab1 (a) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +== 065 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +== 066 +DROP TABLE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +== 067 +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0 +-- +STMT: AlterStatsStmt +== 068 +ALTER STATISTICS IF EXISTS ab1_a_b_stats SET STATISTICS 0 +-- +STMT: AlterStatsStmt +== 069 +-- Ensure we can build statistics for tables with inheritance. +CREATE TABLE ab1 (a INTEGER, b INTEGER) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +== 070 +CREATE TABLE ab1c () INHERITS (ab1) +-- +TABLE: name="ab1c" schema="" table="ab1c" ctx=DDL +STMT: CreateStmt +== 071 +INSERT INTO ab1 VALUES (1,1) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +== 073 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +== 074 +DROP TABLE ab1 CASCADE +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +== 075 +-- Tests for stats with inheritance +CREATE TABLE stxdinh(a int, b int) +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +STMT: CreateStmt +== 076 +CREATE TABLE stxdinh1() INHERITS(stxdinh) +-- +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +STMT: CreateStmt +== 077 +CREATE TABLE stxdinh2() INHERITS(stxdinh) +-- +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: CreateStmt +== 078 +INSERT INTO stxdinh SELECT mod(a,50), mod(a,100) FROM generate_series(0, 1999) a +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO stxdinh1 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a +-- +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO stxdinh2 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a +-- +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 081 +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2 +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: VacuumStmt +== 082 +-- Ensure non-inherited stats are not applied to inherited query +-- Without stats object, it looks like this +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 084 +CREATE STATISTICS stxdinh ON a, b FROM stxdinh +-- +STMT: CreateStatsStmt +== 085 +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2 +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: VacuumStmt +== 086 +-- See if the extended stats affect the estimates +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 087 +-- Dependencies are applied at individual relations (within append), so +-- this estimate changes a bit because we improve estimates for the parent +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 088 +-- Ensure correct (non-inherited) stats are applied to inherited query +SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 089 +SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 090 +DROP TABLE stxdinh, stxdinh1, stxdinh2 +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: DropStmt +== 091 +-- Ensure inherited stats ARE applied to inherited query in partitioned table +CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i) +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DDL +STMT: CreateStmt +== 092 +CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100) +-- +TABLE: name="stxdinp1" schema="" table="stxdinp1" ctx=DDL +STMT: CreateStmt +== 093 +INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 094 +CREATE STATISTICS stxdinp ON (a + 1), a, b FROM stxdinp +-- +STMT: CreateStatsStmt +== 095 +VACUUM ANALYZE stxdinp +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DDL +STMT: VacuumStmt +== 096 +-- partitions are processed recursively +SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxrelid" +STMT: SelectStmt +== 097 +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 098 +SELECT * FROM check_estimated_rows('SELECT a + 1, b FROM ONLY stxdinp GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 099 +DROP TABLE stxdinp +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DDL +STMT: DropStmt +== 100 +-- basic test for statistics on expressions +CREATE TABLE ab1 (a INTEGER, b INTEGER, c TIMESTAMP, d TIMESTAMPTZ) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +== 101 +-- expression stats may be built on a single expression column +CREATE STATISTICS ab1_exprstat_1 ON (a+b) FROM ab1 +-- +STMT: CreateStatsStmt +== 102 +-- with a single expression, we only enable expression statistics +CREATE STATISTICS ab1_exprstat_2 ON (a+b) FROM ab1 +-- +STMT: CreateStatsStmt +== 103 +SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_2' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +== 104 +-- adding anything to the expression builds all statistics kinds +CREATE STATISTICS ab1_exprstat_3 ON (a+b), a FROM ab1 +-- +STMT: CreateStatsStmt +== 105 +SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_3' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +== 106 +-- date_trunc on timestamptz is not immutable, but that should not matter +CREATE STATISTICS ab1_exprstat_4 ON date_trunc('day', d) FROM ab1 +-- +STMT: CreateStatsStmt +== 107 +-- date_trunc on timestamp is immutable +CREATE STATISTICS ab1_exprstat_5 ON date_trunc('day', c) FROM ab1 +-- +STMT: CreateStatsStmt +== 108 +-- check use of a boolean-returning expression +CREATE STATISTICS ab1_exprstat_6 ON + (case a when 1 then true else false end), b FROM ab1 +-- +STMT: CreateStatsStmt +== 109 +-- insert some data and run analyze, to test that these cases build properly +INSERT INTO ab1 +SELECT x / 10, x / 3, + '2020-10-01'::timestamp + x * interval '1 day', + '2020-10-01'::timestamptz + x * interval '1 day' +FROM generate_series(1, 100) x +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 110 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +== 111 +-- apply some stats +SELECT * FROM check_estimated_rows('SELECT * FROM ab1 WHERE (case a when 1 then true else false end) AND b=2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 112 +DROP TABLE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +== 113 +-- Verify supported object types for extended statistics +CREATE schema tststats +-- +STMT: CreateSchemaStmt +== 114 +CREATE TABLE tststats.t (a int, b int, c text) +-- +TABLE: name="tststats.t" schema="tststats" table="t" ctx=DDL +STMT: CreateStmt +== 115 +CREATE INDEX ti ON tststats.t (a, b) +-- +TABLE: name="tststats.t" schema="tststats" table="t" ctx=DDL +STMT: IndexStmt +== 116 +CREATE SEQUENCE tststats.s +-- +STMT: CreateSeqStmt +== 117 +CREATE VIEW tststats.v AS SELECT * FROM tststats.t +-- +TABLE: name="tststats.v" schema="tststats" table="v" ctx=DDL +TABLE: name="tststats.t" schema="tststats" table="t" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 118 +CREATE MATERIALIZED VIEW tststats.mv AS SELECT * FROM tststats.t +-- +TABLE: name="tststats.mv" schema="tststats" table="mv" ctx=DDL +TABLE: name="tststats.t" schema="tststats" table="t" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 119 +CREATE TYPE tststats.ty AS (a int, b int, c text) +-- +STMT: CompositeTypeStmt +== 120 +CREATE FOREIGN DATA WRAPPER extstats_dummy_fdw +-- +STMT: CreateFdwStmt +== 121 +CREATE SERVER extstats_dummy_srv FOREIGN DATA WRAPPER extstats_dummy_fdw +-- +STMT: CreateForeignServerStmt +== 122 +CREATE FOREIGN TABLE tststats.f (a int, b int, c text) SERVER extstats_dummy_srv +-- +STMT: CreateForeignTableStmt +== 123 +CREATE TABLE tststats.pt (a int, b int, c text) PARTITION BY RANGE (a, b) +-- +TABLE: name="tststats.pt" schema="tststats" table="pt" ctx=DDL +STMT: CreateStmt +== 124 +CREATE TABLE tststats.pt1 PARTITION OF tststats.pt FOR VALUES FROM (-10, -10) TO (10, 10) +-- +TABLE: name="tststats.pt1" schema="tststats" table="pt1" ctx=DDL +STMT: CreateStmt +== 125 +CREATE STATISTICS tststats.s1 ON a, b FROM tststats.t +-- +STMT: CreateStatsStmt +== 126 +CREATE STATISTICS tststats.s2 ON a, b FROM tststats.ti +-- +STMT: CreateStatsStmt +== 127 +CREATE STATISTICS tststats.s3 ON a, b FROM tststats.s +-- +STMT: CreateStatsStmt +== 128 +CREATE STATISTICS tststats.s4 ON a, b FROM tststats.v +-- +STMT: CreateStatsStmt +== 129 +CREATE STATISTICS tststats.s5 ON a, b FROM tststats.mv +-- +STMT: CreateStatsStmt +== 130 +CREATE STATISTICS tststats.s6 ON a, b FROM tststats.ty +-- +STMT: CreateStatsStmt +== 131 +CREATE STATISTICS tststats.s7 ON a, b FROM tststats.f +-- +STMT: CreateStatsStmt +== 132 +CREATE STATISTICS tststats.s8 ON a, b FROM tststats.pt +-- +STMT: CreateStatsStmt +== 133 +CREATE STATISTICS tststats.s9 ON a, b FROM tststats.pt1 +-- +STMT: CreateStatsStmt +== 134 +DO $$ +DECLARE + relname text := reltoastrelid::regclass FROM pg_class WHERE oid = 'tststats.t'::regclass; +BEGIN + EXECUTE 'CREATE STATISTICS tststats.s10 ON a, b FROM ' || relname; +EXCEPTION WHEN wrong_object_type THEN + RAISE NOTICE 'stats on toast table not created'; +END; +$$ +-- +STMT: DoStmt +== 135 +DROP SCHEMA tststats CASCADE +-- +STMT: DropStmt +== 136 +DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE +-- +STMT: DropStmt +== 137 +-- n-distinct tests +CREATE TABLE ndistinct ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b INT, + filler3 DATE, + c INT, + d INT +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: CreateStmt +== 138 +-- over-estimates when using only per-column statistics +INSERT INTO ndistinct (a, b, c, filler1) + SELECT i/100, i/100, i/100, (i/100) || ' dollars and zero cents' + FROM generate_series(1,1000) s(i) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 139 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 140 +-- Group Aggregate, due to over-estimate of the number of groups +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 142 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 143 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 144 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 145 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 146 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 147 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 148 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 149 +-- correct command +CREATE STATISTICS s10 ON a, b, c FROM ndistinct +-- +STMT: CreateStatsStmt +== 150 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 151 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 152 +-- minor improvement, make sure the ctid does not break the matching +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 153 +-- Hash Aggregate, thanks to estimates improved by the statistic +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 154 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 156 +-- partial improvement (match on attributes) +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 157 +-- expressions - no improvement +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 158 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 159 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 160 +-- last two plans keep using Group Aggregate, because 'd' is not covered +-- by the statistic and while it's NULL-only we assume 200 values for it +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 161 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 162 +TRUNCATE TABLE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: TruncateStmt +== 163 +-- under-estimates when using only per-column statistics +INSERT INTO ndistinct (a, b, c, filler1) + SELECT mod(i,13), mod(i,17), mod(i,19), + mod(i,23) || ' dollars and zero cents' + FROM generate_series(1,1000) s(i) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 164 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 165 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 166 +-- correct estimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 167 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 168 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 169 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 170 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 171 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 172 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 173 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 174 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 175 +DROP STATISTICS s10 +-- +STMT: DropStmt +== 176 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 177 +-- dropping the statistics results in under-estimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 178 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 179 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 180 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 181 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 182 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 183 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 184 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 185 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 186 +-- ndistinct estimates with statistics on expressions +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 187 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 188 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 189 +CREATE STATISTICS s10 (ndistinct) ON (a+1), (b+100), (2*c) FROM ndistinct +-- +STMT: CreateStatsStmt +== 190 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 191 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 192 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 193 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 194 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 195 +DROP STATISTICS s10 +-- +STMT: DropStmt +== 196 +-- a mix of attributes and expressions +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 197 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 198 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 199 +CREATE STATISTICS s10 (ndistinct) ON a, b, (2*c) FROM ndistinct +-- +STMT: CreateStatsStmt +== 200 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 201 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 202 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 203 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 204 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 205 +DROP STATISTICS s10 +-- +STMT: DropStmt +== 206 +-- combination of multiple ndistinct statistics, with/without expressions +TRUNCATE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: TruncateStmt +== 207 +-- two mostly independent groups of columns +INSERT INTO ndistinct (a, b, c, d) + SELECT mod(i,3), mod(i,9), mod(i,5), mod(i,20) + FROM generate_series(1,1000) s(i) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 208 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 209 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 210 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 211 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 212 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 213 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 214 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 215 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 216 +-- basic statistics on both attributes (no expressions) +CREATE STATISTICS s11 (ndistinct) ON a, b FROM ndistinct +-- +STMT: CreateStatsStmt +== 217 +CREATE STATISTICS s12 (ndistinct) ON c, d FROM ndistinct +-- +STMT: CreateStatsStmt +== 218 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 219 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 220 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 221 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 222 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 223 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 224 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 225 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 226 +-- replace the second statistics by statistics on expressions + +DROP STATISTICS s12 +-- +STMT: DropStmt +== 227 +CREATE STATISTICS s12 (ndistinct) ON (c * 10), (d - 1) FROM ndistinct +-- +STMT: CreateStatsStmt +== 228 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 229 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 232 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 233 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 234 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 235 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 236 +-- replace the second statistics by statistics on both attributes and expressions + +DROP STATISTICS s12 +-- +STMT: DropStmt +== 237 +CREATE STATISTICS s12 (ndistinct) ON c, d, (c * 10), (d - 1) FROM ndistinct +-- +STMT: CreateStatsStmt +== 238 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 239 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 240 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 241 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 242 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 243 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 244 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 245 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 246 +-- replace the other statistics by statistics on both attributes and expressions + +DROP STATISTICS s11 +-- +STMT: DropStmt +== 247 +CREATE STATISTICS s11 (ndistinct) ON a, b, (a*5), (b+1) FROM ndistinct +-- +STMT: CreateStatsStmt +== 248 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 249 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 250 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 251 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 252 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 253 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 254 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 255 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 256 +-- replace statistics by somewhat overlapping ones (this expected to get worse estimate +-- because the first statistics shall be applied to 3 columns, and the second one can't +-- be really applied) + +DROP STATISTICS s11 +-- +STMT: DropStmt +== 257 +DROP STATISTICS s12 +-- +STMT: DropStmt +== 258 +CREATE STATISTICS s11 (ndistinct) ON a, b, (a*5), (b+1) FROM ndistinct +-- +STMT: CreateStatsStmt +== 259 +CREATE STATISTICS s12 (ndistinct) ON a, (b+1), (c * 10) FROM ndistinct +-- +STMT: CreateStatsStmt +== 260 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +== 261 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 262 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 263 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 264 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 265 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 266 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 267 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 268 +DROP STATISTICS s11 +-- +STMT: DropStmt +== 269 +DROP STATISTICS s12 +-- +STMT: DropStmt +== 270 +-- functional dependencies tests +CREATE TABLE functional_dependencies ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b TEXT, + filler3 DATE, + c INT, + d TEXT +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: CreateStmt +== 271 +CREATE INDEX fdeps_ab_idx ON functional_dependencies (a, b) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: IndexStmt +== 272 +CREATE INDEX fdeps_abc_idx ON functional_dependencies (a, b, c) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: IndexStmt +== 273 +-- random data (no functional dependencies) +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT mod(i, 5), mod(i, 7), mod(i, 11), i FROM generate_series(1,1000) s(i) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 274 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 275 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 276 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 277 +-- create statistics +CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies +-- +STMT: CreateStatsStmt +== 278 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 279 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 280 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 281 +-- a => b, a => c, b => c +TRUNCATE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: TruncateStmt +== 282 +DROP STATISTICS func_deps_stat +-- +STMT: DropStmt +== 283 +-- now do the same thing, but with expressions +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,5000) s(i) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 284 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 285 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 286 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1 AND mod(c, 7) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 287 +-- create statistics +CREATE STATISTICS func_deps_stat (dependencies) ON (mod(a,11)), (mod(b::int, 13)), (mod(c, 7)) FROM functional_dependencies +-- +STMT: CreateStatsStmt +== 288 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 289 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 290 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1 AND mod(c, 7) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 291 +-- a => b, a => c, b => c +TRUNCATE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: TruncateStmt +== 292 +DROP STATISTICS func_deps_stat +-- +STMT: DropStmt +== 293 +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), i FROM generate_series(1,5000) s(i) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 294 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 295 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 296 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 297 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 298 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 299 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 300 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 301 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 302 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c IN (1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 303 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 27, 51, 52, 76, 77) AND b IN (''1'', ''2'', ''26'', ''27'') AND c IN (1, 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 304 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 305 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 306 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 307 +-- OR clauses referencing different attributes +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1'') AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 308 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 309 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 310 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 311 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 312 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = ANY (ARRAY[1])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 313 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 26, 27, 51, 52, 76, 77]) AND b = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND c = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 314 +-- ANY with inequalities should not benefit from functional dependencies +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1, 51]) AND b > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 315 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1, 51]) AND b <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 316 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1, 2, 51, 52]) AND b >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 317 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 318 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 319 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 320 +-- create statistics +CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies +-- +STMT: CreateStatsStmt +== 321 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 322 +-- print the detected dependencies +SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat' +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +FILTER: schema="" table="" column="statistics_name" +STMT: SelectStmt +== 323 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 324 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 325 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 326 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 327 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 328 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 329 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 330 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c IN (1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 331 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 27, 51, 52, 76, 77) AND b IN (''1'', ''2'', ''26'', ''27'') AND c IN (1, 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 332 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 333 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 334 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 335 +-- OR clauses referencing different attributes are incompatible +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1'') AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 336 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 337 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 338 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 339 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 340 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = ANY (ARRAY[1])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 341 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 26, 27, 51, 52, 76, 77]) AND b = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND c = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 342 +-- ANY with inequalities should not benefit from functional dependencies +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1, 51]) AND b > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 343 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1, 51]) AND b <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 344 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1, 2, 51, 52]) AND b >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 345 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 346 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 347 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 348 +-- changing the type of column c causes all its stats to be dropped, reverting +-- to default estimates without any statistics, i.e. 0.5% selectivity for each +-- condition +ALTER TABLE functional_dependencies ALTER COLUMN c TYPE numeric +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: AlterTableStmt +== 349 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 350 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 351 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 352 +DROP STATISTICS func_deps_stat +-- +STMT: DropStmt +== 353 +-- now try functional dependencies with expressions + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 354 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'' AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 355 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 356 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 357 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 358 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 359 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 360 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) IN (2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 361 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 52, 54, 102, 104, 152, 154) AND upper(b) IN (''1'', ''2'', ''26'', ''27'') AND (c + 1) IN (2, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 362 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 363 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 364 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 4 OR (a * 2) = 102 OR (a * 2) = 104) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 365 +-- OR clauses referencing different attributes +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR upper(b) = ''1'') AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 366 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 367 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 368 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 102, 104]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 369 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 370 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = ANY (ARRAY[2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 371 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 52, 54, 102, 104, 152, 154]) AND upper(b) = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND (c + 1) = ANY (ARRAY[2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 372 +-- ANY with inequalities should not benefit from functional dependencies +-- the estimates however improve thanks to having expression statistics +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (ARRAY[2, 102]) AND upper(b) > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 373 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (ARRAY[2, 102]) AND upper(b) <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 374 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (ARRAY[2, 4, 102, 104]) AND upper(b) >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 375 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 376 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 377 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 378 +-- create statistics on expressions +CREATE STATISTICS func_deps_stat (dependencies) ON (a * 2), upper(b), (c + 1) FROM functional_dependencies +-- +STMT: CreateStatsStmt +== 379 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +== 380 +-- print the detected dependencies +SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat' +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +FILTER: schema="" table="" column="statistics_name" +STMT: SelectStmt +== 381 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 382 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'' AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 383 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 384 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 385 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 386 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 387 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 388 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) IN (2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 389 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 52, 54, 102, 104, 152, 154) AND upper(b) IN (''1'', ''2'', ''26'', ''27'') AND (c + 1) IN (2, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 390 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 391 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 392 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 4 OR (a * 2) = 102 OR (a * 2) = 104) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 393 +-- OR clauses referencing different attributes +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR upper(b) = ''1'') AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 394 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 395 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 396 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 102, 104]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 397 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 398 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = ANY (ARRAY[2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 399 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 52, 54, 102, 104, 152, 154]) AND upper(b) = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND (c + 1) = ANY (ARRAY[2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 400 +-- ANY with inequalities should not benefit from functional dependencies +-- the estimates however improve thanks to having expression statistics +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (ARRAY[2, 102]) AND upper(b) > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 401 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (ARRAY[2, 102]) AND upper(b) <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 402 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (ARRAY[2, 4, 102, 104]) AND upper(b) >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 403 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 404 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 405 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 406 +-- check the ability to use multiple functional dependencies +CREATE TABLE functional_dependencies_multi ( + a INTEGER, + b INTEGER, + c INTEGER, + d INTEGER +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: CreateStmt +== 407 +INSERT INTO functional_dependencies_multi (a, b, c, d) + SELECT + mod(i,7), + mod(i,7), + mod(i,11), + mod(i,11) + FROM generate_series(1,5000) s(i) +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 408 +ANALYZE functional_dependencies_multi +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: VacuumStmt +== 409 +-- estimates without any functional dependencies +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 410 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0 = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 411 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 412 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 413 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b = 0 AND 0 = c AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 414 +-- create separate functional dependencies +CREATE STATISTICS functional_dependencies_multi_1 (dependencies) ON a, b FROM functional_dependencies_multi +-- +STMT: CreateStatsStmt +== 415 +CREATE STATISTICS functional_dependencies_multi_2 (dependencies) ON c, d FROM functional_dependencies_multi +-- +STMT: CreateStatsStmt +== 416 +ANALYZE functional_dependencies_multi +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: VacuumStmt +== 417 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 418 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0 = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 419 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 420 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 421 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b = 0 AND 0 = c AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 422 +DROP TABLE functional_dependencies_multi +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: DropStmt +== 423 +-- MCV lists +CREATE TABLE mcv_lists ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b VARCHAR, + filler3 DATE, + c INT, + d TEXT, + ia INT[] +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: CreateStmt +== 424 +-- random data (no MCV list) +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT mod(i,37), mod(i,41), mod(i,43), mod(i,47) FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 425 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 426 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 427 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 428 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists +-- +STMT: CreateStatsStmt +== 429 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 430 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 431 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 432 +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +== 433 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +== 434 +-- random data (no MCV list), but with expression +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,1000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 435 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 436 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 437 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1 AND mod(c,13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 438 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a,7)), (mod(b::int,11)), (mod(c,13)) FROM mcv_lists +-- +STMT: CreateStatsStmt +== 439 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 440 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 441 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1 AND mod(c,13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 442 +-- 100 distinct combinations, all in the MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +== 443 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +== 444 +INSERT INTO mcv_lists (a, b, c, ia, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), array[mod(i,25)], i + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 445 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 446 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 447 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 448 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 449 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 450 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 451 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 452 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 453 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 454 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 455 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 456 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 457 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 458 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 459 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 460 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b IN ( ''1'', ''2'', NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 461 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 462 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2'', NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 463 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 464 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3]) AND b IN (''1'', ''2'', NULL, ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 465 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 466 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3, NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 467 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 468 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', NULL, ''3'') AND c > ANY (ARRAY[1, 2, NULL, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 469 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 470 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c, ia FROM mcv_lists +-- +STMT: CreateStatsStmt +== 471 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 472 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 473 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 474 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 475 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 476 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 477 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 478 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 479 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 480 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 481 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 482 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 483 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 484 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 485 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 486 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 487 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b IN ( ''1'', ''2'', NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 488 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 489 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2'', NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 490 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 491 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3]) AND b IN (''1'', ''2'', NULL, ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 492 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 493 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3, NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 494 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 495 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', NULL, ''3'') AND c > ANY (ARRAY[1, 2, NULL, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 496 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 497 +-- check change of unrelated column type does not reset the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN d TYPE VARCHAR(64) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: AlterTableStmt +== 498 +SELECT d.stxdmcv IS NOT NULL + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxname" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 499 +-- check change of column type resets the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: AlterTableStmt +== 500 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 501 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 502 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 503 +-- 100 distinct combinations, all in the MCV list, but with expressions +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +== 504 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +== 505 +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,1000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 506 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 507 +-- without any stats on the expressions, we have to use default selectivities, which +-- is why the estimates here are different from the pre-computed case above + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 508 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 509 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 510 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 511 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 512 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 513 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 514 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 515 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 516 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 517 +-- create statistics with expressions only (we create three separate stats, in order not to build more complex extended stats) +CREATE STATISTICS mcv_lists_stats_1 ON (mod(a,20)) FROM mcv_lists +-- +STMT: CreateStatsStmt +== 518 +CREATE STATISTICS mcv_lists_stats_2 ON (mod(b::int,10)) FROM mcv_lists +-- +STMT: CreateStatsStmt +== 519 +CREATE STATISTICS mcv_lists_stats_3 ON (mod(c,5)) FROM mcv_lists +-- +STMT: CreateStatsStmt +== 520 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 521 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 522 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 523 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 524 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 525 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 526 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 527 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 528 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 529 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 530 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 531 +DROP STATISTICS mcv_lists_stats_1 +-- +STMT: DropStmt +== 532 +DROP STATISTICS mcv_lists_stats_2 +-- +STMT: DropStmt +== 533 +DROP STATISTICS mcv_lists_stats_3 +-- +STMT: DropStmt +== 534 +-- create statistics with both MCV and expressions +CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a,20)), (mod(b::int,10)), (mod(c,5)) FROM mcv_lists +-- +STMT: CreateStatsStmt +== 535 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 536 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 537 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 538 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 539 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 540 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 541 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 542 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 543 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 544 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 545 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 546 +-- we can't use the statistic for OR clauses that are not fully covered (missing 'd' attribute) +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,5) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 547 +-- 100 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +== 548 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +== 549 +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT + (CASE WHEN mod(i,100) = 1 THEN NULL ELSE mod(i,100) END), + (CASE WHEN mod(i,50) = 1 THEN NULL ELSE mod(i,50) END), + (CASE WHEN mod(i,25) = 1 THEN NULL ELSE mod(i,25) END), + i + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 550 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 551 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 552 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 553 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 554 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND c IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 555 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''1'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 556 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists +-- +STMT: CreateStatsStmt +== 557 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 558 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 559 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 560 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 561 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND c IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 562 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''1'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 563 +-- test pg_mcv_list_items with a very simple (single item) MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +== 564 +INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1,1000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 565 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 566 +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FUNCTION: name="pg_mcv_list_items" function="pg_mcv_list_items" schema="" ctx=Call +FILTER: schema="" table="s" column="stxname" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 567 +-- 2 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +== 568 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +== 569 +INSERT INTO mcv_lists (a, b, c, d) + SELECT + NULL, -- always NULL + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 0 END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END) + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 570 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 571 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 572 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 573 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d = ''x'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 574 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, d FROM mcv_lists +-- +STMT: CreateStatsStmt +== 575 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +== 576 +-- test pg_mcv_list_items with MCV list containing variable-length data and NULLs +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FUNCTION: name="pg_mcv_list_items" function="pg_mcv_list_items" schema="" ctx=Call +FILTER: schema="" table="s" column="stxname" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +== 577 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 578 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 579 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d = ''x'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 580 +-- mcv with pass-by-ref fixlen types, e.g. uuid +CREATE TABLE mcv_lists_uuid ( + a UUID, + b UUID, + c UUID +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: CreateStmt +== 581 +INSERT INTO mcv_lists_uuid (a, b, c) + SELECT + fipshash(mod(i,100)::text)::uuid, + fipshash(mod(i,50)::text)::uuid, + fipshash(mod(i,25)::text)::uuid + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DML +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 582 +ANALYZE mcv_lists_uuid +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: VacuumStmt +== 583 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 584 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND c = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 585 +CREATE STATISTICS mcv_lists_uuid_stats (mcv) ON a, b, c + FROM mcv_lists_uuid +-- +STMT: CreateStatsStmt +== 586 +ANALYZE mcv_lists_uuid +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: VacuumStmt +== 587 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 588 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND c = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 589 +DROP TABLE mcv_lists_uuid +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: DropStmt +== 590 +-- mcv with arrays +CREATE TABLE mcv_lists_arrays ( + a TEXT[], + b NUMERIC[], + c INT[] +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_arrays" schema="" table="mcv_lists_arrays" ctx=DDL +STMT: CreateStmt +== 591 +INSERT INTO mcv_lists_arrays (a, b, c) + SELECT + ARRAY[fipshash((i/100)::text), fipshash((i/100-1)::text), fipshash((i/100+1)::text)], + ARRAY[(i/100-1)::numeric/1000, (i/100)::numeric/1000, (i/100+1)::numeric/1000], + ARRAY[(i/100-1), i/100, (i/100+1)] + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists_arrays" schema="" table="mcv_lists_arrays" ctx=DML +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 592 +CREATE STATISTICS mcv_lists_arrays_stats (mcv) ON a, b, c + FROM mcv_lists_arrays +-- +STMT: CreateStatsStmt +== 593 +ANALYZE mcv_lists_arrays +-- +TABLE: name="mcv_lists_arrays" schema="" table="mcv_lists_arrays" ctx=DDL +STMT: VacuumStmt +== 594 +-- mcv with bool +CREATE TABLE mcv_lists_bool ( + a BOOL, + b BOOL, + c BOOL +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DDL +STMT: CreateStmt +== 595 +INSERT INTO mcv_lists_bool (a, b, c) + SELECT + (mod(i,2) = 0), (mod(i,4) = 0), (mod(i,8) = 0) + FROM generate_series(1,10000) s(i) +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 596 +ANALYZE mcv_lists_bool +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DDL +STMT: VacuumStmt +== 597 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 598 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 599 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 600 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 601 +CREATE STATISTICS mcv_lists_bool_stats (mcv) ON a, b, c + FROM mcv_lists_bool +-- +STMT: CreateStatsStmt +== 602 +ANALYZE mcv_lists_bool +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DDL +STMT: VacuumStmt +== 603 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 604 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 605 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 606 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 607 +-- mcv covering just a small fraction of data +CREATE TABLE mcv_lists_partial ( + a INT, + b INT, + c INT +) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: CreateStmt +== 608 +-- 10 frequent groups, each with 100 elements +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + mod(i,10), + mod(i,10), + mod(i,10) + FROM generate_series(0,999) s(i) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 609 +-- 100 groups that will make it to the MCV list (includes the 10 frequent ones) +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + i, + i, + i + FROM generate_series(0,99) s(i) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 610 +-- 4000 groups in total, most of which won't make it (just a single item) +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + i, + i, + i + FROM generate_series(0,3999) s(i) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 611 +ANALYZE mcv_lists_partial +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: VacuumStmt +== 612 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 613 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 614 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 615 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 616 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 617 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 618 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 619 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 620 +CREATE STATISTICS mcv_lists_partial_stats (mcv) ON a, b, c + FROM mcv_lists_partial +-- +STMT: CreateStatsStmt +== 621 +ANALYZE mcv_lists_partial +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: VacuumStmt +== 622 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 623 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 624 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 625 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 626 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 627 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 628 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 629 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 630 +DROP TABLE mcv_lists_partial +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: DropStmt +== 631 +-- check the ability to use multiple MCV lists +CREATE TABLE mcv_lists_multi ( + a INTEGER, + b INTEGER, + c INTEGER, + d INTEGER +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: CreateStmt +== 632 +INSERT INTO mcv_lists_multi (a, b, c, d) + SELECT + mod(i,5), + mod(i,5), + mod(i,7), + mod(i,7) + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 633 +ANALYZE mcv_lists_multi +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: VacuumStmt +== 634 +-- estimates without any mcv statistics +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 635 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 636 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 637 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 638 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 639 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c = 0 AND d = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 640 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 OR d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 641 +-- create separate MCV statistics +CREATE STATISTICS mcv_lists_multi_1 (mcv) ON a, b FROM mcv_lists_multi +-- +STMT: CreateStatsStmt +== 642 +CREATE STATISTICS mcv_lists_multi_2 (mcv) ON c, d FROM mcv_lists_multi +-- +STMT: CreateStatsStmt +== 643 +ANALYZE mcv_lists_multi +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: VacuumStmt +== 644 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 645 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 646 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 647 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 648 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 649 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c = 0 AND d = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 650 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 OR d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 651 +DROP TABLE mcv_lists_multi +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: DropStmt +== 652 +-- statistics on integer expressions +CREATE TABLE expr_stats (a int, b int, c int) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: CreateStmt +== 653 +INSERT INTO expr_stats SELECT mod(i,10), mod(i,10), mod(i,10) FROM generate_series(1,1000) s(i) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 654 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +== 655 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 656 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 657 +CREATE STATISTICS expr_stats_1 (mcv) ON (a+b), (a-b), (2*a), (3*b) FROM expr_stats +-- +STMT: CreateStatsStmt +== 658 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +== 659 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 660 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 661 +DROP STATISTICS expr_stats_1 +-- +STMT: DropStmt +== 662 +DROP TABLE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: DropStmt +== 663 +-- statistics on a mix columns and expressions +CREATE TABLE expr_stats (a int, b int, c int) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: CreateStmt +== 664 +INSERT INTO expr_stats SELECT mod(i,10), mod(i,10), mod(i,10) FROM generate_series(1,1000) s(i) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 665 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +== 666 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 667 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 668 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 669 +CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (2*a), (3*b), (a+b), (a-b) FROM expr_stats +-- +STMT: CreateStatsStmt +== 670 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +== 671 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 672 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 673 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 674 +DROP TABLE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: DropStmt +== 675 +-- statistics on expressions with different data types +CREATE TABLE expr_stats (a int, b name, c text) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: CreateStmt +== 676 +INSERT INTO expr_stats SELECT mod(i,10), fipshash(mod(i,10)::text), fipshash(mod(i,10)::text) FROM generate_series(1,1000) s(i) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 677 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +== 678 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AND (c || b) >= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 679 +CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (b || c), (c || b) FROM expr_stats +-- +STMT: CreateStatsStmt +== 680 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +== 681 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AND (c || b) >= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +== 682 +DROP TABLE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: DropStmt +== 683 +-- test handling of a mix of compatible and incompatible expressions +CREATE TABLE expr_stats_incompatible_test ( + c0 double precision, + c1 boolean NOT NULL +) +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DDL +STMT: CreateStmt +== 684 +CREATE STATISTICS expr_stat_comp_1 ON c0, c1 FROM expr_stats_incompatible_test +-- +STMT: CreateStatsStmt +== 685 +INSERT INTO expr_stats_incompatible_test VALUES (1234,false), (5678,true) +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 686 +ANALYZE expr_stats_incompatible_test +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DDL +STMT: VacuumStmt +== 687 +SELECT c0 FROM ONLY expr_stats_incompatible_test WHERE +( + upper('x') LIKE ('x'||('[0,1]'::int4range)) + AND + (c0 IN (0, 1) OR c1) +) +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="c0" +FILTER: schema="" table="" column="c1" +STMT: SelectStmt +== 688 +DROP TABLE expr_stats_incompatible_test +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DDL +STMT: DropStmt +== 689 +-- Permission tests. Users should not be able to see specific data values in +-- the extended statistics, if they lack permission to see those values in +-- the underlying table. +|-- +-- Currently this is only relevant for MCV stats. +CREATE SCHEMA tststats +-- +STMT: CreateSchemaStmt +== 690 +CREATE TABLE tststats.priv_test_tbl ( + a int, + b int +) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: CreateStmt +== 691 +INSERT INTO tststats.priv_test_tbl + SELECT mod(i,5), mod(i,10) FROM generate_series(1,100) s(i) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 692 +CREATE STATISTICS tststats.priv_test_stats (mcv) ON a, b + FROM tststats.priv_test_tbl +-- +STMT: CreateStatsStmt +== 693 +ANALYZE tststats.priv_test_tbl +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: VacuumStmt +== 694 +-- Check printing info about extended statistics by \dX +create table stts_t1 (a int, b int) +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DDL +STMT: CreateStmt +== 695 +create statistics (ndistinct) on a, b from stts_t1 +-- +STMT: CreateStatsStmt +== 696 +create statistics (ndistinct, dependencies) on a, b from stts_t1 +-- +STMT: CreateStatsStmt +== 697 +create statistics (ndistinct, dependencies, mcv) on a, b from stts_t1 +-- +STMT: CreateStatsStmt +== 698 +create table stts_t2 (a int, b int, c int) +-- +TABLE: name="stts_t2" schema="" table="stts_t2" ctx=DDL +STMT: CreateStmt +== 699 +create statistics on b, c from stts_t2 +-- +STMT: CreateStatsStmt +== 700 +create table stts_t3 (col1 int, col2 int, col3 int) +-- +TABLE: name="stts_t3" schema="" table="stts_t3" ctx=DDL +STMT: CreateStmt +== 701 +create statistics stts_hoge on col1, col2, col3 from stts_t3 +-- +STMT: CreateStatsStmt +== 702 +create schema stts_s1 +-- +STMT: CreateSchemaStmt +== 703 +create schema stts_s2 +-- +STMT: CreateSchemaStmt +== 704 +create statistics stts_s1.stts_foo on col1, col2 from stts_t3 +-- +STMT: CreateStatsStmt +== 705 +create statistics stts_s2.stts_yama (dependencies, mcv) on col1, col3 from stts_t3 +-- +STMT: CreateStatsStmt +== 706 +insert into stts_t1 select i,i from generate_series(1,100) i +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 707 +analyze stts_t1 +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DDL +STMT: VacuumStmt +== 708 +set search_path to public, stts_s1, stts_s2, tststats +-- +STMT: VariableSetStmt +== 709 +create statistics (mcv) ON a, b, (a+b), (a-b) FROM stts_t1 +-- +STMT: CreateStatsStmt +== 710 +create statistics (mcv) ON a, b, (a+b), (a-b) FROM stts_t1 +-- +STMT: CreateStatsStmt +== 711 +create statistics (mcv) ON (a+b), (a-b) FROM stts_t1 +-- +STMT: CreateStatsStmt +== 712 +drop statistics stts_t1_a_b_expr_expr_stat +-- +STMT: DropStmt +== 713 +drop statistics stts_t1_a_b_expr_expr_stat1 +-- +STMT: DropStmt +== 714 +drop statistics stts_t1_expr_expr_stat +-- +STMT: DropStmt +== 715 +set search_path to public, stts_s1 +-- +STMT: VariableSetStmt +== 716 +create role regress_stats_ext nosuperuser +-- +STMT: CreateRoleStmt +== 717 +set role regress_stats_ext +-- +STMT: VariableSetStmt +== 718 +reset role +-- +STMT: VariableSetStmt +== 719 +drop table stts_t1, stts_t2, stts_t3 +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DDL +TABLE: name="stts_t2" schema="" table="stts_t2" ctx=DDL +TABLE: name="stts_t3" schema="" table="stts_t3" ctx=DDL +STMT: DropStmt +== 720 +drop schema stts_s1, stts_s2 cascade +-- +STMT: DropStmt +== 721 +drop user regress_stats_ext +-- +STMT: DropRoleStmt +== 722 +reset search_path +-- +STMT: VariableSetStmt +== 723 +-- User with no access +CREATE USER regress_stats_user1 +-- +STMT: CreateRoleStmt +== 724 +GRANT USAGE ON SCHEMA tststats TO regress_stats_user1 +-- +STMT: GrantStmt +== 725 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 726 +SELECT * FROM tststats.priv_test_tbl +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +STMT: SelectStmt +== 727 +-- Permission denied + +-- Check individual columns if we don't have table privilege +SELECT * FROM tststats.priv_test_tbl + WHERE a = 1 and tststats.priv_test_tbl.* > (1, 1) is not null +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 728 +-- Attempt to gain access using a leaky operator +CREATE FUNCTION op_leak(int, int) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 729 +CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, + restrict = scalarltsel) +-- +STMT: DefineStmt +== 730 +CREATE FUNCTION op_leak(record, record) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 731 +CREATE OPERATOR <<< (procedure = op_leak, leftarg = record, rightarg = record, + restrict = scalarltsel) +-- +STMT: DefineStmt +== 732 +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 733 +-- Permission denied +SELECT * FROM tststats.priv_test_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 734 +-- Permission denied +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DML +STMT: DeleteStmt +== 735 +-- Permission denied + +-- Grant access via a security barrier view, but hide all data +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 736 +CREATE VIEW tststats.priv_test_view WITH (security_barrier=true) + AS SELECT * FROM tststats.priv_test_tbl WHERE false +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=DDL +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 737 +GRANT SELECT, DELETE ON tststats.priv_test_view TO regress_stats_user1 +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=DDL +STMT: GrantStmt +== 738 +-- Should now have access via the view, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 739 +SELECT * FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 740 +-- Should not leak +SELECT * FROM tststats.priv_test_view t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=Select +ALIAS: "t"="tststats.priv_test_view" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 741 +-- Should not leak +DELETE FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=DML +STMT: DeleteStmt +== 742 +-- Should not leak + +-- Grant table access, but hide all data with RLS +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 743 +ALTER TABLE tststats.priv_test_tbl ENABLE ROW LEVEL SECURITY +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: AlterTableStmt +== 744 +CREATE POLICY priv_test_tbl_pol ON tststats.priv_test_tbl USING (2 * a < 0) +-- +STMT: CreatePolicyStmt +== 745 +GRANT SELECT, DELETE ON tststats.priv_test_tbl TO regress_stats_user1 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: GrantStmt +== 746 +-- Should now have direct table access, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 747 +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 748 +-- Should not leak +SELECT * FROM tststats.priv_test_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 749 +-- Should not leak +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DML +STMT: DeleteStmt +== 750 +-- Should not leak + +-- Create plain inheritance parent table with no access permissions +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 751 +CREATE TABLE tststats.priv_test_parent_tbl (a int, b int) +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DDL +STMT: CreateStmt +== 752 +ALTER TABLE tststats.priv_test_tbl INHERIT tststats.priv_test_parent_tbl +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: AlterTableStmt +== 753 +-- Should not have access to parent, and should leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 754 +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 755 +-- Permission denied +SELECT * FROM tststats.priv_test_parent_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_parent_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 756 +-- Permission denied +DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DML +STMT: DeleteStmt +== 757 +-- Permission denied + +-- Grant table access to parent, but hide all data with RLS +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 758 +ALTER TABLE tststats.priv_test_parent_tbl ENABLE ROW LEVEL SECURITY +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DDL +STMT: AlterTableStmt +== 759 +CREATE POLICY priv_test_parent_tbl_pol ON tststats.priv_test_parent_tbl USING (2 * a < 0) +-- +STMT: CreatePolicyStmt +== 760 +GRANT SELECT, DELETE ON tststats.priv_test_parent_tbl TO regress_stats_user1 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DDL +STMT: GrantStmt +== 761 +-- Should now have direct table access to parent, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 762 +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 763 +-- Should not leak +SELECT * FROM tststats.priv_test_parent_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_parent_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 764 +-- Should not leak +DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DML +STMT: DeleteStmt +== 765 +-- Should not leak + +-- privilege checks for pg_stats_ext and pg_stats_ext_exprs +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 766 +CREATE TABLE stats_ext_tbl (id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, col TEXT) +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: CreateStmt +== 767 +INSERT INTO stats_ext_tbl (col) VALUES ('secret'), ('secret'), ('very secret') +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 768 +CREATE STATISTICS s_col ON id, col FROM stats_ext_tbl +-- +STMT: CreateStatsStmt +== 769 +CREATE STATISTICS s_expr ON mod(id, 2), lower(col) FROM stats_ext_tbl +-- +STMT: CreateStatsStmt +== 770 +ANALYZE stats_ext_tbl +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: VacuumStmt +== 771 +-- unprivileged role should not have access +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 772 +SELECT statistics_name, most_common_vals FROM pg_stats_ext x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +ALIAS: "x"="pg_stats_ext" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 773 +SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext_exprs" schema="" table="pg_stats_ext_exprs" ctx=Select +ALIAS: "x"="pg_stats_ext_exprs" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 774 +-- give unprivileged role ownership of table +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 775 +ALTER TABLE stats_ext_tbl OWNER TO regress_stats_user1 +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: AlterTableStmt +== 776 +-- unprivileged role should now have access +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 777 +SELECT statistics_name, most_common_vals FROM pg_stats_ext x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +ALIAS: "x"="pg_stats_ext" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 778 +SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext_exprs" schema="" table="pg_stats_ext_exprs" ctx=Select +ALIAS: "x"="pg_stats_ext_exprs" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +== 779 +-- CREATE STATISTICS checks for CREATE on the schema +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 780 +CREATE SCHEMA sts_sch1 CREATE TABLE sts_sch1.tbl (a INT, b INT, c INT GENERATED ALWAYS AS (b * 2) STORED) +-- +STMT: CreateSchemaStmt +== 781 +CREATE SCHEMA sts_sch2 +-- +STMT: CreateSchemaStmt +== 782 +GRANT USAGE ON SCHEMA sts_sch1, sts_sch2 TO regress_stats_user1 +-- +STMT: GrantStmt +== 783 +ALTER TABLE sts_sch1.tbl OWNER TO regress_stats_user1 +-- +TABLE: name="sts_sch1.tbl" schema="sts_sch1" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 784 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 785 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 786 +CREATE STATISTICS sts_sch2.fail ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 787 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 788 +GRANT CREATE ON SCHEMA sts_sch1 TO regress_stats_user1 +-- +STMT: GrantStmt +== 789 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 790 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 791 +CREATE STATISTICS sts_sch2.fail ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 792 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 793 +REVOKE CREATE ON SCHEMA sts_sch1 FROM regress_stats_user1 +-- +STMT: GrantStmt +== 794 +GRANT CREATE ON SCHEMA sts_sch2 TO regress_stats_user1 +-- +STMT: GrantStmt +== 795 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 796 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 797 +CREATE STATISTICS sts_sch2.pass1 ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 798 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 799 +GRANT CREATE ON SCHEMA sts_sch1, sts_sch2 TO regress_stats_user1 +-- +STMT: GrantStmt +== 800 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 801 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 802 +CREATE STATISTICS sts_sch2.pass2 ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +== 803 +-- re-creating statistics via ALTER TABLE bypasses checks for CREATE on schema +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 804 +REVOKE CREATE ON SCHEMA sts_sch1, sts_sch2 FROM regress_stats_user1 +-- +STMT: GrantStmt +== 805 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +== 806 +ALTER TABLE sts_sch1.tbl ALTER COLUMN a TYPE SMALLINT +-- +TABLE: name="sts_sch1.tbl" schema="sts_sch1" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 807 +ALTER TABLE sts_sch1.tbl ALTER COLUMN c SET EXPRESSION AS (a * 3) +-- +TABLE: name="sts_sch1.tbl" schema="sts_sch1" table="tbl" ctx=DDL +STMT: AlterTableStmt +== 808 +-- Tidy up +DROP OPERATOR <<< (int, int) +-- +STMT: DropStmt +== 809 +DROP FUNCTION op_leak(int, int) +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: DropStmt +== 810 +DROP OPERATOR <<< (record, record) +-- +STMT: DropStmt +== 811 +DROP FUNCTION op_leak(record, record) +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: DropStmt +== 812 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 813 +DROP TABLE stats_ext_tbl +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: DropStmt +== 814 +DROP SCHEMA tststats CASCADE +-- +STMT: DropStmt +== 815 +DROP SCHEMA sts_sch1, sts_sch2 CASCADE +-- +STMT: DropStmt +== 816 +DROP USER regress_stats_user1 +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/strings.metadata.json b/parser/testdata/summary/postgres_regress/strings.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/strings.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary/postgres_regress/strings.test b/parser/testdata/summary/postgres_regress/strings.test new file mode 100644 index 0000000..38b698b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/strings.test @@ -0,0 +1,868 @@ +== 001 +|-- +-- STRINGS +-- Test various data entry syntaxes. +|-- + +-- SQL string continuation syntax +-- E021-03 character string literals +SELECT 'first line' +' - next line' + ' - third line' + AS "Three lines to one"; + +-- illegal string continuation syntax +SELECT 'first line' +' - next line' /* this comment is not allowed here */ +' - third line' + AS "Illegal comment within continuation"; + +-- Unicode escapes +SET standard_conforming_strings TO on; + +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; +SELECT U&'a\\b' AS "a\b"; + +SELECT U&' \' UESCAPE '!' AS "tricky"; +SELECT 'tricky' AS U&"\" UESCAPE '!'; + +SELECT U&'wrong: \061'; +SELECT U&'wrong: \+0061'; +SELECT U&'wrong: +0061' UESCAPE +; +SELECT U&'wrong: +0061' UESCAPE '+'; + +SELECT U&'wrong: \db99'; +SELECT U&'wrong: \db99xy'; +SELECT U&'wrong: \db99\\'; +SELECT U&'wrong: \db99\0061'; +SELECT U&'wrong: \+00db99\+000061'; +SELECT U&'wrong: \+2FFFFF'; + +-- while we're here, check the same cases in E-style literals +SELECT E'd\u0061t\U00000061' AS "data"; +SELECT E'a\\b' AS "a\b"; +SELECT E'wrong: \u061'; +SELECT E'wrong: \U0061'; +SELECT E'wrong: \udb99'; +SELECT E'wrong: \udb99xy'; +SELECT E'wrong: \udb99\\'; +SELECT E'wrong: \udb99\u0061'; +SELECT E'wrong: \U0000db99\U00000061'; +SELECT E'wrong: \U002FFFFF'; + +SET standard_conforming_strings TO off; + +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; + +SELECT U&' \' UESCAPE '!' AS "tricky"; +SELECT 'tricky' AS U&"\" UESCAPE '!'; + +SELECT U&'wrong: \061'; +SELECT U&'wrong: \+0061'; +SELECT U&'wrong: +0061' UESCAPE '+'; + +RESET standard_conforming_strings; + +-- bytea +SET bytea_output TO hex; +SELECT E'\\xDeAdBeEf'::bytea; +SELECT E'\\x De Ad Be Ef '::bytea; +SELECT E'\\xDeAdBeE'::bytea; +SELECT E'\\xDeAdBeEx'::bytea; +SELECT E'\\xDe00BeEf'::bytea; +SELECT E'DeAdBeEf'::bytea; +SELECT E'De\\000dBeEf'::bytea; +SELECT E'De\123dBeEf'::bytea; +SELECT E'De\\123dBeEf'::bytea; +SELECT E'De\\678dBeEf'::bytea; + +SET bytea_output TO escape; +SELECT E'\\xDeAdBeEf'::bytea; +SELECT E'\\x De Ad Be Ef '::bytea; +SELECT E'\\xDe00BeEf'::bytea; +SELECT E'DeAdBeEf'::bytea; +SELECT E'De\\000dBeEf'::bytea; +SELECT E'De\\123dBeEf'::bytea; + +-- Test non-error-throwing API too +SELECT pg_input_is_valid(E'\\xDeAdBeE', 'bytea'); +SELECT * FROM pg_input_error_info(E'\\xDeAdBeE', 'bytea'); +SELECT * FROM pg_input_error_info(E'\\xDeAdBeEx', 'bytea'); +SELECT * FROM pg_input_error_info(E'foo\\99bar', 'bytea'); + +|-- +-- test conversions between various string types +-- E021-10 implicit casting among the character data types +|-- + +SELECT CAST(f1 AS text) AS "text(char)" FROM CHAR_TBL; + +SELECT CAST(f1 AS text) AS "text(varchar)" FROM VARCHAR_TBL; + +SELECT CAST(name 'namefield' AS text) AS "text(name)"; + +-- since this is an explicit cast, it should truncate w/o error: +SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; +-- note: implicit-cast case is tested in char.sql + +SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL; + +SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL; + +SELECT CAST(name 'namefield' AS char(10)) AS "char(name)"; + +SELECT CAST(f1 AS varchar) AS "varchar(text)" FROM TEXT_TBL; + +SELECT CAST(f1 AS varchar) AS "varchar(char)" FROM CHAR_TBL; + +SELECT CAST(name 'namefield' AS varchar) AS "varchar(name)"; + +|-- +-- test SQL string functions +-- E### and T### are feature reference numbers from SQL99 +|-- + +-- E021-09 trim function +SELECT TRIM(BOTH FROM ' bunch o blanks ') = 'bunch o blanks' AS "bunch o blanks"; + +SELECT TRIM(LEADING FROM ' bunch o blanks ') = 'bunch o blanks ' AS "bunch o blanks "; + +SELECT TRIM(TRAILING FROM ' bunch o blanks ') = ' bunch o blanks' AS " bunch o blanks"; + +SELECT TRIM(BOTH 'x' FROM 'xxxxxsome Xsxxxxx') = 'some Xs' AS "some Xs"; + +-- E021-06 substring expression +SELECT SUBSTRING('1234567890' FROM 3) = '34567890' AS "34567890"; + +SELECT SUBSTRING('1234567890' FROM 4 FOR 3) = '456' AS "456"; + +-- test overflow cases +SELECT SUBSTRING('string' FROM 2 FOR 2147483646) AS "tring"; +SELECT SUBSTRING('string' FROM -10 FOR 2147483646) AS "string"; +SELECT SUBSTRING('string' FROM -10 FOR -2147483646) AS "error"; + +-- T581 regular expression substring (with SQL's bizarre regexp syntax) +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"(b_d)#"%' ESCAPE '#') AS "bcd"; +-- obsolete SQL99 syntax +SELECT SUBSTRING('abcdefg' FROM 'a#"(b_d)#"%' FOR '#') AS "bcd"; + +-- No match should return NULL +SELECT SUBSTRING('abcdefg' SIMILAR '#"(b_d)#"%' ESCAPE '#') IS NULL AS "True"; + +-- Null inputs should return NULL +SELECT SUBSTRING('abcdefg' SIMILAR '%' ESCAPE NULL) IS NULL AS "True"; +SELECT SUBSTRING(NULL SIMILAR '%' ESCAPE '#') IS NULL AS "True"; +SELECT SUBSTRING('abcdefg' SIMILAR NULL ESCAPE '#') IS NULL AS "True"; + +-- The first and last parts should act non-greedy +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%#"g' ESCAPE '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a*#"%#"g*' ESCAPE '#') AS "abcdefg"; + +-- Vertical bar in any part affects only that part +SELECT SUBSTRING('abcdefg' SIMILAR 'a|b#"%#"g' ESCAPE '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%#"x|g' ESCAPE '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%|ab#"g' ESCAPE '#') AS "bcdef"; + +-- Can't have more than two part separators +SELECT SUBSTRING('abcdefg' SIMILAR 'a*#"%#"g*#"x' ESCAPE '#') AS "error"; + +-- Postgres extension: with 0 or 1 separator, assume parts 1 and 3 are empty +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%g' ESCAPE '#') AS "bcdefg"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a%g' ESCAPE '#') AS "abcdefg"; + +-- substring() with just two arguments is not allowed by SQL spec; +-- we accept it, but we interpret the pattern as a POSIX regexp not SQL +SELECT SUBSTRING('abcdefg' FROM 'c.e') AS "cde"; + +-- With a parenthesized subexpression, return only what matches the subexpr +SELECT SUBSTRING('abcdefg' FROM 'b(.*)f') AS "cde"; +-- Check case where we have a match, but not a subexpression match +SELECT SUBSTRING('foo' FROM 'foo(bar)?') IS NULL AS t; + +-- Check behavior of SIMILAR TO, which uses largely the same regexp variant +SELECT 'abcdefg' SIMILAR TO '_bcd%' AS true; +SELECT 'abcdefg' SIMILAR TO 'bcd%' AS false; +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '#' AS false; +SELECT 'abcd%' SIMILAR TO '_bcd#%' ESCAPE '#' AS true; +-- Postgres uses '\' as the default escape character, which is not per spec +SELECT 'abcdefg' SIMILAR TO '_bcd\%' AS false; +-- and an empty string to mean "no escape", which is also not per spec +SELECT 'abcd\efg' SIMILAR TO '_bcd\%' ESCAPE '' AS true; +-- these behaviors are per spec, though: +SELECT 'abcdefg' SIMILAR TO '_bcd%' ESCAPE NULL AS null; +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '##' AS error; + +-- Characters that should be left alone in character classes when a +-- SIMILAR TO regexp pattern is converted to POSIX style. +-- Underscore "_" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '_[_[:alpha:]_]_'; +-- Percentage "%" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '%[%[:alnum:]%]%'; +-- Dot "." +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '.[.[:alnum:].].'; +-- Dollar "$" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '$[$[:alnum:]$]$'; +-- Opening parenthesis "(" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '()[([:alnum:](]()'; +-- Caret "^" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '^[^[:alnum:]^[^^][[^^]][\^][[\^]]\^]^'; +-- Closing square bracket "]" at the beginning of character class +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[]%][^]%][^%]%'; +-- Closing square bracket effective after two carets at the beginning +-- of character class. +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[^^]^'; +-- Closing square bracket after an escape sequence at the beginning of +-- a character closes the character class +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[|a]%' ESCAPE '|'; + +-- Test backslash escapes in regexp_replace's replacement string +SELECT regexp_replace('1112223333', E'(\\d{3})(\\d{3})(\\d{4})', E'(\\1) \\2-\\3'); +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\&Y', 'g'); +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\\\Y', 'g'); +-- not an error, though perhaps it should be: +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\Y\\1Z\\'); + +SELECT regexp_replace('AAA BBB CCC ', E'\\s+', ' ', 'g'); +SELECT regexp_replace('AAA', '^|$', 'Z', 'g'); +SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'gi'); +-- invalid regexp option +SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'z'); + +-- extended regexp_replace tests +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 1); +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 1, 2); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 1, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 2, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 9, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 7, 0, 'i'); +-- 'g' flag should be ignored when N is specified +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 1, 'g'); +-- errors +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', -1, 0, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, -1, 'i'); +-- erroneous invocation of non-extended form +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', '1'); + +-- regexp_count tests +SELECT regexp_count('123123123123123', '(12)3'); +SELECT regexp_count('123123123123', '123', 1); +SELECT regexp_count('123123123123', '123', 3); +SELECT regexp_count('123123123123', '123', 33); +SELECT regexp_count('ABCABCABCABC', 'Abc', 1, ''); +SELECT regexp_count('ABCABCABCABC', 'Abc', 1, 'i'); +-- errors +SELECT regexp_count('123123123123', '123', 0); +SELECT regexp_count('123123123123', '123', -3); + +-- regexp_like tests +SELECT regexp_like('Steven', '^Ste(v|ph)en$'); +SELECT regexp_like('a'||CHR(10)||'d', 'a.d', 'n'); +SELECT regexp_like('a'||CHR(10)||'d', 'a.d', 's'); +SELECT regexp_like('abc', ' a . c ', 'x'); +SELECT regexp_like('abc', 'a.c', 'g'); -- error + +-- regexp_instr tests +SELECT regexp_instr('abcdefghi', 'd.f'); +SELECT regexp_instr('abcdefghi', 'd.q'); +SELECT regexp_instr('abcabcabc', 'a.c'); +SELECT regexp_instr('abcabcabc', 'a.c', 2); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 3); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 4); +SELECT regexp_instr('abcabcabc', 'A.C', 1, 2, 0, 'i'); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 0); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 1); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 2); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 3); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 4); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 5); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 0); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 1); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 2); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 3); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 4); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 5); +-- Check case where we have a match, but not a subexpression match +SELECT regexp_instr('foo', 'foo(bar)?', 1, 1, 0, '', 1); +-- errors +SELECT regexp_instr('abcabcabc', 'a.c', 0, 1); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 0); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, -1); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 2); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, 'g'); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, '', -1); + +-- regexp_substr tests +SELECT regexp_substr('abcdefghi', 'd.f'); +SELECT regexp_substr('abcdefghi', 'd.q') IS NULL AS t; +SELECT regexp_substr('abcabcabc', 'a.c'); +SELECT regexp_substr('abcabcabc', 'a.c', 2); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 3); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 4) IS NULL AS t; +SELECT regexp_substr('abcabcabc', 'A.C', 1, 2, 'i'); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 0); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 1); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 2); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 3); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 4); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 5) IS NULL AS t; +-- Check case where we have a match, but not a subexpression match +SELECT regexp_substr('foo', 'foo(bar)?', 1, 1, '', 1) IS NULL AS t; +-- errors +SELECT regexp_substr('abcabcabc', 'a.c', 0, 1); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 0); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, 'g'); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, '', -1); + +-- set so we can tell NULL from empty string + +-- return all matches from regexp +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$); + +-- test case insensitive +SELECT regexp_matches('foObARbEqUEbAz', $re$(bar)(beque)$re$, 'i'); + +-- global option - more than one match +SELECT regexp_matches('foobarbequebazilbarfbonk', $re$(b[^b]+)(b[^b]+)$re$, 'g'); + +-- empty capture group (matched empty string) +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.*)(beque)$re$); +-- no match +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.+)(beque)$re$); +-- optional capture group did not match, null entry in array +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.+)?(beque)$re$); + +-- no capture groups +SELECT regexp_matches('foobarbequebaz', $re$barbeque$re$); + +-- start/end-of-line matches are of zero length +SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '^', 'mg'); +SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '$', 'mg'); +SELECT regexp_matches('1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '^.?', 'mg'); +SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '.?$', 'mg'); +SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4', '.?$', 'mg'); + +-- give me errors +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$, 'gz'); +SELECT regexp_matches('foobarbequebaz', $re$(barbeque$re$); +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque){2,1}$re$); + +-- split string on regexp +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', $re$\s+$re$) AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', $re$\s+$re$); + +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', $re$\s*$re$) AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', $re$\s*$re$); +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '') AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', ''); +-- case insensitive +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'i') AS foo; +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'i'); +-- no match of pattern +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', 'nomatch') AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', 'nomatch'); +-- some corner cases +SELECT regexp_split_to_array('123456','1'); +SELECT regexp_split_to_array('123456','6'); +SELECT regexp_split_to_array('123456','.'); +SELECT regexp_split_to_array('123456',''); +SELECT regexp_split_to_array('123456','(?:)'); +SELECT regexp_split_to_array('1',''); +-- errors +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'zippy') AS foo; +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'iz'); +-- global option meaningless for regexp_split +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g') AS foo; +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g'); + +-- change NULL-display back + +-- E021-11 position expression +SELECT POSITION('4' IN '1234567890') = '4' AS "4"; + +SELECT POSITION('5' IN '1234567890') = '5' AS "5"; + +-- T312 character overlay function +SELECT OVERLAY('abcdef' PLACING '45' FROM 4) AS "abc45f"; + +SELECT OVERLAY('yabadoo' PLACING 'daba' FROM 5) AS "yabadaba"; + +SELECT OVERLAY('yabadoo' PLACING 'daba' FROM 5 FOR 0) AS "yabadabadoo"; + +SELECT OVERLAY('babosa' PLACING 'ubb' FROM 2 FOR 4) AS "bubba"; + +|-- +-- test LIKE +-- Be sure to form every test as a LIKE/NOT LIKE pair. +|-- + +-- simplest examples +-- E061-04 like predicate +SELECT 'hawkeye' LIKE 'h%' AS "true"; +SELECT 'hawkeye' NOT LIKE 'h%' AS "false"; + +SELECT 'hawkeye' LIKE 'H%' AS "false"; +SELECT 'hawkeye' NOT LIKE 'H%' AS "true"; + +SELECT 'hawkeye' LIKE 'indio%' AS "false"; +SELECT 'hawkeye' NOT LIKE 'indio%' AS "true"; + +SELECT 'hawkeye' LIKE 'h%eye' AS "true"; +SELECT 'hawkeye' NOT LIKE 'h%eye' AS "false"; + +SELECT 'indio' LIKE '_ndio' AS "true"; +SELECT 'indio' NOT LIKE '_ndio' AS "false"; + +SELECT 'indio' LIKE 'in__o' AS "true"; +SELECT 'indio' NOT LIKE 'in__o' AS "false"; + +SELECT 'indio' LIKE 'in_o' AS "false"; +SELECT 'indio' NOT LIKE 'in_o' AS "true"; + +SELECT 'abc'::name LIKE '_b_' AS "true"; +SELECT 'abc'::name NOT LIKE '_b_' AS "false"; + +SELECT 'abc'::bytea LIKE '_b_'::bytea AS "true"; +SELECT 'abc'::bytea NOT LIKE '_b_'::bytea AS "false"; + +-- unused escape character +SELECT 'hawkeye' LIKE 'h%' ESCAPE '#' AS "true"; +SELECT 'hawkeye' NOT LIKE 'h%' ESCAPE '#' AS "false"; + +SELECT 'indio' LIKE 'ind_o' ESCAPE '$' AS "true"; +SELECT 'indio' NOT LIKE 'ind_o' ESCAPE '$' AS "false"; + +-- escape character +-- E061-05 like predicate with escape clause +SELECT 'h%' LIKE 'h#%' ESCAPE '#' AS "true"; +SELECT 'h%' NOT LIKE 'h#%' ESCAPE '#' AS "false"; + +SELECT 'h%wkeye' LIKE 'h#%' ESCAPE '#' AS "false"; +SELECT 'h%wkeye' NOT LIKE 'h#%' ESCAPE '#' AS "true"; + +SELECT 'h%wkeye' LIKE 'h#%%' ESCAPE '#' AS "true"; +SELECT 'h%wkeye' NOT LIKE 'h#%%' ESCAPE '#' AS "false"; + +SELECT 'h%awkeye' LIKE 'h#%a%k%e' ESCAPE '#' AS "true"; +SELECT 'h%awkeye' NOT LIKE 'h#%a%k%e' ESCAPE '#' AS "false"; + +SELECT 'indio' LIKE '_ndio' ESCAPE '$' AS "true"; +SELECT 'indio' NOT LIKE '_ndio' ESCAPE '$' AS "false"; + +SELECT 'i_dio' LIKE 'i$_d_o' ESCAPE '$' AS "true"; +SELECT 'i_dio' NOT LIKE 'i$_d_o' ESCAPE '$' AS "false"; + +SELECT 'i_dio' LIKE 'i$_nd_o' ESCAPE '$' AS "false"; +SELECT 'i_dio' NOT LIKE 'i$_nd_o' ESCAPE '$' AS "true"; + +SELECT 'i_dio' LIKE 'i$_d%o' ESCAPE '$' AS "true"; +SELECT 'i_dio' NOT LIKE 'i$_d%o' ESCAPE '$' AS "false"; + +SELECT 'a_c'::bytea LIKE 'a$__'::bytea ESCAPE '$'::bytea AS "true"; +SELECT 'a_c'::bytea NOT LIKE 'a$__'::bytea ESCAPE '$'::bytea AS "false"; + +-- escape character same as pattern character +SELECT 'maca' LIKE 'm%aca' ESCAPE '%' AS "true"; +SELECT 'maca' NOT LIKE 'm%aca' ESCAPE '%' AS "false"; + +SELECT 'ma%a' LIKE 'm%a%%a' ESCAPE '%' AS "true"; +SELECT 'ma%a' NOT LIKE 'm%a%%a' ESCAPE '%' AS "false"; + +SELECT 'bear' LIKE 'b_ear' ESCAPE '_' AS "true"; +SELECT 'bear' NOT LIKE 'b_ear' ESCAPE '_' AS "false"; + +SELECT 'be_r' LIKE 'b_e__r' ESCAPE '_' AS "true"; +SELECT 'be_r' NOT LIKE 'b_e__r' ESCAPE '_' AS "false"; + +SELECT 'be_r' LIKE '__e__r' ESCAPE '_' AS "false"; +SELECT 'be_r' NOT LIKE '__e__r' ESCAPE '_' AS "true"; + + +|-- +-- test ILIKE (case-insensitive LIKE) +-- Be sure to form every test as an ILIKE/NOT ILIKE pair. +|-- + +SELECT 'hawkeye' ILIKE 'h%' AS "true"; +SELECT 'hawkeye' NOT ILIKE 'h%' AS "false"; + +SELECT 'hawkeye' ILIKE 'H%' AS "true"; +SELECT 'hawkeye' NOT ILIKE 'H%' AS "false"; + +SELECT 'hawkeye' ILIKE 'H%Eye' AS "true"; +SELECT 'hawkeye' NOT ILIKE 'H%Eye' AS "false"; + +SELECT 'Hawkeye' ILIKE 'h%' AS "true"; +SELECT 'Hawkeye' NOT ILIKE 'h%' AS "false"; + +SELECT 'ABC'::name ILIKE '_b_' AS "true"; +SELECT 'ABC'::name NOT ILIKE '_b_' AS "false"; + +|-- +-- test %/_ combination cases, cf bugs #4821 and #5478 +|-- + +SELECT 'foo' LIKE '_%' as t, 'f' LIKE '_%' as t, '' LIKE '_%' as f; +SELECT 'foo' LIKE '%_' as t, 'f' LIKE '%_' as t, '' LIKE '%_' as f; + +SELECT 'foo' LIKE '__%' as t, 'foo' LIKE '___%' as t, 'foo' LIKE '____%' as f; +SELECT 'foo' LIKE '%__' as t, 'foo' LIKE '%___' as t, 'foo' LIKE '%____' as f; + +SELECT 'jack' LIKE '%____%' AS t; + + +|-- +-- basic tests of LIKE with indexes +|-- + +CREATE TABLE texttest (a text PRIMARY KEY, b int); +SELECT * FROM texttest WHERE a LIKE '%1%'; + +CREATE TABLE byteatest (a bytea PRIMARY KEY, b int); +SELECT * FROM byteatest WHERE a LIKE '%1%'; + +DROP TABLE texttest, byteatest; + + +|-- +-- test implicit type conversion +|-- + +-- E021-07 character concatenation +SELECT 'unknown' || ' and unknown' AS "Concat unknown types"; + +SELECT text 'text' || ' and unknown' AS "Concat text to unknown type"; + +SELECT char(20) 'characters' || ' and text' AS "Concat char to unknown type"; + +SELECT text 'text' || char(20) ' and characters' AS "Concat text to char"; + +SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar"; + +|-- +-- test substr with toasted text values +|-- +CREATE TABLE toasttest(f1 text); + +insert into toasttest values(repeat('1234567890',10000)); +insert into toasttest values(repeat('1234567890',10000)); + +|-- +-- Ensure that some values are uncompressed, to test the faster substring +-- operation used in that case +|-- +alter table toasttest alter column f1 set storage external; +insert into toasttest values(repeat('1234567890',10000)); +insert into toasttest values(repeat('1234567890',10000)); + +-- If the starting position is zero or less, then return from the start of the string +-- adjusting the length to be consistent with the "negative start" per SQL. +SELECT substr(f1, -1, 5) from toasttest; + +-- If the length is less than zero, an ERROR is thrown. +SELECT substr(f1, 5, -1) from toasttest; + +-- If no third argument (length) is provided, the length to the end of the +-- string is assumed. +SELECT substr(f1, 99995) from toasttest; + +-- If start plus length is > string length, the result is truncated to +-- string length +SELECT substr(f1, 99995, 10) from toasttest; + +TRUNCATE TABLE toasttest; +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +-- expect >0 blocks +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + +TRUNCATE TABLE toasttest; +ALTER TABLE toasttest set (toast_tuple_target = 4080); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +-- expect 0 blocks +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + +DROP TABLE toasttest; + +|-- +-- test substr with toasted bytea values +|-- +CREATE TABLE toasttest(f1 bytea); + +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +|-- +-- Ensure that some values are uncompressed, to test the faster substring +-- operation used in that case +|-- +alter table toasttest alter column f1 set storage external; +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +-- If the starting position is zero or less, then return from the start of the string +-- adjusting the length to be consistent with the "negative start" per SQL. +SELECT substr(f1, -1, 5) from toasttest; + +-- If the length is less than zero, an ERROR is thrown. +SELECT substr(f1, 5, -1) from toasttest; + +-- If no third argument (length) is provided, the length to the end of the +-- string is assumed. +SELECT substr(f1, 99995) from toasttest; + +-- If start plus length is > string length, the result is truncated to +-- string length +SELECT substr(f1, 99995, 10) from toasttest; + +DROP TABLE toasttest; + +-- test internally compressing datums + +-- this tests compressing a datum to a very small size which exercises a +-- corner case in packed-varlena handling: even though small, the compressed +-- datum must be given a 4-byte header because there are no bits to indicate +-- compression in a 1-byte header + +CREATE TABLE toasttest (c char(4096)); +INSERT INTO toasttest VALUES('x'); +SELECT length(c), c::text FROM toasttest; +SELECT c FROM toasttest; +DROP TABLE toasttest; + +|-- +-- test length +|-- + +SELECT length('abcdef') AS "length_6"; + +|-- +-- test strpos +|-- + +SELECT strpos('abcdef', 'cd') AS "pos_3"; + +SELECT strpos('abcdef', 'xy') AS "pos_0"; + +SELECT strpos('abcdef', '') AS "pos_1"; + +SELECT strpos('', 'xy') AS "pos_0"; + +SELECT strpos('', '') AS "pos_1"; + +|-- +-- test replace +|-- +SELECT replace('abcdef', 'de', '45') AS "abc45f"; + +SELECT replace('yabadabadoo', 'ba', '123') AS "ya123da123doo"; + +SELECT replace('yabadoo', 'bad', '') AS "yaoo"; + +|-- +-- test split_part +|-- +select split_part('','@',1) AS "empty string"; + +select split_part('','@',-1) AS "empty string"; + +select split_part('joeuser@mydatabase','',1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','',2) AS "empty string"; + +select split_part('joeuser@mydatabase','',-1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','',-2) AS "empty string"; + +select split_part('joeuser@mydatabase','@',0) AS "an error"; + +select split_part('joeuser@mydatabase','@@',1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','@@',2) AS "empty string"; + +select split_part('joeuser@mydatabase','@',1) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',2) AS "mydatabase"; + +select split_part('joeuser@mydatabase','@',3) AS "empty string"; + +select split_part('@joeuser@mydatabase@','@',2) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',-1) AS "mydatabase"; + +select split_part('joeuser@mydatabase','@',-2) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',-3) AS "empty string"; + +select split_part('@joeuser@mydatabase@','@',-2) AS "mydatabase"; + +|-- +-- test to_bin, to_oct, and to_hex +|-- +select to_bin(-1234) AS "11111111111111111111101100101110"; +select to_bin(-1234::bigint); +select to_bin(256*256*256 - 1) AS "111111111111111111111111"; +select to_bin(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "11111111111111111111111111111111"; + +select to_oct(-1234) AS "37777775456"; +select to_oct(-1234::bigint) AS "1777777777777777775456"; +select to_oct(256*256*256 - 1) AS "77777777"; +select to_oct(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "37777777777"; + +select to_hex(-1234) AS "fffffb2e"; +select to_hex(-1234::bigint) AS "fffffffffffffb2e"; +select to_hex(256*256*256 - 1) AS "ffffff"; +select to_hex(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "ffffffff"; + +|-- +-- SHA-2 +|-- +SET bytea_output TO hex; + +SELECT sha224(''); +SELECT sha224('The quick brown fox jumps over the lazy dog.'); + +SELECT sha256(''); +SELECT sha256('The quick brown fox jumps over the lazy dog.'); + +SELECT sha384(''); +SELECT sha384('The quick brown fox jumps over the lazy dog.'); + +SELECT sha512(''); +SELECT sha512('The quick brown fox jumps over the lazy dog.'); + +|-- +-- encode/decode +|-- +SELECT encode('\x1234567890abcdef00', 'hex'); +SELECT decode('1234567890abcdef00', 'hex'); +SELECT encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea, 'base64'); +SELECT decode(encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea, + 'base64'), 'base64'); +SELECT encode('\x1234567890abcdef00', 'escape'); +SELECT decode(encode('\x1234567890abcdef00', 'escape'), 'escape'); + +|-- +-- get_bit/set_bit etc +|-- +SELECT get_bit('\x1234567890abcdef00'::bytea, 43); +SELECT get_bit('\x1234567890abcdef00'::bytea, 99); -- error +SELECT set_bit('\x1234567890abcdef00'::bytea, 43, 0); +SELECT set_bit('\x1234567890abcdef00'::bytea, 99, 0); -- error +SELECT get_byte('\x1234567890abcdef00'::bytea, 3); +SELECT get_byte('\x1234567890abcdef00'::bytea, 99); -- error +SELECT set_byte('\x1234567890abcdef00'::bytea, 7, 11); +SELECT set_byte('\x1234567890abcdef00'::bytea, 99, 11); -- error + +|-- +-- test behavior of escape_string_warning and standard_conforming_strings options +|-- +set escape_string_warning = off; +set standard_conforming_strings = off; + +show escape_string_warning; +show standard_conforming_strings; + +set escape_string_warning = on; +set standard_conforming_strings = on; + +show escape_string_warning; +show standard_conforming_strings; + +select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; + +set standard_conforming_strings = off; + +select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; + +set escape_string_warning = off; +set standard_conforming_strings = on; + +select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; + +set standard_conforming_strings = off; + +select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; + +reset standard_conforming_strings; + + +|-- +-- Additional string functions +|-- +SET bytea_output TO escape; + +SELECT initcap('hi THOMAS'); + +SELECT lpad('hi', 5, 'xy'); +SELECT lpad('hi', 5); +SELECT lpad('hi', -5, 'xy'); +SELECT lpad('hello', 2); +SELECT lpad('hi', 5, ''); + +SELECT rpad('hi', 5, 'xy'); +SELECT rpad('hi', 5); +SELECT rpad('hi', -5, 'xy'); +SELECT rpad('hello', 2); +SELECT rpad('hi', 5, ''); + +SELECT ltrim('zzzytrim', 'xyz'); + +SELECT translate('', '14', 'ax'); +SELECT translate('12345', '14', 'ax'); +SELECT translate('12345', '134', 'a'); + +SELECT ascii('x'); +SELECT ascii(''); + +SELECT chr(65); +SELECT chr(0); + +SELECT repeat('Pg', 4); +SELECT repeat('Pg', -4); + +SELECT SUBSTRING('1234567890'::bytea FROM 3) "34567890"; +SELECT SUBSTRING('1234567890'::bytea FROM 4 FOR 3) AS "456"; +SELECT SUBSTRING('string'::bytea FROM 2 FOR 2147483646) AS "tring"; +SELECT SUBSTRING('string'::bytea FROM -10 FOR 2147483646) AS "string"; +SELECT SUBSTRING('string'::bytea FROM -10 FOR -2147483646) AS "error"; + +SELECT trim(E'\\000'::bytea from E'\\000Tom\\000'::bytea); +SELECT trim(leading E'\\000'::bytea from E'\\000Tom\\000'::bytea); +SELECT trim(trailing E'\\000'::bytea from E'\\000Tom\\000'::bytea); +SELECT btrim(E'\\000trim\\000'::bytea, E'\\000'::bytea); +SELECT btrim(''::bytea, E'\\000'::bytea); +SELECT btrim(E'\\000trim\\000'::bytea, ''::bytea); +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'Th\\001omas'::bytea from 2),'escape'); +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 8),'escape'); +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5 for 3),'escape'); + +SELECT bit_count('\x1234567890'::bytea); + +SELECT unistr('\0064at\+0000610'); +SELECT unistr('d\u0061t\U000000610'); +SELECT unistr('a\\b'); +-- errors: +SELECT unistr('wrong: \db99'); +SELECT unistr('wrong: \db99\0061'); +SELECT unistr('wrong: \+00db99\+000061'); +SELECT unistr('wrong: \+2FFFFF'); +SELECT unistr('wrong: \udb99\u0061'); +SELECT unistr('wrong: \U0000db99\U00000061'); +SELECT unistr('wrong: \U002FFFFF'); +SELECT unistr('wrong: \xyz'); +-- +ERROR: syntax error at or near "' - third line'" +CURSORPOS: 318 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary/postgres_regress/subscription.metadata.json b/parser/testdata/summary/postgres_regress/subscription.metadata.json new file mode 100644 index 0000000..d3267aa --- /dev/null +++ b/parser/testdata/summary/postgres_regress/subscription.metadata.json @@ -0,0 +1,163 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159" + ] +} diff --git a/parser/testdata/summary/postgres_regress/subscription.test b/parser/testdata/summary/postgres_regress/subscription.test new file mode 100644 index 0000000..0972398 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/subscription.test @@ -0,0 +1,733 @@ +== 001 +|-- +-- SUBSCRIPTION +|-- + +CREATE ROLE regress_subscription_user LOGIN SUPERUSER +-- +STMT: CreateRoleStmt +== 002 +CREATE ROLE regress_subscription_user2 +-- +STMT: CreateRoleStmt +== 003 +CREATE ROLE regress_subscription_user3 IN ROLE pg_create_subscription +-- +STMT: CreateRoleStmt +== 004 +CREATE ROLE regress_subscription_user_dummy LOGIN NOSUPERUSER +-- +STMT: CreateRoleStmt +== 005 +SET SESSION AUTHORIZATION 'regress_subscription_user' +-- +STMT: VariableSetStmt +== 006 +-- fail - no publications +CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo' +-- +ERROR: syntax error at end of input +CURSORPOS: 79 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- fail - no connection +CREATE SUBSCRIPTION regress_testsub PUBLICATION foo +-- +ERROR: syntax error at or near "PUBLICATION" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block +BEGIN +-- +STMT: TransactionStmt +== 009 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot) +-- +STMT: CreateSubscriptionStmt +== 010 +COMMIT +-- +STMT: TransactionStmt +== 011 +-- fail - invalid connection string +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub +-- +STMT: CreateSubscriptionStmt +== 012 +-- fail - duplicate publications +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +== 013 +-- ok +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +== 014 +COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription' +-- +STMT: CommentStmt +== 015 +SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s +-- +TABLE: name="pg_subscription" schema="" table="pg_subscription" ctx=Select +ALIAS: "s"="pg_subscription" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- Check if the subscription stats are created and stats_reset is updated +-- by pg_stat_reset_subscription_stats(). +SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_stat_subscription_stats" schema="" table="pg_stat_subscription_stats" ctx=Select +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +== 017 +SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_subscription" schema="" table="pg_subscription" ctx=Select +FUNCTION: name="pg_stat_reset_subscription_stats" function="pg_stat_reset_subscription_stats" schema="" ctx=Call +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +== 018 +SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_stat_subscription_stats" schema="" table="pg_stat_subscription_stats" ctx=Select +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +== 019 +-- Reset the stats again and check if the new reset_stats is updated. +SELECT stats_reset as prev_stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_stat_subscription_stats" schema="" table="pg_stat_subscription_stats" ctx=Select +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +== 020 +SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_subscription" schema="" table="pg_subscription" ctx=Select +FUNCTION: name="pg_stat_reset_subscription_stats" function="pg_stat_reset_subscription_stats" schema="" ctx=Call +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +== 021 +SELECT :'prev_stats_reset' < stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 022 +-- fail - name already exists +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +== 023 +-- fail - must be superuser +SET SESSION AUTHORIZATION 'regress_subscription_user2' +-- +STMT: VariableSetStmt +== 024 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +== 025 +SET SESSION AUTHORIZATION 'regress_subscription_user' +-- +STMT: VariableSetStmt +== 026 +-- fail - invalid option combinations +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true) +-- +STMT: CreateSubscriptionStmt +== 027 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true) +-- +STMT: CreateSubscriptionStmt +== 028 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true) +-- +STMT: CreateSubscriptionStmt +== 029 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true) +-- +STMT: CreateSubscriptionStmt +== 030 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false, create_slot = true) +-- +STMT: CreateSubscriptionStmt +== 031 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE) +-- +STMT: CreateSubscriptionStmt +== 032 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false) +-- +STMT: CreateSubscriptionStmt +== 033 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false) +-- +STMT: CreateSubscriptionStmt +== 034 +-- ok - with slot_name = NONE +CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false) +-- +STMT: CreateSubscriptionStmt +== 035 +-- fail +ALTER SUBSCRIPTION regress_testsub3 ENABLE +-- +STMT: AlterSubscriptionStmt +== 036 +ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION +-- +STMT: AlterSubscriptionStmt +== 037 +-- fail - origin must be either none or any +CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = foo) +-- +STMT: CreateSubscriptionStmt +== 038 +-- now it works +CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = none) +-- +STMT: CreateSubscriptionStmt +== 039 +ALTER SUBSCRIPTION regress_testsub4 SET (origin = any) +-- +STMT: AlterSubscriptionStmt +== 040 +DROP SUBSCRIPTION regress_testsub3 +-- +STMT: DropSubscriptionStmt +== 041 +DROP SUBSCRIPTION regress_testsub4 +-- +STMT: DropSubscriptionStmt +== 042 +-- fail, connection string does not parse +CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'i_dont_exist=param' PUBLICATION testpub +-- +STMT: CreateSubscriptionStmt +== 043 +-- fail, connection string parses, but doesn't work (and does so without +-- connecting, so this is reliable and safe) +CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'port=-1' PUBLICATION testpub +-- +STMT: CreateSubscriptionStmt +== 044 +-- fail - invalid connection string during ALTER +ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar' +-- +STMT: AlterSubscriptionStmt +== 045 +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 046 +ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2' +-- +STMT: AlterSubscriptionStmt +== 047 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname') +-- +STMT: AlterSubscriptionStmt +== 048 +ALTER SUBSCRIPTION regress_testsub SET (password_required = false) +-- +STMT: AlterSubscriptionStmt +== 049 +ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = true) +-- +STMT: AlterSubscriptionStmt +== 050 +ALTER SUBSCRIPTION regress_testsub SET (password_required = true) +-- +STMT: AlterSubscriptionStmt +== 051 +ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = false) +-- +STMT: AlterSubscriptionStmt +== 052 +-- fail +ALTER SUBSCRIPTION regress_testsub SET (slot_name = '') +-- +STMT: AlterSubscriptionStmt +== 053 +-- fail +ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2' +-- +STMT: AlterSubscriptionStmt +== 054 +ALTER SUBSCRIPTION regress_testsub SET (create_slot = false) +-- +STMT: AlterSubscriptionStmt +== 055 +-- ok +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/12345') +-- +STMT: AlterSubscriptionStmt +== 056 +-- ok - with lsn = NONE +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = NONE) +-- +STMT: AlterSubscriptionStmt +== 057 +-- fail +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/0') +-- +STMT: AlterSubscriptionStmt +== 058 +BEGIN +-- +STMT: TransactionStmt +== 059 +ALTER SUBSCRIPTION regress_testsub ENABLE +-- +STMT: AlterSubscriptionStmt +== 060 +ALTER SUBSCRIPTION regress_testsub DISABLE +-- +STMT: AlterSubscriptionStmt +== 061 +COMMIT +-- +STMT: TransactionStmt +== 062 +-- fail - must be owner of subscription +SET ROLE regress_subscription_user_dummy +-- +STMT: VariableSetStmt +== 063 +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy +-- +STMT: RenameStmt +== 064 +RESET ROLE +-- +STMT: VariableSetStmt +== 065 +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo +-- +STMT: RenameStmt +== 066 +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local) +-- +STMT: AlterSubscriptionStmt +== 067 +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar) +-- +STMT: AlterSubscriptionStmt +== 068 +-- rename back to keep the rest simple +ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub +-- +STMT: RenameStmt +== 069 +-- ok, we're a superuser +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2 +-- +STMT: AlterOwnerStmt +== 070 +-- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name +BEGIN +-- +STMT: TransactionStmt +== 071 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 072 +COMMIT +-- +STMT: TransactionStmt +== 073 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 074 +-- now it works +BEGIN +-- +STMT: TransactionStmt +== 075 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 076 +COMMIT +-- +STMT: TransactionStmt +== 077 +DROP SUBSCRIPTION IF EXISTS regress_testsub +-- +STMT: DropSubscriptionStmt +== 078 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 079 +-- fail + +-- fail - binary must be boolean +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = foo) +-- +STMT: CreateSubscriptionStmt +== 080 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = true) +-- +STMT: CreateSubscriptionStmt +== 081 +ALTER SUBSCRIPTION regress_testsub SET (binary = false) +-- +STMT: AlterSubscriptionStmt +== 082 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 083 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 084 +-- fail - streaming must be boolean or 'parallel' +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = foo) +-- +STMT: CreateSubscriptionStmt +== 085 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true) +-- +STMT: CreateSubscriptionStmt +== 086 +ALTER SUBSCRIPTION regress_testsub SET (streaming = parallel) +-- +STMT: AlterSubscriptionStmt +== 087 +ALTER SUBSCRIPTION regress_testsub SET (streaming = false) +-- +STMT: AlterSubscriptionStmt +== 088 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 089 +-- fail - publication already exists +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 090 +-- fail - publication used more than once +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub1 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 091 +-- ok - add two publications into subscription +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 092 +-- fail - publications already exist +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 093 +-- fail - publication used more than once +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub1 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 094 +-- fail - all publications are deleted +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub, testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 095 +-- fail - publication does not exist in subscription +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub3 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 096 +-- ok - delete publications +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +== 097 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 098 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION mypub + WITH (connect = false, create_slot = false, copy_data = false) +-- +STMT: CreateSubscriptionStmt +== 099 +ALTER SUBSCRIPTION regress_testsub ENABLE +-- +STMT: AlterSubscriptionStmt +== 100 +-- fail - ALTER SUBSCRIPTION with refresh is not allowed in a transaction +-- block or function +BEGIN +-- +STMT: TransactionStmt +== 101 +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh = true) +-- +STMT: AlterSubscriptionStmt +== 102 +END +-- +STMT: TransactionStmt +== 103 +BEGIN +-- +STMT: TransactionStmt +== 104 +ALTER SUBSCRIPTION regress_testsub REFRESH PUBLICATION +-- +STMT: AlterSubscriptionStmt +== 105 +END +-- +STMT: TransactionStmt +== 106 +CREATE FUNCTION func() RETURNS VOID AS +$$ ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh = true) $$ LANGUAGE SQL +-- +FUNCTION: name="func" function="func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 107 +SELECT func() +-- +FUNCTION: name="func" function="func" schema="" ctx=Call +STMT: SelectStmt +== 108 +ALTER SUBSCRIPTION regress_testsub DISABLE +-- +STMT: AlterSubscriptionStmt +== 109 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 110 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 111 +DROP FUNCTION func +-- +FUNCTION: name="func" function="func" schema="" ctx=DDL +STMT: DropStmt +== 112 +-- fail - two_phase must be boolean +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = foo) +-- +STMT: CreateSubscriptionStmt +== 113 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = true) +-- +STMT: CreateSubscriptionStmt +== 114 +--fail - alter of two_phase option not supported. +ALTER SUBSCRIPTION regress_testsub SET (two_phase = false) +-- +STMT: AlterSubscriptionStmt +== 115 +-- but can alter streaming when two_phase enabled +ALTER SUBSCRIPTION regress_testsub SET (streaming = true) +-- +STMT: AlterSubscriptionStmt +== 116 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 117 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 118 +-- two_phase and streaming are compatible. +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true, two_phase = true) +-- +STMT: CreateSubscriptionStmt +== 119 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 120 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 121 +-- fail - disable_on_error must be boolean +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = foo) +-- +STMT: CreateSubscriptionStmt +== 122 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = false) +-- +STMT: CreateSubscriptionStmt +== 123 +ALTER SUBSCRIPTION regress_testsub SET (disable_on_error = true) +-- +STMT: AlterSubscriptionStmt +== 124 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 125 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 126 +-- let's do some tests with pg_create_subscription rather than superuser +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +== 127 +-- fail, not enough privileges +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +== 128 +-- fail, must specify password +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 129 +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3 +-- +STMT: GrantStmt +== 130 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +== 131 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +== 132 +-- fail, can't set password_required=false +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 133 +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3 +-- +STMT: GrantStmt +== 134 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +== 135 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, password_required = false) +-- +STMT: CreateSubscriptionStmt +== 136 +-- ok +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 137 +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3 +-- +STMT: GrantStmt +== 138 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +== 139 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist password=regress_fakepassword' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +== 140 +-- we cannot give the subscription away to some random user +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user +-- +STMT: AlterOwnerStmt +== 141 +-- but we can rename the subscription we just created +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2 +-- +STMT: RenameStmt +== 142 +-- ok, even after losing pg_create_subscription we can still rename it +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 143 +REVOKE pg_create_subscription FROM regress_subscription_user3 +-- +STMT: GrantRoleStmt +== 144 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +== 145 +ALTER SUBSCRIPTION regress_testsub2 RENAME TO regress_testsub +-- +STMT: RenameStmt +== 146 +-- fail, after losing CREATE on the database we can't rename it any more +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 147 +REVOKE CREATE ON DATABASE REGRESSION FROM regress_subscription_user3 +-- +STMT: GrantStmt +== 148 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +== 149 +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2 +-- +STMT: RenameStmt +== 150 +-- fail - cannot do ALTER SUBSCRIPTION SET (failover) inside transaction block +BEGIN +-- +STMT: TransactionStmt +== 151 +ALTER SUBSCRIPTION regress_testsub SET (failover) +-- +STMT: AlterSubscriptionStmt +== 152 +COMMIT +-- +STMT: TransactionStmt +== 153 +-- ok, owning it is enough for this stuff +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +== 154 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +== 155 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 156 +DROP ROLE regress_subscription_user +-- +STMT: DropRoleStmt +== 157 +DROP ROLE regress_subscription_user2 +-- +STMT: DropRoleStmt +== 158 +DROP ROLE regress_subscription_user3 +-- +STMT: DropRoleStmt +== 159 +DROP ROLE regress_subscription_user_dummy +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/subselect.metadata.json b/parser/testdata/summary/postgres_regress/subselect.metadata.json new file mode 100644 index 0000000..354a8d0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/subselect.metadata.json @@ -0,0 +1,273 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269" + ] +} diff --git a/parser/testdata/summary/postgres_regress/subselect.test b/parser/testdata/summary/postgres_regress/subselect.test new file mode 100644 index 0000000..2ad91e8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/subselect.test @@ -0,0 +1,2560 @@ +== 001 +|-- +-- SUBSELECT +|-- + +SELECT 1 AS one WHERE 1 IN (SELECT 1) +-- +STMT: SelectStmt +== 002 +SELECT 1 AS zero WHERE 1 NOT IN (SELECT 1) +-- +STMT: SelectStmt +== 003 +SELECT 1 AS zero WHERE 1 IN (SELECT 2) +-- +STMT: SelectStmt +== 004 +-- Check grammar's handling of extra parens in assorted contexts + +SELECT * FROM (SELECT 1 AS x) ss +-- +STMT: SelectStmt +== 005 +SELECT * FROM ((SELECT 1 AS x)) ss +-- +STMT: SelectStmt +== 006 +SELECT * FROM ((SELECT 1 AS x)), ((SELECT * FROM ((SELECT 2 AS y)))) +-- +STMT: SelectStmt +== 007 +(SELECT 2) UNION SELECT 2 +-- +STMT: SelectStmt +== 008 +((SELECT 2)) UNION SELECT 2 +-- +STMT: SelectStmt +== 009 +SELECT ((SELECT 2) UNION SELECT 2) +-- +STMT: SelectStmt +== 010 +SELECT (((SELECT 2)) UNION SELECT 2) +-- +STMT: SelectStmt +== 011 +SELECT (SELECT ARRAY[1,2,3])[1] +-- +STMT: SelectStmt +== 012 +SELECT ((SELECT ARRAY[1,2,3]))[2] +-- +STMT: SelectStmt +== 013 +SELECT (((SELECT ARRAY[1,2,3])))[3] +-- +STMT: SelectStmt +== 014 +-- Set up some simple test tables + +CREATE TABLE SUBSELECT_TBL ( + f1 integer, + f2 integer, + f3 float +) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DDL +STMT: CreateStmt +== 015 +INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +INSERT INTO SUBSELECT_TBL VALUES (1, 1, 1) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +INSERT INTO SUBSELECT_TBL VALUES (2, 2, 2) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO SUBSELECT_TBL VALUES (3, 3, 3) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO SUBSELECT_TBL VALUES (6, 7, 8) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +SELECT * FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +== 024 +-- Uncorrelated subselects + +SELECT f1 AS "Constant Select" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT 1) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 025 +SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 026 +SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE + f2 IN (SELECT f1 FROM SUBSELECT_TBL)) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 027 +SELECT f1, f2 + FROM SUBSELECT_TBL + WHERE (f1, f2) NOT IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL + WHERE f3 IS NOT NULL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +== 028 +-- Correlated subselects + +SELECT f1 AS "Correlated Field", f2 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "upper"="subselect_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="upper" column="f1" +STMT: SelectStmt +== 029 +SELECT f1 AS "Correlated Field", f3 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f1 IN + (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "upper"="subselect_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="upper" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +== 030 +SELECT f1 AS "Correlated Field", f3 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f3 IN (SELECT upper.f1 + f2 FROM SUBSELECT_TBL + WHERE f2 = CAST(f3 AS integer)) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "upper"="subselect_tbl" +FILTER: schema="" table="" column="f3" +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +== 031 +SELECT f1 AS "Correlated Field" + FROM SUBSELECT_TBL + WHERE (f1, f2) IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL + WHERE f3 IS NOT NULL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +== 032 +-- Check ROWCOMPARE cases, both correlated and not + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 033 +SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +== 034 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 035 +SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +== 036 +SELECT ROW(1, 2) = (SELECT f1, f2 FROM SUBSELECT_TBL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +== 037 +-- error + +-- Subselects without aliases + +SELECT count FROM (SELECT COUNT(DISTINCT name) FROM road) +-- +TABLE: name="road" schema="" table="road" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT COUNT(*) FROM (SELECT DISTINCT name FROM road) +-- +TABLE: name="road" schema="" table="road" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT * FROM (SELECT * FROM int4_tbl), (VALUES (123456)) WHERE f1 = column1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="column1" +STMT: SelectStmt +== 040 +CREATE VIEW view_unnamed_ss AS +SELECT * FROM (SELECT * FROM (SELECT abs(f1) AS a1 FROM int4_tbl)), + (SELECT * FROM int8_tbl) + WHERE a1 < 10 AND q1 > a1 ORDER BY q1, q2 +-- +TABLE: name="view_unnamed_ss" schema="" table="view_unnamed_ss" ctx=DDL +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a1" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="a1" +STMT: ViewStmt +STMT: SelectStmt +== 041 +SELECT * FROM view_unnamed_ss +-- +TABLE: name="view_unnamed_ss" schema="" table="view_unnamed_ss" ctx=Select +STMT: SelectStmt +== 042 +DROP VIEW view_unnamed_ss +-- +STMT: DropStmt +== 043 +-- Test matching of locking clause to correct alias + +CREATE VIEW view_unnamed_ss_locking AS +SELECT * FROM (SELECT * FROM int4_tbl), int8_tbl AS unnamed_subquery + WHERE f1 = q1 + FOR UPDATE OF unnamed_subquery +-- +TABLE: name="view_unnamed_ss_locking" schema="" table="view_unnamed_ss_locking" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "unnamed_subquery"="int8_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="q1" +STMT: ViewStmt +STMT: SelectStmt +== 044 +DROP VIEW view_unnamed_ss_locking +-- +STMT: DropStmt +== 045 +|-- +-- Use some existing tables in the regression test +|-- + +SELECT ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" + FROM SUBSELECT_TBL ss + WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL + WHERE f1 != ss.f1 AND f1 < 2147483647) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "ss"="subselect_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="ss" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 046 +select q1, float8(count(*)) / (select count(*) from int8_tbl) +from int8_tbl group by q1 order by q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="float8" function="float8" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- Unspecified-type literals in output columns should resolve as text + +SELECT *, pg_typeof(f1) FROM + (SELECT 'foo' AS f1 FROM generate_series(1,3)) ss ORDER BY 1 +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 048 +-- ... unless there's context to suggest differently + +explain (verbose, costs off) select '42' union all select '43' +-- +STMT: ExplainStmt +STMT: SelectStmt +== 049 +explain (verbose, costs off) select '42' union all select 43 +-- +STMT: ExplainStmt +STMT: SelectStmt +== 050 +-- check materialization of an initplan reference (bug #14524) +explain (verbose, costs off) +select 1 = all (select (select 1)) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 051 +select 1 = all (select (select 1)) +-- +STMT: SelectStmt +== 052 +|-- +-- Check EXISTS simplification with LIMIT +|-- +explain (costs off) +select * from int4_tbl o where exists + (select 1 from int4_tbl i where i.f1=o.f1 limit null) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="o" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 053 +explain (costs off) +select * from int4_tbl o where not exists + (select 1 from int4_tbl i where i.f1=o.f1 limit 1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="o" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 054 +explain (costs off) +select * from int4_tbl o where exists + (select 1 from int4_tbl i where i.f1=o.f1 limit 0) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="o" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 055 +|-- +-- Test cases to catch unpleasant interactions between IN-join processing +-- and subquery pullup. +|-- + +select count(*) from + (select 1 from tenk1 a + where unique1 IN (select hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 056 +select count(distinct ss.ten) from + (select ten from tenk1 a + where unique1 IN (select hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 057 +select count(*) from + (select 1 from tenk1 a + where unique1 IN (select distinct hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 058 +select count(distinct ss.ten) from + (select ten from tenk1 a + where unique1 IN (select distinct hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 059 +|-- +-- Test cases to check for overenthusiastic optimization of +-- "IN (SELECT DISTINCT ...)" and related cases. Per example from +-- Luca Pireddu and Michael Fuhr. +|-- + +CREATE TEMP TABLE foo (id integer) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +== 060 +CREATE TEMP TABLE bar (id1 integer, id2 integer) +-- +TABLE: name="bar" schema="" table="bar" ctx=DDL +STMT: CreateStmt +== 061 +INSERT INTO foo VALUES (1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +INSERT INTO bar VALUES (1, 1) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +INSERT INTO bar VALUES (2, 2) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +INSERT INTO bar VALUES (3, 1) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +-- These cases require an extra level of distinct-ing above subquery s +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT DISTINCT id1, id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 066 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id1,id2 FROM bar GROUP BY id1,id2) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 067 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id1, id2 FROM bar UNION + SELECT id1, id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 068 +-- These cases do not +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT DISTINCT ON (id2) id1, id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 069 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id2 FROM bar GROUP BY id2) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 070 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id2 FROM bar UNION + SELECT id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 071 +|-- +-- Test case to catch problems with multiply nested sub-SELECTs not getting +-- recalculated properly. Per bug report from Didier Moens. +|-- + +CREATE TABLE orderstest ( + approver_ref integer, + po_ref integer, + ordercanceled boolean +) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DDL +STMT: CreateStmt +== 072 +INSERT INTO orderstest VALUES (1, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +INSERT INTO orderstest VALUES (66, 5, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 074 +INSERT INTO orderstest VALUES (66, 6, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +INSERT INTO orderstest VALUES (66, 7, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +INSERT INTO orderstest VALUES (66, 1, true) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +INSERT INTO orderstest VALUES (66, 8, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +INSERT INTO orderstest VALUES (66, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO orderstest VALUES (77, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO orderstest VALUES (1, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +INSERT INTO orderstest VALUES (66, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +INSERT INTO orderstest VALUES (1, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +CREATE VIEW orders_view AS +SELECT *, +(SELECT CASE + WHEN ord.approver_ref=1 THEN '---' ELSE 'Approved' + END) AS "Approved", +(SELECT CASE + WHEN ord.ordercanceled + THEN 'Canceled' + ELSE + (SELECT CASE + WHEN ord.po_ref=1 + THEN + (SELECT CASE + WHEN ord.approver_ref=1 + THEN '---' + ELSE 'Approved' + END) + ELSE 'PO' + END) +END) AS "Status", +(CASE + WHEN ord.ordercanceled + THEN 'Canceled' + ELSE + (CASE + WHEN ord.po_ref=1 + THEN + (CASE + WHEN ord.approver_ref=1 + THEN '---' + ELSE 'Approved' + END) + ELSE 'PO' + END) +END) AS "Status_OK" +FROM orderstest ord +-- +TABLE: name="orders_view" schema="" table="orders_view" ctx=DDL +TABLE: name="orderstest" schema="" table="orderstest" ctx=Select +ALIAS: "ord"="orderstest" +STMT: ViewStmt +STMT: SelectStmt +== 084 +SELECT * FROM orders_view +-- +TABLE: name="orders_view" schema="" table="orders_view" ctx=Select +STMT: SelectStmt +== 085 +DROP TABLE orderstest cascade +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DDL +STMT: DropStmt +== 086 +|-- +-- Test cases to catch situations where rule rewriter fails to propagate +-- hasSubLinks flag correctly. Per example from Kyle Bateman. +|-- + +create temp table parts ( + partnum text, + cost float8 +) +-- +TABLE: name="parts" schema="" table="parts" ctx=DDL +STMT: CreateStmt +== 087 +create temp table shipped ( + ttype char(2), + ordnum int4, + partnum text, + value float8 +) +-- +TABLE: name="shipped" schema="" table="shipped" ctx=DDL +STMT: CreateStmt +== 088 +create temp view shipped_view as + select * from shipped where ttype = 'wt' +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DDL +TABLE: name="shipped" schema="" table="shipped" ctx=Select +FILTER: schema="" table="" column="ttype" +STMT: ViewStmt +STMT: SelectStmt +== 089 +create rule shipped_view_insert as on insert to shipped_view do instead + insert into shipped values('wt', new.ordnum, new.partnum, new.value) +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DDL +STMT: RuleStmt +== 090 +insert into parts (partnum, cost) values (1, 1234.56) +-- +TABLE: name="parts" schema="" table="parts" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 091 +insert into shipped_view (ordnum, partnum, value) + values (0, 1, (select cost from parts where partnum = '1')) +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DML +TABLE: name="parts" schema="" table="parts" ctx=Select +FILTER: schema="" table="" column="partnum" +STMT: InsertStmt +STMT: SelectStmt +== 092 +select * from shipped_view +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=Select +STMT: SelectStmt +== 093 +create rule shipped_view_update as on update to shipped_view do instead + update shipped set partnum = new.partnum, value = new.value + where ttype = new.ttype and ordnum = new.ordnum +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DDL +STMT: RuleStmt +== 094 +update shipped_view set value = 11 + from int4_tbl a join int4_tbl b + on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)) + where ordnum = a.f1 +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +ALIAS: "c"="int4_tbl" +FILTER: schema="" table="c" column="f1" +FILTER: schema="" table="b" column="f1" +STMT: UpdateStmt +STMT: SelectStmt +== 095 +select * from shipped_view +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=Select +STMT: SelectStmt +== 096 +select f1, ss1 as relabel from + (select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1 + from int4_tbl a) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="a" column="f1" +STMT: SelectStmt +== 097 +|-- +-- Test cases involving PARAM_EXEC parameters and min/max index optimizations. +-- Per bug report from David Sanchez i Gregori. +|-- + +select * from ( + select max(unique1) from tenk1 as a + where exists (select 1 from tenk1 as b where b.thousand = a.unique2) +) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="a" column="unique2" +STMT: SelectStmt +== 098 +select * from ( + select min(unique1) from tenk1 as a + where not exists (select 1 from tenk1 as b where b.unique2 = 10000) +) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +== 099 +|-- +-- Test that an IN implemented using a UniquePath does unique-ification +-- with the right semantics, as per bug #4113. (Unfortunately we have +-- no simple way to ensure that this test case actually chooses that type +-- of plan, but it does in releases 7.4-8.3. Note that an ordering difference +-- here might mean that some other plan type is being used, rendering the test +-- pointless.) +|-- + +create temp table numeric_table (num_col numeric) +-- +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=DDL +STMT: CreateStmt +== 100 +insert into numeric_table values (1), (1.000000000000000000001), (2), (3) +-- +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +create temp table float_table (float_col float8) +-- +TABLE: name="float_table" schema="" table="float_table" ctx=DDL +STMT: CreateStmt +== 102 +insert into float_table values (1), (2), (3) +-- +TABLE: name="float_table" schema="" table="float_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +select * from float_table + where float_col in (select num_col from numeric_table) +-- +TABLE: name="float_table" schema="" table="float_table" ctx=Select +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=Select +FILTER: schema="" table="" column="float_col" +STMT: SelectStmt +== 104 +select * from numeric_table + where num_col in (select float_col from float_table) +-- +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=Select +TABLE: name="float_table" schema="" table="float_table" ctx=Select +FILTER: schema="" table="" column="num_col" +STMT: SelectStmt +== 105 +|-- +-- Test case for bug #4290: bogus calculation of subplan param sets +|-- + +create temp table ta (id int primary key, val int) +-- +TABLE: name="ta" schema="" table="ta" ctx=DDL +STMT: CreateStmt +== 106 +insert into ta values(1,1) +-- +TABLE: name="ta" schema="" table="ta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +insert into ta values(2,2) +-- +TABLE: name="ta" schema="" table="ta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +create temp table tb (id int primary key, aval int) +-- +TABLE: name="tb" schema="" table="tb" ctx=DDL +STMT: CreateStmt +== 109 +insert into tb values(1,1) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +insert into tb values(2,1) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +insert into tb values(3,2) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 112 +insert into tb values(4,2) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 113 +create temp table tc (id int primary key, aid int) +-- +TABLE: name="tc" schema="" table="tc" ctx=DDL +STMT: CreateStmt +== 114 +insert into tc values(1,1) +-- +TABLE: name="tc" schema="" table="tc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +insert into tc values(2,2) +-- +TABLE: name="tc" schema="" table="tc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +select + ( select min(tb.id) from tb + where tb.aval = (select ta.val from ta where ta.id = tc.aid) ) as min_tb_id +from tc +-- +TABLE: name="tc" schema="" table="tc" ctx=Select +TABLE: name="tb" schema="" table="tb" ctx=Select +TABLE: name="ta" schema="" table="ta" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="tb" column="aval" +FILTER: schema="" table="ta" column="id" +FILTER: schema="" table="tc" column="aid" +STMT: SelectStmt +== 117 +|-- +-- Test case for 8.3 "failed to locate grouping columns" bug +|-- + +create temp table t1 (f1 numeric(14,0), f2 varchar(30)) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 118 +select * from + (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs + from t1 up) ss +group by f1,f2,fs +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "up"="t1" +ALIAS: "x"="t1" +FILTER: schema="" table="x" column="f1" +FILTER: schema="" table="up" column="f1" +STMT: SelectStmt +== 119 +|-- +-- Test case for bug #5514 (mishandling of whole-row Vars in subselects) +|-- + +create temp table table_a(id integer) +-- +TABLE: name="table_a" schema="" table="table_a" ctx=DDL +STMT: CreateStmt +== 120 +insert into table_a values (42) +-- +TABLE: name="table_a" schema="" table="table_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +create temp view view_a as select * from table_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=DDL +TABLE: name="table_a" schema="" table="table_a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 122 +select view_a from view_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +STMT: SelectStmt +== 123 +select (select view_a) from view_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +STMT: SelectStmt +== 124 +select (select (select view_a)) from view_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +STMT: SelectStmt +== 125 +select (select (a.*)::text) from view_a a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +ALIAS: "a"="view_a" +STMT: SelectStmt +== 126 +|-- +-- Test case for bug #19037: no relation entry for relid N +|-- + +explain (costs off) +select (1 = any(array_agg(f1))) = any (select false) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 127 +select (1 = any(array_agg(f1))) = any (select false) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +== 128 +|-- +-- Check that whole-row Vars reading the result of a subselect don't include +-- any junk columns therein +|-- + +select q from (select max(f1) from int4_tbl group by f1 order by f1) q +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 129 +with q as (select max(f1) from int4_tbl group by f1 order by f1) + select q from q +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "q" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 130 +|-- +-- Test case for sublinks pulled up into joinaliasvars lists in an +-- inherited update/delete query +|-- + +begin +-- +STMT: TransactionStmt +== 131 +-- this shouldn't delete anything, but be safe + +delete from road +where exists ( + select 1 + from + int4_tbl cross join + ( select f1, array(select q1 from int8_tbl) as arr + from text_tbl ) ss + where road.name = ss.f1 ) +-- +TABLE: name="road" schema="" table="road" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="road" column="name" +FILTER: schema="" table="ss" column="f1" +STMT: DeleteStmt +STMT: SelectStmt +== 132 +rollback +-- +STMT: TransactionStmt +== 133 +|-- +-- Test case for sublinks pushed down into subselects via join alias expansion +|-- + +select + (select sq1) as qq1 +from + (select exists(select 1 from int4_tbl where f1 = q2) as sq1, 42 as dummy + from int8_tbl) sq0 + join + int4_tbl i4 on dummy = i4.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 134 +|-- +-- Test case for subselect within UPDATE of INSERT...ON CONFLICT DO UPDATE +|-- +create temp table upsert(key int4 primary key, val text) +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateStmt +== 135 +insert into upsert values(1, 'val') on conflict (key) do update set val = 'not seen' +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 136 +insert into upsert values(1, 'val') on conflict (key) do update set val = 'seen with subselect ' || (select f1 from int4_tbl where f1 != 0 limit 1)::text +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: InsertStmt +STMT: SelectStmt +== 137 +select * from upsert +-- +TABLE: name="upsert" schema="" table="upsert" ctx=Select +STMT: SelectStmt +== 138 +with aa as (select 'int4_tbl' u from int4_tbl limit 1) +insert into upsert values (1, 'x'), (999, 'y') +on conflict (key) do update set val = (select u from aa) +returning * +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "aa" +STMT: InsertStmt +STMT: SelectStmt +== 139 +|-- +-- Test case for cross-type partial matching in hashed subplan (bug #7597) +|-- + +create temp table outer_7597 (f1 int4, f2 int4) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DDL +STMT: CreateStmt +== 140 +insert into outer_7597 values (0, 0) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 141 +insert into outer_7597 values (1, 0) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +insert into outer_7597 values (0, null) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +insert into outer_7597 values (1, null) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 144 +create temp table inner_7597(c1 int8, c2 int8) +-- +TABLE: name="inner_7597" schema="" table="inner_7597" ctx=DDL +STMT: CreateStmt +== 145 +insert into inner_7597 values(0, null) +-- +TABLE: name="inner_7597" schema="" table="inner_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +select * from outer_7597 where (f1, f2) not in (select * from inner_7597) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=Select +TABLE: name="inner_7597" schema="" table="inner_7597" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 147 +|-- +-- Similar test case using text that verifies that collation +-- information is passed through by execTuplesEqual() in nodeSubplan.c +-- (otherwise it would error in texteq()) +|-- + +create temp table outer_text (f1 text, f2 text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DDL +STMT: CreateStmt +== 148 +insert into outer_text values ('a', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 149 +insert into outer_text values ('b', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +insert into outer_text values ('a', null) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 151 +insert into outer_text values ('b', null) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +create temp table inner_text (c1 text, c2 text) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DDL +STMT: CreateStmt +== 153 +insert into inner_text values ('a', null) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +insert into inner_text values ('123', '456') +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +select * from outer_text where (f1, f2) not in (select * from inner_text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 156 +|-- +-- Another test case for cross-type hashed subplans: comparison of +-- inner-side values must be done with appropriate operator +|-- + +explain (verbose, costs off) +select 'foo'::text in (select 'bar'::name union all select 'bar'::name) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 157 +select 'foo'::text in (select 'bar'::name union all select 'bar'::name) +-- +STMT: SelectStmt +== 158 +|-- +-- Test that we don't try to hash nested records (bug #17363) +-- (Hashing could be supported, but for now we don't) +|-- + +explain (verbose, costs off) +select row(row(row(1))) = any (select row(row(1))) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 159 +select row(row(row(1))) = any (select row(row(1))) +-- +STMT: SelectStmt +== 160 +|-- +-- Test case for premature memory release during hashing of subplan output +|-- + +select '1'::text in (select '1'::name union all select '1'::name) +-- +STMT: SelectStmt +== 161 +|-- +-- Test that we don't try to use a hashed subplan if the simplified +-- testexpr isn't of the right shape +|-- + +-- this fails by default, of course +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 162 +begin +-- +STMT: TransactionStmt +== 163 +-- make an operator to allow it to succeed +create function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $1::text = $2' +-- +FUNCTION: name="bogus_int8_text_eq" function="bogus_int8_text_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 164 +create operator = (procedure=bogus_int8_text_eq, leftarg=int8, rightarg=text) +-- +STMT: DefineStmt +== 165 +explain (costs off) +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 166 +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 167 +-- inlining of this function results in unusual number of hash clauses, +-- which we can still cope with +create or replace function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $1::text = $2 and $1::text = $2' +-- +FUNCTION: name="bogus_int8_text_eq" function="bogus_int8_text_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 168 +explain (costs off) +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 169 +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 170 +-- inlining of this function causes LHS and RHS to be switched, +-- which we can't cope with, so hashing should be abandoned +create or replace function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $2 = $1::text' +-- +FUNCTION: name="bogus_int8_text_eq" function="bogus_int8_text_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 171 +explain (costs off) +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 172 +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +== 173 +rollback +-- +STMT: TransactionStmt +== 174 +-- to get rid of the bogus operator + +|-- +-- Test resolution of hashed vs non-hashed implementation of EXISTS subplan +|-- +explain (costs off) +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 175 +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: SelectStmt +== 176 +explain (costs off) +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) + and thousand = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 177 +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) + and thousand = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: SelectStmt +== 178 +-- It's possible for the same EXISTS to get resolved both ways +create temp table exists_tbl (c1 int, c2 int, c3 int) partition by list (c1) +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=DDL +STMT: CreateStmt +== 179 +create temp table exists_tbl_null partition of exists_tbl for values in (null) +-- +TABLE: name="exists_tbl_null" schema="" table="exists_tbl_null" ctx=DDL +STMT: CreateStmt +== 180 +create temp table exists_tbl_def partition of exists_tbl default +-- +TABLE: name="exists_tbl_def" schema="" table="exists_tbl_def" ctx=DDL +STMT: CreateStmt +== 181 +insert into exists_tbl select x, x/2, x+1 from generate_series(0,10) x +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 182 +analyze exists_tbl +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=DDL +STMT: VacuumStmt +== 183 +explain (costs off) +select * from exists_tbl t1 + where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0) +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +ALIAS: "t1"="exists_tbl" +ALIAS: "t2"="exists_tbl" +FILTER: schema="" table="t1" column="c1" +FILTER: schema="" table="t2" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +== 184 +select * from exists_tbl t1 + where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0) +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +ALIAS: "t1"="exists_tbl" +ALIAS: "t2"="exists_tbl" +FILTER: schema="" table="t1" column="c1" +FILTER: schema="" table="t2" column="c2" +STMT: SelectStmt +== 185 +|-- +-- Test case for planner bug with nested EXISTS handling +|-- +select a.thousand from tenk1 a, tenk1 b +where a.thousand = b.thousand + and exists ( select 1 from tenk1 c where b.hundred = c.hundred + and not exists ( select 1 from tenk1 d + where a.thousand = d.thousand ) ) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +ALIAS: "d"="tenk1" +FILTER: schema="" table="a" column="thousand" +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="b" column="hundred" +FILTER: schema="" table="c" column="hundred" +FILTER: schema="" table="a" column="thousand" +FILTER: schema="" table="d" column="thousand" +STMT: SelectStmt +== 186 +|-- +-- Check that nested sub-selects are not pulled up if they contain volatiles +|-- +explain (verbose, costs off) + select x, x from + (select (select now()) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 187 +explain (verbose, costs off) + select x, x from + (select (select random()) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 188 +explain (verbose, costs off) + select x, x from + (select (select now() where y=y) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 189 +explain (verbose, costs off) + select x, x from + (select (select random() where y=y) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +== 190 +|-- +-- Test rescan of a hashed subplan (the use of random() is to prevent the +-- sub-select from being pulled up, which would result in not hashing) +|-- +explain (verbose, costs off) +select sum(ss.tst::int) from + onek o cross join lateral ( + select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, + random() as r + from onek i where i.unique1 = o.unique1 ) ss +where o.ten = 0 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="onek" +ALIAS: "o"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="o" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +== 191 +select sum(ss.tst::int) from + onek o cross join lateral ( + select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, + random() as r + from onek i where i.unique1 = o.unique1 ) ss +where o.ten = 0 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="onek" +ALIAS: "o"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="o" column="hundred" +STMT: SelectStmt +== 192 +|-- +-- Test rescan of a SetOp node +|-- +explain (costs off) +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "i1"="onek" +ALIAS: "i2"="onek" +ALIAS: "o"="onek" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i1" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="i2" column="unique1" +FILTER: schema="" table="o" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 193 +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "i1"="onek" +ALIAS: "i2"="onek" +ALIAS: "o"="onek" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i1" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="i2" column="unique1" +FILTER: schema="" table="o" column="unique2" +STMT: SelectStmt +== 194 +|-- +-- Test rescan of a RecursiveUnion node +|-- +explain (costs off) +select sum(o.four), sum(ss.a) from + onek o cross join lateral ( + with recursive x(a) as + (select o.four as a + union + select a + 1 from x + where a < 10) + select * from x + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "o"="onek" +CTE: "x" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 195 +select sum(o.four), sum(ss.a) from + onek o cross join lateral ( + with recursive x(a) as + (select o.four as a + union + select a + 1 from x + where a < 10) + select * from x + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "o"="onek" +CTE: "x" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 196 +|-- +-- Check we don't misoptimize a NOT IN where the subquery returns no rows. +|-- +create temp table notinouter (a int) +-- +TABLE: name="notinouter" schema="" table="notinouter" ctx=DDL +STMT: CreateStmt +== 197 +create temp table notininner (b int not null) +-- +TABLE: name="notininner" schema="" table="notininner" ctx=DDL +STMT: CreateStmt +== 198 +insert into notinouter values (null), (1) +-- +TABLE: name="notinouter" schema="" table="notinouter" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 199 +select * from notinouter where a not in (select b from notininner) +-- +TABLE: name="notinouter" schema="" table="notinouter" ctx=Select +TABLE: name="notininner" schema="" table="notininner" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 200 +|-- +-- Check we behave sanely in corner case of empty SELECT list (bug #8648) +|-- +create temp table nocolumns() +-- +TABLE: name="nocolumns" schema="" table="nocolumns" ctx=DDL +STMT: CreateStmt +== 201 +select exists(select * from nocolumns) +-- +TABLE: name="nocolumns" schema="" table="nocolumns" ctx=Select +STMT: SelectStmt +== 202 +|-- +-- Check behavior with a SubPlan in VALUES (bug #14924) +|-- +select val.x + from generate_series(1,10) as s(i), + lateral ( + values ((select s.i + 1)), (s.i + 101) + ) as val(x) +where s.i < 10 and (select val.x) < 110 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="s" column="i" +STMT: SelectStmt +== 203 +-- another variant of that (bug #16213) +explain (verbose, costs off) +select * from +(values + (3 not in (select * from (values (1), (2)) ss1)), + (false) +) ss +-- +STMT: ExplainStmt +STMT: SelectStmt +== 204 +select * from +(values + (3 not in (select * from (values (1), (2)) ss1)), + (false) +) ss +-- +STMT: SelectStmt +== 205 +|-- +-- Check sane behavior with nested IN SubLinks +|-- +explain (verbose, costs off) +select * from int4_tbl where + (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in + (select ten from tenk1 b) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 206 +select * from int4_tbl where + (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in + (select ten from tenk1 b) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 207 +|-- +-- Check for incorrect optimization when IN subquery contains a SRF +|-- +explain (verbose, costs off) +select * from int4_tbl o where (f1, f1) in + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 208 +select * from int4_tbl o where (f1, f1) in + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 209 +|-- +-- check for over-optimization of whole-row Var referencing an Append plan +|-- +select (select q from + (select 1,2,3 where f1 > 0 + union all + select 4,5,6.0 where f1 <= 0 + ) q ) +from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 210 +|-- +-- Check for sane handling of a lateral reference in a subquery's quals +-- (most of the complication here is to prevent the test case from being +-- flattened too much) +|-- +explain (verbose, costs off) +select * from + int4_tbl i4, + lateral ( + select i4.f1 > 1 as b, 1 as id + from (select random() order by 1) as t1 + union all + select true as b, 2 as id + ) as t2 +where b and f1 >= 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 211 +select * from + int4_tbl i4, + lateral ( + select i4.f1 > 1 as b, 1 as id + from (select random() order by 1) as t1 + union all + select true as b, 2 as id + ) as t2 +where b and f1 >= 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 212 +|-- +-- Check that volatile quals aren't pushed down past a DISTINCT: +-- nextval() should not be called more than the nominal number of times +|-- +create temp sequence ts1 +-- +STMT: CreateSeqStmt +== 213 +select * from + (select distinct ten from tenk1) ss + where ten < 10 + nextval('ts1') + order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +FILTER: schema="" table="" column="ten" +STMT: SelectStmt +== 214 +select nextval('ts1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 215 +|-- +-- Check that volatile quals aren't pushed down past a set-returning function; +-- while a nonvolatile qual can be, if it doesn't reference the SRF. +|-- +create function tattle(x int, y int) returns bool +volatile language plpgsql as $$ +begin + raise notice 'x = %, y = %', x, y; + return x > y; +end$$ +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 216 +explain (verbose, costs off) +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 217 +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 218 +-- if we pretend it's stable, we get different results: +alter function tattle(x int, y int) stable +-- +STMT: AlterFunctionStmt +== 219 +explain (verbose, costs off) +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 220 +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 221 +-- although even a stable qual should not be pushed down if it references SRF +explain (verbose, costs off) +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, u) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="u" +STMT: ExplainStmt +STMT: SelectStmt +== 222 +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, u) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="u" +STMT: SelectStmt +== 223 +drop function tattle(x int, y int) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=DDL +STMT: DropStmt +== 224 +|-- +-- Test that LIMIT can be pushed to SORT through a subquery that just projects +-- columns. We check for that having happened by looking to see if EXPLAIN +-- ANALYZE shows that a top-N sort was used. We must suppress or filter away +-- all the non-invariant parts of the EXPLAIN ANALYZE output. +|-- +create table sq_limit (pk int primary key, c1 int, c2 int) +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=DDL +STMT: CreateStmt +== 225 +insert into sq_limit values + (1, 1, 1), + (2, 2, 2), + (3, 3, 3), + (4, 4, 4), + (5, 1, 1), + (6, 2, 2), + (7, 3, 3), + (8, 4, 4) +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 226 +create function explain_sq_limit() returns setof text language plpgsql as +$$ +declare ln text; +begin + for ln in + explain (analyze, summary off, timing off, costs off) + select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3 + loop + ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_sq_limit" function="explain_sq_limit" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 227 +select * from explain_sq_limit() +-- +FUNCTION: name="explain_sq_limit" function="explain_sq_limit" schema="" ctx=Call +STMT: SelectStmt +== 228 +select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3 +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=Select +STMT: SelectStmt +== 229 +drop function explain_sq_limit() +-- +FUNCTION: name="explain_sq_limit" function="explain_sq_limit" schema="" ctx=DDL +STMT: DropStmt +== 230 +drop table sq_limit +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=DDL +STMT: DropStmt +== 231 +|-- +-- Ensure that backward scan direction isn't propagated into +-- expression subqueries (bug #15336) +|-- + +begin +-- +STMT: TransactionStmt +== 232 +declare c1 scroll cursor for + select * from generate_series(1,4) i + where i <> all (values (2),(3)) +-- +STMT: DeclareCursorStmt +== 233 +move forward all in c1 +-- +STMT: FetchStmt +== 234 +fetch backward all in c1 +-- +STMT: FetchStmt +== 235 +commit +-- +STMT: TransactionStmt +== 236 +|-- +-- Check that JsonConstructorExpr is treated as non-strict, and thus can be +-- wrapped in a PlaceHolderVar +|-- + +begin +-- +STMT: TransactionStmt +== 237 +create temp table json_tab (a int) +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=DDL +STMT: CreateStmt +== 238 +insert into json_tab values (1) +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 239 +explain (verbose, costs off) +select * from json_tab t1 left join (select json_array(1, a) from json_tab t2) s on false +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +ALIAS: "t1"="json_tab" +ALIAS: "t2"="json_tab" +STMT: ExplainStmt +STMT: SelectStmt +== 240 +select * from json_tab t1 left join (select json_array(1, a) from json_tab t2) s on false +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +ALIAS: "t1"="json_tab" +ALIAS: "t2"="json_tab" +STMT: SelectStmt +== 241 +rollback +-- +STMT: TransactionStmt +== 242 +|-- +-- Verify that we correctly flatten cases involving a subquery output +-- expression that doesn't need to be wrapped in a PlaceHolderVar +|-- + +explain (costs off) +select tname, attname from ( +select relname::information_schema.sql_identifier as tname, * from + (select * from pg_class c) ss1) ss2 + right join pg_attribute a on a.attrelid = ss2.oid +where tname = 'tenk1' and attnum = 1 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="tname" +FILTER: schema="" table="" column="attnum" +STMT: ExplainStmt +STMT: SelectStmt +== 243 +select tname, attname from ( +select relname::information_schema.sql_identifier as tname, * from + (select * from pg_class c) ss1) ss2 + right join pg_attribute a on a.attrelid = ss2.oid +where tname = 'tenk1' and attnum = 1 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="tname" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +== 244 +-- Check behavior when there's a lateral reference in the output expression +explain (verbose, costs off) +select t1.ten, sum(x) from + tenk1 t1 left join lateral ( + select t1.ten + t2.ten as x, t2.fivethous from tenk1 t2 + ) ss on t1.unique1 = ss.fivethous +group by t1.ten +order by t1.ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 245 +select t1.ten, sum(x) from + tenk1 t1 left join lateral ( + select t1.ten + t2.ten as x, t2.fivethous from tenk1 t2 + ) ss on t1.unique1 = ss.fivethous +group by t1.ten +order by t1.ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 246 +explain (verbose, costs off) +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +== 247 +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +STMT: SelectStmt +== 248 +|-- +-- Tests for CTE inlining behavior +|-- + +-- Basic subquery that can be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 249 +-- Explicitly request materialization +explain (verbose, costs off) +with x as materialized (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 250 +-- Stable functions are safe to inline +explain (verbose, costs off) +with x as (select * from (select f1, now() from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 251 +-- Volatile functions prevent inlining +explain (verbose, costs off) +with x as (select * from (select f1, random() from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 252 +-- SELECT FOR UPDATE cannot be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl for update) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 253 +-- Multiply-referenced CTEs are inlined only when requested +explain (verbose, costs off) +with x as (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "x2"="x" +CTE: "x" +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="x" column="n" +FILTER: schema="" table="x2" column="n" +STMT: ExplainStmt +STMT: SelectStmt +== 254 +explain (verbose, costs off) +with x as not materialized (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "x2"="x" +CTE: "x" +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="x" column="n" +FILTER: schema="" table="x2" column="n" +STMT: ExplainStmt +STMT: SelectStmt +== 255 +-- Multiply-referenced CTEs can't be inlined if they contain outer self-refs +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x +-- +ALIAS: "z1"="z" +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 256 +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x +-- +ALIAS: "z1"="z" +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z1" column="a" +STMT: SelectStmt +== 257 +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x +-- +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 258 +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x +-- +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z" column="a" +STMT: SelectStmt +== 259 +-- Check handling of outer references +explain (verbose, costs off) +with x as (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "y" +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +== 260 +explain (verbose, costs off) +with x as materialized (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "y" +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +== 261 +-- Ensure that we inline the correct CTE when there are +-- multiple CTEs with the same name +explain (verbose, costs off) +with x as (select 1 as y) +select * from (with x as (select 2 as y) select * from x) ss +-- +CTE: "x" +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +== 262 +-- Row marks are not pushed into CTEs +explain (verbose, costs off) +with x as (select * from subselect_tbl) +select * from x for update +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +== 263 +-- Pull up direct-correlated ANY_SUBLINKs +explain (costs off) +select * from tenk1 A where hundred in (select hundred from tenk2 B where B.odd = A.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="b" column="odd" +FILTER: schema="" table="a" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +== 264 +explain (costs off) +select * from tenk1 A where exists +(select 1 from tenk2 B +where A.hundred in (select C.hundred FROM tenk2 C +WHERE c.odd = b.odd)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="a" column="hundred" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +== 265 +-- we should only try to pull up the sublink into RHS of a left join +-- but a.hundred is not available. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON A.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = b.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +== 266 +-- we should only try to pull up the sublink into RHS of a left join +-- but a.odd is not available for this. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON B.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = a.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="a" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +== 267 +-- should be able to pull up since all the references are available. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON B.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = b.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +== 268 +-- we can pull up the sublink into the inner JoinExpr. +explain (costs off) +SELECT * FROM tenk1 A INNER JOIN tenk2 B +ON A.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = b.odd) +WHERE a.thousand < 750 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="a" column="thousand" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +== 269 +-- we can pull up the aggregate sublink into RHS of a left join. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON B.hundred in (SELECT min(c.hundred) FROM tenk2 C WHERE c.odd = b.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/sysviews.metadata.json b/parser/testdata/summary/postgres_regress/sysviews.metadata.json new file mode 100644 index 0000000..7249d3a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sysviews.metadata.json @@ -0,0 +1,31 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027" + ] +} diff --git a/parser/testdata/summary/postgres_regress/sysviews.test b/parser/testdata/summary/postgres_regress/sysviews.test new file mode 100644 index 0000000..6033153 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/sysviews.test @@ -0,0 +1,199 @@ +== 001 +|-- +-- Test assorted system views +|-- +-- This test is mainly meant to provide some code coverage for the +-- set-returning functions that underlie certain system views. +-- The output of most of these functions is very environment-dependent, +-- so our ability to test with fixed expected output is pretty limited; +-- but even a trivial check of count(*) will exercise the normal code path +-- through the SRF. + +select count(*) >= 0 as ok from pg_available_extension_versions +-- +TABLE: name="pg_available_extension_versions" schema="" table="pg_available_extension_versions" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 002 +select count(*) >= 0 as ok from pg_available_extensions +-- +TABLE: name="pg_available_extensions" schema="" table="pg_available_extensions" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- The entire output of pg_backend_memory_contexts is not stable, +-- we test only the existence and basic condition of TopMemoryContext. +select name, ident, parent, level, total_bytes >= free_bytes + from pg_backend_memory_contexts where level = 0 +-- +TABLE: name="pg_backend_memory_contexts" schema="" table="pg_backend_memory_contexts" ctx=Select +FILTER: schema="" table="" column="level" +STMT: SelectStmt +== 004 +-- We can exercise some MemoryContext type stats functions. Most of the +-- column values are too platform-dependant to display. + +-- Ensure stats from the bump allocator look sane. Bump isn't a commonly +-- used context, but it is used in tuplesort.c, so open a cursor to keep +-- the tuplesort alive long enough for us to query the context stats. +begin +-- +STMT: TransactionStmt +== 005 +declare cur cursor for select left(a,10), b + from (values(repeat('a', 512 * 1024),1),(repeat('b', 512),2)) v(a,b) + order by v.a desc +-- +STMT: DeclareCursorStmt +== 006 +fetch 1 from cur +-- +STMT: FetchStmt +== 007 +select name, parent, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks +from pg_backend_memory_contexts where name = 'Caller tuples' +-- +TABLE: name="pg_backend_memory_contexts" schema="" table="pg_backend_memory_contexts" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 008 +rollback +-- +STMT: TransactionStmt +== 009 +-- At introduction, pg_config had 23 entries; it may grow +select count(*) > 20 as ok from pg_config +-- +TABLE: name="pg_config" schema="" table="pg_config" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 010 +-- We expect no cursors in this test; see also portals.sql +select count(*) = 0 as ok from pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 011 +select count(*) >= 0 as ok from pg_file_settings +-- +TABLE: name="pg_file_settings" schema="" table="pg_file_settings" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- There will surely be at least one rule, with no errors. +select count(*) > 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err + from pg_hba_file_rules +-- +TABLE: name="pg_hba_file_rules" schema="" table="pg_hba_file_rules" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- There may be no rules, and there should be no errors. +select count(*) >= 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err + from pg_ident_file_mappings +-- +TABLE: name="pg_ident_file_mappings" schema="" table="pg_ident_file_mappings" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- There will surely be at least one active lock +select count(*) > 0 as ok from pg_locks +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 015 +-- We expect no prepared statements in this test; see also prepare.sql +select count(*) = 0 as ok from pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- See also prepared_xacts.sql +select count(*) >= 0 as ok from pg_prepared_xacts +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- There will surely be at least one SLRU cache +select count(*) > 0 as ok from pg_stat_slru +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- There must be only one record +select count(*) = 1 as ok from pg_stat_wal +-- +TABLE: name="pg_stat_wal" schema="" table="pg_stat_wal" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- We expect no walreceiver running in this test +select count(*) = 0 as ok from pg_stat_wal_receiver +-- +TABLE: name="pg_stat_wal_receiver" schema="" table="pg_stat_wal_receiver" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- This is to record the prevailing planner enable_foo settings during +-- a regression test run. +select name, setting from pg_settings where name like 'enable%' +-- +TABLE: name="pg_settings" schema="" table="pg_settings" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 021 +-- There are always wait event descriptions for various types. InjectionPoint +-- may be present or absent, depending on history since last postmaster start. +select type, count(*) > 0 as ok FROM pg_wait_events + where type <> 'InjectionPoint' group by type order by type COLLATE "C" +-- +TABLE: name="pg_wait_events" schema="" table="pg_wait_events" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="type" +STMT: SelectStmt +== 022 +-- Test that the pg_timezone_names and pg_timezone_abbrevs views are +-- more-or-less working. We can't test their contents in any great detail +-- without the outputs changing anytime IANA updates the underlying data, +-- but it seems reasonable to expect at least one entry per major meridian. +-- (At the time of writing, the actual counts are around 38 because of +-- zones using fractional GMT offsets, so this is a pretty loose test.) +select count(distinct utc_offset) >= 24 as ok from pg_timezone_names +-- +TABLE: name="pg_timezone_names" schema="" table="pg_timezone_names" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 023 +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs +-- +TABLE: name="pg_timezone_abbrevs" schema="" table="pg_timezone_abbrevs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 024 +-- Let's check the non-default timezone abbreviation sets, too +set timezone_abbreviations = 'Australia' +-- +STMT: VariableSetStmt +== 025 +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs +-- +TABLE: name="pg_timezone_abbrevs" schema="" table="pg_timezone_abbrevs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 026 +set timezone_abbreviations = 'India' +-- +STMT: VariableSetStmt +== 027 +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs +-- +TABLE: name="pg_timezone_abbrevs" schema="" table="pg_timezone_abbrevs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/tablesample.metadata.json b/parser/testdata/summary/postgres_regress/tablesample.metadata.json new file mode 100644 index 0000000..dc9d431 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tablesample.metadata.json @@ -0,0 +1,60 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tablesample.test b/parser/testdata/summary/postgres_regress/tablesample.test new file mode 100644 index 0000000..7a52313 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tablesample.test @@ -0,0 +1,327 @@ +== 001 +CREATE TABLE test_tablesample (id int, name text) WITH (fillfactor=10) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=DDL +STMT: CreateStmt +== 002 +-- use fillfactor so we don't have to load too much data to get multiple pages + +INSERT INTO test_tablesample + SELECT i, repeat(i::text, 200) FROM generate_series(0, 9) s(i) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 003 +SELECT t.id FROM test_tablesample AS t TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +ALIAS: "t"="test_tablesample" +STMT: SelectStmt +== 004 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (100.0/11) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 005 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 006 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 007 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (5.5) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 008 +-- 100% should give repeatable count results (ie, all rows) in any case +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 009 +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (1+2) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (0.4) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 011 +CREATE VIEW test_tablesample_v1 AS + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (10*2) REPEATABLE (2) +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=DDL +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 012 +CREATE VIEW test_tablesample_v2 AS + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (99) +-- +TABLE: name="test_tablesample_v2" schema="" table="test_tablesample_v2" ctx=DDL +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 013 +-- check a sampled query doesn't affect cursor in progress +BEGIN +-- +STMT: TransactionStmt +== 014 +DECLARE tablesample_cur SCROLL CURSOR FOR + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +STMT: DeclareCursorStmt +== 015 +FETCH FIRST FROM tablesample_cur +-- +STMT: FetchStmt +== 016 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 017 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 018 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 019 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 020 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 021 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 022 +FETCH FIRST FROM tablesample_cur +-- +STMT: FetchStmt +== 023 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 024 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 025 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 026 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 027 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +== 028 +CLOSE tablesample_cur +-- +STMT: ClosePortalStmt +== 029 +END +-- +STMT: TransactionStmt +== 030 +EXPLAIN (COSTS OFF) + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (2) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 031 +EXPLAIN (COSTS OFF) + SELECT * FROM test_tablesample_v1 +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 032 +-- check inheritance behavior +explain (costs off) + select count(*) from person tablesample bernoulli (100) +-- +TABLE: name="person" schema="" table="person" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 033 +select count(*) from person tablesample bernoulli (100) +-- +TABLE: name="person" schema="" table="person" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 034 +select count(*) from person +-- +TABLE: name="person" schema="" table="person" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 035 +-- check that collations get assigned within the tablesample arguments +SELECT count(*) FROM test_tablesample TABLESAMPLE bernoulli (('1'::text < '0'::text)::int) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- check behavior during rescans, as well as correct handling of min/max pct +select * from + (values (0),(100)) v(pct), + lateral (select count(*) from tenk1 tablesample bernoulli (pct)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 037 +select * from + (values (0),(100)) v(pct), + lateral (select count(*) from tenk1 tablesample system (pct)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 038 +explain (costs off) +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample bernoulli (pct)) ss + group by pct +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 039 +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample bernoulli (pct)) ss + group by pct +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 040 +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample system (pct)) ss + group by pct +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- errors +SELECT id FROM test_tablesample TABLESAMPLE FOOBAR (1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 042 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (NULL) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 043 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (NULL) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 044 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (-1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 045 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (200) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 046 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (-1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 047 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (200) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +== 048 +SELECT id FROM test_tablesample_v1 TABLESAMPLE BERNOULLI (1) +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=Select +STMT: SelectStmt +== 049 +INSERT INTO test_tablesample_v1 VALUES(1) +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +WITH query_select AS (SELECT * FROM test_tablesample) +SELECT * FROM query_select TABLESAMPLE BERNOULLI (5.5) REPEATABLE (1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +CTE: "query_select" +STMT: SelectStmt +== 051 +SELECT q.* FROM (SELECT * FROM test_tablesample) as q TABLESAMPLE BERNOULLI (5) +-- +ERROR: syntax error at or near "TABLESAMPLE" +CURSORPOS: 55 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 052 +-- check partitioned tables support tablesample +create table parted_sample (a int) partition by list (a) +-- +TABLE: name="parted_sample" schema="" table="parted_sample" ctx=DDL +STMT: CreateStmt +== 053 +create table parted_sample_1 partition of parted_sample for values in (1) +-- +TABLE: name="parted_sample_1" schema="" table="parted_sample_1" ctx=DDL +STMT: CreateStmt +== 054 +create table parted_sample_2 partition of parted_sample for values in (2) +-- +TABLE: name="parted_sample_2" schema="" table="parted_sample_2" ctx=DDL +STMT: CreateStmt +== 055 +explain (costs off) + select * from parted_sample tablesample bernoulli (100) +-- +TABLE: name="parted_sample" schema="" table="parted_sample" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 056 +drop table parted_sample, parted_sample_1, parted_sample_2 +-- +TABLE: name="parted_sample" schema="" table="parted_sample" ctx=DDL +TABLE: name="parted_sample_1" schema="" table="parted_sample_1" ctx=DDL +TABLE: name="parted_sample_2" schema="" table="parted_sample_2" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/tablespace.metadata.json b/parser/testdata/summary/postgres_regress/tablespace.metadata.json new file mode 100644 index 0000000..479ae3b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tablespace.metadata.json @@ -0,0 +1,208 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tablespace.test b/parser/testdata/summary/postgres_regress/tablespace.test new file mode 100644 index 0000000..c34cb0c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tablespace.test @@ -0,0 +1,1200 @@ +== 001 +-- relative tablespace locations are not allowed +CREATE TABLESPACE regress_tblspace LOCATION 'relative' +-- +STMT: CreateTableSpaceStmt +== 002 +-- fail + +-- empty tablespace locations are not usually allowed +CREATE TABLESPACE regress_tblspace LOCATION '' +-- +STMT: CreateTableSpaceStmt +== 003 +-- fail + +-- as a special developer-only option to allow us to use tablespaces +-- with streaming replication on the same server, an empty location +-- can be allowed as a way to say that the tablespace should be created +-- as a directory in pg_tblspc, rather than being a symlink +SET allow_in_place_tablespaces = true +-- +STMT: VariableSetStmt +== 004 +-- create a tablespace using WITH clause +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (some_nonexistent_parameter = true) +-- +STMT: CreateTableSpaceStmt +== 005 +-- fail +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (random_page_cost = 3.0) +-- +STMT: CreateTableSpaceStmt +== 006 +-- ok + +-- check to see the parameter was used +SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith' +-- +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +FILTER: schema="" table="" column="spcname" +STMT: SelectStmt +== 007 +-- drop the tablespace so we can re-use the location +DROP TABLESPACE regress_tblspacewith +-- +STMT: DropTableSpaceStmt +== 008 +-- This returns a relative path as of an effect of allow_in_place_tablespaces, +-- masking the tablespace OID used in the path name. +SELECT regexp_replace(pg_tablespace_location(oid), '(pg_tblspc)/(\d+)', '\1/NNN') + FROM pg_tablespace WHERE spcname = 'regress_tblspace' +-- +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FUNCTION: name="pg_tablespace_location" function="pg_tablespace_location" schema="" ctx=Call +FILTER: schema="" table="" column="spcname" +STMT: SelectStmt +== 009 +-- try setting and resetting some properties for the new tablespace +ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1) +-- +STMT: AlterTableSpaceOptionsStmt +== 010 +ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true) +-- +STMT: AlterTableSpaceOptionsStmt +== 011 +-- fail +ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0) +-- +STMT: AlterTableSpaceOptionsStmt +== 012 +-- fail +ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency) +-- +STMT: AlterTableSpaceOptionsStmt +== 013 +-- ok + +-- REINDEX (TABLESPACE) +-- catalogs and system tablespaces +-- system catalog, fail +REINDEX (TABLESPACE regress_tblspace) TABLE pg_am +-- +STMT: ReindexStmt +== 014 +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_am +-- +STMT: ReindexStmt +== 015 +-- shared catalog, fail +REINDEX (TABLESPACE regress_tblspace) TABLE pg_authid +-- +STMT: ReindexStmt +== 016 +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_authid +-- +STMT: ReindexStmt +== 017 +-- toast relations, fail +REINDEX (TABLESPACE regress_tblspace) INDEX pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +== 018 +REINDEX (TABLESPACE regress_tblspace) INDEX CONCURRENTLY pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +== 019 +REINDEX (TABLESPACE regress_tblspace) TABLE pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +== 020 +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +== 021 +-- system catalog, fail +REINDEX (TABLESPACE pg_global) TABLE pg_authid +-- +STMT: ReindexStmt +== 022 +REINDEX (TABLESPACE pg_global) TABLE CONCURRENTLY pg_authid +-- +STMT: ReindexStmt +== 023 +-- table with toast relation +CREATE TABLE regress_tblspace_test_tbl (num1 bigint, num2 double precision, t text) +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: CreateStmt +== 024 +INSERT INTO regress_tblspace_test_tbl (num1, num2, t) + SELECT round(random()*100), random(), 'text' + FROM generate_series(1, 10) s(i) +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DML +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 025 +CREATE INDEX regress_tblspace_test_tbl_idx ON regress_tblspace_test_tbl (num1) +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: IndexStmt +== 026 +-- move to global tablespace, fail +REINDEX (TABLESPACE pg_global) INDEX regress_tblspace_test_tbl_idx +-- +STMT: ReindexStmt +== 027 +REINDEX (TABLESPACE pg_global) INDEX CONCURRENTLY regress_tblspace_test_tbl_idx +-- +STMT: ReindexStmt +== 028 +-- check transactional behavior of REINDEX (TABLESPACE) +BEGIN +-- +STMT: TransactionStmt +== 029 +REINDEX (TABLESPACE regress_tblspace) INDEX regress_tblspace_test_tbl_idx +-- +STMT: ReindexStmt +== 030 +REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl +-- +STMT: ReindexStmt +== 031 +ROLLBACK +-- +STMT: TransactionStmt +== 032 +-- no relation moved to the new tablespace +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +== 033 +-- check that all indexes are moved to a new tablespace with different +-- relfilenode. +-- Save first the existing relfilenode for the toast and main relations. +SELECT relfilenode as main_filenode FROM pg_class + WHERE relname = 'regress_tblspace_test_tbl_idx' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 034 +SELECT relfilenode as toast_filenode FROM pg_class + WHERE oid = + (SELECT i.indexrelid + FROM pg_class c, + pg_index i + WHERE i.indrelid = c.reltoastrelid AND + c.relname = 'regress_tblspace_test_tbl') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="i" column="indrelid" +FILTER: schema="" table="c" column="reltoastrelid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 035 +REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl +-- +STMT: ReindexStmt +== 036 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +== 037 +ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE regress_tblspace +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: AlterTableStmt +== 038 +ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE pg_default +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: AlterTableStmt +== 039 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +== 040 +-- Move back to the default tablespace. +ALTER INDEX regress_tblspace_test_tbl_idx SET TABLESPACE pg_default +-- +STMT: AlterTableStmt +== 041 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +== 042 +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE regress_tblspace_test_tbl +-- +STMT: ReindexStmt +== 043 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +== 044 +SELECT relfilenode = :main_filenode AS main_same FROM pg_class + WHERE relname = 'regress_tblspace_test_tbl_idx' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 045 +SELECT relfilenode = :toast_filenode as toast_same FROM pg_class + WHERE oid = + (SELECT i.indexrelid + FROM pg_class c, + pg_index i + WHERE i.indrelid = c.reltoastrelid AND + c.relname = 'regress_tblspace_test_tbl') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 046 +DROP TABLE regress_tblspace_test_tbl +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: DropStmt +== 047 +-- REINDEX (TABLESPACE) with partitions +-- Create a partition tree and check the set of relations reindexed +-- with their new tablespace. +CREATE TABLE tbspace_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1) +-- +TABLE: name="tbspace_reindex_part" schema="" table="tbspace_reindex_part" ctx=DDL +STMT: CreateStmt +== 048 +CREATE TABLE tbspace_reindex_part_0 PARTITION OF tbspace_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2) +-- +TABLE: name="tbspace_reindex_part_0" schema="" table="tbspace_reindex_part_0" ctx=DDL +STMT: CreateStmt +== 049 +CREATE TABLE tbspace_reindex_part_0_1 PARTITION OF tbspace_reindex_part_0 + FOR VALUES IN (1) +-- +TABLE: name="tbspace_reindex_part_0_1" schema="" table="tbspace_reindex_part_0_1" ctx=DDL +STMT: CreateStmt +== 050 +CREATE TABLE tbspace_reindex_part_0_2 PARTITION OF tbspace_reindex_part_0 + FOR VALUES IN (2) +-- +TABLE: name="tbspace_reindex_part_0_2" schema="" table="tbspace_reindex_part_0_2" ctx=DDL +STMT: CreateStmt +== 051 +-- This partitioned table will have no partitions. +CREATE TABLE tbspace_reindex_part_10 PARTITION OF tbspace_reindex_part + FOR VALUES FROM (10) TO (20) PARTITION BY list (c2) +-- +TABLE: name="tbspace_reindex_part_10" schema="" table="tbspace_reindex_part_10" ctx=DDL +STMT: CreateStmt +== 052 +-- Create some partitioned indexes +CREATE INDEX tbspace_reindex_part_index ON ONLY tbspace_reindex_part (c1) +-- +TABLE: name="tbspace_reindex_part" schema="" table="tbspace_reindex_part" ctx=DDL +STMT: IndexStmt +== 053 +CREATE INDEX tbspace_reindex_part_index_0 ON ONLY tbspace_reindex_part_0 (c1) +-- +TABLE: name="tbspace_reindex_part_0" schema="" table="tbspace_reindex_part_0" ctx=DDL +STMT: IndexStmt +== 054 +ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_0 +-- +STMT: AlterTableStmt +== 055 +-- This partitioned index will have no partitions. +CREATE INDEX tbspace_reindex_part_index_10 ON ONLY tbspace_reindex_part_10 (c1) +-- +TABLE: name="tbspace_reindex_part_10" schema="" table="tbspace_reindex_part_10" ctx=DDL +STMT: IndexStmt +== 056 +ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_10 +-- +STMT: AlterTableStmt +== 057 +CREATE INDEX tbspace_reindex_part_index_0_1 ON ONLY tbspace_reindex_part_0_1 (c1) +-- +TABLE: name="tbspace_reindex_part_0_1" schema="" table="tbspace_reindex_part_0_1" ctx=DDL +STMT: IndexStmt +== 058 +ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_1 +-- +STMT: AlterTableStmt +== 059 +CREATE INDEX tbspace_reindex_part_index_0_2 ON ONLY tbspace_reindex_part_0_2 (c1) +-- +TABLE: name="tbspace_reindex_part_0_2" schema="" table="tbspace_reindex_part_0_2" ctx=DDL +STMT: IndexStmt +== 060 +ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_2 +-- +STMT: AlterTableStmt +== 061 +SELECT relid, parentrelid, level FROM pg_partition_tree('tbspace_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +== 062 +-- Track the original tablespace, relfilenode and OID of each index +-- in the tree. +CREATE TEMP TABLE reindex_temp_before AS + SELECT oid, relname, relfilenode, reltablespace + FROM pg_class + WHERE relname ~ 'tbspace_reindex_part_index' +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +== 063 +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tbspace_reindex_part +-- +STMT: ReindexStmt +== 064 +-- REINDEX CONCURRENTLY changes the OID of the old relation, hence a check +-- based on the relation name below. +SELECT b.relname, + CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' + ELSE 'relfilenode has changed' END AS filenode, + CASE WHEN a.reltablespace = b.reltablespace THEN 'reltablespace is unchanged' + ELSE 'reltablespace has changed' END AS tbspace + FROM reindex_temp_before b JOIN pg_class a ON b.relname = a.relname + ORDER BY 1 +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="reindex_temp_before" +STMT: SelectStmt +== 065 +DROP TABLE tbspace_reindex_part +-- +TABLE: name="tbspace_reindex_part" schema="" table="tbspace_reindex_part" ctx=DDL +STMT: DropStmt +== 066 +-- create a schema we can use +CREATE SCHEMA testschema +-- +STMT: CreateSchemaStmt +== 067 +-- try a table +CREATE TABLE testschema.foo (i int) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DDL +STMT: CreateStmt +== 068 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'foo' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 069 +INSERT INTO testschema.foo VALUES(1) +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +INSERT INTO testschema.foo VALUES(2) +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +-- tables from dynamic sources +CREATE TABLE testschema.asselect TABLESPACE regress_tblspace AS SELECT 1 +-- +TABLE: name="testschema.asselect" schema="testschema" table="asselect" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 072 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'asselect' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 073 +PREPARE selectsource(int) AS SELECT $1 +-- +STMT: PrepareStmt +STMT: SelectStmt +== 074 +CREATE TABLE testschema.asexecute TABLESPACE regress_tblspace + AS EXECUTE selectsource(2) +-- +TABLE: name="testschema.asexecute" schema="testschema" table="asexecute" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 075 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'asexecute' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 076 +-- index +CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DDL +STMT: IndexStmt +== 077 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'foo_idx' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 078 +-- check \d output + +|-- +-- partitioned table +|-- +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a) +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: CreateStmt +== 079 +SET default_tablespace TO pg_global +-- +STMT: VariableSetStmt +== 080 +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1) +-- +TABLE: name="testschema.part_1" schema="testschema" table="part_1" ctx=DDL +STMT: CreateStmt +== 081 +RESET default_tablespace +-- +STMT: VariableSetStmt +== 082 +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1) +-- +TABLE: name="testschema.part_1" schema="testschema" table="part_1" ctx=DDL +STMT: CreateStmt +== 083 +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +== 084 +CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2) +-- +TABLE: name="testschema.part_2" schema="testschema" table="part_2" ctx=DDL +STMT: CreateStmt +== 085 +SET default_tablespace TO pg_global +-- +STMT: VariableSetStmt +== 086 +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3) +-- +TABLE: name="testschema.part_3" schema="testschema" table="part_3" ctx=DDL +STMT: CreateStmt +== 087 +ALTER TABLE testschema.part SET TABLESPACE regress_tblspace +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: AlterTableStmt +== 088 +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3) +-- +TABLE: name="testschema.part_3" schema="testschema" table="part_3" ctx=DDL +STMT: CreateStmt +== 089 +CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) + TABLESPACE pg_default +-- +TABLE: name="testschema.part_4" schema="testschema" table="part_4" ctx=DDL +STMT: CreateStmt +== 090 +CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) + PARTITION BY LIST (a) +-- +TABLE: name="testschema.part_56" schema="testschema" table="part_56" ctx=DDL +STMT: CreateStmt +== 091 +ALTER TABLE testschema.part SET TABLESPACE pg_default +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: AlterTableStmt +== 092 +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a) +-- +TABLE: name="testschema.part_78" schema="testschema" table="part_78" ctx=DDL +STMT: CreateStmt +== 093 +CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) + PARTITION BY LIST (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.part_910" schema="testschema" table="part_910" ctx=DDL +STMT: CreateStmt +== 094 +RESET default_tablespace +-- +STMT: VariableSetStmt +== 095 +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a) +-- +TABLE: name="testschema.part_78" schema="testschema" table="part_78" ctx=DDL +STMT: CreateStmt +== 096 +SELECT relname, spcname FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) + LEFT JOIN pg_catalog.pg_tablespace t ON c.reltablespace = t.oid + where c.relname LIKE 'part%' AND n.nspname = 'testschema' order by relname +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +TABLE: name="pg_catalog.pg_namespace" schema="pg_catalog" table="pg_namespace" ctx=Select +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "n"="pg_catalog.pg_namespace" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +== 097 +RESET default_tablespace +-- +STMT: VariableSetStmt +== 098 +DROP TABLE testschema.part +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: DropStmt +== 099 +-- partitioned index +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a) +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: CreateStmt +== 100 +CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1) +-- +TABLE: name="testschema.part1" schema="testschema" table="part1" ctx=DDL +STMT: CreateStmt +== 101 +CREATE INDEX part_a_idx ON testschema.part (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: IndexStmt +== 102 +CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2) +-- +TABLE: name="testschema.part2" schema="testschema" table="part2" ctx=DDL +STMT: CreateStmt +== 103 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname LIKE 'part%_idx' ORDER BY relname +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 104 +-- partitioned rels cannot specify the default tablespace. These fail: +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE pg_default +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +== 105 +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE pg_default) PARTITION BY LIST (a) +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +== 106 +SET default_tablespace TO 'pg_default' +-- +STMT: VariableSetStmt +== 107 +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +== 108 +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a) +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +== 109 +-- but these work: +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +== 110 +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +== 111 +CREATE TABLE testschema.dflt2 (a int PRIMARY KEY) PARTITION BY LIST (a) +-- +TABLE: name="testschema.dflt2" schema="testschema" table="dflt2" ctx=DDL +STMT: CreateStmt +== 112 +DROP TABLE testschema.dflt, testschema.dflt2 +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +TABLE: name="testschema.dflt2" schema="testschema" table="dflt2" ctx=DDL +STMT: DropStmt +== 113 +-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds +CREATE TABLE testschema.test_default_tab(id bigint) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: CreateStmt +== 114 +INSERT INTO testschema.test_default_tab VALUES (1) +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +CREATE INDEX test_index1 on testschema.test_default_tab (id) +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: IndexStmt +== 116 +CREATE INDEX test_index2 on testschema.test_default_tab (id) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: IndexStmt +== 117 +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index3 PRIMARY KEY (id) +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +== 118 +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +== 119 +-- use a custom tablespace for default_tablespace +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +== 120 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +== 121 +SELECT * FROM testschema.test_default_tab +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=Select +STMT: SelectStmt +== 122 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE int +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +== 123 +SELECT * FROM testschema.test_default_tab +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=Select +STMT: SelectStmt +== 124 +-- now use the default tablespace for default_tablespace +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +== 125 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE int +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +== 126 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +== 127 +DROP TABLE testschema.test_default_tab +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: DropStmt +== 128 +-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds +-- (this time with a partitioned table) +CREATE TABLE testschema.test_default_tab_p(id bigint, val bigint) + PARTITION BY LIST (id) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: CreateStmt +== 129 +CREATE TABLE testschema.test_default_tab_p1 PARTITION OF testschema.test_default_tab_p + FOR VALUES IN (1) +-- +TABLE: name="testschema.test_default_tab_p1" schema="testschema" table="test_default_tab_p1" ctx=DDL +STMT: CreateStmt +== 130 +INSERT INTO testschema.test_default_tab_p VALUES (1) +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 131 +CREATE INDEX test_index1 on testschema.test_default_tab_p (val) +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: IndexStmt +== 132 +CREATE INDEX test_index2 on testschema.test_default_tab_p (val) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: IndexStmt +== 133 +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index3 PRIMARY KEY (id) +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +== 134 +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +== 135 +-- use a custom tablespace for default_tablespace +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +== 136 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +== 137 +SELECT * FROM testschema.test_default_tab_p +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=Select +STMT: SelectStmt +== 138 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +== 139 +SELECT * FROM testschema.test_default_tab_p +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=Select +STMT: SelectStmt +== 140 +-- now use the default tablespace for default_tablespace +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +== 141 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +== 142 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +== 143 +DROP TABLE testschema.test_default_tab_p +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: DropStmt +== 144 +-- check that default_tablespace affects index additions in ALTER TABLE +CREATE TABLE testschema.test_tab(id int) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: CreateStmt +== 145 +INSERT INTO testschema.test_tab VALUES (1) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 146 +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +== 147 +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (id) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +== 148 +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +== 149 +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_pkey PRIMARY KEY (id) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +== 150 +SELECT * FROM testschema.test_tab +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=Select +STMT: SelectStmt +== 151 +DROP TABLE testschema.test_tab +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: DropStmt +== 152 +-- check that default_tablespace is handled correctly by multi-command +-- ALTER TABLE that includes a tablespace-preserving rewrite +CREATE TABLE testschema.test_tab(a int, b int, c int) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: CreateStmt +== 153 +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +== 154 +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (a) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +== 155 +CREATE INDEX test_tab_a_idx ON testschema.test_tab (a) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: IndexStmt +== 156 +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +== 157 +CREATE INDEX test_tab_b_idx ON testschema.test_tab (b) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: IndexStmt +== 158 +ALTER TABLE testschema.test_tab ALTER b TYPE bigint, ADD UNIQUE (c) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +== 159 +DROP TABLE testschema.test_tab +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: DropStmt +== 160 +-- let's try moving a table from one place to another +CREATE TABLE testschema.atable AS VALUES (1), (2) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 161 +CREATE UNIQUE INDEX anindex ON testschema.atable(column1) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DDL +STMT: IndexStmt +== 162 +ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DDL +STMT: AlterTableStmt +== 163 +ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace +-- +STMT: AlterTableStmt +== 164 +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_global +-- +STMT: AlterTableStmt +== 165 +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default +-- +STMT: AlterTableStmt +== 166 +ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace +-- +STMT: AlterTableStmt +== 167 +INSERT INTO testschema.atable VALUES(3) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +-- ok +INSERT INTO testschema.atable VALUES(1) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 169 +-- fail (checks index) +SELECT COUNT(*) FROM testschema.atable +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 170 +-- checks heap + +-- let's try moving a materialized view from one place to another +CREATE MATERIALIZED VIEW testschema.amv AS SELECT * FROM testschema.atable +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=DDL +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 171 +ALTER MATERIALIZED VIEW testschema.amv SET TABLESPACE regress_tblspace +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=DDL +STMT: AlterTableStmt +== 172 +REFRESH MATERIALIZED VIEW testschema.amv +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=DDL +STMT: RefreshMatViewStmt +== 173 +SELECT COUNT(*) FROM testschema.amv +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 174 +-- Will fail with bad path +CREATE TABLESPACE regress_badspace LOCATION '/no/such/location' +-- +STMT: CreateTableSpaceStmt +== 175 +-- No such tablespace +CREATE TABLE bar (i int) TABLESPACE regress_nosuchspace +-- +TABLE: name="bar" schema="" table="bar" ctx=DDL +STMT: CreateStmt +== 176 +-- Fail, in use for some partitioned object +DROP TABLESPACE regress_tblspace +-- +STMT: DropTableSpaceStmt +== 177 +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default +-- +STMT: AlterTableStmt +== 178 +-- Fail, not empty +DROP TABLESPACE regress_tblspace +-- +STMT: DropTableSpaceStmt +== 179 +-- Adequate cache initialization before GRANT +BEGIN +-- +STMT: TransactionStmt +== 180 +GRANT ALL ON TABLESPACE regress_tblspace TO PUBLIC +-- +STMT: GrantStmt +== 181 +ROLLBACK +-- +STMT: TransactionStmt +== 182 +CREATE ROLE regress_tablespace_user1 login +-- +STMT: CreateRoleStmt +== 183 +CREATE ROLE regress_tablespace_user2 login +-- +STMT: CreateRoleStmt +== 184 +GRANT USAGE ON SCHEMA testschema TO regress_tablespace_user2 +-- +STMT: GrantStmt +== 185 +ALTER TABLESPACE regress_tblspace OWNER TO regress_tablespace_user1 +-- +STMT: AlterOwnerStmt +== 186 +CREATE TABLE testschema.tablespace_acl (c int) +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: CreateStmt +== 187 +-- new owner lacks permission to create this index from scratch +CREATE INDEX k ON testschema.tablespace_acl (c) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: IndexStmt +== 188 +ALTER TABLE testschema.tablespace_acl OWNER TO regress_tablespace_user2 +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: AlterTableStmt +== 189 +SET SESSION ROLE regress_tablespace_user2 +-- +STMT: VariableSetStmt +== 190 +CREATE TABLE tablespace_table (i int) TABLESPACE regress_tblspace +-- +TABLE: name="tablespace_table" schema="" table="tablespace_table" ctx=DDL +STMT: CreateStmt +== 191 +-- fail +ALTER TABLE testschema.tablespace_acl ALTER c TYPE bigint +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: AlterTableStmt +== 192 +REINDEX (TABLESPACE regress_tblspace) TABLE tablespace_table +-- +STMT: ReindexStmt +== 193 +-- fail +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tablespace_table +-- +STMT: ReindexStmt +== 194 +-- fail +RESET ROLE +-- +STMT: VariableSetStmt +== 195 +ALTER TABLESPACE regress_tblspace RENAME TO regress_tblspace_renamed +-- +STMT: RenameStmt +== 196 +ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +== 197 +ALTER INDEX ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +== 198 +ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +== 199 +-- Should show notice that nothing was done +ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +== 200 +ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +== 201 +-- Should succeed +DROP TABLESPACE regress_tblspace_renamed +-- +STMT: DropTableSpaceStmt +== 202 +DROP SCHEMA testschema CASCADE +-- +STMT: DropStmt +== 203 +DROP ROLE regress_tablespace_user1 +-- +STMT: DropRoleStmt +== 204 +DROP ROLE regress_tablespace_user2 +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/temp.metadata.json b/parser/testdata/summary/postgres_regress/temp.metadata.json new file mode 100644 index 0000000..4e31a92 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/temp.metadata.json @@ -0,0 +1,166 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162" + ] +} diff --git a/parser/testdata/summary/postgres_regress/temp.test b/parser/testdata/summary/postgres_regress/temp.test new file mode 100644 index 0000000..743a826 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/temp.test @@ -0,0 +1,864 @@ +== 001 +|-- +-- TEMP +-- Test temp relations and indexes +|-- + +-- test temp table/index masking + +CREATE TABLE temptest(col int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 002 +CREATE INDEX i_temptest ON temptest(col) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: IndexStmt +== 003 +CREATE TEMP TABLE temptest(tcol int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 004 +CREATE INDEX i_temptest ON temptest(tcol) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: IndexStmt +== 005 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 006 +DROP INDEX i_temptest +-- +STMT: DropStmt +== 007 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +== 008 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 009 +DROP INDEX i_temptest +-- +STMT: DropStmt +== 010 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +== 011 +-- test temp table selects + +CREATE TABLE temptest(col int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 012 +INSERT INTO temptest VALUES (1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +CREATE TEMP TABLE temptest(tcol float) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 014 +INSERT INTO temptest VALUES (2.1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 016 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +== 017 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 018 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +== 019 +-- test temp table deletion + +CREATE TEMP TABLE temptest(col int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 020 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 021 +-- Test ON COMMIT DELETE ROWS + +CREATE TEMP TABLE temptest(col int) ON COMMIT DELETE ROWS +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 022 +-- while we're here, verify successful truncation of index with SQL function +CREATE INDEX ON temptest(bit_length('')) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +FUNCTION: name="bit_length" function="bit_length" schema="" ctx=Call +STMT: IndexStmt +== 023 +BEGIN +-- +STMT: TransactionStmt +== 024 +INSERT INTO temptest VALUES (1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO temptest VALUES (2) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 027 +COMMIT +-- +STMT: TransactionStmt +== 028 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 029 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +== 030 +BEGIN +-- +STMT: TransactionStmt +== 031 +CREATE TEMP TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1 +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 032 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 033 +COMMIT +-- +STMT: TransactionStmt +== 034 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 035 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +== 036 +-- Test ON COMMIT DROP + +BEGIN +-- +STMT: TransactionStmt +== 037 +CREATE TEMP TABLE temptest(col int) ON COMMIT DROP +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 038 +INSERT INTO temptest VALUES (1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO temptest VALUES (2) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 041 +COMMIT +-- +STMT: TransactionStmt +== 042 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 043 +BEGIN +-- +STMT: TransactionStmt +== 044 +CREATE TEMP TABLE temptest(col) ON COMMIT DROP AS SELECT 1 +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 045 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 046 +COMMIT +-- +STMT: TransactionStmt +== 047 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 048 +-- Test it with a CHECK condition that produces a toasted pg_constraint entry +BEGIN +-- +STMT: TransactionStmt +== 049 +do $$ +begin + execute format($cmd$ + CREATE TEMP TABLE temptest (col text CHECK (col < %L)) ON COMMIT DROP + $cmd$, + (SELECT string_agg(g.i::text || ':' || random()::text, '|') + FROM generate_series(1, 100) g(i))); +end$$ +-- +STMT: DoStmt +== 050 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 051 +COMMIT +-- +STMT: TransactionStmt +== 052 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 053 +-- ON COMMIT is only allowed for TEMP + +CREATE TABLE temptest(col int) ON COMMIT DELETE ROWS +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 054 +CREATE TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1 +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 055 +-- Test foreign keys +BEGIN +-- +STMT: TransactionStmt +== 056 +CREATE TEMP TABLE temptest1(col int PRIMARY KEY) +-- +TABLE: name="temptest1" schema="" table="temptest1" ctx=DDL +STMT: CreateStmt +== 057 +CREATE TEMP TABLE temptest2(col int REFERENCES temptest1) + ON COMMIT DELETE ROWS +-- +TABLE: name="temptest2" schema="" table="temptest2" ctx=DDL +STMT: CreateStmt +== 058 +INSERT INTO temptest1 VALUES (1) +-- +TABLE: name="temptest1" schema="" table="temptest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +INSERT INTO temptest2 VALUES (1) +-- +TABLE: name="temptest2" schema="" table="temptest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +COMMIT +-- +STMT: TransactionStmt +== 061 +SELECT * FROM temptest1 +-- +TABLE: name="temptest1" schema="" table="temptest1" ctx=Select +STMT: SelectStmt +== 062 +SELECT * FROM temptest2 +-- +TABLE: name="temptest2" schema="" table="temptest2" ctx=Select +STMT: SelectStmt +== 063 +BEGIN +-- +STMT: TransactionStmt +== 064 +CREATE TEMP TABLE temptest3(col int PRIMARY KEY) ON COMMIT DELETE ROWS +-- +TABLE: name="temptest3" schema="" table="temptest3" ctx=DDL +STMT: CreateStmt +== 065 +CREATE TEMP TABLE temptest4(col int REFERENCES temptest3) +-- +TABLE: name="temptest4" schema="" table="temptest4" ctx=DDL +STMT: CreateStmt +== 066 +COMMIT +-- +STMT: TransactionStmt +== 067 +-- Test manipulation of temp schema's placement in search path + +create table public.whereami (f1 text) +-- +TABLE: name="public.whereami" schema="public" table="whereami" ctx=DDL +STMT: CreateStmt +== 068 +insert into public.whereami values ('public') +-- +TABLE: name="public.whereami" schema="public" table="whereami" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +create temp table whereami (f1 text) +-- +TABLE: name="whereami" schema="" table="whereami" ctx=DDL +STMT: CreateStmt +== 070 +insert into whereami values ('temp') +-- +TABLE: name="whereami" schema="" table="whereami" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +create function public.whoami() returns text + as $$select 'public'::text$$ language sql +-- +FUNCTION: name="public.whoami" function="whoami" schema="public" ctx=DDL +STMT: CreateFunctionStmt +== 072 +create function pg_temp.whoami() returns text + as $$select 'temp'::text$$ language sql +-- +FUNCTION: name="pg_temp.whoami" function="whoami" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +== 073 +-- default should have pg_temp implicitly first, but only for tables +select * from whereami +-- +TABLE: name="whereami" schema="" table="whereami" ctx=Select +STMT: SelectStmt +== 074 +select whoami() +-- +FUNCTION: name="whoami" function="whoami" schema="" ctx=Call +STMT: SelectStmt +== 075 +-- can list temp first explicitly, but it still doesn't affect functions +set search_path = pg_temp, public +-- +STMT: VariableSetStmt +== 076 +select * from whereami +-- +TABLE: name="whereami" schema="" table="whereami" ctx=Select +STMT: SelectStmt +== 077 +select whoami() +-- +FUNCTION: name="whoami" function="whoami" schema="" ctx=Call +STMT: SelectStmt +== 078 +-- or put it last for security +set search_path = public, pg_temp +-- +STMT: VariableSetStmt +== 079 +select * from whereami +-- +TABLE: name="whereami" schema="" table="whereami" ctx=Select +STMT: SelectStmt +== 080 +select whoami() +-- +FUNCTION: name="whoami" function="whoami" schema="" ctx=Call +STMT: SelectStmt +== 081 +-- you can invoke a temp function explicitly, though +select pg_temp.whoami() +-- +FUNCTION: name="pg_temp.whoami" function="whoami" schema="pg_temp" ctx=Call +STMT: SelectStmt +== 082 +drop table public.whereami +-- +TABLE: name="public.whereami" schema="public" table="whereami" ctx=DDL +STMT: DropStmt +== 083 +-- types in temp schema +set search_path = pg_temp, public +-- +STMT: VariableSetStmt +== 084 +create domain pg_temp.nonempty as text check (value <> '') +-- +STMT: CreateDomainStmt +== 085 +-- function-syntax invocation of types matches rules for functions +select nonempty('') +-- +FUNCTION: name="nonempty" function="nonempty" schema="" ctx=Call +STMT: SelectStmt +== 086 +select pg_temp.nonempty('') +-- +FUNCTION: name="pg_temp.nonempty" function="nonempty" schema="pg_temp" ctx=Call +STMT: SelectStmt +== 087 +-- other syntax matches rules for tables +select ''::nonempty +-- +STMT: SelectStmt +== 088 +reset search_path +-- +STMT: VariableSetStmt +== 089 +-- For partitioned temp tables, ON COMMIT actions ignore storage-less +-- partitioned tables. +begin +-- +STMT: TransactionStmt +== 090 +create temp table temp_parted_oncommit (a int) + partition by list (a) on commit delete rows +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=DDL +STMT: CreateStmt +== 091 +create temp table temp_parted_oncommit_1 + partition of temp_parted_oncommit + for values in (1) on commit delete rows +-- +TABLE: name="temp_parted_oncommit_1" schema="" table="temp_parted_oncommit_1" ctx=DDL +STMT: CreateStmt +== 092 +insert into temp_parted_oncommit values (1) +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +commit +-- +STMT: TransactionStmt +== 094 +-- partitions are emptied by the previous commit +select * from temp_parted_oncommit +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=Select +STMT: SelectStmt +== 095 +drop table temp_parted_oncommit +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=DDL +STMT: DropStmt +== 096 +-- Check dependencies between ON COMMIT actions with a partitioned +-- table and its partitions. Using ON COMMIT DROP on a parent removes +-- the whole set. +begin +-- +STMT: TransactionStmt +== 097 +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit drop +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DDL +STMT: CreateStmt +== 098 +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit delete rows +-- +TABLE: name="temp_parted_oncommit_test1" schema="" table="temp_parted_oncommit_test1" ctx=DDL +STMT: CreateStmt +== 099 +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop +-- +TABLE: name="temp_parted_oncommit_test2" schema="" table="temp_parted_oncommit_test2" ctx=DDL +STMT: CreateStmt +== 100 +insert into temp_parted_oncommit_test values (1), (2) +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +commit +-- +STMT: TransactionStmt +== 102 +-- no relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 103 +-- Using ON COMMIT DELETE on a partitioned table does not remove +-- all rows if partitions preserve their data. +begin +-- +STMT: TransactionStmt +== 104 +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit delete rows +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DDL +STMT: CreateStmt +== 105 +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit preserve rows +-- +TABLE: name="temp_parted_oncommit_test1" schema="" table="temp_parted_oncommit_test1" ctx=DDL +STMT: CreateStmt +== 106 +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop +-- +TABLE: name="temp_parted_oncommit_test2" schema="" table="temp_parted_oncommit_test2" ctx=DDL +STMT: CreateStmt +== 107 +insert into temp_parted_oncommit_test values (1), (2) +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +commit +-- +STMT: TransactionStmt +== 109 +-- Data from the remaining partition is still here as its rows are +-- preserved. +select * from temp_parted_oncommit_test +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=Select +STMT: SelectStmt +== 110 +-- two relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test' + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 111 +drop table temp_parted_oncommit_test +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DDL +STMT: DropStmt +== 112 +-- Check dependencies between ON COMMIT actions with inheritance trees. +-- Using ON COMMIT DROP on a parent removes the whole set. +begin +-- +STMT: TransactionStmt +== 113 +create temp table temp_inh_oncommit_test (a int) on commit drop +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DDL +STMT: CreateStmt +== 114 +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit delete rows +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DDL +STMT: CreateStmt +== 115 +insert into temp_inh_oncommit_test1 values (1) +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 116 +commit +-- +STMT: TransactionStmt +== 117 +-- no relations remain in this case +select relname from pg_class where relname ~ '^temp_inh_oncommit_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 118 +-- Data on the parent is removed, and the child goes away. +begin +-- +STMT: TransactionStmt +== 119 +create temp table temp_inh_oncommit_test (a int) on commit delete rows +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DDL +STMT: CreateStmt +== 120 +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit drop +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DDL +STMT: CreateStmt +== 121 +insert into temp_inh_oncommit_test1 values (1) +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 122 +insert into temp_inh_oncommit_test values (1) +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 123 +commit +-- +STMT: TransactionStmt +== 124 +select * from temp_inh_oncommit_test +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=Select +STMT: SelectStmt +== 125 +-- one relation remains +select relname from pg_class where relname ~ '^temp_inh_oncommit_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 126 +drop table temp_inh_oncommit_test +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DDL +STMT: DropStmt +== 127 +-- Tests with two-phase commit +-- Transactions creating objects in a temporary namespace cannot be used +-- with two-phase commit. + +-- These cases generate errors about temporary namespace. +-- Function creation +begin +-- +STMT: TransactionStmt +== 128 +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql +-- +FUNCTION: name="pg_temp.twophase_func" function="twophase_func" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +== 129 +prepare transaction 'twophase_func' +-- +STMT: TransactionStmt +== 130 +-- Function drop +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql +-- +FUNCTION: name="pg_temp.twophase_func" function="twophase_func" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +== 131 +begin +-- +STMT: TransactionStmt +== 132 +drop function pg_temp.twophase_func() +-- +FUNCTION: name="pg_temp.twophase_func" function="twophase_func" schema="pg_temp" ctx=DDL +STMT: DropStmt +== 133 +prepare transaction 'twophase_func' +-- +STMT: TransactionStmt +== 134 +-- Operator creation +begin +-- +STMT: TransactionStmt +== 135 +create operator pg_temp.@@ (leftarg = int4, rightarg = int4, procedure = int4mi) +-- +STMT: DefineStmt +== 136 +prepare transaction 'twophase_operator' +-- +STMT: TransactionStmt +== 137 +-- These generate errors about temporary tables. +begin +-- +STMT: TransactionStmt +== 138 +create type pg_temp.twophase_type as (a int) +-- +STMT: CompositeTypeStmt +== 139 +prepare transaction 'twophase_type' +-- +STMT: TransactionStmt +== 140 +begin +-- +STMT: TransactionStmt +== 141 +create view pg_temp.twophase_view as select 1 +-- +TABLE: name="pg_temp.twophase_view" schema="pg_temp" table="twophase_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 142 +prepare transaction 'twophase_view' +-- +STMT: TransactionStmt +== 143 +begin +-- +STMT: TransactionStmt +== 144 +create sequence pg_temp.twophase_seq +-- +STMT: CreateSeqStmt +== 145 +prepare transaction 'twophase_sequence' +-- +STMT: TransactionStmt +== 146 +-- Temporary tables cannot be used with two-phase commit. +create temp table twophase_tab (a int) +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DDL +STMT: CreateStmt +== 147 +begin +-- +STMT: TransactionStmt +== 148 +select a from twophase_tab +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=Select +STMT: SelectStmt +== 149 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +== 150 +begin +-- +STMT: TransactionStmt +== 151 +insert into twophase_tab values (1) +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 152 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +== 153 +begin +-- +STMT: TransactionStmt +== 154 +lock twophase_tab in access exclusive mode +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DDL +STMT: LockStmt +== 155 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +== 156 +begin +-- +STMT: TransactionStmt +== 157 +drop table twophase_tab +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DDL +STMT: DropStmt +== 158 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +== 159 +-- Corner case: current_schema may create a temporary schema if namespace +-- creation is pending, so check after that. First reset the connection +-- to remove the temporary namespace. +SET search_path TO 'pg_temp' +-- +STMT: VariableSetStmt +== 160 +BEGIN +-- +STMT: TransactionStmt +== 161 +SELECT current_schema() ~ 'pg_temp' AS is_temp_schema +-- +FUNCTION: name="current_schema" function="current_schema" schema="" ctx=Call +STMT: SelectStmt +== 162 +PREPARE TRANSACTION 'twophase_search' +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/test_setup.metadata.json b/parser/testdata/summary/postgres_regress/test_setup.metadata.json new file mode 100644 index 0000000..abfc1a2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/test_setup.metadata.json @@ -0,0 +1,73 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069" + ] +} diff --git a/parser/testdata/summary/postgres_regress/test_setup.test b/parser/testdata/summary/postgres_regress/test_setup.test new file mode 100644 index 0000000..15cf1fe --- /dev/null +++ b/parser/testdata/summary/postgres_regress/test_setup.test @@ -0,0 +1,540 @@ +== 001 +|-- +-- TEST_SETUP --- prepare environment expected by regression test scripts +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +|-- +-- synchronous_commit=off delays when hint bits may be set. Some plans change +-- depending on the number of all-visible pages, which in turn can be +-- influenced by the delayed hint bits. Force synchronous_commit=on to avoid +-- that source of variability. +|-- +SET synchronous_commit = on +-- +STMT: VariableSetStmt +== 002 +|-- +-- Postgres formerly made the public schema read/write by default, +-- and most of the core regression tests still expect that. +|-- +GRANT ALL ON SCHEMA public TO public +-- +STMT: GrantStmt +== 003 +-- Create a tablespace we can use in tests. +SET allow_in_place_tablespaces = true +-- +STMT: VariableSetStmt +== 004 +CREATE TABLESPACE regress_tblspace LOCATION '' +-- +STMT: CreateTableSpaceStmt +== 005 +|-- +-- These tables have traditionally been referenced by many tests, +-- so create and populate them. Insert only non-error values here. +-- (Some subsequent tests try to insert erroneous values. That's okay +-- because the table won't actually change. Do not change the contents +-- of these tables in later tests, as it may affect other tests.) +|-- + +CREATE TABLE CHAR_TBL(f1 char(4)) +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: CreateStmt +== 006 +INSERT INTO CHAR_TBL (f1) VALUES + ('a'), + ('ab'), + ('abcd'), + ('abcd ') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +VACUUM CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: VacuumStmt +== 008 +CREATE TABLE FLOAT8_TBL(f1 float8) +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: CreateStmt +== 009 +INSERT INTO FLOAT8_TBL(f1) VALUES + ('0.0'), + ('-34.84'), + ('-1004.30'), + ('-1.2345678901234e+200'), + ('-1.2345678901234e-200') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +VACUUM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: VacuumStmt +== 011 +CREATE TABLE INT2_TBL(f1 int2) +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DDL +STMT: CreateStmt +== 012 +INSERT INTO INT2_TBL(f1) VALUES + ('0 '), + (' 1234 '), + (' -1234'), + ('32767'), -- largest and smallest values + ('-32767') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +VACUUM INT2_TBL +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DDL +STMT: VacuumStmt +== 014 +CREATE TABLE INT4_TBL(f1 int4) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DDL +STMT: CreateStmt +== 015 +INSERT INTO INT4_TBL(f1) VALUES + (' 0 '), + ('123456 '), + (' -123456'), + ('2147483647'), -- largest and smallest values + ('-2147483647') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +VACUUM INT4_TBL +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DDL +STMT: VacuumStmt +== 017 +CREATE TABLE INT8_TBL(q1 int8, q2 int8) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DDL +STMT: CreateStmt +== 018 +INSERT INTO INT8_TBL VALUES + (' 123 ',' 456'), + ('123 ','4567890123456789'), + ('4567890123456789','123'), + (+4567890123456789,'4567890123456789'), + ('+4567890123456789','-4567890123456789') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +VACUUM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DDL +STMT: VacuumStmt +== 020 +CREATE TABLE POINT_TBL(f1 point) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +STMT: CreateStmt +== 021 +INSERT INTO POINT_TBL(f1) VALUES + ('(0.0,0.0)'), + ('(-10.0,0.0)'), + ('(-3.0,4.0)'), + ('(5.1, 34.5)'), + ('(-5.0,-12.0)'), + ('(1e-300,-1e-300)'), -- To underflow + ('(1e+300,Inf)'), -- To overflow + ('(Inf,1e+300)'), -- Transposed + (' ( Nan , NaN ) '), + ('10.0,10.0') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +-- We intentionally don't vacuum point_tbl here; geometry depends on that + +CREATE TABLE TEXT_TBL (f1 text) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=DDL +STMT: CreateStmt +== 023 +INSERT INTO TEXT_TBL VALUES + ('doh!'), + ('hi de ho neighbor') +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +VACUUM TEXT_TBL +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=DDL +STMT: VacuumStmt +== 025 +CREATE TABLE VARCHAR_TBL(f1 varchar(4)) +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: CreateStmt +== 026 +INSERT INTO VARCHAR_TBL (f1) VALUES + ('a'), + ('ab'), + ('abcd'), + ('abcd ') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +VACUUM VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: VacuumStmt +== 028 +CREATE TABLE onek ( + unique1 int4, + unique2 int4, + two int4, + four int4, + ten int4, + twenty int4, + hundred int4, + thousand int4, + twothousand int4, + fivethous int4, + tenthous int4, + odd int4, + even int4, + stringu1 name, + stringu2 name, + string4 name +) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: CreateStmt +== 029 +COPY onek FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 030 +VACUUM ANALYZE onek +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: VacuumStmt +== 031 +CREATE TABLE onek2 AS SELECT * FROM onek +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 032 +VACUUM ANALYZE onek2 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: VacuumStmt +== 033 +CREATE TABLE tenk1 ( + unique1 int4, + unique2 int4, + two int4, + four int4, + ten int4, + twenty int4, + hundred int4, + thousand int4, + twothousand int4, + fivethous int4, + tenthous int4, + odd int4, + even int4, + stringu1 name, + stringu2 name, + string4 name +) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: CreateStmt +== 034 +COPY tenk1 FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 17 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 035 +VACUUM ANALYZE tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: VacuumStmt +== 036 +CREATE TABLE tenk2 AS SELECT * FROM tenk1 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 037 +VACUUM ANALYZE tenk2 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: VacuumStmt +== 038 +CREATE TABLE person ( + name text, + age int4, + location point +) +-- +TABLE: name="person" schema="" table="person" ctx=DDL +STMT: CreateStmt +== 039 +COPY person FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 18 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 040 +VACUUM ANALYZE person +-- +TABLE: name="person" schema="" table="person" ctx=DDL +STMT: VacuumStmt +== 041 +CREATE TABLE emp ( + salary int4, + manager name +) INHERITS (person) +-- +TABLE: name="emp" schema="" table="emp" ctx=DDL +STMT: CreateStmt +== 042 +COPY emp FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 043 +VACUUM ANALYZE emp +-- +TABLE: name="emp" schema="" table="emp" ctx=DDL +STMT: VacuumStmt +== 044 +CREATE TABLE student ( + gpa float8 +) INHERITS (person) +-- +TABLE: name="student" schema="" table="student" ctx=DDL +STMT: CreateStmt +== 045 +COPY student FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 046 +VACUUM ANALYZE student +-- +TABLE: name="student" schema="" table="student" ctx=DDL +STMT: VacuumStmt +== 047 +CREATE TABLE stud_emp ( + percent int4 +) INHERITS (emp, student) +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: CreateStmt +== 048 +COPY stud_emp FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 049 +VACUUM ANALYZE stud_emp +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: VacuumStmt +== 050 +CREATE TABLE road ( + name text, + thepath path +) +-- +TABLE: name="road" schema="" table="road" ctx=DDL +STMT: CreateStmt +== 051 +COPY road FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 052 +VACUUM ANALYZE road +-- +TABLE: name="road" schema="" table="road" ctx=DDL +STMT: VacuumStmt +== 053 +CREATE TABLE ihighway () INHERITS (road) +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DDL +STMT: CreateStmt +== 054 +INSERT INTO ihighway + SELECT * + FROM ONLY road + WHERE name ~ 'I- .*' +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DML +TABLE: name="road" schema="" table="road" ctx=Select +FILTER: schema="" table="" column="name" +STMT: InsertStmt +STMT: SelectStmt +== 055 +VACUUM ANALYZE ihighway +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DDL +STMT: VacuumStmt +== 056 +CREATE TABLE shighway ( + surface text +) INHERITS (road) +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DDL +STMT: CreateStmt +== 057 +INSERT INTO shighway + SELECT *, 'asphalt' + FROM ONLY road + WHERE name ~ 'State Hwy.*' +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DML +TABLE: name="road" schema="" table="road" ctx=Select +FILTER: schema="" table="" column="name" +STMT: InsertStmt +STMT: SelectStmt +== 058 +VACUUM ANALYZE shighway +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DDL +STMT: VacuumStmt +== 059 +|-- +-- We must have some enum type in the database for opr_sanity and type_sanity. +|-- + +create type stoplight as enum ('red', 'yellow', 'green') +-- +STMT: CreateEnumStmt +== 060 +|-- +-- Also create some non-built-in range types. +|-- + +create type float8range as range (subtype = float8, subtype_diff = float8mi) +-- +STMT: CreateRangeStmt +== 061 +create type textrange as range (subtype = text, collation = "C") +-- +STMT: CreateRangeStmt +== 062 +|-- +-- Create some C functions that will be used by various tests. +|-- + +CREATE FUNCTION binary_coercible(oid, oid) + RETURNS bool + AS :'regresslib', 'binary_coercible' + LANGUAGE C STRICT STABLE PARALLEL SAFE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 138 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 063 +CREATE FUNCTION ttdummy () + RETURNS trigger + AS :'regresslib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 55 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 064 +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different machines. The hash function for int4 simply returns +-- the sum of the values passed to it and the one for text returns the length +-- of the non-empty string value passed to it or 0. + +create function part_hashint4_noop(value int4, seed int8) + returns int8 as $$ + select value + seed; + $$ language sql strict immutable parallel safe +-- +FUNCTION: name="part_hashint4_noop" function="part_hashint4_noop" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 065 +create operator class part_test_int4_ops for type int4 using hash as + operator 1 =, + function 2 part_hashint4_noop(int4, int8) +-- +STMT: CreateOpClassStmt +== 066 +create function part_hashtext_length(value text, seed int8) + returns int8 as $$ + select length(coalesce(value, ''))::int8 + $$ language sql strict immutable parallel safe +-- +FUNCTION: name="part_hashtext_length" function="part_hashtext_length" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 067 +create operator class part_test_text_ops for type text using hash as + operator 1 =, + function 2 part_hashtext_length(text, int8) +-- +STMT: CreateOpClassStmt +== 068 +|-- +-- These functions are used in tests that used to use md5(), which we now +-- mostly avoid so that the tests will pass in FIPS mode. +|-- + +create function fipshash(bytea) + returns text + strict immutable parallel safe leakproof + return substr(encode(sha256($1), 'hex'), 1, 32) +-- +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 069 +create function fipshash(text) + returns text + strict immutable parallel safe leakproof + return substr(encode(sha256($1::bytea), 'hex'), 1, 32) +-- +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=DDL +STMT: CreateFunctionStmt diff --git a/parser/testdata/summary/postgres_regress/text.metadata.json b/parser/testdata/summary/postgres_regress/text.metadata.json new file mode 100644 index 0000000..2ff9db8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/text.metadata.json @@ -0,0 +1,77 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073" + ] +} diff --git a/parser/testdata/summary/postgres_regress/text.test b/parser/testdata/summary/postgres_regress/text.test new file mode 100644 index 0000000..e896162 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/text.test @@ -0,0 +1,401 @@ +== 001 +|-- +-- TEXT +|-- + +SELECT text 'this is a text string' = text 'this is a text string' AS true +-- +STMT: SelectStmt +== 002 +SELECT text 'this is a text string' = text 'this is a text strin' AS false +-- +STMT: SelectStmt +== 003 +-- text_tbl was already created and filled in test_setup.sql. +SELECT * FROM TEXT_TBL +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +STMT: SelectStmt +== 004 +-- As of 8.3 we have removed most implicit casts to text, so that for example +-- this no longer works: + +select length(42) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 005 +-- But as a special exception for usability's sake, we still allow implicit +-- casting to text in concatenations, so long as the other input is text or +-- an unknown literal. So these work: + +select 'four: '::text || 2+2 +-- +STMT: SelectStmt +== 006 +select 'four: ' || 2+2 +-- +STMT: SelectStmt +== 007 +-- but not this: + +select 3 || 4.0 +-- +STMT: SelectStmt +== 008 +/* + * various string functions + */ +select concat('one') +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 009 +select concat(1,2,3,'hello',true, false, to_date('20100309','YYYYMMDD')) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 010 +select concat_ws('#','one') +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +== 011 +select concat_ws('#',1,2,3,'hello',true, false, to_date('20100309','YYYYMMDD')) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +== 012 +select concat_ws(',',10,20,null,30) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +== 013 +select concat_ws('',10,20,null,30) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +== 014 +select concat_ws(NULL,10,20,null,30) is null +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +== 015 +select reverse('abcde') +-- +FUNCTION: name="reverse" function="reverse" schema="" ctx=Call +STMT: SelectStmt +== 016 +select i, left('ahoj', i), right('ahoj', i) from generate_series(-5, 5) t(i) order by i +-- +FUNCTION: name="left" function="left" schema="" ctx=Call +FUNCTION: name="right" function="right" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 017 +select quote_literal('') +-- +FUNCTION: name="quote_literal" function="quote_literal" schema="" ctx=Call +STMT: SelectStmt +== 018 +select quote_literal('abc''') +-- +FUNCTION: name="quote_literal" function="quote_literal" schema="" ctx=Call +STMT: SelectStmt +== 019 +select quote_literal(e'\\') +-- +FUNCTION: name="quote_literal" function="quote_literal" schema="" ctx=Call +STMT: SelectStmt +== 020 +-- check variadic labeled argument +select concat(variadic array[1,2,3]) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 021 +select concat_ws(',', variadic array[1,2,3]) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +== 022 +select concat_ws(',', variadic NULL::int[]) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +== 023 +select concat(variadic NULL::int[]) is NULL +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 024 +select concat(variadic '{}'::int[]) = '' +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +== 025 +--should fail +select concat_ws(',', variadic 10) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +== 026 +/* + * format + */ +select format(NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 027 +select format('Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 028 +select format('Hello %s', 'World') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 029 +select format('Hello %%') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 030 +select format('Hello %%%%') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- should fail +select format('Hello %s %s', 'World') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 032 +select format('Hello %s') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 033 +select format('Hello %x', 20) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 034 +-- check literal and sql identifiers +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 035 +select format('%s%s%s','Hello', NULL,'World') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 036 +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 037 +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', NULL, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 038 +-- should fail, sql identifier cannot be NULL +select format('INSERT INTO %I VALUES(%L,%L)', NULL, 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 039 +-- check positional placeholders +select format('%1$s %3$s', 1, 2, 3) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 040 +select format('%1$s %12$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- should fail +select format('%1$s %4$s', 1, 2, 3) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 042 +select format('%1$s %13$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 043 +select format('%0$s', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 044 +select format('%*0$s', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 045 +select format('%1$', 1) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 046 +select format('%1$1', 1) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- check mix of positional and ordered placeholders +select format('Hello %s %1$s %s', 'World', 'Hello again') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 048 +select format('Hello %s %s, %2$s %2$s', 'World', 'Hello again') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 049 +-- check variadic labeled arguments +select format('%s, %s', variadic array['Hello','World']) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 050 +select format('%s, %s', variadic array[1, 2]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 051 +select format('%s, %s', variadic array[true, false]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 052 +select format('%s, %s', variadic array[true, false]::text[]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 053 +-- check variadic with positional placeholders +select format('%2$s, %1$s', variadic array['first', 'second']) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 054 +select format('%2$s, %1$s', variadic array[1, 2]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 055 +-- variadic argument can be array type NULL, but should not be referenced +select format('Hello', variadic NULL::int[]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- variadic argument allows simulating more than FUNC_MAX_ARGS parameters +select format(string_agg('%s',','), variadic array_agg(i)) +from generate_series(1,200) g(i) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- check field widths and left, right alignment +select format('>>%10s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 058 +select format('>>%10s<<', NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 059 +select format('>>%10s<<', '') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 060 +select format('>>%-10s<<', '') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 061 +select format('>>%-10s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 062 +select format('>>%-10s<<', NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 063 +select format('>>%1$10s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 064 +select format('>>%1$-10I<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 065 +select format('>>%2$*1$L<<', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 066 +select format('>>%2$*1$L<<', 10, NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 067 +select format('>>%2$*1$L<<', -10, NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 068 +select format('>>%*s<<', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 069 +select format('>>%*1$s<<', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 070 +select format('>>%-s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 071 +select format('>>%10L<<', NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 072 +select format('>>%2$*1$L<<', NULL, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +== 073 +select format('>>%2$*1$L<<', 0, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/tid.metadata.json b/parser/testdata/summary/postgres_regress/tid.metadata.json new file mode 100644 index 0000000..66f0b1d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tid.metadata.json @@ -0,0 +1,45 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tid.test b/parser/testdata/summary/postgres_regress/tid.test new file mode 100644 index 0000000..113959f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tid.test @@ -0,0 +1,239 @@ +== 001 +-- basic tests for the TID data type + +SELECT + '(0,0)'::tid as tid00, + '(0,1)'::tid as tid01, + '(-1,0)'::tid as tidm10, + '(4294967295,65535)'::tid as tidmax +-- +STMT: SelectStmt +== 002 +SELECT '(4294967296,1)'::tid +-- +STMT: SelectStmt +== 003 +-- error +SELECT '(1,65536)'::tid +-- +STMT: SelectStmt +== 004 +-- error + +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('(0)', 'tid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT * FROM pg_input_error_info('(0)', 'tid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT pg_input_is_valid('(0,-1)', 'tid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT * FROM pg_input_error_info('(0,-1)', 'tid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- tests for functions related to TID handling + +CREATE TABLE tid_tab (a int) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: CreateStmt +== 009 +-- min() and max() for TIDs +INSERT INTO tid_tab VALUES (1), (2) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +SELECT min(ctid) FROM tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT max(ctid) FROM tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 012 +TRUNCATE tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: TruncateStmt +== 013 +-- Tests for currtid2() with various relation kinds + +-- Materialized view +CREATE MATERIALIZED VIEW tid_matview AS SELECT a FROM tid_tab +-- +TABLE: name="tid_matview" schema="" table="tid_matview" ctx=DDL +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 014 +SELECT currtid2('tid_matview'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 015 +-- fails +INSERT INTO tid_tab VALUES (1) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +REFRESH MATERIALIZED VIEW tid_matview +-- +TABLE: name="tid_matview" schema="" table="tid_matview" ctx=DDL +STMT: RefreshMatViewStmt +== 017 +SELECT currtid2('tid_matview'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- ok +DROP MATERIALIZED VIEW tid_matview +-- +STMT: DropStmt +== 019 +TRUNCATE tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: TruncateStmt +== 020 +-- Sequence +CREATE SEQUENCE tid_seq +-- +STMT: CreateSeqStmt +== 021 +SELECT currtid2('tid_seq'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- ok +DROP SEQUENCE tid_seq +-- +STMT: DropStmt +== 023 +-- Index, fails with incorrect relation type +CREATE INDEX tid_ind ON tid_tab(a) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: IndexStmt +== 024 +SELECT currtid2('tid_ind'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 025 +-- fails +DROP INDEX tid_ind +-- +STMT: DropStmt +== 026 +-- Partitioned table, no storage +CREATE TABLE tid_part (a int) PARTITION BY RANGE (a) +-- +TABLE: name="tid_part" schema="" table="tid_part" ctx=DDL +STMT: CreateStmt +== 027 +SELECT currtid2('tid_part'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 028 +-- fails +DROP TABLE tid_part +-- +TABLE: name="tid_part" schema="" table="tid_part" ctx=DDL +STMT: DropStmt +== 029 +-- Views +-- ctid not defined in the view +CREATE VIEW tid_view_no_ctid AS SELECT a FROM tid_tab +-- +TABLE: name="tid_view_no_ctid" schema="" table="tid_view_no_ctid" ctx=DDL +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 030 +SELECT currtid2('tid_view_no_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- fails +DROP VIEW tid_view_no_ctid +-- +STMT: DropStmt +== 032 +-- ctid fetched directly from the source table. +CREATE VIEW tid_view_with_ctid AS SELECT ctid, a FROM tid_tab +-- +TABLE: name="tid_view_with_ctid" schema="" table="tid_view_with_ctid" ctx=DDL +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 033 +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 034 +-- fails +INSERT INTO tid_tab VALUES (1) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- ok +DROP VIEW tid_view_with_ctid +-- +STMT: DropStmt +== 037 +TRUNCATE tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: TruncateStmt +== 038 +-- ctid attribute with incorrect data type +CREATE VIEW tid_view_fake_ctid AS SELECT 1 AS ctid, 2 AS a +-- +TABLE: name="tid_view_fake_ctid" schema="" table="tid_view_fake_ctid" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 039 +SELECT currtid2('tid_view_fake_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +== 040 +-- fails +DROP VIEW tid_view_fake_ctid +-- +STMT: DropStmt +== 041 +DROP TABLE tid_tab CASCADE +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/tidrangescan.metadata.json b/parser/testdata/summary/postgres_regress/tidrangescan.metadata.json new file mode 100644 index 0000000..f069709 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tidrangescan.metadata.json @@ -0,0 +1,49 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tidrangescan.test b/parser/testdata/summary/postgres_regress/tidrangescan.test new file mode 100644 index 0000000..f419912 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tidrangescan.test @@ -0,0 +1,312 @@ +== 001 +-- tests for tidrangescans + +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +== 002 +CREATE TABLE tidrangescan(id integer, data text) +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DDL +STMT: CreateStmt +== 003 +-- empty table +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 004 +SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 005 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 006 +SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 007 +-- insert enough tuples to fill at least two pages +INSERT INTO tidrangescan SELECT i,repeat('x', 100) FROM generate_series(1,200) AS s(i) +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- remove all tuples after the 10th tuple on each page. Trying to ensure +-- we get the same layout with all CPU architectures and smaller than standard +-- page sizes. +DELETE FROM tidrangescan +WHERE substring(ctid::text FROM ',(\d+)\)')::integer > 10 OR substring(ctid::text FROM '\((\d+),')::integer > 2 +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DML +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: DeleteStmt +== 009 +VACUUM tidrangescan +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DDL +STMT: VacuumStmt +== 010 +-- range scans with upper bound +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 011 +SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 012 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 013 +SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 014 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 015 +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 016 +-- range scans with lower bound +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 017 +SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 018 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 019 +SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 020 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 021 +SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 022 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 023 +SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 024 +-- range scans with both bounds +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 025 +SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 026 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 027 +SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 028 +-- extreme offsets +SELECT ctid FROM tidrangescan WHERE ctid > '(0,65535)' AND ctid < '(1,0)' LIMIT 1 +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 029 +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' LIMIT 1 +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 030 +SELECT ctid FROM tidrangescan WHERE ctid > '(4294967295,65535)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 031 +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 032 +-- NULLs in the range cannot return tuples +SELECT ctid FROM tidrangescan WHERE ctid >= (SELECT NULL::tid) +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 033 +-- rescans +EXPLAIN (COSTS OFF) +SELECT t.ctid,t2.c FROM tidrangescan t, +LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2 +WHERE t.ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +ALIAS: "t"="tidrangescan" +ALIAS: "t2"="tidrangescan" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t" column="ctid" +FILTER: schema="" table="t2" column="ctid" +FILTER: schema="" table="t" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 034 +SELECT t.ctid,t2.c FROM tidrangescan t, +LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2 +WHERE t.ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +ALIAS: "t"="tidrangescan" +ALIAS: "t2"="tidrangescan" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t" column="ctid" +FILTER: schema="" table="t2" column="ctid" +FILTER: schema="" table="t" column="ctid" +STMT: SelectStmt +== 035 +-- cursors + +-- Ensure we get a TID Range scan without a Materialize node. +EXPLAIN (COSTS OFF) +DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +== 036 +BEGIN +-- +STMT: TransactionStmt +== 037 +DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +STMT: DeclareCursorStmt +== 038 +FETCH NEXT c +-- +STMT: FetchStmt +== 039 +FETCH NEXT c +-- +STMT: FetchStmt +== 040 +FETCH PRIOR c +-- +STMT: FetchStmt +== 041 +FETCH FIRST c +-- +STMT: FetchStmt +== 042 +FETCH LAST c +-- +STMT: FetchStmt +== 043 +COMMIT +-- +STMT: TransactionStmt +== 044 +DROP TABLE tidrangescan +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DDL +STMT: DropStmt +== 045 +RESET enable_seqscan +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/tidscan.metadata.json b/parser/testdata/summary/postgres_regress/tidscan.metadata.json new file mode 100644 index 0000000..74725a7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tidscan.metadata.json @@ -0,0 +1,53 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tidscan.test b/parser/testdata/summary/postgres_regress/tidscan.test new file mode 100644 index 0000000..5ef5ba4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tidscan.test @@ -0,0 +1,340 @@ +== 001 +-- tests for tidscans + +CREATE TABLE tidscan(id integer) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DDL +STMT: CreateStmt +== 002 +-- only insert a few rows, we don't want to spill onto a second table page +INSERT INTO tidscan VALUES (1), (2), (3) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +-- show ctids +SELECT ctid, * FROM tidscan +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +STMT: SelectStmt +== 004 +-- ctid equality - implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)' +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 005 +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)' +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 006 +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 007 +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 008 +-- OR'd clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 009 +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 010 +-- ctid = ScalarArrayOp - implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 011 +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 012 +-- ctid != ScalarArrayOp - can't be implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +== 013 +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 014 +-- tid equality extracted from sub-AND clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="id" +STMT: ExplainStmt +STMT: SelectStmt +== 015 +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 016 +-- nestloop-with-inner-tidscan joins on tid +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +== 017 +-- otherwise hash join might win +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: ExplainStmt +STMT: SelectStmt +== 018 +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: SelectStmt +== 019 +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: ExplainStmt +STMT: SelectStmt +== 020 +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: SelectStmt +== 021 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 022 +-- exercise backward scan and rewind +BEGIN +-- +STMT: TransactionStmt +== 023 +DECLARE c CURSOR FOR +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +STMT: DeclareCursorStmt +== 024 +FETCH ALL FROM c +-- +STMT: FetchStmt +== 025 +FETCH BACKWARD 1 FROM c +-- +STMT: FetchStmt +== 026 +FETCH FIRST FROM c +-- +STMT: FetchStmt +== 027 +ROLLBACK +-- +STMT: TransactionStmt +== 028 +-- tidscan via CURRENT OF +BEGIN +-- +STMT: TransactionStmt +== 029 +DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan +-- +STMT: DeclareCursorStmt +== 030 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 031 +-- skip one row +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 032 +-- perform update +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING * +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 033 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 034 +-- perform update +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING * +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 035 +SELECT * FROM tidscan +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +STMT: SelectStmt +== 036 +-- position cursor past any rows +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 037 +-- should error out +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING * +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 038 +ROLLBACK +-- +STMT: TransactionStmt +== 039 +-- bulk joins on CTID +-- (these plans don't use TID scans, but this still seems like an +-- appropriate place for these tests) +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 040 +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 041 +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +== 042 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 043 +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 044 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +== 045 +-- check predicate lock on CTID +BEGIN ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +== 046 +SELECT * FROM tidscan WHERE ctid = '(0,1)' +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +== 047 +-- locktype should be 'tuple' +SELECT locktype, mode FROM pg_locks WHERE pid = pg_backend_pid() AND mode = 'SIReadLock' +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +== 048 +ROLLBACK +-- +STMT: TransactionStmt +== 049 +DROP TABLE tidscan +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/time.metadata.json b/parser/testdata/summary/postgres_regress/time.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/time.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary/postgres_regress/time.test b/parser/testdata/summary/postgres_regress/time.test new file mode 100644 index 0000000..0cdbc87 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/time.test @@ -0,0 +1,260 @@ +== 001 +|-- +-- TIME +|-- + +CREATE TABLE TIME_TBL (f1 time(2)) +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO TIME_TBL VALUES ('00:00') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO TIME_TBL VALUES ('01:00') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +-- as of 7.4, timezone spec should be accepted and ignored +INSERT INTO TIME_TBL VALUES ('02:03 PST') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO TIME_TBL VALUES ('11:59 EDT') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO TIME_TBL VALUES ('12:00') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO TIME_TBL VALUES ('12:01') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO TIME_TBL VALUES ('23:59') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO TIME_TBL VALUES ('11:59:59.99 PM') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO TIME_TBL VALUES ('2003-03-07 15:36:39 America/New_York') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO TIME_TBL VALUES ('2003-07-07 15:36:39 America/New_York') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +-- this should fail (the timezone offset is not known) +INSERT INTO TIME_TBL VALUES ('15:36:39 America/New_York') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +SELECT f1 AS "Time" FROM TIME_TBL +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +STMT: SelectStmt +== 014 +SELECT f1 AS "Three" FROM TIME_TBL WHERE f1 < '05:06:07' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 015 +SELECT f1 AS "Five" FROM TIME_TBL WHERE f1 > '05:06:07' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 016 +SELECT f1 AS "None" FROM TIME_TBL WHERE f1 < '00:00' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 017 +SELECT f1 AS "Eight" FROM TIME_TBL WHERE f1 >= '00:00' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 018 +-- Check edge cases +SELECT '23:59:59.999999'::time +-- +STMT: SelectStmt +== 019 +SELECT '23:59:59.9999999'::time +-- +STMT: SelectStmt +== 020 +-- rounds up +SELECT '23:59:60'::time +-- +STMT: SelectStmt +== 021 +-- rounds up +SELECT '24:00:00'::time +-- +STMT: SelectStmt +== 022 +-- allowed +SELECT '24:00:00.01'::time +-- +STMT: SelectStmt +== 023 +-- not allowed +SELECT '23:59:60.01'::time +-- +STMT: SelectStmt +== 024 +-- not allowed +SELECT '24:01:00'::time +-- +STMT: SelectStmt +== 025 +-- not allowed +SELECT '25:00:00'::time +-- +STMT: SelectStmt +== 026 +-- not allowed + +-- Test non-error-throwing API +SELECT pg_input_is_valid('12:00:00', 'time') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT pg_input_is_valid('25:00:00', 'time') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT pg_input_is_valid('15:36:39 America/New_York', 'time') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT * FROM pg_input_error_info('25:00:00', 'time') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'time') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 031 +|-- +-- TIME simple math +|-- +-- We now make a distinction between time and intervals, +-- and adding two times together makes no sense at all. +-- Leave in one query to show that it is rejected, +-- and do the rest of the testing in horology.sql +-- where we do mixed-type arithmetic. - thomas 2000-12-02 + +SELECT f1 + time '00:01' AS "Illegal" FROM TIME_TBL +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +STMT: SelectStmt +== 032 +|-- +-- test EXTRACT +|-- +SELECT EXTRACT(MICROSECOND FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 033 +SELECT EXTRACT(MILLISECOND FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 034 +SELECT EXTRACT(SECOND FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 035 +SELECT EXTRACT(MINUTE FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 036 +SELECT EXTRACT(HOUR FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 037 +SELECT EXTRACT(DAY FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 038 +-- error +SELECT EXTRACT(FORTNIGHT FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 039 +-- error +SELECT EXTRACT(TIMEZONE FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 040 +-- error +SELECT EXTRACT(EPOCH FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 041 +-- date_part implementation is mostly the same as extract, so only +-- test a few cases for additional coverage. +SELECT date_part('microsecond', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 042 +SELECT date_part('millisecond', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT date_part('second', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT date_part('epoch', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/timestamp.metadata.json b/parser/testdata/summary/postgres_regress/timestamp.metadata.json new file mode 100644 index 0000000..91e3e07 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/timestamp.metadata.json @@ -0,0 +1,175 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171" + ] +} diff --git a/parser/testdata/summary/postgres_regress/timestamp.test b/parser/testdata/summary/postgres_regress/timestamp.test new file mode 100644 index 0000000..f3349aa --- /dev/null +++ b/parser/testdata/summary/postgres_regress/timestamp.test @@ -0,0 +1,1164 @@ +== 001 +|-- +-- TIMESTAMP +|-- + +CREATE TABLE TIMESTAMP_TBL (d1 timestamp(2) without time zone) +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DDL +STMT: CreateStmt +== 002 +-- Test shorthand input values +-- We can't just "select" the results since they aren't constants; test for +-- equality instead. We can do that by running the test inside a transaction +-- block, within which the value of 'now' shouldn't change, and so these +-- related values shouldn't either. + +BEGIN +-- +STMT: TransactionStmt +== 003 +INSERT INTO TIMESTAMP_TBL VALUES ('today') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO TIMESTAMP_TBL VALUES ('yesterday') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +-- time zone should be ignored by this data type +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow EST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow zulu') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +SELECT count(*) AS One FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'today' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 009 +SELECT count(*) AS Three FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'tomorrow' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 010 +SELECT count(*) AS One FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'yesterday' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 011 +COMMIT +-- +STMT: TransactionStmt +== 012 +DELETE FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: DeleteStmt +== 013 +-- Verify that 'now' *does* change over a reasonable interval such as 100 msec, +-- and that it doesn't change over the same interval within a transaction block + +INSERT INTO TIMESTAMP_TBL VALUES ('now') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 015 +BEGIN +-- +STMT: TransactionStmt +== 016 +INSERT INTO TIMESTAMP_TBL VALUES ('now') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 018 +INSERT INTO TIMESTAMP_TBL VALUES ('now') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT count(*) AS two FROM TIMESTAMP_TBL WHERE d1 = timestamp(2) without time zone 'now' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 021 +SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 022 +COMMIT +-- +STMT: TransactionStmt +== 023 +TRUNCATE TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DDL +STMT: TruncateStmt +== 024 +-- Special values +INSERT INTO TIMESTAMP_TBL VALUES ('-infinity') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO TIMESTAMP_TBL VALUES ('infinity') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO TIMESTAMP_TBL VALUES ('epoch') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +SELECT timestamp 'infinity' = timestamp '+infinity' AS t +-- +STMT: SelectStmt +== 028 +-- Postgres v6.0 standard output format +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +-- Variations on Postgres v6.1 standard output format +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.4 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.5 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.6 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +-- ISO 8601 format +INSERT INTO TIMESTAMP_TBL VALUES ('1997-01-02') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-01-02 03:04:05') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01-08') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01-0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01 -08:00') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 -0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 17:32:01 -07:00') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO TIMESTAMP_TBL VALUES ('2001-09-22T18:19:20') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +-- POSIX format (note that the timezone abbrev is just decoration here) +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 08:14:01 GMT+8') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 13:14:02 GMT-1') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 12:14:03 GMT-2') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 03:14:04 PST+8') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 02:14:05 MST+7:00') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +-- Variations for acceptable input formats +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997 -0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 5:32PM 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO TIMESTAMP_TBL VALUES ('1997/02/10 17:32:01-0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb-10-1997 17:32:01 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO TIMESTAMP_TBL VALUES ('02-10-1997 17:32:01 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +set datestyle to ymd +-- +STMT: VariableSetStmt +== 056 +INSERT INTO TIMESTAMP_TBL VALUES ('97FEB10 5:32:01PM UTC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +INSERT INTO TIMESTAMP_TBL VALUES ('97/02/10 17:32:01 UTC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +reset datestyle +-- +STMT: VariableSetStmt +== 059 +INSERT INTO TIMESTAMP_TBL VALUES ('1997.041 17:32:01 UTC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 America/New_York') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 061 +-- this fails (even though TZ is a no-op, we still look it up) +INSERT INTO TIMESTAMP_TBL VALUES ('19970710 173201 America/Does_not_exist') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +-- Test non-error-throwing API +SELECT pg_input_is_valid('now', 'timestamp') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT pg_input_is_valid('garbage', 'timestamp') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT * FROM pg_input_error_info('garbage', 'timestamp') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 067 +-- Check date conversion and date arithmetic +INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 18:32:01 PDT') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 068 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 11 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 12 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 13 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 072 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 14 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 073 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 15 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 074 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0097 BC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0597') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1697') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1797') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1897') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 2097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 084 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 085 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 086 +INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 091 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1999') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2000') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 2000') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2001') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +-- Currently unsupported syntax and ranges +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 -0097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 5097 BC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +SELECT d1 FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +== 102 +-- Check behavior at the boundaries of the timestamp range +SELECT '4714-11-24 00:00:00 BC'::timestamp +-- +STMT: SelectStmt +== 103 +SELECT '4714-11-23 23:59:59 BC'::timestamp +-- +STMT: SelectStmt +== 104 +-- out of range +SELECT '294276-12-31 23:59:59'::timestamp +-- +STMT: SelectStmt +== 105 +SELECT '294277-01-01 00:00:00'::timestamp +-- +STMT: SelectStmt +== 106 +-- out of range + +-- Demonstrate functions and operators +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 > timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 107 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 < timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 108 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 = timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 109 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 != timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 110 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 <= timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 111 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 >= timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 112 +SELECT d1 - timestamp without time zone '1997-01-02' AS diff + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 113 +SELECT date_trunc( 'week', timestamp '2004-02-29 15:44:17.71393' ) AS week_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 114 +-- verify date_bin behaves the same as date_trunc for relevant intervals + +-- case 1: AD dates, origin < input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2001-01-01') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '2020-02-29 15:44:17.71393')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 115 +-- case 2: BC dates, origin < input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2000-01-01 BC') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '0055-6-10 15:44:17.71393 BC')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 116 +-- case 3: AD dates, origin > input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2020-03-02') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '2020-02-29 15:44:17.71393')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 117 +-- case 4: BC dates, origin > input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '0055-06-17 BC') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '0055-6-10 15:44:17.71393 BC')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 118 +-- bin timestamps into arbitrary intervals +SELECT + interval, + ts, + origin, + date_bin(interval::interval, ts, origin) +FROM ( + VALUES + ('15 days'), + ('2 hours'), + ('1 hour 30 minutes'), + ('15 minutes'), + ('10 seconds'), + ('100 milliseconds'), + ('250 microseconds') +) intervals (interval), +(VALUES (timestamp '2020-02-11 15:44:17.71393')) ts (ts), +(VALUES (timestamp '2001-01-01')) origin (origin) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 119 +-- shift bins using the origin parameter: +SELECT date_bin('5 min'::interval, timestamp '2020-02-01 01:01:01', timestamp '2020-02-01 00:02:30') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 120 +-- test roundoff edge case when source < origin +SELECT date_bin('30 minutes'::interval, timestamp '2024-02-01 15:00:00', timestamp '2024-02-01 17:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 121 +-- disallow intervals with months or years +SELECT date_bin('5 months'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 122 +SELECT date_bin('5 years'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 123 +-- disallow zero intervals +SELECT date_bin('0 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 124 +-- disallow negative intervals +SELECT date_bin('-2 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 125 +-- test overflow cases +select date_bin('15 minutes'::interval, timestamp '294276-12-30', timestamp '4000-12-20 BC') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 126 +select date_bin('200000000 days'::interval, '2024-02-01'::timestamp, '2024-01-01'::timestamp) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 127 +select date_bin('365000 days'::interval, '4400-01-01 BC'::timestamp, '4000-01-01 BC'::timestamp) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 128 +-- Test casting within a BETWEEN qualifier +SELECT d1 - timestamp without time zone '1997-01-02' AS diff + FROM TIMESTAMP_TBL + WHERE d1 BETWEEN timestamp without time zone '1902-01-01' + AND timestamp without time zone '2038-01-01' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 129 +-- DATE_PART (timestamp_part) +SELECT d1 as "timestamp", + date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, + date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, + date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 130 +SELECT d1 as "timestamp", + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 131 +SELECT d1 as "timestamp", + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow, + date_part( 'doy', d1) AS doy + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 132 +SELECT d1 as "timestamp", + date_part( 'decade', d1) AS decade, + date_part( 'century', d1) AS century, + date_part( 'millennium', d1) AS millennium, + round(date_part( 'julian', d1)) AS julian, + date_part( 'epoch', d1) AS epoch + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 133 +-- extract implementation is mostly the same as date_part, so only +-- test a few cases for additional coverage. +SELECT d1 as "timestamp", + extract(microseconds from d1) AS microseconds, + extract(milliseconds from d1) AS milliseconds, + extract(seconds from d1) AS seconds, + round(extract(julian from d1)) AS julian, + extract(epoch from d1) AS epoch + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 134 +-- value near upper bound uses special case in code +SELECT date_part('epoch', '294270-01-01 00:00:00'::timestamp) +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 135 +SELECT extract(epoch from '294270-01-01 00:00:00'::timestamp) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 136 +-- another internal overflow test case +SELECT extract(epoch from '5000-01-01 00:00:00'::timestamp) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 137 +-- test edge-case overflow in timestamp subtraction +SELECT timestamp '294276-12-31 23:59:59' - timestamp '1999-12-23 19:59:04.224193' AS ok +-- +STMT: SelectStmt +== 138 +SELECT timestamp '294276-12-31 23:59:59' - timestamp '1999-12-23 19:59:04.224192' AS overflows +-- +STMT: SelectStmt +== 139 +-- TO_CHAR() +SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 140 +SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 142 +SELECT to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM FMWW FMDDD FMDD FMD FMJ') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 143 +SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 144 +SELECT to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 145 +SELECT to_char(d1, 'HH24--text--MI--text--SS') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 146 +SELECT to_char(d1, 'YYYYTH YYYYth Jth') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 147 +SELECT to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 148 +SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 149 +SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 150 +SELECT to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamp), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d) +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 151 +-- Roman months, with upper and lower case. +SELECT i, + to_char(i * interval '1mon', 'rm'), + to_char(i * interval '1mon', 'RM') + FROM generate_series(-13, 13) i +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 152 +-- timestamp numeric fields constructor +SELECT make_timestamp(2014, 12, 28, 6, 30, 45.887) +-- +FUNCTION: name="make_timestamp" function="make_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 153 +SELECT make_timestamp(-44, 3, 15, 12, 30, 15) +-- +FUNCTION: name="make_timestamp" function="make_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 154 +-- should fail +select make_timestamp(0, 7, 15, 12, 30, 15) +-- +FUNCTION: name="make_timestamp" function="make_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 155 +-- generate_series for timestamp +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '1 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 156 +-- the LIMIT should allow this to terminate in a reasonable amount of time +-- (but that unfortunately doesn't work yet for SELECT * FROM ...) +select generate_series('2022-01-01 00:00'::timestamp, + 'infinity'::timestamp, + '1 month'::interval) limit 10 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 157 +-- errors +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '0 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 158 +select generate_series(timestamp '1995-08-06 12:12:12', timestamp '1996-08-06 12:12:12', interval 'infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 159 +select generate_series(timestamp '1995-08-06 12:12:12', timestamp '1996-08-06 12:12:12', interval '-infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 160 +-- test arithmetic with infinite timestamps +select timestamp 'infinity' - timestamp 'infinity' +-- +STMT: SelectStmt +== 161 +select timestamp 'infinity' - timestamp '-infinity' +-- +STMT: SelectStmt +== 162 +select timestamp '-infinity' - timestamp 'infinity' +-- +STMT: SelectStmt +== 163 +select timestamp '-infinity' - timestamp '-infinity' +-- +STMT: SelectStmt +== 164 +select timestamp 'infinity' - timestamp '1995-08-06 12:12:12' +-- +STMT: SelectStmt +== 165 +select timestamp '-infinity' - timestamp '1995-08-06 12:12:12' +-- +STMT: SelectStmt +== 166 +-- test age() with infinite timestamps +select age(timestamp 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 167 +select age(timestamp '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 168 +select age(timestamp 'infinity', timestamp 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 169 +select age(timestamp 'infinity', timestamp '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 170 +select age(timestamp '-infinity', timestamp 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 171 +select age(timestamp '-infinity', timestamp '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/timestamptz.metadata.json b/parser/testdata/summary/postgres_regress/timestamptz.metadata.json new file mode 100644 index 0000000..82ef9cc --- /dev/null +++ b/parser/testdata/summary/postgres_regress/timestamptz.metadata.json @@ -0,0 +1,386 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382" + ] +} diff --git a/parser/testdata/summary/postgres_regress/timestamptz.test b/parser/testdata/summary/postgres_regress/timestamptz.test new file mode 100644 index 0000000..f390370 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/timestamptz.test @@ -0,0 +1,2227 @@ +== 001 +|-- +-- TIMESTAMPTZ +|-- + +CREATE TABLE TIMESTAMPTZ_TBL (d1 timestamp(2) with time zone) +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DDL +STMT: CreateStmt +== 002 +-- Test shorthand input values +-- We can't just "select" the results since they aren't constants; test for +-- equality instead. We can do that by running the test inside a transaction +-- block, within which the value of 'now' shouldn't change, and so these +-- related values shouldn't either. + +BEGIN +-- +STMT: TransactionStmt +== 003 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('today') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('yesterday') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow EST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow zulu') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'today' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 009 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 010 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'yesterday' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 011 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow EST' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 012 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow zulu' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 013 +COMMIT +-- +STMT: TransactionStmt +== 014 +DELETE FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: DeleteStmt +== 015 +-- Verify that 'now' *does* change over a reasonable interval such as 100 msec, +-- and that it doesn't change over the same interval within a transaction block + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 017 +BEGIN +-- +STMT: TransactionStmt +== 018 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 020 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT count(*) AS two FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp(2) with time zone 'now' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 023 +SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 024 +COMMIT +-- +STMT: TransactionStmt +== 025 +TRUNCATE TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DDL +STMT: TruncateStmt +== 026 +-- Special values +INSERT INTO TIMESTAMPTZ_TBL VALUES ('-infinity') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('infinity') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('epoch') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +SELECT timestamptz 'infinity' = timestamptz '+infinity' AS t +-- +STMT: SelectStmt +== 030 +-- Postgres v6.0 standard output format +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +-- Variations on Postgres v6.1 standard output format +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.4 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.5 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.6 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +-- ISO 8601 format +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-01-02') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-01-02 03:04:05') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01-08') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01-0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 040 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01 -08:00') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 -0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-06-10 17:32:01 -07:00') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2001-09-22T18:19:20') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +-- POSIX format (note that the timezone abbrev is just decoration here) +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 08:14:01 GMT+8') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 13:14:02 GMT-1') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 12:14:03 GMT-2') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 03:14:04 PST+8') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 02:14:05 MST+7:00') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +-- Variations for acceptable input formats +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997 -0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 5:32PM 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997/02/10 17:32:01-0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb-10-1997 17:32:01 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('02-10-1997 17:32:01 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 056 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +set datestyle to ymd +-- +STMT: VariableSetStmt +== 058 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('97FEB10 5:32:01PM UTC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('97/02/10 17:32:01 UTC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +reset datestyle +-- +STMT: VariableSetStmt +== 061 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997.041 17:32:01 UTC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +-- timestamps at different timezones +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 America/New_York') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 063 +SELECT '19970210 173201' AT TIME ZONE 'America/New_York' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 064 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America/New_York') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 065 +SELECT '19970710 173201' AT TIME ZONE 'America/New_York' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 066 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America/Does_not_exist') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 067 +SELECT '19970710 173201' AT TIME ZONE 'America/Does_not_exist' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 068 +-- Daylight saving time for timestamps beyond 32-bit time_t range. +SELECT '20500710 173201 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +== 069 +-- DST +SELECT '20500110 173201 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +== 070 +-- non-DST + +SELECT '205000-07-10 17:32:01 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +== 071 +-- DST +SELECT '205000-01-10 17:32:01 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +== 072 +-- non-DST + +-- Test non-error-throwing API +SELECT pg_input_is_valid('now', 'timestamptz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 073 +SELECT pg_input_is_valid('garbage', 'timestamptz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 075 +SELECT * FROM pg_input_error_info('garbage', 'timestamptz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 076 +SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 077 +-- Check date conversion and date arithmetic +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-06-10 18:32:01 PDT') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 078 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 079 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 11 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 12 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 081 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 13 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 14 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 083 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 15 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 084 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 085 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0097 BC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 086 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 087 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0597') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 088 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 089 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1697') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1797') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 091 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1897') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 093 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 2097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 094 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 098 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 099 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 102 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 105 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1999') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 106 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2000') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 2000') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 108 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2001') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 109 +-- Currently unsupported syntax and ranges +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 110 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +-- Alternative field order that we've historically supported (sort of) +-- with regular and POSIXy timezone specs +SELECT 'Wed Jul 11 10:51:14 America/New_York 2001'::timestamptz +-- +STMT: SelectStmt +== 112 +SELECT 'Wed Jul 11 10:51:14 GMT-4 2001'::timestamptz +-- +STMT: SelectStmt +== 113 +SELECT 'Wed Jul 11 10:51:14 GMT+4 2001'::timestamptz +-- +STMT: SelectStmt +== 114 +SELECT 'Wed Jul 11 10:51:14 PST-03:00 2001'::timestamptz +-- +STMT: SelectStmt +== 115 +SELECT 'Wed Jul 11 10:51:14 PST+03:00 2001'::timestamptz +-- +STMT: SelectStmt +== 116 +SELECT d1 FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +STMT: SelectStmt +== 117 +-- Check behavior at the boundaries of the timestamp range +SELECT '4714-11-24 00:00:00+00 BC'::timestamptz +-- +STMT: SelectStmt +== 118 +SELECT '4714-11-23 16:00:00-08 BC'::timestamptz +-- +STMT: SelectStmt +== 119 +SELECT 'Sun Nov 23 16:00:00 4714 PST BC'::timestamptz +-- +STMT: SelectStmt +== 120 +SELECT '4714-11-23 23:59:59+00 BC'::timestamptz +-- +STMT: SelectStmt +== 121 +-- out of range +SELECT '294276-12-31 23:59:59+00'::timestamptz +-- +STMT: SelectStmt +== 122 +SELECT '294276-12-31 15:59:59-08'::timestamptz +-- +STMT: SelectStmt +== 123 +SELECT '294277-01-01 00:00:00+00'::timestamptz +-- +STMT: SelectStmt +== 124 +-- out of range +SELECT '294277-12-31 16:00:00-08'::timestamptz +-- +STMT: SelectStmt +== 125 +-- out of range + +-- Demonstrate functions and operators +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 > timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 126 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 < timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 127 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 = timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 128 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 != timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 129 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 <= timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 130 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 >= timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 131 +SELECT d1 - timestamp with time zone '1997-01-02' AS diff + FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 132 +SELECT date_trunc( 'week', timestamp with time zone '2004-02-29 15:44:17.71393' ) AS week_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 133 +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'Australia/Sydney') as sydney_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 134 +-- zone name +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'GMT') as gmt_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 135 +-- fixed-offset abbreviation +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'VET') as vet_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +== 136 +-- variable-offset abbreviation + +-- verify date_bin behaves the same as date_trunc for relevant intervals +SELECT + str, + interval, + date_trunc(str, ts, 'Australia/Sydney') = date_bin(interval::interval, ts, timestamp with time zone '2001-01-01+11') AS equal +FROM ( + VALUES + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamptz '2020-02-29 15:44:17.71393+00')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 137 +-- bin timestamps into arbitrary intervals +SELECT + interval, + ts, + origin, + date_bin(interval::interval, ts, origin) +FROM ( + VALUES + ('15 days'), + ('2 hours'), + ('1 hour 30 minutes'), + ('15 minutes'), + ('10 seconds'), + ('100 milliseconds'), + ('250 microseconds') +) intervals (interval), +(VALUES (timestamptz '2020-02-11 15:44:17.71393')) ts (ts), +(VALUES (timestamptz '2001-01-01')) origin (origin) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 138 +-- shift bins using the origin parameter: +SELECT date_bin('5 min'::interval, timestamptz '2020-02-01 01:01:01+00', timestamptz '2020-02-01 00:02:30+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 139 +-- test roundoff edge case when source < origin +SELECT date_bin('30 minutes'::interval, timestamptz '2024-02-01 15:00:00', timestamptz '2024-02-01 17:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 140 +-- disallow intervals with months or years +SELECT date_bin('5 months'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 141 +SELECT date_bin('5 years'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 142 +-- disallow zero intervals +SELECT date_bin('0 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 143 +-- disallow negative intervals +SELECT date_bin('-2 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 144 +-- test overflow cases +select date_bin('15 minutes'::interval, timestamptz '294276-12-30', timestamptz '4000-12-20 BC') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 145 +select date_bin('200000000 days'::interval, '2024-02-01'::timestamptz, '2024-01-01'::timestamptz) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 146 +select date_bin('365000 days'::interval, '4400-01-01 BC'::timestamptz, '4000-01-01 BC'::timestamptz) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +== 147 +-- Test casting within a BETWEEN qualifier +SELECT d1 - timestamp with time zone '1997-01-02' AS diff + FROM TIMESTAMPTZ_TBL + WHERE d1 BETWEEN timestamp with time zone '1902-01-01' AND timestamp with time zone '2038-01-01' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +== 148 +-- DATE_PART (timestamptz_part) +SELECT d1 as timestamptz, + date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, + date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, + date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 149 +SELECT d1 as timestamptz, + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 150 +SELECT d1 as timestamptz, + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow, + date_part( 'doy', d1) AS doy + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 151 +SELECT d1 as timestamptz, + date_part( 'decade', d1) AS decade, + date_part( 'century', d1) AS century, + date_part( 'millennium', d1) AS millennium, + round(date_part( 'julian', d1)) AS julian, + date_part( 'epoch', d1) AS epoch + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 152 +SELECT d1 as timestamptz, + date_part( 'timezone', d1) AS timezone, + date_part( 'timezone_hour', d1) AS timezone_hour, + date_part( 'timezone_minute', d1) AS timezone_minute + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 153 +-- extract implementation is mostly the same as date_part, so only +-- test a few cases for additional coverage. +SELECT d1 as "timestamp", + extract(microseconds from d1) AS microseconds, + extract(milliseconds from d1) AS milliseconds, + extract(seconds from d1) AS seconds, + round(extract(julian from d1)) AS julian, + extract(epoch from d1) AS epoch + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 154 +-- value near upper bound uses special case in code +SELECT date_part('epoch', '294270-01-01 00:00:00+00'::timestamptz) +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT extract(epoch from '294270-01-01 00:00:00+00'::timestamptz) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 156 +-- another internal overflow test case +SELECT extract(epoch from '5000-01-01 00:00:00+00'::timestamptz) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 157 +-- test edge-case overflow in timestamp subtraction +SELECT timestamptz '294276-12-31 23:59:59 UTC' - timestamptz '1999-12-23 19:59:04.224193 UTC' AS ok +-- +STMT: SelectStmt +== 158 +SELECT timestamptz '294276-12-31 23:59:59 UTC' - timestamptz '1999-12-23 19:59:04.224192 UTC' AS overflows +-- +STMT: SelectStmt +== 159 +-- TO_CHAR() +SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 160 +SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 161 +SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 162 +SELECT to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM FMWW FMDDD FMDD FMD FMJ') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 163 +SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 164 +SELECT to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 165 +SELECT to_char(d1, 'HH24--text--MI--text--SS') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 166 +SELECT to_char(d1, 'YYYYTH YYYYth Jth') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 167 +SELECT to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 168 +SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 169 +SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 170 +SELECT to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamptz), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d) +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +== 171 +-- Check OF, TZH, TZM with various zone offsets, particularly fractional hours +SET timezone = '00:00' +-- +STMT: VariableSetStmt +== 172 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 173 +SET timezone = '+02:00' +-- +STMT: VariableSetStmt +== 174 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 175 +SET timezone = '-13:00' +-- +STMT: VariableSetStmt +== 176 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 177 +SET timezone = '-00:30' +-- +STMT: VariableSetStmt +== 178 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 179 +SET timezone = '00:30' +-- +STMT: VariableSetStmt +== 180 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 181 +SET timezone = '-04:30' +-- +STMT: VariableSetStmt +== 182 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 183 +SET timezone = '04:30' +-- +STMT: VariableSetStmt +== 184 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 185 +SET timezone = '-04:15' +-- +STMT: VariableSetStmt +== 186 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 187 +SET timezone = '04:15' +-- +STMT: VariableSetStmt +== 188 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 189 +RESET timezone +-- +STMT: VariableSetStmt +== 190 +-- Check of, tzh, tzm with various zone offsets. +SET timezone = '00:00' +-- +STMT: VariableSetStmt +== 191 +SELECT to_char(now(), 'of') as "Of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 192 +SET timezone = '+02:00' +-- +STMT: VariableSetStmt +== 193 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 194 +SET timezone = '-13:00' +-- +STMT: VariableSetStmt +== 195 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 196 +SET timezone = '-00:30' +-- +STMT: VariableSetStmt +== 197 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 198 +SET timezone = '00:30' +-- +STMT: VariableSetStmt +== 199 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 200 +SET timezone = '-04:30' +-- +STMT: VariableSetStmt +== 201 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 202 +SET timezone = '04:30' +-- +STMT: VariableSetStmt +== 203 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 204 +SET timezone = '-04:15' +-- +STMT: VariableSetStmt +== 205 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 206 +SET timezone = '04:15' +-- +STMT: VariableSetStmt +== 207 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 208 +RESET timezone +-- +STMT: VariableSetStmt +== 209 +CREATE TABLE TIMESTAMPTZ_TST (a int , b timestamptz) +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DDL +STMT: CreateStmt +== 210 +-- Test year field value with len > 4 +INSERT INTO TIMESTAMPTZ_TST VALUES(1, 'Sat Mar 12 23:58:48 1000 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 211 +INSERT INTO TIMESTAMPTZ_TST VALUES(2, 'Sat Mar 12 23:58:48 10000 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 212 +INSERT INTO TIMESTAMPTZ_TST VALUES(3, 'Sat Mar 12 23:58:48 100000 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 213 +INSERT INTO TIMESTAMPTZ_TST VALUES(3, '10000 Mar 12 23:58:48 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 214 +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '100000312 23:58:48 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '1000000312 23:58:48 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +--Verify data +SELECT * FROM TIMESTAMPTZ_TST ORDER BY a +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=Select +STMT: SelectStmt +== 217 +--Cleanup +DROP TABLE TIMESTAMPTZ_TST +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DDL +STMT: DropStmt +== 218 +-- test timestamptz constructors +set TimeZone to 'America/New_York' +-- +STMT: VariableSetStmt +== 219 +-- numeric timezone +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33) +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 220 +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '+2') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 221 +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '-2') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 222 +WITH tzs (tz) AS (VALUES + ('+1'), ('+1:'), ('+1:0'), ('+100'), ('+1:00'), ('+01:00'), + ('+10'), ('+1000'), ('+10:'), ('+10:0'), ('+10:00'), ('+10:00:'), + ('+10:00:1'), ('+10:00:01'), + ('+10:00:10')) + SELECT make_timestamptz(2010, 2, 27, 3, 45, 00, tz), tz FROM tzs +-- +CTE: "tzs" +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 223 +-- these should fail +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '2') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 224 +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '+16') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 225 +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '-16') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 226 +-- should be true +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '+2') = '1973-07-15 08:15:55.33+02'::timestamptz +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 227 +-- full timezone names +SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') = timestamptz '2014-12-10 00:00:00 Europe/Prague' +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 228 +SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 229 +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Asia/Singapore') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Pacific/Honolulu') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Europe/Paris') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 232 +SELECT make_timestamptz(1910, 12, 24, 0, 0, 0, 'Nehwon/Lankhmar') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 233 +-- abbreviations +SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EST') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 234 +SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EDT') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 235 +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'FOO8BAR') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 236 +-- POSIX +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT,M3.2.0,M11.1.0') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 237 +RESET TimeZone +-- +STMT: VariableSetStmt +== 238 +-- generate_series for timestamptz +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '1 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 239 +-- the LIMIT should allow this to terminate in a reasonable amount of time +-- (but that unfortunately doesn't work yet for SELECT * FROM ...) +select generate_series('2022-01-01 00:00'::timestamptz, + 'infinity'::timestamptz, + '1 month'::interval) limit 10 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 240 +-- errors +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '0 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 241 +select generate_series(timestamptz '1995-08-06 12:12:12', timestamptz '1996-08-06 12:12:12', interval 'infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 242 +select generate_series(timestamptz '1995-08-06 12:12:12', timestamptz '1996-08-06 12:12:12', interval '-infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 243 +-- Interval crossing time shift for Europe/Warsaw timezone (with DST) +SET TimeZone to 'UTC' +-- +STMT: VariableSetStmt +== 244 +SELECT date_add('2022-10-30 00:00:00+01'::timestamptz, + '1 day'::interval) +-- +FUNCTION: name="date_add" function="date_add" schema="" ctx=Call +STMT: SelectStmt +== 245 +SELECT date_add('2021-10-31 00:00:00+02'::timestamptz, + '1 day'::interval, + 'Europe/Warsaw') +-- +FUNCTION: name="date_add" function="date_add" schema="" ctx=Call +STMT: SelectStmt +== 246 +SELECT date_subtract('2022-10-30 00:00:00+01'::timestamptz, + '1 day'::interval) +-- +FUNCTION: name="date_subtract" function="date_subtract" schema="" ctx=Call +STMT: SelectStmt +== 247 +SELECT date_subtract('2021-10-31 00:00:00+02'::timestamptz, + '1 day'::interval, + 'Europe/Warsaw') +-- +FUNCTION: name="date_subtract" function="date_subtract" schema="" ctx=Call +STMT: SelectStmt +== 248 +SELECT * FROM generate_series('2021-12-31 23:00:00+00'::timestamptz, + '2020-12-31 23:00:00+00'::timestamptz, + '-1 month'::interval, + 'Europe/Warsaw') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 249 +RESET TimeZone +-- +STMT: VariableSetStmt +== 250 +|-- +-- Test behavior with a dynamic (time-varying) timezone abbreviation. +-- These tests rely on the knowledge that MSK (Europe/Moscow standard time) +-- moved forwards in Mar 2011 and backwards again in Oct 2014. +|-- + +SET TimeZone to 'UTC' +-- +STMT: VariableSetStmt +== 251 +SELECT '2011-03-27 00:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 252 +SELECT '2011-03-27 01:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 253 +SELECT '2011-03-27 01:59:59 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 254 +SELECT '2011-03-27 02:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 255 +SELECT '2011-03-27 02:00:01 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 256 +SELECT '2011-03-27 02:59:59 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 257 +SELECT '2011-03-27 03:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 258 +SELECT '2011-03-27 03:00:01 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 259 +SELECT '2011-03-27 04:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 260 +SELECT '2011-03-27 00:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 261 +SELECT '2011-03-27 01:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 262 +SELECT '2011-03-27 01:59:59 MSK'::timestamptz +-- +STMT: SelectStmt +== 263 +SELECT '2011-03-27 02:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 264 +SELECT '2011-03-27 02:00:01 MSK'::timestamptz +-- +STMT: SelectStmt +== 265 +SELECT '2011-03-27 02:59:59 MSK'::timestamptz +-- +STMT: SelectStmt +== 266 +SELECT '2011-03-27 03:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 267 +SELECT '2011-03-27 03:00:01 MSK'::timestamptz +-- +STMT: SelectStmt +== 268 +SELECT '2011-03-27 04:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 269 +SELECT '2014-10-26 00:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 270 +SELECT '2014-10-26 00:59:59 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 271 +SELECT '2014-10-26 01:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 272 +SELECT '2014-10-26 01:00:01 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 273 +SELECT '2014-10-26 02:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +== 274 +SELECT '2014-10-26 00:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 275 +SELECT '2014-10-26 00:59:59 MSK'::timestamptz +-- +STMT: SelectStmt +== 276 +SELECT '2014-10-26 01:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 277 +SELECT '2014-10-26 01:00:01 MSK'::timestamptz +-- +STMT: SelectStmt +== 278 +SELECT '2014-10-26 02:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +== 279 +SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 280 +SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 281 +SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 282 +SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 283 +SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 284 +SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 285 +SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 286 +SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 287 +SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 288 +SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 289 +SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 290 +SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 291 +SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 292 +SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 293 +SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 294 +SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 295 +SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 296 +SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 297 +SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 298 +SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 299 +SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 300 +SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 301 +SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 302 +SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 303 +SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 304 +SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 305 +SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 306 +SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 307 +SELECT make_timestamptz(2014, 10, 26, 0, 0, 0, 'MSK') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 308 +SELECT make_timestamptz(2014, 10, 26, 1, 0, 0, 'MSK') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +== 309 +SELECT to_timestamp( 0) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 310 +-- 1970-01-01 00:00:00+00 +SELECT to_timestamp( 946684800) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 311 +-- 2000-01-01 00:00:00+00 +SELECT to_timestamp(1262349296.7890123) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 312 +-- 2010-01-01 12:34:56.789012+00 +-- edge cases +SELECT to_timestamp(-210866803200) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 313 +-- 4714-11-24 00:00:00+00 BC +-- upper limit varies between integer and float timestamps, so hard to test +-- nonfinite values +SELECT to_timestamp(' Infinity'::float) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 314 +SELECT to_timestamp('-Infinity'::float) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 315 +SELECT to_timestamp('NaN'::float) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 316 +SET TimeZone to 'Europe/Moscow' +-- +STMT: VariableSetStmt +== 317 +SELECT '2011-03-26 21:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +== 318 +SELECT '2011-03-26 22:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +== 319 +SELECT '2011-03-26 22:59:59 UTC'::timestamptz +-- +STMT: SelectStmt +== 320 +SELECT '2011-03-26 23:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +== 321 +SELECT '2011-03-26 23:00:01 UTC'::timestamptz +-- +STMT: SelectStmt +== 322 +SELECT '2011-03-26 23:59:59 UTC'::timestamptz +-- +STMT: SelectStmt +== 323 +SELECT '2011-03-27 00:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +== 324 +SELECT '2014-10-25 21:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +== 325 +SELECT '2014-10-25 21:59:59 UTC'::timestamptz +-- +STMT: SelectStmt +== 326 +SELECT '2014-10-25 22:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +== 327 +SELECT '2014-10-25 22:00:01 UTC'::timestamptz +-- +STMT: SelectStmt +== 328 +SELECT '2014-10-25 23:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +== 329 +RESET TimeZone +-- +STMT: VariableSetStmt +== 330 +SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 331 +SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 332 +SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 333 +SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 334 +SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 335 +SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 336 +SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 337 +SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 338 +SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 339 +SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 340 +SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 341 +SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 342 +SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 343 +SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 344 +SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 345 +SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 346 +SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 347 +SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 348 +SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 349 +SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 350 +SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 351 +SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 352 +SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 353 +SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 354 +|-- +-- Test LOCAL time zone +|-- +BEGIN +-- +STMT: TransactionStmt +== 355 +SET LOCAL TIME ZONE 'Europe/Paris' +-- +STMT: VariableSetStmt +== 356 +VALUES (CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 357 +VALUES (TIMESTAMP '1978-07-07 19:38' AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 358 +SET LOCAL TIME ZONE 'Australia/Sydney' +-- +STMT: VariableSetStmt +== 359 +VALUES (CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 360 +VALUES (TIMESTAMP '1978-07-07 19:38' AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 361 +SET LOCAL TimeZone TO 'UTC' +-- +STMT: VariableSetStmt +== 362 +CREATE VIEW timestamp_local_view AS + SELECT CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL AS ttz_at_local, + timezone(CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE)) AS ttz_func, + TIMESTAMP '1978-07-07 19:38' AT LOCAL AS t_at_local, + timezone(TIMESTAMP '1978-07-07 19:38') AS t_func +-- +TABLE: name="timestamp_local_view" schema="" table="timestamp_local_view" ctx=DDL +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 363 +SELECT pg_get_viewdef('timestamp_local_view', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 364 +TABLE timestamp_local_view +-- +TABLE: name="timestamp_local_view" schema="" table="timestamp_local_view" ctx=Select +STMT: SelectStmt +== 365 +DROP VIEW timestamp_local_view +-- +STMT: DropStmt +== 366 +COMMIT +-- +STMT: TransactionStmt +== 367 +|-- +-- Test that AT TIME ZONE isn't misoptimized when using an index (bug #14504) +|-- +create temp table tmptz (f1 timestamptz primary key) +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=DDL +STMT: CreateStmt +== 368 +insert into tmptz values ('2017-01-18 00:00+00') +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 369 +explain (costs off) +select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00' +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=Select +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +== 370 +select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00' +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=Select +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 371 +-- test arithmetic with infinite timestamps +SELECT timestamptz 'infinity' - timestamptz 'infinity' +-- +STMT: SelectStmt +== 372 +SELECT timestamptz 'infinity' - timestamptz '-infinity' +-- +STMT: SelectStmt +== 373 +SELECT timestamptz '-infinity' - timestamptz 'infinity' +-- +STMT: SelectStmt +== 374 +SELECT timestamptz '-infinity' - timestamptz '-infinity' +-- +STMT: SelectStmt +== 375 +SELECT timestamptz 'infinity' - timestamptz '1995-08-06 12:12:12' +-- +STMT: SelectStmt +== 376 +SELECT timestamptz '-infinity' - timestamptz '1995-08-06 12:12:12' +-- +STMT: SelectStmt +== 377 +-- test age() with infinite timestamps +SELECT age(timestamptz 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 378 +SELECT age(timestamptz '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 379 +SELECT age(timestamptz 'infinity', timestamptz 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 380 +SELECT age(timestamptz 'infinity', timestamptz '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 381 +SELECT age(timestamptz '-infinity', timestamptz 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +== 382 +SELECT age(timestamptz '-infinity', timestamptz '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/timetz.metadata.json b/parser/testdata/summary/postgres_regress/timetz.metadata.json new file mode 100644 index 0000000..7c6405d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/timetz.metadata.json @@ -0,0 +1,61 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057" + ] +} diff --git a/parser/testdata/summary/postgres_regress/timetz.test b/parser/testdata/summary/postgres_regress/timetz.test new file mode 100644 index 0000000..1586370 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/timetz.test @@ -0,0 +1,349 @@ +== 001 +|-- +-- TIMETZ +|-- + +CREATE TABLE TIMETZ_TBL (f1 time(2) with time zone) +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO TIMETZ_TBL VALUES ('00:01 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO TIMETZ_TBL VALUES ('01:00 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO TIMETZ_TBL VALUES ('02:03 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO TIMETZ_TBL VALUES ('07:07 PST') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO TIMETZ_TBL VALUES ('08:08 EDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO TIMETZ_TBL VALUES ('11:59 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO TIMETZ_TBL VALUES ('12:00 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO TIMETZ_TBL VALUES ('12:01 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO TIMETZ_TBL VALUES ('23:59 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO TIMETZ_TBL VALUES ('11:59:59.99 PM PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO TIMETZ_TBL VALUES ('2003-03-07 15:36:39 America/New_York') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO TIMETZ_TBL VALUES ('2003-07-07 15:36:39 America/New_York') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +-- this should fail (the timezone offset is not known) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +-- this should fail (timezone not specified without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +-- this should fail (dynamic timezone abbreviation without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +SELECT f1 AS "Time TZ" FROM TIMETZ_TBL +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +STMT: SelectStmt +== 018 +SELECT f1 AS "Three" FROM TIMETZ_TBL WHERE f1 < '05:06:07-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 019 +SELECT f1 AS "Seven" FROM TIMETZ_TBL WHERE f1 > '05:06:07-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 020 +SELECT f1 AS "None" FROM TIMETZ_TBL WHERE f1 < '00:00-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 021 +SELECT f1 AS "Ten" FROM TIMETZ_TBL WHERE f1 >= '00:00-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 022 +-- Check edge cases +SELECT '23:59:59.999999 PDT'::timetz +-- +STMT: SelectStmt +== 023 +SELECT '23:59:59.9999999 PDT'::timetz +-- +STMT: SelectStmt +== 024 +-- rounds up +SELECT '23:59:60 PDT'::timetz +-- +STMT: SelectStmt +== 025 +-- rounds up +SELECT '24:00:00 PDT'::timetz +-- +STMT: SelectStmt +== 026 +-- allowed +SELECT '24:00:00.01 PDT'::timetz +-- +STMT: SelectStmt +== 027 +-- not allowed +SELECT '23:59:60.01 PDT'::timetz +-- +STMT: SelectStmt +== 028 +-- not allowed +SELECT '24:01:00 PDT'::timetz +-- +STMT: SelectStmt +== 029 +-- not allowed +SELECT '25:00:00 PDT'::timetz +-- +STMT: SelectStmt +== 030 +-- not allowed + +-- Test non-error-throwing API +SELECT pg_input_is_valid('12:00:00 PDT', 'timetz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT pg_input_is_valid('25:00:00 PDT', 'timetz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT pg_input_is_valid('15:36:39 America/New_York', 'timetz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT * FROM pg_input_error_info('25:00:00 PDT', 'timetz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'timetz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 035 +|-- +-- TIME simple math +|-- +-- We now make a distinction between time and intervals, +-- and adding two times together makes no sense at all. +-- Leave in one query to show that it is rejected, +-- and do the rest of the testing in horology.sql +-- where we do mixed-type arithmetic. - thomas 2000-12-02 + +SELECT f1 + time with time zone '00:01' AS "Illegal" FROM TIMETZ_TBL +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +STMT: SelectStmt +== 036 +|-- +-- test EXTRACT +|-- +SELECT EXTRACT(MICROSECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 037 +SELECT EXTRACT(MILLISECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 038 +SELECT EXTRACT(SECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 039 +SELECT EXTRACT(MINUTE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 040 +SELECT EXTRACT(HOUR FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 041 +SELECT EXTRACT(DAY FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 042 +-- error +SELECT EXTRACT(FORTNIGHT FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 043 +-- error +SELECT EXTRACT(TIMEZONE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 044 +SELECT EXTRACT(TIMEZONE_HOUR FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 045 +SELECT EXTRACT(TIMEZONE_MINUTE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 046 +SELECT EXTRACT(EPOCH FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 047 +-- date_part implementation is mostly the same as extract, so only +-- test a few cases for additional coverage. +SELECT date_part('microsecond', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT date_part('millisecond', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 049 +SELECT date_part('second', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT date_part('epoch', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +== 051 +|-- +-- Test timetz_zone, timetz_izone, AT LOCAL +|-- +BEGIN +-- +STMT: TransactionStmt +== 052 +SET LOCAL TimeZone TO 'UTC' +-- +STMT: VariableSetStmt +== 053 +CREATE VIEW timetz_local_view AS + SELECT f1 AS dat, + timezone(f1) AS dat_func, + f1 AT LOCAL AS dat_at_local, + f1 AT TIME ZONE current_setting('TimeZone') AS dat_at_tz, + f1 AT TIME ZONE INTERVAL '00:00' AS dat_at_int + FROM TIMETZ_TBL + ORDER BY f1 +-- +TABLE: name="timetz_local_view" schema="" table="timetz_local_view" ctx=DDL +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 054 +SELECT pg_get_viewdef('timetz_local_view', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 055 +TABLE timetz_local_view +-- +TABLE: name="timetz_local_view" schema="" table="timetz_local_view" ctx=Select +STMT: SelectStmt +== 056 +SELECT f1 AS dat, + f1 AT TIME ZONE 'UTC+10' AS dat_at_tz, + f1 AT TIME ZONE INTERVAL '-10:00' AS dat_at_int + FROM TIMETZ_TBL + ORDER BY f1 +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 057 +ROLLBACK +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/transactions.metadata.json b/parser/testdata/summary/postgres_regress/transactions.metadata.json new file mode 100644 index 0000000..342e97a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/transactions.metadata.json @@ -0,0 +1,494 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490" + ] +} diff --git a/parser/testdata/summary/postgres_regress/transactions.test b/parser/testdata/summary/postgres_regress/transactions.test new file mode 100644 index 0000000..fea5947 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/transactions.test @@ -0,0 +1,2554 @@ +== 001 +|-- +-- TRANSACTIONS +|-- + +BEGIN +-- +STMT: TransactionStmt +== 002 +CREATE TABLE xacttest (a smallint, b real) +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO xacttest VALUES + (56, 7.8), + (100, 99.097), + (0, 0.09561), + (42, 324.78) +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO xacttest (a, b) VALUES (777, 777.777) +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +END +-- +STMT: TransactionStmt +== 006 +-- should retrieve one value-- +SELECT a FROM xacttest WHERE a > 100 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 007 +BEGIN +-- +STMT: TransactionStmt +== 008 +CREATE TABLE disappear (a int4) +-- +TABLE: name="disappear" schema="" table="disappear" ctx=DDL +STMT: CreateStmt +== 009 +DELETE FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +STMT: DeleteStmt +== 010 +-- should be empty +SELECT * FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +== 011 +ABORT +-- +STMT: TransactionStmt +== 012 +-- should not exist +SELECT oid FROM pg_class WHERE relname = 'disappear' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 013 +-- should have members again +SELECT * FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +== 014 +-- Test that transaction characteristics cannot be reset. +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +== 015 +SELECT COUNT(*) FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 016 +RESET transaction_isolation +-- +STMT: VariableSetStmt +== 017 +-- error +END +-- +STMT: TransactionStmt +== 018 +BEGIN TRANSACTION READ ONLY +-- +STMT: TransactionStmt +== 019 +SELECT COUNT(*) FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 020 +RESET transaction_read_only +-- +STMT: VariableSetStmt +== 021 +-- error +END +-- +STMT: TransactionStmt +== 022 +BEGIN TRANSACTION DEFERRABLE +-- +STMT: TransactionStmt +== 023 +SELECT COUNT(*) FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 024 +RESET transaction_deferrable +-- +STMT: VariableSetStmt +== 025 +-- error +END +-- +STMT: TransactionStmt +== 026 +CREATE FUNCTION errfunc() RETURNS int LANGUAGE SQL AS 'SELECT 1' +SET transaction_read_only = on +-- +FUNCTION: name="errfunc" function="errfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 027 +-- error + +-- Read-only tests + +CREATE TABLE writetest (a int) +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DDL +STMT: CreateStmt +== 028 +CREATE TEMPORARY TABLE temptest (a int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +== 029 +BEGIN +-- +STMT: TransactionStmt +== 030 +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY, DEFERRABLE +-- +STMT: VariableSetStmt +== 031 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +== 032 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 033 +--fail +COMMIT +-- +STMT: TransactionStmt +== 034 +BEGIN +-- +STMT: TransactionStmt +== 035 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 036 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 037 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 038 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +== 039 +-- ok +SAVEPOINT x +-- +STMT: TransactionStmt +== 040 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 041 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +== 042 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 043 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 044 +--fail +COMMIT +-- +STMT: TransactionStmt +== 045 +BEGIN +-- +STMT: TransactionStmt +== 046 +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 047 +-- ok +SAVEPOINT x +-- +STMT: TransactionStmt +== 048 +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 049 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 050 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +== 051 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 052 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 053 +--fail +COMMIT +-- +STMT: TransactionStmt +== 054 +BEGIN +-- +STMT: TransactionStmt +== 055 +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 056 +-- ok +SAVEPOINT x +-- +STMT: TransactionStmt +== 057 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 058 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +== 059 +-- ok +ROLLBACK TO SAVEPOINT x +-- +STMT: TransactionStmt +== 060 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 061 +-- off +SAVEPOINT y +-- +STMT: TransactionStmt +== 062 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 063 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +== 064 +-- ok +RELEASE SAVEPOINT y +-- +STMT: TransactionStmt +== 065 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 066 +-- off +COMMIT +-- +STMT: TransactionStmt +== 067 +SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +== 068 +DROP TABLE writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DDL +STMT: DropStmt +== 069 +-- fail +INSERT INTO writetest VALUES (1) +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +-- fail +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +== 071 +-- ok +DELETE FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: DeleteStmt +== 072 +-- ok +UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: UpdateStmt +== 073 +-- ok +PREPARE test AS UPDATE writetest SET a = 0 +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DML +STMT: PrepareStmt +STMT: UpdateStmt +== 074 +-- ok +EXECUTE test +-- +STMT: ExecuteStmt +== 075 +-- fail +SELECT * FROM writetest, temptest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +== 076 +-- ok +CREATE TABLE test AS SELECT * FROM writetest +-- +TABLE: name="test" schema="" table="test" ctx=DDL +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +== 077 +-- fail + +START TRANSACTION READ WRITE +-- +STMT: TransactionStmt +== 078 +DROP TABLE writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DDL +STMT: DropStmt +== 079 +-- ok +COMMIT +-- +STMT: TransactionStmt +== 080 +-- Subtransactions, basic tests +-- create & drop tables +SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +== 081 +CREATE TABLE trans_foobar (a int) +-- +TABLE: name="trans_foobar" schema="" table="trans_foobar" ctx=DDL +STMT: CreateStmt +== 082 +BEGIN +-- +STMT: TransactionStmt +== 083 +CREATE TABLE trans_foo (a int) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DDL +STMT: CreateStmt +== 084 +SAVEPOINT one +-- +STMT: TransactionStmt +== 085 +DROP TABLE trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DDL +STMT: DropStmt +== 086 +CREATE TABLE trans_bar (a int) +-- +TABLE: name="trans_bar" schema="" table="trans_bar" ctx=DDL +STMT: CreateStmt +== 087 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 088 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 089 +SAVEPOINT two +-- +STMT: TransactionStmt +== 090 +CREATE TABLE trans_baz (a int) +-- +TABLE: name="trans_baz" schema="" table="trans_baz" ctx=DDL +STMT: CreateStmt +== 091 +RELEASE SAVEPOINT two +-- +STMT: TransactionStmt +== 092 +drop TABLE trans_foobar +-- +TABLE: name="trans_foobar" schema="" table="trans_foobar" ctx=DDL +STMT: DropStmt +== 093 +CREATE TABLE trans_barbaz (a int) +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=DDL +STMT: CreateStmt +== 094 +COMMIT +-- +STMT: TransactionStmt +== 095 +-- should exist: trans_barbaz, trans_baz, trans_foo +SELECT * FROM trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=Select +STMT: SelectStmt +== 096 +-- should be empty +SELECT * FROM trans_bar +-- +TABLE: name="trans_bar" schema="" table="trans_bar" ctx=Select +STMT: SelectStmt +== 097 +-- shouldn't exist +SELECT * FROM trans_barbaz +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=Select +STMT: SelectStmt +== 098 +-- should be empty +SELECT * FROM trans_baz +-- +TABLE: name="trans_baz" schema="" table="trans_baz" ctx=Select +STMT: SelectStmt +== 099 +-- should be empty + +-- inserts +BEGIN +-- +STMT: TransactionStmt +== 100 +INSERT INTO trans_foo VALUES (1) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +SAVEPOINT one +-- +STMT: TransactionStmt +== 102 +INSERT into trans_bar VALUES (1) +-- +TABLE: name="trans_bar" schema="" table="trans_bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +ROLLBACK TO one +-- +STMT: TransactionStmt +== 104 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 105 +SAVEPOINT two +-- +STMT: TransactionStmt +== 106 +INSERT into trans_barbaz VALUES (1) +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 107 +RELEASE two +-- +STMT: TransactionStmt +== 108 +SAVEPOINT three +-- +STMT: TransactionStmt +== 109 +SAVEPOINT four +-- +STMT: TransactionStmt +== 110 +INSERT INTO trans_foo VALUES (2) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 111 +RELEASE SAVEPOINT four +-- +STMT: TransactionStmt +== 112 +ROLLBACK TO SAVEPOINT three +-- +STMT: TransactionStmt +== 113 +RELEASE SAVEPOINT three +-- +STMT: TransactionStmt +== 114 +INSERT INTO trans_foo VALUES (3) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 115 +COMMIT +-- +STMT: TransactionStmt +== 116 +SELECT * FROM trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=Select +STMT: SelectStmt +== 117 +-- should have 1 and 3 +SELECT * FROM trans_barbaz +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=Select +STMT: SelectStmt +== 118 +-- should have 1 + +-- test whole-tree commit +BEGIN +-- +STMT: TransactionStmt +== 119 +SAVEPOINT one +-- +STMT: TransactionStmt +== 120 +SELECT trans_foo +-- +STMT: SelectStmt +== 121 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 122 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 123 +SAVEPOINT two +-- +STMT: TransactionStmt +== 124 +CREATE TABLE savepoints (a int) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DDL +STMT: CreateStmt +== 125 +SAVEPOINT three +-- +STMT: TransactionStmt +== 126 +INSERT INTO savepoints VALUES (1) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +SAVEPOINT four +-- +STMT: TransactionStmt +== 128 +INSERT INTO savepoints VALUES (2) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 129 +SAVEPOINT five +-- +STMT: TransactionStmt +== 130 +INSERT INTO savepoints VALUES (3) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 131 +ROLLBACK TO SAVEPOINT five +-- +STMT: TransactionStmt +== 132 +COMMIT +-- +STMT: TransactionStmt +== 133 +COMMIT +-- +STMT: TransactionStmt +== 134 +-- should not be in a transaction block +SELECT * FROM savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +STMT: SelectStmt +== 135 +-- test whole-tree rollback +BEGIN +-- +STMT: TransactionStmt +== 136 +SAVEPOINT one +-- +STMT: TransactionStmt +== 137 +DELETE FROM savepoints WHERE a=1 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: DeleteStmt +== 138 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 139 +SAVEPOINT two +-- +STMT: TransactionStmt +== 140 +DELETE FROM savepoints WHERE a=1 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: DeleteStmt +== 141 +SAVEPOINT three +-- +STMT: TransactionStmt +== 142 +DELETE FROM savepoints WHERE a=2 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: DeleteStmt +== 143 +ROLLBACK +-- +STMT: TransactionStmt +== 144 +COMMIT +-- +STMT: TransactionStmt +== 145 +-- should not be in a transaction block + +SELECT * FROM savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +STMT: SelectStmt +== 146 +-- test whole-tree commit on an aborted subtransaction +BEGIN +-- +STMT: TransactionStmt +== 147 +INSERT INTO savepoints VALUES (4) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +SAVEPOINT one +-- +STMT: TransactionStmt +== 149 +INSERT INTO savepoints VALUES (5) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +SELECT trans_foo +-- +STMT: SelectStmt +== 151 +COMMIT +-- +STMT: TransactionStmt +== 152 +SELECT * FROM savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +STMT: SelectStmt +== 153 +BEGIN +-- +STMT: TransactionStmt +== 154 +INSERT INTO savepoints VALUES (6) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 155 +SAVEPOINT one +-- +STMT: TransactionStmt +== 156 +INSERT INTO savepoints VALUES (7) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 157 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 158 +INSERT INTO savepoints VALUES (8) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 159 +COMMIT +-- +STMT: TransactionStmt +== 160 +-- rows 6 and 8 should have been created by the same xact +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=8 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +ALIAS: "a"="savepoints" +ALIAS: "b"="savepoints" +FILTER: schema="" table="a" column="a" +FILTER: schema="" table="b" column="a" +STMT: SelectStmt +== 161 +-- rows 6 and 7 should have been created by different xacts +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=7 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +ALIAS: "a"="savepoints" +ALIAS: "b"="savepoints" +FILTER: schema="" table="a" column="a" +FILTER: schema="" table="b" column="a" +STMT: SelectStmt +== 162 +BEGIN +-- +STMT: TransactionStmt +== 163 +INSERT INTO savepoints VALUES (9) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +SAVEPOINT one +-- +STMT: TransactionStmt +== 165 +INSERT INTO savepoints VALUES (10) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 166 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 167 +INSERT INTO savepoints VALUES (11) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +COMMIT +-- +STMT: TransactionStmt +== 169 +SELECT a FROM savepoints WHERE a in (9, 10, 11) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 170 +-- rows 9 and 11 should have been created by different xacts +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=9 AND b.a=11 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +ALIAS: "a"="savepoints" +ALIAS: "b"="savepoints" +FILTER: schema="" table="a" column="a" +FILTER: schema="" table="b" column="a" +STMT: SelectStmt +== 171 +BEGIN +-- +STMT: TransactionStmt +== 172 +INSERT INTO savepoints VALUES (12) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +SAVEPOINT one +-- +STMT: TransactionStmt +== 174 +INSERT INTO savepoints VALUES (13) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 175 +SAVEPOINT two +-- +STMT: TransactionStmt +== 176 +INSERT INTO savepoints VALUES (14) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 177 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 178 +INSERT INTO savepoints VALUES (15) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 179 +SAVEPOINT two +-- +STMT: TransactionStmt +== 180 +INSERT INTO savepoints VALUES (16) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 181 +SAVEPOINT three +-- +STMT: TransactionStmt +== 182 +INSERT INTO savepoints VALUES (17) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 183 +COMMIT +-- +STMT: TransactionStmt +== 184 +SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 185 +BEGIN +-- +STMT: TransactionStmt +== 186 +INSERT INTO savepoints VALUES (18) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 187 +SAVEPOINT one +-- +STMT: TransactionStmt +== 188 +INSERT INTO savepoints VALUES (19) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +SAVEPOINT two +-- +STMT: TransactionStmt +== 190 +INSERT INTO savepoints VALUES (20) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 191 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 192 +INSERT INTO savepoints VALUES (21) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 194 +INSERT INTO savepoints VALUES (22) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 195 +COMMIT +-- +STMT: TransactionStmt +== 196 +SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 197 +DROP TABLE savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DDL +STMT: DropStmt +== 198 +-- only in a transaction block: +SAVEPOINT one +-- +STMT: TransactionStmt +== 199 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 200 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 201 +-- Only "rollback to" allowed in aborted state +BEGIN +-- +STMT: TransactionStmt +== 202 +SAVEPOINT one +-- +STMT: TransactionStmt +== 203 +SELECT 0/0 +-- +STMT: SelectStmt +== 204 +SAVEPOINT two +-- +STMT: TransactionStmt +== 205 +-- ignored till the end of ... + RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 206 +-- ignored till the end of ... + ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 207 +SELECT 1 +-- +STMT: SelectStmt +== 208 +COMMIT +-- +STMT: TransactionStmt +== 209 +SELECT 1 +-- +STMT: SelectStmt +== 210 +-- this should work + +-- check non-transactional behavior of cursors +BEGIN +-- +STMT: TransactionStmt +== 211 +DECLARE c CURSOR FOR SELECT unique2 FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +== 212 +SAVEPOINT one +-- +STMT: TransactionStmt +== 213 +FETCH 10 FROM c +-- +STMT: FetchStmt +== 214 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +== 215 +FETCH 10 FROM c +-- +STMT: FetchStmt +== 216 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +== 217 +FETCH 10 FROM c +-- +STMT: FetchStmt +== 218 +CLOSE c +-- +STMT: ClosePortalStmt +== 219 +DECLARE c CURSOR FOR SELECT unique2/0 FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +== 220 +SAVEPOINT two +-- +STMT: TransactionStmt +== 221 +FETCH 10 FROM c +-- +STMT: FetchStmt +== 222 +ROLLBACK TO SAVEPOINT two +-- +STMT: TransactionStmt +== 223 +-- c is now dead to the world ... + FETCH 10 FROM c +-- +STMT: FetchStmt +== 224 +ROLLBACK TO SAVEPOINT two +-- +STMT: TransactionStmt +== 225 +RELEASE SAVEPOINT two +-- +STMT: TransactionStmt +== 226 +FETCH 10 FROM c +-- +STMT: FetchStmt +== 227 +COMMIT +-- +STMT: TransactionStmt +== 228 +|-- +-- Check that "stable" functions are really stable. They should not be +-- able to see the partial results of the calling query. (Ideally we would +-- also check that they don't see commits of concurrent transactions, but +-- that's a mite hard to do within the limitations of pg_regress.) +|-- +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +== 229 +create or replace function max_xacttest() returns smallint language sql as +'select max(a) from xacttest' stable +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 230 +begin +-- +STMT: TransactionStmt +== 231 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +== 232 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +== 233 +rollback +-- +STMT: TransactionStmt +== 234 +-- But a volatile function can see the partial results of the calling query +create or replace function max_xacttest() returns smallint language sql as +'select max(a) from xacttest' volatile +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 235 +begin +-- +STMT: TransactionStmt +== 236 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +== 237 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +== 238 +rollback +-- +STMT: TransactionStmt +== 239 +-- Now the same test with plpgsql (since it depends on SPI which is different) +create or replace function max_xacttest() returns smallint language plpgsql as +'begin return max(a) from xacttest; end' stable +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 240 +begin +-- +STMT: TransactionStmt +== 241 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +== 242 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +== 243 +rollback +-- +STMT: TransactionStmt +== 244 +create or replace function max_xacttest() returns smallint language plpgsql as +'begin return max(a) from xacttest; end' volatile +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 245 +begin +-- +STMT: TransactionStmt +== 246 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +== 247 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +== 248 +rollback +-- +STMT: TransactionStmt +== 249 +-- test case for problems with dropping an open relation during abort +BEGIN +-- +STMT: TransactionStmt +== 250 +savepoint x +-- +STMT: TransactionStmt +== 251 +CREATE TABLE koju (a INT UNIQUE) +-- +TABLE: name="koju" schema="" table="koju" ctx=DDL +STMT: CreateStmt +== 252 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 253 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 254 +rollback to x +-- +STMT: TransactionStmt +== 255 +CREATE TABLE koju (a INT UNIQUE) +-- +TABLE: name="koju" schema="" table="koju" ctx=DDL +STMT: CreateStmt +== 256 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 257 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 258 +ROLLBACK +-- +STMT: TransactionStmt +== 259 +DROP TABLE trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DDL +STMT: DropStmt +== 260 +DROP TABLE trans_baz +-- +TABLE: name="trans_baz" schema="" table="trans_baz" ctx=DDL +STMT: DropStmt +== 261 +DROP TABLE trans_barbaz +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=DDL +STMT: DropStmt +== 262 +-- test case for problems with revalidating an open relation during abort +create function inverse(int) returns float8 as +$$ +begin + analyze revalidate_bug; + return 1::float8/$1; +exception + when division_by_zero then return 0; +end$$ language plpgsql volatile +-- +FUNCTION: name="inverse" function="inverse" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 263 +create table revalidate_bug (c float8 unique) +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DDL +STMT: CreateStmt +== 264 +insert into revalidate_bug values (1) +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 265 +insert into revalidate_bug values (inverse(0)) +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DML +FUNCTION: name="inverse" function="inverse" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 266 +drop table revalidate_bug +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DDL +STMT: DropStmt +== 267 +drop function inverse(int) +-- +FUNCTION: name="inverse" function="inverse" schema="" ctx=DDL +STMT: DropStmt +== 268 +-- verify that cursors created during an aborted subtransaction are +-- closed, but that we do not rollback the effect of any FETCHs +-- performed in the aborted subtransaction +begin +-- +STMT: TransactionStmt +== 269 +savepoint x +-- +STMT: TransactionStmt +== 270 +create table trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +== 271 +insert into trans_abc values (5) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 272 +insert into trans_abc values (10) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 273 +declare foo cursor for select * from trans_abc +-- +STMT: DeclareCursorStmt +== 274 +fetch from foo +-- +STMT: FetchStmt +== 275 +rollback to x +-- +STMT: TransactionStmt +== 276 +-- should fail +fetch from foo +-- +STMT: FetchStmt +== 277 +commit +-- +STMT: TransactionStmt +== 278 +begin +-- +STMT: TransactionStmt +== 279 +create table trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +== 280 +insert into trans_abc values (5) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 281 +insert into trans_abc values (10) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 282 +insert into trans_abc values (15) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +declare foo cursor for select * from trans_abc +-- +STMT: DeclareCursorStmt +== 284 +fetch from foo +-- +STMT: FetchStmt +== 285 +savepoint x +-- +STMT: TransactionStmt +== 286 +fetch from foo +-- +STMT: FetchStmt +== 287 +rollback to x +-- +STMT: TransactionStmt +== 288 +fetch from foo +-- +STMT: FetchStmt +== 289 +abort +-- +STMT: TransactionStmt +== 290 +-- Test for proper cleanup after a failure in a cursor portal +-- that was created in an outer subtransaction +CREATE FUNCTION invert(x float8) RETURNS float8 LANGUAGE plpgsql AS +$$ begin return 1/x; end $$ +-- +FUNCTION: name="invert" function="invert" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 291 +CREATE FUNCTION create_temp_tab() RETURNS text +LANGUAGE plpgsql AS $$ +BEGIN + CREATE TEMP TABLE new_table (f1 float8); + -- case of interest is that we fail while holding an open + -- relcache reference to new_table + INSERT INTO new_table SELECT invert(0.0); + RETURN 'foo'; +END $$ +-- +FUNCTION: name="create_temp_tab" function="create_temp_tab" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 292 +BEGIN +-- +STMT: TransactionStmt +== 293 +DECLARE ok CURSOR FOR SELECT * FROM int8_tbl +-- +STMT: DeclareCursorStmt +== 294 +DECLARE ctt CURSOR FOR SELECT create_temp_tab() +-- +STMT: DeclareCursorStmt +== 295 +FETCH ok +-- +STMT: FetchStmt +== 296 +SAVEPOINT s1 +-- +STMT: TransactionStmt +== 297 +FETCH ok +-- +STMT: FetchStmt +== 298 +-- should work +FETCH ctt +-- +STMT: FetchStmt +== 299 +-- error occurs here +ROLLBACK TO s1 +-- +STMT: TransactionStmt +== 300 +FETCH ok +-- +STMT: FetchStmt +== 301 +-- should work +FETCH ctt +-- +STMT: FetchStmt +== 302 +-- must be rejected +COMMIT +-- +STMT: TransactionStmt +== 303 +DROP FUNCTION create_temp_tab() +-- +FUNCTION: name="create_temp_tab" function="create_temp_tab" schema="" ctx=DDL +STMT: DropStmt +== 304 +DROP FUNCTION invert(x float8) +-- +FUNCTION: name="invert" function="invert" schema="" ctx=DDL +STMT: DropStmt +== 305 +-- Tests for AND CHAIN + +CREATE TABLE trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +== 306 +-- set nondefault value so we have something to override below +SET default_transaction_read_only = on +-- +STMT: VariableSetStmt +== 307 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +== 308 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 309 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 310 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 311 +INSERT INTO trans_abc VALUES (1) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 312 +INSERT INTO trans_abc VALUES (2) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 313 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 314 +-- TBLOCK_END +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 315 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 316 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 317 +INSERT INTO trans_abc VALUES ('error') +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 318 +INSERT INTO trans_abc VALUES (3) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 319 +-- check it's really aborted +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 320 +-- TBLOCK_ABORT_END +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 321 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 322 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 323 +INSERT INTO trans_abc VALUES (4) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 324 +COMMIT +-- +STMT: TransactionStmt +== 325 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +== 326 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 327 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 328 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 329 +SAVEPOINT x +-- +STMT: TransactionStmt +== 330 +INSERT INTO trans_abc VALUES ('error') +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 331 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 332 +-- TBLOCK_ABORT_PENDING +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 333 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 334 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 335 +INSERT INTO trans_abc VALUES (5) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 336 +COMMIT +-- +STMT: TransactionStmt +== 337 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +== 338 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 339 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 340 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 341 +SAVEPOINT x +-- +STMT: TransactionStmt +== 342 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 343 +-- TBLOCK_SUBCOMMIT +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 344 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 345 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 346 +COMMIT +-- +STMT: TransactionStmt +== 347 +START TRANSACTION ISOLATION LEVEL READ COMMITTED, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +== 348 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 349 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 350 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 351 +SAVEPOINT x +-- +STMT: TransactionStmt +== 352 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 353 +-- TBLOCK_SUBCOMMIT +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 354 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 355 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 356 +COMMIT +-- +STMT: TransactionStmt +== 357 +-- different mix of options just for fun +START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE +-- +STMT: TransactionStmt +== 358 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 359 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 360 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 361 +INSERT INTO trans_abc VALUES (6) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 362 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +== 363 +-- TBLOCK_ABORT_PENDING +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 364 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 365 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 366 +INSERT INTO trans_abc VALUES ('error') +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 367 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +== 368 +-- TBLOCK_ABORT_END +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 369 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 370 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +== 371 +ROLLBACK +-- +STMT: TransactionStmt +== 372 +-- not allowed outside a transaction block +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 373 +-- error +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +== 374 +-- error + +SELECT * FROM trans_abc ORDER BY 1 +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=Select +STMT: SelectStmt +== 375 +RESET default_transaction_read_only +-- +STMT: VariableSetStmt +== 376 +DROP TABLE trans_abc +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: DropStmt +== 377 +-- Test assorted behaviors around the implicit transaction block created +-- when multiple SQL commands are sent in a single Query message. These +-- tests rely on the fact that psql will not break SQL commands apart at a +-- backslash-quoted semicolon, but will send them as one Query. + +create temp table i_table (f1 int) +-- +TABLE: name="i_table" schema="" table="i_table" ctx=DDL +STMT: CreateStmt +== 378 +-- psql will show all results of a multi-statement Query +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 66 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 379 +SELECT 2\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 380 +SELECT 3 +-- +STMT: SelectStmt +== 381 +-- this implicitly commits: +insert into i_table values(1)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 58 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 382 +select * from i_table +-- +TABLE: name="i_table" schema="" table="i_table" ctx=Select +STMT: SelectStmt +== 383 +-- 1/0 error will cause rolling back the whole implicit transaction +insert into i_table values(2)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 98 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 384 +select * from i_table\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 385 +select 1/0 +-- +STMT: SelectStmt +== 386 +select * from i_table +-- +TABLE: name="i_table" schema="" table="i_table" ctx=Select +STMT: SelectStmt +== 387 +rollback +-- +STMT: TransactionStmt +== 388 +-- we are not in a transaction at this point + +-- can use regular begin/commit/rollback within a single Query +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 115 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 389 +insert into i_table values(3)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 390 +commit +-- +STMT: TransactionStmt +== 391 +rollback +-- +STMT: TransactionStmt +== 392 +-- we are not in a transaction at this point +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 51 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 393 +insert into i_table values(4)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 394 +rollback +-- +STMT: TransactionStmt +== 395 +rollback +-- +STMT: TransactionStmt +== 396 +-- we are not in a transaction at this point + +-- begin converts implicit transaction into a regular one that +-- can extend past the end of the Query +select 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 158 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 397 +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 398 +insert into i_table values(5) +-- +TABLE: name="i_table" schema="" table="i_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 399 +commit +-- +STMT: TransactionStmt +== 400 +select 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 401 +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 402 +insert into i_table values(6) +-- +TABLE: name="i_table" schema="" table="i_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 403 +rollback +-- +STMT: TransactionStmt +== 404 +-- commit in implicit-transaction state commits but issues a warning. +insert into i_table values(7)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 100 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 405 +commit\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 406 +insert into i_table values(8)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 407 +select 1/0 +-- +STMT: SelectStmt +== 408 +-- similarly, rollback aborts but issues a warning. +insert into i_table values(9)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 82 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 409 +rollback\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 410 +select 2 +-- +STMT: SelectStmt +== 411 +select * from i_table +-- +TABLE: name="i_table" schema="" table="i_table" ctx=Select +STMT: SelectStmt +== 412 +rollback +-- +STMT: TransactionStmt +== 413 +-- we are not in a transaction at this point + +-- implicit transaction block is still a transaction block, for e.g. VACUUM +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 414 +VACUUM +-- +STMT: VacuumStmt +== 415 +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 416 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 417 +VACUUM +-- +STMT: VacuumStmt +== 418 +-- we disallow savepoint-related commands in implicit-transaction state +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 81 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 419 +SAVEPOINT sp +-- +STMT: TransactionStmt +== 420 +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 421 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 422 +SAVEPOINT sp +-- +STMT: TransactionStmt +== 423 +ROLLBACK TO SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 424 +SELECT 2 +-- +STMT: SelectStmt +== 425 +SELECT 2\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 426 +RELEASE SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 427 +SELECT 3 +-- +STMT: SelectStmt +== 428 +-- but this is OK, because the BEGIN converts it to a regular xact +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 429 +BEGIN\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 430 +SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 13 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 431 +ROLLBACK TO SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 432 +COMMIT +-- +STMT: TransactionStmt +== 433 +-- Tests for AND CHAIN in implicit transaction blocks + +SET TRANSACTION READ ONLY\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 81 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 434 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 435 +-- error +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 436 +SET TRANSACTION READ ONLY\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 26 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 437 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +== 438 +-- error +SHOW transaction_read_only +-- +STMT: VariableShowStmt +== 439 +CREATE TABLE trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +== 440 +-- COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +INSERT INTO trans_abc VALUES (7)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 80 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 441 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 442 +INSERT INTO trans_abc VALUES (8)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 33 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 443 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 444 +-- 7 commit, 8 error +INSERT INTO trans_abc VALUES (9)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 445 +ROLLBACK\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 446 +INSERT INTO trans_abc VALUES (10)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 447 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +== 448 +-- 9 rollback, 10 error + +-- COMMIT/ROLLBACK AND CHAIN + COMMIT/ROLLBACK +INSERT INTO trans_abc VALUES (11)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 106 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 449 +COMMIT AND CHAIN\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 17 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 450 +INSERT INTO trans_abc VALUES (12)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 451 +COMMIT +-- +STMT: TransactionStmt +== 452 +-- 11 error, 12 not reached +INSERT INTO trans_abc VALUES (13)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 62 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 453 +ROLLBACK AND CHAIN\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 454 +INSERT INTO trans_abc VALUES (14)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 455 +ROLLBACK +-- +STMT: TransactionStmt +== 456 +-- 13 error, 14 not reached + +-- START TRANSACTION + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 128 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 457 +INSERT INTO trans_abc VALUES (15)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 458 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 459 +-- 15 ok +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 460 +-- transaction is active at this point +COMMIT +-- +STMT: TransactionStmt +== 461 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 50 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 462 +INSERT INTO trans_abc VALUES (16)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 463 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +== 464 +-- 16 ok +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 465 +-- transaction is active at this point +ROLLBACK +-- +STMT: TransactionStmt +== 466 +SET default_transaction_isolation = 'read committed' +-- +STMT: VariableSetStmt +== 467 +-- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 117 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 468 +INSERT INTO trans_abc VALUES (17)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 469 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 470 +INSERT INTO trans_abc VALUES (18)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 471 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +== 472 +-- 17 commit, 18 error +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 473 +-- out of transaction block + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 79 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 474 +INSERT INTO trans_abc VALUES (19)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 475 +ROLLBACK\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 476 +INSERT INTO trans_abc VALUES (20)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 477 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +== 478 +-- 19 rollback, 20 error +SHOW transaction_isolation +-- +STMT: VariableShowStmt +== 479 +-- out of transaction block + +RESET default_transaction_isolation +-- +STMT: VariableSetStmt +== 480 +SELECT * FROM trans_abc ORDER BY 1 +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=Select +STMT: SelectStmt +== 481 +DROP TABLE trans_abc +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: DropStmt +== 482 +-- TRANSACTION SNAPSHOT +-- Incorrect identifier. +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ +-- +STMT: TransactionStmt +== 483 +SET TRANSACTION SNAPSHOT 'Incorrect Identifier' +-- +STMT: VariableSetStmt +== 484 +ROLLBACK +-- +STMT: TransactionStmt +== 485 +-- Correct identifier, missing file. +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ +-- +STMT: TransactionStmt +== 486 +SET TRANSACTION SNAPSHOT 'FFF-FFF-F' +-- +STMT: VariableSetStmt +== 487 +ROLLBACK +-- +STMT: TransactionStmt +== 488 +-- Test for successful cleanup of an aborted transaction at session exit. +-- THIS MUST BE THE LAST TEST IN THIS FILE. + +begin +-- +STMT: TransactionStmt +== 489 +select 1/0 +-- +STMT: SelectStmt +== 490 +rollback to X +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/triggers.metadata.json b/parser/testdata/summary/postgres_regress/triggers.metadata.json new file mode 100644 index 0000000..a56f329 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/triggers.metadata.json @@ -0,0 +1,1060 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary/postgres_regress/triggers.test b/parser/testdata/summary/postgres_regress/triggers.test new file mode 100644 index 0000000..e9b37a6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/triggers.test @@ -0,0 +1,6940 @@ +== 001 +|-- +-- TRIGGERS +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION autoinc () + RETURNS trigger + AS :'autoinclib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 144 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +CREATE FUNCTION check_primary_key () + RETURNS trigger + AS :'refintlib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 59 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +CREATE FUNCTION check_foreign_key () + RETURNS trigger + AS :'refintlib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 59 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +CREATE FUNCTION trigger_return_old () + RETURNS trigger + AS :'regresslib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +CREATE FUNCTION set_ttdummy (int4) + RETURNS int4 + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 68 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +create table pkeys (pkey1 int4 not null, pkey2 text not null) +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: CreateStmt +== 007 +create table fkeys (fkey1 int4, fkey2 text, fkey3 int) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: CreateStmt +== 008 +create table fkeys2 (fkey21 int4, fkey22 text, pkey23 int not null) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: CreateStmt +== 009 +create index fkeys_i on fkeys (fkey1, fkey2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: IndexStmt +== 010 +create index fkeys2_i on fkeys2 (fkey21, fkey22) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: IndexStmt +== 011 +create index fkeys2p_i on fkeys2 (pkey23) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: IndexStmt +== 012 +insert into pkeys values (10, '1') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +insert into pkeys values (20, '2') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +insert into pkeys values (30, '3') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +insert into pkeys values (40, '4') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 016 +insert into pkeys values (50, '5') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 017 +insert into pkeys values (60, '6') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 018 +create unique index pkeys_i on pkeys (pkey1, pkey2) +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: IndexStmt +== 019 +|-- +-- For fkeys: +-- (fkey1, fkey2) --> pkeys (pkey1, pkey2) +-- (fkey3) --> fkeys2 (pkey23) +|-- +create trigger check_fkeys_pkey_exist + before insert or update on fkeys + for each row + execute function + check_primary_key ('fkey1', 'fkey2', 'pkeys', 'pkey1', 'pkey2') +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: CreateTrigStmt +== 020 +create trigger check_fkeys_pkey2_exist + before insert or update on fkeys + for each row + execute function check_primary_key ('fkey3', 'fkeys2', 'pkey23') +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: CreateTrigStmt +== 021 +|-- +-- For fkeys2: +-- (fkey21, fkey22) --> pkeys (pkey1, pkey2) +|-- +create trigger check_fkeys2_pkey_exist + before insert or update on fkeys2 + for each row + execute procedure + check_primary_key ('fkey21', 'fkey22', 'pkeys', 'pkey1', 'pkey2') +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: CreateTrigStmt +== 022 +-- Test comments +COMMENT ON TRIGGER check_fkeys2_pkey_bad ON fkeys2 IS 'wrong' +-- +STMT: CommentStmt +== 023 +COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS 'right' +-- +STMT: CommentStmt +== 024 +COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS NULL +-- +STMT: CommentStmt +== 025 +|-- +-- For pkeys: +-- ON DELETE/UPDATE (pkey1, pkey2) CASCADE: +-- fkeys (fkey1, fkey2) and fkeys2 (fkey21, fkey22) +|-- +create trigger check_pkeys_fkey_cascade + before delete or update on pkeys + for each row + execute procedure + check_foreign_key (2, 'cascade', 'pkey1', 'pkey2', + 'fkeys', 'fkey1', 'fkey2', 'fkeys2', 'fkey21', 'fkey22') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: CreateTrigStmt +== 026 +|-- +-- For fkeys2: +-- ON DELETE/UPDATE (pkey23) RESTRICT: +-- fkeys (fkey3) +|-- +create trigger check_fkeys2_fkey_restrict + before delete or update on fkeys2 + for each row + execute procedure check_foreign_key (1, 'restrict', 'pkey23', 'fkeys', 'fkey3') +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: CreateTrigStmt +== 027 +insert into fkeys2 values (10, '1', 1) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 028 +insert into fkeys2 values (30, '3', 2) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +insert into fkeys2 values (40, '4', 5) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +insert into fkeys2 values (50, '5', 3) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +-- no key in pkeys +insert into fkeys2 values (70, '5', 3) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +insert into fkeys values (10, '1', 2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +insert into fkeys values (30, '3', 3) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +insert into fkeys values (40, '4', 2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 035 +insert into fkeys values (50, '5', 2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 036 +-- no key in pkeys +insert into fkeys values (70, '5', 1) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 037 +-- no key in fkeys2 +insert into fkeys values (60, '6', 4) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 038 +delete from pkeys where pkey1 = 30 and pkey2 = '3' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: DeleteStmt +== 039 +delete from pkeys where pkey1 = 40 and pkey2 = '4' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: DeleteStmt +== 040 +update pkeys set pkey1 = 7, pkey2 = '70' where pkey1 = 50 and pkey2 = '5' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: UpdateStmt +== 041 +update pkeys set pkey1 = 7, pkey2 = '70' where pkey1 = 10 and pkey2 = '1' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: UpdateStmt +== 042 +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table in ('pkeys', 'fkeys', 'fkeys2') + ORDER BY trigger_name COLLATE "C", 2 +-- +TABLE: name="information_schema.triggers" schema="information_schema" table="triggers" ctx=Select +FILTER: schema="" table="" column="event_object_table" +STMT: SelectStmt +== 043 +DROP TABLE pkeys +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: DropStmt +== 044 +DROP TABLE fkeys +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: DropStmt +== 045 +DROP TABLE fkeys2 +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: DropStmt +== 046 +-- Check behavior when trigger returns unmodified trigtuple +create table trigtest (f1 int, f2 text) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateStmt +== 047 +create trigger trigger_return_old + before insert or delete or update on trigtest + for each row execute procedure trigger_return_old() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 048 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 050 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +== 051 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 052 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +== 053 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 054 +-- Also check what happens when such a trigger runs before or after others +create function f1_times_10() returns trigger as +$$ begin new.f1 := new.f1 * 10; return new; end $$ language plpgsql +-- +FUNCTION: name="f1_times_10" function="f1_times_10" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 055 +create trigger trigger_alpha + before insert or update on trigtest + for each row execute procedure f1_times_10() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 056 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 058 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +== 059 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 060 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +== 061 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 062 +create trigger trigger_zed + before insert or update on trigtest + for each row execute procedure f1_times_10() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 063 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 065 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +== 066 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 067 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +== 068 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 069 +drop trigger trigger_alpha on trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +== 070 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 071 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 072 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +== 073 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 074 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +== 075 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 076 +drop table trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +== 077 +-- Check behavior with an implicit column default, too (bug #16644) +create table trigtest ( + a integer, + b bool default true not null, + c text default 'xyzzy' not null) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateStmt +== 078 +create trigger trigger_return_old + before insert or delete or update on trigtest + for each row execute procedure trigger_return_old() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 079 +insert into trigtest values(1) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 080 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 081 +alter table trigtest add column d integer default 42 not null +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +== 082 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 083 +update trigtest set a = 2 where a = 1 returning * +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +== 084 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 085 +alter table trigtest drop column b +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +== 086 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 087 +update trigtest set a = 2 where a = 1 returning * +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +== 088 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 089 +drop table trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +== 090 +create sequence ttdummy_seq increment 10 start 0 minvalue 0 +-- +STMT: CreateSeqStmt +== 091 +create table tttest ( + price_id int4, + price_val int4, + price_on int4, + price_off int4 default 999999 +) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: CreateStmt +== 092 +create trigger ttdummy + before delete or update on tttest + for each row + execute procedure + ttdummy (price_on, price_off) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: CreateTrigStmt +== 093 +create trigger ttserial + before insert or update on tttest + for each row + execute procedure + autoinc (price_on, ttdummy_seq) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: CreateTrigStmt +== 094 +insert into tttest values (1, 1, null) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 095 +insert into tttest values (2, 2, null) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 096 +insert into tttest values (3, 3, 0) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 097 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +== 098 +delete from tttest where price_id = 2 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: DeleteStmt +== 099 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +== 100 +-- what do we see ? + +-- get current prices +select * from tttest where price_off = 999999 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +FILTER: schema="" table="" column="price_off" +STMT: SelectStmt +== 101 +-- change price for price_id == 3 +update tttest set price_val = 30 where price_id = 3 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +== 102 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +== 103 +-- now we want to change pric_id in ALL tuples +-- this gets us not what we need +update tttest set price_id = 5 where price_id = 3 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +== 104 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +== 105 +-- restore data as before last update: +select set_ttdummy(0) +-- +FUNCTION: name="set_ttdummy" function="set_ttdummy" schema="" ctx=Call +STMT: SelectStmt +== 106 +delete from tttest where price_id = 5 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: DeleteStmt +== 107 +update tttest set price_off = 999999 where price_val = 30 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +== 108 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +== 109 +-- and try change price_id now! +update tttest set price_id = 5 where price_id = 3 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +== 110 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +== 111 +-- isn't it what we need ? + +select set_ttdummy(1) +-- +FUNCTION: name="set_ttdummy" function="set_ttdummy" schema="" ctx=Call +STMT: SelectStmt +== 112 +-- we want to correct some "date" +update tttest set price_on = -1 where price_id = 1 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +== 113 +-- but this doesn't work + +-- try in this way +select set_ttdummy(0) +-- +FUNCTION: name="set_ttdummy" function="set_ttdummy" schema="" ctx=Call +STMT: SelectStmt +== 114 +update tttest set price_on = -1 where price_id = 1 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +== 115 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +== 116 +-- isn't it what we need ? + +-- get price for price_id == 5 as it was @ "date" 35 +select * from tttest where price_on <= 35 and price_off > 35 and price_id = 5 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +FILTER: schema="" table="" column="price_on" +FILTER: schema="" table="" column="price_off" +FILTER: schema="" table="" column="price_id" +STMT: SelectStmt +== 117 +drop table tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: DropStmt +== 118 +drop sequence ttdummy_seq +-- +STMT: DropStmt +== 119 +|-- +-- tests for per-statement triggers +|-- + +CREATE TABLE log_table (tstamp timestamp default timeofday()::timestamp) +-- +TABLE: name="log_table" schema="" table="log_table" ctx=DDL +STMT: CreateStmt +== 120 +CREATE TABLE main_table (a int unique, b int) +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateStmt +== 121 +COPY main_table (a,b) FROM stdin +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: CopyStmt +== 122 +CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS ' +BEGIN + RAISE NOTICE ''trigger_func(%) called: action = %, when = %, level = %'', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; + RETURN NULL; +END;' +-- +FUNCTION: name="trigger_func" function="trigger_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 123 +CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_ins_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 124 +CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_ins_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 125 +|-- +-- if neither 'FOR EACH ROW' nor 'FOR EACH STATEMENT' was specified, +-- CREATE TRIGGER should default to 'FOR EACH STATEMENT' +|-- +CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_table +EXECUTE PROCEDURE trigger_func('after_upd_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 126 +-- Both insert and update statement level triggers (before and after) should +-- fire. Doesn't fire UPDATE before trigger, but only because one isn't +-- defined. +INSERT INTO main_table (a, b) VALUES (5, 10) ON CONFLICT (a) + DO UPDATE SET b = EXCLUDED.b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 127 +CREATE TRIGGER after_upd_row_trig AFTER UPDATE ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 128 +INSERT INTO main_table DEFAULT VALUES +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: InsertStmt +== 129 +UPDATE main_table SET a = a + 1 WHERE b < 30 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +== 130 +-- UPDATE that effects zero rows should still call per-statement trigger +UPDATE main_table SET a = a + 2 WHERE b > 100 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +== 131 +-- constraint now unneeded +ALTER TABLE main_table DROP CONSTRAINT main_table_a_key +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: AlterTableStmt +== 132 +-- COPY should fire per-row and per-statement INSERT triggers +COPY main_table (a, b) FROM stdin +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: CopyStmt +== 133 +SELECT * FROM main_table ORDER BY a, b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: SelectStmt +== 134 +|-- +-- test triggers with WHEN clause +|-- + +CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) EXECUTE PROCEDURE trigger_func('modified_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 135 +CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table +FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) EXECUTE PROCEDURE trigger_func('modified_any') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 136 +CREATE TRIGGER insert_a AFTER INSERT ON main_table +FOR EACH ROW WHEN (NEW.a = 123) EXECUTE PROCEDURE trigger_func('insert_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 137 +CREATE TRIGGER delete_a AFTER DELETE ON main_table +FOR EACH ROW WHEN (OLD.a = 123) EXECUTE PROCEDURE trigger_func('delete_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 138 +CREATE TRIGGER insert_when BEFORE INSERT ON main_table +FOR EACH STATEMENT WHEN (true) EXECUTE PROCEDURE trigger_func('insert_when') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 139 +CREATE TRIGGER delete_when AFTER DELETE ON main_table +FOR EACH STATEMENT WHEN (true) EXECUTE PROCEDURE trigger_func('delete_when') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 140 +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table IN ('main_table') + ORDER BY trigger_name COLLATE "C", 2 +-- +TABLE: name="information_schema.triggers" schema="information_schema" table="triggers" ctx=Select +FILTER: schema="" table="" column="event_object_table" +STMT: SelectStmt +== 141 +INSERT INTO main_table (a) VALUES (123), (456) +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +COPY main_table FROM stdin +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: CopyStmt +== 143 +DELETE FROM main_table WHERE a IN (123, 456) +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: DeleteStmt +== 144 +UPDATE main_table SET a = 50, b = 60 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +== 145 +SELECT * FROM main_table ORDER BY a, b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: SelectStmt +== 146 +SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 147 +SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 148 +SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 149 +-- Test RENAME TRIGGER +ALTER TRIGGER modified_a ON main_table RENAME TO modified_modified_a +-- +STMT: RenameStmt +== 150 +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 151 +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 152 +DROP TRIGGER modified_modified_a ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 153 +DROP TRIGGER modified_any ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 154 +DROP TRIGGER insert_a ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 155 +DROP TRIGGER delete_a ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 156 +DROP TRIGGER insert_when ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 157 +DROP TRIGGER delete_when ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 158 +-- Test WHEN condition accessing system columns. +create table table_with_oids(a int) +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DDL +STMT: CreateStmt +== 159 +insert into table_with_oids values (1) +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 160 +create trigger oid_unchanged_trig after update on table_with_oids + for each row + when (new.tableoid = old.tableoid AND new.tableoid <> 0) + execute procedure trigger_func('after_upd_oid_unchanged') +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DDL +STMT: CreateTrigStmt +== 161 +update table_with_oids set a = a + 1 +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DML +STMT: UpdateStmt +== 162 +drop table table_with_oids +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DDL +STMT: DropStmt +== 163 +-- Test column-level triggers +DROP TRIGGER after_upd_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 164 +CREATE TRIGGER before_upd_a_row_trig BEFORE UPDATE OF a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_a_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 165 +CREATE TRIGGER after_upd_b_row_trig AFTER UPDATE OF b ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_b_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 166 +CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_a_b_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 167 +CREATE TRIGGER before_upd_a_stmt_trig BEFORE UPDATE OF a ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_upd_a_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 168 +CREATE TRIGGER after_upd_b_stmt_trig AFTER UPDATE OF b ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_upd_b_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 169 +SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'after_upd_a_b_row_trig' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 170 +UPDATE main_table SET a = 50 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +== 171 +UPDATE main_table SET b = 10 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +== 172 +|-- +-- Test case for bug with BEFORE trigger followed by AFTER trigger with WHEN +|-- + +CREATE TABLE some_t (some_col boolean NOT NULL) +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateStmt +== 173 +CREATE FUNCTION dummy_update_func() RETURNS trigger AS $$ +BEGIN + RAISE NOTICE 'dummy_update_func(%) called: action = %, old = %, new = %', + TG_ARGV[0], TG_OP, OLD, NEW; + RETURN NEW; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="dummy_update_func" function="dummy_update_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 174 +CREATE TRIGGER some_trig_before BEFORE UPDATE ON some_t FOR EACH ROW + EXECUTE PROCEDURE dummy_update_func('before') +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateTrigStmt +== 175 +CREATE TRIGGER some_trig_aftera AFTER UPDATE ON some_t FOR EACH ROW + WHEN (NOT OLD.some_col AND NEW.some_col) + EXECUTE PROCEDURE dummy_update_func('aftera') +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateTrigStmt +== 176 +CREATE TRIGGER some_trig_afterb AFTER UPDATE ON some_t FOR EACH ROW + WHEN (NOT NEW.some_col) + EXECUTE PROCEDURE dummy_update_func('afterb') +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateTrigStmt +== 177 +INSERT INTO some_t VALUES (TRUE) +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 178 +UPDATE some_t SET some_col = TRUE +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: UpdateStmt +== 179 +UPDATE some_t SET some_col = FALSE +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: UpdateStmt +== 180 +UPDATE some_t SET some_col = TRUE +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: UpdateStmt +== 181 +DROP TABLE some_t +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: DropStmt +== 182 +-- bogus cases +CREATE TRIGGER error_upd_and_col BEFORE UPDATE OR UPDATE OF a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('error_upd_and_col') +-- +ERROR: duplicate trigger events specified at or near "ON" +CURSORPOS: 78 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 183 +CREATE TRIGGER error_upd_a_a BEFORE UPDATE OF a, a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('error_upd_a_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 184 +CREATE TRIGGER error_ins_a BEFORE INSERT OF a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('error_ins_a') +-- +ERROR: syntax error at or near "OF" +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 185 +CREATE TRIGGER error_ins_when BEFORE INSERT OR UPDATE ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) +EXECUTE PROCEDURE trigger_func('error_ins_old') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 186 +CREATE TRIGGER error_del_when BEFORE DELETE OR UPDATE ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) +EXECUTE PROCEDURE trigger_func('error_del_new') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 187 +CREATE TRIGGER error_del_when BEFORE INSERT OR UPDATE ON main_table +FOR EACH ROW WHEN (NEW.tableoid <> 0) +EXECUTE PROCEDURE trigger_func('error_when_sys_column') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 188 +CREATE TRIGGER error_stmt_when BEFORE UPDATE OF a ON main_table +FOR EACH STATEMENT WHEN (OLD.* IS DISTINCT FROM NEW.*) +EXECUTE PROCEDURE trigger_func('error_stmt_when') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 189 +-- check dependency restrictions +ALTER TABLE main_table DROP COLUMN b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: AlterTableStmt +== 190 +-- this should succeed, but we'll roll it back to keep the triggers around +begin +-- +STMT: TransactionStmt +== 191 +DROP TRIGGER after_upd_a_b_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 192 +DROP TRIGGER after_upd_b_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 193 +DROP TRIGGER after_upd_b_stmt_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 194 +ALTER TABLE main_table DROP COLUMN b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: AlterTableStmt +== 195 +rollback +-- +STMT: TransactionStmt +== 196 +-- Test enable/disable triggers + +create table trigtest (i serial primary key) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateStmt +== 197 +-- test that disabling RI triggers works +create table trigtest2 (i int references trigtest(i) on delete cascade) +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DDL +STMT: CreateStmt +== 198 +create function trigtest() returns trigger as $$ +begin + raise notice '% % % %', TG_TABLE_NAME, TG_OP, TG_WHEN, TG_LEVEL; + return new; +end;$$ language plpgsql +-- +FUNCTION: name="trigtest" function="trigtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 199 +create trigger trigtest_b_row_tg before insert or update or delete on trigtest +for each row execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 200 +create trigger trigtest_a_row_tg after insert or update or delete on trigtest +for each row execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 201 +create trigger trigtest_b_stmt_tg before insert or update or delete on trigtest +for each statement execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 202 +create trigger trigtest_a_stmt_tg after insert or update or delete on trigtest +for each statement execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +== 203 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +== 204 +alter table trigtest disable trigger trigtest_b_row_tg +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +== 205 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +== 206 +alter table trigtest disable trigger user +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +== 207 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +== 208 +alter table trigtest enable trigger trigtest_a_stmt_tg +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +== 209 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +== 210 +set session_replication_role = replica +-- +STMT: VariableSetStmt +== 211 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +== 212 +-- does not trigger +alter table trigtest enable always trigger trigtest_a_stmt_tg +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +== 213 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +== 214 +-- now it does +reset session_replication_role +-- +STMT: VariableSetStmt +== 215 +insert into trigtest2 values(1) +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +insert into trigtest2 values(2) +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 217 +delete from trigtest where i=2 +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +== 218 +select * from trigtest2 +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=Select +STMT: SelectStmt +== 219 +alter table trigtest disable trigger all +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +== 220 +delete from trigtest where i=1 +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +== 221 +select * from trigtest2 +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=Select +STMT: SelectStmt +== 222 +-- ensure we still insert, even when all triggers are disabled +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +== 223 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +== 224 +drop table trigtest2 +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DDL +STMT: DropStmt +== 225 +drop table trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +== 226 +-- dump trigger data +CREATE TABLE trigger_test ( + i int, + v varchar +) +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateStmt +== 227 +CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger +LANGUAGE plpgsql AS $$ + +declare + + argstr text; + relid text; + +begin + + relid := TG_relid::regclass; + + -- plpgsql can't discover its trigger data in a hash like perl and python + -- can, or by a sort of reflection like tcl can, + -- so we have to hard code the names. + raise NOTICE 'TG_NAME: %', TG_name; + raise NOTICE 'TG_WHEN: %', TG_when; + raise NOTICE 'TG_LEVEL: %', TG_level; + raise NOTICE 'TG_OP: %', TG_op; + raise NOTICE 'TG_RELID::regclass: %', relid; + raise NOTICE 'TG_RELNAME: %', TG_relname; + raise NOTICE 'TG_TABLE_NAME: %', TG_table_name; + raise NOTICE 'TG_TABLE_SCHEMA: %', TG_table_schema; + raise NOTICE 'TG_NARGS: %', TG_nargs; + + argstr := '['; + for i in 0 .. TG_nargs - 1 loop + if i > 0 then + argstr := argstr || ', '; + end if; + argstr := argstr || TG_argv[i]; + end loop; + argstr := argstr || ']'; + raise NOTICE 'TG_ARGV: %', argstr; + + if TG_OP != 'INSERT' then + raise NOTICE 'OLD: %', OLD; + end if; + + if TG_OP != 'DELETE' then + raise NOTICE 'NEW: %', NEW; + end if; + + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; + +end; +$$ +-- +FUNCTION: name="trigger_data" function="trigger_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 228 +CREATE TRIGGER show_trigger_data_trig +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateTrigStmt +== 229 +insert into trigger_test values(1,'insert') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +update trigger_test set v = 'update' where i = 1 +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +== 231 +delete from trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: DeleteStmt +== 232 +DROP TRIGGER show_trigger_data_trig on trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: DropStmt +== 233 +DROP FUNCTION trigger_data() +-- +FUNCTION: name="trigger_data" function="trigger_data" schema="" ctx=DDL +STMT: DropStmt +== 234 +DROP TABLE trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: DropStmt +== 235 +|-- +-- Test use of row comparisons on OLD/NEW +|-- + +CREATE TABLE trigger_test (f1 int, f2 text, f3 text) +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateStmt +== 236 +-- this is the obvious (and wrong...) way to compare rows +CREATE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql as $$ +begin + if row(old.*) = row(new.*) then + raise notice 'row % not changed', new.f1; + else + raise notice 'row % changed', new.f1; + end if; + return new; +end$$ +-- +FUNCTION: name="mytrigger" function="mytrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 237 +CREATE TRIGGER t +BEFORE UPDATE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE mytrigger() +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateTrigStmt +== 238 +INSERT INTO trigger_test VALUES(1, 'foo', 'bar') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 239 +INSERT INTO trigger_test VALUES(2, 'baz', 'quux') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +UPDATE trigger_test SET f3 = 'bar' +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +== 241 +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +== 242 +-- this demonstrates that the above isn't really working as desired: +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +== 243 +-- the right way when considering nulls is +CREATE OR REPLACE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql as $$ +begin + if row(old.*) is distinct from row(new.*) then + raise notice 'row % changed', new.f1; + else + raise notice 'row % not changed', new.f1; + end if; + return new; +end$$ +-- +FUNCTION: name="mytrigger" function="mytrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 244 +UPDATE trigger_test SET f3 = 'bar' +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +== 245 +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +== 246 +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +== 247 +DROP TABLE trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: DropStmt +== 248 +DROP FUNCTION mytrigger() +-- +FUNCTION: name="mytrigger" function="mytrigger" schema="" ctx=DDL +STMT: DropStmt +== 249 +-- Test snapshot management in serializable transactions involving triggers +-- per bug report in 6bc73d4c0910042358k3d1adff3qa36f8df75198ecea@mail.gmail.com +CREATE FUNCTION serializable_update_trig() RETURNS trigger LANGUAGE plpgsql AS +$$ +declare + rec record; +begin + new.description = 'updated in trigger'; + return new; +end; +$$ +-- +FUNCTION: name="serializable_update_trig" function="serializable_update_trig" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 250 +CREATE TABLE serializable_update_tab ( + id int, + filler text, + description text +) +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DDL +STMT: CreateStmt +== 251 +CREATE TRIGGER serializable_update_trig BEFORE UPDATE ON serializable_update_tab + FOR EACH ROW EXECUTE PROCEDURE serializable_update_trig() +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DDL +STMT: CreateTrigStmt +== 252 +INSERT INTO serializable_update_tab SELECT a, repeat('xyzxz', 100), 'new' + FROM generate_series(1, 50) a +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 253 +BEGIN +-- +STMT: TransactionStmt +== 254 +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: VariableSetStmt +== 255 +UPDATE serializable_update_tab SET description = 'no no', id = 1 WHERE id = 1 +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DML +STMT: UpdateStmt +== 256 +COMMIT +-- +STMT: TransactionStmt +== 257 +SELECT description FROM serializable_update_tab WHERE id = 1 +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 258 +DROP TABLE serializable_update_tab +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DDL +STMT: DropStmt +== 259 +-- minimal update trigger + +CREATE TABLE min_updates_test ( + f1 text, + f2 int, + f3 int) +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DDL +STMT: CreateStmt +== 260 +INSERT INTO min_updates_test VALUES ('a',1,2),('b','2',null) +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 261 +CREATE TRIGGER z_min_update +BEFORE UPDATE ON min_updates_test +FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger() +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DDL +STMT: CreateTrigStmt +== 262 +UPDATE min_updates_test SET f1 = f1 +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: UpdateStmt +== 263 +UPDATE min_updates_test SET f2 = f2 + 1 +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: UpdateStmt +== 264 +UPDATE min_updates_test SET f3 = 2 WHERE f3 is null +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: UpdateStmt +== 265 +SELECT * FROM min_updates_test +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=Select +STMT: SelectStmt +== 266 +DROP TABLE min_updates_test +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DDL +STMT: DropStmt +== 267 +|-- +-- Test triggers on views +|-- + +CREATE VIEW main_view AS SELECT a, b FROM main_table +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 268 +-- VIEW trigger function +CREATE OR REPLACE FUNCTION view_trigger() RETURNS trigger +LANGUAGE plpgsql AS $$ +declare + argstr text := ''; +begin + for i in 0 .. TG_nargs - 1 loop + if i > 0 then + argstr := argstr || ', '; + end if; + argstr := argstr || TG_argv[i]; + end loop; + + raise notice '% % % % (%)', TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, argstr; + + if TG_LEVEL = 'ROW' then + if TG_OP = 'INSERT' then + raise NOTICE 'NEW: %', NEW; + INSERT INTO main_table VALUES (NEW.a, NEW.b); + RETURN NEW; + end if; + + if TG_OP = 'UPDATE' then + raise NOTICE 'OLD: %, NEW: %', OLD, NEW; + UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b; + if NOT FOUND then RETURN NULL; end if; + RETURN NEW; + end if; + + if TG_OP = 'DELETE' then + raise NOTICE 'OLD: %', OLD; + DELETE FROM main_table WHERE a = OLD.a AND b = OLD.b; + if NOT FOUND then RETURN NULL; end if; + RETURN OLD; + end if; + end if; + + RETURN NULL; +end; +$$ +-- +FUNCTION: name="view_trigger" function="view_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 269 +-- Before row triggers aren't allowed on views +CREATE TRIGGER invalid_trig BEFORE INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_ins_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 270 +CREATE TRIGGER invalid_trig BEFORE UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 271 +CREATE TRIGGER invalid_trig BEFORE DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_del_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 272 +-- After row triggers aren't allowed on views +CREATE TRIGGER invalid_trig AFTER INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_ins_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 273 +CREATE TRIGGER invalid_trig AFTER UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 274 +CREATE TRIGGER invalid_trig AFTER DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_del_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 275 +-- Truncate triggers aren't allowed on views +CREATE TRIGGER invalid_trig BEFORE TRUNCATE ON main_view +EXECUTE PROCEDURE trigger_func('before_tru_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 276 +CREATE TRIGGER invalid_trig AFTER TRUNCATE ON main_view +EXECUTE PROCEDURE trigger_func('before_tru_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 277 +-- INSTEAD OF triggers aren't allowed on tables +CREATE TRIGGER invalid_trig INSTEAD OF INSERT ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 278 +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 279 +CREATE TRIGGER invalid_trig INSTEAD OF DELETE ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +== 280 +-- Don't support WHEN clauses with INSTEAD OF triggers +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view +FOR EACH ROW WHEN (OLD.a <> NEW.a) EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 281 +-- Don't support column-level INSTEAD OF triggers +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE OF a ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 282 +-- Don't support statement-level INSTEAD OF triggers +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view +EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 283 +-- Valid INSTEAD OF triggers +CREATE TRIGGER instead_of_insert_trig INSTEAD OF INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 284 +CREATE TRIGGER instead_of_update_trig INSTEAD OF UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 285 +CREATE TRIGGER instead_of_delete_trig INSTEAD OF DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 286 +-- Valid BEFORE statement VIEW triggers +CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_ins_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 287 +CREATE TRIGGER before_upd_stmt_trig BEFORE UPDATE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_upd_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 288 +CREATE TRIGGER before_del_stmt_trig BEFORE DELETE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_del_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 289 +-- Valid AFTER statement VIEW triggers +CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_ins_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 290 +CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_upd_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 291 +CREATE TRIGGER after_del_stmt_trig AFTER DELETE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_del_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +== 292 +-- Insert into view using trigger +INSERT INTO main_view VALUES (20, 30) +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +INSERT INTO main_view VALUES (21, 31) RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 294 +-- Table trigger will prevent updates +UPDATE main_view SET b = 31 WHERE a = 20 +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +== 295 +UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +== 296 +-- Remove table trigger to allow updates +DROP TRIGGER before_upd_a_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +== 297 +UPDATE main_view SET b = 31 WHERE a = 20 +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +== 298 +UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +== 299 +-- Before and after stmt triggers should fire even when no rows are affected +UPDATE main_view SET b = 0 WHERE false +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +== 300 +-- Delete from view using trigger +DELETE FROM main_view WHERE a IN (20,21) +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: DeleteStmt +== 301 +DELETE FROM main_view WHERE a = 31 RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: DeleteStmt +== 302 +-- Describe view should list triggers + +-- Test dropping view triggers +DROP TRIGGER instead_of_insert_trig ON main_view +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: DropStmt +== 303 +DROP TRIGGER instead_of_delete_trig ON main_view +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: DropStmt +== 304 +DROP VIEW main_view +-- +STMT: DropStmt +== 305 +|-- +-- Test triggers on a join view +|-- +CREATE TABLE country_table ( + country_id serial primary key, + country_name text unique not null, + continent text not null +) +-- +TABLE: name="country_table" schema="" table="country_table" ctx=DDL +STMT: CreateStmt +== 306 +INSERT INTO country_table (country_name, continent) + VALUES ('Japan', 'Asia'), + ('UK', 'Europe'), + ('USA', 'North America') + RETURNING * +-- +TABLE: name="country_table" schema="" table="country_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 307 +CREATE TABLE city_table ( + city_id serial primary key, + city_name text not null, + population bigint, + country_id int references country_table +) +-- +TABLE: name="city_table" schema="" table="city_table" ctx=DDL +STMT: CreateStmt +== 308 +CREATE VIEW city_view AS + SELECT city_id, city_name, population, country_name, continent + FROM city_table ci + LEFT JOIN country_table co ON co.country_id = ci.country_id +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +TABLE: name="city_table" schema="" table="city_table" ctx=Select +TABLE: name="country_table" schema="" table="country_table" ctx=Select +ALIAS: "ci"="city_table" +ALIAS: "co"="country_table" +STMT: ViewStmt +STMT: SelectStmt +== 309 +CREATE FUNCTION city_insert() RETURNS trigger LANGUAGE plpgsql AS $$ +declare + ctry_id int; +begin + if NEW.country_name IS NOT NULL then + SELECT country_id, continent INTO ctry_id, NEW.continent + FROM country_table WHERE country_name = NEW.country_name; + if NOT FOUND then + raise exception 'No such country: "%"', NEW.country_name; + end if; + else + NEW.continent := NULL; + end if; + + if NEW.city_id IS NOT NULL then + INSERT INTO city_table + VALUES(NEW.city_id, NEW.city_name, NEW.population, ctry_id); + else + INSERT INTO city_table(city_name, population, country_id) + VALUES(NEW.city_name, NEW.population, ctry_id) + RETURNING city_id INTO NEW.city_id; + end if; + + RETURN NEW; +end; +$$ +-- +FUNCTION: name="city_insert" function="city_insert" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 310 +CREATE TRIGGER city_insert_trig INSTEAD OF INSERT ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_insert() +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +STMT: CreateTrigStmt +== 311 +CREATE FUNCTION city_delete() RETURNS trigger LANGUAGE plpgsql AS $$ +begin + DELETE FROM city_table WHERE city_id = OLD.city_id; + if NOT FOUND then RETURN NULL; end if; + RETURN OLD; +end; +$$ +-- +FUNCTION: name="city_delete" function="city_delete" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 312 +CREATE TRIGGER city_delete_trig INSTEAD OF DELETE ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_delete() +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +STMT: CreateTrigStmt +== 313 +CREATE FUNCTION city_update() RETURNS trigger LANGUAGE plpgsql AS $$ +declare + ctry_id int; +begin + if NEW.country_name IS DISTINCT FROM OLD.country_name then + SELECT country_id, continent INTO ctry_id, NEW.continent + FROM country_table WHERE country_name = NEW.country_name; + if NOT FOUND then + raise exception 'No such country: "%"', NEW.country_name; + end if; + + UPDATE city_table SET city_name = NEW.city_name, + population = NEW.population, + country_id = ctry_id + WHERE city_id = OLD.city_id; + else + UPDATE city_table SET city_name = NEW.city_name, + population = NEW.population + WHERE city_id = OLD.city_id; + NEW.continent := OLD.continent; + end if; + + if NOT FOUND then RETURN NULL; end if; + RETURN NEW; +end; +$$ +-- +FUNCTION: name="city_update" function="city_update" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 314 +CREATE TRIGGER city_update_trig INSTEAD OF UPDATE ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_update() +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +STMT: CreateTrigStmt +== 315 +-- INSERT .. RETURNING +INSERT INTO city_view(city_name) VALUES('Tokyo') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 316 +INSERT INTO city_view(city_name, population) VALUES('London', 7556900) RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 317 +INSERT INTO city_view(city_name, country_name) VALUES('Washington DC', 'USA') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 318 +INSERT INTO city_view(city_id, city_name) VALUES(123456, 'New York') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 319 +INSERT INTO city_view VALUES(234567, 'Birmingham', 1016800, 'UK', 'EU') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 320 +-- UPDATE .. RETURNING +UPDATE city_view SET country_name = 'Japon' WHERE city_name = 'Tokyo' +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 321 +-- error +UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Takyo' +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 322 +-- no match +UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Tokyo' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 323 +-- OK + +UPDATE city_view SET population = 13010279 WHERE city_name = 'Tokyo' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 324 +UPDATE city_view SET country_name = 'UK' WHERE city_name = 'New York' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 325 +UPDATE city_view SET country_name = 'USA', population = 8391881 WHERE city_name = 'New York' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 326 +UPDATE city_view SET continent = 'EU' WHERE continent = 'Europe' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 327 +UPDATE city_view v1 SET country_name = v2.country_name FROM city_view v2 + WHERE v2.city_name = 'Birmingham' AND v1.city_name = 'London' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +TABLE: name="city_view" schema="" table="city_view" ctx=Select +ALIAS: "v1"="city_view" +ALIAS: "v2"="city_view" +STMT: UpdateStmt +== 328 +-- DELETE .. RETURNING +DELETE FROM city_view WHERE city_name = 'Birmingham' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: DeleteStmt +== 329 +-- read-only view with WHERE clause +CREATE VIEW european_city_view AS + SELECT * FROM city_view WHERE continent = 'Europe' +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +TABLE: name="city_view" schema="" table="city_view" ctx=Select +FILTER: schema="" table="" column="continent" +STMT: ViewStmt +STMT: SelectStmt +== 330 +SELECT count(*) FROM european_city_view +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 331 +CREATE FUNCTION no_op_trig_fn() RETURNS trigger LANGUAGE plpgsql +AS 'begin RETURN NULL; end' +-- +FUNCTION: name="no_op_trig_fn" function="no_op_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 332 +CREATE TRIGGER no_op_trig INSTEAD OF INSERT OR UPDATE OR DELETE +ON european_city_view FOR EACH ROW EXECUTE PROCEDURE no_op_trig_fn() +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: CreateTrigStmt +== 333 +INSERT INTO european_city_view VALUES (0, 'x', 10000, 'y', 'z') +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 334 +UPDATE european_city_view SET population = 10000 +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: UpdateStmt +== 335 +DELETE FROM european_city_view +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: DeleteStmt +== 336 +-- rules bypassing no-op triggers +CREATE RULE european_city_insert_rule AS ON INSERT TO european_city_view +DO INSTEAD INSERT INTO city_view +VALUES (NEW.city_id, NEW.city_name, NEW.population, NEW.country_name, NEW.continent) +RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: RuleStmt +== 337 +CREATE RULE european_city_update_rule AS ON UPDATE TO european_city_view +DO INSTEAD UPDATE city_view SET + city_name = NEW.city_name, + population = NEW.population, + country_name = NEW.country_name +WHERE city_id = OLD.city_id +RETURNING NEW.* +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: RuleStmt +== 338 +CREATE RULE european_city_delete_rule AS ON DELETE TO european_city_view +DO INSTEAD DELETE FROM city_view WHERE city_id = OLD.city_id RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: RuleStmt +== 339 +-- INSERT not limited by view's WHERE clause, but UPDATE AND DELETE are +INSERT INTO european_city_view(city_name, country_name) + VALUES ('Cambridge', 'USA') RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 340 +UPDATE european_city_view SET country_name = 'UK' + WHERE city_name = 'Cambridge' +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: UpdateStmt +== 341 +DELETE FROM european_city_view WHERE city_name = 'Cambridge' +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: DeleteStmt +== 342 +-- UPDATE and DELETE via rule and trigger +UPDATE city_view SET country_name = 'UK' + WHERE city_name = 'Cambridge' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +== 343 +UPDATE european_city_view SET population = 122800 + WHERE city_name = 'Cambridge' RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: UpdateStmt +== 344 +DELETE FROM european_city_view WHERE city_name = 'Cambridge' RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: DeleteStmt +== 345 +-- join UPDATE test +UPDATE city_view v SET population = 599657 + FROM city_table ci, country_table co + WHERE ci.city_name = 'Washington DC' and co.country_name = 'USA' + AND v.city_id = ci.city_id AND v.country_name = co.country_name + RETURNING co.country_id, v.country_name, + v.city_id, v.city_name, v.population +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +TABLE: name="city_table" schema="" table="city_table" ctx=Select +TABLE: name="country_table" schema="" table="country_table" ctx=Select +ALIAS: "ci"="city_table" +ALIAS: "co"="country_table" +ALIAS: "v"="city_view" +STMT: UpdateStmt +== 346 +SELECT * FROM city_view +-- +TABLE: name="city_view" schema="" table="city_view" ctx=Select +STMT: SelectStmt +== 347 +DROP TABLE city_table CASCADE +-- +TABLE: name="city_table" schema="" table="city_table" ctx=DDL +STMT: DropStmt +== 348 +DROP TABLE country_table +-- +TABLE: name="country_table" schema="" table="country_table" ctx=DDL +STMT: DropStmt +== 349 +-- Test pg_trigger_depth() + +create table depth_a (id int not null primary key) +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DDL +STMT: CreateStmt +== 350 +create table depth_b (id int not null primary key) +-- +TABLE: name="depth_b" schema="" table="depth_b" ctx=DDL +STMT: CreateStmt +== 351 +create table depth_c (id int not null primary key) +-- +TABLE: name="depth_c" schema="" table="depth_c" ctx=DDL +STMT: CreateStmt +== 352 +create function depth_a_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + insert into depth_b values (new.id); + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + return new; +end; +$$ +-- +FUNCTION: name="depth_a_tf" function="depth_a_tf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 353 +create trigger depth_a_tr before insert on depth_a + for each row execute procedure depth_a_tf() +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DDL +STMT: CreateTrigStmt +== 354 +create function depth_b_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + begin + execute 'insert into depth_c values (' || new.id::text || ')'; + exception + when sqlstate 'U9999' then + raise notice 'SQLSTATE = U9999: depth = %', pg_trigger_depth(); + end; + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + if new.id = 1 then + execute 'insert into depth_c values (' || new.id::text || ')'; + end if; + return new; +end; +$$ +-- +FUNCTION: name="depth_b_tf" function="depth_b_tf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 355 +create trigger depth_b_tr before insert on depth_b + for each row execute procedure depth_b_tf() +-- +TABLE: name="depth_b" schema="" table="depth_b" ctx=DDL +STMT: CreateTrigStmt +== 356 +create function depth_c_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + if new.id = 1 then + raise exception sqlstate 'U9999'; + end if; + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + return new; +end; +$$ +-- +FUNCTION: name="depth_c_tf" function="depth_c_tf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 357 +create trigger depth_c_tr before insert on depth_c + for each row execute procedure depth_c_tf() +-- +TABLE: name="depth_c" schema="" table="depth_c" ctx=DDL +STMT: CreateTrigStmt +== 358 +select pg_trigger_depth() +-- +FUNCTION: name="pg_trigger_depth" function="pg_trigger_depth" schema="" ctx=Call +STMT: SelectStmt +== 359 +insert into depth_a values (1) +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +select pg_trigger_depth() +-- +FUNCTION: name="pg_trigger_depth" function="pg_trigger_depth" schema="" ctx=Call +STMT: SelectStmt +== 361 +insert into depth_a values (2) +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 362 +select pg_trigger_depth() +-- +FUNCTION: name="pg_trigger_depth" function="pg_trigger_depth" schema="" ctx=Call +STMT: SelectStmt +== 363 +drop table depth_a, depth_b, depth_c +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DDL +TABLE: name="depth_b" schema="" table="depth_b" ctx=DDL +TABLE: name="depth_c" schema="" table="depth_c" ctx=DDL +STMT: DropStmt +== 364 +drop function depth_a_tf() +-- +FUNCTION: name="depth_a_tf" function="depth_a_tf" schema="" ctx=DDL +STMT: DropStmt +== 365 +drop function depth_b_tf() +-- +FUNCTION: name="depth_b_tf" function="depth_b_tf" schema="" ctx=DDL +STMT: DropStmt +== 366 +drop function depth_c_tf() +-- +FUNCTION: name="depth_c_tf" function="depth_c_tf" schema="" ctx=DDL +STMT: DropStmt +== 367 +|-- +-- Test updates to rows during firing of BEFORE ROW triggers. +-- As of 9.2, such cases should be rejected (see bug #6123). +|-- + +create temp table parent ( + aid int not null primary key, + val1 text, + val2 text, + val3 text, + val4 text, + bcnt int not null default 0) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 368 +create temp table child ( + bid int not null primary key, + aid int not null, + val1 text) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 369 +create function parent_upd_func() + returns trigger language plpgsql as +$$ +begin + if old.val1 <> new.val1 then + new.val2 = new.val1; + delete from child where child.aid = new.aid and child.val1 = new.val1; + end if; + return new; +end; +$$ +-- +FUNCTION: name="parent_upd_func" function="parent_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 370 +create trigger parent_upd_trig before update on parent + for each row execute procedure parent_upd_func() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 371 +create function parent_del_func() + returns trigger language plpgsql as +$$ +begin + delete from child where aid = old.aid; + return old; +end; +$$ +-- +FUNCTION: name="parent_del_func" function="parent_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 372 +create trigger parent_del_trig before delete on parent + for each row execute procedure parent_del_func() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 373 +create function child_ins_func() + returns trigger language plpgsql as +$$ +begin + update parent set bcnt = bcnt + 1 where aid = new.aid; + return new; +end; +$$ +-- +FUNCTION: name="child_ins_func" function="child_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 374 +create trigger child_ins_trig after insert on child + for each row execute procedure child_ins_func() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +== 375 +create function child_del_func() + returns trigger language plpgsql as +$$ +begin + update parent set bcnt = bcnt - 1 where aid = old.aid; + return old; +end; +$$ +-- +FUNCTION: name="child_del_func" function="child_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 376 +create trigger child_del_trig after delete on child + for each row execute procedure child_del_func() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +== 377 +insert into parent values (1, 'a', 'a', 'a', 'a', 0) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 378 +insert into child values (10, 1, 'b') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 379 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 380 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +== 381 +update parent set val1 = 'b' where aid = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +== 382 +-- should fail +merge into parent p using (values (1)) as v(id) on p.aid = v.id + when matched then update set val1 = 'b' +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +ALIAS: "p"="parent" +STMT: MergeStmt +STMT: SelectStmt +== 383 +-- should fail +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 384 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +== 385 +delete from parent where aid = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +== 386 +-- should fail +merge into parent p using (values (1)) as v(id) on p.aid = v.id + when matched then delete +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +ALIAS: "p"="parent" +STMT: MergeStmt +STMT: SelectStmt +== 387 +-- should fail +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 388 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +== 389 +-- replace the trigger function with one that restarts the deletion after +-- having modified a child +create or replace function parent_del_func() + returns trigger language plpgsql as +$$ +begin + delete from child where aid = old.aid; + if found then + delete from parent where aid = old.aid; + return null; -- cancel outer deletion + end if; + return old; +end; +$$ +-- +FUNCTION: name="parent_del_func" function="parent_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 390 +delete from parent where aid = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +== 391 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 392 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +== 393 +drop table parent, child +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 394 +drop function parent_upd_func() +-- +FUNCTION: name="parent_upd_func" function="parent_upd_func" schema="" ctx=DDL +STMT: DropStmt +== 395 +drop function parent_del_func() +-- +FUNCTION: name="parent_del_func" function="parent_del_func" schema="" ctx=DDL +STMT: DropStmt +== 396 +drop function child_ins_func() +-- +FUNCTION: name="child_ins_func" function="child_ins_func" schema="" ctx=DDL +STMT: DropStmt +== 397 +drop function child_del_func() +-- +FUNCTION: name="child_del_func" function="child_del_func" schema="" ctx=DDL +STMT: DropStmt +== 398 +-- similar case, but with a self-referencing FK so that parent and child +-- rows can be affected by a single operation + +create temp table self_ref_trigger ( + id int primary key, + parent int references self_ref_trigger, + data text, + nchildren int not null default 0 +) +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: CreateStmt +== 399 +create function self_ref_trigger_ins_func() + returns trigger language plpgsql as +$$ +begin + if new.parent is not null then + update self_ref_trigger set nchildren = nchildren + 1 + where id = new.parent; + end if; + return new; +end; +$$ +-- +FUNCTION: name="self_ref_trigger_ins_func" function="self_ref_trigger_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 400 +create trigger self_ref_trigger_ins_trig before insert on self_ref_trigger + for each row execute procedure self_ref_trigger_ins_func() +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: CreateTrigStmt +== 401 +create function self_ref_trigger_del_func() + returns trigger language plpgsql as +$$ +begin + if old.parent is not null then + update self_ref_trigger set nchildren = nchildren - 1 + where id = old.parent; + end if; + return old; +end; +$$ +-- +FUNCTION: name="self_ref_trigger_del_func" function="self_ref_trigger_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 402 +create trigger self_ref_trigger_del_trig before delete on self_ref_trigger + for each row execute procedure self_ref_trigger_del_func() +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: CreateTrigStmt +== 403 +insert into self_ref_trigger values (1, null, 'root') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 404 +insert into self_ref_trigger values (2, 1, 'root child A') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 405 +insert into self_ref_trigger values (3, 1, 'root child B') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 406 +insert into self_ref_trigger values (4, 2, 'grandchild 1') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 407 +insert into self_ref_trigger values (5, 3, 'grandchild 2') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 408 +update self_ref_trigger set data = 'root!' where id = 1 +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: UpdateStmt +== 409 +select * from self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=Select +STMT: SelectStmt +== 410 +delete from self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: DeleteStmt +== 411 +select * from self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=Select +STMT: SelectStmt +== 412 +drop table self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: DropStmt +== 413 +drop function self_ref_trigger_ins_func() +-- +FUNCTION: name="self_ref_trigger_ins_func" function="self_ref_trigger_ins_func" schema="" ctx=DDL +STMT: DropStmt +== 414 +drop function self_ref_trigger_del_func() +-- +FUNCTION: name="self_ref_trigger_del_func" function="self_ref_trigger_del_func" schema="" ctx=DDL +STMT: DropStmt +== 415 +|-- +-- Check that statement triggers work correctly even with all children excluded +|-- + +create table stmt_trig_on_empty_upd (a int) +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DDL +STMT: CreateStmt +== 416 +create table stmt_trig_on_empty_upd1 () inherits (stmt_trig_on_empty_upd) +-- +TABLE: name="stmt_trig_on_empty_upd1" schema="" table="stmt_trig_on_empty_upd1" ctx=DDL +STMT: CreateStmt +== 417 +create function update_stmt_notice() returns trigger as $$ +begin + raise notice 'updating %', TG_TABLE_NAME; + return null; +end; +$$ language plpgsql +-- +FUNCTION: name="update_stmt_notice" function="update_stmt_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 418 +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd + execute procedure update_stmt_notice() +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DDL +STMT: CreateTrigStmt +== 419 +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd1 + execute procedure update_stmt_notice() +-- +TABLE: name="stmt_trig_on_empty_upd1" schema="" table="stmt_trig_on_empty_upd1" ctx=DDL +STMT: CreateTrigStmt +== 420 +-- inherited no-op update +update stmt_trig_on_empty_upd set a = a where false returning a+1 as aa +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DML +STMT: UpdateStmt +== 421 +-- simple no-op update +update stmt_trig_on_empty_upd1 set a = a where false returning a+1 as aa +-- +TABLE: name="stmt_trig_on_empty_upd1" schema="" table="stmt_trig_on_empty_upd1" ctx=DML +STMT: UpdateStmt +== 422 +drop table stmt_trig_on_empty_upd cascade +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DDL +STMT: DropStmt +== 423 +drop function update_stmt_notice() +-- +FUNCTION: name="update_stmt_notice" function="update_stmt_notice" schema="" ctx=DDL +STMT: DropStmt +== 424 +|-- +-- Check that index creation (or DDL in general) is prohibited in a trigger +|-- + +create table trigger_ddl_table ( + col1 integer, + col2 integer +) +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DDL +STMT: CreateStmt +== 425 +create function trigger_ddl_func() returns trigger as $$ +begin + alter table trigger_ddl_table add primary key (col1); + return new; +end$$ language plpgsql +-- +FUNCTION: name="trigger_ddl_func" function="trigger_ddl_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 426 +create trigger trigger_ddl_func before insert on trigger_ddl_table for each row + execute procedure trigger_ddl_func() +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DDL +STMT: CreateTrigStmt +== 427 +insert into trigger_ddl_table values (1, 42) +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 428 +-- fail + +create or replace function trigger_ddl_func() returns trigger as $$ +begin + create index on trigger_ddl_table (col2); + return new; +end$$ language plpgsql +-- +FUNCTION: name="trigger_ddl_func" function="trigger_ddl_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 429 +insert into trigger_ddl_table values (1, 42) +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 430 +-- fail + +drop table trigger_ddl_table +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DDL +STMT: DropStmt +== 431 +drop function trigger_ddl_func() +-- +FUNCTION: name="trigger_ddl_func" function="trigger_ddl_func" schema="" ctx=DDL +STMT: DropStmt +== 432 +|-- +-- Verify behavior of before and after triggers with INSERT...ON CONFLICT +-- DO UPDATE +|-- +create table upsert (key int4 primary key, color text) +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateStmt +== 433 +create function upsert_before_func() + returns trigger language plpgsql as +$$ +begin + if (TG_OP = 'UPDATE') then + raise warning 'before update (old): %', old.*::text; + raise warning 'before update (new): %', new.*::text; + elsif (TG_OP = 'INSERT') then + raise warning 'before insert (new): %', new.*::text; + if new.key % 2 = 0 then + new.key := new.key + 1; + new.color := new.color || ' trig modified'; + raise warning 'before insert (new, modified): %', new.*::text; + end if; + end if; + return new; +end; +$$ +-- +FUNCTION: name="upsert_before_func" function="upsert_before_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 434 +create trigger upsert_before_trig before insert or update on upsert + for each row execute procedure upsert_before_func() +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateTrigStmt +== 435 +create function upsert_after_func() + returns trigger language plpgsql as +$$ +begin + if (TG_OP = 'UPDATE') then + raise warning 'after update (old): %', old.*::text; + raise warning 'after update (new): %', new.*::text; + elsif (TG_OP = 'INSERT') then + raise warning 'after insert (new): %', new.*::text; + end if; + return null; +end; +$$ +-- +FUNCTION: name="upsert_after_func" function="upsert_after_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 436 +create trigger upsert_after_trig after insert or update on upsert + for each row execute procedure upsert_after_func() +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateTrigStmt +== 437 +insert into upsert values(1, 'black') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 438 +insert into upsert values(2, 'red') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 439 +insert into upsert values(3, 'orange') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 440 +insert into upsert values(4, 'green') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 441 +insert into upsert values(5, 'purple') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 442 +insert into upsert values(6, 'white') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 443 +insert into upsert values(7, 'pink') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 444 +insert into upsert values(8, 'yellow') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 445 +select * from upsert +-- +TABLE: name="upsert" schema="" table="upsert" ctx=Select +STMT: SelectStmt +== 446 +drop table upsert +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: DropStmt +== 447 +drop function upsert_before_func() +-- +FUNCTION: name="upsert_before_func" function="upsert_before_func" schema="" ctx=DDL +STMT: DropStmt +== 448 +drop function upsert_after_func() +-- +FUNCTION: name="upsert_after_func" function="upsert_after_func" schema="" ctx=DDL +STMT: DropStmt +== 449 +|-- +-- Verify that triggers with transition tables are not allowed on +-- views +|-- + +create table my_table (i int) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateStmt +== 450 +create view my_view as select * from my_table +-- +TABLE: name="my_view" schema="" table="my_view" ctx=DDL +TABLE: name="my_table" schema="" table="my_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 451 +create function my_trigger_function() returns trigger as $$ begin end; $$ language plpgsql +-- +FUNCTION: name="my_trigger_function" function="my_trigger_function" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 452 +create trigger my_trigger after update on my_view referencing old table as old_table + for each statement execute procedure my_trigger_function() +-- +TABLE: name="my_view" schema="" table="my_view" ctx=DDL +STMT: CreateTrigStmt +== 453 +drop function my_trigger_function() +-- +FUNCTION: name="my_trigger_function" function="my_trigger_function" schema="" ctx=DDL +STMT: DropStmt +== 454 +drop view my_view +-- +STMT: DropStmt +== 455 +drop table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: DropStmt +== 456 +|-- +-- Verify cases that are unsupported with partitioned tables +|-- +create table parted_trig (a int) partition by list (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +== 457 +create function trigger_nothing() returns trigger + language plpgsql as $$ begin end; $$ +-- +FUNCTION: name="trigger_nothing" function="trigger_nothing" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 458 +create trigger failed instead of update on parted_trig + for each row execute procedure trigger_nothing() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 459 +create trigger failed after update on parted_trig + referencing old table as old_table + for each row execute procedure trigger_nothing() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 460 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +== 461 +|-- +-- Verify trigger creation for partitioned tables, and drop behavior +|-- +create table trigpart (a int, b int) partition by range (a) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateStmt +== 462 +create table trigpart1 partition of trigpart for values from (0) to (1000) +-- +TABLE: name="trigpart1" schema="" table="trigpart1" ctx=DDL +STMT: CreateStmt +== 463 +create trigger trg1 after insert on trigpart for each row execute procedure trigger_nothing() +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateTrigStmt +== 464 +create table trigpart2 partition of trigpart for values from (1000) to (2000) +-- +TABLE: name="trigpart2" schema="" table="trigpart2" ctx=DDL +STMT: CreateStmt +== 465 +create table trigpart3 (like trigpart) +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: CreateStmt +== 466 +alter table trigpart attach partition trigpart3 for values from (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +== 467 +create table trigpart4 partition of trigpart for values from (3000) to (4000) partition by range (a) +-- +TABLE: name="trigpart4" schema="" table="trigpart4" ctx=DDL +STMT: CreateStmt +== 468 +create table trigpart41 partition of trigpart4 for values from (3000) to (3500) +-- +TABLE: name="trigpart41" schema="" table="trigpart41" ctx=DDL +STMT: CreateStmt +== 469 +create table trigpart42 (like trigpart) +-- +TABLE: name="trigpart42" schema="" table="trigpart42" ctx=DDL +STMT: CreateStmt +== 470 +alter table trigpart4 attach partition trigpart42 for values from (3500) to (4000) +-- +TABLE: name="trigpart4" schema="" table="trigpart4" ctx=DDL +STMT: AlterTableStmt +== 471 +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 472 +drop trigger trg1 on trigpart1 +-- +TABLE: name="trigpart1" schema="" table="trigpart1" ctx=DDL +STMT: DropStmt +== 473 +-- fail +drop trigger trg1 on trigpart2 +-- +TABLE: name="trigpart2" schema="" table="trigpart2" ctx=DDL +STMT: DropStmt +== 474 +-- fail +drop trigger trg1 on trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +== 475 +-- fail +drop table trigpart2 +-- +TABLE: name="trigpart2" schema="" table="trigpart2" ctx=DDL +STMT: DropStmt +== 476 +-- ok, trigger should be gone in that partition +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 477 +drop trigger trg1 on trigpart +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: DropStmt +== 478 +-- ok, all gone +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 479 +-- check detach behavior +create trigger trg1 after insert on trigpart for each row execute procedure trigger_nothing() +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateTrigStmt +== 480 +alter table trigpart detach partition trigpart3 +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +== 481 +drop trigger trg1 on trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +== 482 +-- fail due to "does not exist" +alter table trigpart detach partition trigpart4 +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +== 483 +drop trigger trg1 on trigpart41 +-- +TABLE: name="trigpart41" schema="" table="trigpart41" ctx=DDL +STMT: DropStmt +== 484 +-- fail due to "does not exist" +drop table trigpart4 +-- +TABLE: name="trigpart4" schema="" table="trigpart4" ctx=DDL +STMT: DropStmt +== 485 +alter table trigpart attach partition trigpart3 for values from (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +== 486 +alter table trigpart detach partition trigpart3 +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +== 487 +alter table trigpart attach partition trigpart3 for values from (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +== 488 +drop table trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +== 489 +select tgrelid::regclass::text, tgname, tgfoid::regproc, tgenabled, tgisinternal from pg_trigger + where tgname ~ '^trg1' order by 1 +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 490 +create table trigpart3 (like trigpart) +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: CreateStmt +== 491 +create trigger trg1 after insert on trigpart3 for each row execute procedure trigger_nothing() +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: CreateTrigStmt +== 492 +alter table trigpart attach partition trigpart3 FOR VALUES FROM (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +== 493 +-- fail +drop table trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +== 494 +-- check display of unrelated triggers +create trigger samename after delete on trigpart execute function trigger_nothing() +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateTrigStmt +== 495 +create trigger samename after delete on trigpart1 execute function trigger_nothing() +-- +TABLE: name="trigpart1" schema="" table="trigpart1" ctx=DDL +STMT: CreateTrigStmt +== 496 +drop table trigpart +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: DropStmt +== 497 +drop function trigger_nothing() +-- +FUNCTION: name="trigger_nothing" function="trigger_nothing" schema="" ctx=DDL +STMT: DropStmt +== 498 +|-- +-- Verify that triggers are fired for partitioned tables +|-- +create table parted_stmt_trig (a int) partition by list (a) +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateStmt +== 499 +create table parted_stmt_trig1 partition of parted_stmt_trig for values in (1) +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateStmt +== 500 +create table parted_stmt_trig2 partition of parted_stmt_trig for values in (2) +-- +TABLE: name="parted_stmt_trig2" schema="" table="parted_stmt_trig2" ctx=DDL +STMT: CreateStmt +== 501 +create table parted2_stmt_trig (a int) partition by list (a) +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateStmt +== 502 +create table parted2_stmt_trig1 partition of parted2_stmt_trig for values in (1) +-- +TABLE: name="parted2_stmt_trig1" schema="" table="parted2_stmt_trig1" ctx=DDL +STMT: CreateStmt +== 503 +create table parted2_stmt_trig2 partition of parted2_stmt_trig for values in (2) +-- +TABLE: name="parted2_stmt_trig2" schema="" table="parted2_stmt_trig2" ctx=DDL +STMT: CreateStmt +== 504 +create or replace function trigger_notice() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %', TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL; + if TG_LEVEL = 'ROW' then + return NEW; + end if; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice" function="trigger_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 505 +-- insert/update/delete statement-level triggers on the parent +create trigger trig_ins_before before insert on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 506 +create trigger trig_ins_after after insert on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 507 +create trigger trig_upd_before before update on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 508 +create trigger trig_upd_after after update on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 509 +create trigger trig_del_before before delete on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 510 +create trigger trig_del_after after delete on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 511 +-- insert/update/delete row-level triggers on the parent +create trigger trig_ins_after_parent after insert on parted_stmt_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 512 +create trigger trig_upd_after_parent after update on parted_stmt_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 513 +create trigger trig_del_after_parent after delete on parted_stmt_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 514 +-- insert/update/delete row-level triggers on the first partition +create trigger trig_ins_before_child before insert on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +== 515 +create trigger trig_ins_after_child after insert on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +== 516 +create trigger trig_upd_before_child before update on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +== 517 +create trigger trig_upd_after_child after update on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +== 518 +create trigger trig_del_before_child before delete on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +== 519 +create trigger trig_del_after_child after delete on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +== 520 +-- insert/update/delete statement-level triggers on the parent +create trigger trig_ins_before_3 before insert on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 521 +create trigger trig_ins_after_3 after insert on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 522 +create trigger trig_upd_before_3 before update on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 523 +create trigger trig_upd_after_3 after update on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 524 +create trigger trig_del_before_3 before delete on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 525 +create trigger trig_del_after_3 after delete on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +== 526 +with ins (a) as ( + insert into parted2_stmt_trig values (1), (2) returning a +) insert into parted_stmt_trig select a from ins returning tableoid::regclass, a +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DML +CTE: "ins" +STMT: InsertStmt +STMT: SelectStmt +== 527 +with upd as ( + update parted2_stmt_trig set a = a +) update parted_stmt_trig set a = a +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DML +CTE: "upd" +STMT: UpdateStmt +== 528 +delete from parted_stmt_trig +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +STMT: DeleteStmt +== 529 +-- insert via copy on the parent +copy parted_stmt_trig(a) from stdin +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=Select +STMT: CopyStmt +== 530 +-- insert via copy on the first partition +copy parted_stmt_trig1(a) from stdin +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=Select +STMT: CopyStmt +== 531 +-- Disabling a trigger in the parent table should disable children triggers too +alter table parted_stmt_trig disable trigger trig_ins_after_parent +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: AlterTableStmt +== 532 +insert into parted_stmt_trig values (1) +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 533 +alter table parted_stmt_trig enable trigger trig_ins_after_parent +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: AlterTableStmt +== 534 +insert into parted_stmt_trig values (1) +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 535 +drop table parted_stmt_trig, parted2_stmt_trig +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: DropStmt +== 536 +-- Verify that triggers fire in alphabetical order +create table parted_trig (a int) partition by range (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +== 537 +create table parted_trig_1 partition of parted_trig for values from (0) to (1000) + partition by range (a) +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateStmt +== 538 +create table parted_trig_1_1 partition of parted_trig_1 for values from (0) to (100) +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateStmt +== 539 +create table parted_trig_2 partition of parted_trig for values from (1000) to (2000) +-- +TABLE: name="parted_trig_2" schema="" table="parted_trig_2" ctx=DDL +STMT: CreateStmt +== 540 +create trigger zzz after insert on parted_trig for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 541 +create trigger mmm after insert on parted_trig_1_1 for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateTrigStmt +== 542 +create trigger aaa after insert on parted_trig_1 for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateTrigStmt +== 543 +create trigger bbb after insert on parted_trig for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 544 +create trigger qqq after insert on parted_trig_1_1 for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateTrigStmt +== 545 +insert into parted_trig values (50), (1500) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 546 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +== 547 +-- Verify that the correct triggers fire for cross-partition updates +create table parted_trig (a int) partition by list (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +== 548 +create table parted_trig1 partition of parted_trig for values in (1) +-- +TABLE: name="parted_trig1" schema="" table="parted_trig1" ctx=DDL +STMT: CreateStmt +== 549 +create table parted_trig2 partition of parted_trig for values in (2) +-- +TABLE: name="parted_trig2" schema="" table="parted_trig2" ctx=DDL +STMT: CreateStmt +== 550 +insert into parted_trig values (1) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 551 +create or replace function trigger_notice() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %', TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL; + if TG_LEVEL = 'ROW' then + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; + end if; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice" function="trigger_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 552 +create trigger parted_trig_before_stmt before insert or update or delete on parted_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 553 +create trigger parted_trig_before_row before insert or update or delete on parted_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 554 +create trigger parted_trig_after_row after insert or update or delete on parted_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 555 +create trigger parted_trig_after_stmt after insert or update or delete on parted_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 556 +update parted_trig set a = 2 where a = 1 +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: UpdateStmt +== 557 +-- update action in merge should behave the same +merge into parted_trig using (select 1) as ss on true + when matched and a = 2 then update set a = 1 +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: MergeStmt +STMT: SelectStmt +== 558 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +== 559 +-- Verify propagation of trigger arguments to partitions +create table parted_trig (a int) partition by list (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +== 560 +create table parted_trig1 partition of parted_trig for values in (1) +-- +TABLE: name="parted_trig1" schema="" table="parted_trig1" ctx=DDL +STMT: CreateStmt +== 561 +create or replace function trigger_notice() returns trigger as $$ + declare + arg1 text = TG_ARGV[0]; + arg2 integer = TG_ARGV[1]; + begin + raise notice 'trigger % on % % % for % args % %', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, arg1, arg2; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice" function="trigger_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 562 +create trigger aaa after insert on parted_trig + for each row execute procedure trigger_notice('quirky', 1) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 563 +-- Verify propagation of trigger arguments to partitions attached after creating trigger +create table parted_trig2 partition of parted_trig for values in (2) +-- +TABLE: name="parted_trig2" schema="" table="parted_trig2" ctx=DDL +STMT: CreateStmt +== 564 +create table parted_trig3 (like parted_trig) +-- +TABLE: name="parted_trig3" schema="" table="parted_trig3" ctx=DDL +STMT: CreateStmt +== 565 +alter table parted_trig attach partition parted_trig3 for values in (3) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: AlterTableStmt +== 566 +insert into parted_trig values (1), (2), (3) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 567 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +== 568 +-- test irregular partitions (i.e., different column definitions), +-- including that the WHEN clause works +create function bark(text) returns bool language plpgsql immutable + as $$ begin raise notice '% <- woof!', $1; return true; end; $$ +-- +FUNCTION: name="bark" function="bark" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 569 +create or replace function trigger_notice_ab() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %: (a,b)=(%,%)', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, + NEW.a, NEW.b; + if TG_LEVEL = 'ROW' then + return NEW; + end if; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice_ab" function="trigger_notice_ab" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 570 +create table parted_irreg_ancestor (fd text, b text, fd2 int, fd3 int, a int) + partition by range (b) +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: CreateStmt +== 571 +alter table parted_irreg_ancestor drop column fd, + drop column fd2, drop column fd3 +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: AlterTableStmt +== 572 +create table parted_irreg (fd int, a int, fd2 int, b text) + partition by range (b) +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: CreateStmt +== 573 +alter table parted_irreg drop column fd, drop column fd2 +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: AlterTableStmt +== 574 +alter table parted_irreg_ancestor attach partition parted_irreg + for values from ('aaaa') to ('zzzz') +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: AlterTableStmt +== 575 +create table parted1_irreg (b text, fd int, a int) +-- +TABLE: name="parted1_irreg" schema="" table="parted1_irreg" ctx=DDL +STMT: CreateStmt +== 576 +alter table parted1_irreg drop column fd +-- +TABLE: name="parted1_irreg" schema="" table="parted1_irreg" ctx=DDL +STMT: AlterTableStmt +== 577 +alter table parted_irreg attach partition parted1_irreg + for values from ('aaaa') to ('bbbb') +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: AlterTableStmt +== 578 +create trigger parted_trig after insert on parted_irreg + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: CreateTrigStmt +== 579 +create trigger parted_trig_odd after insert on parted_irreg for each row + when (bark(new.b) AND new.a % 2 = 1) execute procedure trigger_notice_ab() +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: CreateTrigStmt +== 580 +-- we should hear barking for every insert, but parted_trig_odd only emits +-- noise for odd values of a. parted_trig does it for all inserts. +insert into parted_irreg values (1, 'aardvark'), (2, 'aanimals') +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 581 +insert into parted1_irreg values ('aardwolf', 2) +-- +TABLE: name="parted1_irreg" schema="" table="parted1_irreg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 582 +insert into parted_irreg_ancestor values ('aasvogel', 3) +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 583 +drop table parted_irreg_ancestor +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: DropStmt +== 584 +-- Before triggers and partitions +create table parted (a int, b int, c text) partition by list (a) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateStmt +== 585 +create table parted_1 partition of parted for values in (1) + partition by list (b) +-- +TABLE: name="parted_1" schema="" table="parted_1" ctx=DDL +STMT: CreateStmt +== 586 +create table parted_1_1 partition of parted_1 for values in (1) +-- +TABLE: name="parted_1_1" schema="" table="parted_1_1" ctx=DDL +STMT: CreateStmt +== 587 +create function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.a = new.a + 1; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 588 +insert into parted values (1, 1, 'uno uno v1') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 589 +-- works +create trigger t before insert or update or delete on parted + for each row execute function parted_trigfunc() +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateTrigStmt +== 590 +insert into parted values (1, 1, 'uno uno v2') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 591 +-- fail +update parted set c = c || 'v3' +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +== 592 +-- fail +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.b = new.b + 1; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 593 +insert into parted values (1, 1, 'uno uno v4') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 594 +-- fail +update parted set c = c || 'v5' +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +== 595 +-- fail +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.c = new.c || ' did '|| TG_OP; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 596 +insert into parted values (1, 1, 'uno uno') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 597 +-- works +update parted set c = c || ' v6' +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +== 598 +-- works +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +== 599 +-- update itself moves tuple to new partition; trigger still works +truncate table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: TruncateStmt +== 600 +create table parted_2 partition of parted for values in (2) +-- +TABLE: name="parted_2" schema="" table="parted_2" ctx=DDL +STMT: CreateStmt +== 601 +insert into parted values (1, 1, 'uno uno v5') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 602 +update parted set a = 2 +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +== 603 +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +== 604 +-- both trigger and update change the partition +create or replace function parted_trigfunc2() returns trigger language plpgsql as $$ +begin + new.a = new.a + 1; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc2" function="parted_trigfunc2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 605 +create trigger t2 before update on parted + for each row execute function parted_trigfunc2() +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateTrigStmt +== 606 +truncate table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: TruncateStmt +== 607 +insert into parted values (1, 1, 'uno uno v6') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 608 +create table parted_3 partition of parted for values in (3) +-- +TABLE: name="parted_3" schema="" table="parted_3" ctx=DDL +STMT: CreateStmt +== 609 +update parted set a = a + 1 +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +== 610 +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +== 611 +-- there's no partition for a=0, but this update works anyway because +-- the trigger causes the tuple to be routed to another partition +update parted set a = 0 +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +== 612 +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +== 613 +drop table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: DropStmt +== 614 +create table parted (a int, b int, c text) partition by list ((a + b)) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateStmt +== 615 +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.a = new.a + new.b; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 616 +create table parted_1 partition of parted for values in (1, 2) +-- +TABLE: name="parted_1" schema="" table="parted_1" ctx=DDL +STMT: CreateStmt +== 617 +create table parted_2 partition of parted for values in (3, 4) +-- +TABLE: name="parted_2" schema="" table="parted_2" ctx=DDL +STMT: CreateStmt +== 618 +create trigger t before insert or update on parted + for each row execute function parted_trigfunc() +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateTrigStmt +== 619 +insert into parted values (0, 1, 'zero win') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 620 +insert into parted values (1, 1, 'one fail') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 621 +insert into parted values (1, 2, 'two fail') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 622 +select * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +== 623 +drop table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: DropStmt +== 624 +drop function parted_trigfunc() +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: DropStmt +== 625 +|-- +-- Constraint triggers and partitioned tables +create table parted_constr_ancestor (a int, b text) + partition by range (b) +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: CreateStmt +== 626 +create table parted_constr (a int, b text) + partition by range (b) +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DDL +STMT: CreateStmt +== 627 +alter table parted_constr_ancestor attach partition parted_constr + for values from ('aaaa') to ('zzzz') +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: AlterTableStmt +== 628 +create table parted1_constr (a int, b text) +-- +TABLE: name="parted1_constr" schema="" table="parted1_constr" ctx=DDL +STMT: CreateStmt +== 629 +alter table parted_constr attach partition parted1_constr + for values from ('aaaa') to ('bbbb') +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DDL +STMT: AlterTableStmt +== 630 +create constraint trigger parted_trig after insert on parted_constr_ancestor + deferrable + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: CreateTrigStmt +== 631 +create constraint trigger parted_trig_two after insert on parted_constr + deferrable initially deferred + for each row when (bark(new.b) AND new.a % 2 = 1) + execute procedure trigger_notice_ab() +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DDL +STMT: CreateTrigStmt +== 632 +-- The immediate constraint is fired immediately; the WHEN clause of the +-- deferred constraint is also called immediately. The deferred constraint +-- is fired at commit time. +begin +-- +STMT: TransactionStmt +== 633 +insert into parted_constr values (1, 'aardvark') +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 634 +insert into parted1_constr values (2, 'aardwolf') +-- +TABLE: name="parted1_constr" schema="" table="parted1_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 635 +insert into parted_constr_ancestor values (3, 'aasvogel') +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 636 +commit +-- +STMT: TransactionStmt +== 637 +-- The WHEN clause is immediate, and both constraint triggers are fired at +-- commit time. +begin +-- +STMT: TransactionStmt +== 638 +set constraints parted_trig deferred +-- +STMT: ConstraintsSetStmt +== 639 +insert into parted_constr values (1, 'aardvark') +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 640 +insert into parted1_constr values (2, 'aardwolf'), (3, 'aasvogel') +-- +TABLE: name="parted1_constr" schema="" table="parted1_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 641 +commit +-- +STMT: TransactionStmt +== 642 +drop table parted_constr_ancestor +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: DropStmt +== 643 +drop function bark(text) +-- +FUNCTION: name="bark" function="bark" schema="" ctx=DDL +STMT: DropStmt +== 644 +-- Test that the WHEN clause is set properly to partitions +create table parted_trigger (a int, b text) partition by range (a) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateStmt +== 645 +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000) +-- +TABLE: name="parted_trigger_1" schema="" table="parted_trigger_1" ctx=DDL +STMT: CreateStmt +== 646 +create table parted_trigger_2 (drp int, a int, b text) +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: CreateStmt +== 647 +alter table parted_trigger_2 drop column drp +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: AlterTableStmt +== 648 +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +== 649 +create trigger parted_trigger after update on parted_trigger + for each row when (new.a % 2 = 1 and length(old.b) >= 2) execute procedure trigger_notice_ab() +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateTrigStmt +== 650 +create table parted_trigger_3 (b text, a int) partition by range (length(b)) +-- +TABLE: name="parted_trigger_3" schema="" table="parted_trigger_3" ctx=DDL +STMT: CreateStmt +== 651 +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (3) +-- +TABLE: name="parted_trigger_3_1" schema="" table="parted_trigger_3_1" ctx=DDL +STMT: CreateStmt +== 652 +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (3) to (5) +-- +TABLE: name="parted_trigger_3_2" schema="" table="parted_trigger_3_2" ctx=DDL +STMT: CreateStmt +== 653 +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +== 654 +insert into parted_trigger values + (0, 'a'), (1, 'bbb'), (2, 'bcd'), (3, 'c'), + (1000, 'c'), (1001, 'ddd'), (1002, 'efg'), (1003, 'f'), + (2000, 'e'), (2001, 'fff'), (2002, 'ghi'), (2003, 'h') +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 655 +update parted_trigger set a = a + 2 +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: UpdateStmt +== 656 +-- notice for odd 'a' values, long 'b' values +drop table parted_trigger +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: DropStmt +== 657 +-- try a constraint trigger, also +create table parted_referenced (a int) +-- +TABLE: name="parted_referenced" schema="" table="parted_referenced" ctx=DDL +STMT: CreateStmt +== 658 +create table unparted_trigger (a int, b text) +-- +TABLE: name="unparted_trigger" schema="" table="unparted_trigger" ctx=DDL +STMT: CreateStmt +== 659 +-- for comparison purposes +create table parted_trigger (a int, b text) partition by range (a) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateStmt +== 660 +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000) +-- +TABLE: name="parted_trigger_1" schema="" table="parted_trigger_1" ctx=DDL +STMT: CreateStmt +== 661 +create table parted_trigger_2 (drp int, a int, b text) +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: CreateStmt +== 662 +alter table parted_trigger_2 drop column drp +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: AlterTableStmt +== 663 +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +== 664 +create constraint trigger parted_trigger after update on parted_trigger + from parted_referenced + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateTrigStmt +== 665 +create constraint trigger parted_trigger after update on unparted_trigger + from parted_referenced + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="unparted_trigger" schema="" table="unparted_trigger" ctx=DDL +STMT: CreateTrigStmt +== 666 +create table parted_trigger_3 (b text, a int) partition by range (length(b)) +-- +TABLE: name="parted_trigger_3" schema="" table="parted_trigger_3" ctx=DDL +STMT: CreateStmt +== 667 +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (3) +-- +TABLE: name="parted_trigger_3_1" schema="" table="parted_trigger_3_1" ctx=DDL +STMT: CreateStmt +== 668 +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (3) to (5) +-- +TABLE: name="parted_trigger_3_2" schema="" table="parted_trigger_3_2" ctx=DDL +STMT: CreateStmt +== 669 +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +== 670 +select tgname, conname, t.tgrelid::regclass, t.tgconstrrelid::regclass, + c.conrelid::regclass, c.confrelid::regclass + from pg_trigger t join pg_constraint c on (t.tgconstraint = c.oid) + where tgname = 'parted_trigger' + order by t.tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "t"="pg_trigger" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +== 671 +drop table parted_referenced, parted_trigger, unparted_trigger +-- +TABLE: name="parted_referenced" schema="" table="parted_referenced" ctx=DDL +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +TABLE: name="unparted_trigger" schema="" table="unparted_trigger" ctx=DDL +STMT: DropStmt +== 672 +-- verify that the "AFTER UPDATE OF columns" event is propagated correctly +create table parted_trigger (a int, b text) partition by range (a) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateStmt +== 673 +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000) +-- +TABLE: name="parted_trigger_1" schema="" table="parted_trigger_1" ctx=DDL +STMT: CreateStmt +== 674 +create table parted_trigger_2 (drp int, a int, b text) +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: CreateStmt +== 675 +alter table parted_trigger_2 drop column drp +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: AlterTableStmt +== 676 +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +== 677 +create trigger parted_trigger after update of b on parted_trigger + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateTrigStmt +== 678 +create table parted_trigger_3 (b text, a int) partition by range (length(b)) +-- +TABLE: name="parted_trigger_3" schema="" table="parted_trigger_3" ctx=DDL +STMT: CreateStmt +== 679 +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (4) +-- +TABLE: name="parted_trigger_3_1" schema="" table="parted_trigger_3_1" ctx=DDL +STMT: CreateStmt +== 680 +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (4) to (8) +-- +TABLE: name="parted_trigger_3_2" schema="" table="parted_trigger_3_2" ctx=DDL +STMT: CreateStmt +== 681 +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +== 682 +insert into parted_trigger values (0, 'a'), (1000, 'c'), (2000, 'e'), (2001, 'eeee') +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 683 +update parted_trigger set a = a + 2 +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: UpdateStmt +== 684 +-- no notices here +update parted_trigger set b = b || 'b' +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: UpdateStmt +== 685 +-- all triggers should fire +drop table parted_trigger +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: DropStmt +== 686 +drop function trigger_notice_ab() +-- +FUNCTION: name="trigger_notice_ab" function="trigger_notice_ab" schema="" ctx=DDL +STMT: DropStmt +== 687 +-- Make sure we don't end up with unnecessary copies of triggers, when +-- cloning them. +create table trg_clone (a int) partition by range (a) +-- +TABLE: name="trg_clone" schema="" table="trg_clone" ctx=DDL +STMT: CreateStmt +== 688 +create table trg_clone1 partition of trg_clone for values from (0) to (1000) +-- +TABLE: name="trg_clone1" schema="" table="trg_clone1" ctx=DDL +STMT: CreateStmt +== 689 +alter table trg_clone add constraint uniq unique (a) deferrable +-- +TABLE: name="trg_clone" schema="" table="trg_clone" ctx=DDL +STMT: AlterTableStmt +== 690 +create table trg_clone2 partition of trg_clone for values from (1000) to (2000) +-- +TABLE: name="trg_clone2" schema="" table="trg_clone2" ctx=DDL +STMT: CreateStmt +== 691 +create table trg_clone3 partition of trg_clone for values from (2000) to (3000) + partition by range (a) +-- +TABLE: name="trg_clone3" schema="" table="trg_clone3" ctx=DDL +STMT: CreateStmt +== 692 +create table trg_clone_3_3 partition of trg_clone3 for values from (2000) to (2100) +-- +TABLE: name="trg_clone_3_3" schema="" table="trg_clone_3_3" ctx=DDL +STMT: CreateStmt +== 693 +select tgrelid::regclass, count(*) from pg_trigger + where tgrelid::regclass in ('trg_clone', 'trg_clone1', 'trg_clone2', + 'trg_clone3', 'trg_clone_3_3') + group by tgrelid::regclass order by tgrelid::regclass +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 694 +drop table trg_clone +-- +TABLE: name="trg_clone" schema="" table="trg_clone" ctx=DDL +STMT: DropStmt +== 695 +-- Test the interaction between ALTER TABLE .. DISABLE TRIGGER and +-- both kinds of inheritance. Historically, legacy inheritance has +-- not recursed to children, so that behavior is preserved. +create table parent (a int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 696 +create table child1 () inherits (parent) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +== 697 +create function trig_nothing() returns trigger language plpgsql + as $$ begin return null; end $$ +-- +FUNCTION: name="trig_nothing" function="trig_nothing" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 698 +create trigger tg after insert on parent + for each row execute function trig_nothing() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 699 +create trigger tg after insert on child1 + for each row execute function trig_nothing() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +== 700 +alter table parent disable trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 701 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 702 +alter table only parent enable always trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 703 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 704 +drop table parent, child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 705 +create table parent (a int) partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 706 +create table child1 partition of parent for values in (1) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +== 707 +create trigger tg after insert on parent + for each row execute procedure trig_nothing() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 708 +create trigger tg_stmt after insert on parent + for statement execute procedure trig_nothing() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 709 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 710 +alter table only parent enable always trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 711 +-- no recursion because ONLY +alter table parent enable always trigger tg_stmt +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 712 +-- no recursion because statement trigger +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 713 +-- The following is a no-op for the parent trigger but not so +-- for the child trigger, so recursion should be applied. +alter table parent enable always trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 714 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 715 +-- This variant malfunctioned in some releases. +alter table parent disable trigger user +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 716 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 717 +drop table parent, child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 718 +-- Check processing of foreign key triggers +create table parent (a int primary key, f int references parent) + partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 719 +create table child1 partition of parent for values in (1) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +== 720 +select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname, + tgfoid::regproc, tgenabled + from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgfoid +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="rtrim" function="rtrim" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 721 +alter table parent disable trigger all +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 722 +select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname, + tgfoid::regproc, tgenabled + from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgfoid +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="rtrim" function="rtrim" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +== 723 +drop table parent, child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 724 +-- Verify that firing state propagates correctly on creation, too +CREATE TABLE trgfire (i int) PARTITION BY RANGE (i) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: CreateStmt +== 725 +CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10) +-- +TABLE: name="trgfire1" schema="" table="trgfire1" ctx=DDL +STMT: CreateStmt +== 726 +CREATE OR REPLACE FUNCTION tgf() RETURNS trigger LANGUAGE plpgsql + AS $$ begin raise exception 'except'; end $$ +-- +FUNCTION: name="tgf" function="tgf" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 727 +CREATE TRIGGER tg AFTER INSERT ON trgfire FOR EACH ROW EXECUTE FUNCTION tgf() +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: CreateTrigStmt +== 728 +INSERT INTO trgfire VALUES (1) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 729 +ALTER TABLE trgfire DISABLE TRIGGER tg +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +== 730 +INSERT INTO trgfire VALUES (1) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 731 +CREATE TABLE trgfire2 PARTITION OF trgfire FOR VALUES FROM (10) TO (20) +-- +TABLE: name="trgfire2" schema="" table="trgfire2" ctx=DDL +STMT: CreateStmt +== 732 +INSERT INTO trgfire VALUES (11) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 733 +CREATE TABLE trgfire3 (LIKE trgfire) +-- +TABLE: name="trgfire3" schema="" table="trgfire3" ctx=DDL +STMT: CreateStmt +== 734 +ALTER TABLE trgfire ATTACH PARTITION trgfire3 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +== 735 +INSERT INTO trgfire VALUES (21) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 736 +CREATE TABLE trgfire4 PARTITION OF trgfire FOR VALUES FROM (30) TO (40) PARTITION BY LIST (i) +-- +TABLE: name="trgfire4" schema="" table="trgfire4" ctx=DDL +STMT: CreateStmt +== 737 +CREATE TABLE trgfire4_30 PARTITION OF trgfire4 FOR VALUES IN (30) +-- +TABLE: name="trgfire4_30" schema="" table="trgfire4_30" ctx=DDL +STMT: CreateStmt +== 738 +INSERT INTO trgfire VALUES (30) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 739 +CREATE TABLE trgfire5 (LIKE trgfire) PARTITION BY LIST (i) +-- +TABLE: name="trgfire5" schema="" table="trgfire5" ctx=DDL +STMT: CreateStmt +== 740 +CREATE TABLE trgfire5_40 PARTITION OF trgfire5 FOR VALUES IN (40) +-- +TABLE: name="trgfire5_40" schema="" table="trgfire5_40" ctx=DDL +STMT: CreateStmt +== 741 +ALTER TABLE trgfire ATTACH PARTITION trgfire5 FOR VALUES FROM (40) TO (50) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +== 742 +INSERT INTO trgfire VALUES (40) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 743 +SELECT tgrelid::regclass, tgenabled FROM pg_trigger + WHERE tgrelid::regclass IN (SELECT oid from pg_class where relname LIKE 'trgfire%') + ORDER BY tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 744 +ALTER TABLE trgfire ENABLE TRIGGER tg +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +== 745 +INSERT INTO trgfire VALUES (1) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 746 +INSERT INTO trgfire VALUES (11) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 747 +INSERT INTO trgfire VALUES (21) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 748 +INSERT INTO trgfire VALUES (30) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 749 +INSERT INTO trgfire VALUES (40) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 750 +DROP TABLE trgfire +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: DropStmt +== 751 +DROP FUNCTION tgf() +-- +FUNCTION: name="tgf" function="tgf" schema="" ctx=DDL +STMT: DropStmt +== 752 +|-- +-- Test the interaction between transition tables and both kinds of +-- inheritance. We'll dump the contents of the transition tables in a +-- format that shows the attribute order, so that we can distinguish +-- tuple formats (though not dropped attributes). +|-- + +create or replace function dump_insert() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, new table = %', + TG_NAME, + (select string_agg(new_table::text, ', ' order by a) from new_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_insert" function="dump_insert" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 753 +create or replace function dump_update() 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; +$$ +-- +FUNCTION: name="dump_update" function="dump_update" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 754 +create or replace function dump_delete() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, old table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by a) from old_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_delete" function="dump_delete" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 755 +|-- +-- Verify behavior of statement triggers on partition hierarchy with +-- transition tables. Tuples should appear to each trigger in the +-- format of the relation the trigger is attached to. +|-- + +-- set up a partition hierarchy with some different TupleDescriptors +create table parent (a text, b int) partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 756 +-- a child matching parent +create table child1 partition of parent for values in ('AAA') +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +== 757 +-- a child with a dropped column +create table child2 (x int, a text, b int) +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateStmt +== 758 +alter table child2 drop column x +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: AlterTableStmt +== 759 +alter table parent attach partition child2 for values in ('BBB') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 760 +-- a child with a different column order +create table child3 (b int, a text) +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateStmt +== 761 +alter table parent attach partition child3 for values in ('CCC') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 762 +create trigger parent_insert_trig + after insert on parent referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 763 +create trigger parent_update_trig + after update on parent referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 764 +create trigger parent_delete_trig + after delete on parent referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 765 +create trigger child1_insert_trig + after insert on child1 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +== 766 +create trigger child1_update_trig + after update on child1 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +== 767 +create trigger child1_delete_trig + after delete on child1 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +== 768 +create trigger child2_insert_trig + after insert on child2 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +== 769 +create trigger child2_update_trig + after update on child2 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +== 770 +create trigger child2_delete_trig + after delete on child2 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +== 771 +create trigger child3_insert_trig + after insert on child3 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +== 772 +create trigger child3_update_trig + after update on child3 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +== 773 +create trigger child3_delete_trig + after delete on child3 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +== 774 +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table IN ('parent', 'child1', 'child2', 'child3') + ORDER BY trigger_name COLLATE "C", 2 +-- +TABLE: name="information_schema.triggers" schema="information_schema" table="triggers" ctx=Select +FILTER: schema="" table="" column="event_object_table" +STMT: SelectStmt +== 775 +-- insert directly into children sees respective child-format tuples +insert into child1 values ('AAA', 42) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 776 +insert into child2 values ('BBB', 42) +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 777 +insert into child3 values (42, 'CCC') +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 778 +-- update via parent sees parent-format tuples +update parent set b = b + 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +== 779 +-- delete via parent sees parent-format tuples +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +== 780 +-- insert into parent sees parent-format tuples +insert into parent values ('AAA', 42) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 781 +insert into parent values ('BBB', 42) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 782 +insert into parent values ('CCC', 42) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 783 +-- delete from children sees respective child-format tuples +delete from child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: DeleteStmt +== 784 +delete from child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: DeleteStmt +== 785 +delete from child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: DeleteStmt +== 786 +-- copy into parent sees parent-format tuples +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +== 787 +-- check detach/reattach behavior; statement triggers with transition tables +-- should not prevent a table from becoming a partition again +alter table parent detach partition child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 788 +alter table parent attach partition child1 for values in ('AAA') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 789 +-- DML affecting parent sees tuples collected from children even if +-- there is no transition table trigger on the children +drop trigger child1_insert_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 790 +drop trigger child1_update_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 791 +drop trigger child1_delete_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 792 +drop trigger child2_insert_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +== 793 +drop trigger child2_update_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +== 794 +drop trigger child2_delete_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +== 795 +drop trigger child3_insert_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +== 796 +drop trigger child3_update_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +== 797 +drop trigger child3_delete_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +== 798 +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +== 799 +-- copy into parent sees tuples collected from children even if there +-- is no transition-table trigger on the children +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +== 800 +-- insert into parent with a before trigger on a child tuple before +-- insertion, and we capture the newly modified row in parent format +create or replace function intercept_insert() returns trigger language plpgsql as +$$ + begin + new.b = new.b + 1000; + return new; + end; +$$ +-- +FUNCTION: name="intercept_insert" function="intercept_insert" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 801 +create trigger intercept_insert_child3 + before insert on child3 + for each row execute procedure intercept_insert() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +== 802 +-- insert, parent trigger sees post-modification parent-format tuple +insert into parent values ('AAA', 42), ('BBB', 42), ('CCC', 66) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 803 +-- copy, parent trigger sees post-modification parent-format tuple +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +== 804 +drop table child1, child2, child3, parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +TABLE: name="child2" schema="" table="child2" ctx=DDL +TABLE: name="child3" schema="" table="child3" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 805 +drop function intercept_insert() +-- +FUNCTION: name="intercept_insert" function="intercept_insert" schema="" ctx=DDL +STMT: DropStmt +== 806 +|-- +-- Verify prohibition of row triggers with transition triggers on +-- partitions +|-- +create table parent (a text, b int) partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 807 +create table child partition of parent for values in ('AAA') +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 808 +-- adding row trigger with transition table fails +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +== 809 +-- detaching it first works +alter table parent detach partition child +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 810 +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +== 811 +-- but now we're not allowed to reattach it +alter table parent attach partition child for values in ('AAA') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 812 +-- drop the trigger, and now we're allowed to attach it again +drop trigger child_row_trig on child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 813 +alter table parent attach partition child for values in ('AAA') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +== 814 +drop table child, parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 815 +|-- +-- Verify access of transition tables with UPDATE triggers and tuples +-- moved across partitions. +|-- +create or replace function dump_update_new() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, new table = %', TG_NAME, + (select string_agg(new_table::text, ', ' order by a) from new_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_update_new" function="dump_update_new" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 816 +create or replace function dump_update_old() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, old table = %', TG_NAME, + (select string_agg(old_table::text, ', ' order by a) from old_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_update_old" function="dump_update_old" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 817 +create table trans_tab_parent (a text) partition by list (a) +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateStmt +== 818 +create table trans_tab_child1 partition of trans_tab_parent for values in ('AAA1', 'AAA2') +-- +TABLE: name="trans_tab_child1" schema="" table="trans_tab_child1" ctx=DDL +STMT: CreateStmt +== 819 +create table trans_tab_child2 partition of trans_tab_parent for values in ('BBB1', 'BBB2') +-- +TABLE: name="trans_tab_child2" schema="" table="trans_tab_child2" ctx=DDL +STMT: CreateStmt +== 820 +create trigger trans_tab_parent_update_trig + after update on trans_tab_parent referencing old table as old_table + for each statement execute procedure dump_update_old() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +== 821 +create trigger trans_tab_parent_insert_trig + after insert on trans_tab_parent referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +== 822 +create trigger trans_tab_parent_delete_trig + after delete on trans_tab_parent referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +== 823 +insert into trans_tab_parent values ('AAA1'), ('BBB1') +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 824 +-- should not trigger access to new table when moving across partitions. +update trans_tab_parent set a = 'BBB2' where a = 'AAA1' +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: UpdateStmt +== 825 +drop trigger trans_tab_parent_update_trig on trans_tab_parent +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: DropStmt +== 826 +create trigger trans_tab_parent_update_trig + after update on trans_tab_parent referencing new table as new_table + for each statement execute procedure dump_update_new() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +== 827 +-- should not trigger access to old table when moving across partitions. +update trans_tab_parent set a = 'AAA2' where a = 'BBB1' +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: UpdateStmt +== 828 +delete from trans_tab_parent +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: DeleteStmt +== 829 +-- clean up +drop table trans_tab_parent, trans_tab_child1, trans_tab_child2 +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +TABLE: name="trans_tab_child1" schema="" table="trans_tab_child1" ctx=DDL +TABLE: name="trans_tab_child2" schema="" table="trans_tab_child2" ctx=DDL +STMT: DropStmt +== 830 +drop function dump_update_new, dump_update_old +-- +FUNCTION: name="dump_update_new" function="dump_update_new" schema="" ctx=DDL +STMT: DropStmt +== 831 +|-- +-- Verify behavior of statement triggers on (non-partition) +-- inheritance hierarchy with transition tables; similar to the +-- partition case, except there is no rerouting on insertion and child +-- tables can have extra columns +|-- + +-- set up inheritance hierarchy with different TupleDescriptors +create table parent (a text, b int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 832 +-- a child matching parent +create table child1 () inherits (parent) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +== 833 +-- a child with a different column order +create table child2 (b int, a text) +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateStmt +== 834 +alter table child2 inherit parent +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: AlterTableStmt +== 835 +-- a child with an extra column +create table child3 (c text) inherits (parent) +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateStmt +== 836 +create trigger parent_insert_trig + after insert on parent referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 837 +create trigger parent_update_trig + after update on parent referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 838 +create trigger parent_delete_trig + after delete on parent referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 839 +create trigger child1_insert_trig + after insert on child1 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +== 840 +create trigger child1_update_trig + after update on child1 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +== 841 +create trigger child1_delete_trig + after delete on child1 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +== 842 +create trigger child2_insert_trig + after insert on child2 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +== 843 +create trigger child2_update_trig + after update on child2 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +== 844 +create trigger child2_delete_trig + after delete on child2 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +== 845 +create trigger child3_insert_trig + after insert on child3 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +== 846 +create trigger child3_update_trig + after update on child3 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +== 847 +create trigger child3_delete_trig + after delete on child3 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +== 848 +-- insert directly into children sees respective child-format tuples +insert into child1 values ('AAA', 42) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 849 +insert into child2 values (42, 'BBB') +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 850 +insert into child3 values ('CCC', 42, 'foo') +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 851 +-- update via parent sees parent-format tuples +update parent set b = b + 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +== 852 +-- delete via parent sees parent-format tuples +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +== 853 +-- reinsert values into children for next test... +insert into child1 values ('AAA', 42) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 854 +insert into child2 values (42, 'BBB') +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 855 +insert into child3 values ('CCC', 42, 'foo') +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 856 +-- delete from children sees respective child-format tuples +delete from child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: DeleteStmt +== 857 +delete from child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: DeleteStmt +== 858 +delete from child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: DeleteStmt +== 859 +-- copy into parent sees parent-format tuples (no rerouting, so these +-- are really inserted into the parent) +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +== 860 +-- same behavior for copy if there is an index (interesting because rows are +-- captured by a different code path in copyfrom.c if there are indexes) +create index on parent(b) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: IndexStmt +== 861 +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +== 862 +-- check disinherit/reinherit behavior; statement triggers with transition +-- tables should not prevent a table from becoming an inheritance child again +alter table child1 no inherit parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: AlterTableStmt +== 863 +alter table child1 inherit parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: AlterTableStmt +== 864 +-- DML affecting parent sees tuples collected from children even if +-- there is no transition table trigger on the children +drop trigger child1_insert_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 865 +drop trigger child1_update_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 866 +drop trigger child1_delete_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +== 867 +drop trigger child2_insert_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +== 868 +drop trigger child2_update_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +== 869 +drop trigger child2_delete_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +== 870 +drop trigger child3_insert_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +== 871 +drop trigger child3_update_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +== 872 +drop trigger child3_delete_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +== 873 +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +== 874 +drop table child1, child2, child3, parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +TABLE: name="child2" schema="" table="child2" ctx=DDL +TABLE: name="child3" schema="" table="child3" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 875 +|-- +-- Verify prohibition of row triggers with transition triggers on +-- inheritance children +|-- +create table parent (a text, b int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 876 +create table child () inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 877 +-- adding row trigger with transition table fails +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +== 878 +-- disinheriting it first works +alter table child no inherit parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +== 879 +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +== 880 +-- but now we're not allowed to make it inherit anymore +alter table child inherit parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +== 881 +-- drop the trigger, and now we're allowed to make it inherit again +drop trigger child_row_trig on child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 882 +alter table child inherit parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +== 883 +drop table child, parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +== 884 +|-- +-- Verify behavior of queries with wCTEs, where multiple transition +-- tuplestores can be active at the same time because there are +-- multiple DML statements that might fire triggers with transition +-- tables +|-- +create table table1 (a int) +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: CreateStmt +== 885 +create table table2 (a text) +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: CreateStmt +== 886 +create trigger table1_trig + after insert on table1 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: CreateTrigStmt +== 887 +create trigger table2_trig + after insert on table2 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: CreateTrigStmt +== 888 +with wcte as (insert into table1 values (42)) + insert into table2 values ('hello world') +-- +TABLE: name="table2" schema="" table="table2" ctx=DML +TABLE: name="table1" schema="" table="table1" ctx=DML +CTE: "wcte" +STMT: InsertStmt +STMT: SelectStmt +== 889 +with wcte as (insert into table1 values (43)) + insert into table1 values (44) +-- +TABLE: name="table1" schema="" table="table1" ctx=DML +TABLE: name="table1" schema="" table="table1" ctx=DML +CTE: "wcte" +STMT: InsertStmt +STMT: SelectStmt +== 890 +select * from table1 +-- +TABLE: name="table1" schema="" table="table1" ctx=Select +STMT: SelectStmt +== 891 +select * from table2 +-- +TABLE: name="table2" schema="" table="table2" ctx=Select +STMT: SelectStmt +== 892 +drop table table1 +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: DropStmt +== 893 +drop table table2 +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: DropStmt +== 894 +|-- +-- Verify behavior of INSERT ... ON CONFLICT DO UPDATE ... with +-- transition tables. +|-- + +create table my_table (a int primary key, b text) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateStmt +== 895 +create trigger my_table_insert_trig + after insert on my_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +== 896 +create trigger my_table_update_trig + after update on my_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +== 897 +-- inserts only +insert into my_table values (1, 'AAA'), (2, 'BBB') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 898 +-- mixture of inserts and updates +insert into my_table values (1, 'AAA'), (2, 'BBB'), (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 899 +-- updates only +insert into my_table values (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 900 +|-- +-- now using a partitioned table +|-- + +create table iocdu_tt_parted (a int primary key, b text) partition by list (a) +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: CreateStmt +== 901 +create table iocdu_tt_parted1 partition of iocdu_tt_parted for values in (1) +-- +TABLE: name="iocdu_tt_parted1" schema="" table="iocdu_tt_parted1" ctx=DDL +STMT: CreateStmt +== 902 +create table iocdu_tt_parted2 partition of iocdu_tt_parted for values in (2) +-- +TABLE: name="iocdu_tt_parted2" schema="" table="iocdu_tt_parted2" ctx=DDL +STMT: CreateStmt +== 903 +create table iocdu_tt_parted3 partition of iocdu_tt_parted for values in (3) +-- +TABLE: name="iocdu_tt_parted3" schema="" table="iocdu_tt_parted3" ctx=DDL +STMT: CreateStmt +== 904 +create table iocdu_tt_parted4 partition of iocdu_tt_parted for values in (4) +-- +TABLE: name="iocdu_tt_parted4" schema="" table="iocdu_tt_parted4" ctx=DDL +STMT: CreateStmt +== 905 +create trigger iocdu_tt_parted_insert_trig + after insert on iocdu_tt_parted referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: CreateTrigStmt +== 906 +create trigger iocdu_tt_parted_update_trig + after update on iocdu_tt_parted referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: CreateTrigStmt +== 907 +-- inserts only +insert into iocdu_tt_parted values (1, 'AAA'), (2, 'BBB') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 908 +-- mixture of inserts and updates +insert into iocdu_tt_parted values (1, 'AAA'), (2, 'BBB'), (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 909 +-- updates only +insert into iocdu_tt_parted values (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 910 +drop table iocdu_tt_parted +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: DropStmt +== 911 +|-- +-- Verify that you can't create a trigger with transition tables for +-- more than one event. +|-- + +create trigger my_table_multievent_trig + after insert or update on my_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +== 912 +|-- +-- Verify that you can't create a trigger with transition tables with +-- a column list. +|-- + +create trigger my_table_col_update_trig + after update of b on my_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +== 913 +drop table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: DropStmt +== 914 +|-- +-- Test firing of triggers with transition tables by foreign key cascades +|-- + +create table refd_table (a int primary key, b text) +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +STMT: CreateStmt +== 915 +create table trig_table (a int, b text, + foreign key (a) references refd_table on update cascade on delete cascade +) +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateStmt +== 916 +create trigger trig_table_before_trig + before insert or update or delete on trig_table + for each statement execute procedure trigger_func('trig_table') +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +== 917 +create trigger trig_table_insert_trig + after insert on trig_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +== 918 +create trigger trig_table_update_trig + after update on trig_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +== 919 +create trigger trig_table_delete_trig + after delete on trig_table referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +== 920 +insert into refd_table values + (1, 'one'), + (2, 'two'), + (3, 'three') +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 921 +insert into trig_table values + (1, 'one a'), + (1, 'one b'), + (2, 'two a'), + (2, 'two b'), + (3, 'three a'), + (3, 'three b') +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 922 +update refd_table set a = 11 where b = 'one' +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DML +STMT: UpdateStmt +== 923 +select * from trig_table +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=Select +STMT: SelectStmt +== 924 +delete from refd_table where length(b) = 3 +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DML +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: DeleteStmt +== 925 +select * from trig_table +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=Select +STMT: SelectStmt +== 926 +drop table refd_table, trig_table +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: DropStmt +== 927 +|-- +-- Test that we can drop a not-yet-fired deferred trigger +|-- + +create table refd_table (id int primary key) +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +STMT: CreateStmt +== 928 +create table trig_table (fk int references refd_table initially deferred) +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateStmt +== 929 +begin +-- +STMT: TransactionStmt +== 930 +insert into trig_table values (1) +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 931 +drop table refd_table cascade +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +STMT: DropStmt +== 932 +commit +-- +STMT: TransactionStmt +== 933 +drop table trig_table +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: DropStmt +== 934 +|-- +-- self-referential FKs are even more fun +|-- + +create table self_ref (a int primary key, + b int references self_ref(a) on delete cascade) +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateStmt +== 935 +create trigger self_ref_before_trig + before delete on self_ref + for each statement execute procedure trigger_func('self_ref') +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateTrigStmt +== 936 +create trigger self_ref_r_trig + after delete on self_ref referencing old table as old_table + for each row execute procedure dump_delete() +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateTrigStmt +== 937 +create trigger self_ref_s_trig + after delete on self_ref referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateTrigStmt +== 938 +insert into self_ref values (1, null), (2, 1), (3, 2) +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 939 +delete from self_ref where a = 1 +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: DeleteStmt +== 940 +-- without AR trigger, cascaded deletes all end up in one transition table +drop trigger self_ref_r_trig on self_ref +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: DropStmt +== 941 +insert into self_ref values (1, null), (2, 1), (3, 2), (4, 3) +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 942 +delete from self_ref where a = 1 +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: DeleteStmt +== 943 +drop table self_ref +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: DropStmt +== 944 +|-- +-- test transition tables with MERGE +|-- +create table merge_target_table (a int primary key, b text) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateStmt +== 945 +create trigger merge_target_table_insert_trig + after insert on merge_target_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateTrigStmt +== 946 +create trigger merge_target_table_update_trig + after update on merge_target_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateTrigStmt +== 947 +create trigger merge_target_table_delete_trig + after delete on merge_target_table referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateTrigStmt +== 948 +create table merge_source_table (a int, b text) +-- +TABLE: name="merge_source_table" schema="" table="merge_source_table" ctx=DDL +STMT: CreateStmt +== 949 +insert into merge_source_table + values (1, 'initial1'), (2, 'initial2'), + (3, 'initial3'), (4, 'initial4') +-- +TABLE: name="merge_source_table" schema="" table="merge_source_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 950 +merge into merge_target_table t +using merge_source_table s +on t.a = s.a +when not matched then + insert values (a, b) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DML +ALIAS: "t"="merge_target_table" +STMT: MergeStmt +== 951 +merge into merge_target_table t +using merge_source_table s +on t.a = s.a +when matched and s.a <= 2 then + update set b = t.b || ' updated by merge' +when matched and s.a > 2 then + delete +when not matched then + insert values (a, b) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DML +ALIAS: "t"="merge_target_table" +STMT: MergeStmt +== 952 +merge into merge_target_table t +using merge_source_table s +on t.a = s.a +when matched and s.a <= 2 then + update set b = t.b || ' updated again by merge' +when matched and s.a > 2 then + delete +when not matched then + insert values (a, b) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DML +ALIAS: "t"="merge_target_table" +STMT: MergeStmt +== 953 +drop table merge_source_table, merge_target_table +-- +TABLE: name="merge_source_table" schema="" table="merge_source_table" ctx=DDL +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: DropStmt +== 954 +-- cleanup +drop function dump_insert() +-- +FUNCTION: name="dump_insert" function="dump_insert" schema="" ctx=DDL +STMT: DropStmt +== 955 +drop function dump_update() +-- +FUNCTION: name="dump_update" function="dump_update" schema="" ctx=DDL +STMT: DropStmt +== 956 +drop function dump_delete() +-- +FUNCTION: name="dump_delete" function="dump_delete" schema="" ctx=DDL +STMT: DropStmt +== 957 +|-- +-- Tests for CREATE OR REPLACE TRIGGER +|-- +create table my_table (id integer) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateStmt +== 958 +create function funcA() returns trigger as $$ +begin + raise notice 'hello from funcA'; + return null; +end; $$ language plpgsql +-- +FUNCTION: name="funca" function="funca" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 959 +create function funcB() returns trigger as $$ +begin + raise notice 'hello from funcB'; + return null; +end; $$ language plpgsql +-- +FUNCTION: name="funcb" function="funcb" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 960 +create trigger my_trig + after insert on my_table + for each row execute procedure funcA() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +== 961 +create trigger my_trig + before insert on my_table + for each row execute procedure funcB() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +== 962 +-- should fail + +insert into my_table values (1) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 963 +create or replace trigger my_trig + before insert on my_table + for each row execute procedure funcB() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +== 964 +-- OK + +insert into my_table values (2) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 965 +-- this insert should become a no-op + +table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=Select +STMT: SelectStmt +== 966 +drop table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: DropStmt +== 967 +-- test CREATE OR REPLACE TRIGGER on partition table +create table parted_trig (a int) partition by range (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +== 968 +create table parted_trig_1 partition of parted_trig + for values from (0) to (1000) partition by range (a) +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateStmt +== 969 +create table parted_trig_1_1 partition of parted_trig_1 for values from (0) to (100) +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateStmt +== 970 +create table parted_trig_2 partition of parted_trig for values from (1000) to (2000) +-- +TABLE: name="parted_trig_2" schema="" table="parted_trig_2" ctx=DDL +STMT: CreateStmt +== 971 +create table default_parted_trig partition of parted_trig default +-- +TABLE: name="default_parted_trig" schema="" table="default_parted_trig" ctx=DDL +STMT: CreateStmt +== 972 +-- test that trigger can be replaced by another one +-- at the same level of partition table +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcA() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 973 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 974 +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcB() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 975 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 976 +-- test that child trigger cannot be replaced directly +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcA() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 977 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 978 +create or replace trigger my_trig + after insert on parted_trig_1 + for each row execute procedure funcB() +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateTrigStmt +== 979 +-- should fail +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 980 +drop trigger my_trig on parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +== 981 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 982 +-- test that user trigger can be overwritten by one defined at upper level +create trigger my_trig + after insert on parted_trig_1 + for each row execute procedure funcA() +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateTrigStmt +== 983 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 984 +create trigger my_trig + after insert on parted_trig + for each row execute procedure funcB() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 985 +-- should fail +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 986 +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcB() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +== 987 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 988 +-- cleanup +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +== 989 +drop function funcA() +-- +FUNCTION: name="funca" function="funca" schema="" ctx=DDL +STMT: DropStmt +== 990 +drop function funcB() +-- +FUNCTION: name="funcb" function="funcb" schema="" ctx=DDL +STMT: DropStmt +== 991 +-- Leave around some objects for other tests +create table trigger_parted (a int primary key) partition by list (a) +-- +TABLE: name="trigger_parted" schema="" table="trigger_parted" ctx=DDL +STMT: CreateStmt +== 992 +create function trigger_parted_trigfunc() returns trigger language plpgsql as + $$ begin end; $$ +-- +FUNCTION: name="trigger_parted_trigfunc" function="trigger_parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 993 +create trigger aft_row after insert or update on trigger_parted + for each row execute function trigger_parted_trigfunc() +-- +TABLE: name="trigger_parted" schema="" table="trigger_parted" ctx=DDL +STMT: CreateTrigStmt +== 994 +create table trigger_parted_p1 partition of trigger_parted for values in (1) + partition by list (a) +-- +TABLE: name="trigger_parted_p1" schema="" table="trigger_parted_p1" ctx=DDL +STMT: CreateStmt +== 995 +create table trigger_parted_p1_1 partition of trigger_parted_p1 for values in (1) +-- +TABLE: name="trigger_parted_p1_1" schema="" table="trigger_parted_p1_1" ctx=DDL +STMT: CreateStmt +== 996 +create table trigger_parted_p2 partition of trigger_parted for values in (2) + partition by list (a) +-- +TABLE: name="trigger_parted_p2" schema="" table="trigger_parted_p2" ctx=DDL +STMT: CreateStmt +== 997 +create table trigger_parted_p2_2 partition of trigger_parted_p2 for values in (2) +-- +TABLE: name="trigger_parted_p2_2" schema="" table="trigger_parted_p2_2" ctx=DDL +STMT: CreateStmt +== 998 +alter table only trigger_parted_p2 disable trigger aft_row +-- +TABLE: name="trigger_parted_p2" schema="" table="trigger_parted_p2" ctx=DDL +STMT: AlterTableStmt +== 999 +alter table trigger_parted_p2_2 enable always trigger aft_row +-- +TABLE: name="trigger_parted_p2_2" schema="" table="trigger_parted_p2_2" ctx=DDL +STMT: AlterTableStmt +== 1000 +-- verify transition table conversion slot's lifetime +-- https://postgr.es/m/39a71864-b120-5a5c-8cc5-c632b6f16761@amazon.com +create table convslot_test_parent (col1 text primary key) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: CreateStmt +== 1001 +create table convslot_test_child (col1 text primary key, + foreign key (col1) references convslot_test_parent(col1) on delete cascade on update cascade +) +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateStmt +== 1002 +alter table convslot_test_child add column col2 text not null default 'tutu' +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: AlterTableStmt +== 1003 +insert into convslot_test_parent(col1) values ('1') +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1004 +insert into convslot_test_child(col1) values ('1') +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1005 +insert into convslot_test_parent(col1) values ('3') +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1006 +insert into convslot_test_child(col1) values ('3') +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1007 +create function convslot_trig1() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, old_table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by col1) from old_table); +return null; +end; $$ +-- +FUNCTION: name="convslot_trig1" function="convslot_trig1" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1008 +create function convslot_trig2() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, new table = %', + TG_NAME, + (select string_agg(new_table::text, ', ' order by col1) from new_table); +return null; +end; $$ +-- +FUNCTION: name="convslot_trig2" function="convslot_trig2" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1009 +create trigger but_trigger after update on convslot_test_child +referencing new table as new_table +for each statement execute function convslot_trig2() +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateTrigStmt +== 1010 +update convslot_test_parent set col1 = col1 || '1' +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: UpdateStmt +== 1011 +create function convslot_trig3() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, old_table = %, new table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by col1) from old_table), + (select string_agg(new_table::text, ', ' order by col1) from new_table); +return null; +end; $$ +-- +FUNCTION: name="convslot_trig3" function="convslot_trig3" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1012 +create trigger but_trigger2 after update on convslot_test_child +referencing old table as old_table new table as new_table +for each statement execute function convslot_trig3() +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateTrigStmt +== 1013 +update convslot_test_parent set col1 = col1 || '1' +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: UpdateStmt +== 1014 +create trigger bdt_trigger after delete on convslot_test_child +referencing old table as old_table +for each statement execute function convslot_trig1() +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateTrigStmt +== 1015 +delete from convslot_test_parent +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: DeleteStmt +== 1016 +drop table convslot_test_child, convslot_test_parent +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: DropStmt +== 1017 +drop function convslot_trig1() +-- +FUNCTION: name="convslot_trig1" function="convslot_trig1" schema="" ctx=DDL +STMT: DropStmt +== 1018 +drop function convslot_trig2() +-- +FUNCTION: name="convslot_trig2" function="convslot_trig2" schema="" ctx=DDL +STMT: DropStmt +== 1019 +drop function convslot_trig3() +-- +FUNCTION: name="convslot_trig3" function="convslot_trig3" schema="" ctx=DDL +STMT: DropStmt +== 1020 +-- Bug #17607: variant of above in which trigger function raises an error; +-- we don't see any ill effects unless trigger tuple requires mapping + +create table convslot_test_parent (id int primary key, val int) +partition by range (id) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: CreateStmt +== 1021 +create table convslot_test_part (val int, id int not null) +-- +TABLE: name="convslot_test_part" schema="" table="convslot_test_part" ctx=DDL +STMT: CreateStmt +== 1022 +alter table convslot_test_parent + attach partition convslot_test_part for values from (1) to (1000) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: AlterTableStmt +== 1023 +create function convslot_trig4() returns trigger as +$$begin raise exception 'BOOM!'; end$$ language plpgsql +-- +FUNCTION: name="convslot_trig4" function="convslot_trig4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1024 +create trigger convslot_test_parent_update + after update on convslot_test_parent + referencing old table as old_rows new table as new_rows + for each statement execute procedure convslot_trig4() +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: CreateTrigStmt +== 1025 +insert into convslot_test_parent (id, val) values (1, 2) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1026 +begin +-- +STMT: TransactionStmt +== 1027 +savepoint svp +-- +STMT: TransactionStmt +== 1028 +update convslot_test_parent set val = 3 +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: UpdateStmt +== 1029 +-- error expected +rollback to savepoint svp +-- +STMT: TransactionStmt +== 1030 +rollback +-- +STMT: TransactionStmt +== 1031 +drop table convslot_test_parent +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: DropStmt +== 1032 +drop function convslot_trig4() +-- +FUNCTION: name="convslot_trig4" function="convslot_trig4" schema="" ctx=DDL +STMT: DropStmt +== 1033 +-- Test trigger renaming on partitioned tables +create table grandparent (id int, primary key (id)) partition by range (id) +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: CreateStmt +== 1034 +create table middle partition of grandparent for values from (1) to (10) +partition by range (id) +-- +TABLE: name="middle" schema="" table="middle" ctx=DDL +STMT: CreateStmt +== 1035 +create table chi partition of middle for values from (1) to (5) +-- +TABLE: name="chi" schema="" table="chi" ctx=DDL +STMT: CreateStmt +== 1036 +create table cho partition of middle for values from (6) to (10) +-- +TABLE: name="cho" schema="" table="cho" ctx=DDL +STMT: CreateStmt +== 1037 +create function f () returns trigger as +$$ begin return new; end; $$ +language plpgsql +-- +FUNCTION: name="f" function="f" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1038 +create trigger a after insert on grandparent +for each row execute procedure f() +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: CreateTrigStmt +== 1039 +alter trigger a on grandparent rename to b +-- +STMT: RenameStmt +== 1040 +select tgrelid::regclass, tgname, +(select tgname from pg_trigger tr where tr.oid = pg_trigger.tgparentid) parent_tgname +from pg_trigger where tgrelid in (select relid from pg_partition_tree('grandparent')) +order by tgname, tgrelid::regclass::text COLLATE "C" +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +ALIAS: "tr"="pg_trigger" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="tr" column="oid" +FILTER: schema="" table="pg_trigger" column="tgparentid" +STMT: SelectStmt +== 1041 +alter trigger a on only grandparent rename to b +-- +ERROR: syntax error at or near "only" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 1042 +-- ONLY not supported +alter trigger b on middle rename to c +-- +STMT: RenameStmt +== 1043 +-- can't rename trigger on partition +create trigger c after insert on middle +for each row execute procedure f() +-- +TABLE: name="middle" schema="" table="middle" ctx=DDL +STMT: CreateTrigStmt +== 1044 +alter trigger b on grandparent rename to c +-- +STMT: RenameStmt +== 1045 +-- Rename cascading does not affect statement triggers +create trigger p after insert on grandparent for each statement execute function f() +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: CreateTrigStmt +== 1046 +create trigger p after insert on middle for each statement execute function f() +-- +TABLE: name="middle" schema="" table="middle" ctx=DDL +STMT: CreateTrigStmt +== 1047 +alter trigger p on grandparent rename to q +-- +STMT: RenameStmt +== 1048 +select tgrelid::regclass, tgname, +(select tgname from pg_trigger tr where tr.oid = pg_trigger.tgparentid) parent_tgname +from pg_trigger where tgrelid in (select relid from pg_partition_tree('grandparent')) +order by tgname, tgrelid::regclass::text COLLATE "C" +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +ALIAS: "tr"="pg_trigger" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="tr" column="oid" +FILTER: schema="" table="pg_trigger" column="tgparentid" +STMT: SelectStmt +== 1049 +drop table grandparent +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: DropStmt +== 1050 +-- Trigger renaming does not recurse on legacy inheritance +create table parent (a int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 1051 +create table child () inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +== 1052 +create trigger parenttrig after insert on parent +for each row execute procedure f() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +== 1053 +create trigger parenttrig after insert on child +for each row execute procedure f() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +== 1054 +alter trigger parenttrig on parent rename to anothertrig +-- +STMT: RenameStmt +== 1055 +drop table parent, child +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +== 1056 +drop function f() +-- +FUNCTION: name="f" function="f" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/truncate.metadata.json b/parser/testdata/summary/postgres_regress/truncate.metadata.json new file mode 100644 index 0000000..5ad4c2c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/truncate.metadata.json @@ -0,0 +1,197 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193" + ] +} diff --git a/parser/testdata/summary/postgres_regress/truncate.test b/parser/testdata/summary/postgres_regress/truncate.test new file mode 100644 index 0000000..8372c9f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/truncate.test @@ -0,0 +1,1111 @@ +== 001 +-- Test basic TRUNCATE functionality. +CREATE TABLE truncate_a (col1 integer primary key) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO truncate_a VALUES (1) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO truncate_a VALUES (2) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 005 +-- Roll truncate back +BEGIN +-- +STMT: TransactionStmt +== 006 +TRUNCATE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 007 +ROLLBACK +-- +STMT: TransactionStmt +== 008 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 009 +-- Commit the truncate this time +BEGIN +-- +STMT: TransactionStmt +== 010 +TRUNCATE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 011 +COMMIT +-- +STMT: TransactionStmt +== 012 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 013 +-- Test foreign-key checks +CREATE TABLE trunc_b (a int REFERENCES truncate_a) +-- +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: CreateStmt +== 014 +CREATE TABLE trunc_c (a serial PRIMARY KEY) +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: CreateStmt +== 015 +CREATE TABLE trunc_d (a int REFERENCES trunc_c) +-- +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +STMT: CreateStmt +== 016 +CREATE TABLE trunc_e (a int REFERENCES truncate_a, b int REFERENCES trunc_c) +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: CreateStmt +== 017 +TRUNCATE TABLE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 018 +-- fail +TRUNCATE TABLE truncate_a,trunc_b +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: TruncateStmt +== 019 +-- fail +TRUNCATE TABLE truncate_a,trunc_b,trunc_e +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +== 020 +-- ok +TRUNCATE TABLE truncate_a,trunc_e +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +== 021 +-- fail +TRUNCATE TABLE trunc_c +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: TruncateStmt +== 022 +-- fail +TRUNCATE TABLE trunc_c,trunc_d +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +STMT: TruncateStmt +== 023 +-- fail +TRUNCATE TABLE trunc_c,trunc_d,trunc_e +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +== 024 +-- ok +TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 025 +-- fail +TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: TruncateStmt +== 026 +-- ok + +TRUNCATE TABLE truncate_a RESTRICT +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 027 +-- fail +TRUNCATE TABLE truncate_a CASCADE +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 028 +-- ok + +-- circular references +ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: AlterTableStmt +== 029 +-- Add some data to verify that truncating actually works ... +INSERT INTO trunc_c VALUES (1) +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO truncate_a VALUES (1) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO trunc_b VALUES (1) +-- +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +INSERT INTO trunc_d VALUES (1) +-- +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 033 +INSERT INTO trunc_e VALUES (1,1) +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 034 +TRUNCATE TABLE trunc_c +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: TruncateStmt +== 035 +TRUNCATE TABLE trunc_c,truncate_a +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 036 +TRUNCATE TABLE trunc_c,truncate_a,trunc_d +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +STMT: TruncateStmt +== 037 +TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +== 038 +TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e,trunc_b +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: TruncateStmt +== 039 +-- Verify that truncating did actually work +SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=Select +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=Select +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=Select +STMT: SelectStmt +== 040 +SELECT * FROM trunc_e +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=Select +STMT: SelectStmt +== 041 +-- Add data again to test TRUNCATE ... CASCADE +INSERT INTO trunc_c VALUES (1) +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 042 +INSERT INTO truncate_a VALUES (1) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +INSERT INTO trunc_b VALUES (1) +-- +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 044 +INSERT INTO trunc_d VALUES (1) +-- +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 045 +INSERT INTO trunc_e VALUES (1,1) +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +TRUNCATE TABLE trunc_c CASCADE +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: TruncateStmt +== 047 +-- ok + +SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=Select +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=Select +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=Select +STMT: SelectStmt +== 048 +SELECT * FROM trunc_e +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=Select +STMT: SelectStmt +== 049 +DROP TABLE truncate_a,trunc_c,trunc_b,trunc_d,trunc_e CASCADE +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: DropStmt +== 050 +-- Test TRUNCATE with inheritance + +CREATE TABLE trunc_f (col1 integer primary key) +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: CreateStmt +== 051 +INSERT INTO trunc_f VALUES (1) +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 052 +INSERT INTO trunc_f VALUES (2) +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 053 +CREATE TABLE trunc_fa (col2a text) INHERITS (trunc_f) +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DDL +STMT: CreateStmt +== 054 +INSERT INTO trunc_fa VALUES (3, 'three') +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 055 +CREATE TABLE trunc_fb (col2b int) INHERITS (trunc_f) +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DDL +STMT: CreateStmt +== 056 +INSERT INTO trunc_fb VALUES (4, 444) +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 057 +CREATE TABLE trunc_faa (col3 text) INHERITS (trunc_fa) +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=DDL +STMT: CreateStmt +== 058 +INSERT INTO trunc_faa VALUES (5, 'five', 'FIVE') +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +BEGIN +-- +STMT: TransactionStmt +== 060 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 061 +TRUNCATE trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: TruncateStmt +== 062 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 063 +ROLLBACK +-- +STMT: TransactionStmt +== 064 +BEGIN +-- +STMT: TransactionStmt +== 065 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 066 +TRUNCATE ONLY trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: TruncateStmt +== 067 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 068 +ROLLBACK +-- +STMT: TransactionStmt +== 069 +BEGIN +-- +STMT: TransactionStmt +== 070 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 071 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +== 072 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +== 073 +TRUNCATE ONLY trunc_fb, ONLY trunc_fa +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DDL +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DDL +STMT: TruncateStmt +== 074 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 075 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +== 076 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +== 077 +ROLLBACK +-- +STMT: TransactionStmt +== 078 +BEGIN +-- +STMT: TransactionStmt +== 079 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 080 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +== 081 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +== 082 +TRUNCATE ONLY trunc_fb, trunc_fa +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DDL +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DDL +STMT: TruncateStmt +== 083 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +== 084 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +== 085 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +== 086 +ROLLBACK +-- +STMT: TransactionStmt +== 087 +DROP TABLE trunc_f CASCADE +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: DropStmt +== 088 +-- Test ON TRUNCATE triggers + +CREATE TABLE trunc_trigger_test (f1 int, f2 text, f3 text) +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: CreateStmt +== 089 +CREATE TABLE trunc_trigger_log (tgop text, tglevel text, tgwhen text, + tgargv text, tgtable name, rowcount bigint) +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=DDL +STMT: CreateStmt +== 090 +CREATE FUNCTION trunctrigger() RETURNS trigger as $$ +declare c bigint; +begin + execute 'select count(*) from ' || quote_ident(tg_table_name) into c; + insert into trunc_trigger_log values + (TG_OP, TG_LEVEL, TG_WHEN, TG_ARGV[0], tg_table_name, c); + return null; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="trunctrigger" function="trunctrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 091 +-- basic before trigger +INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 092 +CREATE TRIGGER t +BEFORE TRUNCATE ON trunc_trigger_test +FOR EACH STATEMENT +EXECUTE PROCEDURE trunctrigger('before trigger truncate') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: CreateTrigStmt +== 093 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 094 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +== 095 +TRUNCATE trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: TruncateStmt +== 096 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 097 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +== 098 +DROP TRIGGER t ON trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: DropStmt +== 099 +truncate trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=DDL +STMT: TruncateStmt +== 100 +-- same test with an after trigger +INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 101 +CREATE TRIGGER tt +AFTER TRUNCATE ON trunc_trigger_test +FOR EACH STATEMENT +EXECUTE PROCEDURE trunctrigger('after trigger truncate') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: CreateTrigStmt +== 102 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 103 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +== 104 +TRUNCATE trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: TruncateStmt +== 105 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 106 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +== 107 +DROP TABLE trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: DropStmt +== 108 +DROP TABLE trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=DDL +STMT: DropStmt +== 109 +DROP FUNCTION trunctrigger() +-- +FUNCTION: name="trunctrigger" function="trunctrigger" schema="" ctx=DDL +STMT: DropStmt +== 110 +-- test TRUNCATE ... RESTART IDENTITY +CREATE SEQUENCE truncate_a_id1 START WITH 33 +-- +STMT: CreateSeqStmt +== 111 +CREATE TABLE truncate_a (id serial, + id1 integer default nextval('truncate_a_id1')) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: CreateStmt +== 112 +ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1 +-- +STMT: AlterSeqStmt +== 113 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 114 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 115 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 116 +TRUNCATE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 117 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 118 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 119 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 120 +TRUNCATE truncate_a RESTART IDENTITY +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 121 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 122 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 123 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 124 +CREATE TABLE truncate_b (id int GENERATED ALWAYS AS IDENTITY (START WITH 44)) +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DDL +STMT: CreateStmt +== 125 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +== 126 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +== 127 +SELECT * FROM truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=Select +STMT: SelectStmt +== 128 +TRUNCATE truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DDL +STMT: TruncateStmt +== 129 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +== 130 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +== 131 +SELECT * FROM truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=Select +STMT: SelectStmt +== 132 +TRUNCATE truncate_b RESTART IDENTITY +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DDL +STMT: TruncateStmt +== 133 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +== 134 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +== 135 +SELECT * FROM truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=Select +STMT: SelectStmt +== 136 +-- check rollback of a RESTART IDENTITY operation +BEGIN +-- +STMT: TransactionStmt +== 137 +TRUNCATE truncate_a RESTART IDENTITY +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +== 138 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 139 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 140 +ROLLBACK +-- +STMT: TransactionStmt +== 141 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 142 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +== 143 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +== 144 +DROP TABLE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: DropStmt +== 145 +SELECT nextval('truncate_a_id1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +== 146 +-- fail, seq should have been dropped + +-- partitioned table +CREATE TABLE truncparted (a int, b char) PARTITION BY LIST (a) +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: CreateStmt +== 147 +-- error, can't truncate a partitioned table +TRUNCATE ONLY truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: TruncateStmt +== 148 +CREATE TABLE truncparted1 PARTITION OF truncparted FOR VALUES IN (1) +-- +TABLE: name="truncparted1" schema="" table="truncparted1" ctx=DDL +STMT: CreateStmt +== 149 +INSERT INTO truncparted VALUES (1, 'a') +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 150 +-- error, must truncate partitions +TRUNCATE ONLY truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: TruncateStmt +== 151 +TRUNCATE truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: TruncateStmt +== 152 +DROP TABLE truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: DropStmt +== 153 +-- foreign key on partitioned table: partition key is referencing column. +-- Make sure truncate did execute on all tables +CREATE FUNCTION tp_ins_data() RETURNS void LANGUAGE plpgsql AS $$ + BEGIN + INSERT INTO truncprim VALUES (1), (100), (150); + INSERT INTO truncpart VALUES (1), (100), (150); + END +$$ +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 154 +CREATE FUNCTION tp_chk_data(OUT pktb regclass, OUT pkval int, OUT fktb regclass, OUT fkval int) + RETURNS SETOF record LANGUAGE plpgsql AS $$ + BEGIN + RETURN QUERY SELECT + pk.tableoid::regclass, pk.a, fk.tableoid::regclass, fk.a + FROM truncprim pk FULL JOIN truncpart fk USING (a) + ORDER BY 2, 4; + END +$$ +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 155 +CREATE TABLE truncprim (a int PRIMARY KEY) +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +STMT: CreateStmt +== 156 +CREATE TABLE truncpart (a int REFERENCES truncprim) + PARTITION BY RANGE (a) +-- +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: CreateStmt +== 157 +CREATE TABLE truncpart_1 PARTITION OF truncpart FOR VALUES FROM (0) TO (100) +-- +TABLE: name="truncpart_1" schema="" table="truncpart_1" ctx=DDL +STMT: CreateStmt +== 158 +CREATE TABLE truncpart_2 PARTITION OF truncpart FOR VALUES FROM (100) TO (200) + PARTITION BY RANGE (a) +-- +TABLE: name="truncpart_2" schema="" table="truncpart_2" ctx=DDL +STMT: CreateStmt +== 159 +CREATE TABLE truncpart_2_1 PARTITION OF truncpart_2 FOR VALUES FROM (100) TO (150) +-- +TABLE: name="truncpart_2_1" schema="" table="truncpart_2_1" ctx=DDL +STMT: CreateStmt +== 160 +CREATE TABLE truncpart_2_d PARTITION OF truncpart_2 DEFAULT +-- +TABLE: name="truncpart_2_d" schema="" table="truncpart_2_d" ctx=DDL +STMT: CreateStmt +== 161 +TRUNCATE TABLE truncprim +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +STMT: TruncateStmt +== 162 +-- should fail + +select tp_ins_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=Call +STMT: SelectStmt +== 163 +-- should truncate everything +TRUNCATE TABLE truncprim, truncpart +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: TruncateStmt +== 164 +select * from tp_chk_data() +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=Call +STMT: SelectStmt +== 165 +select tp_ins_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=Call +STMT: SelectStmt +== 166 +-- should truncate everything +TRUNCATE TABLE truncprim CASCADE +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +STMT: TruncateStmt +== 167 +SELECT * FROM tp_chk_data() +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=Call +STMT: SelectStmt +== 168 +SELECT tp_ins_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=Call +STMT: SelectStmt +== 169 +-- should truncate all partitions +TRUNCATE TABLE truncpart +-- +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: TruncateStmt +== 170 +SELECT * FROM tp_chk_data() +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=Call +STMT: SelectStmt +== 171 +DROP TABLE truncprim, truncpart +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: DropStmt +== 172 +DROP FUNCTION tp_ins_data(), tp_chk_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=DDL +STMT: DropStmt +== 173 +-- test cascade when referencing a partitioned table +CREATE TABLE trunc_a (a INT PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=DDL +STMT: CreateStmt +== 174 +CREATE TABLE trunc_a1 PARTITION OF trunc_a FOR VALUES FROM (0) TO (10) +-- +TABLE: name="trunc_a1" schema="" table="trunc_a1" ctx=DDL +STMT: CreateStmt +== 175 +CREATE TABLE trunc_a2 PARTITION OF trunc_a FOR VALUES FROM (10) TO (20) + PARTITION BY RANGE (a) +-- +TABLE: name="trunc_a2" schema="" table="trunc_a2" ctx=DDL +STMT: CreateStmt +== 176 +CREATE TABLE trunc_a21 PARTITION OF trunc_a2 FOR VALUES FROM (10) TO (12) +-- +TABLE: name="trunc_a21" schema="" table="trunc_a21" ctx=DDL +STMT: CreateStmt +== 177 +CREATE TABLE trunc_a22 PARTITION OF trunc_a2 FOR VALUES FROM (12) TO (16) +-- +TABLE: name="trunc_a22" schema="" table="trunc_a22" ctx=DDL +STMT: CreateStmt +== 178 +CREATE TABLE trunc_a2d PARTITION OF trunc_a2 DEFAULT +-- +TABLE: name="trunc_a2d" schema="" table="trunc_a2d" ctx=DDL +STMT: CreateStmt +== 179 +CREATE TABLE trunc_a3 PARTITION OF trunc_a FOR VALUES FROM (20) TO (30) +-- +TABLE: name="trunc_a3" schema="" table="trunc_a3" ctx=DDL +STMT: CreateStmt +== 180 +INSERT INTO trunc_a VALUES (0), (5), (10), (15), (20), (25) +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 181 +-- truncate a partition cascading to a table +CREATE TABLE ref_b ( + b INT PRIMARY KEY, + a INT REFERENCES trunc_a(a) ON DELETE CASCADE +) +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=DDL +STMT: CreateStmt +== 182 +INSERT INTO ref_b VALUES (10, 0), (50, 5), (100, 10), (150, 15) +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 183 +TRUNCATE TABLE trunc_a1 CASCADE +-- +TABLE: name="trunc_a1" schema="" table="trunc_a1" ctx=DDL +STMT: TruncateStmt +== 184 +SELECT a FROM ref_b +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=Select +STMT: SelectStmt +== 185 +DROP TABLE ref_b +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=DDL +STMT: DropStmt +== 186 +-- truncate a partition cascading to a partitioned table +CREATE TABLE ref_c ( + c INT PRIMARY KEY, + a INT REFERENCES trunc_a(a) ON DELETE CASCADE +) PARTITION BY RANGE (c) +-- +TABLE: name="ref_c" schema="" table="ref_c" ctx=DDL +STMT: CreateStmt +== 187 +CREATE TABLE ref_c1 PARTITION OF ref_c FOR VALUES FROM (100) TO (200) +-- +TABLE: name="ref_c1" schema="" table="ref_c1" ctx=DDL +STMT: CreateStmt +== 188 +CREATE TABLE ref_c2 PARTITION OF ref_c FOR VALUES FROM (200) TO (300) +-- +TABLE: name="ref_c2" schema="" table="ref_c2" ctx=DDL +STMT: CreateStmt +== 189 +INSERT INTO ref_c VALUES (100, 10), (150, 15), (200, 20), (250, 25) +-- +TABLE: name="ref_c" schema="" table="ref_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 190 +TRUNCATE TABLE trunc_a21 CASCADE +-- +TABLE: name="trunc_a21" schema="" table="trunc_a21" ctx=DDL +STMT: TruncateStmt +== 191 +SELECT a as "from table ref_c" FROM ref_c +-- +TABLE: name="ref_c" schema="" table="ref_c" ctx=Select +STMT: SelectStmt +== 192 +SELECT a as "from table trunc_a" FROM trunc_a ORDER BY a +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=Select +STMT: SelectStmt +== 193 +DROP TABLE trunc_a, ref_c +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=DDL +TABLE: name="ref_c" schema="" table="ref_c" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/tsdicts.metadata.json b/parser/testdata/summary/postgres_regress/tsdicts.metadata.json new file mode 100644 index 0000000..507be8d --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tsdicts.metadata.json @@ -0,0 +1,135 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tsdicts.test b/parser/testdata/summary/postgres_regress/tsdicts.test new file mode 100644 index 0000000..bfa3864 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tsdicts.test @@ -0,0 +1,732 @@ +== 001 +--Test text search dictionaries and configurations + +-- Test ISpell dictionary with ispell affix file +CREATE TEXT SEARCH DICTIONARY ispell ( + Template=ispell, + DictFile=ispell_sample, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +== 002 +SELECT ts_lexize('ispell', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 003 +SELECT ts_lexize('ispell', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT ts_lexize('ispell', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT ts_lexize('ispell', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT ts_lexize('ispell', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT ts_lexize('ispell', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT ts_lexize('ispell', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 009 +SELECT ts_lexize('ispell', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT ts_lexize('ispell', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT ts_lexize('ispell', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT ts_lexize('ispell', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT ts_lexize('ispell', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT ts_lexize('ispell', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT ts_lexize('ispell', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT ts_lexize('ispell', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 017 +-- Test ISpell dictionary with hunspell affix file +CREATE TEXT SEARCH DICTIONARY hunspell ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample +) +-- +STMT: DefineStmt +== 018 +SELECT ts_lexize('hunspell', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT ts_lexize('hunspell', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT ts_lexize('hunspell', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT ts_lexize('hunspell', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT ts_lexize('hunspell', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT ts_lexize('hunspell', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT ts_lexize('hunspell', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT ts_lexize('hunspell', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 026 +SELECT ts_lexize('hunspell', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT ts_lexize('hunspell', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 028 +SELECT ts_lexize('hunspell', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT ts_lexize('hunspell', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT ts_lexize('hunspell', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT ts_lexize('hunspell', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT ts_lexize('hunspell', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 033 +-- Test ISpell dictionary with hunspell affix file with FLAG long parameter +CREATE TEXT SEARCH DICTIONARY hunspell_long ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=hunspell_sample_long +) +-- +STMT: DefineStmt +== 034 +SELECT ts_lexize('hunspell_long', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT ts_lexize('hunspell_long', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT ts_lexize('hunspell_long', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT ts_lexize('hunspell_long', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 038 +SELECT ts_lexize('hunspell_long', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT ts_lexize('hunspell_long', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT ts_lexize('hunspell_long', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT ts_lexize('hunspell_long', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 042 +SELECT ts_lexize('hunspell_long', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT ts_lexize('hunspell_long', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 044 +SELECT ts_lexize('hunspell_long', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 045 +SELECT ts_lexize('hunspell_long', 'booked') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 046 +SELECT ts_lexize('hunspell_long', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 047 +SELECT ts_lexize('hunspell_long', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT ts_lexize('hunspell_long', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 049 +SELECT ts_lexize('hunspell_long', 'ballsklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT ts_lexize('hunspell_long', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 051 +SELECT ts_lexize('hunspell_long', 'ex-machina') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 052 +-- Test ISpell dictionary with hunspell affix file with FLAG num parameter +CREATE TEXT SEARCH DICTIONARY hunspell_num ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=hunspell_sample_num +) +-- +STMT: DefineStmt +== 053 +SELECT ts_lexize('hunspell_num', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 054 +SELECT ts_lexize('hunspell_num', 'sk') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 055 +SELECT ts_lexize('hunspell_num', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 056 +SELECT ts_lexize('hunspell_num', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 057 +SELECT ts_lexize('hunspell_num', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 058 +SELECT ts_lexize('hunspell_num', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 059 +SELECT ts_lexize('hunspell_num', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 060 +SELECT ts_lexize('hunspell_num', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 061 +SELECT ts_lexize('hunspell_num', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 062 +SELECT ts_lexize('hunspell_num', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT ts_lexize('hunspell_num', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT ts_lexize('hunspell_num', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 065 +SELECT ts_lexize('hunspell_num', 'booked') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 066 +SELECT ts_lexize('hunspell_num', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 067 +SELECT ts_lexize('hunspell_num', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT ts_lexize('hunspell_num', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT ts_lexize('hunspell_num', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 070 +-- Test suitability of affix and dict files +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample_long +) +-- +STMT: DefineStmt +== 071 +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample_num +) +-- +STMT: DefineStmt +== 072 +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +== 073 +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=hunspell_sample_num +) +-- +STMT: DefineStmt +== 074 +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +== 075 +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=hunspell_sample_long +) +-- +STMT: DefineStmt +== 076 +-- Synonym dictionary +CREATE TEXT SEARCH DICTIONARY synonym ( + Template=synonym, + Synonyms=synonym_sample +) +-- +STMT: DefineStmt +== 077 +SELECT ts_lexize('synonym', 'PoStGrEs') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT ts_lexize('synonym', 'Gogle') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 079 +SELECT ts_lexize('synonym', 'indices') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 080 +-- test altering boolean parameters +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym' +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictname" +STMT: SelectStmt +== 081 +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = 1) +-- +STMT: AlterTSDictionaryStmt +== 082 +SELECT ts_lexize('synonym', 'PoStGrEs') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 083 +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym' +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictname" +STMT: SelectStmt +== 084 +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = 2) +-- +STMT: AlterTSDictionaryStmt +== 085 +-- fail + +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = off) +-- +STMT: AlterTSDictionaryStmt +== 086 +SELECT ts_lexize('synonym', 'PoStGrEs') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 087 +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym' +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictname" +STMT: SelectStmt +== 088 +-- Create and simple test thesaurus dictionary +-- More tests in configuration checks because ts_lexize() +-- cannot pass more than one word to thesaurus. +CREATE TEXT SEARCH DICTIONARY thesaurus ( + Template=thesaurus, + DictFile=thesaurus_sample, + Dictionary=english_stem +) +-- +STMT: DefineStmt +== 089 +SELECT ts_lexize('thesaurus', 'one') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 090 +-- Test ispell dictionary in configuration +CREATE TEXT SEARCH CONFIGURATION ispell_tst ( + COPY=english +) +-- +STMT: DefineStmt +== 091 +ALTER TEXT SEARCH CONFIGURATION ispell_tst ALTER MAPPING FOR + word, numword, asciiword, hword, numhword, asciihword, hword_part, hword_numpart, hword_asciipart + WITH ispell, english_stem +-- +STMT: AlterTSConfigurationStmt +== 092 +SELECT to_tsvector('ispell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 093 +SELECT to_tsquery('ispell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 094 +SELECT to_tsquery('ispell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 095 +-- Test ispell dictionary with hunspell affix in configuration +CREATE TEXT SEARCH CONFIGURATION hunspell_tst ( + COPY=ispell_tst +) +-- +STMT: DefineStmt +== 096 +ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING + REPLACE ispell WITH hunspell +-- +STMT: AlterTSConfigurationStmt +== 097 +SELECT to_tsvector('hunspell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 098 +SELECT to_tsquery('hunspell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 099 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 100 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b <-> sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 101 +SELECT phraseto_tsquery('hunspell_tst', 'footballyklubber sky') +-- +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 102 +-- Test ispell dictionary with hunspell affix with FLAG long in configuration +ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING + REPLACE hunspell WITH hunspell_long +-- +STMT: AlterTSConfigurationStmt +== 103 +SELECT to_tsvector('hunspell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 104 +SELECT to_tsquery('hunspell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 105 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 106 +-- Test ispell dictionary with hunspell affix with FLAG num in configuration +ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING + REPLACE hunspell_long WITH hunspell_num +-- +STMT: AlterTSConfigurationStmt +== 107 +SELECT to_tsvector('hunspell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT to_tsquery('hunspell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 109 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 110 +-- Test synonym dictionary in configuration +CREATE TEXT SEARCH CONFIGURATION synonym_tst ( + COPY=english +) +-- +STMT: DefineStmt +== 111 +ALTER TEXT SEARCH CONFIGURATION synonym_tst ALTER MAPPING FOR + asciiword, hword_asciipart, asciihword + WITH synonym, english_stem +-- +STMT: AlterTSConfigurationStmt +== 112 +SELECT to_tsvector('synonym_tst', 'Postgresql is often called as postgres or pgsql and pronounced as postgre') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 113 +SELECT to_tsvector('synonym_tst', 'Most common mistake is to write Gogle instead of Google') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 114 +SELECT to_tsvector('synonym_tst', 'Indexes or indices - Which is right plural form of index?') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 115 +SELECT to_tsquery('synonym_tst', 'Index & indices') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 116 +-- test thesaurus in configuration +-- see thesaurus_sample.ths to understand 'odd' resulting tsvector +CREATE TEXT SEARCH CONFIGURATION thesaurus_tst ( + COPY=synonym_tst +) +-- +STMT: DefineStmt +== 117 +ALTER TEXT SEARCH CONFIGURATION thesaurus_tst ALTER MAPPING FOR + asciiword, hword_asciipart, asciihword + WITH synonym, thesaurus, english_stem +-- +STMT: AlterTSConfigurationStmt +== 118 +SELECT to_tsvector('thesaurus_tst', 'one postgres one two one two three one') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 119 +SELECT to_tsvector('thesaurus_tst', 'Supernovae star is very new star and usually called supernovae (abbreviation SN)') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 120 +SELECT to_tsvector('thesaurus_tst', 'Booking tickets is looking like a booking a tickets') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 121 +-- invalid: non-lowercase quoted identifiers +CREATE TEXT SEARCH DICTIONARY tsdict_case +( + Template = ispell, + "DictFile" = ispell_sample, + "AffFile" = ispell_sample +) +-- +STMT: DefineStmt +== 122 +-- Test grammar for configurations +CREATE TEXT SEARCH CONFIGURATION dummy_tst (COPY=english) +-- +STMT: DefineStmt +== 123 +-- Overridden mapping change with duplicated tokens. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + ALTER MAPPING FOR word, word WITH ispell +-- +STMT: AlterTSConfigurationStmt +== 124 +-- Not a token supported by the configuration's parser, fails. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING FOR not_a_token, not_a_token +-- +STMT: AlterTSConfigurationStmt +== 125 +-- Not a token supported by the configuration's parser, fails even +-- with IF EXISTS. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING IF EXISTS FOR not_a_token, not_a_token +-- +STMT: AlterTSConfigurationStmt +== 126 +-- Token supported by the configuration's parser, succeeds. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING FOR word, word +-- +STMT: AlterTSConfigurationStmt +== 127 +-- No mapping for token supported by the configuration's parser, fails. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING FOR word +-- +STMT: AlterTSConfigurationStmt +== 128 +-- Token supported by the configuration's parser, cannot be found, +-- succeeds with IF EXISTS. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING IF EXISTS FOR word, word +-- +STMT: AlterTSConfigurationStmt +== 129 +-- Re-add mapping, with duplicated tokens supported by the parser. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + ADD MAPPING FOR word, word WITH ispell +-- +STMT: AlterTSConfigurationStmt +== 130 +-- Not a token supported by the configuration's parser, fails. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + ADD MAPPING FOR not_a_token WITH ispell +-- +STMT: AlterTSConfigurationStmt +== 131 +DROP TEXT SEARCH CONFIGURATION dummy_tst +-- +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/tsearch.metadata.json b/parser/testdata/summary/postgres_regress/tsearch.metadata.json new file mode 100644 index 0000000..16d1dd4 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tsearch.metadata.json @@ -0,0 +1,446 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tsearch.test b/parser/testdata/summary/postgres_regress/tsearch.test new file mode 100644 index 0000000..56eafe2 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tsearch.test @@ -0,0 +1,2992 @@ +== 001 +-- directory paths are passed to us in environment variables + +|-- +-- Sanity checks for text search catalogs +|-- +-- NB: we assume the oidjoins test will have caught any dangling links, +-- that is OID or REGPROC fields that are not zero and do not match some +-- row in the linked-to table. However, if we want to enforce that a link +-- field can't be 0, we have to check it here. + +-- Find unexpected zero link entries + +SELECT oid, prsname +FROM pg_ts_parser +WHERE prsnamespace = 0 OR prsstart = 0 OR prstoken = 0 OR prsend = 0 OR + -- prsheadline is optional + prslextype = 0 +-- +TABLE: name="pg_ts_parser" schema="" table="pg_ts_parser" ctx=Select +FILTER: schema="" table="" column="prsnamespace" +FILTER: schema="" table="" column="prsstart" +FILTER: schema="" table="" column="prstoken" +FILTER: schema="" table="" column="prsend" +FILTER: schema="" table="" column="prslextype" +STMT: SelectStmt +== 002 +SELECT oid, dictname +FROM pg_ts_dict +WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0 +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictnamespace" +FILTER: schema="" table="" column="dictowner" +FILTER: schema="" table="" column="dicttemplate" +STMT: SelectStmt +== 003 +SELECT oid, tmplname +FROM pg_ts_template +WHERE tmplnamespace = 0 OR tmpllexize = 0 +-- +TABLE: name="pg_ts_template" schema="" table="pg_ts_template" ctx=Select +FILTER: schema="" table="" column="tmplnamespace" +FILTER: schema="" table="" column="tmpllexize" +STMT: SelectStmt +== 004 +-- tmplinit is optional + +SELECT oid, cfgname +FROM pg_ts_config +WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0 +-- +TABLE: name="pg_ts_config" schema="" table="pg_ts_config" ctx=Select +FILTER: schema="" table="" column="cfgnamespace" +FILTER: schema="" table="" column="cfgowner" +FILTER: schema="" table="" column="cfgparser" +STMT: SelectStmt +== 005 +SELECT mapcfg, maptokentype, mapseqno +FROM pg_ts_config_map +WHERE mapcfg = 0 OR mapdict = 0 +-- +TABLE: name="pg_ts_config_map" schema="" table="pg_ts_config_map" ctx=Select +FILTER: schema="" table="" column="mapcfg" +FILTER: schema="" table="" column="mapdict" +STMT: SelectStmt +== 006 +-- Look for pg_ts_config_map entries that aren't one of parser's token types +SELECT * FROM + ( SELECT oid AS cfgid, (ts_token_type(cfgparser)).tokid AS tokid + FROM pg_ts_config ) AS tt +RIGHT JOIN pg_ts_config_map AS m + ON (tt.cfgid=m.mapcfg AND tt.tokid=m.maptokentype) +WHERE + tt.cfgid IS NULL OR tt.tokid IS NULL +-- +TABLE: name="pg_ts_config_map" schema="" table="pg_ts_config_map" ctx=Select +TABLE: name="pg_ts_config" schema="" table="pg_ts_config" ctx=Select +ALIAS: "m"="pg_ts_config_map" +FUNCTION: name="ts_token_type" function="ts_token_type" schema="" ctx=Call +FILTER: schema="" table="tt" column="cfgid" +FILTER: schema="" table="tt" column="tokid" +STMT: SelectStmt +== 007 +-- Load some test data +CREATE TABLE test_tsvector( + t text, + a tsvector +) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: CreateStmt +== 008 +COPY test_tsvector FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +ANALYZE test_tsvector +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: VacuumStmt +== 010 +-- test basic text search behavior without indexes, then with + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 011 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 012 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 013 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 014 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 015 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 016 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 017 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 018 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 019 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 020 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 021 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 022 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 023 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 024 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 025 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 026 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 027 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 028 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 029 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 030 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 031 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 032 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 033 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 034 +create index wowidx on test_tsvector using gist (a) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 035 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +== 036 +SET enable_indexscan=ON +-- +STMT: VariableSetStmt +== 037 +SET enable_bitmapscan=OFF +-- +STMT: VariableSetStmt +== 038 +explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 039 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 040 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 041 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 042 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 043 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 044 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 045 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 046 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 047 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 048 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 049 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 050 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 051 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 052 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 053 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 054 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 055 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 056 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 057 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 058 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 059 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 060 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 061 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 062 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 063 +SET enable_indexscan=OFF +-- +STMT: VariableSetStmt +== 064 +SET enable_bitmapscan=ON +-- +STMT: VariableSetStmt +== 065 +explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 066 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 067 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 068 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 069 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 070 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 071 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 072 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 073 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 074 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 075 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 076 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 077 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 078 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 079 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 080 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 081 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 082 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 083 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 084 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 085 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 086 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 087 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 088 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 089 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 090 +-- Test siglen parameter of GiST tsvector_ops +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(foo=1)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 091 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=0)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 092 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=2048)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 093 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100,foo='bar')) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 094 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100, siglen = 200)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 095 +CREATE INDEX wowidx2 ON test_tsvector USING gist (a tsvector_ops(siglen=1)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 096 +DROP INDEX wowidx +-- +STMT: DropStmt +== 097 +EXPLAIN (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 098 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 099 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 101 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 102 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 103 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 104 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 105 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 106 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 107 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 108 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 109 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 110 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 111 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 112 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 113 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 114 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 115 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 116 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 117 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 118 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 119 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 120 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 121 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 122 +DROP INDEX wowidx2 +-- +STMT: DropStmt +== 123 +CREATE INDEX wowidx ON test_tsvector USING gist (a tsvector_ops(siglen=484)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 124 +EXPLAIN (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 125 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 126 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 127 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 128 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 129 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 130 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 131 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 132 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 133 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 134 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 135 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 136 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 137 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 138 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 139 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 140 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 141 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 142 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 143 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 144 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 145 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 146 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 147 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 148 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 149 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 150 +RESET enable_indexscan +-- +STMT: VariableSetStmt +== 151 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +== 152 +DROP INDEX wowidx +-- +STMT: DropStmt +== 153 +CREATE INDEX wowidx ON test_tsvector USING gin (a) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +== 154 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +== 155 +-- GIN only supports bitmapscan, so no need to test plain indexscan + +explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 156 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 157 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 158 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 159 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 160 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 161 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 162 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 163 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 164 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 165 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 166 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 167 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 168 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 169 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 170 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 171 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 172 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 173 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 174 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 175 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 176 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 177 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 178 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 179 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 180 +-- Test optimization of non-empty GIN_SEARCH_MODE_ALL queries +EXPLAIN (COSTS OFF) +SELECT count(*) FROM test_tsvector WHERE a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 181 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 182 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +== 183 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 184 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 185 +INSERT INTO test_tsvector VALUES ('???', 'DFG:1A,2B,6C,10 FGH') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +SELECT * FROM ts_stat('SELECT a FROM test_tsvector') ORDER BY ndoc DESC, nentry DESC, word LIMIT 10 +-- +FUNCTION: name="ts_stat" function="ts_stat" schema="" ctx=Call +STMT: SelectStmt +== 187 +SELECT * FROM ts_stat('SELECT a FROM test_tsvector', 'AB') ORDER BY ndoc DESC, nentry DESC, word +-- +FUNCTION: name="ts_stat" function="ts_stat" schema="" ctx=Call +STMT: SelectStmt +== 188 +--dictionaries and to_tsvector + +SELECT ts_lexize('english_stem', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 189 +SELECT ts_lexize('english_stem', 'identity') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +== 190 +SELECT * FROM ts_token_type('default') +-- +FUNCTION: name="ts_token_type" function="ts_token_type" schema="" ctx=Call +STMT: SelectStmt +== 191 +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') +-- +FUNCTION: name="ts_parse" function="ts_parse" schema="" ctx=Call +STMT: SelectStmt +== 192 +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') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 193 +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')) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 194 +-- ts_debug + +SELECT * from ts_debug('english', 'abc&nm1;def©ghiõjkl') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +== 195 +-- check parsing of URLs +SELECT * from ts_debug('english', 'http://www.harewoodsolutions.co.uk/press.aspx') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +== 196 +SELECT * from ts_debug('english', 'http://aew.wer0c.ewr/id?ad=qwe&dw') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +== 197 +SELECT * from ts_debug('english', 'http://5aew.werc.ewr:8100/?') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +== 198 +SELECT * from ts_debug('english', '5aew.werc.ewr:8100/?xx') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +== 199 +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') +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +== 200 +-- to_tsquery + +SELECT to_tsquery('english', 'qwe & sKies ') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 201 +SELECT to_tsquery('simple', 'qwe & sKies ') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 202 +SELECT to_tsquery('english', '''the wether'':dc & '' sKies '':BC ') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 203 +SELECT to_tsquery('english', 'asd&(and|fghj)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 204 +SELECT to_tsquery('english', '(asd&and)|fghj') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 205 +SELECT to_tsquery('english', '(asd&!and)|fghj') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 206 +SELECT to_tsquery('english', '(the|and&(i&1))&fghj') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 207 +SELECT plainto_tsquery('english', 'the and z 1))& fghj') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 208 +SELECT plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 209 +SELECT plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 210 +SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 211 +SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg' +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 212 +-- Check stop word deletion, a and s are stop-words +SELECT to_tsquery('english', '!(a & !b) & c') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 213 +SELECT to_tsquery('english', '!(a & !b)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 214 +SELECT to_tsquery('english', '(1 <-> 2) <-> a') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 215 +SELECT to_tsquery('english', '(1 <-> a) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 216 +SELECT to_tsquery('english', '(a <-> 1) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 217 +SELECT to_tsquery('english', 'a <-> (1 <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 218 +SELECT to_tsquery('english', '1 <-> (a <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 219 +SELECT to_tsquery('english', '1 <-> (2 <-> a)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 220 +SELECT to_tsquery('english', '(1 <-> 2) <3> a') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 221 +SELECT to_tsquery('english', '(1 <-> a) <3> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 222 +SELECT to_tsquery('english', '(a <-> 1) <3> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 223 +SELECT to_tsquery('english', 'a <3> (1 <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 224 +SELECT to_tsquery('english', '1 <3> (a <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 225 +SELECT to_tsquery('english', '1 <3> (2 <-> a)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 226 +SELECT to_tsquery('english', '(1 <3> 2) <-> a') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 227 +SELECT to_tsquery('english', '(1 <3> a) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 228 +SELECT to_tsquery('english', '(a <3> 1) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 229 +SELECT to_tsquery('english', 'a <-> (1 <3> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT to_tsquery('english', '1 <-> (a <3> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT to_tsquery('english', '1 <-> (2 <3> a)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 232 +SELECT to_tsquery('english', '((a <-> 1) <-> 2) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 233 +SELECT to_tsquery('english', '(2 <-> (a <-> 1)) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 234 +SELECT to_tsquery('english', '((1 <-> a) <-> 2) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 235 +SELECT to_tsquery('english', '(2 <-> (1 <-> a)) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 236 +SELECT to_tsquery('english', 's <-> ((a <-> 1) <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 237 +SELECT to_tsquery('english', 's <-> (2 <-> (a <-> 1))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 238 +SELECT to_tsquery('english', 's <-> ((1 <-> a) <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 239 +SELECT to_tsquery('english', 's <-> (2 <-> (1 <-> a))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 240 +SELECT to_tsquery('english', '((a <-> 1) <-> s) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 241 +SELECT to_tsquery('english', '(s <-> (a <-> 1)) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 242 +SELECT to_tsquery('english', '((1 <-> a) <-> s) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 243 +SELECT to_tsquery('english', '(s <-> (1 <-> a)) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 244 +SELECT to_tsquery('english', '2 <-> ((a <-> 1) <-> s)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 245 +SELECT to_tsquery('english', '2 <-> (s <-> (a <-> 1))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 246 +SELECT to_tsquery('english', '2 <-> ((1 <-> a) <-> s)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 247 +SELECT to_tsquery('english', '2 <-> (s <-> (1 <-> a))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 248 +SELECT to_tsquery('english', 'foo <-> (a <-> (the <-> bar))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 249 +SELECT to_tsquery('english', '((foo <-> a) <-> the) <-> bar') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 250 +SELECT to_tsquery('english', 'foo <-> a <-> the <-> bar') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 251 +SELECT phraseto_tsquery('english', 'PostgreSQL can be extended by the user in many ways') +-- +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 252 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 253 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 254 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 255 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 256 +SELECT ts_rank_cd(strip(to_tsvector('both stripped')), + to_tsquery('both & stripped')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 257 +SELECT ts_rank_cd(to_tsvector('unstripped') || strip(to_tsvector('stripped')), + to_tsquery('unstripped & stripped')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 258 +--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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 259 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 260 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 261 +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', 'day & drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 262 +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', 'day | drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 263 +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', 'day | !drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 264 +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', 'painted <-> Ship & drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 265 +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', 'painted <-> Ship | drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 266 +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', 'painted <-> Ship | !drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 267 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 268 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 269 +SELECT ts_headline('english', +'Lorem ipsum urna. Nullam nullam ullamcorper urna.', +to_tsquery('english','Lorem') && phraseto_tsquery('english','ullamcorper urna'), +'MaxWords=100, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 270 +SELECT ts_headline('english', +'Lorem ipsum urna. Nullam nullam ullamcorper urna.', +phraseto_tsquery('english','ullamcorper urna'), +'MaxWords=100, MinWords=5') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 271 +SELECT ts_headline('english', ' + + + +Sea view wow foo bar qq +YES   +ff-bg + + +', +to_tsquery('english', 'sea&foo'), 'HighlightAll=true') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 272 +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=2, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +STMT: SelectStmt +== 273 +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 & 3', 'MaxWords=4, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +STMT: SelectStmt +== 274 +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=4, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +STMT: SelectStmt +== 275 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 276 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 277 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 278 +--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=***') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 279 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 280 +-- Edge cases with empty query +SELECT ts_headline('english', +'', to_tsquery('english', '')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 281 +SELECT ts_headline('english', +'foo bar', to_tsquery('english', '')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 282 +--Rewrite sub system + +CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: CreateStmt +== 283 +'New York' new <-> york | big <-> apple | nyc +Moscow moskva | moscow +'Sanct Peter' Peterburg | peter | 'Sanct Peterburg' +foo & bar & qq foo & (bar | qq) & city +1 & (2 <-> 3) 2 <-> 4 +5 <-> 6 5 <-> 7 + +ALTER TABLE test_tsquery ADD COLUMN keyword tsquery +-- +ERROR: syntax error at or near "'New York'" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 284 +UPDATE test_tsquery SET keyword = to_tsquery('english', txtkeyword) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DML +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: UpdateStmt +== 285 +ALTER TABLE test_tsquery ADD COLUMN sample tsquery +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: AlterTableStmt +== 286 +UPDATE test_tsquery SET sample = to_tsquery('english', txtsample::text) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DML +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: UpdateStmt +== 287 +SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 288 +SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 289 +SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 290 +SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 291 +SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 292 +CREATE UNIQUE INDEX bt_tsq ON test_tsquery (keyword) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: IndexStmt +== 293 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +== 294 +SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 295 +SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 296 +SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 297 +SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 298 +SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 299 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 300 +SELECT ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 301 +SELECT ts_rewrite(ts_rewrite('new & !york ', 'york', '!jersey'), + 'jersey', 'mexico') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 302 +SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 303 +SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 304 +SELECT ts_rewrite('bar & qq & foo & (new <-> york)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 305 +SELECT ts_rewrite( 'moscow', 'SELECT keyword, sample FROM test_tsquery') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 306 +SELECT ts_rewrite( 'moscow & hotel', 'SELECT keyword, sample FROM test_tsquery') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 307 +SELECT ts_rewrite( 'bar & qq & foo & (new <-> york)', 'SELECT keyword, sample FROM test_tsquery') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 308 +SELECT ts_rewrite('1 & (2 <-> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 309 +SELECT ts_rewrite('1 & (2 <2> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 310 +SELECT ts_rewrite('5 <-> (1 & (2 <-> 3))', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 311 +SELECT ts_rewrite('5 <-> (6 | 8)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +== 312 +-- Check empty substitution +SELECT ts_rewrite(to_tsquery('5 & (6 | 5)'), to_tsquery('5'), to_tsquery('')) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 313 +SELECT ts_rewrite(to_tsquery('!5'), to_tsquery('5'), to_tsquery('')) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 314 +SELECT keyword FROM test_tsquery WHERE keyword @> 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 315 +SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 316 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 317 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 318 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 319 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 320 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 321 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 322 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 323 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 324 +CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: IndexStmt +== 325 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +== 326 +SELECT keyword FROM test_tsquery WHERE keyword @> 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 327 +SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 328 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 329 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +== 330 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 331 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 332 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 333 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 334 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 335 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 336 +SELECT ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +== 337 +SELECT to_tsvector('foo bar') @@ + ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +== 338 +SELECT to_tsvector('bar baz') @@ + ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +== 339 +RESET enable_seqscan +-- +STMT: VariableSetStmt +== 340 +--test GUC +SET default_text_search_config=simple +-- +STMT: VariableSetStmt +== 341 +SELECT to_tsvector('SKIES My booKs') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 342 +SELECT plainto_tsquery('SKIES My booKs') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 343 +SELECT to_tsquery('SKIES & My | booKs') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 344 +SET default_text_search_config=english +-- +STMT: VariableSetStmt +== 345 +SELECT to_tsvector('SKIES My booKs') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 346 +SELECT plainto_tsquery('SKIES My booKs') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 347 +SELECT to_tsquery('SKIES & My | booKs') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 348 +--trigger +CREATE TRIGGER tsvectorupdate +BEFORE UPDATE OR INSERT ON test_tsvector +FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: CreateTrigStmt +== 349 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 350 +INSERT INTO test_tsvector (t) VALUES ('345 qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 351 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 352 +UPDATE test_tsvector SET t = null WHERE t = '345 qwerty' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: UpdateStmt +== 353 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 354 +INSERT INTO test_tsvector (t) VALUES ('345 qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 355 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 356 +-- 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 +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="txtsample" +FILTER: schema="" table="" column="q" +STMT: ExplainStmt +STMT: SelectStmt +== 357 +-- 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 +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="txtsample" +FILTER: schema="" table="" column="q" +STMT: ExplainStmt +STMT: SelectStmt +== 358 +-- test finding items in GIN's pending list +create temp table pendtest (ts tsvector) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DDL +STMT: CreateStmt +== 359 +create index pendtest_idx on pendtest using gin(ts) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DDL +STMT: IndexStmt +== 360 +insert into pendtest values (to_tsvector('Lore ipsam')) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DML +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 361 +insert into pendtest values (to_tsvector('Lore ipsum')) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DML +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 362 +select * from pendtest where 'ipsu:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +== 363 +select * from pendtest where 'ipsa:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +== 364 +select * from pendtest where 'ips:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +== 365 +select * from pendtest where 'ipt:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +== 366 +select * from pendtest where 'ipi:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +== 367 +--check OP_PHRASE on index +create temp table phrase_index_test(fts tsvector) +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DDL +STMT: CreateStmt +== 368 +insert into phrase_index_test values ('A fat cat has just eaten a rat.') +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 369 +insert into phrase_index_test values (to_tsvector('english', 'A fat cat has just eaten a rat.')) +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DML +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 370 +create index phrase_index_test_idx on phrase_index_test using gin(fts) +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DDL +STMT: IndexStmt +== 371 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 372 +select * from phrase_index_test where fts @@ phraseto_tsquery('english', 'fat cat') +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=Select +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="fts" +STMT: SelectStmt +== 373 +set enable_seqscan = on +-- +STMT: VariableSetStmt +== 374 +-- test websearch_to_tsquery function +select websearch_to_tsquery('simple', 'I have a fat:*ABCD cat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 375 +select websearch_to_tsquery('simple', 'orange:**AABBCCDD') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 376 +select websearch_to_tsquery('simple', 'fat:A!cat:B|rat:C<') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 377 +select websearch_to_tsquery('simple', 'fat:A : cat:B') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 378 +select websearch_to_tsquery('simple', 'fat*rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 379 +select websearch_to_tsquery('simple', 'fat-rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 380 +select websearch_to_tsquery('simple', 'fat_rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 381 +-- weights are completely ignored +select websearch_to_tsquery('simple', 'abc : def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 382 +select websearch_to_tsquery('simple', 'abc:def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 383 +select websearch_to_tsquery('simple', 'a:::b') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 384 +select websearch_to_tsquery('simple', 'abc:d') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 385 +select websearch_to_tsquery('simple', ':') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 386 +-- these operators are ignored +select websearch_to_tsquery('simple', 'abc & def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 387 +select websearch_to_tsquery('simple', 'abc | def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 388 +select websearch_to_tsquery('simple', 'abc <-> def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 389 +-- parens are ignored, too +select websearch_to_tsquery('simple', 'abc (pg or class)') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 390 +select websearch_to_tsquery('simple', '(foo bar) or (ding dong)') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 391 +-- NOT is ignored in quotes +select websearch_to_tsquery('english', 'My brand new smartphone') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 392 +select websearch_to_tsquery('english', 'My brand "new smartphone"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 393 +select websearch_to_tsquery('english', 'My brand "new -smartphone"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 394 +-- test OR operator +select websearch_to_tsquery('simple', 'cat or rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 395 +select websearch_to_tsquery('simple', 'cat OR rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 396 +select websearch_to_tsquery('simple', 'cat "OR" rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 397 +select websearch_to_tsquery('simple', 'cat OR') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 398 +select websearch_to_tsquery('simple', 'OR rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 399 +select websearch_to_tsquery('simple', '"fat cat OR rat"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 400 +select websearch_to_tsquery('simple', 'fat (cat OR rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 401 +select websearch_to_tsquery('simple', 'or OR or') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 402 +-- OR is an operator here ... +select websearch_to_tsquery('simple', '"fat cat"or"fat rat"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 403 +select websearch_to_tsquery('simple', 'fat or(rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 404 +select websearch_to_tsquery('simple', 'fat or)rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 405 +select websearch_to_tsquery('simple', 'fat or&rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 406 +select websearch_to_tsquery('simple', 'fat or|rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 407 +select websearch_to_tsquery('simple', 'fat or!rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 408 +select websearch_to_tsquery('simple', 'fat orrat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 410 +select websearch_to_tsquery('simple', 'fat or ') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 411 +-- ... but not here +select websearch_to_tsquery('simple', 'abc orange') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 412 +select websearch_to_tsquery('simple', 'abc OR1234') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 413 +select websearch_to_tsquery('simple', 'abc or-abc') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 414 +select websearch_to_tsquery('simple', 'abc OR_abc') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 415 +-- test quotes +select websearch_to_tsquery('english', '"pg_class pg') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 416 +select websearch_to_tsquery('english', 'pg_class pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 417 +select websearch_to_tsquery('english', '"pg_class pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 418 +select websearch_to_tsquery('english', '"pg_class : pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 419 +select websearch_to_tsquery('english', 'abc "pg_class pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 420 +select websearch_to_tsquery('english', '"pg_class pg" def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 421 +select websearch_to_tsquery('english', 'abc "pg pg_class pg" def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 422 +select websearch_to_tsquery('english', ' or "pg pg_class pg" or ') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 423 +select websearch_to_tsquery('english', '""pg pg_class pg""') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 424 +select websearch_to_tsquery('english', 'abc """"" def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 425 +select websearch_to_tsquery('english', 'cat -"fat rat"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 426 +select websearch_to_tsquery('english', 'cat -"fat rat" cheese') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 427 +select websearch_to_tsquery('english', 'abc "def -"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 428 +select websearch_to_tsquery('english', 'abc "def :"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 429 +select websearch_to_tsquery('english', '"A fat cat" has just eaten a -rat.') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 430 +select websearch_to_tsquery('english', '"A fat cat" has just eaten OR !rat.') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 431 +select websearch_to_tsquery('english', '"A fat cat" has just (+eaten OR -rat)') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 432 +select websearch_to_tsquery('english', 'this is ----fine') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 433 +select websearch_to_tsquery('english', '(()) )))) this ||| is && -fine, "dear friend" OR good') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 434 +select websearch_to_tsquery('english', 'an old <-> cat " is fine &&& too') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 435 +select websearch_to_tsquery('english', '"A the" OR just on') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 436 +select websearch_to_tsquery('english', '"a fat cat" ate a rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 437 +select to_tsvector('english', 'A fat cat ate a rat') @@ + websearch_to_tsquery('english', '"a fat cat" ate a rat') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 438 +select to_tsvector('english', 'A fat grey cat ate a rat') @@ + websearch_to_tsquery('english', '"a fat cat" ate a rat') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 439 +-- cases handled by gettoken_tsvector() +select websearch_to_tsquery('''') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 440 +select websearch_to_tsquery('''abc''''def''') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 441 +select websearch_to_tsquery('\abc') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +== 442 +select websearch_to_tsquery('\') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/tsrf.metadata.json b/parser/testdata/summary/postgres_regress/tsrf.metadata.json new file mode 100644 index 0000000..e49ea16 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tsrf.metadata.json @@ -0,0 +1,78 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tsrf.test b/parser/testdata/summary/postgres_regress/tsrf.test new file mode 100644 index 0000000..d29cca5 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tsrf.test @@ -0,0 +1,547 @@ +== 001 +|-- +-- tsrf - targetlist set returning function tests +|-- + +-- simple srf +SELECT generate_series(1, 3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 002 +-- parallel iteration +SELECT generate_series(1, 3), generate_series(3,5) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- parallel iteration, different number of rows +SELECT generate_series(1, 2), generate_series(1,4) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 004 +-- srf, with SRF argument +SELECT generate_series(1, generate_series(1, 3)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 005 +-- but we've traditionally rejected the same in FROM +SELECT * FROM generate_series(1, generate_series(1, 3)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 006 +-- srf, with two SRF arguments +SELECT generate_series(generate_series(1,3), generate_series(2, 4)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 007 +-- check proper nesting of SRFs in different expressions +explain (verbose, costs off) +SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 008 +SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 009 +CREATE TABLE few(id int, dataa text, datab text) +-- +TABLE: name="few" schema="" table="few" ctx=DDL +STMT: CreateStmt +== 010 +INSERT INTO few VALUES(1, 'a', 'foo'),(2, 'a', 'bar'),(3, 'b', 'bar') +-- +TABLE: name="few" schema="" table="few" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +-- SRF with a provably-dummy relation +explain (verbose, costs off) +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 012 +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 013 +-- SRF shouldn't prevent upper query from recognizing lower as dummy +explain (verbose, costs off) +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss +-- +TABLE: name="few" schema="" table="few" ctx=Select +TABLE: name="few" schema="" table="few" ctx=Select +ALIAS: "f1"="few" +ALIAS: "f2"="few" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 014 +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss +-- +TABLE: name="few" schema="" table="few" ctx=Select +TABLE: name="few" schema="" table="few" ctx=Select +ALIAS: "f1"="few" +ALIAS: "f2"="few" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 015 +-- SRF output order of sorting is maintained, if SRF is not referenced +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 016 +-- but SRFs can be referenced in sort +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, g DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, generate_series(1,3) DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- it's weird to have ORDER BYs that increase the number of results +SELECT few.id FROM few ORDER BY id, generate_series(1,3) DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- SRFs are computed after aggregation +SET enable_hashagg TO 0 +-- +STMT: VariableSetStmt +== 020 +-- stable output order +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="few" column="id" +STMT: SelectStmt +== 021 +-- unless referenced in GROUP BY clause +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, unnest('{1,1,3}'::int[]) +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="few" column="id" +STMT: SelectStmt +== 022 +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, 5 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="few" column="id" +STMT: SelectStmt +== 023 +RESET enable_hashagg +-- +STMT: VariableSetStmt +== 024 +-- check HAVING works when GROUP BY does [not] reference SRF output +SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1 HAVING count(*) > 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 025 +SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1, 2 HAVING count(*) > 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 026 +-- it's weird to have GROUP BYs that increase the number of results +SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa ORDER BY 2 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="dataa" +STMT: SelectStmt +== 027 +SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa, unnest('{1,1,3}'::int[]) ORDER BY 2 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="dataa" +STMT: SelectStmt +== 028 +-- SRFs are not allowed if they'd need to be conditionally executed +SELECT q1, case when q1 > 0 then generate_series(1,3) else 0 end FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 029 +SELECT q1, coalesce(generate_series(1,3), 0) FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 030 +-- SRFs are not allowed in aggregate arguments +SELECT min(generate_series(1, 3)) FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 031 +-- ... unless they're within a sub-select +SELECT sum((3 = ANY(SELECT generate_series(1,4)))::int) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT sum((3 = ANY(SELECT lag(x) over(order by x) + FROM generate_series(1,4) x))::int) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 033 +-- SRFs are not allowed in window function arguments, either +SELECT min(generate_series(1, 3)) OVER() FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 034 +-- SRFs are normally computed after window functions +SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 035 +-- unless referencing SRFs +SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- sorting + grouping +SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- grouping sets are a bit special, they produce NULLs in columns not actually NULL +set enable_hashagg = false +-- +STMT: VariableSetStmt +== 038 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 039 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY dataa +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 040 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY g +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 041 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 042 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY dataa +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 043 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY g +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 044 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 045 +-- case with degenerate ORDER BY +explain (verbose, costs off) +select 'foo' as f, generate_series(1,2) as g from few order by 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 046 +select 'foo' as f, generate_series(1,2) as g from few order by 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- data modification +CREATE TABLE fewmore AS SELECT generate_series(1,3) AS data +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 048 +INSERT INTO fewmore VALUES(generate_series(4,5)) +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 049 +SELECT * FROM fewmore +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=Select +STMT: SelectStmt +== 050 +-- SRFs are not allowed in UPDATE (they once were, but it was nonsense) +UPDATE fewmore SET data = generate_series(4,9) +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: UpdateStmt +== 051 +-- SRFs are not allowed in RETURNING +INSERT INTO fewmore VALUES(1) RETURNING generate_series(1,3) +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 052 +-- nor standalone VALUES (but surely this is a bug?) +VALUES(1, generate_series(1,2)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 053 +-- We allow tSRFs that are not at top level +SELECT int4mul(generate_series(1,2), 10) +-- +FUNCTION: name="int4mul" function="int4mul" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 054 +SELECT generate_series(1,3) IS DISTINCT FROM 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 055 +-- but SRFs in function RTEs must be at top level (annoying restriction) +SELECT * FROM int4mul(generate_series(1,2), 10) +-- +FUNCTION: name="int4mul" function="int4mul" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- DISTINCT ON is evaluated before tSRF evaluation if SRF is not +-- referenced either in ORDER BY or in the DISTINCT ON list. The ORDER +-- BY reference can be implicitly generated, if there's no other ORDER BY. + +-- implicit reference (via implicit ORDER) to all columns +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 057 +-- unreferenced in DISTINCT ON or ORDER BY +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 058 +-- referenced in ORDER BY +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC, g DESC +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 059 +-- referenced in ORDER BY and DISTINCT ON +SELECT DISTINCT ON (a, b, g) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC, g DESC +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 060 +-- only SRF mentioned in DISTINCT ON +SELECT DISTINCT ON (g) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 061 +-- LIMIT / OFFSET is evaluated after SRF evaluation +SELECT a, generate_series(1,2) FROM (VALUES(1),(2),(3)) r(a) LIMIT 2 OFFSET 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 062 +-- SRFs are not allowed in LIMIT. +SELECT 1 LIMIT generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 063 +-- tSRF in correlated subquery, referencing table outside +SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET few.id) FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 064 +-- tSRF in correlated subquery, referencing SRF outside +SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET g.i) FROM generate_series(0,3) g(i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 065 +-- Operators can return sets too +CREATE OPERATOR |@| (PROCEDURE = unnest, RIGHTARG = ANYARRAY) +-- +STMT: DefineStmt +== 066 +SELECT |@|ARRAY[1,2,3] +-- +STMT: SelectStmt +== 067 +-- Some fun cases involving duplicate SRF calls +explain (verbose, costs off) +select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 068 +select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 069 +explain (verbose, costs off) +select generate_series(1,3)+1 order by generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 070 +select generate_series(1,3)+1 order by generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 071 +-- Check that SRFs of same nesting level run in lockstep +explain (verbose, costs off) +select generate_series(1,3) as x, generate_series(3,6) + 1 as y +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 072 +select generate_series(1,3) as x, generate_series(3,6) + 1 as y +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 073 +-- Clean up +DROP TABLE few +-- +TABLE: name="few" schema="" table="few" ctx=DDL +STMT: DropStmt +== 074 +DROP TABLE fewmore +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/tstypes.metadata.json b/parser/testdata/summary/postgres_regress/tstypes.metadata.json new file mode 100644 index 0000000..1ef8c5f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tstypes.metadata.json @@ -0,0 +1,242 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tstypes.test b/parser/testdata/summary/postgres_regress/tstypes.test new file mode 100644 index 0000000..6bdc6f8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tstypes.test @@ -0,0 +1,1110 @@ +== 001 +-- deal with numeric instability of ts_rank +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +== 002 +--Base tsvector test + +SELECT '1'::tsvector +-- +STMT: SelectStmt +== 003 +SELECT '1 '::tsvector +-- +STMT: SelectStmt +== 004 +SELECT ' 1'::tsvector +-- +STMT: SelectStmt +== 005 +SELECT ' 1 '::tsvector +-- +STMT: SelectStmt +== 006 +SELECT '1 2'::tsvector +-- +STMT: SelectStmt +== 007 +SELECT '''1 2'''::tsvector +-- +STMT: SelectStmt +== 008 +SELECT E'''1 \\''2'''::tsvector +-- +STMT: SelectStmt +== 009 +SELECT E'''1 \\''2''3'::tsvector +-- +STMT: SelectStmt +== 010 +SELECT E'''1 \\''2'' 3'::tsvector +-- +STMT: SelectStmt +== 011 +SELECT E'''1 \\''2'' '' 3'' 4 '::tsvector +-- +STMT: SelectStmt +== 012 +SELECT $$'\\as' ab\c ab\\c AB\\\c ab\\\\c$$::tsvector +-- +STMT: SelectStmt +== 013 +SELECT tsvectorin(tsvectorout($$'\\as' ab\c ab\\c AB\\\c ab\\\\c$$::tsvector)) +-- +FUNCTION: name="tsvectorin" function="tsvectorin" schema="" ctx=Call +FUNCTION: name="tsvectorout" function="tsvectorout" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT '''w'':4A,3B,2C,1D,5 a:8' +-- +STMT: SelectStmt +== 015 +SELECT 'a:3A b:2a'::tsvector || 'ba:1234 a:1B' +-- +STMT: SelectStmt +== 016 +SELECT $$'' '1' '2'$$::tsvector +-- +STMT: SelectStmt +== 017 +-- error, empty lexeme is not allowed + +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('foo', 'tsvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT pg_input_is_valid($$''$$, 'tsvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT * FROM pg_input_error_info($$''$$, 'tsvector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 020 +--Base tsquery test +SELECT '1'::tsquery +-- +STMT: SelectStmt +== 021 +SELECT '1 '::tsquery +-- +STMT: SelectStmt +== 022 +SELECT ' 1'::tsquery +-- +STMT: SelectStmt +== 023 +SELECT ' 1 '::tsquery +-- +STMT: SelectStmt +== 024 +SELECT '''1 2'''::tsquery +-- +STMT: SelectStmt +== 025 +SELECT E'''1 \\''2'''::tsquery +-- +STMT: SelectStmt +== 026 +SELECT '!1'::tsquery +-- +STMT: SelectStmt +== 027 +SELECT '1|2'::tsquery +-- +STMT: SelectStmt +== 028 +SELECT '1|!2'::tsquery +-- +STMT: SelectStmt +== 029 +SELECT '!1|2'::tsquery +-- +STMT: SelectStmt +== 030 +SELECT '!1|!2'::tsquery +-- +STMT: SelectStmt +== 031 +SELECT '!(!1|!2)'::tsquery +-- +STMT: SelectStmt +== 032 +SELECT '!(!1|2)'::tsquery +-- +STMT: SelectStmt +== 033 +SELECT '!(1|!2)'::tsquery +-- +STMT: SelectStmt +== 034 +SELECT '!(1|2)'::tsquery +-- +STMT: SelectStmt +== 035 +SELECT '1&2'::tsquery +-- +STMT: SelectStmt +== 036 +SELECT '!1&2'::tsquery +-- +STMT: SelectStmt +== 037 +SELECT '1&!2'::tsquery +-- +STMT: SelectStmt +== 038 +SELECT '!1&!2'::tsquery +-- +STMT: SelectStmt +== 039 +SELECT '(1&2)'::tsquery +-- +STMT: SelectStmt +== 040 +SELECT '1&(2)'::tsquery +-- +STMT: SelectStmt +== 041 +SELECT '!(1)&2'::tsquery +-- +STMT: SelectStmt +== 042 +SELECT '!(1&2)'::tsquery +-- +STMT: SelectStmt +== 043 +SELECT '1|2&3'::tsquery +-- +STMT: SelectStmt +== 044 +SELECT '1|(2&3)'::tsquery +-- +STMT: SelectStmt +== 045 +SELECT '(1|2)&3'::tsquery +-- +STMT: SelectStmt +== 046 +SELECT '1|2&!3'::tsquery +-- +STMT: SelectStmt +== 047 +SELECT '1|!2&3'::tsquery +-- +STMT: SelectStmt +== 048 +SELECT '!1|2&3'::tsquery +-- +STMT: SelectStmt +== 049 +SELECT '!1|(2&3)'::tsquery +-- +STMT: SelectStmt +== 050 +SELECT '!(1|2)&3'::tsquery +-- +STMT: SelectStmt +== 051 +SELECT '(!1|2)&3'::tsquery +-- +STMT: SelectStmt +== 052 +SELECT '1|(2|(4|(5|6)))'::tsquery +-- +STMT: SelectStmt +== 053 +SELECT '1|2|4|5|6'::tsquery +-- +STMT: SelectStmt +== 054 +SELECT '1&(2&(4&(5&6)))'::tsquery +-- +STMT: SelectStmt +== 055 +SELECT '1&2&4&5&6'::tsquery +-- +STMT: SelectStmt +== 056 +SELECT '1&(2&(4&(5|6)))'::tsquery +-- +STMT: SelectStmt +== 057 +SELECT '1&(2&(4&(5|!6)))'::tsquery +-- +STMT: SelectStmt +== 058 +SELECT E'1&(''2''&('' 4''&(\\|5 | ''6 \\'' !|&'')))'::tsquery +-- +STMT: SelectStmt +== 059 +SELECT $$'\\as'$$::tsquery +-- +STMT: SelectStmt +== 060 +SELECT 'a:* & nbb:*ac | doo:a* | goo'::tsquery +-- +STMT: SelectStmt +== 061 +SELECT '!!b'::tsquery +-- +STMT: SelectStmt +== 062 +SELECT '!!!b'::tsquery +-- +STMT: SelectStmt +== 063 +SELECT '!(!b)'::tsquery +-- +STMT: SelectStmt +== 064 +SELECT 'a & !!b'::tsquery +-- +STMT: SelectStmt +== 065 +SELECT '!!a & b'::tsquery +-- +STMT: SelectStmt +== 066 +SELECT '!!a & !!b'::tsquery +-- +STMT: SelectStmt +== 067 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('foo', 'tsquery') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 068 +SELECT pg_input_is_valid('foo!', 'tsquery') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 069 +SELECT * FROM pg_input_error_info('foo!', 'tsquery') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 070 +SELECT * FROM pg_input_error_info('a <100000> b', 'tsquery') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 071 +--comparisons +SELECT 'a' < 'b & c'::tsquery as "true" +-- +STMT: SelectStmt +== 072 +SELECT 'a' > 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +== 073 +SELECT 'a | f' < 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +== 074 +SELECT 'a | ff' < 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +== 075 +SELECT 'a | f | g' < 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +== 076 +--concatenation +SELECT numnode( 'new'::tsquery ) +-- +FUNCTION: name="numnode" function="numnode" schema="" ctx=Call +STMT: SelectStmt +== 077 +SELECT numnode( 'new & york'::tsquery ) +-- +FUNCTION: name="numnode" function="numnode" schema="" ctx=Call +STMT: SelectStmt +== 078 +SELECT numnode( 'new & york | qwery'::tsquery ) +-- +FUNCTION: name="numnode" function="numnode" schema="" ctx=Call +STMT: SelectStmt +== 079 +SELECT 'foo & bar'::tsquery && 'asd' +-- +STMT: SelectStmt +== 080 +SELECT 'foo & bar'::tsquery || 'asd & fg' +-- +STMT: SelectStmt +== 081 +SELECT 'foo & bar'::tsquery || !!'asd & fg'::tsquery +-- +STMT: SelectStmt +== 082 +SELECT 'foo & bar'::tsquery && 'asd | fg' +-- +STMT: SelectStmt +== 083 +SELECT 'a' <-> 'b & d'::tsquery +-- +STMT: SelectStmt +== 084 +SELECT 'a & g' <-> 'b & d'::tsquery +-- +STMT: SelectStmt +== 085 +SELECT 'a & g' <-> 'b | d'::tsquery +-- +STMT: SelectStmt +== 086 +SELECT 'a & g' <-> 'b <-> d'::tsquery +-- +STMT: SelectStmt +== 087 +SELECT tsquery_phrase('a <3> g', 'b & d', 10) +-- +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +== 088 +-- tsvector-tsquery operations + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca' as "true" +-- +STMT: SelectStmt +== 089 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:B' as "true" +-- +STMT: SelectStmt +== 090 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:A' as "true" +-- +STMT: SelectStmt +== 091 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:C' as "false" +-- +STMT: SelectStmt +== 092 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:CB' as "true" +-- +STMT: SelectStmt +== 093 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*C' as "false" +-- +STMT: SelectStmt +== 094 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*CB' as "true" +-- +STMT: SelectStmt +== 095 +SELECT 'a b:89 ca:23A,64b cb:80c d:34c'::tsvector @@ 'd:AC & c:*C' as "true" +-- +STMT: SelectStmt +== 096 +SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*C' as "true" +-- +STMT: SelectStmt +== 097 +SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*B' as "true" +-- +STMT: SelectStmt +== 098 +SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D & w:*A'::tsquery as "true" +-- +STMT: SelectStmt +== 099 +SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D <-> w:*A'::tsquery as "true" +-- +STMT: SelectStmt +== 100 +SELECT 'wa:1A wb:2D'::tsvector @@ 'w:*D <-> w:*A'::tsquery as "false" +-- +STMT: SelectStmt +== 101 +SELECT 'wa:1A'::tsvector @@ 'w:*A'::tsquery as "true" +-- +STMT: SelectStmt +== 102 +SELECT 'wa:1A'::tsvector @@ 'w:*D'::tsquery as "false" +-- +STMT: SelectStmt +== 103 +SELECT 'wa:1A'::tsvector @@ '!w:*A'::tsquery as "false" +-- +STMT: SelectStmt +== 104 +SELECT 'wa:1A'::tsvector @@ '!w:*D'::tsquery as "true" +-- +STMT: SelectStmt +== 105 +-- historically, a stripped tsvector matches queries ignoring weights: +SELECT strip('wa:1A'::tsvector) @@ 'w:*A'::tsquery as "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +== 106 +SELECT strip('wa:1A'::tsvector) @@ 'w:*D'::tsquery as "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +== 107 +SELECT strip('wa:1A'::tsvector) @@ '!w:*A'::tsquery as "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +== 108 +SELECT strip('wa:1A'::tsvector) @@ '!w:*D'::tsquery as "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +== 109 +SELECT 'supernova'::tsvector @@ 'super'::tsquery AS "false" +-- +STMT: SelectStmt +== 110 +SELECT 'supeanova supernova'::tsvector @@ 'super'::tsquery AS "false" +-- +STMT: SelectStmt +== 111 +SELECT 'supeznova supernova'::tsvector @@ 'super'::tsquery AS "false" +-- +STMT: SelectStmt +== 112 +SELECT 'supernova'::tsvector @@ 'super:*'::tsquery AS "true" +-- +STMT: SelectStmt +== 113 +SELECT 'supeanova supernova'::tsvector @@ 'super:*'::tsquery AS "true" +-- +STMT: SelectStmt +== 114 +SELECT 'supeznova supernova'::tsvector @@ 'super:*'::tsquery AS "true" +-- +STMT: SelectStmt +== 115 +--phrase search +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 2' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 116 +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 2' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 117 +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 3' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 118 +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 119 +SELECT to_tsvector('simple', '1 2 1 2') @@ '1 <3> 2' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 120 +SELECT to_tsvector('simple', '1 2 11 3') @@ '1 <-> 3' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 121 +SELECT to_tsvector('simple', '1 2 11 3') @@ '1:* <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 122 +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> 2 <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 123 +SELECT to_tsvector('simple', '1 2 3 4') @@ '(1 <-> 2) <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 124 +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> (2 <-> 3)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 125 +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <2> (2 <-> 3)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 126 +SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '(1 <-> 2) <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 127 +SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '1 <-> 2 <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 128 +-- without position data, phrase search does not match +SELECT strip(to_tsvector('simple', '1 2 3 4')) @@ '1 <-> 2 <-> 3' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 129 +select to_tsvector('simple', 'q x q y') @@ 'q <-> (x & y)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 130 +select to_tsvector('simple', 'q x') @@ 'q <-> (x | y <-> z)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 131 +select to_tsvector('simple', 'q y') @@ 'q <-> (x | y <-> z)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 132 +select to_tsvector('simple', 'q y z') @@ 'q <-> (x | y <-> z)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 133 +select to_tsvector('simple', 'q y x') @@ 'q <-> (x | y <-> z)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 134 +select to_tsvector('simple', 'q x y') @@ 'q <-> (x | y <-> z)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 135 +select to_tsvector('simple', 'q x') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 136 +select to_tsvector('simple', 'x q') @@ '(x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 137 +select to_tsvector('simple', 'x y q') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 138 +select to_tsvector('simple', 'x y z') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 139 +select to_tsvector('simple', 'x y z q') @@ '(x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 140 +select to_tsvector('simple', 'y z q') @@ '(x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 141 +select to_tsvector('simple', 'y y q') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 142 +select to_tsvector('simple', 'y y q') @@ '(!x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 143 +select to_tsvector('simple', 'x y q') @@ '(!x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 144 +select to_tsvector('simple', 'y y q') @@ '(x | y <-> !z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 145 +select to_tsvector('simple', 'x q') @@ '(x | y <-> !z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 146 +select to_tsvector('simple', 'x q') @@ '(!x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 147 +select to_tsvector('simple', 'z q') @@ '(!x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 148 +select to_tsvector('simple', 'x y q') @@ '(!x | y) <-> y <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 149 +select to_tsvector('simple', 'x y q') @@ '(!x | !y) <-> y <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 150 +select to_tsvector('simple', 'x y q') @@ '(x | !y) <-> y <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 151 +select to_tsvector('simple', 'x y q') @@ '(x | !!z) <-> y <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 152 +select to_tsvector('simple', 'x y q y') @@ '!x <-> y' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 153 +select to_tsvector('simple', 'x y q y') @@ '!x <-> !y' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 154 +select to_tsvector('simple', 'x y q y') @@ '!x <-> !!y' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 155 +select to_tsvector('simple', 'x y q y') @@ '!(x <-> y)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 156 +select to_tsvector('simple', 'x y q y') @@ '!(x <2> y)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 157 +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> y' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 158 +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !y' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 159 +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !!y' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 160 +select strip(to_tsvector('simple', 'x y q y')) @@ '!(x <-> y)' AS "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 161 +select strip(to_tsvector('simple', 'x y q y')) @@ '!(x <2> y)' AS "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 162 +select to_tsvector('simple', 'x y q y') @@ '!foo' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 163 +select to_tsvector('simple', '') @@ '!foo' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 164 +--ranking +SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 165 +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 166 +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s:*') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 167 +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | sa:*') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 168 +SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 169 +SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 170 +SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 171 +SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 172 +SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +== 173 +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 174 +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 175 +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 176 +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | sa:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 177 +SELECT ts_rank_cd(' a:1 sa:3C sab:2c d g'::tsvector, 'a | sa:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 178 +SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 179 +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 180 +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 181 +SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 182 +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 183 +SELECT ts_rank_cd(' a:1 s:2A d g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 184 +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 185 +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 186 +SELECT ts_rank_cd(' a:1 s:2 d:2A g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 187 +SELECT ts_rank_cd(' a:1 s:2,3A d:2A g'::tsvector, 'a <2> s:A') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 188 +SELECT ts_rank_cd(' a:1 b:2 s:3A d:2A g'::tsvector, 'a <2> s:A') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 189 +SELECT ts_rank_cd(' a:1 sa:2D sb:2A g'::tsvector, 'a <-> s:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 190 +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 191 +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:A') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 192 +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:B') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +== 193 +SELECT 'a:1 b:2'::tsvector @@ 'a <-> b'::tsquery AS "true" +-- +STMT: SelectStmt +== 194 +SELECT 'a:1 b:2'::tsvector @@ 'a <0> b'::tsquery AS "false" +-- +STMT: SelectStmt +== 195 +SELECT 'a:1 b:2'::tsvector @@ 'a <1> b'::tsquery AS "true" +-- +STMT: SelectStmt +== 196 +SELECT 'a:1 b:2'::tsvector @@ 'a <2> b'::tsquery AS "false" +-- +STMT: SelectStmt +== 197 +SELECT 'a:1 b:3'::tsvector @@ 'a <-> b'::tsquery AS "false" +-- +STMT: SelectStmt +== 198 +SELECT 'a:1 b:3'::tsvector @@ 'a <0> b'::tsquery AS "false" +-- +STMT: SelectStmt +== 199 +SELECT 'a:1 b:3'::tsvector @@ 'a <1> b'::tsquery AS "false" +-- +STMT: SelectStmt +== 200 +SELECT 'a:1 b:3'::tsvector @@ 'a <2> b'::tsquery AS "true" +-- +STMT: SelectStmt +== 201 +SELECT 'a:1 b:3'::tsvector @@ 'a <3> b'::tsquery AS "false" +-- +STMT: SelectStmt +== 202 +SELECT 'a:1 b:3'::tsvector @@ 'a <0> a:*'::tsquery AS "true" +-- +STMT: SelectStmt +== 203 +-- tsvector editing operations + +SELECT strip('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd'::tsvector) +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +== 204 +SELECT strip('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +== 205 +SELECT strip('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +== 206 +SELECT ts_delete(to_tsvector('english', 'Rebel spaceships, striking from a hidden base'), 'spaceship') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 207 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'base') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 208 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bas') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 209 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bases') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 210 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'spaceship') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 211 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, 'spaceship') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 212 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceship','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 213 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceships','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 214 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceshi','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 215 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceship','leya','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 216 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 217 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 218 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel', '', NULL]) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +== 219 +SELECT unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 220 +SELECT unnest('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 221 +SELECT * FROM unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 222 +SELECT * FROM unnest('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 223 +SELECT lexeme, positions[1] from unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +== 224 +SELECT tsvector_to_array('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="tsvector_to_array" function="tsvector_to_array" schema="" ctx=Call +STMT: SelectStmt +== 225 +SELECT tsvector_to_array('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="tsvector_to_array" function="tsvector_to_array" schema="" ctx=Call +STMT: SelectStmt +== 226 +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship','strike']) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 227 +-- null and empty string are disallowed, since we mustn't make an empty lexeme +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship', NULL]) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 228 +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship', '']) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 229 +-- array_to_tsvector must sort and de-dup +SELECT array_to_tsvector(ARRAY['foo','bar','baz','bar']) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +== 230 +SELECT setweight('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd zxc:81,567,222A'::tsvector, 'c') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +== 231 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +== 232 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +== 233 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +== 234 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a,zxc}') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +== 235 +SELECT setweight('a asd w:5,6,12B,13A zxc'::tsvector, 'c', ARRAY['a', 'zxc', '', NULL]) +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +== 236 +SELECT ts_filter('base:7A empir:17 evil:15 first:11 galact:16 hidden:6A rebel:1A spaceship:2A strike:3A victori:12 won:9'::tsvector, '{a}') +-- +FUNCTION: name="ts_filter" function="ts_filter" schema="" ctx=Call +STMT: SelectStmt +== 237 +SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a}') +-- +FUNCTION: name="ts_filter" function="ts_filter" schema="" ctx=Call +STMT: SelectStmt +== 238 +SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a,b,NULL}') +-- +FUNCTION: name="ts_filter" function="ts_filter" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/tuplesort.metadata.json b/parser/testdata/summary/postgres_regress/tuplesort.metadata.json new file mode 100644 index 0000000..c2deed3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tuplesort.metadata.json @@ -0,0 +1,110 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106" + ] +} diff --git a/parser/testdata/summary/postgres_regress/tuplesort.test b/parser/testdata/summary/postgres_regress/tuplesort.test new file mode 100644 index 0000000..ab5ddd6 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/tuplesort.test @@ -0,0 +1,659 @@ +== 001 +-- only use parallelism when explicitly intending to do so +SET max_parallel_maintenance_workers = 0 +-- +STMT: VariableSetStmt +== 002 +SET max_parallel_workers = 0 +-- +STMT: VariableSetStmt +== 003 +-- A table with contents that, when sorted, triggers abbreviated +-- key aborts. One easy way to achieve that is to use uuids that all +-- have the same prefix, as abbreviated keys for uuids just use the +-- first sizeof(Datum) bytes. +CREATE TEMP TABLE abbrev_abort_uuids ( + id serial not null, + abort_increasing uuid, + abort_decreasing uuid, + noabort_increasing uuid, + noabort_decreasing uuid) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: CreateStmt +== 004 +INSERT INTO abbrev_abort_uuids (abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing) + SELECT + ('00000000-0000-0000-0000-'||to_char(g.i, '000000000000FM'))::uuid abort_increasing, + ('00000000-0000-0000-0000-'||to_char(20000 - g.i, '000000000000FM'))::uuid abort_decreasing, + (to_char(g.i % 10009, '00000000FM')||'-0000-0000-0000-'||to_char(g.i, '000000000000FM'))::uuid noabort_increasing, + (to_char(((20000 - g.i) % 10009), '00000000FM')||'-0000-0000-0000-'||to_char(20000 - g.i, '000000000000FM'))::uuid noabort_decreasing + FROM generate_series(0, 20000, 1) g(i) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 005 +-- and a few NULLs +INSERT INTO abbrev_abort_uuids(id) VALUES(0) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO abbrev_abort_uuids DEFAULT VALUES +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +STMT: InsertStmt +== 007 +INSERT INTO abbrev_abort_uuids DEFAULT VALUES +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +STMT: InsertStmt +== 008 +-- add just a few duplicates +INSERT INTO abbrev_abort_uuids (abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing) + SELECT abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing + FROM abbrev_abort_uuids + WHERE (id < 10 OR id > 19990) AND id % 3 = 0 AND abort_increasing is not null +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="abort_increasing" +STMT: InsertStmt +STMT: SelectStmt +== 009 +---- +-- Check sort node uses of tuplesort wrt. abbreviated keys +---- + +-- plain sort triggering abbreviated abort +SELECT abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 010 +SELECT abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing NULLS FIRST OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 011 +-- plain sort not triggering abbreviated abort +SELECT noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 012 +SELECT noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing NULLS FIRST OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 013 +-- bounded sort (disables abbreviated keys) +SELECT abort_increasing, noabort_increasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 014 +SELECT abort_increasing, noabort_increasing FROM abbrev_abort_uuids ORDER BY noabort_increasing NULLS FIRST LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 015 +---- +-- Check index creation uses of tuplesort wrt. abbreviated keys +---- + +-- index creation using abbreviated keys successfully +CREATE INDEX abbrev_abort_uuids__noabort_increasing_idx ON abbrev_abort_uuids (noabort_increasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +== 016 +CREATE INDEX abbrev_abort_uuids__noabort_decreasing_idx ON abbrev_abort_uuids (noabort_decreasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +== 017 +-- verify +EXPLAIN (COSTS OFF) +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 018 +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 019 +EXPLAIN (COSTS OFF) +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 020 +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 021 +-- index creation using abbreviated keys, hitting abort +CREATE INDEX abbrev_abort_uuids__abort_increasing_idx ON abbrev_abort_uuids (abort_increasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +== 022 +CREATE INDEX abbrev_abort_uuids__abort_decreasing_idx ON abbrev_abort_uuids (abort_decreasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +== 023 +-- verify +EXPLAIN (COSTS OFF) +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 024 +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 025 +EXPLAIN (COSTS OFF) +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 026 +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 027 +---- +-- Check CLUSTER uses of tuplesort wrt. abbreviated keys +---- + +-- when aborting, increasing order +BEGIN +-- +STMT: TransactionStmt +== 028 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +== 029 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_increasing_idx +-- +STMT: ClusterStmt +== 030 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 031 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 032 +ROLLBACK +-- +STMT: TransactionStmt +== 033 +-- when aborting, decreasing order +BEGIN +-- +STMT: TransactionStmt +== 034 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +== 035 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_decreasing_idx +-- +STMT: ClusterStmt +== 036 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 037 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 038 +ROLLBACK +-- +STMT: TransactionStmt +== 039 +-- when not aborting, increasing order +BEGIN +-- +STMT: TransactionStmt +== 040 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +== 041 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_increasing_idx +-- +STMT: ClusterStmt +== 042 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 043 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 044 +ROLLBACK +-- +STMT: TransactionStmt +== 045 +-- when no aborting, decreasing order +BEGIN +-- +STMT: TransactionStmt +== 046 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +== 047 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_decreasing_idx +-- +STMT: ClusterStmt +== 048 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 049 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +== 050 +ROLLBACK +-- +STMT: TransactionStmt +== 051 +---- +-- test sorting of large datums VALUES +---- + +-- Ensure the order is correct and values look intact +SELECT LEFT(a,10),b FROM + (VALUES(REPEAT('a', 512 * 1024),1),(REPEAT('b', 512 * 1024),2)) v(a,b) +ORDER BY v.a DESC +-- +FUNCTION: name="left" function="left" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +== 052 +---- +-- test forward and backward scans for in-memory and disk based tuplesort +---- + +-- in-memory +BEGIN +-- +STMT: TransactionStmt +== 053 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +== 054 +-- unfortunately can't show analyze output confirming sort method, +-- the memory used output wouldn't be stable +EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +== 055 +DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: DeclareCursorStmt +== 056 +-- first and second +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 057 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 058 +-- scroll beyond beginning +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 059 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 060 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 061 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 062 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 063 +-- scroll beyond end +FETCH LAST FROM c +-- +STMT: FetchStmt +== 064 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 065 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 066 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 067 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 068 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 069 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 070 +COMMIT +-- +STMT: TransactionStmt +== 071 +-- disk based +BEGIN +-- +STMT: TransactionStmt +== 072 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +== 073 +SET LOCAL work_mem = '100kB' +-- +STMT: VariableSetStmt +== 074 +-- unfortunately can't show analyze output confirming sort method, +-- the memory used output wouldn't be stable +EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +== 075 +DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: DeclareCursorStmt +== 076 +-- first and second +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 077 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 078 +-- scroll beyond beginning +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 079 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 080 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 081 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 082 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 083 +-- scroll beyond end +FETCH LAST FROM c +-- +STMT: FetchStmt +== 084 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 085 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 086 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 087 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 088 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +== 089 +FETCH NEXT FROM c +-- +STMT: FetchStmt +== 090 +COMMIT +-- +STMT: TransactionStmt +== 091 +---- +-- test tuplesort using both in-memory and disk sort +--- + +-- memory based +SELECT + -- fixed-width by-value datum + (array_agg(id ORDER BY id DESC NULLS FIRST))[0:5], + -- fixed-width by-ref datum + (array_agg(abort_increasing ORDER BY abort_increasing DESC NULLS LAST))[0:5], + -- variable-width datum + (array_agg(id::text ORDER BY id::text DESC NULLS LAST))[0:5], + -- fixed width by-value datum tuplesort + percentile_disc(0.99) WITHIN GROUP (ORDER BY id), + -- ensure state is shared + percentile_disc(0.01) WITHIN GROUP (ORDER BY id), + -- fixed width by-ref datum tuplesort + percentile_disc(0.8) WITHIN GROUP (ORDER BY abort_increasing), + -- variable width by-ref datum tuplesort + percentile_disc(0.2) WITHIN GROUP (ORDER BY id::text), + -- multi-column tuplesort + rank('00000000-0000-0000-0000-000000000000', '2', '2') WITHIN GROUP (ORDER BY noabort_increasing, id, id::text) +FROM ( + SELECT * FROM abbrev_abort_uuids + UNION ALL + SELECT NULL, NULL, NULL, NULL, NULL) s +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 092 +-- disk based (see also above) +BEGIN +-- +STMT: TransactionStmt +== 093 +SET LOCAL work_mem = '100kB' +-- +STMT: VariableSetStmt +== 094 +SELECT + (array_agg(id ORDER BY id DESC NULLS FIRST))[0:5], + (array_agg(abort_increasing ORDER BY abort_increasing DESC NULLS LAST))[0:5], + (array_agg(id::text ORDER BY id::text DESC NULLS LAST))[0:5], + percentile_disc(0.99) WITHIN GROUP (ORDER BY id), + percentile_disc(0.01) WITHIN GROUP (ORDER BY id), + percentile_disc(0.8) WITHIN GROUP (ORDER BY abort_increasing), + percentile_disc(0.2) WITHIN GROUP (ORDER BY id::text), + rank('00000000-0000-0000-0000-000000000000', '2', '2') WITHIN GROUP (ORDER BY noabort_increasing, id, id::text) +FROM ( + SELECT * FROM abbrev_abort_uuids + UNION ALL + SELECT NULL, NULL, NULL, NULL, NULL) s +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 095 +ROLLBACK +-- +STMT: TransactionStmt +== 096 +---- +-- test tuplesort mark/restore +--- + +CREATE TEMP TABLE test_mark_restore(col1 int, col2 int, col12 int) +-- +TABLE: name="test_mark_restore" schema="" table="test_mark_restore" ctx=DDL +STMT: CreateStmt +== 097 +-- need a few duplicates for mark/restore to matter +INSERT INTO test_mark_restore(col1, col2, col12) + SELECT a.i, b.i, a.i * b.i FROM generate_series(1, 500) a(i), generate_series(1, 5) b(i) +-- +TABLE: name="test_mark_restore" schema="" table="test_mark_restore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 098 +BEGIN +-- +STMT: TransactionStmt +== 099 +SET LOCAL enable_nestloop = off +-- +STMT: VariableSetStmt +== 100 +SET LOCAL enable_hashjoin = off +-- +STMT: VariableSetStmt +== 101 +SET LOCAL enable_material = off +-- +STMT: VariableSetStmt +== 102 +-- set query into variable once, to avoid repetition of the fairly long query +SELECT $$ + SELECT col12, count(distinct a.col1), count(distinct a.col2), count(distinct b.col1), count(distinct b.col2), count(*) + FROM test_mark_restore a + JOIN test_mark_restore b USING(col12) + GROUP BY 1 + HAVING count(*) > 1 + ORDER BY 2 DESC, 1 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC + LIMIT 10 +$$ AS qry +-- +STMT: SelectStmt +== 103 +-- test mark/restore with in-memory sorts +EXPLAIN (COSTS OFF) :qry +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 104 +-- test mark/restore with on-disk sorts +SET LOCAL work_mem = '100kB' +-- +STMT: VariableSetStmt +== 105 +EXPLAIN (COSTS OFF) :qry +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 106 +COMMIT +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/txid.metadata.json b/parser/testdata/summary/postgres_regress/txid.metadata.json new file mode 100644 index 0000000..c7ce9e3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/txid.metadata.json @@ -0,0 +1,51 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047" + ] +} diff --git a/parser/testdata/summary/postgres_regress/txid.test b/parser/testdata/summary/postgres_regress/txid.test new file mode 100644 index 0000000..b6a5cd0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/txid.test @@ -0,0 +1,284 @@ +== 001 +-- txid_snapshot data type and related functions +-- Note: these are backward-compatibility functions and types, and have been +-- replaced by new xid8-based variants. See xid.sql. The txid variants will +-- be removed in a future release. + +-- i/o +select '12:13:'::txid_snapshot +-- +STMT: SelectStmt +== 002 +select '12:18:14,16'::txid_snapshot +-- +STMT: SelectStmt +== 003 +select '12:16:14,14'::txid_snapshot +-- +STMT: SelectStmt +== 004 +-- errors +select '31:12:'::txid_snapshot +-- +STMT: SelectStmt +== 005 +select '0:1:'::txid_snapshot +-- +STMT: SelectStmt +== 006 +select '12:13:0'::txid_snapshot +-- +STMT: SelectStmt +== 007 +select '12:16:14,13'::txid_snapshot +-- +STMT: SelectStmt +== 008 +create temp table snapshot_test ( + nr integer, + snap txid_snapshot +) +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DDL +STMT: CreateStmt +== 009 +insert into snapshot_test values (1, '12:13:') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +insert into snapshot_test values (2, '12:20:13,15,18') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 011 +insert into snapshot_test values (3, '100001:100009:100005,100007,100008') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +select snap from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +STMT: SelectStmt +== 014 +select txid_snapshot_xmin(snap), + txid_snapshot_xmax(snap), + txid_snapshot_xip(snap) +from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="txid_snapshot_xmin" function="txid_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="txid_snapshot_xmax" function="txid_snapshot_xmax" schema="" ctx=Call +FUNCTION: name="txid_snapshot_xip" function="txid_snapshot_xip" schema="" ctx=Call +STMT: SelectStmt +== 015 +select id, txid_visible_in_snapshot(id, snap) +from snapshot_test, generate_series(11, 21) id +where nr = 2 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 016 +-- test bsearch +select id, txid_visible_in_snapshot(id, snap) +from snapshot_test, generate_series(90, 160) id +where nr = 4 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 017 +-- test current values also +select txid_current() >= txid_snapshot_xmin(txid_current_snapshot()) +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +FUNCTION: name="txid_snapshot_xmin" function="txid_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="txid_current_snapshot" function="txid_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 018 +-- we can't assume current is always less than xmax, however + +select txid_visible_in_snapshot(txid_current(), txid_current_snapshot()) +-- +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +FUNCTION: name="txid_current_snapshot" function="txid_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 019 +-- test 64bitness + +select txid_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013' +-- +STMT: SelectStmt +== 020 +select txid_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 021 +select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 022 +-- test 64bit overflow +SELECT txid_snapshot '1:9223372036854775807:3' +-- +STMT: SelectStmt +== 023 +SELECT txid_snapshot '1:9223372036854775808:3' +-- +STMT: SelectStmt +== 024 +-- test txid_current_if_assigned +BEGIN +-- +STMT: TransactionStmt +== 025 +SELECT txid_current_if_assigned() IS NULL +-- +FUNCTION: name="txid_current_if_assigned" function="txid_current_if_assigned" schema="" ctx=Call +STMT: SelectStmt +== 026 +SELECT txid_current() +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT txid_current_if_assigned() IS NOT DISTINCT FROM BIGINT :'txid_current' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 028 +COMMIT +-- +STMT: TransactionStmt +== 029 +-- test xid status functions +BEGIN +-- +STMT: TransactionStmt +== 030 +SELECT txid_current() AS committed +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +== 031 +COMMIT +-- +STMT: TransactionStmt +== 032 +BEGIN +-- +STMT: TransactionStmt +== 033 +SELECT txid_current() AS rolledback +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +== 034 +ROLLBACK +-- +STMT: TransactionStmt +== 035 +BEGIN +-- +STMT: TransactionStmt +== 036 +SELECT txid_current() AS inprogress +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +== 037 +SELECT txid_status(:committed) AS committed +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +SELECT txid_status(:rolledback) AS rolledback +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +SELECT txid_status(:inprogress) AS inprogress +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 040 +SELECT txid_status(1) +-- +FUNCTION: name="txid_status" function="txid_status" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- BootstrapTransactionId is always committed +SELECT txid_status(2) +-- +FUNCTION: name="txid_status" function="txid_status" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- FrozenTransactionId is always committed +SELECT txid_status(3) +-- +FUNCTION: name="txid_status" function="txid_status" schema="" ctx=Call +STMT: SelectStmt +== 043 +-- in regress testing FirstNormalTransactionId will always be behind oldestXmin + +COMMIT +-- +STMT: TransactionStmt +== 044 +BEGIN +-- +STMT: TransactionStmt +== 045 +CREATE FUNCTION test_future_xid_status(bigint) +RETURNS void +LANGUAGE plpgsql +AS +$$ +BEGIN + PERFORM txid_status($1); + RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected'; +EXCEPTION + WHEN invalid_parameter_value THEN + RAISE NOTICE 'Got expected error for xid in the future'; +END; +$$ +-- +FUNCTION: name="test_future_xid_status" function="test_future_xid_status" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 046 +SELECT test_future_xid_status(:inprogress + 10000) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 31 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 047 +ROLLBACK +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/type_sanity.metadata.json b/parser/testdata/summary/postgres_regress/type_sanity.metadata.json new file mode 100644 index 0000000..6a71114 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/type_sanity.metadata.json @@ -0,0 +1,65 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061" + ] +} diff --git a/parser/testdata/summary/postgres_regress/type_sanity.test b/parser/testdata/summary/postgres_regress/type_sanity.test new file mode 100644 index 0000000..ddb7771 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/type_sanity.test @@ -0,0 +1,1180 @@ +== 001 +|-- +-- TYPE_SANITY +-- Sanity checks for common errors in making type-related system tables: +-- pg_type, pg_class, pg_attribute, pg_range. +|-- +-- None of the SELECTs here should ever find any matching entries, +-- so the expected output is easy to maintain ;-). +-- A test failure indicates someone messed up an entry in the system tables. +|-- +-- NB: we assume the oidjoins test will have caught any dangling links, +-- that is OID or REGPROC fields that are not zero and do not match some +-- row in the linked-to table. However, if we want to enforce that a link +-- field can't be 0, we have to check it here. + +-- **************** pg_type **************** + +-- Look for illegal values in pg_type fields. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typnamespace = 0 OR + (t1.typlen <= 0 AND t1.typlen != -1 AND t1.typlen != -2) OR + (t1.typtype not in ('b', 'c', 'd', 'e', 'm', 'p', 'r')) OR + NOT t1.typisdefined OR + (t1.typalign not in ('c', 's', 'i', 'd')) OR + (t1.typstorage not in ('p', 'x', 'e', 'm')) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typnamespace" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typisdefined" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typstorage" +STMT: SelectStmt +== 002 +-- Look for "pass by value" types that can't be passed by value. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typbyval AND + (t1.typlen != 1 OR t1.typalign != 'c') AND + (t1.typlen != 2 OR t1.typalign != 's') AND + (t1.typlen != 4 OR t1.typalign != 'i') AND + (t1.typlen != 8 OR t1.typalign != 'd') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typbyval" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +STMT: SelectStmt +== 003 +-- Look for "toastable" types that aren't varlena. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typstorage != 'p' AND + (t1.typbyval OR t1.typlen != -1) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typstorage" +FILTER: schema="" table="t1" column="typbyval" +FILTER: schema="" table="t1" column="typlen" +STMT: SelectStmt +== 004 +-- Look for complex types that do not have a typrelid entry, +-- or basic types that do. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE (t1.typtype = 'c' AND t1.typrelid = 0) OR + (t1.typtype != 'c' AND t1.typrelid != 0) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typrelid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typrelid" +STMT: SelectStmt +== 005 +-- Look for types that should have an array type but don't. +-- Generally anything that's not a pseudotype should have an array type. +-- However, we do have a small number of exceptions. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typtype not in ('p') AND t1.typname NOT LIKE E'\\_%' + AND NOT EXISTS + (SELECT 1 FROM pg_type as t2 + WHERE t2.typname = ('_' || t1.typname)::name AND + t2.typelem = t1.oid and t1.typarray = t2.oid) +ORDER BY t1.oid +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typname" +FILTER: schema="" table="t2" column="typname" +FILTER: schema="" table="t1" column="typname" +FILTER: schema="" table="t2" column="typelem" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +STMT: SelectStmt +== 006 +-- Make sure typarray points to a "true" array type of our own base +SELECT t1.oid, t1.typname as basetype, t2.typname as arraytype, + t2.typsubscript +FROM pg_type t1 LEFT JOIN pg_type t2 ON (t1.typarray = t2.oid) +WHERE t1.typarray <> 0 AND + (t2.oid IS NULL OR + t2.typsubscript <> 'array_subscript_handler'::regproc) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t2" column="typsubscript" +STMT: SelectStmt +== 007 +-- Look for range types that do not have a pg_range entry +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typtype = 'r' AND + NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = t1.oid) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="" column="rngtypid" +FILTER: schema="" table="t1" column="oid" +STMT: SelectStmt +== 008 +-- Look for range types whose typalign isn't sufficient +SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign +FROM pg_type as t1 + LEFT JOIN pg_range as r ON rngtypid = t1.oid + LEFT JOIN pg_type as t2 ON rngsubtype = t2.oid +WHERE t1.typtype = 'r' AND + (t1.typalign != (CASE WHEN t2.typalign = 'd' THEN 'd'::"char" + ELSE 'i'::"char" END) + OR t2.oid IS NULL) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t2" column="typalign" +FILTER: schema="" table="t2" column="oid" +STMT: SelectStmt +== 009 +-- Text conversion routines must be provided. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE (t1.typinput = 0 OR t1.typoutput = 0) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="t1" column="typoutput" +STMT: SelectStmt +== 010 +-- Check for bogus typinput routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND NOT + ((p1.pronargs = 1 AND p1.proargtypes[0] = 'cstring'::regtype) OR + (p1.pronargs = 2 AND p1.proargtypes[0] = 'cstring'::regtype AND + p1.proargtypes[1] = 'oid'::regtype) OR + (p1.pronargs = 3 AND p1.proargtypes[0] = 'cstring'::regtype AND + p1.proargtypes[1] = 'oid'::regtype AND + p1.proargtypes[2] = 'int4'::regtype)) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 011 +-- As of 8.0, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.prorettype = t1.oid AND NOT p1.proretset) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +== 012 +-- Varlena array types will point to array_in +-- Exception as of 8.1: int2vector and oidvector have their own I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.oid = 'array_in'::regproc) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +== 013 +-- typinput routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 014 +-- Composites, domains, enums, multiranges, ranges should all use the same input routines +SELECT DISTINCT typtype, typinput +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +== 015 +-- Check for bogus typoutput routines + +-- As of 8.0, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (p1.pronargs = 1 AND + (p1.proargtypes[0] = t1.oid OR + (p1.oid = 'array_out'::regproc AND + t1.typelem != 0 AND t1.typlen = -1))) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +STMT: SelectStmt +== 016 +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND NOT + (p1.prorettype = 'cstring'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +== 017 +-- typoutput routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 018 +-- Composites, enums, multiranges, ranges should all use the same output routines +SELECT DISTINCT typtype, typoutput +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'd', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +== 019 +-- Domains should have same typoutput as their base types +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid +WHERE t1.typtype = 'd' AND t1.typoutput IS DISTINCT FROM t2.typoutput +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="t2" column="typoutput" +STMT: SelectStmt +== 020 +-- Check for bogus typreceive routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND NOT + ((p1.pronargs = 1 AND p1.proargtypes[0] = 'internal'::regtype) OR + (p1.pronargs = 2 AND p1.proargtypes[0] = 'internal'::regtype AND + p1.proargtypes[1] = 'oid'::regtype) OR + (p1.pronargs = 3 AND p1.proargtypes[0] = 'internal'::regtype AND + p1.proargtypes[1] = 'oid'::regtype AND + p1.proargtypes[2] = 'int4'::regtype)) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +== 021 +-- As of 7.4, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.prorettype = t1.oid AND NOT p1.proretset) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +== 022 +-- Varlena array types will point to array_recv +-- Exception as of 8.1: int2vector and oidvector have their own I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.oid = 'array_recv'::regproc) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +== 023 +-- Suspicious if typreceive doesn't take same number of args as typinput +SELECT t1.oid, t1.typname, p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_type AS t1, pg_proc AS p1, pg_proc AS p2 +WHERE t1.typinput = p1.oid AND t1.typreceive = p2.oid AND + p1.pronargs != p2.pronargs +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p2" column="pronargs" +STMT: SelectStmt +== 024 +-- typreceive routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 025 +-- Composites, domains, enums, multiranges, ranges should all use the same receive routines +SELECT DISTINCT typtype, typreceive +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +== 026 +-- Check for bogus typsend routines + +-- As of 7.4, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (p1.pronargs = 1 AND + (p1.proargtypes[0] = t1.oid OR + (p1.oid = 'array_send'::regproc AND + t1.typelem != 0 AND t1.typlen = -1))) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +STMT: SelectStmt +== 027 +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND NOT + (p1.prorettype = 'bytea'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +== 028 +-- typsend routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 029 +-- Composites, enums, multiranges, ranges should all use the same send routines +SELECT DISTINCT typtype, typsend +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'd', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +== 030 +-- Domains should have same typsend as their base types +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid +WHERE t1.typtype = 'd' AND t1.typsend IS DISTINCT FROM t2.typsend +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="t2" column="typsend" +STMT: SelectStmt +== 031 +-- Check for bogus typmodin routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodin = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'cstring[]'::regtype AND + p1.prorettype = 'int4'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodin" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +== 032 +-- typmodin routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodin = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodin" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 033 +-- Check for bogus typmodout routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodout = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'int4'::regtype AND + p1.prorettype = 'cstring'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodout" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +== 034 +-- typmodout routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodout = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodout" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +== 035 +-- Array types should have same typmodin/out as their element types + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typelem = t2.oid AND NOT + (t1.typmodin = t2.typmodin AND t1.typmodout = t2.typmodout) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t1" column="typmodin" +FILTER: schema="" table="t2" column="typmodin" +FILTER: schema="" table="t1" column="typmodout" +FILTER: schema="" table="t2" column="typmodout" +STMT: SelectStmt +== 036 +-- Array types should have same typdelim as their element types + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typarray = t2.oid AND NOT (t1.typdelim = t2.typdelim) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t1" column="typdelim" +FILTER: schema="" table="t2" column="typdelim" +STMT: SelectStmt +== 037 +-- Look for array types whose typalign isn't sufficient + +SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typarray = t2.oid AND + t2.typalign != (CASE WHEN t1.typalign = 'd' THEN 'd'::"char" + ELSE 'i'::"char" END) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t2" column="typalign" +FILTER: schema="" table="t1" column="typalign" +STMT: SelectStmt +== 038 +-- Check for typelem set without a handler + +SELECT t1.oid, t1.typname, t1.typelem +FROM pg_type AS t1 +WHERE t1.typelem != 0 AND t1.typsubscript = 0 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typsubscript" +STMT: SelectStmt +== 039 +-- Check for misuse of standard subscript handlers + +SELECT t1.oid, t1.typname, + t1.typelem, t1.typlen, t1.typbyval +FROM pg_type AS t1 +WHERE t1.typsubscript = 'array_subscript_handler'::regproc AND NOT + (t1.typelem != 0 AND t1.typlen = -1 AND NOT t1.typbyval) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsubscript" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typbyval" +STMT: SelectStmt +== 040 +SELECT t1.oid, t1.typname, + t1.typelem, t1.typlen, t1.typbyval +FROM pg_type AS t1 +WHERE t1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT + (t1.typelem != 0 AND t1.typlen > 0 AND NOT t1.typbyval) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsubscript" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typbyval" +STMT: SelectStmt +== 041 +-- Check for bogus typanalyze routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typanalyze = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'internal'::regtype AND + p1.prorettype = 'bool'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typanalyze" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +== 042 +-- 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 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "d"="pg_type" +ALIAS: "t"="pg_type" +FILTER: schema="" table="d" column="typanalyze" +FILTER: schema="" table="t" column="typanalyze" +STMT: SelectStmt +== 043 +-- 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) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t"="pg_type" +FILTER: schema="" table="t" column="typbasetype" +FILTER: schema="" table="t" column="typanalyze" +FILTER: schema="" table="r" column="rngtypid" +STMT: SelectStmt +== 044 +-- 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) != + (t.typsubscript = 'array_subscript_handler'::regproc) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t"="pg_type" +FILTER: schema="" table="t" column="typbasetype" +FILTER: schema="" table="t" column="typanalyze" +FILTER: schema="" table="t" column="typsubscript" +STMT: SelectStmt +== 045 +-- **************** pg_class **************** + +-- Look for illegal values in pg_class fields + +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p', 'I') OR + relpersistence NOT IN ('p', 'u', 't') OR + relreplident NOT IN ('d', 'n', 'f', 'i') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c1"="pg_class" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relpersistence" +FILTER: schema="" table="" column="relreplident" +STMT: SelectStmt +== 046 +-- All tables, indexes, partitioned indexes and matviews should have an +-- access method. +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE c1.relkind NOT IN ('S', 'v', 'f', 'c', 'p') and + c1.relam = 0 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c1"="pg_class" +FILTER: schema="" table="c1" column="relkind" +FILTER: schema="" table="c1" column="relam" +STMT: SelectStmt +== 047 +-- Conversely, sequences, views, foreign tables, types and partitioned +-- tables shouldn't have them. +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE c1.relkind IN ('S', 'v', 'f', 'c', 'p') and + c1.relam != 0 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c1"="pg_class" +FILTER: schema="" table="c1" column="relkind" +FILTER: schema="" table="c1" column="relam" +STMT: SelectStmt +== 048 +-- Indexes and partitioned 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', 'I') and + pa.amtype != 'i' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +FILTER: schema="" table="pc" column="relkind" +FILTER: schema="" table="pa" column="amtype" +STMT: SelectStmt +== 049 +-- 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' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +FILTER: schema="" table="pc" column="relkind" +FILTER: schema="" table="pa" column="amtype" +STMT: SelectStmt +== 050 +-- **************** pg_attribute **************** + +-- Look for illegal values in pg_attribute fields + +SELECT a1.attrelid, a1.attname +FROM pg_attribute as a1 +WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR + a1.attcacheoff != -1 OR a1.attinhcount < 0 OR + (a1.attinhcount = 0 AND NOT a1.attislocal) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a1"="pg_attribute" +FILTER: schema="" table="a1" column="attrelid" +FILTER: schema="" table="a1" column="atttypid" +FILTER: schema="" table="a1" column="attnum" +FILTER: schema="" table="a1" column="attcacheoff" +FILTER: schema="" table="a1" column="attinhcount" +FILTER: schema="" table="a1" column="attinhcount" +FILTER: schema="" table="a1" column="attislocal" +STMT: SelectStmt +== 051 +-- Cross-check attnum against parent relation + +SELECT a1.attrelid, a1.attname, c1.oid, c1.relname +FROM pg_attribute AS a1, pg_class AS c1 +WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a1"="pg_attribute" +ALIAS: "c1"="pg_class" +FILTER: schema="" table="a1" column="attrelid" +FILTER: schema="" table="c1" column="oid" +FILTER: schema="" table="a1" column="attnum" +FILTER: schema="" table="c1" column="relnatts" +STMT: SelectStmt +== 052 +-- Detect missing pg_attribute entries: should have as many non-system +-- attributes as parent relation expects + +SELECT c1.oid, c1.relname +FROM pg_class AS c1 +WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1 + WHERE a1.attrelid = c1.oid AND a1.attnum > 0) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a1"="pg_attribute" +ALIAS: "c1"="pg_class" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="c1" column="relnatts" +FILTER: schema="" table="a1" column="attrelid" +FILTER: schema="" table="c1" column="oid" +FILTER: schema="" table="a1" column="attnum" +STMT: SelectStmt +== 053 +-- 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 a1.attrelid, a1.attname, t1.oid, t1.typname +FROM pg_attribute AS a1, pg_type AS t1 +WHERE a1.atttypid = t1.oid AND + (a1.attlen != t1.typlen OR + a1.attalign != t1.typalign OR + a1.attbyval != t1.typbyval OR + (a1.attstorage != t1.typstorage AND a1.attstorage != 'p')) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "a1"="pg_attribute" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="a1" column="atttypid" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="a1" column="attlen" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="a1" column="attalign" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="a1" column="attbyval" +FILTER: schema="" table="t1" column="typbyval" +FILTER: schema="" table="a1" column="attstorage" +FILTER: schema="" table="t1" column="typstorage" +FILTER: schema="" table="a1" column="attstorage" +STMT: SelectStmt +== 054 +-- **************** pg_range **************** + +-- Look for illegal values in pg_range fields. + +SELECT r.rngtypid, r.rngsubtype +FROM pg_range as r +WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0 +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +FILTER: schema="" table="r" column="rngtypid" +FILTER: schema="" table="r" column="rngsubtype" +FILTER: schema="" table="r" column="rngsubopc" +STMT: SelectStmt +== 055 +-- rngcollation should be specified iff subtype is collatable + +SELECT r.rngtypid, r.rngsubtype, r.rngcollation, t.typcollation +FROM pg_range r JOIN pg_type t ON t.oid = r.rngsubtype +WHERE (rngcollation = 0) != (typcollation = 0) +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t"="pg_type" +FILTER: schema="" table="" column="rngcollation" +FILTER: schema="" table="" column="typcollation" +STMT: SelectStmt +== 056 +-- opclass had better be a btree opclass accepting the subtype. +-- We must allow anyarray matches, cf IsBinaryCoercible() + +SELECT r.rngtypid, r.rngsubtype, o.opcmethod, o.opcname +FROM pg_range r JOIN pg_opclass o ON o.oid = r.rngsubopc +WHERE o.opcmethod != 403 OR + ((o.opcintype != r.rngsubtype) AND NOT + (o.opcintype = 'pg_catalog.anyarray'::regtype AND + EXISTS(select 1 from pg_catalog.pg_type where + oid = r.rngsubtype and typelem != 0 and + typsubscript = 'array_subscript_handler'::regproc))) +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_catalog.pg_type" schema="pg_catalog" table="pg_type" ctx=Select +ALIAS: "o"="pg_opclass" +ALIAS: "r"="pg_range" +FILTER: schema="" table="o" column="opcmethod" +FILTER: schema="" table="o" column="opcintype" +FILTER: schema="" table="r" column="rngsubtype" +FILTER: schema="" table="o" column="opcintype" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="r" column="rngsubtype" +FILTER: schema="" table="" column="typelem" +FILTER: schema="" table="" column="typsubscript" +STMT: SelectStmt +== 057 +-- canonical function, if any, had better match the range type + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngcanonical +WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p"="pg_proc" +ALIAS: "r"="pg_range" +FILTER: schema="" table="" column="pronargs" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="rngtypid" +FILTER: schema="" table="" column="prorettype" +FILTER: schema="" table="" column="rngtypid" +STMT: SelectStmt +== 058 +-- subdiff function, if any, had better match the subtype + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngsubdiff +WHERE pronargs != 2 + OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype + OR prorettype != 'pg_catalog.float8'::regtype +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p"="pg_proc" +ALIAS: "r"="pg_range" +FILTER: schema="" table="" column="pronargs" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="rngsubtype" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="rngsubtype" +FILTER: schema="" table="" column="prorettype" +STMT: SelectStmt +== 059 +-- every range should have a valid multirange + +SELECT r.rngtypid, r.rngsubtype, r.rngmultitypid +FROM pg_range r +WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0 +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +FILTER: schema="" table="r" column="rngmultitypid" +FILTER: schema="" table="r" column="rngmultitypid" +STMT: SelectStmt +== 060 +-- Create a table that holds all the known in-core data types and leave it +-- around so as pg_upgrade is able to test their binary compatibility. +CREATE TABLE tab_core_types AS SELECT + '(11,12)'::point, + '(1,1),(2,2)'::line, + '((11,11),(12,12))'::lseg, + '((11,11),(13,13))'::box, + '((11,12),(13,13),(14,14))'::path AS openedpath, + '[(11,12),(13,13),(14,14)]'::path AS closedpath, + '((11,12),(13,13),(14,14))'::polygon, + '1,1,1'::circle, + 'today'::date, + 'now'::time, + 'now'::timestamp, + 'now'::timetz, + 'now'::timestamptz, + '12 seconds'::interval, + '{"reason":"because"}'::json, + '{"when":"now"}'::jsonb, + '$.a[*] ? (@ > 2)'::jsonpath, + '127.0.0.1'::inet, + '127.0.0.0/8'::cidr, + '00:01:03:86:1c:ba'::macaddr8, + '00:01:03:86:1c:ba'::macaddr, + 2::int2, 4::int4, 8::int8, + 4::float4, '8'::float8, pi()::numeric, + 'foo'::"char", + 'c'::bpchar, + 'abc'::varchar, + 'name'::name, + 'txt'::text, + true::bool, + E'\\xDEADBEEF'::bytea, + B'10001'::bit, + B'10001'::varbit AS varbit, + '12.34'::money, + 'abc'::refcursor, + '1 2'::int2vector, + '1 2'::oidvector, + format('%I=UC/%I', USER, USER)::aclitem AS aclitem, + 'a fat cat sat on a mat and ate a fat rat'::tsvector, + 'fat & rat'::tsquery, + 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, + '11'::xid8, + 'pg_class'::regclass, + 'regtype'::regtype type, + 'pg_monitor'::regrole, + 'pg_class'::regclass::oid, + '(1,1)'::tid, '2'::xid, '3'::cid, + '10:20:10,14,15'::txid_snapshot, + '10:20:10,14,15'::pg_snapshot, + '16/B374D848'::pg_lsn, + 1::information_schema.cardinal_number, + 'l'::information_schema.character_data, + 'n'::information_schema.sql_identifier, + 'now'::information_schema.time_stamp, + 'YES'::information_schema.yes_or_no, + '(1,2)'::int4range, '{(1,2)}'::int4multirange, + '(3,4)'::int8range, '{(3,4)}'::int8multirange, + '(3,4)'::numrange, '{(3,4)}'::nummultirange, + '(2020-01-02, 2021-02-03)'::daterange, + '{(2020-01-02, 2021-02-03)}'::datemultirange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tsrange, + '{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tsmultirange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tstzrange, + '{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tstzmultirange +-- +TABLE: name="tab_core_types" schema="" table="tab_core_types" ctx=DDL +FUNCTION: name="pi" function="pi" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 061 +-- Sanity check on the previous table, checking that all core types are +-- included in this table. +SELECT oid, typname, typtype, typelem, typarray + FROM pg_type t + WHERE oid < 16384 AND + -- Exclude pseudotypes and composite types. + typtype NOT IN ('p', 'c') AND + -- These reg* types cannot be pg_upgraded, so discard them. + oid != ALL(ARRAY['regproc', 'regprocedure', 'regoper', + 'regoperator', 'regconfig', 'regdictionary', + 'regnamespace', 'regcollation']::regtype[]) AND + -- Discard types that do not accept input values as these cannot be + -- tested easily. + -- Note: XML might be disabled at compile-time. + oid != ALL(ARRAY['gtsvector', 'pg_node_tree', + 'pg_ndistinct', 'pg_dependencies', 'pg_mcv_list', + 'pg_brin_bloom_summary', + 'pg_brin_minmax_multi_summary', 'xml']::regtype[]) AND + -- Discard arrays. + NOT EXISTS (SELECT 1 FROM pg_type u WHERE u.typarray = t.oid) + -- Exclude everything from the table created above. This checks + -- that no in-core types are missing in tab_core_types. + AND NOT EXISTS (SELECT 1 + FROM pg_attribute a + WHERE a.atttypid=t.oid AND + a.attnum > 0 AND + a.attrelid='tab_core_types'::regclass) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "t"="pg_type" +ALIAS: "u"="pg_type" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="typtype" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="u" column="typarray" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="a" column="atttypid" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="a" column="attrelid" +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/typed_table.metadata.json b/parser/testdata/summary/postgres_regress/typed_table.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary/postgres_regress/typed_table.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary/postgres_regress/typed_table.test b/parser/testdata/summary/postgres_regress/typed_table.test new file mode 100644 index 0000000..af16fff --- /dev/null +++ b/parser/testdata/summary/postgres_regress/typed_table.test @@ -0,0 +1,163 @@ +== 001 +CREATE TABLE ttable1 OF nothing +-- +TABLE: name="ttable1" schema="" table="ttable1" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TYPE person_type AS (id int, name text) +-- +STMT: CompositeTypeStmt +== 003 +CREATE TABLE persons OF person_type +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: CreateStmt +== 004 +CREATE TABLE IF NOT EXISTS persons OF person_type +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: CreateStmt +== 005 +SELECT * FROM persons +-- +TABLE: name="persons" schema="" table="persons" ctx=Select +STMT: SelectStmt +== 006 +CREATE FUNCTION get_all_persons() RETURNS SETOF person_type +LANGUAGE SQL +AS $$ + SELECT * FROM persons; +$$ +-- +FUNCTION: name="get_all_persons" function="get_all_persons" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 007 +SELECT * FROM get_all_persons() +-- +FUNCTION: name="get_all_persons" function="get_all_persons" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- certain ALTER TABLE operations on typed tables are not allowed +ALTER TABLE persons ADD COLUMN comment text +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +== 009 +ALTER TABLE persons DROP COLUMN name +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +== 010 +ALTER TABLE persons RENAME COLUMN id TO num +-- +STMT: RenameStmt +== 011 +ALTER TABLE persons ALTER COLUMN name TYPE varchar +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +== 012 +CREATE TABLE stuff (id int) +-- +TABLE: name="stuff" schema="" table="stuff" ctx=DDL +STMT: CreateStmt +== 013 +ALTER TABLE persons INHERIT stuff +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +== 014 +CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL) +-- +TABLE: name="personsx" schema="" table="personsx" ctx=DDL +STMT: CreateStmt +== 015 +-- error + +CREATE TABLE persons2 OF person_type ( + id WITH OPTIONS PRIMARY KEY, + UNIQUE (name) +) +-- +TABLE: name="persons2" schema="" table="persons2" ctx=DDL +STMT: CreateStmt +== 016 +CREATE TABLE persons3 OF person_type ( + PRIMARY KEY (id), + name WITH OPTIONS DEFAULT '' +) +-- +TABLE: name="persons3" schema="" table="persons3" ctx=DDL +STMT: CreateStmt +== 017 +CREATE TABLE persons4 OF person_type ( + name WITH OPTIONS NOT NULL, + name WITH OPTIONS DEFAULT '' -- error, specified more than once +) +-- +TABLE: name="persons4" schema="" table="persons4" ctx=DDL +STMT: CreateStmt +== 018 +DROP TYPE person_type RESTRICT +-- +STMT: DropStmt +== 019 +DROP TYPE person_type CASCADE +-- +STMT: DropStmt +== 020 +CREATE TABLE persons5 OF stuff +-- +TABLE: name="persons5" schema="" table="persons5" ctx=DDL +STMT: CreateStmt +== 021 +-- only CREATE TYPE AS types may be used + +DROP TABLE stuff +-- +TABLE: name="stuff" schema="" table="stuff" ctx=DDL +STMT: DropStmt +== 022 +-- implicit casting + +CREATE TYPE person_type AS (id int, name text) +-- +STMT: CompositeTypeStmt +== 023 +CREATE TABLE persons OF person_type +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: CreateStmt +== 024 +INSERT INTO persons VALUES (1, 'test') +-- +TABLE: name="persons" schema="" table="persons" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE SQL AS $$ SELECT length($1.name) $$ +-- +FUNCTION: name="namelen" function="namelen" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 026 +SELECT id, namelen(persons) FROM persons +-- +TABLE: name="persons" schema="" table="persons" ctx=Select +FUNCTION: name="namelen" function="namelen" schema="" ctx=Call +STMT: SelectStmt +== 027 +CREATE TABLE persons2 OF person_type ( + id WITH OPTIONS PRIMARY KEY, + UNIQUE (name) +) +-- +TABLE: name="persons2" schema="" table="persons2" ctx=DDL +STMT: CreateStmt +== 028 +CREATE TABLE persons3 OF person_type ( + PRIMARY KEY (id), + name NOT NULL DEFAULT '' +) +-- +TABLE: name="persons3" schema="" table="persons3" ctx=DDL +STMT: CreateStmt diff --git a/parser/testdata/summary/postgres_regress/unicode.metadata.json b/parser/testdata/summary/postgres_regress/unicode.metadata.json new file mode 100644 index 0000000..f51f5c0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/unicode.metadata.json @@ -0,0 +1,21 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017" + ] +} diff --git a/parser/testdata/summary/postgres_regress/unicode.test b/parser/testdata/summary/postgres_regress/unicode.test new file mode 100644 index 0000000..52b53bd --- /dev/null +++ b/parser/testdata/summary/postgres_regress/unicode.test @@ -0,0 +1,100 @@ +== 001 +SELECT getdatabaseencoding() <> 'UTF8' AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +== 002 +SELECT U&'\0061\0308bc' <> U&'\00E4bc' COLLATE "C" AS sanity_check +-- +STMT: SelectStmt +== 003 +SELECT unicode_version() IS NOT NULL +-- +FUNCTION: name="unicode_version" function="unicode_version" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT unicode_assigned(U&'abc') +-- +FUNCTION: name="unicode_assigned" function="unicode_assigned" schema="" ctx=Call +STMT: SelectStmt +== 005 +SELECT unicode_assigned(U&'abc\+10FFFF') +-- +FUNCTION: name="unicode_assigned" function="unicode_assigned" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT normalize('') +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 007 +SELECT normalize(U&'\0061\0308\24D1c') = U&'\00E4\24D1c' COLLATE "C" AS test_default +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 008 +SELECT normalize(U&'\0061\0308\24D1c', NFC) = U&'\00E4\24D1c' COLLATE "C" AS test_nfc +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 009 +SELECT normalize(U&'\00E4bc', NFC) = U&'\00E4bc' COLLATE "C" AS test_nfc_idem +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 010 +SELECT normalize(U&'\00E4\24D1c', NFD) = U&'\0061\0308\24D1c' COLLATE "C" AS test_nfd +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 011 +SELECT normalize(U&'\0061\0308\24D1c', NFKC) = U&'\00E4bc' COLLATE "C" AS test_nfkc +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 012 +SELECT normalize(U&'\00E4\24D1c', NFKD) = U&'\0061\0308bc' COLLATE "C" AS test_nfkd +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 013 +SELECT "normalize"('abc', 'def') +-- +FUNCTION: name="normalize" function="normalize" schema="" ctx=Call +STMT: SelectStmt +== 014 +-- run-time error + +SELECT U&'\00E4\24D1c' IS NORMALIZED AS test_default +-- +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 015 +SELECT U&'\00E4\24D1c' IS NFC NORMALIZED AS test_nfc +-- +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 016 +SELECT num, val, + val IS NFC NORMALIZED AS NFC, + val IS NFD NORMALIZED AS NFD, + val IS NFKC NORMALIZED AS NFKC, + val IS NFKD NORMALIZED AS NFKD +FROM + (VALUES (1, U&'\00E4bc'), + (2, U&'\0061\0308bc'), + (3, U&'\00E4\24D1c'), + (4, U&'\0061\0308\24D1c'), + (5, '')) vals (num, val) +ORDER BY num +-- +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 017 +SELECT is_normalized('abc', 'def') +-- +FUNCTION: name="is_normalized" function="is_normalized" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/union.metadata.json b/parser/testdata/summary/postgres_regress/union.metadata.json new file mode 100644 index 0000000..c2aa882 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/union.metadata.json @@ -0,0 +1,195 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191" + ] +} diff --git a/parser/testdata/summary/postgres_regress/union.test b/parser/testdata/summary/postgres_regress/union.test new file mode 100644 index 0000000..94102d0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/union.test @@ -0,0 +1,1333 @@ +== 001 +|-- +-- UNION (also INTERSECT, EXCEPT) +|-- + +-- Simple UNION constructs + +SELECT 1 AS two UNION SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +== 002 +SELECT 1 AS one UNION SELECT 1 ORDER BY 1 +-- +STMT: SelectStmt +== 003 +SELECT 1 AS two UNION ALL SELECT 2 +-- +STMT: SelectStmt +== 004 +SELECT 1 AS two UNION ALL SELECT 1 +-- +STMT: SelectStmt +== 005 +SELECT 1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1 +-- +STMT: SelectStmt +== 006 +SELECT 1 AS two UNION SELECT 2 UNION SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +== 007 +SELECT 1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +== 008 +SELECT 1.1 AS two UNION SELECT 2.2 ORDER BY 1 +-- +STMT: SelectStmt +== 009 +-- Mixed types + +SELECT 1.1 AS two UNION SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +== 010 +SELECT 1 AS two UNION SELECT 2.2 ORDER BY 1 +-- +STMT: SelectStmt +== 011 +SELECT 1 AS one UNION SELECT 1.0::float8 ORDER BY 1 +-- +STMT: SelectStmt +== 012 +SELECT 1.1 AS two UNION ALL SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +== 013 +SELECT 1.0::float8 AS two UNION ALL SELECT 1 ORDER BY 1 +-- +STMT: SelectStmt +== 014 +SELECT 1.1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1 +-- +STMT: SelectStmt +== 015 +SELECT 1.1::float8 AS two UNION SELECT 2 UNION SELECT 2.0::float8 ORDER BY 1 +-- +STMT: SelectStmt +== 016 +SELECT 1.1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +== 017 +SELECT 1.1 AS two UNION (SELECT 2 UNION ALL SELECT 2) ORDER BY 1 +-- +STMT: SelectStmt +== 018 +|-- +-- Try testing from tables... +|-- + +SELECT f1 AS five FROM FLOAT8_TBL +UNION +SELECT f1 FROM FLOAT8_TBL +ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +== 019 +SELECT f1 AS ten FROM FLOAT8_TBL +UNION ALL +SELECT f1 FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +== 020 +SELECT f1 AS nine FROM FLOAT8_TBL +UNION +SELECT f1 FROM INT4_TBL +ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 021 +SELECT f1 AS ten FROM FLOAT8_TBL +UNION ALL +SELECT f1 FROM INT4_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 022 +SELECT f1 AS five FROM FLOAT8_TBL + WHERE f1 BETWEEN -1e6 AND 1e6 +UNION +SELECT f1 FROM INT4_TBL + WHERE f1 BETWEEN 0 AND 1000000 +ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 023 +SELECT CAST(f1 AS char(4)) AS three FROM VARCHAR_TBL +UNION +SELECT f1 FROM CHAR_TBL +ORDER BY 1 +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +== 024 +SELECT f1 AS three FROM VARCHAR_TBL +UNION +SELECT CAST(f1 AS varchar) FROM CHAR_TBL +ORDER BY 1 +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +== 025 +SELECT f1 AS eight FROM VARCHAR_TBL +UNION ALL +SELECT f1 FROM CHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +== 026 +SELECT f1 AS five FROM TEXT_TBL +UNION +SELECT f1 FROM VARCHAR_TBL +UNION +SELECT TRIM(TRAILING FROM f1) FROM CHAR_TBL +ORDER BY 1 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +FUNCTION: name="pg_catalog.rtrim" function="rtrim" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 027 +|-- +-- INTERSECT and EXCEPT +|-- + +SELECT q2 FROM int8_tbl INTERSECT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 028 +SELECT q2 FROM int8_tbl INTERSECT ALL SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 029 +SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 030 +SELECT q2 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 031 +SELECT q2 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 032 +SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 033 +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 034 +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 035 +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl FOR NO KEY UPDATE +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 036 +-- nested cases +(SELECT 1,2,3 UNION SELECT 4,5,6) INTERSECT SELECT 4,5,6 +-- +STMT: SelectStmt +== 037 +(SELECT 1,2,3 UNION SELECT 4,5,6 ORDER BY 1,2) INTERSECT SELECT 4,5,6 +-- +STMT: SelectStmt +== 038 +(SELECT 1,2,3 UNION SELECT 4,5,6) EXCEPT SELECT 4,5,6 +-- +STMT: SelectStmt +== 039 +(SELECT 1,2,3 UNION SELECT 4,5,6 ORDER BY 1,2) EXCEPT SELECT 4,5,6 +-- +STMT: SelectStmt +== 040 +-- exercise both hashed and sorted implementations of UNION/INTERSECT/EXCEPT + +set enable_hashagg to on +-- +STMT: VariableSetStmt +== 041 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 042 +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 043 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 044 +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 045 +explain (costs off) +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 046 +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 047 +set enable_hashagg to off +-- +STMT: VariableSetStmt +== 048 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 049 +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 050 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 051 +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 052 +explain (costs off) +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +== 053 +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 054 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 055 +-- non-hashable type +set enable_hashagg to on +-- +STMT: VariableSetStmt +== 056 +explain (costs off) +select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 057 +set enable_hashagg to off +-- +STMT: VariableSetStmt +== 058 +explain (costs off) +select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 059 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 060 +-- arrays +set enable_hashagg to on +-- +STMT: VariableSetStmt +== 061 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 062 +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +== 063 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 064 +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +== 065 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 066 +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +== 067 +-- non-hashable type +explain (costs off) +select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 068 +select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x) +-- +STMT: SelectStmt +== 069 +set enable_hashagg to off +-- +STMT: VariableSetStmt +== 070 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 071 +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +== 072 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 073 +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +== 074 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 075 +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +== 076 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 077 +-- records +set enable_hashagg to on +-- +STMT: VariableSetStmt +== 078 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 079 +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +== 080 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 081 +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +== 082 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 083 +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +== 084 +-- non-hashable type + +-- With an anonymous row type, the typcache does not report that the +-- type is hashable. (Otherwise, this would fail at execution time.) +explain (costs off) +select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 085 +select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x) +-- +STMT: SelectStmt +== 086 +-- With a defined row type, the typcache can inspect the type's fields +-- for hashability. +create type ct1 as (f1 varbit) +-- +STMT: CompositeTypeStmt +== 087 +explain (costs off) +select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 088 +select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x) +-- +STMT: SelectStmt +== 089 +drop type ct1 +-- +STMT: DropStmt +== 090 +set enable_hashagg to off +-- +STMT: VariableSetStmt +== 091 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 092 +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +== 093 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 094 +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +== 095 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +== 096 +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +== 097 +-- non-sortable type + +-- Ensure we get a HashAggregate plan. Keep enable_hashagg=off to ensure +-- there's no chance of a sort. +explain (costs off) select '123'::xid union select '123'::xid +-- +STMT: ExplainStmt +STMT: SelectStmt +== 098 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 099 +|-- +-- Mixed types +|-- + +SELECT f1 FROM float8_tbl INTERSECT SELECT f1 FROM int4_tbl ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 100 +SELECT f1 FROM float8_tbl EXCEPT SELECT f1 FROM int4_tbl ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +== 101 +|-- +-- Operator precedence and (((((extra))))) parentheses +|-- + +SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 102 +SELECT q1 FROM int8_tbl INTERSECT (((SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 103 +(((SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl ORDER BY 1))) UNION ALL SELECT q2 FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 104 +SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 105 +SELECT q1 FROM int8_tbl UNION ALL (((SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1))) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 106 +(((SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 107 +|-- +-- Subqueries with ORDER BY & LIMIT clauses +|-- + +-- In this syntax, ORDER BY/LIMIT apply to the result of the EXCEPT +SELECT q1,q2 FROM int8_tbl EXCEPT SELECT q2,q1 FROM int8_tbl +ORDER BY q2,q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 108 +-- This should fail, because q2 isn't a name of an EXCEPT output column +SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 109 +-- But this should work: +SELECT q1 FROM int8_tbl EXCEPT (((SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1))) ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 110 +|-- +-- New syntaxes (7.1) permit new tests +|-- + +(((((select * from int8_tbl))))) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +== 111 +|-- +-- Check behavior with empty select list (allowed since 9.4) +|-- + +select union select +-- +STMT: SelectStmt +== 112 +select intersect select +-- +STMT: SelectStmt +== 113 +select except select +-- +STMT: SelectStmt +== 114 +-- check hashed implementation +set enable_hashagg = true +-- +STMT: VariableSetStmt +== 115 +set enable_sort = false +-- +STMT: VariableSetStmt +== 116 +-- We've no way to check hashed UNION as the empty pathkeys in the Append are +-- fine to make use of Unique, which is cheaper than HashAggregate and we've +-- no means to disable Unique. +explain (costs off) +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 117 +select from generate_series(1,5) union all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 118 +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 119 +select from generate_series(1,5) intersect all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 120 +select from generate_series(1,5) except select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 121 +select from generate_series(1,5) except all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 122 +-- check sorted implementation +set enable_hashagg = false +-- +STMT: VariableSetStmt +== 123 +set enable_sort = true +-- +STMT: VariableSetStmt +== 124 +explain (costs off) +select from generate_series(1,5) union select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 125 +explain (costs off) +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 126 +select from generate_series(1,5) union select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 127 +select from generate_series(1,5) union all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 128 +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 129 +select from generate_series(1,5) intersect all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 130 +select from generate_series(1,5) except select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 131 +select from generate_series(1,5) except all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 132 +-- Try a variation of the above but with a CTE which contains a column, again +-- with an empty final select list. + +-- Ensure we get the expected 1 row with 0 columns +with cte as materialized (select s from generate_series(1,5) s) +select from cte union select from cte +-- +CTE: "cte" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 133 +-- Ensure we get the same result as the above. +with cte as not materialized (select s from generate_series(1,5) s) +select from cte union select from cte +-- +CTE: "cte" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 134 +reset enable_hashagg +-- +STMT: VariableSetStmt +== 135 +reset enable_sort +-- +STMT: VariableSetStmt +== 136 +|-- +-- Check handling of a case with unknown constants. We don't guarantee +-- an undecorated constant will work in all cases, but historically this +-- usage has worked, so test we don't break it. +|-- + +SELECT a.f1 FROM (SELECT 'test' AS f1 FROM varchar_tbl) a +UNION +SELECT b.f1 FROM (SELECT f1 FROM varchar_tbl) b +ORDER BY 1 +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +STMT: SelectStmt +== 137 +-- This should fail, but it should produce an error cursor +SELECT '3.4'::numeric UNION SELECT 'foo' +-- +STMT: SelectStmt +== 138 +|-- +-- Test that expression-index constraints can be pushed down through +-- UNION or UNION ALL +|-- + +CREATE TEMP TABLE t1 (a text, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 139 +CREATE INDEX t1_ab_idx on t1 ((a || b)) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: IndexStmt +== 140 +CREATE TEMP TABLE t2 (ab text primary key) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 141 +INSERT INTO t1 VALUES ('a', 'b'), ('x', 'y') +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 142 +INSERT INTO t2 VALUES ('ab'), ('xy') +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 143 +set enable_seqscan = off +-- +STMT: VariableSetStmt +== 144 +set enable_indexscan = on +-- +STMT: VariableSetStmt +== 145 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +== 146 +set enable_sort = off +-- +STMT: VariableSetStmt +== 147 +explain (costs off) + SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION ALL + SELECT * FROM t2) t + WHERE ab = 'ab' +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +FILTER: schema="" table="" column="ab" +STMT: ExplainStmt +STMT: SelectStmt +== 148 +explain (costs off) + SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION + SELECT * FROM t2) t + WHERE ab = 'ab' +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +FILTER: schema="" table="" column="ab" +STMT: ExplainStmt +STMT: SelectStmt +== 149 +|-- +-- Test that ORDER BY for UNION ALL can be pushed down to inheritance +-- children. +|-- + +CREATE TEMP TABLE t1c (b text, a text) +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: CreateStmt +== 150 +ALTER TABLE t1c INHERIT t1 +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: AlterTableStmt +== 151 +CREATE TEMP TABLE t2c (primary key (ab)) INHERITS (t2) +-- +TABLE: name="t2c" schema="" table="t2c" ctx=DDL +STMT: CreateStmt +== 152 +INSERT INTO t1c VALUES ('v', 'w'), ('c', 'd'), ('m', 'n'), ('e', 'f') +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 153 +INSERT INTO t2c VALUES ('vw'), ('cd'), ('mn'), ('ef') +-- +TABLE: name="t2c" schema="" table="t2c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 154 +CREATE INDEX t1c_ab_idx on t1c ((a || b)) +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: IndexStmt +== 155 +set enable_seqscan = on +-- +STMT: VariableSetStmt +== 156 +set enable_indexonlyscan = off +-- +STMT: VariableSetStmt +== 157 +explain (costs off) + SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION ALL + SELECT ab FROM t2) t + ORDER BY 1 LIMIT 8 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 158 +SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION ALL + SELECT ab FROM t2) t + ORDER BY 1 LIMIT 8 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +== 159 +reset enable_seqscan +-- +STMT: VariableSetStmt +== 160 +reset enable_indexscan +-- +STMT: VariableSetStmt +== 161 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +== 162 +reset enable_sort +-- +STMT: VariableSetStmt +== 163 +-- This simpler variant of the above test has been observed to fail differently + +create table events (event_id int primary key) +-- +TABLE: name="events" schema="" table="events" ctx=DDL +STMT: CreateStmt +== 164 +create table other_events (event_id int primary key) +-- +TABLE: name="other_events" schema="" table="other_events" ctx=DDL +STMT: CreateStmt +== 165 +create table events_child () inherits (events) +-- +TABLE: name="events_child" schema="" table="events_child" ctx=DDL +STMT: CreateStmt +== 166 +explain (costs off) +select event_id + from (select event_id from events + union all + select event_id from other_events) ss + order by event_id +-- +TABLE: name="events" schema="" table="events" ctx=Select +TABLE: name="other_events" schema="" table="other_events" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 167 +drop table events_child, events, other_events +-- +TABLE: name="events_child" schema="" table="events_child" ctx=DDL +TABLE: name="events" schema="" table="events" ctx=DDL +TABLE: name="other_events" schema="" table="other_events" ctx=DDL +STMT: DropStmt +== 168 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +== 169 +-- Test constraint exclusion of UNION ALL subqueries +explain (costs off) + SELECT * FROM + (SELECT 1 AS t, * FROM tenk1 a + UNION ALL + SELECT 2 AS t, * FROM tenk1 b) c + WHERE t = 2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 170 +-- Test that we push quals into UNION sub-selects only when it's safe +explain (costs off) +SELECT * FROM + (SELECT 1 AS t, 2 AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 171 +SELECT * FROM + (SELECT 1 AS t, 2 AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 172 +explain (costs off) +SELECT * FROM + (SELECT 1 AS t, generate_series(1,10) AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 173 +SELECT * FROM + (SELECT 1 AS t, generate_series(1,10) AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 174 +explain (costs off) +SELECT * FROM + (SELECT 1 AS t, (random()*3)::int AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x > 3 +ORDER BY x +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +== 175 +SELECT * FROM + (SELECT 1 AS t, (random()*3)::int AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x > 3 +ORDER BY x +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +== 176 +-- Test cases where the native ordering of a sub-select has more pathkeys +-- than the outer query cares about +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 177 +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 178 +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 179 +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 180 +-- Test proper handling of parameterized appendrel paths when the +-- potential join qual is expensive +create function expensivefunc(int) returns int +language plpgsql immutable strict cost 10000 +as $$begin return $1; end$$ +-- +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 181 +create temp table t3 as select generate_series(-1000,1000) as x +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 182 +create index t3i on t3 (expensivefunc(x)) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=Call +STMT: IndexStmt +== 183 +analyze t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: VacuumStmt +== 184 +explain (costs off) +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "a"="t3" +ALIAS: "b"="t3" +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 185 +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "a"="t3" +ALIAS: "b"="t3" +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=Call +STMT: SelectStmt +== 186 +drop table t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: DropStmt +== 187 +drop function expensivefunc(int) +-- +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=DDL +STMT: DropStmt +== 188 +-- Test handling of appendrel quals that const-simplify into an AND +explain (costs off) +select * from + (select *, 0 as x from int8_tbl a + union all + select *, 1 as x from int8_tbl b) ss +where (x = 0) or (q1 >= q2 and q1 <= q2) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +== 189 +select * from + (select *, 0 as x from int8_tbl a + union all + select *, 1 as x from int8_tbl b) ss +where (x = 0) or (q1 >= q2 and q1 <= q2) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +== 190 +|-- +-- Test the planner's ability to produce cheap startup plans with Append nodes +|-- + +-- Ensure we get a Nested Loop join between tenk1 and tenk2 +explain (costs off) +select t1.unique1 from tenk1 t1 +inner join tenk2 t2 on t1.tenthous = t2.tenthous and t2.thousand = 0 + union all +(values(1)) limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: ExplainStmt +STMT: SelectStmt +== 191 +-- Ensure there is no problem if cheapest_startup_path is NULL +explain (costs off) +select * from tenk1 t1 +left join lateral + (select t1.tenthous from tenk2 t2 union all (values(1))) +on true limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: ExplainStmt +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/updatable_views.metadata.json b/parser/testdata/summary/postgres_regress/updatable_views.metadata.json new file mode 100644 index 0000000..317bbe8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/updatable_views.metadata.json @@ -0,0 +1,1104 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "1060", + "1061", + "1062", + "1063", + "1064", + "1065", + "1066", + "1067", + "1068", + "1069", + "107", + "1070", + "1071", + "1072", + "1073", + "1074", + "1075", + "1076", + "1077", + "1078", + "1079", + "108", + "1080", + "1081", + "1082", + "1083", + "1084", + "1085", + "1086", + "1087", + "1088", + "1089", + "109", + "1090", + "1091", + "1092", + "1093", + "1094", + "1095", + "1096", + "1097", + "1098", + "1099", + "110", + "1100", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary/postgres_regress/updatable_views.test b/parser/testdata/summary/postgres_regress/updatable_views.test new file mode 100644 index 0000000..388471b --- /dev/null +++ b/parser/testdata/summary/postgres_regress/updatable_views.test @@ -0,0 +1,7250 @@ +== 001 +|-- +-- UPDATABLE VIEWS +|-- + +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +== 002 +-- check that non-updatable views and columns are rejected with useful error +-- messages + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 004 +CREATE VIEW ro_view1 AS SELECT DISTINCT a, b FROM base_tbl +-- +TABLE: name="ro_view1" schema="" table="ro_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 005 +-- DISTINCT not supported +CREATE VIEW ro_view2 AS SELECT a, b FROM base_tbl GROUP BY a, b +-- +TABLE: name="ro_view2" schema="" table="ro_view2" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 006 +-- GROUP BY not supported +CREATE VIEW ro_view3 AS SELECT 1 FROM base_tbl HAVING max(a) > 0 +-- +TABLE: name="ro_view3" schema="" table="ro_view3" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 007 +-- HAVING not supported +CREATE VIEW ro_view4 AS SELECT count(*) FROM base_tbl +-- +TABLE: name="ro_view4" schema="" table="ro_view4" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 008 +-- Aggregate functions not supported +CREATE VIEW ro_view5 AS SELECT a, rank() OVER() FROM base_tbl +-- +TABLE: name="ro_view5" schema="" table="ro_view5" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 009 +-- Window functions not supported +CREATE VIEW ro_view6 AS SELECT a, b FROM base_tbl UNION SELECT -a, b FROM base_tbl +-- +TABLE: name="ro_view6" schema="" table="ro_view6" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 010 +-- Set ops not supported +CREATE VIEW ro_view7 AS WITH t AS (SELECT a, b FROM base_tbl) SELECT * FROM t +-- +TABLE: name="ro_view7" schema="" table="ro_view7" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +CTE: "t" +STMT: ViewStmt +STMT: SelectStmt +== 011 +-- WITH not supported +CREATE VIEW ro_view8 AS SELECT a, b FROM base_tbl ORDER BY a OFFSET 1 +-- +TABLE: name="ro_view8" schema="" table="ro_view8" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 012 +-- OFFSET not supported +CREATE VIEW ro_view9 AS SELECT a, b FROM base_tbl ORDER BY a LIMIT 1 +-- +TABLE: name="ro_view9" schema="" table="ro_view9" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 013 +-- LIMIT not supported +CREATE VIEW ro_view10 AS SELECT 1 AS a +-- +TABLE: name="ro_view10" schema="" table="ro_view10" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 014 +-- No base relations +CREATE VIEW ro_view11 AS SELECT b1.a, b2.b FROM base_tbl b1, base_tbl b2 +-- +TABLE: name="ro_view11" schema="" table="ro_view11" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +ALIAS: "b1"="base_tbl" +ALIAS: "b2"="base_tbl" +STMT: ViewStmt +STMT: SelectStmt +== 015 +-- Multiple base relations +CREATE VIEW ro_view12 AS SELECT * FROM generate_series(1, 10) AS g(a) +-- +TABLE: name="ro_view12" schema="" table="ro_view12" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 016 +-- SRF in rangetable +CREATE VIEW ro_view13 AS SELECT a, b FROM (SELECT * FROM base_tbl) AS t +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 017 +-- Subselect in rangetable +CREATE VIEW rw_view14 AS SELECT ctid, a, b FROM base_tbl +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 018 +-- System columns may be part of an updatable view +CREATE VIEW rw_view15 AS SELECT a, upper(b) FROM base_tbl +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 019 +-- Expression/function may be part of an updatable view +CREATE VIEW rw_view16 AS SELECT a, b, a AS aa FROM base_tbl +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 020 +-- Repeated column may be part of an updatable view +CREATE VIEW ro_view17 AS SELECT * FROM ro_view1 +-- +TABLE: name="ro_view17" schema="" table="ro_view17" ctx=DDL +TABLE: name="ro_view1" schema="" table="ro_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 021 +-- Base relation not updatable +CREATE VIEW ro_view18 AS SELECT * FROM (VALUES(1)) AS tmp(a) +-- +TABLE: name="ro_view18" schema="" table="ro_view18" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 022 +-- VALUES in rangetable +CREATE SEQUENCE uv_seq +-- +STMT: CreateSeqStmt +== 023 +CREATE VIEW ro_view19 AS SELECT * FROM uv_seq +-- +TABLE: name="ro_view19" schema="" table="ro_view19" ctx=DDL +TABLE: name="uv_seq" schema="" table="uv_seq" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 024 +-- View based on a sequence +CREATE VIEW ro_view20 AS SELECT a, b, generate_series(1, a) g FROM base_tbl +-- +TABLE: name="ro_view20" schema="" table="ro_view20" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 025 +-- SRF in targetlist not supported + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 026 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 027 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 028 +-- Read-only views +DELETE FROM ro_view1 +-- +TABLE: name="ro_view1" schema="" table="ro_view1" ctx=DML +STMT: DeleteStmt +== 029 +DELETE FROM ro_view2 +-- +TABLE: name="ro_view2" schema="" table="ro_view2" ctx=DML +STMT: DeleteStmt +== 030 +DELETE FROM ro_view3 +-- +TABLE: name="ro_view3" schema="" table="ro_view3" ctx=DML +STMT: DeleteStmt +== 031 +DELETE FROM ro_view4 +-- +TABLE: name="ro_view4" schema="" table="ro_view4" ctx=DML +STMT: DeleteStmt +== 032 +DELETE FROM ro_view5 +-- +TABLE: name="ro_view5" schema="" table="ro_view5" ctx=DML +STMT: DeleteStmt +== 033 +DELETE FROM ro_view6 +-- +TABLE: name="ro_view6" schema="" table="ro_view6" ctx=DML +STMT: DeleteStmt +== 034 +UPDATE ro_view7 SET a=a+1 +-- +TABLE: name="ro_view7" schema="" table="ro_view7" ctx=DML +STMT: UpdateStmt +== 035 +UPDATE ro_view8 SET a=a+1 +-- +TABLE: name="ro_view8" schema="" table="ro_view8" ctx=DML +STMT: UpdateStmt +== 036 +UPDATE ro_view9 SET a=a+1 +-- +TABLE: name="ro_view9" schema="" table="ro_view9" ctx=DML +STMT: UpdateStmt +== 037 +UPDATE ro_view10 SET a=a+1 +-- +TABLE: name="ro_view10" schema="" table="ro_view10" ctx=DML +STMT: UpdateStmt +== 038 +UPDATE ro_view11 SET a=a+1 +-- +TABLE: name="ro_view11" schema="" table="ro_view11" ctx=DML +STMT: UpdateStmt +== 039 +UPDATE ro_view12 SET a=a+1 +-- +TABLE: name="ro_view12" schema="" table="ro_view12" ctx=DML +STMT: UpdateStmt +== 040 +INSERT INTO ro_view13 VALUES (3, 'Row 3') +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 041 +MERGE INTO ro_view13 AS t USING (VALUES (1, 'Row 1')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +== 042 +MERGE INTO ro_view13 AS t USING (VALUES (2, 'Row 2')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = v.b +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +== 043 +MERGE INTO ro_view13 AS t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.b) +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +== 044 +MERGE INTO ro_view13 AS t USING (VALUES (2, 'Row 2')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN DO NOTHING +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +== 045 +-- should be OK to do nothing +MERGE INTO ro_view13 AS t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN DO NOTHING +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +== 046 +-- should be OK to do nothing +-- Partially updatable view +INSERT INTO rw_view14 VALUES (null, 3, 'Row 3') +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +-- should fail +INSERT INTO rw_view14 (a, b) VALUES (3, 'Row 3') +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +-- should be OK +UPDATE rw_view14 SET ctid=null WHERE a=3 +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: UpdateStmt +== 049 +-- should fail +UPDATE rw_view14 SET b='ROW 3' WHERE a=3 +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: UpdateStmt +== 050 +-- should be OK +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 051 +DELETE FROM rw_view14 WHERE a=3 +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: DeleteStmt +== 052 +-- should be OK +MERGE INTO rw_view14 AS t + USING (VALUES (2, 'Merged row 2'), (3, 'Merged row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = v.b -- should be OK, except... + WHEN NOT MATCHED THEN INSERT VALUES (null, v.a, v.b) +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +ALIAS: "t"="rw_view14" +STMT: MergeStmt +STMT: SelectStmt +== 053 +-- should fail +MERGE INTO rw_view14 AS t + USING (VALUES (2, 'Merged row 2'), (3, 'Merged row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = v.b -- should be OK + WHEN NOT MATCHED THEN INSERT (a,b) VALUES (v.a, v.b) +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +ALIAS: "t"="rw_view14" +STMT: MergeStmt +STMT: SelectStmt +== 054 +-- should be OK +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 055 +MERGE INTO rw_view14 AS t + USING (VALUES (2, 'Row 2'), (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED AND t.a = 2 THEN UPDATE SET b = v.b -- should be OK + WHEN MATCHED AND t.a = 3 THEN DELETE +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +ALIAS: "t"="rw_view14" +STMT: MergeStmt +STMT: SelectStmt +== 056 +-- should be OK +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 057 +-- Partially updatable view +INSERT INTO rw_view15 VALUES (3, 'ROW 3') +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 058 +-- should fail +INSERT INTO rw_view15 (a) VALUES (3) +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 059 +-- should be OK +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT DO NOTHING +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 060 +-- succeeds +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +== 061 +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO NOTHING +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 062 +-- succeeds +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +== 063 +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE set a = excluded.a +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 064 +-- succeeds +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +== 065 +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE set upper = 'blarg' +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 066 +-- fails +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +== 067 +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +== 068 +ALTER VIEW rw_view15 ALTER COLUMN upper SET DEFAULT 'NOT SET' +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DDL +STMT: AlterTableStmt +== 069 +INSERT INTO rw_view15 (a) VALUES (4) +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 070 +-- should fail +UPDATE rw_view15 SET upper='ROW 3' WHERE a=3 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: UpdateStmt +== 071 +-- should fail +UPDATE rw_view15 SET upper=DEFAULT WHERE a=3 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: UpdateStmt +== 072 +-- should fail +UPDATE rw_view15 SET a=4 WHERE a=3 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: UpdateStmt +== 073 +-- should be OK +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 074 +DELETE FROM rw_view15 WHERE a=4 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: DeleteStmt +== 075 +-- should be OK +-- Partially updatable view +INSERT INTO rw_view16 VALUES (3, 'Row 3', 3) +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 076 +-- should fail +INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3') +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 077 +-- should be OK +UPDATE rw_view16 SET a=3, aa=-3 WHERE a=3 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: UpdateStmt +== 078 +-- should fail +UPDATE rw_view16 SET aa=-3 WHERE a=3 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: UpdateStmt +== 079 +-- should be OK +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 080 +DELETE FROM rw_view16 WHERE a=-3 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: DeleteStmt +== 081 +-- should be OK +-- Read-only views +INSERT INTO ro_view17 VALUES (3, 'ROW 3') +-- +TABLE: name="ro_view17" schema="" table="ro_view17" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 082 +DELETE FROM ro_view18 +-- +TABLE: name="ro_view18" schema="" table="ro_view18" ctx=DML +STMT: DeleteStmt +== 083 +MERGE INTO ro_view18 AS t USING (VALUES (1, 'Row 1')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING +-- +TABLE: name="ro_view18" schema="" table="ro_view18" ctx=DML +ALIAS: "t"="ro_view18" +STMT: MergeStmt +STMT: SelectStmt +== 084 +-- should be OK to do nothing +UPDATE ro_view19 SET last_value=1000 +-- +TABLE: name="ro_view19" schema="" table="ro_view19" ctx=DML +STMT: UpdateStmt +== 085 +UPDATE ro_view20 SET b=upper(b) +-- +TABLE: name="ro_view20" schema="" table="ro_view20" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: UpdateStmt +== 086 +-- A view with a conditional INSTEAD rule but no unconditional INSTEAD rules +-- or INSTEAD OF triggers should be non-updatable and generate useful error +-- messages with appropriate detail +CREATE RULE rw_view16_ins_rule AS ON INSERT TO rw_view16 + WHERE NEW.a > 0 DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, NEW.b) +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +STMT: RuleStmt +== 087 +CREATE RULE rw_view16_upd_rule AS ON UPDATE TO rw_view16 + WHERE OLD.a > 0 DO INSTEAD UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +STMT: RuleStmt +== 088 +CREATE RULE rw_view16_del_rule AS ON DELETE TO rw_view16 + WHERE OLD.a > 0 DO INSTEAD DELETE FROM base_tbl WHERE a=OLD.a +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +STMT: RuleStmt +== 089 +INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3') +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 090 +-- should fail +UPDATE rw_view16 SET b='ROW 2' WHERE a=2 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: UpdateStmt +== 091 +-- should fail +DELETE FROM rw_view16 WHERE a=2 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: DeleteStmt +== 092 +-- should fail +MERGE INTO rw_view16 AS t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.b) +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +ALIAS: "t"="rw_view16" +STMT: MergeStmt +STMT: SelectStmt +== 093 +-- should fail + +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 094 +DROP VIEW ro_view10, ro_view12, ro_view18 +-- +STMT: DropStmt +== 095 +DROP SEQUENCE uv_seq CASCADE +-- +STMT: DropStmt +== 096 +-- simple updatable view + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 097 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 098 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a>0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 099 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 101 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view1' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 102 +INSERT INTO rw_view1 VALUES (3, 'Row 3') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 103 +INSERT INTO rw_view1 (a) VALUES (4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 104 +UPDATE rw_view1 SET a=5 WHERE a=4 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 105 +DELETE FROM rw_view1 WHERE b='Row 2' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 106 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 107 +MERGE INTO rw_view1 t + USING (VALUES (0, 'ROW 0'), (1, 'ROW 1'), + (2, 'ROW 2'), (3, 'ROW 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED AND t.a <= 1 THEN UPDATE SET b = v.b + WHEN MATCHED THEN DELETE + WHEN NOT MATCHED AND a > 0 THEN INSERT (a) VALUES (v.a) + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 108 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 109 +MERGE INTO rw_view1 t + USING (VALUES (0, 'R0'), (1, 'R1'), + (2, 'R2'), (3, 'R3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED AND t.a <= 1 THEN UPDATE SET b = v.b + WHEN MATCHED THEN DELETE + WHEN NOT MATCHED BY SOURCE THEN DELETE + WHEN NOT MATCHED AND a > 0 THEN INSERT (a) VALUES (v.a) + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 110 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 111 +EXPLAIN (costs off) UPDATE rw_view1 SET a=6 WHERE a=5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 112 +EXPLAIN (costs off) DELETE FROM rw_view1 WHERE a=5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 113 +EXPLAIN (costs off) +MERGE INTO rw_view1 t USING (VALUES (5, 'X')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 114 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (SELECT * FROM generate_series(1,5)) AS s(a) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = 'Updated' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 115 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (SELECT * FROM generate_series(1,5)) AS s(a) ON t.a = s.a + WHEN NOT MATCHED BY SOURCE THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 116 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (SELECT * FROM generate_series(1,5)) AS s(a) ON t.a = s.a + WHEN NOT MATCHED THEN INSERT (a) VALUES (s.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 117 +-- it's still updatable if we add a DO ALSO rule + +CREATE TABLE base_tbl_hist(ts timestamptz default now(), a int, b text) +-- +TABLE: name="base_tbl_hist" schema="" table="base_tbl_hist" ctx=DDL +STMT: CreateStmt +== 118 +CREATE RULE base_tbl_log AS ON INSERT TO rw_view1 DO ALSO + INSERT INTO base_tbl_hist(a,b) VALUES(new.a, new.b) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +== 119 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 120 +-- Check behavior with DEFAULTs (bug #17633) + +INSERT INTO rw_view1 VALUES (9, DEFAULT), (10, DEFAULT) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 121 +SELECT a, b FROM base_tbl_hist +-- +TABLE: name="base_tbl_hist" schema="" table="base_tbl_hist" ctx=Select +STMT: SelectStmt +== 122 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 123 +DROP TABLE base_tbl_hist +-- +TABLE: name="base_tbl_hist" schema="" table="base_tbl_hist" ctx=DDL +STMT: DropStmt +== 124 +-- view on top of view + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 125 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 126 +CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl WHERE a>0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 127 +CREATE VIEW rw_view2 AS SELECT aa AS aaa, bb AS bbb FROM rw_view1 WHERE aa<10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="aa" +STMT: ViewStmt +STMT: SelectStmt +== 128 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 129 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 130 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view2' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 131 +INSERT INTO rw_view2 VALUES (3, 'Row 3') +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 132 +INSERT INTO rw_view2 (aaa) VALUES (4) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 133 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 134 +UPDATE rw_view2 SET bbb='Row 4' WHERE aaa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 135 +DELETE FROM rw_view2 WHERE aaa=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 136 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 137 +MERGE INTO rw_view2 t + USING (VALUES (3, 'R3'), (4, 'R4'), (5, 'R5')) AS v(a,b) ON aaa = v.a + WHEN MATCHED AND aaa = 3 THEN DELETE + WHEN MATCHED THEN UPDATE SET bbb = v.b + WHEN NOT MATCHED THEN INSERT (aaa) VALUES (v.a) + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 138 +SELECT * FROM rw_view2 ORDER BY aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 139 +MERGE INTO rw_view2 t + USING (VALUES (4, 'r4'), (5, 'r5'), (6, 'r6')) AS v(a,b) ON aaa = v.a + WHEN MATCHED AND aaa = 4 THEN DELETE + WHEN MATCHED THEN UPDATE SET bbb = v.b + WHEN NOT MATCHED THEN INSERT (aaa) VALUES (v.a) + WHEN NOT MATCHED BY SOURCE THEN UPDATE SET bbb = 'Not matched by source' + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 140 +SELECT * FROM rw_view2 ORDER BY aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 141 +EXPLAIN (costs off) UPDATE rw_view2 SET aaa=5 WHERE aaa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 142 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE aaa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 143 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 144 +-- view on top of view with rules + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 145 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 146 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a>0 OFFSET 0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 147 +-- not updatable without rules/triggers +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a<10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 148 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 149 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 150 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 151 +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, NEW.b) RETURNING * +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +== 152 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 153 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 154 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 155 +CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 + DO INSTEAD UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a RETURNING NEW.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +== 156 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 157 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 158 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 159 +CREATE RULE rw_view1_del_rule AS ON DELETE TO rw_view1 + DO INSTEAD DELETE FROM base_tbl WHERE a=OLD.a RETURNING OLD.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +== 160 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 161 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 162 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 163 +INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 164 +UPDATE rw_view2 SET b='Row three' WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 165 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 166 +DELETE FROM rw_view2 WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 167 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 168 +MERGE INTO rw_view2 t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 169 +-- should fail + +EXPLAIN (costs off) UPDATE rw_view2 SET a=3 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 170 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 171 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 172 +-- view on top of view with triggers + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 173 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 174 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a>0 OFFSET 0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 175 +-- not updatable without rules/triggers +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a<10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 176 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 177 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 178 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 179 +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + INSERT INTO base_tbl VALUES (NEW.a, NEW.b); + RETURN NEW; + ELSIF TG_OP = 'UPDATE' THEN + UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a; + RETURN NEW; + ELSIF TG_OP = 'DELETE' THEN + DELETE FROM base_tbl WHERE a=OLD.a; + RETURN OLD; + END IF; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 180 +CREATE TRIGGER rw_view1_ins_trig INSTEAD OF INSERT ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +== 181 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 182 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 183 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 184 +CREATE TRIGGER rw_view1_upd_trig INSTEAD OF UPDATE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +== 185 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 186 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 187 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 188 +CREATE TRIGGER rw_view1_del_trig INSTEAD OF DELETE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +== 189 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 190 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 191 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 192 +INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 193 +UPDATE rw_view2 SET b='Row three' WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 194 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 195 +DELETE FROM rw_view2 WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 196 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 197 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED AND t.a <= 1 THEN DELETE + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) + RETURNING merge_action(), s.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 198 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 199 +MERGE INTO rw_view2 t + USING (SELECT x, 'r'||x FROM generate_series(0,2) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) + WHEN NOT MATCHED BY SOURCE THEN UPDATE SET b = 'Not matched by source' + RETURNING merge_action(), s.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 200 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 201 +EXPLAIN (costs off) UPDATE rw_view2 SET a=3 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 202 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +== 203 +EXPLAIN (costs off) +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED AND t.a <= 1 THEN DELETE + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 204 +-- MERGE with incomplete set of INSTEAD OF triggers +DROP TRIGGER rw_view1_del_trig ON rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: DropStmt +== 205 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED AND t.a <= 1 THEN DELETE + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 206 +-- should fail +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 207 +-- ok + +DROP TRIGGER rw_view1_ins_trig ON rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: DropStmt +== 208 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 209 +-- should fail +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 210 +-- ok + +-- MERGE with INSTEAD OF triggers on auto-updatable view +CREATE TRIGGER rw_view2_upd_trig INSTEAD OF UPDATE ON rw_view2 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: CreateTrigStmt +== 211 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 212 +-- should fail +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 213 +-- ok +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 214 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 215 +DROP FUNCTION rw_view1_trig_fn() +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: DropStmt +== 216 +-- update using whole row from view + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 217 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 218 +CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 219 +CREATE FUNCTION rw_view1_aa(x rw_view1) + RETURNS int AS $$ SELECT x.aa $$ LANGUAGE sql +-- +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 220 +UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2 + RETURNING rw_view1_aa(v), v.bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "v"="rw_view1" +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +STMT: UpdateStmt +== 221 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 222 +EXPLAIN (costs off) +UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2 + RETURNING rw_view1_aa(v), v.bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "v"="rw_view1" +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 223 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 224 +-- permissions checks + +CREATE USER regress_view_user1 +-- +STMT: CreateRoleStmt +== 225 +CREATE USER regress_view_user2 +-- +STMT: CreateRoleStmt +== 226 +CREATE USER regress_view_user3 +-- +STMT: CreateRoleStmt +== 227 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 228 +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 229 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 230 +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 231 +INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 232 +GRANT SELECT ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 233 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 234 +GRANT UPDATE (a,c) ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 235 +GRANT UPDATE (bb,cc) ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 236 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 237 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 238 +CREATE VIEW rw_view2 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 239 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 240 +-- ok +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 241 +-- ok +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 242 +-- ok + +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 243 +-- not allowed +INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 244 +-- not allowed +INSERT INTO rw_view2 VALUES ('Row 3', 3.0, 3) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 245 +-- not allowed + +MERGE INTO rw_view1 t + USING (VALUES ('Row 3', 3.0, 3)) AS v(b,c,a) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.b, v.c, v.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 246 +-- not allowed +MERGE INTO rw_view2 t + USING (VALUES ('Row 3', 3.0, 3)) AS v(b,c,a) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.b, v.c, v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 247 +-- not allowed + +UPDATE base_tbl SET a=a, c=c +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +== 248 +-- ok +UPDATE base_tbl SET b=b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +== 249 +-- not allowed +UPDATE rw_view1 SET bb=bb, cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 250 +-- ok +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 251 +-- not allowed +UPDATE rw_view2 SET aa=aa, cc=cc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 252 +-- ok +UPDATE rw_view2 SET bb=bb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 253 +-- not allowed + +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb, cc = cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 254 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 255 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa, cc = cc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 256 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 257 +-- not allowed + +DELETE FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +== 258 +-- not allowed +DELETE FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 259 +-- not allowed +DELETE FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 260 +-- not allowed +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 261 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 262 +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 263 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 264 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 265 +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 266 +-- ok +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 267 +-- not allowed +INSERT INTO rw_view2 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 268 +-- ok +DELETE FROM base_tbl WHERE a=1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +== 269 +-- ok +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 270 +-- not allowed +DELETE FROM rw_view2 WHERE aa=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 271 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 272 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 273 +-- ok +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 274 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 275 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 276 +REVOKE INSERT, DELETE ON base_tbl FROM regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 277 +GRANT INSERT, DELETE ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 278 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 279 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 280 +INSERT INTO base_tbl VALUES (5, 'Row 5', 5.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 281 +-- not allowed +INSERT INTO rw_view1 VALUES ('Row 5', 5.0, 5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 282 +-- ok +INSERT INTO rw_view2 VALUES ('Row 6', 6.0, 6) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 283 +-- not allowed +DELETE FROM base_tbl WHERE a=3 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +== 284 +-- not allowed +DELETE FROM rw_view1 WHERE aa=3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 285 +-- ok +DELETE FROM rw_view2 WHERE aa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 286 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 287 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 288 +-- not allowed +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 289 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 290 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 291 +-- nested-view permissions + +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 292 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 293 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 294 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 295 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 296 +-- not allowed +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 297 +-- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 298 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 299 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 300 +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 301 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 302 +-- not allowed +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 303 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 304 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 305 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 306 +GRANT SELECT ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 307 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 308 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 309 +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 310 +-- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 311 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 312 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 313 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 314 +-- not allowed +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 315 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 316 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 317 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 318 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 319 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 320 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 321 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 322 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 323 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 324 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 325 +GRANT UPDATE ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 326 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 327 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 328 +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 329 +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 330 +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 331 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 332 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 333 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 334 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 335 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'bar' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 336 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 337 +GRANT UPDATE ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 338 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 339 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 340 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 341 +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 342 +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'fud' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 343 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 344 +REVOKE UPDATE ON base_tbl FROM regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 345 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 346 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 347 +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 348 +-- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 349 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 350 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 351 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 352 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 353 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 354 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 355 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 356 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 357 +-- security invoker view permissions + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 358 +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 359 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 360 +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 361 +ALTER VIEW rw_view1 SET (security_invoker = true) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +== 362 +INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 363 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 364 +GRANT UPDATE (bb,cc) ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 365 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 366 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 367 +-- not allowed +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 368 +-- not allowed +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 369 +-- not allowed +INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 370 +-- not allowed +UPDATE base_tbl SET a=a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +== 371 +-- not allowed +UPDATE rw_view1 SET bb=bb, cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 372 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 373 +-- not allowed +DELETE FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +== 374 +-- not allowed +DELETE FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 375 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 376 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 377 +GRANT SELECT ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 378 +GRANT UPDATE (a,c) ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 379 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 380 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 381 +-- ok +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 382 +-- ok +UPDATE base_tbl SET a=a, c=c +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +== 383 +-- ok +UPDATE base_tbl SET b=b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +== 384 +-- not allowed +UPDATE rw_view1 SET cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 385 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET cc = cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 386 +-- ok +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 387 +-- not allowed +UPDATE rw_view1 SET bb=bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 388 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 389 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 390 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 391 +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 392 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 393 +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 394 +-- ok +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 395 +-- not allowed +DELETE FROM base_tbl WHERE a=1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +== 396 +-- ok +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 397 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 398 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 399 +REVOKE INSERT, DELETE ON base_tbl FROM regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 400 +GRANT INSERT, DELETE ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 401 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 402 +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 403 +-- not allowed +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 404 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 405 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 406 +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 407 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 408 +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 409 +-- ok +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 410 +-- ok +MERGE INTO rw_view1 t USING (VALUES (3)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 411 +-- ok +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 412 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 413 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 414 +-- ordinary view on top of security invoker view permissions + +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 415 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 416 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 417 +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 418 +ALTER VIEW rw_view1 SET (security_invoker = true) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +== 419 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 420 +-- not allowed +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 421 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (2, 'Row 2', 2.0)) AS v(a,b,c) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.b, v.c, v.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 422 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 423 +CREATE VIEW rw_view2 AS SELECT cc AS ccc, aa AS aaa, bb AS bbb FROM rw_view1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 424 +GRANT SELECT, UPDATE ON rw_view2 TO regress_view_user3 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: GrantStmt +== 425 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 426 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 427 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (2, 'Row 2', 2.0)) AS v(a,b,c) ON t.aaa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.c, v.a, v.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 428 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 429 +GRANT SELECT ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 430 +GRANT UPDATE (a, b) ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 431 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 432 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 433 +-- ok +UPDATE rw_view1 SET aa=aa, bb=bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 434 +-- ok +UPDATE rw_view1 SET cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 435 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa, bb = bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 436 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET cc = cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 437 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 438 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 439 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 440 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 441 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +== 442 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 443 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 444 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 445 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 446 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 447 +GRANT UPDATE (bb, cc) ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 448 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 449 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 450 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 451 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 452 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +== 453 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 454 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 455 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 456 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 457 +GRANT SELECT ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 458 +GRANT UPDATE (a, c) ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 459 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 460 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 461 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 462 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 463 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 464 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 465 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 466 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 467 +-- ok + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +== 468 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 469 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 470 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 471 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 472 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 473 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 474 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 475 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 476 +GRANT SELECT ON base_tbl TO regress_view_user3 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 477 +GRANT UPDATE (a, c) ON base_tbl TO regress_view_user3 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 478 +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +== 479 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 480 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 481 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 482 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 483 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 484 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 485 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 486 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 487 +REVOKE SELECT, UPDATE ON base_tbl FROM regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 488 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +== 489 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 490 +-- not allowed +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 491 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 492 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 493 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 494 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 495 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 496 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 497 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 498 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 499 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 500 +-- ok + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +== 501 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 502 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 503 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 504 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 505 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 506 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 507 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 508 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 509 +REVOKE SELECT, UPDATE ON base_tbl FROM regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 510 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +== 511 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 512 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 513 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 514 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 515 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 516 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 517 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 518 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +== 519 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 520 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 521 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 522 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 523 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 524 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 525 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 526 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 527 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 528 +DROP USER regress_view_user1 +-- +STMT: DropRoleStmt +== 529 +DROP USER regress_view_user2 +-- +STMT: DropRoleStmt +== 530 +DROP USER regress_view_user3 +-- +STMT: DropRoleStmt +== 531 +-- column defaults + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified', c serial) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 532 +INSERT INTO base_tbl VALUES (1, 'Row 1') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 533 +INSERT INTO base_tbl VALUES (2, 'Row 2') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 534 +INSERT INTO base_tbl VALUES (3) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 535 +CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 536 +ALTER VIEW rw_view1 ALTER COLUMN bb SET DEFAULT 'View default' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +== 537 +INSERT INTO rw_view1 VALUES (4, 'Row 4') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 538 +INSERT INTO rw_view1 (aa) VALUES (5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 539 +MERGE INTO rw_view1 t USING (VALUES (6)) AS v(a) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT (aa) VALUES (v.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 540 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 541 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 542 +-- Table having triggers + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 543 +INSERT INTO base_tbl VALUES (1, 'Row 1') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 544 +INSERT INTO base_tbl VALUES (2, 'Row 2') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 545 +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + UPDATE base_tbl SET b=NEW.b WHERE a=1; + RETURN NULL; + END IF; + RETURN NULL; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 546 +CREATE TRIGGER rw_view1_ins_trig AFTER INSERT ON base_tbl + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateTrigStmt +== 547 +CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 548 +INSERT INTO rw_view1 VALUES (3, 'Row 3') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 549 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 550 +DROP VIEW rw_view1 +-- +STMT: DropStmt +== 551 +DROP TRIGGER rw_view1_ins_trig on base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 552 +DROP FUNCTION rw_view1_trig_fn() +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: DropStmt +== 553 +DROP TABLE base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 554 +-- view with ORDER BY + +CREATE TABLE base_tbl (a int, b int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 555 +INSERT INTO base_tbl VALUES (1,2), (4,5), (3,-3) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 556 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl ORDER BY a+b +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 557 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 558 +INSERT INTO rw_view1 VALUES (7,-8) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 559 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 560 +EXPLAIN (verbose, costs off) UPDATE rw_view1 SET b = b + 1 RETURNING * +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 561 +UPDATE rw_view1 SET b = b + 1 RETURNING * +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 562 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 563 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 564 +-- multiple array-column updates + +CREATE TABLE base_tbl (a int, arr int[]) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 565 +INSERT INTO base_tbl VALUES (1,ARRAY[2]), (3,ARRAY[4]) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 566 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 567 +UPDATE rw_view1 SET arr[1] = 42, arr[2] = 77 WHERE a = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 568 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 569 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 570 +-- views with updatable and non-updatable columns + +CREATE TABLE base_tbl(a float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 571 +INSERT INTO base_tbl SELECT i/10.0 FROM generate_series(1,10) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 572 +CREATE VIEW rw_view1 AS + SELECT ctid, sin(a) s, a, cos(a) c + FROM base_tbl + WHERE a != 0 + ORDER BY abs(a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="sin" function="sin" schema="" ctx=Call +FUNCTION: name="cos" function="cos" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 573 +INSERT INTO rw_view1 VALUES (null, null, 1.1, null) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 574 +-- should fail +INSERT INTO rw_view1 (s, c, a) VALUES (null, null, 1.1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 575 +-- should fail +INSERT INTO rw_view1 (s, c, a) VALUES (default, default, 1.1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 576 +-- should fail +INSERT INTO rw_view1 (a) VALUES (1.1) RETURNING a, s, c +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 577 +-- OK +UPDATE rw_view1 SET s = s WHERE a = 1.1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 578 +-- should fail +UPDATE rw_view1 SET a = 1.05 WHERE a = 1.1 RETURNING s +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 579 +-- OK +DELETE FROM rw_view1 WHERE a = 1.05 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 580 +-- OK + +CREATE VIEW rw_view2 AS + SELECT s, c, s/c t, a base_a, ctid + FROM rw_view1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 581 +INSERT INTO rw_view2 VALUES (null, null, null, 1.1, null) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 582 +-- should fail +INSERT INTO rw_view2(s, c, base_a) VALUES (null, null, 1.1) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 583 +-- should fail +INSERT INTO rw_view2(base_a) VALUES (1.1) RETURNING t +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 584 +-- OK +UPDATE rw_view2 SET s = s WHERE base_a = 1.1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 585 +-- should fail +UPDATE rw_view2 SET t = t WHERE base_a = 1.1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 586 +-- should fail +UPDATE rw_view2 SET base_a = 1.05 WHERE base_a = 1.1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 587 +-- OK +DELETE FROM rw_view2 WHERE base_a = 1.05 RETURNING base_a, s, c, t +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 588 +-- OK + +CREATE VIEW rw_view3 AS + SELECT s, c, s/c t, ctid + FROM rw_view1 +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 589 +INSERT INTO rw_view3 VALUES (null, null, null, null) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 590 +-- should fail +INSERT INTO rw_view3(s) VALUES (null) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 591 +-- should fail +UPDATE rw_view3 SET s = s +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: UpdateStmt +== 592 +-- should fail +DELETE FROM rw_view3 WHERE s = sin(0.1) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +FUNCTION: name="sin" function="sin" schema="" ctx=Call +STMT: DeleteStmt +== 593 +-- should be OK +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 594 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 595 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 596 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 597 +SELECT events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + FROM pg_catalog.pg_relation_is_updatable('rw_view3'::regclass, false) t(events) +-- +FUNCTION: name="pg_catalog.pg_relation_is_updatable" function="pg_relation_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 598 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 599 +-- view on table with GENERATED columns + +CREATE TABLE base_tbl (id int, idplus1 int GENERATED ALWAYS AS (id + 1) STORED) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 600 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 601 +INSERT INTO base_tbl (id) VALUES (1) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 602 +INSERT INTO rw_view1 (id) VALUES (2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 603 +INSERT INTO base_tbl (id, idplus1) VALUES (3, DEFAULT) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 604 +INSERT INTO rw_view1 (id, idplus1) VALUES (4, DEFAULT) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 605 +INSERT INTO base_tbl (id, idplus1) VALUES (5, 6) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 606 +-- error +INSERT INTO rw_view1 (id, idplus1) VALUES (6, 7) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 607 +-- error + +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 608 +UPDATE base_tbl SET id = 2000 WHERE id = 2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +== 609 +UPDATE rw_view1 SET id = 3000 WHERE id = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 610 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 611 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 612 +-- inheritance tests + +CREATE TABLE base_tbl_parent (a int) +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=DDL +STMT: CreateStmt +== 613 +CREATE TABLE base_tbl_child (CHECK (a > 0)) INHERITS (base_tbl_parent) +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=DDL +STMT: CreateStmt +== 614 +INSERT INTO base_tbl_parent SELECT * FROM generate_series(-8, -1) +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 615 +INSERT INTO base_tbl_child SELECT * FROM generate_series(1, 8) +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 616 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl_parent +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 617 +CREATE VIEW rw_view2 AS SELECT * FROM ONLY base_tbl_parent +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 618 +SELECT * FROM rw_view1 ORDER BY a +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 619 +SELECT * FROM ONLY rw_view1 ORDER BY a +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 620 +SELECT * FROM rw_view2 ORDER BY a +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +== 621 +INSERT INTO rw_view1 VALUES (-100), (100) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 622 +INSERT INTO rw_view2 VALUES (-200), (200) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 623 +UPDATE rw_view1 SET a = a*10 WHERE a IN (-1, 1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 624 +-- Should produce -10 and 10 +UPDATE ONLY rw_view1 SET a = a*10 WHERE a IN (-2, 2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 625 +-- Should produce -20 and 20 +UPDATE rw_view2 SET a = a*10 WHERE a IN (-3, 3) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 626 +-- Should produce -30 only +UPDATE ONLY rw_view2 SET a = a*10 WHERE a IN (-4, 4) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 627 +-- Should produce -40 only + +DELETE FROM rw_view1 WHERE a IN (-5, 5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 628 +-- Should delete -5 and 5 +DELETE FROM ONLY rw_view1 WHERE a IN (-6, 6) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +== 629 +-- Should delete -6 and 6 +DELETE FROM rw_view2 WHERE a IN (-7, 7) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 630 +-- Should delete -7 only +DELETE FROM ONLY rw_view2 WHERE a IN (-8, 8) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +== 631 +-- Should delete -8 only + +SELECT * FROM ONLY base_tbl_parent ORDER BY a +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: SelectStmt +== 632 +SELECT * FROM base_tbl_child ORDER BY a +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=Select +STMT: SelectStmt +== 633 +MERGE INTO rw_view1 t USING (VALUES (-200), (10)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 634 +-- Should produce -199 and 11 +MERGE INTO ONLY rw_view1 t USING (VALUES (-100), (20)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 635 +-- Should produce -99 and 21 +MERGE INTO rw_view2 t USING (VALUES (-40), (3)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 636 +-- Should produce -39 only +MERGE INTO ONLY rw_view2 t USING (VALUES (-30), (4)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 637 +-- Should produce -29 only + +SELECT * FROM ONLY base_tbl_parent ORDER BY a +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: SelectStmt +== 638 +SELECT * FROM base_tbl_child ORDER BY a +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=Select +STMT: SelectStmt +== 639 +CREATE TABLE other_tbl_parent (id int) +-- +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=DDL +STMT: CreateStmt +== 640 +CREATE TABLE other_tbl_child () INHERITS (other_tbl_parent) +-- +TABLE: name="other_tbl_child" schema="" table="other_tbl_child" ctx=DDL +STMT: CreateStmt +== 641 +INSERT INTO other_tbl_parent VALUES (7),(200) +-- +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 642 +INSERT INTO other_tbl_child VALUES (8),(100) +-- +TABLE: name="other_tbl_child" schema="" table="other_tbl_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 643 +EXPLAIN (costs off) +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=Select +STMT: ExplainStmt +STMT: UpdateStmt +== 644 +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=Select +STMT: UpdateStmt +== 645 +SELECT * FROM ONLY base_tbl_parent ORDER BY a +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: SelectStmt +== 646 +SELECT * FROM base_tbl_child ORDER BY a +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=Select +STMT: SelectStmt +== 647 +DROP TABLE base_tbl_parent, base_tbl_child CASCADE +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=DDL +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=DDL +STMT: DropStmt +== 648 +DROP TABLE other_tbl_parent CASCADE +-- +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=DDL +STMT: DropStmt +== 649 +-- simple WITH CHECK OPTION + +CREATE TABLE base_tbl (a int, b int DEFAULT 10) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 650 +INSERT INTO base_tbl VALUES (1,2), (2,3), (1,-1) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 651 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b + WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 652 +SELECT * FROM information_schema.views WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 653 +INSERT INTO rw_view1 VALUES(3,4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 654 +-- ok +INSERT INTO rw_view1 VALUES(4,3) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 655 +-- should fail +INSERT INTO rw_view1 VALUES(5,null) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 656 +-- should fail +UPDATE rw_view1 SET b = 5 WHERE a = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 657 +-- ok +UPDATE rw_view1 SET b = -5 WHERE a = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 658 +-- should fail +INSERT INTO rw_view1(a) VALUES (9) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 659 +-- ok +INSERT INTO rw_view1(a) VALUES (10) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 660 +-- should fail +SELECT * FROM base_tbl ORDER BY a, b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 661 +MERGE INTO rw_view1 t USING (VALUES (10)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.a + 1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 662 +-- ok +MERGE INTO rw_view1 t USING (VALUES (11)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.a - 1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 663 +-- should fail +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a - 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 664 +-- ok +MERGE INTO rw_view1 t USING (VALUES (2)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a + 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +== 665 +-- should fail +SELECT * FROM base_tbl ORDER BY a, b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 666 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 667 +-- WITH LOCAL/CASCADED CHECK OPTION + +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 668 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a > 0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 669 +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 + WITH CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 670 +-- implicitly cascaded +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 671 +INSERT INTO rw_view2 VALUES (-5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 672 +-- should fail +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 673 +-- ok +INSERT INTO rw_view2 VALUES (15) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 674 +-- should fail +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 675 +UPDATE rw_view2 SET a = a - 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 676 +-- should fail +UPDATE rw_view2 SET a = a + 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 677 +-- should fail + +CREATE OR REPLACE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 + WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 678 +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 679 +INSERT INTO rw_view2 VALUES (-10) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 680 +-- ok, but not in view +INSERT INTO rw_view2 VALUES (20) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 681 +-- should fail +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 682 +ALTER VIEW rw_view1 SET (check_option=here) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +== 683 +-- invalid +ALTER VIEW rw_view1 SET (check_option=local) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +== 684 +INSERT INTO rw_view2 VALUES (-20) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 685 +-- should fail +INSERT INTO rw_view2 VALUES (30) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 686 +-- should fail + +ALTER VIEW rw_view2 RESET (check_option) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: AlterTableStmt +== 687 +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 688 +INSERT INTO rw_view2 VALUES (30) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 689 +-- ok, but not in view +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 690 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 691 +-- WITH CHECK OPTION with no local view qual + +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 692 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 693 +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a > 0 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 694 +CREATE VIEW rw_view3 AS SELECT * FROM rw_view2 WITH CHECK OPTION +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DDL +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 695 +SELECT * FROM information_schema.views WHERE table_name LIKE E'rw\\_view_' ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 696 +INSERT INTO rw_view1 VALUES (-1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 697 +-- ok +INSERT INTO rw_view1 VALUES (1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 698 +-- ok +INSERT INTO rw_view2 VALUES (-2) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 699 +-- ok, but not in view +INSERT INTO rw_view2 VALUES (2) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 700 +-- ok +INSERT INTO rw_view3 VALUES (-3) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 701 +-- should fail +INSERT INTO rw_view3 VALUES (3) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 702 +-- ok + +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 703 +-- WITH CHECK OPTION with scalar array ops + +CREATE TABLE base_tbl (a int, b int[]) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 704 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a = ANY (b) + WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 705 +INSERT INTO rw_view1 VALUES (1, ARRAY[1,2,3]) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 706 +-- ok +INSERT INTO rw_view1 VALUES (10, ARRAY[4,5]) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 707 +-- should fail + +UPDATE rw_view1 SET b[2] = -b[2] WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 708 +-- ok +UPDATE rw_view1 SET b[1] = -b[1] WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 709 +-- should fail + +PREPARE ins(int, int[]) AS INSERT INTO rw_view1 VALUES($1, $2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: PrepareStmt +STMT: InsertStmt +STMT: SelectStmt +== 710 +EXECUTE ins(2, ARRAY[1,2,3]) +-- +STMT: ExecuteStmt +== 711 +-- ok +EXECUTE ins(10, ARRAY[4,5]) +-- +STMT: ExecuteStmt +== 712 +-- should fail +DEALLOCATE PREPARE ins +-- +STMT: DeallocateStmt +== 713 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 714 +-- WITH CHECK OPTION with subquery + +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 715 +CREATE TABLE ref_tbl (a int PRIMARY KEY) +-- +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=DDL +STMT: CreateStmt +== 716 +INSERT INTO ref_tbl SELECT * FROM generate_series(1,10) +-- +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 717 +CREATE VIEW rw_view1 AS + SELECT * FROM base_tbl b + WHERE EXISTS(SELECT 1 FROM ref_tbl r WHERE r.a = b.a) + WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=Select +ALIAS: "b"="base_tbl" +ALIAS: "r"="ref_tbl" +FILTER: schema="" table="r" column="a" +FILTER: schema="" table="b" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 718 +INSERT INTO rw_view1 VALUES (5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 719 +-- ok +INSERT INTO rw_view1 VALUES (15) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 720 +-- should fail + +UPDATE rw_view1 SET a = a + 5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 721 +-- ok +UPDATE rw_view1 SET a = a + 5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 722 +-- should fail + +EXPLAIN (costs off) INSERT INTO rw_view1 VALUES (5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 723 +EXPLAIN (costs off) UPDATE rw_view1 SET a = a + 5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 724 +DROP TABLE base_tbl, ref_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=DDL +STMT: DropStmt +== 725 +-- WITH CHECK OPTION with BEFORE trigger on base table + +CREATE TABLE base_tbl (a int, b int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 726 +CREATE FUNCTION base_tbl_trig_fn() +RETURNS trigger AS +$$ +BEGIN + NEW.b := 10; + RETURN NEW; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="base_tbl_trig_fn" function="base_tbl_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 727 +CREATE TRIGGER base_tbl_trig BEFORE INSERT OR UPDATE ON base_tbl + FOR EACH ROW EXECUTE PROCEDURE base_tbl_trig_fn() +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateTrigStmt +== 728 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 729 +INSERT INTO rw_view1 VALUES (5,0) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 730 +-- ok +INSERT INTO rw_view1 VALUES (15, 20) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 731 +-- should fail +UPDATE rw_view1 SET a = 20, b = 30 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +== 732 +-- should fail + +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 733 +DROP FUNCTION base_tbl_trig_fn() +-- +FUNCTION: name="base_tbl_trig_fn" function="base_tbl_trig_fn" schema="" ctx=DDL +STMT: DropStmt +== 734 +-- WITH LOCAL CHECK OPTION with INSTEAD OF trigger on base view + +CREATE TABLE base_tbl (a int, b int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 735 +CREATE VIEW rw_view1 AS SELECT a FROM base_tbl WHERE a < b +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 736 +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + INSERT INTO base_tbl VALUES (NEW.a, 10); + RETURN NEW; + ELSIF TG_OP = 'UPDATE' THEN + UPDATE base_tbl SET a=NEW.a WHERE a=OLD.a; + RETURN NEW; + ELSIF TG_OP = 'DELETE' THEN + DELETE FROM base_tbl WHERE a=OLD.a; + RETURN OLD; + END IF; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 737 +CREATE TRIGGER rw_view1_trig + INSTEAD OF INSERT OR UPDATE OR DELETE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +== 738 +CREATE VIEW rw_view2 AS + SELECT * FROM rw_view1 WHERE a > 0 WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 739 +INSERT INTO rw_view2 VALUES (-5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 740 +-- should fail +MERGE INTO rw_view2 t USING (VALUES (-5)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 741 +-- should fail +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 742 +-- ok +MERGE INTO rw_view2 t USING (VALUES (6)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 743 +-- ok +INSERT INTO rw_view2 VALUES (50) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 744 +-- ok, but not in view +MERGE INTO rw_view2 t USING (VALUES (60)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 745 +-- ok, but not in view +UPDATE rw_view2 SET a = a - 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 746 +-- should fail +MERGE INTO rw_view2 t USING (VALUES (6)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a - 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +== 747 +-- should fail +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 748 +-- Check option won't cascade down to base view with INSTEAD OF triggers + +ALTER VIEW rw_view2 SET (check_option=cascaded) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: AlterTableStmt +== 749 +INSERT INTO rw_view2 VALUES (100) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 750 +-- ok, but not in view (doesn't fail rw_view1's check) +UPDATE rw_view2 SET a = 200 WHERE a = 5 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 751 +-- ok, but not in view (doesn't fail rw_view1's check) +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 752 +-- Neither local nor cascaded check options work with INSTEAD rules + +DROP TRIGGER rw_view1_trig ON rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: DropStmt +== 753 +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, 10) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +== 754 +CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 + DO INSTEAD UPDATE base_tbl SET a=NEW.a WHERE a=OLD.a +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +== 755 +INSERT INTO rw_view2 VALUES (-10) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 756 +-- ok, but not in view (doesn't fail rw_view2's check) +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 757 +-- ok +INSERT INTO rw_view2 VALUES (20) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 758 +-- ok, but not in view (doesn't fail rw_view1's check) +UPDATE rw_view2 SET a = 30 WHERE a = 5 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 759 +-- ok, but not in view (doesn't fail rw_view1's check) +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 760 +-- ok +UPDATE rw_view2 SET a = -5 WHERE a = 5 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +== 761 +-- ok, but not in view (doesn't fail rw_view2's check) +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 762 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 763 +DROP FUNCTION rw_view1_trig_fn() +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: DropStmt +== 764 +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 765 +CREATE VIEW rw_view1 AS SELECT a,10 AS b FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 766 +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +== 767 +CREATE VIEW rw_view2 AS + SELECT * FROM rw_view1 WHERE a > b WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +== 768 +INSERT INTO rw_view2 VALUES (2,3) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 769 +-- ok, but not in view (doesn't fail rw_view2's check) +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 770 +-- security barrier view + +CREATE TABLE base_tbl (person text, visibility text) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 771 +INSERT INTO base_tbl VALUES ('Tom', 'public'), + ('Dick', 'private'), + ('Harry', 'public') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 772 +CREATE VIEW rw_view1 AS + SELECT person FROM base_tbl WHERE visibility = 'public' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="visibility" +STMT: ViewStmt +STMT: SelectStmt +== 773 +CREATE FUNCTION snoop(anyelement) +RETURNS boolean AS +$$ +BEGIN + RAISE NOTICE 'snooped value: %', $1; + RETURN true; +END; +$$ +LANGUAGE plpgsql COST 0.000001 +-- +FUNCTION: name="snoop" function="snoop" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 774 +CREATE OR REPLACE FUNCTION leakproof(anyelement) +RETURNS boolean AS +$$ +BEGIN + RETURN true; +END; +$$ +LANGUAGE plpgsql STRICT IMMUTABLE LEAKPROOF +-- +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 775 +SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: SelectStmt +== 776 +UPDATE rw_view1 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: UpdateStmt +== 777 +DELETE FROM rw_view1 WHERE NOT snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +== 778 +ALTER VIEW rw_view1 SET (security_barrier = true) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +== 779 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 780 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 781 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view1' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 782 +SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: SelectStmt +== 783 +UPDATE rw_view1 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: UpdateStmt +== 784 +DELETE FROM rw_view1 WHERE NOT snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +== 785 +MERGE INTO rw_view1 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 786 +EXPLAIN (costs off) SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: ExplainStmt +STMT: SelectStmt +== 787 +EXPLAIN (costs off) UPDATE rw_view1 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 788 +EXPLAIN (costs off) DELETE FROM rw_view1 WHERE NOT snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +== 789 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 790 +-- security barrier view on top of security barrier view + +CREATE VIEW rw_view2 WITH (security_barrier = true) AS + SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: ViewStmt +STMT: SelectStmt +== 791 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 792 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 793 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view2' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 794 +SELECT * FROM rw_view2 WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: SelectStmt +== 795 +UPDATE rw_view2 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: UpdateStmt +== 796 +DELETE FROM rw_view2 WHERE NOT snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +== 797 +MERGE INTO rw_view2 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +== 798 +EXPLAIN (costs off) SELECT * FROM rw_view2 WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: ExplainStmt +STMT: SelectStmt +== 799 +EXPLAIN (costs off) UPDATE rw_view2 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 800 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE NOT snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +== 801 +EXPLAIN (costs off) +MERGE INTO rw_view2 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 802 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 803 +-- security barrier view on top of table with rules + +CREATE TABLE base_tbl(id int PRIMARY KEY, data text, deleted boolean) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 804 +INSERT INTO base_tbl VALUES (1, 'Row 1', false), (2, 'Row 2', true) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 805 +CREATE RULE base_tbl_ins_rule AS ON INSERT TO base_tbl + WHERE EXISTS (SELECT 1 FROM base_tbl t WHERE t.id = new.id) + DO INSTEAD + UPDATE base_tbl SET data = new.data, deleted = false WHERE id = new.id +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: RuleStmt +== 806 +CREATE RULE base_tbl_del_rule AS ON DELETE TO base_tbl + DO INSTEAD + UPDATE base_tbl SET deleted = true WHERE id = old.id +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: RuleStmt +== 807 +CREATE VIEW rw_view1 WITH (security_barrier=true) AS + SELECT id, data FROM base_tbl WHERE NOT deleted +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="deleted" +STMT: ViewStmt +STMT: SelectStmt +== 808 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +== 809 +EXPLAIN (costs off) DELETE FROM rw_view1 WHERE id = 1 AND snoop(data) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +== 810 +DELETE FROM rw_view1 WHERE id = 1 AND snoop(data) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +== 811 +EXPLAIN (costs off) INSERT INTO rw_view1 VALUES (2, 'New row 2') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 812 +INSERT INTO rw_view1 VALUES (2, 'New row 2') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 813 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 814 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 815 +-- security barrier view based on inheritance set +CREATE TABLE t1 (a int, b float, c text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 816 +CREATE INDEX t1_a_idx ON t1(a) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: IndexStmt +== 817 +INSERT INTO t1 +SELECT i,i,'t1' FROM generate_series(1,10) g(i) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 818 +ANALYZE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: VacuumStmt +== 819 +CREATE TABLE t11 (d text) INHERITS (t1) +-- +TABLE: name="t11" schema="" table="t11" ctx=DDL +STMT: CreateStmt +== 820 +CREATE INDEX t11_a_idx ON t11(a) +-- +TABLE: name="t11" schema="" table="t11" ctx=DDL +STMT: IndexStmt +== 821 +INSERT INTO t11 +SELECT i,i,'t11','t11d' FROM generate_series(1,10) g(i) +-- +TABLE: name="t11" schema="" table="t11" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 822 +ANALYZE t11 +-- +TABLE: name="t11" schema="" table="t11" ctx=DDL +STMT: VacuumStmt +== 823 +CREATE TABLE t12 (e int[]) INHERITS (t1) +-- +TABLE: name="t12" schema="" table="t12" ctx=DDL +STMT: CreateStmt +== 824 +CREATE INDEX t12_a_idx ON t12(a) +-- +TABLE: name="t12" schema="" table="t12" ctx=DDL +STMT: IndexStmt +== 825 +INSERT INTO t12 +SELECT i,i,'t12','{1,2}'::int[] FROM generate_series(1,10) g(i) +-- +TABLE: name="t12" schema="" table="t12" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 826 +ANALYZE t12 +-- +TABLE: name="t12" schema="" table="t12" ctx=DDL +STMT: VacuumStmt +== 827 +CREATE TABLE t111 () INHERITS (t11, t12) +-- +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: CreateStmt +== 828 +CREATE INDEX t111_a_idx ON t111(a) +-- +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: IndexStmt +== 829 +INSERT INTO t111 +SELECT i,i,'t111','t111d','{1,1,1}'::int[] FROM generate_series(1,10) g(i) +-- +TABLE: name="t111" schema="" table="t111" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 830 +ANALYZE t111 +-- +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: VacuumStmt +== 831 +CREATE VIEW v1 WITH (security_barrier=true) AS +SELECT *, (SELECT d FROM t11 WHERE t11.a = t1.a LIMIT 1) AS d +FROM t1 +WHERE a > 5 AND EXISTS(SELECT 1 FROM t12 WHERE t12.a = t1.a) +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t11" schema="" table="t11" ctx=Select +TABLE: name="t12" schema="" table="t12" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="t11" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t12" column="a" +FILTER: schema="" table="t1" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 832 +SELECT * FROM v1 WHERE a=3 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 833 +-- should not see anything +SELECT * FROM v1 WHERE a=8 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 834 +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 835 +UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: UpdateStmt +== 836 +SELECT * FROM v1 WHERE a=100 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 837 +-- Nothing should have been changed to 100 +SELECT * FROM t1 WHERE a=100 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 838 +-- Nothing should have been changed to 100 + +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +== 839 +UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: UpdateStmt +== 840 +SELECT * FROM v1 WHERE b=8 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +== 841 +DELETE FROM v1 WHERE snoop(a) AND leakproof(a) +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: DeleteStmt +== 842 +-- should not delete everything, just where a>5 + +TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +== 843 +-- verify all a<=5 are intact + +DROP TABLE t1, t11, t12, t111 CASCADE +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +TABLE: name="t11" schema="" table="t11" ctx=DDL +TABLE: name="t12" schema="" table="t12" ctx=DDL +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: DropStmt +== 844 +DROP FUNCTION snoop(anyelement) +-- +FUNCTION: name="snoop" function="snoop" schema="" ctx=DDL +STMT: DropStmt +== 845 +DROP FUNCTION leakproof(anyelement) +-- +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=DDL +STMT: DropStmt +== 846 +CREATE TABLE tx1 (a integer) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +== 847 +CREATE TABLE tx2 (b integer) +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: CreateStmt +== 848 +CREATE TABLE tx3 (c integer) +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: CreateStmt +== 849 +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=Select +TABLE: name="tx2" schema="" table="tx2" ctx=Select +TABLE: name="tx3" schema="" table="tx3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 850 +INSERT INTO vx1 values (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 851 +SELECT * FROM tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=Select +STMT: SelectStmt +== 852 +SELECT * FROM vx1 +-- +TABLE: name="vx1" schema="" table="vx1" ctx=Select +STMT: SelectStmt +== 853 +DROP VIEW vx1 +-- +STMT: DropStmt +== 854 +DROP TABLE tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: DropStmt +== 855 +DROP TABLE tx2 +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: DropStmt +== 856 +DROP TABLE tx3 +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: DropStmt +== 857 +CREATE TABLE tx1 (a integer) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +== 858 +CREATE TABLE tx2 (b integer) +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: CreateStmt +== 859 +CREATE TABLE tx3 (c integer) +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: CreateStmt +== 860 +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=Select +TABLE: name="tx2" schema="" table="tx2" ctx=Select +TABLE: name="tx3" schema="" table="tx3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 861 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 862 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 863 +SELECT * FROM tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=Select +STMT: SelectStmt +== 864 +SELECT * FROM vx1 +-- +TABLE: name="vx1" schema="" table="vx1" ctx=Select +STMT: SelectStmt +== 865 +DROP VIEW vx1 +-- +STMT: DropStmt +== 866 +DROP TABLE tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: DropStmt +== 867 +DROP TABLE tx2 +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: DropStmt +== 868 +DROP TABLE tx3 +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: DropStmt +== 869 +CREATE TABLE tx1 (a integer, b integer) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +== 870 +CREATE TABLE tx2 (b integer, c integer) +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: CreateStmt +== 871 +CREATE TABLE tx3 (c integer, d integer) +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: CreateStmt +== 872 +ALTER TABLE tx1 DROP COLUMN b +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: AlterTableStmt +== 873 +ALTER TABLE tx2 DROP COLUMN c +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: AlterTableStmt +== 874 +ALTER TABLE tx3 DROP COLUMN d +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: AlterTableStmt +== 875 +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=Select +TABLE: name="tx2" schema="" table="tx2" ctx=Select +TABLE: name="tx3" schema="" table="tx3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 876 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 877 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 878 +SELECT * FROM tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=Select +STMT: SelectStmt +== 879 +SELECT * FROM vx1 +-- +TABLE: name="vx1" schema="" table="vx1" ctx=Select +STMT: SelectStmt +== 880 +DROP VIEW vx1 +-- +STMT: DropStmt +== 881 +DROP TABLE tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: DropStmt +== 882 +DROP TABLE tx2 +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: DropStmt +== 883 +DROP TABLE tx3 +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: DropStmt +== 884 +|-- +-- Test handling of vars from correlated subqueries in quals from outer +-- security barrier views, per bug #13988 +|-- +CREATE TABLE t1 (a int, b text, c int) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 885 +INSERT INTO t1 VALUES (1, 'one', 10) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 886 +CREATE TABLE t2 (cc int) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +== 887 +INSERT INTO t2 VALUES (10), (20) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 888 +CREATE VIEW v1 WITH (security_barrier = true) AS + SELECT * FROM t1 WHERE (a > 0) + WITH CHECK OPTION +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 889 +CREATE VIEW v2 WITH (security_barrier = true) AS + SELECT * FROM v1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.cc = v1.c) + WITH CHECK OPTION +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +FILTER: schema="" table="t2" column="cc" +FILTER: schema="" table="v1" column="c" +STMT: ViewStmt +STMT: SelectStmt +== 890 +INSERT INTO v2 VALUES (2, 'two', 20) +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 891 +-- ok +INSERT INTO v2 VALUES (-2, 'minus two', 20) +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 892 +-- not allowed +INSERT INTO v2 VALUES (3, 'three', 30) +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 893 +-- not allowed + +UPDATE v2 SET b = 'ONE' WHERE a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +== 894 +-- ok +UPDATE v2 SET a = -1 WHERE a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +== 895 +-- not allowed +UPDATE v2 SET c = 30 WHERE a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +== 896 +-- not allowed + +DELETE FROM v2 WHERE a = 2 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: DeleteStmt +== 897 +-- ok +SELECT * FROM v2 +-- +TABLE: name="v2" schema="" table="v2" ctx=Select +STMT: SelectStmt +== 898 +DROP VIEW v2 +-- +STMT: DropStmt +== 899 +DROP VIEW v1 +-- +STMT: DropStmt +== 900 +DROP TABLE t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +== 901 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 902 +|-- +-- Test sub-select in nested security barrier views, per bug #17972 +|-- +CREATE TABLE t1 (a int) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 903 +CREATE VIEW v1 WITH (security_barrier = true) AS + SELECT * FROM t1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 904 +CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD + UPDATE t1 SET a = NEW.a WHERE a = OLD.a +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: RuleStmt +== 905 +CREATE VIEW v2 WITH (security_barrier = true) AS + SELECT * FROM v1 WHERE EXISTS (SELECT 1) +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 906 +EXPLAIN (COSTS OFF) UPDATE v2 SET a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 907 +DROP VIEW v2 +-- +STMT: DropStmt +== 908 +DROP VIEW v1 +-- +STMT: DropStmt +== 909 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 910 +|-- +-- Test CREATE OR REPLACE VIEW turning a non-updatable view into an +-- auto-updatable view and adding check options in a single step +|-- +CREATE TABLE t1 (a int, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 911 +CREATE VIEW v1 AS SELECT null::int AS a +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 912 +CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 WHERE a > 0 WITH CHECK OPTION +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 913 +INSERT INTO v1 VALUES (1, 'ok') +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 914 +-- ok +INSERT INTO v1 VALUES (-1, 'invalid') +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 915 +-- should fail + +DROP VIEW v1 +-- +STMT: DropStmt +== 916 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +== 917 +-- check that an auto-updatable view on a partitioned table works correctly +create table uv_pt (a int, b int, v varchar) partition by range (a, b) +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=DDL +STMT: CreateStmt +== 918 +create table uv_pt1 (b int not null, v varchar, a int not null) partition by range (b) +-- +TABLE: name="uv_pt1" schema="" table="uv_pt1" ctx=DDL +STMT: CreateStmt +== 919 +create table uv_pt11 (like uv_pt1) +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: CreateStmt +== 920 +alter table uv_pt11 drop a +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +== 921 +alter table uv_pt11 add a int +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +== 922 +alter table uv_pt11 drop a +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +== 923 +alter table uv_pt11 add a int not null +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +== 924 +alter table uv_pt1 attach partition uv_pt11 for values from (2) to (5) +-- +TABLE: name="uv_pt1" schema="" table="uv_pt1" ctx=DDL +STMT: AlterTableStmt +== 925 +alter table uv_pt attach partition uv_pt1 for values from (1, 2) to (1, 10) +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=DDL +STMT: AlterTableStmt +== 926 +create view uv_ptv as select * from uv_pt +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DDL +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 927 +select events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + from pg_catalog.pg_relation_is_updatable('uv_pt'::regclass, false) t(events) +-- +FUNCTION: name="pg_catalog.pg_relation_is_updatable" function="pg_relation_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 928 +select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 1::smallint, false) +-- +FUNCTION: name="pg_catalog.pg_column_is_updatable" function="pg_column_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 929 +select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 2::smallint, false) +-- +FUNCTION: name="pg_catalog.pg_column_is_updatable" function="pg_column_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 930 +select table_name, is_updatable, is_insertable_into + from information_schema.views where table_name = 'uv_ptv' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 931 +select table_name, column_name, is_updatable + from information_schema.columns where table_name = 'uv_ptv' order by column_name +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 932 +insert into uv_ptv values (1, 2) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 933 +select tableoid::regclass, * from uv_pt +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +STMT: SelectStmt +== 934 +create view uv_ptv_wco as select * from uv_pt where a = 0 with check option +-- +TABLE: name="uv_ptv_wco" schema="" table="uv_ptv_wco" ctx=DDL +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 935 +insert into uv_ptv_wco values (1, 2) +-- +TABLE: name="uv_ptv_wco" schema="" table="uv_ptv_wco" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 936 +merge into uv_ptv t + using (values (1,2), (1,4)) as v(a,b) on t.a = v.a -- fail: matches 2 src rows + when matched then update set b = t.b + 1 + when not matched then insert values (v.a, v.b + 1) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +ALIAS: "t"="uv_ptv" +STMT: MergeStmt +STMT: SelectStmt +== 937 +merge into uv_ptv t + using (values (1,2), (1,4)) as v(a,b) on t.a = v.a and t.b = v.b + when matched then update set b = t.b + 1 + when not matched then insert values (v.a, v.b + 1) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +ALIAS: "t"="uv_ptv" +STMT: MergeStmt +STMT: SelectStmt +== 938 +-- fail: no partition for b=5 +merge into uv_ptv t + using (values (1,2), (1,3)) as v(a,b) on t.a = v.a and t.b = v.b + when matched then update set b = t.b + 1 + when not matched then insert values (v.a, v.b + 1) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +ALIAS: "t"="uv_ptv" +STMT: MergeStmt +STMT: SelectStmt +== 939 +-- ok +select tableoid::regclass, * from uv_pt order by a, b +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +STMT: SelectStmt +== 940 +drop view uv_ptv, uv_ptv_wco +-- +STMT: DropStmt +== 941 +drop table uv_pt, uv_pt1, uv_pt11 +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=DDL +TABLE: name="uv_pt1" schema="" table="uv_pt1" ctx=DDL +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: DropStmt +== 942 +-- check that wholerow vars appearing in WITH CHECK OPTION constraint expressions +-- work fine with partitioned tables +create table wcowrtest (a int) partition by list (a) +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +STMT: CreateStmt +== 943 +create table wcowrtest1 partition of wcowrtest for values in (1) +-- +TABLE: name="wcowrtest1" schema="" table="wcowrtest1" ctx=DDL +STMT: CreateStmt +== 944 +create view wcowrtest_v as select * from wcowrtest where wcowrtest = '(2)'::wcowrtest with check option +-- +TABLE: name="wcowrtest_v" schema="" table="wcowrtest_v" ctx=DDL +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=Select +FILTER: schema="" table="" column="wcowrtest" +STMT: ViewStmt +STMT: SelectStmt +== 945 +insert into wcowrtest_v values (1) +-- +TABLE: name="wcowrtest_v" schema="" table="wcowrtest_v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 946 +alter table wcowrtest add b text +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +STMT: AlterTableStmt +== 947 +create table wcowrtest2 (b text, c int, a int) +-- +TABLE: name="wcowrtest2" schema="" table="wcowrtest2" ctx=DDL +STMT: CreateStmt +== 948 +alter table wcowrtest2 drop c +-- +TABLE: name="wcowrtest2" schema="" table="wcowrtest2" ctx=DDL +STMT: AlterTableStmt +== 949 +alter table wcowrtest attach partition wcowrtest2 for values in (2) +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +STMT: AlterTableStmt +== 950 +create table sometable (a int, b text) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DDL +STMT: CreateStmt +== 951 +insert into sometable values (1, 'a'), (2, 'b') +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 952 +create view wcowrtest_v2 as + select * + from wcowrtest r + where r in (select s from sometable s where r.a = s.a) +with check option +-- +TABLE: name="wcowrtest_v2" schema="" table="wcowrtest_v2" ctx=DDL +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=Select +TABLE: name="sometable" schema="" table="sometable" ctx=Select +ALIAS: "r"="wcowrtest" +ALIAS: "s"="sometable" +FILTER: schema="" table="" column="r" +FILTER: schema="" table="r" column="a" +FILTER: schema="" table="s" column="a" +STMT: ViewStmt +STMT: SelectStmt +== 953 +-- WITH CHECK qual will be processed with wcowrtest2's +-- rowtype after tuple-routing +insert into wcowrtest_v2 values (2, 'no such row in sometable') +-- +TABLE: name="wcowrtest_v2" schema="" table="wcowrtest_v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 954 +drop view wcowrtest_v, wcowrtest_v2 +-- +STMT: DropStmt +== 955 +drop table wcowrtest, sometable +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +TABLE: name="sometable" schema="" table="sometable" ctx=DDL +STMT: DropStmt +== 956 +-- Check INSERT .. ON CONFLICT DO UPDATE works correctly when the view's +-- columns are named and ordered differently than the underlying table's. +create table uv_iocu_tab (a text unique, b float) +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: CreateStmt +== 957 +insert into uv_iocu_tab values ('xyxyxy', 0) +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 958 +create view uv_iocu_view as + select b, b+1 as c, a, '2.0'::text as two from uv_iocu_tab +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DDL +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 959 +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = uv_iocu_view.b +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 960 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +== 961 +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = excluded.b +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 962 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +== 963 +-- OK to access view columns that are not present in underlying base +-- relation in the ON CONFLICT portion of the query +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = cast(excluded.two as float) +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 964 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +== 965 +explain (costs off) +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0 +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 966 +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0 +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 967 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +== 968 +drop view uv_iocu_view +-- +STMT: DropStmt +== 969 +drop table uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: DropStmt +== 970 +-- Test whole-row references to the view +create table uv_iocu_tab (a int unique, b text) +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: CreateStmt +== 971 +create view uv_iocu_view as + select b as bb, a as aa, uv_iocu_tab::text as cc from uv_iocu_tab +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DDL +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 972 +insert into uv_iocu_view (aa,bb) values (1,'x') +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 973 +explain (costs off) +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +== 974 +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 975 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +== 976 +-- Test omitting a column of the base relation +delete from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: DeleteStmt +== 977 +insert into uv_iocu_view (aa,bb) values (1,'x') +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 978 +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.* +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 979 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +== 980 +alter table uv_iocu_tab alter column b set default 'table default' +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: AlterTableStmt +== 981 +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.* +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 982 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +== 983 +alter view uv_iocu_view alter column bb set default 'view default' +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DDL +STMT: AlterTableStmt +== 984 +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.* +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 985 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +== 986 +-- Should fail to update non-updatable columns +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set cc = 'XXX' +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 987 +drop view uv_iocu_view +-- +STMT: DropStmt +== 988 +drop table uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: DropStmt +== 989 +-- ON CONFLICT DO UPDATE permissions checks +create user regress_view_user1 +-- +STMT: CreateRoleStmt +== 990 +create user regress_view_user2 +-- +STMT: CreateRoleStmt +== 991 +set session authorization regress_view_user1 +-- +STMT: VariableSetStmt +== 992 +create table base_tbl(a int unique, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +== 993 +insert into base_tbl values (1,'xxx',1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 994 +create view rw_view1 as select b as bb, c as cc, a as aa from base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 995 +grant select (aa,bb) on rw_view1 to regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 996 +grant insert on rw_view1 to regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 997 +grant update (bb) on rw_view1 to regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +== 998 +set session authorization regress_view_user2 +-- +STMT: VariableSetStmt +== 999 +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1000 +-- Not allowed +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = rw_view1.cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1001 +-- Not allowed +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1002 +-- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set bb = rw_view1.bb||'xxx' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1003 +-- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set cc = 3.0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1004 +-- Not allowed +reset session authorization +-- +STMT: VariableSetStmt +== 1005 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 1006 +set session authorization regress_view_user1 +-- +STMT: VariableSetStmt +== 1007 +grant select (a,b) on base_tbl to regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 1008 +grant insert (a,b) on base_tbl to regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 1009 +grant update (a,b) on base_tbl to regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +== 1010 +set session authorization regress_view_user2 +-- +STMT: VariableSetStmt +== 1011 +create view rw_view2 as select b as bb, c as cc, a as aa from base_tbl +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 1012 +insert into rw_view2 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1013 +-- Not allowed +create view rw_view3 as select b as bb, a as aa from base_tbl +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 1014 +insert into rw_view3 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1015 +-- OK +reset session authorization +-- +STMT: VariableSetStmt +== 1016 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 1017 +set session authorization regress_view_user2 +-- +STMT: VariableSetStmt +== 1018 +create view rw_view4 as select aa, bb, cc FROM rw_view1 +-- +TABLE: name="rw_view4" schema="" table="rw_view4" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 1019 +insert into rw_view4 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view4" schema="" table="rw_view4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1020 +-- Not allowed +create view rw_view5 as select aa, bb FROM rw_view1 +-- +TABLE: name="rw_view5" schema="" table="rw_view5" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 1021 +insert into rw_view5 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view5" schema="" table="rw_view5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1022 +-- OK +reset session authorization +-- +STMT: VariableSetStmt +== 1023 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +== 1024 +drop view rw_view5 +-- +STMT: DropStmt +== 1025 +drop view rw_view4 +-- +STMT: DropStmt +== 1026 +drop view rw_view3 +-- +STMT: DropStmt +== 1027 +drop view rw_view2 +-- +STMT: DropStmt +== 1028 +drop view rw_view1 +-- +STMT: DropStmt +== 1029 +drop table base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +== 1030 +drop user regress_view_user1 +-- +STMT: DropRoleStmt +== 1031 +drop user regress_view_user2 +-- +STMT: DropRoleStmt +== 1032 +-- Test single- and multi-row inserts with table and view defaults. +-- Table defaults should be used, unless overridden by view defaults. +create table base_tab_def (a int, b text default 'Table default', + c text default 'Table default', d text, e text) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: CreateStmt +== 1033 +create view base_tab_def_view as select * from base_tab_def +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 1034 +alter view base_tab_def_view alter b set default 'View default' +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: AlterTableStmt +== 1035 +alter view base_tab_def_view alter d set default 'View default' +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: AlterTableStmt +== 1036 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1037 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1038 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1039 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1040 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1041 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1042 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1043 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1044 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1045 +select * from base_tab_def order by a +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +== 1046 +-- Adding an INSTEAD OF trigger should cause NULLs to be inserted instead of +-- table defaults, where there are no view defaults. +create function base_tab_def_view_instrig_func() returns trigger +as +$$ +begin + insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); + return new; +end; +$$ +language plpgsql +-- +FUNCTION: name="base_tab_def_view_instrig_func" function="base_tab_def_view_instrig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 1047 +create trigger base_tab_def_view_instrig instead of insert on base_tab_def_view + for each row execute function base_tab_def_view_instrig_func() +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: CreateTrigStmt +== 1048 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +== 1049 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1050 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1051 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1052 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1053 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1054 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1055 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1056 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1057 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1058 +select * from base_tab_def order by a +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +== 1059 +-- Using an unconditional DO INSTEAD rule should also cause NULLs to be +-- inserted where there are no view defaults. +drop trigger base_tab_def_view_instrig on base_tab_def_view +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: DropStmt +== 1060 +drop function base_tab_def_view_instrig_func +-- +FUNCTION: name="base_tab_def_view_instrig_func" function="base_tab_def_view_instrig_func" schema="" ctx=DDL +STMT: DropStmt +== 1061 +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do instead insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: RuleStmt +== 1062 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +== 1063 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1064 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1065 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1066 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1067 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1068 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1069 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1070 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1071 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1072 +select * from base_tab_def order by a +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +== 1073 +-- A DO ALSO rule should cause each row to be inserted twice. The first +-- insert should behave the same as an auto-updatable view (using table +-- defaults, unless overridden by view defaults). The second insert should +-- behave the same as a rule-updatable view (inserting NULLs where there are +-- no view defaults). +drop rule base_tab_def_view_ins_rule on base_tab_def_view +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: DropStmt +== 1074 +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do also insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: RuleStmt +== 1075 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +== 1076 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1077 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1078 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1079 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1080 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1081 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1082 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1083 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1084 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1085 +select * from base_tab_def order by a, c NULLS LAST +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +== 1086 +-- Test a DO ALSO INSERT ... SELECT rule +drop rule base_tab_def_view_ins_rule on base_tab_def_view +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: DropStmt +== 1087 +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do also insert into base_tab_def (a, b, e) select new.a, new.b, 'xxx' +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: RuleStmt +== 1088 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +== 1089 +insert into base_tab_def_view values (1, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1090 +insert into base_tab_def_view values (2, default, default, default, default), + (3, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1091 +select * from base_tab_def order by a, e nulls first +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +== 1092 +drop view base_tab_def_view +-- +STMT: DropStmt +== 1093 +drop table base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: DropStmt +== 1094 +-- Test defaults with array assignments +create table base_tab (a serial, b int[], c text, d text default 'Table default') +-- +TABLE: name="base_tab" schema="" table="base_tab" ctx=DDL +STMT: CreateStmt +== 1095 +create view base_tab_view as select c, a, b from base_tab +-- +TABLE: name="base_tab_view" schema="" table="base_tab_view" ctx=DDL +TABLE: name="base_tab" schema="" table="base_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 1096 +alter view base_tab_view alter column c set default 'View default' +-- +TABLE: name="base_tab_view" schema="" table="base_tab_view" ctx=DDL +STMT: AlterTableStmt +== 1097 +insert into base_tab_view (b[1], b[2], c, b[5], b[4], a, b[3]) +values (1, 2, default, 5, 4, default, 3), (10, 11, 'C value', 14, 13, 100, 12) +-- +TABLE: name="base_tab_view" schema="" table="base_tab_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 1098 +select * from base_tab order by a +-- +TABLE: name="base_tab" schema="" table="base_tab" ctx=Select +STMT: SelectStmt +== 1099 +drop view base_tab_view +-- +STMT: DropStmt +== 1100 +drop table base_tab +-- +TABLE: name="base_tab" schema="" table="base_tab" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/update.metadata.json b/parser/testdata/summary/postgres_regress/update.metadata.json new file mode 100644 index 0000000..1b73a29 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/update.metadata.json @@ -0,0 +1,261 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257" + ] +} diff --git a/parser/testdata/summary/postgres_regress/update.test b/parser/testdata/summary/postgres_regress/update.test new file mode 100644 index 0000000..3818afe --- /dev/null +++ b/parser/testdata/summary/postgres_regress/update.test @@ -0,0 +1,1678 @@ +== 001 +|-- +-- UPDATE syntax tests +|-- + +CREATE TABLE update_test ( + a INT DEFAULT 10, + b INT, + c TEXT +) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE upsert_test ( + a INT PRIMARY KEY, + b TEXT +) +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO update_test VALUES (5, 10, 'foo') +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO update_test(b, a) VALUES (15, 10) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 006 +UPDATE update_test SET a = DEFAULT, b = DEFAULT +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +== 007 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 008 +-- aliases for the UPDATE target table +UPDATE update_test AS t SET b = 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +== 009 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 010 +UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +== 011 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 012 +-- error, you're not supposed to qualify the target column +UPDATE update_test t SET t.b = t.b + 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +== 013 +|-- +-- Test VALUES in FROM +|-- + +UPDATE update_test SET a=v.i FROM (VALUES(100, 20)) AS v(i, j) + WHERE update_test.b = v.j +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +== 014 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 015 +-- fail, wrong data type: +UPDATE update_test SET a = v.* FROM (VALUES(100, 20)) AS v(i, j) + WHERE update_test.b = v.j +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +== 016 +|-- +-- Test multiple-set-clause syntax +|-- + +INSERT INTO update_test SELECT a,b+1,c FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 017 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 018 +UPDATE update_test SET (c,b,a) = ('bugle', b+11, DEFAULT) WHERE c = 'foo' +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +== 019 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 020 +UPDATE update_test SET (c,b) = ('car', a+b), a = a + 1 WHERE a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +== 021 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 022 +-- fail, multi assignment to same column: +UPDATE update_test SET (c,b) = ('car', a+b), b = a + 1 WHERE a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +== 023 +-- uncorrelated sub-select: +UPDATE update_test + SET (b,a) = (select a,b from update_test where b = 41 and c = 'car') + WHERE a = 100 AND b = 20 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: UpdateStmt +STMT: SelectStmt +== 024 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 025 +-- correlated sub-select: +UPDATE update_test o + SET (b,a) = (select a+1,b from update_test i + where i.a=o.a and i.b=o.b and i.c is not distinct from o.c) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +ALIAS: "i"="update_test" +ALIAS: "o"="update_test" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="o" column="a" +FILTER: schema="" table="i" column="b" +FILTER: schema="" table="o" column="b" +FILTER: schema="" table="i" column="c" +FILTER: schema="" table="o" column="c" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="o" column="a" +FILTER: schema="" table="i" column="b" +FILTER: schema="" table="o" column="b" +FILTER: schema="" table="i" column="c" +FILTER: schema="" table="o" column="c" +STMT: UpdateStmt +STMT: SelectStmt +== 026 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 027 +-- fail, multiple rows supplied: +UPDATE update_test SET (b,a) = (select a+1,b from update_test) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +== 028 +-- set to null if no rows supplied: +UPDATE update_test SET (b,a) = (select a+1,b from update_test where a = 1000) + WHERE a = 11 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: UpdateStmt +STMT: SelectStmt +== 029 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +== 030 +-- *-expansion should work in this context: +UPDATE update_test SET (a,b) = ROW(v.*) FROM (VALUES(21, 100)) AS v(i, j) + WHERE update_test.a = v.i +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +== 031 +-- you might expect this to work, but syntactically it's not a RowExpr: +UPDATE update_test SET (a,b) = (v.*) FROM (VALUES(21, 101)) AS v(i, j) + WHERE update_test.a = v.i +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +== 032 +-- if an alias for the target table is specified, don't allow references +-- to the original table name +UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +== 033 +-- Make sure that we can update to a TOASTed value. +UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car' +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: UpdateStmt +== 034 +SELECT a, b, char_length(c) FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +== 035 +-- Check multi-assignment with a Result node to handle a one-time filter. +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +ALIAS: "s"="update_test" +ALIAS: "t"="update_test" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +== 036 +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +ALIAS: "s"="update_test" +ALIAS: "t"="update_test" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +STMT: UpdateStmt +STMT: SelectStmt +== 037 +SELECT a, b, char_length(c) FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +== 038 +-- Test ON CONFLICT DO UPDATE + +INSERT INTO upsert_test VALUES(1, 'Boo'), (3, 'Zoo') +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 039 +-- uncorrelated sub-select: +WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test + VALUES (1, 'Bar') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +CTE: "aaa" +STMT: InsertStmt +STMT: SelectStmt +== 040 +-- correlated sub-select: +INSERT INTO upsert_test VALUES (1, 'Baz'), (3, 'Zaz') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Correlated', a from upsert_test i WHERE i.a = upsert_test.a) + RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="upsert_test" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="upsert_test" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 041 +-- correlated sub-select (EXCLUDED.* alias): +INSERT INTO upsert_test VALUES (1, 'Bat'), (3, 'Zot') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 042 +-- ON CONFLICT using system attributes in RETURNING, testing both the +-- inserting and updating paths. See bug report at: +-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au +INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = 0 AS xmax_correct +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 043 +-- currently xmax is set after a conflict - that's probably not good, +-- but it seems worthwhile to have to be explicit if that changes. +INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = pg_current_xact_id()::xid AS xmax_correct +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 044 +DROP TABLE update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DDL +STMT: DropStmt +== 045 +DROP TABLE upsert_test +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: DropStmt +== 046 +-- Test ON CONFLICT DO UPDATE with partitioned table and non-identical children + +CREATE TABLE upsert_test ( + a INT PRIMARY KEY, + b TEXT +) PARTITION BY LIST (a) +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: CreateStmt +== 047 +CREATE TABLE upsert_test_1 PARTITION OF upsert_test FOR VALUES IN (1) +-- +TABLE: name="upsert_test_1" schema="" table="upsert_test_1" ctx=DDL +STMT: CreateStmt +== 048 +CREATE TABLE upsert_test_2 (b TEXT, a INT PRIMARY KEY) +-- +TABLE: name="upsert_test_2" schema="" table="upsert_test_2" ctx=DDL +STMT: CreateStmt +== 049 +ALTER TABLE upsert_test ATTACH PARTITION upsert_test_2 FOR VALUES IN (2) +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: AlterTableStmt +== 050 +INSERT INTO upsert_test VALUES(1, 'Boo'), (2, 'Zoo') +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 051 +-- uncorrelated sub-select: +WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test + VALUES (1, 'Bar') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +CTE: "aaa" +STMT: InsertStmt +STMT: SelectStmt +== 052 +-- correlated sub-select: +WITH aaa AS (SELECT 1 AS ctea, ' Foo' AS cteb) INSERT INTO upsert_test + VALUES (1, 'Bar'), (2, 'Baz') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT upsert_test.b||cteb, upsert_test.a FROM aaa) RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +CTE: "aaa" +STMT: InsertStmt +STMT: SelectStmt +== 053 +DROP TABLE upsert_test +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: DropStmt +== 054 +--------------------------- +-- UPDATE with row movement +--------------------------- + +-- When a partitioned table receives an UPDATE to the partitioned key and the +-- new values no longer meet the partition's bound, the row must be moved to +-- the correct partition for the new partition key (if one exists). We must +-- also ensure that updatable views on partitioned tables properly enforce any +-- WITH CHECK OPTION that is defined. The situation with triggers in this case +-- also requires thorough testing as partition key updates causing row +-- movement convert UPDATEs into DELETE+INSERT. + +CREATE TABLE range_parted ( + a text, + b bigint, + c numeric, + d int, + e varchar +) PARTITION BY RANGE (a, b) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +== 055 +-- Create partitions intentionally in descending bound order, so as to test +-- that update-row-movement works with the leaf partitions not in bound order. +CREATE TABLE part_b_20_b_30 (e varchar, c numeric, a text, b bigint, d int) +-- +TABLE: name="part_b_20_b_30" schema="" table="part_b_20_b_30" ctx=DDL +STMT: CreateStmt +== 056 +ALTER TABLE range_parted ATTACH PARTITION part_b_20_b_30 FOR VALUES FROM ('b', 20) TO ('b', 30) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 057 +CREATE TABLE part_b_10_b_20 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY RANGE (c) +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DDL +STMT: CreateStmt +== 058 +CREATE TABLE part_b_1_b_10 PARTITION OF range_parted FOR VALUES FROM ('b', 1) TO ('b', 10) +-- +TABLE: name="part_b_1_b_10" schema="" table="part_b_1_b_10" ctx=DDL +STMT: CreateStmt +== 059 +ALTER TABLE range_parted ATTACH PARTITION part_b_10_b_20 FOR VALUES FROM ('b', 10) TO ('b', 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 060 +CREATE TABLE part_a_10_a_20 PARTITION OF range_parted FOR VALUES FROM ('a', 10) TO ('a', 20) +-- +TABLE: name="part_a_10_a_20" schema="" table="part_a_10_a_20" ctx=DDL +STMT: CreateStmt +== 061 +CREATE TABLE part_a_1_a_10 PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('a', 10) +-- +TABLE: name="part_a_1_a_10" schema="" table="part_a_1_a_10" ctx=DDL +STMT: CreateStmt +== 062 +-- Check that partition-key UPDATE works sanely on a partitioned table that +-- does not have any child partitions. +UPDATE part_b_10_b_20 set b = b - 6 +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +== 063 +-- Create some more partitions following the above pattern of descending bound +-- order, but let's make the situation a bit more complex by having the +-- attribute numbers of the columns vary from their parent partition. +CREATE TABLE part_c_100_200 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY range (abs(d)) +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: CreateStmt +== 064 +ALTER TABLE part_c_100_200 DROP COLUMN e, DROP COLUMN c, DROP COLUMN a +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +== 065 +ALTER TABLE part_c_100_200 ADD COLUMN c numeric, ADD COLUMN e varchar, ADD COLUMN a text +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +== 066 +ALTER TABLE part_c_100_200 DROP COLUMN b +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +== 067 +ALTER TABLE part_c_100_200 ADD COLUMN b bigint +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +== 068 +CREATE TABLE part_d_1_15 PARTITION OF part_c_100_200 FOR VALUES FROM (1) TO (15) +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateStmt +== 069 +CREATE TABLE part_d_15_20 PARTITION OF part_c_100_200 FOR VALUES FROM (15) TO (20) +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateStmt +== 070 +ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_100_200 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DDL +STMT: AlterTableStmt +== 071 +CREATE TABLE part_c_1_100 (e varchar, d int, c numeric, b bigint, a text) +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateStmt +== 072 +ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_1_100 FOR VALUES FROM (1) TO (100) +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DDL +STMT: AlterTableStmt +== 073 +-- The order of subplans should be in bound order +EXPLAIN (costs off) UPDATE range_parted set c = c - 50 WHERE c > 97 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +== 074 +-- fail, row movement happens only within the partition subtree. +UPDATE part_c_100_200 set c = c - 20, d = c WHERE c = 105 +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DML +STMT: UpdateStmt +== 075 +-- fail, no partition key update, so no attempt to move tuple, +-- but "a = 'a'" violates partition constraint enforced by root partition) +UPDATE part_b_10_b_20 set a = 'a' +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +== 076 +-- ok, partition key update, no constraint violation +UPDATE range_parted set d = d - 10 WHERE d > 10 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 077 +-- ok, no partition key update, no constraint violation +UPDATE range_parted set e = d +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 078 +-- No row found +UPDATE part_c_1_100 set c = c + 20 WHERE c = 98 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DML +STMT: UpdateStmt +== 079 +-- ok, row movement +UPDATE part_b_10_b_20 set c = c + 20 returning c, b, a +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +== 080 +-- fail, row movement happens only within the partition subtree. +UPDATE part_b_10_b_20 set b = b - 6 WHERE c > 116 returning * +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +== 081 +-- ok, row movement, with subset of rows moved into different partition. +UPDATE range_parted set b = b - 6 WHERE c > 116 returning a, b + c +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 082 +-- Common table needed for multiple test scenarios. +CREATE TABLE mintab(c1 int) +-- +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: CreateStmt +== 083 +INSERT into mintab VALUES (120) +-- +TABLE: name="mintab" schema="" table="mintab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 084 +-- update partition key using updatable view. +CREATE VIEW upview AS SELECT * FROM range_parted WHERE (select c > c1 FROM mintab) WITH CHECK OPTION +-- +TABLE: name="upview" schema="" table="upview" ctx=DDL +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +TABLE: name="mintab" schema="" table="mintab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 085 +-- ok +UPDATE upview set c = 199 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +== 086 +-- fail, check option violation +UPDATE upview set c = 120 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +== 087 +-- fail, row movement with check option violation +UPDATE upview set a = 'b', b = 15, c = 120 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +== 088 +-- ok, row movement, check option passes +UPDATE upview set a = 'b', b = 15 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +== 089 +-- cleanup +DROP VIEW upview +-- +STMT: DropStmt +== 090 +UPDATE range_parted set c = 95 WHERE a = 'b' and b > 10 and c > 100 returning (range_parted), * +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 091 +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; +$$ +-- +FUNCTION: name="trans_updatetrigfunc" function="trans_updatetrigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 092 +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() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +== 093 +UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end ) WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 094 +-- 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() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +== 095 +CREATE TRIGGER trans_inserttrig + AFTER INSERT ON range_parted REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +== 096 +UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 097 +DROP TRIGGER trans_deletetrig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 098 +DROP TRIGGER trans_inserttrig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 099 +-- 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 +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 100 +CREATE TRIGGER trig_c1_100 BEFORE UPDATE OR INSERT ON part_c_1_100 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +== 101 +CREATE TRIGGER trig_d1_15 BEFORE UPDATE OR INSERT ON part_d_1_15 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +== 102 +CREATE TRIGGER trig_d15_20 BEFORE UPDATE OR INSERT ON part_d_15_20 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +== 103 +UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end) WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 104 +UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 105 +UPDATE range_parted set b = 15 WHERE b = 1 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 106 +DROP TRIGGER trans_updatetrig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 107 +DROP TRIGGER trig_c1_100 ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +== 108 +DROP TRIGGER trig_d1_15 ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +== 109 +DROP TRIGGER trig_d15_20 ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +== 110 +DROP FUNCTION func_parted_mod_b() +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: DropStmt +== 111 +-- RLS policies with update-row-movement +----------------------------------------- + +ALTER TABLE range_parted ENABLE ROW LEVEL SECURITY +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +== 112 +CREATE USER regress_range_parted_user +-- +STMT: CreateRoleStmt +== 113 +GRANT ALL ON range_parted, mintab TO regress_range_parted_user +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: GrantStmt +== 114 +CREATE POLICY seeall ON range_parted AS PERMISSIVE FOR SELECT USING (true) +-- +STMT: CreatePolicyStmt +== 115 +CREATE POLICY policy_range_parted ON range_parted for UPDATE USING (true) WITH CHECK (c % 2 = 0) +-- +STMT: CreatePolicyStmt +== 116 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +== 117 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 118 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 119 +-- 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 +-- +FUNCTION: name="func_d_1_15" function="func_d_1_15" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 120 +CREATE TRIGGER trig_d_1_15 BEFORE INSERT ON part_d_1_15 + FOR EACH ROW EXECUTE PROCEDURE func_d_1_15() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +== 121 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +== 122 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 123 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 124 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +== 125 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 126 +-- Cleanup +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 127 +DROP TRIGGER trig_d_1_15 ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +== 128 +DROP FUNCTION func_d_1_15() +-- +FUNCTION: name="func_d_1_15" function="func_d_1_15" schema="" ctx=DDL +STMT: DropStmt +== 129 +-- Policy expression contains SubPlan +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 130 +CREATE POLICY policy_range_parted_subplan on range_parted + AS RESTRICTIVE for UPDATE USING (true) + WITH CHECK ((SELECT range_parted.c <= c1 FROM mintab)) +-- +STMT: CreatePolicyStmt +== 131 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +== 132 +-- fail, mintab has row with c1 = 120 +UPDATE range_parted set a = 'b', c = 122 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 133 +-- ok +UPDATE range_parted set a = 'b', c = 120 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 134 +-- RLS policy expression contains whole row. + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 135 +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) +-- +STMT: CreatePolicyStmt +== 136 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +== 137 +-- ok, should pass the RLS check +UPDATE range_parted set a = 'b', c = 112 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 138 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 139 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +== 140 +-- fail, the whole row RLS check should fail +UPDATE range_parted set a = 'b', c = 116 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 141 +-- Cleanup +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +== 142 +DROP POLICY policy_range_parted ON range_parted +-- +STMT: DropStmt +== 143 +DROP POLICY policy_range_parted_subplan ON range_parted +-- +STMT: DropStmt +== 144 +DROP POLICY policy_range_parted_wholerow ON range_parted +-- +STMT: DropStmt +== 145 +REVOKE ALL ON range_parted, mintab FROM regress_range_parted_user +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: GrantStmt +== 146 +DROP USER regress_range_parted_user +-- +STMT: DropRoleStmt +== 147 +DROP TABLE mintab +-- +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: DropStmt +== 148 +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; +$$ +-- +FUNCTION: name="trigfunc" function="trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 149 +-- Triggers on root partition +CREATE TRIGGER parent_delete_trig + AFTER DELETE ON range_parted for each statement execute procedure trigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +== 150 +CREATE TRIGGER parent_update_trig + AFTER UPDATE ON range_parted for each statement execute procedure trigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +== 151 +CREATE TRIGGER parent_insert_trig + AFTER INSERT ON range_parted for each statement execute procedure trigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +== 152 +-- 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() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +== 153 +CREATE TRIGGER c1_update_trig + AFTER UPDATE ON part_c_1_100 for each statement execute procedure trigfunc() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +== 154 +CREATE TRIGGER c1_insert_trig + AFTER INSERT ON part_c_1_100 for each statement execute procedure trigfunc() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +== 155 +-- 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() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +== 156 +CREATE TRIGGER d1_update_trig + AFTER UPDATE ON part_d_1_15 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +== 157 +CREATE TRIGGER d1_insert_trig + AFTER INSERT ON part_d_1_15 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +== 158 +-- 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() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +== 159 +CREATE TRIGGER d15_update_trig + AFTER UPDATE ON part_d_15_20 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +== 160 +CREATE TRIGGER d15_insert_trig + AFTER INSERT ON part_d_15_20 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +== 161 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 162 +DROP TRIGGER parent_delete_trig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 163 +DROP TRIGGER parent_update_trig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 164 +DROP TRIGGER parent_insert_trig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 165 +DROP TRIGGER c1_delete_trig ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +== 166 +DROP TRIGGER c1_update_trig ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +== 167 +DROP TRIGGER c1_insert_trig ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +== 168 +DROP TRIGGER d1_delete_trig ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +== 169 +DROP TRIGGER d1_update_trig ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +== 170 +DROP TRIGGER d1_insert_trig ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +== 171 +DROP TRIGGER d15_delete_trig ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +== 172 +DROP TRIGGER d15_update_trig ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +== 173 +DROP TRIGGER d15_insert_trig ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +== 174 +create table part_def partition of range_parted default +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DDL +STMT: CreateStmt +== 175 +insert into range_parted values ('c', 9) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 176 +-- ok +update part_def set a = 'd' where a = 'c' +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: UpdateStmt +== 177 +-- fail +update part_def set a = 'a' where a = 'd' +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: UpdateStmt +== 178 +-- 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' +-- +TABLE: name="part_a_10_a_20" schema="" table="part_a_10_a_20" ctx=DML +STMT: UpdateStmt +== 179 +-- ok +UPDATE range_parted set a = 'ad' WHERE a = 'a' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 180 +UPDATE range_parted set a = 'bd' WHERE a = 'b' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 181 +-- Update row movement from default to non-default partitions. +-- ok +UPDATE range_parted set a = 'a' WHERE a = 'ad' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 182 +UPDATE range_parted set a = 'b' WHERE a = 'bd' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +== 183 +-- Cleanup: range_parted no longer needed. +DROP TABLE range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +== 184 +CREATE TABLE list_parted ( + a text, + b int +) PARTITION BY list (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +== 185 +CREATE TABLE list_part1 PARTITION OF list_parted for VALUES in ('a', 'b') +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DDL +STMT: CreateStmt +== 186 +CREATE TABLE list_default PARTITION OF list_parted default +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DDL +STMT: CreateStmt +== 187 +INSERT into list_part1 VALUES ('a', 1) +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 188 +INSERT into list_default VALUES ('d', 10) +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 189 +-- fail +UPDATE list_default set a = 'a' WHERE a = 'd' +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DML +STMT: UpdateStmt +== 190 +-- ok +UPDATE list_default set a = 'x' WHERE a = 'd' +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DML +STMT: UpdateStmt +== 191 +DROP TABLE list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +== 192 +-- 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) +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: CreateStmt +== 193 +create table utr1 (a int check (a in (1)), q text, b text) +-- +TABLE: name="utr1" schema="" table="utr1" ctx=DDL +STMT: CreateStmt +== 194 +create table utr2 (a int check (a in (2)), b text) +-- +TABLE: name="utr2" schema="" table="utr2" ctx=DDL +STMT: CreateStmt +== 195 +alter table utr1 drop column q +-- +TABLE: name="utr1" schema="" table="utr1" ctx=DDL +STMT: AlterTableStmt +== 196 +alter table utrtest attach partition utr1 for values in (1) +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: AlterTableStmt +== 197 +alter table utrtest attach partition utr2 for values in (2) +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: AlterTableStmt +== 198 +insert into utrtest values (1, 'foo') + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 199 +insert into utrtest values (2, 'bar') + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 200 +-- fails +insert into utrtest values (2, 'bar') + returning *, tableoid::regclass +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 201 +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 +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: UpdateStmt +STMT: SelectStmt +== 202 +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 +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: UpdateStmt +STMT: SelectStmt +== 203 +-- fails + +update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x + returning *, tableoid::regclass +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +== 204 +delete from utrtest + returning *, tableoid::regclass, xmax = pg_current_xact_id()::xid as xmax_ok +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: DeleteStmt +== 205 +drop table utrtest +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: DropStmt +== 206 +-------------- +-- 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) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +== 207 +CREATE TABLE sub_parted PARTITION OF list_parted for VALUES in (1) PARTITION BY list (b) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DDL +STMT: CreateStmt +== 208 +CREATE TABLE sub_part1(b int, c int8, a numeric) +-- +TABLE: name="sub_part1" schema="" table="sub_part1" ctx=DDL +STMT: CreateStmt +== 209 +ALTER TABLE sub_parted ATTACH PARTITION sub_part1 for VALUES in (1) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DDL +STMT: AlterTableStmt +== 210 +CREATE TABLE sub_part2(b int, c int8, a numeric) +-- +TABLE: name="sub_part2" schema="" table="sub_part2" ctx=DDL +STMT: CreateStmt +== 211 +ALTER TABLE sub_parted ATTACH PARTITION sub_part2 for VALUES in (2) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DDL +STMT: AlterTableStmt +== 212 +CREATE TABLE list_part1(a numeric, b int, c int8) +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DDL +STMT: CreateStmt +== 213 +ALTER TABLE list_parted ATTACH PARTITION list_part1 for VALUES in (2,3) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +== 214 +INSERT into list_parted VALUES (2,5,50) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 215 +INSERT into list_parted VALUES (3,6,60) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +INSERT into sub_parted VALUES (1,1,60) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 217 +INSERT into sub_parted VALUES (1,2,10) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 218 +-- 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 +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DML +STMT: UpdateStmt +== 219 +-- 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 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 220 +UPDATE list_parted set b = c + a WHERE a = 2 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +== 221 +SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +== 222 +-- 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 +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 223 +CREATE TRIGGER parted_mod_b before update on sub_part1 + for each row execute procedure func_parted_mod_b() +-- +TABLE: name="sub_part1" schema="" table="sub_part1" ctx=DDL +STMT: CreateTrigStmt +== 224 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 225 +-- 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 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +== 226 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 227 +DROP TRIGGER parted_mod_b ON sub_part1 +-- +TABLE: name="sub_part1" schema="" table="sub_part1" ctx=DDL +STMT: DropStmt +== 228 +-- 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 +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 229 +CREATE TRIGGER trig_skip_delete before delete on sub_part2 + for each row execute procedure func_parted_mod_b() +-- +TABLE: name="sub_part2" schema="" table="sub_part2" ctx=DDL +STMT: CreateTrigStmt +== 230 +UPDATE list_parted set b = 1 WHERE c = 70 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +== 231 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 232 +-- Drop the trigger. Now the row should be moved. +DROP TRIGGER trig_skip_delete ON sub_part2 +-- +TABLE: name="sub_part2" schema="" table="sub_part2" ctx=DDL +STMT: DropStmt +== 233 +UPDATE list_parted set b = 1 WHERE c = 70 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +== 234 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 235 +DROP FUNCTION func_parted_mod_b() +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: DropStmt +== 236 +-- 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) +-- +TABLE: name="non_parted" schema="" table="non_parted" ctx=DDL +STMT: CreateStmt +== 237 +INSERT into non_parted VALUES (1), (1), (1), (2), (2), (2), (3), (3), (3) +-- +TABLE: name="non_parted" schema="" table="non_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 238 +UPDATE list_parted t1 set a = 2 FROM non_parted t2 WHERE t1.a = t2.id and a = 1 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +TABLE: name="non_parted" schema="" table="non_parted" ctx=Select +ALIAS: "t1"="list_parted" +ALIAS: "t2"="non_parted" +STMT: UpdateStmt +== 239 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +== 240 +DROP TABLE non_parted +-- +TABLE: name="non_parted" schema="" table="non_parted" ctx=DDL +STMT: DropStmt +== 241 +-- Cleanup: list_parted no longer needed. +DROP TABLE list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +== 242 +-- 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 +-- +FUNCTION: name="dummy_hashint4" function="dummy_hashint4" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 243 +create operator class custom_opclass for type int4 using hash as +operator 1 = , function 2 dummy_hashint4(int4, int8) +-- +STMT: CreateOpClassStmt +== 244 +create table hash_parted ( + a int, + b int +) partition by hash (a custom_opclass, b custom_opclass) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +== 245 +create table hpart1 partition of hash_parted for values with (modulus 2, remainder 1) +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DDL +STMT: CreateStmt +== 246 +create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2) +-- +TABLE: name="hpart2" schema="" table="hpart2" ctx=DDL +STMT: CreateStmt +== 247 +create table hpart3 partition of hash_parted for values with (modulus 8, remainder 0) +-- +TABLE: name="hpart3" schema="" table="hpart3" ctx=DDL +STMT: CreateStmt +== 248 +create table hpart4 partition of hash_parted for values with (modulus 8, remainder 4) +-- +TABLE: name="hpart4" schema="" table="hpart4" ctx=DDL +STMT: CreateStmt +== 249 +insert into hpart1 values (1, 1) +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 250 +insert into hpart2 values (2, 5) +-- +TABLE: name="hpart2" schema="" table="hpart2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 251 +insert into hpart4 values (3, 4) +-- +TABLE: name="hpart4" schema="" table="hpart4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 252 +-- fail +update hpart1 set a = 3, b=4 where a = 1 +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DML +STMT: UpdateStmt +== 253 +-- ok, row movement +update hash_parted set b = b - 1 where b = 1 +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DML +STMT: UpdateStmt +== 254 +-- ok +update hash_parted set b = b + 8 where b = 1 +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DML +STMT: UpdateStmt +== 255 +-- cleanup +drop table hash_parted +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: DropStmt +== 256 +drop operator class custom_opclass using hash +-- +STMT: DropStmt +== 257 +drop function dummy_hashint4(a int4, seed int8) +-- +FUNCTION: name="dummy_hashint4" function="dummy_hashint4" schema="" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/uuid.metadata.json b/parser/testdata/summary/postgres_regress/uuid.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/uuid.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary/postgres_regress/uuid.test b/parser/testdata/summary/postgres_regress/uuid.test new file mode 100644 index 0000000..e3e5ded --- /dev/null +++ b/parser/testdata/summary/postgres_regress/uuid.test @@ -0,0 +1,312 @@ +== 001 +-- regression test for the uuid datatype +-- creating test tables +CREATE TABLE guid1 +( + guid_field UUID, + text_field TEXT DEFAULT(now()) +) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: CreateStmt +== 002 +CREATE TABLE guid2 +( + guid_field UUID, + text_field TEXT DEFAULT(now()) +) +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DDL +STMT: CreateStmt +== 003 +-- inserting invalid data tests +-- too long +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111F') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +-- too short +INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-1111-11111111111}') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +-- valid data but invalid format +INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222 ') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- invalid data +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +-- test non-error-throwing API +SELECT pg_input_is_valid('11', 'uuid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT * FROM pg_input_error_info('11', 'uuid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 011 +--inserting three input formats +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 014 +-- retrieving the inserted data +SELECT guid_field FROM guid1 +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +STMT: SelectStmt +== 015 +-- ordering test +SELECT guid_field FROM guid1 ORDER BY guid_field ASC +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +STMT: SelectStmt +== 016 +SELECT guid_field FROM guid1 ORDER BY guid_field DESC +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +STMT: SelectStmt +== 017 +-- = operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +== 018 +-- <> operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +== 019 +-- < operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field < '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +== 020 +-- <= operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field <= '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +== 021 +-- > operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field > '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +== 022 +-- >= operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field >= '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +== 023 +-- btree and hash index creation test +CREATE INDEX guid1_btree ON guid1 USING BTREE (guid_field) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: IndexStmt +== 024 +CREATE INDEX guid1_hash ON guid1 USING HASH (guid_field) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: IndexStmt +== 025 +-- unique index test +CREATE UNIQUE INDEX guid1_unique_BTREE ON guid1 USING BTREE (guid_field) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: IndexStmt +== 026 +-- should fail +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +-- check to see whether the new indexes are actually there +SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 028 +-- populating the test tables with additional records +INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111') +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}') +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e') +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +-- join test +SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +TABLE: name="guid2" schema="" table="guid2" ctx=Select +ALIAS: "g1"="guid1" +ALIAS: "g2"="guid2" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE g2.guid_field IS NULL +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +TABLE: name="guid2" schema="" table="guid2" ctx=Select +ALIAS: "g1"="guid1" +ALIAS: "g2"="guid2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="g2" column="guid_field" +STMT: SelectStmt +== 034 +-- generation test +TRUNCATE guid1 +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: TruncateStmt +== 035 +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 036 +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 037 +SELECT count(DISTINCT guid_field) FROM guid1 +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 038 +-- extract functions + +-- version +SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111') +-- +FUNCTION: name="uuid_extract_version" function="uuid_extract_version" schema="" ctx=Call +STMT: SelectStmt +== 039 +-- 5 +SELECT uuid_extract_version(gen_random_uuid()) +-- +FUNCTION: name="uuid_extract_version" function="uuid_extract_version" schema="" ctx=Call +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: SelectStmt +== 040 +-- 4 +SELECT uuid_extract_version('11111111-1111-1111-1111-111111111111') +-- +FUNCTION: name="uuid_extract_version" function="uuid_extract_version" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- null + +-- timestamp +SELECT uuid_extract_timestamp('C232AB00-9414-11EC-B3C8-9F6BDECED846') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00' +-- +FUNCTION: name="uuid_extract_timestamp" function="uuid_extract_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- RFC 4122bis test vector +SELECT uuid_extract_timestamp(gen_random_uuid()) +-- +FUNCTION: name="uuid_extract_timestamp" function="uuid_extract_timestamp" schema="" ctx=Call +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: SelectStmt +== 043 +-- null +SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111') +-- +FUNCTION: name="uuid_extract_timestamp" function="uuid_extract_timestamp" schema="" ctx=Call +STMT: SelectStmt +== 044 +-- null + + +-- clean up +DROP TABLE guid1, guid2 CASCADE +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +TABLE: name="guid2" schema="" table="guid2" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/vacuum.metadata.json b/parser/testdata/summary/postgres_regress/vacuum.metadata.json new file mode 100644 index 0000000..11c34e0 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/vacuum.metadata.json @@ -0,0 +1,300 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296" + ] +} diff --git a/parser/testdata/summary/postgres_regress/vacuum.test b/parser/testdata/summary/postgres_regress/vacuum.test new file mode 100644 index 0000000..06486cf --- /dev/null +++ b/parser/testdata/summary/postgres_regress/vacuum.test @@ -0,0 +1,1674 @@ +== 001 +|-- +-- VACUUM +|-- + +CREATE TABLE vactst (i INT) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO vactst VALUES (1) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 007 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 008 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 010 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 011 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 012 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 013 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 014 +INSERT INTO vactst VALUES (0) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 015 +SELECT count(*) FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 016 +DELETE FROM vactst WHERE i != 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +== 017 +SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: SelectStmt +== 018 +VACUUM FULL vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 019 +UPDATE vactst SET i = i + 1 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: UpdateStmt +== 020 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 027 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 028 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 029 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 030 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +== 031 +INSERT INTO vactst VALUES (0) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 032 +SELECT count(*) FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 033 +DELETE FROM vactst WHERE i != 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +== 034 +VACUUM (FULL) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 035 +DELETE FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +== 036 +SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: SelectStmt +== 037 +VACUUM (FULL, FREEZE) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 038 +VACUUM (ANALYZE, FULL) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 039 +CREATE TABLE vaccluster (i INT PRIMARY KEY) +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: CreateStmt +== 040 +ALTER TABLE vaccluster CLUSTER ON vaccluster_pkey +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: AlterTableStmt +== 041 +CLUSTER vaccluster +-- +STMT: ClusterStmt +== 042 +CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL + AS 'ANALYZE pg_am' +-- +FUNCTION: name="do_analyze" function="do_analyze" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 043 +CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL + AS 'SELECT $1 FROM public.do_analyze()' +-- +FUNCTION: name="wrap_do_analyze" function="wrap_do_analyze" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 044 +CREATE INDEX ON vaccluster(wrap_do_analyze(i)) +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +FUNCTION: name="wrap_do_analyze" function="wrap_do_analyze" schema="" ctx=Call +STMT: IndexStmt +== 045 +INSERT INTO vaccluster VALUES (1), (2) +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 046 +ANALYZE vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +== 047 +-- Test ANALYZE in transaction, where the transaction surrounding +-- analyze performed modifications. This tests for the bug at +-- https://postgr.es/m/c7988239-d42c-ddc4-41db-171b23b35e4f%40ssinger.info +-- (which hopefully is unlikely to be reintroduced), but also seems +-- independently worthwhile to cover. +INSERT INTO vactst SELECT generate_series(1, 300) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 048 +DELETE FROM vactst WHERE i % 7 = 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +== 049 +-- delete a few rows outside +BEGIN +-- +STMT: TransactionStmt +== 050 +INSERT INTO vactst SELECT generate_series(301, 400) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 051 +DELETE FROM vactst WHERE i % 5 <> 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +== 052 +-- delete a few rows inside +ANALYZE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 053 +COMMIT +-- +STMT: TransactionStmt +== 054 +-- Test ANALYZE setting relhassubclass=f for non-partitioning inheritance +BEGIN +-- +STMT: TransactionStmt +== 055 +CREATE TABLE past_inh_parent () +-- +TABLE: name="past_inh_parent" schema="" table="past_inh_parent" ctx=DDL +STMT: CreateStmt +== 056 +CREATE TABLE past_inh_child () INHERITS (past_inh_parent) +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DDL +STMT: CreateStmt +== 057 +INSERT INTO past_inh_child DEFAULT VALUES +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DML +STMT: InsertStmt +== 058 +INSERT INTO past_inh_child DEFAULT VALUES +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DML +STMT: InsertStmt +== 059 +ANALYZE past_inh_parent +-- +TABLE: name="past_inh_parent" schema="" table="past_inh_parent" ctx=DDL +STMT: VacuumStmt +== 060 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 061 +DROP TABLE past_inh_child +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DDL +STMT: DropStmt +== 062 +ANALYZE past_inh_parent +-- +TABLE: name="past_inh_parent" schema="" table="past_inh_parent" ctx=DDL +STMT: VacuumStmt +== 063 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 064 +COMMIT +-- +STMT: TransactionStmt +== 065 +-- Test ANALYZE setting relhassubclass=f for partitioning +BEGIN +-- +STMT: TransactionStmt +== 066 +CREATE TABLE past_parted (i int) PARTITION BY LIST(i) +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DDL +STMT: CreateStmt +== 067 +CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1) +-- +TABLE: name="past_part" schema="" table="past_part" ctx=DDL +STMT: CreateStmt +== 068 +INSERT INTO past_parted VALUES (1),(1) +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 069 +ANALYZE past_parted +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DDL +STMT: VacuumStmt +== 070 +DROP TABLE past_part +-- +TABLE: name="past_part" schema="" table="past_part" ctx=DDL +STMT: DropStmt +== 071 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_parted'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 072 +ANALYZE past_parted +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DDL +STMT: VacuumStmt +== 073 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_parted'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 074 +COMMIT +-- +STMT: TransactionStmt +== 075 +VACUUM FULL pg_am +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=DDL +STMT: VacuumStmt +== 076 +VACUUM FULL pg_class +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: VacuumStmt +== 077 +VACUUM FULL pg_database +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=DDL +STMT: VacuumStmt +== 078 +VACUUM FULL vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +== 079 +VACUUM FULL vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 080 +VACUUM (DISABLE_PAGE_SKIPPING) vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +== 081 +-- PARALLEL option +CREATE TABLE pvactst (i INT, a INT[], p POINT) with (autovacuum_enabled = off) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: CreateStmt +== 082 +INSERT INTO pvactst SELECT i, array[1,2,3], point(i, i+1) FROM generate_series(1,1000) i +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 083 +CREATE INDEX btree_pvactst ON pvactst USING btree (i) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +== 084 +CREATE INDEX hash_pvactst ON pvactst USING hash (i) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +== 085 +CREATE INDEX brin_pvactst ON pvactst USING brin (i) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +== 086 +CREATE INDEX gin_pvactst ON pvactst USING gin (a) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +== 087 +CREATE INDEX gist_pvactst ON pvactst USING gist (p) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +== 088 +CREATE INDEX spgist_pvactst ON pvactst USING spgist (p) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +== 089 +CREATE TABLE pvactst2 (i INT) WITH (autovacuum_enabled = off) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: CreateStmt +== 090 +INSERT INTO pvactst2 SELECT generate_series(1, 1000) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 091 +CREATE INDEX ON pvactst2 (i) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: IndexStmt +== 092 +CREATE INDEX ON pvactst2 (i) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: IndexStmt +== 093 +-- VACUUM invokes parallel index cleanup +SET min_parallel_index_scan_size to 0 +-- +STMT: VariableSetStmt +== 094 +VACUUM (PARALLEL 2) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +== 095 +-- VACUUM invokes parallel bulk-deletion +UPDATE pvactst SET i = i WHERE i < 1000 +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DML +STMT: UpdateStmt +== 096 +VACUUM (PARALLEL 2) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +== 097 +UPDATE pvactst SET i = i WHERE i < 1000 +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DML +STMT: UpdateStmt +== 098 +VACUUM (PARALLEL 0) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +== 099 +-- disable parallel vacuum + +VACUUM (PARALLEL -1) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +== 100 +-- error +VACUUM (PARALLEL 2, INDEX_CLEANUP FALSE) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +== 101 +VACUUM (PARALLEL 2, FULL TRUE) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +== 102 +-- error, cannot use both PARALLEL and FULL +VACUUM (PARALLEL) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +== 103 +-- error, cannot use PARALLEL option without parallel degree + +-- Test parallel vacuum using the minimum maintenance_work_mem with and without +-- dead tuples. +SET maintenance_work_mem TO 64 +-- +STMT: VariableSetStmt +== 104 +VACUUM (PARALLEL 2) pvactst2 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: VacuumStmt +== 105 +DELETE FROM pvactst2 WHERE i < 1000 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DML +STMT: DeleteStmt +== 106 +VACUUM (PARALLEL 2) pvactst2 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: VacuumStmt +== 107 +RESET maintenance_work_mem +-- +STMT: VariableSetStmt +== 108 +-- Test different combinations of parallel and full options for temporary tables +CREATE TEMPORARY TABLE tmp (a int PRIMARY KEY) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: CreateStmt +== 109 +CREATE INDEX tmp_idx1 ON tmp (a) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: IndexStmt +== 110 +VACUUM (PARALLEL 1, FULL FALSE) tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: VacuumStmt +== 111 +-- parallel vacuum disabled for temp tables +VACUUM (PARALLEL 0, FULL TRUE) tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: VacuumStmt +== 112 +-- can specify parallel disabled (even though that's implied by FULL) +RESET min_parallel_index_scan_size +-- +STMT: VariableSetStmt +== 113 +DROP TABLE pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: DropStmt +== 114 +DROP TABLE pvactst2 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: DropStmt +== 115 +-- INDEX_CLEANUP option +CREATE TABLE no_index_cleanup (i INT PRIMARY KEY, t TEXT) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: CreateStmt +== 116 +-- Use uncompressed data stored in toast. +CREATE INDEX no_index_cleanup_idx ON no_index_cleanup(t) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: IndexStmt +== 117 +ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE EXTERNAL +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +== 118 +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(1,30), + repeat('1234567890',269)) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 119 +-- index cleanup option is ignored if VACUUM FULL +VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +== 120 +VACUUM (FULL TRUE) no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +== 121 +-- Toast inherits the value from its parent table. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +== 122 +DELETE FROM no_index_cleanup WHERE i < 15 +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +STMT: DeleteStmt +== 123 +-- Nothing is cleaned up. +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +== 124 +-- Both parent relation and toast are cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +== 125 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +== 126 +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = auto) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +== 127 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +== 128 +-- Parameter is set for both the parent table and its toast relation. +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), + repeat('1234567890',269)) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 129 +DELETE FROM no_index_cleanup WHERE i < 45 +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +STMT: DeleteStmt +== 130 +-- Only toast index is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, + toast.vacuum_index_cleanup = yes) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +== 131 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +== 132 +-- Only parent is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, + toast.vacuum_index_cleanup = false) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +== 133 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +== 134 +-- Test some extra relations. +VACUUM (INDEX_CLEANUP FALSE) vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +== 135 +VACUUM (INDEX_CLEANUP AUTO) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 136 +-- index cleanup option is ignored if no indexes +VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +== 137 +-- TRUNCATE option +CREATE TEMP TABLE vac_truncate_test(i INT NOT NULL, j text) + WITH (vacuum_truncate=true, autovacuum_enabled=false) +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: CreateStmt +== 138 +INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL) +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 139 +VACUUM (TRUNCATE FALSE, DISABLE_PAGE_SKIPPING) vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: VacuumStmt +== 140 +SELECT pg_relation_size('vac_truncate_test') > 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +== 141 +VACUUM (DISABLE_PAGE_SKIPPING) vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: VacuumStmt +== 142 +SELECT pg_relation_size('vac_truncate_test') = 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +== 143 +VACUUM (TRUNCATE FALSE, FULL TRUE) vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: VacuumStmt +== 144 +DROP TABLE vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: DropStmt +== 145 +-- partitioned table +CREATE TABLE vacparted (a int, b char) PARTITION BY LIST (a) +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: CreateStmt +== 146 +CREATE TABLE vacparted1 PARTITION OF vacparted FOR VALUES IN (1) +-- +TABLE: name="vacparted1" schema="" table="vacparted1" ctx=DDL +STMT: CreateStmt +== 147 +INSERT INTO vacparted VALUES (1, 'a') +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 148 +UPDATE vacparted SET b = 'b' +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DML +STMT: UpdateStmt +== 149 +VACUUM (ANALYZE) vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 150 +VACUUM (FULL) vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 151 +VACUUM (FREEZE) vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 152 +-- check behavior with duplicate column mentions +VACUUM ANALYZE vacparted(a,b,a) +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 153 +ANALYZE vacparted(a,b,b) +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 154 +-- partitioned table with index +CREATE TABLE vacparted_i (a int primary key, b varchar(100)) + PARTITION BY HASH (a) +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: CreateStmt +== 155 +CREATE TABLE vacparted_i1 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="vacparted_i1" schema="" table="vacparted_i1" ctx=DDL +STMT: CreateStmt +== 156 +CREATE TABLE vacparted_i2 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="vacparted_i2" schema="" table="vacparted_i2" ctx=DDL +STMT: CreateStmt +== 157 +INSERT INTO vacparted_i SELECT i, 'test_'|| i from generate_series(1,10) i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 158 +VACUUM (ANALYZE) vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: VacuumStmt +== 159 +VACUUM (FULL) vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: VacuumStmt +== 160 +VACUUM (FREEZE) vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: VacuumStmt +== 161 +SELECT relname, relhasindex FROM pg_class + WHERE relname LIKE 'vacparted_i%' AND relkind IN ('p','r') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relkind" +STMT: SelectStmt +== 162 +DROP TABLE vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: DropStmt +== 163 +-- multiple tables specified +VACUUM vaccluster, vactst +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 164 +VACUUM vacparted, does_not_exist +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +== 165 +VACUUM (FREEZE) vacparted, vaccluster, vactst +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 166 +VACUUM (FREEZE) does_not_exist, vaccluster +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +== 167 +VACUUM ANALYZE vactst, vacparted (a) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 168 +VACUUM ANALYZE vactst (does_not_exist), vacparted (b) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 169 +VACUUM FULL vacparted, vactst +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 170 +VACUUM FULL vactst, vacparted (a, b), vaccluster (i) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +== 171 +ANALYZE vactst, vacparted +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 172 +ANALYZE vacparted (b), vactst +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 173 +ANALYZE vactst, does_not_exist, vacparted +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 174 +ANALYZE vactst (i), vacparted (does_not_exist) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +== 175 +ANALYZE vactst, vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 176 +BEGIN +-- +STMT: TransactionStmt +== 177 +-- ANALYZE behaves differently inside a transaction block +ANALYZE vactst, vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 178 +COMMIT +-- +STMT: TransactionStmt +== 179 +-- parenthesized syntax for ANALYZE +ANALYZE (VERBOSE) does_not_exist +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +== 180 +ANALYZE (nonexistent-arg) does_not_exist +-- +ERROR: syntax error at or near "arg" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 181 +ANALYZE (nonexistentarg) does_not_exit +-- +TABLE: name="does_not_exit" schema="" table="does_not_exit" ctx=DDL +STMT: VacuumStmt +== 182 +-- ensure argument order independence, and that SKIP_LOCKED on non-existing +-- relation still errors out. Suppress WARNING messages caused by concurrent +-- autovacuums. +SET client_min_messages TO 'ERROR' +-- +STMT: VariableSetStmt +== 183 +ANALYZE (SKIP_LOCKED, VERBOSE) does_not_exist +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +== 184 +ANALYZE (VERBOSE, SKIP_LOCKED) does_not_exist +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +== 185 +-- SKIP_LOCKED option +VACUUM (SKIP_LOCKED) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 186 +VACUUM (SKIP_LOCKED, FULL) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 187 +ANALYZE (SKIP_LOCKED) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 188 +RESET client_min_messages +-- +STMT: VariableSetStmt +== 189 +-- ensure VACUUM and ANALYZE don't have a problem with serializable +SET default_transaction_isolation = serializable +-- +STMT: VariableSetStmt +== 190 +VACUUM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 191 +ANALYZE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 192 +RESET default_transaction_isolation +-- +STMT: VariableSetStmt +== 193 +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +== 194 +ANALYZE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 195 +COMMIT +-- +STMT: TransactionStmt +== 196 +-- PROCESS_TOAST option +CREATE TABLE vac_option_tab (a INT, t TEXT) +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: CreateStmt +== 197 +INSERT INTO vac_option_tab SELECT a, 't' || a FROM generate_series(1, 10) AS a +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 198 +ALTER TABLE vac_option_tab ALTER COLUMN t SET STORAGE EXTERNAL +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: AlterTableStmt +== 199 +-- Check the number of vacuums done on table vac_option_tab and on its +-- toast relation, to check that PROCESS_TOAST and PROCESS_MAIN work on +-- what they should. +CREATE VIEW vac_option_tab_counts AS + SELECT CASE WHEN c.relname IS NULL + THEN 'main' ELSE 'toast' END as rel, + s.vacuum_count + FROM pg_stat_all_tables s + LEFT JOIN pg_class c ON s.relid = c.reltoastrelid + WHERE c.relname = 'vac_option_tab' OR s.relname = 'vac_option_tab' + ORDER BY rel +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=DDL +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_stat_all_tables" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="s" column="relname" +STMT: ViewStmt +STMT: SelectStmt +== 200 +VACUUM (PROCESS_TOAST TRUE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 201 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +== 202 +VACUUM (PROCESS_TOAST FALSE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 203 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +== 204 +VACUUM (PROCESS_TOAST FALSE, FULL) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 205 +-- error + +-- PROCESS_MAIN option +-- Only the toast table is processed. +VACUUM (PROCESS_MAIN FALSE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 206 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +== 207 +-- Nothing is processed. +VACUUM (PROCESS_MAIN FALSE, PROCESS_TOAST FALSE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 208 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +== 209 +-- Check if the filenodes nodes have been updated as wanted after FULL. +SELECT relfilenode AS main_filenode FROM pg_class + WHERE relname = 'vac_option_tab' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +== 210 +SELECT t.relfilenode AS toast_filenode FROM pg_class c, pg_class t + WHERE c.reltoastrelid = t.oid AND c.relname = 'vac_option_tab' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="c" column="reltoastrelid" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +== 211 +-- Only the toast relation is processed. +VACUUM (PROCESS_MAIN FALSE, FULL) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 212 +SELECT relfilenode = :main_filenode AS is_same_main_filenode + FROM pg_class WHERE relname = 'vac_option_tab' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 213 +SELECT t.relfilenode = :toast_filenode AS is_same_toast_filenode + FROM pg_class c, pg_class t + WHERE c.reltoastrelid = t.oid AND c.relname = 'vac_option_tab' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 214 +-- BUFFER_USAGE_LIMIT option +VACUUM (BUFFER_USAGE_LIMIT '512 kB') vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 215 +ANALYZE (BUFFER_USAGE_LIMIT '512 kB') vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 216 +-- try disabling the buffer usage limit +VACUUM (BUFFER_USAGE_LIMIT 0) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 217 +ANALYZE (BUFFER_USAGE_LIMIT 0) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 218 +-- value exceeds max size error +VACUUM (BUFFER_USAGE_LIMIT 16777220) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 219 +-- value is less than min size error +VACUUM (BUFFER_USAGE_LIMIT 120) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 220 +-- integer overflow error +VACUUM (BUFFER_USAGE_LIMIT 10000000000) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 221 +-- incompatible with VACUUM FULL error +VACUUM (BUFFER_USAGE_LIMIT '512 kB', FULL) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +== 222 +-- SKIP_DATABASE_STATS option +VACUUM (SKIP_DATABASE_STATS) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 223 +-- ONLY_DATABASE_STATS option +VACUUM (ONLY_DATABASE_STATS) +-- +STMT: VacuumStmt +== 224 +VACUUM (ONLY_DATABASE_STATS) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +== 225 +-- error + +DROP VIEW vac_option_tab_counts +-- +STMT: DropStmt +== 226 +DROP TABLE vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: DropStmt +== 227 +DROP TABLE vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: DropStmt +== 228 +DROP TABLE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: DropStmt +== 229 +DROP TABLE vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: DropStmt +== 230 +DROP TABLE no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: DropStmt +== 231 +-- relation ownership, WARNING logs generated as all are skipped. +CREATE TABLE vacowned (a int) +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: CreateStmt +== 232 +CREATE TABLE vacowned_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: CreateStmt +== 233 +CREATE TABLE vacowned_part1 PARTITION OF vacowned_parted FOR VALUES IN (1) +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: CreateStmt +== 234 +CREATE TABLE vacowned_part2 PARTITION OF vacowned_parted FOR VALUES IN (2) +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: CreateStmt +== 235 +CREATE ROLE regress_vacuum +-- +STMT: CreateRoleStmt +== 236 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +== 237 +-- Simple table +VACUUM vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: VacuumStmt +== 238 +ANALYZE vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: VacuumStmt +== 239 +VACUUM (ANALYZE) vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: VacuumStmt +== 240 +-- Catalog +VACUUM pg_catalog.pg_class +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=DDL +STMT: VacuumStmt +== 241 +ANALYZE pg_catalog.pg_class +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=DDL +STMT: VacuumStmt +== 242 +VACUUM (ANALYZE) pg_catalog.pg_class +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=DDL +STMT: VacuumStmt +== 243 +-- Shared catalog +VACUUM pg_catalog.pg_authid +-- +TABLE: name="pg_catalog.pg_authid" schema="pg_catalog" table="pg_authid" ctx=DDL +STMT: VacuumStmt +== 244 +ANALYZE pg_catalog.pg_authid +-- +TABLE: name="pg_catalog.pg_authid" schema="pg_catalog" table="pg_authid" ctx=DDL +STMT: VacuumStmt +== 245 +VACUUM (ANALYZE) pg_catalog.pg_authid +-- +TABLE: name="pg_catalog.pg_authid" schema="pg_catalog" table="pg_authid" ctx=DDL +STMT: VacuumStmt +== 246 +-- Partitioned table and its partitions, nothing owned by other user. +-- Relations are not listed in a single command to test ownership +-- independently. +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 247 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 248 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 249 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 250 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 251 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 252 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 253 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 254 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 255 +RESET ROLE +-- +STMT: VariableSetStmt +== 256 +-- Partitioned table and one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: AlterTableStmt +== 257 +ALTER TABLE vacowned_part1 OWNER TO regress_vacuum +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: AlterTableStmt +== 258 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +== 259 +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 260 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 261 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 262 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 263 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 264 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 265 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 266 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 267 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 268 +RESET ROLE +-- +STMT: VariableSetStmt +== 269 +-- Only one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO CURRENT_USER +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: AlterTableStmt +== 270 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +== 271 +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 272 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 273 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 274 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 275 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 276 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 277 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 278 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 279 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 280 +RESET ROLE +-- +STMT: VariableSetStmt +== 281 +-- Only partitioned table owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: AlterTableStmt +== 282 +ALTER TABLE vacowned_part1 OWNER TO CURRENT_USER +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: AlterTableStmt +== 283 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +== 284 +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 285 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 286 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 287 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 288 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 289 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 290 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +== 291 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +== 292 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +== 293 +RESET ROLE +-- +STMT: VariableSetStmt +== 294 +DROP TABLE vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: DropStmt +== 295 +DROP TABLE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: DropStmt +== 296 +DROP ROLE regress_vacuum +-- +STMT: DropRoleStmt diff --git a/parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json b/parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json new file mode 100644 index 0000000..5a08d01 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json @@ -0,0 +1,18 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014" + ] +} diff --git a/parser/testdata/summary/postgres_regress/vacuum_parallel.test b/parser/testdata/summary/postgres_regress/vacuum_parallel.test new file mode 100644 index 0000000..60cfd29 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/vacuum_parallel.test @@ -0,0 +1,110 @@ +== 001 +SET max_parallel_maintenance_workers TO 4 +-- +STMT: VariableSetStmt +== 002 +SET min_parallel_index_scan_size TO '128kB' +-- +STMT: VariableSetStmt +== 003 +-- Bug #17245: Make sure that we don't totally fail to VACUUM individual indexes that +-- happen to be below min_parallel_index_scan_size during parallel VACUUM: +CREATE TABLE parallel_vacuum_table (a int) WITH (autovacuum_enabled = off) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: CreateStmt +== 004 +INSERT INTO parallel_vacuum_table SELECT i from generate_series(1, 10000) i +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 005 +-- Parallel VACUUM will never be used unless there are at least two indexes +-- that exceed min_parallel_index_scan_size. Create two such indexes, and +-- a third index that is smaller than min_parallel_index_scan_size. +CREATE INDEX regular_sized_index ON parallel_vacuum_table(a) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: IndexStmt +== 006 +CREATE INDEX typically_sized_index ON parallel_vacuum_table(a) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: IndexStmt +== 007 +-- Note: vacuum_in_leader_small_index can apply deduplication, making it ~3x +-- smaller than the other indexes +CREATE INDEX vacuum_in_leader_small_index ON parallel_vacuum_table((1)) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: IndexStmt +== 008 +-- Verify (as best we can) that the cost model for parallel VACUUM +-- will make our VACUUM run in parallel, while always leaving it up to the +-- parallel leader to handle the vacuum_in_leader_small_index index: +SELECT EXISTS ( +SELECT 1 +FROM pg_class +WHERE oid = 'vacuum_in_leader_small_index'::regclass AND + pg_relation_size(oid) < + pg_size_bytes(current_setting('min_parallel_index_scan_size')) +) as leader_will_handle_small_index +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 009 +SELECT count(*) as trigger_parallel_vacuum_nindexes +FROM pg_class +WHERE oid in ('regular_sized_index'::regclass, 'typically_sized_index'::regclass) AND + pg_relation_size(oid) >= + pg_size_bytes(current_setting('min_parallel_index_scan_size')) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +== 010 +-- Parallel VACUUM with B-Tree page deletions, ambulkdelete calls: +DELETE FROM parallel_vacuum_table +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DML +STMT: DeleteStmt +== 011 +VACUUM (PARALLEL 4, INDEX_CLEANUP ON) parallel_vacuum_table +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: VacuumStmt +== 012 +-- Since vacuum_in_leader_small_index uses deduplication, we expect an +-- assertion failure with bug #17245 (in the absence of bugfix): +INSERT INTO parallel_vacuum_table SELECT i FROM generate_series(1, 10000) i +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 013 +RESET max_parallel_maintenance_workers +-- +STMT: VariableSetStmt +== 014 +RESET min_parallel_index_scan_size +-- +STMT: VariableSetStmt diff --git a/parser/testdata/summary/postgres_regress/varchar.metadata.json b/parser/testdata/summary/postgres_regress/varchar.metadata.json new file mode 100644 index 0000000..edb706f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/varchar.metadata.json @@ -0,0 +1,26 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022" + ] +} diff --git a/parser/testdata/summary/postgres_regress/varchar.test b/parser/testdata/summary/postgres_regress/varchar.test new file mode 100644 index 0000000..7d0468a --- /dev/null +++ b/parser/testdata/summary/postgres_regress/varchar.test @@ -0,0 +1,163 @@ +== 001 +|-- +-- VARCHAR +|-- + +|-- +-- Build a table for testing +-- (This temporarily hides the table created in test_setup.sql) +|-- + +CREATE TEMP TABLE VARCHAR_TBL(f1 varchar(1)) +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO VARCHAR_TBL (f1) VALUES ('a') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO VARCHAR_TBL (f1) VALUES ('A') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +-- any of the following three input formats are acceptable +INSERT INTO VARCHAR_TBL (f1) VALUES ('1') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 005 +INSERT INTO VARCHAR_TBL (f1) VALUES (2) +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 006 +INSERT INTO VARCHAR_TBL (f1) VALUES ('3') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 007 +-- zero-length char +INSERT INTO VARCHAR_TBL (f1) VALUES ('') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +-- try varchar's of greater than 1 length +INSERT INTO VARCHAR_TBL (f1) VALUES ('cd') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 009 +INSERT INTO VARCHAR_TBL (f1) VALUES ('c ') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 010 +SELECT * FROM VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +STMT: SelectStmt +== 011 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 <> 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 012 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 = 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 013 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 < 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 014 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 <= 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 015 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 > 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 016 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 >= 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +== 017 +DROP TABLE VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: DropStmt +== 018 +|-- +-- Now test longer arrays of char +|-- +-- This varchar_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. +|-- + +INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 019 +SELECT * FROM VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +STMT: SelectStmt +== 020 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('abcd ', 'varchar(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT pg_input_is_valid('abcde', 'varchar(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT * FROM pg_input_error_info('abcde', 'varchar(4)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/window.metadata.json b/parser/testdata/summary/postgres_regress/window.metadata.json new file mode 100644 index 0000000..a1f4321 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/window.metadata.json @@ -0,0 +1,390 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386" + ] +} diff --git a/parser/testdata/summary/postgres_regress/window.test b/parser/testdata/summary/postgres_regress/window.test new file mode 100644 index 0000000..20c84d3 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/window.test @@ -0,0 +1,3859 @@ +== 001 +|-- +-- WINDOW FUNCTIONS +|-- + +CREATE TEMPORARY TABLE empsalary ( + depname varchar, + empno bigint, + salary int, + enroll_date date +) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO empsalary VALUES +('develop', 10, 5200, '2007-08-01'), +('sales', 1, 5000, '2006-10-01'), +('personnel', 5, 3500, '2007-12-10'), +('sales', 4, 4800, '2007-08-08'), +('personnel', 2, 3900, '2006-12-23'), +('develop', 7, 4200, '2008-01-01'), +('develop', 9, 4500, '2008-01-01'), +('sales', 3, 4800, '2007-08-01'), +('develop', 8, 6000, '2006-10-01'), +('develop', 11, 5200, '2007-08-15') +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +SELECT depname, empno, salary, sum(salary) OVER (PARTITION BY depname) FROM empsalary ORDER BY depname, salary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 004 +SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary) FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 005 +-- with GROUP BY +SELECT four, ten, SUM(SUM(four)) OVER (PARTITION BY four), AVG(ten) FROM tenk1 +GROUP BY four, ten ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 006 +SELECT depname, empno, salary, sum(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT depname, empno, salary, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary) ORDER BY rank() OVER w +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 008 +-- empty window specification +SELECT COUNT(*) OVER () FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 009 +SELECT COUNT(*) OVER w FROM tenk1 WHERE unique2 < 10 WINDOW w AS () +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 010 +-- no window operation +SELECT four FROM tenk1 WHERE FALSE WINDOW w AS (PARTITION BY ten) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +== 011 +-- cumulative aggregate +SELECT sum(four) OVER (PARTITION BY ten ORDER BY unique2) AS sum_1, ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 012 +SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 013 +SELECT rank() OVER (PARTITION BY four ORDER BY ten) AS rank_1, ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 014 +SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 015 +SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 016 +SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="cume_dist" function="cume_dist" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 017 +SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 018 +SELECT ntile(NULL) OVER (ORDER BY ten, four), ten, four FROM tenk1 LIMIT 2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 020 +SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 021 +SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 022 +SELECT lag(ten, four, 0.7) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 023 +SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 024 +SELECT lead(ten * 2, 1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 025 +SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 026 +SELECT lead(ten * 2, 1, -1.4) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 027 +SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 028 +-- last_value returns the last row of the frame, which is CURRENT ROW in ORDER BY window. +SELECT last_value(four) OVER (ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 029 +SELECT last_value(ten) OVER (PARTITION BY four), ten, four FROM + (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s + ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 030 +SELECT nth_value(ten, four + 1) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 031 +SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER (PARTITION BY two ORDER BY ten) AS wsum +FROM tenk1 GROUP BY ten, two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT count(*) OVER (PARTITION BY four), four FROM (SELECT * FROM tenk1 WHERE two = 1)s WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="two" +STMT: SelectStmt +== 033 +SELECT (count(*) OVER (PARTITION BY four ORDER BY ten) + + sum(hundred) OVER (PARTITION BY four ORDER BY ten))::varchar AS cntsum + FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 034 +-- opexpr with different windows evaluation. +SELECT * FROM( + SELECT count(*) OVER (PARTITION BY four ORDER BY ten) + + sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS total, + count(*) OVER (PARTITION BY four ORDER BY ten) AS fourcount, + sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS twosum + FROM tenk1 +)sub +WHERE total <> fourcount + twosum +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="total" +FILTER: schema="" table="" column="fourcount" +FILTER: schema="" table="" column="twosum" +STMT: SelectStmt +== 035 +SELECT avg(four) OVER (PARTITION BY four ORDER BY thousand / 100) FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 036 +SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER win AS wsum +FROM tenk1 GROUP BY ten, two WINDOW win AS (PARTITION BY two ORDER BY ten) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- more than one window with GROUP BY +SELECT sum(salary), + row_number() OVER (ORDER BY depname), + sum(sum(salary)) OVER (ORDER BY depname DESC) +FROM empsalary GROUP BY depname +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 038 +-- identical windows with different names +SELECT sum(salary) OVER w1, count(*) OVER w2 +FROM empsalary WINDOW w1 AS (ORDER BY salary), w2 AS (ORDER BY salary) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 039 +-- subplan +SELECT lead(ten, (SELECT two FROM tenk1 WHERE s.unique2 = unique2)) OVER (PARTITION BY four ORDER BY ten) +FROM tenk1 s WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "s"="tenk1" +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="s" column="unique2" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 040 +-- empty table +SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 WHERE FALSE)s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 041 +-- mixture of agg/wfunc in the same window +SELECT sum(salary) OVER w, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +== 042 +-- strict aggs +SELECT empno, depname, salary, bonus, depadj, MIN(bonus) OVER (ORDER BY empno), MAX(depadj) OVER () FROM( + SELECT *, + CASE WHEN enroll_date < '2008-01-01' THEN 2008 - extract(YEAR FROM enroll_date) END * 500 AS bonus, + CASE WHEN + AVG(salary) OVER (PARTITION BY depname) < salary + THEN 200 END AS depadj FROM empsalary +)s +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 043 +-- window function over ungrouped agg over empty row set (bug before 9.1) +SELECT SUM(COUNT(f1)) OVER () FROM int4_tbl WHERE f1=42 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +== 044 +-- window function with ORDER BY an expression involving aggregates (9.1 bug) +select ten, + sum(unique1) + sum(unique2) as res, + rank() over (order by sum(unique1) + sum(unique2)) as rank +from tenk1 +group by ten order by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- window and aggregate with GROUP BY expression (9.2 bug) +explain (costs off) +select first_value(max(x)) over (), y + from (select unique1 as x, ten+four as y from tenk1) ss + group by y +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 046 +-- window functions returning pass-by-ref values from different rows +select x, lag(x, 1) over (order by x), lead(x, 3) over (order by x) +from (select x::numeric as x from generate_series(1,10) x) +-- +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 047 +-- test non-default frame specifications +SELECT four, ten, + sum(ten) over (partition by four order by ten), + last_value(ten) over (partition by four order by ten) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 048 +SELECT four, ten, + sum(ten) over (partition by four order by ten range between unbounded preceding and current row), + last_value(ten) over (partition by four order by ten range between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 049 +SELECT four, ten, + sum(ten) over (partition by four order by ten range between unbounded preceding and unbounded following), + last_value(ten) over (partition by four order by ten range between unbounded preceding and unbounded following) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 050 +SELECT four, ten/4 as two, + sum(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row), + last_value(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 051 +SELECT four, ten/4 as two, + sum(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row), + last_value(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 052 +SELECT sum(unique1) over (order by four range between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 053 +SELECT sum(unique1) over (rows between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 054 +SELECT sum(unique1) over (rows between 2 preceding and 2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 055 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude no others), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 056 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 057 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 058 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 059 +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 060 +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 061 +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 062 +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 063 +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 064 +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 065 +SELECT sum(unique1) over (rows between 2 preceding and 1 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 066 +SELECT sum(unique1) over (rows between 1 following and 3 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 067 +SELECT sum(unique1) over (rows between unbounded preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 068 +SELECT sum(unique1) over (w range between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 069 +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 070 +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 071 +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 072 +SELECT first_value(unique1) over w, + nth_value(unique1, 2) over w AS nth_2, + last_value(unique1) over w, unique1, four +FROM tenk1 WHERE unique1 < 10 +WINDOW w AS (order by four range between current row and unbounded following) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 073 +SELECT sum(unique1) over + (order by unique1 + rows (SELECT unique1 FROM tenk1 ORDER BY unique1 LIMIT 1) + 1 PRECEDING), + unique1 +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 074 +CREATE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following) as sum_rows + FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 075 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +== 076 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 077 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude current row) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 078 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +== 079 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 080 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude group) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 081 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +== 082 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 083 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude ties) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 084 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +== 085 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 086 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude no others) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 087 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +== 088 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 089 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i groups between 1 preceding and 1 following) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 090 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +== 091 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 092 +DROP VIEW v_window +-- +STMT: DropStmt +== 093 +CREATE TEMP VIEW v_window AS + SELECT i, min(i) over (order by i range between '1 day' preceding and '10 days' following) as min_i + FROM generate_series(now(), now()+'100 days'::interval, '1 hour') i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 094 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 095 +-- RANGE offset PRECEDING/FOLLOWING tests + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 096 +SELECT sum(unique1) over (order by four desc range between 2::int8 preceding and 1::int2 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 097 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude no others), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 098 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 099 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 100 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 101 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 102 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 103 +SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 104 +SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following + exclude current row),unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 105 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 106 +select sum(salary) over (order by enroll_date desc range between '1 year'::interval preceding and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 107 +select sum(salary) over (order by enroll_date desc range between '1 year'::interval following and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 108 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude current row), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 109 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude group), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 110 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 111 +select first_value(salary) over(order by salary range between 1000 preceding and 1000 following), + lead(salary) over(order by salary range between 1000 preceding and 1000 following), + nth_value(salary, 1) over(order by salary range between 1000 preceding and 1000 following), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +== 112 +select last_value(salary) over(order by salary range between 1000 preceding and 1000 following), + lag(salary) over(order by salary range between 1000 preceding and 1000 following), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +== 113 +select first_value(salary) over(order by salary range between 1000 following and 3000 following + exclude current row), + lead(salary) over(order by salary range between 1000 following and 3000 following exclude ties), + nth_value(salary, 1) over(order by salary range between 1000 following and 3000 following + exclude ties), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +== 114 +select last_value(salary) over(order by salary range between 1000 following and 3000 following + exclude group), + lag(salary) over(order by salary range between 1000 following and 3000 following exclude group), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +== 115 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 116 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 117 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude group), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude group), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 118 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude current row), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude current row), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 119 +-- RANGE offset PRECEDING/FOLLOWING with null values +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x asc nulls first range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 120 +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x asc nulls last range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 121 +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x desc nulls first range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 122 +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x desc nulls last range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 123 +-- There is a syntactic ambiguity in the SQL standard. Since +-- UNBOUNDED is a non-reserved word, it could be the name of a +-- function parameter and be used as an expression. There is a +-- grammar hack to resolve such cases as the keyword. The following +-- tests record this behavior. + +CREATE FUNCTION unbounded_syntax_test1a(x int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +BEGIN ATOMIC + SELECT sum(unique1) over (rows between x preceding and x following), + unique1, four + FROM tenk1 WHERE unique1 < 10 +-- +ERROR: syntax error at end of input +CURSORPOS: 525 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 124 +END +-- +STMT: TransactionStmt +== 125 +CREATE FUNCTION unbounded_syntax_test1b(x int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +AS $$ + SELECT sum(unique1) over (rows between x preceding and x following), + unique1, four + FROM tenk1 WHERE unique1 < 10; +$$ +-- +FUNCTION: name="unbounded_syntax_test1b" function="unbounded_syntax_test1b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 126 +-- These will apply the argument to the window specification inside the function. +SELECT * FROM unbounded_syntax_test1a(2) +-- +FUNCTION: name="unbounded_syntax_test1a" function="unbounded_syntax_test1a" schema="" ctx=Call +STMT: SelectStmt +== 127 +SELECT * FROM unbounded_syntax_test1b(2) +-- +FUNCTION: name="unbounded_syntax_test1b" function="unbounded_syntax_test1b" schema="" ctx=Call +STMT: SelectStmt +== 128 +CREATE FUNCTION unbounded_syntax_test2a(unbounded int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +BEGIN ATOMIC + SELECT sum(unique1) over (rows between unbounded preceding and unbounded following), + unique1, four + FROM tenk1 WHERE unique1 < 10 +-- +ERROR: syntax error at end of input +CURSORPOS: 259 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 129 +END +-- +STMT: TransactionStmt +== 130 +CREATE FUNCTION unbounded_syntax_test2b(unbounded int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +AS $$ + SELECT sum(unique1) over (rows between unbounded preceding and unbounded following), + unique1, four + FROM tenk1 WHERE unique1 < 10; +$$ +-- +FUNCTION: name="unbounded_syntax_test2b" function="unbounded_syntax_test2b" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 131 +-- These will not apply the argument but instead treat UNBOUNDED as a keyword. +SELECT * FROM unbounded_syntax_test2a(2) +-- +FUNCTION: name="unbounded_syntax_test2a" function="unbounded_syntax_test2a" schema="" ctx=Call +STMT: SelectStmt +== 132 +SELECT * FROM unbounded_syntax_test2b(2) +-- +FUNCTION: name="unbounded_syntax_test2b" function="unbounded_syntax_test2b" schema="" ctx=Call +STMT: SelectStmt +== 133 +DROP FUNCTION unbounded_syntax_test1a, unbounded_syntax_test1b, + unbounded_syntax_test2a, unbounded_syntax_test2b +-- +FUNCTION: name="unbounded_syntax_test1a" function="unbounded_syntax_test1a" schema="" ctx=DDL +STMT: DropStmt +== 134 +-- Other tests with token UNBOUNDED in potentially problematic position +CREATE FUNCTION unbounded(x int) RETURNS int LANGUAGE SQL IMMUTABLE RETURN x +-- +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 135 +SELECT sum(unique1) over (rows between 1 preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 136 +SELECT sum(unique1) over (rows between unbounded(1) preceding and unbounded(1) following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=Call +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 137 +SELECT sum(unique1) over (rows between unbounded.x preceding and unbounded.x following), + unique1, four +FROM tenk1, (values (1)) as unbounded(x) WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 138 +DROP FUNCTION unbounded +-- +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=DDL +STMT: DropStmt +== 139 +-- Check overflow behavior for various integer sizes + +select x, last_value(x) over (order by x::smallint range between current row and 2147450884 following) +from generate_series(32764, 32766) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 140 +select x, last_value(x) over (order by x::smallint desc range between current row and 2147450885 following) +from generate_series(-32766, -32764) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 141 +select x, last_value(x) over (order by x range between current row and 4 following) +from generate_series(2147483644, 2147483646) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 142 +select x, last_value(x) over (order by x desc range between current row and 5 following) +from generate_series(-2147483646, -2147483644) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 143 +select x, last_value(x) over (order by x range between current row and 4 following) +from generate_series(9223372036854775804, 9223372036854775806) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 144 +select x, last_value(x) over (order by x desc range between current row and 5 following) +from generate_series(-9223372036854775806, -9223372036854775804) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 145 +-- Test in_range for other numeric datatypes + +create temp table numerics( + id int, + f_float4 float4, + f_float8 float8, + f_numeric numeric +) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=DDL +STMT: CreateStmt +== 146 +insert into numerics values +(0, '-infinity', '-infinity', '-infinity'), +(1, -3, -3, -3), +(2, -1, -1, -1), +(3, 0, 0, 0), +(4, 1.1, 1.1, 1.1), +(5, 1.12, 1.12, 1.12), +(6, 2, 2, 2), +(7, 100, 100, 100), +(8, 'infinity', 'infinity', 'infinity'), +(9, 'NaN', 'NaN', 'NaN') +-- +TABLE: name="numerics" schema="" table="numerics" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 147 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1 preceding and 1 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 148 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1 preceding and 1.1::float4 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 149 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' preceding and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 150 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' preceding and 'inf' preceding) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 151 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' following and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 152 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1.1 preceding and 'NaN' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 153 +-- error, NaN disallowed + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1 preceding and 1 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 154 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1 preceding and 1.1::float8 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 155 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' preceding and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 156 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' preceding and 'inf' preceding) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 157 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' following and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 158 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1.1 preceding and 'NaN' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 159 +-- error, NaN disallowed + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 160 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1.1::numeric following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 161 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1.1::float8 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 162 +-- currently unsupported +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' preceding and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 163 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' preceding and 'inf' preceding) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 164 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' following and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 165 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1.1 preceding and 'NaN' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 166 +-- error, NaN disallowed + +-- Test in_range for other datetime datatypes + +create temp table datetimes( + id int, + f_time time, + f_timetz timetz, + f_interval interval, + f_timestamptz timestamptz, + f_timestamp timestamp +) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=DDL +STMT: CreateStmt +== 167 +insert into datetimes values +(0, '10:00', '10:00 BST', '-infinity', '-infinity', '-infinity'), +(1, '11:00', '11:00 BST', '1 year', '2000-10-19 10:23:54+01', '2000-10-19 10:23:54'), +(2, '12:00', '12:00 BST', '2 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'), +(3, '13:00', '13:00 BST', '3 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'), +(4, '14:00', '14:00 BST', '4 years', '2002-10-19 10:23:54+01', '2002-10-19 10:23:54'), +(5, '15:00', '15:00 BST', '5 years', '2003-10-19 10:23:54+01', '2003-10-19 10:23:54'), +(6, '15:00', '15:00 BST', '5 years', '2004-10-19 10:23:54+01', '2004-10-19 10:23:54'), +(7, '17:00', '17:00 BST', '7 years', '2005-10-19 10:23:54+01', '2005-10-19 10:23:54'), +(8, '18:00', '18:00 BST', '8 years', '2006-10-19 10:23:54+01', '2006-10-19 10:23:54'), +(9, '19:00', '19:00 BST', '9 years', '2007-10-19 10:23:54+01', '2007-10-19 10:23:54'), +(10, '20:00', '20:00 BST', '10 years', '2008-10-19 10:23:54+01', '2008-10-19 10:23:54'), +(11, '21:00', '21:00 BST', 'infinity', 'infinity', 'infinity') +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 168 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + '70 min'::interval preceding and '2 hours'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 169 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time desc range between + '70 min' preceding and '2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 170 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time desc range between + '-70 min' preceding and '2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 171 +-- error, negative offset disallowed + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 172 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 173 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 174 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 175 +-- error, negative offset disallowed + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + '70 min'::interval preceding and '2 hours'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 176 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz desc range between + '70 min' preceding and '2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 177 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz desc range between + '70 min' preceding and '-2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 178 +-- error, negative offset disallowed + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 179 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 180 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 181 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval following and + '-infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 182 +-- error, negative offset disallowed + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + '1 year'::interval preceding and '1 year'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 183 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval desc range between + '1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 184 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval desc range between + '-1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 185 +-- error, negative offset disallowed + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 186 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 187 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 188 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 189 +-- error, negative offset disallowed + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + '1 year'::interval preceding and '1 year'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 190 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz desc range between + '1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 191 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz desc range between + '1 year' preceding and '-1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 192 +-- error, negative offset disallowed + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 193 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 194 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 195 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 196 +-- error, negative offset disallowed + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + '1 year'::interval preceding and '1 year'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 197 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp desc range between + '1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 198 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp desc range between + '-1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 199 +-- error, negative offset disallowed + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 200 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 201 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 202 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +== 203 +-- error, negative offset disallowed + +-- RANGE offset PRECEDING/FOLLOWING error cases +select sum(salary) over (order by enroll_date, salary range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 204 +select sum(salary) over (range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 205 +select sum(salary) over (order by depname range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 206 +select max(enroll_date) over (order by enroll_date range between 1 preceding and 2 following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 207 +select max(enroll_date) over (order by salary range between -1 preceding and 2 following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 208 +select max(enroll_date) over (order by salary range between 1 preceding and -2 following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 209 +select max(enroll_date) over (order by salary range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 210 +select max(enroll_date) over (order by enroll_date range between '1 year'::interval preceding and '-2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 211 +-- GROUPS tests + +SELECT sum(unique1) over (order by four groups between unbounded preceding and current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 212 +SELECT sum(unique1) over (order by four groups between unbounded preceding and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 213 +SELECT sum(unique1) over (order by four groups between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 214 +SELECT sum(unique1) over (order by four groups between 1 preceding and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 215 +SELECT sum(unique1) over (order by four groups between 1 following and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 216 +SELECT sum(unique1) over (order by four groups between unbounded preceding and 2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 217 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 218 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 219 +SELECT sum(unique1) over (order by four groups between 0 preceding and 0 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 220 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude current row), unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 221 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude group), unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 222 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude ties), unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 223 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following),unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 224 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude current row), unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 225 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude group), unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 226 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude ties), unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +== 227 +select first_value(salary) over(order by enroll_date groups between 1 preceding and 1 following), + lead(salary) over(order by enroll_date groups between 1 preceding and 1 following), + nth_value(salary, 1) over(order by enroll_date groups between 1 preceding and 1 following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +== 228 +select last_value(salary) over(order by enroll_date groups between 1 preceding and 1 following), + lag(salary) over(order by enroll_date groups between 1 preceding and 1 following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +== 229 +select first_value(salary) over(order by enroll_date groups between 1 following and 3 following + exclude current row), + lead(salary) over(order by enroll_date groups between 1 following and 3 following exclude ties), + nth_value(salary, 1) over(order by enroll_date groups between 1 following and 3 following + exclude ties), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +== 230 +select last_value(salary) over(order by enroll_date groups between 1 following and 3 following + exclude group), + lag(salary) over(order by enroll_date groups between 1 following and 3 following exclude group), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +== 231 +-- Show differences in offset interpretation between ROWS, RANGE, and GROUPS +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 232 +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x range between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 233 +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 234 +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 235 +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x range between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 236 +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 237 +-- with UNION +SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2)s LIMIT 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 238 +-- check some degenerate cases +create temp table t1 (f1 int, f2 int8) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +== 239 +insert into t1 values (1,1),(1,2),(2,2) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 240 +select f1, sum(f1) over (partition by f1 + range between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 241 +-- error, must have order by +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: ExplainStmt +STMT: SelectStmt +== 242 +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 243 +select f1, sum(f1) over (partition by f1, f1 order by f2 + range between 2 preceding and 1 preceding) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 244 +select f1, sum(f1) over (partition by f1, f2 order by f2 + range between 1 following and 2 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 245 +select f1, sum(f1) over (partition by f1 + groups between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 246 +-- error, must have order by +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: ExplainStmt +STMT: SelectStmt +== 247 +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 248 +select f1, sum(f1) over (partition by f1, f1 order by f2 + groups between 2 preceding and 1 preceding) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 249 +select f1, sum(f1) over (partition by f1, f2 order by f2 + groups between 1 following and 2 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +== 250 +-- ordering by a non-integer constant is allowed +SELECT rank() OVER (ORDER BY length('abc')) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 251 +-- can't order by another window function +SELECT rank() OVER (ORDER BY rank() OVER (ORDER BY random())) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 252 +-- some other errors +SELECT * FROM empsalary WHERE row_number() OVER (ORDER BY salary) < 10 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="salary" +STMT: SelectStmt +== 253 +SELECT * FROM empsalary INNER JOIN tenk1 ON row_number() OVER (ORDER BY salary) < 10 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: SelectStmt +== 254 +SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GROUP BY 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 255 +SELECT * FROM rank() OVER (ORDER BY random()) +-- +ERROR: syntax error at or near "ORDER" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 256 +DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())) > 10 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DML +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: DeleteStmt +== 257 +DELETE FROM empsalary RETURNING rank() OVER (ORDER BY random()) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DML +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: DeleteStmt +== 258 +SELECT count(*) OVER w FROM tenk1 WINDOW w AS (ORDER BY unique1), w AS (ORDER BY unique1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 259 +SELECT rank() OVER (PARTITION BY four, ORDER BY ten) FROM tenk1 +-- +ERROR: syntax error at or near "ORDER" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 260 +SELECT count() OVER () FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 261 +SELECT generate_series(1, 100) OVER () FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 262 +SELECT ntile(0) OVER (ORDER BY ten), ten, four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +STMT: SelectStmt +== 263 +SELECT nth_value(four, 0) OVER (ORDER BY ten), ten, four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +== 264 +-- filter + +SELECT sum(salary), row_number() OVER (ORDER BY depname), sum( + sum(salary) FILTER (WHERE enroll_date > '2007-01-01') +) FILTER (WHERE depname <> 'sales') OVER (ORDER BY depname DESC) AS "filtered_sum", + depname +FROM empsalary GROUP BY depname +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 265 +|-- +-- Test SupportRequestOptimizeWindowClause's ability to de-duplicate +-- WindowClauses +|-- + +-- Ensure WindowClause frameOptions are changed so that only a single +-- WindowAgg exists in the plan. +EXPLAIN (COSTS OFF) +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + dense_rank() OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) drnk, + ntile(10) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) nt, + percent_rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) pr, + cume_dist() OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) cd +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +FUNCTION: name="cume_dist" function="cume_dist" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 266 +-- Ensure WindowFuncs which cannot support their WindowClause's frameOptions +-- being changed are untouched +EXPLAIN (COSTS OFF, VERBOSE) +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + count(*) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) cnt +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 267 +-- Ensure the above query gives us the expected results +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + count(*) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) cnt +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 268 +-- Test pushdown of quals into a subquery containing window functions + +-- pushdown is safe because all PARTITION BY clauses include depname: +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname) depsalary, + min(salary) OVER (PARTITION BY depname || 'A', depname) depminsalary + FROM empsalary) emp +WHERE depname = 'sales' +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="depname" +STMT: ExplainStmt +STMT: SelectStmt +== 269 +-- pushdown is unsafe because there's a PARTITION BY clause without depname: +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY enroll_date) enroll_salary, + min(salary) OVER (PARTITION BY depname) depminsalary + FROM empsalary) emp +WHERE depname = 'sales' +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="depname" +STMT: ExplainStmt +STMT: SelectStmt +== 270 +-- Test window function run conditions are properly pushed down into the +-- WindowAgg +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: ExplainStmt +STMT: SelectStmt +== 271 +-- The following 3 statements should result the same result. +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +== 272 +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE 3 > rn +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +== 273 +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE 2 >= rn +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +== 274 +-- Ensure r <= 3 is pushed down into the run condition of the window agg +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + rank() OVER (ORDER BY salary DESC) r + FROM empsalary) emp +WHERE r <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="r" +STMT: ExplainStmt +STMT: SelectStmt +== 275 +SELECT * FROM + (SELECT empno, + salary, + rank() OVER (ORDER BY salary DESC) r + FROM empsalary) emp +WHERE r <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="r" +STMT: SelectStmt +== 276 +-- Ensure dr = 1 is converted to dr <= 1 to get all rows leading up to dr = 1 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="dr" +STMT: ExplainStmt +STMT: SelectStmt +== 277 +SELECT * FROM + (SELECT empno, + salary, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="dr" +STMT: SelectStmt +== 278 +-- Check COUNT() and COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 279 +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +== 280 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(empno) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 281 +SELECT * FROM + (SELECT empno, + salary, + count(empno) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +== 282 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) c + FROM empsalary) emp +WHERE c >= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 283 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER () c + FROM empsalary) emp +WHERE 11 <= c +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 284 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="dr" +STMT: ExplainStmt +STMT: SelectStmt +== 285 +-- Ensure we get a run condition when there's a PARTITION BY clause +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: ExplainStmt +STMT: SelectStmt +== 286 +-- and ensure we get the correct results from the above plan +SELECT * FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +== 287 +-- ensure that "unused" subquery columns are not removed when the column only +-- exists in the run condition +EXPLAIN (COSTS OFF) +SELECT empno, depname FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: ExplainStmt +STMT: SelectStmt +== 288 +-- likewise with count(empno) instead of row_number() +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (PARTITION BY depname ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 289 +-- and again, check the results are what we expect. +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (PARTITION BY depname ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +== 290 +-- Ensure we get the correct run condition when the window function is both +-- monotonically increasing and decreasing. +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER () c + FROM empsalary) emp +WHERE c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 291 +-- Try another case with a WindowFunc with a byref return type +SELECT * FROM + (SELECT row_number() OVER (PARTITION BY salary) AS rn, + lead(depname) OVER (PARTITION BY salary) || ' Department' AS n_dep + FROM empsalary) emp +WHERE rn < 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +== 292 +-- Some more complex cases with multiple window clauses +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT *, + count(salary) OVER (PARTITION BY depname || '') c1, -- w1 + row_number() OVER (PARTITION BY depname) rn, -- w2 + count(*) OVER (PARTITION BY depname) c2, -- w2 + count(*) OVER (PARTITION BY '' || depname) c3, -- w3 + ntile(2) OVER (PARTITION BY depname) nt -- w2 + FROM empsalary +) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="nt" +STMT: ExplainStmt +STMT: SelectStmt +== 293 +-- Ensure we correctly filter out all of the run conditions from each window +SELECT * FROM + (SELECT *, + count(salary) OVER (PARTITION BY depname || '') c1, -- w1 + row_number() OVER (PARTITION BY depname) rn, -- w2 + count(*) OVER (PARTITION BY depname) c2, -- w2 + count(*) OVER (PARTITION BY '' || depname) c3, -- w3 + ntile(2) OVER (PARTITION BY depname) nt -- w2 + FROM empsalary +) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="nt" +STMT: SelectStmt +== 294 +-- Ensure we remove references to reduced outer joins as nulling rels in run +-- conditions +EXPLAIN (COSTS OFF) +SELECT 1 FROM + (SELECT ntile(e2.salary) OVER (PARTITION BY e1.depname) AS c + FROM empsalary e1 LEFT JOIN empsalary e2 ON TRUE + WHERE e1.empno = e2.empno) s +WHERE s.c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +ALIAS: "e1"="empsalary" +ALIAS: "e2"="empsalary" +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="s" column="c" +FILTER: schema="" table="e1" column="empno" +FILTER: schema="" table="e2" column="empno" +STMT: ExplainStmt +STMT: SelectStmt +== 295 +-- Ensure the run condition optimization is used in cases where the WindowFunc +-- has a Var from another query level +EXPLAIN (COSTS OFF) +SELECT 1 FROM + (SELECT ntile(s1.x) OVER () AS c + FROM (SELECT (SELECT 1) AS x) AS s1) s +WHERE s.c = 1 +-- +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 296 +-- Tests to ensure we don't push down the run condition when it's not valid to +-- do so. + +-- Ensure we don't push down when the frame options show that the window +-- function is not monotonically increasing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 297 +-- Ensure we don't push down when the window function's monotonic properties +-- don't match that of the clauses. +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary) c + FROM empsalary) emp +WHERE 3 <= c +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 298 +-- Ensure we don't use a run condition when there's a volatile function in the +-- WindowFunc +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(random()) OVER (ORDER BY empno DESC) c + FROM empsalary) emp +WHERE c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 299 +-- Ensure we don't use a run condition when the WindowFunc contains subplans +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count((SELECT 1)) OVER (ORDER BY empno DESC) c + FROM empsalary) emp +WHERE c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +== 300 +-- Test Sort node collapsing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname, empno order by enroll_date) depminsalary + FROM empsalary) emp +WHERE depname = 'sales' +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="depname" +STMT: ExplainStmt +STMT: SelectStmt +== 301 +-- Ensure that the evaluation order of the WindowAggs results in the WindowAgg +-- with the same sort order that's required by the ORDER BY is evaluated last. +EXPLAIN (COSTS OFF) +SELECT empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, empno +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 302 +-- As above, but with an adjusted ORDER BY to ensure the above plan didn't +-- perform only 2 sorts by accident. +EXPLAIN (COSTS OFF) +SELECT empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, enroll_date +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 303 +SET enable_hashagg TO off +-- +STMT: VariableSetStmt +== 304 +-- Ensure we don't get a sort for both DISTINCT and ORDER BY. We expect the +-- sort for the DISTINCT to provide presorted input for the ORDER BY. +EXPLAIN (COSTS OFF) +SELECT DISTINCT + empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, enroll_date +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 305 +-- As above but adjust the ORDER BY clause to help ensure the plan with the +-- minimum amount of sorting wasn't a fluke. +EXPLAIN (COSTS OFF) +SELECT DISTINCT + empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, empno +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 306 +RESET enable_hashagg +-- +STMT: VariableSetStmt +== 307 +-- Test Sort node reordering +EXPLAIN (COSTS OFF) +SELECT + lead(1) OVER (PARTITION BY depname ORDER BY salary, enroll_date), + lag(1) OVER (PARTITION BY depname ORDER BY salary,enroll_date,empno) +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 308 +-- Test incremental sorting +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + empno, + salary, + enroll_date, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp + FROM empsalary) emp +WHERE first_emp = 1 OR last_emp = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="first_emp" +FILTER: schema="" table="" column="last_emp" +STMT: ExplainStmt +STMT: SelectStmt +== 309 +SELECT * FROM + (SELECT depname, + empno, + salary, + enroll_date, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp + FROM empsalary) emp +WHERE first_emp = 1 OR last_emp = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="first_emp" +FILTER: schema="" table="" column="last_emp" +STMT: SelectStmt +== 310 +-- cleanup +DROP TABLE empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DDL +STMT: DropStmt +== 311 +-- test user-defined window function with named args and default args +CREATE FUNCTION nth_value_def(val anyelement, n integer = 1) RETURNS anyelement + LANGUAGE internal WINDOW IMMUTABLE STRICT AS 'window_nth_value' +-- +FUNCTION: name="nth_value_def" function="nth_value_def" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 312 +SELECT nth_value_def(n := 2, val := ten) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value_def" function="nth_value_def" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 313 +SELECT nth_value_def(ten) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value_def" function="nth_value_def" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +== 314 +|-- +-- Test the basic moving-aggregate machinery +|-- + +-- create aggregates that record the series of transform calls (these are +-- intentionally not true inverses) + +CREATE FUNCTION logging_sfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT COALESCE($1, '') || '*' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="logging_sfunc_nonstrict" function="logging_sfunc_nonstrict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 315 +CREATE FUNCTION logging_msfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT COALESCE($1, '') || '+' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="logging_msfunc_nonstrict" function="logging_msfunc_nonstrict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 316 +CREATE FUNCTION logging_minvfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '-' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="logging_minvfunc_nonstrict" function="logging_minvfunc_nonstrict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 317 +CREATE AGGREGATE logging_agg_nonstrict (anyelement) +( + stype = text, + sfunc = logging_sfunc_nonstrict, + mstype = text, + msfunc = logging_msfunc_nonstrict, + minvfunc = logging_minvfunc_nonstrict +) +-- +STMT: DefineStmt +== 318 +CREATE AGGREGATE logging_agg_nonstrict_initcond (anyelement) +( + stype = text, + sfunc = logging_sfunc_nonstrict, + mstype = text, + msfunc = logging_msfunc_nonstrict, + minvfunc = logging_minvfunc_nonstrict, + initcond = 'I', + minitcond = 'MI' +) +-- +STMT: DefineStmt +== 319 +CREATE FUNCTION logging_sfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '*' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE +-- +FUNCTION: name="logging_sfunc_strict" function="logging_sfunc_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 320 +CREATE FUNCTION logging_msfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '+' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE +-- +FUNCTION: name="logging_msfunc_strict" function="logging_msfunc_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 321 +CREATE FUNCTION logging_minvfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '-' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE +-- +FUNCTION: name="logging_minvfunc_strict" function="logging_minvfunc_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 322 +CREATE AGGREGATE logging_agg_strict (text) +( + stype = text, + sfunc = logging_sfunc_strict, + mstype = text, + msfunc = logging_msfunc_strict, + minvfunc = logging_minvfunc_strict +) +-- +STMT: DefineStmt +== 323 +CREATE AGGREGATE logging_agg_strict_initcond (anyelement) +( + stype = text, + sfunc = logging_sfunc_strict, + mstype = text, + msfunc = logging_msfunc_strict, + minvfunc = logging_minvfunc_strict, + initcond = 'I', + minitcond = 'MI' +) +-- +STMT: DefineStmt +== 324 +-- test strict and non-strict cases +SELECT + p::text || ',' || i::text || ':' || COALESCE(v::text, 'NULL') AS row, + logging_agg_nonstrict(v) over wnd as nstrict, + logging_agg_nonstrict_initcond(v) over wnd as nstrict_init, + logging_agg_strict(v::text) over wnd as strict, + logging_agg_strict_initcond(v) over wnd as strict_init +FROM (VALUES + (1, 1, NULL), + (1, 2, 'a'), + (1, 3, 'b'), + (1, 4, NULL), + (1, 5, NULL), + (1, 6, 'c'), + (2, 1, NULL), + (2, 2, 'x'), + (3, 1, 'z') +) AS t(p, i, v) +WINDOW wnd AS (PARTITION BY P ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY p, i +-- +FUNCTION: name="logging_agg_nonstrict" function="logging_agg_nonstrict" schema="" ctx=Call +FUNCTION: name="logging_agg_nonstrict_initcond" function="logging_agg_nonstrict_initcond" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict_initcond" function="logging_agg_strict_initcond" schema="" ctx=Call +STMT: SelectStmt +== 325 +-- and again, but with filter +SELECT + p::text || ',' || i::text || ':' || + CASE WHEN f THEN COALESCE(v::text, 'NULL') ELSE '-' END as row, + logging_agg_nonstrict(v) filter(where f) over wnd as nstrict_filt, + logging_agg_nonstrict_initcond(v) filter(where f) over wnd as nstrict_init_filt, + logging_agg_strict(v::text) filter(where f) over wnd as strict_filt, + logging_agg_strict_initcond(v) filter(where f) over wnd as strict_init_filt +FROM (VALUES + (1, 1, true, NULL), + (1, 2, false, 'a'), + (1, 3, true, 'b'), + (1, 4, false, NULL), + (1, 5, false, NULL), + (1, 6, false, 'c'), + (2, 1, false, NULL), + (2, 2, true, 'x'), + (3, 1, true, 'z') +) AS t(p, i, f, v) +WINDOW wnd AS (PARTITION BY p ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY p, i +-- +FUNCTION: name="logging_agg_nonstrict" function="logging_agg_nonstrict" schema="" ctx=Call +FUNCTION: name="logging_agg_nonstrict_initcond" function="logging_agg_nonstrict_initcond" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict_initcond" function="logging_agg_strict_initcond" schema="" ctx=Call +STMT: SelectStmt +== 326 +-- test that volatile arguments disable moving-aggregate mode +SELECT + i::text || ':' || COALESCE(v::text, 'NULL') as row, + logging_agg_strict(v::text) + over wnd as inverse, + logging_agg_strict(v::text || CASE WHEN random() < 0 then '?' ELSE '' END) + over wnd as noinverse +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY i +-- +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 327 +SELECT + i::text || ':' || COALESCE(v::text, 'NULL') as row, + logging_agg_strict(v::text) filter(where true) + over wnd as inverse, + logging_agg_strict(v::text) filter(where random() >= 0) + over wnd as noinverse +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY i +-- +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +== 328 +-- test that non-overlapping windows don't use inverse transitions +SELECT + logging_agg_strict(v::text) OVER wnd +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW) +ORDER BY i +-- +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +STMT: SelectStmt +== 329 +-- test that returning NULL from the inverse transition functions +-- restarts the aggregation from scratch. The second aggregate is supposed +-- to test cases where only some aggregates restart, the third one checks +-- that one aggregate restarting doesn't cause others to restart. + +CREATE FUNCTION sum_int_randrestart_minvfunc(int4, int4) RETURNS int4 AS +$$ SELECT CASE WHEN random() < 0.2 THEN NULL ELSE $1 - $2 END $$ +LANGUAGE SQL STRICT +-- +FUNCTION: name="sum_int_randrestart_minvfunc" function="sum_int_randrestart_minvfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 330 +CREATE AGGREGATE sum_int_randomrestart (int4) +( + stype = int4, + sfunc = int4pl, + mstype = int4, + msfunc = int4pl, + minvfunc = sum_int_randrestart_minvfunc +) +-- +STMT: DefineStmt +== 331 +WITH +vs AS ( + SELECT i, (random() * 100)::int4 AS v + FROM generate_series(1, 100) AS i +), +sum_following AS ( + SELECT i, SUM(v) OVER + (ORDER BY i DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS s + FROM vs +) +SELECT DISTINCT + sum_following.s = sum_int_randomrestart(v) OVER fwd AS eq1, + -sum_following.s = sum_int_randomrestart(-v) OVER fwd AS eq2, + 100*3+(vs.i-1)*3 = length(logging_agg_nonstrict(''::text) OVER fwd) AS eq3 +FROM vs +JOIN sum_following ON sum_following.i = vs.i +WINDOW fwd AS ( + ORDER BY vs.i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +) +-- +CTE: "vs" +CTE: "sum_following" +FUNCTION: name="sum_int_randomrestart" function="sum_int_randomrestart" schema="" ctx=Call +FUNCTION: name="sum_int_randomrestart" function="sum_int_randomrestart" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="logging_agg_nonstrict" function="logging_agg_nonstrict" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 332 +|-- +-- Test various built-in aggregates that have moving-aggregate support +|-- + +-- test inverse transition functions handle NULLs properly +SELECT i,AVG(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 333 +SELECT i,AVG(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 334 +SELECT i,AVG(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 335 +SELECT i,AVG(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.5),(2,2.5),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 336 +SELECT i,AVG(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +== 337 +-- moving aggregates over infinite intervals +SELECT x + ,avg(x) OVER(ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ) as curr_next_avg + ,avg(x) OVER(ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) as prev_curr_avg + ,sum(x) OVER(ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ) as curr_next_sum + ,sum(x) OVER(ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) as prev_curr_sum +FROM (VALUES (NULL::interval), + ('infinity'::interval), + ('-2147483648 days -2147483648 months -9223372036854775807 usecs'), -- extreme interval value + ('-infinity'::interval), + ('2147483647 days 2147483647 months 9223372036854775806 usecs'), -- extreme interval value + ('infinity'::interval), + ('6 days'::interval), + ('7 days'::interval), + (NULL::interval), + ('-infinity'::interval)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 338 +--should fail. +SELECT x, avg(x) OVER(ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) +FROM (VALUES (NULL::interval), + ('3 days'::interval), + ('infinity'::timestamptz - now()), + ('6 days'::interval), + ('-infinity'::interval)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 339 +--should fail. +SELECT x, sum(x) OVER(ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) +FROM (VALUES (NULL::interval), + ('3 days'::interval), + ('infinity'::timestamptz - now()), + ('6 days'::interval), + ('-infinity'::interval)) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +== 340 +SELECT i,SUM(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 341 +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 342 +SELECT i,SUM(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 343 +SELECT i,SUM(v::money) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1.10'),(2,'2.20'),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 344 +SELECT i,SUM(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 345 +SELECT i,SUM(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.1),(2,2.2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 346 +SELECT SUM(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.01),(2,2),(3,3)) v(i,n) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 347 +SELECT i,COUNT(v) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 348 +SELECT i,COUNT(*) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 349 +SELECT VAR_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 350 +SELECT VAR_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 351 +SELECT VAR_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 352 +SELECT VAR_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +== 353 +SELECT VAR_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 354 +SELECT VAR_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 355 +SELECT VAR_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 356 +SELECT VAR_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +== 357 +SELECT VARIANCE(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 358 +SELECT VARIANCE(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 359 +SELECT VARIANCE(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 360 +SELECT VARIANCE(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +== 361 +SELECT STDDEV_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +== 362 +SELECT STDDEV_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +== 363 +SELECT STDDEV_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +== 364 +SELECT STDDEV_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +== 365 +SELECT STDDEV_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 366 +SELECT STDDEV_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 367 +SELECT STDDEV_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 368 +SELECT STDDEV_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +== 369 +SELECT STDDEV(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +== 370 +SELECT STDDEV(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +== 371 +SELECT STDDEV(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +== 372 +SELECT STDDEV(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +== 373 +-- test that inverse transition functions work with various frame options +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 374 +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 375 +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,3),(4,4)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 376 +-- ensure aggregate over numeric properly recovers from NaN values +SELECT a, b, + SUM(b) OVER(ORDER BY A ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +FROM (VALUES(1,1::numeric),(2,2),(3,'NaN'),(4,3),(5,4)) t(a,b) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 377 +-- It might be tempting for someone to add an inverse trans function for +-- float and double precision. This should not be done as it can give incorrect +-- results. This test should fail if anyone ever does this without thinking too +-- hard about it. +SELECT to_char(SUM(n::float8) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),'999999999999999999999D9') + FROM (VALUES(1,1e20),(2,1)) n(i,n) +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 378 +SELECT i, b, bool_and(b) OVER w, bool_or(b) OVER w + FROM (VALUES (1,true), (2,true), (3,false), (4,false), (5,true)) v(i,b) + WINDOW w AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) +-- +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +== 379 +|-- +-- Test WindowAgg costing takes into account the number of rows that need to +-- be fetched before the first row can be output. +|-- + +-- Ensure we get a cheap start up plan as the WindowAgg can output the first +-- row after reading 1 row from the join. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER (ORDER BY t1.unique1) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 380 +-- Ensure we get a cheap total plan. Lack of ORDER BY in the WindowClause +-- means that all rows must be read from the join, so a cheap startup plan +-- isn't a good choice. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER () +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +WHERE t2.two = 1 +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t2" column="two" +STMT: ExplainStmt +STMT: SelectStmt +== 381 +-- Ensure we get a cheap total plan. This time use UNBOUNDED FOLLOWING, which +-- needs to read all join rows to output the first WindowAgg row. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 382 +-- Ensure we get a cheap total plan. This time use 10000 FOLLOWING so we need +-- to read all join rows. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND 10000 FOLLOWING) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 383 +-- Tests for problems with failure to walk or mutate expressions +-- within window frame clauses. + +-- test walker (fails with collation error if expressions are not walked) +SELECT array_agg(i) OVER w + FROM generate_series(1,5) i +WINDOW w AS (ORDER BY i ROWS BETWEEN (('foo' < 'foobar')::integer) PRECEDING AND CURRENT ROW) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 384 +-- test mutator (fails when inlined if expressions are not mutated) +CREATE FUNCTION pg_temp.f(group_size BIGINT) RETURNS SETOF integer[] +AS $$ + SELECT array_agg(s) OVER w + FROM generate_series(1,5) s + WINDOW w AS (ORDER BY s ROWS BETWEEN CURRENT ROW AND GROUP_SIZE FOLLOWING) +$$ LANGUAGE SQL STABLE +-- +FUNCTION: name="pg_temp.f" function="f" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +== 385 +EXPLAIN (costs off) SELECT * FROM pg_temp.f(2) +-- +FUNCTION: name="pg_temp.f" function="f" schema="pg_temp" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 386 +SELECT * FROM pg_temp.f(2) +-- +FUNCTION: name="pg_temp.f" function="f" schema="pg_temp" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/with.metadata.json b/parser/testdata/summary/postgres_regress/with.metadata.json new file mode 100644 index 0000000..b24b526 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/with.metadata.json @@ -0,0 +1,297 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293" + ] +} diff --git a/parser/testdata/summary/postgres_regress/with.test b/parser/testdata/summary/postgres_regress/with.test new file mode 100644 index 0000000..a558ffb --- /dev/null +++ b/parser/testdata/summary/postgres_regress/with.test @@ -0,0 +1,3310 @@ +== 001 +|-- +-- Tests for common table expressions (WITH query, ... SELECT ...) +|-- + +-- Basic WITH +WITH q1(x,y) AS (SELECT 1,2) +SELECT * FROM q1, q1 AS q2 +-- +ALIAS: "q2"="q1" +CTE: "q1" +STMT: SelectStmt +== 002 +-- Multiple uses are evaluated only once +SELECT count(*) FROM ( + WITH q1(x) AS (SELECT random() FROM generate_series(1, 5)) + SELECT * FROM q1 + UNION + SELECT * FROM q1 +) ss +-- +CTE: "q1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +== 003 +-- WITH RECURSIVE + +-- sum of 1..100 +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t +-- +CTE: "t" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 004 +WITH RECURSIVE t(n) AS ( + SELECT (VALUES(1)) +UNION ALL + SELECT n+1 FROM t WHERE n < 5 +) +SELECT * FROM t +-- +CTE: "t" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 005 +-- UNION DISTINCT requires hashable type +WITH RECURSIVE t(n) AS ( + VALUES ('01'::varbit) +UNION + SELECT n || '10'::varbit FROM t WHERE n < '100'::varbit +) +SELECT n FROM t +-- +CTE: "t" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 006 +-- recursive view +CREATE RECURSIVE VIEW nums (n) AS + VALUES (1) +UNION ALL + SELECT n+1 FROM nums WHERE n < 5 +-- +CTE: "nums" +FILTER: schema="" table="" column="n" +STMT: ViewStmt +STMT: SelectStmt +== 007 +SELECT * FROM nums +-- +TABLE: name="nums" schema="" table="nums" ctx=Select +STMT: SelectStmt +== 008 +CREATE OR REPLACE RECURSIVE VIEW nums (n) AS + VALUES (1) +UNION ALL + SELECT n+1 FROM nums WHERE n < 6 +-- +CTE: "nums" +FILTER: schema="" table="" column="n" +STMT: ViewStmt +STMT: SelectStmt +== 009 +SELECT * FROM nums +-- +TABLE: name="nums" schema="" table="nums" ctx=Select +STMT: SelectStmt +== 010 +-- This is an infinite loop with UNION ALL, but not with UNION +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT 10-n FROM t) +SELECT * FROM t +-- +CTE: "t" +STMT: SelectStmt +== 011 +-- This'd be an infinite loop, but outside query reads only as much as needed +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10 +-- +CTE: "t" +STMT: SelectStmt +== 012 +-- UNION case should have same property +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10 +-- +CTE: "t" +STMT: SelectStmt +== 013 +-- Test behavior with an unknown-type literal in the WITH +WITH q AS (SELECT 'foo' AS x) +SELECT x, pg_typeof(x) FROM q +-- +CTE: "q" +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +== 014 +WITH RECURSIVE t(n) AS ( + SELECT 'foo' +UNION ALL + SELECT n || ' bar' FROM t WHERE length(n) < 20 +) +SELECT n, pg_typeof(n) FROM t +-- +CTE: "t" +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 015 +-- In a perfect world, this would work and resolve the literal as int ... +-- but for now, we have to be content with resolving to text too soon. +WITH RECURSIVE t(n) AS ( + SELECT '7' +UNION ALL + SELECT n+1 FROM t WHERE n < 10 +) +SELECT n, pg_typeof(n) FROM t +-- +CTE: "t" +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 016 +-- Deeply nested WITH caused a list-munging problem in v13 +-- Detection of cross-references and self-references +WITH RECURSIVE w1(c1) AS + (WITH w2(c2) AS + (WITH w3(c3) AS + (WITH w4(c4) AS + (WITH w5(c5) AS + (WITH RECURSIVE w6(c6) AS + (WITH w6(c6) AS + (WITH w8(c8) AS + (SELECT 1) + SELECT * FROM w8) + SELECT * FROM w6) + SELECT * FROM w6) + SELECT * FROM w5) + SELECT * FROM w4) + SELECT * FROM w3) + SELECT * FROM w2) +SELECT * FROM w1 +-- +CTE: "w1" +CTE: "w2" +CTE: "w3" +CTE: "w4" +CTE: "w5" +CTE: "w6" +CTE: "w6" +CTE: "w8" +STMT: SelectStmt +== 017 +-- Detection of invalid self-references +WITH RECURSIVE outermost(x) AS ( + SELECT 1 + UNION (WITH innermost1 AS ( + SELECT 2 + UNION (WITH innermost2 AS ( + SELECT 3 + UNION (WITH innermost3 AS ( + SELECT 4 + UNION (WITH innermost4 AS ( + SELECT 5 + UNION (WITH innermost5 AS ( + SELECT 6 + UNION (WITH innermost6 AS + (SELECT 7) + SELECT * FROM innermost6)) + SELECT * FROM innermost5)) + SELECT * FROM innermost4)) + SELECT * FROM innermost3)) + SELECT * FROM innermost2)) + SELECT * FROM outermost + UNION SELECT * FROM innermost1) + ) + SELECT * FROM outermost ORDER BY 1 +-- +CTE: "outermost" +CTE: "innermost1" +CTE: "innermost2" +CTE: "innermost3" +CTE: "innermost4" +CTE: "innermost5" +CTE: "innermost6" +STMT: SelectStmt +== 018 +|-- +-- Some examples with a tree +|-- +-- department structure represented here is as follows: +|-- +-- ROOT-+->A-+->B-+->C +-- | | +-- | +->D-+->F +-- +->E-+->G + +CREATE TEMP TABLE department ( + id INTEGER PRIMARY KEY, -- department ID + parent_department INTEGER REFERENCES department, -- upper department ID + name TEXT -- department name +) +-- +TABLE: name="department" schema="" table="department" ctx=DDL +STMT: CreateStmt +== 019 +INSERT INTO department VALUES (0, NULL, 'ROOT') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 020 +INSERT INTO department VALUES (1, 0, 'A') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 021 +INSERT INTO department VALUES (2, 1, 'B') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 022 +INSERT INTO department VALUES (3, 2, 'C') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 023 +INSERT INTO department VALUES (4, 2, 'D') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 024 +INSERT INTO department VALUES (5, 0, 'E') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 025 +INSERT INTO department VALUES (6, 4, 'F') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 026 +INSERT INTO department VALUES (7, 5, 'G') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 027 +-- extract all departments under 'A'. Result should be A, B, C, D and F +WITH RECURSIVE subdepartment AS +( + -- non recursive term + SELECT name as root_name, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: SelectStmt +== 028 +-- extract all departments under 'A' with "level" number +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: SelectStmt +== 029 +-- extract all departments under 'A' with "level" number. +-- Only shows level 2 or more +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment WHERE level >= 2 ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="level" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: SelectStmt +== 030 +-- "RECURSIVE" is ignored if the query has no self-reference +WITH RECURSIVE subdepartment AS +( + -- note lack of recursive UNION structure + SELECT * FROM department WHERE name = 'A' +) +SELECT * FROM subdepartment ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +STMT: SelectStmt +== 031 +-- inside subqueries +SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 500 + ) + SELECT * FROM t) AS t WHERE n < ( + SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 100 + ) + SELECT * FROM t WHERE n < 50000 + ) AS t WHERE n < 100) +-- +CTE: "t" +CTE: "t" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 032 +-- use same CTE twice at different subquery levels +WITH q1(x,y) AS ( + SELECT hundred, sum(ten) FROM tenk1 GROUP BY hundred + ) +SELECT count(*) FROM q1 WHERE y > (SELECT sum(y)/100 FROM q1 qsub) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "qsub"="q1" +CTE: "q1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="y" +STMT: SelectStmt +== 033 +-- via a VIEW +CREATE TEMPORARY VIEW vsubdepartment AS + WITH RECURSIVE subdepartment AS + ( + -- non recursive term + SELECT * FROM department WHERE name = 'A' + UNION ALL + -- recursive term + SELECT d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id + ) + SELECT * FROM subdepartment +-- +TABLE: name="vsubdepartment" schema="" table="vsubdepartment" ctx=DDL +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: ViewStmt +STMT: SelectStmt +== 034 +SELECT * FROM vsubdepartment ORDER BY name +-- +TABLE: name="vsubdepartment" schema="" table="vsubdepartment" ctx=Select +STMT: SelectStmt +== 035 +-- Check reverse listing +SELECT pg_get_viewdef('vsubdepartment'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 036 +SELECT pg_get_viewdef('vsubdepartment'::regclass, true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 037 +-- Another reverse-listing example +CREATE VIEW sums_1_100 AS +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t +-- +TABLE: name="sums_1_100" schema="" table="sums_1_100" ctx=DDL +CTE: "t" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: ViewStmt +STMT: SelectStmt +== 038 +-- corner case in which sub-WITH gets initialized first +with recursive q as ( + select * from department + union all + (with x as (select * from q) + select * from x) + ) +select * from q limit 24 +-- +TABLE: name="department" schema="" table="department" ctx=Select +CTE: "q" +CTE: "x" +STMT: SelectStmt +== 039 +with recursive q as ( + select * from department + union all + (with recursive x as ( + select * from department + union all + (select * from q union all select * from x) + ) + select * from x) + ) +select * from q limit 32 +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +CTE: "q" +CTE: "x" +STMT: SelectStmt +== 040 +-- 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 +-- +CTE: "t" +STMT: SelectStmt +== 041 +|-- +-- different tree example +|-- +CREATE TEMPORARY TABLE tree( + id INTEGER PRIMARY KEY, + parent_id INTEGER REFERENCES tree(id) +) +-- +TABLE: name="tree" schema="" table="tree" ctx=DDL +STMT: CreateStmt +== 042 +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) +-- +TABLE: name="tree" schema="" table="tree" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 043 +|-- +-- 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 +-- +TABLE: name="tree" schema="" table="tree" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +CTE: "t" +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +STMT: SelectStmt +== 044 +-- 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 +-- +TABLE: name="tree" schema="" table="tree" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +CTE: "t" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +STMT: SelectStmt +== 045 +-- 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) +-- +TABLE: name="tree" schema="" table="tree" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +CTE: "t" +STMT: SelectStmt +== 046 +CREATE TEMP TABLE duplicates (a INT NOT NULL) +-- +TABLE: name="duplicates" schema="" table="duplicates" ctx=DDL +STMT: CreateStmt +== 047 +INSERT INTO duplicates VALUES(1), (1) +-- +TABLE: name="duplicates" schema="" table="duplicates" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +-- Try out a recursive UNION case where the non-recursive part's table slot +-- uses TTSOpsBufferHeapTuple and contains duplicate rows. +WITH RECURSIVE cte (a) as ( + SELECT a FROM duplicates + UNION + SELECT a FROM cte +) +SELECT a FROM cte +-- +TABLE: name="duplicates" schema="" table="duplicates" ctx=Select +CTE: "cte" +STMT: SelectStmt +== 049 +-- test that column statistics from a materialized CTE are available +-- to upper planner (otherwise, we'd get a stupider plan) +explain (costs off) +with x as materialized (select unique1 from tenk1 b) +select count(*) from tenk1 a + where unique1 in (select * from x) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 050 +explain (costs off) +with x as materialized (insert into tenk1 default values returning unique1) +select count(*) from tenk1 a + where unique1 in (select * from x) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=DML +ALIAS: "a"="tenk1" +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +STMT: InsertStmt +== 051 +-- test that pathkeys from a materialized CTE are propagated up to the +-- outer query +explain (costs off) +with x as materialized (select unique1 from tenk1 b order by unique1) +select count(*) from tenk1 a + where unique1 in (select * from x) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +== 052 +-- SEARCH clause + +create temp table graph0( f int, t int, label text ) +-- +TABLE: name="graph0" schema="" table="graph0" ctx=DDL +STMT: CreateStmt +== 053 +insert into graph0 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') +-- +TABLE: name="graph0" schema="" table="graph0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 054 +explain (verbose, costs off) +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 055 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 056 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union distinct + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 057 +explain (verbose, costs off) +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 058 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 059 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union distinct + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 060 +-- a constant initial value causes issues for EXPLAIN +explain (verbose, costs off) +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search depth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: ExplainStmt +STMT: SelectStmt +== 061 +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search depth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: SelectStmt +== 062 +explain (verbose, costs off) +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search breadth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: ExplainStmt +STMT: SelectStmt +== 063 +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search breadth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: SelectStmt +== 064 +-- various syntax errors +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by foo, tar set seq +select * from search_graph +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 065 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set label +select * from search_graph +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 066 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t, f set seq +select * from search_graph +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 067 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 068 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + (select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t) +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 069 +-- check that we distinguish same CTE name used at different levels +-- (this case could be supported, perhaps, but it isn't today) +with recursive x(col) as ( + select 1 + union + (with x as (select * from x) + select * from x) +) search depth first by col set seq +select * from x +-- +CTE: "x" +CTE: "x" +STMT: SelectStmt +== 070 +-- test ruleutils and view expansion +create temp view v_search as +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select f, t, label from search_graph +-- +TABLE: name="v_search" schema="" table="v_search" ctx=DDL +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ViewStmt +STMT: SelectStmt +== 071 +select pg_get_viewdef('v_search') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 072 +select * from v_search +-- +TABLE: name="v_search" schema="" table="v_search" ctx=Select +STMT: SelectStmt +== 073 +|-- +-- test cycle detection +|-- +create temp table graph( f int, t int, label text ) +-- +TABLE: name="graph" schema="" table="graph" ctx=DDL +STMT: CreateStmt +== 074 +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') +-- +TABLE: name="graph" schema="" table="graph" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 075 +with recursive search_graph(f, t, label, is_cycle, path) as ( + select *, false, array[row(g.f, g.t)] from graph g + union all + select g.*, row(g.f, g.t) = any(path), path || row(g.f, g.t) + from graph g, search_graph sg + where g.f = sg.t and not is_cycle +) +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +== 076 +-- UNION DISTINCT exercises row type hashing support +with recursive search_graph(f, t, label, is_cycle, path) as ( + select *, false, array[row(g.f, g.t)] from graph g + union distinct + select g.*, row(g.f, g.t) = any(path), path || row(g.f, g.t) + from graph g, search_graph sg + where g.f = sg.t and not is_cycle +) +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +== 077 +-- ordering by the path column has same effect as SEARCH DEPTH FIRST +with recursive search_graph(f, t, label, is_cycle, path) as ( + select *, false, array[row(g.f, g.t)] from graph g + union all + select g.*, row(g.f, g.t) = any(path), path || row(g.f, g.t) + from graph g, search_graph sg + where g.f = sg.t and not is_cycle +) +select * from search_graph order by path +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +== 078 +-- CYCLE clause + +explain (verbose, costs off) +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ExplainStmt +STMT: SelectStmt +== 079 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 080 +with recursive search_graph(f, t, label) as ( + select * from graph g + union distinct + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to 'Y' default 'N' using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 081 +explain (verbose, costs off) +with recursive test as ( + select 0 as x + union all + select (x + 1) % 10 + from test +) cycle x set is_cycle using path +select * from test +-- +CTE: "test" +STMT: ExplainStmt +STMT: SelectStmt +== 082 +with recursive test as ( + select 0 as x + union all + select (x + 1) % 10 + from test +) cycle x set is_cycle using path +select * from test +-- +CTE: "test" +STMT: SelectStmt +== 083 +with recursive test as ( + select 0 as x + union all + select (x + 1) % 10 + from test + where not is_cycle -- redundant, but legal +) cycle x set is_cycle using path +select * from test +-- +CTE: "test" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +== 084 +-- multiple CTEs +with recursive +graph(f, t, label) as ( + 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') +), +search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to true default false using path +select f, t, label from search_graph +-- +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 085 +-- star expansion +with recursive a as ( + select 1 as b + union all + select * from a +) cycle b set c using p +select * from a +-- +CTE: "a" +STMT: SelectStmt +== 086 +-- search+cycle +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq + cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 087 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq + cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 088 +-- various syntax errors +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle foo, tar set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 089 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to true default 55 using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 090 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to point '(1,1)' default point '(0,0)' using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 091 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set label to true default false using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 092 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to true default false using label +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 093 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set foo to true default false using foo +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 094 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t, f set is_cycle to true default false using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 095 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search depth first by f, t set foo + cycle f, t set foo to true default false using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 096 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search depth first by f, t set foo + cycle f, t set is_cycle to true default false using foo +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +== 097 +-- test ruleutils and view expansion +create temp view v_cycle1 as +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle using path +select f, t, label from search_graph +-- +TABLE: name="v_cycle1" schema="" table="v_cycle1" ctx=DDL +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ViewStmt +STMT: SelectStmt +== 098 +create temp view v_cycle2 as +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to 'Y' default 'N' using path +select f, t, label from search_graph +-- +TABLE: name="v_cycle2" schema="" table="v_cycle2" ctx=DDL +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ViewStmt +STMT: SelectStmt +== 099 +select pg_get_viewdef('v_cycle1') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 100 +select pg_get_viewdef('v_cycle2') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +== 101 +select * from v_cycle1 +-- +TABLE: name="v_cycle1" schema="" table="v_cycle1" ctx=Select +STMT: SelectStmt +== 102 +select * from v_cycle2 +-- +TABLE: name="v_cycle2" schema="" table="v_cycle2" ctx=Select +STMT: SelectStmt +== 103 +|-- +-- 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 +-- +CTE: "y" +CTE: "x" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 104 +-- 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 +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 105 +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) +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 106 +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) +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 107 +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 +-- +CTE: "x" +CTE: "y" +CTE: "z" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 108 +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 +-- +CTE: "x" +CTE: "y" +CTE: "z" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 109 +|-- +-- Test WITH attached to a data-modifying statement +|-- + +CREATE TEMPORARY TABLE y (a INTEGER) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateStmt +== 110 +INSERT INTO y SELECT generate_series(1, 10) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 111 +WITH t AS ( + SELECT a FROM y +) +INSERT INTO y +SELECT a+20 FROM t RETURNING * +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "t" +STMT: InsertStmt +STMT: SelectStmt +== 112 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 113 +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 +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "t" +STMT: UpdateStmt +STMT: SelectStmt +== 114 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 115 +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 +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +FILTER: schema="" table="" column="a" +STMT: DeleteStmt +STMT: SelectStmt +== 116 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 117 +DROP TABLE y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +== 118 +|-- +-- error cases +|-- + +WITH x(n, b) AS (SELECT 1) +SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 119 +-- INTERSECT +WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 120 +WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 121 +-- EXCEPT +WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 122 +WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 123 +-- no non-recursive term +WITH RECURSIVE x(n) AS (SELECT n FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 124 +-- 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 +-- +CTE: "x" +STMT: SelectStmt +== 125 +-- allow this, because we historically have +WITH RECURSIVE x(n) AS ( + WITH x1 AS (SELECT 1 AS n) + SELECT 0 + UNION + SELECT * FROM x1) + SELECT * FROM x +-- +CTE: "x" +CTE: "x1" +STMT: SelectStmt +== 126 +-- but this should be rejected +WITH RECURSIVE x(n) AS ( + WITH x1 AS (SELECT 1 FROM x) + SELECT 0 + UNION + SELECT * FROM x1) + SELECT * FROM x +-- +CTE: "x" +CTE: "x1" +STMT: SelectStmt +== 127 +-- and this too +WITH RECURSIVE x(n) AS ( + (WITH x1 AS (SELECT 1 FROM x) SELECT * FROM x1) + UNION + SELECT 0) + SELECT * FROM x +-- +CTE: "x" +CTE: "x1" +STMT: SelectStmt +== 128 +-- and this +WITH RECURSIVE x(n) AS ( + SELECT 0 UNION SELECT 1 + ORDER BY (SELECT n FROM x)) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 129 +-- and this +WITH RECURSIVE x(n) AS ( + WITH sub_cte AS (SELECT * FROM x) + DELETE FROM graph RETURNING f) + SELECT * FROM x +-- +TABLE: name="graph" schema="" table="graph" ctx=DML +CTE: "x" +CTE: "sub_cte" +STMT: SelectStmt +STMT: DeleteStmt +== 130 +CREATE TEMPORARY TABLE y (a INTEGER) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateStmt +== 131 +INSERT INTO y SELECT generate_series(1, 10) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 132 +-- 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 +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 133 +-- 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 +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 134 +-- 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 +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 135 +-- subquery +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x + WHERE n IN (SELECT * FROM x)) + SELECT * FROM x +-- +CTE: "x" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +== 136 +-- aggregate functions +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x) + SELECT * FROM x +-- +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 137 +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x) + SELECT * FROM x +-- +CTE: "x" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +== 138 +-- ORDER BY +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 139 +-- LIMIT/OFFSET +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 140 +-- FOR UPDATE +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +== 141 +-- 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 +-- +CTE: "x" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 142 +-- 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 +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 143 +-- 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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 144 +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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 145 +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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 146 +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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 147 +-- 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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 148 +-- 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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +== 149 +-- disallow OLD/NEW reference in CTE +CREATE TEMPORARY TABLE x (n integer) +-- +TABLE: name="x" schema="" table="x" ctx=DDL +STMT: CreateStmt +== 150 +CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD + WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t +-- +TABLE: name="x" schema="" table="x" ctx=DDL +STMT: RuleStmt +== 151 +|-- +-- test for bug #4902 +|-- +with cte(foo) as ( values(42) ) values((select foo from cte)) +-- +CTE: "cte" +STMT: SelectStmt +== 152 +with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q +-- +CTE: "cte" +STMT: SelectStmt +== 153 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "cte" +STMT: SelectStmt +== 154 +select ( with cte(foo) as ( values(f1) ) + values((select foo from cte)) ) +from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "cte" +STMT: SelectStmt +== 155 +|-- +-- test for bug #19055: interaction of WITH with aggregates +|-- +-- The reference to cte1 must determine the aggregate's level, +-- even though it contains no Vars referencing cte1 +explain (verbose, costs off) +select f1, (with cte1(x,y) as (select 1,2) + select count((select i4.f1 from cte1))) as ss +from int4_tbl i4 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +CTE: "cte1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 156 +select f1, (with cte1(x,y) as (select 1,2) + select count((select i4.f1 from cte1))) as ss +from int4_tbl i4 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +CTE: "cte1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +== 157 +|-- +-- 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 +-- +CTE: "t" +CTE: "s" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +STMT: SelectStmt +== 158 +|-- +-- 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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +== 159 +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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +== 160 +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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +== 161 +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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +== 162 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +CTE: "a" +CTE: "b" +CTE: "c" +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="b" column="id" +FILTER: schema="" table="a" column="id" +STMT: SelectStmt +== 163 +|-- +-- 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' + ) + SELECT * FROM first_remaining + UNION ALL SELECT * FROM effect + ) + ) +SELECT * FROM iter +-- +ALIAS: "e"="first_remaining" +CTE: "tab" +CTE: "iter" +CTE: "remaining" +CTE: "first_remaining" +CTE: "effect" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="tab" column="id_key" +FILTER: schema="" table="iter" column="id_key" +FILTER: schema="" table="" column="id_key" +FILTER: schema="" table="" column="min" +FILTER: schema="" table="e" column="row_type" +STMT: SelectStmt +== 164 +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 ( + 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' + ) + SELECT * FROM first_remaining + UNION ALL SELECT * FROM effect + ) + ) +SELECT * FROM iter +-- +ALIAS: "e"="first_remaining" +CTE: "tab" +CTE: "iter" +CTE: "remaining" +CTE: "first_remaining" +CTE: "effect" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="tab" column="id_key" +FILTER: schema="" table="iter" column="id_key" +FILTER: schema="" table="" column="id_key" +FILTER: schema="" table="" column="min" +FILTER: schema="" table="e" column="row_type" +STMT: SelectStmt +== 165 +|-- +-- Data-modifying statements in WITH +|-- + +-- INSERT ... RETURNING +WITH t AS ( + INSERT INTO y + VALUES + (11), + (12), + (13), + (14), + (15), + (16), + (17), + (18), + (19), + (20) + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 166 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 167 +-- UPDATE ... RETURNING +WITH t AS ( + UPDATE y + SET a=a+1 + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: UpdateStmt +== 168 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 169 +-- DELETE ... RETURNING +WITH t AS ( + DELETE FROM y + WHERE a <= 10 + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: DeleteStmt +== 170 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 171 +-- forward reference +WITH RECURSIVE t AS ( + INSERT INTO y + SELECT a+5 FROM t2 WHERE a > 5 + RETURNING * +), t2 AS ( + UPDATE y SET a=a-11 RETURNING * +) +SELECT * FROM t +UNION ALL +SELECT * FROM t2 +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +CTE: "t2" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +STMT: InsertStmt +STMT: UpdateStmt +== 172 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 173 +-- unconditional DO INSTEAD rule +CREATE RULE y_rule AS ON DELETE TO y DO INSTEAD + INSERT INTO y VALUES(42) RETURNING * +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +== 174 +WITH t AS ( + DELETE FROM y RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: DeleteStmt +== 175 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 176 +DROP RULE y_rule ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +== 177 +-- check merging of outer CTE with CTE in a rule action +CREATE TEMP TABLE bug6051 AS + select i from generate_series(1,3) as t(i) +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 178 +SELECT * FROM bug6051 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=Select +STMT: SelectStmt +== 179 +WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) +INSERT INTO bug6051 SELECT * FROM t1 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +== 180 +SELECT * FROM bug6051 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=Select +STMT: SelectStmt +== 181 +CREATE TEMP TABLE bug6051_2 (i int) +-- +TABLE: name="bug6051_2" schema="" table="bug6051_2" ctx=DDL +STMT: CreateStmt +== 182 +CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD + INSERT INTO bug6051_2 + VALUES(NEW.i) +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DDL +STMT: RuleStmt +== 183 +WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) +INSERT INTO bug6051 SELECT * FROM t1 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +== 184 +SELECT * FROM bug6051 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=Select +STMT: SelectStmt +== 185 +SELECT * FROM bug6051_2 +-- +TABLE: name="bug6051_2" schema="" table="bug6051_2" ctx=Select +STMT: SelectStmt +== 186 +-- check INSERT ... SELECT rule actions are disallowed on commands +-- that have modifyingCTEs +CREATE OR REPLACE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD + INSERT INTO bug6051_2 + SELECT NEW.i +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DDL +STMT: RuleStmt +== 187 +WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) +INSERT INTO bug6051 SELECT * FROM t1 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +== 188 +-- silly example to verify that hasModifyingCTE flag is propagated +CREATE TEMP TABLE bug6051_3 AS + SELECT a FROM generate_series(11,13) AS a +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 189 +CREATE RULE bug6051_3_ins AS ON INSERT TO bug6051_3 DO INSTEAD + SELECT i FROM bug6051_2 +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DDL +STMT: RuleStmt +== 190 +BEGIN +-- +STMT: TransactionStmt +== 191 +SET LOCAL debug_parallel_query = on +-- +STMT: VariableSetStmt +== 192 +WITH t1 AS ( DELETE FROM bug6051_3 RETURNING * ) + INSERT INTO bug6051_3 SELECT * FROM t1 +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DML +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +== 193 +COMMIT +-- +STMT: TransactionStmt +== 194 +SELECT * FROM bug6051_3 +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=Select +STMT: SelectStmt +== 195 +-- check case where CTE reference is removed due to optimization +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 196 +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: SelectStmt +== 197 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +== 198 +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: SelectStmt +== 199 +-- a truly recursive CTE in the same list +WITH RECURSIVE t(a) AS ( + SELECT 0 + UNION ALL + SELECT a+1 FROM t WHERE a+1 < 5 +), t2 as ( + INSERT INTO y + SELECT * FROM t RETURNING * +) +SELECT * FROM t2 JOIN y USING (a) ORDER BY a +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +CTE: "t2" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +STMT: InsertStmt +== 200 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 201 +-- data-modifying WITH in a modifying statement +WITH t AS ( + DELETE FROM y + WHERE a <= 10 + RETURNING * +) +INSERT INTO y SELECT -a FROM t RETURNING * +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +== 202 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 203 +-- check that WITH query is run to completion even if outer query isn't +WITH t AS ( + UPDATE y SET a = a * 100 RETURNING * +) +SELECT * FROM t LIMIT 10 +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: UpdateStmt +== 204 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 205 +-- data-modifying WITH containing INSERT...ON CONFLICT DO UPDATE +CREATE TABLE withz AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i +-- +TABLE: name="withz" schema="" table="withz" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 206 +ALTER TABLE withz ADD UNIQUE (k) +-- +TABLE: name="withz" schema="" table="withz" ctx=DDL +STMT: AlterTableStmt +== 207 +WITH t AS ( + INSERT INTO withz SELECT i, 'insert' + FROM generate_series(0, 16) i + ON CONFLICT (k) DO UPDATE SET v = withz.v || ', now update' + RETURNING * +) +SELECT * FROM t JOIN y ON t.k = y.a ORDER BY a, k +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "t" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +STMT: InsertStmt +== 208 +-- Test EXCLUDED.* reference within CTE +WITH aa AS ( + INSERT INTO withz VALUES(1, 5) ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v + WHERE withz.k != EXCLUDED.k + RETURNING * +) +SELECT * FROM aa +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +STMT: SelectStmt +STMT: InsertStmt +== 209 +-- New query/snapshot demonstrates side-effects of previous query. +SELECT * FROM withz ORDER BY k +-- +TABLE: name="withz" schema="" table="withz" ctx=Select +STMT: SelectStmt +== 210 +|-- +-- Ensure subqueries within the update clause work, even if they +-- reference outside values +|-- +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 211 +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = ' update' WHERE withz.k = (SELECT a FROM aa) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +STMT: InsertStmt +STMT: SelectStmt +== 212 +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 213 +WITH aa AS (SELECT 'a' a, 'b' b UNION ALL SELECT 'a' a, 'b' b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 'a' LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 214 +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, (SELECT b || ' insert' FROM aa WHERE a = 1 )) +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +== 215 +-- Update a row more than once, in different parts of a wCTE. That is +-- an allowed, presumably very rare, edge case, but since it was +-- broken in the past, having a test seems worthwhile. +WITH simpletup AS ( + SELECT 2 k, 'Green' v), +upsert_cte AS ( + INSERT INTO withz VALUES(2, 'Blue') ON CONFLICT (k) DO + UPDATE SET (k, v) = (SELECT k, v FROM simpletup WHERE simpletup.k = withz.k) + RETURNING k, v) +INSERT INTO withz VALUES(2, 'Red') ON CONFLICT (k) DO +UPDATE SET (k, v) = (SELECT k, v FROM upsert_cte WHERE upsert_cte.k = withz.k) +RETURNING k, v +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "simpletup" +CTE: "upsert_cte" +FILTER: schema="" table="upsert_cte" column="k" +FILTER: schema="" table="withz" column="k" +FILTER: schema="" table="upsert_cte" column="k" +FILTER: schema="" table="withz" column="k" +FILTER: schema="" table="simpletup" column="k" +FILTER: schema="" table="withz" column="k" +FILTER: schema="" table="simpletup" column="k" +FILTER: schema="" table="withz" column="k" +STMT: InsertStmt +STMT: SelectStmt +== 216 +DROP TABLE withz +-- +TABLE: name="withz" schema="" table="withz" ctx=DDL +STMT: DropStmt +== 217 +-- WITH referenced by MERGE statement +CREATE TABLE m AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i +-- +TABLE: name="m" schema="" table="m" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 218 +ALTER TABLE m ADD UNIQUE (k) +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: AlterTableStmt +== 219 +WITH RECURSIVE cte_basic AS (SELECT 1 a, 'cte_basic val' b) +MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_basic" +FILTER: schema="" table="cte_basic" column="a" +FILTER: schema="" table="m" column="k" +STMT: MergeStmt +STMT: SelectStmt +== 220 +-- Basic: +WITH cte_basic AS MATERIALIZED (SELECT 1 a, 'cte_basic val' b) +MERGE INTO m USING (select 0 k, 'merge source SubPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_basic" +FILTER: schema="" table="cte_basic" column="a" +FILTER: schema="" table="m" column="k" +STMT: MergeStmt +STMT: SelectStmt +== 221 +-- Examine +SELECT * FROM m where k = 0 +-- +TABLE: name="m" schema="" table="m" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +== 222 +-- See EXPLAIN output for same query: +EXPLAIN (VERBOSE, COSTS OFF) +WITH cte_basic AS MATERIALIZED (SELECT 1 a, 'cte_basic val' b) +MERGE INTO m USING (select 0 k, 'merge source SubPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_basic" +FILTER: schema="" table="cte_basic" column="a" +FILTER: schema="" table="m" column="k" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 223 +-- InitPlan +WITH cte_init AS MATERIALIZED (SELECT 1 a, 'cte_init val' b) +MERGE INTO m USING (select 1 k, 'merge source InitPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_init" +FILTER: schema="" table="" column="a" +STMT: MergeStmt +STMT: SelectStmt +== 224 +-- Examine +SELECT * FROM m where k = 1 +-- +TABLE: name="m" schema="" table="m" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +== 225 +-- See EXPLAIN output for same query: +EXPLAIN (VERBOSE, COSTS OFF) +WITH cte_init AS MATERIALIZED (SELECT 1 a, 'cte_init val' b) +MERGE INTO m USING (select 1 k, 'merge source InitPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_init" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 226 +-- MERGE source comes from CTE: +WITH merge_source_cte AS MATERIALIZED (SELECT 15 a, 'merge_source_cte val' b) +MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a +WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) +WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "merge_source_cte" +FILTER: schema="" table="" column="a" +STMT: MergeStmt +STMT: SelectStmt +== 227 +-- Examine +SELECT * FROM m where k = 15 +-- +TABLE: name="m" schema="" table="m" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +== 228 +-- See EXPLAIN output for same query: +EXPLAIN (VERBOSE, COSTS OFF) +WITH merge_source_cte AS MATERIALIZED (SELECT 15 a, 'merge_source_cte val' b) +MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a +WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) +WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "merge_source_cte" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +== 229 +DROP TABLE m +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: DropStmt +== 230 +-- check that run to completion happens in proper ordering + +TRUNCATE TABLE y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: TruncateStmt +== 231 +INSERT INTO y SELECT generate_series(1, 3) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 232 +CREATE TEMPORARY TABLE yy (a INTEGER) +-- +TABLE: name="yy" schema="" table="yy" ctx=DDL +STMT: CreateStmt +== 233 +WITH RECURSIVE t1 AS ( + INSERT INTO y SELECT * FROM y RETURNING * +), t2 AS ( + INSERT INTO yy SELECT * FROM t1 RETURNING * +) +SELECT 1 +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="yy" schema="" table="yy" ctx=DML +CTE: "t1" +CTE: "t2" +STMT: SelectStmt +STMT: InsertStmt +== 234 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 235 +SELECT * FROM yy +-- +TABLE: name="yy" schema="" table="yy" ctx=Select +STMT: SelectStmt +== 236 +WITH RECURSIVE t1 AS ( + INSERT INTO yy SELECT * FROM t2 RETURNING * +), t2 AS ( + INSERT INTO y SELECT * FROM y RETURNING * +) +SELECT 1 +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "t1" +CTE: "t2" +STMT: SelectStmt +STMT: InsertStmt +== 237 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 238 +SELECT * FROM yy +-- +TABLE: name="yy" schema="" table="yy" ctx=Select +STMT: SelectStmt +== 239 +-- triggers + +TRUNCATE TABLE y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: TruncateStmt +== 240 +INSERT INTO y SELECT generate_series(1, 10) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +== 241 +CREATE FUNCTION y_trigger() RETURNS trigger AS $$ +begin + raise notice 'y_trigger: a = %', new.a; + return new; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="y_trigger" function="y_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 242 +CREATE TRIGGER y_trig BEFORE INSERT ON y FOR EACH ROW + EXECUTE PROCEDURE y_trigger() +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateTrigStmt +== 243 +WITH t AS ( + INSERT INTO y + VALUES + (21), + (22), + (23) + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 244 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 245 +DROP TRIGGER y_trig ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +== 246 +CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH ROW + EXECUTE PROCEDURE y_trigger() +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateTrigStmt +== 247 +WITH t AS ( + INSERT INTO y + VALUES + (31), + (32), + (33) + RETURNING * +) +SELECT * FROM t LIMIT 1 +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 248 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 249 +DROP TRIGGER y_trig ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +== 250 +CREATE OR REPLACE FUNCTION y_trigger() RETURNS trigger AS $$ +begin + raise notice 'y_trigger'; + return null; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="y_trigger" function="y_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 251 +CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH STATEMENT + EXECUTE PROCEDURE y_trigger() +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateTrigStmt +== 252 +WITH t AS ( + INSERT INTO y + VALUES + (41), + (42), + (43) + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 253 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +== 254 +DROP TRIGGER y_trig ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +== 255 +DROP FUNCTION y_trigger() +-- +FUNCTION: name="y_trigger" function="y_trigger" schema="" ctx=DDL +STMT: DropStmt +== 256 +-- WITH attached to inherited UPDATE or DELETE + +CREATE TEMP TABLE parent ( id int, val text ) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +== 257 +CREATE TEMP TABLE child1 ( ) INHERITS ( parent ) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +== 258 +CREATE TEMP TABLE child2 ( ) INHERITS ( parent ) +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateStmt +== 259 +INSERT INTO parent VALUES ( 1, 'p1' ) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 260 +INSERT INTO child1 VALUES ( 11, 'c11' ),( 12, 'c12' ) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 261 +INSERT INTO child2 VALUES ( 23, 'c21' ),( 24, 'c22' ) +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 262 +WITH rcte AS ( SELECT sum(id) AS totalid FROM parent ) +UPDATE parent SET id = id + totalid FROM rcte +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="parent" schema="" table="parent" ctx=Select +CTE: "rcte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: UpdateStmt +STMT: SelectStmt +== 263 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 264 +WITH wcte AS ( INSERT INTO child1 VALUES ( 42, 'new' ) RETURNING id AS newid ) +UPDATE parent SET id = id + newid FROM wcte +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="child1" schema="" table="child1" ctx=DML +CTE: "wcte" +STMT: UpdateStmt +STMT: InsertStmt +STMT: SelectStmt +== 265 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 266 +WITH rcte AS ( SELECT max(id) AS maxid FROM parent ) +DELETE FROM parent USING rcte WHERE id = maxid +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="parent" schema="" table="parent" ctx=Select +CTE: "rcte" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: DeleteStmt +STMT: SelectStmt +== 267 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 268 +WITH wcte AS ( INSERT INTO child2 VALUES ( 42, 'new2' ) RETURNING id AS newid ) +DELETE FROM parent USING wcte WHERE id = newid +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="child2" schema="" table="child2" ctx=DML +CTE: "wcte" +STMT: DeleteStmt +STMT: InsertStmt +STMT: SelectStmt +== 269 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +== 270 +-- check EXPLAIN VERBOSE for a wCTE with RETURNING + +EXPLAIN (VERBOSE, COSTS OFF) +WITH wcte AS ( INSERT INTO int8_tbl VALUES ( 42, 47 ) RETURNING q2 ) +DELETE FROM a_star USING wcte WHERE aa = q2 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +CTE: "wcte" +STMT: ExplainStmt +STMT: DeleteStmt +STMT: InsertStmt +STMT: SelectStmt +== 271 +-- error cases + +-- data-modifying WITH tries to use its own output +WITH RECURSIVE t AS ( + INSERT INTO y + SELECT * FROM t +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 272 +-- no RETURNING in a referenced data-modifying WITH +WITH t AS ( + INSERT INTO y VALUES(0) +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 273 +-- RETURNING tries to return its own output +WITH RECURSIVE t(action, a) AS ( + MERGE INTO y USING (VALUES (11)) v(a) ON y.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) + RETURNING merge_action(), (SELECT a FROM t) +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: MergeStmt +== 274 +-- data-modifying WITH allowed only at the top level +SELECT * FROM ( + WITH t AS (UPDATE y SET a=a+1 RETURNING *) + SELECT * FROM t +) ss +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: UpdateStmt +== 275 +-- most variants of rules aren't allowed +CREATE RULE y_rule AS ON INSERT TO y WHERE a=0 DO INSTEAD DELETE FROM y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +== 276 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 277 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +== 278 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 279 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +== 280 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 281 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO ALSO NOTIFY foo +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +== 282 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 283 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y + DO INSTEAD (NOTIFY foo; NOTIFY bar) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +== 284 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +== 285 +DROP RULE y_rule ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +== 286 +-- check that parser lookahead for WITH doesn't cause any odd behavior +create table foo (with baz) +-- +ERROR: syntax error at or near "with" +CURSORPOS: 90 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 287 +-- fail, WITH is a reserved word +create table foo (with ordinality) +-- +ERROR: syntax error at or near "with" +CURSORPOS: 52 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 288 +-- fail, WITH is a reserved word +with ordinality as (select 1 as x) select * from ordinality +-- +CTE: "ordinality" +STMT: SelectStmt +== 289 +-- check sane response to attempt to modify CTE relation +WITH with_test AS (SELECT 42) INSERT INTO with_test VALUES (1) +-- +CTE: "with_test" +STMT: InsertStmt +STMT: SelectStmt +== 290 +-- check response to attempt to modify table with same name as a CTE (perhaps +-- surprisingly it works, because CTEs don't hide tables from data-modifying +-- statements) +create temp table with_test (i int) +-- +TABLE: name="with_test" schema="" table="with_test" ctx=DDL +STMT: CreateStmt +== 291 +with with_test as (select 42) insert into with_test select * from with_test +-- +CTE: "with_test" +STMT: InsertStmt +STMT: SelectStmt +== 292 +select * from with_test +-- +TABLE: name="with_test" schema="" table="with_test" ctx=Select +STMT: SelectStmt +== 293 +drop table with_test +-- +TABLE: name="with_test" schema="" table="with_test" ctx=DDL +STMT: DropStmt diff --git a/parser/testdata/summary/postgres_regress/write_parallel.metadata.json b/parser/testdata/summary/postgres_regress/write_parallel.metadata.json new file mode 100644 index 0000000..edb706f --- /dev/null +++ b/parser/testdata/summary/postgres_regress/write_parallel.metadata.json @@ -0,0 +1,26 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022" + ] +} diff --git a/parser/testdata/summary/postgres_regress/write_parallel.test b/parser/testdata/summary/postgres_regress/write_parallel.test new file mode 100644 index 0000000..4ecb49e --- /dev/null +++ b/parser/testdata/summary/postgres_regress/write_parallel.test @@ -0,0 +1,149 @@ +== 001 +|-- +-- PARALLEL +|-- + +begin +-- +STMT: TransactionStmt +== 002 +-- encourage use of parallel plans +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +== 003 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +== 004 +set min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +== 005 +set max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +== 006 +|-- +-- Test write operations that has an underlying query that is eligible +-- for parallel plans +|-- +explain (costs off) create table parallel_write as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 007 +create table parallel_write as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 008 +drop table parallel_write +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: DropStmt +== 009 +explain (costs off) select length(stringu1) into parallel_write + from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +== 010 +select length(stringu1) into parallel_write + from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +== 011 +drop table parallel_write +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: DropStmt +== 012 +explain (costs off) create materialized view parallel_mat_view as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +== 013 +create materialized view parallel_mat_view as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +== 014 +create unique index on parallel_mat_view(length) +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +STMT: IndexStmt +== 015 +refresh materialized view parallel_mat_view +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +STMT: RefreshMatViewStmt +== 016 +refresh materialized view concurrently parallel_mat_view +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +STMT: RefreshMatViewStmt +== 017 +drop materialized view parallel_mat_view +-- +STMT: DropStmt +== 018 +prepare prep_stmt as select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +== 019 +explain (costs off) create table parallel_write as execute prep_stmt +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 020 +create table parallel_write as execute prep_stmt +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +== 021 +drop table parallel_write +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: DropStmt +== 022 +rollback +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/xid.metadata.json b/parser/testdata/summary/postgres_regress/xid.metadata.json new file mode 100644 index 0000000..7852793 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/xid.metadata.json @@ -0,0 +1,88 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084" + ] +} diff --git a/parser/testdata/summary/postgres_regress/xid.test b/parser/testdata/summary/postgres_regress/xid.test new file mode 100644 index 0000000..051bcca --- /dev/null +++ b/parser/testdata/summary/postgres_regress/xid.test @@ -0,0 +1,475 @@ +== 001 +-- xid and xid8 + +-- values in range, in octal, decimal, hex +select '010'::xid, + '42'::xid, + '0xffffffff'::xid, + '-1'::xid, + '010'::xid8, + '42'::xid8, + '0xffffffffffffffff'::xid8, + '-1'::xid8 +-- +STMT: SelectStmt +== 002 +-- garbage values +select ''::xid +-- +STMT: SelectStmt +== 003 +select 'asdf'::xid +-- +STMT: SelectStmt +== 004 +select ''::xid8 +-- +STMT: SelectStmt +== 005 +select 'asdf'::xid8 +-- +STMT: SelectStmt +== 006 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('42', 'xid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT pg_input_is_valid('asdf', 'xid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 008 +SELECT * FROM pg_input_error_info('0xffffffffff', 'xid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 009 +SELECT pg_input_is_valid('42', 'xid8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT pg_input_is_valid('asdf', 'xid8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT * FROM pg_input_error_info('0xffffffffffffffffffff', 'xid8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 012 +-- equality +select '1'::xid = '1'::xid +-- +STMT: SelectStmt +== 013 +select '1'::xid != '1'::xid +-- +STMT: SelectStmt +== 014 +select '1'::xid8 = '1'::xid8 +-- +STMT: SelectStmt +== 015 +select '1'::xid8 != '1'::xid8 +-- +STMT: SelectStmt +== 016 +-- conversion +select '1'::xid = '1'::xid8::xid +-- +STMT: SelectStmt +== 017 +select '1'::xid != '1'::xid8::xid +-- +STMT: SelectStmt +== 018 +-- we don't want relational operators for xid, due to use of modular arithmetic +select '1'::xid < '2'::xid +-- +STMT: SelectStmt +== 019 +select '1'::xid <= '2'::xid +-- +STMT: SelectStmt +== 020 +select '1'::xid > '2'::xid +-- +STMT: SelectStmt +== 021 +select '1'::xid >= '2'::xid +-- +STMT: SelectStmt +== 022 +-- we want them for xid8 though +select '1'::xid8 < '2'::xid8, '2'::xid8 < '2'::xid8, '2'::xid8 < '1'::xid8 +-- +STMT: SelectStmt +== 023 +select '1'::xid8 <= '2'::xid8, '2'::xid8 <= '2'::xid8, '2'::xid8 <= '1'::xid8 +-- +STMT: SelectStmt +== 024 +select '1'::xid8 > '2'::xid8, '2'::xid8 > '2'::xid8, '2'::xid8 > '1'::xid8 +-- +STMT: SelectStmt +== 025 +select '1'::xid8 >= '2'::xid8, '2'::xid8 >= '2'::xid8, '2'::xid8 >= '1'::xid8 +-- +STMT: SelectStmt +== 026 +-- we also have a 3way compare for btrees +select xid8cmp('1', '2'), xid8cmp('2', '2'), xid8cmp('2', '1') +-- +FUNCTION: name="xid8cmp" function="xid8cmp" schema="" ctx=Call +FUNCTION: name="xid8cmp" function="xid8cmp" schema="" ctx=Call +FUNCTION: name="xid8cmp" function="xid8cmp" schema="" ctx=Call +STMT: SelectStmt +== 027 +-- min() and max() for xid8 +create table xid8_t1 (x xid8) +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: CreateStmt +== 028 +insert into xid8_t1 values ('0'), ('010'), ('42'), ('0xffffffffffffffff'), ('-1') +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 029 +select min(x), max(x) from xid8_t1 +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +== 030 +-- xid8 has btree and hash opclasses +create index on xid8_t1 using btree(x) +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: IndexStmt +== 031 +create index on xid8_t1 using hash(x) +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: IndexStmt +== 032 +drop table xid8_t1 +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: DropStmt +== 033 +-- pg_snapshot data type and related functions + +-- Note: another set of tests similar to this exists in txid.sql, for a limited +-- time (the relevant functions share C code) + +-- i/o +select '12:13:'::pg_snapshot +-- +STMT: SelectStmt +== 034 +select '12:18:14,16'::pg_snapshot +-- +STMT: SelectStmt +== 035 +select '12:16:14,14'::pg_snapshot +-- +STMT: SelectStmt +== 036 +-- errors +select '31:12:'::pg_snapshot +-- +STMT: SelectStmt +== 037 +select '0:1:'::pg_snapshot +-- +STMT: SelectStmt +== 038 +select '12:13:0'::pg_snapshot +-- +STMT: SelectStmt +== 039 +select '12:16:14,13'::pg_snapshot +-- +STMT: SelectStmt +== 040 +-- also try it with non-error-throwing API +select pg_input_is_valid('12:13:', 'pg_snapshot') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 041 +select pg_input_is_valid('31:12:', 'pg_snapshot') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 042 +select * from pg_input_error_info('31:12:', 'pg_snapshot') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 043 +select pg_input_is_valid('12:16:14,13', 'pg_snapshot') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 044 +select * from pg_input_error_info('12:16:14,13', 'pg_snapshot') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 045 +create temp table snapshot_test ( + nr integer, + snap pg_snapshot +) +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DDL +STMT: CreateStmt +== 046 +insert into snapshot_test values (1, '12:13:') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 047 +insert into snapshot_test values (2, '12:20:13,15,18') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 048 +insert into snapshot_test values (3, '100001:100009:100005,100007,100008') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 049 +insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 050 +select snap from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +STMT: SelectStmt +== 051 +select pg_snapshot_xmin(snap), + pg_snapshot_xmax(snap), + pg_snapshot_xip(snap) +from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="pg_snapshot_xmin" function="pg_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="pg_snapshot_xmax" function="pg_snapshot_xmax" schema="" ctx=Call +FUNCTION: name="pg_snapshot_xip" function="pg_snapshot_xip" schema="" ctx=Call +STMT: SelectStmt +== 052 +select id, pg_visible_in_snapshot(id::text::xid8, snap) +from snapshot_test, generate_series(11, 21) id +where nr = 2 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 053 +-- test bsearch +select id, pg_visible_in_snapshot(id::text::xid8, snap) +from snapshot_test, generate_series(90, 160) id +where nr = 4 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +== 054 +-- test current values also +select pg_current_xact_id() >= pg_snapshot_xmin(pg_current_snapshot()) +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_snapshot_xmin" function="pg_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="pg_current_snapshot" function="pg_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 055 +-- we can't assume current is always less than xmax, however + +select pg_visible_in_snapshot(pg_current_xact_id(), pg_current_snapshot()) +-- +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_snapshot" function="pg_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 056 +-- test 64bitness + +select pg_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013' +-- +STMT: SelectStmt +== 057 +select pg_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 058 +select pg_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +== 059 +-- test 64bit overflow +SELECT pg_snapshot '1:9223372036854775807:3' +-- +STMT: SelectStmt +== 060 +SELECT pg_snapshot '1:9223372036854775808:3' +-- +STMT: SelectStmt +== 061 +-- test pg_current_xact_id_if_assigned +BEGIN +-- +STMT: TransactionStmt +== 062 +SELECT pg_current_xact_id_if_assigned() IS NULL +-- +FUNCTION: name="pg_current_xact_id_if_assigned" function="pg_current_xact_id_if_assigned" schema="" ctx=Call +STMT: SelectStmt +== 063 +SELECT pg_current_xact_id() +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +== 064 +SELECT pg_current_xact_id_if_assigned() IS NOT DISTINCT FROM xid8 :'pg_current_xact_id' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 065 +COMMIT +-- +STMT: TransactionStmt +== 066 +-- test xid status functions +BEGIN +-- +STMT: TransactionStmt +== 067 +SELECT pg_current_xact_id() AS committed +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +== 068 +COMMIT +-- +STMT: TransactionStmt +== 069 +BEGIN +-- +STMT: TransactionStmt +== 070 +SELECT pg_current_xact_id() AS rolledback +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +== 071 +ROLLBACK +-- +STMT: TransactionStmt +== 072 +BEGIN +-- +STMT: TransactionStmt +== 073 +SELECT pg_current_xact_id() AS inprogress +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +== 074 +SELECT pg_xact_status(:committed::text::xid8) AS committed +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +SELECT pg_xact_status(:rolledback::text::xid8) AS rolledback +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 076 +SELECT pg_xact_status(:inprogress::text::xid8) AS inprogress +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +SELECT pg_xact_status('1'::xid8) +-- +FUNCTION: name="pg_xact_status" function="pg_xact_status" schema="" ctx=Call +STMT: SelectStmt +== 078 +-- BootstrapTransactionId is always committed +SELECT pg_xact_status('2'::xid8) +-- +FUNCTION: name="pg_xact_status" function="pg_xact_status" schema="" ctx=Call +STMT: SelectStmt +== 079 +-- FrozenTransactionId is always committed +SELECT pg_xact_status('3'::xid8) +-- +FUNCTION: name="pg_xact_status" function="pg_xact_status" schema="" ctx=Call +STMT: SelectStmt +== 080 +-- in regress testing FirstNormalTransactionId will always be behind oldestXmin + +COMMIT +-- +STMT: TransactionStmt +== 081 +BEGIN +-- +STMT: TransactionStmt +== 082 +CREATE FUNCTION test_future_xid_status(xid8) +RETURNS void +LANGUAGE plpgsql +AS +$$ +BEGIN + PERFORM pg_xact_status($1); + RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected'; +EXCEPTION + WHEN invalid_parameter_value THEN + RAISE NOTICE 'Got expected error for xid in the future'; +END; +$$ +-- +FUNCTION: name="test_future_xid_status" function="test_future_xid_status" schema="" ctx=DDL +STMT: CreateFunctionStmt +== 083 +SELECT test_future_xid_status((:inprogress + 10000)::text::xid8) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 084 +ROLLBACK +-- +STMT: TransactionStmt diff --git a/parser/testdata/summary/postgres_regress/xml.metadata.json b/parser/testdata/summary/postgres_regress/xml.metadata.json new file mode 100644 index 0000000..a6ce2f7 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/xml.metadata.json @@ -0,0 +1,274 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270" + ] +} diff --git a/parser/testdata/summary/postgres_regress/xml.test b/parser/testdata/summary/postgres_regress/xml.test new file mode 100644 index 0000000..c5b5ec8 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/xml.test @@ -0,0 +1,1650 @@ +== 001 +CREATE TABLE xmltest ( + id int, + data xml +) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DDL +STMT: CreateStmt +== 002 +INSERT INTO xmltest VALUES (1, 'one') +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 003 +INSERT INTO xmltest VALUES (2, 'two') +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +INSERT INTO xmltest VALUES (3, 'one', 'xml') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 007 +SELECT pg_input_is_valid('oneone', 'xml') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT message FROM pg_input_error_info('', 'xml') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT xmlcomment('test') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT xmlcomment('-test') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT xmlcomment('test-') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT xmlcomment('--test') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT xmlcomment('te st') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT xmlconcat(xmlcomment('hello'), + xmlelement(NAME qux, 'foo'), + xmlcomment('world')) +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT xmlconcat('hello', 'you') +-- +STMT: SelectStmt +== 018 +SELECT xmlconcat(1, 2) +-- +STMT: SelectStmt +== 019 +SELECT xmlconcat('bad', '', NULL, '') +-- +STMT: SelectStmt +== 021 +SELECT xmlconcat('', NULL, '') +-- +STMT: SelectStmt +== 022 +SELECT xmlconcat(NULL) +-- +STMT: SelectStmt +== 023 +SELECT xmlconcat(NULL, NULL) +-- +STMT: SelectStmt +== 024 +SELECT xmlelement(name element, + xmlattributes (1 as one, 'deuce' as two), + 'content') +-- +STMT: SelectStmt +== 025 +SELECT xmlelement(name element, + xmlattributes ('unnamed and wrong')) +-- +STMT: SelectStmt +== 026 +SELECT xmlelement(name element, xmlelement(name nested, 'stuff')) +-- +STMT: SelectStmt +== 027 +SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp +-- +TABLE: name="emp" schema="" table="emp" ctx=Select +STMT: SelectStmt +== 028 +SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a)) +-- +STMT: SelectStmt +== 029 +SELECT xmlelement(name num, 37) +-- +STMT: SelectStmt +== 030 +SELECT xmlelement(name foo, text 'bar') +-- +STMT: SelectStmt +== 031 +SELECT xmlelement(name foo, xml 'bar') +-- +STMT: SelectStmt +== 032 +SELECT xmlelement(name foo, text 'br') +-- +STMT: SelectStmt +== 033 +SELECT xmlelement(name foo, xml 'br') +-- +STMT: SelectStmt +== 034 +SELECT xmlelement(name foo, array[1, 2, 3]) +-- +STMT: SelectStmt +== 035 +SET xmlbinary TO base64 +-- +STMT: VariableSetStmt +== 036 +SELECT xmlelement(name foo, bytea 'bar') +-- +STMT: SelectStmt +== 037 +SET xmlbinary TO hex +-- +STMT: VariableSetStmt +== 038 +SELECT xmlelement(name foo, bytea 'bar') +-- +STMT: SelectStmt +== 039 +SELECT xmlelement(name foo, xmlattributes(true as bar)) +-- +STMT: SelectStmt +== 040 +SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as bar)) +-- +STMT: SelectStmt +== 041 +SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar)) +-- +STMT: SelectStmt +== 042 +SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'br' as funnier)) +-- +STMT: SelectStmt +== 043 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +== 044 +SELECT xmlparse(content ' ') +-- +STMT: SelectStmt +== 045 +SELECT xmlparse(content 'abc') +-- +STMT: SelectStmt +== 046 +SELECT xmlparse(content 'x') +-- +STMT: SelectStmt +== 047 +SELECT xmlparse(content '&') +-- +STMT: SelectStmt +== 048 +SELECT xmlparse(content '&idontexist;') +-- +STMT: SelectStmt +== 049 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +== 050 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +== 051 +SELECT xmlparse(content '&idontexist;') +-- +STMT: SelectStmt +== 052 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +== 053 +SELECT xmlparse(document ' ') +-- +STMT: SelectStmt +== 054 +SELECT xmlparse(document 'abc') +-- +STMT: SelectStmt +== 055 +SELECT xmlparse(document 'x') +-- +STMT: SelectStmt +== 056 +SELECT xmlparse(document '&') +-- +STMT: SelectStmt +== 057 +SELECT xmlparse(document '&idontexist;') +-- +STMT: SelectStmt +== 058 +SELECT xmlparse(document '') +-- +STMT: SelectStmt +== 059 +SELECT xmlparse(document '') +-- +STMT: SelectStmt +== 060 +SELECT xmlparse(document '&idontexist;') +-- +STMT: SelectStmt +== 061 +SELECT xmlparse(document '') +-- +STMT: SelectStmt +== 062 +SELECT xmlpi(name foo) +-- +STMT: SelectStmt +== 063 +SELECT xmlpi(name xml) +-- +STMT: SelectStmt +== 064 +SELECT xmlpi(name xmlstuff) +-- +STMT: SelectStmt +== 065 +SELECT xmlpi(name foo, 'bar') +-- +STMT: SelectStmt +== 066 +SELECT xmlpi(name foo, 'in?>valid') +-- +STMT: SelectStmt +== 067 +SELECT xmlpi(name foo, null) +-- +STMT: SelectStmt +== 068 +SELECT xmlpi(name xml, null) +-- +STMT: SelectStmt +== 069 +SELECT xmlpi(name xmlstuff, null) +-- +STMT: SelectStmt +== 070 +SELECT xmlpi(name "xml-stylesheet", 'href="mystyle.css" type="text/css"') +-- +STMT: SelectStmt +== 071 +SELECT xmlpi(name foo, ' bar') +-- +STMT: SelectStmt +== 072 +SELECT xmlroot(xml '', version no value, standalone no value) +-- +STMT: SelectStmt +== 073 +SELECT xmlroot(xml '', version '2.0') +-- +STMT: SelectStmt +== 074 +SELECT xmlroot(xml '', version no value, standalone yes) +-- +STMT: SelectStmt +== 075 +SELECT xmlroot(xml '', version no value, standalone yes) +-- +STMT: SelectStmt +== 076 +SELECT xmlroot(xmlroot(xml '', version '1.0'), version '1.1', standalone no) +-- +STMT: SelectStmt +== 077 +SELECT xmlroot('', version no value, standalone no) +-- +STMT: SelectStmt +== 078 +SELECT xmlroot('', version no value, standalone no value) +-- +STMT: SelectStmt +== 079 +SELECT xmlroot('', version no value) +-- +STMT: SelectStmt +== 080 +SELECT xmlroot ( + xmlelement ( + name gazonk, + xmlattributes ( + 'val' AS name, + 1 + 1 AS num + ), + xmlelement ( + NAME qux, + 'foo' + ) + ), + version '1.0', + standalone yes +) +-- +STMT: SelectStmt +== 081 +SELECT xmlserialize(content data as character varying(20)) FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +STMT: SelectStmt +== 082 +SELECT xmlserialize(content 'good' as char(10)) +-- +STMT: SelectStmt +== 083 +SELECT xmlserialize(document 'bad' as text) +-- +STMT: SelectStmt +== 084 +-- indent +SELECT xmlserialize(DOCUMENT '42' AS text INDENT) +-- +STMT: SelectStmt +== 085 +SELECT xmlserialize(CONTENT '42' AS text INDENT) +-- +STMT: SelectStmt +== 086 +-- no indent +SELECT xmlserialize(DOCUMENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +== 087 +SELECT xmlserialize(CONTENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +== 088 +-- indent non singly-rooted xml +SELECT xmlserialize(DOCUMENT '7342' AS text INDENT) +-- +STMT: SelectStmt +== 089 +SELECT xmlserialize(CONTENT '7342' AS text INDENT) +-- +STMT: SelectStmt +== 090 +-- indent non singly-rooted xml with mixed contents +SELECT xmlserialize(DOCUMENT 'text node73text node42' AS text INDENT) +-- +STMT: SelectStmt +== 091 +SELECT xmlserialize(CONTENT 'text node73text node42' AS text INDENT) +-- +STMT: SelectStmt +== 092 +-- indent singly-rooted xml with mixed contents +SELECT xmlserialize(DOCUMENT '42text node73' AS text INDENT) +-- +STMT: SelectStmt +== 093 +SELECT xmlserialize(CONTENT '42text node73' AS text INDENT) +-- +STMT: SelectStmt +== 094 +-- indent empty string +SELECT xmlserialize(DOCUMENT '' AS text INDENT) +-- +STMT: SelectStmt +== 095 +SELECT xmlserialize(CONTENT '' AS text INDENT) +-- +STMT: SelectStmt +== 096 +-- whitespaces +SELECT xmlserialize(DOCUMENT ' ' AS text INDENT) +-- +STMT: SelectStmt +== 097 +SELECT xmlserialize(CONTENT ' ' AS text INDENT) +-- +STMT: SelectStmt +== 098 +-- indent null +SELECT xmlserialize(DOCUMENT NULL AS text INDENT) +-- +STMT: SelectStmt +== 099 +SELECT xmlserialize(CONTENT NULL AS text INDENT) +-- +STMT: SelectStmt +== 100 +-- indent with XML declaration +SELECT xmlserialize(DOCUMENT '73' AS text INDENT) +-- +STMT: SelectStmt +== 101 +SELECT xmlserialize(CONTENT '73' AS text INDENT) +-- +STMT: SelectStmt +== 102 +-- indent containing DOCTYPE declaration +SELECT xmlserialize(DOCUMENT '' AS text INDENT) +-- +STMT: SelectStmt +== 103 +SELECT xmlserialize(CONTENT '' AS text INDENT) +-- +STMT: SelectStmt +== 104 +-- indent xml with empty element +SELECT xmlserialize(DOCUMENT '' AS text INDENT) +-- +STMT: SelectStmt +== 105 +SELECT xmlserialize(CONTENT '' AS text INDENT) +-- +STMT: SelectStmt +== 106 +-- 'no indent' = not using 'no indent' +SELECT xmlserialize(DOCUMENT '42' AS text) = xmlserialize(DOCUMENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +== 107 +SELECT xmlserialize(CONTENT '42' AS text) = xmlserialize(CONTENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +== 108 +-- indent xml strings containing blank nodes +SELECT xmlserialize(DOCUMENT ' ' AS text INDENT) +-- +STMT: SelectStmt +== 109 +SELECT xmlserialize(CONTENT 'text node ' AS text INDENT) +-- +STMT: SelectStmt +== 110 +SELECT xml 'bar' IS DOCUMENT +-- +STMT: SelectStmt +== 111 +SELECT xml 'barfoo' IS DOCUMENT +-- +STMT: SelectStmt +== 112 +SELECT xml '' IS NOT DOCUMENT +-- +STMT: SelectStmt +== 113 +SELECT xml 'abc' IS NOT DOCUMENT +-- +STMT: SelectStmt +== 114 +SELECT '<>' IS NOT DOCUMENT +-- +STMT: SelectStmt +== 115 +SELECT xmlagg(data) FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +STMT: SelectStmt +== 116 +SELECT xmlagg(data) FROM xmltest WHERE id > 10 +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +FILTER: schema="" table="" column="id" +STMT: SelectStmt +== 117 +SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp +-- +TABLE: name="emp" schema="" table="emp" ctx=Select +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +STMT: SelectStmt +== 118 +-- Check mapping SQL identifier to XML name + +SELECT xmlpi(name ":::_xml_abc135.%-&_") +-- +STMT: SelectStmt +== 119 +SELECT xmlpi(name "123") +-- +STMT: SelectStmt +== 120 +PREPARE foo (xml) AS SELECT xmlconcat('', $1) +-- +STMT: PrepareStmt +STMT: SelectStmt +== 121 +SET XML OPTION DOCUMENT +-- +STMT: VariableSetStmt +== 122 +EXECUTE foo ('') +-- +STMT: ExecuteStmt +== 123 +EXECUTE foo ('bad') +-- +STMT: ExecuteStmt +== 124 +SELECT xml '' +-- +STMT: SelectStmt +== 125 +SET XML OPTION CONTENT +-- +STMT: VariableSetStmt +== 126 +EXECUTE foo ('') +-- +STMT: ExecuteStmt +== 127 +EXECUTE foo ('good') +-- +STMT: ExecuteStmt +== 128 +SELECT xml ' ' +-- +STMT: SelectStmt +== 129 +SELECT xml ' ' +-- +STMT: SelectStmt +== 130 +SELECT xml '' +-- +STMT: SelectStmt +== 131 +SELECT xml ' oops ' +-- +STMT: SelectStmt +== 132 +SELECT xml ' ' +-- +STMT: SelectStmt +== 133 +SELECT xml '' +-- +STMT: SelectStmt +== 134 +-- Test backwards parsing + +CREATE VIEW xmlview1 AS SELECT xmlcomment('test') +-- +TABLE: name="xmlview1" schema="" table="xmlview1" ctx=DDL +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +== 135 +CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you') +-- +TABLE: name="xmlview2" schema="" table="xmlview2" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 136 +CREATE VIEW xmlview3 AS SELECT xmlelement(name element, xmlattributes (1 as ":one:", 'deuce' as two), 'content&') +-- +TABLE: name="xmlview3" schema="" table="xmlview3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 137 +CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp +-- +TABLE: name="xmlview4" schema="" table="xmlview4" ctx=DDL +TABLE: name="emp" schema="" table="emp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 138 +CREATE VIEW xmlview5 AS SELECT xmlparse(content 'x') +-- +TABLE: name="xmlview5" schema="" table="xmlview5" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 139 +CREATE VIEW xmlview6 AS SELECT xmlpi(name foo, 'bar') +-- +TABLE: name="xmlview6" schema="" table="xmlview6" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 140 +CREATE VIEW xmlview7 AS SELECT xmlroot(xml '', version no value, standalone yes) +-- +TABLE: name="xmlview7" schema="" table="xmlview7" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 141 +CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10)) +-- +TABLE: name="xmlview8" schema="" table="xmlview8" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 142 +CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text) +-- +TABLE: name="xmlview9" schema="" table="xmlview9" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 143 +CREATE VIEW xmlview10 AS SELECT xmlserialize(document '42' AS text indent) +-- +TABLE: name="xmlview10" schema="" table="xmlview10" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 144 +CREATE VIEW xmlview11 AS SELECT xmlserialize(document '42' AS character varying no indent) +-- +TABLE: name="xmlview11" schema="" table="xmlview11" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 145 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'xmlview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +== 146 +-- Text XPath expressions evaluation + +SELECT xpath('/value', data) FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 147 +SELECT xpath(NULL, NULL) IS NULL FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 148 +SELECT xpath('', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 149 +SELECT xpath('//text()', 'number one') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 150 +SELECT xpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]) +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 151 +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]) +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 152 +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]) +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 153 +SELECT xpath('//b', 'one two three etc') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 154 +SELECT xpath('//text()', '<') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 155 +SELECT xpath('//@value', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 156 +SELECT xpath('''<>''', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 157 +SELECT xpath('count(//*)', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 158 +SELECT xpath('count(//*)=0', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 159 +SELECT xpath('count(//*)=3', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 160 +SELECT xpath('name(/*)', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 161 +SELECT xpath('/nosuchtag', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 162 +SELECT xpath('root', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 163 +-- Round-trip non-ASCII data through xpath(). +DO $$ +DECLARE + xml_declaration text := ''; + degree_symbol text; + res xml[]; +BEGIN + -- Per the documentation, except when the server encoding is UTF8, xpath() + -- may not work on non-ASCII data. The untranslatable_character and + -- undefined_function traps below, currently dead code, will become relevant + -- if we remove this limitation. + IF current_setting('server_encoding') <> 'UTF8' THEN + RAISE LOG 'skip: encoding % unsupported for xpath', + current_setting('server_encoding'); + RETURN; + END IF; + + degree_symbol := convert_from('\xc2b0', 'UTF8'); + res := xpath('text()', (xml_declaration || + '' || degree_symbol || '')::xml); + IF degree_symbol <> res[1]::text THEN + RAISE 'expected % (%), got % (%)', + degree_symbol, convert_to(degree_symbol, 'UTF8'), + res[1], convert_to(res[1]::text, 'UTF8'); + END IF; +EXCEPTION + -- character with byte sequence 0xc2 0xb0 in encoding "UTF8" has no equivalent in encoding "LATIN8" + WHEN untranslatable_character + -- default conversion function for encoding "UTF8" to "MULE_INTERNAL" does not exist + OR undefined_function + -- unsupported XML feature + OR feature_not_supported THEN + RAISE LOG 'skip: %', SQLERRM; +END +$$ +-- +STMT: DoStmt +== 164 +-- Test xmlexists and xpath_exists +SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF 'Bidford-on-AvonCwmbranBristol') +-- +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 165 +SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF 'Bidford-on-AvonCwmbranBristol') +-- +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 166 +SELECT xmlexists('count(/nosuchtag)' PASSING BY REF '') +-- +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +STMT: SelectStmt +== 167 +SELECT xpath_exists('//town[text() = ''Toronto'']','Bidford-on-AvonCwmbranBristol'::xml) +-- +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +STMT: SelectStmt +== 168 +SELECT xpath_exists('//town[text() = ''Cwmbran'']','Bidford-on-AvonCwmbranBristol'::xml) +-- +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +STMT: SelectStmt +== 169 +SELECT xpath_exists('count(/nosuchtag)', ''::xml) +-- +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +STMT: SelectStmt +== 170 +INSERT INTO xmltest VALUES (4, 'BudvarfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 171 +INSERT INTO xmltest VALUES (5, 'MolsonfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 172 +INSERT INTO xmltest VALUES (6, 'BudvarfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 173 +INSERT INTO xmltest VALUES (7, 'MolsonfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 174 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 175 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING BY REF data BY REF) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 176 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers' PASSING BY REF data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 177 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molson'']' PASSING BY REF data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 178 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beer',data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 179 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers',data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 180 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers/name[text() = ''Molson'']',data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 181 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beer',data,ARRAY[ARRAY['myns','http://myns.com']]) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 182 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers',data,ARRAY[ARRAY['myns','http://myns.com']]) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 183 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers/myns:name[text() = ''Molson'']',data,ARRAY[ARRAY['myns','http://myns.com']]) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 184 +CREATE TABLE query ( expr TEXT ) +-- +TABLE: name="query" schema="" table="query" ctx=DDL +STMT: CreateStmt +== 185 +INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']') +-- +TABLE: name="query" schema="" table="query" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 186 +SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +TABLE: name="query" schema="" table="query" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="expr" +FILTER: schema="" table="" column="data" +STMT: SelectStmt +== 187 +-- Test xml_is_well_formed and variants + +SELECT xml_is_well_formed_document('bar') +-- +FUNCTION: name="xml_is_well_formed_document" function="xml_is_well_formed_document" schema="" ctx=Call +STMT: SelectStmt +== 188 +SELECT xml_is_well_formed_document('abc') +-- +FUNCTION: name="xml_is_well_formed_document" function="xml_is_well_formed_document" schema="" ctx=Call +STMT: SelectStmt +== 189 +SELECT xml_is_well_formed_content('bar') +-- +FUNCTION: name="xml_is_well_formed_content" function="xml_is_well_formed_content" schema="" ctx=Call +STMT: SelectStmt +== 190 +SELECT xml_is_well_formed_content('abc') +-- +FUNCTION: name="xml_is_well_formed_content" function="xml_is_well_formed_content" schema="" ctx=Call +STMT: SelectStmt +== 191 +SET xmloption TO DOCUMENT +-- +STMT: VariableSetStmt +== 192 +SELECT xml_is_well_formed('abc') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 193 +SELECT xml_is_well_formed('<>') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 194 +SELECT xml_is_well_formed('') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 195 +SELECT xml_is_well_formed('bar') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 196 +SELECT xml_is_well_formed('barbaz') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 198 +SELECT xml_is_well_formed('number one') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 199 +SELECT xml_is_well_formed('bar') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 200 +SELECT xml_is_well_formed('bar') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 201 +SELECT xml_is_well_formed('&') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 202 +SELECT xml_is_well_formed('&idontexist;') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 203 +SELECT xml_is_well_formed('') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 204 +SELECT xml_is_well_formed('') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 205 +SELECT xml_is_well_formed('&idontexist;') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 206 +SET xmloption TO CONTENT +-- +STMT: VariableSetStmt +== 207 +SELECT xml_is_well_formed('abc') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +== 208 +-- Since xpath() deals with namespaces, it's a bit stricter about +-- what's well-formed and what's not. If we don't obey these rules +-- (i.e. ignore namespace-related errors from libxml), xpath() +-- fails in subtle ways. The following would for example produce +-- the xml value +-- +-- which is invalid because '<' may not appear un-escaped in +-- attribute values. +-- Since different libxml versions emit slightly different +-- error messages, we suppress the DETAIL in this test. +SELECT xpath('/*', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 209 +-- Again, the XML isn't well-formed for namespace purposes +SELECT xpath('/*', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 210 +-- XPath deprecates relative namespaces, but they're not supposed to +-- throw an error, only a warning. +SELECT xpath('/*', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +== 211 +-- External entity references should not leak filesystem information. +SELECT XMLPARSE(DOCUMENT ']>&c;') +-- +STMT: SelectStmt +== 212 +SELECT XMLPARSE(DOCUMENT ']>&c;') +-- +STMT: SelectStmt +== 213 +-- This might or might not load the requested DTD, but it mustn't throw error. +SELECT XMLPARSE(DOCUMENT ' ') +-- +STMT: SelectStmt +== 214 +-- XMLPATH tests +CREATE TABLE xmldata(data xml) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DDL +STMT: CreateStmt +== 215 +INSERT INTO xmldata VALUES(' + + AU + Australia + 3 + + + CN + China + 3 + + + HK + HongKong + 3 + + + IN + India + 3 + + + JP + Japan + 3Sinzo Abe + + + SG + Singapore + 3791 + +') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 216 +-- XMLTABLE with columns +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 217 +CREATE VIEW xmltableview1 AS SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=DDL +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +== 218 +SELECT * FROM xmltableview1 +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=Select +STMT: SelectStmt +== 219 +EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1 +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 220 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1 +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 221 +-- errors +SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2) +-- +STMT: SelectStmt +== 222 +SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_not_null 1) AS f (v1) +-- +ERROR: option name "__pg__is_not_null" cannot be used in XMLTABLE +CURSORPOS: 66 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 223 +-- XMLNAMESPACES tests +SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), + '/zz:rows/zz:row' + PASSING '10' + COLUMNS a int PATH 'zz:a') +-- +STMT: SelectStmt +== 224 +CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"), + '/Zz:rows/Zz:row' + PASSING '10' + COLUMNS a int PATH 'Zz:a') +-- +TABLE: name="xmltableview2" schema="" table="xmltableview2" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +== 225 +SELECT * FROM xmltableview2 +-- +TABLE: name="xmltableview2" schema="" table="xmltableview2" ctx=Select +STMT: SelectStmt +== 226 +SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), + '/rows/row' + PASSING '10' + COLUMNS a int PATH 'a') +-- +STMT: SelectStmt +== 227 +SELECT * FROM XMLTABLE('.' + PASSING '' + COLUMNS a text PATH 'foo/namespace::node()') +-- +STMT: SelectStmt +== 228 +-- used in prepare statements +PREPARE pp AS +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +== 229 +EXECUTE pp +-- +STMT: ExecuteStmt +== 230 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 231 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id FOR ORDINALITY, "COUNTRY_NAME" text, "REGION_ID" int) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 232 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 233 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 234 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id FOR ORDINALITY) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 235 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int, rawdata xml PATH '.') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 236 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int, rawdata xml PATH './*') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 237 +SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text) +-- +STMT: SelectStmt +== 238 +SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text PATH 'element/text()') +-- +STMT: SelectStmt +== 239 +-- should fail + +-- CDATA test +select * from xmltable('d/r' passing ' &"<>!foo]]>2' columns c text) +-- +STMT: SelectStmt +== 240 +-- XML builtin entities +SELECT * FROM xmltable('/x/a' PASSING ''"&<>' COLUMNS ent text) +-- +STMT: SelectStmt +== 241 +SELECT * FROM xmltable('/x/a' PASSING ''"&<>' COLUMNS ent xml) +-- +STMT: SelectStmt +== 242 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +== 243 +-- test qual +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) WHERE "COUNTRY_NAME" = 'Japan' +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +FILTER: schema="" table="" column="COUNTRY_NAME" +STMT: SelectStmt +== 244 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) AS f WHERE "COUNTRY_NAME" = 'Japan' +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +FILTER: schema="" table="" column="COUNTRY_NAME" +STMT: ExplainStmt +STMT: SelectStmt +== 245 +EXPLAIN (VERBOSE, FORMAT JSON, COSTS OFF) +SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) AS f WHERE "COUNTRY_NAME" = 'Japan' +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +FILTER: schema="" table="" column="COUNTRY_NAME" +STMT: ExplainStmt +STMT: SelectStmt +== 246 +-- should to work with more data +INSERT INTO xmldata VALUES(' + + CZ + Czech Republic + 2Milos Zeman + + + DE + Germany + 2 + + + FR + France + 2 + +') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 247 +INSERT INTO xmldata VALUES(' + + EG + Egypt + 1 + + + SD + Sudan + 1 + +') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 248 +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 249 +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') + WHERE region_id = 2 +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +FILTER: schema="" table="" column="region_id" +STMT: SelectStmt +== 250 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') + WHERE region_id = 2 +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +FILTER: schema="" table="" column="region_id" +STMT: ExplainStmt +STMT: SelectStmt +== 251 +-- should fail, NULL value +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE' NOT NULL, + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +== 252 +-- if all is ok, then result is empty +-- one line xml test +WITH + x AS (SELECT proname, proowner, procost::numeric, pronargs, + array_to_string(proargnames,',') as proargnames, + case when proargtypes <> '' then array_to_string(proargtypes::oid[],',') end as proargtypes + FROM pg_proc WHERE proname = 'f_leak'), + y AS (SELECT xmlelement(name proc, + xmlforest(proname, proowner, + procost, pronargs, + proargnames, proargtypes)) as proc + FROM x), + z AS (SELECT xmltable.* + FROM y, + LATERAL xmltable('/proc' PASSING proc + COLUMNS proname name, + proowner oid, + procost float, + pronargs int, + proargnames text, + proargtypes text)) + SELECT * FROM z + EXCEPT SELECT * FROM x +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +CTE: "x" +CTE: "y" +CTE: "z" +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +== 253 +-- multi line xml test, result should be empty too +WITH + x AS (SELECT proname, proowner, procost::numeric, pronargs, + array_to_string(proargnames,',') as proargnames, + case when proargtypes <> '' then array_to_string(proargtypes::oid[],',') end as proargtypes + FROM pg_proc), + y AS (SELECT xmlelement(name data, + xmlagg(xmlelement(name proc, + xmlforest(proname, proowner, procost, + pronargs, proargnames, proargtypes)))) as doc + FROM x), + z AS (SELECT xmltable.* + FROM y, + LATERAL xmltable('/data/proc' PASSING doc + COLUMNS proname name, + proowner oid, + procost float, + pronargs int, + proargnames text, + proargtypes text)) + SELECT * FROM z + EXCEPT SELECT * FROM x +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +CTE: "x" +CTE: "y" +CTE: "z" +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +STMT: SelectStmt +== 254 +CREATE TABLE xmltest2(x xml, _path text) +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DDL +STMT: CreateStmt +== 255 +INSERT INTO xmltest2 VALUES('1', 'A') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 256 +INSERT INTO xmltest2 VALUES('2', 'B') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 257 +INSERT INTO xmltest2 VALUES('3', 'C') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 258 +INSERT INTO xmltest2 VALUES('2', 'D') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 259 +SELECT xmltable.* FROM xmltest2, LATERAL xmltable('/d/r' PASSING x COLUMNS a int PATH '' || lower(_path) || 'c') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 260 +SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH '.') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +== 261 +SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH 'x' DEFAULT ascii(_path) - 54) +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="ascii" function="ascii" schema="" ctx=Call +STMT: SelectStmt +== 262 +-- XPath result can be boolean or number too +SELECT * FROM XMLTABLE('*' PASSING 'a' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"', e integer PATH 'string-length(.)') +-- +STMT: SelectStmt +== 263 +SELECT * FROM XMLTABLE('*' PASSING 'pre&deeppost' COLUMNS x xml PATH '/e/n2', y xml PATH '/') +-- +STMT: SelectStmt +== 264 +SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '""', b xml PATH '""') +-- +STMT: SelectStmt +== 265 +SELECT xmltext(NULL) +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +== 266 +SELECT xmltext('') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +== 267 +SELECT xmltext(' ') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +== 268 +SELECT xmltext('foo `$_-+?=*^%!|/\()[]{}') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +== 269 +SELECT xmltext('foo & <"bar">') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +== 270 +SELECT xmltext('x'|| '

      73

      '::xml || .42 || true || 'j'::char) +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary/postgres_regress/xmlmap.metadata.json b/parser/testdata/summary/postgres_regress/xmlmap.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/xmlmap.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary/postgres_regress/xmlmap.test b/parser/testdata/summary/postgres_regress/xmlmap.test new file mode 100644 index 0000000..824ce75 --- /dev/null +++ b/parser/testdata/summary/postgres_regress/xmlmap.test @@ -0,0 +1,209 @@ +== 001 +CREATE SCHEMA testxmlschema +-- +STMT: CreateSchemaStmt +== 002 +CREATE TABLE testxmlschema.test1 (a int, b text) +-- +TABLE: name="testxmlschema.test1" schema="testxmlschema" table="test1" ctx=DDL +STMT: CreateStmt +== 003 +INSERT INTO testxmlschema.test1 VALUES (1, 'one'), (2, 'two'), (-1, null) +-- +TABLE: name="testxmlschema.test1" schema="testxmlschema" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 004 +CREATE DOMAIN testxmldomain AS varchar +-- +STMT: CreateDomainStmt +== 005 +CREATE TABLE testxmlschema.test2 (z int, y varchar(500), x char(6), + w numeric(9,2), v smallint, u bigint, t real, + s time, stz timetz, r timestamp, rtz timestamptz, q date, + p xml, o testxmldomain, n bool, m bytea, aaa text) +-- +TABLE: name="testxmlschema.test2" schema="testxmlschema" table="test2" ctx=DDL +STMT: CreateStmt +== 006 +ALTER TABLE testxmlschema.test2 DROP COLUMN aaa +-- +TABLE: name="testxmlschema.test2" schema="testxmlschema" table="test2" ctx=DDL +STMT: AlterTableStmt +== 007 +INSERT INTO testxmlschema.test2 VALUES (55, 'abc', 'def', + 98.6, 2, 999, 0, + '21:07', '21:11 +05', '2009-06-08 21:07:30', '2009-06-08 21:07:30 -07', '2009-06-08', + NULL, 'ABC', true, 'XYZ') +-- +TABLE: name="testxmlschema.test2" schema="testxmlschema" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +== 008 +SELECT table_to_xml('testxmlschema.test1', false, false, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 009 +SELECT table_to_xml('testxmlschema.test1', true, false, 'foo') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 010 +SELECT table_to_xml('testxmlschema.test1', false, true, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 011 +SELECT table_to_xml('testxmlschema.test1', true, true, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 012 +SELECT table_to_xml('testxmlschema.test2', false, false, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 013 +SELECT table_to_xmlschema('testxmlschema.test1', false, false, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 014 +SELECT table_to_xmlschema('testxmlschema.test1', true, false, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 015 +SELECT table_to_xmlschema('testxmlschema.test1', false, true, 'foo') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 016 +SELECT table_to_xmlschema('testxmlschema.test1', true, true, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 017 +SELECT table_to_xmlschema('testxmlschema.test2', false, false, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 018 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, false, '') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 019 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, false, '') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 020 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, true, '') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 021 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, true, 'foo') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 022 +SELECT query_to_xml('SELECT * FROM testxmlschema.test1', false, false, '') +-- +FUNCTION: name="query_to_xml" function="query_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 023 +SELECT query_to_xmlschema('SELECT * FROM testxmlschema.test1', false, false, '') +-- +FUNCTION: name="query_to_xmlschema" function="query_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 024 +SELECT query_to_xml_and_xmlschema('SELECT * FROM testxmlschema.test1', true, true, '') +-- +FUNCTION: name="query_to_xml_and_xmlschema" function="query_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 025 +DECLARE xc CURSOR WITH HOLD FOR SELECT * FROM testxmlschema.test1 ORDER BY 1, 2 +-- +STMT: DeclareCursorStmt +== 026 +SELECT cursor_to_xml('xc'::refcursor, 5, false, true, '') +-- +FUNCTION: name="cursor_to_xml" function="cursor_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 027 +SELECT cursor_to_xmlschema('xc'::refcursor, false, true, '') +-- +FUNCTION: name="cursor_to_xmlschema" function="cursor_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 028 +MOVE BACKWARD ALL IN xc +-- +STMT: FetchStmt +== 029 +SELECT cursor_to_xml('xc'::refcursor, 5, true, false, '') +-- +FUNCTION: name="cursor_to_xml" function="cursor_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 030 +SELECT cursor_to_xmlschema('xc'::refcursor, true, false, '') +-- +FUNCTION: name="cursor_to_xmlschema" function="cursor_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 031 +SELECT schema_to_xml('testxmlschema', false, true, '') +-- +FUNCTION: name="schema_to_xml" function="schema_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 032 +SELECT schema_to_xml('testxmlschema', true, false, '') +-- +FUNCTION: name="schema_to_xml" function="schema_to_xml" schema="" ctx=Call +STMT: SelectStmt +== 033 +SELECT schema_to_xmlschema('testxmlschema', false, true, '') +-- +FUNCTION: name="schema_to_xmlschema" function="schema_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 034 +SELECT schema_to_xmlschema('testxmlschema', true, false, '') +-- +FUNCTION: name="schema_to_xmlschema" function="schema_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 035 +SELECT schema_to_xml_and_xmlschema('testxmlschema', true, true, 'foo') +-- +FUNCTION: name="schema_to_xml_and_xmlschema" function="schema_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +== 036 +-- test that domains are transformed like their base types + +CREATE DOMAIN testboolxmldomain AS bool +-- +STMT: CreateDomainStmt +== 037 +CREATE DOMAIN testdatexmldomain AS date +-- +STMT: CreateDomainStmt +== 038 +CREATE TABLE testxmlschema.test3 + AS SELECT true c1, + true::testboolxmldomain c2, + '2013-02-21'::date c3, + '2013-02-21'::testdatexmldomain c4 +-- +TABLE: name="testxmlschema.test3" schema="testxmlschema" table="test3" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +== 039 +SELECT xmlforest(c1, c2, c3, c4) FROM testxmlschema.test3 +-- +TABLE: name="testxmlschema.test3" schema="testxmlschema" table="test3" ctx=Select +STMT: SelectStmt +== 040 +SELECT table_to_xml('testxmlschema.test3', true, true, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt diff --git a/parser/testdata/summary_truncate/libpg_query.metadata.json b/parser/testdata/summary_truncate/libpg_query.metadata.json new file mode 100644 index 0000000..8cf86ed --- /dev/null +++ b/parser/testdata/summary_truncate/libpg_query.metadata.json @@ -0,0 +1,120 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116" + ] +} diff --git a/parser/testdata/summary_truncate/libpg_query.test b/parser/testdata/summary_truncate/libpg_query.test new file mode 100644 index 0000000..3967025 --- /dev/null +++ b/parser/testdata/summary_truncate/libpg_query.test @@ -0,0 +1,1222 @@ +== 001 +-- truncate_limit: 40 +SELECT a, b, c, d, e, f FROM xyz WHERE a = b +-- +TABLE: name="xyz" schema="" table="xyz" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xyz WHERE a = b" +== 002 +-- truncate_limit: 40 +WITH x AS (SELECT * FROM y) SELECT * FROM x +-- +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH x AS (...) SELECT * FROM x" +== 003 +-- truncate_limit: 30 +SELECT * FROM z WHERE a = b AND x = y +-- +TABLE: name="z" schema="" table="z" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM z WHERE ..." +== 004 +-- truncate_limit: 32 +INSERT INTO "x" (a, b, c, d, e, f) VALUES ($1) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO x (...) VALUES ($1)" +== 005 +-- truncate_limit: 100 +SELECT $1 /* application:test */ +-- +STMT: SelectStmt +TRUNCATED: "SELECT $1" +== 006 +-- truncate_limit: 10 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 007 +-- truncate_limit: 50 +SELECT CASE WHEN $2.typtype = $1 THEN $2.typtypmod ELSE $1.atttypmod END +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 008 +-- truncate_limit: 30 +UPDATE x SET a = 1, c = 2, e = 'str' +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE x SET ... = ..." +== 009 +-- truncate_limit: 65 +INSERT INTO y(a) VALUES(1) ON CONFLICT DO UPDATE SET a = 123456789 +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y (a) VALUES (1) ON CONFLICT DO UPDATE SET ... = ..." +== 010 +-- truncate_limit: 100 + INSERT INTO foo (a, b, c, d) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29) ON CONFLICT (id) DO UPDATE SET (a, b, c, d) = (excluded.a,excluded.b,excluded.c,case when foo.d = excluded.d then excluded.d end) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo (a, b, c, d) VALUES (...) ON CONFLICT (id) DO UPDATE SET ... = ..." +== 011 +-- truncate_limit: 35 +GRANT SELECT (abc, def, ghj) ON TABLE t1 TO r1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (abc, def, ghj) ON ..." +== 012 +-- truncate_limit: 100 + WITH activity AS ( SELECT pid, COALESCE(a.usename, '') AS usename FROM pganalyze.get_stat_activity() a ) SELECT FROM pganalyze.get_stat_progress_vacuum() v JOIN activity a USING (pid) +-- +ALIAS: "a"="activity" +CTE: "activity" +FUNCTION: name="pganalyze.get_stat_progress_vacuum" function="get_stat_progress_vacuum" schema="pganalyze" ctx=Call +FUNCTION: name="pganalyze.get_stat_activity" function="get_stat_activity" schema="pganalyze" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH activity AS (...) SELECT FROM pganalyze.get_stat_progress_vacuum() v JOIN activity a USING (..." +== 013 +-- truncate_limit: 60 +CREATE INDEX testidx ON test USING btree ((lower(d) || upper(d)), a, (b+c)) +-- +TABLE: name="test" schema="" table="test" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX testidx ON test USING btree ((lower(d) || up..." +== 014 +-- truncate_limit: 21 +WITH "原チコ氏にはす腹腹腹腹腹腹腹腹腹腹腹" AS (SELECT) SELECT w +-- +CTE: "原チコ氏にはす腹腹腹腹腹腹腹腹腹腹腹" +STMT: SelectStmt +TRUNCATED: "WITH \"原チコ氏にはす腹腹腹腹腹..." +== 015 +-- truncate_limit: 50 +SELECT * FROM test WHERE a = 1 +-- +TABLE: name="test" schema="" table="test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test WHERE a = 1" +== 016 +-- truncate_limit: 50 +SELECT * FROM test AS x WHERE a = 1 +-- +TABLE: name="test" schema="" table="test" ctx=Select +ALIAS: "x"="test" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test x WHERE a = 1" +== 017 +-- truncate_limit: 50 +SELECT * FROM test WHERE col1 = (SELECT col2 FROM test2 WHERE col3 = 123) +-- +TABLE: name="test" schema="" table="test" ctx=Select +TABLE: name="test2" schema="" table="test2" ctx=Select +FILTER: schema="" table="" column="col1" +FILTER: schema="" table="" column="col3" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test WHERE ..." +== 018 +-- truncate_limit: 50 +CREATE RANDOM ix_test ON contacts.person; +-- +ERROR: syntax error at or near "RANDOM" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 019 +-- truncate_limit: 50 +SELECT 'ERR +-- +ERROR: unterminated quoted string at or near "'ERR" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 020 +-- truncate_limit: 50 +SELECT * FROM "t0" +-- +TABLE: name="t0" schema="" table="t0" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t0" +== 021 +-- truncate_limit: 50 +SELECT * FROM "t0" JOIN "t1" ON (1) +-- +TABLE: name="t0" schema="" table="t0" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t0 JOIN t1 ON 1" +== 022 +-- truncate_limit: 50 +SELECT * FROM "t0" + JOIN "t1" ON (1) JOIN "t2" ON (1) JOIN "t3" ON (1) JOIN "t4" ON (1) JOIN "t5" ON (1) + JOIN "t6" ON (1) JOIN "t7" ON (1) JOIN "t8" ON (1) JOIN "t9" ON (1) JOIN "t10" ON (1) + JOIN "t11" ON (1) JOIN "t12" ON (1) JOIN "t13" ON (1) JOIN "t14" ON (1) JOIN "t15" ON (1) + JOIN "t16" ON (1) JOIN "t17" ON (1) JOIN "t18" ON (1) JOIN "t19" ON (1) JOIN "t20" ON (1) + JOIN "t21" ON (1) JOIN "t22" ON (1) JOIN "t23" ON (1) JOIN "t24" ON (1) JOIN "t25" ON (1) + JOIN "t26" ON (1) JOIN "t27" ON (1) JOIN "t28" ON (1) JOIN "t29" ON (1) +-- +TABLE: name="t0" schema="" table="t0" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +TABLE: name="t4" schema="" table="t4" ctx=Select +TABLE: name="t5" schema="" table="t5" ctx=Select +TABLE: name="t6" schema="" table="t6" ctx=Select +TABLE: name="t7" schema="" table="t7" ctx=Select +TABLE: name="t8" schema="" table="t8" ctx=Select +TABLE: name="t9" schema="" table="t9" ctx=Select +TABLE: name="t10" schema="" table="t10" ctx=Select +TABLE: name="t11" schema="" table="t11" ctx=Select +TABLE: name="t12" schema="" table="t12" ctx=Select +TABLE: name="t13" schema="" table="t13" ctx=Select +TABLE: name="t14" schema="" table="t14" ctx=Select +TABLE: name="t15" schema="" table="t15" ctx=Select +TABLE: name="t16" schema="" table="t16" ctx=Select +TABLE: name="t17" schema="" table="t17" ctx=Select +TABLE: name="t18" schema="" table="t18" ctx=Select +TABLE: name="t19" schema="" table="t19" ctx=Select +TABLE: name="t20" schema="" table="t20" ctx=Select +TABLE: name="t21" schema="" table="t21" ctx=Select +TABLE: name="t22" schema="" table="t22" ctx=Select +TABLE: name="t23" schema="" table="t23" ctx=Select +TABLE: name="t24" schema="" table="t24" ctx=Select +TABLE: name="t25" schema="" table="t25" ctx=Select +TABLE: name="t26" schema="" table="t26" ctx=Select +TABLE: name="t27" schema="" table="t27" ctx=Select +TABLE: name="t28" schema="" table="t28" ctx=Select +TABLE: name="t29" schema="" table="t29" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t0 JOIN t1 ON 1 JOIN t2 ON 1 JOIN..." +== 023 +-- truncate_limit: 50 + + SELECT memory_total_bytes, memory_free_bytes, memory_pagecache_bytes, memory_buffers_bytes, memory_applications_bytes, + (memory_swap_total_bytes - memory_swap_free_bytes) AS swap, date_part($0, s.collected_at) AS collected_at + FROM snapshots s JOIN system_snapshots ON (snapshot_id = s.id) + WHERE s.database_id = $0 AND s.collected_at BETWEEN $0 AND $0 + ORDER BY collected_at +-- +TABLE: name="snapshots" schema="" table="snapshots" ctx=Select +TABLE: name="system_snapshots" schema="" table="system_snapshots" ctx=Select +ALIAS: "s"="snapshots" +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FILTER: schema="" table="s" column="database_id" +FILTER: schema="" table="s" column="collected_at" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM snapshots s JOIN system_snapsho..." +== 024 +-- truncate_limit: 50 +-- nothing +-- + +== 025 +-- truncate_limit: 50 +SELECT .1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT .1" +== 026 +-- truncate_limit: 50 +SELECT X'EFFF' +-- +STMT: SelectStmt +TRUNCATED: "SELECT x'EFFF'" +== 027 +-- truncate_limit: 50 +ALTER TABLE test ADD PRIMARY KEY (gid) +-- +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test ADD PRIMARY KEY (gid)" +== 028 +-- truncate_limit: 50 +SET statement_timeout=1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET statement_timeout TO 1" +== 029 +-- truncate_limit: 50 +SHOW work_mem +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW work_mem" +== 030 +-- truncate_limit: 50 +COPY test (id) TO stdout +-- +TABLE: name="test" schema="" table="test" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY test(id) TO STDOUT" +== 031 +-- truncate_limit: 50 +drop table abc.test123 cascade +-- +TABLE: name="abc.test123" schema="abc" table="test123" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE abc.test123 CASCADE" +== 032 +-- truncate_limit: 50 +drop table abc.test123, test +-- +TABLE: name="abc.test123" schema="abc" table="test123" ctx=DDL +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE abc.test123, test" +== 033 +-- truncate_limit: 50 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 034 +-- truncate_limit: 50 +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 035 +-- truncate_limit: 50 +VACUUM my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM my_table" +== 036 +-- truncate_limit: 50 +WITH cte AS (SELECT * FROM g.other_table CROSS JOIN p) MERGE INTO my_table USING cte ON (id=oid) WHEN MATCHED THEN UPDATE SET a=b WHEN NOT MATCHED THEN INSERT (id, a) VALUES (oid, b); +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +TABLE: name="g.other_table" schema="g" table="other_table" ctx=Select +TABLE: name="p" schema="" table="p" ctx=Select +CTE: "cte" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "WITH cte AS (...) MERGE INTO my_table USING cte..." +== 037 +-- truncate_limit: 50 +EXPLAIN DELETE FROM test +-- +TABLE: name="test" schema="" table="test" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN DELETE FROM test" +== 038 +-- truncate_limit: 50 +CREATE TEMP TABLE test AS SELECT 1 +-- +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE test AS SELECT 1" +== 039 +-- truncate_limit: 50 +LOCK TABLE public.schema_migrations IN ACCESS SHARE MODE +-- +TABLE: name="public.schema_migrations" schema="public" table="schema_migrations" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE public.schema_migrations IN ACCESS S..." +== 040 +-- truncate_limit: 50 +CREATE TABLE test (a int4) +-- +TABLE: name="test" schema="" table="test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test (a int4)" +== 041 +-- truncate_limit: 50 +CREATE TABLE foo AS SELECT * FROM bar; +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE foo AS SELECT * FROM bar" +== 042 +-- truncate_limit: 50 +CREATE TABLE foo AS SELECT id FROM bar UNION SELECT id from baz; +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="baz" schema="" table="baz" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE foo AS SELECT id FROM bar UNION SE..." +== 043 +-- truncate_limit: 50 +CREATE TABLE test (a int4) WITH OIDS +-- +ERROR: syntax error at or near "OIDS" +CURSORPOS: 33 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 044 +-- truncate_limit: 50 +CREATE INDEX testidx ON test USING btree (a, (lower(b) || upper(c))) WHERE pow(a, 2) > 25 +-- +TABLE: name="test" schema="" table="test" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="pow" function="pow" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX testidx ON test USING btree (a, (l..." +== 045 +-- truncate_limit: 50 +CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe" +== 046 +-- truncate_limit: 50 +CREATE VIEW myview AS SELECT * FROM mytab +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +TABLE: name="mytab" schema="" table="mytab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW myview AS SELECT * FROM mytab" +== 047 +-- truncate_limit: 50 +REFRESH MATERIALIZED VIEW myview +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW myview" +== 048 +-- truncate_limit: 50 +CREATE RULE shoe_ins_protect AS ON INSERT TO shoe DO INSTEAD NOTHING +-- +TABLE: name="shoe" schema="" table="shoe" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE shoe_ins_protect AS ON INSERT TO sh..." +== 049 +-- truncate_limit: 50 +CREATE TRIGGER check_update BEFORE UPDATE ON accounts FOR EACH ROW EXECUTE PROCEDURE check_account_update() +-- +TABLE: name="accounts" schema="" table="accounts" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER check_update BEFORE UPDATE ON ac..." +== 050 +-- truncate_limit: 50 +DROP SCHEMA myschema +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA myschema" +== 051 +-- truncate_limit: 50 +DROP VIEW myview, myview2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW myview, myview2" +== 052 +-- truncate_limit: 50 +DROP INDEX CONCURRENTLY myindex +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY myindex" +== 053 +-- truncate_limit: 50 +DROP RULE myrule ON mytable CASCADE +-- +TABLE: name="mytable" schema="" table="mytable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE myrule ON mytable CASCADE" +== 054 +-- truncate_limit: 50 +DROP TRIGGER IF EXISTS mytrigger ON mytable RESTRICT +-- +TABLE: name="mytable" schema="" table="mytable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER IF EXISTS mytrigger ON mytable" +== 055 +-- truncate_limit: 50 +GRANT INSERT, UPDATE ON mytable TO myuser +-- +TABLE: name="mytable" schema="" table="mytable" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert, update ON mytable TO myuser" +== 056 +-- truncate_limit: 50 +REVOKE admins FROM joe +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE admins FROM joe" +== 057 +-- truncate_limit: 50 +TRUNCATE bigtable, "fattable" RESTART IDENTITY +-- +TABLE: name="bigtable" schema="" table="bigtable" ctx=DDL +TABLE: name="fattable" schema="" table="fattable" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE bigtable, fattable RESTART IDENTITY" +== 058 +-- truncate_limit: 50 +WITH a AS (SELECT * FROM x WHERE x.y = $1 AND x.z = 1) SELECT * FROM a +-- +TABLE: name="x" schema="" table="x" ctx=Select +CTE: "a" +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +TRUNCATED: "WITH a AS (...) SELECT * FROM a" +== 059 +-- truncate_limit: 50 +CREATE OR REPLACE FUNCTION thing(parameter_thing text) + RETURNS bigint AS +$BODY$ +DECLARE + local_thing_id BIGINT := 0; +BEGIN + SELECT thing_id INTO local_thing_id FROM thing_map + WHERE + thing_map_field = parameter_thing + ORDER BY 1 LIMIT 1; + + IF NOT FOUND THEN + local_thing_id = 0; + END IF; + RETURN local_thing_id; +END; +$BODY$ + LANGUAGE plpgsql STABLE +-- +FUNCTION: name="thing" function="thing" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION thing(parameter_thin..." +== 060 +-- truncate_limit: 50 +CREATE FUNCTION getfoo(int) RETURNS TABLE (f1 int) AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getfoo" function="getfoo" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getfoo(int) RETURNS TABLE (f1 i..." +== 061 +-- truncate_limit: 50 +SELECT testfunc(1); +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testfunc(1)" +== 062 +-- truncate_limit: 50 +CALL testfunc(1); +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL testfunc(1)" +== 063 +-- truncate_limit: 50 +DROP FUNCTION IF EXISTS testfunc(x integer); +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION IF EXISTS testfunc(x int)" +== 064 +-- truncate_limit: 50 +ALTER FUNCTION testfunc(integer) RENAME TO testfunc2; +-- +FUNCTION: name="testfunc" function="testfunc" schema="" ctx=DDL +FUNCTION: name="testfunc2" function="testfunc2" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER FUNCTION testfunc(int) RENAME TO testfunc2" +== 065 +-- truncate_limit: 50 +select u.email, (select count(*) from enrollments e where e.user_id = u.id) as num_enrollments from users u +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="enrollments" schema="" table="enrollments" ctx=Select +ALIAS: "e"="enrollments" +ALIAS: "u"="users" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="e" column="user_id" +FILTER: schema="" table="u" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM users u" +== 066 +-- truncate_limit: 50 +WITH cte_name AS (SELECT 1) SELECT * FROM table_name, cte_name +-- +TABLE: name="table_name" schema="" table="table_name" ctx=Select +CTE: "cte_name" +STMT: SelectStmt +TRUNCATED: "WITH cte_name AS (...) SELECT * FROM table_name..." +== 067 +-- truncate_limit: 50 +SELECT * FROM tbl TABLESAMPLE sample(1) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tbl TABLESAMPLE sample(1)" +== 068 +-- truncate_limit: 50 +SELECT xmltable.* FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text) +-- +TABLE: name="xmlelements" schema="" table="xmlelements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmlelements, xmltable(('/root')..." +== 069 +-- truncate_limit: 50 +SELECT jt.* FROM my_films, JSON_TABLE (js, '$.favorites[*]' COLUMNS (id FOR ORDINALITY, kind text PATH '$.kind')) AS jt; +-- +TABLE: name="my_films" schema="" table="my_films" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM my_films, JSON_TABLE(js , '$.fa..." +== 070 +-- truncate_limit: 50 +select u.* from (select * from users) u +-- +TABLE: name="users" schema="" table="users" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT u.* FROM (SELECT * FROM users) u" +== 071 +-- truncate_limit: 50 +select users.id from users where 1 = (select count(*) from user_roles) +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT users.id FROM users WHERE ..." +== 072 +-- truncate_limit: 50 + + SELECT * + FROM pg_catalog.pg_class c + JOIN ( + SELECT 17650 AS oid + UNION ALL + SELECT 17663 AS oid + ) vals ON c.oid = vals.oid + +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_catalog.pg_class c JOIN (SELEC..." +== 073 +-- truncate_limit: 50 + + select users.* + from users + where users.id IN (select user_roles.user_id from user_roles) + and (users.created_at between '2016-06-01' and '2016-06-30') + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT users.* FROM users WHERE ..." +== 074 +-- truncate_limit: 50 + + select users.* + from users + order by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM users ORDER BY (SELECT ... FROM..." +== 075 +-- truncate_limit: 50 + + select users.* + from users + order by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) asc, ( + select max(user_logins.role_id) + from user_logins + where user_logins.user_id = users.id + ) desc + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +FILTER: schema="" table="user_logins" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM users ORDER BY (SELECT ... FROM..." +== 076 +-- truncate_limit: 50 + + select users.* + from users + group by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM users GROUP BY (SELECT ... FROM..." +== 077 +-- truncate_limit: 50 + + select users.* + from users + group by ( + select max(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ), ( + select max(user_logins.role_id) + from user_logins + where user_logins.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +FILTER: schema="" table="user_logins" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM users GROUP BY (SELECT ... FROM..." +== 078 +-- truncate_limit: 50 + + select users.* + from users + group by users.id + having 1 > ( + select count(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM users GROUP BY users.id HAVING ..." +== 079 +-- truncate_limit: 50 + + select users.* + from users + group by users.id + having true and 1 > ( + select count(user_roles.role_id) + from user_roles + where user_roles.user_id = users.id + ) + +-- +TABLE: name="users" schema="" table="users" ctx=Select +TABLE: name="user_roles" schema="" table="user_roles" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="user_roles" column="user_id" +FILTER: schema="" table="users" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM users GROUP BY users.id HAVING ..." +== 080 +-- truncate_limit: 50 + + select foo.* + from foo + join ( select * from bar ) b + on b.baz = foo.quux + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM foo JOIN (SELECT * FROM bar) b ..." +== 081 +-- truncate_limit: 50 + + SELECT * + FROM foo + INNER JOIN join_a ON foo.id = join_a.id AND join_a.id IN ( + SELECT id + FROM sub_a + INNER JOIN sub_b ON sub_a.id = sub_b.id AND sub_b.id IN ( + SELECT id + FROM sub_c + INNER JOIN sub_d ON sub_c.id IN (SELECT id from sub_e) + ) + ) + INNER JOIN join_b ON foo.id = join_b.id AND join_b.id IN ( + SELECT id FROM sub_f + ) + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="join_a" schema="" table="join_a" ctx=Select +TABLE: name="join_b" schema="" table="join_b" ctx=Select +TABLE: name="sub_a" schema="" table="sub_a" ctx=Select +TABLE: name="sub_b" schema="" table="sub_b" ctx=Select +TABLE: name="sub_c" schema="" table="sub_c" ctx=Select +TABLE: name="sub_d" schema="" table="sub_d" ctx=Select +TABLE: name="sub_e" schema="" table="sub_e" ctx=Select +TABLE: name="sub_f" schema="" table="sub_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo JOIN join_a ON foo.id = join_..." +== 082 +-- truncate_limit: 50 + + WITH cte_a AS ( + SELECT * FROM table_a + ), cte_b AS ( + SELECT * FROM table_b + ) + SELECT id FROM table_c + LEFT JOIN cte_b ON table_c.id = cte_b.c_id + UNION + SELECT * FROM cte_a + +-- +TABLE: name="table_a" schema="" table="table_a" ctx=Select +TABLE: name="table_b" schema="" table="table_b" ctx=Select +TABLE: name="table_c" schema="" table="table_c" ctx=Select +CTE: "cte_a" +CTE: "cte_b" +STMT: SelectStmt +TRUNCATED: "WITH cte_a AS (...), cte_b AS (...) SELECT id F..." +== 083 +-- truncate_limit: 50 + + WITH cte_a AS ( + SELECT * FROM table_a + ), cte_b AS ( + SELECT * FROM table_b + ) + SELECT id FROM table_c + LEFT JOIN cte_b ON table_c.id = cte_b.c_id + EXCEPT + SELECT * FROM cte_a + +-- +TABLE: name="table_a" schema="" table="table_a" ctx=Select +TABLE: name="table_b" schema="" table="table_b" ctx=Select +TABLE: name="table_c" schema="" table="table_c" ctx=Select +CTE: "cte_a" +CTE: "cte_b" +STMT: SelectStmt +TRUNCATED: "WITH cte_a AS (...), cte_b AS (...) SELECT id F..." +== 084 +-- truncate_limit: 50 + + WITH cte_a AS ( + SELECT * FROM table_a + ), cte_b AS ( + SELECT * FROM table_b + ) + SELECT id FROM table_c + LEFT JOIN cte_b ON table_c.id = cte_b.c_id + INTERSECT + SELECT * FROM cte_a + +-- +TABLE: name="table_a" schema="" table="table_a" ctx=Select +TABLE: name="table_b" schema="" table="table_b" ctx=Select +TABLE: name="table_c" schema="" table="table_c" ctx=Select +CTE: "cte_a" +CTE: "cte_b" +STMT: SelectStmt +TRUNCATED: "WITH cte_a AS (...), cte_b AS (...) SELECT id F..." +== 085 +-- truncate_limit: 50 + + SELECT GREATEST( + date_trunc($1, $2::timestamptz) + $3::interval, + COALESCE( + ( + SELECT first_aggregate_starts_at + FROM schema_aggregate_infos + WHERE base_table = $4 LIMIT $5 + ), + now() + $6::interval + ) + ) AS first_hourly_start_ts + +-- +TABLE: name="schema_aggregate_infos" schema="" table="schema_aggregate_infos" ctx=Select +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="" column="base_table" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 086 +-- truncate_limit: 50 + + SELECT + CASE + WHEN id IN (SELECT foo_id FROM when_a) THEN (SELECT MAX(id) FROM then_a) + WHEN id IN (SELECT foo_id FROM when_b) THEN (SELECT MAX(id) FROM then_b) + ELSE (SELECT MAX(id) FROM elsey) + END + FROM foo + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="when_a" schema="" table="when_a" ctx=Select +TABLE: name="then_a" schema="" table="then_a" ctx=Select +TABLE: name="when_b" schema="" table="when_b" ctx=Select +TABLE: name="then_b" schema="" table="then_b" ctx=Select +TABLE: name="elsey" schema="" table="elsey" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM foo" +== 087 +-- truncate_limit: 50 + + SELECT 1 + FROM foo + WHERE x = any(cast(array(SELECT a FROM bar) as bigint[])) + OR x = any(array(SELECT a FROM baz)::bigint[]) + +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="baz" schema="" table="baz" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM foo WHERE ..." +== 088 +-- truncate_limit: 50 +SELECT * FROM my_custom_func() +-- +FUNCTION: name="my_custom_func" function="my_custom_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_custom_func()" +== 089 +-- truncate_limit: 50 + + SELECT * + FROM unnest($1::text[]) AS a(x) + LEFT OUTER JOIN LATERAL ( + SELECT json_build_object($2, z.z) + FROM ( + SELECT * + FROM ( + SELECT row_to_json( + (SELECT * FROM (SELECT public.my_function(b) FROM public.c) d) + ) + ) e + ) f + ) AS g ON (1) + +-- +TABLE: name="public.c" schema="public" table="c" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="public.my_function" function="my_function" schema="public" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest($1::text[]) a(x) LEFT JOIN..." +== 090 +-- truncate_limit: 50 +insert into users(pk, name) values (1, 'bob'); +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users (pk, name) VALUES (1, 'bob')" +== 091 +-- truncate_limit: 50 +insert into users(pk, name) select pk, name from other_users; +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users (...) SELECT ... FROM other_u..." +== 092 +-- truncate_limit: 50 + + with cte as ( + select pk, name from other_users + ) + insert into users(pk, name) select * from cte; + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +CTE: "cte" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH cte AS (...) INSERT INTO users (...) SELEC..." +== 093 +-- truncate_limit: 50 +update users set name = 'bob'; +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE users SET name = 'bob'" +== 094 +-- truncate_limit: 50 +update users set name = (select name from other_users limit 1); +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE users SET ... = ..." +== 095 +-- truncate_limit: 50 + + with cte as ( + select name from other_users limit 1 + ) + update users set name = (select name from cte); + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +CTE: "cte" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "WITH cte AS (...) UPDATE users SET ... = ..." +== 096 +-- truncate_limit: 50 + + with cte as ( + select name from other_users limit 1 + ) + update users set name = (select name from cte); + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="other_users" schema="" table="other_users" ctx=Select +CTE: "cte" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "WITH cte AS (...) UPDATE users SET ... = ..." +== 097 +-- truncate_limit: 50 +DELETE FROM users; +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM users" +== 098 +-- truncate_limit: 50 + + DELETE FROM users USING foo + WHERE foo_id = foo.id AND foo.action = 'delete'; + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: DeleteStmt +TRUNCATED: "DELETE FROM users USING foo WHERE ..." +== 099 +-- truncate_limit: 50 + + DELETE FROM users USING foo + WHERE foo_id = foo.id AND foo.action = 'delete'; + +-- +TABLE: name="users" schema="" table="users" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: DeleteStmt +TRUNCATED: "DELETE FROM users USING foo WHERE ..." +== 100 +-- truncate_limit: 50 +DROP TYPE IF EXISTS repack.pk_something +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE IF EXISTS repack.pk_something" +== 101 +-- truncate_limit: 50 +SELECT * FROM x WHERE y = $1 AND z = 1 +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE y = $1 AND z = 1" +== 102 +-- truncate_limit: 50 +SELECT * FROM x WHERE x.y = $1 AND x.z = 1 +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE x.y = $1 AND x.z = 1" +== 103 +-- truncate_limit: 50 +WITH a AS (SELECT * FROM x WHERE x.y = $1 AND x.z = 1) SELECT * FROM a WHERE b = 5 +-- +TABLE: name="x" schema="" table="x" ctx=Select +CTE: "a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +TRUNCATED: "WITH a AS (...) SELECT * FROM a WHERE b = 5" +== 104 +-- truncate_limit: 50 +SELECT * FROM x WHERE x.y IS TRUE AND x.z IS NOT FALSE +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ..." +== 105 +-- truncate_limit: 50 +SELECT * FROM x WHERE x.y IS NULL AND x.z IS NOT NULL +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ..." +== 106 +-- truncate_limit: 50 +SELECT * FROM x WHERE x.y = COALESCE(z.a, z.b) +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE x.y = COALESCE(z.a, z.b)" +== 107 +-- truncate_limit: 50 +SELECT * FROM x where y = $1 UNION SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ... UNION SELECT * FROM x..." +== 108 +-- truncate_limit: 50 +SELECT * FROM x where y = $1 UNION ALL SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ... UNION ALL SELECT * FR..." +== 109 +-- truncate_limit: 50 +SELECT * FROM x where y = $1 EXCEPT SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ... EXCEPT SELECT * FROM ..." +== 110 +-- truncate_limit: 50 +SELECT * FROM x where y = $1 EXCEPT ALL SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ... EXCEPT ALL SELECT * F..." +== 111 +-- truncate_limit: 50 +SELECT * FROM x where y = $1 INTERSECT SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ... INTERSECT SELECT * FR..." +== 112 +-- truncate_limit: 50 +SELECT * FROM x where y = $1 INTERSECT ALL SELECT * FROM x where z = $2 +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ... INTERSECT ALL SELECT ..." +== 113 +-- truncate_limit: 50 +SELECT a, y, z FROM x WHERE x.y = $1 AND x.z = 1 +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT a, y, z FROM x WHERE x.y = $1 AND x.z = 1" +== 114 +-- truncate_limit: 50 +SELECT * FROM x WHERE x.y = $1 AND x.z = 1 ORDER BY a, b +-- +TABLE: name="x" schema="" table="x" ctx=Select +FILTER: schema="" table="x" column="y" +FILTER: schema="" table="x" column="z" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x WHERE ... ORDER BY a, b" +== 115 +-- truncate_limit: 50 +GRANT SELECT ON ALL TABLES IN SCHEMA public TO myrole +-- +STMT: GrantStmt +TRUNCATED: "GRANT select ON ALL TABLES IN SCHEMA public TO ..." +== 116 +-- truncate_limit: 50 +SELECT * FROM b.c WHERE a.b.c = 1 +-- +TABLE: name="b.c" schema="b" table="c" ctx=Select +FILTER: schema="a" table="b" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM b.c WHERE a.b.c = 1" diff --git a/parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json b/parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json new file mode 100644 index 0000000..251a33e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json @@ -0,0 +1,42 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/advisory_lock.test b/parser/testdata/summary_truncate/postgres_regress/advisory_lock.test new file mode 100644 index 0000000..3827ffc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/advisory_lock.test @@ -0,0 +1,394 @@ +== 001 +-- truncate_limit: 100 +|-- +-- ADVISORY LOCKS +|-- + +SELECT oid AS datoid FROM pg_database WHERE datname = current_database() +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +TRUNCATED: "SELECT oid AS datoid FROM pg_database WHERE datname = current_database()" +== 002 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 003 +-- truncate_limit: 100 +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 004 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- truncate_limit: 100 +-- pg_advisory_unlock_all() shouldn't release xact locks +SELECT pg_advisory_unlock_all() +-- +FUNCTION: name="pg_advisory_unlock_all" function="pg_advisory_unlock_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_advisory_unlock_all()" +== 006 +-- truncate_limit: 100 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- truncate_limit: 100 +-- can't unlock xact locks +SELECT + pg_advisory_unlock(1), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 008 +-- truncate_limit: 100 +-- automatically release xact locks at commit +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 009 +-- truncate_limit: 100 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 010 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 011 +-- truncate_limit: 100 +-- holding both session and xact locks on the same objects, xact first +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 012 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 013 +-- truncate_limit: 100 +SELECT + pg_advisory_lock(1), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 014 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 015 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 016 +-- truncate_limit: 100 +-- unlocking session locks +SELECT + pg_advisory_unlock(1), pg_advisory_unlock(1), + pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), + pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 017 +-- truncate_limit: 100 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 018 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 019 +-- truncate_limit: 100 +-- holding both session and xact locks on the same objects, session first +SELECT + pg_advisory_lock(1), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 020 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 021 +-- truncate_limit: 100 +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 022 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 023 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +-- truncate_limit: 100 +-- releasing all session locks +SELECT pg_advisory_unlock_all() +-- +FUNCTION: name="pg_advisory_unlock_all" function="pg_advisory_unlock_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_advisory_unlock_all()" +== 025 +-- truncate_limit: 100 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 027 +-- truncate_limit: 100 +-- grabbing txn locks multiple times + +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock(1), + pg_advisory_xact_lock_shared(2), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock(1, 1), + pg_advisory_xact_lock_shared(2, 2), pg_advisory_xact_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock" function="pg_advisory_xact_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 028 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 030 +-- truncate_limit: 100 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 031 +-- truncate_limit: 100 +-- grabbing session locks multiple times + +SELECT + pg_advisory_lock(1), pg_advisory_lock(1), + pg_advisory_lock_shared(2), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock(1, 1), + pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 032 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 033 +-- truncate_limit: 100 +SELECT + pg_advisory_unlock(1), pg_advisory_unlock(1), + pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), + pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock" function="pg_advisory_unlock" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_unlock_shared" function="pg_advisory_unlock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 034 +-- truncate_limit: 100 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 035 +-- truncate_limit: 100 +-- .. and releasing them all at once + +SELECT + pg_advisory_lock(1), pg_advisory_lock(1), + pg_advisory_lock_shared(2), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock(1, 1), + pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +FUNCTION: name="pg_advisory_lock_shared" function="pg_advisory_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 036 +-- truncate_limit: 100 +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid + ORDER BY classid, objid, objsubid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 037 +-- truncate_limit: 100 +SELECT pg_advisory_unlock_all() +-- +FUNCTION: name="pg_advisory_unlock_all" function="pg_advisory_unlock_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_advisory_unlock_all()" +== 038 +-- truncate_limit: 100 +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json b/parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json new file mode 100644 index 0000000..592c419 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json @@ -0,0 +1,518 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/aggregates.test b/parser/testdata/summary_truncate/postgres_regress/aggregates.test new file mode 100644 index 0000000..c66a4f6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/aggregates.test @@ -0,0 +1,5035 @@ +== 001 +-- truncate_limit: 100 +|-- +-- AGGREGATES +|-- + +-- directory paths are passed to us in environment variables + +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO 0" +== 002 +-- truncate_limit: 100 +-- prepare some test data +CREATE TABLE aggtest ( + a int2, + b float4 +) +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE aggtest (a int2, b float4)" +== 003 +-- truncate_limit: 100 +COPY aggtest FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +ANALYZE aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE aggtest" +== 005 +-- truncate_limit: 100 +SELECT avg(four) AS avg_1 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(four) AS avg_1 FROM onek" +== 006 +-- truncate_limit: 100 +SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100 +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100" +== 007 +-- truncate_limit: 100 +SELECT any_value(v) FROM (VALUES (1), (2), (3)) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT any_value(v) FROM (VALUES (1), (2), (3)) v(v)" +== 008 +-- truncate_limit: 100 +SELECT any_value(v) FROM (VALUES (NULL)) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT any_value(v) FROM (VALUES (NULL)) v(v)" +== 009 +-- truncate_limit: 100 +SELECT any_value(v) FROM (VALUES (NULL), (1), (2)) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT any_value(v) FROM (VALUES (NULL), (1), (2)) v(v)" +== 010 +-- truncate_limit: 100 +SELECT any_value(v) FROM (VALUES (array['hello', 'world'])) AS v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT any_value(v) FROM (VALUES (ARRAY['hello', 'world'])) v(v)" +== 011 +-- truncate_limit: 100 +-- In 7.1, avg(float4) is computed using float8 arithmetic. +-- Round the result to 3 digits to avoid platform-specific results. + +SELECT avg(b)::numeric(10,3) AS avg_107_943 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(b)::numeric(10, 3) AS avg_107_943 FROM aggtest" +== 012 +-- truncate_limit: 100 +SELECT avg(gpa) AS avg_3_4 FROM ONLY student +-- +TABLE: name="student" schema="" table="student" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(gpa) AS avg_3_4 FROM ONLY student" +== 013 +-- truncate_limit: 100 +SELECT sum(four) AS sum_1500 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(four) AS sum_1500 FROM onek" +== 014 +-- truncate_limit: 100 +SELECT sum(a) AS sum_198 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(a) AS sum_198 FROM aggtest" +== 015 +-- truncate_limit: 100 +SELECT sum(b) AS avg_431_773 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(b) AS avg_431_773 FROM aggtest" +== 016 +-- truncate_limit: 100 +SELECT sum(gpa) AS avg_6_8 FROM ONLY student +-- +TABLE: name="student" schema="" table="student" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(gpa) AS avg_6_8 FROM ONLY student" +== 017 +-- truncate_limit: 100 +SELECT max(four) AS max_3 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(four) AS max_3 FROM onek" +== 018 +-- truncate_limit: 100 +SELECT max(a) AS max_100 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(a) AS max_100 FROM aggtest" +== 019 +-- truncate_limit: 100 +SELECT max(aggtest.b) AS max_324_78 FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(aggtest.b) AS max_324_78 FROM aggtest" +== 020 +-- truncate_limit: 100 +SELECT max(student.gpa) AS max_3_7 FROM student +-- +TABLE: name="student" schema="" table="student" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(student.gpa) AS max_3_7 FROM student" +== 021 +-- truncate_limit: 100 +SELECT stddev_pop(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop(b) FROM aggtest" +== 022 +-- truncate_limit: 100 +SELECT stddev_samp(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_samp(b) FROM aggtest" +== 023 +-- truncate_limit: 100 +SELECT var_pop(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop(b) FROM aggtest" +== 024 +-- truncate_limit: 100 +SELECT var_samp(b) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_samp(b) FROM aggtest" +== 025 +-- truncate_limit: 100 +SELECT stddev_pop(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop(b::numeric) FROM aggtest" +== 026 +-- truncate_limit: 100 +SELECT stddev_samp(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_samp(b::numeric) FROM aggtest" +== 027 +-- truncate_limit: 100 +SELECT var_pop(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop(b::numeric) FROM aggtest" +== 028 +-- truncate_limit: 100 +SELECT var_samp(b::numeric) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_samp(b::numeric) FROM aggtest" +== 029 +-- truncate_limit: 100 +-- population variance is defined for a single tuple, sample variance +-- is not +SELECT var_pop(1.0::float8), var_samp(2.0::float8) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop((1.0)::float8), var_samp((2.0)::float8)" +== 030 +-- truncate_limit: 100 +SELECT stddev_pop(3.0::float8), stddev_samp(4.0::float8) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop((3.0)::float8), stddev_samp((4.0)::float8)" +== 031 +-- truncate_limit: 100 +SELECT var_pop('inf'::float8), var_samp('inf'::float8) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop('inf'::float8), var_samp('inf'::float8)" +== 032 +-- truncate_limit: 100 +SELECT stddev_pop('inf'::float8), stddev_samp('inf'::float8) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop('inf'::float8), stddev_samp('inf'::float8)" +== 033 +-- truncate_limit: 100 +SELECT var_pop('nan'::float8), var_samp('nan'::float8) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop('nan'::float8), var_samp('nan'::float8)" +== 034 +-- truncate_limit: 100 +SELECT stddev_pop('nan'::float8), stddev_samp('nan'::float8) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop('nan'::float8), stddev_samp('nan'::float8)" +== 035 +-- truncate_limit: 100 +SELECT var_pop(1.0::float4), var_samp(2.0::float4) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop((1.0)::float4), var_samp((2.0)::float4)" +== 036 +-- truncate_limit: 100 +SELECT stddev_pop(3.0::float4), stddev_samp(4.0::float4) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop((3.0)::float4), stddev_samp((4.0)::float4)" +== 037 +-- truncate_limit: 100 +SELECT var_pop('inf'::float4), var_samp('inf'::float4) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop('inf'::float4), var_samp('inf'::float4)" +== 038 +-- truncate_limit: 100 +SELECT stddev_pop('inf'::float4), stddev_samp('inf'::float4) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop('inf'::float4), stddev_samp('inf'::float4)" +== 039 +-- truncate_limit: 100 +SELECT var_pop('nan'::float4), var_samp('nan'::float4) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop('nan'::float4), var_samp('nan'::float4)" +== 040 +-- truncate_limit: 100 +SELECT stddev_pop('nan'::float4), stddev_samp('nan'::float4) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop('nan'::float4), stddev_samp('nan'::float4)" +== 041 +-- truncate_limit: 100 +SELECT var_pop(1.0::numeric), var_samp(2.0::numeric) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop((1.0)::numeric), var_samp((2.0)::numeric)" +== 042 +-- truncate_limit: 100 +SELECT stddev_pop(3.0::numeric), stddev_samp(4.0::numeric) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop((3.0)::numeric), stddev_samp((4.0)::numeric)" +== 043 +-- truncate_limit: 100 +SELECT var_pop('inf'::numeric), var_samp('inf'::numeric) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop('inf'::numeric), var_samp('inf'::numeric)" +== 044 +-- truncate_limit: 100 +SELECT stddev_pop('inf'::numeric), stddev_samp('inf'::numeric) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop('inf'::numeric), stddev_samp('inf'::numeric)" +== 045 +-- truncate_limit: 100 +SELECT var_pop('nan'::numeric), var_samp('nan'::numeric) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT var_pop('nan'::numeric), var_samp('nan'::numeric)" +== 046 +-- truncate_limit: 100 +SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric)" +== 047 +-- truncate_limit: 100 +-- verify correct results for null and NaN inputs +select sum(null::int4) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(NULL::int4) FROM generate_series(1, 3)" +== 048 +-- truncate_limit: 100 +select sum(null::int8) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(NULL::int8) FROM generate_series(1, 3)" +== 049 +-- truncate_limit: 100 +select sum(null::numeric) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(NULL::numeric) FROM generate_series(1, 3)" +== 050 +-- truncate_limit: 100 +select sum(null::float8) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(NULL::float8) FROM generate_series(1, 3)" +== 051 +-- truncate_limit: 100 +select avg(null::int4) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(NULL::int4) FROM generate_series(1, 3)" +== 052 +-- truncate_limit: 100 +select avg(null::int8) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(NULL::int8) FROM generate_series(1, 3)" +== 053 +-- truncate_limit: 100 +select avg(null::numeric) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(NULL::numeric) FROM generate_series(1, 3)" +== 054 +-- truncate_limit: 100 +select avg(null::float8) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(NULL::float8) FROM generate_series(1, 3)" +== 055 +-- truncate_limit: 100 +select sum('NaN'::numeric) from generate_series(1,3) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum('NaN'::numeric) FROM generate_series(1, 3)" +== 056 +-- truncate_limit: 100 +select avg('NaN'::numeric) from generate_series(1,3) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg('NaN'::numeric) FROM generate_series(1, 3)" +== 057 +-- truncate_limit: 100 +-- verify correct results for infinite inputs +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('1'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) FROM (VALUES ('1'), ('infinity')) v(x)" +== 058 +-- truncate_limit: 100 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('1')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) FROM (VALUES ('infinity'), ('1')) v(x)" +== 059 +-- truncate_limit: 100 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) FROM (VALUES (...)) v(x)" +== 060 +-- truncate_limit: 100 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) FROM (VALUES (...)) v(x)" +== 061 +-- truncate_limit: 100 +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('-infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) FROM (VALUES (...)) v(x)" +== 062 +-- truncate_limit: 100 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('1'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM (VALUES ('1'), ('infinity')) v(x)" +== 063 +-- truncate_limit: 100 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('infinity'), ('1')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM (VALUES ('infinity'), ('1')) v(x)" +== 064 +-- truncate_limit: 100 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM (VALUES (...)) v(x)" +== 065 +-- truncate_limit: 100 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('-infinity'), ('infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM (VALUES (...)) v(x)" +== 066 +-- truncate_limit: 100 +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('-infinity'), ('-infinity')) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM (VALUES (...)) v(x)" +== 067 +-- truncate_limit: 100 +-- test accuracy with a large input offset +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (100000003), (100000004), (100000006), (100000007)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(x::float8), var_pop(x::float8) FROM (VALUES (...)) v(x)" +== 068 +-- truncate_limit: 100 +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (7000000000005), (7000000000007)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(x::float8), var_pop(x::float8) FROM (VALUES (7000000000005), (7000000000007)) v(x)" +== 069 +-- truncate_limit: 100 +-- SQL2003 binary aggregates +SELECT regr_count(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_count" function="regr_count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regr_count(b, a) FROM aggtest" +== 070 +-- truncate_limit: 100 +SELECT regr_sxx(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regr_sxx(b, a) FROM aggtest" +== 071 +-- truncate_limit: 100 +SELECT regr_syy(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regr_syy(b, a) FROM aggtest" +== 072 +-- truncate_limit: 100 +SELECT regr_sxy(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regr_sxy(b, a) FROM aggtest" +== 073 +-- truncate_limit: 100 +SELECT regr_avgx(b, a), regr_avgy(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_avgx" function="regr_avgx" schema="" ctx=Call +FUNCTION: name="regr_avgy" function="regr_avgy" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regr_avgx(b, a), regr_avgy(b, a) FROM aggtest" +== 074 +-- truncate_limit: 100 +SELECT regr_r2(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_r2" function="regr_r2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regr_r2(b, a) FROM aggtest" +== 075 +-- truncate_limit: 100 +SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="regr_slope" function="regr_slope" schema="" ctx=Call +FUNCTION: name="regr_intercept" function="regr_intercept" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest" +== 076 +-- truncate_limit: 100 +SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest" +== 077 +-- truncate_limit: 100 +SELECT corr(b, a) FROM aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="corr" function="corr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT corr(b, a) FROM aggtest" +== 078 +-- truncate_limit: 100 +-- check single-tuple behavior +SELECT covar_pop(1::float8,2::float8), covar_samp(3::float8,4::float8) +-- +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT covar_pop(1::float8, 2::float8), covar_samp(3::float8, 4::float8)" +== 079 +-- truncate_limit: 100 +SELECT covar_pop(1::float8,'inf'::float8), covar_samp(3::float8,'inf'::float8) +-- +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT covar_pop(1::float8, 'inf'::float8), covar_samp(3::float8, 'inf'::float8)" +== 080 +-- truncate_limit: 100 +SELECT covar_pop(1::float8,'nan'::float8), covar_samp(3::float8,'nan'::float8) +-- +FUNCTION: name="covar_pop" function="covar_pop" schema="" ctx=Call +FUNCTION: name="covar_samp" function="covar_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT covar_pop(1::float8, 'nan'::float8), covar_samp(3::float8, 'nan'::float8)" +== 081 +-- truncate_limit: 100 +-- test accum and combine functions directly +CREATE TABLE regr_test (x float8, y float8) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE regr_test (x float8, y float8)" +== 082 +-- truncate_limit: 100 +INSERT INTO regr_test VALUES (10,150),(20,250),(30,350),(80,540),(100,200) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO regr_test VALUES (10, 150), (20, 250), (30, 350), (80, 540), (100, 200)" +== 083 +-- truncate_limit: 100 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30,80) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM regr_test WHERE x IN (10, 20, 30, 80)" +== 084 +-- truncate_limit: 100 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*), sum(x), regr_sxx(y, x), sum(y), regr_syy(y, x), regr_sxy(y, x) FROM regr_test" +== 085 +-- truncate_limit: 100 +SELECT float8_accum('{4,140,2900}'::float8[], 100) +-- +FUNCTION: name="float8_accum" function="float8_accum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8_accum('{4,140,2900}'::float8[], 100)" +== 086 +-- truncate_limit: 100 +SELECT float8_regr_accum('{4,140,2900,1290,83075,15050}'::float8[], 200, 100) +-- +FUNCTION: name="float8_regr_accum" function="float8_regr_accum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8_regr_accum('{4,140,2900,1290,83075,15050}'::float8[], 200, 100)" +== 087 +-- truncate_limit: 100 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM regr_test WHERE x IN (10, 20, 30)" +== 088 +-- truncate_limit: 100 +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (80,100) +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_sxx" function="regr_sxx" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_syy" function="regr_syy" schema="" ctx=Call +FUNCTION: name="regr_sxy" function="regr_sxy" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM regr_test WHERE x IN (80, 100)" +== 089 +-- truncate_limit: 100 +SELECT float8_combine('{3,60,200}'::float8[], '{0,0,0}'::float8[]) +-- +FUNCTION: name="float8_combine" function="float8_combine" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8_combine('{3,60,200}'::float8[], '{0,0,0}'::float8[])" +== 090 +-- truncate_limit: 100 +SELECT float8_combine('{0,0,0}'::float8[], '{2,180,200}'::float8[]) +-- +FUNCTION: name="float8_combine" function="float8_combine" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8_combine('{0,0,0}'::float8[], '{2,180,200}'::float8[])" +== 091 +-- truncate_limit: 100 +SELECT float8_combine('{3,60,200}'::float8[], '{2,180,200}'::float8[]) +-- +FUNCTION: name="float8_combine" function="float8_combine" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8_combine('{3,60,200}'::float8[], '{2,180,200}'::float8[])" +== 092 +-- truncate_limit: 100 +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{0,0,0,0,0,0}'::float8[]) +-- +FUNCTION: name="float8_regr_combine" function="float8_regr_combine" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], '{0,0,0,0,0,0}'::float8[])" +== 093 +-- truncate_limit: 100 +SELECT float8_regr_combine('{0,0,0,0,0,0}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]) +-- +FUNCTION: name="float8_regr_combine" function="float8_regr_combine" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8_regr_combine('{0,0,0,0,0,0}'::float8[], '{2,180,200,740,57800,-3400}'::float8[])" +== 094 +-- truncate_limit: 100 +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]) +-- +FUNCTION: name="float8_regr_combine" function="float8_regr_combine" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 095 +-- truncate_limit: 100 +DROP TABLE regr_test +-- +TABLE: name="regr_test" schema="" table="regr_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE regr_test" +== 096 +-- truncate_limit: 100 +-- test count, distinct +SELECT count(four) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(four) AS cnt_1000 FROM onek" +== 097 +-- truncate_limit: 100 +SELECT count(DISTINCT four) AS cnt_4 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT four) AS cnt_4 FROM onek" +== 098 +-- truncate_limit: 100 +select ten, count(*), sum(four) from onek +group by ten order by ten +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ten, count(*), sum(four) FROM onek GROUP BY ten ORDER BY ten" +== 099 +-- truncate_limit: 100 +select ten, count(four), sum(DISTINCT four) from onek +group by ten order by ten +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ten, count(four), sum(DISTINCT four) FROM onek GROUP BY ten ORDER BY ten" +== 100 +-- truncate_limit: 100 +-- user-defined aggregates +SELECT newavg(four) AS avg_1 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newavg" function="newavg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT newavg(four) AS avg_1 FROM onek" +== 101 +-- truncate_limit: 100 +SELECT newsum(four) AS sum_1500 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newsum" function="newsum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT newsum(four) AS sum_1500 FROM onek" +== 102 +-- truncate_limit: 100 +SELECT newcnt(four) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newcnt" function="newcnt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT newcnt(four) AS cnt_1000 FROM onek" +== 103 +-- truncate_limit: 100 +SELECT newcnt(*) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="newcnt" function="newcnt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT newcnt(*) AS cnt_1000 FROM onek" +== 104 +-- truncate_limit: 100 +SELECT oldcnt(*) AS cnt_1000 FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="oldcnt" function="oldcnt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT oldcnt(*) AS cnt_1000 FROM onek" +== 105 +-- truncate_limit: 100 +SELECT sum2(q1,q2) FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="sum2" function="sum2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum2(q1, q2) FROM int8_tbl" +== 106 +-- truncate_limit: 100 +-- test for outer-level aggregates + +-- this should work +select ten, sum(distinct four) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek a GROUP BY ten HAVING EXISTS (SELECT 1 FROM onek b WHERE ...)" +== 107 +-- truncate_limit: 100 +-- this should fail because subquery has an agg of its own in WHERE +select ten, sum(distinct four) from onek a +group by ten +having exists (select 1 from onek b + where sum(distinct a.four + b.four) = b.four) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek a GROUP BY ten HAVING EXISTS (SELECT 1 FROM onek b WHERE ...)" +== 108 +-- truncate_limit: 100 +-- Test handling of sublinks within outer-level aggregates. +-- Per bug report from Daniel Grace. +select + (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1))) +from tenk1 o +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i"="tenk1" +ALIAS: "o"="tenk1" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT max((SELECT i.unique2 FROM tenk1 i WHERE i.unique1 = o.unique1))) FROM tenk1 o" +== 109 +-- truncate_limit: 100 +-- Test handling of Params within aggregate arguments in hashed aggregation. +-- Per bug report from Jeevan Chalke. +explain (verbose, costs off) +select s1, s2, sm +from generate_series(1, 3) s1, + lateral (select s2, sum(s1 + s2) sm + from generate_series(1, 3) s2 group by s2) ss +order by 1, 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT s1, s2, sm FROM generate_series(1, 3) s1, LATERAL (SELECT s2,..." +== 110 +-- truncate_limit: 100 +select s1, s2, sm +from generate_series(1, 3) s1, + lateral (select s2, sum(s1 + s2) sm + from generate_series(1, 3) s2 group by s2) ss +order by 1, 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 3) s1, LATERAL (SELECT ... FROM generate_series(1, 3) s2 GROUP..." +== 111 +-- truncate_limit: 100 +explain (verbose, costs off) +select array(select sum(x+y) s + from generate_series(1,3) y group by y order by s) + from generate_series(1,3) x +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT ARRAY(SELECT sum(x + y) AS s FROM generate_series(1, 3) y GRO..." +== 112 +-- truncate_limit: 100 +select array(select sum(x+y) s + from generate_series(1,3) y group by y order by s) + from generate_series(1,3) x +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 3) x" +== 113 +-- truncate_limit: 100 +|-- +-- test for bitwise integer aggregates +|-- +CREATE TEMPORARY TABLE bitwise_test( + i2 INT2, + i4 INT4, + i8 INT8, + i INTEGER, + x INT2, + y BIT(4) +) +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE bitwise_test (i2 int2, i4 int4, i8 int8, i int, x int2, y pg_catalog.bit(4))" +== 114 +-- truncate_limit: 100 +-- empty case +SELECT + BIT_AND(i2) AS "?", + BIT_OR(i4) AS "?", + BIT_XOR(i8) AS "?" +FROM bitwise_test +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=Select +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bit_and(i2) AS \"?\", bit_or(i4) AS \"?\", bit_xor(i8) AS \"?\" FROM bitwise_test" +== 115 +-- truncate_limit: 100 +COPY bitwise_test FROM STDIN NULL 'null' +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY bitwise_test FROM STDIN WITH (NULL 'null')" +== 116 +-- truncate_limit: 100 +SELECT + BIT_AND(i2) AS "1", + BIT_AND(i4) AS "1", + BIT_AND(i8) AS "1", + BIT_AND(i) AS "?", + BIT_AND(x) AS "0", + BIT_AND(y) AS "0100", + + BIT_OR(i2) AS "7", + BIT_OR(i4) AS "7", + BIT_OR(i8) AS "7", + BIT_OR(i) AS "?", + BIT_OR(x) AS "7", + BIT_OR(y) AS "1101", + + BIT_XOR(i2) AS "5", + BIT_XOR(i4) AS "5", + BIT_XOR(i8) AS "5", + BIT_XOR(i) AS "?", + BIT_XOR(x) AS "7", + BIT_XOR(y) AS "1101" +FROM bitwise_test +-- +TABLE: name="bitwise_test" schema="" table="bitwise_test" ctx=Select +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_and" function="bit_and" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_or" function="bit_or" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +FUNCTION: name="bit_xor" function="bit_xor" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bitwise_test" +== 117 +-- truncate_limit: 100 +|-- +-- test boolean aggregates +|-- +-- first test all possible transition and final states + +SELECT + -- boolean and transitions + -- null because strict + booland_statefunc(NULL, NULL) IS NULL AS "t", + booland_statefunc(TRUE, NULL) IS NULL AS "t", + booland_statefunc(FALSE, NULL) IS NULL AS "t", + booland_statefunc(NULL, TRUE) IS NULL AS "t", + booland_statefunc(NULL, FALSE) IS NULL AS "t", + -- and actual computations + booland_statefunc(TRUE, TRUE) AS "t", + NOT booland_statefunc(TRUE, FALSE) AS "t", + NOT booland_statefunc(FALSE, TRUE) AS "t", + NOT booland_statefunc(FALSE, FALSE) AS "t" +-- +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +FUNCTION: name="booland_statefunc" function="booland_statefunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 118 +-- truncate_limit: 100 +SELECT + -- boolean or transitions + -- null because strict + boolor_statefunc(NULL, NULL) IS NULL AS "t", + boolor_statefunc(TRUE, NULL) IS NULL AS "t", + boolor_statefunc(FALSE, NULL) IS NULL AS "t", + boolor_statefunc(NULL, TRUE) IS NULL AS "t", + boolor_statefunc(NULL, FALSE) IS NULL AS "t", + -- actual computations + boolor_statefunc(TRUE, TRUE) AS "t", + boolor_statefunc(TRUE, FALSE) AS "t", + boolor_statefunc(FALSE, TRUE) AS "t", + NOT boolor_statefunc(FALSE, FALSE) AS "t" +-- +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +FUNCTION: name="boolor_statefunc" function="boolor_statefunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 119 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE bool_test( + b1 BOOL, + b2 BOOL, + b3 BOOL, + b4 BOOL) +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE bool_test (b1 bool, b2 bool, b3 bool, b4 bool)" +== 120 +-- truncate_limit: 100 +-- empty case +SELECT + BOOL_AND(b1) AS "n", + BOOL_OR(b3) AS "n" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bool_and(b1) AS n, bool_or(b3) AS n FROM bool_test" +== 121 +-- truncate_limit: 100 +COPY bool_test FROM STDIN NULL 'null' +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY bool_test FROM STDIN WITH (NULL 'null')" +== 122 +-- truncate_limit: 100 +SELECT + BOOL_AND(b1) AS "f", + BOOL_AND(b2) AS "t", + BOOL_AND(b3) AS "f", + BOOL_AND(b4) AS "n", + BOOL_AND(NOT b2) AS "f", + BOOL_AND(NOT b3) AS "t" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bool_test" +== 123 +-- truncate_limit: 100 +SELECT + EVERY(b1) AS "f", + EVERY(b2) AS "t", + EVERY(b3) AS "f", + EVERY(b4) AS "n", + EVERY(NOT b2) AS "f", + EVERY(NOT b3) AS "t" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +FUNCTION: name="every" function="every" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bool_test" +== 124 +-- truncate_limit: 100 +SELECT + BOOL_OR(b1) AS "t", + BOOL_OR(b2) AS "t", + BOOL_OR(b3) AS "f", + BOOL_OR(b4) AS "n", + BOOL_OR(NOT b2) AS "f", + BOOL_OR(NOT b3) AS "t" +FROM bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bool_test" +== 125 +-- truncate_limit: 100 +|-- +-- Test cases that should be optimized into indexscans instead of +-- the generic aggregate implementation. +|-- + +-- Basic cases +explain (costs off) + select min(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT min(unique1) FROM tenk1" +== 126 +-- truncate_limit: 100 +select min(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(unique1) FROM tenk1" +== 127 +-- truncate_limit: 100 +explain (costs off) + select max(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique1) FROM tenk1" +== 128 +-- truncate_limit: 100 +select max(unique1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(unique1) FROM tenk1" +== 129 +-- truncate_limit: 100 +explain (costs off) + select max(unique1) from tenk1 where unique1 < 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique1) FROM tenk1 WHERE unique1 < 42" +== 130 +-- truncate_limit: 100 +select max(unique1) from tenk1 where unique1 < 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT max(unique1) FROM tenk1 WHERE unique1 < 42" +== 131 +-- truncate_limit: 100 +explain (costs off) + select max(unique1) from tenk1 where unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique1) FROM tenk1 WHERE unique1 > 42" +== 132 +-- truncate_limit: 100 +select max(unique1) from tenk1 where unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT max(unique1) FROM tenk1 WHERE unique1 > 42" +== 133 +-- truncate_limit: 100 +-- the planner may choose a generic aggregate here if parallel query is +-- enabled, since that plan will be parallel safe and the "optimized" +-- plan, which has almost identical cost, will not be. we want to test +-- the optimized plan, so temporarily disable parallel query. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 134 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 0" +== 135 +-- truncate_limit: 100 +explain (costs off) + select max(unique1) from tenk1 where unique1 > 42000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique1) FROM tenk1 WHERE unique1 > 42000" +== 136 +-- truncate_limit: 100 +select max(unique1) from tenk1 where unique1 > 42000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT max(unique1) FROM tenk1 WHERE unique1 > 42000" +== 137 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 138 +-- truncate_limit: 100 +-- multi-column index (uses tenk1_thous_tenthous) +explain (costs off) + select max(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(tenthous) FROM tenk1 WHERE thousand = 33" +== 139 +-- truncate_limit: 100 +select max(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT max(tenthous) FROM tenk1 WHERE thousand = 33" +== 140 +-- truncate_limit: 100 +explain (costs off) + select min(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT min(tenthous) FROM tenk1 WHERE thousand = 33" +== 141 +-- truncate_limit: 100 +select min(tenthous) from tenk1 where thousand = 33 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT min(tenthous) FROM tenk1 WHERE thousand = 33" +== 142 +-- truncate_limit: 100 +-- check parameter propagation into an indexscan subquery +explain (costs off) + select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt + from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT f1, (SELECT min(unique1) FROM tenk1 WHERE unique1 > f1) AS gt FROM int..." +== 143 +-- truncate_limit: 100 +select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt + from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, (SELECT min(unique1) FROM tenk1 WHERE unique1 > f1) AS gt FROM int4_tbl" +== 144 +-- truncate_limit: 100 +-- check some cases that were handled incorrectly in 8.3.0 +explain (costs off) + select distinct max(unique2) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT max(unique2) FROM tenk1" +== 145 +-- truncate_limit: 100 +select distinct max(unique2) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT max(unique2) FROM tenk1" +== 146 +-- truncate_limit: 100 +explain (costs off) + select max(unique2) from tenk1 order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique2) FROM tenk1 ORDER BY 1" +== 147 +-- truncate_limit: 100 +select max(unique2) from tenk1 order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(unique2) FROM tenk1 ORDER BY 1" +== 148 +-- truncate_limit: 100 +explain (costs off) + select max(unique2) from tenk1 order by max(unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique2) FROM tenk1 ORDER BY max(unique2)" +== 149 +-- truncate_limit: 100 +select max(unique2) from tenk1 order by max(unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(unique2) FROM tenk1 ORDER BY max(unique2)" +== 150 +-- truncate_limit: 100 +explain (costs off) + select max(unique2) from tenk1 order by max(unique2)+1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique2) FROM tenk1 ORDER BY max(unique2) + 1" +== 151 +-- truncate_limit: 100 +select max(unique2) from tenk1 order by max(unique2)+1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(unique2) FROM tenk1 ORDER BY max(unique2) + 1" +== 152 +-- truncate_limit: 100 +explain (costs off) + select max(unique2), generate_series(1,3) as g from tenk1 order by g desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(unique2), generate_series(1, 3) AS g FROM tenk1 ORDER BY g DESC" +== 153 +-- truncate_limit: 100 +select max(unique2), generate_series(1,3) as g from tenk1 order by g desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(unique2), generate_series(1, 3) AS g FROM tenk1 ORDER BY g DESC" +== 154 +-- truncate_limit: 100 +-- interesting corner case: constant gets optimized into a seqscan +explain (costs off) + select max(100) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(100) FROM tenk1" +== 155 +-- truncate_limit: 100 +select max(100) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(100) FROM tenk1" +== 156 +-- truncate_limit: 100 +-- try it on an inheritance tree +create table minmaxtest(f1 int) +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE minmaxtest (f1 int)" +== 157 +-- truncate_limit: 100 +create table minmaxtest1() inherits (minmaxtest) +-- +TABLE: name="minmaxtest1" schema="" table="minmaxtest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE minmaxtest1 () INHERITS (minmaxtest)" +== 158 +-- truncate_limit: 100 +create table minmaxtest2() inherits (minmaxtest) +-- +TABLE: name="minmaxtest2" schema="" table="minmaxtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE minmaxtest2 () INHERITS (minmaxtest)" +== 159 +-- truncate_limit: 100 +create table minmaxtest3() inherits (minmaxtest) +-- +TABLE: name="minmaxtest3" schema="" table="minmaxtest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE minmaxtest3 () INHERITS (minmaxtest)" +== 160 +-- truncate_limit: 100 +create index minmaxtesti on minmaxtest(f1) +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX minmaxtesti ON minmaxtest USING btree (f1)" +== 161 +-- truncate_limit: 100 +create index minmaxtest1i on minmaxtest1(f1) +-- +TABLE: name="minmaxtest1" schema="" table="minmaxtest1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX minmaxtest1i ON minmaxtest1 USING btree (f1)" +== 162 +-- truncate_limit: 100 +create index minmaxtest2i on minmaxtest2(f1 desc) +-- +TABLE: name="minmaxtest2" schema="" table="minmaxtest2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX minmaxtest2i ON minmaxtest2 USING btree (f1 DESC)" +== 163 +-- truncate_limit: 100 +create index minmaxtest3i on minmaxtest3(f1) where f1 is not null +-- +TABLE: name="minmaxtest3" schema="" table="minmaxtest3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX minmaxtest3i ON minmaxtest3 USING btree (f1) WHERE f1 IS NOT NULL" +== 164 +-- truncate_limit: 100 +insert into minmaxtest values(11), (12) +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO minmaxtest VALUES (11), (12)" +== 165 +-- truncate_limit: 100 +insert into minmaxtest1 values(13), (14) +-- +TABLE: name="minmaxtest1" schema="" table="minmaxtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO minmaxtest1 VALUES (13), (14)" +== 166 +-- truncate_limit: 100 +insert into minmaxtest2 values(15), (16) +-- +TABLE: name="minmaxtest2" schema="" table="minmaxtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO minmaxtest2 VALUES (15), (16)" +== 167 +-- truncate_limit: 100 +insert into minmaxtest3 values(17), (18) +-- +TABLE: name="minmaxtest3" schema="" table="minmaxtest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO minmaxtest3 VALUES (17), (18)" +== 168 +-- truncate_limit: 100 +explain (costs off) + select min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT min(f1), max(f1) FROM minmaxtest" +== 169 +-- truncate_limit: 100 +select min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(f1), max(f1) FROM minmaxtest" +== 170 +-- truncate_limit: 100 +-- DISTINCT doesn't do anything useful here, but it shouldn't fail +explain (costs off) + select distinct min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT min(f1), max(f1) FROM minmaxtest" +== 171 +-- truncate_limit: 100 +select distinct min(f1), max(f1) from minmaxtest +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT min(f1), max(f1) FROM minmaxtest" +== 172 +-- truncate_limit: 100 +drop table minmaxtest cascade +-- +TABLE: name="minmaxtest" schema="" table="minmaxtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE minmaxtest CASCADE" +== 173 +-- truncate_limit: 100 +-- DISTINCT can also trigger wrong answers with hash aggregation (bug #18465) +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 174 +-- truncate_limit: 100 +set local enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_sort TO OFF" +== 175 +-- truncate_limit: 100 +explain (costs off) + select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1) + from int4_tbl t0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t0"="int4_tbl" +ALIAS: "t1"="int4_tbl" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="t0" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT f1, (SELECT DISTINCT min(t1.f1) FROM int4_tbl t1 WHERE t1.f1 = t0.f1) ..." +== 176 +-- truncate_limit: 100 +select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1) +from int4_tbl t0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t0"="int4_tbl" +ALIAS: "t1"="int4_tbl" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="t0" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, (SELECT DISTINCT min(t1.f1) FROM int4_tbl t1 WHERE t1.f1 = t0.f1) FROM int4_tbl t0" +== 177 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 178 +-- truncate_limit: 100 +-- check for correct detection of nested-aggregate errors +select max(min(unique1)) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(min(unique1)) FROM tenk1" +== 179 +-- truncate_limit: 100 +select (select max(min(unique1)) from int8_tbl) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT max(min(unique1)) FROM int8_tbl) FROM tenk1" +== 180 +-- truncate_limit: 100 +select avg((select avg(a1.col1 order by (select avg(a2.col2) from tenk1 a3)) + from tenk1 a1(col1))) +from tenk1 a2(col2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a1"="tenk1" +ALIAS: "a2"="tenk1" +ALIAS: "a3"="tenk1" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg((SELECT ... FROM tenk1 a1(col1))) FROM tenk1 a2(col2)" +== 181 +-- truncate_limit: 100 +|-- +-- Test removal of redundant GROUP BY columns +|-- + +create temp table t1 (a int, b int, c int, d int, primary key (a, b)) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (a int, b int, c int, d int, PRIMARY KEY (a, b))" +== 182 +-- truncate_limit: 100 +create temp table t2 (x int, y int, z int, primary key (x, y)) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t2 (x int, y int, z int, PRIMARY KEY (x, y))" +== 183 +-- truncate_limit: 100 +create temp table t3 (a int, b int, c int, primary key(a, b) deferrable) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t3 (a int, b int, c int, PRIMARY KEY (a, b) DEFERRABLE)" +== 184 +-- truncate_limit: 100 +-- Non-primary-key columns can be removed from GROUP BY +explain (costs off) select * from t1 group by a,b,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 GROUP BY a, b, c, d" +== 185 +-- truncate_limit: 100 +-- No removal can happen if the complete PK is not present in GROUP BY +explain (costs off) select a,c from t1 group by a,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, c FROM t1 GROUP BY a, c, d" +== 186 +-- truncate_limit: 100 +-- Test removal across multiple relations +explain (costs off) select * +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.y,t2.z +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 JOIN t2 ON t1.a = t2.x AND t1.b = t2.y GROUP BY t1.a, t1.b, ..." +== 187 +-- truncate_limit: 100 +-- Test case where t1 can be optimized but not t2 +explain (costs off) select t1.*,t2.x,t2.z +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.*, t2.x, t2.z FROM t1 JOIN t2 ON t1.a = t2.x AND t1.b = t2.y GROUP ..." +== 188 +-- truncate_limit: 100 +-- Cannot optimize when PK is deferrable +explain (costs off) select * from t3 group by a,b,c +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t3 GROUP BY a, b, c" +== 189 +-- truncate_limit: 100 +create temp table t1c () inherits (t1) +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1c () INHERITS (t1)" +== 190 +-- truncate_limit: 100 +-- Ensure we don't remove any columns when t1 has a child table +explain (costs off) select * from t1 group by a,b,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 GROUP BY a, b, c, d" +== 191 +-- truncate_limit: 100 +-- Okay to remove columns if we're only querying the parent. +explain (costs off) select * from only t1 group by a,b,c,d +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ONLY t1 GROUP BY a, b, c, d" +== 192 +-- truncate_limit: 100 +create temp table p_t1 ( + a int, + b int, + c int, + d int, + primary key(a,b) +) partition by list(a) +-- +TABLE: name="p_t1" schema="" table="p_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE p_t1 (a int, b int, c int, d int, PRIMARY KEY (a, b)) PARTITION BY LIST (a)" +== 193 +-- truncate_limit: 100 +create temp table p_t1_1 partition of p_t1 for values in(1) +-- +TABLE: name="p_t1_1" schema="" table="p_t1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE p_t1_1 PARTITION OF p_t1 FOR VALUES IN (1)" +== 194 +-- truncate_limit: 100 +create temp table p_t1_2 partition of p_t1 for values in(2) +-- +TABLE: name="p_t1_2" schema="" table="p_t1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE p_t1_2 PARTITION OF p_t1 FOR VALUES IN (2)" +== 195 +-- truncate_limit: 100 +-- Ensure we can remove non-PK columns for partitioned tables. +explain (costs off) select * from p_t1 group by a,b,c,d +-- +TABLE: name="p_t1" schema="" table="p_t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM p_t1 GROUP BY a, b, c, d" +== 196 +-- truncate_limit: 100 +drop table t1 cascade +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1 CASCADE" +== 197 +-- truncate_limit: 100 +drop table t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t2" +== 198 +-- truncate_limit: 100 +drop table t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t3" +== 199 +-- truncate_limit: 100 +drop table p_t1 +-- +TABLE: name="p_t1" schema="" table="p_t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p_t1" +== 200 +-- truncate_limit: 100 +|-- +-- Test GROUP BY matching of join columns that are type-coerced due to USING +|-- + +create temp table t1(f1 int, f2 int) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (f1 int, f2 int)" +== 201 +-- truncate_limit: 100 +create temp table t2(f1 bigint, f2 oid) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t2 (f1 bigint, f2 oid)" +== 202 +-- truncate_limit: 100 +select f1 from t1 left join t2 using (f1) group by f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM t1 LEFT JOIN t2 USING (f1) GROUP BY f1" +== 203 +-- truncate_limit: 100 +select f1 from t1 left join t2 using (f1) group by t1.f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM t1 LEFT JOIN t2 USING (f1) GROUP BY t1.f1" +== 204 +-- truncate_limit: 100 +select t1.f1 from t1 left join t2 using (f1) group by t1.f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT t1.f1 FROM t1 LEFT JOIN t2 USING (f1) GROUP BY t1.f1" +== 205 +-- truncate_limit: 100 +-- only this one should fail: +select t1.f1 from t1 left join t2 using (f1) group by f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT t1.f1 FROM t1 LEFT JOIN t2 USING (f1) GROUP BY f1" +== 206 +-- truncate_limit: 100 +-- check case where we have to inject nullingrels into coerced join alias +select f1, count(*) from +t1 x(x0,x1) left join (t1 left join t2 using(f1)) on (x0 = 0) +group by f1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "x"="t1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, count(*) FROM t1 x(x0, x1) LEFT JOIN (t1 LEFT JOIN t2 USING (f1)) ON x0 = 0 GROUP BY f1" +== 207 +-- truncate_limit: 100 +-- same, for a RelabelType coercion +select f2, count(*) from +t1 x(x0,x1) left join (t1 left join t2 using(f2)) on (x0 = 0) +group by f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "x"="t1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f2, count(*) FROM t1 x(x0, x1) LEFT JOIN (t1 LEFT JOIN t2 USING (f2)) ON x0 = 0 GROUP BY f2" +== 208 +-- truncate_limit: 100 +drop table t1, t2 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1, t2" +== 209 +-- truncate_limit: 100 +|-- +-- Test planner's selection of pathkeys for ORDER BY aggregates +|-- + +-- Ensure we order by four. This suits the most aggregate functions. +explain (costs off) +select sum(two order by two),max(four order by four), min(four order by four) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(two ORDER BY two), max(four ORDER BY four), min(four ORDER BY four..." +== 210 +-- truncate_limit: 100 +-- Ensure we order by two. It's a tie between ordering by two and four but +-- we tiebreak on the aggregate's position. +explain (costs off) +select + sum(two order by two), max(four order by four), + min(four order by four), max(two order by two) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(two ORDER BY two), max(four ORDER BY four), min(four ORDER BY four..." +== 211 +-- truncate_limit: 100 +-- Similar to above, but tiebreak on ordering by four +explain (costs off) +select + max(four order by four), sum(two order by two), + min(four order by four), max(two order by two) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(four ORDER BY four), sum(two ORDER BY two), min(four ORDER BY four..." +== 212 +-- truncate_limit: 100 +-- Ensure this one orders by ten since there are 3 aggregates that require ten +-- vs two that suit two and four. +explain (costs off) +select + max(four order by four), sum(two order by two), + min(four order by four), max(two order by two), + sum(ten order by ten), min(ten order by ten), max(ten order by ten) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT max(four ORDER BY four), sum(two ORDER BY two), min(four ORDER BY four..." +== 213 +-- truncate_limit: 100 +-- Try a case involving a GROUP BY clause where the GROUP BY column is also +-- part of an aggregate's ORDER BY clause. We want a sort order that works +-- for the GROUP BY along with the first and the last aggregate. +explain (costs off) +select + sum(unique1 order by ten, two), sum(unique1 order by four), + sum(unique1 order by two, four) +from tenk1 +group by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(unique1 ORDER BY ten, two), sum(unique1 ORDER BY four), sum(unique..." +== 214 +-- truncate_limit: 100 +-- Ensure that we never choose to provide presorted input to an Aggref with +-- a volatile function in the ORDER BY / DISTINCT clause. We want to ensure +-- these sorts are performed individually rather than at the query level. +explain (costs off) +select + sum(unique1 order by two), sum(unique1 order by four), + sum(unique1 order by four, two), sum(unique1 order by two, random()), + sum(unique1 order by two, random(), random() + 1) +from tenk1 +group by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(unique1 ORDER BY two), sum(unique1 ORDER BY four), sum(unique1 ORD..." +== 215 +-- truncate_limit: 100 +-- Ensure consecutive NULLs are properly treated as distinct from each other +select array_agg(distinct val) +from (select null as val from generate_series(1, 2)) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(DISTINCT val) FROM (SELECT NULL AS val FROM generate_series(1, 2))" +== 216 +-- truncate_limit: 100 +-- Ensure no ordering is requested when enable_presorted_aggregate is off +set enable_presorted_aggregate to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_presorted_aggregate TO OFF" +== 217 +-- truncate_limit: 100 +explain (costs off) +select sum(two order by two) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(two ORDER BY two) FROM tenk1" +== 218 +-- truncate_limit: 100 +reset enable_presorted_aggregate +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_presorted_aggregate" +== 219 +-- truncate_limit: 100 +|-- +-- Test cases with FILTER clause +|-- + +-- Ensure we presort when the aggregate contains plain Vars +explain (costs off) +select sum(two order by two) filter (where two > 1) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(two ORDER BY two) FILTER (WHERE two > 1) FROM tenk1" +== 220 +-- truncate_limit: 100 +-- Ensure we presort for RelabelType'd Vars +explain (costs off) +select string_agg(distinct f1, ',') filter (where length(f1) > 1) +from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT string_agg(DISTINCT f1, ',') FILTER (WHERE length(f1) > 1) FROM varcha..." +== 221 +-- truncate_limit: 100 +-- Ensure we don't presort when the aggregate's argument contains an +-- explicit cast. +explain (costs off) +select string_agg(distinct f1::varchar(2), ',') filter (where length(f1) > 1) +from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT string_agg(DISTINCT f1::varchar(2), ',') FILTER (WHERE length(f1) > 1)..." +== 222 +-- truncate_limit: 100 +|-- +-- Test combinations of DISTINCT and/or ORDER BY +|-- + +select array_agg(a order by b) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(a ORDER BY b) FROM (VALUES (1, 4), (2, 3), (3, 1), (4, 2)) v(a, b)" +== 223 +-- truncate_limit: 100 +select array_agg(a order by a) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(a ORDER BY a) FROM (VALUES (1, 4), (2, 3), (3, 1), (4, 2)) v(a, b)" +== 224 +-- truncate_limit: 100 +select array_agg(a order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(a ORDER BY a DESC) FROM (VALUES (1, 4), (2, 3), (3, 1), (4, 2)) v(a, b)" +== 225 +-- truncate_limit: 100 +select array_agg(b order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY a DESC) FROM (VALUES (1, 4), (2, 3), (3, 1), (4, 2)) v(a, b)" +== 226 +-- truncate_limit: 100 +select array_agg(distinct a) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(DISTINCT a) FROM (VALUES (1), (2), (1), (3), (NULL), (2)) v(a)" +== 227 +-- truncate_limit: 100 +select array_agg(distinct a order by a) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(DISTINCT a ORDER BY a) FROM (VALUES (1), (2), (1), (3), (NULL), (2)) v(a)" +== 228 +-- truncate_limit: 100 +select array_agg(distinct a order by a desc) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(DISTINCT a ORDER BY a DESC) FROM (VALUES (1), (2), (1), (3), (NULL), (2)) v(a)" +== 229 +-- truncate_limit: 100 +select array_agg(distinct a order by a desc nulls last) + from (values (1),(2),(1),(3),(null),(2)) v(a) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(DISTINCT a ORDER BY a DESC NULLS LAST) FROM (VALUES (...)) v(a)" +== 230 +-- truncate_limit: 100 +-- multi-arg aggs, strict/nonstrict, distinct/order by + +select aggfstr(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +FUNCTION: name="aggfstr" function="aggfstr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfstr(a, b, c) FROM (VALUES (...)) v(a, b, c)" +== 231 +-- truncate_limit: 100 +select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfns(a, b, c) FROM (VALUES (...)) v(a, b, c)" +== 232 +-- truncate_limit: 100 +select aggfstr(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfstr" function="aggfstr" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfstr(DISTINCT a, b, c) FROM (VALUES (...)) v(a, b, c), generate_series(1, 3) i" +== 233 +-- truncate_limit: 100 +select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfns(DISTINCT a, b, c) FROM (VALUES (...)) v(a, b, c), generate_series(1, 3) i" +== 234 +-- truncate_limit: 100 +select aggfstr(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfstr" function="aggfstr" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfstr(DISTINCT a, b, c ORDER BY b) FROM (VALUES (...)) v(a, b, c), generate_series(1, 3) i" +== 235 +-- truncate_limit: 100 +select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfns(DISTINCT a, b, c ORDER BY b) FROM (VALUES (...)) v(a, b, c), generate_series(1, 3) i" +== 236 +-- truncate_limit: 100 +-- test specific code paths + +select aggfns(distinct a,a,c order by c using ~<~,a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 237 +-- truncate_limit: 100 +select aggfns(distinct a,a,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 238 +-- truncate_limit: 100 +select aggfns(distinct a,a,c order by a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfns(DISTINCT a, a, c ORDER BY a) FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 239 +-- truncate_limit: 100 +select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 240 +-- truncate_limit: 100 +-- test a more complex permutation that has previous caused issues +select + string_agg(distinct 'a', ','), + sum(( + select sum(1) + from (values(1)) b(id) + where a.id = b.id +)) from unnest(array[1]) a(id) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="b" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY[1]) a(id)" +== 241 +-- truncate_limit: 100 +-- check node I/O via view creation and usage, also deparsing logic + +create view agg_view1 as + select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW agg_view1 AS SELECT aggfns(a, b, c) FROM (VALUES (1, 3, 'foo'), (0, NULL, NULL), (2, ..." +== 242 +-- truncate_limit: 100 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM agg_view1" +== 243 +-- truncate_limit: 100 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('agg_view1'::regclass)" +== 244 +-- truncate_limit: 100 +create or replace view agg_view1 as + select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW agg_view1 AS SELECT aggfns(DISTINCT a, b, c) FROM (VALUES (1, 3, 'foo'), (..." +== 245 +-- truncate_limit: 100 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM agg_view1" +== 246 +-- truncate_limit: 100 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('agg_view1'::regclass)" +== 247 +-- truncate_limit: 100 +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW agg_view1 AS SELECT aggfns(DISTINCT a, b, c ORDER BY b) FROM (VALUES (1, 3..." +== 248 +-- truncate_limit: 100 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM agg_view1" +== 249 +-- truncate_limit: 100 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('agg_view1'::regclass)" +== 250 +-- truncate_limit: 100 +create or replace view agg_view1 as + select aggfns(a,b,c order by b+1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW agg_view1 AS SELECT aggfns(a, b, c ORDER BY b + 1) FROM (VALUES (1, 3, 'fo..." +== 251 +-- truncate_limit: 100 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM agg_view1" +== 252 +-- truncate_limit: 100 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('agg_view1'::regclass)" +== 253 +-- truncate_limit: 100 +create or replace view agg_view1 as + select aggfns(a,a,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW agg_view1 AS SELECT aggfns(a, a, c ORDER BY b) FROM (VALUES (1, 3, 'foo'),..." +== 254 +-- truncate_limit: 100 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM agg_view1" +== 255 +-- truncate_limit: 100 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('agg_view1'::regclass)" +== 256 +-- truncate_limit: 100 +create or replace view agg_view1 as + select aggfns(a,b,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW agg_view1 AS SELECT aggfns(a, b, c ORDER BY c USING ~<~) FROM (VALUES (1, ..." +== 257 +-- truncate_limit: 100 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM agg_view1" +== 258 +-- truncate_limit: 100 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('agg_view1'::regclass)" +== 259 +-- truncate_limit: 100 +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=DDL +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW agg_view1 AS SELECT aggfns(DISTINCT a, b, c ORDER BY a, c USING ~<~, b) FR..." +== 260 +-- truncate_limit: 100 +select * from agg_view1 +-- +TABLE: name="agg_view1" schema="" table="agg_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM agg_view1" +== 261 +-- truncate_limit: 100 +select pg_get_viewdef('agg_view1'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('agg_view1'::regclass)" +== 262 +-- truncate_limit: 100 +drop view agg_view1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW agg_view1" +== 263 +-- truncate_limit: 100 +-- incorrect DISTINCT usage errors + +select aggfns(distinct a,b,c order by i) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT aggfns(DISTINCT a, b, c ORDER BY i) FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 264 +-- truncate_limit: 100 +select aggfns(distinct a,b,c order by a,b+1) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 265 +-- truncate_limit: 100 +select aggfns(distinct a,b,c order by a,b,i,c) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 266 +-- truncate_limit: 100 +select aggfns(distinct a,a,c order by a,b) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 267 +-- truncate_limit: 100 +-- string_agg tests +select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(a, ',') FROM (VALUES ('aaaa'), ('bbbb'), ('cccc')) g(a)" +== 268 +-- truncate_limit: 100 +select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(a, ',') FROM (VALUES ('aaaa'), (NULL), ('bbbb'), ('cccc')) g(a)" +== 269 +-- truncate_limit: 100 +select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(a, 'AB') FROM (VALUES (NULL), (NULL), ('bbbb'), ('cccc')) g(a)" +== 270 +-- truncate_limit: 100 +select string_agg(a,',') from (values(null),(null)) g(a) +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(a, ',') FROM (VALUES (NULL), (NULL)) g(a)" +== 271 +-- truncate_limit: 100 +-- check some implicit casting cases, as per bug #5564 +select string_agg(distinct f1, ',' order by f1) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(DISTINCT f1, ',' ORDER BY f1) FROM varchar_tbl" +== 272 +-- truncate_limit: 100 +-- ok +select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(DISTINCT f1::text, ',' ORDER BY f1) FROM varchar_tbl" +== 273 +-- truncate_limit: 100 +-- not ok +select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(DISTINCT f1, ',' ORDER BY f1::text) FROM varchar_tbl" +== 274 +-- truncate_limit: 100 +-- not ok +select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(DISTINCT f1::text, ',' ORDER BY f1::text) FROM varchar_tbl" +== 275 +-- truncate_limit: 100 +-- ok + +-- string_agg bytea tests +create table bytea_test_table(v bytea) +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bytea_test_table (v bytea)" +== 276 +-- truncate_limit: 100 +select string_agg(v, '') from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(v, '') FROM bytea_test_table" +== 277 +-- truncate_limit: 100 +insert into bytea_test_table values(decode('ff','hex')) +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DML +FUNCTION: name="decode" function="decode" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bytea_test_table VALUES (decode('ff', 'hex'))" +== 278 +-- truncate_limit: 100 +select string_agg(v, '') from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(v, '') FROM bytea_test_table" +== 279 +-- truncate_limit: 100 +insert into bytea_test_table values(decode('aa','hex')) +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DML +FUNCTION: name="decode" function="decode" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bytea_test_table VALUES (decode('aa', 'hex'))" +== 280 +-- truncate_limit: 100 +select string_agg(v, '') from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(v, '') FROM bytea_test_table" +== 281 +-- truncate_limit: 100 +select string_agg(v, NULL) from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(v, NULL) FROM bytea_test_table" +== 282 +-- truncate_limit: 100 +select string_agg(v, decode('ee', 'hex')) from bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="decode" function="decode" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(v, decode('ee', 'hex')) FROM bytea_test_table" +== 283 +-- truncate_limit: 100 +drop table bytea_test_table +-- +TABLE: name="bytea_test_table" schema="" table="bytea_test_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bytea_test_table" +== 284 +-- truncate_limit: 100 +-- Test parallel string_agg and array_agg +create table pagg_test (x int, y int) with (autovacuum_enabled = off) +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_test (x int, y int) WITH (autovacuum_enabled=off)" +== 285 +-- truncate_limit: 100 +insert into pagg_test +select (case x % 4 when 1 then null else x end), x % 10 +from generate_series(1,5000) x +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_test SELECT ... FROM generate_series(1, 5000) x" +== 286 +-- truncate_limit: 100 +set parallel_setup_cost TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 287 +-- truncate_limit: 100 +set parallel_tuple_cost TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 288 +-- truncate_limit: 100 +set parallel_leader_participation TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO 0" +== 289 +-- truncate_limit: 100 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 290 +-- truncate_limit: 100 +set bytea_output = 'escape' +-- +STMT: VariableSetStmt +TRUNCATED: "SET bytea_output TO escape" +== 291 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 292 +-- truncate_limit: 100 +-- create a view as we otherwise have to repeat this query a few times. +create view v_pagg_test AS +select + y, + min(t) AS tmin,max(t) AS tmax,count(distinct t) AS tndistinct, + min(b) AS bmin,max(b) AS bmax,count(distinct b) AS bndistinct, + min(a) AS amin,max(a) AS amax,count(distinct a) AS andistinct, + min(aa) AS aamin,max(aa) AS aamax,count(distinct aa) AS aandistinct +from ( + select + y, + unnest(regexp_split_to_array(a1.t, ','))::int AS t, + unnest(regexp_split_to_array(a1.b::text, ',')) AS b, + unnest(a1.a) AS a, + unnest(a1.aa) AS aa + from ( + select + y, + string_agg(x::text, ',') AS t, + string_agg(x::text::bytea, ',') AS b, + array_agg(x) AS a, + array_agg(ARRAY[x]) AS aa + from pagg_test + group by y + ) a1 +) a2 +group by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=DDL +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="regexp_split_to_array" function="regexp_split_to_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="regexp_split_to_array" function="regexp_split_to_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v_pagg_test AS SELECT y, min(t) AS tmin, max(t) AS tmax, count(DISTINCT t) AS tndisti..." +== 293 +-- truncate_limit: 100 +-- Ensure results are correct. +select * from v_pagg_test order by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_pagg_test ORDER BY y" +== 294 +-- truncate_limit: 100 +-- Ensure parallel aggregation is actually being used. +explain (costs off) select * from v_pagg_test order by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM v_pagg_test ORDER BY y" +== 295 +-- truncate_limit: 100 +-- Ensure results are the same without parallel aggregation. +set max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 0" +== 296 +-- truncate_limit: 100 +select * from v_pagg_test order by y +-- +TABLE: name="v_pagg_test" schema="" table="v_pagg_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_pagg_test ORDER BY y" +== 297 +-- truncate_limit: 100 +-- Check that we don't fail on anonymous record types. +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 298 +-- truncate_limit: 100 +explain (costs off) +select array_dims(array_agg(s)) from (select * from pagg_test) s +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT array_dims(array_agg(s)) FROM (SELECT * FROM pagg_test) s" +== 299 +-- truncate_limit: 100 +select array_dims(array_agg(s)) from (select * from pagg_test) s +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_dims(array_agg(s)) FROM (SELECT * FROM pagg_test) s" +== 300 +-- truncate_limit: 100 +-- Clean up +reset max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers_per_gather" +== 301 +-- truncate_limit: 100 +reset bytea_output +-- +STMT: VariableSetStmt +TRUNCATED: "RESET bytea_output" +== 302 +-- truncate_limit: 100 +reset min_parallel_table_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_table_scan_size" +== 303 +-- truncate_limit: 100 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_leader_participation" +== 304 +-- truncate_limit: 100 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_tuple_cost" +== 305 +-- truncate_limit: 100 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 306 +-- truncate_limit: 100 +drop view v_pagg_test +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW v_pagg_test" +== 307 +-- truncate_limit: 100 +drop table pagg_test +-- +TABLE: name="pagg_test" schema="" table="pagg_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pagg_test" +== 308 +-- truncate_limit: 100 +-- FILTER tests + +select min(unique1) filter (where unique1 > 100) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(unique1) FILTER (WHERE unique1 > 100) FROM tenk1" +== 309 +-- truncate_limit: 100 +select sum(1/ten) filter (where ten > 0) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(1 / ten) FILTER (WHERE ten > 0) FROM tenk1" +== 310 +-- truncate_limit: 100 +select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +group by ten +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ten, sum(DISTINCT four) FILTER (WHERE four::text ~ '123') FROM onek a GROUP BY ten" +== 311 +-- truncate_limit: 100 +select ten, sum(distinct four) filter (where four > 10) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek a GROUP BY ten HAVING EXISTS (SELECT 1 FROM onek b WHERE ...)" +== 312 +-- truncate_limit: 100 +select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') +from (values ('a', 'b')) AS v(foo,bar) +-- +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(foo COLLATE \"C\") FILTER (WHERE bar COLLATE \"POSIX\" > '0') FROM (VALUES (...)) v(foo, bar)" +== 313 +-- truncate_limit: 100 +select any_value(v) filter (where v > 2) from (values (1), (2), (3)) as v (v) +-- +FUNCTION: name="any_value" function="any_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT any_value(v) FILTER (WHERE v > 2) FROM (VALUES (1), (2), (3)) v(v)" +== 314 +-- truncate_limit: 100 +-- outer reference in FILTER (PostgreSQL extension) +select (select count(*) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT count(*) FROM (VALUES (1)) t0(inner_c)) FROM (VALUES (2), (3)) t1(outer_c)" +== 315 +-- truncate_limit: 100 +-- inner query is aggregation query +select (select count(*) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT ... FROM (VALUES (1)) t0(inner_c)) FROM (VALUES (2), (3)) t1(outer_c)" +== 316 +-- truncate_limit: 100 +-- outer query is aggregation query +select (select count(inner_c) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT ... FROM (VALUES (1)) t0(inner_c)) FROM (VALUES (2), (3)) t1(outer_c)" +== 317 +-- truncate_limit: 100 +-- inner query is aggregation query +select + (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)) + filter (where o.unique1 < 10)) +from tenk1 o +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i"="tenk1" +ALIAS: "o"="tenk1" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT max((SELECT ... FROM tenk1 i WHERE ...)) FILTER (WHERE o.unique1 < 10)) FROM tenk1 o" +== 318 +-- truncate_limit: 100 +-- outer query is aggregation query + +-- subquery in FILTER clause (PostgreSQL extension) +select sum(unique1) FILTER (WHERE + unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT sum(unique1) FILTER (WHERE unique1 IN (SELECT unique1 FROM onek WHERE ...)) FROM tenk1" +== 319 +-- truncate_limit: 100 +-- exercise lots of aggregate parts with FILTER +select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- +FUNCTION: name="aggfns" function="aggfns" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b, c), generate_series(1, 2) i" +== 320 +-- truncate_limit: 100 +-- check handling of bare boolean Var in FILTER +select max(0) filter (where b1) from bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(0) FILTER (WHERE b1) FROM bool_test" +== 321 +-- truncate_limit: 100 +select (select max(0) filter (where b1)) from bool_test +-- +TABLE: name="bool_test" schema="" table="bool_test" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT max(0) FILTER (WHERE b1)) FROM bool_test" +== 322 +-- truncate_limit: 100 +-- check for correct detection of nested-aggregate errors in FILTER +select max(unique1) filter (where sum(ten) > 0) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(unique1) FILTER (WHERE sum(ten) > 0) FROM tenk1" +== 323 +-- truncate_limit: 100 +select (select max(unique1) filter (where sum(ten) > 0) from int8_tbl) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT max(unique1) FILTER (WHERE sum(ten) > 0) FROM int8_tbl) FROM tenk1" +== 324 +-- truncate_limit: 100 +select max(unique1) filter (where bool_or(ten > 0)) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(unique1) FILTER (WHERE bool_or(ten > 0)) FROM tenk1" +== 325 +-- truncate_limit: 100 +select (select max(unique1) filter (where bool_or(ten > 0)) from int8_tbl) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT max(unique1) FILTER (WHERE bool_or(ten > 0)) FROM int8_tbl) FROM tenk1" +== 326 +-- truncate_limit: 100 +-- ordered-set aggregates + +select p, percentile_cont(p) within group (order by x::float8) +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 5) x, (VALUES (...)) v(p) GROUP BY p ORDER BY p" +== 327 +-- truncate_limit: 100 +select p, percentile_cont(p order by p) within group (order by x) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +ERROR: cannot use multiple ORDER BY clauses with WITHIN GROUP +CURSORPOS: 41 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 328 +-- truncate_limit: 100 +select p, sum() within group (order by x::float8) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 5) x, (VALUES (...)) v(p) GROUP BY p ORDER BY p" +== 329 +-- truncate_limit: 100 +select p, percentile_cont(p,p) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 5) x, (VALUES (...)) v(p) GROUP BY p ORDER BY p" +== 330 +-- truncate_limit: 100 +select percentile_cont(0.5) within group (order by b) from aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY b) FROM aggtest" +== 331 +-- truncate_limit: 100 +select percentile_cont(0.5) within group (order by b), sum(b) from aggtest +-- +TABLE: name="aggtest" schema="" table="aggtest" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY b), sum(b) FROM aggtest" +== 332 +-- truncate_limit: 100 +select percentile_cont(0.5) within group (order by thousand) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY thousand) FROM tenk1" +== 333 +-- truncate_limit: 100 +select percentile_disc(0.5) within group (order by thousand) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY thousand) FROM tenk1" +== 334 +-- truncate_limit: 100 +select rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank(3) WITHIN GROUP (ORDER BY x) FROM (VALUES (1), (1), (2), (2), (3), (3), (4)) v(x)" +== 335 +-- truncate_limit: 100 +select cume_dist(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="cume_dist" function="cume_dist" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cume_dist(3) WITHIN GROUP (ORDER BY x) FROM (VALUES (1), (1), (2), (2), (3), (3), (4)) v(x)" +== 336 +-- truncate_limit: 100 +select percent_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4),(5)) v(x) +-- +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT percent_rank(3) WITHIN GROUP (ORDER BY x) FROM (VALUES (...)) v(x)" +== 337 +-- truncate_limit: 100 +select dense_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dense_rank(3) WITHIN GROUP (ORDER BY x) FROM (VALUES (1), (1), (2), (2), (3), (3), (4)) v(x)" +== 338 +-- truncate_limit: 100 +select percentile_disc(array[0,0.1,0.25,0.5,0.75,0.9,1]) within group (order by thousand) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1" +== 339 +-- truncate_limit: 100 +select percentile_cont(array[0,0.25,0.5,0.75,1]) within group (order by thousand) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT percentile_cont(ARRAY[0, 0.25, 0.5, 0.75, 1]) WITHIN GROUP (ORDER BY thousand) FROM tenk1" +== 340 +-- truncate_limit: 100 +select percentile_disc(array[[null,1,0.5],[0.75,0.25,null]]) within group (order by thousand) +from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1" +== 341 +-- truncate_limit: 100 +select percentile_cont(array[0,1,0.25,0.75,0.5,1,0.3,0.32,0.35,0.38,0.4]) within group (order by x) +from generate_series(1,6) x +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) x" +== 342 +-- truncate_limit: 100 +select ten, mode() within group (order by string4) from tenk1 group by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="mode" function="mode" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ten, mode() WITHIN GROUP (ORDER BY string4) FROM tenk1 GROUP BY ten" +== 343 +-- truncate_limit: 100 +select percentile_disc(array[0.25,0.5,0.75]) within group (order by x) +from unnest('{fred,jim,fred,jack,jill,fred,jill,jim,jim,sheila,jim,sheila}'::text[]) u(x) +-- +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest('{fred,jim,fred,jack,jill,fred,jill,jim,jim,sheila,jim,sheila}'::text[]) u(x)" +== 344 +-- truncate_limit: 100 +-- check collation propagates up in suitable cases: +select pg_collation_for(percentile_disc(1) within group (order by x collate "POSIX")) + from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="pg_collation_for" function="pg_collation_for" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(x)" +== 345 +-- truncate_limit: 100 +-- ordered-set aggs created with CREATE AGGREGATE +select test_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x) +-- +FUNCTION: name="test_rank" function="test_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_rank(3) WITHIN GROUP (ORDER BY x) FROM (VALUES (1), (1), (2), (2), (3), (3), (4)) v(x)" +== 346 +-- truncate_limit: 100 +select test_percentile_disc(0.5) within group (order by thousand) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="test_percentile_disc" function="test_percentile_disc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_percentile_disc(0.5) WITHIN GROUP (ORDER BY thousand) FROM tenk1" +== 347 +-- truncate_limit: 100 +-- ordered-set aggs can't use ungrouped vars in direct args: +select rank(x) within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank(x) WITHIN GROUP (ORDER BY x) FROM generate_series(1, 5) x" +== 348 +-- truncate_limit: 100 +-- outer-level agg can't use a grouped arg of a lower level, either: +select array(select percentile_disc(a) within group (order by x) + from (values (0.3),(0.7)) v(a) group by a) + from generate_series(1,5) g(x) +-- +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY(SELECT ... FROM (VALUES (...)) v(a) GROUP BY a) FROM generate_series(1, 5) g(x)" +== 349 +-- truncate_limit: 100 +-- agg in the direct args is a grouping violation, too: +select rank(sum(x)) within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank(sum(x)) WITHIN GROUP (ORDER BY x) FROM generate_series(1, 5) x" +== 350 +-- truncate_limit: 100 +-- hypothetical-set type unification and argument-count failures: +select rank(3) within group (order by x) from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank(3) WITHIN GROUP (ORDER BY x) FROM (VALUES ('fred'), ('jim')) v(x)" +== 351 +-- truncate_limit: 100 +select rank(3) within group (order by stringu1,stringu2) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank(3) WITHIN GROUP (ORDER BY stringu1, stringu2) FROM tenk1" +== 352 +-- truncate_limit: 100 +select rank('fred') within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank('fred') WITHIN GROUP (ORDER BY x) FROM generate_series(1, 5) x" +== 353 +-- truncate_limit: 100 +select rank('adam'::text collate "C") within group (order by x collate "POSIX") + from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(x)" +== 354 +-- truncate_limit: 100 +-- hypothetical-set type unification successes: +select rank('adam'::varchar) within group (order by x) from (values ('fred'),('jim')) v(x) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank('adam'::varchar) WITHIN GROUP (ORDER BY x) FROM (VALUES ('fred'), ('jim')) v(x)" +== 355 +-- truncate_limit: 100 +select rank('3') within group (order by x) from generate_series(1,5) x +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank('3') WITHIN GROUP (ORDER BY x) FROM generate_series(1, 5) x" +== 356 +-- truncate_limit: 100 +-- divide by zero check +select percent_rank(0) within group (order by x) from generate_series(1,0) x +-- +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT percent_rank(0) WITHIN GROUP (ORDER BY x) FROM generate_series(1, 0) x" +== 357 +-- truncate_limit: 100 +-- deparse and multiple features: +create view aggordview1 as +select ten, + percentile_disc(0.5) within group (order by thousand) as p50, + percentile_disc(0.5) within group (order by thousand) filter (where hundred=1) as px, + rank(5,'AZZZZ',50) within group (order by hundred, string4 desc, hundred) + from tenk1 + group by ten order by ten +-- +TABLE: name="aggordview1" schema="" table="aggordview1" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW aggordview1 AS SELECT ten, percentile_disc(0.5) WITHIN GROUP (ORDER BY thousand) AS p..." +== 358 +-- truncate_limit: 100 +select pg_get_viewdef('aggordview1') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('aggordview1')" +== 359 +-- truncate_limit: 100 +select * from aggordview1 order by ten +-- +TABLE: name="aggordview1" schema="" table="aggordview1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM aggordview1 ORDER BY ten" +== 360 +-- truncate_limit: 100 +drop view aggordview1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW aggordview1" +== 361 +-- truncate_limit: 100 +-- variadic aggregates +select least_agg(q1,q2) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="least_agg" function="least_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT least_agg(q1, q2) FROM int8_tbl" +== 362 +-- truncate_limit: 100 +select least_agg(variadic array[q1,q2]) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="least_agg" function="least_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT least_agg(VARIADIC ARRAY[q1, q2]) FROM int8_tbl" +== 363 +-- truncate_limit: 100 +select cleast_agg(q1,q2) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cleast_agg(q1, q2) FROM int8_tbl" +== 364 +-- truncate_limit: 100 +select cleast_agg(4.5,f1) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cleast_agg(4.5, f1) FROM int4_tbl" +== 365 +-- truncate_limit: 100 +select cleast_agg(variadic array[4.5,f1]) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cleast_agg(VARIADIC ARRAY[4.5, f1]) FROM int4_tbl" +== 366 +-- truncate_limit: 100 +select pg_typeof(cleast_agg(variadic array[4.5,f1])) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="cleast_agg" function="cleast_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(cleast_agg(VARIADIC ARRAY[4.5, f1])) FROM int4_tbl" +== 367 +-- truncate_limit: 100 +-- test aggregates with common transition functions share the same states +begin work +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 368 +-- truncate_limit: 100 +create type avg_state as (total bigint, count bigint) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE avg_state AS (total bigint, count bigint)" +== 369 +-- truncate_limit: 100 +create or replace function avg_transfn(state avg_state, n int) returns avg_state as +$$ +declare new_state avg_state; +begin + raise notice 'avg_transfn called with %', n; + if state is null then + if n is not null then + new_state.total := n; + new_state.count := 1; + return new_state; + end if; + return null; + elsif n is not null then + state.total := state.total + n; + state.count := state.count + 1; + return state; + end if; + + return null; +end +$$ language plpgsql +-- +FUNCTION: name="avg_transfn" function="avg_transfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION avg_transfn(state avg_state, n int) RETURNS avg_state AS $$\ndeclare ne..." +== 370 +-- truncate_limit: 100 +create function avg_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total / state.count; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="avg_finalfn" function="avg_finalfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION avg_finalfn(state avg_state) RETURNS int4 AS $$\nbegin\n\tif state is null then\n\t\tre..." +== 371 +-- truncate_limit: 100 +create function sum_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="sum_finalfn" function="sum_finalfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sum_finalfn(state avg_state) RETURNS int4 AS $$\nbegin\n\tif state is null then\n\t\tre..." +== 372 +-- truncate_limit: 100 +create aggregate my_avg(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_avg (int4) (stype = avg_state, sfunc = avg_transfn, finalfunc = avg_finalfn)" +== 373 +-- truncate_limit: 100 +create aggregate my_sum(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_sum (int4) (stype = avg_state, sfunc = avg_transfn, finalfunc = sum_finalfn)" +== 374 +-- truncate_limit: 100 +-- aggregate state should be shared as aggs are the same. +select my_avg(one),my_avg(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_avg(one), my_avg(one) FROM (VALUES (1), (3)) t(one)" +== 375 +-- truncate_limit: 100 +-- aggregate state should be shared as transfn is the same for both aggs. +select my_avg(one),my_sum(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_avg(one), my_sum(one) FROM (VALUES (1), (3)) t(one)" +== 376 +-- truncate_limit: 100 +-- same as previous one, but with DISTINCT, which requires sorting the input. +select my_avg(distinct one),my_sum(distinct one) from (values(1),(3),(1)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_avg(DISTINCT one), my_sum(DISTINCT one) FROM (VALUES (1), (3), (1)) t(one)" +== 377 +-- truncate_limit: 100 +-- shouldn't share states due to the distinctness not matching. +select my_avg(distinct one),my_sum(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_avg(DISTINCT one), my_sum(one) FROM (VALUES (1), (3)) t(one)" +== 378 +-- truncate_limit: 100 +-- shouldn't share states due to the filter clause not matching. +select my_avg(one) filter (where one > 1),my_sum(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_avg(one) FILTER (WHERE one > 1), my_sum(one) FROM (VALUES (1), (3)) t(one)" +== 379 +-- truncate_limit: 100 +-- this should not share the state due to different input columns. +select my_avg(one),my_sum(two) from (values(1,2),(3,4)) t(one,two) +-- +FUNCTION: name="my_avg" function="my_avg" schema="" ctx=Call +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_avg(one), my_sum(two) FROM (VALUES (1, 2), (3, 4)) t(one, two)" +== 380 +-- truncate_limit: 100 +-- exercise cases where OSAs share state +select + percentile_cont(0.5) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a) +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(a)" +== 381 +-- truncate_limit: 100 +select + percentile_cont(0.25) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a) +-- +FUNCTION: name="percentile_cont" function="percentile_cont" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(a)" +== 382 +-- truncate_limit: 100 +-- these can't share state currently +select + rank(4) within group (order by a), + dense_rank(4) within group (order by a) +from (values(1),(3),(5),(7)) t(a) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(a)" +== 383 +-- truncate_limit: 100 +-- test that aggs with the same sfunc and initcond share the same agg state +create aggregate my_sum_init(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn, + initcond = '(10,0)' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_sum_init (int4) (stype = avg_state, sfunc = avg_transfn, finalfunc = sum_fina..." +== 384 +-- truncate_limit: 100 +create aggregate my_avg_init(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(10,0)' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_avg_init (int4) (stype = avg_state, sfunc = avg_transfn, finalfunc = avg_fina..." +== 385 +-- truncate_limit: 100 +create aggregate my_avg_init2(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(4,0)' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_avg_init2 (int4) (stype = avg_state, sfunc = avg_transfn, finalfunc = avg_fin..." +== 386 +-- truncate_limit: 100 +-- state should be shared if INITCONDs are matching +select my_sum_init(one),my_avg_init(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_sum_init" function="my_sum_init" schema="" ctx=Call +FUNCTION: name="my_avg_init" function="my_avg_init" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_sum_init(one), my_avg_init(one) FROM (VALUES (1), (3)) t(one)" +== 387 +-- truncate_limit: 100 +-- Varying INITCONDs should cause the states not to be shared. +select my_sum_init(one),my_avg_init2(one) from (values(1),(3)) t(one) +-- +FUNCTION: name="my_sum_init" function="my_sum_init" schema="" ctx=Call +FUNCTION: name="my_avg_init2" function="my_avg_init2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_sum_init(one), my_avg_init2(one) FROM (VALUES (1), (3)) t(one)" +== 388 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 389 +-- truncate_limit: 100 +-- test aggregate state sharing to ensure it works if one aggregate has a +-- finalfn and the other one has none. +begin work +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 390 +-- truncate_limit: 100 +create or replace function sum_transfn(state int4, n int4) returns int4 as +$$ +declare new_state int4; +begin + raise notice 'sum_transfn called with %', n; + if state is null then + if n is not null then + new_state := n; + return new_state; + end if; + return null; + elsif n is not null then + state := state + n; + return state; + end if; + + return null; +end +$$ language plpgsql +-- +FUNCTION: name="sum_transfn" function="sum_transfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION sum_transfn(state int4, n int4) RETURNS int4 AS $$\ndeclare new_state i..." +== 391 +-- truncate_limit: 100 +create function halfsum_finalfn(state int4) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state / 2; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="halfsum_finalfn" function="halfsum_finalfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION halfsum_finalfn(state int4) RETURNS int4 AS $$\nbegin\n\tif state is null then\n\t\tret..." +== 392 +-- truncate_limit: 100 +create aggregate my_sum(int4) +( + stype = int4, + sfunc = sum_transfn +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_sum (int4) (stype = int4, sfunc = sum_transfn)" +== 393 +-- truncate_limit: 100 +create aggregate my_half_sum(int4) +( + stype = int4, + sfunc = sum_transfn, + finalfunc = halfsum_finalfn +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_half_sum (int4) (stype = int4, sfunc = sum_transfn, finalfunc = halfsum_finalfn)" +== 394 +-- truncate_limit: 100 +-- Agg state should be shared even though my_sum has no finalfn +select my_sum(one),my_half_sum(one) from (values(1),(2),(3),(4)) t(one) +-- +FUNCTION: name="my_sum" function="my_sum" schema="" ctx=Call +FUNCTION: name="my_half_sum" function="my_half_sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT my_sum(one), my_half_sum(one) FROM (VALUES (1), (2), (3), (4)) t(one)" +== 395 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 396 +-- truncate_limit: 100 +-- test that the aggregate transition logic correctly handles +-- transition / combine functions returning NULL + +-- First test the case of a normal transition function returning NULL +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 397 +-- truncate_limit: 100 +CREATE FUNCTION balkifnull(int8, int4) +RETURNS int8 +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$ +-- +FUNCTION: name="balkifnull" function="balkifnull" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION balkifnull(int8, int4) RETURNS int8 RETURNS NULL ON NULL INPUT LANGUAGE plpgsql A..." +== 398 +-- truncate_limit: 100 +CREATE AGGREGATE balk(int4) +( + SFUNC = balkifnull(int8, int4), + STYPE = int8, + PARALLEL = SAFE, + INITCOND = '0' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE balk (int4) (sfunc = balkifnull(int8, int4), stype = int8, parallel = safe, init..." +== 399 +-- truncate_limit: 100 +SELECT balk(hundred) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="balk" function="balk" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT balk(hundred) FROM tenk1" +== 400 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 401 +-- truncate_limit: 100 +-- GROUP BY optimization by reordering GROUP BY clauses +CREATE TABLE btg AS SELECT + i % 10 AS x, + i % 10 AS y, + 'abc' || i % 10 AS z, + i AS w +FROM generate_series(1, 100) AS i +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE btg AS SELECT i % 10 AS x, i % 10 AS y, 'abc' || (i % 10) AS z, i AS w FROM generate..." +== 402 +-- truncate_limit: 100 +CREATE INDEX btg_x_y_idx ON btg(x, y) +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX btg_x_y_idx ON btg USING btree (x, y)" +== 403 +-- truncate_limit: 100 +ANALYZE btg +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE btg" +== 404 +-- truncate_limit: 100 +SET enable_hashagg = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 405 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 406 +-- truncate_limit: 100 +-- Utilize the ordering of index scan to avoid a Sort operation +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY y, x +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY y, x" +== 407 +-- truncate_limit: 100 +-- Engage incremental sort +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY z, y, w, x +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY z, y, w, x" +== 408 +-- truncate_limit: 100 +-- Utilize the ordering of subquery scan to avoid a Sort operation +EXPLAIN (COSTS OFF) SELECT count(*) +FROM (SELECT * FROM btg ORDER BY x, y, w, z) AS q1 +GROUP BY w, x, z, y +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM (SELECT * FROM btg ORDER BY x, y, w, z) q1 GROUP BY w, x..." +== 409 +-- truncate_limit: 100 +-- Utilize the ordering of merge join to avoid a full Sort operation +SET enable_hashjoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 410 +-- truncate_limit: 100 +SET enable_nestloop = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 411 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) + FROM btg t1 JOIN btg t2 ON t1.z = t2.z AND t1.w = t2.w AND t1.x = t2.x + GROUP BY t1.x, t1.y, t1.z, t1.w +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +TABLE: name="btg" schema="" table="btg" ctx=Select +ALIAS: "t1"="btg" +ALIAS: "t2"="btg" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM btg t1 JOIN btg t2 ON t1.z = t2.z AND t1.w = t2.w AND t1..." +== 412 +-- truncate_limit: 100 +RESET enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 413 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 414 +-- truncate_limit: 100 +-- Should work with and without GROUP-BY optimization +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY w, x, z, y ORDER BY y, x, z, w +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY w, x, z, y ORDER BY y, x, z, w" +== 415 +-- truncate_limit: 100 +-- Utilize incremental sort to make the ORDER BY rule a bit cheaper +EXPLAIN (COSTS OFF) +SELECT count(*) FROM btg GROUP BY w, x, y, z ORDER BY x*x, z +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY w, x, y, z ORDER BY x * x, z" +== 416 +-- truncate_limit: 100 +-- Test the case where the number of incoming subtree path keys is more than +-- the number of grouping keys. +CREATE INDEX btg_y_x_w_idx ON btg(y, x, w) +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX btg_y_x_w_idx ON btg USING btree (y, x, w)" +== 417 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT y, x, array_agg(distinct w) + FROM btg WHERE y < 0 GROUP BY x, y +-- +TABLE: name="btg" schema="" table="btg" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT y, x, array_agg(DISTINCT w) FROM btg WHERE y < 0 GROUP BY x, y" +== 418 +-- truncate_limit: 100 +-- Ensure that we do not select the aggregate pathkeys instead of the grouping +-- pathkeys +CREATE TABLE group_agg_pk AS SELECT + i % 10 AS x, + i % 2 AS y, + i % 2 AS z, + 2 AS w, + i % 10 AS f +FROM generate_series(1,100) AS i +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE group_agg_pk AS SELECT i % 10 AS x, i % 2 AS y, i % 2 AS z, 2 AS w, i % 10 AS f FROM..." +== 419 +-- truncate_limit: 100 +ANALYZE group_agg_pk +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE group_agg_pk" +== 420 +-- truncate_limit: 100 +SET enable_nestloop = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 421 +-- truncate_limit: 100 +SET enable_hashjoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 422 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT avg(c1.f ORDER BY c1.x, c1.y) +FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x +GROUP BY c1.w, c1.z +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT avg(c1.f ORDER BY c1.x, c1.y) FROM group_agg_pk c1 JOIN group_agg_pk c..." +== 423 +-- truncate_limit: 100 +SELECT avg(c1.f ORDER BY c1.x, c1.y) +FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x +GROUP BY c1.w, c1.z +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x GROUP BY c1.w, c1.z" +== 424 +-- truncate_limit: 100 +-- Pathkeys, built in a subtree, can be used to optimize GROUP-BY clause +-- ordering. Also, here we check that it doesn't depend on the initial clause +-- order in the GROUP-BY list. +EXPLAIN (COSTS OFF) +SELECT c1.y,c1.x FROM group_agg_pk c1 + JOIN group_agg_pk c2 + ON c1.x = c2.x +GROUP BY c1.y,c1.x,c2.x +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c1.y, c1.x FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x GR..." +== 425 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT c1.y,c1.x FROM group_agg_pk c1 + JOIN group_agg_pk c2 + ON c1.x = c2.x +GROUP BY c1.y,c2.x,c1.x +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=Select +ALIAS: "c1"="group_agg_pk" +ALIAS: "c2"="group_agg_pk" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c1.y, c1.x FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x GR..." +== 426 +-- truncate_limit: 100 +RESET enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 427 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 428 +-- truncate_limit: 100 +DROP TABLE group_agg_pk +-- +TABLE: name="group_agg_pk" schema="" table="group_agg_pk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE group_agg_pk" +== 429 +-- truncate_limit: 100 +-- Test the case where the ordering of the scan matches the ordering within the +-- aggregate but cannot be found in the group-by list +CREATE TABLE agg_sort_order (c1 int PRIMARY KEY, c2 int) +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE agg_sort_order (c1 int PRIMARY KEY, c2 int)" +== 430 +-- truncate_limit: 100 +CREATE UNIQUE INDEX agg_sort_order_c2_idx ON agg_sort_order(c2) +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX agg_sort_order_c2_idx ON agg_sort_order USING btree (c2)" +== 431 +-- truncate_limit: 100 +INSERT INTO agg_sort_order SELECT i, i FROM generate_series(1,100)i +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO agg_sort_order SELECT i, i FROM generate_series(1, 100) i" +== 432 +-- truncate_limit: 100 +ANALYZE agg_sort_order +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE agg_sort_order" +== 433 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT array_agg(c1 ORDER BY c2),c2 +FROM agg_sort_order WHERE c2 < 100 GROUP BY c1 ORDER BY 2 +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT array_agg(c1 ORDER BY c2), c2 FROM agg_sort_order WHERE c2 < 100 GROUP..." +== 434 +-- truncate_limit: 100 +DROP TABLE agg_sort_order CASCADE +-- +TABLE: name="agg_sort_order" schema="" table="agg_sort_order" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_sort_order CASCADE" +== 435 +-- truncate_limit: 100 +DROP TABLE btg +-- +TABLE: name="btg" schema="" table="btg" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE btg" +== 436 +-- truncate_limit: 100 +RESET enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 437 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 438 +-- truncate_limit: 100 +-- Secondly test the case of a parallel aggregate combiner function +-- returning NULL. For that use normal transition function, but a +-- combiner function returning NULL. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 439 +-- truncate_limit: 100 +CREATE FUNCTION balkifnull(int8, int8) +RETURNS int8 +PARALLEL SAFE +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$ +-- +FUNCTION: name="balkifnull" function="balkifnull" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION balkifnull(int8, int8) RETURNS int8 PARALLEL safe RETURNS NULL ON NULL INPUT LANG..." +== 440 +-- truncate_limit: 100 +CREATE AGGREGATE balk(int4) +( + SFUNC = int4_sum(int8, int4), + STYPE = int8, + COMBINEFUNC = balkifnull(int8, int8), + PARALLEL = SAFE, + INITCOND = '0' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE balk (int4) (sfunc = int4_sum(int8, int4), stype = int8, combinefunc = balkifnul..." +== 441 +-- truncate_limit: 100 +-- force use of parallelism +ALTER TABLE tenk1 set (parallel_workers = 4) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk1 SET (parallel_workers=4)" +== 442 +-- truncate_limit: 100 +SET LOCAL parallel_setup_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL parallel_setup_cost TO 0" +== 443 +-- truncate_limit: 100 +SET LOCAL max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 4" +== 444 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT balk(hundred) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="balk" function="balk" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT balk(hundred) FROM tenk1" +== 445 +-- truncate_limit: 100 +SELECT balk(hundred) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="balk" function="balk" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT balk(hundred) FROM tenk1" +== 446 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 447 +-- truncate_limit: 100 +-- test multiple usage of an aggregate whose finalfn returns a R/W datum +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 448 +-- truncate_limit: 100 +CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray +LANGUAGE plpgsql IMMUTABLE AS $$ +BEGIN + RETURN array_fill(y[1], ARRAY[4]); +END; +$$ +-- +FUNCTION: name="rwagg_sfunc" function="rwagg_sfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray LANGUAGE plpgsql IMMUTABLE A..." +== 449 +-- truncate_limit: 100 +CREATE FUNCTION rwagg_finalfunc(x anyarray) RETURNS anyarray +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +DECLARE + res x%TYPE; +BEGIN + -- assignment is essential for this test, it expands the array to R/W + res := array_fill(x[1], ARRAY[4]); + RETURN res; +END; +$$ +-- +FUNCTION: name="rwagg_finalfunc" function="rwagg_finalfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rwagg_finalfunc(x anyarray) RETURNS anyarray LANGUAGE plpgsql RETURNS NULL ON NUL..." +== 450 +-- truncate_limit: 100 +CREATE AGGREGATE rwagg(anyarray) ( + STYPE = anyarray, + SFUNC = rwagg_sfunc, + FINALFUNC = rwagg_finalfunc +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE rwagg (anyarray) (stype = anyarray, sfunc = rwagg_sfunc, finalfunc = rwagg_final..." +== 451 +-- truncate_limit: 100 +CREATE FUNCTION eatarray(x real[]) RETURNS real[] +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +BEGIN + x[1] := x[1] + 1; + RETURN x; +END; +$$ +-- +FUNCTION: name="eatarray" function="eatarray" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION eatarray(x real[]) RETURNS real[] LANGUAGE plpgsql RETURNS NULL ON NULL INPUT IMM..." +== 452 +-- truncate_limit: 100 +SELECT eatarray(rwagg(ARRAY[1.0::real])), eatarray(rwagg(ARRAY[1.0::real])) +-- +FUNCTION: name="eatarray" function="eatarray" schema="" ctx=Call +FUNCTION: name="rwagg" function="rwagg" schema="" ctx=Call +FUNCTION: name="eatarray" function="eatarray" schema="" ctx=Call +FUNCTION: name="rwagg" function="rwagg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT eatarray(rwagg(ARRAY[(1.0)::real])), eatarray(rwagg(ARRAY[(1.0)::real]))" +== 453 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 454 +-- truncate_limit: 100 +-- test coverage for aggregate combine/serial/deserial functions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 455 +-- truncate_limit: 100 +SET parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 456 +-- truncate_limit: 100 +SET parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 457 +-- truncate_limit: 100 +SET min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 458 +-- truncate_limit: 100 +SET max_parallel_workers_per_gather = 4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 4" +== 459 +-- truncate_limit: 100 +SET parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 460 +-- truncate_limit: 100 +SET enable_indexonlyscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO OFF" +== 461 +-- truncate_limit: 100 +-- variance(int4) covers numeric_poly_combine +-- sum(int8) covers int8_avg_combine +-- regr_count(float8, float8) covers int8inc_float8_float8 and aggregates with > 1 arg +EXPLAIN (COSTS OFF, VERBOSE) +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_count" function="regr_count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT variance(unique1::int4), sum(unique1::int8), regr_count(uniqu..." +== 462 +-- truncate_limit: 100 +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="regr_count" function="regr_count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (((SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk1) UNION ALL SELECT * FROM ten..." +== 463 +-- truncate_limit: 100 +-- variance(int8) covers numeric_combine +-- avg(numeric) covers numeric_avg_combine +EXPLAIN (COSTS OFF, VERBOSE) +SELECT variance(unique1::int8), avg(unique1::numeric) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT variance(unique1::int8), avg(unique1::numeric) FROM (((SELECT..." +== 464 +-- truncate_limit: 100 +SELECT variance(unique1::int8), avg(unique1::numeric) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (((SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk1) UNION ALL SELECT * FROM ten..." +== 465 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 466 +-- truncate_limit: 100 +-- test coverage for dense_rank +SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (1),(1),(2),(2),(3),(3)) v(x) GROUP BY (x) ORDER BY 1 +-- +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (...)) v(x) GROUP BY x ORDER BY 1" +== 467 +-- truncate_limit: 100 +-- Ensure that the STRICT checks for aggregates does not take NULLness +-- of ORDER BY columns into account. See bug report around +-- 2a505161-2727-2473-7c46-591ed108ac52@email.cz +SELECT min(x ORDER BY y) FROM (VALUES(1, NULL)) AS d(x,y) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(x ORDER BY y) FROM (VALUES (1, NULL)) d(x, y)" +== 468 +-- truncate_limit: 100 +SELECT min(x ORDER BY y) FROM (VALUES(1, 2)) AS d(x,y) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(x ORDER BY y) FROM (VALUES (1, 2)) d(x, y)" +== 469 +-- truncate_limit: 100 +-- check collation-sensitive matching between grouping expressions +select v||'a', case v||'a' when 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY['a', 'b']) u(v) GROUP BY v || 'a' ORDER BY 1" +== 470 +-- truncate_limit: 100 +select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY['a', 'b']) u(v) GROUP BY v || 'a' ORDER BY 1" +== 471 +-- truncate_limit: 100 +-- Make sure that generation of HashAggregate for uniqification purposes +-- does not lead to array overflow due to unexpected duplicate hash keys +-- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com +set enable_memoize to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_memoize TO OFF" +== 472 +-- truncate_limit: 100 +explain (costs off) + select 1 from tenk1 + where (hundred, thousand) in (select twothousand, twothousand from onek) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM tenk1 WHERE (hundred, thousand) IN (SELECT twothousand, twothou..." +== 473 +-- truncate_limit: 100 +reset enable_memoize +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_memoize" +== 474 +-- truncate_limit: 100 +|-- +-- Hash Aggregation Spill tests +|-- + +set enable_sort=false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO FALSE" +== 475 +-- truncate_limit: 100 +set work_mem='64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 476 +-- truncate_limit: 100 +select unique1, count(*), sum(twothousand) from tenk1 +group by unique1 +having sum(fivethous) > 4975 +order by sum(twothousand) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 GROUP BY unique1 HAVING sum(fivethous) > 4975 ORDER BY sum(twothousand)" +== 477 +-- truncate_limit: 100 +set work_mem to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO DEFAULT" +== 478 +-- truncate_limit: 100 +set enable_sort to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO DEFAULT" +== 479 +-- truncate_limit: 100 +|-- +-- 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' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 480 +-- truncate_limit: 100 +create table agg_data_2k as +select g from generate_series(0, 1999) g +-- +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_data_2k AS SELECT g FROM generate_series(0, 1999) g" +== 481 +-- truncate_limit: 100 +analyze agg_data_2k +-- +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE agg_data_2k" +== 482 +-- truncate_limit: 100 +create table agg_data_20k as +select g from generate_series(0, 19999) g +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_data_20k AS SELECT g FROM generate_series(0, 19999) g" +== 483 +-- truncate_limit: 100 +analyze agg_data_20k +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE agg_data_20k" +== 484 +-- truncate_limit: 100 +-- Produce results with sorting. + +set enable_hashagg = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 485 +-- truncate_limit: 100 +set jit_above_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO 0" +== 486 +-- truncate_limit: 100 +explain (costs off) +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000 +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT g % 10000 AS c1, sum(g::numeric) AS c2, count(*) AS c3 FROM agg_data_2..." +== 487 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=DDL +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_group_1 AS SELECT g % 10000 AS c1, sum(g::numeric) AS c2, count(*) AS c3 FROM ag..." +== 488 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="r" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_group_2 AS SELECT * FROM (VALUES (100), (300), (500)) r(a), LATERAL (SELECT (g /..." +== 489 +-- truncate_limit: 100 +set jit_above_cost to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO DEFAULT" +== 490 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_group_3 AS SELECT (g / 2)::numeric AS c1, sum(7::int4) AS c2, count(*) AS c3 FRO..." +== 491 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_group_4 AS SELECT (g / 2)::numeric AS c1, array_agg(g::numeric) AS c2, count(*) ..." +== 492 +-- truncate_limit: 100 +-- Produce results with hash aggregation + +set enable_hashagg = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO TRUE" +== 493 +-- truncate_limit: 100 +set enable_sort = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO FALSE" +== 494 +-- truncate_limit: 100 +set jit_above_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO 0" +== 495 +-- truncate_limit: 100 +explain (costs off) +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000 +-- +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT g % 10000 AS c1, sum(g::numeric) AS c2, count(*) AS c3 FROM agg_data_2..." +== 496 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=DDL +TABLE: name="agg_data_20k" schema="" table="agg_data_20k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_hash_1 AS SELECT g % 10000 AS c1, sum(g::numeric) AS c2, count(*) AS c3 FROM agg..." +== 497 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="r" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_hash_2 AS SELECT * FROM (VALUES (100), (300), (500)) r(a), LATERAL (SELECT (g / ..." +== 498 +-- truncate_limit: 100 +set jit_above_cost to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO DEFAULT" +== 499 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_hash_3 AS SELECT (g / 2)::numeric AS c1, sum(7::int4) AS c2, count(*) AS c3 FROM..." +== 500 +-- truncate_limit: 100 +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 +-- +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=DDL +TABLE: name="agg_data_2k" schema="" table="agg_data_2k" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE agg_hash_4 AS SELECT (g / 2)::numeric AS c1, array_agg(g::numeric) AS c2, count(*) A..." +== 501 +-- truncate_limit: 100 +set enable_sort = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO TRUE" +== 502 +-- truncate_limit: 100 +set work_mem to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO DEFAULT" +== 503 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=Select +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=Select +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=Select +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM agg_hash_1 EXCEPT SELECT * FROM agg_group_1) UNION ALL (SELECT * FROM agg_group_1 ..." +== 504 +-- truncate_limit: 100 +(select * from agg_hash_2 except select * from agg_group_2) + union all +(select * from agg_group_2 except select * from agg_hash_2) +-- +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=Select +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=Select +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=Select +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM agg_hash_2 EXCEPT SELECT * FROM agg_group_2) UNION ALL (SELECT * FROM agg_group_2 ..." +== 505 +-- truncate_limit: 100 +(select * from agg_hash_3 except select * from agg_group_3) + union all +(select * from agg_group_3 except select * from agg_hash_3) +-- +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=Select +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=Select +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=Select +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM agg_hash_3 EXCEPT SELECT * FROM agg_group_3) UNION ALL (SELECT * FROM agg_group_3 ..." +== 506 +-- truncate_limit: 100 +(select * from agg_hash_4 except select * from agg_group_4) + union all +(select * from agg_group_4 except select * from agg_hash_4) +-- +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=Select +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=Select +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=Select +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM agg_hash_4 EXCEPT SELECT * FROM agg_group_4) UNION ALL (SELECT * FROM agg_group_4 ..." +== 507 +-- truncate_limit: 100 +drop table agg_group_1 +-- +TABLE: name="agg_group_1" schema="" table="agg_group_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_group_1" +== 508 +-- truncate_limit: 100 +drop table agg_group_2 +-- +TABLE: name="agg_group_2" schema="" table="agg_group_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_group_2" +== 509 +-- truncate_limit: 100 +drop table agg_group_3 +-- +TABLE: name="agg_group_3" schema="" table="agg_group_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_group_3" +== 510 +-- truncate_limit: 100 +drop table agg_group_4 +-- +TABLE: name="agg_group_4" schema="" table="agg_group_4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_group_4" +== 511 +-- truncate_limit: 100 +drop table agg_hash_1 +-- +TABLE: name="agg_hash_1" schema="" table="agg_hash_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_hash_1" +== 512 +-- truncate_limit: 100 +drop table agg_hash_2 +-- +TABLE: name="agg_hash_2" schema="" table="agg_hash_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_hash_2" +== 513 +-- truncate_limit: 100 +drop table agg_hash_3 +-- +TABLE: name="agg_hash_3" schema="" table="agg_hash_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_hash_3" +== 514 +-- truncate_limit: 100 +drop table agg_hash_4 +-- +TABLE: name="agg_hash_4" schema="" table="agg_hash_4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE agg_hash_4" diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json b/parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json new file mode 100644 index 0000000..d5998bc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json @@ -0,0 +1,336 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_generic.test b/parser/testdata/summary_truncate/postgres_regress/alter_generic.test new file mode 100644 index 0000000..f26f10a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/alter_generic.test @@ -0,0 +1,2472 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test for ALTER some_object {RENAME TO, OWNER TO, SET SCHEMA} +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION test_opclass_options_func(internal) + RETURNS void + AS :'regresslib', 'test_opclass_options_func' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 224 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +-- Clean up in case a prior regression run failed +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 003 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_alter_generic_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_alter_generic_user1" +== 004 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_alter_generic_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_alter_generic_user2" +== 005 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_alter_generic_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_alter_generic_user3" +== 006 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 007 +-- truncate_limit: 100 +CREATE USER regress_alter_generic_user3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_alter_generic_user3" +== 008 +-- truncate_limit: 100 +CREATE USER regress_alter_generic_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_alter_generic_user2" +== 009 +-- truncate_limit: 100 +CREATE USER regress_alter_generic_user1 IN ROLE regress_alter_generic_user3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_alter_generic_user1 WITH IN ROLE regress_alter_generic_user3" +== 010 +-- truncate_limit: 100 +CREATE SCHEMA alt_nsp1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alt_nsp1" +== 011 +-- truncate_limit: 100 +CREATE SCHEMA alt_nsp2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alt_nsp2" +== 012 +-- truncate_limit: 100 +GRANT ALL ON SCHEMA alt_nsp1, alt_nsp2 TO public +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON SCHEMA alt_nsp1, alt_nsp2 TO public" +== 013 +-- truncate_limit: 100 +SET search_path = alt_nsp1, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO alt_nsp1, public" +== 014 +-- truncate_limit: 100 +|-- +-- Function and Aggregate +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 015 +-- truncate_limit: 100 +CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 + 1' +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql AS $$SELECT $1 + 1$$" +== 016 +-- truncate_limit: 100 +CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 - 1' +-- +FUNCTION: name="alt_func2" function="alt_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql AS $$SELECT $1 - 1$$" +== 017 +-- truncate_limit: 100 +CREATE AGGREGATE alt_agg1 ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 0 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE alt_agg1 (sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 0)" +== 018 +-- truncate_limit: 100 +CREATE AGGREGATE alt_agg2 ( + sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = 0 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE alt_agg2 (sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = 0)" +== 019 +-- truncate_limit: 100 +ALTER AGGREGATE alt_func1(int) RENAME TO alt_func3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER AGGREGATE alt_func1(int) RENAME TO alt_func3" +== 020 +-- truncate_limit: 100 +-- failed (not aggregate) +ALTER AGGREGATE alt_func1(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER AGGREGATE alt_func1(int) OWNER TO regress_alter_generic_user3" +== 021 +-- truncate_limit: 100 +-- failed (not aggregate) +ALTER AGGREGATE alt_func1(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER AGGREGATE alt_func1(int) SET SCHEMA alt_nsp2" +== 022 +-- truncate_limit: 100 +-- failed (not aggregate) + +ALTER FUNCTION alt_func1(int) RENAME TO alt_func2 +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +FUNCTION: name="alt_func2" function="alt_func2" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER FUNCTION alt_func1(int) RENAME TO alt_func2" +== 023 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER FUNCTION alt_func1(int) RENAME TO alt_func3 +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +FUNCTION: name="alt_func3" function="alt_func3" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER FUNCTION alt_func1(int) RENAME TO alt_func3" +== 024 +-- truncate_limit: 100 +-- OK +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user2" +== 025 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3" +== 026 +-- truncate_limit: 100 +-- OK +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp1 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp1" +== 027 +-- truncate_limit: 100 +-- OK, already there +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2" +== 028 +-- truncate_limit: 100 +-- OK + +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg2" +== 029 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg3" +== 030 +-- truncate_limit: 100 +-- OK +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user2" +== 031 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3" +== 032 +-- truncate_limit: 100 +-- OK +ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2" +== 033 +-- truncate_limit: 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user2" +== 034 +-- truncate_limit: 100 +CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 + 2' +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql AS $$SELECT $1 + 2$$" +== 035 +-- truncate_limit: 100 +CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 - 2' +-- +FUNCTION: name="alt_func2" function="alt_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql AS $$SELECT $1 - 2$$" +== 036 +-- truncate_limit: 100 +CREATE AGGREGATE alt_agg1 ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 100 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE alt_agg1 (sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 100)" +== 037 +-- truncate_limit: 100 +CREATE AGGREGATE alt_agg2 ( + sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = -100 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE alt_agg2 (sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = -100)" +== 038 +-- truncate_limit: 100 +ALTER FUNCTION alt_func3(int) RENAME TO alt_func4 +-- +FUNCTION: name="alt_func3" function="alt_func3" schema="" ctx=DDL +FUNCTION: name="alt_func4" function="alt_func4" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER FUNCTION alt_func3(int) RENAME TO alt_func4" +== 039 +-- truncate_limit: 100 +-- failed (not owner) +ALTER FUNCTION alt_func1(int) RENAME TO alt_func4 +-- +FUNCTION: name="alt_func1" function="alt_func1" schema="" ctx=DDL +FUNCTION: name="alt_func4" function="alt_func4" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER FUNCTION alt_func1(int) RENAME TO alt_func4" +== 040 +-- truncate_limit: 100 +-- OK +ALTER FUNCTION alt_func3(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FUNCTION alt_func3(int) OWNER TO regress_alter_generic_user2" +== 041 +-- truncate_limit: 100 +-- failed (not owner) +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3" +== 042 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2" +== 043 +-- truncate_limit: 100 +-- failed (not owner) +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2" +== 044 +-- truncate_limit: 100 +-- failed (name conflicts) + +ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4" +== 045 +-- truncate_limit: 100 +-- failed (not owner) +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4" +== 046 +-- truncate_limit: 100 +-- OK +ALTER AGGREGATE alt_agg3(int) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER AGGREGATE alt_agg3(int) OWNER TO regress_alter_generic_user2" +== 047 +-- truncate_limit: 100 +-- failed (not owner) +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3" +== 048 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2" +== 049 +-- truncate_limit: 100 +-- failed (not owner) +ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2" +== 050 +-- truncate_limit: 100 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 051 +-- truncate_limit: 100 +SELECT n.nspname, proname, prorettype::regtype, prokind, a.rolname + FROM pg_proc p, pg_namespace n, pg_authid a + WHERE p.pronamespace = n.oid AND p.proowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="p" column="pronamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="p" column="proowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_proc p, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, proname" +== 052 +-- truncate_limit: 100 +|-- +-- We would test collations here, but it's not possible because the error +-- messages tend to be nonportable. +|-- + +|-- +-- Conversion +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 053 +-- truncate_limit: 100 +CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 054 +-- truncate_limit: 100 +CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 055 +-- truncate_limit: 100 +ALTER CONVERSION alt_conv1 RENAME TO alt_conv2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER CONVERSION alt_conv1 RENAME TO alt_conv2" +== 056 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER CONVERSION alt_conv1 RENAME TO alt_conv3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER CONVERSION alt_conv1 RENAME TO alt_conv3" +== 057 +-- truncate_limit: 100 +-- OK +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user2" +== 058 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3" +== 059 +-- truncate_limit: 100 +-- OK +ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2" +== 060 +-- truncate_limit: 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user2" +== 061 +-- truncate_limit: 100 +CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 062 +-- truncate_limit: 100 +CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 063 +-- truncate_limit: 100 +ALTER CONVERSION alt_conv3 RENAME TO alt_conv4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER CONVERSION alt_conv3 RENAME TO alt_conv4" +== 064 +-- truncate_limit: 100 +-- failed (not owner) +ALTER CONVERSION alt_conv1 RENAME TO alt_conv4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER CONVERSION alt_conv1 RENAME TO alt_conv4" +== 065 +-- truncate_limit: 100 +-- OK +ALTER CONVERSION alt_conv3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER CONVERSION alt_conv3 OWNER TO regress_alter_generic_user2" +== 066 +-- truncate_limit: 100 +-- failed (not owner) +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3" +== 067 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER CONVERSION alt_conv3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER CONVERSION alt_conv3 SET SCHEMA alt_nsp2" +== 068 +-- truncate_limit: 100 +-- failed (not owner) +ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2" +== 069 +-- truncate_limit: 100 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 070 +-- truncate_limit: 100 +SELECT n.nspname, c.conname, a.rolname + FROM pg_conversion c, pg_namespace n, pg_authid a + WHERE c.connamespace = n.oid AND c.conowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, conname +-- +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "c"="pg_conversion" +ALIAS: "n"="pg_namespace" +FILTER: schema="" table="c" column="connamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="c" column="conowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_conversion c, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, conname" +== 071 +-- truncate_limit: 100 +|-- +-- Foreign Data Wrapper and Foreign Server +|-- +CREATE FOREIGN DATA WRAPPER alt_fdw1 +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER alt_fdw1" +== 072 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER alt_fdw2 +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER alt_fdw2" +== 073 +-- truncate_limit: 100 +CREATE SERVER alt_fserv1 FOREIGN DATA WRAPPER alt_fdw1 +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER alt_fserv1 FOREIGN DATA WRAPPER alt_fdw1" +== 074 +-- truncate_limit: 100 +CREATE SERVER alt_fserv2 FOREIGN DATA WRAPPER alt_fdw2 +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER alt_fserv2 FOREIGN DATA WRAPPER alt_fdw2" +== 075 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw2" +== 076 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw3" +== 077 +-- truncate_limit: 100 +-- OK + +ALTER SERVER alt_fserv1 RENAME TO alt_fserv2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER SERVER alt_fserv1 RENAME TO alt_fserv2" +== 078 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER SERVER alt_fserv1 RENAME TO alt_fserv3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER SERVER alt_fserv1 RENAME TO alt_fserv3" +== 079 +-- truncate_limit: 100 +-- OK + +SELECT fdwname FROM pg_foreign_data_wrapper WHERE fdwname like 'alt_fdw%' +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +TRUNCATED: "SELECT fdwname FROM pg_foreign_data_wrapper WHERE fdwname LIKE 'alt_fdw%'" +== 080 +-- truncate_limit: 100 +SELECT srvname FROM pg_foreign_server WHERE srvname like 'alt_fserv%' +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +TRUNCATED: "SELECT srvname FROM pg_foreign_server WHERE srvname LIKE 'alt_fserv%'" +== 081 +-- truncate_limit: 100 +|-- +-- Procedural Language +|-- +CREATE LANGUAGE alt_lang1 HANDLER plpgsql_call_handler +-- +STMT: CreatePLangStmt +TRUNCATED: "CREATE LANGUAGE alt_lang1 HANDLER plpgsql_call_handler" +== 082 +-- truncate_limit: 100 +CREATE LANGUAGE alt_lang2 HANDLER plpgsql_call_handler +-- +STMT: CreatePLangStmt +TRUNCATED: "CREATE LANGUAGE alt_lang2 HANDLER plpgsql_call_handler" +== 083 +-- truncate_limit: 100 +ALTER LANGUAGE alt_lang1 OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER LANGUAGE alt_lang1 OWNER TO regress_alter_generic_user1" +== 084 +-- truncate_limit: 100 +-- OK +ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user2" +== 085 +-- truncate_limit: 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 086 +-- truncate_limit: 100 +ALTER LANGUAGE alt_lang1 RENAME TO alt_lang2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER LANGUAGE alt_lang1 RENAME TO alt_lang2" +== 087 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER LANGUAGE alt_lang2 RENAME TO alt_lang3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER LANGUAGE alt_lang2 RENAME TO alt_lang3" +== 088 +-- truncate_limit: 100 +-- failed (not owner) +ALTER LANGUAGE alt_lang1 RENAME TO alt_lang3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER LANGUAGE alt_lang1 RENAME TO alt_lang3" +== 089 +-- truncate_limit: 100 +-- OK + +ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user3" +== 090 +-- truncate_limit: 100 +-- failed (not owner) +ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user2" +== 091 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user3" +== 092 +-- truncate_limit: 100 +-- OK + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 093 +-- truncate_limit: 100 +SELECT lanname, a.rolname + FROM pg_language l, pg_authid a + WHERE l.lanowner = a.oid AND l.lanname like 'alt_lang%' + ORDER BY lanname +-- +TABLE: name="pg_language" schema="" table="pg_language" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "l"="pg_language" +FILTER: schema="" table="l" column="lanowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="l" column="lanname" +STMT: SelectStmt +TRUNCATED: "SELECT lanname, a.rolname FROM pg_language l, pg_authid a WHERE ... ORDER BY lanname" +== 094 +-- truncate_limit: 100 +|-- +-- Operator +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 095 +-- truncate_limit: 100 +CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR @-@ (leftarg = int4, rightarg = int4, procedure = int4mi)" +== 096 +-- truncate_limit: 100 +CREATE OPERATOR @+@ ( leftarg = int4, rightarg = int4, procedure = int4pl ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR @+@ (leftarg = int4, rightarg = int4, procedure = int4pl)" +== 097 +-- truncate_limit: 100 +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2" +== 098 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user3" +== 099 +-- truncate_limit: 100 +-- OK +ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2" +== 100 +-- truncate_limit: 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user2" +== 101 +-- truncate_limit: 100 +CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR @-@ (leftarg = int4, rightarg = int4, procedure = int4mi)" +== 102 +-- truncate_limit: 100 +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2" +== 103 +-- truncate_limit: 100 +-- failed (not owner) +ALTER OPERATOR @-@(int4, int4) OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR @-@(int4, int4) OWNER TO regress_alter_generic_user3" +== 104 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER OPERATOR @+@(int4, int4) SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR @+@(int4, int4) SET SCHEMA alt_nsp2" +== 105 +-- truncate_limit: 100 +-- failed (not owner) +-- can't test this: the error message includes the raw oid of namespace +-- ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2; -- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 106 +-- truncate_limit: 100 +SELECT n.nspname, oprname, a.rolname, + oprleft::regtype, oprright::regtype, oprcode::regproc + FROM pg_operator o, pg_namespace n, pg_authid a + WHERE o.oprnamespace = n.oid AND o.oprowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, oprname +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "o"="pg_operator" +FILTER: schema="" table="o" column="oprnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="o" column="oprowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator o, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, oprname" +== 107 +-- truncate_limit: 100 +|-- +-- OpFamily and OpClass +|-- +CREATE OPERATOR FAMILY alt_opf1 USING hash +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf1 USING hash" +== 108 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf2 USING hash +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf2 USING hash" +== 109 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user1" +== 110 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user1" +== 111 +-- truncate_limit: 100 +CREATE OPERATOR CLASS alt_opc1 FOR TYPE uuid USING hash AS STORAGE uuid +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS alt_opc1 FOR TYPE uuid USING hash AS STORAGE uuid" +== 112 +-- truncate_limit: 100 +CREATE OPERATOR CLASS alt_opc2 FOR TYPE uuid USING hash AS STORAGE uuid +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS alt_opc2 FOR TYPE uuid USING hash AS STORAGE uuid" +== 113 +-- truncate_limit: 100 +ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user1" +== 114 +-- truncate_limit: 100 +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user1 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user1" +== 115 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 116 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf2" +== 117 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf3" +== 118 +-- truncate_limit: 100 +-- OK +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2" +== 119 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3" +== 120 +-- truncate_limit: 100 +-- OK +ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2" +== 121 +-- truncate_limit: 100 +-- OK + +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc2" +== 122 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc3" +== 123 +-- truncate_limit: 100 +-- OK +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2" +== 124 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3" +== 125 +-- truncate_limit: 100 +-- OK +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2" +== 126 +-- truncate_limit: 100 +-- OK + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 127 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf1 USING hash +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf1 USING hash" +== 128 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf2 USING hash +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf2 USING hash" +== 129 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user2" +== 130 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2" +== 131 +-- truncate_limit: 100 +CREATE OPERATOR CLASS alt_opc1 FOR TYPE macaddr USING hash AS STORAGE macaddr +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS alt_opc1 FOR TYPE macaddr USING hash AS STORAGE macaddr" +== 132 +-- truncate_limit: 100 +CREATE OPERATOR CLASS alt_opc2 FOR TYPE macaddr USING hash AS STORAGE macaddr +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS alt_opc2 FOR TYPE macaddr USING hash AS STORAGE macaddr" +== 133 +-- truncate_limit: 100 +ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user2" +== 134 +-- truncate_limit: 100 +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2" +== 135 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user2" +== 136 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf3 USING hash RENAME TO alt_opf4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf3 USING hash RENAME TO alt_opf4" +== 137 +-- truncate_limit: 100 +-- failed (not owner) +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf4" +== 138 +-- truncate_limit: 100 +-- OK +ALTER OPERATOR FAMILY alt_opf3 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf3 USING hash OWNER TO regress_alter_generic_user2" +== 139 +-- truncate_limit: 100 +-- failed (not owner) +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3" +== 140 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER OPERATOR FAMILY alt_opf3 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf3 USING hash SET SCHEMA alt_nsp2" +== 141 +-- truncate_limit: 100 +-- failed (not owner) +ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2" +== 142 +-- truncate_limit: 100 +-- failed (name conflict) + +ALTER OPERATOR CLASS alt_opc3 USING hash RENAME TO alt_opc4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc3 USING hash RENAME TO alt_opc4" +== 143 +-- truncate_limit: 100 +-- failed (not owner) +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc4" +== 144 +-- truncate_limit: 100 +-- OK +ALTER OPERATOR CLASS alt_opc3 USING hash OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc3 USING hash OWNER TO regress_alter_generic_user2" +== 145 +-- truncate_limit: 100 +-- failed (not owner) +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3" +== 146 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER OPERATOR CLASS alt_opc3 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc3 USING hash SET SCHEMA alt_nsp2" +== 147 +-- truncate_limit: 100 +-- failed (not owner) +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2" +== 148 +-- truncate_limit: 100 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 149 +-- truncate_limit: 100 +SELECT nspname, opfname, amname, rolname + FROM pg_opfamily o, pg_am m, pg_namespace n, pg_authid a + WHERE o.opfmethod = m.oid AND o.opfnamespace = n.oid AND o.opfowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + AND NOT opfname LIKE 'alt_opc%' + ORDER BY nspname, opfname +-- +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "m"="pg_am" +ALIAS: "n"="pg_namespace" +ALIAS: "o"="pg_opfamily" +FILTER: schema="" table="o" column="opfmethod" +FILTER: schema="" table="m" column="oid" +FILTER: schema="" table="o" column="opfnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="o" column="opfowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +FILTER: schema="" table="" column="opfname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_opfamily o, pg_am m, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, o..." +== 150 +-- truncate_limit: 100 +SELECT nspname, opcname, amname, rolname + FROM pg_opclass o, pg_am m, pg_namespace n, pg_authid a + WHERE o.opcmethod = m.oid AND o.opcnamespace = n.oid AND o.opcowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, opcname +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "m"="pg_am" +ALIAS: "n"="pg_namespace" +ALIAS: "o"="pg_opclass" +FILTER: schema="" table="o" column="opcmethod" +FILTER: schema="" table="m" column="oid" +FILTER: schema="" table="o" column="opcnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="o" column="opcowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_opclass o, pg_am m, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, op..." +== 151 +-- truncate_limit: 100 +-- ALTER OPERATOR FAMILY ... ADD/DROP + +-- Should work. Textbook case of CREATE / ALTER ADD / ALTER DROP / DROP +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 152 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf4 USING btree" +== 153 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD + -- int4 vs int2 + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 1 <(int4, int2), OPERATOR 2 <=(int4, int2..." +== 154 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf4 USING btree DROP + -- int4 vs int2 + OPERATOR 1 (int4, int2) , + OPERATOR 2 (int4, int2) , + OPERATOR 3 (int4, int2) , + OPERATOR 4 (int4, int2) , + OPERATOR 5 (int4, int2) , + FUNCTION 1 (int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree DROP OPERATOR 1 (int4, int2), OPERATOR 2 (int4, int2),..." +== 155 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf4 USING btree" +== 156 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 157 +-- truncate_limit: 100 +-- Should fail. Invalid values for ALTER OPERATOR FAMILY .. ADD / DROP +CREATE OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf4 USING btree" +== 158 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf4 USING invalid_index_method ADD OPERATOR 1 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING invalid_index_method ADD OPERATOR 1 <(int4, int2)" +== 159 +-- truncate_limit: 100 +-- invalid indexing_method +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 6 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 6 <(int4, int2)" +== 160 +-- truncate_limit: 100 +-- operator number should be between 1 and 5 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 0 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 0 <(int4, int2)" +== 161 +-- truncate_limit: 100 +-- operator number should be between 1 and 5 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 1 < +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 1 <" +== 162 +-- truncate_limit: 100 +-- operator without argument types +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 0 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 0 btint42cmp(int4, int2)" +== 163 +-- truncate_limit: 100 +-- invalid options parsing function +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 6 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 6 btint42cmp(int4, int2)" +== 164 +-- truncate_limit: 100 +-- function number should be between 1 and 5 +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD STORAGE invalid_storage +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf4 USING btree ADD STORAGE invalid_storage" +== 165 +-- truncate_limit: 100 +-- Ensure STORAGE is not a part of ALTER OPERATOR FAMILY +DROP OPERATOR FAMILY alt_opf4 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf4 USING btree" +== 166 +-- truncate_limit: 100 +-- Should fail. Need to be SUPERUSER to do ALTER OPERATOR FAMILY .. ADD / DROP +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 167 +-- truncate_limit: 100 +CREATE ROLE regress_alter_generic_user5 NOSUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_alter_generic_user5 WITH NOSUPERUSER" +== 168 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf5 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf5 USING btree" +== 169 +-- truncate_limit: 100 +SET ROLE regress_alter_generic_user5 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_alter_generic_user5" +== 170 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf5 USING btree ADD OPERATOR 1 < (int4, int2), FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf5 USING btree ADD OPERATOR 1 <(int4, int2), FUNCTION 1 btint42cmp(in..." +== 171 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 172 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf5 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf5 USING btree" +== 173 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 174 +-- truncate_limit: 100 +-- Should fail. Need rights to namespace for ALTER OPERATOR FAMILY .. ADD / DROP +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 175 +-- truncate_limit: 100 +CREATE ROLE regress_alter_generic_user6 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_alter_generic_user6" +== 176 +-- truncate_limit: 100 +CREATE SCHEMA alt_nsp6 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alt_nsp6" +== 177 +-- truncate_limit: 100 +REVOKE ALL ON SCHEMA alt_nsp6 FROM regress_alter_generic_user6 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON SCHEMA alt_nsp6 FROM regress_alter_generic_user6" +== 178 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree" +== 179 +-- truncate_limit: 100 +SET ROLE regress_alter_generic_user6 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_alter_generic_user6" +== 180 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree ADD OPERATOR 1 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree ADD OPERATOR 1 <(int4, int2)" +== 181 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 182 +-- truncate_limit: 100 +-- Should fail. Only two arguments required for ALTER OPERATOR FAMILY ... DROP OPERATOR +CREATE OPERATOR FAMILY alt_opf7 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf7 USING btree" +== 183 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf7 USING btree ADD OPERATOR 1 < (int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf7 USING btree ADD OPERATOR 1 <(int4, int2)" +== 184 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf7 USING btree DROP OPERATOR 1 (int4, int2, int8) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf7 USING btree DROP OPERATOR 1 (int4, int2, int8)" +== 185 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf7 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf7 USING btree" +== 186 +-- truncate_limit: 100 +-- Should work. During ALTER OPERATOR FAMILY ... DROP OPERATOR +-- when left type is the same as right type, a DROP with only one argument type should work +CREATE OPERATOR FAMILY alt_opf8 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf8 USING btree" +== 187 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf8 USING btree ADD OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf8 USING btree ADD OPERATOR 1 <(int4, int4)" +== 188 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf8 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf8 USING btree" +== 189 +-- truncate_limit: 100 +-- Should work. Textbook case of ALTER OPERATOR FAMILY ... ADD OPERATOR with FOR ORDER BY +CREATE OPERATOR FAMILY alt_opf9 USING gist +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf9 USING gist" +== 190 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf9 USING gist ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf9 USING gist ADD OPERATOR 1 <(int4, int4) FOR ORDER BY float_ops" +== 191 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf9 USING gist +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf9 USING gist" +== 192 +-- truncate_limit: 100 +-- Should fail. Ensure correct ordering methods in ALTER OPERATOR FAMILY ... ADD OPERATOR .. FOR ORDER BY +CREATE OPERATOR FAMILY alt_opf10 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf10 USING btree" +== 193 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf10 USING btree ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf10 USING btree ADD OPERATOR 1 <(int4, int4) FOR ORDER BY float_ops" +== 194 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf10 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf10 USING btree" +== 195 +-- truncate_limit: 100 +-- Should work. Textbook case of ALTER OPERATOR FAMILY ... ADD OPERATOR with FOR ORDER BY +CREATE OPERATOR FAMILY alt_opf11 USING gist +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf11 USING gist" +== 196 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf11 USING gist ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf11 USING gist ADD OPERATOR 1 <(int4, int4) FOR ORDER BY float_ops" +== 197 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf11 USING gist DROP OPERATOR 1 (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf11 USING gist DROP OPERATOR 1 (int4, int4)" +== 198 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf11 USING gist +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf11 USING gist" +== 199 +-- truncate_limit: 100 +-- Should fail. btree comparison functions should return INTEGER in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 200 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf12 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf12 USING btree" +== 201 +-- truncate_limit: 100 +CREATE FUNCTION fn_opf12 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf12" function="fn_opf12" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_opf12(int4, int2) RETURNS bigint AS $$SELECT NULL::BIGINT;$$ LANGUAGE sql" +== 202 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf12 USING btree ADD FUNCTION 1 fn_opf12(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf12 USING btree ADD FUNCTION 1 fn_opf12(int4, int2)" +== 203 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf12 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf12 USING btree" +== 204 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 205 +-- truncate_limit: 100 +-- Should fail. hash comparison functions should return INTEGER in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 206 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf13 USING hash +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf13 USING hash" +== 207 +-- truncate_limit: 100 +CREATE FUNCTION fn_opf13 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf13" function="fn_opf13" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_opf13(int4) RETURNS bigint AS $$SELECT NULL::BIGINT;$$ LANGUAGE sql" +== 208 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf13 USING hash ADD FUNCTION 1 fn_opf13(int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf13 USING hash ADD FUNCTION 1 fn_opf13(int4)" +== 209 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf13 USING hash +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf13 USING hash" +== 210 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 211 +-- truncate_limit: 100 +-- Should fail. btree comparison functions should have two arguments in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 212 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf14 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf14 USING btree" +== 213 +-- truncate_limit: 100 +CREATE FUNCTION fn_opf14 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf14" function="fn_opf14" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_opf14(int4) RETURNS bigint AS $$SELECT NULL::BIGINT;$$ LANGUAGE sql" +== 214 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf14 USING btree ADD FUNCTION 1 fn_opf14(int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf14 USING btree ADD FUNCTION 1 fn_opf14(int4)" +== 215 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf14 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf14 USING btree" +== 216 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 217 +-- truncate_limit: 100 +-- Should fail. hash comparison functions should have one argument in ALTER OPERATOR FAMILY ... ADD FUNCTION +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 218 +-- truncate_limit: 100 +CREATE OPERATOR FAMILY alt_opf15 USING hash +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf15 USING hash" +== 219 +-- truncate_limit: 100 +CREATE FUNCTION fn_opf15 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL +-- +FUNCTION: name="fn_opf15" function="fn_opf15" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_opf15(int4, int2) RETURNS bigint AS $$SELECT NULL::BIGINT;$$ LANGUAGE sql" +== 220 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf15 USING hash ADD FUNCTION 1 fn_opf15(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf15 USING hash ADD FUNCTION 1 fn_opf15(int4, int2)" +== 221 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf15 USING hash +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf15 USING hash" +== 222 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 223 +-- truncate_limit: 100 +-- Should fail. In gist throw an error when giving different data types for function argument +-- without defining left / right type in ALTER OPERATOR FAMILY ... ADD FUNCTION +CREATE OPERATOR FAMILY alt_opf16 USING gist +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf16 USING gist" +== 224 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf16 USING gist ADD FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf16 USING gist ADD FUNCTION 1 btint42cmp(int4, int2)" +== 225 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf16 USING gist +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf16 USING gist" +== 226 +-- truncate_limit: 100 +-- Should fail. duplicate operator number / function number in ALTER OPERATOR FAMILY ... ADD FUNCTION +CREATE OPERATOR FAMILY alt_opf17 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf17 USING btree" +== 227 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4), OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 <(int4, int4), OPERATOR 1 <(int4, int4)" +== 228 +-- truncate_limit: 100 +-- operator # appears twice in same statement +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 <(int4, int4)" +== 229 +-- truncate_limit: 100 +-- operator 1 requested first-time +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 <(int4, int4)" +== 230 +-- truncate_limit: 100 +-- operator 1 requested again in separate statement +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 <(int4, int2), OPERATOR 2 <=(int4, int..." +== 231 +-- truncate_limit: 100 +-- procedure 1 appears twice in same statement +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 <(int4, int2), OPERATOR 2 <=(int4, int..." +== 232 +-- truncate_limit: 100 +-- procedure 1 appears first time +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 <(int4, int2), OPERATOR 2 <=(int4, int..." +== 233 +-- truncate_limit: 100 +-- procedure 1 requested again in separate statement +DROP OPERATOR FAMILY alt_opf17 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf17 USING btree" +== 234 +-- truncate_limit: 100 +-- Should fail. Ensure that DROP requests for missing OPERATOR / FUNCTIONS +-- return appropriate message in ALTER OPERATOR FAMILY ... DROP OPERATOR / FUNCTION +CREATE OPERATOR FAMILY alt_opf18 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf18 USING btree" +== 235 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf18 USING btree DROP OPERATOR 1 (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf18 USING btree DROP OPERATOR 1 (int4, int4)" +== 236 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf18 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf18 USING btree ADD OPERATOR 1 <(int4, int2), OPERATOR 2 <=(int4, int..." +== 237 +-- truncate_limit: 100 +-- Should fail. Not allowed to have cross-type equalimage function. +ALTER OPERATOR FAMILY alt_opf18 USING btree + ADD FUNCTION 4 (int4, int2) btequalimage(oid) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf18 USING btree ADD FUNCTION 4 (int4, int2) btequalimage(oid)" +== 238 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf18 USING btree DROP FUNCTION 2 (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf18 USING btree DROP FUNCTION 2 (int4, int4)" +== 239 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf18 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf18 USING btree" +== 240 +-- truncate_limit: 100 +-- Should fail. Invalid opclass options function (#5) specifications. +CREATE OPERATOR FAMILY alt_opf19 USING btree +-- +STMT: CreateOpFamilyStmt +TRUNCATED: "CREATE OPERATOR FAMILY alt_opf19 USING btree" +== 241 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 test_opclass_options_func(internal, text[], bool) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 test_opclass_options_func(internal, te..." +== 242 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) btint42cmp(int4, int2)" +== 243 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4, int2) btint42cmp(int4, int2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4, int2) btint42cmp(int4, int2)" +== 244 +-- truncate_limit: 100 +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) test_opclass_options_func(internal) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) test_opclass_options_func(inter..." +== 245 +-- truncate_limit: 100 +-- Ok +ALTER OPERATOR FAMILY alt_opf19 USING btree DROP FUNCTION 5 (int4, int4) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY alt_opf19 USING btree DROP FUNCTION 5 (int4, int4)" +== 246 +-- truncate_limit: 100 +DROP OPERATOR FAMILY alt_opf19 USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY alt_opf19 USING btree" +== 247 +-- truncate_limit: 100 +|-- +-- Statistics +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 248 +-- truncate_limit: 100 +CREATE TABLE alt_regress_1 (a INTEGER, b INTEGER) +-- +TABLE: name="alt_regress_1" schema="" table="alt_regress_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alt_regress_1 (a int, b int)" +== 249 +-- truncate_limit: 100 +CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_1" +== 250 +-- truncate_limit: 100 +CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_1" +== 251 +-- truncate_limit: 100 +ALTER STATISTICS alt_stat1 RENAME TO alt_stat2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER STATISTICS alt_stat1 RENAME TO alt_stat2" +== 252 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER STATISTICS alt_stat1 RENAME TO alt_stat3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER STATISTICS alt_stat1 RENAME TO alt_stat3" +== 253 +-- truncate_limit: 100 +-- OK +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user2" +== 254 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3" +== 255 +-- truncate_limit: 100 +-- OK +ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2" +== 256 +-- truncate_limit: 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user2" +== 257 +-- truncate_limit: 100 +CREATE TABLE alt_regress_2 (a INTEGER, b INTEGER) +-- +TABLE: name="alt_regress_2" schema="" table="alt_regress_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alt_regress_2 (a int, b int)" +== 258 +-- truncate_limit: 100 +CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_2 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_2" +== 259 +-- truncate_limit: 100 +CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_2 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_2" +== 260 +-- truncate_limit: 100 +ALTER STATISTICS alt_stat3 RENAME TO alt_stat4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER STATISTICS alt_stat3 RENAME TO alt_stat4" +== 261 +-- truncate_limit: 100 +-- failed (not owner) +ALTER STATISTICS alt_stat1 RENAME TO alt_stat4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER STATISTICS alt_stat1 RENAME TO alt_stat4" +== 262 +-- truncate_limit: 100 +-- OK +ALTER STATISTICS alt_stat3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER STATISTICS alt_stat3 OWNER TO regress_alter_generic_user2" +== 263 +-- truncate_limit: 100 +-- failed (not owner) +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3" +== 264 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER STATISTICS alt_stat3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER STATISTICS alt_stat3 SET SCHEMA alt_nsp2" +== 265 +-- truncate_limit: 100 +-- failed (not owner) +ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2" +== 266 +-- truncate_limit: 100 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 267 +-- truncate_limit: 100 +SELECT nspname, stxname, rolname + FROM pg_statistic_ext s, pg_namespace n, pg_authid a + WHERE s.stxnamespace = n.oid AND s.stxowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, stxname +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="s" column="stxowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_statistic_ext s, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, stxname" +== 268 +-- truncate_limit: 100 +|-- +-- Text Search Dictionary +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 269 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template = simple)" +== 270 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template = simple)" +== 271 +-- truncate_limit: 100 +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict2" +== 272 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict3" +== 273 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user2" +== 274 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3" +== 275 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2" +== 276 +-- truncate_limit: 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user2" +== 277 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template = simple)" +== 278 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template = simple)" +== 279 +-- truncate_limit: 100 +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 RENAME TO alt_ts_dict4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 RENAME TO alt_ts_dict4" +== 280 +-- truncate_limit: 100 +-- failed (not owner) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict4" +== 281 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 OWNER TO regress_alter_generic_user2" +== 282 +-- truncate_limit: 100 +-- failed (not owner) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3" +== 283 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 SET SCHEMA alt_nsp2" +== 284 +-- truncate_limit: 100 +-- failed (not owner) +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2" +== 285 +-- truncate_limit: 100 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 286 +-- truncate_limit: 100 +SELECT nspname, dictname, rolname + FROM pg_ts_dict t, pg_namespace n, pg_authid a + WHERE t.dictnamespace = n.oid AND t.dictowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, dictname +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_dict" +FILTER: schema="" table="t" column="dictnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="t" column="dictowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_ts_dict t, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, dictname" +== 287 +-- truncate_limit: 100 +|-- +-- Text Search Configuration +|-- +SET SESSION AUTHORIZATION regress_alter_generic_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user1" +== 288 +-- truncate_limit: 100 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy = english)" +== 289 +-- truncate_limit: 100 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy = english)" +== 290 +-- truncate_limit: 100 +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf2" +== 291 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf3" +== 292 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user2" +== 293 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3" +== 294 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2" +== 295 +-- truncate_limit: 100 +-- OK + +SET SESSION AUTHORIZATION regress_alter_generic_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_generic_user2" +== 296 +-- truncate_limit: 100 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy = english)" +== 297 +-- truncate_limit: 100 +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy = english)" +== 298 +-- truncate_limit: 100 +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 RENAME TO alt_ts_conf4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 RENAME TO alt_ts_conf4" +== 299 +-- truncate_limit: 100 +-- failed (not owner) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf4 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf4" +== 300 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 OWNER TO regress_alter_generic_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 OWNER TO regress_alter_generic_user2" +== 301 +-- truncate_limit: 100 +-- failed (not owner) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3" +== 302 +-- truncate_limit: 100 +-- failed (no role membership) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 SET SCHEMA alt_nsp2" +== 303 +-- truncate_limit: 100 +-- failed (not owner) +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2" +== 304 +-- truncate_limit: 100 +-- failed (name conflict) + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 305 +-- truncate_limit: 100 +SELECT nspname, cfgname, rolname + FROM pg_ts_config t, pg_namespace n, pg_authid a + WHERE t.cfgnamespace = n.oid AND t.cfgowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, cfgname +-- +TABLE: name="pg_ts_config" schema="" table="pg_ts_config" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +ALIAS: "a"="pg_authid" +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_config" +FILTER: schema="" table="t" column="cfgnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="t" column="cfgowner" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_ts_config t, pg_namespace n, pg_authid a WHERE ... ORDER BY nspname, cfgname" +== 306 +-- truncate_limit: 100 +|-- +-- Text Search Template +|-- +CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize = dsimple_lexize)" +== 307 +-- truncate_limit: 100 +CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize = dsimple_lexize)" +== 308 +-- truncate_limit: 100 +ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2" +== 309 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp3" +== 310 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2" +== 311 +-- truncate_limit: 100 +-- OK + +CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize = dsimple_lexize)" +== 312 +-- truncate_limit: 100 +ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2" +== 313 +-- truncate_limit: 100 +-- failed (name conflict) + +-- invalid: non-lowercase quoted identifiers +CREATE TEXT SEARCH TEMPLATE tstemp_case ("Init" = init_function) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH TEMPLATE tstemp_case (\"Init\" = init_function)" +== 314 +-- truncate_limit: 100 +SELECT nspname, tmplname + FROM pg_ts_template t, pg_namespace n + WHERE t.tmplnamespace = n.oid AND nspname like 'alt_nsp%' + ORDER BY nspname, tmplname +-- +TABLE: name="pg_ts_template" schema="" table="pg_ts_template" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_template" +FILTER: schema="" table="t" column="tmplnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT nspname, tmplname FROM pg_ts_template t, pg_namespace n WHERE ... ORDER BY nspname, tmplname" +== 315 +-- truncate_limit: 100 +|-- +-- Text Search Parser +|-- + +CREATE TEXT SEARCH PARSER alt_ts_prs1 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH PARSER alt_ts_prs1 (start = prsd_start, gettoken = prsd_nexttoken, \"end\" = prs..." +== 316 +-- truncate_limit: 100 +CREATE TEXT SEARCH PARSER alt_ts_prs2 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH PARSER alt_ts_prs2 (start = prsd_start, gettoken = prsd_nexttoken, \"end\" = prs..." +== 317 +-- truncate_limit: 100 +ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs2" +== 318 +-- truncate_limit: 100 +-- failed (name conflict) +ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs3" +== 319 +-- truncate_limit: 100 +-- OK +ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2" +== 320 +-- truncate_limit: 100 +-- OK + +CREATE TEXT SEARCH PARSER alt_ts_prs2 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH PARSER alt_ts_prs2 (start = prsd_start, gettoken = prsd_nexttoken, \"end\" = prs..." +== 321 +-- truncate_limit: 100 +ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2" +== 322 +-- truncate_limit: 100 +-- failed (name conflict) + +-- invalid: non-lowercase quoted identifiers +CREATE TEXT SEARCH PARSER tspars_case ("Start" = start_function) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH PARSER tspars_case (\"Start\" = start_function)" +== 323 +-- truncate_limit: 100 +SELECT nspname, prsname + FROM pg_ts_parser t, pg_namespace n + WHERE t.prsnamespace = n.oid AND nspname like 'alt_nsp%' + ORDER BY nspname, prsname +-- +TABLE: name="pg_ts_parser" schema="" table="pg_ts_parser" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "n"="pg_namespace" +ALIAS: "t"="pg_ts_parser" +FILTER: schema="" table="t" column="prsnamespace" +FILTER: schema="" table="n" column="oid" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT nspname, prsname FROM pg_ts_parser t, pg_namespace n WHERE ... ORDER BY nspname, prsname" +== 324 +-- truncate_limit: 100 +--- +--- Cleanup resources +--- +DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE" +== 325 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE" +== 326 +-- truncate_limit: 100 +DROP LANGUAGE alt_lang2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP LANGUAGE alt_lang2 CASCADE" +== 327 +-- truncate_limit: 100 +DROP LANGUAGE alt_lang3 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP LANGUAGE alt_lang3 CASCADE" +== 328 +-- truncate_limit: 100 +DROP SCHEMA alt_nsp1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA alt_nsp1 CASCADE" +== 329 +-- truncate_limit: 100 +DROP SCHEMA alt_nsp2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA alt_nsp2 CASCADE" +== 330 +-- truncate_limit: 100 +DROP USER regress_alter_generic_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_alter_generic_user1" +== 331 +-- truncate_limit: 100 +DROP USER regress_alter_generic_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_alter_generic_user2" +== 332 +-- truncate_limit: 100 +DROP USER regress_alter_generic_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_alter_generic_user3" diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json b/parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json new file mode 100644 index 0000000..8836c0c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json @@ -0,0 +1,69 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_operator.test b/parser/testdata/summary_truncate/postgres_regress/alter_operator.test new file mode 100644 index 0000000..0a3035d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/alter_operator.test @@ -0,0 +1,582 @@ +== 001 +-- truncate_limit: 100 +CREATE FUNCTION alter_op_test_fn(boolean, boolean) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="alter_op_test_fn" function="alter_op_test_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alter_op_test_fn(boolean, boolean) RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$..." +== 002 +-- truncate_limit: 100 +CREATE FUNCTION customcontsel(internal, oid, internal, integer) +RETURNS float8 AS 'contsel' LANGUAGE internal STABLE STRICT +-- +FUNCTION: name="customcontsel" function="customcontsel" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION customcontsel(internal, oid, internal, int) RETURNS float8 AS $$contsel$$ LANGUAG..." +== 003 +-- truncate_limit: 100 +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn, + COMMUTATOR = ===, + NEGATOR = !==, + RESTRICT = customcontsel, + JOIN = contjoinsel, + HASHES, MERGES +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = boolean, rightarg = boolean, procedure = alter_op_test_fn, commuta..." +== 004 +-- truncate_limit: 100 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1" +== 005 +-- truncate_limit: 100 +|-- +-- Test resetting and setting restrict and join attributes. +|-- + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (restrict = NONE)" +== 006 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, boolean) SET (JOIN = NONE) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (\"join\" = NONE)" +== 007 +-- truncate_limit: 100 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT oprrest, oprjoin FROM pg_operator WHERE ..." +== 008 +-- truncate_limit: 100 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1" +== 009 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (restrict = contsel)" +== 010 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, boolean) SET (JOIN = contjoinsel) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (\"join\" = contjoinsel)" +== 011 +-- truncate_limit: 100 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT oprrest, oprjoin FROM pg_operator WHERE ..." +== 012 +-- truncate_limit: 100 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1" +== 013 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE, JOIN = NONE) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (restrict = NONE, \"join\" = NONE)" +== 014 +-- truncate_limit: 100 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT oprrest, oprjoin FROM pg_operator WHERE ..." +== 015 +-- truncate_limit: 100 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1" +== 016 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = customcontsel, JOIN = contjoinsel) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (restrict = customcontsel, \"join\" = contjoinsel)" +== 017 +-- truncate_limit: 100 +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT oprrest, oprjoin FROM pg_operator WHERE ..." +== 018 +-- truncate_limit: 100 +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1" +== 019 +-- truncate_limit: 100 +|-- +-- Test invalid options. +|-- +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = non_existent_func) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (restrict = non_existent_func)" +== 020 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, boolean) SET (JOIN = non_existent_func) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (\"join\" = non_existent_func)" +== 021 +-- truncate_limit: 100 +-- invalid: non-lowercase quoted identifiers +ALTER OPERATOR & (bit, bit) SET ("Restrict" = _int_contsel, "Join" = _int_contjoinsel) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR &(pg_catalog.bit(1), pg_catalog.bit(1)) SET (\"Restrict\" = _int_contsel, \"Join\" = _..." +== 022 +-- truncate_limit: 100 +|-- +-- Test permission check. Must be owner to ALTER OPERATOR. +|-- +CREATE USER regress_alter_op_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_alter_op_user" +== 023 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_alter_op_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alter_op_user" +== 024 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, boolean) SET (restrict = NONE)" +== 025 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 026 +-- truncate_limit: 100 +|-- +-- Test setting commutator, negator, merges, and hashes attributes, +-- which can only be set if not already set +|-- + +CREATE FUNCTION alter_op_test_fn_bool_real(boolean, real) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="alter_op_test_fn_bool_real" function="alter_op_test_fn_bool_real" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alter_op_test_fn_bool_real(boolean, real) RETURNS boolean AS $$ SELECT NULL::BOOL..." +== 027 +-- truncate_limit: 100 +CREATE FUNCTION alter_op_test_fn_real_bool(real, boolean) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="alter_op_test_fn_real_bool" function="alter_op_test_fn_real_bool" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alter_op_test_fn_real_bool(real, boolean) RETURNS boolean AS $$ SELECT NULL::BOOL..." +== 028 +-- truncate_limit: 100 +-- operator +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = boolean, rightarg = real, procedure = alter_op_test_fn_bool_real)" +== 029 +-- truncate_limit: 100 +-- commutator +CREATE OPERATOR ==== ( + LEFTARG = real, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn_real_bool +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR ==== (leftarg = real, rightarg = boolean, procedure = alter_op_test_fn_real_bool)" +== 030 +-- truncate_limit: 100 +-- negator +CREATE OPERATOR !==== ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR !==== (leftarg = boolean, rightarg = real, procedure = alter_op_test_fn_bool_real)" +== 031 +-- truncate_limit: 100 +-- No-op setting already false hashes and merges to false works +ALTER OPERATOR === (boolean, real) SET (MERGES = false) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (merges = false)" +== 032 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (HASHES = false) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (hashes = false)" +== 033 +-- truncate_limit: 100 +-- Test setting merges and hashes +ALTER OPERATOR === (boolean, real) SET (MERGES) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (merges = NONE)" +== 034 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (HASHES) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (hashes = NONE)" +== 035 +-- truncate_limit: 100 +SELECT oprcanmerge, oprcanhash +FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT oprcanmerge, oprcanhash FROM pg_operator WHERE ..." +== 036 +-- truncate_limit: 100 +-- Test setting commutator +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = ====) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (commutator = ====)" +== 037 +-- truncate_limit: 100 +-- Check that oprcom has been set on both the operator and commutator, +-- that they reference each other, and that the operator used is the existing +-- one we created and not a new shell operator. +SELECT op.oprname AS operator_name, com.oprname AS commutator_name, + com.oprcode AS commutator_func + FROM pg_operator op + INNER JOIN pg_operator com ON (op.oid = com.oprcom AND op.oprcom = com.oid) + WHERE op.oprname = '===' + AND op.oprleft = 'boolean'::regtype AND op.oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "com"="pg_operator" +ALIAS: "op"="pg_operator" +FILTER: schema="" table="op" column="oprname" +FILTER: schema="" table="op" column="oprleft" +FILTER: schema="" table="op" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator op JOIN pg_operator com ON op.oid = com.oprcom AND op.oprcom = com.oi..." +== 038 +-- truncate_limit: 100 +-- Cannot set self as negator +ALTER OPERATOR === (boolean, real) SET (NEGATOR = ===) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (negator = ===)" +== 039 +-- truncate_limit: 100 +-- Test setting negator +ALTER OPERATOR === (boolean, real) SET (NEGATOR = !====) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (negator = !====)" +== 040 +-- truncate_limit: 100 +-- Check that oprnegate has been set on both the operator and negator, +-- that they reference each other, and that the operator used is the existing +-- one we created and not a new shell operator. +SELECT op.oprname AS operator_name, neg.oprname AS negator_name, + neg.oprcode AS negator_func + FROM pg_operator op + INNER JOIN pg_operator neg ON (op.oid = neg.oprnegate AND op.oprnegate = neg.oid) + WHERE op.oprname = '===' + AND op.oprleft = 'boolean'::regtype AND op.oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "neg"="pg_operator" +ALIAS: "op"="pg_operator" +FILTER: schema="" table="op" column="oprname" +FILTER: schema="" table="op" column="oprleft" +FILTER: schema="" table="op" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator op JOIN pg_operator neg ON op.oid = neg.oprnegate AND op.oprnegate = ..." +== 041 +-- truncate_limit: 100 +-- Test that no-op set succeeds +ALTER OPERATOR === (boolean, real) SET (NEGATOR = !====) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (negator = !====)" +== 042 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = ====) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (commutator = ====)" +== 043 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (MERGES) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (merges = NONE)" +== 044 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (HASHES) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (hashes = NONE)" +== 045 +-- truncate_limit: 100 +-- Check that the final state of the operator is as we expect +SELECT oprcanmerge, oprcanhash, + pg_describe_object('pg_operator'::regclass, oprcom, 0) AS commutator, + pg_describe_object('pg_operator'::regclass, oprnegate, 0) AS negator + FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator WHERE ..." +== 046 +-- truncate_limit: 100 +-- Cannot change commutator, negator, merges, and hashes when already set + +CREATE OPERATOR @= ( + LEFTARG = real, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn_real_bool +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR @= (leftarg = real, rightarg = boolean, procedure = alter_op_test_fn_real_bool)" +== 047 +-- truncate_limit: 100 +CREATE OPERATOR @!= ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR @!= (leftarg = boolean, rightarg = real, procedure = alter_op_test_fn_bool_real)" +== 048 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = @=) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (commutator = @=)" +== 049 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (NEGATOR = @!=) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (negator = @!=)" +== 050 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (MERGES = false) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (merges = false)" +== 051 +-- truncate_limit: 100 +ALTER OPERATOR === (boolean, real) SET (HASHES = false) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR ===(boolean, real) SET (hashes = false)" +== 052 +-- truncate_limit: 100 +-- Cannot set an operator that already has a commutator as the commutator +ALTER OPERATOR @=(real, boolean) SET (COMMUTATOR = ===) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR @=(real, boolean) SET (commutator = ===)" +== 053 +-- truncate_limit: 100 +-- Cannot set an operator that already has a negator as the negator +ALTER OPERATOR @!=(boolean, real) SET (NEGATOR = ===) +-- +STMT: AlterOperatorStmt +TRUNCATED: "ALTER OPERATOR @!=(boolean, real) SET (negator = ===)" +== 054 +-- truncate_limit: 100 +-- Check no changes made +SELECT oprcanmerge, oprcanhash, + pg_describe_object('pg_operator'::regclass, oprcom, 0) AS commutator, + pg_describe_object('pg_operator'::regclass, oprnegate, 0) AS negator + FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="oprname" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator WHERE ..." +== 055 +-- truncate_limit: 100 +|-- +-- Clean up +|-- + +DROP USER regress_alter_op_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_alter_op_user" +== 056 +-- truncate_limit: 100 +DROP OPERATOR === (boolean, boolean) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ===(boolean, boolean)" +== 057 +-- truncate_limit: 100 +DROP OPERATOR === (boolean, real) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ===(boolean, real)" +== 058 +-- truncate_limit: 100 +DROP OPERATOR ==== (real, boolean) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ====(real, boolean)" +== 059 +-- truncate_limit: 100 +DROP OPERATOR !==== (boolean, real) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR !====(boolean, real)" +== 060 +-- truncate_limit: 100 +DROP OPERATOR @= (real, boolean) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR @=(real, boolean)" +== 061 +-- truncate_limit: 100 +DROP OPERATOR @!= (boolean, real) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR @!=(boolean, real)" +== 062 +-- truncate_limit: 100 +DROP FUNCTION customcontsel(internal, oid, internal, integer) +-- +FUNCTION: name="customcontsel" function="customcontsel" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION customcontsel(internal, oid, internal, int)" +== 063 +-- truncate_limit: 100 +DROP FUNCTION alter_op_test_fn(boolean, boolean) +-- +FUNCTION: name="alter_op_test_fn" function="alter_op_test_fn" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION alter_op_test_fn(boolean, boolean)" +== 064 +-- truncate_limit: 100 +DROP FUNCTION alter_op_test_fn_bool_real(boolean, real) +-- +FUNCTION: name="alter_op_test_fn_bool_real" function="alter_op_test_fn_bool_real" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION alter_op_test_fn_bool_real(boolean, real)" +== 065 +-- truncate_limit: 100 +DROP FUNCTION alter_op_test_fn_real_bool(real, boolean) +-- +FUNCTION: name="alter_op_test_fn_real_bool" function="alter_op_test_fn_real_bool" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION alter_op_test_fn_real_bool(real, boolean)" diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json b/parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json new file mode 100644 index 0000000..bfe6d13 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json @@ -0,0 +1,1657 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "1060", + "1061", + "1062", + "1063", + "1064", + "1065", + "1066", + "1067", + "1068", + "1069", + "107", + "1070", + "1071", + "1072", + "1073", + "1074", + "1075", + "1076", + "1077", + "1078", + "1079", + "108", + "1080", + "1081", + "1082", + "1083", + "1084", + "1085", + "1086", + "1087", + "1088", + "1089", + "109", + "1090", + "1091", + "1092", + "1093", + "1094", + "1095", + "1096", + "1097", + "1098", + "1099", + "110", + "1100", + "1101", + "1102", + "1103", + "1104", + "1105", + "1106", + "1107", + "1108", + "1109", + "111", + "1110", + "1111", + "1112", + "1113", + "1114", + "1115", + "1116", + "1117", + "1118", + "1119", + "112", + "1120", + "1121", + "1122", + "1123", + "1124", + "1125", + "1126", + "1127", + "1128", + "1129", + "113", + "1130", + "1131", + "1132", + "1133", + "1134", + "1135", + "1136", + "1137", + "1138", + "1139", + "114", + "1140", + "1141", + "1142", + "1143", + "1144", + "1145", + "1146", + "1147", + "1148", + "1149", + "115", + "1150", + "1151", + "1152", + "1153", + "1154", + "1155", + "1156", + "1157", + "1158", + "1159", + "116", + "1160", + "1161", + "1162", + "1163", + "1164", + "1165", + "1166", + "1167", + "1168", + "1169", + "117", + "1170", + "1171", + "1172", + "1173", + "1174", + "1175", + "1176", + "1177", + "1178", + "1179", + "118", + "1180", + "1181", + "1182", + "1183", + "1184", + "1185", + "1186", + "1187", + "1188", + "1189", + "119", + "1190", + "1191", + "1192", + "1193", + "1194", + "1195", + "1196", + "1197", + "1198", + "1199", + "120", + "1200", + "1201", + "1202", + "1203", + "1204", + "1205", + "1206", + "1207", + "1208", + "1209", + "121", + "1210", + "1211", + "1212", + "1213", + "1214", + "1215", + "1216", + "1217", + "1218", + "1219", + "122", + "1220", + "1221", + "1222", + "1223", + "1224", + "1225", + "1226", + "1227", + "1228", + "1229", + "123", + "1230", + "1231", + "1232", + "1233", + "1234", + "1235", + "1236", + "1237", + "1238", + "1239", + "124", + "1240", + "1241", + "1242", + "1243", + "1244", + "1245", + "1246", + "1247", + "1248", + "1249", + "125", + "1250", + "1251", + "1252", + "1253", + "1254", + "1255", + "1256", + "1257", + "1258", + "1259", + "126", + "1260", + "1261", + "1262", + "1263", + "1264", + "1265", + "1266", + "1267", + "1268", + "1269", + "127", + "1270", + "1271", + "1272", + "1273", + "1274", + "1275", + "1276", + "1277", + "1278", + "1279", + "128", + "1280", + "1281", + "1282", + "1283", + "1284", + "1285", + "1286", + "1287", + "1288", + "1289", + "129", + "1290", + "1291", + "1292", + "1293", + "1294", + "1295", + "1296", + "1297", + "1298", + "1299", + "130", + "1300", + "1301", + "1302", + "1303", + "1304", + "1305", + "1306", + "1307", + "1308", + "1309", + "131", + "1310", + "1311", + "1312", + "1313", + "1314", + "1315", + "1316", + "1317", + "1318", + "1319", + "132", + "1320", + "1321", + "1322", + "1323", + "1324", + "1325", + "1326", + "1327", + "1328", + "1329", + "133", + "1330", + "1331", + "1332", + "1333", + "1334", + "1335", + "1336", + "1337", + "1338", + "1339", + "134", + "1340", + "1341", + "1342", + "1343", + "1344", + "1345", + "1346", + "1347", + "1348", + "1349", + "135", + "1350", + "1351", + "1352", + "1353", + "1354", + "1355", + "1356", + "1357", + "1358", + "1359", + "136", + "1360", + "1361", + "1362", + "1363", + "1364", + "1365", + "1366", + "1367", + "1368", + "1369", + "137", + "1370", + "1371", + "1372", + "1373", + "1374", + "1375", + "1376", + "1377", + "1378", + "1379", + "138", + "1380", + "1381", + "1382", + "1383", + "1384", + "1385", + "1386", + "1387", + "1388", + "1389", + "139", + "1390", + "1391", + "1392", + "1393", + "1394", + "1395", + "1396", + "1397", + "1398", + "1399", + "140", + "1400", + "1401", + "1402", + "1403", + "1404", + "1405", + "1406", + "1407", + "1408", + "1409", + "141", + "1410", + "1411", + "1412", + "1413", + "1414", + "1415", + "1416", + "1417", + "1418", + "1419", + "142", + "1420", + "1421", + "1422", + "1423", + "1424", + "1425", + "1426", + "1427", + "1428", + "1429", + "143", + "1430", + "1431", + "1432", + "1433", + "1434", + "1435", + "1436", + "1437", + "1438", + "1439", + "144", + "1440", + "1441", + "1442", + "1443", + "1444", + "1445", + "1446", + "1447", + "1448", + "1449", + "145", + "1450", + "1451", + "1452", + "1453", + "1454", + "1455", + "1456", + "1457", + "1458", + "1459", + "146", + "1460", + "1461", + "1462", + "1463", + "1464", + "1465", + "1466", + "1467", + "1468", + "1469", + "147", + "1470", + "1471", + "1472", + "1473", + "1474", + "1475", + "1476", + "1477", + "1478", + "1479", + "148", + "1480", + "1481", + "1482", + "1483", + "1484", + "1485", + "1486", + "1487", + "1488", + "1489", + "149", + "1490", + "1491", + "1492", + "1493", + "1494", + "1495", + "1496", + "1497", + "1498", + "1499", + "150", + "1500", + "1501", + "1502", + "1503", + "1504", + "1505", + "1506", + "1507", + "1508", + "1509", + "151", + "1510", + "1511", + "1512", + "1513", + "1514", + "1515", + "1516", + "1517", + "1518", + "1519", + "152", + "1520", + "1521", + "1522", + "1523", + "1524", + "1525", + "1526", + "1527", + "1528", + "1529", + "153", + "1530", + "1531", + "1532", + "1533", + "1534", + "1535", + "1536", + "1537", + "1538", + "1539", + "154", + "1540", + "1541", + "1542", + "1543", + "1544", + "1545", + "1546", + "1547", + "1548", + "1549", + "155", + "1550", + "1551", + "1552", + "1553", + "1554", + "1555", + "1556", + "1557", + "1558", + "1559", + "156", + "1560", + "1561", + "1562", + "1563", + "1564", + "1565", + "1566", + "1567", + "1568", + "1569", + "157", + "1570", + "1571", + "1572", + "1573", + "1574", + "1575", + "1576", + "1577", + "1578", + "1579", + "158", + "1580", + "1581", + "1582", + "1583", + "1584", + "1585", + "1586", + "1587", + "1588", + "1589", + "159", + "1590", + "1591", + "1592", + "1593", + "1594", + "1595", + "1596", + "1597", + "1598", + "1599", + "160", + "1600", + "1601", + "1602", + "1603", + "1604", + "1605", + "1606", + "1607", + "1608", + "1609", + "161", + "1610", + "1611", + "1612", + "1613", + "1614", + "1615", + "1616", + "1617", + "1618", + "1619", + "162", + "1620", + "1621", + "1622", + "1623", + "1624", + "1625", + "1626", + "1627", + "1628", + "1629", + "163", + "1630", + "1631", + "1632", + "1633", + "1634", + "1635", + "1636", + "1637", + "1638", + "1639", + "164", + "1640", + "1641", + "1642", + "1643", + "1644", + "1645", + "1646", + "1647", + "1648", + "1649", + "165", + "1650", + "1651", + "1652", + "1653", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_table.test b/parser/testdata/summary_truncate/postgres_regress/alter_table.test new file mode 100644 index 0000000..d594340 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/alter_table.test @@ -0,0 +1,12806 @@ +== 001 +-- truncate_limit: 100 +|-- +-- ALTER_TABLE +|-- + +-- Clean up in case a prior regression run failed +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 002 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_alter_table_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_alter_table_user1" +== 003 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 004 +-- truncate_limit: 100 +CREATE USER regress_alter_table_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_alter_table_user1" +== 005 +-- truncate_limit: 100 +|-- +-- add attribute +|-- + +CREATE TABLE attmp (initial int4) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp (initial int4)" +== 006 +-- truncate_limit: 100 +COMMENT ON TABLE attmp_wrong IS 'table comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TABLE attmp_wrong IS 'table comment'" +== 007 +-- truncate_limit: 100 +COMMENT ON TABLE attmp IS 'table comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TABLE attmp IS 'table comment'" +== 008 +-- truncate_limit: 100 +COMMENT ON TABLE attmp IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TABLE attmp IS NULL" +== 009 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN xmin integer +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN xmin int" +== 010 +-- truncate_limit: 100 +-- fails + +ALTER TABLE attmp ADD COLUMN a int4 default 3 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN a int4 DEFAULT 3" +== 011 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN b name +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN b name" +== 012 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN c text +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN c text" +== 013 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN d float8 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN d float8" +== 014 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN e float4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN e float4" +== 015 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN f int2 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN f int2" +== 016 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN g polygon +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN g polygon" +== 017 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN i char +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN i char(1)" +== 018 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN k int4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN k int4" +== 019 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN l tid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN l tid" +== 020 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN m xid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN m xid" +== 021 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN n oidvector +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN n oidvector" +== 022 +-- truncate_limit: 100 +--ALTER TABLE attmp ADD COLUMN o lock; +ALTER TABLE attmp ADD COLUMN p boolean +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN p boolean" +== 023 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN q point +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN q point" +== 024 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN r lseg +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN r lseg" +== 025 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN s path +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN s path" +== 026 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN t box +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN t box" +== 027 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN v timestamp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN v timestamp" +== 028 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN w interval +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN w interval" +== 029 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN x float8[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN x float8[]" +== 030 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN y float4[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN y float4[]" +== 031 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN z int2[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN z int2[]" +== 032 +-- truncate_limit: 100 +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, + v, w, x, y, z) + VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', + 'c', + 314159, '(1,1)', '512', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', + 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}') +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, v, w, x, y, z) VALUES (...)" +== 033 +-- truncate_limit: 100 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp" +== 034 +-- truncate_limit: 100 +DROP TABLE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp" +== 035 +-- truncate_limit: 100 +-- the wolf bug - schema mods caused inconsistent row descriptors +CREATE TABLE attmp ( + initial int4 +) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp (initial int4)" +== 036 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN a int4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN a int4" +== 037 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN b name +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN b name" +== 038 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN c text +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN c text" +== 039 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN d float8 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN d float8" +== 040 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN e float4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN e float4" +== 041 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN f int2 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN f int2" +== 042 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN g polygon +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN g polygon" +== 043 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN i char +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN i char(1)" +== 044 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN k int4 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN k int4" +== 045 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN l tid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN l tid" +== 046 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN m xid +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN m xid" +== 047 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN n oidvector +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN n oidvector" +== 048 +-- truncate_limit: 100 +--ALTER TABLE attmp ADD COLUMN o lock; +ALTER TABLE attmp ADD COLUMN p boolean +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN p boolean" +== 049 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN q point +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN q point" +== 050 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN r lseg +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN r lseg" +== 051 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN s path +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN s path" +== 052 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN t box +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN t box" +== 053 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN v timestamp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN v timestamp" +== 054 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN w interval +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN w interval" +== 055 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN x float8[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN x float8[]" +== 056 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN y float4[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN y float4[]" +== 057 +-- truncate_limit: 100 +ALTER TABLE attmp ADD COLUMN z int2[] +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ADD COLUMN z int2[]" +== 058 +-- truncate_limit: 100 +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, + v, w, x, y, z) + VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', + 'c', + 314159, '(1,1)', '512', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', + 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}') +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, v, w, x, y, z) VALUES (...)" +== 059 +-- truncate_limit: 100 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp" +== 060 +-- truncate_limit: 100 +CREATE INDEX attmp_idx ON attmp (a, (d + e), b) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX attmp_idx ON attmp USING btree (a, (d + e), b)" +== 061 +-- truncate_limit: 100 +ALTER INDEX attmp_idx ALTER COLUMN 0 SET STATISTICS 1000 +-- +ERROR: column number must be in range from 1 to 32767 +CURSORPOS: 36 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 062 +-- truncate_limit: 100 +ALTER INDEX attmp_idx ALTER COLUMN 1 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX attmp_idx ALTER COLUMN 1 SET STATISTICS 1000" +== 063 +-- truncate_limit: 100 +ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000" +== 064 +-- truncate_limit: 100 +ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000" +== 065 +-- truncate_limit: 100 +ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000" +== 066 +-- truncate_limit: 100 +ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1" +== 067 +-- truncate_limit: 100 +DROP TABLE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp" +== 068 +-- truncate_limit: 100 +|-- +-- rename - check on both non-temp and temp tables +|-- +CREATE TABLE attmp (regtable int) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp (regtable int)" +== 069 +-- truncate_limit: 100 +CREATE TEMP TABLE attmp (attmptable int) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE attmp (attmptable int)" +== 070 +-- truncate_limit: 100 +ALTER TABLE attmp RENAME TO attmp_new +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE attmp RENAME TO attmp_new" +== 071 +-- truncate_limit: 100 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp" +== 072 +-- truncate_limit: 100 +SELECT * FROM attmp_new +-- +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp_new" +== 073 +-- truncate_limit: 100 +ALTER TABLE attmp RENAME TO attmp_new2 +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +TABLE: name="attmp_new2" schema="" table="attmp_new2" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE attmp RENAME TO attmp_new2" +== 074 +-- truncate_limit: 100 +SELECT * FROM attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp" +== 075 +-- truncate_limit: 100 +-- should fail +SELECT * FROM attmp_new +-- +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp_new" +== 076 +-- truncate_limit: 100 +SELECT * FROM attmp_new2 +-- +TABLE: name="attmp_new2" schema="" table="attmp_new2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp_new2" +== 077 +-- truncate_limit: 100 +DROP TABLE attmp_new +-- +TABLE: name="attmp_new" schema="" table="attmp_new" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp_new" +== 078 +-- truncate_limit: 100 +DROP TABLE attmp_new2 +-- +TABLE: name="attmp_new2" schema="" table="attmp_new2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp_new2" +== 079 +-- truncate_limit: 100 +-- check rename of partitioned tables and indexes also +CREATE TABLE part_attmp (a int primary key) partition by range (a) +-- +TABLE: name="part_attmp" schema="" table="part_attmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_attmp (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 080 +-- truncate_limit: 100 +CREATE TABLE part_attmp1 PARTITION OF part_attmp FOR VALUES FROM (0) TO (100) +-- +TABLE: name="part_attmp1" schema="" table="part_attmp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_attmp1 PARTITION OF part_attmp FOR VALUES FROM (0) TO (100)" +== 081 +-- truncate_limit: 100 +ALTER INDEX part_attmp_pkey RENAME TO part_attmp_index +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX part_attmp_pkey RENAME TO part_attmp_index" +== 082 +-- truncate_limit: 100 +ALTER INDEX part_attmp1_pkey RENAME TO part_attmp1_index +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX part_attmp1_pkey RENAME TO part_attmp1_index" +== 083 +-- truncate_limit: 100 +ALTER TABLE part_attmp RENAME TO part_at2tmp +-- +TABLE: name="part_attmp" schema="" table="part_attmp" ctx=DDL +TABLE: name="part_at2tmp" schema="" table="part_at2tmp" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE part_attmp RENAME TO part_at2tmp" +== 084 +-- truncate_limit: 100 +ALTER TABLE part_attmp1 RENAME TO part_at2tmp1 +-- +TABLE: name="part_attmp1" schema="" table="part_attmp1" ctx=DDL +TABLE: name="part_at2tmp1" schema="" table="part_at2tmp1" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE part_attmp1 RENAME TO part_at2tmp1" +== 085 +-- truncate_limit: 100 +SET ROLE regress_alter_table_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_alter_table_user1" +== 086 +-- truncate_limit: 100 +ALTER INDEX part_attmp_index RENAME TO fail +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX part_attmp_index RENAME TO fail" +== 087 +-- truncate_limit: 100 +ALTER INDEX part_attmp1_index RENAME TO fail +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX part_attmp1_index RENAME TO fail" +== 088 +-- truncate_limit: 100 +ALTER TABLE part_at2tmp RENAME TO fail +-- +TABLE: name="part_at2tmp" schema="" table="part_at2tmp" ctx=DDL +TABLE: name="fail" schema="" table="fail" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE part_at2tmp RENAME TO fail" +== 089 +-- truncate_limit: 100 +ALTER TABLE part_at2tmp1 RENAME TO fail +-- +TABLE: name="part_at2tmp1" schema="" table="part_at2tmp1" ctx=DDL +TABLE: name="fail" schema="" table="fail" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE part_at2tmp1 RENAME TO fail" +== 090 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 091 +-- truncate_limit: 100 +DROP TABLE part_at2tmp +-- +TABLE: name="part_at2tmp" schema="" table="part_at2tmp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_at2tmp" +== 092 +-- truncate_limit: 100 +|-- +-- check renaming to a table's array type's autogenerated name +-- (the array type's name should get out of the way) +|-- +CREATE TABLE attmp_array (id int) +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp_array (id int)" +== 093 +-- truncate_limit: 100 +CREATE TABLE attmp_array2 (id int) +-- +TABLE: name="attmp_array2" schema="" table="attmp_array2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp_array2 (id int)" +== 094 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype" +== 095 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE oid = 'attmp_array2[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE oid = 'attmp_array2[]'::regtype" +== 096 +-- truncate_limit: 100 +ALTER TABLE attmp_array2 RENAME TO _attmp_array +-- +TABLE: name="attmp_array2" schema="" table="attmp_array2" ctx=DDL +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE attmp_array2 RENAME TO _attmp_array" +== 097 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype" +== 098 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype" +== 099 +-- truncate_limit: 100 +DROP TABLE _attmp_array +-- +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE _attmp_array" +== 100 +-- truncate_limit: 100 +DROP TABLE attmp_array +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp_array" +== 101 +-- truncate_limit: 100 +-- renaming to table's own array type's name is an interesting corner case +CREATE TABLE attmp_array (id int) +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp_array (id int)" +== 102 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype" +== 103 +-- truncate_limit: 100 +ALTER TABLE attmp_array RENAME TO _attmp_array +-- +TABLE: name="attmp_array" schema="" table="attmp_array" ctx=DDL +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE attmp_array RENAME TO _attmp_array" +== 104 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype" +== 105 +-- truncate_limit: 100 +DROP TABLE _attmp_array +-- +TABLE: name="_attmp_array" schema="" table="_attmp_array" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE _attmp_array" +== 106 +-- truncate_limit: 100 +-- ALTER TABLE ... RENAME on non-table relations +-- renaming indexes (FIXME: this should probably test the index's functionality) +ALTER INDEX IF EXISTS __onek_unique1 RENAME TO attmp_onek_unique1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX IF EXISTS __onek_unique1 RENAME TO attmp_onek_unique1" +== 107 +-- truncate_limit: 100 +ALTER INDEX IF EXISTS __attmp_onek_unique1 RENAME TO onek_unique1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX IF EXISTS __attmp_onek_unique1 RENAME TO onek_unique1" +== 108 +-- truncate_limit: 100 +ALTER INDEX onek_unique1 RENAME TO attmp_onek_unique1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX onek_unique1 RENAME TO attmp_onek_unique1" +== 109 +-- truncate_limit: 100 +ALTER INDEX attmp_onek_unique1 RENAME TO onek_unique1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX attmp_onek_unique1 RENAME TO onek_unique1" +== 110 +-- truncate_limit: 100 +SET ROLE regress_alter_table_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_alter_table_user1" +== 111 +-- truncate_limit: 100 +ALTER INDEX onek_unique1 RENAME TO fail +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX onek_unique1 RENAME TO fail" +== 112 +-- truncate_limit: 100 +-- permission denied +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 113 +-- truncate_limit: 100 +-- rename statements with mismatching statement and object types +CREATE TABLE alter_idx_rename_test (a INT) +-- +TABLE: name="alter_idx_rename_test" schema="" table="alter_idx_rename_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alter_idx_rename_test (a int)" +== 114 +-- truncate_limit: 100 +CREATE INDEX alter_idx_rename_test_idx ON alter_idx_rename_test (a) +-- +TABLE: name="alter_idx_rename_test" schema="" table="alter_idx_rename_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX alter_idx_rename_test_idx ON alter_idx_rename_test USING btree (a)" +== 115 +-- truncate_limit: 100 +CREATE TABLE alter_idx_rename_test_parted (a INT) PARTITION BY LIST (a) +-- +TABLE: name="alter_idx_rename_test_parted" schema="" table="alter_idx_rename_test_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alter_idx_rename_test_parted (a int) PARTITION BY LIST (a)" +== 116 +-- truncate_limit: 100 +CREATE INDEX alter_idx_rename_test_parted_idx ON alter_idx_rename_test_parted (a) +-- +TABLE: name="alter_idx_rename_test_parted" schema="" table="alter_idx_rename_test_parted" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX alter_idx_rename_test_parted_idx ON alter_idx_rename_test_parted USING btree (a)" +== 117 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 118 +-- truncate_limit: 100 +ALTER INDEX alter_idx_rename_test RENAME TO alter_idx_rename_test_2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX alter_idx_rename_test RENAME TO alter_idx_rename_test_2" +== 119 +-- truncate_limit: 100 +ALTER INDEX alter_idx_rename_test_parted RENAME TO alter_idx_rename_test_parted_2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX alter_idx_rename_test_parted RENAME TO alter_idx_rename_test_parted_2" +== 120 +-- truncate_limit: 100 +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C" +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="locktype" +FILTER: schema="" table="" column="relation" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_locks WHERE ... ORDER BY relation::regclass::text COLLATE \"C\"" +== 121 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 122 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 123 +-- truncate_limit: 100 +ALTER INDEX alter_idx_rename_test_idx RENAME TO alter_idx_rename_test_idx_2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX alter_idx_rename_test_idx RENAME TO alter_idx_rename_test_idx_2" +== 124 +-- truncate_limit: 100 +ALTER INDEX alter_idx_rename_test_parted_idx RENAME TO alter_idx_rename_test_parted_idx_2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX alter_idx_rename_test_parted_idx RENAME TO alter_idx_rename_test_parted_idx_2" +== 125 +-- truncate_limit: 100 +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C" +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="locktype" +FILTER: schema="" table="" column="relation" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_locks WHERE ... ORDER BY relation::regclass::text COLLATE \"C\"" +== 126 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 127 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 128 +-- truncate_limit: 100 +ALTER TABLE alter_idx_rename_test_idx_2 RENAME TO alter_idx_rename_test_idx_3 +-- +TABLE: name="alter_idx_rename_test_idx_2" schema="" table="alter_idx_rename_test_idx_2" ctx=DDL +TABLE: name="alter_idx_rename_test_idx_3" schema="" table="alter_idx_rename_test_idx_3" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE alter_idx_rename_test_idx_2 RENAME TO alter_idx_rename_test_idx_3" +== 129 +-- truncate_limit: 100 +ALTER TABLE alter_idx_rename_test_parted_idx_2 RENAME TO alter_idx_rename_test_parted_idx_3 +-- +TABLE: name="alter_idx_rename_test_parted_idx_2" schema="" table="alter_idx_rename_test_parted_idx_2" ctx=DDL +TABLE: name="alter_idx_rename_test_parted_idx_3" schema="" table="alter_idx_rename_test_parted_idx_3" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE alter_idx_rename_test_parted_idx_2 RENAME TO alter_idx_rename_test_parted_idx_3" +== 130 +-- truncate_limit: 100 +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C" +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="locktype" +FILTER: schema="" table="" column="relation" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_locks WHERE ... ORDER BY relation::regclass::text COLLATE \"C\"" +== 131 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 132 +-- truncate_limit: 100 +DROP TABLE alter_idx_rename_test_2 +-- +TABLE: name="alter_idx_rename_test_2" schema="" table="alter_idx_rename_test_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE alter_idx_rename_test_2" +== 133 +-- truncate_limit: 100 +-- renaming views +CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1 +-- +TABLE: name="attmp_view" schema="" table="attmp_view" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1" +== 134 +-- truncate_limit: 100 +ALTER TABLE attmp_view RENAME TO attmp_view_new +-- +TABLE: name="attmp_view" schema="" table="attmp_view" ctx=DDL +TABLE: name="attmp_view_new" schema="" table="attmp_view_new" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE attmp_view RENAME TO attmp_view_new" +== 135 +-- truncate_limit: 100 +SET ROLE regress_alter_table_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_alter_table_user1" +== 136 +-- truncate_limit: 100 +ALTER VIEW attmp_view_new RENAME TO fail +-- +STMT: RenameStmt +TRUNCATED: "ALTER VIEW attmp_view_new RENAME TO fail" +== 137 +-- truncate_limit: 100 +-- permission denied +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 138 +-- truncate_limit: 100 +-- hack to ensure we get an indexscan here +set enable_seqscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 139 +-- truncate_limit: 100 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 140 +-- truncate_limit: 100 +-- 5 values, sorted +SELECT unique1 FROM tenk1 WHERE unique1 < 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 < 5" +== 141 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 142 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 143 +-- truncate_limit: 100 +DROP VIEW attmp_view_new +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW attmp_view_new" +== 144 +-- truncate_limit: 100 +-- toast-like relation name +alter table stud_emp rename to pg_toast_stud_emp +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +TABLE: name="pg_toast_stud_emp" schema="" table="pg_toast_stud_emp" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE stud_emp RENAME TO pg_toast_stud_emp" +== 145 +-- truncate_limit: 100 +alter table pg_toast_stud_emp rename to stud_emp +-- +TABLE: name="pg_toast_stud_emp" schema="" table="pg_toast_stud_emp" ctx=DDL +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE pg_toast_stud_emp RENAME TO stud_emp" +== 146 +-- truncate_limit: 100 +-- renaming index should rename constraint as well +ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1)" +== 147 +-- truncate_limit: 100 +ALTER INDEX onek_unique1_constraint RENAME TO onek_unique1_constraint_foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER INDEX onek_unique1_constraint RENAME TO onek_unique1_constraint_foo" +== 148 +-- truncate_limit: 100 +ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo" +== 149 +-- truncate_limit: 100 +-- renaming constraint +ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= 0) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= 0)" +== 150 +-- truncate_limit: 100 +ALTER TABLE onek RENAME CONSTRAINT onek_check_constraint TO onek_check_constraint_foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE onek RENAME CONSTRAINT onek_check_constraint TO onek_check_constraint_foo" +== 151 +-- truncate_limit: 100 +ALTER TABLE onek DROP CONSTRAINT onek_check_constraint_foo +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE onek DROP CONSTRAINT onek_check_constraint_foo" +== 152 +-- truncate_limit: 100 +-- renaming constraint should rename index as well +ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1)" +== 153 +-- truncate_limit: 100 +DROP INDEX onek_unique1_constraint +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX onek_unique1_constraint" +== 154 +-- truncate_limit: 100 +-- to see whether it's there +ALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo" +== 155 +-- truncate_limit: 100 +DROP INDEX onek_unique1_constraint_foo +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX onek_unique1_constraint_foo" +== 156 +-- truncate_limit: 100 +-- to see whether it's there +ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo" +== 157 +-- truncate_limit: 100 +-- renaming constraints vs. inheritance +CREATE TABLE constraint_rename_test (a int CONSTRAINT con1 CHECK (a > 0), b int, c int) +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE constraint_rename_test (a int CONSTRAINT con1 CHECK (a > 0), b int, c int)" +== 158 +-- truncate_limit: 100 +CREATE TABLE constraint_rename_test2 (a int CONSTRAINT con1 CHECK (a > 0), d int) INHERITS (constraint_rename_test) +-- +TABLE: name="constraint_rename_test2" schema="" table="constraint_rename_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE constraint_rename_test2 (a int CONSTRAINT con1 CHECK (a > 0), d int) INHERITS (const..." +== 159 +-- truncate_limit: 100 +ALTER TABLE constraint_rename_test2 RENAME CONSTRAINT con1 TO con1foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE constraint_rename_test2 RENAME CONSTRAINT con1 TO con1foo" +== 160 +-- truncate_limit: 100 +-- fail +ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con1 TO con1foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con1 TO con1foo" +== 161 +-- truncate_limit: 100 +-- fail +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con1 TO con1foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE constraint_rename_test RENAME CONSTRAINT con1 TO con1foo" +== 162 +-- truncate_limit: 100 +-- ok +ALTER TABLE constraint_rename_test ADD CONSTRAINT con2 CHECK (b > 0) NO INHERIT +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE constraint_rename_test ADD CONSTRAINT con2 CHECK (b > 0) NO INHERIT" +== 163 +-- truncate_limit: 100 +ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con2 TO con2foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con2 TO con2foo" +== 164 +-- truncate_limit: 100 +-- ok +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con2foo TO con2bar +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE constraint_rename_test RENAME CONSTRAINT con2foo TO con2bar" +== 165 +-- truncate_limit: 100 +-- ok +ALTER TABLE constraint_rename_test ADD CONSTRAINT con3 PRIMARY KEY (a) +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE constraint_rename_test ADD CONSTRAINT con3 PRIMARY KEY (a)" +== 166 +-- truncate_limit: 100 +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con3 TO con3foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE constraint_rename_test RENAME CONSTRAINT con3 TO con3foo" +== 167 +-- truncate_limit: 100 +-- ok +DROP TABLE constraint_rename_test2 +-- +TABLE: name="constraint_rename_test2" schema="" table="constraint_rename_test2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE constraint_rename_test2" +== 168 +-- truncate_limit: 100 +DROP TABLE constraint_rename_test +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE constraint_rename_test" +== 169 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo" +== 170 +-- truncate_limit: 100 +-- ok +ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a) +-- +TABLE: name="constraint_rename_test" schema="" table="constraint_rename_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a)" +== 171 +-- truncate_limit: 100 +-- renaming constraints with cache reset of target relation +CREATE TABLE constraint_rename_cache (a int, + CONSTRAINT chk_a CHECK (a > 0), + PRIMARY KEY (a)) +-- +TABLE: name="constraint_rename_cache" schema="" table="constraint_rename_cache" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE constraint_rename_cache (a int, CONSTRAINT chk_a CHECK (a > 0), PRIMARY KEY (a))" +== 172 +-- truncate_limit: 100 +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT chk_a TO chk_a_new +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE constraint_rename_cache RENAME CONSTRAINT chk_a TO chk_a_new" +== 173 +-- truncate_limit: 100 +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT constraint_rename_cache_pkey TO constraint_rename_pkey_new +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE constraint_rename_cache RENAME CONSTRAINT constraint_rename_cache_pkey TO constraint_..." +== 174 +-- truncate_limit: 100 +CREATE TABLE like_constraint_rename_cache + (LIKE constraint_rename_cache INCLUDING ALL) +-- +TABLE: name="like_constraint_rename_cache" schema="" table="like_constraint_rename_cache" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE like_constraint_rename_cache (LIKE constraint_rename_cache INCLUDING ALL)" +== 175 +-- truncate_limit: 100 +DROP TABLE constraint_rename_cache +-- +TABLE: name="constraint_rename_cache" schema="" table="constraint_rename_cache" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE constraint_rename_cache" +== 176 +-- truncate_limit: 100 +DROP TABLE like_constraint_rename_cache +-- +TABLE: name="like_constraint_rename_cache" schema="" table="like_constraint_rename_cache" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE like_constraint_rename_cache" +== 177 +-- truncate_limit: 100 +-- FOREIGN KEY CONSTRAINT adding TEST + +CREATE TABLE attmp2 (a int primary key) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp2 (a int PRIMARY KEY)" +== 178 +-- truncate_limit: 100 +CREATE TABLE attmp3 (a int, b int) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp3 (a int, b int)" +== 179 +-- truncate_limit: 100 +CREATE TABLE attmp4 (a int, b int, unique(a,b)) +-- +TABLE: name="attmp4" schema="" table="attmp4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp4 (a int, b int, UNIQUE (a, b))" +== 180 +-- truncate_limit: 100 +CREATE TABLE attmp5 (a int, b int) +-- +TABLE: name="attmp5" schema="" table="attmp5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp5 (a int, b int)" +== 181 +-- truncate_limit: 100 +-- Insert rows into attmp2 (pktable) +INSERT INTO attmp2 values (1) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp2 VALUES (1)" +== 182 +-- truncate_limit: 100 +INSERT INTO attmp2 values (2) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp2 VALUES (2)" +== 183 +-- truncate_limit: 100 +INSERT INTO attmp2 values (3) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp2 VALUES (3)" +== 184 +-- truncate_limit: 100 +INSERT INTO attmp2 values (4) +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp2 VALUES (4)" +== 185 +-- truncate_limit: 100 +-- Insert rows into attmp3 +INSERT INTO attmp3 values (1,10) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp3 VALUES (1, 10)" +== 186 +-- truncate_limit: 100 +INSERT INTO attmp3 values (1,20) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp3 VALUES (1, 20)" +== 187 +-- truncate_limit: 100 +INSERT INTO attmp3 values (5,50) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp3 VALUES (5, 50)" +== 188 +-- truncate_limit: 100 +-- Try (and fail) to add constraint due to invalid source columns +ALTER TABLE attmp3 add constraint attmpconstr foreign key(c) references attmp2 match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT attmpconstr FOREIGN KEY (c) REFERENCES attmp2 MATCH FULL" +== 189 +-- truncate_limit: 100 +-- Try (and fail) to add constraint due to invalid destination columns explicitly given +ALTER TABLE attmp3 add constraint attmpconstr foreign key(a) references attmp2(b) match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT attmpconstr FOREIGN KEY (a) REFERENCES attmp2 (b) MATCH FULL" +== 190 +-- truncate_limit: 100 +-- Try (and fail) to add constraint due to invalid data +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT attmpconstr FOREIGN KEY (a) REFERENCES attmp2 MATCH FULL" +== 191 +-- truncate_limit: 100 +-- Delete failing row +DELETE FROM attmp3 where a=5 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM attmp3 WHERE a = 5" +== 192 +-- truncate_limit: 100 +-- Try (and succeed) +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT attmpconstr FOREIGN KEY (a) REFERENCES attmp2 MATCH FULL" +== 193 +-- truncate_limit: 100 +ALTER TABLE attmp3 drop constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 DROP CONSTRAINT attmpconstr" +== 194 +-- truncate_limit: 100 +INSERT INTO attmp3 values (5,50) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp3 VALUES (5, 50)" +== 195 +-- truncate_limit: 100 +-- Try NOT VALID and then VALIDATE CONSTRAINT, but fails. Delete failure then re-validate +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT attmpconstr FOREIGN KEY (a) REFERENCES attmp2 MATCH FULL NOT VALID" +== 196 +-- truncate_limit: 100 +ALTER TABLE attmp3 validate constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT attmpconstr" +== 197 +-- truncate_limit: 100 +-- Delete failing row +DELETE FROM attmp3 where a=5 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM attmp3 WHERE a = 5" +== 198 +-- truncate_limit: 100 +-- Try (and succeed) and repeat to show it works on already valid constraint +ALTER TABLE attmp3 validate constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT attmpconstr" +== 199 +-- truncate_limit: 100 +ALTER TABLE attmp3 validate constraint attmpconstr +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT attmpconstr" +== 200 +-- truncate_limit: 100 +-- Try a non-verified CHECK constraint +ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10)" +== 201 +-- truncate_limit: 100 +-- fail +ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID" +== 202 +-- truncate_limit: 100 +-- succeeds +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten" +== 203 +-- truncate_limit: 100 +-- fails +DELETE FROM attmp3 WHERE NOT b > 10 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM attmp3 WHERE NOT b > 10" +== 204 +-- truncate_limit: 100 +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten" +== 205 +-- truncate_limit: 100 +-- succeeds +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten" +== 206 +-- truncate_limit: 100 +-- succeeds + +-- Test inherited NOT VALID CHECK constraints +select * from attmp3 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attmp3" +== 207 +-- truncate_limit: 100 +CREATE TABLE attmp6 () INHERITS (attmp3) +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp6 () INHERITS (attmp3)" +== 208 +-- truncate_limit: 100 +CREATE TABLE attmp7 () INHERITS (attmp3) +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp7 () INHERITS (attmp3)" +== 209 +-- truncate_limit: 100 +INSERT INTO attmp6 VALUES (6, 30), (7, 16) +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp6 VALUES (6, 30), (7, 16)" +== 210 +-- truncate_limit: 100 +ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID" +== 211 +-- truncate_limit: 100 +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20" +== 212 +-- truncate_limit: 100 +-- fails +DELETE FROM attmp6 WHERE b > 20 +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM attmp6 WHERE b > 20" +== 213 +-- truncate_limit: 100 +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20" +== 214 +-- truncate_limit: 100 +-- succeeds + +-- An already validated constraint must not be revalidated +CREATE FUNCTION boo(int) RETURNS int IMMUTABLE STRICT LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'boo: %', $1; RETURN $1; END; $$ +-- +FUNCTION: name="boo" function="boo" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION boo(int) RETURNS int IMMUTABLE RETURNS NULL ON NULL INPUT LANGUAGE plpgsql AS $$ ..." +== 215 +-- truncate_limit: 100 +INSERT INTO attmp7 VALUES (8, 18) +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp7 VALUES (8, 18)" +== 216 +-- truncate_limit: 100 +ALTER TABLE attmp7 ADD CONSTRAINT identity CHECK (b = boo(b)) +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp7 ADD CONSTRAINT identity CHECK (b = boo(b))" +== 217 +-- truncate_limit: 100 +ALTER TABLE attmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 ADD CONSTRAINT identity CHECK (b = boo(b)) NOT VALID" +== 218 +-- truncate_limit: 100 +ALTER TABLE attmp3 VALIDATE CONSTRAINT identity +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp3 VALIDATE CONSTRAINT identity" +== 219 +-- truncate_limit: 100 +-- A NO INHERIT constraint should not be looked for in children during VALIDATE CONSTRAINT +create table parent_noinh_convalid (a int) +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent_noinh_convalid (a int)" +== 220 +-- truncate_limit: 100 +create table child_noinh_convalid () inherits (parent_noinh_convalid) +-- +TABLE: name="child_noinh_convalid" schema="" table="child_noinh_convalid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child_noinh_convalid () INHERITS (parent_noinh_convalid)" +== 221 +-- truncate_limit: 100 +insert into parent_noinh_convalid values (1) +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent_noinh_convalid VALUES (1)" +== 222 +-- truncate_limit: 100 +insert into child_noinh_convalid values (1) +-- +TABLE: name="child_noinh_convalid" schema="" table="child_noinh_convalid" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child_noinh_convalid VALUES (1)" +== 223 +-- truncate_limit: 100 +alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent_noinh_convalid ADD CONSTRAINT check_a_is_2 CHECK (a = 2) NO INHERIT NOT VALID" +== 224 +-- truncate_limit: 100 +-- fail, because of the row in parent +alter table parent_noinh_convalid validate constraint check_a_is_2 +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent_noinh_convalid VALIDATE CONSTRAINT check_a_is_2" +== 225 +-- truncate_limit: 100 +delete from only parent_noinh_convalid +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ONLY parent_noinh_convalid" +== 226 +-- truncate_limit: 100 +-- ok (parent itself contains no violating rows) +alter table parent_noinh_convalid validate constraint check_a_is_2 +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent_noinh_convalid VALIDATE CONSTRAINT check_a_is_2" +== 227 +-- truncate_limit: 100 +select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid'::regclass and conname = 'check_a_is_2' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT convalidated FROM pg_constraint WHERE ..." +== 228 +-- truncate_limit: 100 +-- cleanup +drop table parent_noinh_convalid, child_noinh_convalid +-- +TABLE: name="parent_noinh_convalid" schema="" table="parent_noinh_convalid" ctx=DDL +TABLE: name="child_noinh_convalid" schema="" table="child_noinh_convalid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent_noinh_convalid, child_noinh_convalid" +== 229 +-- truncate_limit: 100 +-- Try (and fail) to create constraint from attmp5(a) to attmp4(a) - unique constraint on +-- attmp4 is a,b + +ALTER TABLE attmp5 add constraint attmpconstr foreign key(a) references attmp4(a) match full +-- +TABLE: name="attmp5" schema="" table="attmp5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp5 ADD CONSTRAINT attmpconstr FOREIGN KEY (a) REFERENCES attmp4 (a) MATCH FULL" +== 230 +-- truncate_limit: 100 +DROP TABLE attmp7 +-- +TABLE: name="attmp7" schema="" table="attmp7" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp7" +== 231 +-- truncate_limit: 100 +DROP TABLE attmp6 +-- +TABLE: name="attmp6" schema="" table="attmp6" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp6" +== 232 +-- truncate_limit: 100 +DROP TABLE attmp5 +-- +TABLE: name="attmp5" schema="" table="attmp5" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp5" +== 233 +-- truncate_limit: 100 +DROP TABLE attmp4 +-- +TABLE: name="attmp4" schema="" table="attmp4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp4" +== 234 +-- truncate_limit: 100 +DROP TABLE attmp3 +-- +TABLE: name="attmp3" schema="" table="attmp3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp3" +== 235 +-- truncate_limit: 100 +DROP TABLE attmp2 +-- +TABLE: name="attmp2" schema="" table="attmp2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp2" +== 236 +-- truncate_limit: 100 +-- NOT VALID with plan invalidation -- ensure we don't use a constraint for +-- exclusion until validated +set constraint_exclusion TO 'partition' +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO partition" +== 237 +-- truncate_limit: 100 +create table nv_parent (d date, check (false) no inherit not valid) +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nv_parent (d date, CHECK (false) NO INHERIT NOT VALID)" +== 238 +-- truncate_limit: 100 +-- not valid constraint added at creation time should automatically become valid + +create table nv_child_2010 () inherits (nv_parent) +-- +TABLE: name="nv_child_2010" schema="" table="nv_child_2010" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nv_child_2010 () INHERITS (nv_parent)" +== 239 +-- truncate_limit: 100 +create table nv_child_2011 () inherits (nv_parent) +-- +TABLE: name="nv_child_2011" schema="" table="nv_child_2011" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nv_child_2011 () INHERITS (nv_parent)" +== 240 +-- truncate_limit: 100 +alter table nv_child_2010 add check (d between '2010-01-01'::date and '2010-12-31'::date) not valid +-- +TABLE: name="nv_child_2010" schema="" table="nv_child_2010" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE nv_child_2010 ADD CHECK (d BETWEEN '2010-01-01'::date AND '2010-12-31'::date) NOT VALID" +== 241 +-- truncate_limit: 100 +alter table nv_child_2011 add check (d between '2011-01-01'::date and '2011-12-31'::date) not valid +-- +TABLE: name="nv_child_2011" schema="" table="nv_child_2011" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE nv_child_2011 ADD CHECK (d BETWEEN '2011-01-01'::date AND '2011-12-31'::date) NOT VALID" +== 242 +-- truncate_limit: 100 +explain (costs off) select * from nv_parent where d between '2011-08-01' and '2011-08-31' +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM nv_parent WHERE d BETWEEN '2011-08-01' AND '2011-08-31'" +== 243 +-- truncate_limit: 100 +create table nv_child_2009 (check (d between '2009-01-01'::date and '2009-12-31'::date)) inherits (nv_parent) +-- +TABLE: name="nv_child_2009" schema="" table="nv_child_2009" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nv_child_2009 (CHECK (d BETWEEN '2009-01-01'::date AND '2009-12-31'::date)) INHERITS..." +== 244 +-- truncate_limit: 100 +explain (costs off) select * from nv_parent where d between '2011-08-01'::date and '2011-08-31'::date +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM nv_parent WHERE d BETWEEN '2011-08-01'::date AND '2011-08-31'::..." +== 245 +-- truncate_limit: 100 +explain (costs off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM nv_parent WHERE d BETWEEN '2009-08-01'::date AND '2009-08-31'::..." +== 246 +-- truncate_limit: 100 +-- after validation, the constraint should be used +alter table nv_child_2011 VALIDATE CONSTRAINT nv_child_2011_d_check +-- +TABLE: name="nv_child_2011" schema="" table="nv_child_2011" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE nv_child_2011 VALIDATE CONSTRAINT nv_child_2011_d_check" +== 247 +-- truncate_limit: 100 +explain (costs off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=Select +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM nv_parent WHERE d BETWEEN '2009-08-01'::date AND '2009-08-31'::..." +== 248 +-- truncate_limit: 100 +-- add an inherited NOT VALID constraint +alter table nv_parent add check (d between '2001-01-01'::date and '2099-12-31'::date) not valid +-- +TABLE: name="nv_parent" schema="" table="nv_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE nv_parent ADD CHECK (d BETWEEN '2001-01-01'::date AND '2099-12-31'::date) NOT VALID" +== 249 +-- truncate_limit: 100 +-- we leave nv_parent and children around to help test pg_dump logic + +-- Foreign key adding test with mixed types + +-- Note: these tables are TEMP to avoid name conflicts when this test +-- is run in parallel with foreign_key.sql. + +CREATE TEMP TABLE PKTABLE (ptest1 int PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pktable (ptest1 int PRIMARY KEY)" +== 250 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (42)" +== 251 +-- truncate_limit: 100 +CREATE TEMP TABLE FKTABLE (ftest1 inet) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 inet)" +== 252 +-- truncate_limit: 100 +-- This next should fail, because int=inet does not exist +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1) REFERENCES pktable" +== 253 +-- truncate_limit: 100 +-- This should also fail for the same reason, but here we +-- give the column name +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1) REFERENCES pktable (ptest1)" +== 254 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 255 +-- truncate_limit: 100 +-- This should succeed, even though they are different types, +-- because int=int8 exists and is a member of the integer opfamily +CREATE TEMP TABLE FKTABLE (ftest1 int8) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 int8)" +== 256 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1) REFERENCES pktable" +== 257 +-- truncate_limit: 100 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (42)" +== 258 +-- truncate_limit: 100 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (43)" +== 259 +-- truncate_limit: 100 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 260 +-- truncate_limit: 100 +-- This should fail, because we'd have to cast numeric to int which is +-- not an implicit coercion (or use numeric=numeric, but that's not part +-- of the integer opfamily) +CREATE TEMP TABLE FKTABLE (ftest1 numeric) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 numeric)" +== 261 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1) REFERENCES pktable" +== 262 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 263 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 264 +-- truncate_limit: 100 +-- On the other hand, this should work because int implicitly promotes to +-- numeric, and we allow promotion on the FK side +CREATE TEMP TABLE PKTABLE (ptest1 numeric PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pktable (ptest1 numeric PRIMARY KEY)" +== 265 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (42)" +== 266 +-- truncate_limit: 100 +CREATE TEMP TABLE FKTABLE (ftest1 int) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 int)" +== 267 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1) REFERENCES pktable" +== 268 +-- truncate_limit: 100 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (42)" +== 269 +-- truncate_limit: 100 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (43)" +== 270 +-- truncate_limit: 100 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 271 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 272 +-- truncate_limit: 100 +CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet, + PRIMARY KEY(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pktable (ptest1 int, ptest2 inet, PRIMARY KEY (ptest1, ptest2))" +== 273 +-- truncate_limit: 100 +-- This should fail, because we just chose really odd types +CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 cidr, ftest2 timestamp)" +== 274 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1, ftest2) REFERENCES pktable" +== 275 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 276 +-- truncate_limit: 100 +-- Again, so should this... +CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 cidr, ftest2 timestamp)" +== 277 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) + references pktable(ptest1, ptest2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1, ftest2) REFERENCES pktable (ptest1, ptest2)" +== 278 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 279 +-- truncate_limit: 100 +-- This fails because we mixed up the column ordering +CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 int, ftest2 inet)" +== 280 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) + references pktable(ptest2, ptest1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1, ftest2) REFERENCES pktable (ptest2, ptest1)" +== 281 +-- truncate_limit: 100 +-- As does this... +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1) + references pktable(ptest1, ptest2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest2, ftest1) REFERENCES pktable (ptest1, ptest2)" +== 282 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 283 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 284 +-- truncate_limit: 100 +-- Test that ALTER CONSTRAINT updates trigger deferrability properly + +CREATE TEMP TABLE PKTABLE (ptest1 int primary key) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pktable (ptest1 int PRIMARY KEY)" +== 285 +-- truncate_limit: 100 +CREATE TEMP TABLE FKTABLE (ftest1 int) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (ftest1 int)" +== 286 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD CONSTRAINT fknd FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fknd FOREIGN KEY (ftest1) REFERENCES pktable ON DELETE CASCADE" +== 287 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdd FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fkdd FOREIGN KEY (ftest1) REFERENCES pktable ON DELETE CASCADE..." +== 288 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdi FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fkdi FOREIGN KEY (ftest1) REFERENCES pktable ON DELETE CASCADE..." +== 289 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD CONSTRAINT fknd2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fknd2 FOREIGN KEY (ftest1) REFERENCES pktable ON DELETE CASCAD..." +== 290 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ALTER CONSTRAINT fknd2 NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ALTER CONSTRAINT fknd2" +== 291 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdd2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fkdd2 FOREIGN KEY (ftest1) REFERENCES pktable ON DELETE CASCADE" +== 292 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ALTER CONSTRAINT fkdd2 DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ALTER CONSTRAINT fkdd2 DEFERRABLE INITIALLY DEFERRED" +== 293 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD CONSTRAINT fkdi2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fkdi2 FOREIGN KEY (ftest1) REFERENCES pktable ON DELETE CASCADE" +== 294 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ALTER CONSTRAINT fkdi2 DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ALTER CONSTRAINT fkdi2 DEFERRABLE" +== 295 +-- truncate_limit: 100 +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred +FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint +WHERE tgrelid = 'pktable'::regclass +ORDER BY 1,2,3 +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint WHERE ... ORDER BY 1,..." +== 296 +-- truncate_limit: 100 +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred +FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint +WHERE tgrelid = 'fktable'::regclass +ORDER BY 1,2,3 +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint WHERE ... ORDER BY 1,..." +== 297 +-- truncate_limit: 100 +-- temp tables should go away by themselves, need not drop them. + +-- test check constraint adding + +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 298 +-- truncate_limit: 100 +-- add a check constraint +alter table atacc1 add constraint atacc_test1 check (test>3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 CHECK (test > 3)" +== 299 +-- truncate_limit: 100 +-- should fail +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 300 +-- truncate_limit: 100 +-- should succeed +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (4)" +== 301 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 302 +-- truncate_limit: 100 +-- let's do one where the check fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 303 +-- truncate_limit: 100 +-- insert a soon to be failing row +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 304 +-- truncate_limit: 100 +-- add a check constraint (fails) +alter table atacc1 add constraint atacc_test1 check (test>3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 CHECK (test > 3)" +== 305 +-- truncate_limit: 100 +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (4)" +== 306 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 307 +-- truncate_limit: 100 +-- let's do one where the check fails because the column doesn't exist +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 308 +-- truncate_limit: 100 +-- add a check constraint (fails) +alter table atacc1 add constraint atacc_test1 check (test1>3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 CHECK (test1 > 3)" +== 309 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 310 +-- truncate_limit: 100 +-- something a little more complicated +create table atacc1 ( test int, test2 int, test3 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int, test2 int, test3 int)" +== 311 +-- truncate_limit: 100 +-- add a check constraint (fails) +alter table atacc1 add constraint atacc_test1 check (test+test23), test2 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int CHECK (test > 3), test2 int)" +== 316 +-- truncate_limit: 100 +alter table atacc1 add check (test2>test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CHECK (test2 > test)" +== 317 +-- truncate_limit: 100 +-- should fail for $2 +insert into atacc1 (test2, test) values (3, 4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test2, test) VALUES (3, 4)" +== 318 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 319 +-- truncate_limit: 100 +-- inheritance related tests +create table atacc1 (test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 320 +-- truncate_limit: 100 +create table atacc2 (test2 int) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc2 (test2 int)" +== 321 +-- truncate_limit: 100 +create table atacc3 (test3 int) inherits (atacc1, atacc2) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc3 (test3 int) INHERITS (atacc1, atacc2)" +== 322 +-- truncate_limit: 100 +alter table atacc2 add constraint foo check (test2>0) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc2 ADD CONSTRAINT foo CHECK (test2 > 0)" +== 323 +-- truncate_limit: 100 +-- fail and then succeed on atacc2 +insert into atacc2 (test2) values (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc2 (test2) VALUES (-3)" +== 324 +-- truncate_limit: 100 +insert into atacc2 (test2) values (3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc2 (test2) VALUES (3)" +== 325 +-- truncate_limit: 100 +-- fail and then succeed on atacc3 +insert into atacc3 (test2) values (-3) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc3 (test2) VALUES (-3)" +== 326 +-- truncate_limit: 100 +insert into atacc3 (test2) values (3) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc3 (test2) VALUES (3)" +== 327 +-- truncate_limit: 100 +drop table atacc3 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc3" +== 328 +-- truncate_limit: 100 +drop table atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc2" +== 329 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 330 +-- truncate_limit: 100 +-- same things with one created with INHERIT +create table atacc1 (test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 331 +-- truncate_limit: 100 +create table atacc2 (test2 int) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc2 (test2 int)" +== 332 +-- truncate_limit: 100 +create table atacc3 (test3 int) inherits (atacc1, atacc2) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc3 (test3 int) INHERITS (atacc1, atacc2)" +== 333 +-- truncate_limit: 100 +alter table atacc3 no inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 NO INHERIT atacc2" +== 334 +-- truncate_limit: 100 +-- fail +alter table atacc3 no inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 NO INHERIT atacc2" +== 335 +-- truncate_limit: 100 +-- make sure it really isn't a child +insert into atacc3 (test2) values (3) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc3 (test2) VALUES (3)" +== 336 +-- truncate_limit: 100 +select test2 from atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT test2 FROM atacc2" +== 337 +-- truncate_limit: 100 +-- fail due to missing constraint +alter table atacc2 add constraint foo check (test2>0) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc2 ADD CONSTRAINT foo CHECK (test2 > 0)" +== 338 +-- truncate_limit: 100 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 INHERIT atacc2" +== 339 +-- truncate_limit: 100 +-- fail due to missing column +alter table atacc3 rename test2 to testx +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE atacc3 RENAME COLUMN test2 TO testx" +== 340 +-- truncate_limit: 100 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 INHERIT atacc2" +== 341 +-- truncate_limit: 100 +-- fail due to mismatched data type +alter table atacc3 add test2 bool +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 ADD COLUMN test2 bool" +== 342 +-- truncate_limit: 100 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 INHERIT atacc2" +== 343 +-- truncate_limit: 100 +alter table atacc3 drop test2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 DROP test2" +== 344 +-- truncate_limit: 100 +-- succeed +alter table atacc3 add test2 int +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 ADD COLUMN test2 int" +== 345 +-- truncate_limit: 100 +update atacc3 set test2 = 4 where test2 is null +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atacc3 SET test2 = 4 WHERE test2 IS NULL" +== 346 +-- truncate_limit: 100 +alter table atacc3 add constraint foo check (test2>0) +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 ADD CONSTRAINT foo CHECK (test2 > 0)" +== 347 +-- truncate_limit: 100 +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 INHERIT atacc2" +== 348 +-- truncate_limit: 100 +-- fail due to duplicates and circular inheritance +alter table atacc3 inherit atacc2 +-- +TABLE: name="atacc3" schema="" table="atacc3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc3 INHERIT atacc2" +== 349 +-- truncate_limit: 100 +alter table atacc2 inherit atacc3 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc2 INHERIT atacc3" +== 350 +-- truncate_limit: 100 +alter table atacc2 inherit atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc2 INHERIT atacc2" +== 351 +-- truncate_limit: 100 +-- test that we really are a child now (should see 4 not 3 and cascade should go through) +select test2 from atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT test2 FROM atacc2" +== 352 +-- truncate_limit: 100 +drop table atacc2 cascade +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc2 CASCADE" +== 353 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 354 +-- truncate_limit: 100 +-- adding only to a parent is allowed as of 9.2 + +create table atacc1 (test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 355 +-- truncate_limit: 100 +create table atacc2 (test2 int) inherits (atacc1) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc2 (test2 int) INHERITS (atacc1)" +== 356 +-- truncate_limit: 100 +-- ok: +alter table atacc1 add constraint foo check (test>0) no inherit +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT foo CHECK (test > 0) NO INHERIT" +== 357 +-- truncate_limit: 100 +-- check constraint is not there on child +insert into atacc2 (test) values (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc2 (test) VALUES (-3)" +== 358 +-- truncate_limit: 100 +-- check constraint is there on parent +insert into atacc1 (test) values (-3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (-3)" +== 359 +-- truncate_limit: 100 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (3)" +== 360 +-- truncate_limit: 100 +-- fail, violating row: +alter table atacc2 add constraint foo check (test>0) no inherit +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc2 ADD CONSTRAINT foo CHECK (test > 0) NO INHERIT" +== 361 +-- truncate_limit: 100 +drop table atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc2" +== 362 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 363 +-- truncate_limit: 100 +-- test unique constraint adding + +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 364 +-- truncate_limit: 100 +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 UNIQUE (test)" +== 365 +-- truncate_limit: 100 +-- insert first value +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 366 +-- truncate_limit: 100 +-- should fail +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 367 +-- truncate_limit: 100 +-- should succeed +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (4)" +== 368 +-- truncate_limit: 100 +-- try to create duplicates via alter table using - should fail +alter table atacc1 alter column test type integer using 0 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test TYPE int USING 0" +== 369 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 370 +-- truncate_limit: 100 +-- let's do one where the unique constraint fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 371 +-- truncate_limit: 100 +-- insert soon to be failing rows +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 372 +-- truncate_limit: 100 +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 373 +-- truncate_limit: 100 +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 UNIQUE (test)" +== 374 +-- truncate_limit: 100 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (3)" +== 375 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 376 +-- truncate_limit: 100 +-- let's do one where the unique constraint fails +-- because the column doesn't exist +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 377 +-- truncate_limit: 100 +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 UNIQUE (test1)" +== 378 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 379 +-- truncate_limit: 100 +-- something a little more complicated +create table atacc1 ( test int, test2 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int, test2 int)" +== 380 +-- truncate_limit: 100 +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test, test2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 UNIQUE (test, test2)" +== 381 +-- truncate_limit: 100 +-- insert initial value +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (4, 4)" +== 382 +-- truncate_limit: 100 +-- should fail +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (4, 4)" +== 383 +-- truncate_limit: 100 +-- should all succeed +insert into atacc1 (test,test2) values (4,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (4, 5)" +== 384 +-- truncate_limit: 100 +insert into atacc1 (test,test2) values (5,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (5, 4)" +== 385 +-- truncate_limit: 100 +insert into atacc1 (test,test2) values (5,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (5, 5)" +== 386 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 387 +-- truncate_limit: 100 +-- lets do some naming tests +create table atacc1 (test int, test2 int, unique(test)) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int, test2 int, UNIQUE (test))" +== 388 +-- truncate_limit: 100 +alter table atacc1 add unique (test2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD UNIQUE (test2)" +== 389 +-- truncate_limit: 100 +-- should fail for @@ second one @@ +insert into atacc1 (test2, test) values (3, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test2, test) VALUES (3, 3)" +== 390 +-- truncate_limit: 100 +insert into atacc1 (test2, test) values (2, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test2, test) VALUES (2, 3)" +== 391 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 392 +-- truncate_limit: 100 +-- test primary key constraint adding + +create table atacc1 ( id serial, test int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (id serial, test int)" +== 393 +-- truncate_limit: 100 +-- add a primary key constraint +alter table atacc1 add constraint atacc_test1 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 PRIMARY KEY (test)" +== 394 +-- truncate_limit: 100 +-- insert first value +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 395 +-- truncate_limit: 100 +-- should fail +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 396 +-- truncate_limit: 100 +-- should succeed +insert into atacc1 (test) values (4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (4)" +== 397 +-- truncate_limit: 100 +-- inserting NULL should fail +insert into atacc1 (test) values(NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (NULL)" +== 398 +-- truncate_limit: 100 +-- try adding a second primary key (should fail) +alter table atacc1 add constraint atacc_oid1 primary key(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_oid1 PRIMARY KEY (id)" +== 399 +-- truncate_limit: 100 +-- drop first primary key constraint +alter table atacc1 drop constraint atacc_test1 restrict +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP CONSTRAINT atacc_test1" +== 400 +-- truncate_limit: 100 +-- try adding a primary key on oid (should succeed) +alter table atacc1 add constraint atacc_oid1 primary key(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_oid1 PRIMARY KEY (id)" +== 401 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 402 +-- truncate_limit: 100 +-- let's do one where the primary key constraint fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 403 +-- truncate_limit: 100 +-- insert soon to be failing rows +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 404 +-- truncate_limit: 100 +insert into atacc1 (test) values (2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (2)" +== 405 +-- truncate_limit: 100 +-- add a primary key (fails) +alter table atacc1 add constraint atacc_test1 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 PRIMARY KEY (test)" +== 406 +-- truncate_limit: 100 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (3)" +== 407 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 408 +-- truncate_limit: 100 +-- let's do another one where the primary key constraint fails when added +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 409 +-- truncate_limit: 100 +-- insert soon to be failing row +insert into atacc1 (test) values (NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (NULL)" +== 410 +-- truncate_limit: 100 +-- add a primary key (fails) +alter table atacc1 add constraint atacc_test1 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 PRIMARY KEY (test)" +== 411 +-- truncate_limit: 100 +insert into atacc1 (test) values (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (3)" +== 412 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 413 +-- truncate_limit: 100 +-- let's do one where the primary key constraint fails +-- because the column doesn't exist +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 414 +-- truncate_limit: 100 +-- add a primary key constraint (fails) +alter table atacc1 add constraint atacc_test1 primary key (test1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 PRIMARY KEY (test1)" +== 415 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 416 +-- truncate_limit: 100 +-- adding a new column as primary key to a non-empty table. +-- should fail unless the column has a non-null default value. +create table atacc1 ( test int ) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int)" +== 417 +-- truncate_limit: 100 +insert into atacc1 (test) values (0) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (0)" +== 418 +-- truncate_limit: 100 +-- add a primary key column without a default (fails). +alter table atacc1 add column test2 int primary key +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD COLUMN test2 int PRIMARY KEY" +== 419 +-- truncate_limit: 100 +-- now add a primary key column with a default (succeeds). +alter table atacc1 add column test2 int default 0 primary key +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD COLUMN test2 int DEFAULT 0 PRIMARY KEY" +== 420 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 421 +-- truncate_limit: 100 +-- this combination used to have order-of-execution problems (bug #15580) +create table atacc1 (a int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (a int)" +== 422 +-- truncate_limit: 100 +insert into atacc1 values(1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (1)" +== 423 +-- truncate_limit: 100 +alter table atacc1 + add column b float8 not null default random(), + add primary key(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD COLUMN b float8 NOT NULL DEFAULT random(), ADD PRIMARY KEY (a)" +== 424 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 425 +-- truncate_limit: 100 +-- additionally, we've seen issues with foreign key validation not being +-- properly delayed until after a table rewrite. Check that works ok. +create table atacc1 (a int primary key) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (a int PRIMARY KEY)" +== 426 +-- truncate_limit: 100 +alter table atacc1 add constraint atacc1_fkey foreign key (a) references atacc1 (a) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_fkey FOREIGN KEY (a) REFERENCES atacc1 (a) NOT VALID" +== 427 +-- truncate_limit: 100 +alter table atacc1 validate constraint atacc1_fkey, alter a type bigint +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 VALIDATE CONSTRAINT atacc1_fkey, ALTER COLUMN a TYPE bigint" +== 428 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 429 +-- truncate_limit: 100 +-- we've also seen issues with check constraints being validated at the wrong +-- time when there's a pending table rewrite. +create table atacc1 (a bigint, b int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (a bigint, b int)" +== 430 +-- truncate_limit: 100 +insert into atacc1 values(1,1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (1, 1)" +== 431 +-- truncate_limit: 100 +alter table atacc1 add constraint atacc1_chk check(b = 1) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_chk CHECK (b = 1) NOT VALID" +== 432 +-- truncate_limit: 100 +alter table atacc1 validate constraint atacc1_chk, alter a type int +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 VALIDATE CONSTRAINT atacc1_chk, ALTER COLUMN a TYPE int" +== 433 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 434 +-- truncate_limit: 100 +-- same as above, but ensure the constraint violation is detected +create table atacc1 (a bigint, b int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (a bigint, b int)" +== 435 +-- truncate_limit: 100 +insert into atacc1 values(1,2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (1, 2)" +== 436 +-- truncate_limit: 100 +alter table atacc1 add constraint atacc1_chk check(b = 1) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_chk CHECK (b = 1) NOT VALID" +== 437 +-- truncate_limit: 100 +alter table atacc1 validate constraint atacc1_chk, alter a type int +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 VALIDATE CONSTRAINT atacc1_chk, ALTER COLUMN a TYPE int" +== 438 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 439 +-- truncate_limit: 100 +-- something a little more complicated +create table atacc1 ( test int, test2 int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int, test2 int)" +== 440 +-- truncate_limit: 100 +-- add a primary key constraint +alter table atacc1 add constraint atacc_test1 primary key (test, test2) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test1 PRIMARY KEY (test, test2)" +== 441 +-- truncate_limit: 100 +-- try adding a second primary key - should fail +alter table atacc1 add constraint atacc_test2 primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc_test2 PRIMARY KEY (test)" +== 442 +-- truncate_limit: 100 +-- insert initial value +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (4, 4)" +== 443 +-- truncate_limit: 100 +-- should fail +insert into atacc1 (test,test2) values (4,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (4, 4)" +== 444 +-- truncate_limit: 100 +insert into atacc1 (test,test2) values (NULL,3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (NULL, 3)" +== 445 +-- truncate_limit: 100 +insert into atacc1 (test,test2) values (3, NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (3, NULL)" +== 446 +-- truncate_limit: 100 +insert into atacc1 (test,test2) values (NULL,NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (NULL, NULL)" +== 447 +-- truncate_limit: 100 +-- should all succeed +insert into atacc1 (test,test2) values (4,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (4, 5)" +== 448 +-- truncate_limit: 100 +insert into atacc1 (test,test2) values (5,4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (5, 4)" +== 449 +-- truncate_limit: 100 +insert into atacc1 (test,test2) values (5,5) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test, test2) VALUES (5, 5)" +== 450 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 451 +-- truncate_limit: 100 +-- lets do some naming tests +create table atacc1 (test int, test2 int, primary key(test)) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int, test2 int, PRIMARY KEY (test))" +== 452 +-- truncate_limit: 100 +-- only first should succeed +insert into atacc1 (test2, test) values (3, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test2, test) VALUES (3, 3)" +== 453 +-- truncate_limit: 100 +insert into atacc1 (test2, test) values (2, 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test2, test) VALUES (2, 3)" +== 454 +-- truncate_limit: 100 +insert into atacc1 (test2, test) values (1, NULL) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test2, test) VALUES (1, NULL)" +== 455 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 456 +-- truncate_limit: 100 +-- alter table / alter column [set/drop] not null tests +-- try altering system catalogs, should fail +alter table pg_class alter column relname drop not null +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pg_class ALTER COLUMN relname DROP NOT NULL" +== 457 +-- truncate_limit: 100 +alter table pg_class alter relname set not null +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pg_class ALTER COLUMN relname SET NOT NULL" +== 458 +-- truncate_limit: 100 +-- try altering non-existent table, should fail +alter table non_existent alter column bar set not null +-- +TABLE: name="non_existent" schema="" table="non_existent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE non_existent ALTER COLUMN bar SET NOT NULL" +== 459 +-- truncate_limit: 100 +alter table non_existent alter column bar drop not null +-- +TABLE: name="non_existent" schema="" table="non_existent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE non_existent ALTER COLUMN bar DROP NOT NULL" +== 460 +-- truncate_limit: 100 +-- test setting columns to null and not null and vice versa +-- test checking for null values and primary key +create table atacc1 (test int not null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int NOT NULL)" +== 461 +-- truncate_limit: 100 +alter table atacc1 add constraint "atacc1_pkey" primary key (test) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_pkey PRIMARY KEY (test)" +== 462 +-- truncate_limit: 100 +alter table atacc1 alter column test drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test DROP NOT NULL" +== 463 +-- truncate_limit: 100 +alter table atacc1 drop constraint "atacc1_pkey" +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP CONSTRAINT atacc1_pkey" +== 464 +-- truncate_limit: 100 +alter table atacc1 alter column test drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test DROP NOT NULL" +== 465 +-- truncate_limit: 100 +insert into atacc1 values (null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (NULL)" +== 466 +-- truncate_limit: 100 +alter table atacc1 alter test set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test SET NOT NULL" +== 467 +-- truncate_limit: 100 +delete from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atacc1" +== 468 +-- truncate_limit: 100 +alter table atacc1 alter test set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test SET NOT NULL" +== 469 +-- truncate_limit: 100 +-- try altering a non-existent column, should fail +alter table atacc1 alter bar set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN bar SET NOT NULL" +== 470 +-- truncate_limit: 100 +alter table atacc1 alter bar drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN bar DROP NOT NULL" +== 471 +-- truncate_limit: 100 +-- try creating a view and altering that, should fail +create view myview as select * from atacc1 +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW myview AS SELECT * FROM atacc1" +== 472 +-- truncate_limit: 100 +alter table myview alter column test drop not null +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE myview ALTER COLUMN test DROP NOT NULL" +== 473 +-- truncate_limit: 100 +alter table myview alter column test set not null +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE myview ALTER COLUMN test SET NOT NULL" +== 474 +-- truncate_limit: 100 +drop view myview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW myview" +== 475 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 476 +-- truncate_limit: 100 +-- set not null verified by constraints +create table atacc1 (test_a int, test_b int) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test_a int, test_b int)" +== 477 +-- truncate_limit: 100 +insert into atacc1 values (null, 1) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (NULL, 1)" +== 478 +-- truncate_limit: 100 +-- constraint not cover all values, should fail +alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_constr_or CHECK (test_a IS NOT NULL OR test_b < 10)" +== 479 +-- truncate_limit: 100 +alter table atacc1 alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_a SET NOT NULL" +== 480 +-- truncate_limit: 100 +alter table atacc1 drop constraint atacc1_constr_or +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP CONSTRAINT atacc1_constr_or" +== 481 +-- truncate_limit: 100 +-- not valid constraint, should fail +alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_constr_invalid CHECK (test_a IS NOT NULL) NOT VALID" +== 482 +-- truncate_limit: 100 +alter table atacc1 alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_a SET NOT NULL" +== 483 +-- truncate_limit: 100 +alter table atacc1 drop constraint atacc1_constr_invalid +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP CONSTRAINT atacc1_constr_invalid" +== 484 +-- truncate_limit: 100 +-- with valid constraint +update atacc1 set test_a = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atacc1 SET test_a = 1" +== 485 +-- truncate_limit: 100 +alter table atacc1 add constraint atacc1_constr_a_valid check(test_a is not null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_constr_a_valid CHECK (test_a IS NOT NULL)" +== 486 +-- truncate_limit: 100 +alter table atacc1 alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_a SET NOT NULL" +== 487 +-- truncate_limit: 100 +delete from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atacc1" +== 488 +-- truncate_limit: 100 +insert into atacc1 values (2, null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (2, NULL)" +== 489 +-- truncate_limit: 100 +alter table atacc1 alter test_a drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_a DROP NOT NULL" +== 490 +-- truncate_limit: 100 +-- test multiple set not null at same time +-- test_a checked by atacc1_constr_a_valid, test_b should fail by table scan +alter table atacc1 alter test_a set not null, alter test_b set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_a SET NOT NULL, ALTER COLUMN test_b SET NOT NULL" +== 491 +-- truncate_limit: 100 +-- commands order has no importance +alter table atacc1 alter test_b set not null, alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_b SET NOT NULL, ALTER COLUMN test_a SET NOT NULL" +== 492 +-- truncate_limit: 100 +-- valid one by table scan, one by check constraints +update atacc1 set test_b = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atacc1 SET test_b = 1" +== 493 +-- truncate_limit: 100 +alter table atacc1 alter test_b set not null, alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_b SET NOT NULL, ALTER COLUMN test_a SET NOT NULL" +== 494 +-- truncate_limit: 100 +alter table atacc1 alter test_a drop not null, alter test_b drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_a DROP NOT NULL, ALTER COLUMN test_b DROP NOT NULL" +== 495 +-- truncate_limit: 100 +-- both column has check constraints +alter table atacc1 add constraint atacc1_constr_b_valid check(test_b is not null) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CONSTRAINT atacc1_constr_b_valid CHECK (test_b IS NOT NULL)" +== 496 +-- truncate_limit: 100 +alter table atacc1 alter test_b set not null, alter test_a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN test_b SET NOT NULL, ALTER COLUMN test_a SET NOT NULL" +== 497 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 498 +-- truncate_limit: 100 +-- test inheritance +create table parent (a int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a int)" +== 499 +-- truncate_limit: 100 +create table child (b varchar(255)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child (b varchar(255)) INHERITS (parent)" +== 500 +-- truncate_limit: 100 +alter table parent alter a set not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ALTER COLUMN a SET NOT NULL" +== 501 +-- truncate_limit: 100 +insert into parent values (NULL) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (NULL)" +== 502 +-- truncate_limit: 100 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child (a, b) VALUES (NULL, 'foo')" +== 503 +-- truncate_limit: 100 +alter table parent alter a drop not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ALTER COLUMN a DROP NOT NULL" +== 504 +-- truncate_limit: 100 +insert into parent values (NULL) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (NULL)" +== 505 +-- truncate_limit: 100 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child (a, b) VALUES (NULL, 'foo')" +== 506 +-- truncate_limit: 100 +alter table only parent alter a set not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parent ALTER COLUMN a SET NOT NULL" +== 507 +-- truncate_limit: 100 +alter table child alter a set not null +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child ALTER COLUMN a SET NOT NULL" +== 508 +-- truncate_limit: 100 +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parent" +== 509 +-- truncate_limit: 100 +alter table only parent alter a set not null +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parent ALTER COLUMN a SET NOT NULL" +== 510 +-- truncate_limit: 100 +insert into parent values (NULL) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (NULL)" +== 511 +-- truncate_limit: 100 +alter table child alter a set not null +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child ALTER COLUMN a SET NOT NULL" +== 512 +-- truncate_limit: 100 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child (a, b) VALUES (NULL, 'foo')" +== 513 +-- truncate_limit: 100 +delete from child +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM child" +== 514 +-- truncate_limit: 100 +alter table child alter a set not null +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child ALTER COLUMN a SET NOT NULL" +== 515 +-- truncate_limit: 100 +insert into child (a, b) values (NULL, 'foo') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child (a, b) VALUES (NULL, 'foo')" +== 516 +-- truncate_limit: 100 +drop table child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child" +== 517 +-- truncate_limit: 100 +drop table parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent" +== 518 +-- truncate_limit: 100 +-- test setting and removing default values +create table def_test ( + c1 int4 default 5, + c2 text default 'initial_default' +) +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE def_test (c1 int4 DEFAULT 5, c2 text DEFAULT 'initial_default')" +== 519 +-- truncate_limit: 100 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO def_test DEFAULT VALUES" +== 520 +-- truncate_limit: 100 +alter table def_test alter column c1 drop default +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_test ALTER COLUMN c1 DROP DEFAULT" +== 521 +-- truncate_limit: 100 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO def_test DEFAULT VALUES" +== 522 +-- truncate_limit: 100 +alter table def_test alter column c2 drop default +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_test ALTER COLUMN c2 DROP DEFAULT" +== 523 +-- truncate_limit: 100 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO def_test DEFAULT VALUES" +== 524 +-- truncate_limit: 100 +alter table def_test alter column c1 set default 10 +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_test ALTER COLUMN c1 SET DEFAULT 10" +== 525 +-- truncate_limit: 100 +alter table def_test alter column c2 set default 'new_default' +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_test ALTER COLUMN c2 SET DEFAULT 'new_default'" +== 526 +-- truncate_limit: 100 +insert into def_test default values +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO def_test DEFAULT VALUES" +== 527 +-- truncate_limit: 100 +select * from def_test +-- +TABLE: name="def_test" schema="" table="def_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM def_test" +== 528 +-- truncate_limit: 100 +-- set defaults to an incorrect type: this should fail +alter table def_test alter column c1 set default 'wrong_datatype' +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_test ALTER COLUMN c1 SET DEFAULT 'wrong_datatype'" +== 529 +-- truncate_limit: 100 +alter table def_test alter column c2 set default 20 +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_test ALTER COLUMN c2 SET DEFAULT 20" +== 530 +-- truncate_limit: 100 +-- set defaults on a non-existent column: this should fail +alter table def_test alter column c3 set default 30 +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_test ALTER COLUMN c3 SET DEFAULT 30" +== 531 +-- truncate_limit: 100 +-- set defaults on views: we need to create a view, add a rule +-- to allow insertions into it, and then alter the view to add +-- a default +create view def_view_test as select * from def_test +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +TABLE: name="def_test" schema="" table="def_test" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW def_view_test AS SELECT * FROM def_test" +== 532 +-- truncate_limit: 100 +create rule def_view_test_ins as + on insert to def_view_test + do instead insert into def_test select new.* +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE def_view_test_ins AS ON INSERT TO def_view_test DO INSTEAD INSERT INTO def_test SELEC..." +== 533 +-- truncate_limit: 100 +insert into def_view_test default values +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO def_view_test DEFAULT VALUES" +== 534 +-- truncate_limit: 100 +alter table def_view_test alter column c1 set default 45 +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_view_test ALTER COLUMN c1 SET DEFAULT 45" +== 535 +-- truncate_limit: 100 +insert into def_view_test default values +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO def_view_test DEFAULT VALUES" +== 536 +-- truncate_limit: 100 +alter table def_view_test alter column c2 set default 'view_default' +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE def_view_test ALTER COLUMN c2 SET DEFAULT 'view_default'" +== 537 +-- truncate_limit: 100 +insert into def_view_test default values +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO def_view_test DEFAULT VALUES" +== 538 +-- truncate_limit: 100 +select * from def_view_test +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM def_view_test" +== 539 +-- truncate_limit: 100 +drop rule def_view_test_ins on def_view_test +-- +TABLE: name="def_view_test" schema="" table="def_view_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE def_view_test_ins ON def_view_test" +== 540 +-- truncate_limit: 100 +drop view def_view_test +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW def_view_test" +== 541 +-- truncate_limit: 100 +drop table def_test +-- +TABLE: name="def_test" schema="" table="def_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE def_test" +== 542 +-- truncate_limit: 100 +-- alter table / drop column tests +-- try altering system catalogs, should fail +alter table pg_class drop column relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pg_class DROP relname" +== 543 +-- truncate_limit: 100 +-- try altering non-existent table, should fail +alter table nosuchtable drop column bar +-- +TABLE: name="nosuchtable" schema="" table="nosuchtable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE nosuchtable DROP bar" +== 544 +-- truncate_limit: 100 +-- test dropping columns +create table atacc1 (a int4 not null, b int4, c int4 not null, d int4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (a int4 NOT NULL, b int4, c int4 NOT NULL, d int4)" +== 545 +-- truncate_limit: 100 +insert into atacc1 values (1, 2, 3, 4) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (1, 2, 3, 4)" +== 546 +-- truncate_limit: 100 +alter table atacc1 drop a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP a" +== 547 +-- truncate_limit: 100 +alter table atacc1 drop a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP a" +== 548 +-- truncate_limit: 100 +-- SELECTs +select * from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1" +== 549 +-- truncate_limit: 100 +select * from atacc1 order by a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1 ORDER BY a" +== 550 +-- truncate_limit: 100 +select * from atacc1 order by "........pg.dropped.1........" +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1 ORDER BY \"........pg.dropped.1........\"" +== 551 +-- truncate_limit: 100 +select * from atacc1 group by a +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1 GROUP BY a" +== 552 +-- truncate_limit: 100 +select * from atacc1 group by "........pg.dropped.1........" +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1 GROUP BY \"........pg.dropped.1........\"" +== 553 +-- truncate_limit: 100 +select atacc1.* from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atacc1.* FROM atacc1" +== 554 +-- truncate_limit: 100 +select a from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a FROM atacc1" +== 555 +-- truncate_limit: 100 +select atacc1.a from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atacc1.a FROM atacc1" +== 556 +-- truncate_limit: 100 +select b,c,d from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b, c, d FROM atacc1" +== 557 +-- truncate_limit: 100 +select a,b,c,d from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c, d FROM atacc1" +== 558 +-- truncate_limit: 100 +select * from atacc1 where a = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1 WHERE a = 1" +== 559 +-- truncate_limit: 100 +select "........pg.dropped.1........" from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT \"........pg.dropped.1........\" FROM atacc1" +== 560 +-- truncate_limit: 100 +select atacc1."........pg.dropped.1........" from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atacc1.\"........pg.dropped.1........\" FROM atacc1" +== 561 +-- truncate_limit: 100 +select "........pg.dropped.1........",b,c,d from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT \"........pg.dropped.1........\", b, c, d FROM atacc1" +== 562 +-- truncate_limit: 100 +select * from atacc1 where "........pg.dropped.1........" = 1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +FILTER: schema="" table="" column="........pg.dropped.1........" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1 WHERE \"........pg.dropped.1........\" = 1" +== 563 +-- truncate_limit: 100 +-- UPDATEs +update atacc1 set a = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atacc1 SET a = 3" +== 564 +-- truncate_limit: 100 +update atacc1 set b = 2 where a = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atacc1 SET b = 2 WHERE a = 3" +== 565 +-- truncate_limit: 100 +update atacc1 set "........pg.dropped.1........" = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atacc1 SET \"........pg.dropped.1........\" = 3" +== 566 +-- truncate_limit: 100 +update atacc1 set b = 2 where "........pg.dropped.1........" = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atacc1 SET b = 2 WHERE \"........pg.dropped.1........\" = 3" +== 567 +-- truncate_limit: 100 +-- INSERTs +insert into atacc1 values (10, 11, 12, 13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (10, 11, 12, 13)" +== 568 +-- truncate_limit: 100 +insert into atacc1 values (default, 11, 12, 13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (DEFAULT, 11, 12, 13)" +== 569 +-- truncate_limit: 100 +insert into atacc1 values (11, 12, 13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (11, 12, 13)" +== 570 +-- truncate_limit: 100 +insert into atacc1 (a) values (10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (a) VALUES (10)" +== 571 +-- truncate_limit: 100 +insert into atacc1 (a) values (default) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (a) VALUES (DEFAULT)" +== 572 +-- truncate_limit: 100 +insert into atacc1 (a,b,c,d) values (10,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (a, b, c, d) VALUES (10, 11, 12, 13)" +== 573 +-- truncate_limit: 100 +insert into atacc1 (a,b,c,d) values (default,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (a, b, c, d) VALUES (DEFAULT, 11, 12, 13)" +== 574 +-- truncate_limit: 100 +insert into atacc1 (b,c,d) values (11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (b, c, d) VALUES (11, 12, 13)" +== 575 +-- truncate_limit: 100 +insert into atacc1 ("........pg.dropped.1........") values (10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (\"........pg.dropped.1........\") VALUES (10)" +== 576 +-- truncate_limit: 100 +insert into atacc1 ("........pg.dropped.1........") values (default) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (\"........pg.dropped.1........\") VALUES (DEFAULT)" +== 577 +-- truncate_limit: 100 +insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (\"........pg.dropped.1........\", b, c, d) VALUES (10, 11, 12, 13)" +== 578 +-- truncate_limit: 100 +insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (\"........pg.dropped.1........\", b, c, d) VALUES (DEFAULT, 11, 12, 13)" +== 579 +-- truncate_limit: 100 +-- DELETEs +delete from atacc1 where a = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atacc1 WHERE a = 3" +== 580 +-- truncate_limit: 100 +delete from atacc1 where "........pg.dropped.1........" = 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atacc1 WHERE \"........pg.dropped.1........\" = 3" +== 581 +-- truncate_limit: 100 +delete from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atacc1" +== 582 +-- truncate_limit: 100 +-- try dropping a non-existent column, should fail +alter table atacc1 drop bar +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP bar" +== 583 +-- truncate_limit: 100 +-- try removing an oid column, should succeed (as it's nonexistent) +alter table atacc1 SET WITHOUT OIDS +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 SET WITHOUT OIDS" +== 584 +-- truncate_limit: 100 +-- try adding an oid column, should fail (not supported) +alter table atacc1 SET WITH OIDS +-- +ERROR: syntax error at or near "WITH" +CURSORPOS: 81 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 585 +-- truncate_limit: 100 +-- try dropping the xmin column, should fail +alter table atacc1 drop xmin +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP xmin" +== 586 +-- truncate_limit: 100 +-- try creating a view and altering that, should fail +create view myview as select * from atacc1 +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW myview AS SELECT * FROM atacc1" +== 587 +-- truncate_limit: 100 +select * from myview +-- +TABLE: name="myview" schema="" table="myview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM myview" +== 588 +-- truncate_limit: 100 +alter table myview drop d +-- +TABLE: name="myview" schema="" table="myview" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE myview DROP d" +== 589 +-- truncate_limit: 100 +drop view myview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW myview" +== 590 +-- truncate_limit: 100 +-- test some commands to make sure they fail on the dropped column +analyze atacc1(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE atacc1(a)" +== 591 +-- truncate_limit: 100 +analyze atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE atacc1(\"........pg.dropped.1........\")" +== 592 +-- truncate_limit: 100 +vacuum analyze atacc1(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) atacc1(a)" +== 593 +-- truncate_limit: 100 +vacuum analyze atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) atacc1(\"........pg.dropped.1........\")" +== 594 +-- truncate_limit: 100 +comment on column atacc1.a is 'testing' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN atacc1.a IS 'testing'" +== 595 +-- truncate_limit: 100 +comment on column atacc1."........pg.dropped.1........" is 'testing' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN atacc1.\"........pg.dropped.1........\" IS 'testing'" +== 596 +-- truncate_limit: 100 +alter table atacc1 alter a set storage plain +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN a SET STORAGE plain" +== 597 +-- truncate_limit: 100 +alter table atacc1 alter "........pg.dropped.1........" set storage plain +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN \"........pg.dropped.1........\" SET STORAGE plain" +== 598 +-- truncate_limit: 100 +alter table atacc1 alter a set statistics 0 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN a SET STATISTICS 0" +== 599 +-- truncate_limit: 100 +alter table atacc1 alter "........pg.dropped.1........" set statistics 0 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN \"........pg.dropped.1........\" SET STATISTICS 0" +== 600 +-- truncate_limit: 100 +alter table atacc1 alter a set default 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN a SET DEFAULT 3" +== 601 +-- truncate_limit: 100 +alter table atacc1 alter "........pg.dropped.1........" set default 3 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN \"........pg.dropped.1........\" SET DEFAULT 3" +== 602 +-- truncate_limit: 100 +alter table atacc1 alter a drop default +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN a DROP DEFAULT" +== 603 +-- truncate_limit: 100 +alter table atacc1 alter "........pg.dropped.1........" drop default +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN \"........pg.dropped.1........\" DROP DEFAULT" +== 604 +-- truncate_limit: 100 +alter table atacc1 alter a set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN a SET NOT NULL" +== 605 +-- truncate_limit: 100 +alter table atacc1 alter "........pg.dropped.1........" set not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN \"........pg.dropped.1........\" SET NOT NULL" +== 606 +-- truncate_limit: 100 +alter table atacc1 alter a drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN a DROP NOT NULL" +== 607 +-- truncate_limit: 100 +alter table atacc1 alter "........pg.dropped.1........" drop not null +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ALTER COLUMN \"........pg.dropped.1........\" DROP NOT NULL" +== 608 +-- truncate_limit: 100 +alter table atacc1 rename a to x +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE atacc1 RENAME COLUMN a TO x" +== 609 +-- truncate_limit: 100 +alter table atacc1 rename "........pg.dropped.1........" to x +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE atacc1 RENAME COLUMN \"........pg.dropped.1........\" TO x" +== 610 +-- truncate_limit: 100 +alter table atacc1 add primary key(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD PRIMARY KEY (a)" +== 611 +-- truncate_limit: 100 +alter table atacc1 add primary key("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD PRIMARY KEY (\"........pg.dropped.1........\")" +== 612 +-- truncate_limit: 100 +alter table atacc1 add unique(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD UNIQUE (a)" +== 613 +-- truncate_limit: 100 +alter table atacc1 add unique("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD UNIQUE (\"........pg.dropped.1........\")" +== 614 +-- truncate_limit: 100 +alter table atacc1 add check (a > 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CHECK (a > 3)" +== 615 +-- truncate_limit: 100 +alter table atacc1 add check ("........pg.dropped.1........" > 3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD CHECK (\"........pg.dropped.1........\" > 3)" +== 616 +-- truncate_limit: 100 +create table atacc2 (id int4 unique) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc2 (id int4 UNIQUE)" +== 617 +-- truncate_limit: 100 +alter table atacc1 add foreign key (a) references atacc2(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD FOREIGN KEY (a) REFERENCES atacc2 (id)" +== 618 +-- truncate_limit: 100 +alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD FOREIGN KEY (\"........pg.dropped.1........\") REFERENCES atacc2 (id)" +== 619 +-- truncate_limit: 100 +alter table atacc2 add foreign key (id) references atacc1(a) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc2 ADD FOREIGN KEY (id) REFERENCES atacc1 (a)" +== 620 +-- truncate_limit: 100 +alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc2 ADD FOREIGN KEY (id) REFERENCES atacc1 (\"........pg.dropped.1........\")" +== 621 +-- truncate_limit: 100 +drop table atacc2 +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc2" +== 622 +-- truncate_limit: 100 +create index "testing_idx" on atacc1(a) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX testing_idx ON atacc1 USING btree (a)" +== 623 +-- truncate_limit: 100 +create index "testing_idx" on atacc1("........pg.dropped.1........") +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX testing_idx ON atacc1 USING btree (\"........pg.dropped.1........\")" +== 624 +-- truncate_limit: 100 +-- test create as and select into +insert into atacc1 values (21, 22, 23) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 VALUES (21, 22, 23)" +== 625 +-- truncate_limit: 100 +create table attest1 as select * from atacc1 +-- +TABLE: name="attest1" schema="" table="attest1" ctx=DDL +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE attest1 AS SELECT * FROM atacc1" +== 626 +-- truncate_limit: 100 +select * from attest1 +-- +TABLE: name="attest1" schema="" table="attest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attest1" +== 627 +-- truncate_limit: 100 +drop table attest1 +-- +TABLE: name="attest1" schema="" table="attest1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attest1" +== 628 +-- truncate_limit: 100 +select * into attest2 from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +TABLE: name="attest2" schema="" table="attest2" ctx=DDL +STMT: SelectStmt +TRUNCATED: "SELECT * INTO attest2 FROM atacc1" +== 629 +-- truncate_limit: 100 +select * from attest2 +-- +TABLE: name="attest2" schema="" table="attest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attest2" +== 630 +-- truncate_limit: 100 +drop table attest2 +-- +TABLE: name="attest2" schema="" table="attest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attest2" +== 631 +-- truncate_limit: 100 +-- try dropping all columns +alter table atacc1 drop c +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP c" +== 632 +-- truncate_limit: 100 +alter table atacc1 drop d +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP d" +== 633 +-- truncate_limit: 100 +alter table atacc1 drop b +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP b" +== 634 +-- truncate_limit: 100 +select * from atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atacc1" +== 635 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 636 +-- truncate_limit: 100 +-- test constraint error reporting in presence of dropped columns +create table atacc1 (id serial primary key, value int check (value < 10)) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (id serial PRIMARY KEY, value int CHECK (value < 10))" +== 637 +-- truncate_limit: 100 +insert into atacc1(value) values (100) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (value) VALUES (100)" +== 638 +-- truncate_limit: 100 +alter table atacc1 drop column value +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 DROP value" +== 639 +-- truncate_limit: 100 +alter table atacc1 add column value int check (value < 10) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atacc1 ADD COLUMN value int CHECK (value < 10)" +== 640 +-- truncate_limit: 100 +insert into atacc1(value) values (100) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (value) VALUES (100)" +== 641 +-- truncate_limit: 100 +insert into atacc1(id, value) values (null, 0) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (id, value) VALUES (NULL, 0)" +== 642 +-- truncate_limit: 100 +drop table atacc1 +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1" +== 643 +-- truncate_limit: 100 +-- test inheritance +create table parent (a int, b int, c int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a int, b int, c int)" +== 644 +-- truncate_limit: 100 +insert into parent values (1, 2, 3) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (1, 2, 3)" +== 645 +-- truncate_limit: 100 +alter table parent drop a +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent DROP a" +== 646 +-- truncate_limit: 100 +create table child (d varchar(255)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child (d varchar(255)) INHERITS (parent)" +== 647 +-- truncate_limit: 100 +insert into child values (12, 13, 'testing') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child VALUES (12, 13, 'testing')" +== 648 +-- truncate_limit: 100 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 649 +-- truncate_limit: 100 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM child" +== 650 +-- truncate_limit: 100 +alter table parent drop c +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent DROP c" +== 651 +-- truncate_limit: 100 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 652 +-- truncate_limit: 100 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM child" +== 653 +-- truncate_limit: 100 +drop table child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child" +== 654 +-- truncate_limit: 100 +drop table parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent" +== 655 +-- truncate_limit: 100 +-- check error cases for inheritance column merging +create table parent (a float8, b numeric(10,4), c text collate "C") +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a float8, b numeric(10, 4), c text COLLATE \"C\")" +== 656 +-- truncate_limit: 100 +create table child (a float4) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child (a float4) INHERITS (parent)" +== 657 +-- truncate_limit: 100 +-- fail +create table child (b decimal(10,7)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child (b numeric(10, 7)) INHERITS (parent)" +== 658 +-- truncate_limit: 100 +-- fail +create table child (c text collate "POSIX") inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child (c text COLLATE \"POSIX\") INHERITS (parent)" +== 659 +-- truncate_limit: 100 +-- fail +create table child (a double precision, b decimal(10,4)) inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child (a double precision, b numeric(10, 4)) INHERITS (parent)" +== 660 +-- truncate_limit: 100 +drop table child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child" +== 661 +-- truncate_limit: 100 +drop table parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent" +== 662 +-- truncate_limit: 100 +-- test copy in/out +create table attest (a int4, b int4, c int4) +-- +TABLE: name="attest" schema="" table="attest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attest (a int4, b int4, c int4)" +== 663 +-- truncate_limit: 100 +insert into attest values (1,2,3) +-- +TABLE: name="attest" schema="" table="attest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attest VALUES (1, 2, 3)" +== 664 +-- truncate_limit: 100 +alter table attest drop a +-- +TABLE: name="attest" schema="" table="attest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attest DROP a" +== 665 +-- truncate_limit: 100 +copy attest to stdout +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY attest TO STDOUT" +== 666 +-- truncate_limit: 100 +copy attest(a) to stdout +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY attest(a) TO STDOUT" +== 667 +-- truncate_limit: 100 +copy attest("........pg.dropped.1........") to stdout +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY attest(\"........pg.dropped.1........\") TO STDOUT" +== 668 +-- truncate_limit: 100 +copy attest from stdin +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY attest FROM STDIN" +== 669 +-- truncate_limit: 100 +select * from attest +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attest" +== 670 +-- truncate_limit: 100 +copy attest from stdin +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY attest FROM STDIN" +== 671 +-- truncate_limit: 100 +select * from attest +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attest" +== 672 +-- truncate_limit: 100 +copy attest(a) from stdin +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY attest(a) FROM STDIN" +== 673 +-- truncate_limit: 100 +select * from attest +-- +TABLE: name="attest" schema="" table="attest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM attest" +== 674 +-- truncate_limit: 100 +drop table attest +-- +TABLE: name="attest" schema="" table="attest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attest" +== 675 +-- truncate_limit: 100 +-- test inheritance + +create table dropColumn (a int, b int, e int) +-- +TABLE: name="dropcolumn" schema="" table="dropcolumn" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dropcolumn (a int, b int, e int)" +== 676 +-- truncate_limit: 100 +create table dropColumnChild (c int) inherits (dropColumn) +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dropcolumnchild (c int) INHERITS (dropcolumn)" +== 677 +-- truncate_limit: 100 +create table dropColumnAnother (d int) inherits (dropColumnChild) +-- +TABLE: name="dropcolumnanother" schema="" table="dropcolumnanother" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dropcolumnanother (d int) INHERITS (dropcolumnchild)" +== 678 +-- truncate_limit: 100 +-- these two should fail +alter table dropColumnchild drop column a +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE dropcolumnchild DROP a" +== 679 +-- truncate_limit: 100 +alter table only dropColumnChild drop column b +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY dropcolumnchild DROP b" +== 680 +-- truncate_limit: 100 +-- these three should work +alter table only dropColumn drop column e +-- +TABLE: name="dropcolumn" schema="" table="dropcolumn" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY dropcolumn DROP e" +== 681 +-- truncate_limit: 100 +alter table dropColumnChild drop column c +-- +TABLE: name="dropcolumnchild" schema="" table="dropcolumnchild" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE dropcolumnchild DROP c" +== 682 +-- truncate_limit: 100 +alter table dropColumn drop column a +-- +TABLE: name="dropcolumn" schema="" table="dropcolumn" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE dropcolumn DROP a" +== 683 +-- truncate_limit: 100 +create table renameColumn (a int) +-- +TABLE: name="renamecolumn" schema="" table="renamecolumn" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE renamecolumn (a int)" +== 684 +-- truncate_limit: 100 +create table renameColumnChild (b int) inherits (renameColumn) +-- +TABLE: name="renamecolumnchild" schema="" table="renamecolumnchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE renamecolumnchild (b int) INHERITS (renamecolumn)" +== 685 +-- truncate_limit: 100 +create table renameColumnAnother (c int) inherits (renameColumnChild) +-- +TABLE: name="renamecolumnanother" schema="" table="renamecolumnanother" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE renamecolumnanother (c int) INHERITS (renamecolumnchild)" +== 686 +-- truncate_limit: 100 +-- these three should fail +alter table renameColumnChild rename column a to d +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE renamecolumnchild RENAME COLUMN a TO d" +== 687 +-- truncate_limit: 100 +alter table only renameColumnChild rename column a to d +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE ONLY renamecolumnchild RENAME COLUMN a TO d" +== 688 +-- truncate_limit: 100 +alter table only renameColumn rename column a to d +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE ONLY renamecolumn RENAME COLUMN a TO d" +== 689 +-- truncate_limit: 100 +-- these should work +alter table renameColumn rename column a to d +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE renamecolumn RENAME COLUMN a TO d" +== 690 +-- truncate_limit: 100 +alter table renameColumnChild rename column b to a +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE renamecolumnchild RENAME COLUMN b TO a" +== 691 +-- truncate_limit: 100 +-- these should work +alter table if exists doesnt_exist_tab rename column a to d +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE IF EXISTS doesnt_exist_tab RENAME COLUMN a TO d" +== 692 +-- truncate_limit: 100 +alter table if exists doesnt_exist_tab rename column b to a +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE IF EXISTS doesnt_exist_tab RENAME COLUMN b TO a" +== 693 +-- truncate_limit: 100 +-- this should work +alter table renameColumn add column w int +-- +TABLE: name="renamecolumn" schema="" table="renamecolumn" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE renamecolumn ADD COLUMN w int" +== 694 +-- truncate_limit: 100 +-- this should fail +alter table only renameColumn add column x int +-- +TABLE: name="renamecolumn" schema="" table="renamecolumn" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY renamecolumn ADD COLUMN x int" +== 695 +-- truncate_limit: 100 +-- Test corner cases in dropping of inherited columns + +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int, f2 int)" +== 696 +-- truncate_limit: 100 +create table c1 (f1 int not null) inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 (f1 int NOT NULL) INHERITS (p1)" +== 697 +-- truncate_limit: 100 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP f1" +== 698 +-- truncate_limit: 100 +-- should work +alter table p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 DROP f1" +== 699 +-- truncate_limit: 100 +-- c1.f1 is still there, but no longer inherited +select f1 from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM c1" +== 700 +-- truncate_limit: 100 +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP f1" +== 701 +-- truncate_limit: 100 +select f1 from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM c1" +== 702 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 703 +-- truncate_limit: 100 +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int, f2 int)" +== 704 +-- truncate_limit: 100 +create table c1 () inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 () INHERITS (p1)" +== 705 +-- truncate_limit: 100 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP f1" +== 706 +-- truncate_limit: 100 +alter table p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 DROP f1" +== 707 +-- truncate_limit: 100 +-- c1.f1 is dropped now, since there is no local definition for it +select f1 from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM c1" +== 708 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 709 +-- truncate_limit: 100 +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int, f2 int)" +== 710 +-- truncate_limit: 100 +create table c1 () inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 () INHERITS (p1)" +== 711 +-- truncate_limit: 100 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP f1" +== 712 +-- truncate_limit: 100 +alter table only p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY p1 DROP f1" +== 713 +-- truncate_limit: 100 +-- c1.f1 is NOT dropped, but must now be considered non-inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP f1" +== 714 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 715 +-- truncate_limit: 100 +create table p1 (f1 int, f2 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int, f2 int)" +== 716 +-- truncate_limit: 100 +create table c1 (f1 int not null) inherits(p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 (f1 int NOT NULL) INHERITS (p1)" +== 717 +-- truncate_limit: 100 +-- should be rejected since c1.f1 is inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP f1" +== 718 +-- truncate_limit: 100 +alter table only p1 drop column f1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY p1 DROP f1" +== 719 +-- truncate_limit: 100 +-- c1.f1 is still there, but no longer inherited +alter table c1 drop column f1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP f1" +== 720 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 721 +-- truncate_limit: 100 +create table p1(id int, name text) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (id int, name text)" +== 722 +-- truncate_limit: 100 +create table p2(id2 int, name text, height int) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p2 (id2 int, name text, height int)" +== 723 +-- truncate_limit: 100 +create table c1(age int) inherits(p1,p2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 (age int) INHERITS (p1, p2)" +== 724 +-- truncate_limit: 100 +create table gc1() inherits (c1) +-- +TABLE: name="gc1" schema="" table="gc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gc1 () INHERITS (c1)" +== 725 +-- truncate_limit: 100 +select relname, attname, attinhcount, attislocal +from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid) +where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped +order by relname, attnum +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attisdropped" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class JOIN pg_attribute ON pg_class.oid = pg_attribute.attrelid WHERE ... ORDE..." +== 726 +-- truncate_limit: 100 +-- should work +alter table only p1 drop column name +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY p1 DROP name" +== 727 +-- truncate_limit: 100 +-- should work. Now c1.name is local and inhcount is 0. +alter table p2 drop column name +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p2 DROP name" +== 728 +-- truncate_limit: 100 +-- should be rejected since its inherited +alter table gc1 drop column name +-- +TABLE: name="gc1" schema="" table="gc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gc1 DROP name" +== 729 +-- truncate_limit: 100 +-- should work, and drop gc1.name along +alter table c1 drop column name +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c1 DROP name" +== 730 +-- truncate_limit: 100 +-- should fail: column does not exist +alter table gc1 drop column name +-- +TABLE: name="gc1" schema="" table="gc1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gc1 DROP name" +== 731 +-- truncate_limit: 100 +-- should work and drop the attribute in all tables +alter table p2 drop column height +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p2 DROP height" +== 732 +-- truncate_limit: 100 +-- IF EXISTS test +create table dropColumnExists () +-- +TABLE: name="dropcolumnexists" schema="" table="dropcolumnexists" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dropcolumnexists ()" +== 733 +-- truncate_limit: 100 +alter table dropColumnExists drop column non_existing +-- +TABLE: name="dropcolumnexists" schema="" table="dropcolumnexists" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE dropcolumnexists DROP non_existing" +== 734 +-- truncate_limit: 100 +--fail +alter table dropColumnExists drop column if exists non_existing +-- +TABLE: name="dropcolumnexists" schema="" table="dropcolumnexists" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE dropcolumnexists DROP IF EXISTS non_existing" +== 735 +-- truncate_limit: 100 +--succeed + +select relname, attname, attinhcount, attislocal +from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid) +where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped +order by relname, attnum +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attisdropped" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class JOIN pg_attribute ON pg_class.oid = pg_attribute.attrelid WHERE ... ORDE..." +== 736 +-- truncate_limit: 100 +drop table p1, p2 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1, p2 CASCADE" +== 737 +-- truncate_limit: 100 +-- test attinhcount tracking with merged columns + +create table depth0() +-- +TABLE: name="depth0" schema="" table="depth0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE depth0 ()" +== 738 +-- truncate_limit: 100 +create table depth1(c text) inherits (depth0) +-- +TABLE: name="depth1" schema="" table="depth1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE depth1 (c text) INHERITS (depth0)" +== 739 +-- truncate_limit: 100 +create table depth2() inherits (depth1) +-- +TABLE: name="depth2" schema="" table="depth2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE depth2 () INHERITS (depth1)" +== 740 +-- truncate_limit: 100 +alter table depth0 add c text +-- +TABLE: name="depth0" schema="" table="depth0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE depth0 ADD COLUMN c text" +== 741 +-- truncate_limit: 100 +select attrelid::regclass, attname, attinhcount, attislocal +from pg_attribute +where attnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2') +order by attrelid::regclass::text, attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE ... ORDER BY attrelid::regclass::text, attnum" +== 742 +-- truncate_limit: 100 +-- test renumbering of child-table columns in inherited operations + +create table p1 (f1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int)" +== 743 +-- truncate_limit: 100 +create table c1 (f2 text, f3 int) inherits (p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 (f2 text, f3 int) INHERITS (p1)" +== 744 +-- truncate_limit: 100 +alter table p1 add column a1 int check (a1 > 0) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 ADD COLUMN a1 int CHECK (a1 > 0)" +== 745 +-- truncate_limit: 100 +alter table p1 add column f2 text +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 ADD COLUMN f2 text" +== 746 +-- truncate_limit: 100 +insert into p1 values (1,2,'abc') +-- +TABLE: name="p1" schema="" table="p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO p1 VALUES (1, 2, 'abc')" +== 747 +-- truncate_limit: 100 +insert into c1 values(11,'xyz',33,0) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c1 VALUES (11, 'xyz', 33, 0)" +== 748 +-- truncate_limit: 100 +-- should fail +insert into c1 values(11,'xyz',33,22) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c1 VALUES (11, 'xyz', 33, 22)" +== 749 +-- truncate_limit: 100 +select * from p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM p1" +== 750 +-- truncate_limit: 100 +update p1 set a1 = a1 + 1, f2 = upper(f2) +-- +TABLE: name="p1" schema="" table="p1" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE p1 SET a1 = a1 + 1, f2 = upper(f2)" +== 751 +-- truncate_limit: 100 +select * from p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM p1" +== 752 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 753 +-- truncate_limit: 100 +-- test that operations with a dropped column do not try to reference +-- its datatype + +create domain mytype as text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN mytype AS text" +== 754 +-- truncate_limit: 100 +create temp table foo (f1 text, f2 mytype, f3 text) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (f1 text, f2 mytype, f3 text)" +== 755 +-- truncate_limit: 100 +insert into foo values('bb','cc','dd') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES ('bb', 'cc', 'dd')" +== 756 +-- truncate_limit: 100 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 757 +-- truncate_limit: 100 +drop domain mytype cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN mytype CASCADE" +== 758 +-- truncate_limit: 100 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 759 +-- truncate_limit: 100 +insert into foo values('qq','rr') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES ('qq', 'rr')" +== 760 +-- truncate_limit: 100 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 761 +-- truncate_limit: 100 +update foo set f3 = 'zz' +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f3 = 'zz'" +== 762 +-- truncate_limit: 100 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 763 +-- truncate_limit: 100 +select f3,max(f1) from foo group by f3 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, max(f1) FROM foo GROUP BY f3" +== 764 +-- truncate_limit: 100 +-- Simple tests for alter table column type +alter table foo alter f1 TYPE integer +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE foo ALTER COLUMN f1 TYPE int" +== 765 +-- truncate_limit: 100 +-- fails +alter table foo alter f1 TYPE varchar(10) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE foo ALTER COLUMN f1 TYPE varchar(10)" +== 766 +-- truncate_limit: 100 +create table anothertab (atcol1 serial8, atcol2 boolean, + constraint anothertab_chk check (atcol1 <= 3)) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE anothertab (atcol1 serial8, atcol2 boolean, CONSTRAINT anothertab_chk CHECK (atcol1 ..." +== 767 +-- truncate_limit: 100 +insert into anothertab (atcol1, atcol2) values (default, true) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO anothertab (atcol1, atcol2) VALUES (DEFAULT, true)" +== 768 +-- truncate_limit: 100 +insert into anothertab (atcol1, atcol2) values (default, false) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO anothertab (atcol1, atcol2) VALUES (DEFAULT, false)" +== 769 +-- truncate_limit: 100 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM anothertab" +== 770 +-- truncate_limit: 100 +alter table anothertab alter column atcol1 type boolean +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol1 TYPE boolean" +== 771 +-- truncate_limit: 100 +-- fails +alter table anothertab alter column atcol1 type boolean using atcol1::int +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol1 TYPE boolean USING atcol1::int" +== 772 +-- truncate_limit: 100 +-- fails +alter table anothertab alter column atcol1 type integer +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol1 TYPE int" +== 773 +-- truncate_limit: 100 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM anothertab" +== 774 +-- truncate_limit: 100 +insert into anothertab (atcol1, atcol2) values (45, null) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO anothertab (atcol1, atcol2) VALUES (45, NULL)" +== 775 +-- truncate_limit: 100 +-- fails +insert into anothertab (atcol1, atcol2) values (default, null) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO anothertab (atcol1, atcol2) VALUES (DEFAULT, NULL)" +== 776 +-- truncate_limit: 100 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM anothertab" +== 777 +-- truncate_limit: 100 +alter table anothertab alter column atcol2 type text + using case when atcol2 is true then 'IT WAS TRUE' + when atcol2 is false then 'IT WAS FALSE' + else 'IT WAS NULL!' end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol2 TYPE text USING CASE WHEN atcol2 IS TRUE THEN 'IT WAS ..." +== 778 +-- truncate_limit: 100 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM anothertab" +== 779 +-- truncate_limit: 100 +alter table anothertab alter column atcol1 type boolean + using case when atcol1 % 2 = 0 then true else false end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol1 TYPE boolean USING CASE WHEN (atcol1 % 2) = 0 THEN tru..." +== 780 +-- truncate_limit: 100 +-- fails +alter table anothertab alter column atcol1 drop default +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol1 DROP DEFAULT" +== 781 +-- truncate_limit: 100 +alter table anothertab alter column atcol1 type boolean + using case when atcol1 % 2 = 0 then true else false end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol1 TYPE boolean USING CASE WHEN (atcol1 % 2) = 0 THEN tru..." +== 782 +-- truncate_limit: 100 +-- fails +alter table anothertab drop constraint anothertab_chk +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab DROP CONSTRAINT anothertab_chk" +== 783 +-- truncate_limit: 100 +alter table anothertab drop constraint anothertab_chk +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab DROP CONSTRAINT anothertab_chk" +== 784 +-- truncate_limit: 100 +-- fails +alter table anothertab drop constraint IF EXISTS anothertab_chk +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab DROP CONSTRAINT IF EXISTS anothertab_chk" +== 785 +-- truncate_limit: 100 +-- succeeds + +alter table anothertab alter column atcol1 type boolean + using case when atcol1 % 2 = 0 then true else false end +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN atcol1 TYPE boolean USING CASE WHEN (atcol1 % 2) = 0 THEN tru..." +== 786 +-- truncate_limit: 100 +select * from anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM anothertab" +== 787 +-- truncate_limit: 100 +drop table anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE anothertab" +== 788 +-- truncate_limit: 100 +-- Test index handling in alter table column type (cf. bugs #15835, #15865) +create table anothertab(f1 int primary key, f2 int unique, + f3 int, f4 int, f5 int) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE anothertab (f1 int PRIMARY KEY, f2 int UNIQUE, f3 int, f4 int, f5 int)" +== 789 +-- truncate_limit: 100 +alter table anothertab + add exclude using btree (f3 with =) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ADD EXCLUDE (f3 WITH =)" +== 790 +-- truncate_limit: 100 +alter table anothertab + add exclude using btree (f4 with =) where (f4 is not null) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ADD EXCLUDE (f4 WITH =) WHERE (f4 IS NOT NULL)" +== 791 +-- truncate_limit: 100 +alter table anothertab + add exclude using btree (f4 with =) where (f5 > 0) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ADD EXCLUDE (f4 WITH =) WHERE (f5 > 0)" +== 792 +-- truncate_limit: 100 +alter table anothertab + add unique(f1,f4) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ADD UNIQUE (f1, f4)" +== 793 +-- truncate_limit: 100 +create index on anothertab(f2,f3) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON anothertab USING btree (f2, f3)" +== 794 +-- truncate_limit: 100 +create unique index on anothertab(f4) +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON anothertab USING btree (f4)" +== 795 +-- truncate_limit: 100 +alter table anothertab alter column f1 type bigint +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN f1 TYPE bigint" +== 796 +-- truncate_limit: 100 +alter table anothertab + alter column f2 type bigint, + alter column f3 type bigint, + alter column f4 type bigint +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN f2 TYPE bigint, ALTER COLUMN f3 TYPE bigint, ALTER COLUMN f4 ..." +== 797 +-- truncate_limit: 100 +alter table anothertab alter column f5 type bigint +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE anothertab ALTER COLUMN f5 TYPE bigint" +== 798 +-- truncate_limit: 100 +drop table anothertab +-- +TABLE: name="anothertab" schema="" table="anothertab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE anothertab" +== 799 +-- truncate_limit: 100 +-- test that USING expressions are parsed before column alter type / drop steps +create table another (f1 int, f2 text, f3 text) +-- +TABLE: name="another" schema="" table="another" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE another (f1 int, f2 text, f3 text)" +== 800 +-- truncate_limit: 100 +insert into another values(1, 'one', 'uno') +-- +TABLE: name="another" schema="" table="another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO another VALUES (1, 'one', 'uno')" +== 801 +-- truncate_limit: 100 +insert into another values(2, 'two', 'due') +-- +TABLE: name="another" schema="" table="another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO another VALUES (2, 'two', 'due')" +== 802 +-- truncate_limit: 100 +insert into another values(3, 'three', 'tre') +-- +TABLE: name="another" schema="" table="another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO another VALUES (3, 'three', 'tre')" +== 803 +-- truncate_limit: 100 +select * from another +-- +TABLE: name="another" schema="" table="another" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM another" +== 804 +-- truncate_limit: 100 +alter table another + alter f1 type text using f2 || ' and ' || f3 || ' more', + alter f2 type bigint using f1 * 10, + drop column f3 +-- +TABLE: name="another" schema="" table="another" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE another ALTER COLUMN f1 TYPE text USING ((f2 || ' and ') || f3) || ' more', ALTER COL..." +== 805 +-- truncate_limit: 100 +select * from another +-- +TABLE: name="another" schema="" table="another" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM another" +== 806 +-- truncate_limit: 100 +drop table another +-- +TABLE: name="another" schema="" table="another" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE another" +== 807 +-- truncate_limit: 100 +-- Create an index that skips WAL, then perform a SET DATA TYPE that skips +-- rewriting the index. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 808 +-- truncate_limit: 100 +create table skip_wal_skip_rewrite_index (c varchar(10) primary key) +-- +TABLE: name="skip_wal_skip_rewrite_index" schema="" table="skip_wal_skip_rewrite_index" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE skip_wal_skip_rewrite_index (c varchar(10) PRIMARY KEY)" +== 809 +-- truncate_limit: 100 +alter table skip_wal_skip_rewrite_index alter c type varchar(20) +-- +TABLE: name="skip_wal_skip_rewrite_index" schema="" table="skip_wal_skip_rewrite_index" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE skip_wal_skip_rewrite_index ALTER COLUMN c TYPE varchar(20)" +== 810 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 811 +-- truncate_limit: 100 +-- We disallow changing table's row type if it's used for storage +create table at_tab1 (a int, b text) +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_tab1 (a int, b text)" +== 812 +-- truncate_limit: 100 +create table at_tab2 (x int, y at_tab1) +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_tab2 (x int, y at_tab1)" +== 813 +-- truncate_limit: 100 +alter table at_tab1 alter column b type varchar +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE at_tab1 ALTER COLUMN b TYPE varchar" +== 814 +-- truncate_limit: 100 +-- fails +drop table at_tab2 +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE at_tab2" +== 815 +-- truncate_limit: 100 +-- Use of row type in an expression is defended differently +create table at_tab2 (x int, y text, check((x,y)::at_tab1 = (1,'42')::at_tab1)) +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_tab2 (x int, y text, CHECK ((x, y)::at_tab1 = (1, '42')::at_tab1))" +== 816 +-- truncate_limit: 100 +alter table at_tab1 alter column b type varchar +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE at_tab1 ALTER COLUMN b TYPE varchar" +== 817 +-- truncate_limit: 100 +-- allowed, but ... +insert into at_tab2 values(1,'42') +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO at_tab2 VALUES (1, '42')" +== 818 +-- truncate_limit: 100 +-- ... this will fail +drop table at_tab1, at_tab2 +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE at_tab1, at_tab2" +== 819 +-- truncate_limit: 100 +-- Check it for a partitioned table, too +create table at_tab1 (a int, b text) partition by list(a) +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_tab1 (a int, b text) PARTITION BY LIST (a)" +== 820 +-- truncate_limit: 100 +create table at_tab2 (x int, y at_tab1) +-- +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_tab2 (x int, y at_tab1)" +== 821 +-- truncate_limit: 100 +alter table at_tab1 alter column b type varchar +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE at_tab1 ALTER COLUMN b TYPE varchar" +== 822 +-- truncate_limit: 100 +-- fails +drop table at_tab1, at_tab2 +-- +TABLE: name="at_tab1" schema="" table="at_tab1" ctx=DDL +TABLE: name="at_tab2" schema="" table="at_tab2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE at_tab1, at_tab2" +== 823 +-- truncate_limit: 100 +-- Alter column type that's part of a partitioned index +create table at_partitioned (a int, b text) partition by range (a) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_partitioned (a int, b text) PARTITION BY RANGE (a)" +== 824 +-- truncate_limit: 100 +create table at_part_1 partition of at_partitioned for values from (0) to (1000) +-- +TABLE: name="at_part_1" schema="" table="at_part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_part_1 PARTITION OF at_partitioned FOR VALUES FROM (0) TO (1000)" +== 825 +-- truncate_limit: 100 +insert into at_partitioned values (512, '0.123') +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO at_partitioned VALUES (512, '0.123')" +== 826 +-- truncate_limit: 100 +create table at_part_2 (b text, a int) +-- +TABLE: name="at_part_2" schema="" table="at_part_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_part_2 (b text, a int)" +== 827 +-- truncate_limit: 100 +insert into at_part_2 values ('1.234', 1024) +-- +TABLE: name="at_part_2" schema="" table="at_part_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO at_part_2 VALUES ('1.234', 1024)" +== 828 +-- truncate_limit: 100 +create index on at_partitioned (b) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON at_partitioned USING btree (b)" +== 829 +-- truncate_limit: 100 +create index on at_partitioned (a) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON at_partitioned USING btree (a)" +== 830 +-- truncate_limit: 100 +alter table at_partitioned attach partition at_part_2 for values from (1000) to (2000) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE at_partitioned ATTACH PARTITION at_part_2 FOR VALUES FROM (1000) TO (2000)" +== 831 +-- truncate_limit: 100 +alter table at_partitioned alter column b type numeric using b::numeric +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE at_partitioned ALTER COLUMN b TYPE numeric USING b::numeric" +== 832 +-- truncate_limit: 100 +drop table at_partitioned +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE at_partitioned" +== 833 +-- truncate_limit: 100 +-- Alter column type when no table rewrite is required +-- Also check that comments are preserved +create table at_partitioned(id int, name varchar(64), unique (id, name)) + partition by hash(id) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_partitioned (id int, name varchar(64), UNIQUE (id, name)) PARTITION BY HASH (id)" +== 834 +-- truncate_limit: 100 +comment on constraint at_partitioned_id_name_key on at_partitioned is 'parent constraint' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT at_partitioned_id_name_key ON at_partitioned IS 'parent constraint'" +== 835 +-- truncate_limit: 100 +comment on index at_partitioned_id_name_key is 'parent index' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX at_partitioned_id_name_key IS 'parent index'" +== 836 +-- truncate_limit: 100 +create table at_partitioned_0 partition of at_partitioned + for values with (modulus 2, remainder 0) +-- +TABLE: name="at_partitioned_0" schema="" table="at_partitioned_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_partitioned_0 PARTITION OF at_partitioned FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 837 +-- truncate_limit: 100 +comment on constraint at_partitioned_0_id_name_key on at_partitioned_0 is 'child 0 constraint' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT at_partitioned_0_id_name_key ON at_partitioned_0 IS 'child 0 constraint'" +== 838 +-- truncate_limit: 100 +comment on index at_partitioned_0_id_name_key is 'child 0 index' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX at_partitioned_0_id_name_key IS 'child 0 index'" +== 839 +-- truncate_limit: 100 +create table at_partitioned_1 partition of at_partitioned + for values with (modulus 2, remainder 1) +-- +TABLE: name="at_partitioned_1" schema="" table="at_partitioned_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_partitioned_1 PARTITION OF at_partitioned FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 840 +-- truncate_limit: 100 +comment on constraint at_partitioned_1_id_name_key on at_partitioned_1 is 'child 1 constraint' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT at_partitioned_1_id_name_key ON at_partitioned_1 IS 'child 1 constraint'" +== 841 +-- truncate_limit: 100 +comment on index at_partitioned_1_id_name_key is 'child 1 index' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX at_partitioned_1_id_name_key IS 'child 1 index'" +== 842 +-- truncate_limit: 100 +insert into at_partitioned values(1, 'foo') +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO at_partitioned VALUES (1, 'foo')" +== 843 +-- truncate_limit: 100 +insert into at_partitioned values(3, 'bar') +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO at_partitioned VALUES (3, 'bar')" +== 844 +-- truncate_limit: 100 +create temp table old_oids as + select relname, oid as oldoid, relfilenode as oldfilenode + from pg_class where relname like 'at_partitioned%' +-- +TABLE: name="old_oids" schema="" table="old_oids" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE old_oids AS SELECT relname, oid AS oldoid, relfilenode AS oldfilenode FROM..." +== 845 +-- truncate_limit: 100 +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="old_oids" schema="" table="old_oids" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c LEFT JOIN old_oids USING (relname) WHERE ... ORDER BY relname" +== 846 +-- truncate_limit: 100 +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conname LIKE 'at_partitioned%' ORDER BY conname" +== 847 +-- truncate_limit: 100 +alter table at_partitioned alter column name type varchar(127) +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE at_partitioned ALTER COLUMN name TYPE varchar(127)" +== 848 +-- truncate_limit: 100 +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="old_oids" schema="" table="old_oids" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c LEFT JOIN old_oids USING (relname) WHERE ... ORDER BY relname" +== 849 +-- truncate_limit: 100 +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conname LIKE 'at_partitioned%' ORDER BY conname" +== 850 +-- truncate_limit: 100 +-- Don't remove this DROP, it exposes bug #15672 +drop table at_partitioned +-- +TABLE: name="at_partitioned" schema="" table="at_partitioned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE at_partitioned" +== 851 +-- truncate_limit: 100 +-- disallow recursive containment of row types +create temp table recur1 (f1 int) +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE recur1 (f1 int)" +== 852 +-- truncate_limit: 100 +alter table recur1 add column f2 recur1 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE recur1 ADD COLUMN f2 recur1" +== 853 +-- truncate_limit: 100 +-- fails +alter table recur1 add column f2 recur1[] +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE recur1 ADD COLUMN f2 recur1[]" +== 854 +-- truncate_limit: 100 +-- fails +create domain array_of_recur1 as recur1[] +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN array_of_recur1 AS recur1[]" +== 855 +-- truncate_limit: 100 +alter table recur1 add column f2 array_of_recur1 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE recur1 ADD COLUMN f2 array_of_recur1" +== 856 +-- truncate_limit: 100 +-- fails +create temp table recur2 (f1 int, f2 recur1) +-- +TABLE: name="recur2" schema="" table="recur2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE recur2 (f1 int, f2 recur1)" +== 857 +-- truncate_limit: 100 +alter table recur1 add column f2 recur2 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE recur1 ADD COLUMN f2 recur2" +== 858 +-- truncate_limit: 100 +-- fails +alter table recur1 add column f2 int +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE recur1 ADD COLUMN f2 int" +== 859 +-- truncate_limit: 100 +alter table recur1 alter column f2 type recur2 +-- +TABLE: name="recur1" schema="" table="recur1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE recur1 ALTER COLUMN f2 TYPE recur2" +== 860 +-- truncate_limit: 100 +-- fails + +-- SET STORAGE may need to add a TOAST table +create table test_storage (a text, c text storage plain) +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_storage (a text, c text STORAGE plain)" +== 861 +-- truncate_limit: 100 +select reltoastrelid <> 0 as has_toast_table + from pg_class where oid = 'test_storage'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltoastrelid <> 0 AS has_toast_table FROM pg_class WHERE oid = 'test_storage'::regclass" +== 862 +-- truncate_limit: 100 +alter table test_storage alter a set storage plain +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_storage ALTER COLUMN a SET STORAGE plain" +== 863 +-- truncate_limit: 100 +-- rewrite table to remove its TOAST table; need a non-constant column default +alter table test_storage add b int default random()::int +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_storage ADD COLUMN b int DEFAULT (random()::int)" +== 864 +-- truncate_limit: 100 +select reltoastrelid <> 0 as has_toast_table + from pg_class where oid = 'test_storage'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltoastrelid <> 0 AS has_toast_table FROM pg_class WHERE oid = 'test_storage'::regclass" +== 865 +-- truncate_limit: 100 +alter table test_storage alter a set storage default +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_storage ALTER COLUMN a SET STORAGE \"default\"" +== 866 +-- truncate_limit: 100 +-- re-add TOAST table +select reltoastrelid <> 0 as has_toast_table + from pg_class where oid = 'test_storage'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltoastrelid <> 0 AS has_toast_table FROM pg_class WHERE oid = 'test_storage'::regclass" +== 867 +-- truncate_limit: 100 +-- check STORAGE correctness +create table test_storage_failed (a text, b int storage extended) +-- +TABLE: name="test_storage_failed" schema="" table="test_storage_failed" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_storage_failed (a text, b int STORAGE extended)" +== 868 +-- truncate_limit: 100 +-- test that SET STORAGE propagates to index correctly +create index test_storage_idx on test_storage (b, a) +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_storage_idx ON test_storage USING btree (b, a)" +== 869 +-- truncate_limit: 100 +alter table test_storage alter column a set storage external +-- +TABLE: name="test_storage" schema="" table="test_storage" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_storage ALTER COLUMN a SET STORAGE external" +== 870 +-- truncate_limit: 100 +-- ALTER COLUMN TYPE with a check constraint and a child table (bug #13779) +CREATE TABLE test_inh_check (a float check (a > 10.2), b float) +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_inh_check (a double precision CHECK (a > 10.2), b double precision)" +== 871 +-- truncate_limit: 100 +CREATE TABLE test_inh_check_child() INHERITS(test_inh_check) +-- +TABLE: name="test_inh_check_child" schema="" table="test_inh_check_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_inh_check_child () INHERITS (test_inh_check)" +== 872 +-- truncate_limit: 100 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint c, pg_class r WHERE ... ORDER BY 1, 2" +== 873 +-- truncate_limit: 100 +ALTER TABLE test_inh_check ALTER COLUMN a TYPE numeric +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_inh_check ALTER COLUMN a TYPE numeric" +== 874 +-- truncate_limit: 100 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint c, pg_class r WHERE ... ORDER BY 1, 2" +== 875 +-- truncate_limit: 100 +-- also try noinherit, local, and local+inherited cases +ALTER TABLE test_inh_check ADD CONSTRAINT bnoinherit CHECK (b > 100) NO INHERIT +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_inh_check ADD CONSTRAINT bnoinherit CHECK (b > 100) NO INHERIT" +== 876 +-- truncate_limit: 100 +ALTER TABLE test_inh_check_child ADD CONSTRAINT blocal CHECK (b < 1000) +-- +TABLE: name="test_inh_check_child" schema="" table="test_inh_check_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_inh_check_child ADD CONSTRAINT blocal CHECK (b < 1000)" +== 877 +-- truncate_limit: 100 +ALTER TABLE test_inh_check_child ADD CONSTRAINT bmerged CHECK (b > 1) +-- +TABLE: name="test_inh_check_child" schema="" table="test_inh_check_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_inh_check_child ADD CONSTRAINT bmerged CHECK (b > 1)" +== 878 +-- truncate_limit: 100 +ALTER TABLE test_inh_check ADD CONSTRAINT bmerged CHECK (b > 1) +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_inh_check ADD CONSTRAINT bmerged CHECK (b > 1)" +== 879 +-- truncate_limit: 100 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint c, pg_class r WHERE ... ORDER BY 1, 2" +== 880 +-- truncate_limit: 100 +ALTER TABLE test_inh_check ALTER COLUMN b TYPE numeric +-- +TABLE: name="test_inh_check" schema="" table="test_inh_check" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_inh_check ALTER COLUMN b TYPE numeric" +== 881 +-- truncate_limit: 100 +select relname, conname, coninhcount, conislocal, connoinherit + from pg_constraint c, pg_class r + where relname like 'test_inh_check%' and c.conrelid = r.oid + order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "r"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="c" column="conrelid" +FILTER: schema="" table="r" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint c, pg_class r WHERE ... ORDER BY 1, 2" +== 882 +-- truncate_limit: 100 +-- ALTER COLUMN TYPE with different schema in children +-- Bug at https://postgr.es/m/20170102225618.GA10071@telsasoft.com +CREATE TABLE test_type_diff (f1 int) +-- +TABLE: name="test_type_diff" schema="" table="test_type_diff" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_type_diff (f1 int)" +== 883 +-- truncate_limit: 100 +CREATE TABLE test_type_diff_c (extra smallint) INHERITS (test_type_diff) +-- +TABLE: name="test_type_diff_c" schema="" table="test_type_diff_c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_type_diff_c (extra smallint) INHERITS (test_type_diff)" +== 884 +-- truncate_limit: 100 +ALTER TABLE test_type_diff ADD COLUMN f2 int +-- +TABLE: name="test_type_diff" schema="" table="test_type_diff" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_type_diff ADD COLUMN f2 int" +== 885 +-- truncate_limit: 100 +INSERT INTO test_type_diff_c VALUES (1, 2, 3) +-- +TABLE: name="test_type_diff_c" schema="" table="test_type_diff_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_type_diff_c VALUES (1, 2, 3)" +== 886 +-- truncate_limit: 100 +ALTER TABLE test_type_diff ALTER COLUMN f2 TYPE bigint USING f2::bigint +-- +TABLE: name="test_type_diff" schema="" table="test_type_diff" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_type_diff ALTER COLUMN f2 TYPE bigint USING f2::bigint" +== 887 +-- truncate_limit: 100 +CREATE TABLE test_type_diff2 (int_two int2, int_four int4, int_eight int8) +-- +TABLE: name="test_type_diff2" schema="" table="test_type_diff2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_type_diff2 (int_two int2, int_four int4, int_eight int8)" +== 888 +-- truncate_limit: 100 +CREATE TABLE test_type_diff2_c1 (int_four int4, int_eight int8, int_two int2) +-- +TABLE: name="test_type_diff2_c1" schema="" table="test_type_diff2_c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_type_diff2_c1 (int_four int4, int_eight int8, int_two int2)" +== 889 +-- truncate_limit: 100 +CREATE TABLE test_type_diff2_c2 (int_eight int8, int_two int2, int_four int4) +-- +TABLE: name="test_type_diff2_c2" schema="" table="test_type_diff2_c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_type_diff2_c2 (int_eight int8, int_two int2, int_four int4)" +== 890 +-- truncate_limit: 100 +CREATE TABLE test_type_diff2_c3 (int_two int2, int_four int4, int_eight int8) +-- +TABLE: name="test_type_diff2_c3" schema="" table="test_type_diff2_c3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_type_diff2_c3 (int_two int2, int_four int4, int_eight int8)" +== 891 +-- truncate_limit: 100 +ALTER TABLE test_type_diff2_c1 INHERIT test_type_diff2 +-- +TABLE: name="test_type_diff2_c1" schema="" table="test_type_diff2_c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_type_diff2_c1 INHERIT test_type_diff2" +== 892 +-- truncate_limit: 100 +ALTER TABLE test_type_diff2_c2 INHERIT test_type_diff2 +-- +TABLE: name="test_type_diff2_c2" schema="" table="test_type_diff2_c2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_type_diff2_c2 INHERIT test_type_diff2" +== 893 +-- truncate_limit: 100 +ALTER TABLE test_type_diff2_c3 INHERIT test_type_diff2 +-- +TABLE: name="test_type_diff2_c3" schema="" table="test_type_diff2_c3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_type_diff2_c3 INHERIT test_type_diff2" +== 894 +-- truncate_limit: 100 +INSERT INTO test_type_diff2_c1 VALUES (1, 2, 3) +-- +TABLE: name="test_type_diff2_c1" schema="" table="test_type_diff2_c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_type_diff2_c1 VALUES (1, 2, 3)" +== 895 +-- truncate_limit: 100 +INSERT INTO test_type_diff2_c2 VALUES (4, 5, 6) +-- +TABLE: name="test_type_diff2_c2" schema="" table="test_type_diff2_c2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_type_diff2_c2 VALUES (4, 5, 6)" +== 896 +-- truncate_limit: 100 +INSERT INTO test_type_diff2_c3 VALUES (7, 8, 9) +-- +TABLE: name="test_type_diff2_c3" schema="" table="test_type_diff2_c3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_type_diff2_c3 VALUES (7, 8, 9)" +== 897 +-- truncate_limit: 100 +ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int8 USING int_four::int8 +-- +TABLE: name="test_type_diff2" schema="" table="test_type_diff2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int8 USING int_four::int8" +== 898 +-- truncate_limit: 100 +-- whole-row references are disallowed +ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int4 USING (pg_column_size(test_type_diff2)) +-- +TABLE: name="test_type_diff2" schema="" table="test_type_diff2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int4 USING pg_column_size(test_type_diff2)" +== 899 +-- truncate_limit: 100 +-- check for rollback of ANALYZE corrupting table property flags (bug #11638) +CREATE TABLE check_fk_presence_1 (id int PRIMARY KEY, t text) +-- +TABLE: name="check_fk_presence_1" schema="" table="check_fk_presence_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE check_fk_presence_1 (id int PRIMARY KEY, t text)" +== 900 +-- truncate_limit: 100 +CREATE TABLE check_fk_presence_2 (id int REFERENCES check_fk_presence_1, t text) +-- +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE check_fk_presence_2 (id int REFERENCES check_fk_presence_1, t text)" +== 901 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 902 +-- truncate_limit: 100 +ALTER TABLE check_fk_presence_2 DROP CONSTRAINT check_fk_presence_2_id_fkey +-- +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE check_fk_presence_2 DROP CONSTRAINT check_fk_presence_2_id_fkey" +== 903 +-- truncate_limit: 100 +ANALYZE check_fk_presence_2 +-- +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE check_fk_presence_2" +== 904 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 905 +-- truncate_limit: 100 +DROP TABLE check_fk_presence_1, check_fk_presence_2 +-- +TABLE: name="check_fk_presence_1" schema="" table="check_fk_presence_1" ctx=DDL +TABLE: name="check_fk_presence_2" schema="" table="check_fk_presence_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE check_fk_presence_1, check_fk_presence_2" +== 906 +-- truncate_limit: 100 +-- check column addition within a view (bug #14876) +create table at_base_table(id int, stuff text) +-- +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_base_table (id int, stuff text)" +== 907 +-- truncate_limit: 100 +insert into at_base_table values (23, 'skidoo') +-- +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO at_base_table VALUES (23, 'skidoo')" +== 908 +-- truncate_limit: 100 +create view at_view_1 as select * from at_base_table bt +-- +TABLE: name="at_view_1" schema="" table="at_view_1" ctx=DDL +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=Select +ALIAS: "bt"="at_base_table" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW at_view_1 AS SELECT * FROM at_base_table bt" +== 909 +-- truncate_limit: 100 +create view at_view_2 as select *, to_json(v1) as j from at_view_1 v1 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=DDL +TABLE: name="at_view_1" schema="" table="at_view_1" ctx=Select +ALIAS: "v1"="at_view_1" +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW at_view_2 AS SELECT *, to_json(v1) AS j FROM at_view_1 v1" +== 910 +-- truncate_limit: 100 +explain (verbose, costs off) select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM at_view_2" +== 911 +-- truncate_limit: 100 +select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM at_view_2" +== 912 +-- truncate_limit: 100 +create or replace view at_view_1 as select *, 2+2 as more from at_base_table bt +-- +TABLE: name="at_view_1" schema="" table="at_view_1" ctx=DDL +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=Select +ALIAS: "bt"="at_base_table" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW at_view_1 AS SELECT *, 2 + 2 AS more FROM at_base_table bt" +== 913 +-- truncate_limit: 100 +explain (verbose, costs off) select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM at_view_2" +== 914 +-- truncate_limit: 100 +select * from at_view_2 +-- +TABLE: name="at_view_2" schema="" table="at_view_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM at_view_2" +== 915 +-- truncate_limit: 100 +drop view at_view_2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW at_view_2" +== 916 +-- truncate_limit: 100 +drop view at_view_1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW at_view_1" +== 917 +-- truncate_limit: 100 +drop table at_base_table +-- +TABLE: name="at_base_table" schema="" table="at_base_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE at_base_table" +== 918 +-- truncate_limit: 100 +-- related case (bug #17811) +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 919 +-- truncate_limit: 100 +create temp table t1 as select * from int8_tbl +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 AS SELECT * FROM int8_tbl" +== 920 +-- truncate_limit: 100 +create temp view v1 as select 1::int8 as q1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v1 AS SELECT 1::int8 AS q1" +== 921 +-- truncate_limit: 100 +create temp view v2 as select * from v1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v2 AS SELECT * FROM v1" +== 922 +-- truncate_limit: 100 +create or replace temp view v1 with (security_barrier = true) + as select * from t1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v1 WITH (security_barrier=true) AS SELECT * FROM t1" +== 923 +-- truncate_limit: 100 +create temp table log (q1 int8, q2 int8) +-- +TABLE: name="log" schema="" table="log" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE log (q1 int8, q2 int8)" +== 924 +-- truncate_limit: 100 +create rule v1_upd_rule as on update to v1 + do also insert into log values (new.*) +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSERT INTO log VALUES (new.*)" +== 925 +-- truncate_limit: 100 +update v2 set q1 = q1 + 1 where q1 = 123 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE v2 SET q1 = q1 + 1 WHERE q1 = 123" +== 926 +-- truncate_limit: 100 +select * from t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 927 +-- truncate_limit: 100 +select * from log +-- +TABLE: name="log" schema="" table="log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM log" +== 928 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 929 +-- truncate_limit: 100 +-- check adding a column not itself requiring a rewrite, together with +-- a column requiring a default (bug #16038) + +-- ensure that rewrites aren't silently optimized away, removing the +-- value of the test +CREATE FUNCTION check_ddl_rewrite(p_tablename regclass, p_ddl text) +RETURNS boolean +LANGUAGE plpgsql AS $$ +DECLARE + v_relfilenode oid; +BEGIN + v_relfilenode := relfilenode FROM pg_class WHERE oid = p_tablename; + + EXECUTE p_ddl; + + RETURN v_relfilenode <> (SELECT relfilenode FROM pg_class WHERE oid = p_tablename); +END; +$$ +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION check_ddl_rewrite(p_tablename regclass, p_ddl text) RETURNS boolean LANGUAGE plpg..." +== 930 +-- truncate_limit: 100 +CREATE TABLE rewrite_test(col text) +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rewrite_test (col text)" +== 931 +-- truncate_limit: 100 +INSERT INTO rewrite_test VALUES ('something') +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rewrite_test VALUES ('something')" +== 932 +-- truncate_limit: 100 +INSERT INTO rewrite_test VALUES (NULL) +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rewrite_test VALUES (NULL)" +== 933 +-- truncate_limit: 100 +-- empty[12] don't need rewrite, but notempty[12]_rewrite will force one +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN empty1 text, + ADD COLUMN notempty1_rewrite serial; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 934 +-- truncate_limit: 100 +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN notempty2_rewrite serial, + ADD COLUMN empty2 text; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 935 +-- truncate_limit: 100 +-- also check that fast defaults cause no problem, first without rewrite +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN empty3 text, + ADD COLUMN notempty3_norewrite int default 42; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 936 +-- truncate_limit: 100 +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN notempty4_norewrite int default 42, + ADD COLUMN empty4 text; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 937 +-- truncate_limit: 100 +-- then with rewrite +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN empty5 text, + ADD COLUMN notempty5_norewrite int default 42, + ADD COLUMN notempty5_rewrite serial; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 938 +-- truncate_limit: 100 +SELECT check_ddl_rewrite('rewrite_test', $$ + ALTER TABLE rewrite_test + ADD COLUMN notempty6_rewrite serial, + ADD COLUMN empty6 text, + ADD COLUMN notempty6_norewrite int default 42; +$$) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 939 +-- truncate_limit: 100 +-- cleanup +DROP FUNCTION check_ddl_rewrite(regclass, text) +-- +FUNCTION: name="check_ddl_rewrite" function="check_ddl_rewrite" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION check_ddl_rewrite(regclass, text)" +== 940 +-- truncate_limit: 100 +DROP TABLE rewrite_test +-- +TABLE: name="rewrite_test" schema="" table="rewrite_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rewrite_test" +== 941 +-- truncate_limit: 100 +|-- +-- lock levels +|-- +drop type lockmodes +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE lockmodes" +== 942 +-- truncate_limit: 100 +create type lockmodes as enum ( + 'SIReadLock' +,'AccessShareLock' +,'RowShareLock' +,'RowExclusiveLock' +,'ShareUpdateExclusiveLock' +,'ShareLock' +,'ShareRowExclusiveLock' +,'ExclusiveLock' +,'AccessExclusiveLock' +) +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE lockmodes AS ENUM ('SIReadLock', 'AccessShareLock', 'RowShareLock', 'RowExclusiveLock..." +== 943 +-- truncate_limit: 100 +drop view my_locks +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW my_locks" +== 944 +-- truncate_limit: 100 +create or replace view my_locks as +select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode +from pg_locks l join pg_class c on l.relation = c.oid +where virtualtransaction = ( + select virtualtransaction + from pg_locks + where transactionid = pg_current_xact_id()::xid) +and locktype = 'relation' +and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog') +and c.relname != 'my_locks' +group by c.relname +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="" column="virtualtransaction" +FILTER: schema="" table="" column="transactionid" +FILTER: schema="" table="" column="nspname" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW my_locks AS SELECT CASE WHEN c.relname LIKE 'pg_toast%' THEN 'pg_toast' EL..." +== 945 +-- truncate_limit: 100 +create table alterlock (f1 int primary key, f2 text) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alterlock (f1 int PRIMARY KEY, f2 text)" +== 946 +-- truncate_limit: 100 +insert into alterlock values (1, 'foo') +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alterlock VALUES (1, 'foo')" +== 947 +-- truncate_limit: 100 +create table alterlock2 (f3 int primary key, f1 int) +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alterlock2 (f3 int PRIMARY KEY, f1 int)" +== 948 +-- truncate_limit: 100 +insert into alterlock2 values (1, 1) +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alterlock2 VALUES (1, 1)" +== 949 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 950 +-- truncate_limit: 100 +alter table alterlock alter column f2 set statistics 150 +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock ALTER COLUMN f2 SET STATISTICS 150" +== 951 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 952 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 953 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 954 +-- truncate_limit: 100 +alter table alterlock cluster on alterlock_pkey +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock CLUSTER ON alterlock_pkey" +== 955 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 956 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 957 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 958 +-- truncate_limit: 100 +alter table alterlock set without cluster +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock SET WITHOUT CLUSTER" +== 959 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 960 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 961 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 962 +-- truncate_limit: 100 +alter table alterlock set (fillfactor = 100) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock SET (fillfactor=100)" +== 963 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 964 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 965 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 966 +-- truncate_limit: 100 +alter table alterlock reset (fillfactor) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock RESET (fillfactor)" +== 967 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 968 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 969 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 970 +-- truncate_limit: 100 +alter table alterlock set (toast.autovacuum_enabled = off) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock SET (toast.autovacuum_enabled=off)" +== 971 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 972 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 973 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 974 +-- truncate_limit: 100 +alter table alterlock set (autovacuum_enabled = off) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock SET (autovacuum_enabled=off)" +== 975 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 976 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 977 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 978 +-- truncate_limit: 100 +alter table alterlock alter column f2 set (n_distinct = 1) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock ALTER COLUMN f2 SET (n_distinct=1)" +== 979 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 980 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 981 +-- truncate_limit: 100 +-- test that mixing options with different lock levels works as expected +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 982 +-- truncate_limit: 100 +alter table alterlock set (autovacuum_enabled = off, fillfactor = 80) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock SET (autovacuum_enabled=off, fillfactor=80)" +== 983 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 984 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 985 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 986 +-- truncate_limit: 100 +alter table alterlock alter column f2 set storage extended +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock ALTER COLUMN f2 SET STORAGE extended" +== 987 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 988 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 989 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 990 +-- truncate_limit: 100 +alter table alterlock alter column f2 set default 'x' +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock ALTER COLUMN f2 SET DEFAULT 'x'" +== 991 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 992 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 993 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 994 +-- truncate_limit: 100 +create trigger ttdummy + before delete or update on alterlock + for each row + execute procedure + ttdummy (1, 1) +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER ttdummy BEFORE DELETE OR UPDATE ON alterlock FOR EACH ROW EXECUTE FUNCTION ttdummy..." +== 995 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 996 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 997 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 998 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 999 +-- truncate_limit: 100 +alter table alterlock2 add foreign key (f1) references alterlock (f1) +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock2 ADD FOREIGN KEY (f1) REFERENCES alterlock (f1)" +== 1000 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 1001 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 1002 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1003 +-- truncate_limit: 100 +alter table alterlock2 +add constraint alterlock2nv foreign key (f1) references alterlock (f1) NOT VALID +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock2 ADD CONSTRAINT alterlock2nv FOREIGN KEY (f1) REFERENCES alterlock (f1) NOT..." +== 1004 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 1005 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1006 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1007 +-- truncate_limit: 100 +alter table alterlock2 validate constraint alterlock2nv +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alterlock2 VALIDATE CONSTRAINT alterlock2nv" +== 1008 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 1009 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 1010 +-- truncate_limit: 100 +create or replace view my_locks as +select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode +from pg_locks l join pg_class c on l.relation = c.oid +where virtualtransaction = ( + select virtualtransaction + from pg_locks + where transactionid = pg_current_xact_id()::xid) +and locktype = 'relation' +and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog') +and c.relname = 'my_locks' +group by c.relname +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="" column="virtualtransaction" +FILTER: schema="" table="" column="transactionid" +FILTER: schema="" table="" column="nspname" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW my_locks AS SELECT CASE WHEN c.relname LIKE 'pg_toast%' THEN 'pg_toast' EL..." +== 1011 +-- truncate_limit: 100 +-- raise exception +alter table my_locks set (autovacuum_enabled = false) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE my_locks SET (autovacuum_enabled=false)" +== 1012 +-- truncate_limit: 100 +alter view my_locks set (autovacuum_enabled = false) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW my_locks SET (autovacuum_enabled=false)" +== 1013 +-- truncate_limit: 100 +alter table my_locks reset (autovacuum_enabled) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE my_locks RESET (autovacuum_enabled)" +== 1014 +-- truncate_limit: 100 +alter view my_locks reset (autovacuum_enabled) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW my_locks RESET (autovacuum_enabled)" +== 1015 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1016 +-- truncate_limit: 100 +alter view my_locks set (security_barrier=off) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW my_locks SET (security_barrier=off)" +== 1017 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 1018 +-- truncate_limit: 100 +alter view my_locks reset (security_barrier) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW my_locks RESET (security_barrier)" +== 1019 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 1020 +-- truncate_limit: 100 +-- this test intentionally applies the ALTER TABLE command against a view, but +-- uses a view option so we expect this to succeed. This form of SQL is +-- accepted for historical reasons, as shown in the docs for ALTER VIEW +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1021 +-- truncate_limit: 100 +alter table my_locks set (security_barrier=off) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE my_locks SET (security_barrier=off)" +== 1022 +-- truncate_limit: 100 +select * from my_locks order by 1 +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_locks ORDER BY 1" +== 1023 +-- truncate_limit: 100 +alter table my_locks reset (security_barrier) +-- +TABLE: name="my_locks" schema="" table="my_locks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE my_locks RESET (security_barrier)" +== 1024 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 1025 +-- truncate_limit: 100 +-- cleanup +drop table alterlock2 +-- +TABLE: name="alterlock2" schema="" table="alterlock2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE alterlock2" +== 1026 +-- truncate_limit: 100 +drop table alterlock +-- +TABLE: name="alterlock" schema="" table="alterlock" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE alterlock" +== 1027 +-- truncate_limit: 100 +drop view my_locks +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW my_locks" +== 1028 +-- truncate_limit: 100 +drop type lockmodes +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE lockmodes" +== 1029 +-- truncate_limit: 100 +|-- +-- alter function +|-- +create function test_strict(text) returns text as + 'select coalesce($1, ''got passed a null'');' + language sql returns null on null input +-- +FUNCTION: name="test_strict" function="test_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_strict(text) RETURNS text AS $$select coalesce($1, 'got passed a null');$$ L..." +== 1030 +-- truncate_limit: 100 +select test_strict(NULL) +-- +FUNCTION: name="test_strict" function="test_strict" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_strict(NULL)" +== 1031 +-- truncate_limit: 100 +alter function test_strict(text) called on null input +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION test_strict(text) CALLED ON NULL INPUT" +== 1032 +-- truncate_limit: 100 +select test_strict(NULL) +-- +FUNCTION: name="test_strict" function="test_strict" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_strict(NULL)" +== 1033 +-- truncate_limit: 100 +create function non_strict(text) returns text as + 'select coalesce($1, ''got passed a null'');' + language sql called on null input +-- +FUNCTION: name="non_strict" function="non_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION non_strict(text) RETURNS text AS $$select coalesce($1, 'got passed a null');$$ LA..." +== 1034 +-- truncate_limit: 100 +select non_strict(NULL) +-- +FUNCTION: name="non_strict" function="non_strict" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT non_strict(NULL)" +== 1035 +-- truncate_limit: 100 +alter function non_strict(text) returns null on null input +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION non_strict(text) RETURNS NULL ON NULL INPUT" +== 1036 +-- truncate_limit: 100 +select non_strict(NULL) +-- +FUNCTION: name="non_strict" function="non_strict" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT non_strict(NULL)" +== 1037 +-- truncate_limit: 100 +|-- +-- alter object set schema +|-- + +create schema alter1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alter1" +== 1038 +-- truncate_limit: 100 +create schema alter2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alter2" +== 1039 +-- truncate_limit: 100 +create table alter1.t1(f1 serial primary key, f2 int check (f2 > 0)) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alter1.t1 (f1 serial PRIMARY KEY, f2 int CHECK (f2 > 0))" +== 1040 +-- truncate_limit: 100 +create view alter1.v1 as select * from alter1.t1 +-- +TABLE: name="alter1.v1" schema="alter1" table="v1" ctx=DDL +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW alter1.v1 AS SELECT * FROM alter1.t1" +== 1041 +-- truncate_limit: 100 +create function alter1.plus1(int) returns int as 'select $1+1' language sql +-- +FUNCTION: name="alter1.plus1" function="plus1" schema="alter1" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alter1.plus1(int) RETURNS int AS $$select $1+1$$ LANGUAGE sql" +== 1042 +-- truncate_limit: 100 +create domain alter1.posint integer check (value > 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN alter1.posint AS int CHECK (value > 0)" +== 1043 +-- truncate_limit: 100 +create type alter1.ctype as (f1 int, f2 text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE alter1.ctype AS (f1 int, f2 text)" +== 1044 +-- truncate_limit: 100 +create function alter1.same(alter1.ctype, alter1.ctype) returns boolean language sql +as 'select $1.f1 is not distinct from $2.f1 and $1.f2 is not distinct from $2.f2' +-- +FUNCTION: name="alter1.same" function="same" schema="alter1" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alter1.same(alter1.ctype, alter1.ctype) RETURNS boolean LANGUAGE sql AS $$select ..." +== 1045 +-- truncate_limit: 100 +create operator alter1.=(procedure = alter1.same, leftarg = alter1.ctype, rightarg = alter1.ctype) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR alter1.= (procedure = alter1.same, leftarg = alter1.ctype, rightarg = alter1.ctype)" +== 1046 +-- truncate_limit: 100 +create operator class alter1.ctype_hash_ops default for type alter1.ctype using hash as + operator 1 alter1.=(alter1.ctype, alter1.ctype) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS alter1.ctype_hash_ops DEFAULT FOR TYPE alter1.ctype USING hash AS OPERATOR ..." +== 1047 +-- truncate_limit: 100 +create conversion alter1.latin1_to_utf8 for 'latin1' to 'utf8' from iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION alter1.latin1_to_utf8 FOR 'latin1' TO 'utf8'FROM iso8859_1_to_utf8" +== 1048 +-- truncate_limit: 100 +create text search parser alter1.prs(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH PARSER alter1.prs (start = prsd_start, gettoken = prsd_nexttoken, \"end\" = prsd..." +== 1049 +-- truncate_limit: 100 +create text search configuration alter1.cfg(parser = alter1.prs) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION alter1.cfg (parser = alter1.prs)" +== 1050 +-- truncate_limit: 100 +create text search template alter1.tmpl(init = dsimple_init, lexize = dsimple_lexize) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH TEMPLATE alter1.tmpl (init = dsimple_init, lexize = dsimple_lexize)" +== 1051 +-- truncate_limit: 100 +create text search dictionary alter1.dict(template = alter1.tmpl) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY alter1.dict (template = alter1.tmpl)" +== 1052 +-- truncate_limit: 100 +insert into alter1.t1(f2) values(11) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alter1.t1 (f2) VALUES (11)" +== 1053 +-- truncate_limit: 100 +insert into alter1.t1(f2) values(12) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alter1.t1 (f2) VALUES (12)" +== 1054 +-- truncate_limit: 100 +alter table alter1.t1 set schema alter1 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE alter1.t1 SET SCHEMA alter1" +== 1055 +-- truncate_limit: 100 +-- no-op, same schema +alter table alter1.t1 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE alter1.t1 SET SCHEMA alter2" +== 1056 +-- truncate_limit: 100 +alter table alter1.v1 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE alter1.v1 SET SCHEMA alter2" +== 1057 +-- truncate_limit: 100 +alter function alter1.plus1(int) set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FUNCTION alter1.plus1(int) SET SCHEMA alter2" +== 1058 +-- truncate_limit: 100 +alter domain alter1.posint set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER DOMAIN alter1.posint SET SCHEMA alter2" +== 1059 +-- truncate_limit: 100 +alter operator class alter1.ctype_hash_ops using hash set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR CLASS alter1.ctype_hash_ops USING hash SET SCHEMA alter2" +== 1060 +-- truncate_limit: 100 +alter operator family alter1.ctype_hash_ops using hash set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR FAMILY alter1.ctype_hash_ops USING hash SET SCHEMA alter2" +== 1061 +-- truncate_limit: 100 +alter operator alter1.=(alter1.ctype, alter1.ctype) set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER OPERATOR alter1.=(alter1.ctype, alter1.ctype) SET SCHEMA alter2" +== 1062 +-- truncate_limit: 100 +alter function alter1.same(alter1.ctype, alter1.ctype) set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FUNCTION alter1.same(alter1.ctype, alter1.ctype) SET SCHEMA alter2" +== 1063 +-- truncate_limit: 100 +alter type alter1.ctype set schema alter1 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TYPE alter1.ctype SET SCHEMA alter1" +== 1064 +-- truncate_limit: 100 +-- no-op, same schema +alter type alter1.ctype set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TYPE alter1.ctype SET SCHEMA alter2" +== 1065 +-- truncate_limit: 100 +alter conversion alter1.latin1_to_utf8 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER CONVERSION alter1.latin1_to_utf8 SET SCHEMA alter2" +== 1066 +-- truncate_limit: 100 +alter text search parser alter1.prs set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH PARSER alter1.prs SET SCHEMA alter2" +== 1067 +-- truncate_limit: 100 +alter text search configuration alter1.cfg set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION alter1.cfg SET SCHEMA alter2" +== 1068 +-- truncate_limit: 100 +alter text search template alter1.tmpl set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH TEMPLATE alter1.tmpl SET SCHEMA alter2" +== 1069 +-- truncate_limit: 100 +alter text search dictionary alter1.dict set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY alter1.dict SET SCHEMA alter2" +== 1070 +-- truncate_limit: 100 +-- this should succeed because nothing is left in alter1 +drop schema alter1 +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA alter1" +== 1071 +-- truncate_limit: 100 +insert into alter2.t1(f2) values(13) +-- +TABLE: name="alter2.t1" schema="alter2" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alter2.t1 (f2) VALUES (13)" +== 1072 +-- truncate_limit: 100 +insert into alter2.t1(f2) values(14) +-- +TABLE: name="alter2.t1" schema="alter2" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alter2.t1 (f2) VALUES (14)" +== 1073 +-- truncate_limit: 100 +select * from alter2.t1 +-- +TABLE: name="alter2.t1" schema="alter2" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM alter2.t1" +== 1074 +-- truncate_limit: 100 +select * from alter2.v1 +-- +TABLE: name="alter2.v1" schema="alter2" table="v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM alter2.v1" +== 1075 +-- truncate_limit: 100 +select alter2.plus1(41) +-- +FUNCTION: name="alter2.plus1" function="plus1" schema="alter2" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT alter2.plus1(41)" +== 1076 +-- truncate_limit: 100 +-- clean up +drop schema alter2 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA alter2 CASCADE" +== 1077 +-- truncate_limit: 100 +|-- +-- composite types +|-- + +CREATE TYPE test_type AS (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE test_type AS (a int)" +== 1078 +-- truncate_limit: 100 +ALTER TYPE nosuchtype ADD ATTRIBUTE b text +-- +TABLE: name="nosuchtype" schema="" table="nosuchtype" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE nosuchtype ADD ATTRIBUTE b text" +== 1079 +-- truncate_limit: 100 +-- fails + +ALTER TYPE test_type ADD ATTRIBUTE b text +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type ADD ATTRIBUTE b text" +== 1080 +-- truncate_limit: 100 +ALTER TYPE test_type ADD ATTRIBUTE b text +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type ADD ATTRIBUTE b text" +== 1081 +-- truncate_limit: 100 +-- fails + +ALTER TYPE test_type ALTER ATTRIBUTE b SET DATA TYPE varchar +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type ALTER ATTRIBUTE b TYPE varchar" +== 1082 +-- truncate_limit: 100 +ALTER TYPE test_type ALTER ATTRIBUTE b SET DATA TYPE integer +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type ALTER ATTRIBUTE b TYPE int" +== 1083 +-- truncate_limit: 100 +ALTER TYPE test_type DROP ATTRIBUTE b +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type DROP ATTRIBUTE b" +== 1084 +-- truncate_limit: 100 +ALTER TYPE test_type DROP ATTRIBUTE c +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type DROP ATTRIBUTE c" +== 1085 +-- truncate_limit: 100 +-- fails + +ALTER TYPE test_type DROP ATTRIBUTE IF EXISTS c +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type DROP ATTRIBUTE IF EXISTS c" +== 1086 +-- truncate_limit: 100 +ALTER TYPE test_type DROP ATTRIBUTE a, ADD ATTRIBUTE d boolean +-- +TABLE: name="test_type" schema="" table="test_type" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type DROP ATTRIBUTE a, ADD ATTRIBUTE d boolean" +== 1087 +-- truncate_limit: 100 +ALTER TYPE test_type RENAME ATTRIBUTE a TO aa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE test_type RENAME ATTRIBUTE a TO aa" +== 1088 +-- truncate_limit: 100 +ALTER TYPE test_type RENAME ATTRIBUTE d TO dd +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE test_type RENAME ATTRIBUTE d TO dd" +== 1089 +-- truncate_limit: 100 +DROP TYPE test_type +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE test_type" +== 1090 +-- truncate_limit: 100 +CREATE TYPE test_type1 AS (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE test_type1 AS (a int, b text)" +== 1091 +-- truncate_limit: 100 +CREATE TABLE test_tbl1 (x int, y test_type1) +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tbl1 (x int, y test_type1)" +== 1092 +-- truncate_limit: 100 +ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar +-- +TABLE: name="test_type1" schema="" table="test_type1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar" +== 1093 +-- truncate_limit: 100 +-- fails + +DROP TABLE test_tbl1 +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_tbl1" +== 1094 +-- truncate_limit: 100 +CREATE TABLE test_tbl1 (x int, y text) +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tbl1 (x int, y text)" +== 1095 +-- truncate_limit: 100 +CREATE INDEX test_tbl1_idx ON test_tbl1((row(x,y)::test_type1)) +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_tbl1_idx ON test_tbl1 USING btree ((ROW(x, y)::test_type1))" +== 1096 +-- truncate_limit: 100 +ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar +-- +TABLE: name="test_type1" schema="" table="test_type1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar" +== 1097 +-- truncate_limit: 100 +-- fails + +DROP TABLE test_tbl1 +-- +TABLE: name="test_tbl1" schema="" table="test_tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_tbl1" +== 1098 +-- truncate_limit: 100 +DROP TYPE test_type1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE test_type1" +== 1099 +-- truncate_limit: 100 +CREATE TYPE test_type2 AS (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE test_type2 AS (a int, b text)" +== 1100 +-- truncate_limit: 100 +CREATE TABLE test_tbl2 OF test_type2 +-- +TABLE: name="test_tbl2" schema="" table="test_tbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tbl2 OF test_type2" +== 1101 +-- truncate_limit: 100 +CREATE TABLE test_tbl2_subclass () INHERITS (test_tbl2) +-- +TABLE: name="test_tbl2_subclass" schema="" table="test_tbl2_subclass" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tbl2_subclass () INHERITS (test_tbl2)" +== 1102 +-- truncate_limit: 100 +ALTER TYPE test_type2 ADD ATTRIBUTE c text +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type2 ADD ATTRIBUTE c text" +== 1103 +-- truncate_limit: 100 +-- fails +ALTER TYPE test_type2 ADD ATTRIBUTE c text CASCADE +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type2 ADD ATTRIBUTE c text CASCADE" +== 1104 +-- truncate_limit: 100 +ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar" +== 1105 +-- truncate_limit: 100 +-- fails +ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar CASCADE +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar CASCADE" +== 1106 +-- truncate_limit: 100 +ALTER TYPE test_type2 DROP ATTRIBUTE b +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type2 DROP ATTRIBUTE b" +== 1107 +-- truncate_limit: 100 +-- fails +ALTER TYPE test_type2 DROP ATTRIBUTE b CASCADE +-- +TABLE: name="test_type2" schema="" table="test_type2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type2 DROP ATTRIBUTE b CASCADE" +== 1108 +-- truncate_limit: 100 +ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa" +== 1109 +-- truncate_limit: 100 +-- fails +ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa CASCADE +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa CASCADE" +== 1110 +-- truncate_limit: 100 +DROP TABLE test_tbl2_subclass, test_tbl2 +-- +TABLE: name="test_tbl2_subclass" schema="" table="test_tbl2_subclass" ctx=DDL +TABLE: name="test_tbl2" schema="" table="test_tbl2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_tbl2_subclass, test_tbl2" +== 1111 +-- truncate_limit: 100 +DROP TYPE test_type2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE test_type2" +== 1112 +-- truncate_limit: 100 +CREATE TYPE test_typex AS (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE test_typex AS (a int, b text)" +== 1113 +-- truncate_limit: 100 +CREATE TABLE test_tblx (x int, y test_typex check ((y).a > 0)) +-- +TABLE: name="test_tblx" schema="" table="test_tblx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tblx (x int, y test_typex CHECK ((y).a > 0))" +== 1114 +-- truncate_limit: 100 +ALTER TYPE test_typex DROP ATTRIBUTE a +-- +TABLE: name="test_typex" schema="" table="test_typex" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_typex DROP ATTRIBUTE a" +== 1115 +-- truncate_limit: 100 +-- fails +ALTER TYPE test_typex DROP ATTRIBUTE a CASCADE +-- +TABLE: name="test_typex" schema="" table="test_typex" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_typex DROP ATTRIBUTE a CASCADE" +== 1116 +-- truncate_limit: 100 +DROP TABLE test_tblx +-- +TABLE: name="test_tblx" schema="" table="test_tblx" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_tblx" +== 1117 +-- truncate_limit: 100 +DROP TYPE test_typex +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE test_typex" +== 1118 +-- truncate_limit: 100 +-- This test isn't that interesting on its own, but the purpose is to leave +-- behind a table to test pg_upgrade with. The table has a composite type +-- column in it, and the composite type has a dropped attribute. +CREATE TYPE test_type3 AS (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE test_type3 AS (a int)" +== 1119 +-- truncate_limit: 100 +CREATE TABLE test_tbl3 (c) AS SELECT '(1)'::test_type3 +-- +TABLE: name="test_tbl3" schema="" table="test_tbl3" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_tbl3(c) AS SELECT '(1)'::test_type3" +== 1120 +-- truncate_limit: 100 +ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int +-- +TABLE: name="test_type3" schema="" table="test_type3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int" +== 1121 +-- truncate_limit: 100 +CREATE TYPE test_type_empty AS () +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE test_type_empty AS ()" +== 1122 +-- truncate_limit: 100 +DROP TYPE test_type_empty +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE test_type_empty" +== 1123 +-- truncate_limit: 100 +|-- +-- typed tables: OF / NOT OF +|-- + +CREATE TYPE tt_t0 AS (z inet, x int, y numeric(8,2)) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE tt_t0 AS (z inet, x int, y numeric(8, 2))" +== 1124 +-- truncate_limit: 100 +ALTER TYPE tt_t0 DROP ATTRIBUTE z +-- +TABLE: name="tt_t0" schema="" table="tt_t0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE tt_t0 DROP ATTRIBUTE z" +== 1125 +-- truncate_limit: 100 +CREATE TABLE tt0 (x int NOT NULL, y numeric(8,2)) +-- +TABLE: name="tt0" schema="" table="tt0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt0 (x int NOT NULL, y numeric(8, 2))" +== 1126 +-- truncate_limit: 100 +-- OK +CREATE TABLE tt1 (x int, y bigint) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt1 (x int, y bigint)" +== 1127 +-- truncate_limit: 100 +-- wrong base type +CREATE TABLE tt2 (x int, y numeric(9,2)) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt2 (x int, y numeric(9, 2))" +== 1128 +-- truncate_limit: 100 +-- wrong typmod +CREATE TABLE tt3 (y numeric(8,2), x int) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt3 (y numeric(8, 2), x int)" +== 1129 +-- truncate_limit: 100 +-- wrong column order +CREATE TABLE tt4 (x int) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt4 (x int)" +== 1130 +-- truncate_limit: 100 +-- too few columns +CREATE TABLE tt5 (x int, y numeric(8,2), z int) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt5 (x int, y numeric(8, 2), z int)" +== 1131 +-- truncate_limit: 100 +-- too few columns +CREATE TABLE tt6 () INHERITS (tt0) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt6 () INHERITS (tt0)" +== 1132 +-- truncate_limit: 100 +-- can't have a parent +CREATE TABLE tt7 (x int, q text, y numeric(8,2)) +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt7 (x int, q text, y numeric(8, 2))" +== 1133 +-- truncate_limit: 100 +ALTER TABLE tt7 DROP q +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 DROP q" +== 1134 +-- truncate_limit: 100 +-- OK + +ALTER TABLE tt0 OF tt_t0 +-- +TABLE: name="tt0" schema="" table="tt0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt0 OF tt_t0" +== 1135 +-- truncate_limit: 100 +ALTER TABLE tt1 OF tt_t0 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt1 OF tt_t0" +== 1136 +-- truncate_limit: 100 +ALTER TABLE tt2 OF tt_t0 +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt2 OF tt_t0" +== 1137 +-- truncate_limit: 100 +ALTER TABLE tt3 OF tt_t0 +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt3 OF tt_t0" +== 1138 +-- truncate_limit: 100 +ALTER TABLE tt4 OF tt_t0 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt4 OF tt_t0" +== 1139 +-- truncate_limit: 100 +ALTER TABLE tt5 OF tt_t0 +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt5 OF tt_t0" +== 1140 +-- truncate_limit: 100 +ALTER TABLE tt6 OF tt_t0 +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt6 OF tt_t0" +== 1141 +-- truncate_limit: 100 +ALTER TABLE tt7 OF tt_t0 +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 OF tt_t0" +== 1142 +-- truncate_limit: 100 +CREATE TYPE tt_t1 AS (x int, y numeric(8,2)) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE tt_t1 AS (x int, y numeric(8, 2))" +== 1143 +-- truncate_limit: 100 +ALTER TABLE tt7 OF tt_t1 +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 OF tt_t1" +== 1144 +-- truncate_limit: 100 +-- reassign an already-typed table +ALTER TABLE tt7 NOT OF +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 NOT OF" +== 1145 +-- truncate_limit: 100 +-- make sure we can drop a constraint on the parent but it remains on the child +CREATE TABLE test_drop_constr_parent (c text CHECK (c IS NOT NULL)) +-- +TABLE: name="test_drop_constr_parent" schema="" table="test_drop_constr_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_drop_constr_parent (c text CHECK (c IS NOT NULL))" +== 1146 +-- truncate_limit: 100 +CREATE TABLE test_drop_constr_child () INHERITS (test_drop_constr_parent) +-- +TABLE: name="test_drop_constr_child" schema="" table="test_drop_constr_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_drop_constr_child () INHERITS (test_drop_constr_parent)" +== 1147 +-- truncate_limit: 100 +ALTER TABLE ONLY test_drop_constr_parent DROP CONSTRAINT "test_drop_constr_parent_c_check" +-- +TABLE: name="test_drop_constr_parent" schema="" table="test_drop_constr_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_drop_constr_parent DROP CONSTRAINT test_drop_constr_parent_c_check" +== 1148 +-- truncate_limit: 100 +-- should fail +INSERT INTO test_drop_constr_child (c) VALUES (NULL) +-- +TABLE: name="test_drop_constr_child" schema="" table="test_drop_constr_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_drop_constr_child (c) VALUES (NULL)" +== 1149 +-- truncate_limit: 100 +DROP TABLE test_drop_constr_parent CASCADE +-- +TABLE: name="test_drop_constr_parent" schema="" table="test_drop_constr_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_drop_constr_parent CASCADE" +== 1150 +-- truncate_limit: 100 +|-- +-- IF EXISTS test +|-- +ALTER TABLE IF EXISTS tt8 ADD COLUMN f int +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ADD COLUMN f int" +== 1151 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY(f) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY (f)" +== 1152 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10)" +== 1153 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0 +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0" +== 1154 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1" +== 1155 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2" +== 1156 +-- truncate_limit: 100 +CREATE TABLE tt8(a int) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt8 (a int)" +== 1157 +-- truncate_limit: 100 +CREATE SCHEMA alter2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alter2" +== 1158 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 ADD COLUMN f int +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ADD COLUMN f int" +== 1159 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY(f) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY (f)" +== 1160 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10)" +== 1161 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0 +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0" +== 1162 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1" +== 1163 +-- truncate_limit: 100 +ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2" +== 1164 +-- truncate_limit: 100 +DROP TABLE alter2.tt8 +-- +TABLE: name="alter2.tt8" schema="alter2" table="tt8" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE alter2.tt8" +== 1165 +-- truncate_limit: 100 +DROP SCHEMA alter2 +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA alter2" +== 1166 +-- truncate_limit: 100 +|-- +-- Check conflicts between index and CHECK constraint names +|-- +CREATE TABLE tt9(c integer) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt9 (c int)" +== 1167 +-- truncate_limit: 100 +ALTER TABLE tt9 ADD CHECK(c > 1) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CHECK (c > 1)" +== 1168 +-- truncate_limit: 100 +ALTER TABLE tt9 ADD CHECK(c > 2) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CHECK (c > 2)" +== 1169 +-- truncate_limit: 100 +-- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 3) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CONSTRAINT foo CHECK (c > 3)" +== 1170 +-- truncate_limit: 100 +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 4) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CONSTRAINT foo CHECK (c > 4)" +== 1171 +-- truncate_limit: 100 +-- fail, dup name +ALTER TABLE tt9 ADD UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD UNIQUE (c)" +== 1172 +-- truncate_limit: 100 +ALTER TABLE tt9 ADD UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD UNIQUE (c)" +== 1173 +-- truncate_limit: 100 +-- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key UNIQUE (c)" +== 1174 +-- truncate_limit: 100 +-- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT foo UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CONSTRAINT foo UNIQUE (c)" +== 1175 +-- truncate_limit: 100 +-- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key CHECK(c > 5) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key CHECK (c > 5)" +== 1176 +-- truncate_limit: 100 +-- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key2 CHECK(c > 6) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key2 CHECK (c > 6)" +== 1177 +-- truncate_limit: 100 +ALTER TABLE tt9 ADD UNIQUE(c) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 ADD UNIQUE (c)" +== 1178 +-- truncate_limit: 100 +-- picks nonconflicting name +DROP TABLE tt9 +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tt9" +== 1179 +-- truncate_limit: 100 +-- Check that comments on constraints and indexes are not lost at ALTER TABLE. +CREATE TABLE comment_test ( + id int, + positive_col int CHECK (positive_col > 0), + indexed_col int, + CONSTRAINT comment_test_pk PRIMARY KEY (id)) +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE comment_test (id int, positive_col int CHECK (positive_col > 0), indexed_col int, CO..." +== 1180 +-- truncate_limit: 100 +CREATE INDEX comment_test_index ON comment_test(indexed_col) +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX comment_test_index ON comment_test USING btree (indexed_col)" +== 1181 +-- truncate_limit: 100 +COMMENT ON COLUMN comment_test.id IS 'Column ''id'' on comment_test' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN comment_test.id IS 'Column ''id'' on comment_test'" +== 1182 +-- truncate_limit: 100 +COMMENT ON INDEX comment_test_index IS 'Simple index on comment_test' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX comment_test_index IS 'Simple index on comment_test'" +== 1183 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT comment_test_positive_col_check ON comment_test IS 'CHECK constraint on comment_test.positive_col' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT comment_test_positive_col_check ON comment_test IS 'CHECK constraint on com..." +== 1184 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT comment_test_pk ON comment_test IS 'PRIMARY KEY constraint of comment_test' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT comment_test_pk ON comment_test IS 'PRIMARY KEY constraint of comment_test'" +== 1185 +-- truncate_limit: 100 +COMMENT ON INDEX comment_test_pk IS 'Index backing the PRIMARY KEY of comment_test' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX comment_test_pk IS 'Index backing the PRIMARY KEY of comment_test'" +== 1186 +-- truncate_limit: 100 +SELECT col_description('comment_test'::regclass, 1) as comment +-- +FUNCTION: name="col_description" function="col_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT col_description('comment_test'::regclass, 1) AS comment" +== 1187 +-- truncate_limit: 100 +SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'comment_test'::regclass ORDER BY 1, 2" +== 1188 +-- truncate_limit: 100 +SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'comment_test'::regclass ORDER BY 1, 2" +== 1189 +-- truncate_limit: 100 +-- Change the datatype of all the columns. ALTER TABLE is optimized to not +-- rebuild an index if the new data type is binary compatible with the old +-- one. Check do a dummy ALTER TABLE that doesn't change the datatype +-- first, to test that no-op codepath, and another one that does. +ALTER TABLE comment_test ALTER COLUMN indexed_col SET DATA TYPE int +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN indexed_col TYPE int" +== 1190 +-- truncate_limit: 100 +ALTER TABLE comment_test ALTER COLUMN indexed_col SET DATA TYPE text +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN indexed_col TYPE text" +== 1191 +-- truncate_limit: 100 +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN id TYPE int" +== 1192 +-- truncate_limit: 100 +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE text +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN id TYPE text" +== 1193 +-- truncate_limit: 100 +ALTER TABLE comment_test ALTER COLUMN positive_col SET DATA TYPE int +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN positive_col TYPE int" +== 1194 +-- truncate_limit: 100 +ALTER TABLE comment_test ALTER COLUMN positive_col SET DATA TYPE bigint +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN positive_col TYPE bigint" +== 1195 +-- truncate_limit: 100 +-- Check that the comments are intact. +SELECT col_description('comment_test'::regclass, 1) as comment +-- +FUNCTION: name="col_description" function="col_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT col_description('comment_test'::regclass, 1) AS comment" +== 1196 +-- truncate_limit: 100 +SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'comment_test'::regclass ORDER BY 1, 2" +== 1197 +-- truncate_limit: 100 +SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'comment_test'::regclass ORDER BY 1, 2" +== 1198 +-- truncate_limit: 100 +-- Check compatibility for foreign keys and comments. This is done +-- separately as rebuilding the column type of the parent leads +-- to an error and would reduce the test scope. +CREATE TABLE comment_test_child ( + id text CONSTRAINT comment_test_child_fk REFERENCES comment_test) +-- +TABLE: name="comment_test_child" schema="" table="comment_test_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE comment_test_child (id text CONSTRAINT comment_test_child_fk REFERENCES comment_test)" +== 1199 +-- truncate_limit: 100 +CREATE INDEX comment_test_child_fk ON comment_test_child(id) +-- +TABLE: name="comment_test_child" schema="" table="comment_test_child" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX comment_test_child_fk ON comment_test_child USING btree (id)" +== 1200 +-- truncate_limit: 100 +COMMENT ON COLUMN comment_test_child.id IS 'Column ''id'' on comment_test_child' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN comment_test_child.id IS 'Column ''id'' on comment_test_child'" +== 1201 +-- truncate_limit: 100 +COMMENT ON INDEX comment_test_child_fk IS 'Index backing the FOREIGN KEY of comment_test_child' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX comment_test_child_fk IS 'Index backing the FOREIGN KEY of comment_test_child'" +== 1202 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT comment_test_child_fk ON comment_test_child IS 'FOREIGN KEY constraint of comment_test_child' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT comment_test_child_fk ON comment_test_child IS 'FOREIGN KEY constraint of c..." +== 1203 +-- truncate_limit: 100 +-- Change column type of parent +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE text +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN id TYPE text" +== 1204 +-- truncate_limit: 100 +ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int USING id::integer +-- +TABLE: name="comment_test" schema="" table="comment_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment_test ALTER COLUMN id TYPE int USING id::int" +== 1205 +-- truncate_limit: 100 +-- Comments should be intact +SELECT col_description('comment_test_child'::regclass, 1) as comment +-- +FUNCTION: name="col_description" function="col_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT col_description('comment_test_child'::regclass, 1) AS comment" +== 1206 +-- truncate_limit: 100 +SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test_child'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'comment_test_child'::regclass ORDER BY 1, 2" +== 1207 +-- truncate_limit: 100 +SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test_child'::regclass ORDER BY 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'comment_test_child'::regclass ORDER BY 1, 2" +== 1208 +-- truncate_limit: 100 +-- Check that we map relation oids to filenodes and back correctly. Only +-- display bad mappings so the test output doesn't change all the time. A +-- filenode function call can return NULL for a relation dropped concurrently +-- with the call's surrounding query, so ignore a NULL mapped_oid for +-- relations that no longer exist after all calls finish. +-- Temporary relations are ignored, as not supported by pg_filenode_relation(). +CREATE TEMP TABLE filenode_mapping AS +SELECT + oid, mapped_oid, reltablespace, relfilenode, relname +FROM pg_class, + pg_filenode_relation(reltablespace, pg_relation_filenode(oid)) AS mapped_oid +WHERE relkind IN ('r', 'i', 'S', 't', 'm') + AND relpersistence != 't' + AND mapped_oid IS DISTINCT FROM oid +-- +TABLE: name="filenode_mapping" schema="" table="filenode_mapping" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_filenode_relation" function="pg_filenode_relation" schema="" ctx=Call +FUNCTION: name="pg_relation_filenode" function="pg_relation_filenode" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relpersistence" +FILTER: schema="" table="" column="mapped_oid" +FILTER: schema="" table="" column="oid" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE filenode_mapping AS SELECT oid, mapped_oid, reltablespace, relfilenode, re..." +== 1209 +-- truncate_limit: 100 +SELECT m.* FROM filenode_mapping m LEFT JOIN pg_class c ON c.oid = m.oid +WHERE c.oid IS NOT NULL OR m.mapped_oid IS NOT NULL +-- +TABLE: name="filenode_mapping" schema="" table="filenode_mapping" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "m"="filenode_mapping" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="m" column="mapped_oid" +STMT: SelectStmt +TRUNCATED: "SELECT m.* FROM filenode_mapping m LEFT JOIN pg_class c ON c.oid = m.oid WHERE ..." +== 1210 +-- truncate_limit: 100 +-- Checks on creating and manipulation of user defined relations in +-- pg_catalog. + +SHOW allow_system_table_mods +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW allow_system_table_mods" +== 1211 +-- truncate_limit: 100 +-- disallowed because of search_path issues with pg_dump +CREATE TABLE pg_catalog.new_system_table() +-- +TABLE: name="pg_catalog.new_system_table" schema="pg_catalog" table="new_system_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pg_catalog.new_system_table ()" +== 1212 +-- truncate_limit: 100 +-- instead create in public first, move to catalog +CREATE TABLE new_system_table(id serial primary key, othercol text) +-- +TABLE: name="new_system_table" schema="" table="new_system_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE new_system_table (id serial PRIMARY KEY, othercol text)" +== 1213 +-- truncate_limit: 100 +ALTER TABLE new_system_table SET SCHEMA pg_catalog +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE new_system_table SET SCHEMA pg_catalog" +== 1214 +-- truncate_limit: 100 +ALTER TABLE new_system_table SET SCHEMA public +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE new_system_table SET SCHEMA public" +== 1215 +-- truncate_limit: 100 +ALTER TABLE new_system_table SET SCHEMA pg_catalog +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE new_system_table SET SCHEMA pg_catalog" +== 1216 +-- truncate_limit: 100 +-- will be ignored -- already there: +ALTER TABLE new_system_table SET SCHEMA pg_catalog +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE new_system_table SET SCHEMA pg_catalog" +== 1217 +-- truncate_limit: 100 +ALTER TABLE new_system_table RENAME TO old_system_table +-- +TABLE: name="new_system_table" schema="" table="new_system_table" ctx=DDL +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE new_system_table RENAME TO old_system_table" +== 1218 +-- truncate_limit: 100 +CREATE INDEX old_system_table__othercol ON old_system_table (othercol) +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX old_system_table__othercol ON old_system_table USING btree (othercol)" +== 1219 +-- truncate_limit: 100 +INSERT INTO old_system_table(othercol) VALUES ('somedata'), ('otherdata') +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO old_system_table (othercol) VALUES ('somedata'), ('otherdata')" +== 1220 +-- truncate_limit: 100 +UPDATE old_system_table SET id = -id +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE old_system_table SET id = - id" +== 1221 +-- truncate_limit: 100 +DELETE FROM old_system_table WHERE othercol = 'somedata' +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM old_system_table WHERE othercol = 'somedata'" +== 1222 +-- truncate_limit: 100 +TRUNCATE old_system_table +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE old_system_table" +== 1223 +-- truncate_limit: 100 +ALTER TABLE old_system_table DROP CONSTRAINT new_system_table_pkey +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE old_system_table DROP CONSTRAINT new_system_table_pkey" +== 1224 +-- truncate_limit: 100 +ALTER TABLE old_system_table DROP COLUMN othercol +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE old_system_table DROP othercol" +== 1225 +-- truncate_limit: 100 +DROP TABLE old_system_table +-- +TABLE: name="old_system_table" schema="" table="old_system_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE old_system_table" +== 1226 +-- truncate_limit: 100 +-- set logged +CREATE UNLOGGED TABLE unlogged1(f1 SERIAL PRIMARY KEY, f2 TEXT) +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE unlogged1 (f1 serial PRIMARY KEY, f2 text)" +== 1227 +-- truncate_limit: 100 +-- has sequence, toast +-- check relpersistence of an unlogged table +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^unlogged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +TRUNCATED: "(SELECT ... FROM pg_class WHERE ... UNION ALL SELECT ... FROM pg_class r JOIN pg_class t ON t.oid..." +== 1228 +-- truncate_limit: 100 +CREATE UNLOGGED TABLE unlogged2(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES unlogged1) +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE unlogged2 (f1 serial PRIMARY KEY, f2 int REFERENCES unlogged1)" +== 1229 +-- truncate_limit: 100 +-- foreign key +CREATE UNLOGGED TABLE unlogged3(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES unlogged3) +-- +TABLE: name="unlogged3" schema="" table="unlogged3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE unlogged3 (f1 serial PRIMARY KEY, f2 int REFERENCES unlogged3)" +== 1230 +-- truncate_limit: 100 +-- self-referencing foreign key +ALTER TABLE unlogged3 SET LOGGED +-- +TABLE: name="unlogged3" schema="" table="unlogged3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE unlogged3 SET LOGGED" +== 1231 +-- truncate_limit: 100 +-- skip self-referencing foreign key +ALTER TABLE unlogged2 SET LOGGED +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE unlogged2 SET LOGGED" +== 1232 +-- truncate_limit: 100 +-- fails because a foreign key to an unlogged table exists +ALTER TABLE unlogged1 SET LOGGED +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE unlogged1 SET LOGGED" +== 1233 +-- truncate_limit: 100 +-- check relpersistence of an unlogged table after changing to permanent +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^unlogged1' +UNION ALL +SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^unlogged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +TRUNCATED: "(SELECT ... FROM pg_class WHERE ... UNION ALL SELECT ... FROM pg_class r JOIN pg_class t ON t.oid..." +== 1234 +-- truncate_limit: 100 +ALTER TABLE unlogged1 SET LOGGED +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE unlogged1 SET LOGGED" +== 1235 +-- truncate_limit: 100 +-- silently do nothing +DROP TABLE unlogged3 +-- +TABLE: name="unlogged3" schema="" table="unlogged3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unlogged3" +== 1236 +-- truncate_limit: 100 +DROP TABLE unlogged2 +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unlogged2" +== 1237 +-- truncate_limit: 100 +DROP TABLE unlogged1 +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unlogged1" +== 1238 +-- truncate_limit: 100 +-- set unlogged +CREATE TABLE logged1(f1 SERIAL PRIMARY KEY, f2 TEXT) +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE logged1 (f1 serial PRIMARY KEY, f2 text)" +== 1239 +-- truncate_limit: 100 +-- has sequence, toast +-- check relpersistence of a permanent table +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^logged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^logged1' +UNION ALL +SELECT r.relname ||' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^logged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +TRUNCATED: "(SELECT ... FROM pg_class WHERE ... UNION ALL SELECT ... FROM pg_class r JOIN pg_class t ON t.oid..." +== 1240 +-- truncate_limit: 100 +CREATE TABLE logged2(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES logged1) +-- +TABLE: name="logged2" schema="" table="logged2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE logged2 (f1 serial PRIMARY KEY, f2 int REFERENCES logged1)" +== 1241 +-- truncate_limit: 100 +-- foreign key +CREATE TABLE logged3(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES logged3) +-- +TABLE: name="logged3" schema="" table="logged3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE logged3 (f1 serial PRIMARY KEY, f2 int REFERENCES logged3)" +== 1242 +-- truncate_limit: 100 +-- self-referencing foreign key +ALTER TABLE logged1 SET UNLOGGED +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE logged1 SET UNLOGGED" +== 1243 +-- truncate_limit: 100 +-- fails because a foreign key from a permanent table exists +ALTER TABLE logged3 SET UNLOGGED +-- +TABLE: name="logged3" schema="" table="logged3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE logged3 SET UNLOGGED" +== 1244 +-- truncate_limit: 100 +-- skip self-referencing foreign key +ALTER TABLE logged2 SET UNLOGGED +-- +TABLE: name="logged2" schema="" table="logged2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE logged2 SET UNLOGGED" +== 1245 +-- truncate_limit: 100 +ALTER TABLE logged1 SET UNLOGGED +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE logged1 SET UNLOGGED" +== 1246 +-- truncate_limit: 100 +-- check relpersistence of a permanent table after changing to unlogged +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^logged1' +UNION ALL +SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^logged1' +UNION ALL +SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^logged1' +ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "i"="pg_index" +ALIAS: "r"="pg_class" +ALIAS: "ri"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="r" column="relname" +FILTER: schema="" table="r" column="relname" +STMT: SelectStmt +TRUNCATED: "(SELECT ... FROM pg_class WHERE ... UNION ALL SELECT ... FROM pg_class r JOIN pg_class t ON t.oid..." +== 1247 +-- truncate_limit: 100 +ALTER TABLE logged1 SET UNLOGGED +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE logged1 SET UNLOGGED" +== 1248 +-- truncate_limit: 100 +-- silently do nothing +DROP TABLE logged3 +-- +TABLE: name="logged3" schema="" table="logged3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE logged3" +== 1249 +-- truncate_limit: 100 +DROP TABLE logged2 +-- +TABLE: name="logged2" schema="" table="logged2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE logged2" +== 1250 +-- truncate_limit: 100 +DROP TABLE logged1 +-- +TABLE: name="logged1" schema="" table="logged1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE logged1" +== 1251 +-- truncate_limit: 100 +-- test ADD COLUMN IF NOT EXISTS +CREATE TABLE test_add_column(c1 integer) +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_add_column (c1 int)" +== 1252 +-- truncate_limit: 100 +ALTER TABLE test_add_column + ADD COLUMN c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN c2 int" +== 1253 +-- truncate_limit: 100 +ALTER TABLE test_add_column + ADD COLUMN c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN c2 int" +== 1254 +-- truncate_limit: 100 +-- fail because c2 already exists +ALTER TABLE ONLY test_add_column + ADD COLUMN c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_add_column ADD COLUMN c2 int" +== 1255 +-- truncate_limit: 100 +-- fail because c2 already exists +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c2 int" +== 1256 +-- truncate_limit: 100 +-- skipping because c2 already exists +ALTER TABLE ONLY test_add_column + ADD COLUMN IF NOT EXISTS c2 integer +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_add_column ADD COLUMN IF NOT EXISTS c2 int" +== 1257 +-- truncate_limit: 100 +-- skipping because c2 already exists +ALTER TABLE test_add_column + ADD COLUMN c2 integer, -- fail because c2 already exists + ADD COLUMN c3 integer primary key +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN c2 int, ADD COLUMN c3 int PRIMARY KEY" +== 1258 +-- truncate_limit: 100 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists + ADD COLUMN c3 integer primary key +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c2 int, ADD COLUMN c3 int PRIMARY KEY" +== 1259 +-- truncate_limit: 100 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists + ADD COLUMN IF NOT EXISTS c3 integer primary key +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c2 int, ADD COLUMN IF NOT EXISTS c3 int PRIM..." +== 1260 +-- truncate_limit: 100 +-- skipping because c3 already exists +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists + ADD COLUMN IF NOT EXISTS c3 integer, -- skipping because c3 already exists + ADD COLUMN c4 integer REFERENCES test_add_column +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c2 int, ADD COLUMN IF NOT EXISTS c3 int, ADD..." +== 1261 +-- truncate_limit: 100 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c4 integer REFERENCES test_add_column +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c4 int REFERENCES test_add_column" +== 1262 +-- truncate_limit: 100 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c5 SERIAL CHECK (c5 > 8) +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c5 serial CHECK (c5 > 8)" +== 1263 +-- truncate_limit: 100 +ALTER TABLE test_add_column + ADD COLUMN IF NOT EXISTS c5 SERIAL CHECK (c5 > 10) +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c5 serial CHECK (c5 > 10)" +== 1264 +-- truncate_limit: 100 +DROP TABLE test_add_column +-- +TABLE: name="test_add_column" schema="" table="test_add_column" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_add_column" +== 1265 +-- truncate_limit: 100 +-- assorted cases with multiple ALTER TABLE steps +CREATE TABLE ataddindex(f1 INT) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ataddindex (f1 int)" +== 1266 +-- truncate_limit: 100 +INSERT INTO ataddindex VALUES (42), (43) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ataddindex VALUES (42), (43)" +== 1267 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ataddindexi0 ON ataddindex(f1) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ataddindexi0 ON ataddindex USING btree (f1)" +== 1268 +-- truncate_limit: 100 +ALTER TABLE ataddindex + ADD PRIMARY KEY USING INDEX ataddindexi0, + ALTER f1 TYPE BIGINT +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ataddindex ADD PRIMARY KEY USING INDEX ataddindexi0, ALTER COLUMN f1 TYPE bigint" +== 1269 +-- truncate_limit: 100 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ataddindex" +== 1270 +-- truncate_limit: 100 +CREATE TABLE ataddindex(f1 VARCHAR(10)) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ataddindex (f1 varchar(10))" +== 1271 +-- truncate_limit: 100 +INSERT INTO ataddindex(f1) VALUES ('foo'), ('a') +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ataddindex (f1) VALUES ('foo'), ('a')" +== 1272 +-- truncate_limit: 100 +ALTER TABLE ataddindex + ALTER f1 SET DATA TYPE TEXT, + ADD EXCLUDE ((f1 LIKE 'a') WITH =) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ataddindex ALTER COLUMN f1 TYPE text, ADD EXCLUDE ((f1 LIKE 'a') WITH =)" +== 1273 +-- truncate_limit: 100 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ataddindex" +== 1274 +-- truncate_limit: 100 +CREATE TABLE ataddindex(id int, ref_id int) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ataddindex (id int, ref_id int)" +== 1275 +-- truncate_limit: 100 +ALTER TABLE ataddindex + ADD PRIMARY KEY (id), + ADD FOREIGN KEY (ref_id) REFERENCES ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ataddindex ADD PRIMARY KEY (id), ADD FOREIGN KEY (ref_id) REFERENCES ataddindex" +== 1276 +-- truncate_limit: 100 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ataddindex" +== 1277 +-- truncate_limit: 100 +CREATE TABLE ataddindex(id int, ref_id int) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ataddindex (id int, ref_id int)" +== 1278 +-- truncate_limit: 100 +ALTER TABLE ataddindex + ADD UNIQUE (id), + ADD FOREIGN KEY (ref_id) REFERENCES ataddindex (id) +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ataddindex ADD UNIQUE (id), ADD FOREIGN KEY (ref_id) REFERENCES ataddindex (id)" +== 1279 +-- truncate_limit: 100 +DROP TABLE ataddindex +-- +TABLE: name="ataddindex" schema="" table="ataddindex" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ataddindex" +== 1280 +-- truncate_limit: 100 +CREATE TABLE atnotnull1 () +-- +TABLE: name="atnotnull1" schema="" table="atnotnull1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atnotnull1 ()" +== 1281 +-- truncate_limit: 100 +ALTER TABLE atnotnull1 + ADD COLUMN a INT, + ALTER a SET NOT NULL +-- +TABLE: name="atnotnull1" schema="" table="atnotnull1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atnotnull1 ADD COLUMN a int, ALTER COLUMN a SET NOT NULL" +== 1282 +-- truncate_limit: 100 +ALTER TABLE atnotnull1 + ADD COLUMN c INT, + ADD PRIMARY KEY (c) +-- +TABLE: name="atnotnull1" schema="" table="atnotnull1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atnotnull1 ADD COLUMN c int, ADD PRIMARY KEY (c)" +== 1283 +-- truncate_limit: 100 +-- cannot drop column that is part of the partition key +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (a, (a+b+1)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, b int) PARTITION BY RANGE (a, ((a + b) + 1))" +== 1284 +-- truncate_limit: 100 +ALTER TABLE partitioned DROP COLUMN a +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned DROP a" +== 1285 +-- truncate_limit: 100 +ALTER TABLE partitioned ALTER COLUMN a TYPE char(5) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned ALTER COLUMN a TYPE char(5)" +== 1286 +-- truncate_limit: 100 +ALTER TABLE partitioned DROP COLUMN b +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned DROP b" +== 1287 +-- truncate_limit: 100 +ALTER TABLE partitioned ALTER COLUMN b TYPE char(5) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned ALTER COLUMN b TYPE char(5)" +== 1288 +-- truncate_limit: 100 +-- specifying storage parameters for partitioned tables is not supported +ALTER TABLE partitioned SET (fillfactor=100) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned SET (fillfactor=100)" +== 1289 +-- truncate_limit: 100 +-- partitioned table cannot participate in regular inheritance +CREATE TABLE nonpartitioned ( + a int, + b int +) +-- +TABLE: name="nonpartitioned" schema="" table="nonpartitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nonpartitioned (a int, b int)" +== 1290 +-- truncate_limit: 100 +ALTER TABLE partitioned INHERIT nonpartitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned INHERIT nonpartitioned" +== 1291 +-- truncate_limit: 100 +ALTER TABLE nonpartitioned INHERIT partitioned +-- +TABLE: name="nonpartitioned" schema="" table="nonpartitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE nonpartitioned INHERIT partitioned" +== 1292 +-- truncate_limit: 100 +-- cannot add NO INHERIT constraint to partitioned tables +ALTER TABLE partitioned ADD CONSTRAINT chk_a CHECK (a > 0) NO INHERIT +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned ADD CONSTRAINT chk_a CHECK (a > 0) NO INHERIT" +== 1293 +-- truncate_limit: 100 +DROP TABLE partitioned, nonpartitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +TABLE: name="nonpartitioned" schema="" table="nonpartitioned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE partitioned, nonpartitioned" +== 1294 +-- truncate_limit: 100 +|-- +-- ATTACH PARTITION +|-- + +-- check that target table is partitioned +CREATE TABLE unparted ( + a int +) +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unparted (a int)" +== 1295 +-- truncate_limit: 100 +CREATE TABLE fail_part (like unparted) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (LIKE unparted)" +== 1296 +-- truncate_limit: 100 +ALTER TABLE unparted ATTACH PARTITION fail_part FOR VALUES IN ('a') +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE unparted ATTACH PARTITION fail_part FOR VALUES IN ('a')" +== 1297 +-- truncate_limit: 100 +DROP TABLE unparted, fail_part +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unparted, fail_part" +== 1298 +-- truncate_limit: 100 +-- check that partition bound is compatible +CREATE TABLE list_parted ( + a int NOT NULL, + b char(2) COLLATE "C", + CONSTRAINT check_a CHECK (a > 0) +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted (a int NOT NULL, b char(2) COLLATE \"C\", CONSTRAINT check_a CHECK (a > 0)..." +== 1299 +-- truncate_limit: 100 +CREATE TABLE fail_part (LIKE list_parted) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (LIKE list_parted)" +== 1300 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES FROM (1) TO (10) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES FROM (1) TO (10)" +== 1301 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1302 +-- truncate_limit: 100 +-- check that the table being attached exists +ALTER TABLE list_parted ATTACH PARTITION nonexistent FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION nonexistent FOR VALUES IN (1)" +== 1303 +-- truncate_limit: 100 +-- check ownership of the source table +CREATE ROLE regress_test_me +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_me" +== 1304 +-- truncate_limit: 100 +CREATE ROLE regress_test_not_me +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_not_me" +== 1305 +-- truncate_limit: 100 +CREATE TABLE not_owned_by_me (LIKE list_parted) +-- +TABLE: name="not_owned_by_me" schema="" table="not_owned_by_me" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE not_owned_by_me (LIKE list_parted)" +== 1306 +-- truncate_limit: 100 +ALTER TABLE not_owned_by_me OWNER TO regress_test_not_me +-- +TABLE: name="not_owned_by_me" schema="" table="not_owned_by_me" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE not_owned_by_me OWNER TO regress_test_not_me" +== 1307 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_test_me +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_test_me" +== 1308 +-- truncate_limit: 100 +CREATE TABLE owned_by_me ( + a int +) PARTITION BY LIST (a) +-- +TABLE: name="owned_by_me" schema="" table="owned_by_me" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE owned_by_me (a int) PARTITION BY LIST (a)" +== 1309 +-- truncate_limit: 100 +ALTER TABLE owned_by_me ATTACH PARTITION not_owned_by_me FOR VALUES IN (1) +-- +TABLE: name="owned_by_me" schema="" table="owned_by_me" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE owned_by_me ATTACH PARTITION not_owned_by_me FOR VALUES IN (1)" +== 1310 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 1311 +-- truncate_limit: 100 +DROP TABLE owned_by_me, not_owned_by_me +-- +TABLE: name="owned_by_me" schema="" table="owned_by_me" ctx=DDL +TABLE: name="not_owned_by_me" schema="" table="not_owned_by_me" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE owned_by_me, not_owned_by_me" +== 1312 +-- truncate_limit: 100 +DROP ROLE regress_test_not_me +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_not_me" +== 1313 +-- truncate_limit: 100 +DROP ROLE regress_test_me +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_me" +== 1314 +-- truncate_limit: 100 +-- check that the table being attached is not part of regular inheritance +CREATE TABLE parent (LIKE list_parted) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (LIKE list_parted)" +== 1315 +-- truncate_limit: 100 +CREATE TABLE child () INHERITS (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child () INHERITS (parent)" +== 1316 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1)" +== 1317 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1)" +== 1318 +-- truncate_limit: 100 +DROP TABLE child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child" +== 1319 +-- truncate_limit: 100 +-- now it should work, with a little tweak +ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0)" +== 1320 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1)" +== 1321 +-- truncate_limit: 100 +-- test insert/update, per bug #18550 +INSERT INTO parent VALUES (1) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (1)" +== 1322 +-- truncate_limit: 100 +UPDATE parent SET a = 2 WHERE a = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parent SET a = 2 WHERE a = 1" +== 1323 +-- truncate_limit: 100 +DROP TABLE parent CASCADE +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent CASCADE" +== 1324 +-- truncate_limit: 100 +-- check any TEMP-ness +CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted (a int) PARTITION BY LIST (a)" +== 1325 +-- truncate_limit: 100 +CREATE TABLE perm_part (a int) +-- +TABLE: name="perm_part" schema="" table="perm_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE perm_part (a int)" +== 1326 +-- truncate_limit: 100 +ALTER TABLE temp_parted ATTACH PARTITION perm_part FOR VALUES IN (1) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE temp_parted ATTACH PARTITION perm_part FOR VALUES IN (1)" +== 1327 +-- truncate_limit: 100 +DROP TABLE temp_parted, perm_part +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +TABLE: name="perm_part" schema="" table="perm_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_parted, perm_part" +== 1328 +-- truncate_limit: 100 +-- check that the table being attached is not a typed table +CREATE TYPE mytype AS (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE mytype AS (a int)" +== 1329 +-- truncate_limit: 100 +CREATE TABLE fail_part OF mytype +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part OF mytype" +== 1330 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1331 +-- truncate_limit: 100 +DROP TYPE mytype CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE mytype CASCADE" +== 1332 +-- truncate_limit: 100 +-- check that the table being attached has only columns present in the parent +CREATE TABLE fail_part (like list_parted, c int) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (LIKE list_parted, c int)" +== 1333 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1334 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1335 +-- truncate_limit: 100 +-- check that the table being attached has every column of the parent +CREATE TABLE fail_part (a int NOT NULL) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (a int NOT NULL)" +== 1336 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1337 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1338 +-- truncate_limit: 100 +-- check that columns match in type, collation and NOT NULL status +CREATE TABLE fail_part ( + b char(3), + a int NOT NULL +) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (b char(3), a int NOT NULL)" +== 1339 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1340 +-- truncate_limit: 100 +ALTER TABLE fail_part ALTER b TYPE char (2) COLLATE "POSIX" +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fail_part ALTER COLUMN b TYPE char(2) COLLATE \"POSIX\"" +== 1341 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1342 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1343 +-- truncate_limit: 100 +-- check that the table being attached has all constraints of the parent +CREATE TABLE fail_part ( + b char(2) COLLATE "C", + a int NOT NULL +) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (b char(2) COLLATE \"C\", a int NOT NULL)" +== 1344 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1345 +-- truncate_limit: 100 +-- check that the constraint matches in definition with parent's constraint +ALTER TABLE fail_part ADD CONSTRAINT check_a CHECK (a >= 0) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fail_part ADD CONSTRAINT check_a CHECK (a >= 0)" +== 1346 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1347 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1348 +-- truncate_limit: 100 +-- check the attributes and constraints after partition is attached +CREATE TABLE part_1 ( + a int NOT NULL, + b char(2) COLLATE "C", + CONSTRAINT check_a CHECK (a > 0) +) +-- +TABLE: name="part_1" schema="" table="part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_1 (a int NOT NULL, b char(2) COLLATE \"C\", CONSTRAINT check_a CHECK (a > 0))" +== 1349 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (1)" +== 1350 +-- truncate_limit: 100 +-- attislocal and conislocal are always false for merged attributes and constraints respectively. +SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attnum > 0 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attnum > 0" +== 1351 +-- truncate_limit: 100 +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_1'::regclass AND conname = 'check_a' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT conislocal, coninhcount FROM pg_constraint WHERE ..." +== 1352 +-- truncate_limit: 100 +-- check that the new partition won't overlap with an existing partition +CREATE TABLE fail_part (LIKE part_1 INCLUDING CONSTRAINTS) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (LIKE part_1 INCLUDING CONSTRAINTS)" +== 1353 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1)" +== 1354 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1355 +-- truncate_limit: 100 +-- check that an existing table can be attached as a default partition +CREATE TABLE def_part (LIKE list_parted INCLUDING CONSTRAINTS) +-- +TABLE: name="def_part" schema="" table="def_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE def_part (LIKE list_parted INCLUDING CONSTRAINTS)" +== 1356 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION def_part DEFAULT +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION def_part DEFAULT" +== 1357 +-- truncate_limit: 100 +-- check attaching default partition fails if a default partition already +-- exists +CREATE TABLE fail_def_part (LIKE part_1 INCLUDING CONSTRAINTS) +-- +TABLE: name="fail_def_part" schema="" table="fail_def_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_def_part (LIKE part_1 INCLUDING CONSTRAINTS)" +== 1358 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION fail_def_part DEFAULT +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION fail_def_part DEFAULT" +== 1359 +-- truncate_limit: 100 +-- check validation when attaching list partitions +CREATE TABLE list_parted2 ( + a int, + b char +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted2 (a int, b char(1)) PARTITION BY LIST (a)" +== 1360 +-- truncate_limit: 100 +-- check that violating rows are correctly reported +CREATE TABLE part_2 (LIKE list_parted2) +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_2 (LIKE list_parted2)" +== 1361 +-- truncate_limit: 100 +INSERT INTO part_2 VALUES (3, 'a') +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_2 VALUES (3, 'a')" +== 1362 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2)" +== 1363 +-- truncate_limit: 100 +-- should be ok after deleting the bad row +DELETE FROM part_2 +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM part_2" +== 1364 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2)" +== 1365 +-- truncate_limit: 100 +-- check partition cannot be attached if default has some row for its values +CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT" +== 1366 +-- truncate_limit: 100 +INSERT INTO list_parted2_def VALUES (11, 'z') +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted2_def VALUES (11, 'z')" +== 1367 +-- truncate_limit: 100 +CREATE TABLE part_3 (LIKE list_parted2) +-- +TABLE: name="part_3" schema="" table="part_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_3 (LIKE list_parted2)" +== 1368 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11)" +== 1369 +-- truncate_limit: 100 +-- should be ok after deleting the bad row +DELETE FROM list_parted2_def WHERE a = 11 +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM list_parted2_def WHERE a = 11" +== 1370 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11)" +== 1371 +-- truncate_limit: 100 +-- adding constraints that describe the desired partition constraint +-- (or more restrictive) will help skip the validation scan +CREATE TABLE part_3_4 ( + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IN (3)) +) +-- +TABLE: name="part_3_4" schema="" table="part_3_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_3_4 (LIKE list_parted2, CONSTRAINT check_a CHECK (a IN (3)))" +== 1372 +-- truncate_limit: 100 +-- however, if a list partition does not accept nulls, there should be +-- an explicit NOT NULL constraint on the partition key column for the +-- validation scan to be skipped; +ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4)" +== 1373 +-- truncate_limit: 100 +-- adding a NOT NULL constraint will cause the scan to be skipped +ALTER TABLE list_parted2 DETACH PARTITION part_3_4 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DETACH PARTITION part_3_4" +== 1374 +-- truncate_limit: 100 +ALTER TABLE part_3_4 ALTER a SET NOT NULL +-- +TABLE: name="part_3_4" schema="" table="part_3_4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_3_4 ALTER COLUMN a SET NOT NULL" +== 1375 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4)" +== 1376 +-- truncate_limit: 100 +-- check if default partition scan skipped +ALTER TABLE list_parted2_def ADD CONSTRAINT check_a CHECK (a IN (5, 6)) +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2_def ADD CONSTRAINT check_a CHECK (a IN (5, 6))" +== 1377 +-- truncate_limit: 100 +CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66) +-- +TABLE: name="part_55_66" schema="" table="part_55_66" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66)" +== 1378 +-- truncate_limit: 100 +-- check validation when attaching range partitions +CREATE TABLE range_parted ( + a int, + b int +) PARTITION BY RANGE (a, b) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted (a int, b int) PARTITION BY RANGE (a, b)" +== 1379 +-- truncate_limit: 100 +-- check that violating rows are correctly reported +CREATE TABLE part1 ( + a int NOT NULL CHECK (a = 1), + b int NOT NULL CHECK (b >= 1 AND b <= 10) +) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part1 (a int NOT NULL CHECK (a = 1), b int NOT NULL CHECK (b >= 1 AND b <= 10))" +== 1380 +-- truncate_limit: 100 +INSERT INTO part1 VALUES (1, 10) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part1 VALUES (1, 10)" +== 1381 +-- truncate_limit: 100 +-- Remember the TO bound is exclusive +ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10)" +== 1382 +-- truncate_limit: 100 +-- should be ok after deleting the bad row +DELETE FROM part1 +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM part1" +== 1383 +-- truncate_limit: 100 +ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10)" +== 1384 +-- truncate_limit: 100 +-- adding constraints that describe the desired partition constraint +-- (or more restrictive) will help skip the validation scan +CREATE TABLE part2 ( + a int NOT NULL CHECK (a = 1), + b int NOT NULL CHECK (b >= 10 AND b < 18) +) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part2 (a int NOT NULL CHECK (a = 1), b int NOT NULL CHECK (b >= 10 AND b < 18))" +== 1385 +-- truncate_limit: 100 +ALTER TABLE range_parted ATTACH PARTITION part2 FOR VALUES FROM (1, 10) TO (1, 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION part2 FOR VALUES FROM (1, 10) TO (1, 20)" +== 1386 +-- truncate_limit: 100 +-- Create default partition +CREATE TABLE partr_def1 PARTITION OF range_parted DEFAULT +-- +TABLE: name="partr_def1" schema="" table="partr_def1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partr_def1 PARTITION OF range_parted DEFAULT" +== 1387 +-- truncate_limit: 100 +-- Only one default partition is allowed, hence, following should give error +CREATE TABLE partr_def2 (LIKE part1 INCLUDING CONSTRAINTS) +-- +TABLE: name="partr_def2" schema="" table="partr_def2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partr_def2 (LIKE part1 INCLUDING CONSTRAINTS)" +== 1388 +-- truncate_limit: 100 +ALTER TABLE range_parted ATTACH PARTITION partr_def2 DEFAULT +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION partr_def2 DEFAULT" +== 1389 +-- truncate_limit: 100 +-- Overlapping partitions cannot be attached, hence, following should give error +INSERT INTO partr_def1 VALUES (2, 10) +-- +TABLE: name="partr_def1" schema="" table="partr_def1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO partr_def1 VALUES (2, 10)" +== 1390 +-- truncate_limit: 100 +CREATE TABLE part3 (LIKE range_parted) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part3 (LIKE range_parted)" +== 1391 +-- truncate_limit: 100 +ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (2, 10) TO (2, 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION part3 FOR VALUES FROM (2, 10) TO (2, 20)" +== 1392 +-- truncate_limit: 100 +-- Attaching partitions should be successful when there are no overlapping rows +ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (3, 10) TO (3, 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION part3 FOR VALUES FROM (3, 10) TO (3, 20)" +== 1393 +-- truncate_limit: 100 +-- check that leaf partitions are scanned when attaching a partitioned +-- table +CREATE TABLE part_5 ( + LIKE list_parted2 +) PARTITION BY LIST (b) +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_5 (LIKE list_parted2) PARTITION BY LIST (b)" +== 1394 +-- truncate_limit: 100 +-- check that violating rows are correctly reported +CREATE TABLE part_5_a PARTITION OF part_5 FOR VALUES IN ('a') +-- +TABLE: name="part_5_a" schema="" table="part_5_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_5_a PARTITION OF part_5 FOR VALUES IN ('a')" +== 1395 +-- truncate_limit: 100 +INSERT INTO part_5_a (a, b) VALUES (6, 'a') +-- +TABLE: name="part_5_a" schema="" table="part_5_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_5_a (a, b) VALUES (6, 'a')" +== 1396 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5)" +== 1397 +-- truncate_limit: 100 +-- delete the faulting row and also add a constraint to skip the scan +DELETE FROM part_5_a WHERE a NOT IN (3) +-- +TABLE: name="part_5_a" schema="" table="part_5_a" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM part_5_a WHERE a NOT IN (3)" +== 1398 +-- truncate_limit: 100 +ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5) +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5)" +== 1399 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5)" +== 1400 +-- truncate_limit: 100 +ALTER TABLE list_parted2 DETACH PARTITION part_5 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DETACH PARTITION part_5" +== 1401 +-- truncate_limit: 100 +ALTER TABLE part_5 DROP CONSTRAINT check_a +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_5 DROP CONSTRAINT check_a" +== 1402 +-- truncate_limit: 100 +-- scan should again be skipped, even though NOT NULL is now a column property +ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), ALTER a SET NOT NULL +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), ALTER COLUMN a SET NOT NULL" +== 1403 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5)" +== 1404 +-- truncate_limit: 100 +-- Check the case where attnos of the partitioning columns in the table being +-- attached differs from the parent. It should not affect the constraint- +-- checking logic that allows to skip the scan. +CREATE TABLE part_6 ( + c int, + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 6) +) +-- +TABLE: name="part_6" schema="" table="part_6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_6 (c int, LIKE list_parted2, CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 6))" +== 1405 +-- truncate_limit: 100 +ALTER TABLE part_6 DROP c +-- +TABLE: name="part_6" schema="" table="part_6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_6 DROP c" +== 1406 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6)" +== 1407 +-- truncate_limit: 100 +-- Similar to above, but the table being attached is a partitioned table +-- whose partition has still different attnos for the root partitioning +-- columns. +CREATE TABLE part_7 ( + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7) +) PARTITION BY LIST (b) +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_7 (LIKE list_parted2, CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7)) PARTI..." +== 1408 +-- truncate_limit: 100 +CREATE TABLE part_7_a_null ( + c int, + d int, + e int, + LIKE list_parted2, -- 'a' will have attnum = 4 + CONSTRAINT check_b CHECK (b IS NULL OR b = 'a'), + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7) +) +-- +TABLE: name="part_7_a_null" schema="" table="part_7_a_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_7_a_null (c int, d int, e int, LIKE list_parted2, CONSTRAINT check_b CHECK (b I..." +== 1409 +-- truncate_limit: 100 +ALTER TABLE part_7_a_null DROP c, DROP d, DROP e +-- +TABLE: name="part_7_a_null" schema="" table="part_7_a_null" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_7_a_null DROP c, DROP d, DROP e" +== 1410 +-- truncate_limit: 100 +ALTER TABLE part_7 ATTACH PARTITION part_7_a_null FOR VALUES IN ('a', null) +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_7 ATTACH PARTITION part_7_a_null FOR VALUES IN ('a', NULL)" +== 1411 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7)" +== 1412 +-- truncate_limit: 100 +-- Same example, but check this time that the constraint correctly detects +-- violating rows +ALTER TABLE list_parted2 DETACH PARTITION part_7 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DETACH PARTITION part_7" +== 1413 +-- truncate_limit: 100 +ALTER TABLE part_7 DROP CONSTRAINT check_a +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_7 DROP CONSTRAINT check_a" +== 1414 +-- truncate_limit: 100 +-- thusly, scan won't be skipped +INSERT INTO part_7 (a, b) VALUES (8, null), (9, 'a') +-- +TABLE: name="part_7" schema="" table="part_7" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_7 (a, b) VALUES (8, NULL), (9, 'a')" +== 1415 +-- truncate_limit: 100 +SELECT tableoid::regclass, a, b FROM part_7 order by a +-- +TABLE: name="part_7" schema="" table="part_7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, a, b FROM part_7 ORDER BY a" +== 1416 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7)" +== 1417 +-- truncate_limit: 100 +-- check that leaf partitions of default partition are scanned when +-- attaching a partitioned table. +ALTER TABLE part_5 DROP CONSTRAINT check_a +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_5 DROP CONSTRAINT check_a" +== 1418 +-- truncate_limit: 100 +CREATE TABLE part5_def PARTITION OF part_5 DEFAULT PARTITION BY LIST(a) +-- +TABLE: name="part5_def" schema="" table="part5_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part5_def PARTITION OF part_5 DEFAULT PARTITION BY LIST (a)" +== 1419 +-- truncate_limit: 100 +CREATE TABLE part5_def_p1 PARTITION OF part5_def FOR VALUES IN (5) +-- +TABLE: name="part5_def_p1" schema="" table="part5_def_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part5_def_p1 PARTITION OF part5_def FOR VALUES IN (5)" +== 1420 +-- truncate_limit: 100 +INSERT INTO part5_def_p1 VALUES (5, 'y') +-- +TABLE: name="part5_def_p1" schema="" table="part5_def_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part5_def_p1 VALUES (5, 'y')" +== 1421 +-- truncate_limit: 100 +CREATE TABLE part5_p1 (LIKE part_5) +-- +TABLE: name="part5_p1" schema="" table="part5_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part5_p1 (LIKE part_5)" +== 1422 +-- truncate_limit: 100 +ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y') +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y')" +== 1423 +-- truncate_limit: 100 +-- should be ok after deleting the bad row +DELETE FROM part5_def_p1 WHERE b = 'y' +-- +TABLE: name="part5_def_p1" schema="" table="part5_def_p1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM part5_def_p1 WHERE b = 'y'" +== 1424 +-- truncate_limit: 100 +ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y') +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y')" +== 1425 +-- truncate_limit: 100 +-- check that the table being attached is not already a partition +ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2)" +== 1426 +-- truncate_limit: 100 +-- check that circular inheritance is not allowed +ALTER TABLE part_5 ATTACH PARTITION list_parted2 FOR VALUES IN ('b') +-- +TABLE: name="part_5" schema="" table="part_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_5 ATTACH PARTITION list_parted2 FOR VALUES IN ('b')" +== 1427 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ATTACH PARTITION list_parted2 FOR VALUES IN (0) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ATTACH PARTITION list_parted2 FOR VALUES IN (0)" +== 1428 +-- truncate_limit: 100 +-- If a partitioned table being created or an existing table being attached +-- as a partition does not have a constraint that would allow validation scan +-- to be skipped, but an individual partition does, then the partition's +-- validation scan is skipped. +CREATE TABLE quuux (a int, b text) PARTITION BY LIST (a) +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quuux (a int, b text) PARTITION BY LIST (a)" +== 1429 +-- truncate_limit: 100 +CREATE TABLE quuux_default PARTITION OF quuux DEFAULT PARTITION BY LIST (b) +-- +TABLE: name="quuux_default" schema="" table="quuux_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quuux_default PARTITION OF quuux DEFAULT PARTITION BY LIST (b)" +== 1430 +-- truncate_limit: 100 +CREATE TABLE quuux_default1 PARTITION OF quuux_default ( + CONSTRAINT check_1 CHECK (a IS NOT NULL AND a = 1) +) FOR VALUES IN ('b') +-- +TABLE: name="quuux_default1" schema="" table="quuux_default1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quuux_default1 PARTITION OF quuux_default (CONSTRAINT check_1 CHECK (a IS NOT NULL A..." +== 1431 +-- truncate_limit: 100 +CREATE TABLE quuux1 (a int, b text) +-- +TABLE: name="quuux1" schema="" table="quuux1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quuux1 (a int, b text)" +== 1432 +-- truncate_limit: 100 +ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1) +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1)" +== 1433 +-- truncate_limit: 100 +-- validate! +CREATE TABLE quuux2 (a int, b text) +-- +TABLE: name="quuux2" schema="" table="quuux2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quuux2 (a int, b text)" +== 1434 +-- truncate_limit: 100 +ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2) +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2)" +== 1435 +-- truncate_limit: 100 +-- skip validation +DROP TABLE quuux1, quuux2 +-- +TABLE: name="quuux1" schema="" table="quuux1" ctx=DDL +TABLE: name="quuux2" schema="" table="quuux2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE quuux1, quuux2" +== 1436 +-- truncate_limit: 100 +-- should validate for quuux1, but not for quuux2 +CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1) +-- +TABLE: name="quuux1" schema="" table="quuux1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1)" +== 1437 +-- truncate_limit: 100 +CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2) +-- +TABLE: name="quuux2" schema="" table="quuux2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2)" +== 1438 +-- truncate_limit: 100 +DROP TABLE quuux +-- +TABLE: name="quuux" schema="" table="quuux" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE quuux" +== 1439 +-- truncate_limit: 100 +-- check validation when attaching hash partitions + +-- Use hand-rolled hash functions and operator class to get predictable result +-- on different machines. part_test_int4_ops is defined in test_setup.sql. + +-- check that the new partition won't overlap with an existing partition +CREATE TABLE hash_parted ( + a int, + b int +) PARTITION BY HASH (a part_test_int4_ops) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_parted (a int, b int) PARTITION BY HASH (a part_test_int4_ops)" +== 1440 +-- truncate_limit: 100 +CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 0) +-- +TABLE: name="hpart_1" schema="" table="hpart_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 0)" +== 1441 +-- truncate_limit: 100 +CREATE TABLE fail_part (LIKE hpart_1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (LIKE hpart_1)" +== 1442 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 4) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 4)" +== 1443 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 0) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 0)" +== 1444 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1445 +-- truncate_limit: 100 +-- check validation when attaching hash partitions + +-- check that violating rows are correctly reported +CREATE TABLE hpart_2 (LIKE hash_parted) +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_2 (LIKE hash_parted)" +== 1446 +-- truncate_limit: 100 +INSERT INTO hpart_2 VALUES (3, 0) +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart_2 VALUES (3, 0)" +== 1447 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1)" +== 1448 +-- truncate_limit: 100 +-- should be ok after deleting the bad row +DELETE FROM hpart_2 +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM hpart_2" +== 1449 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1)" +== 1450 +-- truncate_limit: 100 +-- check that leaf partitions are scanned when attaching a partitioned +-- table +CREATE TABLE hpart_5 ( + LIKE hash_parted +) PARTITION BY LIST (b) +-- +TABLE: name="hpart_5" schema="" table="hpart_5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_5 (LIKE hash_parted) PARTITION BY LIST (b)" +== 1451 +-- truncate_limit: 100 +-- check that violating rows are correctly reported +CREATE TABLE hpart_5_a PARTITION OF hpart_5 FOR VALUES IN ('1', '2', '3') +-- +TABLE: name="hpart_5_a" schema="" table="hpart_5_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_5_a PARTITION OF hpart_5 FOR VALUES IN ('1', '2', '3')" +== 1452 +-- truncate_limit: 100 +INSERT INTO hpart_5_a (a, b) VALUES (7, 1) +-- +TABLE: name="hpart_5_a" schema="" table="hpart_5_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart_5_a (a, b) VALUES (7, 1)" +== 1453 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2)" +== 1454 +-- truncate_limit: 100 +-- should be ok after deleting the bad row +DELETE FROM hpart_5_a +-- +TABLE: name="hpart_5_a" schema="" table="hpart_5_a" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM hpart_5_a" +== 1455 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2)" +== 1456 +-- truncate_limit: 100 +-- check that the table being attach is with valid modulus and remainder value +CREATE TABLE fail_part(LIKE hash_parted) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part (LIKE hash_parted)" +== 1457 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 0, REMAINDER 1) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 0, REMAINDER 1)" +== 1458 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 8) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 8)" +== 1459 +-- truncate_limit: 100 +ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 3, REMAINDER 2)" +== 1460 +-- truncate_limit: 100 +DROP TABLE fail_part +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_part" +== 1461 +-- truncate_limit: 100 +|-- +-- DETACH PARTITION +|-- + +-- check that the table is partitioned at all +CREATE TABLE regular_table (a int) +-- +TABLE: name="regular_table" schema="" table="regular_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE regular_table (a int)" +== 1462 +-- truncate_limit: 100 +ALTER TABLE regular_table DETACH PARTITION any_name +-- +TABLE: name="regular_table" schema="" table="regular_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE regular_table DETACH PARTITION any_name" +== 1463 +-- truncate_limit: 100 +DROP TABLE regular_table +-- +TABLE: name="regular_table" schema="" table="regular_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE regular_table" +== 1464 +-- truncate_limit: 100 +-- check that the partition being detached exists at all +ALTER TABLE list_parted2 DETACH PARTITION part_4 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DETACH PARTITION part_4" +== 1465 +-- truncate_limit: 100 +ALTER TABLE hash_parted DETACH PARTITION hpart_4 +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted DETACH PARTITION hpart_4" +== 1466 +-- truncate_limit: 100 +-- check that the partition being detached is actually a partition of the parent +CREATE TABLE not_a_part (a int) +-- +TABLE: name="not_a_part" schema="" table="not_a_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE not_a_part (a int)" +== 1467 +-- truncate_limit: 100 +ALTER TABLE list_parted2 DETACH PARTITION not_a_part +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DETACH PARTITION not_a_part" +== 1468 +-- truncate_limit: 100 +ALTER TABLE list_parted2 DETACH PARTITION part_1 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DETACH PARTITION part_1" +== 1469 +-- truncate_limit: 100 +ALTER TABLE hash_parted DETACH PARTITION not_a_part +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted DETACH PARTITION not_a_part" +== 1470 +-- truncate_limit: 100 +DROP TABLE not_a_part +-- +TABLE: name="not_a_part" schema="" table="not_a_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE not_a_part" +== 1471 +-- truncate_limit: 100 +-- check that, after being detached, attinhcount/coninhcount is dropped to 0 and +-- attislocal/conislocal is set to true +ALTER TABLE list_parted2 DETACH PARTITION part_3_4 +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DETACH PARTITION part_3_4" +== 1472 +-- truncate_limit: 100 +SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::regclass AND attnum > 0 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT attinhcount, attislocal FROM pg_attribute WHERE ..." +== 1473 +-- truncate_limit: 100 +SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::regclass AND conname = 'check_a' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT coninhcount, conislocal FROM pg_constraint WHERE ..." +== 1474 +-- truncate_limit: 100 +DROP TABLE part_3_4 +-- +TABLE: name="part_3_4" schema="" table="part_3_4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_3_4" +== 1475 +-- truncate_limit: 100 +-- check that a detached partition is not dropped on dropping a partitioned table +CREATE TABLE range_parted2 ( + a int +) PARTITION BY RANGE(a) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted2 (a int) PARTITION BY RANGE (a)" +== 1476 +-- truncate_limit: 100 +CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100) +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) TO (100)" +== 1477 +-- truncate_limit: 100 +ALTER TABLE range_parted2 DETACH PARTITION part_rp +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted2 DETACH PARTITION part_rp" +== 1478 +-- truncate_limit: 100 +DROP TABLE range_parted2 +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE range_parted2" +== 1479 +-- truncate_limit: 100 +SELECT * from part_rp +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_rp" +== 1480 +-- truncate_limit: 100 +DROP TABLE part_rp +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_rp" +== 1481 +-- truncate_limit: 100 +-- concurrent detach +CREATE TABLE range_parted2 ( + a int +) PARTITION BY RANGE(a) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted2 (a int) PARTITION BY RANGE (a)" +== 1482 +-- truncate_limit: 100 +CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100) +-- +TABLE: name="part_rp" schema="" table="part_rp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) TO (100)" +== 1483 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1484 +-- truncate_limit: 100 +-- doesn't work in a partition block +ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY" +== 1485 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1486 +-- truncate_limit: 100 +CREATE TABLE part_rpd PARTITION OF range_parted2 DEFAULT +-- +TABLE: name="part_rpd" schema="" table="part_rpd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_rpd PARTITION OF range_parted2 DEFAULT" +== 1487 +-- truncate_limit: 100 +-- doesn't work if there's a default partition +ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY" +== 1488 +-- truncate_limit: 100 +-- doesn't work for the default partition +ALTER TABLE range_parted2 DETACH PARTITION part_rpd CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted2 DETACH PARTITION part_rpd CONCURRENTLY" +== 1489 +-- truncate_limit: 100 +DROP TABLE part_rpd +-- +TABLE: name="part_rpd" schema="" table="part_rpd" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_rpd" +== 1490 +-- truncate_limit: 100 +-- works fine +ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY" +== 1491 +-- truncate_limit: 100 +-- constraint should be created +CREATE TABLE part_rp100 PARTITION OF range_parted2 (CHECK (a>=123 AND a<133 AND a IS NOT NULL)) FOR VALUES FROM (100) to (200) +-- +TABLE: name="part_rp100" schema="" table="part_rp100" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_rp100 PARTITION OF range_parted2 (CHECK (a >= 123 AND a < 133 AND a IS NOT NULL..." +== 1492 +-- truncate_limit: 100 +ALTER TABLE range_parted2 DETACH PARTITION part_rp100 CONCURRENTLY +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted2 DETACH PARTITION part_rp100 CONCURRENTLY" +== 1493 +-- truncate_limit: 100 +-- redundant constraint should not be created +DROP TABLE range_parted2 +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE range_parted2" +== 1494 +-- truncate_limit: 100 +-- Test that hash partitions continue to work after they're concurrently +-- detached (bugs #18371, #19070) +CREATE TABLE hash_parted2 (a int) PARTITION BY HASH(a) +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_parted2 (a int) PARTITION BY HASH (a)" +== 1495 +-- truncate_limit: 100 +CREATE TABLE part_hp PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="part_hp" schema="" table="part_hp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_hp PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 1496 +-- truncate_limit: 100 +ALTER TABLE hash_parted2 DETACH PARTITION part_hp CONCURRENTLY +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE hash_parted2 DETACH PARTITION part_hp CONCURRENTLY" +== 1497 +-- truncate_limit: 100 +DROP TABLE hash_parted2 +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_parted2" +== 1498 +-- truncate_limit: 100 +INSERT INTO part_hp VALUES (1) +-- +TABLE: name="part_hp" schema="" table="part_hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_hp VALUES (1)" +== 1499 +-- truncate_limit: 100 +DROP TABLE part_hp +-- +TABLE: name="part_hp" schema="" table="part_hp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_hp" +== 1500 +-- truncate_limit: 100 +-- Check ALTER TABLE commands for partitioned tables and partitions + +-- cannot add/drop column to/from *only* the parent +ALTER TABLE ONLY list_parted2 ADD COLUMN c int +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY list_parted2 ADD COLUMN c int" +== 1501 +-- truncate_limit: 100 +ALTER TABLE ONLY list_parted2 DROP COLUMN b +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY list_parted2 DROP b" +== 1502 +-- truncate_limit: 100 +-- cannot add a column to partition or drop an inherited one +ALTER TABLE part_2 ADD COLUMN c text +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_2 ADD COLUMN c text" +== 1503 +-- truncate_limit: 100 +ALTER TABLE part_2 DROP COLUMN b +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_2 DROP b" +== 1504 +-- truncate_limit: 100 +-- Nor rename, alter type +ALTER TABLE part_2 RENAME COLUMN b to c +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE part_2 RENAME COLUMN b TO c" +== 1505 +-- truncate_limit: 100 +ALTER TABLE part_2 ALTER COLUMN b TYPE text +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_2 ALTER COLUMN b TYPE text" +== 1506 +-- truncate_limit: 100 +-- cannot add/drop NOT NULL or check constraints to *only* the parent, when +-- partitions exist +ALTER TABLE ONLY list_parted2 ALTER b SET NOT NULL +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY list_parted2 ALTER COLUMN b SET NOT NULL" +== 1507 +-- truncate_limit: 100 +ALTER TABLE ONLY list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz') +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz')" +== 1508 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ALTER b SET NOT NULL +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ALTER COLUMN b SET NOT NULL" +== 1509 +-- truncate_limit: 100 +ALTER TABLE ONLY list_parted2 ALTER b DROP NOT NULL +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY list_parted2 ALTER COLUMN b DROP NOT NULL" +== 1510 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz') +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz')" +== 1511 +-- truncate_limit: 100 +ALTER TABLE ONLY list_parted2 DROP CONSTRAINT check_b +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY list_parted2 DROP CONSTRAINT check_b" +== 1512 +-- truncate_limit: 100 +-- It's alright though, if no partitions are yet created +CREATE TABLE parted_no_parts (a int) PARTITION BY LIST (a) +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_no_parts (a int) PARTITION BY LIST (a)" +== 1513 +-- truncate_limit: 100 +ALTER TABLE ONLY parted_no_parts ALTER a SET NOT NULL +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parted_no_parts ALTER COLUMN a SET NOT NULL" +== 1514 +-- truncate_limit: 100 +ALTER TABLE ONLY parted_no_parts ADD CONSTRAINT check_a CHECK (a > 0) +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parted_no_parts ADD CONSTRAINT check_a CHECK (a > 0)" +== 1515 +-- truncate_limit: 100 +ALTER TABLE ONLY parted_no_parts ALTER a DROP NOT NULL +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parted_no_parts ALTER COLUMN a DROP NOT NULL" +== 1516 +-- truncate_limit: 100 +ALTER TABLE ONLY parted_no_parts DROP CONSTRAINT check_a +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parted_no_parts DROP CONSTRAINT check_a" +== 1517 +-- truncate_limit: 100 +DROP TABLE parted_no_parts +-- +TABLE: name="parted_no_parts" schema="" table="parted_no_parts" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_no_parts" +== 1518 +-- truncate_limit: 100 +-- cannot drop inherited NOT NULL or check constraints from partition +ALTER TABLE list_parted2 ALTER b SET NOT NULL, ADD CONSTRAINT check_a2 CHECK (a > 0) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ALTER COLUMN b SET NOT NULL, ADD CONSTRAINT check_a2 CHECK (a > 0)" +== 1519 +-- truncate_limit: 100 +ALTER TABLE part_2 ALTER b DROP NOT NULL +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_2 ALTER COLUMN b DROP NOT NULL" +== 1520 +-- truncate_limit: 100 +ALTER TABLE part_2 DROP CONSTRAINT check_a2 +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_2 DROP CONSTRAINT check_a2" +== 1521 +-- truncate_limit: 100 +-- Doesn't make sense to add NO INHERIT constraints on partitioned tables +ALTER TABLE list_parted2 add constraint check_b2 check (b <> 'zz') NO INHERIT +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ADD CONSTRAINT check_b2 CHECK (b <> 'zz') NO INHERIT" +== 1522 +-- truncate_limit: 100 +-- check that a partition cannot participate in regular inheritance +CREATE TABLE inh_test () INHERITS (part_2) +-- +TABLE: name="inh_test" schema="" table="inh_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_test () INHERITS (part_2)" +== 1523 +-- truncate_limit: 100 +CREATE TABLE inh_test (LIKE part_2) +-- +TABLE: name="inh_test" schema="" table="inh_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_test (LIKE part_2)" +== 1524 +-- truncate_limit: 100 +ALTER TABLE inh_test INHERIT part_2 +-- +TABLE: name="inh_test" schema="" table="inh_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inh_test INHERIT part_2" +== 1525 +-- truncate_limit: 100 +ALTER TABLE part_2 INHERIT inh_test +-- +TABLE: name="part_2" schema="" table="part_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_2 INHERIT inh_test" +== 1526 +-- truncate_limit: 100 +-- cannot drop or alter type of partition key columns of lower level +-- partitioned tables; for example, part_5, which is list_parted2's +-- partition, is partitioned on b; +ALTER TABLE list_parted2 DROP COLUMN b +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 DROP b" +== 1527 +-- truncate_limit: 100 +ALTER TABLE list_parted2 ALTER COLUMN b TYPE text +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted2 ALTER COLUMN b TYPE text" +== 1528 +-- truncate_limit: 100 +-- dropping non-partition key columns should be allowed on the parent table. +ALTER TABLE list_parted DROP COLUMN b +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted DROP b" +== 1529 +-- truncate_limit: 100 +SELECT * FROM list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM list_parted" +== 1530 +-- truncate_limit: 100 +-- cleanup +DROP TABLE list_parted, list_parted2, range_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE list_parted, list_parted2, range_parted" +== 1531 +-- truncate_limit: 100 +DROP TABLE fail_def_part +-- +TABLE: name="fail_def_part" schema="" table="fail_def_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fail_def_part" +== 1532 +-- truncate_limit: 100 +DROP TABLE hash_parted +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_parted" +== 1533 +-- truncate_limit: 100 +-- more tests for certain multi-level partitioning scenarios +create table p (a int, b int) partition by range (a, b) +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p (a int, b int) PARTITION BY RANGE (a, b)" +== 1534 +-- truncate_limit: 100 +create table p1 (b int, a int not null) partition by range (b) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (b int, a int NOT NULL) PARTITION BY RANGE (b)" +== 1535 +-- truncate_limit: 100 +create table p11 (like p1) +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p11 (LIKE p1)" +== 1536 +-- truncate_limit: 100 +alter table p11 drop a +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p11 DROP a" +== 1537 +-- truncate_limit: 100 +alter table p11 add a int +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p11 ADD COLUMN a int" +== 1538 +-- truncate_limit: 100 +alter table p11 drop a +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p11 DROP a" +== 1539 +-- truncate_limit: 100 +alter table p11 add a int not null +-- +TABLE: name="p11" schema="" table="p11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p11 ADD COLUMN a int NOT NULL" +== 1540 +-- truncate_limit: 100 +-- attnum for key attribute 'a' is different in p, p1, and p11 +select attrelid::regclass, attname, attnum +from pg_attribute +where attname = 'a' + and (attrelid = 'p'::regclass + or attrelid = 'p1'::regclass + or attrelid = 'p11'::regclass) +order by attrelid::regclass::text +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attname" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE ... ORDER BY attrelid::regclass::text" +== 1541 +-- truncate_limit: 100 +alter table p1 attach partition p11 for values from (2) to (5) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 ATTACH PARTITION p11 FOR VALUES FROM (2) TO (5)" +== 1542 +-- truncate_limit: 100 +insert into p1 (a, b) values (2, 3) +-- +TABLE: name="p1" schema="" table="p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO p1 (a, b) VALUES (2, 3)" +== 1543 +-- truncate_limit: 100 +-- check that partition validation scan correctly detects violating rows +alter table p attach partition p1 for values from (1, 2) to (1, 10) +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p ATTACH PARTITION p1 FOR VALUES FROM (1, 2) TO (1, 10)" +== 1544 +-- truncate_limit: 100 +-- cleanup +drop table p +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p" +== 1545 +-- truncate_limit: 100 +drop table p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1" +== 1546 +-- truncate_limit: 100 +-- validate constraint on partitioned tables should only scan leaf partitions +create table parted_validate_test (a int) partition by list (a) +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_validate_test (a int) PARTITION BY LIST (a)" +== 1547 +-- truncate_limit: 100 +create table parted_validate_test_1 partition of parted_validate_test for values in (0, 1) +-- +TABLE: name="parted_validate_test_1" schema="" table="parted_validate_test_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_validate_test_1 PARTITION OF parted_validate_test FOR VALUES IN (0, 1)" +== 1548 +-- truncate_limit: 100 +alter table parted_validate_test add constraint parted_validate_test_chka check (a > 0) not valid +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_validate_test ADD CONSTRAINT parted_validate_test_chka CHECK (a > 0) NOT VALID" +== 1549 +-- truncate_limit: 100 +alter table parted_validate_test validate constraint parted_validate_test_chka +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_validate_test VALIDATE CONSTRAINT parted_validate_test_chka" +== 1550 +-- truncate_limit: 100 +drop table parted_validate_test +-- +TABLE: name="parted_validate_test" schema="" table="parted_validate_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_validate_test" +== 1551 +-- truncate_limit: 100 +-- test alter column options +CREATE TABLE attmp(i integer) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attmp (i int)" +== 1552 +-- truncate_limit: 100 +INSERT INTO attmp VALUES (1) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attmp VALUES (1)" +== 1553 +-- truncate_limit: 100 +ALTER TABLE attmp ALTER COLUMN i SET (n_distinct = 1, n_distinct_inherited = 2) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ALTER COLUMN i SET (n_distinct=1, n_distinct_inherited=2)" +== 1554 +-- truncate_limit: 100 +ALTER TABLE attmp ALTER COLUMN i RESET (n_distinct_inherited) +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attmp ALTER COLUMN i RESET (n_distinct_inherited)" +== 1555 +-- truncate_limit: 100 +ANALYZE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE attmp" +== 1556 +-- truncate_limit: 100 +DROP TABLE attmp +-- +TABLE: name="attmp" schema="" table="attmp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attmp" +== 1557 +-- truncate_limit: 100 +DROP USER regress_alter_table_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_alter_table_user1" +== 1558 +-- truncate_limit: 100 +-- check that violating rows are correctly reported when attaching as the +-- default partition +create table defpart_attach_test (a int) partition by list (a) +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defpart_attach_test (a int) PARTITION BY LIST (a)" +== 1559 +-- truncate_limit: 100 +create table defpart_attach_test1 partition of defpart_attach_test for values in (1) +-- +TABLE: name="defpart_attach_test1" schema="" table="defpart_attach_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defpart_attach_test1 PARTITION OF defpart_attach_test FOR VALUES IN (1)" +== 1560 +-- truncate_limit: 100 +create table defpart_attach_test_d (b int, a int) +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defpart_attach_test_d (b int, a int)" +== 1561 +-- truncate_limit: 100 +alter table defpart_attach_test_d drop b +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defpart_attach_test_d DROP b" +== 1562 +-- truncate_limit: 100 +insert into defpart_attach_test_d values (1), (2) +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defpart_attach_test_d VALUES (1), (2)" +== 1563 +-- truncate_limit: 100 +-- error because its constraint as the default partition would be violated +-- by the row containing 1 +alter table defpart_attach_test attach partition defpart_attach_test_d default +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defpart_attach_test ATTACH PARTITION defpart_attach_test_d DEFAULT" +== 1564 +-- truncate_limit: 100 +delete from defpart_attach_test_d where a = 1 +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM defpart_attach_test_d WHERE a = 1" +== 1565 +-- truncate_limit: 100 +alter table defpart_attach_test_d add check (a > 1) +-- +TABLE: name="defpart_attach_test_d" schema="" table="defpart_attach_test_d" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defpart_attach_test_d ADD CHECK (a > 1)" +== 1566 +-- truncate_limit: 100 +-- should be attached successfully and without needing to be scanned +alter table defpart_attach_test attach partition defpart_attach_test_d default +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defpart_attach_test ATTACH PARTITION defpart_attach_test_d DEFAULT" +== 1567 +-- truncate_limit: 100 +-- check that attaching a partition correctly reports any rows in the default +-- partition that should not be there for the new partition to be attached +-- successfully +create table defpart_attach_test_2 (like defpart_attach_test_d) +-- +TABLE: name="defpart_attach_test_2" schema="" table="defpart_attach_test_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defpart_attach_test_2 (LIKE defpart_attach_test_d)" +== 1568 +-- truncate_limit: 100 +alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2) +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defpart_attach_test ATTACH PARTITION defpart_attach_test_2 FOR VALUES IN (2)" +== 1569 +-- truncate_limit: 100 +drop table defpart_attach_test +-- +TABLE: name="defpart_attach_test" schema="" table="defpart_attach_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE defpart_attach_test" +== 1570 +-- truncate_limit: 100 +-- check combinations of temporary and permanent relations when attaching +-- partitions. +create table perm_part_parent (a int) partition by list (a) +-- +TABLE: name="perm_part_parent" schema="" table="perm_part_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE perm_part_parent (a int) PARTITION BY LIST (a)" +== 1571 +-- truncate_limit: 100 +create temp table temp_part_parent (a int) partition by list (a) +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_part_parent (a int) PARTITION BY LIST (a)" +== 1572 +-- truncate_limit: 100 +create table perm_part_child (a int) +-- +TABLE: name="perm_part_child" schema="" table="perm_part_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE perm_part_child (a int)" +== 1573 +-- truncate_limit: 100 +create temp table temp_part_child (a int) +-- +TABLE: name="temp_part_child" schema="" table="temp_part_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_part_child (a int)" +== 1574 +-- truncate_limit: 100 +alter table temp_part_parent attach partition perm_part_child default +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE temp_part_parent ATTACH PARTITION perm_part_child DEFAULT" +== 1575 +-- truncate_limit: 100 +-- error +alter table perm_part_parent attach partition temp_part_child default +-- +TABLE: name="perm_part_parent" schema="" table="perm_part_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE perm_part_parent ATTACH PARTITION temp_part_child DEFAULT" +== 1576 +-- truncate_limit: 100 +-- error +alter table temp_part_parent attach partition temp_part_child default +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE temp_part_parent ATTACH PARTITION temp_part_child DEFAULT" +== 1577 +-- truncate_limit: 100 +-- ok +drop table perm_part_parent cascade +-- +TABLE: name="perm_part_parent" schema="" table="perm_part_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE perm_part_parent CASCADE" +== 1578 +-- truncate_limit: 100 +drop table temp_part_parent cascade +-- +TABLE: name="temp_part_parent" schema="" table="temp_part_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_part_parent CASCADE" +== 1579 +-- truncate_limit: 100 +-- check that attaching partitions to a table while it is being used is +-- prevented +create table tab_part_attach (a int) partition by list (a) +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tab_part_attach (a int) PARTITION BY LIST (a)" +== 1580 +-- truncate_limit: 100 +create or replace function func_part_attach() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_attach_1 (a int)'; + execute 'alter table tab_part_attach attach partition tab_part_attach_1 for values in (1)'; + return null; + end $$ +-- +FUNCTION: name="func_part_attach" function="func_part_attach" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION func_part_attach() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n ..." +== 1581 +-- truncate_limit: 100 +create trigger trig_part_attach before insert on tab_part_attach + for each statement execute procedure func_part_attach() +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_part_attach BEFORE INSERT ON tab_part_attach EXECUTE FUNCTION func_part_attach()" +== 1582 +-- truncate_limit: 100 +insert into tab_part_attach values (1) +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tab_part_attach VALUES (1)" +== 1583 +-- truncate_limit: 100 +drop table tab_part_attach +-- +TABLE: name="tab_part_attach" schema="" table="tab_part_attach" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tab_part_attach" +== 1584 +-- truncate_limit: 100 +drop function func_part_attach() +-- +FUNCTION: name="func_part_attach" function="func_part_attach" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION func_part_attach()" +== 1585 +-- truncate_limit: 100 +-- test case where the partitioning operator is a SQL function whose +-- evaluation results in the table's relcache being rebuilt partway through +-- the execution of an ATTACH PARTITION command +create function at_test_sql_partop (int4, int4) returns int language sql +as $$ select case when $1 = $2 then 0 when $1 > $2 then 1 else -1 end; $$ +-- +FUNCTION: name="at_test_sql_partop" function="at_test_sql_partop" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION at_test_sql_partop(int4, int4) RETURNS int LANGUAGE sql AS $$ select case when $1..." +== 1586 +-- truncate_limit: 100 +create operator class at_test_sql_partop for type int4 using btree as + operator 1 < (int4, int4), operator 2 <= (int4, int4), + operator 3 = (int4, int4), operator 4 >= (int4, int4), + operator 5 > (int4, int4), function 1 at_test_sql_partop(int4, int4) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS at_test_sql_partop FOR TYPE int4 USING btree AS OPERATOR 1 <(int4, int4), O..." +== 1587 +-- truncate_limit: 100 +create table at_test_sql_partop (a int) partition by range (a at_test_sql_partop) +-- +TABLE: name="at_test_sql_partop" schema="" table="at_test_sql_partop" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_test_sql_partop (a int) PARTITION BY RANGE (a at_test_sql_partop)" +== 1588 +-- truncate_limit: 100 +create table at_test_sql_partop_1 (a int) +-- +TABLE: name="at_test_sql_partop_1" schema="" table="at_test_sql_partop_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE at_test_sql_partop_1 (a int)" +== 1589 +-- truncate_limit: 100 +alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values from (0) to (10) +-- +TABLE: name="at_test_sql_partop" schema="" table="at_test_sql_partop" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE at_test_sql_partop ATTACH PARTITION at_test_sql_partop_1 FOR VALUES FROM (0) TO (10)" +== 1590 +-- truncate_limit: 100 +drop table at_test_sql_partop +-- +TABLE: name="at_test_sql_partop" schema="" table="at_test_sql_partop" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE at_test_sql_partop" +== 1591 +-- truncate_limit: 100 +drop operator class at_test_sql_partop using btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS at_test_sql_partop USING btree" +== 1592 +-- truncate_limit: 100 +drop function at_test_sql_partop +-- +FUNCTION: name="at_test_sql_partop" function="at_test_sql_partop" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION at_test_sql_partop" +== 1593 +-- truncate_limit: 100 +/* Test case for bug #16242 */ + +-- We create a parent and child where the child has missing +-- non-null attribute values, and arrange to pass them through +-- tuple conversion from the child to the parent tupdesc +create table bar1 (a integer, b integer not null default 1) + partition by range (a) +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bar1 (a int, b int NOT NULL DEFAULT 1) PARTITION BY RANGE (a)" +== 1594 +-- truncate_limit: 100 +create table bar2 (a integer) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bar2 (a int)" +== 1595 +-- truncate_limit: 100 +insert into bar2 values (1) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar2 VALUES (1)" +== 1596 +-- truncate_limit: 100 +alter table bar2 add column b integer not null default 1 +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bar2 ADD COLUMN b int NOT NULL DEFAULT 1" +== 1597 +-- truncate_limit: 100 +-- (at this point bar2 contains tuple with natts=1) +alter table bar1 attach partition bar2 default +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bar1 ATTACH PARTITION bar2 DEFAULT" +== 1598 +-- truncate_limit: 100 +-- this works: +select * from bar1 +-- +TABLE: name="bar1" schema="" table="bar1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bar1" +== 1599 +-- truncate_limit: 100 +-- this exercises tuple conversion: +create function xtrig() + returns trigger language plpgsql +as $$ + declare + r record; + begin + for r in select * from old loop + raise info 'a=%, b=%', r.a, r.b; + end loop; + return NULL; + end; +$$ +-- +FUNCTION: name="xtrig" function="xtrig" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION xtrig() RETURNS trigger LANGUAGE plpgsql AS $$\n declare\n r record;\n begin\n ..." +== 1600 +-- truncate_limit: 100 +create trigger xtrig + after update on bar1 + referencing old table as old + for each statement execute procedure xtrig() +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER xtrig AFTER UPDATE ON bar1 REFERENCING OLD TABLE old EXECUTE FUNCTION xtrig()" +== 1601 +-- truncate_limit: 100 +update bar1 set a = a + 1 +-- +TABLE: name="bar1" schema="" table="bar1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE bar1 SET a = a + 1" +== 1602 +-- truncate_limit: 100 +/* End test case for bug #16242 */ + +/* Test case for bug #17409 */ + +create table attbl (p1 int constraint pk_attbl primary key) +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attbl (p1 int CONSTRAINT pk_attbl PRIMARY KEY)" +== 1603 +-- truncate_limit: 100 +create table atref (c1 int references attbl(p1)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atref (c1 int REFERENCES attbl (p1))" +== 1604 +-- truncate_limit: 100 +cluster attbl using pk_attbl +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER attbl USING pk_attbl" +== 1605 +-- truncate_limit: 100 +alter table attbl alter column p1 set data type bigint +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attbl ALTER COLUMN p1 TYPE bigint" +== 1606 +-- truncate_limit: 100 +alter table atref alter column c1 set data type bigint +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atref ALTER COLUMN c1 TYPE bigint" +== 1607 +-- truncate_limit: 100 +drop table attbl, atref +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attbl, atref" +== 1608 +-- truncate_limit: 100 +create table attbl (p1 int constraint pk_attbl primary key) +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attbl (p1 int CONSTRAINT pk_attbl PRIMARY KEY)" +== 1609 +-- truncate_limit: 100 +alter table attbl replica identity using index pk_attbl +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attbl REPLICA IDENTITY USING INDEX pk_attbl" +== 1610 +-- truncate_limit: 100 +create table atref (c1 int references attbl(p1)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atref (c1 int REFERENCES attbl (p1))" +== 1611 +-- truncate_limit: 100 +alter table attbl alter column p1 set data type bigint +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attbl ALTER COLUMN p1 TYPE bigint" +== 1612 +-- truncate_limit: 100 +alter table atref alter column c1 set data type bigint +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atref ALTER COLUMN c1 TYPE bigint" +== 1613 +-- truncate_limit: 100 +drop table attbl, atref +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attbl, atref" +== 1614 +-- truncate_limit: 100 +/* End test case for bug #17409 */ + +/* Test case for bug #18970 */ + +create table attbl(a int) +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attbl (a int)" +== 1615 +-- truncate_limit: 100 +create table atref(b attbl check ((b).a is not null)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atref (b attbl CHECK ((b).a IS NOT NULL))" +== 1616 +-- truncate_limit: 100 +alter table attbl alter column a type numeric +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attbl ALTER COLUMN a TYPE numeric" +== 1617 +-- truncate_limit: 100 +-- someday this should work +alter table atref drop constraint atref_b_check +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atref DROP CONSTRAINT atref_b_check" +== 1618 +-- truncate_limit: 100 +create statistics atref_stat on ((b).a is not null) from atref +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS atref_stat ON ((b).a IS NOT NULL) FROM atref" +== 1619 +-- truncate_limit: 100 +alter table attbl alter column a type numeric +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attbl ALTER COLUMN a TYPE numeric" +== 1620 +-- truncate_limit: 100 +-- someday this should work +drop statistics atref_stat +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS atref_stat" +== 1621 +-- truncate_limit: 100 +create index atref_idx on atref (((b).a)) +-- +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX atref_idx ON atref USING btree (((b).a))" +== 1622 +-- truncate_limit: 100 +alter table attbl alter column a type numeric +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE attbl ALTER COLUMN a TYPE numeric" +== 1623 +-- truncate_limit: 100 +-- someday this should work +drop table attbl, atref +-- +TABLE: name="attbl" schema="" table="attbl" ctx=DDL +TABLE: name="atref" schema="" table="atref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE attbl, atref" +== 1624 +-- truncate_limit: 100 +/* End test case for bug #18970 */ + +-- Test that ALTER TABLE rewrite preserves a clustered index +-- for normal indexes and indexes on constraints. +create table alttype_cluster (a int) +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alttype_cluster (a int)" +== 1625 +-- truncate_limit: 100 +alter table alttype_cluster add primary key (a) +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alttype_cluster ADD PRIMARY KEY (a)" +== 1626 +-- truncate_limit: 100 +create index alttype_cluster_ind on alttype_cluster (a) +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX alttype_cluster_ind ON alttype_cluster USING btree (a)" +== 1627 +-- truncate_limit: 100 +alter table alttype_cluster cluster on alttype_cluster_ind +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alttype_cluster CLUSTER ON alttype_cluster_ind" +== 1628 +-- truncate_limit: 100 +-- Normal index remains clustered. +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE ... ORDER BY indexrelid::regclass::text" +== 1629 +-- truncate_limit: 100 +alter table alttype_cluster alter a type bigint +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alttype_cluster ALTER COLUMN a TYPE bigint" +== 1630 +-- truncate_limit: 100 +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE ... ORDER BY indexrelid::regclass::text" +== 1631 +-- truncate_limit: 100 +-- Constraint index remains clustered. +alter table alttype_cluster cluster on alttype_cluster_pkey +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alttype_cluster CLUSTER ON alttype_cluster_pkey" +== 1632 +-- truncate_limit: 100 +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE ... ORDER BY indexrelid::regclass::text" +== 1633 +-- truncate_limit: 100 +alter table alttype_cluster alter a type int +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alttype_cluster ALTER COLUMN a TYPE int" +== 1634 +-- truncate_limit: 100 +select indexrelid::regclass, indisclustered from pg_index + where indrelid = 'alttype_cluster'::regclass + order by indexrelid::regclass::text +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE ... ORDER BY indexrelid::regclass::text" +== 1635 +-- truncate_limit: 100 +drop table alttype_cluster +-- +TABLE: name="alttype_cluster" schema="" table="alttype_cluster" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE alttype_cluster" +== 1636 +-- truncate_limit: 100 +|-- +-- Check that attaching or detaching a partitioned partition correctly leads +-- to its partitions' constraint being updated to reflect the parent's +-- newly added/removed constraint +create table target_parted (a int, b int) partition by list (a) +-- +TABLE: name="target_parted" schema="" table="target_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE target_parted (a int, b int) PARTITION BY LIST (a)" +== 1637 +-- truncate_limit: 100 +create table attach_parted (a int, b int) partition by list (b) +-- +TABLE: name="attach_parted" schema="" table="attach_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attach_parted (a int, b int) PARTITION BY LIST (b)" +== 1638 +-- truncate_limit: 100 +create table attach_parted_part1 partition of attach_parted for values in (1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE attach_parted_part1 PARTITION OF attach_parted FOR VALUES IN (1)" +== 1639 +-- truncate_limit: 100 +-- insert a row directly into the leaf partition so that its partition +-- constraint is built and stored in the relcache +insert into attach_parted_part1 values (1, 1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attach_parted_part1 VALUES (1, 1)" +== 1640 +-- truncate_limit: 100 +-- the following better invalidate the partition constraint of the leaf +-- partition too... +alter table target_parted attach partition attach_parted for values in (1) +-- +TABLE: name="target_parted" schema="" table="target_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE target_parted ATTACH PARTITION attach_parted FOR VALUES IN (1)" +== 1641 +-- truncate_limit: 100 +-- ...such that the following insert fails +insert into attach_parted_part1 values (2, 1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attach_parted_part1 VALUES (2, 1)" +== 1642 +-- truncate_limit: 100 +-- ...and doesn't when the partition is detached along with its own partition +alter table target_parted detach partition attach_parted +-- +TABLE: name="target_parted" schema="" table="target_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE target_parted DETACH PARTITION attach_parted" +== 1643 +-- truncate_limit: 100 +insert into attach_parted_part1 values (2, 1) +-- +TABLE: name="attach_parted_part1" schema="" table="attach_parted_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO attach_parted_part1 VALUES (2, 1)" +== 1644 +-- truncate_limit: 100 +-- Test altering table having publication +create schema alter1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alter1" +== 1645 +-- truncate_limit: 100 +create schema alter2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA alter2" +== 1646 +-- truncate_limit: 100 +create table alter1.t1 (a int) +-- +TABLE: name="alter1.t1" schema="alter1" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alter1.t1 (a int)" +== 1647 +-- truncate_limit: 100 +set client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 1648 +-- truncate_limit: 100 +create publication pub1 for table alter1.t1, tables in schema alter2 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub1 FOR TABLE alter1.t1, TABLES IN SCHEMA alter2" +== 1649 +-- truncate_limit: 100 +reset client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 1650 +-- truncate_limit: 100 +alter table alter1.t1 set schema alter2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE alter1.t1 SET SCHEMA alter2" +== 1651 +-- truncate_limit: 100 +drop publication pub1 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub1" +== 1652 +-- truncate_limit: 100 +drop schema alter1 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA alter1 CASCADE" +== 1653 +-- truncate_limit: 100 +drop schema alter2 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA alter2 CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json b/parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json new file mode 100644 index 0000000..92b8f9e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json @@ -0,0 +1,14 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/amutils.test b/parser/testdata/summary_truncate/postgres_regress/amutils.test new file mode 100644 index 0000000..a0da3a2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/amutils.test @@ -0,0 +1,181 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test index AM property-reporting functions +|-- + +select prop, + pg_indexam_has_property(a.oid, prop) as "AM", + pg_index_has_property('onek_hundred'::regclass, prop) as "Index", + pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as "Column" + from pg_am a, + unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'can_order', 'can_unique', 'can_multi_col', + 'can_exclude', 'can_include', + 'bogus']::text[]) + with ordinality as u(prop,ord) + where a.amname = 'btree' + order by ord +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +FUNCTION: name="pg_indexam_has_property" function="pg_indexam_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_am a, unnest(ARRAY['asc', 'desc', 'nulls_first', 'nulls_last', 'orderable', 'd..." +== 002 +-- truncate_limit: 100 +select prop, + pg_indexam_has_property(a.oid, prop) as "AM", + pg_index_has_property('gcircleind'::regclass, prop) as "Index", + pg_index_column_has_property('gcircleind'::regclass, 1, prop) as "Column" + from pg_am a, + unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'can_order', 'can_unique', 'can_multi_col', + 'can_exclude', 'can_include', + 'bogus']::text[]) + with ordinality as u(prop,ord) + where a.amname = 'gist' + order by ord +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +FUNCTION: name="pg_indexam_has_property" function="pg_indexam_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_am a, unnest(ARRAY['asc', 'desc', 'nulls_first', 'nulls_last', 'orderable', 'd..." +== 003 +-- truncate_limit: 100 +select prop, + pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as btree, + pg_index_column_has_property('hash_i4_index'::regclass, 1, prop) as hash, + pg_index_column_has_property('gcircleind'::regclass, 1, prop) as gist, + pg_index_column_has_property('sp_radix_ind'::regclass, 1, prop) as spgist_radix, + pg_index_column_has_property('sp_quad_ind'::regclass, 1, prop) as spgist_quad, + pg_index_column_has_property('botharrayidx'::regclass, 1, prop) as gin, + pg_index_column_has_property('brinidx'::regclass, 1, prop) as brin + from unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'bogus']::text[]) + with ordinality as u(prop,ord) + order by ord +-- +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY['asc', 'desc', 'nulls_first', 'nulls_last', 'orderable', 'distance_o..." +== 004 +-- truncate_limit: 100 +select prop, + pg_index_has_property('onek_hundred'::regclass, prop) as btree, + pg_index_has_property('hash_i4_index'::regclass, prop) as hash, + pg_index_has_property('gcircleind'::regclass, prop) as gist, + pg_index_has_property('sp_radix_ind'::regclass, prop) as spgist, + pg_index_has_property('botharrayidx'::regclass, prop) as gin, + pg_index_has_property('brinidx'::regclass, prop) as brin + from unnest(array['clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'bogus']::text[]) + with ordinality as u(prop,ord) + order by ord +-- +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="pg_index_has_property" function="pg_index_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY['clusterable', 'index_scan', 'bitmap_scan', 'backward_scan', 'bogus'..." +== 005 +-- truncate_limit: 100 +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', + 'can_exclude', 'can_include', 'bogus']::text[]) + with ordinality as u(prop,ord) + where amtype = 'i' + order by amname, ord +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +FUNCTION: name="pg_indexam_has_property" function="pg_indexam_has_property" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="amtype" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_am a, unnest(ARRAY['can_order', 'can_unique', 'can_multi_col', 'can_exclude', ..." +== 006 +-- truncate_limit: 100 +|-- +-- additional checks for pg_index_column_has_property +|-- +CREATE TEMP TABLE foo (f1 int, f2 int, f3 int, f4 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (f1 int, f2 int, f3 int, f4 int)" +== 007 +-- truncate_limit: 100 +CREATE INDEX fooindex ON foo (f1 desc, f2 asc, f3 nulls first, f4 nulls last) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fooindex ON foo USING btree (f1 DESC, f2 ASC, f3 NULLS FIRST, f4 NULLS LAST)" +== 008 +-- truncate_limit: 100 +select col, prop, pg_index_column_has_property(o, col, prop) + from (values ('fooindex'::regclass)) v1(o), + (values (1,'orderable'),(2,'asc'),(3,'desc'), + (4,'nulls_first'),(5,'nulls_last'), + (6, 'bogus')) v2(idx,prop), + generate_series(1,4) col + order by col, idx +-- +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v1(o), (VALUES (...)) v2(idx, prop), generate_series(1, 4) col ORD..." +== 009 +-- truncate_limit: 100 +CREATE INDEX foocover ON foo (f1) INCLUDE (f2,f3) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX foocover ON foo USING btree (f1) INCLUDE (f2, f3)" +== 010 +-- truncate_limit: 100 +select col, prop, pg_index_column_has_property(o, col, prop) + from (values ('foocover'::regclass)) v1(o), + (values (1,'orderable'),(2,'asc'),(3,'desc'), + (4,'nulls_first'),(5,'nulls_last'), + (6,'distance_orderable'),(7,'returnable'), + (8, 'bogus')) v2(idx,prop), + generate_series(1,3) col + order by col, idx +-- +FUNCTION: name="pg_index_column_has_property" function="pg_index_column_has_property" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v1(o), (VALUES (...)) v2(idx, prop), generate_series(1, 3) col ORD..." diff --git a/parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json b/parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json new file mode 100644 index 0000000..a8dc578 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json @@ -0,0 +1,488 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/arrays.test b/parser/testdata/summary_truncate/postgres_regress/arrays.test new file mode 100644 index 0000000..f831404 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/arrays.test @@ -0,0 +1,3752 @@ +== 001 +-- truncate_limit: 100 +|-- +-- ARRAYS +|-- + +-- directory paths are passed to us in environment variables + +CREATE TABLE arrtest ( + a int2[], + b int4[][][], + c name[], + d text[][], + e float8[], + f char(5)[], + g varchar(5)[] +) +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE arrtest (a int2[], b int4[][][], c name[], d text[][], e float8[], f char(5)[], g va..." +== 002 +-- truncate_limit: 100 +CREATE TABLE array_op_test ( + seqno int4, + i int4[], + t text[] +) +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE array_op_test (seqno int4, i int4[], t text[])" +== 003 +-- truncate_limit: 100 +COPY array_op_test FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +ANALYZE array_op_test +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE array_op_test" +== 005 +-- truncate_limit: 100 +|-- +-- only the 'e' array is 0-based, the others are 1-based. +|-- + +INSERT INTO arrtest (a[1:5], b[1:1][1:2][1:2], c, d, f, g) + VALUES ('{1,2,3,4,5}', '{{{0,0},{1,2}}}', '{}', '{}', '{}', '{}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest (a[1:5], b[1:1][1:2][1:2], c, d, f, g) VALUES (...)" +== 006 +-- truncate_limit: 100 +UPDATE arrtest SET e[0] = '1.1' +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET e[0] = '1.1'" +== 007 +-- truncate_limit: 100 +UPDATE arrtest SET e[1] = '2.2' +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET e[1] = '2.2'" +== 008 +-- truncate_limit: 100 +INSERT INTO arrtest (f) + VALUES ('{"too long"}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest (f) VALUES ('{\"too long\"}')" +== 009 +-- truncate_limit: 100 +INSERT INTO arrtest (a, b[1:2][1:2], c, d, e, f, g) + VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}', + '{{"elt1", "elt2"}}', '{"3.4", "6.7"}', + '{"abc","abcde"}', '{"abc","abcde"}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest (a, b[1:2][1:2], c, d, e, f, g) VALUES (...)" +== 010 +-- truncate_limit: 100 +INSERT INTO arrtest (a, b[1:2], c, d[1:2]) + VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest (a, b[1:2], c, d[1:2]) VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}')" +== 011 +-- truncate_limit: 100 +INSERT INTO arrtest (b[2]) VALUES(now()) +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest (b[2]) VALUES (now())" +== 012 +-- truncate_limit: 100 +-- error, type mismatch + +INSERT INTO arrtest (b[1:2]) VALUES(now()) +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest (b[1:2]) VALUES (now())" +== 013 +-- truncate_limit: 100 +-- error, type mismatch + +SELECT * FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest" +== 014 +-- truncate_limit: 100 +SELECT arrtest.a[1], + arrtest.b[1][1][1], + arrtest.c[1], + arrtest.d[1][1], + arrtest.e[0] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT arrtest.a[1], arrtest.b[1][1][1], arrtest.c[1], arrtest.d[1][1], arrtest.e[0] FROM arrtest" +== 015 +-- truncate_limit: 100 +SELECT a[1], b[1][1][1], c[1], d[1][1], e[0] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a[1], b[1][1][1], c[1], d[1][1], e[0] FROM arrtest" +== 016 +-- truncate_limit: 100 +SELECT a[1:3], + b[1:1][1:2][1:2], + c[1:2], + d[1:1][1:2] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a[1:3], b[1:1][1:2][1:2], c[1:2], d[1:1][1:2] FROM arrtest" +== 017 +-- truncate_limit: 100 +SELECT array_ndims(a) AS a,array_ndims(b) AS b,array_ndims(c) AS c + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_ndims(a) AS a, array_ndims(b) AS b, array_ndims(c) AS c FROM arrtest" +== 018 +-- truncate_limit: 100 +SELECT array_dims(a) AS a,array_dims(b) AS b,array_dims(c) AS c + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_dims(a) AS a, array_dims(b) AS b, array_dims(c) AS c FROM arrtest" +== 019 +-- truncate_limit: 100 +-- returns nothing +SELECT * + FROM arrtest + WHERE a[1] < 5 and + c = '{"foobar"}'::_name +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest WHERE a[1] < 5 AND c = '{\"foobar\"}'::_name" +== 020 +-- truncate_limit: 100 +UPDATE arrtest + SET a[1:2] = '{16,25}' + WHERE NOT a = '{}'::_int2 +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET a[1:2] = '{16,25}' WHERE NOT a = '{}'::_int2" +== 021 +-- truncate_limit: 100 +UPDATE arrtest + SET b[1:1][1:1][1:2] = '{113, 117}', + b[1:1][1:2][2:2] = '{142, 147}' + WHERE array_dims(b) = '[1:1][1:2][1:2]' +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET ... = ... WHERE array_dims(b) = '[1:1][1:2][1:2]'" +== 022 +-- truncate_limit: 100 +UPDATE arrtest + SET c[2:2] = '{"new_word"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET c[2:2] = '{\"new_word\"}' WHERE array_dims(c) IS NOT NULL" +== 023 +-- truncate_limit: 100 +SELECT a,b,c FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM arrtest" +== 024 +-- truncate_limit: 100 +SELECT a[1:3], + b[1:1][1:2][1:2], + c[1:2], + d[1:1][2:2] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a[1:3], b[1:1][1:2][1:2], c[1:2], d[1:1][2:2] FROM arrtest" +== 025 +-- truncate_limit: 100 +SELECT b[1:1][2][2], + d[1:1][2] + FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b[1:1][2][2], d[1:1][2] FROM arrtest" +== 026 +-- truncate_limit: 100 +INSERT INTO arrtest(a) VALUES('{1,null,3}') +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest (a) VALUES ('{1,null,3}')" +== 027 +-- truncate_limit: 100 +SELECT a FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a FROM arrtest" +== 028 +-- truncate_limit: 100 +UPDATE arrtest SET a[4] = NULL WHERE a[2] IS NULL +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET a[4] = NULL WHERE a[2] IS NULL" +== 029 +-- truncate_limit: 100 +SELECT a FROM arrtest WHERE a[2] IS NULL +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM arrtest WHERE a[2] IS NULL" +== 030 +-- truncate_limit: 100 +DELETE FROM arrtest WHERE a[2] IS NULL AND b IS NULL +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM arrtest WHERE a[2] IS NULL AND b IS NULL" +== 031 +-- truncate_limit: 100 +SELECT a,b,c FROM arrtest +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM arrtest" +== 032 +-- truncate_limit: 100 +-- test non-error-throwing API +SELECT pg_input_is_valid('{1,2,3}', 'integer[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{1,2,3}', 'integer[]')" +== 033 +-- truncate_limit: 100 +SELECT pg_input_is_valid('{1,2', 'integer[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{1,2', 'integer[]')" +== 034 +-- truncate_limit: 100 +SELECT pg_input_is_valid('{1,zed}', 'integer[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{1,zed}', 'integer[]')" +== 035 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('{1,zed}', 'integer[]') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{1,zed}', 'integer[]')" +== 036 +-- truncate_limit: 100 +-- test mixed slice/scalar subscripting +select '{{1,2,3},{4,5,6},{7,8,9}}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{1,2,3},{4,5,6},{7,8,9}}'::int[]" +== 037 +-- truncate_limit: 100 +select ('{{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2]" +== 038 +-- truncate_limit: 100 +select '[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[]" +== 039 +-- truncate_limit: 100 +select ('[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2]" +== 040 +-- truncate_limit: 100 +|-- +-- check subscription corner cases +|-- +-- More subscripts than MAXDIM (6) +SELECT ('{}'::int[])[1][2][3][4][5][6][7] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{}'::int[])[1][2][3][4][5][6][7]" +== 041 +-- truncate_limit: 100 +-- NULL index yields NULL when selecting +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL][1] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL][1]" +== 042 +-- truncate_limit: 100 +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL:1][1] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL:1][1]" +== 043 +-- truncate_limit: 100 +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][1:NULL][1] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][1:NULL][1]" +== 044 +-- truncate_limit: 100 +-- NULL index in assignment is an error +UPDATE arrtest + SET c[NULL] = '{"can''t assign"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET c[NULL] = '{\"can''t assign\"}' WHERE array_dims(c) IS NOT NULL" +== 045 +-- truncate_limit: 100 +UPDATE arrtest + SET c[NULL:1] = '{"can''t assign"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET c[NULL:1] = '{\"can''t assign\"}' WHERE array_dims(c) IS NOT NULL" +== 046 +-- truncate_limit: 100 +UPDATE arrtest + SET c[1:NULL] = '{"can''t assign"}' + WHERE array_dims(c) is not null +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=DML +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest SET c[1:NULL] = '{\"can''t assign\"}' WHERE array_dims(c) IS NOT NULL" +== 047 +-- truncate_limit: 100 +-- Un-subscriptable type +SELECT (now())[1] +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (now())[1]" +== 048 +-- truncate_limit: 100 +-- test slices with empty lower and/or upper index +CREATE TEMP TABLE arrtest_s ( + a int2[], + b int2[][] +) +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arrtest_s (a int2[], b int2[][])" +== 049 +-- truncate_limit: 100 +INSERT INTO arrtest_s VALUES ('{1,2,3,4,5}', '{{1,2,3}, {4,5,6}, {7,8,9}}') +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_s VALUES ('{1,2,3,4,5}', '{{1,2,3}, {4,5,6}, {7,8,9}}')" +== 050 +-- truncate_limit: 100 +INSERT INTO arrtest_s VALUES ('[0:4]={1,2,3,4,5}', '[0:2][0:2]={{1,2,3}, {4,5,6}, {7,8,9}}') +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_s VALUES ('[0:4]={1,2,3,4,5}', '[0:2][0:2]={{1,2,3}, {4,5,6}, {7,8,9}}')" +== 051 +-- truncate_limit: 100 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest_s" +== 052 +-- truncate_limit: 100 +SELECT a[:3], b[:2][:2] FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a[:3], b[:2][:2] FROM arrtest_s" +== 053 +-- truncate_limit: 100 +SELECT a[2:], b[2:][2:] FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a[2:], b[2:][2:] FROM arrtest_s" +== 054 +-- truncate_limit: 100 +SELECT a[:], b[:] FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a[:], b[:] FROM arrtest_s" +== 055 +-- truncate_limit: 100 +-- updates +UPDATE arrtest_s SET a[:3] = '{11, 12, 13}', b[:2][:2] = '{{11,12}, {14,15}}' + WHERE array_lower(a,1) = 1 +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest_s SET ... = ... WHERE array_lower(a, 1) = 1" +== 056 +-- truncate_limit: 100 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest_s" +== 057 +-- truncate_limit: 100 +UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{25,26}, {28,29}}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{25,26}, {28,29}}'" +== 058 +-- truncate_limit: 100 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest_s" +== 059 +-- truncate_limit: 100 +UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}'" +== 060 +-- truncate_limit: 100 +SELECT * FROM arrtest_s +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest_s" +== 061 +-- truncate_limit: 100 +UPDATE arrtest_s SET a[:] = '{23, 24, 25}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest_s SET a[:] = '{23, 24, 25}'" +== 062 +-- truncate_limit: 100 +-- fail, too small +INSERT INTO arrtest_s VALUES(NULL, NULL) +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_s VALUES (NULL, NULL)" +== 063 +-- truncate_limit: 100 +UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}' +-- +TABLE: name="arrtest_s" schema="" table="arrtest_s" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}'" +== 064 +-- truncate_limit: 100 +-- fail, no good with null + +-- we want to work with a point_tbl that includes a null +CREATE TEMP TABLE point_tbl AS SELECT * FROM public.point_tbl +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +TABLE: name="public.point_tbl" schema="public" table="point_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE point_tbl AS SELECT * FROM public.point_tbl" +== 065 +-- truncate_limit: 100 +INSERT INTO POINT_TBL(f1) VALUES (NULL) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES (NULL)" +== 066 +-- truncate_limit: 100 +-- check with fixed-length-array type, such as point +SELECT f1[0:1] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1[0:1] FROM point_tbl" +== 067 +-- truncate_limit: 100 +SELECT f1[0:] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1[0:] FROM point_tbl" +== 068 +-- truncate_limit: 100 +SELECT f1[:1] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1[:1] FROM point_tbl" +== 069 +-- truncate_limit: 100 +SELECT f1[:] FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1[:] FROM point_tbl" +== 070 +-- truncate_limit: 100 +-- subscript assignments to fixed-width result in NULL if previous value is NULL +UPDATE point_tbl SET f1[0] = 10 WHERE f1 IS NULL RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE point_tbl SET f1[0] = 10 WHERE f1 IS NULL RETURNING *" +== 071 +-- truncate_limit: 100 +INSERT INTO point_tbl(f1[0]) VALUES(0) RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1[0]) VALUES (0) RETURNING *" +== 072 +-- truncate_limit: 100 +-- NULL assignments get ignored +UPDATE point_tbl SET f1[0] = NULL WHERE f1::text = '(10,10)'::point::text RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE point_tbl SET f1[0] = NULL WHERE f1::text = '(10,10)'::point::text RETURNING *" +== 073 +-- truncate_limit: 100 +-- but non-NULL subscript assignments work +UPDATE point_tbl SET f1[0] = -10, f1[1] = -10 WHERE f1::text = '(10,10)'::point::text RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE point_tbl SET f1[0] = -10, f1[1] = -10 WHERE f1::text = '(10,10)'::point::text RETURNING *" +== 074 +-- truncate_limit: 100 +-- but not to expand the range +UPDATE point_tbl SET f1[3] = 10 WHERE f1::text = '(-10,-10)'::point::text RETURNING * +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE point_tbl SET f1[3] = 10 WHERE f1::text = '(-10,-10)'::point::text RETURNING *" +== 075 +-- truncate_limit: 100 +|-- +-- test array extension +|-- +CREATE TEMP TABLE arrtest1 (i int[], t text[]) +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arrtest1 (i int[], t text[])" +== 076 +-- truncate_limit: 100 +insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']) +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest1 VALUES (ARRAY[1, 2, NULL, 4], ARRAY['one', 'two', NULL, 'four'])" +== 077 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 078 +-- truncate_limit: 100 +update arrtest1 set i[2] = 22, t[2] = 'twenty-two' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[2] = 22, t[2] = 'twenty-two'" +== 079 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 080 +-- truncate_limit: 100 +update arrtest1 set i[5] = 5, t[5] = 'five' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[5] = 5, t[5] = 'five'" +== 081 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 082 +-- truncate_limit: 100 +update arrtest1 set i[8] = 8, t[8] = 'eight' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[8] = 8, t[8] = 'eight'" +== 083 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 084 +-- truncate_limit: 100 +update arrtest1 set i[0] = 0, t[0] = 'zero' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[0] = 0, t[0] = 'zero'" +== 085 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 086 +-- truncate_limit: 100 +update arrtest1 set i[-3] = -3, t[-3] = 'minus-three' +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[-3] = -3, t[-3] = 'minus-three'" +== 087 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 088 +-- truncate_limit: 100 +update arrtest1 set i[0:2] = array[10,11,12], t[0:2] = array['ten','eleven','twelve'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[0:2] = ARRAY[10, 11, 12], t[0:2] = ARRAY['ten', 'eleven', 'twelve']" +== 089 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 090 +-- truncate_limit: 100 +update arrtest1 set i[8:10] = array[18,null,20], t[8:10] = array['p18',null,'p20'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[8:10] = ARRAY[18, NULL, 20], t[8:10] = ARRAY['p18', NULL, 'p20']" +== 091 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 092 +-- truncate_limit: 100 +update arrtest1 set i[11:12] = array[null,22], t[11:12] = array[null,'p22'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[11:12] = ARRAY[NULL, 22], t[11:12] = ARRAY[NULL, 'p22']" +== 093 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 094 +-- truncate_limit: 100 +update arrtest1 set i[15:16] = array[null,26], t[15:16] = array[null,'p26'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[15:16] = ARRAY[NULL, 26], t[15:16] = ARRAY[NULL, 'p26']" +== 095 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 096 +-- truncate_limit: 100 +update arrtest1 set i[-5:-3] = array[-15,-14,-13], t[-5:-3] = array['m15','m14','m13'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[-5:-3] = ARRAY[-15, -14, -13], t[-5:-3] = ARRAY['m15', 'm14', 'm13']" +== 097 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 098 +-- truncate_limit: 100 +update arrtest1 set i[-7:-6] = array[-17,null], t[-7:-6] = array['m17',null] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[-7:-6] = ARRAY[-17, NULL], t[-7:-6] = ARRAY['m17', NULL]" +== 099 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 100 +-- truncate_limit: 100 +update arrtest1 set i[-12:-10] = array[-22,null,-20], t[-12:-10] = array['m22',null,'m20'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET i[-12:-10] = ARRAY[-22, NULL, -20], t[-12:-10] = ARRAY['m22', NULL, 'm20']" +== 101 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 102 +-- truncate_limit: 100 +delete from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM arrtest1" +== 103 +-- truncate_limit: 100 +insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']) +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest1 VALUES (ARRAY[1, 2, NULL, 4], ARRAY['one', 'two', NULL, 'four'])" +== 104 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 105 +-- truncate_limit: 100 +update arrtest1 set i[0:5] = array[0,1,2,null,4,5], t[0:5] = array['z','p1','p2',null,'p4','p5'] +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arrtest1 SET ... = ..." +== 106 +-- truncate_limit: 100 +select * from arrtest1 +-- +TABLE: name="arrtest1" schema="" table="arrtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arrtest1" +== 107 +-- truncate_limit: 100 +|-- +-- array expressions and operators +|-- + +-- table creation and INSERTs +CREATE TEMP TABLE arrtest2 (i integer ARRAY[4], f float8[], n numeric[], t text[], d timestamp[]) +-- +TABLE: name="arrtest2" schema="" table="arrtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arrtest2 (i int[4], f float8[], n numeric[], t text[], d timestamp[])" +== 108 +-- truncate_limit: 100 +INSERT INTO arrtest2 VALUES( + ARRAY[[[113,142],[1,147]]], + ARRAY[1.1,1.2,1.3]::float8[], + ARRAY[1.1,1.2,1.3], + ARRAY[[['aaa','aab'],['aba','abb'],['aca','acb']],[['baa','bab'],['bba','bbb'],['bca','bcb']]], + ARRAY['19620326','19931223','19970117']::timestamp[] +) +-- +TABLE: name="arrtest2" schema="" table="arrtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest2 VALUES (...)" +== 109 +-- truncate_limit: 100 +-- some more test data +CREATE TEMP TABLE arrtest_f (f0 int, f1 text, f2 float8) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arrtest_f (f0 int, f1 text, f2 float8)" +== 110 +-- truncate_limit: 100 +insert into arrtest_f values(1,'cat1',1.21) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (1, 'cat1', 1.21)" +== 111 +-- truncate_limit: 100 +insert into arrtest_f values(2,'cat1',1.24) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (2, 'cat1', 1.24)" +== 112 +-- truncate_limit: 100 +insert into arrtest_f values(3,'cat1',1.18) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (3, 'cat1', 1.18)" +== 113 +-- truncate_limit: 100 +insert into arrtest_f values(4,'cat1',1.26) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (4, 'cat1', 1.26)" +== 114 +-- truncate_limit: 100 +insert into arrtest_f values(5,'cat1',1.15) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (5, 'cat1', 1.15)" +== 115 +-- truncate_limit: 100 +insert into arrtest_f values(6,'cat2',1.15) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (6, 'cat2', 1.15)" +== 116 +-- truncate_limit: 100 +insert into arrtest_f values(7,'cat2',1.26) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (7, 'cat2', 1.26)" +== 117 +-- truncate_limit: 100 +insert into arrtest_f values(8,'cat2',1.32) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (8, 'cat2', 1.32)" +== 118 +-- truncate_limit: 100 +insert into arrtest_f values(9,'cat2',1.30) +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_f VALUES (9, 'cat2', 1.30)" +== 119 +-- truncate_limit: 100 +CREATE TEMP TABLE arrtest_i (f0 int, f1 text, f2 int) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arrtest_i (f0 int, f1 text, f2 int)" +== 120 +-- truncate_limit: 100 +insert into arrtest_i values(1,'cat1',21) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (1, 'cat1', 21)" +== 121 +-- truncate_limit: 100 +insert into arrtest_i values(2,'cat1',24) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (2, 'cat1', 24)" +== 122 +-- truncate_limit: 100 +insert into arrtest_i values(3,'cat1',18) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (3, 'cat1', 18)" +== 123 +-- truncate_limit: 100 +insert into arrtest_i values(4,'cat1',26) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (4, 'cat1', 26)" +== 124 +-- truncate_limit: 100 +insert into arrtest_i values(5,'cat1',15) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (5, 'cat1', 15)" +== 125 +-- truncate_limit: 100 +insert into arrtest_i values(6,'cat2',15) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (6, 'cat2', 15)" +== 126 +-- truncate_limit: 100 +insert into arrtest_i values(7,'cat2',26) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (7, 'cat2', 26)" +== 127 +-- truncate_limit: 100 +insert into arrtest_i values(8,'cat2',32) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (8, 'cat2', 32)" +== 128 +-- truncate_limit: 100 +insert into arrtest_i values(9,'cat2',30) +-- +TABLE: name="arrtest_i" schema="" table="arrtest_i" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arrtest_i VALUES (9, 'cat2', 30)" +== 129 +-- truncate_limit: 100 +-- expressions +SELECT t.f[1][3][1] AS "131", t.f[2][2][1] AS "221" FROM ( + SELECT ARRAY[[[111,112],[121,122],[131,132]],[[211,212],[221,122],[231,232]]] AS f +) AS t +-- +STMT: SelectStmt +TRUNCATED: "SELECT t.f[1][3][1] AS \"131\", t.f[2][2][1] AS \"221\" FROM (SELECT ...) t" +== 130 +-- truncate_limit: 100 +SELECT ARRAY[[[[[['hello'],['world']]]]]] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[ARRAY[ARRAY[ARRAY[ARRAY[ARRAY['hello'], ARRAY['world']]]]]]" +== 131 +-- truncate_limit: 100 +SELECT ARRAY[ARRAY['hello'],ARRAY['world']] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[ARRAY['hello'], ARRAY['world']]" +== 132 +-- truncate_limit: 100 +SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY" +-- +TABLE: name="arrtest_f" schema="" table="arrtest_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY(SELECT f2 FROM arrtest_f ORDER BY f2) AS \"ARRAY\"" +== 133 +-- truncate_limit: 100 +-- with nulls +SELECT '{1,null,3}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{1,null,3}'::int[]" +== 134 +-- truncate_limit: 100 +SELECT ARRAY[1,NULL,3] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, NULL, 3]" +== 135 +-- truncate_limit: 100 +-- functions +SELECT array_append(array[42], 6) AS "{42,6}" +-- +FUNCTION: name="array_append" function="array_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_append(ARRAY[42], 6) AS \"{42,6}\"" +== 136 +-- truncate_limit: 100 +SELECT array_prepend(6, array[42]) AS "{6,42}" +-- +FUNCTION: name="array_prepend" function="array_prepend" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_prepend(6, ARRAY[42]) AS \"{6,42}\"" +== 137 +-- truncate_limit: 100 +SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}" +-- +FUNCTION: name="array_cat" function="array_cat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_cat(ARRAY[1, 2], ARRAY[3, 4]) AS \"{1,2,3,4}\"" +== 138 +-- truncate_limit: 100 +SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}" +-- +FUNCTION: name="array_cat" function="array_cat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_cat(ARRAY[1, 2], ARRAY[ARRAY[3, 4], ARRAY[5, 6]]) AS \"{{1,2},{3,4},{5,6}}\"" +== 139 +-- truncate_limit: 100 +SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}" +-- +FUNCTION: name="array_cat" function="array_cat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_cat(ARRAY[ARRAY[3, 4], ARRAY[5, 6]], ARRAY[1, 2]) AS \"{{3,4},{5,6},{1,2}}\"" +== 140 +-- truncate_limit: 100 +SELECT array_position(ARRAY[1,2,3,4,5], 4) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY[1, 2, 3, 4, 5], 4)" +== 141 +-- truncate_limit: 100 +SELECT array_position(ARRAY[5,3,4,2,1], 4) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY[5, 3, 4, 2, 1], 4)" +== 142 +-- truncate_limit: 100 +SELECT array_position(ARRAY[[1,2],[3,4]], 3) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY[ARRAY[1, 2], ARRAY[3, 4]], 3)" +== 143 +-- truncate_limit: 100 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon') +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 'mon')" +== 144 +-- truncate_limit: 100 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'sat') +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 'sat')" +== 145 +-- truncate_limit: 100 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], NULL) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], NULL)" +== 146 +-- truncate_limit: 100 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], NULL) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', NULL, 'fri', 'sat'], NULL)" +== 147 +-- truncate_limit: 100 +SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], 'sat') +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', NULL, 'fri', 'sat'], 'sat')" +== 148 +-- truncate_limit: 100 +SELECT array_positions(NULL, 10) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_positions(NULL, 10)" +== 149 +-- truncate_limit: 100 +SELECT array_positions(NULL, NULL::int) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_positions(NULL, NULL::int)" +== 150 +-- truncate_limit: 100 +SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], 4) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_positions(ARRAY[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6], 4)" +== 151 +-- truncate_limit: 100 +SELECT array_positions(ARRAY[[1,2],[3,4]], 4) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_positions(ARRAY[ARRAY[1, 2], ARRAY[3, 4]], 4)" +== 152 +-- truncate_limit: 100 +SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], NULL) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_positions(ARRAY[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6], NULL)" +== 153 +-- truncate_limit: 100 +SELECT array_positions(ARRAY[1,2,3,NULL,5,6,1,2,3,NULL,5,6], NULL) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_positions(ARRAY[1, 2, 3, NULL, 5, 6, 1, 2, 3, NULL, 5, 6], NULL)" +== 154 +-- truncate_limit: 100 +SELECT array_length(array_positions(ARRAY(SELECT 'AAAAAAAAAAAAAAAAAAAAAAAAA'::text || i % 10 + FROM generate_series(1,100) g(i)), + 'AAAAAAAAAAAAAAAAAAAAAAAAA5'), 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 155 +-- truncate_limit: 100 +DO $$ +DECLARE + o int; + a int[] := ARRAY[1,2,3,2,3,1,2]; +BEGIN + o := array_position(a, 2); + WHILE o IS NOT NULL + LOOP + RAISE NOTICE '%', o; + o := array_position(a, 2, o + 1); + END LOOP; +END +$$ LANGUAGE plpgsql +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n o int;\n a int[] := ARRAY[1,2,3,2,3,1,2];\nBEGIN\n o := array_position(a, 2);\n WH..." +== 156 +-- truncate_limit: 100 +SELECT array_position('[2:4]={1,2,3}'::int[], 1) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position('[2:4]={1,2,3}'::int[], 1)" +== 157 +-- truncate_limit: 100 +SELECT array_positions('[2:4]={1,2,3}'::int[], 1) +-- +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_positions('[2:4]={1,2,3}'::int[], 1)" +== 158 +-- truncate_limit: 100 +SELECT + array_position(ids, (1, 1)), + array_positions(ids, (1, 1)) + FROM +(VALUES + (ARRAY[(0, 0), (1, 1)]), + (ARRAY[(1, 1)]) +) AS f (ids) +-- +FUNCTION: name="array_position" function="array_position" schema="" ctx=Call +FUNCTION: name="array_positions" function="array_positions" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_position(ids, (1, 1)), array_positions(ids, (1, 1)) FROM (VALUES (...)) f(ids)" +== 159 +-- truncate_limit: 100 +-- operators +SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]] +-- +TABLE: name="arrtest" schema="" table="arrtest" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM arrtest WHERE b = ARRAY[ARRAY[ARRAY[113, 142], ARRAY[1, 147]]]" +== 160 +-- truncate_limit: 100 +SELECT NOT ARRAY[1.1,1.2,1.3] = ARRAY[1.1,1.2,1.3] AS "FALSE" +-- +STMT: SelectStmt +TRUNCATED: "SELECT NOT ARRAY[1.1, 1.2, 1.3] = ARRAY[1.1, 1.2, 1.3] AS \"FALSE\"" +== 161 +-- truncate_limit: 100 +SELECT ARRAY[1,2] || 3 AS "{1,2,3}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 2] || 3 AS \"{1,2,3}\"" +== 162 +-- truncate_limit: 100 +SELECT 0 || ARRAY[1,2] AS "{0,1,2}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0 || ARRAY[1, 2] AS \"{0,1,2}\"" +== 163 +-- truncate_limit: 100 +SELECT ARRAY[1,2] || ARRAY[3,4] AS "{1,2,3,4}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 2] || ARRAY[3, 4] AS \"{1,2,3,4}\"" +== 164 +-- truncate_limit: 100 +SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[ARRAY[ARRAY['hello', 'world']]] || ARRAY[ARRAY[ARRAY['happy', 'birthday']]] AS \"ARRAY\"" +== 165 +-- truncate_limit: 100 +SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[ARRAY[1, 2], ARRAY[3, 4]] || ARRAY[5, 6] AS \"{{1,2},{3,4},{5,6}}\"" +== 166 +-- truncate_limit: 100 +SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT (ARRAY[0, 0] || ARRAY[1, 1]) || ARRAY[2, 2] AS \"{0,0,1,1,2,2}\"" +== 167 +-- truncate_limit: 100 +SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT (0 || ARRAY[1, 2]) || 3 AS \"{0,1,2,3}\"" +== 168 +-- truncate_limit: 100 +SELECT ARRAY[1.1] || ARRAY[2,3,4] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1.1] || ARRAY[2, 3, 4]" +== 169 +-- truncate_limit: 100 +SELECT array_agg(x) || array_agg(x) FROM (VALUES (ROW(1,2)), (ROW(3,4))) v(x) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(x) || array_agg(x) FROM (VALUES (ROW(1, 2)), (ROW(3, 4))) v(x)" +== 170 +-- truncate_limit: 100 +SELECT ROW(1,2) || array_agg(x) FROM (VALUES (ROW(3,4)), (ROW(5,6))) v(x) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) || array_agg(x) FROM (VALUES (ROW(3, 4)), (ROW(5, 6))) v(x)" +== 171 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno" +== 172 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno" +== 173 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i @> '{17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i @> '{17}' ORDER BY seqno" +== 174 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i && '{17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i && '{17}' ORDER BY seqno" +== 175 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i @> '{32,17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i @> '{32,17}' ORDER BY seqno" +== 176 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i && '{32,17}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i && '{32,17}' ORDER BY seqno" +== 177 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno" +== 178 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i = '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i = '{}' ORDER BY seqno" +== 179 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i @> '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i @> '{}' ORDER BY seqno" +== 180 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i && '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i && '{}' ORDER BY seqno" +== 181 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i <@ '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i <@ '{}' ORDER BY seqno" +== 182 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno" +== 183 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i @> '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i @> '{NULL}' ORDER BY seqno" +== 184 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i && '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i && '{NULL}' ORDER BY seqno" +== 185 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno" +== 186 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno" +== 187 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno" +== 188 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno" +== 189 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno" +== 190 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno" +== 191 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno" +== 192 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE ... ORDER BY seqno" +== 193 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t = '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t = '{}' ORDER BY seqno" +== 194 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t @> '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t @> '{}' ORDER BY seqno" +== 195 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t && '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t && '{}' ORDER BY seqno" +== 196 +-- truncate_limit: 100 +SELECT * FROM array_op_test WHERE t <@ '{}' ORDER BY seqno +-- +TABLE: name="array_op_test" schema="" table="array_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_op_test WHERE t <@ '{}' ORDER BY seqno" +== 197 +-- truncate_limit: 100 +-- array casts +SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 2, 3]::text[]::int[]::float8[] AS \"{1,2,3}\"" +== 198 +-- truncate_limit: 100 +SELECT pg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[]) AS "double precision[]" +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(ARRAY[1, 2, 3]::text[]::int[]::float8[]) AS \"double precision[]\"" +== 199 +-- truncate_limit: 100 +SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[ARRAY['a', 'bc'], ARRAY['def', 'hijk']]::text[]::varchar[] AS \"{{a,bc},{def,hijk}}\"" +== 200 +-- truncate_limit: 100 +SELECT pg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]) AS "character varying[]" +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 201 +-- truncate_limit: 100 +SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[ARRAY[ARRAY[ARRAY[ARRAY[ARRAY['a', 'bb', 'ccc']]]]]]::text[] AS \"{{{{{{a,bb,ccc}}}}}}\"" +== 202 +-- truncate_limit: 100 +SELECT NULL::text[]::int[] AS "NULL" +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::text[]::int[] AS \"NULL\"" +== 203 +-- truncate_limit: 100 +-- scalar op any/all (array) +select 33 = any ('{1,2,3}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ANY('{1,2,3}')" +== 204 +-- truncate_limit: 100 +select 33 = any ('{1,2,33}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ANY('{1,2,33}')" +== 205 +-- truncate_limit: 100 +select 33 = all ('{1,2,33}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ALL('{1,2,33}')" +== 206 +-- truncate_limit: 100 +select 33 >= all ('{1,2,33}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 >= ALL('{1,2,33}')" +== 207 +-- truncate_limit: 100 +-- boundary cases +select null::int >= all ('{1,2,33}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::int >= ALL('{1,2,33}')" +== 208 +-- truncate_limit: 100 +select null::int >= all ('{}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::int >= ALL('{}')" +== 209 +-- truncate_limit: 100 +select null::int >= any ('{}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::int >= ANY('{}')" +== 210 +-- truncate_limit: 100 +-- cross-datatype +select 33.4 = any (array[1,2,3]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33.4 = ANY(ARRAY[1, 2, 3])" +== 211 +-- truncate_limit: 100 +select 33.4 > all (array[1,2,3]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33.4 > ALL(ARRAY[1, 2, 3])" +== 212 +-- truncate_limit: 100 +-- errors +select 33 * any ('{1,2,3}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 * ANY('{1,2,3}')" +== 213 +-- truncate_limit: 100 +select 33 * any (44) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 * ANY(44)" +== 214 +-- truncate_limit: 100 +-- nulls +select 33 = any (null::int[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ANY(NULL::int[])" +== 215 +-- truncate_limit: 100 +select null::int = any ('{1,2,3}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::int = ANY('{1,2,3}')" +== 216 +-- truncate_limit: 100 +select 33 = any ('{1,null,3}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ANY('{1,null,3}')" +== 217 +-- truncate_limit: 100 +select 33 = any ('{1,null,33}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ANY('{1,null,33}')" +== 218 +-- truncate_limit: 100 +select 33 = all (null::int[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ALL(NULL::int[])" +== 219 +-- truncate_limit: 100 +select null::int = all ('{1,2,3}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::int = ALL('{1,2,3}')" +== 220 +-- truncate_limit: 100 +select 33 = all ('{1,null,3}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ALL('{1,null,3}')" +== 221 +-- truncate_limit: 100 +select 33 = all ('{33,null,33}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT 33 = ALL('{33,null,33}')" +== 222 +-- truncate_limit: 100 +-- nulls later in the bitmap +SELECT -1 != ALL(ARRAY(SELECT NULLIF(g.i, 900) FROM generate_series(1,1000) g(i))) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT -1 <> ALL(ARRAY(SELECT NULLIF(g.i, 900) FROM generate_series(1, 1000) g(i)))" +== 223 +-- truncate_limit: 100 +-- test indexes on arrays +create temp table arr_tbl (f1 int[] unique) +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arr_tbl (f1 int[] UNIQUE)" +== 224 +-- truncate_limit: 100 +insert into arr_tbl values ('{1,2,3}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_tbl VALUES ('{1,2,3}')" +== 225 +-- truncate_limit: 100 +insert into arr_tbl values ('{1,2}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_tbl VALUES ('{1,2}')" +== 226 +-- truncate_limit: 100 +-- failure expected: +insert into arr_tbl values ('{1,2,3}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_tbl VALUES ('{1,2,3}')" +== 227 +-- truncate_limit: 100 +insert into arr_tbl values ('{2,3,4}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_tbl VALUES ('{2,3,4}')" +== 228 +-- truncate_limit: 100 +insert into arr_tbl values ('{1,5,3}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_tbl VALUES ('{1,5,3}')" +== 229 +-- truncate_limit: 100 +insert into arr_tbl values ('{1,2,10}') +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_tbl VALUES ('{1,2,10}')" +== 230 +-- truncate_limit: 100 +set enable_seqscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 231 +-- truncate_limit: 100 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 232 +-- truncate_limit: 100 +select * from arr_tbl where f1 > '{1,2,3}' and f1 <= '{1,5,3}' +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arr_tbl WHERE f1 > '{1,2,3}' AND f1 <= '{1,5,3}'" +== 233 +-- truncate_limit: 100 +select * from arr_tbl where f1 >= '{1,2,3}' and f1 < '{1,5,3}' +-- +TABLE: name="arr_tbl" schema="" table="arr_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM arr_tbl WHERE f1 >= '{1,2,3}' AND f1 < '{1,5,3}'" +== 234 +-- truncate_limit: 100 +-- test ON CONFLICT DO UPDATE with arrays +create temp table arr_pk_tbl (pk int4 primary key, f1 int[]) +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arr_pk_tbl (pk int4 PRIMARY KEY, f1 int[])" +== 235 +-- truncate_limit: 100 +insert into arr_pk_tbl values (1, '{1,2,3}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_pk_tbl VALUES (1, '{1,2,3}')" +== 236 +-- truncate_limit: 100 +insert into arr_pk_tbl values (1, '{3,4,5}') on conflict (pk) + do update set f1[1] = excluded.f1[1], f1[3] = excluded.f1[3] + returning pk, f1 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_pk_tbl VALUES (...) ON CONFLICT (pk) DO UPDATE SET ... = ... RETURNING pk, f1" +== 237 +-- truncate_limit: 100 +insert into arr_pk_tbl(pk, f1[1:2]) values (1, '{6,7,8}') on conflict (pk) + do update set f1[1] = excluded.f1[1], + f1[2] = excluded.f1[2], + f1[3] = excluded.f1[3] + returning pk, f1 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_pk_tbl (...) VALUES (...) ON CONFLICT (pk) DO UPDATE SET ... = ... RETURNING pk, f1" +== 238 +-- truncate_limit: 100 +-- note: if above selects don't produce the expected tuple order, +-- then you didn't get an indexscan plan, and something is busted. +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 239 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 240 +-- truncate_limit: 100 +-- test subscript overflow detection + +-- The normal error message includes a platform-dependent limit, +-- so suppress it to avoid needing multiple expected-files. + +insert into arr_pk_tbl values(10, '[-2147483648:-2147483647]={1,2}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_pk_tbl VALUES (10, '[-2147483648:-2147483647]={1,2}')" +== 241 +-- truncate_limit: 100 +update arr_pk_tbl set f1[2147483647] = 42 where pk = 10 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arr_pk_tbl SET f1[2147483647] = 42 WHERE pk = 10" +== 242 +-- truncate_limit: 100 +update arr_pk_tbl set f1[2147483646:2147483647] = array[4,2] where pk = 10 +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE arr_pk_tbl SET f1[2147483646:2147483647] = ARRAY[4, 2] WHERE pk = 10" +== 243 +-- truncate_limit: 100 +insert into arr_pk_tbl(pk, f1[0:2147483647]) values (2, '{}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_pk_tbl (pk, f1[0:2147483647]) VALUES (2, '{}')" +== 244 +-- truncate_limit: 100 +insert into arr_pk_tbl(pk, f1[-2147483648:2147483647]) values (2, '{}') +-- +TABLE: name="arr_pk_tbl" schema="" table="arr_pk_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arr_pk_tbl (pk, f1[-2147483648:2147483647]) VALUES (2, '{}')" +== 245 +-- truncate_limit: 100 +-- also exercise the expanded-array case +do $$ declare a int[]; +begin + a := '[-2147483648:-2147483647]={1,2}'::int[]; + a[2147483647] := 42; +end $$ +-- +STMT: DoStmt +TRUNCATED: "DO $$ declare a int[];\nbegin\n a := '[-2147483648:-2147483647]={1,2}'::int[];\n a[2147483647] := ..." +== 246 +-- truncate_limit: 100 +-- test [not] (like|ilike) (any|all) (...) +select 'foo' like any (array['%a', '%o']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' LIKE ANY(ARRAY['%a', '%o'])" +== 247 +-- truncate_limit: 100 +-- t +select 'foo' like any (array['%a', '%b']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' LIKE ANY(ARRAY['%a', '%b'])" +== 248 +-- truncate_limit: 100 +-- f +select 'foo' like all (array['f%', '%o']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' LIKE ALL(ARRAY['f%', '%o'])" +== 249 +-- truncate_limit: 100 +-- t +select 'foo' like all (array['f%', '%b']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' LIKE ALL(ARRAY['f%', '%b'])" +== 250 +-- truncate_limit: 100 +-- f +select 'foo' not like any (array['%a', '%b']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' NOT LIKE ANY(ARRAY['%a', '%b'])" +== 251 +-- truncate_limit: 100 +-- t +select 'foo' not like all (array['%a', '%o']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' NOT LIKE ALL(ARRAY['%a', '%o'])" +== 252 +-- truncate_limit: 100 +-- f +select 'foo' ilike any (array['%A', '%O']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' ILIKE ANY(ARRAY['%A', '%O'])" +== 253 +-- truncate_limit: 100 +-- t +select 'foo' ilike all (array['F%', '%O']) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' ILIKE ALL(ARRAY['F%', '%O'])" +== 254 +-- truncate_limit: 100 +-- t + +|-- +-- General array parser tests +|-- + +-- none of the following should be accepted +select '{{1,{2}},{2,3}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{1,{2}},{2,3}}'::text[]" +== 255 +-- truncate_limit: 100 +select E'{{1,2},\\{2,3}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{{1,2},\\\\{2,3}}'::text[]" +== 256 +-- truncate_limit: 100 +select '{"a"b}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\"b}'::text[]" +== 257 +-- truncate_limit: 100 +select '{a"b"}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{a\"b\"}'::text[]" +== 258 +-- truncate_limit: 100 +select '{"a""b"}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\"\"b\"}'::text[]" +== 259 +-- truncate_limit: 100 +select '{{"1 2" x},{3}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{\"1 2\" x},{3}}'::text[]" +== 260 +-- truncate_limit: 100 +select '{{"1 2"} x,{3}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{\"1 2\"} x,{3}}'::text[]" +== 261 +-- truncate_limit: 100 +select '{}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}}'::text[]" +== 262 +-- truncate_limit: 100 +select '{ }}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{ }}'::text[]" +== 263 +-- truncate_limit: 100 +select '}{'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '}{'::text[]" +== 264 +-- truncate_limit: 100 +select '{foo{}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{foo{}}'::text[]" +== 265 +-- truncate_limit: 100 +select '{"foo"{}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"foo\"{}}'::text[]" +== 266 +-- truncate_limit: 100 +select '{foo,,bar}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{foo,,bar}'::text[]" +== 267 +-- truncate_limit: 100 +select '{{1},{{2}}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{1},{{2}}}'::text[]" +== 268 +-- truncate_limit: 100 +select '{{{1}},{2}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{{1}},{2}}'::text[]" +== 269 +-- truncate_limit: 100 +select '{{},{{}}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{},{{}}}'::text[]" +== 270 +-- truncate_limit: 100 +select '{{{}},{}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{{}},{}}'::text[]" +== 271 +-- truncate_limit: 100 +select '{{1},{}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{1},{}}'::text[]" +== 272 +-- truncate_limit: 100 +select '{{},{1}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{},{1}}'::text[]" +== 273 +-- truncate_limit: 100 +select '[1:0]={}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1:0]={}'::int[]" +== 274 +-- truncate_limit: 100 +select '[2147483646:2147483647]={1,2}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[2147483646:2147483647]={1,2}'::int[]" +== 275 +-- truncate_limit: 100 +select '[1:-1]={}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1:-1]={}'::int[]" +== 276 +-- truncate_limit: 100 +select '[2]={1}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[2]={1}'::int[]" +== 277 +-- truncate_limit: 100 +select '[1:]={1}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1:]={1}'::int[]" +== 278 +-- truncate_limit: 100 +select '[:1]={1}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[:1]={1}'::int[]" +== 279 +-- truncate_limit: 100 +select array[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[]" +== 280 +-- truncate_limit: 100 +select '{{1,},{1},}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{1,},{1},}'::text[]" +== 281 +-- truncate_limit: 100 +select '{{1,},{1}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{1,},{1}}'::text[]" +== 282 +-- truncate_limit: 100 +select '{{1,}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{1,}}'::text[]" +== 283 +-- truncate_limit: 100 +select '{1,}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{1,}'::text[]" +== 284 +-- truncate_limit: 100 +select '[21474836488:21474836489]={1,2}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[21474836488:21474836489]={1,2}'::int[]" +== 285 +-- truncate_limit: 100 +select '[-2147483649:-2147483648]={1,2}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[-2147483649:-2147483648]={1,2}'::int[]" +== 286 +-- truncate_limit: 100 +-- none of the above should be accepted + +-- all of the following should be accepted +select '{}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::text[]" +== 287 +-- truncate_limit: 100 +select '{{},{}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{},{}}'::text[]" +== 288 +-- truncate_limit: 100 +select '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[]" +== 289 +-- truncate_limit: 100 +select '{null,n\ull,"null"}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{null,n\\\\ull,\"null\"}'::text[]" +== 290 +-- truncate_limit: 100 +select '{ ab\c , "ab\"c" }'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ ab\\\\c , \"ab\\\\\"c\" }'::text[]" +== 291 +-- truncate_limit: 100 +select '{0 second ,0 second}'::interval[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{0 second ,0 second}'::interval[]" +== 292 +-- truncate_limit: 100 +select '{ { "," } , { 3 } }'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{ { \",\" } , { 3 } }'::text[]" +== 293 +-- truncate_limit: 100 +select ' { { " 0 second " , 0 second } }'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' { { \" 0 second \" , 0 second } }'::text[]" +== 294 +-- truncate_limit: 100 +select '{ + 0 second, + @ 1 hour @ 42 minutes @ 20 seconds + }'::interval[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\n 0 second,\n @ 1 hour @ 42 minutes @ 20 seconds\n }'::interval[]" +== 295 +-- truncate_limit: 100 +select array[]::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[]::text[]" +== 296 +-- truncate_limit: 100 +select '[2]={1,7}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[2]={1,7}'::int[]" +== 297 +-- truncate_limit: 100 +select '[0:1]={1.1,2.2}'::float8[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[0:1]={1.1,2.2}'::float8[]" +== 298 +-- truncate_limit: 100 +select '[2147483646:2147483646]={1}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[2147483646:2147483646]={1}'::int[]" +== 299 +-- truncate_limit: 100 +select '[-2147483648:-2147483647]={1,2}'::int[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[-2147483648:-2147483647]={1,2}'::int[]" +== 300 +-- truncate_limit: 100 +-- all of the above should be accepted + +-- tests for array aggregates +CREATE TEMP TABLE arraggtest ( f1 INT[], f2 TEXT[][], f3 FLOAT[]) +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE arraggtest (f1 int[], f2 text[][], f3 double precision[])" +== 301 +-- truncate_limit: 100 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{1,2,3,4}','{{grey,red},{blue,blue}}','{1.6, 0.0}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arraggtest (f1, f2, f3) VALUES ('{1,2,3,4}', '{{grey,red},{blue,blue}}', '{1.6, 0.0}')" +== 302 +-- truncate_limit: 100 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{1,2,3}','{{grey,red},{grey,blue}}','{1.6}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arraggtest (f1, f2, f3) VALUES ('{1,2,3}', '{{grey,red},{grey,blue}}', '{1.6}')" +== 303 +-- truncate_limit: 100 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest" +== 304 +-- truncate_limit: 100 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{3,3,2,4,5,6}','{{white,yellow},{pink,orange}}','{2.1,3.3,1.8,1.7,1.6}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arraggtest (f1, f2, f3) VALUES (...)" +== 305 +-- truncate_limit: 100 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest" +== 306 +-- truncate_limit: 100 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{2}','{{black,red},{green,orange}}','{1.6,2.2,2.6,0.4}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arraggtest (f1, f2, f3) VALUES (...)" +== 307 +-- truncate_limit: 100 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest" +== 308 +-- truncate_limit: 100 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{4,2,6,7,8,1}','{{red},{black},{purple},{blue},{blue}}',NULL) +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arraggtest (f1, f2, f3) VALUES (...)" +== 309 +-- truncate_limit: 100 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest" +== 310 +-- truncate_limit: 100 +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{}','{{pink,white,blue,red,grey,orange}}','{2.1,1.87,1.4,2.2}') +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO arraggtest (f1, f2, f3) VALUES (...)" +== 311 +-- truncate_limit: 100 +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest +-- +TABLE: name="arraggtest" schema="" table="arraggtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest" +== 312 +-- truncate_limit: 100 +-- A few simple tests for arrays of composite types + +create type comptype as (f1 int, f2 text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE comptype AS (f1 int, f2 text)" +== 313 +-- truncate_limit: 100 +create table comptable (c1 comptype, c2 comptype[]) +-- +TABLE: name="comptable" schema="" table="comptable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE comptable (c1 comptype, c2 comptype[])" +== 314 +-- truncate_limit: 100 +-- XXX would like to not have to specify row() construct types here ... +insert into comptable + values (row(1,'foo'), array[row(2,'bar')::comptype, row(3,'baz')::comptype]) +-- +TABLE: name="comptable" schema="" table="comptable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO comptable VALUES (...)" +== 315 +-- truncate_limit: 100 +-- check that implicitly named array type _comptype isn't a problem +create type _comptype as enum('fooey') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE _comptype AS ENUM ('fooey')" +== 316 +-- truncate_limit: 100 +select * from comptable +-- +TABLE: name="comptable" schema="" table="comptable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM comptable" +== 317 +-- truncate_limit: 100 +select c2[2].f2 from comptable +-- +TABLE: name="comptable" schema="" table="comptable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT c2[2].f2 FROM comptable" +== 318 +-- truncate_limit: 100 +drop type _comptype +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE _comptype" +== 319 +-- truncate_limit: 100 +drop table comptable +-- +TABLE: name="comptable" schema="" table="comptable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE comptable" +== 320 +-- truncate_limit: 100 +drop type comptype +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE comptype" +== 321 +-- truncate_limit: 100 +create or replace function unnest1(anyarray) +returns setof anyelement as $$ +select $1[s] from generate_subscripts($1,1) g(s); +$$ language sql immutable +-- +FUNCTION: name="unnest1" function="unnest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION unnest1(anyarray) RETURNS SETOF anyelement AS $$\nselect $1[s] from gen..." +== 322 +-- truncate_limit: 100 +create or replace function unnest2(anyarray) +returns setof anyelement as $$ +select $1[s1][s2] from generate_subscripts($1,1) g1(s1), + generate_subscripts($1,2) g2(s2); +$$ language sql immutable +-- +FUNCTION: name="unnest2" function="unnest2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$\nselect $1[s1][s2] fro..." +== 323 +-- truncate_limit: 100 +select * from unnest1(array[1,2,3]) +-- +FUNCTION: name="unnest1" function="unnest1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest1(ARRAY[1, 2, 3])" +== 324 +-- truncate_limit: 100 +select * from unnest2(array[[1,2,3],[4,5,6]]) +-- +FUNCTION: name="unnest2" function="unnest2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest2(ARRAY[ARRAY[1, 2, 3], ARRAY[4, 5, 6]])" +== 325 +-- truncate_limit: 100 +drop function unnest1(anyarray) +-- +FUNCTION: name="unnest1" function="unnest1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION unnest1(anyarray)" +== 326 +-- truncate_limit: 100 +drop function unnest2(anyarray) +-- +FUNCTION: name="unnest2" function="unnest2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION unnest2(anyarray)" +== 327 +-- truncate_limit: 100 +select array_fill(null::integer, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(NULL::int, ARRAY[3, 3], ARRAY[2, 2])" +== 328 +-- truncate_limit: 100 +select array_fill(null::integer, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(NULL::int, ARRAY[3, 3])" +== 329 +-- truncate_limit: 100 +select array_fill(null::text, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(NULL::text, ARRAY[3, 3], ARRAY[2, 2])" +== 330 +-- truncate_limit: 100 +select array_fill(null::text, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(NULL::text, ARRAY[3, 3])" +== 331 +-- truncate_limit: 100 +select array_fill(7, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(7, ARRAY[3, 3], ARRAY[2, 2])" +== 332 +-- truncate_limit: 100 +select array_fill(7, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(7, ARRAY[3, 3])" +== 333 +-- truncate_limit: 100 +select array_fill('juhu'::text, array[3,3],array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill('juhu'::text, ARRAY[3, 3], ARRAY[2, 2])" +== 334 +-- truncate_limit: 100 +select array_fill('juhu'::text, array[3,3]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill('juhu'::text, ARRAY[3, 3])" +== 335 +-- truncate_limit: 100 +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, array[0]) as a) ss +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, a = '{}' AS is_eq, array_dims(a) FROM (SELECT array_fill(42, ARRAY[0]) AS a) ss" +== 336 +-- truncate_limit: 100 +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, '{}') as a) ss +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, a = '{}' AS is_eq, array_dims(a) FROM (SELECT array_fill(42, '{}') AS a) ss" +== 337 +-- truncate_limit: 100 +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, '{}', '{}') as a) ss +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, a = '{}' AS is_eq, array_dims(a) FROM (SELECT array_fill(42, '{}', '{}') AS a) ss" +== 338 +-- truncate_limit: 100 +-- raise exception +select array_fill(1, null, array[2,2]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(1, NULL, ARRAY[2, 2])" +== 339 +-- truncate_limit: 100 +select array_fill(1, array[2,2], null) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(1, ARRAY[2, 2], NULL)" +== 340 +-- truncate_limit: 100 +select array_fill(1, array[2,2], '{}') +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(1, ARRAY[2, 2], '{}')" +== 341 +-- truncate_limit: 100 +select array_fill(1, array[3,3], array[1,1,1]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(1, ARRAY[3, 3], ARRAY[1, 1, 1])" +== 342 +-- truncate_limit: 100 +select array_fill(1, array[1,2,null]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(1, ARRAY[1, 2, NULL])" +== 343 +-- truncate_limit: 100 +select array_fill(1, array[[1,2],[3,4]]) +-- +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_fill(1, ARRAY[ARRAY[1, 2], ARRAY[3, 4]])" +== 344 +-- truncate_limit: 100 +select string_to_array('1|2|3', '|') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1|2|3', '|')" +== 345 +-- truncate_limit: 100 +select string_to_array('1|2|3|', '|') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1|2|3|', '|')" +== 346 +-- truncate_limit: 100 +select string_to_array('1||2|3||', '||') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1||2|3||', '||')" +== 347 +-- truncate_limit: 100 +select string_to_array('1|2|3', '') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1|2|3', '')" +== 348 +-- truncate_limit: 100 +select string_to_array('', '|') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('', '|')" +== 349 +-- truncate_limit: 100 +select string_to_array('1|2|3', NULL) +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1|2|3', NULL)" +== 350 +-- truncate_limit: 100 +select string_to_array(NULL, '|') IS NULL +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array(NULL, '|') IS NULL" +== 351 +-- truncate_limit: 100 +select string_to_array('abc', '') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('abc', '')" +== 352 +-- truncate_limit: 100 +select string_to_array('abc', '', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('abc', '', 'abc')" +== 353 +-- truncate_limit: 100 +select string_to_array('abc', ',') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('abc', ',')" +== 354 +-- truncate_limit: 100 +select string_to_array('abc', ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('abc', ',', 'abc')" +== 355 +-- truncate_limit: 100 +select string_to_array('1,2,3,4,,6', ',') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1,2,3,4,,6', ',')" +== 356 +-- truncate_limit: 100 +select string_to_array('1,2,3,4,,6', ',', '') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1,2,3,4,,6', ',', '')" +== 357 +-- truncate_limit: 100 +select string_to_array('1,2,3,4,*,6', ',', '*') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('1,2,3,4,*,6', ',', '*')" +== 358 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1|2|3', '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1|2|3', '|') g(v)" +== 359 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1|2|3|', '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1|2|3|', '|') g(v)" +== 360 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1||2|3||', '||') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1||2|3||', '||') g(v)" +== 361 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1|2|3', '') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1|2|3', '') g(v)" +== 362 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('', '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('', '|') g(v)" +== 363 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1|2|3', NULL) g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1|2|3', NULL) g(v)" +== 364 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table(NULL, '|') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table(NULL, '|') g(v)" +== 365 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('abc', '') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('abc', '') g(v)" +== 366 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('abc', '', 'abc') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('abc', '', 'abc') g(v)" +== 367 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('abc', ',') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('abc', ',') g(v)" +== 368 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('abc', ',', 'abc') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('abc', ',', 'abc') g(v)" +== 369 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1,2,3,4,,6', ',') g(v)" +== 370 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',', '') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1,2,3,4,,6', ',', '') g(v)" +== 371 +-- truncate_limit: 100 +select v, v is null as "is null" from string_to_table('1,2,3,4,*,6', ',', '*') g(v) +-- +FUNCTION: name="string_to_table" function="string_to_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, v IS NULL AS \"is null\" FROM string_to_table('1,2,3,4,*,6', ',', '*') g(v)" +== 372 +-- truncate_limit: 100 +select array_to_string(NULL::int4[], ',') IS NULL +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_string(NULL::int4[], ',') IS NULL" +== 373 +-- truncate_limit: 100 +select array_to_string('{}'::int4[], ',') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_string('{}'::int4[], ',')" +== 374 +-- truncate_limit: 100 +select array_to_string(array[1,2,3,4,NULL,6], ',') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_string(ARRAY[1, 2, 3, 4, NULL, 6], ',')" +== 375 +-- truncate_limit: 100 +select array_to_string(array[1,2,3,4,NULL,6], ',', '*') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_string(ARRAY[1, 2, 3, 4, NULL, 6], ',', '*')" +== 376 +-- truncate_limit: 100 +select array_to_string(array[1,2,3,4,NULL,6], NULL) +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_string(ARRAY[1, 2, 3, 4, NULL, 6], NULL)" +== 377 +-- truncate_limit: 100 +select array_to_string(array[1,2,3,4,NULL,6], ',', NULL) +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_string(ARRAY[1, 2, 3, 4, NULL, 6], ',', NULL)" +== 378 +-- truncate_limit: 100 +select array_to_string(string_to_array('1|2|3', '|'), '|') +-- +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_string(string_to_array('1|2|3', '|'), '|')" +== 379 +-- truncate_limit: 100 +select array_length(array[1,2,3], 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_length(ARRAY[1, 2, 3], 1)" +== 380 +-- truncate_limit: 100 +select array_length(array[[1,2,3], [4,5,6]], 0) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_length(ARRAY[ARRAY[1, 2, 3], ARRAY[4, 5, 6]], 0)" +== 381 +-- truncate_limit: 100 +select array_length(array[[1,2,3], [4,5,6]], 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_length(ARRAY[ARRAY[1, 2, 3], ARRAY[4, 5, 6]], 1)" +== 382 +-- truncate_limit: 100 +select array_length(array[[1,2,3], [4,5,6]], 2) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_length(ARRAY[ARRAY[1, 2, 3], ARRAY[4, 5, 6]], 2)" +== 383 +-- truncate_limit: 100 +select array_length(array[[1,2,3], [4,5,6]], 3) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_length(ARRAY[ARRAY[1, 2, 3], ARRAY[4, 5, 6]], 3)" +== 384 +-- truncate_limit: 100 +select cardinality(NULL::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cardinality(NULL::int[])" +== 385 +-- truncate_limit: 100 +select cardinality('{}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cardinality('{}'::int[])" +== 386 +-- truncate_limit: 100 +select cardinality(array[1,2,3]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cardinality(ARRAY[1, 2, 3])" +== 387 +-- truncate_limit: 100 +select cardinality('[2:4]={5,6,7}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cardinality('[2:4]={5,6,7}'::int[])" +== 388 +-- truncate_limit: 100 +select cardinality('{{1,2}}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cardinality('{{1,2}}'::int[])" +== 389 +-- truncate_limit: 100 +select cardinality('{{1,2},{3,4},{5,6}}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cardinality('{{1,2},{3,4},{5,6}}'::int[])" +== 390 +-- truncate_limit: 100 +select cardinality('{{{1,9},{5,6}},{{2,3},{3,4}}}'::int[]) +-- +FUNCTION: name="cardinality" function="cardinality" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cardinality('{{{1,9},{5,6}},{{2,3},{3,4}}}'::int[])" +== 391 +-- truncate_limit: 100 +-- array_agg(anynonarray) +select array_agg(unique1) from (select unique1 from tenk1 where unique1 < 15 order by unique1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(unique1) FROM (SELECT unique1 FROM tenk1 WHERE unique1 < 15 ORDER BY unique1) ss" +== 392 +-- truncate_limit: 100 +select array_agg(ten) from (select ten from tenk1 where unique1 < 15 order by unique1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(ten) FROM (SELECT ten FROM tenk1 WHERE unique1 < 15 ORDER BY unique1) ss" +== 393 +-- truncate_limit: 100 +select array_agg(nullif(ten, 4)) from (select ten from tenk1 where unique1 < 15 order by unique1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(NULLIF(ten, 4)) FROM (SELECT ten FROM tenk1 WHERE unique1 < 15 ORDER BY unique1) ss" +== 394 +-- truncate_limit: 100 +select array_agg(unique1) from tenk1 where unique1 < -15 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(unique1) FROM tenk1 WHERE unique1 < -15" +== 395 +-- truncate_limit: 100 +-- array_agg(anyarray) +select array_agg(ar) + from (values ('{1,2}'::int[]), ('{3,4}'::int[])) v(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(ar) FROM (VALUES ('{1,2}'::int[]), ('{3,4}'::int[])) v(ar)" +== 396 +-- truncate_limit: 100 +select array_agg(distinct ar order by ar desc) + from (select array[i / 2] from generate_series(1,10) a(i)) b(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 10) a(i)) b(ar)" +== 397 +-- truncate_limit: 100 +select array_agg(ar) + from (select array_agg(array[i, i+1, i-1]) + from generate_series(1,2) a(i)) b(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(ar) FROM (SELECT ... FROM generate_series(1, 2) a(i)) b(ar)" +== 398 +-- truncate_limit: 100 +select array_agg(array[i+1.2, i+1.3, i+1.4]) from generate_series(1,3) g(i) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(ARRAY[i + 1.2, i + 1.3, i + 1.4]) FROM generate_series(1, 3) g(i)" +== 399 +-- truncate_limit: 100 +select array_agg(array['Hello', i::text]) from generate_series(9,11) g(i) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(ARRAY['Hello', i::text]) FROM generate_series(9, 11) g(i)" +== 400 +-- truncate_limit: 100 +select array_agg(array[i, nullif(i, 3), i+1]) from generate_series(1,4) g(i) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(ARRAY[i, NULLIF(i, 3), i + 1]) FROM generate_series(1, 4) g(i)" +== 401 +-- truncate_limit: 100 +-- errors +select array_agg('{}'::int[]) from generate_series(1,2) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg('{}'::int[]) FROM generate_series(1, 2)" +== 402 +-- truncate_limit: 100 +select array_agg(null::int[]) from generate_series(1,2) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(NULL::int[]) FROM generate_series(1, 2)" +== 403 +-- truncate_limit: 100 +select array_agg(ar) + from (values ('{1,2}'::int[]), ('{3}'::int[])) v(ar) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(ar) FROM (VALUES ('{1,2}'::int[]), ('{3}'::int[])) v(ar)" +== 404 +-- truncate_limit: 100 +select unnest(array[1,2,3]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY[1, 2, 3])" +== 405 +-- truncate_limit: 100 +select * from unnest(array[1,2,3]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest(ARRAY[1, 2, 3])" +== 406 +-- truncate_limit: 100 +select unnest(array[1,2,3,4.5]::float8[]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY[1, 2, 3, 4.5]::float8[])" +== 407 +-- truncate_limit: 100 +select unnest(array[1,2,3,4.5]::numeric[]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY[1, 2, 3, 4.5]::numeric[])" +== 408 +-- truncate_limit: 100 +select unnest(array[1,2,3,null,4,null,null,5,6]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY[1, 2, 3, NULL, 4, NULL, NULL, 5, 6])" +== 409 +-- truncate_limit: 100 +select unnest(array[1,2,3,null,4,null,null,5,6]::text[]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY[1, 2, 3, NULL, 4, NULL, NULL, 5, 6]::text[])" +== 410 +-- truncate_limit: 100 +select abs(unnest(array[1,2,null,-3])) +-- +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT abs(unnest(ARRAY[1, 2, NULL, -3]))" +== 411 +-- truncate_limit: 100 +select array_remove(array[1,2,2,3], 2) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_remove(ARRAY[1, 2, 2, 3], 2)" +== 412 +-- truncate_limit: 100 +select array_remove(array[1,2,2,3], 5) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_remove(ARRAY[1, 2, 2, 3], 5)" +== 413 +-- truncate_limit: 100 +select array_remove(array[1,NULL,NULL,3], NULL) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_remove(ARRAY[1, NULL, NULL, 3], NULL)" +== 414 +-- truncate_limit: 100 +select array_remove(array['A','CC','D','C','RR'], 'RR') +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_remove(ARRAY['A', 'CC', 'D', 'C', 'RR'], 'RR')" +== 415 +-- truncate_limit: 100 +select array_remove(array[1.0, 2.1, 3.3], 1) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_remove(ARRAY[1.0, 2.1, 3.3], 1)" +== 416 +-- truncate_limit: 100 +select array_remove('{{1,2,2},{1,4,3}}', 2) +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_remove('{{1,2,2},{1,4,3}}', 2)" +== 417 +-- truncate_limit: 100 +-- not allowed +select array_remove(array['X','X','X'], 'X') = '{}' +-- +FUNCTION: name="array_remove" function="array_remove" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_remove(ARRAY['X', 'X', 'X'], 'X') = '{}'" +== 418 +-- truncate_limit: 100 +select array_replace(array[1,2,5,4],5,3) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_replace(ARRAY[1, 2, 5, 4], 5, 3)" +== 419 +-- truncate_limit: 100 +select array_replace(array[1,2,5,4],5,NULL) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_replace(ARRAY[1, 2, 5, 4], 5, NULL)" +== 420 +-- truncate_limit: 100 +select array_replace(array[1,2,NULL,4,NULL],NULL,5) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_replace(ARRAY[1, 2, NULL, 4, NULL], NULL, 5)" +== 421 +-- truncate_limit: 100 +select array_replace(array['A','B','DD','B'],'B','CC') +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_replace(ARRAY['A', 'B', 'DD', 'B'], 'B', 'CC')" +== 422 +-- truncate_limit: 100 +select array_replace(array[1,NULL,3],NULL,NULL) +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_replace(ARRAY[1, NULL, 3], NULL, NULL)" +== 423 +-- truncate_limit: 100 +select array_replace(array['AB',NULL,'CDE'],NULL,'12') +-- +FUNCTION: name="array_replace" function="array_replace" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_replace(ARRAY['AB', NULL, 'CDE'], NULL, '12')" +== 424 +-- truncate_limit: 100 +-- array(select array-value ...) +select array(select array[i,i/2] from generate_series(1,5) i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY(SELECT ARRAY[i, i / 2] FROM generate_series(1, 5) i)" +== 425 +-- truncate_limit: 100 +select array(select array['Hello', i::text] from generate_series(9,11) i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY(SELECT ARRAY['Hello', i::text] FROM generate_series(9, 11) i)" +== 426 +-- truncate_limit: 100 +-- int2vector and oidvector should be treated as scalar types for this purpose +select pg_typeof(array(select '11 22 33'::int2vector from generate_series(1,5))) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(ARRAY(SELECT '11 22 33'::int2vector FROM generate_series(1, 5)))" +== 427 +-- truncate_limit: 100 +select array(select '11 22 33'::int2vector from generate_series(1,5)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY(SELECT '11 22 33'::int2vector FROM generate_series(1, 5))" +== 428 +-- truncate_limit: 100 +select unnest(array(select '11 22 33'::int2vector from generate_series(1,5))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY(SELECT '11 22 33'::int2vector FROM generate_series(1, 5)))" +== 429 +-- truncate_limit: 100 +select pg_typeof(array(select '11 22 33'::oidvector from generate_series(1,5))) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(ARRAY(SELECT '11 22 33'::oidvector FROM generate_series(1, 5)))" +== 430 +-- truncate_limit: 100 +select array(select '11 22 33'::oidvector from generate_series(1,5)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY(SELECT '11 22 33'::oidvector FROM generate_series(1, 5))" +== 431 +-- truncate_limit: 100 +select unnest(array(select '11 22 33'::oidvector from generate_series(1,5))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY(SELECT '11 22 33'::oidvector FROM generate_series(1, 5)))" +== 432 +-- truncate_limit: 100 +-- array[] should do the same +select pg_typeof(array['11 22 33'::int2vector]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(ARRAY['11 22 33'::int2vector])" +== 433 +-- truncate_limit: 100 +select array['11 22 33'::int2vector] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY['11 22 33'::int2vector]" +== 434 +-- truncate_limit: 100 +select pg_typeof(unnest(array['11 22 33'::int2vector])) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(unnest(ARRAY['11 22 33'::int2vector]))" +== 435 +-- truncate_limit: 100 +select unnest(array['11 22 33'::int2vector]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY['11 22 33'::int2vector])" +== 436 +-- truncate_limit: 100 +select pg_typeof(unnest('11 22 33'::int2vector)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(unnest('11 22 33'::int2vector))" +== 437 +-- truncate_limit: 100 +select unnest('11 22 33'::int2vector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest('11 22 33'::int2vector)" +== 438 +-- truncate_limit: 100 +select pg_typeof(array['11 22 33'::oidvector]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(ARRAY['11 22 33'::oidvector])" +== 439 +-- truncate_limit: 100 +select array['11 22 33'::oidvector] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY['11 22 33'::oidvector]" +== 440 +-- truncate_limit: 100 +select pg_typeof(unnest(array['11 22 33'::oidvector])) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(unnest(ARRAY['11 22 33'::oidvector]))" +== 441 +-- truncate_limit: 100 +select unnest(array['11 22 33'::oidvector]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY['11 22 33'::oidvector])" +== 442 +-- truncate_limit: 100 +select pg_typeof(unnest('11 22 33'::oidvector)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(unnest('11 22 33'::oidvector))" +== 443 +-- truncate_limit: 100 +select unnest('11 22 33'::oidvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest('11 22 33'::oidvector)" +== 444 +-- truncate_limit: 100 +-- Insert/update on a column that is array of composite + +create temp table t1 (f1 int8_tbl[]) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (f1 int8_tbl[])" +== 445 +-- truncate_limit: 100 +insert into t1 (f1[5].q1) values(42) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 (f1[5].q1) VALUES (42)" +== 446 +-- truncate_limit: 100 +select * from t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 447 +-- truncate_limit: 100 +update t1 set f1[5].q2 = 43 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t1 SET f1[5].q2 = 43" +== 448 +-- truncate_limit: 100 +select * from t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 449 +-- truncate_limit: 100 +-- Check that arrays of composites are safely detoasted when needed + +create temp table src (f1 text) +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE src (f1 text)" +== 450 +-- truncate_limit: 100 +insert into src + select string_agg(random()::text,'') from generate_series(1,10000) +-- +TABLE: name="src" schema="" table="src" ctx=DML +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO src SELECT string_agg(random()::text, '') FROM generate_series(1, 10000)" +== 451 +-- truncate_limit: 100 +create type textandtext as (c1 text, c2 text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE textandtext AS (c1 text, c2 text)" +== 452 +-- truncate_limit: 100 +create temp table dest (f1 textandtext[]) +-- +TABLE: name="dest" schema="" table="dest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE dest (f1 textandtext[])" +== 453 +-- truncate_limit: 100 +insert into dest select array[row(f1,f1)::textandtext] from src +-- +TABLE: name="dest" schema="" table="dest" ctx=DML +TABLE: name="src" schema="" table="src" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dest SELECT ARRAY[ROW(f1, f1)::textandtext] FROM src" +== 454 +-- truncate_limit: 100 +select length(fipshash((f1[1]).c2)) from dest +-- +TABLE: name="dest" schema="" table="dest" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(fipshash((f1[1]).c2)) FROM dest" +== 455 +-- truncate_limit: 100 +delete from src +-- +TABLE: name="src" schema="" table="src" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM src" +== 456 +-- truncate_limit: 100 +select length(fipshash((f1[1]).c2)) from dest +-- +TABLE: name="dest" schema="" table="dest" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(fipshash((f1[1]).c2)) FROM dest" +== 457 +-- truncate_limit: 100 +truncate table src +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE src" +== 458 +-- truncate_limit: 100 +drop table src +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE src" +== 459 +-- truncate_limit: 100 +select length(fipshash((f1[1]).c2)) from dest +-- +TABLE: name="dest" schema="" table="dest" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(fipshash((f1[1]).c2)) FROM dest" +== 460 +-- truncate_limit: 100 +drop table dest +-- +TABLE: name="dest" schema="" table="dest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE dest" +== 461 +-- truncate_limit: 100 +drop type textandtext +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textandtext" +== 462 +-- truncate_limit: 100 +-- Tests for polymorphic-array form of width_bucket() + +-- this exercises the varwidth and float8 code paths +SELECT + op, + width_bucket(op::numeric, ARRAY[1, 3, 5, 10.0]::numeric[]) AS wb_n1, + width_bucket(op::numeric, ARRAY[0, 5.5, 9.99]::numeric[]) AS wb_n2, + width_bucket(op::numeric, ARRAY[-6, -5, 2.0]::numeric[]) AS wb_n3, + width_bucket(op::float8, ARRAY[1, 3, 5, 10.0]::float8[]) AS wb_f1, + width_bucket(op::float8, ARRAY[0, 5.5, 9.99]::float8[]) AS wb_f2, + width_bucket(op::float8, ARRAY[-6, -5, 2.0]::float8[]) AS wb_f3 +FROM (VALUES + (-5.2), + (-0.0000000001), + (0.000000000001), + (1), + (1.99999999999999), + (2), + (2.00000000000001), + (3), + (4), + (4.5), + (5), + (5.5), + (6), + (7), + (8), + (9), + (9.99999999999999), + (10), + (10.0000000000001) +) v(op) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(op)" +== 463 +-- truncate_limit: 100 +-- ensure float8 path handles NaN properly +SELECT + op, + width_bucket(op, ARRAY[1, 3, 9, 'NaN', 'NaN']::float8[]) AS wb +FROM (VALUES + (-5.2::float8), + (4::float8), + (77::float8), + ('NaN'::float8) +) v(op) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT op, width_bucket(op, ARRAY[1, 3, 9, 'NaN', 'NaN']::float8[]) AS wb FROM (VALUES (...)) v(op)" +== 464 +-- truncate_limit: 100 +-- these exercise the generic fixed-width code path +SELECT + op, + width_bucket(op, ARRAY[1, 3, 5, 10]) AS wb_1 +FROM generate_series(0,11) as op +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT op, width_bucket(op, ARRAY[1, 3, 5, 10]) AS wb_1 FROM generate_series(0, 11) op" +== 465 +-- truncate_limit: 100 +SELECT width_bucket(now(), + array['yesterday', 'today', 'tomorrow']::timestamptz[]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(now(), ARRAY['yesterday', 'today', 'tomorrow']::timestamptz[])" +== 466 +-- truncate_limit: 100 +-- corner cases +SELECT width_bucket(5, ARRAY[3]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(5, ARRAY[3])" +== 467 +-- truncate_limit: 100 +SELECT width_bucket(5, '{}') +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(5, '{}')" +== 468 +-- truncate_limit: 100 +-- error cases +SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket('5'::text, ARRAY[3, 4]::int[])" +== 469 +-- truncate_limit: 100 +SELECT width_bucket(5, ARRAY[3, 4, NULL]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(5, ARRAY[3, 4, NULL])" +== 470 +-- truncate_limit: 100 +SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]])" +== 471 +-- truncate_limit: 100 +-- trim_array + +SELECT arr, trim_array(arr, 2) +FROM +(VALUES ('{1,2,3,4,5,6}'::bigint[]), + ('{1,2}'), + ('[10:16]={1,2,3,4,5,6,7}'), + ('[-15:-10]={1,2,3,4,5,6}'), + ('{{1,10},{2,20},{3,30},{4,40}}')) v(arr) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT arr, trim_array(arr, 2) FROM (VALUES (...)) v(arr)" +== 472 +-- truncate_limit: 100 +SELECT trim_array(ARRAY[1, 2, 3], -1) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_array(ARRAY[1, 2, 3], -1)" +== 473 +-- truncate_limit: 100 +-- fail +SELECT trim_array(ARRAY[1, 2, 3], 10) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_array(ARRAY[1, 2, 3], 10)" +== 474 +-- truncate_limit: 100 +-- fail +SELECT trim_array(ARRAY[]::int[], 1) +-- +FUNCTION: name="trim_array" function="trim_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_array(ARRAY[]::int[], 1)" +== 475 +-- truncate_limit: 100 +-- fail + +-- array_shuffle +SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) <@ '{1,2,3,4,5,6}' +-- +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) <@ '{1,2,3,4,5,6}'" +== 476 +-- truncate_limit: 100 +SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) @> '{1,2,3,4,5,6}' +-- +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) @> '{1,2,3,4,5,6}'" +== 477 +-- truncate_limit: 100 +SELECT array_dims(array_shuffle('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[])) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_dims(array_shuffle('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[]))" +== 478 +-- truncate_limit: 100 +SELECT array_dims(array_shuffle('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[])) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_shuffle" function="array_shuffle" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_dims(array_shuffle('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[]))" +== 479 +-- truncate_limit: 100 +-- array_sample +SELECT array_sample('{1,2,3,4,5,6}'::int[], 3) <@ '{1,2,3,4,5,6}' +-- +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_sample('{1,2,3,4,5,6}'::int[], 3) <@ '{1,2,3,4,5,6}'" +== 480 +-- truncate_limit: 100 +SELECT array_length(array_sample('{1,2,3,4,5,6}'::int[], 3), 1) +-- +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_length(array_sample('{1,2,3,4,5,6}'::int[], 3), 1)" +== 481 +-- truncate_limit: 100 +SELECT array_dims(array_sample('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[], 3)) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_dims(array_sample('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[], 3))" +== 482 +-- truncate_limit: 100 +SELECT array_dims(array_sample('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[], 2)) +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_dims(array_sample('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[], 2))" +== 483 +-- truncate_limit: 100 +SELECT array_sample('{1,2,3,4,5,6}'::int[], -1) +-- +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_sample('{1,2,3,4,5,6}'::int[], -1)" +== 484 +-- truncate_limit: 100 +-- fail +SELECT array_sample('{1,2,3,4,5,6}'::int[], 7) +-- +FUNCTION: name="array_sample" function="array_sample" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_sample('{1,2,3,4,5,6}'::int[], 7)" diff --git a/parser/testdata/summary_truncate/postgres_regress/async.metadata.json b/parser/testdata/summary_truncate/postgres_regress/async.metadata.json new file mode 100644 index 0000000..4739b17 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/async.metadata.json @@ -0,0 +1,15 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/async.test b/parser/testdata/summary_truncate/postgres_regress/async.test new file mode 100644 index 0000000..342128c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/async.test @@ -0,0 +1,82 @@ +== 001 +-- truncate_limit: 100 +|-- +-- ASYNC +|-- + +--Should work. Send a valid message via a valid channel name +SELECT pg_notify('notify_async1','sample message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_notify('notify_async1', 'sample message1')" +== 002 +-- truncate_limit: 100 +SELECT pg_notify('notify_async1','') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_notify('notify_async1', '')" +== 003 +-- truncate_limit: 100 +SELECT pg_notify('notify_async1',NULL) +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_notify('notify_async1', NULL)" +== 004 +-- truncate_limit: 100 +-- Should fail. Send a valid message via an invalid channel name +SELECT pg_notify('','sample message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_notify('', 'sample message1')" +== 005 +-- truncate_limit: 100 +SELECT pg_notify(NULL,'sample message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_notify(NULL, 'sample message1')" +== 006 +-- truncate_limit: 100 +SELECT pg_notify('notify_async_channel_name_too_long______________________________','sample_message1') +-- +FUNCTION: name="pg_notify" function="pg_notify" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 007 +-- truncate_limit: 100 +--Should work. Valid NOTIFY/LISTEN/UNLISTEN commands +NOTIFY notify_async2 +-- +STMT: NotifyStmt +TRUNCATED: "NOTIFY notify_async2" +== 008 +-- truncate_limit: 100 +LISTEN notify_async2 +-- +STMT: ListenStmt +TRUNCATED: "LISTEN notify_async2" +== 009 +-- truncate_limit: 100 +UNLISTEN notify_async2 +-- +STMT: UnlistenStmt +TRUNCATED: "UNLISTEN notify_async2" +== 010 +-- truncate_limit: 100 +UNLISTEN * +-- +STMT: UnlistenStmt +TRUNCATED: "UNLISTEN *" +== 011 +-- truncate_limit: 100 +-- Should return zero while there are no pending notifications. +-- src/test/isolation/specs/async-notify.spec tests for actual usage. +SELECT pg_notification_queue_usage() +-- +FUNCTION: name="pg_notification_queue_usage" function="pg_notification_queue_usage" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_notification_queue_usage()" diff --git a/parser/testdata/summary_truncate/postgres_regress/bit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/bit.metadata.json new file mode 100644 index 0000000..0b25d44 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/bit.metadata.json @@ -0,0 +1,136 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/bit.test b/parser/testdata/summary_truncate/postgres_regress/bit.test new file mode 100644 index 0000000..80fd39d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/bit.test @@ -0,0 +1,1077 @@ +== 001 +-- truncate_limit: 100 +|-- +-- BIT types +|-- + +|-- +-- Build tables for testing +|-- + +CREATE TABLE BIT_TABLE(b BIT(11)) +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bit_table (b pg_catalog.bit(11))" +== 002 +-- truncate_limit: 100 +INSERT INTO BIT_TABLE VALUES (B'10') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_table VALUES (b'10')" +== 003 +-- truncate_limit: 100 +-- too short +INSERT INTO BIT_TABLE VALUES (B'00000000000') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_table VALUES (b'00000000000')" +== 004 +-- truncate_limit: 100 +INSERT INTO BIT_TABLE VALUES (B'11011000000') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_table VALUES (b'11011000000')" +== 005 +-- truncate_limit: 100 +INSERT INTO BIT_TABLE VALUES (B'01010101010') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_table VALUES (b'01010101010')" +== 006 +-- truncate_limit: 100 +INSERT INTO BIT_TABLE VALUES (B'101011111010') +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_table VALUES (b'101011111010')" +== 007 +-- truncate_limit: 100 +-- too long +--INSERT INTO BIT_TABLE VALUES ('X554'); +--INSERT INTO BIT_TABLE VALUES ('X555'); + +SELECT * FROM BIT_TABLE +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bit_table" +== 008 +-- truncate_limit: 100 +CREATE TABLE VARBIT_TABLE(v BIT VARYING(11)) +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE varbit_table (v pg_catalog.varbit(11))" +== 009 +-- truncate_limit: 100 +INSERT INTO VARBIT_TABLE VALUES (B'') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_table VALUES (b'')" +== 010 +-- truncate_limit: 100 +INSERT INTO VARBIT_TABLE VALUES (B'0') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_table VALUES (b'0')" +== 011 +-- truncate_limit: 100 +INSERT INTO VARBIT_TABLE VALUES (B'010101') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_table VALUES (b'010101')" +== 012 +-- truncate_limit: 100 +INSERT INTO VARBIT_TABLE VALUES (B'01010101010') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_table VALUES (b'01010101010')" +== 013 +-- truncate_limit: 100 +INSERT INTO VARBIT_TABLE VALUES (B'101011111010') +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_table VALUES (b'101011111010')" +== 014 +-- truncate_limit: 100 +-- too long +--INSERT INTO VARBIT_TABLE VALUES ('X554'); +--INSERT INTO VARBIT_TABLE VALUES ('X555'); +SELECT * FROM VARBIT_TABLE +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM varbit_table" +== 015 +-- truncate_limit: 100 +-- Literals with syntax errors +SELECT b' 0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT b' 0'" +== 016 +-- truncate_limit: 100 +SELECT b'0 ' +-- +STMT: SelectStmt +TRUNCATED: "SELECT b'0 '" +== 017 +-- truncate_limit: 100 +SELECT x' 0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT x' 0'" +== 018 +-- truncate_limit: 100 +SELECT x'0 ' +-- +STMT: SelectStmt +TRUNCATED: "SELECT x'0 '" +== 019 +-- truncate_limit: 100 +-- Concatenation +SELECT v, b, (v || b) AS concat + FROM BIT_TABLE, VARBIT_TABLE + ORDER BY 3 +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT v, b, v || b AS concat FROM bit_table, varbit_table ORDER BY 3" +== 020 +-- truncate_limit: 100 +-- Length +SELECT b, length(b) AS lb + FROM BIT_TABLE +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT b, length(b) AS lb FROM bit_table" +== 021 +-- truncate_limit: 100 +SELECT v, length(v) AS lv + FROM VARBIT_TABLE +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, length(v) AS lv FROM varbit_table" +== 022 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bit_table" +== 023 +-- truncate_limit: 100 +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 +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM varbit_table" +== 024 +-- truncate_limit: 100 +-- test overflow cases +SELECT SUBSTRING('01010101'::bit(8) FROM 2 FOR 2147483646) AS "1010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('01010101'::pg_catalog.bit(8) FROM 2 FOR 2147483646) AS \"1010101\"" +== 025 +-- truncate_limit: 100 +SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR 2147483646) AS "01010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('01010101'::pg_catalog.bit(8) FROM -10 FOR 2147483646) AS \"01010101\"" +== 026 +-- truncate_limit: 100 +SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR -2147483646) AS "error" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('01010101'::pg_catalog.bit(8) FROM -10 FOR -2147483646) AS error" +== 027 +-- truncate_limit: 100 +SELECT SUBSTRING('01010101'::varbit FROM 2 FOR 2147483646) AS "1010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('01010101'::varbit FROM 2 FOR 2147483646) AS \"1010101\"" +== 028 +-- truncate_limit: 100 +SELECT SUBSTRING('01010101'::varbit FROM -10 FOR 2147483646) AS "01010101" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('01010101'::varbit FROM -10 FOR 2147483646) AS \"01010101\"" +== 029 +-- truncate_limit: 100 +SELECT SUBSTRING('01010101'::varbit FROM -10 FOR -2147483646) AS "error" +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('01010101'::varbit FROM -10 FOR -2147483646) AS error" +== 030 +-- truncate_limit: 100 +--- Bit operations +DROP TABLE varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE varbit_table" +== 031 +-- truncate_limit: 100 +CREATE TABLE varbit_table (a BIT VARYING(16), b BIT VARYING(16)) +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE varbit_table (a pg_catalog.varbit(16), b pg_catalog.varbit(16))" +== 032 +-- truncate_limit: 100 +COPY varbit_table FROM stdin +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY varbit_table FROM STDIN" +== 033 +-- truncate_limit: 100 +SELECT a, b, ~a AS "~ a", a & b AS "a & b", + a | b AS "a | b", a # b AS "a # b" FROM varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, ~ a AS \"~ a\", a & b AS \"a & b\", a | b AS \"a | b\", a # b AS \"a # b\" FROM varbit_table" +== 034 +-- truncate_limit: 100 +SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM varbit_table" +== 035 +-- truncate_limit: 100 +SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, a << 4 AS \"a<<4\", b, b >> 2 AS \"b>>2\" FROM varbit_table" +== 036 +-- truncate_limit: 100 +DROP TABLE varbit_table +-- +TABLE: name="varbit_table" schema="" table="varbit_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE varbit_table" +== 037 +-- truncate_limit: 100 +--- Bit operations +DROP TABLE bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bit_table" +== 038 +-- truncate_limit: 100 +CREATE TABLE bit_table (a BIT(16), b BIT(16)) +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bit_table (a pg_catalog.bit(16), b pg_catalog.bit(16))" +== 039 +-- truncate_limit: 100 +COPY bit_table FROM stdin +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY bit_table FROM STDIN" +== 040 +-- truncate_limit: 100 +SELECT a,b,~a AS "~ a",a & b AS "a & b", + a|b AS "a | b", a # b AS "a # b" FROM bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, ~ a AS \"~ a\", a & b AS \"a & b\", a | b AS \"a | b\", a # b AS \"a # b\" FROM bit_table" +== 041 +-- truncate_limit: 100 +SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bit_table" +== 042 +-- truncate_limit: 100 +SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, a << 4 AS \"a<<4\", b, b >> 2 AS \"b>>2\" FROM bit_table" +== 043 +-- truncate_limit: 100 +DROP TABLE bit_table +-- +TABLE: name="bit_table" schema="" table="bit_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bit_table" +== 044 +-- truncate_limit: 100 +-- The following should fail +select B'001' & B'10' +-- +STMT: SelectStmt +TRUNCATED: "SELECT b'001' & b'10'" +== 045 +-- truncate_limit: 100 +select B'0111' | B'011' +-- +STMT: SelectStmt +TRUNCATED: "SELECT b'0111' | b'011'" +== 046 +-- truncate_limit: 100 +select B'0010' # B'011101' +-- +STMT: SelectStmt +TRUNCATED: "SELECT b'0010' # b'011101'" +== 047 +-- truncate_limit: 100 +-- More position tests, checking all the boundary cases +SELECT POSITION(B'1010' IN B'0000101') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1010' IN b'0000101')" +== 048 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'1010' IN B'00001010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1010' IN b'00001010')" +== 049 +-- truncate_limit: 100 +-- 5 +SELECT POSITION(B'1010' IN B'00000101') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1010' IN b'00000101')" +== 050 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'1010' IN B'000001010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1010' IN b'000001010')" +== 051 +-- truncate_limit: 100 +-- 6 + +SELECT POSITION(B'' IN B'00001010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'' IN b'00001010')" +== 052 +-- truncate_limit: 100 +-- 1 +SELECT POSITION(B'0' IN B'') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'0' IN b'')" +== 053 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'' IN B'') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'' IN b'')" +== 054 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'101101' IN B'001011011011011000') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'101101' IN b'001011011011011000')" +== 055 +-- truncate_limit: 100 +-- 3 +SELECT POSITION(B'10110110' IN B'001011011011010') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'10110110' IN b'001011011011010')" +== 056 +-- truncate_limit: 100 +-- 3 +SELECT POSITION(B'1011011011011' IN B'001011011011011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1011011011011' IN b'001011011011011')" +== 057 +-- truncate_limit: 100 +-- 3 +SELECT POSITION(B'1011011011011' IN B'00001011011011011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1011011011011' IN b'00001011011011011')" +== 058 +-- truncate_limit: 100 +-- 5 + +SELECT POSITION(B'11101011' IN B'11101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'11101011' IN b'11101011')" +== 059 +-- truncate_limit: 100 +-- 1 +SELECT POSITION(B'11101011' IN B'011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'11101011' IN b'011101011')" +== 060 +-- truncate_limit: 100 +-- 2 +SELECT POSITION(B'11101011' IN B'00011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'11101011' IN b'00011101011')" +== 061 +-- truncate_limit: 100 +-- 4 +SELECT POSITION(B'11101011' IN B'0000011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'11101011' IN b'0000011101011')" +== 062 +-- truncate_limit: 100 +-- 6 + +SELECT POSITION(B'111010110' IN B'111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'111010110')" +== 063 +-- truncate_limit: 100 +-- 1 +SELECT POSITION(B'111010110' IN B'0111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'0111010110')" +== 064 +-- truncate_limit: 100 +-- 2 +SELECT POSITION(B'111010110' IN B'000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'000111010110')" +== 065 +-- truncate_limit: 100 +-- 4 +SELECT POSITION(B'111010110' IN B'00000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'00000111010110')" +== 066 +-- truncate_limit: 100 +-- 6 + +SELECT POSITION(B'111010110' IN B'11101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'11101011')" +== 067 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'111010110' IN B'011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'011101011')" +== 068 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'111010110' IN B'00011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'00011101011')" +== 069 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'111010110' IN B'0000011101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'0000011101011')" +== 070 +-- truncate_limit: 100 +-- 0 + +SELECT POSITION(B'111010110' IN B'111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'111010110')" +== 071 +-- truncate_limit: 100 +-- 1 +SELECT POSITION(B'111010110' IN B'0111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'0111010110')" +== 072 +-- truncate_limit: 100 +-- 2 +SELECT POSITION(B'111010110' IN B'000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'000111010110')" +== 073 +-- truncate_limit: 100 +-- 4 +SELECT POSITION(B'111010110' IN B'00000111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'00000111010110')" +== 074 +-- truncate_limit: 100 +-- 6 + +SELECT POSITION(B'111010110' IN B'000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'000001110101111101011')" +== 075 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'111010110' IN B'0000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'0000001110101111101011')" +== 076 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'111010110' IN B'000000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'000000001110101111101011')" +== 077 +-- truncate_limit: 100 +-- 0 +SELECT POSITION(B'111010110' IN B'00000000001110101111101011') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'00000000001110101111101011')" +== 078 +-- truncate_limit: 100 +-- 0 + +SELECT POSITION(B'111010110' IN B'0000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'0000011101011111010110')" +== 079 +-- truncate_limit: 100 +-- 14 +SELECT POSITION(B'111010110' IN B'00000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'00000011101011111010110')" +== 080 +-- truncate_limit: 100 +-- 15 +SELECT POSITION(B'111010110' IN B'0000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'0000000011101011111010110')" +== 081 +-- truncate_limit: 100 +-- 17 +SELECT POSITION(B'111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'111010110' IN b'000000000011101011111010110')" +== 082 +-- truncate_limit: 100 +-- 19 + +SELECT POSITION(B'000000000011101011111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'000000000011101011111010110' IN b'000000000011101011111010110')" +== 083 +-- truncate_limit: 100 +-- 1 +SELECT POSITION(B'00000000011101011111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'00000000011101011111010110' IN b'000000000011101011111010110')" +== 084 +-- truncate_limit: 100 +-- 2 +SELECT POSITION(B'0000000000011101011111010110' IN B'000000000011101011111010110') +-- +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'0000000000011101011111010110' IN b'000000000011101011111010110')" +== 085 +-- truncate_limit: 100 +-- 0 + + +-- Shifting + +CREATE TABLE BIT_SHIFT_TABLE(b BIT(16)) +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bit_shift_table (b pg_catalog.bit(16))" +== 086 +-- truncate_limit: 100 +INSERT INTO BIT_SHIFT_TABLE VALUES (B'1101100000000000') +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_shift_table VALUES (b'1101100000000000')" +== 087 +-- truncate_limit: 100 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>1 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_shift_table SELECT b >> 1 FROM bit_shift_table" +== 088 +-- truncate_limit: 100 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>2 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_shift_table SELECT b >> 2 FROM bit_shift_table" +== 089 +-- truncate_limit: 100 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>4 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_shift_table SELECT b >> 4 FROM bit_shift_table" +== 090 +-- truncate_limit: 100 +INSERT INTO BIT_SHIFT_TABLE SELECT b>>8 FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DML +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bit_shift_table SELECT b >> 8 FROM bit_shift_table" +== 091 +-- truncate_limit: 100 +SELECT POSITION(B'1101' IN b), + POSITION(B'11011' IN b), + b + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1101' IN b), POSITION(b'11011' IN b), b FROM bit_shift_table" +== 092 +-- truncate_limit: 100 +SELECT b, b >> 1 AS bsr, b << 1 AS bsl + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b, b >> 1 AS bsr, b << 1 AS bsl FROM bit_shift_table" +== 093 +-- truncate_limit: 100 +SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8 + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8 FROM bit_shift_table" +== 094 +-- truncate_limit: 100 +SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bit_shift_table" +== 095 +-- truncate_limit: 100 +SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8 + FROM BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM bit_shift_table" +== 096 +-- truncate_limit: 100 +CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20)) +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE varbit_shift_table (v pg_catalog.varbit(20))" +== 097 +-- truncate_limit: 100 +INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011') +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_shift_table VALUES (b'11011')" +== 098 +-- truncate_limit: 100 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0' AS BIT VARYING(6)) >>1 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_shift_table SELECT (v || b'0')::pg_catalog.varbit(6) >> 1 FROM varbit_shift_table" +== 099 +-- truncate_limit: 100 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00' AS BIT VARYING(8)) >>2 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_shift_table SELECT ... FROM varbit_shift_table" +== 100 +-- truncate_limit: 100 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0000' AS BIT VARYING(12)) >>4 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_shift_table SELECT ... FROM varbit_shift_table" +== 101 +-- truncate_limit: 100 +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00000000' AS BIT VARYING(20)) >>8 FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DML +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varbit_shift_table SELECT ... FROM varbit_shift_table" +== 102 +-- truncate_limit: 100 +SELECT POSITION(B'1101' IN v), + POSITION(B'11011' IN v), + v + FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT POSITION(b'1101' IN v), POSITION(b'11011' IN v), v FROM varbit_shift_table" +== 103 +-- truncate_limit: 100 +SELECT v, v >> 1 AS vsr, v << 1 AS vsl + FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT v, v >> 1 AS vsr, v << 1 AS vsl FROM varbit_shift_table" +== 104 +-- truncate_limit: 100 +SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8 + FROM VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8 FROM varbit_shift_table" +== 105 +-- truncate_limit: 100 +DROP TABLE BIT_SHIFT_TABLE +-- +TABLE: name="bit_shift_table" schema="" table="bit_shift_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bit_shift_table" +== 106 +-- truncate_limit: 100 +DROP TABLE VARBIT_SHIFT_TABLE +-- +TABLE: name="varbit_shift_table" schema="" table="varbit_shift_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE varbit_shift_table" +== 107 +-- truncate_limit: 100 +-- Get/Set bit +SELECT get_bit(B'0101011000100', 10) +-- +FUNCTION: name="get_bit" function="get_bit" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT get_bit(b'0101011000100', 10)" +== 108 +-- truncate_limit: 100 +SELECT set_bit(B'0101011000100100', 15, 1) +-- +FUNCTION: name="set_bit" function="set_bit" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_bit(b'0101011000100100', 15, 1)" +== 109 +-- truncate_limit: 100 +SELECT set_bit(B'0101011000100100', 16, 1) +-- +FUNCTION: name="set_bit" function="set_bit" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_bit(b'0101011000100100', 16, 1)" +== 110 +-- truncate_limit: 100 +-- fail + +-- Overlay +SELECT overlay(B'0101011100' placing '001' from 2 for 3) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT OVERLAY(b'0101011100' PLACING '001' FROM 2 FOR 3)" +== 111 +-- truncate_limit: 100 +SELECT overlay(B'0101011100' placing '101' from 6) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT overlay(b'0101011100' placing '101' from 6)" +== 112 +-- truncate_limit: 100 +SELECT overlay(B'0101011100' placing '001' from 11) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT overlay(b'0101011100' placing '001' from 11)" +== 113 +-- truncate_limit: 100 +SELECT overlay(B'0101011100' placing '001' from 20) +-- +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT overlay(b'0101011100' placing '001' from 20)" +== 114 +-- truncate_limit: 100 +-- bit_count +SELECT bit_count(B'0101011100'::bit(10)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bit_count(b'0101011100'::pg_catalog.bit(10))" +== 115 +-- truncate_limit: 100 +SELECT bit_count(B'1111111111'::bit(10)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bit_count(b'1111111111'::pg_catalog.bit(10))" +== 116 +-- truncate_limit: 100 +SELECT bit_count(repeat('0', 100)::bit(100)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bit_count(repeat('0', 100)::pg_catalog.bit(100))" +== 117 +-- truncate_limit: 100 +SELECT bit_count(repeat('1', 100)::bit(100)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bit_count(repeat('1', 100)::pg_catalog.bit(100))" +== 118 +-- truncate_limit: 100 +SELECT bit_count(repeat('01', 500)::bit(1000)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bit_count(repeat('01', 500)::pg_catalog.bit(1000))" +== 119 +-- truncate_limit: 100 +SELECT bit_count(repeat('10101', 200)::bit(1000)) +-- +FUNCTION: name="bit_count" function="bit_count" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bit_count(repeat('10101', 200)::pg_catalog.bit(1000))" +== 120 +-- truncate_limit: 100 +-- 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' +) +-- +TABLE: name="bit_defaults" schema="" table="bit_defaults" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bit_defaults (b1 pg_catalog.bit(4) DEFAULT '1001', b2 pg_catalog.bit(4) DEFAULT b'01..." +== 121 +-- truncate_limit: 100 +INSERT INTO bit_defaults DEFAULT VALUES +-- +TABLE: name="bit_defaults" schema="" table="bit_defaults" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO bit_defaults DEFAULT VALUES" +== 122 +-- truncate_limit: 100 +TABLE bit_defaults +-- +TABLE: name="bit_defaults" schema="" table="bit_defaults" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bit_defaults" +== 123 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('01010001', 'bit(10)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('01010001', 'bit(10)')" +== 124 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('01010001', 'bit(10)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('01010001', 'bit(10)')" +== 125 +-- truncate_limit: 100 +SELECT pg_input_is_valid('01010Z01', 'bit(8)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('01010Z01', 'bit(8)')" +== 126 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('01010Z01', 'bit(8)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('01010Z01', 'bit(8)')" +== 127 +-- truncate_limit: 100 +SELECT pg_input_is_valid('x01010Z01', 'bit(32)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('x01010Z01', 'bit(32)')" +== 128 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('x01010Z01', 'bit(32)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('x01010Z01', 'bit(32)')" +== 129 +-- truncate_limit: 100 +SELECT pg_input_is_valid('01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('01010Z01', 'varbit')" +== 130 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('01010Z01', 'varbit')" +== 131 +-- truncate_limit: 100 +SELECT pg_input_is_valid('x01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('x01010Z01', 'varbit')" +== 132 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('x01010Z01', 'varbit') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('x01010Z01', 'varbit')" diff --git a/parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json b/parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json new file mode 100644 index 0000000..92b8f9e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json @@ -0,0 +1,14 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/bitmapops.test b/parser/testdata/summary_truncate/postgres_regress/bitmapops.test new file mode 100644 index 0000000..1f19548 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/bitmapops.test @@ -0,0 +1,97 @@ +== 001 +-- truncate_limit: 100 +-- Test bitmap AND and OR + + +-- Generate enough data that we can test the lossy bitmaps. + +-- There's 55 tuples per page in the table. 53 is just +-- below 55, so that an index scan with qual a = constant +-- will return at least one hit per page. 59 is just above +-- 55, so that an index scan with qual b = constant will return +-- hits on most but not all pages. 53 and 59 are prime, so that +-- there's a maximum number of a,b combinations in the table. +-- That allows us to test all the different combinations of +-- lossy and non-lossy pages with the minimum amount of data + +CREATE TABLE bmscantest (a int, b int, t text) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bmscantest (a int, b int, t text)" +== 002 +-- truncate_limit: 100 +INSERT INTO bmscantest + SELECT (r%53), (r%59), 'foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' + FROM generate_series(1,70000) r +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bmscantest SELECT ... FROM generate_series(1, 70000) r" +== 003 +-- truncate_limit: 100 +CREATE INDEX i_bmtest_a ON bmscantest(a) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX i_bmtest_a ON bmscantest USING btree (a)" +== 004 +-- truncate_limit: 100 +CREATE INDEX i_bmtest_b ON bmscantest(b) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX i_bmtest_b ON bmscantest USING btree (b)" +== 005 +-- truncate_limit: 100 +-- We want to use bitmapscans. With default settings, the planner currently +-- chooses a bitmap scan for the queries below anyway, but let's make sure. +set enable_indexscan=false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO FALSE" +== 006 +-- truncate_limit: 100 +set enable_seqscan=false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO FALSE" +== 007 +-- truncate_limit: 100 +-- Lower work_mem to trigger use of lossy bitmaps +set work_mem = 64 +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO 64" +== 008 +-- truncate_limit: 100 +-- Test bitmap-and. +SELECT count(*) FROM bmscantest WHERE a = 1 AND b = 1 +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM bmscantest WHERE a = 1 AND b = 1" +== 009 +-- truncate_limit: 100 +-- Test bitmap-or. +SELECT count(*) FROM bmscantest WHERE a = 1 OR b = 1 +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM bmscantest WHERE a = 1 OR b = 1" +== 010 +-- truncate_limit: 100 +-- clean up +DROP TABLE bmscantest +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bmscantest" diff --git a/parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json b/parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json new file mode 100644 index 0000000..463f4d4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json @@ -0,0 +1,102 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/boolean.test b/parser/testdata/summary_truncate/postgres_regress/boolean.test new file mode 100644 index 0000000..61109cc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/boolean.test @@ -0,0 +1,775 @@ +== 001 +-- truncate_limit: 100 +|-- +-- BOOLEAN +|-- + +|-- +-- sanity check - if this fails go insane! +|-- +SELECT 1 AS one +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one" +== 002 +-- truncate_limit: 100 +-- ******************testing built-in type bool******************** + +-- check bool input syntax + +SELECT true AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT true AS \"true\"" +== 003 +-- truncate_limit: 100 +SELECT false AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT false AS \"false\"" +== 004 +-- truncate_limit: 100 +SELECT bool 't' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 't'::bool AS \"true\"" +== 005 +-- truncate_limit: 100 +SELECT bool ' f ' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' f '::bool AS \"false\"" +== 006 +-- truncate_limit: 100 +SELECT bool 'true' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true'::bool AS \"true\"" +== 007 +-- truncate_limit: 100 +SELECT bool 'test' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'test'::bool AS error" +== 008 +-- truncate_limit: 100 +SELECT bool 'false' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'false'::bool AS \"false\"" +== 009 +-- truncate_limit: 100 +SELECT bool 'foo' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo'::bool AS error" +== 010 +-- truncate_limit: 100 +SELECT bool 'y' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'y'::bool AS \"true\"" +== 011 +-- truncate_limit: 100 +SELECT bool 'yes' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'yes'::bool AS \"true\"" +== 012 +-- truncate_limit: 100 +SELECT bool 'yeah' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'yeah'::bool AS error" +== 013 +-- truncate_limit: 100 +SELECT bool 'n' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'n'::bool AS \"false\"" +== 014 +-- truncate_limit: 100 +SELECT bool 'no' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'no'::bool AS \"false\"" +== 015 +-- truncate_limit: 100 +SELECT bool 'nay' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nay'::bool AS error" +== 016 +-- truncate_limit: 100 +SELECT bool 'on' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'on'::bool AS \"true\"" +== 017 +-- truncate_limit: 100 +SELECT bool 'off' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'off'::bool AS \"false\"" +== 018 +-- truncate_limit: 100 +SELECT bool 'of' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'of'::bool AS \"false\"" +== 019 +-- truncate_limit: 100 +SELECT bool 'o' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'o'::bool AS error" +== 020 +-- truncate_limit: 100 +SELECT bool 'on_' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'on_'::bool AS error" +== 021 +-- truncate_limit: 100 +SELECT bool 'off_' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'off_'::bool AS error" +== 022 +-- truncate_limit: 100 +SELECT bool '1' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::bool AS \"true\"" +== 023 +-- truncate_limit: 100 +SELECT bool '11' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11'::bool AS error" +== 024 +-- truncate_limit: 100 +SELECT bool '0' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0'::bool AS \"false\"" +== 025 +-- truncate_limit: 100 +SELECT bool '000' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT '000'::bool AS error" +== 026 +-- truncate_limit: 100 +SELECT bool '' AS error +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::bool AS error" +== 027 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('true', 'bool') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('true', 'bool')" +== 028 +-- truncate_limit: 100 +SELECT pg_input_is_valid('asdf', 'bool') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('asdf', 'bool')" +== 029 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('junk', 'bool') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('junk', 'bool')" +== 030 +-- truncate_limit: 100 +-- and, or, not in qualifications + +SELECT bool 't' or bool 'f' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 't'::bool OR 'f'::bool AS \"true\"" +== 031 +-- truncate_limit: 100 +SELECT bool 't' and bool 'f' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 't'::bool AND 'f'::bool AS \"false\"" +== 032 +-- truncate_limit: 100 +SELECT not bool 'f' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT NOT 'f'::bool AS \"true\"" +== 033 +-- truncate_limit: 100 +SELECT bool 't' = bool 'f' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 't'::bool = 'f'::bool AS \"false\"" +== 034 +-- truncate_limit: 100 +SELECT bool 't' <> bool 'f' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 't'::bool <> 'f'::bool AS \"true\"" +== 035 +-- truncate_limit: 100 +SELECT bool 't' > bool 'f' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 't'::bool > 'f'::bool AS \"true\"" +== 036 +-- truncate_limit: 100 +SELECT bool 't' >= bool 'f' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 't'::bool >= 'f'::bool AS \"true\"" +== 037 +-- truncate_limit: 100 +SELECT bool 'f' < bool 't' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'f'::bool < 't'::bool AS \"true\"" +== 038 +-- truncate_limit: 100 +SELECT bool 'f' <= bool 't' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'f'::bool <= 't'::bool AS \"true\"" +== 039 +-- truncate_limit: 100 +-- explicit casts to/from text +SELECT 'TrUe'::text::boolean AS true, 'fAlse'::text::boolean AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'TrUe'::text::boolean AS \"true\", 'fAlse'::text::boolean AS \"false\"" +== 040 +-- truncate_limit: 100 +SELECT ' true '::text::boolean AS true, + ' FALSE'::text::boolean AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' true '::text::boolean AS \"true\", ' FALSE'::text::boolean AS \"false\"" +== 041 +-- truncate_limit: 100 +SELECT true::boolean::text AS true, false::boolean::text AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT true::boolean::text AS \"true\", false::boolean::text AS \"false\"" +== 042 +-- truncate_limit: 100 +SELECT ' tru e '::text::boolean AS invalid +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' tru e '::text::boolean AS invalid" +== 043 +-- truncate_limit: 100 +-- error +SELECT ''::text::boolean AS invalid +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::text::boolean AS invalid" +== 044 +-- truncate_limit: 100 +-- error + +CREATE TABLE BOOLTBL1 (f1 bool) +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE booltbl1 (f1 bool)" +== 045 +-- truncate_limit: 100 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 't') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl1 (f1) VALUES ('t'::bool)" +== 046 +-- truncate_limit: 100 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'True') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl1 (f1) VALUES ('True'::bool)" +== 047 +-- truncate_limit: 100 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'true') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl1 (f1) VALUES ('true'::bool)" +== 048 +-- truncate_limit: 100 +-- BOOLTBL1 should be full of true's at this point +SELECT BOOLTBL1.* FROM BOOLTBL1 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.* FROM booltbl1" +== 049 +-- truncate_limit: 100 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 = bool 'true' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.* FROM booltbl1 WHERE f1 = 'true'::bool" +== 050 +-- truncate_limit: 100 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 <> bool 'false' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.* FROM booltbl1 WHERE f1 <> 'false'::bool" +== 051 +-- truncate_limit: 100 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE booleq(bool 'false', f1) +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FUNCTION: name="booleq" function="booleq" schema="" ctx=Call +FUNCTION: name="booleq" function="booleq" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.* FROM booltbl1 WHERE booleq('false'::bool, f1)" +== 052 +-- truncate_limit: 100 +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'f') +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl1 (f1) VALUES ('f'::bool)" +== 053 +-- truncate_limit: 100 +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 = bool 'false' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.* FROM booltbl1 WHERE f1 = 'false'::bool" +== 054 +-- truncate_limit: 100 +CREATE TABLE BOOLTBL2 (f1 bool) +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE booltbl2 (f1 bool)" +== 055 +-- truncate_limit: 100 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'f') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl2 (f1) VALUES ('f'::bool)" +== 056 +-- truncate_limit: 100 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'false') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl2 (f1) VALUES ('false'::bool)" +== 057 +-- truncate_limit: 100 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'False') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl2 (f1) VALUES ('False'::bool)" +== 058 +-- truncate_limit: 100 +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'FALSE') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl2 (f1) VALUES ('FALSE'::bool)" +== 059 +-- truncate_limit: 100 +-- This is now an invalid expression +-- For pre-v6.3 this evaluated to false - thomas 1997-10-23 +INSERT INTO BOOLTBL2 (f1) + VALUES (bool 'XXX') +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl2 (f1) VALUES ('XXX'::bool)" +== 060 +-- truncate_limit: 100 +-- BOOLTBL2 should be full of false's at this point +SELECT BOOLTBL2.* FROM BOOLTBL2 +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT booltbl2.* FROM booltbl2" +== 061 +-- truncate_limit: 100 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 <> BOOLTBL1.f1 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.*, booltbl2.* FROM booltbl1, booltbl2 WHERE booltbl2.f1 <> booltbl1.f1" +== 062 +-- truncate_limit: 100 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE boolne(BOOLTBL2.f1,BOOLTBL1.f1) +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FUNCTION: name="boolne" function="boolne" schema="" ctx=Call +FUNCTION: name="boolne" function="boolne" schema="" ctx=Call +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.*, booltbl2.* FROM booltbl1, booltbl2 WHERE boolne(booltbl2.f1, booltbl1.f1)" +== 063 +-- truncate_limit: 100 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 = BOOLTBL1.f1 and BOOLTBL1.f1 = bool 'false' +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.*, booltbl2.* FROM booltbl1, booltbl2 WHERE ..." +== 064 +-- truncate_limit: 100 +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 = BOOLTBL1.f1 or BOOLTBL1.f1 = bool 'true' + ORDER BY BOOLTBL1.f1, BOOLTBL2.f1 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="booltbl2" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +FILTER: schema="" table="booltbl1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT booltbl1.*, booltbl2.* FROM booltbl1, booltbl2 WHERE ... ORDER BY booltbl1.f1, booltbl2.f1" +== 065 +-- truncate_limit: 100 +|-- +-- SQL syntax +-- Try all combinations to ensure that we get nothing when we expect nothing +-- - thomas 2000-01-04 +|-- + +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS TRUE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl1 WHERE f1 IS TRUE" +== 066 +-- truncate_limit: 100 +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS NOT FALSE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl1 WHERE f1 IS NOT FALSE" +== 067 +-- truncate_limit: 100 +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS FALSE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl1 WHERE f1 IS FALSE" +== 068 +-- truncate_limit: 100 +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS NOT TRUE +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl1 WHERE f1 IS NOT TRUE" +== 069 +-- truncate_limit: 100 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS TRUE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl2 WHERE f1 IS TRUE" +== 070 +-- truncate_limit: 100 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS NOT FALSE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl2 WHERE f1 IS NOT FALSE" +== 071 +-- truncate_limit: 100 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS FALSE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl2 WHERE f1 IS FALSE" +== 072 +-- truncate_limit: 100 +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS NOT TRUE +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM booltbl2 WHERE f1 IS NOT TRUE" +== 073 +-- truncate_limit: 100 +|-- +-- Tests for BooleanTest +|-- +CREATE TABLE BOOLTBL3 (d text, b bool, o int) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE booltbl3 (d text, b bool, o int)" +== 074 +-- truncate_limit: 100 +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('true', true, 1) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl3 (d, b, o) VALUES ('true', true, 1)" +== 075 +-- truncate_limit: 100 +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('false', false, 2) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl3 (d, b, o) VALUES ('false', false, 2)" +== 076 +-- truncate_limit: 100 +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('null', null, 3) +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl3 (d, b, o) VALUES ('null', NULL, 3)" +== 077 +-- truncate_limit: 100 +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 +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM booltbl3 ORDER BY o" +== 078 +-- truncate_limit: 100 +-- Test to make sure short-circuiting and NULL handling is +-- correct. Use a table as source to prevent constant simplification +-- from interfering. +CREATE TABLE booltbl4(isfalse bool, istrue bool, isnul bool) +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE booltbl4 (isfalse bool, istrue bool, isnul bool)" +== 079 +-- truncate_limit: 100 +INSERT INTO booltbl4 VALUES (false, true, null) +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO booltbl4 VALUES (false, true, NULL)" +== 080 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT istrue AND isnul AND istrue FROM booltbl4" +== 081 +-- truncate_limit: 100 +SELECT istrue AND istrue AND isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT istrue AND istrue AND isnul FROM booltbl4" +== 082 +-- truncate_limit: 100 +SELECT isnul AND istrue AND istrue FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isnul AND istrue AND istrue FROM booltbl4" +== 083 +-- truncate_limit: 100 +SELECT isfalse AND isnul AND istrue FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isfalse AND isnul AND istrue FROM booltbl4" +== 084 +-- truncate_limit: 100 +SELECT istrue AND isfalse AND isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT istrue AND isfalse AND isnul FROM booltbl4" +== 085 +-- truncate_limit: 100 +SELECT isnul AND istrue AND isfalse FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isnul AND istrue AND isfalse FROM booltbl4" +== 086 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isfalse OR isnul OR isfalse FROM booltbl4" +== 087 +-- truncate_limit: 100 +SELECT isfalse OR isfalse OR isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isfalse OR isfalse OR isnul FROM booltbl4" +== 088 +-- truncate_limit: 100 +SELECT isnul OR isfalse OR isfalse FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isnul OR isfalse OR isfalse FROM booltbl4" +== 089 +-- truncate_limit: 100 +SELECT isfalse OR isnul OR istrue FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isfalse OR isnul OR istrue FROM booltbl4" +== 090 +-- truncate_limit: 100 +SELECT istrue OR isfalse OR isnul FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT istrue OR isfalse OR isnul FROM booltbl4" +== 091 +-- truncate_limit: 100 +SELECT isnul OR istrue OR isfalse FROM booltbl4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT isnul OR istrue OR isfalse FROM booltbl4" +== 092 +-- truncate_limit: 100 +-- Casts +SELECT 0::boolean +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0::boolean" +== 093 +-- truncate_limit: 100 +SELECT 1::boolean +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1::boolean" +== 094 +-- truncate_limit: 100 +SELECT 2::boolean +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2::boolean" +== 095 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="booltbl1" schema="" table="booltbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE booltbl1" +== 096 +-- truncate_limit: 100 +DROP TABLE BOOLTBL2 +-- +TABLE: name="booltbl2" schema="" table="booltbl2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE booltbl2" +== 097 +-- truncate_limit: 100 +DROP TABLE BOOLTBL3 +-- +TABLE: name="booltbl3" schema="" table="booltbl3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE booltbl3" +== 098 +-- truncate_limit: 100 +DROP TABLE BOOLTBL4 +-- +TABLE: name="booltbl4" schema="" table="booltbl4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE booltbl4" diff --git a/parser/testdata/summary_truncate/postgres_regress/box.metadata.json b/parser/testdata/summary_truncate/postgres_regress/box.metadata.json new file mode 100644 index 0000000..8b15b4c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/box.metadata.json @@ -0,0 +1,105 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/box.test b/parser/testdata/summary_truncate/postgres_regress/box.test new file mode 100644 index 0000000..4efa12a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/box.test @@ -0,0 +1,966 @@ +== 001 +-- truncate_limit: 100 +|-- +-- BOX +|-- + +|-- +-- box logic +-- o +-- 3 o--|X +-- | o| +-- 2 +-+-+ | +-- | | | | +-- 1 | o-+-o +-- | | +-- 0 +---+ +|-- +-- 0 1 2 3 +|-- + +-- boxes are specified by two points, given by four floats x1,y1,x2,y2 + + +CREATE TABLE BOX_TBL (f1 box) +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE box_tbl (f1 box)" +== 002 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('(2.0,2.0,0.0,0.0)')" +== 003 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('(1.0,1.0,3.0,3.0)')" +== 004 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('((-8, 2), (-2, -10))') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('((-8, 2), (-2, -10))')" +== 005 +-- truncate_limit: 100 +-- degenerate cases where the box is a line or a point +-- note that lines and points boxes all have zero area +INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('(2.5, 2.5, 2.5,3.5)')" +== 006 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('(3.0, 3.0,3.0,3.0)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('(3.0, 3.0,3.0,3.0)')" +== 007 +-- truncate_limit: 100 +-- badly formatted box inputs +INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('(2.3, 4.5)')" +== 008 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('[1, 2, 3, 4)')" +== 009 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('(1, 2, 3, 4]')" +== 010 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('(1, 2, 3, 4) x')" +== 011 +-- truncate_limit: 100 +INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad') +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_tbl (f1) VALUES ('asdfasdf(ad')" +== 012 +-- truncate_limit: 100 +SELECT * FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_tbl" +== 013 +-- truncate_limit: 100 +SELECT b.*, area(b.f1) as barea + FROM BOX_TBL b +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FUNCTION: name="area" function="area" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT b.*, area(b.f1) AS barea FROM box_tbl b" +== 014 +-- truncate_limit: 100 +-- overlap +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 && box '(2.5,2.5,1.0,1.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 && '(2.5,2.5,1.0,1.0)'::box" +== 015 +-- truncate_limit: 100 +-- left-or-overlap (x only) +SELECT b1.* + FROM BOX_TBL b1 + WHERE b1.f1 &< box '(2.0,2.0,2.5,2.5)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +FILTER: schema="" table="b1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b1.* FROM box_tbl b1 WHERE b1.f1 &< '(2.0,2.0,2.5,2.5)'::box" +== 016 +-- truncate_limit: 100 +-- right-or-overlap (x only) +SELECT b1.* + FROM BOX_TBL b1 + WHERE b1.f1 &> box '(2.0,2.0,2.5,2.5)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +FILTER: schema="" table="b1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b1.* FROM box_tbl b1 WHERE b1.f1 &> '(2.0,2.0,2.5,2.5)'::box" +== 017 +-- truncate_limit: 100 +-- left of +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 << box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 << '(3.0,3.0,5.0,5.0)'::box" +== 018 +-- truncate_limit: 100 +-- area <= +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 <= box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 <= '(3.0,3.0,5.0,5.0)'::box" +== 019 +-- truncate_limit: 100 +-- area < +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 < box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 < '(3.0,3.0,5.0,5.0)'::box" +== 020 +-- truncate_limit: 100 +-- area = +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 = box '(3.0,3.0,5.0,5.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 = '(3.0,3.0,5.0,5.0)'::box" +== 021 +-- truncate_limit: 100 +-- area > +SELECT b.f1 + FROM BOX_TBL b -- zero area + WHERE b.f1 > box '(3.5,3.0,4.5,3.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 > '(3.5,3.0,4.5,3.0)'::box" +== 022 +-- truncate_limit: 100 +-- area >= +SELECT b.f1 + FROM BOX_TBL b -- zero area + WHERE b.f1 >= box '(3.5,3.0,4.5,3.0)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 >= '(3.5,3.0,4.5,3.0)'::box" +== 023 +-- truncate_limit: 100 +-- right of +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(3.0,3.0,5.0,5.0)' >> b.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE '(3.0,3.0,5.0,5.0)'::box >> b.f1" +== 024 +-- truncate_limit: 100 +-- contained in +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 <@ box '(0,0,3,3)' +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE b.f1 <@ '(0,0,3,3)'::box" +== 025 +-- truncate_limit: 100 +-- contains +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(0,0,3,3)' @> b.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE '(0,0,3,3)'::box @> b.f1" +== 026 +-- truncate_limit: 100 +-- box equality +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(1,1,3,3)' ~= b.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 FROM box_tbl b WHERE '(1,1,3,3)'::box ~= b.f1" +== 027 +-- truncate_limit: 100 +-- center of box, left unary operator +SELECT @@(b1.f1) AS p + FROM BOX_TBL b1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT @@ b1.f1 AS p FROM box_tbl b1" +== 028 +-- truncate_limit: 100 +-- wholly-contained +SELECT b1.*, b2.* + FROM BOX_TBL b1, BOX_TBL b2 + WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +FILTER: schema="" table="b1" column="f1" +FILTER: schema="" table="b2" column="f1" +FILTER: schema="" table="b1" column="f1" +FILTER: schema="" table="b2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b1.*, b2.* FROM box_tbl b1, box_tbl b2 WHERE b1.f1 @> b2.f1 AND NOT b1.f1 ~= b2.f1" +== 029 +-- truncate_limit: 100 +SELECT height(f1), width(f1) FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="height" function="height" schema="" ctx=Call +FUNCTION: name="width" function="width" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT height(f1), width(f1) FROM box_tbl" +== 030 +-- truncate_limit: 100 +|-- +-- Test the SP-GiST index +|-- + +CREATE TEMPORARY TABLE box_temp (f1 box) +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE box_temp (f1 box)" +== 031 +-- truncate_limit: 100 +INSERT INTO box_temp + SELECT box(point(i, i), point(i * 2, i * 2)) + FROM generate_series(1, 50) AS i +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_temp SELECT box(point(i, i), point(i * 2, i * 2)) FROM generate_series(1, 50) i" +== 032 +-- truncate_limit: 100 +CREATE INDEX box_spgist ON box_temp USING spgist (f1) +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX box_spgist ON box_temp USING spgist (f1)" +== 033 +-- truncate_limit: 100 +INSERT INTO box_temp + VALUES (NULL), + ('(0,0)(0,100)'), + ('(-3,4.3333333333)(40,1)'), + ('(0,100)(0,infinity)'), + ('(-infinity,0)(0,infinity)'), + ('(-infinity,-infinity)(infinity,infinity)') +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO box_temp VALUES (...)" +== 034 +-- truncate_limit: 100 +SET enable_seqscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO FALSE" +== 035 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)'" +== 036 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)'" +== 037 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)'" +== 038 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)'" +== 039 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)'" +== 040 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)'" +== 041 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)'" +== 042 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)'" +== 043 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)'" +== 044 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)'" +== 045 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)'" +== 046 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)'" +== 047 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)'" +== 048 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)'" +== 049 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)'" +== 050 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)'" +== 051 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)'" +== 052 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)'" +== 053 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)'" +== 054 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)'" +== 055 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)'" +== 056 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)'" +== 057 +-- truncate_limit: 100 +SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)'" +== 058 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)' +-- +TABLE: name="box_temp" schema="" table="box_temp" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)'" +== 059 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 060 +-- truncate_limit: 100 +DROP INDEX box_spgist +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX box_spgist" +== 061 +-- truncate_limit: 100 +|-- +-- Test the SP-GiST index on the larger volume of data +|-- +CREATE TABLE quad_box_tbl (id int, b box) +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quad_box_tbl (id int, b box)" +== 062 +-- truncate_limit: 100 +INSERT INTO quad_box_tbl + SELECT (x - 1) * 100 + y, box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_box_tbl SELECT ... FROM generate_series(1, 100) x, generate_series(1, 100) y" +== 063 +-- truncate_limit: 100 +-- insert repeating data to test allTheSame +INSERT INTO quad_box_tbl + SELECT i, '((200, 300),(210, 310))' + FROM generate_series(10001, 11000) AS i +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_box_tbl SELECT i, '((200, 300),(210, 310))' FROM generate_series(10001, 11000) i" +== 064 +-- truncate_limit: 100 +INSERT INTO quad_box_tbl +VALUES + (11001, NULL), + (11002, NULL), + (11003, '((-infinity,-infinity),(infinity,infinity))'), + (11004, '((-infinity,100),(-infinity,500))'), + (11005, '((-infinity,-infinity),(700,infinity))') +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_box_tbl VALUES (...)" +== 065 +-- truncate_limit: 100 +CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b) +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist (b)" +== 066 +-- truncate_limit: 100 +-- get reference results for ORDER BY distance from seq scan +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 067 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 068 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 069 +-- truncate_limit: 100 +CREATE TABLE quad_box_tbl_ord_seq1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl +-- +TABLE: name="quad_box_tbl_ord_seq1" schema="" table="quad_box_tbl_ord_seq1" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE quad_box_tbl_ord_seq1 AS SELECT rank() OVER (ORDER BY b <-> point '123,456') AS n, ..." +== 070 +-- truncate_limit: 100 +CREATE TABLE quad_box_tbl_ord_seq2 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))' +-- +TABLE: name="quad_box_tbl_ord_seq2" schema="" table="quad_box_tbl_ord_seq2" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE quad_box_tbl_ord_seq2 AS SELECT rank() OVER (ORDER BY b <-> point '123,456') AS n, ..." +== 071 +-- truncate_limit: 100 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 072 +-- truncate_limit: 100 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 073 +-- truncate_limit: 100 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 074 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b << box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b << '((100,200),(300,500))'::box" +== 075 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b &< box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b &< '((100,200),(300,500))'::box" +== 076 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b && box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b && '((100,200),(300,500))'::box" +== 077 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b &> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b &> '((100,200),(300,500))'::box" +== 078 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b >> '((100,200),(300,500))'::box" +== 079 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b >> '((100,200),(300,500))'::box" +== 080 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b <<| box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b <<| '((100,200),(300,500))'::box" +== 081 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b &<| box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b &<| '((100,200),(300,500))'::box" +== 082 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b |&> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b |&> '((100,200),(300,500))'::box" +== 083 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b |>> box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b |>> '((100,200),(300,500))'::box" +== 084 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b @> box '((201,301),(202,303))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b @> '((201,301),(202,303))'::box" +== 085 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b <@ box '((100,200),(300,500))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b <@ '((100,200),(300,500))'::box" +== 086 +-- truncate_limit: 100 +SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_box_tbl WHERE b ~= '((200,300),(205,305))'::box" +== 087 +-- truncate_limit: 100 +-- test ORDER BY distance +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 088 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 089 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT rank() OVER (ORDER BY b <-> point '123,456') AS n, b <-> point '123,..." +== 090 +-- truncate_limit: 100 +CREATE TEMP TABLE quad_box_tbl_ord_idx1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl +-- +TABLE: name="quad_box_tbl_ord_idx1" schema="" table="quad_box_tbl_ord_idx1" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_box_tbl_ord_idx1 AS SELECT rank() OVER (ORDER BY b <-> point '123,45..." +== 091 +-- truncate_limit: 100 +SELECT * +FROM quad_box_tbl_ord_seq1 seq FULL JOIN quad_box_tbl_ord_idx1 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 +-- +TABLE: name="quad_box_tbl_ord_seq1" schema="" table="quad_box_tbl_ord_seq1" ctx=Select +TABLE: name="quad_box_tbl_ord_idx1" schema="" table="quad_box_tbl_ord_idx1" ctx=Select +ALIAS: "idx"="quad_box_tbl_ord_idx1" +ALIAS: "seq"="quad_box_tbl_ord_seq1" +FILTER: schema="" table="seq" column="id" +FILTER: schema="" table="idx" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_box_tbl_ord_seq1 seq FULL JOIN quad_box_tbl_ord_idx1 idx ON seq.n = idx.n AND ..." +== 092 +-- truncate_limit: 100 +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))' +-- +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT rank() OVER (ORDER BY b <-> point '123,456') AS n, b <-> point '123,..." +== 093 +-- truncate_limit: 100 +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))' +-- +TABLE: name="quad_box_tbl_ord_idx2" schema="" table="quad_box_tbl_ord_idx2" ctx=DDL +TABLE: name="quad_box_tbl" schema="" table="quad_box_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_box_tbl_ord_idx2 AS SELECT rank() OVER (ORDER BY b <-> point '123,45..." +== 094 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_box_tbl_ord_seq2" schema="" table="quad_box_tbl_ord_seq2" ctx=Select +TABLE: name="quad_box_tbl_ord_idx2" schema="" table="quad_box_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="quad_box_tbl_ord_idx2" +ALIAS: "seq"="quad_box_tbl_ord_seq2" +FILTER: schema="" table="seq" column="id" +FILTER: schema="" table="idx" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_box_tbl_ord_seq2 seq FULL JOIN quad_box_tbl_ord_idx2 idx ON seq.n = idx.n AND ..." +== 095 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 096 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 097 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 098 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('200', 'box') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('200', 'box')" +== 099 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('200', 'box') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('200', 'box')" +== 100 +-- truncate_limit: 100 +SELECT pg_input_is_valid('((200,300),(500, xyz))', 'box') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('((200,300),(500, xyz))', 'box')" +== 101 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('((200,300),(500, xyz))', 'box') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('((200,300),(500, xyz))', 'box')" diff --git a/parser/testdata/summary_truncate/postgres_regress/brin.metadata.json b/parser/testdata/summary_truncate/postgres_regress/brin.metadata.json new file mode 100644 index 0000000..af46f65 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/brin.metadata.json @@ -0,0 +1,72 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/brin.test b/parser/testdata/summary_truncate/postgres_regress/brin.test new file mode 100644 index 0000000..78ace09 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/brin.test @@ -0,0 +1,985 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE brintest (byteacol bytea, + charcol "char", + namecol name, + int8col bigint, + int2col smallint, + int4col integer, + textcol text, + oidcol oid, + tidcol tid, + float4col real, + float8col double precision, + macaddrcol macaddr, + inetcol inet, + cidrcol cidr, + bpcharcol character, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + bitcol bit(10), + varbitcol bit varying(16), + numericcol numeric, + uuidcol uuid, + int4rangecol int4range, + lsncol pg_lsn, + boxcol box +) WITH (fillfactor=10, autovacuum_enabled=off) +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brintest (byteacol bytea, charcol \"char\", namecol name, int8col bigint, int2col smal..." +== 002 +-- truncate_limit: 100 +INSERT INTO brintest SELECT + repeat(stringu1, 8)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 8), + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + thousand::bit(10), + tenthous::bit(16)::varbit, + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) +FROM tenk1 ORDER BY unique2 LIMIT 100 +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest SELECT ... FROM tenk1 ORDER BY unique2 LIMIT 100" +== 003 +-- truncate_limit: 100 +-- throw in some NULL's and different values +INSERT INTO brintest (inetcol, cidrcol, int4rangecol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous, + 'empty'::int4range +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25 +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest (...) SELECT ... FROM tenk1 ORDER BY thousand, tenthous LIMIT 25" +== 004 +-- truncate_limit: 100 +CREATE INDEX brinidx ON brintest USING brin ( + byteacol, + charcol, + namecol, + int8col, + int2col, + int4col, + textcol, + oidcol, + tidcol, + float4col, + float8col, + macaddrcol, + inetcol inet_inclusion_ops, + inetcol inet_minmax_ops, + cidrcol inet_inclusion_ops, + cidrcol inet_minmax_ops, + bpcharcol, + datecol, + timecol, + timestampcol, + timestamptzcol, + intervalcol, + timetzcol, + bitcol, + varbitcol, + numericcol, + uuidcol, + int4rangecol, + lsncol, + boxcol +) with (pages_per_range = 1) +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx ON brintest USING brin (byteacol, charcol, namecol, int8col, int2col, int4co..." +== 005 +-- truncate_limit: 100 +CREATE TABLE brinopers (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))) +-- +TABLE: name="brinopers" schema="" table="brinopers" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brinopers (colname name, typ text, op text[], value text[], matches int[], CHECK (ca..." +== 006 +-- truncate_limit: 100 +INSERT INTO brinopers VALUES + ('byteacol', 'bytea', + '{>, >=, =, <=, <}', + '{AAAAAA, AAAAAA, BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA, ZZZZZZ, ZZZZZZ}', + '{100, 100, 1, 100, 100}'), + ('charcol', '"char"', + '{>, >=, =, <=, <}', + '{A, A, M, Z, Z}', + '{97, 100, 6, 100, 98}'), + ('namecol', 'name', + '{>, >=, =, <=, <}', + '{AAAAAA, AAAAAA, MAAAAA, ZZAAAA, ZZAAAA}', + '{100, 100, 2, 100, 100}'), + ('int2col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int8col', 'int2', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int4', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 1257141600, 1428427143, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('textcol', 'text', + '{>, >=, =, <=, <}', + '{ABABAB, ABABAB, BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA, ZZAAAA, ZZAAAA}', + '{100, 100, 1, 100, 100}'), + ('oidcol', 'oid', + '{>, >=, =, <=, <}', + '{0, 0, 8800, 9999, 9999}', + '{100, 100, 1, 100, 100}'), + ('tidcol', 'tid', + '{>, >=, =, <=, <}', + '{"(0,0)", "(0,0)", "(8800,0)", "(9999,19)", "(9999,19)"}', + '{100, 100, 1, 100, 100}'), + ('float4col', 'float4', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float4col', 'float8', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float8col', 'float4', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('float8col', 'float8', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('macaddrcol', 'macaddr', + '{>, >=, =, <=, <}', + '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}', + '{99, 100, 2, 100, 100}'), + ('inetcol', 'inet', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}', + '{100, 1, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('inetcol', 'inet', + '{&&, >>=, <<=, =}', + '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('inetcol', 'cidr', + '{&&, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}', + '{100, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('inetcol', 'cidr', + '{&&, >>=, <<=, =}', + '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('cidrcol', 'inet', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}', + '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('cidrcol', 'inet', + '{&&, >>=, <<=, =}', + '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('cidrcol', 'cidr', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}', + '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('cidrcol', 'cidr', + '{&&, >>=, <<=, =}', + '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('bpcharcol', 'bpchar', + '{>, >=, =, <=, <}', + '{A, A, W, Z, Z}', + '{97, 100, 6, 100, 98}'), + ('datecol', 'date', + '{>, >=, =, <=, <}', + '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}', + '{100, 100, 1, 100, 100}'), + ('timecol', 'time', + '{>, >=, =, <=, <}', + '{01:20:30, 01:20:30, 02:28:57, 06:28:31.5, 06:28:31.5}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamp', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestamptzcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-19 09:00:00-07, 1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03}', + '{100, 100, 1, 100, 100}'), + ('intervalcol', 'interval', + '{>, >=, =, <=, <}', + '{00:00:00, 00:00:00, 1 mons 13 days 12:24, 2 mons 23 days 07:48:00, 1 year}', + '{100, 100, 1, 100, 100}'), + ('timetzcol', 'timetz', + '{>, >=, =, <=, <}', + '{01:30:20+02, 01:30:20+02, 01:35:50+02, 23:55:05+02, 23:55:05+02}', + '{99, 100, 2, 100, 100}'), + ('bitcol', 'bit(10)', + '{>, >=, =, <=, <}', + '{0000000010, 0000000010, 0011011110, 1111111000, 1111111000}', + '{100, 100, 1, 100, 100}'), + ('varbitcol', 'varbit(16)', + '{>, >=, =, <=, <}', + '{0000000000000100, 0000000000000100, 0001010001100110, 1111111111111000, 1111111111111000}', + '{100, 100, 1, 100, 100}'), + ('numericcol', 'numeric', + '{>, >=, =, <=, <}', + '{0.00, 0.01, 2268164.347826086956521739130434782609, 99470151.9, 99470151.9}', + '{100, 100, 1, 100, 100}'), + ('uuidcol', 'uuid', + '{>, >=, =, <=, <}', + '{00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 52225222-5222-5222-5222-522252225222, 99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998}', + '{100, 100, 1, 100, 100}'), + ('int4rangecol', 'int4range', + '{<<, &<, &&, &>, >>, @>, <@, =, <, <=, >, >=}', + '{"[10000,)","[10000,)","(,]","[3,4)","[36,44)","(1500,1501]","[3,4)","[222,1222)","[36,44)","[43,1043)","[367,4466)","[519,)"}', + '{53, 53, 53, 53, 50, 22, 72, 1, 74, 75, 34, 21}'), + ('int4rangecol', 'int4range', + '{@>, <@, =, <=, >, >=}', + '{empty, empty, empty, empty, empty, empty}', + '{125, 72, 72, 72, 53, 125}'), + ('int4rangecol', 'int4', + '{@>}', + '{1500}', + '{22}'), + ('lsncol', 'pg_lsn', + '{>, >=, =, <=, <, IS, IS NOT}', + '{0/1200, 0/1200, 44/455222, 198/1999799, 198/1999799, NULL, NULL}', + '{100, 100, 1, 100, 100, 25, 100}'), + ('boxcol', 'point', + '{@>}', + '{"(500,43)"}', + '{11}'), + ('boxcol', 'box', + '{<<, &<, &&, &>, >>, <<|, &<|, |&>, |>>, @>, <@, ~=}', + '{"((1000,2000),(3000,4000))","((1,2),(3000,4000))","((1,2),(3000,4000))","((1,2),(3000,4000))","((1,2),(3,4))","((1000,2000),(3000,4000))","((1,2000),(3,4000))","((1000,2),(3000,4))","((1,2),(3,4))","((1,2),(300,400))","((1,2),(3000,4000))","((222,1222),(44,45))"}', + '{100, 100, 100, 99, 96, 100, 100, 99, 96, 1, 99, 1}') +-- +TABLE: name="brinopers" schema="" table="brinopers" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brinopers VALUES (...)" +== 007 +-- truncate_limit: 100 +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n\tr record;\n\tr2 record;\n\tcond text;\n\tidx_ctids tid[];\n\tss_ctids tid[];\n\tcount int;\n\t..." +== 008 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 009 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 010 +-- truncate_limit: 100 +INSERT INTO brintest SELECT + repeat(stringu1, 42)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 42), + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + thousand::bit(10), + tenthous::bit(16)::varbit, + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5 +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest SELECT ... FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5" +== 011 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx', 0)" +== 012 +-- truncate_limit: 100 +VACUUM brintest +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM brintest" +== 013 +-- truncate_limit: 100 +-- force a summarization cycle in brinidx + +UPDATE brintest SET int8col = int8col * int4col +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brintest SET int8col = int8col * int4col" +== 014 +-- truncate_limit: 100 +UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL +-- +TABLE: name="brintest" schema="" table="brintest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL" +== 015 +-- truncate_limit: 100 +-- Tests for brin_summarize_new_values +SELECT brin_summarize_new_values('brintest') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('brintest')" +== 016 +-- truncate_limit: 100 +-- error, not an index +SELECT brin_summarize_new_values('tenk1_unique1') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('tenk1_unique1')" +== 017 +-- truncate_limit: 100 +-- error, not a BRIN index +SELECT brin_summarize_new_values('brinidx') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('brinidx')" +== 018 +-- truncate_limit: 100 +-- ok, no change expected + +-- Tests for brin_desummarize_range +SELECT brin_desummarize_range('brinidx', -1) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx', -1)" +== 019 +-- truncate_limit: 100 +-- error, invalid range +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx', 0)" +== 020 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx', 0)" +== 021 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx', 100000000) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx', 100000000)" +== 022 +-- truncate_limit: 100 +-- Test brin_summarize_range +CREATE TABLE brin_summarize ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false) +-- +TABLE: name="brin_summarize" schema="" table="brin_summarize" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_summarize (value int) WITH (fillfactor=10, autovacuum_enabled=false)" +== 023 +-- truncate_limit: 100 +CREATE INDEX brin_summarize_idx ON brin_summarize USING brin (value) WITH (pages_per_range=2) +-- +TABLE: name="brin_summarize" schema="" table="brin_summarize" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_summarize_idx ON brin_summarize USING brin (value) WITH (pages_per_range=2)" +== 024 +-- truncate_limit: 100 +-- Fill a few pages +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE curtid tid;\nBEGIN\n LOOP\n INSERT INTO brin_summarize VALUES (1) RETURNING ctid I..." +== 025 +-- truncate_limit: 100 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_idx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_idx', 0)" +== 026 +-- truncate_limit: 100 +-- nothing: already summarized +SELECT brin_summarize_range('brin_summarize_idx', 1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_idx', 1)" +== 027 +-- truncate_limit: 100 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_idx', 2) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_idx', 2)" +== 028 +-- truncate_limit: 100 +-- nothing: page doesn't exist in table +SELECT brin_summarize_range('brin_summarize_idx', 4294967295) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_idx', 4294967295)" +== 029 +-- truncate_limit: 100 +-- invalid block number values +SELECT brin_summarize_range('brin_summarize_idx', -1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_idx', -1)" +== 030 +-- truncate_limit: 100 +SELECT brin_summarize_range('brin_summarize_idx', 4294967296) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_idx', 4294967296)" +== 031 +-- truncate_limit: 100 +-- test value merging in add_value +CREATE TABLE brintest_2 (n numrange) +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brintest_2 (n numrange)" +== 032 +-- truncate_limit: 100 +CREATE INDEX brinidx_2 ON brintest_2 USING brin (n) +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_2 ON brintest_2 USING brin (n)" +== 033 +-- truncate_limit: 100 +INSERT INTO brintest_2 VALUES ('empty') +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_2 VALUES ('empty')" +== 034 +-- truncate_limit: 100 +INSERT INTO brintest_2 VALUES (numrange(0, 2^1000::numeric)) +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_2 VALUES (numrange(0, 2 ^ 1000::numeric))" +== 035 +-- truncate_limit: 100 +INSERT INTO brintest_2 VALUES ('(-1, 0)') +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_2 VALUES ('(-1, 0)')" +== 036 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx', 0)" +== 037 +-- truncate_limit: 100 +SELECT brin_summarize_range('brinidx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brinidx', 0)" +== 038 +-- truncate_limit: 100 +DROP TABLE brintest_2 +-- +TABLE: name="brintest_2" schema="" table="brintest_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brintest_2" +== 039 +-- truncate_limit: 100 +-- test brin cost estimates behave sanely based on correlation of values +CREATE TABLE brin_test (a INT, b INT) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_test (a int, b int)" +== 040 +-- truncate_limit: 100 +INSERT INTO brin_test SELECT x/100,x%100 FROM generate_series(1,10000) x(x) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test SELECT x / 100, x % 100 FROM generate_series(1, 10000) x(x)" +== 041 +-- truncate_limit: 100 +CREATE INDEX brin_test_a_idx ON brin_test USING brin (a) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_a_idx ON brin_test USING brin (a) WITH (pages_per_range=2)" +== 042 +-- truncate_limit: 100 +CREATE INDEX brin_test_b_idx ON brin_test USING brin (b) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_b_idx ON brin_test USING brin (b) WITH (pages_per_range=2)" +== 043 +-- truncate_limit: 100 +VACUUM ANALYZE brin_test +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) brin_test" +== 044 +-- truncate_limit: 100 +-- Ensure brin index is used when columns are perfectly correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test WHERE a = 1 +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_test WHERE a = 1" +== 045 +-- truncate_limit: 100 +-- Ensure brin index is not used when values are not correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test WHERE b = 1 +-- +TABLE: name="brin_test" schema="" table="brin_test" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_test WHERE b = 1" +== 046 +-- truncate_limit: 100 +-- make sure data are properly de-toasted in BRIN index +CREATE TABLE brintest_3 (a text, b text, c text, d text) +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brintest_3 (a text, b text, c text, d text)" +== 047 +-- truncate_limit: 100 +-- long random strings (~2000 chars each, so ~6kB for min/max on two +-- columns) to trigger toasting +WITH rand_value AS (SELECT string_agg(fipshash(i::text),'') AS val FROM generate_series(1,60) s(i)) +INSERT INTO brintest_3 +SELECT val, val, val, val FROM rand_value +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DML +CTE: "rand_value" +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH rand_value AS (...) INSERT INTO brintest_3 SELECT val, val, val, val FROM rand_value" +== 048 +-- truncate_limit: 100 +CREATE INDEX brin_test_toast_idx ON brintest_3 USING brin (b, c) +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_toast_idx ON brintest_3 USING brin (b, c)" +== 049 +-- truncate_limit: 100 +DELETE FROM brintest_3 +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM brintest_3" +== 050 +-- truncate_limit: 100 +-- We need to wait a bit for all transactions to complete, so that the +-- vacuum actually removes the TOAST rows. Creating an index concurrently +-- is a one way to achieve that, because it does exactly such wait. +CREATE INDEX CONCURRENTLY brin_test_temp_idx ON brintest_3(a) +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY brin_test_temp_idx ON brintest_3 USING btree (a)" +== 051 +-- truncate_limit: 100 +DROP INDEX brin_test_temp_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX brin_test_temp_idx" +== 052 +-- truncate_limit: 100 +-- vacuum the table, to discard TOAST data +VACUUM brintest_3 +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM brintest_3" +== 053 +-- truncate_limit: 100 +-- retry insert with a different random-looking (but deterministic) value +-- the value is different, and so should replace either min or max in the +-- brin summary +WITH rand_value AS (SELECT string_agg(fipshash((-i)::text),'') AS val FROM generate_series(1,60) s(i)) +INSERT INTO brintest_3 +SELECT val, val, val, val FROM rand_value +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DML +CTE: "rand_value" +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH rand_value AS (...) INSERT INTO brintest_3 SELECT val, val, val, val FROM rand_value" +== 054 +-- truncate_limit: 100 +-- now try some queries, accessing the brin index +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 055 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM brintest_3 WHERE b < '0' +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brintest_3 WHERE b < '0'" +== 056 +-- truncate_limit: 100 +SELECT * FROM brintest_3 WHERE b < '0' +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM brintest_3 WHERE b < '0'" +== 057 +-- truncate_limit: 100 +DROP TABLE brintest_3 +-- +TABLE: name="brintest_3" schema="" table="brintest_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brintest_3" +== 058 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 059 +-- truncate_limit: 100 +-- test an unlogged table, mostly to get coverage of brinbuildempty +CREATE UNLOGGED TABLE brintest_unlogged (n numrange) +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE brintest_unlogged (n numrange)" +== 060 +-- truncate_limit: 100 +CREATE INDEX brinidx_unlogged ON brintest_unlogged USING brin (n) +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_unlogged ON brintest_unlogged USING brin (n)" +== 061 +-- truncate_limit: 100 +INSERT INTO brintest_unlogged VALUES (numrange(0, 2^1000::numeric)) +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_unlogged VALUES (numrange(0, 2 ^ 1000::numeric))" +== 062 +-- truncate_limit: 100 +DROP TABLE brintest_unlogged +-- +TABLE: name="brintest_unlogged" schema="" table="brintest_unlogged" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brintest_unlogged" +== 063 +-- truncate_limit: 100 +-- test that the insert optimization works if no rows end up inserted +CREATE TABLE brin_insert_optimization (a int) +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_insert_optimization (a int)" +== 064 +-- truncate_limit: 100 +INSERT INTO brin_insert_optimization VALUES (1) +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_insert_optimization VALUES (1)" +== 065 +-- truncate_limit: 100 +CREATE INDEX brin_insert_optimization_idx ON brin_insert_optimization USING brin (a) +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_insert_optimization_idx ON brin_insert_optimization USING brin (a)" +== 066 +-- truncate_limit: 100 +UPDATE brin_insert_optimization SET a = a +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brin_insert_optimization SET a = a" +== 067 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY brin_insert_optimization_idx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX brin_insert_optimization_idx" +== 068 +-- truncate_limit: 100 +DROP TABLE brin_insert_optimization +-- +TABLE: name="brin_insert_optimization" schema="" table="brin_insert_optimization" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_insert_optimization" diff --git a/parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json b/parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/brin_bloom.test b/parser/testdata/summary_truncate/postgres_regress/brin_bloom.test new file mode 100644 index 0000000..199a2e2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/brin_bloom.test @@ -0,0 +1,654 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE brintest_bloom (byteacol bytea, + charcol "char", + namecol name, + int8col bigint, + int2col smallint, + int4col integer, + textcol text, + oidcol oid, + float4col real, + float8col double precision, + macaddrcol macaddr, + inetcol inet, + cidrcol cidr, + bpcharcol character, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + numericcol numeric, + uuidcol uuid, + lsncol pg_lsn +) WITH (fillfactor=10) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brintest_bloom (byteacol bytea, charcol \"char\", namecol name, int8col bigint, int2co..." +== 002 +-- truncate_limit: 100 +INSERT INTO brintest_bloom SELECT + repeat(stringu1, 8)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 8), + unique1::oid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 100 +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_bloom SELECT ... FROM tenk1 ORDER BY unique2 LIMIT 100" +== 003 +-- truncate_limit: 100 +-- throw in some NULL's and different values +INSERT INTO brintest_bloom (inetcol, cidrcol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25 +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_bloom (...) SELECT ... FROM tenk1 ORDER BY thousand, tenthous LIMIT 25" +== 004 +-- truncate_limit: 100 +-- test bloom specific index options +-- ndistinct must be >= -1.0 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(n_distinct_per_range = -1.1) +) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_bloom ON brintest_bloom USING brin (byteacol bytea_bloom_ops(n_distinct_per_..." +== 005 +-- truncate_limit: 100 +-- false_positive_rate must be between 0.0001 and 0.25 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(false_positive_rate = 0.00009) +) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_bloom ON brintest_bloom USING brin (byteacol bytea_bloom_ops(false_positive_..." +== 006 +-- truncate_limit: 100 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(false_positive_rate = 0.26) +) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_bloom ON brintest_bloom USING brin (byteacol bytea_bloom_ops(false_positive_..." +== 007 +-- truncate_limit: 100 +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops, + charcol char_bloom_ops, + namecol name_bloom_ops, + int8col int8_bloom_ops, + int2col int2_bloom_ops, + int4col int4_bloom_ops, + textcol text_bloom_ops, + oidcol oid_bloom_ops, + float4col float4_bloom_ops, + float8col float8_bloom_ops, + macaddrcol macaddr_bloom_ops, + inetcol inet_bloom_ops, + cidrcol inet_bloom_ops, + bpcharcol bpchar_bloom_ops, + datecol date_bloom_ops, + timecol time_bloom_ops, + timestampcol timestamp_bloom_ops, + timestamptzcol timestamptz_bloom_ops, + intervalcol interval_bloom_ops, + timetzcol timetz_bloom_ops, + numericcol numeric_bloom_ops, + uuidcol uuid_bloom_ops, + lsncol pg_lsn_bloom_ops +) with (pages_per_range = 1) +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_bloom ON brintest_bloom USING brin (byteacol bytea_bloom_ops, charcol char_b..." +== 008 +-- truncate_limit: 100 +CREATE TABLE brinopers_bloom (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))) +-- +TABLE: name="brinopers_bloom" schema="" table="brinopers_bloom" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brinopers_bloom (colname name, typ text, op text[], value text[], matches int[], CHE..." +== 009 +-- truncate_limit: 100 +INSERT INTO brinopers_bloom VALUES + ('byteacol', 'bytea', + '{=}', + '{BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA}', + '{1}'), + ('charcol', '"char"', + '{=}', + '{M}', + '{6}'), + ('namecol', 'name', + '{=}', + '{MAAAAA}', + '{2}'), + ('int2col', 'int2', + '{=}', + '{800}', + '{1}'), + ('int4col', 'int4', + '{=}', + '{800}', + '{1}'), + ('int8col', 'int8', + '{=}', + '{1257141600}', + '{1}'), + ('textcol', 'text', + '{=}', + '{BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA}', + '{1}'), + ('oidcol', 'oid', + '{=}', + '{8800}', + '{1}'), + ('float4col', 'float4', + '{=}', + '{1}', + '{4}'), + ('float8col', 'float8', + '{=}', + '{0}', + '{1}'), + ('macaddrcol', 'macaddr', + '{=}', + '{2c:00:2d:00:16:00}', + '{2}'), + ('inetcol', 'inet', + '{=}', + '{10.2.14.231/24}', + '{1}'), + ('inetcol', 'cidr', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('cidrcol', 'inet', + '{=}', + '{10.2.14/24}', + '{2}'), + ('cidrcol', 'inet', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('cidrcol', 'cidr', + '{=}', + '{10.2.14/24}', + '{2}'), + ('cidrcol', 'cidr', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('bpcharcol', 'bpchar', + '{=}', + '{W}', + '{6}'), + ('datecol', 'date', + '{=}', + '{2009-12-01}', + '{1}'), + ('timecol', 'time', + '{=}', + '{02:28:57}', + '{1}'), + ('timestampcol', 'timestamp', + '{=}', + '{1964-03-24 19:26:45}', + '{1}'), + ('timestamptzcol', 'timestamptz', + '{=}', + '{1972-10-19 09:00:00-07}', + '{1}'), + ('intervalcol', 'interval', + '{=}', + '{1 mons 13 days 12:24}', + '{1}'), + ('timetzcol', 'timetz', + '{=}', + '{01:35:50+02}', + '{2}'), + ('numericcol', 'numeric', + '{=}', + '{2268164.347826086956521739130434782609}', + '{1}'), + ('uuidcol', 'uuid', + '{=}', + '{52225222-5222-5222-5222-522252225222}', + '{1}'), + ('lsncol', 'pg_lsn', + '{=, IS, IS NOT}', + '{44/455222, NULL, NULL}', + '{1, 25, 100}') +-- +TABLE: name="brinopers_bloom" schema="" table="brinopers_bloom" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brinopers_bloom VALUES (...)" +== 010 +-- truncate_limit: 100 +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers_bloom, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest_bloom%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest_bloom%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_bloom WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_bloom WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n\tr record;\n\tr2 record;\n\tcond text;\n\tidx_ctids tid[];\n\tss_ctids tid[];\n\tcount int;\n\t..." +== 011 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 012 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 013 +-- truncate_limit: 100 +INSERT INTO brintest_bloom SELECT + repeat(stringu1, 42)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 42), + unique1::oid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5 +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_bloom SELECT ... FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5" +== 014 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx_bloom', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_bloom', 0)" +== 015 +-- truncate_limit: 100 +VACUUM brintest_bloom +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM brintest_bloom" +== 016 +-- truncate_limit: 100 +-- force a summarization cycle in brinidx + +UPDATE brintest_bloom SET int8col = int8col * int4col +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brintest_bloom SET int8col = int8col * int4col" +== 017 +-- truncate_limit: 100 +UPDATE brintest_bloom SET textcol = '' WHERE textcol IS NOT NULL +-- +TABLE: name="brintest_bloom" schema="" table="brintest_bloom" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brintest_bloom SET textcol = '' WHERE textcol IS NOT NULL" +== 018 +-- truncate_limit: 100 +-- Tests for brin_summarize_new_values +SELECT brin_summarize_new_values('brintest_bloom') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('brintest_bloom')" +== 019 +-- truncate_limit: 100 +-- error, not an index +SELECT brin_summarize_new_values('tenk1_unique1') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('tenk1_unique1')" +== 020 +-- truncate_limit: 100 +-- error, not a BRIN index +SELECT brin_summarize_new_values('brinidx_bloom') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('brinidx_bloom')" +== 021 +-- truncate_limit: 100 +-- ok, no change expected + +-- Tests for brin_desummarize_range +SELECT brin_desummarize_range('brinidx_bloom', -1) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_bloom', -1)" +== 022 +-- truncate_limit: 100 +-- error, invalid range +SELECT brin_desummarize_range('brinidx_bloom', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_bloom', 0)" +== 023 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx_bloom', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_bloom', 0)" +== 024 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx_bloom', 100000000) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_bloom', 100000000)" +== 025 +-- truncate_limit: 100 +-- Test brin_summarize_range +CREATE TABLE brin_summarize_bloom ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false) +-- +TABLE: name="brin_summarize_bloom" schema="" table="brin_summarize_bloom" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_summarize_bloom (value int) WITH (fillfactor=10, autovacuum_enabled=false)" +== 026 +-- truncate_limit: 100 +CREATE INDEX brin_summarize_bloom_idx ON brin_summarize_bloom USING brin (value) WITH (pages_per_range=2) +-- +TABLE: name="brin_summarize_bloom" schema="" table="brin_summarize_bloom" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_summarize_bloom_idx ON brin_summarize_bloom USING brin (value) WITH (pages_per_..." +== 027 +-- truncate_limit: 100 +-- Fill a few pages +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize_bloom VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE curtid tid;\nBEGIN\n LOOP\n INSERT INTO brin_summarize_bloom VALUES (1) RETURNING ..." +== 028 +-- truncate_limit: 100 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_bloom_idx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_bloom_idx', 0)" +== 029 +-- truncate_limit: 100 +-- nothing: already summarized +SELECT brin_summarize_range('brin_summarize_bloom_idx', 1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_bloom_idx', 1)" +== 030 +-- truncate_limit: 100 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_bloom_idx', 2) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_bloom_idx', 2)" +== 031 +-- truncate_limit: 100 +-- nothing: page doesn't exist in table +SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967295) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967295)" +== 032 +-- truncate_limit: 100 +-- invalid block number values +SELECT brin_summarize_range('brin_summarize_bloom_idx', -1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_bloom_idx', -1)" +== 033 +-- truncate_limit: 100 +SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967296) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967296)" +== 034 +-- truncate_limit: 100 +-- test brin cost estimates behave sanely based on correlation of values +CREATE TABLE brin_test_bloom (a INT, b INT) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_test_bloom (a int, b int)" +== 035 +-- truncate_limit: 100 +INSERT INTO brin_test_bloom SELECT x/100,x%100 FROM generate_series(1,10000) x(x) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_bloom SELECT x / 100, x % 100 FROM generate_series(1, 10000) x(x)" +== 036 +-- truncate_limit: 100 +CREATE INDEX brin_test_bloom_a_idx ON brin_test_bloom USING brin (a) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_bloom_a_idx ON brin_test_bloom USING brin (a) WITH (pages_per_range=2)" +== 037 +-- truncate_limit: 100 +CREATE INDEX brin_test_bloom_b_idx ON brin_test_bloom USING brin (b) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_bloom_b_idx ON brin_test_bloom USING brin (b) WITH (pages_per_range=2)" +== 038 +-- truncate_limit: 100 +VACUUM ANALYZE brin_test_bloom +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) brin_test_bloom" +== 039 +-- truncate_limit: 100 +-- Ensure brin index is used when columns are perfectly correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_bloom WHERE a = 1 +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_test_bloom WHERE a = 1" +== 040 +-- truncate_limit: 100 +-- Ensure brin index is not used when values are not correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_bloom WHERE b = 1 +-- +TABLE: name="brin_test_bloom" schema="" table="brin_test_bloom" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_test_bloom WHERE b = 1" diff --git a/parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json b/parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json new file mode 100644 index 0000000..643d115 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json @@ -0,0 +1,176 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/brin_multi.test b/parser/testdata/summary_truncate/postgres_regress/brin_multi.test new file mode 100644 index 0000000..597bcd4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/brin_multi.test @@ -0,0 +1,1810 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE brintest_multi ( + int8col bigint, + int2col smallint, + int4col integer, + oidcol oid, + tidcol tid, + float4col real, + float8col double precision, + macaddrcol macaddr, + macaddr8col macaddr8, + inetcol inet, + cidrcol cidr, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + numericcol numeric, + uuidcol uuid, + lsncol pg_lsn +) WITH (fillfactor=10) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brintest_multi (int8col bigint, int2col smallint, int4col int, oidcol oid, tidcol ti..." +== 002 +-- truncate_limit: 100 +INSERT INTO brintest_multi SELECT + 142857 * tenthous, + thousand, + twothousand, + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + substr(fipshash(unique1::text), 1, 16)::macaddr8, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 100 +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_multi SELECT ... FROM tenk1 ORDER BY unique2 LIMIT 100" +== 003 +-- truncate_limit: 100 +-- throw in some NULL's and different values +INSERT INTO brintest_multi (inetcol, cidrcol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25 +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_multi (...) SELECT ... FROM tenk1 ORDER BY thousand, tenthous LIMIT 25" +== 004 +-- truncate_limit: 100 +-- test minmax-multi specific index options +-- number of values must be >= 16 +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops(values_per_range = 7) +) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_multi ON brintest_multi USING brin (int8col int8_minmax_multi_ops(values_per..." +== 005 +-- truncate_limit: 100 +-- number of values must be <= 256 +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops(values_per_range = 257) +) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_multi ON brintest_multi USING brin (int8col int8_minmax_multi_ops(values_per..." +== 006 +-- truncate_limit: 100 +-- first create an index with a single page range, to force compaction +-- due to exceeding the number of values per summary +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops, + int2col int2_minmax_multi_ops, + int4col int4_minmax_multi_ops, + oidcol oid_minmax_multi_ops, + tidcol tid_minmax_multi_ops, + float4col float4_minmax_multi_ops, + float8col float8_minmax_multi_ops, + macaddrcol macaddr_minmax_multi_ops, + macaddr8col macaddr8_minmax_multi_ops, + inetcol inet_minmax_multi_ops, + cidrcol inet_minmax_multi_ops, + datecol date_minmax_multi_ops, + timecol time_minmax_multi_ops, + timestampcol timestamp_minmax_multi_ops, + timestamptzcol timestamptz_minmax_multi_ops, + intervalcol interval_minmax_multi_ops, + timetzcol timetz_minmax_multi_ops, + numericcol numeric_minmax_multi_ops, + uuidcol uuid_minmax_multi_ops, + lsncol pg_lsn_minmax_multi_ops +) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_multi ON brintest_multi USING brin (int8col int8_minmax_multi_ops, int2col i..." +== 007 +-- truncate_limit: 100 +DROP INDEX brinidx_multi +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX brinidx_multi" +== 008 +-- truncate_limit: 100 +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops, + int2col int2_minmax_multi_ops, + int4col int4_minmax_multi_ops, + oidcol oid_minmax_multi_ops, + tidcol tid_minmax_multi_ops, + float4col float4_minmax_multi_ops, + float8col float8_minmax_multi_ops, + macaddrcol macaddr_minmax_multi_ops, + macaddr8col macaddr8_minmax_multi_ops, + inetcol inet_minmax_multi_ops, + cidrcol inet_minmax_multi_ops, + datecol date_minmax_multi_ops, + timecol time_minmax_multi_ops, + timestampcol timestamp_minmax_multi_ops, + timestamptzcol timestamptz_minmax_multi_ops, + intervalcol interval_minmax_multi_ops, + timetzcol timetz_minmax_multi_ops, + numericcol numeric_minmax_multi_ops, + uuidcol uuid_minmax_multi_ops, + lsncol pg_lsn_minmax_multi_ops +) with (pages_per_range = 1) +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brinidx_multi ON brintest_multi USING brin (int8col int8_minmax_multi_ops, int2col i..." +== 009 +-- truncate_limit: 100 +CREATE TABLE brinopers_multi (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))) +-- +TABLE: name="brinopers_multi" schema="" table="brinopers_multi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brinopers_multi (colname name, typ text, op text[], value text[], matches int[], CHE..." +== 010 +-- truncate_limit: 100 +INSERT INTO brinopers_multi VALUES + ('int2col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int8col', 'int2', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int4', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 1257141600, 1428427143, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('oidcol', 'oid', + '{>, >=, =, <=, <}', + '{0, 0, 8800, 9999, 9999}', + '{100, 100, 1, 100, 100}'), + ('tidcol', 'tid', + '{>, >=, =, <=, <}', + '{"(0,0)", "(0,0)", "(8800,0)", "(9999,19)", "(9999,19)"}', + '{100, 100, 1, 100, 100}'), + ('float4col', 'float4', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float4col', 'float8', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float8col', 'float4', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('float8col', 'float8', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('macaddrcol', 'macaddr', + '{>, >=, =, <=, <}', + '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}', + '{99, 100, 2, 100, 100}'), + ('macaddr8col', 'macaddr8', + '{>, >=, =, <=, <}', + '{b1:d1:0e:7b:af:a4:42:12, d9:35:91:bd:f7:86:0e:1e, 72:8f:20:6c:2a:01:bf:57, 23:e8:46:63:86:07:ad:cb, 13:16:8e:6a:2e:6c:84:b4}', + '{31, 17, 1, 11, 4}'), + ('inetcol', 'inet', + '{=, <, <=, >, >=}', + '{10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{1, 100, 100, 125, 125}'), + ('inetcol', 'cidr', + '{<, <=, >, >=}', + '{255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{100, 100, 125, 125}'), + ('cidrcol', 'inet', + '{=, <, <=, >, >=}', + '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{2, 100, 100, 125, 125}'), + ('cidrcol', 'cidr', + '{=, <, <=, >, >=}', + '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{2, 100, 100, 125, 125}'), + ('datecol', 'date', + '{>, >=, =, <=, <}', + '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}', + '{100, 100, 1, 100, 100}'), + ('timecol', 'time', + '{>, >=, =, <=, <}', + '{01:20:30, 01:20:30, 02:28:57, 06:28:31.5, 06:28:31.5}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamp', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestamptzcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-19 09:00:00-07, 1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03}', + '{100, 100, 1, 100, 100}'), + ('intervalcol', 'interval', + '{>, >=, =, <=, <}', + '{00:00:00, 00:00:00, 1 mons 13 days 12:24, 2 mons 23 days 07:48:00, 1 year}', + '{100, 100, 1, 100, 100}'), + ('timetzcol', 'timetz', + '{>, >=, =, <=, <}', + '{01:30:20+02, 01:30:20+02, 01:35:50+02, 23:55:05+02, 23:55:05+02}', + '{99, 100, 2, 100, 100}'), + ('numericcol', 'numeric', + '{>, >=, =, <=, <}', + '{0.00, 0.01, 2268164.347826086956521739130434782609, 99470151.9, 99470151.9}', + '{100, 100, 1, 100, 100}'), + ('uuidcol', 'uuid', + '{>, >=, =, <=, <}', + '{00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 52225222-5222-5222-5222-522252225222, 99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998}', + '{100, 100, 1, 100, 100}'), + ('lsncol', 'pg_lsn', + '{>, >=, =, <=, <, IS, IS NOT}', + '{0/1200, 0/1200, 44/455222, 198/1999799, 198/1999799, NULL, NULL}', + '{100, 100, 1, 100, 100, 25, 100}') +-- +TABLE: name="brinopers_multi" schema="" table="brinopers_multi" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brinopers_multi VALUES (...)" +== 011 +-- truncate_limit: 100 +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers_multi, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest_multi%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest_multi%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n\tr record;\n\tr2 record;\n\tcond text;\n\tidx_ctids tid[];\n\tss_ctids tid[];\n\tcount int;\n\t..." +== 012 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 013 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 014 +-- truncate_limit: 100 +INSERT INTO brintest_multi SELECT + 142857 * tenthous, + thousand, + twothousand, + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + substr(fipshash(unique1::text), 1, 16)::macaddr8, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5 +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="to_hex" function="to_hex" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brintest_multi SELECT ... FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5" +== 015 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx_multi', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_multi', 0)" +== 016 +-- truncate_limit: 100 +VACUUM brintest_multi +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM brintest_multi" +== 017 +-- truncate_limit: 100 +-- force a summarization cycle in brinidx + +-- Try inserting a values with NaN, to test distance calculation. +insert into public.brintest_multi (float4col) values (real 'nan') +-- +TABLE: name="public.brintest_multi" schema="public" table="brintest_multi" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO public.brintest_multi (float4col) VALUES ('nan'::real)" +== 018 +-- truncate_limit: 100 +insert into public.brintest_multi (float8col) values (real 'nan') +-- +TABLE: name="public.brintest_multi" schema="public" table="brintest_multi" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO public.brintest_multi (float8col) VALUES ('nan'::real)" +== 019 +-- truncate_limit: 100 +UPDATE brintest_multi SET int8col = int8col * int4col +-- +TABLE: name="brintest_multi" schema="" table="brintest_multi" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brintest_multi SET int8col = int8col * int4col" +== 020 +-- truncate_limit: 100 +-- Test handling of inet netmasks with inet_minmax_multi_ops +CREATE TABLE brin_test_inet (a inet) +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_test_inet (a inet)" +== 021 +-- truncate_limit: 100 +CREATE INDEX ON brin_test_inet USING brin (a inet_minmax_multi_ops) +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_test_inet USING brin (a inet_minmax_multi_ops)" +== 022 +-- truncate_limit: 100 +INSERT INTO brin_test_inet VALUES ('127.0.0.1/0') +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_inet VALUES ('127.0.0.1/0')" +== 023 +-- truncate_limit: 100 +INSERT INTO brin_test_inet VALUES ('0.0.0.0/12') +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_inet VALUES ('0.0.0.0/12')" +== 024 +-- truncate_limit: 100 +DROP TABLE brin_test_inet +-- +TABLE: name="brin_test_inet" schema="" table="brin_test_inet" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_test_inet" +== 025 +-- truncate_limit: 100 +-- Tests for brin_summarize_new_values +SELECT brin_summarize_new_values('brintest_multi') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('brintest_multi')" +== 026 +-- truncate_limit: 100 +-- error, not an index +SELECT brin_summarize_new_values('tenk1_unique1') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('tenk1_unique1')" +== 027 +-- truncate_limit: 100 +-- error, not a BRIN index +SELECT brin_summarize_new_values('brinidx_multi') +-- +FUNCTION: name="brin_summarize_new_values" function="brin_summarize_new_values" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_new_values('brinidx_multi')" +== 028 +-- truncate_limit: 100 +-- ok, no change expected + +-- Tests for brin_desummarize_range +SELECT brin_desummarize_range('brinidx_multi', -1) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_multi', -1)" +== 029 +-- truncate_limit: 100 +-- error, invalid range +SELECT brin_desummarize_range('brinidx_multi', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_multi', 0)" +== 030 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx_multi', 0) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_multi', 0)" +== 031 +-- truncate_limit: 100 +SELECT brin_desummarize_range('brinidx_multi', 100000000) +-- +FUNCTION: name="brin_desummarize_range" function="brin_desummarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_desummarize_range('brinidx_multi', 100000000)" +== 032 +-- truncate_limit: 100 +-- test building an index with many values, to force compaction of the buffer +CREATE TABLE brin_large_range (a int4) +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_large_range (a int4)" +== 033 +-- truncate_limit: 100 +INSERT INTO brin_large_range SELECT i FROM generate_series(1,10000) s(i) +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_large_range SELECT i FROM generate_series(1, 10000) s(i)" +== 034 +-- truncate_limit: 100 +CREATE INDEX brin_large_range_idx ON brin_large_range USING brin (a int4_minmax_multi_ops) +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_large_range_idx ON brin_large_range USING brin (a int4_minmax_multi_ops)" +== 035 +-- truncate_limit: 100 +DROP TABLE brin_large_range +-- +TABLE: name="brin_large_range" schema="" table="brin_large_range" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_large_range" +== 036 +-- truncate_limit: 100 +-- Test brin_summarize_range +CREATE TABLE brin_summarize_multi ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false) +-- +TABLE: name="brin_summarize_multi" schema="" table="brin_summarize_multi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_summarize_multi (value int) WITH (fillfactor=10, autovacuum_enabled=false)" +== 037 +-- truncate_limit: 100 +CREATE INDEX brin_summarize_multi_idx ON brin_summarize_multi USING brin (value) WITH (pages_per_range=2) +-- +TABLE: name="brin_summarize_multi" schema="" table="brin_summarize_multi" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_summarize_multi_idx ON brin_summarize_multi USING brin (value) WITH (pages_per_..." +== 038 +-- truncate_limit: 100 +-- Fill a few pages +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize_multi VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE curtid tid;\nBEGIN\n LOOP\n INSERT INTO brin_summarize_multi VALUES (1) RETURNING ..." +== 039 +-- truncate_limit: 100 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_multi_idx', 0) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_multi_idx', 0)" +== 040 +-- truncate_limit: 100 +-- nothing: already summarized +SELECT brin_summarize_range('brin_summarize_multi_idx', 1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_multi_idx', 1)" +== 041 +-- truncate_limit: 100 +-- summarize one range +SELECT brin_summarize_range('brin_summarize_multi_idx', 2) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_multi_idx', 2)" +== 042 +-- truncate_limit: 100 +-- nothing: page doesn't exist in table +SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967295) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967295)" +== 043 +-- truncate_limit: 100 +-- invalid block number values +SELECT brin_summarize_range('brin_summarize_multi_idx', -1) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_multi_idx', -1)" +== 044 +-- truncate_limit: 100 +SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967296) +-- +FUNCTION: name="brin_summarize_range" function="brin_summarize_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967296)" +== 045 +-- truncate_limit: 100 +-- test brin cost estimates behave sanely based on correlation of values +CREATE TABLE brin_test_multi (a INT, b INT) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_test_multi (a int, b int)" +== 046 +-- truncate_limit: 100 +INSERT INTO brin_test_multi SELECT x/100,x%100 FROM generate_series(1,10000) x(x) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_multi SELECT x / 100, x % 100 FROM generate_series(1, 10000) x(x)" +== 047 +-- truncate_limit: 100 +CREATE INDEX brin_test_multi_a_idx ON brin_test_multi USING brin (a) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_multi_a_idx ON brin_test_multi USING brin (a) WITH (pages_per_range=2)" +== 048 +-- truncate_limit: 100 +CREATE INDEX brin_test_multi_b_idx ON brin_test_multi USING brin (b) WITH (pages_per_range = 2) +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_multi_b_idx ON brin_test_multi USING brin (b) WITH (pages_per_range=2)" +== 049 +-- truncate_limit: 100 +VACUUM ANALYZE brin_test_multi +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) brin_test_multi" +== 050 +-- truncate_limit: 100 +-- Ensure brin index is used when columns are perfectly correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE a = 1 +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE a = 1" +== 051 +-- truncate_limit: 100 +-- Ensure brin index is not used when values are not correlated +EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE b = 1 +-- +TABLE: name="brin_test_multi" schema="" table="brin_test_multi" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE b = 1" +== 052 +-- truncate_limit: 100 +-- do some inequality tests +CREATE TABLE brin_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_test_multi_1 (a int, b bigint) WITH (fillfactor=10)" +== 053 +-- truncate_limit: 100 +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_multi_1 SELECT ... FROM generate_series(1, 1000) s(i)" +== 054 +-- truncate_limit: 100 +CREATE INDEX brin_test_multi_1_idx_1 ON brin_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=5) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_multi_1_idx_1 ON brin_test_multi_1 USING brin (a int4_minmax_multi_ops) WI..." +== 055 +-- truncate_limit: 100 +CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=5) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_minmax_multi_ops) WI..." +== 056 +-- truncate_limit: 100 +SET enable_seqscan=off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 057 +-- truncate_limit: 100 +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a < 37" +== 058 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a < 113" +== 059 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a <= 177" +== 060 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a <= 25" +== 061 +-- truncate_limit: 100 +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a > 120" +== 062 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a >= 180" +== 063 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a > 71" +== 064 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a >= 63" +== 065 +-- truncate_limit: 100 +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a = 207" +== 066 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a = 177" +== 067 +-- truncate_limit: 100 +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b < 73" +== 068 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b <= 47" +== 069 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b < 199" +== 070 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b <= 150" +== 071 +-- truncate_limit: 100 +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b > 93" +== 072 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b > 37" +== 073 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b >= 215" +== 074 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b > 201" +== 075 +-- truncate_limit: 100 +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b = 88" +== 076 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b = 103" +== 077 +-- truncate_limit: 100 +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges +TRUNCATE brin_test_multi_1 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE brin_test_multi_1" +== 078 +-- truncate_limit: 100 +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i) +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_multi_1 SELECT ... FROM generate_series(1, 1000) s(i)" +== 079 +-- truncate_limit: 100 +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a < 37" +== 080 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a < 113" +== 081 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a <= 177" +== 082 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a <= 25" +== 083 +-- truncate_limit: 100 +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a > 120" +== 084 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a >= 180" +== 085 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a > 71" +== 086 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a >= 63" +== 087 +-- truncate_limit: 100 +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a = 207" +== 088 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE a = 177" +== 089 +-- truncate_limit: 100 +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b < 73" +== 090 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b <= 47" +== 091 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b < 199" +== 092 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b <= 150" +== 093 +-- truncate_limit: 100 +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b > 93" +== 094 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b > 37" +== 095 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b >= 215" +== 096 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b > 201" +== 097 +-- truncate_limit: 100 +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b = 88" +== 098 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_1 WHERE b = 103" +== 099 +-- truncate_limit: 100 +DROP TABLE brin_test_multi_1 +-- +TABLE: name="brin_test_multi_1" schema="" table="brin_test_multi_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_test_multi_1" +== 100 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 101 +-- truncate_limit: 100 +-- do some inequality tests for varlena data types +CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10) +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_test_multi_2 (a uuid) WITH (fillfactor=10)" +== 102 +-- truncate_limit: 100 +INSERT INTO brin_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random() +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DML +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_multi_2 SELECT ... FROM (SELECT ... FROM (SELECT ... FROM generate_series(1..." +== 103 +-- truncate_limit: 100 +CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5) +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH..." +== 104 +-- truncate_limit: 100 +SET enable_seqscan=off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 105 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'" +== 106 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'" +== 107 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea'" +== 108 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d'" +== 109 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79'" +== 110 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6'" +== 111 +-- truncate_limit: 100 +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges + +TRUNCATE brin_test_multi_2 +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE brin_test_multi_2" +== 112 +-- truncate_limit: 100 +INSERT INTO brin_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random() +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DML +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_test_multi_2 SELECT ... FROM (SELECT ... FROM (SELECT ... FROM generate_series(1..." +== 113 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'" +== 114 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'" +== 115 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea'" +== 116 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d'" +== 117 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79'" +== 118 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6' +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6'" +== 119 +-- truncate_limit: 100 +DROP TABLE brin_test_multi_2 +-- +TABLE: name="brin_test_multi_2" schema="" table="brin_test_multi_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_test_multi_2" +== 120 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 121 +-- truncate_limit: 100 +-- test overflows during CREATE INDEX with extreme timestamp values +CREATE TABLE brin_timestamp_test(a TIMESTAMPTZ) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_timestamp_test (a timestamptz)" +== 122 +-- truncate_limit: 100 +SET datestyle TO iso +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO iso" +== 123 +-- truncate_limit: 100 +-- values close to timestamp minimum +INSERT INTO brin_timestamp_test +SELECT '4713-01-01 00:00:01 BC'::timestamptz + (i || ' seconds')::interval + FROM generate_series(1,30) s(i) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_timestamp_test SELECT ... FROM generate_series(1, 30) s(i)" +== 124 +-- truncate_limit: 100 +-- values close to timestamp maximum +INSERT INTO brin_timestamp_test +SELECT '294276-12-01 00:00:01'::timestamptz + (i || ' seconds')::interval + FROM generate_series(1,30) s(i) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_timestamp_test SELECT ... FROM generate_series(1, 30) s(i)" +== 125 +-- truncate_limit: 100 +CREATE INDEX ON brin_timestamp_test USING brin (a timestamptz_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_timestamp_test USING brin (a timestamptz_minmax_multi_ops) WITH (pages_per_r..." +== 126 +-- truncate_limit: 100 +DROP TABLE brin_timestamp_test +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_timestamp_test" +== 127 +-- truncate_limit: 100 +-- test overflows during CREATE INDEX with extreme date values +CREATE TABLE brin_date_test(a DATE) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_date_test (a date)" +== 128 +-- truncate_limit: 100 +-- insert values close to date minimum +INSERT INTO brin_date_test SELECT '4713-01-01 BC'::date + i FROM generate_series(1, 30) s(i) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_date_test SELECT '4713-01-01 BC'::date + i FROM generate_series(1, 30) s(i)" +== 129 +-- truncate_limit: 100 +-- insert values close to date minimum +INSERT INTO brin_date_test SELECT '5874897-12-01'::date + i FROM generate_series(1, 30) s(i) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_date_test SELECT '5874897-12-01'::date + i FROM generate_series(1, 30) s(i)" +== 130 +-- truncate_limit: 100 +CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1)" +== 131 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 132 +-- truncate_limit: 100 +-- make sure the ranges were built correctly and 2023-01-01 eliminates all +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_date_test WHERE a = '202..." +== 133 +-- truncate_limit: 100 +DROP TABLE brin_date_test +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_date_test" +== 134 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 135 +-- truncate_limit: 100 +-- test handling of infinite timestamp values +CREATE TABLE brin_timestamp_test(a TIMESTAMP) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_timestamp_test (a timestamp)" +== 136 +-- truncate_limit: 100 +INSERT INTO brin_timestamp_test VALUES ('-infinity'), ('infinity') +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_timestamp_test VALUES ('-infinity'), ('infinity')" +== 137 +-- truncate_limit: 100 +INSERT INTO brin_timestamp_test +SELECT i FROM generate_series('2000-01-01'::timestamp, '2000-02-09'::timestamp, '1 day'::interval) s(i) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_timestamp_test SELECT i FROM generate_series('2000-01-01'::timestamp, '2000-02-0..." +== 138 +-- truncate_limit: 100 +CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WITH (pages_per_ran..." +== 139 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 140 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_timestamp_test WHERE a =..." +== 141 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_timestamp_test WHERE a =..." +== 142 +-- truncate_limit: 100 +DROP TABLE brin_timestamp_test +-- +TABLE: name="brin_timestamp_test" schema="" table="brin_timestamp_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_timestamp_test" +== 143 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 144 +-- truncate_limit: 100 +-- test handling of infinite date values +CREATE TABLE brin_date_test(a DATE) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_date_test (a date)" +== 145 +-- truncate_limit: 100 +INSERT INTO brin_date_test VALUES ('-infinity'), ('infinity') +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_date_test VALUES ('-infinity'), ('infinity')" +== 146 +-- truncate_limit: 100 +INSERT INTO brin_date_test SELECT '2000-01-01'::date + i FROM generate_series(1, 40) s(i) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_date_test SELECT '2000-01-01'::date + i FROM generate_series(1, 40) s(i)" +== 147 +-- truncate_limit: 100 +CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1)" +== 148 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 149 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_date_test WHERE a = '202..." +== 150 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_date_test WHERE a = '190..." +== 151 +-- truncate_limit: 100 +DROP TABLE brin_date_test +-- +TABLE: name="brin_date_test" schema="" table="brin_date_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_date_test" +== 152 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 153 +-- truncate_limit: 100 +RESET datestyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" +== 154 +-- truncate_limit: 100 +-- test handling of overflow for interval values +CREATE TABLE brin_interval_test(a INTERVAL) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_interval_test (a interval)" +== 155 +-- truncate_limit: 100 +INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series(-178000000, -177999980) s(i) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_interval_test SELECT ... FROM generate_series(-178000000, -177999980) s(i)" +== 156 +-- truncate_limit: 100 +INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series( 177999980, 178000000) s(i) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_interval_test SELECT ... FROM generate_series(177999980, 178000000) s(i)" +== 157 +-- truncate_limit: 100 +CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1)" +== 158 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 159 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_interval_test WHERE a = ..." +== 160 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_interval_test WHERE a = ..." +== 161 +-- truncate_limit: 100 +DROP TABLE brin_interval_test +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_interval_test" +== 162 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 163 +-- truncate_limit: 100 +-- test handling of infinite interval values +CREATE TABLE brin_interval_test(a INTERVAL) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_interval_test (a interval)" +== 164 +-- truncate_limit: 100 +INSERT INTO brin_interval_test VALUES ('-infinity'), ('infinity') +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_interval_test VALUES ('-infinity'), ('infinity')" +== 165 +-- truncate_limit: 100 +INSERT INTO brin_interval_test SELECT (i || ' days')::interval FROM generate_series(100, 140) s(i) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_interval_test SELECT (i || ' days')::interval FROM generate_series(100, 140) s(i)" +== 166 +-- truncate_limit: 100 +CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1) +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1)" +== 167 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 168 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_interval_test WHERE a = ..." +== 169 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) +SELECT * FROM brin_interval_test WHERE a = '30 years'::interval +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF) SELECT * FROM brin_interval_test WHERE a = ..." +== 170 +-- truncate_limit: 100 +DROP TABLE brin_interval_test +-- +TABLE: name="brin_interval_test" schema="" table="brin_interval_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_interval_test" +== 171 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 172 +-- truncate_limit: 100 +RESET datestyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" diff --git a/parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json b/parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json new file mode 100644 index 0000000..11ed4d1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json @@ -0,0 +1,100 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/btree_index.test b/parser/testdata/summary_truncate/postgres_regress/btree_index.test new file mode 100644 index 0000000..c4e0869 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/btree_index.test @@ -0,0 +1,883 @@ +== 001 +-- truncate_limit: 100 +|-- +-- BTREE_INDEX +|-- + +-- directory paths are passed to us in environment variables + +CREATE TABLE bt_i4_heap ( + seqno int4, + random int4 +) +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bt_i4_heap (seqno int4, random int4)" +== 002 +-- truncate_limit: 100 +CREATE TABLE bt_name_heap ( + seqno name, + random int4 +) +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bt_name_heap (seqno name, random int4)" +== 003 +-- truncate_limit: 100 +CREATE TABLE bt_txt_heap ( + seqno text, + random int4 +) +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bt_txt_heap (seqno text, random int4)" +== 004 +-- truncate_limit: 100 +CREATE TABLE bt_f8_heap ( + seqno float8, + random int4 +) +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bt_f8_heap (seqno float8, random int4)" +== 005 +-- truncate_limit: 100 +COPY bt_i4_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- truncate_limit: 100 +COPY bt_name_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- truncate_limit: 100 +COPY bt_txt_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- truncate_limit: 100 +COPY bt_f8_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- truncate_limit: 100 +ANALYZE bt_i4_heap +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE bt_i4_heap" +== 010 +-- truncate_limit: 100 +ANALYZE bt_name_heap +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE bt_name_heap" +== 011 +-- truncate_limit: 100 +ANALYZE bt_txt_heap +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE bt_txt_heap" +== 012 +-- truncate_limit: 100 +ANALYZE bt_f8_heap +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE bt_f8_heap" +== 013 +-- truncate_limit: 100 +|-- +-- BTREE ascending/descending cases +|-- +-- we load int4/text from pure descending data (each key is a new +-- low key) and name/f8 from pure ascending data (each key is a new +-- high key). we had a bug where new low keys would sometimes be +-- "lost". +|-- +CREATE INDEX bt_i4_index ON bt_i4_heap USING btree (seqno int4_ops) +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX bt_i4_index ON bt_i4_heap USING btree (seqno int4_ops)" +== 014 +-- truncate_limit: 100 +CREATE INDEX bt_name_index ON bt_name_heap USING btree (seqno name_ops) +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX bt_name_index ON bt_name_heap USING btree (seqno name_ops)" +== 015 +-- truncate_limit: 100 +CREATE INDEX bt_txt_index ON bt_txt_heap USING btree (seqno text_ops) +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX bt_txt_index ON bt_txt_heap USING btree (seqno text_ops)" +== 016 +-- truncate_limit: 100 +CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops) +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops)" +== 017 +-- truncate_limit: 100 +|-- +-- test retrieval of min/max keys for each index +|-- + +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno < 1 +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=Select +ALIAS: "b"="bt_i4_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_i4_heap b WHERE b.seqno < 1" +== 018 +-- truncate_limit: 100 +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno >= 9999 +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=Select +ALIAS: "b"="bt_i4_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_i4_heap b WHERE b.seqno >= 9999" +== 019 +-- truncate_limit: 100 +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno = 4500 +-- +TABLE: name="bt_i4_heap" schema="" table="bt_i4_heap" ctx=Select +ALIAS: "b"="bt_i4_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_i4_heap b WHERE b.seqno = 4500" +== 020 +-- truncate_limit: 100 +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno < '1'::name +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=Select +ALIAS: "b"="bt_name_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_name_heap b WHERE b.seqno < '1'::name" +== 021 +-- truncate_limit: 100 +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno >= '9999'::name +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=Select +ALIAS: "b"="bt_name_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_name_heap b WHERE b.seqno >= '9999'::name" +== 022 +-- truncate_limit: 100 +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno = '4500'::name +-- +TABLE: name="bt_name_heap" schema="" table="bt_name_heap" ctx=Select +ALIAS: "b"="bt_name_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_name_heap b WHERE b.seqno = '4500'::name" +== 023 +-- truncate_limit: 100 +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno < '1'::text +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=Select +ALIAS: "b"="bt_txt_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_txt_heap b WHERE b.seqno < '1'::text" +== 024 +-- truncate_limit: 100 +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno >= '9999'::text +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=Select +ALIAS: "b"="bt_txt_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_txt_heap b WHERE b.seqno >= '9999'::text" +== 025 +-- truncate_limit: 100 +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno = '4500'::text +-- +TABLE: name="bt_txt_heap" schema="" table="bt_txt_heap" ctx=Select +ALIAS: "b"="bt_txt_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_txt_heap b WHERE b.seqno = '4500'::text" +== 026 +-- truncate_limit: 100 +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno < '1'::float8 +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=Select +ALIAS: "b"="bt_f8_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_f8_heap b WHERE b.seqno < '1'::float8" +== 027 +-- truncate_limit: 100 +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno >= '9999'::float8 +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=Select +ALIAS: "b"="bt_f8_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_f8_heap b WHERE b.seqno >= '9999'::float8" +== 028 +-- truncate_limit: 100 +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno = '4500'::float8 +-- +TABLE: name="bt_f8_heap" schema="" table="bt_f8_heap" ctx=Select +ALIAS: "b"="bt_f8_heap" +FILTER: schema="" table="b" column="seqno" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM bt_f8_heap b WHERE b.seqno = '4500'::float8" +== 029 +-- truncate_limit: 100 +|-- +-- Add coverage for optimization of backwards scan index descents +|-- +-- Here we expect _bt_search to descend straight to a leaf page containing a +-- non-pivot tuple with the value '47', which comes last (after 11 similar +-- non-pivot tuples). Query execution should only need to visit a single +-- leaf page here. +|-- +-- Test case relies on tenk1_hundred index having a leaf page whose high key +-- is '(48, -inf)'. We use a low cardinality index to make our test case less +-- sensitive to implementation details that may change in the future. +set enable_seqscan to false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO FALSE" +== 030 +-- truncate_limit: 100 +set enable_indexscan to true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO TRUE" +== 031 +-- truncate_limit: 100 +set enable_bitmapscan to false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO FALSE" +== 032 +-- truncate_limit: 100 +explain (costs off) +select hundred, twenty from tenk1 where hundred < 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT hundred, twenty FROM tenk1 WHERE hundred < 48 ORDER BY hundred DESC LI..." +== 033 +-- truncate_limit: 100 +select hundred, twenty from tenk1 where hundred < 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT hundred, twenty FROM tenk1 WHERE hundred < 48 ORDER BY hundred DESC LIMIT 1" +== 034 +-- truncate_limit: 100 +-- This variant of the query need only return a single tuple located to the immediate +-- right of the '(48, -inf)' high key. It also only needs to scan one single +-- leaf page (the right sibling of the page scanned by the last test case): +explain (costs off) +select hundred, twenty from tenk1 where hundred <= 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT hundred, twenty FROM tenk1 WHERE hundred <= 48 ORDER BY hundred DESC L..." +== 035 +-- truncate_limit: 100 +select hundred, twenty from tenk1 where hundred <= 48 order by hundred desc limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT hundred, twenty FROM tenk1 WHERE hundred <= 48 ORDER BY hundred DESC LIMIT 1" +== 036 +-- truncate_limit: 100 +|-- +-- Add coverage for ScalarArrayOp btree quals with pivot tuple constants +|-- +explain (costs off) +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT hundred FROM tenk1 WHERE hundred IN (47, 48, 72, 82)" +== 037 +-- truncate_limit: 100 +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT hundred FROM tenk1 WHERE hundred IN (47, 48, 72, 82)" +== 038 +-- truncate_limit: 100 +explain (costs off) +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) order by hundred desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT hundred FROM tenk1 WHERE hundred IN (47, 48, 72, 82) ORDER BY..." +== 039 +-- truncate_limit: 100 +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) order by hundred desc +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT hundred FROM tenk1 WHERE hundred IN (47, 48, 72, 82) ORDER BY hundred DESC" +== 040 +-- truncate_limit: 100 +explain (costs off) +select thousand from tenk1 where thousand in (364, 366,380) and tenthous = 200000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand FROM tenk1 WHERE thousand IN (364, 366, 380) AND tenthous = 2..." +== 041 +-- truncate_limit: 100 +select thousand from tenk1 where thousand in (364, 366,380) and tenthous = 200000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT thousand FROM tenk1 WHERE thousand IN (364, 366, 380) AND tenthous = 200000" +== 042 +-- truncate_limit: 100 +|-- +-- Check correct optimization of LIKE (special index operator support) +-- for both indexscan and bitmapscan cases +|-- + +set enable_seqscan to false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO FALSE" +== 043 +-- truncate_limit: 100 +set enable_indexscan to true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO TRUE" +== 044 +-- truncate_limit: 100 +set enable_bitmapscan to false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO FALSE" +== 045 +-- truncate_limit: 100 +explain (costs off) +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT proname FROM pg_proc WHERE proname LIKE E'RI\\\\_FKey%del' ORDER BY 1" +== 046 +-- truncate_limit: 100 +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +TRUNCATED: "SELECT proname FROM pg_proc WHERE proname LIKE E'RI\\\\_FKey%del' ORDER BY 1" +== 047 +-- truncate_limit: 100 +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT proname FROM pg_proc WHERE proname ILIKE '00%foo' ORDER BY 1" +== 048 +-- truncate_limit: 100 +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +TRUNCATED: "SELECT proname FROM pg_proc WHERE proname ILIKE '00%foo' ORDER BY 1" +== 049 +-- truncate_limit: 100 +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT proname FROM pg_proc WHERE proname ILIKE 'ri%foo' ORDER BY 1" +== 050 +-- truncate_limit: 100 +set enable_indexscan to false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO FALSE" +== 051 +-- truncate_limit: 100 +set enable_bitmapscan to true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO TRUE" +== 052 +-- truncate_limit: 100 +explain (costs off) +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT proname FROM pg_proc WHERE proname LIKE E'RI\\\\_FKey%del' ORDER BY 1" +== 053 +-- truncate_limit: 100 +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +TRUNCATED: "SELECT proname FROM pg_proc WHERE proname LIKE E'RI\\\\_FKey%del' ORDER BY 1" +== 054 +-- truncate_limit: 100 +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT proname FROM pg_proc WHERE proname ILIKE '00%foo' ORDER BY 1" +== 055 +-- truncate_limit: 100 +select proname from pg_proc where proname ilike '00%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +TRUNCATED: "SELECT proname FROM pg_proc WHERE proname ILIKE '00%foo' ORDER BY 1" +== 056 +-- truncate_limit: 100 +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT proname FROM pg_proc WHERE proname ILIKE 'ri%foo' ORDER BY 1" +== 057 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 058 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 059 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 060 +-- truncate_limit: 100 +-- Also check LIKE optimization with binary-compatible cases + +create temp table btree_bpchar (f1 text collate "C") +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE btree_bpchar (f1 text COLLATE \"C\")" +== 061 +-- truncate_limit: 100 +create index on btree_bpchar(f1 bpchar_ops) WITH (deduplicate_items=on) +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON btree_bpchar USING btree (f1 bpchar_ops) WITH (deduplicate_items=on)" +== 062 +-- truncate_limit: 100 +insert into btree_bpchar values ('foo'), ('fool'), ('bar'), ('quux') +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO btree_bpchar VALUES ('foo'), ('fool'), ('bar'), ('quux')" +== 063 +-- truncate_limit: 100 +-- doesn't match index: +explain (costs off) +select * from btree_bpchar where f1 like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM btree_bpchar WHERE f1 LIKE 'foo'" +== 064 +-- truncate_limit: 100 +select * from btree_bpchar where f1 like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM btree_bpchar WHERE f1 LIKE 'foo'" +== 065 +-- truncate_limit: 100 +explain (costs off) +select * from btree_bpchar where f1 like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM btree_bpchar WHERE f1 LIKE 'foo%'" +== 066 +-- truncate_limit: 100 +select * from btree_bpchar where f1 like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM btree_bpchar WHERE f1 LIKE 'foo%'" +== 067 +-- truncate_limit: 100 +-- these do match the index: +explain (costs off) +select * from btree_bpchar where f1::bpchar like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM btree_bpchar WHERE f1::bpchar LIKE 'foo'" +== 068 +-- truncate_limit: 100 +select * from btree_bpchar where f1::bpchar like 'foo' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM btree_bpchar WHERE f1::bpchar LIKE 'foo'" +== 069 +-- truncate_limit: 100 +explain (costs off) +select * from btree_bpchar where f1::bpchar like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM btree_bpchar WHERE f1::bpchar LIKE 'foo%'" +== 070 +-- truncate_limit: 100 +select * from btree_bpchar where f1::bpchar like 'foo%' +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM btree_bpchar WHERE f1::bpchar LIKE 'foo%'" +== 071 +-- truncate_limit: 100 +-- get test coverage for "single value" deduplication strategy: +insert into btree_bpchar select 'foo' from generate_series(1,1500) +-- +TABLE: name="btree_bpchar" schema="" table="btree_bpchar" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO btree_bpchar SELECT 'foo' FROM generate_series(1, 1500)" +== 072 +-- truncate_limit: 100 +|-- +-- Perform unique checking, with and without the use of deduplication +|-- +CREATE TABLE dedup_unique_test_table (a int) WITH (autovacuum_enabled=false) +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dedup_unique_test_table (a int) WITH (autovacuum_enabled=false)" +== 073 +-- truncate_limit: 100 +CREATE UNIQUE INDEX dedup_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=on) +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX dedup_unique ON dedup_unique_test_table USING btree (a) WITH (deduplicate_ite..." +== 074 +-- truncate_limit: 100 +CREATE UNIQUE INDEX plain_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=off) +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX plain_unique ON dedup_unique_test_table USING btree (a) WITH (deduplicate_ite..." +== 075 +-- truncate_limit: 100 +-- 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$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n FOR r IN 1..1350 LOOP\n DELETE FROM dedup_unique_test_table;\n INSERT..." +== 076 +-- truncate_limit: 100 +-- 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 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX plain_unique" +== 077 +-- truncate_limit: 100 +DELETE FROM dedup_unique_test_table WHERE a = 1 +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM dedup_unique_test_table WHERE a = 1" +== 078 +-- truncate_limit: 100 +INSERT INTO dedup_unique_test_table SELECT i FROM generate_series(0,450) i +-- +TABLE: name="dedup_unique_test_table" schema="" table="dedup_unique_test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dedup_unique_test_table SELECT i FROM generate_series(0, 450) i" +== 079 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE btree_tall_tbl (id int4, t text)" +== 080 +-- truncate_limit: 100 +alter table btree_tall_tbl alter COLUMN t set storage plain +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE btree_tall_tbl ALTER COLUMN t SET STORAGE plain" +== 081 +-- truncate_limit: 100 +create index btree_tall_idx on btree_tall_tbl (t, id) with (fillfactor = 10) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX btree_tall_idx ON btree_tall_tbl USING btree (t, id) WITH (fillfactor=10)" +== 082 +-- truncate_limit: 100 +insert into btree_tall_tbl select g, repeat('x', 250) +from generate_series(1, 130) g +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO btree_tall_tbl SELECT g, repeat('x', 250) FROM generate_series(1, 130) g" +== 083 +-- truncate_limit: 100 +|-- +-- Test for multilevel page deletion +|-- +CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint) +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint)" +== 084 +-- truncate_limit: 100 +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1, 80000) i" +== 085 +-- truncate_limit: 100 +ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d) +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE delete_test_table ADD PRIMARY KEY (a, b, c, d)" +== 086 +-- truncate_limit: 100 +-- Delete most entries, and vacuum, deleting internal pages and creating "fast +-- root" +DELETE FROM delete_test_table WHERE a < 79990 +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM delete_test_table WHERE a < 79990" +== 087 +-- truncate_limit: 100 +VACUUM delete_test_table +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM delete_test_table" +== 088 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="delete_test_table" schema="" table="delete_test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1, 1000) i" +== 089 +-- truncate_limit: 100 +-- Test unsupported btree opclass parameters +create index on btree_tall_tbl (id int4_ops(foo=1)) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON btree_tall_tbl USING btree (id int4_ops(foo=1))" +== 090 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="btree_tall_tbl" schema="" table="btree_tall_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX btree_tall_idx2 ON btree_tall_tbl USING btree (id)" +== 091 +-- truncate_limit: 100 +ALTER INDEX btree_tall_idx2 ALTER COLUMN id SET (n_distinct=100) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX btree_tall_idx2 ALTER COLUMN id SET (n_distinct=100)" +== 092 +-- truncate_limit: 100 +DROP INDEX btree_tall_idx2 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX btree_tall_idx2" +== 093 +-- truncate_limit: 100 +-- Partitioned index +CREATE TABLE btree_part (id int4) PARTITION BY RANGE (id) +-- +TABLE: name="btree_part" schema="" table="btree_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE btree_part (id int4) PARTITION BY RANGE (id)" +== 094 +-- truncate_limit: 100 +CREATE INDEX btree_part_idx ON btree_part(id) +-- +TABLE: name="btree_part" schema="" table="btree_part" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX btree_part_idx ON btree_part USING btree (id)" +== 095 +-- truncate_limit: 100 +ALTER INDEX btree_part_idx ALTER COLUMN id SET (n_distinct=100) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX btree_part_idx ALTER COLUMN id SET (n_distinct=100)" +== 096 +-- truncate_limit: 100 +DROP TABLE btree_part +-- +TABLE: name="btree_part" schema="" table="btree_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE btree_part" diff --git a/parser/testdata/summary_truncate/postgres_regress/case.metadata.json b/parser/testdata/summary_truncate/postgres_regress/case.metadata.json new file mode 100644 index 0000000..f47f175 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/case.metadata.json @@ -0,0 +1,68 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/case.test b/parser/testdata/summary_truncate/postgres_regress/case.test new file mode 100644 index 0000000..6853382 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/case.test @@ -0,0 +1,618 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CASE +-- Test the case statement +|-- + +CREATE TABLE CASE_TBL ( + i integer, + f double precision +) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE case_tbl (i int, f double precision)" +== 002 +-- truncate_limit: 100 +CREATE TABLE CASE2_TBL ( + i integer, + j integer +) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE case2_tbl (i int, j int)" +== 003 +-- truncate_limit: 100 +INSERT INTO CASE_TBL VALUES (1, 10.1) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case_tbl VALUES (1, 10.1)" +== 004 +-- truncate_limit: 100 +INSERT INTO CASE_TBL VALUES (2, 20.2) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case_tbl VALUES (2, 20.2)" +== 005 +-- truncate_limit: 100 +INSERT INTO CASE_TBL VALUES (3, -30.3) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case_tbl VALUES (3, -30.3)" +== 006 +-- truncate_limit: 100 +INSERT INTO CASE_TBL VALUES (4, NULL) +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case_tbl VALUES (4, NULL)" +== 007 +-- truncate_limit: 100 +INSERT INTO CASE2_TBL VALUES (1, -1) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case2_tbl VALUES (1, -1)" +== 008 +-- truncate_limit: 100 +INSERT INTO CASE2_TBL VALUES (2, -2) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case2_tbl VALUES (2, -2)" +== 009 +-- truncate_limit: 100 +INSERT INTO CASE2_TBL VALUES (3, -3) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case2_tbl VALUES (3, -3)" +== 010 +-- truncate_limit: 100 +INSERT INTO CASE2_TBL VALUES (2, -4) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case2_tbl VALUES (2, -4)" +== 011 +-- truncate_limit: 100 +INSERT INTO CASE2_TBL VALUES (1, NULL) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case2_tbl VALUES (1, NULL)" +== 012 +-- truncate_limit: 100 +INSERT INTO CASE2_TBL VALUES (NULL, -6) +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO case2_tbl VALUES (NULL, -6)" +== 013 +-- truncate_limit: 100 +|-- +-- Simplest examples without tables +|-- + +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + END AS "Simple WHEN" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3' AS \"One\", CASE WHEN 1 < 2 THEN 3 END AS \"Simple WHEN\"" +== 014 +-- truncate_limit: 100 +SELECT '' AS "One", + CASE + WHEN 1 > 2 THEN 3 + END AS "Simple default" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '' AS \"One\", CASE WHEN 1 > 2 THEN 3 END AS \"Simple default\"" +== 015 +-- truncate_limit: 100 +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + ELSE 4 + END AS "Simple ELSE" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3' AS \"One\", CASE WHEN 1 < 2 THEN 3 ELSE 4 END AS \"Simple ELSE\"" +== 016 +-- truncate_limit: 100 +SELECT '4' AS "One", + CASE + WHEN 1 > 2 THEN 3 + ELSE 4 + END AS "ELSE default" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4' AS \"One\", CASE WHEN 1 > 2 THEN 3 ELSE 4 END AS \"ELSE default\"" +== 017 +-- truncate_limit: 100 +SELECT '6' AS "One", + CASE + WHEN 1 > 2 THEN 3 + WHEN 4 < 5 THEN 6 + ELSE 7 + END AS "Two WHEN with default" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '6' AS \"One\", CASE WHEN 1 > 2 THEN 3 WHEN 4 < 5 THEN 6 ELSE 7 END AS \"Two WHEN with default\"" +== 018 +-- truncate_limit: 100 +SELECT '7' AS "None", + CASE WHEN random() < 0 THEN 1 + END AS "NULL on no matches" +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '7' AS \"None\", CASE WHEN random() < 0 THEN 1 END AS \"NULL on no matches\"" +== 019 +-- truncate_limit: 100 +-- Constant-expression folding shouldn't evaluate unreachable subexpressions +SELECT CASE WHEN 1=0 THEN 1/0 WHEN 1=1 THEN 1 ELSE 2/0 END +-- +STMT: SelectStmt +TRUNCATED: "SELECT CASE WHEN 1 = 0 THEN 1 / 0 WHEN 1 = 1 THEN 1 ELSE 2 / 0 END" +== 020 +-- truncate_limit: 100 +SELECT CASE 1 WHEN 0 THEN 1/0 WHEN 1 THEN 1 ELSE 2/0 END +-- +STMT: SelectStmt +TRUNCATED: "SELECT CASE 1 WHEN 0 THEN 1 / 0 WHEN 1 THEN 1 ELSE 2 / 0 END" +== 021 +-- truncate_limit: 100 +-- However we do not currently suppress folding of potentially +-- reachable subexpressions +SELECT CASE WHEN i > 100 THEN 1/0 ELSE 0 END FROM case_tbl +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT CASE WHEN i > 100 THEN 1 / 0 ELSE 0 END FROM case_tbl" +== 022 +-- truncate_limit: 100 +-- Test for cases involving untyped literals in test expression +SELECT CASE 'a' WHEN 'a' THEN 1 ELSE 2 END +-- +STMT: SelectStmt +TRUNCATED: "SELECT CASE 'a' WHEN 'a' THEN 1 ELSE 2 END" +== 023 +-- truncate_limit: 100 +|-- +-- Examples of targets involving tables +|-- + +SELECT + CASE + WHEN i >= 3 THEN i + END AS ">= 3 or Null" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT CASE WHEN i >= 3 THEN i END AS \">= 3 or Null\" FROM case_tbl" +== 024 +-- truncate_limit: 100 +SELECT + CASE WHEN i >= 3 THEN (i + i) + ELSE i + END AS "Simplest Math" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT CASE WHEN i >= 3 THEN i + i ELSE i END AS \"Simplest Math\" FROM case_tbl" +== 025 +-- truncate_limit: 100 +SELECT i AS "Value", + CASE WHEN (i < 0) THEN 'small' + WHEN (i = 0) THEN 'zero' + WHEN (i = 1) THEN 'one' + WHEN (i = 2) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM case_tbl" +== 026 +-- truncate_limit: 100 +SELECT + CASE WHEN ((i < 0) or (i < 0)) THEN 'small' + WHEN ((i = 0) or (i = 0)) THEN 'zero' + WHEN ((i = 1) or (i = 1)) THEN 'one' + WHEN ((i = 2) or (i = 2)) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM case_tbl" +== 027 +-- truncate_limit: 100 +|-- +-- Examples of qualifications involving tables +|-- + +|-- +-- NULLIF() and COALESCE() +-- Shorthand forms for typical CASE constructs +-- defined in the SQL standard. +|-- + +SELECT * FROM CASE_TBL WHERE COALESCE(f,i) = 4 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +FILTER: schema="" table="" column="f" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM case_tbl WHERE COALESCE(f, i) = 4" +== 028 +-- truncate_limit: 100 +SELECT * FROM CASE_TBL WHERE NULLIF(f,i) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +FILTER: schema="" table="" column="f" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM case_tbl WHERE (NULLIF(f, i)) = 2" +== 029 +-- truncate_limit: 100 +SELECT COALESCE(a.f, b.i, b.j) + FROM CASE_TBL a, CASE2_TBL b +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT COALESCE(a.f, b.i, b.j) FROM case_tbl a, case2_tbl b" +== 030 +-- truncate_limit: 100 +SELECT * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(a.f, b.i, b.j) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +FILTER: schema="" table="a" column="f" +FILTER: schema="" table="b" column="i" +FILTER: schema="" table="b" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM case_tbl a, case2_tbl b WHERE COALESCE(a.f, b.i, b.j) = 2" +== 031 +-- truncate_limit: 100 +SELECT NULLIF(a.i,b.i) AS "NULLIF(a.i,b.i)", + NULLIF(b.i, 4) AS "NULLIF(b.i,4)" + FROM CASE_TBL a, CASE2_TBL b +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM case_tbl a, case2_tbl b" +== 032 +-- truncate_limit: 100 +SELECT * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(f,b.i) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "a"="case_tbl" +ALIAS: "b"="case2_tbl" +FILTER: schema="" table="" column="f" +FILTER: schema="" table="b" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM case_tbl a, case2_tbl b WHERE COALESCE(f, b.i) = 2" +== 033 +-- truncate_limit: 100 +-- Tests for constant subexpression simplification + +explain (costs off) +SELECT * FROM CASE_TBL WHERE NULLIF(1, 2) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM case_tbl WHERE (NULLIF(1, 2)) = 2" +== 034 +-- truncate_limit: 100 +explain (costs off) +SELECT * FROM CASE_TBL WHERE NULLIF(1, 1) IS NOT NULL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM case_tbl WHERE NULLIF(1, 1) IS NOT NULL" +== 035 +-- truncate_limit: 100 +explain (costs off) +SELECT * FROM CASE_TBL WHERE NULLIF(1, null) = 2 +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM case_tbl WHERE (NULLIF(1, NULL)) = 2" +== 036 +-- truncate_limit: 100 +|-- +-- Examples of updates involving tables +|-- + +UPDATE CASE_TBL + SET i = CASE WHEN i >= 3 THEN (- i) + ELSE (2 * i) END +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE case_tbl SET i = CASE WHEN i >= 3 THEN - i ELSE 2 * i END" +== 037 +-- truncate_limit: 100 +SELECT * FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM case_tbl" +== 038 +-- truncate_limit: 100 +UPDATE CASE_TBL + SET i = CASE WHEN i >= 2 THEN (2 * i) + ELSE (3 * i) END +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE case_tbl SET i = CASE WHEN i >= 2 THEN 2 * i ELSE 3 * i END" +== 039 +-- truncate_limit: 100 +SELECT * FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM case_tbl" +== 040 +-- truncate_limit: 100 +UPDATE CASE_TBL + SET i = CASE WHEN b.i >= 2 THEN (2 * j) + ELSE (3 * j) END + FROM CASE2_TBL b + WHERE j = -CASE_TBL.i +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DML +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=Select +ALIAS: "b"="case2_tbl" +STMT: UpdateStmt +TRUNCATED: "UPDATE case_tbl SET ... = ... FROM case2_tbl b WHERE j = (- case_tbl.i)" +== 041 +-- truncate_limit: 100 +SELECT * FROM CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM case_tbl" +== 042 +-- truncate_limit: 100 +|-- +-- Nested CASE expressions +|-- + +-- This test exercises a bug caused by aliasing econtext->caseValue_isNull +-- with the isNull argument of the inner CASE's CaseExpr evaluation. After +-- evaluating the vol(null) expression in the inner CASE's second WHEN-clause, +-- the isNull flag for the case test value incorrectly became true, causing +-- the third WHEN-clause not to match. The volatile function calls are needed +-- to prevent constant-folding in the planner, which would hide the bug. + +-- Wrap this in a single transaction so the transient '=' operator doesn't +-- cause problems in concurrent sessions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 043 +-- truncate_limit: 100 +CREATE FUNCTION vol(text) returns text as + 'begin return $1; end' language plpgsql volatile +-- +FUNCTION: name="vol" function="vol" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION vol(text) RETURNS text AS $$begin return $1; end$$ LANGUAGE plpgsql VOLATILE" +== 044 +-- truncate_limit: 100 +SELECT CASE + (CASE vol('bar') + WHEN 'foo' THEN 'it was foo!' + WHEN vol(null) THEN 'null input' + WHEN 'bar' THEN 'it was bar!' END + ) + WHEN 'it was foo!' THEN 'foo recognized' + WHEN 'it was bar!' THEN 'bar recognized' + ELSE 'unrecognized' END +-- +FUNCTION: name="vol" function="vol" schema="" ctx=Call +FUNCTION: name="vol" function="vol" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 045 +-- truncate_limit: 100 +-- In this case, we can't inline the SQL function without confusing things. +CREATE DOMAIN foodomain AS text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN foodomain AS text" +== 046 +-- truncate_limit: 100 +CREATE FUNCTION volfoo(text) returns foodomain as + 'begin return $1::foodomain; end' language plpgsql volatile +-- +FUNCTION: name="volfoo" function="volfoo" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION volfoo(text) RETURNS foodomain AS $$begin return $1::foodomain; end$$ LANGUAGE pl..." +== 047 +-- truncate_limit: 100 +CREATE FUNCTION inline_eq(foodomain, foodomain) returns boolean as + 'SELECT CASE $2::text WHEN $1::text THEN true ELSE false END' language sql +-- +FUNCTION: name="inline_eq" function="inline_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION inline_eq(foodomain, foodomain) RETURNS boolean AS $$SELECT CASE $2::text WHEN $1..." +== 048 +-- truncate_limit: 100 +CREATE OPERATOR = (procedure = inline_eq, + leftarg = foodomain, rightarg = foodomain) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (procedure = inline_eq, leftarg = foodomain, rightarg = foodomain)" +== 049 +-- truncate_limit: 100 +SELECT CASE volfoo('bar') WHEN 'foo'::foodomain THEN 'is foo' ELSE 'is not foo' END +-- +FUNCTION: name="volfoo" function="volfoo" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT CASE volfoo('bar') WHEN 'foo'::foodomain THEN 'is foo' ELSE 'is not foo' END" +== 050 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 051 +-- truncate_limit: 100 +-- Test multiple evaluation of a CASE arg that is a read/write object (#14472) +-- Wrap this in a single transaction so the transient '=' operator doesn't +-- cause problems in concurrent sessions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 052 +-- truncate_limit: 100 +CREATE DOMAIN arrdomain AS int[] +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN arrdomain AS int[]" +== 053 +-- truncate_limit: 100 +CREATE FUNCTION make_ad(int,int) returns arrdomain as + 'declare x arrdomain; + begin + x := array[$1,$2]; + return x; + end' language plpgsql volatile +-- +FUNCTION: name="make_ad" function="make_ad" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION make_ad(int, int) RETURNS arrdomain AS $$declare x arrdomain;\n begin\n x := ..." +== 054 +-- truncate_limit: 100 +CREATE FUNCTION ad_eq(arrdomain, arrdomain) returns boolean as + 'begin return array_eq($1, $2); end' language plpgsql +-- +FUNCTION: name="ad_eq" function="ad_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ad_eq(arrdomain, arrdomain) RETURNS boolean AS $$begin return array_eq($1, $2); e..." +== 055 +-- truncate_limit: 100 +CREATE OPERATOR = (procedure = ad_eq, + leftarg = arrdomain, rightarg = arrdomain) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (procedure = ad_eq, leftarg = arrdomain, rightarg = arrdomain)" +== 056 +-- truncate_limit: 100 +SELECT CASE make_ad(1,2) + WHEN array[2,4]::arrdomain THEN 'wrong' + WHEN array[2,5]::arrdomain THEN 'still wrong' + WHEN array[1,2]::arrdomain THEN 'right' + END +-- +FUNCTION: name="make_ad" function="make_ad" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 057 +-- truncate_limit: 100 +-- While we're here, also test handling of a NULLIF arg that is a read/write +-- object (bug #18722) + +SELECT NULLIF(make_ad(1,2), array[2,3]::arrdomain) +-- +FUNCTION: name="make_ad" function="make_ad" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT NULLIF(make_ad(1, 2), ARRAY[2, 3]::arrdomain)" +== 058 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 059 +-- truncate_limit: 100 +-- Test interaction of CASE with ArrayCoerceExpr (bug #15471) +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 060 +-- truncate_limit: 100 +CREATE TYPE casetestenum AS ENUM ('e', 'f', 'g') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE casetestenum AS ENUM ('e', 'f', 'g')" +== 061 +-- truncate_limit: 100 +SELECT + CASE 'foo'::text + WHEN 'foo' THEN ARRAY['a', 'b', 'c', 'd'] || enum_range(NULL::casetestenum)::text[] + ELSE ARRAY['x', 'y'] + END +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 062 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 063 +-- truncate_limit: 100 +|-- +-- Clean up +|-- + +DROP TABLE CASE_TBL +-- +TABLE: name="case_tbl" schema="" table="case_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE case_tbl" +== 064 +-- truncate_limit: 100 +DROP TABLE CASE2_TBL +-- +TABLE: name="case2_tbl" schema="" table="case2_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE case2_tbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/char.metadata.json b/parser/testdata/summary_truncate/postgres_regress/char.metadata.json new file mode 100644 index 0000000..efb3a10 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/char.metadata.json @@ -0,0 +1,36 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/char.test b/parser/testdata/summary_truncate/postgres_regress/char.test new file mode 100644 index 0000000..b5eb8d8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/char.test @@ -0,0 +1,276 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CHAR +|-- + +-- Per SQL standard, CHAR means character(1), that is a varlena type +-- with a constraint restricting it to one character (not byte) + +SELECT char 'c' = char 'c' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT char 'c' = char 'c' AS \"true\"" +== 002 +-- truncate_limit: 100 +|-- +-- Build a table for testing +-- (This temporarily hides the table created in test_setup.sql) +|-- + +CREATE TEMP TABLE CHAR_TBL(f1 char) +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE char_tbl (f1 char(1))" +== 003 +-- truncate_limit: 100 +INSERT INTO CHAR_TBL (f1) VALUES ('a') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('a')" +== 004 +-- truncate_limit: 100 +INSERT INTO CHAR_TBL (f1) VALUES ('A') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('A')" +== 005 +-- truncate_limit: 100 +-- any of the following three input formats are acceptable +INSERT INTO CHAR_TBL (f1) VALUES ('1') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('1')" +== 006 +-- truncate_limit: 100 +INSERT INTO CHAR_TBL (f1) VALUES (2) +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES (2)" +== 007 +-- truncate_limit: 100 +INSERT INTO CHAR_TBL (f1) VALUES ('3') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('3')" +== 008 +-- truncate_limit: 100 +-- zero-length char +INSERT INTO CHAR_TBL (f1) VALUES ('') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('')" +== 009 +-- truncate_limit: 100 +-- try char's of greater than 1 length +INSERT INTO CHAR_TBL (f1) VALUES ('cd') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('cd')" +== 010 +-- truncate_limit: 100 +INSERT INTO CHAR_TBL (f1) VALUES ('c ') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('c ')" +== 011 +-- truncate_limit: 100 +SELECT * FROM CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM char_tbl" +== 012 +-- truncate_limit: 100 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 <> 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM char_tbl c WHERE c.f1 <> 'a'" +== 013 +-- truncate_limit: 100 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 = 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM char_tbl c WHERE c.f1 = 'a'" +== 014 +-- truncate_limit: 100 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 < 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM char_tbl c WHERE c.f1 < 'a'" +== 015 +-- truncate_limit: 100 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 <= 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM char_tbl c WHERE c.f1 <= 'a'" +== 016 +-- truncate_limit: 100 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 > 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM char_tbl c WHERE c.f1 > 'a'" +== 017 +-- truncate_limit: 100 +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 >= 'a' +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +ALIAS: "c"="char_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM char_tbl c WHERE c.f1 >= 'a'" +== 018 +-- truncate_limit: 100 +DROP TABLE CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE char_tbl" +== 019 +-- truncate_limit: 100 +|-- +-- Now test longer arrays of char +|-- +-- This char_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. +|-- + +INSERT INTO CHAR_TBL (f1) VALUES ('abcde') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('abcde')" +== 020 +-- truncate_limit: 100 +SELECT * FROM CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM char_tbl" +== 021 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('abcd ', 'char(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('abcd ', 'char(4)')" +== 022 +-- truncate_limit: 100 +SELECT pg_input_is_valid('abcde', 'char(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('abcde', 'char(4)')" +== 023 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('abcde', 'char(4)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('abcde', 'char(4)')" +== 024 +-- truncate_limit: 100 +|-- +-- Also test "char", which is an ad-hoc one-byte type. It can only +-- really store ASCII characters, but we allow high-bit-set characters +-- to be accessed via bytea-like escapes. +|-- + +SELECT 'a'::"char" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a'::\"char\"" +== 025 +-- truncate_limit: 100 +SELECT '\101'::"char" +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\101'::\"char\"" +== 026 +-- truncate_limit: 100 +SELECT '\377'::"char" +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\377'::\"char\"" +== 027 +-- truncate_limit: 100 +SELECT 'a'::"char"::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a'::\"char\"::text" +== 028 +-- truncate_limit: 100 +SELECT '\377'::"char"::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\377'::\"char\"::text" +== 029 +-- truncate_limit: 100 +SELECT '\000'::"char"::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\000'::\"char\"::text" +== 030 +-- truncate_limit: 100 +SELECT 'a'::text::"char" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a'::text::\"char\"" +== 031 +-- truncate_limit: 100 +SELECT '\377'::text::"char" +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\377'::text::\"char\"" +== 032 +-- truncate_limit: 100 +SELECT ''::text::"char" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::text::\"char\"" diff --git a/parser/testdata/summary_truncate/postgres_regress/circle.metadata.json b/parser/testdata/summary_truncate/postgres_regress/circle.metadata.json new file mode 100644 index 0000000..edb706f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/circle.metadata.json @@ -0,0 +1,26 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/circle.test b/parser/testdata/summary_truncate/postgres_regress/circle.test new file mode 100644 index 0000000..feb9c63 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/circle.test @@ -0,0 +1,202 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CIRCLE +|-- + +-- Back off displayed precision a little bit to reduce platform-to-platform +-- variation in results. +SET extra_float_digits = -1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO -1" +== 002 +-- truncate_limit: 100 +CREATE TABLE CIRCLE_TBL (f1 circle) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE circle_tbl (f1 circle)" +== 003 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('<(5,1),3>')" +== 004 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES ('((1,2),100)') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('((1,2),100)')" +== 005 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES (' 1 , 3 , 5 ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES (' 1 , 3 , 5 ')" +== 006 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES (' ( ( 1 , 2 ) , 3 ) ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES (' ( ( 1 , 2 ) , 3 ) ')" +== 007 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES (' ( 100 , 200 ) , 10 ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES (' ( 100 , 200 ) , 10 ')" +== 008 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES (' < ( 100 , 1 ) , 115 > ') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES (' < ( 100 , 1 ) , 115 > ')" +== 009 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),0>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('<(3,5),0>')" +== 010 +-- truncate_limit: 100 +-- Zero radius + +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),NaN>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('<(3,5),NaN>')" +== 011 +-- truncate_limit: 100 +-- NaN radius + +-- bad values + +INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('<(-100,0),-100>')" +== 012 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('<(100,200),10')" +== 013 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10> x') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('<(100,200),10> x')" +== 014 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('1abc,3,5')" +== 015 +-- truncate_limit: 100 +INSERT INTO CIRCLE_TBL VALUES ('(3,(1,2),3)') +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circle_tbl VALUES ('(3,(1,2),3)')" +== 016 +-- truncate_limit: 100 +SELECT * FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM circle_tbl" +== 017 +-- truncate_limit: 100 +SELECT center(f1) AS center + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="center" function="center" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT center(f1) AS center FROM circle_tbl" +== 018 +-- truncate_limit: 100 +SELECT radius(f1) AS radius + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT radius(f1) AS radius FROM circle_tbl" +== 019 +-- truncate_limit: 100 +SELECT diameter(f1) AS diameter + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="diameter" function="diameter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT diameter(f1) AS diameter FROM circle_tbl" +== 020 +-- truncate_limit: 100 +SELECT f1 FROM CIRCLE_TBL WHERE radius(f1) < 5 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="radius" function="radius" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM circle_tbl WHERE radius(f1) < 5" +== 021 +-- truncate_limit: 100 +SELECT f1 FROM CIRCLE_TBL WHERE diameter(f1) >= 10 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="diameter" function="diameter" schema="" ctx=Call +FUNCTION: name="diameter" function="diameter" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM circle_tbl WHERE diameter(f1) >= 10" +== 022 +-- truncate_limit: 100 +SELECT c1.f1 AS one, c2.f1 AS two, (c1.f1 <-> c2.f1) AS distance + FROM CIRCLE_TBL c1, CIRCLE_TBL c2 + WHERE (c1.f1 < c2.f1) AND ((c1.f1 <-> c2.f1) > 0) + ORDER BY distance, area(c1.f1), area(c2.f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FUNCTION: name="area" function="area" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM circle_tbl c1, circle_tbl c2 WHERE ... ORDER BY distance, area(c1.f1), area(c2.f1)" diff --git a/parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json b/parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json new file mode 100644 index 0000000..479ae3b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json @@ -0,0 +1,208 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/cluster.test b/parser/testdata/summary_truncate/postgres_regress/cluster.test new file mode 100644 index 0000000..7037c7a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/cluster.test @@ -0,0 +1,1644 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CLUSTER +|-- + +CREATE TABLE clstr_tst_s (rf_a SERIAL PRIMARY KEY, + b INT) +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstr_tst_s (rf_a serial PRIMARY KEY, b int)" +== 002 +-- truncate_limit: 100 +CREATE TABLE clstr_tst (a SERIAL PRIMARY KEY, + b INT, + c TEXT, + d TEXT, + CONSTRAINT clstr_tst_con FOREIGN KEY (b) REFERENCES clstr_tst_s) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstr_tst (a serial PRIMARY KEY, b int, c text, d text, CONSTRAINT clstr_tst_con FOR..." +== 003 +-- truncate_limit: 100 +CREATE INDEX clstr_tst_b ON clstr_tst (b) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstr_tst_b ON clstr_tst USING btree (b)" +== 004 +-- truncate_limit: 100 +CREATE INDEX clstr_tst_c ON clstr_tst (c) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstr_tst_c ON clstr_tst USING btree (c)" +== 005 +-- truncate_limit: 100 +CREATE INDEX clstr_tst_c_b ON clstr_tst (c,b) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstr_tst_c_b ON clstr_tst USING btree (c, b)" +== 006 +-- truncate_limit: 100 +CREATE INDEX clstr_tst_b_c ON clstr_tst (b,c) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstr_tst_b_c ON clstr_tst USING btree (b, c)" +== 007 +-- truncate_limit: 100 +INSERT INTO clstr_tst_s (b) VALUES (0) +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst_s (b) VALUES (0)" +== 008 +-- truncate_limit: 100 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s" +== 009 +-- truncate_limit: 100 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s" +== 010 +-- truncate_limit: 100 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s" +== 011 +-- truncate_limit: 100 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s" +== 012 +-- truncate_limit: 100 +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s +-- +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=DML +TABLE: name="clstr_tst_s" schema="" table="clstr_tst_s" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s" +== 013 +-- truncate_limit: 100 +CREATE TABLE clstr_tst_inh () INHERITS (clstr_tst) +-- +TABLE: name="clstr_tst_inh" schema="" table="clstr_tst_inh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstr_tst_inh () INHERITS (clstr_tst)" +== 014 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (11, 'once') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (11, 'once')" +== 015 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (10, 'diez') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (10, 'diez')" +== 016 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (31, 'treinta y uno') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (31, 'treinta y uno')" +== 017 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (22, 'veintidos') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (22, 'veintidos')" +== 018 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (3, 'tres') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (3, 'tres')" +== 019 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (20, 'veinte') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (20, 'veinte')" +== 020 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (23, 'veintitres') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (23, 'veintitres')" +== 021 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (21, 'veintiuno') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (21, 'veintiuno')" +== 022 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (4, 'cuatro') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (4, 'cuatro')" +== 023 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (14, 'catorce') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (14, 'catorce')" +== 024 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (2, 'dos') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (2, 'dos')" +== 025 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (18, 'dieciocho') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (18, 'dieciocho')" +== 026 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (27, 'veintisiete') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (27, 'veintisiete')" +== 027 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (25, 'veinticinco') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (25, 'veinticinco')" +== 028 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (13, 'trece') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (13, 'trece')" +== 029 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (28, 'veintiocho') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (28, 'veintiocho')" +== 030 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (32, 'treinta y dos') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (32, 'treinta y dos')" +== 031 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (5, 'cinco') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (5, 'cinco')" +== 032 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (29, 'veintinueve') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (29, 'veintinueve')" +== 033 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (1, 'uno') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (1, 'uno')" +== 034 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (24, 'veinticuatro') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (24, 'veinticuatro')" +== 035 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (30, 'treinta') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (30, 'treinta')" +== 036 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (12, 'doce') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (12, 'doce')" +== 037 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (17, 'diecisiete') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (17, 'diecisiete')" +== 038 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (9, 'nueve') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (9, 'nueve')" +== 039 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (19, 'diecinueve') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (19, 'diecinueve')" +== 040 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (26, 'veintiseis') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (26, 'veintiseis')" +== 041 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (15, 'quince') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (15, 'quince')" +== 042 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (7, 'siete') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (7, 'siete')" +== 043 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (16, 'dieciseis') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (16, 'dieciseis')" +== 044 +-- truncate_limit: 100 +INSERT INTO clstr_tst (b, c) VALUES (8, 'ocho') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (8, 'ocho')" +== 045 +-- truncate_limit: 100 +-- This entry is needed to test that TOASTED values are copied correctly. +INSERT INTO clstr_tst (b, c, d) VALUES (6, 'seis', repeat('xyzzy', 100000)) +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c, d) VALUES (6, 'seis', repeat('xyzzy', 100000))" +== 046 +-- truncate_limit: 100 +CLUSTER clstr_tst_c ON clstr_tst +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_tst USING clstr_tst_c" +== 047 +-- truncate_limit: 100 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c, SUBSTRING(d FROM 1 FOR 30::int), length(d) FROM clstr_tst" +== 048 +-- truncate_limit: 100 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY a +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c, SUBSTRING(d FROM 1 FOR 30::int), length(d) FROM clstr_tst ORDER BY a" +== 049 +-- truncate_limit: 100 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY b +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c, SUBSTRING(d FROM 1 FOR 30::int), length(d) FROM clstr_tst ORDER BY b" +== 050 +-- truncate_limit: 100 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY c +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c, SUBSTRING(d FROM 1 FOR 30::int), length(d) FROM clstr_tst ORDER BY c" +== 051 +-- truncate_limit: 100 +-- Verify that inheritance link still works +INSERT INTO clstr_tst_inh VALUES (0, 100, 'in child table') +-- +TABLE: name="clstr_tst_inh" schema="" table="clstr_tst_inh" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst_inh VALUES (0, 100, 'in child table')" +== 052 +-- truncate_limit: 100 +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=Select +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c, SUBSTRING(d FROM 1 FOR 30::int), length(d) FROM clstr_tst" +== 053 +-- truncate_limit: 100 +-- Verify that foreign key link still works +INSERT INTO clstr_tst (b, c) VALUES (1111, 'this should fail') +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_tst (b, c) VALUES (1111, 'this should fail')" +== 054 +-- truncate_limit: 100 +SELECT conname FROM pg_constraint WHERE conrelid = 'clstr_tst'::regclass +ORDER BY 1 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT conname FROM pg_constraint WHERE conrelid = 'clstr_tst'::regclass ORDER BY 1" +== 055 +-- truncate_limit: 100 +SELECT relname, relkind, + EXISTS(SELECT 1 FROM pg_class WHERE oid = c.reltoastrelid) AS hastoast +FROM pg_class c WHERE relname LIKE 'clstr_tst%' ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="c" column="reltoastrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c WHERE relname LIKE 'clstr_tst%' ORDER BY relname" +== 056 +-- truncate_limit: 100 +-- Verify that indisclustered is correctly set +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pg_class_2"="pg_class" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="pg_class_2" column="oid" +FILTER: schema="" table="pg_class_2" column="relname" +FILTER: schema="" table="" column="indisclustered" +STMT: SelectStmt +TRUNCATED: "SELECT pg_class.relname FROM pg_index, pg_class, pg_class pg_class_2 WHERE ..." +== 057 +-- truncate_limit: 100 +-- Try changing indisclustered +ALTER TABLE clstr_tst CLUSTER ON clstr_tst_b_c +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE clstr_tst CLUSTER ON clstr_tst_b_c" +== 058 +-- truncate_limit: 100 +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pg_class_2"="pg_class" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="pg_class_2" column="oid" +FILTER: schema="" table="pg_class_2" column="relname" +FILTER: schema="" table="" column="indisclustered" +STMT: SelectStmt +TRUNCATED: "SELECT pg_class.relname FROM pg_index, pg_class, pg_class pg_class_2 WHERE ..." +== 059 +-- truncate_limit: 100 +-- Try turning off all clustering +ALTER TABLE clstr_tst SET WITHOUT CLUSTER +-- +TABLE: name="clstr_tst" schema="" table="clstr_tst" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE clstr_tst SET WITHOUT CLUSTER" +== 060 +-- truncate_limit: 100 +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pg_class_2"="pg_class" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="pg_class_2" column="oid" +FILTER: schema="" table="pg_class_2" column="relname" +FILTER: schema="" table="" column="indisclustered" +STMT: SelectStmt +TRUNCATED: "SELECT pg_class.relname FROM pg_index, pg_class, pg_class pg_class_2 WHERE ..." +== 061 +-- truncate_limit: 100 +-- Verify that toast tables are clusterable +CLUSTER pg_toast.pg_toast_826 USING pg_toast_826_index +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER pg_toast.pg_toast_826 USING pg_toast_826_index" +== 062 +-- truncate_limit: 100 +-- Verify that clustering all tables does in fact cluster the right ones +CREATE USER regress_clstr_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_clstr_user" +== 063 +-- truncate_limit: 100 +CREATE TABLE clstr_1 (a INT PRIMARY KEY) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstr_1 (a int PRIMARY KEY)" +== 064 +-- truncate_limit: 100 +CREATE TABLE clstr_2 (a INT PRIMARY KEY) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstr_2 (a int PRIMARY KEY)" +== 065 +-- truncate_limit: 100 +CREATE TABLE clstr_3 (a INT PRIMARY KEY) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstr_3 (a int PRIMARY KEY)" +== 066 +-- truncate_limit: 100 +ALTER TABLE clstr_1 OWNER TO regress_clstr_user +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE clstr_1 OWNER TO regress_clstr_user" +== 067 +-- truncate_limit: 100 +ALTER TABLE clstr_3 OWNER TO regress_clstr_user +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE clstr_3 OWNER TO regress_clstr_user" +== 068 +-- truncate_limit: 100 +GRANT SELECT ON clstr_2 TO regress_clstr_user +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON clstr_2 TO regress_clstr_user" +== 069 +-- truncate_limit: 100 +INSERT INTO clstr_1 VALUES (2) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_1 VALUES (2)" +== 070 +-- truncate_limit: 100 +INSERT INTO clstr_1 VALUES (1) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_1 VALUES (1)" +== 071 +-- truncate_limit: 100 +INSERT INTO clstr_2 VALUES (2) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_2 VALUES (2)" +== 072 +-- truncate_limit: 100 +INSERT INTO clstr_2 VALUES (1) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_2 VALUES (1)" +== 073 +-- truncate_limit: 100 +INSERT INTO clstr_3 VALUES (2) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_3 VALUES (2)" +== 074 +-- truncate_limit: 100 +INSERT INTO clstr_3 VALUES (1) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_3 VALUES (1)" +== 075 +-- truncate_limit: 100 +-- "CLUSTER " on a table that hasn't been clustered +CLUSTER clstr_2 +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_2" +== 076 +-- truncate_limit: 100 +CLUSTER clstr_1_pkey ON clstr_1 +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_1 USING clstr_1_pkey" +== 077 +-- truncate_limit: 100 +CLUSTER clstr_2 USING clstr_2_pkey +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_2 USING clstr_2_pkey" +== 078 +-- truncate_limit: 100 +SELECT * FROM clstr_1 UNION ALL + SELECT * FROM clstr_2 UNION ALL + SELECT * FROM clstr_3 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=Select +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=Select +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM clstr_1 UNION ALL SELECT * FROM clstr_2) UNION ALL SELECT * FROM clstr_3" +== 079 +-- truncate_limit: 100 +-- revert to the original state +DELETE FROM clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM clstr_1" +== 080 +-- truncate_limit: 100 +DELETE FROM clstr_2 +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM clstr_2" +== 081 +-- truncate_limit: 100 +DELETE FROM clstr_3 +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM clstr_3" +== 082 +-- truncate_limit: 100 +INSERT INTO clstr_1 VALUES (2) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_1 VALUES (2)" +== 083 +-- truncate_limit: 100 +INSERT INTO clstr_1 VALUES (1) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_1 VALUES (1)" +== 084 +-- truncate_limit: 100 +INSERT INTO clstr_2 VALUES (2) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_2 VALUES (2)" +== 085 +-- truncate_limit: 100 +INSERT INTO clstr_2 VALUES (1) +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_2 VALUES (1)" +== 086 +-- truncate_limit: 100 +INSERT INTO clstr_3 VALUES (2) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_3 VALUES (2)" +== 087 +-- truncate_limit: 100 +INSERT INTO clstr_3 VALUES (1) +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_3 VALUES (1)" +== 088 +-- truncate_limit: 100 +-- this user can only cluster clstr_1 and clstr_3, but the latter +-- has not been clustered +SET SESSION AUTHORIZATION regress_clstr_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_clstr_user" +== 089 +-- truncate_limit: 100 +SET client_min_messages = ERROR +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO error" +== 090 +-- truncate_limit: 100 +-- order of "skipping" warnings may vary +CLUSTER +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER" +== 091 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 092 +-- truncate_limit: 100 +SELECT * FROM clstr_1 UNION ALL + SELECT * FROM clstr_2 UNION ALL + SELECT * FROM clstr_3 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=Select +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=Select +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM clstr_1 UNION ALL SELECT * FROM clstr_2) UNION ALL SELECT * FROM clstr_3" +== 093 +-- truncate_limit: 100 +-- cluster a single table using the indisclustered bit previously set +DELETE FROM clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM clstr_1" +== 094 +-- truncate_limit: 100 +INSERT INTO clstr_1 VALUES (2) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_1 VALUES (2)" +== 095 +-- truncate_limit: 100 +INSERT INTO clstr_1 VALUES (1) +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_1 VALUES (1)" +== 096 +-- truncate_limit: 100 +CLUSTER clstr_1 +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_1" +== 097 +-- truncate_limit: 100 +SELECT * FROM clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_1" +== 098 +-- truncate_limit: 100 +-- Test MVCC-safety of cluster. There isn't much we can do to verify the +-- results with a single backend... + +CREATE TABLE clustertest (key int PRIMARY KEY) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clustertest (key int PRIMARY KEY)" +== 099 +-- truncate_limit: 100 +INSERT INTO clustertest VALUES (10) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clustertest VALUES (10)" +== 100 +-- truncate_limit: 100 +INSERT INTO clustertest VALUES (20) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clustertest VALUES (20)" +== 101 +-- truncate_limit: 100 +INSERT INTO clustertest VALUES (30) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clustertest VALUES (30)" +== 102 +-- truncate_limit: 100 +INSERT INTO clustertest VALUES (40) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clustertest VALUES (40)" +== 103 +-- truncate_limit: 100 +INSERT INTO clustertest VALUES (50) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clustertest VALUES (50)" +== 104 +-- truncate_limit: 100 +-- Use a transaction so that updates are not committed when CLUSTER sees 'em +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 105 +-- truncate_limit: 100 +-- Test update where the old row version is found first in the scan +UPDATE clustertest SET key = 100 WHERE key = 10 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE clustertest SET key = 100 WHERE key = 10" +== 106 +-- truncate_limit: 100 +-- Test update where the new row version is found first in the scan +UPDATE clustertest SET key = 35 WHERE key = 40 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE clustertest SET key = 35 WHERE key = 40" +== 107 +-- truncate_limit: 100 +-- Test longer update chain +UPDATE clustertest SET key = 60 WHERE key = 50 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE clustertest SET key = 60 WHERE key = 50" +== 108 +-- truncate_limit: 100 +UPDATE clustertest SET key = 70 WHERE key = 60 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE clustertest SET key = 70 WHERE key = 60" +== 109 +-- truncate_limit: 100 +UPDATE clustertest SET key = 80 WHERE key = 70 +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE clustertest SET key = 80 WHERE key = 70" +== 110 +-- truncate_limit: 100 +SELECT * FROM clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clustertest" +== 111 +-- truncate_limit: 100 +CLUSTER clustertest_pkey ON clustertest +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clustertest USING clustertest_pkey" +== 112 +-- truncate_limit: 100 +SELECT * FROM clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clustertest" +== 113 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 114 +-- truncate_limit: 100 +SELECT * FROM clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clustertest" +== 115 +-- truncate_limit: 100 +-- check that temp tables can be clustered +create temp table clstr_temp (col1 int primary key, col2 text) +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE clstr_temp (col1 int PRIMARY KEY, col2 text)" +== 116 +-- truncate_limit: 100 +insert into clstr_temp values (2, 'two'), (1, 'one') +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_temp VALUES (2, 'two'), (1, 'one')" +== 117 +-- truncate_limit: 100 +cluster clstr_temp using clstr_temp_pkey +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_temp USING clstr_temp_pkey" +== 118 +-- truncate_limit: 100 +select * from clstr_temp +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_temp" +== 119 +-- truncate_limit: 100 +drop table clstr_temp +-- +TABLE: name="clstr_temp" schema="" table="clstr_temp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clstr_temp" +== 120 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 121 +-- truncate_limit: 100 +-- check clustering an empty table +DROP TABLE clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clustertest" +== 122 +-- truncate_limit: 100 +CREATE TABLE clustertest (f1 int PRIMARY KEY) +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clustertest (f1 int PRIMARY KEY)" +== 123 +-- truncate_limit: 100 +CLUSTER clustertest USING clustertest_pkey +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clustertest USING clustertest_pkey" +== 124 +-- truncate_limit: 100 +CLUSTER clustertest +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clustertest" +== 125 +-- truncate_limit: 100 +-- Check that partitioned tables can be clustered +CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a)" +== 126 +-- truncate_limit: 100 +CREATE TABLE clstrpart1 PARTITION OF clstrpart FOR VALUES FROM (1) TO (10) PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart1" schema="" table="clstrpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstrpart1 PARTITION OF clstrpart FOR VALUES FROM (1) TO (10) PARTITION BY RANGE (a)" +== 127 +-- truncate_limit: 100 +CREATE TABLE clstrpart11 PARTITION OF clstrpart1 FOR VALUES FROM (1) TO (5) +-- +TABLE: name="clstrpart11" schema="" table="clstrpart11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstrpart11 PARTITION OF clstrpart1 FOR VALUES FROM (1) TO (5)" +== 128 +-- truncate_limit: 100 +CREATE TABLE clstrpart12 PARTITION OF clstrpart1 FOR VALUES FROM (5) TO (10) PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart12" schema="" table="clstrpart12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstrpart12 PARTITION OF clstrpart1 FOR VALUES FROM (5) TO (10) PARTITION BY RANGE (a)" +== 129 +-- truncate_limit: 100 +CREATE TABLE clstrpart2 PARTITION OF clstrpart FOR VALUES FROM (10) TO (20) +-- +TABLE: name="clstrpart2" schema="" table="clstrpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstrpart2 PARTITION OF clstrpart FOR VALUES FROM (10) TO (20)" +== 130 +-- truncate_limit: 100 +CREATE TABLE clstrpart3 PARTITION OF clstrpart DEFAULT PARTITION BY RANGE (a) +-- +TABLE: name="clstrpart3" schema="" table="clstrpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstrpart3 PARTITION OF clstrpart DEFAULT PARTITION BY RANGE (a)" +== 131 +-- truncate_limit: 100 +CREATE TABLE clstrpart33 PARTITION OF clstrpart3 DEFAULT +-- +TABLE: name="clstrpart33" schema="" table="clstrpart33" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstrpart33 PARTITION OF clstrpart3 DEFAULT" +== 132 +-- truncate_limit: 100 +CREATE INDEX clstrpart_only_idx ON ONLY clstrpart (a) +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstrpart_only_idx ON ONLY clstrpart USING btree (a)" +== 133 +-- truncate_limit: 100 +CLUSTER clstrpart USING clstrpart_only_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstrpart USING clstrpart_only_idx" +== 134 +-- truncate_limit: 100 +-- fails +DROP INDEX clstrpart_only_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX clstrpart_only_idx" +== 135 +-- truncate_limit: 100 +CREATE INDEX clstrpart_idx ON clstrpart (a) +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstrpart_idx ON clstrpart USING btree (a)" +== 136 +-- truncate_limit: 100 +-- Check that clustering sets new relfilenodes: +CREATE TEMP TABLE old_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid +-- +TABLE: name="old_cluster_info" schema="" table="old_cluster_info" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE old_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_pa..." +== 137 +-- truncate_limit: 100 +CLUSTER clstrpart USING clstrpart_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstrpart USING clstrpart_idx" +== 138 +-- truncate_limit: 100 +CREATE TEMP TABLE new_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid +-- +TABLE: name="new_cluster_info" schema="" table="new_cluster_info" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE new_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_pa..." +== 139 +-- truncate_limit: 100 +SELECT relname, old.level, old.relkind, old.relfilenode = new.relfilenode FROM old_cluster_info AS old JOIN new_cluster_info AS new USING (relname) ORDER BY relname COLLATE "C" +-- +TABLE: name="old_cluster_info" schema="" table="old_cluster_info" ctx=Select +TABLE: name="new_cluster_info" schema="" table="new_cluster_info" ctx=Select +ALIAS: "new"="new_cluster_info" +ALIAS: "old"="old_cluster_info" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM old_cluster_info old JOIN new_cluster_info new USING (relname) ORDER BY relname C..." +== 140 +-- truncate_limit: 100 +-- Partitioned indexes aren't and can't be marked un/clustered: +CLUSTER clstrpart +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstrpart" +== 141 +-- truncate_limit: 100 +ALTER TABLE clstrpart SET WITHOUT CLUSTER +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE clstrpart SET WITHOUT CLUSTER" +== 142 +-- truncate_limit: 100 +ALTER TABLE clstrpart CLUSTER ON clstrpart_idx +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE clstrpart CLUSTER ON clstrpart_idx" +== 143 +-- truncate_limit: 100 +DROP TABLE clstrpart +-- +TABLE: name="clstrpart" schema="" table="clstrpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clstrpart" +== 144 +-- truncate_limit: 100 +-- Ownership of partitions is checked +CREATE TABLE ptnowner(i int unique) PARTITION BY LIST (i) +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptnowner (i int UNIQUE) PARTITION BY LIST (i)" +== 145 +-- truncate_limit: 100 +CREATE INDEX ptnowner_i_idx ON ptnowner(i) +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptnowner_i_idx ON ptnowner USING btree (i)" +== 146 +-- truncate_limit: 100 +CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1) +-- +TABLE: name="ptnowner1" schema="" table="ptnowner1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1)" +== 147 +-- truncate_limit: 100 +CREATE ROLE regress_ptnowner +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_ptnowner" +== 148 +-- truncate_limit: 100 +CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2) +-- +TABLE: name="ptnowner2" schema="" table="ptnowner2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2)" +== 149 +-- truncate_limit: 100 +ALTER TABLE ptnowner1 OWNER TO regress_ptnowner +-- +TABLE: name="ptnowner1" schema="" table="ptnowner1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ptnowner1 OWNER TO regress_ptnowner" +== 150 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_ptnowner +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_ptnowner" +== 151 +-- truncate_limit: 100 +CLUSTER ptnowner USING ptnowner_i_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER ptnowner USING ptnowner_i_idx" +== 152 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 153 +-- truncate_limit: 100 +ALTER TABLE ptnowner OWNER TO regress_ptnowner +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ptnowner OWNER TO regress_ptnowner" +== 154 +-- truncate_limit: 100 +CREATE TEMP TABLE ptnowner_oldnodes AS + SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree + JOIN pg_class AS c ON c.oid=tree.relid +-- +TABLE: name="ptnowner_oldnodes" schema="" table="ptnowner_oldnodes" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE ptnowner_oldnodes AS SELECT oid, relname, relfilenode FROM pg_partition_tr..." +== 155 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_ptnowner +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_ptnowner" +== 156 +-- truncate_limit: 100 +CLUSTER ptnowner USING ptnowner_i_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER ptnowner USING ptnowner_i_idx" +== 157 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 158 +-- truncate_limit: 100 +SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a + JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="ptnowner_oldnodes" schema="" table="ptnowner_oldnodes" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="ptnowner_oldnodes" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class a JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE \"C\"" +== 159 +-- truncate_limit: 100 +DROP TABLE ptnowner +-- +TABLE: name="ptnowner" schema="" table="ptnowner" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ptnowner" +== 160 +-- truncate_limit: 100 +DROP ROLE regress_ptnowner +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_ptnowner" +== 161 +-- truncate_limit: 100 +-- Test CLUSTER with external tuplesorting + +create table clstr_4 as select * from tenk1 +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE clstr_4 AS SELECT * FROM tenk1" +== 162 +-- truncate_limit: 100 +create index cluster_sort on clstr_4 (hundred, thousand, tenthous) +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX cluster_sort ON clstr_4 USING btree (hundred, thousand, tenthous)" +== 163 +-- truncate_limit: 100 +-- ensure we don't use the index in CLUSTER nor the checking SELECTs +set enable_indexscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 164 +-- truncate_limit: 100 +-- Use external sort: +set maintenance_work_mem = '1MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET maintenance_work_mem TO \"1MB\"" +== 165 +-- truncate_limit: 100 +cluster clstr_4 using cluster_sort +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_4 USING cluster_sort" +== 166 +-- truncate_limit: 100 +select * from +(select hundred, lag(hundred) over () as lhundred, + thousand, lag(thousand) over () as lthousand, + tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss +where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous) +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="lhundred" +FILTER: schema="" table="" column="lthousand" +FILTER: schema="" table="" column="ltenthous" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM clstr_4) ss WHERE ..." +== 167 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 168 +-- truncate_limit: 100 +reset maintenance_work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET maintenance_work_mem" +== 169 +-- truncate_limit: 100 +-- test CLUSTER on expression index +CREATE TABLE clstr_expression(id serial primary key, a int, b text COLLATE "C") +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clstr_expression (id serial PRIMARY KEY, a int, b text COLLATE \"C\")" +== 170 +-- truncate_limit: 100 +INSERT INTO clstr_expression(a, b) SELECT g.i % 42, 'prefix'||g.i FROM generate_series(1, 133) g(i) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clstr_expression (a, b) SELECT ... FROM generate_series(1, 133) g(i)" +== 171 +-- truncate_limit: 100 +CREATE INDEX clstr_expression_minus_a ON clstr_expression ((-a), b) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstr_expression_minus_a ON clstr_expression USING btree ((- a), b)" +== 172 +-- truncate_limit: 100 +CREATE INDEX clstr_expression_upper_b ON clstr_expression ((upper(b))) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clstr_expression_upper_b ON clstr_expression USING btree (upper(b))" +== 173 +-- truncate_limit: 100 +-- verify indexes work before cluster +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 174 +-- truncate_limit: 100 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO FALSE" +== 175 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'" +== 176 +-- truncate_limit: 100 +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'" +== 177 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE (- a) = -3 ORDER BY - a, b" +== 178 +-- truncate_limit: 100 +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_expression WHERE (- a) = -3 ORDER BY - a, b" +== 179 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 180 +-- truncate_limit: 100 +-- and after clustering on clstr_expression_minus_a +CLUSTER clstr_expression USING clstr_expression_minus_a +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_expression USING clstr_expression_minus_a" +== 181 +-- truncate_limit: 100 +WITH rows AS + (SELECT ctid, lag(a) OVER (ORDER BY ctid) AS la, a FROM clstr_expression) +SELECT * FROM rows WHERE la < a +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +CTE: "rows" +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="la" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "WITH rows AS (SELECT ... FROM clstr_expression) SELECT * FROM rows WHERE la < a" +== 182 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 183 +-- truncate_limit: 100 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO FALSE" +== 184 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'" +== 185 +-- truncate_limit: 100 +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'" +== 186 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE (- a) = -3 ORDER BY - a, b" +== 187 +-- truncate_limit: 100 +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_expression WHERE (- a) = -3 ORDER BY - a, b" +== 188 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 189 +-- truncate_limit: 100 +-- and after clustering on clstr_expression_upper_b +CLUSTER clstr_expression USING clstr_expression_upper_b +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER clstr_expression USING clstr_expression_upper_b" +== 190 +-- truncate_limit: 100 +WITH rows AS + (SELECT ctid, lag(b) OVER (ORDER BY ctid) AS lb, b FROM clstr_expression) +SELECT * FROM rows WHERE upper(lb) > upper(b) +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +CTE: "rows" +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="lb" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "WITH rows AS (SELECT ... FROM clstr_expression) SELECT * FROM rows WHERE upper(lb) > upper(b)" +== 191 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 192 +-- truncate_limit: 100 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO FALSE" +== 193 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'" +== 194 +-- truncate_limit: 100 +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3' +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'" +== 195 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE (- a) = -3 ORDER BY - a, b" +== 196 +-- truncate_limit: 100 +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM clstr_expression WHERE (- a) = -3 ORDER BY - a, b" +== 197 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 198 +-- truncate_limit: 100 +-- clean up +DROP TABLE clustertest +-- +TABLE: name="clustertest" schema="" table="clustertest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clustertest" +== 199 +-- truncate_limit: 100 +DROP TABLE clstr_1 +-- +TABLE: name="clstr_1" schema="" table="clstr_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clstr_1" +== 200 +-- truncate_limit: 100 +DROP TABLE clstr_2 +-- +TABLE: name="clstr_2" schema="" table="clstr_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clstr_2" +== 201 +-- truncate_limit: 100 +DROP TABLE clstr_3 +-- +TABLE: name="clstr_3" schema="" table="clstr_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clstr_3" +== 202 +-- truncate_limit: 100 +DROP TABLE clstr_4 +-- +TABLE: name="clstr_4" schema="" table="clstr_4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clstr_4" +== 203 +-- truncate_limit: 100 +DROP TABLE clstr_expression +-- +TABLE: name="clstr_expression" schema="" table="clstr_expression" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE clstr_expression" +== 204 +-- truncate_limit: 100 +DROP USER regress_clstr_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_clstr_user" diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json new file mode 100644 index 0000000..faccb98 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json @@ -0,0 +1,505 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.test b/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.test new file mode 100644 index 0000000..c85d0b2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.test @@ -0,0 +1,3980 @@ +== 001 +-- truncate_limit: 100 +/* + * This test is for ICU collations. + */ + +/* skip test if not UTF8 server encoding or no ICU collations installed */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collprovider = 'i' AND collname <> 'unicode') = 0 + AS skip_test +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="collprovider" +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT getdatabaseencoding() <> 'UTF8' OR (SELECT ... FROM pg_collation WHERE ...) = 0 AS skip_test" +== 002 +-- truncate_limit: 100 +SET client_encoding TO UTF8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_encoding TO utf8" +== 003 +-- truncate_limit: 100 +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA collate_tests" +== 004 +-- truncate_limit: 100 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO collate_tests" +== 005 +-- truncate_limit: 100 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en-x-icu" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test1 (a int, b text NOT NULL COLLATE \"en-x-icu\")" +== 006 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp-x-icu" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int, b text COLLATE \"ja_JP.eucjp-x-icu\")" +== 007 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo-x-icu" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int, b text COLLATE \"foo-x-icu\")" +== 008 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int COLLATE "en-x-icu", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int COLLATE \"en-x-icu\", b text)" +== 009 +-- truncate_limit: 100 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_like (LIKE collate_test1)" +== 010 +-- truncate_limit: 100 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv-x-icu" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test2 (a int, b text COLLATE \"sv-x-icu\")" +== 011 +-- truncate_limit: 100 +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +) +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test3 (a int, b text COLLATE \"C\")" +== 012 +-- truncate_limit: 100 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC')" +== 013 +-- truncate_limit: 100 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test2 SELECT * FROM collate_test1" +== 014 +-- truncate_limit: 100 +INSERT INTO collate_test3 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test3 SELECT * FROM collate_test1" +== 015 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b >= 'bbc'" +== 016 +-- truncate_limit: 100 +SELECT * FROM collate_test2 WHERE b >= 'bbc' +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 WHERE b >= 'bbc'" +== 017 +-- truncate_limit: 100 +SELECT * FROM collate_test3 WHERE b >= 'bbc' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 WHERE b >= 'bbc'" +== 018 +-- truncate_limit: 100 +SELECT * FROM collate_test3 WHERE b >= 'BBC' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 WHERE b >= 'BBC'" +== 019 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc'" +== 020 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE \"C\"" +== 021 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc' COLLATE \"C\"" +== 022 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en-x-icu" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc' COLLATE \"en-x-icu\"" +== 023 +-- truncate_limit: 100 +CREATE DOMAIN testdomain_sv AS text COLLATE "sv-x-icu" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_sv AS text COLLATE \"sv-x-icu\"" +== 024 +-- truncate_limit: 100 +CREATE DOMAIN testdomain_i AS int COLLATE "sv-x-icu" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_i AS int COLLATE \"sv-x-icu\"" +== 025 +-- truncate_limit: 100 +-- fails +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test4 (a int, b testdomain_sv)" +== 026 +-- truncate_limit: 100 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test4 SELECT * FROM collate_test1" +== 027 +-- truncate_limit: 100 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test4 ORDER BY b" +== 028 +-- truncate_limit: 100 +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en-x-icu" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test5 (a int, b testdomain_sv COLLATE \"en-x-icu\")" +== 029 +-- truncate_limit: 100 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test5 SELECT * FROM collate_test1" +== 030 +-- truncate_limit: 100 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test5 ORDER BY b" +== 031 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b" +== 032 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 ORDER BY b" +== 033 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test3 ORDER BY b" +== 034 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 035 +-- truncate_limit: 100 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 ORDER BY b" +== 036 +-- truncate_limit: 100 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 ORDER BY b" +== 037 +-- truncate_limit: 100 +SELECT * FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 ORDER BY b" +== 038 +-- truncate_limit: 100 +-- constant expression folding +SELECT 'bbc' COLLATE "en-x-icu" > 'äbc' COLLATE "en-x-icu" AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"en-x-icu\" > 'äbc' COLLATE \"en-x-icu\" AS \"true\"" +== 039 +-- truncate_limit: 100 +SELECT 'bbc' COLLATE "sv-x-icu" > 'äbc' COLLATE "sv-x-icu" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"sv-x-icu\" > 'äbc' COLLATE \"sv-x-icu\" AS \"false\"" +== 040 +-- truncate_limit: 100 +-- upper/lower + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "en-x-icu", + y text COLLATE "tr-x-icu" +) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test10 (a int, x text COLLATE \"en-x-icu\", y text COLLATE \"tr-x-icu\")" +== 041 +-- truncate_limit: 100 +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ') +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ')" +== 042 +-- truncate_limit: 100 +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10" +== 043 +-- truncate_limit: 100 +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x COLLATE \"C\"), lower(y COLLATE \"C\") FROM collate_test10" +== 044 +-- truncate_limit: 100 +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a" +== 045 +-- truncate_limit: 100 +-- LIKE/ILIKE + +SELECT * FROM collate_test1 WHERE b LIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE 'abc'" +== 046 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b LIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE 'abc%'" +== 047 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b LIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE '%bc%'" +== 048 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'abc'" +== 049 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'abc%'" +== 050 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE '%bc%'" +== 051 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "en-x-icu" ILIKE '%KI%' AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"en-x-icu\" ILIKE '%KI%' AS \"true\"" +== 052 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "tr-x-icu" ILIKE '%KI%' AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"tr-x-icu\" ILIKE '%KI%' AS \"false\"" +== 053 +-- truncate_limit: 100 +SELECT 'bıt' ILIKE 'BIT' COLLATE "en-x-icu" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ILIKE 'BIT' COLLATE \"en-x-icu\" AS \"false\"" +== 054 +-- truncate_limit: 100 +SELECT 'bıt' ILIKE 'BIT' COLLATE "tr-x-icu" AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ILIKE 'BIT' COLLATE \"tr-x-icu\" AS \"true\"" +== 055 +-- truncate_limit: 100 +-- The following actually exercises the selectivity estimation for ILIKE. +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ILIKE 'abc%'" +== 056 +-- truncate_limit: 100 +-- regular expressions + +SELECT * FROM collate_test1 WHERE b ~ '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ '^abc$'" +== 057 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~ '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ '^abc'" +== 058 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~ 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ 'bc'" +== 059 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* '^abc$'" +== 060 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* '^abc'" +== 061 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* 'bc'" +== 062 +-- truncate_limit: 100 +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en-x-icu" +) +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test6 (a int, b text COLLATE \"en-x-icu\")" +== 063 +-- truncate_limit: 100 +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, 'äbç'), (10, 'ÄBÇ') +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test6 VALUES (...)" +== 064 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test6" +== 065 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "en-x-icu" ~* 'KI' AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"en-x-icu\" ~* 'KI' AS \"true\"" +== 066 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "tr-x-icu" ~* 'KI' AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"tr-x-icu\" ~* 'KI' AS \"true\"" +== 067 +-- truncate_limit: 100 +-- true with ICU + +SELECT 'bıt' ~* 'BIT' COLLATE "en-x-icu" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ~* 'BIT' COLLATE \"en-x-icu\" AS \"false\"" +== 068 +-- truncate_limit: 100 +SELECT 'bıt' ~* 'BIT' COLLATE "tr-x-icu" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ~* 'BIT' COLLATE \"tr-x-icu\" AS \"false\"" +== 069 +-- truncate_limit: 100 +-- false with ICU + +-- The following actually exercises the selectivity estimation for ~*. +SELECT relname FROM pg_class WHERE relname ~* '^abc' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ~* '^abc'" +== 070 +-- truncate_limit: 100 +/* 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' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc'" +== 071 +-- truncate_limit: 100 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 072 +-- truncate_limit: 100 +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10 +-- +TABLE: name="collview3" schema="" table="collview3" ctx=DDL +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE \"C\") FROM collate_test10" +== 073 +-- truncate_limit: 100 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'collview%' ORDER BY 1" +== 074 +-- truncate_limit: 100 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test1 ORDER BY 2" +== 075 +-- truncate_limit: 100 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test2 ORDER BY 2" +== 076 +-- truncate_limit: 100 +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test3 ORDER BY 2" +== 077 +-- truncate_limit: 100 +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(COALESCE(x, 'foo')), lower(COALESCE(y, 'foo')) FROM collate_test10" +== 078 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test1 ORDER BY 3" +== 079 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test2 ORDER BY 3" +== 080 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test3 ORDER BY 3" +== 081 +-- truncate_limit: 100 +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, x, y, lower(GREATEST(x, 'foo')), lower(GREATEST(y, 'foo')) FROM collate_test10" +== 082 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test1 ORDER BY 2" +== 083 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test2 ORDER BY 2" +== 084 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test3 ORDER BY 2" +== 085 +-- truncate_limit: 100 +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(NULLIF(x, 'foo')), lower(NULLIF(y, 'foo')) FROM collate_test10" +== 086 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2" +== 087 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2" +== 088 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2" +== 089 +-- truncate_limit: 100 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain AS text" +== 090 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test1 ORDER BY 2" +== 091 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test2 ORDER BY 2" +== 092 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test3 ORDER BY 2" +== 093 +-- truncate_limit: 100 +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2" +== 094 +-- truncate_limit: 100 +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10" +== 095 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test1" +== 096 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test2" +== 097 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test3" +== 098 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test1" +== 099 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test2" +== 100 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test3" +== 101 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2" +== 102 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2" +== 103 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test3 WHERE ... INTERSECT SELECT ... FROM collate_test3 WHERE ... ORDER BY 2" +== 104 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2" +== 105 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2" +== 106 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3" +== 107 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2" +== 108 +-- truncate_limit: 100 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b COLLATE \"C\" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2" +== 109 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2" +== 110 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2" +== 111 +-- truncate_limit: 100 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3" +== 112 +-- truncate_limit: 100 +-- fail + +-- ideally this would be a parse-time error, but for now it must be run-time: +select x < y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x < y FROM collate_test10" +== 113 +-- truncate_limit: 100 +-- fail +select x || y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x || y FROM collate_test10" +== 114 +-- truncate_limit: 100 +-- ok, because || is not collation aware +select x, y from collate_test10 order by x || y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x, y FROM collate_test10 ORDER BY x || y" +== 115 +-- truncate_limit: 100 +-- not so ok + +-- 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 +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(x) AS (...) SELECT * FROM foo" +== 116 +-- truncate_limit: 100 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 117 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test1 ORDER BY 2" +== 118 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test2 ORDER BY 2" +== 119 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test3 ORDER BY 2" +== 120 +-- truncate_limit: 100 +-- 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 $$ +-- +FUNCTION: name="mylt" function="mylt" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt(text, text) RETURNS boolean LANGUAGE sql AS $$ select $1 < $2 $$" +== 121 +-- truncate_limit: 100 +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$ +-- +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt_noninline(text, text) RETURNS boolean LANGUAGE sql AS $$ select $1 < $2 limi..." +== 122 +-- truncate_limit: 100 +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$ +-- +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt_plpgsql(text, text) RETURNS boolean LANGUAGE plpgsql AS $$ begin return $1 <..." +== 123 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test1 a, collate_test1 b ORDER BY a.b, b.b" +== 124 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test1 a, collate_test1 b ORDER BY a.b, b.b" +== 125 +-- truncate_limit: 100 +-- 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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt2(x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$\ndeclare\n xx text :=..." +== 126 +-- truncate_limit: 100 +SELECT mylt2('a', 'B' collate "en-x-icu") as t, mylt2('a', 'B' collate "C") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"en-x-icu\") AS t, mylt2('a', 'B' COLLATE \"C\") AS f" +== 127 +-- truncate_limit: 100 +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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION mylt2(x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$\ndeclare\n ..." +== 128 +-- truncate_limit: 100 +SELECT mylt2('a', 'B') as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B') AS f" +== 129 +-- truncate_limit: 100 +SELECT mylt2('a', 'B' collate "C") as fail +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"C\") AS fail" +== 130 +-- truncate_limit: 100 +-- conflicting collations +SELECT mylt2('a', 'B' collate "POSIX") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"POSIX\") AS f" +== 131 +-- truncate_limit: 100 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1" +== 132 +-- truncate_limit: 100 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1" +== 133 +-- truncate_limit: 100 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1" +== 134 +-- truncate_limit: 100 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dup(anyelement) RETURNS anyelement AS $$select $1$$ LANGUAGE sql" +== 135 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test1 ORDER BY 2" +== 136 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test2 ORDER BY 2" +== 137 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test3 ORDER BY 2" +== 138 +-- truncate_limit: 100 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx1 ON collate_test1 USING btree (b)" +== 139 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx2 ON collate_test1 USING btree (b COLLATE \"C\")" +== 140 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx3 ON collate_test1 USING btree ((b COLLATE \"C\"))" +== 141 +-- truncate_limit: 100 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx4 ON collate_test1 USING btree (((b || 'foo') COLLATE \"POSIX\"))" +== 142 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx5 ON collate_test1 USING btree (a COLLATE \"C\")" +== 143 +-- truncate_limit: 100 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx6 ON collate_test1 USING btree ((a COLLATE \"C\"))" +== 144 +-- truncate_limit: 100 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE ... ORDER BY 1" +== 145 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 146 +-- truncate_limit: 100 +explain (costs off) +select * from collate_test1 where b ilike 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM collate_test1 WHERE b ILIKE 'abc'" +== 147 +-- truncate_limit: 100 +select * from collate_test1 where b ilike 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'abc'" +== 148 +-- truncate_limit: 100 +explain (costs off) +select * from collate_test1 where b ilike 'ABC' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM collate_test1 WHERE b ILIKE 'ABC'" +== 149 +-- truncate_limit: 100 +select * from collate_test1 where b ilike 'ABC' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'ABC'" +== 150 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 151 +-- truncate_limit: 100 +-- schema manipulation commands + +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_role" +== 152 +-- truncate_limit: 100 +CREATE SCHEMA test_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_schema" +== 153 +-- truncate_limit: 100 +-- We need to do this this way to cope with varying names for encodings: +SET client_min_messages TO WARNING +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 154 +-- truncate_limit: 100 +SET icu_validation_level = disabled +-- +STMT: VariableSetStmt +TRUNCATED: "SET icu_validation_level TO disabled" +== 155 +-- truncate_limit: 100 +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' || + quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||\n quote_lite..." +== 156 +-- truncate_limit: 100 +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test0 FROM \"C\"" +== 157 +-- truncate_limit: 100 +-- fail, duplicate name +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' || + quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||\n quote_lite..." +== 158 +-- truncate_limit: 100 +RESET icu_validation_level +-- +STMT: VariableSetStmt +TRUNCATED: "RESET icu_validation_level" +== 159 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 160 +-- truncate_limit: 100 +CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8')" +== 161 +-- truncate_limit: 100 +-- fail, needs "locale" +SET icu_validation_level = ERROR +-- +STMT: VariableSetStmt +TRUNCATED: "SET icu_validation_level TO error" +== 162 +-- truncate_limit: 100 +CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere')" +== 163 +-- truncate_limit: 100 +-- fails +CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes')" +== 164 +-- truncate_limit: 100 +-- fails +RESET icu_validation_level +-- +STMT: VariableSetStmt +TRUNCATED: "RESET icu_validation_level" +== 165 +-- truncate_limit: 100 +CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes')" +== 166 +-- truncate_limit: 100 +DROP COLLATION testx +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION testx" +== 167 +-- truncate_limit: 100 +CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere')" +== 168 +-- truncate_limit: 100 +DROP COLLATION testx +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION testx" +== 169 +-- truncate_limit: 100 +CREATE COLLATION test4 FROM nonsense +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test4 FROM nonsense" +== 170 +-- truncate_limit: 100 +CREATE COLLATION test5 FROM test0 +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test5 FROM test0" +== 171 +-- truncate_limit: 100 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1" +== 172 +-- truncate_limit: 100 +ALTER COLLATION test1 RENAME TO test11 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test1 RENAME TO test11" +== 173 +-- truncate_limit: 100 +ALTER COLLATION test0 RENAME TO test11 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test0 RENAME TO test11" +== 174 +-- truncate_limit: 100 +-- fail +ALTER COLLATION test1 RENAME TO test22 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test1 RENAME TO test22" +== 175 +-- truncate_limit: 100 +-- fail + +ALTER COLLATION test11 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER COLLATION test11 OWNER TO regress_test_role" +== 176 +-- truncate_limit: 100 +ALTER COLLATION test11 OWNER TO nonsense +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER COLLATION test11 OWNER TO nonsense" +== 177 +-- truncate_limit: 100 +ALTER COLLATION test11 SET SCHEMA test_schema +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER COLLATION test11 SET SCHEMA test_schema" +== 178 +-- truncate_limit: 100 +COMMENT ON COLLATION test0 IS 'US English' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLLATION test0 IS 'US English'" +== 179 +-- truncate_limit: 100 +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_collation JOIN pg_namespace ON collnamespace = pg_namespace.oid WHERE ... ORDE..." +== 180 +-- truncate_limit: 100 +DROP COLLATION test0, test_schema.test11, test5 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0, test_schema.test11, test5" +== 181 +-- truncate_limit: 100 +DROP COLLATION test0 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0" +== 182 +-- truncate_limit: 100 +-- fail +DROP COLLATION IF EXISTS test0 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION IF EXISTS test0" +== 183 +-- truncate_limit: 100 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT collname FROM pg_collation WHERE collname LIKE 'test%'" +== 184 +-- truncate_limit: 100 +DROP SCHEMA test_schema +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_schema" +== 185 +-- truncate_limit: 100 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role" +== 186 +-- truncate_limit: 100 +-- ALTER + +ALTER COLLATION "en-x-icu" REFRESH VERSION +-- +STMT: AlterCollationStmt +TRUNCATED: "ALTER COLLATION \"en-x-icu\" REFRESH VERSION" +== 187 +-- truncate_limit: 100 +-- also test for database while we are here +SELECT current_database() AS datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_database() AS datname" +== 188 +-- truncate_limit: 100 +ALTER DATABASE :"datname" REFRESH COLLATION VERSION +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 189 +-- truncate_limit: 100 +-- dependencies + +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test0 FROM \"C\"" +== 190 +-- truncate_limit: 100 +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0) +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0)" +== 191 +-- truncate_limit: 100 +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0" +== 192 +-- truncate_limit: 100 +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0)" +== 193 +-- truncate_limit: 100 +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo +-- +TABLE: name="collate_dep_test3" schema="" table="collate_dep_test3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collate_dep_test3 AS SELECT 'foo'::text COLLATE test0 AS foo" +== 194 +-- truncate_limit: 100 +CREATE TABLE collate_dep_test4t (a int, b text) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_dep_test4t (a int, b text)" +== 195 +-- truncate_limit: 100 +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_dep_test4i ON collate_dep_test4t USING btree (b COLLATE test0)" +== 196 +-- truncate_limit: 100 +DROP COLLATION test0 RESTRICT +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0" +== 197 +-- truncate_limit: 100 +-- fail +DROP COLLATION test0 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0 CASCADE" +== 198 +-- truncate_limit: 100 +DROP TABLE collate_dep_test1, collate_dep_test4t +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE collate_dep_test1, collate_dep_test4t" +== 199 +-- truncate_limit: 100 +DROP TYPE collate_dep_test2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE collate_dep_test2" +== 200 +-- truncate_limit: 100 +-- test range types and collations + +create type textrange_c as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange_c AS RANGE (subtype = text, \"collation\" = \"C\")" +== 201 +-- truncate_limit: 100 +create type textrange_en_us as range(subtype=text, collation="en-x-icu") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange_en_us AS RANGE (subtype = text, \"collation\" = \"en-x-icu\")" +== 202 +-- truncate_limit: 100 +select textrange_c('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_c" function="textrange_c" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange_c('A', 'Z') @> 'b'::text" +== 203 +-- truncate_limit: 100 +select textrange_en_us('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_en_us" function="textrange_en_us" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange_en_us('A', 'Z') @> 'b'::text" +== 204 +-- truncate_limit: 100 +drop type textrange_c +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange_c" +== 205 +-- truncate_limit: 100 +drop type textrange_en_us +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange_en_us" +== 206 +-- truncate_limit: 100 +-- standard collations + +SELECT * FROM collate_test2 ORDER BY b COLLATE UCS_BASIC +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 ORDER BY b COLLATE ucs_basic" +== 207 +-- truncate_limit: 100 +SELECT * FROM collate_test2 ORDER BY b COLLATE UNICODE +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 ORDER BY b COLLATE unicode" +== 208 +-- truncate_limit: 100 +-- test ICU collation customization + +-- test the attributes handled by icu_set_collation_attributes() + +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 209 +-- truncate_limit: 100 +CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseL..." +== 210 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 211 +-- truncate_limit: 100 +SELECT 'aaá' > 'AAA' COLLATE "und-x-icu", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'aaá' > 'AAA' COLLATE \"und-x-icu\", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents" +== 212 +-- truncate_limit: 100 +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 213 +-- truncate_limit: 100 +CREATE COLLATION testcoll_backwards (provider = icu, locale = '@colBackwards=yes') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_backwards (provider = icu, locale = '@colBackwards=yes')" +== 214 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 215 +-- truncate_limit: 100 +SELECT 'coté' < 'côte' COLLATE "und-x-icu", 'coté' > 'côte' COLLATE testcoll_backwards +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'coté' < 'côte' COLLATE \"und-x-icu\", 'coté' > 'côte' COLLATE testcoll_backwards" +== 216 +-- truncate_limit: 100 +CREATE COLLATION testcoll_lower_first (provider = icu, locale = '@colCaseFirst=lower') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_lower_first (provider = icu, locale = '@colCaseFirst=lower')" +== 217 +-- truncate_limit: 100 +CREATE COLLATION testcoll_upper_first (provider = icu, locale = '@colCaseFirst=upper') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_upper_first (provider = icu, locale = '@colCaseFirst=upper')" +== 218 +-- truncate_limit: 100 +SELECT 'aaa' < 'AAA' COLLATE testcoll_lower_first, 'aaa' > 'AAA' COLLATE testcoll_upper_first +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'aaa' < 'AAA' COLLATE testcoll_lower_first, 'aaa' > 'AAA' COLLATE testcoll_upper_first" +== 219 +-- truncate_limit: 100 +CREATE COLLATION testcoll_shifted (provider = icu, locale = '@colAlternate=shifted') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_shifted (provider = icu, locale = '@colAlternate=shifted')" +== 220 +-- truncate_limit: 100 +SELECT 'de-luge' < 'deanza' COLLATE "und-x-icu", 'de-luge' > 'deanza' COLLATE testcoll_shifted +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'de-luge' < 'deanza' COLLATE \"und-x-icu\", 'de-luge' > 'deanza' COLLATE testcoll_shifted" +== 221 +-- truncate_limit: 100 +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 222 +-- truncate_limit: 100 +CREATE COLLATION testcoll_numeric (provider = icu, locale = '@colNumeric=yes') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_numeric (provider = icu, locale = '@colNumeric=yes')" +== 223 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 224 +-- truncate_limit: 100 +SELECT 'A-21' > 'A-123' COLLATE "und-x-icu", 'A-21' < 'A-123' COLLATE testcoll_numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'A-21' > 'A-123' COLLATE \"und-x-icu\", 'A-21' < 'A-123' COLLATE testcoll_numeric" +== 225 +-- truncate_limit: 100 +CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower')" +== 226 +-- truncate_limit: 100 +-- test that attributes not handled by icu_set_collation_attributes() +-- (handled by ucol_open() directly) also work +CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook')" +== 227 +-- truncate_limit: 100 +SELECT 'Goldmann' < 'Götz' COLLATE "de-x-icu", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Goldmann' < 'Götz' COLLATE \"de-x-icu\", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook" +== 228 +-- truncate_limit: 100 +-- rules + +CREATE COLLATION testcoll_rules1 (provider = icu, locale = '', rules = '&a < g') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_rules1 (provider = icu, locale = '', rules = '&a < g')" +== 229 +-- truncate_limit: 100 +CREATE TABLE test7 (a text) +-- +TABLE: name="test7" schema="" table="test7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test7 (a text)" +== 230 +-- truncate_limit: 100 +-- example from https://unicode-org.github.io/icu/userguide/collation/customization/#syntax +INSERT INTO test7 VALUES ('Abernathy'), ('apple'), ('bird'), ('Boston'), ('Graham'), ('green') +-- +TABLE: name="test7" schema="" table="test7" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test7 VALUES ('Abernathy'), ('apple'), ('bird'), ('Boston'), ('Graham'), ('green')" +== 231 +-- truncate_limit: 100 +SELECT * FROM test7 ORDER BY a COLLATE "en-x-icu" +-- +TABLE: name="test7" schema="" table="test7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test7 ORDER BY a COLLATE \"en-x-icu\"" +== 232 +-- truncate_limit: 100 +SELECT * FROM test7 ORDER BY a COLLATE testcoll_rules1 +-- +TABLE: name="test7" schema="" table="test7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test7 ORDER BY a COLLATE testcoll_rules1" +== 233 +-- truncate_limit: 100 +DROP TABLE test7 +-- +TABLE: name="test7" schema="" table="test7" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test7" +== 234 +-- truncate_limit: 100 +CREATE COLLATION testcoll_rulesx (provider = icu, locale = '', rules = '!!wrong!!') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testcoll_rulesx (provider = icu, locale = '', rules = '!!wrong!!')" +== 235 +-- truncate_limit: 100 +-- nondeterministic collations + +CREATE COLLATION ctest_det (provider = icu, locale = '', deterministic = true) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION ctest_det (provider = icu, locale = '', deterministic = true)" +== 236 +-- truncate_limit: 100 +CREATE COLLATION ctest_nondet (provider = icu, locale = '', deterministic = false) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION ctest_nondet (provider = icu, locale = '', deterministic = false)" +== 237 +-- truncate_limit: 100 +CREATE TABLE test6 (a int, b text) +-- +TABLE: name="test6" schema="" table="test6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test6 (a int, b text)" +== 238 +-- truncate_limit: 100 +-- same string in different normal forms +INSERT INTO test6 VALUES (1, U&'\00E4bc') +-- +TABLE: name="test6" schema="" table="test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test6 VALUES (1, 'äbc')" +== 239 +-- truncate_limit: 100 +INSERT INTO test6 VALUES (2, U&'\0061\0308bc') +-- +TABLE: name="test6" schema="" table="test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test6 VALUES (2, 'äbc')" +== 240 +-- truncate_limit: 100 +SELECT * FROM test6 +-- +TABLE: name="test6" schema="" table="test6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test6" +== 241 +-- truncate_limit: 100 +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_det +-- +TABLE: name="test6" schema="" table="test6" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_det" +== 242 +-- truncate_limit: 100 +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_nondet +-- +TABLE: name="test6" schema="" table="test6" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_nondet" +== 243 +-- truncate_limit: 100 +-- same with arrays +CREATE TABLE test6a (a int, b text[]) +-- +TABLE: name="test6a" schema="" table="test6a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test6a (a int, b text[])" +== 244 +-- truncate_limit: 100 +INSERT INTO test6a VALUES (1, ARRAY[U&'\00E4bc']) +-- +TABLE: name="test6a" schema="" table="test6a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test6a VALUES (1, ARRAY['äbc'])" +== 245 +-- truncate_limit: 100 +INSERT INTO test6a VALUES (2, ARRAY[U&'\0061\0308bc']) +-- +TABLE: name="test6a" schema="" table="test6a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test6a VALUES (2, ARRAY['äbc'])" +== 246 +-- truncate_limit: 100 +SELECT * FROM test6a +-- +TABLE: name="test6a" schema="" table="test6a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test6a" +== 247 +-- truncate_limit: 100 +SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_det +-- +TABLE: name="test6a" schema="" table="test6a" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_det" +== 248 +-- truncate_limit: 100 +SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_nondet +-- +TABLE: name="test6a" schema="" table="test6a" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_nondet" +== 249 +-- truncate_limit: 100 +CREATE COLLATION case_sensitive (provider = icu, locale = '') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION case_sensitive (provider = icu, locale = '')" +== 250 +-- truncate_limit: 100 +CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', deterministic = false) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', determinist..." +== 251 +-- truncate_limit: 100 +SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive" +== 252 +-- truncate_limit: 100 +SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive" +== 253 +-- truncate_limit: 100 +-- test language tags +CREATE COLLATION lt_insensitive (provider = icu, locale = 'en-u-ks-level1', deterministic = false) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION lt_insensitive (provider = icu, locale = 'en-u-ks-level1', deterministic = false)" +== 254 +-- truncate_limit: 100 +SELECT 'aBcD' COLLATE lt_insensitive = 'AbCd' COLLATE lt_insensitive +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'aBcD' COLLATE lt_insensitive = 'AbCd' COLLATE lt_insensitive" +== 255 +-- truncate_limit: 100 +CREATE COLLATION lt_upperfirst (provider = icu, locale = 'und-u-kf-upper') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION lt_upperfirst (provider = icu, locale = 'und-u-kf-upper')" +== 256 +-- truncate_limit: 100 +SELECT 'Z' COLLATE lt_upperfirst < 'z' COLLATE lt_upperfirst +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Z' COLLATE lt_upperfirst < 'z' COLLATE lt_upperfirst" +== 257 +-- truncate_limit: 100 +CREATE TABLE test1cs (x text COLLATE case_sensitive) +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test1cs (x text COLLATE case_sensitive)" +== 258 +-- truncate_limit: 100 +CREATE TABLE test2cs (x text COLLATE case_sensitive) +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test2cs (x text COLLATE case_sensitive)" +== 259 +-- truncate_limit: 100 +CREATE TABLE test3cs (x text COLLATE case_sensitive) +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test3cs (x text COLLATE case_sensitive)" +== 260 +-- truncate_limit: 100 +INSERT INTO test1cs VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1cs VALUES ('abc'), ('def'), ('ghi')" +== 261 +-- truncate_limit: 100 +INSERT INTO test2cs VALUES ('ABC'), ('ghi') +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2cs VALUES ('ABC'), ('ghi')" +== 262 +-- truncate_limit: 100 +INSERT INTO test3cs VALUES ('abc'), ('ABC'), ('def'), ('ghi') +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test3cs VALUES ('abc'), ('ABC'), ('def'), ('ghi')" +== 263 +-- truncate_limit: 100 +SELECT x FROM test3cs WHERE x = 'abc' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3cs WHERE x = 'abc'" +== 264 +-- truncate_limit: 100 +SELECT x FROM test3cs WHERE x <> 'abc' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3cs WHERE x <> 'abc'" +== 265 +-- truncate_limit: 100 +SELECT x FROM test3cs WHERE x LIKE 'a%' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3cs WHERE x LIKE 'a%'" +== 266 +-- truncate_limit: 100 +SELECT x FROM test3cs WHERE x ILIKE 'a%' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3cs WHERE x ILIKE 'a%'" +== 267 +-- truncate_limit: 100 +SELECT x FROM test3cs WHERE x SIMILAR TO 'a%' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3cs WHERE x SIMILAR TO 'a%'" +== 268 +-- truncate_limit: 100 +SELECT x FROM test3cs WHERE x ~ 'a' +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3cs WHERE x ~ 'a'" +== 269 +-- truncate_limit: 100 +SET enable_hashagg TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 270 +-- truncate_limit: 100 +SELECT x FROM test1cs UNION SELECT x FROM test2cs ORDER BY x +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1cs UNION SELECT x FROM test2cs ORDER BY x" +== 271 +-- truncate_limit: 100 +SELECT x FROM test2cs UNION SELECT x FROM test1cs ORDER BY x +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2cs UNION SELECT x FROM test1cs ORDER BY x" +== 272 +-- truncate_limit: 100 +SELECT x FROM test1cs INTERSECT SELECT x FROM test2cs +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1cs INTERSECT SELECT x FROM test2cs" +== 273 +-- truncate_limit: 100 +SELECT x FROM test2cs INTERSECT SELECT x FROM test1cs +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2cs INTERSECT SELECT x FROM test1cs" +== 274 +-- truncate_limit: 100 +SELECT x FROM test1cs EXCEPT SELECT x FROM test2cs +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1cs EXCEPT SELECT x FROM test2cs" +== 275 +-- truncate_limit: 100 +SELECT x FROM test2cs EXCEPT SELECT x FROM test1cs +-- +TABLE: name="test2cs" schema="" table="test2cs" ctx=Select +TABLE: name="test1cs" schema="" table="test1cs" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2cs EXCEPT SELECT x FROM test1cs" +== 276 +-- truncate_limit: 100 +SELECT DISTINCT x FROM test3cs ORDER BY x +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT x FROM test3cs ORDER BY x" +== 277 +-- truncate_limit: 100 +RESET enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 278 +-- truncate_limit: 100 +SELECT count(DISTINCT x) FROM test3cs +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT x) FROM test3cs" +== 279 +-- truncate_limit: 100 +SELECT x, count(*) FROM test3cs GROUP BY x ORDER BY x +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, count(*) FROM test3cs GROUP BY x ORDER BY x" +== 280 +-- truncate_limit: 100 +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3cs ORDER BY x +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3cs ORDER BY x" +== 281 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON test1cs (x) +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON test1cs USING btree (x)" +== 282 +-- truncate_limit: 100 +-- ok +INSERT INTO test1cs VALUES ('ABC') +-- +TABLE: name="test1cs" schema="" table="test1cs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1cs VALUES ('ABC')" +== 283 +-- truncate_limit: 100 +-- ok +CREATE UNIQUE INDEX ON test3cs (x) +-- +TABLE: name="test3cs" schema="" table="test3cs" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON test3cs USING btree (x)" +== 284 +-- truncate_limit: 100 +-- ok +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_sensitive, ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('ABC,DEF,GHI' COLLATE case_sensitive, ',', 'abc')" +== 285 +-- truncate_limit: 100 +SELECT string_to_array('ABCDEFGHI' COLLATE case_sensitive, NULL, 'b') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('ABCDEFGHI' COLLATE case_sensitive, NULL, 'b')" +== 286 +-- truncate_limit: 100 +CREATE TABLE test1ci (x text COLLATE case_insensitive) +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test1ci (x text COLLATE case_insensitive)" +== 287 +-- truncate_limit: 100 +CREATE TABLE test2ci (x text COLLATE case_insensitive) +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test2ci (x text COLLATE case_insensitive)" +== 288 +-- truncate_limit: 100 +CREATE TABLE test3ci (x text COLLATE case_insensitive) +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test3ci (x text COLLATE case_insensitive)" +== 289 +-- truncate_limit: 100 +CREATE INDEX ON test3ci (x text_pattern_ops) +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test3ci USING btree (x text_pattern_ops)" +== 290 +-- truncate_limit: 100 +-- error +INSERT INTO test1ci VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1ci VALUES ('abc'), ('def'), ('ghi')" +== 291 +-- truncate_limit: 100 +INSERT INTO test2ci VALUES ('ABC'), ('ghi') +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2ci VALUES ('ABC'), ('ghi')" +== 292 +-- truncate_limit: 100 +INSERT INTO test3ci VALUES ('abc'), ('ABC'), ('def'), ('ghi') +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test3ci VALUES ('abc'), ('ABC'), ('def'), ('ghi')" +== 293 +-- truncate_limit: 100 +SELECT x FROM test3ci WHERE x = 'abc' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3ci WHERE x = 'abc'" +== 294 +-- truncate_limit: 100 +SELECT x FROM test3ci WHERE x <> 'abc' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3ci WHERE x <> 'abc'" +== 295 +-- truncate_limit: 100 +SELECT x FROM test3ci WHERE x LIKE 'a%' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3ci WHERE x LIKE 'a%'" +== 296 +-- truncate_limit: 100 +SELECT x FROM test3ci WHERE x ILIKE 'a%' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3ci WHERE x ILIKE 'a%'" +== 297 +-- truncate_limit: 100 +SELECT x FROM test3ci WHERE x SIMILAR TO 'a%' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3ci WHERE x SIMILAR TO 'a%'" +== 298 +-- truncate_limit: 100 +SELECT x FROM test3ci WHERE x ~ 'a' +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3ci WHERE x ~ 'a'" +== 299 +-- truncate_limit: 100 +SELECT x FROM test1ci UNION SELECT x FROM test2ci ORDER BY x +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1ci UNION SELECT x FROM test2ci ORDER BY x" +== 300 +-- truncate_limit: 100 +SELECT x FROM test2ci UNION SELECT x FROM test1ci ORDER BY x +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2ci UNION SELECT x FROM test1ci ORDER BY x" +== 301 +-- truncate_limit: 100 +SELECT x FROM test1ci INTERSECT SELECT x FROM test2ci ORDER BY x +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1ci INTERSECT SELECT x FROM test2ci ORDER BY x" +== 302 +-- truncate_limit: 100 +SELECT x FROM test2ci INTERSECT SELECT x FROM test1ci ORDER BY x +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2ci INTERSECT SELECT x FROM test1ci ORDER BY x" +== 303 +-- truncate_limit: 100 +SELECT x FROM test1ci EXCEPT SELECT x FROM test2ci +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1ci EXCEPT SELECT x FROM test2ci" +== 304 +-- truncate_limit: 100 +SELECT x FROM test2ci EXCEPT SELECT x FROM test1ci +-- +TABLE: name="test2ci" schema="" table="test2ci" ctx=Select +TABLE: name="test1ci" schema="" table="test1ci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2ci EXCEPT SELECT x FROM test1ci" +== 305 +-- truncate_limit: 100 +SELECT DISTINCT x FROM test3ci ORDER BY x +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT x FROM test3ci ORDER BY x" +== 306 +-- truncate_limit: 100 +SELECT count(DISTINCT x) FROM test3ci +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT x) FROM test3ci" +== 307 +-- truncate_limit: 100 +SELECT x, count(*) FROM test3ci GROUP BY x ORDER BY x +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, count(*) FROM test3ci GROUP BY x ORDER BY x" +== 308 +-- truncate_limit: 100 +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3ci ORDER BY x +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3ci ORDER BY x" +== 309 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON test1ci (x) +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON test1ci USING btree (x)" +== 310 +-- truncate_limit: 100 +-- ok +INSERT INTO test1ci VALUES ('ABC') +-- +TABLE: name="test1ci" schema="" table="test1ci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1ci VALUES ('ABC')" +== 311 +-- truncate_limit: 100 +-- error +CREATE UNIQUE INDEX ON test3ci (x) +-- +TABLE: name="test3ci" schema="" table="test3ci" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON test3ci USING btree (x)" +== 312 +-- truncate_limit: 100 +-- error +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc')" +== 313 +-- truncate_limit: 100 +SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b')" +== 314 +-- truncate_limit: 100 +-- bpchar +CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive) +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive)" +== 315 +-- truncate_limit: 100 +CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive) +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive)" +== 316 +-- truncate_limit: 100 +CREATE TABLE test3bpci (x char(3) COLLATE case_insensitive) +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test3bpci (x char(3) COLLATE case_insensitive)" +== 317 +-- truncate_limit: 100 +CREATE INDEX ON test3bpci (x bpchar_pattern_ops) +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test3bpci USING btree (x bpchar_pattern_ops)" +== 318 +-- truncate_limit: 100 +-- error +INSERT INTO test1bpci VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1bpci VALUES ('abc'), ('def'), ('ghi')" +== 319 +-- truncate_limit: 100 +INSERT INTO test2bpci VALUES ('ABC'), ('ghi') +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2bpci VALUES ('ABC'), ('ghi')" +== 320 +-- truncate_limit: 100 +INSERT INTO test3bpci VALUES ('abc'), ('ABC'), ('def'), ('ghi') +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test3bpci VALUES ('abc'), ('ABC'), ('def'), ('ghi')" +== 321 +-- truncate_limit: 100 +SELECT x FROM test3bpci WHERE x = 'abc' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3bpci WHERE x = 'abc'" +== 322 +-- truncate_limit: 100 +SELECT x FROM test3bpci WHERE x <> 'abc' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3bpci WHERE x <> 'abc'" +== 323 +-- truncate_limit: 100 +SELECT x FROM test3bpci WHERE x LIKE 'a%' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3bpci WHERE x LIKE 'a%'" +== 324 +-- truncate_limit: 100 +SELECT x FROM test3bpci WHERE x ILIKE 'a%' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3bpci WHERE x ILIKE 'a%'" +== 325 +-- truncate_limit: 100 +SELECT x FROM test3bpci WHERE x SIMILAR TO 'a%' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.similar_to_escape" function="similar_to_escape" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3bpci WHERE x SIMILAR TO 'a%'" +== 326 +-- truncate_limit: 100 +SELECT x FROM test3bpci WHERE x ~ 'a' +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test3bpci WHERE x ~ 'a'" +== 327 +-- truncate_limit: 100 +SELECT x FROM test1bpci UNION SELECT x FROM test2bpci ORDER BY x +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1bpci UNION SELECT x FROM test2bpci ORDER BY x" +== 328 +-- truncate_limit: 100 +SELECT x FROM test2bpci UNION SELECT x FROM test1bpci ORDER BY x +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2bpci UNION SELECT x FROM test1bpci ORDER BY x" +== 329 +-- truncate_limit: 100 +SELECT x FROM test1bpci INTERSECT SELECT x FROM test2bpci ORDER BY x +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1bpci INTERSECT SELECT x FROM test2bpci ORDER BY x" +== 330 +-- truncate_limit: 100 +SELECT x FROM test2bpci INTERSECT SELECT x FROM test1bpci ORDER BY x +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2bpci INTERSECT SELECT x FROM test1bpci ORDER BY x" +== 331 +-- truncate_limit: 100 +SELECT x FROM test1bpci EXCEPT SELECT x FROM test2bpci +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test1bpci EXCEPT SELECT x FROM test2bpci" +== 332 +-- truncate_limit: 100 +SELECT x FROM test2bpci EXCEPT SELECT x FROM test1bpci +-- +TABLE: name="test2bpci" schema="" table="test2bpci" ctx=Select +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test2bpci EXCEPT SELECT x FROM test1bpci" +== 333 +-- truncate_limit: 100 +SELECT DISTINCT x FROM test3bpci ORDER BY x +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT x FROM test3bpci ORDER BY x" +== 334 +-- truncate_limit: 100 +SELECT count(DISTINCT x) FROM test3bpci +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT x) FROM test3bpci" +== 335 +-- truncate_limit: 100 +SELECT x, count(*) FROM test3bpci GROUP BY x ORDER BY x +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, count(*) FROM test3bpci GROUP BY x ORDER BY x" +== 336 +-- truncate_limit: 100 +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3bpci ORDER BY x +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3bpci ORDER BY x" +== 337 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON test1bpci (x) +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON test1bpci USING btree (x)" +== 338 +-- truncate_limit: 100 +-- ok +INSERT INTO test1bpci VALUES ('ABC') +-- +TABLE: name="test1bpci" schema="" table="test1bpci" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1bpci VALUES ('ABC')" +== 339 +-- truncate_limit: 100 +-- error +CREATE UNIQUE INDEX ON test3bpci (x) +-- +TABLE: name="test3bpci" schema="" table="test3bpci" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON test3bpci USING btree (x)" +== 340 +-- truncate_limit: 100 +-- error +SELECT string_to_array('ABC,DEF,GHI'::char(11) COLLATE case_insensitive, ',', 'abc') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('ABC,DEF,GHI'::char(11) COLLATE case_insensitive, ',', 'abc')" +== 341 +-- truncate_limit: 100 +SELECT string_to_array('ABCDEFGHI'::char(9) COLLATE case_insensitive, NULL, 'b') +-- +FUNCTION: name="string_to_array" function="string_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_to_array('ABCDEFGHI'::char(9) COLLATE case_insensitive, NULL, 'b')" +== 342 +-- truncate_limit: 100 +-- This tests the issue described in match_pattern_prefix(). In the +-- absence of that check, the case_insensitive tests below would +-- return no rows where they should logically return one. +CREATE TABLE test4c (x text COLLATE "C") +-- +TABLE: name="test4c" schema="" table="test4c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test4c (x text COLLATE \"C\")" +== 343 +-- truncate_limit: 100 +INSERT INTO test4c VALUES ('abc') +-- +TABLE: name="test4c" schema="" table="test4c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test4c VALUES ('abc')" +== 344 +-- truncate_limit: 100 +CREATE INDEX ON test4c (x) +-- +TABLE: name="test4c" schema="" table="test4c" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test4c USING btree (x)" +== 345 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 346 +-- truncate_limit: 100 +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_sensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_sensitive" +== 347 +-- truncate_limit: 100 +-- ok, no rows +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_sensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_sensitive" +== 348 +-- truncate_limit: 100 +-- ok, no rows +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_insensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_insensitive" +== 349 +-- truncate_limit: 100 +-- error +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_insensitive +-- +TABLE: name="test4c" schema="" table="test4c" ctx=Select +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_insensitive" +== 350 +-- truncate_limit: 100 +-- error +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 351 +-- truncate_limit: 100 +-- Unicode special case: different variants of Greek lower case sigma. +-- A naive implementation like citext that just does lower(x) = +-- lower(y) will do the wrong thing here, because lower('Σ') is 'σ' +-- but upper('ς') is 'Σ'. +SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_sensitive +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_sensitive" +== 352 +-- truncate_limit: 100 +SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_insensitive +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_insensitive" +== 353 +-- truncate_limit: 100 +-- name vs. text comparison operators +SELECT relname FROM pg_class WHERE relname = 'PG_CLASS'::text COLLATE case_insensitive +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname = 'PG_CLASS'::text COLLATE case_insensitive" +== 354 +-- truncate_limit: 100 +SELECT relname FROM pg_class WHERE 'PG_CLASS'::text = relname COLLATE case_insensitive +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE 'PG_CLASS'::text = relname COLLATE case_insensitive" +== 355 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND typname <> 'INT2'::text + COLLATE case_insensitive ORDER BY typname +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE ... ORDER BY typname" +== 356 +-- truncate_limit: 100 +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND 'INT2'::text <> typname + COLLATE case_insensitive ORDER BY typname +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT typname FROM pg_type WHERE ... ORDER BY typname" +== 357 +-- truncate_limit: 100 +-- test case adapted from subselect.sql +CREATE TEMP TABLE outer_text (f1 text COLLATE case_insensitive, f2 text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE outer_text (f1 text COLLATE case_insensitive, f2 text)" +== 358 +-- truncate_limit: 100 +INSERT INTO outer_text VALUES ('a', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('a', 'a')" +== 359 +-- truncate_limit: 100 +INSERT INTO outer_text VALUES ('b', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('b', 'a')" +== 360 +-- truncate_limit: 100 +INSERT INTO outer_text VALUES ('A', NULL) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('A', NULL)" +== 361 +-- truncate_limit: 100 +INSERT INTO outer_text VALUES ('B', NULL) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('B', NULL)" +== 362 +-- truncate_limit: 100 +CREATE TEMP TABLE inner_text (c1 text COLLATE case_insensitive, c2 text) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE inner_text (c1 text COLLATE case_insensitive, c2 text)" +== 363 +-- truncate_limit: 100 +INSERT INTO inner_text VALUES ('a', NULL) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inner_text VALUES ('a', NULL)" +== 364 +-- truncate_limit: 100 +SELECT * FROM outer_text WHERE (f1, f2) NOT IN (SELECT * FROM inner_text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM outer_text WHERE NOT (f1, f2) IN (SELECT * FROM inner_text)" +== 365 +-- truncate_limit: 100 +-- accents +SET client_min_messages=WARNING +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 366 +-- truncate_limit: 100 +CREATE COLLATION ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes', deterministic = false) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes'..." +== 367 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 368 +-- truncate_limit: 100 +CREATE TABLE test4 (a int, b text) +-- +TABLE: name="test4" schema="" table="test4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test4 (a int, b text)" +== 369 +-- truncate_limit: 100 +INSERT INTO test4 VALUES (1, 'cote'), (2, 'côte'), (3, 'coté'), (4, 'côté') +-- +TABLE: name="test4" schema="" table="test4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test4 VALUES (1, 'cote'), (2, 'côte'), (3, 'coté'), (4, 'côté')" +== 370 +-- truncate_limit: 100 +SELECT * FROM test4 WHERE b = 'cote' +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test4 WHERE b = 'cote'" +== 371 +-- truncate_limit: 100 +SELECT * FROM test4 WHERE b = 'cote' COLLATE ignore_accents +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test4 WHERE b = 'cote' COLLATE ignore_accents" +== 372 +-- truncate_limit: 100 +SELECT * FROM test4 WHERE b = 'Cote' COLLATE ignore_accents +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test4 WHERE b = 'Cote' COLLATE ignore_accents" +== 373 +-- truncate_limit: 100 +-- still case-sensitive +SELECT * FROM test4 WHERE b = 'Cote' COLLATE case_insensitive +-- +TABLE: name="test4" schema="" table="test4" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test4 WHERE b = 'Cote' COLLATE case_insensitive" +== 374 +-- truncate_limit: 100 +-- foreign keys (should use collation of primary key) + +-- PK is case-sensitive, FK is case-insensitive +CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY) +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test10pk (x text PRIMARY KEY COLLATE case_sensitive)" +== 375 +-- truncate_limit: 100 +INSERT INTO test10pk VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test10pk VALUES ('abc'), ('def'), ('ghi')" +== 376 +-- truncate_limit: 100 +CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE) +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test10fk (x text REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE COLLATE..." +== 377 +-- truncate_limit: 100 +INSERT INTO test10fk VALUES ('abc') +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test10fk VALUES ('abc')" +== 378 +-- truncate_limit: 100 +-- ok +INSERT INTO test10fk VALUES ('ABC') +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test10fk VALUES ('ABC')" +== 379 +-- truncate_limit: 100 +-- error +INSERT INTO test10fk VALUES ('xyz') +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test10fk VALUES ('xyz')" +== 380 +-- truncate_limit: 100 +-- error +SELECT * FROM test10pk +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test10pk" +== 381 +-- truncate_limit: 100 +SELECT * FROM test10fk +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test10fk" +== 382 +-- truncate_limit: 100 +-- restrict update even though the values are "equal" in the FK table +UPDATE test10fk SET x = 'ABC' WHERE x = 'abc' +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test10fk SET x = 'ABC' WHERE x = 'abc'" +== 383 +-- truncate_limit: 100 +-- error +SELECT * FROM test10fk +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test10fk" +== 384 +-- truncate_limit: 100 +DELETE FROM test10pk WHERE x = 'abc' +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test10pk WHERE x = 'abc'" +== 385 +-- truncate_limit: 100 +SELECT * FROM test10pk +-- +TABLE: name="test10pk" schema="" table="test10pk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test10pk" +== 386 +-- truncate_limit: 100 +SELECT * FROM test10fk +-- +TABLE: name="test10fk" schema="" table="test10fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test10fk" +== 387 +-- truncate_limit: 100 +-- PK is case-insensitive, FK is case-sensitive +CREATE TABLE test11pk (x text COLLATE case_insensitive PRIMARY KEY) +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test11pk (x text PRIMARY KEY COLLATE case_insensitive)" +== 388 +-- truncate_limit: 100 +INSERT INTO test11pk VALUES ('abc'), ('def'), ('ghi') +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test11pk VALUES ('abc'), ('def'), ('ghi')" +== 389 +-- truncate_limit: 100 +CREATE TABLE test11fk (x text COLLATE case_sensitive REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE) +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test11fk (x text REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE COLLATE..." +== 390 +-- truncate_limit: 100 +INSERT INTO test11fk VALUES ('abc') +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test11fk VALUES ('abc')" +== 391 +-- truncate_limit: 100 +-- ok +INSERT INTO test11fk VALUES ('ABC') +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test11fk VALUES ('ABC')" +== 392 +-- truncate_limit: 100 +-- ok +INSERT INTO test11fk VALUES ('xyz') +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test11fk VALUES ('xyz')" +== 393 +-- truncate_limit: 100 +-- error +SELECT * FROM test11pk +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test11pk" +== 394 +-- truncate_limit: 100 +SELECT * FROM test11fk +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test11fk" +== 395 +-- truncate_limit: 100 +-- cascade update even though the values are "equal" in the PK table +UPDATE test11pk SET x = 'ABC' WHERE x = 'abc' +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test11pk SET x = 'ABC' WHERE x = 'abc'" +== 396 +-- truncate_limit: 100 +SELECT * FROM test11fk +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test11fk" +== 397 +-- truncate_limit: 100 +DELETE FROM test11pk WHERE x = 'abc' +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test11pk WHERE x = 'abc'" +== 398 +-- truncate_limit: 100 +SELECT * FROM test11pk +-- +TABLE: name="test11pk" schema="" table="test11pk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test11pk" +== 399 +-- truncate_limit: 100 +SELECT * FROM test11fk +-- +TABLE: name="test11fk" schema="" table="test11fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test11fk" +== 400 +-- truncate_limit: 100 +-- partitioning +CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b) +-- +TABLE: name="test20" schema="" table="test20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b)" +== 401 +-- truncate_limit: 100 +CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc') +-- +TABLE: name="test20_1" schema="" table="test20_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc')" +== 402 +-- truncate_limit: 100 +INSERT INTO test20 VALUES (1, 'abc') +-- +TABLE: name="test20" schema="" table="test20" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test20 VALUES (1, 'abc')" +== 403 +-- truncate_limit: 100 +INSERT INTO test20 VALUES (2, 'ABC') +-- +TABLE: name="test20" schema="" table="test20" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test20 VALUES (2, 'ABC')" +== 404 +-- truncate_limit: 100 +SELECT * FROM test20_1 +-- +TABLE: name="test20_1" schema="" table="test20_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test20_1" +== 405 +-- truncate_limit: 100 +CREATE TABLE test21 (a int, b text COLLATE case_insensitive) PARTITION BY RANGE (b) +-- +TABLE: name="test21" schema="" table="test21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test21 (a int, b text COLLATE case_insensitive) PARTITION BY RANGE (b)" +== 406 +-- truncate_limit: 100 +CREATE TABLE test21_1 PARTITION OF test21 FOR VALUES FROM ('ABC') TO ('DEF') +-- +TABLE: name="test21_1" schema="" table="test21_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test21_1 PARTITION OF test21 FOR VALUES FROM ('ABC') TO ('DEF')" +== 407 +-- truncate_limit: 100 +INSERT INTO test21 VALUES (1, 'abc') +-- +TABLE: name="test21" schema="" table="test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test21 VALUES (1, 'abc')" +== 408 +-- truncate_limit: 100 +INSERT INTO test21 VALUES (2, 'ABC') +-- +TABLE: name="test21" schema="" table="test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test21 VALUES (2, 'ABC')" +== 409 +-- truncate_limit: 100 +SELECT * FROM test21_1 +-- +TABLE: name="test21_1" schema="" table="test21_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test21_1" +== 410 +-- truncate_limit: 100 +CREATE TABLE test22 (a int, b text COLLATE case_sensitive) PARTITION BY HASH (b) +-- +TABLE: name="test22" schema="" table="test22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test22 (a int, b text COLLATE case_sensitive) PARTITION BY HASH (b)" +== 411 +-- truncate_limit: 100 +CREATE TABLE test22_0 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test22_0" schema="" table="test22_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test22_0 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 412 +-- truncate_limit: 100 +CREATE TABLE test22_1 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test22_1" schema="" table="test22_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test22_1 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 413 +-- truncate_limit: 100 +INSERT INTO test22 VALUES (1, 'def') +-- +TABLE: name="test22" schema="" table="test22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test22 VALUES (1, 'def')" +== 414 +-- truncate_limit: 100 +INSERT INTO test22 VALUES (2, 'DEF') +-- +TABLE: name="test22" schema="" table="test22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test22 VALUES (2, 'DEF')" +== 415 +-- truncate_limit: 100 +-- they end up in different partitions +SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1) +-- +TABLE: name="test22_0" schema="" table="test22_0" ctx=Select +TABLE: name="test22_1" schema="" table="test22_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1)" +== 416 +-- truncate_limit: 100 +-- same with arrays +CREATE TABLE test22a (a int, b text[] COLLATE case_sensitive) PARTITION BY HASH (b) +-- +TABLE: name="test22a" schema="" table="test22a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test22a (a int, b text[] COLLATE case_sensitive) PARTITION BY HASH (b)" +== 417 +-- truncate_limit: 100 +CREATE TABLE test22a_0 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test22a_0" schema="" table="test22a_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test22a_0 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 418 +-- truncate_limit: 100 +CREATE TABLE test22a_1 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test22a_1" schema="" table="test22a_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test22a_1 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 419 +-- truncate_limit: 100 +INSERT INTO test22a VALUES (1, ARRAY['def']) +-- +TABLE: name="test22a" schema="" table="test22a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test22a VALUES (1, ARRAY['def'])" +== 420 +-- truncate_limit: 100 +INSERT INTO test22a VALUES (2, ARRAY['DEF']) +-- +TABLE: name="test22a" schema="" table="test22a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test22a VALUES (2, ARRAY['DEF'])" +== 421 +-- truncate_limit: 100 +-- they end up in different partitions +SELECT (SELECT count(*) FROM test22a_0) = (SELECT count(*) FROM test22a_1) +-- +TABLE: name="test22a_0" schema="" table="test22a_0" ctx=Select +TABLE: name="test22a_1" schema="" table="test22a_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT count(*) FROM test22a_0) = (SELECT count(*) FROM test22a_1)" +== 422 +-- truncate_limit: 100 +CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b) +-- +TABLE: name="test23" schema="" table="test23" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b)" +== 423 +-- truncate_limit: 100 +CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test23_0" schema="" table="test23_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 424 +-- truncate_limit: 100 +CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test23_1" schema="" table="test23_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 425 +-- truncate_limit: 100 +INSERT INTO test23 VALUES (1, 'def') +-- +TABLE: name="test23" schema="" table="test23" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test23 VALUES (1, 'def')" +== 426 +-- truncate_limit: 100 +INSERT INTO test23 VALUES (2, 'DEF') +-- +TABLE: name="test23" schema="" table="test23" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test23 VALUES (2, 'DEF')" +== 427 +-- truncate_limit: 100 +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1) +-- +TABLE: name="test23_0" schema="" table="test23_0" ctx=Select +TABLE: name="test23_1" schema="" table="test23_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1)" +== 428 +-- truncate_limit: 100 +-- same with arrays +CREATE TABLE test23a (a int, b text[] COLLATE case_insensitive) PARTITION BY HASH (b) +-- +TABLE: name="test23a" schema="" table="test23a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test23a (a int, b text[] COLLATE case_insensitive) PARTITION BY HASH (b)" +== 429 +-- truncate_limit: 100 +CREATE TABLE test23a_0 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test23a_0" schema="" table="test23a_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test23a_0 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 430 +-- truncate_limit: 100 +CREATE TABLE test23a_1 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test23a_1" schema="" table="test23a_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test23a_1 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 431 +-- truncate_limit: 100 +INSERT INTO test23a VALUES (1, ARRAY['def']) +-- +TABLE: name="test23a" schema="" table="test23a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test23a VALUES (1, ARRAY['def'])" +== 432 +-- truncate_limit: 100 +INSERT INTO test23a VALUES (2, ARRAY['DEF']) +-- +TABLE: name="test23a" schema="" table="test23a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test23a VALUES (2, ARRAY['DEF'])" +== 433 +-- truncate_limit: 100 +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test23a_0) <> (SELECT count(*) FROM test23a_1) +-- +TABLE: name="test23a_0" schema="" table="test23a_0" ctx=Select +TABLE: name="test23a_1" schema="" table="test23a_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT count(*) FROM test23a_0) <> (SELECT count(*) FROM test23a_1)" +== 434 +-- truncate_limit: 100 +CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b) +-- +TABLE: name="test30" schema="" table="test30" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b)" +== 435 +-- truncate_limit: 100 +CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc') +-- +TABLE: name="test30_1" schema="" table="test30_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc')" +== 436 +-- truncate_limit: 100 +INSERT INTO test30 VALUES (1, 'abc') +-- +TABLE: name="test30" schema="" table="test30" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test30 VALUES (1, 'abc')" +== 437 +-- truncate_limit: 100 +INSERT INTO test30 VALUES (2, 'ABC') +-- +TABLE: name="test30" schema="" table="test30" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test30 VALUES (2, 'ABC')" +== 438 +-- truncate_limit: 100 +SELECT * FROM test30_1 +-- +TABLE: name="test30_1" schema="" table="test30_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test30_1" +== 439 +-- truncate_limit: 100 +CREATE TABLE test31 (a int, b char(3) COLLATE case_insensitive) PARTITION BY RANGE (b) +-- +TABLE: name="test31" schema="" table="test31" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test31 (a int, b char(3) COLLATE case_insensitive) PARTITION BY RANGE (b)" +== 440 +-- truncate_limit: 100 +CREATE TABLE test31_1 PARTITION OF test31 FOR VALUES FROM ('ABC') TO ('DEF') +-- +TABLE: name="test31_1" schema="" table="test31_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test31_1 PARTITION OF test31 FOR VALUES FROM ('ABC') TO ('DEF')" +== 441 +-- truncate_limit: 100 +INSERT INTO test31 VALUES (1, 'abc') +-- +TABLE: name="test31" schema="" table="test31" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test31 VALUES (1, 'abc')" +== 442 +-- truncate_limit: 100 +INSERT INTO test31 VALUES (2, 'ABC') +-- +TABLE: name="test31" schema="" table="test31" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test31 VALUES (2, 'ABC')" +== 443 +-- truncate_limit: 100 +SELECT * FROM test31_1 +-- +TABLE: name="test31_1" schema="" table="test31_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test31_1" +== 444 +-- truncate_limit: 100 +CREATE TABLE test32 (a int, b char(3) COLLATE case_sensitive) PARTITION BY HASH (b) +-- +TABLE: name="test32" schema="" table="test32" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test32 (a int, b char(3) COLLATE case_sensitive) PARTITION BY HASH (b)" +== 445 +-- truncate_limit: 100 +CREATE TABLE test32_0 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test32_0" schema="" table="test32_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test32_0 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 446 +-- truncate_limit: 100 +CREATE TABLE test32_1 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test32_1" schema="" table="test32_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test32_1 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 447 +-- truncate_limit: 100 +INSERT INTO test32 VALUES (1, 'def') +-- +TABLE: name="test32" schema="" table="test32" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test32 VALUES (1, 'def')" +== 448 +-- truncate_limit: 100 +INSERT INTO test32 VALUES (2, 'DEF') +-- +TABLE: name="test32" schema="" table="test32" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test32 VALUES (2, 'DEF')" +== 449 +-- truncate_limit: 100 +-- they end up in different partitions +SELECT (SELECT count(*) FROM test32_0) = (SELECT count(*) FROM test32_1) +-- +TABLE: name="test32_0" schema="" table="test32_0" ctx=Select +TABLE: name="test32_1" schema="" table="test32_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT count(*) FROM test32_0) = (SELECT count(*) FROM test32_1)" +== 450 +-- truncate_limit: 100 +CREATE TABLE test33 (a int, b char(3) COLLATE case_insensitive) PARTITION BY HASH (b) +-- +TABLE: name="test33" schema="" table="test33" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test33 (a int, b char(3) COLLATE case_insensitive) PARTITION BY HASH (b)" +== 451 +-- truncate_limit: 100 +CREATE TABLE test33_0 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="test33_0" schema="" table="test33_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test33_0 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 452 +-- truncate_limit: 100 +CREATE TABLE test33_1 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="test33_1" schema="" table="test33_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test33_1 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 453 +-- truncate_limit: 100 +INSERT INTO test33 VALUES (1, 'def') +-- +TABLE: name="test33" schema="" table="test33" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test33 VALUES (1, 'def')" +== 454 +-- truncate_limit: 100 +INSERT INTO test33 VALUES (2, 'DEF') +-- +TABLE: name="test33" schema="" table="test33" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test33 VALUES (2, 'DEF')" +== 455 +-- truncate_limit: 100 +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test33_0) <> (SELECT count(*) FROM test33_1) +-- +TABLE: name="test33_0" schema="" table="test33_0" ctx=Select +TABLE: name="test33_1" schema="" table="test33_1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT count(*) FROM test33_0) <> (SELECT count(*) FROM test33_1)" +== 456 +-- truncate_limit: 100 +|-- +-- Bug #18568 +|-- +-- Partitionwise aggregate (full or partial) should not be used when a +-- partition key's collation doesn't match that of the GROUP BY column it is +-- matched with. +SET max_parallel_workers_per_gather TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 0" +== 457 +-- truncate_limit: 100 +SET enable_incremental_sort TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_incremental_sort TO OFF" +== 458 +-- truncate_limit: 100 +CREATE TABLE pagg_tab3 (a text, c text collate case_insensitive) PARTITION BY LIST(c collate "C") +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab3 (a text, c text COLLATE case_insensitive) PARTITION BY LIST (c COLLATE \"C\")" +== 459 +-- truncate_limit: 100 +CREATE TABLE pagg_tab3_p1 PARTITION OF pagg_tab3 FOR VALUES IN ('a', 'b') +-- +TABLE: name="pagg_tab3_p1" schema="" table="pagg_tab3_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab3_p1 PARTITION OF pagg_tab3 FOR VALUES IN ('a', 'b')" +== 460 +-- truncate_limit: 100 +CREATE TABLE pagg_tab3_p2 PARTITION OF pagg_tab3 FOR VALUES IN ('B', 'A') +-- +TABLE: name="pagg_tab3_p2" schema="" table="pagg_tab3_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab3_p2 PARTITION OF pagg_tab3 FOR VALUES IN ('B', 'A')" +== 461 +-- truncate_limit: 100 +INSERT INTO pagg_tab3 SELECT i % 4 + 1, substr('abAB', (i % 4) + 1 , 1) FROM generate_series(0, 19) i +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DML +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_tab3 SELECT ... FROM generate_series(0, 19) i" +== 462 +-- truncate_limit: 100 +ANALYZE pagg_tab3 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab3" +== 463 +-- truncate_limit: 100 +SET enable_partitionwise_aggregate TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_aggregate TO FALSE" +== 464 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT upper(c COLLATE case_insensitive), count(c) FROM pagg_tab3 GROUP BY c ..." +== 465 +-- truncate_limit: 100 +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab3 GROUP BY c COLLATE case_insensitive ORDER BY 1" +== 466 +-- truncate_limit: 100 +-- No "full" partitionwise aggregation allowed, though "partial" is allowed. +SET enable_partitionwise_aggregate TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_aggregate TO TRUE" +== 467 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT upper(c COLLATE case_insensitive), count(c) FROM pagg_tab3 GROUP BY c ..." +== 468 +-- truncate_limit: 100 +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab3 GROUP BY c COLLATE case_insensitive ORDER BY 1" +== 469 +-- truncate_limit: 100 +-- OK to use full partitionwise aggregate after changing the GROUP BY column's +-- collation to be the same as that of the partition key. +EXPLAIN (COSTS OFF) +SELECT c collate "C", count(c) FROM pagg_tab3 GROUP BY c collate "C" ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c COLLATE \"C\", count(c) FROM pagg_tab3 GROUP BY c COLLATE \"C\" ORDER BY 1" +== 470 +-- truncate_limit: 100 +SELECT c collate "C", count(c) FROM pagg_tab3 GROUP BY c collate "C" ORDER BY 1 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c COLLATE \"C\", count(c) FROM pagg_tab3 GROUP BY c COLLATE \"C\" ORDER BY 1" +== 471 +-- truncate_limit: 100 +-- Partitionwise join should not be allowed too when the collation used by the +-- join keys doesn't match the partition key collation. +SET enable_partitionwise_join TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO FALSE" +== 472 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c G..." +== 473 +-- truncate_limit: 100 +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE \"C\"" +== 474 +-- truncate_limit: 100 +SET enable_partitionwise_join TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO TRUE" +== 475 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c G..." +== 476 +-- truncate_limit: 100 +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE \"C\"" +== 477 +-- truncate_limit: 100 +-- OK when the join clause uses the same collation as the partition key. +EXPLAIN (COSTS OFF) +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.c COLLATE \"C\", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t..." +== 478 +-- truncate_limit: 100 +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE \"C\" GROUP BY t1.c COLLATE \"..." +== 479 +-- truncate_limit: 100 +SET enable_partitionwise_join TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO FALSE" +== 480 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.c COLLATE \"C\", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t..." +== 481 +-- truncate_limit: 100 +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C" +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=Select +ALIAS: "t1"="pagg_tab3" +ALIAS: "t2"="pagg_tab3" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE \"C\" GROUP BY t1.c COLLATE \"..." +== 482 +-- truncate_limit: 100 +DROP TABLE pagg_tab3 +-- +TABLE: name="pagg_tab3" schema="" table="pagg_tab3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pagg_tab3" +== 483 +-- truncate_limit: 100 +RESET enable_partitionwise_aggregate +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_partitionwise_aggregate" +== 484 +-- truncate_limit: 100 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers_per_gather" +== 485 +-- truncate_limit: 100 +RESET enable_incremental_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_incremental_sort" +== 486 +-- truncate_limit: 100 +-- Check that DEFAULT expressions in SQL/JSON functions use the same collation +-- as the RETURNING type. Mismatched collations should raise an error. +CREATE DOMAIN d1 AS text COLLATE case_insensitive +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN d1 AS text COLLATE case_insensitive" +== 487 +-- truncate_limit: 100 +CREATE DOMAIN d2 AS text COLLATE "C" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN d2 AS text COLLATE \"C\"" +== 488 +-- truncate_limit: 100 +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT ('C' COLLATE "C") COLLATE case_insensitive ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 489 +-- truncate_limit: 100 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT 'C' ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": \"A\"}' , '$.a' RETURNING d1 DEFAULT 'C' ON EMPTY) = 'a'" +== 490 +-- truncate_limit: 100 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT 'C'::d2 ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": \"A\"}' , '$.a' RETURNING d1 DEFAULT 'C'::d2 ON EMPTY) = 'a'" +== 491 +-- truncate_limit: 100 +-- error +SELECT JSON_VALUE('{"a": "A"}', '$.a' RETURNING d1 DEFAULT 'C' COLLATE "C" ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": \"A\"}' , '$.a' RETURNING d1 DEFAULT 'C' COLLATE \"C\" ON EMPTY) = 'a'" +== 492 +-- truncate_limit: 100 +-- error +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A' ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": \"A\"}' , '$.c' RETURNING d1 DEFAULT 'A' ON EMPTY) = 'a'" +== 493 +-- truncate_limit: 100 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A' COLLATE case_insensitive ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 494 +-- truncate_limit: 100 +-- true +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A'::d2 ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": \"A\"}' , '$.c' RETURNING d1 DEFAULT 'A'::d2 ON EMPTY) = 'a'" +== 495 +-- truncate_limit: 100 +-- error +SELECT JSON_VALUE('{"a": "A"}', '$.c' RETURNING d1 DEFAULT 'A' COLLATE "C" ON EMPTY) = 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": \"A\"}' , '$.c' RETURNING d1 DEFAULT 'A' COLLATE \"C\" ON EMPTY) = 'a'" +== 496 +-- truncate_limit: 100 +-- error +DROP DOMAIN d1, d2 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN d1, d2" +== 497 +-- truncate_limit: 100 +-- cleanup +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 498 +-- truncate_limit: 100 +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 499 +-- truncate_limit: 100 +DROP SCHEMA collate_tests CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA collate_tests CASCADE" +== 500 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 501 +-- truncate_limit: 100 +-- leave a collation for pg_upgrade test +CREATE COLLATION coll_icu_upgrade FROM "und-x-icu" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_icu_upgrade FROM \"und-x-icu\"" diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json new file mode 100644 index 0000000..648a6d3 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json @@ -0,0 +1,207 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.test b/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.test new file mode 100644 index 0000000..08f5914 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.test @@ -0,0 +1,1673 @@ +== 001 +-- truncate_limit: 100 +/* + * This test is for Linux/glibc systems and assumes that a full set of + * locales is installed. It must be run in a database with UTF-8 encoding, + * because other encodings don't support all the characters used. + */ + +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR + version() !~ 'linux-gnu' + AS skip_test +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +FILTER: schema="" table="" column="collencoding" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 002 +-- truncate_limit: 100 +SET client_encoding TO UTF8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_encoding TO utf8" +== 003 +-- truncate_limit: 100 +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA collate_tests" +== 004 +-- truncate_limit: 100 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO collate_tests" +== 005 +-- truncate_limit: 100 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en_US" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test1 (a int, b text NOT NULL COLLATE \"en_US\")" +== 006 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int, b text COLLATE \"ja_JP.eucjp\")" +== 007 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int, b text COLLATE foo)" +== 008 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int COLLATE "en_US", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int COLLATE \"en_US\", b text)" +== 009 +-- truncate_limit: 100 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_like (LIKE collate_test1)" +== 010 +-- truncate_limit: 100 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv_SE" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test2 (a int, b text COLLATE \"sv_SE\")" +== 011 +-- truncate_limit: 100 +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +) +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test3 (a int, b text COLLATE \"C\")" +== 012 +-- truncate_limit: 100 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC')" +== 013 +-- truncate_limit: 100 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test2 SELECT * FROM collate_test1" +== 014 +-- truncate_limit: 100 +INSERT INTO collate_test3 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test3 SELECT * FROM collate_test1" +== 015 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b >= 'bbc'" +== 016 +-- truncate_limit: 100 +SELECT * FROM collate_test2 WHERE b >= 'bbc' +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 WHERE b >= 'bbc'" +== 017 +-- truncate_limit: 100 +SELECT * FROM collate_test3 WHERE b >= 'bbc' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 WHERE b >= 'bbc'" +== 018 +-- truncate_limit: 100 +SELECT * FROM collate_test3 WHERE b >= 'BBC' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 WHERE b >= 'BBC'" +== 019 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc'" +== 020 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE \"C\"" +== 021 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc' COLLATE \"C\"" +== 022 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en_US" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc' COLLATE \"en_US\"" +== 023 +-- truncate_limit: 100 +CREATE DOMAIN testdomain_sv AS text COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_sv AS text COLLATE \"sv_SE\"" +== 024 +-- truncate_limit: 100 +CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_i AS int COLLATE \"sv_SE\"" +== 025 +-- truncate_limit: 100 +-- fails +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test4 (a int, b testdomain_sv)" +== 026 +-- truncate_limit: 100 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test4 SELECT * FROM collate_test1" +== 027 +-- truncate_limit: 100 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test4 ORDER BY b" +== 028 +-- truncate_limit: 100 +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en_US" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test5 (a int, b testdomain_sv COLLATE \"en_US\")" +== 029 +-- truncate_limit: 100 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test5 SELECT * FROM collate_test1" +== 030 +-- truncate_limit: 100 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test5 ORDER BY b" +== 031 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b" +== 032 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 ORDER BY b" +== 033 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test3 ORDER BY b" +== 034 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 035 +-- truncate_limit: 100 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 ORDER BY b" +== 036 +-- truncate_limit: 100 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 ORDER BY b" +== 037 +-- truncate_limit: 100 +SELECT * FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 ORDER BY b" +== 038 +-- truncate_limit: 100 +-- constant expression folding +SELECT 'bbc' COLLATE "en_US" > 'äbc' COLLATE "en_US" AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"en_US\" > 'äbc' COLLATE \"en_US\" AS \"true\"" +== 039 +-- truncate_limit: 100 +SELECT 'bbc' COLLATE "sv_SE" > 'äbc' COLLATE "sv_SE" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"sv_SE\" > 'äbc' COLLATE \"sv_SE\" AS \"false\"" +== 040 +-- truncate_limit: 100 +-- upper/lower + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "en_US", + y text COLLATE "tr_TR" +) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test10 (a int, x text COLLATE \"en_US\", y text COLLATE \"tr_TR\")" +== 041 +-- truncate_limit: 100 +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ') +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ')" +== 042 +-- truncate_limit: 100 +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10" +== 043 +-- truncate_limit: 100 +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x COLLATE \"C\"), lower(y COLLATE \"C\") FROM collate_test10" +== 044 +-- truncate_limit: 100 +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a" +== 045 +-- truncate_limit: 100 +-- LIKE/ILIKE + +SELECT * FROM collate_test1 WHERE b LIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE 'abc'" +== 046 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b LIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE 'abc%'" +== 047 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b LIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE '%bc%'" +== 048 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'abc'" +== 049 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'abc%'" +== 050 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE '%bc%'" +== 051 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "en_US" ILIKE '%KI%' AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"en_US\" ILIKE '%KI%' AS \"true\"" +== 052 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "tr_TR" ILIKE '%KI%' AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"tr_TR\" ILIKE '%KI%' AS \"false\"" +== 053 +-- truncate_limit: 100 +SELECT 'bıt' ILIKE 'BIT' COLLATE "en_US" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ILIKE 'BIT' COLLATE \"en_US\" AS \"false\"" +== 054 +-- truncate_limit: 100 +SELECT 'bıt' ILIKE 'BIT' COLLATE "tr_TR" AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ILIKE 'BIT' COLLATE \"tr_TR\" AS \"true\"" +== 055 +-- truncate_limit: 100 +-- The following actually exercises the selectivity estimation for ILIKE. +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ILIKE 'abc%'" +== 056 +-- truncate_limit: 100 +-- regular expressions + +SELECT * FROM collate_test1 WHERE b ~ '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ '^abc$'" +== 057 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~ '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ '^abc'" +== 058 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~ 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ 'bc'" +== 059 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* '^abc$'" +== 060 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* '^abc'" +== 061 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* 'bc'" +== 062 +-- truncate_limit: 100 +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en_US" +) +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test6 (a int, b text COLLATE \"en_US\")" +== 063 +-- truncate_limit: 100 +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, 'äbç'), (10, 'ÄBÇ') +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test6 VALUES (...)" +== 064 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test6" +== 065 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "en_US" ~* 'KI' AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"en_US\" ~* 'KI' AS \"true\"" +== 066 +-- truncate_limit: 100 +SELECT 'Türkiye' COLLATE "tr_TR" ~* 'KI' AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Türkiye' COLLATE \"tr_TR\" ~* 'KI' AS \"false\"" +== 067 +-- truncate_limit: 100 +SELECT 'bıt' ~* 'BIT' COLLATE "en_US" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ~* 'BIT' COLLATE \"en_US\" AS \"false\"" +== 068 +-- truncate_limit: 100 +SELECT 'bıt' ~* 'BIT' COLLATE "tr_TR" AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bıt' ~* 'BIT' COLLATE \"tr_TR\" AS \"true\"" +== 069 +-- truncate_limit: 100 +-- The following actually exercises the selectivity estimation for ~*. +SELECT relname FROM pg_class WHERE relname ~* '^abc' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ~* '^abc'" +== 070 +-- truncate_limit: 100 +-- to_char + +SET lc_time TO 'tr_TR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET lc_time TO \"tr_TR\"" +== 071 +-- truncate_limit: 100 +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2010-02-01'::date, 'DD TMMON YYYY')" +== 072 +-- truncate_limit: 100 +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY' COLLATE "tr_TR") +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2010-02-01'::date, 'DD TMMON YYYY' COLLATE \"tr_TR\")" +== 073 +-- truncate_limit: 100 +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2010-04-01'::date, 'DD TMMON YYYY')" +== 074 +-- truncate_limit: 100 +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY' COLLATE "tr_TR") +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2010-04-01'::date, 'DD TMMON YYYY' COLLATE \"tr_TR\")" +== 075 +-- truncate_limit: 100 +-- to_date + +SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY')" +== 076 +-- truncate_limit: 100 +SELECT to_date('01 Şub 2010', 'DD TMMON YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('01 Şub 2010', 'DD TMMON YYYY')" +== 077 +-- truncate_limit: 100 +SELECT to_date('1234567890ab 2010', 'TMMONTH YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('1234567890ab 2010', 'TMMONTH YYYY')" +== 078 +-- truncate_limit: 100 +-- fail + + +-- backwards parsing + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc'" +== 079 +-- truncate_limit: 100 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 080 +-- truncate_limit: 100 +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10 +-- +TABLE: name="collview3" schema="" table="collview3" ctx=DDL +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE \"C\") FROM collate_test10" +== 081 +-- truncate_limit: 100 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'collview%' ORDER BY 1" +== 082 +-- truncate_limit: 100 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test1 ORDER BY 2" +== 083 +-- truncate_limit: 100 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test2 ORDER BY 2" +== 084 +-- truncate_limit: 100 +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test3 ORDER BY 2" +== 085 +-- truncate_limit: 100 +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(COALESCE(x, 'foo')), lower(COALESCE(y, 'foo')) FROM collate_test10" +== 086 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test1 ORDER BY 3" +== 087 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test2 ORDER BY 3" +== 088 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test3 ORDER BY 3" +== 089 +-- truncate_limit: 100 +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, x, y, lower(GREATEST(x, 'foo')), lower(GREATEST(y, 'foo')) FROM collate_test10" +== 090 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test1 ORDER BY 2" +== 091 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test2 ORDER BY 2" +== 092 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test3 ORDER BY 2" +== 093 +-- truncate_limit: 100 +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(NULLIF(x, 'foo')), lower(NULLIF(y, 'foo')) FROM collate_test10" +== 094 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2" +== 095 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2" +== 096 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2" +== 097 +-- truncate_limit: 100 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain AS text" +== 098 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test1 ORDER BY 2" +== 099 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test2 ORDER BY 2" +== 100 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test3 ORDER BY 2" +== 101 +-- truncate_limit: 100 +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2" +== 102 +-- truncate_limit: 100 +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10" +== 103 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test1" +== 104 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test2" +== 105 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test3" +== 106 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test1" +== 107 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test2" +== 108 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test3" +== 109 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2" +== 110 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2" +== 111 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test3 WHERE ... INTERSECT SELECT ... FROM collate_test3 WHERE ... ORDER BY 2" +== 112 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2" +== 113 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2" +== 114 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3" +== 115 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2" +== 116 +-- truncate_limit: 100 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b COLLATE \"C\" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2" +== 117 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2" +== 118 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2" +== 119 +-- truncate_limit: 100 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3" +== 120 +-- truncate_limit: 100 +-- fail + +-- ideally this would be a parse-time error, but for now it must be run-time: +select x < y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x < y FROM collate_test10" +== 121 +-- truncate_limit: 100 +-- fail +select x || y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x || y FROM collate_test10" +== 122 +-- truncate_limit: 100 +-- ok, because || is not collation aware +select x, y from collate_test10 order by x || y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x, y FROM collate_test10 ORDER BY x || y" +== 123 +-- truncate_limit: 100 +-- not so ok + +-- collation mismatch between recursive and non-recursive term +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "en_US"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "de_DE" FROM foo WHERE length(x) < 10) +SELECT * FROM foo +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(x) AS (...) SELECT * FROM foo" +== 124 +-- truncate_limit: 100 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 125 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test1 ORDER BY 2" +== 126 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test2 ORDER BY 2" +== 127 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test3 ORDER BY 2" +== 128 +-- truncate_limit: 100 +-- 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 $$ +-- +FUNCTION: name="mylt" function="mylt" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt(text, text) RETURNS boolean LANGUAGE sql AS $$ select $1 < $2 $$" +== 129 +-- truncate_limit: 100 +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$ +-- +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt_noninline(text, text) RETURNS boolean LANGUAGE sql AS $$ select $1 < $2 limi..." +== 130 +-- truncate_limit: 100 +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$ +-- +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt_plpgsql(text, text) RETURNS boolean LANGUAGE plpgsql AS $$ begin return $1 <..." +== 131 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test1 a, collate_test1 b ORDER BY a.b, b.b" +== 132 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test1 a, collate_test1 b ORDER BY a.b, b.b" +== 133 +-- truncate_limit: 100 +-- 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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt2(x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$\ndeclare\n xx text :=..." +== 134 +-- truncate_limit: 100 +SELECT mylt2('a', 'B' collate "en_US") as t, mylt2('a', 'B' collate "C") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"en_US\") AS t, mylt2('a', 'B' COLLATE \"C\") AS f" +== 135 +-- truncate_limit: 100 +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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION mylt2(x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$\ndeclare\n ..." +== 136 +-- truncate_limit: 100 +SELECT mylt2('a', 'B') as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B') AS f" +== 137 +-- truncate_limit: 100 +SELECT mylt2('a', 'B' collate "C") as fail +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"C\") AS fail" +== 138 +-- truncate_limit: 100 +-- conflicting collations +SELECT mylt2('a', 'B' collate "POSIX") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"POSIX\") AS f" +== 139 +-- truncate_limit: 100 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1" +== 140 +-- truncate_limit: 100 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1" +== 141 +-- truncate_limit: 100 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1" +== 142 +-- truncate_limit: 100 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dup(anyelement) RETURNS anyelement AS $$select $1$$ LANGUAGE sql" +== 143 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test1 ORDER BY 2" +== 144 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test2 ORDER BY 2" +== 145 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test3 ORDER BY 2" +== 146 +-- truncate_limit: 100 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx1 ON collate_test1 USING btree (b)" +== 147 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx2 ON collate_test1 USING btree (b COLLATE \"C\")" +== 148 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx3 ON collate_test1 USING btree ((b COLLATE \"C\"))" +== 149 +-- truncate_limit: 100 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx4 ON collate_test1 USING btree (((b || 'foo') COLLATE \"POSIX\"))" +== 150 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx5 ON collate_test1 USING btree (a COLLATE \"C\")" +== 151 +-- truncate_limit: 100 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx6 ON collate_test1 USING btree ((a COLLATE \"C\"))" +== 152 +-- truncate_limit: 100 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE ... ORDER BY 1" +== 153 +-- truncate_limit: 100 +-- schema manipulation commands + +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_role" +== 154 +-- truncate_limit: 100 +CREATE SCHEMA test_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_schema" +== 155 +-- truncate_limit: 100 +-- We need to do this this way to cope with varying names for encodings: +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (locale = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n EXECUTE 'CREATE COLLATION test0 (locale = ' ||\n quote_literal((SELECT datc..." +== 156 +-- truncate_limit: 100 +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test0 FROM \"C\"" +== 157 +-- truncate_limit: 100 +-- fail, duplicate name +CREATE COLLATION IF NOT EXISTS test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION IF NOT EXISTS test0 FROM \"C\"" +== 158 +-- truncate_limit: 100 +-- ok, skipped +CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo')" +== 159 +-- truncate_limit: 100 +-- ok, skipped +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (lc_collate = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || + ', lc_ctype = ' || + quote_literal((SELECT datctype FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||\n quote_literal((SELECT ..." +== 160 +-- truncate_limit: 100 +CREATE COLLATION test3 (lc_collate = 'en_US.utf8') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test3 (lc_collate = 'en_US.utf8')" +== 161 +-- truncate_limit: 100 +-- fail, need lc_ctype +CREATE COLLATION testx (locale = 'nonsense') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testx (locale = 'nonsense')" +== 162 +-- truncate_limit: 100 +-- fail + +CREATE COLLATION test4 FROM nonsense +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test4 FROM nonsense" +== 163 +-- truncate_limit: 100 +CREATE COLLATION test5 FROM test0 +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test5 FROM test0" +== 164 +-- truncate_limit: 100 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1" +== 165 +-- truncate_limit: 100 +ALTER COLLATION test1 RENAME TO test11 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test1 RENAME TO test11" +== 166 +-- truncate_limit: 100 +ALTER COLLATION test0 RENAME TO test11 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test0 RENAME TO test11" +== 167 +-- truncate_limit: 100 +-- fail +ALTER COLLATION test1 RENAME TO test22 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test1 RENAME TO test22" +== 168 +-- truncate_limit: 100 +-- fail + +ALTER COLLATION test11 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER COLLATION test11 OWNER TO regress_test_role" +== 169 +-- truncate_limit: 100 +ALTER COLLATION test11 OWNER TO nonsense +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER COLLATION test11 OWNER TO nonsense" +== 170 +-- truncate_limit: 100 +ALTER COLLATION test11 SET SCHEMA test_schema +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER COLLATION test11 SET SCHEMA test_schema" +== 171 +-- truncate_limit: 100 +COMMENT ON COLLATION test0 IS 'US English' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLLATION test0 IS 'US English'" +== 172 +-- truncate_limit: 100 +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_collation JOIN pg_namespace ON collnamespace = pg_namespace.oid WHERE ... ORDE..." +== 173 +-- truncate_limit: 100 +DROP COLLATION test0, test_schema.test11, test5 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0, test_schema.test11, test5" +== 174 +-- truncate_limit: 100 +DROP COLLATION test0 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0" +== 175 +-- truncate_limit: 100 +-- fail +DROP COLLATION IF EXISTS test0 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION IF EXISTS test0" +== 176 +-- truncate_limit: 100 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT collname FROM pg_collation WHERE collname LIKE 'test%'" +== 177 +-- truncate_limit: 100 +DROP SCHEMA test_schema +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_schema" +== 178 +-- truncate_limit: 100 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role" +== 179 +-- truncate_limit: 100 +-- ALTER + +ALTER COLLATION "en_US" REFRESH VERSION +-- +STMT: AlterCollationStmt +TRUNCATED: "ALTER COLLATION \"en_US\" REFRESH VERSION" +== 180 +-- truncate_limit: 100 +-- also test for database while we are here +SELECT current_database() AS datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_database() AS datname" +== 181 +-- truncate_limit: 100 +ALTER DATABASE :"datname" REFRESH COLLATION VERSION +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 182 +-- truncate_limit: 100 +-- dependencies + +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test0 FROM \"C\"" +== 183 +-- truncate_limit: 100 +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0) +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0)" +== 184 +-- truncate_limit: 100 +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0" +== 185 +-- truncate_limit: 100 +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0)" +== 186 +-- truncate_limit: 100 +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo +-- +TABLE: name="collate_dep_test3" schema="" table="collate_dep_test3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collate_dep_test3 AS SELECT 'foo'::text COLLATE test0 AS foo" +== 187 +-- truncate_limit: 100 +CREATE TABLE collate_dep_test4t (a int, b text) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_dep_test4t (a int, b text)" +== 188 +-- truncate_limit: 100 +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_dep_test4i ON collate_dep_test4t USING btree (b COLLATE test0)" +== 189 +-- truncate_limit: 100 +DROP COLLATION test0 RESTRICT +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0" +== 190 +-- truncate_limit: 100 +-- fail +DROP COLLATION test0 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0 CASCADE" +== 191 +-- truncate_limit: 100 +DROP TABLE collate_dep_test1, collate_dep_test4t +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE collate_dep_test1, collate_dep_test4t" +== 192 +-- truncate_limit: 100 +DROP TYPE collate_dep_test2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE collate_dep_test2" +== 193 +-- truncate_limit: 100 +-- test range types and collations + +create type textrange_c as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange_c AS RANGE (subtype = text, \"collation\" = \"C\")" +== 194 +-- truncate_limit: 100 +create type textrange_en_us as range(subtype=text, collation="en_US") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange_en_us AS RANGE (subtype = text, \"collation\" = \"en_US\")" +== 195 +-- truncate_limit: 100 +select textrange_c('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_c" function="textrange_c" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange_c('A', 'Z') @> 'b'::text" +== 196 +-- truncate_limit: 100 +select textrange_en_us('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_en_us" function="textrange_en_us" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange_en_us('A', 'Z') @> 'b'::text" +== 197 +-- truncate_limit: 100 +drop type textrange_c +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange_c" +== 198 +-- truncate_limit: 100 +drop type textrange_en_us +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange_en_us" +== 199 +-- truncate_limit: 100 +-- standard collations + +SELECT * FROM collate_test2 ORDER BY b COLLATE UCS_BASIC +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 ORDER BY b COLLATE ucs_basic" +== 200 +-- truncate_limit: 100 +-- nondeterministic collations +-- (not supported with libc provider) + +CREATE COLLATION ctest_det (locale = 'en_US.utf8', deterministic = true) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION ctest_det (locale = 'en_US.utf8', deterministic = true)" +== 201 +-- truncate_limit: 100 +CREATE COLLATION ctest_nondet (locale = 'en_US.utf8', deterministic = false) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION ctest_nondet (locale = 'en_US.utf8', deterministic = false)" +== 202 +-- truncate_limit: 100 +-- cleanup +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 203 +-- truncate_limit: 100 +DROP SCHEMA collate_tests CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA collate_tests CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.metadata.json new file mode 100644 index 0000000..267f283 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.metadata.json @@ -0,0 +1,148 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.test b/parser/testdata/summary_truncate/postgres_regress/collate.test new file mode 100644 index 0000000..c3416c6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.test @@ -0,0 +1,1198 @@ +== 001 +-- truncate_limit: 100 +/* + * This test is intended to pass on all platforms supported by Postgres. + * We can therefore only assume that the default, C, and POSIX collations + * are available --- and since the regression tests are often run in a + * C-locale database, these may well all have the same behavior. But + * fortunately, the system doesn't know that and will treat them as + * incompatible collations. It is therefore at least possible to test + * parser behaviors such as collation conflict resolution. This test will, + * however, be more revealing when run in a database with non-C locale, + * since any departure from C sorting behavior will show as a failure. + */ + +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA collate_tests" +== 002 +-- truncate_limit: 100 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO collate_tests" +== 003 +-- truncate_limit: 100 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "C" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test1 (a int, b text NOT NULL COLLATE \"C\")" +== 004 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int COLLATE "C", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int COLLATE \"C\", b text)" +== 005 +-- truncate_limit: 100 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_like (LIKE collate_test1)" +== 006 +-- truncate_limit: 100 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "POSIX" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test2 (a int, b text COLLATE \"POSIX\")" +== 007 +-- truncate_limit: 100 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'Abc'), (3, 'bbc'), (4, 'ABD') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'Abc'), (3, 'bbc'), (4, 'ABD')" +== 008 +-- truncate_limit: 100 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test2 SELECT * FROM collate_test1" +== 009 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'abc'" +== 010 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b >= 'abc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b >= 'abc' COLLATE \"C\"" +== 011 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'abc' COLLATE \"C\"" +== 012 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "POSIX" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc' COLLATE \"POSIX\"" +== 013 +-- truncate_limit: 100 +-- fail + +CREATE DOMAIN testdomain_p AS text COLLATE "POSIX" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_p AS text COLLATE \"POSIX\"" +== 014 +-- truncate_limit: 100 +CREATE DOMAIN testdomain_i AS int COLLATE "POSIX" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_i AS int COLLATE \"POSIX\"" +== 015 +-- truncate_limit: 100 +-- fail +CREATE TABLE collate_test4 ( + a int, + b testdomain_p +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test4 (a int, b testdomain_p)" +== 016 +-- truncate_limit: 100 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test4 SELECT * FROM collate_test1" +== 017 +-- truncate_limit: 100 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test4 ORDER BY b" +== 018 +-- truncate_limit: 100 +CREATE TABLE collate_test5 ( + a int, + b testdomain_p COLLATE "C" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test5 (a int, b testdomain_p COLLATE \"C\")" +== 019 +-- truncate_limit: 100 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test5 SELECT * FROM collate_test1" +== 020 +-- truncate_limit: 100 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test5 ORDER BY b" +== 021 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b" +== 022 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 ORDER BY b" +== 023 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 024 +-- truncate_limit: 100 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 ORDER BY b" +== 025 +-- truncate_limit: 100 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 ORDER BY b" +== 026 +-- truncate_limit: 100 +-- constant expression folding +SELECT 'bbc' COLLATE "C" > 'Abc' COLLATE "C" AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"C\" > 'Abc' COLLATE \"C\" AS \"true\"" +== 027 +-- truncate_limit: 100 +SELECT 'bbc' COLLATE "POSIX" < 'Abc' COLLATE "POSIX" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"POSIX\" < 'Abc' COLLATE \"POSIX\" AS \"false\"" +== 028 +-- truncate_limit: 100 +-- upper/lower + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "C", + y text COLLATE "POSIX" +) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test10 (a int, x text COLLATE \"C\", y text COLLATE \"POSIX\")" +== 029 +-- truncate_limit: 100 +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ') +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ')" +== 030 +-- truncate_limit: 100 +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10" +== 031 +-- truncate_limit: 100 +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x COLLATE \"C\"), lower(y COLLATE \"C\") FROM collate_test10" +== 032 +-- truncate_limit: 100 +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a" +== 033 +-- truncate_limit: 100 +-- backwards parsing + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc'" +== 034 +-- truncate_limit: 100 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 035 +-- truncate_limit: 100 +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collview3" schema="" table="collview3" ctx=DDL +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE \"POSIX\") FROM collate_test10" +== 036 +-- truncate_limit: 100 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'collview%' ORDER BY 1" +== 037 +-- truncate_limit: 100 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test1 ORDER BY 2" +== 038 +-- truncate_limit: 100 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test2 ORDER BY 2" +== 039 +-- truncate_limit: 100 +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(COALESCE(x, 'foo')), lower(COALESCE(y, 'foo')) FROM collate_test10" +== 040 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test1 ORDER BY 3" +== 041 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test2 ORDER BY 3" +== 042 +-- truncate_limit: 100 +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, x, y, lower(GREATEST(x, 'foo')), lower(GREATEST(y, 'foo')) FROM collate_test10" +== 043 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test1 ORDER BY 2" +== 044 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test2 ORDER BY 2" +== 045 +-- truncate_limit: 100 +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(NULLIF(x, 'foo')), lower(NULLIF(y, 'foo')) FROM collate_test10" +== 046 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2" +== 047 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2" +== 048 +-- truncate_limit: 100 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain AS text" +== 049 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test1 ORDER BY 2" +== 050 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test2 ORDER BY 2" +== 051 +-- truncate_limit: 100 +SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2" +== 052 +-- truncate_limit: 100 +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10" +== 053 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test1" +== 054 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test2" +== 055 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test1" +== 056 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test2" +== 057 +-- truncate_limit: 100 +-- In aggregates, ORDER BY expressions don't affect aggregate's collation +SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT string_agg(x COLLATE \"C\", y COLLATE \"POSIX\") FROM collate_test10" +== 058 +-- truncate_limit: 100 +-- fail +SELECT array_agg(x COLLATE "C" ORDER BY y COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(x COLLATE \"C\" ORDER BY y COLLATE \"POSIX\") FROM collate_test10" +== 059 +-- truncate_limit: 100 +SELECT array_agg(a ORDER BY x COLLATE "C", y COLLATE "POSIX") FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(a ORDER BY x COLLATE \"C\", y COLLATE \"POSIX\") FROM collate_test10" +== 060 +-- truncate_limit: 100 +SELECT array_agg(a ORDER BY x||y) FROM collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(a ORDER BY x || y) FROM collate_test10" +== 061 +-- truncate_limit: 100 +-- fail + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2" +== 062 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2" +== 063 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test2 WHERE ... INTERSECT SELECT ... FROM collate_test2 WHERE ... ORDER BY 2" +== 064 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2" +== 065 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2" +== 066 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2" +== 067 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2" +== 068 +-- truncate_limit: 100 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b COLLATE \"C\" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2" +== 069 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test2 ORDER BY 2" +== 070 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2" +== 071 +-- truncate_limit: 100 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2" +== 072 +-- truncate_limit: 100 +-- fail + +-- ideally this would be a parse-time error, but for now it must be run-time: +select x < y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x < y FROM collate_test10" +== 073 +-- truncate_limit: 100 +-- fail +select x || y from collate_test10 +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x || y FROM collate_test10" +== 074 +-- truncate_limit: 100 +-- ok, because || is not collation aware +select x, y from collate_test10 order by x || y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT x, y FROM collate_test10 ORDER BY x || y" +== 075 +-- truncate_limit: 100 +-- not so ok + +-- collation mismatch between recursive and non-recursive term +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "POSIX" FROM foo WHERE length(x) < 10) +SELECT * FROM foo +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(x) AS (...) SELECT * FROM foo" +== 076 +-- truncate_limit: 100 +SELECT a, b, a < b as lt FROM + (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b) +-- +STMT: SelectStmt +TRUNCATED: "SELECT a, b, a < b AS lt FROM (VALUES ('a', 'B'), ('A', 'b' COLLATE \"C\")) v(a, b)" +== 077 +-- truncate_limit: 100 +-- collation mismatch in subselects +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y, x FROM collate_test10) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test10 WHERE NOT (x, y) IN (SELECT y, x FROM collate_test10)" +== 078 +-- truncate_limit: 100 +-- now it works with overrides +SELECT * FROM collate_test10 WHERE (x COLLATE "POSIX", y COLLATE "C") NOT IN (SELECT y, x FROM collate_test10) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test10 WHERE ..." +== 079 +-- truncate_limit: 100 +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y COLLATE "C", x COLLATE "POSIX" FROM collate_test10) +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test10 WHERE NOT (x, y) IN (SELECT ... FROM collate_test10)" +== 080 +-- truncate_limit: 100 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 081 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test1 ORDER BY 2" +== 082 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test2 ORDER BY 2" +== 083 +-- truncate_limit: 100 +-- result of a SQL function + +CREATE FUNCTION vc (text) RETURNS text LANGUAGE sql + AS 'select $1::varchar' +-- +FUNCTION: name="vc" function="vc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION vc(text) RETURNS text LANGUAGE sql AS $$select $1::varchar$$" +== 084 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY a, vc(b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="vc" function="vc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY a, vc(b)" +== 085 +-- truncate_limit: 100 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1" +== 086 +-- truncate_limit: 100 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1" +== 087 +-- truncate_limit: 100 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dup(anyelement) RETURNS anyelement AS $$select $1$$ LANGUAGE sql" +== 088 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test1 ORDER BY 2" +== 089 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test2 ORDER BY 2" +== 090 +-- truncate_limit: 100 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx1 ON collate_test1 USING btree (b)" +== 091 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "POSIX") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx2 ON collate_test1 USING btree (b COLLATE \"POSIX\")" +== 092 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx3 ON collate_test1 USING btree ((b COLLATE \"POSIX\"))" +== 093 +-- truncate_limit: 100 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx4 ON collate_test1 USING btree (((b || 'foo') COLLATE \"POSIX\"))" +== 094 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx5 ON collate_test1 USING btree (a COLLATE \"POSIX\")" +== 095 +-- truncate_limit: 100 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx6 ON collate_test1 USING btree ((a COLLATE \"POSIX\"))" +== 096 +-- truncate_limit: 100 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE ... ORDER BY 1" +== 097 +-- truncate_limit: 100 +-- foreign keys + +-- force indexes and mergejoins to be used for FK checking queries, +-- else they might not exercise collation-dependent operators +SET enable_seqscan TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO 0" +== 098 +-- truncate_limit: 100 +SET enable_hashjoin TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO 0" +== 099 +-- truncate_limit: 100 +SET enable_nestloop TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO 0" +== 100 +-- truncate_limit: 100 +CREATE TABLE collate_test20 (f1 text COLLATE "C" PRIMARY KEY) +-- +TABLE: name="collate_test20" schema="" table="collate_test20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test20 (f1 text PRIMARY KEY COLLATE \"C\")" +== 101 +-- truncate_limit: 100 +INSERT INTO collate_test20 VALUES ('foo'), ('bar') +-- +TABLE: name="collate_test20" schema="" table="collate_test20" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test20 VALUES ('foo'), ('bar')" +== 102 +-- truncate_limit: 100 +CREATE TABLE collate_test21 (f2 text COLLATE "POSIX" REFERENCES collate_test20) +-- +TABLE: name="collate_test21" schema="" table="collate_test21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test21 (f2 text REFERENCES collate_test20 COLLATE \"POSIX\")" +== 103 +-- truncate_limit: 100 +INSERT INTO collate_test21 VALUES ('foo'), ('bar') +-- +TABLE: name="collate_test21" schema="" table="collate_test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test21 VALUES ('foo'), ('bar')" +== 104 +-- truncate_limit: 100 +INSERT INTO collate_test21 VALUES ('baz') +-- +TABLE: name="collate_test21" schema="" table="collate_test21" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test21 VALUES ('baz')" +== 105 +-- truncate_limit: 100 +-- fail +CREATE TABLE collate_test22 (f2 text COLLATE "POSIX") +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test22 (f2 text COLLATE \"POSIX\")" +== 106 +-- truncate_limit: 100 +INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz') +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz')" +== 107 +-- truncate_limit: 100 +ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20 +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20" +== 108 +-- truncate_limit: 100 +-- fail +DELETE FROM collate_test22 WHERE f2 = 'baz' +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM collate_test22 WHERE f2 = 'baz'" +== 109 +-- truncate_limit: 100 +ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20 +-- +TABLE: name="collate_test22" schema="" table="collate_test22" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20" +== 110 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 111 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 112 +-- truncate_limit: 100 +RESET enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 113 +-- truncate_limit: 100 +-- EXPLAIN + +EXPLAIN (COSTS OFF) + SELECT * FROM collate_test10 ORDER BY x, y +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM collate_test10 ORDER BY x, y" +== 114 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) + SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE "C" ASC NULLS FIRST +-- +TABLE: name="collate_test10" schema="" table="collate_test10" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE \"C\" ASC NULLS FIRST" +== 115 +-- truncate_limit: 100 +-- CREATE/DROP COLLATION + +CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION builtin_c (provider = builtin, locale = \"C\")" +== 116 +-- truncate_limit: 100 +SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c" +== 117 +-- truncate_limit: 100 +CREATE COLLATION builtin2 ( PROVIDER = builtin ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION builtin2 (provider = builtin)" +== 118 +-- truncate_limit: 100 +-- fails +CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION builtin2 (provider = builtin, locale = \"en_US\")" +== 119 +-- truncate_limit: 100 +-- fails +CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION builtin2 (provider = builtin, lc_ctype = \"C\", lc_collate = \"C\")" +== 120 +-- truncate_limit: 100 +-- fails + +CREATE COLLATION mycoll1 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION mycoll1 FROM \"C\"" +== 121 +-- truncate_limit: 100 +CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" ) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION mycoll2 (lc_collate = \"POSIX\", lc_ctype = \"POSIX\")" +== 122 +-- truncate_limit: 100 +CREATE COLLATION mycoll3 FROM "default" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION mycoll3 FROM \"default\"" +== 123 +-- truncate_limit: 100 +-- intentionally unsupported + +DROP COLLATION mycoll1 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION mycoll1" +== 124 +-- truncate_limit: 100 +CREATE TABLE collate_test23 (f1 text collate mycoll2) +-- +TABLE: name="collate_test23" schema="" table="collate_test23" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test23 (f1 text COLLATE mycoll2)" +== 125 +-- truncate_limit: 100 +DROP COLLATION mycoll2 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION mycoll2" +== 126 +-- truncate_limit: 100 +-- fail + +-- invalid: non-lowercase quoted identifiers +CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctype" = "POSIX") +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION case_coll (\"Lc_Collate\" = \"POSIX\", \"Lc_Ctype\" = \"POSIX\")" +== 127 +-- truncate_limit: 100 +-- 9.1 bug with useless COLLATE in an expression subject to length coercion + +CREATE TEMP TABLE vctable (f1 varchar(25)) +-- +TABLE: name="vctable" schema="" table="vctable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE vctable (f1 varchar(25))" +== 128 +-- truncate_limit: 100 +INSERT INTO vctable VALUES ('foo' COLLATE "C") +-- +TABLE: name="vctable" schema="" table="vctable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vctable VALUES ('foo' COLLATE \"C\")" +== 129 +-- truncate_limit: 100 +SELECT collation for ('foo') +-- +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT collation for ('foo')" +== 130 +-- truncate_limit: 100 +-- unknown type - null +SELECT collation for ('foo'::text) +-- +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT collation for ('foo'::text)" +== 131 +-- truncate_limit: 100 +SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1))" +== 132 +-- truncate_limit: 100 +-- non-collatable type - error +SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1))" +== 133 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="collate_on_int" schema="" table="collate_on_int" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collate_on_int AS SELECT c1 + 1 AS c1p FROM (SELECT '4' COLLATE \"C\"::int AS c1) ss" +== 134 +-- truncate_limit: 100 +-- Check conflicting or redundant options in CREATE COLLATION +-- LC_COLLATE +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_COLLATE = "NONSENSE", LC_CTYPE = "POSIX") +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (lc_collate = \"POSIX\", lc_collate = \"NONSENSE\", lc_ctype = \"POSIX\")" +== 135 +-- truncate_limit: 100 +-- LC_CTYPE +CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LC_CTYPE = "NONSENSE", LC_COLLATE = "POSIX") +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (lc_ctype = \"POSIX\", lc_ctype = \"NONSENSE\", lc_collate = \"POSIX\")" +== 136 +-- truncate_limit: 100 +-- PROVIDER +CREATE COLLATION coll_dup_chk (PROVIDER = icu, PROVIDER = NONSENSE, LC_COLLATE = "POSIX", LC_CTYPE = "POSIX") +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (provider = icu, provider = nonsense, lc_collate = \"POSIX\", lc_ctyp..." +== 137 +-- truncate_limit: 100 +-- LOCALE +CREATE COLLATION case_sensitive (LOCALE = '', LOCALE = "NONSENSE") +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION case_sensitive (locale = '', locale = \"NONSENSE\")" +== 138 +-- truncate_limit: 100 +-- DETERMINISTIC +CREATE COLLATION coll_dup_chk (DETERMINISTIC = TRUE, DETERMINISTIC = NONSENSE, LOCALE = '') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (deterministic = true, deterministic = nonsense, locale = '')" +== 139 +-- truncate_limit: 100 +-- VERSION +CREATE COLLATION coll_dup_chk (VERSION = '1', VERSION = "NONSENSE", LOCALE = '') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (version = '1', version = \"NONSENSE\", locale = '')" +== 140 +-- truncate_limit: 100 +-- LOCALE conflicts with LC_COLLATE and LC_CTYPE +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_CTYPE = "POSIX", LOCALE = '') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (lc_collate = \"POSIX\", lc_ctype = \"POSIX\", locale = '')" +== 141 +-- truncate_limit: 100 +-- LOCALE conflicts with LC_COLLATE +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LOCALE = '') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (lc_collate = \"POSIX\", locale = '')" +== 142 +-- truncate_limit: 100 +-- LOCALE conflicts with LC_CTYPE +CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LOCALE = '') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (lc_ctype = \"POSIX\", locale = '')" +== 143 +-- truncate_limit: 100 +-- FROM conflicts with any other option +CREATE COLLATION coll_dup_chk (FROM = "C", VERSION = "1") +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION coll_dup_chk (\"from\" = \"C\", version = \"1\")" +== 144 +-- truncate_limit: 100 +|-- +-- 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 +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA collate_tests CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json new file mode 100644 index 0000000..5d34ab7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json @@ -0,0 +1,28 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.utf8.test b/parser/testdata/summary_truncate/postgres_regress/collate.utf8.test new file mode 100644 index 0000000..d7655dd --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.utf8.test @@ -0,0 +1,203 @@ +== 001 +-- truncate_limit: 100 +/* + * This test is for collations and character operations when using the + * builtin provider with the C.UTF-8 locale. + */ + +/* skip test if not UTF8 server encoding */ +SELECT getdatabaseencoding() <> 'UTF8' AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT getdatabaseencoding() <> 'UTF8' AS skip_test" +== 002 +-- truncate_limit: 100 +SET client_encoding TO UTF8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_encoding TO utf8" +== 003 +-- truncate_limit: 100 +|-- +-- Test PG_C_UTF8 +|-- + +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C_UTF8') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION regress_pg_c_utf8 (provider = builtin, locale = 'C_UTF8')" +== 004 +-- truncate_limit: 100 +-- fails +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C.UTF8') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION regress_pg_c_utf8 (provider = builtin, locale = 'C.UTF8')" +== 005 +-- truncate_limit: 100 +DROP COLLATION regress_pg_c_utf8 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION regress_pg_c_utf8" +== 006 +-- truncate_limit: 100 +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C.UTF-8') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION regress_pg_c_utf8 (provider = builtin, locale = 'C.UTF-8')" +== 007 +-- truncate_limit: 100 +CREATE TABLE test_pg_c_utf8 ( + t TEXT COLLATE PG_C_UTF8 +) +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_pg_c_utf8 (t text COLLATE pg_c_utf8)" +== 008 +-- truncate_limit: 100 +INSERT INTO test_pg_c_utf8 VALUES + ('abc DEF 123abc'), + ('ábc sßs ßss DÉF'), + ('DŽxxDŽ džxxDž Džxxdž'), + ('ȺȺȺ'), + ('ⱥⱥⱥ'), + ('ⱥȺ') +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_pg_c_utf8 VALUES (...)" +== 009 +-- truncate_limit: 100 +SELECT + t, lower(t), initcap(t), upper(t), + length(convert_to(t, 'UTF8')) AS t_bytes, + length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes, + length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes, + length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes + FROM test_pg_c_utf8 +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="initcap" function="initcap" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="convert_to" function="convert_to" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_pg_c_utf8" +== 010 +-- truncate_limit: 100 +DROP TABLE test_pg_c_utf8 +-- +TABLE: name="test_pg_c_utf8" schema="" table="test_pg_c_utf8" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_pg_c_utf8" +== 011 +-- truncate_limit: 100 +-- negative test: Final_Sigma not used for builtin locale C.UTF-8 +SELECT lower('ΑΣ' COLLATE PG_C_UTF8) +-- +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lower('ΑΣ' COLLATE pg_c_utf8)" +== 012 +-- truncate_limit: 100 +SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8) +-- +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lower('ΑͺΣͺ' COLLATE pg_c_utf8)" +== 013 +-- truncate_limit: 100 +SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8) +-- +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lower('Α΄Σ΄' COLLATE pg_c_utf8)" +== 014 +-- truncate_limit: 100 +-- properties + +SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'xyz' ~ '[[:alnum:]]' COLLATE pg_c_utf8" +== 015 +-- truncate_limit: 100 +SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'xyz' !~ '[[:upper:]]' COLLATE pg_c_utf8" +== 016 +-- truncate_limit: 100 +SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '@' !~ '[[:alnum:]]' COLLATE pg_c_utf8" +== 017 +-- truncate_limit: 100 +SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '=' ~ '[[:punct:]]' COLLATE pg_c_utf8" +== 018 +-- truncate_limit: 100 +-- symbols are punctuation in posix +SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a8a' ~ '[[:digit:]]' COLLATE pg_c_utf8" +== 019 +-- truncate_limit: 100 +SELECT '൧' !~ '\d' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '൧' !~ E'\\\\d' COLLATE pg_c_utf8" +== 020 +-- truncate_limit: 100 +-- only 0-9 considered digits in posix + +-- case mapping + +SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'xYz' ~* 'XyZ' COLLATE pg_c_utf8" +== 021 +-- truncate_limit: 100 +SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'xAb' ~* '[W-Y]' COLLATE pg_c_utf8" +== 022 +-- truncate_limit: 100 +SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'xAb' !~* '[c-d]' COLLATE pg_c_utf8" +== 023 +-- truncate_limit: 100 +SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Δ' ~* '[γ-λ]' COLLATE pg_c_utf8" +== 024 +-- truncate_limit: 100 +SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'δ' ~* '[Γ-Λ]' COLLATE pg_c_utf8" diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json new file mode 100644 index 0000000..a4f4300 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json @@ -0,0 +1,177 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.test b/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.test new file mode 100644 index 0000000..2a63f6b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.test @@ -0,0 +1,1439 @@ +== 001 +-- truncate_limit: 100 +/* + * This test is meant to run on Windows systems that has successfully + * run pg_import_system_collations(). Also, the database must have + * WIN1252 encoding, because of the locales' own encodings. Because + * of this, some test are lost from UTF-8 version, such as Turkish + * dotted and undotted 'i'. + */ +SELECT getdatabaseencoding() <> 'WIN1252' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE') AND collencoding = pg_char_to_encoding('WIN1252')) <> 3 OR + (version() !~ 'Visual C\+\+' AND version() !~ 'mingw32' AND version() !~ 'windows') + AS skip_test +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_char_to_encoding" function="pg_char_to_encoding" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +FILTER: schema="" table="" column="collencoding" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 002 +-- truncate_limit: 100 +SET client_encoding TO WIN1252 +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_encoding TO win1252" +== 003 +-- truncate_limit: 100 +CREATE SCHEMA collate_tests +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA collate_tests" +== 004 +-- truncate_limit: 100 +SET search_path = collate_tests +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO collate_tests" +== 005 +-- truncate_limit: 100 +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en_US" NOT NULL +) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test1 (a int, b text NOT NULL COLLATE \"en_US\")" +== 006 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int, b text COLLATE \"ja_JP.eucjp\")" +== 007 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo" +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int, b text COLLATE foo)" +== 008 +-- truncate_limit: 100 +CREATE TABLE collate_test_fail ( + a int COLLATE "en_US", + b text +) +-- +TABLE: name="collate_test_fail" schema="" table="collate_test_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_fail (a int COLLATE \"en_US\", b text)" +== 009 +-- truncate_limit: 100 +CREATE TABLE collate_test_like ( + LIKE collate_test1 +) +-- +TABLE: name="collate_test_like" schema="" table="collate_test_like" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test_like (LIKE collate_test1)" +== 010 +-- truncate_limit: 100 +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv_SE" +) +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test2 (a int, b text COLLATE \"sv_SE\")" +== 011 +-- truncate_limit: 100 +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +) +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test3 (a int, b text COLLATE \"C\")" +== 012 +-- truncate_limit: 100 +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, '�bc'), (3, 'bbc'), (4, 'ABC') +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test1 VALUES (1, 'abc'), (2, '�bc'), (3, 'bbc'), (4, 'ABC')" +== 013 +-- truncate_limit: 100 +INSERT INTO collate_test2 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test2 SELECT * FROM collate_test1" +== 014 +-- truncate_limit: 100 +INSERT INTO collate_test3 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test3 SELECT * FROM collate_test1" +== 015 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b >= 'bbc'" +== 016 +-- truncate_limit: 100 +SELECT * FROM collate_test2 WHERE b >= 'bbc' +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 WHERE b >= 'bbc'" +== 017 +-- truncate_limit: 100 +SELECT * FROM collate_test3 WHERE b >= 'bbc' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 WHERE b >= 'bbc'" +== 018 +-- truncate_limit: 100 +SELECT * FROM collate_test3 WHERE b >= 'BBC' +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 WHERE b >= 'BBC'" +== 019 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc'" +== 020 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE \"C\"" +== 021 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc' COLLATE \"C\"" +== 022 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en_US" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc' COLLATE \"en_US\"" +== 023 +-- truncate_limit: 100 +CREATE DOMAIN testdomain_sv AS text COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_sv AS text COLLATE \"sv_SE\"" +== 024 +-- truncate_limit: 100 +CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE" +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain_i AS int COLLATE \"sv_SE\"" +== 025 +-- truncate_limit: 100 +-- fails +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +) +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test4 (a int, b testdomain_sv)" +== 026 +-- truncate_limit: 100 +INSERT INTO collate_test4 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test4 SELECT * FROM collate_test1" +== 027 +-- truncate_limit: 100 +SELECT a, b FROM collate_test4 ORDER BY b +-- +TABLE: name="collate_test4" schema="" table="collate_test4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test4 ORDER BY b" +== 028 +-- truncate_limit: 100 +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en_US" +) +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test5 (a int, b testdomain_sv COLLATE \"en_US\")" +== 029 +-- truncate_limit: 100 +INSERT INTO collate_test5 SELECT * FROM collate_test1 +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=DML +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test5 SELECT * FROM collate_test1" +== 030 +-- truncate_limit: 100 +SELECT a, b FROM collate_test5 ORDER BY b +-- +TABLE: name="collate_test5" schema="" table="collate_test5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test5 ORDER BY b" +== 031 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b" +== 032 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 ORDER BY b" +== 033 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test3 ORDER BY b" +== 034 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 035 +-- truncate_limit: 100 +-- star expansion +SELECT * FROM collate_test1 ORDER BY b +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 ORDER BY b" +== 036 +-- truncate_limit: 100 +SELECT * FROM collate_test2 ORDER BY b +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test2 ORDER BY b" +== 037 +-- truncate_limit: 100 +SELECT * FROM collate_test3 ORDER BY b +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test3 ORDER BY b" +== 038 +-- truncate_limit: 100 +-- constant expression folding +SELECT 'bbc' COLLATE "en_US" > '�bc' COLLATE "en_US" AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"en_US\" > '�bc' COLLATE \"en_US\" AS \"true\"" +== 039 +-- truncate_limit: 100 +SELECT 'bbc' COLLATE "sv_SE" > '�bc' COLLATE "sv_SE" AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' COLLATE \"sv_SE\" > '�bc' COLLATE \"sv_SE\" AS \"false\"" +== 040 +-- truncate_limit: 100 +-- LIKE/ILIKE + +SELECT * FROM collate_test1 WHERE b LIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE 'abc'" +== 041 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b LIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE 'abc%'" +== 042 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b LIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b LIKE '%bc%'" +== 043 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'abc'" +== 044 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE 'abc%'" +== 045 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ILIKE '%bc%'" +== 046 +-- truncate_limit: 100 +-- The following actually exercises the selectivity estimation for ILIKE. +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ILIKE 'abc%'" +== 047 +-- truncate_limit: 100 +-- regular expressions + +SELECT * FROM collate_test1 WHERE b ~ '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ '^abc$'" +== 048 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~ '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ '^abc'" +== 049 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~ 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~ 'bc'" +== 050 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* '^abc$' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* '^abc$'" +== 051 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* '^abc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* '^abc'" +== 052 +-- truncate_limit: 100 +SELECT * FROM collate_test1 WHERE b ~* 'bc' +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM collate_test1 WHERE b ~* 'bc'" +== 053 +-- truncate_limit: 100 +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en_US" +) +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_test6 (a int, b text COLLATE \"en_US\")" +== 054 +-- truncate_limit: 100 +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, '�b�'), (10, '�B�') +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO collate_test6 VALUES (...)" +== 055 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test6" schema="" table="collate_test6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test6" +== 056 +-- truncate_limit: 100 +-- The following actually exercises the selectivity estimation for ~*. +SELECT relname FROM pg_class WHERE relname ~* '^abc' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ~* '^abc'" +== 057 +-- truncate_limit: 100 +-- backwards parsing + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' +-- +TABLE: name="collview1" schema="" table="collview1" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE \"C\" >= 'bbc'" +== 058 +-- truncate_limit: 100 +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C" +-- +TABLE: name="collview2" schema="" table="collview2" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE \"C\"" +== 059 +-- truncate_limit: 100 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'collview%' ORDER BY 1" +== 060 +-- truncate_limit: 100 +-- collation propagation in various expression types + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test1 ORDER BY 2" +== 061 +-- truncate_limit: 100 +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test2 ORDER BY 2" +== 062 +-- truncate_limit: 100 +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, COALESCE(b, 'foo') FROM collate_test3 ORDER BY 2" +== 063 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test1 ORDER BY 3" +== 064 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test2 ORDER BY 3" +== 065 +-- truncate_limit: 100 +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GREATEST(b, 'CCC') FROM collate_test3 ORDER BY 3" +== 066 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test1 ORDER BY 2" +== 067 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test2 ORDER BY 2" +== 068 +-- truncate_limit: 100 +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, NULLIF(b, 'abc') FROM collate_test3 ORDER BY 2" +== 069 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2" +== 070 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2" +== 071 +-- truncate_limit: 100 +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2" +== 072 +-- truncate_limit: 100 +CREATE DOMAIN testdomain AS text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain AS text" +== 073 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test1 ORDER BY 2" +== 074 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test2 ORDER BY 2" +== 075 +-- truncate_limit: 100 +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain FROM collate_test3 ORDER BY 2" +== 076 +-- truncate_limit: 100 +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2" +== 077 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test1" +== 078 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test2" +== 079 +-- truncate_limit: 100 +SELECT min(b), max(b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(b), max(b) FROM collate_test3" +== 080 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test1" +== 081 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test2" +== 082 +-- truncate_limit: 100 +SELECT array_agg(b ORDER BY b) FROM collate_test3 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(b ORDER BY b) FROM collate_test3" +== 083 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2" +== 084 +-- truncate_limit: 100 +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2" +== 085 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test3 WHERE ... INTERSECT SELECT ... FROM collate_test3 WHERE ... ORDER BY 2" +== 086 +-- truncate_limit: 100 +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2" +== 087 +-- truncate_limit: 100 +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2" +== 088 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3" +== 089 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2" +== 090 +-- truncate_limit: 100 +-- fail +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b COLLATE \"C\" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2" +== 091 +-- truncate_limit: 100 +-- ok +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2" +== 092 +-- truncate_limit: 100 +-- fail +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2" +== 093 +-- truncate_limit: 100 +-- fail + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 +-- +TABLE: name="test_u" schema="" table="test_u" ctx=DDL +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3" +== 094 +-- truncate_limit: 100 +-- fail + +-- collation mismatch between recursive and non-recursive term +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "en_US"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "de_DE" FROM foo WHERE length(x) < 10) +SELECT * FROM foo +-- +CTE: "foo" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(x) AS (...) SELECT * FROM foo" +== 095 +-- truncate_limit: 100 +-- casting + +SELECT CAST('42' AS text COLLATE "C") +-- +ERROR: syntax error at or near "COLLATE" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 096 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test1 ORDER BY 2" +== 097 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test2 ORDER BY 2" +== 098 +-- truncate_limit: 100 +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b::varchar FROM collate_test3 ORDER BY 2" +== 099 +-- truncate_limit: 100 +-- 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 $$ +-- +FUNCTION: name="mylt" function="mylt" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt(text, text) RETURNS boolean LANGUAGE sql AS $$ select $1 < $2 $$" +== 100 +-- truncate_limit: 100 +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$ +-- +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt_noninline(text, text) RETURNS boolean LANGUAGE sql AS $$ select $1 < $2 limi..." +== 101 +-- truncate_limit: 100 +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$ +-- +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt_plpgsql(text, text) RETURNS boolean LANGUAGE plpgsql AS $$ begin return $1 <..." +== 102 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test1 a, collate_test1 b ORDER BY a.b, b.b" +== 103 +-- truncate_limit: 100 +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 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +ALIAS: "a"="collate_test1" +ALIAS: "b"="collate_test1" +FUNCTION: name="mylt" function="mylt" schema="" ctx=Call +FUNCTION: name="mylt_noninline" function="mylt_noninline" schema="" ctx=Call +FUNCTION: name="mylt_plpgsql" function="mylt_plpgsql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM collate_test1 a, collate_test1 b ORDER BY a.b, b.b" +== 104 +-- truncate_limit: 100 +-- 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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mylt2(x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$\ndeclare\n xx text :=..." +== 105 +-- truncate_limit: 100 +SELECT mylt2('a', 'B' collate "en_US") as t, mylt2('a', 'B' collate "C") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"en_US\") AS t, mylt2('a', 'B' COLLATE \"C\") AS f" +== 106 +-- truncate_limit: 100 +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 +$$ +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION mylt2(x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$\ndeclare\n ..." +== 107 +-- truncate_limit: 100 +SELECT mylt2('a', 'B') as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B') AS f" +== 108 +-- truncate_limit: 100 +SELECT mylt2('a', 'B' collate "C") as fail +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"C\") AS fail" +== 109 +-- truncate_limit: 100 +-- conflicting collations +SELECT mylt2('a', 'B' collate "POSIX") as f +-- +FUNCTION: name="mylt2" function="mylt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mylt2('a', 'B' COLLATE \"POSIX\") AS f" +== 110 +-- truncate_limit: 100 +-- polymorphism + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1" +== 111 +-- truncate_limit: 100 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1" +== 112 +-- truncate_limit: 100 +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1" +== 113 +-- truncate_limit: 100 +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dup(anyelement) RETURNS anyelement AS $$select $1$$ LANGUAGE sql" +== 114 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test1 ORDER BY 2 +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test1 ORDER BY 2" +== 115 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test2 ORDER BY 2 +-- +TABLE: name="collate_test2" schema="" table="collate_test2" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test2 ORDER BY 2" +== 116 +-- truncate_limit: 100 +SELECT a, dup(b) FROM collate_test3 ORDER BY 2 +-- +TABLE: name="collate_test3" schema="" table="collate_test3" ctx=Select +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, dup(b) FROM collate_test3 ORDER BY 2" +== 117 +-- truncate_limit: 100 +-- indexes + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx1 ON collate_test1 USING btree (b)" +== 118 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx2 ON collate_test1 USING btree (b COLLATE \"C\")" +== 119 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx3 ON collate_test1 USING btree ((b COLLATE \"C\"))" +== 120 +-- truncate_limit: 100 +-- this is different grammatically +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx4 ON collate_test1 USING btree (((b || 'foo') COLLATE \"POSIX\"))" +== 121 +-- truncate_limit: 100 +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C") +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx5 ON collate_test1 USING btree (a COLLATE \"C\")" +== 122 +-- truncate_limit: 100 +-- fail +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")) +-- +TABLE: name="collate_test1" schema="" table="collate_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_test1_idx6 ON collate_test1 USING btree ((a COLLATE \"C\"))" +== 123 +-- truncate_limit: 100 +-- fail + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE ... ORDER BY 1" +== 124 +-- truncate_limit: 100 +-- schema manipulation commands + +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_role" +== 125 +-- truncate_limit: 100 +CREATE SCHEMA test_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_schema" +== 126 +-- truncate_limit: 100 +-- We need to do this this way to cope with varying names for encodings: +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (locale = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n EXECUTE 'CREATE COLLATION test0 (locale = ' ||\n quote_literal((SELECT datc..." +== 127 +-- truncate_limit: 100 +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test0 FROM \"C\"" +== 128 +-- truncate_limit: 100 +-- fail, duplicate name +CREATE COLLATION IF NOT EXISTS test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION IF NOT EXISTS test0 FROM \"C\"" +== 129 +-- truncate_limit: 100 +-- ok, skipped +CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo')" +== 130 +-- truncate_limit: 100 +-- ok, skipped +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (lc_collate = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || + ', lc_ctype = ' || + quote_literal((SELECT datctype FROM pg_database WHERE datname = current_database())) || ');'; +END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||\n quote_literal((SELECT ..." +== 131 +-- truncate_limit: 100 +CREATE COLLATION test3 (lc_collate = 'en_US.utf8') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test3 (lc_collate = 'en_US.utf8')" +== 132 +-- truncate_limit: 100 +-- fail, need lc_ctype +CREATE COLLATION testx (locale = 'nonsense') +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION testx (locale = 'nonsense')" +== 133 +-- truncate_limit: 100 +-- fail + +CREATE COLLATION test4 FROM nonsense +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test4 FROM nonsense" +== 134 +-- truncate_limit: 100 +CREATE COLLATION test5 FROM test0 +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test5 FROM test0" +== 135 +-- truncate_limit: 100 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1" +== 136 +-- truncate_limit: 100 +ALTER COLLATION test1 RENAME TO test11 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test1 RENAME TO test11" +== 137 +-- truncate_limit: 100 +ALTER COLLATION test0 RENAME TO test11 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test0 RENAME TO test11" +== 138 +-- truncate_limit: 100 +-- fail +ALTER COLLATION test1 RENAME TO test22 +-- +STMT: RenameStmt +TRUNCATED: "ALTER COLLATION test1 RENAME TO test22" +== 139 +-- truncate_limit: 100 +-- fail + +ALTER COLLATION test11 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER COLLATION test11 OWNER TO regress_test_role" +== 140 +-- truncate_limit: 100 +ALTER COLLATION test11 OWNER TO nonsense +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER COLLATION test11 OWNER TO nonsense" +== 141 +-- truncate_limit: 100 +ALTER COLLATION test11 SET SCHEMA test_schema +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER COLLATION test11 SET SCHEMA test_schema" +== 142 +-- truncate_limit: 100 +COMMENT ON COLLATION test0 IS 'US English' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLLATION test0 IS 'US English'" +== 143 +-- truncate_limit: 100 +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1 +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_collation JOIN pg_namespace ON collnamespace = pg_namespace.oid WHERE ... ORDE..." +== 144 +-- truncate_limit: 100 +DROP COLLATION test0, test_schema.test11, test5 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0, test_schema.test11, test5" +== 145 +-- truncate_limit: 100 +DROP COLLATION test0 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0" +== 146 +-- truncate_limit: 100 +-- fail +DROP COLLATION IF EXISTS test0 +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION IF EXISTS test0" +== 147 +-- truncate_limit: 100 +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' +-- +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT collname FROM pg_collation WHERE collname LIKE 'test%'" +== 148 +-- truncate_limit: 100 +DROP SCHEMA test_schema +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_schema" +== 149 +-- truncate_limit: 100 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role" +== 150 +-- truncate_limit: 100 +-- ALTER + +ALTER COLLATION "en_US" REFRESH VERSION +-- +STMT: AlterCollationStmt +TRUNCATED: "ALTER COLLATION \"en_US\" REFRESH VERSION" +== 151 +-- truncate_limit: 100 +-- also test for database while we are here +SELECT current_database() AS datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_database() AS datname" +== 152 +-- truncate_limit: 100 +ALTER DATABASE :"datname" REFRESH COLLATION VERSION +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 153 +-- truncate_limit: 100 +-- dependencies + +CREATE COLLATION test0 FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION test0 FROM \"C\"" +== 154 +-- truncate_limit: 100 +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0) +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0)" +== 155 +-- truncate_limit: 100 +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0" +== 156 +-- truncate_limit: 100 +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0)" +== 157 +-- truncate_limit: 100 +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo +-- +TABLE: name="collate_dep_test3" schema="" table="collate_dep_test3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW collate_dep_test3 AS SELECT 'foo'::text COLLATE test0 AS foo" +== 158 +-- truncate_limit: 100 +CREATE TABLE collate_dep_test4t (a int, b text) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE collate_dep_test4t (a int, b text)" +== 159 +-- truncate_limit: 100 +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0) +-- +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX collate_dep_test4i ON collate_dep_test4t USING btree (b COLLATE test0)" +== 160 +-- truncate_limit: 100 +DROP COLLATION test0 RESTRICT +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0" +== 161 +-- truncate_limit: 100 +-- fail +DROP COLLATION test0 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION test0 CASCADE" +== 162 +-- truncate_limit: 100 +DROP TABLE collate_dep_test1, collate_dep_test4t +-- +TABLE: name="collate_dep_test1" schema="" table="collate_dep_test1" ctx=DDL +TABLE: name="collate_dep_test4t" schema="" table="collate_dep_test4t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE collate_dep_test1, collate_dep_test4t" +== 163 +-- truncate_limit: 100 +DROP TYPE collate_dep_test2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE collate_dep_test2" +== 164 +-- truncate_limit: 100 +-- test range types and collations + +create type textrange_c as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange_c AS RANGE (subtype = text, \"collation\" = \"C\")" +== 165 +-- truncate_limit: 100 +create type textrange_en_us as range(subtype=text, collation="en_US") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange_en_us AS RANGE (subtype = text, \"collation\" = \"en_US\")" +== 166 +-- truncate_limit: 100 +select textrange_c('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_c" function="textrange_c" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange_c('A', 'Z') @> 'b'::text" +== 167 +-- truncate_limit: 100 +select textrange_en_us('A','Z') @> 'b'::text +-- +FUNCTION: name="textrange_en_us" function="textrange_en_us" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange_en_us('A', 'Z') @> 'b'::text" +== 168 +-- truncate_limit: 100 +drop type textrange_c +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange_c" +== 169 +-- truncate_limit: 100 +drop type textrange_en_us +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange_en_us" +== 170 +-- truncate_limit: 100 +-- nondeterministic collations +-- (not supported with libc provider) +do $$ +BEGIN + EXECUTE 'CREATE COLLATION ctest_det (locale = ' || + quote_literal((SELECT collcollate FROM pg_collation WHERE + collname = 'en_US')) || ', deterministic = true);'; + END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n EXECUTE 'CREATE COLLATION ctest_det (locale = ' ||\n quote_literal((SELECT ..." +== 171 +-- truncate_limit: 100 +CREATE COLLATION ctest_nondet (locale = 'en_US', deterministic = false) +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION ctest_nondet (locale = 'en_US', deterministic = false)" +== 172 +-- truncate_limit: 100 +-- cleanup +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 173 +-- truncate_limit: 100 +DROP SCHEMA collate_tests CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA collate_tests CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/combocid.test b/parser/testdata/summary_truncate/postgres_regress/combocid.test new file mode 100644 index 0000000..0c75ce5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/combocid.test @@ -0,0 +1,463 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for some likely failure cases with combo cmin/cmax mechanism +|-- +CREATE TEMP TABLE combocidtest (foobar int) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE combocidtest (foobar int)" +== 002 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 003 +-- truncate_limit: 100 +-- a few dummy ops to push up the CommandId counter +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 004 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 005 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 006 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 007 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 008 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 009 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 010 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 011 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 012 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 013 +-- truncate_limit: 100 +INSERT INTO combocidtest VALUES (1) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest VALUES (1)" +== 014 +-- truncate_limit: 100 +INSERT INTO combocidtest VALUES (2) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest VALUES (2)" +== 015 +-- truncate_limit: 100 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 016 +-- truncate_limit: 100 +SAVEPOINT s1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT s1" +== 017 +-- truncate_limit: 100 +UPDATE combocidtest SET foobar = foobar + 10 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE combocidtest SET foobar = foobar + 10" +== 018 +-- truncate_limit: 100 +-- here we should see only updated tuples +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 019 +-- truncate_limit: 100 +ROLLBACK TO s1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT s1" +== 020 +-- truncate_limit: 100 +-- now we should see old tuples, but with combo CIDs starting at 0 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 021 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 022 +-- truncate_limit: 100 +-- combo data is not there anymore, but should still see tuples +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 023 +-- truncate_limit: 100 +-- Test combo CIDs with portals +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 024 +-- truncate_limit: 100 +INSERT INTO combocidtest VALUES (333) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest VALUES (333)" +== 025 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT ctid,cmin,* FROM combocidtest +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT ctid, cmin, * FROM combocidtest" +== 026 +-- truncate_limit: 100 +DELETE FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM combocidtest" +== 027 +-- truncate_limit: 100 +FETCH ALL FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c" +== 028 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 029 +-- truncate_limit: 100 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 030 +-- truncate_limit: 100 +-- check behavior with locked tuples +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 031 +-- truncate_limit: 100 +-- a few dummy ops to push up the CommandId counter +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 032 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 033 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 034 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 035 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 036 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 037 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 038 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 039 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 040 +-- truncate_limit: 100 +INSERT INTO combocidtest SELECT 1 LIMIT 0 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest SELECT 1 LIMIT 0" +== 041 +-- truncate_limit: 100 +INSERT INTO combocidtest VALUES (444) +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO combocidtest VALUES (444)" +== 042 +-- truncate_limit: 100 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 043 +-- truncate_limit: 100 +SAVEPOINT s1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT s1" +== 044 +-- truncate_limit: 100 +-- this doesn't affect cmin +SELECT ctid,cmin,* FROM combocidtest FOR UPDATE +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest FOR UPDATE" +== 045 +-- truncate_limit: 100 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 046 +-- truncate_limit: 100 +-- but this does +UPDATE combocidtest SET foobar = foobar + 10 +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE combocidtest SET foobar = foobar + 10" +== 047 +-- truncate_limit: 100 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 048 +-- truncate_limit: 100 +ROLLBACK TO s1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT s1" +== 049 +-- truncate_limit: 100 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 050 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 051 +-- truncate_limit: 100 +SELECT ctid,cmin,* FROM combocidtest +-- +TABLE: name="combocidtest" schema="" table="combocidtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, cmin, * FROM combocidtest" +== 052 +-- truncate_limit: 100 +-- test for bug reported in +-- CABRT9RC81YUf1=jsmWopcKJEro=VoeG2ou6sPwyOUTx_qteRsg@mail.gmail.com +CREATE TABLE IF NOT EXISTS testcase( + id int PRIMARY KEY, + balance numeric +) +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE IF NOT EXISTS testcase (id int PRIMARY KEY, balance numeric)" +== 053 +-- truncate_limit: 100 +INSERT INTO testcase VALUES (1, 0) +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testcase VALUES (1, 0)" +== 054 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 055 +-- truncate_limit: 100 +SELECT * FROM testcase WHERE testcase.id = 1 FOR UPDATE +-- +TABLE: name="testcase" schema="" table="testcase" ctx=Select +FILTER: schema="" table="testcase" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testcase WHERE testcase.id = 1 FOR UPDATE" +== 056 +-- truncate_limit: 100 +UPDATE testcase SET balance = balance + 400 WHERE id=1 +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testcase SET balance = balance + 400 WHERE id = 1" +== 057 +-- truncate_limit: 100 +SAVEPOINT subxact +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT subxact" +== 058 +-- truncate_limit: 100 +UPDATE testcase SET balance = balance - 100 WHERE id=1 +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testcase SET balance = balance - 100 WHERE id = 1" +== 059 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT subxact +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT subxact" +== 060 +-- truncate_limit: 100 +-- should return one tuple +SELECT * FROM testcase WHERE id = 1 FOR UPDATE +-- +TABLE: name="testcase" schema="" table="testcase" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testcase WHERE id = 1 FOR UPDATE" +== 061 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 062 +-- truncate_limit: 100 +DROP TABLE testcase +-- +TABLE: name="testcase" schema="" table="testcase" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testcase" diff --git a/parser/testdata/summary_truncate/postgres_regress/comments.metadata.json b/parser/testdata/summary_truncate/postgres_regress/comments.metadata.json new file mode 100644 index 0000000..980156f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/comments.metadata.json @@ -0,0 +1,10 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/comments.test b/parser/testdata/summary_truncate/postgres_regress/comments.test new file mode 100644 index 0000000..0ad170a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/comments.test @@ -0,0 +1,71 @@ +== 001 +-- truncate_limit: 100 +|-- +-- COMMENTS +|-- + +SELECT 'trailing' AS first +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'trailing' AS first" +== 002 +-- truncate_limit: 100 +-- trailing single line +SELECT /* embedded single line */ 'embedded' AS second +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'embedded' AS second" +== 003 +-- truncate_limit: 100 +SELECT /* both embedded and trailing single line */ 'both' AS third +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'both' AS third" +== 004 +-- truncate_limit: 100 +-- trailing single line + +SELECT 'before multi-line' AS fourth +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'before multi-line' AS fourth" +== 005 +-- truncate_limit: 100 +/* This is an example of SQL which should not execute: + * select 'multi-line'; + */ +SELECT 'after multi-line' AS fifth +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'after multi-line' AS fifth" +== 006 +-- truncate_limit: 100 +|-- +-- Nested comments +|-- + +/* +SELECT 'trailing' as x1; -- inside block comment +*/ + +/* This block comment surrounds a query which itself has a block comment... +SELECT /* embedded single line */ 'embedded' AS x2; +*/ + +SELECT -- continued after the following block comments... +/* Deeply nested comment. + This includes a single apostrophe to make sure we aren't decoding this part as a string. +SELECT 'deep nest' AS n1; +/* Second level of nesting... +SELECT 'deeper nest' as n2; +/* Third level of nesting... +SELECT 'deepest nest' as n3; +*/ +Hoo boy. Still two deep... +*/ +Now just one deep... +*/ +'deeply nested example' AS sixth +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'deeply nested example' AS sixth" diff --git a/parser/testdata/summary_truncate/postgres_regress/compression.metadata.json b/parser/testdata/summary_truncate/postgres_regress/compression.metadata.json new file mode 100644 index 0000000..8e8d1f7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/compression.metadata.json @@ -0,0 +1,91 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/compression.test b/parser/testdata/summary_truncate/postgres_regress/compression.test new file mode 100644 index 0000000..7400d93 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/compression.test @@ -0,0 +1,698 @@ +== 001 +-- truncate_limit: 100 +-- ensure we get stable results regardless of installation's default +SET default_toast_compression = 'pglz' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_toast_compression TO pglz" +== 002 +-- truncate_limit: 100 +-- test creating table with compression method +CREATE TABLE cmdata(f1 text COMPRESSION pglz) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata (f1 text COMPRESSION pglz)" +== 003 +-- truncate_limit: 100 +CREATE INDEX idx ON cmdata(f1) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idx ON cmdata USING btree (f1)" +== 004 +-- truncate_limit: 100 +INSERT INTO cmdata VALUES(repeat('1234567890', 1000)) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmdata VALUES (repeat('1234567890', 1000))" +== 005 +-- truncate_limit: 100 +CREATE TABLE cmdata1(f1 TEXT COMPRESSION lz4) +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata1 (f1 text COMPRESSION lz4)" +== 006 +-- truncate_limit: 100 +INSERT INTO cmdata1 VALUES(repeat('1234567890', 1004)) +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmdata1 VALUES (repeat('1234567890', 1004))" +== 007 +-- truncate_limit: 100 +-- verify stored compression method in the data +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata" +== 008 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata1" +== 009 +-- truncate_limit: 100 +-- decompress data slice +SELECT SUBSTR(f1, 200, 5) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT substr(f1, 200, 5) FROM cmdata" +== 010 +-- truncate_limit: 100 +SELECT SUBSTR(f1, 2000, 50) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT substr(f1, 2000, 50) FROM cmdata1" +== 011 +-- truncate_limit: 100 +-- copy with table creation +SELECT * INTO cmmove1 FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +TABLE: name="cmmove1" schema="" table="cmmove1" ctx=DDL +STMT: SelectStmt +TRUNCATED: "SELECT * INTO cmmove1 FROM cmdata" +== 012 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmmove1 +-- +TABLE: name="cmmove1" schema="" table="cmmove1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmmove1" +== 013 +-- truncate_limit: 100 +-- copy to existing table +CREATE TABLE cmmove3(f1 text COMPRESSION pglz) +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmmove3 (f1 text COMPRESSION pglz)" +== 014 +-- truncate_limit: 100 +INSERT INTO cmmove3 SELECT * FROM cmdata +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=DML +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmmove3 SELECT * FROM cmdata" +== 015 +-- truncate_limit: 100 +INSERT INTO cmmove3 SELECT * FROM cmdata1 +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=DML +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmmove3 SELECT * FROM cmdata1" +== 016 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmmove3 +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmmove3" +== 017 +-- truncate_limit: 100 +-- test LIKE INCLUDING COMPRESSION +CREATE TABLE cmdata2 (LIKE cmdata1 INCLUDING COMPRESSION) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata2 (LIKE cmdata1 INCLUDING COMPRESSION)" +== 018 +-- truncate_limit: 100 +DROP TABLE cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cmdata2" +== 019 +-- truncate_limit: 100 +-- try setting compression for incompressible data type +CREATE TABLE cmdata2 (f1 int COMPRESSION pglz) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata2 (f1 int COMPRESSION pglz)" +== 020 +-- truncate_limit: 100 +-- update using datum from different table +CREATE TABLE cmmove2(f1 text COMPRESSION pglz) +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmmove2 (f1 text COMPRESSION pglz)" +== 021 +-- truncate_limit: 100 +INSERT INTO cmmove2 VALUES (repeat('1234567890', 1004)) +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmmove2 VALUES (repeat('1234567890', 1004))" +== 022 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmmove2 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmmove2" +== 023 +-- truncate_limit: 100 +UPDATE cmmove2 SET f1 = cmdata1.f1 FROM cmdata1 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=DML +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +STMT: UpdateStmt +TRUNCATED: "UPDATE cmmove2 SET f1 = cmdata1.f1 FROM cmdata1" +== 024 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmmove2 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmmove2" +== 025 +-- truncate_limit: 100 +-- test externally stored compressed data +CREATE OR REPLACE FUNCTION large_val() RETURNS TEXT LANGUAGE SQL AS +'select array_agg(fipshash(g::text))::text from generate_series(1, 256) g' +-- +FUNCTION: name="large_val" function="large_val" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION large_val() RETURNS text LANGUAGE sql AS $$select array_agg(fipshash(g..." +== 026 +-- truncate_limit: 100 +CREATE TABLE cmdata2 (f1 text COMPRESSION pglz) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata2 (f1 text COMPRESSION pglz)" +== 027 +-- truncate_limit: 100 +INSERT INTO cmdata2 SELECT large_val() || repeat('a', 4000) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DML +FUNCTION: name="large_val" function="large_val" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmdata2 SELECT large_val() || repeat('a', 4000)" +== 028 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata2" +== 029 +-- truncate_limit: 100 +INSERT INTO cmdata1 SELECT large_val() || repeat('a', 4000) +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=DML +FUNCTION: name="large_val" function="large_val" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmdata1 SELECT large_val() || repeat('a', 4000)" +== 030 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata1" +== 031 +-- truncate_limit: 100 +SELECT SUBSTR(f1, 200, 5) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT substr(f1, 200, 5) FROM cmdata1" +== 032 +-- truncate_limit: 100 +SELECT SUBSTR(f1, 200, 5) FROM cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT substr(f1, 200, 5) FROM cmdata2" +== 033 +-- truncate_limit: 100 +DROP TABLE cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cmdata2" +== 034 +-- truncate_limit: 100 +--test column type update varlena/non-varlena +CREATE TABLE cmdata2 (f1 int) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata2 (f1 int)" +== 035 +-- truncate_limit: 100 +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar" +== 036 +-- truncate_limit: 100 +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::int" +== 037 +-- truncate_limit: 100 +--changing column storage should not impact the compression method +--but the data should not be compressed +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar" +== 038 +-- truncate_limit: 100 +ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION pglz +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION pglz" +== 039 +-- truncate_limit: 100 +ALTER TABLE cmdata2 ALTER COLUMN f1 SET STORAGE plain +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmdata2 ALTER COLUMN f1 SET STORAGE plain" +== 040 +-- truncate_limit: 100 +INSERT INTO cmdata2 VALUES (repeat('123456789', 800)) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmdata2 VALUES (repeat('123456789', 800))" +== 041 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata2" +== 042 +-- truncate_limit: 100 +-- test compression with materialized view +CREATE MATERIALIZED VIEW compressmv(x) AS SELECT * FROM cmdata1 +-- +TABLE: name="compressmv" schema="" table="compressmv" ctx=DDL +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW compressmv(x) AS SELECT * FROM cmdata1" +== 043 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata1" +== 044 +-- truncate_limit: 100 +SELECT pg_column_compression(x) FROM compressmv +-- +TABLE: name="compressmv" schema="" table="compressmv" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(x) FROM compressmv" +== 045 +-- truncate_limit: 100 +-- test compression with partition +CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmpart (f1 text COMPRESSION lz4) PARTITION BY HASH (f1)" +== 046 +-- truncate_limit: 100 +CREATE TABLE cmpart1 PARTITION OF cmpart FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmpart1 PARTITION OF cmpart FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 047 +-- truncate_limit: 100 +CREATE TABLE cmpart2(f1 text COMPRESSION pglz) +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmpart2 (f1 text COMPRESSION pglz)" +== 048 +-- truncate_limit: 100 +ALTER TABLE cmpart ATTACH PARTITION cmpart2 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmpart ATTACH PARTITION cmpart2 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 049 +-- truncate_limit: 100 +INSERT INTO cmpart VALUES (repeat('123456789', 1004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmpart VALUES (repeat('123456789', 1004))" +== 050 +-- truncate_limit: 100 +INSERT INTO cmpart VALUES (repeat('123456789', 4004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmpart VALUES (repeat('123456789', 4004))" +== 051 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmpart1 +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmpart1" +== 052 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmpart2 +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmpart2" +== 053 +-- truncate_limit: 100 +-- test compression with inheritance +CREATE TABLE cminh() INHERITS(cmdata, cmdata1) +-- +TABLE: name="cminh" schema="" table="cminh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cminh () INHERITS (cmdata, cmdata1)" +== 054 +-- truncate_limit: 100 +-- error +CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata) +-- +TABLE: name="cminh" schema="" table="cminh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cminh (f1 text COMPRESSION lz4) INHERITS (cmdata)" +== 055 +-- truncate_limit: 100 +-- error +CREATE TABLE cmdata3(f1 text) +-- +TABLE: name="cmdata3" schema="" table="cmdata3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata3 (f1 text)" +== 056 +-- truncate_limit: 100 +CREATE TABLE cminh() INHERITS (cmdata, cmdata3) +-- +TABLE: name="cminh" schema="" table="cminh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cminh () INHERITS (cmdata, cmdata3)" +== 057 +-- truncate_limit: 100 +-- test default_toast_compression GUC +SET default_toast_compression = '' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_toast_compression TO ''" +== 058 +-- truncate_limit: 100 +SET default_toast_compression = 'I do not exist compression' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_toast_compression TO \"I do not exist compression\"" +== 059 +-- truncate_limit: 100 +SET default_toast_compression = 'lz4' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_toast_compression TO lz4" +== 060 +-- truncate_limit: 100 +SET default_toast_compression = 'pglz' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_toast_compression TO pglz" +== 061 +-- truncate_limit: 100 +-- test alter compression method +ALTER TABLE cmdata ALTER COLUMN f1 SET COMPRESSION lz4 +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmdata ALTER COLUMN f1 SET COMPRESSION lz4" +== 062 +-- truncate_limit: 100 +INSERT INTO cmdata VALUES (repeat('123456789', 4004)) +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmdata VALUES (repeat('123456789', 4004))" +== 063 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata" +== 064 +-- truncate_limit: 100 +ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION default +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION DEFAULT" +== 065 +-- truncate_limit: 100 +-- test alter compression method for materialized views +ALTER MATERIALIZED VIEW compressmv ALTER COLUMN x SET COMPRESSION lz4 +-- +TABLE: name="compressmv" schema="" table="compressmv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER MATERIALIZED VIEW compressmv ALTER COLUMN x SET COMPRESSION lz4" +== 066 +-- truncate_limit: 100 +-- test alter compression method for partitioned tables +ALTER TABLE cmpart1 ALTER COLUMN f1 SET COMPRESSION pglz +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmpart1 ALTER COLUMN f1 SET COMPRESSION pglz" +== 067 +-- truncate_limit: 100 +ALTER TABLE cmpart2 ALTER COLUMN f1 SET COMPRESSION lz4 +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cmpart2 ALTER COLUMN f1 SET COMPRESSION lz4" +== 068 +-- truncate_limit: 100 +-- new data should be compressed with the current compression method +INSERT INTO cmpart VALUES (repeat('123456789', 1004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmpart VALUES (repeat('123456789', 1004))" +== 069 +-- truncate_limit: 100 +INSERT INTO cmpart VALUES (repeat('123456789', 4004)) +-- +TABLE: name="cmpart" schema="" table="cmpart" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmpart VALUES (repeat('123456789', 4004))" +== 070 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmpart1 +-- +TABLE: name="cmpart1" schema="" table="cmpart1" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmpart1" +== 071 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmpart2 +-- +TABLE: name="cmpart2" schema="" table="cmpart2" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmpart2" +== 072 +-- truncate_limit: 100 +-- VACUUM FULL does not recompress +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata" +== 073 +-- truncate_limit: 100 +VACUUM FULL cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) cmdata" +== 074 +-- truncate_limit: 100 +SELECT pg_column_compression(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="pg_column_compression" function="pg_column_compression" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_compression(f1) FROM cmdata" +== 075 +-- truncate_limit: 100 +-- test expression index +DROP TABLE cmdata2 +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cmdata2" +== 076 +-- truncate_limit: 100 +CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cmdata2 (f1 text COMPRESSION pglz, f2 text COMPRESSION lz4)" +== 077 +-- truncate_limit: 100 +CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2)) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX idx1 ON cmdata2 USING btree ((f1 || f2))" +== 078 +-- truncate_limit: 100 +INSERT INTO cmdata2 VALUES((SELECT array_agg(fipshash(g::TEXT))::TEXT FROM +generate_series(1, 50) g), VERSION()) +-- +TABLE: name="cmdata2" schema="" table="cmdata2" ctx=DML +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="version" function="version" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cmdata2 VALUES ((SELECT ... FROM generate_series(1, 50) g), version())" +== 079 +-- truncate_limit: 100 +-- check data is ok +SELECT length(f1) FROM cmdata +-- +TABLE: name="cmdata" schema="" table="cmdata" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(f1) FROM cmdata" +== 080 +-- truncate_limit: 100 +SELECT length(f1) FROM cmdata1 +-- +TABLE: name="cmdata1" schema="" table="cmdata1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(f1) FROM cmdata1" +== 081 +-- truncate_limit: 100 +SELECT length(f1) FROM cmmove1 +-- +TABLE: name="cmmove1" schema="" table="cmmove1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(f1) FROM cmmove1" +== 082 +-- truncate_limit: 100 +SELECT length(f1) FROM cmmove2 +-- +TABLE: name="cmmove2" schema="" table="cmmove2" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(f1) FROM cmmove2" +== 083 +-- truncate_limit: 100 +SELECT length(f1) FROM cmmove3 +-- +TABLE: name="cmmove3" schema="" table="cmmove3" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(f1) FROM cmmove3" +== 084 +-- truncate_limit: 100 +CREATE TABLE badcompresstbl (a text COMPRESSION I_Do_Not_Exist_Compression) +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE badcompresstbl (a text COMPRESSION i_do_not_exist_compression)" +== 085 +-- truncate_limit: 100 +-- fails +CREATE TABLE badcompresstbl (a text) +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE badcompresstbl (a text)" +== 086 +-- truncate_limit: 100 +ALTER TABLE badcompresstbl ALTER a SET COMPRESSION I_Do_Not_Exist_Compression +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE badcompresstbl ALTER COLUMN a SET COMPRESSION i_do_not_exist_compression" +== 087 +-- truncate_limit: 100 +-- fails +DROP TABLE badcompresstbl +-- +TABLE: name="badcompresstbl" schema="" table="badcompresstbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE badcompresstbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json b/parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json new file mode 100644 index 0000000..60d70f4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json @@ -0,0 +1,323 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/constraints.test b/parser/testdata/summary_truncate/postgres_regress/constraints.test new file mode 100644 index 0000000..4c2034b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/constraints.test @@ -0,0 +1,2521 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CONSTRAINTS +-- Constraints can be specified with: +-- - DEFAULT clause +-- - CHECK clauses +-- - PRIMARY KEY clauses +-- - UNIQUE clauses +-- - EXCLUDE clauses +|-- + +-- directory paths are passed to us in environment variables + +|-- +-- DEFAULT syntax +|-- + +CREATE TABLE DEFAULT_TBL (i int DEFAULT 100, + x text DEFAULT 'vadim', f float8 DEFAULT 123.456) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_tbl (i int DEFAULT 100, x text DEFAULT 'vadim', f float8 DEFAULT 123.456)" +== 002 +-- truncate_limit: 100 +INSERT INTO DEFAULT_TBL VALUES (1, 'thomas', 57.0613) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO default_tbl VALUES (1, 'thomas', 57.0613)" +== 003 +-- truncate_limit: 100 +INSERT INTO DEFAULT_TBL VALUES (1, 'bruce') +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO default_tbl VALUES (1, 'bruce')" +== 004 +-- truncate_limit: 100 +INSERT INTO DEFAULT_TBL (i, f) VALUES (2, 987.654) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO default_tbl (i, f) VALUES (2, 987.654)" +== 005 +-- truncate_limit: 100 +INSERT INTO DEFAULT_TBL (x) VALUES ('marc') +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO default_tbl (x) VALUES ('marc')" +== 006 +-- truncate_limit: 100 +INSERT INTO DEFAULT_TBL VALUES (3, null, 1.0) +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO default_tbl VALUES (3, NULL, 1.0)" +== 007 +-- truncate_limit: 100 +SELECT * FROM DEFAULT_TBL +-- +TABLE: name="default_tbl" schema="" table="default_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM default_tbl" +== 008 +-- truncate_limit: 100 +CREATE SEQUENCE DEFAULT_SEQ +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE default_seq" +== 009 +-- truncate_limit: 100 +CREATE TABLE DEFAULTEXPR_TBL (i1 int DEFAULT 100 + (200-199) * 2, + i2 int DEFAULT nextval('default_seq')) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defaultexpr_tbl (i1 int DEFAULT 100 + ((200 - 199) * 2), i2 int DEFAULT nextval('def..." +== 010 +-- truncate_limit: 100 +INSERT INTO DEFAULTEXPR_TBL VALUES (-1, -2) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defaultexpr_tbl VALUES (-1, -2)" +== 011 +-- truncate_limit: 100 +INSERT INTO DEFAULTEXPR_TBL (i1) VALUES (-3) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defaultexpr_tbl (i1) VALUES (-3)" +== 012 +-- truncate_limit: 100 +INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (-4) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defaultexpr_tbl (i2) VALUES (-4)" +== 013 +-- truncate_limit: 100 +INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (NULL) +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defaultexpr_tbl (i2) VALUES (NULL)" +== 014 +-- truncate_limit: 100 +SELECT * FROM DEFAULTEXPR_TBL +-- +TABLE: name="defaultexpr_tbl" schema="" table="defaultexpr_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM defaultexpr_tbl" +== 015 +-- truncate_limit: 100 +-- syntax errors +-- test for extraneous comma +CREATE TABLE error_tbl (i int DEFAULT (100, )) +-- +ERROR: syntax error at or near ")" +CURSORPOS: 92 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 016 +-- truncate_limit: 100 +-- this will fail because gram.y uses b_expr not a_expr for defaults, +-- to avoid a shift/reduce conflict that arises from NOT NULL being +-- part of the column definition syntax: +CREATE TABLE error_tbl (b1 bool DEFAULT 1 IN (1, 2)) +-- +ERROR: syntax error at or near "IN" +CURSORPOS: 225 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 017 +-- truncate_limit: 100 +-- this should work, however: +CREATE TABLE error_tbl (b1 bool DEFAULT (1 IN (1, 2))) +-- +TABLE: name="error_tbl" schema="" table="error_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE error_tbl (b1 bool DEFAULT (1 IN (1, 2)))" +== 018 +-- truncate_limit: 100 +DROP TABLE error_tbl +-- +TABLE: name="error_tbl" schema="" table="error_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE error_tbl" +== 019 +-- truncate_limit: 100 +|-- +-- CHECK syntax +|-- + +CREATE TABLE CHECK_TBL (x int, + CONSTRAINT CHECK_CON CHECK (x > 3)) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE check_tbl (x int, CONSTRAINT check_con CHECK (x > 3))" +== 020 +-- truncate_limit: 100 +INSERT INTO CHECK_TBL VALUES (5) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check_tbl VALUES (5)" +== 021 +-- truncate_limit: 100 +INSERT INTO CHECK_TBL VALUES (4) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check_tbl VALUES (4)" +== 022 +-- truncate_limit: 100 +INSERT INTO CHECK_TBL VALUES (3) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check_tbl VALUES (3)" +== 023 +-- truncate_limit: 100 +INSERT INTO CHECK_TBL VALUES (2) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check_tbl VALUES (2)" +== 024 +-- truncate_limit: 100 +INSERT INTO CHECK_TBL VALUES (6) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check_tbl VALUES (6)" +== 025 +-- truncate_limit: 100 +INSERT INTO CHECK_TBL VALUES (1) +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check_tbl VALUES (1)" +== 026 +-- truncate_limit: 100 +SELECT * FROM CHECK_TBL +-- +TABLE: name="check_tbl" schema="" table="check_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_tbl" +== 027 +-- truncate_limit: 100 +CREATE SEQUENCE CHECK_SEQ +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE check_seq" +== 028 +-- truncate_limit: 100 +CREATE TABLE CHECK2_TBL (x int, y text, z int, + CONSTRAINT SEQUENCE_CON + CHECK (x > 3 and y <> 'check failed' and z < 8)) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE check2_tbl (x int, y text, z int, CONSTRAINT sequence_con CHECK (x > 3 AND y <> 'che..." +== 029 +-- truncate_limit: 100 +INSERT INTO CHECK2_TBL VALUES (4, 'check ok', -2) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check2_tbl VALUES (4, 'check ok', -2)" +== 030 +-- truncate_limit: 100 +INSERT INTO CHECK2_TBL VALUES (1, 'x check failed', -2) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check2_tbl VALUES (1, 'x check failed', -2)" +== 031 +-- truncate_limit: 100 +INSERT INTO CHECK2_TBL VALUES (5, 'z check failed', 10) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check2_tbl VALUES (5, 'z check failed', 10)" +== 032 +-- truncate_limit: 100 +INSERT INTO CHECK2_TBL VALUES (0, 'check failed', -2) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check2_tbl VALUES (0, 'check failed', -2)" +== 033 +-- truncate_limit: 100 +INSERT INTO CHECK2_TBL VALUES (6, 'check failed', 11) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check2_tbl VALUES (6, 'check failed', 11)" +== 034 +-- truncate_limit: 100 +INSERT INTO CHECK2_TBL VALUES (7, 'check ok', 7) +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO check2_tbl VALUES (7, 'check ok', 7)" +== 035 +-- truncate_limit: 100 +SELECT * from CHECK2_TBL +-- +TABLE: name="check2_tbl" schema="" table="check2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check2_tbl" +== 036 +-- truncate_limit: 100 +|-- +-- Check constraints on INSERT +|-- + +CREATE SEQUENCE INSERT_SEQ +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE insert_seq" +== 037 +-- truncate_limit: 100 +CREATE TABLE INSERT_TBL (x INT DEFAULT nextval('insert_seq'), + y TEXT DEFAULT '-NULL-', + z INT DEFAULT -1 * currval('insert_seq'), + CONSTRAINT INSERT_TBL_CON CHECK (x >= 3 AND y <> 'check failed' AND x < 8), + CHECK (x + z = 0)) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE insert_tbl (x int DEFAULT nextval('insert_seq'), y text DEFAULT '-NULL-', z int DEFA..." +== 038 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(x,z) VALUES (2, -2) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (x, z) VALUES (2, -2)" +== 039 +-- truncate_limit: 100 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tbl" +== 040 +-- truncate_limit: 100 +SELECT 'one' AS one, nextval('insert_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'one' AS one, nextval('insert_seq')" +== 041 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y) VALUES ('Y') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y) VALUES ('Y')" +== 042 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y) VALUES ('Y') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y) VALUES ('Y')" +== 043 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(x,z) VALUES (1, -2) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (x, z) VALUES (1, -2)" +== 044 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(z,x) VALUES (-7, 7) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (z, x) VALUES (-7, 7)" +== 045 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL VALUES (5, 'check failed', -5) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl VALUES (5, 'check failed', -5)" +== 046 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL VALUES (7, '!check failed', -7) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl VALUES (7, '!check failed', -7)" +== 047 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y) VALUES ('-!NULL-')" +== 048 +-- truncate_limit: 100 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tbl" +== 049 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y,z) VALUES ('check failed', 4) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y, z) VALUES ('check failed', 4)" +== 050 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(x,y) VALUES (5, 'check failed') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (x, y) VALUES (5, 'check failed')" +== 051 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(x,y) VALUES (5, '!check failed') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (x, y) VALUES (5, '!check failed')" +== 052 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y) VALUES ('-!NULL-')" +== 053 +-- truncate_limit: 100 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tbl" +== 054 +-- truncate_limit: 100 +SELECT 'seven' AS one, nextval('insert_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'seven' AS one, nextval('insert_seq')" +== 055 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y) VALUES ('Y') +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y) VALUES ('Y')" +== 056 +-- truncate_limit: 100 +SELECT 'eight' AS one, currval('insert_seq') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'eight' AS one, currval('insert_seq')" +== 057 +-- truncate_limit: 100 +-- According to SQL, it is OK to insert a record that gives rise to NULL +-- constraint-condition results. Postgres used to reject this, but it +-- was wrong: +INSERT INTO INSERT_TBL VALUES (null, null, null) +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl VALUES (NULL, NULL, NULL)" +== 058 +-- truncate_limit: 100 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tbl" +== 059 +-- truncate_limit: 100 +|-- +-- Check constraints on system columns +|-- + +CREATE TABLE SYS_COL_CHECK_TBL (city text, state text, is_capital bool, + altitude int, + CHECK (NOT (is_capital AND tableoid::regclass::text = 'sys_col_check_tbl'))) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sys_col_check_tbl (city text, state text, is_capital bool, altitude int, CHECK (NOT ..." +== 060 +-- truncate_limit: 100 +INSERT INTO SYS_COL_CHECK_TBL VALUES ('Seattle', 'Washington', false, 100) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sys_col_check_tbl VALUES ('Seattle', 'Washington', false, 100)" +== 061 +-- truncate_limit: 100 +INSERT INTO SYS_COL_CHECK_TBL VALUES ('Olympia', 'Washington', true, 100) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sys_col_check_tbl VALUES ('Olympia', 'Washington', true, 100)" +== 062 +-- truncate_limit: 100 +SELECT *, tableoid::regclass::text FROM SYS_COL_CHECK_TBL +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT *, tableoid::regclass::text FROM sys_col_check_tbl" +== 063 +-- truncate_limit: 100 +DROP TABLE SYS_COL_CHECK_TBL +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sys_col_check_tbl" +== 064 +-- truncate_limit: 100 +|-- +-- Check constraints on system columns other then TableOid should return error +|-- +CREATE TABLE SYS_COL_CHECK_TBL (city text, state text, is_capital bool, + altitude int, + CHECK (NOT (is_capital AND ctid::text = 'sys_col_check_tbl'))) +-- +TABLE: name="sys_col_check_tbl" schema="" table="sys_col_check_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sys_col_check_tbl (city text, state text, is_capital bool, altitude int, CHECK (NOT ..." +== 065 +-- truncate_limit: 100 +|-- +-- Check inheritance of defaults and constraints +|-- + +CREATE TABLE INSERT_CHILD (cx INT default 42, + cy INT CHECK (cy > x)) + INHERITS (INSERT_TBL) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE insert_child (cx int DEFAULT 42, cy int CHECK (cy > x)) INHERITS (insert_tbl)" +== 066 +-- truncate_limit: 100 +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,11) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_child (x, z, cy) VALUES (7, -7, 11)" +== 067 +-- truncate_limit: 100 +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,6) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_child (x, z, cy) VALUES (7, -7, 6)" +== 068 +-- truncate_limit: 100 +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (6,-7,7) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_child (x, z, cy) VALUES (6, -7, 7)" +== 069 +-- truncate_limit: 100 +INSERT INTO INSERT_CHILD(x,y,z,cy) VALUES (6,'check failed',-6,7) +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_child (x, y, z, cy) VALUES (6, 'check failed', -6, 7)" +== 070 +-- truncate_limit: 100 +SELECT * FROM INSERT_CHILD +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_child" +== 071 +-- truncate_limit: 100 +DROP TABLE INSERT_CHILD +-- +TABLE: name="insert_child" schema="" table="insert_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE insert_child" +== 072 +-- truncate_limit: 100 +|-- +-- Check NO INHERIT type of constraints and inheritance +|-- + +CREATE TABLE ATACC1 (TEST INT + CHECK (TEST > 0) NO INHERIT) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int CHECK (test > 0) NO INHERIT)" +== 073 +-- truncate_limit: 100 +CREATE TABLE ATACC2 (TEST2 INT) INHERITS (ATACC1) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc2 (test2 int) INHERITS (atacc1)" +== 074 +-- truncate_limit: 100 +-- check constraint is not there on child +INSERT INTO ATACC2 (TEST) VALUES (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc2 (test) VALUES (-3)" +== 075 +-- truncate_limit: 100 +-- check constraint is there on parent +INSERT INTO ATACC1 (TEST) VALUES (-3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (-3)" +== 076 +-- truncate_limit: 100 +DROP TABLE ATACC1 CASCADE +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1 CASCADE" +== 077 +-- truncate_limit: 100 +CREATE TABLE ATACC1 (TEST INT, TEST2 INT + CHECK (TEST > 0), CHECK (TEST2 > 10) NO INHERIT) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc1 (test int, test2 int CHECK (test > 0), CHECK (test2 > 10) NO INHERIT)" +== 078 +-- truncate_limit: 100 +CREATE TABLE ATACC2 () INHERITS (ATACC1) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atacc2 () INHERITS (atacc1)" +== 079 +-- truncate_limit: 100 +-- check constraint is there on child +INSERT INTO ATACC2 (TEST) VALUES (-3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc2 (test) VALUES (-3)" +== 080 +-- truncate_limit: 100 +-- check constraint is there on parent +INSERT INTO ATACC1 (TEST) VALUES (-3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test) VALUES (-3)" +== 081 +-- truncate_limit: 100 +-- check constraint is not there on child +INSERT INTO ATACC2 (TEST2) VALUES (3) +-- +TABLE: name="atacc2" schema="" table="atacc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc2 (test2) VALUES (3)" +== 082 +-- truncate_limit: 100 +-- check constraint is there on parent +INSERT INTO ATACC1 (TEST2) VALUES (3) +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atacc1 (test2) VALUES (3)" +== 083 +-- truncate_limit: 100 +DROP TABLE ATACC1 CASCADE +-- +TABLE: name="atacc1" schema="" table="atacc1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE atacc1 CASCADE" +== 084 +-- truncate_limit: 100 +|-- +-- Check constraints on INSERT INTO +|-- + +DELETE FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM insert_tbl" +== 085 +-- truncate_limit: 100 +ALTER SEQUENCE INSERT_SEQ RESTART WITH 4 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE insert_seq RESTART 4" +== 086 +-- truncate_limit: 100 +CREATE TEMP TABLE tmp (xd INT, yd TEXT, zd INT) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tmp (xd int, yd text, zd int)" +== 087 +-- truncate_limit: 100 +INSERT INTO tmp VALUES (null, 'Y', null) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tmp VALUES (NULL, 'Y', NULL)" +== 088 +-- truncate_limit: 100 +INSERT INTO tmp VALUES (5, '!check failed', null) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tmp VALUES (5, '!check failed', NULL)" +== 089 +-- truncate_limit: 100 +INSERT INTO tmp VALUES (null, 'try again', null) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tmp VALUES (NULL, 'try again', NULL)" +== 090 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y) select yd from tmp +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y) SELECT yd FROM tmp" +== 091 +-- truncate_limit: 100 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tbl" +== 092 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL SELECT * FROM tmp WHERE yd = 'try again' +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +FILTER: schema="" table="" column="yd" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl SELECT * FROM tmp WHERE yd = 'try again'" +== 093 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y,z) SELECT yd, -7 FROM tmp WHERE yd = 'try again' +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +FILTER: schema="" table="" column="yd" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y, z) SELECT yd, -7 FROM tmp WHERE yd = 'try again'" +== 094 +-- truncate_limit: 100 +INSERT INTO INSERT_TBL(y,z) SELECT yd, -8 FROM tmp WHERE yd = 'try again' +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +TABLE: name="tmp" schema="" table="tmp" ctx=Select +FILTER: schema="" table="" column="yd" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insert_tbl (y, z) SELECT yd, -8 FROM tmp WHERE yd = 'try again'" +== 095 +-- truncate_limit: 100 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tbl" +== 096 +-- truncate_limit: 100 +DROP TABLE tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tmp" +== 097 +-- truncate_limit: 100 +|-- +-- Check constraints on UPDATE +|-- + +UPDATE INSERT_TBL SET x = NULL WHERE x = 5 +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE insert_tbl SET x = NULL WHERE x = 5" +== 098 +-- truncate_limit: 100 +UPDATE INSERT_TBL SET x = 6 WHERE x = 6 +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE insert_tbl SET x = 6 WHERE x = 6" +== 099 +-- truncate_limit: 100 +UPDATE INSERT_TBL SET x = -z, z = -x +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE insert_tbl SET x = - z, z = - x" +== 100 +-- truncate_limit: 100 +UPDATE INSERT_TBL SET x = z, z = x +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE insert_tbl SET x = z, z = x" +== 101 +-- truncate_limit: 100 +SELECT * FROM INSERT_TBL +-- +TABLE: name="insert_tbl" schema="" table="insert_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tbl" +== 102 +-- truncate_limit: 100 +-- DROP TABLE INSERT_TBL; + +|-- +-- Check constraints on COPY FROM +|-- + +CREATE TABLE COPY_TBL (x INT, y TEXT, z INT, + CONSTRAINT COPY_CON + CHECK (x > 3 AND y <> 'check failed' AND x < 7 )) +-- +TABLE: name="copy_tbl" schema="" table="copy_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE copy_tbl (x int, y text, z int, CONSTRAINT copy_con CHECK (x > 3 AND y <> 'check fai..." +== 103 +-- truncate_limit: 100 +COPY COPY_TBL FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 104 +-- truncate_limit: 100 +SELECT * FROM COPY_TBL +-- +TABLE: name="copy_tbl" schema="" table="copy_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM copy_tbl" +== 105 +-- truncate_limit: 100 +COPY COPY_TBL FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 106 +-- truncate_limit: 100 +SELECT * FROM COPY_TBL +-- +TABLE: name="copy_tbl" schema="" table="copy_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM copy_tbl" +== 107 +-- truncate_limit: 100 +|-- +-- Primary keys +|-- + +CREATE TABLE PRIMARY_TBL (i int PRIMARY KEY, t text) +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE primary_tbl (i int PRIMARY KEY, t text)" +== 108 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (1, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (1, 'one')" +== 109 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (2, 'two') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (2, 'two')" +== 110 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (1, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (1, 'three')" +== 111 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (4, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (4, 'three')" +== 112 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (5, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (5, 'one')" +== 113 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL (t) VALUES ('six') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl (t) VALUES ('six')" +== 114 +-- truncate_limit: 100 +SELECT * FROM PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM primary_tbl" +== 115 +-- truncate_limit: 100 +DROP TABLE PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE primary_tbl" +== 116 +-- truncate_limit: 100 +CREATE TABLE PRIMARY_TBL (i int, t text, + PRIMARY KEY(i,t)) +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE primary_tbl (i int, t text, PRIMARY KEY (i, t))" +== 117 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (1, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (1, 'one')" +== 118 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (2, 'two') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (2, 'two')" +== 119 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (1, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (1, 'three')" +== 120 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (4, 'three') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (4, 'three')" +== 121 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL VALUES (5, 'one') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl VALUES (5, 'one')" +== 122 +-- truncate_limit: 100 +INSERT INTO PRIMARY_TBL (t) VALUES ('six') +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO primary_tbl (t) VALUES ('six')" +== 123 +-- truncate_limit: 100 +SELECT * FROM PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM primary_tbl" +== 124 +-- truncate_limit: 100 +DROP TABLE PRIMARY_TBL +-- +TABLE: name="primary_tbl" schema="" table="primary_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE primary_tbl" +== 125 +-- truncate_limit: 100 +|-- +-- Unique keys +|-- + +CREATE TABLE UNIQUE_TBL (i int UNIQUE, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unique_tbl (i int UNIQUE, t text)" +== 126 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'one')" +== 127 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (2, 'two')" +== 128 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (1, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'three')" +== 129 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (4, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (4, 'four')" +== 130 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (5, 'one')" +== 131 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('six')" +== 132 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('seven')" +== 133 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (5, 'five-upsert-insert') ON CONFLICT (i) DO UPDATE SET t = 'five-upsert-update' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (5, 'five-upsert-insert') ON CONFLICT (i) DO UPDATE SET ... = ..." +== 134 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (6, 'six-upsert-insert') ON CONFLICT (i) DO UPDATE SET t = 'six-upsert-update' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (6, 'six-upsert-insert') ON CONFLICT (i) DO UPDATE SET ... = ..." +== 135 +-- truncate_limit: 100 +-- should fail +INSERT INTO UNIQUE_TBL VALUES (1, 'a'), (2, 'b'), (2, 'b') ON CONFLICT (i) DO UPDATE SET t = 'fails' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'a'), (2, 'b'), (2, 'b') ON CONFLICT (i) DO UPDATE SET t = 'fails'" +== 136 +-- truncate_limit: 100 +SELECT * FROM UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 137 +-- truncate_limit: 100 +DROP TABLE UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unique_tbl" +== 138 +-- truncate_limit: 100 +CREATE TABLE UNIQUE_TBL (i int UNIQUE NULLS NOT DISTINCT, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unique_tbl (i int UNIQUE NULLS NOT DISTINCT, t text)" +== 139 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'one')" +== 140 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (2, 'two')" +== 141 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (1, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'three')" +== 142 +-- truncate_limit: 100 +-- fail +INSERT INTO UNIQUE_TBL VALUES (4, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (4, 'four')" +== 143 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (5, 'one')" +== 144 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('six')" +== 145 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('seven')" +== 146 +-- truncate_limit: 100 +-- fail +INSERT INTO UNIQUE_TBL (t) VALUES ('eight') ON CONFLICT DO NOTHING +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('eight') ON CONFLICT DO NOTHING" +== 147 +-- truncate_limit: 100 +-- no-op + +SELECT * FROM UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 148 +-- truncate_limit: 100 +DROP TABLE UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unique_tbl" +== 149 +-- truncate_limit: 100 +CREATE TABLE UNIQUE_TBL (i int, t text, + UNIQUE(i,t)) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unique_tbl (i int, t text, UNIQUE (i, t))" +== 150 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'one')" +== 151 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (2, 'two')" +== 152 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (1, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'three')" +== 153 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'one')" +== 154 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (5, 'one')" +== 155 +-- truncate_limit: 100 +INSERT INTO UNIQUE_TBL (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('six')" +== 156 +-- truncate_limit: 100 +SELECT * FROM UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 157 +-- truncate_limit: 100 +DROP TABLE UNIQUE_TBL +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unique_tbl" +== 158 +-- truncate_limit: 100 +|-- +-- Deferrable unique constraints +|-- + +CREATE TABLE unique_tbl (i int UNIQUE DEFERRABLE, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unique_tbl (i int UNIQUE DEFERRABLE, t text)" +== 159 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (0, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (0, 'one')" +== 160 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (1, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'two')" +== 161 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (2, 'tree') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (2, 'tree')" +== 162 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (3, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'four')" +== 163 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (4, 'five') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (4, 'five')" +== 164 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 165 +-- truncate_limit: 100 +-- default is immediate so this should fail right away +UPDATE unique_tbl SET i = 1 WHERE i = 0 +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE unique_tbl SET i = 1 WHERE i = 0" +== 166 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 167 +-- truncate_limit: 100 +-- check is done at end of statement, so this should succeed +UPDATE unique_tbl SET i = i+1 +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE unique_tbl SET i = i + 1" +== 168 +-- truncate_limit: 100 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 169 +-- truncate_limit: 100 +-- explicitly defer the constraint +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 170 +-- truncate_limit: 100 +SET CONSTRAINTS unique_tbl_i_key DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS unique_tbl_i_key DEFERRED" +== 171 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (3, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'three')" +== 172 +-- truncate_limit: 100 +DELETE FROM unique_tbl WHERE t = 'tree' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM unique_tbl WHERE t = 'tree'" +== 173 +-- truncate_limit: 100 +-- makes constraint valid again + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 174 +-- truncate_limit: 100 +-- should succeed + +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 175 +-- truncate_limit: 100 +-- try adding an initially deferred constraint +ALTER TABLE unique_tbl DROP CONSTRAINT unique_tbl_i_key +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE unique_tbl DROP CONSTRAINT unique_tbl_i_key" +== 176 +-- truncate_limit: 100 +ALTER TABLE unique_tbl ADD CONSTRAINT unique_tbl_i_key + UNIQUE (i) DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE unique_tbl ADD CONSTRAINT unique_tbl_i_key UNIQUE (i) DEFERRABLE INITIALLY DEFERRED" +== 177 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 178 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (1, 'five') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'five')" +== 179 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (5, 'one')" +== 180 +-- truncate_limit: 100 +UPDATE unique_tbl SET i = 4 WHERE i = 2 +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE unique_tbl SET i = 4 WHERE i = 2" +== 181 +-- truncate_limit: 100 +UPDATE unique_tbl SET i = 2 WHERE i = 4 AND t = 'four' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE unique_tbl SET i = 2 WHERE i = 4 AND t = 'four'" +== 182 +-- truncate_limit: 100 +DELETE FROM unique_tbl WHERE i = 1 AND t = 'one' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM unique_tbl WHERE i = 1 AND t = 'one'" +== 183 +-- truncate_limit: 100 +DELETE FROM unique_tbl WHERE i = 5 AND t = 'five' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM unique_tbl WHERE i = 5 AND t = 'five'" +== 184 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 185 +-- truncate_limit: 100 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 186 +-- truncate_limit: 100 +-- should fail at commit-time +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 187 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'Three')" +== 188 +-- truncate_limit: 100 +-- should succeed for now +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 189 +-- truncate_limit: 100 +-- should fail + +-- make constraint check immediate +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 190 +-- truncate_limit: 100 +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS ALL IMMEDIATE" +== 191 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'Three')" +== 192 +-- truncate_limit: 100 +-- should fail + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 193 +-- truncate_limit: 100 +-- forced check when SET CONSTRAINTS is called +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 194 +-- truncate_limit: 100 +SET CONSTRAINTS ALL DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS ALL DEFERRED" +== 195 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'Three')" +== 196 +-- truncate_limit: 100 +-- should succeed for now + +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS ALL IMMEDIATE" +== 197 +-- truncate_limit: 100 +-- should fail + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 198 +-- truncate_limit: 100 +-- test deferrable UNIQUE with a partitioned table +CREATE TABLE parted_uniq_tbl (i int UNIQUE DEFERRABLE) partition by range (i) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_uniq_tbl (i int UNIQUE DEFERRABLE) PARTITION BY RANGE (i)" +== 199 +-- truncate_limit: 100 +CREATE TABLE parted_uniq_tbl_1 PARTITION OF parted_uniq_tbl FOR VALUES FROM (0) TO (10) +-- +TABLE: name="parted_uniq_tbl_1" schema="" table="parted_uniq_tbl_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_uniq_tbl_1 PARTITION OF parted_uniq_tbl FOR VALUES FROM (0) TO (10)" +== 200 +-- truncate_limit: 100 +CREATE TABLE parted_uniq_tbl_2 PARTITION OF parted_uniq_tbl FOR VALUES FROM (20) TO (30) +-- +TABLE: name="parted_uniq_tbl_2" schema="" table="parted_uniq_tbl_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_uniq_tbl_2 PARTITION OF parted_uniq_tbl FOR VALUES FROM (20) TO (30)" +== 201 +-- truncate_limit: 100 +SELECT conname, conrelid::regclass FROM pg_constraint + WHERE conname LIKE 'parted_uniq%' ORDER BY conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conname LIKE 'parted_uniq%' ORDER BY conname" +== 202 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 203 +-- truncate_limit: 100 +INSERT INTO parted_uniq_tbl VALUES (1) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_uniq_tbl VALUES (1)" +== 204 +-- truncate_limit: 100 +SAVEPOINT f +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT f" +== 205 +-- truncate_limit: 100 +INSERT INTO parted_uniq_tbl VALUES (1) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_uniq_tbl VALUES (1)" +== 206 +-- truncate_limit: 100 +-- unique violation +ROLLBACK TO f +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT f" +== 207 +-- truncate_limit: 100 +SET CONSTRAINTS parted_uniq_tbl_i_key DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS parted_uniq_tbl_i_key DEFERRED" +== 208 +-- truncate_limit: 100 +INSERT INTO parted_uniq_tbl VALUES (1) +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_uniq_tbl VALUES (1)" +== 209 +-- truncate_limit: 100 +-- OK now, fail at commit +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 210 +-- truncate_limit: 100 +DROP TABLE parted_uniq_tbl +-- +TABLE: name="parted_uniq_tbl" schema="" table="parted_uniq_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_uniq_tbl" +== 211 +-- truncate_limit: 100 +-- test naming a constraint in a partition when a conflict exists +CREATE TABLE parted_fk_naming ( + id bigint NOT NULL default 1, + id_abc bigint, + CONSTRAINT dummy_constr FOREIGN KEY (id_abc) + REFERENCES parted_fk_naming (id), + PRIMARY KEY (id) +) +PARTITION BY LIST (id) +-- +TABLE: name="parted_fk_naming" schema="" table="parted_fk_naming" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_fk_naming (id bigint NOT NULL DEFAULT 1, id_abc bigint, CONSTRAINT dummy_cons..." +== 212 +-- truncate_limit: 100 +CREATE TABLE parted_fk_naming_1 ( + id bigint NOT NULL default 1, + id_abc bigint, + PRIMARY KEY (id), + CONSTRAINT dummy_constr CHECK (true) +) +-- +TABLE: name="parted_fk_naming_1" schema="" table="parted_fk_naming_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_fk_naming_1 (id bigint NOT NULL DEFAULT 1, id_abc bigint, PRIMARY KEY (id), C..." +== 213 +-- truncate_limit: 100 +ALTER TABLE parted_fk_naming ATTACH PARTITION parted_fk_naming_1 FOR VALUES IN ('1') +-- +TABLE: name="parted_fk_naming" schema="" table="parted_fk_naming" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_fk_naming ATTACH PARTITION parted_fk_naming_1 FOR VALUES IN ('1')" +== 214 +-- truncate_limit: 100 +SELECT conname FROM pg_constraint WHERE conrelid = 'parted_fk_naming_1'::regclass AND contype = 'f' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +FILTER: schema="" table="" column="contype" +STMT: SelectStmt +TRUNCATED: "SELECT conname FROM pg_constraint WHERE conrelid = 'parted_fk_naming_1'::regclass AND contype = 'f'" +== 215 +-- truncate_limit: 100 +DROP TABLE parted_fk_naming +-- +TABLE: name="parted_fk_naming" schema="" table="parted_fk_naming" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_fk_naming" +== 216 +-- truncate_limit: 100 +|-- +-- Test various ways to create primary keys on partitions, linked to unique +-- indexes (without constraints) on the partitioned table. Ideally these should +-- fail, but we don't dare change released behavior, so instead cope with it at +-- DETACH time. +CREATE TEMP TABLE t (a integer, b integer) PARTITION BY HASH (a, b) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t (a int, b int) PARTITION BY HASH (a, b)" +== 217 +-- truncate_limit: 100 +CREATE TEMP TABLE tp (a integer, b integer, PRIMARY KEY (a, b), UNIQUE (b, a)) +-- +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tp (a int, b int, PRIMARY KEY (a, b), UNIQUE (b, a))" +== 218 +-- truncate_limit: 100 +ALTER TABLE t ATTACH PARTITION tp FOR VALUES WITH (MODULUS 1, REMAINDER 0) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ATTACH PARTITION tp FOR VALUES WITH (MODULUS 1, REMAINDER 0)" +== 219 +-- truncate_limit: 100 +CREATE UNIQUE INDEX t_a_idx ON t (a, b) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX t_a_idx ON t USING btree (a, b)" +== 220 +-- truncate_limit: 100 +CREATE UNIQUE INDEX t_b_idx ON t (b, a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX t_b_idx ON t USING btree (b, a)" +== 221 +-- truncate_limit: 100 +ALTER INDEX t_a_idx ATTACH PARTITION tp_pkey +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX t_a_idx ATTACH PARTITION tp_pkey" +== 222 +-- truncate_limit: 100 +ALTER INDEX t_b_idx ATTACH PARTITION tp_b_a_key +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX t_b_idx ATTACH PARTITION tp_b_a_key" +== 223 +-- truncate_limit: 100 +SELECT conname, conparentid, conislocal, coninhcount + FROM pg_constraint WHERE conname IN ('tp_pkey', 'tp_b_a_key') + ORDER BY conname DESC +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conname IN ('tp_pkey', 'tp_b_a_key') ORDER BY conname DESC" +== 224 +-- truncate_limit: 100 +ALTER TABLE t DETACH PARTITION tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t DETACH PARTITION tp" +== 225 +-- truncate_limit: 100 +DROP TABLE t, tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t, tp" +== 226 +-- truncate_limit: 100 +CREATE TEMP TABLE t (a integer) PARTITION BY LIST (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t (a int) PARTITION BY LIST (a)" +== 227 +-- truncate_limit: 100 +CREATE TEMP TABLE tp (a integer PRIMARY KEY) +-- +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tp (a int PRIMARY KEY)" +== 228 +-- truncate_limit: 100 +CREATE UNIQUE INDEX t_a_idx ON t (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX t_a_idx ON t USING btree (a)" +== 229 +-- truncate_limit: 100 +ALTER TABLE t ATTACH PARTITION tp FOR VALUES IN (1) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ATTACH PARTITION tp FOR VALUES IN (1)" +== 230 +-- truncate_limit: 100 +ALTER TABLE t DETACH PARTITION tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t DETACH PARTITION tp" +== 231 +-- truncate_limit: 100 +DROP TABLE t, tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t, tp" +== 232 +-- truncate_limit: 100 +CREATE TEMP TABLE t (a integer) PARTITION BY LIST (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t (a int) PARTITION BY LIST (a)" +== 233 +-- truncate_limit: 100 +CREATE TEMP TABLE tp (a integer PRIMARY KEY) +-- +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tp (a int PRIMARY KEY)" +== 234 +-- truncate_limit: 100 +CREATE UNIQUE INDEX t_a_idx ON ONLY t (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX t_a_idx ON ONLY t USING btree (a)" +== 235 +-- truncate_limit: 100 +ALTER TABLE t ATTACH PARTITION tp FOR VALUES IN (1) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ATTACH PARTITION tp FOR VALUES IN (1)" +== 236 +-- truncate_limit: 100 +ALTER TABLE t DETACH PARTITION tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t DETACH PARTITION tp" +== 237 +-- truncate_limit: 100 +DROP TABLE t, tp +-- +TABLE: name="t" schema="" table="t" ctx=DDL +TABLE: name="tp" schema="" table="tp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t, tp" +== 238 +-- truncate_limit: 100 +CREATE TABLE regress_constr_partitioned (a integer) PARTITION BY LIST (a) +-- +TABLE: name="regress_constr_partitioned" schema="" table="regress_constr_partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE regress_constr_partitioned (a int) PARTITION BY LIST (a)" +== 239 +-- truncate_limit: 100 +CREATE TABLE regress_constr_partition1 PARTITION OF regress_constr_partitioned FOR VALUES IN (1) +-- +TABLE: name="regress_constr_partition1" schema="" table="regress_constr_partition1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE regress_constr_partition1 PARTITION OF regress_constr_partitioned FOR VALUES IN (1)" +== 240 +-- truncate_limit: 100 +ALTER TABLE regress_constr_partition1 ADD PRIMARY KEY (a) +-- +TABLE: name="regress_constr_partition1" schema="" table="regress_constr_partition1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE regress_constr_partition1 ADD PRIMARY KEY (a)" +== 241 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON regress_constr_partitioned (a) +-- +TABLE: name="regress_constr_partitioned" schema="" table="regress_constr_partitioned" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON regress_constr_partitioned USING btree (a)" +== 242 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 243 +-- truncate_limit: 100 +ALTER TABLE regress_constr_partitioned DETACH PARTITION regress_constr_partition1 +-- +TABLE: name="regress_constr_partitioned" schema="" table="regress_constr_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE regress_constr_partitioned DETACH PARTITION regress_constr_partition1" +== 244 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 245 +-- truncate_limit: 100 +-- Leave this one in funny state for pg_upgrade testing + +-- test a HOT update that invalidates the conflicting tuple. +-- the trigger should still fire and catch the violation + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 246 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (3, 'Three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'Three')" +== 247 +-- truncate_limit: 100 +-- should succeed for now +UPDATE unique_tbl SET t = 'THREE' WHERE i = 3 AND t = 'Three' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE unique_tbl SET t = 'THREE' WHERE i = 3 AND t = 'Three'" +== 248 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 249 +-- truncate_limit: 100 +-- should fail + +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 250 +-- truncate_limit: 100 +-- test a HOT update that modifies the newly inserted tuple, +-- but should succeed because we then remove the other conflicting tuple. + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 251 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES(3, 'tree') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'tree')" +== 252 +-- truncate_limit: 100 +-- should succeed for now +UPDATE unique_tbl SET t = 'threex' WHERE t = 'tree' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE unique_tbl SET t = 'threex' WHERE t = 'tree'" +== 253 +-- truncate_limit: 100 +DELETE FROM unique_tbl WHERE t = 'three' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM unique_tbl WHERE t = 'three'" +== 254 +-- truncate_limit: 100 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 255 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 256 +-- truncate_limit: 100 +SELECT * FROM unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unique_tbl" +== 257 +-- truncate_limit: 100 +DROP TABLE unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unique_tbl" +== 258 +-- truncate_limit: 100 +|-- +-- EXCLUDE constraints +|-- + +CREATE TABLE circles ( + c1 CIRCLE, + c2 TEXT, + EXCLUDE USING gist + (c1 WITH &&, (c2::circle) WITH &&) + WHERE (circle_center(c1) <> '(0,0)') +) +-- +TABLE: name="circles" schema="" table="circles" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE circles (c1 circle, c2 text, EXCLUDE USING gist (c1 WITH &&, (c2::circle) WITH &&) W..." +== 259 +-- truncate_limit: 100 +-- these should succeed because they don't match the index predicate +INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES ('<(0,0), 5>', '<(0,0), 5>')" +== 260 +-- truncate_limit: 100 +INSERT INTO circles VALUES('<(0,0), 5>', '<(0,0), 4>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES ('<(0,0), 5>', '<(0,0), 4>')" +== 261 +-- truncate_limit: 100 +-- succeed +INSERT INTO circles VALUES('<(10,10), 10>', '<(0,0), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES ('<(10,10), 10>', '<(0,0), 5>')" +== 262 +-- truncate_limit: 100 +-- fail, overlaps +INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES ('<(20,20), 10>', '<(0,0), 4>')" +== 263 +-- truncate_limit: 100 +-- succeed, because violation is ignored +INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>') + ON CONFLICT ON CONSTRAINT circles_c1_c2_excl DO NOTHING +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES (...) ON CONFLICT ON CONSTRAINT circles_c1_c2_excl DO NOTHING" +== 264 +-- truncate_limit: 100 +-- fail, because DO UPDATE variant requires unique index +INSERT INTO circles VALUES('<(20,20), 10>', '<(0,0), 4>') + ON CONFLICT ON CONSTRAINT circles_c1_c2_excl DO UPDATE SET c2 = EXCLUDED.c2 +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES (...) ON CONFLICT ON CONSTRAINT circles_c1_c2_excl DO UPDATE SET ... =..." +== 265 +-- truncate_limit: 100 +-- succeed because c1 doesn't overlap +INSERT INTO circles VALUES('<(20,20), 1>', '<(0,0), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES ('<(20,20), 1>', '<(0,0), 5>')" +== 266 +-- truncate_limit: 100 +-- succeed because c2 doesn't overlap +INSERT INTO circles VALUES('<(20,20), 10>', '<(10,10), 5>') +-- +TABLE: name="circles" schema="" table="circles" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO circles VALUES ('<(20,20), 10>', '<(10,10), 5>')" +== 267 +-- truncate_limit: 100 +-- should fail on existing data without the WHERE clause +ALTER TABLE circles ADD EXCLUDE USING gist + (c1 WITH &&, (c2::circle) WITH &&) +-- +TABLE: name="circles" schema="" table="circles" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE circles ADD EXCLUDE USING gist (c1 WITH &&, (c2::circle) WITH &&)" +== 268 +-- truncate_limit: 100 +-- try reindexing an existing constraint +REINDEX INDEX circles_c1_c2_excl +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX circles_c1_c2_excl" +== 269 +-- truncate_limit: 100 +DROP TABLE circles +-- +TABLE: name="circles" schema="" table="circles" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE circles" +== 270 +-- truncate_limit: 100 +-- Check deferred exclusion constraint + +CREATE TABLE deferred_excl ( + f1 int, + f2 int, + CONSTRAINT deferred_excl_con EXCLUDE (f1 WITH =) INITIALLY DEFERRED +) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE deferred_excl (f1 int, f2 int, CONSTRAINT deferred_excl_con EXCLUDE (f1 WITH =) DEFE..." +== 271 +-- truncate_limit: 100 +INSERT INTO deferred_excl VALUES(1) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (1)" +== 272 +-- truncate_limit: 100 +INSERT INTO deferred_excl VALUES(2) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (2)" +== 273 +-- truncate_limit: 100 +INSERT INTO deferred_excl VALUES(1) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (1)" +== 274 +-- truncate_limit: 100 +-- fail +INSERT INTO deferred_excl VALUES(1) ON CONFLICT ON CONSTRAINT deferred_excl_con DO NOTHING +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (1) ON CONFLICT ON CONSTRAINT deferred_excl_con DO NOTHING" +== 275 +-- truncate_limit: 100 +-- fail +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 276 +-- truncate_limit: 100 +INSERT INTO deferred_excl VALUES(2) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (2)" +== 277 +-- truncate_limit: 100 +-- no fail here +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 278 +-- truncate_limit: 100 +-- should fail here +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 279 +-- truncate_limit: 100 +INSERT INTO deferred_excl VALUES(3) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (3)" +== 280 +-- truncate_limit: 100 +INSERT INTO deferred_excl VALUES(3) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (3)" +== 281 +-- truncate_limit: 100 +-- no fail here +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 282 +-- truncate_limit: 100 +-- should fail here + +-- bug #13148: deferred constraint versus HOT update +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 283 +-- truncate_limit: 100 +INSERT INTO deferred_excl VALUES(2, 1) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO deferred_excl VALUES (2, 1)" +== 284 +-- truncate_limit: 100 +-- no fail here +DELETE FROM deferred_excl WHERE f1 = 2 AND f2 IS NULL +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM deferred_excl WHERE f1 = 2 AND f2 IS NULL" +== 285 +-- truncate_limit: 100 +-- remove old row +UPDATE deferred_excl SET f2 = 2 WHERE f1 = 2 +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE deferred_excl SET f2 = 2 WHERE f1 = 2" +== 286 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 287 +-- truncate_limit: 100 +-- should not fail + +SELECT * FROM deferred_excl +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM deferred_excl" +== 288 +-- truncate_limit: 100 +ALTER TABLE deferred_excl DROP CONSTRAINT deferred_excl_con +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE deferred_excl DROP CONSTRAINT deferred_excl_con" +== 289 +-- truncate_limit: 100 +-- This should fail, but worth testing because of HOT updates +UPDATE deferred_excl SET f1 = 3 +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE deferred_excl SET f1 = 3" +== 290 +-- truncate_limit: 100 +ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =) +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =)" +== 291 +-- truncate_limit: 100 +DROP TABLE deferred_excl +-- +TABLE: name="deferred_excl" schema="" table="deferred_excl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE deferred_excl" +== 292 +-- truncate_limit: 100 +-- Comments +-- Setup a low-level role to enforce non-superuser checks. +CREATE ROLE regress_constraint_comments +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_constraint_comments" +== 293 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_constraint_comments +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_constraint_comments" +== 294 +-- truncate_limit: 100 +CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0)) +-- +TABLE: name="constraint_comments_tbl" schema="" table="constraint_comments_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0))" +== 295 +-- truncate_limit: 100 +CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0)" +== 296 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'yes, the comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'yes, the comment'" +== 297 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment'" +== 298 +-- truncate_limit: 100 +-- no such constraint +COMMENT ON CONSTRAINT no_constraint ON constraint_comments_tbl IS 'yes, the comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT no_constraint ON constraint_comments_tbl IS 'yes, the comment'" +== 299 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT no_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT no_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment'" +== 300 +-- truncate_limit: 100 +-- no such table/domain +COMMENT ON CONSTRAINT the_constraint ON no_comments_tbl IS 'bad comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON no_comments_tbl IS 'bad comment'" +== 301 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad comment'" +== 302 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL" +== 303 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL" +== 304 +-- truncate_limit: 100 +-- unauthorized user +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 305 +-- truncate_limit: 100 +CREATE ROLE regress_constraint_comments_noaccess +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_constraint_comments_noaccess" +== 306 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_constraint_comments_noaccess +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_constraint_comments_noaccess" +== 307 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'no, the comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'no, the comment'" +== 308 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'no, another comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'no, another comment'" +== 309 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 310 +-- truncate_limit: 100 +DROP TABLE constraint_comments_tbl +-- +TABLE: name="constraint_comments_tbl" schema="" table="constraint_comments_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE constraint_comments_tbl" +== 311 +-- truncate_limit: 100 +DROP DOMAIN constraint_comments_dom +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN constraint_comments_dom" +== 312 +-- truncate_limit: 100 +DROP ROLE regress_constraint_comments +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_constraint_comments" +== 313 +-- truncate_limit: 100 +DROP ROLE regress_constraint_comments_noaccess +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_constraint_comments_noaccess" +== 314 +-- truncate_limit: 100 +-- Leave some constraints for the pg_upgrade test to pick up +CREATE DOMAIN constraint_comments_dom AS int +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN constraint_comments_dom AS int" +== 315 +-- truncate_limit: 100 +ALTER DOMAIN constraint_comments_dom ADD CONSTRAINT inv_ck CHECK (value > 0) NOT VALID +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN constraint_comments_dom ADD CONSTRAINT inv_ck CHECK (value > 0) NOT VALID" +== 316 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT inv_ck ON DOMAIN constraint_comments_dom IS 'comment on invalid constraint' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT inv_ck ON DOMAIN constraint_comments_dom IS 'comment on invalid constraint'" +== 317 +-- truncate_limit: 100 +-- Create a table that exercises pg_upgrade +CREATE TABLE regress_notnull1 (a integer) +-- +TABLE: name="regress_notnull1" schema="" table="regress_notnull1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE regress_notnull1 (a int)" +== 318 +-- truncate_limit: 100 +CREATE TABLE regress_notnull2 () INHERITS (regress_notnull1) +-- +TABLE: name="regress_notnull2" schema="" table="regress_notnull2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE regress_notnull2 () INHERITS (regress_notnull1)" +== 319 +-- truncate_limit: 100 +ALTER TABLE ONLY regress_notnull2 ALTER COLUMN a SET NOT NULL +-- +TABLE: name="regress_notnull2" schema="" table="regress_notnull2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY regress_notnull2 ALTER COLUMN a SET NOT NULL" diff --git a/parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json b/parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json new file mode 100644 index 0000000..8836c0c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json @@ -0,0 +1,69 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/conversion.test b/parser/testdata/summary_truncate/postgres_regress/conversion.test new file mode 100644 index 0000000..1e1a5fd --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/conversion.test @@ -0,0 +1,805 @@ +== 001 +-- truncate_limit: 100 +|-- +-- create user defined conversion +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION test_enc_setup() RETURNS void + AS :'regresslib', 'test_enc_setup' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 171 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +SELECT FROM test_enc_setup() +-- +FUNCTION: name="test_enc_setup" function="test_enc_setup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM test_enc_setup()" +== 003 +-- truncate_limit: 100 +CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea) + AS :'regresslib', 'test_enc_conversion' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 105 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +CREATE USER regress_conversion_user WITH NOCREATEDB NOCREATEROLE +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_conversion_user WITH NOCREATEDB NOCREATEROLE" +== 005 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_conversion_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_conversion_user" +== 006 +-- truncate_limit: 100 +CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 007 +-- truncate_limit: 100 +|-- +-- cannot make same name conversion in same schema +|-- +CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 008 +-- truncate_limit: 100 +|-- +-- create default conversion with qualified name +|-- +CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 009 +-- truncate_limit: 100 +|-- +-- cannot make default conversion with same schema/for_encoding/to_encoding +|-- +CREATE DEFAULT CONVERSION public.mydef2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE DEFAULT CONVERSION public.mydef2 FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 010 +-- truncate_limit: 100 +-- test comments +COMMENT ON CONVERSION myconv_bad IS 'foo' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONVERSION myconv_bad IS 'foo'" +== 011 +-- truncate_limit: 100 +COMMENT ON CONVERSION myconv IS 'bar' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONVERSION myconv IS 'bar'" +== 012 +-- truncate_limit: 100 +COMMENT ON CONVERSION myconv IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONVERSION myconv IS NULL" +== 013 +-- truncate_limit: 100 +|-- +-- drop user defined conversion +|-- +DROP CONVERSION myconv +-- +STMT: DropStmt +TRUNCATED: "DROP CONVERSION myconv" +== 014 +-- truncate_limit: 100 +DROP CONVERSION mydef +-- +STMT: DropStmt +TRUNCATED: "DROP CONVERSION mydef" +== 015 +-- truncate_limit: 100 +|-- +-- Note: the built-in conversions are exercised in opr_sanity.sql, +-- so there's no need to do that here. +|-- +|-- +-- return to the superuser +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 016 +-- truncate_limit: 100 +DROP USER regress_conversion_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_conversion_user" +== 017 +-- truncate_limit: 100 +|-- +-- Test built-in conversion functions. +|-- + +-- Helper function to test a conversion. Uses the test_enc_conversion function +-- that was created in the create_function_0 test. +create or replace function test_conv( + input IN bytea, + src_encoding IN text, + dst_encoding IN text, + + result OUT bytea, + errorat OUT bytea, + error OUT text) +language plpgsql as +$$ +declare + validlen int; +begin + -- First try to perform the conversion with noError = false. If that errors out, + -- capture the error message, and try again with noError = true. The second call + -- should succeed and return the position of the error, return that too. + begin + select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, false); + errorat = NULL; + error := NULL; + exception when others then + error := sqlerrm; + select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, true); + errorat = substr(input, validlen + 1); + end; + return; +end; +$$ +-- +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION test_conv(IN input bytea, IN src_encoding text, IN dst_encoding text, ..." +== 018 +-- truncate_limit: 100 +|-- +-- UTF-8 +|-- +-- The description column must be unique. +CREATE TABLE utf8_verification_inputs (inbytes bytea, description text PRIMARY KEY) +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE utf8_verification_inputs (inbytes bytea, description text PRIMARY KEY)" +== 019 +-- truncate_limit: 100 +insert into utf8_verification_inputs values + ('\x66006f', 'NUL byte'), + ('\xaf', 'bare continuation'), + ('\xc5', 'missing second byte in 2-byte char'), + ('\xc080', 'smallest 2-byte overlong'), + ('\xc1bf', 'largest 2-byte overlong'), + ('\xc280', 'next 2-byte after overlongs'), + ('\xdfbf', 'largest 2-byte'), + ('\xe9af', 'missing third byte in 3-byte char'), + ('\xe08080', 'smallest 3-byte overlong'), + ('\xe09fbf', 'largest 3-byte overlong'), + ('\xe0a080', 'next 3-byte after overlong'), + ('\xed9fbf', 'last before surrogates'), + ('\xeda080', 'smallest surrogate'), + ('\xedbfbf', 'largest surrogate'), + ('\xee8080', 'next after surrogates'), + ('\xefbfbf', 'largest 3-byte'), + ('\xf1afbf', 'missing fourth byte in 4-byte char'), + ('\xf0808080', 'smallest 4-byte overlong'), + ('\xf08fbfbf', 'largest 4-byte overlong'), + ('\xf0908080', 'next 4-byte after overlong'), + ('\xf48fbfbf', 'largest 4-byte'), + ('\xf4908080', 'smallest too large'), + ('\xfa9a9a8a8a', '5-byte') +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO utf8_verification_inputs VALUES (...)" +== 020 +-- truncate_limit: 100 +-- Test UTF-8 verification slow path +select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_verification_inputs +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, (test_conv(inbytes, 'utf8', 'utf8')).* FROM utf8_verification_inputs" +== 021 +-- truncate_limit: 100 +-- Test UTF-8 verification with ASCII padding appended to provide +-- coverage for algorithms that work on multiple bytes at a time. +-- The error message for a sequence starting with a 4-byte lead +-- will contain all 4 bytes if they are present, so various +-- expressions below add 3 ASCII bytes to the end to ensure +-- consistent error messages. +-- The number 64 below needs to be at least the value of STRIDE_LENGTH in wchar.c. + +-- Test multibyte verification in fast path +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +TRUNCATED: "WITH test_bytes AS (...), test_padded AS (...) SELECT ... FROM test_padded p JOIN test_bytes b US..." +== 022 +-- truncate_limit: 100 +-- Test ASCII verification in fast path where incomplete +-- UTF-8 sequences fall at the end of the preceding chunk. +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +TRUNCATED: "WITH test_bytes AS (...), test_padded AS (...) SELECT ... FROM test_padded p JOIN test_bytes b US..." +== 023 +-- truncate_limit: 100 +-- Test cases where UTF-8 sequences within short text +-- come after the fast path returns. +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64)::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +TRUNCATED: "WITH test_bytes AS (...), test_padded AS (...) SELECT ... FROM test_padded p JOIN test_bytes b US..." +== 024 +-- truncate_limit: 100 +-- Test cases where incomplete UTF-8 sequences fall at the +-- end of the part checked by the fast path. +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description +-- +TABLE: name="utf8_verification_inputs" schema="" table="utf8_verification_inputs" ctx=Select +ALIAS: "b"="test_bytes" +ALIAS: "p"="test_padded" +CTE: "test_bytes" +CTE: "test_padded" +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="p" column="error" +FILTER: schema="" table="b" column="error" +STMT: SelectStmt +TRUNCATED: "WITH test_bytes AS (...), test_padded AS (...) SELECT ... FROM test_padded p JOIN test_bytes b US..." +== 025 +-- truncate_limit: 100 +CREATE TABLE utf8_inputs (inbytes bytea, description text) +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE utf8_inputs (inbytes bytea, description text)" +== 026 +-- truncate_limit: 100 +insert into utf8_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\xc3a4c3b6', 'valid, extra latin chars'), + ('\xd184d0bed0be', 'valid, cyrillic'), + ('\x666f6fe8b1a1', 'valid, kanji/Chinese'), + ('\xe382abe3829a', 'valid, two chars that combine to one in EUC_JIS_2004'), + ('\xe382ab', 'only first half of combined char in EUC_JIS_2004'), + ('\xe382abe382', 'incomplete combination when converted EUC_JIS_2004'), + ('\xecbd94eb81bceba6ac', 'valid, Hangul, Korean'), + ('\x666f6fefa8aa', 'valid, needs mapping function to convert to GB18030'), + ('\x66e8b1ff6f6f', 'invalid byte sequence'), + ('\x66006f', 'invalid, NUL byte'), + ('\x666f6fe8b100', 'invalid, NUL byte'), + ('\x666f6fe8b1', 'incomplete character at end') +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO utf8_inputs VALUES (...)" +== 027 +-- truncate_limit: 100 +-- Test UTF-8 verification +select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, (test_conv(inbytes, 'utf8', 'utf8')).* FROM utf8_inputs" +== 028 +-- truncate_limit: 100 +-- Test conversions from UTF-8 +select description, inbytes, (test_conv(inbytes, 'utf8', 'euc_jis_2004')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'utf8', 'euc_jis_2004')).* FROM utf8_inputs" +== 029 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin1')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'utf8', 'latin1')).* FROM utf8_inputs" +== 030 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin2')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'utf8', 'latin2')).* FROM utf8_inputs" +== 031 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin5')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'utf8', 'latin5')).* FROM utf8_inputs" +== 032 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'utf8', 'koi8r')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'utf8', 'koi8r')).* FROM utf8_inputs" +== 033 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'utf8', 'gb18030')).* from utf8_inputs +-- +TABLE: name="utf8_inputs" schema="" table="utf8_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'utf8', 'gb18030')).* FROM utf8_inputs" +== 034 +-- truncate_limit: 100 +|-- +-- EUC_JIS_2004 +|-- +CREATE TABLE euc_jis_2004_inputs (inbytes bytea, description text) +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE euc_jis_2004_inputs (inbytes bytea, description text)" +== 035 +-- truncate_limit: 100 +insert into euc_jis_2004_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fbedd', 'valid'), + ('\xa5f7', 'valid, translates to two UTF-8 chars '), + ('\xbeddbe', 'incomplete char '), + ('\x666f6f00bedd', 'invalid, NUL byte'), + ('\x666f6fbe00dd', 'invalid, NUL byte'), + ('\x666f6fbedd00', 'invalid, NUL byte'), + ('\xbe04', 'invalid byte sequence') +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO euc_jis_2004_inputs VALUES (...)" +== 036 +-- truncate_limit: 100 +-- Test EUC_JIS_2004 verification +select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'euc_jis_2004')).* from euc_jis_2004_inputs +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM euc_jis_2004_inputs" +== 037 +-- truncate_limit: 100 +-- Test conversions from EUC_JIS_2004 +select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'utf8')).* from euc_jis_2004_inputs +-- +TABLE: name="euc_jis_2004_inputs" schema="" table="euc_jis_2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'utf8')).* FROM euc_jis_2004_inputs" +== 038 +-- truncate_limit: 100 +|-- +-- SHIFT-JIS-2004 +|-- +CREATE TABLE shiftjis2004_inputs (inbytes bytea, description text) +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE shiftjis2004_inputs (inbytes bytea, description text)" +== 039 +-- truncate_limit: 100 +insert into shiftjis2004_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6f8fdb', 'valid'), + ('\x666f6f81c0', 'valid, no translation to UTF-8'), + ('\x666f6f82f5', 'valid, translates to two UTF-8 chars '), + ('\x666f6f8fdb8f', 'incomplete char '), + ('\x666f6f820a', 'incomplete char, followed by newline '), + ('\x666f6f008fdb', 'invalid, NUL byte'), + ('\x666f6f8f00db', 'invalid, NUL byte'), + ('\x666f6f8fdb00', 'invalid, NUL byte') +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shiftjis2004_inputs VALUES (...)" +== 040 +-- truncate_limit: 100 +-- Test SHIFT-JIS-2004 verification +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'shiftjis2004')).* from shiftjis2004_inputs +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM shiftjis2004_inputs" +== 041 +-- truncate_limit: 100 +-- Test conversions from SHIFT-JIS-2004 +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'utf8')).* from shiftjis2004_inputs +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'utf8')).* FROM shiftjis2004_inputs" +== 042 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'euc_jis_2004')).* from shiftjis2004_inputs +-- +TABLE: name="shiftjis2004_inputs" schema="" table="shiftjis2004_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM shiftjis2004_inputs" +== 043 +-- truncate_limit: 100 +|-- +-- GB18030 +|-- +CREATE TABLE gb18030_inputs (inbytes bytea, description text) +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gb18030_inputs (inbytes bytea, description text)" +== 044 +-- truncate_limit: 100 +insert into gb18030_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fcff3', 'valid'), + ('\x666f6f8431a530', 'valid, no translation to UTF-8'), + ('\x666f6f84309c38', 'valid, translates to UTF-8 by mapping function'), + ('\x666f6f84309c', 'incomplete char '), + ('\x666f6f84309c0a', 'incomplete char, followed by newline '), + ('\x666f6f84', 'incomplete char at end'), + ('\x666f6f84309c3800', 'invalid, NUL byte'), + ('\x666f6f84309c0038', 'invalid, NUL byte') +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gb18030_inputs VALUES (...)" +== 045 +-- truncate_limit: 100 +-- Test GB18030 verification. Round-trip through text so the backing of the +-- bytea values is palloc, not shared_buffers. This lets Valgrind detect +-- reads past the end. +select description, inbytes, (test_conv(inbytes::text::bytea, 'gb18030', 'gb18030')).* from gb18030_inputs +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gb18030_inputs" +== 046 +-- truncate_limit: 100 +-- Test conversions from GB18030 +select description, inbytes, (test_conv(inbytes, 'gb18030', 'utf8')).* from gb18030_inputs +-- +TABLE: name="gb18030_inputs" schema="" table="gb18030_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'gb18030', 'utf8')).* FROM gb18030_inputs" +== 047 +-- truncate_limit: 100 +|-- +-- ISO-8859-5 +|-- +CREATE TABLE iso8859_5_inputs (inbytes bytea, description text) +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iso8859_5_inputs (inbytes bytea, description text)" +== 048 +-- truncate_limit: 100 +insert into iso8859_5_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\xe4dede', 'valid'), + ('\x00', 'invalid, NUL byte'), + ('\xe400dede', 'invalid, NUL byte'), + ('\xe4dede00', 'invalid, NUL byte') +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iso8859_5_inputs VALUES (...)" +== 049 +-- truncate_limit: 100 +-- Test ISO-8859-5 verification +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'iso8859-5')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'iso8859-5', 'iso8859-5')).* FROM iso8859_5_inputs" +== 050 +-- truncate_limit: 100 +-- Test conversions from ISO-8859-5 +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'utf8')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'iso8859-5', 'utf8')).* FROM iso8859_5_inputs" +== 051 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'koi8r')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'iso8859-5', 'koi8r')).* FROM iso8859_5_inputs" +== 052 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'iso8859_5', 'mule_internal')).* from iso8859_5_inputs +-- +TABLE: name="iso8859_5_inputs" schema="" table="iso8859_5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM iso8859_5_inputs" +== 053 +-- truncate_limit: 100 +|-- +-- Big5 +|-- +CREATE TABLE big5_inputs (inbytes bytea, description text) +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE big5_inputs (inbytes bytea, description text)" +== 054 +-- truncate_limit: 100 +insert into big5_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fb648', 'valid'), + ('\x666f6fa27f', 'valid, no translation to UTF-8'), + ('\x666f6fb60048', 'invalid, NUL byte'), + ('\x666f6fb64800', 'invalid, NUL byte') +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO big5_inputs VALUES (...)" +== 055 +-- truncate_limit: 100 +-- Test Big5 verification +select description, inbytes, (test_conv(inbytes, 'big5', 'big5')).* from big5_inputs +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'big5', 'big5')).* FROM big5_inputs" +== 056 +-- truncate_limit: 100 +-- Test conversions from Big5 +select description, inbytes, (test_conv(inbytes, 'big5', 'utf8')).* from big5_inputs +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'big5', 'utf8')).* FROM big5_inputs" +== 057 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'big5', 'mule_internal')).* from big5_inputs +-- +TABLE: name="big5_inputs" schema="" table="big5_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'big5', 'mule_internal')).* FROM big5_inputs" +== 058 +-- truncate_limit: 100 +|-- +-- MULE_INTERNAL +|-- +CREATE TABLE mic_inputs (inbytes bytea, description text) +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mic_inputs (inbytes bytea, description text)" +== 059 +-- truncate_limit: 100 +insert into mic_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x8bc68bcf8bcf', 'valid (in KOI8R)'), + ('\x8bc68bcf8b', 'invalid,incomplete char'), + ('\x92bedd', 'valid (in SHIFT_JIS)'), + ('\x92be', 'invalid, incomplete char)'), + ('\x666f6f95a3c1', 'valid (in Big5)'), + ('\x666f6f95a3', 'invalid, incomplete char'), + ('\x9200bedd', 'invalid, NUL byte'), + ('\x92bedd00', 'invalid, NUL byte'), + ('\x8b00c68bcf8bcf', 'invalid, NUL byte') +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mic_inputs VALUES (...)" +== 060 +-- truncate_limit: 100 +-- Test MULE_INTERNAL verification +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'mule_internal')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM mic_inputs" +== 061 +-- truncate_limit: 100 +-- Test conversions from MULE_INTERNAL +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'koi8r')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'mule_internal', 'koi8r')).* FROM mic_inputs" +== 062 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'iso8859-5')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'mule_internal', 'iso8859-5')).* FROM mic_inputs" +== 063 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'sjis')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'mule_internal', 'sjis')).* FROM mic_inputs" +== 064 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'big5')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'mule_internal', 'big5')).* FROM mic_inputs" +== 065 +-- truncate_limit: 100 +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'euc_jp')).* from mic_inputs +-- +TABLE: name="mic_inputs" schema="" table="mic_inputs" ctx=Select +FUNCTION: name="test_conv" function="test_conv" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT description, inbytes, (test_conv(inbytes, 'mule_internal', 'euc_jp')).* FROM mic_inputs" diff --git a/parser/testdata/summary_truncate/postgres_regress/copy.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copy.metadata.json new file mode 100644 index 0000000..8e8d1f7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copy.metadata.json @@ -0,0 +1,91 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/copy.test b/parser/testdata/summary_truncate/postgres_regress/copy.test new file mode 100644 index 0000000..092a0f8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copy.test @@ -0,0 +1,759 @@ +== 001 +-- truncate_limit: 100 +|-- +-- COPY +|-- + +-- directory paths are passed to us in environment variables + +--- test copying in CSV mode with various styles +--- of embedded line ending characters + +create temp table copytest ( + style text, + test text, + filler int) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE copytest (style text, test text, filler int)" +== 002 +-- truncate_limit: 100 +insert into copytest values('DOS',E'abc\r\ndef',1) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copytest VALUES ('DOS', 'abc\r\ndef', 1)" +== 003 +-- truncate_limit: 100 +insert into copytest values('Unix',E'abc\ndef',2) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copytest VALUES ('Unix', 'abc\ndef', 2)" +== 004 +-- truncate_limit: 100 +insert into copytest values('Mac',E'abc\rdef',3) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copytest VALUES ('Mac', 'abc\rdef', 3)" +== 005 +-- truncate_limit: 100 +insert into copytest values(E'esc\\ape',E'a\\r\\\r\\\n\\nb',4) +-- +TABLE: name="copytest" schema="" table="copytest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copytest VALUES (E'esc\\\\ape', E'a\\\\r\\\\\r\\\\\n\\\\nb', 4)" +== 006 +-- truncate_limit: 100 +copy copytest to :'filename' csv +-- +ERROR: syntax error at or near ":" +CURSORPOS: 18 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- truncate_limit: 100 +create temp table copytest2 (like copytest) +-- +TABLE: name="copytest2" schema="" table="copytest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE copytest2 (LIKE copytest)" +== 008 +-- truncate_limit: 100 +copy copytest2 from :'filename' csv +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- truncate_limit: 100 +select * from copytest except select * from copytest2 +-- +TABLE: name="copytest" schema="" table="copytest" ctx=Select +TABLE: name="copytest2" schema="" table="copytest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM copytest EXCEPT SELECT * FROM copytest2" +== 010 +-- truncate_limit: 100 +truncate copytest2 +-- +TABLE: name="copytest2" schema="" table="copytest2" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE copytest2" +== 011 +-- truncate_limit: 100 +--- same test but with an escape char different from quote char + +copy copytest to :'filename' csv quote '''' escape E'\\' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 83 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- truncate_limit: 100 +copy copytest2 from :'filename' csv quote '''' escape E'\\' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 013 +-- truncate_limit: 100 +select * from copytest except select * from copytest2 +-- +TABLE: name="copytest" schema="" table="copytest" ctx=Select +TABLE: name="copytest2" schema="" table="copytest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM copytest EXCEPT SELECT * FROM copytest2" +== 014 +-- truncate_limit: 100 +-- test header line feature + +create temp table copytest3 ( + c1 int, + "col with , comma" text, + "col with "" quote" int) +-- +TABLE: name="copytest3" schema="" table="copytest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE copytest3 (c1 int, \"col with , comma\" text, \"col with \"\" quote\" int)" +== 015 +-- truncate_limit: 100 +copy copytest3 from stdin csv header +-- +TABLE: name="copytest3" schema="" table="copytest3" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copytest3 FROM STDIN CSV HEADER" +== 016 +-- truncate_limit: 100 +copy copytest3 to stdout csv header +-- +TABLE: name="copytest3" schema="" table="copytest3" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copytest3 TO STDOUT CSV HEADER" +== 017 +-- truncate_limit: 100 +create temp table copytest4 ( + c1 int, + "colname with tab: " text) +-- +TABLE: name="copytest4" schema="" table="copytest4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE copytest4 (c1 int, \"colname with tab: \t\" text)" +== 018 +-- truncate_limit: 100 +copy copytest4 from stdin (header) +-- +TABLE: name="copytest4" schema="" table="copytest4" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copytest4 FROM STDIN WITH (HEADER)" +== 019 +-- truncate_limit: 100 +copy copytest4 to stdout (header) +-- +TABLE: name="copytest4" schema="" table="copytest4" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copytest4 TO STDOUT WITH (HEADER)" +== 020 +-- truncate_limit: 100 +-- test copy from with a partitioned table +create table parted_copytest ( + a int, + b int, + c text +) partition by list (b) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_copytest (a int, b int, c text) PARTITION BY LIST (b)" +== 021 +-- truncate_limit: 100 +create table parted_copytest_a1 (c text, b int, a int) +-- +TABLE: name="parted_copytest_a1" schema="" table="parted_copytest_a1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_copytest_a1 (c text, b int, a int)" +== 022 +-- truncate_limit: 100 +create table parted_copytest_a2 (a int, c text, b int) +-- +TABLE: name="parted_copytest_a2" schema="" table="parted_copytest_a2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_copytest_a2 (a int, c text, b int)" +== 023 +-- truncate_limit: 100 +alter table parted_copytest attach partition parted_copytest_a1 for values in(1) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_copytest ATTACH PARTITION parted_copytest_a1 FOR VALUES IN (1)" +== 024 +-- truncate_limit: 100 +alter table parted_copytest attach partition parted_copytest_a2 for values in(2) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_copytest ATTACH PARTITION parted_copytest_a2 FOR VALUES IN (2)" +== 025 +-- truncate_limit: 100 +-- We must insert enough rows to trigger multi-inserts. These are only +-- enabled adaptively when there are few enough partition changes. +insert into parted_copytest select x,1,'One' from generate_series(1,1000) x +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_copytest SELECT x, 1, 'One' FROM generate_series(1, 1000) x" +== 026 +-- truncate_limit: 100 +insert into parted_copytest select x,2,'Two' from generate_series(1001,1010) x +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_copytest SELECT x, 2, 'Two' FROM generate_series(1001, 1010) x" +== 027 +-- truncate_limit: 100 +insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_copytest SELECT x, 1, 'One' FROM generate_series(1011, 1020) x" +== 028 +-- truncate_limit: 100 +copy (select * from parted_copytest order by a) to :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 52 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +-- truncate_limit: 100 +truncate parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_copytest" +== 030 +-- truncate_limit: 100 +copy parted_copytest from :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 031 +-- truncate_limit: 100 +-- Ensure COPY FREEZE errors for partitioned tables. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 032 +-- truncate_limit: 100 +truncate parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_copytest" +== 033 +-- truncate_limit: 100 +copy parted_copytest from :'filename' (freeze) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 034 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 035 +-- truncate_limit: 100 +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM parted_copytest GROUP BY tableoid ORDER BY tableoid::regclass::name" +== 036 +-- truncate_limit: 100 +truncate parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_copytest" +== 037 +-- truncate_limit: 100 +-- create before insert row trigger on parted_copytest_a2 +create function part_ins_func() returns trigger language plpgsql as $$ +begin + return new; +end; +$$ +-- +FUNCTION: name="part_ins_func" function="part_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION part_ins_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n return new;\nend;\n$$" +== 038 +-- truncate_limit: 100 +create trigger part_ins_trig + before insert on parted_copytest_a2 + for each row + execute procedure part_ins_func() +-- +TABLE: name="parted_copytest_a2" schema="" table="parted_copytest_a2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER part_ins_trig BEFORE INSERT ON parted_copytest_a2 FOR EACH ROW EXECUTE FUNCTION pa..." +== 039 +-- truncate_limit: 100 +copy parted_copytest from :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 040 +-- truncate_limit: 100 +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM parted_copytest GROUP BY tableoid ORDER BY tableoid::regclass::name" +== 041 +-- truncate_limit: 100 +truncate table parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_copytest" +== 042 +-- truncate_limit: 100 +create index on parted_copytest (b) +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON parted_copytest USING btree (b)" +== 043 +-- truncate_limit: 100 +drop trigger part_ins_trig on parted_copytest_a2 +-- +TABLE: name="parted_copytest_a2" schema="" table="parted_copytest_a2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER part_ins_trig ON parted_copytest_a2" +== 044 +-- truncate_limit: 100 +copy parted_copytest from stdin +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parted_copytest FROM STDIN" +== 045 +-- truncate_limit: 100 +-- Ensure index entries were properly added during the copy. +select * from parted_copytest where b = 1 +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_copytest WHERE b = 1" +== 046 +-- truncate_limit: 100 +select * from parted_copytest where b = 2 +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_copytest WHERE b = 2" +== 047 +-- truncate_limit: 100 +drop table parted_copytest +-- +TABLE: name="parted_copytest" schema="" table="parted_copytest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_copytest" +== 048 +-- truncate_limit: 100 +|-- +-- Progress reporting for COPY +|-- +create table tab_progress_reporting ( + name text, + age int4, + location point, + salary int4, + manager name +) +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tab_progress_reporting (name text, age int4, location point, salary int4, manager name)" +== 049 +-- truncate_limit: 100 +-- Add a trigger to catch and print the contents of the catalog view +-- pg_stat_progress_copy during data insertion. This allows to test +-- the validation of some progress reports for COPY FROM where the trigger +-- would fire. +create function notice_after_tab_progress_reporting() returns trigger AS +$$ +declare report record; +begin + -- The fields ignored here are the ones that may not remain + -- consistent across multiple runs. The sizes reported may differ + -- across platforms, so just check if these are strictly positive. + with progress_data as ( + select + relid::regclass::text as relname, + command, + type, + bytes_processed > 0 as has_bytes_processed, + bytes_total > 0 as has_bytes_total, + tuples_processed, + tuples_excluded + from pg_stat_progress_copy + where pid = pg_backend_pid()) + select into report (to_jsonb(r)) as value + from progress_data r; + + raise info 'progress: %', report.value::text; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="notice_after_tab_progress_reporting" function="notice_after_tab_progress_reporting" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION notice_after_tab_progress_reporting() RETURNS trigger AS $$\ndeclare report record..." +== 050 +-- truncate_limit: 100 +create trigger check_after_tab_progress_reporting + after insert on tab_progress_reporting + for each statement + execute function notice_after_tab_progress_reporting() +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER check_after_tab_progress_reporting AFTER INSERT ON tab_progress_reporting EXECUTE ..." +== 051 +-- truncate_limit: 100 +-- Generate COPY FROM report with PIPE. +copy tab_progress_reporting from stdin +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY tab_progress_reporting FROM STDIN" +== 052 +-- truncate_limit: 100 +-- Generate COPY FROM report with FILE, with some excluded tuples. +truncate tab_progress_reporting +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE tab_progress_reporting" +== 053 +-- truncate_limit: 100 +copy tab_progress_reporting from :'filename' + where (salary < 2000) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 054 +-- truncate_limit: 100 +drop trigger check_after_tab_progress_reporting on tab_progress_reporting +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER check_after_tab_progress_reporting ON tab_progress_reporting" +== 055 +-- truncate_limit: 100 +drop function notice_after_tab_progress_reporting() +-- +FUNCTION: name="notice_after_tab_progress_reporting" function="notice_after_tab_progress_reporting" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION notice_after_tab_progress_reporting()" +== 056 +-- truncate_limit: 100 +drop table tab_progress_reporting +-- +TABLE: name="tab_progress_reporting" schema="" table="tab_progress_reporting" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tab_progress_reporting" +== 057 +-- truncate_limit: 100 +-- Test header matching feature +create table header_copytest ( + a int, + b int, + c text +) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE header_copytest (a int, b int, c text)" +== 058 +-- truncate_limit: 100 +-- Make sure it works with dropped columns +alter table header_copytest drop column c +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE header_copytest DROP c" +== 059 +-- truncate_limit: 100 +alter table header_copytest add column c text +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE header_copytest ADD COLUMN c text" +== 060 +-- truncate_limit: 100 +copy header_copytest to stdout with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest TO STDOUT WITH (HEADER match)" +== 061 +-- truncate_limit: 100 +copy header_copytest from stdin with (header wrong_choice) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest FROM STDIN WITH (HEADER wrong_choice)" +== 062 +-- truncate_limit: 100 +copy header_copytest (c, a, b) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest(c, a, b) FROM STDIN WITH (HEADER match)" +== 063 +-- truncate_limit: 100 +copy header_copytest from stdin with (header match, format csv) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest FROM STDIN WITH (HEADER match, FORMAT CSV)" +== 064 +-- truncate_limit: 100 +-- errors +copy header_copytest (c, b, a) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest(c, b, a) FROM STDIN WITH (HEADER match)" +== 065 +-- truncate_limit: 100 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest FROM STDIN WITH (HEADER match)" +== 066 +-- truncate_limit: 100 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest FROM STDIN WITH (HEADER match)" +== 067 +-- truncate_limit: 100 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest FROM STDIN WITH (HEADER match)" +== 068 +-- truncate_limit: 100 +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest FROM STDIN WITH (HEADER match)" +== 069 +-- truncate_limit: 100 +SELECT * FROM header_copytest ORDER BY a +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM header_copytest ORDER BY a" +== 070 +-- truncate_limit: 100 +-- Drop an extra column, in the middle of the existing set. +alter table header_copytest drop column b +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE header_copytest DROP b" +== 071 +-- truncate_limit: 100 +-- works +copy header_copytest (c, a) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest(c, a) FROM STDIN WITH (HEADER match)" +== 072 +-- truncate_limit: 100 +copy header_copytest (a, c) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest(a, c) FROM STDIN WITH (HEADER match)" +== 073 +-- truncate_limit: 100 +-- errors +copy header_copytest from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest FROM STDIN WITH (HEADER match)" +== 074 +-- truncate_limit: 100 +copy header_copytest (a, c) from stdin with (header match) +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY header_copytest(a, c) FROM STDIN WITH (HEADER match)" +== 075 +-- truncate_limit: 100 +SELECT * FROM header_copytest ORDER BY a +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM header_copytest ORDER BY a" +== 076 +-- truncate_limit: 100 +drop table header_copytest +-- +TABLE: name="header_copytest" schema="" table="header_copytest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE header_copytest" +== 077 +-- truncate_limit: 100 +-- test COPY with overlong column defaults +create temp table oversized_column_default ( + col1 varchar(5) DEFAULT 'more than 5 chars', + col2 varchar(5)) +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE oversized_column_default (col1 varchar(5) DEFAULT 'more than 5 chars', col..." +== 078 +-- truncate_limit: 100 +-- normal COPY should work +copy oversized_column_default from stdin +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY oversized_column_default FROM STDIN" +== 079 +-- truncate_limit: 100 +-- error if the column is excluded +copy oversized_column_default (col2) from stdin +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY oversized_column_default(col2) FROM STDIN" +== 080 +-- truncate_limit: 100 +-- error if the DEFAULT option is given +copy oversized_column_default from stdin (default '') +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY oversized_column_default FROM STDIN WITH (\"default\" '')" +== 081 +-- truncate_limit: 100 +drop table oversized_column_default +-- +TABLE: name="oversized_column_default" schema="" table="oversized_column_default" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE oversized_column_default" +== 082 +-- truncate_limit: 100 +|-- +-- Create partitioned table that does not allow bulk insertions, to test bugs +-- related to the reuse of BulkInsertState across partitions (only done when +-- not using bulk insert). Switching between partitions often makes it more +-- likely to encounter these bugs, so we just switch on roughly every insert +-- by having an even/odd number partition and inserting evenly distributed +-- data. +|-- +CREATE TABLE parted_si ( + id int not null, + data text not null, + -- prevent use of bulk insert by having a volatile function + rand float8 not null default random() +) +PARTITION BY LIST((id % 2)) +-- +TABLE: name="parted_si" schema="" table="parted_si" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_si (id int NOT NULL, data text NOT NULL, rand float8 NOT NULL DEFAULT random(..." +== 083 +-- truncate_limit: 100 +CREATE TABLE parted_si_p_even PARTITION OF parted_si FOR VALUES IN (0) +-- +TABLE: name="parted_si_p_even" schema="" table="parted_si_p_even" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_si_p_even PARTITION OF parted_si FOR VALUES IN (0)" +== 084 +-- truncate_limit: 100 +CREATE TABLE parted_si_p_odd PARTITION OF parted_si FOR VALUES IN (1) +-- +TABLE: name="parted_si_p_odd" schema="" table="parted_si_p_odd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_si_p_odd PARTITION OF parted_si FOR VALUES IN (1)" +== 085 +-- truncate_limit: 100 +-- Test that bulk relation extension handles reusing a single BulkInsertState +-- across partitions. Without the fix applied, this reliably reproduces +-- #18130 unless shared_buffers is extremely small (preventing any use of bulk +-- relation extension). See +-- https://postgr.es/m/18130-7a86a7356a75209d%40postgresql.org +-- https://postgr.es/m/257696.1695670946%40sss.pgh.pa.us +COPY parted_si(id, data) FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 409 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 086 +-- truncate_limit: 100 +-- An earlier bug (see commit b1ecb9b3fcf) could end up using a buffer from +-- the wrong partition. This test is *not* guaranteed to trigger that bug, but +-- does so when shared_buffers is small enough. To test if we encountered the +-- bug, check that the partition condition isn't violated. +SELECT tableoid::regclass, id % 2 = 0 is_even, count(*) from parted_si GROUP BY 1, 2 ORDER BY 1 +-- +TABLE: name="parted_si" schema="" table="parted_si" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, (id % 2) = 0 AS is_even, count(*) FROM parted_si GROUP BY 1, 2 ORDER BY 1" +== 087 +-- truncate_limit: 100 +DROP TABLE parted_si +-- +TABLE: name="parted_si" schema="" table="parted_si" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_si" diff --git a/parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/copy2.test b/parser/testdata/summary_truncate/postgres_regress/copy2.test new file mode 100644 index 0000000..247cf06 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copy2.test @@ -0,0 +1,374 @@ +== 001 +-- truncate_limit: 100 +CREATE TEMP TABLE x ( + a serial, + b int, + c text not null default 'stuff', + d text, + e text +) ; + +CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS ' + BEGIN + NEW.e := ''before trigger fired''::text; + return NEW; + END; +' LANGUAGE plpgsql; + +CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS ' + BEGIN + UPDATE x set e=''after trigger fired'' where c=''stuff''; + return NULL; + END; +' LANGUAGE plpgsql; + +CREATE TRIGGER trg_x_after AFTER INSERT ON x +FOR EACH ROW EXECUTE PROCEDURE fn_x_after(); + +CREATE TRIGGER trg_x_before BEFORE INSERT ON x +FOR EACH ROW EXECUTE PROCEDURE fn_x_before(); + +COPY x (a, b, c, d, e) from stdin; + +COPY x (b, d) from stdin; + +COPY x (b, d) from stdin; + +COPY x (a, b, c, d, e) from stdin; + +-- non-existent column in column list: should fail +COPY x (xyz) from stdin; +COPY x from stdin; +COPY x from stdin; + +-- extra data: should fail +COPY x from stdin; + +-- various COPY options: delimiters, oids, NULL string, encoding +COPY x (b, c, d, e) from stdin delimiter ',' null 'x'; + +COPY x from stdin WITH DELIMITER AS ';' NULL AS ''; + +COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii'; + +COPY x TO stdout WHERE a = 1; +COPY x from stdin WHERE a = 50004; + +COPY x from stdin WHERE a > 60003; + +COPY x from stdin WHERE f > 60003; + +-- test end of copy marker +CREATE TEMP TABLE testeoc (a text); + +COPY testeoc FROM stdin CSV; + +COPY testeoc TO stdout CSV; + +-- test handling of nonstandard null marker that violates escaping rules + +CREATE TEMP TABLE testnull(a int, b text); +INSERT INTO testnull VALUES (1, E'\\0'), (NULL, NULL); + +COPY testnull TO stdout WITH NULL AS E'\\0'; + +COPY testnull FROM stdin WITH NULL AS E'\\0'; + +SELECT * FROM testnull; + +BEGIN; +CREATE TABLE vistest (LIKE testeoc); +COPY vistest FROM stdin CSV; +COMMIT; +SELECT * FROM vistest; +BEGIN; +TRUNCATE vistest; +COPY vistest FROM stdin CSV; +SELECT * FROM vistest; +SAVEPOINT s1; +TRUNCATE vistest; +COPY vistest FROM stdin CSV; +SELECT * FROM vistest; +COMMIT; +SELECT * FROM vistest; + +BEGIN; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +SAVEPOINT s1; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +COMMIT; +SELECT * FROM vistest; + +BEGIN; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +COMMIT; +TRUNCATE vistest; +COPY vistest FROM stdin CSV FREEZE; +BEGIN; +TRUNCATE vistest; +SAVEPOINT s1; +COPY vistest FROM stdin CSV FREEZE; +COMMIT; +BEGIN; +INSERT INTO vistest VALUES ('z'); +SAVEPOINT s1; +TRUNCATE vistest; +ROLLBACK TO SAVEPOINT s1; +COPY vistest FROM stdin CSV FREEZE; +COMMIT; +CREATE FUNCTION truncate_in_subxact() RETURNS VOID AS +$$ +BEGIN + TRUNCATE vistest; +EXCEPTION + WHEN OTHERS THEN + INSERT INTO vistest VALUES ('subxact failure'); +END; +$$ language plpgsql; +BEGIN; +INSERT INTO vistest VALUES ('z'); +SELECT truncate_in_subxact(); +COPY vistest FROM stdin CSV FREEZE; +SELECT * FROM vistest; +COMMIT; +SELECT * FROM vistest; +-- Test FORCE_NOT_NULL and FORCE_NULL options +CREATE TEMP TABLE forcetest ( + a INT NOT NULL, + b TEXT NOT NULL, + c TEXT, + d TEXT, + e TEXT +); +-- should succeed with no effect ("b" remains an empty string, "c" remains NULL) +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b), FORCE_NULL(c)); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 1; +-- should succeed, FORCE_NULL and FORCE_NOT_NULL can be both specified +BEGIN; +COPY forcetest (a, b, c, d) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(c,d), FORCE_NULL(c,d)); +COMMIT; +SELECT c, d FROM forcetest WHERE a = 2; +-- should fail with not-null constraint violation +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b), FORCE_NOT_NULL(c)); +ROLLBACK; +-- should fail with "not referenced by COPY" error +BEGIN; +COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b)); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 4; +-- should succeed with effect ("b" remains an empty string) +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL *); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 5; +-- should succeed with effect ("c" remains NULL) +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL *); +COMMIT; +SELECT b, c FROM forcetest WHERE a = 6; +-- should fail with "conflicting or redundant options" error +BEGIN; +COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL *, FORCE_NOT_NULL(b)); +copy check_con_tbl from stdin; +select * from check_con_tbl; + +-- test with RLS enabled. +CREATE ROLE regress_rls_copy_user; +CREATE ROLE regress_rls_copy_user_colperms; +CREATE TABLE rls_t1 (a int, b int, c int); + +COPY rls_t1 (a, b, c) from stdin; + +CREATE POLICY p1 ON rls_t1 FOR SELECT USING (a % 2 = 0); +ALTER TABLE rls_t1 ENABLE ROW LEVEL SECURITY; +ALTER TABLE rls_t1 FORCE ROW LEVEL SECURITY; + +GRANT SELECT ON TABLE rls_t1 TO regress_rls_copy_user; +GRANT SELECT (a, b) ON TABLE rls_t1 TO regress_rls_copy_user_colperms; + +-- all columns +COPY rls_t1 TO stdout; +COPY rls_t1 (a, b, c) TO stdout; + +-- subset of columns +COPY rls_t1 (a) TO stdout; +COPY rls_t1 (a, b) TO stdout; + +-- column reordering +COPY rls_t1 (b, a) TO stdout; + +SET SESSION AUTHORIZATION regress_rls_copy_user; + +-- all columns +COPY rls_t1 TO stdout; +COPY rls_t1 (a, b, c) TO stdout; + +-- subset of columns +COPY rls_t1 (a) TO stdout; +COPY rls_t1 (a, b) TO stdout; + +-- column reordering +COPY rls_t1 (b, a) TO stdout; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_rls_copy_user_colperms; + +-- attempt all columns (should fail) +COPY rls_t1 TO stdout; +COPY rls_t1 (a, b, c) TO stdout; + +-- try to copy column with no privileges (should fail) +COPY rls_t1 (c) TO stdout; + +-- subset of columns (should succeed) +COPY rls_t1 (a) TO stdout; +COPY rls_t1 (a, b) TO stdout; + +RESET SESSION AUTHORIZATION; + +-- test with INSTEAD OF INSERT trigger on a view +CREATE TABLE instead_of_insert_tbl(id serial, name text); +CREATE VIEW instead_of_insert_tbl_view AS SELECT ''::text AS str; + +COPY instead_of_insert_tbl_view FROM stdin; -- fail +test1 + +CREATE FUNCTION fun_instead_of_insert_tbl() RETURNS trigger AS $$ +BEGIN + INSERT INTO instead_of_insert_tbl (name) VALUES (NEW.str); + +SELECT * FROM instead_of_insert_tbl; + +-- Test of COPY optimization with view using INSTEAD OF INSERT +-- trigger when relation is created in the same transaction as +-- when COPY is executed. +BEGIN; +CREATE VIEW instead_of_insert_tbl_view_2 as select ''::text as str; +CREATE TRIGGER trig_instead_of_insert_tbl_view_2 + INSTEAD OF INSERT ON instead_of_insert_tbl_view_2 + FOR EACH ROW EXECUTE PROCEDURE fun_instead_of_insert_tbl(); + +COPY instead_of_insert_tbl_view_2 FROM stdin; + +SELECT * FROM instead_of_insert_tbl; +COMMIT; + +-- tests for on_error option +CREATE TABLE check_ign_err (n int, m int[], k int); +COPY check_ign_err FROM STDIN WITH (on_error stop); + +-- want context for notices + +COPY check_ign_err FROM STDIN WITH (on_error ignore, log_verbosity verbose); + +-- tests for on_error option with log_verbosity and null constraint via domain +CREATE DOMAIN dcheck_ign_err2 varchar(15) NOT NULL; +CREATE TABLE check_ign_err2 (n int, m int[], k int, l dcheck_ign_err2); +COPY check_ign_err2 FROM STDIN WITH (on_error ignore, log_verbosity verbose); + +-- reset context choice + +SELECT * FROM check_ign_err; + +SELECT * FROM check_ign_err2; + +-- test datatype error that can't be handled as soft: should fail +CREATE TABLE hard_err(foo widget); +COPY hard_err FROM STDIN WITH (on_error ignore); + +-- test missing data: should fail +COPY check_ign_err FROM STDIN WITH (on_error ignore); + +-- test extra data: should fail +COPY check_ign_err FROM STDIN WITH (on_error ignore); + +-- clean up +DROP TABLE forcetest; +DROP TABLE vistest; +DROP FUNCTION truncate_in_subxact(); +DROP TABLE x, y; +DROP TABLE rls_t1 CASCADE; +DROP ROLE regress_rls_copy_user; +DROP ROLE regress_rls_copy_user_colperms; +DROP FUNCTION fn_x_before(); +DROP FUNCTION fn_x_after(); +DROP TABLE instead_of_insert_tbl; +DROP VIEW instead_of_insert_tbl_view; +DROP VIEW instead_of_insert_tbl_view_2; +DROP FUNCTION fun_instead_of_insert_tbl(); +DROP TABLE check_ign_err; +DROP TABLE check_ign_err2; +DROP DOMAIN dcheck_ign_err2; +DROP TABLE hard_err; + +|-- +-- COPY FROM ... DEFAULT +|-- + +create temp table copy_default ( + id integer primary key, + text_value text not null default 'test', + ts_value timestamp without time zone not null default '2022-07-05' +); + +-- if DEFAULT is not specified, then the marker will be regular data +copy copy_default from stdin; + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +copy copy_default from stdin with (format csv); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +-- DEFAULT cannot be used in binary mode +copy copy_default from stdin with (format binary, default '\D'); + +copy copy_default from stdin with (format csv, default '\D'); + +-- The DEFAULT marker must be unquoted and unescaped or it's not recognized +copy copy_default from stdin with (default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +copy copy_default from stdin with (format csv, default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +-- successful usage of DEFAULT option in COPY +copy copy_default from stdin with (default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +copy copy_default from stdin with (format csv, default '\D'); + +select id, text_value, ts_value from copy_default; + +truncate copy_default; + +-- DEFAULT cannot be used in COPY TO +copy (select 1 as test) TO stdout with (default '\D'); +-- +ERROR: WHERE clause not allowed with COPY TO +CURSORPOS: 1145 +FILENAME: gram.y +FUNCNAME: base_yyparse diff --git a/parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json new file mode 100644 index 0000000..f53b7f4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json @@ -0,0 +1,63 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/copydml.test b/parser/testdata/summary_truncate/postgres_regress/copydml.test new file mode 100644 index 0000000..4bd999d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copydml.test @@ -0,0 +1,442 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test cases for COPY (INSERT/UPDATE/DELETE) TO +|-- +create table copydml_test (id serial, t text) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE copydml_test (id serial, t text)" +== 002 +-- truncate_limit: 100 +insert into copydml_test (t) values ('a') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copydml_test (t) VALUES ('a')" +== 003 +-- truncate_limit: 100 +insert into copydml_test (t) values ('b') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copydml_test (t) VALUES ('b')" +== 004 +-- truncate_limit: 100 +insert into copydml_test (t) values ('c') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copydml_test (t) VALUES ('c')" +== 005 +-- truncate_limit: 100 +insert into copydml_test (t) values ('d') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copydml_test (t) VALUES ('d')" +== 006 +-- truncate_limit: 100 +insert into copydml_test (t) values ('e') +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copydml_test (t) VALUES ('e')" +== 007 +-- truncate_limit: 100 +|-- +-- Test COPY (insert/update/delete ...) +|-- +copy (insert into copydml_test (t) values ('f') returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test (t) VALUES ('f') RETURNING id) TO STDOUT" +== 008 +-- truncate_limit: 100 +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (UPDATE copydml_test SET t = 'g' WHERE t = 'f' RETURNING id) TO STDOUT" +== 009 +-- truncate_limit: 100 +copy (delete from copydml_test where t = 'g' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (DELETE FROM copydml_test WHERE t = 'g' RETURNING id) TO STDOUT" +== 010 +-- truncate_limit: 100 +|-- +-- Test \copy (insert/update/delete ...) +|-- + +-- Error cases +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test DEFAULT VALUES) TO STDOUT" +== 011 +-- truncate_limit: 100 +copy (update copydml_test set t = 'g') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (UPDATE copydml_test SET t = 'g') TO STDOUT" +== 012 +-- truncate_limit: 100 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (DELETE FROM copydml_test) TO STDOUT" +== 013 +-- truncate_limit: 100 +create rule qqq as on insert to copydml_test do instead nothing +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON INSERT TO copydml_test DO INSTEAD NOTHING" +== 014 +-- truncate_limit: 100 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test DEFAULT VALUES) TO STDOUT" +== 015 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 016 +-- truncate_limit: 100 +create rule qqq as on insert to copydml_test do also delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON INSERT TO copydml_test DO DELETE FROM copydml_test" +== 017 +-- truncate_limit: 100 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test DEFAULT VALUES) TO STDOUT" +== 018 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 019 +-- truncate_limit: 100 +create rule qqq as on insert to copydml_test do instead (delete from copydml_test; delete from copydml_test) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON INSERT TO copydml_test DO INSTEAD (DELETE FROM copydml_test; DELETE FROM co..." +== 020 +-- truncate_limit: 100 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test DEFAULT VALUES) TO STDOUT" +== 021 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 022 +-- truncate_limit: 100 +create rule qqq as on insert to copydml_test where new.t <> 'f' do instead delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON INSERT TO copydml_test WHERE new.t <> 'f' DO INSTEAD DELETE FROM copydml_test" +== 023 +-- truncate_limit: 100 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test DEFAULT VALUES) TO STDOUT" +== 024 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 025 +-- truncate_limit: 100 +create rule qqq as on update to copydml_test do instead nothing +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON UPDATE TO copydml_test DO INSTEAD NOTHING" +== 026 +-- truncate_limit: 100 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (UPDATE copydml_test SET t = 'f') TO STDOUT" +== 027 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 028 +-- truncate_limit: 100 +create rule qqq as on update to copydml_test do also delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON UPDATE TO copydml_test DO DELETE FROM copydml_test" +== 029 +-- truncate_limit: 100 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (UPDATE copydml_test SET t = 'f') TO STDOUT" +== 030 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 031 +-- truncate_limit: 100 +create rule qqq as on update to copydml_test do instead (delete from copydml_test; delete from copydml_test) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON UPDATE TO copydml_test DO INSTEAD (DELETE FROM copydml_test; DELETE FROM co..." +== 032 +-- truncate_limit: 100 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (UPDATE copydml_test SET t = 'f') TO STDOUT" +== 033 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 034 +-- truncate_limit: 100 +create rule qqq as on update to copydml_test where new.t <> 'f' do instead delete from copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON UPDATE TO copydml_test WHERE new.t <> 'f' DO INSTEAD DELETE FROM copydml_test" +== 035 +-- truncate_limit: 100 +copy (update copydml_test set t = 'f') to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (UPDATE copydml_test SET t = 'f') TO STDOUT" +== 036 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 037 +-- truncate_limit: 100 +create rule qqq as on delete to copydml_test do instead nothing +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON DELETE TO copydml_test DO INSTEAD NOTHING" +== 038 +-- truncate_limit: 100 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (DELETE FROM copydml_test) TO STDOUT" +== 039 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 040 +-- truncate_limit: 100 +create rule qqq as on delete to copydml_test do also insert into copydml_test default values +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON DELETE TO copydml_test DO INSERT INTO copydml_test DEFAULT VALUES" +== 041 +-- truncate_limit: 100 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (DELETE FROM copydml_test) TO STDOUT" +== 042 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 043 +-- truncate_limit: 100 +create rule qqq as on delete to copydml_test do instead (insert into copydml_test default values; insert into copydml_test default values) +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON DELETE TO copydml_test DO INSTEAD (INSERT INTO copydml_test DEFAULT VALUES;..." +== 044 +-- truncate_limit: 100 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (DELETE FROM copydml_test) TO STDOUT" +== 045 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 046 +-- truncate_limit: 100 +create rule qqq as on delete to copydml_test where old.t <> 'f' do instead insert into copydml_test default values +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON DELETE TO copydml_test WHERE ... DO INSTEAD INSERT INTO copydml_test DEFAUL..." +== 047 +-- truncate_limit: 100 +copy (delete from copydml_test) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (DELETE FROM copydml_test) TO STDOUT" +== 048 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 049 +-- truncate_limit: 100 +create rule qqq as on insert to copydml_test do instead notify copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE qqq AS ON INSERT TO copydml_test DO INSTEAD NOTIFY copydml_test" +== 050 +-- truncate_limit: 100 +copy (insert into copydml_test default values) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test DEFAULT VALUES) TO STDOUT" +== 051 +-- truncate_limit: 100 +drop rule qqq on copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE qqq ON copydml_test" +== 052 +-- truncate_limit: 100 +-- triggers +create function qqq_trig() returns trigger as $$ +begin +if tg_op in ('INSERT', 'UPDATE') then + raise notice '% % %', tg_when, tg_op, new.id; + return new; +else + raise notice '% % %', tg_when, tg_op, old.id; + return old; +end if; +end +$$ language plpgsql +-- +FUNCTION: name="qqq_trig" function="qqq_trig" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION qqq_trig() RETURNS trigger AS $$\nbegin\nif tg_op in ('INSERT', 'UPDATE') then\n ..." +== 053 +-- truncate_limit: 100 +create trigger qqqbef before insert or update or delete on copydml_test + for each row execute procedure qqq_trig() +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER qqqbef BEFORE INSERT OR DELETE OR UPDATE ON copydml_test FOR EACH ROW EXECUTE FUNC..." +== 054 +-- truncate_limit: 100 +create trigger qqqaf after insert or update or delete on copydml_test + for each row execute procedure qqq_trig() +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER qqqaf AFTER INSERT OR DELETE OR UPDATE ON copydml_test FOR EACH ROW EXECUTE FUNCTI..." +== 055 +-- truncate_limit: 100 +copy (insert into copydml_test (t) values ('f') returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (INSERT INTO copydml_test (t) VALUES ('f') RETURNING id) TO STDOUT" +== 056 +-- truncate_limit: 100 +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (UPDATE copydml_test SET t = 'g' WHERE t = 'f' RETURNING id) TO STDOUT" +== 057 +-- truncate_limit: 100 +copy (delete from copydml_test where t = 'g' returning id) to stdout +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (DELETE FROM copydml_test WHERE t = 'g' RETURNING id) TO STDOUT" +== 058 +-- truncate_limit: 100 +drop table copydml_test +-- +TABLE: name="copydml_test" schema="" table="copydml_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE copydml_test" +== 059 +-- truncate_limit: 100 +drop function qqq_trig() +-- +FUNCTION: name="qqq_trig" function="qqq_trig" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION qqq_trig()" diff --git a/parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json new file mode 100644 index 0000000..56098cb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json @@ -0,0 +1,25 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/copyselect.test b/parser/testdata/summary_truncate/postgres_regress/copyselect.test new file mode 100644 index 0000000..92904b4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/copyselect.test @@ -0,0 +1,188 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test cases for COPY (select) TO +|-- +create table test1 (id serial, t text) +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test1 (id serial, t text)" +== 002 +-- truncate_limit: 100 +insert into test1 (t) values ('a') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1 (t) VALUES ('a')" +== 003 +-- truncate_limit: 100 +insert into test1 (t) values ('b') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1 (t) VALUES ('b')" +== 004 +-- truncate_limit: 100 +insert into test1 (t) values ('c') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1 (t) VALUES ('c')" +== 005 +-- truncate_limit: 100 +insert into test1 (t) values ('d') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1 (t) VALUES ('d')" +== 006 +-- truncate_limit: 100 +insert into test1 (t) values ('e') +-- +TABLE: name="test1" schema="" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test1 (t) VALUES ('e')" +== 007 +-- truncate_limit: 100 +create table test2 (id serial, t text) +-- +TABLE: name="test2" schema="" table="test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test2 (id serial, t text)" +== 008 +-- truncate_limit: 100 +insert into test2 (t) values ('A') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2 (t) VALUES ('A')" +== 009 +-- truncate_limit: 100 +insert into test2 (t) values ('B') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2 (t) VALUES ('B')" +== 010 +-- truncate_limit: 100 +insert into test2 (t) values ('C') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2 (t) VALUES ('C')" +== 011 +-- truncate_limit: 100 +insert into test2 (t) values ('D') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2 (t) VALUES ('D')" +== 012 +-- truncate_limit: 100 +insert into test2 (t) values ('E') +-- +TABLE: name="test2" schema="" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test2 (t) VALUES ('E')" +== 013 +-- truncate_limit: 100 +create view v_test1 +as select 'v_'||t from test1 +-- +TABLE: name="v_test1" schema="" table="v_test1" ctx=DDL +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v_test1 AS SELECT 'v_' || t FROM test1" +== 014 +-- truncate_limit: 100 +|-- +-- Test COPY table TO +|-- +copy test1 to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY test1 TO STDOUT" +== 015 +-- truncate_limit: 100 +|-- +-- This should fail +|-- +copy v_test1 to stdout +-- +TABLE: name="v_test1" schema="" table="v_test1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY v_test1 TO STDOUT" +== 016 +-- truncate_limit: 100 +|-- +-- Test COPY (select) TO +|-- +copy (select t from test1 where id=1) to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +FILTER: schema="" table="" column="id" +STMT: CopyStmt +TRUNCATED: "COPY (SELECT t FROM test1 WHERE id = 1) TO STDOUT" +== 017 +-- truncate_limit: 100 +|-- +-- Test COPY (select for update) TO +|-- +copy (select t from test1 where id=3 for update) to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +FILTER: schema="" table="" column="id" +STMT: CopyStmt +TRUNCATED: "COPY (SELECT t FROM test1 WHERE id = 3 FOR UPDATE) TO STDOUT" +== 018 +-- truncate_limit: 100 +|-- +-- This should fail +|-- +copy (select t into temp test3 from test1 where id=3) to stdout +-- +TABLE: name="test1" schema="" table="test1" ctx=Select +TABLE: name="test3" schema="" table="test3" ctx=DDL +FILTER: schema="" table="" column="id" +STMT: CopyStmt +TRUNCATED: "COPY (SELECT t INTO TEMPORARY test3 FROM test1 WHERE id = 3) TO STDOUT" +== 019 +-- truncate_limit: 100 +|-- +-- This should fail +|-- +copy (select * from test1) from stdin +-- +ERROR: syntax error at or near "from" +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 020 +-- truncate_limit: 100 +2 +select * from test3 +-- +ERROR: syntax error at or near "2" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 021 +-- truncate_limit: 100 +drop table test3 +-- +TABLE: name="test3" schema="" table="test3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test3" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json new file mode 100644 index 0000000..f53b7f4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json @@ -0,0 +1,63 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_aggregate.test b/parser/testdata/summary_truncate/postgres_regress/create_aggregate.test new file mode 100644 index 0000000..50e5b0e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_aggregate.test @@ -0,0 +1,594 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_AGGREGATE +|-- + +-- all functions CREATEd +CREATE AGGREGATE newavg ( + sfunc = int4_avg_accum, basetype = int4, stype = _int8, + finalfunc = int8_avg, + initcond1 = '{0,0}' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE newavg (sfunc = int4_avg_accum, basetype = int4, stype = _int8, finalfunc = int8..." +== 002 +-- truncate_limit: 100 +-- test comments +COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON AGGREGATE newavg_wrong(int4) IS 'an agg comment'" +== 003 +-- truncate_limit: 100 +COMMENT ON AGGREGATE newavg (int4) IS 'an agg comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON AGGREGATE newavg(int4) IS 'an agg comment'" +== 004 +-- truncate_limit: 100 +COMMENT ON AGGREGATE newavg (int4) IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON AGGREGATE newavg(int4) IS NULL" +== 005 +-- truncate_limit: 100 +-- without finalfunc; test obsolete spellings 'sfunc1' etc +CREATE AGGREGATE newsum ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, + initcond1 = '0' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE newsum (sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond1 = '0')" +== 006 +-- truncate_limit: 100 +-- zero-argument aggregate +CREATE AGGREGATE newcnt (*) ( + sfunc = int8inc, stype = int8, + initcond = '0', parallel = safe +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE newcnt (*) (sfunc = int8inc, stype = int8, initcond = '0', parallel = safe)" +== 007 +-- truncate_limit: 100 +-- old-style spelling of same (except without parallel-safe; that's too new) +CREATE AGGREGATE oldcnt ( + sfunc = int8inc, basetype = 'ANY', stype = int8, + initcond = '0' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE oldcnt (sfunc = int8inc, basetype = 'ANY', stype = int8, initcond = '0')" +== 008 +-- truncate_limit: 100 +-- aggregate that only cares about null/nonnull input +CREATE AGGREGATE newcnt ("any") ( + sfunc = int8inc_any, stype = int8, + initcond = '0' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE newcnt (\"any\") (sfunc = int8inc_any, stype = int8, initcond = '0')" +== 009 +-- truncate_limit: 100 +COMMENT ON AGGREGATE nosuchagg (*) IS 'should fail' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON AGGREGATE nosuchagg(*) IS 'should fail'" +== 010 +-- truncate_limit: 100 +COMMENT ON AGGREGATE newcnt (*) IS 'an agg(*) comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON AGGREGATE newcnt(*) IS 'an agg(*) comment'" +== 011 +-- truncate_limit: 100 +COMMENT ON AGGREGATE newcnt ("any") IS 'an agg(any) comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON AGGREGATE newcnt(\"any\") IS 'an agg(any) comment'" +== 012 +-- truncate_limit: 100 +-- multi-argument aggregate +create function sum3(int8,int8,int8) returns int8 as +'select $1 + $2 + $3' language sql strict immutable +-- +FUNCTION: name="sum3" function="sum3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sum3(int8, int8, int8) RETURNS int8 AS $$select $1 + $2 + $3$$ LANGUAGE sql RETUR..." +== 013 +-- truncate_limit: 100 +create aggregate sum2(int8,int8) ( + sfunc = sum3, stype = int8, + initcond = '0' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE sum2 (int8, int8) (sfunc = sum3, stype = int8, initcond = '0')" +== 014 +-- truncate_limit: 100 +-- multi-argument aggregates sensitive to distinct/order, strict/nonstrict +create type aggtype as (a integer, b integer, c text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE aggtype AS (a int, b int, c text)" +== 015 +-- truncate_limit: 100 +create function aggf_trans(aggtype[],integer,integer,text) returns aggtype[] +as 'select array_append($1,ROW($2,$3,$4)::aggtype)' +language sql strict immutable +-- +FUNCTION: name="aggf_trans" function="aggf_trans" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION aggf_trans(aggtype[], int, int, text) RETURNS aggtype[] AS $$select array_append(..." +== 016 +-- truncate_limit: 100 +create function aggfns_trans(aggtype[],integer,integer,text) returns aggtype[] +as 'select array_append($1,ROW($2,$3,$4)::aggtype)' +language sql immutable +-- +FUNCTION: name="aggfns_trans" function="aggfns_trans" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION aggfns_trans(aggtype[], int, int, text) RETURNS aggtype[] AS $$select array_appen..." +== 017 +-- truncate_limit: 100 +create aggregate aggfstr(integer,integer,text) ( + sfunc = aggf_trans, stype = aggtype[], + initcond = '{}' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE aggfstr (int, int, text) (sfunc = aggf_trans, stype = aggtype[], initcond = '{}')" +== 018 +-- truncate_limit: 100 +create aggregate aggfns(integer,integer,text) ( + sfunc = aggfns_trans, stype = aggtype[], sspace = 10000, + initcond = '{}' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE aggfns (int, int, text) (sfunc = aggfns_trans, stype = aggtype[], sspace = 10000..." +== 019 +-- truncate_limit: 100 +-- check error cases that would require run-time type coercion +create function least_accum(int8, int8) returns int8 language sql as + 'select least($1, $2)' +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION least_accum(int8, int8) RETURNS int8 LANGUAGE sql AS $$select least($1, $2)$$" +== 020 +-- truncate_limit: 100 +create aggregate least_agg(int4) ( + stype = int8, sfunc = least_accum +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE least_agg (int4) (stype = int8, sfunc = least_accum)" +== 021 +-- truncate_limit: 100 +-- fails + +drop function least_accum(int8, int8) +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION least_accum(int8, int8)" +== 022 +-- truncate_limit: 100 +create function least_accum(anycompatible, anycompatible) +returns anycompatible language sql as + 'select least($1, $2)' +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION least_accum(anycompatible, anycompatible) RETURNS anycompatible LANGUAGE sql AS $..." +== 023 +-- truncate_limit: 100 +create aggregate least_agg(int4) ( + stype = int8, sfunc = least_accum +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE least_agg (int4) (stype = int8, sfunc = least_accum)" +== 024 +-- truncate_limit: 100 +-- fails + +create aggregate least_agg(int8) ( + stype = int8, sfunc = least_accum +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE least_agg (int8) (stype = int8, sfunc = least_accum)" +== 025 +-- truncate_limit: 100 +drop function least_accum(anycompatible, anycompatible) cascade +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION least_accum(anycompatible, anycompatible) CASCADE" +== 026 +-- truncate_limit: 100 +-- variadic aggregates +create function least_accum(anyelement, variadic anyarray) +returns anyelement language sql as + 'select least($1, min($2[i])) from generate_subscripts($2,1) g(i)' +-- +FUNCTION: name="least_accum" function="least_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION least_accum(anyelement, VARIADIC anyarray) RETURNS anyelement LANGUAGE sql AS $$s..." +== 027 +-- truncate_limit: 100 +create aggregate least_agg(variadic items anyarray) ( + stype = anyelement, sfunc = least_accum +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE least_agg (VARIADIC items anyarray) (stype = anyelement, sfunc = least_accum)" +== 028 +-- truncate_limit: 100 +create function cleast_accum(anycompatible, variadic anycompatiblearray) +returns anycompatible language sql as + 'select least($1, min($2[i])) from generate_subscripts($2,1) g(i)' +-- +FUNCTION: name="cleast_accum" function="cleast_accum" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION cleast_accum(anycompatible, VARIADIC anycompatiblearray) RETURNS anycompatible LA..." +== 029 +-- truncate_limit: 100 +create aggregate cleast_agg(variadic items anycompatiblearray) ( + stype = anycompatible, sfunc = cleast_accum +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE cleast_agg (VARIADIC items anycompatiblearray) (stype = anycompatible, sfunc = c..." +== 030 +-- truncate_limit: 100 +-- test ordered-set aggs using built-in support functions +create aggregate my_percentile_disc(float8 ORDER BY anyelement) ( + stype = internal, + sfunc = ordered_set_transition, + finalfunc = percentile_disc_final, + finalfunc_extra = true, + finalfunc_modify = read_write +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_percentile_disc (float8 ORDER BY anyelement) (stype = internal, sfunc = order..." +== 031 +-- truncate_limit: 100 +create aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") ( + stype = internal, + sfunc = ordered_set_transition_multi, + finalfunc = rank_final, + finalfunc_extra = true, + hypothetical +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE my_rank (VARIADIC \"any\" ORDER BY VARIADIC \"any\") (stype = internal, sfunc = orde..." +== 032 +-- truncate_limit: 100 +alter aggregate my_percentile_disc(float8 ORDER BY anyelement) + rename to test_percentile_disc +-- +STMT: RenameStmt +TRUNCATED: "ALTER AGGREGATE my_percentile_disc(float8, anyelement) RENAME TO test_percentile_disc" +== 033 +-- truncate_limit: 100 +alter aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") + rename to test_rank +-- +STMT: RenameStmt +TRUNCATED: "ALTER AGGREGATE my_rank(VARIADIC \"any\") RENAME TO test_rank" +== 034 +-- truncate_limit: 100 +-- moving-aggregate options + +CREATE AGGREGATE sumdouble (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE sumdouble (float8) (stype = float8, sfunc = float8pl, mstype = float8, msfunc = ..." +== 035 +-- truncate_limit: 100 +-- aggregate combine and serialization functions + +-- can't specify just one of serialfunc and deserialfunc +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myavg (numeric) (stype = internal, sfunc = numeric_avg_accum, serialfunc = numer..." +== 036 +-- truncate_limit: 100 +-- serialfunc must have correct parameters +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_deserialize, + deserialfunc = numeric_avg_deserialize +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myavg (numeric) (stype = internal, sfunc = numeric_avg_accum, serialfunc = numer..." +== 037 +-- truncate_limit: 100 +-- deserialfunc must have correct parameters +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_serialize +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myavg (numeric) (stype = internal, sfunc = numeric_avg_accum, serialfunc = numer..." +== 038 +-- truncate_limit: 100 +-- ensure combine function parameters are checked +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = int4larger +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myavg (numeric) (stype = internal, sfunc = numeric_avg_accum, serialfunc = numer..." +== 039 +-- truncate_limit: 100 +-- ensure create aggregate works. +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myavg (numeric) (stype = internal, sfunc = numeric_avg_accum, finalfunc = numeri..." +== 040 +-- truncate_limit: 100 +-- Ensure all these functions made it into the catalog +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggfnoid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate WHERE aggfnoid = 'myavg'::regproc" +== 041 +-- truncate_limit: 100 +DROP AGGREGATE myavg (numeric) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE myavg(numeric)" +== 042 +-- truncate_limit: 100 +-- create or replace aggregate +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myavg (numeric) (stype = internal, sfunc = numeric_avg_accum, finalfunc = numeri..." +== 043 +-- truncate_limit: 100 +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OR REPLACE AGGREGATE myavg (numeric) (stype = internal, sfunc = numeric_avg_accum, finalfu..." +== 044 +-- truncate_limit: 100 +-- Ensure all these functions made it into the catalog again +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggfnoid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate WHERE aggfnoid = 'myavg'::regproc" +== 045 +-- truncate_limit: 100 +-- can change stype: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OR REPLACE AGGREGATE myavg (numeric) (stype = numeric, sfunc = numeric_add)" +== 046 +-- truncate_limit: 100 +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggfnoid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate WHERE aggfnoid = 'myavg'::regproc" +== 047 +-- truncate_limit: 100 +-- can't change return type: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add, + finalfunc = numeric_out +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OR REPLACE AGGREGATE myavg (numeric) (stype = numeric, sfunc = numeric_add, finalfunc = nu..." +== 048 +-- truncate_limit: 100 +-- can't change to a different kind: +CREATE OR REPLACE AGGREGATE myavg (order by numeric) +( + stype = numeric, + sfunc = numeric_add +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OR REPLACE AGGREGATE myavg (ORDER BY numeric) (stype = numeric, sfunc = numeric_add)" +== 049 +-- truncate_limit: 100 +-- can't change plain function to aggregate: +create function sum4(int8,int8,int8,int8) returns int8 as +'select $1 + $2 + $3 + $4' language sql strict immutable +-- +FUNCTION: name="sum4" function="sum4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sum4(int8, int8, int8, int8) RETURNS int8 AS $$select $1 + $2 + $3 + $4$$ LANGUAG..." +== 050 +-- truncate_limit: 100 +CREATE OR REPLACE AGGREGATE sum3 (int8,int8,int8) +( + stype = int8, + sfunc = sum4 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OR REPLACE AGGREGATE sum3 (int8, int8, int8) (stype = int8, sfunc = sum4)" +== 051 +-- truncate_limit: 100 +drop function sum4(int8,int8,int8,int8) +-- +FUNCTION: name="sum4" function="sum4" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sum4(int8, int8, int8, int8)" +== 052 +-- truncate_limit: 100 +DROP AGGREGATE myavg (numeric) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE myavg(numeric)" +== 053 +-- truncate_limit: 100 +-- invalid: bad parallel-safety marking +CREATE AGGREGATE mysum (int) +( + stype = int, + sfunc = int4pl, + parallel = pear +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE mysum (int) (stype = int, sfunc = int4pl, parallel = pear)" +== 054 +-- truncate_limit: 100 +-- invalid: nonstrict inverse with strict forward function + +CREATE FUNCTION float8mi_n(float8, float8) RETURNS float8 AS +$$ SELECT $1 - $2; $$ +LANGUAGE SQL +-- +FUNCTION: name="float8mi_n" function="float8mi_n" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION float8mi_n(float8, float8) RETURNS float8 AS $$ SELECT $1 - $2; $$ LANGUAGE sql" +== 055 +-- truncate_limit: 100 +CREATE AGGREGATE invalidsumdouble (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi_n +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE invalidsumdouble (float8) (stype = float8, sfunc = float8pl, mstype = float8, ms..." +== 056 +-- truncate_limit: 100 +-- invalid: non-matching result types + +CREATE FUNCTION float8mi_int(float8, float8) RETURNS int AS +$$ SELECT CAST($1 - $2 AS INT); $$ +LANGUAGE SQL +-- +FUNCTION: name="float8mi_int" function="float8mi_int" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION float8mi_int(float8, float8) RETURNS int AS $$ SELECT CAST($1 - $2 AS INT); $$ LA..." +== 057 +-- truncate_limit: 100 +CREATE AGGREGATE wrongreturntype (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi_int +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE wrongreturntype (float8) (stype = float8, sfunc = float8pl, mstype = float8, msf..." +== 058 +-- truncate_limit: 100 +-- invalid: non-lowercase quoted identifiers + +CREATE AGGREGATE case_agg ( -- old syntax + "Sfunc1" = int4pl, + "Basetype" = int4, + "Stype1" = int4, + "Initcond1" = '0', + "Parallel" = safe +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE case_agg (\"Sfunc1\" = int4pl, \"Basetype\" = int4, \"Stype1\" = int4, \"Initcond1\" = '..." +== 059 +-- truncate_limit: 100 +CREATE AGGREGATE case_agg(float8) +( + "Stype" = internal, + "Sfunc" = ordered_set_transition, + "Finalfunc" = percentile_disc_final, + "Finalfunc_extra" = true, + "Finalfunc_modify" = read_write, + "Parallel" = safe +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE case_agg (float8) (\"Stype\" = internal, \"Sfunc\" = ordered_set_transition, \"Finalf..." diff --git a/parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json new file mode 100644 index 0000000..83b3df4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json @@ -0,0 +1,146 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_am.test b/parser/testdata/summary_truncate/postgres_regress/create_am.test new file mode 100644 index 0000000..561a851 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_am.test @@ -0,0 +1,1300 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Create access method tests +|-- + +-- Make gist2 over gisthandler. In fact, it would be a synonym to gist. +CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler +-- +STMT: CreateAmStmt +TRUNCATED: "CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler" +== 002 +-- truncate_limit: 100 +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER int4in +-- +STMT: CreateAmStmt +TRUNCATED: "CREATE ACCESS METHOD bogus TYPE INDEX HANDLER int4in" +== 003 +-- truncate_limit: 100 +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER heap_tableam_handler +-- +STMT: CreateAmStmt +TRUNCATED: "CREATE ACCESS METHOD bogus TYPE INDEX HANDLER heap_tableam_handler" +== 004 +-- truncate_limit: 100 +-- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist +CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base)" +== 005 +-- truncate_limit: 100 +-- Make operator class for boxes using gist2 +CREATE OPERATOR CLASS box_ops DEFAULT + FOR TYPE box USING gist2 AS + OPERATOR 1 <<, + OPERATOR 2 &<, + OPERATOR 3 &&, + OPERATOR 4 &>, + OPERATOR 5 >>, + OPERATOR 6 ~=, + OPERATOR 7 @>, + OPERATOR 8 <@, + OPERATOR 9 &<|, + OPERATOR 10 <<|, + OPERATOR 11 |>>, + OPERATOR 12 |&>, + FUNCTION 1 gist_box_consistent(internal, box, smallint, oid, internal), + FUNCTION 2 gist_box_union(internal, internal), + -- don't need compress, decompress, or fetch functions + FUNCTION 5 gist_box_penalty(internal, internal, internal), + FUNCTION 6 gist_box_picksplit(internal, internal), + FUNCTION 7 gist_box_same(box, box, internal) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS box_ops DEFAULT FOR TYPE box USING gist2 AS OPERATOR 1 <<, OPERATOR 2 &<, O..." +== 006 +-- truncate_limit: 100 +-- Create gist2 index on fast_emp4000 +CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base)" +== 007 +-- truncate_limit: 100 +-- Now check the results from plain indexscan; temporarily drop existing +-- index grect2ind to ensure it doesn't capture the plan +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 008 +-- truncate_limit: 100 +DROP INDEX grect2ind +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX grect2ind" +== 009 +-- truncate_limit: 100 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 010 +-- truncate_limit: 100 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 011 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 012 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM fast_emp4000 WHERE home_base <@ '(200,200),(2000,1000)'::box OR..." +== 013 +-- truncate_limit: 100 +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fast_emp4000 WHERE ... ORDER BY (home_base[0])[0]" +== 014 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box" +== 015 +-- truncate_limit: 100 +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box" +== 016 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL" +== 017 +-- truncate_limit: 100 +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL" +== 018 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 019 +-- truncate_limit: 100 +-- Try to drop access method: fail because of dependent objects +DROP ACCESS METHOD gist2 +-- +STMT: DropStmt +TRUNCATED: "DROP ACCESS METHOD gist2" +== 020 +-- truncate_limit: 100 +-- Drop access method cascade +-- To prevent a (rare) deadlock against autovacuum, +-- we must lock the table that owns the index that will be dropped +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 021 +-- truncate_limit: 100 +LOCK TABLE fast_emp4000 +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE fast_emp4000" +== 022 +-- truncate_limit: 100 +DROP ACCESS METHOD gist2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP ACCESS METHOD gist2 CASCADE" +== 023 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 024 +-- truncate_limit: 100 +|-- +-- Test table access methods +|-- + +-- prevent empty values +SET default_table_access_method = '' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_table_access_method TO ''" +== 025 +-- truncate_limit: 100 +-- prevent nonexistent values +SET default_table_access_method = 'I do not exist AM' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_table_access_method TO \"I do not exist AM\"" +== 026 +-- truncate_limit: 100 +-- prevent setting it to an index AM +SET default_table_access_method = 'btree' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_table_access_method TO btree" +== 027 +-- truncate_limit: 100 +-- Create a heap2 table am handler with heapam handler +CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler +-- +STMT: CreateAmStmt +TRUNCATED: "CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler" +== 028 +-- truncate_limit: 100 +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER int4in +-- +STMT: CreateAmStmt +TRUNCATED: "CREATE ACCESS METHOD bogus TYPE TABLE HANDLER int4in" +== 029 +-- truncate_limit: 100 +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER bthandler +-- +STMT: CreateAmStmt +TRUNCATED: "CREATE ACCESS METHOD bogus TYPE TABLE HANDLER bthandler" +== 030 +-- truncate_limit: 100 +SELECT amname, amhandler, amtype FROM pg_am where amtype = 't' ORDER BY 1, 2 +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FILTER: schema="" table="" column="amtype" +STMT: SelectStmt +TRUNCATED: "SELECT amname, amhandler, amtype FROM pg_am WHERE amtype = 't' ORDER BY 1, 2" +== 031 +-- truncate_limit: 100 +-- First create tables employing the new AM using USING + +-- plain CREATE TABLE +CREATE TABLE tableam_tbl_heap2(f1 int) USING heap2 +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_tbl_heap2 (f1 int) USING heap2" +== 032 +-- truncate_limit: 100 +INSERT INTO tableam_tbl_heap2 VALUES(1) +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tableam_tbl_heap2 VALUES (1)" +== 033 +-- truncate_limit: 100 +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1 +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1" +== 034 +-- truncate_limit: 100 +-- CREATE TABLE AS +CREATE TABLE tableam_tblas_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2 +-- +TABLE: name="tableam_tblas_heap2" schema="" table="tableam_tblas_heap2" ctx=DDL +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE tableam_tblas_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2" +== 035 +-- truncate_limit: 100 +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1 +-- +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1" +== 036 +-- truncate_limit: 100 +-- SELECT INTO doesn't support USING +SELECT INTO tableam_tblselectinto_heap2 USING heap2 FROM tableam_tbl_heap2 +-- +ERROR: syntax error at or near "USING" +CURSORPOS: 78 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 037 +-- truncate_limit: 100 +-- CREATE VIEW doesn't support USING +CREATE VIEW tableam_view_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2 +-- +ERROR: syntax error at or near "USING" +CURSORPOS: 69 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +-- truncate_limit: 100 +-- CREATE SEQUENCE doesn't support USING +CREATE SEQUENCE tableam_seq_heap2 USING heap2 +-- +ERROR: syntax error at or near "USING" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +-- truncate_limit: 100 +-- CREATE MATERIALIZED VIEW does support USING +CREATE MATERIALIZED VIEW tableam_tblmv_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2 +-- +TABLE: name="tableam_tblmv_heap2" schema="" table="tableam_tblmv_heap2" ctx=DDL +TABLE: name="tableam_tbl_heap2" schema="" table="tableam_tbl_heap2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW tableam_tblmv_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2" +== 040 +-- truncate_limit: 100 +SELECT f1 FROM tableam_tblmv_heap2 ORDER BY f1 +-- +TABLE: name="tableam_tblmv_heap2" schema="" table="tableam_tblmv_heap2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM tableam_tblmv_heap2 ORDER BY f1" +== 041 +-- truncate_limit: 100 +-- CREATE TABLE .. PARTITION BY supports USING. +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a) USING heap2 +-- +TABLE: name="tableam_parted_heap2" schema="" table="tableam_parted_heap2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY LIST (a) USING heap2" +== 042 +-- truncate_limit: 100 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'tableam_parted_heap2' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +TRUNCATED: "SELECT a.amname FROM pg_class c, pg_am a WHERE ..." +== 043 +-- truncate_limit: 100 +DROP TABLE tableam_parted_heap2 +-- +TABLE: name="tableam_parted_heap2" schema="" table="tableam_parted_heap2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tableam_parted_heap2" +== 044 +-- truncate_limit: 100 +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a) +-- +TABLE: name="tableam_parted_heap2" schema="" table="tableam_parted_heap2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY LIST (a)" +== 045 +-- truncate_limit: 100 +-- new partitions will inherit from the current default, rather the partition root +SET default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_table_access_method TO heap" +== 046 +-- truncate_limit: 100 +CREATE TABLE tableam_parted_a_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('a') +-- +TABLE: name="tableam_parted_a_heap2" schema="" table="tableam_parted_a_heap2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_a_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('a')" +== 047 +-- truncate_limit: 100 +SET default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_table_access_method TO heap2" +== 048 +-- truncate_limit: 100 +CREATE TABLE tableam_parted_b_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('b') +-- +TABLE: name="tableam_parted_b_heap2" schema="" table="tableam_parted_b_heap2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_b_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('b')" +== 049 +-- truncate_limit: 100 +RESET default_table_access_method +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_table_access_method" +== 050 +-- truncate_limit: 100 +-- but the method can be explicitly specified +CREATE TABLE tableam_parted_c_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('c') USING heap +-- +TABLE: name="tableam_parted_c_heap2" schema="" table="tableam_parted_c_heap2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_c_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('c') USING heap" +== 051 +-- truncate_limit: 100 +CREATE TABLE tableam_parted_d_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('d') USING heap2 +-- +TABLE: name="tableam_parted_d_heap2" schema="" table="tableam_parted_d_heap2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_d_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('d') USING h..." +== 052 +-- truncate_limit: 100 +-- List all objects in AM +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc, + pg_am AS pa +WHERE pa.oid = pc.relam + AND pa.amname = 'heap2' +ORDER BY 3, 1, 2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +ALIAS: "pcm"="pg_class" +FILTER: schema="" table="pa" column="oid" +FILTER: schema="" table="pc" column="relam" +FILTER: schema="" table="pa" column="amname" +FILTER: schema="" table="pcm" column="reltoastrelid" +FILTER: schema="" table="pc" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc, pg_am pa WHERE ... ORDER BY 3, 1, 2" +== 053 +-- truncate_limit: 100 +-- Show dependencies onto AM - there shouldn't be any for toast +SELECT pg_describe_object(classid,objid,objsubid) AS obj +FROM pg_depend, pg_am +WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_am.amname = 'heap2' +ORDER BY classid, objid, objsubid +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_am" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend, pg_am WHERE ... ORDER BY classid, objid, objsubid" +== 054 +-- truncate_limit: 100 +-- ALTER TABLE SET ACCESS METHOD +CREATE TABLE heaptable USING heap AS + SELECT a, repeat(a::text, 100) FROM generate_series(1,9) AS a +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE heaptable USING heap AS SELECT a, repeat(a::text, 100) FROM generate_series(1, 9) a" +== 055 +-- truncate_limit: 100 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass" +== 056 +-- truncate_limit: 100 +-- Switching to heap2 adds new dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE heaptable SET ACCESS METHOD heap2" +== 057 +-- truncate_limit: 100 +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 = 'heaptable'::regclass + ORDER BY 1, 2 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1, 2" +== 058 +-- truncate_limit: 100 +-- Switching to heap should not have a dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE heaptable SET ACCESS METHOD heap" +== 059 +-- truncate_limit: 100 +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 = 'heaptable'::regclass + ORDER BY 1, 2 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1, 2" +== 060 +-- truncate_limit: 100 +ALTER TABLE heaptable SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE heaptable SET ACCESS METHOD heap2" +== 061 +-- truncate_limit: 100 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass" +== 062 +-- truncate_limit: 100 +SELECT COUNT(a), COUNT(1) FILTER(WHERE a=1) FROM heaptable +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(a), count(1) FILTER (WHERE a = 1) FROM heaptable" +== 063 +-- truncate_limit: 100 +-- DEFAULT access method +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 064 +-- truncate_limit: 100 +SET LOCAL default_table_access_method TO heap2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap2" +== 065 +-- truncate_limit: 100 +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE heaptable SET ACCESS METHOD DEFAULT" +== 066 +-- truncate_limit: 100 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass" +== 067 +-- truncate_limit: 100 +SET LOCAL default_table_access_method TO heap +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap" +== 068 +-- truncate_limit: 100 +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE heaptable SET ACCESS METHOD DEFAULT" +== 069 +-- truncate_limit: 100 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass" +== 070 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 071 +-- truncate_limit: 100 +-- ALTER MATERIALIZED VIEW SET ACCESS METHOD +CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT * FROM heaptable +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +TABLE: name="heaptable" schema="" table="heaptable" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT * FROM heaptable" +== 072 +-- truncate_limit: 100 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass" +== 073 +-- truncate_limit: 100 +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2 +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2" +== 074 +-- truncate_limit: 100 +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="am" column="oid" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass" +== 075 +-- truncate_limit: 100 +SELECT COUNT(a), COUNT(1) FILTER(WHERE a=1) FROM heapmv +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(a), count(1) FILTER (WHERE a = 1) FROM heapmv" +== 076 +-- truncate_limit: 100 +-- No support for multiple subcommands +ALTER TABLE heaptable SET ACCESS METHOD heap, SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE heaptable SET ACCESS METHOD heap, SET ACCESS METHOD heap2" +== 077 +-- truncate_limit: 100 +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT, SET ACCESS METHOD heap2 +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE heaptable SET ACCESS METHOD DEFAULT, SET ACCESS METHOD heap2" +== 078 +-- truncate_limit: 100 +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2 +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2" +== 079 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW heapmv +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW heapmv" +== 080 +-- truncate_limit: 100 +DROP TABLE heaptable +-- +TABLE: name="heaptable" schema="" table="heaptable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE heaptable" +== 081 +-- truncate_limit: 100 +-- Partitioned table with USING +CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) USING heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned (x int, y int) PARTITION BY HASH (x) USING heap2" +== 082 +-- truncate_limit: 100 +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend, pg_am WHERE ..." +== 083 +-- truncate_limit: 100 +DROP TABLE am_partitioned +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE am_partitioned" +== 084 +-- truncate_limit: 100 +-- Partition hierarchies with access methods +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 085 +-- truncate_limit: 100 +SET LOCAL default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap" +== 086 +-- truncate_limit: 100 +CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned (x int, y int) PARTITION BY HASH (x)" +== 087 +-- truncate_limit: 100 +-- pg_class.relam is 0, no dependency recorded between the AM and the +-- partitioned table. +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relam FROM pg_class WHERE relname = 'am_partitioned'" +== 088 +-- truncate_limit: 100 +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend, pg_am WHERE ..." +== 089 +-- truncate_limit: 100 +-- New default is set, with dependency added. +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD heap2" +== 090 +-- truncate_limit: 100 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +TRUNCATED: "SELECT a.amname FROM pg_class c, pg_am a WHERE c.relname = 'am_partitioned' AND a.oid = c.relam" +== 091 +-- truncate_limit: 100 +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend, pg_am WHERE ..." +== 092 +-- truncate_limit: 100 +-- Default is set, with dependency updated. +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap2" +== 093 +-- truncate_limit: 100 +ALTER TABLE am_partitioned SET ACCESS METHOD heap +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD heap" +== 094 +-- truncate_limit: 100 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +TRUNCATED: "SELECT a.amname FROM pg_class c, pg_am a WHERE c.relname = 'am_partitioned' AND a.oid = c.relam" +== 095 +-- truncate_limit: 100 +-- Dependency pinned, hence removed. +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="pg_depend" column="refclassid" +FILTER: schema="" table="pg_am" column="oid" +FILTER: schema="" table="pg_depend" column="refobjid" +FILTER: schema="" table="pg_depend" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend, pg_am WHERE ..." +== 096 +-- truncate_limit: 100 +-- Default and AM set in the clause are the same, relam should be set. +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap2" +== 097 +-- truncate_limit: 100 +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD heap2" +== 098 +-- truncate_limit: 100 +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relam" +STMT: SelectStmt +TRUNCATED: "SELECT a.amname FROM pg_class c, pg_am a WHERE c.relname = 'am_partitioned' AND a.oid = c.relam" +== 099 +-- truncate_limit: 100 +-- Reset to default +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT" +== 100 +-- truncate_limit: 100 +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relam FROM pg_class WHERE relname = 'am_partitioned'" +== 101 +-- truncate_limit: 100 +-- Upon ALTER TABLE SET ACCESS METHOD on a partitioned table, new partitions +-- will inherit the AM set. Existing partitioned are unchanged. +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relam FROM pg_class WHERE relname = 'am_partitioned'" +== 102 +-- truncate_limit: 100 +SET LOCAL default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap" +== 103 +-- truncate_limit: 100 +CREATE TABLE am_partitioned_0 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 0) +-- +TABLE: name="am_partitioned_0" schema="" table="am_partitioned_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_0 PARTITION OF am_partitioned FOR VALUES WITH (MODULUS 10, REMAINDER 0)" +== 104 +-- truncate_limit: 100 +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap2" +== 105 +-- truncate_limit: 100 +CREATE TABLE am_partitioned_1 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="am_partitioned_1" schema="" table="am_partitioned_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_1 PARTITION OF am_partitioned FOR VALUES WITH (MODULUS 10, REMAINDER 1)" +== 106 +-- truncate_limit: 100 +SET LOCAL default_table_access_method = 'heap' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap" +== 107 +-- truncate_limit: 100 +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD heap2" +== 108 +-- truncate_limit: 100 +CREATE TABLE am_partitioned_2 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 2) +-- +TABLE: name="am_partitioned_2" schema="" table="am_partitioned_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_2 PARTITION OF am_partitioned FOR VALUES WITH (MODULUS 10, REMAINDER 2)" +== 109 +-- truncate_limit: 100 +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT" +== 110 +-- truncate_limit: 100 +SELECT relam FROM pg_class WHERE relname = 'am_partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relam FROM pg_class WHERE relname = 'am_partitioned'" +== 111 +-- truncate_limit: 100 +CREATE TABLE am_partitioned_3 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 3) +-- +TABLE: name="am_partitioned_3" schema="" table="am_partitioned_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_3 PARTITION OF am_partitioned FOR VALUES WITH (MODULUS 10, REMAINDER 3)" +== 112 +-- truncate_limit: 100 +-- Partitioned table with relam at 0 +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT" +== 113 +-- truncate_limit: 100 +CREATE TABLE am_partitioned_5p PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 5) PARTITION BY hash(y) +-- +TABLE: name="am_partitioned_5p" schema="" table="am_partitioned_5p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_5p PARTITION OF am_partitioned FOR VALUES WITH (MODULUS 10, REMAINDER..." +== 114 +-- truncate_limit: 100 +-- Partitions of this partitioned table inherit default AM at creation +-- time. +CREATE TABLE am_partitioned_5p1 PARTITION OF am_partitioned_5p + FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="am_partitioned_5p1" schema="" table="am_partitioned_5p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_5p1 PARTITION OF am_partitioned_5p FOR VALUES WITH (MODULUS 10, REMAI..." +== 115 +-- truncate_limit: 100 +-- Partitioned table with relam set. +ALTER TABLE am_partitioned SET ACCESS METHOD heap2 +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE am_partitioned SET ACCESS METHOD heap2" +== 116 +-- truncate_limit: 100 +CREATE TABLE am_partitioned_6p PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 6) PARTITION BY hash(y) +-- +TABLE: name="am_partitioned_6p" schema="" table="am_partitioned_6p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_6p PARTITION OF am_partitioned FOR VALUES WITH (MODULUS 10, REMAINDER..." +== 117 +-- truncate_limit: 100 +-- Partitions of this partitioned table inherit its AM. +CREATE TABLE am_partitioned_6p1 PARTITION OF am_partitioned_6p + FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="am_partitioned_6p1" schema="" table="am_partitioned_6p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE am_partitioned_6p1 PARTITION OF am_partitioned_6p FOR VALUES WITH (MODULUS 10, REMAI..." +== 118 +-- truncate_limit: 100 +SELECT c.relname, a.amname FROM pg_class c, pg_am a + WHERE c.relam = a.oid AND + c.relname LIKE 'am_partitioned%' +UNION ALL +SELECT c.relname, 'default' FROM pg_class c + WHERE c.relam = 0 + AND c.relname LIKE 'am_partitioned%' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_am" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="a" column="oid" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="c" column="relam" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c, pg_am a WHERE ... UNION ALL SELECT ... FROM pg_class c WHERE ... ORDE..." +== 119 +-- truncate_limit: 100 +DROP TABLE am_partitioned +-- +TABLE: name="am_partitioned" schema="" table="am_partitioned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE am_partitioned" +== 120 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 121 +-- truncate_limit: 100 +-- Second, create objects in the new AM by changing the default AM +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 122 +-- truncate_limit: 100 +SET LOCAL default_table_access_method = 'heap2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL default_table_access_method TO heap2" +== 123 +-- truncate_limit: 100 +-- following tests should all respect the default AM +CREATE TABLE tableam_tbl_heapx(f1 int) +-- +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_tbl_heapx (f1 int)" +== 124 +-- truncate_limit: 100 +CREATE TABLE tableam_tblas_heapx AS SELECT * FROM tableam_tbl_heapx +-- +TABLE: name="tableam_tblas_heapx" schema="" table="tableam_tblas_heapx" ctx=DDL +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE tableam_tblas_heapx AS SELECT * FROM tableam_tbl_heapx" +== 125 +-- truncate_limit: 100 +SELECT INTO tableam_tblselectinto_heapx FROM tableam_tbl_heapx +-- +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +TABLE: name="tableam_tblselectinto_heapx" schema="" table="tableam_tblselectinto_heapx" ctx=DDL +STMT: SelectStmt +TRUNCATED: "SELECT INTO tableam_tblselectinto_heapx FROM tableam_tbl_heapx" +== 126 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW tableam_tblmv_heapx USING heap2 AS SELECT * FROM tableam_tbl_heapx +-- +TABLE: name="tableam_tblmv_heapx" schema="" table="tableam_tblmv_heapx" ctx=DDL +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW tableam_tblmv_heapx USING heap2 AS SELECT * FROM tableam_tbl_heapx" +== 127 +-- truncate_limit: 100 +CREATE TABLE tableam_parted_heapx (a text, b int) PARTITION BY list (a) +-- +TABLE: name="tableam_parted_heapx" schema="" table="tableam_parted_heapx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_heapx (a text, b int) PARTITION BY LIST (a)" +== 128 +-- truncate_limit: 100 +CREATE TABLE tableam_parted_1_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('a', 'b') +-- +TABLE: name="tableam_parted_1_heapx" schema="" table="tableam_parted_1_heapx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_1_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('a', 'b')" +== 129 +-- truncate_limit: 100 +-- but an explicitly set AM overrides it +CREATE TABLE tableam_parted_2_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('c', 'd') USING heap +-- +TABLE: name="tableam_parted_2_heapx" schema="" table="tableam_parted_2_heapx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tableam_parted_2_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('c', 'd') US..." +== 130 +-- truncate_limit: 100 +-- sequences, views and foreign servers shouldn't have an AM +CREATE VIEW tableam_view_heapx AS SELECT * FROM tableam_tbl_heapx +-- +TABLE: name="tableam_view_heapx" schema="" table="tableam_view_heapx" ctx=DDL +TABLE: name="tableam_tbl_heapx" schema="" table="tableam_tbl_heapx" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tableam_view_heapx AS SELECT * FROM tableam_tbl_heapx" +== 131 +-- truncate_limit: 100 +CREATE SEQUENCE tableam_seq_heapx +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE tableam_seq_heapx" +== 132 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER fdw_heap2 VALIDATOR postgresql_fdw_validator +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER fdw_heap2 VALIDATOR postgresql_fdw_validator" +== 133 +-- truncate_limit: 100 +CREATE SERVER fs_heap2 FOREIGN DATA WRAPPER fdw_heap2 +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER fs_heap2 FOREIGN DATA WRAPPER fdw_heap2" +== 134 +-- truncate_limit: 100 +CREATE FOREIGN table tableam_fdw_heapx () SERVER fs_heap2 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE tableam_fdw_heapx () SERVER fs_heap2" +== 135 +-- truncate_limit: 100 +-- Verify that new AM was used for tables, matviews, but not for sequences, views and fdws +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc + LEFT JOIN pg_am AS pa ON (pa.oid = pc.relam) +WHERE pc.relname LIKE 'tableam_%_heapx' +ORDER BY 3, 1, 2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +ALIAS: "pcm"="pg_class" +FILTER: schema="" table="pc" column="relname" +FILTER: schema="" table="pcm" column="reltoastrelid" +FILTER: schema="" table="pc" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc LEFT JOIN pg_am pa ON pa.oid = pc.relam WHERE ... ORDER BY 3, 1, 2" +== 136 +-- truncate_limit: 100 +-- don't want to keep those tables, nor the default +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 137 +-- truncate_limit: 100 +-- Third, check that we can neither create a table using a nonexistent +-- AM, nor using an index AM +CREATE TABLE i_am_a_failure() USING "notempty" +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE i_am_a_failure () USING notempty" +== 138 +-- truncate_limit: 100 +CREATE TABLE i_am_a_failure() USING i_do_not_exist_am +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE i_am_a_failure () USING i_do_not_exist_am" +== 139 +-- truncate_limit: 100 +CREATE TABLE i_am_a_failure() USING "I do not exist AM" +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE i_am_a_failure () USING \"I do not exist AM\"" +== 140 +-- truncate_limit: 100 +CREATE TABLE i_am_a_failure() USING "btree" +-- +TABLE: name="i_am_a_failure" schema="" table="i_am_a_failure" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE i_am_a_failure () USING btree" +== 141 +-- truncate_limit: 100 +-- Other weird invalid cases that cause problems +CREATE FOREIGN TABLE fp PARTITION OF tableam_parted_a_heap2 DEFAULT SERVER x +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE fp PARTITION OF tableam_parted_a_heap2 DEFAULT SERVER x" +== 142 +-- truncate_limit: 100 +-- Drop table access method, which fails as objects depends on it +DROP ACCESS METHOD heap2 +-- +STMT: DropStmt +TRUNCATED: "DROP ACCESS METHOD heap2" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json new file mode 100644 index 0000000..5d34ab7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json @@ -0,0 +1,28 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_cast.test b/parser/testdata/summary_truncate/postgres_regress/create_cast.test new file mode 100644 index 0000000..25468b0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_cast.test @@ -0,0 +1,214 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_CAST +|-- + +-- Create some types to test with +CREATE TYPE casttesttype +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE casttesttype" +== 002 +-- truncate_limit: 100 +CREATE FUNCTION casttesttype_in(cstring) + RETURNS casttesttype + AS 'textin' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="casttesttype_in" function="casttesttype_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION casttesttype_in(cstring) RETURNS casttesttype AS $$textin$$ LANGUAGE internal RET..." +== 003 +-- truncate_limit: 100 +CREATE FUNCTION casttesttype_out(casttesttype) + RETURNS cstring + AS 'textout' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="casttesttype_out" function="casttesttype_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION casttesttype_out(casttesttype) RETURNS cstring AS $$textout$$ LANGUAGE internal R..." +== 004 +-- truncate_limit: 100 +CREATE TYPE casttesttype ( + internallength = variable, + input = casttesttype_in, + output = casttesttype_out, + alignment = int4 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE casttesttype (internallength = variable, input = casttesttype_in, output = casttestty..." +== 005 +-- truncate_limit: 100 +-- a dummy function to test with +CREATE FUNCTION casttestfunc(casttesttype) RETURNS int4 LANGUAGE SQL AS +$$ SELECT 1; $$ +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION casttestfunc(casttesttype) RETURNS int4 LANGUAGE sql AS $$ SELECT 1; $$" +== 006 +-- truncate_limit: 100 +SELECT casttestfunc('foo'::text) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT casttestfunc('foo'::text)" +== 007 +-- truncate_limit: 100 +-- fails, as there's no cast + +-- Try binary coercion cast +CREATE CAST (text AS casttesttype) WITHOUT FUNCTION +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (text AS casttesttype) WITHOUT FUNCTION" +== 008 +-- truncate_limit: 100 +SELECT casttestfunc('foo'::text) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT casttestfunc('foo'::text)" +== 009 +-- truncate_limit: 100 +-- doesn't work, as the cast is explicit +SELECT casttestfunc('foo'::text::casttesttype) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT casttestfunc('foo'::text::casttesttype)" +== 010 +-- truncate_limit: 100 +-- should work +DROP CAST (text AS casttesttype) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST (text AS casttesttype)" +== 011 +-- truncate_limit: 100 +-- cleanup + +-- Try IMPLICIT binary coercion cast +CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT" +== 012 +-- truncate_limit: 100 +SELECT casttestfunc('foo'::text) +-- +FUNCTION: name="casttestfunc" function="casttestfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT casttestfunc('foo'::text)" +== 013 +-- truncate_limit: 100 +-- Should work now + +-- Try I/O conversion cast. +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1234::int4::casttesttype" +== 014 +-- truncate_limit: 100 +-- No cast yet, should fail + +CREATE CAST (int4 AS casttesttype) WITH INOUT +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int4 AS casttesttype) WITH INOUT" +== 015 +-- truncate_limit: 100 +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1234::int4::casttesttype" +== 016 +-- truncate_limit: 100 +-- Should work now + +DROP CAST (int4 AS casttesttype) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST (int4 AS casttesttype)" +== 017 +-- truncate_limit: 100 +-- Try cast with a function + +CREATE FUNCTION int4_casttesttype(int4) RETURNS casttesttype LANGUAGE SQL AS +$$ SELECT ('foo'::text || $1::text)::casttesttype; $$ +-- +FUNCTION: name="int4_casttesttype" function="int4_casttesttype" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int4_casttesttype(int4) RETURNS casttesttype LANGUAGE sql AS $$ SELECT ('foo'::te..." +== 018 +-- truncate_limit: 100 +CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT" +== 019 +-- truncate_limit: 100 +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1234::int4::casttesttype" +== 020 +-- truncate_limit: 100 +-- Should work now + +DROP FUNCTION int4_casttesttype(int4) CASCADE +-- +FUNCTION: name="int4_casttesttype" function="int4_casttesttype" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION int4_casttesttype(int4) CASCADE" +== 021 +-- truncate_limit: 100 +-- Try it with a function that requires an implicit cast + +CREATE FUNCTION bar_int4_text(int4) RETURNS text LANGUAGE SQL AS +$$ SELECT ('bar'::text || $1::text); $$ +-- +FUNCTION: name="bar_int4_text" function="bar_int4_text" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bar_int4_text(int4) RETURNS text LANGUAGE sql AS $$ SELECT ('bar'::text || $1::te..." +== 022 +-- truncate_limit: 100 +CREATE CAST (int4 AS casttesttype) WITH FUNCTION bar_int4_text(int4) AS IMPLICIT +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int4 AS casttesttype) WITH FUNCTION bar_int4_text(int4) AS IMPLICIT" +== 023 +-- truncate_limit: 100 +SELECT 1234::int4::casttesttype +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1234::int4::casttesttype" +== 024 +-- truncate_limit: 100 +-- Should work now + +-- check dependencies generated for that +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype +FROM pg_depend +WHERE classid = 'pg_cast'::regclass AND + objid = (SELECT oid FROM pg_cast + WHERE castsource = 'int4'::regtype + AND casttarget = 'casttesttype'::regtype) +ORDER BY refclassid +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY refclassid" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json new file mode 100644 index 0000000..e8e06a4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json @@ -0,0 +1,9 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_function_c.test b/parser/testdata/summary_truncate/postgres_regress/create_function_c.test new file mode 100644 index 0000000..8207bd8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_function_c.test @@ -0,0 +1,60 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_FUNCTION_C +|-- +-- This script used to create C functions for other scripts to use. +-- But to get rid of the ordering dependencies that caused, such +-- functions are now made either in test_setup.sql or in the specific +-- test script that needs them. All that remains here is error cases. + +-- directory path and dlsuffix are passed to us in environment variables + + +|-- +-- Check LOAD command. (The alternative of implicitly loading the library +-- is checked in many other test scripts.) +|-- +LOAD :'regresslib' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 507 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +-- Things that shouldn't work: + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS 'nosuchfile' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test1(int) RETURNS int LANGUAGE c AS $$nosuchfile$$" +== 003 +-- truncate_limit: 100 +-- To produce stable regression test output, we have to filter the name +-- of the regresslib file out of the error message in this test. +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS :'regresslib', 'nosuchsymbol' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 196 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +SELECT regexp_replace(:'LAST_ERROR_MESSAGE', 'file ".*"', 'file "..."') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- truncate_limit: 100 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal + AS 'nosuch' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test1(int) RETURNS int LANGUAGE internal AS $$nosuch$$" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json new file mode 100644 index 0000000..643249b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json @@ -0,0 +1,159 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_function_sql.test b/parser/testdata/summary_truncate/postgres_regress/create_function_sql.test new file mode 100644 index 0000000..3f3ea95 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_function_sql.test @@ -0,0 +1,1288 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_FUNCTION_SQL +|-- +-- Assorted tests using SQL-language functions +|-- + +-- All objects made in this test are in temp_func_test schema + +CREATE USER regress_unpriv_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_unpriv_user" +== 002 +-- truncate_limit: 100 +CREATE SCHEMA temp_func_test +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA temp_func_test" +== 003 +-- truncate_limit: 100 +GRANT ALL ON SCHEMA temp_func_test TO public +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON SCHEMA temp_func_test TO public" +== 004 +-- truncate_limit: 100 +SET search_path TO temp_func_test, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO temp_func_test, public" +== 005 +-- truncate_limit: 100 +|-- +-- Make sanity checks on the pg_proc entries created by CREATE FUNCTION +|-- + +|-- +-- ARGUMENT and RETURN TYPES +|-- +CREATE FUNCTION functest_A_1(text, date) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 = ''abcd'' AND $2 > ''2001-01-01''' +-- +FUNCTION: name="functest_a_1" function="functest_a_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_a_1(text, date) RETURNS bool LANGUAGE sql AS $$SELECT $1 = 'abcd' AND $2..." +== 006 +-- truncate_limit: 100 +CREATE FUNCTION functest_A_2(text[]) RETURNS int LANGUAGE 'sql' + AS 'SELECT $1[1]::int' +-- +FUNCTION: name="functest_a_2" function="functest_a_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_a_2(text[]) RETURNS int LANGUAGE sql AS $$SELECT $1[1]::int$$" +== 007 +-- truncate_limit: 100 +CREATE FUNCTION functest_A_3() RETURNS bool LANGUAGE 'sql' + AS 'SELECT false' +-- +FUNCTION: name="functest_a_3" function="functest_a_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_a_3() RETURNS bool LANGUAGE sql AS $$SELECT false$$" +== 008 +-- truncate_limit: 100 +SELECT proname, prorettype::regtype, proargtypes::regtype[] FROM pg_proc + WHERE oid in ('functest_A_1'::regproc, + 'functest_A_2'::regproc, + 'functest_A_3'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, prorettype::regtype, proargtypes::regtype[] FROM pg_proc WHERE ... ORDER BY proname" +== 009 +-- truncate_limit: 100 +SELECT functest_A_1('abcd', '2020-01-01') +-- +FUNCTION: name="functest_a_1" function="functest_a_1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_a_1('abcd', '2020-01-01')" +== 010 +-- truncate_limit: 100 +SELECT functest_A_2(ARRAY['1', '2', '3']) +-- +FUNCTION: name="functest_a_2" function="functest_a_2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_a_2(ARRAY['1', '2', '3'])" +== 011 +-- truncate_limit: 100 +SELECT functest_A_3() +-- +FUNCTION: name="functest_a_3" function="functest_a_3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_a_3()" +== 012 +-- truncate_limit: 100 +|-- +-- IMMUTABLE | STABLE | VOLATILE +|-- +CREATE FUNCTION functest_B_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_b_1" function="functest_b_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_b_1(int) RETURNS bool LANGUAGE sql AS $$SELECT $1 > 0$$" +== 013 +-- truncate_limit: 100 +CREATE FUNCTION functest_B_2(int) RETURNS bool LANGUAGE 'sql' + IMMUTABLE AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_b_2" function="functest_b_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_b_2(int) RETURNS bool LANGUAGE sql IMMUTABLE AS $$SELECT $1 > 0$$" +== 014 +-- truncate_limit: 100 +CREATE FUNCTION functest_B_3(int) RETURNS bool LANGUAGE 'sql' + STABLE AS 'SELECT $1 = 0' +-- +FUNCTION: name="functest_b_3" function="functest_b_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_b_3(int) RETURNS bool LANGUAGE sql STABLE AS $$SELECT $1 = 0$$" +== 015 +-- truncate_limit: 100 +CREATE FUNCTION functest_B_4(int) RETURNS bool LANGUAGE 'sql' + VOLATILE AS 'SELECT $1 < 0' +-- +FUNCTION: name="functest_b_4" function="functest_b_4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_b_4(int) RETURNS bool LANGUAGE sql VOLATILE AS $$SELECT $1 < 0$$" +== 016 +-- truncate_limit: 100 +SELECT proname, provolatile FROM pg_proc + WHERE oid in ('functest_B_1'::regproc, + 'functest_B_2'::regproc, + 'functest_B_3'::regproc, + 'functest_B_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, provolatile FROM pg_proc WHERE ... ORDER BY proname" +== 017 +-- truncate_limit: 100 +ALTER FUNCTION functest_B_2(int) VOLATILE +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_b_2(int) VOLATILE" +== 018 +-- truncate_limit: 100 +ALTER FUNCTION functest_B_3(int) COST 100 +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_b_3(int) COST 100" +== 019 +-- truncate_limit: 100 +-- unrelated change, no effect +SELECT proname, provolatile FROM pg_proc + WHERE oid in ('functest_B_1'::regproc, + 'functest_B_2'::regproc, + 'functest_B_3'::regproc, + 'functest_B_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, provolatile FROM pg_proc WHERE ... ORDER BY proname" +== 020 +-- truncate_limit: 100 +|-- +-- SECURITY DEFINER | INVOKER +|-- +CREATE FUNCTION functest_C_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_c_1" function="functest_c_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_c_1(int) RETURNS bool LANGUAGE sql AS $$SELECT $1 > 0$$" +== 021 +-- truncate_limit: 100 +CREATE FUNCTION functest_C_2(int) RETURNS bool LANGUAGE 'sql' + SECURITY DEFINER AS 'SELECT $1 = 0' +-- +FUNCTION: name="functest_c_2" function="functest_c_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_c_2(int) RETURNS bool LANGUAGE sql SECURITY DEFINER AS $$SELECT $1 = 0$$" +== 022 +-- truncate_limit: 100 +CREATE FUNCTION functest_C_3(int) RETURNS bool LANGUAGE 'sql' + SECURITY INVOKER AS 'SELECT $1 < 0' +-- +FUNCTION: name="functest_c_3" function="functest_c_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_c_3(int) RETURNS bool LANGUAGE sql SECURITY INVOKER AS $$SELECT $1 < 0$$" +== 023 +-- truncate_limit: 100 +SELECT proname, prosecdef FROM pg_proc + WHERE oid in ('functest_C_1'::regproc, + 'functest_C_2'::regproc, + 'functest_C_3'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, prosecdef FROM pg_proc WHERE ... ORDER BY proname" +== 024 +-- truncate_limit: 100 +ALTER FUNCTION functest_C_1(int) IMMUTABLE +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_c_1(int) IMMUTABLE" +== 025 +-- truncate_limit: 100 +-- unrelated change, no effect +ALTER FUNCTION functest_C_2(int) SECURITY INVOKER +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_c_2(int) SECURITY INVOKER" +== 026 +-- truncate_limit: 100 +ALTER FUNCTION functest_C_3(int) SECURITY DEFINER +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_c_3(int) SECURITY DEFINER" +== 027 +-- truncate_limit: 100 +SELECT proname, prosecdef FROM pg_proc + WHERE oid in ('functest_C_1'::regproc, + 'functest_C_2'::regproc, + 'functest_C_3'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, prosecdef FROM pg_proc WHERE ... ORDER BY proname" +== 028 +-- truncate_limit: 100 +|-- +-- LEAKPROOF +|-- +CREATE FUNCTION functest_E_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 100' +-- +FUNCTION: name="functest_e_1" function="functest_e_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_e_1(int) RETURNS bool LANGUAGE sql AS $$SELECT $1 > 100$$" +== 029 +-- truncate_limit: 100 +CREATE FUNCTION functest_E_2(int) RETURNS bool LANGUAGE 'sql' + LEAKPROOF AS 'SELECT $1 > 100' +-- +FUNCTION: name="functest_e_2" function="functest_e_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_e_2(int) RETURNS bool LANGUAGE sql LEAKPROOF AS $$SELECT $1 > 100$$" +== 030 +-- truncate_limit: 100 +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, proleakproof FROM pg_proc WHERE ... ORDER BY proname" +== 031 +-- truncate_limit: 100 +ALTER FUNCTION functest_E_1(int) LEAKPROOF +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_e_1(int) LEAKPROOF" +== 032 +-- truncate_limit: 100 +ALTER FUNCTION functest_E_2(int) STABLE +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_e_2(int) STABLE" +== 033 +-- truncate_limit: 100 +-- unrelated change, no effect +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, proleakproof FROM pg_proc WHERE ... ORDER BY proname" +== 034 +-- truncate_limit: 100 +ALTER FUNCTION functest_E_2(int) NOT LEAKPROOF +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_e_2(int) NOT LEAKPROOF" +== 035 +-- truncate_limit: 100 +-- remove leakproof attribute +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, proleakproof FROM pg_proc WHERE ... ORDER BY proname" +== 036 +-- truncate_limit: 100 +-- it takes superuser privilege to turn on leakproof, but not to turn off +ALTER FUNCTION functest_E_1(int) OWNER TO regress_unpriv_user +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FUNCTION functest_e_1(int) OWNER TO regress_unpriv_user" +== 037 +-- truncate_limit: 100 +ALTER FUNCTION functest_E_2(int) OWNER TO regress_unpriv_user +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FUNCTION functest_e_2(int) OWNER TO regress_unpriv_user" +== 038 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_unpriv_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_unpriv_user" +== 039 +-- truncate_limit: 100 +SET search_path TO temp_func_test, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO temp_func_test, public" +== 040 +-- truncate_limit: 100 +ALTER FUNCTION functest_E_1(int) NOT LEAKPROOF +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_e_1(int) NOT LEAKPROOF" +== 041 +-- truncate_limit: 100 +ALTER FUNCTION functest_E_2(int) LEAKPROOF +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_e_2(int) LEAKPROOF" +== 042 +-- truncate_limit: 100 +CREATE FUNCTION functest_E_3(int) RETURNS bool LANGUAGE 'sql' + LEAKPROOF AS 'SELECT $1 < 200' +-- +FUNCTION: name="functest_e_3" function="functest_e_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_e_3(int) RETURNS bool LANGUAGE sql LEAKPROOF AS $$SELECT $1 < 200$$" +== 043 +-- truncate_limit: 100 +-- fail + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 044 +-- truncate_limit: 100 +|-- +-- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT +|-- +CREATE FUNCTION functest_F_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 50' +-- +FUNCTION: name="functest_f_1" function="functest_f_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_f_1(int) RETURNS bool LANGUAGE sql AS $$SELECT $1 > 50$$" +== 045 +-- truncate_limit: 100 +CREATE FUNCTION functest_F_2(int) RETURNS bool LANGUAGE 'sql' + CALLED ON NULL INPUT AS 'SELECT $1 = 50' +-- +FUNCTION: name="functest_f_2" function="functest_f_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_f_2(int) RETURNS bool LANGUAGE sql CALLED ON NULL INPUT AS $$SELECT $1 =..." +== 046 +-- truncate_limit: 100 +CREATE FUNCTION functest_F_3(int) RETURNS bool LANGUAGE 'sql' + RETURNS NULL ON NULL INPUT AS 'SELECT $1 < 50' +-- +FUNCTION: name="functest_f_3" function="functest_f_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_f_3(int) RETURNS bool LANGUAGE sql RETURNS NULL ON NULL INPUT AS $$SELEC..." +== 047 +-- truncate_limit: 100 +CREATE FUNCTION functest_F_4(int) RETURNS bool LANGUAGE 'sql' + STRICT AS 'SELECT $1 = 50' +-- +FUNCTION: name="functest_f_4" function="functest_f_4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_f_4(int) RETURNS bool LANGUAGE sql RETURNS NULL ON NULL INPUT AS $$SELEC..." +== 048 +-- truncate_limit: 100 +SELECT proname, proisstrict FROM pg_proc + WHERE oid in ('functest_F_1'::regproc, + 'functest_F_2'::regproc, + 'functest_F_3'::regproc, + 'functest_F_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, proisstrict FROM pg_proc WHERE ... ORDER BY proname" +== 049 +-- truncate_limit: 100 +ALTER FUNCTION functest_F_1(int) IMMUTABLE +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_f_1(int) IMMUTABLE" +== 050 +-- truncate_limit: 100 +-- unrelated change, no effect +ALTER FUNCTION functest_F_2(int) STRICT +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_f_2(int) RETURNS NULL ON NULL INPUT" +== 051 +-- truncate_limit: 100 +ALTER FUNCTION functest_F_3(int) CALLED ON NULL INPUT +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION functest_f_3(int) CALLED ON NULL INPUT" +== 052 +-- truncate_limit: 100 +SELECT proname, proisstrict FROM pg_proc + WHERE oid in ('functest_F_1'::regproc, + 'functest_F_2'::regproc, + 'functest_F_3'::regproc, + 'functest_F_4'::regproc) ORDER BY proname +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT proname, proisstrict FROM pg_proc WHERE ... ORDER BY proname" +== 053 +-- truncate_limit: 100 +-- pg_get_functiondef tests + +SELECT pg_get_functiondef('functest_A_1'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_A_1'::regproc)" +== 054 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_B_3'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_B_3'::regproc)" +== 055 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_C_3'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_C_3'::regproc)" +== 056 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_F_2'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_F_2'::regproc)" +== 057 +-- truncate_limit: 100 +|-- +-- SQL-standard body +|-- +CREATE FUNCTION functest_S_1(a text, b date) RETURNS boolean + LANGUAGE SQL + RETURN a = 'abcd' AND b > '2001-01-01' +-- +FUNCTION: name="functest_s_1" function="functest_s_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_s_1(a text, b date) RETURNS boolean LANGUAGE sql RETURN a = 'abcd' AND b..." +== 058 +-- truncate_limit: 100 +CREATE FUNCTION functest_S_2(a text[]) RETURNS int + RETURN a[1]::int +-- +FUNCTION: name="functest_s_2" function="functest_s_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_s_2(a text[]) RETURNS int RETURN a[1]::int" +== 059 +-- truncate_limit: 100 +CREATE FUNCTION functest_S_3() RETURNS boolean + RETURN false +-- +FUNCTION: name="functest_s_3" function="functest_s_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_s_3() RETURNS boolean RETURN false" +== 060 +-- truncate_limit: 100 +CREATE FUNCTION functest_S_3a() RETURNS boolean + BEGIN ATOMIC +-- +ERROR: syntax error at end of input +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 061 +-- truncate_limit: 100 +RETURN false +-- +ERROR: syntax error at or near "RETURN" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 062 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 063 +-- truncate_limit: 100 +CREATE FUNCTION functest_S_10(a text, b date) RETURNS boolean + LANGUAGE SQL + BEGIN ATOMIC + SELECT a = 'abcd' AND b > '2001-01-01' +-- +ERROR: syntax error at end of input +CURSORPOS: 143 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 064 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 065 +-- truncate_limit: 100 +CREATE FUNCTION functest_S_13() RETURNS boolean + BEGIN ATOMIC + SELECT 1 +-- +ERROR: syntax error at end of input +CURSORPOS: 82 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 066 +-- truncate_limit: 100 +SELECT false +-- +STMT: SelectStmt +TRUNCATED: "SELECT false" +== 067 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 068 +-- truncate_limit: 100 +-- check display of function arguments in sub-SELECT +CREATE TABLE functest1 (i int) +-- +TABLE: name="functest1" schema="" table="functest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE functest1 (i int)" +== 069 +-- truncate_limit: 100 +CREATE FUNCTION functest_S_16(a int, b int) RETURNS void + LANGUAGE SQL + BEGIN ATOMIC + INSERT INTO functest1 SELECT a + $2 +-- +ERROR: syntax error at end of input +CURSORPOS: 135 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 070 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 071 +-- truncate_limit: 100 +-- error: duplicate function body +CREATE FUNCTION functest_S_xxx(x int) RETURNS int + LANGUAGE SQL + AS $$ SELECT x * 2 $$ + RETURN x * 3 +-- +FUNCTION: name="functest_s_xxx" function="functest_s_xxx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_s_xxx(x int) RETURNS int LANGUAGE sql AS $$ SELECT x * 2 $$ RETURN x * 3" +== 072 +-- truncate_limit: 100 +-- polymorphic arguments not allowed in this form +CREATE FUNCTION functest_S_xx(x anyarray) RETURNS anyelement + LANGUAGE SQL + RETURN x[1] +-- +FUNCTION: name="functest_s_xx" function="functest_s_xx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_s_xx(x anyarray) RETURNS anyelement LANGUAGE sql RETURN x[1]" +== 073 +-- truncate_limit: 100 +-- check reporting of parse-analysis errors +CREATE FUNCTION functest_S_xx(x date) RETURNS boolean + LANGUAGE SQL + RETURN x > 1 +-- +FUNCTION: name="functest_s_xx" function="functest_s_xx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_s_xx(x date) RETURNS boolean LANGUAGE sql RETURN x > 1" +== 074 +-- truncate_limit: 100 +-- tricky parsing +CREATE FUNCTION functest_S_15(x int) RETURNS boolean +LANGUAGE SQL +BEGIN ATOMIC + select case when x % 2 = 0 then true else false end +-- +ERROR: syntax error at end of input +CURSORPOS: 153 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 076 +-- truncate_limit: 100 +SELECT functest_S_1('abcd', '2020-01-01') +-- +FUNCTION: name="functest_s_1" function="functest_s_1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_s_1('abcd', '2020-01-01')" +== 077 +-- truncate_limit: 100 +SELECT functest_S_2(ARRAY['1', '2', '3']) +-- +FUNCTION: name="functest_s_2" function="functest_s_2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_s_2(ARRAY['1', '2', '3'])" +== 078 +-- truncate_limit: 100 +SELECT functest_S_3() +-- +FUNCTION: name="functest_s_3" function="functest_s_3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_s_3()" +== 079 +-- truncate_limit: 100 +SELECT functest_S_10('abcd', '2020-01-01') +-- +FUNCTION: name="functest_s_10" function="functest_s_10" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_s_10('abcd', '2020-01-01')" +== 080 +-- truncate_limit: 100 +SELECT functest_S_13() +-- +FUNCTION: name="functest_s_13" function="functest_s_13" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_s_13()" +== 081 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_1'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_1'::regproc)" +== 082 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_2'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_2'::regproc)" +== 083 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_3'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_3'::regproc)" +== 084 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_3a'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_3a'::regproc)" +== 085 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_10'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_10'::regproc)" +== 086 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_13'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_13'::regproc)" +== 087 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_15'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_15'::regproc)" +== 088 +-- truncate_limit: 100 +SELECT pg_get_functiondef('functest_S_16'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('functest_S_16'::regproc)" +== 089 +-- truncate_limit: 100 +DROP TABLE functest1 CASCADE +-- +TABLE: name="functest1" schema="" table="functest1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE functest1 CASCADE" +== 090 +-- truncate_limit: 100 +-- test with views +CREATE TABLE functest3 (a int) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE functest3 (a int)" +== 091 +-- truncate_limit: 100 +INSERT INTO functest3 VALUES (1), (2) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO functest3 VALUES (1), (2)" +== 092 +-- truncate_limit: 100 +CREATE VIEW functestv3 AS SELECT * FROM functest3 +-- +TABLE: name="functestv3" schema="" table="functestv3" ctx=DDL +TABLE: name="functest3" schema="" table="functest3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW functestv3 AS SELECT * FROM functest3" +== 093 +-- truncate_limit: 100 +CREATE FUNCTION functest_S_14() RETURNS bigint + RETURN (SELECT count(*) FROM functestv3) +-- +FUNCTION: name="functest_s_14" function="functest_s_14" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_s_14() RETURNS bigint RETURN (SELECT count(*) FROM functestv3)" +== 094 +-- truncate_limit: 100 +SELECT functest_S_14() +-- +FUNCTION: name="functest_s_14" function="functest_s_14" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT functest_s_14()" +== 095 +-- truncate_limit: 100 +DROP TABLE functest3 CASCADE +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE functest3 CASCADE" +== 096 +-- truncate_limit: 100 +-- information_schema tests + +CREATE FUNCTION functest_IS_1(a int, b int default 1, c text default 'foo') + RETURNS int + LANGUAGE SQL + AS 'SELECT $1 + $2' +-- +FUNCTION: name="functest_is_1" function="functest_is_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_1(a int, b int = 1, c text = 'foo') RETURNS int LANGUAGE sql AS $$SEL..." +== 097 +-- truncate_limit: 100 +CREATE FUNCTION functest_IS_2(out a int, b int default 1) + RETURNS int + LANGUAGE SQL + AS 'SELECT $1' +-- +FUNCTION: name="functest_is_2" function="functest_is_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_2(OUT a int, b int = 1) RETURNS int LANGUAGE sql AS $$SELECT $1$$" +== 098 +-- truncate_limit: 100 +CREATE FUNCTION functest_IS_3(a int default 1, out b int) + RETURNS int + LANGUAGE SQL + AS 'SELECT $1' +-- +FUNCTION: name="functest_is_3" function="functest_is_3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_3(a int = 1, OUT b int) RETURNS int LANGUAGE sql AS $$SELECT $1$$" +== 099 +-- truncate_limit: 100 +SELECT routine_name, ordinal_position, parameter_name, parameter_default + FROM information_schema.parameters JOIN information_schema.routines USING (specific_schema, specific_name) + WHERE routine_schema = 'temp_func_test' AND routine_name ~ '^functest_is_' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.parameters" schema="information_schema" table="parameters" ctx=Select +TABLE: name="information_schema.routines" schema="information_schema" table="routines" ctx=Select +FILTER: schema="" table="" column="routine_schema" +FILTER: schema="" table="" column="routine_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.parameters JOIN information_schema.routines USING (specific_sc..." +== 100 +-- truncate_limit: 100 +DROP FUNCTION functest_IS_1(int, int, text), functest_IS_2(int), functest_IS_3(int) +-- +FUNCTION: name="functest_is_1" function="functest_is_1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION functest_is_1(int, int, text), functest_is_2(int), functest_is_3(int)" +== 101 +-- truncate_limit: 100 +-- routine usage views + +CREATE FUNCTION functest_IS_4a() RETURNS int LANGUAGE SQL AS 'SELECT 1' +-- +FUNCTION: name="functest_is_4a" function="functest_is_4a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_4a() RETURNS int LANGUAGE sql AS $$SELECT 1$$" +== 102 +-- truncate_limit: 100 +CREATE FUNCTION functest_IS_4b(x int DEFAULT functest_IS_4a()) RETURNS int LANGUAGE SQL AS 'SELECT x' +-- +FUNCTION: name="functest_is_4b" function="functest_is_4b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_4b(x int = functest_is_4a()) RETURNS int LANGUAGE sql AS $$SELECT x$$" +== 103 +-- truncate_limit: 100 +CREATE SEQUENCE functest1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE functest1" +== 104 +-- truncate_limit: 100 +CREATE FUNCTION functest_IS_5(x int DEFAULT nextval('functest1')) + RETURNS int + LANGUAGE SQL + AS 'SELECT x' +-- +FUNCTION: name="functest_is_5" function="functest_is_5" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_5(x int = nextval('functest1')) RETURNS int LANGUAGE sql AS $$SELECT x$$" +== 105 +-- truncate_limit: 100 +CREATE FUNCTION functest_IS_6() + RETURNS int + LANGUAGE SQL + RETURN nextval('functest1') +-- +FUNCTION: name="functest_is_6" function="functest_is_6" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_6() RETURNS int LANGUAGE sql RETURN nextval('functest1')" +== 106 +-- truncate_limit: 100 +CREATE TABLE functest2 (a int, b int) +-- +TABLE: name="functest2" schema="" table="functest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE functest2 (a int, b int)" +== 107 +-- truncate_limit: 100 +CREATE FUNCTION functest_IS_7() + RETURNS int + LANGUAGE SQL + RETURN (SELECT count(a) FROM functest2) +-- +FUNCTION: name="functest_is_7" function="functest_is_7" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_is_7() RETURNS int LANGUAGE sql RETURN (SELECT count(a) FROM functest2)" +== 108 +-- truncate_limit: 100 +SELECT r0.routine_name, r1.routine_name + FROM information_schema.routine_routine_usage rru + JOIN information_schema.routines r0 ON r0.specific_name = rru.specific_name + JOIN information_schema.routines r1 ON r1.specific_name = rru.routine_name + WHERE r0.routine_schema = 'temp_func_test' AND + r1.routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_routine_usage" schema="information_schema" table="routine_routine_usage" ctx=Select +TABLE: name="information_schema.routines" schema="information_schema" table="routines" ctx=Select +TABLE: name="information_schema.routines" schema="information_schema" table="routines" ctx=Select +ALIAS: "r0"="information_schema.routines" +ALIAS: "r1"="information_schema.routines" +ALIAS: "rru"="information_schema.routine_routine_usage" +FILTER: schema="" table="r0" column="routine_schema" +FILTER: schema="" table="r1" column="routine_schema" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.routine_routine_usage rru JOIN information_schema.routines r0 ..." +== 109 +-- truncate_limit: 100 +SELECT routine_name, sequence_name FROM information_schema.routine_sequence_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_sequence_usage" schema="information_schema" table="routine_sequence_usage" ctx=Select +FILTER: schema="" table="" column="routine_schema" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.routine_sequence_usage WHERE ... ORDER BY 1, 2" +== 110 +-- truncate_limit: 100 +SELECT routine_name, table_name, column_name FROM information_schema.routine_column_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_column_usage" schema="information_schema" table="routine_column_usage" ctx=Select +FILTER: schema="" table="" column="routine_schema" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.routine_column_usage WHERE ... ORDER BY 1, 2" +== 111 +-- truncate_limit: 100 +SELECT routine_name, table_name FROM information_schema.routine_table_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2 +-- +TABLE: name="information_schema.routine_table_usage" schema="information_schema" table="routine_table_usage" ctx=Select +FILTER: schema="" table="" column="routine_schema" +STMT: SelectStmt +TRUNCATED: "SELECT routine_name, table_name FROM information_schema.routine_table_usage WHERE ... ORDER BY 1, 2" +== 112 +-- truncate_limit: 100 +DROP FUNCTION functest_IS_4a CASCADE +-- +FUNCTION: name="functest_is_4a" function="functest_is_4a" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION functest_is_4a CASCADE" +== 113 +-- truncate_limit: 100 +DROP SEQUENCE functest1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE functest1 CASCADE" +== 114 +-- truncate_limit: 100 +DROP TABLE functest2 CASCADE +-- +TABLE: name="functest2" schema="" table="functest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE functest2 CASCADE" +== 115 +-- truncate_limit: 100 +-- overload +CREATE FUNCTION functest_B_2(bigint) RETURNS bool LANGUAGE 'sql' + IMMUTABLE AS 'SELECT $1 > 0' +-- +FUNCTION: name="functest_b_2" function="functest_b_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_b_2(bigint) RETURNS bool LANGUAGE sql IMMUTABLE AS $$SELECT $1 > 0$$" +== 116 +-- truncate_limit: 100 +DROP FUNCTION functest_b_1 +-- +FUNCTION: name="functest_b_1" function="functest_b_1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION functest_b_1" +== 117 +-- truncate_limit: 100 +DROP FUNCTION functest_b_1 +-- +FUNCTION: name="functest_b_1" function="functest_b_1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION functest_b_1" +== 118 +-- truncate_limit: 100 +-- error, not found +DROP FUNCTION functest_b_2 +-- +FUNCTION: name="functest_b_2" function="functest_b_2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION functest_b_2" +== 119 +-- truncate_limit: 100 +-- error, ambiguous + + +-- CREATE OR REPLACE tests + +CREATE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL AS 'SELECT $1' +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest1(a int) RETURNS int LANGUAGE sql AS $$SELECT $1$$" +== 120 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL WINDOW AS 'SELECT $1' +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION functest1(a int) RETURNS int LANGUAGE sql WINDOW AS $$SELECT $1$$" +== 121 +-- truncate_limit: 100 +CREATE OR REPLACE PROCEDURE functest1(a int) LANGUAGE SQL AS 'SELECT $1' +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE PROCEDURE functest1(a int) LANGUAGE sql AS $$SELECT $1$$" +== 122 +-- truncate_limit: 100 +DROP FUNCTION functest1(a int) +-- +FUNCTION: name="functest1" function="functest1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION functest1(a int)" +== 123 +-- truncate_limit: 100 +-- inlining of set-returning functions + +CREATE TABLE functest3 (a int) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE functest3 (a int)" +== 124 +-- truncate_limit: 100 +INSERT INTO functest3 VALUES (1), (2), (3) +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO functest3 VALUES (1), (2), (3)" +== 125 +-- truncate_limit: 100 +CREATE FUNCTION functest_sri1() RETURNS SETOF int +LANGUAGE SQL +STABLE +AS ' + SELECT * FROM functest3; +' +-- +FUNCTION: name="functest_sri1" function="functest_sri1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION functest_sri1() RETURNS SETOF int LANGUAGE sql STABLE AS $$\n SELECT * FROM fun..." +== 126 +-- truncate_limit: 100 +SELECT * FROM functest_sri1() +-- +FUNCTION: name="functest_sri1" function="functest_sri1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM functest_sri1()" +== 127 +-- truncate_limit: 100 +EXPLAIN (verbose, costs off) SELECT * FROM functest_sri1() +-- +FUNCTION: name="functest_sri1" function="functest_sri1" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM functest_sri1()" +== 128 +-- truncate_limit: 100 +CREATE FUNCTION functest_sri2() RETURNS SETOF int +LANGUAGE SQL +STABLE +BEGIN ATOMIC + SELECT * FROM functest3 +-- +ERROR: syntax error at end of input +CURSORPOS: 111 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 129 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 130 +-- truncate_limit: 100 +SELECT * FROM functest_sri2() +-- +FUNCTION: name="functest_sri2" function="functest_sri2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM functest_sri2()" +== 131 +-- truncate_limit: 100 +EXPLAIN (verbose, costs off) SELECT * FROM functest_sri2() +-- +FUNCTION: name="functest_sri2" function="functest_sri2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM functest_sri2()" +== 132 +-- truncate_limit: 100 +DROP TABLE functest3 CASCADE +-- +TABLE: name="functest3" schema="" table="functest3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE functest3 CASCADE" +== 133 +-- truncate_limit: 100 +-- Check behavior of VOID-returning SQL functions + +CREATE FUNCTION voidtest1(a int) RETURNS VOID LANGUAGE SQL AS +$$ SELECT a + 1 $$ +-- +FUNCTION: name="voidtest1" function="voidtest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION voidtest1(a int) RETURNS void LANGUAGE sql AS $$ SELECT a + 1 $$" +== 134 +-- truncate_limit: 100 +SELECT voidtest1(42) +-- +FUNCTION: name="voidtest1" function="voidtest1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT voidtest1(42)" +== 135 +-- truncate_limit: 100 +CREATE FUNCTION voidtest2(a int, b int) RETURNS VOID LANGUAGE SQL AS +$$ SELECT voidtest1(a + b) $$ +-- +FUNCTION: name="voidtest2" function="voidtest2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION voidtest2(a int, b int) RETURNS void LANGUAGE sql AS $$ SELECT voidtest1(a + b) $$" +== 136 +-- truncate_limit: 100 +SELECT voidtest2(11,22) +-- +FUNCTION: name="voidtest2" function="voidtest2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT voidtest2(11, 22)" +== 137 +-- truncate_limit: 100 +-- currently, we can inline voidtest2 but not voidtest1 +EXPLAIN (verbose, costs off) SELECT voidtest2(11,22) +-- +FUNCTION: name="voidtest2" function="voidtest2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT voidtest2(11, 22)" +== 138 +-- truncate_limit: 100 +CREATE TEMP TABLE sometable(f1 int) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE sometable (f1 int)" +== 139 +-- truncate_limit: 100 +CREATE FUNCTION voidtest3(a int) RETURNS VOID LANGUAGE SQL AS +$$ INSERT INTO sometable VALUES(a + 1) $$ +-- +FUNCTION: name="voidtest3" function="voidtest3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION voidtest3(a int) RETURNS void LANGUAGE sql AS $$ INSERT INTO sometable VALUES(a +..." +== 140 +-- truncate_limit: 100 +SELECT voidtest3(17) +-- +FUNCTION: name="voidtest3" function="voidtest3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT voidtest3(17)" +== 141 +-- truncate_limit: 100 +CREATE FUNCTION voidtest4(a int) RETURNS VOID LANGUAGE SQL AS +$$ INSERT INTO sometable VALUES(a - 1) RETURNING f1 $$ +-- +FUNCTION: name="voidtest4" function="voidtest4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION voidtest4(a int) RETURNS void LANGUAGE sql AS $$ INSERT INTO sometable VALUES(a -..." +== 142 +-- truncate_limit: 100 +SELECT voidtest4(39) +-- +FUNCTION: name="voidtest4" function="voidtest4" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT voidtest4(39)" +== 143 +-- truncate_limit: 100 +TABLE sometable +-- +TABLE: name="sometable" schema="" table="sometable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sometable" +== 144 +-- truncate_limit: 100 +CREATE FUNCTION voidtest5(a int) RETURNS SETOF VOID LANGUAGE SQL AS +$$ SELECT generate_series(1, a) $$ STABLE +-- +FUNCTION: name="voidtest5" function="voidtest5" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION voidtest5(a int) RETURNS SETOF void LANGUAGE sql AS $$ SELECT generate_series(1, ..." +== 145 +-- truncate_limit: 100 +SELECT * FROM voidtest5(3) +-- +FUNCTION: name="voidtest5" function="voidtest5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM voidtest5(3)" +== 146 +-- truncate_limit: 100 +-- Regression tests for bugs: + +-- Check that arguments that are R/W expanded datums aren't corrupted by +-- multiple uses. This test knows that array_append() returns a R/W datum +-- and will modify a R/W array input in-place. We use SETOF to prevent +-- inlining of the SQL function. +CREATE FUNCTION double_append(anyarray, anyelement) RETURNS SETOF anyarray +LANGUAGE SQL IMMUTABLE AS +$$ SELECT array_append($1, $2) || array_append($1, $2) $$ +-- +FUNCTION: name="double_append" function="double_append" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION double_append(anyarray, anyelement) RETURNS SETOF anyarray LANGUAGE sql IMMUTABLE..." +== 147 +-- truncate_limit: 100 +SELECT double_append(array_append(ARRAY[q1], q2), q3) + FROM (VALUES(1,2,3), (4,5,6)) v(q1,q2,q3) +-- +FUNCTION: name="double_append" function="double_append" schema="" ctx=Call +FUNCTION: name="array_append" function="array_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT double_append(array_append(ARRAY[q1], q2), q3) FROM (VALUES (...)) v(q1, q2, q3)" +== 148 +-- truncate_limit: 100 +-- Things that shouldn't work: + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT ''not an integer'';' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test1(int) RETURNS int LANGUAGE sql AS $$SELECT 'not an integer';$$" +== 149 +-- truncate_limit: 100 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'not even SQL' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test1(int) RETURNS int LANGUAGE sql AS $$not even SQL$$" +== 150 +-- truncate_limit: 100 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT 1, 2, 3;' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test1(int) RETURNS int LANGUAGE sql AS $$SELECT 1, 2, 3;$$" +== 151 +-- truncate_limit: 100 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT $2;' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test1(int) RETURNS int LANGUAGE sql AS $$SELECT $2;$$" +== 152 +-- truncate_limit: 100 +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'a', 'b' +-- +FUNCTION: name="test1" function="test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test1(int) RETURNS int LANGUAGE sql AS $$a$$, $$b$$" +== 153 +-- truncate_limit: 100 +-- Cleanup +DROP SCHEMA temp_func_test CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA temp_func_test CASCADE" +== 154 +-- truncate_limit: 100 +DROP USER regress_unpriv_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_unpriv_user" +== 155 +-- truncate_limit: 100 +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json new file mode 100644 index 0000000..528c575 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json @@ -0,0 +1,615 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_index.test b/parser/testdata/summary_truncate/postgres_regress/create_index.test new file mode 100644 index 0000000..c19843a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_index.test @@ -0,0 +1,5129 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_INDEX +-- Create ancillary data structures (i.e. indices) +|-- + +-- directory paths are passed to us in environment variables + +|-- +-- BTREE +|-- +CREATE INDEX onek_unique1 ON onek USING btree(unique1 int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX onek_unique1 ON onek USING btree (unique1 int4_ops)" +== 002 +-- truncate_limit: 100 +CREATE INDEX IF NOT EXISTS onek_unique1 ON onek USING btree(unique1 int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX IF NOT EXISTS onek_unique1 ON onek USING btree (unique1 int4_ops)" +== 003 +-- truncate_limit: 100 +CREATE INDEX IF NOT EXISTS ON onek USING btree(unique1 int4_ops) +-- +ERROR: syntax error at or near "ON" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +CREATE INDEX onek_unique2 ON onek USING btree(unique2 int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX onek_unique2 ON onek USING btree (unique2 int4_ops)" +== 005 +-- truncate_limit: 100 +CREATE INDEX onek_hundred ON onek USING btree(hundred int4_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX onek_hundred ON onek USING btree (hundred int4_ops)" +== 006 +-- truncate_limit: 100 +CREATE INDEX onek_stringu1 ON onek USING btree(stringu1 name_ops) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX onek_stringu1 ON onek USING btree (stringu1 name_ops)" +== 007 +-- truncate_limit: 100 +CREATE INDEX tenk1_unique1 ON tenk1 USING btree(unique1 int4_ops) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenk1_unique1 ON tenk1 USING btree (unique1 int4_ops)" +== 008 +-- truncate_limit: 100 +CREATE INDEX tenk1_unique2 ON tenk1 USING btree(unique2 int4_ops) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenk1_unique2 ON tenk1 USING btree (unique2 int4_ops)" +== 009 +-- truncate_limit: 100 +CREATE INDEX tenk1_hundred ON tenk1 USING btree(hundred int4_ops) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenk1_hundred ON tenk1 USING btree (hundred int4_ops)" +== 010 +-- truncate_limit: 100 +CREATE INDEX tenk1_thous_tenthous ON tenk1 (thousand, tenthous) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenk1_thous_tenthous ON tenk1 USING btree (thousand, tenthous)" +== 011 +-- truncate_limit: 100 +CREATE INDEX tenk2_unique1 ON tenk2 USING btree(unique1 int4_ops) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenk2_unique1 ON tenk2 USING btree (unique1 int4_ops)" +== 012 +-- truncate_limit: 100 +CREATE INDEX tenk2_unique2 ON tenk2 USING btree(unique2 int4_ops) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenk2_unique2 ON tenk2 USING btree (unique2 int4_ops)" +== 013 +-- truncate_limit: 100 +CREATE INDEX tenk2_hundred ON tenk2 USING btree(hundred int4_ops) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenk2_hundred ON tenk2 USING btree (hundred int4_ops)" +== 014 +-- truncate_limit: 100 +CREATE INDEX rix ON road USING btree (name text_ops) +-- +TABLE: name="road" schema="" table="road" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX rix ON road USING btree (name text_ops)" +== 015 +-- truncate_limit: 100 +CREATE INDEX iix ON ihighway USING btree (name text_ops) +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iix ON ihighway USING btree (name text_ops)" +== 016 +-- truncate_limit: 100 +CREATE INDEX six ON shighway USING btree (name text_ops) +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX six ON shighway USING btree (name text_ops)" +== 017 +-- truncate_limit: 100 +-- test comments +COMMENT ON INDEX six_wrong IS 'bad index' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX six_wrong IS 'bad index'" +== 018 +-- truncate_limit: 100 +COMMENT ON INDEX six IS 'good index' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX six IS 'good index'" +== 019 +-- truncate_limit: 100 +COMMENT ON INDEX six IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX six IS NULL" +== 020 +-- truncate_limit: 100 +|-- +-- BTREE partial indices +|-- +CREATE INDEX onek2_u1_prtl ON onek2 USING btree(unique1 int4_ops) + where unique1 < 20 or unique1 > 980 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX onek2_u1_prtl ON onek2 USING btree (unique1 int4_ops) WHERE ..." +== 021 +-- truncate_limit: 100 +CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops) + where stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX onek2_u2_prtl ON onek2 USING btree (unique2 int4_ops) WHERE stringu1 < 'B'" +== 022 +-- truncate_limit: 100 +CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops) + where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX onek2_stu1_prtl ON onek2 USING btree (stringu1 name_ops) WHERE ..." +== 023 +-- truncate_limit: 100 +|-- +-- GiST (rtree-equivalent opclasses only) +|-- + +CREATE TABLE slow_emp4000 ( + home_base box +) +-- +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE slow_emp4000 (home_base box)" +== 024 +-- truncate_limit: 100 +CREATE TABLE fast_emp4000 ( + home_base box +) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fast_emp4000 (home_base box)" +== 025 +-- truncate_limit: 100 +COPY slow_emp4000 FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +-- truncate_limit: 100 +INSERT INTO fast_emp4000 SELECT * FROM slow_emp4000 +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DML +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fast_emp4000 SELECT * FROM slow_emp4000" +== 027 +-- truncate_limit: 100 +ANALYZE slow_emp4000 +-- +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE slow_emp4000" +== 028 +-- truncate_limit: 100 +ANALYZE fast_emp4000 +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE fast_emp4000" +== 029 +-- truncate_limit: 100 +CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base) +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base)" +== 030 +-- truncate_limit: 100 +-- we want to work with a point_tbl that includes a null +CREATE TEMP TABLE point_tbl AS SELECT * FROM public.point_tbl +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +TABLE: name="public.point_tbl" schema="public" table="point_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE point_tbl AS SELECT * FROM public.point_tbl" +== 031 +-- truncate_limit: 100 +INSERT INTO POINT_TBL(f1) VALUES (NULL) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES (NULL)" +== 032 +-- truncate_limit: 100 +CREATE INDEX gpointind ON point_tbl USING gist (f1) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gpointind ON point_tbl USING gist (f1)" +== 033 +-- truncate_limit: 100 +CREATE TEMP TABLE gpolygon_tbl AS + SELECT polygon(home_base) AS f1 FROM slow_emp4000 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DDL +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE gpolygon_tbl AS SELECT polygon(home_base) AS f1 FROM slow_emp4000" +== 034 +-- truncate_limit: 100 +INSERT INTO gpolygon_tbl VALUES ( '(1000,0,0,1000)' ) +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gpolygon_tbl VALUES ('(1000,0,0,1000)')" +== 035 +-- truncate_limit: 100 +INSERT INTO gpolygon_tbl VALUES ( '(0,1000,1000,1000)' ) +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gpolygon_tbl VALUES ('(0,1000,1000,1000)')" +== 036 +-- truncate_limit: 100 +CREATE TEMP TABLE gcircle_tbl AS + SELECT circle(home_base) AS f1 FROM slow_emp4000 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=DDL +TABLE: name="slow_emp4000" schema="" table="slow_emp4000" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE gcircle_tbl AS SELECT circle(home_base) AS f1 FROM slow_emp4000" +== 037 +-- truncate_limit: 100 +CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1) +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1)" +== 038 +-- truncate_limit: 100 +CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1) +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1)" +== 039 +-- truncate_limit: 100 +|-- +-- Test GiST indexes +|-- + +-- get non-indexed results for comparison purposes + +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 040 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 041 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 042 +-- truncate_limit: 100 +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fast_emp4000 WHERE ... ORDER BY (home_base[0])[0]" +== 043 +-- truncate_limit: 100 +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box" +== 044 +-- truncate_limit: 100 +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL" +== 045 +-- truncate_limit: 100 +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon" +== 046 +-- truncate_limit: 100 +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle" +== 047 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE f1 <@ '(0,0,100,100)'::box" +== 048 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE '(0,0,100,100)'::box @> f1" +== 049 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE f1 <@ '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)'::polygon" +== 050 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE f1 <@ '<(50,50),50>'::circle" +== 051 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'" +== 052 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'" +== 053 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)'" +== 054 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)'" +== 055 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'" +== 056 +-- truncate_limit: 100 +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'" +== 057 +-- truncate_limit: 100 +SELECT * FROM point_tbl WHERE f1 IS NULL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl WHERE f1 IS NULL" +== 058 +-- truncate_limit: 100 +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'" +== 059 +-- truncate_limit: 100 +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)'::box ORDER BY f1 <-> '0,1'" +== 060 +-- truncate_limit: 100 +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10" +== 061 +-- truncate_limit: 100 +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="circle_center" function="circle_center" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10" +== 062 +-- truncate_limit: 100 +-- Now check the results from plain indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 063 +-- truncate_limit: 100 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 064 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 065 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM fast_emp4000 WHERE home_base <@ '(200,200),(2000,1000)'::box OR..." +== 066 +-- truncate_limit: 100 +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0] +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fast_emp4000 WHERE ... ORDER BY (home_base[0])[0]" +== 067 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box" +== 068 +-- truncate_limit: 100 +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box" +== 069 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL" +== 070 +-- truncate_limit: 100 +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL +-- +TABLE: name="fast_emp4000" schema="" table="fast_emp4000" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="home_base" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL" +== 071 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon" +== 072 +-- truncate_limit: 100 +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon" +== 073 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle" +== 074 +-- truncate_limit: 100 +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle" +== 075 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl WHERE f1 <@ '(0,0,100,100)'::box" +== 076 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE f1 <@ '(0,0,100,100)'::box" +== 077 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl WHERE '(0,0,100,100)'::box @> f1" +== 078 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE '(0,0,100,100)'::box @> f1" +== 079 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl WHERE f1 <@ '(0,0),(0,100),(100,100),(50,50),(..." +== 080 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE f1 <@ '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)'::polygon" +== 081 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl WHERE f1 <@ '<(50,50),50>'::circle" +== 082 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl WHERE f1 <@ '<(50,50),50>'::circle" +== 083 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'" +== 084 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'" +== 085 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'" +== 086 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'" +== 087 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)'" +== 088 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)'" +== 089 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)'" +== 090 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)'" +== 091 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'" +== 092 +-- truncate_limit: 100 +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'" +== 093 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'" +== 094 +-- truncate_limit: 100 +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'" +== 095 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 IS NULL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 IS NULL" +== 096 +-- truncate_limit: 100 +SELECT * FROM point_tbl WHERE f1 IS NULL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl WHERE f1 IS NULL" +== 097 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'" +== 098 +-- truncate_limit: 100 +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'" +== 099 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)'::box ORDER BY f1 <-> ..." +== 100 +-- truncate_limit: 100 +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)'::box ORDER BY f1 <-> '0,1'" +== 101 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10" +== 102 +-- truncate_limit: 100 +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10 +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10" +== 103 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="circle_center" function="circle_center" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT circle_center(f1), round(radius(f1)) AS radius FROM gcircle_tbl ORDER ..." +== 104 +-- truncate_limit: 100 +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10 +-- +TABLE: name="gcircle_tbl" schema="" table="gcircle_tbl" ctx=Select +FUNCTION: name="circle_center" function="circle_center" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="radius" function="radius" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10" +== 105 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT point(x, x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x, x) ..." +== 106 +-- truncate_limit: 100 +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x +-- +TABLE: name="gpolygon_tbl" schema="" table="gpolygon_tbl" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(0, 10, 1) x" +== 107 +-- truncate_limit: 100 +-- Now check the results from bitmap indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 108 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 109 +-- truncate_limit: 100 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 110 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)'::box ORDER BY f1 <-> ..." +== 111 +-- truncate_limit: 100 +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)'::box ORDER BY f1 <-> '0,1'" +== 112 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 113 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 114 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 115 +-- truncate_limit: 100 +|-- +-- GIN over int[] and text[] +|-- +-- Note: GIN currently supports only bitmap scans, not plain indexscans +|-- + +CREATE TABLE array_index_op_test ( + seqno int4, + i int4[], + t text[] +) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE array_index_op_test (seqno int4, i int4[], t text[])" +== 116 +-- truncate_limit: 100 +COPY array_index_op_test FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 31 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 117 +-- truncate_limit: 100 +ANALYZE array_index_op_test +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE array_index_op_test" +== 118 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i = '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i = '{NULL}' ORDER BY seqno" +== 119 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i @> '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i @> '{NULL}' ORDER BY seqno" +== 120 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i && '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i && '{NULL}' ORDER BY seqno" +== 121 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i <@ '{NULL}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i <@ '{NULL}' ORDER BY seqno" +== 122 +-- truncate_limit: 100 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 123 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 124 +-- truncate_limit: 100 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 125 +-- truncate_limit: 100 +CREATE INDEX intarrayidx ON array_index_op_test USING gin (i) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX intarrayidx ON array_index_op_test USING gin (i)" +== 126 +-- truncate_limit: 100 +explain (costs off) +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno" +== 127 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno" +== 128 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno" +== 129 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i @> '{17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i @> '{17}' ORDER BY seqno" +== 130 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i && '{17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i && '{17}' ORDER BY seqno" +== 131 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i @> '{32,17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i @> '{32,17}' ORDER BY seqno" +== 132 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i && '{32,17}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i && '{32,17}' ORDER BY seqno" +== 133 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno" +== 134 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i = '{47,77}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i = '{47,77}' ORDER BY seqno" +== 135 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i = '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i = '{}' ORDER BY seqno" +== 136 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i @> '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i @> '{}' ORDER BY seqno" +== 137 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i && '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i && '{}' ORDER BY seqno" +== 138 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i <@ '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i <@ '{}' ORDER BY seqno" +== 139 +-- truncate_limit: 100 +CREATE INDEX textarrayidx ON array_index_op_test USING gin (t) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX textarrayidx ON array_index_op_test USING gin (t)" +== 140 +-- truncate_limit: 100 +explain (costs off) +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno" +== 141 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno" +== 142 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno" +== 143 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno" +== 144 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno" +== 145 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno" +== 146 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno" +== 147 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE ... ORDER BY seqno" +== 148 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t = '{AAAAAAAAAA646,A87088}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t = '{AAAAAAAAAA646,A87088}' ORDER BY seqno" +== 149 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno" +== 150 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t @> '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t @> '{}' ORDER BY seqno" +== 151 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t && '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t && '{}' ORDER BY seqno" +== 152 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t <@ '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t <@ '{}' ORDER BY seqno" +== 153 +-- truncate_limit: 100 +-- And try it with a multicolumn GIN index + +DROP INDEX intarrayidx, textarrayidx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX intarrayidx, textarrayidx" +== 154 +-- truncate_limit: 100 +CREATE INDEX botharrayidx ON array_index_op_test USING gin (i, t) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX botharrayidx ON array_index_op_test USING gin (i, t)" +== 155 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno" +== 156 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno" +== 157 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAA80240}' ORDER BY seqno" +== 158 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t && '{AAAAAAA80240}' ORDER BY seqno" +== 159 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i @> '{32}' AND t && '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i @> '{32}' AND t && '{AAAAAAA80240}' ORDER BY seqno" +== 160 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE i && '{32}' AND t @> '{AAAAAAA80240}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE i && '{32}' AND t @> '{AAAAAAA80240}' ORDER BY seqno" +== 161 +-- truncate_limit: 100 +SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=Select +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno" +== 162 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 163 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 164 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 165 +-- truncate_limit: 100 +|-- +-- 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[]) +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE array_gin_test (a int[])" +== 166 +-- truncate_limit: 100 +INSERT INTO array_gin_test SELECT ARRAY[1, g%5, g] FROM generate_series(1, 10000) g +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO array_gin_test SELECT ARRAY[1, g % 5, g] FROM generate_series(1, 10000) g" +== 167 +-- truncate_limit: 100 +CREATE INDEX array_gin_test_idx ON array_gin_test USING gin (a) +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX array_gin_test_idx ON array_gin_test USING gin (a)" +== 168 +-- truncate_limit: 100 +SELECT COUNT(*) FROM array_gin_test WHERE a @> '{2}' +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM array_gin_test WHERE a @> '{2}'" +== 169 +-- truncate_limit: 100 +DROP TABLE array_gin_test +-- +TABLE: name="array_gin_test" schema="" table="array_gin_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE array_gin_test" +== 170 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="array_index_op_test" schema="" table="array_index_op_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gin_relopts_test ON array_index_op_test USING gin (i) WITH (fastupdate=on, gin_pendi..." +== 171 +-- truncate_limit: 100 +|-- +-- HASH +|-- +CREATE UNLOGGED TABLE unlogged_hash_table (id int4) +-- +TABLE: name="unlogged_hash_table" schema="" table="unlogged_hash_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE unlogged_hash_table (id int4)" +== 172 +-- truncate_limit: 100 +CREATE INDEX unlogged_hash_index ON unlogged_hash_table USING hash (id int4_ops) +-- +TABLE: name="unlogged_hash_table" schema="" table="unlogged_hash_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX unlogged_hash_index ON unlogged_hash_table USING hash (id int4_ops)" +== 173 +-- truncate_limit: 100 +DROP TABLE unlogged_hash_table +-- +TABLE: name="unlogged_hash_table" schema="" table="unlogged_hash_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unlogged_hash_table" +== 174 +-- truncate_limit: 100 +-- 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' +-- +STMT: VariableSetStmt +TRUNCATED: "SET maintenance_work_mem TO \"1MB\"" +== 175 +-- truncate_limit: 100 +CREATE INDEX hash_tuplesort_idx ON tenk1 USING hash (stringu1 name_ops) WITH (fillfactor = 10) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_tuplesort_idx ON tenk1 USING hash (stringu1 name_ops) WITH (fillfactor=10)" +== 176 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'" +== 177 +-- truncate_limit: 100 +SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'" +== 178 +-- truncate_limit: 100 +DROP INDEX hash_tuplesort_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX hash_tuplesort_idx" +== 179 +-- truncate_limit: 100 +RESET maintenance_work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET maintenance_work_mem" +== 180 +-- truncate_limit: 100 +|-- +-- Test unique null behavior +|-- +CREATE TABLE unique_tbl (i int, t text) +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unique_tbl (i int, t text)" +== 181 +-- truncate_limit: 100 +CREATE UNIQUE INDEX unique_idx1 ON unique_tbl (i) NULLS DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX unique_idx1 ON unique_tbl USING btree (i)" +== 182 +-- truncate_limit: 100 +CREATE UNIQUE INDEX unique_idx2 ON unique_tbl (i) NULLS NOT DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX unique_idx2 ON unique_tbl USING btree (i) NULLS NOT DISTINCT" +== 183 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (1, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (1, 'one')" +== 184 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (2, 'two') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (2, 'two')" +== 185 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (3, 'three') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (3, 'three')" +== 186 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (4, 'four') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (4, 'four')" +== 187 +-- truncate_limit: 100 +INSERT INTO unique_tbl VALUES (5, 'one') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl VALUES (5, 'one')" +== 188 +-- truncate_limit: 100 +INSERT INTO unique_tbl (t) VALUES ('six') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('six')" +== 189 +-- truncate_limit: 100 +INSERT INTO unique_tbl (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('seven')" +== 190 +-- truncate_limit: 100 +-- error from unique_idx2 + +DROP INDEX unique_idx1, unique_idx2 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX unique_idx1, unique_idx2" +== 191 +-- truncate_limit: 100 +INSERT INTO unique_tbl (t) VALUES ('seven') +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unique_tbl (t) VALUES ('seven')" +== 192 +-- truncate_limit: 100 +-- build indexes on filled table +CREATE UNIQUE INDEX unique_idx3 ON unique_tbl (i) NULLS DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX unique_idx3 ON unique_tbl USING btree (i)" +== 193 +-- truncate_limit: 100 +-- ok +CREATE UNIQUE INDEX unique_idx4 ON unique_tbl (i) NULLS NOT DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX unique_idx4 ON unique_tbl USING btree (i) NULLS NOT DISTINCT" +== 194 +-- truncate_limit: 100 +-- error + +DELETE FROM unique_tbl WHERE t = 'seven' +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM unique_tbl WHERE t = 'seven'" +== 195 +-- truncate_limit: 100 +CREATE UNIQUE INDEX unique_idx4 ON unique_tbl (i) NULLS NOT DISTINCT +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX unique_idx4 ON unique_tbl USING btree (i) NULLS NOT DISTINCT" +== 196 +-- truncate_limit: 100 +-- ok now + +SELECT pg_get_indexdef('unique_idx3'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('unique_idx3'::regclass)" +== 197 +-- truncate_limit: 100 +SELECT pg_get_indexdef('unique_idx4'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('unique_idx4'::regclass)" +== 198 +-- truncate_limit: 100 +DROP TABLE unique_tbl +-- +TABLE: name="unique_tbl" schema="" table="unique_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unique_tbl" +== 199 +-- truncate_limit: 100 +|-- +-- Test functional index +|-- +CREATE TABLE func_index_heap (f1 text, f2 text) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE func_index_heap (f1 text, f2 text)" +== 200 +-- truncate_limit: 100 +CREATE UNIQUE INDEX func_index_index on func_index_heap (textcat(f1,f2)) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +FUNCTION: name="textcat" function="textcat" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX func_index_index ON func_index_heap USING btree (textcat(f1, f2))" +== 201 +-- truncate_limit: 100 +INSERT INTO func_index_heap VALUES('ABC','DEF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('ABC', 'DEF')" +== 202 +-- truncate_limit: 100 +INSERT INTO func_index_heap VALUES('AB','CDEFG') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('AB', 'CDEFG')" +== 203 +-- truncate_limit: 100 +INSERT INTO func_index_heap VALUES('QWE','RTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('QWE', 'RTY')" +== 204 +-- truncate_limit: 100 +-- this should fail because of unique index: +INSERT INTO func_index_heap VALUES('ABCD', 'EF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('ABCD', 'EF')" +== 205 +-- truncate_limit: 100 +-- but this shouldn't: +INSERT INTO func_index_heap VALUES('QWERTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('QWERTY')" +== 206 +-- truncate_limit: 100 +-- while we're here, see that the metadata looks sane + + +|-- +-- Same test, expressional index +|-- +DROP TABLE func_index_heap +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE func_index_heap" +== 207 +-- truncate_limit: 100 +CREATE TABLE func_index_heap (f1 text, f2 text) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE func_index_heap (f1 text, f2 text)" +== 208 +-- truncate_limit: 100 +CREATE UNIQUE INDEX func_index_index on func_index_heap ((f1 || f2) text_ops) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX func_index_index ON func_index_heap USING btree ((f1 || f2) text_ops)" +== 209 +-- truncate_limit: 100 +INSERT INTO func_index_heap VALUES('ABC','DEF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('ABC', 'DEF')" +== 210 +-- truncate_limit: 100 +INSERT INTO func_index_heap VALUES('AB','CDEFG') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('AB', 'CDEFG')" +== 211 +-- truncate_limit: 100 +INSERT INTO func_index_heap VALUES('QWE','RTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('QWE', 'RTY')" +== 212 +-- truncate_limit: 100 +-- this should fail because of unique index: +INSERT INTO func_index_heap VALUES('ABCD', 'EF') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('ABCD', 'EF')" +== 213 +-- truncate_limit: 100 +-- but this shouldn't: +INSERT INTO func_index_heap VALUES('QWERTY') +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO func_index_heap VALUES ('QWERTY')" +== 214 +-- truncate_limit: 100 +-- while we're here, see that the metadata looks sane + +-- this should fail because of unsafe column type (anonymous record) +create index on func_index_heap ((f1 || f2), (row(f1, f2))) +-- +TABLE: name="func_index_heap" schema="" table="func_index_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON func_index_heap USING btree ((f1 || f2), (ROW(f1, f2)))" +== 215 +-- truncate_limit: 100 +|-- +-- Test unique index with included columns +|-- +CREATE TABLE covering_index_heap (f1 int, f2 int, f3 text) +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE covering_index_heap (f1 int, f2 int, f3 text)" +== 216 +-- truncate_limit: 100 +CREATE UNIQUE INDEX covering_index_index on covering_index_heap (f1,f2) INCLUDE(f3) +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX covering_index_index ON covering_index_heap USING btree (f1, f2) INCLUDE (f3)" +== 217 +-- truncate_limit: 100 +INSERT INTO covering_index_heap VALUES(1,1,'AAA') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covering_index_heap VALUES (1, 1, 'AAA')" +== 218 +-- truncate_limit: 100 +INSERT INTO covering_index_heap VALUES(1,2,'AAA') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covering_index_heap VALUES (1, 2, 'AAA')" +== 219 +-- truncate_limit: 100 +-- this should fail because of unique index on f1,f2: +INSERT INTO covering_index_heap VALUES(1,2,'BBB') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covering_index_heap VALUES (1, 2, 'BBB')" +== 220 +-- truncate_limit: 100 +-- and this shouldn't: +INSERT INTO covering_index_heap VALUES(1,4,'AAA') +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covering_index_heap VALUES (1, 4, 'AAA')" +== 221 +-- truncate_limit: 100 +-- Try to build index on table that already contains data +CREATE UNIQUE INDEX covering_pkey on covering_index_heap (f1,f2) INCLUDE(f3) +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX covering_pkey ON covering_index_heap USING btree (f1, f2) INCLUDE (f3)" +== 222 +-- truncate_limit: 100 +-- Try to use existing covering index as primary key +ALTER TABLE covering_index_heap ADD CONSTRAINT covering_pkey PRIMARY KEY USING INDEX +covering_pkey +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE covering_index_heap ADD CONSTRAINT covering_pkey PRIMARY KEY USING INDEX covering_pkey" +== 223 +-- truncate_limit: 100 +DROP TABLE covering_index_heap +-- +TABLE: name="covering_index_heap" schema="" table="covering_index_heap" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE covering_index_heap" +== 224 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_heap (f1 text, f2 text)" +== 225 +-- truncate_limit: 100 +-- empty table +CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap(f2,f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap USING btree (f2, f1)" +== 226 +-- truncate_limit: 100 +CREATE INDEX CONCURRENTLY IF NOT EXISTS concur_index1 ON concur_heap(f2,f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY IF NOT EXISTS concur_index1 ON concur_heap USING btree (f2, f1)" +== 227 +-- truncate_limit: 100 +INSERT INTO concur_heap VALUES ('a','b') +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_heap VALUES ('a', 'b')" +== 228 +-- truncate_limit: 100 +INSERT INTO concur_heap VALUES ('b','b') +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_heap VALUES ('b', 'b')" +== 229 +-- truncate_limit: 100 +-- unique index +CREATE UNIQUE INDEX CONCURRENTLY concur_index2 ON concur_heap(f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX CONCURRENTLY concur_index2 ON concur_heap USING btree (f1)" +== 230 +-- truncate_limit: 100 +CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS concur_index2 ON concur_heap(f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS concur_index2 ON concur_heap USING btree (f1)" +== 231 +-- truncate_limit: 100 +-- check if constraint is set up properly to be enforced +INSERT INTO concur_heap VALUES ('b','x') +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_heap VALUES ('b', 'x')" +== 232 +-- truncate_limit: 100 +-- check if constraint is enforced properly at build time +CREATE UNIQUE INDEX CONCURRENTLY concur_index3 ON concur_heap(f2) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX CONCURRENTLY concur_index3 ON concur_heap USING btree (f2)" +== 233 +-- truncate_limit: 100 +-- test that expression indexes and partial indexes work concurrently +CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a' +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_index4 ON concur_heap USING btree (f2) WHERE f1 = 'a'" +== 234 +-- truncate_limit: 100 +CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x' +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_index5 ON concur_heap USING btree (f2) WHERE f1 = 'x'" +== 235 +-- truncate_limit: 100 +-- here we also check that you can default the index name +CREATE INDEX CONCURRENTLY on concur_heap((f2||f1)) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY ON concur_heap USING btree ((f2 || f1))" +== 236 +-- truncate_limit: 100 +-- You can't do a concurrent index build in a transaction +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 237 +-- truncate_limit: 100 +CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap(f1) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap USING btree (f1)" +== 238 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 239 +-- truncate_limit: 100 +-- 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; $$ +-- +FUNCTION: name="predicate_stable" function="predicate_stable" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION predicate_stable() RETURNS bool IMMUTABLE LANGUAGE plpgsql AS $$\nBEGIN\n EXECUTE ..." +== 240 +-- truncate_limit: 100 +CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap (f1) + WHERE predicate_stable() +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +FUNCTION: name="predicate_stable" function="predicate_stable" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap USING btree (f1) WHERE predicate_stable()" +== 241 +-- truncate_limit: 100 +DROP INDEX concur_index8 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX concur_index8" +== 242 +-- truncate_limit: 100 +DROP FUNCTION predicate_stable() +-- +FUNCTION: name="predicate_stable" function="predicate_stable" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION predicate_stable()" +== 243 +-- truncate_limit: 100 +-- But you can do a regular index build in a transaction +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 244 +-- truncate_limit: 100 +CREATE INDEX std_index on concur_heap(f2) +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX std_index ON concur_heap USING btree (f2)" +== 245 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 246 +-- truncate_limit: 100 +-- Failed builds are left invalid by VACUUM FULL, fixed by REINDEX +VACUUM FULL concur_heap +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) concur_heap" +== 247 +-- truncate_limit: 100 +REINDEX TABLE concur_heap +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_heap" +== 248 +-- truncate_limit: 100 +DELETE FROM concur_heap WHERE f1 = 'b' +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM concur_heap WHERE f1 = 'b'" +== 249 +-- truncate_limit: 100 +VACUUM FULL concur_heap +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) concur_heap" +== 250 +-- truncate_limit: 100 +REINDEX TABLE concur_heap +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_heap" +== 251 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE concur_temp (f1 int, f2 text) ON COMMIT PRESERVE ROWS" +== 252 +-- truncate_limit: 100 +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar')" +== 253 +-- truncate_limit: 100 +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1) +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp USING btree (f1)" +== 254 +-- truncate_limit: 100 +DROP INDEX CONCURRENTLY concur_temp_ind +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_temp_ind" +== 255 +-- truncate_limit: 100 +DROP TABLE concur_temp +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_temp" +== 256 +-- truncate_limit: 100 +-- ON COMMIT DROP +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 257 +-- truncate_limit: 100 +CREATE TEMP TABLE concur_temp (f1 int, f2 text) + ON COMMIT DROP +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE concur_temp (f1 int, f2 text) ON COMMIT DROP" +== 258 +-- truncate_limit: 100 +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar')" +== 259 +-- truncate_limit: 100 +-- Fails when running in a transaction. +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1) +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp USING btree (f1)" +== 260 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 261 +-- truncate_limit: 100 +-- ON COMMIT DELETE ROWS +CREATE TEMP TABLE concur_temp (f1 int, f2 text) + ON COMMIT DELETE ROWS +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE concur_temp (f1 int, f2 text) ON COMMIT DELETE ROWS" +== 262 +-- truncate_limit: 100 +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar')" +== 263 +-- truncate_limit: 100 +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1) +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp USING btree (f1)" +== 264 +-- truncate_limit: 100 +DROP INDEX CONCURRENTLY concur_temp_ind +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_temp_ind" +== 265 +-- truncate_limit: 100 +DROP TABLE concur_temp +-- +TABLE: name="concur_temp" schema="" table="concur_temp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_temp" +== 266 +-- truncate_limit: 100 +|-- +-- Try some concurrent index drops +|-- +DROP INDEX CONCURRENTLY "concur_index2" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_index2" +== 267 +-- truncate_limit: 100 +-- works +DROP INDEX CONCURRENTLY IF EXISTS "concur_index2" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY IF EXISTS concur_index2" +== 268 +-- truncate_limit: 100 +-- notice + +-- failures +DROP INDEX CONCURRENTLY "concur_index2", "concur_index3" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_index2, concur_index3" +== 269 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 270 +-- truncate_limit: 100 +DROP INDEX CONCURRENTLY "concur_index5" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_index5" +== 271 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 272 +-- truncate_limit: 100 +-- successes +DROP INDEX CONCURRENTLY IF EXISTS "concur_index3" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY IF EXISTS concur_index3" +== 273 +-- truncate_limit: 100 +DROP INDEX CONCURRENTLY "concur_index4" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_index4" +== 274 +-- truncate_limit: 100 +DROP INDEX CONCURRENTLY "concur_index5" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_index5" +== 275 +-- truncate_limit: 100 +DROP INDEX CONCURRENTLY "concur_index1" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_index1" +== 276 +-- truncate_limit: 100 +DROP INDEX CONCURRENTLY "concur_heap_expr_idx" +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY concur_heap_expr_idx" +== 277 +-- truncate_limit: 100 +DROP TABLE concur_heap +-- +TABLE: name="concur_heap" schema="" table="concur_heap" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_heap" +== 278 +-- truncate_limit: 100 +|-- +-- Test ADD CONSTRAINT USING INDEX +|-- + +CREATE TABLE cwi_test( a int , b varchar(10), c char) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cwi_test (a int, b varchar(10), c char(1))" +== 279 +-- truncate_limit: 100 +-- add some data so that all tests have something to work with. + +INSERT INTO cwi_test VALUES(1, 2), (3, 4), (5, 6) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cwi_test VALUES (1, 2), (3, 4), (5, 6)" +== 280 +-- truncate_limit: 100 +CREATE UNIQUE INDEX cwi_uniq_idx ON cwi_test(a , b) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX cwi_uniq_idx ON cwi_test USING btree (a, b)" +== 281 +-- truncate_limit: 100 +ALTER TABLE cwi_test ADD primary key USING INDEX cwi_uniq_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_uniq_idx" +== 282 +-- truncate_limit: 100 +CREATE UNIQUE INDEX cwi_uniq2_idx ON cwi_test(b , a) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX cwi_uniq2_idx ON cwi_test USING btree (b, a)" +== 283 +-- truncate_limit: 100 +ALTER TABLE cwi_test DROP CONSTRAINT cwi_uniq_idx, + ADD CONSTRAINT cwi_replaced_pkey PRIMARY KEY + USING INDEX cwi_uniq2_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cwi_test DROP CONSTRAINT cwi_uniq_idx, ADD CONSTRAINT cwi_replaced_pkey PRIMARY KEY U..." +== 284 +-- truncate_limit: 100 +DROP INDEX cwi_replaced_pkey +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX cwi_replaced_pkey" +== 285 +-- truncate_limit: 100 +-- Should fail; a constraint depends on it + +-- Check that non-default index options are rejected +CREATE UNIQUE INDEX cwi_uniq3_idx ON cwi_test(a desc) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX cwi_uniq3_idx ON cwi_test USING btree (a DESC)" +== 286 +-- truncate_limit: 100 +ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq3_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq3_idx" +== 287 +-- truncate_limit: 100 +-- fail +CREATE UNIQUE INDEX cwi_uniq4_idx ON cwi_test(b collate "POSIX") +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX cwi_uniq4_idx ON cwi_test USING btree (b COLLATE \"POSIX\")" +== 288 +-- truncate_limit: 100 +ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq4_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq4_idx" +== 289 +-- truncate_limit: 100 +-- fail + +DROP TABLE cwi_test +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cwi_test" +== 290 +-- truncate_limit: 100 +-- ADD CONSTRAINT USING INDEX is forbidden on partitioned tables +CREATE TABLE cwi_test(a int) PARTITION BY hash (a) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cwi_test (a int) PARTITION BY HASH (a)" +== 291 +-- truncate_limit: 100 +create unique index on cwi_test (a) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON cwi_test USING btree (a)" +== 292 +-- truncate_limit: 100 +alter table cwi_test add primary key using index cwi_test_a_idx +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_test_a_idx" +== 293 +-- truncate_limit: 100 +DROP TABLE cwi_test +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cwi_test" +== 294 +-- truncate_limit: 100 +-- PRIMARY KEY constraint cannot be backed by a NULLS NOT DISTINCT index +CREATE TABLE cwi_test(a int, b int) +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cwi_test (a int, b int)" +== 295 +-- truncate_limit: 100 +CREATE UNIQUE INDEX cwi_a_nnd ON cwi_test (a) NULLS NOT DISTINCT +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX cwi_a_nnd ON cwi_test USING btree (a) NULLS NOT DISTINCT" +== 296 +-- truncate_limit: 100 +ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_a_nnd +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_a_nnd" +== 297 +-- truncate_limit: 100 +DROP TABLE cwi_test +-- +TABLE: name="cwi_test" schema="" table="cwi_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cwi_test" +== 298 +-- truncate_limit: 100 +|-- +-- Check handling of indexes on system columns +|-- +CREATE TABLE syscol_table (a INT) +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE syscol_table (a int)" +== 299 +-- truncate_limit: 100 +-- System columns cannot be indexed +CREATE INDEX ON syscol_table (ctid) +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON syscol_table USING btree (ctid)" +== 300 +-- truncate_limit: 100 +-- nor used in expressions +CREATE INDEX ON syscol_table ((ctid >= '(1000,0)')) +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON syscol_table USING btree ((ctid >= '(1000,0)'))" +== 301 +-- truncate_limit: 100 +-- nor used in predicates +CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)' +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON syscol_table USING btree (a) WHERE ctid >= '(1000,0)'" +== 302 +-- truncate_limit: 100 +DROP TABLE syscol_table +-- +TABLE: name="syscol_table" schema="" table="syscol_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE syscol_table" +== 303 +-- truncate_limit: 100 +|-- +-- Tests for IS NULL/IS NOT NULL with b-tree indexes +|-- + +CREATE TABLE onek_with_null AS SELECT unique1, unique2 FROM onek +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE onek_with_null AS SELECT unique1, unique2 FROM onek" +== 304 +-- truncate_limit: 100 +INSERT INTO onek_with_null (unique1,unique2) VALUES (NULL, -1), (NULL, NULL) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO onek_with_null (unique1, unique2) VALUES (NULL, -1), (NULL, NULL)" +== 305 +-- truncate_limit: 100 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX onek_nulltest ON onek_with_null USING btree (unique2, unique1)" +== 306 +-- truncate_limit: 100 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 307 +-- truncate_limit: 100 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 308 +-- truncate_limit: 100 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 309 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL" +== 310 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL" +== 311 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL" +== 312 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL" +== 313 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500" +== 314 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500" +== 315 +-- truncate_limit: 100 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX onek_nulltest" +== 316 +-- truncate_limit: 100 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX onek_nulltest ON onek_with_null USING btree (unique2 DESC, unique1)" +== 317 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL" +== 318 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL" +== 319 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL" +== 320 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL" +== 321 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500" +== 322 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500" +== 323 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IN (-1, 0, 1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IN (-1, 0, 1)" +== 324 +-- truncate_limit: 100 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX onek_nulltest" +== 325 +-- truncate_limit: 100 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc nulls last,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX onek_nulltest ON onek_with_null USING btree (unique2 DESC NULLS LAST, unique1)" +== 326 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL" +== 327 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL" +== 328 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL" +== 329 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL" +== 330 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500" +== 331 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500" +== 332 +-- truncate_limit: 100 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX onek_nulltest" +== 333 +-- truncate_limit: 100 +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 nulls first,unique1) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX onek_nulltest ON onek_with_null USING btree (unique2 NULLS FIRST, unique1)" +== 334 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL" +== 335 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL" +== 336 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL" +== 337 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL" +== 338 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500" +== 339 +-- truncate_limit: 100 +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500" +== 340 +-- truncate_limit: 100 +DROP INDEX onek_nulltest +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX onek_nulltest" +== 341 +-- truncate_limit: 100 +-- Check initial-positioning logic too + +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2) +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX onek_nulltest ON onek_with_null USING btree (unique2)" +== 342 +-- truncate_limit: 100 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 343 +-- truncate_limit: 100 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 344 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 345 +-- truncate_limit: 100 +SELECT unique1, unique2 FROM onek_with_null + ORDER BY unique2 LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek_with_null ORDER BY unique2 LIMIT 2" +== 346 +-- truncate_limit: 100 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 + ORDER BY unique2 LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 ORDER BY unique2 LIMIT 2" +== 347 +-- truncate_limit: 100 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= 0 + ORDER BY unique2 LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= 0 ORDER BY unique2 LIMIT 2" +== 348 +-- truncate_limit: 100 +SELECT unique1, unique2 FROM onek_with_null + ORDER BY unique2 DESC LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek_with_null ORDER BY unique2 DESC LIMIT 2" +== 349 +-- truncate_limit: 100 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 + ORDER BY unique2 DESC LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 ORDER BY unique2 DESC LIMIT 2" +== 350 +-- truncate_limit: 100 +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 < 999 + ORDER BY unique2 DESC LIMIT 2 +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek_with_null WHERE unique2 < 999 ORDER BY unique2 DESC LIMIT 2" +== 351 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 352 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 353 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 354 +-- truncate_limit: 100 +DROP TABLE onek_with_null +-- +TABLE: name="onek_with_null" schema="" table="onek_with_null" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE onek_with_null" +== 355 +-- truncate_limit: 100 +|-- +-- Check bitmap index path planning +|-- + +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR ..." +== 356 +-- truncate_limit: 100 +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tenk1 WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42)" +== 357 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE hundred = 42 AND (thousand = 42 OR thousand ..." +== 358 +-- truncate_limit: 100 +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 WHERE hundred = 42 AND (thousand = 42 OR thousand = 99)" +== 359 +-- truncate_limit: 100 +|-- +-- Check behavior with duplicate index column contents +|-- + +CREATE TABLE dupindexcols AS + SELECT unique1 as id, stringu2::text as f1 FROM tenk1 +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE dupindexcols AS SELECT unique1 AS id, stringu2::text AS f1 FROM tenk1" +== 360 +-- truncate_limit: 100 +CREATE INDEX dupindexcols_i ON dupindexcols (f1, id, f1 text_pattern_ops) +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX dupindexcols_i ON dupindexcols USING btree (f1, id, f1 text_pattern_ops)" +== 361 +-- truncate_limit: 100 +ANALYZE dupindexcols +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE dupindexcols" +== 362 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) + SELECT count(*) FROM dupindexcols + WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX' +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM dupindexcols WHERE f1 BETWEEN 'WA' AND 'ZZZ' AND id < 10..." +== 363 +-- truncate_limit: 100 +SELECT count(*) FROM dupindexcols + WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX' +-- +TABLE: name="dupindexcols" schema="" table="dupindexcols" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM dupindexcols WHERE f1 BETWEEN 'WA' AND 'ZZZ' AND id < 1000 AND f1 ~<~ 'YX'" +== 364 +-- truncate_limit: 100 +|-- +-- Check that index scans with =ANY indexquals return rows in index order +|-- + +explain (costs off) +SELECT unique1 FROM tenk1 +WHERE unique1 IN (1,42,7) +ORDER BY unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) ORDER BY unique1" +== 365 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 +WHERE unique1 IN (1,42,7) +ORDER BY unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) ORDER BY unique1" +== 366 +-- truncate_limit: 100 +-- Non-required array scan key on "tenthous": +explain (costs off) +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous FROM tenk1 WHERE thousand < 2 AND tenthous IN (1001..." +== 367 +-- truncate_limit: 100 +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT thousand, tenthous FROM tenk1 WHERE ... ORDER BY thousand" +== 368 +-- truncate_limit: 100 +-- Non-required array scan key on "tenthous", backward scan: +explain (costs off) +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand DESC, tenthous DESC +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous FROM tenk1 WHERE thousand < 2 AND tenthous IN (1001..." +== 369 +-- truncate_limit: 100 +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand DESC, tenthous DESC +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT thousand, tenthous FROM tenk1 WHERE ... ORDER BY thousand DESC, tenthous DESC" +== 370 +-- truncate_limit: 100 +|-- +-- Check elimination of redundant and contradictory index quals +|-- +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = ANY('{7, 8, 9}') +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 = ANY('{7, ..." +== 371 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = ANY('{7, 8, 9}') +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 = ANY('{7, 8, 9}')" +== 372 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') and unique1 = ANY('{33, 44}'::bigint[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') AND unique1 = AN..." +== 373 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') and unique1 = ANY('{33, 44}'::bigint[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') AND unique1 = ANY('{33, 44}'::bigint[])" +== 374 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 = 1" +== 375 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 = 1" +== 376 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 12345 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 = 12345" +== 377 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 12345 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 = 12345" +== 378 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 >= 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 >= 42" +== 379 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 >= 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 >= 42" +== 380 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 > 42" +== 381 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 > 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 > 42" +== 382 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 > 9996 and unique1 >= 9999 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 > 9996 AND unique1 >= 9999" +== 383 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 > 9996 and unique1 >= 9999 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 > 9996 AND unique1 >= 9999" +== 384 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 <= 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 < 3 AND unique1 <= 3" +== 385 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 <= 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 < 3 AND unique1 <= 3" +== 386 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 < 3 AND unique1 < (-1)::bigint" +== 387 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 < 3 AND unique1 < (-1)::bigint" +== 388 +-- truncate_limit: 100 +explain (costs off) +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 < (-1)::bigint" +== 389 +-- truncate_limit: 100 +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 < (-1)::bigint +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) AND unique1 < (-1)::bigint" +== 390 +-- truncate_limit: 100 +|-- +-- Check elimination of constant-NULL subexpressions +|-- + +explain (costs off) + select * from tenk1 where (thousand, tenthous) in ((1,1001), (null,null)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE (thousand, tenthous) IN ((1, 1001), (NULL, NULL))" +== 391 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE boolindex (b bool, i int, UNIQUE (b, i), junk double precision)" +== 392 +-- truncate_limit: 100 +explain (costs off) + select * from boolindex order by b, i limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolindex ORDER BY b, i LIMIT 10" +== 393 +-- truncate_limit: 100 +explain (costs off) + select * from boolindex where b order by i limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolindex WHERE b ORDER BY i LIMIT 10" +== 394 +-- truncate_limit: 100 +explain (costs off) + select * from boolindex where b = true order by i desc limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolindex WHERE b = true ORDER BY i DESC LIMIT 10" +== 395 +-- truncate_limit: 100 +explain (costs off) + select * from boolindex where not b order by i limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolindex WHERE NOT b ORDER BY i LIMIT 10" +== 396 +-- truncate_limit: 100 +explain (costs off) + select * from boolindex where b is true order by i desc limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolindex WHERE b IS TRUE ORDER BY i DESC LIMIT 10" +== 397 +-- truncate_limit: 100 +explain (costs off) + select * from boolindex where b is false order by i desc limit 10 +-- +TABLE: name="boolindex" schema="" table="boolindex" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolindex WHERE b IS FALSE ORDER BY i DESC LIMIT 10" +== 398 +-- truncate_limit: 100 +|-- +-- REINDEX (VERBOSE) +|-- +CREATE TABLE reindex_verbose(id integer primary key) +-- +TABLE: name="reindex_verbose" schema="" table="reindex_verbose" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE reindex_verbose (id int PRIMARY KEY)" +== 399 +-- truncate_limit: 100 +REINDEX (VERBOSE) TABLE reindex_verbose +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (VERBOSE) TABLE reindex_verbose" +== 400 +-- truncate_limit: 100 +DROP TABLE reindex_verbose +-- +TABLE: name="reindex_verbose" schema="" table="reindex_verbose" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE reindex_verbose" +== 401 +-- truncate_limit: 100 +|-- +-- REINDEX CONCURRENTLY +|-- +CREATE TABLE concur_reindex_tab (c1 int) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_tab (c1 int)" +== 402 +-- truncate_limit: 100 +-- REINDEX +REINDEX TABLE concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_tab" +== 403 +-- truncate_limit: 100 +-- notice +REINDEX (CONCURRENTLY) TABLE concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_tab" +== 404 +-- truncate_limit: 100 +-- notice +ALTER TABLE concur_reindex_tab ADD COLUMN c2 text +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE concur_reindex_tab ADD COLUMN c2 text" +== 405 +-- truncate_limit: 100 +-- add toast index +-- Normal index with integer column +CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab USING btree (c1)" +== 406 +-- truncate_limit: 100 +-- Normal index with text column +CREATE INDEX concur_reindex_ind2 ON concur_reindex_tab(c2) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_ind2 ON concur_reindex_tab USING btree (c2)" +== 407 +-- truncate_limit: 100 +-- UNIQUE index with expression +CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab(abs(c1)) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab USING btree (abs(c1))" +== 408 +-- truncate_limit: 100 +-- Duplicate column names +CREATE INDEX concur_reindex_ind4 ON concur_reindex_tab(c1, c1, c2) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_ind4 ON concur_reindex_tab USING btree (c1, c1, c2)" +== 409 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE concur_reindex_tab ADD PRIMARY KEY USING INDEX concur_reindex_ind1" +== 410 +-- truncate_limit: 100 +CREATE TABLE concur_reindex_tab2 (c1 int REFERENCES concur_reindex_tab) +-- +TABLE: name="concur_reindex_tab2" schema="" table="concur_reindex_tab2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_tab2 (c1 int REFERENCES concur_reindex_tab)" +== 411 +-- truncate_limit: 100 +INSERT INTO concur_reindex_tab VALUES (1, 'a') +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_reindex_tab VALUES (1, 'a')" +== 412 +-- truncate_limit: 100 +INSERT INTO concur_reindex_tab VALUES (2, 'a') +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_reindex_tab VALUES (2, 'a')" +== 413 +-- truncate_limit: 100 +-- Reindex concurrently of exclusion constraint currently not supported +CREATE TABLE concur_reindex_tab3 (c1 int, c2 int4range, EXCLUDE USING gist (c2 WITH &&)) +-- +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_tab3 (c1 int, c2 int4range, EXCLUDE USING gist (c2 WITH &&))" +== 414 +-- truncate_limit: 100 +INSERT INTO concur_reindex_tab3 VALUES (3, '[1,2]') +-- +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_reindex_tab3 VALUES (3, '[1,2]')" +== 415 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_tab3_c2_excl +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_tab3_c2_excl" +== 416 +-- truncate_limit: 100 +-- error +REINDEX TABLE CONCURRENTLY concur_reindex_tab3 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_tab3" +== 417 +-- truncate_limit: 100 +-- succeeds with warning +INSERT INTO concur_reindex_tab3 VALUES (4, '[2,4]') +-- +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_reindex_tab3 VALUES (4, '[2,4]')" +== 418 +-- truncate_limit: 100 +-- Check materialized views +CREATE MATERIALIZED VIEW concur_reindex_matview AS SELECT * FROM concur_reindex_tab +-- +TABLE: name="concur_reindex_matview" schema="" table="concur_reindex_matview" ctx=DDL +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW concur_reindex_matview AS SELECT * FROM concur_reindex_tab" +== 419 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1, 2" +== 420 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_ind1 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_ind1" +== 421 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_tab" +== 422 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_matview +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_matview" +== 423 +-- truncate_limit: 100 +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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1, 2" +== 424 +-- truncate_limit: 100 +-- Check that comments are preserved +CREATE TABLE testcomment (i int) +-- +TABLE: name="testcomment" schema="" table="testcomment" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testcomment (i int)" +== 425 +-- truncate_limit: 100 +CREATE INDEX testcomment_idx1 ON testcomment (i) +-- +TABLE: name="testcomment" schema="" table="testcomment" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX testcomment_idx1 ON testcomment USING btree (i)" +== 426 +-- truncate_limit: 100 +COMMENT ON INDEX testcomment_idx1 IS 'test comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX testcomment_idx1 IS 'test comment'" +== 427 +-- truncate_limit: 100 +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT obj_description('testcomment_idx1'::regclass, 'pg_class')" +== 428 +-- truncate_limit: 100 +REINDEX TABLE testcomment +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE testcomment" +== 429 +-- truncate_limit: 100 +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT obj_description('testcomment_idx1'::regclass, 'pg_class')" +== 430 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY testcomment +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE testcomment" +== 431 +-- truncate_limit: 100 +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT obj_description('testcomment_idx1'::regclass, 'pg_class')" +== 432 +-- truncate_limit: 100 +DROP TABLE testcomment +-- +TABLE: name="testcomment" schema="" table="testcomment" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testcomment" +== 433 +-- truncate_limit: 100 +-- Check that indisclustered updates are preserved +CREATE TABLE concur_clustered(i int) +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_clustered (i int)" +== 434 +-- truncate_limit: 100 +CREATE INDEX concur_clustered_i_idx ON concur_clustered(i) +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_clustered_i_idx ON concur_clustered USING btree (i)" +== 435 +-- truncate_limit: 100 +ALTER TABLE concur_clustered CLUSTER ON concur_clustered_i_idx +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE concur_clustered CLUSTER ON concur_clustered_i_idx" +== 436 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_clustered +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_clustered" +== 437 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indisclustered FROM pg_index + WHERE indrelid = 'concur_clustered'::regclass +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT indexrelid::regclass, indisclustered FROM pg_index WHERE ..." +== 438 +-- truncate_limit: 100 +DROP TABLE concur_clustered +-- +TABLE: name="concur_clustered" schema="" table="concur_clustered" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_clustered" +== 439 +-- truncate_limit: 100 +-- Check that indisreplident updates are preserved. +CREATE TABLE concur_replident(i int NOT NULL) +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_replident (i int NOT NULL)" +== 440 +-- truncate_limit: 100 +CREATE UNIQUE INDEX concur_replident_i_idx ON concur_replident(i) +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX concur_replident_i_idx ON concur_replident USING btree (i)" +== 441 +-- truncate_limit: 100 +ALTER TABLE concur_replident REPLICA IDENTITY + USING INDEX concur_replident_i_idx +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE concur_replident REPLICA IDENTITY USING INDEX concur_replident_i_idx" +== 442 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indisreplident FROM pg_index + WHERE indrelid = 'concur_replident'::regclass +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT indexrelid::regclass, indisreplident FROM pg_index WHERE ..." +== 443 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_replident +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_replident" +== 444 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indisreplident FROM pg_index + WHERE indrelid = 'concur_replident'::regclass +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT indexrelid::regclass, indisreplident FROM pg_index WHERE ..." +== 445 +-- truncate_limit: 100 +DROP TABLE concur_replident +-- +TABLE: name="concur_replident" schema="" table="concur_replident" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_replident" +== 446 +-- truncate_limit: 100 +-- Check that opclass parameters are preserved +CREATE TABLE concur_appclass_tab(i tsvector, j tsvector, k tsvector) +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_appclass_tab (i tsvector, j tsvector, k tsvector)" +== 447 +-- truncate_limit: 100 +CREATE INDEX concur_appclass_ind on concur_appclass_tab + USING gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500')) +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_appclass_ind ON concur_appclass_tab USING gist (i tsvector_ops(siglen='1000')..." +== 448 +-- truncate_limit: 100 +CREATE INDEX concur_appclass_ind_2 on concur_appclass_tab + USING gist (k tsvector_ops (siglen='300'), j tsvector_ops) +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_appclass_ind_2 ON concur_appclass_tab USING gist (k tsvector_ops(siglen='300'..." +== 449 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_appclass_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_appclass_tab" +== 450 +-- truncate_limit: 100 +DROP TABLE concur_appclass_tab +-- +TABLE: name="concur_appclass_tab" schema="" table="concur_appclass_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_appclass_tab" +== 451 +-- truncate_limit: 100 +-- Partitions +-- Create some partitioned tables +CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1)" +== 452 +-- truncate_limit: 100 +CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2) +-- +TABLE: name="concur_reindex_part_0" schema="" table="concur_reindex_part_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part FOR VALUES FROM (0) TO (10) P..." +== 453 +-- truncate_limit: 100 +CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (1) +-- +TABLE: name="concur_reindex_part_0_1" schema="" table="concur_reindex_part_0_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0 FOR VALUES IN (1)" +== 454 +-- truncate_limit: 100 +CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (2) +-- +TABLE: name="concur_reindex_part_0_2" schema="" table="concur_reindex_part_0_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0 FOR VALUES IN (2)" +== 455 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="concur_reindex_part_10" schema="" table="concur_reindex_part_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_part_10 PARTITION OF concur_reindex_part FOR VALUES FROM (10) TO (20)..." +== 456 +-- truncate_limit: 100 +-- Create some partitioned indexes +CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part USING btree (c1)" +== 457 +-- truncate_limit: 100 +CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1) +-- +TABLE: name="concur_reindex_part_0" schema="" table="concur_reindex_part_0" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 USING btree (c1)" +== 458 +-- truncate_limit: 100 +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0" +== 459 +-- truncate_limit: 100 +-- This partitioned index will have no partitions. +CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1) +-- +TABLE: name="concur_reindex_part_10" schema="" table="concur_reindex_part_10" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 USING btree (c1)" +== 460 +-- truncate_limit: 100 +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10" +== 461 +-- truncate_limit: 100 +CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1) +-- +TABLE: name="concur_reindex_part_0_1" schema="" table="concur_reindex_part_0_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 USING btree (c1)" +== 462 +-- truncate_limit: 100 +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1" +== 463 +-- truncate_limit: 100 +CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1) +-- +TABLE: name="concur_reindex_part_0_2" schema="" table="concur_reindex_part_0_2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 USING btree (c1)" +== 464 +-- truncate_limit: 100 +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2" +== 465 +-- truncate_limit: 100 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('concur_reindex_part_index') ORDER BY relid, level" +== 466 +-- truncate_limit: 100 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('concur_reindex_part_index') ORDER BY relid, level" +== 467 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1, 2" +== 468 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_part_index_0_1" +== 469 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_part_index_0_2" +== 470 +-- truncate_limit: 100 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('concur_reindex_part_index') ORDER BY relid, level" +== 471 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part_0_1" +== 472 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part_0_2" +== 473 +-- truncate_limit: 100 +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 +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_depend WHERE ... ORDER BY 1, 2" +== 474 +-- truncate_limit: 100 +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('concur_reindex_part_index') ORDER BY relid, level" +== 475 +-- truncate_limit: 100 +-- REINDEX for partitioned indexes +-- REINDEX TABLE fails for partitioned indexes +-- Top-most parent index +REINDEX TABLE concur_reindex_part_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_part_index" +== 476 +-- truncate_limit: 100 +-- error +REINDEX TABLE CONCURRENTLY concur_reindex_part_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part_index" +== 477 +-- truncate_limit: 100 +-- error +-- Partitioned index with no leaves +REINDEX TABLE concur_reindex_part_index_10 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_part_index_10" +== 478 +-- truncate_limit: 100 +-- error +REINDEX TABLE CONCURRENTLY concur_reindex_part_index_10 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part_index_10" +== 479 +-- truncate_limit: 100 +-- error +-- Cannot run in a transaction block +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 480 +-- truncate_limit: 100 +REINDEX INDEX concur_reindex_part_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX concur_reindex_part_index" +== 481 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 482 +-- truncate_limit: 100 +-- Helper functions to track changes of relfilenodes in a partition tree. +-- Create a table tracking the relfilenode state. +CREATE OR REPLACE FUNCTION create_relfilenode_part(relname text, indname text) + RETURNS VOID AS + $func$ + BEGIN + EXECUTE format(' + CREATE TABLE %I AS + SELECT oid, relname, relfilenode, relkind, reltoastrelid + FROM pg_class + WHERE oid IN + (SELECT relid FROM pg_partition_tree(''%I''));', + relname, indname); + END + $func$ LANGUAGE plpgsql +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION create_relfilenode_part(relname text, indname text) RETURNS void AS $$..." +== 483 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION compare_relfilenode_part(tabname text) + RETURNS TABLE (relname name, relkind "char", state text) AS + $func$ + BEGIN + RETURN QUERY EXECUTE + format( + 'SELECT b.relname, + b.relkind, + CASE WHEN a.relfilenode = b.relfilenode THEN ''relfilenode is unchanged'' + ELSE ''relfilenode has changed'' END + -- Do not join with OID here as CONCURRENTLY changes it. + FROM %I b JOIN pg_class a ON b.relname = a.relname + ORDER BY 1;', tabname); + END + $func$ LANGUAGE plpgsql +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compare_relfilenode_part(tabname text) RETURNS TABLE (relname name, re..." +== 484 +-- truncate_limit: 100 +-- Check that expected relfilenodes are changed, non-concurrent case. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index')" +== 485 +-- truncate_limit: 100 +REINDEX INDEX concur_reindex_part_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX concur_reindex_part_index" +== 486 +-- truncate_limit: 100 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM compare_relfilenode_part('reindex_index_status')" +== 487 +-- truncate_limit: 100 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE reindex_index_status" +== 488 +-- truncate_limit: 100 +-- concurrent case. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index')" +== 489 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_part_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_part_index" +== 490 +-- truncate_limit: 100 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM compare_relfilenode_part('reindex_index_status')" +== 491 +-- truncate_limit: 100 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE reindex_index_status" +== 492 +-- truncate_limit: 100 +-- REINDEX for partitioned tables +-- REINDEX INDEX fails for partitioned tables +-- Top-most parent +REINDEX INDEX concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX concur_reindex_part" +== 493 +-- truncate_limit: 100 +-- error +REINDEX INDEX CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_part" +== 494 +-- truncate_limit: 100 +-- error +-- Partitioned with no leaves +REINDEX INDEX concur_reindex_part_10 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX concur_reindex_part_10" +== 495 +-- truncate_limit: 100 +-- error +REINDEX INDEX CONCURRENTLY concur_reindex_part_10 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_part_10" +== 496 +-- truncate_limit: 100 +-- error +-- Cannot run in a transaction block +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 497 +-- truncate_limit: 100 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_part" +== 498 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 499 +-- truncate_limit: 100 +-- Check that expected relfilenodes are changed, non-concurrent case. +-- Note that the partition tree changes of the *indexes* need to be checked. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index')" +== 500 +-- truncate_limit: 100 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_part" +== 501 +-- truncate_limit: 100 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM compare_relfilenode_part('reindex_index_status')" +== 502 +-- truncate_limit: 100 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE reindex_index_status" +== 503 +-- truncate_limit: 100 +-- concurrent case. +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index') +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index')" +== 504 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part" +== 505 +-- truncate_limit: 100 +SELECT * FROM compare_relfilenode_part('reindex_index_status') +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM compare_relfilenode_part('reindex_index_status')" +== 506 +-- truncate_limit: 100 +DROP TABLE reindex_index_status +-- +TABLE: name="reindex_index_status" schema="" table="reindex_index_status" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE reindex_index_status" +== 507 +-- truncate_limit: 100 +DROP FUNCTION create_relfilenode_part +-- +FUNCTION: name="create_relfilenode_part" function="create_relfilenode_part" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION create_relfilenode_part" +== 508 +-- truncate_limit: 100 +DROP FUNCTION compare_relfilenode_part +-- +FUNCTION: name="compare_relfilenode_part" function="compare_relfilenode_part" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION compare_relfilenode_part" +== 509 +-- truncate_limit: 100 +-- Cleanup of partition tree used for REINDEX test. +DROP TABLE concur_reindex_part +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_reindex_part" +== 510 +-- truncate_limit: 100 +-- Check errors +-- Cannot run inside a transaction block +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 511 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_tab" +== 512 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 513 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY pg_class +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE pg_class" +== 514 +-- truncate_limit: 100 +-- no catalog relation +REINDEX INDEX CONCURRENTLY pg_class_oid_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX pg_class_oid_index" +== 515 +-- truncate_limit: 100 +-- no catalog index +-- These are the toast table and index of pg_authid. +REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE pg_toast.pg_toast_1260" +== 516 +-- truncate_limit: 100 +-- no catalog toast table +REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX pg_toast.pg_toast_1260_index" +== 517 +-- truncate_limit: 100 +-- no catalog toast index +REINDEX SYSTEM CONCURRENTLY postgres +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SYSTEM postgres" +== 518 +-- truncate_limit: 100 +-- not allowed for SYSTEM +REINDEX (CONCURRENTLY) SYSTEM postgres +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SYSTEM postgres" +== 519 +-- truncate_limit: 100 +-- ditto +REINDEX (CONCURRENTLY) SYSTEM +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SYSTEM" +== 520 +-- truncate_limit: 100 +-- ditto +-- Warns about catalog relations +REINDEX SCHEMA CONCURRENTLY pg_catalog +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SCHEMA pg_catalog" +== 521 +-- truncate_limit: 100 +-- Not the current database +REINDEX DATABASE not_current_database +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX DATABASE not_current_database" +== 522 +-- truncate_limit: 100 +-- Check the relation status, there should not be invalid indexes +DROP MATERIALIZED VIEW concur_reindex_matview +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW concur_reindex_matview" +== 523 +-- truncate_limit: 100 +DROP TABLE concur_reindex_tab, concur_reindex_tab2, concur_reindex_tab3 +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +TABLE: name="concur_reindex_tab2" schema="" table="concur_reindex_tab2" ctx=DDL +TABLE: name="concur_reindex_tab3" schema="" table="concur_reindex_tab3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_reindex_tab, concur_reindex_tab2, concur_reindex_tab3" +== 524 +-- truncate_limit: 100 +-- Check handling of invalid indexes +CREATE TABLE concur_reindex_tab4 (c1 int) +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_tab4 (c1 int)" +== 525 +-- truncate_limit: 100 +INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2) +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2)" +== 526 +-- truncate_limit: 100 +-- This trick creates an invalid index. +CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1) +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 USING btree (c1)" +== 527 +-- truncate_limit: 100 +-- 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 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_ind5" +== 528 +-- truncate_limit: 100 +DROP INDEX concur_reindex_ind5_ccnew +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX concur_reindex_ind5_ccnew" +== 529 +-- truncate_limit: 100 +-- This makes the previous failure go away, so the index can become valid. +DELETE FROM concur_reindex_tab4 WHERE c1 = 1 +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM concur_reindex_tab4 WHERE c1 = 1" +== 530 +-- truncate_limit: 100 +-- The invalid index is not processed when running REINDEX TABLE. +REINDEX TABLE CONCURRENTLY concur_reindex_tab4 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_tab4" +== 531 +-- truncate_limit: 100 +-- But it is fixed with REINDEX INDEX. +REINDEX INDEX CONCURRENTLY concur_reindex_ind5 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_ind5" +== 532 +-- truncate_limit: 100 +DROP TABLE concur_reindex_tab4 +-- +TABLE: name="concur_reindex_tab4" schema="" table="concur_reindex_tab4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_reindex_tab4" +== 533 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_exprs_tab (c1 int, c2 boolean)" +== 534 +-- truncate_limit: 100 +INSERT INTO concur_exprs_tab (c1, c2) VALUES (1369652450, FALSE), + (414515746, TRUE), + (897778963, FALSE) +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_exprs_tab (c1, c2) VALUES (...)" +== 535 +-- truncate_limit: 100 +CREATE UNIQUE INDEX concur_exprs_index_expr + ON concur_exprs_tab ((c1::text COLLATE "C")) +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX concur_exprs_index_expr ON concur_exprs_tab USING btree ((c1::text COLLATE \"C\"))" +== 536 +-- truncate_limit: 100 +CREATE UNIQUE INDEX concur_exprs_index_pred ON concur_exprs_tab (c1) + WHERE (c1::text > 500000000::text COLLATE "C") +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX concur_exprs_index_pred ON concur_exprs_tab USING btree (c1) WHERE ..." +== 537 +-- truncate_limit: 100 +CREATE UNIQUE INDEX concur_exprs_index_pred_2 + ON concur_exprs_tab ((1 / c1)) + WHERE ('-H') >= (c2::TEXT) COLLATE "C" +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX concur_exprs_index_pred_2 ON concur_exprs_tab USING btree ((1 / c1)) WHERE ..." +== 538 +-- truncate_limit: 100 +ALTER INDEX concur_exprs_index_expr ALTER COLUMN 1 SET STATISTICS 100 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX concur_exprs_index_expr ALTER COLUMN 1 SET STATISTICS 100" +== 539 +-- truncate_limit: 100 +ANALYZE concur_exprs_tab +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE concur_exprs_tab" +== 540 +-- truncate_limit: 100 +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 +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="starelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_statistic WHERE ... GROUP BY starelid ORDER BY starelid::regclass::text" +== 541 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass)" +== 542 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass)" +== 543 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass)" +== 544 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_exprs_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_exprs_tab" +== 545 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass)" +== 546 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass)" +== 547 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass)" +== 548 +-- truncate_limit: 100 +-- ALTER TABLE recreates the indexes, which should keep their collations. +ALTER TABLE concur_exprs_tab ALTER c2 TYPE TEXT +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE concur_exprs_tab ALTER COLUMN c2 TYPE text" +== 549 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass)" +== 550 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass)" +== 551 +-- truncate_limit: 100 +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass)" +== 552 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="starelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_statistic WHERE ... GROUP BY starelid ORDER BY starelid::regclass::text" +== 553 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE ... ORDER BY attrelid::regclass::text, attnum" +== 554 +-- truncate_limit: 100 +DROP TABLE concur_exprs_tab +-- +TABLE: name="concur_exprs_tab" schema="" table="concur_exprs_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_exprs_tab" +== 555 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE concur_temp_tab_1 (c1 int, c2 text) ON COMMIT PRESERVE ROWS" +== 556 +-- truncate_limit: 100 +INSERT INTO concur_temp_tab_1 VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_temp_tab_1 VALUES (1, 'foo'), (2, 'bar')" +== 557 +-- truncate_limit: 100 +CREATE INDEX concur_temp_ind_1 ON concur_temp_tab_1(c2) +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_temp_ind_1 ON concur_temp_tab_1 USING btree (c2)" +== 558 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_temp_tab_1 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_temp_tab_1" +== 559 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_temp_ind_1 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_temp_ind_1" +== 560 +-- truncate_limit: 100 +-- Still fails in transaction blocks +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 561 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_temp_ind_1 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_temp_ind_1" +== 562 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 563 +-- truncate_limit: 100 +-- ON COMMIT DELETE ROWS +CREATE TEMP TABLE concur_temp_tab_2 (c1 int, c2 text) + ON COMMIT DELETE ROWS +-- +TABLE: name="concur_temp_tab_2" schema="" table="concur_temp_tab_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE concur_temp_tab_2 (c1 int, c2 text) ON COMMIT DELETE ROWS" +== 564 +-- truncate_limit: 100 +CREATE INDEX concur_temp_ind_2 ON concur_temp_tab_2(c2) +-- +TABLE: name="concur_temp_tab_2" schema="" table="concur_temp_tab_2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_temp_ind_2 ON concur_temp_tab_2 USING btree (c2)" +== 565 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_temp_tab_2 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_temp_tab_2" +== 566 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_temp_ind_2 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_temp_ind_2" +== 567 +-- truncate_limit: 100 +-- ON COMMIT DROP +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 568 +-- truncate_limit: 100 +CREATE TEMP TABLE concur_temp_tab_3 (c1 int, c2 text) + ON COMMIT PRESERVE ROWS +-- +TABLE: name="concur_temp_tab_3" schema="" table="concur_temp_tab_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE concur_temp_tab_3 (c1 int, c2 text) ON COMMIT PRESERVE ROWS" +== 569 +-- truncate_limit: 100 +INSERT INTO concur_temp_tab_3 VALUES (1, 'foo'), (2, 'bar') +-- +TABLE: name="concur_temp_tab_3" schema="" table="concur_temp_tab_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO concur_temp_tab_3 VALUES (1, 'foo'), (2, 'bar')" +== 570 +-- truncate_limit: 100 +CREATE INDEX concur_temp_ind_3 ON concur_temp_tab_3(c2) +-- +TABLE: name="concur_temp_tab_3" schema="" table="concur_temp_tab_3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_temp_ind_3 ON concur_temp_tab_3 USING btree (c2)" +== 571 +-- truncate_limit: 100 +-- Fails when running in a transaction +REINDEX INDEX CONCURRENTLY concur_temp_ind_3 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_temp_ind_3" +== 572 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 573 +-- truncate_limit: 100 +-- 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') +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE reindex_temp_before AS SELECT oid, relname, relfilenode, relkind, reltoastrelid FROM..." +== 574 +-- truncate_limit: 100 +SELECT pg_my_temp_schema()::regnamespace as temp_schema_name +-- +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_my_temp_schema()::regnamespace AS temp_schema_name" +== 575 +-- truncate_limit: 100 +REINDEX SCHEMA CONCURRENTLY :temp_schema_name +-- +ERROR: syntax error at or near ":" +CURSORPOS: 29 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 576 +-- truncate_limit: 100 +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 +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="reindex_temp_before" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM reindex_temp_before b JOIN pg_class a ON b.oid = a.oid ORDER BY 1" +== 577 +-- truncate_limit: 100 +DROP TABLE concur_temp_tab_1, concur_temp_tab_2, reindex_temp_before +-- +TABLE: name="concur_temp_tab_1" schema="" table="concur_temp_tab_1" ctx=DDL +TABLE: name="concur_temp_tab_2" schema="" table="concur_temp_tab_2" ctx=DDL +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_temp_tab_1, concur_temp_tab_2, reindex_temp_before" +== 578 +-- truncate_limit: 100 +|-- +-- REINDEX SCHEMA +|-- +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA schema_to_reindex" +== 579 +-- truncate_limit: 100 +-- failure, schema does not exist +CREATE SCHEMA schema_to_reindex +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA schema_to_reindex" +== 580 +-- truncate_limit: 100 +SET search_path = 'schema_to_reindex' +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO schema_to_reindex" +== 581 +-- truncate_limit: 100 +CREATE TABLE table1(col1 SERIAL PRIMARY KEY) +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE table1 (col1 serial PRIMARY KEY)" +== 582 +-- truncate_limit: 100 +INSERT INTO table1 SELECT generate_series(1,400) +-- +TABLE: name="table1" schema="" table="table1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO table1 SELECT generate_series(1, 400)" +== 583 +-- truncate_limit: 100 +CREATE TABLE table2(col1 SERIAL PRIMARY KEY, col2 TEXT NOT NULL) +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE table2 (col1 serial PRIMARY KEY, col2 text NOT NULL)" +== 584 +-- truncate_limit: 100 +INSERT INTO table2 SELECT generate_series(1,400), 'abc' +-- +TABLE: name="table2" schema="" table="table2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO table2 SELECT generate_series(1, 400), 'abc'" +== 585 +-- truncate_limit: 100 +CREATE INDEX ON table2(col2) +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON table2 USING btree (col2)" +== 586 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW matview AS SELECT col1 FROM table2 +-- +TABLE: name="matview" schema="" table="matview" ctx=DDL +TABLE: name="table2" schema="" table="table2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW matview AS SELECT col1 FROM table2" +== 587 +-- truncate_limit: 100 +CREATE INDEX ON matview(col1) +-- +TABLE: name="matview" schema="" table="matview" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON matview USING btree (col1)" +== 588 +-- truncate_limit: 100 +CREATE VIEW view AS SELECT col2 FROM table2 +-- +TABLE: name="view" schema="" table="view" ctx=DDL +TABLE: name="table2" schema="" table="table2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view AS SELECT col2 FROM table2" +== 589 +-- truncate_limit: 100 +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') +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE reindex_before AS SELECT oid, relname, relfilenode, relkind, reltoastrelid FROM pg_c..." +== 590 +-- truncate_limit: 100 +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) +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=DML +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="reltoastrelid" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO reindex_before SELECT ... FROM pg_class WHERE ..." +== 591 +-- truncate_limit: 100 +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)) +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=DML +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="reltoastrelid" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO reindex_before SELECT ... FROM pg_class WHERE ..." +== 592 +-- truncate_limit: 100 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA schema_to_reindex" +== 593 +-- truncate_limit: 100 +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') +-- +TABLE: name="reindex_after" schema="" table="reindex_after" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE reindex_after AS SELECT oid, relname, relfilenode, relkind FROM pg_class WHERE relna..." +== 594 +-- truncate_limit: 100 +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 +-- +TABLE: name="reindex_before" schema="" table="reindex_before" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="reindex_before" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM reindex_before b JOIN pg_class a ON b.oid = a.oid ORDER BY 1" +== 595 +-- truncate_limit: 100 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA schema_to_reindex" +== 596 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 597 +-- truncate_limit: 100 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA schema_to_reindex" +== 598 +-- truncate_limit: 100 +-- failure, cannot run in a transaction +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 599 +-- truncate_limit: 100 +-- concurrently +REINDEX SCHEMA CONCURRENTLY schema_to_reindex +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SCHEMA schema_to_reindex" +== 600 +-- truncate_limit: 100 +-- Failure for unauthorized user +CREATE ROLE regress_reindexuser NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_reindexuser WITH NOLOGIN" +== 601 +-- truncate_limit: 100 +SET SESSION ROLE regress_reindexuser +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_reindexuser" +== 602 +-- truncate_limit: 100 +REINDEX SCHEMA schema_to_reindex +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA schema_to_reindex" +== 603 +-- truncate_limit: 100 +-- Permission failures with toast tables and indexes (pg_authid here) +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 604 +-- truncate_limit: 100 +GRANT USAGE ON SCHEMA pg_toast TO regress_reindexuser +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON SCHEMA pg_toast TO regress_reindexuser" +== 605 +-- truncate_limit: 100 +SET SESSION ROLE regress_reindexuser +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_reindexuser" +== 606 +-- truncate_limit: 100 +REINDEX TABLE pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE pg_toast.pg_toast_1260" +== 607 +-- truncate_limit: 100 +REINDEX INDEX pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX pg_toast.pg_toast_1260_index" +== 608 +-- truncate_limit: 100 +-- Clean up +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 609 +-- truncate_limit: 100 +REVOKE USAGE ON SCHEMA pg_toast FROM regress_reindexuser +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON SCHEMA pg_toast FROM regress_reindexuser" +== 610 +-- truncate_limit: 100 +DROP ROLE regress_reindexuser +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_reindexuser" +== 611 +-- truncate_limit: 100 +DROP SCHEMA schema_to_reindex CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA schema_to_reindex CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json new file mode 100644 index 0000000..18fb3ca --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json @@ -0,0 +1,206 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.test b/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.test new file mode 100644 index 0000000..712a8e7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.test @@ -0,0 +1,1989 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SP-GiST index tests +|-- + +CREATE TABLE quad_point_tbl AS + SELECT point(unique1,unique2) AS p FROM tenk1 +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE quad_point_tbl AS SELECT point(unique1, unique2) AS p FROM tenk1" +== 002 +-- truncate_limit: 100 +INSERT INTO quad_point_tbl + SELECT '(333.0,400.0)'::point FROM generate_series(1,1000) +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_point_tbl SELECT '(333.0,400.0)'::point FROM generate_series(1, 1000)" +== 003 +-- truncate_limit: 100 +INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL) +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL)" +== 004 +-- truncate_limit: 100 +CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p) +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p)" +== 005 +-- truncate_limit: 100 +CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl" +== 006 +-- truncate_limit: 100 +CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops) +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops)" +== 007 +-- truncate_limit: 100 +CREATE TABLE radix_text_tbl AS + SELECT name AS t FROM road WHERE name !~ '^[0-9]' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DDL +TABLE: name="road" schema="" table="road" ctx=Select +FILTER: schema="" table="" column="name" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE radix_text_tbl AS SELECT name AS t FROM road WHERE name !~ '^[0-9]'" +== 008 +-- truncate_limit: 100 +INSERT INTO radix_text_tbl + SELECT 'P0123456789abcdef' FROM generate_series(1,1000) +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO radix_text_tbl SELECT 'P0123456789abcdef' FROM generate_series(1, 1000)" +== 009 +-- truncate_limit: 100 +INSERT INTO radix_text_tbl VALUES ('P0123456789abcde') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO radix_text_tbl VALUES ('P0123456789abcde')" +== 010 +-- truncate_limit: 100 +INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF')" +== 011 +-- truncate_limit: 100 +CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t) +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t)" +== 012 +-- truncate_limit: 100 +-- get non-indexed results for comparison purposes + +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 013 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 014 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 015 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p IS NULL" +== 016 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL" +== 017 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl" +== 018 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 019 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 020 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'" +== 021 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'" +== 022 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'" +== 023 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'" +== 024 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'" +== 025 +-- truncate_limit: 100 +CREATE TEMP TABLE quad_point_tbl_ord_seq1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_point_tbl_ord_seq1 AS SELECT row_number() OVER (ORDER BY p <-> '0,0')..." +== 026 +-- truncate_limit: 100 +CREATE TEMP TABLE quad_point_tbl_ord_seq2 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)' +-- +TABLE: name="quad_point_tbl_ord_seq2" schema="" table="quad_point_tbl_ord_seq2" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_point_tbl_ord_seq2 AS SELECT row_number() OVER (ORDER BY p <-> '0,0')..." +== 027 +-- truncate_limit: 100 +CREATE TEMP TABLE quad_point_tbl_ord_seq3 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 +-- +TABLE: name="quad_point_tbl_ord_seq3" schema="" table="quad_point_tbl_ord_seq3" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_point_tbl_ord_seq3 AS SELECT row_number() OVER (ORDER BY p <-> '333,4..." +== 028 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'" +== 029 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'" +== 030 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'" +== 031 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '" +== 032 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '" +== 033 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '" +== 034 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '" +== 035 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '" +== 036 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '" +== 037 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '" +== 038 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '" +== 039 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '" +== 040 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '" +== 041 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'" +== 042 +-- truncate_limit: 100 +-- Now check the results from plain indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 043 +-- truncate_limit: 100 +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 044 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 045 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p IS NULL" +== 046 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p IS NULL" +== 047 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL" +== 048 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL" +== 049 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl" +== 050 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl" +== 051 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 052 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 053 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 054 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 055 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'" +== 056 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'" +== 057 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'" +== 058 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'" +== 059 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'" +== 060 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'" +== 061 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'" +== 062 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'" +== 063 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'" +== 064 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'" +== 065 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT row_number() OVER (ORDER BY p <-> '0,0') AS n, p <-> '0,0' AS dist, p ..." +== 066 +-- truncate_limit: 100 +CREATE TEMP TABLE quad_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl_ord_idx1" schema="" table="quad_point_tbl_ord_idx1" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_point_tbl_ord_idx1 AS SELECT row_number() OVER (ORDER BY p <-> '0,0')..." +== 067 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +TABLE: name="quad_point_tbl_ord_idx1" schema="" table="quad_point_tbl_ord_idx1" ctx=Select +ALIAS: "idx"="quad_point_tbl_ord_idx1" +ALIAS: "seq"="quad_point_tbl_ord_seq1" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN quad_point_tbl_ord_idx1 idx ON seq.n = idx.n ..." +== 068 +-- truncate_limit: 100 +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)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT row_number() OVER (ORDER BY p <-> '0,0') AS n, p <-> '0,0' AS dist, p ..." +== 069 +-- truncate_limit: 100 +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)' +-- +TABLE: name="quad_point_tbl_ord_idx2" schema="" table="quad_point_tbl_ord_idx2" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_point_tbl_ord_idx2 AS SELECT row_number() OVER (ORDER BY p <-> '0,0')..." +== 070 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl_ord_seq2" schema="" table="quad_point_tbl_ord_seq2" ctx=Select +TABLE: name="quad_point_tbl_ord_idx2" schema="" table="quad_point_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="quad_point_tbl_ord_idx2" +ALIAS: "seq"="quad_point_tbl_ord_seq2" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN quad_point_tbl_ord_idx2 idx ON seq.n = idx.n ..." +== 071 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT row_number() OVER (ORDER BY p <-> '333,400') AS n, p <-> '333,400' AS ..." +== 072 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl_ord_idx3" schema="" table="quad_point_tbl_ord_idx3" ctx=DDL +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_point_tbl_ord_idx3 AS SELECT row_number() OVER (ORDER BY p <-> '333,4..." +== 073 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl_ord_seq3" schema="" table="quad_point_tbl_ord_seq3" ctx=Select +TABLE: name="quad_point_tbl_ord_idx3" schema="" table="quad_point_tbl_ord_idx3" ctx=Select +ALIAS: "idx"="quad_point_tbl_ord_idx3" +ALIAS: "seq"="quad_point_tbl_ord_seq3" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN quad_point_tbl_ord_idx3 idx ON seq.n = idx.n ..." +== 074 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 075 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 076 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 077 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 078 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'" +== 079 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'" +== 080 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'" +== 081 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'" +== 082 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'" +== 083 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'" +== 084 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'" +== 085 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'" +== 086 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'" +== 087 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'" +== 088 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT row_number() OVER (ORDER BY p <-> '0,0') AS n, p <-> '0,0' AS dist, p ..." +== 089 +-- truncate_limit: 100 +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 +-- +TABLE: name="kd_point_tbl_ord_idx1" schema="" table="kd_point_tbl_ord_idx1" ctx=DDL +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE kd_point_tbl_ord_idx1 AS SELECT row_number() OVER (ORDER BY p <-> '0,0') A..." +== 090 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +TABLE: name="kd_point_tbl_ord_idx1" schema="" table="kd_point_tbl_ord_idx1" ctx=Select +ALIAS: "idx"="kd_point_tbl_ord_idx1" +ALIAS: "seq"="quad_point_tbl_ord_seq1" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN kd_point_tbl_ord_idx1 idx ON seq.n = idx.n WH..." +== 091 +-- truncate_limit: 100 +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)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT row_number() OVER (ORDER BY p <-> '0,0') AS n, p <-> '0,0' AS dist, p ..." +== 092 +-- truncate_limit: 100 +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)' +-- +TABLE: name="kd_point_tbl_ord_idx2" schema="" table="kd_point_tbl_ord_idx2" ctx=DDL +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE kd_point_tbl_ord_idx2 AS SELECT row_number() OVER (ORDER BY p <-> '0,0') A..." +== 093 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl_ord_seq2" schema="" table="quad_point_tbl_ord_seq2" ctx=Select +TABLE: name="kd_point_tbl_ord_idx2" schema="" table="kd_point_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="kd_point_tbl_ord_idx2" +ALIAS: "seq"="quad_point_tbl_ord_seq2" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN kd_point_tbl_ord_idx2 idx ON seq.n = idx.n WH..." +== 094 +-- truncate_limit: 100 +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 +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT row_number() OVER (ORDER BY p <-> '333,400') AS n, p <-> '333,400' AS ..." +== 095 +-- truncate_limit: 100 +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 +-- +TABLE: name="kd_point_tbl_ord_idx3" schema="" table="kd_point_tbl_ord_idx3" ctx=DDL +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE kd_point_tbl_ord_idx3 AS SELECT row_number() OVER (ORDER BY p <-> '333,400..." +== 096 +-- truncate_limit: 100 +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 +-- +TABLE: name="quad_point_tbl_ord_seq3" schema="" table="quad_point_tbl_ord_seq3" ctx=Select +TABLE: name="kd_point_tbl_ord_idx3" schema="" table="kd_point_tbl_ord_idx3" ctx=Select +ALIAS: "idx"="kd_point_tbl_ord_idx3" +ALIAS: "seq"="quad_point_tbl_ord_seq3" +FILTER: schema="" table="seq" column="dist" +FILTER: schema="" table="idx" column="dist" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN kd_point_tbl_ord_idx3 idx ON seq.n = idx.n WH..." +== 097 +-- truncate_limit: 100 +-- test KNN scan with included columns +-- the distance numbers are not exactly the same across platforms +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO 0" +== 098 +-- truncate_limit: 100 +CREATE INDEX ON quad_point_tbl_ord_seq1 USING spgist(p) INCLUDE(dist) +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON quad_point_tbl_ord_seq1 USING spgist (p) INCLUDE (dist)" +== 099 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10" +== 100 +-- truncate_limit: 100 +SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10 +-- +TABLE: name="quad_point_tbl_ord_seq1" schema="" table="quad_point_tbl_ord_seq1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10" +== 101 +-- truncate_limit: 100 +RESET extra_float_digits +-- +STMT: VariableSetStmt +TRUNCATED: "RESET extra_float_digits" +== 102 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) pts(pt)" +== 103 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'" +== 104 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'" +== 105 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'" +== 106 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'" +== 107 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'" +== 108 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'" +== 109 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec ..." +== 110 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '" +== 111 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec ..." +== 112 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '" +== 113 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec ..." +== 114 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '" +== 115 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec ..." +== 116 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '" +== 117 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec ..." +== 118 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '" +== 119 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth ..." +== 120 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '" +== 121 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth ..." +== 122 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '" +== 123 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth ..." +== 124 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '" +== 125 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth ..." +== 126 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '" +== 127 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth ..." +== 128 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '" +== 129 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'" +== 130 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'" +== 131 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth')" +== 132 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth')" +== 133 +-- truncate_limit: 100 +-- Now check the results from bitmap indexscan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 134 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 135 +-- truncate_limit: 100 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 136 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p IS NULL" +== 137 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p IS NULL" +== 138 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL" +== 139 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL" +== 140 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl" +== 141 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl" +== 142 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 143 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 144 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 145 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 146 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'" +== 147 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'" +== 148 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'" +== 149 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'" +== 150 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'" +== 151 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'" +== 152 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'" +== 153 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'" +== 154 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'" +== 155 +-- truncate_limit: 100 +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="quad_point_tbl" schema="" table="quad_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'" +== 156 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 157 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p <@ '(200,200,1000,1000)'::box" +== 158 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 159 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE '(200,200,1000,1000)'::box @> p" +== 160 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'" +== 161 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'" +== 162 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'" +== 163 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'" +== 164 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'" +== 165 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'" +== 166 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'" +== 167 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'" +== 168 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'" +== 169 +-- truncate_limit: 100 +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)' +-- +TABLE: name="kd_point_tbl" schema="" table="kd_point_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'" +== 170 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'" +== 171 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'" +== 172 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'" +== 173 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'" +== 174 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'" +== 175 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'" +== 176 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec ..." +== 177 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '" +== 178 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec ..." +== 179 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '" +== 180 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec ..." +== 181 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '" +== 182 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec ..." +== 183 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '" +== 184 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec ..." +== 185 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '" +== 186 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth ..." +== 187 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '" +== 188 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth ..." +== 189 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '" +== 190 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth ..." +== 191 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '" +== 192 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth ..." +== 193 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '" +== 194 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth ..." +== 195 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '" +== 196 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'" +== 197 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth' +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'" +== 198 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth')" +== 199 +-- truncate_limit: 100 +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth') +-- +TABLE: name="radix_text_tbl" schema="" table="radix_text_tbl" ctx=Select +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="starts_with" function="starts_with" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth')" +== 200 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 201 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 202 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json new file mode 100644 index 0000000..aa15346 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json @@ -0,0 +1,92 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_misc.test b/parser/testdata/summary_truncate/postgres_regress/create_misc.test new file mode 100644 index 0000000..8a672f0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_misc.test @@ -0,0 +1,764 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_MISC +|-- + +|-- +-- a is the type root +-- b and c inherit from a (one-level single inheritance) +-- d inherits from b and c (two-level multiple inheritance) +-- e inherits from c (two-level single inheritance) +-- f inherits from e (three-level single inheritance) +|-- +CREATE TABLE a_star ( + class char, + a int4 +) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE a_star (class char(1), a int4)" +== 002 +-- truncate_limit: 100 +CREATE TABLE b_star ( + b text +) INHERITS (a_star) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE b_star (b text) INHERITS (a_star)" +== 003 +-- truncate_limit: 100 +CREATE TABLE c_star ( + c name +) INHERITS (a_star) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c_star (c name) INHERITS (a_star)" +== 004 +-- truncate_limit: 100 +CREATE TABLE d_star ( + d float8 +) INHERITS (b_star, c_star) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE d_star (d float8) INHERITS (b_star, c_star)" +== 005 +-- truncate_limit: 100 +CREATE TABLE e_star ( + e int2 +) INHERITS (c_star) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE e_star (e int2) INHERITS (c_star)" +== 006 +-- truncate_limit: 100 +CREATE TABLE f_star ( + f polygon +) INHERITS (e_star) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE f_star (f polygon) INHERITS (e_star)" +== 007 +-- truncate_limit: 100 +INSERT INTO a_star (class, a) VALUES ('a', 1) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a_star (class, a) VALUES ('a', 1)" +== 008 +-- truncate_limit: 100 +INSERT INTO a_star (class, a) VALUES ('a', 2) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a_star (class, a) VALUES ('a', 2)" +== 009 +-- truncate_limit: 100 +INSERT INTO a_star (class) VALUES ('a') +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a_star (class) VALUES ('a')" +== 010 +-- truncate_limit: 100 +INSERT INTO b_star (class, a, b) VALUES ('b', 3, 'mumble'::text) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b_star (class, a, b) VALUES ('b', 3, 'mumble'::text)" +== 011 +-- truncate_limit: 100 +INSERT INTO b_star (class, a) VALUES ('b', 4) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b_star (class, a) VALUES ('b', 4)" +== 012 +-- truncate_limit: 100 +INSERT INTO b_star (class, b) VALUES ('b', 'bumble'::text) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b_star (class, b) VALUES ('b', 'bumble'::text)" +== 013 +-- truncate_limit: 100 +INSERT INTO b_star (class) VALUES ('b') +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b_star (class) VALUES ('b')" +== 014 +-- truncate_limit: 100 +INSERT INTO c_star (class, a, c) VALUES ('c', 5, 'hi mom'::name) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c_star (class, a, c) VALUES ('c', 5, 'hi mom'::name)" +== 015 +-- truncate_limit: 100 +INSERT INTO c_star (class, a) VALUES ('c', 6) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c_star (class, a) VALUES ('c', 6)" +== 016 +-- truncate_limit: 100 +INSERT INTO c_star (class, c) VALUES ('c', 'hi paul'::name) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c_star (class, c) VALUES ('c', 'hi paul'::name)" +== 017 +-- truncate_limit: 100 +INSERT INTO c_star (class) VALUES ('c') +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c_star (class) VALUES ('c')" +== 018 +-- truncate_limit: 100 +INSERT INTO d_star (class, a, b, c, d) + VALUES ('d', 7, 'grumble'::text, 'hi sunita'::name, '0.0'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a, b, c, d) VALUES (...)" +== 019 +-- truncate_limit: 100 +INSERT INTO d_star (class, a, b, c) + VALUES ('d', 8, 'stumble'::text, 'hi koko'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a, b, c) VALUES ('d', 8, 'stumble'::text, 'hi koko'::name)" +== 020 +-- truncate_limit: 100 +INSERT INTO d_star (class, a, b, d) + VALUES ('d', 9, 'rumble'::text, '1.1'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a, b, d) VALUES ('d', 9, 'rumble'::text, '1.1'::float8)" +== 021 +-- truncate_limit: 100 +INSERT INTO d_star (class, a, c, d) + VALUES ('d', 10, 'hi kristin'::name, '10.01'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a, c, d) VALUES ('d', 10, 'hi kristin'::name, '10.01'::float8)" +== 022 +-- truncate_limit: 100 +INSERT INTO d_star (class, b, c, d) + VALUES ('d', 'crumble'::text, 'hi boris'::name, '100.001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, b, c, d) VALUES (...)" +== 023 +-- truncate_limit: 100 +INSERT INTO d_star (class, a, b) + VALUES ('d', 11, 'fumble'::text) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a, b) VALUES ('d', 11, 'fumble'::text)" +== 024 +-- truncate_limit: 100 +INSERT INTO d_star (class, a, c) + VALUES ('d', 12, 'hi avi'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a, c) VALUES ('d', 12, 'hi avi'::name)" +== 025 +-- truncate_limit: 100 +INSERT INTO d_star (class, a, d) + VALUES ('d', 13, '1000.0001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a, d) VALUES ('d', 13, '1000.0001'::float8)" +== 026 +-- truncate_limit: 100 +INSERT INTO d_star (class, b, c) + VALUES ('d', 'tumble'::text, 'hi andrew'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, b, c) VALUES ('d', 'tumble'::text, 'hi andrew'::name)" +== 027 +-- truncate_limit: 100 +INSERT INTO d_star (class, b, d) + VALUES ('d', 'humble'::text, '10000.00001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, b, d) VALUES ('d', 'humble'::text, '10000.00001'::float8)" +== 028 +-- truncate_limit: 100 +INSERT INTO d_star (class, c, d) + VALUES ('d', 'hi ginger'::name, '100000.000001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, c, d) VALUES ('d', 'hi ginger'::name, '100000.000001'::float8)" +== 029 +-- truncate_limit: 100 +INSERT INTO d_star (class, a) VALUES ('d', 14) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, a) VALUES ('d', 14)" +== 030 +-- truncate_limit: 100 +INSERT INTO d_star (class, b) VALUES ('d', 'jumble'::text) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, b) VALUES ('d', 'jumble'::text)" +== 031 +-- truncate_limit: 100 +INSERT INTO d_star (class, c) VALUES ('d', 'hi jolly'::name) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, c) VALUES ('d', 'hi jolly'::name)" +== 032 +-- truncate_limit: 100 +INSERT INTO d_star (class, d) VALUES ('d', '1000000.0000001'::float8) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class, d) VALUES ('d', '1000000.0000001'::float8)" +== 033 +-- truncate_limit: 100 +INSERT INTO d_star (class) VALUES ('d') +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d_star (class) VALUES ('d')" +== 034 +-- truncate_limit: 100 +INSERT INTO e_star (class, a, c, e) + VALUES ('e', 15, 'hi carol'::name, '-1'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO e_star (class, a, c, e) VALUES ('e', 15, 'hi carol'::name, '-1'::int2)" +== 035 +-- truncate_limit: 100 +INSERT INTO e_star (class, a, c) + VALUES ('e', 16, 'hi bob'::name) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO e_star (class, a, c) VALUES ('e', 16, 'hi bob'::name)" +== 036 +-- truncate_limit: 100 +INSERT INTO e_star (class, a, e) + VALUES ('e', 17, '-2'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO e_star (class, a, e) VALUES ('e', 17, '-2'::int2)" +== 037 +-- truncate_limit: 100 +INSERT INTO e_star (class, c, e) + VALUES ('e', 'hi michelle'::name, '-3'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO e_star (class, c, e) VALUES ('e', 'hi michelle'::name, '-3'::int2)" +== 038 +-- truncate_limit: 100 +INSERT INTO e_star (class, a) + VALUES ('e', 18) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO e_star (class, a) VALUES ('e', 18)" +== 039 +-- truncate_limit: 100 +INSERT INTO e_star (class, c) + VALUES ('e', 'hi elisa'::name) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO e_star (class, c) VALUES ('e', 'hi elisa'::name)" +== 040 +-- truncate_limit: 100 +INSERT INTO e_star (class, e) + VALUES ('e', '-4'::int2) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO e_star (class, e) VALUES ('e', '-4'::int2)" +== 041 +-- truncate_limit: 100 +INSERT INTO f_star (class, a, c, e, f) + VALUES ('f', 19, 'hi claire'::name, '-5'::int2, '(1,3),(2,4)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a, c, e, f) VALUES (...)" +== 042 +-- truncate_limit: 100 +INSERT INTO f_star (class, a, c, e) + VALUES ('f', 20, 'hi mike'::name, '-6'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a, c, e) VALUES ('f', 20, 'hi mike'::name, '-6'::int2)" +== 043 +-- truncate_limit: 100 +INSERT INTO f_star (class, a, c, f) + VALUES ('f', 21, 'hi marcel'::name, '(11,44),(22,55),(33,66)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a, c, f) VALUES (...)" +== 044 +-- truncate_limit: 100 +INSERT INTO f_star (class, a, e, f) + VALUES ('f', 22, '-7'::int2, '(111,555),(222,666),(333,777),(444,888)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a, e, f) VALUES (...)" +== 045 +-- truncate_limit: 100 +INSERT INTO f_star (class, c, e, f) + VALUES ('f', 'hi keith'::name, '-8'::int2, + '(1111,3333),(2222,4444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, c, e, f) VALUES (...)" +== 046 +-- truncate_limit: 100 +INSERT INTO f_star (class, a, c) + VALUES ('f', 24, 'hi marc'::name) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a, c) VALUES ('f', 24, 'hi marc'::name)" +== 047 +-- truncate_limit: 100 +INSERT INTO f_star (class, a, e) + VALUES ('f', 25, '-9'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a, e) VALUES ('f', 25, '-9'::int2)" +== 048 +-- truncate_limit: 100 +INSERT INTO f_star (class, a, f) + VALUES ('f', 26, '(11111,33333),(22222,44444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a, f) VALUES ('f', 26, '(11111,33333),(22222,44444)'::polygon)" +== 049 +-- truncate_limit: 100 +INSERT INTO f_star (class, c, e) + VALUES ('f', 'hi allison'::name, '-10'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, c, e) VALUES ('f', 'hi allison'::name, '-10'::int2)" +== 050 +-- truncate_limit: 100 +INSERT INTO f_star (class, c, f) + VALUES ('f', 'hi jeff'::name, + '(111111,333333),(222222,444444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, c, f) VALUES (...)" +== 051 +-- truncate_limit: 100 +INSERT INTO f_star (class, e, f) + VALUES ('f', '-11'::int2, '(1111111,3333333),(2222222,4444444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, e, f) VALUES (...)" +== 052 +-- truncate_limit: 100 +INSERT INTO f_star (class, a) VALUES ('f', 27) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, a) VALUES ('f', 27)" +== 053 +-- truncate_limit: 100 +INSERT INTO f_star (class, c) VALUES ('f', 'hi carl'::name) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, c) VALUES ('f', 'hi carl'::name)" +== 054 +-- truncate_limit: 100 +INSERT INTO f_star (class, e) VALUES ('f', '-12'::int2) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, e) VALUES ('f', '-12'::int2)" +== 055 +-- truncate_limit: 100 +INSERT INTO f_star (class, f) + VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class, f) VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon)" +== 056 +-- truncate_limit: 100 +INSERT INTO f_star (class) VALUES ('f') +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO f_star (class) VALUES ('f')" +== 057 +-- truncate_limit: 100 +-- Analyze the X_star tables for better plan stability in later tests +ANALYZE a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE a_star" +== 058 +-- truncate_limit: 100 +ANALYZE b_star +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE b_star" +== 059 +-- truncate_limit: 100 +ANALYZE c_star +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE c_star" +== 060 +-- truncate_limit: 100 +ANALYZE d_star +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE d_star" +== 061 +-- truncate_limit: 100 +ANALYZE e_star +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE e_star" +== 062 +-- truncate_limit: 100 +ANALYZE f_star +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE f_star" +== 063 +-- truncate_limit: 100 +|-- +-- inheritance stress test +|-- +SELECT * FROM a_star* +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM a_star" +== 064 +-- truncate_limit: 100 +SELECT * + FROM b_star* x + WHERE x.b = text 'bumble' or x.a < 3 +-- +TABLE: name="b_star" schema="" table="b_star" ctx=Select +ALIAS: "x"="b_star" +FILTER: schema="" table="x" column="b" +FILTER: schema="" table="x" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM b_star x WHERE x.b = 'bumble'::text OR x.a < 3" +== 065 +-- truncate_limit: 100 +SELECT class, a + FROM c_star* x + WHERE x.c ~ text 'hi' +-- +TABLE: name="c_star" schema="" table="c_star" ctx=Select +ALIAS: "x"="c_star" +FILTER: schema="" table="x" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT class, a FROM c_star x WHERE x.c ~ 'hi'::text" +== 066 +-- truncate_limit: 100 +SELECT class, b, c + FROM d_star* x + WHERE x.a < 100 +-- +TABLE: name="d_star" schema="" table="d_star" ctx=Select +ALIAS: "x"="d_star" +FILTER: schema="" table="x" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT class, b, c FROM d_star x WHERE x.a < 100" +== 067 +-- truncate_limit: 100 +SELECT class, c FROM e_star* x WHERE x.c NOTNULL +-- +TABLE: name="e_star" schema="" table="e_star" ctx=Select +ALIAS: "x"="e_star" +FILTER: schema="" table="x" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT class, c FROM e_star x WHERE x.c IS NOT NULL" +== 068 +-- truncate_limit: 100 +SELECT * FROM f_star* x WHERE x.c ISNULL +-- +TABLE: name="f_star" schema="" table="f_star" ctx=Select +ALIAS: "x"="f_star" +FILTER: schema="" table="x" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM f_star x WHERE x.c IS NULL" +== 069 +-- truncate_limit: 100 +-- grouping and aggregation on inherited sets have been busted in the past... + +SELECT sum(a) FROM a_star* +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(a) FROM a_star" +== 070 +-- truncate_limit: 100 +SELECT class, sum(a) FROM a_star* GROUP BY class ORDER BY class +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT class, sum(a) FROM a_star GROUP BY class ORDER BY class" +== 071 +-- truncate_limit: 100 +ALTER TABLE f_star RENAME COLUMN f TO ff +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE f_star RENAME COLUMN f TO ff" +== 072 +-- truncate_limit: 100 +ALTER TABLE e_star* RENAME COLUMN e TO ee +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE e_star RENAME COLUMN e TO ee" +== 073 +-- truncate_limit: 100 +ALTER TABLE d_star* RENAME COLUMN d TO dd +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE d_star RENAME COLUMN d TO dd" +== 074 +-- truncate_limit: 100 +ALTER TABLE c_star* RENAME COLUMN c TO cc +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE c_star RENAME COLUMN c TO cc" +== 075 +-- truncate_limit: 100 +ALTER TABLE b_star* RENAME COLUMN b TO bb +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE b_star RENAME COLUMN b TO bb" +== 076 +-- truncate_limit: 100 +ALTER TABLE a_star* RENAME COLUMN a TO aa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE a_star RENAME COLUMN a TO aa" +== 077 +-- truncate_limit: 100 +SELECT class, aa + FROM a_star* x + WHERE aa ISNULL +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "x"="a_star" +FILTER: schema="" table="" column="aa" +STMT: SelectStmt +TRUNCATED: "SELECT class, aa FROM a_star x WHERE aa IS NULL" +== 078 +-- truncate_limit: 100 +-- As of Postgres 7.1, ALTER implicitly recurses, +-- so this should be same as ALTER a_star* + +ALTER TABLE a_star RENAME COLUMN aa TO foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE a_star RENAME COLUMN aa TO foo" +== 079 +-- truncate_limit: 100 +SELECT class, foo + FROM a_star* x + WHERE x.foo >= 2 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "x"="a_star" +FILTER: schema="" table="x" column="foo" +STMT: SelectStmt +TRUNCATED: "SELECT class, foo FROM a_star x WHERE x.foo >= 2" +== 080 +-- truncate_limit: 100 +ALTER TABLE a_star RENAME COLUMN foo TO aa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE a_star RENAME COLUMN foo TO aa" +== 081 +-- truncate_limit: 100 +SELECT * + from a_star* + WHERE aa < 1000 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FILTER: schema="" table="" column="aa" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM a_star WHERE aa < 1000" +== 082 +-- truncate_limit: 100 +ALTER TABLE f_star ADD COLUMN f int4 +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE f_star ADD COLUMN f int4" +== 083 +-- truncate_limit: 100 +UPDATE f_star SET f = 10 +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE f_star SET f = 10" +== 084 +-- truncate_limit: 100 +ALTER TABLE e_star* ADD COLUMN e int4 +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE e_star ADD COLUMN e int4" +== 085 +-- truncate_limit: 100 +--UPDATE e_star* SET e = 42; + +SELECT * FROM e_star* +-- +TABLE: name="e_star" schema="" table="e_star" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM e_star" +== 086 +-- truncate_limit: 100 +ALTER TABLE a_star* ADD COLUMN a text +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE a_star ADD COLUMN a text" +== 087 +-- truncate_limit: 100 +-- That ALTER TABLE should have added TOAST tables. +SELECT relname, reltoastrelid <> 0 AS has_toast_table + FROM pg_class + WHERE oid::regclass IN ('a_star', 'c_star') + ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class WHERE oid::regclass IN ('a_star', 'c_star') ORDER BY 1" +== 088 +-- truncate_limit: 100 +--UPDATE b_star* +-- SET a = text 'gazpacho' +-- WHERE aa > 4; + +SELECT class, aa, a FROM a_star* +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT class, aa, a FROM a_star" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json new file mode 100644 index 0000000..44e163a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json @@ -0,0 +1,94 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_operator.test b/parser/testdata/summary_truncate/postgres_regress/create_operator.test new file mode 100644 index 0000000..52b5429 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_operator.test @@ -0,0 +1,708 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_OPERATOR +|-- + +CREATE OPERATOR ## ( + leftarg = path, + rightarg = path, + function = path_inter, + commutator = ## +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR ## (leftarg = path, rightarg = path, function = path_inter, commutator = ##)" +== 002 +-- truncate_limit: 100 +CREATE OPERATOR @#@ ( + rightarg = int8, -- prefix + procedure = factorial +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR @#@ (rightarg = int8, procedure = factorial)" +== 003 +-- truncate_limit: 100 +CREATE OPERATOR #%# ( + leftarg = int8, -- fail, postfix is no longer supported + procedure = factorial +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #%# (leftarg = int8, procedure = factorial)" +== 004 +-- truncate_limit: 100 +-- Test operator created above +SELECT @#@ 24 +-- +STMT: SelectStmt +TRUNCATED: "SELECT @#@ 24" +== 005 +-- truncate_limit: 100 +-- Test comments +COMMENT ON OPERATOR ###### (NONE, int4) IS 'bad prefix' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON OPERATOR ######(NONE, int4) IS 'bad prefix'" +== 006 +-- truncate_limit: 100 +COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad postfix' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON OPERATOR ######(int4, NONE) IS 'bad postfix'" +== 007 +-- truncate_limit: 100 +COMMENT ON OPERATOR ###### (int4, int8) IS 'bad infix' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON OPERATOR ######(int4, int8) IS 'bad infix'" +== 008 +-- truncate_limit: 100 +-- Check that DROP on a nonexistent op behaves sanely, too +DROP OPERATOR ###### (NONE, int4) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ######(NONE, int4)" +== 009 +-- truncate_limit: 100 +DROP OPERATOR ###### (int4, NONE) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ######(int4, NONE)" +== 010 +-- truncate_limit: 100 +DROP OPERATOR ###### (int4, int8) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ######(int4, int8)" +== 011 +-- truncate_limit: 100 +-- => is disallowed as an operator name now +CREATE OPERATOR => ( + rightarg = int8, + procedure = factorial +) +-- +ERROR: syntax error at or near "=>" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- truncate_limit: 100 +-- lexing of <=, >=, <>, != has a number of edge cases +-- (=> is tested elsewhere) + +-- this is legal because ! is not allowed in sql ops +CREATE OPERATOR !=- ( + rightarg = int8, + procedure = factorial +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR !=- (rightarg = int8, procedure = factorial)" +== 013 +-- truncate_limit: 100 +SELECT !=- 10 +-- +STMT: SelectStmt +TRUNCATED: "SELECT !=- 10" +== 014 +-- truncate_limit: 100 +-- postfix operators don't work anymore +SELECT 10 !=- +-- +ERROR: syntax error at end of input +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 015 +-- truncate_limit: 100 +-- make sure lexer returns != as <> even in edge cases +SELECT 2 !=/**/ 1, 2 !=/**/ 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 <> 1, 2 <> 2" +== 016 +-- truncate_limit: 100 +SELECT 2 !=-- comment to be removed by psql + 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 <> 1" +== 017 +-- truncate_limit: 100 +DO $$ -- use DO to protect -- from psql + declare r boolean; + begin + execute $e$ select 2 !=-- comment + 1 $e$ into r; + raise info 'r = %', r; + end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$ -- use DO to protect -- from psql\n declare r boolean;\n begin\n execute $e$ select 2 !=-..." +== 018 +-- truncate_limit: 100 +-- check that <= etc. followed by more operator characters are returned +-- as the correct token with correct precedence +SELECT true<>-1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT true <> (-1 BETWEEN 1 AND 1)" +== 019 +-- truncate_limit: 100 +-- BETWEEN has prec. above <> but below Op +SELECT false<>/**/1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT false <> (1 BETWEEN 1 AND 1)" +== 020 +-- truncate_limit: 100 +SELECT false<=-1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT false <= (-1 BETWEEN 1 AND 1)" +== 021 +-- truncate_limit: 100 +SELECT false>=-1 BETWEEN 1 AND 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT false >= (-1 BETWEEN 1 AND 1)" +== 022 +-- truncate_limit: 100 +SELECT 2<=/**/3, 3>=/**/2, 2<>/**/3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 <= 3, 3 >= 2, 2 <> 3" +== 023 +-- truncate_limit: 100 +SELECT 3<=/**/2, 2>=/**/3, 2<>/**/2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3 <= 2, 2 >= 3, 2 <> 2" +== 024 +-- truncate_limit: 100 +-- Should fail. CREATE OPERATOR requires USAGE on SCHEMA +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 025 +-- truncate_limit: 100 +CREATE ROLE regress_rol_op1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rol_op1" +== 026 +-- truncate_limit: 100 +CREATE SCHEMA schema_op1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA schema_op1" +== 027 +-- truncate_limit: 100 +GRANT USAGE ON SCHEMA schema_op1 TO PUBLIC +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON SCHEMA schema_op1 TO public" +== 028 +-- truncate_limit: 100 +REVOKE USAGE ON SCHEMA schema_op1 FROM regress_rol_op1 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON SCHEMA schema_op1 FROM regress_rol_op1" +== 029 +-- truncate_limit: 100 +SET ROLE regress_rol_op1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_op1" +== 030 +-- truncate_limit: 100 +CREATE OPERATOR schema_op1.#*# ( + rightarg = int8, + procedure = factorial +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR schema_op1.#*# (rightarg = int8, procedure = factorial)" +== 031 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 032 +-- truncate_limit: 100 +-- Should fail. SETOF type functions not allowed as argument (testing leftarg) +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 033 +-- truncate_limit: 100 +CREATE OPERATOR #*# ( + leftarg = SETOF int8, + procedure = factorial +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #*# (leftarg = SETOF int8, procedure = factorial)" +== 034 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 035 +-- truncate_limit: 100 +-- Should fail. SETOF type functions not allowed as argument (testing rightarg) +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 036 +-- truncate_limit: 100 +CREATE OPERATOR #*# ( + rightarg = SETOF int8, + procedure = factorial +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #*# (rightarg = SETOF int8, procedure = factorial)" +== 037 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 038 +-- truncate_limit: 100 +-- Should work. Sample text-book case +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 039 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION fn_op2(boolean, boolean) +RETURNS boolean AS $$ + SELECT NULL::BOOLEAN; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op2" function="fn_op2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION fn_op2(boolean, boolean) RETURNS boolean AS $$\n SELECT NULL::BOOLEA..." +== 040 +-- truncate_limit: 100 +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = boolean, + PROCEDURE = fn_op2, + COMMUTATOR = ===, + NEGATOR = !==, + RESTRICT = contsel, + JOIN = contjoinsel, + SORT1, SORT2, LTCMP, GTCMP, HASHES, MERGES +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = boolean, rightarg = boolean, procedure = fn_op2, commutator = ===,..." +== 041 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 042 +-- truncate_limit: 100 +-- Should fail. Invalid attribute +CREATE OPERATOR #@%# ( + rightarg = int8, + procedure = factorial, + invalid_att = int8 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #@%# (rightarg = int8, procedure = factorial, invalid_att = int8)" +== 043 +-- truncate_limit: 100 +-- Should fail. At least rightarg should be mandatorily specified +CREATE OPERATOR #@%# ( + procedure = factorial +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #@%# (procedure = factorial)" +== 044 +-- truncate_limit: 100 +-- Should fail. Procedure should be mandatorily specified +CREATE OPERATOR #@%# ( + rightarg = int8 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #@%# (rightarg = int8)" +== 045 +-- truncate_limit: 100 +-- Should fail. CREATE OPERATOR requires USAGE on TYPE +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 046 +-- truncate_limit: 100 +CREATE ROLE regress_rol_op3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rol_op3" +== 047 +-- truncate_limit: 100 +CREATE TYPE type_op3 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE type_op3 AS ENUM ('new', 'open', 'closed')" +== 048 +-- truncate_limit: 100 +CREATE FUNCTION fn_op3(type_op3, int8) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op3" function="fn_op3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_op3(type_op3, int8) RETURNS int8 AS $$\n SELECT NULL::int8;\n$$ LANGUAGE sql ..." +== 049 +-- truncate_limit: 100 +REVOKE USAGE ON TYPE type_op3 FROM regress_rol_op3 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE type_op3 FROM regress_rol_op3" +== 050 +-- truncate_limit: 100 +REVOKE USAGE ON TYPE type_op3 FROM PUBLIC +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE type_op3 FROM public" +== 051 +-- truncate_limit: 100 +-- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC +SET ROLE regress_rol_op3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_op3" +== 052 +-- truncate_limit: 100 +CREATE OPERATOR #*# ( + leftarg = type_op3, + rightarg = int8, + procedure = fn_op3 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #*# (leftarg = type_op3, rightarg = int8, procedure = fn_op3)" +== 053 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 054 +-- truncate_limit: 100 +-- Should fail. CREATE OPERATOR requires USAGE on TYPE (need to check separately for rightarg) +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 055 +-- truncate_limit: 100 +CREATE ROLE regress_rol_op4 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rol_op4" +== 056 +-- truncate_limit: 100 +CREATE TYPE type_op4 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE type_op4 AS ENUM ('new', 'open', 'closed')" +== 057 +-- truncate_limit: 100 +CREATE FUNCTION fn_op4(int8, type_op4) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op4" function="fn_op4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_op4(int8, type_op4) RETURNS int8 AS $$\n SELECT NULL::int8;\n$$ LANGUAGE sql ..." +== 058 +-- truncate_limit: 100 +REVOKE USAGE ON TYPE type_op4 FROM regress_rol_op4 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE type_op4 FROM regress_rol_op4" +== 059 +-- truncate_limit: 100 +REVOKE USAGE ON TYPE type_op4 FROM PUBLIC +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE type_op4 FROM public" +== 060 +-- truncate_limit: 100 +-- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC +SET ROLE regress_rol_op4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_op4" +== 061 +-- truncate_limit: 100 +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = type_op4, + procedure = fn_op4 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #*# (leftarg = int8, rightarg = type_op4, procedure = fn_op4)" +== 062 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 063 +-- truncate_limit: 100 +-- Should fail. CREATE OPERATOR requires EXECUTE on function +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 064 +-- truncate_limit: 100 +CREATE ROLE regress_rol_op5 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rol_op5" +== 065 +-- truncate_limit: 100 +CREATE TYPE type_op5 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE type_op5 AS ENUM ('new', 'open', 'closed')" +== 066 +-- truncate_limit: 100 +CREATE FUNCTION fn_op5(int8, int8) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op5" function="fn_op5" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_op5(int8, int8) RETURNS int8 AS $$\n SELECT NULL::int8;\n$$ LANGUAGE sql IMMU..." +== 067 +-- truncate_limit: 100 +REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM regress_rol_op5 +-- +FUNCTION: name="fn_op5" function="fn_op5" schema="" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE execute ON FUNCTION fn_op5(int8, int8) FROM regress_rol_op5" +== 068 +-- truncate_limit: 100 +REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM PUBLIC +-- +FUNCTION: name="fn_op5" function="fn_op5" schema="" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE execute ON FUNCTION fn_op5(int8, int8) FROM public" +== 069 +-- truncate_limit: 100 +-- Need to do this so that regress_rol_op3 is not allowed EXECUTE via PUBLIC +SET ROLE regress_rol_op5 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_op5" +== 070 +-- truncate_limit: 100 +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = int8, + procedure = fn_op5 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #*# (leftarg = int8, rightarg = int8, procedure = fn_op5)" +== 071 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 072 +-- truncate_limit: 100 +-- Should fail. CREATE OPERATOR requires USAGE on return TYPE +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 073 +-- truncate_limit: 100 +CREATE ROLE regress_rol_op6 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rol_op6" +== 074 +-- truncate_limit: 100 +CREATE TYPE type_op6 AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE type_op6 AS ENUM ('new', 'open', 'closed')" +== 075 +-- truncate_limit: 100 +CREATE FUNCTION fn_op6(int8, int8) +RETURNS type_op6 AS $$ + SELECT NULL::type_op6; +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="fn_op6" function="fn_op6" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn_op6(int8, int8) RETURNS type_op6 AS $$\n SELECT NULL::type_op6;\n$$ LANGUAGE ..." +== 076 +-- truncate_limit: 100 +REVOKE USAGE ON TYPE type_op6 FROM regress_rol_op6 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE type_op6 FROM regress_rol_op6" +== 077 +-- truncate_limit: 100 +REVOKE USAGE ON TYPE type_op6 FROM PUBLIC +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE type_op6 FROM public" +== 078 +-- truncate_limit: 100 +-- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC +SET ROLE regress_rol_op6 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_op6" +== 079 +-- truncate_limit: 100 +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = int8, + procedure = fn_op6 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR #*# (leftarg = int8, rightarg = int8, procedure = fn_op6)" +== 080 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 081 +-- truncate_limit: 100 +-- Should fail. An operator cannot be its own negator. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 082 +-- truncate_limit: 100 +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + negator = === +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = int, rightarg = int, procedure = int4eq, negator = ===)" +== 083 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 084 +-- truncate_limit: 100 +-- Should fail. An operator cannot be its own negator. Here we check that +-- this error is detected when replacing a shell operator. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 085 +-- truncate_limit: 100 +-- create a shell operator for ===!!! by referencing it as a commutator +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + commutator = ===!!! +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = int, rightarg = int, procedure = int4eq, commutator = ===!!!)" +== 086 +-- truncate_limit: 100 +CREATE OPERATOR ===!!! ( + leftarg = integer, + rightarg = integer, + procedure = int4ne, + negator = ===!!! +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR ===!!! (leftarg = int, rightarg = int, procedure = int4ne, negator = ===!!!)" +== 087 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 088 +-- truncate_limit: 100 +-- test that we can't use part of an existing commutator or negator pair +-- as a commutator or negator +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + commutator = = +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = int, rightarg = int, procedure = int4eq, commutator = =)" +== 089 +-- truncate_limit: 100 +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + negator = <> +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = int, rightarg = int, procedure = int4eq, negator = <>)" +== 090 +-- truncate_limit: 100 +-- invalid: non-lowercase quoted identifiers +CREATE OPERATOR === +( + "Leftarg" = box, + "Rightarg" = box, + "Procedure" = area_equal_function, + "Commutator" = ===, + "Negator" = !==, + "Restrict" = area_restriction_function, + "Join" = area_join_function, + "Hashes", + "Merges" +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (\"Leftarg\" = box, \"Rightarg\" = box, \"Procedure\" = area_equal_function, \"Commu..." diff --git a/parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json new file mode 100644 index 0000000..c169184 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json @@ -0,0 +1,113 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_procedure.test b/parser/testdata/summary_truncate/postgres_regress/create_procedure.test new file mode 100644 index 0000000..b3f8983 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_procedure.test @@ -0,0 +1,870 @@ +== 001 +-- truncate_limit: 100 +CALL nonexistent() +-- +FUNCTION: name="nonexistent" function="nonexistent" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL nonexistent()" +== 002 +-- truncate_limit: 100 +-- error +CALL random() +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL random()" +== 003 +-- truncate_limit: 100 +-- error + +CREATE FUNCTION cp_testfunc1(a int) RETURNS int LANGUAGE SQL AS $$ SELECT a $$ +-- +FUNCTION: name="cp_testfunc1" function="cp_testfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION cp_testfunc1(a int) RETURNS int LANGUAGE sql AS $$ SELECT a $$" +== 004 +-- truncate_limit: 100 +CREATE TABLE cp_test (a int, b text) +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cp_test (a int, b text)" +== 005 +-- truncate_limit: 100 +CREATE PROCEDURE ptest1(x text) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES (1, x); +$$ +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest1(x text) LANGUAGE sql AS $$\nINSERT INTO cp_test VALUES (1, x);\n$$" +== 006 +-- truncate_limit: 100 +SELECT pg_get_functiondef('ptest1'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('ptest1'::regproc)" +== 007 +-- truncate_limit: 100 +-- show only normal functions + +-- show only procedures + +SELECT ptest1('x') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ptest1('x')" +== 008 +-- truncate_limit: 100 +-- error +CALL ptest1('a') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest1('a')" +== 009 +-- truncate_limit: 100 +-- ok +CALL ptest1('xy' || 'zzy') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest1('xy' || 'zzy')" +== 010 +-- truncate_limit: 100 +-- ok, constant-folded arg +CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1)) +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +FUNCTION: name="substring" function="substring" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest1(\"substring\"(random()::numeric(20, 15)::text, 1, 1))" +== 011 +-- truncate_limit: 100 +-- ok, volatile arg + +SELECT * FROM cp_test ORDER BY b COLLATE "C" +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cp_test ORDER BY b COLLATE \"C\"" +== 012 +-- truncate_limit: 100 +-- SQL-standard body +CREATE PROCEDURE ptest1s(x text) +LANGUAGE SQL +BEGIN ATOMIC + INSERT INTO cp_test VALUES (1, x) +-- +ERROR: syntax error at end of input +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 013 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 014 +-- truncate_limit: 100 +SELECT pg_get_functiondef('ptest1s'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('ptest1s'::regproc)" +== 015 +-- truncate_limit: 100 +CALL ptest1s('b') +-- +FUNCTION: name="ptest1s" function="ptest1s" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest1s('b')" +== 016 +-- truncate_limit: 100 +SELECT * FROM cp_test ORDER BY b COLLATE "C" +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cp_test ORDER BY b COLLATE \"C\"" +== 017 +-- truncate_limit: 100 +-- utility functions currently not supported here +CREATE PROCEDURE ptestx() +LANGUAGE SQL +BEGIN ATOMIC + CREATE TABLE x (a int) +-- +ERROR: syntax error at end of input +CURSORPOS: 127 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 018 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 019 +-- truncate_limit: 100 +CREATE PROCEDURE ptest2() +LANGUAGE SQL +AS $$ +SELECT 5; +$$ +-- +FUNCTION: name="ptest2" function="ptest2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest2() LANGUAGE sql AS $$\nSELECT 5;\n$$" +== 020 +-- truncate_limit: 100 +CALL ptest2() +-- +FUNCTION: name="ptest2" function="ptest2" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest2()" +== 021 +-- truncate_limit: 100 +-- nested CALL +TRUNCATE cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE cp_test" +== 022 +-- truncate_limit: 100 +CREATE PROCEDURE ptest3(y text) +LANGUAGE SQL +AS $$ +CALL ptest1(y); +CALL ptest1($1); +$$ +-- +FUNCTION: name="ptest3" function="ptest3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest3(y text) LANGUAGE sql AS $$\nCALL ptest1(y);\nCALL ptest1($1);\n$$" +== 023 +-- truncate_limit: 100 +CALL ptest3('b') +-- +FUNCTION: name="ptest3" function="ptest3" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest3('b')" +== 024 +-- truncate_limit: 100 +SELECT * FROM cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cp_test" +== 025 +-- truncate_limit: 100 +-- output arguments + +CREATE PROCEDURE ptest4a(INOUT a int, INOUT b int) +LANGUAGE SQL +AS $$ +SELECT 1, 2; +$$ +-- +FUNCTION: name="ptest4a" function="ptest4a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest4a(INOUT a int, INOUT b int) LANGUAGE sql AS $$\nSELECT 1, 2;\n$$" +== 026 +-- truncate_limit: 100 +CALL ptest4a(NULL, NULL) +-- +FUNCTION: name="ptest4a" function="ptest4a" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest4a(NULL, NULL)" +== 027 +-- truncate_limit: 100 +CREATE PROCEDURE ptest4b(INOUT b int, INOUT a int) +LANGUAGE SQL +AS $$ +CALL ptest4a(a, b); -- error, not supported +$$ +-- +FUNCTION: name="ptest4b" function="ptest4b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest4b(INOUT b int, INOUT a int) LANGUAGE sql AS $$\nCALL ptest4a(a, b); -- err..." +== 028 +-- truncate_limit: 100 +-- we used to get confused by a single output argument that is composite +CREATE PROCEDURE ptest4c(INOUT comp int8_tbl) +LANGUAGE SQL +AS $$ +SELECT ROW(1, 2); +$$ +-- +FUNCTION: name="ptest4c" function="ptest4c" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest4c(INOUT comp int8_tbl) LANGUAGE sql AS $$\nSELECT ROW(1, 2);\n$$" +== 029 +-- truncate_limit: 100 +CALL ptest4c(NULL) +-- +FUNCTION: name="ptest4c" function="ptest4c" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest4c(NULL)" +== 030 +-- truncate_limit: 100 +DROP PROCEDURE ptest4a, ptest4c +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest4a, ptest4c" +== 031 +-- truncate_limit: 100 +-- named and default parameters + +CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int default 100) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES(a, b); +INSERT INTO cp_test VALUES(c, b); +$$ +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int = 100) LANGUAGE sql AS $$\nINSERT INTO cp_..." +== 032 +-- truncate_limit: 100 +TRUNCATE cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE cp_test" +== 033 +-- truncate_limit: 100 +CALL ptest5(10, 'Hello', 20) +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest5(10, 'Hello', 20)" +== 034 +-- truncate_limit: 100 +CALL ptest5(10, 'Hello') +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest5(10, 'Hello')" +== 035 +-- truncate_limit: 100 +CALL ptest5(10, b => 'Hello') +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest5(10, b := 'Hello')" +== 036 +-- truncate_limit: 100 +CALL ptest5(b => 'Hello', a => 10) +-- +FUNCTION: name="ptest5" function="ptest5" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest5(b := 'Hello', a := 10)" +== 037 +-- truncate_limit: 100 +SELECT * FROM cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cp_test" +== 038 +-- truncate_limit: 100 +-- polymorphic types + +CREATE PROCEDURE ptest6(a int, b anyelement) +LANGUAGE SQL +AS $$ +SELECT NULL::int; +$$ +-- +FUNCTION: name="ptest6" function="ptest6" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest6(a int, b anyelement) LANGUAGE sql AS $$\nSELECT NULL::int;\n$$" +== 039 +-- truncate_limit: 100 +CALL ptest6(1, 2) +-- +FUNCTION: name="ptest6" function="ptest6" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest6(1, 2)" +== 040 +-- truncate_limit: 100 +CREATE PROCEDURE ptest6a(inout a anyelement, out b anyelement) +LANGUAGE SQL +AS $$ +SELECT $1, $1; +$$ +-- +FUNCTION: name="ptest6a" function="ptest6a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest6a(INOUT a anyelement, OUT b anyelement) LANGUAGE sql AS $$\nSELECT $1, $1;\n$$" +== 041 +-- truncate_limit: 100 +CALL ptest6a(1, null) +-- +FUNCTION: name="ptest6a" function="ptest6a" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest6a(1, NULL)" +== 042 +-- truncate_limit: 100 +CALL ptest6a(1.1, null) +-- +FUNCTION: name="ptest6a" function="ptest6a" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest6a(1.1, NULL)" +== 043 +-- truncate_limit: 100 +CREATE PROCEDURE ptest6b(a anyelement, out b anyelement, out c anyarray) +LANGUAGE SQL +AS $$ +SELECT $1, array[$1]; +$$ +-- +FUNCTION: name="ptest6b" function="ptest6b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest6b(a anyelement, OUT b anyelement, OUT c anyarray) LANGUAGE sql AS $$\nSELEC..." +== 044 +-- truncate_limit: 100 +CALL ptest6b(1, null, null) +-- +FUNCTION: name="ptest6b" function="ptest6b" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest6b(1, NULL, NULL)" +== 045 +-- truncate_limit: 100 +CALL ptest6b(1.1, null, null) +-- +FUNCTION: name="ptest6b" function="ptest6b" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest6b(1.1, NULL, NULL)" +== 046 +-- truncate_limit: 100 +CREATE PROCEDURE ptest6c(inout a anyelement, inout b anyelement) +LANGUAGE SQL +AS $$ +SELECT $1, 1; +$$ +-- +FUNCTION: name="ptest6c" function="ptest6c" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest6c(INOUT a anyelement, INOUT b anyelement) LANGUAGE sql AS $$\nSELECT $1, 1;\n$$" +== 047 +-- truncate_limit: 100 +CALL ptest6c(1, null) +-- +FUNCTION: name="ptest6c" function="ptest6c" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest6c(1, NULL)" +== 048 +-- truncate_limit: 100 +CALL ptest6c(1.1, null) +-- +FUNCTION: name="ptest6c" function="ptest6c" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest6c(1.1, NULL)" +== 049 +-- truncate_limit: 100 +-- fails before v13 + + +-- collation assignment + +CREATE PROCEDURE ptest7(a text, b text) +LANGUAGE SQL +AS $$ +SELECT a = b; +$$ +-- +FUNCTION: name="ptest7" function="ptest7" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest7(a text, b text) LANGUAGE sql AS $$\nSELECT a = b;\n$$" +== 050 +-- truncate_limit: 100 +CALL ptest7(least('a', 'b'), 'a') +-- +FUNCTION: name="ptest7" function="ptest7" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest7(LEAST('a', 'b'), 'a')" +== 051 +-- truncate_limit: 100 +-- empty body +CREATE PROCEDURE ptest8(x text) +BEGIN ATOMIC +END +-- +FUNCTION: name="ptest8" function="ptest8" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest8(x text) BEGIN ATOMIC END" +== 052 +-- truncate_limit: 100 +SELECT pg_get_functiondef('ptest8'::regproc) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('ptest8'::regproc)" +== 053 +-- truncate_limit: 100 +CALL ptest8('') +-- +FUNCTION: name="ptest8" function="ptest8" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest8('')" +== 054 +-- truncate_limit: 100 +-- OUT parameters + +CREATE PROCEDURE ptest9(OUT a int) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES (1, 'a'); +SELECT 1; +$$ +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest9(OUT a int) LANGUAGE sql AS $$\nINSERT INTO cp_test VALUES (1, 'a');\nSELECT..." +== 055 +-- truncate_limit: 100 +-- standard way to do a call: +CALL ptest9(NULL) +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest9(NULL)" +== 056 +-- truncate_limit: 100 +-- you can write an expression, but it's not evaluated +CALL ptest9(1/0) +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest9(1 / 0)" +== 057 +-- truncate_limit: 100 +-- no error +-- ... and it had better match the type of the parameter +CALL ptest9(1./0.) +-- +FUNCTION: name="ptest9" function="ptest9" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest9(1. / 0.)" +== 058 +-- truncate_limit: 100 +-- error + +-- check named-parameter matching +CREATE PROCEDURE ptest10(OUT a int, IN b int, IN c int) +LANGUAGE SQL AS $$ SELECT b - c $$ +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest10(OUT a int, IN b int, IN c int) LANGUAGE sql AS $$ SELECT b - c $$" +== 059 +-- truncate_limit: 100 +CALL ptest10(null, 7, 4) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest10(NULL, 7, 4)" +== 060 +-- truncate_limit: 100 +CALL ptest10(a => null, b => 8, c => 2) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest10(a := NULL, b := 8, c := 2)" +== 061 +-- truncate_limit: 100 +CALL ptest10(null, 7, c => 2) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest10(NULL, 7, c := 2)" +== 062 +-- truncate_limit: 100 +CALL ptest10(null, c => 4, b => 11) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest10(NULL, c := 4, b := 11)" +== 063 +-- truncate_limit: 100 +CALL ptest10(b => 8, c => 2, a => 0) +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest10(b := 8, c := 2, a := 0)" +== 064 +-- truncate_limit: 100 +CREATE PROCEDURE ptest11(a OUT int, VARIADIC b int[]) LANGUAGE SQL + AS $$ SELECT b[1] + b[2] $$ +-- +FUNCTION: name="ptest11" function="ptest11" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest11(OUT a int, VARIADIC b int[]) LANGUAGE sql AS $$ SELECT b[1] + b[2] $$" +== 065 +-- truncate_limit: 100 +CALL ptest11(null, 11, 12, 13) +-- +FUNCTION: name="ptest11" function="ptest11" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest11(NULL, 11, 12, 13)" +== 066 +-- truncate_limit: 100 +-- check resolution of ambiguous DROP commands + +CREATE PROCEDURE ptest10(IN a int, IN b int, IN c int) +LANGUAGE SQL AS $$ SELECT a + b - c $$ +-- +FUNCTION: name="ptest10" function="ptest10" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptest10(IN a int, IN b int, IN c int) LANGUAGE sql AS $$ SELECT a + b - c $$" +== 067 +-- truncate_limit: 100 +drop procedure ptest10 +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest10" +== 068 +-- truncate_limit: 100 +-- fail +drop procedure ptest10(int, int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest10(int, int, int)" +== 069 +-- truncate_limit: 100 +-- fail +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 070 +-- truncate_limit: 100 +drop procedure ptest10(out int, int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest10(OUT int, int, int)" +== 071 +-- truncate_limit: 100 +drop procedure ptest10(int, int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest10(int, int, int)" +== 072 +-- truncate_limit: 100 +-- now this would work +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 073 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 074 +-- truncate_limit: 100 +drop procedure ptest10(in int, int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest10(IN int, int, int)" +== 075 +-- truncate_limit: 100 +drop procedure ptest10(int, int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest10(int, int, int)" +== 076 +-- truncate_limit: 100 +-- now this would work +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 077 +-- truncate_limit: 100 +-- various error cases + +CALL version() +-- +FUNCTION: name="version" function="version" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL version()" +== 078 +-- truncate_limit: 100 +-- error: not a procedure +CALL sum(1) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL sum(1)" +== 079 +-- truncate_limit: 100 +-- error: not a procedure + +CREATE PROCEDURE ptestx() LANGUAGE SQL WINDOW AS $$ INSERT INTO cp_test VALUES (1, 'a') $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptestx() LANGUAGE sql WINDOW AS $$ INSERT INTO cp_test VALUES (1, 'a') $$" +== 080 +-- truncate_limit: 100 +CREATE PROCEDURE ptestx() LANGUAGE SQL STRICT AS $$ INSERT INTO cp_test VALUES (1, 'a') $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptestx() LANGUAGE sql RETURNS NULL ON NULL INPUT AS $$ INSERT INTO cp_test VALUE..." +== 081 +-- truncate_limit: 100 +CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAGE SQL + AS $$ SELECT a[1] $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptestx(VARIADIC a int[], OUT b int) LANGUAGE sql AS $$ SELECT a[1] $$" +== 082 +-- truncate_limit: 100 +CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAGE SQL + AS $$ SELECT a $$ +-- +FUNCTION: name="ptestx" function="ptestx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE ptestx(a int = 42, OUT b int) LANGUAGE sql AS $$ SELECT a $$" +== 083 +-- truncate_limit: 100 +ALTER PROCEDURE ptest1(text) STRICT +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER PROCEDURE ptest1(text) RETURNS NULL ON NULL INPUT" +== 084 +-- truncate_limit: 100 +ALTER FUNCTION ptest1(text) VOLATILE +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION ptest1(text) VOLATILE" +== 085 +-- truncate_limit: 100 +-- error: not a function +ALTER PROCEDURE cp_testfunc1(int) VOLATILE +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER PROCEDURE cp_testfunc1(int) VOLATILE" +== 086 +-- truncate_limit: 100 +-- error: not a procedure +ALTER PROCEDURE nonexistent() VOLATILE +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER PROCEDURE nonexistent() VOLATILE" +== 087 +-- truncate_limit: 100 +DROP FUNCTION ptest1(text) +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION ptest1(text)" +== 088 +-- truncate_limit: 100 +-- error: not a function +DROP PROCEDURE cp_testfunc1(int) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE cp_testfunc1(int)" +== 089 +-- truncate_limit: 100 +-- error: not a procedure +DROP PROCEDURE nonexistent() +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE nonexistent()" +== 090 +-- truncate_limit: 100 +-- privileges + +CREATE USER regress_cp_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_cp_user1" +== 091 +-- truncate_limit: 100 +GRANT INSERT ON cp_test TO regress_cp_user1 +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON cp_test TO regress_cp_user1" +== 092 +-- truncate_limit: 100 +REVOKE EXECUTE ON PROCEDURE ptest1(text) FROM PUBLIC +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE execute ON PROCEDURE ptest1(text) FROM public" +== 093 +-- truncate_limit: 100 +SET ROLE regress_cp_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_cp_user1" +== 094 +-- truncate_limit: 100 +CALL ptest1('a') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest1('a')" +== 095 +-- truncate_limit: 100 +-- error +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 096 +-- truncate_limit: 100 +GRANT EXECUTE ON PROCEDURE ptest1(text) TO regress_cp_user1 +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT execute ON PROCEDURE ptest1(text) TO regress_cp_user1" +== 097 +-- truncate_limit: 100 +SET ROLE regress_cp_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_cp_user1" +== 098 +-- truncate_limit: 100 +CALL ptest1('a') +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL ptest1('a')" +== 099 +-- truncate_limit: 100 +-- ok +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 100 +-- truncate_limit: 100 +-- ROUTINE syntax + +ALTER ROUTINE cp_testfunc1(int) RENAME TO cp_testfunc1a +-- +FUNCTION: name="cp_testfunc1" function="cp_testfunc1" schema="" ctx=DDL +FUNCTION: name="cp_testfunc1a" function="cp_testfunc1a" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER ROUTINE cp_testfunc1(int) RENAME TO cp_testfunc1a" +== 101 +-- truncate_limit: 100 +ALTER ROUTINE cp_testfunc1a RENAME TO cp_testfunc1 +-- +FUNCTION: name="cp_testfunc1a" function="cp_testfunc1a" schema="" ctx=DDL +FUNCTION: name="cp_testfunc1" function="cp_testfunc1" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER ROUTINE cp_testfunc1a RENAME TO cp_testfunc1" +== 102 +-- truncate_limit: 100 +ALTER ROUTINE ptest1(text) RENAME TO ptest1a +-- +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +FUNCTION: name="ptest1a" function="ptest1a" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER ROUTINE ptest1(text) RENAME TO ptest1a" +== 103 +-- truncate_limit: 100 +ALTER ROUTINE ptest1a RENAME TO ptest1 +-- +FUNCTION: name="ptest1a" function="ptest1a" schema="" ctx=DDL +FUNCTION: name="ptest1" function="ptest1" schema="" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER ROUTINE ptest1a RENAME TO ptest1" +== 104 +-- truncate_limit: 100 +DROP ROUTINE cp_testfunc1(int) +-- +STMT: DropStmt +TRUNCATED: "DROP ROUTINE cp_testfunc1(int)" +== 105 +-- truncate_limit: 100 +-- cleanup + +DROP PROCEDURE ptest1 +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest1" +== 106 +-- truncate_limit: 100 +DROP PROCEDURE ptest1s +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest1s" +== 107 +-- truncate_limit: 100 +DROP PROCEDURE ptest2 +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE ptest2" +== 108 +-- truncate_limit: 100 +DROP TABLE cp_test +-- +TABLE: name="cp_test" schema="" table="cp_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cp_test" +== 109 +-- truncate_limit: 100 +DROP USER regress_cp_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_cp_user1" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json new file mode 100644 index 0000000..6835d4b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json @@ -0,0 +1,141 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_role.test b/parser/testdata/summary_truncate/postgres_regress/create_role.test new file mode 100644 index 0000000..3849444 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_role.test @@ -0,0 +1,883 @@ +== 001 +-- truncate_limit: 100 +-- ok, superuser can create users with any set of privileges +CREATE ROLE regress_role_super SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_role_super WITH SUPERUSER" +== 002 +-- truncate_limit: 100 +CREATE ROLE regress_role_admin CREATEDB CREATEROLE REPLICATION BYPASSRLS +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_role_admin WITH CREATEDB CREATEROLE REPLICATION BYPASSRLS" +== 003 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE regression TO regress_role_admin WITH GRANT OPTION +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_role_admin WITH GRANT OPTION" +== 004 +-- truncate_limit: 100 +CREATE ROLE regress_role_limited_admin CREATEROLE +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_role_limited_admin WITH CREATEROLE" +== 005 +-- truncate_limit: 100 +CREATE ROLE regress_role_normal +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_role_normal" +== 006 +-- truncate_limit: 100 +-- fail, CREATEROLE user can't give away role attributes without having them +SET SESSION AUTHORIZATION regress_role_limited_admin +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_role_limited_admin" +== 007 +-- truncate_limit: 100 +CREATE ROLE regress_nosuch_superuser SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_superuser WITH SUPERUSER" +== 008 +-- truncate_limit: 100 +CREATE ROLE regress_nosuch_replication_bypassrls REPLICATION BYPASSRLS +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_replication_bypassrls WITH REPLICATION BYPASSRLS" +== 009 +-- truncate_limit: 100 +CREATE ROLE regress_nosuch_replication REPLICATION +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_replication WITH REPLICATION" +== 010 +-- truncate_limit: 100 +CREATE ROLE regress_nosuch_bypassrls BYPASSRLS +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_bypassrls WITH BYPASSRLS" +== 011 +-- truncate_limit: 100 +CREATE ROLE regress_nosuch_createdb CREATEDB +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_createdb WITH CREATEDB" +== 012 +-- truncate_limit: 100 +-- ok, can create a role without any special attributes +CREATE ROLE regress_role_limited +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_role_limited" +== 013 +-- truncate_limit: 100 +-- fail, can't give it in any of the restricted attributes +ALTER ROLE regress_role_limited SUPERUSER +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_role_limited WITH SUPERUSER" +== 014 +-- truncate_limit: 100 +ALTER ROLE regress_role_limited REPLICATION +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_role_limited WITH REPLICATION" +== 015 +-- truncate_limit: 100 +ALTER ROLE regress_role_limited CREATEDB +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_role_limited WITH CREATEDB" +== 016 +-- truncate_limit: 100 +ALTER ROLE regress_role_limited BYPASSRLS +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_role_limited WITH BYPASSRLS" +== 017 +-- truncate_limit: 100 +DROP ROLE regress_role_limited +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_role_limited" +== 018 +-- truncate_limit: 100 +-- ok, can give away these role attributes if you have them +SET SESSION AUTHORIZATION regress_role_admin +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_role_admin" +== 019 +-- truncate_limit: 100 +CREATE ROLE regress_replication_bypassrls REPLICATION BYPASSRLS +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_replication_bypassrls WITH REPLICATION BYPASSRLS" +== 020 +-- truncate_limit: 100 +CREATE ROLE regress_replication REPLICATION +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_replication WITH REPLICATION" +== 021 +-- truncate_limit: 100 +CREATE ROLE regress_bypassrls BYPASSRLS +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_bypassrls WITH BYPASSRLS" +== 022 +-- truncate_limit: 100 +CREATE ROLE regress_createdb CREATEDB +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_createdb WITH CREATEDB" +== 023 +-- truncate_limit: 100 +-- ok, can toggle these role attributes off and on if you have them +ALTER ROLE regress_replication NOREPLICATION +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_replication WITH NOREPLICATION" +== 024 +-- truncate_limit: 100 +ALTER ROLE regress_replication REPLICATION +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_replication WITH REPLICATION" +== 025 +-- truncate_limit: 100 +ALTER ROLE regress_bypassrls NOBYPASSRLS +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_bypassrls WITH NOBYPASSRLS" +== 026 +-- truncate_limit: 100 +ALTER ROLE regress_bypassrls BYPASSRLS +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_bypassrls WITH BYPASSRLS" +== 027 +-- truncate_limit: 100 +ALTER ROLE regress_createdb NOCREATEDB +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_createdb WITH NOCREATEDB" +== 028 +-- truncate_limit: 100 +ALTER ROLE regress_createdb CREATEDB +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_createdb WITH CREATEDB" +== 029 +-- truncate_limit: 100 +-- fail, can't toggle SUPERUSER +ALTER ROLE regress_createdb SUPERUSER +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_createdb WITH SUPERUSER" +== 030 +-- truncate_limit: 100 +ALTER ROLE regress_createdb NOSUPERUSER +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_createdb WITH NOSUPERUSER" +== 031 +-- truncate_limit: 100 +-- ok, having CREATEROLE is enough to create users with these privileges +CREATE ROLE regress_createrole CREATEROLE NOINHERIT +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_createrole WITH CREATEROLE NOINHERIT" +== 032 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE regression TO regress_createrole WITH GRANT OPTION +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_createrole WITH GRANT OPTION" +== 033 +-- truncate_limit: 100 +CREATE ROLE regress_login LOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_login WITH LOGIN" +== 034 +-- truncate_limit: 100 +CREATE ROLE regress_inherit INHERIT +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_inherit WITH INHERIT" +== 035 +-- truncate_limit: 100 +CREATE ROLE regress_connection_limit CONNECTION LIMIT 5 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_connection_limit WITH CONNECTION LIMIT 5" +== 036 +-- truncate_limit: 100 +CREATE ROLE regress_encrypted_password ENCRYPTED PASSWORD 'foo' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_encrypted_password WITH PASSWORD 'foo'" +== 037 +-- truncate_limit: 100 +CREATE ROLE regress_password_null PASSWORD NULL +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_password_null WITH PASSWORD NULL" +== 038 +-- truncate_limit: 100 +-- ok, backwards compatible noise words should be ignored +CREATE ROLE regress_noiseword SYSID 12345 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_noiseword WITH SYSID 12345" +== 039 +-- truncate_limit: 100 +-- fail, cannot grant membership in superuser role +CREATE ROLE regress_nosuch_super IN ROLE regress_role_super +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_super WITH IN ROLE regress_role_super" +== 040 +-- truncate_limit: 100 +-- fail, database owner cannot have members +CREATE ROLE regress_nosuch_dbowner IN ROLE pg_database_owner +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_dbowner WITH IN ROLE pg_database_owner" +== 041 +-- truncate_limit: 100 +-- ok, can grant other users into a role +CREATE ROLE regress_inroles ROLE + regress_role_super, regress_createdb, regress_createrole, regress_login, + regress_inherit, regress_connection_limit, regress_encrypted_password, regress_password_null +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_inroles WITH ROLE regress_role_super, regress_createdb, regress_createrole, r..." +== 042 +-- truncate_limit: 100 +-- fail, cannot grant a role into itself +CREATE ROLE regress_nosuch_recursive ROLE regress_nosuch_recursive +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_recursive WITH ROLE regress_nosuch_recursive" +== 043 +-- truncate_limit: 100 +-- ok, can grant other users into a role with admin option +CREATE ROLE regress_adminroles ADMIN + regress_role_super, regress_createdb, regress_createrole, regress_login, + regress_inherit, regress_connection_limit, regress_encrypted_password, regress_password_null +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_adminroles WITH ADMIN regress_role_super, regress_createdb, regress_createrol..." +== 044 +-- truncate_limit: 100 +-- fail, cannot grant a role into itself with admin option +CREATE ROLE regress_nosuch_admin_recursive ADMIN regress_nosuch_admin_recursive +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_nosuch_admin_recursive WITH ADMIN regress_nosuch_admin_recursive" +== 045 +-- truncate_limit: 100 +-- fail, regress_createrole does not have CREATEDB privilege +SET SESSION AUTHORIZATION regress_createrole +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_createrole" +== 046 +-- truncate_limit: 100 +CREATE DATABASE regress_nosuch_db +-- +STMT: CreatedbStmt +TRUNCATED: "CREATE DATABASE regress_nosuch_db" +== 047 +-- truncate_limit: 100 +-- ok, regress_createrole can create new roles +CREATE ROLE regress_plainrole +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_plainrole" +== 048 +-- truncate_limit: 100 +-- ok, roles with CREATEROLE can create new roles with it +CREATE ROLE regress_rolecreator CREATEROLE +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rolecreator WITH CREATEROLE" +== 049 +-- truncate_limit: 100 +-- ok, roles with CREATEROLE can create new roles with different role +-- attributes, including CREATEROLE +CREATE ROLE regress_hasprivs CREATEROLE LOGIN INHERIT CONNECTION LIMIT 5 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_hasprivs WITH CREATEROLE LOGIN INHERIT CONNECTION LIMIT 5" +== 050 +-- truncate_limit: 100 +-- ok, we should be able to modify a role we created +COMMENT ON ROLE regress_hasprivs IS 'some comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON ROLE regress_hasprivs IS 'some comment'" +== 051 +-- truncate_limit: 100 +ALTER ROLE regress_hasprivs RENAME TO regress_tenant +-- +STMT: RenameStmt +TRUNCATED: "ALTER ROLE regress_hasprivs RENAME TO regress_tenant" +== 052 +-- truncate_limit: 100 +ALTER ROLE regress_tenant NOINHERIT NOLOGIN CONNECTION LIMIT 7 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_tenant WITH NOINHERIT NOLOGIN CONNECTION LIMIT 7" +== 053 +-- truncate_limit: 100 +-- fail, we should be unable to modify a role we did not create +COMMENT ON ROLE regress_role_normal IS 'some comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON ROLE regress_role_normal IS 'some comment'" +== 054 +-- truncate_limit: 100 +ALTER ROLE regress_role_normal RENAME TO regress_role_abnormal +-- +STMT: RenameStmt +TRUNCATED: "ALTER ROLE regress_role_normal RENAME TO regress_role_abnormal" +== 055 +-- truncate_limit: 100 +ALTER ROLE regress_role_normal NOINHERIT NOLOGIN CONNECTION LIMIT 7 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_role_normal WITH NOINHERIT NOLOGIN CONNECTION LIMIT 7" +== 056 +-- truncate_limit: 100 +-- ok, regress_tenant can create objects within the database +SET SESSION AUTHORIZATION regress_tenant +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_tenant" +== 057 +-- truncate_limit: 100 +CREATE TABLE tenant_table (i integer) +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tenant_table (i int)" +== 058 +-- truncate_limit: 100 +CREATE INDEX tenant_idx ON tenant_table(i) +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tenant_idx ON tenant_table USING btree (i)" +== 059 +-- truncate_limit: 100 +CREATE VIEW tenant_view AS SELECT * FROM pg_catalog.pg_class +-- +TABLE: name="tenant_view" schema="" table="tenant_view" ctx=DDL +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tenant_view AS SELECT * FROM pg_catalog.pg_class" +== 060 +-- truncate_limit: 100 +REVOKE ALL PRIVILEGES ON tenant_table FROM PUBLIC +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON tenant_table FROM public" +== 061 +-- truncate_limit: 100 +-- fail, these objects belonging to regress_tenant +SET SESSION AUTHORIZATION regress_createrole +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_createrole" +== 062 +-- truncate_limit: 100 +DROP INDEX tenant_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX tenant_idx" +== 063 +-- truncate_limit: 100 +ALTER TABLE tenant_table ADD COLUMN t text +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenant_table ADD COLUMN t text" +== 064 +-- truncate_limit: 100 +DROP TABLE tenant_table +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tenant_table" +== 065 +-- truncate_limit: 100 +ALTER VIEW tenant_view OWNER TO regress_role_admin +-- +TABLE: name="tenant_view" schema="" table="tenant_view" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW tenant_view OWNER TO regress_role_admin" +== 066 +-- truncate_limit: 100 +DROP VIEW tenant_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW tenant_view" +== 067 +-- truncate_limit: 100 +-- fail, can't create objects owned as regress_tenant +CREATE SCHEMA regress_tenant_schema AUTHORIZATION regress_tenant +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_tenant_schema AUTHORIZATION regress_tenant" +== 068 +-- truncate_limit: 100 +-- fail, we don't inherit permissions from regress_tenant +REASSIGN OWNED BY regress_tenant TO regress_createrole +-- +STMT: ReassignOwnedStmt +TRUNCATED: "REASSIGN OWNED BY regress_tenant TO regress_createrole" +== 069 +-- truncate_limit: 100 +-- ok, create a role with a value for createrole_self_grant +SET createrole_self_grant = 'set, inherit' +-- +STMT: VariableSetStmt +TRUNCATED: "SET createrole_self_grant TO \"set, inherit\"" +== 070 +-- truncate_limit: 100 +CREATE ROLE regress_tenant2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_tenant2" +== 071 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE regression TO regress_tenant2 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_tenant2" +== 072 +-- truncate_limit: 100 +-- ok, regress_tenant2 can create objects within the database +SET SESSION AUTHORIZATION regress_tenant2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_tenant2" +== 073 +-- truncate_limit: 100 +CREATE TABLE tenant2_table (i integer) +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tenant2_table (i int)" +== 074 +-- truncate_limit: 100 +REVOKE ALL PRIVILEGES ON tenant2_table FROM PUBLIC +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON tenant2_table FROM public" +== 075 +-- truncate_limit: 100 +-- ok, because we have SET and INHERIT on regress_tenant2 +SET SESSION AUTHORIZATION regress_createrole +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_createrole" +== 076 +-- truncate_limit: 100 +CREATE SCHEMA regress_tenant2_schema AUTHORIZATION regress_tenant2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_tenant2_schema AUTHORIZATION regress_tenant2" +== 077 +-- truncate_limit: 100 +ALTER SCHEMA regress_tenant2_schema OWNER TO regress_createrole +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SCHEMA regress_tenant2_schema OWNER TO regress_createrole" +== 078 +-- truncate_limit: 100 +ALTER TABLE tenant2_table OWNER TO regress_createrole +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenant2_table OWNER TO regress_createrole" +== 079 +-- truncate_limit: 100 +ALTER TABLE tenant2_table OWNER TO regress_tenant2 +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenant2_table OWNER TO regress_tenant2" +== 080 +-- truncate_limit: 100 +-- with SET but not INHERIT, we can give away objects but not take them +REVOKE INHERIT OPTION FOR regress_tenant2 FROM regress_createrole +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE INHERIT OPTION FOR regress_tenant2 FROM regress_createrole" +== 081 +-- truncate_limit: 100 +ALTER SCHEMA regress_tenant2_schema OWNER TO regress_tenant2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SCHEMA regress_tenant2_schema OWNER TO regress_tenant2" +== 082 +-- truncate_limit: 100 +ALTER TABLE tenant2_table OWNER TO regress_createrole +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenant2_table OWNER TO regress_createrole" +== 083 +-- truncate_limit: 100 +-- with INHERIT but not SET, we can take objects but not give them away +GRANT regress_tenant2 TO regress_createrole WITH INHERIT TRUE, SET FALSE +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_tenant2 TO regress_createrole WITH INHERIT OPTION, SET FALSE" +== 084 +-- truncate_limit: 100 +ALTER TABLE tenant2_table OWNER TO regress_createrole +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenant2_table OWNER TO regress_createrole" +== 085 +-- truncate_limit: 100 +ALTER TABLE tenant2_table OWNER TO regress_tenant2 +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenant2_table OWNER TO regress_tenant2" +== 086 +-- truncate_limit: 100 +DROP TABLE tenant2_table +-- +TABLE: name="tenant2_table" schema="" table="tenant2_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tenant2_table" +== 087 +-- truncate_limit: 100 +-- fail, CREATEROLE is not enough to create roles in privileged roles +CREATE ROLE regress_read_all_data IN ROLE pg_read_all_data +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_read_all_data WITH IN ROLE pg_read_all_data" +== 088 +-- truncate_limit: 100 +CREATE ROLE regress_write_all_data IN ROLE pg_write_all_data +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_write_all_data WITH IN ROLE pg_write_all_data" +== 089 +-- truncate_limit: 100 +CREATE ROLE regress_monitor IN ROLE pg_monitor +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_monitor WITH IN ROLE pg_monitor" +== 090 +-- truncate_limit: 100 +CREATE ROLE regress_read_all_settings IN ROLE pg_read_all_settings +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_read_all_settings WITH IN ROLE pg_read_all_settings" +== 091 +-- truncate_limit: 100 +CREATE ROLE regress_read_all_stats IN ROLE pg_read_all_stats +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_read_all_stats WITH IN ROLE pg_read_all_stats" +== 092 +-- truncate_limit: 100 +CREATE ROLE regress_stat_scan_tables IN ROLE pg_stat_scan_tables +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_stat_scan_tables WITH IN ROLE pg_stat_scan_tables" +== 093 +-- truncate_limit: 100 +CREATE ROLE regress_read_server_files IN ROLE pg_read_server_files +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_read_server_files WITH IN ROLE pg_read_server_files" +== 094 +-- truncate_limit: 100 +CREATE ROLE regress_write_server_files IN ROLE pg_write_server_files +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_write_server_files WITH IN ROLE pg_write_server_files" +== 095 +-- truncate_limit: 100 +CREATE ROLE regress_execute_server_program IN ROLE pg_execute_server_program +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_execute_server_program WITH IN ROLE pg_execute_server_program" +== 096 +-- truncate_limit: 100 +CREATE ROLE regress_signal_backend IN ROLE pg_signal_backend +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_signal_backend WITH IN ROLE pg_signal_backend" +== 097 +-- truncate_limit: 100 +-- fail, role still owns database objects +DROP ROLE regress_tenant +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_tenant" +== 098 +-- truncate_limit: 100 +-- fail, creation of these roles failed above so they do not now exist +SET SESSION AUTHORIZATION regress_role_admin +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_role_admin" +== 099 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_superuser +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_superuser" +== 100 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_replication_bypassrls +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_replication_bypassrls" +== 101 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_replication +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_replication" +== 102 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_bypassrls +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_bypassrls" +== 103 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_super +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_super" +== 104 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_dbowner +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_dbowner" +== 105 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_recursive +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_recursive" +== 106 +-- truncate_limit: 100 +DROP ROLE regress_nosuch_admin_recursive +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_nosuch_admin_recursive" +== 107 +-- truncate_limit: 100 +DROP ROLE regress_plainrole +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_plainrole" +== 108 +-- truncate_limit: 100 +-- must revoke privileges before dropping role +REVOKE CREATE ON DATABASE regression FROM regress_createrole CASCADE +-- +STMT: GrantStmt +TRUNCATED: "REVOKE create ON DATABASE regression FROM regress_createrole CASCADE" +== 109 +-- truncate_limit: 100 +-- ok, should be able to drop non-superuser roles we created +DROP ROLE regress_replication_bypassrls +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_replication_bypassrls" +== 110 +-- truncate_limit: 100 +DROP ROLE regress_replication +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_replication" +== 111 +-- truncate_limit: 100 +DROP ROLE regress_bypassrls +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_bypassrls" +== 112 +-- truncate_limit: 100 +DROP ROLE regress_createdb +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_createdb" +== 113 +-- truncate_limit: 100 +DROP ROLE regress_createrole +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_createrole" +== 114 +-- truncate_limit: 100 +DROP ROLE regress_login +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_login" +== 115 +-- truncate_limit: 100 +DROP ROLE regress_inherit +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_inherit" +== 116 +-- truncate_limit: 100 +DROP ROLE regress_connection_limit +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_connection_limit" +== 117 +-- truncate_limit: 100 +DROP ROLE regress_encrypted_password +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_encrypted_password" +== 118 +-- truncate_limit: 100 +DROP ROLE regress_password_null +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_password_null" +== 119 +-- truncate_limit: 100 +DROP ROLE regress_noiseword +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_noiseword" +== 120 +-- truncate_limit: 100 +DROP ROLE regress_inroles +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_inroles" +== 121 +-- truncate_limit: 100 +DROP ROLE regress_adminroles +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_adminroles" +== 122 +-- truncate_limit: 100 +-- fail, cannot drop ourself, nor superusers or roles we lack ADMIN for +DROP ROLE regress_role_super +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_role_super" +== 123 +-- truncate_limit: 100 +DROP ROLE regress_role_admin +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_role_admin" +== 124 +-- truncate_limit: 100 +DROP ROLE regress_rolecreator +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_rolecreator" +== 125 +-- truncate_limit: 100 +-- ok +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 126 +-- truncate_limit: 100 +REVOKE CREATE ON DATABASE regression FROM regress_role_admin CASCADE +-- +STMT: GrantStmt +TRUNCATED: "REVOKE create ON DATABASE regression FROM regress_role_admin CASCADE" +== 127 +-- truncate_limit: 100 +DROP INDEX tenant_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX tenant_idx" +== 128 +-- truncate_limit: 100 +DROP TABLE tenant_table +-- +TABLE: name="tenant_table" schema="" table="tenant_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tenant_table" +== 129 +-- truncate_limit: 100 +DROP VIEW tenant_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW tenant_view" +== 130 +-- truncate_limit: 100 +DROP SCHEMA regress_tenant2_schema +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA regress_tenant2_schema" +== 131 +-- truncate_limit: 100 +-- check for duplicated drop +DROP ROLE regress_tenant, regress_tenant +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_tenant, regress_tenant" +== 132 +-- truncate_limit: 100 +DROP ROLE regress_tenant2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_tenant2" +== 133 +-- truncate_limit: 100 +DROP ROLE regress_rolecreator +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_rolecreator" +== 134 +-- truncate_limit: 100 +DROP ROLE regress_role_admin +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_role_admin" +== 135 +-- truncate_limit: 100 +DROP ROLE regress_role_limited_admin +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_role_limited_admin" +== 136 +-- truncate_limit: 100 +DROP ROLE regress_role_super +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_role_super" +== 137 +-- truncate_limit: 100 +DROP ROLE regress_role_normal +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_role_normal" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json new file mode 100644 index 0000000..7249d3a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json @@ -0,0 +1,31 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_schema.test b/parser/testdata/summary_truncate/postgres_regress/create_schema.test new file mode 100644 index 0000000..f170c01 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_schema.test @@ -0,0 +1,199 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_SCHEMA +|-- + +-- Schema creation with elements. + +CREATE ROLE regress_create_schema_role SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_create_schema_role WITH SUPERUSER" +== 002 +-- truncate_limit: 100 +-- Cases where schema creation fails as objects are qualified with a schema +-- that does not match with what's expected. +-- This checks all the object types that include schema qualifications. +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE SEQUENCE schema_not_existing.seq +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION regress_create_schema_role CREATE SEQUENCE schema_not_existing.seq" +== 003 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE TABLE schema_not_existing.tab (id int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION regress_create_schema_role CREATE TABLE schema_not_existing.tab (id int)" +== 004 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE VIEW schema_not_existing.view AS SELECT 1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION regress_create_schema_role CREATE VIEW schema_not_existing.view AS SE..." +== 005 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE INDEX ON schema_not_existing.tab (id) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION regress_create_schema_role CREATE INDEX ON schema_not_existing.tab US..." +== 006 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func() +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION regress_create_schema_role CREATE TRIGGER schema_trig BEFORE INSERT O..." +== 007 +-- truncate_limit: 100 +-- Again, with a role specification and no schema names. +SET ROLE regress_create_schema_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_create_schema_role" +== 008 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE SEQUENCE schema_not_existing.seq +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION CURRENT_ROLE CREATE SEQUENCE schema_not_existing.seq" +== 009 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE TABLE schema_not_existing.tab (id int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION CURRENT_ROLE CREATE TABLE schema_not_existing.tab (id int)" +== 010 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE VIEW schema_not_existing.view AS SELECT 1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION CURRENT_ROLE CREATE VIEW schema_not_existing.view AS SELECT 1" +== 011 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE INDEX ON schema_not_existing.tab (id) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION CURRENT_ROLE CREATE INDEX ON schema_not_existing.tab USING btree (id)" +== 012 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func() +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION CURRENT_ROLE CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_e..." +== 013 +-- truncate_limit: 100 +-- Again, with a schema name and a role specification. +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE SEQUENCE schema_not_existing.seq +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE CREATE SEQUENCE schema_not_existing.seq" +== 014 +-- truncate_limit: 100 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE TABLE schema_not_existing.tab (id int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE CREATE TABLE schema_not_existing.tab (i..." +== 015 +-- truncate_limit: 100 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE VIEW schema_not_existing.view AS SELECT 1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE CREATE VIEW schema_not_existing.view AS..." +== 016 +-- truncate_limit: 100 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE INDEX ON schema_not_existing.tab (id) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE CREATE INDEX ON schema_not_existing.tab..." +== 017 +-- truncate_limit: 100 +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func() +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE CREATE TRIGGER schema_trig BEFORE INSER..." +== 018 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 019 +-- truncate_limit: 100 +-- Cases where the schema creation succeeds. +-- The schema created matches the role name. +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + CREATE TABLE regress_create_schema_role.tab (id int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION regress_create_schema_role CREATE TABLE regress_create_schema_role.ta..." +== 020 +-- truncate_limit: 100 +DROP SCHEMA regress_create_schema_role CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA regress_create_schema_role CASCADE" +== 021 +-- truncate_limit: 100 +-- Again, with a different role specification and no schema names. +SET ROLE regress_create_schema_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_create_schema_role" +== 022 +-- truncate_limit: 100 +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + CREATE TABLE regress_create_schema_role.tab (id int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA AUTHORIZATION CURRENT_ROLE CREATE TABLE regress_create_schema_role.tab (id int)" +== 023 +-- truncate_limit: 100 +DROP SCHEMA regress_create_schema_role CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA regress_create_schema_role CASCADE" +== 024 +-- truncate_limit: 100 +-- Again, with a schema name and a role specification. +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + CREATE TABLE regress_schema_1.tab (id int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE CREATE TABLE regress_schema_1.tab (id int)" +== 025 +-- truncate_limit: 100 +DROP SCHEMA regress_schema_1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA regress_schema_1 CASCADE" +== 026 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 027 +-- truncate_limit: 100 +-- Clean up +DROP ROLE regress_create_schema_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_create_schema_role" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json new file mode 100644 index 0000000..f382372 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json @@ -0,0 +1,330 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_table.test b/parser/testdata/summary_truncate/postgres_regress/create_table.test new file mode 100644 index 0000000..3b97c76 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_table.test @@ -0,0 +1,2628 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_TABLE +|-- + +-- Error cases +CREATE TABLE unknowntab ( + u unknown -- fail +) +-- +TABLE: name="unknowntab" schema="" table="unknowntab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unknowntab (u unknown)" +== 002 +-- truncate_limit: 100 +CREATE TYPE unknown_comptype AS ( + u unknown -- fail +) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE unknown_comptype AS (u unknown)" +== 003 +-- truncate_limit: 100 +-- invalid: non-lowercase quoted reloptions identifiers +CREATE TABLE tas_case WITH ("Fillfactor" = 10) AS SELECT 1 a +-- +TABLE: name="tas_case" schema="" table="tas_case" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE tas_case WITH (\"Fillfactor\"=10) AS SELECT 1 AS a" +== 004 +-- truncate_limit: 100 +CREATE UNLOGGED TABLE unlogged1 (a int primary key) +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE unlogged1 (a int PRIMARY KEY)" +== 005 +-- truncate_limit: 100 +-- OK +CREATE TEMPORARY TABLE unlogged2 (a int primary key) +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE unlogged2 (a int PRIMARY KEY)" +== 006 +-- truncate_limit: 100 +-- OK +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class WHERE relname ~ E'^unlogged\\\\d' ORDER BY relname" +== 007 +-- truncate_limit: 100 +REINDEX INDEX unlogged1_pkey +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX unlogged1_pkey" +== 008 +-- truncate_limit: 100 +REINDEX INDEX unlogged2_pkey +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX unlogged2_pkey" +== 009 +-- truncate_limit: 100 +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class WHERE relname ~ E'^unlogged\\\\d' ORDER BY relname" +== 010 +-- truncate_limit: 100 +DROP TABLE unlogged2 +-- +TABLE: name="unlogged2" schema="" table="unlogged2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unlogged2" +== 011 +-- truncate_limit: 100 +INSERT INTO unlogged1 VALUES (42) +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unlogged1 VALUES (42)" +== 012 +-- truncate_limit: 100 +CREATE UNLOGGED TABLE public.unlogged2 (a int primary key) +-- +TABLE: name="public.unlogged2" schema="public" table="unlogged2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE public.unlogged2 (a int PRIMARY KEY)" +== 013 +-- truncate_limit: 100 +-- also OK +CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int primary key) +-- +TABLE: name="pg_temp.unlogged3" schema="pg_temp" table="unlogged3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int PRIMARY KEY)" +== 014 +-- truncate_limit: 100 +-- not OK +CREATE TABLE pg_temp.implicitly_temp (a int primary key) +-- +TABLE: name="pg_temp.implicitly_temp" schema="pg_temp" table="implicitly_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pg_temp.implicitly_temp (a int PRIMARY KEY)" +== 015 +-- truncate_limit: 100 +-- OK +CREATE TEMP TABLE explicitly_temp (a int primary key) +-- +TABLE: name="explicitly_temp" schema="" table="explicitly_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE explicitly_temp (a int PRIMARY KEY)" +== 016 +-- truncate_limit: 100 +-- also OK +CREATE TEMP TABLE pg_temp.doubly_temp (a int primary key) +-- +TABLE: name="pg_temp.doubly_temp" schema="pg_temp" table="doubly_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pg_temp.doubly_temp (a int PRIMARY KEY)" +== 017 +-- truncate_limit: 100 +-- also OK +CREATE TEMP TABLE public.temp_to_perm (a int primary key) +-- +TABLE: name="public.temp_to_perm" schema="public" table="temp_to_perm" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE public.temp_to_perm (a int PRIMARY KEY)" +== 018 +-- truncate_limit: 100 +-- not OK +DROP TABLE unlogged1, public.unlogged2 +-- +TABLE: name="unlogged1" schema="" table="unlogged1" ctx=DDL +TABLE: name="public.unlogged2" schema="public" table="unlogged2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unlogged1, public.unlogged2" +== 019 +-- truncate_limit: 100 +CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r' +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'" +== 020 +-- truncate_limit: 100 +CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r' +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'" +== 021 +-- truncate_limit: 100 +CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r' +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'" +== 022 +-- truncate_limit: 100 +DROP TABLE as_select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE as_select1" +== 023 +-- truncate_limit: 100 +PREPARE select1 AS SELECT 1 as a +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE select1 AS SELECT 1 AS a" +== 024 +-- truncate_limit: 100 +CREATE TABLE as_select1 AS EXECUTE select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TABLE as_select1 AS EXECUTE select1" +== 025 +-- truncate_limit: 100 +CREATE TABLE as_select1 AS EXECUTE select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TABLE as_select1 AS EXECUTE select1" +== 026 +-- truncate_limit: 100 +SELECT * FROM as_select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM as_select1" +== 027 +-- truncate_limit: 100 +CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1" +== 028 +-- truncate_limit: 100 +DROP TABLE as_select1 +-- +TABLE: name="as_select1" schema="" table="as_select1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE as_select1" +== 029 +-- truncate_limit: 100 +DEALLOCATE select1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE select1" +== 030 +-- truncate_limit: 100 +-- create an extra wide table to test for issues related to that +-- (temporarily hide query, to avoid the long CREATE TABLE stmt) +SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);' +FROM generate_series(1, 1100) g(i) +INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col') +-- +ERROR: syntax error at or near "INSERT" +CURSORPOS: 287 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 031 +-- truncate_limit: 100 +SELECT firstc, lastc FROM extra_wide_table +-- +TABLE: name="extra_wide_table" schema="" table="extra_wide_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT firstc, lastc FROM extra_wide_table" +== 032 +-- truncate_limit: 100 +-- check that tables with oids cannot be created anymore +CREATE TABLE withoid() WITH OIDS +-- +ERROR: syntax error at or near "OIDS" +CURSORPOS: 86 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 033 +-- truncate_limit: 100 +CREATE TABLE withoid() WITH (oids) +-- +TABLE: name="withoid" schema="" table="withoid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE withoid () WITH (oids)" +== 034 +-- truncate_limit: 100 +CREATE TABLE withoid() WITH (oids = true) +-- +TABLE: name="withoid" schema="" table="withoid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE withoid () WITH (oids=true)" +== 035 +-- truncate_limit: 100 +-- but explicitly not adding oids is still supported +CREATE TEMP TABLE withoutoid() WITHOUT OIDS +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE withoutoid ()" +== 036 +-- truncate_limit: 100 +DROP TABLE withoutoid +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE withoutoid" +== 037 +-- truncate_limit: 100 +CREATE TEMP TABLE withoutoid() WITH (oids = false) +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE withoutoid () WITH (oids=false)" +== 038 +-- truncate_limit: 100 +DROP TABLE withoutoid +-- +TABLE: name="withoutoid" schema="" table="withoutoid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE withoutoid" +== 039 +-- truncate_limit: 100 +-- temporary tables are ignored by pg_filenode_relation(). +CREATE TEMP TABLE relation_filenode_check(c1 int) +-- +TABLE: name="relation_filenode_check" schema="" table="relation_filenode_check" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE relation_filenode_check (c1 int)" +== 040 +-- truncate_limit: 100 +SELECT relpersistence, + pg_filenode_relation (reltablespace, pg_relation_filenode(oid)) + FROM pg_class + WHERE relname = 'relation_filenode_check' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_filenode_relation" function="pg_filenode_relation" schema="" ctx=Call +FUNCTION: name="pg_relation_filenode" function="pg_relation_filenode" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class WHERE relname = 'relation_filenode_check'" +== 041 +-- truncate_limit: 100 +DROP TABLE relation_filenode_check +-- +TABLE: name="relation_filenode_check" schema="" table="relation_filenode_check" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE relation_filenode_check" +== 042 +-- truncate_limit: 100 +-- check restriction with default expressions +-- invalid use of column reference in default expressions +CREATE TABLE default_expr_column (id int DEFAULT (id)) +-- +TABLE: name="default_expr_column" schema="" table="default_expr_column" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_expr_column (id int DEFAULT id)" +== 043 +-- truncate_limit: 100 +CREATE TABLE default_expr_column (id int DEFAULT (bar.id)) +-- +TABLE: name="default_expr_column" schema="" table="default_expr_column" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_expr_column (id int DEFAULT bar.id)" +== 044 +-- truncate_limit: 100 +CREATE TABLE default_expr_agg_column (id int DEFAULT (avg(id))) +-- +TABLE: name="default_expr_agg_column" schema="" table="default_expr_agg_column" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_expr_agg_column (id int DEFAULT avg(id))" +== 045 +-- truncate_limit: 100 +-- invalid column definition +CREATE TABLE default_expr_non_column (a int DEFAULT (avg(non_existent))) +-- +TABLE: name="default_expr_non_column" schema="" table="default_expr_non_column" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_expr_non_column (a int DEFAULT avg(non_existent))" +== 046 +-- truncate_limit: 100 +-- invalid use of aggregate +CREATE TABLE default_expr_agg (a int DEFAULT (avg(1))) +-- +TABLE: name="default_expr_agg" schema="" table="default_expr_agg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_expr_agg (a int DEFAULT avg(1))" +== 047 +-- truncate_limit: 100 +-- invalid use of subquery +CREATE TABLE default_expr_agg (a int DEFAULT (select 1)) +-- +TABLE: name="default_expr_agg" schema="" table="default_expr_agg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_expr_agg (a int DEFAULT (SELECT 1))" +== 048 +-- truncate_limit: 100 +-- invalid use of set-returning function +CREATE TABLE default_expr_agg (a int DEFAULT (generate_series(1,3))) +-- +TABLE: name="default_expr_agg" schema="" table="default_expr_agg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_expr_agg (a int DEFAULT generate_series(1, 3))" +== 049 +-- truncate_limit: 100 +-- Verify that subtransaction rollback restores rd_createSubid. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 050 +-- truncate_limit: 100 +CREATE TABLE remember_create_subid (c int) +-- +TABLE: name="remember_create_subid" schema="" table="remember_create_subid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE remember_create_subid (c int)" +== 051 +-- truncate_limit: 100 +SAVEPOINT q +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT q" +== 052 +-- truncate_limit: 100 +DROP TABLE remember_create_subid +-- +TABLE: name="remember_create_subid" schema="" table="remember_create_subid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE remember_create_subid" +== 053 +-- truncate_limit: 100 +ROLLBACK TO q +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT q" +== 054 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 055 +-- truncate_limit: 100 +DROP TABLE remember_create_subid +-- +TABLE: name="remember_create_subid" schema="" table="remember_create_subid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE remember_create_subid" +== 056 +-- truncate_limit: 100 +-- Verify that subtransaction rollback restores rd_firstRelfilenodeSubid. +CREATE TABLE remember_node_subid (c int) +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE remember_node_subid (c int)" +== 057 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 058 +-- truncate_limit: 100 +ALTER TABLE remember_node_subid ALTER c TYPE bigint +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE remember_node_subid ALTER COLUMN c TYPE bigint" +== 059 +-- truncate_limit: 100 +SAVEPOINT q +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT q" +== 060 +-- truncate_limit: 100 +DROP TABLE remember_node_subid +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE remember_node_subid" +== 061 +-- truncate_limit: 100 +ROLLBACK TO q +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT q" +== 062 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 063 +-- truncate_limit: 100 +DROP TABLE remember_node_subid +-- +TABLE: name="remember_node_subid" schema="" table="remember_node_subid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE remember_node_subid" +== 064 +-- truncate_limit: 100 +|-- +-- Partitioned tables +|-- + +-- cannot combine INHERITS and PARTITION BY (although grammar allows) +CREATE TABLE partitioned ( + a int +) INHERITS (some_table) PARTITION BY LIST (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) INHERITS (some_table) PARTITION BY LIST (a)" +== 065 +-- truncate_limit: 100 +-- cannot use more than 1 column as partition key for list partitioned table +CREATE TABLE partitioned ( + a1 int, + a2 int +) PARTITION BY LIST (a1, a2) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a1 int, a2 int) PARTITION BY LIST (a1, a2)" +== 066 +-- truncate_limit: 100 +-- fail + +-- prevent using prohibited expressions in the key +CREATE FUNCTION retset (a int) RETURNS SETOF int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="retset" function="retset" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION retset(a int) RETURNS SETOF int AS $$ SELECT 1; $$ LANGUAGE sql IMMUTABLE" +== 067 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (retset(a)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY RANGE ((retset(a)))" +== 068 +-- truncate_limit: 100 +DROP FUNCTION retset(int) +-- +FUNCTION: name="retset" function="retset" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION retset(int)" +== 069 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE ((avg(a))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY RANGE ((avg(a)))" +== 070 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, b int) PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b)))" +== 071 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int +) PARTITION BY LIST ((a LIKE (SELECT 1))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY LIST ((a LIKE (SELECT 1)))" +== 072 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE ((42)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY RANGE ((42))" +== 073 +-- truncate_limit: 100 +CREATE FUNCTION const_func () RETURNS int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="const_func" function="const_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION const_func() RETURNS int AS $$ SELECT 1; $$ LANGUAGE sql IMMUTABLE" +== 074 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (const_func()) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY RANGE ((const_func()))" +== 075 +-- truncate_limit: 100 +DROP FUNCTION const_func() +-- +FUNCTION: name="const_func" function="const_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION const_func()" +== 076 +-- truncate_limit: 100 +-- only accept valid partitioning strategy +CREATE TABLE partitioned ( + a int +) PARTITION BY MAGIC (a) +-- +ERROR: unrecognized partitioning strategy "magic" +FILENAME: gram.y +FUNCNAME: parsePartitionStrategy +== 077 +-- truncate_limit: 100 +-- specified column must be present in the table +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (b) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY RANGE (b)" +== 078 +-- truncate_limit: 100 +-- cannot use system columns in partition key +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (xmin) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY RANGE (xmin)" +== 079 +-- truncate_limit: 100 +-- cannot use pseudotypes +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (((a, b))) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, b int) PARTITION BY RANGE (((a, b)))" +== 080 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (a, ('unknown')) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, b int) PARTITION BY RANGE (a, ('unknown'))" +== 081 +-- truncate_limit: 100 +-- functions in key must be immutable +CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL +-- +FUNCTION: name="immut_func" function="immut_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION immut_func(a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE sql" +== 082 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (immut_func(a)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int) PARTITION BY RANGE ((immut_func(a)))" +== 083 +-- truncate_limit: 100 +DROP FUNCTION immut_func(int) +-- +FUNCTION: name="immut_func" function="immut_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION immut_func(int)" +== 084 +-- truncate_limit: 100 +-- prevent using columns of unsupported types in key (type must have a btree operator class) +CREATE TABLE partitioned ( + a point +) PARTITION BY LIST (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a point) PARTITION BY LIST (a)" +== 085 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a point +) PARTITION BY LIST (a point_ops) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a point) PARTITION BY LIST (a point_ops)" +== 086 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a point +) PARTITION BY RANGE (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a point) PARTITION BY RANGE (a)" +== 087 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a point +) PARTITION BY RANGE (a point_ops) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a point) PARTITION BY RANGE (a point_ops)" +== 088 +-- truncate_limit: 100 +-- cannot add NO INHERIT constraints to partitioned tables +CREATE TABLE partitioned ( + a int, + CONSTRAINT check_a CHECK (a > 0) NO INHERIT +) PARTITION BY RANGE (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, CONSTRAINT check_a CHECK (a > 0) NO INHERIT) PARTITION BY RANGE (a)" +== 089 +-- truncate_limit: 100 +-- some checks after successful creation of a partitioned table +CREATE FUNCTION plusone(a int) RETURNS INT AS $$ SELECT a+1; $$ LANGUAGE SQL +-- +FUNCTION: name="plusone" function="plusone" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION plusone(a int) RETURNS int AS $$ SELECT a+1; $$ LANGUAGE sql" +== 090 +-- truncate_limit: 100 +CREATE TABLE partitioned ( + a int, + b int, + c text, + d text +) PARTITION BY RANGE (a oid_ops, plusone(b), c collate "default", d collate "C") +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, b int, c text, d text) PARTITION BY RANGE (a oid_ops, (plusone(b..." +== 091 +-- truncate_limit: 100 +-- check relkind +SELECT relkind FROM pg_class WHERE relname = 'partitioned' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relkind FROM pg_class WHERE relname = 'partitioned'" +== 092 +-- truncate_limit: 100 +-- prevent a function referenced in partition key from being dropped +DROP FUNCTION plusone(int) +-- +FUNCTION: name="plusone" function="plusone" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION plusone(int)" +== 093 +-- truncate_limit: 100 +-- partitioned table cannot participate in regular inheritance +CREATE TABLE partitioned2 ( + a int, + b text +) PARTITION BY RANGE ((a+1), substr(b, 1, 5)) +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned2 (a int, b text) PARTITION BY RANGE ((a + 1), (substr(b, 1, 5)))" +== 094 +-- truncate_limit: 100 +CREATE TABLE fail () INHERITS (partitioned2) +-- +TABLE: name="fail" schema="" table="fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail () INHERITS (partitioned2)" +== 095 +-- truncate_limit: 100 +-- Partition key in describe output + +INSERT INTO partitioned2 VALUES (1, 'hello') +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO partitioned2 VALUES (1, 'hello')" +== 096 +-- truncate_limit: 100 +CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc') +-- +TABLE: name="part2_1" schema="" table="part2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc')" +== 097 +-- truncate_limit: 100 +DROP TABLE partitioned, partitioned2 +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE partitioned, partitioned2" +== 098 +-- truncate_limit: 100 +-- check reference to partitioned table's rowtype in partition descriptor +create table partitioned (a int, b int) + partition by list ((row(a, b)::partitioned)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, b int) PARTITION BY LIST ((ROW(a, b)::partitioned))" +== 099 +-- truncate_limit: 100 +create table partitioned1 + partition of partitioned for values in ('(1,2)'::partitioned) +-- +TABLE: name="partitioned1" schema="" table="partitioned1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned1 PARTITION OF partitioned FOR VALUES IN ('(1,2)'::partitioned)" +== 100 +-- truncate_limit: 100 +create table partitioned2 + partition of partitioned for values in ('(2,4)'::partitioned) +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned2 PARTITION OF partitioned FOR VALUES IN ('(2,4)'::partitioned)" +== 101 +-- truncate_limit: 100 +explain (costs off) +select * from partitioned where row(a,b)::partitioned = '(1,2)'::partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM partitioned WHERE ROW(a, b)::partitioned = '(1,2)'::partitioned" +== 102 +-- truncate_limit: 100 +drop table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE partitioned" +== 103 +-- truncate_limit: 100 +-- whole-row Var in partition key works too +create table partitioned (a int, b int) + partition by list ((partitioned)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a int, b int) PARTITION BY LIST ((partitioned))" +== 104 +-- truncate_limit: 100 +create table partitioned1 + partition of partitioned for values in ('(1,2)') +-- +TABLE: name="partitioned1" schema="" table="partitioned1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned1 PARTITION OF partitioned FOR VALUES IN ('(1,2)')" +== 105 +-- truncate_limit: 100 +create table partitioned2 + partition of partitioned for values in ('(2,4)') +-- +TABLE: name="partitioned2" schema="" table="partitioned2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned2 PARTITION OF partitioned FOR VALUES IN ('(2,4)')" +== 106 +-- truncate_limit: 100 +explain (costs off) +select * from partitioned where partitioned = '(1,2)'::partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +FILTER: schema="" table="" column="partitioned" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM partitioned WHERE partitioned = '(1,2)'::partitioned" +== 107 +-- truncate_limit: 100 +drop table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE partitioned" +== 108 +-- truncate_limit: 100 +-- check that dependencies of partition columns are handled correctly +create domain intdom1 as int +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN intdom1 AS int" +== 109 +-- truncate_limit: 100 +create table partitioned ( + a intdom1, + b text +) partition by range (a) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a intdom1, b text) PARTITION BY RANGE (a)" +== 110 +-- truncate_limit: 100 +alter table partitioned drop column a +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned DROP a" +== 111 +-- truncate_limit: 100 +-- fail + +drop domain intdom1 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN intdom1" +== 112 +-- truncate_limit: 100 +-- fail, requires cascade + +drop domain intdom1 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN intdom1 CASCADE" +== 113 +-- truncate_limit: 100 +table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM partitioned" +== 114 +-- truncate_limit: 100 +-- gone + +-- likewise for columns used in partition expressions +create domain intdom1 as int +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN intdom1 AS int" +== 115 +-- truncate_limit: 100 +create table partitioned ( + a intdom1, + b text +) partition by range (plusone(a)) +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned (a intdom1, b text) PARTITION BY RANGE ((plusone(a)))" +== 116 +-- truncate_limit: 100 +alter table partitioned drop column a +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE partitioned DROP a" +== 117 +-- truncate_limit: 100 +-- fail + +drop domain intdom1 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN intdom1" +== 118 +-- truncate_limit: 100 +-- fail, requires cascade + +drop domain intdom1 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN intdom1 CASCADE" +== 119 +-- truncate_limit: 100 +table partitioned +-- +TABLE: name="partitioned" schema="" table="partitioned" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM partitioned" +== 120 +-- truncate_limit: 100 +-- gone + + +|-- +-- Partitions +|-- + +-- check partition bound syntax + +CREATE TABLE list_parted ( + a int +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted (a int) PARTITION BY LIST (a)" +== 121 +-- truncate_limit: 100 +CREATE TABLE part_p1 PARTITION OF list_parted FOR VALUES IN ('1') +-- +TABLE: name="part_p1" schema="" table="part_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_p1 PARTITION OF list_parted FOR VALUES IN ('1')" +== 122 +-- truncate_limit: 100 +CREATE TABLE part_p2 PARTITION OF list_parted FOR VALUES IN (2) +-- +TABLE: name="part_p2" schema="" table="part_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_p2 PARTITION OF list_parted FOR VALUES IN (2)" +== 123 +-- truncate_limit: 100 +CREATE TABLE part_p3 PARTITION OF list_parted FOR VALUES IN ((2+1)) +-- +TABLE: name="part_p3" schema="" table="part_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_p3 PARTITION OF list_parted FOR VALUES IN (2 + 1)" +== 124 +-- truncate_limit: 100 +CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (null) +-- +TABLE: name="part_null" schema="" table="part_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (NULL)" +== 125 +-- truncate_limit: 100 +-- forbidden expressions for partition bound with list partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename)" +== 126 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename.somename) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename.somename)" +== 127 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (a) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (a)" +== 128 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(a)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(a))" +== 129 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(somename)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(somename))" +== 130 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(1)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(1))" +== 131 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((select 1)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((SELECT 1))" +== 132 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (generate_series(4, 6)) +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (generate_series(4, 6))" +== 133 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((1+1) collate "POSIX") +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((1 + 1) COLLATE \"POSIX\")" +== 134 +-- truncate_limit: 100 +-- syntax does not allow empty list of values for list partitions +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN () +-- +ERROR: syntax error at or near ")" +CURSORPOS: 130 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 135 +-- truncate_limit: 100 +-- trying to specify range for list partitioned table +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES FROM (1) TO (2) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES FROM (1) TO (2)" +== 136 +-- truncate_limit: 100 +-- trying to specify modulus and remainder for list partitioned table +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1)" +== 137 +-- truncate_limit: 100 +-- check default partition cannot be created more than once +CREATE TABLE part_default PARTITION OF list_parted DEFAULT +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_default PARTITION OF list_parted DEFAULT" +== 138 +-- truncate_limit: 100 +CREATE TABLE fail_default_part PARTITION OF list_parted DEFAULT +-- +TABLE: name="fail_default_part" schema="" table="fail_default_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_default_part PARTITION OF list_parted DEFAULT" +== 139 +-- truncate_limit: 100 +-- specified literal can't be cast to the partition column data type +CREATE TABLE bools ( + a bool +) PARTITION BY LIST (a) +-- +TABLE: name="bools" schema="" table="bools" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bools (a bool) PARTITION BY LIST (a)" +== 140 +-- truncate_limit: 100 +CREATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1) +-- +TABLE: name="bools_true" schema="" table="bools_true" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1)" +== 141 +-- truncate_limit: 100 +DROP TABLE bools +-- +TABLE: name="bools" schema="" table="bools" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bools" +== 142 +-- truncate_limit: 100 +-- specified literal can be cast, and the cast might not be immutable +CREATE TABLE moneyp ( + a money +) PARTITION BY LIST (a) +-- +TABLE: name="moneyp" schema="" table="moneyp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE moneyp (a money) PARTITION BY LIST (a)" +== 143 +-- truncate_limit: 100 +CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10) +-- +TABLE: name="moneyp_10" schema="" table="moneyp_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10)" +== 144 +-- truncate_limit: 100 +CREATE TABLE moneyp_11 PARTITION OF moneyp FOR VALUES IN ('11') +-- +TABLE: name="moneyp_11" schema="" table="moneyp_11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE moneyp_11 PARTITION OF moneyp FOR VALUES IN ('11')" +== 145 +-- truncate_limit: 100 +CREATE TABLE moneyp_12 PARTITION OF moneyp FOR VALUES IN (to_char(12, '99')::int) +-- +TABLE: name="moneyp_12" schema="" table="moneyp_12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE moneyp_12 PARTITION OF moneyp FOR VALUES IN (to_char(12, '99')::int)" +== 146 +-- truncate_limit: 100 +DROP TABLE moneyp +-- +TABLE: name="moneyp" schema="" table="moneyp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE moneyp" +== 147 +-- truncate_limit: 100 +-- cast is immutable +CREATE TABLE bigintp ( + a bigint +) PARTITION BY LIST (a) +-- +TABLE: name="bigintp" schema="" table="bigintp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bigintp (a bigint) PARTITION BY LIST (a)" +== 148 +-- truncate_limit: 100 +CREATE TABLE bigintp_10 PARTITION OF bigintp FOR VALUES IN (10) +-- +TABLE: name="bigintp_10" schema="" table="bigintp_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bigintp_10 PARTITION OF bigintp FOR VALUES IN (10)" +== 149 +-- truncate_limit: 100 +-- fails due to overlap: +CREATE TABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10') +-- +TABLE: name="bigintp_10_2" schema="" table="bigintp_10_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10')" +== 150 +-- truncate_limit: 100 +DROP TABLE bigintp +-- +TABLE: name="bigintp" schema="" table="bigintp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bigintp" +== 151 +-- truncate_limit: 100 +CREATE TABLE range_parted ( + a date +) PARTITION BY RANGE (a) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted (a date) PARTITION BY RANGE (a)" +== 152 +-- truncate_limit: 100 +-- forbidden expressions for partition bounds with range partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM (somename) TO ('2019-..." +== 153 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename.somename) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM (somename.somename) T..." +== 154 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (a) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM (a) TO ('2019-01-01')" +== 155 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(a)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM (max(a)) TO ('2019-01..." +== 156 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(somename)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM (max(somename)) TO ('..." +== 157 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max('2019-02-01'::date)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM (max('2019-02-01'::da..." +== 158 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM ((select 1)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM ((SELECT 1)) TO ('201..." +== 159 +-- truncate_limit: 100 +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (generate_series(1, 3)) TO ('2019-01-01') +-- +TABLE: name="part_bogus_expr_fail" schema="" table="part_bogus_expr_fail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted FOR VALUES FROM (generate_series(1, 3..." +== 160 +-- truncate_limit: 100 +-- trying to specify list for range partitioned table +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES IN ('a') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES IN ('a')" +== 161 +-- truncate_limit: 100 +-- trying to specify modulus and remainder for range partitioned table +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1)" +== 162 +-- truncate_limit: 100 +-- each of start and end bounds must have same number of values as the +-- length of the partition key +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('z') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('z')" +== 163 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a') TO ('z', 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a') TO ('z', 1)" +== 164 +-- truncate_limit: 100 +-- cannot specify null values in range bounds +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (maxvalue) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (NULL) TO (maxvalue)" +== 165 +-- truncate_limit: 100 +-- trying to specify modulus and remainder for range partitioned table +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1)" +== 166 +-- truncate_limit: 100 +-- check partition bound syntax for the hash partition +CREATE TABLE hash_parted ( + a int +) PARTITION BY HASH (a) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_parted (a int) PARTITION BY HASH (a)" +== 167 +-- truncate_limit: 100 +CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 0) +-- +TABLE: name="hpart_1" schema="" table="hpart_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 0)" +== 168 +-- truncate_limit: 100 +CREATE TABLE hpart_2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 50, REMAINDER 1) +-- +TABLE: name="hpart_2" schema="" table="hpart_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 50, REMAINDER 1)" +== 169 +-- truncate_limit: 100 +CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200, REMAINDER 2) +-- +TABLE: name="hpart_3" schema="" table="hpart_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200, REMAINDER 2)" +== 170 +-- truncate_limit: 100 +CREATE TABLE hpart_4 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 3) +-- +TABLE: name="hpart_4" schema="" table="hpart_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart_4 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 3)" +== 171 +-- truncate_limit: 100 +-- modulus 25 is factor of modulus of 50 but 10 is not a factor of 25. +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 25, REMAINDER 3) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 25, REMAINDER 3)" +== 172 +-- truncate_limit: 100 +-- previous modulus 50 is factor of 150 but this modulus is not a factor of next modulus 200. +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3)" +== 173 +-- truncate_limit: 100 +-- overlapping remainders +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 100, REMAINDER 3) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 100, REMAINDER 3)" +== 174 +-- truncate_limit: 100 +-- trying to specify range for the hash partitioned table +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES FROM ('a', 1) TO ('z') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES FROM ('a', 1) TO ('z')" +== 175 +-- truncate_limit: 100 +-- trying to specify list value for the hash partitioned table +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES IN (1000) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES IN (1000)" +== 176 +-- truncate_limit: 100 +-- trying to create default partition for the hash partitioned table +CREATE TABLE fail_default_part PARTITION OF hash_parted DEFAULT +-- +TABLE: name="fail_default_part" schema="" table="fail_default_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_default_part PARTITION OF hash_parted DEFAULT" +== 177 +-- truncate_limit: 100 +-- check if compatible with the specified parent + +-- cannot create as partition of a non-partitioned table +CREATE TABLE unparted ( + a int +) +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unparted (a int)" +== 178 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF unparted FOR VALUES IN ('a') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF unparted FOR VALUES IN ('a')" +== 179 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF unparted FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF unparted FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 180 +-- truncate_limit: 100 +DROP TABLE unparted +-- +TABLE: name="unparted" schema="" table="unparted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unparted" +== 181 +-- truncate_limit: 100 +-- cannot create a permanent rel as partition of a temp rel +CREATE TEMP TABLE temp_parted ( + a int +) PARTITION BY LIST (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted (a int) PARTITION BY LIST (a)" +== 182 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a')" +== 183 +-- truncate_limit: 100 +DROP TABLE temp_parted +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_parted" +== 184 +-- truncate_limit: 100 +-- check for partition bound overlap and other invalid specifications + +CREATE TABLE list_parted2 ( + a varchar +) PARTITION BY LIST (a) +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted2 (a varchar) PARTITION BY LIST (a)" +== 185 +-- truncate_limit: 100 +CREATE TABLE part_null_z PARTITION OF list_parted2 FOR VALUES IN (null, 'z') +-- +TABLE: name="part_null_z" schema="" table="part_null_z" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_null_z PARTITION OF list_parted2 FOR VALUES IN (NULL, 'z')" +== 186 +-- truncate_limit: 100 +CREATE TABLE part_ab PARTITION OF list_parted2 FOR VALUES IN ('a', 'b') +-- +TABLE: name="part_ab" schema="" table="part_ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ab PARTITION OF list_parted2 FOR VALUES IN ('a', 'b')" +== 187 +-- truncate_limit: 100 +CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT +-- +TABLE: name="list_parted2_def" schema="" table="list_parted2_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT" +== 188 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN (null) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN (NULL)" +== 189 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c')" +== 190 +-- truncate_limit: 100 +-- check default partition overlap +INSERT INTO list_parted2 VALUES('X') +-- +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted2 VALUES ('X')" +== 191 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('W', 'X', 'Y') +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('W', 'X', 'Y')" +== 192 +-- truncate_limit: 100 +CREATE TABLE range_parted2 ( + a int +) PARTITION BY RANGE (a) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted2 (a int) PARTITION BY RANGE (a)" +== 193 +-- truncate_limit: 100 +-- trying to create range partition with empty range +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0)" +== 194 +-- truncate_limit: 100 +-- note that the range '[1, 1)' has no elements +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1)" +== 195 +-- truncate_limit: 100 +CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1) +-- +TABLE: name="part0" schema="" table="part0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1)" +== 196 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2)" +== 197 +-- truncate_limit: 100 +CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10)" +== 198 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (-1) TO (1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (-1) TO (1)" +== 199 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue)" +== 200 +-- truncate_limit: 100 +CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30)" +== 201 +-- truncate_limit: 100 +CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40)" +== 202 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30)" +== 203 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50)" +== 204 +-- truncate_limit: 100 +-- Create a default partition for range partitioned table +CREATE TABLE range2_default PARTITION OF range_parted2 DEFAULT +-- +TABLE: name="range2_default" schema="" table="range2_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range2_default PARTITION OF range_parted2 DEFAULT" +== 205 +-- truncate_limit: 100 +-- More than one default partition is not allowed, so this should give error +CREATE TABLE fail_default_part PARTITION OF range_parted2 DEFAULT +-- +TABLE: name="fail_default_part" schema="" table="fail_default_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_default_part PARTITION OF range_parted2 DEFAULT" +== 206 +-- truncate_limit: 100 +-- Check if the range for default partitions overlap +INSERT INTO range_parted2 VALUES (85) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted2 VALUES (85)" +== 207 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (80) TO (90) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (80) TO (90)" +== 208 +-- truncate_limit: 100 +CREATE TABLE part4 PARTITION OF range_parted2 FOR VALUES FROM (90) TO (100) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part4 PARTITION OF range_parted2 FOR VALUES FROM (90) TO (100)" +== 209 +-- truncate_limit: 100 +-- now check for multi-column range partition key +CREATE TABLE range_parted3 ( + a int, + b int +) PARTITION BY RANGE (a, (b+1)) +-- +TABLE: name="range_parted3" schema="" table="range_parted3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted3 (a int, b int) PARTITION BY RANGE (a, (b + 1))" +== 210 +-- truncate_limit: 100 +CREATE TABLE part00 PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, maxvalue) +-- +TABLE: name="part00" schema="" table="part00" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part00 PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, maxvalue)" +== 211 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, 1)" +== 212 +-- truncate_limit: 100 +CREATE TABLE part10 PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, 1) +-- +TABLE: name="part10" schema="" table="part10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part10 PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, 1)" +== 213 +-- truncate_limit: 100 +CREATE TABLE part11 PARTITION OF range_parted3 FOR VALUES FROM (1, 1) TO (1, 10) +-- +TABLE: name="part11" schema="" table="part11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part11 PARTITION OF range_parted3 FOR VALUES FROM (1, 1) TO (1, 10)" +== 214 +-- truncate_limit: 100 +CREATE TABLE part12 PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, maxvalue) +-- +TABLE: name="part12" schema="" table="part12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part12 PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, maxvalue)" +== 215 +-- truncate_limit: 100 +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, 20) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, 20)" +== 216 +-- truncate_limit: 100 +CREATE TABLE range3_default PARTITION OF range_parted3 DEFAULT +-- +TABLE: name="range3_default" schema="" table="range3_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range3_default PARTITION OF range_parted3 DEFAULT" +== 217 +-- truncate_limit: 100 +-- cannot create a partition that says column b is allowed to range +-- from -infinity to +infinity, while there exist partitions that have +-- more specific ranges +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, maxvalue) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, maxvalue)" +== 218 +-- truncate_limit: 100 +-- check for partition bound overlap and other invalid specifications for the hash partition +CREATE TABLE hash_parted2 ( + a varchar +) PARTITION BY HASH (a) +-- +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_parted2 (a varchar) PARTITION BY HASH (a)" +== 219 +-- truncate_limit: 100 +CREATE TABLE h2part_1 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 4, REMAINDER 2) +-- +TABLE: name="h2part_1" schema="" table="h2part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE h2part_1 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 4, REMAINDER 2)" +== 220 +-- truncate_limit: 100 +CREATE TABLE h2part_2 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 0) +-- +TABLE: name="h2part_2" schema="" table="h2part_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE h2part_2 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 0)" +== 221 +-- truncate_limit: 100 +CREATE TABLE h2part_3 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 4) +-- +TABLE: name="h2part_3" schema="" table="h2part_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE h2part_3 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 4)" +== 222 +-- truncate_limit: 100 +CREATE TABLE h2part_4 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 5) +-- +TABLE: name="h2part_4" schema="" table="h2part_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE h2part_4 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 5)" +== 223 +-- truncate_limit: 100 +-- overlap with part_4 +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 224 +-- truncate_limit: 100 +-- modulus must be greater than zero +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 0, REMAINDER 1) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 0, REMAINDER 1)" +== 225 +-- truncate_limit: 100 +-- remainder must be greater than or equal to zero and less than modulus +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 8) +-- +TABLE: name="fail_part" schema="" table="fail_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 8)" +== 226 +-- truncate_limit: 100 +-- check schema propagation from parent + +CREATE TABLE parted ( + a text, + b int NOT NULL DEFAULT 0, + CONSTRAINT check_a CHECK (length(a) > 0) +) PARTITION BY LIST (a) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted (a text, b int NOT NULL DEFAULT 0, CONSTRAINT check_a CHECK (length(a) > 0)) ..." +== 227 +-- truncate_limit: 100 +CREATE TABLE part_a PARTITION OF parted FOR VALUES IN ('a') +-- +TABLE: name="part_a" schema="" table="part_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_a PARTITION OF parted FOR VALUES IN ('a')" +== 228 +-- truncate_limit: 100 +-- only inherited attributes (never local ones) +SELECT attname, attislocal, attinhcount FROM pg_attribute + WHERE attrelid = 'part_a'::regclass and attnum > 0 + ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT attname, attislocal, attinhcount FROM pg_attribute WHERE ... ORDER BY attnum" +== 229 +-- truncate_limit: 100 +-- able to specify column default, column constraint, and table constraint + +-- first check the "column specified more than once" error +CREATE TABLE part_b PARTITION OF parted ( + b NOT NULL, + b DEFAULT 1, + b CHECK (b >= 0), + CONSTRAINT check_a CHECK (length(a) > 0) +) FOR VALUES IN ('b') +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_b PARTITION OF parted (b NOT NULL, b DEFAULT 1, b CHECK (b >= 0), CONSTRAINT ch..." +== 230 +-- truncate_limit: 100 +CREATE TABLE part_b PARTITION OF parted ( + b NOT NULL DEFAULT 1, + CONSTRAINT check_a CHECK (length(a) > 0), + CONSTRAINT check_b CHECK (b >= 0) +) FOR VALUES IN ('b') +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_b PARTITION OF parted (b NOT NULL DEFAULT 1, CONSTRAINT check_a CHECK (length(a..." +== 231 +-- truncate_limit: 100 +-- conislocal should be false for any merged constraints, true otherwise +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname" +== 232 +-- truncate_limit: 100 +-- Once check_b is added to the parent, it should be made non-local for part_b +ALTER TABLE parted ADD CONSTRAINT check_b CHECK (b >= 0) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted ADD CONSTRAINT check_b CHECK (b >= 0)" +== 233 +-- truncate_limit: 100 +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname" +== 234 +-- truncate_limit: 100 +-- Neither check_a nor check_b are droppable from part_b +ALTER TABLE part_b DROP CONSTRAINT check_a +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_b DROP CONSTRAINT check_a" +== 235 +-- truncate_limit: 100 +ALTER TABLE part_b DROP CONSTRAINT check_b +-- +TABLE: name="part_b" schema="" table="part_b" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_b DROP CONSTRAINT check_b" +== 236 +-- truncate_limit: 100 +-- And dropping it from parted should leave no trace of them on part_b, unlike +-- traditional inheritance where they will be left behind, because they would +-- be local constraints. +ALTER TABLE parted DROP CONSTRAINT check_a, DROP CONSTRAINT check_b +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted DROP CONSTRAINT check_a, DROP CONSTRAINT check_b" +== 237 +-- truncate_limit: 100 +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname" +== 238 +-- truncate_limit: 100 +-- specify PARTITION BY for a partition +CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c) +-- +TABLE: name="fail_part_col_not_found" schema="" table="fail_part_col_not_found" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c)" +== 239 +-- truncate_limit: 100 +CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b)) +-- +TABLE: name="part_c" schema="" table="part_c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_c PARTITION OF parted (b NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY R..." +== 240 +-- truncate_limit: 100 +-- create a level-2 partition +CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10) +-- +TABLE: name="part_c_1_10" schema="" table="part_c_1_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10)" +== 241 +-- truncate_limit: 100 +-- check that NOT NULL and default value are inherited correctly +create table parted_notnull_inh_test (a int default 1, b int not null default 0) partition by list (a) +-- +TABLE: name="parted_notnull_inh_test" schema="" table="parted_notnull_inh_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_notnull_inh_test (a int DEFAULT 1, b int NOT NULL DEFAULT 0) PARTITION BY LIS..." +== 242 +-- truncate_limit: 100 +create table parted_notnull_inh_test1 partition of parted_notnull_inh_test (a not null, b default 1) for values in (1) +-- +TABLE: name="parted_notnull_inh_test1" schema="" table="parted_notnull_inh_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_notnull_inh_test1 PARTITION OF parted_notnull_inh_test (a NOT NULL, b DEFAULT..." +== 243 +-- truncate_limit: 100 +insert into parted_notnull_inh_test (b) values (null) +-- +TABLE: name="parted_notnull_inh_test" schema="" table="parted_notnull_inh_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_notnull_inh_test (b) VALUES (NULL)" +== 244 +-- truncate_limit: 100 +-- note that while b's default is overridden, a's default is preserved +drop table parted_notnull_inh_test +-- +TABLE: name="parted_notnull_inh_test" schema="" table="parted_notnull_inh_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_notnull_inh_test" +== 245 +-- truncate_limit: 100 +-- check that collations are assigned in partition bound expressions +create table parted_boolean_col (a bool, b text) partition by list(a) +-- +TABLE: name="parted_boolean_col" schema="" table="parted_boolean_col" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_boolean_col (a bool, b text) PARTITION BY LIST (a)" +== 246 +-- truncate_limit: 100 +create table parted_boolean_less partition of parted_boolean_col + for values in ('foo' < 'bar') +-- +TABLE: name="parted_boolean_less" schema="" table="parted_boolean_less" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_boolean_less PARTITION OF parted_boolean_col FOR VALUES IN ('foo' < 'bar')" +== 247 +-- truncate_limit: 100 +create table parted_boolean_greater partition of parted_boolean_col + for values in ('foo' > 'bar') +-- +TABLE: name="parted_boolean_greater" schema="" table="parted_boolean_greater" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_boolean_greater PARTITION OF parted_boolean_col FOR VALUES IN ('foo' > 'bar')" +== 248 +-- truncate_limit: 100 +drop table parted_boolean_col +-- +TABLE: name="parted_boolean_col" schema="" table="parted_boolean_col" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_boolean_col" +== 249 +-- truncate_limit: 100 +-- check for a conflicting COLLATE clause +create table parted_collate_must_match (a text collate "C", b text collate "C") + partition by range (a) +-- +TABLE: name="parted_collate_must_match" schema="" table="parted_collate_must_match" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_collate_must_match (a text COLLATE \"C\", b text COLLATE \"C\") PARTITION BY RANG..." +== 250 +-- truncate_limit: 100 +-- on the partition key +create table parted_collate_must_match1 partition of parted_collate_must_match + (a collate "POSIX") for values from ('a') to ('m') +-- +TABLE: name="parted_collate_must_match1" schema="" table="parted_collate_must_match1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_collate_must_match1 PARTITION OF parted_collate_must_match (a COLLATE \"POSIX\"..." +== 251 +-- truncate_limit: 100 +-- on another column +create table parted_collate_must_match2 partition of parted_collate_must_match + (b collate "POSIX") for values from ('m') to ('z') +-- +TABLE: name="parted_collate_must_match2" schema="" table="parted_collate_must_match2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_collate_must_match2 PARTITION OF parted_collate_must_match (b COLLATE \"POSIX\"..." +== 252 +-- truncate_limit: 100 +drop table parted_collate_must_match +-- +TABLE: name="parted_collate_must_match" schema="" table="parted_collate_must_match" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_collate_must_match" +== 253 +-- truncate_limit: 100 +-- check that non-matching collations for partition bound +-- expressions are coerced to the right collation + +create table test_part_coll_posix (a text) partition by range (a collate "POSIX") +-- +TABLE: name="test_part_coll_posix" schema="" table="test_part_coll_posix" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_part_coll_posix (a text) PARTITION BY RANGE (a COLLATE \"POSIX\")" +== 254 +-- truncate_limit: 100 +-- ok, collation is implicitly coerced +create table test_part_coll partition of test_part_coll_posix for values from ('a' collate "C") to ('g') +-- +TABLE: name="test_part_coll" schema="" table="test_part_coll" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_part_coll PARTITION OF test_part_coll_posix FOR VALUES FROM ('a' COLLATE \"C\") T..." +== 255 +-- truncate_limit: 100 +-- ok +create table test_part_coll2 partition of test_part_coll_posix for values from ('g') to ('m') +-- +TABLE: name="test_part_coll2" schema="" table="test_part_coll2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_part_coll2 PARTITION OF test_part_coll_posix FOR VALUES FROM ('g') TO ('m')" +== 256 +-- truncate_limit: 100 +-- ok, collation is implicitly coerced +create table test_part_coll_cast partition of test_part_coll_posix for values from (name 'm' collate "C") to ('s') +-- +TABLE: name="test_part_coll_cast" schema="" table="test_part_coll_cast" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_part_coll_cast PARTITION OF test_part_coll_posix FOR VALUES FROM ('m'::name COL..." +== 257 +-- truncate_limit: 100 +-- ok; partition collation silently overrides the default collation of type 'name' +create table test_part_coll_cast2 partition of test_part_coll_posix for values from (name 's') to ('z') +-- +TABLE: name="test_part_coll_cast2" schema="" table="test_part_coll_cast2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_part_coll_cast2 PARTITION OF test_part_coll_posix FOR VALUES FROM ('s'::name) T..." +== 258 +-- truncate_limit: 100 +drop table test_part_coll_posix +-- +TABLE: name="test_part_coll_posix" schema="" table="test_part_coll_posix" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_part_coll_posix" +== 259 +-- truncate_limit: 100 +-- Partition bound in describe output + +-- Both partition bound and partition key in describe output + +-- a level-2 partition's constraint will include the parent's expressions + +-- Show partition count in the parent's describe output +-- Tempted to include \d+ output listing partitions with bound info but +-- output could vary depending on the order in which partition oids are +-- returned. + +-- check that we get the expected partition constraints +CREATE TABLE range_parted4 (a int, b int, c int) PARTITION BY RANGE (abs(a), abs(b), c) +-- +TABLE: name="range_parted4" schema="" table="range_parted4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted4 (a int, b int, c int) PARTITION BY RANGE ((abs(a)), (abs(b)), c)" +== 260 +-- truncate_limit: 100 +CREATE TABLE unbounded_range_part PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, MINVALUE, MINVALUE) TO (MAXVALUE, MAXVALUE, MAXVALUE) +-- +TABLE: name="unbounded_range_part" schema="" table="unbounded_range_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unbounded_range_part PARTITION OF range_parted4 FOR VALUES FROM (minvalue, minvalue,..." +== 261 +-- truncate_limit: 100 +DROP TABLE unbounded_range_part +-- +TABLE: name="unbounded_range_part" schema="" table="unbounded_range_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE unbounded_range_part" +== 262 +-- truncate_limit: 100 +CREATE TABLE range_parted4_1 PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, MINVALUE, MINVALUE) TO (1, MAXVALUE, MAXVALUE) +-- +TABLE: name="range_parted4_1" schema="" table="range_parted4_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted4_1 PARTITION OF range_parted4 FOR VALUES FROM (minvalue, minvalue, minv..." +== 263 +-- truncate_limit: 100 +CREATE TABLE range_parted4_2 PARTITION OF range_parted4 FOR VALUES FROM (3, 4, 5) TO (6, 7, MAXVALUE) +-- +TABLE: name="range_parted4_2" schema="" table="range_parted4_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted4_2 PARTITION OF range_parted4 FOR VALUES FROM (3, 4, 5) TO (6, 7, maxva..." +== 264 +-- truncate_limit: 100 +CREATE TABLE range_parted4_3 PARTITION OF range_parted4 FOR VALUES FROM (6, 8, MINVALUE) TO (9, MAXVALUE, MAXVALUE) +-- +TABLE: name="range_parted4_3" schema="" table="range_parted4_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted4_3 PARTITION OF range_parted4 FOR VALUES FROM (6, 8, minvalue) TO (9, m..." +== 265 +-- truncate_limit: 100 +DROP TABLE range_parted4 +-- +TABLE: name="range_parted4" schema="" table="range_parted4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE range_parted4" +== 266 +-- truncate_limit: 100 +-- user-defined operator class in partition key +CREATE FUNCTION my_int4_sort(int4,int4) RETURNS int LANGUAGE sql + AS $$ SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$ +-- +FUNCTION: name="my_int4_sort" function="my_int4_sort" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION my_int4_sort(int4, int4) RETURNS int LANGUAGE sql AS $$ SELECT CASE WHEN $1 = $2 ..." +== 267 +-- truncate_limit: 100 +CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4,int4), OPERATOR 2 <= (int4,int4), + OPERATOR 3 = (int4,int4), OPERATOR 4 >= (int4,int4), + OPERATOR 5 > (int4,int4), FUNCTION 1 my_int4_sort(int4,int4) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS OPERATOR 1 <(int4, int4), OPERAT..." +== 268 +-- truncate_limit: 100 +CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops) +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops)" +== 269 +-- truncate_limit: 100 +CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="partkey_t_1" schema="" table="partkey_t_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000)" +== 270 +-- truncate_limit: 100 +INSERT INTO partkey_t VALUES (100) +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO partkey_t VALUES (100)" +== 271 +-- truncate_limit: 100 +INSERT INTO partkey_t VALUES (200) +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO partkey_t VALUES (200)" +== 272 +-- truncate_limit: 100 +-- cleanup +DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3 +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="list_parted2" schema="" table="list_parted2" ctx=DDL +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +TABLE: name="range_parted3" schema="" table="range_parted3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3" +== 273 +-- truncate_limit: 100 +DROP TABLE partkey_t, hash_parted, hash_parted2 +-- +TABLE: name="partkey_t" schema="" table="partkey_t" ctx=DDL +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +TABLE: name="hash_parted2" schema="" table="hash_parted2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE partkey_t, hash_parted, hash_parted2" +== 274 +-- truncate_limit: 100 +DROP OPERATOR CLASS test_int4_ops USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS test_int4_ops USING btree" +== 275 +-- truncate_limit: 100 +DROP FUNCTION my_int4_sort(int4,int4) +-- +FUNCTION: name="my_int4_sort" function="my_int4_sort" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION my_int4_sort(int4, int4)" +== 276 +-- truncate_limit: 100 +-- comments on partitioned tables columns +CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a) +-- +TABLE: name="parted_col_comment" schema="" table="parted_col_comment" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a)" +== 277 +-- truncate_limit: 100 +COMMENT ON TABLE parted_col_comment IS 'Am partitioned table' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TABLE parted_col_comment IS 'Am partitioned table'" +== 278 +-- truncate_limit: 100 +COMMENT ON COLUMN parted_col_comment.a IS 'Partition key' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN parted_col_comment.a IS 'Partition key'" +== 279 +-- truncate_limit: 100 +SELECT obj_description('parted_col_comment'::regclass) +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT obj_description('parted_col_comment'::regclass)" +== 280 +-- truncate_limit: 100 +DROP TABLE parted_col_comment +-- +TABLE: name="parted_col_comment" schema="" table="parted_col_comment" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_col_comment" +== 281 +-- truncate_limit: 100 +-- specifying storage parameters for partitioned tables is not supported +CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a) WITH (fillfactor=100) +-- +TABLE: name="parted_col_comment" schema="" table="parted_col_comment" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a) WITH (fillfactor=100)" +== 282 +-- truncate_limit: 100 +-- list partitioning on array type column +CREATE TABLE arrlp (a int[]) PARTITION BY LIST (a) +-- +TABLE: name="arrlp" schema="" table="arrlp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE arrlp (a int[]) PARTITION BY LIST (a)" +== 283 +-- truncate_limit: 100 +CREATE TABLE arrlp12 PARTITION OF arrlp FOR VALUES IN ('{1}', '{2}') +-- +TABLE: name="arrlp12" schema="" table="arrlp12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE arrlp12 PARTITION OF arrlp FOR VALUES IN ('{1}', '{2}')" +== 284 +-- truncate_limit: 100 +DROP TABLE arrlp +-- +TABLE: name="arrlp" schema="" table="arrlp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE arrlp" +== 285 +-- truncate_limit: 100 +-- partition on boolean column +create table boolspart (a bool) partition by list (a) +-- +TABLE: name="boolspart" schema="" table="boolspart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolspart (a bool) PARTITION BY LIST (a)" +== 286 +-- truncate_limit: 100 +create table boolspart_t partition of boolspart for values in (true) +-- +TABLE: name="boolspart_t" schema="" table="boolspart_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolspart_t PARTITION OF boolspart FOR VALUES IN (true)" +== 287 +-- truncate_limit: 100 +create table boolspart_f partition of boolspart for values in (false) +-- +TABLE: name="boolspart_f" schema="" table="boolspart_f" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolspart_f PARTITION OF boolspart FOR VALUES IN (false)" +== 288 +-- truncate_limit: 100 +drop table boolspart +-- +TABLE: name="boolspart" schema="" table="boolspart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE boolspart" +== 289 +-- truncate_limit: 100 +-- partitions mixing temporary and permanent relations +create table perm_parted (a int) partition by list (a) +-- +TABLE: name="perm_parted" schema="" table="perm_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE perm_parted (a int) PARTITION BY LIST (a)" +== 290 +-- truncate_limit: 100 +create temporary table temp_parted (a int) partition by list (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted (a int) PARTITION BY LIST (a)" +== 291 +-- truncate_limit: 100 +create table perm_part partition of temp_parted default +-- +TABLE: name="perm_part" schema="" table="perm_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE perm_part PARTITION OF temp_parted DEFAULT" +== 292 +-- truncate_limit: 100 +-- error +create temp table temp_part partition of perm_parted default +-- +TABLE: name="temp_part" schema="" table="temp_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_part PARTITION OF perm_parted DEFAULT" +== 293 +-- truncate_limit: 100 +-- error +create temp table temp_part partition of temp_parted default +-- +TABLE: name="temp_part" schema="" table="temp_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_part PARTITION OF temp_parted DEFAULT" +== 294 +-- truncate_limit: 100 +-- ok +drop table perm_parted cascade +-- +TABLE: name="perm_parted" schema="" table="perm_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE perm_parted CASCADE" +== 295 +-- truncate_limit: 100 +drop table temp_parted cascade +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_parted CASCADE" +== 296 +-- truncate_limit: 100 +-- check that adding partitions to a table while it is being used is prevented +create table tab_part_create (a int) partition by list (a) +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tab_part_create (a int) PARTITION BY LIST (a)" +== 297 +-- truncate_limit: 100 +create or replace function func_part_create() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_create_1 partition of tab_part_create for values in (1)'; + return null; + end $$ +-- +FUNCTION: name="func_part_create" function="func_part_create" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION func_part_create() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n ..." +== 298 +-- truncate_limit: 100 +create trigger trig_part_create before insert on tab_part_create + for each statement execute procedure func_part_create() +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_part_create BEFORE INSERT ON tab_part_create EXECUTE FUNCTION func_part_create()" +== 299 +-- truncate_limit: 100 +insert into tab_part_create values (1) +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tab_part_create VALUES (1)" +== 300 +-- truncate_limit: 100 +drop table tab_part_create +-- +TABLE: name="tab_part_create" schema="" table="tab_part_create" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tab_part_create" +== 301 +-- truncate_limit: 100 +drop function func_part_create() +-- +FUNCTION: name="func_part_create" function="func_part_create" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION func_part_create()" +== 302 +-- truncate_limit: 100 +-- test using a volatile expression as partition bound +create table volatile_partbound_test (partkey timestamp) partition by range (partkey) +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE volatile_partbound_test (partkey timestamp) PARTITION BY RANGE (partkey)" +== 303 +-- truncate_limit: 100 +create table volatile_partbound_test1 partition of volatile_partbound_test for values from (minvalue) to (current_timestamp) +-- +TABLE: name="volatile_partbound_test1" schema="" table="volatile_partbound_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE volatile_partbound_test1 PARTITION OF volatile_partbound_test FOR VALUES FROM (minva..." +== 304 +-- truncate_limit: 100 +create table volatile_partbound_test2 partition of volatile_partbound_test for values from (current_timestamp) to (maxvalue) +-- +TABLE: name="volatile_partbound_test2" schema="" table="volatile_partbound_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE volatile_partbound_test2 PARTITION OF volatile_partbound_test FOR VALUES FROM (curre..." +== 305 +-- truncate_limit: 100 +-- this should go into the partition volatile_partbound_test2 +insert into volatile_partbound_test values (current_timestamp) +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO volatile_partbound_test VALUES (current_timestamp)" +== 306 +-- truncate_limit: 100 +select tableoid::regclass from volatile_partbound_test +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass FROM volatile_partbound_test" +== 307 +-- truncate_limit: 100 +drop table volatile_partbound_test +-- +TABLE: name="volatile_partbound_test" schema="" table="volatile_partbound_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE volatile_partbound_test" +== 308 +-- truncate_limit: 100 +-- test the case where a check constraint on default partition allows +-- to avoid scanning it when adding a new partition +create table defcheck (a int, b int) partition by list (b) +-- +TABLE: name="defcheck" schema="" table="defcheck" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defcheck (a int, b int) PARTITION BY LIST (b)" +== 309 +-- truncate_limit: 100 +create table defcheck_def (a int, c int, b int) +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defcheck_def (a int, c int, b int)" +== 310 +-- truncate_limit: 100 +alter table defcheck_def drop c +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defcheck_def DROP c" +== 311 +-- truncate_limit: 100 +alter table defcheck attach partition defcheck_def default +-- +TABLE: name="defcheck" schema="" table="defcheck" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defcheck ATTACH PARTITION defcheck_def DEFAULT" +== 312 +-- truncate_limit: 100 +alter table defcheck_def add check (b <= 0 and b is not null) +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defcheck_def ADD CHECK (b <= 0 AND b IS NOT NULL)" +== 313 +-- truncate_limit: 100 +create table defcheck_1 partition of defcheck for values in (1, null) +-- +TABLE: name="defcheck_1" schema="" table="defcheck_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defcheck_1 PARTITION OF defcheck FOR VALUES IN (1, NULL)" +== 314 +-- truncate_limit: 100 +-- test that complex default partition constraints are enforced correctly +insert into defcheck_def values (0, 0) +-- +TABLE: name="defcheck_def" schema="" table="defcheck_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defcheck_def VALUES (0, 0)" +== 315 +-- truncate_limit: 100 +create table defcheck_0 partition of defcheck for values in (0) +-- +TABLE: name="defcheck_0" schema="" table="defcheck_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defcheck_0 PARTITION OF defcheck FOR VALUES IN (0)" +== 316 +-- truncate_limit: 100 +drop table defcheck +-- +TABLE: name="defcheck" schema="" table="defcheck" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE defcheck" +== 317 +-- truncate_limit: 100 +-- tests of column drop with partition tables and indexes using +-- predicates and expressions. +create table part_column_drop ( + useless_1 int, + id int, + useless_2 int, + d int, + b int, + useless_3 int +) partition by range (id) +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_column_drop (useless_1 int, id int, useless_2 int, d int, b int, useless_3 int)..." +== 318 +-- truncate_limit: 100 +alter table part_column_drop drop column useless_1 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_column_drop DROP useless_1" +== 319 +-- truncate_limit: 100 +alter table part_column_drop drop column useless_2 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_column_drop DROP useless_2" +== 320 +-- truncate_limit: 100 +alter table part_column_drop drop column useless_3 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_column_drop DROP useless_3" +== 321 +-- truncate_limit: 100 +create index part_column_drop_b_pred on part_column_drop(b) where b = 1 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX part_column_drop_b_pred ON part_column_drop USING btree (b) WHERE b = 1" +== 322 +-- truncate_limit: 100 +create index part_column_drop_b_expr on part_column_drop((b = 1)) +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX part_column_drop_b_expr ON part_column_drop USING btree ((b = 1))" +== 323 +-- truncate_limit: 100 +create index part_column_drop_d_pred on part_column_drop(d) where d = 2 +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX part_column_drop_d_pred ON part_column_drop USING btree (d) WHERE d = 2" +== 324 +-- truncate_limit: 100 +create index part_column_drop_d_expr on part_column_drop((d = 2)) +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX part_column_drop_d_expr ON part_column_drop USING btree ((d = 2))" +== 325 +-- truncate_limit: 100 +create table part_column_drop_1_10 partition of + part_column_drop for values from (1) to (10) +-- +TABLE: name="part_column_drop_1_10" schema="" table="part_column_drop_1_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_column_drop_1_10 PARTITION OF part_column_drop FOR VALUES FROM (1) TO (10)" +== 326 +-- truncate_limit: 100 +drop table part_column_drop +-- +TABLE: name="part_column_drop" schema="" table="part_column_drop" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_column_drop" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json new file mode 100644 index 0000000..267f283 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json @@ -0,0 +1,148 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_table_like.test b/parser/testdata/summary_truncate/postgres_regress/create_table_like.test new file mode 100644 index 0000000..db1fa6c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_table_like.test @@ -0,0 +1,1110 @@ +== 001 +-- truncate_limit: 100 +/* Test inheritance of structure (LIKE) */ +CREATE TABLE inhx (xx text DEFAULT 'text') +-- +TABLE: name="inhx" schema="" table="inhx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhx (xx text DEFAULT 'text')" +== 002 +-- truncate_limit: 100 +/* + * Test double inheritance + * + * Ensure that defaults are NOT included unless + * INCLUDING DEFAULTS is specified + */ +CREATE TABLE ctla (aa TEXT) +-- +TABLE: name="ctla" schema="" table="ctla" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctla (aa text)" +== 003 +-- truncate_limit: 100 +CREATE TABLE ctlb (bb TEXT) INHERITS (ctla) +-- +TABLE: name="ctlb" schema="" table="ctlb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlb (bb text) INHERITS (ctla)" +== 004 +-- truncate_limit: 100 +CREATE TABLE foo (LIKE nonexistent) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE foo (LIKE nonexistent)" +== 005 +-- truncate_limit: 100 +CREATE TABLE inhe (ee text, LIKE inhx) inherits (ctlb) +-- +TABLE: name="inhe" schema="" table="inhe" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhe (ee text, LIKE inhx) INHERITS (ctlb)" +== 006 +-- truncate_limit: 100 +INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4') +-- +TABLE: name="inhe" schema="" table="inhe" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4')" +== 007 +-- truncate_limit: 100 +SELECT * FROM inhe +-- +TABLE: name="inhe" schema="" table="inhe" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inhe" +== 008 +-- truncate_limit: 100 +/* Columns aa, bb, xx value NULL, ee */ +SELECT * FROM inhx +-- +TABLE: name="inhx" schema="" table="inhx" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inhx" +== 009 +-- truncate_limit: 100 +/* Empty set since LIKE inherits structure only */ +SELECT * FROM ctlb +-- +TABLE: name="ctlb" schema="" table="ctlb" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ctlb" +== 010 +-- truncate_limit: 100 +/* Has ee entry */ +SELECT * FROM ctla +-- +TABLE: name="ctla" schema="" table="ctla" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ctla" +== 011 +-- truncate_limit: 100 +/* Has ee entry */ + +CREATE TABLE inhf (LIKE inhx, LIKE inhx) +-- +TABLE: name="inhf" schema="" table="inhf" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhf (LIKE inhx, LIKE inhx)" +== 012 +-- truncate_limit: 100 +/* Throw error */ + +CREATE TABLE inhf (LIKE inhx INCLUDING DEFAULTS INCLUDING CONSTRAINTS) +-- +TABLE: name="inhf" schema="" table="inhf" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhf (LIKE inhx INCLUDING CONSTRAINTS INCLUDING DEFAULTS)" +== 013 +-- truncate_limit: 100 +INSERT INTO inhf DEFAULT VALUES +-- +TABLE: name="inhf" schema="" table="inhf" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO inhf DEFAULT VALUES" +== 014 +-- truncate_limit: 100 +SELECT * FROM inhf +-- +TABLE: name="inhf" schema="" table="inhf" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inhf" +== 015 +-- truncate_limit: 100 +/* Single entry with value 'text' */ + +ALTER TABLE inhx add constraint foo CHECK (xx = 'text') +-- +TABLE: name="inhx" schema="" table="inhx" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inhx ADD CONSTRAINT foo CHECK (xx = 'text')" +== 016 +-- truncate_limit: 100 +ALTER TABLE inhx ADD PRIMARY KEY (xx) +-- +TABLE: name="inhx" schema="" table="inhx" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inhx ADD PRIMARY KEY (xx)" +== 017 +-- truncate_limit: 100 +CREATE TABLE inhg (LIKE inhx) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhg (LIKE inhx)" +== 018 +-- truncate_limit: 100 +/* Doesn't copy constraint */ +INSERT INTO inhg VALUES ('foo') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg VALUES ('foo')" +== 019 +-- truncate_limit: 100 +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhg" +== 020 +-- truncate_limit: 100 +CREATE TABLE inhg (x text, LIKE inhx INCLUDING CONSTRAINTS, y text) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhg (x text, LIKE inhx INCLUDING CONSTRAINTS, y text)" +== 021 +-- truncate_limit: 100 +/* Copies constraints */ +INSERT INTO inhg VALUES ('x', 'text', 'y') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg VALUES ('x', 'text', 'y')" +== 022 +-- truncate_limit: 100 +/* Succeeds */ +INSERT INTO inhg VALUES ('x', 'text', 'y') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg VALUES ('x', 'text', 'y')" +== 023 +-- truncate_limit: 100 +/* Succeeds -- Unique constraints not copied */ +INSERT INTO inhg VALUES ('x', 'foo', 'y') +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg VALUES ('x', 'foo', 'y')" +== 024 +-- truncate_limit: 100 +/* fails due to constraint */ +SELECT * FROM inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inhg" +== 025 +-- truncate_limit: 100 +/* Two records with three columns in order x=x, xx=text, y=y */ +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhg" +== 026 +-- truncate_limit: 100 +CREATE TABLE test_like_id_1 (a bigint GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_id_1 (a bigint GENERATED ALWAYS AS IDENTITY, b text)" +== 027 +-- truncate_limit: 100 +INSERT INTO test_like_id_1 (b) VALUES ('b1') +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_id_1 (b) VALUES ('b1')" +== 028 +-- truncate_limit: 100 +SELECT * FROM test_like_id_1 +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_like_id_1" +== 029 +-- truncate_limit: 100 +CREATE TABLE test_like_id_2 (LIKE test_like_id_1) +-- +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_id_2 (LIKE test_like_id_1)" +== 030 +-- truncate_limit: 100 +INSERT INTO test_like_id_2 (b) VALUES ('b2') +-- +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_id_2 (b) VALUES ('b2')" +== 031 +-- truncate_limit: 100 +SELECT * FROM test_like_id_2 +-- +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_like_id_2" +== 032 +-- truncate_limit: 100 +-- identity was not copied +CREATE TABLE test_like_id_3 (LIKE test_like_id_1 INCLUDING IDENTITY) +-- +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_id_3 (LIKE test_like_id_1 INCLUDING IDENTITY)" +== 033 +-- truncate_limit: 100 +INSERT INTO test_like_id_3 (b) VALUES ('b3') +-- +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_id_3 (b) VALUES ('b3')" +== 034 +-- truncate_limit: 100 +SELECT * FROM test_like_id_3 +-- +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_like_id_3" +== 035 +-- truncate_limit: 100 +-- identity was copied and applied +DROP TABLE test_like_id_1, test_like_id_2, test_like_id_3 +-- +TABLE: name="test_like_id_1" schema="" table="test_like_id_1" ctx=DDL +TABLE: name="test_like_id_2" schema="" table="test_like_id_2" ctx=DDL +TABLE: name="test_like_id_3" schema="" table="test_like_id_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_like_id_1, test_like_id_2, test_like_id_3" +== 036 +-- truncate_limit: 100 +CREATE TABLE test_like_gen_1 (a int, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_gen_1 (a int, b int GENERATED ALWAYS AS (a * 2) STORED)" +== 037 +-- truncate_limit: 100 +INSERT INTO test_like_gen_1 (a) VALUES (1) +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_gen_1 (a) VALUES (1)" +== 038 +-- truncate_limit: 100 +SELECT * FROM test_like_gen_1 +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_like_gen_1" +== 039 +-- truncate_limit: 100 +CREATE TABLE test_like_gen_2 (LIKE test_like_gen_1) +-- +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_gen_2 (LIKE test_like_gen_1)" +== 040 +-- truncate_limit: 100 +INSERT INTO test_like_gen_2 (a) VALUES (1) +-- +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_gen_2 (a) VALUES (1)" +== 041 +-- truncate_limit: 100 +SELECT * FROM test_like_gen_2 +-- +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_like_gen_2" +== 042 +-- truncate_limit: 100 +CREATE TABLE test_like_gen_3 (LIKE test_like_gen_1 INCLUDING GENERATED) +-- +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_gen_3 (LIKE test_like_gen_1 INCLUDING GENERATED)" +== 043 +-- truncate_limit: 100 +INSERT INTO test_like_gen_3 (a) VALUES (1) +-- +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_gen_3 (a) VALUES (1)" +== 044 +-- truncate_limit: 100 +SELECT * FROM test_like_gen_3 +-- +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_like_gen_3" +== 045 +-- truncate_limit: 100 +DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3 +-- +TABLE: name="test_like_gen_1" schema="" table="test_like_gen_1" ctx=DDL +TABLE: name="test_like_gen_2" schema="" table="test_like_gen_2" ctx=DDL +TABLE: name="test_like_gen_3" schema="" table="test_like_gen_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3" +== 046 +-- truncate_limit: 100 +-- also test generated column with a "forward" reference (bug #16342) +CREATE TABLE test_like_4 (b int DEFAULT 42, + c int GENERATED ALWAYS AS (a * 2) STORED, + a int CHECK (a > 0)) +-- +TABLE: name="test_like_4" schema="" table="test_like_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_4 (b int DEFAULT 42, c int GENERATED ALWAYS AS (a * 2) STORED, a int CHECK..." +== 047 +-- truncate_limit: 100 +CREATE TABLE test_like_4a (LIKE test_like_4) +-- +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_4a (LIKE test_like_4)" +== 048 +-- truncate_limit: 100 +CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS) +-- +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS)" +== 049 +-- truncate_limit: 100 +CREATE TABLE test_like_4c (LIKE test_like_4 INCLUDING GENERATED) +-- +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_4c (LIKE test_like_4 INCLUDING GENERATED)" +== 050 +-- truncate_limit: 100 +CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERATED) +-- +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERATED)" +== 051 +-- truncate_limit: 100 +INSERT INTO test_like_4a (a) VALUES(11) +-- +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_4a (a) VALUES (11)" +== 052 +-- truncate_limit: 100 +SELECT a, b, c FROM test_like_4a +-- +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM test_like_4a" +== 053 +-- truncate_limit: 100 +INSERT INTO test_like_4b (a) VALUES(11) +-- +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_4b (a) VALUES (11)" +== 054 +-- truncate_limit: 100 +SELECT a, b, c FROM test_like_4b +-- +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM test_like_4b" +== 055 +-- truncate_limit: 100 +INSERT INTO test_like_4c (a) VALUES(11) +-- +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_4c (a) VALUES (11)" +== 056 +-- truncate_limit: 100 +SELECT a, b, c FROM test_like_4c +-- +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM test_like_4c" +== 057 +-- truncate_limit: 100 +INSERT INTO test_like_4d (a) VALUES(11) +-- +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_like_4d (a) VALUES (11)" +== 058 +-- truncate_limit: 100 +SELECT a, b, c FROM test_like_4d +-- +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM test_like_4d" +== 059 +-- truncate_limit: 100 +-- Test renumbering of Vars when combining LIKE with inheritance +CREATE TABLE test_like_5 (x point, y point, z point) +-- +TABLE: name="test_like_5" schema="" table="test_like_5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_5 (x point, y point, z point)" +== 060 +-- truncate_limit: 100 +CREATE TABLE test_like_5x (p int CHECK (p > 0), + q int GENERATED ALWAYS AS (p * 2) STORED) +-- +TABLE: name="test_like_5x" schema="" table="test_like_5x" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_5x (p int CHECK (p > 0), q int GENERATED ALWAYS AS (p * 2) STORED)" +== 061 +-- truncate_limit: 100 +CREATE TABLE test_like_5c (LIKE test_like_4 INCLUDING ALL) + INHERITS (test_like_5, test_like_5x) +-- +TABLE: name="test_like_5c" schema="" table="test_like_5c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_5c (LIKE test_like_4 INCLUDING ALL) INHERITS (test_like_5, test_like_5x)" +== 062 +-- truncate_limit: 100 +-- Test updating of column numbers in statistics expressions (bug #18468) +CREATE TABLE test_like_6 (a int, c text, b text) +-- +TABLE: name="test_like_6" schema="" table="test_like_6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_6 (a int, c text, b text)" +== 063 +-- truncate_limit: 100 +CREATE STATISTICS ext_stat ON (a || b) FROM test_like_6 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ext_stat ON (a || b) FROM test_like_6" +== 064 +-- truncate_limit: 100 +ALTER TABLE test_like_6 DROP COLUMN c +-- +TABLE: name="test_like_6" schema="" table="test_like_6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_like_6 DROP c" +== 065 +-- truncate_limit: 100 +CREATE TABLE test_like_6c (LIKE test_like_6 INCLUDING ALL) +-- +TABLE: name="test_like_6c" schema="" table="test_like_6c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_like_6c (LIKE test_like_6 INCLUDING ALL)" +== 066 +-- truncate_limit: 100 +DROP TABLE test_like_4, test_like_4a, test_like_4b, test_like_4c, test_like_4d +-- +TABLE: name="test_like_4" schema="" table="test_like_4" ctx=DDL +TABLE: name="test_like_4a" schema="" table="test_like_4a" ctx=DDL +TABLE: name="test_like_4b" schema="" table="test_like_4b" ctx=DDL +TABLE: name="test_like_4c" schema="" table="test_like_4c" ctx=DDL +TABLE: name="test_like_4d" schema="" table="test_like_4d" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_like_4, test_like_4a, test_like_4b, test_like_4c, test_like_4d" +== 067 +-- truncate_limit: 100 +DROP TABLE test_like_5, test_like_5x, test_like_5c +-- +TABLE: name="test_like_5" schema="" table="test_like_5" ctx=DDL +TABLE: name="test_like_5x" schema="" table="test_like_5x" ctx=DDL +TABLE: name="test_like_5c" schema="" table="test_like_5c" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_like_5, test_like_5x, test_like_5c" +== 068 +-- truncate_limit: 100 +DROP TABLE test_like_6, test_like_6c +-- +TABLE: name="test_like_6" schema="" table="test_like_6" ctx=DDL +TABLE: name="test_like_6c" schema="" table="test_like_6c" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_like_6, test_like_6c" +== 069 +-- truncate_limit: 100 +CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text)" +== 070 +-- truncate_limit: 100 +/* copies indexes */ +INSERT INTO inhg VALUES (5, 10) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg VALUES (5, 10)" +== 071 +-- truncate_limit: 100 +INSERT INTO inhg VALUES (20, 10) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg VALUES (20, 10)" +== 072 +-- truncate_limit: 100 +-- should fail +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhg" +== 073 +-- truncate_limit: 100 +/* Multiple primary keys creation should fail */ +CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, PRIMARY KEY(x)) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, PRIMARY KEY (x))" +== 074 +-- truncate_limit: 100 +/* fails */ +CREATE TABLE inhz (xx text DEFAULT 'text', yy int UNIQUE) +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhz (xx text DEFAULT 'text', yy int UNIQUE)" +== 075 +-- truncate_limit: 100 +CREATE UNIQUE INDEX inhz_xx_idx on inhz (xx) WHERE xx <> 'test' +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX inhz_xx_idx ON inhz USING btree (xx) WHERE xx <> 'test'" +== 076 +-- truncate_limit: 100 +/* Ok to create multiple unique indexes */ +CREATE TABLE inhg (x text UNIQUE, LIKE inhz INCLUDING INDEXES) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhg (x text UNIQUE, LIKE inhz INCLUDING INDEXES)" +== 077 +-- truncate_limit: 100 +INSERT INTO inhg (xx, yy, x) VALUES ('test', 5, 10) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg (xx, yy, x) VALUES ('test', 5, 10)" +== 078 +-- truncate_limit: 100 +INSERT INTO inhg (xx, yy, x) VALUES ('test', 10, 15) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg (xx, yy, x) VALUES ('test', 10, 15)" +== 079 +-- truncate_limit: 100 +INSERT INTO inhg (xx, yy, x) VALUES ('foo', 10, 15) +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhg (xx, yy, x) VALUES ('foo', 10, 15)" +== 080 +-- truncate_limit: 100 +-- should fail +DROP TABLE inhg +-- +TABLE: name="inhg" schema="" table="inhg" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhg" +== 081 +-- truncate_limit: 100 +DROP TABLE inhz +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhz" +== 082 +-- truncate_limit: 100 +/* Use primary key imported by LIKE for self-referential FK constraint */ +CREATE TABLE inhz (x text REFERENCES inhz, LIKE inhx INCLUDING INDEXES) +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhz (x text REFERENCES inhz, LIKE inhx INCLUDING INDEXES)" +== 083 +-- truncate_limit: 100 +DROP TABLE inhz +-- +TABLE: name="inhz" schema="" table="inhz" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhz" +== 084 +-- truncate_limit: 100 +-- including storage and comments +CREATE TABLE ctlt1 (a text CHECK (length(a) > 2) PRIMARY KEY, b text) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt1 (a text CHECK (length(a) > 2) PRIMARY KEY, b text)" +== 085 +-- truncate_limit: 100 +CREATE INDEX ctlt1_b_key ON ctlt1 (b) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ctlt1_b_key ON ctlt1 USING btree (b)" +== 086 +-- truncate_limit: 100 +CREATE INDEX ctlt1_fnidx ON ctlt1 ((a || b)) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ctlt1_fnidx ON ctlt1 USING btree ((a || b))" +== 087 +-- truncate_limit: 100 +CREATE STATISTICS ctlt1_a_b_stat ON a,b FROM ctlt1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ctlt1_a_b_stat ON a, b FROM ctlt1" +== 088 +-- truncate_limit: 100 +CREATE STATISTICS ctlt1_expr_stat ON (a || b) FROM ctlt1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ctlt1_expr_stat ON (a || b) FROM ctlt1" +== 089 +-- truncate_limit: 100 +COMMENT ON STATISTICS ctlt1_a_b_stat IS 'ab stats' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON STATISTICS ctlt1_a_b_stat IS 'ab stats'" +== 090 +-- truncate_limit: 100 +COMMENT ON STATISTICS ctlt1_expr_stat IS 'ab expr stats' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON STATISTICS ctlt1_expr_stat IS 'ab expr stats'" +== 091 +-- truncate_limit: 100 +COMMENT ON COLUMN ctlt1.a IS 'A' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ctlt1.a IS 'A'" +== 092 +-- truncate_limit: 100 +COMMENT ON COLUMN ctlt1.b IS 'B' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ctlt1.b IS 'B'" +== 093 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT ctlt1_a_check ON ctlt1 IS 't1_a_check' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT ctlt1_a_check ON ctlt1 IS 't1_a_check'" +== 094 +-- truncate_limit: 100 +COMMENT ON INDEX ctlt1_pkey IS 'index pkey' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX ctlt1_pkey IS 'index pkey'" +== 095 +-- truncate_limit: 100 +COMMENT ON INDEX ctlt1_b_key IS 'index b_key' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON INDEX ctlt1_b_key IS 'index b_key'" +== 096 +-- truncate_limit: 100 +ALTER TABLE ctlt1 ALTER COLUMN a SET STORAGE MAIN +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ctlt1 ALTER COLUMN a SET STORAGE main" +== 097 +-- truncate_limit: 100 +CREATE TABLE ctlt2 (c text) +-- +TABLE: name="ctlt2" schema="" table="ctlt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt2 (c text)" +== 098 +-- truncate_limit: 100 +ALTER TABLE ctlt2 ALTER COLUMN c SET STORAGE EXTERNAL +-- +TABLE: name="ctlt2" schema="" table="ctlt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ctlt2 ALTER COLUMN c SET STORAGE external" +== 099 +-- truncate_limit: 100 +COMMENT ON COLUMN ctlt2.c IS 'C' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ctlt2.c IS 'C'" +== 100 +-- truncate_limit: 100 +CREATE TABLE ctlt3 (a text CHECK (length(a) < 5), c text CHECK (length(c) < 7)) +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt3 (a text CHECK (length(a) < 5), c text CHECK (length(c) < 7))" +== 101 +-- truncate_limit: 100 +ALTER TABLE ctlt3 ALTER COLUMN c SET STORAGE EXTERNAL +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ctlt3 ALTER COLUMN c SET STORAGE external" +== 102 +-- truncate_limit: 100 +ALTER TABLE ctlt3 ALTER COLUMN a SET STORAGE MAIN +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ctlt3 ALTER COLUMN a SET STORAGE main" +== 103 +-- truncate_limit: 100 +CREATE INDEX ctlt3_fnidx ON ctlt3 ((a || c)) +-- +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ctlt3_fnidx ON ctlt3 USING btree ((a || c))" +== 104 +-- truncate_limit: 100 +COMMENT ON COLUMN ctlt3.a IS 'A3' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ctlt3.a IS 'A3'" +== 105 +-- truncate_limit: 100 +COMMENT ON COLUMN ctlt3.c IS 'C' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ctlt3.c IS 'C'" +== 106 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT ctlt3_a_check ON ctlt3 IS 't3_a_check' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT ctlt3_a_check ON ctlt3 IS 't3_a_check'" +== 107 +-- truncate_limit: 100 +CREATE TABLE ctlt4 (a text, c text) +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt4 (a text, c text)" +== 108 +-- truncate_limit: 100 +ALTER TABLE ctlt4 ALTER COLUMN c SET STORAGE EXTERNAL +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ctlt4 ALTER COLUMN c SET STORAGE external" +== 109 +-- truncate_limit: 100 +CREATE TABLE ctlt12_storage (LIKE ctlt1 INCLUDING STORAGE, LIKE ctlt2 INCLUDING STORAGE) +-- +TABLE: name="ctlt12_storage" schema="" table="ctlt12_storage" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt12_storage (LIKE ctlt1 INCLUDING STORAGE, LIKE ctlt2 INCLUDING STORAGE)" +== 110 +-- truncate_limit: 100 +CREATE TABLE ctlt12_comments (LIKE ctlt1 INCLUDING COMMENTS, LIKE ctlt2 INCLUDING COMMENTS) +-- +TABLE: name="ctlt12_comments" schema="" table="ctlt12_comments" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt12_comments (LIKE ctlt1 INCLUDING COMMENTS, LIKE ctlt2 INCLUDING COMMENTS)" +== 111 +-- truncate_limit: 100 +CREATE TABLE ctlt1_inh (LIKE ctlt1 INCLUDING CONSTRAINTS INCLUDING COMMENTS) INHERITS (ctlt1) +-- +TABLE: name="ctlt1_inh" schema="" table="ctlt1_inh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt1_inh (LIKE ctlt1 INCLUDING COMMENTS INCLUDING CONSTRAINTS) INHERITS (ctlt1)" +== 112 +-- truncate_limit: 100 +SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt1_inh'::regclass +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_constraint" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="c" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT description FROM pg_description, pg_constraint c WHERE ..." +== 113 +-- truncate_limit: 100 +CREATE TABLE ctlt13_inh () INHERITS (ctlt1, ctlt3) +-- +TABLE: name="ctlt13_inh" schema="" table="ctlt13_inh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt13_inh () INHERITS (ctlt1, ctlt3)" +== 114 +-- truncate_limit: 100 +CREATE TABLE ctlt13_like (LIKE ctlt3 INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING COMMENTS INCLUDING STORAGE) INHERITS (ctlt1) +-- +TABLE: name="ctlt13_like" schema="" table="ctlt13_like" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt13_like (LIKE ctlt3 INCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING INDEXES I..." +== 115 +-- truncate_limit: 100 +SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt13_like'::regclass +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_constraint" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="c" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT description FROM pg_description, pg_constraint c WHERE ..." +== 116 +-- truncate_limit: 100 +CREATE TABLE ctlt_all (LIKE ctlt1 INCLUDING ALL) +-- +TABLE: name="ctlt_all" schema="" table="ctlt_all" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt_all (LIKE ctlt1 INCLUDING ALL)" +== 117 +-- truncate_limit: 100 +SELECT c.relname, objsubid, description FROM pg_description, pg_index i, pg_class c WHERE classoid = 'pg_class'::regclass AND objoid = i.indexrelid AND c.oid = i.indexrelid AND i.indrelid = 'ctlt_all'::regclass ORDER BY c.relname, objsubid +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="i" column="indexrelid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="i" column="indexrelid" +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_description, pg_index i, pg_class c WHERE ... ORDER BY c.relname, objsubid" +== 118 +-- truncate_limit: 100 +SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s WHERE classoid = 'pg_statistic_ext'::regclass AND objoid = s.oid AND s.stxrelid = 'ctlt_all'::regclass ORDER BY s.stxname, objsubid +-- +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="" column="classoid" +FILTER: schema="" table="" column="objoid" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="stxrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_description, pg_statistic_ext s WHERE ... ORDER BY s.stxname, objsubid" +== 119 +-- truncate_limit: 100 +CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4) +-- +TABLE: name="inh_error1" schema="" table="inh_error1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4)" +== 120 +-- truncate_limit: 100 +CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1) +-- +TABLE: name="inh_error2" schema="" table="inh_error2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1)" +== 121 +-- truncate_limit: 100 +-- Check that LIKE isn't confused by a system catalog of the same name +CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL) +-- +TABLE: name="pg_attrdef" schema="" table="pg_attrdef" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL)" +== 122 +-- truncate_limit: 100 +DROP TABLE public.pg_attrdef +-- +TABLE: name="public.pg_attrdef" schema="public" table="pg_attrdef" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE public.pg_attrdef" +== 123 +-- truncate_limit: 100 +-- Check that LIKE isn't confused when new table masks the old, either +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 124 +-- truncate_limit: 100 +CREATE SCHEMA ctl_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA ctl_schema" +== 125 +-- truncate_limit: 100 +SET LOCAL search_path = ctl_schema, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL search_path TO ctl_schema, public" +== 126 +-- truncate_limit: 100 +CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL) +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL)" +== 127 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 128 +-- truncate_limit: 100 +DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE +-- +TABLE: name="ctlt1" schema="" table="ctlt1" ctx=DDL +TABLE: name="ctlt2" schema="" table="ctlt2" ctx=DDL +TABLE: name="ctlt3" schema="" table="ctlt3" ctx=DDL +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +TABLE: name="ctlt12_storage" schema="" table="ctlt12_storage" ctx=DDL +TABLE: name="ctlt12_comments" schema="" table="ctlt12_comments" ctx=DDL +TABLE: name="ctlt1_inh" schema="" table="ctlt1_inh" ctx=DDL +TABLE: name="ctlt13_inh" schema="" table="ctlt13_inh" ctx=DDL +TABLE: name="ctlt13_like" schema="" table="ctlt13_like" ctx=DDL +TABLE: name="ctlt_all" schema="" table="ctlt_all" ctx=DDL +TABLE: name="ctla" schema="" table="ctla" ctx=DDL +TABLE: name="ctlb" schema="" table="ctlb" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ct..." +== 129 +-- truncate_limit: 100 +-- LIKE must respect NO INHERIT property of constraints +CREATE TABLE noinh_con_copy (a int CHECK (a > 0) NO INHERIT) +-- +TABLE: name="noinh_con_copy" schema="" table="noinh_con_copy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE noinh_con_copy (a int CHECK (a > 0) NO INHERIT)" +== 130 +-- truncate_limit: 100 +CREATE TABLE noinh_con_copy1 (LIKE noinh_con_copy INCLUDING CONSTRAINTS) +-- +TABLE: name="noinh_con_copy1" schema="" table="noinh_con_copy1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE noinh_con_copy1 (LIKE noinh_con_copy INCLUDING CONSTRAINTS)" +== 131 +-- truncate_limit: 100 +-- fail, as partitioned tables don't allow NO INHERIT constraints +CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL) + PARTITION BY LIST (a) +-- +TABLE: name="noinh_con_copy1_parted" schema="" table="noinh_con_copy1_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL) PARTITION BY LIST (a)" +== 132 +-- truncate_limit: 100 +DROP TABLE noinh_con_copy, noinh_con_copy1 +-- +TABLE: name="noinh_con_copy" schema="" table="noinh_con_copy" ctx=DDL +TABLE: name="noinh_con_copy1" schema="" table="noinh_con_copy1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE noinh_con_copy, noinh_con_copy1" +== 133 +-- truncate_limit: 100 +/* LIKE with other relation kinds */ + +CREATE TABLE ctlt4 (a int, b text) +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt4 (a int, b text)" +== 134 +-- truncate_limit: 100 +CREATE SEQUENCE ctlseq1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE ctlseq1" +== 135 +-- truncate_limit: 100 +CREATE TABLE ctlt10 (LIKE ctlseq1) +-- +TABLE: name="ctlt10" schema="" table="ctlt10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt10 (LIKE ctlseq1)" +== 136 +-- truncate_limit: 100 +-- fail + +CREATE VIEW ctlv1 AS SELECT * FROM ctlt4 +-- +TABLE: name="ctlv1" schema="" table="ctlv1" ctx=DDL +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ctlv1 AS SELECT * FROM ctlt4" +== 137 +-- truncate_limit: 100 +CREATE TABLE ctlt11 (LIKE ctlv1) +-- +TABLE: name="ctlt11" schema="" table="ctlt11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt11 (LIKE ctlv1)" +== 138 +-- truncate_limit: 100 +CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL) +-- +TABLE: name="ctlt11a" schema="" table="ctlt11a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL)" +== 139 +-- truncate_limit: 100 +CREATE TYPE ctlty1 AS (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE ctlty1 AS (a int, b text)" +== 140 +-- truncate_limit: 100 +CREATE TABLE ctlt12 (LIKE ctlty1) +-- +TABLE: name="ctlt12" schema="" table="ctlt12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctlt12 (LIKE ctlty1)" +== 141 +-- truncate_limit: 100 +DROP SEQUENCE ctlseq1 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE ctlseq1" +== 142 +-- truncate_limit: 100 +DROP TYPE ctlty1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE ctlty1" +== 143 +-- truncate_limit: 100 +DROP VIEW ctlv1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW ctlv1" +== 144 +-- truncate_limit: 100 +DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12 +-- +TABLE: name="ctlt4" schema="" table="ctlt4" ctx=DDL +TABLE: name="ctlt10" schema="" table="ctlt10" ctx=DDL +TABLE: name="ctlt11" schema="" table="ctlt11" ctx=DDL +TABLE: name="ctlt11a" schema="" table="ctlt11a" ctx=DDL +TABLE: name="ctlt12" schema="" table="ctlt12" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json new file mode 100644 index 0000000..b064cb7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json @@ -0,0 +1,89 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_type.test b/parser/testdata/summary_truncate/postgres_regress/create_type.test new file mode 100644 index 0000000..bbba180 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_type.test @@ -0,0 +1,743 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_TYPE +|-- + +-- directory path and dlsuffix are passed to us in environment variables + + +|-- +-- Test the "old style" approach of making the I/O functions first, +-- with no explicit shell type creation. +|-- +CREATE FUNCTION widget_in(cstring) + RETURNS widget + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 272 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +CREATE FUNCTION widget_out(widget) + RETURNS cstring + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +-- truncate_limit: 100 +CREATE FUNCTION int44in(cstring) + RETURNS city_budget + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +CREATE FUNCTION int44out(city_budget) + RETURNS cstring + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 64 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- truncate_limit: 100 +CREATE TYPE widget ( + internallength = 24, + input = widget_in, + output = widget_out, + typmod_in = numerictypmodin, + typmod_out = numerictypmodout, + alignment = double +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE widget (internallength = 24, input = widget_in, output = widget_out, typmod_in = nume..." +== 006 +-- truncate_limit: 100 +CREATE TYPE city_budget ( + internallength = 16, + input = int44in, + output = int44out, + element = int4, + category = 'x', -- just to verify the system will take it + preferred = true -- ditto +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE city_budget (internallength = 16, input = int44in, output = int44out, element = int4,..." +== 007 +-- truncate_limit: 100 +-- Test creation and destruction of shell types +CREATE TYPE shell +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE shell" +== 008 +-- truncate_limit: 100 +CREATE TYPE shell +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE shell" +== 009 +-- truncate_limit: 100 +-- fail, type already present +DROP TYPE shell +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE shell" +== 010 +-- truncate_limit: 100 +DROP TYPE shell +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE shell" +== 011 +-- truncate_limit: 100 +-- fail, type not exist + +-- also, let's leave one around for purposes of pg_dump testing +CREATE TYPE myshell +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE myshell" +== 012 +-- truncate_limit: 100 +|-- +-- Test type-related default values (broken in releases before PG 7.2) +|-- +-- This part of the test also exercises the "new style" approach of making +-- a shell type and then filling it in. +|-- +CREATE TYPE int42 +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE int42" +== 013 +-- truncate_limit: 100 +CREATE TYPE text_w_default +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE text_w_default" +== 014 +-- truncate_limit: 100 +-- Make dummy I/O routines using the existing internal support for int4, text +CREATE FUNCTION int42_in(cstring) + RETURNS int42 + AS 'int4in' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="int42_in" function="int42_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int42_in(cstring) RETURNS int42 AS $$int4in$$ LANGUAGE internal RETURNS NULL ON N..." +== 015 +-- truncate_limit: 100 +CREATE FUNCTION int42_out(int42) + RETURNS cstring + AS 'int4out' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="int42_out" function="int42_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int42_out(int42) RETURNS cstring AS $$int4out$$ LANGUAGE internal RETURNS NULL ON..." +== 016 +-- truncate_limit: 100 +CREATE FUNCTION text_w_default_in(cstring) + RETURNS text_w_default + AS 'textin' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="text_w_default_in" function="text_w_default_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION text_w_default_in(cstring) RETURNS text_w_default AS $$textin$$ LANGUAGE internal..." +== 017 +-- truncate_limit: 100 +CREATE FUNCTION text_w_default_out(text_w_default) + RETURNS cstring + AS 'textout' + LANGUAGE internal STRICT IMMUTABLE +-- +FUNCTION: name="text_w_default_out" function="text_w_default_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION text_w_default_out(text_w_default) RETURNS cstring AS $$textout$$ LANGUAGE intern..." +== 018 +-- truncate_limit: 100 +CREATE TYPE int42 ( + internallength = 4, + input = int42_in, + output = int42_out, + alignment = int4, + default = 42, + passedbyvalue +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE int42 (internallength = 4, input = int42_in, output = int42_out, alignment = int4, \"d..." +== 019 +-- truncate_limit: 100 +CREATE TYPE text_w_default ( + internallength = variable, + input = text_w_default_in, + output = text_w_default_out, + alignment = int4, + default = 'zippo' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE text_w_default (internallength = variable, input = text_w_default_in, output = text_w..." +== 020 +-- truncate_limit: 100 +CREATE TABLE default_test (f1 text_w_default, f2 int42) +-- +TABLE: name="default_test" schema="" table="default_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_test (f1 text_w_default, f2 int42)" +== 021 +-- truncate_limit: 100 +INSERT INTO default_test DEFAULT VALUES +-- +TABLE: name="default_test" schema="" table="default_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO default_test DEFAULT VALUES" +== 022 +-- truncate_limit: 100 +SELECT * FROM default_test +-- +TABLE: name="default_test" schema="" table="default_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM default_test" +== 023 +-- truncate_limit: 100 +-- We need a shell type to test some CREATE TYPE failure cases with +CREATE TYPE bogus_type +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE bogus_type" +== 024 +-- truncate_limit: 100 +-- invalid: non-lowercase quoted identifiers +CREATE TYPE bogus_type ( + "Internallength" = 4, + "Input" = int42_in, + "Output" = int42_out, + "Alignment" = int4, + "Default" = 42, + "Passedbyvalue" +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE bogus_type (\"Internallength\" = 4, \"Input\" = int42_in, \"Output\" = int42_out, \"Alignmen..." +== 025 +-- truncate_limit: 100 +-- invalid: input/output function incompatibility +CREATE TYPE bogus_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE bogus_type (input = array_in, output = array_out, element = int, internallength = 32)" +== 026 +-- truncate_limit: 100 +DROP TYPE bogus_type +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE bogus_type" +== 027 +-- truncate_limit: 100 +-- It no longer is possible to issue CREATE TYPE without making a shell first +CREATE TYPE bogus_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE bogus_type (input = array_in, output = array_out, element = int, internallength = 32)" +== 028 +-- truncate_limit: 100 +-- Test stand-alone composite type + +CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42)" +== 029 +-- truncate_limit: 100 +CREATE FUNCTION get_default_test() RETURNS SETOF default_test_row AS ' + SELECT * FROM default_test; +' LANGUAGE SQL +-- +FUNCTION: name="get_default_test" function="get_default_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION get_default_test() RETURNS SETOF default_test_row AS $$\n SELECT * FROM default_t..." +== 030 +-- truncate_limit: 100 +SELECT * FROM get_default_test() +-- +FUNCTION: name="get_default_test" function="get_default_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM get_default_test()" +== 031 +-- truncate_limit: 100 +-- Test comments +COMMENT ON TYPE bad IS 'bad comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TYPE bad IS 'bad comment'" +== 032 +-- truncate_limit: 100 +COMMENT ON TYPE default_test_row IS 'good comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TYPE default_test_row IS 'good comment'" +== 033 +-- truncate_limit: 100 +COMMENT ON TYPE default_test_row IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TYPE default_test_row IS NULL" +== 034 +-- truncate_limit: 100 +COMMENT ON COLUMN default_test_row.nope IS 'bad comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN default_test_row.nope IS 'bad comment'" +== 035 +-- truncate_limit: 100 +COMMENT ON COLUMN default_test_row.f1 IS 'good comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN default_test_row.f1 IS 'good comment'" +== 036 +-- truncate_limit: 100 +COMMENT ON COLUMN default_test_row.f1 IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN default_test_row.f1 IS NULL" +== 037 +-- truncate_limit: 100 +-- Check shell type create for existing types +CREATE TYPE text_w_default +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE text_w_default" +== 038 +-- truncate_limit: 100 +-- should fail + +DROP TYPE default_test_row CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE default_test_row CASCADE" +== 039 +-- truncate_limit: 100 +DROP TABLE default_test +-- +TABLE: name="default_test" schema="" table="default_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE default_test" +== 040 +-- truncate_limit: 100 +-- Check dependencies are established when creating a new type +CREATE TYPE base_type +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE base_type" +== 041 +-- truncate_limit: 100 +CREATE FUNCTION base_fn_in(cstring) RETURNS base_type AS 'boolin' + LANGUAGE internal IMMUTABLE STRICT +-- +FUNCTION: name="base_fn_in" function="base_fn_in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION base_fn_in(cstring) RETURNS base_type AS $$boolin$$ LANGUAGE internal IMMUTABLE R..." +== 042 +-- truncate_limit: 100 +CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'boolout' + LANGUAGE internal IMMUTABLE STRICT +-- +FUNCTION: name="base_fn_out" function="base_fn_out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS $$boolout$$ LANGUAGE internal IMMUTABLE..." +== 043 +-- truncate_limit: 100 +CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE base_type (input = base_fn_in, output = base_fn_out)" +== 044 +-- truncate_limit: 100 +DROP FUNCTION base_fn_in(cstring) +-- +FUNCTION: name="base_fn_in" function="base_fn_in" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION base_fn_in(cstring)" +== 045 +-- truncate_limit: 100 +-- error +DROP FUNCTION base_fn_out(base_type) +-- +FUNCTION: name="base_fn_out" function="base_fn_out" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION base_fn_out(base_type)" +== 046 +-- truncate_limit: 100 +-- error +DROP TYPE base_type +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE base_type" +== 047 +-- truncate_limit: 100 +-- error +DROP TYPE base_type CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE base_type CASCADE" +== 048 +-- truncate_limit: 100 +-- Check usage of typmod with a user-defined type +-- (we have borrowed numeric's typmod functions) + +CREATE TEMP TABLE mytab (foo widget(42,13,7)) +-- +TABLE: name="mytab" schema="" table="mytab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE mytab (foo widget(42, 13, 7))" +== 049 +-- truncate_limit: 100 +-- should fail +CREATE TEMP TABLE mytab (foo widget(42,13)) +-- +TABLE: name="mytab" schema="" table="mytab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE mytab (foo widget(42, 13))" +== 050 +-- truncate_limit: 100 +SELECT format_type(atttypid,atttypmod) FROM pg_attribute +WHERE attrelid = 'mytab'::regclass AND attnum > 0 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT format_type(atttypid, atttypmod) FROM pg_attribute WHERE ..." +== 051 +-- truncate_limit: 100 +-- might as well exercise the widget type while we're here +INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)') +-- +TABLE: name="mytab" schema="" table="mytab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)')" +== 052 +-- truncate_limit: 100 +TABLE mytab +-- +TABLE: name="mytab" schema="" table="mytab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mytab" +== 053 +-- truncate_limit: 100 +-- and test format_type() a bit more, too +select format_type('varchar'::regtype, 42) +-- +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format_type('varchar'::regtype, 42)" +== 054 +-- truncate_limit: 100 +select format_type('bpchar'::regtype, null) +-- +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format_type('bpchar'::regtype, NULL)" +== 055 +-- truncate_limit: 100 +-- this behavior difference is intentional +select format_type('bpchar'::regtype, -1) +-- +FUNCTION: name="format_type" function="format_type" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format_type('bpchar'::regtype, -1)" +== 056 +-- truncate_limit: 100 +-- Test non-error-throwing APIs using widget, which still throws errors +SELECT pg_input_is_valid('(1,2,3)', 'widget') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,2,3)', 'widget')" +== 057 +-- truncate_limit: 100 +SELECT pg_input_is_valid('(1,2)', 'widget') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,2)', 'widget')" +== 058 +-- truncate_limit: 100 +-- hard error expected +SELECT pg_input_is_valid('{"(1,2,3)"}', 'widget[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{\"(1,2,3)\"}', 'widget[]')" +== 059 +-- truncate_limit: 100 +SELECT pg_input_is_valid('{"(1,2)"}', 'widget[]') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{\"(1,2)\"}', 'widget[]')" +== 060 +-- truncate_limit: 100 +-- hard error expected +SELECT pg_input_is_valid('("(1,2,3)")', 'mytab') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(\"(1,2,3)\")', 'mytab')" +== 061 +-- truncate_limit: 100 +SELECT pg_input_is_valid('("(1,2)")', 'mytab') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(\"(1,2)\")', 'mytab')" +== 062 +-- truncate_limit: 100 +-- hard error expected + +-- Test creation of an operator over a user-defined type + +CREATE FUNCTION pt_in_widget(point, widget) + RETURNS bool + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 149 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 063 +-- truncate_limit: 100 +CREATE OPERATOR <% ( + leftarg = point, + rightarg = widget, + procedure = pt_in_widget, + commutator = >% , + negator = >=% +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR <% (leftarg = point, rightarg = widget, procedure = pt_in_widget, commutator = >%..." +== 064 +-- truncate_limit: 100 +SELECT point '(1,2)' <% widget '(0,0,3)' AS t, + point '(1,2)' <% widget '(0,0,1)' AS f +-- +STMT: SelectStmt +TRUNCATED: "SELECT point '(1,2)' <% '(0,0,3)'::widget AS t, point '(1,2)' <% '(0,0,1)'::widget AS f" +== 065 +-- truncate_limit: 100 +-- exercise city_budget type +CREATE TABLE city ( + name name, + location box, + budget city_budget +) +-- +TABLE: name="city" schema="" table="city" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE city (name name, location box, budget city_budget)" +== 066 +-- truncate_limit: 100 +INSERT INTO city VALUES +('Podunk', '(1,2),(3,4)', '100,127,1000'), +('Gotham', '(1000,34),(1100,334)', '123456,127,-1000,6789') +-- +TABLE: name="city" schema="" table="city" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO city VALUES (...)" +== 067 +-- truncate_limit: 100 +TABLE city +-- +TABLE: name="city" schema="" table="city" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM city" +== 068 +-- truncate_limit: 100 +|-- +-- Test CREATE/ALTER TYPE using a type that's compatible with varchar, +-- so we can re-use those support functions +|-- +CREATE TYPE myvarchar +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE myvarchar" +== 069 +-- truncate_limit: 100 +CREATE FUNCTION myvarcharin(cstring, oid, integer) RETURNS myvarchar +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharin' +-- +FUNCTION: name="myvarcharin" function="myvarcharin" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myvarcharin(cstring, oid, int) RETURNS myvarchar LANGUAGE internal IMMUTABLE PARA..." +== 070 +-- truncate_limit: 100 +CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout' +-- +FUNCTION: name="myvarcharout" function="myvarcharout" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring LANGUAGE internal IMMUTABLE PARALLEL safe..." +== 071 +-- truncate_limit: 100 +CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea +LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharsend' +-- +FUNCTION: name="myvarcharsend" function="myvarcharsend" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea LANGUAGE internal STABLE PARALLEL safe RET..." +== 072 +-- truncate_limit: 100 +CREATE FUNCTION myvarcharrecv(internal, oid, integer) RETURNS myvarchar +LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv' +-- +FUNCTION: name="myvarcharrecv" function="myvarcharrecv" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myvarcharrecv(internal, oid, int) RETURNS myvarchar LANGUAGE internal STABLE PARA..." +== 073 +-- truncate_limit: 100 +-- fail, it's still a shell: +ALTER TYPE myvarchar SET (storage = extended) +-- +STMT: AlterTypeStmt +TRUNCATED: "ALTER TYPE myvarchar SET (storage = extended)" +== 074 +-- truncate_limit: 100 +CREATE TYPE myvarchar ( + input = myvarcharin, + output = myvarcharout, + alignment = integer, + storage = main +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE myvarchar (input = myvarcharin, output = myvarcharout, alignment = int, storage = main)" +== 075 +-- truncate_limit: 100 +-- want to check updating of a domain over the target type, too +CREATE DOMAIN myvarchardom AS myvarchar +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN myvarchardom AS myvarchar" +== 076 +-- truncate_limit: 100 +ALTER TYPE myvarchar SET (storage = plain) +-- +STMT: AlterTypeStmt +TRUNCATED: "ALTER TYPE myvarchar SET (storage = plain)" +== 077 +-- truncate_limit: 100 +-- not allowed + +ALTER TYPE myvarchar SET (storage = extended) +-- +STMT: AlterTypeStmt +TRUNCATED: "ALTER TYPE myvarchar SET (storage = extended)" +== 078 +-- truncate_limit: 100 +ALTER TYPE myvarchar SET ( + send = myvarcharsend, + receive = myvarcharrecv, + typmod_in = varchartypmodin, + typmod_out = varchartypmodout, + -- these are bogus, but it's safe as long as we don't use the type: + analyze = ts_typanalyze, + subscript = raw_array_subscript_handler +) +-- +STMT: AlterTypeStmt +TRUNCATED: "ALTER TYPE myvarchar SET (send = myvarcharsend, receive = myvarcharrecv, typmod_in = varchartypmo..." +== 079 +-- truncate_limit: 100 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = 'myvarchar' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type WHERE typname = 'myvarchar'" +== 080 +-- truncate_limit: 100 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = '_myvarchar' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type WHERE typname = '_myvarchar'" +== 081 +-- truncate_limit: 100 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = 'myvarchardom' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type WHERE typname = 'myvarchardom'" +== 082 +-- truncate_limit: 100 +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = '_myvarchardom' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type WHERE typname = '_myvarchardom'" +== 083 +-- truncate_limit: 100 +-- ensure dependencies are straight +DROP FUNCTION myvarcharsend(myvarchar) +-- +FUNCTION: name="myvarcharsend" function="myvarcharsend" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION myvarcharsend(myvarchar)" +== 084 +-- truncate_limit: 100 +-- fail +DROP TYPE myvarchar +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE myvarchar" +== 085 +-- truncate_limit: 100 +-- fail + +DROP TYPE myvarchar CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE myvarchar CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json new file mode 100644 index 0000000..5d2a46c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json @@ -0,0 +1,311 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/create_view.test b/parser/testdata/summary_truncate/postgres_regress/create_view.test new file mode 100644 index 0000000..bc12a87 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/create_view.test @@ -0,0 +1,2924 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE_VIEW +-- Virtual class definitions +-- (this also tests the query rewrite system) +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION interpt_pp(path, path) + RETURNS point + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 238 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +CREATE TABLE real_city ( + pop int4, + cname text, + outline path +) +-- +TABLE: name="real_city" schema="" table="real_city" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE real_city (pop int4, cname text, outline path)" +== 003 +-- truncate_limit: 100 +COPY real_city FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +ANALYZE real_city +-- +TABLE: name="real_city" schema="" table="real_city" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE real_city" +== 005 +-- truncate_limit: 100 +SELECT * + INTO TABLE ramp + FROM ONLY road + WHERE name ~ '.*Ramp' +-- +TABLE: name="road" schema="" table="road" ctx=Select +TABLE: name="ramp" schema="" table="ramp" ctx=DDL +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT * INTO ramp FROM ONLY road WHERE name ~ '.*Ramp'" +== 006 +-- truncate_limit: 100 +CREATE VIEW street AS + SELECT r.name, r.thepath, c.cname AS cname + FROM ONLY road r, real_city c + WHERE c.outline ?# r.thepath +-- +TABLE: name="street" schema="" table="street" ctx=DDL +TABLE: name="road" schema="" table="road" ctx=Select +TABLE: name="real_city" schema="" table="real_city" ctx=Select +ALIAS: "c"="real_city" +ALIAS: "r"="road" +FILTER: schema="" table="c" column="outline" +FILTER: schema="" table="r" column="thepath" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW street AS SELECT r.name, r.thepath, c.cname AS cname FROM ONLY road r, real_city c WH..." +== 007 +-- truncate_limit: 100 +CREATE VIEW iexit AS + SELECT ih.name, ih.thepath, + interpt_pp(ih.thepath, r.thepath) AS exit + FROM ihighway ih, ramp r + WHERE ih.thepath ?# r.thepath +-- +TABLE: name="iexit" schema="" table="iexit" ctx=DDL +TABLE: name="ihighway" schema="" table="ihighway" ctx=Select +TABLE: name="ramp" schema="" table="ramp" ctx=Select +ALIAS: "ih"="ihighway" +ALIAS: "r"="ramp" +FUNCTION: name="interpt_pp" function="interpt_pp" schema="" ctx=Call +FILTER: schema="" table="ih" column="thepath" +FILTER: schema="" table="r" column="thepath" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW iexit AS SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM i..." +== 008 +-- truncate_limit: 100 +CREATE VIEW toyemp AS + SELECT name, age, location, 12*salary AS annualsal + FROM emp +-- +TABLE: name="toyemp" schema="" table="toyemp" ctx=DDL +TABLE: name="emp" schema="" table="emp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW toyemp AS SELECT name, age, location, 12 * salary AS annualsal FROM emp" +== 009 +-- truncate_limit: 100 +-- Test comments +COMMENT ON VIEW noview IS 'no view' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON VIEW noview IS 'no view'" +== 010 +-- truncate_limit: 100 +COMMENT ON VIEW toyemp IS 'is a view' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON VIEW toyemp IS 'is a view'" +== 011 +-- truncate_limit: 100 +COMMENT ON VIEW toyemp IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON VIEW toyemp IS NULL" +== 012 +-- truncate_limit: 100 +-- These views are left around mainly to exercise special cases in pg_dump. + +CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20)) +-- +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20))" +== 013 +-- truncate_limit: 100 +CREATE VIEW key_dependent_view AS + SELECT * FROM view_base_table GROUP BY key +-- +TABLE: name="key_dependent_view" schema="" table="key_dependent_view" ctx=DDL +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW key_dependent_view AS SELECT * FROM view_base_table GROUP BY key" +== 014 +-- truncate_limit: 100 +ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey +-- +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey" +== 015 +-- truncate_limit: 100 +-- fails + +CREATE VIEW key_dependent_view_no_cols AS + SELECT FROM view_base_table GROUP BY key HAVING length(data) > 0 +-- +TABLE: name="key_dependent_view_no_cols" schema="" table="key_dependent_view_no_cols" ctx=DDL +TABLE: name="view_base_table" schema="" table="view_base_table" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW key_dependent_view_no_cols AS SELECT FROM view_base_table GROUP BY key HAVING length(..." +== 016 +-- truncate_limit: 100 +|-- +-- CREATE OR REPLACE VIEW +|-- + +CREATE TABLE viewtest_tbl (a int, b int, c numeric(10,1), d text COLLATE "C") +-- +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE viewtest_tbl (a int, b int, c numeric(10, 1), d text COLLATE \"C\")" +== 017 +-- truncate_limit: 100 +COPY viewtest_tbl FROM stdin +-- +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY viewtest_tbl FROM STDIN" +== 018 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW viewtest AS + SELECT * FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT * FROM viewtest_tbl" +== 019 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW viewtest AS + SELECT * FROM viewtest_tbl WHERE a > 10 +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT * FROM viewtest_tbl WHERE a > 10" +== 020 +-- truncate_limit: 100 +SELECT * FROM viewtest +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM viewtest" +== 021 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT a, b, c, d FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC" +== 022 +-- truncate_limit: 100 +SELECT * FROM viewtest +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM viewtest" +== 023 +-- truncate_limit: 100 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a FROM viewtest_tbl WHERE a <> 20 +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT a FROM viewtest_tbl WHERE a <> 20" +== 024 +-- truncate_limit: 100 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT 1, * FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT 1, * FROM viewtest_tbl" +== 025 +-- truncate_limit: 100 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b::numeric, c, d FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT a, b::numeric, c, d FROM viewtest_tbl" +== 026 +-- truncate_limit: 100 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c::numeric(10,2), d FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT a, b, c::numeric(10, 2), d FROM viewtest_tbl" +== 027 +-- truncate_limit: 100 +-- should fail +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d COLLATE "POSIX" FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT a, b, c, d COLLATE \"POSIX\" FROM viewtest_tbl" +== 028 +-- truncate_limit: 100 +-- should work +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d, 0 AS e FROM viewtest_tbl +-- +TABLE: name="viewtest" schema="" table="viewtest" ctx=DDL +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW viewtest AS SELECT a, b, c, d, 0 AS e FROM viewtest_tbl" +== 029 +-- truncate_limit: 100 +DROP VIEW viewtest +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW viewtest" +== 030 +-- truncate_limit: 100 +DROP TABLE viewtest_tbl +-- +TABLE: name="viewtest_tbl" schema="" table="viewtest_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE viewtest_tbl" +== 031 +-- truncate_limit: 100 +-- tests for temporary views + +CREATE SCHEMA temp_view_test + CREATE TABLE base_table (a int, id int) + CREATE TABLE base_table2 (a int, id int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA temp_view_test CREATE TABLE base_table (a int, id int) CREATE TABLE base_table2 (a ..." +== 032 +-- truncate_limit: 100 +SET search_path TO temp_view_test, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO temp_view_test, public" +== 033 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE temp_table (a int, id int) +-- +TABLE: name="temp_table" schema="" table="temp_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_table (a int, id int)" +== 034 +-- truncate_limit: 100 +-- should be created in temp_view_test schema +CREATE VIEW v1 AS SELECT * FROM base_table +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1 AS SELECT * FROM base_table" +== 035 +-- truncate_limit: 100 +-- should be created in temp object schema +CREATE VIEW v1_temp AS SELECT * FROM temp_table +-- +TABLE: name="v1_temp" schema="" table="v1_temp" ctx=DDL +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1_temp AS SELECT * FROM temp_table" +== 036 +-- truncate_limit: 100 +-- should be created in temp object schema +CREATE TEMP VIEW v2_temp AS SELECT * FROM base_table +-- +TABLE: name="v2_temp" schema="" table="v2_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v2_temp AS SELECT * FROM base_table" +== 037 +-- truncate_limit: 100 +-- should be created in temp_views schema +CREATE VIEW temp_view_test.v2 AS SELECT * FROM base_table +-- +TABLE: name="temp_view_test.v2" schema="temp_view_test" table="v2" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW temp_view_test.v2 AS SELECT * FROM base_table" +== 038 +-- truncate_limit: 100 +-- should fail +CREATE VIEW temp_view_test.v3_temp AS SELECT * FROM temp_table +-- +TABLE: name="temp_view_test.v3_temp" schema="temp_view_test" table="v3_temp" ctx=DDL +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW temp_view_test.v3_temp AS SELECT * FROM temp_table" +== 039 +-- truncate_limit: 100 +-- should fail +CREATE SCHEMA test_view_schema + CREATE TEMP VIEW testview AS SELECT 1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_view_schema CREATE TEMPORARY VIEW testview AS SELECT 1" +== 040 +-- truncate_limit: 100 +-- joins: if any of the join relations are temporary, the view +-- should also be temporary + +-- should be non-temp +CREATE VIEW v3 AS + SELECT t1.a AS t1_a, t2.a AS t2_a + FROM base_table t1, base_table2 t2 + WHERE t1.id = t2.id +-- +TABLE: name="v3" schema="" table="v3" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="base_table2" +FILTER: schema="" table="t1" column="id" +FILTER: schema="" table="t2" column="id" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v3 AS SELECT t1.a AS t1_a, t2.a AS t2_a FROM base_table t1, base_table2 t2 WHERE t1.i..." +== 041 +-- truncate_limit: 100 +-- should be temp (one join rel is temp) +CREATE VIEW v4_temp AS + SELECT t1.a AS t1_a, t2.a AS t2_a + FROM base_table t1, temp_table t2 + WHERE t1.id = t2.id +-- +TABLE: name="v4_temp" schema="" table="v4_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="temp_table" +FILTER: schema="" table="t1" column="id" +FILTER: schema="" table="t2" column="id" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v4_temp AS SELECT t1.a AS t1_a, t2.a AS t2_a FROM base_table t1, temp_table t2 WHERE ..." +== 042 +-- truncate_limit: 100 +-- should be temp +CREATE VIEW v5_temp AS + SELECT t1.a AS t1_a, t2.a AS t2_a, t3.a AS t3_a + FROM base_table t1, base_table2 t2, temp_table t3 + WHERE t1.id = t2.id and t2.id = t3.id +-- +TABLE: name="v5_temp" schema="" table="v5_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="base_table2" +ALIAS: "t3"="temp_table" +FILTER: schema="" table="t1" column="id" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t3" column="id" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v5_temp AS SELECT t1.a AS t1_a, t2.a AS t2_a, t3.a AS t3_a FROM base_table t1, base_t..." +== 043 +-- truncate_limit: 100 +-- subqueries +CREATE VIEW v4 AS SELECT * FROM base_table WHERE id IN (SELECT id FROM base_table2) +-- +TABLE: name="v4" schema="" table="v4" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +FILTER: schema="" table="" column="id" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v4 AS SELECT * FROM base_table WHERE id IN (SELECT id FROM base_table2)" +== 044 +-- truncate_limit: 100 +CREATE VIEW v5 AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM base_table2) t2 +-- +TABLE: name="v5" schema="" table="v5" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +ALIAS: "t1"="base_table" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v5 AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM base_table2) t2" +== 045 +-- truncate_limit: 100 +CREATE VIEW v6 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM base_table2) +-- +TABLE: name="v6" schema="" table="v6" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v6 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM base_table2)" +== 046 +-- truncate_limit: 100 +CREATE VIEW v7 AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM base_table2) +-- +TABLE: name="v7" schema="" table="v7" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="base_table2" schema="" table="base_table2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v7 AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM base_table2)" +== 047 +-- truncate_limit: 100 +CREATE VIEW v8 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1) +-- +TABLE: name="v8" schema="" table="v8" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v8 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1)" +== 048 +-- truncate_limit: 100 +CREATE VIEW v6_temp AS SELECT * FROM base_table WHERE id IN (SELECT id FROM temp_table) +-- +TABLE: name="v6_temp" schema="" table="v6_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +FILTER: schema="" table="" column="id" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v6_temp AS SELECT * FROM base_table WHERE id IN (SELECT id FROM temp_table)" +== 049 +-- truncate_limit: 100 +CREATE VIEW v7_temp AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM temp_table) t2 +-- +TABLE: name="v7_temp" schema="" table="v7_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +ALIAS: "t1"="base_table" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v7_temp AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM temp_table) t2" +== 050 +-- truncate_limit: 100 +CREATE VIEW v8_temp AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM temp_table) +-- +TABLE: name="v8_temp" schema="" table="v8_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v8_temp AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM temp_table)" +== 051 +-- truncate_limit: 100 +CREATE VIEW v9_temp AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM temp_table) +-- +TABLE: name="v9_temp" schema="" table="v9_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="temp_table" schema="" table="temp_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v9_temp AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM temp_table)" +== 052 +-- truncate_limit: 100 +-- a view should also be temporary if it references a temporary view +CREATE VIEW v10_temp AS SELECT * FROM v7_temp +-- +TABLE: name="v10_temp" schema="" table="v10_temp" ctx=DDL +TABLE: name="v7_temp" schema="" table="v7_temp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v10_temp AS SELECT * FROM v7_temp" +== 053 +-- truncate_limit: 100 +CREATE VIEW v11_temp AS SELECT t1.id, t2.a FROM base_table t1, v10_temp t2 +-- +TABLE: name="v11_temp" schema="" table="v11_temp" ctx=DDL +TABLE: name="base_table" schema="" table="base_table" ctx=Select +TABLE: name="v10_temp" schema="" table="v10_temp" ctx=Select +ALIAS: "t1"="base_table" +ALIAS: "t2"="v10_temp" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v11_temp AS SELECT t1.id, t2.a FROM base_table t1, v10_temp t2" +== 054 +-- truncate_limit: 100 +CREATE VIEW v12_temp AS SELECT true FROM v11_temp +-- +TABLE: name="v12_temp" schema="" table="v12_temp" ctx=DDL +TABLE: name="v11_temp" schema="" table="v11_temp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v12_temp AS SELECT true FROM v11_temp" +== 055 +-- truncate_limit: 100 +-- a view should also be temporary if it references a temporary sequence +CREATE SEQUENCE seq1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq1" +== 056 +-- truncate_limit: 100 +CREATE TEMPORARY SEQUENCE seq1_temp +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE seq1_temp" +== 057 +-- truncate_limit: 100 +CREATE VIEW v9 AS SELECT seq1.is_called FROM seq1 +-- +TABLE: name="v9" schema="" table="v9" ctx=DDL +TABLE: name="seq1" schema="" table="seq1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v9 AS SELECT seq1.is_called FROM seq1" +== 058 +-- truncate_limit: 100 +CREATE VIEW v13_temp AS SELECT seq1_temp.is_called FROM seq1_temp +-- +TABLE: name="v13_temp" schema="" table="v13_temp" ctx=DDL +TABLE: name="seq1_temp" schema="" table="seq1_temp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v13_temp AS SELECT seq1_temp.is_called FROM seq1_temp" +== 059 +-- truncate_limit: 100 +SELECT relname FROM pg_class + WHERE relname LIKE 'v_' + AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'temp_view_test') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE ... ORDER BY relname" +== 060 +-- truncate_limit: 100 +SELECT relname FROM pg_class + WHERE relname LIKE 'v%' + AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp%') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE ... ORDER BY relname" +== 061 +-- truncate_limit: 100 +CREATE SCHEMA testviewschm2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA testviewschm2" +== 062 +-- truncate_limit: 100 +SET search_path TO testviewschm2, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO testviewschm2, public" +== 063 +-- truncate_limit: 100 +CREATE TABLE t1 (num int, name text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (num int, name text)" +== 064 +-- truncate_limit: 100 +CREATE TABLE t2 (num2 int, value text) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t2 (num2 int, value text)" +== 065 +-- truncate_limit: 100 +CREATE TEMP TABLE tt (num2 int, value text) +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt (num2 int, value text)" +== 066 +-- truncate_limit: 100 +CREATE VIEW nontemp1 AS SELECT * FROM t1 CROSS JOIN t2 +-- +TABLE: name="nontemp1" schema="" table="nontemp1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW nontemp1 AS SELECT * FROM t1 CROSS JOIN t2" +== 067 +-- truncate_limit: 100 +CREATE VIEW temporal1 AS SELECT * FROM t1 CROSS JOIN tt +-- +TABLE: name="temporal1" schema="" table="temporal1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW temporal1 AS SELECT * FROM t1 CROSS JOIN tt" +== 068 +-- truncate_limit: 100 +CREATE VIEW nontemp2 AS SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num2 +-- +TABLE: name="nontemp2" schema="" table="nontemp2" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW nontemp2 AS SELECT * FROM t1 JOIN t2 ON t1.num = t2.num2" +== 069 +-- truncate_limit: 100 +CREATE VIEW temporal2 AS SELECT * FROM t1 INNER JOIN tt ON t1.num = tt.num2 +-- +TABLE: name="temporal2" schema="" table="temporal2" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW temporal2 AS SELECT * FROM t1 JOIN tt ON t1.num = tt.num2" +== 070 +-- truncate_limit: 100 +CREATE VIEW nontemp3 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2 +-- +TABLE: name="nontemp3" schema="" table="nontemp3" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW nontemp3 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2" +== 071 +-- truncate_limit: 100 +CREATE VIEW temporal3 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2 +-- +TABLE: name="temporal3" schema="" table="temporal3" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW temporal3 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2" +== 072 +-- truncate_limit: 100 +CREATE VIEW nontemp4 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2 AND t2.value = 'xxx' +-- +TABLE: name="nontemp4" schema="" table="nontemp4" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW nontemp4 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2 AND t2.value = 'xxx'" +== 073 +-- truncate_limit: 100 +CREATE VIEW temporal4 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2 AND tt.value = 'xxx' +-- +TABLE: name="temporal4" schema="" table="temporal4" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW temporal4 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2 AND tt.value = 'xxx'" +== 074 +-- truncate_limit: 100 +SELECT relname FROM pg_class + WHERE relname LIKE 'nontemp%' + AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'testviewschm2') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE ... ORDER BY relname" +== 075 +-- truncate_limit: 100 +SELECT relname FROM pg_class + WHERE relname LIKE 'temporal%' + AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp%') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE ... ORDER BY relname" +== 076 +-- truncate_limit: 100 +CREATE TABLE tbl1 ( a int, b int) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl1 (a int, b int)" +== 077 +-- truncate_limit: 100 +CREATE TABLE tbl2 (c int, d int) +-- +TABLE: name="tbl2" schema="" table="tbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl2 (c int, d int)" +== 078 +-- truncate_limit: 100 +CREATE TABLE tbl3 (e int, f int) +-- +TABLE: name="tbl3" schema="" table="tbl3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl3 (e int, f int)" +== 079 +-- truncate_limit: 100 +CREATE TABLE tbl4 (g int, h int) +-- +TABLE: name="tbl4" schema="" table="tbl4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl4 (g int, h int)" +== 080 +-- truncate_limit: 100 +CREATE TEMP TABLE tmptbl (i int, j int) +-- +TABLE: name="tmptbl" schema="" table="tmptbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tmptbl (i int, j int)" +== 081 +-- truncate_limit: 100 +--Should be in testviewschm2 +CREATE VIEW pubview AS SELECT * FROM tbl1 WHERE tbl1.a +BETWEEN (SELECT d FROM tbl2 WHERE c = 1) AND (SELECT e FROM tbl3 WHERE f = 2) +AND EXISTS (SELECT g FROM tbl4 LEFT JOIN tbl3 ON tbl4.h = tbl3.f) +-- +TABLE: name="pubview" schema="" table="pubview" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl2" schema="" table="tbl2" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +FILTER: schema="" table="tbl1" column="a" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="f" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW pubview AS SELECT * FROM tbl1 WHERE tbl1.a BETWEEN (SELECT d FROM tbl2 WHERE c = 1) A..." +== 082 +-- truncate_limit: 100 +SELECT count(*) FROM pg_class where relname = 'pubview' +AND relnamespace IN (SELECT OID FROM pg_namespace WHERE nspname = 'testviewschm2') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_class WHERE ..." +== 083 +-- truncate_limit: 100 +--Should be in temp object schema +CREATE VIEW mytempview AS SELECT * FROM tbl1 WHERE tbl1.a +BETWEEN (SELECT d FROM tbl2 WHERE c = 1) AND (SELECT e FROM tbl3 WHERE f = 2) +AND EXISTS (SELECT g FROM tbl4 LEFT JOIN tbl3 ON tbl4.h = tbl3.f) +AND NOT EXISTS (SELECT g FROM tbl4 LEFT JOIN tmptbl ON tbl4.h = tmptbl.j) +-- +TABLE: name="mytempview" schema="" table="mytempview" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl2" schema="" table="tbl2" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tmptbl" schema="" table="tmptbl" ctx=Select +FILTER: schema="" table="tbl1" column="a" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="f" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mytempview AS SELECT * FROM tbl1 WHERE tbl1.a BETWEEN (SELECT d FROM tbl2 WHERE c = 1..." +== 084 +-- truncate_limit: 100 +SELECT count(*) FROM pg_class where relname LIKE 'mytempview' +And relnamespace IN (SELECT OID FROM pg_namespace WHERE nspname LIKE 'pg_temp%') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_class WHERE ..." +== 085 +-- truncate_limit: 100 +|-- +-- CREATE VIEW and WITH(...) clause +|-- +CREATE VIEW mysecview1 + AS SELECT * FROM tbl1 WHERE a = 0 +-- +TABLE: name="mysecview1" schema="" table="mysecview1" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview1 AS SELECT * FROM tbl1 WHERE a = 0" +== 086 +-- truncate_limit: 100 +CREATE VIEW mysecview2 WITH (security_barrier=true) + AS SELECT * FROM tbl1 WHERE a > 0 +-- +TABLE: name="mysecview2" schema="" table="mysecview2" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview2 WITH (security_barrier=true) AS SELECT * FROM tbl1 WHERE a > 0" +== 087 +-- truncate_limit: 100 +CREATE VIEW mysecview3 WITH (security_barrier=false) + AS SELECT * FROM tbl1 WHERE a < 0 +-- +TABLE: name="mysecview3" schema="" table="mysecview3" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview3 WITH (security_barrier=false) AS SELECT * FROM tbl1 WHERE a < 0" +== 088 +-- truncate_limit: 100 +CREATE VIEW mysecview4 WITH (security_barrier) + AS SELECT * FROM tbl1 WHERE a <> 0 +-- +TABLE: name="mysecview4" schema="" table="mysecview4" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview4 WITH (security_barrier) AS SELECT * FROM tbl1 WHERE a <> 0" +== 089 +-- truncate_limit: 100 +CREATE VIEW mysecview5 WITH (security_barrier=100) -- Error + AS SELECT * FROM tbl1 WHERE a > 100 +-- +TABLE: name="mysecview5" schema="" table="mysecview5" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview5 WITH (security_barrier=100) AS SELECT * FROM tbl1 WHERE a > 100" +== 090 +-- truncate_limit: 100 +CREATE VIEW mysecview6 WITH (invalid_option) -- Error + AS SELECT * FROM tbl1 WHERE a < 100 +-- +TABLE: name="mysecview6" schema="" table="mysecview6" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview6 WITH (invalid_option) AS SELECT * FROM tbl1 WHERE a < 100" +== 091 +-- truncate_limit: 100 +CREATE VIEW mysecview7 WITH (security_invoker=true) + AS SELECT * FROM tbl1 WHERE a = 100 +-- +TABLE: name="mysecview7" schema="" table="mysecview7" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview7 WITH (security_invoker=true) AS SELECT * FROM tbl1 WHERE a = 100" +== 092 +-- truncate_limit: 100 +CREATE VIEW mysecview8 WITH (security_invoker=false, security_barrier=true) + AS SELECT * FROM tbl1 WHERE a > 100 +-- +TABLE: name="mysecview8" schema="" table="mysecview8" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview8 WITH (security_invoker=false, security_barrier=true) AS SELECT * FROM tbl1..." +== 093 +-- truncate_limit: 100 +CREATE VIEW mysecview9 WITH (security_invoker) + AS SELECT * FROM tbl1 WHERE a < 100 +-- +TABLE: name="mysecview9" schema="" table="mysecview9" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview9 WITH (security_invoker) AS SELECT * FROM tbl1 WHERE a < 100" +== 094 +-- truncate_limit: 100 +CREATE VIEW mysecview10 WITH (security_invoker=100) -- Error + AS SELECT * FROM tbl1 WHERE a <> 100 +-- +TABLE: name="mysecview10" schema="" table="mysecview10" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mysecview10 WITH (security_invoker=100) AS SELECT * FROM tbl1 WHERE a <> 100" +== 095 +-- truncate_limit: 100 +SELECT relname, relkind, reloptions FROM pg_class + WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, + 'mysecview3'::regclass, 'mysecview4'::regclass, + 'mysecview7'::regclass, 'mysecview8'::regclass, + 'mysecview9'::regclass) + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind, reloptions FROM pg_class WHERE ... ORDER BY relname" +== 096 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW mysecview1 + AS SELECT * FROM tbl1 WHERE a = 256 +-- +TABLE: name="mysecview1" schema="" table="mysecview1" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW mysecview1 AS SELECT * FROM tbl1 WHERE a = 256" +== 097 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW mysecview2 + AS SELECT * FROM tbl1 WHERE a > 256 +-- +TABLE: name="mysecview2" schema="" table="mysecview2" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW mysecview2 AS SELECT * FROM tbl1 WHERE a > 256" +== 098 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW mysecview3 WITH (security_barrier=true) + AS SELECT * FROM tbl1 WHERE a < 256 +-- +TABLE: name="mysecview3" schema="" table="mysecview3" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW mysecview3 WITH (security_barrier=true) AS SELECT * FROM tbl1 WHERE a < 256" +== 099 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW mysecview4 WITH (security_barrier=false) + AS SELECT * FROM tbl1 WHERE a <> 256 +-- +TABLE: name="mysecview4" schema="" table="mysecview4" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW mysecview4 WITH (security_barrier=false) AS SELECT * FROM tbl1 WHERE a <> 256" +== 100 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW mysecview7 + AS SELECT * FROM tbl1 WHERE a > 256 +-- +TABLE: name="mysecview7" schema="" table="mysecview7" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW mysecview7 AS SELECT * FROM tbl1 WHERE a > 256" +== 101 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW mysecview8 WITH (security_invoker=true) + AS SELECT * FROM tbl1 WHERE a < 256 +-- +TABLE: name="mysecview8" schema="" table="mysecview8" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW mysecview8 WITH (security_invoker=true) AS SELECT * FROM tbl1 WHERE a < 256" +== 102 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW mysecview9 WITH (security_invoker=false, security_barrier=true) + AS SELECT * FROM tbl1 WHERE a <> 256 +-- +TABLE: name="mysecview9" schema="" table="mysecview9" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW mysecview9 WITH (security_invoker=false, security_barrier=true) AS SELECT ..." +== 103 +-- truncate_limit: 100 +SELECT relname, relkind, reloptions FROM pg_class + WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, + 'mysecview3'::regclass, 'mysecview4'::regclass, + 'mysecview7'::regclass, 'mysecview8'::regclass, + 'mysecview9'::regclass) + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind, reloptions FROM pg_class WHERE ... ORDER BY relname" +== 104 +-- truncate_limit: 100 +-- Check that unknown literals are converted to "text" in CREATE VIEW, +-- so that we don't end up with unknown-type columns. + +CREATE VIEW unspecified_types AS + SELECT 42 as i, 42.5 as num, 'foo' as u, 'foo'::unknown as u2, null as n +-- +TABLE: name="unspecified_types" schema="" table="unspecified_types" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW unspecified_types AS SELECT 42 AS i, 42.5 AS num, 'foo' AS u, 'foo'::unknown AS u2, N..." +== 105 +-- truncate_limit: 100 +SELECT * FROM unspecified_types +-- +TABLE: name="unspecified_types" schema="" table="unspecified_types" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unspecified_types" +== 106 +-- truncate_limit: 100 +-- This test checks that proper typmods are assigned in a multi-row VALUES + +CREATE VIEW tt1 AS + SELECT * FROM ( + VALUES + ('abc'::varchar(3), '0123456789', 42, 'abcd'::varchar(4)), + ('0123456789', 'abc'::varchar(3), 42.12, 'abc'::varchar(4)) + ) vv(a,b,c,d) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt1 AS SELECT * FROM (VALUES ('abc'::varchar(3), '0123456789', 42, 'abcd'::varchar(4)..." +== 107 +-- truncate_limit: 100 +SELECT * FROM tt1 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt1" +== 108 +-- truncate_limit: 100 +SELECT a::varchar(3) FROM tt1 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a::varchar(3) FROM tt1" +== 109 +-- truncate_limit: 100 +DROP VIEW tt1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW tt1" +== 110 +-- truncate_limit: 100 +-- Test view decompilation in the face of relation renaming conflicts + +CREATE TABLE tt1 (f1 int, f2 int, f3 text) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt1 (f1 int, f2 int, f3 text)" +== 111 +-- truncate_limit: 100 +CREATE TABLE tx1 (x1 int, x2 int, x3 text) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx1 (x1 int, x2 int, x3 text)" +== 112 +-- truncate_limit: 100 +CREATE TABLE temp_view_test.tt1 (y1 int, f2 int, f3 text) +-- +TABLE: name="temp_view_test.tt1" schema="temp_view_test" table="tt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE temp_view_test.tt1 (y1 int, f2 int, f3 text)" +== 113 +-- truncate_limit: 100 +CREATE VIEW aliased_view_1 AS + select * from tt1 + where exists (select 1 from tx1 where tt1.f1 = tx1.x1) +-- +TABLE: name="aliased_view_1" schema="" table="aliased_view_1" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tx1" schema="" table="tx1" ctx=Select +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="tx1" column="x1" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW aliased_view_1 AS SELECT * FROM tt1 WHERE EXISTS (SELECT 1 FROM tx1 WHERE tt1.f1 = tx..." +== 114 +-- truncate_limit: 100 +CREATE VIEW aliased_view_2 AS + select * from tt1 a1 + where exists (select 1 from tx1 where a1.f1 = tx1.x1) +-- +TABLE: name="aliased_view_2" schema="" table="aliased_view_2" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tx1" schema="" table="tx1" ctx=Select +ALIAS: "a1"="tt1" +FILTER: schema="" table="a1" column="f1" +FILTER: schema="" table="tx1" column="x1" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW aliased_view_2 AS SELECT * FROM tt1 a1 WHERE EXISTS (SELECT 1 FROM tx1 WHERE a1.f1 = ..." +== 115 +-- truncate_limit: 100 +CREATE VIEW aliased_view_3 AS + select * from tt1 + where exists (select 1 from tx1 a2 where tt1.f1 = a2.x1) +-- +TABLE: name="aliased_view_3" schema="" table="aliased_view_3" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tx1" schema="" table="tx1" ctx=Select +ALIAS: "a2"="tx1" +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="a2" column="x1" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW aliased_view_3 AS SELECT * FROM tt1 WHERE EXISTS (SELECT 1 FROM tx1 a2 WHERE tt1.f1 =..." +== 116 +-- truncate_limit: 100 +CREATE VIEW aliased_view_4 AS + select * from temp_view_test.tt1 + where exists (select 1 from tt1 where temp_view_test.tt1.y1 = tt1.f1) +-- +TABLE: name="aliased_view_4" schema="" table="aliased_view_4" ctx=DDL +TABLE: name="temp_view_test.tt1" schema="temp_view_test" table="tt1" ctx=Select +TABLE: name="tt1" schema="" table="tt1" ctx=Select +FILTER: schema="temp_view_test" table="tt1" column="y1" +FILTER: schema="" table="tt1" column="f1" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW aliased_view_4 AS SELECT * FROM temp_view_test.tt1 WHERE EXISTS (SELECT 1 FROM tt1 WH..." +== 117 +-- truncate_limit: 100 +ALTER TABLE tx1 RENAME TO a1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +TABLE: name="a1" schema="" table="a1" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE tx1 RENAME TO a1" +== 118 +-- truncate_limit: 100 +ALTER TABLE tt1 RENAME TO a2 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +TABLE: name="a2" schema="" table="a2" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE tt1 RENAME TO a2" +== 119 +-- truncate_limit: 100 +ALTER TABLE a1 RENAME TO tt1 +-- +TABLE: name="a1" schema="" table="a1" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE a1 RENAME TO tt1" +== 120 +-- truncate_limit: 100 +ALTER TABLE a2 RENAME TO tx1 +-- +TABLE: name="a2" schema="" table="a2" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE a2 RENAME TO tx1" +== 121 +-- truncate_limit: 100 +ALTER TABLE tx1 SET SCHEMA temp_view_test +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE tx1 SET SCHEMA temp_view_test" +== 122 +-- truncate_limit: 100 +ALTER TABLE temp_view_test.tt1 RENAME TO tmp1 +-- +TABLE: name="temp_view_test.tt1" schema="temp_view_test" table="tt1" ctx=DDL +TABLE: name="temp_view_test.tmp1" schema="temp_view_test" table="tmp1" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE temp_view_test.tt1 RENAME TO tmp1" +== 123 +-- truncate_limit: 100 +ALTER TABLE temp_view_test.tmp1 SET SCHEMA testviewschm2 +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER TABLE temp_view_test.tmp1 SET SCHEMA testviewschm2" +== 124 +-- truncate_limit: 100 +ALTER TABLE tmp1 RENAME TO tx1 +-- +TABLE: name="tmp1" schema="" table="tmp1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE tmp1 RENAME TO tx1" +== 125 +-- truncate_limit: 100 +-- Test correct deparsing of ORDER BY when there is an output name conflict + +create view aliased_order_by as +select x1 as x2, x2 as x1, x3 from tt1 + order by x2 +-- +TABLE: name="aliased_order_by" schema="" table="aliased_order_by" ctx=DDL +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW aliased_order_by AS SELECT x1 AS x2, x2 AS x1, x3 FROM tt1 ORDER BY x2" +== 126 +-- truncate_limit: 100 +-- this is interpreted per SQL92, so really ordering by x1 + + +alter view aliased_order_by rename column x1 to x0 +-- +STMT: RenameStmt +TRUNCATED: "ALTER VIEW aliased_order_by RENAME COLUMN x1 TO x0" +== 127 +-- truncate_limit: 100 +alter view aliased_order_by rename column x3 to x1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER VIEW aliased_order_by RENAME COLUMN x3 TO x1" +== 128 +-- truncate_limit: 100 +-- Test aliasing of joins + +create view view_of_joins as +select * from + (select * from (tbl1 cross join tbl2) same) ss, + (tbl3 cross join tbl4) same +-- +TABLE: name="view_of_joins" schema="" table="view_of_joins" ctx=DDL +TABLE: name="tbl3" schema="" table="tbl3" ctx=Select +TABLE: name="tbl4" schema="" table="tbl4" ctx=Select +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl2" schema="" table="tbl2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_of_joins AS SELECT * FROM (SELECT * FROM (tbl1 CROSS JOIN tbl2 ) same) ss, (tbl3..." +== 129 +-- truncate_limit: 100 +create table tbl1a (a int, c int) +-- +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl1a (a int, c int)" +== 130 +-- truncate_limit: 100 +create view view_of_joins_2a as select * from tbl1 join tbl1a using (a) +-- +TABLE: name="view_of_joins_2a" schema="" table="view_of_joins_2a" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_of_joins_2a AS SELECT * FROM tbl1 JOIN tbl1a USING (a)" +== 131 +-- truncate_limit: 100 +create view view_of_joins_2b as select * from tbl1 join tbl1a using (a) as x +-- +TABLE: name="view_of_joins_2b" schema="" table="view_of_joins_2b" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_of_joins_2b AS SELECT * FROM tbl1 JOIN tbl1a USING (a) AS x" +== 132 +-- truncate_limit: 100 +create view view_of_joins_2c as select * from (tbl1 join tbl1a using (a)) as y +-- +TABLE: name="view_of_joins_2c" schema="" table="view_of_joins_2c" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_of_joins_2c AS SELECT * FROM (tbl1 JOIN tbl1a USING (a) ) y" +== 133 +-- truncate_limit: 100 +create view view_of_joins_2d as select * from (tbl1 join tbl1a using (a) as x) as y +-- +TABLE: name="view_of_joins_2d" schema="" table="view_of_joins_2d" ctx=DDL +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tbl1a" schema="" table="tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_of_joins_2d AS SELECT * FROM (tbl1 JOIN tbl1a USING (a) AS x) y" +== 134 +-- truncate_limit: 100 +select pg_get_viewdef('view_of_joins_2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('view_of_joins_2a', true)" +== 135 +-- truncate_limit: 100 +select pg_get_viewdef('view_of_joins_2b', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('view_of_joins_2b', true)" +== 136 +-- truncate_limit: 100 +select pg_get_viewdef('view_of_joins_2c', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('view_of_joins_2c', true)" +== 137 +-- truncate_limit: 100 +select pg_get_viewdef('view_of_joins_2d', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('view_of_joins_2d', true)" +== 138 +-- truncate_limit: 100 +-- Test view decompilation in the face of column addition/deletion/renaming + +create table tt2 (a int, b int, c int) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt2 (a int, b int, c int)" +== 139 +-- truncate_limit: 100 +create table tt3 (ax int8, b int2, c numeric) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt3 (ax int8, b int2, c numeric)" +== 140 +-- truncate_limit: 100 +create table tt4 (ay int, b int, q int) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt4 (ay int, b int, q int)" +== 141 +-- truncate_limit: 100 +create view v1 as select * from tt2 natural join tt3 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1 AS SELECT * FROM tt2 NATURAL JOIN tt3" +== 142 +-- truncate_limit: 100 +create view v1a as select * from (tt2 natural join tt3) j +-- +TABLE: name="v1a" schema="" table="v1a" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1a AS SELECT * FROM (tt2 NATURAL JOIN tt3 ) j" +== 143 +-- truncate_limit: 100 +create view v2 as select * from tt2 join tt3 using (b,c) join tt4 using (b) +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt4" schema="" table="tt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v2 AS SELECT * FROM tt2 JOIN tt3 USING (b, c) JOIN tt4 USING (b)" +== 144 +-- truncate_limit: 100 +create view v2a as select * from (tt2 join tt3 using (b,c) join tt4 using (b)) j +-- +TABLE: name="v2a" schema="" table="v2a" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt4" schema="" table="tt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v2a AS SELECT * FROM (tt2 JOIN tt3 USING (b, c) JOIN tt4 USING (b) ) j" +== 145 +-- truncate_limit: 100 +create view v3 as select * from tt2 join tt3 using (b,c) full join tt4 using (b) +-- +TABLE: name="v3" schema="" table="v3" ctx=DDL +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt4" schema="" table="tt4" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v3 AS SELECT * FROM tt2 JOIN tt3 USING (b, c) FULL JOIN tt4 USING (b)" +== 146 +-- truncate_limit: 100 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1', true)" +== 147 +-- truncate_limit: 100 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1a', true)" +== 148 +-- truncate_limit: 100 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2', true)" +== 149 +-- truncate_limit: 100 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2a', true)" +== 150 +-- truncate_limit: 100 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v3', true)" +== 151 +-- truncate_limit: 100 +alter table tt2 add column d int +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt2 ADD COLUMN d int" +== 152 +-- truncate_limit: 100 +alter table tt2 add column e int +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt2 ADD COLUMN e int" +== 153 +-- truncate_limit: 100 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1', true)" +== 154 +-- truncate_limit: 100 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1a', true)" +== 155 +-- truncate_limit: 100 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2', true)" +== 156 +-- truncate_limit: 100 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2a', true)" +== 157 +-- truncate_limit: 100 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v3', true)" +== 158 +-- truncate_limit: 100 +alter table tt3 rename c to d +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE tt3 RENAME COLUMN c TO d" +== 159 +-- truncate_limit: 100 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1', true)" +== 160 +-- truncate_limit: 100 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1a', true)" +== 161 +-- truncate_limit: 100 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2', true)" +== 162 +-- truncate_limit: 100 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2a', true)" +== 163 +-- truncate_limit: 100 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v3', true)" +== 164 +-- truncate_limit: 100 +alter table tt3 add column c int +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt3 ADD COLUMN c int" +== 165 +-- truncate_limit: 100 +alter table tt3 add column e int +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt3 ADD COLUMN e int" +== 166 +-- truncate_limit: 100 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1', true)" +== 167 +-- truncate_limit: 100 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1a', true)" +== 168 +-- truncate_limit: 100 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2', true)" +== 169 +-- truncate_limit: 100 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2a', true)" +== 170 +-- truncate_limit: 100 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v3', true)" +== 171 +-- truncate_limit: 100 +alter table tt2 drop column d +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt2 DROP d" +== 172 +-- truncate_limit: 100 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1', true)" +== 173 +-- truncate_limit: 100 +select pg_get_viewdef('v1a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1a', true)" +== 174 +-- truncate_limit: 100 +select pg_get_viewdef('v2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2', true)" +== 175 +-- truncate_limit: 100 +select pg_get_viewdef('v2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v2a', true)" +== 176 +-- truncate_limit: 100 +select pg_get_viewdef('v3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v3', true)" +== 177 +-- truncate_limit: 100 +create table tt5 (a int, b int) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt5 (a int, b int)" +== 178 +-- truncate_limit: 100 +create table tt6 (c int, d int) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt6 (c int, d int)" +== 179 +-- truncate_limit: 100 +create view vv1 as select * from (tt5 cross join tt6) j(aa,bb,cc,dd) +-- +TABLE: name="vv1" schema="" table="vv1" ctx=DDL +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vv1 AS SELECT * FROM (tt5 CROSS JOIN tt6 ) j(aa, bb, cc, dd)" +== 180 +-- truncate_limit: 100 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv1', true)" +== 181 +-- truncate_limit: 100 +alter table tt5 add column c int +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt5 ADD COLUMN c int" +== 182 +-- truncate_limit: 100 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv1', true)" +== 183 +-- truncate_limit: 100 +alter table tt5 add column cc int +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt5 ADD COLUMN cc int" +== 184 +-- truncate_limit: 100 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv1', true)" +== 185 +-- truncate_limit: 100 +alter table tt5 drop column c +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt5 DROP c" +== 186 +-- truncate_limit: 100 +select pg_get_viewdef('vv1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv1', true)" +== 187 +-- truncate_limit: 100 +create view v4 as select * from v1 +-- +TABLE: name="v4" schema="" table="v4" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v4 AS SELECT * FROM v1" +== 188 +-- truncate_limit: 100 +alter view v1 rename column a to x +-- +STMT: RenameStmt +TRUNCATED: "ALTER VIEW v1 RENAME COLUMN a TO x" +== 189 +-- truncate_limit: 100 +select pg_get_viewdef('v1', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v1', true)" +== 190 +-- truncate_limit: 100 +select pg_get_viewdef('v4', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v4', true)" +== 191 +-- truncate_limit: 100 +-- Unnamed FULL JOIN USING is lots of fun too + +create table tt7 (x int, xx int, y int) +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt7 (x int, xx int, y int)" +== 192 +-- truncate_limit: 100 +alter table tt7 drop column xx +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 DROP xx" +== 193 +-- truncate_limit: 100 +create table tt8 (x int, z int) +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt8 (x int, z int)" +== 194 +-- truncate_limit: 100 +create view vv2 as +select * from (values(1,2,3,4,5)) v(a,b,c,d,e) +union all +select * from tt7 full join tt8 using (x), tt8 tt8x +-- +TABLE: name="vv2" schema="" table="vv2" ctx=DDL +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +ALIAS: "tt8x"="tt8" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vv2 AS SELECT * FROM (VALUES (1, 2, 3, 4, 5)) v(a, b, c, d, e) UNION ALL SELECT * FRO..." +== 195 +-- truncate_limit: 100 +select pg_get_viewdef('vv2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv2', true)" +== 196 +-- truncate_limit: 100 +create view vv3 as +select * from (values(1,2,3,4,5,6)) v(a,b,c,x,e,f) +union all +select * from + tt7 full join tt8 using (x), + tt7 tt7x full join tt8 tt8x using (x) +-- +TABLE: name="vv3" schema="" table="vv3" ctx=DDL +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +ALIAS: "tt7x"="tt7" +ALIAS: "tt8x"="tt8" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vv3 AS SELECT * FROM (VALUES (1, 2, 3, 4, 5, 6)) v(a, b, c, x, e, f) UNION ALL SELECT..." +== 197 +-- truncate_limit: 100 +select pg_get_viewdef('vv3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv3', true)" +== 198 +-- truncate_limit: 100 +create view vv4 as +select * from (values(1,2,3,4,5,6,7)) v(a,b,c,x,e,f,g) +union all +select * from + tt7 full join tt8 using (x), + tt7 tt7x full join tt8 tt8x using (x) full join tt8 tt8y using (x) +-- +TABLE: name="vv4" schema="" table="vv4" ctx=DDL +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt7" schema="" table="tt7" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +TABLE: name="tt8" schema="" table="tt8" ctx=Select +ALIAS: "tt7x"="tt7" +ALIAS: "tt8x"="tt8" +ALIAS: "tt8y"="tt8" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vv4 AS SELECT * FROM (VALUES (1, 2, 3, 4, 5, 6, 7)) v(a, b, c, x, e, f, g) UNION ALL ..." +== 199 +-- truncate_limit: 100 +select pg_get_viewdef('vv4', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv4', true)" +== 200 +-- truncate_limit: 100 +alter table tt7 add column zz int +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 ADD COLUMN zz int" +== 201 +-- truncate_limit: 100 +alter table tt7 add column z int +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 ADD COLUMN z int" +== 202 +-- truncate_limit: 100 +alter table tt7 drop column zz +-- +TABLE: name="tt7" schema="" table="tt7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7 DROP zz" +== 203 +-- truncate_limit: 100 +alter table tt8 add column z2 int +-- +TABLE: name="tt8" schema="" table="tt8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt8 ADD COLUMN z2 int" +== 204 +-- truncate_limit: 100 +select pg_get_viewdef('vv2', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv2', true)" +== 205 +-- truncate_limit: 100 +select pg_get_viewdef('vv3', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv3', true)" +== 206 +-- truncate_limit: 100 +select pg_get_viewdef('vv4', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv4', true)" +== 207 +-- truncate_limit: 100 +-- Implicit coercions in a JOIN USING create issues similar to FULL JOIN + +create table tt7a (x date, xx int, y int) +-- +TABLE: name="tt7a" schema="" table="tt7a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt7a (x date, xx int, y int)" +== 208 +-- truncate_limit: 100 +alter table tt7a drop column xx +-- +TABLE: name="tt7a" schema="" table="tt7a" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt7a DROP xx" +== 209 +-- truncate_limit: 100 +create table tt8a (x timestamptz, z int) +-- +TABLE: name="tt8a" schema="" table="tt8a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt8a (x timestamptz, z int)" +== 210 +-- truncate_limit: 100 +create view vv2a as +select * from (values(now(),2,3,now(),5)) v(a,b,c,d,e) +union all +select * from tt7a left join tt8a using (x), tt8a tt8ax +-- +TABLE: name="vv2a" schema="" table="vv2a" ctx=DDL +TABLE: name="tt7a" schema="" table="tt7a" ctx=Select +TABLE: name="tt8a" schema="" table="tt8a" ctx=Select +TABLE: name="tt8a" schema="" table="tt8a" ctx=Select +ALIAS: "tt8ax"="tt8a" +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vv2a AS SELECT * FROM (VALUES (now(), 2, 3, now(), 5)) v(a, b, c, d, e) UNION ALL SEL..." +== 211 +-- truncate_limit: 100 +select pg_get_viewdef('vv2a', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv2a', true)" +== 212 +-- truncate_limit: 100 +|-- +-- Also check dropping a column that existed when the view was made +|-- + +create table tt9 (x int, xx int, y int) +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt9 (x int, xx int, y int)" +== 213 +-- truncate_limit: 100 +create table tt10 (x int, z int) +-- +TABLE: name="tt10" schema="" table="tt10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt10 (x int, z int)" +== 214 +-- truncate_limit: 100 +create view vv5 as select x,y,z from tt9 join tt10 using(x) +-- +TABLE: name="vv5" schema="" table="vv5" ctx=DDL +TABLE: name="tt9" schema="" table="tt9" ctx=Select +TABLE: name="tt10" schema="" table="tt10" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vv5 AS SELECT x, y, z FROM tt9 JOIN tt10 USING (x)" +== 215 +-- truncate_limit: 100 +select pg_get_viewdef('vv5', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv5', true)" +== 216 +-- truncate_limit: 100 +alter table tt9 drop column xx +-- +TABLE: name="tt9" schema="" table="tt9" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt9 DROP xx" +== 217 +-- truncate_limit: 100 +select pg_get_viewdef('vv5', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv5', true)" +== 218 +-- truncate_limit: 100 +|-- +-- Another corner case is that we might add a column to a table below a +-- JOIN USING, and thereby make the USING column name ambiguous +|-- + +create table tt11 (x int, y int) +-- +TABLE: name="tt11" schema="" table="tt11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt11 (x int, y int)" +== 219 +-- truncate_limit: 100 +create table tt12 (x int, z int) +-- +TABLE: name="tt12" schema="" table="tt12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt12 (x int, z int)" +== 220 +-- truncate_limit: 100 +create table tt13 (z int, q int) +-- +TABLE: name="tt13" schema="" table="tt13" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt13 (z int, q int)" +== 221 +-- truncate_limit: 100 +create view vv6 as select x,y,z,q from + (tt11 join tt12 using(x)) join tt13 using(z) +-- +TABLE: name="vv6" schema="" table="vv6" ctx=DDL +TABLE: name="tt11" schema="" table="tt11" ctx=Select +TABLE: name="tt12" schema="" table="tt12" ctx=Select +TABLE: name="tt13" schema="" table="tt13" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vv6 AS SELECT x, y, z, q FROM tt11 JOIN tt12 USING (x) JOIN tt13 USING (z)" +== 222 +-- truncate_limit: 100 +select pg_get_viewdef('vv6', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv6', true)" +== 223 +-- truncate_limit: 100 +alter table tt11 add column z int +-- +TABLE: name="tt11" schema="" table="tt11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt11 ADD COLUMN z int" +== 224 +-- truncate_limit: 100 +select pg_get_viewdef('vv6', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vv6', true)" +== 225 +-- truncate_limit: 100 +|-- +-- Check cases involving dropped/altered columns in a function's rowtype result +|-- + +create table tt14t (f1 text, f2 text, f3 text, f4 text) +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt14t (f1 text, f2 text, f3 text, f4 text)" +== 226 +-- truncate_limit: 100 +insert into tt14t values('foo', 'bar', 'baz', '42') +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt14t VALUES ('foo', 'bar', 'baz', '42')" +== 227 +-- truncate_limit: 100 +alter table tt14t drop column f2 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt14t DROP f2" +== 228 +-- truncate_limit: 100 +create function tt14f() returns setof tt14t as +$$ +declare + rec1 record; +begin + for rec1 in select * from tt14t + loop + return next rec1; + end loop; +end; +$$ +language plpgsql +-- +FUNCTION: name="tt14f" function="tt14f" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tt14f() RETURNS SETOF tt14t AS $$\ndeclare\n rec1 record;\nbegin\n for rec1 in ..." +== 229 +-- truncate_limit: 100 +create view tt14v as select t.* from tt14f() t +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=DDL +FUNCTION: name="tt14f" function="tt14f" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt14v AS SELECT t.* FROM tt14f() t" +== 230 +-- truncate_limit: 100 +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt14v', true)" +== 231 +-- truncate_limit: 100 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt14v" +== 232 +-- truncate_limit: 100 +alter table tt14t drop column f3 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt14t DROP f3" +== 233 +-- truncate_limit: 100 +-- fail, view has explicit reference to f3 + +-- We used to have a bug that would allow the above to succeed, posing +-- hazards for later execution of the view. Check that the internal +-- defenses for those hazards haven't bit-rotted, in case some other +-- bug with similar symptoms emerges. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 234 +-- truncate_limit: 100 +-- destroy the dependency entry that prevents the DROP: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'tt14v'::regclass and rulename = '_RETURN') + and refobjsubid = 3 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM pg_depend WHERE ... RETURNING pg_describe_object(classid, objid, objsubid) AS obj, pg..." +== 235 +-- truncate_limit: 100 +-- this will now succeed: +alter table tt14t drop column f3 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt14t DROP f3" +== 236 +-- truncate_limit: 100 +-- column f3 is still in the view, sort of ... +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt14v', true)" +== 237 +-- truncate_limit: 100 +-- ... and you can even EXPLAIN it ... +explain (verbose, costs off) select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM tt14v" +== 238 +-- truncate_limit: 100 +-- but it will fail at execution +select f1, f4 from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f4 FROM tt14v" +== 239 +-- truncate_limit: 100 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt14v" +== 240 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 241 +-- truncate_limit: 100 +-- likewise, altering a referenced column's type is prohibited ... +alter table tt14t alter column f4 type integer using f4::integer +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt14t ALTER COLUMN f4 TYPE int USING f4::int" +== 242 +-- truncate_limit: 100 +-- fail + +-- ... but some bug might let it happen, so check defenses +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 243 +-- truncate_limit: 100 +-- destroy the dependency entry that prevents the ALTER: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'tt14v'::regclass and rulename = '_RETURN') + and refobjsubid = 4 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM pg_depend WHERE ... RETURNING pg_describe_object(classid, objid, objsubid) AS obj, pg..." +== 244 +-- truncate_limit: 100 +-- this will now succeed: +alter table tt14t alter column f4 type integer using f4::integer +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt14t ALTER COLUMN f4 TYPE int USING f4::int" +== 245 +-- truncate_limit: 100 +-- f4 is still in the view ... +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt14v', true)" +== 246 +-- truncate_limit: 100 +-- but will fail at execution +select f1, f3 from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f3 FROM tt14v" +== 247 +-- truncate_limit: 100 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt14v" +== 248 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 249 +-- truncate_limit: 100 +drop view tt14v +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW tt14v" +== 250 +-- truncate_limit: 100 +create view tt14v as select t.f1, t.f4 from tt14f() t +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=DDL +FUNCTION: name="tt14f" function="tt14f" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt14v AS SELECT t.f1, t.f4 FROM tt14f() t" +== 251 +-- truncate_limit: 100 +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt14v', true)" +== 252 +-- truncate_limit: 100 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt14v" +== 253 +-- truncate_limit: 100 +alter table tt14t drop column f3 +-- +TABLE: name="tt14t" schema="" table="tt14t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tt14t DROP f3" +== 254 +-- truncate_limit: 100 +-- ok + +select pg_get_viewdef('tt14v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt14v', true)" +== 255 +-- truncate_limit: 100 +explain (verbose, costs off) select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM tt14v" +== 256 +-- truncate_limit: 100 +select * from tt14v +-- +TABLE: name="tt14v" schema="" table="tt14v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt14v" +== 257 +-- truncate_limit: 100 +-- check display of whole-row variables in some corner cases + +create type nestedcomposite as (x int8_tbl) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE nestedcomposite AS (x int8_tbl)" +== 258 +-- truncate_limit: 100 +create view tt15v as select row(i)::nestedcomposite from int8_tbl i +-- +TABLE: name="tt15v" schema="" table="tt15v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt15v AS SELECT ROW(i)::nestedcomposite FROM int8_tbl i" +== 259 +-- truncate_limit: 100 +select * from tt15v +-- +TABLE: name="tt15v" schema="" table="tt15v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt15v" +== 260 +-- truncate_limit: 100 +select pg_get_viewdef('tt15v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt15v', true)" +== 261 +-- truncate_limit: 100 +select row(i.*::int8_tbl)::nestedcomposite from int8_tbl i +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ROW(i.*::int8_tbl)::nestedcomposite FROM int8_tbl i" +== 262 +-- truncate_limit: 100 +create view tt16v as select * from int8_tbl i, lateral(values(i)) ss +-- +TABLE: name="tt16v" schema="" table="tt16v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt16v AS SELECT * FROM int8_tbl i, LATERAL (VALUES (i)) ss" +== 263 +-- truncate_limit: 100 +select * from tt16v +-- +TABLE: name="tt16v" schema="" table="tt16v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt16v" +== 264 +-- truncate_limit: 100 +select pg_get_viewdef('tt16v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt16v', true)" +== 265 +-- truncate_limit: 100 +select * from int8_tbl i, lateral(values(i.*::int8_tbl)) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl i, LATERAL (VALUES (i.*::int8_tbl)) ss" +== 266 +-- truncate_limit: 100 +create view tt17v as select * from int8_tbl i where i in (values(i)) +-- +TABLE: name="tt17v" schema="" table="tt17v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +FILTER: schema="" table="" column="i" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt17v AS SELECT * FROM int8_tbl i WHERE i IN (VALUES (i))" +== 267 +-- truncate_limit: 100 +select * from tt17v +-- +TABLE: name="tt17v" schema="" table="tt17v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt17v" +== 268 +-- truncate_limit: 100 +select pg_get_viewdef('tt17v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt17v', true)" +== 269 +-- truncate_limit: 100 +select * from int8_tbl i where i.* in (values(i.*::int8_tbl)) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl i WHERE i.* IN (VALUES (i.*::int8_tbl))" +== 270 +-- truncate_limit: 100 +create table tt15v_log(o tt15v, n tt15v, incr bool) +-- +TABLE: name="tt15v_log" schema="" table="tt15v_log" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt15v_log (o tt15v, n tt15v, incr bool)" +== 271 +-- truncate_limit: 100 +create rule updlog as on update to tt15v do also + insert into tt15v_log values(old, new, row(old,old) < row(new,new)) +-- +TABLE: name="tt15v" schema="" table="tt15v" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE updlog AS ON UPDATE TO tt15v DO INSERT INTO tt15v_log VALUES (old, new, ROW(old, old)..." +== 272 +-- truncate_limit: 100 +-- check unique-ification of overlength names + +create view tt18v as + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy + union all + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz +-- +TABLE: name="tt18v" schema="" table="tt18v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"="int8_tbl" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt18v AS SELECT * FROM int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..." +== 273 +-- truncate_limit: 100 +select pg_get_viewdef('tt18v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt18v', true)" +== 274 +-- truncate_limit: 100 +explain (costs off) select * from tt18v +-- +TABLE: name="tt18v" schema="" table="tt18v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tt18v" +== 275 +-- truncate_limit: 100 +-- check display of ScalarArrayOp with a sub-select + +select 'foo'::text = any(array['abc','def','foo']::text[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo'::text = ANY(ARRAY['abc', 'def', 'foo']::text[])" +== 276 +-- truncate_limit: 100 +select 'foo'::text = any((select array['abc','def','foo']::text[])) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo'::text = ANY (SELECT ARRAY['abc', 'def', 'foo']::text[])" +== 277 +-- truncate_limit: 100 +-- fail +select 'foo'::text = any((select array['abc','def','foo']::text[])::text[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo'::text = ANY((SELECT ARRAY['abc', 'def', 'foo']::text[])::text[])" +== 278 +-- truncate_limit: 100 +create view tt19v as +select 'foo'::text = any(array['abc','def','foo']::text[]) c1, + 'foo'::text = any((select array['abc','def','foo']::text[])::text[]) c2 +-- +TABLE: name="tt19v" schema="" table="tt19v" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt19v AS SELECT 'foo'::text = ANY(ARRAY['abc', 'def', 'foo']::text[]) AS c1, 'foo'::t..." +== 279 +-- truncate_limit: 100 +select pg_get_viewdef('tt19v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt19v', true)" +== 280 +-- truncate_limit: 100 +-- check display of assorted RTE_FUNCTION expressions + +create view tt20v as +select * from + coalesce(1,2) as c, + collation for ('x'::text) col, + current_date as d, + localtimestamp(3) as t, + cast(1+2 as int4) as i4, + cast(1+2 as int8) as i8 +-- +TABLE: name="tt20v" schema="" table="tt20v" ctx=DDL +FUNCTION: name="pg_catalog.pg_collation_for" function="pg_collation_for" schema="pg_catalog" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt20v AS SELECT * FROM COALESCE(1, 2) c, collation for ('x'::text) col, current_date ..." +== 281 +-- truncate_limit: 100 +select pg_get_viewdef('tt20v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt20v', true)" +== 282 +-- truncate_limit: 100 +-- reverse-listing of various special function syntaxes required by SQL + +create view tt201v as +select + ('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz, + extract(day from now()) as extr, + (now(), '1 day'::interval) overlaps + (current_timestamp(2), '1 day'::interval) as o, + 'foo' is normalized isn, + 'foo' is nfkc normalized isnn, + normalize('foo') as n, + normalize('foo', nfkd) as nfkd, + overlay('foo' placing 'bar' from 2) as ovl, + overlay('foo' placing 'bar' from 2 for 3) as ovl2, + position('foo' in 'foobar') as p, + substring('foo' from 2 for 3) as s, + substring('foo' similar 'f' escape '#') as ss, + substring('foo' from 'oo') as ssf, -- historically-permitted abuse + trim(' ' from ' foo ') as bt, + trim(leading ' ' from ' foo ') as lt, + trim(trailing ' foo ') as rt, + trim(E'\\000'::bytea from E'\\000Tom\\000'::bytea) as btb, + trim(leading E'\\000'::bytea from E'\\000Tom\\000'::bytea) as ltb, + trim(trailing E'\\000'::bytea from E'\\000Tom\\000'::bytea) as rtb, + CURRENT_DATE as cd, + (select * from CURRENT_DATE) as cd2, + CURRENT_TIME as ct, + (select * from CURRENT_TIME) as ct2, + CURRENT_TIME (1) as ct3, + (select * from CURRENT_TIME (1)) as ct4, + CURRENT_TIMESTAMP as ct5, + (select * from CURRENT_TIMESTAMP) as ct6, + CURRENT_TIMESTAMP (1) as ct7, + (select * from CURRENT_TIMESTAMP (1)) as ct8, + LOCALTIME as lt1, + (select * from LOCALTIME) as lt2, + LOCALTIME (1) as lt3, + (select * from LOCALTIME (1)) as lt4, + LOCALTIMESTAMP as lt5, + (select * from LOCALTIMESTAMP) as lt6, + LOCALTIMESTAMP (1) as lt7, + (select * from LOCALTIMESTAMP (1)) as lt8, + CURRENT_CATALOG as ca, + (select * from CURRENT_CATALOG) as ca2, + CURRENT_ROLE as cr, + (select * from CURRENT_ROLE) as cr2, + CURRENT_SCHEMA as cs, + (select * from CURRENT_SCHEMA) as cs2, + CURRENT_USER as cu, + (select * from CURRENT_USER) as cu2, + USER as us, + (select * from USER) as us2, + SESSION_USER seu, + (select * from SESSION_USER) as seu2, + SYSTEM_USER as su, + (select * from SYSTEM_USER) as su2 +-- +TABLE: name="tt201v" schema="" table="tt201v" ctx=DDL +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.overlay" function="overlay" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.position" function="position" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.btrim" function="btrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.ltrim" function="ltrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.rtrim" function="rtrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.btrim" function="btrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.ltrim" function="ltrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.rtrim" function="rtrim" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.system_user" function="system_user" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.system_user" function="system_user" schema="pg_catalog" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt201v AS SELECT ('2022-12-01'::date + '1 day'::interval) AT TIME ZONE 'UTC' AS atz, ..." +== 283 +-- truncate_limit: 100 +select pg_get_viewdef('tt201v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt201v', true)" +== 284 +-- truncate_limit: 100 +-- corner cases with empty join conditions + +create view tt21v as +select * from tt5 natural inner join tt6 +-- +TABLE: name="tt21v" schema="" table="tt21v" ctx=DDL +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt21v AS SELECT * FROM tt5 NATURAL JOIN tt6" +== 285 +-- truncate_limit: 100 +select pg_get_viewdef('tt21v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt21v', true)" +== 286 +-- truncate_limit: 100 +create view tt22v as +select * from tt5 natural left join tt6 +-- +TABLE: name="tt22v" schema="" table="tt22v" ctx=DDL +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt22v AS SELECT * FROM tt5 NATURAL LEFT JOIN tt6" +== 287 +-- truncate_limit: 100 +select pg_get_viewdef('tt22v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt22v', true)" +== 288 +-- truncate_limit: 100 +-- check handling of views with immediately-renamed columns + +create view tt23v (col_a, col_b) as +select q1 as other_name1, q2 as other_name2 from int8_tbl +union +select 42, 43 +-- +TABLE: name="tt23v" schema="" table="tt23v" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt23v (col_a, col_b) AS SELECT q1 AS other_name1, q2 AS other_name2 FROM int8_tbl UNI..." +== 289 +-- truncate_limit: 100 +select pg_get_viewdef('tt23v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt23v', true)" +== 290 +-- truncate_limit: 100 +select pg_get_ruledef(oid, true) from pg_rewrite + where ev_class = 'tt23v'::regclass and ev_type = '1' +-- +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_get_ruledef" function="pg_get_ruledef" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="ev_type" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_ruledef(oid, true) FROM pg_rewrite WHERE ..." +== 291 +-- truncate_limit: 100 +-- test extraction of FieldSelect field names (get_name_for_var_field) + +create view tt24v as +with cte as materialized (select r from (values(1,2),(3,4)) r) +select (r).column2 as col_a, (rr).column2 as col_b from + cte join (select rr from (values(1,7),(3,8)) rr limit 2) ss + on (r).column1 = (rr).column1 +-- +TABLE: name="tt24v" schema="" table="tt24v" ctx=DDL +CTE: "cte" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt24v AS WITH cte AS MATERIALIZED (SELECT r FROM (VALUES (1, 2), (3, 4)) r) SELECT (r..." +== 292 +-- truncate_limit: 100 +select pg_get_viewdef('tt24v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt24v', true)" +== 293 +-- truncate_limit: 100 +create view tt25v as +with cte as materialized (select pg_get_keywords() k) +select (k).word from cte +-- +TABLE: name="tt25v" schema="" table="tt25v" ctx=DDL +CTE: "cte" +FUNCTION: name="pg_get_keywords" function="pg_get_keywords" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt25v AS WITH cte AS MATERIALIZED (SELECT pg_get_keywords() AS k) SELECT (k).word FRO..." +== 294 +-- truncate_limit: 100 +select pg_get_viewdef('tt25v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt25v', true)" +== 295 +-- truncate_limit: 100 +-- also check cases seen only in EXPLAIN +explain (verbose, costs off) +select * from tt24v +-- +TABLE: name="tt24v" schema="" table="tt24v" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM tt24v" +== 296 +-- truncate_limit: 100 +explain (verbose, costs off) +select (r).column2 from (select r from (values(1,2),(3,4)) r limit 1) ss +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT (r).column2 FROM (SELECT r FROM (VALUES (1, 2), (3, 4)) r LIM..." +== 297 +-- truncate_limit: 100 +-- test pretty-print parenthesization rules, and SubLink deparsing + +create view tt26v as +select x + y + z as c1, + (x * y) + z as c2, + x + (y * z) as c3, + (x + y) * z as c4, + x * (y + z) as c5, + x + (y + z) as c6, + x + (y # z) as c7, + (x > y) AND (y > z OR x > z) as c8, + (x > y) OR (y > z AND NOT (x > z)) as c9, + (x,y) <> ALL (values(1,2),(3,4)) as c10, + (x,y) <= ANY (values(1,2),(3,4)) as c11 +from (values(1,2,3)) v(x,y,z) +-- +TABLE: name="tt26v" schema="" table="tt26v" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt26v AS SELECT (x + y) + z AS c1, (x * y) + z AS c2, x + (y * z) AS c3, (x + y) * z ..." +== 298 +-- truncate_limit: 100 +select pg_get_viewdef('tt26v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('tt26v', true)" +== 299 +-- truncate_limit: 100 +-- test restriction on non-system view expansion. +create table tt27v_tbl (a int) +-- +TABLE: name="tt27v_tbl" schema="" table="tt27v_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tt27v_tbl (a int)" +== 300 +-- truncate_limit: 100 +create view tt27v as select a from tt27v_tbl +-- +TABLE: name="tt27v" schema="" table="tt27v" ctx=DDL +TABLE: name="tt27v_tbl" schema="" table="tt27v_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tt27v AS SELECT a FROM tt27v_tbl" +== 301 +-- truncate_limit: 100 +set restrict_nonsystem_relation_kind to 'view' +-- +STMT: VariableSetStmt +TRUNCATED: "SET restrict_nonsystem_relation_kind TO view" +== 302 +-- truncate_limit: 100 +select a from tt27v where a > 0 +-- +TABLE: name="tt27v" schema="" table="tt27v" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM tt27v WHERE a > 0" +== 303 +-- truncate_limit: 100 +-- Error +insert into tt27v values (1) +-- +TABLE: name="tt27v" schema="" table="tt27v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt27v VALUES (1)" +== 304 +-- truncate_limit: 100 +-- Error +select viewname from pg_views where viewname = 'tt27v' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +TRUNCATED: "SELECT viewname FROM pg_views WHERE viewname = 'tt27v'" +== 305 +-- truncate_limit: 100 +-- Ok to access a system view. +reset restrict_nonsystem_relation_kind +-- +STMT: VariableSetStmt +TRUNCATED: "RESET restrict_nonsystem_relation_kind" +== 306 +-- truncate_limit: 100 +-- clean up all the random objects we made above +DROP SCHEMA temp_view_test CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA temp_view_test CASCADE" +== 307 +-- truncate_limit: 100 +DROP SCHEMA testviewschm2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA testviewschm2 CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/database.metadata.json b/parser/testdata/summary_truncate/postgres_regress/database.metadata.json new file mode 100644 index 0000000..e71b2c2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/database.metadata.json @@ -0,0 +1,20 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/database.test b/parser/testdata/summary_truncate/postgres_regress/database.test new file mode 100644 index 0000000..82c36b1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/database.test @@ -0,0 +1,104 @@ +== 001 +-- truncate_limit: 100 +CREATE DATABASE regression_tbd + ENCODING utf8 LC_COLLATE "C" LC_CTYPE "C" TEMPLATE template0 +-- +STMT: CreatedbStmt +TRUNCATED: "CREATE DATABASE regression_tbd ENCODING utf8 LC_COLLATE \"C\" LC_CTYPE \"C\" TEMPLATE template0" +== 002 +-- truncate_limit: 100 +ALTER DATABASE regression_tbd RENAME TO regression_utf8 +-- +STMT: RenameStmt +TRUNCATED: "ALTER DATABASE regression_tbd RENAME TO regression_utf8" +== 003 +-- truncate_limit: 100 +ALTER DATABASE regression_utf8 SET TABLESPACE regress_tblspace +-- +STMT: AlterDatabaseStmt +TRUNCATED: "ALTER DATABASE regression_utf8 TABLESPACE regress_tblspace" +== 004 +-- truncate_limit: 100 +ALTER DATABASE regression_utf8 RESET TABLESPACE +-- +STMT: AlterDatabaseSetStmt +TRUNCATED: "ALTER DATABASE regression_utf8 RESET tablespace" +== 005 +-- truncate_limit: 100 +ALTER DATABASE regression_utf8 CONNECTION_LIMIT 123 +-- +STMT: AlterDatabaseStmt +TRUNCATED: "ALTER DATABASE regression_utf8 CONNECTION LIMIT 123" +== 006 +-- truncate_limit: 100 +-- Test PgDatabaseToastTable. Doing this with GRANT would be slow. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 007 +-- truncate_limit: 100 +UPDATE pg_database +SET datacl = array_fill(makeaclitem(10, 10, 'USAGE', false), ARRAY[5e5::int]) +WHERE datname = 'regression_utf8' +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=DML +FUNCTION: name="array_fill" function="array_fill" schema="" ctx=Call +FUNCTION: name="makeaclitem" function="makeaclitem" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE pg_database SET ... = ... WHERE datname = 'regression_utf8'" +== 008 +-- truncate_limit: 100 +-- load catcache entry, if nothing else does +ALTER DATABASE regression_utf8 RESET TABLESPACE +-- +STMT: AlterDatabaseSetStmt +TRUNCATED: "ALTER DATABASE regression_utf8 RESET tablespace" +== 009 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 010 +-- truncate_limit: 100 +CREATE ROLE regress_datdba_before +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_datdba_before" +== 011 +-- truncate_limit: 100 +CREATE ROLE regress_datdba_after +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_datdba_after" +== 012 +-- truncate_limit: 100 +ALTER DATABASE regression_utf8 OWNER TO regress_datdba_before +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER DATABASE regression_utf8 OWNER TO regress_datdba_before" +== 013 +-- truncate_limit: 100 +REASSIGN OWNED BY regress_datdba_before TO regress_datdba_after +-- +STMT: ReassignOwnedStmt +TRUNCATED: "REASSIGN OWNED BY regress_datdba_before TO regress_datdba_after" +== 014 +-- truncate_limit: 100 +DROP DATABASE regression_utf8 +-- +STMT: DropdbStmt +TRUNCATED: "DROP DATABASE regression_utf8" +== 015 +-- truncate_limit: 100 +DROP ROLE regress_datdba_before +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_datdba_before" +== 016 +-- truncate_limit: 100 +DROP ROLE regress_datdba_after +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_datdba_after" diff --git a/parser/testdata/summary_truncate/postgres_regress/date.metadata.json b/parser/testdata/summary_truncate/postgres_regress/date.metadata.json new file mode 100644 index 0000000..a6ce2f7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/date.metadata.json @@ -0,0 +1,274 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/date.test b/parser/testdata/summary_truncate/postgres_regress/date.test new file mode 100644 index 0000000..258d36e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/date.test @@ -0,0 +1,1902 @@ +== 001 +-- truncate_limit: 100 +|-- +-- DATE +|-- + +CREATE TABLE DATE_TBL (f1 date) +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE date_tbl (f1 date)" +== 002 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1957-04-09') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1957-04-09')" +== 003 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1957-06-13') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1957-06-13')" +== 004 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1996-02-28') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1996-02-28')" +== 005 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1996-02-29') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1996-02-29')" +== 006 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1996-03-01') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1996-03-01')" +== 007 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1996-03-02') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1996-03-02')" +== 008 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1997-02-28') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1997-02-28')" +== 009 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1997-02-29') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1997-02-29')" +== 010 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1997-03-01') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1997-03-01')" +== 011 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('1997-03-02') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('1997-03-02')" +== 012 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('2000-04-01') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('2000-04-01')" +== 013 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('2000-04-02') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('2000-04-02')" +== 014 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('2000-04-03') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('2000-04-03')" +== 015 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('2038-04-08') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('2038-04-08')" +== 016 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('2039-04-09') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('2039-04-09')" +== 017 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('2040-04-10') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('2040-04-10')" +== 018 +-- truncate_limit: 100 +INSERT INTO DATE_TBL VALUES ('2040-04-10 BC') +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO date_tbl VALUES ('2040-04-10 BC')" +== 019 +-- truncate_limit: 100 +SELECT f1 FROM DATE_TBL +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM date_tbl" +== 020 +-- truncate_limit: 100 +SELECT f1 FROM DATE_TBL WHERE f1 < '2000-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM date_tbl WHERE f1 < '2000-01-01'" +== 021 +-- truncate_limit: 100 +SELECT f1 FROM DATE_TBL + WHERE f1 BETWEEN '2000-01-01' AND '2001-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM date_tbl WHERE f1 BETWEEN '2000-01-01' AND '2001-01-01'" +== 022 +-- truncate_limit: 100 +|-- +-- Check all the documented input formats +|-- +SET datestyle TO iso +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO iso" +== 023 +-- truncate_limit: 100 +-- display results in ISO + +SET datestyle TO ymd +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO ymd" +== 024 +-- truncate_limit: 100 +SELECT date 'January 8, 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'January 8, 1999'::date" +== 025 +-- truncate_limit: 100 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-08'::date" +== 026 +-- truncate_limit: 100 +SELECT date '1999-01-18' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-18'::date" +== 027 +-- truncate_limit: 100 +SELECT date '1/8/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1/8/1999'::date" +== 028 +-- truncate_limit: 100 +SELECT date '1/18/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1/18/1999'::date" +== 029 +-- truncate_limit: 100 +SELECT date '18/1/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '18/1/1999'::date" +== 030 +-- truncate_limit: 100 +SELECT date '01/02/03' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01/02/03'::date" +== 031 +-- truncate_limit: 100 +SELECT date '19990108' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '19990108'::date" +== 032 +-- truncate_limit: 100 +SELECT date '990108' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '990108'::date" +== 033 +-- truncate_limit: 100 +SELECT date '1999.008' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999.008'::date" +== 034 +-- truncate_limit: 100 +SELECT date 'J2451187' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2451187'::date" +== 035 +-- truncate_limit: 100 +SELECT date 'January 8, 99 BC' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'January 8, 99 BC'::date" +== 036 +-- truncate_limit: 100 +SELECT date '99-Jan-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-Jan-08'::date" +== 037 +-- truncate_limit: 100 +SELECT date '1999-Jan-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-Jan-08'::date" +== 038 +-- truncate_limit: 100 +SELECT date '08-Jan-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-Jan-99'::date" +== 039 +-- truncate_limit: 100 +SELECT date '08-Jan-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-Jan-1999'::date" +== 040 +-- truncate_limit: 100 +SELECT date 'Jan-08-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan-08-99'::date" +== 041 +-- truncate_limit: 100 +SELECT date 'Jan-08-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan-08-1999'::date" +== 042 +-- truncate_limit: 100 +SELECT date '99-08-Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-08-Jan'::date" +== 043 +-- truncate_limit: 100 +SELECT date '1999-08-Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-08-Jan'::date" +== 044 +-- truncate_limit: 100 +SELECT date '99 Jan 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 Jan 08'::date" +== 045 +-- truncate_limit: 100 +SELECT date '1999 Jan 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 Jan 08'::date" +== 046 +-- truncate_limit: 100 +SELECT date '08 Jan 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 Jan 99'::date" +== 047 +-- truncate_limit: 100 +SELECT date '08 Jan 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 Jan 1999'::date" +== 048 +-- truncate_limit: 100 +SELECT date 'Jan 08 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 08 99'::date" +== 049 +-- truncate_limit: 100 +SELECT date 'Jan 08 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 08 1999'::date" +== 050 +-- truncate_limit: 100 +SELECT date '99 08 Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 08 Jan'::date" +== 051 +-- truncate_limit: 100 +SELECT date '1999 08 Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 08 Jan'::date" +== 052 +-- truncate_limit: 100 +SELECT date '99-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-01-08'::date" +== 053 +-- truncate_limit: 100 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-08'::date" +== 054 +-- truncate_limit: 100 +SELECT date '08-01-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-01-99'::date" +== 055 +-- truncate_limit: 100 +SELECT date '08-01-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-01-1999'::date" +== 056 +-- truncate_limit: 100 +SELECT date '01-08-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01-08-99'::date" +== 057 +-- truncate_limit: 100 +SELECT date '01-08-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01-08-1999'::date" +== 058 +-- truncate_limit: 100 +SELECT date '99-08-01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-08-01'::date" +== 059 +-- truncate_limit: 100 +SELECT date '1999-08-01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-08-01'::date" +== 060 +-- truncate_limit: 100 +SELECT date '99 01 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 01 08'::date" +== 061 +-- truncate_limit: 100 +SELECT date '1999 01 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 01 08'::date" +== 062 +-- truncate_limit: 100 +SELECT date '08 01 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 01 99'::date" +== 063 +-- truncate_limit: 100 +SELECT date '08 01 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 01 1999'::date" +== 064 +-- truncate_limit: 100 +SELECT date '01 08 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01 08 99'::date" +== 065 +-- truncate_limit: 100 +SELECT date '01 08 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01 08 1999'::date" +== 066 +-- truncate_limit: 100 +SELECT date '99 08 01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 08 01'::date" +== 067 +-- truncate_limit: 100 +SELECT date '1999 08 01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 08 01'::date" +== 068 +-- truncate_limit: 100 +SET datestyle TO dmy +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO dmy" +== 069 +-- truncate_limit: 100 +SELECT date 'January 8, 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'January 8, 1999'::date" +== 070 +-- truncate_limit: 100 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-08'::date" +== 071 +-- truncate_limit: 100 +SELECT date '1999-01-18' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-18'::date" +== 072 +-- truncate_limit: 100 +SELECT date '1/8/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1/8/1999'::date" +== 073 +-- truncate_limit: 100 +SELECT date '1/18/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1/18/1999'::date" +== 074 +-- truncate_limit: 100 +SELECT date '18/1/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '18/1/1999'::date" +== 075 +-- truncate_limit: 100 +SELECT date '01/02/03' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01/02/03'::date" +== 076 +-- truncate_limit: 100 +SELECT date '19990108' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '19990108'::date" +== 077 +-- truncate_limit: 100 +SELECT date '990108' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '990108'::date" +== 078 +-- truncate_limit: 100 +SELECT date '1999.008' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999.008'::date" +== 079 +-- truncate_limit: 100 +SELECT date 'J2451187' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2451187'::date" +== 080 +-- truncate_limit: 100 +SELECT date 'January 8, 99 BC' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'January 8, 99 BC'::date" +== 081 +-- truncate_limit: 100 +SELECT date '99-Jan-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-Jan-08'::date" +== 082 +-- truncate_limit: 100 +SELECT date '1999-Jan-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-Jan-08'::date" +== 083 +-- truncate_limit: 100 +SELECT date '08-Jan-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-Jan-99'::date" +== 084 +-- truncate_limit: 100 +SELECT date '08-Jan-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-Jan-1999'::date" +== 085 +-- truncate_limit: 100 +SELECT date 'Jan-08-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan-08-99'::date" +== 086 +-- truncate_limit: 100 +SELECT date 'Jan-08-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan-08-1999'::date" +== 087 +-- truncate_limit: 100 +SELECT date '99-08-Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-08-Jan'::date" +== 088 +-- truncate_limit: 100 +SELECT date '1999-08-Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-08-Jan'::date" +== 089 +-- truncate_limit: 100 +SELECT date '99 Jan 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 Jan 08'::date" +== 090 +-- truncate_limit: 100 +SELECT date '1999 Jan 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 Jan 08'::date" +== 091 +-- truncate_limit: 100 +SELECT date '08 Jan 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 Jan 99'::date" +== 092 +-- truncate_limit: 100 +SELECT date '08 Jan 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 Jan 1999'::date" +== 093 +-- truncate_limit: 100 +SELECT date 'Jan 08 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 08 99'::date" +== 094 +-- truncate_limit: 100 +SELECT date 'Jan 08 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 08 1999'::date" +== 095 +-- truncate_limit: 100 +SELECT date '99 08 Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 08 Jan'::date" +== 096 +-- truncate_limit: 100 +SELECT date '1999 08 Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 08 Jan'::date" +== 097 +-- truncate_limit: 100 +SELECT date '99-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-01-08'::date" +== 098 +-- truncate_limit: 100 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-08'::date" +== 099 +-- truncate_limit: 100 +SELECT date '08-01-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-01-99'::date" +== 100 +-- truncate_limit: 100 +SELECT date '08-01-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-01-1999'::date" +== 101 +-- truncate_limit: 100 +SELECT date '01-08-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01-08-99'::date" +== 102 +-- truncate_limit: 100 +SELECT date '01-08-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01-08-1999'::date" +== 103 +-- truncate_limit: 100 +SELECT date '99-08-01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-08-01'::date" +== 104 +-- truncate_limit: 100 +SELECT date '1999-08-01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-08-01'::date" +== 105 +-- truncate_limit: 100 +SELECT date '99 01 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 01 08'::date" +== 106 +-- truncate_limit: 100 +SELECT date '1999 01 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 01 08'::date" +== 107 +-- truncate_limit: 100 +SELECT date '08 01 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 01 99'::date" +== 108 +-- truncate_limit: 100 +SELECT date '08 01 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 01 1999'::date" +== 109 +-- truncate_limit: 100 +SELECT date '01 08 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01 08 99'::date" +== 110 +-- truncate_limit: 100 +SELECT date '01 08 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01 08 1999'::date" +== 111 +-- truncate_limit: 100 +SELECT date '99 08 01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 08 01'::date" +== 112 +-- truncate_limit: 100 +SELECT date '1999 08 01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 08 01'::date" +== 113 +-- truncate_limit: 100 +SET datestyle TO mdy +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO mdy" +== 114 +-- truncate_limit: 100 +SELECT date 'January 8, 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'January 8, 1999'::date" +== 115 +-- truncate_limit: 100 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-08'::date" +== 116 +-- truncate_limit: 100 +SELECT date '1999-01-18' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-18'::date" +== 117 +-- truncate_limit: 100 +SELECT date '1/8/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1/8/1999'::date" +== 118 +-- truncate_limit: 100 +SELECT date '1/18/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1/18/1999'::date" +== 119 +-- truncate_limit: 100 +SELECT date '18/1/1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '18/1/1999'::date" +== 120 +-- truncate_limit: 100 +SELECT date '01/02/03' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01/02/03'::date" +== 121 +-- truncate_limit: 100 +SELECT date '19990108' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '19990108'::date" +== 122 +-- truncate_limit: 100 +SELECT date '990108' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '990108'::date" +== 123 +-- truncate_limit: 100 +SELECT date '1999.008' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999.008'::date" +== 124 +-- truncate_limit: 100 +SELECT date 'J2451187' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2451187'::date" +== 125 +-- truncate_limit: 100 +SELECT date 'January 8, 99 BC' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'January 8, 99 BC'::date" +== 126 +-- truncate_limit: 100 +SELECT date '99-Jan-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-Jan-08'::date" +== 127 +-- truncate_limit: 100 +SELECT date '1999-Jan-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-Jan-08'::date" +== 128 +-- truncate_limit: 100 +SELECT date '08-Jan-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-Jan-99'::date" +== 129 +-- truncate_limit: 100 +SELECT date '08-Jan-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-Jan-1999'::date" +== 130 +-- truncate_limit: 100 +SELECT date 'Jan-08-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan-08-99'::date" +== 131 +-- truncate_limit: 100 +SELECT date 'Jan-08-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan-08-1999'::date" +== 132 +-- truncate_limit: 100 +SELECT date '99-08-Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-08-Jan'::date" +== 133 +-- truncate_limit: 100 +SELECT date '1999-08-Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-08-Jan'::date" +== 134 +-- truncate_limit: 100 +SELECT date '99 Jan 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 Jan 08'::date" +== 135 +-- truncate_limit: 100 +SELECT date '1999 Jan 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 Jan 08'::date" +== 136 +-- truncate_limit: 100 +SELECT date '08 Jan 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 Jan 99'::date" +== 137 +-- truncate_limit: 100 +SELECT date '08 Jan 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 Jan 1999'::date" +== 138 +-- truncate_limit: 100 +SELECT date 'Jan 08 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 08 99'::date" +== 139 +-- truncate_limit: 100 +SELECT date 'Jan 08 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 08 1999'::date" +== 140 +-- truncate_limit: 100 +SELECT date '99 08 Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 08 Jan'::date" +== 141 +-- truncate_limit: 100 +SELECT date '1999 08 Jan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 08 Jan'::date" +== 142 +-- truncate_limit: 100 +SELECT date '99-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-01-08'::date" +== 143 +-- truncate_limit: 100 +SELECT date '1999-01-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-01-08'::date" +== 144 +-- truncate_limit: 100 +SELECT date '08-01-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-01-99'::date" +== 145 +-- truncate_limit: 100 +SELECT date '08-01-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-01-1999'::date" +== 146 +-- truncate_limit: 100 +SELECT date '01-08-99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01-08-99'::date" +== 147 +-- truncate_limit: 100 +SELECT date '01-08-1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01-08-1999'::date" +== 148 +-- truncate_limit: 100 +SELECT date '99-08-01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99-08-01'::date" +== 149 +-- truncate_limit: 100 +SELECT date '1999-08-01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-08-01'::date" +== 150 +-- truncate_limit: 100 +SELECT date '99 01 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 01 08'::date" +== 151 +-- truncate_limit: 100 +SELECT date '1999 01 08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 01 08'::date" +== 152 +-- truncate_limit: 100 +SELECT date '08 01 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 01 99'::date" +== 153 +-- truncate_limit: 100 +SELECT date '08 01 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08 01 1999'::date" +== 154 +-- truncate_limit: 100 +SELECT date '01 08 99' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01 08 99'::date" +== 155 +-- truncate_limit: 100 +SELECT date '01 08 1999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01 08 1999'::date" +== 156 +-- truncate_limit: 100 +SELECT date '99 08 01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '99 08 01'::date" +== 157 +-- truncate_limit: 100 +SELECT date '1999 08 01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999 08 01'::date" +== 158 +-- truncate_limit: 100 +-- Check upper and lower limits of date range +SELECT date '4714-11-24 BC' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-24 BC'::date" +== 159 +-- truncate_limit: 100 +SELECT date '4714-11-23 BC' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-23 BC'::date" +== 160 +-- truncate_limit: 100 +-- out of range +SELECT date '5874897-12-31' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5874897-12-31'::date" +== 161 +-- truncate_limit: 100 +SELECT date '5874898-01-01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5874898-01-01'::date" +== 162 +-- truncate_limit: 100 +-- out of range + +-- Test non-error-throwing API +SELECT pg_input_is_valid('now', 'date') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('now', 'date')" +== 163 +-- truncate_limit: 100 +SELECT pg_input_is_valid('garbage', 'date') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('garbage', 'date')" +== 164 +-- truncate_limit: 100 +SELECT pg_input_is_valid('6874898-01-01', 'date') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('6874898-01-01', 'date')" +== 165 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('garbage', 'date') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('garbage', 'date')" +== 166 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('6874898-01-01', 'date') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('6874898-01-01', 'date')" +== 167 +-- truncate_limit: 100 +RESET datestyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" +== 168 +-- truncate_limit: 100 +|-- +-- Simple math +-- Leave most of it for the horology tests +|-- + +SELECT f1 - date '2000-01-01' AS "Days From 2K" FROM DATE_TBL +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 - '2000-01-01'::date AS \"Days From 2K\" FROM date_tbl" +== 169 +-- truncate_limit: 100 +SELECT f1 - date 'epoch' AS "Days From Epoch" FROM DATE_TBL +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 - 'epoch'::date AS \"Days From Epoch\" FROM date_tbl" +== 170 +-- truncate_limit: 100 +SELECT date 'yesterday' - date 'today' AS "One day" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'yesterday'::date - 'today'::date AS \"One day\"" +== 171 +-- truncate_limit: 100 +SELECT date 'today' - date 'tomorrow' AS "One day" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'today'::date - 'tomorrow'::date AS \"One day\"" +== 172 +-- truncate_limit: 100 +SELECT date 'yesterday' - date 'tomorrow' AS "Two days" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'yesterday'::date - 'tomorrow'::date AS \"Two days\"" +== 173 +-- truncate_limit: 100 +SELECT date 'tomorrow' - date 'today' AS "One day" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'tomorrow'::date - 'today'::date AS \"One day\"" +== 174 +-- truncate_limit: 100 +SELECT date 'today' - date 'yesterday' AS "One day" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'today'::date - 'yesterday'::date AS \"One day\"" +== 175 +-- truncate_limit: 100 +SELECT date 'tomorrow' - date 'yesterday' AS "Two days" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'tomorrow'::date - 'yesterday'::date AS \"Two days\"" +== 176 +-- truncate_limit: 100 +|-- +-- test extract! +|-- +SELECT f1 as "date", + date_part('year', f1) AS year, + date_part('month', f1) AS month, + date_part('day', f1) AS day, + date_part('quarter', f1) AS quarter, + date_part('decade', f1) AS decade, + date_part('century', f1) AS century, + date_part('millennium', f1) AS millennium, + date_part('isoyear', f1) AS isoyear, + date_part('week', f1) AS week, + date_part('dow', f1) AS dow, + date_part('isodow', f1) AS isodow, + date_part('doy', f1) AS doy, + date_part('julian', f1) AS julian, + date_part('epoch', f1) AS epoch + FROM date_tbl +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM date_tbl" +== 177 +-- truncate_limit: 100 +|-- +-- epoch +|-- +SELECT EXTRACT(EPOCH FROM DATE '1970-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '1970-01-01'::date)" +== 178 +-- truncate_limit: 100 +-- 0 +|-- +-- century +|-- +SELECT EXTRACT(CENTURY FROM DATE '0101-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '0101-12-31 BC'::date)" +== 179 +-- truncate_limit: 100 +-- -2 +SELECT EXTRACT(CENTURY FROM DATE '0100-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '0100-12-31 BC'::date)" +== 180 +-- truncate_limit: 100 +-- -1 +SELECT EXTRACT(CENTURY FROM DATE '0001-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '0001-12-31 BC'::date)" +== 181 +-- truncate_limit: 100 +-- -1 +SELECT EXTRACT(CENTURY FROM DATE '0001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '0001-01-01'::date)" +== 182 +-- truncate_limit: 100 +-- 1 +SELECT EXTRACT(CENTURY FROM DATE '0001-01-01 AD') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '0001-01-01 AD'::date)" +== 183 +-- truncate_limit: 100 +-- 1 +SELECT EXTRACT(CENTURY FROM DATE '1900-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '1900-12-31'::date)" +== 184 +-- truncate_limit: 100 +-- 19 +SELECT EXTRACT(CENTURY FROM DATE '1901-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '1901-01-01'::date)" +== 185 +-- truncate_limit: 100 +-- 20 +SELECT EXTRACT(CENTURY FROM DATE '2000-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '2000-12-31'::date)" +== 186 +-- truncate_limit: 100 +-- 20 +SELECT EXTRACT(CENTURY FROM DATE '2001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '2001-01-01'::date)" +== 187 +-- truncate_limit: 100 +-- 21 +SELECT EXTRACT(CENTURY FROM CURRENT_DATE)>=21 AS True +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM current_date) >= 21 AS \"true\"" +== 188 +-- truncate_limit: 100 +-- true +|-- +-- millennium +|-- +SELECT EXTRACT(MILLENNIUM FROM DATE '0001-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM '0001-12-31 BC'::date)" +== 189 +-- truncate_limit: 100 +-- -1 +SELECT EXTRACT(MILLENNIUM FROM DATE '0001-01-01 AD') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM '0001-01-01 AD'::date)" +== 190 +-- truncate_limit: 100 +-- 1 +SELECT EXTRACT(MILLENNIUM FROM DATE '1000-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM '1000-12-31'::date)" +== 191 +-- truncate_limit: 100 +-- 1 +SELECT EXTRACT(MILLENNIUM FROM DATE '1001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM '1001-01-01'::date)" +== 192 +-- truncate_limit: 100 +-- 2 +SELECT EXTRACT(MILLENNIUM FROM DATE '2000-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM '2000-12-31'::date)" +== 193 +-- truncate_limit: 100 +-- 2 +SELECT EXTRACT(MILLENNIUM FROM DATE '2001-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM '2001-01-01'::date)" +== 194 +-- truncate_limit: 100 +-- 3 +-- next test to be fixed on the turn of the next millennium;-) +SELECT EXTRACT(MILLENNIUM FROM CURRENT_DATE) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM current_date)" +== 195 +-- truncate_limit: 100 +-- 3 +|-- +-- decade +|-- +SELECT EXTRACT(DECADE FROM DATE '1994-12-25') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '1994-12-25'::date)" +== 196 +-- truncate_limit: 100 +-- 199 +SELECT EXTRACT(DECADE FROM DATE '0010-01-01') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '0010-01-01'::date)" +== 197 +-- truncate_limit: 100 +-- 1 +SELECT EXTRACT(DECADE FROM DATE '0009-12-31') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '0009-12-31'::date)" +== 198 +-- truncate_limit: 100 +-- 0 +SELECT EXTRACT(DECADE FROM DATE '0001-01-01 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '0001-01-01 BC'::date)" +== 199 +-- truncate_limit: 100 +-- 0 +SELECT EXTRACT(DECADE FROM DATE '0002-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '0002-12-31 BC'::date)" +== 200 +-- truncate_limit: 100 +-- -1 +SELECT EXTRACT(DECADE FROM DATE '0011-01-01 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '0011-01-01 BC'::date)" +== 201 +-- truncate_limit: 100 +-- -1 +SELECT EXTRACT(DECADE FROM DATE '0012-12-31 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '0012-12-31 BC'::date)" +== 202 +-- truncate_limit: 100 +-- -2 +|-- +-- all possible fields +|-- +SELECT EXTRACT(MICROSECONDS FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('microseconds' FROM '2020-08-11'::date)" +== 203 +-- truncate_limit: 100 +SELECT EXTRACT(MILLISECONDS FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('milliseconds' FROM '2020-08-11'::date)" +== 204 +-- truncate_limit: 100 +SELECT EXTRACT(SECOND FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('second' FROM '2020-08-11'::date)" +== 205 +-- truncate_limit: 100 +SELECT EXTRACT(MINUTE FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('minute' FROM '2020-08-11'::date)" +== 206 +-- truncate_limit: 100 +SELECT EXTRACT(HOUR FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('hour' FROM '2020-08-11'::date)" +== 207 +-- truncate_limit: 100 +SELECT EXTRACT(DAY FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('day' FROM '2020-08-11'::date)" +== 208 +-- truncate_limit: 100 +SELECT EXTRACT(MONTH FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('month' FROM '2020-08-11'::date)" +== 209 +-- truncate_limit: 100 +SELECT EXTRACT(YEAR FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('year' FROM '2020-08-11'::date)" +== 210 +-- truncate_limit: 100 +SELECT EXTRACT(YEAR FROM DATE '2020-08-11 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('year' FROM '2020-08-11 BC'::date)" +== 211 +-- truncate_limit: 100 +SELECT EXTRACT(DECADE FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '2020-08-11'::date)" +== 212 +-- truncate_limit: 100 +SELECT EXTRACT(CENTURY FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '2020-08-11'::date)" +== 213 +-- truncate_limit: 100 +SELECT EXTRACT(MILLENNIUM FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM '2020-08-11'::date)" +== 214 +-- truncate_limit: 100 +SELECT EXTRACT(ISOYEAR FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('isoyear' FROM '2020-08-11'::date)" +== 215 +-- truncate_limit: 100 +SELECT EXTRACT(ISOYEAR FROM DATE '2020-08-11 BC') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('isoyear' FROM '2020-08-11 BC'::date)" +== 216 +-- truncate_limit: 100 +SELECT EXTRACT(QUARTER FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('quarter' FROM '2020-08-11'::date)" +== 217 +-- truncate_limit: 100 +SELECT EXTRACT(WEEK FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('week' FROM '2020-08-11'::date)" +== 218 +-- truncate_limit: 100 +SELECT EXTRACT(DOW FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('dow' FROM '2020-08-11'::date)" +== 219 +-- truncate_limit: 100 +SELECT EXTRACT(DOW FROM DATE '2020-08-16') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('dow' FROM '2020-08-16'::date)" +== 220 +-- truncate_limit: 100 +SELECT EXTRACT(ISODOW FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('isodow' FROM '2020-08-11'::date)" +== 221 +-- truncate_limit: 100 +SELECT EXTRACT(ISODOW FROM DATE '2020-08-16') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('isodow' FROM '2020-08-16'::date)" +== 222 +-- truncate_limit: 100 +SELECT EXTRACT(DOY FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('doy' FROM '2020-08-11'::date)" +== 223 +-- truncate_limit: 100 +SELECT EXTRACT(TIMEZONE FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone' FROM '2020-08-11'::date)" +== 224 +-- truncate_limit: 100 +SELECT EXTRACT(TIMEZONE_M FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone_m' FROM '2020-08-11'::date)" +== 225 +-- truncate_limit: 100 +SELECT EXTRACT(TIMEZONE_H FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone_h' FROM '2020-08-11'::date)" +== 226 +-- truncate_limit: 100 +SELECT EXTRACT(EPOCH FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '2020-08-11'::date)" +== 227 +-- truncate_limit: 100 +SELECT EXTRACT(JULIAN FROM DATE '2020-08-11') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('julian' FROM '2020-08-11'::date)" +== 228 +-- truncate_limit: 100 +|-- +-- test trunc function! +|-- +SELECT DATE_TRUNC('MILLENNIUM', TIMESTAMP '1970-03-20 04:30:00.00000') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('MILLENNIUM', '1970-03-20 04:30:00.00000'::timestamp)" +== 229 +-- truncate_limit: 100 +-- 1001 +SELECT DATE_TRUNC('MILLENNIUM', DATE '1970-03-20') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('MILLENNIUM', '1970-03-20'::date)" +== 230 +-- truncate_limit: 100 +-- 1001-01-01 +SELECT DATE_TRUNC('CENTURY', TIMESTAMP '1970-03-20 04:30:00.00000') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('CENTURY', '1970-03-20 04:30:00.00000'::timestamp)" +== 231 +-- truncate_limit: 100 +-- 1901 +SELECT DATE_TRUNC('CENTURY', DATE '1970-03-20') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('CENTURY', '1970-03-20'::date)" +== 232 +-- truncate_limit: 100 +-- 1901 +SELECT DATE_TRUNC('CENTURY', DATE '2004-08-10') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('CENTURY', '2004-08-10'::date)" +== 233 +-- truncate_limit: 100 +-- 2001-01-01 +SELECT DATE_TRUNC('CENTURY', DATE '0002-02-04') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('CENTURY', '0002-02-04'::date)" +== 234 +-- truncate_limit: 100 +-- 0001-01-01 +SELECT DATE_TRUNC('CENTURY', DATE '0055-08-10 BC') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('CENTURY', '0055-08-10 BC'::date)" +== 235 +-- truncate_limit: 100 +-- 0100-01-01 BC +SELECT DATE_TRUNC('DECADE', DATE '1993-12-25') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('DECADE', '1993-12-25'::date)" +== 236 +-- truncate_limit: 100 +-- 1990-01-01 +SELECT DATE_TRUNC('DECADE', DATE '0004-12-25') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('DECADE', '0004-12-25'::date)" +== 237 +-- truncate_limit: 100 +-- 0001-01-01 BC +SELECT DATE_TRUNC('DECADE', DATE '0002-12-31 BC') +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('DECADE', '0002-12-31 BC'::date)" +== 238 +-- truncate_limit: 100 +-- 0011-01-01 BC +|-- +-- test infinity +|-- +select 'infinity'::date, '-infinity'::date +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::date, '-infinity'::date" +== 239 +-- truncate_limit: 100 +select 'infinity'::date > 'today'::date as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::date > 'today'::date AS t" +== 240 +-- truncate_limit: 100 +select '-infinity'::date < 'today'::date as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::date < 'today'::date AS t" +== 241 +-- truncate_limit: 100 +select isfinite('infinity'::date), isfinite('-infinity'::date), isfinite('today'::date) +-- +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT isfinite('infinity'::date), isfinite('-infinity'::date), isfinite('today'::date)" +== 242 +-- truncate_limit: 100 +select 'infinity'::date = '+infinity'::date as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::date = '+infinity'::date AS t" +== 243 +-- truncate_limit: 100 +|-- +-- oscillating fields from non-finite date: +|-- +SELECT EXTRACT(DAY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('day' FROM 'infinity'::date)" +== 244 +-- truncate_limit: 100 +-- NULL +SELECT EXTRACT(DAY FROM DATE '-infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('day' FROM '-infinity'::date)" +== 245 +-- truncate_limit: 100 +-- NULL +-- all supported fields +SELECT EXTRACT(DAY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('day' FROM 'infinity'::date)" +== 246 +-- truncate_limit: 100 +-- NULL +SELECT EXTRACT(MONTH FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('month' FROM 'infinity'::date)" +== 247 +-- truncate_limit: 100 +-- NULL +SELECT EXTRACT(QUARTER FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('quarter' FROM 'infinity'::date)" +== 248 +-- truncate_limit: 100 +-- NULL +SELECT EXTRACT(WEEK FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('week' FROM 'infinity'::date)" +== 249 +-- truncate_limit: 100 +-- NULL +SELECT EXTRACT(DOW FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('dow' FROM 'infinity'::date)" +== 250 +-- truncate_limit: 100 +-- NULL +SELECT EXTRACT(ISODOW FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('isodow' FROM 'infinity'::date)" +== 251 +-- truncate_limit: 100 +-- NULL +SELECT EXTRACT(DOY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('doy' FROM 'infinity'::date)" +== 252 +-- truncate_limit: 100 +-- NULL +|-- +-- monotonic fields from non-finite date: +|-- +SELECT EXTRACT(EPOCH FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM 'infinity'::date)" +== 253 +-- truncate_limit: 100 +-- Infinity +SELECT EXTRACT(EPOCH FROM DATE '-infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '-infinity'::date)" +== 254 +-- truncate_limit: 100 +-- -Infinity +-- all supported fields +SELECT EXTRACT(YEAR FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('year' FROM 'infinity'::date)" +== 255 +-- truncate_limit: 100 +-- Infinity +SELECT EXTRACT(DECADE FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM 'infinity'::date)" +== 256 +-- truncate_limit: 100 +-- Infinity +SELECT EXTRACT(CENTURY FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM 'infinity'::date)" +== 257 +-- truncate_limit: 100 +-- Infinity +SELECT EXTRACT(MILLENNIUM FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millennium' FROM 'infinity'::date)" +== 258 +-- truncate_limit: 100 +-- Infinity +SELECT EXTRACT(JULIAN FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('julian' FROM 'infinity'::date)" +== 259 +-- truncate_limit: 100 +-- Infinity +SELECT EXTRACT(ISOYEAR FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('isoyear' FROM 'infinity'::date)" +== 260 +-- truncate_limit: 100 +-- Infinity +SELECT EXTRACT(EPOCH FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM 'infinity'::date)" +== 261 +-- truncate_limit: 100 +-- Infinity +|-- +-- wrong fields from non-finite date: +|-- +SELECT EXTRACT(MICROSEC FROM DATE 'infinity') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('microsec' FROM 'infinity'::date)" +== 262 +-- truncate_limit: 100 +-- error + +-- test constructors +select make_date(2013, 7, 15) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_date(2013, 7, 15)" +== 263 +-- truncate_limit: 100 +select make_date(-44, 3, 15) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_date(-44, 3, 15)" +== 264 +-- truncate_limit: 100 +select make_time(8, 20, 0.0) +-- +FUNCTION: name="make_time" function="make_time" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_time(8, 20, 0.0)" +== 265 +-- truncate_limit: 100 +-- should fail +select make_date(0, 7, 15) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_date(0, 7, 15)" +== 266 +-- truncate_limit: 100 +select make_date(2013, 2, 30) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_date(2013, 2, 30)" +== 267 +-- truncate_limit: 100 +select make_date(2013, 13, 1) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_date(2013, 13, 1)" +== 268 +-- truncate_limit: 100 +select make_date(2013, 11, -1) +-- +FUNCTION: name="make_date" function="make_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_date(2013, 11, -1)" +== 269 +-- truncate_limit: 100 +select make_time(10, 55, 100.1) +-- +FUNCTION: name="make_time" function="make_time" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_time(10, 55, 100.1)" +== 270 +-- truncate_limit: 100 +select make_time(24, 0, 2.1) +-- +FUNCTION: name="make_time" function="make_time" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_time(24, 0, 2.1)" diff --git a/parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json b/parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json new file mode 100644 index 0000000..253273e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json @@ -0,0 +1,29 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/dbsize.test b/parser/testdata/summary_truncate/postgres_regress/dbsize.test new file mode 100644 index 0000000..c0e201d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/dbsize.test @@ -0,0 +1,217 @@ +== 001 +-- truncate_limit: 100 +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10::bigint), (1000::bigint), (1000000::bigint), + (1000000000::bigint), (1000000000000::bigint), + (1000000000000000::bigint)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM (VALUES (...)) x(size)" +== 002 +-- truncate_limit: 100 +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10::numeric), (1000::numeric), (1000000::numeric), + (1000000000::numeric), (1000000000000::numeric), + (1000000000000000::numeric), + (10.5::numeric), (1000.5::numeric), (1000000.5::numeric), + (1000000000.5::numeric), (1000000000000.5::numeric), + (1000000000000000.5::numeric)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM (VALUES (...)) x(size)" +== 003 +-- truncate_limit: 100 +-- test where units change up +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::bigint), (10240::bigint), + (10485247::bigint), (10485248::bigint), + (10736893951::bigint), (10736893952::bigint), + (10994579406847::bigint), (10994579406848::bigint), + (11258449312612351::bigint), (11258449312612352::bigint)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM (VALUES (...)) x(size)" +== 004 +-- truncate_limit: 100 +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::numeric), (10240::numeric), + (10485247::numeric), (10485248::numeric), + (10736893951::numeric), (10736893952::numeric), + (10994579406847::numeric), (10994579406848::numeric), + (11258449312612351::numeric), (11258449312612352::numeric), + (11528652096115048447::numeric), (11528652096115048448::numeric)) x(size) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM (VALUES (...)) x(size)" +== 005 +-- truncate_limit: 100 +-- Ensure we get the expected results when passing the extremities of bigint +SELECT pg_size_pretty('-9223372036854775808'::bigint), + pg_size_pretty('9223372036854775807'::bigint) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_pretty('-9223372036854775808'::bigint), pg_size_pretty('9223372036854775807'::bigint)" +== 006 +-- truncate_limit: 100 +-- pg_size_bytes() tests +SELECT size, pg_size_bytes(size) FROM + (VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '), + ('1TB'), ('3000 TB'), ('1e6 MB'), ('99 PB')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_bytes(size) FROM (VALUES (...)) x(size)" +== 007 +-- truncate_limit: 100 +-- case-insensitive units are supported +SELECT size, pg_size_bytes(size) FROM + (VALUES ('1'), ('123bYteS'), ('1kb'), ('1mb'), (' 1 Gb'), ('1.5 gB '), + ('1tb'), ('3000 tb'), ('1e6 mb'), ('99 pb')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_bytes(size) FROM (VALUES (...)) x(size)" +== 008 +-- truncate_limit: 100 +-- negative numbers are supported +SELECT size, pg_size_bytes(size) FROM + (VALUES ('-1'), ('-123bytes'), ('-1kb'), ('-1mb'), (' -1 Gb'), ('-1.5 gB '), + ('-1tb'), ('-3000 TB'), ('-10e-1 MB'), ('-99 PB')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_bytes(size) FROM (VALUES (...)) x(size)" +== 009 +-- truncate_limit: 100 +-- different cases with allowed points +SELECT size, pg_size_bytes(size) FROM + (VALUES ('-1.'), ('-1.kb'), ('-1. kb'), ('-0. gb'), + ('-.1'), ('-.1kb'), ('-.1 kb'), ('-.0 gb')) x(size) +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size, pg_size_bytes(size) FROM (VALUES (...)) x(size)" +== 010 +-- truncate_limit: 100 +-- invalid inputs +SELECT pg_size_bytes('1 AB') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('1 AB')" +== 011 +-- truncate_limit: 100 +SELECT pg_size_bytes('1 AB A') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('1 AB A')" +== 012 +-- truncate_limit: 100 +SELECT pg_size_bytes('1 AB A ') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('1 AB A ')" +== 013 +-- truncate_limit: 100 +SELECT pg_size_bytes('9223372036854775807.9') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('9223372036854775807.9')" +== 014 +-- truncate_limit: 100 +SELECT pg_size_bytes('1e100') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('1e100')" +== 015 +-- truncate_limit: 100 +SELECT pg_size_bytes('1e1000000000000000000') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('1e1000000000000000000')" +== 016 +-- truncate_limit: 100 +SELECT pg_size_bytes('1 byte') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('1 byte')" +== 017 +-- truncate_limit: 100 +-- the singular "byte" is not supported +SELECT pg_size_bytes('') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('')" +== 018 +-- truncate_limit: 100 +SELECT pg_size_bytes('kb') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('kb')" +== 019 +-- truncate_limit: 100 +SELECT pg_size_bytes('..') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('..')" +== 020 +-- truncate_limit: 100 +SELECT pg_size_bytes('-.') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('-.')" +== 021 +-- truncate_limit: 100 +SELECT pg_size_bytes('-.kb') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('-.kb')" +== 022 +-- truncate_limit: 100 +SELECT pg_size_bytes('-. kb') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('-. kb')" +== 023 +-- truncate_limit: 100 +SELECT pg_size_bytes('.+912') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('.+912')" +== 024 +-- truncate_limit: 100 +SELECT pg_size_bytes('+912+ kB') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('+912+ kB')" +== 025 +-- truncate_limit: 100 +SELECT pg_size_bytes('++123 kB') +-- +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_bytes('++123 kB')" diff --git a/parser/testdata/summary_truncate/postgres_regress/delete.metadata.json b/parser/testdata/summary_truncate/postgres_regress/delete.metadata.json new file mode 100644 index 0000000..92b8f9e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/delete.metadata.json @@ -0,0 +1,14 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/delete.test b/parser/testdata/summary_truncate/postgres_regress/delete.test new file mode 100644 index 0000000..bad2e31 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/delete.test @@ -0,0 +1,86 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE delete_test ( + id SERIAL PRIMARY KEY, + a INT, + b text +) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE delete_test (id serial PRIMARY KEY, a int, b text)" +== 002 +-- truncate_limit: 100 +INSERT INTO delete_test (a) VALUES (10) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO delete_test (a) VALUES (10)" +== 003 +-- truncate_limit: 100 +INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000))" +== 004 +-- truncate_limit: 100 +INSERT INTO delete_test (a) VALUES (100) +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO delete_test (a) VALUES (100)" +== 005 +-- truncate_limit: 100 +-- allow an alias to be specified for DELETE's target table +DELETE FROM delete_test AS dt WHERE dt.a > 75 +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +ALIAS: "dt"="delete_test" +STMT: DeleteStmt +TRUNCATED: "DELETE FROM delete_test dt WHERE dt.a > 75" +== 006 +-- truncate_limit: 100 +-- if an alias is specified, don't allow the original table name +-- to be referenced +DELETE FROM delete_test dt WHERE delete_test.a > 25 +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +ALIAS: "dt"="delete_test" +STMT: DeleteStmt +TRUNCATED: "DELETE FROM delete_test dt WHERE delete_test.a > 25" +== 007 +-- truncate_limit: 100 +SELECT id, a, char_length(b) FROM delete_test +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT id, a, char_length(b) FROM delete_test" +== 008 +-- truncate_limit: 100 +-- delete a row with a TOASTed value +DELETE FROM delete_test WHERE a > 25 +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM delete_test WHERE a > 25" +== 009 +-- truncate_limit: 100 +SELECT id, a, char_length(b) FROM delete_test +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT id, a, char_length(b) FROM delete_test" +== 010 +-- truncate_limit: 100 +DROP TABLE delete_test +-- +TABLE: name="delete_test" schema="" table="delete_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE delete_test" diff --git a/parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json b/parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/dependency.test b/parser/testdata/summary_truncate/postgres_regress/dependency.test new file mode 100644 index 0000000..e048fed --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/dependency.test @@ -0,0 +1,426 @@ +== 001 +-- truncate_limit: 100 +|-- +-- DEPENDENCIES +|-- + +CREATE USER regress_dep_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_dep_user" +== 002 +-- truncate_limit: 100 +CREATE USER regress_dep_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_dep_user2" +== 003 +-- truncate_limit: 100 +CREATE USER regress_dep_user3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_dep_user3" +== 004 +-- truncate_limit: 100 +CREATE GROUP regress_dep_group +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE GROUP regress_dep_group" +== 005 +-- truncate_limit: 100 +CREATE TABLE deptest (f1 serial primary key, f2 text) +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE deptest (f1 serial PRIMARY KEY, f2 text)" +== 006 +-- truncate_limit: 100 +GRANT SELECT ON TABLE deptest TO GROUP regress_dep_group +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON deptest TO regress_dep_group" +== 007 +-- truncate_limit: 100 +GRANT ALL ON TABLE deptest TO regress_dep_user, regress_dep_user2 +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON deptest TO regress_dep_user, regress_dep_user2" +== 008 +-- truncate_limit: 100 +-- can't drop neither because they have privileges somewhere +DROP USER regress_dep_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user" +== 009 +-- truncate_limit: 100 +DROP GROUP regress_dep_group +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_group" +== 010 +-- truncate_limit: 100 +-- if we revoke the privileges we can drop the group +REVOKE SELECT ON deptest FROM GROUP regress_dep_group +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select ON deptest FROM regress_dep_group" +== 011 +-- truncate_limit: 100 +DROP GROUP regress_dep_group +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_group" +== 012 +-- truncate_limit: 100 +-- can't drop the user if we revoke the privileges partially +REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, MAINTAIN ON deptest FROM regress_dep_user +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select, insert, update, delete, truncate, references, maintain ON deptest FROM regress_dep..." +== 013 +-- truncate_limit: 100 +DROP USER regress_dep_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user" +== 014 +-- truncate_limit: 100 +-- now we are OK to drop him +REVOKE TRIGGER ON deptest FROM regress_dep_user +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE trigger ON deptest FROM regress_dep_user" +== 015 +-- truncate_limit: 100 +DROP USER regress_dep_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user" +== 016 +-- truncate_limit: 100 +-- we are OK too if we drop the privileges all at once +REVOKE ALL ON deptest FROM regress_dep_user2 +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON deptest FROM regress_dep_user2" +== 017 +-- truncate_limit: 100 +DROP USER regress_dep_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user2" +== 018 +-- truncate_limit: 100 +-- can't drop the owner of an object +-- the error message detail here would include a pg_toast_nnn name that +-- is not constant, so suppress it +ALTER TABLE deptest OWNER TO regress_dep_user3 +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE deptest OWNER TO regress_dep_user3" +== 019 +-- truncate_limit: 100 +DROP USER regress_dep_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user3" +== 020 +-- truncate_limit: 100 +-- if we drop the object, we can drop the user too +DROP TABLE deptest +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE deptest" +== 021 +-- truncate_limit: 100 +DROP USER regress_dep_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user3" +== 022 +-- truncate_limit: 100 +-- Test DROP OWNED +CREATE USER regress_dep_user0 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_dep_user0" +== 023 +-- truncate_limit: 100 +CREATE USER regress_dep_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_dep_user1" +== 024 +-- truncate_limit: 100 +CREATE USER regress_dep_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_dep_user2" +== 025 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_dep_user0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_dep_user0" +== 026 +-- truncate_limit: 100 +-- permission denied +DROP OWNED BY regress_dep_user1 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_dep_user1" +== 027 +-- truncate_limit: 100 +DROP OWNED BY regress_dep_user0, regress_dep_user2 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_dep_user0, regress_dep_user2" +== 028 +-- truncate_limit: 100 +REASSIGN OWNED BY regress_dep_user0 TO regress_dep_user1 +-- +STMT: ReassignOwnedStmt +TRUNCATED: "REASSIGN OWNED BY regress_dep_user0 TO regress_dep_user1" +== 029 +-- truncate_limit: 100 +REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user0 +-- +STMT: ReassignOwnedStmt +TRUNCATED: "REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user0" +== 030 +-- truncate_limit: 100 +-- this one is allowed +DROP OWNED BY regress_dep_user0 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_dep_user0" +== 031 +-- truncate_limit: 100 +CREATE TABLE deptest1 (f1 int unique) +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE deptest1 (f1 int UNIQUE)" +== 032 +-- truncate_limit: 100 +GRANT ALL ON deptest1 TO regress_dep_user1 WITH GRANT OPTION +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON deptest1 TO regress_dep_user1 WITH GRANT OPTION" +== 033 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_dep_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_dep_user1" +== 034 +-- truncate_limit: 100 +CREATE TABLE deptest (a serial primary key, b text) +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE deptest (a serial PRIMARY KEY, b text)" +== 035 +-- truncate_limit: 100 +GRANT ALL ON deptest1 TO regress_dep_user2 +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON deptest1 TO regress_dep_user2" +== 036 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 037 +-- truncate_limit: 100 +DROP OWNED BY regress_dep_user1 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_dep_user1" +== 038 +-- truncate_limit: 100 +-- all grants revoked +-- table was dropped + +-- Test REASSIGN OWNED +GRANT ALL ON deptest1 TO regress_dep_user1 +-- +TABLE: name="deptest1" schema="" table="deptest1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON deptest1 TO regress_dep_user1" +== 039 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE regression TO regress_dep_user1 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_dep_user1" +== 040 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_dep_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_dep_user1" +== 041 +-- truncate_limit: 100 +CREATE SCHEMA deptest +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA deptest" +== 042 +-- truncate_limit: 100 +CREATE TABLE deptest (a serial primary key, b text) +-- +TABLE: name="deptest" schema="" table="deptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE deptest (a serial PRIMARY KEY, b text)" +== 043 +-- truncate_limit: 100 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_dep_user1 IN SCHEMA deptest + GRANT ALL ON TABLES TO regress_dep_user2 +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_dep_user1 IN SCHEMA deptest GRANT ALL ON TABLES TO regr..." +== 044 +-- truncate_limit: 100 +CREATE FUNCTION deptest_func() RETURNS void LANGUAGE plpgsql + AS $$ BEGIN END; $$ +-- +FUNCTION: name="deptest_func" function="deptest_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION deptest_func() RETURNS void LANGUAGE plpgsql AS $$ BEGIN END; $$" +== 045 +-- truncate_limit: 100 +CREATE TYPE deptest_enum AS ENUM ('red') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE deptest_enum AS ENUM ('red')" +== 046 +-- truncate_limit: 100 +CREATE TYPE deptest_range AS RANGE (SUBTYPE = int4) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE deptest_range AS RANGE (subtype = int4)" +== 047 +-- truncate_limit: 100 +CREATE TABLE deptest2 (f1 int) +-- +TABLE: name="deptest2" schema="" table="deptest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE deptest2 (f1 int)" +== 048 +-- truncate_limit: 100 +-- make a serial column the hard way +CREATE SEQUENCE ss1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE ss1" +== 049 +-- truncate_limit: 100 +ALTER TABLE deptest2 ALTER f1 SET DEFAULT nextval('ss1') +-- +TABLE: name="deptest2" schema="" table="deptest2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE deptest2 ALTER COLUMN f1 SET DEFAULT nextval('ss1')" +== 050 +-- truncate_limit: 100 +ALTER SEQUENCE ss1 OWNED BY deptest2.f1 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE ss1 OWNED BY deptest2.f1" +== 051 +-- truncate_limit: 100 +-- When reassigning ownership of a composite type, its pg_class entry +-- should match +CREATE TYPE deptest_t AS (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE deptest_t AS (a int)" +== 052 +-- truncate_limit: 100 +SELECT typowner = relowner +FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT typowner = relowner FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE ..." +== 053 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 054 +-- truncate_limit: 100 +REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user2 +-- +STMT: ReassignOwnedStmt +TRUNCATED: "REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user2" +== 055 +-- truncate_limit: 100 +SELECT typowner = relowner +FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT typowner = relowner FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE ..." +== 056 +-- truncate_limit: 100 +-- doesn't work: grant still exists +DROP USER regress_dep_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user1" +== 057 +-- truncate_limit: 100 +DROP OWNED BY regress_dep_user1 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_dep_user1" +== 058 +-- truncate_limit: 100 +DROP USER regress_dep_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user1" +== 059 +-- truncate_limit: 100 +DROP USER regress_dep_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user2" +== 060 +-- truncate_limit: 100 +DROP OWNED BY regress_dep_user2, regress_dep_user0 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_dep_user2, regress_dep_user0" +== 061 +-- truncate_limit: 100 +DROP USER regress_dep_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user2" +== 062 +-- truncate_limit: 100 +DROP USER regress_dep_user0 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_dep_user0" diff --git a/parser/testdata/summary_truncate/postgres_regress/domain.metadata.json b/parser/testdata/summary_truncate/postgres_regress/domain.metadata.json new file mode 100644 index 0000000..60d70f4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/domain.metadata.json @@ -0,0 +1,323 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/domain.test b/parser/testdata/summary_truncate/postgres_regress/domain.test new file mode 100644 index 0000000..020578d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/domain.test @@ -0,0 +1,2424 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test domains. +|-- + +-- Test Comment / Drop +create domain domaindroptest int4 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domaindroptest AS int4" +== 002 +-- truncate_limit: 100 +comment on domain domaindroptest is 'About to drop this..' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON DOMAIN domaindroptest IS 'About to drop this..'" +== 003 +-- truncate_limit: 100 +create domain dependenttypetest domaindroptest +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN dependenttypetest AS domaindroptest" +== 004 +-- truncate_limit: 100 +-- fail because of dependent type +drop domain domaindroptest +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domaindroptest" +== 005 +-- truncate_limit: 100 +drop domain domaindroptest cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domaindroptest CASCADE" +== 006 +-- truncate_limit: 100 +-- this should fail because already gone +drop domain domaindroptest cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domaindroptest CASCADE" +== 007 +-- truncate_limit: 100 +-- Test domain input. + +-- Note: the point of checking both INSERT and COPY FROM is that INSERT +-- exercises CoerceToDomain while COPY exercises domain_in. + +create domain domainvarchar varchar(5) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domainvarchar AS varchar(5)" +== 008 +-- truncate_limit: 100 +create domain domainnumeric numeric(8,2) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domainnumeric AS numeric(8, 2)" +== 009 +-- truncate_limit: 100 +create domain domainint4 int4 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domainint4 AS int4" +== 010 +-- truncate_limit: 100 +create domain domaintext text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domaintext AS text" +== 011 +-- truncate_limit: 100 +-- Test explicit coercions --- these should succeed (and truncate) +SELECT cast('123456' as domainvarchar) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123456'::domainvarchar" +== 012 +-- truncate_limit: 100 +SELECT cast('12345' as domainvarchar) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345'::domainvarchar" +== 013 +-- truncate_limit: 100 +-- Test tables using domains +create table basictest + ( testint4 domainint4 + , testtext domaintext + , testvarchar domainvarchar + , testnumeric domainnumeric + ) +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE basictest (testint4 domainint4, testtext domaintext, testvarchar domainvarchar, test..." +== 014 +-- truncate_limit: 100 +INSERT INTO basictest values ('88', 'haha', 'short', '123.12') +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO basictest VALUES ('88', 'haha', 'short', '123.12')" +== 015 +-- truncate_limit: 100 +-- Good +INSERT INTO basictest values ('88', 'haha', 'short text', '123.12') +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO basictest VALUES ('88', 'haha', 'short text', '123.12')" +== 016 +-- truncate_limit: 100 +-- Bad varchar +INSERT INTO basictest values ('88', 'haha', 'short', '123.1212') +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO basictest VALUES ('88', 'haha', 'short', '123.1212')" +== 017 +-- truncate_limit: 100 +-- Truncate numeric + +-- Test copy +COPY basictest (testvarchar) FROM stdin +-- +TABLE: name="basictest" schema="" table="basictest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY basictest(testvarchar) FROM STDIN" +== 018 +-- truncate_limit: 100 +-- fail +notsoshorttext + +COPY basictest (testvarchar) FROM stdin +-- +ERROR: syntax error at or near "notsoshorttext" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 019 +-- truncate_limit: 100 +select * from basictest +-- +TABLE: name="basictest" schema="" table="basictest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM basictest" +== 020 +-- truncate_limit: 100 +-- check that domains inherit operations from base types +select testtext || testvarchar as concat, testnumeric + 42 as sum +from basictest +-- +TABLE: name="basictest" schema="" table="basictest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT testtext || testvarchar AS concat, testnumeric + 42 AS sum FROM basictest" +== 021 +-- truncate_limit: 100 +-- check that union/case/coalesce type resolution handles domains properly +select pg_typeof(coalesce(4::domainint4, 7)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(COALESCE(4::domainint4, 7))" +== 022 +-- truncate_limit: 100 +select pg_typeof(coalesce(4::domainint4, 7::domainint4)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(COALESCE(4::domainint4, 7::domainint4))" +== 023 +-- truncate_limit: 100 +drop table basictest +-- +TABLE: name="basictest" schema="" table="basictest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE basictest" +== 024 +-- truncate_limit: 100 +drop domain domainvarchar restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domainvarchar" +== 025 +-- truncate_limit: 100 +drop domain domainnumeric restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domainnumeric" +== 026 +-- truncate_limit: 100 +drop domain domainint4 restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domainint4" +== 027 +-- truncate_limit: 100 +drop domain domaintext +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domaintext" +== 028 +-- truncate_limit: 100 +-- Test non-error-throwing input + +create domain positiveint int4 check(value > 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN positiveint AS int4 CHECK (value > 0)" +== 029 +-- truncate_limit: 100 +create domain weirdfloat float8 check((1 / value) < 10) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN weirdfloat AS float8 CHECK ((1 / value) < 10)" +== 030 +-- truncate_limit: 100 +select pg_input_is_valid('1', 'positiveint') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1', 'positiveint')" +== 031 +-- truncate_limit: 100 +select pg_input_is_valid('junk', 'positiveint') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('junk', 'positiveint')" +== 032 +-- truncate_limit: 100 +select pg_input_is_valid('-1', 'positiveint') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('-1', 'positiveint')" +== 033 +-- truncate_limit: 100 +select * from pg_input_error_info('junk', 'positiveint') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('junk', 'positiveint')" +== 034 +-- truncate_limit: 100 +select * from pg_input_error_info('-1', 'positiveint') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('-1', 'positiveint')" +== 035 +-- truncate_limit: 100 +select * from pg_input_error_info('junk', 'weirdfloat') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('junk', 'weirdfloat')" +== 036 +-- truncate_limit: 100 +select * from pg_input_error_info('0.01', 'weirdfloat') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('0.01', 'weirdfloat')" +== 037 +-- truncate_limit: 100 +-- We currently can't trap errors raised in the CHECK expression itself +select * from pg_input_error_info('0', 'weirdfloat') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('0', 'weirdfloat')" +== 038 +-- truncate_limit: 100 +drop domain positiveint +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN positiveint" +== 039 +-- truncate_limit: 100 +drop domain weirdfloat +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN weirdfloat" +== 040 +-- truncate_limit: 100 +-- Test domains over array types + +create domain domainint4arr int4[1] +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domainint4arr AS int4[1]" +== 041 +-- truncate_limit: 100 +create domain domainchar4arr varchar(4)[2][3] +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domainchar4arr AS varchar(4)[2][3]" +== 042 +-- truncate_limit: 100 +create table domarrtest + ( testint4arr domainint4arr + , testchar4arr domainchar4arr + ) +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE domarrtest (testint4arr domainint4arr, testchar4arr domainchar4arr)" +== 043 +-- truncate_limit: 100 +INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domarrtest VALUES ('{2,2}', '{{\"a\",\"b\"},{\"c\",\"d\"}}')" +== 044 +-- truncate_limit: 100 +INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domarrtest VALUES ('{{2,2},{2,2}}', '{{\"a\",\"b\"}}')" +== 045 +-- truncate_limit: 100 +INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domarrtest VALUES ('{2,2}', '{{\"a\",\"b\"},{\"c\",\"d\"},{\"e\",\"f\"}}')" +== 046 +-- truncate_limit: 100 +INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domarrtest VALUES ('{2,2}', '{{\"a\"},{\"c\"}}')" +== 047 +-- truncate_limit: 100 +INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domarrtest VALUES (NULL, '{{\"a\",\"b\",\"c\"},{\"d\",\"e\",\"f\"}}')" +== 048 +-- truncate_limit: 100 +INSERT INTO domarrtest values (NULL, '{{"toolong","b","c"},{"d","e","f"}}') +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domarrtest VALUES (NULL, '{{\"toolong\",\"b\",\"c\"},{\"d\",\"e\",\"f\"}}')" +== 049 +-- truncate_limit: 100 +INSERT INTO domarrtest (testint4arr[1], testint4arr[3]) values (11,22) +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domarrtest (testint4arr[1], testint4arr[3]) VALUES (11, 22)" +== 050 +-- truncate_limit: 100 +select * from domarrtest +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domarrtest" +== 051 +-- truncate_limit: 100 +select testint4arr[1], testchar4arr[2:2] from domarrtest +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT testint4arr[1], testchar4arr[2:2] FROM domarrtest" +== 052 +-- truncate_limit: 100 +select array_dims(testint4arr), array_dims(testchar4arr) from domarrtest +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_dims(testint4arr), array_dims(testchar4arr) FROM domarrtest" +== 053 +-- truncate_limit: 100 +COPY domarrtest FROM stdin +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY domarrtest FROM STDIN" +== 054 +-- truncate_limit: 100 +COPY domarrtest FROM stdin +-- +TABLE: name="domarrtest" schema="" table="domarrtest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY domarrtest FROM STDIN" +== 055 +-- truncate_limit: 100 +-- fail +{3,4} {qwerty,w,e} + +select * from domarrtest +-- +ERROR: syntax error at or near "{" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 056 +-- truncate_limit: 100 +COPY nulltest FROM stdin +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY nulltest FROM STDIN" +== 057 +-- truncate_limit: 100 +--fail +a b c d \N + +-- Last row is bad +COPY nulltest FROM stdin +-- +ERROR: syntax error at or near "a" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 058 +-- truncate_limit: 100 +select * from nulltest +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nulltest" +== 059 +-- truncate_limit: 100 +-- Test out coerced (casted) constraints +SELECT cast('1' as dnotnull) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::dnotnull" +== 060 +-- truncate_limit: 100 +SELECT cast(NULL as dnotnull) +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::dnotnull" +== 061 +-- truncate_limit: 100 +-- fail +SELECT cast(cast(NULL as dnull) as dnotnull) +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::dnull::dnotnull" +== 062 +-- truncate_limit: 100 +-- fail +SELECT cast(col4 as dnotnull) from nulltest +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT col4::dnotnull FROM nulltest" +== 063 +-- truncate_limit: 100 +-- fail + +-- cleanup +drop table nulltest +-- +TABLE: name="nulltest" schema="" table="nulltest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE nulltest" +== 064 +-- truncate_limit: 100 +drop domain dnotnull restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN dnotnull" +== 065 +-- truncate_limit: 100 +drop domain dnull restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN dnull" +== 066 +-- truncate_limit: 100 +drop domain dcheck restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN dcheck" +== 067 +-- truncate_limit: 100 +create domain ddef1 int4 DEFAULT 3 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN ddef1 AS int4 DEFAULT 3" +== 068 +-- truncate_limit: 100 +create domain ddef2 oid DEFAULT '12' +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN ddef2 AS oid DEFAULT '12'" +== 069 +-- truncate_limit: 100 +-- Type mixing, function returns int8 +create domain ddef3 text DEFAULT 5 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN ddef3 AS text DEFAULT 5" +== 070 +-- truncate_limit: 100 +create sequence ddef4_seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE ddef4_seq" +== 071 +-- truncate_limit: 100 +create domain ddef4 int4 DEFAULT nextval('ddef4_seq') +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN ddef4 AS int4 DEFAULT nextval('ddef4_seq')" +== 072 +-- truncate_limit: 100 +create domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12' +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN ddef5 AS numeric(8, 2) NOT NULL DEFAULT '12.12'" +== 073 +-- truncate_limit: 100 +create table defaulttest + ( col1 ddef1 + , col2 ddef2 + , col3 ddef3 + , col4 ddef4 PRIMARY KEY + , col5 ddef1 NOT NULL DEFAULT NULL + , col6 ddef2 DEFAULT '88' + , col7 ddef4 DEFAULT 8000 + , col8 ddef5 + ) +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE defaulttest (col1 ddef1, col2 ddef2, col3 ddef3, col4 ddef4 PRIMARY KEY, col5 ddef1 ..." +== 074 +-- truncate_limit: 100 +insert into defaulttest(col4) values(0) +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defaulttest (col4) VALUES (0)" +== 075 +-- truncate_limit: 100 +-- fails, col5 defaults to null +alter table defaulttest alter column col5 drop default +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defaulttest ALTER COLUMN col5 DROP DEFAULT" +== 076 +-- truncate_limit: 100 +insert into defaulttest default values +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO defaulttest DEFAULT VALUES" +== 077 +-- truncate_limit: 100 +-- succeeds, inserts domain default +-- We used to treat SET DEFAULT NULL as equivalent to DROP DEFAULT; wrong +alter table defaulttest alter column col5 set default null +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defaulttest ALTER COLUMN col5 SET DEFAULT NULL" +== 078 +-- truncate_limit: 100 +insert into defaulttest(col4) values(0) +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defaulttest (col4) VALUES (0)" +== 079 +-- truncate_limit: 100 +-- fails +alter table defaulttest alter column col5 drop default +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defaulttest ALTER COLUMN col5 DROP DEFAULT" +== 080 +-- truncate_limit: 100 +insert into defaulttest default values +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO defaulttest DEFAULT VALUES" +== 081 +-- truncate_limit: 100 +insert into defaulttest default values +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO defaulttest DEFAULT VALUES" +== 082 +-- truncate_limit: 100 +-- Test defaults with copy +COPY defaulttest(col5) FROM stdin +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY defaulttest(col5) FROM STDIN" +== 083 +-- truncate_limit: 100 +select * from defaulttest +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM defaulttest" +== 084 +-- truncate_limit: 100 +drop table defaulttest cascade +-- +TABLE: name="defaulttest" schema="" table="defaulttest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE defaulttest CASCADE" +== 085 +-- truncate_limit: 100 +-- Test ALTER DOMAIN .. NOT NULL +create domain dnotnulltest integer +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN dnotnulltest AS int" +== 086 +-- truncate_limit: 100 +create table domnotnull +( col1 dnotnulltest +, col2 dnotnulltest +) +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE domnotnull (col1 dnotnulltest, col2 dnotnulltest)" +== 087 +-- truncate_limit: 100 +insert into domnotnull default values +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO domnotnull DEFAULT VALUES" +== 088 +-- truncate_limit: 100 +alter domain dnotnulltest set not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dnotnulltest SET NOT NULL" +== 089 +-- truncate_limit: 100 +-- fails + +update domnotnull set col1 = 5 +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domnotnull SET col1 = 5" +== 090 +-- truncate_limit: 100 +alter domain dnotnulltest set not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dnotnulltest SET NOT NULL" +== 091 +-- truncate_limit: 100 +-- fails + +update domnotnull set col2 = 6 +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domnotnull SET col2 = 6" +== 092 +-- truncate_limit: 100 +alter domain dnotnulltest set not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dnotnulltest SET NOT NULL" +== 093 +-- truncate_limit: 100 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domnotnull SET col1 = NULL" +== 094 +-- truncate_limit: 100 +-- fails + +alter domain dnotnulltest drop not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dnotnulltest DROP NOT NULL" +== 095 +-- truncate_limit: 100 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domnotnull SET col1 = NULL" +== 096 +-- truncate_limit: 100 +update domnotnull set col1 = 5 +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domnotnull SET col1 = 5" +== 097 +-- truncate_limit: 100 +-- these constraints can also be added and removed by name +alter domain dnotnulltest add constraint dnotnulltest_notnull not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dnotnulltest ADD CONSTRAINT dnotnulltest_notnull NOT NULL" +== 098 +-- truncate_limit: 100 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domnotnull SET col1 = NULL" +== 099 +-- truncate_limit: 100 +-- fails +select conname, pg_get_constraintdef(oid) from pg_constraint + where contypid = 'dnotnulltest'::regtype +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="contypid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE contypid = 'dnotnulltest'::regtype" +== 100 +-- truncate_limit: 100 +alter domain dnotnulltest drop constraint dnotnulltest_notnull +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dnotnulltest DROP CONSTRAINT dnotnulltest_notnull" +== 101 +-- truncate_limit: 100 +update domnotnull set col1 = null +-- +TABLE: name="domnotnull" schema="" table="domnotnull" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domnotnull SET col1 = NULL" +== 102 +-- truncate_limit: 100 +drop domain dnotnulltest cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN dnotnulltest CASCADE" +== 103 +-- truncate_limit: 100 +-- Test ALTER DOMAIN .. DEFAULT .. +create table domdeftest (col1 ddef1) +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE domdeftest (col1 ddef1)" +== 104 +-- truncate_limit: 100 +insert into domdeftest default values +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO domdeftest DEFAULT VALUES" +== 105 +-- truncate_limit: 100 +select * from domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domdeftest" +== 106 +-- truncate_limit: 100 +alter domain ddef1 set default '42' +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN ddef1 SET DEFAULT '42'" +== 107 +-- truncate_limit: 100 +insert into domdeftest default values +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO domdeftest DEFAULT VALUES" +== 108 +-- truncate_limit: 100 +select * from domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domdeftest" +== 109 +-- truncate_limit: 100 +alter domain ddef1 drop default +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN ddef1 DROP DEFAULT" +== 110 +-- truncate_limit: 100 +insert into domdeftest default values +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO domdeftest DEFAULT VALUES" +== 111 +-- truncate_limit: 100 +select * from domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domdeftest" +== 112 +-- truncate_limit: 100 +drop table domdeftest +-- +TABLE: name="domdeftest" schema="" table="domdeftest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE domdeftest" +== 113 +-- truncate_limit: 100 +-- Test ALTER DOMAIN .. CONSTRAINT .. +create domain con as integer +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN con AS int" +== 114 +-- truncate_limit: 100 +create table domcontest (col1 con) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE domcontest (col1 con)" +== 115 +-- truncate_limit: 100 +insert into domcontest values (1) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domcontest VALUES (1)" +== 116 +-- truncate_limit: 100 +insert into domcontest values (2) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domcontest VALUES (2)" +== 117 +-- truncate_limit: 100 +alter domain con add constraint t check (VALUE < 1) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN con ADD CONSTRAINT t CHECK (value < 1)" +== 118 +-- truncate_limit: 100 +-- fails + +alter domain con add constraint t check (VALUE < 34) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN con ADD CONSTRAINT t CHECK (value < 34)" +== 119 +-- truncate_limit: 100 +alter domain con add check (VALUE > 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN con ADD CHECK (value > 0)" +== 120 +-- truncate_limit: 100 +insert into domcontest values (-5) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domcontest VALUES (-5)" +== 121 +-- truncate_limit: 100 +-- fails +insert into domcontest values (42) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domcontest VALUES (42)" +== 122 +-- truncate_limit: 100 +-- fails +insert into domcontest values (5) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domcontest VALUES (5)" +== 123 +-- truncate_limit: 100 +alter domain con drop constraint t +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN con DROP CONSTRAINT t" +== 124 +-- truncate_limit: 100 +insert into domcontest values (-5) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domcontest VALUES (-5)" +== 125 +-- truncate_limit: 100 +--fails +insert into domcontest values (42) +-- +TABLE: name="domcontest" schema="" table="domcontest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domcontest VALUES (42)" +== 126 +-- truncate_limit: 100 +alter domain con drop constraint nonexistent +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN con DROP CONSTRAINT nonexistent" +== 127 +-- truncate_limit: 100 +alter domain con drop constraint if exists nonexistent +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN con DROP CONSTRAINT IF EXISTS nonexistent" +== 128 +-- truncate_limit: 100 +-- not-null constraints +create domain connotnull integer +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN connotnull AS int" +== 129 +-- truncate_limit: 100 +create table domconnotnulltest +( col1 connotnull +, col2 connotnull +) +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE domconnotnulltest (col1 connotnull, col2 connotnull)" +== 130 +-- truncate_limit: 100 +insert into domconnotnulltest default values +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO domconnotnulltest DEFAULT VALUES" +== 131 +-- truncate_limit: 100 +alter domain connotnull add not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN connotnull ADD NOT NULL" +== 132 +-- truncate_limit: 100 +-- fails + +update domconnotnulltest set col1 = 5 +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domconnotnulltest SET col1 = 5" +== 133 +-- truncate_limit: 100 +alter domain connotnull add not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN connotnull ADD NOT NULL" +== 134 +-- truncate_limit: 100 +-- fails + +update domconnotnulltest set col2 = 6 +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domconnotnulltest SET col2 = 6" +== 135 +-- truncate_limit: 100 +alter domain connotnull add constraint constr1 not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN connotnull ADD CONSTRAINT constr1 NOT NULL" +== 136 +-- truncate_limit: 100 +select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="contypid" +FILTER: schema="" table="" column="contype" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_constraint WHERE contypid = 'connotnull'::regtype AND contype = 'n'" +== 137 +-- truncate_limit: 100 +alter domain connotnull add constraint constr1bis not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN connotnull ADD CONSTRAINT constr1bis NOT NULL" +== 138 +-- truncate_limit: 100 +-- redundant +select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n' +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="contypid" +FILTER: schema="" table="" column="contype" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_constraint WHERE contypid = 'connotnull'::regtype AND contype = 'n'" +== 139 +-- truncate_limit: 100 +update domconnotnulltest set col1 = null +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domconnotnulltest SET col1 = NULL" +== 140 +-- truncate_limit: 100 +-- fails + +alter domain connotnull drop constraint constr1 +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN connotnull DROP CONSTRAINT constr1" +== 141 +-- truncate_limit: 100 +update domconnotnulltest set col1 = null +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE domconnotnulltest SET col1 = NULL" +== 142 +-- truncate_limit: 100 +drop domain connotnull cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN connotnull CASCADE" +== 143 +-- truncate_limit: 100 +drop table domconnotnulltest +-- +TABLE: name="domconnotnulltest" schema="" table="domconnotnulltest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE domconnotnulltest" +== 144 +-- truncate_limit: 100 +-- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID +create domain things AS INT +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN things AS int" +== 145 +-- truncate_limit: 100 +CREATE TABLE thethings (stuff things) +-- +TABLE: name="thethings" schema="" table="thethings" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE thethings (stuff things)" +== 146 +-- truncate_limit: 100 +INSERT INTO thethings (stuff) VALUES (55) +-- +TABLE: name="thethings" schema="" table="thethings" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO thethings (stuff) VALUES (55)" +== 147 +-- truncate_limit: 100 +ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN things ADD CONSTRAINT meow CHECK (value < 11)" +== 148 +-- truncate_limit: 100 +ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11) NOT VALID +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN things ADD CONSTRAINT meow CHECK (value < 11) NOT VALID" +== 149 +-- truncate_limit: 100 +ALTER DOMAIN things VALIDATE CONSTRAINT meow +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN things VALIDATE CONSTRAINT meow" +== 150 +-- truncate_limit: 100 +UPDATE thethings SET stuff = 10 +-- +TABLE: name="thethings" schema="" table="thethings" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE thethings SET stuff = 10" +== 151 +-- truncate_limit: 100 +ALTER DOMAIN things VALIDATE CONSTRAINT meow +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN things VALIDATE CONSTRAINT meow" +== 152 +-- truncate_limit: 100 +-- Confirm ALTER DOMAIN with RULES. +create table domtab (col1 integer) +-- +TABLE: name="domtab" schema="" table="domtab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE domtab (col1 int)" +== 153 +-- truncate_limit: 100 +create domain dom as integer +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN dom AS int" +== 154 +-- truncate_limit: 100 +create view domview as select cast(col1 as dom) from domtab +-- +TABLE: name="domview" schema="" table="domview" ctx=DDL +TABLE: name="domtab" schema="" table="domtab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW domview AS SELECT col1::dom FROM domtab" +== 155 +-- truncate_limit: 100 +insert into domtab (col1) values (null) +-- +TABLE: name="domtab" schema="" table="domtab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domtab (col1) VALUES (NULL)" +== 156 +-- truncate_limit: 100 +insert into domtab (col1) values (5) +-- +TABLE: name="domtab" schema="" table="domtab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domtab (col1) VALUES (5)" +== 157 +-- truncate_limit: 100 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domview" +== 158 +-- truncate_limit: 100 +alter domain dom set not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dom SET NOT NULL" +== 159 +-- truncate_limit: 100 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domview" +== 160 +-- truncate_limit: 100 +-- fail + +alter domain dom drop not null +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dom DROP NOT NULL" +== 161 +-- truncate_limit: 100 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domview" +== 162 +-- truncate_limit: 100 +alter domain dom add constraint domchkgt6 check(value > 6) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dom ADD CONSTRAINT domchkgt6 CHECK (value > 6)" +== 163 +-- truncate_limit: 100 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domview" +== 164 +-- truncate_limit: 100 +--fail + +alter domain dom drop constraint domchkgt6 restrict +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN dom DROP CONSTRAINT domchkgt6" +== 165 +-- truncate_limit: 100 +select * from domview +-- +TABLE: name="domview" schema="" table="domview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM domview" +== 166 +-- truncate_limit: 100 +-- cleanup +drop domain ddef1 restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN ddef1" +== 167 +-- truncate_limit: 100 +drop domain ddef2 restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN ddef2" +== 168 +-- truncate_limit: 100 +drop domain ddef3 restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN ddef3" +== 169 +-- truncate_limit: 100 +drop domain ddef4 restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN ddef4" +== 170 +-- truncate_limit: 100 +drop domain ddef5 restrict +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN ddef5" +== 171 +-- truncate_limit: 100 +drop sequence ddef4_seq +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE ddef4_seq" +== 172 +-- truncate_limit: 100 +-- Test domains over domains +create domain vchar4 varchar(4) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN vchar4 AS varchar(4)" +== 173 +-- truncate_limit: 100 +create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x') +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN dinter AS vchar4 CHECK (\"substring\"(value, 1, 1) = 'x')" +== 174 +-- truncate_limit: 100 +create domain dtop dinter check (substring(VALUE, 2, 1) = '1') +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN dtop AS dinter CHECK (\"substring\"(value, 2, 1) = '1')" +== 175 +-- truncate_limit: 100 +select 'x123'::dtop +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'x123'::dtop" +== 176 +-- truncate_limit: 100 +select 'x1234'::dtop +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'x1234'::dtop" +== 177 +-- truncate_limit: 100 +-- explicit coercion should truncate +select 'y1234'::dtop +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'y1234'::dtop" +== 178 +-- truncate_limit: 100 +-- fail +select 'y123'::dtop +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'y123'::dtop" +== 179 +-- truncate_limit: 100 +-- fail +select 'yz23'::dtop +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'yz23'::dtop" +== 180 +-- truncate_limit: 100 +-- fail +select 'xz23'::dtop +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'xz23'::dtop" +== 181 +-- truncate_limit: 100 +-- fail + +create temp table dtest(f1 dtop) +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE dtest (f1 dtop)" +== 182 +-- truncate_limit: 100 +insert into dtest values('x123') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dtest VALUES ('x123')" +== 183 +-- truncate_limit: 100 +insert into dtest values('x1234') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dtest VALUES ('x1234')" +== 184 +-- truncate_limit: 100 +-- fail, implicit coercion +insert into dtest values('y1234') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dtest VALUES ('y1234')" +== 185 +-- truncate_limit: 100 +-- fail, implicit coercion +insert into dtest values('y123') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dtest VALUES ('y123')" +== 186 +-- truncate_limit: 100 +-- fail +insert into dtest values('yz23') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dtest VALUES ('yz23')" +== 187 +-- truncate_limit: 100 +-- fail +insert into dtest values('xz23') +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dtest VALUES ('xz23')" +== 188 +-- truncate_limit: 100 +-- fail + +drop table dtest +-- +TABLE: name="dtest" schema="" table="dtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE dtest" +== 189 +-- truncate_limit: 100 +drop domain vchar4 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN vchar4 CASCADE" +== 190 +-- truncate_limit: 100 +-- Make sure that constraints of newly-added domain columns are +-- enforced correctly, even if there's no default value for the new +-- column. Per bug #1433 +create domain str_domain as text not null +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN str_domain AS text NOT NULL" +== 191 +-- truncate_limit: 100 +create table domain_test (a int, b int) +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE domain_test (a int, b int)" +== 192 +-- truncate_limit: 100 +insert into domain_test values (1, 2) +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domain_test VALUES (1, 2)" +== 193 +-- truncate_limit: 100 +insert into domain_test values (1, 2) +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO domain_test VALUES (1, 2)" +== 194 +-- truncate_limit: 100 +-- should fail +alter table domain_test add column c str_domain +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE domain_test ADD COLUMN c str_domain" +== 195 +-- truncate_limit: 100 +create domain str_domain2 as text check (value <> 'foo') default 'foo' +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN str_domain2 AS text CHECK (value <> 'foo') DEFAULT 'foo'" +== 196 +-- truncate_limit: 100 +-- should fail +alter table domain_test add column d str_domain2 +-- +TABLE: name="domain_test" schema="" table="domain_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE domain_test ADD COLUMN d str_domain2" +== 197 +-- truncate_limit: 100 +-- Check that domain constraints on prepared statement parameters of +-- unknown type are enforced correctly. +create domain pos_int as int4 check (value > 0) not null +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN pos_int AS int4 CHECK (value > 0) NOT NULL" +== 198 +-- truncate_limit: 100 +prepare s1 as select $1::pos_int = 10 as "is_ten" +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE s1 AS SELECT $1::pos_int = 10 AS is_ten" +== 199 +-- truncate_limit: 100 +execute s1(10) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE s1(10)" +== 200 +-- truncate_limit: 100 +execute s1(0) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE s1(0)" +== 201 +-- truncate_limit: 100 +-- should fail +execute s1(NULL) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE s1(NULL)" +== 202 +-- truncate_limit: 100 +-- should fail + +-- Check that domain constraints on plpgsql function parameters, results, +-- and local variables are enforced correctly. + +create function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int; +begin + return p1; +end$$ language plpgsql +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION doubledecrement(p1 pos_int) RETURNS pos_int AS $$\ndeclare v pos_int;\nbegin\n re..." +== 203 +-- truncate_limit: 100 +select doubledecrement(3) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT doubledecrement(3)" +== 204 +-- truncate_limit: 100 +-- fail because of implicit null assignment + +create or replace function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int := 0; +begin + return p1; +end$$ language plpgsql +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION doubledecrement(p1 pos_int) RETURNS pos_int AS $$\ndeclare v pos_int :=..." +== 205 +-- truncate_limit: 100 +select doubledecrement(3) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT doubledecrement(3)" +== 206 +-- truncate_limit: 100 +-- fail at initialization assignment + +create or replace function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int := 1; +begin + v := p1 - 1; + return v - 1; +end$$ language plpgsql +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION doubledecrement(p1 pos_int) RETURNS pos_int AS $$\ndeclare v pos_int :=..." +== 207 +-- truncate_limit: 100 +select doubledecrement(null) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT doubledecrement(NULL)" +== 208 +-- truncate_limit: 100 +-- fail before call +select doubledecrement(0) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT doubledecrement(0)" +== 209 +-- truncate_limit: 100 +-- fail before call +select doubledecrement(1) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT doubledecrement(1)" +== 210 +-- truncate_limit: 100 +-- fail at assignment to v +select doubledecrement(2) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT doubledecrement(2)" +== 211 +-- truncate_limit: 100 +-- fail at return +select doubledecrement(3) +-- +FUNCTION: name="doubledecrement" function="doubledecrement" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT doubledecrement(3)" +== 212 +-- truncate_limit: 100 +-- good + +-- Check that ALTER DOMAIN tests columns of derived types + +create domain posint as int4 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN posint AS int4" +== 213 +-- truncate_limit: 100 +-- Currently, this doesn't work for composite types, but verify it complains +create type ddtest1 as (f1 posint) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE ddtest1 AS (f1 posint)" +== 214 +-- truncate_limit: 100 +create table ddtest2(f1 ddtest1) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ddtest2 (f1 ddtest1)" +== 215 +-- truncate_limit: 100 +insert into ddtest2 values(row(-1)) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES (ROW(-1))" +== 216 +-- truncate_limit: 100 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c1 CHECK (value >= 0)" +== 217 +-- truncate_limit: 100 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ddtest2" +== 218 +-- truncate_limit: 100 +-- Likewise for domains within arrays of composite +create table ddtest2(f1 ddtest1[]) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ddtest2 (f1 ddtest1[])" +== 219 +-- truncate_limit: 100 +insert into ddtest2 values('{(-1)}') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES ('{(-1)}')" +== 220 +-- truncate_limit: 100 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c1 CHECK (value >= 0)" +== 221 +-- truncate_limit: 100 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ddtest2" +== 222 +-- truncate_limit: 100 +-- Likewise for domains within domains over composite +create domain ddtest1d as ddtest1 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN ddtest1d AS ddtest1" +== 223 +-- truncate_limit: 100 +create table ddtest2(f1 ddtest1d) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ddtest2 (f1 ddtest1d)" +== 224 +-- truncate_limit: 100 +insert into ddtest2 values('(-1)') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES ('(-1)')" +== 225 +-- truncate_limit: 100 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c1 CHECK (value >= 0)" +== 226 +-- truncate_limit: 100 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ddtest2" +== 227 +-- truncate_limit: 100 +drop domain ddtest1d +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN ddtest1d" +== 228 +-- truncate_limit: 100 +-- Likewise for domains within domains over array of composite +create domain ddtest1d as ddtest1[] +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN ddtest1d AS ddtest1[]" +== 229 +-- truncate_limit: 100 +create table ddtest2(f1 ddtest1d) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ddtest2 (f1 ddtest1d)" +== 230 +-- truncate_limit: 100 +insert into ddtest2 values('{(-1)}') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES ('{(-1)}')" +== 231 +-- truncate_limit: 100 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c1 CHECK (value >= 0)" +== 232 +-- truncate_limit: 100 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ddtest2" +== 233 +-- truncate_limit: 100 +drop domain ddtest1d +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN ddtest1d" +== 234 +-- truncate_limit: 100 +-- Doesn't work for ranges, either +create type rposint as range (subtype = posint) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE rposint AS RANGE (subtype = posint)" +== 235 +-- truncate_limit: 100 +create table ddtest2(f1 rposint) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ddtest2 (f1 rposint)" +== 236 +-- truncate_limit: 100 +insert into ddtest2 values('(-1,3]') +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES ('(-1,3]')" +== 237 +-- truncate_limit: 100 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c1 CHECK (value >= 0)" +== 238 +-- truncate_limit: 100 +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ddtest2" +== 239 +-- truncate_limit: 100 +drop type rposint +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE rposint" +== 240 +-- truncate_limit: 100 +alter domain posint add constraint c1 check(value >= 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c1 CHECK (value >= 0)" +== 241 +-- truncate_limit: 100 +create domain posint2 as posint check (value % 2 = 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN posint2 AS posint CHECK ((value % 2) = 0)" +== 242 +-- truncate_limit: 100 +create table ddtest2(f1 posint2) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ddtest2 (f1 posint2)" +== 243 +-- truncate_limit: 100 +insert into ddtest2 values(11) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES (11)" +== 244 +-- truncate_limit: 100 +-- fail +insert into ddtest2 values(-2) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES (-2)" +== 245 +-- truncate_limit: 100 +-- fail +insert into ddtest2 values(2) +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ddtest2 VALUES (2)" +== 246 +-- truncate_limit: 100 +alter domain posint add constraint c2 check(value >= 10) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c2 CHECK (value >= 10)" +== 247 +-- truncate_limit: 100 +-- fail +alter domain posint add constraint c2 check(value > 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN posint ADD CONSTRAINT c2 CHECK (value > 0)" +== 248 +-- truncate_limit: 100 +-- OK + +drop table ddtest2 +-- +TABLE: name="ddtest2" schema="" table="ddtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ddtest2" +== 249 +-- truncate_limit: 100 +drop type ddtest1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE ddtest1" +== 250 +-- truncate_limit: 100 +drop domain posint cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN posint CASCADE" +== 251 +-- truncate_limit: 100 +|-- +-- Check enforcement of domain-related typmod in plpgsql (bug #5717) +|-- + +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x numeric(4,2)[1]; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION array_elem_check(numeric) RETURNS numeric AS $$\ndeclare\n x numeric(4,..." +== 252 +-- truncate_limit: 100 +select array_elem_check(121.00) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(121.00)" +== 253 +-- truncate_limit: 100 +select array_elem_check(1.23456) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(1.23456)" +== 254 +-- truncate_limit: 100 +create domain mynums as numeric(4,2)[1] +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN mynums AS numeric(4, 2)[1]" +== 255 +-- truncate_limit: 100 +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x mynums; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION array_elem_check(numeric) RETURNS numeric AS $$\ndeclare\n x mynums;\nbe..." +== 256 +-- truncate_limit: 100 +select array_elem_check(121.00) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(121.00)" +== 257 +-- truncate_limit: 100 +select array_elem_check(1.23456) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(1.23456)" +== 258 +-- truncate_limit: 100 +create domain mynums2 as mynums +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN mynums2 AS mynums" +== 259 +-- truncate_limit: 100 +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x mynums2; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION array_elem_check(numeric) RETURNS numeric AS $$\ndeclare\n x mynums2;\nb..." +== 260 +-- truncate_limit: 100 +select array_elem_check(121.00) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(121.00)" +== 261 +-- truncate_limit: 100 +select array_elem_check(1.23456) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(1.23456)" +== 262 +-- truncate_limit: 100 +drop function array_elem_check(numeric) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION array_elem_check(numeric)" +== 263 +-- truncate_limit: 100 +|-- +-- Check enforcement of array-level domain constraints +|-- + +create domain orderedpair as int[2] check (value[1] < value[2]) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN orderedpair AS int[2] CHECK (value[1] < value[2])" +== 264 +-- truncate_limit: 100 +select array[1,2]::orderedpair +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 2]::orderedpair" +== 265 +-- truncate_limit: 100 +select array[2,1]::orderedpair +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[2, 1]::orderedpair" +== 266 +-- truncate_limit: 100 +-- fail + +create temp table op (f1 orderedpair) +-- +TABLE: name="op" schema="" table="op" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE op (f1 orderedpair)" +== 267 +-- truncate_limit: 100 +insert into op values (array[1,2]) +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO op VALUES (ARRAY[1, 2])" +== 268 +-- truncate_limit: 100 +insert into op values (array[2,1]) +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO op VALUES (ARRAY[2, 1])" +== 269 +-- truncate_limit: 100 +-- fail + +update op set f1[2] = 3 +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE op SET f1[2] = 3" +== 270 +-- truncate_limit: 100 +update op set f1[2] = 0 +-- +TABLE: name="op" schema="" table="op" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE op SET f1[2] = 0" +== 271 +-- truncate_limit: 100 +-- fail +select * from op +-- +TABLE: name="op" schema="" table="op" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM op" +== 272 +-- truncate_limit: 100 +create or replace function array_elem_check(int) returns int as $$ +declare + x orderedpair := '{1,2}'; +begin + x[2] := $1; + return x[2]; +end$$ language plpgsql +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION array_elem_check(int) RETURNS int AS $$\ndeclare\n x orderedpair := '{1..." +== 273 +-- truncate_limit: 100 +select array_elem_check(3) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(3)" +== 274 +-- truncate_limit: 100 +select array_elem_check(-1) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_elem_check(-1)" +== 275 +-- truncate_limit: 100 +drop function array_elem_check(int) +-- +FUNCTION: name="array_elem_check" function="array_elem_check" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION array_elem_check(int)" +== 276 +-- truncate_limit: 100 +|-- +-- Check enforcement of changing constraints in plpgsql +|-- + +create domain di as int +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN di AS int" +== 277 +-- truncate_limit: 100 +create function dom_check(int) returns di as $$ +declare d di; +begin + d := $1::di; + return d; +end +$$ language plpgsql immutable +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dom_check(int) RETURNS di AS $$\ndeclare d di;\nbegin\n d := $1::di;\n return d;\nen..." +== 278 +-- truncate_limit: 100 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dom_check(0)" +== 279 +-- truncate_limit: 100 +alter domain di add constraint pos check (value > 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN di ADD CONSTRAINT pos CHECK (value > 0)" +== 280 +-- truncate_limit: 100 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dom_check(0)" +== 281 +-- truncate_limit: 100 +-- fail + +alter domain di drop constraint pos +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN di DROP CONSTRAINT pos" +== 282 +-- truncate_limit: 100 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dom_check(0)" +== 283 +-- truncate_limit: 100 +-- implicit cast during assignment is a separate code path, test that too + +create or replace function dom_check(int) returns di as $$ +declare d di; +begin + d := $1; + return d; +end +$$ language plpgsql immutable +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dom_check(int) RETURNS di AS $$\ndeclare d di;\nbegin\n d := $1;\n retur..." +== 284 +-- truncate_limit: 100 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dom_check(0)" +== 285 +-- truncate_limit: 100 +alter domain di add constraint pos check (value > 0) +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN di ADD CONSTRAINT pos CHECK (value > 0)" +== 286 +-- truncate_limit: 100 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dom_check(0)" +== 287 +-- truncate_limit: 100 +-- fail + +alter domain di drop constraint pos +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN di DROP CONSTRAINT pos" +== 288 +-- truncate_limit: 100 +select dom_check(0) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dom_check(0)" +== 289 +-- truncate_limit: 100 +drop function dom_check(int) +-- +FUNCTION: name="dom_check" function="dom_check" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dom_check(int)" +== 290 +-- truncate_limit: 100 +drop domain di +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN di" +== 291 +-- truncate_limit: 100 +|-- +-- Check use of a (non-inline-able) SQL function in a domain constraint; +-- this has caused issues in the past +|-- + +create function sql_is_distinct_from(anyelement, anyelement) +returns boolean language sql +as 'select $1 is distinct from $2 limit 1' +-- +FUNCTION: name="sql_is_distinct_from" function="sql_is_distinct_from" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sql_is_distinct_from(anyelement, anyelement) RETURNS boolean LANGUAGE sql AS $$se..." +== 292 +-- truncate_limit: 100 +create domain inotnull int + check (sql_is_distinct_from(value, null)) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN inotnull AS int CHECK (sql_is_distinct_from(value, NULL))" +== 293 +-- truncate_limit: 100 +select 1::inotnull +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1::inotnull" +== 294 +-- truncate_limit: 100 +select null::inotnull +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::inotnull" +== 295 +-- truncate_limit: 100 +create table dom_table (x inotnull) +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dom_table (x inotnull)" +== 296 +-- truncate_limit: 100 +insert into dom_table values ('1') +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dom_table VALUES ('1')" +== 297 +-- truncate_limit: 100 +insert into dom_table values (1) +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dom_table VALUES (1)" +== 298 +-- truncate_limit: 100 +insert into dom_table values (null) +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dom_table VALUES (NULL)" +== 299 +-- truncate_limit: 100 +drop table dom_table +-- +TABLE: name="dom_table" schema="" table="dom_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE dom_table" +== 300 +-- truncate_limit: 100 +drop domain inotnull +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN inotnull" +== 301 +-- truncate_limit: 100 +drop function sql_is_distinct_from(anyelement, anyelement) +-- +FUNCTION: name="sql_is_distinct_from" function="sql_is_distinct_from" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sql_is_distinct_from(anyelement, anyelement)" +== 302 +-- truncate_limit: 100 +|-- +-- Renaming +|-- + +create domain testdomain1 as int +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain1 AS int" +== 303 +-- truncate_limit: 100 +alter domain testdomain1 rename to testdomain2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER DOMAIN testdomain1 RENAME TO testdomain2" +== 304 +-- truncate_limit: 100 +alter type testdomain2 rename to testdomain3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE testdomain2 RENAME TO testdomain3" +== 305 +-- truncate_limit: 100 +-- alter type also works +drop domain testdomain3 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN testdomain3" +== 306 +-- truncate_limit: 100 +|-- +-- Renaming domain constraints +|-- + +create domain testdomain1 as int constraint unsigned check (value > 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdomain1 AS int CONSTRAINT unsigned CHECK (value > 0)" +== 307 +-- truncate_limit: 100 +alter domain testdomain1 rename constraint unsigned to unsigned_foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER DOMAIN testdomain1 RENAME CONSTRAINT unsigned TO unsigned_foo" +== 308 +-- truncate_limit: 100 +alter domain testdomain1 drop constraint unsigned_foo +-- +STMT: AlterDomainStmt +TRUNCATED: "ALTER DOMAIN testdomain1 DROP CONSTRAINT unsigned_foo" +== 309 +-- truncate_limit: 100 +drop domain testdomain1 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN testdomain1" +== 310 +-- truncate_limit: 100 +|-- +-- Get the base type of a domain +|-- +create domain mytext as text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN mytext AS text" +== 311 +-- truncate_limit: 100 +create domain mytext_child_1 as mytext +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN mytext_child_1 AS mytext" +== 312 +-- truncate_limit: 100 +select pg_basetype('mytext'::regtype) +-- +FUNCTION: name="pg_basetype" function="pg_basetype" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_basetype('mytext'::regtype)" +== 313 +-- truncate_limit: 100 +select pg_basetype('mytext_child_1'::regtype) +-- +FUNCTION: name="pg_basetype" function="pg_basetype" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_basetype('mytext_child_1'::regtype)" +== 314 +-- truncate_limit: 100 +select pg_basetype(1) +-- +FUNCTION: name="pg_basetype" function="pg_basetype" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_basetype(1)" +== 315 +-- truncate_limit: 100 +-- expect NULL not error + +drop domain mytext cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN mytext CASCADE" +== 316 +-- truncate_limit: 100 +|-- +-- Information schema +|-- + +SELECT * FROM information_schema.column_domain_usage + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY domain_name +-- +TABLE: name="information_schema.column_domain_usage" schema="information_schema" table="column_domain_usage" ctx=Select +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.column_domain_usage WHERE ... ORDER BY domain_name" +== 317 +-- truncate_limit: 100 +SELECT * FROM information_schema.domain_constraints + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY constraint_name +-- +TABLE: name="information_schema.domain_constraints" schema="information_schema" table="domain_constraints" ctx=Select +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.domain_constraints WHERE ... ORDER BY constraint_name" +== 318 +-- truncate_limit: 100 +SELECT * FROM information_schema.domains + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY domain_name +-- +TABLE: name="information_schema.domains" schema="information_schema" table="domains" ctx=Select +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.domains WHERE ... ORDER BY domain_name" +== 319 +-- truncate_limit: 100 +SELECT * FROM information_schema.check_constraints + WHERE (constraint_schema, constraint_name) + IN (SELECT constraint_schema, constraint_name + FROM information_schema.domain_constraints + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things')) + ORDER BY constraint_name +-- +TABLE: name="information_schema.check_constraints" schema="information_schema" table="check_constraints" ctx=Select +TABLE: name="information_schema.domain_constraints" schema="information_schema" table="domain_constraints" ctx=Select +FILTER: schema="" table="" column="constraint_schema" +FILTER: schema="" table="" column="constraint_name" +FILTER: schema="" table="" column="domain_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.check_constraints WHERE ... ORDER BY constraint_name" diff --git a/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json b/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json new file mode 100644 index 0000000..3b3c7f2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json @@ -0,0 +1,165 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.test b/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.test new file mode 100644 index 0000000..7e83e24 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.test @@ -0,0 +1,1072 @@ +== 001 +-- truncate_limit: 100 +|-- +-- IF EXISTS tests +|-- + +-- table (will be really dropped at the end) + +DROP TABLE test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_exists" +== 002 +-- truncate_limit: 100 +DROP TABLE IF EXISTS test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE IF EXISTS test_exists" +== 003 +-- truncate_limit: 100 +CREATE TABLE test_exists (a int, b text) +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_exists (a int, b text)" +== 004 +-- truncate_limit: 100 +-- view + +DROP VIEW test_view_exists +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW test_view_exists" +== 005 +-- truncate_limit: 100 +DROP VIEW IF EXISTS test_view_exists +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW IF EXISTS test_view_exists" +== 006 +-- truncate_limit: 100 +CREATE VIEW test_view_exists AS select * from test_exists +-- +TABLE: name="test_view_exists" schema="" table="test_view_exists" ctx=DDL +TABLE: name="test_exists" schema="" table="test_exists" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW test_view_exists AS SELECT * FROM test_exists" +== 007 +-- truncate_limit: 100 +DROP VIEW IF EXISTS test_view_exists +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW IF EXISTS test_view_exists" +== 008 +-- truncate_limit: 100 +DROP VIEW test_view_exists +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW test_view_exists" +== 009 +-- truncate_limit: 100 +-- index + +DROP INDEX test_index_exists +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX test_index_exists" +== 010 +-- truncate_limit: 100 +DROP INDEX IF EXISTS test_index_exists +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX IF EXISTS test_index_exists" +== 011 +-- truncate_limit: 100 +CREATE INDEX test_index_exists on test_exists(a) +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_index_exists ON test_exists USING btree (a)" +== 012 +-- truncate_limit: 100 +DROP INDEX IF EXISTS test_index_exists +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX IF EXISTS test_index_exists" +== 013 +-- truncate_limit: 100 +DROP INDEX test_index_exists +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX test_index_exists" +== 014 +-- truncate_limit: 100 +-- sequence + +DROP SEQUENCE test_sequence_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE test_sequence_exists" +== 015 +-- truncate_limit: 100 +DROP SEQUENCE IF EXISTS test_sequence_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE IF EXISTS test_sequence_exists" +== 016 +-- truncate_limit: 100 +CREATE SEQUENCE test_sequence_exists +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE test_sequence_exists" +== 017 +-- truncate_limit: 100 +DROP SEQUENCE IF EXISTS test_sequence_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE IF EXISTS test_sequence_exists" +== 018 +-- truncate_limit: 100 +DROP SEQUENCE test_sequence_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE test_sequence_exists" +== 019 +-- truncate_limit: 100 +-- schema + +DROP SCHEMA test_schema_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_schema_exists" +== 020 +-- truncate_limit: 100 +DROP SCHEMA IF EXISTS test_schema_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA IF EXISTS test_schema_exists" +== 021 +-- truncate_limit: 100 +CREATE SCHEMA test_schema_exists +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_schema_exists" +== 022 +-- truncate_limit: 100 +DROP SCHEMA IF EXISTS test_schema_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA IF EXISTS test_schema_exists" +== 023 +-- truncate_limit: 100 +DROP SCHEMA test_schema_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_schema_exists" +== 024 +-- truncate_limit: 100 +-- type + +DROP TYPE test_type_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE test_type_exists" +== 025 +-- truncate_limit: 100 +DROP TYPE IF EXISTS test_type_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE IF EXISTS test_type_exists" +== 026 +-- truncate_limit: 100 +CREATE type test_type_exists as (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE test_type_exists AS (a int, b text)" +== 027 +-- truncate_limit: 100 +DROP TYPE IF EXISTS test_type_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE IF EXISTS test_type_exists" +== 028 +-- truncate_limit: 100 +DROP TYPE test_type_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE test_type_exists" +== 029 +-- truncate_limit: 100 +-- domain + +DROP DOMAIN test_domain_exists +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN test_domain_exists" +== 030 +-- truncate_limit: 100 +DROP DOMAIN IF EXISTS test_domain_exists +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN IF EXISTS test_domain_exists" +== 031 +-- truncate_limit: 100 +CREATE domain test_domain_exists as int not null check (value > 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN test_domain_exists AS int NOT NULL CHECK (value > 0)" +== 032 +-- truncate_limit: 100 +DROP DOMAIN IF EXISTS test_domain_exists +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN IF EXISTS test_domain_exists" +== 033 +-- truncate_limit: 100 +DROP DOMAIN test_domain_exists +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN test_domain_exists" +== 034 +-- truncate_limit: 100 +--- +--- role/user/group +--- + +CREATE USER regress_test_u1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_test_u1" +== 035 +-- truncate_limit: 100 +CREATE ROLE regress_test_r1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_r1" +== 036 +-- truncate_limit: 100 +CREATE GROUP regress_test_g1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE GROUP regress_test_g1" +== 037 +-- truncate_limit: 100 +DROP USER regress_test_u2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_u2" +== 038 +-- truncate_limit: 100 +DROP USER IF EXISTS regress_test_u1, regress_test_u2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_test_u1, regress_test_u2" +== 039 +-- truncate_limit: 100 +DROP USER regress_test_u1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_u1" +== 040 +-- truncate_limit: 100 +DROP ROLE regress_test_r2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_r2" +== 041 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_test_r1, regress_test_r2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_test_r1, regress_test_r2" +== 042 +-- truncate_limit: 100 +DROP ROLE regress_test_r1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_r1" +== 043 +-- truncate_limit: 100 +DROP GROUP regress_test_g2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_g2" +== 044 +-- truncate_limit: 100 +DROP GROUP IF EXISTS regress_test_g1, regress_test_g2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_test_g1, regress_test_g2" +== 045 +-- truncate_limit: 100 +DROP GROUP regress_test_g1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_g1" +== 046 +-- truncate_limit: 100 +-- collation +DROP COLLATION IF EXISTS test_collation_exists +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION IF EXISTS test_collation_exists" +== 047 +-- truncate_limit: 100 +-- conversion +DROP CONVERSION test_conversion_exists +-- +STMT: DropStmt +TRUNCATED: "DROP CONVERSION test_conversion_exists" +== 048 +-- truncate_limit: 100 +DROP CONVERSION IF EXISTS test_conversion_exists +-- +STMT: DropStmt +TRUNCATED: "DROP CONVERSION IF EXISTS test_conversion_exists" +== 049 +-- truncate_limit: 100 +CREATE CONVERSION test_conversion_exists + FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8 +-- +STMT: CreateConversionStmt +TRUNCATED: "CREATE CONVERSION test_conversion_exists FOR 'LATIN1' TO 'UTF8'FROM iso8859_1_to_utf8" +== 050 +-- truncate_limit: 100 +DROP CONVERSION test_conversion_exists +-- +STMT: DropStmt +TRUNCATED: "DROP CONVERSION test_conversion_exists" +== 051 +-- truncate_limit: 100 +-- text search parser +DROP TEXT SEARCH PARSER test_tsparser_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH PARSER test_tsparser_exists" +== 052 +-- truncate_limit: 100 +DROP TEXT SEARCH PARSER IF EXISTS test_tsparser_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH PARSER IF EXISTS test_tsparser_exists" +== 053 +-- truncate_limit: 100 +-- text search dictionary +DROP TEXT SEARCH DICTIONARY test_tsdict_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH DICTIONARY test_tsdict_exists" +== 054 +-- truncate_limit: 100 +DROP TEXT SEARCH DICTIONARY IF EXISTS test_tsdict_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH DICTIONARY IF EXISTS test_tsdict_exists" +== 055 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY test_tsdict_exists ( + Template=ispell, + DictFile=ispell_sample, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY test_tsdict_exists (template = ispell, dictfile = ispell_sample, af..." +== 056 +-- truncate_limit: 100 +DROP TEXT SEARCH DICTIONARY test_tsdict_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH DICTIONARY test_tsdict_exists" +== 057 +-- truncate_limit: 100 +-- test search template +DROP TEXT SEARCH TEMPLATE test_tstemplate_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH TEMPLATE test_tstemplate_exists" +== 058 +-- truncate_limit: 100 +DROP TEXT SEARCH TEMPLATE IF EXISTS test_tstemplate_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH TEMPLATE IF EXISTS test_tstemplate_exists" +== 059 +-- truncate_limit: 100 +-- text search configuration +DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists" +== 060 +-- truncate_limit: 100 +DROP TEXT SEARCH CONFIGURATION IF EXISTS test_tsconfig_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH CONFIGURATION IF EXISTS test_tsconfig_exists" +== 061 +-- truncate_limit: 100 +CREATE TEXT SEARCH CONFIGURATION test_tsconfig_exists (COPY=english) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION test_tsconfig_exists (copy = english)" +== 062 +-- truncate_limit: 100 +DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists" +== 063 +-- truncate_limit: 100 +-- extension +DROP EXTENSION test_extension_exists +-- +STMT: DropStmt +TRUNCATED: "DROP EXTENSION test_extension_exists" +== 064 +-- truncate_limit: 100 +DROP EXTENSION IF EXISTS test_extension_exists +-- +STMT: DropStmt +TRUNCATED: "DROP EXTENSION IF EXISTS test_extension_exists" +== 065 +-- truncate_limit: 100 +-- functions +DROP FUNCTION test_function_exists() +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION test_function_exists()" +== 066 +-- truncate_limit: 100 +DROP FUNCTION IF EXISTS test_function_exists() +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION IF EXISTS test_function_exists()" +== 067 +-- truncate_limit: 100 +DROP FUNCTION test_function_exists(int, text, int[]) +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION test_function_exists(int, text, int[])" +== 068 +-- truncate_limit: 100 +DROP FUNCTION IF EXISTS test_function_exists(int, text, int[]) +-- +FUNCTION: name="test_function_exists" function="test_function_exists" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION IF EXISTS test_function_exists(int, text, int[])" +== 069 +-- truncate_limit: 100 +-- aggregate +DROP AGGREGATE test_aggregate_exists(*) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE test_aggregate_exists(*)" +== 070 +-- truncate_limit: 100 +DROP AGGREGATE IF EXISTS test_aggregate_exists(*) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE IF EXISTS test_aggregate_exists(*)" +== 071 +-- truncate_limit: 100 +DROP AGGREGATE test_aggregate_exists(int) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE test_aggregate_exists(int)" +== 072 +-- truncate_limit: 100 +DROP AGGREGATE IF EXISTS test_aggregate_exists(int) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE IF EXISTS test_aggregate_exists(int)" +== 073 +-- truncate_limit: 100 +-- operator +DROP OPERATOR @#@ (int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR @#@(int, int)" +== 074 +-- truncate_limit: 100 +DROP OPERATOR IF EXISTS @#@ (int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR IF EXISTS @#@(int, int)" +== 075 +-- truncate_limit: 100 +CREATE OPERATOR @#@ + (leftarg = int8, rightarg = int8, procedure = int8xor) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR @#@ (leftarg = int8, rightarg = int8, procedure = int8xor)" +== 076 +-- truncate_limit: 100 +DROP OPERATOR @#@ (int8, int8) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR @#@(int8, int8)" +== 077 +-- truncate_limit: 100 +-- language +DROP LANGUAGE test_language_exists +-- +STMT: DropStmt +TRUNCATED: "DROP LANGUAGE test_language_exists" +== 078 +-- truncate_limit: 100 +DROP LANGUAGE IF EXISTS test_language_exists +-- +STMT: DropStmt +TRUNCATED: "DROP LANGUAGE IF EXISTS test_language_exists" +== 079 +-- truncate_limit: 100 +-- cast +DROP CAST (text AS text) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST (text AS text)" +== 080 +-- truncate_limit: 100 +DROP CAST IF EXISTS (text AS text) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST IF EXISTS (text AS text)" +== 081 +-- truncate_limit: 100 +-- trigger +DROP TRIGGER test_trigger_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER test_trigger_exists ON test_exists" +== 082 +-- truncate_limit: 100 +DROP TRIGGER IF EXISTS test_trigger_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER IF EXISTS test_trigger_exists ON test_exists" +== 083 +-- truncate_limit: 100 +DROP TRIGGER test_trigger_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER test_trigger_exists ON no_such_table" +== 084 +-- truncate_limit: 100 +DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_table" +== 085 +-- truncate_limit: 100 +DROP TRIGGER test_trigger_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER test_trigger_exists ON no_such_schema.no_such_table" +== 086 +-- truncate_limit: 100 +DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_schema.no_such_table" +== 087 +-- truncate_limit: 100 +CREATE TRIGGER test_trigger_exists + BEFORE UPDATE ON test_exists + FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger() +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER test_trigger_exists BEFORE UPDATE ON test_exists FOR EACH ROW EXECUTE FUNCTION sup..." +== 088 +-- truncate_limit: 100 +DROP TRIGGER test_trigger_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER test_trigger_exists ON test_exists" +== 089 +-- truncate_limit: 100 +-- rule +DROP RULE test_rule_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE test_rule_exists ON test_exists" +== 090 +-- truncate_limit: 100 +DROP RULE IF EXISTS test_rule_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE IF EXISTS test_rule_exists ON test_exists" +== 091 +-- truncate_limit: 100 +DROP RULE test_rule_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE test_rule_exists ON no_such_table" +== 092 +-- truncate_limit: 100 +DROP RULE IF EXISTS test_rule_exists ON no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE IF EXISTS test_rule_exists ON no_such_table" +== 093 +-- truncate_limit: 100 +DROP RULE test_rule_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE test_rule_exists ON no_such_schema.no_such_table" +== 094 +-- truncate_limit: 100 +DROP RULE IF EXISTS test_rule_exists ON no_such_schema.no_such_table +-- +TABLE: name="no_such_schema.no_such_table" schema="no_such_schema" table="no_such_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE IF EXISTS test_rule_exists ON no_such_schema.no_such_table" +== 095 +-- truncate_limit: 100 +CREATE RULE test_rule_exists AS ON INSERT TO test_exists + DO INSTEAD + INSERT INTO test_exists VALUES (NEW.a, NEW.b || NEW.a::text) +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE test_rule_exists AS ON INSERT TO test_exists DO INSTEAD INSERT INTO test_exists VALUE..." +== 096 +-- truncate_limit: 100 +DROP RULE test_rule_exists ON test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE test_rule_exists ON test_exists" +== 097 +-- truncate_limit: 100 +-- foreign data wrapper +DROP FOREIGN DATA WRAPPER test_fdw_exists +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER test_fdw_exists" +== 098 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER IF EXISTS test_fdw_exists +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER IF EXISTS test_fdw_exists" +== 099 +-- truncate_limit: 100 +-- foreign server +DROP SERVER test_server_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER test_server_exists" +== 100 +-- truncate_limit: 100 +DROP SERVER IF EXISTS test_server_exists +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER IF EXISTS test_server_exists" +== 101 +-- truncate_limit: 100 +-- operator class +DROP OPERATOR CLASS test_operator_class USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS test_operator_class USING btree" +== 102 +-- truncate_limit: 100 +DROP OPERATOR CLASS IF EXISTS test_operator_class USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS IF EXISTS test_operator_class USING btree" +== 103 +-- truncate_limit: 100 +DROP OPERATOR CLASS test_operator_class USING no_such_am +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS test_operator_class USING no_such_am" +== 104 +-- truncate_limit: 100 +DROP OPERATOR CLASS IF EXISTS test_operator_class USING no_such_am +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS IF EXISTS test_operator_class USING no_such_am" +== 105 +-- truncate_limit: 100 +-- operator family +DROP OPERATOR FAMILY test_operator_family USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY test_operator_family USING btree" +== 106 +-- truncate_limit: 100 +DROP OPERATOR FAMILY IF EXISTS test_operator_family USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY IF EXISTS test_operator_family USING btree" +== 107 +-- truncate_limit: 100 +DROP OPERATOR FAMILY test_operator_family USING no_such_am +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY test_operator_family USING no_such_am" +== 108 +-- truncate_limit: 100 +DROP OPERATOR FAMILY IF EXISTS test_operator_family USING no_such_am +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY IF EXISTS test_operator_family USING no_such_am" +== 109 +-- truncate_limit: 100 +-- access method +DROP ACCESS METHOD no_such_am +-- +STMT: DropStmt +TRUNCATED: "DROP ACCESS METHOD no_such_am" +== 110 +-- truncate_limit: 100 +DROP ACCESS METHOD IF EXISTS no_such_am +-- +STMT: DropStmt +TRUNCATED: "DROP ACCESS METHOD IF EXISTS no_such_am" +== 111 +-- truncate_limit: 100 +-- drop the table + +DROP TABLE IF EXISTS test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE IF EXISTS test_exists" +== 112 +-- truncate_limit: 100 +DROP TABLE test_exists +-- +TABLE: name="test_exists" schema="" table="test_exists" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_exists" +== 113 +-- truncate_limit: 100 +-- be tolerant with missing schemas, types, etc + +DROP AGGREGATE IF EXISTS no_such_schema.foo(int) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE IF EXISTS no_such_schema.foo(int)" +== 114 +-- truncate_limit: 100 +DROP AGGREGATE IF EXISTS foo(no_such_type) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE IF EXISTS foo(no_such_type)" +== 115 +-- truncate_limit: 100 +DROP AGGREGATE IF EXISTS foo(no_such_schema.no_such_type) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE IF EXISTS foo(no_such_schema.no_such_type)" +== 116 +-- truncate_limit: 100 +DROP CAST IF EXISTS (INTEGER AS no_such_type2) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST IF EXISTS (int AS no_such_type2)" +== 117 +-- truncate_limit: 100 +DROP CAST IF EXISTS (no_such_type1 AS INTEGER) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST IF EXISTS (no_such_type1 AS int)" +== 118 +-- truncate_limit: 100 +DROP CAST IF EXISTS (INTEGER AS no_such_schema.bar) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST IF EXISTS (int AS no_such_schema.bar)" +== 119 +-- truncate_limit: 100 +DROP CAST IF EXISTS (no_such_schema.foo AS INTEGER) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST IF EXISTS (no_such_schema.foo AS int)" +== 120 +-- truncate_limit: 100 +DROP COLLATION IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION IF EXISTS no_such_schema.foo" +== 121 +-- truncate_limit: 100 +DROP CONVERSION IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP CONVERSION IF EXISTS no_such_schema.foo" +== 122 +-- truncate_limit: 100 +DROP DOMAIN IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN IF EXISTS no_such_schema.foo" +== 123 +-- truncate_limit: 100 +DROP FOREIGN TABLE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE IF EXISTS no_such_schema.foo" +== 124 +-- truncate_limit: 100 +DROP FUNCTION IF EXISTS no_such_schema.foo() +-- +FUNCTION: name="no_such_schema.foo" function="foo" schema="no_such_schema" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION IF EXISTS no_such_schema.foo()" +== 125 +-- truncate_limit: 100 +DROP FUNCTION IF EXISTS foo(no_such_type) +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION IF EXISTS foo(no_such_type)" +== 126 +-- truncate_limit: 100 +DROP FUNCTION IF EXISTS foo(no_such_schema.no_such_type) +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION IF EXISTS foo(no_such_schema.no_such_type)" +== 127 +-- truncate_limit: 100 +DROP INDEX IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX IF EXISTS no_such_schema.foo" +== 128 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW IF EXISTS no_such_schema.foo" +== 129 +-- truncate_limit: 100 +DROP OPERATOR IF EXISTS no_such_schema.+ (int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR IF EXISTS no_such_schema.+(int, int)" +== 130 +-- truncate_limit: 100 +DROP OPERATOR IF EXISTS + (no_such_type, no_such_type) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR IF EXISTS +(no_such_type, no_such_type)" +== 131 +-- truncate_limit: 100 +DROP OPERATOR IF EXISTS + (no_such_schema.no_such_type, no_such_schema.no_such_type) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR IF EXISTS +(no_such_schema.no_such_type, no_such_schema.no_such_type)" +== 132 +-- truncate_limit: 100 +DROP OPERATOR IF EXISTS # (NONE, no_such_schema.no_such_type) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR IF EXISTS #(NONE, no_such_schema.no_such_type)" +== 133 +-- truncate_limit: 100 +DROP OPERATOR CLASS IF EXISTS no_such_schema.widget_ops USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS IF EXISTS no_such_schema.widget_ops USING btree" +== 134 +-- truncate_limit: 100 +DROP OPERATOR FAMILY IF EXISTS no_such_schema.float_ops USING btree +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR FAMILY IF EXISTS no_such_schema.float_ops USING btree" +== 135 +-- truncate_limit: 100 +DROP RULE IF EXISTS foo ON no_such_schema.bar +-- +TABLE: name="no_such_schema.bar" schema="no_such_schema" table="bar" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE IF EXISTS foo ON no_such_schema.bar" +== 136 +-- truncate_limit: 100 +DROP SEQUENCE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE IF EXISTS no_such_schema.foo" +== 137 +-- truncate_limit: 100 +DROP TABLE IF EXISTS no_such_schema.foo +-- +TABLE: name="no_such_schema.foo" schema="no_such_schema" table="foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE IF EXISTS no_such_schema.foo" +== 138 +-- truncate_limit: 100 +DROP TEXT SEARCH CONFIGURATION IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH CONFIGURATION IF EXISTS no_such_schema.foo" +== 139 +-- truncate_limit: 100 +DROP TEXT SEARCH DICTIONARY IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH DICTIONARY IF EXISTS no_such_schema.foo" +== 140 +-- truncate_limit: 100 +DROP TEXT SEARCH PARSER IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH PARSER IF EXISTS no_such_schema.foo" +== 141 +-- truncate_limit: 100 +DROP TEXT SEARCH TEMPLATE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH TEMPLATE IF EXISTS no_such_schema.foo" +== 142 +-- truncate_limit: 100 +DROP TRIGGER IF EXISTS foo ON no_such_schema.bar +-- +TABLE: name="no_such_schema.bar" schema="no_such_schema" table="bar" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER IF EXISTS foo ON no_such_schema.bar" +== 143 +-- truncate_limit: 100 +DROP TYPE IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE IF EXISTS no_such_schema.foo" +== 144 +-- truncate_limit: 100 +DROP VIEW IF EXISTS no_such_schema.foo +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW IF EXISTS no_such_schema.foo" +== 145 +-- truncate_limit: 100 +-- Check we receive an ambiguous function error when there are +-- multiple matching functions. +CREATE FUNCTION test_ambiguous_funcname(int) returns int as $$ select $1; $$ language sql +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_ambiguous_funcname(int) RETURNS int AS $$ select $1; $$ LANGUAGE sql" +== 146 +-- truncate_limit: 100 +CREATE FUNCTION test_ambiguous_funcname(text) returns text as $$ select $1; $$ language sql +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_ambiguous_funcname(text) RETURNS text AS $$ select $1; $$ LANGUAGE sql" +== 147 +-- truncate_limit: 100 +DROP FUNCTION test_ambiguous_funcname +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION test_ambiguous_funcname" +== 148 +-- truncate_limit: 100 +DROP FUNCTION IF EXISTS test_ambiguous_funcname +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION IF EXISTS test_ambiguous_funcname" +== 149 +-- truncate_limit: 100 +-- cleanup +DROP FUNCTION test_ambiguous_funcname(int) +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION test_ambiguous_funcname(int)" +== 150 +-- truncate_limit: 100 +DROP FUNCTION test_ambiguous_funcname(text) +-- +FUNCTION: name="test_ambiguous_funcname" function="test_ambiguous_funcname" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION test_ambiguous_funcname(text)" +== 151 +-- truncate_limit: 100 +-- Likewise for procedures. +CREATE PROCEDURE test_ambiguous_procname(int) as $$ begin end; $$ language plpgsql +-- +FUNCTION: name="test_ambiguous_procname" function="test_ambiguous_procname" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE test_ambiguous_procname(int) AS $$ begin end; $$ LANGUAGE plpgsql" +== 152 +-- truncate_limit: 100 +CREATE PROCEDURE test_ambiguous_procname(text) as $$ begin end; $$ language plpgsql +-- +FUNCTION: name="test_ambiguous_procname" function="test_ambiguous_procname" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE test_ambiguous_procname(text) AS $$ begin end; $$ LANGUAGE plpgsql" +== 153 +-- truncate_limit: 100 +DROP PROCEDURE test_ambiguous_procname +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE test_ambiguous_procname" +== 154 +-- truncate_limit: 100 +DROP PROCEDURE IF EXISTS test_ambiguous_procname +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE IF EXISTS test_ambiguous_procname" +== 155 +-- truncate_limit: 100 +-- Check we get a similar error if we use ROUTINE instead of PROCEDURE. +DROP ROUTINE IF EXISTS test_ambiguous_procname +-- +STMT: DropStmt +TRUNCATED: "DROP ROUTINE IF EXISTS test_ambiguous_procname" +== 156 +-- truncate_limit: 100 +-- cleanup +DROP PROCEDURE test_ambiguous_procname(int) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE test_ambiguous_procname(int)" +== 157 +-- truncate_limit: 100 +DROP PROCEDURE test_ambiguous_procname(text) +-- +STMT: DropStmt +TRUNCATED: "DROP PROCEDURE test_ambiguous_procname(text)" +== 158 +-- truncate_limit: 100 +-- This test checks both the functionality of 'if exists' and the syntax +-- of the drop database command. +drop database test_database_exists (force) +-- +STMT: DropdbStmt +TRUNCATED: "DROP DATABASE test_database_exists (FORCE)" +== 159 +-- truncate_limit: 100 +drop database test_database_exists with (force) +-- +STMT: DropdbStmt +TRUNCATED: "DROP DATABASE test_database_exists (FORCE)" +== 160 +-- truncate_limit: 100 +drop database if exists test_database_exists (force) +-- +STMT: DropdbStmt +TRUNCATED: "DROP DATABASE IF EXISTS test_database_exists (FORCE)" +== 161 +-- truncate_limit: 100 +drop database if exists test_database_exists with (force) +-- +STMT: DropdbStmt +TRUNCATED: "DROP DATABASE IF EXISTS test_database_exists (FORCE)" diff --git a/parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json b/parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json new file mode 100644 index 0000000..bf73c3a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json @@ -0,0 +1,16 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/drop_operator.test b/parser/testdata/summary_truncate/postgres_regress/drop_operator.test new file mode 100644 index 0000000..defeca5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/drop_operator.test @@ -0,0 +1,133 @@ +== 001 +-- truncate_limit: 100 +CREATE OPERATOR === ( + PROCEDURE = int8eq, + LEFTARG = bigint, + RIGHTARG = bigint, + COMMUTATOR = === +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (procedure = int8eq, leftarg = bigint, rightarg = bigint, commutator = ===)" +== 002 +-- truncate_limit: 100 +CREATE OPERATOR !== ( + PROCEDURE = int8ne, + LEFTARG = bigint, + RIGHTARG = bigint, + NEGATOR = ===, + COMMUTATOR = !== +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR !== (procedure = int8ne, leftarg = bigint, rightarg = bigint, negator = ===, comm..." +== 003 +-- truncate_limit: 100 +DROP OPERATOR !==(bigint, bigint) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR !==(bigint, bigint)" +== 004 +-- truncate_limit: 100 +SELECT ctid, oprcom +FROM pg_catalog.pg_operator fk +WHERE oprcom != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprcom" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprcom" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, oprcom FROM pg_catalog.pg_operator fk WHERE ..." +== 005 +-- truncate_limit: 100 +SELECT ctid, oprnegate +FROM pg_catalog.pg_operator fk +WHERE oprnegate != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprnegate" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprnegate" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, oprnegate FROM pg_catalog.pg_operator fk WHERE ..." +== 006 +-- truncate_limit: 100 +DROP OPERATOR ===(bigint, bigint) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ===(bigint, bigint)" +== 007 +-- truncate_limit: 100 +CREATE OPERATOR <| ( + PROCEDURE = int8lt, + LEFTARG = bigint, + RIGHTARG = bigint +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR <| (procedure = int8lt, leftarg = bigint, rightarg = bigint)" +== 008 +-- truncate_limit: 100 +CREATE OPERATOR |> ( + PROCEDURE = int8gt, + LEFTARG = bigint, + RIGHTARG = bigint, + NEGATOR = <|, + COMMUTATOR = <| +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR |> (procedure = int8gt, leftarg = bigint, rightarg = bigint, negator = <|, commut..." +== 009 +-- truncate_limit: 100 +DROP OPERATOR |>(bigint, bigint) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR |>(bigint, bigint)" +== 010 +-- truncate_limit: 100 +SELECT ctid, oprcom +FROM pg_catalog.pg_operator fk +WHERE oprcom != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprcom" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprcom" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, oprcom FROM pg_catalog.pg_operator fk WHERE ..." +== 011 +-- truncate_limit: 100 +SELECT ctid, oprnegate +FROM pg_catalog.pg_operator fk +WHERE oprnegate != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate) +-- +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +TABLE: name="pg_catalog.pg_operator" schema="pg_catalog" table="pg_operator" ctx=Select +ALIAS: "fk"="pg_catalog.pg_operator" +ALIAS: "pk"="pg_catalog.pg_operator" +FILTER: schema="" table="" column="oprnegate" +FILTER: schema="" table="pk" column="oid" +FILTER: schema="" table="fk" column="oprnegate" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, oprnegate FROM pg_catalog.pg_operator fk WHERE ..." +== 012 +-- truncate_limit: 100 +DROP OPERATOR <|(bigint, bigint) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR <|(bigint, bigint)" diff --git a/parser/testdata/summary_truncate/postgres_regress/enum.metadata.json b/parser/testdata/summary_truncate/postgres_regress/enum.metadata.json new file mode 100644 index 0000000..6f770d9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/enum.metadata.json @@ -0,0 +1,174 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/enum.test b/parser/testdata/summary_truncate/postgres_regress/enum.test new file mode 100644 index 0000000..68e413c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/enum.test @@ -0,0 +1,1267 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Enum tests +|-- + +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple')" +== 002 +-- truncate_limit: 100 +|-- +-- Did it create the right number of rows? +|-- +SELECT COUNT(*) FROM pg_enum WHERE enumtypid = 'rainbow'::regtype +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_enum WHERE enumtypid = 'rainbow'::regtype" +== 003 +-- truncate_limit: 100 +|-- +-- I/O functions +|-- +SELECT 'red'::rainbow +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'red'::rainbow" +== 004 +-- truncate_limit: 100 +SELECT 'mauve'::rainbow +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'mauve'::rainbow" +== 005 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('red', 'rainbow') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('red', 'rainbow')" +== 006 +-- truncate_limit: 100 +SELECT pg_input_is_valid('mauve', 'rainbow') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('mauve', 'rainbow')" +== 007 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('mauve', 'rainbow') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('mauve', 'rainbow')" +== 008 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info(repeat('too_long', 32), 'rainbow') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info(repeat('too_long', 32), 'rainbow')" +== 009 +-- truncate_limit: 100 +|-- +-- adding new values +|-- + +CREATE TYPE planets AS ENUM ( 'venus', 'earth', 'mars' ) +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE planets AS ENUM ('venus', 'earth', 'mars')" +== 010 +-- truncate_limit: 100 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT enumlabel, enumsortorder FROM pg_enum WHERE enumtypid = 'planets'::regtype ORDER BY 2" +== 011 +-- truncate_limit: 100 +ALTER TYPE planets ADD VALUE 'uranus' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'uranus'" +== 012 +-- truncate_limit: 100 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT enumlabel, enumsortorder FROM pg_enum WHERE enumtypid = 'planets'::regtype ORDER BY 2" +== 013 +-- truncate_limit: 100 +ALTER TYPE planets ADD VALUE 'mercury' BEFORE 'venus' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'mercury' BEFORE 'venus'" +== 014 +-- truncate_limit: 100 +ALTER TYPE planets ADD VALUE 'saturn' BEFORE 'uranus' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'saturn' BEFORE 'uranus'" +== 015 +-- truncate_limit: 100 +ALTER TYPE planets ADD VALUE 'jupiter' AFTER 'mars' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'jupiter' AFTER 'mars'" +== 016 +-- truncate_limit: 100 +ALTER TYPE planets ADD VALUE 'neptune' AFTER 'uranus' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'neptune' AFTER 'uranus'" +== 017 +-- truncate_limit: 100 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT enumlabel, enumsortorder FROM pg_enum WHERE enumtypid = 'planets'::regtype ORDER BY 2" +== 018 +-- truncate_limit: 100 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY enumlabel::planets +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT enumlabel, enumsortorder FROM pg_enum WHERE ... ORDER BY enumlabel::planets" +== 019 +-- truncate_limit: 100 +-- errors for adding labels +ALTER TYPE planets ADD VALUE + 'plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopl..." +== 020 +-- truncate_limit: 100 +ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus'" +== 021 +-- truncate_limit: 100 +-- if not exists tests + +-- existing value gives error +ALTER TYPE planets ADD VALUE 'mercury' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE 'mercury'" +== 022 +-- truncate_limit: 100 +-- unless IF NOT EXISTS is specified +ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury'" +== 023 +-- truncate_limit: 100 +-- should be neptune, not mercury +SELECT enum_last(NULL::planets) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_last(NULL::planets)" +== 024 +-- truncate_limit: 100 +ALTER TYPE planets ADD VALUE IF NOT EXISTS 'pluto' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE planets ADD VALUE IF NOT EXISTS 'pluto'" +== 025 +-- truncate_limit: 100 +-- should be pluto, i.e. the new value +SELECT enum_last(NULL::planets) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_last(NULL::planets)" +== 026 +-- truncate_limit: 100 +|-- +-- Test inserting so many values that we have to renumber +|-- + +create type insenum as enum ('L1', 'L2') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE insenum AS ENUM ('L1', 'L2')" +== 027 +-- truncate_limit: 100 +alter type insenum add value 'i1' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i1' BEFORE 'L2'" +== 028 +-- truncate_limit: 100 +alter type insenum add value 'i2' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i2' BEFORE 'L2'" +== 029 +-- truncate_limit: 100 +alter type insenum add value 'i3' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i3' BEFORE 'L2'" +== 030 +-- truncate_limit: 100 +alter type insenum add value 'i4' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i4' BEFORE 'L2'" +== 031 +-- truncate_limit: 100 +alter type insenum add value 'i5' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i5' BEFORE 'L2'" +== 032 +-- truncate_limit: 100 +alter type insenum add value 'i6' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i6' BEFORE 'L2'" +== 033 +-- truncate_limit: 100 +alter type insenum add value 'i7' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i7' BEFORE 'L2'" +== 034 +-- truncate_limit: 100 +alter type insenum add value 'i8' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i8' BEFORE 'L2'" +== 035 +-- truncate_limit: 100 +alter type insenum add value 'i9' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i9' BEFORE 'L2'" +== 036 +-- truncate_limit: 100 +alter type insenum add value 'i10' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i10' BEFORE 'L2'" +== 037 +-- truncate_limit: 100 +alter type insenum add value 'i11' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i11' BEFORE 'L2'" +== 038 +-- truncate_limit: 100 +alter type insenum add value 'i12' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i12' BEFORE 'L2'" +== 039 +-- truncate_limit: 100 +alter type insenum add value 'i13' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i13' BEFORE 'L2'" +== 040 +-- truncate_limit: 100 +alter type insenum add value 'i14' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i14' BEFORE 'L2'" +== 041 +-- truncate_limit: 100 +alter type insenum add value 'i15' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i15' BEFORE 'L2'" +== 042 +-- truncate_limit: 100 +alter type insenum add value 'i16' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i16' BEFORE 'L2'" +== 043 +-- truncate_limit: 100 +alter type insenum add value 'i17' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i17' BEFORE 'L2'" +== 044 +-- truncate_limit: 100 +alter type insenum add value 'i18' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i18' BEFORE 'L2'" +== 045 +-- truncate_limit: 100 +alter type insenum add value 'i19' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i19' BEFORE 'L2'" +== 046 +-- truncate_limit: 100 +alter type insenum add value 'i20' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i20' BEFORE 'L2'" +== 047 +-- truncate_limit: 100 +alter type insenum add value 'i21' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i21' BEFORE 'L2'" +== 048 +-- truncate_limit: 100 +alter type insenum add value 'i22' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i22' BEFORE 'L2'" +== 049 +-- truncate_limit: 100 +alter type insenum add value 'i23' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i23' BEFORE 'L2'" +== 050 +-- truncate_limit: 100 +alter type insenum add value 'i24' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i24' BEFORE 'L2'" +== 051 +-- truncate_limit: 100 +alter type insenum add value 'i25' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i25' BEFORE 'L2'" +== 052 +-- truncate_limit: 100 +alter type insenum add value 'i26' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i26' BEFORE 'L2'" +== 053 +-- truncate_limit: 100 +alter type insenum add value 'i27' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i27' BEFORE 'L2'" +== 054 +-- truncate_limit: 100 +alter type insenum add value 'i28' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i28' BEFORE 'L2'" +== 055 +-- truncate_limit: 100 +alter type insenum add value 'i29' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i29' BEFORE 'L2'" +== 056 +-- truncate_limit: 100 +alter type insenum add value 'i30' before 'L2' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE insenum ADD VALUE 'i30' BEFORE 'L2'" +== 057 +-- truncate_limit: 100 +-- The exact values of enumsortorder will now depend on the local properties +-- of float4, but in any reasonable implementation we should get at least +-- 20 splits before having to renumber; so only hide values > 20. + +SELECT enumlabel, + case when enumsortorder > 20 then null else enumsortorder end as so +FROM pg_enum +WHERE enumtypid = 'insenum'::regtype +ORDER BY enumsortorder +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_enum WHERE enumtypid = 'insenum'::regtype ORDER BY enumsortorder" +== 058 +-- truncate_limit: 100 +|-- +-- Basic table creation, row selection +|-- +CREATE TABLE enumtest (col rainbow) +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE enumtest (col rainbow)" +== 059 +-- truncate_limit: 100 +INSERT INTO enumtest values ('red'), ('orange'), ('yellow'), ('green') +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO enumtest VALUES ('red'), ('orange'), ('yellow'), ('green')" +== 060 +-- truncate_limit: 100 +COPY enumtest FROM stdin +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY enumtest FROM STDIN" +== 061 +-- truncate_limit: 100 +SELECT * FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest" +== 062 +-- truncate_limit: 100 +|-- +-- Operators, no index +|-- +SELECT * FROM enumtest WHERE col = 'orange' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col = 'orange'" +== 063 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col" +== 064 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col" +== 065 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col" +== 066 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col < 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col < 'green' ORDER BY col" +== 067 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col" +== 068 +-- truncate_limit: 100 +|-- +-- Cast to/from text +|-- +SELECT 'red'::rainbow::text || 'hithere' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'red'::rainbow::text || 'hithere'" +== 069 +-- truncate_limit: 100 +SELECT 'red'::text::rainbow = 'red'::rainbow +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'red'::text::rainbow = 'red'::rainbow" +== 070 +-- truncate_limit: 100 +|-- +-- Aggregates +|-- +SELECT min(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(col) FROM enumtest" +== 071 +-- truncate_limit: 100 +SELECT max(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(col) FROM enumtest" +== 072 +-- truncate_limit: 100 +SELECT max(col) FROM enumtest WHERE col < 'green' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT max(col) FROM enumtest WHERE col < 'green'" +== 073 +-- truncate_limit: 100 +|-- +-- Index tests, force use of index +|-- +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 074 +-- truncate_limit: 100 +SET enable_bitmapscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 075 +-- truncate_limit: 100 +|-- +-- Btree index / opclass with the various operators +|-- +CREATE UNIQUE INDEX enumtest_btree ON enumtest USING btree (col) +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX enumtest_btree ON enumtest USING btree (col)" +== 076 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col = 'orange' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col = 'orange'" +== 077 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col" +== 078 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col" +== 079 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col" +== 080 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col < 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col < 'green' ORDER BY col" +== 081 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col" +== 082 +-- truncate_limit: 100 +SELECT min(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(col) FROM enumtest" +== 083 +-- truncate_limit: 100 +SELECT max(col) FROM enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(col) FROM enumtest" +== 084 +-- truncate_limit: 100 +SELECT max(col) FROM enumtest WHERE col < 'green' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT max(col) FROM enumtest WHERE col < 'green'" +== 085 +-- truncate_limit: 100 +DROP INDEX enumtest_btree +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX enumtest_btree" +== 086 +-- truncate_limit: 100 +|-- +-- Hash index / opclass with the = operator +|-- +CREATE INDEX enumtest_hash ON enumtest USING hash (col) +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX enumtest_hash ON enumtest USING hash (col)" +== 087 +-- truncate_limit: 100 +SELECT * FROM enumtest WHERE col = 'orange' +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=Select +FILTER: schema="" table="" column="col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM enumtest WHERE col = 'orange'" +== 088 +-- truncate_limit: 100 +DROP INDEX enumtest_hash +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX enumtest_hash" +== 089 +-- truncate_limit: 100 +|-- +-- End index tests +|-- +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 090 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 091 +-- truncate_limit: 100 +|-- +-- Domains over enums +|-- +CREATE DOMAIN rgb AS rainbow CHECK (VALUE IN ('red', 'green', 'blue')) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN rgb AS rainbow CHECK (value IN ('red', 'green', 'blue'))" +== 092 +-- truncate_limit: 100 +SELECT 'red'::rgb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'red'::rgb" +== 093 +-- truncate_limit: 100 +SELECT 'purple'::rgb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'purple'::rgb" +== 094 +-- truncate_limit: 100 +SELECT 'purple'::rainbow::rgb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'purple'::rainbow::rgb" +== 095 +-- truncate_limit: 100 +DROP DOMAIN rgb +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN rgb" +== 096 +-- truncate_limit: 100 +|-- +-- Arrays +|-- +SELECT '{red,green,blue}'::rainbow[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{red,green,blue}'::rainbow[]" +== 097 +-- truncate_limit: 100 +SELECT ('{red,green,blue}'::rainbow[])[2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{red,green,blue}'::rainbow[])[2]" +== 098 +-- truncate_limit: 100 +SELECT 'red' = ANY ('{red,green,blue}'::rainbow[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'red' = ANY('{red,green,blue}'::rainbow[])" +== 099 +-- truncate_limit: 100 +SELECT 'yellow' = ANY ('{red,green,blue}'::rainbow[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'yellow' = ANY('{red,green,blue}'::rainbow[])" +== 100 +-- truncate_limit: 100 +SELECT 'red' = ALL ('{red,green,blue}'::rainbow[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'red' = ALL('{red,green,blue}'::rainbow[])" +== 101 +-- truncate_limit: 100 +SELECT 'red' = ALL ('{red,red}'::rainbow[]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'red' = ALL('{red,red}'::rainbow[])" +== 102 +-- truncate_limit: 100 +|-- +-- Support functions +|-- +SELECT enum_first(NULL::rainbow) +-- +FUNCTION: name="enum_first" function="enum_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_first(NULL::rainbow)" +== 103 +-- truncate_limit: 100 +SELECT enum_last('green'::rainbow) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_last('green'::rainbow)" +== 104 +-- truncate_limit: 100 +SELECT enum_range(NULL::rainbow) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range(NULL::rainbow)" +== 105 +-- truncate_limit: 100 +SELECT enum_range('orange'::rainbow, 'green'::rainbow) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range('orange'::rainbow, 'green'::rainbow)" +== 106 +-- truncate_limit: 100 +SELECT enum_range(NULL, 'green'::rainbow) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range(NULL, 'green'::rainbow)" +== 107 +-- truncate_limit: 100 +SELECT enum_range('orange'::rainbow, NULL) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range('orange'::rainbow, NULL)" +== 108 +-- truncate_limit: 100 +SELECT enum_range(NULL::rainbow, NULL) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range(NULL::rainbow, NULL)" +== 109 +-- truncate_limit: 100 +|-- +-- User functions, can't test perl/python etc here since may not be compiled. +|-- +CREATE FUNCTION echo_me(anyenum) RETURNS text AS $$ +BEGIN +RETURN $1::text || 'omg'; +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION echo_me(anyenum) RETURNS text AS $$\nBEGIN\nRETURN $1::text || 'omg';\nEND\n$$ LANGUA..." +== 110 +-- truncate_limit: 100 +SELECT echo_me('red'::rainbow) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT echo_me('red'::rainbow)" +== 111 +-- truncate_limit: 100 +|-- +-- Concrete function should override generic one +|-- +CREATE FUNCTION echo_me(rainbow) RETURNS text AS $$ +BEGIN +RETURN $1::text || 'wtf'; +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION echo_me(rainbow) RETURNS text AS $$\nBEGIN\nRETURN $1::text || 'wtf';\nEND\n$$ LANGUA..." +== 112 +-- truncate_limit: 100 +SELECT echo_me('red'::rainbow) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT echo_me('red'::rainbow)" +== 113 +-- truncate_limit: 100 +|-- +-- If we drop the original generic one, we don't have to qualify the type +-- anymore, since there's only one match +|-- +DROP FUNCTION echo_me(anyenum) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION echo_me(anyenum)" +== 114 +-- truncate_limit: 100 +SELECT echo_me('red') +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT echo_me('red')" +== 115 +-- truncate_limit: 100 +DROP FUNCTION echo_me(rainbow) +-- +FUNCTION: name="echo_me" function="echo_me" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION echo_me(rainbow)" +== 116 +-- truncate_limit: 100 +|-- +-- RI triggers on enum types +|-- +CREATE TABLE enumtest_parent (id rainbow PRIMARY KEY) +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE enumtest_parent (id rainbow PRIMARY KEY)" +== 117 +-- truncate_limit: 100 +CREATE TABLE enumtest_child (parent rainbow REFERENCES enumtest_parent) +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE enumtest_child (parent rainbow REFERENCES enumtest_parent)" +== 118 +-- truncate_limit: 100 +INSERT INTO enumtest_parent VALUES ('red') +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO enumtest_parent VALUES ('red')" +== 119 +-- truncate_limit: 100 +INSERT INTO enumtest_child VALUES ('red') +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO enumtest_child VALUES ('red')" +== 120 +-- truncate_limit: 100 +INSERT INTO enumtest_child VALUES ('blue') +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO enumtest_child VALUES ('blue')" +== 121 +-- truncate_limit: 100 +-- fail +DELETE FROM enumtest_parent +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM enumtest_parent" +== 122 +-- truncate_limit: 100 +-- fail +|-- +-- cross-type RI should fail +|-- +CREATE TYPE bogus AS ENUM('good', 'bad', 'ugly') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE bogus AS ENUM ('good', 'bad', 'ugly')" +== 123 +-- truncate_limit: 100 +CREATE TABLE enumtest_bogus_child(parent bogus REFERENCES enumtest_parent) +-- +TABLE: name="enumtest_bogus_child" schema="" table="enumtest_bogus_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE enumtest_bogus_child (parent bogus REFERENCES enumtest_parent)" +== 124 +-- truncate_limit: 100 +DROP TYPE bogus +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE bogus" +== 125 +-- truncate_limit: 100 +-- check renaming a value +ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson'" +== 126 +-- truncate_limit: 100 +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'rainbow'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT enumlabel, enumsortorder FROM pg_enum WHERE enumtypid = 'rainbow'::regtype ORDER BY 2" +== 127 +-- truncate_limit: 100 +-- check that renaming a non-existent value fails +ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson'" +== 128 +-- truncate_limit: 100 +-- check that renaming to an existent value fails +ALTER TYPE rainbow RENAME VALUE 'blue' TO 'green' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE rainbow RENAME VALUE 'blue' TO 'green'" +== 129 +-- truncate_limit: 100 +|-- +-- check transactional behaviour of ALTER TYPE ... ADD VALUE +|-- +CREATE TYPE bogus AS ENUM('good') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE bogus AS ENUM ('good')" +== 130 +-- truncate_limit: 100 +-- check that we can add new values to existing enums in a transaction +-- but we can't use them +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 131 +-- truncate_limit: 100 +ALTER TYPE bogus ADD VALUE 'new' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE bogus ADD VALUE 'new'" +== 132 +-- truncate_limit: 100 +SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 133 +-- truncate_limit: 100 +SELECT 'new'::bogus +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'new'::bogus" +== 134 +-- truncate_limit: 100 +-- unsafe +ROLLBACK TO x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 135 +-- truncate_limit: 100 +SELECT enum_first(null::bogus) +-- +FUNCTION: name="enum_first" function="enum_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_first(NULL::bogus)" +== 136 +-- truncate_limit: 100 +-- safe +SELECT enum_last(null::bogus) +-- +FUNCTION: name="enum_last" function="enum_last" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_last(NULL::bogus)" +== 137 +-- truncate_limit: 100 +-- unsafe +ROLLBACK TO x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 138 +-- truncate_limit: 100 +SELECT enum_range(null::bogus) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range(NULL::bogus)" +== 139 +-- truncate_limit: 100 +-- unsafe +ROLLBACK TO x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 140 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 141 +-- truncate_limit: 100 +SELECT 'new'::bogus +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'new'::bogus" +== 142 +-- truncate_limit: 100 +-- now safe +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'bogus'::regtype +ORDER BY 2 +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT enumlabel, enumsortorder FROM pg_enum WHERE enumtypid = 'bogus'::regtype ORDER BY 2" +== 143 +-- truncate_limit: 100 +-- check that we recognize the case where the enum already existed but was +-- modified in the current txn; this should not be considered safe +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 144 +-- truncate_limit: 100 +ALTER TYPE bogus RENAME TO bogon +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE bogus RENAME TO bogon" +== 145 +-- truncate_limit: 100 +ALTER TYPE bogon ADD VALUE 'bad' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE bogon ADD VALUE 'bad'" +== 146 +-- truncate_limit: 100 +SELECT 'bad'::bogon +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bad'::bogon" +== 147 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 148 +-- truncate_limit: 100 +-- but a renamed value is safe to use later in same transaction +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 149 +-- truncate_limit: 100 +ALTER TYPE bogus RENAME VALUE 'good' to 'bad' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE bogus RENAME VALUE 'good' TO 'bad'" +== 150 +-- truncate_limit: 100 +SELECT 'bad'::bogus +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bad'::bogus" +== 151 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 152 +-- truncate_limit: 100 +DROP TYPE bogus +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE bogus" +== 153 +-- truncate_limit: 100 +-- check that values created during CREATE TYPE can be used in any case +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 154 +-- truncate_limit: 100 +CREATE TYPE bogus AS ENUM('good','bad','ugly') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE bogus AS ENUM ('good', 'bad', 'ugly')" +== 155 +-- truncate_limit: 100 +ALTER TYPE bogus RENAME TO bogon +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE bogus RENAME TO bogon" +== 156 +-- truncate_limit: 100 +select enum_range(null::bogon) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range(NULL::bogon)" +== 157 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 158 +-- truncate_limit: 100 +-- we must allow this usage to support pg_dump in binary upgrade mode +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 159 +-- truncate_limit: 100 +CREATE TYPE bogus AS ENUM('good') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE bogus AS ENUM ('good')" +== 160 +-- truncate_limit: 100 +ALTER TYPE bogus RENAME TO bogon +-- +STMT: RenameStmt +TRUNCATED: "ALTER TYPE bogus RENAME TO bogon" +== 161 +-- truncate_limit: 100 +ALTER TYPE bogon ADD VALUE 'bad' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE bogon ADD VALUE 'bad'" +== 162 +-- truncate_limit: 100 +ALTER TYPE bogon ADD VALUE 'ugly' +-- +STMT: AlterEnumStmt +TRUNCATED: "ALTER TYPE bogon ADD VALUE 'ugly'" +== 163 +-- truncate_limit: 100 +select enum_range(null::bogon) +-- +FUNCTION: name="enum_range" function="enum_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT enum_range(NULL::bogon)" +== 164 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 165 +-- truncate_limit: 100 +|-- +-- Cleanup +|-- +DROP TABLE enumtest_child +-- +TABLE: name="enumtest_child" schema="" table="enumtest_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE enumtest_child" +== 166 +-- truncate_limit: 100 +DROP TABLE enumtest_parent +-- +TABLE: name="enumtest_parent" schema="" table="enumtest_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE enumtest_parent" +== 167 +-- truncate_limit: 100 +DROP TABLE enumtest +-- +TABLE: name="enumtest" schema="" table="enumtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE enumtest" +== 168 +-- truncate_limit: 100 +DROP TYPE rainbow +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE rainbow" +== 169 +-- truncate_limit: 100 +|-- +-- Verify properly cleaned up +|-- +SELECT COUNT(*) FROM pg_type WHERE typname = 'rainbow' +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="typname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_type WHERE typname = 'rainbow'" +== 170 +-- truncate_limit: 100 +SELECT * FROM pg_enum WHERE NOT EXISTS + (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid) +-- +TABLE: name="pg_enum" schema="" table="pg_enum" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +FILTER: schema="" table="pg_type" column="oid" +FILTER: schema="" table="" column="enumtypid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_enum WHERE NOT EXISTS (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid)" diff --git a/parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json b/parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json new file mode 100644 index 0000000..364fcc5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json @@ -0,0 +1,83 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/equivclass.test b/parser/testdata/summary_truncate/postgres_regress/equivclass.test new file mode 100644 index 0000000..22fdbb4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/equivclass.test @@ -0,0 +1,798 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for the planner's "equivalence class" mechanism +|-- + +-- One thing that's not tested well during normal querying is the logic +-- for handling "broken" ECs. This is because an EC can only become broken +-- if its underlying btree operator family doesn't include a complete set +-- of cross-type equality operators. There are not (and should not be) +-- any such families built into Postgres; so we have to hack things up +-- to create one. We do this by making two alias types that are really +-- int8 (so we need no new C code) and adding only some operators for them +-- into the standard integer_ops opfamily. + +create type int8alias1 +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE int8alias1" +== 002 +-- truncate_limit: 100 +create function int8alias1in(cstring) returns int8alias1 + strict immutable language internal as 'int8in' +-- +FUNCTION: name="int8alias1in" function="int8alias1in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias1in(cstring) RETURNS int8alias1 RETURNS NULL ON NULL INPUT IMMUTABLE LAN..." +== 003 +-- truncate_limit: 100 +create function int8alias1out(int8alias1) returns cstring + strict immutable language internal as 'int8out' +-- +FUNCTION: name="int8alias1out" function="int8alias1out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias1out(int8alias1) RETURNS cstring RETURNS NULL ON NULL INPUT IMMUTABLE LA..." +== 004 +-- truncate_limit: 100 +create type int8alias1 ( + input = int8alias1in, + output = int8alias1out, + like = int8 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE int8alias1 (input = int8alias1in, output = int8alias1out, \"like\" = int8)" +== 005 +-- truncate_limit: 100 +create type int8alias2 +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE int8alias2" +== 006 +-- truncate_limit: 100 +create function int8alias2in(cstring) returns int8alias2 + strict immutable language internal as 'int8in' +-- +FUNCTION: name="int8alias2in" function="int8alias2in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias2in(cstring) RETURNS int8alias2 RETURNS NULL ON NULL INPUT IMMUTABLE LAN..." +== 007 +-- truncate_limit: 100 +create function int8alias2out(int8alias2) returns cstring + strict immutable language internal as 'int8out' +-- +FUNCTION: name="int8alias2out" function="int8alias2out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias2out(int8alias2) RETURNS cstring RETURNS NULL ON NULL INPUT IMMUTABLE LA..." +== 008 +-- truncate_limit: 100 +create type int8alias2 ( + input = int8alias2in, + output = int8alias2out, + like = int8 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE int8alias2 (input = int8alias2in, output = int8alias2out, \"like\" = int8)" +== 009 +-- truncate_limit: 100 +create cast (int8 as int8alias1) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int8 AS int8alias1) WITHOUT FUNCTION" +== 010 +-- truncate_limit: 100 +create cast (int8 as int8alias2) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int8 AS int8alias2) WITHOUT FUNCTION" +== 011 +-- truncate_limit: 100 +create cast (int8alias1 as int8) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int8alias1 AS int8) WITHOUT FUNCTION" +== 012 +-- truncate_limit: 100 +create cast (int8alias2 as int8) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int8alias2 AS int8) WITHOUT FUNCTION" +== 013 +-- truncate_limit: 100 +create function int8alias1eq(int8alias1, int8alias1) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias1eq" function="int8alias1eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias1eq(int8alias1, int8alias1) RETURNS bool RETURNS NULL ON NULL INPUT IMMU..." +== 014 +-- truncate_limit: 100 +create operator = ( + procedure = int8alias1eq, + leftarg = int8alias1, rightarg = int8alias1, + commutator = =, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (procedure = int8alias1eq, leftarg = int8alias1, rightarg = int8alias1, commuta..." +== 015 +-- truncate_limit: 100 +alter operator family integer_ops using btree add + operator 3 = (int8alias1, int8alias1) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY integer_ops USING btree ADD OPERATOR 3 =(int8alias1, int8alias1)" +== 016 +-- truncate_limit: 100 +create function int8alias2eq(int8alias2, int8alias2) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias2eq" function="int8alias2eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias2eq(int8alias2, int8alias2) RETURNS bool RETURNS NULL ON NULL INPUT IMMU..." +== 017 +-- truncate_limit: 100 +create operator = ( + procedure = int8alias2eq, + leftarg = int8alias2, rightarg = int8alias2, + commutator = =, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (procedure = int8alias2eq, leftarg = int8alias2, rightarg = int8alias2, commuta..." +== 018 +-- truncate_limit: 100 +alter operator family integer_ops using btree add + operator 3 = (int8alias2, int8alias2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY integer_ops USING btree ADD OPERATOR 3 =(int8alias2, int8alias2)" +== 019 +-- truncate_limit: 100 +create function int8alias1eq(int8, int8alias1) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias1eq" function="int8alias1eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias1eq(int8, int8alias1) RETURNS bool RETURNS NULL ON NULL INPUT IMMUTABLE ..." +== 020 +-- truncate_limit: 100 +create operator = ( + procedure = int8alias1eq, + leftarg = int8, rightarg = int8alias1, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (procedure = int8alias1eq, leftarg = int8, rightarg = int8alias1, restrict = eq..." +== 021 +-- truncate_limit: 100 +alter operator family integer_ops using btree add + operator 3 = (int8, int8alias1) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY integer_ops USING btree ADD OPERATOR 3 =(int8, int8alias1)" +== 022 +-- truncate_limit: 100 +create function int8alias1eq(int8alias1, int8alias2) returns bool + strict immutable language internal as 'int8eq' +-- +FUNCTION: name="int8alias1eq" function="int8alias1eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias1eq(int8alias1, int8alias2) RETURNS bool RETURNS NULL ON NULL INPUT IMMU..." +== 023 +-- truncate_limit: 100 +create operator = ( + procedure = int8alias1eq, + leftarg = int8alias1, rightarg = int8alias2, + restrict = eqsel, join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (procedure = int8alias1eq, leftarg = int8alias1, rightarg = int8alias2, restric..." +== 024 +-- truncate_limit: 100 +alter operator family integer_ops using btree add + operator 3 = (int8alias1, int8alias2) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY integer_ops USING btree ADD OPERATOR 3 =(int8alias1, int8alias2)" +== 025 +-- truncate_limit: 100 +create function int8alias1lt(int8alias1, int8alias1) returns bool + strict immutable language internal as 'int8lt' +-- +FUNCTION: name="int8alias1lt" function="int8alias1lt" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias1lt(int8alias1, int8alias1) RETURNS bool RETURNS NULL ON NULL INPUT IMMU..." +== 026 +-- truncate_limit: 100 +create operator < ( + procedure = int8alias1lt, + leftarg = int8alias1, rightarg = int8alias1 +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR < (procedure = int8alias1lt, leftarg = int8alias1, rightarg = int8alias1)" +== 027 +-- truncate_limit: 100 +alter operator family integer_ops using btree add + operator 1 < (int8alias1, int8alias1) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY integer_ops USING btree ADD OPERATOR 1 <(int8alias1, int8alias1)" +== 028 +-- truncate_limit: 100 +create function int8alias1cmp(int8, int8alias1) returns int + strict immutable language internal as 'btint8cmp' +-- +FUNCTION: name="int8alias1cmp" function="int8alias1cmp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION int8alias1cmp(int8, int8alias1) RETURNS int RETURNS NULL ON NULL INPUT IMMUTABLE ..." +== 029 +-- truncate_limit: 100 +alter operator family integer_ops using btree add + function 1 int8alias1cmp (int8, int8alias1) +-- +STMT: AlterOpFamilyStmt +TRUNCATED: "ALTER OPERATOR FAMILY integer_ops USING btree ADD FUNCTION 1 int8alias1cmp(int8, int8alias1)" +== 030 +-- truncate_limit: 100 +create table ec0 (ff int8 primary key, f1 int8, f2 int8) +-- +TABLE: name="ec0" schema="" table="ec0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ec0 (ff int8 PRIMARY KEY, f1 int8, f2 int8)" +== 031 +-- truncate_limit: 100 +create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ec1 (ff int8 PRIMARY KEY, f1 int8alias1, f2 int8alias2)" +== 032 +-- truncate_limit: 100 +create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2) +-- +TABLE: name="ec2" schema="" table="ec2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ec2 (xf int8 PRIMARY KEY, x1 int8alias1, x2 int8alias2)" +== 033 +-- truncate_limit: 100 +-- for the moment we only want to look at nestloop plans +set enable_hashjoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 034 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 035 +-- truncate_limit: 100 +|-- +-- Note that for cases where there's a missing operator, we don't care so +-- much whether the plan is ideal as that we don't fail or generate an +-- outright incorrect plan. +|-- + +explain (costs off) + select * from ec0 where ff = f1 and f1 = '42'::int8 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec0 WHERE ff = f1 AND f1 = '42'::int8" +== 036 +-- truncate_limit: 100 +explain (costs off) + select * from ec0 where ff = f1 and f1 = '42'::int8alias1 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec0 WHERE ff = f1 AND f1 = '42'::int8alias1" +== 037 +-- truncate_limit: 100 +explain (costs off) + select * from ec1 where ff = f1 and f1 = '42'::int8alias1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1 WHERE ff = f1 AND f1 = '42'::int8alias1" +== 038 +-- truncate_limit: 100 +explain (costs off) + select * from ec1 where ff = f1 and f1 = '42'::int8alias2 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1 WHERE ff = f1 AND f1 = '42'::int8alias2" +== 039 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, ec2 where ff = x1 and ff = '42'::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, ec2 WHERE ff = x1 AND ff = '42'::int8" +== 040 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, ec2 where ff = x1 and ff = '42'::int8alias1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, ec2 WHERE ff = x1 AND ff = '42'::int8alias1" +== 041 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, ec2 where ff = x1 and '42'::int8 = x1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, ec2 WHERE ff = x1 AND '42'::int8 = x1" +== 042 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, ec2 WHERE ff = x1 AND x1 = '42'::int8alias1" +== 043 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias2 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec2" schema="" table="ec2" ctx=Select +FILTER: schema="" table="" column="ff" +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, ec2 WHERE ff = x1 AND x1 = '42'::int8alias2" +== 044 +-- truncate_limit: 100 +create unique index ec1_expr1 on ec1((ff + 1)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ec1_expr1 ON ec1 USING btree ((ff + 1))" +== 045 +-- truncate_limit: 100 +create unique index ec1_expr2 on ec1((ff + 2 + 1)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ec1_expr2 ON ec1 USING btree (((ff + 2) + 1))" +== 046 +-- truncate_limit: 100 +create unique index ec1_expr3 on ec1((ff + 3 + 1)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ec1_expr3 ON ec1 USING btree (((ff + 3) + 1))" +== 047 +-- truncate_limit: 100 +create unique index ec1_expr4 on ec1((ff + 4)) +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ec1_expr4 ON ec1 USING btree ((ff + 4))" +== 048 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, (SELECT ff + 1 AS x FROM (SELECT ff + 2 AS ff FROM ec1 UNI..." +== 049 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 and ec1.ff = ec1.f1 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +FILTER: schema="" table="ec1" column="ff" +FILTER: schema="" table="ec1" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, (SELECT ff + 1 AS x FROM (SELECT ff + 2 AS ff FROM ec1 UNI..." +== 050 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss2 + where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ss2" column="x" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, (SELECT ff + 1 AS x FROM (SELECT ff + 2 AS ff FROM ec1 UNI..." +== 051 +-- truncate_limit: 100 +-- let's try that as a mergejoin +set enable_mergejoin = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO ON" +== 052 +-- truncate_limit: 100 +set enable_nestloop = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 053 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss2 + where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ss2" column="x" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, (SELECT ff + 1 AS x FROM (SELECT ff + 2 AS ff FROM ec1 UNI..." +== 054 +-- truncate_limit: 100 +-- check partially indexed scan +set enable_nestloop = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO ON" +== 055 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 056 +-- truncate_limit: 100 +drop index ec1_expr3 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX ec1_expr3" +== 057 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, (SELECT ff + 1 AS x FROM (SELECT ff + 2 AS ff FROM ec1 UNI..." +== 058 +-- truncate_limit: 100 +-- let's try that as a mergejoin +set enable_mergejoin = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO ON" +== 059 +-- truncate_limit: 100 +set enable_nestloop = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 060 +-- truncate_limit: 100 +explain (costs off) + select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 +-- +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +FILTER: schema="" table="ss1" column="x" +FILTER: schema="" table="ec1" column="f1" +FILTER: schema="" table="ec1" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec1, (SELECT ff + 1 AS x FROM (SELECT ff + 2 AS ff FROM ec1 UNI..." +== 061 +-- truncate_limit: 100 +-- check effects of row-level security +set enable_nestloop = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO ON" +== 062 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 063 +-- truncate_limit: 100 +alter table ec1 enable row level security +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ec1 ENABLE ROW LEVEL SECURITY" +== 064 +-- truncate_limit: 100 +create policy p1 on ec1 using (f1 < '5'::int8alias1) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON ec1 TO public USING (f1 < '5'::int8alias1)" +== 065 +-- truncate_limit: 100 +create user regress_user_ectest +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_user_ectest" +== 066 +-- truncate_limit: 100 +grant select on ec0 to regress_user_ectest +-- +TABLE: name="ec0" schema="" table="ec0" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON ec0 TO regress_user_ectest" +== 067 +-- truncate_limit: 100 +grant select on ec1 to regress_user_ectest +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON ec1 TO regress_user_ectest" +== 068 +-- truncate_limit: 100 +-- without any RLS, we'll treat {a.ff, b.ff, 43} as an EquivalenceClass +explain (costs off) + select * from ec0 a, ec1 b + where a.ff = b.ff and a.ff = 43::bigint::int8alias1 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +ALIAS: "a"="ec0" +ALIAS: "b"="ec1" +FILTER: schema="" table="a" column="ff" +FILTER: schema="" table="b" column="ff" +FILTER: schema="" table="a" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec0 a, ec1 b WHERE a.ff = b.ff AND a.ff = 43::bigint::int8alias1" +== 069 +-- truncate_limit: 100 +set session authorization regress_user_ectest +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_user_ectest" +== 070 +-- truncate_limit: 100 +-- with RLS active, the non-leakproof a.ff = 43 clause is not treated +-- as a suitable source for an EquivalenceClass; currently, this is true +-- even though the RLS clause has nothing to do directly with the EC +explain (costs off) + select * from ec0 a, ec1 b + where a.ff = b.ff and a.ff = 43::bigint::int8alias1 +-- +TABLE: name="ec0" schema="" table="ec0" ctx=Select +TABLE: name="ec1" schema="" table="ec1" ctx=Select +ALIAS: "a"="ec0" +ALIAS: "b"="ec1" +FILTER: schema="" table="a" column="ff" +FILTER: schema="" table="b" column="ff" +FILTER: schema="" table="a" column="ff" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ec0 a, ec1 b WHERE a.ff = b.ff AND a.ff = 43::bigint::int8alias1" +== 071 +-- truncate_limit: 100 +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 072 +-- truncate_limit: 100 +revoke select on ec0 from regress_user_ectest +-- +TABLE: name="ec0" schema="" table="ec0" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select ON ec0 FROM regress_user_ectest" +== 073 +-- truncate_limit: 100 +revoke select on ec1 from regress_user_ectest +-- +TABLE: name="ec1" schema="" table="ec1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select ON ec1 FROM regress_user_ectest" +== 074 +-- truncate_limit: 100 +drop user regress_user_ectest +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_user_ectest" +== 075 +-- truncate_limit: 100 +-- check that X=X is converted to X IS NOT NULL when appropriate +explain (costs off) + select * from tenk1 where unique1 = unique1 and unique2 = unique2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE unique1 = unique1 AND unique2 = unique2" +== 076 +-- truncate_limit: 100 +-- this could be converted, but isn't at present +explain (costs off) + select * from tenk1 where unique1 = unique1 or unique2 = unique2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE unique1 = unique1 OR unique2 = unique2" +== 077 +-- truncate_limit: 100 +-- check that we recognize equivalence with dummy domains in the way +create temp table undername (f1 name, f2 int) +-- +TABLE: name="undername" schema="" table="undername" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE undername (f1 name, f2 int)" +== 078 +-- truncate_limit: 100 +create temp view overview as + select f1::information_schema.sql_identifier as sqli, f2 from undername +-- +TABLE: name="overview" schema="" table="overview" ctx=DDL +TABLE: name="undername" schema="" table="undername" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW overview AS SELECT f1::information_schema.sql_identifier AS sqli, f2 FROM u..." +== 079 +-- truncate_limit: 100 +explain (costs off) -- this should not require a sort + select * from overview where sqli = 'foo' order by sqli +-- +TABLE: name="overview" schema="" table="overview" ctx=Select +FILTER: schema="" table="" column="sqli" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM overview WHERE sqli = 'foo' ORDER BY sqli" diff --git a/parser/testdata/summary_truncate/postgres_regress/errors.metadata.json b/parser/testdata/summary_truncate/postgres_regress/errors.metadata.json new file mode 100644 index 0000000..b064cb7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/errors.metadata.json @@ -0,0 +1,89 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/errors.test b/parser/testdata/summary_truncate/postgres_regress/errors.test new file mode 100644 index 0000000..cdc361f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/errors.test @@ -0,0 +1,795 @@ +== 001 +-- truncate_limit: 100 +|-- +-- ERRORS +|-- + +-- bad in postquel, but ok in PostgreSQL +select 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1" +== 002 +-- truncate_limit: 100 +|-- +-- UNSUPPORTED STUFF + +-- doesn't work +-- notify pg_class +|-- + +|-- +-- SELECT + +-- this used to be a syntax error, but now we allow an empty target list +select +-- +STMT: SelectStmt +TRUNCATED: "SELECT" +== 003 +-- truncate_limit: 100 +-- no such relation +select * from nonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nonesuch" +== 004 +-- truncate_limit: 100 +-- bad name in target list +select nonesuch from pg_database +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT nonesuch FROM pg_database" +== 005 +-- truncate_limit: 100 +-- empty distinct list isn't OK +select distinct from pg_database +-- +ERROR: syntax error at or near "from" +CURSORPOS: 49 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- truncate_limit: 100 +-- bad attribute name on lhs of operator +select * from pg_database where nonesuch = pg_database.datname +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FILTER: schema="" table="" column="nonesuch" +FILTER: schema="" table="pg_database" column="datname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_database WHERE nonesuch = pg_database.datname" +== 007 +-- truncate_limit: 100 +-- bad attribute name on rhs of operator +select * from pg_database where pg_database.datname = nonesuch +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FILTER: schema="" table="pg_database" column="datname" +FILTER: schema="" table="" column="nonesuch" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_database WHERE pg_database.datname = nonesuch" +== 008 +-- truncate_limit: 100 +-- bad attribute name in select distinct on +select distinct on (foobar) * from pg_database +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (foobar) * FROM pg_database" +== 009 +-- truncate_limit: 100 +-- grouping with FOR UPDATE +select null from pg_database group by datname for update +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT NULL FROM pg_database GROUP BY datname FOR UPDATE" +== 010 +-- truncate_limit: 100 +select null from pg_database group by grouping sets (()) for update +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT NULL FROM pg_database GROUP BY GROUPING SETS (()) FOR UPDATE" +== 011 +-- truncate_limit: 100 +|-- +-- DELETE + +-- missing relation name (this had better not wildcard!) +delete from +-- +ERROR: syntax error at end of input +CURSORPOS: 83 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- truncate_limit: 100 +-- no such relation +delete from nonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM nonesuch" +== 013 +-- truncate_limit: 100 +|-- +-- DROP + +-- missing relation name (this had better not wildcard!) +drop table +-- +ERROR: syntax error at end of input +CURSORPOS: 80 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 014 +-- truncate_limit: 100 +-- no such relation +drop table nonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE nonesuch" +== 015 +-- truncate_limit: 100 +|-- +-- ALTER TABLE + +-- relation renaming + +-- missing relation name +alter table rename +-- +ERROR: syntax error at end of input +CURSORPOS: 85 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 016 +-- truncate_limit: 100 +-- no such relation +alter table nonesuch rename to newnonesuch +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DDL +TABLE: name="newnonesuch" schema="" table="newnonesuch" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE nonesuch RENAME TO newnonesuch" +== 017 +-- truncate_limit: 100 +-- no such relation +alter table nonesuch rename to stud_emp +-- +TABLE: name="nonesuch" schema="" table="nonesuch" ctx=DDL +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE nonesuch RENAME TO stud_emp" +== 018 +-- truncate_limit: 100 +-- conflict +alter table stud_emp rename to student +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +TABLE: name="student" schema="" table="student" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE stud_emp RENAME TO student" +== 019 +-- truncate_limit: 100 +-- self-conflict +alter table stud_emp rename to stud_emp +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE stud_emp RENAME TO stud_emp" +== 020 +-- truncate_limit: 100 +-- attribute renaming + +-- no such relation +alter table nonesuchrel rename column nonesuchatt to newnonesuchatt +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE nonesuchrel RENAME COLUMN nonesuchatt TO newnonesuchatt" +== 021 +-- truncate_limit: 100 +-- no such attribute +alter table emp rename column nonesuchatt to newnonesuchatt +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE emp RENAME COLUMN nonesuchatt TO newnonesuchatt" +== 022 +-- truncate_limit: 100 +-- conflict +alter table emp rename column salary to manager +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE emp RENAME COLUMN salary TO manager" +== 023 +-- truncate_limit: 100 +-- conflict +alter table emp rename column salary to ctid +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE emp RENAME COLUMN salary TO ctid" +== 024 +-- truncate_limit: 100 +|-- +-- TRANSACTION STUFF + +-- not in a xact +abort +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 025 +-- truncate_limit: 100 +-- not in a xact +end +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 026 +-- truncate_limit: 100 +|-- +-- CREATE AGGREGATE + +-- sfunc/finalfunc type disagreement +create aggregate newavg2 (sfunc = int4pl, + basetype = int4, + stype = int4, + finalfunc = int2um, + initcond = '0') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE newavg2 (sfunc = int4pl, basetype = int4, stype = int4, finalfunc = int2um, init..." +== 027 +-- truncate_limit: 100 +-- left out basetype +create aggregate newcnt1 (sfunc = int4inc, + stype = int4, + initcond = '0') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE newcnt1 (sfunc = int4inc, stype = int4, initcond = '0')" +== 028 +-- truncate_limit: 100 +|-- +-- DROP INDEX + +-- missing index name +drop index +-- +ERROR: syntax error at end of input +CURSORPOS: 51 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +-- truncate_limit: 100 +-- bad index name +drop index 314159 +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 030 +-- truncate_limit: 100 +-- no such index +drop index nonesuch +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX nonesuch" +== 031 +-- truncate_limit: 100 +|-- +-- DROP AGGREGATE + +-- missing aggregate name +drop aggregate +-- +ERROR: syntax error at end of input +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 032 +-- truncate_limit: 100 +-- missing aggregate type +drop aggregate newcnt1 +-- +ERROR: syntax error at end of input +CURSORPOS: 49 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 033 +-- truncate_limit: 100 +-- bad aggregate name +drop aggregate 314159 (int) +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 034 +-- truncate_limit: 100 +-- bad aggregate type +drop aggregate newcnt (nonesuch) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE newcnt(nonesuch)" +== 035 +-- truncate_limit: 100 +-- no such aggregate +drop aggregate nonesuch (int4) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE nonesuch(int4)" +== 036 +-- truncate_limit: 100 +-- no such aggregate for type +drop aggregate newcnt (float4) +-- +STMT: DropStmt +TRUNCATED: "DROP AGGREGATE newcnt(float4)" +== 037 +-- truncate_limit: 100 +|-- +-- DROP FUNCTION + +-- missing function name +drop function () +-- +ERROR: syntax error at or near "(" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +-- truncate_limit: 100 +-- bad function name +drop function 314159() +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +-- truncate_limit: 100 +-- no such function +drop function nonesuch() +-- +FUNCTION: name="nonesuch" function="nonesuch" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION nonesuch()" +== 040 +-- truncate_limit: 100 +|-- +-- DROP TYPE + +-- missing type name +drop type +-- +ERROR: syntax error at end of input +CURSORPOS: 48 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 041 +-- truncate_limit: 100 +-- bad type name +drop type 314159 +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 042 +-- truncate_limit: 100 +-- no such type +drop type nonesuch +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE nonesuch" +== 043 +-- truncate_limit: 100 +|-- +-- DROP OPERATOR + +-- missing everything +drop operator +-- +ERROR: syntax error at end of input +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 044 +-- truncate_limit: 100 +-- bad operator name +drop operator equals +-- +ERROR: syntax error at end of input +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 045 +-- truncate_limit: 100 +-- missing type list +drop operator === +-- +ERROR: syntax error at end of input +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 046 +-- truncate_limit: 100 +-- missing parentheses +drop operator int4, int4 +-- +ERROR: syntax error at or near "," +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 047 +-- truncate_limit: 100 +-- missing operator name +drop operator (int4, int4) +-- +ERROR: syntax error at or near "(" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 048 +-- truncate_limit: 100 +-- missing type list contents +drop operator === () +-- +ERROR: syntax error at or near ")" +CURSORPOS: 50 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 049 +-- truncate_limit: 100 +-- no such operator +drop operator === (int4) +-- +ERROR: missing argument +CURSORPOS: 44 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 050 +-- truncate_limit: 100 +-- no such operator by that name +drop operator === (int4, int4) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ===(int4, int4)" +== 051 +-- truncate_limit: 100 +-- no such type1 +drop operator = (nonesuch) +-- +ERROR: missing argument +CURSORPOS: 43 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 052 +-- truncate_limit: 100 +-- no such type1 +drop operator = ( , int4) +-- +ERROR: syntax error at or near "," +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 053 +-- truncate_limit: 100 +-- no such type1 +drop operator = (nonesuch, int4) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR =(nonesuch, int4)" +== 054 +-- truncate_limit: 100 +-- no such type2 +drop operator = (int4, nonesuch) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR =(int4, nonesuch)" +== 055 +-- truncate_limit: 100 +-- no such type2 +drop operator = (int4, ) +-- +ERROR: syntax error at or near ")" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 056 +-- truncate_limit: 100 +|-- +-- DROP RULE + +-- missing rule name +drop rule +-- +ERROR: syntax error at end of input +CURSORPOS: 48 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 057 +-- truncate_limit: 100 +-- bad rule name +drop rule 314159 +-- +ERROR: syntax error at or near "314159" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 058 +-- truncate_limit: 100 +-- no such rule +drop rule nonesuch on noplace +-- +TABLE: name="noplace" schema="" table="noplace" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE nonesuch ON noplace" +== 059 +-- truncate_limit: 100 +-- these postquel variants are no longer supported +drop tuple rule nonesuch +-- +ERROR: syntax error at or near "tuple" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 060 +-- truncate_limit: 100 +drop instance rule nonesuch on noplace +-- +ERROR: syntax error at or near "instance" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 061 +-- truncate_limit: 100 +drop rewrite rule nonesuch +-- +ERROR: syntax error at or near "rewrite" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 062 +-- truncate_limit: 100 +|-- +-- Check that division-by-zero is properly caught. +|-- + +select 1/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0" +== 063 +-- truncate_limit: 100 +select 1::int8/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1::int8 / 0" +== 064 +-- truncate_limit: 100 +select 1/0::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0::int8" +== 065 +-- truncate_limit: 100 +select 1::int2/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1::int2 / 0" +== 066 +-- truncate_limit: 100 +select 1/0::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0::int2" +== 067 +-- truncate_limit: 100 +select 1::numeric/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1::numeric / 0" +== 068 +-- truncate_limit: 100 +select 1/0::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0::numeric" +== 069 +-- truncate_limit: 100 +select 1::float8/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1::float8 / 0" +== 070 +-- truncate_limit: 100 +select 1/0::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0::float8" +== 071 +-- truncate_limit: 100 +select 1::float4/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1::float4 / 0" +== 072 +-- truncate_limit: 100 +select 1/0::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0::float4" +== 073 +-- truncate_limit: 100 +CREATE foo +-- +ERROR: syntax error at or near "foo" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 074 +-- truncate_limit: 100 +CREATE TABLE +-- +ERROR: syntax error at end of input +CURSORPOS: 13 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +-- truncate_limit: 100 +CREATE TABLE + +INSERT INTO foo VALUES(123) foo +-- +ERROR: syntax error at or near "INTO" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 076 +-- truncate_limit: 100 +INSERT INTO 123 +VALUES(123) +-- +ERROR: syntax error at or near "123" +CURSORPOS: 13 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +-- truncate_limit: 100 +INSERT INTO foo +VALUES(123) 123 +-- +ERROR: syntax error at or near "123" +CURSORPOS: 29 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 078 +-- truncate_limit: 100 +-- with a tab +CREATE TABLE foo + (id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, + id3 INTEGER NOT NUL, + id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 108 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 079 +-- truncate_limit: 100 +-- long line to be truncated on the left +CREATE TABLE foo(id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, +id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 080 +-- truncate_limit: 100 +-- long line to be truncated on the right +CREATE TABLE foo( +id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 77 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 081 +-- truncate_limit: 100 +-- long line to be truncated both ways +CREATE TABLE foo(id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 129 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 082 +-- truncate_limit: 100 +-- long line to be truncated on the left, many lines +CREATE +TEMPORARY +TABLE +foo(id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, +id4 INT4 +UNIQUE +NOT +NULL, +id5 TEXT +UNIQUE +NOT +NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 153 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 083 +-- truncate_limit: 100 +-- long line to be truncated on the right, many lines +CREATE +TEMPORARY +TABLE +foo( +id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, id INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 99 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 084 +-- truncate_limit: 100 +-- long line to be truncated both ways, many lines +CREATE +TEMPORARY +TABLE +foo +(id +INT4 +UNIQUE NOT NULL, idx INT4 UNIQUE NOT NULL, idy INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, +idz INT4 UNIQUE NOT NULL, +idv INT4 UNIQUE NOT NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 204 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 085 +-- truncate_limit: 100 +-- more than 10 lines... +CREATE +TEMPORARY +TABLE +foo +(id +INT4 +UNIQUE +NOT +NULL +, +idm +INT4 +UNIQUE +NOT +NULL, +idx INT4 UNIQUE NOT NULL, idy INT4 UNIQUE NOT NULL, id2 TEXT NOT NULL PRIMARY KEY, id3 INTEGER NOT NUL, id4 INT4 UNIQUE NOT NULL, id5 TEXT UNIQUE NOT NULL, +idz INT4 UNIQUE NOT NULL, +idv +INT4 +UNIQUE +NOT +NULL) +-- +ERROR: syntax error at or near "NUL" +CURSORPOS: 205 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json b/parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json new file mode 100644 index 0000000..21e7df0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json @@ -0,0 +1,234 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/event_trigger.test b/parser/testdata/summary_truncate/postgres_regress/event_trigger.test new file mode 100644 index 0000000..9a094b0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/event_trigger.test @@ -0,0 +1,1826 @@ +== 001 +-- truncate_limit: 100 +-- should fail, return type mismatch +create event trigger regress_event_trigger + on ddl_command_start + execute procedure pg_backend_pid() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger ON ddl_command_start EXECUTE FUNCTION pg_backend_pid()" +== 002 +-- truncate_limit: 100 +-- OK +create function test_event_trigger() returns event_trigger as $$ +BEGIN + RAISE NOTICE 'test_event_trigger: % %', tg_event, tg_tag; +END +$$ language plpgsql +-- +FUNCTION: name="test_event_trigger" function="test_event_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_event_trigger() RETURNS event_trigger AS $$\nBEGIN\n RAISE NOTICE 'test_eve..." +== 003 +-- truncate_limit: 100 +-- should fail, can't call it as a plain function +SELECT test_event_trigger() +-- +FUNCTION: name="test_event_trigger" function="test_event_trigger" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_event_trigger()" +== 004 +-- truncate_limit: 100 +-- should fail, event triggers cannot have declared arguments +create function test_event_trigger_arg(name text) +returns event_trigger as $$ BEGIN RETURN 1; END $$ language plpgsql +-- +FUNCTION: name="test_event_trigger_arg" function="test_event_trigger_arg" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_event_trigger_arg(name text) RETURNS event_trigger AS $$ BEGIN RETURN 1; END..." +== 005 +-- truncate_limit: 100 +-- should fail, SQL functions cannot be event triggers +create function test_event_trigger_sql() returns event_trigger as $$ +SELECT 1 $$ language sql +-- +FUNCTION: name="test_event_trigger_sql" function="test_event_trigger_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_event_trigger_sql() RETURNS event_trigger AS $$\nSELECT 1 $$ LANGUAGE sql" +== 006 +-- truncate_limit: 100 +-- should fail, no elephant_bootstrap entry point +create event trigger regress_event_trigger on elephant_bootstrap + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger ON elephant_bootstrap EXECUTE FUNCTION test_event_trig..." +== 007 +-- truncate_limit: 100 +-- OK +create event trigger regress_event_trigger on ddl_command_start + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger ON ddl_command_start EXECUTE FUNCTION test_event_trigg..." +== 008 +-- truncate_limit: 100 +-- OK +create event trigger regress_event_trigger_end on ddl_command_end + execute function test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger_end ON ddl_command_end EXECUTE FUNCTION test_event_tri..." +== 009 +-- truncate_limit: 100 +-- should fail, food is not a valid filter variable +create event trigger regress_event_trigger2 on ddl_command_start + when food in ('sandwich') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN food IN ('sandwich') EXECUT..." +== 010 +-- truncate_limit: 100 +-- should fail, sandwich is not a valid command tag +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('sandwich') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('sandwich') EXECUTE..." +== 011 +-- truncate_limit: 100 +-- should fail, create skunkcabbage is not a valid command tag +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table', 'create skunkcabbage') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('create table', 'cr..." +== 012 +-- truncate_limit: 100 +-- should fail, can't have event triggers on event triggers +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('DROP EVENT TRIGGER') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('DROP EVENT TRIGGER..." +== 013 +-- truncate_limit: 100 +-- should fail, can't have event triggers on global objects +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE ROLE') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('CREATE ROLE') EXEC..." +== 014 +-- truncate_limit: 100 +-- should fail, can't have event triggers on global objects +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE DATABASE') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('CREATE DATABASE') ..." +== 015 +-- truncate_limit: 100 +-- should fail, can't have event triggers on global objects +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE TABLESPACE') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('CREATE TABLESPACE'..." +== 016 +-- truncate_limit: 100 +-- should fail, can't have same filter variable twice +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table') and tag in ('CREATE FUNCTION') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('create table') AND..." +== 017 +-- truncate_limit: 100 +-- should fail, can't have arguments +create event trigger regress_event_trigger2 on ddl_command_start + execute procedure test_event_trigger('argument not allowed') +-- +ERROR: syntax error at or near "'argument not allowed'" +CURSORPOS: 143 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 018 +-- truncate_limit: 100 +-- OK +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table', 'CREATE FUNCTION') + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger2 ON ddl_command_start WHEN tag IN ('create table', 'CR..." +== 019 +-- truncate_limit: 100 +-- OK +comment on event trigger regress_event_trigger is 'test comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON EVENT TRIGGER regress_event_trigger IS 'test comment'" +== 020 +-- truncate_limit: 100 +-- drop as non-superuser should fail +create role regress_evt_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_evt_user" +== 021 +-- truncate_limit: 100 +set role regress_evt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_evt_user" +== 022 +-- truncate_limit: 100 +create event trigger regress_event_trigger_noperms on ddl_command_start + execute procedure test_event_trigger() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger_noperms ON ddl_command_start EXECUTE FUNCTION test_eve..." +== 023 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 024 +-- truncate_limit: 100 +-- test enabling and disabling +alter event trigger regress_event_trigger disable +-- +STMT: AlterEventTrigStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger DISABLE" +== 025 +-- truncate_limit: 100 +-- fires _trigger2 and _trigger_end should fire, but not _trigger +create table event_trigger_fire1 (a int) +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE event_trigger_fire1 (a int)" +== 026 +-- truncate_limit: 100 +alter event trigger regress_event_trigger enable +-- +STMT: AlterEventTrigStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger ENABLE" +== 027 +-- truncate_limit: 100 +set session_replication_role = replica +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_replication_role TO replica" +== 028 +-- truncate_limit: 100 +-- fires nothing +create table event_trigger_fire2 (a int) +-- +TABLE: name="event_trigger_fire2" schema="" table="event_trigger_fire2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE event_trigger_fire2 (a int)" +== 029 +-- truncate_limit: 100 +alter event trigger regress_event_trigger enable replica +-- +STMT: AlterEventTrigStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger ENABLE REPLICA" +== 030 +-- truncate_limit: 100 +-- fires only _trigger +create table event_trigger_fire3 (a int) +-- +TABLE: name="event_trigger_fire3" schema="" table="event_trigger_fire3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE event_trigger_fire3 (a int)" +== 031 +-- truncate_limit: 100 +alter event trigger regress_event_trigger enable always +-- +STMT: AlterEventTrigStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger ENABLE ALWAYS" +== 032 +-- truncate_limit: 100 +-- fires only _trigger +create table event_trigger_fire4 (a int) +-- +TABLE: name="event_trigger_fire4" schema="" table="event_trigger_fire4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE event_trigger_fire4 (a int)" +== 033 +-- truncate_limit: 100 +reset session_replication_role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_replication_role" +== 034 +-- truncate_limit: 100 +-- fires all three +create table event_trigger_fire5 (a int) +-- +TABLE: name="event_trigger_fire5" schema="" table="event_trigger_fire5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE event_trigger_fire5 (a int)" +== 035 +-- truncate_limit: 100 +-- non-top-level command +create function f1() returns int +language plpgsql +as $$ +begin + create table event_trigger_fire6 (a int); + return 0; +end $$ +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1() RETURNS int LANGUAGE plpgsql AS $$\nbegin\n create table event_trigger_fire6 ..." +== 036 +-- truncate_limit: 100 +select f1() +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1()" +== 037 +-- truncate_limit: 100 +-- non-top-level command +create procedure p1() +language plpgsql +as $$ +begin + create table event_trigger_fire7 (a int); +end $$ +-- +FUNCTION: name="p1" function="p1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE p1() LANGUAGE plpgsql AS $$\nbegin\n create table event_trigger_fire7 (a int);\nen..." +== 038 +-- truncate_limit: 100 +call p1() +-- +FUNCTION: name="p1" function="p1" schema="" ctx=Call +STMT: CallStmt +TRUNCATED: "CALL p1()" +== 039 +-- truncate_limit: 100 +-- clean up +alter event trigger regress_event_trigger disable +-- +STMT: AlterEventTrigStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger DISABLE" +== 040 +-- truncate_limit: 100 +drop table event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5, event_trigger_fire6, event_trigger_fire7 +-- +TABLE: name="event_trigger_fire2" schema="" table="event_trigger_fire2" ctx=DDL +TABLE: name="event_trigger_fire3" schema="" table="event_trigger_fire3" ctx=DDL +TABLE: name="event_trigger_fire4" schema="" table="event_trigger_fire4" ctx=DDL +TABLE: name="event_trigger_fire5" schema="" table="event_trigger_fire5" ctx=DDL +TABLE: name="event_trigger_fire6" schema="" table="event_trigger_fire6" ctx=DDL +TABLE: name="event_trigger_fire7" schema="" table="event_trigger_fire7" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5, ev..." +== 041 +-- truncate_limit: 100 +drop routine f1(), p1() +-- +STMT: DropStmt +TRUNCATED: "DROP ROUTINE f1(), p1()" +== 042 +-- truncate_limit: 100 +-- regress_event_trigger_end should fire on these commands +grant all on table event_trigger_fire1 to public +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON event_trigger_fire1 TO public" +== 043 +-- truncate_limit: 100 +comment on table event_trigger_fire1 is 'here is a comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TABLE event_trigger_fire1 IS 'here is a comment'" +== 044 +-- truncate_limit: 100 +revoke all on table event_trigger_fire1 from public +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON event_trigger_fire1 FROM public" +== 045 +-- truncate_limit: 100 +drop table event_trigger_fire1 +-- +TABLE: name="event_trigger_fire1" schema="" table="event_trigger_fire1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE event_trigger_fire1" +== 046 +-- truncate_limit: 100 +create foreign data wrapper useless +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER useless" +== 047 +-- truncate_limit: 100 +create server useless_server foreign data wrapper useless +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER useless_server FOREIGN DATA WRAPPER useless" +== 048 +-- truncate_limit: 100 +create user mapping for regress_evt_user server useless_server +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR regress_evt_user SERVER useless_server" +== 049 +-- truncate_limit: 100 +alter default privileges for role regress_evt_user + revoke delete on tables from regress_evt_user +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_evt_user REVOKE delete ON TABLES FROM regress_evt_user" +== 050 +-- truncate_limit: 100 +-- alter owner to non-superuser should fail +alter event trigger regress_event_trigger owner to regress_evt_user +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger OWNER TO regress_evt_user" +== 051 +-- truncate_limit: 100 +-- alter owner to superuser should work +alter role regress_evt_user superuser +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_evt_user WITH SUPERUSER" +== 052 +-- truncate_limit: 100 +alter event trigger regress_event_trigger owner to regress_evt_user +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger OWNER TO regress_evt_user" +== 053 +-- truncate_limit: 100 +-- should fail, name collision +alter event trigger regress_event_trigger rename to regress_event_trigger2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger RENAME TO regress_event_trigger2" +== 054 +-- truncate_limit: 100 +-- OK +alter event trigger regress_event_trigger rename to regress_event_trigger3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_event_trigger RENAME TO regress_event_trigger3" +== 055 +-- truncate_limit: 100 +-- should fail, doesn't exist any more +drop event trigger regress_event_trigger +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_event_trigger" +== 056 +-- truncate_limit: 100 +-- should fail, regress_evt_user owns some objects +drop role regress_evt_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_evt_user" +== 057 +-- truncate_limit: 100 +-- cleanup before next test +-- these are all OK; the second one should emit a NOTICE +drop event trigger if exists regress_event_trigger2 +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER IF EXISTS regress_event_trigger2" +== 058 +-- truncate_limit: 100 +drop event trigger if exists regress_event_trigger2 +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER IF EXISTS regress_event_trigger2" +== 059 +-- truncate_limit: 100 +drop event trigger regress_event_trigger3 +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_event_trigger3" +== 060 +-- truncate_limit: 100 +drop event trigger regress_event_trigger_end +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_event_trigger_end" +== 061 +-- truncate_limit: 100 +-- test support for dropped objects +CREATE SCHEMA schema_one authorization regress_evt_user +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA schema_one AUTHORIZATION regress_evt_user" +== 062 +-- truncate_limit: 100 +CREATE SCHEMA schema_two authorization regress_evt_user +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA schema_two AUTHORIZATION regress_evt_user" +== 063 +-- truncate_limit: 100 +CREATE SCHEMA audit_tbls authorization regress_evt_user +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA audit_tbls AUTHORIZATION regress_evt_user" +== 064 +-- truncate_limit: 100 +CREATE TEMP TABLE a_temp_tbl () +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE a_temp_tbl ()" +== 065 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_evt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_evt_user" +== 066 +-- truncate_limit: 100 +CREATE TABLE schema_one.table_one(a int) +-- +TABLE: name="schema_one.table_one" schema="schema_one" table="table_one" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE schema_one.table_one (a int)" +== 067 +-- truncate_limit: 100 +CREATE TABLE schema_one."table two"(a int) +-- +TABLE: name="schema_one.\"table two\"" schema="schema_one" table="table two" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE schema_one.\"table two\" (a int)" +== 068 +-- truncate_limit: 100 +CREATE TABLE schema_one.table_three(a int) +-- +TABLE: name="schema_one.table_three" schema="schema_one" table="table_three" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE schema_one.table_three (a int)" +== 069 +-- truncate_limit: 100 +CREATE TABLE audit_tbls.schema_one_table_two(the_value text) +-- +TABLE: name="audit_tbls.schema_one_table_two" schema="audit_tbls" table="schema_one_table_two" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE audit_tbls.schema_one_table_two (the_value text)" +== 070 +-- truncate_limit: 100 +CREATE TABLE schema_two.table_two(a int) +-- +TABLE: name="schema_two.table_two" schema="schema_two" table="table_two" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE schema_two.table_two (a int)" +== 071 +-- truncate_limit: 100 +CREATE TABLE schema_two.table_three(a int, b text) +-- +TABLE: name="schema_two.table_three" schema="schema_two" table="table_three" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE schema_two.table_three (a int, b text)" +== 072 +-- truncate_limit: 100 +CREATE TABLE audit_tbls.schema_two_table_three(the_value text) +-- +TABLE: name="audit_tbls.schema_two_table_three" schema="audit_tbls" table="schema_two_table_three" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE audit_tbls.schema_two_table_three (the_value text)" +== 073 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION schema_two.add(int, int) RETURNS int LANGUAGE plpgsql + CALLED ON NULL INPUT + AS $$ BEGIN RETURN coalesce($1,0) + coalesce($2,0); END; $$ +-- +FUNCTION: name="schema_two.add" function="add" schema="schema_two" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION schema_two.add(int, int) RETURNS int LANGUAGE plpgsql CALLED ON NULL I..." +== 074 +-- truncate_limit: 100 +CREATE AGGREGATE schema_two.newton + (BASETYPE = int, SFUNC = schema_two.add, STYPE = int) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE schema_two.newton (basetype = int, sfunc = schema_two.add, stype = int)" +== 075 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 076 +-- truncate_limit: 100 +CREATE TABLE undroppable_objs ( + object_type text, + object_identity text +) +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE undroppable_objs (object_type text, object_identity text)" +== 077 +-- truncate_limit: 100 +INSERT INTO undroppable_objs VALUES +('table', 'schema_one.table_three'), +('table', 'audit_tbls.schema_two_table_three') +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO undroppable_objs VALUES (...)" +== 078 +-- truncate_limit: 100 +CREATE TABLE dropped_objects ( + object_type text, + schema_name text, + object_name text, + object_identity text, + address_names text[], + address_args text[], + is_temporary bool, + original bool, + normal bool +) +-- +TABLE: name="dropped_objects" schema="" table="dropped_objects" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dropped_objects (object_type text, schema_name text, object_name text, object_identi..." +== 079 +-- truncate_limit: 100 +-- This tests errors raised within event triggers; the one in audit_tbls +-- uses 2nd-level recursive invocation via test_evtrig_dropped_objects(). +CREATE OR REPLACE FUNCTION undroppable() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + PERFORM 1 FROM pg_tables WHERE tablename = 'undroppable_objs'; + IF NOT FOUND THEN + RAISE NOTICE 'table undroppable_objs not found, skipping'; + RETURN; + END IF; + FOR obj IN + SELECT * FROM pg_event_trigger_dropped_objects() JOIN + undroppable_objs USING (object_type, object_identity) + LOOP + RAISE EXCEPTION 'object % of type % cannot be dropped', + obj.object_identity, obj.object_type; + END LOOP; +END; +$$ +-- +FUNCTION: name="undroppable" function="undroppable" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION undroppable() RETURNS event_trigger LANGUAGE plpgsql AS $$\nDECLARE\n\tob..." +== 080 +-- truncate_limit: 100 +CREATE EVENT TRIGGER undroppable ON sql_drop + EXECUTE PROCEDURE undroppable() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER undroppable ON sql_drop EXECUTE FUNCTION undroppable()" +== 081 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION test_evtrig_dropped_objects() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + IF obj.object_type = 'table' THEN + EXECUTE format('DROP TABLE IF EXISTS audit_tbls.%I', + format('%s_%s', obj.schema_name, obj.object_name)); + END IF; + + INSERT INTO dropped_objects + (object_type, schema_name, object_name, + object_identity, address_names, address_args, + is_temporary, original, normal) VALUES + (obj.object_type, obj.schema_name, obj.object_name, + obj.object_identity, obj.address_names, obj.address_args, + obj.is_temporary, obj.original, obj.normal); + END LOOP; +END +$$ +-- +FUNCTION: name="test_evtrig_dropped_objects" function="test_evtrig_dropped_objects" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION test_evtrig_dropped_objects() RETURNS event_trigger LANGUAGE plpgsql A..." +== 082 +-- truncate_limit: 100 +CREATE EVENT TRIGGER regress_event_trigger_drop_objects ON sql_drop + WHEN TAG IN ('drop table', 'drop function', 'drop view', + 'drop owned', 'drop schema', 'alter table') + EXECUTE PROCEDURE test_evtrig_dropped_objects() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger_drop_objects ON sql_drop WHEN tag IN ('drop table', 'd..." +== 083 +-- truncate_limit: 100 +ALTER TABLE schema_one.table_one DROP COLUMN a +-- +TABLE: name="schema_one.table_one" schema="schema_one" table="table_one" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE schema_one.table_one DROP a" +== 084 +-- truncate_limit: 100 +DROP SCHEMA schema_one, schema_two CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA schema_one, schema_two CASCADE" +== 085 +-- truncate_limit: 100 +DELETE FROM undroppable_objs WHERE object_identity = 'audit_tbls.schema_two_table_three' +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM undroppable_objs WHERE object_identity = 'audit_tbls.schema_two_table_three'" +== 086 +-- truncate_limit: 100 +DROP SCHEMA schema_one, schema_two CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA schema_one, schema_two CASCADE" +== 087 +-- truncate_limit: 100 +DELETE FROM undroppable_objs WHERE object_identity = 'schema_one.table_three' +-- +TABLE: name="undroppable_objs" schema="" table="undroppable_objs" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM undroppable_objs WHERE object_identity = 'schema_one.table_three'" +== 088 +-- truncate_limit: 100 +DROP SCHEMA schema_one, schema_two CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA schema_one, schema_two CASCADE" +== 089 +-- truncate_limit: 100 +-- exclude TOAST objects because they have unstable names +SELECT * FROM dropped_objects + WHERE schema_name IS NULL OR schema_name <> 'pg_toast' +-- +TABLE: name="dropped_objects" schema="" table="dropped_objects" ctx=Select +FILTER: schema="" table="" column="schema_name" +FILTER: schema="" table="" column="schema_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dropped_objects WHERE schema_name IS NULL OR schema_name <> 'pg_toast'" +== 090 +-- truncate_limit: 100 +DROP OWNED BY regress_evt_user +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_evt_user" +== 091 +-- truncate_limit: 100 +SELECT * FROM dropped_objects WHERE object_type = 'schema' +-- +TABLE: name="dropped_objects" schema="" table="dropped_objects" ctx=Select +FILTER: schema="" table="" column="object_type" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dropped_objects WHERE object_type = 'schema'" +== 092 +-- truncate_limit: 100 +DROP ROLE regress_evt_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_evt_user" +== 093 +-- truncate_limit: 100 +DROP EVENT TRIGGER regress_event_trigger_drop_objects +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_event_trigger_drop_objects" +== 094 +-- truncate_limit: 100 +DROP EVENT TRIGGER undroppable +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER undroppable" +== 095 +-- truncate_limit: 100 +-- Event triggers on relations. +CREATE OR REPLACE FUNCTION event_trigger_report_dropped() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r record; +BEGIN + FOR r IN SELECT * from pg_event_trigger_dropped_objects() + LOOP + IF NOT r.normal AND NOT r.original THEN + CONTINUE; + END IF; + RAISE NOTICE 'NORMAL: orig=% normal=% istemp=% type=% identity=% schema=% name=% addr=% args=%', + r.original, r.normal, r.is_temporary, r.object_type, + r.object_identity, r.schema_name, r.object_name, + r.address_names, r.address_args; + END LOOP; +END; $$ +-- +FUNCTION: name="event_trigger_report_dropped" function="event_trigger_report_dropped" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION event_trigger_report_dropped() RETURNS event_trigger LANGUAGE plpgsql ..." +== 096 +-- truncate_limit: 100 +CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop + EXECUTE PROCEDURE event_trigger_report_dropped() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop EXECUTE FUNCTION event_trig..." +== 097 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION event_trigger_report_end() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + RAISE NOTICE 'END: command_tag=% type=% identity=%', + r.command_tag, r.object_type, r.object_identity; + END LOOP; +END; $$ +-- +FUNCTION: name="event_trigger_report_end" function="event_trigger_report_end" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION event_trigger_report_end() RETURNS event_trigger LANGUAGE plpgsql AS $..." +== 098 +-- truncate_limit: 100 +CREATE EVENT TRIGGER regress_event_trigger_report_end ON ddl_command_end + EXECUTE PROCEDURE event_trigger_report_end() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_event_trigger_report_end ON ddl_command_end EXECUTE FUNCTION event_t..." +== 099 +-- truncate_limit: 100 +CREATE SCHEMA evttrig + CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL) + CREATE INDEX one_idx ON one (col_b) + CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42) + CREATE TABLE id (col_d int NOT NULL GENERATED ALWAYS AS IDENTITY) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA evttrig CREATE TABLE one (col_a serial PRIMARY KEY, col_b text DEFAULT 'forty two',..." +== 100 +-- truncate_limit: 100 +-- Partitioned tables with a partitioned index +CREATE TABLE evttrig.parted ( + id int PRIMARY KEY) + PARTITION BY RANGE (id) +-- +TABLE: name="evttrig.parted" schema="evttrig" table="parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE evttrig.parted (id int PRIMARY KEY) PARTITION BY RANGE (id)" +== 101 +-- truncate_limit: 100 +CREATE TABLE evttrig.part_1_10 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (1) TO (10) +-- +TABLE: name="evttrig.part_1_10" schema="evttrig" table="part_1_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE evttrig.part_1_10 PARTITION OF evttrig.parted (id) FOR VALUES FROM (1) TO (10)" +== 102 +-- truncate_limit: 100 +CREATE TABLE evttrig.part_10_20 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (10) TO (20) PARTITION BY RANGE (id) +-- +TABLE: name="evttrig.part_10_20" schema="evttrig" table="part_10_20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE evttrig.part_10_20 PARTITION OF evttrig.parted (id) FOR VALUES FROM (10) TO (20) PAR..." +== 103 +-- truncate_limit: 100 +CREATE TABLE evttrig.part_10_15 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (10) TO (15) +-- +TABLE: name="evttrig.part_10_15" schema="evttrig" table="part_10_15" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE evttrig.part_10_15 PARTITION OF evttrig.part_10_20 (id) FOR VALUES FROM (10) TO (15)" +== 104 +-- truncate_limit: 100 +CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (15) TO (20) +-- +TABLE: name="evttrig.part_15_20" schema="evttrig" table="part_15_20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id) FOR VALUES FROM (15) TO (20)" +== 105 +-- truncate_limit: 100 +ALTER TABLE evttrig.two DROP COLUMN col_c +-- +TABLE: name="evttrig.two" schema="evttrig" table="two" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE evttrig.two DROP col_c" +== 106 +-- truncate_limit: 100 +ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT +-- +TABLE: name="evttrig.one" schema="evttrig" table="one" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT" +== 107 +-- truncate_limit: 100 +ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey +-- +TABLE: name="evttrig.one" schema="evttrig" table="one" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey" +== 108 +-- truncate_limit: 100 +ALTER TABLE evttrig.one DROP COLUMN col_c +-- +TABLE: name="evttrig.one" schema="evttrig" table="one" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE evttrig.one DROP col_c" +== 109 +-- truncate_limit: 100 +ALTER TABLE evttrig.id ALTER COLUMN col_d SET DATA TYPE bigint +-- +TABLE: name="evttrig.id" schema="evttrig" table="id" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE evttrig.id ALTER COLUMN col_d TYPE bigint" +== 110 +-- truncate_limit: 100 +ALTER TABLE evttrig.id ALTER COLUMN col_d DROP IDENTITY, + ALTER COLUMN col_d SET DATA TYPE int +-- +TABLE: name="evttrig.id" schema="evttrig" table="id" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE evttrig.id ALTER COLUMN col_d DROP IDENTITY, ALTER COLUMN col_d TYPE int" +== 111 +-- truncate_limit: 100 +DROP INDEX evttrig.one_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX evttrig.one_idx" +== 112 +-- truncate_limit: 100 +DROP SCHEMA evttrig CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA evttrig CASCADE" +== 113 +-- truncate_limit: 100 +DROP TABLE a_temp_tbl +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE a_temp_tbl" +== 114 +-- truncate_limit: 100 +-- check unfiltered results, too +CREATE OR REPLACE FUNCTION event_trigger_report_dropped() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r record; +BEGIN + FOR r IN SELECT * from pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE 'DROP: orig=% normal=% istemp=% type=% identity=% schema=% name=% addr=% args=%', + r.original, r.normal, r.is_temporary, r.object_type, + r.object_identity, r.schema_name, r.object_name, + r.address_names, r.address_args; + END LOOP; +END; $$ +-- +FUNCTION: name="event_trigger_report_dropped" function="event_trigger_report_dropped" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION event_trigger_report_dropped() RETURNS event_trigger LANGUAGE plpgsql ..." +== 115 +-- truncate_limit: 100 +CREATE FUNCTION event_trigger_dummy_trigger() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + RETURN new; +END; $$ +-- +FUNCTION: name="event_trigger_dummy_trigger" function="event_trigger_dummy_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION event_trigger_dummy_trigger() RETURNS trigger LANGUAGE plpgsql AS $$\nBEGIN\n RE..." +== 116 +-- truncate_limit: 100 +CREATE TABLE evtrg_nontemp_table (f1 int primary key, f2 int default 42) +-- +TABLE: name="evtrg_nontemp_table" schema="" table="evtrg_nontemp_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE evtrg_nontemp_table (f1 int PRIMARY KEY, f2 int DEFAULT 42)" +== 117 +-- truncate_limit: 100 +CREATE TRIGGER evtrg_nontemp_trig + BEFORE INSERT ON evtrg_nontemp_table + EXECUTE FUNCTION event_trigger_dummy_trigger() +-- +TABLE: name="evtrg_nontemp_table" schema="" table="evtrg_nontemp_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER evtrg_nontemp_trig BEFORE INSERT ON evtrg_nontemp_table EXECUTE FUNCTION event_tri..." +== 118 +-- truncate_limit: 100 +CREATE POLICY evtrg_nontemp_pol ON evtrg_nontemp_table USING (f2 > 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY evtrg_nontemp_pol ON evtrg_nontemp_table TO public USING (f2 > 0)" +== 119 +-- truncate_limit: 100 +DROP TABLE evtrg_nontemp_table +-- +TABLE: name="evtrg_nontemp_table" schema="" table="evtrg_nontemp_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE evtrg_nontemp_table" +== 120 +-- truncate_limit: 100 +CREATE TEMP TABLE a_temp_tbl (f1 int primary key, f2 int default 42) +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE a_temp_tbl (f1 int PRIMARY KEY, f2 int DEFAULT 42)" +== 121 +-- truncate_limit: 100 +CREATE TRIGGER a_temp_trig + BEFORE INSERT ON a_temp_tbl + EXECUTE FUNCTION event_trigger_dummy_trigger() +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a_temp_trig BEFORE INSERT ON a_temp_tbl EXECUTE FUNCTION event_trigger_dummy_trigg..." +== 122 +-- truncate_limit: 100 +CREATE POLICY a_temp_pol ON a_temp_tbl USING (f2 > 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY a_temp_pol ON a_temp_tbl TO public USING (f2 > 0)" +== 123 +-- truncate_limit: 100 +DROP TABLE a_temp_tbl +-- +TABLE: name="a_temp_tbl" schema="" table="a_temp_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE a_temp_tbl" +== 124 +-- truncate_limit: 100 +DROP FUNCTION event_trigger_dummy_trigger() +-- +FUNCTION: name="event_trigger_dummy_trigger" function="event_trigger_dummy_trigger" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION event_trigger_dummy_trigger()" +== 125 +-- truncate_limit: 100 +-- CREATE OPERATOR CLASS without FAMILY clause should report +-- both CREATE OPERATOR FAMILY and CREATE OPERATOR CLASS +CREATE OPERATOR CLASS evttrigopclass FOR TYPE int USING btree AS STORAGE int +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS evttrigopclass FOR TYPE int USING btree AS STORAGE int" +== 126 +-- truncate_limit: 100 +DROP EVENT TRIGGER regress_event_trigger_report_dropped +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_event_trigger_report_dropped" +== 127 +-- truncate_limit: 100 +DROP EVENT TRIGGER regress_event_trigger_report_end +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_event_trigger_report_end" +== 128 +-- truncate_limit: 100 +-- only allowed from within an event trigger function, should fail +select pg_event_trigger_table_rewrite_oid() +-- +FUNCTION: name="pg_event_trigger_table_rewrite_oid" function="pg_event_trigger_table_rewrite_oid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_event_trigger_table_rewrite_oid()" +== 129 +-- truncate_limit: 100 +-- test Table Rewrite Event Trigger +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE EXCEPTION 'rewrites not allowed'; +END; +$$ +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS $$\n..." +== 130 +-- truncate_limit: 100 +create event trigger no_rewrite_allowed on table_rewrite + execute procedure test_evtrig_no_rewrite() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER no_rewrite_allowed ON table_rewrite EXECUTE FUNCTION test_evtrig_no_rewrite()" +== 131 +-- truncate_limit: 100 +create table rewriteme (id serial primary key, foo float, bar timestamptz) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rewriteme (id serial PRIMARY KEY, foo double precision, bar timestamptz)" +== 132 +-- truncate_limit: 100 +insert into rewriteme + select x * 1.001 from generate_series(1, 500) as t(x) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rewriteme SELECT x * 1.001 FROM generate_series(1, 500) t(x)" +== 133 +-- truncate_limit: 100 +alter table rewriteme alter column foo type numeric +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rewriteme ALTER COLUMN foo TYPE numeric" +== 134 +-- truncate_limit: 100 +alter table rewriteme add column baz int default 0 +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rewriteme ADD COLUMN baz int DEFAULT 0" +== 135 +-- truncate_limit: 100 +-- test with more than one reason to rewrite a single table +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'Table ''%'' is being rewritten (reason = %)', + pg_event_trigger_table_rewrite_oid()::regclass, + pg_event_trigger_table_rewrite_reason(); +END; +$$ +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS $$\n..." +== 136 +-- truncate_limit: 100 +alter table rewriteme + add column onemore int default 0, + add column another int default -1, + alter column foo type numeric(10,4) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rewriteme ADD COLUMN onemore int DEFAULT 0, ADD COLUMN another int DEFAULT -1, ALTER ..." +== 137 +-- truncate_limit: 100 +-- matview rewrite when changing access method +CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT 1 AS a +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT 1 AS a" +== 138 +-- truncate_limit: 100 +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2 +-- +TABLE: name="heapmv" schema="" table="heapmv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2" +== 139 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW heapmv +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW heapmv" +== 140 +-- truncate_limit: 100 +-- shouldn't trigger a table_rewrite event +alter table rewriteme alter column foo type numeric(12,4) +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rewriteme ALTER COLUMN foo TYPE numeric(12, 4)" +== 141 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 142 +-- truncate_limit: 100 +set timezone to 'UTC' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"UTC\"" +== 143 +-- truncate_limit: 100 +alter table rewriteme alter column bar type timestamp +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rewriteme ALTER COLUMN bar TYPE timestamp" +== 144 +-- truncate_limit: 100 +set timezone to '0' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"0\"" +== 145 +-- truncate_limit: 100 +alter table rewriteme alter column bar type timestamptz +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rewriteme ALTER COLUMN bar TYPE timestamptz" +== 146 +-- truncate_limit: 100 +set timezone to 'Europe/London' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"Europe/London\"" +== 147 +-- truncate_limit: 100 +alter table rewriteme alter column bar type timestamp +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rewriteme ALTER COLUMN bar TYPE timestamp" +== 148 +-- truncate_limit: 100 +-- does rewrite +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 149 +-- truncate_limit: 100 +-- typed tables are rewritten when their type changes. Don't emit table +-- name, because firing order is not stable. +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'Table is being rewritten (reason = %)', + pg_event_trigger_table_rewrite_reason(); +END; +$$ +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS $$\n..." +== 150 +-- truncate_limit: 100 +create type rewritetype as (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE rewritetype AS (a int)" +== 151 +-- truncate_limit: 100 +create table rewritemetoo1 of rewritetype +-- +TABLE: name="rewritemetoo1" schema="" table="rewritemetoo1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rewritemetoo1 OF rewritetype" +== 152 +-- truncate_limit: 100 +create table rewritemetoo2 of rewritetype +-- +TABLE: name="rewritemetoo2" schema="" table="rewritemetoo2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rewritemetoo2 OF rewritetype" +== 153 +-- truncate_limit: 100 +alter type rewritetype alter attribute a type text cascade +-- +TABLE: name="rewritetype" schema="" table="rewritetype" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE rewritetype ALTER ATTRIBUTE a TYPE text CASCADE" +== 154 +-- truncate_limit: 100 +-- but this doesn't work +create table rewritemetoo3 (a rewritetype) +-- +TABLE: name="rewritemetoo3" schema="" table="rewritemetoo3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rewritemetoo3 (a rewritetype)" +== 155 +-- truncate_limit: 100 +alter type rewritetype alter attribute a type varchar cascade +-- +TABLE: name="rewritetype" schema="" table="rewritetype" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE rewritetype ALTER ATTRIBUTE a TYPE varchar CASCADE" +== 156 +-- truncate_limit: 100 +drop table rewriteme +-- +TABLE: name="rewriteme" schema="" table="rewriteme" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rewriteme" +== 157 +-- truncate_limit: 100 +drop event trigger no_rewrite_allowed +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER no_rewrite_allowed" +== 158 +-- truncate_limit: 100 +drop function test_evtrig_no_rewrite() +-- +FUNCTION: name="test_evtrig_no_rewrite" function="test_evtrig_no_rewrite" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION test_evtrig_no_rewrite()" +== 159 +-- truncate_limit: 100 +-- Tests for REINDEX +CREATE OR REPLACE FUNCTION reindex_start_command() +RETURNS event_trigger AS $$ +BEGIN + RAISE NOTICE 'REINDEX START: % %', tg_event, tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="reindex_start_command" function="reindex_start_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION reindex_start_command() RETURNS event_trigger AS $$\nBEGIN\n RAISE NO..." +== 160 +-- truncate_limit: 100 +CREATE EVENT TRIGGER regress_reindex_start ON ddl_command_start + WHEN TAG IN ('REINDEX') + EXECUTE PROCEDURE reindex_start_command() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_reindex_start ON ddl_command_start WHEN tag IN ('REINDEX') EXECUTE F..." +== 161 +-- truncate_limit: 100 +CREATE FUNCTION reindex_end_command() +RETURNS event_trigger AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + RAISE NOTICE 'REINDEX END: command_tag=% type=% identity=%', + obj.command_tag, obj.object_type, obj.object_identity; + END LOOP; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="reindex_end_command" function="reindex_end_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION reindex_end_command() RETURNS event_trigger AS $$\nDECLARE\n obj record;\nBEGIN\n ..." +== 162 +-- truncate_limit: 100 +CREATE EVENT TRIGGER regress_reindex_end ON ddl_command_end + WHEN TAG IN ('REINDEX') + EXECUTE PROCEDURE reindex_end_command() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_reindex_end ON ddl_command_end WHEN tag IN ('REINDEX') EXECUTE FUNCT..." +== 163 +-- truncate_limit: 100 +-- Extra event to force the use of a snapshot. +CREATE FUNCTION reindex_end_command_snap() RETURNS EVENT_TRIGGER + AS $$ BEGIN PERFORM 1; END $$ LANGUAGE plpgsql +-- +FUNCTION: name="reindex_end_command_snap" function="reindex_end_command_snap" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION reindex_end_command_snap() RETURNS event_trigger AS $$ BEGIN PERFORM 1; END $$ LA..." +== 164 +-- truncate_limit: 100 +CREATE EVENT TRIGGER regress_reindex_end_snap ON ddl_command_end + EXECUTE FUNCTION reindex_end_command_snap() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER regress_reindex_end_snap ON ddl_command_end EXECUTE FUNCTION reindex_end_com..." +== 165 +-- truncate_limit: 100 +-- With simple relation +CREATE TABLE concur_reindex_tab (c1 int) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_tab (c1 int)" +== 166 +-- truncate_limit: 100 +CREATE INDEX concur_reindex_ind ON concur_reindex_tab (c1) +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_ind ON concur_reindex_tab USING btree (c1)" +== 167 +-- truncate_limit: 100 +-- Both start and end triggers enabled. +REINDEX INDEX concur_reindex_ind +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX concur_reindex_ind" +== 168 +-- truncate_limit: 100 +REINDEX TABLE concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_tab" +== 169 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_ind +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_ind" +== 170 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_tab" +== 171 +-- truncate_limit: 100 +-- with start trigger disabled. +ALTER EVENT TRIGGER regress_reindex_start DISABLE +-- +STMT: AlterEventTrigStmt +TRUNCATED: "ALTER EVENT TRIGGER regress_reindex_start DISABLE" +== 172 +-- truncate_limit: 100 +REINDEX INDEX concur_reindex_ind +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX concur_reindex_ind" +== 173 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_ind +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_ind" +== 174 +-- truncate_limit: 100 +-- without an index +DROP INDEX concur_reindex_ind +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX concur_reindex_ind" +== 175 +-- truncate_limit: 100 +REINDEX TABLE concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_tab" +== 176 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_tab +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_tab" +== 177 +-- truncate_limit: 100 +-- With a Schema +CREATE SCHEMA concur_reindex_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA concur_reindex_schema" +== 178 +-- truncate_limit: 100 +-- No indexes +REINDEX SCHEMA concur_reindex_schema +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA concur_reindex_schema" +== 179 +-- truncate_limit: 100 +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SCHEMA concur_reindex_schema" +== 180 +-- truncate_limit: 100 +CREATE TABLE concur_reindex_schema.tab (a int) +-- +TABLE: name="concur_reindex_schema.tab" schema="concur_reindex_schema" table="tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_schema.tab (a int)" +== 181 +-- truncate_limit: 100 +CREATE INDEX ind ON concur_reindex_schema.tab (a) +-- +TABLE: name="concur_reindex_schema.tab" schema="concur_reindex_schema" table="tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ind ON concur_reindex_schema.tab USING btree (a)" +== 182 +-- truncate_limit: 100 +-- One index reported +REINDEX SCHEMA concur_reindex_schema +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA concur_reindex_schema" +== 183 +-- truncate_limit: 100 +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SCHEMA concur_reindex_schema" +== 184 +-- truncate_limit: 100 +-- One table on schema but no indexes +DROP INDEX concur_reindex_schema.ind +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX concur_reindex_schema.ind" +== 185 +-- truncate_limit: 100 +REINDEX SCHEMA concur_reindex_schema +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX SCHEMA concur_reindex_schema" +== 186 +-- truncate_limit: 100 +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) SCHEMA concur_reindex_schema" +== 187 +-- truncate_limit: 100 +DROP SCHEMA concur_reindex_schema CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA concur_reindex_schema CASCADE" +== 188 +-- truncate_limit: 100 +-- With a partitioned table, and nothing else. +CREATE TABLE concur_reindex_part (id int) PARTITION BY RANGE (id) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_part (id int) PARTITION BY RANGE (id)" +== 189 +-- truncate_limit: 100 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_part" +== 190 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part" +== 191 +-- truncate_limit: 100 +-- Partition that would be reindexed, still nothing. +CREATE TABLE concur_reindex_child PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10) +-- +TABLE: name="concur_reindex_child" schema="" table="concur_reindex_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE concur_reindex_child PARTITION OF concur_reindex_part FOR VALUES FROM (0) TO (10)" +== 192 +-- truncate_limit: 100 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_part" +== 193 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part" +== 194 +-- truncate_limit: 100 +-- Now add some indexes. +CREATE INDEX concur_reindex_partidx ON concur_reindex_part (id) +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX concur_reindex_partidx ON concur_reindex_part USING btree (id)" +== 195 +-- truncate_limit: 100 +REINDEX INDEX concur_reindex_partidx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX concur_reindex_partidx" +== 196 +-- truncate_limit: 100 +REINDEX INDEX CONCURRENTLY concur_reindex_partidx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX concur_reindex_partidx" +== 197 +-- truncate_limit: 100 +REINDEX TABLE concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE concur_reindex_part" +== 198 +-- truncate_limit: 100 +REINDEX TABLE CONCURRENTLY concur_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) TABLE concur_reindex_part" +== 199 +-- truncate_limit: 100 +DROP TABLE concur_reindex_part +-- +TABLE: name="concur_reindex_part" schema="" table="concur_reindex_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_reindex_part" +== 200 +-- truncate_limit: 100 +-- Clean up +DROP EVENT TRIGGER regress_reindex_start +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_reindex_start" +== 201 +-- truncate_limit: 100 +DROP EVENT TRIGGER regress_reindex_end +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_reindex_end" +== 202 +-- truncate_limit: 100 +DROP EVENT TRIGGER regress_reindex_end_snap +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER regress_reindex_end_snap" +== 203 +-- truncate_limit: 100 +DROP FUNCTION reindex_end_command() +-- +FUNCTION: name="reindex_end_command" function="reindex_end_command" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION reindex_end_command()" +== 204 +-- truncate_limit: 100 +DROP FUNCTION reindex_end_command_snap() +-- +FUNCTION: name="reindex_end_command_snap" function="reindex_end_command_snap" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION reindex_end_command_snap()" +== 205 +-- truncate_limit: 100 +DROP FUNCTION reindex_start_command() +-- +FUNCTION: name="reindex_start_command" function="reindex_start_command" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION reindex_start_command()" +== 206 +-- truncate_limit: 100 +DROP TABLE concur_reindex_tab +-- +TABLE: name="concur_reindex_tab" schema="" table="concur_reindex_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE concur_reindex_tab" +== 207 +-- truncate_limit: 100 +-- test Row Security Event Trigger +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 208 +-- truncate_limit: 100 +CREATE TABLE event_trigger_test (a integer, b text) +-- +TABLE: name="event_trigger_test" schema="" table="event_trigger_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE event_trigger_test (a int, b text)" +== 209 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION start_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - ddl_command_start', tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="start_command" function="start_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION start_command() RETURNS event_trigger AS $$\nBEGIN\nRAISE NOTICE '% - dd..." +== 210 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION end_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - ddl_command_end', tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="end_command" function="end_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION end_command() RETURNS event_trigger AS $$\nBEGIN\nRAISE NOTICE '% - ddl_..." +== 211 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION drop_sql_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - sql_drop', tg_tag; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="drop_sql_command" function="drop_sql_command" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION drop_sql_command() RETURNS event_trigger AS $$\nBEGIN\nRAISE NOTICE '% -..." +== 212 +-- truncate_limit: 100 +CREATE EVENT TRIGGER start_rls_command ON ddl_command_start + WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE start_command() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER start_rls_command ON ddl_command_start WHEN tag IN ('CREATE POLICY', 'ALTER ..." +== 213 +-- truncate_limit: 100 +CREATE EVENT TRIGGER end_rls_command ON ddl_command_end + WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE end_command() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER end_rls_command ON ddl_command_end WHEN tag IN ('CREATE POLICY', 'ALTER POLI..." +== 214 +-- truncate_limit: 100 +CREATE EVENT TRIGGER sql_drop_command ON sql_drop + WHEN TAG IN ('DROP POLICY') EXECUTE PROCEDURE drop_sql_command() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER sql_drop_command ON sql_drop WHEN tag IN ('DROP POLICY') EXECUTE FUNCTION dr..." +== 215 +-- truncate_limit: 100 +CREATE POLICY p1 ON event_trigger_test USING (FALSE) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON event_trigger_test TO public USING (false)" +== 216 +-- truncate_limit: 100 +ALTER POLICY p1 ON event_trigger_test USING (TRUE) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY p1 ON event_trigger_test USING (true)" +== 217 +-- truncate_limit: 100 +ALTER POLICY p1 ON event_trigger_test RENAME TO p2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER POLICY p1 ON event_trigger_test RENAME TO p2" +== 218 +-- truncate_limit: 100 +DROP POLICY p2 ON event_trigger_test +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p2 ON event_trigger_test" +== 219 +-- truncate_limit: 100 +-- Check the object addresses of all the event triggers. +SELECT + e.evtname, + pg_describe_object('pg_event_trigger'::regclass, e.oid, 0) as descr, + b.type, b.object_names, b.object_args, + pg_identify_object(a.classid, a.objid, a.objsubid) as ident + FROM pg_event_trigger as e, + LATERAL pg_identify_object_as_address('pg_event_trigger'::regclass, e.oid, 0) as b, + LATERAL pg_get_object_address(b.type, b.object_names, b.object_args) as a + ORDER BY e.evtname +-- +TABLE: name="pg_event_trigger" schema="" table="pg_event_trigger" ctx=Select +ALIAS: "e"="pg_event_trigger" +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object_as_address" function="pg_identify_object_as_address" schema="" ctx=Call +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_event_trigger e, LATERAL pg_identify_object_as_address('pg_event_trigger'::reg..." +== 220 +-- truncate_limit: 100 +DROP EVENT TRIGGER start_rls_command +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER start_rls_command" +== 221 +-- truncate_limit: 100 +DROP EVENT TRIGGER end_rls_command +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER end_rls_command" +== 222 +-- truncate_limit: 100 +DROP EVENT TRIGGER sql_drop_command +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER sql_drop_command" +== 223 +-- truncate_limit: 100 +-- Check the GUC for disabling event triggers +CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE '% dropped %', tg_tag, obj.object_type; + END LOOP; +END; +$$ +-- +FUNCTION: name="test_event_trigger_guc" function="test_event_trigger_guc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger LANGUAGE plpgsql AS $$\nDECLARE\n\tob..." +== 224 +-- truncate_limit: 100 +CREATE EVENT TRIGGER test_event_trigger_guc + ON sql_drop + WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER test_event_trigger_guc ON sql_drop WHEN tag IN ('DROP POLICY') EXECUTE FUNCT..." +== 225 +-- truncate_limit: 100 +SET event_triggers = 'on' +-- +STMT: VariableSetStmt +TRUNCATED: "SET event_triggers TO ON" +== 226 +-- truncate_limit: 100 +CREATE POLICY pguc ON event_trigger_test USING (FALSE) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY pguc ON event_trigger_test TO public USING (false)" +== 227 +-- truncate_limit: 100 +DROP POLICY pguc ON event_trigger_test +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY pguc ON event_trigger_test" +== 228 +-- truncate_limit: 100 +CREATE POLICY pguc ON event_trigger_test USING (FALSE) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY pguc ON event_trigger_test TO public USING (false)" +== 229 +-- truncate_limit: 100 +SET event_triggers = 'off' +-- +STMT: VariableSetStmt +TRUNCATED: "SET event_triggers TO OFF" +== 230 +-- truncate_limit: 100 +DROP POLICY pguc ON event_trigger_test +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY pguc ON event_trigger_test" diff --git a/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json b/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json new file mode 100644 index 0000000..4739b17 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json @@ -0,0 +1,15 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.test b/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.test new file mode 100644 index 0000000..0941ee7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.test @@ -0,0 +1,85 @@ +== 001 +-- truncate_limit: 100 +-- Login event triggers +CREATE TABLE user_logins(id serial, who text) +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE user_logins (id serial, who text)" +== 002 +-- truncate_limit: 100 +GRANT SELECT ON user_logins TO public +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON user_logins TO public" +== 003 +-- truncate_limit: 100 +CREATE FUNCTION on_login_proc() RETURNS event_trigger AS $$ +BEGIN + INSERT INTO user_logins (who) VALUES (SESSION_USER); + RAISE NOTICE 'You are welcome!'; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="on_login_proc" function="on_login_proc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION on_login_proc() RETURNS event_trigger AS $$\nBEGIN\n INSERT INTO user_logins (who)..." +== 004 +-- truncate_limit: 100 +CREATE EVENT TRIGGER on_login_trigger ON login EXECUTE PROCEDURE on_login_proc() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER on_login_trigger ON login EXECUTE FUNCTION on_login_proc()" +== 005 +-- truncate_limit: 100 +ALTER EVENT TRIGGER on_login_trigger ENABLE ALWAYS +-- +STMT: AlterEventTrigStmt +TRUNCATED: "ALTER EVENT TRIGGER on_login_trigger ENABLE ALWAYS" +== 006 +-- truncate_limit: 100 +SELECT COUNT(*) FROM user_logins +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM user_logins" +== 007 +-- truncate_limit: 100 +SELECT COUNT(*) FROM user_logins +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM user_logins" +== 008 +-- truncate_limit: 100 +-- Check dathasloginevt in system catalog +SELECT dathasloginevt FROM pg_database WHERE datname= :'DBNAME' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 97 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- truncate_limit: 100 +-- Cleanup +DROP TABLE user_logins +-- +TABLE: name="user_logins" schema="" table="user_logins" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE user_logins" +== 010 +-- truncate_limit: 100 +DROP EVENT TRIGGER on_login_trigger +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER on_login_trigger" +== 011 +-- truncate_limit: 100 +DROP FUNCTION on_login_proc() +-- +FUNCTION: name="on_login_proc" function="on_login_proc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION on_login_proc()" diff --git a/parser/testdata/summary_truncate/postgres_regress/explain.metadata.json b/parser/testdata/summary_truncate/postgres_regress/explain.metadata.json new file mode 100644 index 0000000..fbb3e40 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/explain.metadata.json @@ -0,0 +1,55 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/explain.test b/parser/testdata/summary_truncate/postgres_regress/explain.test new file mode 100644 index 0000000..05561eb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/explain.test @@ -0,0 +1,450 @@ +== 001 +-- truncate_limit: 100 +|-- +-- EXPLAIN +|-- +-- There are many test cases elsewhere that use EXPLAIN as a vehicle for +-- checking something else (usually planner behavior). This file is +-- concerned with testing EXPLAIN in its own right. +|-- + +-- To produce stable regression test output, it's usually necessary to +-- ignore details such as exact costs or row counts. These filter +-- functions replace changeable output details with fixed strings. + +create function explain_filter(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in execute $1 + loop + -- Replace any numeric word with just 'N' + ln := regexp_replace(ln, '-?\m\d+\M', 'N', 'g'); + -- In sort output, the above won't match units-suffixed numbers + ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g'); + -- Ignore text-mode buffers output because it varies depending + -- on the system state + CONTINUE WHEN (ln ~ ' +Buffers: .*'); + -- Ignore text-mode "Planning:" line because whether it's output + -- varies depending on the system state + CONTINUE WHEN (ln = 'Planning:'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_filter(text) RETURNS SETOF text LANGUAGE plpgsql AS $$\ndeclare\n ln tex..." +== 002 +-- truncate_limit: 100 +-- To produce valid JSON output, replace numbers with "0" or "0.0" not "N" +create function explain_filter_to_json(text) returns jsonb +language plpgsql as +$$ +declare + data text := ''; + ln text; +begin + for ln in execute $1 + loop + -- Replace any numeric word with just '0' + ln := regexp_replace(ln, '\m\d+\M', '0', 'g'); + data := data || ln; + end loop; + return data::jsonb; +end; +$$ +-- +FUNCTION: name="explain_filter_to_json" function="explain_filter_to_json" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_filter_to_json(text) RETURNS jsonb LANGUAGE plpgsql AS $$\ndeclare\n dat..." +== 003 +-- truncate_limit: 100 +-- Disable JIT, or we'll get different output on machines where that's been +-- forced on +set jit = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit TO OFF" +== 004 +-- truncate_limit: 100 +-- Similarly, disable track_io_timing, to avoid output differences when +-- enabled. +set track_io_timing = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET track_io_timing TO OFF" +== 005 +-- truncate_limit: 100 +-- Simple cases + +select explain_filter('explain select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain select * from int8_tbl i8')" +== 006 +-- truncate_limit: 100 +select explain_filter('explain (analyze) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (analyze) select * from int8_tbl i8')" +== 007 +-- truncate_limit: 100 +select explain_filter('explain (analyze, verbose) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (analyze, verbose) select * from int8_tbl i8')" +== 008 +-- truncate_limit: 100 +select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8')" +== 009 +-- truncate_limit: 100 +select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8')" +== 010 +-- truncate_limit: 100 +select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 011 +-- truncate_limit: 100 +select explain_filter('explain (buffers, format text) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (buffers, format text) select * from int8_tbl i8')" +== 012 +-- truncate_limit: 100 +select explain_filter('explain (buffers, format json) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (buffers, format json) select * from int8_tbl i8')" +== 013 +-- truncate_limit: 100 +-- Check output including I/O timings. These fields are conditional +-- but always set in JSON format, so check them only in this case. +set track_io_timing = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET track_io_timing TO ON" +== 014 +-- truncate_limit: 100 +select explain_filter('explain (analyze, buffers, format json) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (analyze, buffers, format json) select * from int8_tbl i8')" +== 015 +-- truncate_limit: 100 +set track_io_timing = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET track_io_timing TO OFF" +== 016 +-- truncate_limit: 100 +-- SETTINGS option +-- We have to ignore other settings that might be imposed by the environment, +-- so printing the whole Settings field unfortunately won't do. + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 017 +-- truncate_limit: 100 +set local plan_cache_mode = force_generic_plan +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL plan_cache_mode TO force_generic_plan" +== 018 +-- truncate_limit: 100 +select true as "OK" + from explain_filter('explain (settings) select * from int8_tbl i8') ln + where ln ~ '^ *Settings: .*plan_cache_mode = ''force_generic_plan''' +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +FILTER: schema="" table="" column="ln" +STMT: SelectStmt +TRUNCATED: "SELECT true AS \"OK\" FROM explain_filter('explain (settings) select * from int8_tbl i8') ln WHERE ..." +== 019 +-- truncate_limit: 100 +select explain_filter_to_json('explain (settings, format json) select * from int8_tbl i8') #> '{0,Settings,plan_cache_mode}' +-- +FUNCTION: name="explain_filter_to_json" function="explain_filter_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 020 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 021 +-- truncate_limit: 100 +-- GENERIC_PLAN option + +select explain_filter('explain (generic_plan) select unique1 from tenk1 where thousand = $1') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (generic_plan) select unique1 from tenk1 where thousand = $1')" +== 022 +-- truncate_limit: 100 +-- should fail +select explain_filter('explain (analyze, generic_plan) select unique1 from tenk1 where thousand = $1') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 023 +-- truncate_limit: 100 +-- MEMORY option +select explain_filter('explain (memory) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (memory) select * from int8_tbl i8')" +== 024 +-- truncate_limit: 100 +select explain_filter('explain (memory, analyze) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (memory, analyze) select * from int8_tbl i8')" +== 025 +-- truncate_limit: 100 +select explain_filter('explain (memory, summary, format yaml) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (memory, summary, format yaml) select * from int8_tbl i8')" +== 026 +-- truncate_limit: 100 +select explain_filter('explain (memory, analyze, format json) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (memory, analyze, format json) select * from int8_tbl i8')" +== 027 +-- truncate_limit: 100 +prepare int8_query as select * from int8_tbl i8 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE int8_query AS SELECT * FROM int8_tbl i8" +== 028 +-- truncate_limit: 100 +select explain_filter('explain (memory) execute int8_query') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (memory) execute int8_query')" +== 029 +-- truncate_limit: 100 +-- Test EXPLAIN (GENERIC_PLAN) with partition pruning +-- partitions should be pruned at plan time, based on constants, +-- but there should be no pruning based on parameter placeholders +create table gen_part ( + key1 integer not null, + key2 integer not null +) partition by list (key1) +-- +TABLE: name="gen_part" schema="" table="gen_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gen_part (key1 int NOT NULL, key2 int NOT NULL) PARTITION BY LIST (key1)" +== 030 +-- truncate_limit: 100 +create table gen_part_1 + partition of gen_part for values in (1) + partition by range (key2) +-- +TABLE: name="gen_part_1" schema="" table="gen_part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gen_part_1 PARTITION OF gen_part FOR VALUES IN (1) PARTITION BY RANGE (key2)" +== 031 +-- truncate_limit: 100 +create table gen_part_1_1 + partition of gen_part_1 for values from (1) to (2) +-- +TABLE: name="gen_part_1_1" schema="" table="gen_part_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gen_part_1_1 PARTITION OF gen_part_1 FOR VALUES FROM (1) TO (2)" +== 032 +-- truncate_limit: 100 +create table gen_part_1_2 + partition of gen_part_1 for values from (2) to (3) +-- +TABLE: name="gen_part_1_2" schema="" table="gen_part_1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gen_part_1_2 PARTITION OF gen_part_1 FOR VALUES FROM (2) TO (3)" +== 033 +-- truncate_limit: 100 +create table gen_part_2 + partition of gen_part for values in (2) +-- +TABLE: name="gen_part_2" schema="" table="gen_part_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gen_part_2 PARTITION OF gen_part FOR VALUES IN (2)" +== 034 +-- truncate_limit: 100 +-- should scan gen_part_1_1 and gen_part_1_2, but not gen_part_2 +select explain_filter('explain (generic_plan) select key1, key2 from gen_part where key1 = 1 and key2 = $1') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 035 +-- truncate_limit: 100 +drop table gen_part +-- +TABLE: name="gen_part" schema="" table="gen_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gen_part" +== 036 +-- truncate_limit: 100 +|-- +-- Test production of per-worker data +|-- +-- Unfortunately, because we don't know how many worker processes we'll +-- actually get (maybe none at all), we can't examine the "Workers" output +-- in any detail. We can check that it parses correctly as JSON, and then +-- remove it from the displayed results. + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 037 +-- truncate_limit: 100 +-- encourage use of parallel plans +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 038 +-- truncate_limit: 100 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 039 +-- truncate_limit: 100 +set min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 040 +-- truncate_limit: 100 +set max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 4" +== 041 +-- truncate_limit: 100 +select jsonb_pretty( + explain_filter_to_json('explain (analyze, verbose, buffers, format json) + select * from tenk1 order by tenthous') + -- remove "Workers" node of the Seq Scan plan node + #- '{0,Plan,Plans,0,Plans,0,Workers}' + -- remove "Workers" node of the Sort plan node + #- '{0,Plan,Plans,0,Workers}' + -- Also remove its sort-type fields, as those aren't 100% stable + #- '{0,Plan,Plans,0,Sort Method}' + #- '{0,Plan,Plans,0,Sort Space Type}' +) +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +FUNCTION: name="explain_filter_to_json" function="explain_filter_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 042 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 043 +-- truncate_limit: 100 +-- Test display of temporary objects +create temp table t1(f1 float8) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (f1 float8)" +== 044 +-- truncate_limit: 100 +create function pg_temp.mysin(float8) returns float8 language plpgsql +as 'begin return sin($1); end' +-- +FUNCTION: name="pg_temp.mysin" function="mysin" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pg_temp.mysin(float8) RETURNS float8 LANGUAGE plpgsql AS $$begin return sin($1); ..." +== 045 +-- truncate_limit: 100 +select explain_filter('explain (verbose) select * from t1 where pg_temp.mysin(f1) < 0.5') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (verbose) select * from t1 where pg_temp.mysin(f1) < 0.5')" +== 046 +-- truncate_limit: 100 +-- Test compute_query_id +set compute_query_id = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET compute_query_id TO ON" +== 047 +-- truncate_limit: 100 +select explain_filter('explain (verbose) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (verbose) select * from int8_tbl i8')" +== 048 +-- truncate_limit: 100 +-- Test SERIALIZE option +select explain_filter('explain (analyze,serialize) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (analyze,serialize) select * from int8_tbl i8')" +== 049 +-- truncate_limit: 100 +select explain_filter('explain (analyze,serialize text,buffers,timing off) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 050 +-- truncate_limit: 100 +select explain_filter('explain (analyze,serialize binary,buffers,timing) select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_filter('explain (analyze,serialize binary,buffers,timing) select * from int8_tbl i8')" +== 051 +-- truncate_limit: 100 +-- this tests an edge case where we have no data to return +select explain_filter('explain (analyze,serialize) create temp table explain_temp as select * from int8_tbl i8') +-- +FUNCTION: name="explain_filter" function="explain_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." diff --git a/parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json b/parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json new file mode 100644 index 0000000..fb72ee9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json @@ -0,0 +1,75 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/expressions.test b/parser/testdata/summary_truncate/postgres_regress/expressions.test new file mode 100644 index 0000000..2a5aa3f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/expressions.test @@ -0,0 +1,594 @@ +== 001 +-- truncate_limit: 100 +|-- +-- expression evaluation tests that don't fit into a more specific file +|-- + +|-- +-- Tests for SQLValueFunction +|-- + + +-- current_date (always matches because of transactional behaviour) +SELECT date(now())::text = current_date::text +-- +FUNCTION: name="date" function="date" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date(now())::text = current_date::text" +== 002 +-- truncate_limit: 100 +-- current_time / localtime +SELECT now()::timetz::text = current_time::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT now()::timetz::text = current_time::text" +== 003 +-- truncate_limit: 100 +SELECT now()::timetz(4)::text = current_time(4)::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT now()::timetz(4)::text = current_time(4)::text" +== 004 +-- truncate_limit: 100 +SELECT now()::time::text = localtime::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT now()::time::text = localtime::text" +== 005 +-- truncate_limit: 100 +SELECT now()::time(3)::text = localtime(3)::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT now()::time(3)::text = localtime(3)::text" +== 006 +-- truncate_limit: 100 +-- current_time[stamp]/ localtime[stamp] (always matches because of transactional behaviour) +SELECT current_timestamp = NOW() +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_timestamp = now()" +== 007 +-- truncate_limit: 100 +-- precision +SELECT length(current_timestamp::text) >= length(current_timestamp(0)::text) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(current_timestamp::text) >= length(current_timestamp(0)::text)" +== 008 +-- truncate_limit: 100 +-- localtimestamp +SELECT now()::timestamp::text = localtimestamp::text +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT now()::timestamp::text = localtimestamp::text" +== 009 +-- truncate_limit: 100 +-- precision overflow +SELECT current_time = current_time(7) +-- +STMT: SelectStmt +TRUNCATED: "SELECT current_time = current_time(7)" +== 010 +-- truncate_limit: 100 +SELECT current_timestamp = current_timestamp(7) +-- +STMT: SelectStmt +TRUNCATED: "SELECT current_timestamp = current_timestamp(7)" +== 011 +-- truncate_limit: 100 +SELECT localtime = localtime(7) +-- +STMT: SelectStmt +TRUNCATED: "SELECT localtime = localtime(7)" +== 012 +-- truncate_limit: 100 +SELECT localtimestamp = localtimestamp(7) +-- +STMT: SelectStmt +TRUNCATED: "SELECT localtimestamp = localtimestamp(7)" +== 013 +-- truncate_limit: 100 +-- current_role/user/user is tested in rolenames.sql + +-- current database / catalog +SELECT current_catalog = current_database() +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_catalog = current_database()" +== 014 +-- truncate_limit: 100 +-- current_schema +SELECT current_schema +-- +STMT: SelectStmt +TRUNCATED: "SELECT current_schema" +== 015 +-- truncate_limit: 100 +SET search_path = 'notme' +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO notme" +== 016 +-- truncate_limit: 100 +SELECT current_schema +-- +STMT: SelectStmt +TRUNCATED: "SELECT current_schema" +== 017 +-- truncate_limit: 100 +SET search_path = 'pg_catalog' +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO pg_catalog" +== 018 +-- truncate_limit: 100 +SELECT current_schema +-- +STMT: SelectStmt +TRUNCATED: "SELECT current_schema" +== 019 +-- truncate_limit: 100 +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 020 +-- truncate_limit: 100 +|-- +-- Test parsing of a no-op cast to a type with unspecified typmod +|-- +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 021 +-- truncate_limit: 100 +create table numeric_tbl (f1 numeric(18,3), f2 numeric) +-- +TABLE: name="numeric_tbl" schema="" table="numeric_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE numeric_tbl (f1 numeric(18, 3), f2 numeric)" +== 022 +-- truncate_limit: 100 +create view numeric_view as + select + f1, f1::numeric(16,4) as f1164, f1::numeric as f1n, + f2, f2::numeric(16,4) as f2164, f2::numeric as f2n + from numeric_tbl +-- +TABLE: name="numeric_view" schema="" table="numeric_view" ctx=DDL +TABLE: name="numeric_tbl" schema="" table="numeric_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW numeric_view AS SELECT f1, f1::numeric(16, 4) AS f1164, f1::numeric AS f1n, f2, f2::n..." +== 023 +-- truncate_limit: 100 +explain (verbose, costs off) select * from numeric_view +-- +TABLE: name="numeric_view" schema="" table="numeric_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM numeric_view" +== 024 +-- truncate_limit: 100 +-- bpchar, lacking planner support for its length coercion function, +-- could behave differently + +create table bpchar_tbl (f1 character(16) unique, f2 bpchar) +-- +TABLE: name="bpchar_tbl" schema="" table="bpchar_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bpchar_tbl (f1 char(16) UNIQUE, f2 bpchar)" +== 025 +-- truncate_limit: 100 +create view bpchar_view as + select + f1, f1::character(14) as f114, f1::bpchar as f1n, + f2, f2::character(14) as f214, f2::bpchar as f2n + from bpchar_tbl +-- +TABLE: name="bpchar_view" schema="" table="bpchar_view" ctx=DDL +TABLE: name="bpchar_tbl" schema="" table="bpchar_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW bpchar_view AS SELECT f1, f1::char(14) AS f114, f1::bpchar AS f1n, f2, f2::char(14) A..." +== 026 +-- truncate_limit: 100 +explain (verbose, costs off) select * from bpchar_view + where f1::bpchar = 'foo' +-- +TABLE: name="bpchar_view" schema="" table="bpchar_view" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM bpchar_view WHERE f1::bpchar = 'foo'" +== 027 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 028 +-- truncate_limit: 100 +|-- +-- Ordinarily, IN/NOT IN can be converted to a ScalarArrayOpExpr +-- with a suitably-chosen array type. +|-- +explain (verbose, costs off) +select random() IN (1, 4, 8.0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT random() IN (1, 4, 8.0)" +== 029 +-- truncate_limit: 100 +explain (verbose, costs off) +select random()::int IN (1, 4, 8.0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT random()::int IN (1, 4, 8.0)" +== 030 +-- truncate_limit: 100 +-- However, if there's not a common supertype for the IN elements, +-- we should instead try to produce "x = v1 OR x = v2 OR ...". +-- In most cases that'll fail for lack of all the requisite = operators, +-- but it can succeed sometimes. So this should complain about lack of +-- an = operator, not about cast failure. +select '(0,0)'::point in ('(0,0,0,0)'::box, point(0,0)) +-- +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '(0,0)'::point IN ('(0,0,0,0)'::box, point(0, 0))" +== 031 +-- truncate_limit: 100 +|-- +-- Tests for ScalarArrayOpExpr with a hashfn +|-- + +-- create a stable function so that the tests below are not +-- evaluated using the planner's constant folding. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 032 +-- truncate_limit: 100 +create function return_int_input(int) returns int as $$ +begin + return $1; +end; +$$ language plpgsql stable +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION return_int_input(int) RETURNS int AS $$\nbegin\n\treturn $1;\nend;\n$$ LANGUAGE plpgsq..." +== 033 +-- truncate_limit: 100 +create function return_text_input(text) returns text as $$ +begin + return $1; +end; +$$ language plpgsql stable +-- +FUNCTION: name="return_text_input" function="return_text_input" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION return_text_input(text) RETURNS text AS $$\nbegin\n\treturn $1;\nend;\n$$ LANGUAGE plp..." +== 034 +-- truncate_limit: 100 +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 1)" +== 035 +-- truncate_limit: 100 +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) IN (10, 9, 2, 8, 3, 7, 4, 6, 5, NULL)" +== 036 +-- truncate_limit: 100 +select return_int_input(1) in (null, null, null, null, null, null, null, null, null, null, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) IN (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)" +== 037 +-- truncate_limit: 100 +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, NULL)" +== 038 +-- truncate_limit: 100 +select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(NULL::int) IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 1)" +== 039 +-- truncate_limit: 100 +select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(NULL::int) IN (10, 9, 2, 8, 3, 7, 4, 6, 5, NULL)" +== 040 +-- truncate_limit: 100 +select return_text_input('a') in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j') +-- +FUNCTION: name="return_text_input" function="return_text_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_text_input('a') IN ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')" +== 041 +-- truncate_limit: 100 +-- NOT IN +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) NOT IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 1)" +== 042 +-- truncate_limit: 100 +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 0) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) NOT IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 0)" +== 043 +-- truncate_limit: 100 +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 2, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) NOT IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 2, NULL)" +== 044 +-- truncate_limit: 100 +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) NOT IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, NULL)" +== 045 +-- truncate_limit: 100 +select return_int_input(1) not in (null, null, null, null, null, null, null, null, null, null, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(1) NOT IN (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)" +== 046 +-- truncate_limit: 100 +select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(NULL::int) NOT IN (10, 9, 2, 8, 3, 7, 4, 6, 5, 1)" +== 047 +-- truncate_limit: 100 +select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, null) +-- +FUNCTION: name="return_int_input" function="return_int_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_int_input(NULL::int) NOT IN (10, 9, 2, 8, 3, 7, 4, 6, 5, NULL)" +== 048 +-- truncate_limit: 100 +select return_text_input('a') not in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j') +-- +FUNCTION: name="return_text_input" function="return_text_input" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT return_text_input('a') NOT IN ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')" +== 049 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 050 +-- truncate_limit: 100 +-- Test with non-strict equality function. +-- We need to create our own type for this. + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 051 +-- truncate_limit: 100 +create type myint +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE myint" +== 052 +-- truncate_limit: 100 +create function myintin(cstring) returns myint strict immutable language + internal as 'int4in' +-- +FUNCTION: name="myintin" function="myintin" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myintin(cstring) RETURNS myint RETURNS NULL ON NULL INPUT IMMUTABLE LANGUAGE inte..." +== 053 +-- truncate_limit: 100 +create function myintout(myint) returns cstring strict immutable language + internal as 'int4out' +-- +FUNCTION: name="myintout" function="myintout" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myintout(myint) RETURNS cstring RETURNS NULL ON NULL INPUT IMMUTABLE LANGUAGE int..." +== 054 +-- truncate_limit: 100 +create function myinthash(myint) returns integer strict immutable language + internal as 'hashint4' +-- +FUNCTION: name="myinthash" function="myinthash" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myinthash(myint) RETURNS int RETURNS NULL ON NULL INPUT IMMUTABLE LANGUAGE intern..." +== 055 +-- truncate_limit: 100 +create type myint (input = myintin, output = myintout, like = int4) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE myint (input = myintin, output = myintout, \"like\" = int4)" +== 056 +-- truncate_limit: 100 +create cast (int4 as myint) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int4 AS myint) WITHOUT FUNCTION" +== 057 +-- truncate_limit: 100 +create cast (myint as int4) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (myint AS int4) WITHOUT FUNCTION" +== 058 +-- truncate_limit: 100 +create function myinteq(myint, myint) returns bool as $$ +begin + if $1 is null and $2 is null then + return true; + else + return $1::int = $2::int; + end if; +end; +$$ language plpgsql immutable +-- +FUNCTION: name="myinteq" function="myinteq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myinteq(myint, myint) RETURNS bool AS $$\nbegin\n if $1 is null and $2 is null the..." +== 059 +-- truncate_limit: 100 +create function myintne(myint, myint) returns bool as $$ +begin + return not myinteq($1, $2); +end; +$$ language plpgsql immutable +-- +FUNCTION: name="myintne" function="myintne" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myintne(myint, myint) RETURNS bool AS $$\nbegin\n return not myinteq($1, $2);\nend;..." +== 060 +-- truncate_limit: 100 +create operator = ( + leftarg = myint, + rightarg = myint, + commutator = =, + negator = <>, + procedure = myinteq, + restrict = eqsel, + join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (leftarg = myint, rightarg = myint, commutator = =, negator = <>, procedure = m..." +== 061 +-- truncate_limit: 100 +create operator <> ( + leftarg = myint, + rightarg = myint, + commutator = <>, + negator = =, + procedure = myintne, + restrict = eqsel, + join = eqjoinsel, + merges +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR <> (leftarg = myint, rightarg = myint, commutator = <>, negator = =, procedure = ..." +== 062 +-- truncate_limit: 100 +create operator class myint_ops +default for type myint using hash as + operator 1 = (myint, myint), + function 1 myinthash(myint) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS myint_ops DEFAULT FOR TYPE myint USING hash AS OPERATOR 1 =(myint, myint), ..." +== 063 +-- truncate_limit: 100 +create table inttest (a myint) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inttest (a myint)" +== 064 +-- truncate_limit: 100 +insert into inttest values(1::myint),(null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inttest VALUES (1::myint), (NULL)" +== 065 +-- truncate_limit: 100 +-- try an array with enough elements to cause hashing +select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inttest WHERE ..." +== 066 +-- truncate_limit: 100 +select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inttest WHERE ..." +== 067 +-- truncate_limit: 100 +select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inttest WHERE ..." +== 068 +-- truncate_limit: 100 +-- ensure the result matched with the non-hashed version. We simply remove +-- some array elements so that we don't reach the hashing threshold. +select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inttest WHERE a IN (1::myint, 2::myint, 3::myint, 4::myint, 5::myint, NULL)" +== 069 +-- truncate_limit: 100 +select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inttest WHERE a NOT IN (1::myint, 2::myint, 3::myint, 4::myint, 5::myint, NULL)" +== 070 +-- truncate_limit: 100 +select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint, null) +-- +TABLE: name="inttest" schema="" table="inttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inttest WHERE a NOT IN (0::myint, 2::myint, 3::myint, 4::myint, 5::myint, NULL)" +== 071 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json b/parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json new file mode 100644 index 0000000..354a8d0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json @@ -0,0 +1,273 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/fast_default.test b/parser/testdata/summary_truncate/postgres_regress/fast_default.test new file mode 100644 index 0000000..9b304b8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/fast_default.test @@ -0,0 +1,2155 @@ +== 001 +-- truncate_limit: 100 +|-- +-- ALTER TABLE ADD COLUMN DEFAULT test +|-- + +SET search_path = fast_default +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fast_default" +== 002 +-- truncate_limit: 100 +CREATE SCHEMA fast_default +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fast_default" +== 003 +-- truncate_limit: 100 +CREATE TABLE m(id OID) +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE m (id oid)" +== 004 +-- truncate_limit: 100 +INSERT INTO m VALUES (NULL::OID) +-- +TABLE: name="m" schema="" table="m" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO m VALUES (NULL::oid)" +== 005 +-- truncate_limit: 100 +CREATE FUNCTION set(tabname name) RETURNS VOID +AS $$ +BEGIN + UPDATE m + SET id = (SELECT c.relfilenode + FROM pg_class AS c, pg_namespace AS s + WHERE c.relname = tabname + AND c.relnamespace = s.oid + AND s.nspname = 'fast_default'); +END; +$$ LANGUAGE 'plpgsql' +-- +FUNCTION: name="set" function="set" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION set(tabname name) RETURNS void AS $$\nBEGIN\n UPDATE m\n SET id = (SELECT c.relfil..." +== 006 +-- truncate_limit: 100 +CREATE FUNCTION comp() RETURNS TEXT +AS $$ +BEGIN + RETURN (SELECT CASE + WHEN m.id = c.relfilenode THEN 'Unchanged' + ELSE 'Rewritten' + END + FROM m, pg_class AS c, pg_namespace AS s + WHERE c.relname = 't' + AND c.relnamespace = s.oid + AND s.nspname = 'fast_default'); +END; +$$ LANGUAGE 'plpgsql' +-- +FUNCTION: name="comp" function="comp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION comp() RETURNS text AS $$\nBEGIN\n RETURN (SELECT CASE\n WHEN m.id = ..." +== 007 +-- truncate_limit: 100 +CREATE FUNCTION log_rewrite() RETURNS event_trigger +LANGUAGE plpgsql as +$func$ + +declare + this_schema text; +begin + select into this_schema relnamespace::regnamespace::text + from pg_class + where oid = pg_event_trigger_table_rewrite_oid(); + if this_schema = 'fast_default' + then + RAISE NOTICE 'rewriting table % for reason %', + pg_event_trigger_table_rewrite_oid()::regclass, + pg_event_trigger_table_rewrite_reason(); + end if; +end; +$func$ +-- +FUNCTION: name="log_rewrite" function="log_rewrite" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION log_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS $$\n\ndeclare\n this_schem..." +== 008 +-- truncate_limit: 100 +CREATE TABLE has_volatile AS +SELECT * FROM generate_series(1,10) id +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE has_volatile AS SELECT * FROM generate_series(1, 10) id" +== 009 +-- truncate_limit: 100 +CREATE EVENT TRIGGER has_volatile_rewrite + ON table_rewrite + EXECUTE PROCEDURE log_rewrite() +-- +STMT: CreateEventTrigStmt +TRUNCATED: "CREATE EVENT TRIGGER has_volatile_rewrite ON table_rewrite EXECUTE FUNCTION log_rewrite()" +== 010 +-- truncate_limit: 100 +-- only the last of these should trigger a rewrite +ALTER TABLE has_volatile ADD col1 int +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE has_volatile ADD COLUMN col1 int" +== 011 +-- truncate_limit: 100 +ALTER TABLE has_volatile ADD col2 int DEFAULT 1 +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE has_volatile ADD COLUMN col2 int DEFAULT 1" +== 012 +-- truncate_limit: 100 +ALTER TABLE has_volatile ADD col3 timestamptz DEFAULT current_timestamp +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE has_volatile ADD COLUMN col3 timestamptz DEFAULT current_timestamp" +== 013 +-- truncate_limit: 100 +ALTER TABLE has_volatile ADD col4 int DEFAULT (random() * 10000)::int +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE has_volatile ADD COLUMN col4 int DEFAULT ((random() * 10000)::int)" +== 014 +-- truncate_limit: 100 +-- Test a large sample of different datatypes +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT 1) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (pk int NOT NULL PRIMARY KEY, c_int int DEFAULT 1)" +== 015 +-- truncate_limit: 100 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set('t')" +== 016 +-- truncate_limit: 100 +INSERT INTO T VALUES (1), (2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1), (2)" +== 017 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT 'hello', + ALTER COLUMN c_int SET DEFAULT 2 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_bpchar bpchar(5) DEFAULT 'hello', ALTER COLUMN c_int SET DEFAULT 2" +== 018 +-- truncate_limit: 100 +INSERT INTO T VALUES (3), (4) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (3), (4)" +== 019 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'world', + ALTER COLUMN c_bpchar SET DEFAULT 'dog' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_text text DEFAULT 'world', ALTER COLUMN c_bpchar SET DEFAULT 'dog'" +== 020 +-- truncate_limit: 100 +INSERT INTO T VALUES (5), (6) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (5), (6)" +== 021 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_date DATE DEFAULT '2016-06-02', + ALTER COLUMN c_text SET DEFAULT 'cat' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_date date DEFAULT '2016-06-02', ALTER COLUMN c_text SET DEFAULT 'cat'" +== 022 +-- truncate_limit: 100 +INSERT INTO T VALUES (7), (8) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (7), (8)" +== 023 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP DEFAULT '2016-09-01 12:00:00', + ADD COLUMN c_timestamp_null TIMESTAMP, + ALTER COLUMN c_date SET DEFAULT '2010-01-01' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_timestamp timestamp DEFAULT '2016-09-01 12:00:00', ADD COLUMN c_timest..." +== 024 +-- truncate_limit: 100 +INSERT INTO T VALUES (9), (10) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (9), (10)" +== 025 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_array TEXT[] + DEFAULT '{"This", "is", "the", "real", "world"}', + ALTER COLUMN c_timestamp SET DEFAULT '1970-12-31 11:12:13', + ALTER COLUMN c_timestamp_null SET DEFAULT '2016-09-29 12:00:00' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_array text[] DEFAULT '{\"This\", \"is\", \"the\", \"real\", \"world\"}', ALTER C..." +== 026 +-- truncate_limit: 100 +INSERT INTO T VALUES (11), (12) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (11), (12)" +== 027 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_small SMALLINT DEFAULT -5, + ADD COLUMN c_small_null SMALLINT, + ALTER COLUMN c_array + SET DEFAULT '{"This", "is", "no", "fantasy"}' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_small smallint DEFAULT -5, ADD COLUMN c_small_null smallint, ALTER COL..." +== 028 +-- truncate_limit: 100 +INSERT INTO T VALUES (13), (14) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (13), (14)" +== 029 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_big BIGINT DEFAULT 180000000000018, + ALTER COLUMN c_small SET DEFAULT 9, + ALTER COLUMN c_small_null SET DEFAULT 13 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_big bigint DEFAULT 180000000000018, ALTER COLUMN c_small SET DEFAULT 9..." +== 030 +-- truncate_limit: 100 +INSERT INTO T VALUES (15), (16) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (15), (16)" +== 031 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_num NUMERIC DEFAULT 1.00000000001, + ALTER COLUMN c_big SET DEFAULT -9999999999999999 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_num numeric DEFAULT 1.00000000001, ALTER COLUMN c_big SET DEFAULT -999..." +== 032 +-- truncate_limit: 100 +INSERT INTO T VALUES (17), (18) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (17), (18)" +== 033 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_time TIME DEFAULT '12:00:00', + ALTER COLUMN c_num SET DEFAULT 2.000000000000002 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_time time DEFAULT '12:00:00', ALTER COLUMN c_num SET DEFAULT 2.0000000..." +== 034 +-- truncate_limit: 100 +INSERT INTO T VALUES (19), (20) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (19), (20)" +== 035 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_interval INTERVAL DEFAULT '1 day', + ALTER COLUMN c_time SET DEFAULT '23:59:59' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_interval interval DEFAULT '1 day', ALTER COLUMN c_time SET DEFAULT '23..." +== 036 +-- truncate_limit: 100 +INSERT INTO T VALUES (21), (22) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (21), (22)" +== 037 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_hugetext TEXT DEFAULT repeat('abcdefg',1000), + ALTER COLUMN c_interval SET DEFAULT '3 hours' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_hugetext text DEFAULT repeat('abcdefg', 1000), ALTER COLUMN c_interval..." +== 038 +-- truncate_limit: 100 +INSERT INTO T VALUES (23), (24) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (23), (24)" +== 039 +-- truncate_limit: 100 +ALTER TABLE T ALTER COLUMN c_interval DROP DEFAULT, + ALTER COLUMN c_hugetext SET DEFAULT repeat('poiuyt', 1000) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ALTER COLUMN c_interval DROP DEFAULT, ALTER COLUMN c_hugetext SET DEFAULT repeat('p..." +== 040 +-- truncate_limit: 100 +INSERT INTO T VALUES (25), (26) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (25), (26)" +== 041 +-- truncate_limit: 100 +ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT, + ALTER COLUMN c_date DROP DEFAULT, + ALTER COLUMN c_text DROP DEFAULT, + ALTER COLUMN c_timestamp DROP DEFAULT, + ALTER COLUMN c_array DROP DEFAULT, + ALTER COLUMN c_small DROP DEFAULT, + ALTER COLUMN c_big DROP DEFAULT, + ALTER COLUMN c_num DROP DEFAULT, + ALTER COLUMN c_time DROP DEFAULT, + ALTER COLUMN c_hugetext DROP DEFAULT +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ALTER COLUMN c_bpchar DROP DEFAULT, ALTER COLUMN c_date DROP DEFAULT, ALTER COLUMN ..." +== 042 +-- truncate_limit: 100 +INSERT INTO T VALUES (27), (28) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (27), (28)" +== 043 +-- truncate_limit: 100 +SELECT pk, c_int, c_bpchar, c_text, c_date, c_timestamp, + c_timestamp_null, c_array, c_small, c_small_null, + c_big, c_num, c_time, c_interval, + c_hugetext = repeat('abcdefg',1000) as c_hugetext_origdef, + c_hugetext = repeat('poiuyt', 1000) as c_hugetext_newdef +FROM T ORDER BY pk +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t ORDER BY pk" +== 044 +-- truncate_limit: 100 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT comp()" +== 045 +-- truncate_limit: 100 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 046 +-- truncate_limit: 100 +-- Test expressions in the defaults +CREATE OR REPLACE FUNCTION foo(a INT) RETURNS TEXT AS $$ +DECLARE res TEXT := ''; + i INT; +BEGIN + i := 0; + WHILE (i < a) LOOP + res := res || chr(ascii('a') + i); + i := i + 1; + END LOOP; + RETURN res; +END; $$ LANGUAGE PLPGSQL STABLE +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION foo(a int) RETURNS text AS $$\nDECLARE res TEXT := '';\n i INT;\nB..." +== 047 +-- truncate_limit: 100 +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT LENGTH(foo(6))) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (pk int NOT NULL PRIMARY KEY, c_int int DEFAULT length(foo(6)))" +== 048 +-- truncate_limit: 100 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set('t')" +== 049 +-- truncate_limit: 100 +INSERT INTO T VALUES (1), (2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1), (2)" +== 050 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT foo(4), + ALTER COLUMN c_int SET DEFAULT LENGTH(foo(8)) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_bpchar bpchar(5) DEFAULT foo(4), ALTER COLUMN c_int SET DEFAULT length..." +== 051 +-- truncate_limit: 100 +INSERT INTO T VALUES (3), (4) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (3), (4)" +== 052 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT foo(6), + ALTER COLUMN c_bpchar SET DEFAULT foo(3) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_text text DEFAULT foo(6), ALTER COLUMN c_bpchar SET DEFAULT foo(3)" +== 053 +-- truncate_limit: 100 +INSERT INTO T VALUES (5), (6) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (5), (6)" +== 054 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_date DATE + DEFAULT '2016-06-02'::DATE + LENGTH(foo(10)), + ALTER COLUMN c_text SET DEFAULT foo(12) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_date date DEFAULT '2016-06-02'::date + length(foo(10)), ALTER COLUMN c..." +== 055 +-- truncate_limit: 100 +INSERT INTO T VALUES (7), (8) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (7), (8)" +== 056 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP + DEFAULT '2016-09-01'::DATE + LENGTH(foo(10)), + ALTER COLUMN c_date + SET DEFAULT '2010-01-01'::DATE - LENGTH(foo(4)) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_timestamp timestamp DEFAULT '2016-09-01'::date + length(foo(10)), ALTE..." +== 057 +-- truncate_limit: 100 +INSERT INTO T VALUES (9), (10) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (9), (10)" +== 058 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_array TEXT[] + DEFAULT ('{"This", "is", "' || foo(4) || + '","the", "real", "world"}')::TEXT[], + ALTER COLUMN c_timestamp + SET DEFAULT '1970-12-31'::DATE + LENGTH(foo(30)) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_array text[] DEFAULT ((('{\"This\", \"is\", \"' || foo(4)) || '\",\"the\", \"re..." +== 059 +-- truncate_limit: 100 +INSERT INTO T VALUES (11), (12) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (11), (12)" +== 060 +-- truncate_limit: 100 +ALTER TABLE T ALTER COLUMN c_int DROP DEFAULT, + ALTER COLUMN c_array + SET DEFAULT ('{"This", "is", "' || foo(1) || + '", "fantasy"}')::text[] +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ALTER COLUMN c_int DROP DEFAULT, ALTER COLUMN c_array SET DEFAULT (('{\"This\", \"is\",..." +== 061 +-- truncate_limit: 100 +INSERT INTO T VALUES (13), (14) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (13), (14)" +== 062 +-- truncate_limit: 100 +ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT, + ALTER COLUMN c_date DROP DEFAULT, + ALTER COLUMN c_text DROP DEFAULT, + ALTER COLUMN c_timestamp DROP DEFAULT, + ALTER COLUMN c_array DROP DEFAULT +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ALTER COLUMN c_bpchar DROP DEFAULT, ALTER COLUMN c_date DROP DEFAULT, ALTER COLUMN ..." +== 063 +-- truncate_limit: 100 +INSERT INTO T VALUES (15), (16) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (15), (16)" +== 064 +-- truncate_limit: 100 +SELECT * FROM T +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 065 +-- truncate_limit: 100 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT comp()" +== 066 +-- truncate_limit: 100 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 067 +-- truncate_limit: 100 +-- Test domains with default value for table rewrite. +CREATE DOMAIN domain1 AS int DEFAULT 11 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domain1 AS int DEFAULT 11" +== 068 +-- truncate_limit: 100 +-- constant +CREATE DOMAIN domain2 AS int DEFAULT random(min=>10, max=>100) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domain2 AS int DEFAULT random(min := 10, max := 100)" +== 069 +-- truncate_limit: 100 +-- volatile +CREATE DOMAIN domain3 AS text DEFAULT foo(4) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domain3 AS text DEFAULT foo(4)" +== 070 +-- truncate_limit: 100 +-- stable +CREATE DOMAIN domain4 AS text[] + DEFAULT ('{"This", "is", "' || foo(4) || '","the", "real", "world"}')::TEXT[] +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN domain4 AS text[] DEFAULT ((('{\"This\", \"is\", \"' || foo(4)) || '\",\"the\", \"real\", \"wo..." +== 071 +-- truncate_limit: 100 +CREATE TABLE t2 (a domain1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t2 (a domain1)" +== 072 +-- truncate_limit: 100 +INSERT INTO t2 VALUES (1),(2) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 VALUES (1), (2)" +== 073 +-- truncate_limit: 100 +-- no table rewrite +ALTER TABLE t2 ADD COLUMN b domain1 default 3 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t2 ADD COLUMN b domain1 DEFAULT 3" +== 074 +-- truncate_limit: 100 +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE attnum > 0 AND attrelid = 't2'::regclass ORDER BY attnum" +== 075 +-- truncate_limit: 100 +-- table rewrite should happen +ALTER TABLE t2 ADD COLUMN c domain3 default left(random()::text,3) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t2 ADD COLUMN c domain3 DEFAULT \"left\"(random()::text, 3)" +== 076 +-- truncate_limit: 100 +-- no table rewrite +ALTER TABLE t2 ADD COLUMN d domain4 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t2 ADD COLUMN d domain4" +== 077 +-- truncate_limit: 100 +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE attnum > 0 AND attrelid = 't2'::regclass ORDER BY attnum" +== 078 +-- truncate_limit: 100 +-- table rewrite should happen +ALTER TABLE t2 ADD COLUMN e domain2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t2 ADD COLUMN e domain2" +== 079 +-- truncate_limit: 100 +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attnum" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE attnum > 0 AND attrelid = 't2'::regclass ORDER BY attnum" +== 080 +-- truncate_limit: 100 +SELECT a, b, length(c) = 3 as c_ok, d, e >= 10 as e_ok FROM t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, length(c) = 3 AS c_ok, d, e >= 10 AS e_ok FROM t2" +== 081 +-- truncate_limit: 100 +DROP TABLE t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t2" +== 082 +-- truncate_limit: 100 +DROP DOMAIN domain1 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domain1" +== 083 +-- truncate_limit: 100 +DROP DOMAIN domain2 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domain2" +== 084 +-- truncate_limit: 100 +DROP DOMAIN domain3 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domain3" +== 085 +-- truncate_limit: 100 +DROP DOMAIN domain4 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN domain4" +== 086 +-- truncate_limit: 100 +DROP FUNCTION foo(INT) +-- +FUNCTION: name="foo" function="foo" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION foo(int)" +== 087 +-- truncate_limit: 100 +-- Fall back to full rewrite for volatile expressions +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (pk int NOT NULL PRIMARY KEY)" +== 088 +-- truncate_limit: 100 +INSERT INTO T VALUES (1) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1)" +== 089 +-- truncate_limit: 100 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set('t')" +== 090 +-- truncate_limit: 100 +-- now() is stable, because it returns the transaction timestamp +ALTER TABLE T ADD COLUMN c1 TIMESTAMP DEFAULT now() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c1 timestamp DEFAULT now()" +== 091 +-- truncate_limit: 100 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT comp()" +== 092 +-- truncate_limit: 100 +-- clock_timestamp() is volatile +ALTER TABLE T ADD COLUMN c2 TIMESTAMP DEFAULT clock_timestamp() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c2 timestamp DEFAULT clock_timestamp()" +== 093 +-- truncate_limit: 100 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT comp()" +== 094 +-- truncate_limit: 100 +-- check that we notice insertion of a volatile default argument +CREATE FUNCTION foolme(timestamptz DEFAULT clock_timestamp()) + RETURNS timestamptz + IMMUTABLE AS 'select $1' LANGUAGE sql +-- +FUNCTION: name="foolme" function="foolme" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION foolme(timestamptz = clock_timestamp()) RETURNS timestamptz IMMUTABLE AS $$select..." +== 095 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c3 timestamptz DEFAULT foolme() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c3 timestamptz DEFAULT foolme()" +== 096 +-- truncate_limit: 100 +SELECT attname, atthasmissing, attmissingval FROM pg_attribute + WHERE attrelid = 't'::regclass AND attnum > 0 + ORDER BY attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT attname, atthasmissing, attmissingval FROM pg_attribute WHERE ... ORDER BY attnum" +== 097 +-- truncate_limit: 100 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 098 +-- truncate_limit: 100 +DROP FUNCTION foolme(timestamptz) +-- +FUNCTION: name="foolme" function="foolme" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION foolme(timestamptz)" +== 099 +-- truncate_limit: 100 +-- Simple querie +CREATE TABLE T (pk INT NOT NULL PRIMARY KEY) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (pk int NOT NULL PRIMARY KEY)" +== 100 +-- truncate_limit: 100 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set('t')" +== 101 +-- truncate_limit: 100 +INSERT INTO T SELECT * FROM generate_series(1, 10) a +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t SELECT * FROM generate_series(1, 10) a" +== 102 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_bigint BIGINT NOT NULL DEFAULT -1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_bigint bigint NOT NULL DEFAULT -1" +== 103 +-- truncate_limit: 100 +INSERT INTO T SELECT b, b - 10 FROM generate_series(11, 20) a(b) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t SELECT b, b - 10 FROM generate_series(11, 20) a(b)" +== 104 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'hello' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_text text DEFAULT 'hello'" +== 105 +-- truncate_limit: 100 +INSERT INTO T SELECT b, b - 10, (b + 10)::text FROM generate_series(21, 30) a(b) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t SELECT b, b - 10, (b + 10)::text FROM generate_series(21, 30) a(b)" +== 106 +-- truncate_limit: 100 +-- WHERE clause +SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: SelectStmt +TRUNCATED: "SELECT c_bigint, c_text FROM t WHERE c_bigint = -1 LIMIT 1" +== 107 +-- truncate_limit: 100 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE TRUE, COSTS FALSE) SELECT c_bigint, c_text FROM t WHERE c_bigint = -1 LIMIT 1" +== 108 +-- truncate_limit: 100 +SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_text" +STMT: SelectStmt +TRUNCATED: "SELECT c_bigint, c_text FROM t WHERE c_text = 'hello' LIMIT 1" +== 109 +-- truncate_limit: 100 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_text" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE TRUE, COSTS FALSE) SELECT c_bigint, c_text FROM t WHERE c_text = 'hello' LIMIT 1" +== 110 +-- truncate_limit: 100 +-- COALESCE +SELECT COALESCE(c_bigint, pk), COALESCE(c_text, pk::text) +FROM T +ORDER BY pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT COALESCE(c_bigint, pk), COALESCE(c_text, pk::text) FROM t ORDER BY pk LIMIT 10" +== 111 +-- truncate_limit: 100 +-- Aggregate function +SELECT SUM(c_bigint), MAX(c_text COLLATE "C" ), MIN(c_text COLLATE "C") FROM T +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(c_bigint), max(c_text COLLATE \"C\"), min(c_text COLLATE \"C\") FROM t" +== 112 +-- truncate_limit: 100 +-- ORDER BY +SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t ORDER BY c_bigint, c_text, pk LIMIT 10" +== 113 +-- truncate_limit: 100 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE TRUE, COSTS FALSE) SELECT * FROM t ORDER BY c_bigint, c_text, pk LIMIT 10" +== 114 +-- truncate_limit: 100 +-- LIMIT +SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10" +== 115 +-- truncate_limit: 100 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_bigint" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE TRUE, COSTS FALSE) SELECT * FROM t WHERE c_bigint > -1 ORDER BY c_bigint, c_text..." +== 116 +-- truncate_limit: 100 +-- DELETE with RETURNING +DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING * +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t WHERE pk BETWEEN 10 AND 20 RETURNING *" +== 117 +-- truncate_limit: 100 +EXPLAIN (VERBOSE TRUE, COSTS FALSE) +DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING * +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (VERBOSE TRUE, COSTS FALSE) DELETE FROM t WHERE pk BETWEEN 10 AND 20 RETURNING *" +== 118 +-- truncate_limit: 100 +-- UPDATE +UPDATE T SET c_text = '"' || c_text || '"' WHERE pk < 10 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET c_text = ('\"' || c_text) || '\"' WHERE pk < 10" +== 119 +-- truncate_limit: 100 +SELECT * FROM T WHERE c_text LIKE '"%"' ORDER BY PK +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_text" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t WHERE c_text LIKE '\"%\"' ORDER BY pk" +== 120 +-- truncate_limit: 100 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT comp()" +== 121 +-- truncate_limit: 100 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 122 +-- truncate_limit: 100 +-- Combine with other DDL +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (pk int NOT NULL PRIMARY KEY)" +== 123 +-- truncate_limit: 100 +SELECT set('t') +-- +FUNCTION: name="set" function="set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set('t')" +== 124 +-- truncate_limit: 100 +INSERT INTO T VALUES (1), (2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1), (2)" +== 125 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_int INT NOT NULL DEFAULT -1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_int int NOT NULL DEFAULT -1" +== 126 +-- truncate_limit: 100 +INSERT INTO T VALUES (3), (4) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (3), (4)" +== 127 +-- truncate_limit: 100 +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'Hello' +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN c_text text DEFAULT 'Hello'" +== 128 +-- truncate_limit: 100 +INSERT INTO T VALUES (5), (6) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (5), (6)" +== 129 +-- truncate_limit: 100 +ALTER TABLE T ALTER COLUMN c_text SET DEFAULT 'world', + ALTER COLUMN c_int SET DEFAULT 1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ALTER COLUMN c_text SET DEFAULT 'world', ALTER COLUMN c_int SET DEFAULT 1" +== 130 +-- truncate_limit: 100 +INSERT INTO T VALUES (7), (8) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (7), (8)" +== 131 +-- truncate_limit: 100 +SELECT * FROM T ORDER BY pk +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t ORDER BY pk" +== 132 +-- truncate_limit: 100 +-- Add an index +CREATE INDEX i ON T(c_int, c_text) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX i ON t USING btree (c_int, c_text)" +== 133 +-- truncate_limit: 100 +SELECT c_text FROM T WHERE c_int = -1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="c_int" +STMT: SelectStmt +TRUNCATED: "SELECT c_text FROM t WHERE c_int = -1" +== 134 +-- truncate_limit: 100 +SELECT comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT comp()" +== 135 +-- truncate_limit: 100 +-- query to exercise expand_tuple function +CREATE TABLE t1 AS +SELECT 1::int AS a , 2::int AS b +FROM generate_series(1,20) q +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE t1 AS SELECT 1::int AS a, 2::int AS b FROM generate_series(1, 20) q" +== 136 +-- truncate_limit: 100 +ALTER TABLE t1 ADD COLUMN c text +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t1 ADD COLUMN c text" +== 137 +-- truncate_limit: 100 +SELECT a, + stddev(cast((SELECT sum(1) FROM generate_series(1,20) x) AS float4)) + OVER (PARTITION BY a,b,c ORDER BY b) + AS z +FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1" +== 138 +-- truncate_limit: 100 +DROP TABLE T +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 139 +-- truncate_limit: 100 +-- test that we account for missing columns without defaults correctly +-- in expand_tuple, and that rows are correctly expanded for triggers + +CREATE FUNCTION test_trigger() +RETURNS trigger +LANGUAGE plpgsql +AS $$ + +begin + raise notice 'old tuple: %', to_json(OLD)::text; + if TG_OP = 'DELETE' + then + return OLD; + else + return NEW; + end if; +end; + +$$ +-- +FUNCTION: name="test_trigger" function="test_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_trigger() RETURNS trigger LANGUAGE plpgsql AS $$\n\nbegin\n raise notice 'ol..." +== 140 +-- truncate_limit: 100 +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 141 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, 3)" +== 142 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4" +== 143 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5" +== 144 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 145 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 146 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 147 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 148 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 149 +-- truncate_limit: 100 +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 150 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, 3)" +== 151 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4" +== 152 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int" +== 153 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 154 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 155 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 156 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 157 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 158 +-- truncate_limit: 100 +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 159 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, 3)" +== 160 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int" +== 161 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5" +== 162 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 163 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 164 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 165 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 166 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 167 +-- truncate_limit: 100 +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 168 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,3) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, 3)" +== 169 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int" +== 170 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int" +== 171 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 172 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 173 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 174 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 175 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 176 +-- truncate_limit: 100 +-- same as last 4 tests but here the last original column has a NULL value +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 177 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, NULL)" +== 178 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4" +== 179 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5" +== 180 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 181 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 182 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 183 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 184 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 185 +-- truncate_limit: 100 +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 186 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, NULL)" +== 187 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4" +== 188 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int" +== 189 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 190 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 191 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 192 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 193 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 194 +-- truncate_limit: 100 +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 195 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, NULL)" +== 196 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int" +== 197 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5" +== 198 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 199 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 200 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 201 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 202 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 203 +-- truncate_limit: 100 +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int)" +== 204 +-- truncate_limit: 100 +INSERT INTO t (a,b,c) VALUES (1,2,NULL) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b, c) VALUES (1, 2, NULL)" +== 205 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN x int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN x int" +== 206 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN y int +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN y int" +== 207 +-- truncate_limit: 100 +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE FUNCTION test_trigger()" +== 208 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 209 +-- truncate_limit: 100 +UPDATE t SET y = 2 +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET y = 2" +== 210 +-- truncate_limit: 100 +SELECT * FROM t +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t" +== 211 +-- truncate_limit: 100 +DROP TABLE t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 212 +-- truncate_limit: 100 +-- make sure expanded tuple has correct self pointer +-- it will be required by the RI trigger doing the cascading delete + +CREATE TABLE leader (a int PRIMARY KEY, b int) +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE leader (a int PRIMARY KEY, b int)" +== 213 +-- truncate_limit: 100 +CREATE TABLE follower (a int REFERENCES leader ON DELETE CASCADE, b int) +-- +TABLE: name="follower" schema="" table="follower" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE follower (a int REFERENCES leader ON DELETE CASCADE, b int)" +== 214 +-- truncate_limit: 100 +INSERT INTO leader VALUES (1, 1), (2, 2) +-- +TABLE: name="leader" schema="" table="leader" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO leader VALUES (1, 1), (2, 2)" +== 215 +-- truncate_limit: 100 +ALTER TABLE leader ADD c int +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE leader ADD COLUMN c int" +== 216 +-- truncate_limit: 100 +ALTER TABLE leader DROP c +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE leader DROP c" +== 217 +-- truncate_limit: 100 +DELETE FROM leader +-- +TABLE: name="leader" schema="" table="leader" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM leader" +== 218 +-- truncate_limit: 100 +-- check that ALTER TABLE ... ALTER TYPE does the right thing + +CREATE TABLE vtype( a integer) +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vtype (a int)" +== 219 +-- truncate_limit: 100 +INSERT INTO vtype VALUES (1) +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vtype VALUES (1)" +== 220 +-- truncate_limit: 100 +ALTER TABLE vtype ADD COLUMN b DOUBLE PRECISION DEFAULT 0.2 +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vtype ADD COLUMN b double precision DEFAULT 0.2" +== 221 +-- truncate_limit: 100 +ALTER TABLE vtype ADD COLUMN c BOOLEAN DEFAULT true +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vtype ADD COLUMN c boolean DEFAULT true" +== 222 +-- truncate_limit: 100 +SELECT * FROM vtype +-- +TABLE: name="vtype" schema="" table="vtype" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vtype" +== 223 +-- truncate_limit: 100 +ALTER TABLE vtype + ALTER b TYPE text USING b::text, + ALTER c TYPE text USING c::text +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vtype ALTER COLUMN b TYPE text USING b::text, ALTER COLUMN c TYPE text USING c::text" +== 224 +-- truncate_limit: 100 +SELECT * FROM vtype +-- +TABLE: name="vtype" schema="" table="vtype" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vtype" +== 225 +-- truncate_limit: 100 +-- also check the case that doesn't rewrite the table + +CREATE TABLE vtype2 (a int) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vtype2 (a int)" +== 226 +-- truncate_limit: 100 +INSERT INTO vtype2 VALUES (1) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vtype2 VALUES (1)" +== 227 +-- truncate_limit: 100 +ALTER TABLE vtype2 ADD COLUMN b varchar(10) DEFAULT 'xxx' +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vtype2 ADD COLUMN b varchar(10) DEFAULT 'xxx'" +== 228 +-- truncate_limit: 100 +ALTER TABLE vtype2 ALTER COLUMN b SET DEFAULT 'yyy' +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vtype2 ALTER COLUMN b SET DEFAULT 'yyy'" +== 229 +-- truncate_limit: 100 +INSERT INTO vtype2 VALUES (2) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vtype2 VALUES (2)" +== 230 +-- truncate_limit: 100 +ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20) +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20)" +== 231 +-- truncate_limit: 100 +SELECT * FROM vtype2 +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vtype2" +== 232 +-- truncate_limit: 100 +-- Ensure that defaults are checked when evaluating whether HOT update +-- is possible, this was broken for a while: +-- https://postgr.es/m/20190202133521.ylauh3ckqa7colzj%40alap3.anarazel.de +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 233 +-- truncate_limit: 100 +CREATE TABLE t() +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t ()" +== 234 +-- truncate_limit: 100 +INSERT INTO t DEFAULT VALUES +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO t DEFAULT VALUES" +== 235 +-- truncate_limit: 100 +ALTER TABLE t ADD COLUMN a int DEFAULT 1 +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t ADD COLUMN a int DEFAULT 1" +== 236 +-- truncate_limit: 100 +CREATE INDEX ON t(a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON t USING btree (a)" +== 237 +-- truncate_limit: 100 +-- set column with a default 1 to NULL, due to a bug that wasn't +-- noticed has heap_getattr buggily returned NULL for default columns +UPDATE t SET a = NULL +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t SET a = NULL" +== 238 +-- truncate_limit: 100 +-- verify that index and non-index scans show the same result +SET LOCAL enable_seqscan = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO TRUE" +== 239 +-- truncate_limit: 100 +SELECT * FROM t WHERE a IS NULL +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t WHERE a IS NULL" +== 240 +-- truncate_limit: 100 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO FALSE" +== 241 +-- truncate_limit: 100 +SELECT * FROM t WHERE a IS NULL +-- +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t WHERE a IS NULL" +== 242 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 243 +-- truncate_limit: 100 +-- verify that a default set on a non-plain table doesn't set a missing +-- value on the attribute +CREATE FOREIGN DATA WRAPPER dummy +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER dummy" +== 244 +-- truncate_limit: 100 +CREATE SERVER s0 FOREIGN DATA WRAPPER dummy +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s0 FOREIGN DATA WRAPPER dummy" +== 245 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft1 (c1 integer NOT NULL) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft1 (c1 int NOT NULL) SERVER s0" +== 246 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer DEFAULT 0 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c8 int DEFAULT 0" +== 247 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10)" +== 248 +-- truncate_limit: 100 +SELECT count(*) + FROM pg_attribute + WHERE attrelid = 'ft1'::regclass AND + (attmissingval IS NOT NULL OR atthasmissing) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attmissingval" +FILTER: schema="" table="" column="atthasmissing" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_attribute WHERE ..." +== 249 +-- truncate_limit: 100 +-- cleanup +DROP FOREIGN TABLE ft1 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft1" +== 250 +-- truncate_limit: 100 +DROP SERVER s0 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s0" +== 251 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER dummy +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER dummy" +== 252 +-- truncate_limit: 100 +DROP TABLE vtype +-- +TABLE: name="vtype" schema="" table="vtype" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vtype" +== 253 +-- truncate_limit: 100 +DROP TABLE vtype2 +-- +TABLE: name="vtype2" schema="" table="vtype2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vtype2" +== 254 +-- truncate_limit: 100 +DROP TABLE follower +-- +TABLE: name="follower" schema="" table="follower" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE follower" +== 255 +-- truncate_limit: 100 +DROP TABLE leader +-- +TABLE: name="leader" schema="" table="leader" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE leader" +== 256 +-- truncate_limit: 100 +DROP FUNCTION test_trigger() +-- +FUNCTION: name="test_trigger" function="test_trigger" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION test_trigger()" +== 257 +-- truncate_limit: 100 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1" +== 258 +-- truncate_limit: 100 +DROP FUNCTION set(name) +-- +FUNCTION: name="set" function="set" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION set(name)" +== 259 +-- truncate_limit: 100 +DROP FUNCTION comp() +-- +FUNCTION: name="comp" function="comp" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION comp()" +== 260 +-- truncate_limit: 100 +DROP TABLE m +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE m" +== 261 +-- truncate_limit: 100 +DROP TABLE has_volatile +-- +TABLE: name="has_volatile" schema="" table="has_volatile" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE has_volatile" +== 262 +-- truncate_limit: 100 +DROP EVENT TRIGGER has_volatile_rewrite +-- +STMT: DropStmt +TRUNCATED: "DROP EVENT TRIGGER has_volatile_rewrite" +== 263 +-- truncate_limit: 100 +DROP FUNCTION log_rewrite +-- +FUNCTION: name="log_rewrite" function="log_rewrite" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION log_rewrite" +== 264 +-- truncate_limit: 100 +DROP SCHEMA fast_default +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fast_default" +== 265 +-- truncate_limit: 100 +-- Leave a table with an active fast default in place, for pg_upgrade testing +set search_path = public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO public" +== 266 +-- truncate_limit: 100 +create table has_fast_default(f1 int) +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE has_fast_default (f1 int)" +== 267 +-- truncate_limit: 100 +insert into has_fast_default values(1) +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO has_fast_default VALUES (1)" +== 268 +-- truncate_limit: 100 +alter table has_fast_default add column f2 int default 42 +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE has_fast_default ADD COLUMN f2 int DEFAULT 42" +== 269 +-- truncate_limit: 100 +table has_fast_default +-- +TABLE: name="has_fast_default" schema="" table="has_fast_default" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM has_fast_default" diff --git a/parser/testdata/summary_truncate/postgres_regress/float4.metadata.json b/parser/testdata/summary_truncate/postgres_regress/float4.metadata.json new file mode 100644 index 0000000..a864d8e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/float4.metadata.json @@ -0,0 +1,104 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/float4.test b/parser/testdata/summary_truncate/postgres_regress/float4.test new file mode 100644 index 0000000..b109fc8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/float4.test @@ -0,0 +1,947 @@ +== 001 +-- truncate_limit: 100 +|-- +-- FLOAT4 +|-- + +CREATE TABLE FLOAT4_TBL (f1 float4) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE float4_tbl (f1 float4)" +== 002 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES (' 0.0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES (' 0.0')" +== 003 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30 ') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('1004.30 ')" +== 004 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 ') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES (' -34.84 ')" +== 005 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('1.2345678901234e+20')" +== 006 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('1.2345678901234e-20')" +== 007 +-- truncate_limit: 100 +-- test for over and under flow +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('10e70')" +== 008 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('-10e70')" +== 009 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('10e-70')" +== 010 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('-10e-70')" +== 011 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('10e70'::float8)" +== 012 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('-10e70'::float8)" +== 013 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('10e-70'::float8)" +== 014 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'::float8) +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('-10e-70'::float8)" +== 015 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('10e400')" +== 016 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('-10e400')" +== 017 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('10e-400')" +== 018 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('-10e-400')" +== 019 +-- truncate_limit: 100 +-- bad input +INSERT INTO FLOAT4_TBL(f1) VALUES ('') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('')" +== 020 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES (' ') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES (' ')" +== 021 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('xyz')" +== 022 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('5.0.0')" +== 023 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('5 . 0')" +== 024 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('5. 0')" +== 025 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES (' - 3.0')" +== 026 +-- truncate_limit: 100 +INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5') +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float4_tbl (f1) VALUES ('123 5')" +== 027 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34.5', 'float4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('34.5', 'float4')" +== 028 +-- truncate_limit: 100 +SELECT pg_input_is_valid('xyz', 'float4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('xyz', 'float4')" +== 029 +-- truncate_limit: 100 +SELECT pg_input_is_valid('1e400', 'float4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1e400', 'float4')" +== 030 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1e400', 'float4') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1e400', 'float4')" +== 031 +-- truncate_limit: 100 +-- special inputs +SELECT 'NaN'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::float4" +== 032 +-- truncate_limit: 100 +SELECT 'nan'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::float4" +== 033 +-- truncate_limit: 100 +SELECT ' NAN '::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' NAN '::float4" +== 034 +-- truncate_limit: 100 +SELECT 'infinity'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::float4" +== 035 +-- truncate_limit: 100 +SELECT ' -INFINiTY '::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' -INFINiTY '::float4" +== 036 +-- truncate_limit: 100 +-- bad special inputs +SELECT 'N A N'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'N A N'::float4" +== 037 +-- truncate_limit: 100 +SELECT 'NaN x'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN x'::float4" +== 038 +-- truncate_limit: 100 +SELECT ' INFINITY x'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' INFINITY x'::float4" +== 039 +-- truncate_limit: 100 +SELECT 'Infinity'::float4 + 100.0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::float4 + 100.0" +== 040 +-- truncate_limit: 100 +SELECT 'Infinity'::float4 / 'Infinity'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::float4 / 'Infinity'::float4" +== 041 +-- truncate_limit: 100 +SELECT '42'::float4 / 'Infinity'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::float4 / 'Infinity'::float4" +== 042 +-- truncate_limit: 100 +SELECT 'nan'::float4 / 'nan'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::float4 / 'nan'::float4" +== 043 +-- truncate_limit: 100 +SELECT 'nan'::float4 / '0'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::float4 / '0'::float4" +== 044 +-- truncate_limit: 100 +SELECT 'nan'::numeric::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::numeric::float4" +== 045 +-- truncate_limit: 100 +SELECT * FROM FLOAT4_TBL +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float4_tbl" +== 046 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float4_tbl f WHERE f.f1 <> '1004.3'" +== 047 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float4_tbl f WHERE f.f1 = '1004.3'" +== 048 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1 +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float4_tbl f WHERE '1004.3' > f.f1" +== 049 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float4_tbl f WHERE f.f1 < '1004.3'" +== 050 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1 +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float4_tbl f WHERE '1004.3' >= f.f1" +== 051 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float4_tbl f WHERE f.f1 <= '1004.3'" +== 052 +-- truncate_limit: 100 +SELECT f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 * '-10' AS x FROM float4_tbl f WHERE f.f1 > '0.0'" +== 053 +-- truncate_limit: 100 +SELECT f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 + '-10' AS x FROM float4_tbl f WHERE f.f1 > '0.0'" +== 054 +-- truncate_limit: 100 +SELECT f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 / '-10' AS x FROM float4_tbl f WHERE f.f1 > '0.0'" +== 055 +-- truncate_limit: 100 +SELECT f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 - '-10' AS x FROM float4_tbl f WHERE f.f1 > '0.0'" +== 056 +-- truncate_limit: 100 +-- test divide by zero +SELECT f.f1 / '0.0' from FLOAT4_TBL f +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1 / '0.0' FROM float4_tbl f" +== 057 +-- truncate_limit: 100 +SELECT * FROM FLOAT4_TBL +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float4_tbl" +== 058 +-- truncate_limit: 100 +-- test the unary float4abs operator +SELECT f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +ALIAS: "f"="float4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, @ f.f1 AS abs_f1 FROM float4_tbl f" +== 059 +-- truncate_limit: 100 +UPDATE FLOAT4_TBL + SET f1 = FLOAT4_TBL.f1 * '-1' + WHERE FLOAT4_TBL.f1 > '0.0' +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE float4_tbl SET f1 = float4_tbl.f1 * '-1' WHERE float4_tbl.f1 > '0.0'" +== 060 +-- truncate_limit: 100 +SELECT * FROM FLOAT4_TBL +-- +TABLE: name="float4_tbl" schema="" table="float4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float4_tbl" +== 061 +-- truncate_limit: 100 +-- test edge-case coercions to integer +SELECT '32767.4'::float4::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '32767.4'::float4::int2" +== 062 +-- truncate_limit: 100 +SELECT '32767.6'::float4::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '32767.6'::float4::int2" +== 063 +-- truncate_limit: 100 +SELECT '-32768.4'::float4::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-32768.4'::float4::int2" +== 064 +-- truncate_limit: 100 +SELECT '-32768.6'::float4::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-32768.6'::float4::int2" +== 065 +-- truncate_limit: 100 +SELECT '2147483520'::float4::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483520'::float4::int4" +== 066 +-- truncate_limit: 100 +SELECT '2147483647'::float4::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647'::float4::int4" +== 067 +-- truncate_limit: 100 +SELECT '-2147483648.5'::float4::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648.5'::float4::int4" +== 068 +-- truncate_limit: 100 +SELECT '-2147483900'::float4::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483900'::float4::int4" +== 069 +-- truncate_limit: 100 +SELECT '9223369837831520256'::float4::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223369837831520256'::float4::int8" +== 070 +-- truncate_limit: 100 +SELECT '9223372036854775807'::float4::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807'::float4::int8" +== 071 +-- truncate_limit: 100 +SELECT '-9223372036854775808.5'::float4::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808.5'::float4::int8" +== 072 +-- truncate_limit: 100 +SELECT '-9223380000000000000'::float4::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223380000000000000'::float4::int8" +== 073 +-- truncate_limit: 100 +-- Test for correct input rounding in edge cases. +-- These lists are from Paxson 1991, excluding subnormals and +-- inputs of over 9 sig. digits. + +SELECT float4send('5e-20'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('5e-20'::float4)" +== 074 +-- truncate_limit: 100 +SELECT float4send('67e14'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('67e14'::float4)" +== 075 +-- truncate_limit: 100 +SELECT float4send('985e15'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('985e15'::float4)" +== 076 +-- truncate_limit: 100 +SELECT float4send('55895e-16'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('55895e-16'::float4)" +== 077 +-- truncate_limit: 100 +SELECT float4send('7038531e-32'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('7038531e-32'::float4)" +== 078 +-- truncate_limit: 100 +SELECT float4send('702990899e-20'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('702990899e-20'::float4)" +== 079 +-- truncate_limit: 100 +SELECT float4send('3e-23'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('3e-23'::float4)" +== 080 +-- truncate_limit: 100 +SELECT float4send('57e18'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('57e18'::float4)" +== 081 +-- truncate_limit: 100 +SELECT float4send('789e-35'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('789e-35'::float4)" +== 082 +-- truncate_limit: 100 +SELECT float4send('2539e-18'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('2539e-18'::float4)" +== 083 +-- truncate_limit: 100 +SELECT float4send('76173e28'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('76173e28'::float4)" +== 084 +-- truncate_limit: 100 +SELECT float4send('887745e-11'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('887745e-11'::float4)" +== 085 +-- truncate_limit: 100 +SELECT float4send('5382571e-37'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('5382571e-37'::float4)" +== 086 +-- truncate_limit: 100 +SELECT float4send('82381273e-35'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('82381273e-35'::float4)" +== 087 +-- truncate_limit: 100 +SELECT float4send('750486563e-38'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('750486563e-38'::float4)" +== 088 +-- truncate_limit: 100 +-- Test that the smallest possible normalized input value inputs +-- correctly, either in 9-significant-digit or shortest-decimal +-- format. +|-- +-- exact val is 1.1754943508... +-- shortest val is 1.1754944000 +-- midpoint to next val is 1.1754944208... + +SELECT float4send('1.17549435e-38'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('1.17549435e-38'::float4)" +== 089 +-- truncate_limit: 100 +SELECT float4send('1.1754944e-38'::float4) +-- +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float4send('1.1754944e-38'::float4)" +== 090 +-- truncate_limit: 100 +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). + +create type xfloat4 +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE xfloat4" +== 091 +-- truncate_limit: 100 +create function xfloat4in(cstring) returns xfloat4 immutable strict + language internal as 'int4in' +-- +FUNCTION: name="xfloat4in" function="xfloat4in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION xfloat4in(cstring) RETURNS xfloat4 IMMUTABLE RETURNS NULL ON NULL INPUT LANGUAGE ..." +== 092 +-- truncate_limit: 100 +create function xfloat4out(xfloat4) returns cstring immutable strict + language internal as 'int4out' +-- +FUNCTION: name="xfloat4out" function="xfloat4out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION xfloat4out(xfloat4) RETURNS cstring IMMUTABLE RETURNS NULL ON NULL INPUT LANGUAGE..." +== 093 +-- truncate_limit: 100 +create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE xfloat4 (input = xfloat4in, output = xfloat4out, \"like\" = float4)" +== 094 +-- truncate_limit: 100 +create cast (xfloat4 as float4) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (xfloat4 AS float4) WITHOUT FUNCTION" +== 095 +-- truncate_limit: 100 +create cast (float4 as xfloat4) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (float4 AS xfloat4) WITHOUT FUNCTION" +== 096 +-- truncate_limit: 100 +create cast (xfloat4 as integer) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (xfloat4 AS int) WITHOUT FUNCTION" +== 097 +-- truncate_limit: 100 +create cast (integer as xfloat4) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int AS xfloat4) WITHOUT FUNCTION" +== 098 +-- truncate_limit: 100 +-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm + +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. + +with testdata(bits) as (values + -- small subnormals + (x'00000001'), + (x'00000002'), (x'00000003'), + (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'), + (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'), + -- stress values + (x'0053c4f4'), -- 7693e-42 + (x'006c85c4'), -- 996622e-44 + (x'0041ca76'), -- 60419369e-46 + (x'004b7678'), -- 6930161142e-48 + -- taken from upstream testsuite + (x'00000007'), + (x'00424fe2'), + -- borderline between subnormal and normal + (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff')) +select float4send(flt) as ibits, + flt + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH testdata(bits) AS (...) SELECT ... FROM (SELECT ... FROM testdata OFFSET 0) s" +== 099 +-- truncate_limit: 100 +with testdata(bits) as (values + (x'00000000'), + -- smallest normal values + (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'), + (x'00800006'), + -- small normal values chosen for short vs. long output + (x'008002f1'), (x'008002f2'), (x'008002f3'), + (x'00800e17'), (x'00800e18'), (x'00800e19'), + -- assorted values (random mantissae) + (x'01000001'), (x'01102843'), (x'01a52c98'), + (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'), + (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'), + (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'), + (x'1f850283'), (x'2874a9d6'), + -- values around 5e-08 + (x'3356bf94'), (x'3356bf95'), (x'3356bf96'), + -- around 1e-07 + (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'), + -- around 3e-07 .. 1e-04 + (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'), + (x'350637bc'), (x'350637bd'), (x'350637be'), + (x'35719786'), (x'35719787'), (x'35719788'), + (x'358637bc'), (x'358637bd'), (x'358637be'), + (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'), + (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'), + -- format crossover at 1e-04 + (x'38d1b714'), (x'38d1b715'), (x'38d1b716'), + (x'38d1b717'), (x'38d1b718'), (x'38d1b719'), + (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'), + (x'38d1b71d'), + -- + (x'38dffffe'), (x'38dfffff'), (x'38e00000'), + (x'38efffff'), (x'38f00000'), (x'38f00001'), + (x'3a83126e'), (x'3a83126f'), (x'3a831270'), + (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'), + (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'), + -- chosen to need 9 digits for 3dcccd70 + (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'), + -- + (x'3effffff'), (x'3f000000'), (x'3f000001'), + (x'3f333332'), (x'3f333333'), (x'3f333334'), + -- approach 1.0 with increasing numbers of 9s + (x'3f666665'), (x'3f666666'), (x'3f666667'), + (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'), + (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'), + (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'), + (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'), + (x'3f7fffee'), (x'3f7fffef'), + -- values very close to 1 + (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'), + (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'), + (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'), + (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'), + (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'), + (x'3f7fffff'), + (x'3f800000'), + (x'3f800001'), (x'3f800002'), (x'3f800003'), + (x'3f800004'), (x'3f800005'), (x'3f800006'), + (x'3f800007'), (x'3f800008'), (x'3f800009'), + -- values 1 to 1.1 + (x'3f80000f'), (x'3f800010'), (x'3f800011'), + (x'3f800012'), (x'3f800013'), (x'3f800014'), + (x'3f800017'), (x'3f800018'), (x'3f800019'), + (x'3f80001a'), (x'3f80001b'), (x'3f80001c'), + (x'3f800029'), (x'3f80002a'), (x'3f80002b'), + (x'3f800053'), (x'3f800054'), (x'3f800055'), + (x'3f800346'), (x'3f800347'), (x'3f800348'), + (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'), + (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'), + (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'), + -- + (x'3fc90fdb'), -- pi/2 + (x'402df854'), -- e + (x'40490fdb'), -- pi + -- + (x'409fffff'), (x'40a00000'), (x'40a00001'), + (x'40afffff'), (x'40b00000'), (x'40b00001'), + (x'411fffff'), (x'41200000'), (x'41200001'), + (x'42c7ffff'), (x'42c80000'), (x'42c80001'), + (x'4479ffff'), (x'447a0000'), (x'447a0001'), + (x'461c3fff'), (x'461c4000'), (x'461c4001'), + (x'47c34fff'), (x'47c35000'), (x'47c35001'), + (x'497423ff'), (x'49742400'), (x'49742401'), + (x'4b18967f'), (x'4b189680'), (x'4b189681'), + (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'), + (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'), + (x'501502f8'), (x'501502f9'), (x'501502fa'), + (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'), + -- stress values + (x'1f6c1e4a'), -- 5e-20 + (x'59be6cea'), -- 67e14 + (x'5d5ab6c4'), -- 985e15 + (x'2cc4a9bd'), -- 55895e-16 + (x'15ae43fd'), -- 7038531e-32 + (x'2cf757ca'), -- 702990899e-20 + (x'665ba998'), -- 25933168707e13 + (x'743c3324'), -- 596428896559e20 + -- exercise fixed-point memmoves + (x'47f1205a'), + (x'4640e6ae'), + (x'449a5225'), + (x'42f6e9d5'), + (x'414587dd'), + (x'3f9e064b'), + -- these cases come from the upstream's testsuite + -- BoundaryRoundEven + (x'4c000004'), + (x'50061c46'), + (x'510006a8'), + -- ExactValueRoundEven + (x'48951f84'), + (x'45fd1840'), + -- LotsOfTrailingZeros + (x'39800000'), + (x'3b200000'), + (x'3b900000'), + (x'3bd00000'), + -- Regression + (x'63800000'), + (x'4b000000'), + (x'4b800000'), + (x'4c000001'), + (x'4c800b0d'), + (x'00d24584'), + (x'00d90b88'), + (x'45803f34'), + (x'4f9f24f7'), + (x'3a8722c3'), + (x'5c800041'), + (x'15ae43fd'), + (x'5d4cccfb'), + (x'4c800001'), + (x'57800ed8'), + (x'5f000000'), + (x'700000f0'), + (x'5f23e9ac'), + (x'5e9502f9'), + (x'5e8012b1'), + (x'3c000028'), + (x'60cde861'), + (x'03aa2a50'), + (x'43480000'), + (x'4c000000'), + -- LooksLikePow5 + (x'5D1502F9'), + (x'5D9502F9'), + (x'5E1502F9'), + -- OutputLength + (x'3f99999a'), + (x'3f9d70a4'), + (x'3f9df3b6'), + (x'3f9e0419'), + (x'3f9e0610'), + (x'3f9e064b'), + (x'3f9e0651'), + (x'03d20cfe') +) +select float4send(flt) as ibits, + flt, + flt::text::float4 as r_flt, + float4send(flt::text::float4) as obits, + float4send(flt::text::float4) = float4send(flt) as correct + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +FUNCTION: name="float4send" function="float4send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH testdata(bits) AS (...) SELECT ... FROM (SELECT ... FROM testdata OFFSET 0) s" +== 100 +-- truncate_limit: 100 +-- clean up, lest opr_sanity complain +drop type xfloat4 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE xfloat4 CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/float8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/float8.metadata.json new file mode 100644 index 0000000..194b55b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/float8.metadata.json @@ -0,0 +1,173 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/float8.test b/parser/testdata/summary_truncate/postgres_regress/float8.test new file mode 100644 index 0000000..250ad66 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/float8.test @@ -0,0 +1,1511 @@ +== 001 +-- truncate_limit: 100 +|-- +-- FLOAT8 +|-- + +|-- +-- Build a table for testing +-- (This temporarily hides the table created in test_setup.sql) +|-- + +CREATE TEMP TABLE FLOAT8_TBL(f1 float8) +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE float8_tbl (f1 float8)" +== 002 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 ') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES (' 0.0 ')" +== 003 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 ') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('1004.30 ')" +== 004 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES (' -34.84')" +== 005 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('1.2345678901234e+200')" +== 006 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('1.2345678901234e-200')" +== 007 +-- truncate_limit: 100 +-- test for underflow and overflow handling +SELECT '10e400'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '10e400'::float8" +== 008 +-- truncate_limit: 100 +SELECT '-10e400'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-10e400'::float8" +== 009 +-- truncate_limit: 100 +SELECT '10e-400'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '10e-400'::float8" +== 010 +-- truncate_limit: 100 +SELECT '-10e-400'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-10e-400'::float8" +== 011 +-- truncate_limit: 100 +-- test smallest normalized input +SELECT float8send('2.2250738585072014E-308'::float8) +-- +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT float8send('2.2250738585072014E-308'::float8)" +== 012 +-- truncate_limit: 100 +-- bad input +INSERT INTO FLOAT8_TBL(f1) VALUES ('') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('')" +== 013 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES (' ') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES (' ')" +== 014 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('xyz')" +== 015 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('5.0.0')" +== 016 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('5 . 0')" +== 017 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('5. 0')" +== 018 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES (' - 3')" +== 019 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('123 5')" +== 020 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34.5', 'float8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('34.5', 'float8')" +== 021 +-- truncate_limit: 100 +SELECT pg_input_is_valid('xyz', 'float8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('xyz', 'float8')" +== 022 +-- truncate_limit: 100 +SELECT pg_input_is_valid('1e4000', 'float8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1e4000', 'float8')" +== 023 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1e4000', 'float8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1e4000', 'float8')" +== 024 +-- truncate_limit: 100 +-- special inputs +SELECT 'NaN'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::float8" +== 025 +-- truncate_limit: 100 +SELECT 'nan'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::float8" +== 026 +-- truncate_limit: 100 +SELECT ' NAN '::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' NAN '::float8" +== 027 +-- truncate_limit: 100 +SELECT 'infinity'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::float8" +== 028 +-- truncate_limit: 100 +SELECT ' -INFINiTY '::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' -INFINiTY '::float8" +== 029 +-- truncate_limit: 100 +-- bad special inputs +SELECT 'N A N'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'N A N'::float8" +== 030 +-- truncate_limit: 100 +SELECT 'NaN x'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN x'::float8" +== 031 +-- truncate_limit: 100 +SELECT ' INFINITY x'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' INFINITY x'::float8" +== 032 +-- truncate_limit: 100 +SELECT 'Infinity'::float8 + 100.0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::float8 + 100.0" +== 033 +-- truncate_limit: 100 +SELECT 'Infinity'::float8 / 'Infinity'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::float8 / 'Infinity'::float8" +== 034 +-- truncate_limit: 100 +SELECT '42'::float8 / 'Infinity'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::float8 / 'Infinity'::float8" +== 035 +-- truncate_limit: 100 +SELECT 'nan'::float8 / 'nan'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::float8 / 'nan'::float8" +== 036 +-- truncate_limit: 100 +SELECT 'nan'::float8 / '0'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::float8 / '0'::float8" +== 037 +-- truncate_limit: 100 +SELECT 'nan'::numeric::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::numeric::float8" +== 038 +-- truncate_limit: 100 +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float8_tbl" +== 039 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float8_tbl f WHERE f.f1 <> '1004.3'" +== 040 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float8_tbl f WHERE f.f1 = '1004.3'" +== 041 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float8_tbl f WHERE '1004.3' > f.f1" +== 042 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float8_tbl f WHERE f.f1 < '1004.3'" +== 043 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float8_tbl f WHERE '1004.3' >= f.f1" +== 044 +-- truncate_limit: 100 +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.* FROM float8_tbl f WHERE f.f1 <= '1004.3'" +== 045 +-- truncate_limit: 100 +SELECT f.f1, f.f1 * '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 * '-10' AS x FROM float8_tbl f WHERE f.f1 > '0.0'" +== 046 +-- truncate_limit: 100 +SELECT f.f1, f.f1 + '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 + '-10' AS x FROM float8_tbl f WHERE f.f1 > '0.0'" +== 047 +-- truncate_limit: 100 +SELECT f.f1, f.f1 / '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 / '-10' AS x FROM float8_tbl f WHERE f.f1 > '0.0'" +== 048 +-- truncate_limit: 100 +SELECT f.f1, f.f1 - '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, f.f1 - '-10' AS x FROM float8_tbl f WHERE f.f1 > '0.0'" +== 049 +-- truncate_limit: 100 +SELECT f.f1 ^ '2.0' AS square_f1 + FROM FLOAT8_TBL f where f.f1 = '1004.3' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1 ^ '2.0' AS square_f1 FROM float8_tbl f WHERE f.f1 = '1004.3'" +== 050 +-- truncate_limit: 100 +-- absolute value +SELECT f.f1, @f.f1 AS abs_f1 + FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, @ f.f1 AS abs_f1 FROM float8_tbl f" +== 051 +-- truncate_limit: 100 +-- truncate +SELECT f.f1, trunc(f.f1) AS trunc_f1 + FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, trunc(f.f1) AS trunc_f1 FROM float8_tbl f" +== 052 +-- truncate_limit: 100 +-- round +SELECT f.f1, round(f.f1) AS round_f1 + FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, round(f.f1) AS round_f1 FROM float8_tbl f" +== 053 +-- truncate_limit: 100 +-- ceil / ceiling +select ceil(f1) as ceil_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ceil" function="ceil" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ceil(f1) AS ceil_f1 FROM float8_tbl f" +== 054 +-- truncate_limit: 100 +select ceiling(f1) as ceiling_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ceiling" function="ceiling" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ceiling(f1) AS ceiling_f1 FROM float8_tbl f" +== 055 +-- truncate_limit: 100 +-- floor +select floor(f1) as floor_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="floor" function="floor" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT floor(f1) AS floor_f1 FROM float8_tbl f" +== 056 +-- truncate_limit: 100 +-- sign +select sign(f1) as sign_f1 from float8_tbl f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="sign" function="sign" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sign(f1) AS sign_f1 FROM float8_tbl f" +== 057 +-- truncate_limit: 100 +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO 0" +== 058 +-- truncate_limit: 100 +-- square root +SELECT sqrt(float8 '64') AS eight +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt('64'::float8) AS eight" +== 059 +-- truncate_limit: 100 +SELECT |/ float8 '64' AS eight +-- +STMT: SelectStmt +TRUNCATED: "SELECT |/ '64'::float8 AS eight" +== 060 +-- truncate_limit: 100 +SELECT f.f1, |/f.f1 AS sqrt_f1 + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, |/ f.f1 AS sqrt_f1 FROM float8_tbl f WHERE f.f1 > '0.0'" +== 061 +-- truncate_limit: 100 +-- power +SELECT power(float8 '144', float8 '0.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('144'::float8, '0.5'::float8)" +== 062 +-- truncate_limit: 100 +SELECT power(float8 'NaN', float8 '0.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('NaN'::float8, '0.5'::float8)" +== 063 +-- truncate_limit: 100 +SELECT power(float8 '144', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('144'::float8, 'NaN'::float8)" +== 064 +-- truncate_limit: 100 +SELECT power(float8 'NaN', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('NaN'::float8, 'NaN'::float8)" +== 065 +-- truncate_limit: 100 +SELECT power(float8 '-1', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-1'::float8, 'NaN'::float8)" +== 066 +-- truncate_limit: 100 +SELECT power(float8 '1', float8 'NaN') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('1'::float8, 'NaN'::float8)" +== 067 +-- truncate_limit: 100 +SELECT power(float8 'NaN', float8 '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('NaN'::float8, '0'::float8)" +== 068 +-- truncate_limit: 100 +SELECT power(float8 'inf', float8 '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('inf'::float8, '0'::float8)" +== 069 +-- truncate_limit: 100 +SELECT power(float8 '-inf', float8 '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, '0'::float8)" +== 070 +-- truncate_limit: 100 +SELECT power(float8 '0', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('0'::float8, 'inf'::float8)" +== 071 +-- truncate_limit: 100 +SELECT power(float8 '0', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('0'::float8, '-inf'::float8)" +== 072 +-- truncate_limit: 100 +SELECT power(float8 '1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('1'::float8, 'inf'::float8)" +== 073 +-- truncate_limit: 100 +SELECT power(float8 '1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('1'::float8, '-inf'::float8)" +== 074 +-- truncate_limit: 100 +SELECT power(float8 '-1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-1'::float8, 'inf'::float8)" +== 075 +-- truncate_limit: 100 +SELECT power(float8 '-1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-1'::float8, '-inf'::float8)" +== 076 +-- truncate_limit: 100 +SELECT power(float8 '0.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('0.1'::float8, 'inf'::float8)" +== 077 +-- truncate_limit: 100 +SELECT power(float8 '-0.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-0.1'::float8, 'inf'::float8)" +== 078 +-- truncate_limit: 100 +SELECT power(float8 '1.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('1.1'::float8, 'inf'::float8)" +== 079 +-- truncate_limit: 100 +SELECT power(float8 '-1.1', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-1.1'::float8, 'inf'::float8)" +== 080 +-- truncate_limit: 100 +SELECT power(float8 '0.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('0.1'::float8, '-inf'::float8)" +== 081 +-- truncate_limit: 100 +SELECT power(float8 '-0.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-0.1'::float8, '-inf'::float8)" +== 082 +-- truncate_limit: 100 +SELECT power(float8 '1.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('1.1'::float8, '-inf'::float8)" +== 083 +-- truncate_limit: 100 +SELECT power(float8 '-1.1', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-1.1'::float8, '-inf'::float8)" +== 084 +-- truncate_limit: 100 +SELECT power(float8 'inf', float8 '-2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('inf'::float8, '-2'::float8)" +== 085 +-- truncate_limit: 100 +SELECT power(float8 'inf', float8 '2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('inf'::float8, '2'::float8)" +== 086 +-- truncate_limit: 100 +SELECT power(float8 'inf', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('inf'::float8, 'inf'::float8)" +== 087 +-- truncate_limit: 100 +SELECT power(float8 'inf', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('inf'::float8, '-inf'::float8)" +== 088 +-- truncate_limit: 100 +-- Intel's icc misoptimizes the code that controls the sign of this result, +-- even with -mp1. Pending a fix for that, only test for "is it zero". +SELECT power(float8 '-inf', float8 '-2') = '0' +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, '-2'::float8) = '0'" +== 089 +-- truncate_limit: 100 +SELECT power(float8 '-inf', float8 '-3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, '-3'::float8)" +== 090 +-- truncate_limit: 100 +SELECT power(float8 '-inf', float8 '2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, '2'::float8)" +== 091 +-- truncate_limit: 100 +SELECT power(float8 '-inf', float8 '3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, '3'::float8)" +== 092 +-- truncate_limit: 100 +SELECT power(float8 '-inf', float8 '3.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, '3.5'::float8)" +== 093 +-- truncate_limit: 100 +SELECT power(float8 '-inf', float8 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, 'inf'::float8)" +== 094 +-- truncate_limit: 100 +SELECT power(float8 '-inf', float8 '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::float8, '-inf'::float8)" +== 095 +-- truncate_limit: 100 +-- take exp of ln(f.f1) +SELECT f.f1, exp(ln(f.f1)) AS exp_ln_f1 + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, exp(ln(f.f1)) AS exp_ln_f1 FROM float8_tbl f WHERE f.f1 > '0.0'" +== 096 +-- truncate_limit: 100 +-- check edge cases for exp +SELECT exp('inf'::float8), exp('-inf'::float8), exp('nan'::float8) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp('inf'::float8), exp('-inf'::float8), exp('nan'::float8)" +== 097 +-- truncate_limit: 100 +-- cube root +SELECT ||/ float8 '27' AS three +-- +STMT: SelectStmt +TRUNCATED: "SELECT ||/ '27'::float8 AS three" +== 098 +-- truncate_limit: 100 +SELECT f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1, ||/ f.f1 AS cbrt_f1 FROM float8_tbl f" +== 099 +-- truncate_limit: 100 +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float8_tbl" +== 100 +-- truncate_limit: 100 +UPDATE FLOAT8_TBL + SET f1 = FLOAT8_TBL.f1 * '-1' + WHERE FLOAT8_TBL.f1 > '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE float8_tbl SET f1 = float8_tbl.f1 * '-1' WHERE float8_tbl.f1 > '0.0'" +== 101 +-- truncate_limit: 100 +SELECT f.f1 * '1e200' from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1 * '1e200' FROM float8_tbl f" +== 102 +-- truncate_limit: 100 +SELECT f.f1 ^ '1e200' from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1 ^ '1e200' FROM float8_tbl f" +== 103 +-- truncate_limit: 100 +SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (((0 ^ 0) + (0 ^ 1)) + (0 ^ 0.0)) + (0 ^ 0.5)" +== 104 +-- truncate_limit: 100 +SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ln(f.f1) FROM float8_tbl f WHERE f.f1 = '0.0'" +== 105 +-- truncate_limit: 100 +SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FILTER: schema="" table="f" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ln(f.f1) FROM float8_tbl f WHERE f.f1 < '0.0'" +== 106 +-- truncate_limit: 100 +SELECT exp(f.f1) from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(f.f1) FROM float8_tbl f" +== 107 +-- truncate_limit: 100 +SELECT f.f1 / '0.0' from FLOAT8_TBL f +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "f"="float8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f.f1 / '0.0' FROM float8_tbl f" +== 108 +-- truncate_limit: 100 +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float8_tbl" +== 109 +-- truncate_limit: 100 +-- hyperbolic functions +-- we run these with extra_float_digits = 0 too, since different platforms +-- tend to produce results that vary in the last place. +SELECT sinh(float8 '1') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sinh('1'::float8)" +== 110 +-- truncate_limit: 100 +SELECT cosh(float8 '1') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cosh('1'::float8)" +== 111 +-- truncate_limit: 100 +SELECT tanh(float8 '1') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tanh('1'::float8)" +== 112 +-- truncate_limit: 100 +SELECT asinh(float8 '1') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT asinh('1'::float8)" +== 113 +-- truncate_limit: 100 +SELECT acosh(float8 '2') +-- +FUNCTION: name="acosh" function="acosh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT acosh('2'::float8)" +== 114 +-- truncate_limit: 100 +SELECT atanh(float8 '0.5') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT atanh('0.5'::float8)" +== 115 +-- truncate_limit: 100 +-- test Inf/NaN cases for hyperbolic functions +SELECT sinh(float8 'infinity') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sinh('infinity'::float8)" +== 116 +-- truncate_limit: 100 +SELECT sinh(float8 '-infinity') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sinh('-infinity'::float8)" +== 117 +-- truncate_limit: 100 +SELECT sinh(float8 'nan') +-- +FUNCTION: name="sinh" function="sinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sinh('nan'::float8)" +== 118 +-- truncate_limit: 100 +SELECT cosh(float8 'infinity') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cosh('infinity'::float8)" +== 119 +-- truncate_limit: 100 +SELECT cosh(float8 '-infinity') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cosh('-infinity'::float8)" +== 120 +-- truncate_limit: 100 +SELECT cosh(float8 'nan') +-- +FUNCTION: name="cosh" function="cosh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cosh('nan'::float8)" +== 121 +-- truncate_limit: 100 +SELECT tanh(float8 'infinity') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tanh('infinity'::float8)" +== 122 +-- truncate_limit: 100 +SELECT tanh(float8 '-infinity') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tanh('-infinity'::float8)" +== 123 +-- truncate_limit: 100 +SELECT tanh(float8 'nan') +-- +FUNCTION: name="tanh" function="tanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tanh('nan'::float8)" +== 124 +-- truncate_limit: 100 +SELECT asinh(float8 'infinity') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT asinh('infinity'::float8)" +== 125 +-- truncate_limit: 100 +SELECT asinh(float8 '-infinity') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT asinh('-infinity'::float8)" +== 126 +-- truncate_limit: 100 +SELECT asinh(float8 'nan') +-- +FUNCTION: name="asinh" function="asinh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT asinh('nan'::float8)" +== 127 +-- truncate_limit: 100 +-- acosh(Inf) should be Inf, but some mingw versions produce NaN, so skip test +-- SELECT acosh(float8 'infinity'); +SELECT acosh(float8 '-infinity') +-- +FUNCTION: name="acosh" function="acosh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT acosh('-infinity'::float8)" +== 128 +-- truncate_limit: 100 +SELECT acosh(float8 'nan') +-- +FUNCTION: name="acosh" function="acosh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT acosh('nan'::float8)" +== 129 +-- truncate_limit: 100 +SELECT atanh(float8 'infinity') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT atanh('infinity'::float8)" +== 130 +-- truncate_limit: 100 +SELECT atanh(float8 '-infinity') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT atanh('-infinity'::float8)" +== 131 +-- truncate_limit: 100 +SELECT atanh(float8 'nan') +-- +FUNCTION: name="atanh" function="atanh" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT atanh('nan'::float8)" +== 132 +-- truncate_limit: 100 +-- error functions +-- we run these with extra_float_digits = -1, to get consistently rounded +-- results on all platforms. +SET extra_float_digits = -1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO -1" +== 133 +-- truncate_limit: 100 +SELECT x, + erf(x), + erfc(x) +FROM (VALUES (float8 '-infinity'), + (-28), (-6), (-3.4), (-2.1), (-1.1), (-0.45), + (-1.2e-9), (-2.3e-13), (-1.2e-17), (0), + (1.2e-17), (2.3e-13), (1.2e-9), + (0.45), (1.1), (2.1), (3.4), (6), (28), + (float8 'infinity'), (float8 'nan')) AS t(x) +-- +FUNCTION: name="erf" function="erf" schema="" ctx=Call +FUNCTION: name="erfc" function="erfc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, erf(x), erfc(x) FROM (VALUES (...)) t(x)" +== 134 +-- truncate_limit: 100 +RESET extra_float_digits +-- +STMT: VariableSetStmt +TRUNCATED: "RESET extra_float_digits" +== 135 +-- truncate_limit: 100 +-- test for over- and underflow +INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('10e400')" +== 136 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('-10e400')" +== 137 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('10e-400')" +== 138 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES ('-10e-400')" +== 139 +-- truncate_limit: 100 +DROP TABLE FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE float8_tbl" +== 140 +-- truncate_limit: 100 +-- Check the float8 values exported for use by other tests + +SELECT * FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float8_tbl" +== 141 +-- truncate_limit: 100 +-- test edge-case coercions to integer +SELECT '32767.4'::float8::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '32767.4'::float8::int2" +== 142 +-- truncate_limit: 100 +SELECT '32767.6'::float8::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '32767.6'::float8::int2" +== 143 +-- truncate_limit: 100 +SELECT '-32768.4'::float8::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-32768.4'::float8::int2" +== 144 +-- truncate_limit: 100 +SELECT '-32768.6'::float8::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-32768.6'::float8::int2" +== 145 +-- truncate_limit: 100 +SELECT '2147483647.4'::float8::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647.4'::float8::int4" +== 146 +-- truncate_limit: 100 +SELECT '2147483647.6'::float8::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647.6'::float8::int4" +== 147 +-- truncate_limit: 100 +SELECT '-2147483648.4'::float8::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648.4'::float8::int4" +== 148 +-- truncate_limit: 100 +SELECT '-2147483648.6'::float8::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648.6'::float8::int4" +== 149 +-- truncate_limit: 100 +SELECT '9223372036854773760'::float8::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854773760'::float8::int8" +== 150 +-- truncate_limit: 100 +SELECT '9223372036854775807'::float8::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807'::float8::int8" +== 151 +-- truncate_limit: 100 +SELECT '-9223372036854775808.5'::float8::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808.5'::float8::int8" +== 152 +-- truncate_limit: 100 +SELECT '-9223372036854780000'::float8::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854780000'::float8::int8" +== 153 +-- truncate_limit: 100 +-- test exact cases for trigonometric functions in degrees + +SELECT x, + sind(x), + sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact +FROM (VALUES (0), (30), (90), (150), (180), + (210), (270), (330), (360)) AS t(x) +-- +FUNCTION: name="sind" function="sind" schema="" ctx=Call +FUNCTION: name="sind" function="sind" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, sind(x), sind(x) IN (-1, -0.5, 0, 0.5, 1) AS sind_exact FROM (VALUES (...)) t(x)" +== 154 +-- truncate_limit: 100 +SELECT x, + cosd(x), + cosd(x) IN (-1,-0.5,0,0.5,1) AS cosd_exact +FROM (VALUES (0), (60), (90), (120), (180), + (240), (270), (300), (360)) AS t(x) +-- +FUNCTION: name="cosd" function="cosd" schema="" ctx=Call +FUNCTION: name="cosd" function="cosd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, cosd(x), cosd(x) IN (-1, -0.5, 0, 0.5, 1) AS cosd_exact FROM (VALUES (...)) t(x)" +== 155 +-- truncate_limit: 100 +SELECT x, + tand(x), + tand(x) IN ('-Infinity'::float8,-1,0, + 1,'Infinity'::float8) AS tand_exact, + cotd(x), + cotd(x) IN ('-Infinity'::float8,-1,0, + 1,'Infinity'::float8) AS cotd_exact +FROM (VALUES (0), (45), (90), (135), (180), + (225), (270), (315), (360)) AS t(x) +-- +FUNCTION: name="tand" function="tand" schema="" ctx=Call +FUNCTION: name="tand" function="tand" schema="" ctx=Call +FUNCTION: name="cotd" function="cotd" schema="" ctx=Call +FUNCTION: name="cotd" function="cotd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(x)" +== 156 +-- truncate_limit: 100 +SELECT x, + asind(x), + asind(x) IN (-90,-30,0,30,90) AS asind_exact, + acosd(x), + acosd(x) IN (0,60,90,120,180) AS acosd_exact +FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x) +-- +FUNCTION: name="asind" function="asind" schema="" ctx=Call +FUNCTION: name="asind" function="asind" schema="" ctx=Call +FUNCTION: name="acosd" function="acosd" schema="" ctx=Call +FUNCTION: name="acosd" function="acosd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(x)" +== 157 +-- truncate_limit: 100 +SELECT x, + atand(x), + atand(x) IN (-90,-45,0,45,90) AS atand_exact +FROM (VALUES ('-Infinity'::float8), (-1), (0), (1), + ('Infinity'::float8)) AS t(x) +-- +FUNCTION: name="atand" function="atand" schema="" ctx=Call +FUNCTION: name="atand" function="atand" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, atand(x), atand(x) IN (-90, -45, 0, 45, 90) AS atand_exact FROM (VALUES (...)) t(x)" +== 158 +-- truncate_limit: 100 +SELECT x, y, + atan2d(y, x), + atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact +FROM (SELECT 10*cosd(a), 10*sind(a) + FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y) +-- +FUNCTION: name="atan2d" function="atan2d" schema="" ctx=Call +FUNCTION: name="atan2d" function="atan2d" schema="" ctx=Call +FUNCTION: name="cosd" function="cosd" schema="" ctx=Call +FUNCTION: name="sind" function="sind" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(0, 360, 90) t(a)) t(x, y)" +== 159 +-- truncate_limit: 100 +|-- +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). + +create type xfloat8 +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE xfloat8" +== 160 +-- truncate_limit: 100 +create function xfloat8in(cstring) returns xfloat8 immutable strict + language internal as 'int8in' +-- +FUNCTION: name="xfloat8in" function="xfloat8in" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION xfloat8in(cstring) RETURNS xfloat8 IMMUTABLE RETURNS NULL ON NULL INPUT LANGUAGE ..." +== 161 +-- truncate_limit: 100 +create function xfloat8out(xfloat8) returns cstring immutable strict + language internal as 'int8out' +-- +FUNCTION: name="xfloat8out" function="xfloat8out" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION xfloat8out(xfloat8) RETURNS cstring IMMUTABLE RETURNS NULL ON NULL INPUT LANGUAGE..." +== 162 +-- truncate_limit: 100 +create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TYPE xfloat8 (input = xfloat8in, output = xfloat8out, \"like\" = float8)" +== 163 +-- truncate_limit: 100 +create cast (xfloat8 as float8) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (xfloat8 AS float8) WITHOUT FUNCTION" +== 164 +-- truncate_limit: 100 +create cast (float8 as xfloat8) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (float8 AS xfloat8) WITHOUT FUNCTION" +== 165 +-- truncate_limit: 100 +create cast (xfloat8 as bigint) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (xfloat8 AS bigint) WITHOUT FUNCTION" +== 166 +-- truncate_limit: 100 +create cast (bigint as xfloat8) without function +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (bigint AS xfloat8) WITHOUT FUNCTION" +== 167 +-- truncate_limit: 100 +-- float8: seeeeeee eeeeeeee eeeeeeee mmmmmmmm mmmmmmmm(x4) + +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. + +with testdata(bits) as (values + -- small subnormals + (x'0000000000000001'), + (x'0000000000000002'), (x'0000000000000003'), + (x'0000000000001000'), (x'0000000100000000'), + (x'0000010000000000'), (x'0000010100000000'), + (x'0000400000000000'), (x'0000400100000000'), + (x'0000800000000000'), (x'0000800000000001'), + -- these values taken from upstream testsuite + (x'00000000000f4240'), + (x'00000000016e3600'), + (x'0000008cdcdea440'), + -- borderline between subnormal and normal + (x'000ffffffffffff0'), (x'000ffffffffffff1'), + (x'000ffffffffffffe'), (x'000fffffffffffff')) +select float8send(flt) as ibits, + flt + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH testdata(bits) AS (...) SELECT ... FROM (SELECT ... FROM testdata OFFSET 0) s" +== 168 +-- truncate_limit: 100 +-- round-trip tests + +with testdata(bits) as (values + (x'0000000000000000'), + -- smallest normal values + (x'0010000000000000'), (x'0010000000000001'), + (x'0010000000000002'), (x'0018000000000000'), + -- + (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'), + (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'), + (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'), + (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'), + (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'), + (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'), + (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'), + (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'), + (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'), + (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'), + -- values very close to 1 + (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'), + (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'), + (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'), + (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'), + (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'), + (x'3fefffffffffffff'), + (x'3ff0000000000000'), + (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'), + (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'), + (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'), + -- + (x'3ff921fb54442d18'), + (x'4005bf0a8b14576a'), + (x'400921fb54442d18'), + -- + (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'), + (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'), + (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'), + (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'), + (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'), + (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'), + (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'), + (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'), + (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'), + (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'), + (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'), + (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'), + (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'), + (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'), + (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'), + (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'), + (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'), + (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'), + (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'), + (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'), + (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'), + (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'), + (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'), + (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'), + (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'), + -- + (x'7feffffffffffffe'), (x'7fefffffffffffff'), + -- round to even tests (+ve) + (x'4350000000000002'), + (x'4350000000002e06'), + (x'4352000000000003'), + (x'4352000000000004'), + (x'4358000000000003'), + (x'4358000000000004'), + (x'435f000000000020'), + -- round to even tests (-ve) + (x'c350000000000002'), + (x'c350000000002e06'), + (x'c352000000000003'), + (x'c352000000000004'), + (x'c358000000000003'), + (x'c358000000000004'), + (x'c35f000000000020'), + -- exercise fixed-point memmoves + (x'42dc12218377de66'), + (x'42a674e79c5fe51f'), + (x'4271f71fb04cb74c'), + (x'423cbe991a145879'), + (x'4206fee0e1a9e061'), + (x'41d26580b487e6b4'), + (x'419d6f34540ca453'), + (x'41678c29dcd6e9dc'), + (x'4132d687e3df217d'), + (x'40fe240c9fcb68c8'), + (x'40c81cd6e63c53d3'), + (x'40934a4584fd0fdc'), + (x'405edd3c07fb4c93'), + (x'4028b0fcd32f7076'), + (x'3ff3c0ca428c59f8'), + -- these cases come from the upstream's testsuite + -- LotsOfTrailingZeros) + (x'3e60000000000000'), + -- Regression + (x'c352bd2668e077c4'), + (x'434018601510c000'), + (x'43d055dc36f24000'), + (x'43e052961c6f8000'), + (x'3ff3c0ca2a5b1d5d'), + -- LooksLikePow5 + (x'4830f0cf064dd592'), + (x'4840f0cf064dd592'), + (x'4850f0cf064dd592'), + -- OutputLength + (x'3ff3333333333333'), + (x'3ff3ae147ae147ae'), + (x'3ff3be76c8b43958'), + (x'3ff3c083126e978d'), + (x'3ff3c0c1fc8f3238'), + (x'3ff3c0c9539b8887'), + (x'3ff3c0ca2a5b1d5d'), + (x'3ff3c0ca4283de1b'), + (x'3ff3c0ca43db770a'), + (x'3ff3c0ca428abd53'), + (x'3ff3c0ca428c1d2b'), + (x'3ff3c0ca428c51f2'), + (x'3ff3c0ca428c58fc'), + (x'3ff3c0ca428c59dd'), + (x'3ff3c0ca428c59f8'), + (x'3ff3c0ca428c59fb'), + -- 32-bit chunking + (x'40112e0be8047a7d'), + (x'40112e0be815a889'), + (x'40112e0be826d695'), + (x'40112e0be83804a1'), + (x'40112e0be84932ad'), + -- MinMaxShift + (x'0040000000000000'), + (x'007fffffffffffff'), + (x'0290000000000000'), + (x'029fffffffffffff'), + (x'4350000000000000'), + (x'435fffffffffffff'), + (x'1330000000000000'), + (x'133fffffffffffff'), + (x'3a6fa7161a4d6e0c') +) +select float8send(flt) as ibits, + flt, + flt::text::float8 as r_flt, + float8send(flt::text::float8) as obits, + float8send(flt::text::float8) = float8send(flt) as correct + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s +-- +CTE: "testdata" +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +FUNCTION: name="float8send" function="float8send" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH testdata(bits) AS (...) SELECT ... FROM (SELECT ... FROM testdata OFFSET 0) s" +== 169 +-- truncate_limit: 100 +-- clean up, lest opr_sanity complain +drop type xfloat8 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE xfloat8 CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json b/parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json new file mode 100644 index 0000000..efde331 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json @@ -0,0 +1,534 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/foreign_data.test b/parser/testdata/summary_truncate/postgres_regress/foreign_data.test new file mode 100644 index 0000000..44c2d65 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/foreign_data.test @@ -0,0 +1,3708 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test foreign-data wrapper and server management. +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION test_fdw_handler() + RETURNS fdw_handler + AS :'regresslib', 'test_fdw_handler' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 202 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +-- Clean up in case a prior regression run failed + +-- Suppress NOTICE messages when roles don't exist +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 003 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_foreign_data_user, regress_test_role, regress_test_role2, regress_test_role_super, regress_test_indirect, regress_unprivileged_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_foreign_data_user, regress_test_role, regress_test_role2, regress_tes..." +== 004 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 005 +-- truncate_limit: 100 +CREATE ROLE regress_foreign_data_user LOGIN SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_foreign_data_user WITH LOGIN SUPERUSER" +== 006 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION 'regress_foreign_data_user' +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_foreign_data_user" +== 007 +-- truncate_limit: 100 +CREATE ROLE regress_test_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_role" +== 008 +-- truncate_limit: 100 +CREATE ROLE regress_test_role2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_role2" +== 009 +-- truncate_limit: 100 +CREATE ROLE regress_test_role_super SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_role_super WITH SUPERUSER" +== 010 +-- truncate_limit: 100 +CREATE ROLE regress_test_indirect +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_indirect" +== 011 +-- truncate_limit: 100 +CREATE ROLE regress_unprivileged_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_unprivileged_role" +== 012 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER dummy +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER dummy" +== 013 +-- truncate_limit: 100 +COMMENT ON FOREIGN DATA WRAPPER dummy IS 'useless' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON FOREIGN DATA WRAPPER dummy IS 'useless'" +== 014 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator" +== 015 +-- truncate_limit: 100 +-- At this point we should have 2 built-in wrappers and no servers. +SELECT fdwname, fdwhandler::regproc, fdwvalidator::regproc, fdwoptions FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3 +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3" +== 016 +-- truncate_limit: 100 +SELECT srvname, srvoptions FROM pg_foreign_server +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT srvname, srvoptions FROM pg_foreign_server" +== 017 +-- truncate_limit: 100 +SELECT * FROM pg_user_mapping +-- +TABLE: name="pg_user_mapping" schema="" table="pg_user_mapping" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_user_mapping" +== 018 +-- truncate_limit: 100 +-- CREATE FOREIGN DATA WRAPPER +CREATE FOREIGN DATA WRAPPER foo VALIDATOR bar +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo VALIDATOR bar" +== 019 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo" +== 020 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo" +== 021 +-- truncate_limit: 100 +-- duplicate +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo" +== 022 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1') +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1')" +== 023 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo" +== 024 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', testing '2') +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', testing '2')" +== 025 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', another '2') +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', another '2')" +== 026 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo" +== 027 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 028 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo" +== 029 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 030 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator" +== 031 +-- truncate_limit: 100 +-- HANDLER related checks +CREATE FUNCTION invalid_fdw_handler() RETURNS int LANGUAGE SQL AS 'SELECT 1;' +-- +FUNCTION: name="invalid_fdw_handler" function="invalid_fdw_handler" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION invalid_fdw_handler() RETURNS int LANGUAGE sql AS $$SELECT 1;$$" +== 032 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER invalid_fdw_handler +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER test_fdw HANDLER invalid_fdw_handler" +== 033 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER invalid_fdw_handler +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER invalid_fdw_handler" +== 034 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler" +== 035 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER test_fdw +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER test_fdw" +== 036 +-- truncate_limit: 100 +-- ALTER FOREIGN DATA WRAPPER +ALTER FOREIGN DATA WRAPPER foo OPTIONS (nonexistent 'fdw') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (nonexistent 'fdw')" +== 037 +-- truncate_limit: 100 +-- ERROR + +ALTER FOREIGN DATA WRAPPER foo +-- +ERROR: syntax error at end of input +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo VALIDATOR bar +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo VALIDATOR bar" +== 039 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo NO VALIDATOR +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo NO VALIDATOR" +== 040 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2')" +== 041 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (SET c '4') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (SET c '4')" +== 042 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP c) +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP c)" +== 043 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD x '1', DROP x) +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD x '1', DROP x)" +== 044 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP a, SET b '3', ADD c '4') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP a, SET b '3', ADD c '4')" +== 045 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '2') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '2')" +== 046 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (b '4') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (b '4')" +== 047 +-- truncate_limit: 100 +-- ERROR + +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 048 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5')" +== 049 +-- truncate_limit: 100 +-- ERROR +SET ROLE regress_test_role_super +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role_super" +== 050 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5')" +== 051 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role" +== 052 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role_super +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role_super" +== 053 +-- truncate_limit: 100 +ALTER ROLE regress_test_role_super NOSUPERUSER +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_role_super WITH NOSUPERUSER" +== 054 +-- truncate_limit: 100 +SET ROLE regress_test_role_super +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role_super" +== 055 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD e '6') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD e '6')" +== 056 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 057 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo RENAME TO foo1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo RENAME TO foo1" +== 058 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo1 RENAME TO foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo1 RENAME TO foo" +== 059 +-- truncate_limit: 100 +-- HANDLER related checks +ALTER FOREIGN DATA WRAPPER foo HANDLER invalid_fdw_handler +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo HANDLER invalid_fdw_handler" +== 060 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler HANDLER anything +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler HANDLER anything" +== 061 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler" +== 062 +-- truncate_limit: 100 +DROP FUNCTION invalid_fdw_handler() +-- +FUNCTION: name="invalid_fdw_handler" function="invalid_fdw_handler" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION invalid_fdw_handler()" +== 063 +-- truncate_limit: 100 +-- DROP FOREIGN DATA WRAPPER +DROP FOREIGN DATA WRAPPER nonexistent +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER nonexistent" +== 064 +-- truncate_limit: 100 +-- ERROR +DROP FOREIGN DATA WRAPPER IF EXISTS nonexistent +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER IF EXISTS nonexistent" +== 065 +-- truncate_limit: 100 +DROP ROLE regress_test_role_super +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role_super" +== 066 +-- truncate_limit: 100 +-- ERROR +SET ROLE regress_test_role_super +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role_super" +== 067 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo" +== 068 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 069 +-- truncate_limit: 100 +DROP ROLE regress_test_role_super +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role_super" +== 070 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foo +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo" +== 071 +-- truncate_limit: 100 +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s1 FOREIGN DATA WRAPPER foo" +== 072 +-- truncate_limit: 100 +COMMENT ON SERVER s1 IS 'foreign server' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON SERVER s1 IS 'foreign server'" +== 073 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s1" +== 074 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s1" +== 075 +-- truncate_limit: 100 +-- ERROR +CREATE USER MAPPING IF NOT EXISTS FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING IF NOT EXISTS FOR CURRENT_USER SERVER s1" +== 076 +-- truncate_limit: 100 +-- NOTICE +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo" +== 077 +-- truncate_limit: 100 +-- ERROR +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 078 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER foo CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo CASCADE" +== 079 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 080 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER foo CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo CASCADE" +== 081 +-- truncate_limit: 100 +-- exercise CREATE SERVER +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s1 FOREIGN DATA WRAPPER foo" +== 082 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN DATA WRAPPER foo OPTIONS ("test wrapper" 'true') +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foo OPTIONS (\"test wrapper\" 'true')" +== 083 +-- truncate_limit: 100 +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s1 FOREIGN DATA WRAPPER foo" +== 084 +-- truncate_limit: 100 +CREATE SERVER s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s1 FOREIGN DATA WRAPPER foo" +== 085 +-- truncate_limit: 100 +-- ERROR +CREATE SERVER IF NOT EXISTS s1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER IF NOT EXISTS s1 FOREIGN DATA WRAPPER foo" +== 086 +-- truncate_limit: 100 +-- No ERROR, just NOTICE +CREATE SERVER s2 FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s2 FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b')" +== 087 +-- truncate_limit: 100 +CREATE SERVER s3 TYPE 'oracle' FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s3 TYPE 'oracle' FOREIGN DATA WRAPPER foo" +== 088 +-- truncate_limit: 100 +CREATE SERVER s4 TYPE 'oracle' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s4 TYPE 'oracle' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b')" +== 089 +-- truncate_limit: 100 +CREATE SERVER s5 VERSION '15.0' FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s5 VERSION '15.0' FOREIGN DATA WRAPPER foo" +== 090 +-- truncate_limit: 100 +CREATE SERVER s6 VERSION '16.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s6 VERSION '16.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b')" +== 091 +-- truncate_limit: 100 +CREATE SERVER s7 TYPE 'oracle' VERSION '17.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b') +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s7 TYPE 'oracle' VERSION '17.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname ..." +== 092 +-- truncate_limit: 100 +CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (foo '1') +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (foo '1')" +== 093 +-- truncate_limit: 100 +-- ERROR +CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (host 'localhost', dbname 's8db') +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (host 'localhost', dbname 's8db')" +== 094 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 095 +-- truncate_limit: 100 +CREATE SERVER t1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER t1 FOREIGN DATA WRAPPER foo" +== 096 +-- truncate_limit: 100 +-- ERROR: no usage on FDW +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 097 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_test_role" +== 098 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 099 +-- truncate_limit: 100 +CREATE SERVER t1 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER t1 FOREIGN DATA WRAPPER foo" +== 100 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 101 +-- truncate_limit: 100 +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON FOREIGN DATA WRAPPER foo FROM regress_test_role" +== 102 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_indirect +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_test_indirect" +== 103 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 104 +-- truncate_limit: 100 +CREATE SERVER t2 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER t2 FOREIGN DATA WRAPPER foo" +== 105 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 106 +-- truncate_limit: 100 +GRANT regress_test_indirect TO regress_test_role +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_test_indirect TO regress_test_role" +== 107 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 108 +-- truncate_limit: 100 +CREATE SERVER t2 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER t2 FOREIGN DATA WRAPPER foo" +== 109 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 110 +-- truncate_limit: 100 +REVOKE regress_test_indirect FROM regress_test_role +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE regress_test_indirect FROM regress_test_role" +== 111 +-- truncate_limit: 100 +-- ALTER SERVER +ALTER SERVER s0 +-- +ERROR: syntax error at end of input +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 112 +-- truncate_limit: 100 +-- ERROR +ALTER SERVER s0 OPTIONS (a '1') +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s0 OPTIONS (a '1')" +== 113 +-- truncate_limit: 100 +-- ERROR +ALTER SERVER s1 VERSION '1.0' OPTIONS (servername 's1') +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s1 VERSION '1.0' OPTIONS (servername 's1')" +== 114 +-- truncate_limit: 100 +ALTER SERVER s2 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s2 VERSION '1.1'" +== 115 +-- truncate_limit: 100 +ALTER SERVER s3 OPTIONS ("tns name" 'orcl', port '1521') +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s3 OPTIONS (\"tns name\" 'orcl', port '1521')" +== 116 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN SERVER s1 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s1 TO regress_test_role" +== 117 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN SERVER s6 TO regress_test_role2 WITH GRANT OPTION +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s6 TO regress_test_role2 WITH GRANT OPTION" +== 118 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 119 +-- truncate_limit: 100 +ALTER SERVER s1 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s1 VERSION '1.1'" +== 120 +-- truncate_limit: 100 +-- ERROR +ALTER SERVER s1 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s1 OWNER TO regress_test_role" +== 121 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 122 +-- truncate_limit: 100 +ALTER SERVER s1 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s1 OWNER TO regress_test_role" +== 123 +-- truncate_limit: 100 +GRANT regress_test_role2 TO regress_test_role +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_test_role2 TO regress_test_role" +== 124 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 125 +-- truncate_limit: 100 +ALTER SERVER s1 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s1 VERSION '1.1'" +== 126 +-- truncate_limit: 100 +ALTER SERVER s1 OWNER TO regress_test_role2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s1 OWNER TO regress_test_role2" +== 127 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 128 +-- truncate_limit: 100 +ALTER SERVER s8 OPTIONS (foo '1') +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s8 OPTIONS (foo '1')" +== 129 +-- truncate_limit: 100 +-- ERROR option validation +ALTER SERVER s8 OPTIONS (connect_timeout '30', SET dbname 'db1', DROP host) +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s8 OPTIONS (connect_timeout '30', SET dbname 'db1', DROP host)" +== 130 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 131 +-- truncate_limit: 100 +ALTER SERVER s1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s1 OWNER TO regress_test_indirect" +== 132 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 133 +-- truncate_limit: 100 +GRANT regress_test_indirect TO regress_test_role +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_test_indirect TO regress_test_role" +== 134 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 135 +-- truncate_limit: 100 +ALTER SERVER s1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s1 OWNER TO regress_test_indirect" +== 136 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 137 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_indirect +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_test_indirect" +== 138 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 139 +-- truncate_limit: 100 +ALTER SERVER s1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s1 OWNER TO regress_test_indirect" +== 140 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 141 +-- truncate_limit: 100 +DROP ROLE regress_test_indirect +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_indirect" +== 142 +-- truncate_limit: 100 +-- ERROR + +ALTER SERVER s8 RENAME to s8new +-- +STMT: RenameStmt +TRUNCATED: "ALTER SERVER s8 RENAME TO s8new" +== 143 +-- truncate_limit: 100 +ALTER SERVER s8new RENAME to s8 +-- +STMT: RenameStmt +TRUNCATED: "ALTER SERVER s8new RENAME TO s8" +== 144 +-- truncate_limit: 100 +-- DROP SERVER +DROP SERVER nonexistent +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER nonexistent" +== 145 +-- truncate_limit: 100 +-- ERROR +DROP SERVER IF EXISTS nonexistent +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER IF EXISTS nonexistent" +== 146 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 147 +-- truncate_limit: 100 +DROP SERVER s2 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s2" +== 148 +-- truncate_limit: 100 +-- ERROR +DROP SERVER s1 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s1" +== 149 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 150 +-- truncate_limit: 100 +ALTER SERVER s2 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s2 OWNER TO regress_test_role" +== 151 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 152 +-- truncate_limit: 100 +DROP SERVER s2 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s2" +== 153 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 154 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER s3 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s3" +== 155 +-- truncate_limit: 100 +DROP SERVER s3 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s3" +== 156 +-- truncate_limit: 100 +-- ERROR +DROP SERVER s3 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s3 CASCADE" +== 157 +-- truncate_limit: 100 +-- CREATE USER MAPPING +CREATE USER MAPPING FOR regress_test_missing_role SERVER s1 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR regress_test_missing_role SERVER s1" +== 158 +-- truncate_limit: 100 +-- ERROR +CREATE USER MAPPING FOR current_user SERVER s1 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s1" +== 159 +-- truncate_limit: 100 +-- ERROR +CREATE USER MAPPING FOR current_user SERVER s4 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s4" +== 160 +-- truncate_limit: 100 +CREATE USER MAPPING FOR user SERVER s4 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s4" +== 161 +-- truncate_limit: 100 +-- ERROR duplicate +CREATE USER MAPPING FOR public SERVER s4 OPTIONS ("this mapping" 'is public') +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER s4 OPTIONS (\"this mapping\" 'is public')" +== 162 +-- truncate_limit: 100 +CREATE USER MAPPING FOR user SERVER s8 OPTIONS (username 'test', password 'secret') +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s8 OPTIONS (username 'test', password 'secret')" +== 163 +-- truncate_limit: 100 +-- ERROR +CREATE USER MAPPING FOR user SERVER s8 OPTIONS (user 'test', password 'secret') +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s8 OPTIONS (\"user\" 'test', password 'secret')" +== 164 +-- truncate_limit: 100 +ALTER SERVER s5 OWNER TO regress_test_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s5 OWNER TO regress_test_role" +== 165 +-- truncate_limit: 100 +ALTER SERVER s6 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s6 OWNER TO regress_test_indirect" +== 166 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 167 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER s5 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s5" +== 168 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER s6 OPTIONS (username 'test') +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s6 OPTIONS (username 'test')" +== 169 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER s7 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s7" +== 170 +-- truncate_limit: 100 +-- ERROR +CREATE USER MAPPING FOR public SERVER s8 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER s8" +== 171 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 172 +-- truncate_limit: 100 +ALTER SERVER t1 OWNER TO regress_test_indirect +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER t1 OWNER TO regress_test_indirect" +== 173 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 174 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER t1 OPTIONS (username 'bob', password 'boo') +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER t1 OPTIONS (username 'bob', password 'boo')" +== 175 +-- truncate_limit: 100 +CREATE USER MAPPING FOR public SERVER t1 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER t1" +== 176 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 177 +-- truncate_limit: 100 +-- ALTER USER MAPPING +ALTER USER MAPPING FOR regress_test_missing_role SERVER s4 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR regress_test_missing_role SERVER s4 OPTIONS (gotcha 'true')" +== 178 +-- truncate_limit: 100 +-- ERROR +ALTER USER MAPPING FOR user SERVER ss4 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR CURRENT_USER SERVER ss4 OPTIONS (gotcha 'true')" +== 179 +-- truncate_limit: 100 +-- ERROR +ALTER USER MAPPING FOR public SERVER s5 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR public SERVER s5 OPTIONS (gotcha 'true')" +== 180 +-- truncate_limit: 100 +-- ERROR +ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (username 'test') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR CURRENT_USER SERVER s8 OPTIONS (username 'test')" +== 181 +-- truncate_limit: 100 +-- ERROR +ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (DROP user, SET password 'public') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR CURRENT_USER SERVER s8 OPTIONS (DROP \"user\", SET password 'public')" +== 182 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 183 +-- truncate_limit: 100 +ALTER USER MAPPING FOR current_user SERVER s5 OPTIONS (ADD modified '1') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR CURRENT_USER SERVER s5 OPTIONS (ADD modified '1')" +== 184 +-- truncate_limit: 100 +ALTER USER MAPPING FOR public SERVER s4 OPTIONS (ADD modified '1') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR public SERVER s4 OPTIONS (ADD modified '1')" +== 185 +-- truncate_limit: 100 +-- ERROR +ALTER USER MAPPING FOR public SERVER t1 OPTIONS (ADD modified '1') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR public SERVER t1 OPTIONS (ADD modified '1')" +== 186 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 187 +-- truncate_limit: 100 +-- DROP USER MAPPING +DROP USER MAPPING FOR regress_test_missing_role SERVER s4 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR regress_test_missing_role SERVER s4" +== 188 +-- truncate_limit: 100 +-- ERROR +DROP USER MAPPING FOR user SERVER ss4 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR CURRENT_USER SERVER ss4" +== 189 +-- truncate_limit: 100 +DROP USER MAPPING FOR public SERVER s7 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR public SERVER s7" +== 190 +-- truncate_limit: 100 +-- ERROR +DROP USER MAPPING IF EXISTS FOR regress_test_missing_role SERVER s4 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING IF EXISTS FOR regress_test_missing_role SERVER s4" +== 191 +-- truncate_limit: 100 +DROP USER MAPPING IF EXISTS FOR user SERVER ss4 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER ss4" +== 192 +-- truncate_limit: 100 +DROP USER MAPPING IF EXISTS FOR public SERVER s7 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING IF EXISTS FOR public SERVER s7" +== 193 +-- truncate_limit: 100 +CREATE USER MAPPING FOR public SERVER s8 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER s8" +== 194 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 195 +-- truncate_limit: 100 +DROP USER MAPPING FOR public SERVER s8 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR public SERVER s8" +== 196 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 197 +-- truncate_limit: 100 +DROP SERVER s7 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s7" +== 198 +-- truncate_limit: 100 +-- CREATE FOREIGN TABLE +CREATE SCHEMA foreign_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA foreign_schema" +== 199 +-- truncate_limit: 100 +CREATE SERVER s0 FOREIGN DATA WRAPPER dummy +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s0 FOREIGN DATA WRAPPER dummy" +== 200 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft1 () +-- +ERROR: syntax error at end of input +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 201 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN TABLE ft1 () SERVER no_server +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft1 () SERVER no_server" +== 202 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') PRIMARY KEY, + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft1 (c1 int OPTIONS (\"param 1\" 'val1') PRIMARY KEY, c2 text OPTIONS (param2 ..." +== 203 +-- truncate_limit: 100 +-- ERROR +CREATE TABLE ref_table (id integer PRIMARY KEY) +-- +TABLE: name="ref_table" schema="" table="ref_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref_table (id int PRIMARY KEY)" +== 204 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') REFERENCES ref_table (id), + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft1 (c1 int OPTIONS (\"param 1\" 'val1') REFERENCES ref_table (id), c2 text OP..." +== 205 +-- truncate_limit: 100 +-- ERROR +DROP TABLE ref_table +-- +TABLE: name="ref_table" schema="" table="ref_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ref_table" +== 206 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') NOT NULL, + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date, + UNIQUE (c3) +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft1 (c1 int OPTIONS (\"param 1\" 'val1') NOT NULL, c2 text OPTIONS (param2 'va..." +== 207 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') NOT NULL, + c2 text OPTIONS (param2 'val2', param3 'val3') CHECK (c2 <> ''), + c3 date, + CHECK (c3 BETWEEN '1994-01-01'::date AND '1994-01-31'::date) +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft1 (c1 int OPTIONS (\"param 1\" 'val1') NOT NULL, c2 text OPTIONS (param2 'va..." +== 208 +-- truncate_limit: 100 +COMMENT ON FOREIGN TABLE ft1 IS 'ft1' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON FOREIGN TABLE ft1 IS 'ft1'" +== 209 +-- truncate_limit: 100 +COMMENT ON COLUMN ft1.c1 IS 'ft1.c1' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ft1.c1 IS 'ft1.c1'" +== 210 +-- truncate_limit: 100 +CREATE INDEX id_ft1_c2 ON ft1 (c2) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX id_ft1_c2 ON ft1 USING btree (c2)" +== 211 +-- truncate_limit: 100 +-- ERROR +SELECT * FROM ft1 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ft1" +== 212 +-- truncate_limit: 100 +-- ERROR +EXPLAIN SELECT * FROM ft1 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN SELECT * FROM ft1" +== 213 +-- truncate_limit: 100 +-- ERROR + +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lt1 (a int) PARTITION BY RANGE (a)" +== 214 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part1 PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0" +== 215 +-- truncate_limit: 100 +CREATE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON lt1 USING btree (a)" +== 216 +-- truncate_limit: 100 +-- skips partition +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON lt1 USING btree (a)" +== 217 +-- truncate_limit: 100 +-- ERROR +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1 ADD PRIMARY KEY (a)" +== 218 +-- truncate_limit: 100 +-- ERROR +DROP TABLE lt1 +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lt1" +== 219 +-- truncate_limit: 100 +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lt1 (a int) PARTITION BY RANGE (a)" +== 220 +-- truncate_limit: 100 +CREATE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON lt1 USING btree (a)" +== 221 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part1 PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0" +== 222 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part2 (a INT) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part2 (a int) SERVER s0" +== 223 +-- truncate_limit: 100 +ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000)" +== 224 +-- truncate_limit: 100 +DROP FOREIGN TABLE ft_part1, ft_part2 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft_part1, ft_part2" +== 225 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON lt1 USING btree (a)" +== 226 +-- truncate_limit: 100 +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1 ADD PRIMARY KEY (a)" +== 227 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part1 PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0" +== 228 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN TABLE ft_part2 (a INT NOT NULL) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part2 (a int NOT NULL) SERVER s0" +== 229 +-- truncate_limit: 100 +ALTER TABLE lt1 ATTACH PARTITION ft_part2 + FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000)" +== 230 +-- truncate_limit: 100 +-- ERROR +DROP TABLE lt1 +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lt1" +== 231 +-- truncate_limit: 100 +DROP FOREIGN TABLE ft_part2 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft_part2" +== 232 +-- truncate_limit: 100 +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lt1 (a int) PARTITION BY RANGE (a)" +== 233 +-- truncate_limit: 100 +CREATE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON lt1 USING btree (a)" +== 234 +-- truncate_limit: 100 +CREATE TABLE lt1_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) + PARTITION BY RANGE (a) +-- +TABLE: name="lt1_part1" schema="" table="lt1_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lt1_part1 PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) PARTITION BY RANGE (a)" +== 235 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part_1_1 PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0" +== 236 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part_1_2 (a INT) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part_1_2 (a int) SERVER s0" +== 237 +-- truncate_limit: 100 +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="lt1_part1" schema="" table="lt1_part1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200)" +== 238 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON lt1 USING btree (a)" +== 239 +-- truncate_limit: 100 +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1 ADD PRIMARY KEY (a)" +== 240 +-- truncate_limit: 100 +DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2" +== 241 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON lt1 (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON lt1 USING btree (a)" +== 242 +-- truncate_limit: 100 +ALTER TABLE lt1 ADD PRIMARY KEY (a) +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1 ADD PRIMARY KEY (a)" +== 243 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part_1_1 PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0" +== 244 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft_part_1_2 (a INT NOT NULL) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft_part_1_2 (a int NOT NULL) SERVER s0" +== 245 +-- truncate_limit: 100 +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="lt1_part1" schema="" table="lt1_part1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200)" +== 246 +-- truncate_limit: 100 +DROP TABLE lt1 +-- +TABLE: name="lt1" schema="" table="lt1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lt1" +== 247 +-- truncate_limit: 100 +DROP FOREIGN TABLE ft_part_1_2 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft_part_1_2" +== 248 +-- truncate_limit: 100 +-- ALTER FOREIGN TABLE +COMMENT ON FOREIGN TABLE ft1 IS 'foreign table' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON FOREIGN TABLE ft1 IS 'foreign table'" +== 249 +-- truncate_limit: 100 +COMMENT ON FOREIGN TABLE ft1 IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON FOREIGN TABLE ft1 IS NULL" +== 250 +-- truncate_limit: 100 +COMMENT ON COLUMN ft1.c1 IS 'foreign column' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ft1.c1 IS 'foreign column'" +== 251 +-- truncate_limit: 100 +COMMENT ON COLUMN ft1.c1 IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON COLUMN ft1.c1 IS NULL" +== 252 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c4 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c4 int" +== 253 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c5 integer DEFAULT 0 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c5 int DEFAULT 0" +== 254 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c6 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c6 int" +== 255 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c7 integer NOT NULL +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c7 int NOT NULL" +== 256 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c8 int" +== 257 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c9 integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c9 int" +== 258 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c10 int OPTIONS (p1 'v1')" +== 259 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0" +== 260 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT" +== 261 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c6 SET NOT NULL +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c6 SET NOT NULL" +== 262 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 DROP NOT NULL +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 DROP NOT NULL" +== 263 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) USING '0' +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) USING '0'" +== 264 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10)" +== 265 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET DATA TYPE text +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE text" +== 266 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN xmin OPTIONS (ADD p1 'v1') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN xmin OPTIONS (ADD p1 'v1')" +== 267 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2'), + ALTER COLUMN c8 OPTIONS (ADD p1 'v1', ADD p2 'v2') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2') , ALTER COLUMN c8 OPTI..." +== 268 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1)" +== 269 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET STATISTICS 10000 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET STATISTICS 10000" +== 270 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET (n_distinct = 100) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET (n_distinct=100)" +== 271 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STATISTICS -1 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STATISTICS -1" +== 272 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STORAGE PLAIN +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STORAGE plain" +== 273 +-- truncate_limit: 100 +-- can't change the column type if it's used elsewhere +CREATE TABLE use_ft1_column_type (x ft1) +-- +TABLE: name="use_ft1_column_type" schema="" table="use_ft1_column_type" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE use_ft1_column_type (x ft1)" +== 274 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET DATA TYPE integer +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int" +== 275 +-- truncate_limit: 100 +-- ERROR +DROP TABLE use_ft1_column_type +-- +TABLE: name="use_ft1_column_type" schema="" table="use_ft1_column_type" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE use_ft1_column_type" +== 276 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD PRIMARY KEY (c7) +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD PRIMARY KEY (c7)" +== 277 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c9_check CHECK (c9 < 0) NOT VALID +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c9_check CHECK (c9 < 0) NOT VALID" +== 278 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ALTER CONSTRAINT ft1_c9_check DEFERRABLE +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ALTER CONSTRAINT ft1_c9_check DEFERRABLE" +== 279 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c9_check +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c9_check" +== 280 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const" +== 281 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const" +== 282 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role" +== 283 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@') +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@')" +== 284 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 DROP COLUMN no_column +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 DROP no_column" +== 285 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE ft1 DROP COLUMN IF EXISTS no_column +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 DROP IF EXISTS no_column" +== 286 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 DROP COLUMN c9 +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 DROP c9" +== 287 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 ADD COLUMN c11 serial +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 ADD COLUMN c11 serial" +== 288 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 SET SCHEMA foreign_schema +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 SET SCHEMA foreign_schema" +== 289 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft1 SET TABLESPACE ts +-- +TABLE: name="ft1" schema="" table="ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft1 SET TABLESPACE ts" +== 290 +-- truncate_limit: 100 +-- ERROR +ALTER SEQUENCE foreign_schema.ft1_c11_seq SET SCHEMA public +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER SEQUENCE foreign_schema.ft1_c11_seq SET SCHEMA public" +== 291 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE foreign_schema.ft1 RENAME c1 TO foreign_column_1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN TABLE foreign_schema.ft1 RENAME COLUMN c1 TO foreign_column_1" +== 292 +-- truncate_limit: 100 +ALTER FOREIGN TABLE foreign_schema.ft1 RENAME TO foreign_table_1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN TABLE foreign_schema.ft1 RENAME TO foreign_table_1" +== 293 +-- truncate_limit: 100 +-- alter noexisting table +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c4 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c4 int" +== 294 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c6 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c6 int" +== 295 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c7 integer NOT NULL +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c7 int NOT NULL" +== 296 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c8 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c8 int" +== 297 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c9 integer +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c9 int" +== 298 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1') +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c10 int OPTIONS (p1 'v1')" +== 299 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c6 SET NOT NULL +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c6 SET NOT NULL" +== 300 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 DROP NOT NULL +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 DROP NOT NULL" +== 301 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 TYPE char(10)" +== 302 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 SET DATA TYPE text +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 TYPE text" +== 303 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2'), + ALTER COLUMN c8 OPTIONS (ADD p1 'v1', ADD p2 'v2') +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2')..." +== 304 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1) +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1)" +== 305 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT IF EXISTS no_const +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT IF EXISTS no_const" +== 306 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT ft1_c1_check +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT ft1_c1_check" +== 307 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OWNER TO regress_test_role +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OWNER TO regress_test_role" +== 308 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@') +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape..." +== 309 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP COLUMN IF EXISTS no_column +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP IF EXISTS no_column" +== 310 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP COLUMN c9 +-- +TABLE: name="doesnt_exist_ft1" schema="" table="doesnt_exist_ft1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP c9" +== 311 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 SET SCHEMA foreign_schema +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 SET SCHEMA foreign_schema" +== 312 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME c1 TO foreign_column_1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME COLUMN c1 TO foreign_column_1" +== 313 +-- truncate_limit: 100 +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME TO foreign_table_1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME TO foreign_table_1" +== 314 +-- truncate_limit: 100 +-- Information schema + +SELECT * FROM information_schema.foreign_data_wrappers ORDER BY 1, 2 +-- +TABLE: name="information_schema.foreign_data_wrappers" schema="information_schema" table="foreign_data_wrappers" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.foreign_data_wrappers ORDER BY 1, 2" +== 315 +-- truncate_limit: 100 +SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_data_wrapper_options" schema="information_schema" table="foreign_data_wrapper_options" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3" +== 316 +-- truncate_limit: 100 +SELECT * FROM information_schema.foreign_servers ORDER BY 1, 2 +-- +TABLE: name="information_schema.foreign_servers" schema="information_schema" table="foreign_servers" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.foreign_servers ORDER BY 1, 2" +== 317 +-- truncate_limit: 100 +SELECT * FROM information_schema.foreign_server_options ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_server_options" schema="information_schema" table="foreign_server_options" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.foreign_server_options ORDER BY 1, 2, 3" +== 318 +-- truncate_limit: 100 +SELECT * FROM information_schema.user_mappings ORDER BY lower(authorization_identifier), 2, 3 +-- +TABLE: name="information_schema.user_mappings" schema="information_schema" table="user_mappings" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.user_mappings ORDER BY lower(authorization_identifier), 2, 3" +== 319 +-- truncate_limit: 100 +SELECT * FROM information_schema.user_mapping_options ORDER BY lower(authorization_identifier), 2, 3, 4 +-- +TABLE: name="information_schema.user_mapping_options" schema="information_schema" table="user_mapping_options" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.user_mapping_options ORDER BY lower(authorization_identifier), 2..." +== 320 +-- truncate_limit: 100 +SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.usage_privileges" schema="information_schema" table="usage_privileges" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.usage_privileges WHERE ... ORDER BY 1, 2, 3, 4, 5" +== 321 +-- truncate_limit: 100 +SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.role_usage_grants" schema="information_schema" table="role_usage_grants" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.role_usage_grants WHERE ... ORDER BY 1, 2, 3, 4, 5" +== 322 +-- truncate_limit: 100 +SELECT * FROM information_schema.foreign_tables ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_tables" schema="information_schema" table="foreign_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.foreign_tables ORDER BY 1, 2, 3" +== 323 +-- truncate_limit: 100 +SELECT * FROM information_schema.foreign_table_options ORDER BY 1, 2, 3, 4 +-- +TABLE: name="information_schema.foreign_table_options" schema="information_schema" table="foreign_table_options" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.foreign_table_options ORDER BY 1, 2, 3, 4" +== 324 +-- truncate_limit: 100 +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 325 +-- truncate_limit: 100 +SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4 +-- +TABLE: name="information_schema.user_mapping_options" schema="information_schema" table="user_mapping_options" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4" +== 326 +-- truncate_limit: 100 +SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.usage_privileges" schema="information_schema" table="usage_privileges" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.usage_privileges WHERE ... ORDER BY 1, 2, 3, 4, 5" +== 327 +-- truncate_limit: 100 +SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5 +-- +TABLE: name="information_schema.role_usage_grants" schema="information_schema" table="role_usage_grants" ctx=Select +FILTER: schema="" table="" column="object_type" +FILTER: schema="" table="" column="object_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.role_usage_grants WHERE ... ORDER BY 1, 2, 3, 4, 5" +== 328 +-- truncate_limit: 100 +DROP USER MAPPING FOR current_user SERVER t1 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR CURRENT_USER SERVER t1" +== 329 +-- truncate_limit: 100 +SET ROLE regress_test_role2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role2" +== 330 +-- truncate_limit: 100 +SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4 +-- +TABLE: name="information_schema.user_mapping_options" schema="information_schema" table="user_mapping_options" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4" +== 331 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 332 +-- truncate_limit: 100 +-- has_foreign_data_wrapper_privilege +SELECT has_foreign_data_wrapper_privilege('regress_test_role', + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE') +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 333 +-- truncate_limit: 100 +SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE') +-- +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE')" +== 334 +-- truncate_limit: 100 +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 335 +-- truncate_limit: 100 +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE') +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="fdwname" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 336 +-- truncate_limit: 100 +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), 'foo', 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT has_foreign_data_wrapper_privilege((SELECT oid FROM pg_roles WHERE ...), 'foo', 'USAGE')" +== 337 +-- truncate_limit: 100 +SELECT has_foreign_data_wrapper_privilege('foo', 'USAGE') +-- +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_foreign_data_wrapper_privilege('foo', 'USAGE')" +== 338 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_test_role" +== 339 +-- truncate_limit: 100 +SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE') +-- +FUNCTION: name="has_foreign_data_wrapper_privilege" function="has_foreign_data_wrapper_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE')" +== 340 +-- truncate_limit: 100 +-- has_server_privilege +SELECT has_server_privilege('regress_test_role', + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE') +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 341 +-- truncate_limit: 100 +SELECT has_server_privilege('regress_test_role', 's8', 'USAGE') +-- +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_server_privilege('regress_test_role', 's8', 'USAGE')" +== 342 +-- truncate_limit: 100 +SELECT has_server_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 343 +-- truncate_limit: 100 +SELECT has_server_privilege( + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE') +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="srvname" +STMT: SelectStmt +TRUNCATED: "SELECT has_server_privilege((SELECT oid FROM pg_foreign_server WHERE srvname = 's8'), 'USAGE')" +== 344 +-- truncate_limit: 100 +SELECT has_server_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), 's8', 'USAGE') +-- +TABLE: name="pg_roles" schema="" table="pg_roles" ctx=Select +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT has_server_privilege((SELECT oid FROM pg_roles WHERE ...), 's8', 'USAGE')" +== 345 +-- truncate_limit: 100 +SELECT has_server_privilege('s8', 'USAGE') +-- +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_server_privilege('s8', 'USAGE')" +== 346 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN SERVER s8 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s8 TO regress_test_role" +== 347 +-- truncate_limit: 100 +SELECT has_server_privilege('regress_test_role', 's8', 'USAGE') +-- +FUNCTION: name="has_server_privilege" function="has_server_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_server_privilege('regress_test_role', 's8', 'USAGE')" +== 348 +-- truncate_limit: 100 +REVOKE USAGE ON FOREIGN SERVER s8 FROM regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON FOREIGN SERVER s8 FROM regress_test_role" +== 349 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s4 TO regress_test_role" +== 350 +-- truncate_limit: 100 +DROP USER MAPPING FOR public SERVER s4 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR public SERVER s4" +== 351 +-- truncate_limit: 100 +ALTER SERVER s6 OPTIONS (DROP host, DROP dbname) +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s6 OPTIONS (DROP host, DROP dbname)" +== 352 +-- truncate_limit: 100 +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username) +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username)" +== 353 +-- truncate_limit: 100 +ALTER FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator" +== 354 +-- truncate_limit: 100 +-- Privileges +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_unprivileged_role" +== 355 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foobar +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foobar" +== 356 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true')" +== 357 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_unprivileged_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_unprivileged_role" +== 358 +-- truncate_limit: 100 +-- ERROR +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo" +== 359 +-- truncate_limit: 100 +-- ERROR +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_test_role" +== 360 +-- truncate_limit: 100 +-- ERROR +CREATE SERVER s9 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s9 FOREIGN DATA WRAPPER foo" +== 361 +-- truncate_limit: 100 +-- ERROR +ALTER SERVER s4 VERSION '0.5' +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s4 VERSION '0.5'" +== 362 +-- truncate_limit: 100 +-- ERROR +ALTER SERVER s4 OWNER TO regress_unprivileged_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SERVER s4 OWNER TO regress_unprivileged_role" +== 363 +-- truncate_limit: 100 +-- ERROR +DROP SERVER s4 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s4" +== 364 +-- truncate_limit: 100 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s4 TO regress_test_role" +== 365 +-- truncate_limit: 100 +-- ERROR +CREATE USER MAPPING FOR public SERVER s4 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER s4" +== 366 +-- truncate_limit: 100 +-- ERROR +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true')" +== 367 +-- truncate_limit: 100 +-- ERROR +DROP USER MAPPING FOR regress_test_role SERVER s6 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR regress_test_role SERVER s6" +== 368 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 369 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_unprivileged_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER postgresql TO regress_unprivileged_role" +== 370 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_unprivileged_role WITH GRANT OPTION +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_unprivileged_role WITH GRANT OPTION" +== 371 +-- truncate_limit: 100 +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_unprivileged_role" +== 372 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER foobar +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER foobar" +== 373 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true') +-- +STMT: AlterFdwStmt +TRUNCATED: "ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true')" +== 374 +-- truncate_limit: 100 +-- ERROR +DROP FOREIGN DATA WRAPPER foo +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo" +== 375 +-- truncate_limit: 100 +-- ERROR +GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER postgresql TO regress_test_role" +== 376 +-- truncate_limit: 100 +-- WARNING +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_test_role" +== 377 +-- truncate_limit: 100 +CREATE SERVER s9 FOREIGN DATA WRAPPER postgresql +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s9 FOREIGN DATA WRAPPER postgresql" +== 378 +-- truncate_limit: 100 +ALTER SERVER s6 VERSION '0.5' +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s6 VERSION '0.5'" +== 379 +-- truncate_limit: 100 +-- ERROR +DROP SERVER s6 +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s6" +== 380 +-- truncate_limit: 100 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s6 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s6 TO regress_test_role" +== 381 +-- truncate_limit: 100 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s9 TO regress_test_role" +== 382 +-- truncate_limit: 100 +CREATE USER MAPPING FOR public SERVER s6 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER s6" +== 383 +-- truncate_limit: 100 +-- ERROR +CREATE USER MAPPING FOR public SERVER s9 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER s9" +== 384 +-- truncate_limit: 100 +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true') +-- +STMT: AlterUserMappingStmt +TRUNCATED: "ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true')" +== 385 +-- truncate_limit: 100 +-- ERROR +DROP USER MAPPING FOR regress_test_role SERVER s6 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR regress_test_role SERVER s6" +== 386 +-- truncate_limit: 100 +-- ERROR +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 387 +-- truncate_limit: 100 +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role" +== 388 +-- truncate_limit: 100 +-- ERROR +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role CASCADE +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role CASCADE" +== 389 +-- truncate_limit: 100 +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_unprivileged_role" +== 390 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN DATA WRAPPER foo TO regress_test_role" +== 391 +-- truncate_limit: 100 +-- ERROR +CREATE SERVER s10 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s10 FOREIGN DATA WRAPPER foo" +== 392 +-- truncate_limit: 100 +-- ERROR +ALTER SERVER s9 VERSION '1.1' +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s9 VERSION '1.1'" +== 393 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s9 TO regress_test_role" +== 394 +-- truncate_limit: 100 +CREATE USER MAPPING FOR current_user SERVER s9 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s9" +== 395 +-- truncate_limit: 100 +DROP SERVER s9 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s9 CASCADE" +== 396 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 397 +-- truncate_limit: 100 +CREATE SERVER s9 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s9 FOREIGN DATA WRAPPER foo" +== 398 +-- truncate_limit: 100 +GRANT USAGE ON FOREIGN SERVER s9 TO regress_unprivileged_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s9 TO regress_unprivileged_role" +== 399 +-- truncate_limit: 100 +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_unprivileged_role" +== 400 +-- truncate_limit: 100 +ALTER SERVER s9 VERSION '1.2' +-- +STMT: AlterForeignServerStmt +TRUNCATED: "ALTER SERVER s9 VERSION '1.2'" +== 401 +-- truncate_limit: 100 +-- ERROR +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON FOREIGN SERVER s9 TO regress_test_role" +== 402 +-- truncate_limit: 100 +-- WARNING +CREATE USER MAPPING FOR current_user SERVER s9 +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR CURRENT_USER SERVER s9" +== 403 +-- truncate_limit: 100 +DROP SERVER s9 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s9 CASCADE" +== 404 +-- truncate_limit: 100 +-- ERROR + +-- Check visibility of user mapping data +SET ROLE regress_test_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_test_role" +== 405 +-- truncate_limit: 100 +CREATE SERVER s10 FOREIGN DATA WRAPPER foo +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER s10 FOREIGN DATA WRAPPER foo" +== 406 +-- truncate_limit: 100 +CREATE USER MAPPING FOR public SERVER s10 OPTIONS (user 'secret') +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR public SERVER s10 OPTIONS (\"user\" 'secret')" +== 407 +-- truncate_limit: 100 +CREATE USER MAPPING FOR regress_unprivileged_role SERVER s10 OPTIONS (user 'secret') +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR regress_unprivileged_role SERVER s10 OPTIONS (\"user\" 'secret')" +== 408 +-- truncate_limit: 100 +-- owner of server can see some option fields +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 409 +-- truncate_limit: 100 +-- superuser can see all option fields +-- unprivileged user cannot see any option field +SET ROLE regress_unprivileged_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_unprivileged_role" +== 410 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 411 +-- truncate_limit: 100 +DROP SERVER s10 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s10 CASCADE" +== 412 +-- truncate_limit: 100 +-- Triggers +CREATE FUNCTION dummy_trigger() RETURNS TRIGGER AS $$ + BEGIN + RETURN NULL; + END +$$ language plpgsql +-- +FUNCTION: name="dummy_trigger" function="dummy_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dummy_trigger() RETURNS trigger AS $$\n BEGIN\n RETURN NULL;\n END\n$$ LANGUAGE ..." +== 413 +-- truncate_limit: 100 +CREATE TRIGGER trigtest_before_stmt BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_before_stmt BEFORE INSERT OR DELETE OR UPDATE ON foreign_schema.foreign_t..." +== 414 +-- truncate_limit: 100 +CREATE TRIGGER trigtest_after_stmt AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_after_stmt AFTER INSERT OR DELETE OR UPDATE ON foreign_schema.foreign_tab..." +== 415 +-- truncate_limit: 100 +CREATE TRIGGER trigtest_after_stmt_tt AFTER INSERT OR UPDATE OR DELETE -- ERROR +ON foreign_schema.foreign_table_1 +REFERENCING NEW TABLE AS new_table +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_after_stmt_tt AFTER INSERT OR DELETE OR UPDATE ON foreign_schema.foreign_..." +== 416 +-- truncate_limit: 100 +CREATE TRIGGER trigtest_before_row BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_before_row BEFORE INSERT OR DELETE OR UPDATE ON foreign_schema.foreign_ta..." +== 417 +-- truncate_limit: 100 +CREATE TRIGGER trigtest_after_row AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_after_row AFTER INSERT OR DELETE OR UPDATE ON foreign_schema.foreign_tabl..." +== 418 +-- truncate_limit: 100 +CREATE CONSTRAINT TRIGGER trigtest_constraint AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger() +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER trigtest_constraint AFTER INSERT OR DELETE OR UPDATE ON foreign_schema...." +== 419 +-- truncate_limit: 100 +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + DISABLE TRIGGER trigtest_before_stmt +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE foreign_schema.foreign_table_1 DISABLE TRIGGER trigtest_before_stmt" +== 420 +-- truncate_limit: 100 +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + ENABLE TRIGGER trigtest_before_stmt +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE foreign_schema.foreign_table_1 ENABLE TRIGGER trigtest_before_stmt" +== 421 +-- truncate_limit: 100 +DROP TRIGGER trigtest_before_stmt ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trigtest_before_stmt ON foreign_schema.foreign_table_1" +== 422 +-- truncate_limit: 100 +DROP TRIGGER trigtest_before_row ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trigtest_before_row ON foreign_schema.foreign_table_1" +== 423 +-- truncate_limit: 100 +DROP TRIGGER trigtest_after_stmt ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trigtest_after_stmt ON foreign_schema.foreign_table_1" +== 424 +-- truncate_limit: 100 +DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1 +-- +TABLE: name="foreign_schema.foreign_table_1" schema="foreign_schema" table="foreign_table_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1" +== 425 +-- truncate_limit: 100 +DROP FUNCTION dummy_trigger() +-- +FUNCTION: name="dummy_trigger" function="dummy_trigger" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dummy_trigger()" +== 426 +-- truncate_limit: 100 +-- Table inheritance +CREATE TABLE fd_pt1 ( + c1 integer NOT NULL, + c2 text, + c3 date +) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fd_pt1 (c1 int NOT NULL, c2 text, c3 date)" +== 427 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft2 () INHERITS (fd_pt1) + SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft2 () INHERITS (fd_pt1) SERVER s0 OPTIONS (delimiter ',', quote '\"', \"be qu..." +== 428 +-- truncate_limit: 100 +DROP FOREIGN TABLE ft2 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft2" +== 429 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft2 (c1 int NOT NULL, c2 text, c3 date) SERVER s0 OPTIONS (delimiter ',', qu..." +== 430 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1 +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft2 INHERIT fd_pt1" +== 431 +-- truncate_limit: 100 +CREATE TABLE ct3() INHERITS(ft2) +-- +TABLE: name="ct3" schema="" table="ct3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ct3 () INHERITS (ft2)" +== 432 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft3 ( + c1 integer NOT NULL, + c2 text, + c3 date +) INHERITS(ft2) + SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft3 (c1 int NOT NULL, c2 text, c3 date) INHERITS (ft2) SERVER s0" +== 433 +-- truncate_limit: 100 +-- add attributes recursively +ALTER TABLE fd_pt1 ADD COLUMN c4 integer +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD COLUMN c4 int" +== 434 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ADD COLUMN c5 integer DEFAULT 0 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD COLUMN c5 int DEFAULT 0" +== 435 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ADD COLUMN c6 integer +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD COLUMN c6 int" +== 436 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ADD COLUMN c7 integer NOT NULL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD COLUMN c7 int NOT NULL" +== 437 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ADD COLUMN c8 integer +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD COLUMN c8 int" +== 438 +-- truncate_limit: 100 +-- alter attributes recursively +ALTER TABLE fd_pt1 ALTER COLUMN c4 SET DEFAULT 0 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c4 SET DEFAULT 0" +== 439 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c5 DROP DEFAULT +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c5 DROP DEFAULT" +== 440 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c6 SET NOT NULL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c6 SET NOT NULL" +== 441 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c7 DROP NOT NULL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c7 DROP NOT NULL" +== 442 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) USING '0' +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) USING '0'" +== 443 +-- truncate_limit: 100 +-- ERROR +ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10)" +== 444 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET DATA TYPE text +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE text" +== 445 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c1 SET STATISTICS 10000 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c1 SET STATISTICS 10000" +== 446 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c1 SET (n_distinct = 100) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c1 SET (n_distinct=100)" +== 447 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STATISTICS -1 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STATISTICS -1" +== 448 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STORAGE EXTERNAL +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STORAGE external" +== 449 +-- truncate_limit: 100 +-- drop attributes recursively +ALTER TABLE fd_pt1 DROP COLUMN c4 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 DROP c4" +== 450 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 DROP COLUMN c5 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 DROP c5" +== 451 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 DROP COLUMN c6 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 DROP c6" +== 452 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 DROP COLUMN c7 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 DROP c7" +== 453 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 DROP COLUMN c8 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 DROP c8" +== 454 +-- truncate_limit: 100 +-- add constraints recursively +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk1 CHECK (c1 > 0) NO INHERIT +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk1 CHECK (c1 > 0) NO INHERIT" +== 455 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '') +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '')" +== 456 +-- truncate_limit: 100 +-- connoinherit should be true for NO INHERIT constraint +SELECT relname, conname, contype, conislocal, coninhcount, connoinherit + FROM pg_class AS pc JOIN pg_constraint AS pgc ON (conrelid = pc.oid) + WHERE pc.relname = 'fd_pt1' + ORDER BY 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 457 +-- truncate_limit: 100 +-- child does not inherit NO INHERIT constraints +DROP FOREIGN TABLE ft2 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft2" +== 458 +-- truncate_limit: 100 +-- ERROR +DROP FOREIGN TABLE ft2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE ft2 CASCADE" +== 459 +-- truncate_limit: 100 +CREATE FOREIGN TABLE ft2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE ft2 (c1 int NOT NULL, c2 text, c3 date) SERVER s0 OPTIONS (delimiter ',', qu..." +== 460 +-- truncate_limit: 100 +-- child must have parent's INHERIT constraints +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1 +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft2 INHERIT fd_pt1" +== 461 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE ft2 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '') +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft2 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '')" +== 462 +-- truncate_limit: 100 +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1 +-- +TABLE: name="ft2" schema="" table="ft2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE ft2 INHERIT fd_pt1" +== 463 +-- truncate_limit: 100 +-- child does not inherit NO INHERIT constraints + +-- drop constraints recursively +ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk1 CASCADE +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk1 CASCADE" +== 464 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk2 CASCADE +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk2 CASCADE" +== 465 +-- truncate_limit: 100 +-- NOT VALID case +INSERT INTO fd_pt1 VALUES (1, 'fd_pt1'::text, '1994-01-01'::date) +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fd_pt1 VALUES (1, 'fd_pt1'::text, '1994-01-01'::date)" +== 466 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk3 CHECK (c2 <> '') NOT VALID +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk3 CHECK (c2 <> '') NOT VALID" +== 467 +-- truncate_limit: 100 +-- VALIDATE CONSTRAINT need do nothing on foreign tables +ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3 +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3" +== 468 +-- truncate_limit: 100 +-- changes name of an attribute recursively +ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1" +== 469 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2" +== 470 +-- truncate_limit: 100 +ALTER TABLE fd_pt1 RENAME COLUMN c3 TO f3 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE fd_pt1 RENAME COLUMN c3 TO f3" +== 471 +-- truncate_limit: 100 +-- changes name of a constraint recursively +ALTER TABLE fd_pt1 RENAME CONSTRAINT fd_pt1chk3 TO f2_check +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE fd_pt1 RENAME CONSTRAINT fd_pt1chk3 TO f2_check" +== 472 +-- truncate_limit: 100 +DROP TABLE fd_pt1 CASCADE +-- +TABLE: name="fd_pt1" schema="" table="fd_pt1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fd_pt1 CASCADE" +== 473 +-- truncate_limit: 100 +-- IMPORT FOREIGN SCHEMA +IMPORT FOREIGN SCHEMA s1 FROM SERVER s9 INTO public +-- +STMT: ImportForeignSchemaStmt +TRUNCATED: "IMPORT FOREIGN SCHEMA s1 FROM SERVER s9 INTO public" +== 474 +-- truncate_limit: 100 +-- ERROR +IMPORT FOREIGN SCHEMA s1 LIMIT TO (t1) FROM SERVER s9 INTO public +-- +STMT: ImportForeignSchemaStmt +TRUNCATED: "IMPORT FOREIGN SCHEMA s1 LIMIT TO (t1) FROM SERVER s9 INTO public" +== 475 +-- truncate_limit: 100 +--ERROR +IMPORT FOREIGN SCHEMA s1 EXCEPT (t1) FROM SERVER s9 INTO public +-- +STMT: ImportForeignSchemaStmt +TRUNCATED: "IMPORT FOREIGN SCHEMA s1 EXCEPT (t1) FROM SERVER s9 INTO public" +== 476 +-- truncate_limit: 100 +-- ERROR +IMPORT FOREIGN SCHEMA s1 EXCEPT (t1, t2) FROM SERVER s9 INTO public +OPTIONS (option1 'value1', option2 'value2') +-- +STMT: ImportForeignSchemaStmt +TRUNCATED: "IMPORT FOREIGN SCHEMA s1 EXCEPT (t1, t2) FROM SERVER s9 INTO public OPTIONS (option1 'value1', op..." +== 477 +-- truncate_limit: 100 +-- ERROR + +-- DROP FOREIGN TABLE +DROP FOREIGN TABLE no_table +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE no_table" +== 478 +-- truncate_limit: 100 +-- ERROR +DROP FOREIGN TABLE IF EXISTS no_table +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE IF EXISTS no_table" +== 479 +-- truncate_limit: 100 +DROP FOREIGN TABLE foreign_schema.foreign_table_1 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE foreign_schema.foreign_table_1" +== 480 +-- truncate_limit: 100 +-- REASSIGN OWNED/DROP OWNED of foreign objects +REASSIGN OWNED BY regress_test_role TO regress_test_role2 +-- +STMT: ReassignOwnedStmt +TRUNCATED: "REASSIGN OWNED BY regress_test_role TO regress_test_role2" +== 481 +-- truncate_limit: 100 +DROP OWNED BY regress_test_role2 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_test_role2" +== 482 +-- truncate_limit: 100 +DROP OWNED BY regress_test_role2 CASCADE +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_test_role2 CASCADE" +== 483 +-- truncate_limit: 100 +-- Foreign partition DDL stuff +CREATE TABLE fd_pt2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) PARTITION BY LIST (c1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fd_pt2 (c1 int NOT NULL, c2 text, c3 date) PARTITION BY LIST (c1)" +== 484 +-- truncate_limit: 100 +CREATE FOREIGN TABLE fd_pt2_1 PARTITION OF fd_pt2 FOR VALUES IN (1) + SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE fd_pt2_1 PARTITION OF fd_pt2 FOR VALUES IN (1) SERVER s0 OPTIONS (delimiter ..." +== 485 +-- truncate_limit: 100 +-- partition cannot have additional columns +DROP FOREIGN TABLE fd_pt2_1 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE fd_pt2_1" +== 486 +-- truncate_limit: 100 +CREATE FOREIGN TABLE fd_pt2_1 ( + c1 integer NOT NULL, + c2 text, + c3 date, + c4 char +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE fd_pt2_1 (c1 int NOT NULL, c2 text, c3 date, c4 char(1)) SERVER s0 OPTIONS (..." +== 487 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1)" +== 488 +-- truncate_limit: 100 +-- ERROR + +DROP FOREIGN TABLE fd_pt2_1 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE fd_pt2_1" +== 489 +-- truncate_limit: 100 +CREATE FOREIGN TABLE fd_pt2_1 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value') +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE fd_pt2_1 (c1 int NOT NULL, c2 text, c3 date) SERVER s0 OPTIONS (delimiter ',..." +== 490 +-- truncate_limit: 100 +-- no attach partition validation occurs for foreign tables +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1)" +== 491 +-- truncate_limit: 100 +-- cannot add column to a partition +ALTER TABLE fd_pt2_1 ADD c4 char +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2_1 ADD COLUMN c4 char(1)" +== 492 +-- truncate_limit: 100 +-- ok to have a partition's own constraints though +ALTER TABLE fd_pt2_1 ALTER c3 SET NOT NULL +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2_1 ALTER COLUMN c3 SET NOT NULL" +== 493 +-- truncate_limit: 100 +ALTER TABLE fd_pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> '') +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> '')" +== 494 +-- truncate_limit: 100 +-- cannot drop inherited NOT NULL constraint from a partition +ALTER TABLE fd_pt2_1 ALTER c1 DROP NOT NULL +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2_1 ALTER COLUMN c1 DROP NOT NULL" +== 495 +-- truncate_limit: 100 +-- partition must have parent's constraints +ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1 +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1" +== 496 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 ALTER c2 SET NOT NULL +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ALTER COLUMN c2 SET NOT NULL" +== 497 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1)" +== 498 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE fd_pt2_1 ALTER c2 SET NOT NULL +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE fd_pt2_1 ALTER COLUMN c2 SET NOT NULL" +== 499 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1)" +== 500 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1 +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1" +== 501 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0)" +== 502 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1)" +== 503 +-- truncate_limit: 100 +-- ERROR +ALTER FOREIGN TABLE fd_pt2_1 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0) +-- +TABLE: name="fd_pt2_1" schema="" table="fd_pt2_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER FOREIGN TABLE fd_pt2_1 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0)" +== 504 +-- truncate_limit: 100 +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1) +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1)" +== 505 +-- truncate_limit: 100 +DROP FOREIGN TABLE fd_pt2_1 +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE fd_pt2_1" +== 506 +-- truncate_limit: 100 +DROP TABLE fd_pt2 +-- +TABLE: name="fd_pt2" schema="" table="fd_pt2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fd_pt2" +== 507 +-- truncate_limit: 100 +-- foreign table cannot be part of partition tree made of temporary +-- relations. +CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted (a int) PARTITION BY LIST (a)" +== 508 +-- truncate_limit: 100 +CREATE FOREIGN TABLE foreign_part PARTITION OF temp_parted DEFAULT + SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE foreign_part PARTITION OF temp_parted DEFAULT SERVER s0" +== 509 +-- truncate_limit: 100 +-- ERROR +CREATE FOREIGN TABLE foreign_part (a int) SERVER s0 +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE foreign_part (a int) SERVER s0" +== 510 +-- truncate_limit: 100 +ALTER TABLE temp_parted ATTACH PARTITION foreign_part DEFAULT +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE temp_parted ATTACH PARTITION foreign_part DEFAULT" +== 511 +-- truncate_limit: 100 +-- ERROR +DROP FOREIGN TABLE foreign_part +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN TABLE foreign_part" +== 512 +-- truncate_limit: 100 +DROP TABLE temp_parted +-- +TABLE: name="temp_parted" schema="" table="temp_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_parted" +== 513 +-- truncate_limit: 100 +-- Cleanup +DROP SCHEMA foreign_schema CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA foreign_schema CASCADE" +== 514 +-- truncate_limit: 100 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role" +== 515 +-- truncate_limit: 100 +-- ERROR +DROP SERVER t1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER t1 CASCADE" +== 516 +-- truncate_limit: 100 +DROP USER MAPPING FOR regress_test_role SERVER s6 +-- +STMT: DropUserMappingStmt +TRUNCATED: "DROP USER MAPPING FOR regress_test_role SERVER s6" +== 517 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER foo CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER foo CASCADE" +== 518 +-- truncate_limit: 100 +DROP SERVER s8 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SERVER s8 CASCADE" +== 519 +-- truncate_limit: 100 +DROP ROLE regress_test_indirect +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_indirect" +== 520 +-- truncate_limit: 100 +DROP ROLE regress_test_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role" +== 521 +-- truncate_limit: 100 +DROP ROLE regress_unprivileged_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_unprivileged_role" +== 522 +-- truncate_limit: 100 +-- ERROR +REVOKE ALL ON FOREIGN DATA WRAPPER postgresql FROM regress_unprivileged_role +-- +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON FOREIGN DATA WRAPPER postgresql FROM regress_unprivileged_role" +== 523 +-- truncate_limit: 100 +DROP ROLE regress_unprivileged_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_unprivileged_role" +== 524 +-- truncate_limit: 100 +DROP ROLE regress_test_role2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role2" +== 525 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER postgresql CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER postgresql CASCADE" +== 526 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER dummy CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER dummy CASCADE" +== 527 +-- truncate_limit: 100 +DROP ROLE regress_foreign_data_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_foreign_data_user" +== 528 +-- truncate_limit: 100 +-- At this point we should have no wrappers, no servers, and no mappings. +SELECT fdwname, fdwhandler, fdwvalidator, fdwoptions FROM pg_foreign_data_wrapper +-- +TABLE: name="pg_foreign_data_wrapper" schema="" table="pg_foreign_data_wrapper" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT fdwname, fdwhandler, fdwvalidator, fdwoptions FROM pg_foreign_data_wrapper" +== 529 +-- truncate_limit: 100 +SELECT srvname, srvoptions FROM pg_foreign_server +-- +TABLE: name="pg_foreign_server" schema="" table="pg_foreign_server" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT srvname, srvoptions FROM pg_foreign_server" +== 530 +-- truncate_limit: 100 +SELECT * FROM pg_user_mapping +-- +TABLE: name="pg_user_mapping" schema="" table="pg_user_mapping" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_user_mapping" diff --git a/parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json b/parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json new file mode 100644 index 0000000..0d39ce9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json @@ -0,0 +1,1158 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "1060", + "1061", + "1062", + "1063", + "1064", + "1065", + "1066", + "1067", + "1068", + "1069", + "107", + "1070", + "1071", + "1072", + "1073", + "1074", + "1075", + "1076", + "1077", + "1078", + "1079", + "108", + "1080", + "1081", + "1082", + "1083", + "1084", + "1085", + "1086", + "1087", + "1088", + "1089", + "109", + "1090", + "1091", + "1092", + "1093", + "1094", + "1095", + "1096", + "1097", + "1098", + "1099", + "110", + "1100", + "1101", + "1102", + "1103", + "1104", + "1105", + "1106", + "1107", + "1108", + "1109", + "111", + "1110", + "1111", + "1112", + "1113", + "1114", + "1115", + "1116", + "1117", + "1118", + "1119", + "112", + "1120", + "1121", + "1122", + "1123", + "1124", + "1125", + "1126", + "1127", + "1128", + "1129", + "113", + "1130", + "1131", + "1132", + "1133", + "1134", + "1135", + "1136", + "1137", + "1138", + "1139", + "114", + "1140", + "1141", + "1142", + "1143", + "1144", + "1145", + "1146", + "1147", + "1148", + "1149", + "115", + "1150", + "1151", + "1152", + "1153", + "1154", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/foreign_key.test b/parser/testdata/summary_truncate/postgres_regress/foreign_key.test new file mode 100644 index 0000000..fac38a6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/foreign_key.test @@ -0,0 +1,9039 @@ +== 001 +-- truncate_limit: 100 +|-- +-- FOREIGN KEY +|-- + +-- MATCH FULL +|-- +-- First test, check and cascade +|-- +CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int PRIMARY KEY, ptest2 text)" +== 002 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int REFERENCES PKTABLE MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, ftest2 int ) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int REFERENCES pktable MATCH FULL ON UPDATE CASCADE ON DELETE CASCAD..." +== 003 +-- truncate_limit: 100 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 'Test1')" +== 004 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 'Test2')" +== 005 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (3, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (3, 'Test3')" +== 006 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (4, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (4, 'Test4')" +== 007 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (5, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (5, 'Test5')" +== 008 +-- truncate_limit: 100 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2)" +== 009 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 3)" +== 010 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (3, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (3, 4)" +== 011 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 1)" +== 012 +-- truncate_limit: 100 +-- Insert a failed row into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (100, 2)" +== 013 +-- truncate_limit: 100 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 014 +-- truncate_limit: 100 +-- Delete a row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 1" +== 015 +-- truncate_limit: 100 +-- Check FKTABLE for removal of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 016 +-- truncate_limit: 100 +-- Update a row from PK TABLE +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 1 WHERE ptest1 = 2" +== 017 +-- truncate_limit: 100 +-- Check FKTABLE for update of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 018 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 019 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 020 +-- truncate_limit: 100 +|-- +-- check set NULL and table constraint on multiple columns +|-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY (ptest1, ptest2))" +== 021 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, CONSTRAINT constrname FOREIGN KEY(ftest1, ftest2) + REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 int, ftest3 int, CONSTRAINT constrname FOREIGN KEY (ftes..." +== 022 +-- truncate_limit: 100 +-- Test comments +COMMENT ON CONSTRAINT constrname_wrong ON FKTABLE IS 'fk constraint comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT constrname_wrong ON fktable IS 'fk constraint comment'" +== 023 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT constrname ON FKTABLE IS 'fk constraint comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT constrname ON fktable IS 'fk constraint comment'" +== 024 +-- truncate_limit: 100 +COMMENT ON CONSTRAINT constrname ON FKTABLE IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON CONSTRAINT constrname ON fktable IS NULL" +== 025 +-- truncate_limit: 100 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 2, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2, 'Test1')" +== 026 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 3, 'Test1-2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 3, 'Test1-2')" +== 027 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 4, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 4, 'Test2')" +== 028 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (3, 6, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (3, 6, 'Test3')" +== 029 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (4, 8, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (4, 8, 'Test4')" +== 030 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (5, 10, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (5, 10, 'Test5')" +== 031 +-- truncate_limit: 100 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 4)" +== 032 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (1, 3, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 3, 5)" +== 033 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 4, 8) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 4, 8)" +== 034 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (3, 6, 12) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (3, 6, 12)" +== 035 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, NULL, 0) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, NULL, 0)" +== 036 +-- truncate_limit: 100 +-- Insert failed rows into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (100, 2, 4)" +== 037 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 2, 4)" +== 038 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 4)" +== 039 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (1, NULL, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, NULL, 4)" +== 040 +-- truncate_limit: 100 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 041 +-- truncate_limit: 100 +-- Delete a row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=1 and ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 1 AND ptest2 = 2" +== 042 +-- truncate_limit: 100 +-- Check FKTABLE for removal of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 043 +-- truncate_limit: 100 +-- Delete another row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=5 and ptest2=10 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 5 AND ptest2 = 10" +== 044 +-- truncate_limit: 100 +-- Check FKTABLE (should be no change) +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 045 +-- truncate_limit: 100 +-- Update a row from PK TABLE +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 1 WHERE ptest1 = 2" +== 046 +-- truncate_limit: 100 +-- Check FKTABLE for update of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 047 +-- truncate_limit: 100 +-- Check update with part of key null +UPDATE FKTABLE SET ftest1 = NULL WHERE ftest1 = 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET ftest1 = NULL WHERE ftest1 = 1" +== 048 +-- truncate_limit: 100 +-- Check update with old and new key values equal +UPDATE FKTABLE SET ftest1 = 1 WHERE ftest1 = 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET ftest1 = 1 WHERE ftest1 = 1" +== 049 +-- truncate_limit: 100 +-- Try altering the column type where foreign keys are involved +ALTER TABLE PKTABLE ALTER COLUMN ptest1 TYPE bigint +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pktable ALTER COLUMN ptest1 TYPE bigint" +== 050 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ALTER COLUMN ftest1 TYPE bigint +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ALTER COLUMN ftest1 TYPE bigint" +== 051 +-- truncate_limit: 100 +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 052 +-- truncate_limit: 100 +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 053 +-- truncate_limit: 100 +DROP TABLE PKTABLE CASCADE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable CASCADE" +== 054 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 055 +-- truncate_limit: 100 +|-- +-- check set default and table constraint on multiple columns +|-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY (ptest1, ptest2))" +== 056 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int DEFAULT -1, ftest2 int DEFAULT -2, ftest3 int, CONSTRAINT constrname2 FOREIGN KEY(ftest1, ftest2) + REFERENCES PKTABLE MATCH FULL ON DELETE SET DEFAULT ON UPDATE SET DEFAULT) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int DEFAULT -1, ftest2 int DEFAULT -2, ftest3 int, CONSTRAINT constr..." +== 057 +-- truncate_limit: 100 +-- Insert a value in PKTABLE for default +INSERT INTO PKTABLE VALUES (-1, -2, 'The Default!') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (-1, -2, 'The Default!')" +== 058 +-- truncate_limit: 100 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 2, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2, 'Test1')" +== 059 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 3, 'Test1-2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 3, 'Test1-2')" +== 060 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 4, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 4, 'Test2')" +== 061 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (3, 6, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (3, 6, 'Test3')" +== 062 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (4, 8, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (4, 8, 'Test4')" +== 063 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (5, 10, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (5, 10, 'Test5')" +== 064 +-- truncate_limit: 100 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 4)" +== 065 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (1, 3, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 3, 5)" +== 066 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 4, 8) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 4, 8)" +== 067 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (3, 6, 12) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (3, 6, 12)" +== 068 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, NULL, 0) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, NULL, 0)" +== 069 +-- truncate_limit: 100 +-- Insert failed rows into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (100, 2, 4)" +== 070 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 2, 4)" +== 071 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 4)" +== 072 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (1, NULL, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, NULL, 4)" +== 073 +-- truncate_limit: 100 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 074 +-- truncate_limit: 100 +-- Delete a row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=1 and ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 1 AND ptest2 = 2" +== 075 +-- truncate_limit: 100 +-- Check FKTABLE to check for removal +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 076 +-- truncate_limit: 100 +-- Delete another row from PK TABLE +DELETE FROM PKTABLE WHERE ptest1=5 and ptest2=10 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 5 AND ptest2 = 10" +== 077 +-- truncate_limit: 100 +-- Check FKTABLE (should be no change) +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 078 +-- truncate_limit: 100 +-- Update a row from PK TABLE +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 1 WHERE ptest1 = 2" +== 079 +-- truncate_limit: 100 +-- Check FKTABLE for update of matched row +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 080 +-- truncate_limit: 100 +-- this should fail for lack of CASCADE +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 081 +-- truncate_limit: 100 +DROP TABLE PKTABLE CASCADE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable CASCADE" +== 082 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 083 +-- truncate_limit: 100 +|-- +-- First test, check with no on delete or on update +|-- +CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int PRIMARY KEY, ptest2 text)" +== 084 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int REFERENCES PKTABLE MATCH FULL, ftest2 int ) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int REFERENCES pktable MATCH FULL, ftest2 int)" +== 085 +-- truncate_limit: 100 +-- Insert test data into PKTABLE +INSERT INTO PKTABLE VALUES (1, 'Test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 'Test1')" +== 086 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 'Test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 'Test2')" +== 087 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (3, 'Test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (3, 'Test3')" +== 088 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (4, 'Test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (4, 'Test4')" +== 089 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (5, 'Test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (5, 'Test5')" +== 090 +-- truncate_limit: 100 +-- Insert successful rows into FK TABLE +INSERT INTO FKTABLE VALUES (1, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2)" +== 091 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 3)" +== 092 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (3, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (3, 4)" +== 093 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 1)" +== 094 +-- truncate_limit: 100 +-- Insert a failed row into FK TABLE +INSERT INTO FKTABLE VALUES (100, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (100, 2)" +== 095 +-- truncate_limit: 100 +-- Check FKTABLE +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 096 +-- truncate_limit: 100 +-- Check PKTABLE +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 097 +-- truncate_limit: 100 +-- Delete a row from PK TABLE (should fail) +DELETE FROM PKTABLE WHERE ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 1" +== 098 +-- truncate_limit: 100 +-- Delete a row from PK TABLE (should succeed) +DELETE FROM PKTABLE WHERE ptest1=5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 5" +== 099 +-- truncate_limit: 100 +-- Check PKTABLE for deletes +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 100 +-- truncate_limit: 100 +-- Update a row from PK TABLE (should fail) +UPDATE PKTABLE SET ptest1=0 WHERE ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 0 WHERE ptest1 = 2" +== 101 +-- truncate_limit: 100 +-- Update a row from PK TABLE (should succeed) +UPDATE PKTABLE SET ptest1=0 WHERE ptest1=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 0 WHERE ptest1 = 4" +== 102 +-- truncate_limit: 100 +-- Check PKTABLE for updates +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 103 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 104 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 105 +-- truncate_limit: 100 +|-- +-- Check initial check upon ALTER TABLE +|-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, PRIMARY KEY(ptest1, ptest2) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, PRIMARY KEY (ptest1, ptest2))" +== 106 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int ) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 int)" +== 107 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2)" +== 108 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (1, NULL) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, NULL)" +== 109 +-- truncate_limit: 100 +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) REFERENCES PKTABLE MATCH FULL +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD FOREIGN KEY (ftest1, ftest2) REFERENCES pktable MATCH FULL" +== 110 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 111 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 112 +-- truncate_limit: 100 +-- MATCH SIMPLE + +-- Base test restricting update/delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY (ptest1, ptest..." +== 113 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 FORE..." +== 114 +-- truncate_limit: 100 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2, 3, 'test1')" +== 115 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 3, 3, 'test2')" +== 116 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 3, 4, 'test3')" +== 117 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 4, 5, 'test4')" +== 118 +-- truncate_limit: 100 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 3, 1)" +== 119 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 3, 2)" +== 120 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, NULL, 3, 3)" +== 121 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 7, 4)" +== 122 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 3, 4, 5)" +== 123 +-- truncate_limit: 100 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 7, 6)" +== 124 +-- truncate_limit: 100 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 125 +-- truncate_limit: 100 +-- Try to update something that should fail +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest2 = 5 WHERE ptest2 = 2" +== 126 +-- truncate_limit: 100 +-- Try to update something that should succeed +UPDATE PKTABLE set ptest1=1 WHERE ptest2=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 1 WHERE ptest2 = 3" +== 127 +-- truncate_limit: 100 +-- Try to delete something that should fail +DELETE FROM PKTABLE where ptest1=1 and ptest2=2 and ptest3=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 1 AND ptest2 = 2 AND ptest3 = 3" +== 128 +-- truncate_limit: 100 +-- Try to delete something that should work +DELETE FROM PKTABLE where ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 2" +== 129 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 130 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 131 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 132 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 133 +-- truncate_limit: 100 +-- restrict with null values +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, UNIQUE(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, ptest3 int, ptest4 text, UNIQUE (ptest1, ptest2, pt..." +== 134 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE (ptest1, ptest2, ptest3)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 FORE..." +== 135 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2, 3, 'test1')" +== 136 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 3, NULL, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 3, NULL, 'test2')" +== 137 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, NULL, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, NULL, 4, 'test3')" +== 138 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 3, 1)" +== 139 +-- truncate_limit: 100 +DELETE FROM PKTABLE WHERE ptest1 = 2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 2" +== 140 +-- truncate_limit: 100 +SELECT * FROM PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 141 +-- truncate_limit: 100 +SELECT * FROM FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 142 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 143 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 144 +-- truncate_limit: 100 +-- cascade update/delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY (ptest1, ptest..." +== 145 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE CASCADE ON UPDATE CASCADE) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 FORE..." +== 146 +-- truncate_limit: 100 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2, 3, 'test1')" +== 147 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 3, 3, 'test2')" +== 148 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 3, 4, 'test3')" +== 149 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 4, 5, 'test4')" +== 150 +-- truncate_limit: 100 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 3, 1)" +== 151 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 3, 2)" +== 152 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, NULL, 3, 3)" +== 153 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 7, 4)" +== 154 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 3, 4, 5)" +== 155 +-- truncate_limit: 100 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 7, 6)" +== 156 +-- truncate_limit: 100 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 157 +-- truncate_limit: 100 +-- Try to update something that will cascade +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest2 = 5 WHERE ptest2 = 2" +== 158 +-- truncate_limit: 100 +-- Try to update something that should not cascade +UPDATE PKTABLE set ptest1=1 WHERE ptest2=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 1 WHERE ptest2 = 3" +== 159 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 160 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 161 +-- truncate_limit: 100 +-- Try to delete something that should cascade +DELETE FROM PKTABLE where ptest1=1 and ptest2=5 and ptest3=3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 1 AND ptest2 = 5 AND ptest3 = 3" +== 162 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 163 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 164 +-- truncate_limit: 100 +-- Try to delete something that should not have a cascade +DELETE FROM PKTABLE where ptest1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 2" +== 165 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 166 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 167 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 168 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 169 +-- truncate_limit: 100 +-- set null update / set default delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY (ptest1, ptest..." +== 170 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE SET DEFAULT ON UPDATE SET NULL) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int DEFAULT 0, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constr..." +== 171 +-- truncate_limit: 100 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2, 3, 'test1')" +== 172 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 3, 3, 'test2')" +== 173 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 3, 4, 'test3')" +== 174 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 4, 5, 'test4')" +== 175 +-- truncate_limit: 100 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 3, 1)" +== 176 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 3, 4, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 3, 4, 1)" +== 177 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 3, 2)" +== 178 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, NULL, 3, 3)" +== 179 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 7, 4)" +== 180 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 3, 4, 5)" +== 181 +-- truncate_limit: 100 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 7, 6)" +== 182 +-- truncate_limit: 100 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 183 +-- truncate_limit: 100 +-- Try to update something that will set null +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest2 = 5 WHERE ptest2 = 2" +== 184 +-- truncate_limit: 100 +-- Try to update something that should not set null +UPDATE PKTABLE set ptest2=2 WHERE ptest2=3 and ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest2 = 2 WHERE ptest2 = 3 AND ptest1 = 1" +== 185 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 186 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 187 +-- truncate_limit: 100 +-- Try to delete something that should set default +DELETE FROM PKTABLE where ptest1=2 and ptest2=3 and ptest3=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 2 AND ptest2 = 3 AND ptest3 = 4" +== 188 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 189 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 190 +-- truncate_limit: 100 +-- Try to delete something that should not set default +DELETE FROM PKTABLE where ptest2=5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest2 = 5" +== 191 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 192 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 193 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 194 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 195 +-- truncate_limit: 100 +-- set default update / set null delete +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY (ptest1, ptest..." +== 196 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int DEFAULT -1, ftest3 int DEFAULT -2, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE SET NULL ON UPDATE SET DEFAULT) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int DEFAULT 0, ftest2 int DEFAULT -1, ftest3 int DEFAULT -2, ftest4 ..." +== 197 +-- truncate_limit: 100 +-- Insert Primary Key values +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 2, 3, 'test1')" +== 198 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 3, 3, 'test2')" +== 199 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 3, 4, 'test3')" +== 200 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, 4, 5, 'test4')" +== 201 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (2, -1, 5, 'test5') +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2, -1, 5, 'test5')" +== 202 +-- truncate_limit: 100 +-- Insert Foreign Key values +INSERT INTO FKTABLE VALUES (1, 2, 3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 3, 1)" +== 203 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 3, 4, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 3, 4, 1)" +== 204 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, 4, 5, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, 4, 5, 1)" +== 205 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 3, 2)" +== 206 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (2, NULL, 3, 3)" +== 207 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 2, 7, 4)" +== 208 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (NULL, 3, 4, 5)" +== 209 +-- truncate_limit: 100 +-- Insert a failed values +INSERT INTO FKTABLE VALUES (1, 2, 7, 6) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 2, 7, 6)" +== 210 +-- truncate_limit: 100 +-- Show FKTABLE +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 211 +-- truncate_limit: 100 +-- Try to update something that will fail +UPDATE PKTABLE set ptest2=5 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest2 = 5 WHERE ptest2 = 2" +== 212 +-- truncate_limit: 100 +-- Try to update something that will set default +UPDATE PKTABLE set ptest1=0, ptest2=-1, ptest3=-2 where ptest2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest1 = 0, ptest2 = -1, ptest3 = -2 WHERE ptest2 = 2" +== 213 +-- truncate_limit: 100 +UPDATE PKTABLE set ptest2=10 where ptest2=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest2 = 10 WHERE ptest2 = 4" +== 214 +-- truncate_limit: 100 +-- Try to update something that should not set default +UPDATE PKTABLE set ptest2=2 WHERE ptest2=3 and ptest1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET ptest2 = 2 WHERE ptest2 = 3 AND ptest1 = 1" +== 215 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 216 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 217 +-- truncate_limit: 100 +-- Try to delete something that should set null +DELETE FROM PKTABLE where ptest1=2 and ptest2=3 and ptest3=4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest1 = 2 AND ptest2 = 3 AND ptest3 = 4" +== 218 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 219 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 220 +-- truncate_limit: 100 +-- Try to delete something that should not set null +DELETE FROM PKTABLE where ptest2=-1 and ptest3=5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE ptest2 = -1 AND ptest3 = 5" +== 221 +-- truncate_limit: 100 +-- Show PKTABLE and FKTABLE +SELECT * from PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable" +== 222 +-- truncate_limit: 100 +SELECT * from FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable" +== 223 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 224 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 225 +-- truncate_limit: 100 +-- Test for ON DELETE SET NULL/DEFAULT (column_list); +CREATE TABLE PKTABLE (tid int, id int, PRIMARY KEY (tid, id)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (tid int, id int, PRIMARY KEY (tid, id))" +== 226 +-- truncate_limit: 100 +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES PKTABLE ON DELETE SET NULL (bar)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES pktable ON DELET..." +== 227 +-- truncate_limit: 100 +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES PKTABLE ON DELETE SET NULL (foo)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES pktable ON DELET..." +== 228 +-- truncate_limit: 100 +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, foo) REFERENCES PKTABLE ON UPDATE SET NULL (foo)) +-- +ERROR: a column list with SET NULL is only supported for ON DELETE actions +CURSORPOS: 91 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 229 +-- truncate_limit: 100 +CREATE TABLE FKTABLE ( + tid int, id int, + fk_id_del_set_null int, + fk_id_del_set_default int DEFAULT 0, + FOREIGN KEY (tid, fk_id_del_set_null) REFERENCES PKTABLE ON DELETE SET NULL (fk_id_del_set_null), + -- this tests handling of duplicate entries in SET DEFAULT column list + FOREIGN KEY (tid, fk_id_del_set_default) REFERENCES PKTABLE ON DELETE SET DEFAULT (fk_id_del_set_default, fk_id_del_set_default) +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (tid int, id int, fk_id_del_set_null int, fk_id_del_set_default int DEFAULT ..." +== 230 +-- truncate_limit: 100 +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'fktable'::regclass::oid ORDER BY oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE ... ORDER BY oid" +== 231 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES (1, 0), (1, 1), (1, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (1, 0), (1, 1), (1, 2)" +== 232 +-- truncate_limit: 100 +INSERT INTO FKTABLE VALUES + (1, 1, 1, NULL), + (1, 2, NULL, 2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 1, 1, NULL), (1, 2, NULL, 2)" +== 233 +-- truncate_limit: 100 +DELETE FROM PKTABLE WHERE id = 1 OR id = 2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE id = 1 OR id = 2" +== 234 +-- truncate_limit: 100 +SELECT * FROM FKTABLE ORDER BY id +-- +TABLE: name="fktable" schema="" table="fktable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable ORDER BY id" +== 235 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 236 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 237 +-- truncate_limit: 100 +-- Test some invalid FK definitions +CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY, someoid oid) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int PRIMARY KEY, someoid oid)" +== 238 +-- truncate_limit: 100 +CREATE TABLE FKTABLE_FAIL1 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest2) REFERENCES PKTABLE) +-- +TABLE: name="fktable_fail1" schema="" table="fktable_fail1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable_fail1 (ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest2) REFERENCES pktable)" +== 239 +-- truncate_limit: 100 +CREATE TABLE FKTABLE_FAIL2 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES PKTABLE(ptest2)) +-- +TABLE: name="fktable_fail2" schema="" table="fktable_fail2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable_fail2 (ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES pktabl..." +== 240 +-- truncate_limit: 100 +CREATE TABLE FKTABLE_FAIL3 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (tableoid) REFERENCES PKTABLE(someoid)) +-- +TABLE: name="fktable_fail3" schema="" table="fktable_fail3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable_fail3 (ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (tableoid) REFERENCES pkta..." +== 241 +-- truncate_limit: 100 +CREATE TABLE FKTABLE_FAIL4 ( ftest1 oid, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES PKTABLE(tableoid)) +-- +TABLE: name="fktable_fail4" schema="" table="fktable_fail4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable_fail4 (ftest1 oid, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES pktabl..." +== 242 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 243 +-- truncate_limit: 100 +-- Test for referencing column number smaller than referenced constraint +CREATE TABLE PKTABLE (ptest1 int, ptest2 int, UNIQUE(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, UNIQUE (ptest1, ptest2))" +== 244 +-- truncate_limit: 100 +CREATE TABLE FKTABLE_FAIL1 (ftest1 int REFERENCES pktable(ptest1)) +-- +TABLE: name="fktable_fail1" schema="" table="fktable_fail1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable_fail1 (ftest1 int REFERENCES pktable (ptest1))" +== 245 +-- truncate_limit: 100 +DROP TABLE FKTABLE_FAIL1 +-- +TABLE: name="fktable_fail1" schema="" table="fktable_fail1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable_fail1" +== 246 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 247 +-- truncate_limit: 100 +|-- +-- Tests for mismatched types +|-- +-- Basic one column, two table setup +CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int PRIMARY KEY)" +== 248 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (42)" +== 249 +-- truncate_limit: 100 +-- This next should fail, because int=inet does not exist +CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 inet REFERENCES pktable)" +== 250 +-- truncate_limit: 100 +-- This should also fail for the same reason, but here we +-- give the column name +CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable(ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 inet REFERENCES pktable (ptest1))" +== 251 +-- truncate_limit: 100 +-- This should succeed, even though they are different types, +-- because int=int8 exists and is a member of the integer opfamily +CREATE TABLE FKTABLE (ftest1 int8 REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int8 REFERENCES pktable)" +== 252 +-- truncate_limit: 100 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (42)" +== 253 +-- truncate_limit: 100 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (43)" +== 254 +-- truncate_limit: 100 +-- should fail +UPDATE FKTABLE SET ftest1 = ftest1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET ftest1 = ftest1" +== 255 +-- truncate_limit: 100 +-- should succeed +UPDATE FKTABLE SET ftest1 = ftest1 + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET ftest1 = ftest1 + 1" +== 256 +-- truncate_limit: 100 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 257 +-- truncate_limit: 100 +-- This should fail, because we'd have to cast numeric to int which is +-- not an implicit coercion (or use numeric=numeric, but that's not part +-- of the integer opfamily) +CREATE TABLE FKTABLE (ftest1 numeric REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 numeric REFERENCES pktable)" +== 258 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 259 +-- truncate_limit: 100 +-- On the other hand, this should work because int implicitly promotes to +-- numeric, and we allow promotion on the FK side +CREATE TABLE PKTABLE (ptest1 numeric PRIMARY KEY) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 numeric PRIMARY KEY)" +== 260 +-- truncate_limit: 100 +INSERT INTO PKTABLE VALUES(42) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (42)" +== 261 +-- truncate_limit: 100 +CREATE TABLE FKTABLE (ftest1 int REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int REFERENCES pktable)" +== 262 +-- truncate_limit: 100 +-- Check it actually works +INSERT INTO FKTABLE VALUES(42) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (42)" +== 263 +-- truncate_limit: 100 +-- should succeed +INSERT INTO FKTABLE VALUES(43) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (43)" +== 264 +-- truncate_limit: 100 +-- should fail +UPDATE FKTABLE SET ftest1 = ftest1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET ftest1 = ftest1" +== 265 +-- truncate_limit: 100 +-- should succeed +UPDATE FKTABLE SET ftest1 = ftest1 + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET ftest1 = ftest1 + 1" +== 266 +-- truncate_limit: 100 +-- should fail +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 267 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 268 +-- truncate_limit: 100 +-- Two columns, two tables +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 inet, PRIMARY KEY (ptest1, ptest2))" +== 269 +-- truncate_limit: 100 +-- This should fail, because we just chose really odd types +CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 cidr, ftest2 timestamp, FOREIGN KEY (ftest1, ftest2) REFERENCES pkta..." +== 270 +-- truncate_limit: 100 +-- Again, so should this... +CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 cidr, ftest2 timestamp, FOREIGN KEY (ftest1, ftest2) REFERENCES pkta..." +== 271 +-- truncate_limit: 100 +-- This fails because we mixed up the column ordering +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest2, ftest1) REFERENCES pktable)" +== 272 +-- truncate_limit: 100 +-- As does this... +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest2, ftest1) REFERENCES pktable (p..." +== 273 +-- truncate_limit: 100 +-- And again.. +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest1, ftest2) REFERENCES pktable (p..." +== 274 +-- truncate_limit: 100 +-- This works... +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest2, ftest1) REFERENCES pktable (p..." +== 275 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 276 +-- truncate_limit: 100 +-- As does this +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest1, ftest2) REFERENCES pktable (p..." +== 277 +-- truncate_limit: 100 +DROP TABLE FKTABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 278 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 279 +-- truncate_limit: 100 +-- Two columns, same table +-- Make sure this still works... +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY (ptest1, ptes..." +== 280 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 281 +-- truncate_limit: 100 +-- And this, +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY (ptest1, ptes..." +== 282 +-- truncate_limit: 100 +DROP TABLE PKTABLE +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 283 +-- truncate_limit: 100 +-- This shouldn't (mixed up columns) +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable(ptest2, ptest1)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY (ptest1, ptes..." +== 284 +-- truncate_limit: 100 +-- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, +ptest3) REFERENCES pktable(ptest1, ptest2)) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY (ptest1, ptes..." +== 285 +-- truncate_limit: 100 +-- Not this one either... Same as the last one except we didn't defined the columns being referenced. +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, +ptest3) REFERENCES pktable) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY (ptest1, ptes..." +== 286 +-- truncate_limit: 100 +|-- +-- Now some cases with inheritance +-- Basic 2 table case: 1 column of matching types. +create table pktable_base (base1 int not null) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable_base (base1 int NOT NULL)" +== 287 +-- truncate_limit: 100 +create table pktable (ptest1 int, primary key(base1), unique(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, PRIMARY KEY (base1), UNIQUE (base1, ptest1)) INHERITS (pktable_..." +== 288 +-- truncate_limit: 100 +create table fktable (ftest1 int references pktable(base1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int REFERENCES pktable (base1))" +== 289 +-- truncate_limit: 100 +-- now some ins, upd, del +insert into pktable(base1) values (1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1) VALUES (1)" +== 290 +-- truncate_limit: 100 +insert into pktable(base1) values (2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1) VALUES (2)" +== 291 +-- truncate_limit: 100 +-- let's insert a non-existent fktable value +insert into fktable(ftest1) values (3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable (ftest1) VALUES (3)" +== 292 +-- truncate_limit: 100 +-- let's make a valid row for that +insert into pktable(base1) values (3) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1) VALUES (3)" +== 293 +-- truncate_limit: 100 +insert into fktable(ftest1) values (3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable (ftest1) VALUES (3)" +== 294 +-- truncate_limit: 100 +-- let's try removing a row that should fail from pktable +delete from pktable where base1>2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE base1 > 2" +== 295 +-- truncate_limit: 100 +-- okay, let's try updating all of the base1 values to *4 +-- which should fail. +update pktable set base1=base1*4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET base1 = base1 * 4" +== 296 +-- truncate_limit: 100 +-- okay, let's try an update that should work. +update pktable set base1=base1*4 where base1<3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET base1 = base1 * 4 WHERE base1 < 3" +== 297 +-- truncate_limit: 100 +-- and a delete that should work +delete from pktable where base1>3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE base1 > 3" +== 298 +-- truncate_limit: 100 +-- cleanup +drop table fktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 299 +-- truncate_limit: 100 +delete from pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable" +== 300 +-- truncate_limit: 100 +-- Now 2 columns 2 tables, matching types +create table fktable (ftest1 int, ftest2 int, foreign key(ftest1, ftest2) references pktable(base1, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 int, FOREIGN KEY (ftest1, ftest2) REFERENCES pktable (ba..." +== 301 +-- truncate_limit: 100 +-- now some ins, upd, del +insert into pktable(base1, ptest1) values (1, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1) VALUES (1, 1)" +== 302 +-- truncate_limit: 100 +insert into pktable(base1, ptest1) values (2, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1) VALUES (2, 2)" +== 303 +-- truncate_limit: 100 +-- let's insert a non-existent fktable value +insert into fktable(ftest1, ftest2) values (3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable (ftest1, ftest2) VALUES (3, 1)" +== 304 +-- truncate_limit: 100 +-- let's make a valid row for that +insert into pktable(base1,ptest1) values (3, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1) VALUES (3, 1)" +== 305 +-- truncate_limit: 100 +insert into fktable(ftest1, ftest2) values (3, 1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable (ftest1, ftest2) VALUES (3, 1)" +== 306 +-- truncate_limit: 100 +-- let's try removing a row that should fail from pktable +delete from pktable where base1>2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE base1 > 2" +== 307 +-- truncate_limit: 100 +-- okay, let's try updating all of the base1 values to *4 +-- which should fail. +update pktable set base1=base1*4 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET base1 = base1 * 4" +== 308 +-- truncate_limit: 100 +-- okay, let's try an update that should work. +update pktable set base1=base1*4 where base1<3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET base1 = base1 * 4 WHERE base1 < 3" +== 309 +-- truncate_limit: 100 +-- and a delete that should work +delete from pktable where base1>3 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE base1 > 3" +== 310 +-- truncate_limit: 100 +-- cleanup +drop table fktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable" +== 311 +-- truncate_limit: 100 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 312 +-- truncate_limit: 100 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable_base" +== 313 +-- truncate_limit: 100 +-- Now we'll do one all in 1 table with 2 columns of matching types +create table pktable_base(base1 int not null, base2 int) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable_base (base1 int NOT NULL, base2 int)" +== 314 +-- truncate_limit: 100 +create table pktable(ptest1 int, ptest2 int, primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 int, ptest2 int, PRIMARY KEY (base1, ptest1), FOREIGN KEY (base2, pt..." +== 315 +-- truncate_limit: 100 +insert into pktable (base1, ptest1, base2, ptest2) values (1, 1, 1, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1, base2, ptest2) VALUES (1, 1, 1, 1)" +== 316 +-- truncate_limit: 100 +insert into pktable (base1, ptest1, base2, ptest2) values (2, 1, 1, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1, base2, ptest2) VALUES (2, 1, 1, 1)" +== 317 +-- truncate_limit: 100 +insert into pktable (base1, ptest1, base2, ptest2) values (2, 2, 2, 1) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1, base2, ptest2) VALUES (2, 2, 2, 1)" +== 318 +-- truncate_limit: 100 +insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1, base2, ptest2) VALUES (1, 3, 2, 2)" +== 319 +-- truncate_limit: 100 +-- fails (3,2) isn't in base1, ptest1 +insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable (base1, ptest1, base2, ptest2) VALUES (2, 3, 3, 2)" +== 320 +-- truncate_limit: 100 +-- fails (2,2) is being referenced +delete from pktable where base1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE base1 = 2" +== 321 +-- truncate_limit: 100 +-- fails (1,1) is being referenced (twice) +update pktable set base1=3 where base1=1 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET base1 = 3 WHERE base1 = 1" +== 322 +-- truncate_limit: 100 +-- this sequence of two deletes will work, since after the first there will be no (2,*) references +delete from pktable where base2=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE base2 = 2" +== 323 +-- truncate_limit: 100 +delete from pktable where base1=2 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable WHERE base1 = 2" +== 324 +-- truncate_limit: 100 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 325 +-- truncate_limit: 100 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable_base" +== 326 +-- truncate_limit: 100 +-- 2 columns (2 tables), mismatched types +create table pktable_base(base1 int not null) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable_base (base1 int NOT NULL)" +== 327 +-- truncate_limit: 100 +create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 inet, PRIMARY KEY (base1, ptest1)) INHERITS (pktable_base)" +== 328 +-- truncate_limit: 100 +-- just generally bad types (with and without column references on the referenced table) +create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 cidr, ftest2 int[], FOREIGN KEY (ftest1, ftest2) REFERENCES pktable)" +== 329 +-- truncate_limit: 100 +create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 cidr, ftest2 int[], FOREIGN KEY (ftest1, ftest2) REFERENCES pktable ..." +== 330 +-- truncate_limit: 100 +-- let's mix up which columns reference which +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest2, ftest1) REFERENCES pktable)" +== 331 +-- truncate_limit: 100 +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest2, ftest1) REFERENCES pktable (b..." +== 332 +-- truncate_limit: 100 +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1)) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (ftest1 int, ftest2 inet, FOREIGN KEY (ftest1, ftest2) REFERENCES pktable (p..." +== 333 +-- truncate_limit: 100 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 334 +-- truncate_limit: 100 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable_base" +== 335 +-- truncate_limit: 100 +-- 2 columns (1 table), mismatched types +create table pktable_base(base1 int not null, base2 int) +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable_base (base1 int NOT NULL, base2 int)" +== 336 +-- truncate_limit: 100 +create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 inet, ptest2 inet[], PRIMARY KEY (base1, ptest1), FOREIGN KEY (base2..." +== 337 +-- truncate_limit: 100 +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(ptest1, base1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 inet, ptest2 inet, PRIMARY KEY (base1, ptest1), FOREIGN KEY (base2, ..." +== 338 +-- truncate_limit: 100 +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 inet, ptest2 inet, PRIMARY KEY (base1, ptest1), FOREIGN KEY (ptest2,..." +== 339 +-- truncate_limit: 100 +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references + pktable(base1, ptest1)) inherits (pktable_base) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (ptest1 inet, ptest2 inet, PRIMARY KEY (base1, ptest1), FOREIGN KEY (ptest2,..." +== 340 +-- truncate_limit: 100 +drop table pktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable" +== 341 +-- truncate_limit: 100 +drop table pktable_base +-- +TABLE: name="pktable_base" schema="" table="pktable_base" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable_base" +== 342 +-- truncate_limit: 100 +|-- +-- Deferrable constraints +|-- + +-- deferrable, explicitly deferred +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (id int4 PRIMARY KEY, other int4)" +== 343 +-- truncate_limit: 100 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (id int4 PRIMARY KEY, fk int4 REFERENCES pktable DEFERRABLE)" +== 344 +-- truncate_limit: 100 +-- default to immediate: should fail +INSERT INTO fktable VALUES (5, 10) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (5, 10)" +== 345 +-- truncate_limit: 100 +-- explicitly defer the constraint +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 346 +-- truncate_limit: 100 +SET CONSTRAINTS ALL DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS ALL DEFERRED" +== 347 +-- truncate_limit: 100 +INSERT INTO fktable VALUES (10, 15) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (10, 15)" +== 348 +-- truncate_limit: 100 +INSERT INTO pktable VALUES (15, 0) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (15, 0)" +== 349 +-- truncate_limit: 100 +-- make the FK insert valid + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 350 +-- truncate_limit: 100 +DROP TABLE fktable, pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable, pktable" +== 351 +-- truncate_limit: 100 +-- deferrable, initially deferred +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (id int4 PRIMARY KEY, other int4)" +== 352 +-- truncate_limit: 100 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (id int4 PRIMARY KEY, fk int4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED)" +== 353 +-- truncate_limit: 100 +-- default to deferred, should succeed +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 354 +-- truncate_limit: 100 +INSERT INTO fktable VALUES (100, 200) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (100, 200)" +== 355 +-- truncate_limit: 100 +INSERT INTO pktable VALUES (200, 500) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (200, 500)" +== 356 +-- truncate_limit: 100 +-- make the FK insert valid + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 357 +-- truncate_limit: 100 +-- default to deferred, explicitly make immediate +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 358 +-- truncate_limit: 100 +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS ALL IMMEDIATE" +== 359 +-- truncate_limit: 100 +-- should fail +INSERT INTO fktable VALUES (500, 1000) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (500, 1000)" +== 360 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 361 +-- truncate_limit: 100 +DROP TABLE fktable, pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable, pktable" +== 362 +-- truncate_limit: 100 +-- tricky behavior: according to SQL99, if a deferred constraint is set +-- to 'immediate' mode, it should be checked for validity *immediately*, +-- not when the current transaction commits (i.e. the mode change applies +-- retroactively) +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (id int4 PRIMARY KEY, other int4)" +== 363 +-- truncate_limit: 100 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (id int4 PRIMARY KEY, fk int4 REFERENCES pktable DEFERRABLE)" +== 364 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 365 +-- truncate_limit: 100 +SET CONSTRAINTS ALL DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS ALL DEFERRED" +== 366 +-- truncate_limit: 100 +-- should succeed, for now +INSERT INTO fktable VALUES (1000, 2000) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1000, 2000)" +== 367 +-- truncate_limit: 100 +-- should cause transaction abort, due to preceding error +SET CONSTRAINTS ALL IMMEDIATE +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS ALL IMMEDIATE" +== 368 +-- truncate_limit: 100 +INSERT INTO pktable VALUES (2000, 3) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (2000, 3)" +== 369 +-- truncate_limit: 100 +-- too late + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 370 +-- truncate_limit: 100 +DROP TABLE fktable, pktable +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fktable, pktable" +== 371 +-- truncate_limit: 100 +-- deferrable, initially deferred +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable (id int4 PRIMARY KEY, other int4)" +== 372 +-- truncate_limit: 100 +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable (id int4 PRIMARY KEY, fk int4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED)" +== 373 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 374 +-- truncate_limit: 100 +-- no error here +INSERT INTO fktable VALUES (100, 200) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (100, 200)" +== 375 +-- truncate_limit: 100 +-- error here on commit +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 376 +-- truncate_limit: 100 +DROP TABLE pktable, fktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable, fktable" +== 377 +-- truncate_limit: 100 +-- test notice about expensive referential integrity checks, +-- where the index cannot be used because of type incompatibilities. + +CREATE TEMP TABLE pktable ( + id1 INT4 PRIMARY KEY, + id2 VARCHAR(4) UNIQUE, + id3 REAL UNIQUE, + UNIQUE(id1, id2, id3) +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pktable (id1 int4 PRIMARY KEY, id2 varchar(4) UNIQUE, id3 real UNIQUE, UNI..." +== 378 +-- truncate_limit: 100 +CREATE TEMP TABLE fktable ( + x1 INT4 REFERENCES pktable(id1), + x2 VARCHAR(4) REFERENCES pktable(id2), + x3 REAL REFERENCES pktable(id3), + x4 TEXT, + x5 INT2 +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (x1 int4 REFERENCES pktable (id1), x2 varchar(4) REFERENCES pktabl..." +== 379 +-- truncate_limit: 100 +-- check individual constraints with alter table. + +-- should fail + +-- varchar does not promote to real +ALTER TABLE fktable ADD CONSTRAINT fk_2_3 +FOREIGN KEY (x2) REFERENCES pktable(id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_2_3 FOREIGN KEY (x2) REFERENCES pktable (id3)" +== 380 +-- truncate_limit: 100 +-- nor to int4 +ALTER TABLE fktable ADD CONSTRAINT fk_2_1 +FOREIGN KEY (x2) REFERENCES pktable(id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_2_1 FOREIGN KEY (x2) REFERENCES pktable (id1)" +== 381 +-- truncate_limit: 100 +-- real does not promote to int4 +ALTER TABLE fktable ADD CONSTRAINT fk_3_1 +FOREIGN KEY (x3) REFERENCES pktable(id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_3_1 FOREIGN KEY (x3) REFERENCES pktable (id1)" +== 382 +-- truncate_limit: 100 +-- int4 does not promote to text +ALTER TABLE fktable ADD CONSTRAINT fk_1_2 +FOREIGN KEY (x1) REFERENCES pktable(id2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_1_2 FOREIGN KEY (x1) REFERENCES pktable (id2)" +== 383 +-- truncate_limit: 100 +-- should succeed + +-- int4 promotes to real +ALTER TABLE fktable ADD CONSTRAINT fk_1_3 +FOREIGN KEY (x1) REFERENCES pktable(id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_1_3 FOREIGN KEY (x1) REFERENCES pktable (id3)" +== 384 +-- truncate_limit: 100 +-- text is compatible with varchar +ALTER TABLE fktable ADD CONSTRAINT fk_4_2 +FOREIGN KEY (x4) REFERENCES pktable(id2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_4_2 FOREIGN KEY (x4) REFERENCES pktable (id2)" +== 385 +-- truncate_limit: 100 +-- int2 is part of integer opfamily as of 8.0 +ALTER TABLE fktable ADD CONSTRAINT fk_5_1 +FOREIGN KEY (x5) REFERENCES pktable(id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_5_1 FOREIGN KEY (x5) REFERENCES pktable (id1)" +== 386 +-- truncate_limit: 100 +-- check multikey cases, especially out-of-order column lists + +-- these should work + +ALTER TABLE fktable ADD CONSTRAINT fk_123_123 +FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id1,id2,id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_123_123 FOREIGN KEY (x1, x2, x3) REFERENCES pktable (id1, i..." +== 387 +-- truncate_limit: 100 +ALTER TABLE fktable ADD CONSTRAINT fk_213_213 +FOREIGN KEY (x2,x1,x3) REFERENCES pktable(id2,id1,id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_213_213 FOREIGN KEY (x2, x1, x3) REFERENCES pktable (id2, i..." +== 388 +-- truncate_limit: 100 +ALTER TABLE fktable ADD CONSTRAINT fk_253_213 +FOREIGN KEY (x2,x5,x3) REFERENCES pktable(id2,id1,id3) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_253_213 FOREIGN KEY (x2, x5, x3) REFERENCES pktable (id2, i..." +== 389 +-- truncate_limit: 100 +-- these should fail + +ALTER TABLE fktable ADD CONSTRAINT fk_123_231 +FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id2,id3,id1) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_123_231 FOREIGN KEY (x1, x2, x3) REFERENCES pktable (id2, i..." +== 390 +-- truncate_limit: 100 +ALTER TABLE fktable ADD CONSTRAINT fk_241_132 +FOREIGN KEY (x2,x4,x1) REFERENCES pktable(id1,id3,id2) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ADD CONSTRAINT fk_241_132 FOREIGN KEY (x2, x4, x1) REFERENCES pktable (id1, i..." +== 391 +-- truncate_limit: 100 +DROP TABLE pktable, fktable +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable, fktable" +== 392 +-- truncate_limit: 100 +-- test a tricky case: we can elide firing the FK check trigger during +-- an UPDATE if the UPDATE did not change the foreign key +-- field. However, we can't do this if our transaction was the one that +-- created the updated row and the trigger is deferred, since our UPDATE +-- will have invalidated the original newly-inserted tuple, and therefore +-- cause the on-INSERT RI trigger not to be fired. + +CREATE TEMP TABLE pktable ( + id int primary key, + other int +) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pktable (id int PRIMARY KEY, other int)" +== 393 +-- truncate_limit: 100 +CREATE TEMP TABLE fktable ( + id int primary key, + fk int references pktable deferrable initially deferred +) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fktable (id int PRIMARY KEY, fk int REFERENCES pktable DEFERRABLE INITIALL..." +== 394 +-- truncate_limit: 100 +INSERT INTO pktable VALUES (5, 10) +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable VALUES (5, 10)" +== 395 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 396 +-- truncate_limit: 100 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (0, 20)" +== 397 +-- truncate_limit: 100 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET id = id + 1" +== 398 +-- truncate_limit: 100 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 399 +-- truncate_limit: 100 +-- check same case when insert is in a different subtransaction than update + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 400 +-- truncate_limit: 100 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (0, 20)" +== 401 +-- truncate_limit: 100 +-- UPDATE will be in a subxact +SAVEPOINT savept1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT savept1" +== 402 +-- truncate_limit: 100 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET id = id + 1" +== 403 +-- truncate_limit: 100 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 404 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 405 +-- truncate_limit: 100 +-- INSERT will be in a subxact +SAVEPOINT savept1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT savept1" +== 406 +-- truncate_limit: 100 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (0, 20)" +== 407 +-- truncate_limit: 100 +RELEASE SAVEPOINT savept1 +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE savept1" +== 408 +-- truncate_limit: 100 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET id = id + 1" +== 409 +-- truncate_limit: 100 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 410 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 411 +-- truncate_limit: 100 +-- doesn't match PK, but no error yet +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (0, 20)" +== 412 +-- truncate_limit: 100 +-- UPDATE will be in a subxact +SAVEPOINT savept1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT savept1" +== 413 +-- truncate_limit: 100 +-- don't change FK +UPDATE fktable SET id = id + 1 +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fktable SET id = id + 1" +== 414 +-- truncate_limit: 100 +-- Roll back the UPDATE +ROLLBACK TO savept1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT savept1" +== 415 +-- truncate_limit: 100 +-- should catch error from initial INSERT +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 416 +-- truncate_limit: 100 +|-- +-- check ALTER CONSTRAINT +|-- + +INSERT INTO fktable VALUES (1, 5) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (1, 5)" +== 417 +-- truncate_limit: 100 +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey DEFERRABLE" +== 418 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 419 +-- truncate_limit: 100 +-- doesn't match FK, should throw error now +UPDATE pktable SET id = 10 WHERE id = 5 +-- +TABLE: name="pktable" schema="" table="pktable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable SET id = 10 WHERE id = 5" +== 420 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 421 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 422 +-- truncate_limit: 100 +-- doesn't match PK, should throw error now +INSERT INTO fktable VALUES (0, 20) +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable VALUES (0, 20)" +== 423 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 424 +-- truncate_limit: 100 +-- try additional syntax +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT DEFERRABLE +-- +TABLE: name="fktable" schema="" table="fktable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey" +== 425 +-- truncate_limit: 100 +-- illegal options +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT DEFERRABLE INITIALLY DEFERRED +-- +ERROR: constraint declared INITIALLY DEFERRED must be DEFERRABLE +CURSORPOS: 88 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 426 +-- truncate_limit: 100 +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NO INHERIT +-- +ERROR: FOREIGN KEY constraints cannot be marked NO INHERIT +FILENAME: gram.y +FUNCNAME: processCASbits +== 427 +-- truncate_limit: 100 +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT VALID +-- +ERROR: FOREIGN KEY constraints cannot be marked NOT VALID +FILENAME: gram.y +FUNCNAME: processCASbits +== 428 +-- truncate_limit: 100 +-- test order of firing of FK triggers when several RI-induced changes need to +-- be made to the same row. This was broken by subtransaction-related +-- changes in 8.0. + +CREATE TEMP TABLE users ( + id INT PRIMARY KEY, + name VARCHAR NOT NULL +) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE users (id int PRIMARY KEY, name varchar NOT NULL)" +== 429 +-- truncate_limit: 100 +INSERT INTO users VALUES (1, 'Jozko') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users VALUES (1, 'Jozko')" +== 430 +-- truncate_limit: 100 +INSERT INTO users VALUES (2, 'Ferko') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users VALUES (2, 'Ferko')" +== 431 +-- truncate_limit: 100 +INSERT INTO users VALUES (3, 'Samko') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users VALUES (3, 'Samko')" +== 432 +-- truncate_limit: 100 +CREATE TEMP TABLE tasks ( + id INT PRIMARY KEY, + owner INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, + worker INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, + checked_by INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL +) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tasks (id int PRIMARY KEY, owner int REFERENCES users ON UPDATE CASCADE ON..." +== 433 +-- truncate_limit: 100 +INSERT INTO tasks VALUES (1,1,NULL,NULL) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tasks VALUES (1, 1, NULL, NULL)" +== 434 +-- truncate_limit: 100 +INSERT INTO tasks VALUES (2,2,2,NULL) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tasks VALUES (2, 2, 2, NULL)" +== 435 +-- truncate_limit: 100 +INSERT INTO tasks VALUES (3,3,3,3) +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tasks VALUES (3, 3, 3, 3)" +== 436 +-- truncate_limit: 100 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tasks" +== 437 +-- truncate_limit: 100 +UPDATE users SET id = 4 WHERE id = 3 +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE users SET id = 4 WHERE id = 3" +== 438 +-- truncate_limit: 100 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tasks" +== 439 +-- truncate_limit: 100 +DELETE FROM users WHERE id = 4 +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM users WHERE id = 4" +== 440 +-- truncate_limit: 100 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tasks" +== 441 +-- truncate_limit: 100 +-- could fail with only 2 changes to make, if row was already updated +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 442 +-- truncate_limit: 100 +UPDATE tasks set id=id WHERE id=2 +-- +TABLE: name="tasks" schema="" table="tasks" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tasks SET id = id WHERE id = 2" +== 443 +-- truncate_limit: 100 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tasks" +== 444 +-- truncate_limit: 100 +DELETE FROM users WHERE id = 2 +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM users WHERE id = 2" +== 445 +-- truncate_limit: 100 +SELECT * FROM tasks +-- +TABLE: name="tasks" schema="" table="tasks" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tasks" +== 446 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 447 +-- truncate_limit: 100 +|-- +-- Test self-referential FK with CASCADE (bug #6268) +|-- +create temp table selfref ( + a int primary key, + b int, + foreign key (b) references selfref (a) + on update cascade on delete cascade +) +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE selfref (a int PRIMARY KEY, b int, FOREIGN KEY (b) REFERENCES selfref (a) ..." +== 448 +-- truncate_limit: 100 +insert into selfref (a, b) +values + (0, 0), + (1, 1) +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selfref (a, b) VALUES (0, 0), (1, 1)" +== 449 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 450 +-- truncate_limit: 100 +update selfref set a = 123 where a = 0 +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE selfref SET a = 123 WHERE a = 0" +== 451 +-- truncate_limit: 100 +select a, b from selfref +-- +TABLE: name="selfref" schema="" table="selfref" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM selfref" +== 452 +-- truncate_limit: 100 +update selfref set a = 456 where a = 123 +-- +TABLE: name="selfref" schema="" table="selfref" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE selfref SET a = 456 WHERE a = 123" +== 453 +-- truncate_limit: 100 +select a, b from selfref +-- +TABLE: name="selfref" schema="" table="selfref" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM selfref" +== 454 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 455 +-- truncate_limit: 100 +|-- +-- Test that SET DEFAULT actions recognize updates to default values +|-- +create temp table defp (f1 int primary key) +-- +TABLE: name="defp" schema="" table="defp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE defp (f1 int PRIMARY KEY)" +== 456 +-- truncate_limit: 100 +create temp table defc (f1 int default 0 + references defp on delete set default) +-- +TABLE: name="defc" schema="" table="defc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE defc (f1 int DEFAULT 0 REFERENCES defp ON DELETE SET DEFAULT)" +== 457 +-- truncate_limit: 100 +insert into defp values (0), (1), (2) +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defp VALUES (0), (1), (2)" +== 458 +-- truncate_limit: 100 +insert into defc values (2) +-- +TABLE: name="defc" schema="" table="defc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO defc VALUES (2)" +== 459 +-- truncate_limit: 100 +select * from defc +-- +TABLE: name="defc" schema="" table="defc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM defc" +== 460 +-- truncate_limit: 100 +delete from defp where f1 = 2 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM defp WHERE f1 = 2" +== 461 +-- truncate_limit: 100 +select * from defc +-- +TABLE: name="defc" schema="" table="defc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM defc" +== 462 +-- truncate_limit: 100 +delete from defp where f1 = 0 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM defp WHERE f1 = 0" +== 463 +-- truncate_limit: 100 +-- fail +alter table defc alter column f1 set default 1 +-- +TABLE: name="defc" schema="" table="defc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE defc ALTER COLUMN f1 SET DEFAULT 1" +== 464 +-- truncate_limit: 100 +delete from defp where f1 = 0 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM defp WHERE f1 = 0" +== 465 +-- truncate_limit: 100 +select * from defc +-- +TABLE: name="defc" schema="" table="defc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM defc" +== 466 +-- truncate_limit: 100 +delete from defp where f1 = 1 +-- +TABLE: name="defp" schema="" table="defp" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM defp WHERE f1 = 1" +== 467 +-- truncate_limit: 100 +-- fail + +|-- +-- Test the difference between NO ACTION and RESTRICT +|-- +create temp table pp (f1 int primary key) +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pp (f1 int PRIMARY KEY)" +== 468 +-- truncate_limit: 100 +create temp table cc (f1 int references pp on update no action on delete no action) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE cc (f1 int REFERENCES pp)" +== 469 +-- truncate_limit: 100 +insert into pp values(12) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pp VALUES (12)" +== 470 +-- truncate_limit: 100 +insert into pp values(11) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pp VALUES (11)" +== 471 +-- truncate_limit: 100 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pp SET f1 = f1 + 1" +== 472 +-- truncate_limit: 100 +insert into cc values(13) +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cc VALUES (13)" +== 473 +-- truncate_limit: 100 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pp SET f1 = f1 + 1" +== 474 +-- truncate_limit: 100 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pp SET f1 = f1 + 1" +== 475 +-- truncate_limit: 100 +-- fail +delete from pp where f1 = 13 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pp WHERE f1 = 13" +== 476 +-- truncate_limit: 100 +-- fail +drop table pp, cc +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp, cc" +== 477 +-- truncate_limit: 100 +create temp table pp (f1 int primary key) +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pp (f1 int PRIMARY KEY)" +== 478 +-- truncate_limit: 100 +create temp table cc (f1 int references pp on update restrict on delete restrict) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE cc (f1 int REFERENCES pp ON UPDATE RESTRICT ON DELETE RESTRICT)" +== 479 +-- truncate_limit: 100 +insert into pp values(12) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pp VALUES (12)" +== 480 +-- truncate_limit: 100 +insert into pp values(11) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pp VALUES (11)" +== 481 +-- truncate_limit: 100 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pp SET f1 = f1 + 1" +== 482 +-- truncate_limit: 100 +insert into cc values(13) +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cc VALUES (13)" +== 483 +-- truncate_limit: 100 +update pp set f1=f1+1 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pp SET f1 = f1 + 1" +== 484 +-- truncate_limit: 100 +-- fail +delete from pp where f1 = 13 +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pp WHERE f1 = 13" +== 485 +-- truncate_limit: 100 +-- fail +drop table pp, cc +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp, cc" +== 486 +-- truncate_limit: 100 +|-- +-- Test interaction of foreign-key optimization with rules (bug #14219) +|-- +create temp table t1 (a integer primary key, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (a int PRIMARY KEY, b text)" +== 487 +-- truncate_limit: 100 +create temp table t2 (a integer primary key, b integer references t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t2 (a int PRIMARY KEY, b int REFERENCES t1)" +== 488 +-- truncate_limit: 100 +create rule r1 as on delete to t1 do delete from t2 where t2.b = old.a +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r1 AS ON DELETE TO t1 DO DELETE FROM t2 WHERE t2.b = old.a" +== 489 +-- truncate_limit: 100 +explain (costs off) delete from t1 where a = 1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE a = 1" +== 490 +-- truncate_limit: 100 +delete from t1 where a = 1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t1 WHERE a = 1" +== 491 +-- truncate_limit: 100 +-- Test a primary key with attributes located in later attnum positions +-- compared to the fk attributes. +create table pktable2 (a int, b int, c int, d int, e int, primary key (d, e)) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable2 (a int, b int, c int, d int, e int, PRIMARY KEY (d, e))" +== 492 +-- truncate_limit: 100 +create table fktable2 (d int, e int, foreign key (d, e) references pktable2) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable2 (d int, e int, FOREIGN KEY (d, e) REFERENCES pktable2)" +== 493 +-- truncate_limit: 100 +insert into pktable2 values (1, 2, 3, 4, 5) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable2 VALUES (1, 2, 3, 4, 5)" +== 494 +-- truncate_limit: 100 +insert into fktable2 values (4, 5) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable2 VALUES (4, 5)" +== 495 +-- truncate_limit: 100 +delete from pktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable2" +== 496 +-- truncate_limit: 100 +update pktable2 set d = 5 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable2 SET d = 5" +== 497 +-- truncate_limit: 100 +drop table pktable2, fktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable2, fktable2" +== 498 +-- truncate_limit: 100 +-- Test truncation of long foreign key names +create table pktable1 (a int primary key) +-- +TABLE: name="pktable1" schema="" table="pktable1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable1 (a int PRIMARY KEY)" +== 499 +-- truncate_limit: 100 +create table pktable2 (a int, b int, primary key (a, b)) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable2 (a int, b int, PRIMARY KEY (a, b))" +== 500 +-- truncate_limit: 100 +create table fktable2 ( + a int, + b int, + very_very_long_column_name_to_exceed_63_characters int, + foreign key (very_very_long_column_name_to_exceed_63_characters) references pktable1, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2 +) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable2 (a int, b int, very_very_long_column_name_to_exceed_63_characters int, FORE..." +== 501 +-- truncate_limit: 100 +select conname from pg_constraint where conrelid = 'fktable2'::regclass order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT conname FROM pg_constraint WHERE conrelid = 'fktable2'::regclass ORDER BY conname" +== 502 +-- truncate_limit: 100 +drop table pktable1, pktable2, fktable2 +-- +TABLE: name="pktable1" schema="" table="pktable1" ctx=DDL +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable1, pktable2, fktable2" +== 503 +-- truncate_limit: 100 +|-- +-- Test deferred FK check on a tuple deleted by a rolled-back subtransaction +|-- +create table pktable2(f1 int primary key) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable2 (f1 int PRIMARY KEY)" +== 504 +-- truncate_limit: 100 +create table fktable2(f1 int references pktable2 deferrable initially deferred) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable2 (f1 int REFERENCES pktable2 DEFERRABLE INITIALLY DEFERRED)" +== 505 +-- truncate_limit: 100 +insert into pktable2 values(1) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable2 VALUES (1)" +== 506 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 507 +-- truncate_limit: 100 +insert into fktable2 values(1) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable2 VALUES (1)" +== 508 +-- truncate_limit: 100 +savepoint x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 509 +-- truncate_limit: 100 +delete from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fktable2" +== 510 +-- truncate_limit: 100 +rollback to x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 511 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 512 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 513 +-- truncate_limit: 100 +insert into fktable2 values(2) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable2 VALUES (2)" +== 514 +-- truncate_limit: 100 +savepoint x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 515 +-- truncate_limit: 100 +delete from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fktable2" +== 516 +-- truncate_limit: 100 +rollback to x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 517 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 518 +-- truncate_limit: 100 +-- fail + +|-- +-- Test that we prevent dropping FK constraint with pending trigger events +|-- +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 519 +-- truncate_limit: 100 +insert into fktable2 values(2) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable2 VALUES (2)" +== 520 +-- truncate_limit: 100 +alter table fktable2 drop constraint fktable2_f1_fkey +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable2 DROP CONSTRAINT fktable2_f1_fkey" +== 521 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 522 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 523 +-- truncate_limit: 100 +delete from pktable2 where f1 = 1 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pktable2 WHERE f1 = 1" +== 524 +-- truncate_limit: 100 +alter table fktable2 drop constraint fktable2_f1_fkey +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fktable2 DROP CONSTRAINT fktable2_f1_fkey" +== 525 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 526 +-- truncate_limit: 100 +drop table pktable2, fktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable2, fktable2" +== 527 +-- truncate_limit: 100 +|-- +-- Test keys that "look" different but compare as equal +|-- +create table pktable2 (a float8, b float8, primary key (a, b)) +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pktable2 (a float8, b float8, PRIMARY KEY (a, b))" +== 528 +-- truncate_limit: 100 +create table fktable2 (x float8, y float8, foreign key (x, y) references pktable2 (a, b) on update cascade) +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fktable2 (x float8, y float8, FOREIGN KEY (x, y) REFERENCES pktable2 (a, b) ON UPDAT..." +== 529 +-- truncate_limit: 100 +insert into pktable2 values ('-0', '-0') +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pktable2 VALUES ('-0', '-0')" +== 530 +-- truncate_limit: 100 +insert into fktable2 values ('-0', '-0') +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fktable2 VALUES ('-0', '-0')" +== 531 +-- truncate_limit: 100 +select * from pktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable2" +== 532 +-- truncate_limit: 100 +select * from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable2" +== 533 +-- truncate_limit: 100 +update pktable2 set a = '0' where a = '-0' +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pktable2 SET a = '0' WHERE a = '-0'" +== 534 +-- truncate_limit: 100 +select * from pktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pktable2" +== 535 +-- truncate_limit: 100 +-- should have updated fktable2.x +select * from fktable2 +-- +TABLE: name="fktable2" schema="" table="fktable2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fktable2" +== 536 +-- truncate_limit: 100 +drop table pktable2, fktable2 +-- +TABLE: name="pktable2" schema="" table="pktable2" ctx=DDL +TABLE: name="fktable2" schema="" table="fktable2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pktable2, fktable2" +== 537 +-- truncate_limit: 100 +|-- +-- Foreign keys and partitioned tables +|-- + +-- Creation of a partitioned hierarchy with irregular definitions +CREATE TABLE fk_notpartitioned_pk (fdrop1 int, a int, fdrop2 int, b int, + PRIMARY KEY (a, b)) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_notpartitioned_pk (fdrop1 int, a int, fdrop2 int, b int, PRIMARY KEY (a, b))" +== 538 +-- truncate_limit: 100 +ALTER TABLE fk_notpartitioned_pk DROP COLUMN fdrop1, DROP COLUMN fdrop2 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_notpartitioned_pk DROP fdrop1, DROP fdrop2" +== 539 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk (b int, fdrop1 int, a int) PARTITION BY RANGE (a, b) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk (b int, fdrop1 int, a int) PARTITION BY RANGE (a, b)" +== 540 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk DROP COLUMN fdrop1 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DROP fdrop1" +== 541 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_1 (fdrop1 int, fdrop2 int, a int, fdrop3 int, b int) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_1 (fdrop1 int, fdrop2 int, a int, fdrop3 int, b int)" +== 542 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_1 DROP COLUMN fdrop1, DROP COLUMN fdrop2, DROP COLUMN fdrop3 +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_1 DROP fdrop1, DROP fdrop2, DROP fdrop3" +== 543 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR VALUES FROM (0,0) TO (1000,1000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR VALUES FROM (0, 0) TO (100..." +== 544 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk" +== 545 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_2 (b int, fdrop1 int, fdrop2 int, a int) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_2 (b int, fdrop1 int, fdrop2 int, a int)" +== 546 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN fdrop1, DROP COLUMN fdrop2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_2 DROP fdrop1, DROP fdrop2" +== 547 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FROM (1000,1000) TO (2000,2000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FROM (1000, 1000) T..." +== 548 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_3 (fdrop1 int, fdrop2 int, fdrop3 int, fdrop4 int, b int, a int) + PARTITION BY HASH (a) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_3 (fdrop1 int, fdrop2 int, fdrop3 int, fdrop4 int, b int, a int) P..." +== 549 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_3 DROP COLUMN fdrop1, DROP COLUMN fdrop2, + DROP COLUMN fdrop3, DROP COLUMN fdrop4 +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_3 DROP fdrop1, DROP fdrop2, DROP fdrop3, DROP fdrop4" +== 550 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_3_0 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, REMAINDER 0) +-- +TABLE: name="fk_partitioned_fk_3_0" schema="" table="fk_partitioned_fk_3_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_3_0 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, R..." +== 551 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_3_1 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, REMAINDER 1) +-- +TABLE: name="fk_partitioned_fk_3_1" schema="" table="fk_partitioned_fk_3_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_3_1 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, R..." +== 552 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 + FOR VALUES FROM (2000,2000) TO (3000,3000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES FROM (2000, 2000) T..." +== 553 +-- truncate_limit: 100 +-- Creating a foreign key with ONLY on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE ONLY fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk" +== 554 +-- truncate_limit: 100 +-- Adding a NOT VALID foreign key on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk NOT VALID +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk NOT VALID" +== 555 +-- truncate_limit: 100 +-- these inserts, targeting both the partition directly as well as the +-- partitioned table, should all fail +INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (500, 501)" +== 556 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_1 (a,b) VALUES (500, 501) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_1 (a, b) VALUES (500, 501)" +== 557 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk (a,b) VALUES (1500, 1501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (1500, 1501)" +== 558 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_2 (a,b) VALUES (1500, 1501) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_2 (a, b) VALUES (1500, 1501)" +== 559 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (2500, 2502)" +== 560 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2500, 2502) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2500, 2502)" +== 561 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (2501, 2503)" +== 562 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2501, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2501, 2503)" +== 563 +-- truncate_limit: 100 +-- but if we insert the values that make them valid, then they work +INSERT INTO fk_notpartitioned_pk VALUES (500, 501), (1500, 1501), + (2500, 2502), (2501, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (500, 501), (1500, 1501), (2500, 2502), (2501, 2503)" +== 564 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (500, 501)" +== 565 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk (a,b) VALUES (1500, 1501) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (1500, 1501)" +== 566 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (2500, 2502)" +== 567 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (2501, 2503)" +== 568 +-- truncate_limit: 100 +-- this update fails because there is no referenced row +UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501" +== 569 +-- truncate_limit: 100 +-- but we can fix it thusly: +INSERT INTO fk_notpartitioned_pk (a,b) VALUES (2502, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk (a, b) VALUES (2502, 2503)" +== 570 +-- truncate_limit: 100 +UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501" +== 571 +-- truncate_limit: 100 +-- these updates would leave lingering rows in the referencing table; disallow +UPDATE fk_notpartitioned_pk SET b = 502 WHERE a = 500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_notpartitioned_pk SET b = 502 WHERE a = 500" +== 572 +-- truncate_limit: 100 +UPDATE fk_notpartitioned_pk SET b = 1502 WHERE a = 1500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_notpartitioned_pk SET b = 1502 WHERE a = 1500" +== 573 +-- truncate_limit: 100 +UPDATE fk_notpartitioned_pk SET b = 2504 WHERE a = 2500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_notpartitioned_pk SET b = 2504 WHERE a = 2500" +== 574 +-- truncate_limit: 100 +-- check psql behavior +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey" +== 575 +-- truncate_limit: 100 +-- done. +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk" +== 576 +-- truncate_limit: 100 +-- Altering a type referenced by a foreign key needs to drop/recreate the FK. +-- Ensure that works. +CREATE TABLE fk_notpartitioned_pk (a INT, PRIMARY KEY(a), CHECK (a > 0)) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_notpartitioned_pk (a int, PRIMARY KEY (a), CHECK (a > 0))" +== 577 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk (a INT REFERENCES fk_notpartitioned_pk(a) PRIMARY KEY) PARTITION BY RANGE(a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk (a int REFERENCES fk_notpartitioned_pk (a) PRIMARY KEY) PARTITION ..." +== 578 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES FROM (MINVALUE) TO (MAXVALUE) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES FROM (minvalue) TO (ma..." +== 579 +-- truncate_limit: 100 +INSERT INTO fk_notpartitioned_pk VALUES (1) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (1)" +== 580 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk VALUES (1) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk VALUES (1)" +== 581 +-- truncate_limit: 100 +ALTER TABLE fk_notpartitioned_pk ALTER COLUMN a TYPE bigint +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_notpartitioned_pk ALTER COLUMN a TYPE bigint" +== 582 +-- truncate_limit: 100 +DELETE FROM fk_notpartitioned_pk WHERE a = 1 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_notpartitioned_pk WHERE a = 1" +== 583 +-- truncate_limit: 100 +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk" +== 584 +-- truncate_limit: 100 +-- Test some other exotic foreign key features: MATCH SIMPLE, ON UPDATE/DELETE +-- actions +CREATE TABLE fk_notpartitioned_pk (a int, b int, primary key (a, b)) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_notpartitioned_pk (a int, b int, PRIMARY KEY (a, b))" +== 585 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk (a int default 2501, b int default 142857) PARTITION BY LIST (a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk (a int DEFAULT 2501, b int DEFAULT 142857) PARTITION BY LIST (a)" +== 586 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES IN (NULL,500,501,502) +-- +TABLE: name="fk_partitioned_fk_1" schema="" table="fk_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES IN (NULL, 500, 501, 502)" +== 587 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk MATCH SIMPLE + ON DELETE SET NULL ON UPDATE SET NULL +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE SE..." +== 588 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500, 1502)" +== 589 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_3 (a int, b int) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_3 (a int, b int)" +== 590 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES IN (2500,2501,2502,2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES IN (2500, 2501, 250..." +== 591 +-- truncate_limit: 100 +-- this insert fails +INSERT INTO fk_partitioned_fk (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (2502, 2503)" +== 592 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503)" +== 593 +-- truncate_limit: 100 +-- but since the FK is MATCH SIMPLE, this one doesn't +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, NULL) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, NULL)" +== 594 +-- truncate_limit: 100 +-- now create the referenced row ... +INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503)" +== 595 +-- truncate_limit: 100 +--- and now the same insert work +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503)" +== 596 +-- truncate_limit: 100 +-- this always works +INSERT INTO fk_partitioned_fk (a,b) VALUES (NULL, NULL) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk (a, b) VALUES (NULL, NULL)" +== 597 +-- truncate_limit: 100 +-- MATCH FULL +INSERT INTO fk_notpartitioned_pk VALUES (1, 2) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (1, 2)" +== 598 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_full (x int, y int) PARTITION BY RANGE (x) +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_full (x int, y int) PARTITION BY RANGE (x)" +== 599 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_full_1 PARTITION OF fk_partitioned_fk_full DEFAULT +-- +TABLE: name="fk_partitioned_fk_full_1" schema="" table="fk_partitioned_fk_full_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_full_1 PARTITION OF fk_partitioned_fk_full DEFAULT" +== 600 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL) +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_full VALUES (1, NULL)" +== 601 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL" +== 602 +-- truncate_limit: 100 +-- fails +TRUNCATE fk_partitioned_fk_full +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE fk_partitioned_fk_full" +== 603 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL" +== 604 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL) +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_full VALUES (1, NULL)" +== 605 +-- truncate_limit: 100 +-- fails +DROP TABLE fk_partitioned_fk_full +-- +TABLE: name="fk_partitioned_fk_full" schema="" table="fk_partitioned_fk_full" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_partitioned_fk_full" +== 606 +-- truncate_limit: 100 +-- ON UPDATE SET NULL +SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a" +== 607 +-- truncate_limit: 100 +UPDATE fk_notpartitioned_pk SET a = a + 1 WHERE a = 2502 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_notpartitioned_pk SET a = a + 1 WHERE a = 2502" +== 608 +-- truncate_limit: 100 +SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a" +== 609 +-- truncate_limit: 100 +-- ON DELETE SET NULL +INSERT INTO fk_partitioned_fk VALUES (2503, 2503) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk VALUES (2503, 2503)" +== 610 +-- truncate_limit: 100 +SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL" +== 611 +-- truncate_limit: 100 +DELETE FROM fk_notpartitioned_pk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_notpartitioned_pk" +== 612 +-- truncate_limit: 100 +SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL" +== 613 +-- truncate_limit: 100 +-- ON UPDATE/DELETE SET DEFAULT +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey" +== 614 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET DEFAULT ON UPDATE SET DEFAULT +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE SE..." +== 615 +-- truncate_limit: 100 +INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503)" +== 616 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503) +-- +TABLE: name="fk_partitioned_fk_3" schema="" table="fk_partitioned_fk_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503)" +== 617 +-- truncate_limit: 100 +-- this fails, because the defaults for the referencing table are not present +-- in the referenced table: +UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502" +== 618 +-- truncate_limit: 100 +-- but inserting the row we can make it work: +INSERT INTO fk_notpartitioned_pk VALUES (2501, 142857) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (2501, 142857)" +== 619 +-- truncate_limit: 100 +UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502" +== 620 +-- truncate_limit: 100 +SELECT * FROM fk_partitioned_fk WHERE b = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fk_partitioned_fk WHERE b = 142857" +== 621 +-- truncate_limit: 100 +-- ON DELETE SET NULL column_list +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey" +== 622 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET NULL (a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON DELETE SE..." +== 623 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 624 +-- truncate_limit: 100 +DELETE FROM fk_notpartitioned_pk WHERE b = 142857 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_notpartitioned_pk WHERE b = 142857" +== 625 +-- truncate_limit: 100 +SELECT * FROM fk_partitioned_fk WHERE a IS NOT NULL OR b IS NOT NULL ORDER BY a NULLS LAST +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fk_partitioned_fk WHERE a IS NOT NULL OR b IS NOT NULL ORDER BY a NULLS LAST" +== 626 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 627 +-- truncate_limit: 100 +-- ON DELETE SET DEFAULT column_list +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey" +== 628 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET DEFAULT (a) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON DELETE SE..." +== 629 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 630 +-- truncate_limit: 100 +DELETE FROM fk_partitioned_fk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_partitioned_fk" +== 631 +-- truncate_limit: 100 +DELETE FROM fk_notpartitioned_pk +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_notpartitioned_pk" +== 632 +-- truncate_limit: 100 +INSERT INTO fk_notpartitioned_pk VALUES (500, 100000), (2501, 100000) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (500, 100000), (2501, 100000)" +== 633 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk VALUES (500, 100000) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk VALUES (500, 100000)" +== 634 +-- truncate_limit: 100 +DELETE FROM fk_notpartitioned_pk WHERE a = 500 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_notpartitioned_pk WHERE a = 500" +== 635 +-- truncate_limit: 100 +SELECT * FROM fk_partitioned_fk ORDER BY a +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fk_partitioned_fk ORDER BY a" +== 636 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 637 +-- truncate_limit: 100 +-- ON UPDATE/DELETE CASCADE +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey" +== 638 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE CASCADE ON UPDATE CASCADE +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE CA..." +== 639 +-- truncate_limit: 100 +UPDATE fk_notpartitioned_pk SET a = 2502 WHERE a = 2501 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fk_notpartitioned_pk SET a = 2502 WHERE a = 2501" +== 640 +-- truncate_limit: 100 +SELECT * FROM fk_partitioned_fk WHERE b = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fk_partitioned_fk WHERE b = 142857" +== 641 +-- truncate_limit: 100 +-- Now you see it ... +SELECT * FROM fk_partitioned_fk WHERE b = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fk_partitioned_fk WHERE b = 142857" +== 642 +-- truncate_limit: 100 +DELETE FROM fk_notpartitioned_pk WHERE b = 142857 +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_notpartitioned_pk WHERE b = 142857" +== 643 +-- truncate_limit: 100 +-- now you don't. +SELECT * FROM fk_partitioned_fk WHERE a = 142857 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fk_partitioned_fk WHERE a = 142857" +== 644 +-- truncate_limit: 100 +-- verify that DROP works +DROP TABLE fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_partitioned_fk_2" +== 645 +-- truncate_limit: 100 +-- Test behavior of the constraint together with attaching and detaching +-- partitions. +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500, 1502)" +== 646 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_2" +== 647 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 648 +-- truncate_limit: 100 +DROP TABLE fk_partitioned_fk +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_partitioned_fk" +== 649 +-- truncate_limit: 100 +-- constraint should still be there +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 650 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500, 1502)" +== 651 +-- truncate_limit: 100 +DROP TABLE fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_partitioned_fk_2" +== 652 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_2 (b int, c text, a int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE CASCADE ON DELETE CASCADE) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_2 (b int, c text, a int, FOREIGN KEY (a, b) REFERENCES fk_notparti..." +== 653 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN c +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_2 DROP c" +== 654 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500, 1502)" +== 655 +-- truncate_limit: 100 +-- should have only one constraint +DROP TABLE fk_partitioned_fk_2 +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_partitioned_fk_2" +== 656 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_4 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE) PARTITION BY RANGE (b, a) +-- +TABLE: name="fk_partitioned_fk_4" schema="" table="fk_partitioned_fk_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_4 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_p..." +== 657 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_4_1 PARTITION OF fk_partitioned_fk_4 FOR VALUES FROM (1,1) TO (100,100) +-- +TABLE: name="fk_partitioned_fk_4_1" schema="" table="fk_partitioned_fk_4_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_4_1 PARTITION OF fk_partitioned_fk_4 FOR VALUES FROM (1, 1) TO (10..." +== 658 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_4_2 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE SET NULL) +-- +TABLE: name="fk_partitioned_fk_4_2" schema="" table="fk_partitioned_fk_4_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_4_2 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned..." +== 659 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_4 ATTACH PARTITION fk_partitioned_fk_4_2 FOR VALUES FROM (100,100) TO (1000,1000) +-- +TABLE: name="fk_partitioned_fk_4" schema="" table="fk_partitioned_fk_4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_4 ATTACH PARTITION fk_partitioned_fk_4_2 FOR VALUES FROM (100, 100)..." +== 660 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500, 3502)" +== 661 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_4 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_4" +== 662 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500, 3502)" +== 663 +-- truncate_limit: 100 +-- should only have one constraint +-- this one has an FK with mismatched properties + +CREATE TABLE fk_partitioned_fk_5 (a int, b int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE) + PARTITION BY RANGE (a) +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_5 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_p..." +== 664 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_5_1 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk) +-- +TABLE: name="fk_partitioned_fk_5_1" schema="" table="fk_partitioned_fk_5_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_5_1 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned..." +== 665 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500)" +== 666 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10)" +== 667 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_5 +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_5" +== 668 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500)" +== 669 +-- truncate_limit: 100 +-- this one has two constraints, similar but not quite the one in the parent, +-- so it gets a new one +-- verify that it works to reattaching a child with multiple candidate +-- constraints +ALTER TABLE fk_partitioned_fk_5 DETACH PARTITION fk_partitioned_fk_5_1 +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_5 DETACH PARTITION fk_partitioned_fk_5_1" +== 670 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="fk_partitioned_fk_5" schema="" table="fk_partitioned_fk_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10)" +== 671 +-- truncate_limit: 100 +-- verify that attaching a table checks that the existing data satisfies the +-- constraint +CREATE TABLE fk_partitioned_fk_2 (a int, b int) PARTITION BY RANGE (b) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_2 (a int, b int) PARTITION BY RANGE (b)" +== 672 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_2_1 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="fk_partitioned_fk_2_1" schema="" table="fk_partitioned_fk_2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_2_1 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (0) TO (1000)" +== 673 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_2_2 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="fk_partitioned_fk_2_2" schema="" table="fk_partitioned_fk_2_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_2_2 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (1000) TO (2000)" +== 674 +-- truncate_limit: 100 +INSERT INTO fk_partitioned_fk_2 VALUES (1600, 601), (1600, 1601) +-- +TABLE: name="fk_partitioned_fk_2" schema="" table="fk_partitioned_fk_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_partitioned_fk_2 VALUES (1600, 601), (1600, 1601)" +== 675 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 + FOR VALUES IN (1600) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1600)" +== 676 +-- truncate_limit: 100 +INSERT INTO fk_notpartitioned_pk VALUES (1600, 601), (1600, 1601) +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk VALUES (1600, 601), (1600, 1601)" +== 677 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 + FOR VALUES IN (1600) +-- +TABLE: name="fk_partitioned_fk" schema="" table="fk_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1600)" +== 678 +-- truncate_limit: 100 +-- leave these tables around intentionally + +-- Verify that attaching a table that's referenced by an existing FK +-- in the parent throws an error +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY)" +== 679 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITION BY LIST (a) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITION BY LIST (a)" +== 680 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1)" +== 681 +-- truncate_limit: 100 +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6 +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6" +== 682 +-- truncate_limit: 100 +-- This case is similar to above, but the referenced relation is one level +-- lower in the hierarchy. This one fails in a different way as the above, +-- because we don't bother to protect against this case explicitly. If the +-- current error stops happening, we'll need to add a better protection. +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) PARTITION BY list (a) +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) PARTITION BY LIST (a)" +== 683 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_pk_61 PARTITION OF fk_partitioned_pk_6 FOR VALUES IN (1) +-- +TABLE: name="fk_partitioned_pk_61" schema="" table="fk_partitioned_pk_61" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_pk_61 PARTITION OF fk_partitioned_pk_6 FOR VALUES IN (1)" +== 684 +-- truncate_limit: 100 +CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_61) PARTITION BY LIST (a) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_61) PARTITION BY LIST (a)" +== 685 +-- truncate_limit: 100 +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1) +-- +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1)" +== 686 +-- truncate_limit: 100 +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6 +-- +TABLE: name="fk_partitioned_pk_6" schema="" table="fk_partitioned_pk_6" ctx=DDL +TABLE: name="fk_partitioned_fk_6" schema="" table="fk_partitioned_fk_6" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6" +== 687 +-- truncate_limit: 100 +-- test the case when the referenced table is owned by a different user +create role regress_other_partitioned_fk_owner +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_other_partitioned_fk_owner" +== 688 +-- truncate_limit: 100 +grant references on fk_notpartitioned_pk to regress_other_partitioned_fk_owner +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT references ON fk_notpartitioned_pk TO regress_other_partitioned_fk_owner" +== 689 +-- truncate_limit: 100 +set role regress_other_partitioned_fk_owner +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_other_partitioned_fk_owner" +== 690 +-- truncate_limit: 100 +create table other_partitioned_fk(a int, b int) partition by list (a) +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE other_partitioned_fk (a int, b int) PARTITION BY LIST (a)" +== 691 +-- truncate_limit: 100 +create table other_partitioned_fk_1 partition of other_partitioned_fk + for values in (2048) +-- +TABLE: name="other_partitioned_fk_1" schema="" table="other_partitioned_fk_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE other_partitioned_fk_1 PARTITION OF other_partitioned_fk FOR VALUES IN (2048)" +== 692 +-- truncate_limit: 100 +insert into other_partitioned_fk + select 2048, x from generate_series(1,10) x +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO other_partitioned_fk SELECT 2048, x FROM generate_series(1, 10) x" +== 693 +-- truncate_limit: 100 +-- this should fail +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b) +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE other_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk (a, b)" +== 694 +-- truncate_limit: 100 +-- add the missing keys and retry +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 695 +-- truncate_limit: 100 +insert into fk_notpartitioned_pk (a, b) + select 2048, x from generate_series(1,10) x +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_notpartitioned_pk (a, b) SELECT 2048, x FROM generate_series(1, 10) x" +== 696 +-- truncate_limit: 100 +set role regress_other_partitioned_fk_owner +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_other_partitioned_fk_owner" +== 697 +-- truncate_limit: 100 +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b) +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE other_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk (a, b)" +== 698 +-- truncate_limit: 100 +-- clean up +drop table other_partitioned_fk +-- +TABLE: name="other_partitioned_fk" schema="" table="other_partitioned_fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE other_partitioned_fk" +== 699 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 700 +-- truncate_limit: 100 +revoke all on fk_notpartitioned_pk from regress_other_partitioned_fk_owner +-- +TABLE: name="fk_notpartitioned_pk" schema="" table="fk_notpartitioned_pk" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON fk_notpartitioned_pk FROM regress_other_partitioned_fk_owner" +== 701 +-- truncate_limit: 100 +drop role regress_other_partitioned_fk_owner +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_other_partitioned_fk_owner" +== 702 +-- truncate_limit: 100 +|-- +-- Test self-referencing foreign key with partition. +-- This should create only one fk constraint per partition +|-- +CREATE TABLE parted_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint, + FOREIGN KEY (id_abc) REFERENCES parted_self_fk(id) +) +PARTITION BY RANGE (id) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_self_fk (id bigint NOT NULL PRIMARY KEY, id_abc bigint, FOREIGN KEY (id_abc) ..." +== 703 +-- truncate_limit: 100 +CREATE TABLE part1_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +) +-- +TABLE: name="part1_self_fk" schema="" table="part1_self_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part1_self_fk (id bigint NOT NULL PRIMARY KEY, id_abc bigint)" +== 704 +-- truncate_limit: 100 +ALTER TABLE parted_self_fk ATTACH PARTITION part1_self_fk FOR VALUES FROM (0) TO (10) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk ATTACH PARTITION part1_self_fk FOR VALUES FROM (0) TO (10)" +== 705 +-- truncate_limit: 100 +CREATE TABLE part2_self_fk PARTITION OF parted_self_fk FOR VALUES FROM (10) TO (20) +-- +TABLE: name="part2_self_fk" schema="" table="part2_self_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part2_self_fk PARTITION OF parted_self_fk FOR VALUES FROM (10) TO (20)" +== 706 +-- truncate_limit: 100 +CREATE TABLE part3_self_fk ( -- a partitioned partition + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +) PARTITION BY RANGE (id) +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part3_self_fk (id bigint NOT NULL PRIMARY KEY, id_abc bigint) PARTITION BY RANGE (id)" +== 707 +-- truncate_limit: 100 +CREATE TABLE part32_self_fk PARTITION OF part3_self_fk FOR VALUES FROM (20) TO (30) +-- +TABLE: name="part32_self_fk" schema="" table="part32_self_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part32_self_fk PARTITION OF part3_self_fk FOR VALUES FROM (20) TO (30)" +== 708 +-- truncate_limit: 100 +ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (20) TO (40) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (20) TO (40)" +== 709 +-- truncate_limit: 100 +CREATE TABLE part33_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +) +-- +TABLE: name="part33_self_fk" schema="" table="part33_self_fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part33_self_fk (id bigint NOT NULL PRIMARY KEY, id_abc bigint)" +== 710 +-- truncate_limit: 100 +ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40) +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40)" +== 711 +-- truncate_limit: 100 +-- verify that this constraint works +INSERT INTO parted_self_fk VALUES (1, NULL), (2, NULL), (3, NULL) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_self_fk VALUES (1, NULL), (2, NULL), (3, NULL)" +== 712 +-- truncate_limit: 100 +INSERT INTO parted_self_fk VALUES (10, 1), (11, 2), (12, 3) RETURNING tableoid::regclass +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_self_fk VALUES (10, 1), (11, 2), (12, 3) RETURNING tableoid::regclass" +== 713 +-- truncate_limit: 100 +INSERT INTO parted_self_fk VALUES (4, 5) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_self_fk VALUES (4, 5)" +== 714 +-- truncate_limit: 100 +-- error: referenced doesn't exist +DELETE FROM parted_self_fk WHERE id = 1 RETURNING * +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parted_self_fk WHERE id = 1 RETURNING *" +== 715 +-- truncate_limit: 100 +-- error: reference remains + +SELECT cr.relname, co.conname, co.convalidated, + p.conname AS conparent, p.convalidated, cf.relname AS foreignrel +FROM pg_constraint co +JOIN pg_class cr ON cr.oid = co.conrelid +LEFT JOIN pg_class cf ON cf.oid = co.confrelid +LEFT JOIN pg_constraint p ON p.oid = co.conparentid +WHERE co.contype = 'f' AND + cr.oid IN (SELECT relid FROM pg_partition_tree('parted_self_fk')) +ORDER BY cr.relname, co.conname, p.conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "cf"="pg_class" +ALIAS: "co"="pg_constraint" +ALIAS: "cr"="pg_class" +ALIAS: "p"="pg_constraint" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="co" column="contype" +FILTER: schema="" table="cr" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint co JOIN pg_class cr ON cr.oid = co.conrelid LEFT JOIN pg_class cf O..." +== 716 +-- truncate_limit: 100 +-- detach and re-attach multiple times just to ensure everything is kosher +ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk" +== 717 +-- truncate_limit: 100 +INSERT INTO part2_self_fk VALUES (16, 9) +-- +TABLE: name="part2_self_fk" schema="" table="part2_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part2_self_fk VALUES (16, 9)" +== 718 +-- truncate_limit: 100 +-- error: referenced doesn't exist +DELETE FROM parted_self_fk WHERE id = 2 RETURNING * +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parted_self_fk WHERE id = 2 RETURNING *" +== 719 +-- truncate_limit: 100 +-- error: reference remains + +ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20)" +== 720 +-- truncate_limit: 100 +INSERT INTO parted_self_fk VALUES (16, 9) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_self_fk VALUES (16, 9)" +== 721 +-- truncate_limit: 100 +-- error: referenced doesn't exist +DELETE FROM parted_self_fk WHERE id = 3 RETURNING * +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parted_self_fk WHERE id = 3 RETURNING *" +== 722 +-- truncate_limit: 100 +-- error: reference remains + +ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk" +== 723 +-- truncate_limit: 100 +ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20)" +== 724 +-- truncate_limit: 100 +ALTER TABLE parted_self_fk DETACH PARTITION part3_self_fk +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk DETACH PARTITION part3_self_fk" +== 725 +-- truncate_limit: 100 +ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (30) TO (40) +-- +TABLE: name="parted_self_fk" schema="" table="parted_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (30) TO (40)" +== 726 +-- truncate_limit: 100 +ALTER TABLE part3_self_fk DETACH PARTITION part33_self_fk +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part3_self_fk DETACH PARTITION part33_self_fk" +== 727 +-- truncate_limit: 100 +ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40) +-- +TABLE: name="part3_self_fk" schema="" table="part3_self_fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40)" +== 728 +-- truncate_limit: 100 +SELECT cr.relname, co.conname, co.convalidated, + p.conname AS conparent, p.convalidated, cf.relname AS foreignrel +FROM pg_constraint co +JOIN pg_class cr ON cr.oid = co.conrelid +LEFT JOIN pg_class cf ON cf.oid = co.confrelid +LEFT JOIN pg_constraint p ON p.oid = co.conparentid +WHERE co.contype = 'f' AND + cr.oid IN (SELECT relid FROM pg_partition_tree('parted_self_fk')) +ORDER BY cr.relname, co.conname, p.conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "cf"="pg_class" +ALIAS: "co"="pg_constraint" +ALIAS: "cr"="pg_class" +ALIAS: "p"="pg_constraint" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="co" column="contype" +FILTER: schema="" table="cr" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint co JOIN pg_class cr ON cr.oid = co.conrelid LEFT JOIN pg_class cf O..." +== 729 +-- truncate_limit: 100 +-- Leave this table around, for pg_upgrade/pg_dump tests + + +-- Test creating a constraint at the parent that already exists in partitions. +-- There should be no duplicated constraints, and attempts to drop the +-- constraint in partitions should raise appropriate errors. +create schema fkpart0 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (1) + create table fk_part_23 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (2, 3) + partition by list (a) + create table fk_part_23_2 partition of fk_part_23 for values in (2) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart0 CREATE TABLE pkey (a int PRIMARY KEY) CREATE TABLE fk_part (a int) PARTITIO..." +== 730 +-- truncate_limit: 100 +alter table fkpart0.fk_part add foreign key (a) references fkpart0.pkey +-- +TABLE: name="fkpart0.fk_part" schema="fkpart0" table="fk_part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart0.fk_part ADD FOREIGN KEY (a) REFERENCES fkpart0.pkey" +== 731 +-- truncate_limit: 100 +alter table fkpart0.fk_part_1 drop constraint fk_part_1_a_fkey +-- +TABLE: name="fkpart0.fk_part_1" schema="fkpart0" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart0.fk_part_1 DROP CONSTRAINT fk_part_1_a_fkey" +== 732 +-- truncate_limit: 100 +alter table fkpart0.fk_part_23 drop constraint fk_part_23_a_fkey +-- +TABLE: name="fkpart0.fk_part_23" schema="fkpart0" table="fk_part_23" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart0.fk_part_23 DROP CONSTRAINT fk_part_23_a_fkey" +== 733 +-- truncate_limit: 100 +alter table fkpart0.fk_part_23_2 drop constraint fk_part_23_a_fkey +-- +TABLE: name="fkpart0.fk_part_23_2" schema="fkpart0" table="fk_part_23_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart0.fk_part_23_2 DROP CONSTRAINT fk_part_23_a_fkey" +== 734 +-- truncate_limit: 100 +create table fkpart0.fk_part_4 partition of fkpart0.fk_part for values in (4) +-- +TABLE: name="fkpart0.fk_part_4" schema="fkpart0" table="fk_part_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart0.fk_part_4 PARTITION OF fkpart0.fk_part FOR VALUES IN (4)" +== 735 +-- truncate_limit: 100 +alter table fkpart0.fk_part_4 drop constraint fk_part_a_fkey +-- +TABLE: name="fkpart0.fk_part_4" schema="fkpart0" table="fk_part_4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart0.fk_part_4 DROP CONSTRAINT fk_part_a_fkey" +== 736 +-- truncate_limit: 100 +create table fkpart0.fk_part_56 partition of fkpart0.fk_part + for values in (5,6) partition by list (a) +-- +TABLE: name="fkpart0.fk_part_56" schema="fkpart0" table="fk_part_56" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart0.fk_part_56 PARTITION OF fkpart0.fk_part FOR VALUES IN (5, 6) PARTITION BY LI..." +== 737 +-- truncate_limit: 100 +create table fkpart0.fk_part_56_5 partition of fkpart0.fk_part_56 + for values in (5) +-- +TABLE: name="fkpart0.fk_part_56_5" schema="fkpart0" table="fk_part_56_5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart0.fk_part_56_5 PARTITION OF fkpart0.fk_part_56 FOR VALUES IN (5)" +== 738 +-- truncate_limit: 100 +alter table fkpart0.fk_part_56 drop constraint fk_part_a_fkey +-- +TABLE: name="fkpart0.fk_part_56" schema="fkpart0" table="fk_part_56" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart0.fk_part_56 DROP CONSTRAINT fk_part_a_fkey" +== 739 +-- truncate_limit: 100 +alter table fkpart0.fk_part_56_5 drop constraint fk_part_a_fkey +-- +TABLE: name="fkpart0.fk_part_56_5" schema="fkpart0" table="fk_part_56_5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart0.fk_part_56_5 DROP CONSTRAINT fk_part_a_fkey" +== 740 +-- truncate_limit: 100 +-- verify that attaching and detaching partitions maintains the right set of +-- triggers +create schema fkpart1 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part for values in (1) partition by list (a) + create table fk_part_1_1 partition of fk_part_1 for values in (1) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart1 CREATE TABLE pkey (a int PRIMARY KEY) CREATE TABLE fk_part (a int) PARTITIO..." +== 741 +-- truncate_limit: 100 +alter table fkpart1.fk_part add foreign key (a) references fkpart1.pkey +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart1.fk_part ADD FOREIGN KEY (a) REFERENCES fkpart1.pkey" +== 742 +-- truncate_limit: 100 +insert into fkpart1.fk_part values (1) +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart1.fk_part VALUES (1)" +== 743 +-- truncate_limit: 100 +-- should fail +insert into fkpart1.pkey values (1) +-- +TABLE: name="fkpart1.pkey" schema="fkpart1" table="pkey" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart1.pkey VALUES (1)" +== 744 +-- truncate_limit: 100 +insert into fkpart1.fk_part values (1) +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart1.fk_part VALUES (1)" +== 745 +-- truncate_limit: 100 +delete from fkpart1.pkey where a = 1 +-- +TABLE: name="fkpart1.pkey" schema="fkpart1" table="pkey" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart1.pkey WHERE a = 1" +== 746 +-- truncate_limit: 100 +-- should fail +alter table fkpart1.fk_part detach partition fkpart1.fk_part_1 +-- +TABLE: name="fkpart1.fk_part" schema="fkpart1" table="fk_part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart1.fk_part DETACH PARTITION fkpart1.fk_part_1" +== 747 +-- truncate_limit: 100 +create table fkpart1.fk_part_1_2 partition of fkpart1.fk_part_1 for values in (2) +-- +TABLE: name="fkpart1.fk_part_1_2" schema="fkpart1" table="fk_part_1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart1.fk_part_1_2 PARTITION OF fkpart1.fk_part_1 FOR VALUES IN (2)" +== 748 +-- truncate_limit: 100 +insert into fkpart1.fk_part_1 values (2) +-- +TABLE: name="fkpart1.fk_part_1" schema="fkpart1" table="fk_part_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart1.fk_part_1 VALUES (2)" +== 749 +-- truncate_limit: 100 +-- should fail +delete from fkpart1.pkey where a = 1 +-- +TABLE: name="fkpart1.pkey" schema="fkpart1" table="pkey" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart1.pkey WHERE a = 1" +== 750 +-- truncate_limit: 100 +-- verify that attaching and detaching partitions manipulates the inheritance +-- properties of their FK constraints correctly +create schema fkpart2 + create table pkey (a int primary key) + create table fk_part (a int, constraint fkey foreign key (a) references fkpart2.pkey) partition by list (a) + create table fk_part_1 partition of fkpart2.fk_part for values in (1) partition by list (a) + create table fk_part_1_1 (a int, constraint my_fkey foreign key (a) references fkpart2.pkey) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart2 CREATE TABLE pkey (a int PRIMARY KEY) CREATE TABLE fk_part (a int, CONSTRAI..." +== 751 +-- truncate_limit: 100 +alter table fkpart2.fk_part_1 attach partition fkpart2.fk_part_1_1 for values in (1) +-- +TABLE: name="fkpart2.fk_part_1" schema="fkpart2" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart2.fk_part_1 ATTACH PARTITION fkpart2.fk_part_1_1 FOR VALUES IN (1)" +== 752 +-- truncate_limit: 100 +alter table fkpart2.fk_part_1 drop constraint fkey +-- +TABLE: name="fkpart2.fk_part_1" schema="fkpart2" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart2.fk_part_1 DROP CONSTRAINT fkey" +== 753 +-- truncate_limit: 100 +-- should fail +alter table fkpart2.fk_part_1_1 drop constraint my_fkey +-- +TABLE: name="fkpart2.fk_part_1_1" schema="fkpart2" table="fk_part_1_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart2.fk_part_1_1 DROP CONSTRAINT my_fkey" +== 754 +-- truncate_limit: 100 +-- should fail +alter table fkpart2.fk_part detach partition fkpart2.fk_part_1 +-- +TABLE: name="fkpart2.fk_part" schema="fkpart2" table="fk_part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart2.fk_part DETACH PARTITION fkpart2.fk_part_1" +== 755 +-- truncate_limit: 100 +alter table fkpart2.fk_part_1 drop constraint fkey +-- +TABLE: name="fkpart2.fk_part_1" schema="fkpart2" table="fk_part_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart2.fk_part_1 DROP CONSTRAINT fkey" +== 756 +-- truncate_limit: 100 +-- ok +alter table fkpart2.fk_part_1_1 drop constraint my_fkey +-- +TABLE: name="fkpart2.fk_part_1_1" schema="fkpart2" table="fk_part_1_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart2.fk_part_1_1 DROP CONSTRAINT my_fkey" +== 757 +-- truncate_limit: 100 +-- doesn't exist + +-- verify constraint deferrability +create schema fkpart3 + create table pkey (a int primary key) + create table fk_part (a int, constraint fkey foreign key (a) references fkpart3.pkey deferrable initially immediate) partition by list (a) + create table fk_part_1 partition of fkpart3.fk_part for values in (1) partition by list (a) + create table fk_part_1_1 partition of fkpart3.fk_part_1 for values in (1) + create table fk_part_2 partition of fkpart3.fk_part for values in (2) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart3 CREATE TABLE pkey (a int PRIMARY KEY) CREATE TABLE fk_part (a int, CONSTRAI..." +== 758 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 759 +-- truncate_limit: 100 +set constraints fkpart3.fkey deferred +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS fkpart3.fkey DEFERRED" +== 760 +-- truncate_limit: 100 +insert into fkpart3.fk_part values (1) +-- +TABLE: name="fkpart3.fk_part" schema="fkpart3" table="fk_part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart3.fk_part VALUES (1)" +== 761 +-- truncate_limit: 100 +insert into fkpart3.pkey values (1) +-- +TABLE: name="fkpart3.pkey" schema="fkpart3" table="pkey" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart3.pkey VALUES (1)" +== 762 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 763 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 764 +-- truncate_limit: 100 +set constraints fkpart3.fkey deferred +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS fkpart3.fkey DEFERRED" +== 765 +-- truncate_limit: 100 +delete from fkpart3.pkey +-- +TABLE: name="fkpart3.pkey" schema="fkpart3" table="pkey" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart3.pkey" +== 766 +-- truncate_limit: 100 +delete from fkpart3.fk_part +-- +TABLE: name="fkpart3.fk_part" schema="fkpart3" table="fk_part" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart3.fk_part" +== 767 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 768 +-- truncate_limit: 100 +drop schema fkpart0, fkpart1, fkpart2, fkpart3 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart0, fkpart1, fkpart2, fkpart3 CASCADE" +== 769 +-- truncate_limit: 100 +-- Test a partitioned table as referenced table. + +-- Verify basic functionality with a regular partition creation and a partition +-- with a different column layout, as well as partitions added (created and +-- attached) after creating the foreign key. +CREATE SCHEMA fkpart3 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart3" +== 770 +-- truncate_limit: 100 +SET search_path TO fkpart3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fkpart3" +== 771 +-- truncate_limit: 100 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 772 +-- truncate_limit: 100 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (0) TO (1000)" +== 773 +-- truncate_limit: 100 +CREATE TABLE pk2 (b int, a int) +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk2 (b int, a int)" +== 774 +-- truncate_limit: 100 +ALTER TABLE pk2 DROP COLUMN b +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk2 DROP b" +== 775 +-- truncate_limit: 100 +ALTER TABLE pk2 ALTER a SET NOT NULL +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk2 ALTER COLUMN a SET NOT NULL" +== 776 +-- truncate_limit: 100 +ALTER TABLE pk ATTACH PARTITION pk2 FOR VALUES FROM (1000) TO (2000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk ATTACH PARTITION pk2 FOR VALUES FROM (1000) TO (2000)" +== 777 +-- truncate_limit: 100 +CREATE TABLE fk (a int) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk (a int) PARTITION BY RANGE (a)" +== 778 +-- truncate_limit: 100 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (0) TO (750) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (0) TO (750)" +== 779 +-- truncate_limit: 100 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk" +== 780 +-- truncate_limit: 100 +CREATE TABLE fk2 (b int, a int) +-- +TABLE: name="fk2" schema="" table="fk2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk2 (b int, a int)" +== 781 +-- truncate_limit: 100 +ALTER TABLE fk2 DROP COLUMN b +-- +TABLE: name="fk2" schema="" table="fk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk2 DROP b" +== 782 +-- truncate_limit: 100 +ALTER TABLE fk ATTACH PARTITION fk2 FOR VALUES FROM (750) TO (3500) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ATTACH PARTITION fk2 FOR VALUES FROM (750) TO (3500)" +== 783 +-- truncate_limit: 100 +CREATE TABLE pk3 PARTITION OF pk FOR VALUES FROM (2000) TO (3000) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk3 PARTITION OF pk FOR VALUES FROM (2000) TO (3000)" +== 784 +-- truncate_limit: 100 +CREATE TABLE pk4 (LIKE pk) +-- +TABLE: name="pk4" schema="" table="pk4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk4 (LIKE pk)" +== 785 +-- truncate_limit: 100 +ALTER TABLE pk ATTACH PARTITION pk4 FOR VALUES FROM (3000) TO (4000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk ATTACH PARTITION pk4 FOR VALUES FROM (3000) TO (4000)" +== 786 +-- truncate_limit: 100 +CREATE TABLE pk5 (c int, b int, a int NOT NULL) PARTITION BY RANGE (a) +-- +TABLE: name="pk5" schema="" table="pk5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk5 (c int, b int, a int NOT NULL) PARTITION BY RANGE (a)" +== 787 +-- truncate_limit: 100 +ALTER TABLE pk5 DROP COLUMN b, DROP COLUMN c +-- +TABLE: name="pk5" schema="" table="pk5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk5 DROP b, DROP c" +== 788 +-- truncate_limit: 100 +CREATE TABLE pk51 PARTITION OF pk5 FOR VALUES FROM (4000) TO (4500) +-- +TABLE: name="pk51" schema="" table="pk51" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk51 PARTITION OF pk5 FOR VALUES FROM (4000) TO (4500)" +== 789 +-- truncate_limit: 100 +CREATE TABLE pk52 PARTITION OF pk5 FOR VALUES FROM (4500) TO (5000) +-- +TABLE: name="pk52" schema="" table="pk52" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk52 PARTITION OF pk5 FOR VALUES FROM (4500) TO (5000)" +== 790 +-- truncate_limit: 100 +ALTER TABLE pk ATTACH PARTITION pk5 FOR VALUES FROM (4000) TO (5000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk ATTACH PARTITION pk5 FOR VALUES FROM (4000) TO (5000)" +== 791 +-- truncate_limit: 100 +CREATE TABLE fk3 PARTITION OF fk FOR VALUES FROM (3500) TO (5000) +-- +TABLE: name="fk3" schema="" table="fk3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk3 PARTITION OF fk FOR VALUES FROM (3500) TO (5000)" +== 792 +-- truncate_limit: 100 +-- these should fail: referenced value not present +INSERT into fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1)" +== 793 +-- truncate_limit: 100 +INSERT into fk VALUES (1000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1000)" +== 794 +-- truncate_limit: 100 +INSERT into fk VALUES (2000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (2000)" +== 795 +-- truncate_limit: 100 +INSERT into fk VALUES (3000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (3000)" +== 796 +-- truncate_limit: 100 +INSERT into fk VALUES (4000) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (4000)" +== 797 +-- truncate_limit: 100 +INSERT into fk VALUES (4500) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (4500)" +== 798 +-- truncate_limit: 100 +-- insert into the referenced table, now they should work +INSERT into pk VALUES (1), (1000), (2000), (3000), (4000), (4500) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pk VALUES (1), (1000), (2000), (3000), (4000), (4500)" +== 799 +-- truncate_limit: 100 +INSERT into fk VALUES (1), (1000), (2000), (3000), (4000), (4500) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1), (1000), (2000), (3000), (4000), (4500)" +== 800 +-- truncate_limit: 100 +-- should fail: referencing value present +DELETE FROM pk WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 1" +== 801 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 1000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 1000" +== 802 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 2000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 2000" +== 803 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 3000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 3000" +== 804 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 4000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 4000" +== 805 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 4500 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 4500" +== 806 +-- truncate_limit: 100 +UPDATE pk SET a = 2 WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 2 WHERE a = 1" +== 807 +-- truncate_limit: 100 +UPDATE pk SET a = 1002 WHERE a = 1000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 1002 WHERE a = 1000" +== 808 +-- truncate_limit: 100 +UPDATE pk SET a = 2002 WHERE a = 2000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 2002 WHERE a = 2000" +== 809 +-- truncate_limit: 100 +UPDATE pk SET a = 3002 WHERE a = 3000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 3002 WHERE a = 3000" +== 810 +-- truncate_limit: 100 +UPDATE pk SET a = 4002 WHERE a = 4000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 4002 WHERE a = 4000" +== 811 +-- truncate_limit: 100 +UPDATE pk SET a = 4502 WHERE a = 4500 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 4502 WHERE a = 4500" +== 812 +-- truncate_limit: 100 +-- now they should work +DELETE FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk" +== 813 +-- truncate_limit: 100 +UPDATE pk SET a = 2 WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 2 WHERE a = 1" +== 814 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 2 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 2" +== 815 +-- truncate_limit: 100 +UPDATE pk SET a = 1002 WHERE a = 1000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 1002 WHERE a = 1000" +== 816 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 1002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 1002" +== 817 +-- truncate_limit: 100 +UPDATE pk SET a = 2002 WHERE a = 2000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 2002 WHERE a = 2000" +== 818 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 2002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 2002" +== 819 +-- truncate_limit: 100 +UPDATE pk SET a = 3002 WHERE a = 3000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 3002 WHERE a = 3000" +== 820 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 3002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 3002" +== 821 +-- truncate_limit: 100 +UPDATE pk SET a = 4002 WHERE a = 4000 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 4002 WHERE a = 4000" +== 822 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 4002 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 4002" +== 823 +-- truncate_limit: 100 +UPDATE pk SET a = 4502 WHERE a = 4500 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 4502 WHERE a = 4500" +== 824 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 4502 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 4502" +== 825 +-- truncate_limit: 100 +-- Also, detaching a partition that has the FK itself should work +-- https://postgr.es/m/CAAJ_b97GuPh6wQPbxQS-Zpy16Oh+0aMv-w64QcGrLhCOZZ6p+g@mail.gmail.com +CREATE TABLE ffk (a int, b int REFERENCES pk) PARTITION BY list (a) +-- +TABLE: name="ffk" schema="" table="ffk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ffk (a int, b int REFERENCES pk) PARTITION BY LIST (a)" +== 826 +-- truncate_limit: 100 +CREATE TABLE ffk1 PARTITION OF ffk FOR VALUES IN (1) +-- +TABLE: name="ffk1" schema="" table="ffk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ffk1 PARTITION OF ffk FOR VALUES IN (1)" +== 827 +-- truncate_limit: 100 +ALTER TABLE ffk1 ADD FOREIGN KEY (a) REFERENCES pk +-- +TABLE: name="ffk1" schema="" table="ffk1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ffk1 ADD FOREIGN KEY (a) REFERENCES pk" +== 828 +-- truncate_limit: 100 +ALTER TABLE ffk DETACH PARTITION ffk1 +-- +TABLE: name="ffk" schema="" table="ffk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ffk DETACH PARTITION ffk1" +== 829 +-- truncate_limit: 100 +DROP TABLE ffk, ffk1 +-- +TABLE: name="ffk" schema="" table="ffk" ctx=DDL +TABLE: name="ffk1" schema="" table="ffk1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ffk, ffk1" +== 830 +-- truncate_limit: 100 +CREATE SCHEMA fkpart4 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart4" +== 831 +-- truncate_limit: 100 +SET search_path TO fkpart4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fkpart4" +== 832 +-- truncate_limit: 100 +-- dropping/detaching PARTITIONs is prevented if that would break +-- a foreign key's existing data +CREATE TABLE droppk (a int PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE droppk (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 833 +-- truncate_limit: 100 +CREATE TABLE droppk1 PARTITION OF droppk FOR VALUES FROM (0) TO (1000) +-- +TABLE: name="droppk1" schema="" table="droppk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE droppk1 PARTITION OF droppk FOR VALUES FROM (0) TO (1000)" +== 834 +-- truncate_limit: 100 +CREATE TABLE droppk_d PARTITION OF droppk DEFAULT +-- +TABLE: name="droppk_d" schema="" table="droppk_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE droppk_d PARTITION OF droppk DEFAULT" +== 835 +-- truncate_limit: 100 +CREATE TABLE droppk2 PARTITION OF droppk FOR VALUES FROM (1000) TO (2000) + PARTITION BY RANGE (a) +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE droppk2 PARTITION OF droppk FOR VALUES FROM (1000) TO (2000) PARTITION BY RANGE (a)" +== 836 +-- truncate_limit: 100 +CREATE TABLE droppk21 PARTITION OF droppk2 FOR VALUES FROM (1000) TO (1400) +-- +TABLE: name="droppk21" schema="" table="droppk21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE droppk21 PARTITION OF droppk2 FOR VALUES FROM (1000) TO (1400)" +== 837 +-- truncate_limit: 100 +CREATE TABLE droppk2_d PARTITION OF droppk2 DEFAULT +-- +TABLE: name="droppk2_d" schema="" table="droppk2_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE droppk2_d PARTITION OF droppk2 DEFAULT" +== 838 +-- truncate_limit: 100 +INSERT into droppk VALUES (1), (1000), (1500), (2000) +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO droppk VALUES (1), (1000), (1500), (2000)" +== 839 +-- truncate_limit: 100 +CREATE TABLE dropfk (a int REFERENCES droppk) +-- +TABLE: name="dropfk" schema="" table="dropfk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dropfk (a int REFERENCES droppk)" +== 840 +-- truncate_limit: 100 +INSERT into dropfk VALUES (1), (1000), (1500), (2000) +-- +TABLE: name="dropfk" schema="" table="dropfk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dropfk VALUES (1), (1000), (1500), (2000)" +== 841 +-- truncate_limit: 100 +-- these should all fail +ALTER TABLE droppk DETACH PARTITION droppk_d +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE droppk DETACH PARTITION droppk_d" +== 842 +-- truncate_limit: 100 +ALTER TABLE droppk2 DETACH PARTITION droppk2_d +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE droppk2 DETACH PARTITION droppk2_d" +== 843 +-- truncate_limit: 100 +ALTER TABLE droppk DETACH PARTITION droppk1 +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE droppk DETACH PARTITION droppk1" +== 844 +-- truncate_limit: 100 +ALTER TABLE droppk DETACH PARTITION droppk2 +-- +TABLE: name="droppk" schema="" table="droppk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE droppk DETACH PARTITION droppk2" +== 845 +-- truncate_limit: 100 +ALTER TABLE droppk2 DETACH PARTITION droppk21 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE droppk2 DETACH PARTITION droppk21" +== 846 +-- truncate_limit: 100 +-- dropping partitions is disallowed +DROP TABLE droppk_d +-- +TABLE: name="droppk_d" schema="" table="droppk_d" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk_d" +== 847 +-- truncate_limit: 100 +DROP TABLE droppk2_d +-- +TABLE: name="droppk2_d" schema="" table="droppk2_d" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk2_d" +== 848 +-- truncate_limit: 100 +DROP TABLE droppk1 +-- +TABLE: name="droppk1" schema="" table="droppk1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk1" +== 849 +-- truncate_limit: 100 +DROP TABLE droppk2 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk2" +== 850 +-- truncate_limit: 100 +DROP TABLE droppk21 +-- +TABLE: name="droppk21" schema="" table="droppk21" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk21" +== 851 +-- truncate_limit: 100 +DELETE FROM dropfk +-- +TABLE: name="dropfk" schema="" table="dropfk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM dropfk" +== 852 +-- truncate_limit: 100 +-- dropping partitions is disallowed, even when no referencing values +DROP TABLE droppk_d +-- +TABLE: name="droppk_d" schema="" table="droppk_d" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk_d" +== 853 +-- truncate_limit: 100 +DROP TABLE droppk2_d +-- +TABLE: name="droppk2_d" schema="" table="droppk2_d" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk2_d" +== 854 +-- truncate_limit: 100 +DROP TABLE droppk1 +-- +TABLE: name="droppk1" schema="" table="droppk1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk1" +== 855 +-- truncate_limit: 100 +-- but DETACH is allowed, and DROP afterwards works +ALTER TABLE droppk2 DETACH PARTITION droppk21 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE droppk2 DETACH PARTITION droppk21" +== 856 +-- truncate_limit: 100 +DROP TABLE droppk2 +-- +TABLE: name="droppk2" schema="" table="droppk2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE droppk2" +== 857 +-- truncate_limit: 100 +-- Verify that initial constraint creation and cloning behave correctly +CREATE SCHEMA fkpart5 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart5" +== 858 +-- truncate_limit: 100 +SET search_path TO fkpart5 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fkpart5" +== 859 +-- truncate_limit: 100 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a)" +== 860 +-- truncate_limit: 100 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1) PARTITION BY LIST (a) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1) PARTITION BY LIST (a)" +== 861 +-- truncate_limit: 100 +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1) +-- +TABLE: name="pk11" schema="" table="pk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1)" +== 862 +-- truncate_limit: 100 +CREATE TABLE fk (a int) PARTITION BY LIST (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk (a int) PARTITION BY LIST (a)" +== 863 +-- truncate_limit: 100 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES IN (1) PARTITION BY LIST (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk1 PARTITION OF fk FOR VALUES IN (1) PARTITION BY LIST (a)" +== 864 +-- truncate_limit: 100 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES IN (1) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES IN (1)" +== 865 +-- truncate_limit: 100 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk" +== 866 +-- truncate_limit: 100 +CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (2) +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (2)" +== 867 +-- truncate_limit: 100 +CREATE TABLE pk3 (a int NOT NULL) PARTITION BY LIST (a) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk3 (a int NOT NULL) PARTITION BY LIST (a)" +== 868 +-- truncate_limit: 100 +CREATE TABLE pk31 PARTITION OF pk3 FOR VALUES IN (31) +-- +TABLE: name="pk31" schema="" table="pk31" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk31 PARTITION OF pk3 FOR VALUES IN (31)" +== 869 +-- truncate_limit: 100 +CREATE TABLE pk32 (b int, a int NOT NULL) +-- +TABLE: name="pk32" schema="" table="pk32" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk32 (b int, a int NOT NULL)" +== 870 +-- truncate_limit: 100 +ALTER TABLE pk32 DROP COLUMN b +-- +TABLE: name="pk32" schema="" table="pk32" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk32 DROP b" +== 871 +-- truncate_limit: 100 +ALTER TABLE pk3 ATTACH PARTITION pk32 FOR VALUES IN (32) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk3 ATTACH PARTITION pk32 FOR VALUES IN (32)" +== 872 +-- truncate_limit: 100 +ALTER TABLE pk ATTACH PARTITION pk3 FOR VALUES IN (31, 32) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk ATTACH PARTITION pk3 FOR VALUES IN (31, 32)" +== 873 +-- truncate_limit: 100 +CREATE TABLE fk2 PARTITION OF fk FOR VALUES IN (2) +-- +TABLE: name="fk2" schema="" table="fk2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk2 PARTITION OF fk FOR VALUES IN (2)" +== 874 +-- truncate_limit: 100 +CREATE TABLE fk3 (b int, a int) +-- +TABLE: name="fk3" schema="" table="fk3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk3 (b int, a int)" +== 875 +-- truncate_limit: 100 +ALTER TABLE fk3 DROP COLUMN b +-- +TABLE: name="fk3" schema="" table="fk3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk3 DROP b" +== 876 +-- truncate_limit: 100 +ALTER TABLE fk ATTACH PARTITION fk3 FOR VALUES IN (3) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ATTACH PARTITION fk3 FOR VALUES IN (3)" +== 877 +-- truncate_limit: 100 +SELECT pg_describe_object('pg_constraint'::regclass, oid, 0), confrelid::regclass, + CASE WHEN conparentid <> 0 THEN pg_describe_object('pg_constraint'::regclass, conparentid, 0) ELSE 'TOP' END +FROM pg_catalog.pg_constraint +WHERE conrelid IN (SELECT relid FROM pg_partition_tree('fk')) +ORDER BY conrelid::regclass::text, conname +-- +TABLE: name="pg_catalog.pg_constraint" schema="pg_catalog" table="pg_constraint" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_catalog.pg_constraint WHERE ... ORDER BY conrelid::regclass::text, conname" +== 878 +-- truncate_limit: 100 +CREATE TABLE fk4 (LIKE fk) +-- +TABLE: name="fk4" schema="" table="fk4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk4 (LIKE fk)" +== 879 +-- truncate_limit: 100 +INSERT INTO fk4 VALUES (50) +-- +TABLE: name="fk4" schema="" table="fk4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk4 VALUES (50)" +== 880 +-- truncate_limit: 100 +ALTER TABLE fk ATTACH PARTITION fk4 FOR VALUES IN (50) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ATTACH PARTITION fk4 FOR VALUES IN (50)" +== 881 +-- truncate_limit: 100 +-- Verify constraint deferrability +CREATE SCHEMA fkpart9 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart9" +== 882 +-- truncate_limit: 100 +SET search_path TO fkpart9 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fkpart9" +== 883 +-- truncate_limit: 100 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a)" +== 884 +-- truncate_limit: 100 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1, 2) PARTITION BY LIST (a) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1, 2) PARTITION BY LIST (a)" +== 885 +-- truncate_limit: 100 +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1) +-- +TABLE: name="pk11" schema="" table="pk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1)" +== 886 +-- truncate_limit: 100 +CREATE TABLE pk3 PARTITION OF pk FOR VALUES IN (3) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk3 PARTITION OF pk FOR VALUES IN (3)" +== 887 +-- truncate_limit: 100 +CREATE TABLE fk (a int REFERENCES pk DEFERRABLE INITIALLY IMMEDIATE) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk (a int REFERENCES pk DEFERRABLE INITIALLY IMMEDIATE)" +== 888 +-- truncate_limit: 100 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1)" +== 889 +-- truncate_limit: 100 +-- should fail +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 890 +-- truncate_limit: 100 +SET CONSTRAINTS fk_a_fkey DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS fk_a_fkey DEFERRED" +== 891 +-- truncate_limit: 100 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1)" +== 892 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 893 +-- truncate_limit: 100 +-- should fail +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 894 +-- truncate_limit: 100 +SET CONSTRAINTS fk_a_fkey DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS fk_a_fkey DEFERRED" +== 895 +-- truncate_limit: 100 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1)" +== 896 +-- truncate_limit: 100 +INSERT INTO pk VALUES (1) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pk VALUES (1)" +== 897 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 898 +-- truncate_limit: 100 +-- OK +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 899 +-- truncate_limit: 100 +SET CONSTRAINTS fk_a_fkey DEFERRED +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS fk_a_fkey DEFERRED" +== 900 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 1 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 1" +== 901 +-- truncate_limit: 100 +DELETE FROM fk WHERE a = 1 +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk WHERE a = 1" +== 902 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 903 +-- truncate_limit: 100 +-- OK + +-- Verify constraint deferrability when changed by ALTER +-- Partitioned table at referencing end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt (f1 int, f2 int, f3 int, PRIMARY KEY (f1, f2))" +== 904 +-- truncate_limit: 100 +CREATE TABLE ref(f1 int, f2 int, f3 int) + PARTITION BY list(f1) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref (f1 int, f2 int, f3 int) PARTITION BY LIST (f1)" +== 905 +-- truncate_limit: 100 +CREATE TABLE ref1 PARTITION OF ref FOR VALUES IN (1) +-- +TABLE: name="ref1" schema="" table="ref1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref1 PARTITION OF ref FOR VALUES IN (1)" +== 906 +-- truncate_limit: 100 +CREATE TABLE ref2 PARTITION OF ref FOR VALUES in (2) +-- +TABLE: name="ref2" schema="" table="ref2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref2 PARTITION OF ref FOR VALUES IN (2)" +== 907 +-- truncate_limit: 100 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ADD FOREIGN KEY (f1, f2) REFERENCES pt" +== 908 +-- truncate_limit: 100 +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey DEFERRABLE INITIALLY DEFERRED" +== 909 +-- truncate_limit: 100 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pt VALUES (1, 2, 3)" +== 910 +-- truncate_limit: 100 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ref VALUES (1, 2, 3)" +== 911 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 912 +-- truncate_limit: 100 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pt" +== 913 +-- truncate_limit: 100 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ref" +== 914 +-- truncate_limit: 100 +ABORT +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 915 +-- truncate_limit: 100 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pt, ref" +== 916 +-- truncate_limit: 100 +-- Multi-level partitioning at referencing end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt (f1 int, f2 int, f3 int, PRIMARY KEY (f1, f2))" +== 917 +-- truncate_limit: 100 +CREATE TABLE ref(f1 int, f2 int, f3 int) + PARTITION BY list(f1) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref (f1 int, f2 int, f3 int) PARTITION BY LIST (f1)" +== 918 +-- truncate_limit: 100 +CREATE TABLE ref1_2 PARTITION OF ref FOR VALUES IN (1, 2) PARTITION BY list (f2) +-- +TABLE: name="ref1_2" schema="" table="ref1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref1_2 PARTITION OF ref FOR VALUES IN (1, 2) PARTITION BY LIST (f2)" +== 919 +-- truncate_limit: 100 +CREATE TABLE ref1 PARTITION OF ref1_2 FOR VALUES IN (1) +-- +TABLE: name="ref1" schema="" table="ref1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref1 PARTITION OF ref1_2 FOR VALUES IN (1)" +== 920 +-- truncate_limit: 100 +CREATE TABLE ref2 PARTITION OF ref1_2 FOR VALUES IN (2) PARTITION BY list (f2) +-- +TABLE: name="ref2" schema="" table="ref2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref2 PARTITION OF ref1_2 FOR VALUES IN (2) PARTITION BY LIST (f2)" +== 921 +-- truncate_limit: 100 +CREATE TABLE ref22 PARTITION OF ref2 FOR VALUES IN (2) +-- +TABLE: name="ref22" schema="" table="ref22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref22 PARTITION OF ref2 FOR VALUES IN (2)" +== 922 +-- truncate_limit: 100 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ADD FOREIGN KEY (f1, f2) REFERENCES pt" +== 923 +-- truncate_limit: 100 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pt VALUES (1, 2, 3)" +== 924 +-- truncate_limit: 100 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ref VALUES (1, 2, 3)" +== 925 +-- truncate_limit: 100 +ALTER TABLE ref22 ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY IMMEDIATE +-- +TABLE: name="ref22" schema="" table="ref22" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref22 ALTER CONSTRAINT ref_f1_f2_fkey DEFERRABLE" +== 926 +-- truncate_limit: 100 +-- fails +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey DEFERRABLE INITIALLY DEFERRED" +== 927 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 928 +-- truncate_limit: 100 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pt" +== 929 +-- truncate_limit: 100 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ref" +== 930 +-- truncate_limit: 100 +ABORT +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 931 +-- truncate_limit: 100 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pt, ref" +== 932 +-- truncate_limit: 100 +-- Partitioned table at referenced end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) + PARTITION BY LIST(f1) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt (f1 int, f2 int, f3 int, PRIMARY KEY (f1, f2)) PARTITION BY LIST (f1)" +== 933 +-- truncate_limit: 100 +CREATE TABLE pt1 PARTITION OF pt FOR VALUES IN (1) +-- +TABLE: name="pt1" schema="" table="pt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt1 PARTITION OF pt FOR VALUES IN (1)" +== 934 +-- truncate_limit: 100 +CREATE TABLE pt2 PARTITION OF pt FOR VALUES IN (2) +-- +TABLE: name="pt2" schema="" table="pt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt2 PARTITION OF pt FOR VALUES IN (2)" +== 935 +-- truncate_limit: 100 +CREATE TABLE ref(f1 int, f2 int, f3 int) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref (f1 int, f2 int, f3 int)" +== 936 +-- truncate_limit: 100 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ADD FOREIGN KEY (f1, f2) REFERENCES pt" +== 937 +-- truncate_limit: 100 +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey DEFERRABLE INITIALLY DEFERRED" +== 938 +-- truncate_limit: 100 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pt VALUES (1, 2, 3)" +== 939 +-- truncate_limit: 100 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ref VALUES (1, 2, 3)" +== 940 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 941 +-- truncate_limit: 100 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pt" +== 942 +-- truncate_limit: 100 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ref" +== 943 +-- truncate_limit: 100 +ABORT +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 944 +-- truncate_limit: 100 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pt, ref" +== 945 +-- truncate_limit: 100 +-- Multi-level partitioning at referenced end +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) + PARTITION BY LIST(f1) +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt (f1 int, f2 int, f3 int, PRIMARY KEY (f1, f2)) PARTITION BY LIST (f1)" +== 946 +-- truncate_limit: 100 +CREATE TABLE pt1_2 PARTITION OF pt FOR VALUES IN (1, 2) PARTITION BY LIST (f1) +-- +TABLE: name="pt1_2" schema="" table="pt1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt1_2 PARTITION OF pt FOR VALUES IN (1, 2) PARTITION BY LIST (f1)" +== 947 +-- truncate_limit: 100 +CREATE TABLE pt1 PARTITION OF pt1_2 FOR VALUES IN (1) +-- +TABLE: name="pt1" schema="" table="pt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt1 PARTITION OF pt1_2 FOR VALUES IN (1)" +== 948 +-- truncate_limit: 100 +CREATE TABLE pt2 PARTITION OF pt1_2 FOR VALUES IN (2) +-- +TABLE: name="pt2" schema="" table="pt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt2 PARTITION OF pt1_2 FOR VALUES IN (2)" +== 949 +-- truncate_limit: 100 +CREATE TABLE ref(f1 int, f2 int, f3 int) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref (f1 int, f2 int, f3 int)" +== 950 +-- truncate_limit: 100 +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ADD FOREIGN KEY (f1, f2) REFERENCES pt" +== 951 +-- truncate_limit: 100 +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey1 + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey1 DEFERRABLE INITIALLY DEFERRED" +== 952 +-- truncate_limit: 100 +-- fails +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey DEFERRABLE INITIALLY DEFERRED" +== 953 +-- truncate_limit: 100 +INSERT INTO pt VALUES(1,2,3) +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pt VALUES (1, 2, 3)" +== 954 +-- truncate_limit: 100 +INSERT INTO ref VALUES(1,2,3) +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ref VALUES (1, 2, 3)" +== 955 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 956 +-- truncate_limit: 100 +DELETE FROM pt +-- +TABLE: name="pt" schema="" table="pt" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pt" +== 957 +-- truncate_limit: 100 +DELETE FROM ref +-- +TABLE: name="ref" schema="" table="ref" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ref" +== 958 +-- truncate_limit: 100 +ABORT +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 959 +-- truncate_limit: 100 +DROP TABLE pt, ref +-- +TABLE: name="pt" schema="" table="pt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pt, ref" +== 960 +-- truncate_limit: 100 +DROP SCHEMA fkpart9 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart9 CASCADE" +== 961 +-- truncate_limit: 100 +-- Verify ON UPDATE/DELETE behavior +CREATE SCHEMA fkpart6 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart6" +== 962 +-- truncate_limit: 100 +SET search_path TO fkpart6 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fkpart6" +== 963 +-- truncate_limit: 100 +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 964 +-- truncate_limit: 100 +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a)" +== 965 +-- truncate_limit: 100 +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (1) TO (50) +-- +TABLE: name="pk11" schema="" table="pk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (1) TO (50)" +== 966 +-- truncate_limit: 100 +CREATE TABLE pk12 PARTITION OF pk1 FOR VALUES FROM (50) TO (100) +-- +TABLE: name="pk12" schema="" table="pk12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk12 PARTITION OF pk1 FOR VALUES FROM (50) TO (100)" +== 967 +-- truncate_limit: 100 +CREATE TABLE fk (a int) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk (a int) PARTITION BY RANGE (a)" +== 968 +-- truncate_limit: 100 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a)" +== 969 +-- truncate_limit: 100 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10)" +== 970 +-- truncate_limit: 100 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100)" +== 971 +-- truncate_limit: 100 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE CASCADE ON DELETE CASCADE +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE CASCADE ON DELETE CASCADE" +== 972 +-- truncate_limit: 100 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_d PARTITION OF fk DEFAULT" +== 973 +-- truncate_limit: 100 +INSERT INTO pk VALUES (1) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pk VALUES (1)" +== 974 +-- truncate_limit: 100 +INSERT INTO fk VALUES (1) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1)" +== 975 +-- truncate_limit: 100 +UPDATE pk SET a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 20" +== 976 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM fk" +== 977 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 20" +== 978 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM fk" +== 979 +-- truncate_limit: 100 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk" +== 980 +-- truncate_limit: 100 +TRUNCATE TABLE pk +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE pk" +== 981 +-- truncate_limit: 100 +INSERT INTO pk VALUES (20), (50) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pk VALUES (20), (50)" +== 982 +-- truncate_limit: 100 +CREATE TABLE fk (a int) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk (a int) PARTITION BY RANGE (a)" +== 983 +-- truncate_limit: 100 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a)" +== 984 +-- truncate_limit: 100 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10)" +== 985 +-- truncate_limit: 100 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100)" +== 986 +-- truncate_limit: 100 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET NULL ON DELETE SET NULL +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET NULL ON DELETE SET NULL" +== 987 +-- truncate_limit: 100 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_d PARTITION OF fk DEFAULT" +== 988 +-- truncate_limit: 100 +INSERT INTO fk VALUES (20), (50) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (20), (50)" +== 989 +-- truncate_limit: 100 +UPDATE pk SET a = 21 WHERE a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 21 WHERE a = 20" +== 990 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 50 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 50" +== 991 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM fk" +== 992 +-- truncate_limit: 100 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk" +== 993 +-- truncate_limit: 100 +TRUNCATE TABLE pk +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE pk" +== 994 +-- truncate_limit: 100 +INSERT INTO pk VALUES (20), (30), (50) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pk VALUES (20), (30), (50)" +== 995 +-- truncate_limit: 100 +CREATE TABLE fk (id int, a int DEFAULT 50) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk (id int, a int DEFAULT 50) PARTITION BY RANGE (a)" +== 996 +-- truncate_limit: 100 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a)" +== 997 +-- truncate_limit: 100 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10)" +== 998 +-- truncate_limit: 100 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100)" +== 999 +-- truncate_limit: 100 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET DEFAULT ON DELETE SET DEFAULT +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET DEFAULT ON DELETE SET DEFAULT" +== 1000 +-- truncate_limit: 100 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_d PARTITION OF fk DEFAULT" +== 1001 +-- truncate_limit: 100 +INSERT INTO fk VALUES (1, 20), (2, 30) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (1, 20), (2, 30)" +== 1002 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 20 RETURNING * +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 20 RETURNING *" +== 1003 +-- truncate_limit: 100 +UPDATE pk SET a = 90 WHERE a = 30 RETURNING * +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 90 WHERE a = 30 RETURNING *" +== 1004 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM fk" +== 1005 +-- truncate_limit: 100 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk" +== 1006 +-- truncate_limit: 100 +TRUNCATE TABLE pk +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE pk" +== 1007 +-- truncate_limit: 100 +INSERT INTO pk VALUES (20), (30) +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pk VALUES (20), (30)" +== 1008 +-- truncate_limit: 100 +CREATE TABLE fk (a int DEFAULT 50) PARTITION BY RANGE (a) +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk (a int DEFAULT 50) PARTITION BY RANGE (a)" +== 1009 +-- truncate_limit: 100 +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a) +-- +TABLE: name="fk1" schema="" table="fk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a)" +== 1010 +-- truncate_limit: 100 +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="fk11" schema="" table="fk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10)" +== 1011 +-- truncate_limit: 100 +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100) +-- +TABLE: name="fk12" schema="" table="fk12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100)" +== 1012 +-- truncate_limit: 100 +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE RESTRICT ON DELETE RESTRICT +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE RESTRICT ON DELETE RESTRICT" +== 1013 +-- truncate_limit: 100 +CREATE TABLE fk_d PARTITION OF fk DEFAULT +-- +TABLE: name="fk_d" schema="" table="fk_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fk_d PARTITION OF fk DEFAULT" +== 1014 +-- truncate_limit: 100 +INSERT INTO fk VALUES (20), (30) +-- +TABLE: name="fk" schema="" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk VALUES (20), (30)" +== 1015 +-- truncate_limit: 100 +DELETE FROM pk WHERE a = 20 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pk WHERE a = 20" +== 1016 +-- truncate_limit: 100 +UPDATE pk SET a = 90 WHERE a = 30 +-- +TABLE: name="pk" schema="" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pk SET a = 90 WHERE a = 30" +== 1017 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM fk +-- +TABLE: name="fk" schema="" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM fk" +== 1018 +-- truncate_limit: 100 +DROP TABLE fk +-- +TABLE: name="fk" schema="" table="fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fk" +== 1019 +-- truncate_limit: 100 +-- test for reported bug: relispartition not set +-- https://postgr.es/m/CA+HiwqHMsRtRYRWYTWavKJ8x14AFsv7bmAV46mYwnfD3vy8goQ@mail.gmail.com +CREATE SCHEMA fkpart7 + CREATE TABLE pkpart (a int) PARTITION BY LIST (a) + CREATE TABLE pkpart1 PARTITION OF pkpart FOR VALUES IN (1) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart7 CREATE TABLE pkpart (a int) PARTITION BY LIST (a) CREATE TABLE pkpart1 PART..." +== 1020 +-- truncate_limit: 100 +ALTER TABLE fkpart7.pkpart1 ADD PRIMARY KEY (a) +-- +TABLE: name="fkpart7.pkpart1" schema="fkpart7" table="pkpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart7.pkpart1 ADD PRIMARY KEY (a)" +== 1021 +-- truncate_limit: 100 +ALTER TABLE fkpart7.pkpart ADD PRIMARY KEY (a) +-- +TABLE: name="fkpart7.pkpart" schema="fkpart7" table="pkpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart7.pkpart ADD PRIMARY KEY (a)" +== 1022 +-- truncate_limit: 100 +CREATE TABLE fkpart7.fk (a int REFERENCES fkpart7.pkpart) +-- +TABLE: name="fkpart7.fk" schema="fkpart7" table="fk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart7.fk (a int REFERENCES fkpart7.pkpart)" +== 1023 +-- truncate_limit: 100 +DROP SCHEMA fkpart7 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart7 CASCADE" +== 1024 +-- truncate_limit: 100 +-- ensure we check partitions are "not used" when dropping constraints +CREATE SCHEMA fkpart8 + CREATE TABLE tbl1(f1 int PRIMARY KEY) + CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) PARTITION BY RANGE(f1) + CREATE TABLE tbl2_p1 PARTITION OF tbl2 FOR VALUES FROM (minvalue) TO (maxvalue) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart8 CREATE TABLE tbl1 (f1 int PRIMARY KEY) CREATE TABLE tbl2 (f1 int REFERENCES..." +== 1025 +-- truncate_limit: 100 +INSERT INTO fkpart8.tbl1 VALUES(1) +-- +TABLE: name="fkpart8.tbl1" schema="fkpart8" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart8.tbl1 VALUES (1)" +== 1026 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1027 +-- truncate_limit: 100 +INSERT INTO fkpart8.tbl2 VALUES(1) +-- +TABLE: name="fkpart8.tbl2" schema="fkpart8" table="tbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart8.tbl2 VALUES (1)" +== 1028 +-- truncate_limit: 100 +ALTER TABLE fkpart8.tbl2 DROP CONSTRAINT tbl2_f1_fkey +-- +TABLE: name="fkpart8.tbl2" schema="fkpart8" table="tbl2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart8.tbl2 DROP CONSTRAINT tbl2_f1_fkey" +== 1029 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1030 +-- truncate_limit: 100 +DROP SCHEMA fkpart8 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart8 CASCADE" +== 1031 +-- truncate_limit: 100 +-- ensure FK referencing a multi-level partitioned table are +-- enforce reference to sub-children. +CREATE SCHEMA fkpart9 + CREATE TABLE pk (a INT PRIMARY KEY) PARTITION BY RANGE (a) + CREATE TABLE fk ( + fk_a INT REFERENCES pk(a) ON DELETE CASCADE + ) + CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (30) TO (50) PARTITION BY RANGE (a) + CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (30) TO (40) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart9 CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a) CREATE TABLE fk ..." +== 1032 +-- truncate_limit: 100 +INSERT INTO fkpart9.pk VALUES (35) +-- +TABLE: name="fkpart9.pk" schema="fkpart9" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart9.pk VALUES (35)" +== 1033 +-- truncate_limit: 100 +INSERT INTO fkpart9.fk VALUES (35) +-- +TABLE: name="fkpart9.fk" schema="fkpart9" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart9.fk VALUES (35)" +== 1034 +-- truncate_limit: 100 +DELETE FROM fkpart9.pk WHERE a=35 +-- +TABLE: name="fkpart9.pk" schema="fkpart9" table="pk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart9.pk WHERE a = 35" +== 1035 +-- truncate_limit: 100 +SELECT * FROM fkpart9.pk +-- +TABLE: name="fkpart9.pk" schema="fkpart9" table="pk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fkpart9.pk" +== 1036 +-- truncate_limit: 100 +SELECT * FROM fkpart9.fk +-- +TABLE: name="fkpart9.fk" schema="fkpart9" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fkpart9.fk" +== 1037 +-- truncate_limit: 100 +DROP SCHEMA fkpart9 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart9 CASCADE" +== 1038 +-- truncate_limit: 100 +-- test that ri_Check_Pk_Match() scans the correct partition for a deferred +-- ON DELETE/UPDATE NO ACTION constraint +CREATE SCHEMA fkpart10 + CREATE TABLE tbl1(f1 int PRIMARY KEY) PARTITION BY RANGE(f1) + CREATE TABLE tbl1_p1 PARTITION OF tbl1 FOR VALUES FROM (minvalue) TO (1) + CREATE TABLE tbl1_p2 PARTITION OF tbl1 FOR VALUES FROM (1) TO (maxvalue) + CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) + CREATE TABLE tbl3(f1 int PRIMARY KEY) PARTITION BY RANGE(f1) + CREATE TABLE tbl3_p1 PARTITION OF tbl3 FOR VALUES FROM (minvalue) TO (1) + CREATE TABLE tbl3_p2 PARTITION OF tbl3 FOR VALUES FROM (1) TO (maxvalue) + CREATE TABLE tbl4(f1 int REFERENCES tbl3 DEFERRABLE INITIALLY DEFERRED) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart10 CREATE TABLE tbl1 (f1 int PRIMARY KEY) PARTITION BY RANGE (f1) CREATE TABL..." +== 1039 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl1 VALUES (0), (1) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl1 VALUES (0), (1)" +== 1040 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl2 VALUES (0), (1) +-- +TABLE: name="fkpart10.tbl2" schema="fkpart10" table="tbl2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl2 VALUES (0), (1)" +== 1041 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl3 VALUES (-2), (-1), (0) +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl3 VALUES (-2), (-1), (0)" +== 1042 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl4 VALUES (-2), (-1) +-- +TABLE: name="fkpart10.tbl4" schema="fkpart10" table="tbl4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl4 VALUES (-2), (-1)" +== 1043 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1044 +-- truncate_limit: 100 +DELETE FROM fkpart10.tbl1 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart10.tbl1 WHERE f1 = 0" +== 1045 +-- truncate_limit: 100 +UPDATE fkpart10.tbl1 SET f1 = 2 WHERE f1 = 1 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl1 SET f1 = 2 WHERE f1 = 1" +== 1046 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl1 VALUES (0), (1) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl1 VALUES (0), (1)" +== 1047 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1048 +-- truncate_limit: 100 +-- test that cross-partition updates correctly enforces the foreign key +-- restriction (specifically testing INITIALLY DEFERRED) +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1049 +-- truncate_limit: 100 +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0" +== 1050 +-- truncate_limit: 100 +UPDATE fkpart10.tbl3 SET f1 = f1 * -1 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl3 SET f1 = f1 * -1" +== 1051 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl1 VALUES (4) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl1 VALUES (4)" +== 1052 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1053 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1054 +-- truncate_limit: 100 +UPDATE fkpart10.tbl3 SET f1 = f1 * -1 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl3 SET f1 = f1 * -1" +== 1055 +-- truncate_limit: 100 +UPDATE fkpart10.tbl3 SET f1 = f1 + 3 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl3 SET f1 = f1 + 3" +== 1056 +-- truncate_limit: 100 +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0" +== 1057 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl1 VALUES (0) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl1 VALUES (0)" +== 1058 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1059 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1060 +-- truncate_limit: 100 +UPDATE fkpart10.tbl3 SET f1 = f1 * -1 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl3 SET f1 = f1 * -1" +== 1061 +-- truncate_limit: 100 +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0 +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0" +== 1062 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl1 VALUES (0) +-- +TABLE: name="fkpart10.tbl1" schema="fkpart10" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl1 VALUES (0)" +== 1063 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl3 VALUES (-2), (-1) +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl3 VALUES (-2), (-1)" +== 1064 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1065 +-- truncate_limit: 100 +-- test where the updated table now has both an IMMEDIATE and a DEFERRED +-- constraint pointing into it +CREATE TABLE fkpart10.tbl5(f1 int REFERENCES fkpart10.tbl3) +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart10.tbl5 (f1 int REFERENCES fkpart10.tbl3)" +== 1066 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl5 VALUES (-2), (-1) +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl5 VALUES (-2), (-1)" +== 1067 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1068 +-- truncate_limit: 100 +UPDATE fkpart10.tbl3 SET f1 = f1 * -3 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl3 SET f1 = f1 * -3" +== 1069 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1070 +-- truncate_limit: 100 +-- Now test where the row referenced from the table with an IMMEDIATE +-- constraint stays in place, while those referenced from the table with a +-- DEFERRED constraint don't. +DELETE FROM fkpart10.tbl5 +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart10.tbl5" +== 1071 +-- truncate_limit: 100 +INSERT INTO fkpart10.tbl5 VALUES (0) +-- +TABLE: name="fkpart10.tbl5" schema="fkpart10" table="tbl5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart10.tbl5 VALUES (0)" +== 1072 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1073 +-- truncate_limit: 100 +UPDATE fkpart10.tbl3 SET f1 = f1 * -3 +-- +TABLE: name="fkpart10.tbl3" schema="fkpart10" table="tbl3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart10.tbl3 SET f1 = f1 * -3" +== 1074 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 1075 +-- truncate_limit: 100 +DROP SCHEMA fkpart10 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart10 CASCADE" +== 1076 +-- truncate_limit: 100 +-- verify foreign keys are enforced during cross-partition updates, +-- especially on the PK side +CREATE SCHEMA fkpart11 + CREATE TABLE pk (a INT PRIMARY KEY, b text) PARTITION BY LIST (a) + CREATE TABLE fk ( + a INT, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES pk(a) ON UPDATE CASCADE ON DELETE CASCADE + ) + CREATE TABLE fk_parted ( + a INT PRIMARY KEY, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES pk(a) ON UPDATE CASCADE ON DELETE CASCADE + ) PARTITION BY LIST (a) + CREATE TABLE fk_another ( + a INT, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fk_parted (a) ON UPDATE CASCADE ON DELETE CASCADE + ) + CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1, 2) PARTITION BY LIST (a) + CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (3) + CREATE TABLE pk3 PARTITION OF pk FOR VALUES IN (4) + CREATE TABLE fk1 PARTITION OF fk_parted FOR VALUES IN (1, 2) + CREATE TABLE fk2 PARTITION OF fk_parted FOR VALUES IN (3) + CREATE TABLE fk3 PARTITION OF fk_parted FOR VALUES IN (4) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart11 CREATE TABLE pk (a int PRIMARY KEY, b text) PARTITION BY LIST (a) CREATE T..." +== 1077 +-- truncate_limit: 100 +CREATE TABLE fkpart11.pk11 (b text, a int NOT NULL) +-- +TABLE: name="fkpart11.pk11" schema="fkpart11" table="pk11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart11.pk11 (b text, a int NOT NULL)" +== 1078 +-- truncate_limit: 100 +ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk11 FOR VALUES IN (1) +-- +TABLE: name="fkpart11.pk1" schema="fkpart11" table="pk1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk11 FOR VALUES IN (1)" +== 1079 +-- truncate_limit: 100 +CREATE TABLE fkpart11.pk12 (b text, c int, a int NOT NULL) +-- +TABLE: name="fkpart11.pk12" schema="fkpart11" table="pk12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart11.pk12 (b text, c int, a int NOT NULL)" +== 1080 +-- truncate_limit: 100 +ALTER TABLE fkpart11.pk12 DROP c +-- +TABLE: name="fkpart11.pk12" schema="fkpart11" table="pk12" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart11.pk12 DROP c" +== 1081 +-- truncate_limit: 100 +ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk12 FOR VALUES IN (2) +-- +TABLE: name="fkpart11.pk1" schema="fkpart11" table="pk1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk12 FOR VALUES IN (2)" +== 1082 +-- truncate_limit: 100 +INSERT INTO fkpart11.pk VALUES (1, 'xxx'), (3, 'yyy') +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart11.pk VALUES (1, 'xxx'), (3, 'yyy')" +== 1083 +-- truncate_limit: 100 +INSERT INTO fkpart11.fk VALUES (1), (3) +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart11.fk VALUES (1), (3)" +== 1084 +-- truncate_limit: 100 +INSERT INTO fkpart11.fk_parted VALUES (1), (3) +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart11.fk_parted VALUES (1), (3)" +== 1085 +-- truncate_limit: 100 +INSERT INTO fkpart11.fk_another VALUES (1), (3) +-- +TABLE: name="fkpart11.fk_another" schema="fkpart11" table="fk_another" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart11.fk_another VALUES (1), (3)" +== 1086 +-- truncate_limit: 100 +-- moves 2 rows from one leaf partition to another, with both updates being +-- cascaded to fk and fk_parted. Updates of fk_parted, of which one is +-- cross-partition (3 -> 4), are further cascaded to fk_another. +UPDATE fkpart11.pk SET a = a + 1 RETURNING tableoid::pg_catalog.regclass, * +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart11.pk SET a = a + 1 RETURNING tableoid::pg_catalog.regclass, *" +== 1087 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk" +== 1088 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted" +== 1089 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another +-- +TABLE: name="fkpart11.fk_another" schema="fkpart11" table="fk_another" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another" +== 1090 +-- truncate_limit: 100 +-- let's try with the foreign key pointing at tables in the partition tree +-- that are not the same as the query's target table + +-- 1. foreign key pointing into a non-root ancestor +|-- +-- A cross-partition update on the root table will fail, because we currently +-- can't enforce the foreign keys pointing into a non-leaf partition +ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey" +== 1091 +-- truncate_limit: 100 +DELETE FROM fkpart11.fk WHERE a = 4 +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fkpart11.fk WHERE a = 4" +== 1092 +-- truncate_limit: 100 +ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk1 (a) ON UPDATE CASCADE ON DELETE CASCADE +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk1 (a) ON UPDATE..." +== 1093 +-- truncate_limit: 100 +UPDATE fkpart11.pk SET a = a - 1 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart11.pk SET a = a - 1" +== 1094 +-- truncate_limit: 100 +-- it's okay though if the non-leaf partition is updated directly +UPDATE fkpart11.pk1 SET a = a - 1 +-- +TABLE: name="fkpart11.pk1" schema="fkpart11" table="pk1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart11.pk1 SET a = a - 1" +== 1095 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.pk +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.pk" +== 1096 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk" +== 1097 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted" +== 1098 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another +-- +TABLE: name="fkpart11.fk_another" schema="fkpart11" table="fk_another" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another" +== 1099 +-- truncate_limit: 100 +-- 2. foreign key pointing into a single leaf partition +|-- +-- A cross-partition update that deletes from the pointed-to leaf partition +-- is allowed to succeed +ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey" +== 1100 +-- truncate_limit: 100 +ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk11 (a) ON UPDATE CASCADE ON DELETE CASCADE +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk11 (a) ON UPDAT..." +== 1101 +-- truncate_limit: 100 +-- will delete (1) from p11 which is cascaded to fk +UPDATE fkpart11.pk SET a = a + 1 WHERE a = 1 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart11.pk SET a = a + 1 WHERE a = 1" +== 1102 +-- truncate_limit: 100 +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk" +== 1103 +-- truncate_limit: 100 +DROP TABLE fkpart11.fk +-- +TABLE: name="fkpart11.fk" schema="fkpart11" table="fk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fkpart11.fk" +== 1104 +-- truncate_limit: 100 +-- check that regular and deferrable AR triggers on the PK tables +-- still work as expected +CREATE FUNCTION fkpart11.print_row () RETURNS TRIGGER LANGUAGE plpgsql AS $$ + BEGIN + RAISE NOTICE 'TABLE: %, OP: %, OLD: %, NEW: %', TG_RELNAME, TG_OP, OLD, NEW; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="fkpart11.print_row" function="print_row" schema="fkpart11" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fkpart11.print_row() RETURNS trigger LANGUAGE plpgsql AS $$\n BEGIN\n RAISE NOT..." +== 1105 +-- truncate_limit: 100 +CREATE TRIGGER trig_upd_pk AFTER UPDATE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_pk AFTER UPDATE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.pri..." +== 1106 +-- truncate_limit: 100 +CREATE TRIGGER trig_del_pk AFTER DELETE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_pk AFTER DELETE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.pri..." +== 1107 +-- truncate_limit: 100 +CREATE TRIGGER trig_ins_pk AFTER INSERT ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_pk AFTER INSERT ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.pri..." +== 1108 +-- truncate_limit: 100 +CREATE CONSTRAINT TRIGGER trig_upd_fk_parted AFTER UPDATE ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER trig_upd_fk_parted AFTER UPDATE ON fkpart11.fk_parted DEFERRABLE INITIA..." +== 1109 +-- truncate_limit: 100 +CREATE CONSTRAINT TRIGGER trig_del_fk_parted AFTER DELETE ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER trig_del_fk_parted AFTER DELETE ON fkpart11.fk_parted DEFERRABLE INITIA..." +== 1110 +-- truncate_limit: 100 +CREATE CONSTRAINT TRIGGER trig_ins_fk_parted AFTER INSERT ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row() +-- +TABLE: name="fkpart11.fk_parted" schema="fkpart11" table="fk_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER trig_ins_fk_parted AFTER INSERT ON fkpart11.fk_parted DEFERRABLE INITIA..." +== 1111 +-- truncate_limit: 100 +UPDATE fkpart11.pk SET a = 3 WHERE a = 4 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart11.pk SET a = 3 WHERE a = 4" +== 1112 +-- truncate_limit: 100 +UPDATE fkpart11.pk SET a = 1 WHERE a = 2 +-- +TABLE: name="fkpart11.pk" schema="fkpart11" table="pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart11.pk SET a = 1 WHERE a = 2" +== 1113 +-- truncate_limit: 100 +DROP SCHEMA fkpart11 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart11 CASCADE" +== 1114 +-- truncate_limit: 100 +-- When a table is attached as partition to a partitioned table that has +-- a foreign key to another partitioned table, it acquires a clone of the +-- FK. Upon detach, this clone is not removed, but instead becomes an +-- independent FK. If it then attaches to the partitioned table again, +-- the FK from the parent "takes over" ownership of the independent FK rather +-- than creating a separate one. +CREATE SCHEMA fkpart12 + CREATE TABLE fk_p ( id int, jd int, PRIMARY KEY(id, jd)) PARTITION BY list (id) + CREATE TABLE fk_p_1 PARTITION OF fk_p FOR VALUES IN (1) PARTITION BY list (jd) + CREATE TABLE fk_p_1_1 PARTITION OF fk_p_1 FOR VALUES IN (1) + CREATE TABLE fk_p_1_2 (x int, y int, jd int NOT NULL, id int NOT NULL) + CREATE TABLE fk_p_2 PARTITION OF fk_p FOR VALUES IN (2) PARTITION BY list (jd) + CREATE TABLE fk_p_2_1 PARTITION OF fk_p_2 FOR VALUES IN (1) + CREATE TABLE fk_p_2_2 PARTITION OF fk_p_2 FOR VALUES IN (2) + CREATE TABLE fk_r_1 ( p_jd int NOT NULL, x int, id int PRIMARY KEY, p_id int NOT NULL) + CREATE TABLE fk_r_2 ( id int PRIMARY KEY, p_id int NOT NULL, p_jd int NOT NULL) PARTITION BY list (id) + CREATE TABLE fk_r_2_1 PARTITION OF fk_r_2 FOR VALUES IN (2, 1) + CREATE TABLE fk_r ( id int PRIMARY KEY, p_id int NOT NULL, p_jd int NOT NULL, + FOREIGN KEY (p_id, p_jd) REFERENCES fk_p (id, jd) + ) PARTITION BY list (id) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart12 CREATE TABLE fk_p (id int, jd int, PRIMARY KEY (id, jd)) PARTITION BY LIST..." +== 1115 +-- truncate_limit: 100 +SET search_path TO fkpart12 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fkpart12" +== 1116 +-- truncate_limit: 100 +ALTER TABLE fk_p_1_2 DROP COLUMN x, DROP COLUMN y +-- +TABLE: name="fk_p_1_2" schema="" table="fk_p_1_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_p_1_2 DROP x, DROP y" +== 1117 +-- truncate_limit: 100 +ALTER TABLE fk_p_1 ATTACH PARTITION fk_p_1_2 FOR VALUES IN (2) +-- +TABLE: name="fk_p_1" schema="" table="fk_p_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_p_1 ATTACH PARTITION fk_p_1_2 FOR VALUES IN (2)" +== 1118 +-- truncate_limit: 100 +ALTER TABLE fk_r_1 DROP COLUMN x +-- +TABLE: name="fk_r_1" schema="" table="fk_r_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r_1 DROP x" +== 1119 +-- truncate_limit: 100 +INSERT INTO fk_p VALUES (1, 1) +-- +TABLE: name="fk_p" schema="" table="fk_p" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_p VALUES (1, 1)" +== 1120 +-- truncate_limit: 100 +ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1)" +== 1121 +-- truncate_limit: 100 +ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2)" +== 1122 +-- truncate_limit: 100 +INSERT INTO fk_r VALUES (1, 1, 1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_r VALUES (1, 1, 1)" +== 1123 +-- truncate_limit: 100 +INSERT INTO fk_r VALUES (2, 2, 1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_r VALUES (2, 2, 1)" +== 1124 +-- truncate_limit: 100 +ALTER TABLE fk_r DETACH PARTITION fk_r_1 +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r DETACH PARTITION fk_r_1" +== 1125 +-- truncate_limit: 100 +ALTER TABLE fk_r DETACH PARTITION fk_r_2 +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r DETACH PARTITION fk_r_2" +== 1126 +-- truncate_limit: 100 +INSERT INTO fk_r_1 (id, p_id, p_jd) VALUES (2, 1, 2) +-- +TABLE: name="fk_r_1" schema="" table="fk_r_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fk_r_1 (id, p_id, p_jd) VALUES (2, 1, 2)" +== 1127 +-- truncate_limit: 100 +-- should fail +DELETE FROM fk_p +-- +TABLE: name="fk_p" schema="" table="fk_p" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_p" +== 1128 +-- truncate_limit: 100 +-- should fail + +ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1)" +== 1129 +-- truncate_limit: 100 +ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2) +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2)" +== 1130 +-- truncate_limit: 100 +DELETE FROM fk_p +-- +TABLE: name="fk_p" schema="" table="fk_p" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM fk_p" +== 1131 +-- truncate_limit: 100 +-- should fail + +-- these should all fail +ALTER TABLE fk_r_1 DROP CONSTRAINT fk_r_p_id_p_jd_fkey +-- +TABLE: name="fk_r_1" schema="" table="fk_r_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r_1 DROP CONSTRAINT fk_r_p_id_p_jd_fkey" +== 1132 +-- truncate_limit: 100 +ALTER TABLE fk_r DROP CONSTRAINT fk_r_p_id_p_jd_fkey1 +-- +TABLE: name="fk_r" schema="" table="fk_r" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r DROP CONSTRAINT fk_r_p_id_p_jd_fkey1" +== 1133 +-- truncate_limit: 100 +ALTER TABLE fk_r_2 DROP CONSTRAINT fk_r_p_id_p_jd_fkey +-- +TABLE: name="fk_r_2" schema="" table="fk_r_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fk_r_2 DROP CONSTRAINT fk_r_p_id_p_jd_fkey" +== 1134 +-- truncate_limit: 100 +SET client_min_messages TO warning +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 1135 +-- truncate_limit: 100 +DROP SCHEMA fkpart12 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart12 CASCADE" +== 1136 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 1137 +-- truncate_limit: 100 +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 1138 +-- truncate_limit: 100 +-- Exercise the column mapping code with foreign keys. In this test we'll +-- create a partitioned table which has a partition with a dropped column and +-- check to ensure that an UPDATE cascades the changes correctly to the +-- partitioned table. +CREATE SCHEMA fkpart13 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA fkpart13" +== 1139 +-- truncate_limit: 100 +SET search_path TO fkpart13 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO fkpart13" +== 1140 +-- truncate_limit: 100 +CREATE TABLE fkpart13_t1 (a int PRIMARY KEY) +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart13_t1 (a int PRIMARY KEY)" +== 1141 +-- truncate_limit: 100 +CREATE TABLE fkpart13_t2 ( + part_id int PRIMARY KEY, + column_to_drop int, + FOREIGN KEY (part_id) REFERENCES fkpart13_t1 ON UPDATE CASCADE ON DELETE CASCADE +) PARTITION BY LIST (part_id) +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart13_t2 (part_id int PRIMARY KEY, column_to_drop int, FOREIGN KEY (part_id) REFE..." +== 1142 +-- truncate_limit: 100 +CREATE TABLE fkpart13_t2_p1 PARTITION OF fkpart13_t2 FOR VALUES IN (1) +-- +TABLE: name="fkpart13_t2_p1" schema="" table="fkpart13_t2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart13_t2_p1 PARTITION OF fkpart13_t2 FOR VALUES IN (1)" +== 1143 +-- truncate_limit: 100 +-- drop the column +ALTER TABLE fkpart13_t2 DROP COLUMN column_to_drop +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkpart13_t2 DROP column_to_drop" +== 1144 +-- truncate_limit: 100 +-- create a new partition without the dropped column +CREATE TABLE fkpart13_t2_p2 PARTITION OF fkpart13_t2 FOR VALUES IN (2) +-- +TABLE: name="fkpart13_t2_p2" schema="" table="fkpart13_t2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart13_t2_p2 PARTITION OF fkpart13_t2 FOR VALUES IN (2)" +== 1145 +-- truncate_limit: 100 +CREATE TABLE fkpart13_t3 ( + a int NOT NULL, + FOREIGN KEY (a) + REFERENCES fkpart13_t2 + ON UPDATE CASCADE ON DELETE CASCADE +) +-- +TABLE: name="fkpart13_t3" schema="" table="fkpart13_t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkpart13_t3 (a int NOT NULL, FOREIGN KEY (a) REFERENCES fkpart13_t2 ON UPDATE CASCAD..." +== 1146 +-- truncate_limit: 100 +INSERT INTO fkpart13_t1 (a) VALUES (1) +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart13_t1 (a) VALUES (1)" +== 1147 +-- truncate_limit: 100 +INSERT INTO fkpart13_t2 (part_id) VALUES (1) +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart13_t2 (part_id) VALUES (1)" +== 1148 +-- truncate_limit: 100 +INSERT INTO fkpart13_t3 (a) VALUES (1) +-- +TABLE: name="fkpart13_t3" schema="" table="fkpart13_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkpart13_t3 (a) VALUES (1)" +== 1149 +-- truncate_limit: 100 +-- Test a cascading update works correctly with with the dropped column +UPDATE fkpart13_t1 SET a = 2 WHERE a = 1 +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE fkpart13_t1 SET a = 2 WHERE a = 1" +== 1150 +-- truncate_limit: 100 +SELECT tableoid::regclass,* FROM fkpart13_t2 +-- +TABLE: name="fkpart13_t2" schema="" table="fkpart13_t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM fkpart13_t2" +== 1151 +-- truncate_limit: 100 +SELECT tableoid::regclass,* FROM fkpart13_t3 +-- +TABLE: name="fkpart13_t3" schema="" table="fkpart13_t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM fkpart13_t3" +== 1152 +-- truncate_limit: 100 +-- Exercise code in ExecGetTriggerResultRel() as there's been previous issues +-- with ResultRelInfos being returned with the incorrect ri_RootResultRelInfo +WITH cte AS ( + UPDATE fkpart13_t2_p1 SET part_id = part_id +) UPDATE fkpart13_t1 SET a = 2 WHERE a = 1 +-- +TABLE: name="fkpart13_t1" schema="" table="fkpart13_t1" ctx=DML +TABLE: name="fkpart13_t2_p1" schema="" table="fkpart13_t2_p1" ctx=DML +CTE: "cte" +STMT: UpdateStmt +TRUNCATED: "WITH cte AS (UPDATE fkpart13_t2_p1 SET part_id = part_id) UPDATE fkpart13_t1 SET a = 2 WHERE a = 1" +== 1153 +-- truncate_limit: 100 +DROP SCHEMA fkpart13 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA fkpart13 CASCADE" +== 1154 +-- truncate_limit: 100 +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" diff --git a/parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json b/parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/functional_deps.test b/parser/testdata/summary_truncate/postgres_regress/functional_deps.test new file mode 100644 index 0000000..e0be077 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/functional_deps.test @@ -0,0 +1,475 @@ +== 001 +-- truncate_limit: 100 +-- from http://www.depesz.com/index.php/2010/04/19/getting-unique-elements/ + +CREATE TEMP TABLE articles ( + id int CONSTRAINT articles_pkey PRIMARY KEY, + keywords text, + title text UNIQUE NOT NULL, + body text UNIQUE, + created date +) +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE articles (id int CONSTRAINT articles_pkey PRIMARY KEY, keywords text, titl..." +== 002 +-- truncate_limit: 100 +CREATE TEMP TABLE articles_in_category ( + article_id int, + category_id int, + changed date, + PRIMARY KEY (article_id, category_id) +) +-- +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE articles_in_category (article_id int, category_id int, changed date, PRIMA..." +== 003 +-- truncate_limit: 100 +-- test functional dependencies based on primary keys/unique constraints + +-- base tables + +-- group by primary key (OK) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, keywords, title, body, created FROM articles GROUP BY id" +== 004 +-- truncate_limit: 100 +-- group by unique not null (fail/todo) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY title +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, keywords, title, body, created FROM articles GROUP BY title" +== 005 +-- truncate_limit: 100 +-- group by unique nullable (fail) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY body +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, keywords, title, body, created FROM articles GROUP BY body" +== 006 +-- truncate_limit: 100 +-- group by something else (fail) +SELECT id, keywords, title, body, created +FROM articles +GROUP BY keywords +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, keywords, title, body, created FROM articles GROUP BY keywords" +== 007 +-- truncate_limit: 100 +-- multiple tables + +-- group by primary key (OK) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a, articles_in_category AS aic +WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138) +GROUP BY a.id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="aic" column="article_id" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM articles a, articles_in_category aic WHERE ... GROUP BY a.id" +== 008 +-- truncate_limit: 100 +-- group by something else (fail) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a, articles_in_category AS aic +WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id, aic.category_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="aic" column="article_id" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM articles a, articles_in_category aic WHERE ... GROUP BY aic.article_id, aic.categ..." +== 009 +-- truncate_limit: 100 +-- JOIN syntax + +-- group by left table's primary key (OK) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY a.id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM articles a JOIN articles_in_category aic ON a.id = aic.article_id WHERE ... GROUP..." +== 010 +-- truncate_limit: 100 +-- group by something else (fail) +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id, aic.category_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM articles a JOIN articles_in_category aic ON a.id = aic.article_id WHERE ... GROUP..." +== 011 +-- truncate_limit: 100 +-- group by right table's (composite) primary key (OK) +SELECT aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.category_id, aic.article_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM articles a JOIN articles_in_category aic ON a.id = aic.article_id WHERE ... GROUP..." +== 012 +-- truncate_limit: 100 +-- group by right table's partial primary key (fail) +SELECT aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM articles a JOIN articles_in_category aic ON a.id = aic.article_id WHERE ... GROUP..." +== 013 +-- truncate_limit: 100 +-- example from documentation + +CREATE TEMP TABLE products (product_id int, name text, price numeric) +-- +TABLE: name="products" schema="" table="products" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE products (product_id int, name text, price numeric)" +== 014 +-- truncate_limit: 100 +CREATE TEMP TABLE sales (product_id int, units int) +-- +TABLE: name="sales" schema="" table="sales" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE sales (product_id int, units int)" +== 015 +-- truncate_limit: 100 +-- OK +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id, p.name, p.price +-- +TABLE: name="products" schema="" table="products" ctx=Select +TABLE: name="sales" schema="" table="sales" ctx=Select +ALIAS: "p"="products" +ALIAS: "s"="sales" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM products p LEFT JOIN sales s USING (product_id) GROUP BY product_id, p.name, p.price" +== 016 +-- truncate_limit: 100 +-- fail +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id +-- +TABLE: name="products" schema="" table="products" ctx=Select +TABLE: name="sales" schema="" table="sales" ctx=Select +ALIAS: "p"="products" +ALIAS: "s"="sales" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM products p LEFT JOIN sales s USING (product_id) GROUP BY product_id" +== 017 +-- truncate_limit: 100 +ALTER TABLE products ADD PRIMARY KEY (product_id) +-- +TABLE: name="products" schema="" table="products" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE products ADD PRIMARY KEY (product_id)" +== 018 +-- truncate_limit: 100 +-- OK now +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id +-- +TABLE: name="products" schema="" table="products" ctx=Select +TABLE: name="sales" schema="" table="sales" ctx=Select +ALIAS: "p"="products" +ALIAS: "s"="sales" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM products p LEFT JOIN sales s USING (product_id) GROUP BY product_id" +== 019 +-- truncate_limit: 100 +-- Drupal example, http://drupal.org/node/555530 + +CREATE TEMP TABLE node ( + nid SERIAL, + vid integer NOT NULL default '0', + type varchar(32) NOT NULL default '', + title varchar(128) NOT NULL default '', + uid integer NOT NULL default '0', + status integer NOT NULL default '1', + created integer NOT NULL default '0', + -- snip + PRIMARY KEY (nid, vid) +) +-- +TABLE: name="node" schema="" table="node" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE node (nid serial, vid int NOT NULL DEFAULT '0', type varchar(32) NOT NULL ..." +== 020 +-- truncate_limit: 100 +CREATE TEMP TABLE users ( + uid integer NOT NULL default '0', + name varchar(60) NOT NULL default '', + pass varchar(32) NOT NULL default '', + -- snip + PRIMARY KEY (uid), + UNIQUE (name) +) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE users (uid int NOT NULL DEFAULT '0', name varchar(60) NOT NULL DEFAULT '',..." +== 021 +-- truncate_limit: 100 +-- OK +SELECT u.uid, u.name FROM node n +INNER JOIN users u ON u.uid = n.uid +WHERE n.type = 'blog' AND n.status = 1 +GROUP BY u.uid, u.name +-- +TABLE: name="node" schema="" table="node" ctx=Select +TABLE: name="users" schema="" table="users" ctx=Select +ALIAS: "n"="node" +ALIAS: "u"="users" +FILTER: schema="" table="n" column="type" +FILTER: schema="" table="n" column="status" +STMT: SelectStmt +TRUNCATED: "SELECT u.uid, u.name FROM node n JOIN users u ON u.uid = n.uid WHERE ... GROUP BY u.uid, u.name" +== 022 +-- truncate_limit: 100 +-- OK +SELECT u.uid, u.name FROM node n +INNER JOIN users u ON u.uid = n.uid +WHERE n.type = 'blog' AND n.status = 1 +GROUP BY u.uid +-- +TABLE: name="node" schema="" table="node" ctx=Select +TABLE: name="users" schema="" table="users" ctx=Select +ALIAS: "n"="node" +ALIAS: "u"="users" +FILTER: schema="" table="n" column="type" +FILTER: schema="" table="n" column="status" +STMT: SelectStmt +TRUNCATED: "SELECT u.uid, u.name FROM node n JOIN users u ON u.uid = n.uid WHERE ... GROUP BY u.uid" +== 023 +-- truncate_limit: 100 +-- Check views and dependencies + +-- fail +CREATE TEMP VIEW fdv1 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY body +-- +TABLE: name="fdv1" schema="" table="fdv1" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW fdv1 AS SELECT id, keywords, title, body, created FROM articles GROUP BY body" +== 024 +-- truncate_limit: 100 +-- OK +CREATE TEMP VIEW fdv1 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +-- +TABLE: name="fdv1" schema="" table="fdv1" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW fdv1 AS SELECT id, keywords, title, body, created FROM articles GROUP BY id" +== 025 +-- truncate_limit: 100 +-- fail +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE articles DROP CONSTRAINT articles_pkey" +== 026 +-- truncate_limit: 100 +DROP VIEW fdv1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW fdv1" +== 027 +-- truncate_limit: 100 +-- multiple dependencies +CREATE TEMP VIEW fdv2 AS +SELECT a.id, a.keywords, a.title, aic.category_id, aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY a.id, aic.category_id, aic.article_id +-- +TABLE: name="fdv2" schema="" table="fdv2" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=Select +ALIAS: "a"="articles" +ALIAS: "aic"="articles_in_category" +FILTER: schema="" table="aic" column="category_id" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW fdv2 AS SELECT a.id, a.keywords, a.title, aic.category_id, aic.changed FROM..." +== 028 +-- truncate_limit: 100 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE articles DROP CONSTRAINT articles_pkey" +== 029 +-- truncate_limit: 100 +-- fail +ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey RESTRICT +-- +TABLE: name="articles_in_category" schema="" table="articles_in_category" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey" +== 030 +-- truncate_limit: 100 +--fail + +DROP VIEW fdv2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW fdv2" +== 031 +-- truncate_limit: 100 +-- nested queries + +CREATE TEMP VIEW fdv3 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +UNION +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +-- +TABLE: name="fdv3" schema="" table="fdv3" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW fdv3 AS SELECT id, keywords, title, body, created FROM articles GROUP BY id..." +== 032 +-- truncate_limit: 100 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE articles DROP CONSTRAINT articles_pkey" +== 033 +-- truncate_limit: 100 +-- fail + +DROP VIEW fdv3 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW fdv3" +== 034 +-- truncate_limit: 100 +CREATE TEMP VIEW fdv4 AS +SELECT * FROM articles WHERE title IN (SELECT title FROM articles GROUP BY id) +-- +TABLE: name="fdv4" schema="" table="fdv4" ctx=DDL +TABLE: name="articles" schema="" table="articles" ctx=Select +TABLE: name="articles" schema="" table="articles" ctx=Select +FILTER: schema="" table="" column="title" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW fdv4 AS SELECT * FROM articles WHERE title IN (SELECT title FROM articles G..." +== 035 +-- truncate_limit: 100 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE articles DROP CONSTRAINT articles_pkey" +== 036 +-- truncate_limit: 100 +-- fail + +DROP VIEW fdv4 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW fdv4" +== 037 +-- truncate_limit: 100 +-- prepared query plans: this results in failure on reuse + +PREPARE foo AS + SELECT id, keywords, title, body, created + FROM articles + GROUP BY id +-- +TABLE: name="articles" schema="" table="articles" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE foo AS SELECT id, keywords, title, body, created FROM articles GROUP BY id" +== 038 +-- truncate_limit: 100 +EXECUTE foo +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo" +== 039 +-- truncate_limit: 100 +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT +-- +TABLE: name="articles" schema="" table="articles" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE articles DROP CONSTRAINT articles_pkey" +== 040 +-- truncate_limit: 100 +EXECUTE foo +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo" diff --git a/parser/testdata/summary_truncate/postgres_regress/generated.metadata.json b/parser/testdata/summary_truncate/postgres_regress/generated.metadata.json new file mode 100644 index 0000000..b6ecb7b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/generated.metadata.json @@ -0,0 +1,123 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/generated.test b/parser/testdata/summary_truncate/postgres_regress/generated.test new file mode 100644 index 0000000..d389a23 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/generated.test @@ -0,0 +1,936 @@ +== 001 +-- truncate_limit: 100 +-- sanity check of system catalog +SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's') +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attgenerated" +STMT: SelectStmt +TRUNCATED: "SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's')" +== 002 +-- truncate_limit: 100 +CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED) +-- +TABLE: name="gtest0" schema="" table="gtest0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED)" +== 003 +-- truncate_limit: 100 +CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED)" +== 004 +-- truncate_limit: 100 +SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_name LIKE 'gtest_' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name LIKE 'gtest_' ORDER BY 1, 2" +== 005 +-- truncate_limit: 100 +SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.column_column_usage" schema="information_schema" table="column_column_usage" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.column_column_usage ORDER BY 1, 2, 3" +== 006 +-- truncate_limit: 100 +-- duplicate generated +CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED) +-- +TABLE: name="gtest_err_1" schema="" table="gtest_err_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED A..." +== 007 +-- truncate_limit: 100 +-- references to other generated columns, including self-references +CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED) +-- +TABLE: name="gtest_err_2a" schema="" table="gtest_err_2a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED)" +== 008 +-- truncate_limit: 100 +CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED) +-- +TABLE: name="gtest_err_2b" schema="" table="gtest_err_2b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GEN..." +== 009 +-- truncate_limit: 100 +-- a whole-row var is a self-reference on steroids, so disallow that too +CREATE TABLE gtest_err_2c (a int PRIMARY KEY, + b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STORED) +-- +TABLE: name="gtest_err_2c" schema="" table="gtest_err_2c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_2c (a int PRIMARY KEY, b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c))..." +== 010 +-- truncate_limit: 100 +-- invalid reference +CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED) +-- +TABLE: name="gtest_err_3" schema="" table="gtest_err_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED)" +== 011 +-- truncate_limit: 100 +-- generation expression must be immutable +CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED) +-- +TABLE: name="gtest_err_4" schema="" table="gtest_err_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) ST..." +== 012 +-- truncate_limit: 100 +-- ... but be sure that the immutability test is accurate +CREATE TABLE gtest2 (a int, b text GENERATED ALWAYS AS (a || ' sec') STORED) +-- +TABLE: name="gtest2" schema="" table="gtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest2 (a int, b text GENERATED ALWAYS AS (a || ' sec') STORED)" +== 013 +-- truncate_limit: 100 +DROP TABLE gtest2 +-- +TABLE: name="gtest2" schema="" table="gtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gtest2" +== 014 +-- truncate_limit: 100 +-- cannot have default/identity and generated +CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest_err_5a" schema="" table="gtest_err_5a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED)" +== 015 +-- truncate_limit: 100 +CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest_err_5b" schema="" table="gtest_err_5b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS IDENTITY GENERATED ALWAYS..." +== 016 +-- truncate_limit: 100 +-- reference to system column not allowed in generated column +-- (except tableoid, which we test below) +CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED) +-- +TABLE: name="gtest_err_6a" schema="" table="gtest_err_6a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED)" +== 017 +-- truncate_limit: 100 +-- various prohibited constructs +CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED) +-- +TABLE: name="gtest_err_7a" schema="" table="gtest_err_7a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED)" +== 018 +-- truncate_limit: 100 +CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED) +-- +TABLE: name="gtest_err_7b" schema="" table="gtest_err_7b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER..." +== 019 +-- truncate_limit: 100 +CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED) +-- +TABLE: name="gtest_err_7c" schema="" table="gtest_err_7c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED)" +== 020 +-- truncate_limit: 100 +CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED) +-- +TABLE: name="gtest_err_7d" schema="" table="gtest_err_7d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) S..." +== 021 +-- truncate_limit: 100 +-- GENERATED BY DEFAULT not allowed +CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED) +-- +ERROR: for a generated column, GENERATED ALWAYS must be specified +CURSORPOS: 98 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 022 +-- truncate_limit: 100 +INSERT INTO gtest1 VALUES (1) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (1)" +== 023 +-- truncate_limit: 100 +INSERT INTO gtest1 VALUES (2, DEFAULT) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (2, DEFAULT)" +== 024 +-- truncate_limit: 100 +-- ok +INSERT INTO gtest1 VALUES (3, 33) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (3, 33)" +== 025 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1 VALUES (3, 33), (4, 44) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (3, 33), (4, 44)" +== 026 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, 44) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (3, DEFAULT), (4, 44)" +== 027 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT)" +== 028 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT)" +== 029 +-- truncate_limit: 100 +-- ok + +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1 ORDER BY a" +== 030 +-- truncate_limit: 100 +DELETE FROM gtest1 WHERE a >= 3 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gtest1 WHERE a >= 3" +== 031 +-- truncate_limit: 100 +UPDATE gtest1 SET b = DEFAULT WHERE a = 1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE gtest1 SET b = DEFAULT WHERE a = 1" +== 032 +-- truncate_limit: 100 +UPDATE gtest1 SET b = 11 WHERE a = 1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE gtest1 SET b = 11 WHERE a = 1" +== 033 +-- truncate_limit: 100 +-- error + +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1 ORDER BY a" +== 034 +-- truncate_limit: 100 +SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a" +== 035 +-- truncate_limit: 100 +SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a" +== 036 +-- truncate_limit: 100 +-- test that overflow error happens on write +INSERT INTO gtest1 VALUES (2000000000) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 VALUES (2000000000)" +== 037 +-- truncate_limit: 100 +SELECT * FROM gtest1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1" +== 038 +-- truncate_limit: 100 +DELETE FROM gtest1 WHERE a = 2000000000 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gtest1 WHERE a = 2000000000" +== 039 +-- truncate_limit: 100 +-- test with joins +CREATE TABLE gtestx (x int, y int) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestx (x int, y int)" +== 040 +-- truncate_limit: 100 +INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3)" +== 041 +-- truncate_limit: 100 +SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=Select +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +FILTER: schema="" table="gtestx" column="y" +FILTER: schema="" table="gtest1" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a" +== 042 +-- truncate_limit: 100 +DROP TABLE gtestx +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gtestx" +== 043 +-- truncate_limit: 100 +-- test UPDATE/DELETE quals +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1 ORDER BY a" +== 044 +-- truncate_limit: 100 +UPDATE gtest1 SET a = 3 WHERE b = 4 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE gtest1 SET a = 3 WHERE b = 4" +== 045 +-- truncate_limit: 100 +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1 ORDER BY a" +== 046 +-- truncate_limit: 100 +DELETE FROM gtest1 WHERE b = 2 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gtest1 WHERE b = 2" +== 047 +-- truncate_limit: 100 +SELECT * FROM gtest1 ORDER BY a +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1 ORDER BY a" +== 048 +-- truncate_limit: 100 +-- test MERGE +CREATE TABLE gtestm ( + id int PRIMARY KEY, + f1 int, + f2 int, + f3 int GENERATED ALWAYS AS (f1 * 2) STORED, + f4 int GENERATED ALWAYS AS (f2 * 2) STORED +) +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestm (id int PRIMARY KEY, f1 int, f2 int, f3 int GENERATED ALWAYS AS (f1 * 2) STOR..." +== 049 +-- truncate_limit: 100 +INSERT INTO gtestm VALUES (1, 5, 100) +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtestm VALUES (1, 5, 100)" +== 050 +-- truncate_limit: 100 +MERGE INTO gtestm t USING (VALUES (1, 10), (2, 20)) v(id, f1) ON t.id = v.id + WHEN MATCHED THEN UPDATE SET f1 = v.f1 + WHEN NOT MATCHED THEN INSERT VALUES (v.id, v.f1, 200) +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DML +ALIAS: "t"="gtestm" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO gtestm t USING (VALUES (...)) v(id, f1) ON t.id = v.id WHEN MATCHED THEN UPDATE SET f1..." +== 051 +-- truncate_limit: 100 +SELECT * FROM gtestm ORDER BY id +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtestm ORDER BY id" +== 052 +-- truncate_limit: 100 +DROP TABLE gtestm +-- +TABLE: name="gtestm" schema="" table="gtestm" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gtestm" +== 053 +-- truncate_limit: 100 +-- views +CREATE VIEW gtest1v AS SELECT * FROM gtest1 +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DDL +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW gtest1v AS SELECT * FROM gtest1" +== 054 +-- truncate_limit: 100 +SELECT * FROM gtest1v +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1v" +== 055 +-- truncate_limit: 100 +INSERT INTO gtest1v VALUES (4, 8) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (4, 8)" +== 056 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1v VALUES (5, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (5, DEFAULT)" +== 057 +-- truncate_limit: 100 +-- ok +INSERT INTO gtest1v VALUES (6, 66), (7, 77) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (6, 66), (7, 77)" +== 058 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, 77) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (6, DEFAULT), (7, 77)" +== 059 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1v VALUES (6, 66), (7, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (6, 66), (7, DEFAULT)" +== 060 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (6, DEFAULT), (7, DEFAULT)" +== 061 +-- truncate_limit: 100 +-- ok + +ALTER VIEW gtest1v ALTER COLUMN b SET DEFAULT 100 +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW gtest1v ALTER COLUMN b SET DEFAULT 100" +== 062 +-- truncate_limit: 100 +INSERT INTO gtest1v VALUES (8, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (8, DEFAULT)" +== 063 +-- truncate_limit: 100 +-- error +INSERT INTO gtest1v VALUES (8, DEFAULT), (9, DEFAULT) +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1v VALUES (8, DEFAULT), (9, DEFAULT)" +== 064 +-- truncate_limit: 100 +-- error + +SELECT * FROM gtest1v +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1v" +== 065 +-- truncate_limit: 100 +DELETE FROM gtest1v WHERE a >= 5 +-- +TABLE: name="gtest1v" schema="" table="gtest1v" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gtest1v WHERE a >= 5" +== 066 +-- truncate_limit: 100 +DROP VIEW gtest1v +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW gtest1v" +== 067 +-- truncate_limit: 100 +-- CTEs +WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +CTE: "foo" +STMT: SelectStmt +TRUNCATED: "WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo" +== 068 +-- truncate_limit: 100 +-- inheritance +CREATE TABLE gtest1_1 () INHERITS (gtest1) +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest1_1 () INHERITS (gtest1)" +== 069 +-- truncate_limit: 100 +SELECT * FROM gtest1_1 +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1_1" +== 070 +-- truncate_limit: 100 +INSERT INTO gtest1_1 VALUES (4) +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1_1 VALUES (4)" +== 071 +-- truncate_limit: 100 +SELECT * FROM gtest1_1 +-- +TABLE: name="gtest1_1" schema="" table="gtest1_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1_1" +== 072 +-- truncate_limit: 100 +SELECT * FROM gtest1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest1" +== 073 +-- truncate_limit: 100 +-- can't have generated column that is a child of normal column +CREATE TABLE gtest_normal (a int, b int) +-- +TABLE: name="gtest_normal" schema="" table="gtest_normal" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_normal (a int, b int)" +== 074 +-- truncate_limit: 100 +CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) INHERITS (gtest_normal) +-- +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) INHERITS (gtest..." +== 075 +-- truncate_limit: 100 +-- error +CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED)" +== 076 +-- truncate_limit: 100 +ALTER TABLE gtest_normal_child INHERIT gtest_normal +-- +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gtest_normal_child INHERIT gtest_normal" +== 077 +-- truncate_limit: 100 +-- error +DROP TABLE gtest_normal, gtest_normal_child +-- +TABLE: name="gtest_normal" schema="" table="gtest_normal" ctx=DDL +TABLE: name="gtest_normal_child" schema="" table="gtest_normal_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gtest_normal, gtest_normal_child" +== 078 +-- truncate_limit: 100 +-- test inheritance mismatches between parent and child +CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1)" +== 079 +-- truncate_limit: 100 +-- error +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1)" +== 080 +-- truncate_limit: 100 +-- error +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1) +-- +TABLE: name="gtestx" schema="" table="gtestx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1)" +== 081 +-- truncate_limit: 100 +-- ok, overrides parent + +CREATE TABLE gtestxx_1 (a int NOT NULL, b int) +-- +TABLE: name="gtestxx_1" schema="" table="gtestxx_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestxx_1 (a int NOT NULL, b int)" +== 082 +-- truncate_limit: 100 +ALTER TABLE gtestxx_1 INHERIT gtest1 +-- +TABLE: name="gtestxx_1" schema="" table="gtestxx_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gtestxx_1 INHERIT gtest1" +== 083 +-- truncate_limit: 100 +-- error +CREATE TABLE gtestxx_3 (a int NOT NULL, b int GENERATED ALWAYS AS (a * 2) STORED) +-- +TABLE: name="gtestxx_3" schema="" table="gtestxx_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestxx_3 (a int NOT NULL, b int GENERATED ALWAYS AS (a * 2) STORED)" +== 084 +-- truncate_limit: 100 +ALTER TABLE gtestxx_3 INHERIT gtest1 +-- +TABLE: name="gtestxx_3" schema="" table="gtestxx_3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gtestxx_3 INHERIT gtest1" +== 085 +-- truncate_limit: 100 +-- ok +CREATE TABLE gtestxx_4 (b int GENERATED ALWAYS AS (a * 2) STORED, a int NOT NULL) +-- +TABLE: name="gtestxx_4" schema="" table="gtestxx_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestxx_4 (b int GENERATED ALWAYS AS (a * 2) STORED, a int NOT NULL)" +== 086 +-- truncate_limit: 100 +ALTER TABLE gtestxx_4 INHERIT gtest1 +-- +TABLE: name="gtestxx_4" schema="" table="gtestxx_4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gtestxx_4 INHERIT gtest1" +== 087 +-- truncate_limit: 100 +-- ok + +-- test multiple inheritance mismatches +CREATE TABLE gtesty (x int, b int DEFAULT 55) +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtesty (x int, b int DEFAULT 55)" +== 088 +-- truncate_limit: 100 +CREATE TABLE gtest1_y () INHERITS (gtest0, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest1_y () INHERITS (gtest0, gtesty)" +== 089 +-- truncate_limit: 100 +-- error +DROP TABLE gtesty +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gtesty" +== 090 +-- truncate_limit: 100 +CREATE TABLE gtesty (x int, b int) +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtesty (x int, b int)" +== 091 +-- truncate_limit: 100 +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty)" +== 092 +-- truncate_limit: 100 +-- error +DROP TABLE gtesty +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gtesty" +== 093 +-- truncate_limit: 100 +CREATE TABLE gtesty (x int, b int GENERATED ALWAYS AS (x * 22) STORED) +-- +TABLE: name="gtesty" schema="" table="gtesty" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtesty (x int, b int GENERATED ALWAYS AS (x * 22) STORED)" +== 094 +-- truncate_limit: 100 +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty)" +== 095 +-- truncate_limit: 100 +-- error +CREATE TABLE gtest1_y (b int GENERATED ALWAYS AS (x + 1) STORED) INHERITS (gtest1, gtesty) +-- +TABLE: name="gtest1_y" schema="" table="gtest1_y" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest1_y (b int GENERATED ALWAYS AS (x + 1) STORED) INHERITS (gtest1, gtesty)" +== 096 +-- truncate_limit: 100 +-- ok + +-- test correct handling of GENERATED column that's only in child +CREATE TABLE gtestp (f1 int) +-- +TABLE: name="gtestp" schema="" table="gtestp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestp (f1 int)" +== 097 +-- truncate_limit: 100 +CREATE TABLE gtestc (f2 int GENERATED ALWAYS AS (f1+1) STORED) INHERITS(gtestp) +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtestc (f2 int GENERATED ALWAYS AS (f1 + 1) STORED) INHERITS (gtestp)" +== 098 +-- truncate_limit: 100 +INSERT INTO gtestc values(42) +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtestc VALUES (42)" +== 099 +-- truncate_limit: 100 +TABLE gtestc +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtestc" +== 100 +-- truncate_limit: 100 +UPDATE gtestp SET f1 = f1 * 10 +-- +TABLE: name="gtestp" schema="" table="gtestp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE gtestp SET f1 = f1 * 10" +== 101 +-- truncate_limit: 100 +TABLE gtestc +-- +TABLE: name="gtestc" schema="" table="gtestc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtestc" +== 102 +-- truncate_limit: 100 +DROP TABLE gtestp CASCADE +-- +TABLE: name="gtestp" schema="" table="gtestp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gtestp CASCADE" +== 103 +-- truncate_limit: 100 +-- test stored update +CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED) +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED)" +== 104 +-- truncate_limit: 100 +INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL) +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL)" +== 105 +-- truncate_limit: 100 +SELECT * FROM gtest3 ORDER BY a +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest3 ORDER BY a" +== 106 +-- truncate_limit: 100 +UPDATE gtest3 SET a = 22 WHERE a = 2 +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE gtest3 SET a = 22 WHERE a = 2" +== 107 +-- truncate_limit: 100 +SELECT * FROM gtest3 ORDER BY a +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest3 ORDER BY a" +== 108 +-- truncate_limit: 100 +CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS (a || '+' || a) STORED) +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS ((a || '+') || a) STORED)" +== 109 +-- truncate_limit: 100 +INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL) +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL)" +== 110 +-- truncate_limit: 100 +SELECT * FROM gtest3a ORDER BY a +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest3a ORDER BY a" +== 111 +-- truncate_limit: 100 +UPDATE gtest3a SET a = 'bb' WHERE a = 'b' +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE gtest3a SET a = 'bb' WHERE a = 'b'" +== 112 +-- truncate_limit: 100 +SELECT * FROM gtest3a ORDER BY a +-- +TABLE: name="gtest3a" schema="" table="gtest3a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM gtest3a ORDER BY a" +== 113 +-- truncate_limit: 100 +-- COPY +TRUNCATE gtest1 +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE gtest1" +== 114 +-- truncate_limit: 100 +INSERT INTO gtest1 (a) VALUES (1), (2) +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gtest1 (a) VALUES (1), (2)" +== 115 +-- truncate_limit: 100 +COPY gtest1 TO stdout +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY gtest1 TO STDOUT" +== 116 +-- truncate_limit: 100 +COPY gtest1 (a, b) TO stdout +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY gtest1(a, b) TO STDOUT" +== 117 +-- truncate_limit: 100 +COPY gtest1 FROM stdin +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY gtest1 FROM STDIN" +== 118 +-- truncate_limit: 100 +COPY gtest1 (a, b) FROM stdin +-- +TABLE: name="gtest1" schema="" table="gtest1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY gtest1(a, b) FROM STDIN" +== 119 +-- truncate_limit: 100 +COPY gtest3 (a, b) FROM stdin +-- +TABLE: name="gtest3" schema="" table="gtest3" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY gtest3(a, b) FROM STDIN" diff --git a/parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json b/parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json new file mode 100644 index 0000000..4e31a92 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json @@ -0,0 +1,166 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/geometry.test b/parser/testdata/summary_truncate/postgres_regress/geometry.test new file mode 100644 index 0000000..1ea7864 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/geometry.test @@ -0,0 +1,1894 @@ +== 001 +-- truncate_limit: 100 +|-- +-- GEOMETRY +|-- + +-- Back off displayed precision a little bit to reduce platform-to-platform +-- variation in results. +SET extra_float_digits TO -3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO -3" +== 002 +-- truncate_limit: 100 +|-- +-- Points +|-- + +SELECT center(f1) AS center + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="center" function="center" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT center(f1) AS center FROM box_tbl" +== 003 +-- truncate_limit: 100 +SELECT (@@ f1) AS center + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT @@ f1 AS center FROM box_tbl" +== 004 +-- truncate_limit: 100 +SELECT point(f1) AS center + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT point(f1) AS center FROM circle_tbl" +== 005 +-- truncate_limit: 100 +SELECT (@@ f1) AS center + FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT @@ f1 AS center FROM circle_tbl" +== 006 +-- truncate_limit: 100 +SELECT (@@ f1) AS center + FROM POLYGON_TBL + WHERE (# f1) > 2 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT @@ f1 AS center FROM polygon_tbl WHERE (# f1) > 2" +== 007 +-- truncate_limit: 100 +-- "is horizontal" function +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE ishorizontal(p1.f1, point '(0,0)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FUNCTION: name="ishorizontal" function="ishorizontal" schema="" ctx=Call +FUNCTION: name="ishorizontal" function="ishorizontal" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1 FROM point_tbl p1 WHERE ishorizontal(p1.f1, point '(0,0)')" +== 008 +-- truncate_limit: 100 +-- "is horizontal" operator +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE p1.f1 ?- point '(0,0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1 FROM point_tbl p1 WHERE p1.f1 ?- point '(0,0)'" +== 009 +-- truncate_limit: 100 +-- "is vertical" function +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE isvertical(p1.f1, point '(5.1,34.5)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FUNCTION: name="isvertical" function="isvertical" schema="" ctx=Call +FUNCTION: name="isvertical" function="isvertical" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1 FROM point_tbl p1 WHERE isvertical(p1.f1, point '(5.1,34.5)')" +== 010 +-- truncate_limit: 100 +-- "is vertical" operator +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE p1.f1 ?| point '(5.1,34.5)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1 FROM point_tbl p1 WHERE p1.f1 ?| point '(5.1,34.5)'" +== 011 +-- truncate_limit: 100 +-- Slope +SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FUNCTION: name="slope" function="slope" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM point_tbl p1, point_tbl p2" +== 012 +-- truncate_limit: 100 +-- Add point +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM point_tbl p1, point_tbl p2" +== 013 +-- truncate_limit: 100 +-- Subtract point +SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM point_tbl p1, point_tbl p2" +== 014 +-- truncate_limit: 100 +-- Multiply with point +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM point_tbl p1, point_tbl p2 WHERE p1.f1[0] BETWEEN 1 AND 1000" +== 015 +-- truncate_limit: 100 +-- Underflow error +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] < 1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM point_tbl p1, point_tbl p2 WHERE p1.f1[0] < 1" +== 016 +-- truncate_limit: 100 +-- Divide by point +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM point_tbl p1, point_tbl p2 WHERE p2.f1[0] BETWEEN 1 AND 1000" +== 017 +-- truncate_limit: 100 +-- Overflow error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] > 1000 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM point_tbl p1, point_tbl p2 WHERE p2.f1[0] > 1000" +== 018 +-- truncate_limit: 100 +-- Division by 0 error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1 ~= '(0,0)'::point +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM point_tbl p1, point_tbl p2 WHERE p2.f1 ~= '(0,0)'::point" +== 019 +-- truncate_limit: 100 +-- Distance to line +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TBL p, LINE_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM point_tbl p, line_tbl l" +== 020 +-- truncate_limit: 100 +-- Distance to line segment +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TBL p, LSEG_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM point_tbl p, lseg_tbl l" +== 021 +-- truncate_limit: 100 +-- Distance to box +SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT_TBL p, BOX_TBL b +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM point_tbl p, box_tbl b" +== 022 +-- truncate_limit: 100 +-- Distance to path +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp FROM POINT_TBL p, PATH_TBL p1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "p1"="path_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM point_tbl p, path_tbl p1" +== 023 +-- truncate_limit: 100 +-- Distance to polygon +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp FROM POINT_TBL p, POLYGON_TBL p1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "p1"="polygon_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM point_tbl p, polygon_tbl p1" +== 024 +-- truncate_limit: 100 +-- Construct line through two points +SELECT p1.f1, p2.f1, line(p1.f1, p2.f1) + FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1 <> p2.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FUNCTION: name="line" function="line" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, line(p1.f1, p2.f1) FROM point_tbl p1, point_tbl p2 WHERE p1.f1 <> p2.f1" +== 025 +-- truncate_limit: 100 +-- Closest point to line +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, l.s, p.f1 ## l.s FROM point_tbl p, line_tbl l" +== 026 +-- truncate_limit: 100 +-- Closest point to line segment +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, l.s, p.f1 ## l.s FROM point_tbl p, lseg_tbl l" +== 027 +-- truncate_limit: 100 +-- Closest point to box +SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, b.f1, p.f1 ## b.f1 FROM point_tbl p, box_tbl b" +== 028 +-- truncate_limit: 100 +-- On line +SELECT p.f1, l.s FROM POINT_TBL p, LINE_TBL l WHERE p.f1 <@ l.s +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +FILTER: schema="" table="l" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, l.s FROM point_tbl p, line_tbl l WHERE p.f1 <@ l.s" +== 029 +-- truncate_limit: 100 +-- On line segment +SELECT p.f1, l.s FROM POINT_TBL p, LSEG_TBL l WHERE p.f1 <@ l.s +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +FILTER: schema="" table="l" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, l.s FROM point_tbl p, lseg_tbl l WHERE p.f1 <@ l.s" +== 030 +-- truncate_limit: 100 +-- On path +SELECT p.f1, p1.f1 FROM POINT_TBL p, PATH_TBL p1 WHERE p.f1 <@ p1.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "p1"="path_tbl" +FILTER: schema="" table="p" column="f1" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, p1.f1 FROM point_tbl p, path_tbl p1 WHERE p.f1 <@ p1.f1" +== 031 +-- truncate_limit: 100 +|-- +-- Lines +|-- + +-- Vertical +SELECT s FROM LINE_TBL WHERE ?| s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT s FROM line_tbl WHERE ?| s" +== 032 +-- truncate_limit: 100 +-- Horizontal +SELECT s FROM LINE_TBL WHERE ?- s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT s FROM line_tbl WHERE ?- s" +== 033 +-- truncate_limit: 100 +-- Same as line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s = l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM line_tbl l1, line_tbl l2 WHERE l1.s = l2.s" +== 034 +-- truncate_limit: 100 +-- Parallel to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?|| l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM line_tbl l1, line_tbl l2 WHERE l1.s ?|| l2.s" +== 035 +-- truncate_limit: 100 +-- Perpendicular to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?-| l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM line_tbl l1, line_tbl l2 WHERE l1.s ?-| l2.s" +== 036 +-- truncate_limit: 100 +-- Distance to line +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s, l1.s <-> l2.s FROM line_tbl l1, line_tbl l2" +== 037 +-- truncate_limit: 100 +-- Intersect with line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM line_tbl l1, line_tbl l2 WHERE l1.s ?# l2.s" +== 038 +-- truncate_limit: 100 +-- Intersect with box +SELECT l.s, b.f1 FROM LINE_TBL l, BOX_TBL b WHERE l.s ?# b.f1 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="line_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, b.f1 FROM line_tbl l, box_tbl b WHERE l.s ?# b.f1" +== 039 +-- truncate_limit: 100 +-- Intersection point with line +SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l1"="line_tbl" +ALIAS: "l2"="line_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s, l1.s # l2.s FROM line_tbl l1, line_tbl l2" +== 040 +-- truncate_limit: 100 +-- Closest point to line segment +SELECT l.s, l1.s, l.s ## l1.s FROM LINE_TBL l, LSEG_TBL l1 +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l"="line_tbl" +ALIAS: "l1"="lseg_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, l1.s, l.s ## l1.s FROM line_tbl l, lseg_tbl l1" +== 041 +-- truncate_limit: 100 +|-- +-- Line segments +|-- + +-- intersection +SELECT p.f1, l.s, l.s # p.f1 AS intersection + FROM LSEG_TBL l, POINT_TBL p +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, l.s, l.s # p.f1 AS intersection FROM lseg_tbl l, point_tbl p" +== 042 +-- truncate_limit: 100 +-- Length +SELECT s, @-@ s FROM LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT s, @-@ s FROM lseg_tbl" +== 043 +-- truncate_limit: 100 +-- Vertical +SELECT s FROM LSEG_TBL WHERE ?| s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT s FROM lseg_tbl WHERE ?| s" +== 044 +-- truncate_limit: 100 +-- Horizontal +SELECT s FROM LSEG_TBL WHERE ?- s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +FILTER: schema="" table="" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT s FROM lseg_tbl WHERE ?- s" +== 045 +-- truncate_limit: 100 +-- Center +SELECT s, @@ s FROM LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT s, @@ s FROM lseg_tbl" +== 046 +-- truncate_limit: 100 +-- To point +SELECT s, s::point FROM LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT s, s::point FROM lseg_tbl" +== 047 +-- truncate_limit: 100 +-- Has points less than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s < l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s < l2.s" +== 048 +-- truncate_limit: 100 +-- Has points less than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s <= l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s <= l2.s" +== 049 +-- truncate_limit: 100 +-- Has points equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s = l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s = l2.s" +== 050 +-- truncate_limit: 100 +-- Has points greater than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s >= l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s >= l2.s" +== 051 +-- truncate_limit: 100 +-- Has points greater than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s > l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s > l2.s" +== 052 +-- truncate_limit: 100 +-- Has points not equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s != l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s <> l2.s" +== 053 +-- truncate_limit: 100 +-- Parallel with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?|| l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s ?|| l2.s" +== 054 +-- truncate_limit: 100 +-- Perpendicular with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?-| l2.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +FILTER: schema="" table="l1" column="s" +FILTER: schema="" table="l2" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s FROM lseg_tbl l1, lseg_tbl l2 WHERE l1.s ?-| l2.s" +== 055 +-- truncate_limit: 100 +-- Distance to line +SELECT l.s, l1.s, l.s <-> l1.s AS dist_sl, l1.s <-> l.s AS dist_ls FROM LSEG_TBL l, LINE_TBL l1 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "l1"="line_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, l1.s, l.s <-> l1.s AS dist_sl, l1.s <-> l.s AS dist_ls FROM lseg_tbl l, line_tbl l1" +== 056 +-- truncate_limit: 100 +-- Distance to line segment +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LSEG_TBL l1, LSEG_TBL l2 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s, l1.s <-> l2.s FROM lseg_tbl l1, lseg_tbl l2" +== 057 +-- truncate_limit: 100 +-- Distance to box +SELECT l.s, b.f1, l.s <-> b.f1 AS dist_sb, b.f1 <-> l.s AS dist_bs FROM LSEG_TBL l, BOX_TBL b +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, b.f1, l.s <-> b.f1 AS dist_sb, b.f1 <-> l.s AS dist_bs FROM lseg_tbl l, box_tbl b" +== 058 +-- truncate_limit: 100 +-- Intersect with line segment +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s ?# l1.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "l1"="line_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="l1" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, l1.s FROM lseg_tbl l, line_tbl l1 WHERE l.s ?# l1.s" +== 059 +-- truncate_limit: 100 +-- Intersect with box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s ?# b.f1 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, b.f1 FROM lseg_tbl l, box_tbl b WHERE l.s ?# b.f1" +== 060 +-- truncate_limit: 100 +-- Intersection point with line segment +SELECT l1.s, l2.s, l1.s # l2.s FROM LSEG_TBL l1, LSEG_TBL l2 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s, l1.s # l2.s FROM lseg_tbl l1, lseg_tbl l2" +== 061 +-- truncate_limit: 100 +-- Closest point to line segment +SELECT l1.s, l2.s, l1.s ## l2.s FROM LSEG_TBL l1, LSEG_TBL l2 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +ALIAS: "l1"="lseg_tbl" +ALIAS: "l2"="lseg_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l1.s, l2.s, l1.s ## l2.s FROM lseg_tbl l1, lseg_tbl l2" +== 062 +-- truncate_limit: 100 +-- Closest point to box +SELECT l.s, b.f1, l.s ## b.f1 FROM LSEG_TBL l, BOX_TBL b +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, b.f1, l.s ## b.f1 FROM lseg_tbl l, box_tbl b" +== 063 +-- truncate_limit: 100 +-- On line +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s <@ l1.s +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +ALIAS: "l"="lseg_tbl" +ALIAS: "l1"="line_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="l1" column="s" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, l1.s FROM lseg_tbl l, line_tbl l1 WHERE l.s <@ l1.s" +== 064 +-- truncate_limit: 100 +-- On box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s <@ b.f1 +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "l"="lseg_tbl" +FILTER: schema="" table="l" column="s" +FILTER: schema="" table="b" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT l.s, b.f1 FROM lseg_tbl l, box_tbl b WHERE l.s <@ b.f1" +== 065 +-- truncate_limit: 100 +|-- +-- Boxes +|-- + +SELECT box(f1) AS box FROM CIRCLE_TBL +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT box(f1) AS box FROM circle_tbl" +== 066 +-- truncate_limit: 100 +-- translation +SELECT b.f1 + p.f1 AS translation + FROM BOX_TBL b, POINT_TBL p +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 + p.f1 AS translation FROM box_tbl b, point_tbl p" +== 067 +-- truncate_limit: 100 +SELECT b.f1 - p.f1 AS translation + FROM BOX_TBL b, POINT_TBL p +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1 - p.f1 AS translation FROM box_tbl b, point_tbl p" +== 068 +-- truncate_limit: 100 +-- Multiply with point +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1, p.f1, b.f1 * p.f1 FROM box_tbl b, point_tbl p WHERE p.f1[0] BETWEEN 1 AND 1000" +== 069 +-- truncate_limit: 100 +-- Overflow error +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] > 1000 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1, p.f1, b.f1 * p.f1 FROM box_tbl b, point_tbl p WHERE p.f1[0] > 1000" +== 070 +-- truncate_limit: 100 +-- Divide by point +SELECT b.f1, p.f1, b.f1 / p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "b"="box_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT b.f1, p.f1, b.f1 / p.f1 FROM box_tbl b, point_tbl p WHERE p.f1[0] BETWEEN 1 AND 1000" +== 071 +-- truncate_limit: 100 +-- To box +SELECT f1::box + FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1::box FROM point_tbl" +== 072 +-- truncate_limit: 100 +SELECT bound_box(a.f1, b.f1) + FROM BOX_TBL a, BOX_TBL b +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "a"="box_tbl" +ALIAS: "b"="box_tbl" +FUNCTION: name="bound_box" function="bound_box" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT bound_box(a.f1, b.f1) FROM box_tbl a, box_tbl b" +== 073 +-- truncate_limit: 100 +-- Below box +SELECT b1.f1, b2.f1, b1.f1 <^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT b1.f1, b2.f1, b1.f1 <^ b2.f1 FROM box_tbl b1, box_tbl b2" +== 074 +-- truncate_limit: 100 +-- Above box +SELECT b1.f1, b2.f1, b1.f1 >^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT b1.f1, b2.f1, b1.f1 >^ b2.f1 FROM box_tbl b1, box_tbl b2" +== 075 +-- truncate_limit: 100 +-- Intersection point with box +SELECT b1.f1, b2.f1, b1.f1 # b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT b1.f1, b2.f1, b1.f1 # b2.f1 FROM box_tbl b1, box_tbl b2" +== 076 +-- truncate_limit: 100 +-- Diagonal +SELECT f1, diagonal(f1) FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="diagonal" function="diagonal" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, diagonal(f1) FROM box_tbl" +== 077 +-- truncate_limit: 100 +-- Distance to box +SELECT b1.f1, b2.f1, b1.f1 <-> b2.f1 FROM BOX_TBL b1, BOX_TBL b2 +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +ALIAS: "b1"="box_tbl" +ALIAS: "b2"="box_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT b1.f1, b2.f1, b1.f1 <-> b2.f1 FROM box_tbl b1, box_tbl b2" +== 078 +-- truncate_limit: 100 +|-- +-- Paths +|-- + +-- Points +SELECT f1, npoints(f1) FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="npoints" function="npoints" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, npoints(f1) FROM path_tbl" +== 079 +-- truncate_limit: 100 +-- Area +SELECT f1, area(f1) FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="area" function="area" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, area(f1) FROM path_tbl" +== 080 +-- truncate_limit: 100 +-- Length +SELECT f1, @-@ f1 FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, @-@ f1 FROM path_tbl" +== 081 +-- truncate_limit: 100 +-- To polygon +SELECT f1, f1::polygon FROM PATH_TBL WHERE isclosed(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1::polygon FROM path_tbl WHERE isclosed(f1)" +== 082 +-- truncate_limit: 100 +-- Open path cannot be converted to polygon error +SELECT f1, f1::polygon FROM PATH_TBL WHERE isopen(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1::polygon FROM path_tbl WHERE isopen(f1)" +== 083 +-- truncate_limit: 100 +-- Has points less than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 < p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM path_tbl p1, path_tbl p2 WHERE p1.f1 < p2.f1" +== 084 +-- truncate_limit: 100 +-- Has points less than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 <= p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM path_tbl p1, path_tbl p2 WHERE p1.f1 <= p2.f1" +== 085 +-- truncate_limit: 100 +-- Has points equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 = p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM path_tbl p1, path_tbl p2 WHERE p1.f1 = p2.f1" +== 086 +-- truncate_limit: 100 +-- Has points greater than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 >= p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM path_tbl p1, path_tbl p2 WHERE p1.f1 >= p2.f1" +== 087 +-- truncate_limit: 100 +-- Has points greater than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 > p2.f1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM path_tbl p1, path_tbl p2 WHERE p1.f1 > p2.f1" +== 088 +-- truncate_limit: 100 +-- Add path +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM PATH_TBL p1, PATH_TBL p2 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM path_tbl p1, path_tbl p2" +== 089 +-- truncate_limit: 100 +-- Add point +SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM path_tbl p, point_tbl p1" +== 090 +-- truncate_limit: 100 +-- Subtract point +SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM path_tbl p, point_tbl p1" +== 091 +-- truncate_limit: 100 +-- Multiply with point +SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM path_tbl p, point_tbl p1" +== 092 +-- truncate_limit: 100 +-- Divide by point +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1[0] BETWEEN 1 AND 1000 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM path_tbl p, point_tbl p1 WHERE p1.f1[0] BETWEEN 1 AND 1000" +== 093 +-- truncate_limit: 100 +-- Division by 0 error +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1 ~= '(0,0)'::point +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="path_tbl" +ALIAS: "p1"="point_tbl" +FILTER: schema="" table="p1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM path_tbl p, point_tbl p1 WHERE p1.f1 ~= '(0,0)'::point" +== 094 +-- truncate_limit: 100 +-- Distance to path +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM PATH_TBL p1, PATH_TBL p2 +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +ALIAS: "p1"="path_tbl" +ALIAS: "p2"="path_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM path_tbl p1, path_tbl p2" +== 095 +-- truncate_limit: 100 +|-- +-- Polygons +|-- + +-- containment +SELECT p.f1, poly.f1, poly.f1 @> p.f1 AS contains + FROM POLYGON_TBL poly, POINT_TBL p +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "poly"="polygon_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, poly.f1, poly.f1 @> p.f1 AS contains FROM polygon_tbl poly, point_tbl p" +== 096 +-- truncate_limit: 100 +SELECT p.f1, poly.f1, p.f1 <@ poly.f1 AS contained + FROM POLYGON_TBL poly, POINT_TBL p +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +ALIAS: "poly"="polygon_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, poly.f1, p.f1 <@ poly.f1 AS contained FROM polygon_tbl poly, point_tbl p" +== 097 +-- truncate_limit: 100 +SELECT npoints(f1) AS npoints, f1 AS polygon + FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="npoints" function="npoints" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT npoints(f1) AS npoints, f1 AS polygon FROM polygon_tbl" +== 098 +-- truncate_limit: 100 +SELECT polygon(f1) + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polygon(f1) FROM box_tbl" +== 099 +-- truncate_limit: 100 +SELECT polygon(f1) + FROM PATH_TBL WHERE isclosed(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT polygon(f1) FROM path_tbl WHERE isclosed(f1)" +== 100 +-- truncate_limit: 100 +SELECT f1 AS open_path, polygon( pclose(f1)) AS polygon + FROM PATH_TBL + WHERE isopen(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FUNCTION: name="pclose" function="pclose" schema="" ctx=Call +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS open_path, polygon(pclose(f1)) AS polygon FROM path_tbl WHERE isopen(f1)" +== 101 +-- truncate_limit: 100 +-- To box +SELECT f1, f1::box FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1::box FROM polygon_tbl" +== 102 +-- truncate_limit: 100 +-- To path +SELECT f1, f1::path FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1::path FROM polygon_tbl" +== 103 +-- truncate_limit: 100 +-- Same as polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 ~= p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 ~= p2.f1" +== 104 +-- truncate_limit: 100 +-- Contained by polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <@ p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 <@ p2.f1" +== 105 +-- truncate_limit: 100 +-- Contains polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 @> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 @> p2.f1" +== 106 +-- truncate_limit: 100 +-- Overlap with polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 && p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 && p2.f1" +== 107 +-- truncate_limit: 100 +-- Left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 << p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 << p2.f1" +== 108 +-- truncate_limit: 100 +-- Overlap of left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &< p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 &< p2.f1" +== 109 +-- truncate_limit: 100 +-- Right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 >> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 >> p2.f1" +== 110 +-- truncate_limit: 100 +-- Overlap of right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 &> p2.f1" +== 111 +-- truncate_limit: 100 +-- Below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <<| p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 <<| p2.f1" +== 112 +-- truncate_limit: 100 +-- Overlap or below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &<| p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 &<| p2.f1" +== 113 +-- truncate_limit: 100 +-- Above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |>> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 |>> p2.f1" +== 114 +-- truncate_limit: 100 +-- Overlap or above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |&> p2.f1 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1 FROM polygon_tbl p1, polygon_tbl p2 WHERE p1.f1 |&> p2.f1" +== 115 +-- truncate_limit: 100 +-- Distance to polygon +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "p1"="polygon_tbl" +ALIAS: "p2"="polygon_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM polygon_tbl p1, polygon_tbl p2" +== 116 +-- truncate_limit: 100 +|-- +-- Circles +|-- + +SELECT circle(f1, 50.0) + FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT circle(f1, 50.0) FROM point_tbl" +== 117 +-- truncate_limit: 100 +SELECT circle(f1) + FROM BOX_TBL +-- +TABLE: name="box_tbl" schema="" table="box_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT circle(f1) FROM box_tbl" +== 118 +-- truncate_limit: 100 +SELECT circle(f1) + FROM POLYGON_TBL + WHERE (# f1) >= 3 +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT circle(f1) FROM polygon_tbl WHERE (# f1) >= 3" +== 119 +-- truncate_limit: 100 +SELECT c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS distance + FROM CIRCLE_TBL c1, POINT_TBL p1 + WHERE (p1.f1 <-> c1.f1) > 0 + ORDER BY distance, area(c1.f1), p1.f1[0] +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "p1"="point_tbl" +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="c1" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM circle_tbl c1, point_tbl p1 WHERE ... ORDER BY distance, area(c1.f1), p1.f1[0]" +== 120 +-- truncate_limit: 100 +-- To polygon +SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1::polygon FROM circle_tbl WHERE f1 >= '<(0,0),1>'" +== 121 +-- truncate_limit: 100 +-- To polygon with less points +SELECT f1, polygon(8, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, polygon(8, f1) FROM circle_tbl WHERE f1 >= '<(0,0),1>'" +== 122 +-- truncate_limit: 100 +-- Error for insufficient number of points +SELECT f1, polygon(1, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, polygon(1, f1) FROM circle_tbl WHERE f1 >= '<(0,0),1>'" +== 123 +-- truncate_limit: 100 +-- Zero radius error +SELECT f1, polygon(10, f1) FROM CIRCLE_TBL WHERE f1 < '<(0,0),1>' +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, polygon(10, f1) FROM circle_tbl WHERE f1 < '<(0,0),1>'" +== 124 +-- truncate_limit: 100 +-- Same as circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 ~= c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 ~= c2.f1" +== 125 +-- truncate_limit: 100 +-- Overlap with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 && c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 && c2.f1" +== 126 +-- truncate_limit: 100 +-- Overlap or left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &< c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 &< c2.f1" +== 127 +-- truncate_limit: 100 +-- Left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 << c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 << c2.f1" +== 128 +-- truncate_limit: 100 +-- Right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 >> c2.f1" +== 129 +-- truncate_limit: 100 +-- Overlap or right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 &> c2.f1" +== 130 +-- truncate_limit: 100 +-- Contained by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <@ c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 <@ c2.f1" +== 131 +-- truncate_limit: 100 +-- Contain by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 @> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 @> c2.f1" +== 132 +-- truncate_limit: 100 +-- Below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <<| c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 <<| c2.f1" +== 133 +-- truncate_limit: 100 +-- Above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |>> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 |>> c2.f1" +== 134 +-- truncate_limit: 100 +-- Overlap or below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &<| c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 &<| c2.f1" +== 135 +-- truncate_limit: 100 +-- Overlap or above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |&> c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 |&> c2.f1" +== 136 +-- truncate_limit: 100 +-- Area equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 = c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 = c2.f1" +== 137 +-- truncate_limit: 100 +-- Area not equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 != c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 <> c2.f1" +== 138 +-- truncate_limit: 100 +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 < c2.f1" +== 139 +-- truncate_limit: 100 +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 > c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 > c2.f1" +== 140 +-- truncate_limit: 100 +-- Area less than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <= c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 <= c2.f1" +== 141 +-- truncate_limit: 100 +-- Area greater than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >= c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 >= c2.f1" +== 142 +-- truncate_limit: 100 +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 < c2.f1" +== 143 +-- truncate_limit: 100 +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +ALIAS: "c1"="circle_tbl" +ALIAS: "c2"="circle_tbl" +FILTER: schema="" table="c1" column="f1" +FILTER: schema="" table="c2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c1.f1, c2.f1 FROM circle_tbl c1, circle_tbl c2 WHERE c1.f1 < c2.f1" +== 144 +-- truncate_limit: 100 +-- Add point +SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1, p.f1, c.f1 + p.f1 FROM circle_tbl c, point_tbl p" +== 145 +-- truncate_limit: 100 +-- Subtract point +SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1, p.f1, c.f1 - p.f1 FROM circle_tbl c, point_tbl p" +== 146 +-- truncate_limit: 100 +-- Multiply with point +SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1, p.f1, c.f1 * p.f1 FROM circle_tbl c, point_tbl p" +== 147 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1, p.f1, c.f1 / p.f1 FROM circle_tbl c, point_tbl p WHERE p.f1[0] BETWEEN 1 AND 1000" +== 148 +-- truncate_limit: 100 +-- Overflow error +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] > 1000 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1, p.f1, c.f1 / p.f1 FROM circle_tbl c, point_tbl p WHERE p.f1[0] > 1000" +== 149 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1, p.f1, c.f1 / p.f1 FROM circle_tbl c, point_tbl p WHERE p.f1 ~= '(0,0)'::point" +== 150 +-- truncate_limit: 100 +-- Distance to polygon +SELECT c.f1, p.f1, c.f1 <-> p.f1 FROM CIRCLE_TBL c, POLYGON_TBL p +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +ALIAS: "c"="circle_tbl" +ALIAS: "p"="polygon_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1, p.f1, c.f1 <-> p.f1 FROM circle_tbl c, polygon_tbl p" +== 151 +-- truncate_limit: 100 +-- Check index behavior for circles + +CREATE INDEX gcircleind ON circle_tbl USING gist (f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gcircleind ON circle_tbl USING gist (f1)" +== 152 +-- truncate_limit: 100 +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM circle_tbl WHERE f1 && circle(point(1, -2), 1) ORDER BY area(f1)" +== 153 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM circle_tbl WHERE f1 && circle(point(1, -2), 1) ORDER BY area(f1)" +== 154 +-- truncate_limit: 100 +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1) +-- +TABLE: name="circle_tbl" schema="" table="circle_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="area" function="area" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM circle_tbl WHERE f1 && circle(point(1, -2), 1) ORDER BY area(f1)" +== 155 +-- truncate_limit: 100 +-- Check index behavior for polygons + +CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1) +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1)" +== 156 +-- truncate_limit: 100 +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0] +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="poly_center" function="poly_center" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon ORDER BY (poly_center(f1))[0]" +== 157 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0] +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="poly_center" function="poly_center" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon ORDER BY..." +== 158 +-- truncate_limit: 100 +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0] +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +FUNCTION: name="poly_center" function="poly_center" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon ORDER BY (poly_center(f1))[0]" +== 159 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('(1', 'circle') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1', 'circle')" +== 160 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1,', 'circle') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1,', 'circle')" +== 161 +-- truncate_limit: 100 +SELECT pg_input_is_valid('(1,2),-1', 'circle') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,2),-1', 'circle')" +== 162 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(1,2),-1', 'circle') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(1,2),-1', 'circle')" diff --git a/parser/testdata/summary_truncate/postgres_regress/gin.metadata.json b/parser/testdata/summary_truncate/postgres_regress/gin.metadata.json new file mode 100644 index 0000000..f53b7f4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/gin.metadata.json @@ -0,0 +1,63 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/gin.test b/parser/testdata/summary_truncate/postgres_regress/gin.test new file mode 100644 index 0000000..8378feb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/gin.test @@ -0,0 +1,556 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test GIN indexes. +|-- +-- There are other tests to test different GIN opclasses. This is for testing +-- GIN itself. + +-- Create and populate a test table with a GIN index. +create table gin_test_tbl(i int4[]) with (autovacuum_enabled = off) +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gin_test_tbl (i int4[]) WITH (autovacuum_enabled=off)" +== 002 +-- truncate_limit: 100 +create index gin_test_idx on gin_test_tbl using gin (i) + with (fastupdate = on, gin_pending_list_limit = 4096) +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gin_test_idx ON gin_test_tbl USING gin (i) WITH (fastupdate=on, gin_pending_list_lim..." +== 003 +-- truncate_limit: 100 +insert into gin_test_tbl select array[1, 2, g] from generate_series(1, 20000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gin_test_tbl SELECT ARRAY[1, 2, g] FROM generate_series(1, 20000) g" +== 004 +-- truncate_limit: 100 +insert into gin_test_tbl select array[1, 3, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gin_test_tbl SELECT ARRAY[1, 3, g] FROM generate_series(1, 1000) g" +== 005 +-- truncate_limit: 100 +select gin_clean_pending_list('gin_test_idx')>10 as many +-- +FUNCTION: name="gin_clean_pending_list" function="gin_clean_pending_list" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT gin_clean_pending_list('gin_test_idx') > 10 AS many" +== 006 +-- truncate_limit: 100 +-- flush the fastupdate buffers + +insert into gin_test_tbl select array[3, 1, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gin_test_tbl SELECT ARRAY[3, 1, g] FROM generate_series(1, 1000) g" +== 007 +-- truncate_limit: 100 +vacuum gin_test_tbl +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM gin_test_tbl" +== 008 +-- truncate_limit: 100 +-- flush the fastupdate buffers + +select gin_clean_pending_list('gin_test_idx') +-- +FUNCTION: name="gin_clean_pending_list" function="gin_clean_pending_list" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT gin_clean_pending_list('gin_test_idx')" +== 009 +-- truncate_limit: 100 +-- nothing to flush + +-- Test vacuuming +delete from gin_test_tbl where i @> array[2] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gin_test_tbl WHERE i @> ARRAY[2]" +== 010 +-- truncate_limit: 100 +vacuum gin_test_tbl +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM gin_test_tbl" +== 011 +-- truncate_limit: 100 +-- Disable fastupdate, and do more insertions. With fastupdate enabled, most +-- insertions (by flushing the list pages) cause page splits. Without +-- fastupdate, we get more churn in the GIN data leaf pages, and exercise the +-- recompression codepaths. +alter index gin_test_idx set (fastupdate = off) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX gin_test_idx SET (fastupdate=off)" +== 012 +-- truncate_limit: 100 +insert into gin_test_tbl select array[1, 2, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gin_test_tbl SELECT ARRAY[1, 2, g] FROM generate_series(1, 1000) g" +== 013 +-- truncate_limit: 100 +insert into gin_test_tbl select array[1, 3, g] from generate_series(1, 1000) g +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gin_test_tbl SELECT ARRAY[1, 3, g] FROM generate_series(1, 1000) g" +== 014 +-- truncate_limit: 100 +delete from gin_test_tbl where i @> array[2] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gin_test_tbl WHERE i @> ARRAY[2]" +== 015 +-- truncate_limit: 100 +vacuum gin_test_tbl +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM gin_test_tbl" +== 016 +-- truncate_limit: 100 +-- Test for "rare && frequent" searches +explain (costs off) +select count(*) from gin_test_tbl where i @> array[1, 999] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM gin_test_tbl WHERE i @> ARRAY[1, 999]" +== 017 +-- truncate_limit: 100 +select count(*) from gin_test_tbl where i @> array[1, 999] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM gin_test_tbl WHERE i @> ARRAY[1, 999]" +== 018 +-- truncate_limit: 100 +-- Very weak test for gin_fuzzy_search_limit +set gin_fuzzy_search_limit = 1000 +-- +STMT: VariableSetStmt +TRUNCATED: "SET gin_fuzzy_search_limit TO 1000" +== 019 +-- truncate_limit: 100 +explain (costs off) +select count(*) > 0 as ok from gin_test_tbl where i @> array[1] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) > 0 AS ok FROM gin_test_tbl WHERE i @> ARRAY[1]" +== 020 +-- truncate_limit: 100 +select count(*) > 0 as ok from gin_test_tbl where i @> array[1] +-- +TABLE: name="gin_test_tbl" schema="" table="gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM gin_test_tbl WHERE i @> ARRAY[1]" +== 021 +-- truncate_limit: 100 +reset gin_fuzzy_search_limit +-- +STMT: VariableSetStmt +TRUNCATED: "RESET gin_fuzzy_search_limit" +== 022 +-- truncate_limit: 100 +-- Test optimization of empty queries +create temp table t_gin_test_tbl(i int4[], j int4[]) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t_gin_test_tbl (i int4[], j int4[])" +== 023 +-- truncate_limit: 100 +create index on t_gin_test_tbl using gin (i, j) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON t_gin_test_tbl USING gin (i, j)" +== 024 +-- truncate_limit: 100 +insert into t_gin_test_tbl +values + (null, null), + ('{}', null), + ('{1}', null), + ('{1,2}', null), + (null, '{}'), + (null, '{10}'), + ('{1,2}', '{10}'), + ('{2}', '{10}'), + ('{1,3}', '{}'), + ('{1,1}', '{10}') +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t_gin_test_tbl VALUES (...)" +== 025 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 026 +-- truncate_limit: 100 +explain (costs off) +select * from t_gin_test_tbl where array[0] <@ i +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t_gin_test_tbl WHERE ARRAY[0] <@ i" +== 027 +-- truncate_limit: 100 +select * from t_gin_test_tbl where array[0] <@ i +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t_gin_test_tbl WHERE ARRAY[0] <@ i" +== 028 +-- truncate_limit: 100 +select * from t_gin_test_tbl where array[0] <@ i and '{}'::int4[] <@ j +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t_gin_test_tbl WHERE ARRAY[0] <@ i AND '{}'::int4[] <@ j" +== 029 +-- truncate_limit: 100 +explain (costs off) +select * from t_gin_test_tbl where i @> '{}' +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t_gin_test_tbl WHERE i @> '{}'" +== 030 +-- truncate_limit: 100 +select * from t_gin_test_tbl where i @> '{}' +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t_gin_test_tbl WHERE i @> '{}'" +== 031 +-- truncate_limit: 100 +create function explain_query_json(query_sql text) +returns table (explain_line json) +language plpgsql as +$$ +begin + set enable_seqscan = off; + set enable_bitmapscan = on; + return query execute 'EXPLAIN (ANALYZE, FORMAT json) ' || query_sql; +end; +$$ +-- +FUNCTION: name="explain_query_json" function="explain_query_json" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_query_json(query_sql text) RETURNS TABLE (explain_line pg_catalog.json) L..." +== 032 +-- truncate_limit: 100 +create function execute_text_query_index(query_sql text) +returns setof text +language plpgsql +as +$$ +begin + set enable_seqscan = off; + set enable_bitmapscan = on; + return query execute query_sql; +end; +$$ +-- +FUNCTION: name="execute_text_query_index" function="execute_text_query_index" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION execute_text_query_index(query_sql text) RETURNS SETOF text LANGUAGE plpgsql AS $..." +== 033 +-- truncate_limit: 100 +create function execute_text_query_heap(query_sql text) +returns setof text +language plpgsql +as +$$ +begin + set enable_seqscan = on; + set enable_bitmapscan = off; + return query execute query_sql; +end; +$$ +-- +FUNCTION: name="execute_text_query_heap" function="execute_text_query_heap" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION execute_text_query_heap(query_sql text) RETURNS SETOF text LANGUAGE plpgsql AS $$..." +== 034 +-- truncate_limit: 100 +-- check number of rows returned by index and removed by recheck +select + query, + js->0->'Plan'->'Plans'->0->'Actual Rows' as "return by index", + js->0->'Plan'->'Rows Removed by Index Recheck' as "removed by recheck", + (res_index = res_heap) as "match" +from + (values + ($$ i @> '{}' $$), + ($$ j @> '{}' $$), + ($$ i @> '{}' and j @> '{}' $$), + ($$ i @> '{1}' $$), + ($$ i @> '{1}' and j @> '{}' $$), + ($$ i @> '{1}' and i @> '{}' and j @> '{}' $$), + ($$ j @> '{10}' $$), + ($$ j @> '{10}' and i @> '{}' $$), + ($$ j @> '{10}' and j @> '{}' and i @> '{}' $$), + ($$ i @> '{1}' and j @> '{10}' $$) + ) q(query), + 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 +-- +FUNCTION: name="explain_query_json" function="explain_query_json" schema="" ctx=Call +FUNCTION: name="execute_text_query_index" function="execute_text_query_index" schema="" ctx=Call +FUNCTION: name="execute_text_query_heap" function="execute_text_query_heap" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) q(query), LATERAL explain_query_json('select * from t_gin_test_tbl..." +== 035 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 036 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 037 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t_gin_test_tbl SELECT ... FROM generate_series(1, 20000) g" +== 038 +-- truncate_limit: 100 +select gin_clean_pending_list('t_gin_test_tbl_i_j_idx') is not null +-- +FUNCTION: name="gin_clean_pending_list" function="gin_clean_pending_list" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT gin_clean_pending_list('t_gin_test_tbl_i_j_idx') IS NOT NULL" +== 039 +-- truncate_limit: 100 +analyze t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t_gin_test_tbl" +== 040 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 041 +-- truncate_limit: 100 +set enable_bitmapscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 042 +-- truncate_limit: 100 +explain (costs off) +select count(*) from t_gin_test_tbl where j @> array[50] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM t_gin_test_tbl WHERE j @> ARRAY[50]" +== 043 +-- truncate_limit: 100 +select count(*) from t_gin_test_tbl where j @> array[50] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM t_gin_test_tbl WHERE j @> ARRAY[50]" +== 044 +-- truncate_limit: 100 +explain (costs off) +select count(*) from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM t_gin_test_tbl WHERE j @> ARRAY[2]" +== 045 +-- truncate_limit: 100 +select count(*) from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM t_gin_test_tbl WHERE j @> ARRAY[2]" +== 046 +-- truncate_limit: 100 +explain (costs off) +select count(*) from t_gin_test_tbl where j @> '{}'::int[] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM t_gin_test_tbl WHERE j @> '{}'::int[]" +== 047 +-- truncate_limit: 100 +select count(*) from t_gin_test_tbl where j @> '{}'::int[] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM t_gin_test_tbl WHERE j @> '{}'::int[]" +== 048 +-- truncate_limit: 100 +-- test vacuuming of posting trees +delete from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t_gin_test_tbl WHERE j @> ARRAY[2]" +== 049 +-- truncate_limit: 100 +vacuum t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM t_gin_test_tbl" +== 050 +-- truncate_limit: 100 +select count(*) from t_gin_test_tbl where j @> array[50] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM t_gin_test_tbl WHERE j @> ARRAY[50]" +== 051 +-- truncate_limit: 100 +select count(*) from t_gin_test_tbl where j @> array[2] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM t_gin_test_tbl WHERE j @> ARRAY[2]" +== 052 +-- truncate_limit: 100 +select count(*) from t_gin_test_tbl where j @> '{}'::int[] +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM t_gin_test_tbl WHERE j @> '{}'::int[]" +== 053 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 054 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 055 +-- truncate_limit: 100 +drop table t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t_gin_test_tbl" +== 056 +-- truncate_limit: 100 +-- test an unlogged table, mostly to get coverage of ginbuildempty +create unlogged table t_gin_test_tbl(i int4[], j int4[]) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE t_gin_test_tbl (i int4[], j int4[])" +== 057 +-- truncate_limit: 100 +create index on t_gin_test_tbl using gin (i, j) +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON t_gin_test_tbl USING gin (i, j)" +== 058 +-- truncate_limit: 100 +insert into t_gin_test_tbl +values + (null, null), + ('{}', null), + ('{1}', '{2,3}') +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t_gin_test_tbl VALUES (NULL, NULL), ('{}', NULL), ('{1}', '{2,3}')" +== 059 +-- truncate_limit: 100 +drop table t_gin_test_tbl +-- +TABLE: name="t_gin_test_tbl" schema="" table="t_gin_test_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t_gin_test_tbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/gist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/gist.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/gist.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/gist.test b/parser/testdata/summary_truncate/postgres_regress/gist.test new file mode 100644 index 0000000..a027d53 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/gist.test @@ -0,0 +1,708 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test GiST indexes. +|-- +-- There are other tests to test different GiST opclasses. This is for +-- testing GiST code itself. Vacuuming in particular. + +create table gist_point_tbl(id int4, p point) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gist_point_tbl (id int4, p point)" +== 002 +-- truncate_limit: 100 +create index gist_pointidx on gist_point_tbl using gist(p) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pointidx ON gist_point_tbl USING gist (p)" +== 003 +-- truncate_limit: 100 +-- Verify the fillfactor and buffering options +create index gist_pointidx2 on gist_point_tbl using gist(p) with (buffering = on, fillfactor=50) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pointidx2 ON gist_point_tbl USING gist (p) WITH (buffering=on, fillfactor=50)" +== 004 +-- truncate_limit: 100 +create index gist_pointidx3 on gist_point_tbl using gist(p) with (buffering = off) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pointidx3 ON gist_point_tbl USING gist (p) WITH (buffering=off)" +== 005 +-- truncate_limit: 100 +create index gist_pointidx4 on gist_point_tbl using gist(p) with (buffering = auto) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pointidx4 ON gist_point_tbl USING gist (p) WITH (buffering=auto)" +== 006 +-- truncate_limit: 100 +drop index gist_pointidx2, gist_pointidx3, gist_pointidx4 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX gist_pointidx2, gist_pointidx3, gist_pointidx4" +== 007 +-- truncate_limit: 100 +-- Make sure bad values are refused +create index gist_pointidx5 on gist_point_tbl using gist(p) with (buffering = invalid_value) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pointidx5 ON gist_point_tbl USING gist (p) WITH (buffering=invalid_value)" +== 008 +-- truncate_limit: 100 +create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=9) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pointidx5 ON gist_point_tbl USING gist (p) WITH (fillfactor=9)" +== 009 +-- truncate_limit: 100 +create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=101) +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pointidx5 ON gist_point_tbl USING gist (p) WITH (fillfactor=101)" +== 010 +-- truncate_limit: 100 +-- Insert enough data to create a tree that's a couple of levels deep. +insert into gist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10000) g +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gist_point_tbl (id, p) SELECT g, point(g * 10, g * 10) FROM generate_series(1, 10000) g" +== 011 +-- truncate_limit: 100 +insert into gist_point_tbl (id, p) +select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gist_point_tbl (id, p) SELECT ... FROM generate_series(1, 10000) g" +== 012 +-- truncate_limit: 100 +-- To test vacuum, delete some entries from all over the index. +delete from gist_point_tbl where id % 2 = 1 +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gist_point_tbl WHERE (id % 2) = 1" +== 013 +-- truncate_limit: 100 +-- And also delete some concentration of values. +delete from gist_point_tbl where id > 5000 +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM gist_point_tbl WHERE id > 5000" +== 014 +-- truncate_limit: 100 +vacuum analyze gist_point_tbl +-- +TABLE: name="gist_point_tbl" schema="" table="gist_point_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) gist_point_tbl" +== 015 +-- truncate_limit: 100 +-- rebuild the index with a different fillfactor +alter index gist_pointidx SET (fillfactor = 40) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX gist_pointidx SET (fillfactor=40)" +== 016 +-- truncate_limit: 100 +reindex index gist_pointidx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX gist_pointidx" +== 017 +-- truncate_limit: 100 +|-- +-- Test Index-only plans on GiST indexes +|-- + +create table gist_tbl (b box, p point, c circle) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE gist_tbl (b box, p point, c circle)" +== 018 +-- truncate_limit: 100 +insert into gist_tbl +select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), + point(0.05*i, 0.05*i), + circle(point(0.05*i, 0.05*i), 1.0) +from generate_series(0,10000) as i +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gist_tbl SELECT ... FROM generate_series(0, 10000) i" +== 019 +-- truncate_limit: 100 +vacuum analyze gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) gist_tbl" +== 020 +-- truncate_limit: 100 +set enable_seqscan=off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 021 +-- truncate_limit: 100 +set enable_bitmapscan=off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 022 +-- truncate_limit: 100 +set enable_indexonlyscan=on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO ON" +== 023 +-- truncate_limit: 100 +-- Test index-only scan with point opclass +create index gist_tbl_point_index on gist_tbl using gist (p) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_tbl_point_index ON gist_tbl USING gist (p)" +== 024 +-- truncate_limit: 100 +-- check that the planner chooses an index-only scan +explain (costs off) +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p FROM gist_tbl WHERE p <@ box(point(0, 0), point(0.5, 0.5))" +== 025 +-- truncate_limit: 100 +-- execute the same +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT p FROM gist_tbl WHERE p <@ box(point(0, 0), point(0.5, 0.5))" +== 026 +-- truncate_limit: 100 +-- Also test an index-only knn-search +explain (costs off) +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by p <-> point(0.201, 0.201) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p FROM gist_tbl WHERE p <@ box(point(0, 0), point(0.5, 0.5)) ORDER BY ..." +== 027 +-- truncate_limit: 100 +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by p <-> point(0.201, 0.201) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT p FROM gist_tbl WHERE ... ORDER BY p <-> point(0.201, 0.201)" +== 028 +-- truncate_limit: 100 +-- Check commuted case as well +explain (costs off) +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by point(0.101, 0.101) <-> p +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p FROM gist_tbl WHERE p <@ box(point(0, 0), point(0.5, 0.5)) ORDER BY ..." +== 029 +-- truncate_limit: 100 +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by point(0.101, 0.101) <-> p +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT p FROM gist_tbl WHERE ... ORDER BY point(0.101, 0.101) <-> p" +== 030 +-- truncate_limit: 100 +-- Check case with multiple rescans (bug #14641) +explain (costs off) +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +FILTER: schema="" table="" column="bb" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p FROM (VALUES (box(point(0, 0), point(0.5, 0.5))), (box(point(0.5, 0...." +== 031 +-- truncate_limit: 100 +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +FILTER: schema="" table="" column="bb" +STMT: SelectStmt +TRUNCATED: "SELECT p FROM (VALUES (...)) v(bb) CROSS JOIN LATERAL (SELECT p FROM gist_tbl WHERE ... ORDER BY ..." +== 032 +-- truncate_limit: 100 +drop index gist_tbl_point_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX gist_tbl_point_index" +== 033 +-- truncate_limit: 100 +-- Test index-only scan with box opclass +create index gist_tbl_box_index on gist_tbl using gist (b) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_tbl_box_index ON gist_tbl USING gist (b)" +== 034 +-- truncate_limit: 100 +-- check that the planner chooses an index-only scan +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b FROM gist_tbl WHERE b <@ box(point(5, 5), point(6, 6))" +== 035 +-- truncate_limit: 100 +-- execute the same +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT b FROM gist_tbl WHERE b <@ box(point(5, 5), point(6, 6))" +== 036 +-- truncate_limit: 100 +-- Also test an index-only knn-search +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b FROM gist_tbl WHERE b <@ box(point(5, 5), point(6, 6)) ORDER BY b <-..." +== 037 +-- truncate_limit: 100 +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT b FROM gist_tbl WHERE b <@ box(point(5, 5), point(6, 6)) ORDER BY b <-> point(5.2, 5.91)" +== 038 +-- truncate_limit: 100 +-- Check commuted case as well +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b FROM gist_tbl WHERE b <@ box(point(5, 5), point(6, 6)) ORDER BY poin..." +== 039 +-- truncate_limit: 100 +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT b FROM gist_tbl WHERE b <@ box(point(5, 5), point(6, 6)) ORDER BY point(5.2, 5.91) <-> b" +== 040 +-- truncate_limit: 100 +drop index gist_tbl_box_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX gist_tbl_box_index" +== 041 +-- truncate_limit: 100 +-- Test that an index-only scan is not chosen, when the query involves the +-- circle column (the circle opclass does not support index-only scans). +create index gist_tbl_multi_index on gist_tbl using gist (p, c) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_tbl_multi_index ON gist_tbl USING gist (p, c)" +== 042 +-- truncate_limit: 100 +explain (costs off) +select p, c from gist_tbl +where p <@ box(point(5,5), point(6, 6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p, c FROM gist_tbl WHERE p <@ box(point(5, 5), point(6, 6))" +== 043 +-- truncate_limit: 100 +-- execute the same +select b, p from gist_tbl +where b <@ box(point(4.5, 4.5), point(5.5, 5.5)) +and p <@ box(point(5,5), point(6, 6)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT b, p FROM gist_tbl WHERE ..." +== 044 +-- truncate_limit: 100 +drop index gist_tbl_multi_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX gist_tbl_multi_index" +== 045 +-- truncate_limit: 100 +-- Test that we don't try to return the value of a non-returnable +-- column in an index-only scan. (This isn't GIST-specific, but +-- it only applies to index AMs that can return some columns and not +-- others, so GIST with appropriate opclasses is a convenient test case.) +create index gist_tbl_multi_index on gist_tbl using gist (circle(p,1), p) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +FUNCTION: name="circle" function="circle" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_tbl_multi_index ON gist_tbl USING gist (circle(p, 1), p)" +== 046 +-- truncate_limit: 100 +explain (verbose, costs off) +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT circle(p, 1) FROM gist_tbl WHERE p <@ box(point(5, 5), point(..." +== 047 +-- truncate_limit: 100 +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT circle(p, 1) FROM gist_tbl WHERE p <@ box(point(5, 5), point(5.3, 5.3))" +== 048 +-- truncate_limit: 100 +-- Similarly, test that index rechecks involving a non-returnable column +-- are done correctly. +explain (verbose, costs off) +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT p FROM gist_tbl WHERE circle(p, 1) @> circle(point(0, 0), 0.95)" +== 049 +-- truncate_limit: 100 +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT p FROM gist_tbl WHERE circle(p, 1) @> circle(point(0, 0), 0.95)" +== 050 +-- truncate_limit: 100 +-- Also check that use_physical_tlist doesn't trigger in such cases. +explain (verbose, costs off) +select count(*) from gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM gist_tbl" +== 051 +-- truncate_limit: 100 +select count(*) from gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM gist_tbl" +== 052 +-- truncate_limit: 100 +-- This case isn't supported, but it should at least EXPLAIN correctly. +explain (verbose, costs off) +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1 +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT p FROM gist_tbl ORDER BY circle(p, 1) <-> point(0, 0) LIMIT 1" +== 053 +-- truncate_limit: 100 +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1 +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=Select +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT p FROM gist_tbl ORDER BY circle(p, 1) <-> point(0, 0) LIMIT 1" +== 054 +-- truncate_limit: 100 +-- Force an index build using buffering. +create index gist_tbl_box_index_forcing_buffering on gist_tbl using gist (p) + with (buffering=on, fillfactor=50) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_tbl_box_index_forcing_buffering ON gist_tbl USING gist (p) WITH (buffering=on, ..." +== 055 +-- truncate_limit: 100 +-- Clean up +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 056 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 057 +-- truncate_limit: 100 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexonlyscan" +== 058 +-- truncate_limit: 100 +drop table gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gist_tbl" +== 059 +-- truncate_limit: 100 +-- test an unlogged table, mostly to get coverage of gistbuildempty +create unlogged table gist_tbl (b box) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE gist_tbl (b box)" +== 060 +-- truncate_limit: 100 +create index gist_tbl_box_index on gist_tbl using gist (b) +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_tbl_box_index ON gist_tbl USING gist (b)" +== 061 +-- truncate_limit: 100 +insert into gist_tbl + select box(point(0.05*i, 0.05*i)) from generate_series(0,10) as i +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gist_tbl SELECT box(point(0.05 * i, 0.05 * i)) FROM generate_series(0, 10) i" +== 062 +-- truncate_limit: 100 +drop table gist_tbl +-- +TABLE: name="gist_tbl" schema="" table="gist_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gist_tbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json b/parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json new file mode 100644 index 0000000..643d115 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json @@ -0,0 +1,176 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/groupingsets.test b/parser/testdata/summary_truncate/postgres_regress/groupingsets.test new file mode 100644 index 0000000..8add3f4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/groupingsets.test @@ -0,0 +1,1749 @@ +== 001 +-- truncate_limit: 100 +|-- +-- grouping sets +|-- + +-- test data sources + +create temp view gstest1(a,b,v) + as 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) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW gstest1 (a, b, v) AS VALUES (1, 1, 10), (1, 1, 11), (1, 2, 12), (1, 2, 13),..." +== 002 +-- truncate_limit: 100 +create temp table gstest2 (a integer, b integer, c integer, d integer, + e integer, f integer, g integer, h integer) +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE gstest2 (a int, b int, c int, d int, e int, f int, g int, h int)" +== 003 +-- truncate_limit: 100 +copy gstest2 from stdin +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY gstest2 FROM STDIN" +== 004 +-- truncate_limit: 100 +create temp table gstest3 (a integer, b integer, c integer, d integer) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE gstest3 (a int, b int, c int, d int)" +== 005 +-- truncate_limit: 100 +copy gstest3 from stdin +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY gstest3 FROM STDIN" +== 006 +-- truncate_limit: 100 +alter table gstest3 add primary key (a) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gstest3 ADD PRIMARY KEY (a)" +== 007 +-- truncate_limit: 100 +create temp table gstest4(id integer, v integer, + unhashable_col bit(4), unsortable_col xid) +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE gstest4 (id int, v int, unhashable_col pg_catalog.bit(4), unsortable_col xid)" +== 008 +-- truncate_limit: 100 +insert into gstest4 +values (1,1,b'0000','1'), (2,2,b'0001','1'), + (3,4,b'0010','2'), (4,8,b'0011','2'), + (5,16,b'0000','2'), (6,32,b'0001','2'), + (7,64,b'0010','1'), (8,128,b'0011','1') +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO gstest4 VALUES (...)" +== 009 +-- truncate_limit: 100 +create temp table gstest_empty (a integer, b integer, v integer) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE gstest_empty (a int, b int, v int)" +== 010 +-- truncate_limit: 100 +create function gstest_data(v integer, out a integer, out b integer) + returns setof record + as $f$ + begin + return query select v, i from generate_series(1,3) i; + end; + $f$ language plpgsql +-- +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION gstest_data(v int, OUT a int, OUT b int) RETURNS SETOF record AS $$\n begin\n ..." +== 011 +-- truncate_limit: 100 +-- basic functionality + +set enable_hashagg = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 012 +-- truncate_limit: 100 +-- test hashing explicitly later + +-- simple rollup with multiple plain aggregates, with and without ordering +-- (and with ordering differing from grouping) + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, GROUPING(a, b), sum(v), count(*), max(v) FROM gstest1 GROUP BY ROLLUP (a, b)" +== 013 +-- truncate_limit: 100 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by a,b +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY ROLLUP (a, b) ORDER BY a, b" +== 014 +-- truncate_limit: 100 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by b desc, a +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY ROLLUP (a, b) ORDER BY b DESC, a" +== 015 +-- truncate_limit: 100 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by coalesce(a,0)+coalesce(b,0) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY ROLLUP (a, b) ORDER BY COALESCE(a, 0) + COALESCE(b, 0)" +== 016 +-- truncate_limit: 100 +-- various types of ordered aggs +select a, b, grouping(a,b), + array_agg(v order by v), + string_agg(v::text, ':' order by v desc), + percentile_disc(0.5) within group (order by v), + rank(1,2,12) within group (order by a,b,v) + from gstest1 group by rollup (a,b) order by a,b +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY ROLLUP (a, b) ORDER BY a, b" +== 017 +-- truncate_limit: 100 +-- test usage of grouped columns in direct args of aggs +select grouping(a), a, array_agg(b), + rank(a) within group (order by b nulls first), + rank(a) within group (order by b nulls last) + from (values (1,1),(1,4),(1,5),(3,1),(3,2)) v(a,b) + group by rollup (a) order by a +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a, b) GROUP BY ROLLUP (a) ORDER BY a" +== 018 +-- truncate_limit: 100 +-- nesting with window functions +select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum + from gstest2 group by rollup (a,b) order by rsum, a, b +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY ROLLUP (a, b) ORDER BY rsum, a, b" +== 019 +-- truncate_limit: 100 +-- nesting with grouping sets +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(()))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY GROUPING SETS ((), GROUPING SETS ((), GROUPING SETS (()))) ORDER..." +== 020 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(((a, b))))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY GROUPING SETS ((), GROUPING SETS ((), GROUPING SETS ((a, b)))) O..." +== 021 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets(grouping sets(rollup(c), grouping sets(cube(c)))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY GROUPING SETS (GROUPING SETS (ROLLUP (c), GROUPING SETS (CUBE (c..." +== 022 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets(a, grouping sets(a, cube(b))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(c) FROM gstest2 GROUP BY GROUPING SETS (a, GROUPING SETS (a, CUBE (b))) ORDER BY 1 DESC" +== 023 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, (b)))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(c) FROM gstest2 GROUP BY GROUPING SETS (GROUPING SETS ((a, b))) ORDER BY 1 DESC" +== 024 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, b))) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(c) FROM gstest2 GROUP BY GROUPING SETS (GROUPING SETS ((a, b))) ORDER BY 1 DESC" +== 025 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a), a)) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY GROUPING SETS (GROUPING SETS (a, GROUPING SETS (a), a)) ORDER BY..." +== 026 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a, grouping sets(a), ((a)), a, grouping sets(a), (a)), a)) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY GROUPING SETS (GROUPING SETS (a, GROUPING SETS (a, GROUPING SETS..." +== 027 +-- truncate_limit: 100 +select sum(c) from gstest2 + group by grouping sets((a,(a,b)), grouping sets((a,(a,b)),a)) + order by 1 desc +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY GROUPING SETS ((a, (a, b)), GROUPING SETS ((a, (a, b)), a)) ORDE..." +== 028 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b), a)" +== 029 +-- truncate_limit: 100 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b), ())" +== 030 +-- truncate_limit: 100 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b), (), (), ())" +== 031 +-- truncate_limit: 100 +select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((), (), ())" +== 032 +-- truncate_limit: 100 +-- 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),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +ALIAS: "t1"="gstest_empty" +ALIAS: "t2"="gstest_empty" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest_empty t1, gstest_empty t2 GROUP BY GROUPING SETS ((t1.a, t2.b), ())" +== 033 +-- truncate_limit: 100 +-- 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), ()) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +ALIAS: "t1"="gstest1" +ALIAS: "t2"="gstest2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 t1, gstest2 t2 GROUP BY GROUPING SETS ((t1.a, t2.b), ())" +== 034 +-- truncate_limit: 100 +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), ()) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +ALIAS: "t1"="gstest1" +ALIAS: "t2"="gstest2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 t1 JOIN gstest2 t2 ON t1.a = t2.a GROUP BY GROUPING SETS ((t1.a, t2.b), ())" +== 035 +-- truncate_limit: 100 +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), ()) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +ALIAS: "t1"="gstest1" +ALIAS: "t2"="gstest2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 t1 JOIN gstest2 t2 USING (a, b) GROUP BY GROUPING SETS ((a, b), ())" +== 036 +-- truncate_limit: 100 +-- 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)) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, d, GROUPING(a, b, c) FROM gstest3 GROUP BY GROUPING SETS ((a, b), (a, c))" +== 037 +-- truncate_limit: 100 +-- 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) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT g AS alias1, g AS alias2 FROM generate_series(1, 3) g GROUP BY alias1,..." +== 038 +-- truncate_limit: 100 +select g as alias1, g as alias2 + from generate_series(1,3) g + group by alias1, rollup(alias2) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT g AS alias1, g AS alias2 FROM generate_series(1, 3) g GROUP BY alias1, ROLLUP (alias2)" +== 039 +-- truncate_limit: 100 +-- 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' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT four, x FROM (SELECT ... FROM tenk1) t GROUP BY GROUPING SETS (four, x) HAVING x = 'foo'" +== 040 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT four, x || 'x' FROM (SELECT ... FROM tenk1) t GROUP BY GROUPING SETS (four, x) ORDER BY four" +== 041 +-- truncate_limit: 100 +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) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "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)" +== 042 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM int8_tbl i1) t GROUP BY GROUPING SETS (x, q2) ORDER BY x, q2" +== 043 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT 1 AS x, q1, sum(q2) FROM int8_tbl i1 GROUP BY ..." +== 044 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM int8_tbl i1 GROUP BY GROUPING SETS (1, 2)) ss WHERE ..." +== 045 +-- truncate_limit: 100 +-- check handling of pulled-up SubPlan in GROUPING() argument (bug #17479) +explain (verbose, costs off) +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT GROUPING(ss.x) FROM int8_tbl i1 CROSS JOIN LATERAL (SELECT (S..." +== 046 +-- truncate_limit: 100 +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT GROUPING(ss.x) FROM int8_tbl i1 CROSS JOIN LATERAL (SELECT ...) ss GROUP BY ss.x" +== 047 +-- truncate_limit: 100 +explain (verbose, costs off) +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT (SELECT GROUPING(ss.x)) FROM int8_tbl i1 CROSS JOIN LATERAL (..." +== 048 +-- truncate_limit: 100 +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT GROUPING(ss.x)) FROM int8_tbl i1 CROSS JOIN LATERAL (SELECT ...) ss GROUP BY ss.x" +== 049 +-- truncate_limit: 100 +-- simple rescan tests + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by rollup (a,b) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v.x) FROM (VALUES (1), (2)) v(x), gstest_data(v.x) GROUP BY ROLLUP (a, b)" +== 050 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(x), LATERAL (SELECT ... FROM gstest_data(v.x) GROUP BY ROLLUP (a, ..." +== 051 +-- truncate_limit: 100 +-- min max optimization should still work with GROUP BY () +explain (costs off) + select min(unique1) from tenk1 GROUP BY () +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT min(unique1) FROM tenk1 GROUP BY ()" +== 052 +-- truncate_limit: 100 +-- 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)) +-- +TABLE: name="gstest_view" schema="" table="gstest_view" ctx=DDL +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW gstest_view AS SELECT a, b, GROUPING(a, b), sum(c), count(*), max(c) FROM gstest2 GRO..." +== 053 +-- truncate_limit: 100 +select pg_get_viewdef('gstest_view'::regclass, true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('gstest_view'::regclass, true)" +== 054 +-- truncate_limit: 100 +-- 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) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v3(e, f) GROUP BY ROLLUP (e, f)" +== 055 +-- truncate_limit: 100 +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) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v3(e, f) GROUP BY ROLLUP (e, f)" +== 056 +-- truncate_limit: 100 +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) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v3(e, f) GROUP BY ROLLUP (e, f)" +== 057 +-- truncate_limit: 100 +-- Combinations of operations +select a, b, c, d from gstest2 group by rollup(a,b),grouping sets(c,d) +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c, d FROM gstest2 GROUP BY ROLLUP (a, b), GROUPING SETS (c, d)" +== 058 +-- truncate_limit: 100 +select a, b from (values (1,2),(2,3)) v(a,b) group by a,b, grouping sets(a) +-- +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM (VALUES (1, 2), (2, 3)) v(a, b) GROUP BY a, b, GROUPING SETS (a)" +== 059 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY GROUPING SETS ((a, b), (a + 1, b + 1), (a + 2, b + 2)) ORDER BY ..." +== 060 +-- truncate_limit: 100 +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)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v3(e, f) GROUP BY ROLLUP (e + 1, f + 1)" +== 061 +-- truncate_limit: 100 +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) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v3(e, f) GROUP BY CUBE (e + 1, f + 1) ORDER BY e + 1, f + 1" +== 062 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY CUBE (a, b) ORDER BY rsum, a, b" +== 063 +-- truncate_limit: 100 +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) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(c) FROM (VALUES (...)) v(a, b, c) GROUP BY ROLLUP (a, b)" +== 064 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v.x) FROM (VALUES (...)) v(x), gstest_data(v.x) GROUP BY CUBE (a, b) ORDER BY a, b" +== 065 +-- truncate_limit: 100 +-- Test reordering of grouping sets +explain (costs off) +select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM gstest1 GROUP BY GROUPING SETS ((a, b, v), v) ORDER BY v, b, a" +== 066 +-- truncate_limit: 100 +-- Agg level check. This query should error out. +select (select grouping(a,b) from gstest2) from gstest2 group by a,b +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT GROUPING(a, b) FROM gstest2) FROM gstest2 GROUP BY a, b" +== 067 +-- truncate_limit: 100 +--Nested queries +select a, b, sum(c), count(*) from gstest2 group by grouping sets (rollup(a,b),a) +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(c), count(*) FROM gstest2 GROUP BY GROUPING SETS (ROLLUP (a, b), a)" +== 068 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="a" column="four" +FILTER: schema="" table="b" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek a GROUP BY GROUPING SETS ((ten, four), ten) HAVING EXISTS (SELECT 1 FROM one..." +== 069 +-- truncate_limit: 100 +-- Tests around pushdown of HAVING clauses, partially testing against previous bugs +select a,count(*) from gstest2 group by rollup(a) order by a +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, count(*) FROM gstest2 GROUP BY ROLLUP (a) ORDER BY a" +== 070 +-- truncate_limit: 100 +select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, count(*) FROM gstest2 GROUP BY ROLLUP (a) HAVING a IS DISTINCT FROM 1 ORDER BY a" +== 071 +-- truncate_limit: 100 +explain (costs off) + select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, count(*) FROM gstest2 GROUP BY ROLLUP (a) HAVING a IS DISTINCT FROM..." +== 072 +-- truncate_limit: 100 +select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v.c, (SELECT ... FROM gstest2 GROUP BY () HAVING v.c) FROM (VALUES (...)) v(c) ORDER BY v.c" +== 073 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT v.c, (SELECT count(*) FROM gstest2 GROUP BY () HAVING v.c) FROM (VALUE..." +== 074 +-- truncate_limit: 100 +-- HAVING with GROUPING queries +select ten, grouping(ten) from onek +group by grouping sets(ten) having grouping(ten) >= 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek GROUP BY GROUPING SETS (ten) HAVING GROUPING(ten) >= 0 ORDER BY 2, 1" +== 075 +-- truncate_limit: 100 +select ten, grouping(ten) from onek +group by grouping sets(ten, four) having grouping(ten) > 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek GROUP BY GROUPING SETS (ten, four) HAVING GROUPING(ten) > 0 ORDER BY 2, 1" +== 076 +-- truncate_limit: 100 +select ten, grouping(ten) from onek +group by rollup(ten) having grouping(ten) > 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ten, GROUPING(ten) FROM onek GROUP BY ROLLUP (ten) HAVING GROUPING(ten) > 0 ORDER BY 2, 1" +== 077 +-- truncate_limit: 100 +select ten, grouping(ten) from onek +group by cube(ten) having grouping(ten) > 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ten, GROUPING(ten) FROM onek GROUP BY CUBE (ten) HAVING GROUPING(ten) > 0 ORDER BY 2, 1" +== 078 +-- truncate_limit: 100 +select ten, grouping(ten) from onek +group by (ten) having grouping(ten) >= 0 +order by 2,1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ten, GROUPING(ten) FROM onek GROUP BY ten HAVING GROUPING(ten) >= 0 ORDER BY 2, 1" +== 079 +-- truncate_limit: 100 +-- FILTER queries +select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +group by rollup(ten) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ten, sum(DISTINCT four) FILTER (WHERE four::text ~ '123') FROM onek a GROUP BY ROLLUP (ten)" +== 080 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(a) LEFT JOIN LATERAL (SELECT ... FROM onek GROUP BY CUBE (four, te..." +== 081 +-- truncate_limit: 100 +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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a)" +== 082 +-- truncate_limit: 100 +-- Grouping on text columns +select sum(ten) from onek group by two, rollup(four::text) order by 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(ten) FROM onek GROUP BY two, ROLLUP (four::text) ORDER BY 1" +== 083 +-- truncate_limit: 100 +select sum(ten) from onek group by rollup(four::text), two order by 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(ten) FROM onek GROUP BY ROLLUP (four::text), two ORDER BY 1" +== 084 +-- truncate_limit: 100 +-- hashing support + +set enable_hashagg = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO TRUE" +== 085 +-- truncate_limit: 100 +-- failure cases + +select count(*) from gstest4 group by rollup(unhashable_col,unsortable_col) +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM gstest4 GROUP BY ROLLUP (unhashable_col, unsortable_col)" +== 086 +-- truncate_limit: 100 +select array_agg(v order by v) from gstest4 group by grouping sets ((id,unsortable_col),(id)) +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_agg(v ORDER BY v) FROM gstest4 GROUP BY GROUPING SETS ((id, unsortable_col), id)" +== 087 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY GROUPING SETS (a, b) ORDER BY 3, 1, 2" +== 088 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, GROUPING(a, b), sum(v), count(*), max(v) FROM gstest1 GROUP BY G..." +== 089 +-- truncate_limit: 100 +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by cube(a,b) order by 3,1,2 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY CUBE (a, b) ORDER BY 3, 1, 2" +== 090 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, GROUPING(a, b), sum(v), count(*), max(v) FROM gstest1 GROUP BY C..." +== 091 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, GROUPING(a, b), array_agg(v ORDER BY v) FROM gstest1 GROUP BY CU..." +== 092 +-- truncate_limit: 100 +-- unsortable cases +select unsortable_col, count(*) + from gstest4 group by grouping sets ((unsortable_col),(unsortable_col)) + order by unsortable_col::text +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest4 GROUP BY GROUPING SETS (unsortable_col, unsortable_col) ORDER BY unsortab..." +== 093 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest4 GROUP BY GROUPING SETS (unhashable_col, unsortable_col) ORDER BY 3, 5" +== 094 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unhashable_col, unsortable_col, GROUPING(unhashable_col, unsortable_co..." +== 095 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest4 GROUP BY GROUPING SETS ((v, unhashable_col), (v, unsortable_col)) ORDER B..." +== 096 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest4" schema="" table="gstest4" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unhashable_col, unsortable_col, GROUPING(unhashable_col, unsortable_co..." +== 097 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b), a)" +== 098 +-- truncate_limit: 100 +explain (costs off) + select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b..." +== 099 +-- truncate_limit: 100 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b), ())" +== 100 +-- truncate_limit: 100 +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b), (), (), ())" +== 101 +-- truncate_limit: 100 +explain (costs off) + select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((a, b..." +== 102 +-- truncate_limit: 100 +select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((), (), ())" +== 103 +-- truncate_limit: 100 +explain (costs off) + select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()) +-- +TABLE: name="gstest_empty" schema="" table="gstest_empty" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(v), count(*) FROM gstest_empty GROUP BY GROUPING SETS ((), (), ())" +== 104 +-- truncate_limit: 100 +-- 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)) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, d, GROUPING(a, b, c) FROM gstest3 GROUP BY GROUPING SETS ((a, b), (a, c))" +== 105 +-- truncate_limit: 100 +explain (costs off) + select a, d, grouping(a,b,c) + from gstest3 + group by grouping sets ((a,b), (a,c)) +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, d, GROUPING(a, b, c) FROM gstest3 GROUP BY GROUPING SETS ((a, b), (..." +== 106 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(x), gstest_data(v.x) GROUP BY GROUPING SETS (a, b) ORDER BY 1, 2, 3" +== 107 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, sum(v.x) FROM (VALUES (1), (2)) v(x), gstest_data(v.x) GROUP BY ..." +== 108 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(x), LATERAL (SELECT ... FROM gstest_data(v.x) GROUP BY GROUPING SE..." +== 109 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (VALUES (1), (2)) v(x), LATERAL (SELECT a, b, sum(v.x) FROM gst..." +== 110 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest1 GROUP BY GROUPING SETS ((a, b), (a + 1, b + 1), (a + 2, b + 2)) ORDER BY ..." +== 111 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest1" schema="" table="gstest1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, GROUPING(a, b), sum(v), count(*), max(v) FROM gstest1 GROUP BY G..." +== 112 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM gstest2 GROUP BY CUBE (a, b) ORDER BY rsum, a, b" +== 113 +-- truncate_limit: 100 +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 +-- +TABLE: name="gstest2" schema="" table="gstest2" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, sum(c), sum(sum(c)) OVER (ORDER BY a, b) AS rsum FROM gstest2 GR..." +== 114 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, sum(v.x) FROM (VALUES (...)) v(x), gstest_data(v.x) GROUP BY CUBE (a, b) ORDER BY a, b" +== 115 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="gstest_data" function="gstest_data" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, sum(v.x) FROM (VALUES (1), (2)) v(x), gstest_data(v.x) GROUP BY ..." +== 116 +-- truncate_limit: 100 +-- 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 +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 117 +-- truncate_limit: 100 +SET LOCAL enable_hashagg = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_hashagg TO FALSE" +== 118 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS (a,..." +== 119 +-- truncate_limit: 100 +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS (a, b, ()) ORDER BY a, b" +== 120 +-- truncate_limit: 100 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO FALSE" +== 121 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS (a,..." +== 122 +-- truncate_limit: 100 +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b +-- +TABLE: name="gstest3" schema="" table="gstest3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS (a, b, ()) ORDER BY a, b" +== 123 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 124 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(a) LEFT JOIN LATERAL (SELECT ... FROM onek GROUP BY CUBE (four, te..." +== 125 +-- truncate_limit: 100 +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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a)" +== 126 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(a) LEFT JOIN LATERAL (SELECT ... FROM onek GROUP BY GROUPING SETS ..." +== 127 +-- truncate_limit: 100 +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) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(a)" +== 128 +-- truncate_limit: 100 +-- test the knapsack + +set enable_indexscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO FALSE" +== 129 +-- truncate_limit: 100 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO 1.0" +== 130 +-- truncate_limit: 100 +set work_mem = '64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 131 +-- truncate_limit: 100 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, count(two), count(four), count(ten), count(hundred), count(th..." +== 132 +-- truncate_limit: 100 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, count(two), count(four), count(ten), count(hundred), count(th..." +== 133 +-- truncate_limit: 100 +set work_mem = '384kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"384kB\"" +== 134 +-- truncate_limit: 100 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, count(two), count(four), count(ten), count(hundred), count(th..." +== 135 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY[1, 1], ARRAY['a', 'b']) u(i, v) GROUP BY ROLLUP (i, v || 'a') ORDER ..." +== 136 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY[1, 1], ARRAY['a', 'b']) u(i, v) GROUP BY ROLLUP (i, v || 'a') ORDER ..." +== 137 +-- truncate_limit: 100 +-- Bug #16784 +create table bug_16784(i int, j int) +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bug_16784 (i int, j int)" +== 138 +-- truncate_limit: 100 +analyze bug_16784 +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE bug_16784" +== 139 +-- truncate_limit: 100 +alter table bug_16784 set (autovacuum_enabled = 'false') +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bug_16784 SET (autovacuum_enabled=false)" +== 140 +-- truncate_limit: 100 +update pg_class set reltuples = 10 where relname='bug_16784' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pg_class SET reltuples = 10 WHERE relname = 'bug_16784'" +== 141 +-- truncate_limit: 100 +insert into bug_16784 select g/10, g from generate_series(1,40) g +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bug_16784 SELECT g / 10, g FROM generate_series(1, 40) g" +== 142 +-- truncate_limit: 100 +set work_mem='64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 143 +-- truncate_limit: 100 +set enable_sort = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO FALSE" +== 144 +-- truncate_limit: 100 +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 +-- +TABLE: name="bug_16784" schema="" table="bug_16784" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(a), LATERAL (SELECT ... FROM bug_16784 GROUP BY CUBE (i, j)) s ORD..." +== 145 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE gs_data_1 AS SELECT g % 1000 AS g1000, g % 100 AS g100, g % 10 AS g10, g FROM genera..." +== 146 +-- truncate_limit: 100 +analyze gs_data_1 +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE gs_data_1" +== 147 +-- truncate_limit: 100 +alter table gs_data_1 set (autovacuum_enabled = 'false') +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE gs_data_1 SET (autovacuum_enabled=false)" +== 148 +-- truncate_limit: 100 +update pg_class set reltuples = 10 where relname='gs_data_1' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pg_class SET reltuples = 10 WHERE relname = 'gs_data_1'" +== 149 +-- truncate_limit: 100 +set work_mem='64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 150 +-- truncate_limit: 100 +-- Produce results with sorting. + +set enable_sort = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO TRUE" +== 151 +-- truncate_limit: 100 +set enable_hashagg = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 152 +-- truncate_limit: 100 +set jit_above_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO 0" +== 153 +-- truncate_limit: 100 +explain (costs off) +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10) +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT g100, g10, sum(g::numeric), count(*), max(g::text) FROM gs_data_1 GROU..." +== 154 +-- truncate_limit: 100 +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) +-- +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=DDL +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE gs_group_1 AS SELECT g100, g10, sum(g::numeric), count(*), max(g::text) FROM gs_data..." +== 155 +-- truncate_limit: 100 +-- Produce results with hash aggregation. + +set enable_hashagg = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO TRUE" +== 156 +-- truncate_limit: 100 +set enable_sort = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO FALSE" +== 157 +-- truncate_limit: 100 +explain (costs off) +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10) +-- +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT g100, g10, sum(g::numeric), count(*), max(g::text) FROM gs_data_1 GROU..." +== 158 +-- truncate_limit: 100 +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) +-- +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=DDL +TABLE: name="gs_data_1" schema="" table="gs_data_1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE gs_hash_1 AS SELECT g100, g10, sum(g::numeric), count(*), max(g::text) FROM gs_data_..." +== 159 +-- truncate_limit: 100 +set enable_sort = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO TRUE" +== 160 +-- truncate_limit: 100 +set work_mem to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO DEFAULT" +== 161 +-- truncate_limit: 100 +set hash_mem_multiplier to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO DEFAULT" +== 162 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=Select +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=Select +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=Select +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM gs_hash_1 EXCEPT SELECT * FROM gs_group_1) UNION ALL (SELECT * FROM gs_group_1 EXC..." +== 163 +-- truncate_limit: 100 +drop table gs_group_1 +-- +TABLE: name="gs_group_1" schema="" table="gs_group_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gs_group_1" +== 164 +-- truncate_limit: 100 +drop table gs_hash_1 +-- +TABLE: name="gs_hash_1" schema="" table="gs_hash_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE gs_hash_1" +== 165 +-- truncate_limit: 100 +-- GROUP BY DISTINCT + +-- "normal" behavior... +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by all rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM (VALUES (...)) t(a, b, c) GROUP BY ROLLUP (a, b), ROLLUP (a, c) ORDER BY a, b, c" +== 166 +-- truncate_limit: 100 +-- ...which is also the default +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +TRUNCATED: "SELECT a, b, c FROM (VALUES (...)) t(a, b, c) GROUP BY ROLLUP (a, b), ROLLUP (a, c) ORDER BY a, b, c" +== 167 +-- truncate_limit: 100 +-- "group by distinct" behavior... +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by distinct rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(a, b, c) GROUP BY DISTINCT ROLLUP (a, b), ROLLUP (a, c) ORDER BY..." +== 168 +-- truncate_limit: 100 +-- ...which is not the same as "select distinct" +select distinct a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by rollup(a, b), rollup(a, c) +order by a, b, c +-- +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM (VALUES (...)) t(a, b, c) GROUP BY ROLLUP (a, b), ROLLUP (a, c) O..." +== 169 +-- truncate_limit: 100 +-- test handling of outer GroupingFunc within subqueries +explain (costs off) +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT (SELECT GROUPING(v1)) FROM (VALUES ((SELECT 1))) v(v1) GROUP BY CUBE (v1)" +== 170 +-- truncate_limit: 100 +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1) +-- +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT GROUPING(v1)) FROM (VALUES ((SELECT 1))) v(v1) GROUP BY CUBE (v1)" +== 171 +-- truncate_limit: 100 +explain (costs off) +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1 +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT (SELECT GROUPING(v1)) FROM (VALUES ((SELECT 1))) v(v1) GROUP BY v1" +== 172 +-- truncate_limit: 100 +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT GROUPING(v1)) FROM (VALUES ((SELECT 1))) v(v1) GROUP BY v1" diff --git a/parser/testdata/summary_truncate/postgres_regress/guc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/guc.metadata.json new file mode 100644 index 0000000..8f8fab6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/guc.metadata.json @@ -0,0 +1,218 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/guc.test b/parser/testdata/summary_truncate/postgres_regress/guc.test new file mode 100644 index 0000000..d09c128 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/guc.test @@ -0,0 +1,1462 @@ +== 001 +-- truncate_limit: 100 +-- pg_regress should ensure that this default value applies; however +-- we can't rely on any specific default value of vacuum_cost_delay +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 002 +-- truncate_limit: 100 +-- SET to some nondefault value +SET vacuum_cost_delay TO 40 +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO 40" +== 003 +-- truncate_limit: 100 +SET datestyle = 'ISO, YMD' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"ISO, YMD\"" +== 004 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 005 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 006 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 007 +-- truncate_limit: 100 +-- SET LOCAL has no effect outside of a transaction +SET LOCAL vacuum_cost_delay TO 50 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL vacuum_cost_delay TO 50" +== 008 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 009 +-- truncate_limit: 100 +SET LOCAL datestyle = 'SQL' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL datestyle TO \"SQL\"" +== 010 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 011 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 012 +-- truncate_limit: 100 +-- SET LOCAL within a transaction that commits +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 013 +-- truncate_limit: 100 +SET LOCAL vacuum_cost_delay TO 50 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL vacuum_cost_delay TO 50" +== 014 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 015 +-- truncate_limit: 100 +SET LOCAL datestyle = 'SQL' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL datestyle TO \"SQL\"" +== 016 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 017 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 018 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 019 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 020 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 021 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 022 +-- truncate_limit: 100 +-- SET should be reverted after ROLLBACK +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 023 +-- truncate_limit: 100 +SET vacuum_cost_delay TO 60 +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO 60" +== 024 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 025 +-- truncate_limit: 100 +SET datestyle = 'German' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"German\"" +== 026 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 027 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 028 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 029 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 030 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 031 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 032 +-- truncate_limit: 100 +-- Some tests with subtransactions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 033 +-- truncate_limit: 100 +SET vacuum_cost_delay TO 70 +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO 70" +== 034 +-- truncate_limit: 100 +SET datestyle = 'MDY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"MDY\"" +== 035 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 036 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 037 +-- truncate_limit: 100 +SAVEPOINT first_sp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT first_sp" +== 038 +-- truncate_limit: 100 +SET vacuum_cost_delay TO 80.1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO 80.1" +== 039 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 040 +-- truncate_limit: 100 +SET datestyle = 'German, DMY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"German, DMY\"" +== 041 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 042 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 043 +-- truncate_limit: 100 +ROLLBACK TO first_sp +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT first_sp" +== 044 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 045 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 046 +-- truncate_limit: 100 +SAVEPOINT second_sp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT second_sp" +== 047 +-- truncate_limit: 100 +SET vacuum_cost_delay TO '900us' +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO \"900us\"" +== 048 +-- truncate_limit: 100 +SET datestyle = 'SQL, YMD' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"SQL, YMD\"" +== 049 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 050 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 051 +-- truncate_limit: 100 +SAVEPOINT third_sp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT third_sp" +== 052 +-- truncate_limit: 100 +SET vacuum_cost_delay TO 100 +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO 100" +== 053 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 054 +-- truncate_limit: 100 +SET datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"Postgres, MDY\"" +== 055 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 056 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 057 +-- truncate_limit: 100 +ROLLBACK TO third_sp +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT third_sp" +== 058 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 059 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 060 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 061 +-- truncate_limit: 100 +ROLLBACK TO second_sp +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT second_sp" +== 062 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 063 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 064 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 065 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 066 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 067 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 068 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 069 +-- truncate_limit: 100 +-- SET LOCAL with Savepoints +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 070 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 071 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 072 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 073 +-- truncate_limit: 100 +SAVEPOINT sp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp" +== 074 +-- truncate_limit: 100 +SET LOCAL vacuum_cost_delay TO 30 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL vacuum_cost_delay TO 30" +== 075 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 076 +-- truncate_limit: 100 +SET LOCAL datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL datestyle TO \"Postgres, MDY\"" +== 077 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 078 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 079 +-- truncate_limit: 100 +ROLLBACK TO sp +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT sp" +== 080 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 081 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 082 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 083 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 084 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 085 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 086 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 087 +-- truncate_limit: 100 +-- SET LOCAL persists through RELEASE (which was not true in 8.0-8.2) +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 088 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 089 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 090 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 091 +-- truncate_limit: 100 +SAVEPOINT sp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp" +== 092 +-- truncate_limit: 100 +SET LOCAL vacuum_cost_delay TO 30 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL vacuum_cost_delay TO 30" +== 093 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 094 +-- truncate_limit: 100 +SET LOCAL datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL datestyle TO \"Postgres, MDY\"" +== 095 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 096 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 097 +-- truncate_limit: 100 +RELEASE SAVEPOINT sp +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE sp" +== 098 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 099 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 100 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 101 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 102 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 103 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 104 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 105 +-- truncate_limit: 100 +-- SET followed by SET LOCAL +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 106 +-- truncate_limit: 100 +SET vacuum_cost_delay TO 40 +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO 40" +== 107 +-- truncate_limit: 100 +SET LOCAL vacuum_cost_delay TO 50 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL vacuum_cost_delay TO 50" +== 108 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 109 +-- truncate_limit: 100 +SET datestyle = 'ISO, DMY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"ISO, DMY\"" +== 110 +-- truncate_limit: 100 +SET LOCAL datestyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL datestyle TO \"Postgres, MDY\"" +== 111 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 112 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 113 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 114 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 115 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 116 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 117 +-- truncate_limit: 100 +|-- +-- Test RESET. We use datestyle because the reset value is forced by +-- pg_regress, so it doesn't depend on the installation's configuration. +|-- +SET datestyle = iso, ymd +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO iso, ymd" +== 118 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 119 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 120 +-- truncate_limit: 100 +RESET datestyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" +== 121 +-- truncate_limit: 100 +SHOW datestyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 122 +-- truncate_limit: 100 +SELECT '2006-08-13 12:34:56'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2006-08-13 12:34:56'::timestamptz" +== 123 +-- truncate_limit: 100 +-- Test some simple error cases +SET seq_page_cost TO 'NaN' +-- +STMT: VariableSetStmt +TRUNCATED: "SET seq_page_cost TO \"NaN\"" +== 124 +-- truncate_limit: 100 +SET vacuum_cost_delay TO '10s' +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO \"10s\"" +== 125 +-- truncate_limit: 100 +SET no_such_variable TO 42 +-- +STMT: VariableSetStmt +TRUNCATED: "SET no_such_variable TO 42" +== 126 +-- truncate_limit: 100 +-- Test "custom" GUCs created on the fly (which aren't really an +-- intended feature, but many people use them). +SHOW custom.my_guc +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW \"custom.my_guc\"" +== 127 +-- truncate_limit: 100 +-- error, not known yet +SET custom.my_guc = 42 +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"custom.my_guc\" TO 42" +== 128 +-- truncate_limit: 100 +SHOW custom.my_guc +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW \"custom.my_guc\"" +== 129 +-- truncate_limit: 100 +RESET custom.my_guc +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"custom.my_guc\"" +== 130 +-- truncate_limit: 100 +-- this makes it go to empty, not become unknown again +SHOW custom.my_guc +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW \"custom.my_guc\"" +== 131 +-- truncate_limit: 100 +SET custom.my.qualified.guc = 'foo' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"custom.my.qualified.guc\" TO foo" +== 132 +-- truncate_limit: 100 +SHOW custom.my.qualified.guc +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW \"custom.my.qualified.guc\"" +== 133 +-- truncate_limit: 100 +SET custom."bad-guc" = 42 +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"custom.bad-guc\" TO 42" +== 134 +-- truncate_limit: 100 +-- disallowed because -c cannot set this name +SHOW custom."bad-guc" +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW \"custom.bad-guc\"" +== 135 +-- truncate_limit: 100 +SET special."weird name" = 'foo' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"special.weird name\" TO foo" +== 136 +-- truncate_limit: 100 +-- could be allowed, but we choose not to +SHOW special."weird name" +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW \"special.weird name\"" +== 137 +-- truncate_limit: 100 +-- Check what happens when you try to set a "custom" GUC within the +-- namespace of an extension. +SET plpgsql.extra_foo_warnings = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_foo_warnings\" TO TRUE" +== 138 +-- truncate_limit: 100 +-- allowed if plpgsql is not loaded yet +LOAD 'plpgsql' +-- +STMT: LoadStmt +TRUNCATED: "LOAD 'plpgsql'" +== 139 +-- truncate_limit: 100 +-- this will throw a warning and delete the variable +SET plpgsql.extra_foo_warnings = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_foo_warnings\" TO TRUE" +== 140 +-- truncate_limit: 100 +-- now, it's an error +SHOW plpgsql.extra_foo_warnings +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW \"plpgsql.extra_foo_warnings\"" +== 141 +-- truncate_limit: 100 +|-- +-- Test DISCARD TEMP +|-- +CREATE TEMP TABLE reset_test ( data text ) ON COMMIT DELETE ROWS +-- +TABLE: name="reset_test" schema="" table="reset_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE reset_test (data text) ON COMMIT DELETE ROWS" +== 142 +-- truncate_limit: 100 +SELECT relname FROM pg_class WHERE relname = 'reset_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname = 'reset_test'" +== 143 +-- truncate_limit: 100 +DISCARD TEMP +-- +STMT: DiscardStmt +TRUNCATED: "DISCARD TEMP" +== 144 +-- truncate_limit: 100 +SELECT relname FROM pg_class WHERE relname = 'reset_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname = 'reset_test'" +== 145 +-- truncate_limit: 100 +|-- +-- Test DISCARD ALL +|-- + +-- do changes +DECLARE foo CURSOR WITH HOLD FOR SELECT 1 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo CURSOR WITH HOLD FOR SELECT 1" +== 146 +-- truncate_limit: 100 +PREPARE foo AS SELECT 1 +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE foo AS SELECT 1" +== 147 +-- truncate_limit: 100 +LISTEN foo_event +-- +STMT: ListenStmt +TRUNCATED: "LISTEN foo_event" +== 148 +-- truncate_limit: 100 +SET vacuum_cost_delay = 13 +-- +STMT: VariableSetStmt +TRUNCATED: "SET vacuum_cost_delay TO 13" +== 149 +-- truncate_limit: 100 +CREATE TEMP TABLE tmp_foo (data text) ON COMMIT DELETE ROWS +-- +TABLE: name="tmp_foo" schema="" table="tmp_foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tmp_foo (data text) ON COMMIT DELETE ROWS" +== 150 +-- truncate_limit: 100 +CREATE ROLE regress_guc_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_guc_user" +== 151 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_guc_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_guc_user" +== 152 +-- truncate_limit: 100 +-- look changes +SELECT pg_listening_channels() +-- +FUNCTION: name="pg_listening_channels" function="pg_listening_channels" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_listening_channels()" +== 153 +-- truncate_limit: 100 +SELECT name FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_prepared_statements" +== 154 +-- truncate_limit: 100 +SELECT name FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_cursors" +== 155 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 156 +-- truncate_limit: 100 +SELECT relname from pg_class where relname = 'tmp_foo' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname = 'tmp_foo'" +== 157 +-- truncate_limit: 100 +SELECT current_user = 'regress_guc_user' +-- +STMT: SelectStmt +TRUNCATED: "SELECT current_user = 'regress_guc_user'" +== 158 +-- truncate_limit: 100 +-- discard everything +DISCARD ALL +-- +STMT: DiscardStmt +TRUNCATED: "DISCARD ALL" +== 159 +-- truncate_limit: 100 +-- look again +SELECT pg_listening_channels() +-- +FUNCTION: name="pg_listening_channels" function="pg_listening_channels" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_listening_channels()" +== 160 +-- truncate_limit: 100 +SELECT name FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_prepared_statements" +== 161 +-- truncate_limit: 100 +SELECT name FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_cursors" +== 162 +-- truncate_limit: 100 +SHOW vacuum_cost_delay +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW vacuum_cost_delay" +== 163 +-- truncate_limit: 100 +SELECT relname from pg_class where relname = 'tmp_foo' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname = 'tmp_foo'" +== 164 +-- truncate_limit: 100 +SELECT current_user = 'regress_guc_user' +-- +STMT: SelectStmt +TRUNCATED: "SELECT current_user = 'regress_guc_user'" +== 165 +-- truncate_limit: 100 +DROP ROLE regress_guc_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_guc_user" +== 166 +-- truncate_limit: 100 +|-- +-- search_path should react to changes in pg_namespace +|-- + +set search_path = foo, public, not_there_initially +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO foo, public, not_there_initially" +== 167 +-- truncate_limit: 100 +select current_schemas(false) +-- +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_schemas(false)" +== 168 +-- truncate_limit: 100 +create schema not_there_initially +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA not_there_initially" +== 169 +-- truncate_limit: 100 +select current_schemas(false) +-- +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_schemas(false)" +== 170 +-- truncate_limit: 100 +drop schema not_there_initially +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA not_there_initially" +== 171 +-- truncate_limit: 100 +select current_schemas(false) +-- +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_schemas(false)" +== 172 +-- truncate_limit: 100 +reset search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 173 +-- truncate_limit: 100 +|-- +-- Tests for function-local GUC settings +|-- + +set work_mem = '3MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"3MB\"" +== 174 +-- truncate_limit: 100 +create function report_guc(text) returns text as +$$ select current_setting($1) $$ language sql +set work_mem = '1MB' +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION report_guc(text) RETURNS text AS $$ select current_setting($1) $$ LANGUAGE sql SE..." +== 175 +-- truncate_limit: 100 +select report_guc('work_mem'), current_setting('work_mem') +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT report_guc('work_mem'), current_setting('work_mem')" +== 176 +-- truncate_limit: 100 +alter function report_guc(text) set work_mem = '2MB' +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION report_guc(text) SET work_mem TO \"2MB\"" +== 177 +-- truncate_limit: 100 +select report_guc('work_mem'), current_setting('work_mem') +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT report_guc('work_mem'), current_setting('work_mem')" +== 178 +-- truncate_limit: 100 +alter function report_guc(text) reset all +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION report_guc(text) RESET ALL" +== 179 +-- truncate_limit: 100 +select report_guc('work_mem'), current_setting('work_mem') +-- +FUNCTION: name="report_guc" function="report_guc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT report_guc('work_mem'), current_setting('work_mem')" +== 180 +-- truncate_limit: 100 +-- SET LOCAL is restricted by a function SET option +create or replace function myfunc(int) returns text as $$ +begin + set local work_mem = '2MB'; + return current_setting('work_mem'); +end $$ +language plpgsql +set work_mem = '1MB' +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION myfunc(int) RETURNS text AS $$\nbegin\n set local work_mem = '2MB';\n r..." +== 181 +-- truncate_limit: 100 +select myfunc(0), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myfunc(0), current_setting('work_mem')" +== 182 +-- truncate_limit: 100 +alter function myfunc(int) reset all +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION myfunc(int) RESET ALL" +== 183 +-- truncate_limit: 100 +select myfunc(0), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myfunc(0), current_setting('work_mem')" +== 184 +-- truncate_limit: 100 +set work_mem = '3MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"3MB\"" +== 185 +-- truncate_limit: 100 +-- but SET isn't +create or replace function myfunc(int) returns text as $$ +begin + set work_mem = '2MB'; + return current_setting('work_mem'); +end $$ +language plpgsql +set work_mem = '1MB' +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION myfunc(int) RETURNS text AS $$\nbegin\n set work_mem = '2MB';\n return ..." +== 186 +-- truncate_limit: 100 +select myfunc(0), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myfunc(0), current_setting('work_mem')" +== 187 +-- truncate_limit: 100 +set work_mem = '3MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"3MB\"" +== 188 +-- truncate_limit: 100 +-- it should roll back on error, though +create or replace function myfunc(int) returns text as $$ +begin + set work_mem = '2MB'; + perform 1/$1; + return current_setting('work_mem'); +end $$ +language plpgsql +set work_mem = '1MB' +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION myfunc(int) RETURNS text AS $$\nbegin\n set work_mem = '2MB';\n perform..." +== 189 +-- truncate_limit: 100 +select myfunc(0) +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myfunc(0)" +== 190 +-- truncate_limit: 100 +select current_setting('work_mem') +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_setting('work_mem')" +== 191 +-- truncate_limit: 100 +select myfunc(1), current_setting('work_mem') +-- +FUNCTION: name="myfunc" function="myfunc" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myfunc(1), current_setting('work_mem')" +== 192 +-- truncate_limit: 100 +-- check current_setting()'s behavior with invalid setting name + +select current_setting('nosuch.setting') +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_setting('nosuch.setting')" +== 193 +-- truncate_limit: 100 +-- FAIL +select current_setting('nosuch.setting', false) +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_setting('nosuch.setting', false)" +== 194 +-- truncate_limit: 100 +-- FAIL +select current_setting('nosuch.setting', true) is null +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_setting('nosuch.setting', true) IS NULL" +== 195 +-- truncate_limit: 100 +-- after this, all three cases should yield 'nada' +set nosuch.setting = 'nada' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"nosuch.setting\" TO nada" +== 196 +-- truncate_limit: 100 +select current_setting('nosuch.setting') +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_setting('nosuch.setting')" +== 197 +-- truncate_limit: 100 +select current_setting('nosuch.setting', false) +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_setting('nosuch.setting', false)" +== 198 +-- truncate_limit: 100 +select current_setting('nosuch.setting', true) +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_setting('nosuch.setting', true)" +== 199 +-- truncate_limit: 100 +-- Normally, CREATE FUNCTION should complain about invalid values in +-- function SET options; but not if check_function_bodies is off, +-- because that creates ordering hazards for pg_dump + +create function func_with_bad_set() returns int as $$ select 1 $$ +language sql +set default_text_search_config = no_such_config +-- +FUNCTION: name="func_with_bad_set" function="func_with_bad_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION func_with_bad_set() RETURNS int AS $$ select 1 $$ LANGUAGE sql SET default_text_s..." +== 200 +-- truncate_limit: 100 +set check_function_bodies = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET check_function_bodies TO OFF" +== 201 +-- truncate_limit: 100 +create function func_with_bad_set() returns int as $$ select 1 $$ +language sql +set default_text_search_config = no_such_config +-- +FUNCTION: name="func_with_bad_set" function="func_with_bad_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION func_with_bad_set() RETURNS int AS $$ select 1 $$ LANGUAGE sql SET default_text_s..." +== 202 +-- truncate_limit: 100 +select func_with_bad_set() +-- +FUNCTION: name="func_with_bad_set" function="func_with_bad_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT func_with_bad_set()" +== 203 +-- truncate_limit: 100 +reset check_function_bodies +-- +STMT: VariableSetStmt +TRUNCATED: "RESET check_function_bodies" +== 204 +-- truncate_limit: 100 +set default_with_oids to f +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_with_oids TO f" +== 205 +-- truncate_limit: 100 +-- Should not allow to set it to true. +set default_with_oids to t +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_with_oids TO t" +== 206 +-- truncate_limit: 100 +-- Test GUC categories and flag patterns +SELECT pg_settings_get_flags(NULL) +-- +FUNCTION: name="pg_settings_get_flags" function="pg_settings_get_flags" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_settings_get_flags(NULL)" +== 207 +-- truncate_limit: 100 +SELECT pg_settings_get_flags('does_not_exist') +-- +FUNCTION: name="pg_settings_get_flags" function="pg_settings_get_flags" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_settings_get_flags('does_not_exist')" +== 208 +-- truncate_limit: 100 +CREATE TABLE tab_settings_flags AS SELECT name, category, + 'EXPLAIN' = ANY(flags) AS explain, + 'NO_RESET' = ANY(flags) AS no_reset, + 'NO_RESET_ALL' = ANY(flags) AS no_reset_all, + 'NOT_IN_SAMPLE' = ANY(flags) AS not_in_sample, + 'RUNTIME_COMPUTED' = ANY(flags) AS runtime_computed + FROM pg_show_all_settings() AS psas, + pg_settings_get_flags(psas.name) AS flags +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=DDL +FUNCTION: name="pg_show_all_settings" function="pg_show_all_settings" schema="" ctx=Call +FUNCTION: name="pg_settings_get_flags" function="pg_settings_get_flags" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE tab_settings_flags AS SELECT name, category, 'EXPLAIN' = ANY(flags) AS explain, 'NO_..." +== 209 +-- truncate_limit: 100 +-- Developer GUCs should be flagged with GUC_NOT_IN_SAMPLE: +SELECT name FROM tab_settings_flags + WHERE category = 'Developer Options' AND NOT not_in_sample + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="not_in_sample" +STMT: SelectStmt +TRUNCATED: "SELECT name FROM tab_settings_flags WHERE ... ORDER BY 1" +== 210 +-- truncate_limit: 100 +-- Most query-tuning GUCs are flagged as valid for EXPLAIN. +-- default_statistics_target is an exception. +SELECT name FROM tab_settings_flags + WHERE category ~ '^Query Tuning' AND NOT explain + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="explain" +STMT: SelectStmt +TRUNCATED: "SELECT name FROM tab_settings_flags WHERE category ~ '^Query Tuning' AND NOT explain ORDER BY 1" +== 211 +-- truncate_limit: 100 +-- Runtime-computed GUCs should be part of the preset category. +SELECT name FROM tab_settings_flags + WHERE NOT category = 'Preset Options' AND runtime_computed + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="runtime_computed" +STMT: SelectStmt +TRUNCATED: "SELECT name FROM tab_settings_flags WHERE ... ORDER BY 1" +== 212 +-- truncate_limit: 100 +-- Preset GUCs are flagged as NOT_IN_SAMPLE. +SELECT name FROM tab_settings_flags + WHERE category = 'Preset Options' AND NOT not_in_sample + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="category" +FILTER: schema="" table="" column="not_in_sample" +STMT: SelectStmt +TRUNCATED: "SELECT name FROM tab_settings_flags WHERE ... ORDER BY 1" +== 213 +-- truncate_limit: 100 +-- NO_RESET implies NO_RESET_ALL. +SELECT name FROM tab_settings_flags + WHERE no_reset AND NOT no_reset_all + ORDER BY 1 +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=Select +FILTER: schema="" table="" column="no_reset" +FILTER: schema="" table="" column="no_reset_all" +STMT: SelectStmt +TRUNCATED: "SELECT name FROM tab_settings_flags WHERE no_reset AND NOT no_reset_all ORDER BY 1" +== 214 +-- truncate_limit: 100 +DROP TABLE tab_settings_flags +-- +TABLE: name="tab_settings_flags" schema="" table="tab_settings_flags" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tab_settings_flags" diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json b/parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json new file mode 100644 index 0000000..e74143a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json @@ -0,0 +1,47 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_func.test b/parser/testdata/summary_truncate/postgres_regress/hash_func.test new file mode 100644 index 0000000..d4dc2df --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/hash_func.test @@ -0,0 +1,889 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test hash functions +|-- +-- When the salt is 0, the extended hash function should produce a result +-- whose low 32 bits match the standard hash function. When the salt is +-- not 0, we should get a different result. +|-- + +SELECT v as value, hashint2(v)::bit(32) as standard, + hashint2extended(v, 0)::bit(32) as extended0, + hashint2extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0::int2), (1::int2), (17::int2), (42::int2)) x(v) +WHERE hashint2(v)::bit(32) != hashint2extended(v, 0)::bit(32) + OR hashint2(v)::bit(32) = hashint2extended(v, 1)::bit(32) +-- +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FUNCTION: name="hashint2" function="hashint2" schema="" ctx=Call +FUNCTION: name="hashint2extended" function="hashint2extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 002 +-- truncate_limit: 100 +SELECT v as value, hashint4(v)::bit(32) as standard, + hashint4extended(v, 0)::bit(32) as extended0, + hashint4extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashint4(v)::bit(32) != hashint4extended(v, 0)::bit(32) + OR hashint4(v)::bit(32) = hashint4extended(v, 1)::bit(32) +-- +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FUNCTION: name="hashint4" function="hashint4" schema="" ctx=Call +FUNCTION: name="hashint4extended" function="hashint4extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 003 +-- truncate_limit: 100 +SELECT v as value, hashint8(v)::bit(32) as standard, + hashint8extended(v, 0)::bit(32) as extended0, + hashint8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashint8(v)::bit(32) != hashint8extended(v, 0)::bit(32) + OR hashint8(v)::bit(32) = hashint8extended(v, 1)::bit(32) +-- +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FUNCTION: name="hashint8" function="hashint8" schema="" ctx=Call +FUNCTION: name="hashint8extended" function="hashint8extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 004 +-- truncate_limit: 100 +SELECT v as value, hashfloat4(v)::bit(32) as standard, + hashfloat4extended(v, 0)::bit(32) as extended0, + hashfloat4extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashfloat4(v)::bit(32) != hashfloat4extended(v, 0)::bit(32) + OR hashfloat4(v)::bit(32) = hashfloat4extended(v, 1)::bit(32) +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4extended" function="hashfloat4extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 005 +-- truncate_limit: 100 +SELECT v as value, hashfloat8(v)::bit(32) as standard, + hashfloat8extended(v, 0)::bit(32) as extended0, + hashfloat8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashfloat8(v)::bit(32) != hashfloat8extended(v, 0)::bit(32) + OR hashfloat8(v)::bit(32) = hashfloat8extended(v, 1)::bit(32) +-- +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8extended" function="hashfloat8extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 006 +-- truncate_limit: 100 +SELECT v as value, hashoid(v)::bit(32) as standard, + hashoidextended(v, 0)::bit(32) as extended0, + hashoidextended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashoid(v)::bit(32) != hashoidextended(v, 0)::bit(32) + OR hashoid(v)::bit(32) = hashoidextended(v, 1)::bit(32) +-- +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FUNCTION: name="hashoid" function="hashoid" schema="" ctx=Call +FUNCTION: name="hashoidextended" function="hashoidextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 007 +-- truncate_limit: 100 +SELECT v as value, hashchar(v)::bit(32) as standard, + hashcharextended(v, 0)::bit(32) as extended0, + hashcharextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::"char"), ('1'), ('x'), ('X'), ('p'), ('N')) x(v) +WHERE hashchar(v)::bit(32) != hashcharextended(v, 0)::bit(32) + OR hashchar(v)::bit(32) = hashcharextended(v, 1)::bit(32) +-- +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FUNCTION: name="hashchar" function="hashchar" schema="" ctx=Call +FUNCTION: name="hashcharextended" function="hashcharextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 008 +-- truncate_limit: 100 +SELECT v as value, hashname(v)::bit(32) as standard, + hashnameextended(v, 0)::bit(32) as extended0, + hashnameextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashname(v)::bit(32) != hashnameextended(v, 0)::bit(32) + OR hashname(v)::bit(32) = hashnameextended(v, 1)::bit(32) +-- +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FUNCTION: name="hashname" function="hashname" schema="" ctx=Call +FUNCTION: name="hashnameextended" function="hashnameextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 009 +-- truncate_limit: 100 +SELECT v as value, hashtext(v)::bit(32) as standard, + hashtextextended(v, 0)::bit(32) as extended0, + hashtextextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashtext(v)::bit(32) != hashtextextended(v, 0)::bit(32) + OR hashtext(v)::bit(32) = hashtextextended(v, 1)::bit(32) +-- +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FUNCTION: name="hashtext" function="hashtext" schema="" ctx=Call +FUNCTION: name="hashtextextended" function="hashtextextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 010 +-- truncate_limit: 100 +SELECT v as value, hashoidvector(v)::bit(32) as standard, + hashoidvectorextended(v, 0)::bit(32) as extended0, + hashoidvectorextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::oidvector), ('0 1 2 3 4'), ('17 18 19 20'), + ('42 43 42 45'), ('550273 550273 570274'), + ('207112489 207112499 21512 2155 372325 1363252')) x(v) +WHERE hashoidvector(v)::bit(32) != hashoidvectorextended(v, 0)::bit(32) + OR hashoidvector(v)::bit(32) = hashoidvectorextended(v, 1)::bit(32) +-- +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FUNCTION: name="hashoidvector" function="hashoidvector" schema="" ctx=Call +FUNCTION: name="hashoidvectorextended" function="hashoidvectorextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 011 +-- truncate_limit: 100 +SELECT v as value, hash_aclitem(v)::bit(32) as standard, + hash_aclitem_extended(v, 0)::bit(32) as extended0, + hash_aclitem_extended(v, 1)::bit(32) as extended1 +FROM (SELECT DISTINCT(relacl[1]) FROM pg_class LIMIT 10) x(v) +WHERE hash_aclitem(v)::bit(32) != hash_aclitem_extended(v, 0)::bit(32) + OR hash_aclitem(v)::bit(32) = hash_aclitem_extended(v, 1)::bit(32) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FUNCTION: name="hash_aclitem" function="hash_aclitem" schema="" ctx=Call +FUNCTION: name="hash_aclitem_extended" function="hash_aclitem_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT DISTINCT ... AS ... FROM pg_class LIMIT 10) x(v) WHERE ..." +== 012 +-- truncate_limit: 100 +SELECT v as value, hashmacaddr(v)::bit(32) as standard, + hashmacaddrextended(v, 0)::bit(32) as extended0, + hashmacaddrextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::macaddr), ('08:00:2b:01:02:04'), ('08:00:2b:01:02:04'), + ('e2:7f:51:3e:70:49'), ('d6:a9:4a:78:1c:d5'), + ('ea:29:b1:5e:1f:a5')) x(v) +WHERE hashmacaddr(v)::bit(32) != hashmacaddrextended(v, 0)::bit(32) + OR hashmacaddr(v)::bit(32) = hashmacaddrextended(v, 1)::bit(32) +-- +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FUNCTION: name="hashmacaddr" function="hashmacaddr" schema="" ctx=Call +FUNCTION: name="hashmacaddrextended" function="hashmacaddrextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 013 +-- truncate_limit: 100 +SELECT v as value, hashinet(v)::bit(32) as standard, + hashinetextended(v, 0)::bit(32) as extended0, + hashinetextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::inet), ('192.168.100.128/25'), ('192.168.100.0/8'), + ('172.168.10.126/16'), ('172.18.103.126/24'), ('192.188.13.16/32')) x(v) +WHERE hashinet(v)::bit(32) != hashinetextended(v, 0)::bit(32) + OR hashinet(v)::bit(32) = hashinetextended(v, 1)::bit(32) +-- +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FUNCTION: name="hashinet" function="hashinet" schema="" ctx=Call +FUNCTION: name="hashinetextended" function="hashinetextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 014 +-- truncate_limit: 100 +SELECT v as value, hash_numeric(v)::bit(32) as standard, + hash_numeric_extended(v, 0)::bit(32) as extended0, + hash_numeric_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1.149484958), (17.149484958), (42.149484958), + (149484958.550273), (2071124898672)) x(v) +WHERE hash_numeric(v)::bit(32) != hash_numeric_extended(v, 0)::bit(32) + OR hash_numeric(v)::bit(32) = hash_numeric_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FUNCTION: name="hash_numeric" function="hash_numeric" schema="" ctx=Call +FUNCTION: name="hash_numeric_extended" function="hash_numeric_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 015 +-- truncate_limit: 100 +SELECT v as value, hashmacaddr8(v)::bit(32) as standard, + hashmacaddr8extended(v, 0)::bit(32) as extended0, + hashmacaddr8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::macaddr8), ('08:00:2b:01:02:04:36:49'), + ('08:00:2b:01:02:04:f0:e8'), ('e2:7f:51:3e:70:49:16:29'), + ('d6:a9:4a:78:1c:d5:47:32'), ('ea:29:b1:5e:1f:a5')) x(v) +WHERE hashmacaddr8(v)::bit(32) != hashmacaddr8extended(v, 0)::bit(32) + OR hashmacaddr8(v)::bit(32) = hashmacaddr8extended(v, 1)::bit(32) +-- +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FUNCTION: name="hashmacaddr8" function="hashmacaddr8" schema="" ctx=Call +FUNCTION: name="hashmacaddr8extended" function="hashmacaddr8extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 016 +-- truncate_limit: 100 +SELECT v as value, hash_array(v)::bit(32) as standard, + hash_array_extended(v, 0)::bit(32) as extended0, + hash_array_extended(v, 1)::bit(32) as extended1 +FROM (VALUES ('{0}'::int4[]), ('{0,1,2,3,4}'), ('{17,18,19,20}'), + ('{42,34,65,98}'), ('{550273,590027, 870273}'), + ('{207112489, 807112489}')) x(v) +WHERE hash_array(v)::bit(32) != hash_array_extended(v, 0)::bit(32) + OR hash_array(v)::bit(32) = hash_array_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 017 +-- truncate_limit: 100 +-- array hashing with non-hashable element type +SELECT v as value, hash_array(v)::bit(32) as standard +FROM (VALUES ('{101}'::varbit[])) x(v) +-- +FUNCTION: name="hash_array" function="hash_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v AS value, hash_array(v)::pg_catalog.bit(32) AS standard FROM (VALUES (...)) x(v)" +== 018 +-- truncate_limit: 100 +SELECT v as value, hash_array_extended(v, 0)::bit(32) as extended0 +FROM (VALUES ('{101}'::varbit[])) x(v) +-- +FUNCTION: name="hash_array_extended" function="hash_array_extended" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v)" +== 019 +-- truncate_limit: 100 +SELECT v as value, hashbpchar(v)::bit(32) as standard, + hashbpcharextended(v, 0)::bit(32) as extended0, + hashbpcharextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashbpchar(v)::bit(32) != hashbpcharextended(v, 0)::bit(32) + OR hashbpchar(v)::bit(32) = hashbpcharextended(v, 1)::bit(32) +-- +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FUNCTION: name="hashbpchar" function="hashbpchar" schema="" ctx=Call +FUNCTION: name="hashbpcharextended" function="hashbpcharextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 020 +-- truncate_limit: 100 +SELECT v as value, time_hash(v)::bit(32) as standard, + time_hash_extended(v, 0)::bit(32) as extended0, + time_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::time), ('11:09:59'), ('1:09:59'), ('11:59:59'), + ('7:9:59'), ('5:15:59')) x(v) +WHERE time_hash(v)::bit(32) != time_hash_extended(v, 0)::bit(32) + OR time_hash(v)::bit(32) = time_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FUNCTION: name="time_hash" function="time_hash" schema="" ctx=Call +FUNCTION: name="time_hash_extended" function="time_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 021 +-- truncate_limit: 100 +SELECT v as value, timetz_hash(v)::bit(32) as standard, + timetz_hash_extended(v, 0)::bit(32) as extended0, + timetz_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::timetz), ('00:11:52.518762-07'), ('00:11:52.51762-08'), + ('00:11:52.62-01'), ('00:11:52.62+01'), ('11:59:59+04')) x(v) +WHERE timetz_hash(v)::bit(32) != timetz_hash_extended(v, 0)::bit(32) + OR timetz_hash(v)::bit(32) = timetz_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FUNCTION: name="timetz_hash" function="timetz_hash" schema="" ctx=Call +FUNCTION: name="timetz_hash_extended" function="timetz_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 022 +-- truncate_limit: 100 +SELECT v as value, interval_hash(v)::bit(32) as standard, + interval_hash_extended(v, 0)::bit(32) as extended0, + interval_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::interval), + ('5 month 7 day 46 minutes'), ('1 year 7 day 46 minutes'), + ('1 year 7 month 20 day 46 minutes'), ('5 month'), + ('17 year 11 month 7 day 9 hours 46 minutes 5 seconds')) x(v) +WHERE interval_hash(v)::bit(32) != interval_hash_extended(v, 0)::bit(32) + OR interval_hash(v)::bit(32) = interval_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash_extended" function="interval_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 023 +-- truncate_limit: 100 +SELECT v as value, timestamp_hash(v)::bit(32) as standard, + timestamp_hash_extended(v, 0)::bit(32) as extended0, + timestamp_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::timestamp), ('2017-08-22 00:09:59.518762'), + ('2015-08-20 00:11:52.51762-08'), + ('2017-05-22 00:11:52.62-01'), + ('2013-08-22 00:11:52.62+01'), ('2013-08-22 11:59:59+04')) x(v) +WHERE timestamp_hash(v)::bit(32) != timestamp_hash_extended(v, 0)::bit(32) + OR timestamp_hash(v)::bit(32) = timestamp_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FUNCTION: name="timestamp_hash" function="timestamp_hash" schema="" ctx=Call +FUNCTION: name="timestamp_hash_extended" function="timestamp_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 024 +-- truncate_limit: 100 +SELECT v as value, uuid_hash(v)::bit(32) as standard, + uuid_hash_extended(v, 0)::bit(32) as extended0, + uuid_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::uuid), ('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'), + ('5a9ba4ac-8d6f-11e7-bb31-be2e44b06b34'), + ('99c6705c-d939-461c-a3c9-1690ad64ed7b'), + ('7deed3ca-8d6f-11e7-bb31-be2e44b06b34'), + ('9ad46d4f-6f2a-4edd-aadb-745993928e1e')) x(v) +WHERE uuid_hash(v)::bit(32) != uuid_hash_extended(v, 0)::bit(32) + OR uuid_hash(v)::bit(32) = uuid_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FUNCTION: name="uuid_hash" function="uuid_hash" schema="" ctx=Call +FUNCTION: name="uuid_hash_extended" function="uuid_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 025 +-- truncate_limit: 100 +SELECT v as value, pg_lsn_hash(v)::bit(32) as standard, + pg_lsn_hash_extended(v, 0)::bit(32) as extended0, + pg_lsn_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::pg_lsn), ('16/B374D84'), ('30/B374D84'), + ('255/B374D84'), ('25/B379D90'), ('900/F37FD90')) x(v) +WHERE pg_lsn_hash(v)::bit(32) != pg_lsn_hash_extended(v, 0)::bit(32) + OR pg_lsn_hash(v)::bit(32) = pg_lsn_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash" function="pg_lsn_hash" schema="" ctx=Call +FUNCTION: name="pg_lsn_hash_extended" function="pg_lsn_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 026 +-- truncate_limit: 100 +CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')" +== 027 +-- truncate_limit: 100 +SELECT v as value, hashenum(v)::bit(32) as standard, + hashenumextended(v, 0)::bit(32) as extended0, + hashenumextended(v, 1)::bit(32) as extended1 +FROM (VALUES ('sad'::mood), ('ok'), ('happy')) x(v) +WHERE hashenum(v)::bit(32) != hashenumextended(v, 0)::bit(32) + OR hashenum(v)::bit(32) = hashenumextended(v, 1)::bit(32) +-- +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FUNCTION: name="hashenum" function="hashenum" schema="" ctx=Call +FUNCTION: name="hashenumextended" function="hashenumextended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 028 +-- truncate_limit: 100 +DROP TYPE mood +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE mood" +== 029 +-- truncate_limit: 100 +SELECT v as value, jsonb_hash(v)::bit(32) as standard, + jsonb_hash_extended(v, 0)::bit(32) as extended0, + jsonb_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::jsonb), + ('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'), + ('{"foo": [true, "bar"], "tags": {"e": 1, "f": null}}'), + ('{"g": {"h": "value"}}')) x(v) +WHERE jsonb_hash(v)::bit(32) != jsonb_hash_extended(v, 0)::bit(32) + OR jsonb_hash(v)::bit(32) = jsonb_hash_extended(v, 1)::bit(32) +-- +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FUNCTION: name="jsonb_hash" function="jsonb_hash" schema="" ctx=Call +FUNCTION: name="jsonb_hash_extended" function="jsonb_hash_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 030 +-- truncate_limit: 100 +SELECT v as value, hash_range(v)::bit(32) as standard, + hash_range_extended(v, 0)::bit(32) as extended0, + hash_range_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (int4range(10, 20)), (int4range(23, 43)), + (int4range(5675, 550273)), + (int4range(550274, 1550274)), (int4range(1550275, 208112489))) x(v) +WHERE hash_range(v)::bit(32) != hash_range_extended(v, 0)::bit(32) + OR hash_range(v)::bit(32) = hash_range_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FUNCTION: name="hash_range" function="hash_range" schema="" ctx=Call +FUNCTION: name="hash_range_extended" function="hash_range_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 031 +-- truncate_limit: 100 +SELECT v as value, hash_multirange(v)::bit(32) as standard, + hash_multirange_extended(v, 0)::bit(32) as extended0, + hash_multirange_extended(v, 1)::bit(32) as extended1 +FROM (VALUES ('{[10,20)}'::int4multirange), ('{[23, 43]}'::int4multirange), + ('{[5675, 550273)}'::int4multirange), + ('{[550274, 1550274)}'::int4multirange), + ('{[1550275, 208112489)}'::int4multirange)) x(v) +WHERE hash_multirange(v)::bit(32) != hash_multirange_extended(v, 0)::bit(32) + OR hash_multirange(v)::bit(32) = hash_multirange_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FUNCTION: name="hash_multirange" function="hash_multirange" schema="" ctx=Call +FUNCTION: name="hash_multirange_extended" function="hash_multirange_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 032 +-- truncate_limit: 100 +CREATE TYPE hash_test_t1 AS (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE hash_test_t1 AS (a int, b text)" +== 033 +-- truncate_limit: 100 +SELECT v as value, hash_record(v)::bit(32) as standard, + hash_record_extended(v, 0)::bit(32) as extended0, + hash_record_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (row(1, 'aaa')::hash_test_t1, row(2, 'bbb'), row(-1, 'ccc'))) x(v) +WHERE hash_record(v)::bit(32) != hash_record_extended(v, 0)::bit(32) + OR hash_record(v)::bit(32) = hash_record_extended(v, 1)::bit(32) +-- +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +FILTER: schema="" table="" column="v" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v) WHERE ..." +== 034 +-- truncate_limit: 100 +DROP TYPE hash_test_t1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE hash_test_t1" +== 035 +-- truncate_limit: 100 +-- record hashing with non-hashable field type +CREATE TYPE hash_test_t2 AS (a varbit, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE hash_test_t2 AS (a varbit, b text)" +== 036 +-- truncate_limit: 100 +SELECT v as value, hash_record(v)::bit(32) as standard +FROM (VALUES (row('10'::varbit, 'aaa')::hash_test_t2)) x(v) +-- +FUNCTION: name="hash_record" function="hash_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v AS value, hash_record(v)::pg_catalog.bit(32) AS standard FROM (VALUES (...)) x(v)" +== 037 +-- truncate_limit: 100 +SELECT v as value, hash_record_extended(v, 0)::bit(32) as extended0 +FROM (VALUES (row('11'::varbit, 'aaa')::hash_test_t2)) x(v) +-- +FUNCTION: name="hash_record_extended" function="hash_record_extended" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(v)" +== 038 +-- truncate_limit: 100 +DROP TYPE hash_test_t2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE hash_test_t2" +== 039 +-- truncate_limit: 100 +|-- +-- Check special cases for specific data types +|-- +SELECT hashfloat4('0'::float4) = hashfloat4('-0'::float4) AS t +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT hashfloat4('0'::float4) = hashfloat4('-0'::float4) AS t" +== 040 +-- truncate_limit: 100 +SELECT hashfloat4('NaN'::float4) = hashfloat4(-'NaN'::float4) AS t +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT hashfloat4('NaN'::float4) = hashfloat4(- 'NaN'::float4) AS t" +== 041 +-- truncate_limit: 100 +SELECT hashfloat8('0'::float8) = hashfloat8('-0'::float8) AS t +-- +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT hashfloat8('0'::float8) = hashfloat8('-0'::float8) AS t" +== 042 +-- truncate_limit: 100 +SELECT hashfloat8('NaN'::float8) = hashfloat8(-'NaN'::float8) AS t +-- +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT hashfloat8('NaN'::float8) = hashfloat8(- 'NaN'::float8) AS t" +== 043 +-- truncate_limit: 100 +SELECT hashfloat4('NaN'::float4) = hashfloat8('NaN'::float8) AS t +-- +FUNCTION: name="hashfloat4" function="hashfloat4" schema="" ctx=Call +FUNCTION: name="hashfloat8" function="hashfloat8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT hashfloat4('NaN'::float4) = hashfloat8('NaN'::float8) AS t" diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json b/parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json new file mode 100644 index 0000000..ba349a5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json @@ -0,0 +1,101 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_index.test b/parser/testdata/summary_truncate/postgres_regress/hash_index.test new file mode 100644 index 0000000..07870f0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/hash_index.test @@ -0,0 +1,878 @@ +== 001 +-- truncate_limit: 100 +|-- +-- HASH_INDEX +|-- + +-- directory paths are passed to us in environment variables + +CREATE TABLE hash_i4_heap ( + seqno int4, + random int4 +) +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_i4_heap (seqno int4, random int4)" +== 002 +-- truncate_limit: 100 +CREATE TABLE hash_name_heap ( + seqno int4, + random name +) +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_name_heap (seqno int4, random name)" +== 003 +-- truncate_limit: 100 +CREATE TABLE hash_txt_heap ( + seqno int4, + random text +) +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_txt_heap (seqno int4, random text)" +== 004 +-- truncate_limit: 100 +CREATE TABLE hash_f8_heap ( + seqno int4, + random float8 +) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_f8_heap (seqno int4, random float8)" +== 005 +-- truncate_limit: 100 +COPY hash_i4_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- truncate_limit: 100 +COPY hash_name_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 26 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- truncate_limit: 100 +COPY hash_txt_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- truncate_limit: 100 +COPY hash_f8_heap FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- truncate_limit: 100 +-- the data in this file has a lot of duplicates in the index key +-- fields, leading to long bucket chains and lots of table expansion. +-- this is therefore a stress test of the bucket overflow code (unlike +-- the data in hash.data, which has unique index keys). +|-- +-- \set filename :abs_srcdir '/data/hashovfl.data' +-- COPY hash_ovfl_heap FROM :'filename'; + +ANALYZE hash_i4_heap +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE hash_i4_heap" +== 010 +-- truncate_limit: 100 +ANALYZE hash_name_heap +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE hash_name_heap" +== 011 +-- truncate_limit: 100 +ANALYZE hash_txt_heap +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE hash_txt_heap" +== 012 +-- truncate_limit: 100 +ANALYZE hash_f8_heap +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE hash_f8_heap" +== 013 +-- truncate_limit: 100 +CREATE INDEX hash_i4_index ON hash_i4_heap USING hash (random int4_ops) +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_i4_index ON hash_i4_heap USING hash (random int4_ops)" +== 014 +-- truncate_limit: 100 +CREATE INDEX hash_name_index ON hash_name_heap USING hash (random name_ops) +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_name_index ON hash_name_heap USING hash (random name_ops)" +== 015 +-- truncate_limit: 100 +CREATE INDEX hash_txt_index ON hash_txt_heap USING hash (random text_ops) +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_txt_index ON hash_txt_heap USING hash (random text_ops)" +== 016 +-- truncate_limit: 100 +CREATE INDEX hash_f8_index ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=60) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_f8_index ON hash_f8_heap USING hash (random float8_ops) WITH (fillfactor=60)" +== 017 +-- truncate_limit: 100 +|-- +-- 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)) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX hash_f8_index_1 ON hash_f8_heap USING btree (abs(random))" +== 018 +-- truncate_limit: 100 +create unique index hash_f8_index_2 on hash_f8_heap((seqno + 1), random) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX hash_f8_index_2 ON hash_f8_heap USING btree ((seqno + 1), random)" +== 019 +-- truncate_limit: 100 +create unique index hash_f8_index_3 on hash_f8_heap(random) where seqno > 1000 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX hash_f8_index_3 ON hash_f8_heap USING btree (random) WHERE seqno > 1000" +== 020 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 843938989 hash.data +|-- +SELECT * FROM hash_i4_heap + WHERE hash_i4_heap.random = 843938989 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +FILTER: schema="" table="hash_i4_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_i4_heap WHERE hash_i4_heap.random = 843938989" +== 021 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 66766766 hash.data +|-- +SELECT * FROM hash_i4_heap + WHERE hash_i4_heap.random = 66766766 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +FILTER: schema="" table="hash_i4_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_i4_heap WHERE hash_i4_heap.random = 66766766" +== 022 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 1505703298 hash.data +|-- +SELECT * FROM hash_name_heap + WHERE hash_name_heap.random = '1505703298'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +FILTER: schema="" table="hash_name_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_name_heap WHERE hash_name_heap.random = '1505703298'::name" +== 023 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 7777777 hash.data +|-- +SELECT * FROM hash_name_heap + WHERE hash_name_heap.random = '7777777'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +FILTER: schema="" table="hash_name_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_name_heap WHERE hash_name_heap.random = '7777777'::name" +== 024 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 1351610853 hash.data +|-- +SELECT * FROM hash_txt_heap + WHERE hash_txt_heap.random = '1351610853'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +FILTER: schema="" table="hash_txt_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_txt_heap WHERE hash_txt_heap.random = '1351610853'::text" +== 025 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 111111112222222233333333 hash.data +|-- +SELECT * FROM hash_txt_heap + WHERE hash_txt_heap.random = '111111112222222233333333'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +FILTER: schema="" table="hash_txt_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_txt_heap WHERE hash_txt_heap.random = '111111112222222233333333'::text" +== 026 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 444705537 hash.data +|-- +SELECT * FROM hash_f8_heap + WHERE hash_f8_heap.random = '444705537'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +FILTER: schema="" table="hash_f8_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_f8_heap WHERE hash_f8_heap.random = '444705537'::float8" +== 027 +-- truncate_limit: 100 +|-- +-- hash index +-- grep 88888888 hash.data +|-- +SELECT * FROM hash_f8_heap + WHERE hash_f8_heap.random = '88888888'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +FILTER: schema="" table="hash_f8_heap" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_f8_heap WHERE hash_f8_heap.random = '88888888'::float8" +== 028 +-- truncate_limit: 100 +|-- +-- hash index +-- grep '^90[^0-9]' hashovfl.data +|-- +-- SELECT count(*) AS i988 FROM hash_ovfl_heap +-- WHERE x = 90; + +|-- +-- hash index +-- grep '^1000[^0-9]' hashovfl.data +|-- +-- SELECT count(*) AS i0 FROM hash_ovfl_heap +-- WHERE x = 1000; + +|-- +-- HASH +|-- +UPDATE hash_i4_heap + SET random = 1 + WHERE hash_i4_heap.seqno = 1492 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_i4_heap SET random = 1 WHERE hash_i4_heap.seqno = 1492" +== 029 +-- truncate_limit: 100 +SELECT h.seqno AS i1492, h.random AS i1 + FROM hash_i4_heap h + WHERE h.random = 1 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +ALIAS: "h"="hash_i4_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT h.seqno AS i1492, h.random AS i1 FROM hash_i4_heap h WHERE h.random = 1" +== 030 +-- truncate_limit: 100 +UPDATE hash_i4_heap + SET seqno = 20000 + WHERE hash_i4_heap.random = 1492795354 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_i4_heap SET seqno = 20000 WHERE hash_i4_heap.random = 1492795354" +== 031 +-- truncate_limit: 100 +SELECT h.seqno AS i20000 + FROM hash_i4_heap h + WHERE h.random = 1492795354 +-- +TABLE: name="hash_i4_heap" schema="" table="hash_i4_heap" ctx=Select +ALIAS: "h"="hash_i4_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT h.seqno AS i20000 FROM hash_i4_heap h WHERE h.random = 1492795354" +== 032 +-- truncate_limit: 100 +UPDATE hash_name_heap + SET random = '0123456789abcdef'::name + WHERE hash_name_heap.seqno = 6543 +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_name_heap SET random = '0123456789abcdef'::name WHERE hash_name_heap.seqno = 6543" +== 033 +-- truncate_limit: 100 +SELECT h.seqno AS i6543, h.random AS c0_to_f + FROM hash_name_heap h + WHERE h.random = '0123456789abcdef'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +ALIAS: "h"="hash_name_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_name_heap h WHERE h.random = '0123456789abcdef'::name" +== 034 +-- truncate_limit: 100 +UPDATE hash_name_heap + SET seqno = 20000 + WHERE hash_name_heap.random = '76652222'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_name_heap SET seqno = 20000 WHERE hash_name_heap.random = '76652222'::name" +== 035 +-- truncate_limit: 100 +|-- +-- this is the row we just replaced; index scan should return zero rows +|-- +SELECT h.seqno AS emptyset + FROM hash_name_heap h + WHERE h.random = '76652222'::name +-- +TABLE: name="hash_name_heap" schema="" table="hash_name_heap" ctx=Select +ALIAS: "h"="hash_name_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT h.seqno AS emptyset FROM hash_name_heap h WHERE h.random = '76652222'::name" +== 036 +-- truncate_limit: 100 +UPDATE hash_txt_heap + SET random = '0123456789abcdefghijklmnop'::text + WHERE hash_txt_heap.seqno = 4002 +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_txt_heap SET ... = ... WHERE hash_txt_heap.seqno = 4002" +== 037 +-- truncate_limit: 100 +SELECT h.seqno AS i4002, h.random AS c0_to_p + FROM hash_txt_heap h + WHERE h.random = '0123456789abcdefghijklmnop'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +ALIAS: "h"="hash_txt_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT h.seqno AS i4002, h.random AS c0_to_p FROM hash_txt_heap h WHERE ..." +== 038 +-- truncate_limit: 100 +UPDATE hash_txt_heap + SET seqno = 20000 + WHERE hash_txt_heap.random = '959363399'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_txt_heap SET seqno = 20000 WHERE hash_txt_heap.random = '959363399'::text" +== 039 +-- truncate_limit: 100 +SELECT h.seqno AS t20000 + FROM hash_txt_heap h + WHERE h.random = '959363399'::text +-- +TABLE: name="hash_txt_heap" schema="" table="hash_txt_heap" ctx=Select +ALIAS: "h"="hash_txt_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT h.seqno AS t20000 FROM hash_txt_heap h WHERE h.random = '959363399'::text" +== 040 +-- truncate_limit: 100 +UPDATE hash_f8_heap + SET random = '-1234.1234'::float8 + WHERE hash_f8_heap.seqno = 8906 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_f8_heap SET random = '-1234.1234'::float8 WHERE hash_f8_heap.seqno = 8906" +== 041 +-- truncate_limit: 100 +SELECT h.seqno AS i8096, h.random AS f1234_1234 + FROM hash_f8_heap h + WHERE h.random = '-1234.1234'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +ALIAS: "h"="hash_f8_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_f8_heap h WHERE h.random = '-1234.1234'::float8" +== 042 +-- truncate_limit: 100 +UPDATE hash_f8_heap + SET seqno = 20000 + WHERE hash_f8_heap.random = '488912369'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_f8_heap SET seqno = 20000 WHERE hash_f8_heap.random = '488912369'::float8" +== 043 +-- truncate_limit: 100 +SELECT h.seqno AS f20000 + FROM hash_f8_heap h + WHERE h.random = '488912369'::float8 +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=Select +ALIAS: "h"="hash_f8_heap" +FILTER: schema="" table="h" column="random" +STMT: SelectStmt +TRUNCATED: "SELECT h.seqno AS f20000 FROM hash_f8_heap h WHERE h.random = '488912369'::float8" +== 044 +-- truncate_limit: 100 +-- UPDATE hash_ovfl_heap +-- SET x = 1000 +-- WHERE x = 90; + +-- this vacuums the index as well +-- VACUUM hash_ovfl_heap; + +-- SELECT count(*) AS i0 FROM hash_ovfl_heap +-- WHERE x = 90; + +-- SELECT count(*) AS i988 FROM hash_ovfl_heap +-- WHERE x = 1000; + +|-- +-- Cause some overflow insert and splits. +|-- +CREATE TABLE hash_split_heap (keycol INT) +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_split_heap (keycol int)" +== 045 +-- truncate_limit: 100 +INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 500) a +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 500) a" +== 046 +-- truncate_limit: 100 +CREATE INDEX hash_split_index on hash_split_heap USING HASH (keycol) +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_split_index ON hash_split_heap USING hash (keycol)" +== 047 +-- truncate_limit: 100 +INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 5000) a +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 5000) a" +== 048 +-- truncate_limit: 100 +-- Let's do a backward scan. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 049 +-- truncate_limit: 100 +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 050 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 051 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT * from hash_split_heap WHERE keycol = 1 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT * FROM hash_split_heap WHERE keycol = 1" +== 052 +-- truncate_limit: 100 +MOVE FORWARD ALL FROM c +-- +STMT: FetchStmt +TRUNCATED: "MOVE ALL c" +== 053 +-- truncate_limit: 100 +MOVE BACKWARD 10000 FROM c +-- +STMT: FetchStmt +TRUNCATED: "MOVE BACKWARD 10000 c" +== 054 +-- truncate_limit: 100 +MOVE BACKWARD ALL FROM c +-- +STMT: FetchStmt +TRUNCATED: "MOVE BACKWARD ALL c" +== 055 +-- truncate_limit: 100 +CLOSE c +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE c" +== 056 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 057 +-- truncate_limit: 100 +-- DELETE, INSERT, VACUUM. +DELETE FROM hash_split_heap WHERE keycol = 1 +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM hash_split_heap WHERE keycol = 1" +== 058 +-- truncate_limit: 100 +INSERT INTO hash_split_heap SELECT a/2 FROM generate_series(1, 25000) a +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_split_heap SELECT a / 2 FROM generate_series(1, 25000) a" +== 059 +-- truncate_limit: 100 +VACUUM hash_split_heap +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM hash_split_heap" +== 060 +-- truncate_limit: 100 +-- Rebuild the index using a different fillfactor +ALTER INDEX hash_split_index SET (fillfactor = 10) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX hash_split_index SET (fillfactor=10)" +== 061 +-- truncate_limit: 100 +REINDEX INDEX hash_split_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX hash_split_index" +== 062 +-- truncate_limit: 100 +-- Clean up. +DROP TABLE hash_split_heap +-- +TABLE: name="hash_split_heap" schema="" table="hash_split_heap" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_split_heap" +== 063 +-- truncate_limit: 100 +-- Testcases for removing overflow pages. +CREATE TABLE hash_cleanup_heap(keycol INT) +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_cleanup_heap (keycol int)" +== 064 +-- truncate_limit: 100 +CREATE INDEX hash_cleanup_index on hash_cleanup_heap USING HASH (keycol) +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_cleanup_index ON hash_cleanup_heap USING hash (keycol)" +== 065 +-- truncate_limit: 100 +-- Insert tuples to both the primary bucket page and overflow pages. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) i" +== 066 +-- truncate_limit: 100 +-- Fill overflow pages by "dead" tuples. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 067 +-- truncate_limit: 100 +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1000) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1000) i" +== 068 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 069 +-- truncate_limit: 100 +-- Checkpoint will ensure that all hash buffers are cleaned before we try +-- to remove overflow pages. +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 070 +-- truncate_limit: 100 +-- This will squeeze the bucket and remove overflow pages. +VACUUM hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM hash_cleanup_heap" +== 071 +-- truncate_limit: 100 +TRUNCATE hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE hash_cleanup_heap" +== 072 +-- truncate_limit: 100 +-- Insert a few tuples so that the primary bucket page doesn't get full and +-- tuples can be moved to it. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) i" +== 073 +-- truncate_limit: 100 +-- Fill overflow pages by "dead" tuples. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 074 +-- truncate_limit: 100 +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) i" +== 075 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 076 +-- truncate_limit: 100 +-- And insert some tuples again. During squeeze operation, these will be moved +-- to the primary bucket allowing to test freeing intermediate overflow pages. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) i" +== 077 +-- truncate_limit: 100 +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 078 +-- truncate_limit: 100 +VACUUM hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM hash_cleanup_heap" +== 079 +-- truncate_limit: 100 +TRUNCATE hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE hash_cleanup_heap" +== 080 +-- truncate_limit: 100 +-- Insert tuples to both the primary bucket page and overflow pages. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) i" +== 081 +-- truncate_limit: 100 +-- Fill overflow pages by "dead" tuples. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 082 +-- truncate_limit: 100 +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) i" +== 083 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 084 +-- truncate_limit: 100 +-- And insert some tuples again. During squeeze operation, these will be moved +-- to other overflow pages and also allow overflow pages filled by dead tuples +-- to be freed. Note the main purpose of this test is to test the case where +-- we don't need to move any tuple from the overflow page being freed. +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) as i +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) i" +== 085 +-- truncate_limit: 100 +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 086 +-- truncate_limit: 100 +VACUUM hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM hash_cleanup_heap" +== 087 +-- truncate_limit: 100 +-- Clean up. +DROP TABLE hash_cleanup_heap +-- +TABLE: name="hash_cleanup_heap" schema="" table="hash_cleanup_heap" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_cleanup_heap" +== 088 +-- truncate_limit: 100 +-- Index on temp table. +CREATE TEMP TABLE hash_temp_heap (x int, y int) +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE hash_temp_heap (x int, y int)" +== 089 +-- truncate_limit: 100 +INSERT INTO hash_temp_heap VALUES (1,1) +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_temp_heap VALUES (1, 1)" +== 090 +-- truncate_limit: 100 +CREATE INDEX hash_idx ON hash_temp_heap USING hash (x) +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_idx ON hash_temp_heap USING hash (x)" +== 091 +-- truncate_limit: 100 +DROP TABLE hash_temp_heap CASCADE +-- +TABLE: name="hash_temp_heap" schema="" table="hash_temp_heap" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_temp_heap CASCADE" +== 092 +-- truncate_limit: 100 +-- Float4 type. +CREATE TABLE hash_heap_float4 (x float4, y int) +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_heap_float4 (x float4, y int)" +== 093 +-- truncate_limit: 100 +INSERT INTO hash_heap_float4 VALUES (1.1,1) +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_heap_float4 VALUES (1.1, 1)" +== 094 +-- truncate_limit: 100 +CREATE INDEX hash_idx ON hash_heap_float4 USING hash (x) +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_idx ON hash_heap_float4 USING hash (x)" +== 095 +-- truncate_limit: 100 +DROP TABLE hash_heap_float4 CASCADE +-- +TABLE: name="hash_heap_float4" schema="" table="hash_heap_float4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_heap_float4 CASCADE" +== 096 +-- truncate_limit: 100 +-- Test out-of-range fillfactor values +CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=9) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) WITH (fillfactor=9)" +== 097 +-- truncate_limit: 100 +CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=101) +-- +TABLE: name="hash_f8_heap" schema="" table="hash_f8_heap" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) WITH (fillfactor=101)" diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json b/parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_part.test b/parser/testdata/summary_truncate/postgres_regress/hash_part.test new file mode 100644 index 0000000..2d7412e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/hash_part.test @@ -0,0 +1,240 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Hash partitioning. +|-- + +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different machines. See the definitions of +-- part_test_int4_ops and part_test_text_ops in test_setup.sql. + +CREATE TABLE mchash (a int, b text, c jsonb) + PARTITION BY HASH (a part_test_int4_ops, b part_test_text_ops) +-- +TABLE: name="mchash" schema="" table="mchash" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mchash (a int, b text, c jsonb) PARTITION BY HASH (a part_test_int4_ops, b part_test..." +== 002 +-- truncate_limit: 100 +CREATE TABLE mchash1 + PARTITION OF mchash FOR VALUES WITH (MODULUS 4, REMAINDER 0) +-- +TABLE: name="mchash1" schema="" table="mchash1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mchash1 PARTITION OF mchash FOR VALUES WITH (MODULUS 4, REMAINDER 0)" +== 003 +-- truncate_limit: 100 +-- invalid OID, no such table +SELECT satisfies_hash_partition(0, 4, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition(0, 4, 0, NULL)" +== 004 +-- truncate_limit: 100 +-- not partitioned +SELECT satisfies_hash_partition('tenk1'::regclass, 4, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('tenk1'::regclass, 4, 0, NULL)" +== 005 +-- truncate_limit: 100 +-- partition rather than the parent +SELECT satisfies_hash_partition('mchash1'::regclass, 4, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash1'::regclass, 4, 0, NULL)" +== 006 +-- truncate_limit: 100 +-- invalid modulus +SELECT satisfies_hash_partition('mchash'::regclass, 0, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 0, 0, NULL)" +== 007 +-- truncate_limit: 100 +-- remainder too small +SELECT satisfies_hash_partition('mchash'::regclass, 1, -1, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 1, -1, NULL)" +== 008 +-- truncate_limit: 100 +-- remainder too large +SELECT satisfies_hash_partition('mchash'::regclass, 1, 1, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 1, 1, NULL)" +== 009 +-- truncate_limit: 100 +-- modulus is null +SELECT satisfies_hash_partition('mchash'::regclass, NULL, 0, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, NULL, 0, NULL)" +== 010 +-- truncate_limit: 100 +-- remainder is null +SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL)" +== 011 +-- truncate_limit: 100 +-- too many arguments +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, NULL::int, NULL::text, NULL::json) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 012 +-- truncate_limit: 100 +-- too few arguments +SELECT satisfies_hash_partition('mchash'::regclass, 3, 1, NULL::int) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 3, 1, NULL::int)" +== 013 +-- truncate_limit: 100 +-- wrong argument type +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, NULL::int, NULL::int) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, NULL::int, NULL::int)" +== 014 +-- truncate_limit: 100 +-- ok, should be false +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 0, ''::text) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 0, ''::text)" +== 015 +-- truncate_limit: 100 +-- ok, should be true +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 2, ''::text) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 2, ''::text)" +== 016 +-- truncate_limit: 100 +-- argument via variadic syntax, should fail because not all partitioning +-- columns are of the correct type +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, + variadic array[1,2]::int[]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, VARIADIC ARRAY[1, 2]::int[])" +== 017 +-- truncate_limit: 100 +-- multiple partitioning columns of the same type +CREATE TABLE mcinthash (a int, b int, c jsonb) + PARTITION BY HASH (a part_test_int4_ops, b part_test_int4_ops) +-- +TABLE: name="mcinthash" schema="" table="mcinthash" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcinthash (a int, b int, c jsonb) PARTITION BY HASH (a part_test_int4_ops, b part_te..." +== 018 +-- truncate_limit: 100 +-- now variadic should work, should be false +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[0, 0]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, VARIADIC ARRAY[0, 0])" +== 019 +-- truncate_limit: 100 +-- should be true +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[0, 1]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, VARIADIC ARRAY[0, 1])" +== 020 +-- truncate_limit: 100 +-- wrong length +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[]::int[]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, VARIADIC ARRAY[]::int[])" +== 021 +-- truncate_limit: 100 +-- wrong type +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[now(), now()]) +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, VARIADIC ARRAY[now(), now()])" +== 022 +-- truncate_limit: 100 +-- check satisfies_hash_partition passes correct collation +create table text_hashp (a text) partition by hash (a) +-- +TABLE: name="text_hashp" schema="" table="text_hashp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE text_hashp (a text) PARTITION BY HASH (a)" +== 023 +-- truncate_limit: 100 +create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0) +-- +TABLE: name="text_hashp0" schema="" table="text_hashp0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE text_hashp0 PARTITION OF text_hashp FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 024 +-- truncate_limit: 100 +create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1) +-- +TABLE: name="text_hashp1" schema="" table="text_hashp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE text_hashp1 PARTITION OF text_hashp FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 025 +-- truncate_limit: 100 +-- The result here should always be true, because 'xxx' must belong to +-- one of the two defined partitions +select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR + satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies +-- +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +FUNCTION: name="satisfies_hash_partition" function="satisfies_hash_partition" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 026 +-- truncate_limit: 100 +-- cleanup +DROP TABLE mchash +-- +TABLE: name="mchash" schema="" table="mchash" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mchash" +== 027 +-- truncate_limit: 100 +DROP TABLE mcinthash +-- +TABLE: name="mcinthash" schema="" table="mcinthash" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcinthash" +== 028 +-- truncate_limit: 100 +DROP TABLE text_hashp +-- +TABLE: name="text_hashp" schema="" table="text_hashp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE text_hashp" diff --git a/parser/testdata/summary_truncate/postgres_regress/horology.metadata.json b/parser/testdata/summary_truncate/postgres_regress/horology.metadata.json new file mode 100644 index 0000000..820fe8a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/horology.metadata.json @@ -0,0 +1,392 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/horology.test b/parser/testdata/summary_truncate/postgres_regress/horology.test new file mode 100644 index 0000000..24e28e5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/horology.test @@ -0,0 +1,2771 @@ +== 001 +-- truncate_limit: 100 +|-- +-- HOROLOGY +|-- + +SHOW TimeZone +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TIME ZONE" +== 002 +-- truncate_limit: 100 +-- Many of these tests depend on the prevailing settings +SHOW DateStyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 003 +-- truncate_limit: 100 +|-- +-- Test various input formats +|-- +SELECT timestamp with time zone '20011227 040506+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227 040506+08'::timestamp with time zone" +== 004 +-- truncate_limit: 100 +SELECT timestamp with time zone '20011227 040506-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227 040506-08'::timestamp with time zone" +== 005 +-- truncate_limit: 100 +SELECT timestamp with time zone '20011227 040506.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227 040506.789+08'::timestamp with time zone" +== 006 +-- truncate_limit: 100 +SELECT timestamp with time zone '20011227 040506.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227 040506.789-08'::timestamp with time zone" +== 007 +-- truncate_limit: 100 +SELECT timestamp with time zone '20011227T040506+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227T040506+08'::timestamp with time zone" +== 008 +-- truncate_limit: 100 +SELECT timestamp with time zone '20011227T040506-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227T040506-08'::timestamp with time zone" +== 009 +-- truncate_limit: 100 +SELECT timestamp with time zone '20011227T040506.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227T040506.789+08'::timestamp with time zone" +== 010 +-- truncate_limit: 100 +SELECT timestamp with time zone '20011227T040506.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20011227T040506.789-08'::timestamp with time zone" +== 011 +-- truncate_limit: 100 +SELECT timestamp with time zone '2001-12-27 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001-12-27 04:05:06.789-08'::timestamp with time zone" +== 012 +-- truncate_limit: 100 +SELECT timestamp with time zone '2001.12.27 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001.12.27 04:05:06.789-08'::timestamp with time zone" +== 013 +-- truncate_limit: 100 +SELECT timestamp with time zone '2001/12/27 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001/12/27 04:05:06.789-08'::timestamp with time zone" +== 014 +-- truncate_limit: 100 +SELECT timestamp with time zone '12/27/2001 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12/27/2001 04:05:06.789-08'::timestamp with time zone" +== 015 +-- truncate_limit: 100 +SELECT timestamp with time zone '2001-12-27 04:05:06.789 MET DST' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001-12-27 04:05:06.789 MET DST'::timestamp with time zone" +== 016 +-- truncate_limit: 100 +SELECT timestamp with time zone '2001-12-27 allballs' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001-12-27 allballs'::timestamp with time zone" +== 017 +-- truncate_limit: 100 +-- should fail in mdy mode: +SELECT timestamp with time zone '27/12/2001 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '27/12/2001 04:05:06.789-08'::timestamp with time zone" +== 018 +-- truncate_limit: 100 +set datestyle to dmy +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO dmy" +== 019 +-- truncate_limit: 100 +SELECT timestamp with time zone '27/12/2001 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '27/12/2001 04:05:06.789-08'::timestamp with time zone" +== 020 +-- truncate_limit: 100 +reset datestyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" +== 021 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271+08'::timestamp with time zone" +== 022 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271-08'::timestamp with time zone" +== 023 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271.5+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271.5+08'::timestamp with time zone" +== 024 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271.5-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271.5-08'::timestamp with time zone" +== 025 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271 04:05:06+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271 04:05:06+08'::timestamp with time zone" +== 026 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271 04:05:06-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271 04:05:06-08'::timestamp with time zone" +== 027 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271T040506+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271T040506+08'::timestamp with time zone" +== 028 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271T040506-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271T040506-08'::timestamp with time zone" +== 029 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271T040506.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271T040506.789+08'::timestamp with time zone" +== 030 +-- truncate_limit: 100 +SELECT timestamp with time zone 'J2452271T040506.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271T040506.789-08'::timestamp with time zone" +== 031 +-- truncate_limit: 100 +-- German/European-style dates with periods as delimiters +SELECT timestamp with time zone '12.27.2001 04:05:06.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12.27.2001 04:05:06.789+08'::timestamp with time zone" +== 032 +-- truncate_limit: 100 +SELECT timestamp with time zone '12.27.2001 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12.27.2001 04:05:06.789-08'::timestamp with time zone" +== 033 +-- truncate_limit: 100 +SET DateStyle = 'German' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"German\"" +== 034 +-- truncate_limit: 100 +SELECT timestamp with time zone '27.12.2001 04:05:06.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '27.12.2001 04:05:06.789+08'::timestamp with time zone" +== 035 +-- truncate_limit: 100 +SELECT timestamp with time zone '27.12.2001 04:05:06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '27.12.2001 04:05:06.789-08'::timestamp with time zone" +== 036 +-- truncate_limit: 100 +SET DateStyle = 'ISO' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"ISO\"" +== 037 +-- truncate_limit: 100 +-- As of 7.4, allow time without time zone having a time zone specified +SELECT time without time zone '040506.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506.789+08'::time" +== 038 +-- truncate_limit: 100 +SELECT time without time zone '040506.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506.789-08'::time" +== 039 +-- truncate_limit: 100 +SELECT time without time zone 'T040506.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.789+08'::time" +== 040 +-- truncate_limit: 100 +SELECT time without time zone 'T040506.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.789-08'::time" +== 041 +-- truncate_limit: 100 +SELECT time with time zone '040506.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506.789+08'::time with time zone" +== 042 +-- truncate_limit: 100 +SELECT time with time zone '040506.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506.789-08'::time with time zone" +== 043 +-- truncate_limit: 100 +SELECT time with time zone 'T040506.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.789+08'::time with time zone" +== 044 +-- truncate_limit: 100 +SELECT time with time zone 'T040506.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.789-08'::time with time zone" +== 045 +-- truncate_limit: 100 +SELECT time with time zone 'T040506.789 +08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.789 +08'::time with time zone" +== 046 +-- truncate_limit: 100 +SELECT time with time zone 'T040506.789 -08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.789 -08'::time with time zone" +== 047 +-- truncate_limit: 100 +-- time with time zone should accept a date for DST resolution purposes +SELECT time with time zone 'T040506.789 America/Los_Angeles' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.789 America/Los_Angeles'::time with time zone" +== 048 +-- truncate_limit: 100 +SELECT time with time zone '2001-12-27 T040506.789 America/Los_Angeles' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001-12-27 T040506.789 America/Los_Angeles'::time with time zone" +== 049 +-- truncate_limit: 100 +SELECT time with time zone 'J2452271 T040506.789 America/Los_Angeles' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J2452271 T040506.789 America/Los_Angeles'::time with time zone" +== 050 +-- truncate_limit: 100 +-- Check time formats required by ISO 8601 +SELECT time without time zone '040506.07' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506.07'::time" +== 051 +-- truncate_limit: 100 +SELECT time without time zone '04:05:06.07' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '04:05:06.07'::time" +== 052 +-- truncate_limit: 100 +SELECT time without time zone '040506' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506'::time" +== 053 +-- truncate_limit: 100 +SELECT time without time zone '04:05:06' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '04:05:06'::time" +== 054 +-- truncate_limit: 100 +SELECT time without time zone '0405' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0405'::time" +== 055 +-- truncate_limit: 100 +SELECT time without time zone '04:05' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '04:05'::time" +== 056 +-- truncate_limit: 100 +SELECT time without time zone 'T040506.07' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.07'::time" +== 057 +-- truncate_limit: 100 +SELECT time without time zone 'T04:05:06.07' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04:05:06.07'::time" +== 058 +-- truncate_limit: 100 +SELECT time without time zone 'T040506' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506'::time" +== 059 +-- truncate_limit: 100 +SELECT time without time zone 'T04:05:06' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04:05:06'::time" +== 060 +-- truncate_limit: 100 +SELECT time without time zone 'T0405' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T0405'::time" +== 061 +-- truncate_limit: 100 +SELECT time without time zone 'T04:05' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04:05'::time" +== 062 +-- truncate_limit: 100 +-- 8601 says "Thh" is allowed, but we intentionally reject it as too vague +SELECT time without time zone 'T04' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04'::time" +== 063 +-- truncate_limit: 100 +SELECT time with time zone '040506.07+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506.07+08'::time with time zone" +== 064 +-- truncate_limit: 100 +SELECT time with time zone '04:05:06.07+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '04:05:06.07+08'::time with time zone" +== 065 +-- truncate_limit: 100 +SELECT time with time zone '040506+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '040506+08'::time with time zone" +== 066 +-- truncate_limit: 100 +SELECT time with time zone '04:05:06+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '04:05:06+08'::time with time zone" +== 067 +-- truncate_limit: 100 +SELECT time with time zone '0405+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0405+08'::time with time zone" +== 068 +-- truncate_limit: 100 +SELECT time with time zone '04:05+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '04:05+08'::time with time zone" +== 069 +-- truncate_limit: 100 +SELECT time with time zone 'T040506.07+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506.07+08'::time with time zone" +== 070 +-- truncate_limit: 100 +SELECT time with time zone 'T04:05:06.07+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04:05:06.07+08'::time with time zone" +== 071 +-- truncate_limit: 100 +SELECT time with time zone 'T040506+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T040506+08'::time with time zone" +== 072 +-- truncate_limit: 100 +SELECT time with time zone 'T04:05:06+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04:05:06+08'::time with time zone" +== 073 +-- truncate_limit: 100 +SELECT time with time zone 'T0405+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T0405+08'::time with time zone" +== 074 +-- truncate_limit: 100 +SELECT time with time zone 'T04:05+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04:05+08'::time with time zone" +== 075 +-- truncate_limit: 100 +-- 8601 says "Thh" is allowed, but we intentionally reject it as too vague +SELECT time with time zone 'T04+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'T04+08'::time with time zone" +== 076 +-- truncate_limit: 100 +SET DateStyle = 'Postgres, MDY' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"Postgres, MDY\"" +== 077 +-- truncate_limit: 100 +-- Check Julian dates BC +SELECT date 'J1520447' AS "Confucius' Birthday" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J1520447'::date AS \"Confucius' Birthday\"" +== 078 +-- truncate_limit: 100 +SELECT date 'J0' AS "Julian Epoch" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J0'::date AS \"Julian Epoch\"" +== 079 +-- truncate_limit: 100 +-- test error on dangling Julian units +SELECT date '1995-08-06 J J J' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 J J J'::date" +== 080 +-- truncate_limit: 100 +SELECT date 'J J 1520447' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'J J 1520447'::date" +== 081 +-- truncate_limit: 100 +-- We used to accept this input style, but it was based on a misreading +-- of ISO8601, and it was never documented anyway +SELECT timestamp with time zone 'Y2001M12D27H04M05S06.789+08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Y2001M12D27H04M05S06.789+08'::timestamp with time zone" +== 082 +-- truncate_limit: 100 +SELECT timestamp with time zone 'Y2001M12D27H04MM05S06.789-08' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Y2001M12D27H04MM05S06.789-08'::timestamp with time zone" +== 083 +-- truncate_limit: 100 +-- conflicting fields should throw errors +SELECT date '1995-08-06 epoch' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 epoch'::date" +== 084 +-- truncate_limit: 100 +SELECT date '1995-08-06 infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 infinity'::date" +== 085 +-- truncate_limit: 100 +SELECT date '1995-08-06 -infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 -infinity'::date" +== 086 +-- truncate_limit: 100 +SELECT date 'today infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'today infinity'::date" +== 087 +-- truncate_limit: 100 +SELECT date '-infinity infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity infinity'::date" +== 088 +-- truncate_limit: 100 +SELECT timestamp '1995-08-06 epoch' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 epoch'::timestamp" +== 089 +-- truncate_limit: 100 +SELECT timestamp '1995-08-06 infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 infinity'::timestamp" +== 090 +-- truncate_limit: 100 +SELECT timestamp '1995-08-06 -infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 -infinity'::timestamp" +== 091 +-- truncate_limit: 100 +SELECT timestamp 'epoch 01:01:01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'epoch 01:01:01'::timestamp" +== 092 +-- truncate_limit: 100 +SELECT timestamp 'infinity 01:01:01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity 01:01:01'::timestamp" +== 093 +-- truncate_limit: 100 +SELECT timestamp '-infinity 01:01:01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity 01:01:01'::timestamp" +== 094 +-- truncate_limit: 100 +SELECT timestamp 'now epoch' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'now epoch'::timestamp" +== 095 +-- truncate_limit: 100 +SELECT timestamp '-infinity infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity infinity'::timestamp" +== 096 +-- truncate_limit: 100 +SELECT timestamptz '1995-08-06 epoch' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 epoch'::timestamptz" +== 097 +-- truncate_limit: 100 +SELECT timestamptz '1995-08-06 infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 infinity'::timestamptz" +== 098 +-- truncate_limit: 100 +SELECT timestamptz '1995-08-06 -infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1995-08-06 -infinity'::timestamptz" +== 099 +-- truncate_limit: 100 +SELECT timestamptz 'epoch 01:01:01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'epoch 01:01:01'::timestamptz" +== 100 +-- truncate_limit: 100 +SELECT timestamptz 'infinity 01:01:01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity 01:01:01'::timestamptz" +== 101 +-- truncate_limit: 100 +SELECT timestamptz '-infinity 01:01:01' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity 01:01:01'::timestamptz" +== 102 +-- truncate_limit: 100 +SELECT timestamptz 'now epoch' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'now epoch'::timestamptz" +== 103 +-- truncate_limit: 100 +SELECT timestamptz '-infinity infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity infinity'::timestamptz" +== 104 +-- truncate_limit: 100 +|-- +-- date, time arithmetic +|-- + +SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1981-02-03'::date + '04:05:06'::time AS \"Date + Time\"" +== 105 +-- truncate_limit: 100 +SELECT date '1991-02-03' + time with time zone '04:05:06 PST' AS "Date + Time PST" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1991-02-03'::date + '04:05:06 PST'::time with time zone AS \"Date + Time PST\"" +== 106 +-- truncate_limit: 100 +SELECT date '2001-02-03' + time with time zone '04:05:06 UTC' AS "Date + Time UTC" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001-02-03'::date + '04:05:06 UTC'::time with time zone AS \"Date + Time UTC\"" +== 107 +-- truncate_limit: 100 +SELECT date '1991-02-03' + interval '2 years' AS "Add Two Years" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1991-02-03'::date + '2 years'::interval AS \"Add Two Years\"" +== 108 +-- truncate_limit: 100 +SELECT date '2001-12-13' - interval '2 years' AS "Subtract Two Years" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2001-12-13'::date - '2 years'::interval AS \"Subtract Two Years\"" +== 109 +-- truncate_limit: 100 +-- subtract time from date should not make sense; use interval instead +SELECT date '1991-02-03' - time '04:05:06' AS "Subtract Time" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1991-02-03'::date - '04:05:06'::time AS \"Subtract Time\"" +== 110 +-- truncate_limit: 100 +SELECT date '1991-02-03' - time with time zone '04:05:06 UTC' AS "Subtract Time UTC" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1991-02-03'::date - '04:05:06 UTC'::time with time zone AS \"Subtract Time UTC\"" +== 111 +-- truncate_limit: 100 +|-- +-- timestamp, interval arithmetic +|-- + +SELECT timestamp without time zone '1996-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1996-03-01'::timestamp - '1 second'::interval AS \"Feb 29\"" +== 112 +-- truncate_limit: 100 +SELECT timestamp without time zone '1999-03-01' - interval '1 second' AS "Feb 28" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-03-01'::timestamp - '1 second'::interval AS \"Feb 28\"" +== 113 +-- truncate_limit: 100 +SELECT timestamp without time zone '2000-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2000-03-01'::timestamp - '1 second'::interval AS \"Feb 29\"" +== 114 +-- truncate_limit: 100 +SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-12-01'::timestamp + '1 month - 1 second'::interval AS \"Dec 31\"" +== 115 +-- truncate_limit: 100 +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 1, 4713 BC'::timestamp + '106000000 days'::interval AS \"Feb 23, 285506\"" +== 116 +-- truncate_limit: 100 +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 1, 4713 BC'::timestamp + '107000000 days'::interval AS \"Jan 20, 288244\"" +== 117 +-- truncate_limit: 100 +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Jan 1, 4713 BC'::timestamp + '109203489 days'::interval AS \"Dec 31, 294276\"" +== 118 +-- truncate_limit: 100 +SELECT timestamp without time zone '2000-01-01' - interval '2483590 days' AS "out of range" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2000-01-01'::timestamp - '2483590 days'::interval AS \"out of range\"" +== 119 +-- truncate_limit: 100 +SELECT timestamp without time zone '294276-12-31 23:59:59' + interval '9223372036854775807 microseconds' AS "out of range" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 120 +-- truncate_limit: 100 +SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12/31/294276'::timestamp - '12/23/1999'::timestamp AS \"106751991 Days\"" +== 121 +-- truncate_limit: 100 +-- Shorthand values +-- Not directly usable for regression testing since these are not constants. +-- So, just try to test parser and hope for the best - thomas 97/04/26 +SELECT (timestamp without time zone 'today' = (timestamp without time zone 'yesterday' + interval '1 day')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'today'::timestamp = ('yesterday'::timestamp + '1 day'::interval) AS \"True\"" +== 122 +-- truncate_limit: 100 +SELECT (timestamp without time zone 'today' = (timestamp without time zone 'tomorrow' - interval '1 day')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'today'::timestamp = ('tomorrow'::timestamp - '1 day'::interval) AS \"True\"" +== 123 +-- truncate_limit: 100 +SELECT (timestamp without time zone 'today 10:30' = (timestamp without time zone 'yesterday' + interval '1 day 10 hr 30 min')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 124 +-- truncate_limit: 100 +SELECT (timestamp without time zone '10:30 today' = (timestamp without time zone 'yesterday' + interval '1 day 10 hr 30 min')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 125 +-- truncate_limit: 100 +SELECT (timestamp without time zone 'tomorrow' = (timestamp without time zone 'yesterday' + interval '2 days')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'tomorrow'::timestamp = ('yesterday'::timestamp + '2 days'::interval) AS \"True\"" +== 126 +-- truncate_limit: 100 +SELECT (timestamp without time zone 'tomorrow 16:00:00' = (timestamp without time zone 'today' + interval '1 day 16 hours')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'tomorrow 16:00:00'::timestamp = ('today'::timestamp + '1 day 16 hours'::interval) AS \"True\"" +== 127 +-- truncate_limit: 100 +SELECT (timestamp without time zone '16:00:00 tomorrow' = (timestamp without time zone 'today' + interval '1 day 16 hours')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '16:00:00 tomorrow'::timestamp = ('today'::timestamp + '1 day 16 hours'::interval) AS \"True\"" +== 128 +-- truncate_limit: 100 +SELECT (timestamp without time zone 'yesterday 12:34:56' = (timestamp without time zone 'tomorrow' - interval '2 days - 12:34:56')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 129 +-- truncate_limit: 100 +SELECT (timestamp without time zone '12:34:56 yesterday' = (timestamp without time zone 'tomorrow' - interval '2 days - 12:34:56')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 130 +-- truncate_limit: 100 +SELECT (timestamp without time zone 'tomorrow' > 'now') as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'tomorrow'::timestamp > 'now' AS \"True\"" +== 131 +-- truncate_limit: 100 +-- Convert from date and time to timestamp +-- This test used to be timestamp(date,time) but no longer allowed by grammar +-- to enable support for SQL99 timestamp type syntax. +SELECT date '1994-01-01' + time '11:00' AS "Jan_01_1994_11am" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1994-01-01'::date + '11:00'::time AS \"Jan_01_1994_11am\"" +== 132 +-- truncate_limit: 100 +SELECT date '1994-01-01' + time '10:00' AS "Jan_01_1994_10am" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1994-01-01'::date + '10:00'::time AS \"Jan_01_1994_10am\"" +== 133 +-- truncate_limit: 100 +SELECT date '1994-01-01' + timetz '11:00-5' AS "Jan_01_1994_8am" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1994-01-01'::date + '11:00-5'::timetz AS \"Jan_01_1994_8am\"" +== 134 +-- truncate_limit: 100 +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timestamptz('1994-01-01'::date, '11:00-5'::time with time zone) AS \"Jan_01_1994_8am\"" +== 135 +-- truncate_limit: 100 +SELECT d1 + interval '1 year' AS one_year FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 + '1 year'::interval AS one_year FROM timestamp_tbl" +== 136 +-- truncate_limit: 100 +SELECT d1 - interval '1 year' AS one_year FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 - '1 year'::interval AS one_year FROM timestamp_tbl" +== 137 +-- truncate_limit: 100 +SELECT timestamp with time zone '1996-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1996-03-01'::timestamp with time zone - '1 second'::interval AS \"Feb 29\"" +== 138 +-- truncate_limit: 100 +SELECT timestamp with time zone '1999-03-01' - interval '1 second' AS "Feb 28" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-03-01'::timestamp with time zone - '1 second'::interval AS \"Feb 28\"" +== 139 +-- truncate_limit: 100 +SELECT timestamp with time zone '2000-03-01' - interval '1 second' AS "Feb 29" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2000-03-01'::timestamp with time zone - '1 second'::interval AS \"Feb 29\"" +== 140 +-- truncate_limit: 100 +SELECT timestamp with time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1999-12-01'::timestamp with time zone + '1 month - 1 second'::interval AS \"Dec 31\"" +== 141 +-- truncate_limit: 100 +SELECT timestamp with time zone '2000-01-01' - interval '2483590 days' AS "out of range" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2000-01-01'::timestamp with time zone - '2483590 days'::interval AS \"out of range\"" +== 142 +-- truncate_limit: 100 +SELECT timestamp with time zone '294276-12-31 23:59:59 UTC' + interval '9223372036854775807 microseconds' AS "out of range" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 143 +-- truncate_limit: 100 +SELECT (timestamp with time zone 'today' = (timestamp with time zone 'yesterday' + interval '1 day')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 144 +-- truncate_limit: 100 +SELECT (timestamp with time zone 'today' = (timestamp with time zone 'tomorrow' - interval '1 day')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 145 +-- truncate_limit: 100 +SELECT (timestamp with time zone 'tomorrow' = (timestamp with time zone 'yesterday' + interval '2 days')) as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 146 +-- truncate_limit: 100 +SELECT (timestamp with time zone 'tomorrow' > 'now') as "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'tomorrow'::timestamp with time zone > 'now' AS \"True\"" +== 147 +-- truncate_limit: 100 +-- timestamp with time zone, interval arithmetic around DST change +-- (just for fun, let's use an intentionally nonstandard POSIX zone spec) +SET TIME ZONE 'CST7CDT,M4.1.0,M10.5.0' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"CST7CDT,M4.1.0,M10.5.0\"" +== 148 +-- truncate_limit: 100 +SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' as "Apr 3, 12:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2005-04-02 12:00-07'::timestamp with time zone + '1 day'::interval AS \"Apr 3, 12:00\"" +== 149 +-- truncate_limit: 100 +SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '24 hours' as "Apr 3, 13:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2005-04-02 12:00-07'::timestamp with time zone + '24 hours'::interval AS \"Apr 3, 13:00\"" +== 150 +-- truncate_limit: 100 +SELECT timestamp with time zone '2005-04-03 12:00-06' - interval '1 day' as "Apr 2, 12:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2005-04-03 12:00-06'::timestamp with time zone - '1 day'::interval AS \"Apr 2, 12:00\"" +== 151 +-- truncate_limit: 100 +SELECT timestamp with time zone '2005-04-03 12:00-06' - interval '24 hours' as "Apr 2, 11:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2005-04-03 12:00-06'::timestamp with time zone - '24 hours'::interval AS \"Apr 2, 11:00\"" +== 152 +-- truncate_limit: 100 +RESET TIME ZONE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" +== 153 +-- truncate_limit: 100 +SELECT timestamptz(date '1994-01-01', time '11:00') AS "Jan_01_1994_10am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timestamptz('1994-01-01'::date, '11:00'::time) AS \"Jan_01_1994_10am\"" +== 154 +-- truncate_limit: 100 +SELECT timestamptz(date '1994-01-01', time '10:00') AS "Jan_01_1994_9am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timestamptz('1994-01-01'::date, '10:00'::time) AS \"Jan_01_1994_9am\"" +== 155 +-- truncate_limit: 100 +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-8') AS "Jan_01_1994_11am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timestamptz('1994-01-01'::date, '11:00-8'::time with time zone) AS \"Jan_01_1994_11am\"" +== 156 +-- truncate_limit: 100 +SELECT timestamptz(date '1994-01-01', time with time zone '10:00-8') AS "Jan_01_1994_10am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timestamptz('1994-01-01'::date, '10:00-8'::time with time zone) AS \"Jan_01_1994_10am\"" +== 157 +-- truncate_limit: 100 +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am" +-- +FUNCTION: name="timestamptz" function="timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timestamptz('1994-01-01'::date, '11:00-5'::time with time zone) AS \"Jan_01_1994_8am\"" +== 158 +-- truncate_limit: 100 +SELECT d1 + interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 + '1 year'::interval AS one_year FROM timestamptz_tbl" +== 159 +-- truncate_limit: 100 +SELECT d1 - interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 - '1 year'::interval AS one_year FROM timestamptz_tbl" +== 160 +-- truncate_limit: 100 +|-- +-- time, interval arithmetic +|-- + +SELECT CAST(time '01:02' AS interval) AS "+01:02" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01:02'::time::interval AS \"+01:02\"" +== 161 +-- truncate_limit: 100 +SELECT CAST(interval '02:03' AS time) AS "02:03:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '02:03'::interval::time AS \"02:03:00\"" +== 162 +-- truncate_limit: 100 +SELECT CAST(interval '-02:03' AS time) AS "21:57:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-02:03'::interval::time AS \"21:57:00\"" +== 163 +-- truncate_limit: 100 +SELECT CAST(interval '-9223372022400000000 us' AS time) AS "00:00:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372022400000000 us'::interval::time AS \"00:00:00\"" +== 164 +-- truncate_limit: 100 +SELECT time '01:30' + interval '02:01' AS "03:31:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01:30'::time + '02:01'::interval AS \"03:31:00\"" +== 165 +-- truncate_limit: 100 +SELECT time '01:30' - interval '02:01' AS "23:29:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01:30'::time - '02:01'::interval AS \"23:29:00\"" +== 166 +-- truncate_limit: 100 +SELECT time '02:30' + interval '36:01' AS "14:31:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '02:30'::time + '36:01'::interval AS \"14:31:00\"" +== 167 +-- truncate_limit: 100 +SELECT time '03:30' + interval '1 month 04:01' AS "07:31:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '03:30'::time + '1 month 04:01'::interval AS \"07:31:00\"" +== 168 +-- truncate_limit: 100 +SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01:02-08'::time with time zone::interval AS \"+00:01\"" +== 169 +-- truncate_limit: 100 +SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '02:03'::interval::time with time zone AS \"02:03:00-08\"" +== 170 +-- truncate_limit: 100 +SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01:30-08'::time with time zone - '02:01'::interval AS \"23:29:00-08\"" +== 171 +-- truncate_limit: 100 +SELECT time with time zone '02:30-08' + interval '36:01' AS "14:31:00-08" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '02:30-08'::time with time zone + '36:01'::interval AS \"14:31:00-08\"" +== 172 +-- truncate_limit: 100 +-- These two tests cannot be used because they default to current timezone, +-- which may be either -08 or -07 depending on the time of year. +-- SELECT time with time zone '01:30' + interval '02:01' AS "03:31:00-08"; +-- SELECT time with time zone '03:30' + interval '1 month 04:01' AS "07:31:00-08"; +-- Try the following two tests instead, as a poor substitute + +SELECT CAST(CAST(date 'today' + time with time zone '05:30' + + interval '02:01' AS time with time zone) AS time) AS "07:31:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 173 +-- truncate_limit: 100 +SELECT CAST(cast(date 'today' + time with time zone '03:30' + + interval '1 month 04:01' as timestamp without time zone) AS time) AS "07:31:00" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 174 +-- truncate_limit: 100 +SELECT t.d1 AS t, i.f1 AS i, t.d1 + i.f1 AS "add", t.d1 - i.f1 AS "subtract" + FROM TIMESTAMP_TBL t, INTERVAL_TBL i + WHERE t.d1 BETWEEN '1990-01-01' AND '2001-01-01' + AND i.f1 BETWEEN '00:00' AND '23:00' + ORDER BY 1,2 +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "i"="interval_tbl" +ALIAS: "t"="timestamp_tbl" +FILTER: schema="" table="t" column="d1" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl t, interval_tbl i WHERE ... ORDER BY 1, 2" +== 175 +-- truncate_limit: 100 +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 + WHERE isfinite(i.f1) + ORDER BY 1,2 +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "i"="interval_tbl" +ALIAS: "t"="time_tbl" +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM time_tbl t, interval_tbl i WHERE isfinite(i.f1) ORDER BY 1, 2" +== 176 +-- truncate_limit: 100 +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 + WHERE isfinite(i.f1) + ORDER BY 1,2 +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "i"="interval_tbl" +ALIAS: "t"="timetz_tbl" +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timetz_tbl t, interval_tbl i WHERE isfinite(i.f1) ORDER BY 1, 2" +== 177 +-- truncate_limit: 100 +-- 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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 178 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 179 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 180 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 181 +-- truncate_limit: 100 +SELECT (timestamp with time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp with time zone '2000-11-27', interval '12 hours') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 182 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 183 +-- truncate_limit: 100 +-- 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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 184 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 185 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 186 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 187 +-- truncate_limit: 100 +SELECT (timestamp without time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp without time zone '2000-11-27', interval '12 hours') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 188 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 189 +-- truncate_limit: 100 +-- test time and interval +SELECT (time '00:00', time '01:00') + OVERLAPS (time '00:30', time '01:30') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ('00:00'::time, '01:00'::time) overlaps ('00:30'::time, '01:30'::time) AS \"True\"" +== 190 +-- truncate_limit: 100 +SELECT (time '00:00', interval '1 hour') + OVERLAPS (time '00:30', interval '1 hour') AS "True" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ('00:00'::time, '1 hour'::interval) overlaps ('00:30'::time, '1 hour'::interval) AS \"True\"" +== 191 +-- truncate_limit: 100 +SELECT (time '00:00', interval '1 hour') + OVERLAPS (time '01:30', interval '1 hour') AS "False" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ('00:00'::time, '1 hour'::interval) overlaps ('01:30'::time, '1 hour'::interval) AS \"False\"" +== 192 +-- truncate_limit: 100 +-- 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" +-- +FUNCTION: name="pg_catalog.overlaps" function="overlaps" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ('00:00'::time, '1 hour'::interval) overlaps ('01:30'::time, '1 day'::interval) AS \"False\"" +== 193 +-- truncate_limit: 100 +CREATE TABLE TEMP_TIMESTAMP (f1 timestamp with time zone) +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE temp_timestamp (f1 timestamp with time zone)" +== 194 +-- truncate_limit: 100 +-- 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' +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=DML +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +FILTER: schema="" table="" column="d1" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temp_timestamp (f1) SELECT d1 FROM timestamp_tbl WHERE ..." +== 195 +-- truncate_limit: 100 +SELECT f1 AS "timestamp" + FROM TEMP_TIMESTAMP + ORDER BY "timestamp" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"timestamp\" FROM temp_timestamp ORDER BY \"timestamp\"" +== 196 +-- truncate_limit: 100 +SELECT 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" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "d"="temp_timestamp" +ALIAS: "t"="interval_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM temp_timestamp d, interval_tbl t ORDER BY plus, \"timestamp\", \"interval\"" +== 197 +-- truncate_limit: 100 +SELECT d.f1 AS "timestamp", t.f1 AS "interval", d.f1 - t.f1 AS minus + FROM TEMP_TIMESTAMP d, INTERVAL_TBL t + ORDER BY minus, "timestamp", "interval" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "d"="temp_timestamp" +ALIAS: "t"="interval_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM temp_timestamp d, interval_tbl t ORDER BY minus, \"timestamp\", \"interval\"" +== 198 +-- truncate_limit: 100 +SELECT 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 +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +ALIAS: "d"="temp_timestamp" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM temp_timestamp d ORDER BY difference" +== 199 +-- truncate_limit: 100 +SELECT 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 +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +ALIAS: "d1"="temp_timestamp" +ALIAS: "d2"="temp_timestamp" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM temp_timestamp d1, temp_timestamp d2 ORDER BY timestamp1, timestamp2, difference" +== 200 +-- truncate_limit: 100 +|-- +-- Conversions +|-- + +SELECT f1 AS "timestamp", date(f1) AS date + FROM TEMP_TIMESTAMP + WHERE f1 <> timestamp 'now' + ORDER BY date, "timestamp" +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=Select +FUNCTION: name="date" function="date" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM temp_timestamp WHERE f1 <> 'now'::timestamp ORDER BY date, \"timestamp\"" +== 201 +-- truncate_limit: 100 +DROP TABLE TEMP_TIMESTAMP +-- +TABLE: name="temp_timestamp" schema="" table="temp_timestamp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_timestamp" +== 202 +-- truncate_limit: 100 +|-- +-- Comparisons between datetime types, especially overflow cases +--- + +SELECT '2202020-10-05'::date::timestamp +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2202020-10-05'::date::timestamp" +== 203 +-- truncate_limit: 100 +-- fail +SELECT '2202020-10-05'::date > '2020-10-05'::timestamp as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2202020-10-05'::date > '2020-10-05'::timestamp AS t" +== 204 +-- truncate_limit: 100 +SELECT '2020-10-05'::timestamp > '2202020-10-05'::date as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2020-10-05'::timestamp > '2202020-10-05'::date AS f" +== 205 +-- truncate_limit: 100 +SELECT '2202020-10-05'::date::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2202020-10-05'::date::timestamptz" +== 206 +-- truncate_limit: 100 +-- fail +SELECT '2202020-10-05'::date > '2020-10-05'::timestamptz as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2202020-10-05'::date > '2020-10-05'::timestamptz AS t" +== 207 +-- truncate_limit: 100 +SELECT '2020-10-05'::timestamptz > '2202020-10-05'::date as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2020-10-05'::timestamptz > '2202020-10-05'::date AS f" +== 208 +-- truncate_limit: 100 +-- This conversion may work depending on timezone +SELECT '4714-11-24 BC'::date::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-24 BC'::date::timestamptz" +== 209 +-- truncate_limit: 100 +SET TimeZone = 'UTC-2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"UTC-2\"" +== 210 +-- truncate_limit: 100 +SELECT '4714-11-24 BC'::date::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-24 BC'::date::timestamptz" +== 211 +-- truncate_limit: 100 +-- fail + +SELECT '4714-11-24 BC'::date < '2020-10-05'::timestamptz as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-24 BC'::date < '2020-10-05'::timestamptz AS t" +== 212 +-- truncate_limit: 100 +SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::date as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::date AS t" +== 213 +-- truncate_limit: 100 +SELECT '4714-11-24 BC'::timestamp < '2020-10-05'::timestamptz as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-24 BC'::timestamp < '2020-10-05'::timestamptz AS t" +== 214 +-- truncate_limit: 100 +SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::timestamp as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::timestamp AS t" +== 215 +-- truncate_limit: 100 +RESET TimeZone +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" +== 216 +-- truncate_limit: 100 +|-- +-- Tests for BETWEEN +|-- + +explain (costs off) +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM date_tbl WHERE f1 BETWEEN '1997-01-01' AND '1998-01-01'" +== 217 +-- truncate_limit: 100 +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM date_tbl WHERE f1 BETWEEN '1997-01-01' AND '1998-01-01'" +== 218 +-- truncate_limit: 100 +explain (costs off) +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM date_tbl WHERE f1 NOT BETWEEN '1997-01-01' AND '1998-01-01'" +== 219 +-- truncate_limit: 100 +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM date_tbl WHERE f1 NOT BETWEEN '1997-01-01' AND '1998-01-01'" +== 220 +-- truncate_limit: 100 +explain (costs off) +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM date_tbl WHERE f1 BETWEEN SYMMETRIC '1997-01-01' AND '19..." +== 221 +-- truncate_limit: 100 +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM date_tbl WHERE f1 BETWEEN SYMMETRIC '1997-01-01' AND '1998-01-01'" +== 222 +-- truncate_limit: 100 +explain (costs off) +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM date_tbl WHERE f1 NOT BETWEEN SYMMETRIC '1997-01-01' AND..." +== 223 +-- truncate_limit: 100 +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01' +-- +TABLE: name="date_tbl" schema="" table="date_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM date_tbl WHERE f1 NOT BETWEEN SYMMETRIC '1997-01-01' AND '1998-01-01'" +== 224 +-- truncate_limit: 100 +|-- +-- Formats +|-- + +SET DateStyle TO 'US,Postgres' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"US,Postgres\"" +== 225 +-- truncate_limit: 100 +SHOW DateStyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 226 +-- truncate_limit: 100 +SELECT d1 AS us_postgres FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 AS us_postgres FROM timestamp_tbl" +== 227 +-- truncate_limit: 100 +SET DateStyle TO 'US,ISO' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"US,ISO\"" +== 228 +-- truncate_limit: 100 +SELECT d1 AS us_iso FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 AS us_iso FROM timestamp_tbl" +== 229 +-- truncate_limit: 100 +SET DateStyle TO 'US,SQL' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"US,SQL\"" +== 230 +-- truncate_limit: 100 +SHOW DateStyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 231 +-- truncate_limit: 100 +SELECT d1 AS us_sql FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 AS us_sql FROM timestamp_tbl" +== 232 +-- truncate_limit: 100 +SET DateStyle TO 'European,Postgres' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"European,Postgres\"" +== 233 +-- truncate_limit: 100 +SHOW DateStyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 234 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES('13/06/1957') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('13/06/1957')" +== 235 +-- truncate_limit: 100 +SELECT count(*) as one FROM TIMESTAMP_TBL WHERE d1 = 'Jun 13 1957' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamp_tbl WHERE d1 = 'Jun 13 1957'" +== 236 +-- truncate_limit: 100 +SELECT d1 AS european_postgres FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 AS european_postgres FROM timestamp_tbl" +== 237 +-- truncate_limit: 100 +SET DateStyle TO 'European,ISO' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"European,ISO\"" +== 238 +-- truncate_limit: 100 +SHOW DateStyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 239 +-- truncate_limit: 100 +SELECT d1 AS european_iso FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 AS european_iso FROM timestamp_tbl" +== 240 +-- truncate_limit: 100 +SET DateStyle TO 'European,SQL' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"European,SQL\"" +== 241 +-- truncate_limit: 100 +SHOW DateStyle +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW datestyle" +== 242 +-- truncate_limit: 100 +SELECT d1 AS european_sql FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 AS european_sql FROM timestamp_tbl" +== 243 +-- truncate_limit: 100 +RESET DateStyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" +== 244 +-- truncate_limit: 100 +|-- +-- to_timestamp() +|-- + +SELECT to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS')" +== 245 +-- truncate_limit: 100 +SELECT to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS')" +== 246 +-- truncate_limit: 100 +SELECT to_timestamp('2011$03!18 23_38_15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011$03!18 23_38_15', 'YYYY-MM-DD HH24:MI:SS')" +== 247 +-- truncate_limit: 100 +SELECT to_timestamp('1985 January 12', 'YYYY FMMonth DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1985 January 12', 'YYYY FMMonth DD')" +== 248 +-- truncate_limit: 100 +SELECT to_timestamp('1985 FMMonth 12', 'YYYY "FMMonth" DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1985 FMMonth 12', 'YYYY \"FMMonth\" DD')" +== 249 +-- truncate_limit: 100 +SELECT to_timestamp('1985 \ 12', 'YYYY \\ DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(E'1985 \\\\ 12', E'YYYY \\\\\\\\ DD')" +== 250 +-- truncate_limit: 100 +SELECT to_timestamp('My birthday-> Year: 1976, Month: May, Day: 16', + '"My birthday-> Year:" YYYY, "Month:" FMMonth, "Day:" DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 251 +-- truncate_limit: 100 +SELECT to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD')" +== 252 +-- truncate_limit: 100 +SELECT to_timestamp('15 "text between quote marks" 98 54 45', + E'HH24 "\\"text between quote marks\\"" YY MI SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 253 +-- truncate_limit: 100 +SELECT to_timestamp('05121445482000', 'MMDDHH24MISSYYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('05121445482000', 'MMDDHH24MISSYYYY')" +== 254 +-- truncate_limit: 100 +SELECT to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay')" +== 255 +-- truncate_limit: 100 +SELECT to_timestamp('97/Feb/16', 'YYMonDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('97/Feb/16', 'YYMonDD')" +== 256 +-- truncate_limit: 100 +SELECT to_timestamp('97/Feb/16', 'YY:Mon:DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('97/Feb/16', 'YY:Mon:DD')" +== 257 +-- truncate_limit: 100 +SELECT to_timestamp('97/Feb/16', 'FXYY:Mon:DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('97/Feb/16', 'FXYY:Mon:DD')" +== 258 +-- truncate_limit: 100 +SELECT to_timestamp('97/Feb/16', 'FXYY/Mon/DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('97/Feb/16', 'FXYY/Mon/DD')" +== 259 +-- truncate_limit: 100 +SELECT to_timestamp('19971116', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('19971116', 'YYYYMMDD')" +== 260 +-- truncate_limit: 100 +SELECT to_timestamp('20000-1116', 'YYYY-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('20000-1116', 'YYYY-MMDD')" +== 261 +-- truncate_limit: 100 +SELECT to_timestamp('1997 AD 11 16', 'YYYY BC MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1997 AD 11 16', 'YYYY BC MM DD')" +== 262 +-- truncate_limit: 100 +SELECT to_timestamp('1997 BC 11 16', 'YYYY BC MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1997 BC 11 16', 'YYYY BC MM DD')" +== 263 +-- truncate_limit: 100 +SELECT to_timestamp('1997 A.D. 11 16', 'YYYY B.C. MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1997 A.D. 11 16', 'YYYY B.C. MM DD')" +== 264 +-- truncate_limit: 100 +SELECT to_timestamp('1997 B.C. 11 16', 'YYYY B.C. MM DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1997 B.C. 11 16', 'YYYY B.C. MM DD')" +== 265 +-- truncate_limit: 100 +SELECT to_timestamp('9-1116', 'Y-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('9-1116', 'Y-MMDD')" +== 266 +-- truncate_limit: 100 +SELECT to_timestamp('95-1116', 'YY-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('95-1116', 'YY-MMDD')" +== 267 +-- truncate_limit: 100 +SELECT to_timestamp('995-1116', 'YYY-MMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('995-1116', 'YYY-MMDD')" +== 268 +-- truncate_limit: 100 +SELECT to_timestamp('2005426', 'YYYYWWD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2005426', 'YYYYWWD')" +== 269 +-- truncate_limit: 100 +SELECT to_timestamp('2005300', 'YYYYDDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2005300', 'YYYYDDD')" +== 270 +-- truncate_limit: 100 +SELECT to_timestamp('2005527', 'IYYYIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2005527', 'IYYYIWID')" +== 271 +-- truncate_limit: 100 +SELECT to_timestamp('005527', 'IYYIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('005527', 'IYYIWID')" +== 272 +-- truncate_limit: 100 +SELECT to_timestamp('05527', 'IYIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('05527', 'IYIWID')" +== 273 +-- truncate_limit: 100 +SELECT to_timestamp('5527', 'IIWID') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('5527', 'IIWID')" +== 274 +-- truncate_limit: 100 +SELECT to_timestamp('2005364', 'IYYYIDDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2005364', 'IYYYIDDD')" +== 275 +-- truncate_limit: 100 +SELECT to_timestamp('20050302', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('20050302', 'YYYYMMDD')" +== 276 +-- truncate_limit: 100 +SELECT to_timestamp('2005 03 02', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2005 03 02', 'YYYYMMDD')" +== 277 +-- truncate_limit: 100 +SELECT to_timestamp(' 2005 03 02', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(' 2005 03 02', 'YYYYMMDD')" +== 278 +-- truncate_limit: 100 +SELECT to_timestamp(' 20050302', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(' 20050302', 'YYYYMMDD')" +== 279 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 AM', 'YYYY-MM-DD HH12:MI PM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 AM', 'YYYY-MM-DD HH12:MI PM')" +== 280 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 PM', 'YYYY-MM-DD HH12:MI PM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 PM', 'YYYY-MM-DD HH12:MI PM')" +== 281 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 A.M.', 'YYYY-MM-DD HH12:MI P.M.') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 A.M.', 'YYYY-MM-DD HH12:MI P.M.')" +== 282 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 P.M.', 'YYYY-MM-DD HH12:MI P.M.') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 P.M.', 'YYYY-MM-DD HH12:MI P.M.')" +== 283 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 +05', 'YYYY-MM-DD HH12:MI TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 +05', 'YYYY-MM-DD HH12:MI TZH')" +== 284 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZH')" +== 285 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 +05:20', 'YYYY-MM-DD HH12:MI TZH:TZM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 +05:20', 'YYYY-MM-DD HH12:MI TZH:TZM')" +== 286 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 -05:20', 'YYYY-MM-DD HH12:MI TZH:TZM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 -05:20', 'YYYY-MM-DD HH12:MI TZH:TZM')" +== 287 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM')" +== 288 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 EST', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 EST', 'YYYY-MM-DD HH12:MI TZ')" +== 289 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZ')" +== 290 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI TZ')" +== 291 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 MSK', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 MSK', 'YYYY-MM-DD HH12:MI TZ')" +== 292 +-- truncate_limit: 100 +-- dyntz +SELECT to_timestamp('2011-12-18 11:38ESTFOO24', 'YYYY-MM-DD HH12:MITZFOOSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38ESTFOO24', 'YYYY-MM-DD HH12:MITZFOOSS')" +== 293 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38-05FOO24', 'YYYY-MM-DD HH12:MITZFOOSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38-05FOO24', 'YYYY-MM-DD HH12:MITZFOOSS')" +== 294 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 JUNK', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 JUNK', 'YYYY-MM-DD HH12:MI TZ')" +== 295 +-- truncate_limit: 100 +-- error +SELECT to_timestamp('2011-12-18 11:38 ...', 'YYYY-MM-DD HH12:MI TZ') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 ...', 'YYYY-MM-DD HH12:MI TZ')" +== 296 +-- truncate_limit: 100 +-- error + +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI OF')" +== 297 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI OF')" +== 298 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 11:38 +xyz', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 +xyz', 'YYYY-MM-DD HH12:MI OF')" +== 299 +-- truncate_limit: 100 +-- error +SELECT to_timestamp('2011-12-18 11:38 +01:xyz', 'YYYY-MM-DD HH12:MI OF') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 11:38 +01:xyz', 'YYYY-MM-DD HH12:MI OF')" +== 300 +-- truncate_limit: 100 +-- error + +SELECT to_timestamp('2018-11-02 12:34:56.025', 'YYYY-MM-DD HH24:MI:SS.MS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2018-11-02 12:34:56.025', 'YYYY-MM-DD HH24:MI:SS.MS')" +== 301 +-- truncate_limit: 100 +SELECT i, to_timestamp('2018-11-02 12:34:56', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 302 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 303 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 304 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 305 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 306 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 307 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 308 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 309 +-- truncate_limit: 100 +SELECT i, to_timestamp('20181102123456123456', 'YYYYMMDDHH24MISSFF' || i) FROM generate_series(1, 6) i +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 6) i" +== 310 +-- truncate_limit: 100 +SELECT to_date('1 4 1902', 'Q MM YYYY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('1 4 1902', 'Q MM YYYY')" +== 311 +-- truncate_limit: 100 +-- Q is ignored +SELECT to_date('3 4 21 01', 'W MM CC YY') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('3 4 21 01', 'W MM CC YY')" +== 312 +-- truncate_limit: 100 +SELECT to_date('2458872', 'J') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2458872', 'J')" +== 313 +-- truncate_limit: 100 +|-- +-- Check handling of BC dates +|-- + +SELECT to_date('44-02-01 BC','YYYY-MM-DD BC') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('44-02-01 BC', 'YYYY-MM-DD BC')" +== 314 +-- truncate_limit: 100 +SELECT to_date('-44-02-01','YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('-44-02-01', 'YYYY-MM-DD')" +== 315 +-- truncate_limit: 100 +SELECT to_date('-44-02-01 BC','YYYY-MM-DD BC') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('-44-02-01 BC', 'YYYY-MM-DD BC')" +== 316 +-- truncate_limit: 100 +SELECT to_timestamp('44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('44-02-01 11:12:13 BC', 'YYYY-MM-DD HH24:MI:SS BC')" +== 317 +-- truncate_limit: 100 +SELECT to_timestamp('-44-02-01 11:12:13','YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('-44-02-01 11:12:13', 'YYYY-MM-DD HH24:MI:SS')" +== 318 +-- truncate_limit: 100 +SELECT to_timestamp('-44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('-44-02-01 11:12:13 BC', 'YYYY-MM-DD HH24:MI:SS BC')" +== 319 +-- truncate_limit: 100 +|-- +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS')" +== 320 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS')" +== 321 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS')" +== 322 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS')" +== 323 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS')" +== 324 +-- truncate_limit: 100 +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS')" +== 325 +-- truncate_limit: 100 +SELECT to_timestamp('2000+ JUN', 'YYYY/MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000+ JUN', 'YYYY/MON')" +== 326 +-- truncate_limit: 100 +SELECT to_timestamp(' 2000 +JUN', 'YYYY/MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(' 2000 +JUN', 'YYYY/MON')" +== 327 +-- truncate_limit: 100 +SELECT to_timestamp(' 2000 +JUN', 'YYYY//MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(' 2000 +JUN', 'YYYY//MON')" +== 328 +-- truncate_limit: 100 +SELECT to_timestamp('2000 +JUN', 'YYYY//MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000 +JUN', 'YYYY//MON')" +== 329 +-- truncate_limit: 100 +SELECT to_timestamp('2000 + JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000 + JUN', 'YYYY MON')" +== 330 +-- truncate_limit: 100 +SELECT to_timestamp('2000 ++ JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000 ++ JUN', 'YYYY MON')" +== 331 +-- truncate_limit: 100 +SELECT to_timestamp('2000 + + JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000 + + JUN', 'YYYY MON')" +== 332 +-- truncate_limit: 100 +SELECT to_timestamp('2000 + + JUN', 'YYYY MON') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000 + + JUN', 'YYYY MON')" +== 333 +-- truncate_limit: 100 +SELECT to_timestamp('2000 -10', 'YYYY TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000 -10', 'YYYY TZH')" +== 334 +-- truncate_limit: 100 +SELECT to_timestamp('2000 -10', 'YYYY TZH') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2000 -10', 'YYYY TZH')" +== 335 +-- truncate_limit: 100 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 12 18', 'YYYY MM DD')" +== 336 +-- truncate_limit: 100 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 12 18', 'YYYY MM DD')" +== 337 +-- truncate_limit: 100 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 12 18', 'YYYY MM DD')" +== 338 +-- truncate_limit: 100 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 12 18', 'YYYY MM DD')" +== 339 +-- truncate_limit: 100 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 12 18', 'YYYY MM DD')" +== 340 +-- truncate_limit: 100 +SELECT to_date('2011 12 18', 'YYYY MM DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 12 18', 'YYYY MM DD')" +== 341 +-- truncate_limit: 100 +SELECT to_date('2011 12 18', 'YYYYxMMxDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 12 18', 'YYYYxMMxDD')" +== 342 +-- truncate_limit: 100 +SELECT to_date('2011x 12x 18', 'YYYYxMMxDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011x 12x 18', 'YYYYxMMxDD')" +== 343 +-- truncate_limit: 100 +SELECT to_date('2011 x12 x18', 'YYYYxMMxDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2011 x12 x18', 'YYYYxMMxDD')" +== 344 +-- truncate_limit: 100 +|-- +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2005527', 'YYYYIWID')" +== 345 +-- truncate_limit: 100 +-- Insufficient characters in the source string: +SELECT to_timestamp('19971', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('19971', 'YYYYMMDD')" +== 346 +-- truncate_limit: 100 +-- Insufficient digit characters for a single node: +SELECT to_timestamp('19971)24', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('19971)24', 'YYYYMMDD')" +== 347 +-- truncate_limit: 100 +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('Friday 1-January-1999', 'DY DD MON YYYY')" +== 348 +-- truncate_limit: 100 +SELECT to_timestamp('Fri 1-January-1999', 'DY DD MON YYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('Fri 1-January-1999', 'DY DD MON YYYY')" +== 349 +-- truncate_limit: 100 +SELECT to_timestamp('Fri 1-Jan-1999', 'DY DD MON YYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('Fri 1-Jan-1999', 'DY DD MON YYYY')" +== 350 +-- truncate_limit: 100 +-- ok + +-- Value clobbering: +SELECT to_timestamp('1997-11-Jan-16', 'YYYY-MM-Mon-DD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('1997-11-Jan-16', 'YYYY-MM-Mon-DD')" +== 351 +-- truncate_limit: 100 +-- Non-numeric input: +SELECT to_timestamp('199711xy', 'YYYYMMDD') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('199711xy', 'YYYYMMDD')" +== 352 +-- truncate_limit: 100 +-- Input that doesn't fit in an int: +SELECT to_timestamp('10000000000', 'FMYYYY') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('10000000000', 'FMYYYY')" +== 353 +-- truncate_limit: 100 +-- 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') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-06-13 25:00:00', 'YYYY-MM-DD HH24:MI:SS')" +== 354 +-- truncate_limit: 100 +SELECT to_timestamp('2016-06-13 15:60:00', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-06-13 15:60:00', 'YYYY-MM-DD HH24:MI:SS')" +== 355 +-- truncate_limit: 100 +SELECT to_timestamp('2016-06-13 15:50:60', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-06-13 15:50:60', 'YYYY-MM-DD HH24:MI:SS')" +== 356 +-- truncate_limit: 100 +SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH24:MI:SS')" +== 357 +-- truncate_limit: 100 +-- ok +SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH:MI:SS')" +== 358 +-- truncate_limit: 100 +SELECT to_timestamp('2016-13-01 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-13-01 15:50:55', 'YYYY-MM-DD HH24:MI:SS')" +== 359 +-- truncate_limit: 100 +SELECT to_timestamp('2016-02-30 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-02-30 15:50:55', 'YYYY-MM-DD HH24:MI:SS')" +== 360 +-- truncate_limit: 100 +SELECT to_timestamp('2016-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2016-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS')" +== 361 +-- truncate_limit: 100 +-- ok +SELECT to_timestamp('2015-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2015-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS')" +== 362 +-- truncate_limit: 100 +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSS')" +== 363 +-- truncate_limit: 100 +-- ok +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSS')" +== 364 +-- truncate_limit: 100 +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSSS')" +== 365 +-- truncate_limit: 100 +-- ok +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSSS') +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSSS')" +== 366 +-- truncate_limit: 100 +SELECT to_date('2016-13-10', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2016-13-10', 'YYYY-MM-DD')" +== 367 +-- truncate_limit: 100 +SELECT to_date('2016-02-30', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2016-02-30', 'YYYY-MM-DD')" +== 368 +-- truncate_limit: 100 +SELECT to_date('2016-02-29', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2016-02-29', 'YYYY-MM-DD')" +== 369 +-- truncate_limit: 100 +-- ok +SELECT to_date('2015-02-29', 'YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2015-02-29', 'YYYY-MM-DD')" +== 370 +-- truncate_limit: 100 +SELECT to_date('2015 365', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2015 365', 'YYYY DDD')" +== 371 +-- truncate_limit: 100 +-- ok +SELECT to_date('2015 366', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2015 366', 'YYYY DDD')" +== 372 +-- truncate_limit: 100 +SELECT to_date('2016 365', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2016 365', 'YYYY DDD')" +== 373 +-- truncate_limit: 100 +-- ok +SELECT to_date('2016 366', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2016 366', 'YYYY DDD')" +== 374 +-- truncate_limit: 100 +-- ok +SELECT to_date('2016 367', 'YYYY DDD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('2016 367', 'YYYY DDD')" +== 375 +-- truncate_limit: 100 +SELECT to_date('0000-02-01','YYYY-MM-DD') +-- +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_date('0000-02-01', 'YYYY-MM-DD')" +== 376 +-- truncate_limit: 100 +-- allowed, though it shouldn't be + +-- to_char's TZ format code produces zone abbrev if known +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ')" +== 377 +-- truncate_limit: 100 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS tz') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS tz')" +== 378 +-- truncate_limit: 100 +|-- +-- Check behavior with SQL-style fixed-GMT-offset time zone (cf bug #8572) +|-- + +SET TIME ZONE 'America/New_York' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"America/New_York\"" +== 379 +-- truncate_limit: 100 +SET TIME ZONE '-1.5' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-1.5\"" +== 380 +-- truncate_limit: 100 +SHOW TIME ZONE +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TIME ZONE" +== 381 +-- truncate_limit: 100 +SELECT '2012-12-12 12:00'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2012-12-12 12:00'::timestamptz" +== 382 +-- truncate_limit: 100 +SELECT '2012-12-12 12:00 America/New_York'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2012-12-12 12:00 America/New_York'::timestamptz" +== 383 +-- truncate_limit: 100 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ')" +== 384 +-- truncate_limit: 100 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSS') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSS')" +== 385 +-- truncate_limit: 100 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSSS') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSSS')" +== 386 +-- truncate_limit: 100 +SET TIME ZONE '+2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"+2\"" +== 387 +-- truncate_limit: 100 +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ')" +== 388 +-- truncate_limit: 100 +RESET TIME ZONE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" diff --git a/parser/testdata/summary_truncate/postgres_regress/identity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/identity.metadata.json new file mode 100644 index 0000000..a6ce2f7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/identity.metadata.json @@ -0,0 +1,274 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/identity.test b/parser/testdata/summary_truncate/postgres_regress/identity.test new file mode 100644 index 0000000..df315af --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/identity.test @@ -0,0 +1,2140 @@ +== 001 +-- truncate_limit: 100 +-- sanity check of system catalog +SELECT attrelid, attname, attidentity FROM pg_attribute WHERE attidentity NOT IN ('', 'a', 'd') +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attidentity" +STMT: SelectStmt +TRUNCATED: "SELECT attrelid, attname, attidentity FROM pg_attribute WHERE attidentity NOT IN ('', 'a', 'd')" +== 002 +-- truncate_limit: 100 +CREATE TABLE itest1 (a int generated by default as identity, b text) +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest1 (a int GENERATED BY DEFAULT AS IDENTITY, b text)" +== 003 +-- truncate_limit: 100 +CREATE TABLE itest2 (a bigint generated always as identity, b text) +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest2 (a bigint GENERATED ALWAYS AS IDENTITY, b text)" +== 004 +-- truncate_limit: 100 +CREATE TABLE itest3 (a smallint generated by default as identity (start with 7 increment by 5), b text) +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest3 (a smallint GENERATED BY DEFAULT AS IDENTITY (START 7 INCREMENT 5 ), b text)" +== 005 +-- truncate_limit: 100 +ALTER TABLE itest3 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest3 ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 006 +-- truncate_limit: 100 +-- error + +SELECT table_name, column_name, column_default, is_nullable, is_identity, identity_generation, identity_start, identity_increment, identity_maximum, identity_minimum, identity_cycle FROM information_schema.columns WHERE table_name LIKE 'itest_' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name LIKE 'itest_' ORDER BY 1, 2" +== 007 +-- truncate_limit: 100 +-- internal sequences should not be shown here +SELECT sequence_name FROM information_schema.sequences WHERE sequence_name LIKE 'itest%' +-- +TABLE: name="information_schema.sequences" schema="information_schema" table="sequences" ctx=Select +FILTER: schema="" table="" column="sequence_name" +STMT: SelectStmt +TRUNCATED: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name LIKE 'itest%'" +== 008 +-- truncate_limit: 100 +SELECT pg_get_serial_sequence('itest1', 'a') +-- +FUNCTION: name="pg_get_serial_sequence" function="pg_get_serial_sequence" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_serial_sequence('itest1', 'a')" +== 009 +-- truncate_limit: 100 +CREATE TABLE itest4 (a int, b text) +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest4 (a int, b text)" +== 010 +-- truncate_limit: 100 +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 011 +-- truncate_limit: 100 +-- error, requires NOT NULL +ALTER TABLE itest4 ALTER COLUMN a SET NOT NULL +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER COLUMN a SET NOT NULL" +== 012 +-- truncate_limit: 100 +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 013 +-- truncate_limit: 100 +-- ok +ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL" +== 014 +-- truncate_limit: 100 +-- error, disallowed +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 015 +-- truncate_limit: 100 +-- error, already set +ALTER TABLE itest4 ALTER COLUMN b ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER b ADD GENERATED ALWAYS AS IDENTITY" +== 016 +-- truncate_limit: 100 +-- error, wrong data type + +-- for later +ALTER TABLE itest4 ALTER COLUMN b SET DEFAULT '' +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER COLUMN b SET DEFAULT ''" +== 017 +-- truncate_limit: 100 +-- invalid column type +CREATE TABLE itest_err_1 (a text generated by default as identity) +-- +TABLE: name="itest_err_1" schema="" table="itest_err_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest_err_1 (a text GENERATED BY DEFAULT AS IDENTITY)" +== 018 +-- truncate_limit: 100 +-- duplicate identity +CREATE TABLE itest_err_2 (a int generated always as identity generated by default as identity) +-- +TABLE: name="itest_err_2" schema="" table="itest_err_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest_err_2 (a int GENERATED ALWAYS AS IDENTITY GENERATED BY DEFAULT AS IDENTITY)" +== 019 +-- truncate_limit: 100 +-- cannot have default and identity +CREATE TABLE itest_err_3 (a int default 5 generated by default as identity) +-- +TABLE: name="itest_err_3" schema="" table="itest_err_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest_err_3 (a int DEFAULT 5 GENERATED BY DEFAULT AS IDENTITY)" +== 020 +-- truncate_limit: 100 +-- cannot combine serial and identity +CREATE TABLE itest_err_4 (a serial generated by default as identity) +-- +TABLE: name="itest_err_4" schema="" table="itest_err_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest_err_4 (a serial GENERATED BY DEFAULT AS IDENTITY)" +== 021 +-- truncate_limit: 100 +INSERT INTO itest1 DEFAULT VALUES +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest1 DEFAULT VALUES" +== 022 +-- truncate_limit: 100 +INSERT INTO itest1 DEFAULT VALUES +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest1 DEFAULT VALUES" +== 023 +-- truncate_limit: 100 +INSERT INTO itest2 DEFAULT VALUES +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest2 DEFAULT VALUES" +== 024 +-- truncate_limit: 100 +INSERT INTO itest2 DEFAULT VALUES +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest2 DEFAULT VALUES" +== 025 +-- truncate_limit: 100 +INSERT INTO itest3 DEFAULT VALUES +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest3 DEFAULT VALUES" +== 026 +-- truncate_limit: 100 +INSERT INTO itest3 DEFAULT VALUES +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest3 DEFAULT VALUES" +== 027 +-- truncate_limit: 100 +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest4 DEFAULT VALUES" +== 028 +-- truncate_limit: 100 +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest4 DEFAULT VALUES" +== 029 +-- truncate_limit: 100 +SELECT * FROM itest1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest1" +== 030 +-- truncate_limit: 100 +SELECT * FROM itest2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest2" +== 031 +-- truncate_limit: 100 +SELECT * FROM itest3 +-- +TABLE: name="itest3" schema="" table="itest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest3" +== 032 +-- truncate_limit: 100 +SELECT * FROM itest4 +-- +TABLE: name="itest4" schema="" table="itest4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest4" +== 033 +-- truncate_limit: 100 +-- VALUES RTEs + +CREATE TABLE itest5 (a int generated always as identity, b text) +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest5 (a int GENERATED ALWAYS AS IDENTITY, b text)" +== 034 +-- truncate_limit: 100 +INSERT INTO itest5 VALUES (1, 'a') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 VALUES (1, 'a')" +== 035 +-- truncate_limit: 100 +-- error +INSERT INTO itest5 VALUES (DEFAULT, 'a') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 VALUES (DEFAULT, 'a')" +== 036 +-- truncate_limit: 100 +-- ok +INSERT INTO itest5 VALUES (2, 'b'), (3, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 VALUES (2, 'b'), (3, 'c')" +== 037 +-- truncate_limit: 100 +-- error +INSERT INTO itest5 VALUES (DEFAULT, 'b'), (3, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 VALUES (DEFAULT, 'b'), (3, 'c')" +== 038 +-- truncate_limit: 100 +-- error +INSERT INTO itest5 VALUES (2, 'b'), (DEFAULT, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 VALUES (2, 'b'), (DEFAULT, 'c')" +== 039 +-- truncate_limit: 100 +-- error +INSERT INTO itest5 VALUES (DEFAULT, 'b'), (DEFAULT, 'c') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 VALUES (DEFAULT, 'b'), (DEFAULT, 'c')" +== 040 +-- truncate_limit: 100 +-- ok + +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-1, 'aa') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-1, 'aa')" +== 041 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-2, 'bb'), (-3, 'cc') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-2, 'bb'), (-3, 'cc')" +== 042 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'dd'), (-4, 'ee') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'dd'), (-4, 'ee')" +== 043 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-5, 'ff'), (DEFAULT, 'gg') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-5, 'ff'), (DEFAULT, 'gg')" +== 044 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'hh'), (DEFAULT, 'ii') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'hh'), (DEFAULT, 'ii')" +== 045 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-1, 'aaa') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-1, 'aaa')" +== 046 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-2, 'bbb'), (-3, 'ccc') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-2, 'bbb'), (-3, 'ccc')" +== 047 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'ddd'), (-4, 'eee') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'ddd'), (-4, 'eee')" +== 048 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-5, 'fff'), (DEFAULT, 'ggg') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-5, 'fff'), (DEFAULT, 'ggg')" +== 049 +-- truncate_limit: 100 +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'hhh'), (DEFAULT, 'iii') +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'hhh'), (DEFAULT, 'iii')" +== 050 +-- truncate_limit: 100 +SELECT * FROM itest5 +-- +TABLE: name="itest5" schema="" table="itest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest5" +== 051 +-- truncate_limit: 100 +DROP TABLE itest5 +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE itest5" +== 052 +-- truncate_limit: 100 +INSERT INTO itest3 VALUES (DEFAULT, 'a') +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest3 VALUES (DEFAULT, 'a')" +== 053 +-- truncate_limit: 100 +INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c') +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c')" +== 054 +-- truncate_limit: 100 +SELECT * FROM itest3 +-- +TABLE: name="itest3" schema="" table="itest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest3" +== 055 +-- truncate_limit: 100 +-- OVERRIDING tests + +-- GENERATED BY DEFAULT + +-- This inserts the row as presented: +INSERT INTO itest1 VALUES (10, 'xyz') +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest1 VALUES (10, 'xyz')" +== 056 +-- truncate_limit: 100 +-- With GENERATED BY DEFAULT, OVERRIDING SYSTEM VALUE is not allowed +-- by the standard, but we allow it as a no-op, since it is of use if +-- there are multiple identity columns in a table, which is also an +-- extension. +INSERT INTO itest1 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz') +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest1 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz')" +== 057 +-- truncate_limit: 100 +-- This ignores the 30 and uses the sequence value instead: +INSERT INTO itest1 OVERRIDING USER VALUE VALUES (30, 'xyz') +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest1 OVERRIDING USER VALUE VALUES (30, 'xyz')" +== 058 +-- truncate_limit: 100 +SELECT * FROM itest1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest1" +== 059 +-- truncate_limit: 100 +-- GENERATED ALWAYS + +-- This is an error: +INSERT INTO itest2 VALUES (10, 'xyz') +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest2 VALUES (10, 'xyz')" +== 060 +-- truncate_limit: 100 +-- This inserts the row as presented: +INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz') +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz')" +== 061 +-- truncate_limit: 100 +-- This ignores the 30 and uses the sequence value instead: +INSERT INTO itest2 OVERRIDING USER VALUE VALUES (30, 'xyz') +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest2 OVERRIDING USER VALUE VALUES (30, 'xyz')" +== 062 +-- truncate_limit: 100 +SELECT * FROM itest2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest2" +== 063 +-- truncate_limit: 100 +-- UPDATE tests + +-- GENERATED BY DEFAULT is not restricted. +UPDATE itest1 SET a = 101 WHERE a = 1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE itest1 SET a = 101 WHERE a = 1" +== 064 +-- truncate_limit: 100 +UPDATE itest1 SET a = DEFAULT WHERE a = 2 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE itest1 SET a = DEFAULT WHERE a = 2" +== 065 +-- truncate_limit: 100 +SELECT * FROM itest1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest1" +== 066 +-- truncate_limit: 100 +-- GENERATED ALWAYS allows only DEFAULT. +UPDATE itest2 SET a = 101 WHERE a = 1 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE itest2 SET a = 101 WHERE a = 1" +== 067 +-- truncate_limit: 100 +-- error +UPDATE itest2 SET a = DEFAULT WHERE a = 2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE itest2 SET a = DEFAULT WHERE a = 2" +== 068 +-- truncate_limit: 100 +-- ok +SELECT * FROM itest2 +-- +TABLE: name="itest2" schema="" table="itest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest2" +== 069 +-- truncate_limit: 100 +-- COPY tests + +CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint) +-- +TABLE: name="itest9" schema="" table="itest9" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint)" +== 070 +-- truncate_limit: 100 +COPY itest9 FROM stdin +-- +TABLE: name="itest9" schema="" table="itest9" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY itest9 FROM STDIN" +== 071 +-- truncate_limit: 100 +COPY itest9 (b, c) FROM stdin +-- +TABLE: name="itest9" schema="" table="itest9" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY itest9(b, c) FROM STDIN" +== 072 +-- truncate_limit: 100 +SELECT * FROM itest9 ORDER BY c +-- +TABLE: name="itest9" schema="" table="itest9" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest9 ORDER BY c" +== 073 +-- truncate_limit: 100 +-- DROP IDENTITY tests + +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY" +== 074 +-- truncate_limit: 100 +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY" +== 075 +-- truncate_limit: 100 +-- error +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY IF EXISTS +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY IF EXISTS" +== 076 +-- truncate_limit: 100 +-- noop + +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest4 DEFAULT VALUES" +== 077 +-- truncate_limit: 100 +-- fails because NOT NULL is not dropped +ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL" +== 078 +-- truncate_limit: 100 +INSERT INTO itest4 DEFAULT VALUES +-- +TABLE: name="itest4" schema="" table="itest4" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest4 DEFAULT VALUES" +== 079 +-- truncate_limit: 100 +SELECT * FROM itest4 +-- +TABLE: name="itest4" schema="" table="itest4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest4" +== 080 +-- truncate_limit: 100 +-- check that sequence is removed +SELECT sequence_name FROM itest4_a_seq +-- +TABLE: name="itest4_a_seq" schema="" table="itest4_a_seq" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT sequence_name FROM itest4_a_seq" +== 081 +-- truncate_limit: 100 +-- test views + +CREATE TABLE itest10 (a int generated by default as identity, b text) +-- +TABLE: name="itest10" schema="" table="itest10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest10 (a int GENERATED BY DEFAULT AS IDENTITY, b text)" +== 082 +-- truncate_limit: 100 +CREATE TABLE itest11 (a int generated always as identity, b text) +-- +TABLE: name="itest11" schema="" table="itest11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest11 (a int GENERATED ALWAYS AS IDENTITY, b text)" +== 083 +-- truncate_limit: 100 +CREATE VIEW itestv10 AS SELECT * FROM itest10 +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DDL +TABLE: name="itest10" schema="" table="itest10" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW itestv10 AS SELECT * FROM itest10" +== 084 +-- truncate_limit: 100 +CREATE VIEW itestv11 AS SELECT * FROM itest11 +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DDL +TABLE: name="itest11" schema="" table="itest11" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW itestv11 AS SELECT * FROM itest11" +== 085 +-- truncate_limit: 100 +INSERT INTO itestv10 DEFAULT VALUES +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itestv10 DEFAULT VALUES" +== 086 +-- truncate_limit: 100 +INSERT INTO itestv10 DEFAULT VALUES +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itestv10 DEFAULT VALUES" +== 087 +-- truncate_limit: 100 +INSERT INTO itestv11 DEFAULT VALUES +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itestv11 DEFAULT VALUES" +== 088 +-- truncate_limit: 100 +INSERT INTO itestv11 DEFAULT VALUES +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itestv11 DEFAULT VALUES" +== 089 +-- truncate_limit: 100 +SELECT * FROM itestv10 +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itestv10" +== 090 +-- truncate_limit: 100 +SELECT * FROM itestv11 +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itestv11" +== 091 +-- truncate_limit: 100 +INSERT INTO itestv10 VALUES (10, 'xyz') +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itestv10 VALUES (10, 'xyz')" +== 092 +-- truncate_limit: 100 +INSERT INTO itestv10 OVERRIDING USER VALUE VALUES (11, 'xyz') +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itestv10 OVERRIDING USER VALUE VALUES (11, 'xyz')" +== 093 +-- truncate_limit: 100 +SELECT * FROM itestv10 +-- +TABLE: name="itestv10" schema="" table="itestv10" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itestv10" +== 094 +-- truncate_limit: 100 +INSERT INTO itestv11 VALUES (10, 'xyz') +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itestv11 VALUES (10, 'xyz')" +== 095 +-- truncate_limit: 100 +INSERT INTO itestv11 OVERRIDING SYSTEM VALUE VALUES (11, 'xyz') +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itestv11 OVERRIDING SYSTEM VALUE VALUES (11, 'xyz')" +== 096 +-- truncate_limit: 100 +SELECT * FROM itestv11 +-- +TABLE: name="itestv11" schema="" table="itestv11" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itestv11" +== 097 +-- truncate_limit: 100 +DROP VIEW itestv10, itestv11 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW itestv10, itestv11" +== 098 +-- truncate_limit: 100 +-- ADD COLUMN + +CREATE TABLE itest13 (a int) +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest13 (a int)" +== 099 +-- truncate_limit: 100 +-- add column to empty table +ALTER TABLE itest13 ADD COLUMN b int GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest13 ADD COLUMN b int GENERATED BY DEFAULT AS IDENTITY" +== 100 +-- truncate_limit: 100 +INSERT INTO itest13 VALUES (1), (2), (3) +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest13 VALUES (1), (2), (3)" +== 101 +-- truncate_limit: 100 +-- add column to populated table +ALTER TABLE itest13 ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="itest13" schema="" table="itest13" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest13 ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY" +== 102 +-- truncate_limit: 100 +SELECT * FROM itest13 +-- +TABLE: name="itest13" schema="" table="itest13" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest13" +== 103 +-- truncate_limit: 100 +-- various ALTER COLUMN tests + +-- fail, not allowed for identity columns +ALTER TABLE itest1 ALTER COLUMN a SET DEFAULT 1 +-- +TABLE: name="itest1" schema="" table="itest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest1 ALTER COLUMN a SET DEFAULT 1" +== 104 +-- truncate_limit: 100 +-- fail, not allowed, already has a default +CREATE TABLE itest5 (a serial, b text) +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest5 (a serial, b text)" +== 105 +-- truncate_limit: 100 +ALTER TABLE itest5 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest5" schema="" table="itest5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest5 ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 106 +-- truncate_limit: 100 +ALTER TABLE itest3 ALTER COLUMN a TYPE int +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest3 ALTER COLUMN a TYPE int" +== 107 +-- truncate_limit: 100 +SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regclass +-- +TABLE: name="pg_sequence" schema="" table="pg_sequence" ctx=Select +FILTER: schema="" table="" column="seqrelid" +STMT: SelectStmt +TRUNCATED: "SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regclass" +== 108 +-- truncate_limit: 100 +ALTER TABLE itest3 ALTER COLUMN a TYPE text +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest3 ALTER COLUMN a TYPE text" +== 109 +-- truncate_limit: 100 +-- error + +-- check that unlogged propagates to sequence +CREATE UNLOGGED TABLE itest17 (a int NOT NULL, b text) +-- +TABLE: name="itest17" schema="" table="itest17" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE itest17 (a int NOT NULL, b text)" +== 110 +-- truncate_limit: 100 +ALTER TABLE itest17 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest17" schema="" table="itest17" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest17 ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 111 +-- truncate_limit: 100 +ALTER TABLE itest17 ADD COLUMN c int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest17" schema="" table="itest17" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest17 ADD COLUMN c int GENERATED ALWAYS AS IDENTITY" +== 112 +-- truncate_limit: 100 +CREATE TABLE itest18 (a int NOT NULL, b text) +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest18 (a int NOT NULL, b text)" +== 113 +-- truncate_limit: 100 +ALTER TABLE itest18 SET UNLOGGED, ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest18 SET UNLOGGED, ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 114 +-- truncate_limit: 100 +ALTER TABLE itest18 SET LOGGED +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest18 SET LOGGED" +== 115 +-- truncate_limit: 100 +ALTER TABLE itest18 SET UNLOGGED +-- +TABLE: name="itest18" schema="" table="itest18" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest18 SET UNLOGGED" +== 116 +-- truncate_limit: 100 +-- kinda silly to change property in the same command, but it should work +ALTER TABLE itest3 + ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY, + ALTER COLUMN c SET GENERATED ALWAYS +-- +TABLE: name="itest3" schema="" table="itest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest3 ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY, ALTER c SET GENERATED ALWAYS" +== 117 +-- truncate_limit: 100 +-- ALTER COLUMN ... SET + +CREATE TABLE itest6 (a int GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest6 (a int GENERATED ALWAYS AS IDENTITY, b text)" +== 118 +-- truncate_limit: 100 +INSERT INTO itest6 DEFAULT VALUES +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest6 DEFAULT VALUES" +== 119 +-- truncate_limit: 100 +ALTER TABLE itest6 ALTER COLUMN a SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 100 RESTART +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest6 ALTER a SET GENERATED BY DEFAULT SET INCREMENT 2 SET START 100 RESTART" +== 120 +-- truncate_limit: 100 +INSERT INTO itest6 DEFAULT VALUES +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest6 DEFAULT VALUES" +== 121 +-- truncate_limit: 100 +INSERT INTO itest6 DEFAULT VALUES +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest6 DEFAULT VALUES" +== 122 +-- truncate_limit: 100 +SELECT * FROM itest6 +-- +TABLE: name="itest6" schema="" table="itest6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest6" +== 123 +-- truncate_limit: 100 +SELECT table_name, column_name, is_identity, identity_generation FROM information_schema.columns WHERE table_name = 'itest6' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name = 'itest6' ORDER BY 1, 2" +== 124 +-- truncate_limit: 100 +ALTER TABLE itest6 ALTER COLUMN b SET INCREMENT BY 2 +-- +TABLE: name="itest6" schema="" table="itest6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest6 ALTER b SET INCREMENT 2" +== 125 +-- truncate_limit: 100 +-- fail, not identity + + +-- prohibited direct modification of sequence + +ALTER SEQUENCE itest6_a_seq OWNED BY NONE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE itest6_a_seq OWNED BY \"none\"" +== 126 +-- truncate_limit: 100 +-- inheritance + +CREATE TABLE itest7 (a int GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest7 (a int GENERATED ALWAYS AS IDENTITY)" +== 127 +-- truncate_limit: 100 +INSERT INTO itest7 DEFAULT VALUES +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest7 DEFAULT VALUES" +== 128 +-- truncate_limit: 100 +SELECT * FROM itest7 +-- +TABLE: name="itest7" schema="" table="itest7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest7" +== 129 +-- truncate_limit: 100 +-- identity property is not inherited +CREATE TABLE itest7a (b text) INHERITS (itest7) +-- +TABLE: name="itest7a" schema="" table="itest7a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest7a (b text) INHERITS (itest7)" +== 130 +-- truncate_limit: 100 +-- make column identity in child table +CREATE TABLE itest7b (a int) +-- +TABLE: name="itest7b" schema="" table="itest7b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest7b (a int)" +== 131 +-- truncate_limit: 100 +CREATE TABLE itest7c (a int GENERATED ALWAYS AS IDENTITY) INHERITS (itest7b) +-- +TABLE: name="itest7c" schema="" table="itest7c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest7c (a int GENERATED ALWAYS AS IDENTITY) INHERITS (itest7b)" +== 132 +-- truncate_limit: 100 +INSERT INTO itest7c DEFAULT VALUES +-- +TABLE: name="itest7c" schema="" table="itest7c" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest7c DEFAULT VALUES" +== 133 +-- truncate_limit: 100 +SELECT * FROM itest7c +-- +TABLE: name="itest7c" schema="" table="itest7c" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest7c" +== 134 +-- truncate_limit: 100 +CREATE TABLE itest7d (a int not null) +-- +TABLE: name="itest7d" schema="" table="itest7d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest7d (a int NOT NULL)" +== 135 +-- truncate_limit: 100 +CREATE TABLE itest7e () INHERITS (itest7d) +-- +TABLE: name="itest7e" schema="" table="itest7e" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest7e () INHERITS (itest7d)" +== 136 +-- truncate_limit: 100 +ALTER TABLE itest7d ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest7d" schema="" table="itest7d" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest7d ALTER a ADD GENERATED ALWAYS AS IDENTITY" +== 137 +-- truncate_limit: 100 +ALTER TABLE itest7d ADD COLUMN b int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest7d" schema="" table="itest7d" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest7d ADD COLUMN b int GENERATED ALWAYS AS IDENTITY" +== 138 +-- truncate_limit: 100 +-- error + +SELECT table_name, column_name, is_nullable, is_identity, identity_generation FROM information_schema.columns WHERE table_name LIKE 'itest7%' ORDER BY 1, 2 +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name LIKE 'itest7%' ORDER BY 1, 2" +== 139 +-- truncate_limit: 100 +-- These ALTER TABLE variants will not recurse. +ALTER TABLE itest7 ALTER COLUMN a SET GENERATED BY DEFAULT +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest7 ALTER a SET GENERATED BY DEFAULT" +== 140 +-- truncate_limit: 100 +ALTER TABLE itest7 ALTER COLUMN a RESTART +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest7 ALTER a RESTART" +== 141 +-- truncate_limit: 100 +ALTER TABLE itest7 ALTER COLUMN a DROP IDENTITY +-- +TABLE: name="itest7" schema="" table="itest7" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest7 ALTER COLUMN a DROP IDENTITY" +== 142 +-- truncate_limit: 100 +-- privileges +CREATE USER regress_identity_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_identity_user1" +== 143 +-- truncate_limit: 100 +CREATE TABLE itest8 (a int GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest8 (a int GENERATED ALWAYS AS IDENTITY, b text)" +== 144 +-- truncate_limit: 100 +GRANT SELECT, INSERT ON itest8 TO regress_identity_user1 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select, insert ON itest8 TO regress_identity_user1" +== 145 +-- truncate_limit: 100 +SET ROLE regress_identity_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_identity_user1" +== 146 +-- truncate_limit: 100 +INSERT INTO itest8 DEFAULT VALUES +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO itest8 DEFAULT VALUES" +== 147 +-- truncate_limit: 100 +SELECT * FROM itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest8" +== 148 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 149 +-- truncate_limit: 100 +DROP TABLE itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE itest8" +== 150 +-- truncate_limit: 100 +DROP USER regress_identity_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_identity_user1" +== 151 +-- truncate_limit: 100 +-- multiple steps in ALTER TABLE +CREATE TABLE itest8 (f1 int) +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest8 (f1 int)" +== 152 +-- truncate_limit: 100 +ALTER TABLE itest8 + ADD COLUMN f2 int NOT NULL, + ALTER COLUMN f2 ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest8 ADD COLUMN f2 int NOT NULL, ALTER f2 ADD GENERATED ALWAYS AS IDENTITY" +== 153 +-- truncate_limit: 100 +ALTER TABLE itest8 + ADD COLUMN f3 int NOT NULL, + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY, + ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT 10 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest8 ADD COLUMN f3 int NOT NULL, ALTER f3 ADD GENERATED ALWAYS AS IDENTITY, ALTER f..." +== 154 +-- truncate_limit: 100 +ALTER TABLE itest8 + ADD COLUMN f4 int +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest8 ADD COLUMN f4 int" +== 155 +-- truncate_limit: 100 +ALTER TABLE itest8 + ALTER COLUMN f4 SET NOT NULL, + ALTER COLUMN f4 ADD GENERATED ALWAYS AS IDENTITY, + ALTER COLUMN f4 SET DATA TYPE bigint +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest8 ALTER COLUMN f4 SET NOT NULL, ALTER f4 ADD GENERATED ALWAYS AS IDENTITY, ALTER..." +== 156 +-- truncate_limit: 100 +ALTER TABLE itest8 + ADD COLUMN f5 int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest8 ADD COLUMN f5 int GENERATED ALWAYS AS IDENTITY" +== 157 +-- truncate_limit: 100 +ALTER TABLE itest8 + ALTER COLUMN f5 DROP IDENTITY, + ALTER COLUMN f5 DROP NOT NULL, + ALTER COLUMN f5 SET DATA TYPE bigint +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest8 ALTER COLUMN f5 DROP IDENTITY, ALTER COLUMN f5 DROP NOT NULL, ALTER COLUMN f5 ..." +== 158 +-- truncate_limit: 100 +INSERT INTO itest8 VALUES(0), (1) +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest8 VALUES (0), (1)" +== 159 +-- truncate_limit: 100 +-- This does not work when the table isn't empty. That's intentional, +-- since ADD GENERATED should only affect later insertions: +ALTER TABLE itest8 + ADD COLUMN f22 int NOT NULL, + ALTER COLUMN f22 ADD GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest8 ADD COLUMN f22 int NOT NULL, ALTER f22 ADD GENERATED ALWAYS AS IDENTITY" +== 160 +-- truncate_limit: 100 +TABLE itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest8" +== 161 +-- truncate_limit: 100 +DROP TABLE itest8 +-- +TABLE: name="itest8" schema="" table="itest8" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE itest8" +== 162 +-- truncate_limit: 100 +-- typed tables (currently not supported) + +CREATE TYPE itest_type AS (f1 integer, f2 text, f3 bigint) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE itest_type AS (f1 int, f2 text, f3 bigint)" +== 163 +-- truncate_limit: 100 +CREATE TABLE itest12 OF itest_type (f1 WITH OPTIONS GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest12" schema="" table="itest12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest12 OF itest_type (f1 GENERATED ALWAYS AS IDENTITY)" +== 164 +-- truncate_limit: 100 +-- error +DROP TYPE itest_type CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE itest_type CASCADE" +== 165 +-- truncate_limit: 100 +-- table partitions + +-- partitions inherit identity column and share sequence +CREATE TABLE pitest1 (f1 date NOT NULL, f2 text, f3 bigint generated always as identity) PARTITION BY RANGE (f1) +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest1 (f1 date NOT NULL, f2 text, f3 bigint GENERATED ALWAYS AS IDENTITY) PARTITIO..." +== 166 +-- truncate_limit: 100 +-- new partition +CREATE TABLE pitest1_p1 PARTITION OF pitest1 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest1_p1" schema="" table="pitest1_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest1_p1 PARTITION OF pitest1 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01')" +== 167 +-- truncate_limit: 100 +INSERT into pitest1(f1, f2) VALUES ('2016-07-2', 'from pitest1') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest1 (f1, f2) VALUES ('2016-07-2', 'from pitest1')" +== 168 +-- truncate_limit: 100 +INSERT into pitest1_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest1_p1') +-- +TABLE: name="pitest1_p1" schema="" table="pitest1_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest1_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest1_p1')" +== 169 +-- truncate_limit: 100 +-- attached partition +CREATE TABLE pitest1_p2 (f3 bigint, f2 text, f1 date NOT NULL) +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest1_p2 (f3 bigint, f2 text, f1 date NOT NULL)" +== 170 +-- truncate_limit: 100 +INSERT INTO pitest1_p2 (f1, f2, f3) VALUES ('2016-08-2', 'before attaching', 100) +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest1_p2 (f1, f2, f3) VALUES ('2016-08-2', 'before attaching', 100)" +== 171 +-- truncate_limit: 100 +ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01')" +== 172 +-- truncate_limit: 100 +-- requires NOT NULL constraint +ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET NOT NULL +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET NOT NULL" +== 173 +-- truncate_limit: 100 +ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01')" +== 174 +-- truncate_limit: 100 +INSERT INTO pitest1_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest1_p2') +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest1_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest1_p2')" +== 175 +-- truncate_limit: 100 +INSERT INTO pitest1 (f1, f2) VALUES ('2016-08-4', 'from pitest1') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest1 (f1, f2) VALUES ('2016-08-4', 'from pitest1')" +== 176 +-- truncate_limit: 100 +-- LIKE INCLUDING on partition +CREATE TABLE pitest1_p1_like (LIKE pitest1_p1 INCLUDING IDENTITY) +-- +TABLE: name="pitest1_p1_like" schema="" table="pitest1_p1_like" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest1_p1_like (LIKE pitest1_p1 INCLUDING IDENTITY)" +== 177 +-- truncate_limit: 100 +INSERT into pitest1_p1_like(f1, f2) VALUES ('2016-07-2', 'from pitest1_p1_like') +-- +TABLE: name="pitest1_p1_like" schema="" table="pitest1_p1_like" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest1_p1_like (f1, f2) VALUES ('2016-07-2', 'from pitest1_p1_like')" +== 178 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest1 +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest1" +== 179 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest1_p1_like +-- +TABLE: name="pitest1_p1_like" schema="" table="pitest1_p1_like" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest1_p1_like" +== 180 +-- truncate_limit: 100 +ALTER TABLE pitest1 ALTER COLUMN f3 SET DATA TYPE bigint +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1 ALTER COLUMN f3 TYPE bigint" +== 181 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1 +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=Select +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1" +== 182 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1_p2 +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=Select +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1_p2" +== 183 +-- truncate_limit: 100 +-- add identity column +CREATE TABLE pitest2 (f1 date NOT NULL, f2 text) PARTITION BY RANGE (f1) +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest2 (f1 date NOT NULL, f2 text) PARTITION BY RANGE (f1)" +== 184 +-- truncate_limit: 100 +CREATE TABLE pitest2_p1 PARTITION OF pitest2 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest2_p1 PARTITION OF pitest2 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01')" +== 185 +-- truncate_limit: 100 +CREATE TABLE pitest2_p2 PARTITION OF pitest2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01') +-- +TABLE: name="pitest2_p2" schema="" table="pitest2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest2_p2 PARTITION OF pitest2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01')" +== 186 +-- truncate_limit: 100 +INSERT into pitest2(f1, f2) VALUES ('2016-07-2', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2 (f1, f2) VALUES ('2016-07-2', 'from pitest2')" +== 187 +-- truncate_limit: 100 +INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-2', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-2', 'from pitest2')" +== 188 +-- truncate_limit: 100 +ALTER TABLE pitest2 ADD COLUMN f3 int GENERATED ALWAYS AS IDENTITY +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest2 ADD COLUMN f3 int GENERATED ALWAYS AS IDENTITY" +== 189 +-- truncate_limit: 100 +INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest2_p1') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest2_p1')" +== 190 +-- truncate_limit: 100 +INSERT INTO pitest2_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest2_p2') +-- +TABLE: name="pitest2_p2" schema="" table="pitest2_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest2_p2')" +== 191 +-- truncate_limit: 100 +INSERT into pitest2(f1, f2) VALUES ('2016-07-4', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2 (f1, f2) VALUES ('2016-07-4', 'from pitest2')" +== 192 +-- truncate_limit: 100 +INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-4', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-4', 'from pitest2')" +== 193 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest2" +== 194 +-- truncate_limit: 100 +-- SET identity column +ALTER TABLE pitest2_p1 ALTER COLUMN f3 SET GENERATED BY DEFAULT +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest2_p1 ALTER f3 SET GENERATED BY DEFAULT" +== 195 +-- truncate_limit: 100 +-- fails +ALTER TABLE pitest2_p1 ALTER COLUMN f3 SET INCREMENT BY 2 +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest2_p1 ALTER f3 SET INCREMENT 2" +== 196 +-- truncate_limit: 100 +-- fails +ALTER TABLE ONLY pitest2 ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 1000 RESTART +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY pitest2 ALTER f3 SET GENERATED BY DEFAULT SET INCREMENT 2 SET START 1000 RESTART" +== 197 +-- truncate_limit: 100 +-- fails +ALTER TABLE pitest2 ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 1000 RESTART +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest2 ALTER f3 SET GENERATED BY DEFAULT SET INCREMENT 2 SET START 1000 RESTART" +== 198 +-- truncate_limit: 100 +INSERT into pitest2(f1, f2, f3) VALUES ('2016-07-5', 'from pitest2', 200) +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2 (f1, f2, f3) VALUES ('2016-07-5', 'from pitest2', 200)" +== 199 +-- truncate_limit: 100 +INSERT INTO pitest2(f1, f2) VALUES ('2016-08-5', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-5', 'from pitest2')" +== 200 +-- truncate_limit: 100 +INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-6', 'from pitest2_p1') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2_p1 (f1, f2) VALUES ('2016-07-6', 'from pitest2_p1')" +== 201 +-- truncate_limit: 100 +INSERT INTO pitest2_p2 (f1, f2, f3) VALUES ('2016-08-6', 'from pitest2_p2', 300) +-- +TABLE: name="pitest2_p2" schema="" table="pitest2_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2_p2 (f1, f2, f3) VALUES ('2016-08-6', 'from pitest2_p2', 300)" +== 202 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest2" +== 203 +-- truncate_limit: 100 +-- detaching a partition removes identity property +ALTER TABLE pitest2 DETACH PARTITION pitest2_p1 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest2 DETACH PARTITION pitest2_p1" +== 204 +-- truncate_limit: 100 +INSERT into pitest2(f1, f2) VALUES ('2016-08-7', 'from pitest2') +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-7', 'from pitest2')" +== 205 +-- truncate_limit: 100 +INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-7', 'from pitest2_p1') +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2_p1 (f1, f2) VALUES ('2016-07-7', 'from pitest2_p1')" +== 206 +-- truncate_limit: 100 +-- error +INSERT into pitest2_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest2_p1', 2000) +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest2_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest2_p1', 2000)" +== 207 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2 +-- +TABLE: name="pitest2" schema="" table="pitest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest2" +== 208 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest2_p1 +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest2_p1" +== 209 +-- truncate_limit: 100 +DROP TABLE pitest2_p1 +-- +TABLE: name="pitest2_p1" schema="" table="pitest2_p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pitest2_p1" +== 210 +-- truncate_limit: 100 +-- changing a regular column to identity column in a partitioned table +CREATE TABLE pitest3 (f1 date NOT NULL, f2 text, f3 int) PARTITION BY RANGE (f1) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest3 (f1 date NOT NULL, f2 text, f3 int) PARTITION BY RANGE (f1)" +== 211 +-- truncate_limit: 100 +CREATE TABLE pitest3_p1 PARTITION OF pitest3 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest3_p1 PARTITION OF pitest3 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01')" +== 212 +-- truncate_limit: 100 +INSERT into pitest3 VALUES ('2016-07-2', 'from pitest3', 1) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3 VALUES ('2016-07-2', 'from pitest3', 1)" +== 213 +-- truncate_limit: 100 +INSERT into pitest3_p1 VALUES ('2016-07-3', 'from pitest3_p1', 2) +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3_p1 VALUES ('2016-07-3', 'from pitest3_p1', 2)" +== 214 +-- truncate_limit: 100 +-- fails, changing only a partition not allowed +ALTER TABLE pitest3_p1 + ALTER COLUMN f3 SET NOT NULL, + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3) +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest3_p1 ALTER COLUMN f3 SET NOT NULL, ALTER f3 ADD GENERATED ALWAYS AS IDENTITY (S..." +== 215 +-- truncate_limit: 100 +-- fails, changing only the partitioned table not allowed +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 216 +-- truncate_limit: 100 +ALTER TABLE pitest3_p1 ALTER COLUMN f3 SET NOT NULL +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest3_p1 ALTER COLUMN f3 SET NOT NULL" +== 217 +-- truncate_limit: 100 +ALTER TABLE ONLY pitest3 + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY pitest3 ALTER f3 ADD GENERATED ALWAYS AS IDENTITY (START 3 )" +== 218 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 219 +-- truncate_limit: 100 +ALTER TABLE pitest3 + ALTER COLUMN f3 SET NOT NULL, + ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest3 ALTER COLUMN f3 SET NOT NULL, ALTER f3 ADD GENERATED ALWAYS AS IDENTITY (STAR..." +== 220 +-- truncate_limit: 100 +INSERT into pitest3(f1, f2) VALUES ('2016-07-4', 'from pitest3') +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3 (f1, f2) VALUES ('2016-07-4', 'from pitest3')" +== 221 +-- truncate_limit: 100 +INSERT into pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1') +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1')" +== 222 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest3 +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest3" +== 223 +-- truncate_limit: 100 +-- changing an identity column to a non-identity column in a partitioned table +ALTER TABLE pitest3_p1 ALTER COLUMN f3 DROP IDENTITY +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest3_p1 ALTER COLUMN f3 DROP IDENTITY" +== 224 +-- truncate_limit: 100 +-- fails +ALTER TABLE ONLY pitest3 ALTER COLUMN f3 DROP IDENTITY +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY pitest3 ALTER COLUMN f3 DROP IDENTITY" +== 225 +-- truncate_limit: 100 +-- fails +ALTER TABLE pitest3 ALTER COLUMN f3 DROP IDENTITY +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest3 ALTER COLUMN f3 DROP IDENTITY" +== 226 +-- truncate_limit: 100 +INSERT into pitest3(f1, f2) VALUES ('2016-07-4', 'from pitest3') +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3 (f1, f2) VALUES ('2016-07-4', 'from pitest3')" +== 227 +-- truncate_limit: 100 +-- fails +INSERT into pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1') +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1')" +== 228 +-- truncate_limit: 100 +-- fails +INSERT into pitest3(f1, f2, f3) VALUES ('2016-07-6', 'from pitest3', 5) +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3 (f1, f2, f3) VALUES ('2016-07-6', 'from pitest3', 5)" +== 229 +-- truncate_limit: 100 +INSERT into pitest3_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest3_p1', 6) +-- +TABLE: name="pitest3_p1" schema="" table="pitest3_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pitest3_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest3_p1', 6)" +== 230 +-- truncate_limit: 100 +SELECT tableoid::regclass, f1, f2, f3 FROM pitest3 +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, f1, f2, f3 FROM pitest3" +== 231 +-- truncate_limit: 100 +-- Changing NOT NULL constraint of identity columns is not allowed +ALTER TABLE pitest1_p1 ALTER COLUMN f3 DROP NOT NULL +-- +TABLE: name="pitest1_p1" schema="" table="pitest1_p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1_p1 ALTER COLUMN f3 DROP NOT NULL" +== 232 +-- truncate_limit: 100 +ALTER TABLE pitest1 ALTER COLUMN f3 DROP NOT NULL +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1 ALTER COLUMN f3 DROP NOT NULL" +== 233 +-- truncate_limit: 100 +-- Identity columns have their own default +ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET DEFAULT 10000 +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET DEFAULT 10000" +== 234 +-- truncate_limit: 100 +ALTER TABLE pitest1 ALTER COLUMN f3 SET DEFAULT 10000 +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1 ALTER COLUMN f3 SET DEFAULT 10000" +== 235 +-- truncate_limit: 100 +-- Adding identity to an identity column is not allowed +ALTER TABLE pitest1_p2 ALTER COLUMN f3 ADD GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="pitest1_p2" schema="" table="pitest1_p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1_p2 ALTER f3 ADD GENERATED BY DEFAULT AS IDENTITY" +== 236 +-- truncate_limit: 100 +ALTER TABLE pitest1 ALTER COLUMN f3 ADD GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1 ALTER f3 ADD GENERATED BY DEFAULT AS IDENTITY" +== 237 +-- truncate_limit: 100 +-- partitions with their own identity columns are not allowed, even if the +-- partitioned table does not have an identity column. +CREATE TABLE pitest1_pfail PARTITION OF pitest1 ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY +) FOR VALUES FROM ('2016-11-01') TO ('2016-12-01') +-- +TABLE: name="pitest1_pfail" schema="" table="pitest1_pfail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest1_pfail PARTITION OF pitest1 (f3 GENERATED ALWAYS AS IDENTITY) FOR VALUES FROM..." +== 238 +-- truncate_limit: 100 +CREATE TABLE pitest_pfail PARTITION OF pitest3 ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY +) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01') +-- +TABLE: name="pitest_pfail" schema="" table="pitest_pfail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest_pfail PARTITION OF pitest3 (f3 GENERATED ALWAYS AS IDENTITY) FOR VALUES FROM ..." +== 239 +-- truncate_limit: 100 +CREATE TABLE pitest1_pfail (f1 date NOT NULL, f2 text, f3 bigint GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="pitest1_pfail" schema="" table="pitest1_pfail" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pitest1_pfail (f1 date NOT NULL, f2 text, f3 bigint GENERATED ALWAYS AS IDENTITY)" +== 240 +-- truncate_limit: 100 +ALTER TABLE pitest1 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01') +-- +TABLE: name="pitest1" schema="" table="pitest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest1 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01')" +== 241 +-- truncate_limit: 100 +ALTER TABLE pitest3 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01') +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pitest3 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01')" +== 242 +-- truncate_limit: 100 +DROP TABLE pitest1_pfail +-- +TABLE: name="pitest1_pfail" schema="" table="pitest1_pfail" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pitest1_pfail" +== 243 +-- truncate_limit: 100 +DROP TABLE pitest3 +-- +TABLE: name="pitest3" schema="" table="pitest3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pitest3" +== 244 +-- truncate_limit: 100 +-- test that sequence of half-dropped serial column is properly ignored + +CREATE TABLE itest14 (id serial) +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest14 (id serial)" +== 245 +-- truncate_limit: 100 +ALTER TABLE itest14 ALTER id DROP DEFAULT +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest14 ALTER COLUMN id DROP DEFAULT" +== 246 +-- truncate_limit: 100 +ALTER TABLE itest14 ALTER id ADD GENERATED BY DEFAULT AS IDENTITY +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE itest14 ALTER id ADD GENERATED BY DEFAULT AS IDENTITY" +== 247 +-- truncate_limit: 100 +INSERT INTO itest14 (id) VALUES (DEFAULT) +-- +TABLE: name="itest14" schema="" table="itest14" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO itest14 (id) VALUES (DEFAULT)" +== 248 +-- truncate_limit: 100 +-- Identity columns must be NOT NULL (cf bug #16913) + +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NULL) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest15 (id int GENERATED ALWAYS AS IDENTITY NULL)" +== 249 +-- truncate_limit: 100 +-- fail +CREATE TABLE itest15 (id integer NULL GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest15 (id int NULL GENERATED ALWAYS AS IDENTITY)" +== 250 +-- truncate_limit: 100 +-- fail +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NOT NULL) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest15 (id int GENERATED ALWAYS AS IDENTITY NOT NULL)" +== 251 +-- truncate_limit: 100 +DROP TABLE itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE itest15" +== 252 +-- truncate_limit: 100 +CREATE TABLE itest15 (id integer NOT NULL GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest15 (id int NOT NULL GENERATED ALWAYS AS IDENTITY)" +== 253 +-- truncate_limit: 100 +DROP TABLE itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE itest15" +== 254 +-- truncate_limit: 100 +-- MERGE tests +CREATE TABLE itest15 (a int GENERATED ALWAYS AS IDENTITY, b text) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest15 (a int GENERATED ALWAYS AS IDENTITY, b text)" +== 255 +-- truncate_limit: 100 +CREATE TABLE itest16 (a int GENERATED BY DEFAULT AS IDENTITY, b text) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE itest16 (a int GENERATED BY DEFAULT AS IDENTITY, b text)" +== 256 +-- truncate_limit: 100 +MERGE INTO itest15 t +USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DML +ALIAS: "t"="itest15" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO itest15 t USING (SELECT ...) s ON t.a = s.s_a WHEN NOT MATCHED THEN INSERT (a, b) VALU..." +== 257 +-- truncate_limit: 100 +-- Used to fail, but now it works and ignores the user supplied value +MERGE INTO itest15 t +USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DML +ALIAS: "t"="itest15" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO itest15 t USING (SELECT ...) s ON t.a = s.s_a WHEN NOT MATCHED THEN INSERT (a, b) OVER..." +== 258 +-- truncate_limit: 100 +MERGE INTO itest15 t +USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DML +ALIAS: "t"="itest15" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO itest15 t USING (SELECT ...) s ON t.a = s.s_a WHEN NOT MATCHED THEN INSERT (a, b) OVER..." +== 259 +-- truncate_limit: 100 +MERGE INTO itest16 t +USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DML +ALIAS: "t"="itest16" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO itest16 t USING (SELECT ...) s ON t.a = s.s_a WHEN NOT MATCHED THEN INSERT (a, b) VALU..." +== 260 +-- truncate_limit: 100 +MERGE INTO itest16 t +USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DML +ALIAS: "t"="itest16" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO itest16 t USING (SELECT ...) s ON t.a = s.s_a WHEN NOT MATCHED THEN INSERT (a, b) OVER..." +== 261 +-- truncate_limit: 100 +MERGE INTO itest16 t +USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s +ON t.a = s.s_a +WHEN NOT MATCHED THEN + INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b) +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DML +ALIAS: "t"="itest16" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO itest16 t USING (SELECT ...) s ON t.a = s.s_a WHEN NOT MATCHED THEN INSERT (a, b) OVER..." +== 262 +-- truncate_limit: 100 +SELECT * FROM itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest15" +== 263 +-- truncate_limit: 100 +SELECT * FROM itest16 +-- +TABLE: name="itest16" schema="" table="itest16" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM itest16" +== 264 +-- truncate_limit: 100 +DROP TABLE itest15 +-- +TABLE: name="itest15" schema="" table="itest15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE itest15" +== 265 +-- truncate_limit: 100 +DROP TABLE itest16 +-- +TABLE: name="itest16" schema="" table="itest16" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE itest16" +== 266 +-- truncate_limit: 100 +-- For testing of pg_dump and pg_upgrade, leave behind some identity +-- sequences whose logged-ness doesn't match their owning table's. +CREATE TABLE identity_dump_logged (a INT GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="identity_dump_logged" schema="" table="identity_dump_logged" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE identity_dump_logged (a int GENERATED ALWAYS AS IDENTITY)" +== 267 +-- truncate_limit: 100 +ALTER SEQUENCE identity_dump_logged_a_seq SET UNLOGGED +-- +TABLE: name="identity_dump_logged_a_seq" schema="" table="identity_dump_logged_a_seq" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER SEQUENCE identity_dump_logged_a_seq SET UNLOGGED" +== 268 +-- truncate_limit: 100 +CREATE UNLOGGED TABLE identity_dump_unlogged (a INT GENERATED ALWAYS AS IDENTITY) +-- +TABLE: name="identity_dump_unlogged" schema="" table="identity_dump_unlogged" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE identity_dump_unlogged (a int GENERATED ALWAYS AS IDENTITY)" +== 269 +-- truncate_limit: 100 +ALTER SEQUENCE identity_dump_unlogged_a_seq SET LOGGED +-- +TABLE: name="identity_dump_unlogged_a_seq" schema="" table="identity_dump_unlogged_a_seq" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER SEQUENCE identity_dump_unlogged_a_seq SET LOGGED" +== 270 +-- truncate_limit: 100 +SELECT relname, relpersistence FROM pg_class + WHERE relname ~ '^identity_dump_' ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relpersistence FROM pg_class WHERE relname ~ '^identity_dump_' ORDER BY 1" diff --git a/parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json b/parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json new file mode 100644 index 0000000..b6ecb7b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json @@ -0,0 +1,123 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/incremental_sort.test b/parser/testdata/summary_truncate/postgres_regress/incremental_sort.test new file mode 100644 index 0000000..f3c6456 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/incremental_sort.test @@ -0,0 +1,1041 @@ +== 001 +-- truncate_limit: 100 +-- When there is a LIMIT clause, incremental sort is beneficial because +-- it only has to sort some of the groups, and not the entire table. +explain (costs off) +select * from (select * from tenk1 order by four) t order by four, ten +limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM tenk1 ORDER BY four) t ORDER BY four, ten LIMIT 1" +== 002 +-- truncate_limit: 100 +-- When work_mem is not enough to sort the entire table, incremental sort +-- may be faster if individual groups still fit into work_mem. +set work_mem to '2MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"2MB\"" +== 003 +-- truncate_limit: 100 +explain (costs off) +select * from (select * from tenk1 order by four) t order by four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM tenk1 ORDER BY four) t ORDER BY four, ten" +== 004 +-- truncate_limit: 100 +reset work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET work_mem" +== 005 +-- truncate_limit: 100 +create table t(a integer, b integer) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (a int, b int)" +== 006 +-- truncate_limit: 100 +create or replace function explain_analyze_without_memory(query text) +returns table (out_line text) language plpgsql +as +$$ +declare + line text; +begin + for line in + execute 'explain (analyze, costs off, summary off, timing off) ' || query + loop + out_line := regexp_replace(line, '\d+kB', 'NNkB', 'g'); + return next; + end loop; +end; +$$ +-- +FUNCTION: name="explain_analyze_without_memory" function="explain_analyze_without_memory" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION explain_analyze_without_memory(query text) RETURNS TABLE (out_line tex..." +== 007 +-- truncate_limit: 100 +create or replace function explain_analyze_inc_sort_nodes(query text) +returns jsonb language plpgsql +as +$$ +declare + elements jsonb; + element jsonb; + matching_nodes jsonb := '[]'::jsonb; +begin + execute 'explain (analyze, costs off, summary off, timing off, format ''json'') ' || query into strict elements; + while jsonb_array_length(elements) > 0 loop + element := elements->0; + elements := elements - 0; + case jsonb_typeof(element) + when 'array' then + if jsonb_array_length(element) > 0 then + elements := elements || element; + end if; + when 'object' then + if element ? 'Plan' then + elements := elements || jsonb_build_array(element->'Plan'); + element := element - 'Plan'; + else + if element ? 'Plans' then + elements := elements || jsonb_build_array(element->'Plans'); + element := element - 'Plans'; + end if; + if (element->>'Node Type')::text = 'Incremental Sort' then + matching_nodes := matching_nodes || element; + end if; + end if; + end case; + end loop; + return matching_nodes; +end; +$$ +-- +FUNCTION: name="explain_analyze_inc_sort_nodes" function="explain_analyze_inc_sort_nodes" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION explain_analyze_inc_sort_nodes(query text) RETURNS jsonb LANGUAGE plpg..." +== 008 +-- truncate_limit: 100 +create or replace function explain_analyze_inc_sort_nodes_without_memory(query text) +returns jsonb language plpgsql +as +$$ +declare + nodes jsonb := '[]'::jsonb; + node jsonb; + group_key text; + space_key text; +begin + for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop + for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop + for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop + node := jsonb_set(node, array[group_key, space_key, 'Average Sort Space Used'], '"NN"', false); + node := jsonb_set(node, array[group_key, space_key, 'Peak Sort Space Used'], '"NN"', false); + end loop; + end loop; + nodes := nodes || node; + end loop; + return nodes; +end; +$$ +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_without_memory" function="explain_analyze_inc_sort_nodes_without_memory" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION explain_analyze_inc_sort_nodes_without_memory(query text) RETURNS json..." +== 009 +-- truncate_limit: 100 +create or replace function explain_analyze_inc_sort_nodes_verify_invariants(query text) +returns bool language plpgsql +as +$$ +declare + node jsonb; + group_stats jsonb; + group_key text; + space_key text; +begin + for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop + for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop + group_stats := node->group_key; + for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop + if (group_stats->space_key->'Peak Sort Space Used')::bigint < (group_stats->space_key->'Peak Sort Space Used')::bigint then + raise exception '% has invalid max space < average space', group_key; + end if; + end loop; + end loop; + end loop; + return true; +end; +$$ +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_verify_invariants" function="explain_analyze_inc_sort_nodes_verify_invariants" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION explain_analyze_inc_sort_nodes_verify_invariants(query text) RETURNS b..." +== 010 +-- truncate_limit: 100 +-- A single large group tested around each mode transition point. +insert into t(a, b) select i/100 + 1, i + 1 from generate_series(0, 999) n(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b) SELECT (i / 100) + 1, i + 1 FROM generate_series(0, 999) n(i)" +== 011 +-- truncate_limit: 100 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t" +== 012 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 31" +== 013 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 31" +== 014 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 32" +== 015 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 32" +== 016 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 33" +== 017 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 33" +== 018 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 65" +== 019 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 65" +== 020 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 66" +== 021 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 66" +== 022 +-- truncate_limit: 100 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t" +== 023 +-- truncate_limit: 100 +-- An initial large group followed by a small group. +insert into t(a, b) select i/50 + 1, i + 1 from generate_series(0, 999) n(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b) SELECT (i / 50) + 1, i + 1 FROM generate_series(0, 999) n(i)" +== 024 +-- truncate_limit: 100 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t" +== 025 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 55 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 55" +== 026 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 55 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 55" +== 027 +-- truncate_limit: 100 +-- Test EXPLAIN ANALYZE with only a fullsort group. +select explain_analyze_without_memory('select * from (select * from t order by a) s order by a, b limit 55') +-- +FUNCTION: name="explain_analyze_without_memory" function="explain_analyze_without_memory" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 028 +-- truncate_limit: 100 +select jsonb_pretty(explain_analyze_inc_sort_nodes_without_memory('select * from (select * from t order by a) s order by a, b limit 55')) +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +FUNCTION: name="explain_analyze_inc_sort_nodes_without_memory" function="explain_analyze_inc_sort_nodes_without_memory" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 029 +-- truncate_limit: 100 +select explain_analyze_inc_sort_nodes_verify_invariants('select * from (select * from t order by a) s order by a, b limit 55') +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_verify_invariants" function="explain_analyze_inc_sort_nodes_verify_invariants" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 030 +-- truncate_limit: 100 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t" +== 031 +-- truncate_limit: 100 +-- An initial small group followed by a large group. +insert into t(a, b) select (case when i < 5 then i else 9 end), i from generate_series(1, 1000) n(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b) SELECT CASE WHEN i < 5 THEN i ELSE 9 END, i FROM generate_series(1, 1000) n(i)" +== 032 +-- truncate_limit: 100 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t" +== 033 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 70 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 70" +== 034 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 70 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 70" +== 035 +-- truncate_limit: 100 +-- Checks case where we hit a group boundary at the last tuple of a batch. +-- Because the full sort state is bounded, we scan 64 tuples (the mode +-- transition point) but only retain 5. Thus when we transition modes, all +-- tuples in the full sort state have different prefix keys. +explain (costs off) select * from (select * from t order by a) s order by a, b limit 5 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 5" +== 036 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 5 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 5" +== 037 +-- truncate_limit: 100 +-- Test rescan. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 038 +-- truncate_limit: 100 +-- We force the planner to choose a plan with incremental sort on the right side +-- of a nested loop join node. That way we trigger the rescan code path. +set local enable_hashjoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_hashjoin TO OFF" +== 039 +-- truncate_limit: 100 +set local enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_mergejoin TO OFF" +== 040 +-- truncate_limit: 100 +set local enable_material = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_material TO OFF" +== 041 +-- truncate_limit: 100 +set local enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_sort TO OFF" +== 042 +-- truncate_limit: 100 +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) +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="t" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t LEFT JOIN (SELECT * FROM (SELECT * FROM t ORDER BY a) v ORDER..." +== 043 +-- truncate_limit: 100 +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) +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +FILTER: schema="" table="t" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t LEFT JOIN (SELECT * FROM (SELECT * FROM t ORDER BY a) v ORDER BY a, b) s ON s.a =..." +== 044 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 045 +-- truncate_limit: 100 +-- 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') +-- +FUNCTION: name="explain_analyze_without_memory" function="explain_analyze_without_memory" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 046 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +FUNCTION: name="explain_analyze_inc_sort_nodes_without_memory" function="explain_analyze_inc_sort_nodes_without_memory" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 047 +-- truncate_limit: 100 +select explain_analyze_inc_sort_nodes_verify_invariants('select * from (select * from t order by a) s order by a, b limit 70') +-- +FUNCTION: name="explain_analyze_inc_sort_nodes_verify_invariants" function="explain_analyze_inc_sort_nodes_verify_invariants" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 048 +-- truncate_limit: 100 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t" +== 049 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b) SELECT i / 10, i FROM generate_series(1, 1000) n(i)" +== 050 +-- truncate_limit: 100 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t" +== 051 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 31" +== 052 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 31" +== 053 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 32" +== 054 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 32" +== 055 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 33" +== 056 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 33" +== 057 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 65" +== 058 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 65" +== 059 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 66" +== 060 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 66" +== 061 +-- truncate_limit: 100 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t" +== 062 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t (a, b) SELECT i, i FROM generate_series(1, 1000) n(i)" +== 063 +-- truncate_limit: 100 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t" +== 064 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 31" +== 065 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 31 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 31" +== 066 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 32" +== 067 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 32 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 32" +== 068 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 33" +== 069 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 33 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 33" +== 070 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 65" +== 071 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 65 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 65" +== 072 +-- truncate_limit: 100 +explain (costs off) select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 66" +== 073 +-- truncate_limit: 100 +select * from (select * from t order by a) s order by a, b limit 66 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t ORDER BY a) s ORDER BY a, b LIMIT 66" +== 074 +-- truncate_limit: 100 +delete from t +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t" +== 075 +-- truncate_limit: 100 +drop table t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 076 +-- truncate_limit: 100 +-- Incremental sort vs. parallel queries +set min_parallel_table_scan_size = '1kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO \"1kB\"" +== 077 +-- truncate_limit: 100 +set min_parallel_index_scan_size = '1kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_index_scan_size TO \"1kB\"" +== 078 +-- truncate_limit: 100 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 079 +-- truncate_limit: 100 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 080 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 081 +-- truncate_limit: 100 +create table t (a int, b int, c int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t (a int, b int, c int)" +== 082 +-- truncate_limit: 100 +insert into t select mod(i,10),mod(i,10),i from generate_series(1,10000) s(i) +-- +TABLE: name="t" schema="" table="t" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t SELECT mod(i, 10), mod(i, 10), i FROM generate_series(1, 10000) s(i)" +== 083 +-- truncate_limit: 100 +create index on t (a) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON t USING btree (a)" +== 084 +-- truncate_limit: 100 +analyze t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t" +== 085 +-- truncate_limit: 100 +set enable_incremental_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_incremental_sort TO OFF" +== 086 +-- truncate_limit: 100 +explain (costs off) select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, sum(c) FROM t GROUP BY 1, 2 ORDER BY 1, 2, 3 LIMIT 1" +== 087 +-- truncate_limit: 100 +set enable_incremental_sort = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_incremental_sort TO ON" +== 088 +-- truncate_limit: 100 +explain (costs off) select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, sum(c) FROM t GROUP BY 1, 2 ORDER BY 1, 2, 3 LIMIT 1" +== 089 +-- truncate_limit: 100 +-- Incremental sort vs. set operations with varno 0 +set enable_hashagg to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 090 +-- truncate_limit: 100 +explain (costs off) select * from t union select * from t order by 1,3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t UNION SELECT * FROM t ORDER BY 1, 3" +== 091 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="t" schema="" table="t" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT a, b FROM t" +== 092 +-- truncate_limit: 100 +drop table t +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t" +== 093 +-- truncate_limit: 100 +-- 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 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 094 +-- truncate_limit: 100 +set enable_seqscan=off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 095 +-- truncate_limit: 100 +set enable_incremental_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_incremental_sort TO OFF" +== 096 +-- truncate_limit: 100 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 097 +-- truncate_limit: 100 +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 098 +-- truncate_limit: 100 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 099 +-- truncate_limit: 100 +set min_parallel_index_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_index_scan_size TO 0" +== 100 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT sub.unique1, stringu1 FROM tenk1, LATERAL (SELECT tenk1.uniqu..." +== 101 +-- truncate_limit: 100 +explain (costs off) select sub.unique1, stringu1 +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub +order by 1, 2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sub.unique1, stringu1 FROM tenk1, LATERAL (SELECT tenk1.unique1 FROM g..." +== 102 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="md5" function="md5" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT sub.unique1, md5(stringu1) FROM tenk1, LATERAL (SELECT tenk1...." +== 103 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="md5" function="md5" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sub.unique1, md5(stringu1) FROM tenk1, LATERAL (SELECT tenk1.unique1 F..." +== 104 +-- truncate_limit: 100 +-- 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(*) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.unique1 = t2.unique2 JOIN t..." +== 105 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t"="tenk1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="t" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT unique1, (SELECT t.unique1 FROM tenk1 WHERE tenk1.unique1 = t..." +== 106 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t"="tenk1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="t" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, (SELECT t.unique1 FROM tenk1 WHERE tenk1.unique1 = t.unique1)..." +== 107 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT sub.unique1, stringu1 || random()::text FROM tenk1, LATERAL (..." +== 108 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sub.unique1, stringu1 || random()::text FROM tenk1, LATERAL (SELECT te..." +== 109 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 110 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 111 +-- truncate_limit: 100 +reset enable_incremental_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_incremental_sort" +== 112 +-- truncate_limit: 100 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_tuple_cost" +== 113 +-- truncate_limit: 100 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 114 +-- truncate_limit: 100 +reset min_parallel_table_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_table_scan_size" +== 115 +-- truncate_limit: 100 +reset min_parallel_index_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_index_scan_size" +== 116 +-- truncate_limit: 100 +-- Ensure incremental sorts work for amcanorderbyop type indexes +create table point_table (a point, b int) +-- +TABLE: name="point_table" schema="" table="point_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE point_table (a point, b int)" +== 117 +-- truncate_limit: 100 +create index point_table_a_idx on point_table using gist(a) +-- +TABLE: name="point_table" schema="" table="point_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX point_table_a_idx ON point_table USING gist (a)" +== 118 +-- truncate_limit: 100 +-- Ensure we get an incremental sort plan for both of the following queries +explain (costs off) select a, b, a <-> point(5, 5) dist from point_table order by dist, b limit 1 +-- +TABLE: name="point_table" schema="" table="point_table" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, a <-> point(5, 5) AS dist FROM point_table ORDER BY dist, b LIMIT 1" +== 119 +-- truncate_limit: 100 +explain (costs off) select a, b, a <-> point(5, 5) dist from point_table order by dist, b desc limit 1 +-- +TABLE: name="point_table" schema="" table="point_table" ctx=Select +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, a <-> point(5, 5) AS dist FROM point_table ORDER BY dist, b DESC..." diff --git a/parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json b/parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json new file mode 100644 index 0000000..e6f6795 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json @@ -0,0 +1,139 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/index_including.test b/parser/testdata/summary_truncate/postgres_regress/index_including.test new file mode 100644 index 0000000..fd90ad2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/index_including.test @@ -0,0 +1,1132 @@ +== 001 +-- truncate_limit: 100 +/* + * 1.test CREATE INDEX + * + * Deliberately avoid dropping objects in this section, to get some pg_dump + * coverage. + */ + +-- Regular index with included columns +CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box)" +== 002 +-- truncate_limit: 100 +INSERT INTO tbl_include_reg SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_include_reg SELECT x, 2 * x, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 003 +-- truncate_limit: 100 +CREATE INDEX tbl_include_reg_idx ON tbl_include_reg (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbl_include_reg_idx ON tbl_include_reg USING btree (c1, c2) INCLUDE (c3, c4)" +== 004 +-- truncate_limit: 100 +-- duplicate column is pretty pointless, but we allow it anyway +CREATE INDEX ON tbl_include_reg (c1, c2) INCLUDE (c1, c3) +-- +TABLE: name="tbl_include_reg" schema="" table="tbl_include_reg" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl_include_reg USING btree (c1, c2) INCLUDE (c1, c3)" +== 005 +-- truncate_limit: 100 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid WHERE ... ORDER BY c.relname" +== 006 +-- truncate_limit: 100 +-- Unique index and unique constraint +CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box)" +== 007 +-- truncate_limit: 100 +INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_include_unique1 SELECT x, 2 * x, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 008 +-- truncate_limit: 100 +CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 using btree (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 USING btree (c1, c2) IN..." +== 009 +-- truncate_limit: 100 +ALTER TABLE tbl_include_unique1 add UNIQUE USING INDEX tbl_include_unique1_idx_unique +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_include_unique1 ADD UNIQUE USING INDEX tbl_include_unique1_idx_unique" +== 010 +-- truncate_limit: 100 +ALTER TABLE tbl_include_unique1 add UNIQUE (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique1" schema="" table="tbl_include_unique1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_include_unique1 ADD UNIQUE (c1, c2) INCLUDE (c3, c4)" +== 011 +-- truncate_limit: 100 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_unique1'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid WHERE ... ORDER BY c.relname" +== 012 +-- truncate_limit: 100 +-- Unique index and unique constraint. Both must fail. +CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box)" +== 013 +-- truncate_limit: 100 +INSERT INTO tbl_include_unique2 SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_include_unique2 SELECT 1, 2, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 014 +-- truncate_limit: 100 +CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 using btree (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 USING btree (c1, c2) IN..." +== 015 +-- truncate_limit: 100 +ALTER TABLE tbl_include_unique2 add UNIQUE (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_unique2" schema="" table="tbl_include_unique2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_include_unique2 ADD UNIQUE (c1, c2) INCLUDE (c3, c4)" +== 016 +-- truncate_limit: 100 +-- PK constraint +CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_pk" schema="" table="tbl_include_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box)" +== 017 +-- truncate_limit: 100 +INSERT INTO tbl_include_pk SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_pk" schema="" table="tbl_include_pk" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_include_pk SELECT 1, 2 * x, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 018 +-- truncate_limit: 100 +ALTER TABLE tbl_include_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_pk" schema="" table="tbl_include_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_include_pk ADD PRIMARY KEY (c1, c2) INCLUDE (c3, c4)" +== 019 +-- truncate_limit: 100 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_pk'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid WHERE ... ORDER BY c.relname" +== 020 +-- truncate_limit: 100 +CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box)" +== 021 +-- truncate_limit: 100 +INSERT INTO tbl_include_box SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_include_box SELECT 1, 2 * x, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 022 +-- truncate_limit: 100 +CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box using btree (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box USING btree (c1, c2) INCLUDE (c..." +== 023 +-- truncate_limit: 100 +ALTER TABLE tbl_include_box add PRIMARY KEY USING INDEX tbl_include_box_idx_unique +-- +TABLE: name="tbl_include_box" schema="" table="tbl_include_box" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_include_box ADD PRIMARY KEY USING INDEX tbl_include_box_idx_unique" +== 024 +-- truncate_limit: 100 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_box'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid WHERE ... ORDER BY c.relname" +== 025 +-- truncate_limit: 100 +-- PK constraint. Must fail. +CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_include_box_pk" schema="" table="tbl_include_box_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box)" +== 026 +-- truncate_limit: 100 +INSERT INTO tbl_include_box_pk SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_include_box_pk" schema="" table="tbl_include_box_pk" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_include_box_pk SELECT 1, 2, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 027 +-- truncate_limit: 100 +ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl_include_box_pk" schema="" table="tbl_include_box_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_include_box_pk ADD PRIMARY KEY (c1, c2) INCLUDE (c3, c4)" +== 028 +-- truncate_limit: 100 +/* + * 2. Test CREATE TABLE with constraint + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + CONSTRAINT covering UNIQUE(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, CONSTRAINT covering UNIQUE (c1, c2) INCLUDE (c3..." +== 029 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'tbl'::regclass::oid" +== 030 +-- truncate_limit: 100 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid" +== 031 +-- truncate_limit: 100 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT 1, 2, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 032 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 033 +-- truncate_limit: 100 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + CONSTRAINT covering PRIMARY KEY(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, CONSTRAINT covering PRIMARY KEY (c1, c2) INCLUD..." +== 034 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'tbl'::regclass::oid" +== 035 +-- truncate_limit: 100 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid" +== 036 +-- truncate_limit: 100 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT 1, 2, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 037 +-- truncate_limit: 100 +INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT 1, NULL, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 038 +-- truncate_limit: 100 +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,300) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT x, 2 * x, NULL, NULL FROM generate_series(1, 300) x" +== 039 +-- truncate_limit: 100 +explain (costs off) +select * from tbl where (c1,c2,c3) < (2,5,1) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tbl WHERE (c1, c2, c3) < (2, 5, 1)" +== 040 +-- truncate_limit: 100 +select * from tbl where (c1,c2,c3) < (2,5,1) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tbl WHERE (c1, c2, c3) < (2, 5, 1)" +== 041 +-- truncate_limit: 100 +-- row comparison that compares high key at page boundary +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 042 +-- truncate_limit: 100 +explain (costs off) +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tbl WHERE (c1, c2, c3) < (262, 1, 1) LIMIT 1" +== 043 +-- truncate_limit: 100 +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=Select +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c3" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tbl WHERE (c1, c2, c3) < (262, 1, 1) LIMIT 1" +== 044 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 045 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 046 +-- truncate_limit: 100 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + UNIQUE(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, UNIQUE (c1, c2) INCLUDE (c3, c4))" +== 047 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'tbl'::regclass::oid" +== 048 +-- truncate_limit: 100 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid" +== 049 +-- truncate_limit: 100 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT 1, 2, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 050 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 051 +-- truncate_limit: 100 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + PRIMARY KEY(c1,c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, PRIMARY KEY (c1, c2) INCLUDE (c3, c4))" +== 052 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'tbl'::regclass::oid" +== 053 +-- truncate_limit: 100 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid" +== 054 +-- truncate_limit: 100 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT 1, 2, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 055 +-- truncate_limit: 100 +INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT 1, NULL, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 056 +-- truncate_limit: 100 +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT x, 2 * x, NULL, NULL FROM generate_series(1, 10) x" +== 057 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 058 +-- truncate_limit: 100 +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + EXCLUDE USING btree (c1 WITH =) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, EXCLUDE (c1 WITH =) INCLUDE (c3, c4))" +== 059 +-- truncate_limit: 100 +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index WHERE indrelid = 'tbl'::regclass::oid" +== 060 +-- truncate_limit: 100 +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid" +== 061 +-- truncate_limit: 100 +-- ensure that constraint works +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT 1, 2, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 062 +-- truncate_limit: 100 +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT x, 2 * x, NULL, NULL FROM generate_series(1, 10) x" +== 063 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 064 +-- truncate_limit: 100 +/* + * 3.0 Test ALTER TABLE DROP COLUMN. + * Any column deletion leads to index deletion. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 int) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 int)" +== 065 +-- truncate_limit: 100 +CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2, c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX tbl_idx ON tbl USING btree (c1, c2, c3, c4)" +== 066 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 067 +-- truncate_limit: 100 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl DROP c3" +== 068 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 069 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 070 +-- truncate_limit: 100 +/* + * 3.1 Test ALTER TABLE DROP COLUMN. + * Included column deletion leads to the index deletion, + * AS well AS key columns deletion. It's explained in documentation. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box)" +== 071 +-- truncate_limit: 100 +CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDE(c3,c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX tbl_idx ON tbl USING btree (c1, c2) INCLUDE (c3, c4)" +== 072 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 073 +-- truncate_limit: 100 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl DROP c3" +== 074 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 075 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 076 +-- truncate_limit: 100 +/* + * 3.2 Test ALTER TABLE DROP COLUMN. + * Included column deletion leads to the index deletion. + * AS well AS key columns deletion. It's explained in documentation. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, UNIQUE (c1, c2) INCLUDE (c3, c4))" +== 077 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 078 +-- truncate_limit: 100 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl DROP c3" +== 079 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 080 +-- truncate_limit: 100 +ALTER TABLE tbl DROP COLUMN c1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl DROP c1" +== 081 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 082 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 083 +-- truncate_limit: 100 +/* + * 3.3 Test ALTER TABLE SET STATISTICS + */ +CREATE TABLE tbl (c1 int, c2 int) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int)" +== 084 +-- truncate_limit: 100 +CREATE INDEX tbl_idx ON tbl (c1, (c1+0)) INCLUDE (c2) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbl_idx ON tbl USING btree (c1, (c1 + 0)) INCLUDE (c2)" +== 085 +-- truncate_limit: 100 +ALTER INDEX tbl_idx ALTER COLUMN 1 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbl_idx ALTER COLUMN 1 SET STATISTICS 1000" +== 086 +-- truncate_limit: 100 +ALTER INDEX tbl_idx ALTER COLUMN 2 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbl_idx ALTER COLUMN 2 SET STATISTICS 1000" +== 087 +-- truncate_limit: 100 +ALTER INDEX tbl_idx ALTER COLUMN 3 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbl_idx ALTER COLUMN 3 SET STATISTICS 1000" +== 088 +-- truncate_limit: 100 +ALTER INDEX tbl_idx ALTER COLUMN 4 SET STATISTICS 1000 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbl_idx ALTER COLUMN 4 SET STATISTICS 1000" +== 089 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 090 +-- truncate_limit: 100 +/* + * 4. CREATE INDEX CONCURRENTLY + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, UNIQUE (c1, c2) INCLUDE (c3, c4))" +== 091 +-- truncate_limit: 100 +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,1000) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT x, 2 * x, 3 * x, box('4,4,4,4') FROM generate_series(1, 1000) x" +== 092 +-- truncate_limit: 100 +CREATE UNIQUE INDEX CONCURRENTLY on tbl (c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX CONCURRENTLY ON tbl USING btree (c1, c2) INCLUDE (c3, c4)" +== 093 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 094 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 095 +-- truncate_limit: 100 +/* + * 5. REINDEX + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, UNIQUE (c1, c2) INCLUDE (c3, c4))" +== 096 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 097 +-- truncate_limit: 100 +ALTER TABLE tbl DROP COLUMN c3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl DROP c3" +== 098 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 099 +-- truncate_limit: 100 +REINDEX INDEX tbl_c1_c2_c3_c4_key +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX tbl_c1_c2_c3_c4_key" +== 100 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 101 +-- truncate_limit: 100 +ALTER TABLE tbl DROP COLUMN c1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl DROP c1" +== 102 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname" +== 103 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 104 +-- truncate_limit: 100 +/* + * 7. Check various AMs. All but btree, gist and spgist must fail. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 box, c4 box) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 box, c4 box)" +== 105 +-- truncate_limit: 100 +CREATE INDEX on tbl USING brin(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl USING brin (c1, c2) INCLUDE (c3, c4)" +== 106 +-- truncate_limit: 100 +CREATE INDEX on tbl USING gist(c3) INCLUDE (c1, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl USING gist (c3) INCLUDE (c1, c4)" +== 107 +-- truncate_limit: 100 +CREATE INDEX on tbl USING spgist(c3) INCLUDE (c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl USING spgist (c3) INCLUDE (c4)" +== 108 +-- truncate_limit: 100 +CREATE INDEX on tbl USING gin(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl USING gin (c1, c2) INCLUDE (c3, c4)" +== 109 +-- truncate_limit: 100 +CREATE INDEX on tbl USING hash(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl USING hash (c1, c2) INCLUDE (c3, c4)" +== 110 +-- truncate_limit: 100 +CREATE INDEX on tbl USING rtree(c3) INCLUDE (c1, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl USING rtree (c3) INCLUDE (c1, c4)" +== 111 +-- truncate_limit: 100 +CREATE INDEX on tbl USING btree(c1, c2) INCLUDE (c3, c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl USING btree (c1, c2) INCLUDE (c3, c4)" +== 112 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 113 +-- truncate_limit: 100 +/* + * 8. Update, delete values in indexed table. + */ +CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box)" +== 114 +-- truncate_limit: 100 +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT x, 2 * x, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 115 +-- truncate_limit: 100 +CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDE (c3,c4) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX tbl_idx_unique ON tbl USING btree (c1, c2) INCLUDE (c3, c4)" +== 116 +-- truncate_limit: 100 +UPDATE tbl SET c1 = 100 WHERE c1 = 2 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tbl SET c1 = 100 WHERE c1 = 2" +== 117 +-- truncate_limit: 100 +UPDATE tbl SET c1 = 1 WHERE c1 = 3 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tbl SET c1 = 1 WHERE c1 = 3" +== 118 +-- truncate_limit: 100 +-- should fail +UPDATE tbl SET c2 = 2 WHERE c1 = 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tbl SET c2 = 2 WHERE c1 = 1" +== 119 +-- truncate_limit: 100 +UPDATE tbl SET c3 = 1 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tbl SET c3 = 1" +== 120 +-- truncate_limit: 100 +DELETE FROM tbl WHERE c1 = 5 OR c3 = 12 +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tbl WHERE c1 = 5 OR c3 = 12" +== 121 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 122 +-- truncate_limit: 100 +/* + * 9. Alter column type. + */ +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)) +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box, UNIQUE (c1, c2) INCLUDE (c3, c4))" +== 123 +-- truncate_limit: 100 +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl SELECT x, 2 * x, 3 * x, box('4,4,4,4') FROM generate_series(1, 10) x" +== 124 +-- truncate_limit: 100 +ALTER TABLE tbl ALTER c1 TYPE bigint +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl ALTER COLUMN c1 TYPE bigint" +== 125 +-- truncate_limit: 100 +ALTER TABLE tbl ALTER c3 TYPE bigint +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl ALTER COLUMN c3 TYPE bigint" +== 126 +-- truncate_limit: 100 +DROP TABLE tbl +-- +TABLE: name="tbl" schema="" table="tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl" +== 127 +-- truncate_limit: 100 +/* + * 10. Test coverage for names stored as cstrings in indexes + */ +CREATE TABLE nametbl (c1 int, c2 name, c3 float) +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nametbl (c1 int, c2 name, c3 double precision)" +== 128 +-- truncate_limit: 100 +CREATE INDEX nametbl_c1_c2_idx ON nametbl (c2, c1) INCLUDE (c3) +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX nametbl_c1_c2_idx ON nametbl USING btree (c2, c1) INCLUDE (c3)" +== 129 +-- truncate_limit: 100 +INSERT INTO nametbl VALUES(1, 'two', 3.0) +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nametbl VALUES (1, 'two', 3.0)" +== 130 +-- truncate_limit: 100 +VACUUM nametbl +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM nametbl" +== 131 +-- truncate_limit: 100 +SET enable_seqscan = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO 0" +== 132 +-- truncate_limit: 100 +-- Ensure we get an index only scan plan +EXPLAIN (COSTS OFF) SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1 +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=Select +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1" +== 133 +-- truncate_limit: 100 +-- Validate the results look sane +SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1 +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=Select +FILTER: schema="" table="" column="c2" +FILTER: schema="" table="" column="c1" +STMT: SelectStmt +TRUNCATED: "SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1" +== 134 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 135 +-- truncate_limit: 100 +DROP TABLE nametbl +-- +TABLE: name="nametbl" schema="" table="nametbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE nametbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json new file mode 100644 index 0000000..147070d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json @@ -0,0 +1,54 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/index_including_gist.test b/parser/testdata/summary_truncate/postgres_regress/index_including_gist.test new file mode 100644 index 0000000..c2b0f81 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/index_including_gist.test @@ -0,0 +1,468 @@ +== 001 +-- truncate_limit: 100 +/* + * 1.1. test CREATE INDEX with buffered build + */ + +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box)" +== 002 +-- truncate_limit: 100 +-- size is chosen to exceed page size and trigger actual truncation +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 8000) x" +== 003 +-- truncate_limit: 100 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbl_gist_idx ON tbl_gist USING gist (c4) INCLUDE (c1, c2, c3)" +== 004 +-- truncate_limit: 100 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid WHERE ... ORDER BY c.relname" +== 005 +-- truncate_limit: 100 +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tbl_gist WHERE c4 <@ box(point(1, 1), point(10, 10))" +== 006 +-- truncate_limit: 100 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 007 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tbl_gist WHERE c4 <@ box(point(1, 1), point(10, 10))" +== 008 +-- truncate_limit: 100 +SET enable_bitmapscan TO default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO DEFAULT" +== 009 +-- truncate_limit: 100 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl_gist" +== 010 +-- truncate_limit: 100 +/* + * 1.2. test CREATE INDEX with inserts + */ + +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box)" +== 011 +-- truncate_limit: 100 +-- size is chosen to exceed page size and trigger actual truncation +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbl_gist_idx ON tbl_gist USING gist (c4) INCLUDE (c1, c2, c3)" +== 012 +-- truncate_limit: 100 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 8000) x" +== 013 +-- truncate_limit: 100 +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="i" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid WHERE ... ORDER BY c.relname" +== 014 +-- truncate_limit: 100 +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tbl_gist WHERE c4 <@ box(point(1, 1), point(10, 10))" +== 015 +-- truncate_limit: 100 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 016 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tbl_gist WHERE c4 <@ box(point(1, 1), point(10, 10))" +== 017 +-- truncate_limit: 100 +SET enable_bitmapscan TO default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO DEFAULT" +== 018 +-- truncate_limit: 100 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl_gist" +== 019 +-- truncate_limit: 100 +/* + * 2. CREATE INDEX CONCURRENTLY + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box)" +== 020 +-- truncate_limit: 100 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 10) x" +== 021 +-- truncate_limit: 100 +CREATE INDEX CONCURRENTLY tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY tbl_gist_idx ON tbl_gist USING gist (c4) INCLUDE (c1, c2, c3)" +== 022 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname" +== 023 +-- truncate_limit: 100 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl_gist" +== 024 +-- truncate_limit: 100 +/* + * 3. REINDEX + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box)" +== 025 +-- truncate_limit: 100 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 10) x" +== 026 +-- truncate_limit: 100 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbl_gist_idx ON tbl_gist USING gist (c4) INCLUDE (c1, c3)" +== 027 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname" +== 028 +-- truncate_limit: 100 +REINDEX INDEX tbl_gist_idx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX tbl_gist_idx" +== 029 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname" +== 030 +-- truncate_limit: 100 +ALTER TABLE tbl_gist DROP COLUMN c1 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_gist DROP c1" +== 031 +-- truncate_limit: 100 +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname" +== 032 +-- truncate_limit: 100 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl_gist" +== 033 +-- truncate_limit: 100 +/* + * 4. Update, delete values in indexed table. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box)" +== 034 +-- truncate_limit: 100 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 10) x" +== 035 +-- truncate_limit: 100 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbl_gist_idx ON tbl_gist USING gist (c4) INCLUDE (c1, c3)" +== 036 +-- truncate_limit: 100 +UPDATE tbl_gist SET c1 = 100 WHERE c1 = 2 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tbl_gist SET c1 = 100 WHERE c1 = 2" +== 037 +-- truncate_limit: 100 +UPDATE tbl_gist SET c1 = 1 WHERE c1 = 3 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tbl_gist SET c1 = 1 WHERE c1 = 3" +== 038 +-- truncate_limit: 100 +DELETE FROM tbl_gist WHERE c1 = 5 OR c3 = 12 +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tbl_gist WHERE c1 = 5 OR c3 = 12" +== 039 +-- truncate_limit: 100 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl_gist" +== 040 +-- truncate_limit: 100 +/* + * 5. Alter column type. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box)" +== 041 +-- truncate_limit: 100 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 10) x" +== 042 +-- truncate_limit: 100 +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbl_gist_idx ON tbl_gist USING gist (c4) INCLUDE (c1, c3)" +== 043 +-- truncate_limit: 100 +ALTER TABLE tbl_gist ALTER c1 TYPE bigint +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_gist ALTER COLUMN c1 TYPE bigint" +== 044 +-- truncate_limit: 100 +ALTER TABLE tbl_gist ALTER c3 TYPE bigint +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tbl_gist ALTER COLUMN c3 TYPE bigint" +== 045 +-- truncate_limit: 100 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl_gist" +== 046 +-- truncate_limit: 100 +/* + * 6. EXCLUDE constraint. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box, EXCLUDE USING gist (c4 WITH &&) INCLUDE (c1, c2, c3)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box, EXCLUDE USING gist (c4 WITH &&) INCLUDE (c..." +== 047 +-- truncate_limit: 100 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 10) x" +== 048 +-- truncate_limit: 100 +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(3*x,2*x),point(3*x+1,2*x+1)) FROM generate_series(1,10) AS x +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_gist SELECT ... FROM generate_series(1, 10) x" +== 049 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)) +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=Select +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FILTER: schema="" table="" column="c4" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tbl_gist WHERE c4 <@ box(point(1, 1), point(10, 10))" +== 050 +-- truncate_limit: 100 +DROP TABLE tbl_gist +-- +TABLE: name="tbl_gist" schema="" table="tbl_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl_gist" diff --git a/parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json b/parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json new file mode 100644 index 0000000..44a2d56 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json @@ -0,0 +1,564 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/indexing.test b/parser/testdata/summary_truncate/postgres_regress/indexing.test new file mode 100644 index 0000000..9c8892b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/indexing.test @@ -0,0 +1,4348 @@ +== 001 +-- truncate_limit: 100 +-- Creating an index on a partitioned table makes the partitions +-- automatically get the index +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c text) PARTITION BY RANGE (a)" +== 002 +-- truncate_limit: 100 +-- relhassubclass of a partitioned index is false before creating any partition. +-- It will be set after the first partition is created. +create index idxpart_idx on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_idx ON idxpart USING btree (a)" +== 003 +-- truncate_limit: 100 +select relhassubclass from pg_class where relname = 'idxpart_idx' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relhassubclass FROM pg_class WHERE relname = 'idxpart_idx'" +== 004 +-- truncate_limit: 100 +-- Check that partitioned indexes are present in pg_indexes. +select indexdef from pg_indexes where indexname like 'idxpart_idx%' +-- +TABLE: name="pg_indexes" schema="" table="pg_indexes" ctx=Select +FILTER: schema="" table="" column="indexname" +STMT: SelectStmt +TRUNCATED: "SELECT indexdef FROM pg_indexes WHERE indexname LIKE 'idxpart_idx%'" +== 005 +-- truncate_limit: 100 +drop index idxpart_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_idx" +== 006 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (10)" +== 007 +-- truncate_limit: 100 +create table idxpart2 partition of idxpart for values from (10) to (100) + partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 PARTITION OF idxpart FOR VALUES FROM (10) TO (100) PARTITION BY RANGE (b)" +== 008 +-- truncate_limit: 100 +create table idxpart21 partition of idxpart2 for values from (0) to (100) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart21 PARTITION OF idxpart2 FOR VALUES FROM (0) TO (100)" +== 009 +-- truncate_limit: 100 +-- Even with partitions, relhassubclass should not be set if a partitioned +-- index is created only on the parent. +create index idxpart_idx on only idxpart(a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_idx ON ONLY idxpart USING btree (a)" +== 010 +-- truncate_limit: 100 +select relhassubclass from pg_class where relname = 'idxpart_idx' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relhassubclass FROM pg_class WHERE relname = 'idxpart_idx'" +== 011 +-- truncate_limit: 100 +drop index idxpart_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_idx" +== 012 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 013 +-- truncate_limit: 100 +select relname, relkind, relhassubclass, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_index ix ON indexrelid = oid LEFT JOIN pg_inherits ON ix.in..." +== 014 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 015 +-- truncate_limit: 100 +-- Some unsupported features +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c text) PARTITION BY RANGE (a)" +== 016 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (10)" +== 017 +-- truncate_limit: 100 +create index concurrently on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY ON idxpart USING btree (a)" +== 018 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 019 +-- truncate_limit: 100 +-- Verify bugfix with query on indexed partitioned table with no partitions +-- https://postgr.es/m/20180124162006.pmapfiznhgngwtjf@alvherre.pgsql +CREATE TABLE idxpart (col1 INT) PARTITION BY RANGE (col1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (col1 int) PARTITION BY RANGE (col1)" +== 020 +-- truncate_limit: 100 +CREATE INDEX ON idxpart (col1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (col1)" +== 021 +-- truncate_limit: 100 +CREATE TABLE idxpart_two (col2 INT) +-- +TABLE: name="idxpart_two" schema="" table="idxpart_two" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart_two (col2 int)" +== 022 +-- truncate_limit: 100 +SELECT col2 FROM idxpart_two fk LEFT OUTER JOIN idxpart pk ON (col1 = col2) +-- +TABLE: name="idxpart_two" schema="" table="idxpart_two" ctx=Select +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +ALIAS: "fk"="idxpart_two" +ALIAS: "pk"="idxpart" +STMT: SelectStmt +TRUNCATED: "SELECT col2 FROM idxpart_two fk LEFT JOIN idxpart pk ON col1 = col2" +== 023 +-- truncate_limit: 100 +DROP table idxpart, idxpart_two +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart_two" schema="" table="idxpart_two" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart, idxpart_two" +== 024 +-- truncate_limit: 100 +-- Verify bugfix with index rewrite on ALTER TABLE / SET DATA TYPE +-- https://postgr.es/m/CAKcux6mxNCGsgATwf5CGMF8g4WSupCXicCVMeKUTuWbyxHOMsQ@mail.gmail.com +CREATE TABLE idxpart (a INT, b TEXT, c INT) PARTITION BY RANGE(a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b text, c int) PARTITION BY RANGE (a)" +== 025 +-- truncate_limit: 100 +CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (MINVALUE) TO (MAXVALUE) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (minvalue) TO (maxvalue)" +== 026 +-- truncate_limit: 100 +CREATE INDEX partidx_abc_idx ON idxpart (a, b, c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX partidx_abc_idx ON idxpart USING btree (a, b, c)" +== 027 +-- truncate_limit: 100 +INSERT INTO idxpart (a, b, c) SELECT i, i, i FROM generate_series(1, 50) i +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart (a, b, c) SELECT i, i, i FROM generate_series(1, 50) i" +== 028 +-- truncate_limit: 100 +ALTER TABLE idxpart ALTER COLUMN c TYPE numeric +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ALTER COLUMN c TYPE numeric" +== 029 +-- truncate_limit: 100 +DROP TABLE idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 030 +-- truncate_limit: 100 +-- If a table without index is attached as partition to a table with +-- an index, the index is automatically created +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c text) PARTITION BY RANGE (a)" +== 031 +-- truncate_limit: 100 +create index idxparti on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxparti ON idxpart USING btree (a)" +== 032 +-- truncate_limit: 100 +create index idxparti2 on idxpart (b, c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxparti2 ON idxpart USING btree (b, c)" +== 033 +-- truncate_limit: 100 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart)" +== 034 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (10) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (10)" +== 035 +-- truncate_limit: 100 +-- Forbid ALTER TABLE when attaching or detaching an index to a partition. +create index idxpart_c on only idxpart (c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_c ON ONLY idxpart USING btree (c)" +== 036 +-- truncate_limit: 100 +create index idxpart1_c on idxpart1 (c) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_c ON idxpart1 USING btree (c)" +== 037 +-- truncate_limit: 100 +alter table idxpart_c attach partition idxpart1_c for values from (10) to (20) +-- +TABLE: name="idxpart_c" schema="" table="idxpart_c" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart_c ATTACH PARTITION idxpart1_c FOR VALUES FROM (10) TO (20)" +== 038 +-- truncate_limit: 100 +alter index idxpart_c attach partition idxpart1_c +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_c ATTACH PARTITION idxpart1_c" +== 039 +-- truncate_limit: 100 +select relname, relpartbound from pg_class + where relname in ('idxpart_c', 'idxpart1_c') + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relpartbound FROM pg_class WHERE ... ORDER BY relname" +== 040 +-- truncate_limit: 100 +alter table idxpart_c detach partition idxpart1_c +-- +TABLE: name="idxpart_c" schema="" table="idxpart_c" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart_c DETACH PARTITION idxpart1_c" +== 041 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 042 +-- truncate_limit: 100 +-- If a partition already has an index, don't create a duplicative one +create table idxpart (a int, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a, b)" +== 043 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0, 0) TO (10, 10)" +== 044 +-- truncate_limit: 100 +create index on idxpart1 (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree (a, b)" +== 045 +-- truncate_limit: 100 +create index on idxpart (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a, b)" +== 046 +-- truncate_limit: 100 +select relname, relkind, relhassubclass, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_index ix ON indexrelid = oid LEFT JOIN pg_inherits ON ix.in..." +== 047 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 048 +-- truncate_limit: 100 +-- DROP behavior for partitioned indexes +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 049 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 050 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (10)" +== 051 +-- truncate_limit: 100 +drop index idxpart1_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart1_a_idx" +== 052 +-- truncate_limit: 100 +-- no way +drop index concurrently idxpart_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY idxpart_a_idx" +== 053 +-- truncate_limit: 100 +-- unsupported +drop index idxpart_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_a_idx" +== 054 +-- truncate_limit: 100 +-- both indexes go away +select relname, relkind from pg_class + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 055 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 056 +-- truncate_limit: 100 +drop table idxpart1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart1" +== 057 +-- truncate_limit: 100 +-- the index on partition goes away too +select relname, relkind from pg_class + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 058 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 059 +-- truncate_limit: 100 +-- DROP behavior with temporary partitioned indexes +create temp table idxpart_temp (a int) partition by range (a) +-- +TABLE: name="idxpart_temp" schema="" table="idxpart_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE idxpart_temp (a int) PARTITION BY RANGE (a)" +== 060 +-- truncate_limit: 100 +create index on idxpart_temp(a) +-- +TABLE: name="idxpart_temp" schema="" table="idxpart_temp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart_temp USING btree (a)" +== 061 +-- truncate_limit: 100 +create temp table idxpart1_temp partition of idxpart_temp + for values from (0) to (10) +-- +TABLE: name="idxpart1_temp" schema="" table="idxpart1_temp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE idxpart1_temp PARTITION OF idxpart_temp FOR VALUES FROM (0) TO (10)" +== 062 +-- truncate_limit: 100 +drop index idxpart1_temp_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart1_temp_a_idx" +== 063 +-- truncate_limit: 100 +-- error +-- non-concurrent drop is enforced here, so it is a valid case. +drop index concurrently idxpart_temp_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX CONCURRENTLY idxpart_temp_a_idx" +== 064 +-- truncate_limit: 100 +select relname, relkind from pg_class + where relname like 'idxpart_temp%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart_temp%' ORDER BY relname" +== 065 +-- truncate_limit: 100 +drop table idxpart_temp +-- +TABLE: name="idxpart_temp" schema="" table="idxpart_temp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart_temp" +== 066 +-- truncate_limit: 100 +-- ALTER INDEX .. ATTACH, error cases +create table idxpart (a int, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a, b)" +== 067 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0, 0) TO (10, 10)" +== 068 +-- truncate_limit: 100 +create index idxpart_a_b_idx on only idxpart (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_a_b_idx ON ONLY idxpart USING btree (a, b)" +== 069 +-- truncate_limit: 100 +create index idxpart1_a_b_idx on idxpart1 (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_a_b_idx ON idxpart1 USING btree (a, b)" +== 070 +-- truncate_limit: 100 +create index idxpart1_tst1 on idxpart1 (b, a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_tst1 ON idxpart1 USING btree (b, a)" +== 071 +-- truncate_limit: 100 +create index idxpart1_tst2 on idxpart1 using hash (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_tst2 ON idxpart1 USING hash (a)" +== 072 +-- truncate_limit: 100 +create index idxpart1_tst3 on idxpart1 (a, b) where a > 10 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_tst3 ON idxpart1 USING btree (a, b) WHERE a > 10" +== 073 +-- truncate_limit: 100 +alter index idxpart attach partition idxpart1 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart ATTACH PARTITION idxpart1" +== 074 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart1 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1" +== 075 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart_a_b_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart_a_b_idx" +== 076 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart1_b_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1_b_idx" +== 077 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart1_tst1 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1_tst1" +== 078 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart1_tst2 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1_tst2" +== 079 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart1_tst3 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1_tst3" +== 080 +-- truncate_limit: 100 +-- OK +alter index idxpart_a_b_idx attach partition idxpart1_a_b_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1_a_b_idx" +== 081 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart1_a_b_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1_a_b_idx" +== 082 +-- truncate_limit: 100 +-- quiet + +-- reject dupe +create index idxpart1_2_a_b on idxpart1 (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_2_a_b ON idxpart1 USING btree (a, b)" +== 083 +-- truncate_limit: 100 +alter index idxpart_a_b_idx attach partition idxpart1_2_a_b +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_b_idx ATTACH PARTITION idxpart1_2_a_b" +== 084 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 085 +-- truncate_limit: 100 +-- make sure everything's gone +select indexrelid::regclass, indrelid::regclass + from pg_index where indexrelid::regclass::text like 'idxpart%' +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT indexrelid::regclass, indrelid::regclass FROM pg_index WHERE ..." +== 086 +-- truncate_limit: 100 +-- Don't auto-attach incompatible indexes +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a)" +== 087 +-- truncate_limit: 100 +create table idxpart1 (a int, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (a int, b int)" +== 088 +-- truncate_limit: 100 +create index on idxpart1 using hash (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING hash (a)" +== 089 +-- truncate_limit: 100 +create index on idxpart1 (a) where b > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree (a) WHERE b > 1" +== 090 +-- truncate_limit: 100 +create index on idxpart1 ((a + 0)) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree ((a + 0))" +== 091 +-- truncate_limit: 100 +create index on idxpart1 (a, a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree (a, a)" +== 092 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 093 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 094 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 095 +-- truncate_limit: 100 +-- If CREATE INDEX ONLY, don't create indexes on partitions; and existing +-- indexes on partitions don't change parent. ALTER INDEX ATTACH can change +-- the parent after the fact. +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 096 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (100) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (100)" +== 097 +-- truncate_limit: 100 +create table idxpart2 partition of idxpart for values from (100) to (1000) + partition by range (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 PARTITION OF idxpart FOR VALUES FROM (100) TO (1000) PARTITION BY RANGE (a)" +== 098 +-- truncate_limit: 100 +create table idxpart21 partition of idxpart2 for values from (100) to (200) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart21 PARTITION OF idxpart2 FOR VALUES FROM (100) TO (200)" +== 099 +-- truncate_limit: 100 +create table idxpart22 partition of idxpart2 for values from (200) to (300) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart22 PARTITION OF idxpart2 FOR VALUES FROM (200) TO (300)" +== 100 +-- truncate_limit: 100 +create index on idxpart22 (a) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart22 USING btree (a)" +== 101 +-- truncate_limit: 100 +create index on only idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON ONLY idxpart2 USING btree (a)" +== 102 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 103 +-- truncate_limit: 100 +-- Here we expect that idxpart1 and idxpart2 have a new index, but idxpart21 +-- does not; also, idxpart22 is not attached. +select indexrelid::regclass, indrelid::regclass, inhparent::regclass + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) +where indexrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid WHERE ......" +== 104 +-- truncate_limit: 100 +alter index idxpart2_a_idx attach partition idxpart22_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart2_a_idx ATTACH PARTITION idxpart22_a_idx" +== 105 +-- truncate_limit: 100 +select indexrelid::regclass, indrelid::regclass, inhparent::regclass + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) +where indexrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid WHERE ......" +== 106 +-- truncate_limit: 100 +-- attaching idxpart22 is not enough to set idxpart22_a_idx valid ... +alter index idxpart2_a_idx attach partition idxpart22_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart2_a_idx ATTACH PARTITION idxpart22_a_idx" +== 107 +-- truncate_limit: 100 +-- ... but this one is. +create index on idxpart21 (a) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart21 USING btree (a)" +== 108 +-- truncate_limit: 100 +alter index idxpart2_a_idx attach partition idxpart21_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart2_a_idx ATTACH PARTITION idxpart21_a_idx" +== 109 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 110 +-- truncate_limit: 100 +-- When a table is attached a partition and it already has an index, a +-- duplicate index should not get created, but rather the index becomes +-- attached to the parent's index. +create table idxpart (a int, b int, c text, d bool) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c text, d bool) PARTITION BY RANGE (a)" +== 111 +-- truncate_limit: 100 +create index idxparti on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxparti ON idxpart USING btree (a)" +== 112 +-- truncate_limit: 100 +create index idxparti2 on idxpart (b, c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxparti2 ON idxpart USING btree (b, c)" +== 113 +-- truncate_limit: 100 +create table idxpart1 (like idxpart including indexes) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart INCLUDING INDEXES)" +== 114 +-- truncate_limit: 100 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_index ix ON indexrelid = oid LEFT JOIN pg_inherits ON ix.in..." +== 115 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (10) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (10)" +== 116 +-- truncate_limit: 100 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_index ix ON indexrelid = oid LEFT JOIN pg_inherits ON ix.in..." +== 117 +-- truncate_limit: 100 +-- While here, also check matching when creating an index after the fact. +create index on idxpart1 ((a+b)) where d = true +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree ((a + b)) WHERE d = true" +== 118 +-- truncate_limit: 100 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_index ix ON indexrelid = oid LEFT JOIN pg_inherits ON ix.in..." +== 119 +-- truncate_limit: 100 +create index idxparti3 on idxpart ((a+b)) where d = true +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxparti3 ON idxpart USING btree ((a + b)) WHERE d = true" +== 120 +-- truncate_limit: 100 +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "ix"="pg_index" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_index ix ON indexrelid = oid LEFT JOIN pg_inherits ON ix.in..." +== 121 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 122 +-- truncate_limit: 100 +-- Verify that attaching an invalid index does not mark the parent index valid. +-- On the other hand, attaching a valid index marks not only its direct +-- ancestor valid, but also any indirect ancestor that was only missing the one +-- that was just made valid +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a)" +== 123 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (1) to (1000) partition by range (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (1) TO (1000) PARTITION BY RANGE (a)" +== 124 +-- truncate_limit: 100 +create table idxpart11 partition of idxpart1 for values from (1) to (100) +-- +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart11 PARTITION OF idxpart1 FOR VALUES FROM (1) TO (100)" +== 125 +-- truncate_limit: 100 +create index on only idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON ONLY idxpart1 USING btree (a)" +== 126 +-- truncate_limit: 100 +create index on only idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON ONLY idxpart USING btree (a)" +== 127 +-- truncate_limit: 100 +-- this results in two invalid indexes: +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class JOIN pg_index ON indexrelid = oid WHERE ... ORDER BY relname" +== 128 +-- truncate_limit: 100 +-- idxpart1_a_idx is not valid, so idxpart_a_idx should not become valid: +alter index idxpart_a_idx attach partition idxpart1_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_idx ATTACH PARTITION idxpart1_a_idx" +== 129 +-- truncate_limit: 100 +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class JOIN pg_index ON indexrelid = oid WHERE ... ORDER BY relname" +== 130 +-- truncate_limit: 100 +-- after creating and attaching this, both idxpart1_a_idx and idxpart_a_idx +-- should become valid +create index on idxpart11 (a) +-- +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart11 USING btree (a)" +== 131 +-- truncate_limit: 100 +alter index idxpart1_a_idx attach partition idxpart11_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart1_a_idx ATTACH PARTITION idxpart11_a_idx" +== 132 +-- truncate_limit: 100 +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class JOIN pg_index ON indexrelid = oid WHERE ... ORDER BY relname" +== 133 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 134 +-- truncate_limit: 100 +-- verify dependency handling during ALTER TABLE DETACH PARTITION +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 135 +-- truncate_limit: 100 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart)" +== 136 +-- truncate_limit: 100 +create index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree (a)" +== 137 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 138 +-- truncate_limit: 100 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (LIKE idxpart)" +== 139 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0000) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 140 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM (1000) TO (2000)" +== 141 +-- truncate_limit: 100 +create table idxpart3 partition of idxpart for values from (2000) to (3000) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart3 PARTITION OF idxpart FOR VALUES FROM (2000) TO (3000)" +== 142 +-- truncate_limit: 100 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 143 +-- truncate_limit: 100 +-- a) after detaching partitions, the indexes can be dropped independently +alter table idxpart detach partition idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DETACH PARTITION idxpart1" +== 144 +-- truncate_limit: 100 +alter table idxpart detach partition idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DETACH PARTITION idxpart2" +== 145 +-- truncate_limit: 100 +alter table idxpart detach partition idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DETACH PARTITION idxpart3" +== 146 +-- truncate_limit: 100 +drop index idxpart1_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart1_a_idx" +== 147 +-- truncate_limit: 100 +drop index idxpart2_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart2_a_idx" +== 148 +-- truncate_limit: 100 +drop index idxpart3_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart3_a_idx" +== 149 +-- truncate_limit: 100 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 150 +-- truncate_limit: 100 +drop table idxpart, idxpart1, idxpart2, idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart, idxpart1, idxpart2, idxpart3" +== 151 +-- truncate_limit: 100 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 152 +-- truncate_limit: 100 +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 153 +-- truncate_limit: 100 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart)" +== 154 +-- truncate_limit: 100 +create index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree (a)" +== 155 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 156 +-- truncate_limit: 100 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (LIKE idxpart)" +== 157 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0000) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 158 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM (1000) TO (2000)" +== 159 +-- truncate_limit: 100 +create table idxpart3 partition of idxpart for values from (2000) to (3000) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart3 PARTITION OF idxpart FOR VALUES FROM (2000) TO (3000)" +== 160 +-- truncate_limit: 100 +-- b) after detaching, dropping the index on parent does not remove the others +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 161 +-- truncate_limit: 100 +alter table idxpart detach partition idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DETACH PARTITION idxpart1" +== 162 +-- truncate_limit: 100 +alter table idxpart detach partition idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DETACH PARTITION idxpart2" +== 163 +-- truncate_limit: 100 +alter table idxpart detach partition idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DETACH PARTITION idxpart3" +== 164 +-- truncate_limit: 100 +drop index idxpart_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_a_idx" +== 165 +-- truncate_limit: 100 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 166 +-- truncate_limit: 100 +drop table idxpart, idxpart1, idxpart2, idxpart3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart, idxpart1, idxpart2, idxpart3" +== 167 +-- truncate_limit: 100 +select relname, relkind from pg_class where relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE relname LIKE 'idxpart%' ORDER BY relname" +== 168 +-- truncate_limit: 100 +create table idxpart (a int, b int, c int) partition by range(a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c int) PARTITION BY RANGE (a)" +== 169 +-- truncate_limit: 100 +create index on idxpart(c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (c)" +== 170 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (250) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (250)" +== 171 +-- truncate_limit: 100 +create table idxpart2 partition of idxpart for values from (250) to (500) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 PARTITION OF idxpart FOR VALUES FROM (250) TO (500)" +== 172 +-- truncate_limit: 100 +alter table idxpart detach partition idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DETACH PARTITION idxpart2" +== 173 +-- truncate_limit: 100 +alter table idxpart2 drop column c +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart2 DROP c" +== 174 +-- truncate_limit: 100 +drop table idxpart, idxpart2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart, idxpart2" +== 175 +-- truncate_limit: 100 +-- Verify that expression indexes inherit correctly +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a)" +== 176 +-- truncate_limit: 100 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart)" +== 177 +-- truncate_limit: 100 +create index on idxpart1 ((a + b)) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree ((a + b))" +== 178 +-- truncate_limit: 100 +create index on idxpart ((a + b)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree ((a + b))" +== 179 +-- truncate_limit: 100 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (LIKE idxpart)" +== 180 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0000) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 181 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM (1000) TO (2000)" +== 182 +-- truncate_limit: 100 +create table idxpart3 partition of idxpart for values from (2000) to (3000) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart3 PARTITION OF idxpart FOR VALUES FROM (2000) TO (3000)" +== 183 +-- truncate_limit: 100 +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class JOIN pg_inherits ON inhrelid = oid, LATERAL pg_get_indexdef(pg_class.oid..." +== 184 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 185 +-- truncate_limit: 100 +-- Verify behavior for collation (mis)matches +create table idxpart (a text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a text) PARTITION BY RANGE (a)" +== 186 +-- truncate_limit: 100 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart)" +== 187 +-- truncate_limit: 100 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (LIKE idxpart)" +== 188 +-- truncate_limit: 100 +create index on idxpart2 (a collate "POSIX") +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (a COLLATE \"POSIX\")" +== 189 +-- truncate_limit: 100 +create index on idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (a)" +== 190 +-- truncate_limit: 100 +create index on idxpart2 (a collate "C") +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (a COLLATE \"C\")" +== 191 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from ('aaa') to ('bbb') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM ('aaa') TO ('bbb')" +== 192 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from ('bbb') to ('ccc') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM ('bbb') TO ('ccc')" +== 193 +-- truncate_limit: 100 +create table idxpart3 partition of idxpart for values from ('ccc') to ('ddd') +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart3 PARTITION OF idxpart FOR VALUES FROM ('ccc') TO ('ddd')" +== 194 +-- truncate_limit: 100 +create index on idxpart (a collate "C") +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a COLLATE \"C\")" +== 195 +-- truncate_limit: 100 +create table idxpart4 partition of idxpart for values from ('ddd') to ('eee') +-- +TABLE: name="idxpart4" schema="" table="idxpart4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart4 PARTITION OF idxpart FOR VALUES FROM ('ddd') TO ('eee')" +== 196 +-- truncate_limit: 100 +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_inherits ON inhrelid = oid, LATERAL pg_get_indexdef(pg_clas..." +== 197 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 198 +-- truncate_limit: 100 +-- Verify behavior for opclass (mis)matches +create table idxpart (a text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a text) PARTITION BY RANGE (a)" +== 199 +-- truncate_limit: 100 +create table idxpart1 (like idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart)" +== 200 +-- truncate_limit: 100 +create table idxpart2 (like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (LIKE idxpart)" +== 201 +-- truncate_limit: 100 +create index on idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (a)" +== 202 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from ('aaa') to ('bbb') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM ('aaa') TO ('bbb')" +== 203 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from ('bbb') to ('ccc') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM ('bbb') TO ('ccc')" +== 204 +-- truncate_limit: 100 +create table idxpart3 partition of idxpart for values from ('ccc') to ('ddd') +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart3 PARTITION OF idxpart FOR VALUES FROM ('ccc') TO ('ddd')" +== 205 +-- truncate_limit: 100 +create index on idxpart (a text_pattern_ops) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a text_pattern_ops)" +== 206 +-- truncate_limit: 100 +create table idxpart4 partition of idxpart for values from ('ddd') to ('eee') +-- +TABLE: name="idxpart4" schema="" table="idxpart4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart4 PARTITION OF idxpart FOR VALUES FROM ('ddd') TO ('eee')" +== 207 +-- truncate_limit: 100 +-- must *not* have attached the index we created on idxpart2 +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_inherits ON inhrelid = oid, LATERAL pg_get_indexdef(pg_clas..." +== 208 +-- truncate_limit: 100 +drop index idxpart_a_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_a_idx" +== 209 +-- truncate_limit: 100 +create index on only idxpart (a text_pattern_ops) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON ONLY idxpart USING btree (a text_pattern_ops)" +== 210 +-- truncate_limit: 100 +-- must reject +alter index idxpart_a_idx attach partition idxpart2_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_a_idx ATTACH PARTITION idxpart2_a_idx" +== 211 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 212 +-- truncate_limit: 100 +-- Verify that attaching indexes maps attribute numbers correctly +create table idxpart (col1 int, a int, col2 int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (col1 int, a int, col2 int, b int) PARTITION BY RANGE (a)" +== 213 +-- truncate_limit: 100 +create table idxpart1 (b int, col1 int, col2 int, col3 int, a int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (b int, col1 int, col2 int, col3 int, a int)" +== 214 +-- truncate_limit: 100 +alter table idxpart drop column col1, drop column col2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DROP col1, DROP col2" +== 215 +-- truncate_limit: 100 +alter table idxpart1 drop column col1, drop column col2, drop column col3 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 DROP col1, DROP col2, DROP col3" +== 216 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 217 +-- truncate_limit: 100 +create index idxpart_1_idx on only idxpart (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_1_idx ON ONLY idxpart USING btree (b, a)" +== 218 +-- truncate_limit: 100 +create index idxpart1_1_idx on idxpart1 (b, a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_1_idx ON idxpart1 USING btree (b, a)" +== 219 +-- truncate_limit: 100 +create index idxpart1_1b_idx on idxpart1 (b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_1b_idx ON idxpart1 USING btree (b)" +== 220 +-- truncate_limit: 100 +-- test expressions and partial-index predicate, too +create index idxpart_2_idx on only idxpart ((b + a)) where a > 1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_2_idx ON ONLY idxpart USING btree ((b + a)) WHERE a > 1" +== 221 +-- truncate_limit: 100 +create index idxpart1_2_idx on idxpart1 ((b + a)) where a > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_2_idx ON idxpart1 USING btree ((b + a)) WHERE a > 1" +== 222 +-- truncate_limit: 100 +create index idxpart1_2b_idx on idxpart1 ((a + b)) where a > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_2b_idx ON idxpart1 USING btree ((a + b)) WHERE a > 1" +== 223 +-- truncate_limit: 100 +create index idxpart1_2c_idx on idxpart1 ((b + a)) where b > 1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart1_2c_idx ON idxpart1 USING btree ((b + a)) WHERE b > 1" +== 224 +-- truncate_limit: 100 +alter index idxpart_1_idx attach partition idxpart1_1b_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_1_idx ATTACH PARTITION idxpart1_1b_idx" +== 225 +-- truncate_limit: 100 +-- fail +alter index idxpart_1_idx attach partition idxpart1_1_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_1_idx ATTACH PARTITION idxpart1_1_idx" +== 226 +-- truncate_limit: 100 +alter index idxpart_2_idx attach partition idxpart1_2b_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_2_idx ATTACH PARTITION idxpart1_2b_idx" +== 227 +-- truncate_limit: 100 +-- fail +alter index idxpart_2_idx attach partition idxpart1_2c_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_2_idx ATTACH PARTITION idxpart1_2c_idx" +== 228 +-- truncate_limit: 100 +-- fail +alter index idxpart_2_idx attach partition idxpart1_2_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_2_idx ATTACH PARTITION idxpart1_2_idx" +== 229 +-- truncate_limit: 100 +-- ok +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class LEFT JOIN pg_inherits ON inhrelid = oid, LATERAL pg_get_indexdef(pg_clas..." +== 230 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 231 +-- truncate_limit: 100 +-- Make sure the partition columns are mapped correctly +create table idxpart (a int, b int, c text) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c text) PARTITION BY RANGE (a)" +== 232 +-- truncate_limit: 100 +create index idxparti on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxparti ON idxpart USING btree (a)" +== 233 +-- truncate_limit: 100 +create index idxparti2 on idxpart (c, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxparti2 ON idxpart USING btree (c, b)" +== 234 +-- truncate_limit: 100 +create table idxpart1 (c text, a int, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (c text, a int, b int)" +== 235 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (10) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (10)" +== 236 +-- truncate_limit: 100 +create table idxpart2 (c text, a int, b int) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (c text, a int, b int)" +== 237 +-- truncate_limit: 100 +create index on idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (a)" +== 238 +-- truncate_limit: 100 +create index on idxpart2 (c, b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (c, b)" +== 239 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from (10) to (20) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM (10) TO (20)" +== 240 +-- truncate_limit: 100 +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid WHERE ... ORDER BY indexrelid:..." +== 241 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 242 +-- truncate_limit: 100 +-- Verify that columns are mapped correctly in expression indexes +create table idxpart (col1 int, col2 int, a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (col1 int, col2 int, a int, b int) PARTITION BY RANGE (a)" +== 243 +-- truncate_limit: 100 +create table idxpart1 (col2 int, b int, col1 int, a int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (col2 int, b int, col1 int, a int)" +== 244 +-- truncate_limit: 100 +create table idxpart2 (col1 int, col2 int, b int, a int) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (col1 int, col2 int, b int, a int)" +== 245 +-- truncate_limit: 100 +alter table idxpart drop column col1, drop column col2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DROP col1, DROP col2" +== 246 +-- truncate_limit: 100 +alter table idxpart1 drop column col1, drop column col2 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 DROP col1, DROP col2" +== 247 +-- truncate_limit: 100 +alter table idxpart2 drop column col1, drop column col2 +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart2 DROP col1, DROP col2" +== 248 +-- truncate_limit: 100 +create index on idxpart2 (abs(b)) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (abs(b))" +== 249 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from (0) to (1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM (0) TO (1)" +== 250 +-- truncate_limit: 100 +create index on idxpart (abs(b)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (abs(b))" +== 251 +-- truncate_limit: 100 +create index on idxpart ((b + 1)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree ((b + 1))" +== 252 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (1) to (2) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (1) TO (2)" +== 253 +-- truncate_limit: 100 +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid WHERE ... ORDER BY indexrelid:..." +== 254 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 255 +-- truncate_limit: 100 +-- Verify that columns are mapped correctly for WHERE in a partial index +create table idxpart (col1 int, a int, col3 int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (col1 int, a int, col3 int, b int) PARTITION BY RANGE (a)" +== 256 +-- truncate_limit: 100 +alter table idxpart drop column col1, drop column col3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DROP col1, DROP col3" +== 257 +-- truncate_limit: 100 +create table idxpart1 (col1 int, col2 int, col3 int, col4 int, b int, a int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (col1 int, col2 int, col3 int, col4 int, b int, a int)" +== 258 +-- truncate_limit: 100 +alter table idxpart1 drop column col1, drop column col2, drop column col3, drop column col4 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 DROP col1, DROP col2, DROP col3, DROP col4" +== 259 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 260 +-- truncate_limit: 100 +create table idxpart2 (col1 int, col2 int, b int, a int) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (col1 int, col2 int, b int, a int)" +== 261 +-- truncate_limit: 100 +create index on idxpart2 (a) where b > 1000 +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart2 USING btree (a) WHERE b > 1000" +== 262 +-- truncate_limit: 100 +alter table idxpart2 drop column col1, drop column col2 +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart2 DROP col1, DROP col2" +== 263 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM (1000) TO (2000)" +== 264 +-- truncate_limit: 100 +create index on idxpart (a) where b > 1000 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a) WHERE b > 1000" +== 265 +-- truncate_limit: 100 +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid WHERE ... ORDER BY indexrelid:..." +== 266 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 267 +-- truncate_limit: 100 +-- Column number mapping: dropped columns in the partition +create table idxpart1 (drop_1 int, drop_2 int, col_keep int, drop_3 int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (drop_1 int, drop_2 int, col_keep int, drop_3 int)" +== 268 +-- truncate_limit: 100 +alter table idxpart1 drop column drop_1 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 DROP drop_1" +== 269 +-- truncate_limit: 100 +alter table idxpart1 drop column drop_2 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 DROP drop_2" +== 270 +-- truncate_limit: 100 +alter table idxpart1 drop column drop_3 +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 DROP drop_3" +== 271 +-- truncate_limit: 100 +create index on idxpart1 (col_keep) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree (col_keep)" +== 272 +-- truncate_limit: 100 +create table idxpart (col_keep int) partition by range (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (col_keep int) PARTITION BY RANGE (col_keep)" +== 273 +-- truncate_limit: 100 +create index on idxpart (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (col_keep)" +== 274 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 275 +-- truncate_limit: 100 +select attrelid::regclass, attname, attnum from pg_attribute + where attrelid::regclass::text like 'idxpart%' and attnum > 0 + order by attrelid::regclass, attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE ... ORDER BY attrelid::regclass, attnum" +== 276 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 277 +-- truncate_limit: 100 +-- Column number mapping: dropped columns in the parent table +create table idxpart(drop_1 int, drop_2 int, col_keep int, drop_3 int) partition by range (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (drop_1 int, drop_2 int, col_keep int, drop_3 int) PARTITION BY RANGE (col_k..." +== 278 +-- truncate_limit: 100 +alter table idxpart drop column drop_1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DROP drop_1" +== 279 +-- truncate_limit: 100 +alter table idxpart drop column drop_2 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DROP drop_2" +== 280 +-- truncate_limit: 100 +alter table idxpart drop column drop_3 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DROP drop_3" +== 281 +-- truncate_limit: 100 +create table idxpart1 (col_keep int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (col_keep int)" +== 282 +-- truncate_limit: 100 +create index on idxpart1 (col_keep) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart1 USING btree (col_keep)" +== 283 +-- truncate_limit: 100 +create index on idxpart (col_keep) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (col_keep)" +== 284 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (1000)" +== 285 +-- truncate_limit: 100 +select attrelid::regclass, attname, attnum from pg_attribute + where attrelid::regclass::text like 'idxpart%' and attnum > 0 + order by attrelid::regclass, attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE ... ORDER BY attrelid::regclass, attnum" +== 286 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 287 +-- truncate_limit: 100 +|-- +-- Constraint-related indexes +|-- + +-- Verify that it works to add primary key / unique to partitioned tables +create table idxpart (a int primary key, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int PRIMARY KEY, b int) PARTITION BY RANGE (a)" +== 288 +-- truncate_limit: 100 +-- multiple primary key on child should fail +create table failpart partition of idxpart (b primary key) for values from (0) to (100) +-- +TABLE: name="failpart" schema="" table="failpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE failpart PARTITION OF idxpart (b PRIMARY KEY) FOR VALUES FROM (0) TO (100)" +== 289 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 290 +-- truncate_limit: 100 +-- primary key on child is okay if there's no PK in the parent, though +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 291 +-- truncate_limit: 100 +create table idxpart1pk partition of idxpart (a primary key) for values from (0) to (100) +-- +TABLE: name="idxpart1pk" schema="" table="idxpart1pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1pk PARTITION OF idxpart (a PRIMARY KEY) FOR VALUES FROM (0) TO (100)" +== 292 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 293 +-- truncate_limit: 100 +-- Failing to use the full partition key is not allowed +create table idxpart (a int unique, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int UNIQUE, b int) PARTITION BY RANGE (a, b)" +== 294 +-- truncate_limit: 100 +create table idxpart (a int, b int unique) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int UNIQUE) PARTITION BY RANGE (a, b)" +== 295 +-- truncate_limit: 100 +create table idxpart (a int primary key, b int) partition by range (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int PRIMARY KEY, b int) PARTITION BY RANGE (b, a)" +== 296 +-- truncate_limit: 100 +create table idxpart (a int, b int primary key) partition by range (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int PRIMARY KEY) PARTITION BY RANGE (b, a)" +== 297 +-- truncate_limit: 100 +-- OK if you use them in some other order +create table idxpart (a int, b int, c text, primary key (a, b, c)) partition by range (b, c, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c text, PRIMARY KEY (a, b, c)) PARTITION BY RANGE (b, c, a)" +== 298 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 299 +-- truncate_limit: 100 +-- OK to add an exclusion constraint if partitioning by its equal column +create table idxpart (a int4range, exclude USING GIST (a with = )) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, EXCLUDE USING gist (a WITH =)) PARTITION BY RANGE (a)" +== 300 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 301 +-- truncate_limit: 100 +-- OK more than one equal column +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with =)) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, EXCLUDE USING gist (a WITH =, b WITH =)) PARTITIO..." +== 302 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 303 +-- truncate_limit: 100 +-- OK with more than one equal column: constraint is a proper superset of partition key +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with =)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, EXCLUDE USING gist (a WITH =, b WITH =)) PARTITIO..." +== 304 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 305 +-- truncate_limit: 100 +-- Not OK more than one equal column: partition keys are a proper superset of constraint +create table idxpart (a int4range, b int4range, exclude USING GIST (a with = )) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, EXCLUDE USING gist (a WITH =)) PARTITION BY RANGE..." +== 306 +-- truncate_limit: 100 +-- Not OK with just -|- +create table idxpart (a int4range, exclude USING GIST (a with -|- )) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, EXCLUDE USING gist (a WITH -|-)) PARTITION BY RANGE (a)" +== 307 +-- truncate_limit: 100 +-- OK with equals and &&, and equals is the partition key +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with &&)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, EXCLUDE USING gist (a WITH =, b WITH &&)) PARTITI..." +== 308 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 309 +-- truncate_limit: 100 +-- Not OK with equals and &&, and equals is not the partition key +create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (b with =, c with &&)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, c int4range, EXCLUDE USING gist (b WITH =, c WITH..." +== 310 +-- truncate_limit: 100 +-- OK more than one equal column and a && column +create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (a with =, b with =, c with &&)) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, c int4range, EXCLUDE USING gist (a WITH =, b WITH..." +== 311 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 312 +-- truncate_limit: 100 +-- no expressions in partition key for PK/UNIQUE +create table idxpart (a int primary key, b int) partition by range ((b + a)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int PRIMARY KEY, b int) PARTITION BY RANGE ((b + a))" +== 313 +-- truncate_limit: 100 +create table idxpart (a int unique, b int) partition by range ((b + a)) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int UNIQUE, b int) PARTITION BY RANGE ((b + a))" +== 314 +-- truncate_limit: 100 +-- use ALTER TABLE to add a primary key +create table idxpart (a int, b int, c text) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, c text) PARTITION BY RANGE (a, b)" +== 315 +-- truncate_limit: 100 +alter table idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD PRIMARY KEY (a)" +== 316 +-- truncate_limit: 100 +-- not an incomplete one though +alter table idxpart add primary key (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD PRIMARY KEY (a, b)" +== 317 +-- truncate_limit: 100 +-- this works +create table idxpart1 partition of idxpart for values from (0, 0) to (1000, 1000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0, 0) TO (1000, 1000)" +== 318 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 319 +-- truncate_limit: 100 +-- use ALTER TABLE to add a unique constraint +create table idxpart (a int, b int) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a, b)" +== 320 +-- truncate_limit: 100 +alter table idxpart add unique (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD UNIQUE (a)" +== 321 +-- truncate_limit: 100 +-- not an incomplete one though +alter table idxpart add unique (b, a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD UNIQUE (b, a)" +== 322 +-- truncate_limit: 100 +-- this works +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 323 +-- truncate_limit: 100 +-- Exclusion constraints can be added if partitioning by their equal column +create table idxpart (a int4range, b int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range) PARTITION BY RANGE (a)" +== 324 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (a with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (a WITH =)" +== 325 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 326 +-- truncate_limit: 100 +-- OK more than one equal column +create table idxpart (a int4range, b int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range) PARTITION BY RANGE (a, b)" +== 327 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (a with =, b with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (a WITH =, b WITH =)" +== 328 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 329 +-- truncate_limit: 100 +-- OK with more than one equal column: constraint is a proper superset of partition key +create table idxpart (a int4range, b int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range) PARTITION BY RANGE (a)" +== 330 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (a with =, b with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (a WITH =, b WITH =)" +== 331 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 332 +-- truncate_limit: 100 +-- Not OK more than one equal column: partition keys are a proper superset of constraint +create table idxpart (a int4range, b int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range) PARTITION BY RANGE (a, b)" +== 333 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (a with =) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (a WITH =)" +== 334 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 335 +-- truncate_limit: 100 +-- Not OK with just -|- +create table idxpart (a int4range, b int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range) PARTITION BY RANGE (a, b)" +== 336 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (a with -|-) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (a WITH -|-)" +== 337 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 338 +-- truncate_limit: 100 +-- OK with equals and &&, and equals is the partition key +create table idxpart (a int4range, b int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range) PARTITION BY RANGE (a)" +== 339 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (a with =, b with &&) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (a WITH =, b WITH &&)" +== 340 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 341 +-- truncate_limit: 100 +-- Not OK with equals and &&, and equals is not the partition key +create table idxpart (a int4range, b int4range, c int4range) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, c int4range) PARTITION BY RANGE (a)" +== 342 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (b with =, c with &&) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (b WITH =, c WITH &&)" +== 343 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 344 +-- truncate_limit: 100 +-- OK more than one equal column and a && column +create table idxpart (a int4range, b int4range, c int4range) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int4range, b int4range, c int4range) PARTITION BY RANGE (a, b)" +== 345 +-- truncate_limit: 100 +alter table idxpart add exclude USING GIST (a with =, b with =, c with &&) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD EXCLUDE USING gist (a WITH =, b WITH =, c WITH &&)" +== 346 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 347 +-- truncate_limit: 100 +-- When (sub)partitions are created, they also contain the constraint +create table idxpart (a int, b int, primary key (a, b)) partition by range (a, b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, PRIMARY KEY (a, b)) PARTITION BY RANGE (a, b)" +== 348 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (1, 1) to (10, 10) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (1, 1) TO (10, 10)" +== 349 +-- truncate_limit: 100 +create table idxpart2 partition of idxpart for values from (10, 10) to (20, 20) + partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 PARTITION OF idxpart FOR VALUES FROM (10, 10) TO (20, 20) PARTITION BY RANG..." +== 350 +-- truncate_limit: 100 +create table idxpart21 partition of idxpart2 for values from (10) to (15) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart21 PARTITION OF idxpart2 FOR VALUES FROM (10) TO (15)" +== 351 +-- truncate_limit: 100 +create table idxpart22 partition of idxpart2 for values from (15) to (20) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart22 PARTITION OF idxpart2 FOR VALUES FROM (15) TO (20)" +== 352 +-- truncate_limit: 100 +create table idxpart3 (b int not null, a int not null) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart3 (b int NOT NULL, a int NOT NULL)" +== 353 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart3 for values from (20, 20) to (30, 30) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart3 FOR VALUES FROM (20, 20) TO (30, 30)" +== 354 +-- truncate_limit: 100 +select conname, contype, conrelid::regclass, conindid::regclass, conkey + from pg_constraint where conrelid::regclass::text like 'idxpart%' + order by conrelid::regclass::text, conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE ... ORDER BY conrelid::regclass::text, conname" +== 355 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 356 +-- truncate_limit: 100 +-- Verify that multi-layer partitioning honors the requirement that all +-- columns in the partition key must appear in primary/unique key +create table idxpart (a int, b int, primary key (a)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, PRIMARY KEY (a)) PARTITION BY RANGE (a)" +== 357 +-- truncate_limit: 100 +create table idxpart2 partition of idxpart +for values from (0) to (1000) partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 PARTITION OF idxpart FOR VALUES FROM (0) TO (1000) PARTITION BY RANGE (b)" +== 358 +-- truncate_limit: 100 +-- fail +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 359 +-- truncate_limit: 100 +-- Ditto for the ATTACH PARTITION case +create table idxpart (a int unique, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int UNIQUE, b int) PARTITION BY RANGE (a)" +== 360 +-- truncate_limit: 100 +create table idxpart1 (a int not null, b int, unique (a, b)) + partition by range (a, b) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (a int NOT NULL, b int, UNIQUE (a, b)) PARTITION BY RANGE (a, b)" +== 361 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (1) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (1) TO (1000)" +== 362 +-- truncate_limit: 100 +DROP TABLE idxpart, idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart, idxpart1" +== 363 +-- truncate_limit: 100 +-- Multi-layer partitioning works correctly in this case: +create table idxpart (a int, b int, primary key (a, b)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, PRIMARY KEY (a, b)) PARTITION BY RANGE (a)" +== 364 +-- truncate_limit: 100 +create table idxpart2 partition of idxpart for values from (0) to (1000) partition by range (b) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 PARTITION OF idxpart FOR VALUES FROM (0) TO (1000) PARTITION BY RANGE (b)" +== 365 +-- truncate_limit: 100 +create table idxpart21 partition of idxpart2 for values from (0) to (1000) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart21 PARTITION OF idxpart2 FOR VALUES FROM (0) TO (1000)" +== 366 +-- truncate_limit: 100 +select conname, contype, conrelid::regclass, conindid::regclass, conkey + from pg_constraint where conrelid::regclass::text like 'idxpart%' + order by conname +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conrelid::regclass::text LIKE 'idxpart%' ORDER BY conname" +== 367 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 368 +-- truncate_limit: 100 +-- If a partitioned table has a unique/PK constraint, then it's not possible +-- to drop the corresponding constraint in the children; nor it's possible +-- to drop the indexes individually. Dropping the constraint in the parent +-- gets rid of the lot. +create table idxpart (i int) partition by hash (i) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (i int) PARTITION BY HASH (i)" +== 369 +-- truncate_limit: 100 +create table idxpart0 partition of idxpart (i) for values with (modulus 2, remainder 0) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart0 PARTITION OF idxpart (i) FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 370 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart (i) for values with (modulus 2, remainder 1) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart (i) FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 371 +-- truncate_limit: 100 +alter table idxpart0 add primary key(i) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart0 ADD PRIMARY KEY (i)" +== 372 +-- truncate_limit: 100 +alter table idxpart add primary key(i) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD PRIMARY KEY (i)" +== 373 +-- truncate_limit: 100 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid LEFT JOIN..." +== 374 +-- truncate_limit: 100 +drop index idxpart0_pkey +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart0_pkey" +== 375 +-- truncate_limit: 100 +-- fail +drop index idxpart1_pkey +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart1_pkey" +== 376 +-- truncate_limit: 100 +-- fail +alter table idxpart0 drop constraint idxpart0_pkey +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart0 DROP CONSTRAINT idxpart0_pkey" +== 377 +-- truncate_limit: 100 +-- fail +alter table idxpart1 drop constraint idxpart1_pkey +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 DROP CONSTRAINT idxpart1_pkey" +== 378 +-- truncate_limit: 100 +-- fail +alter table idxpart drop constraint idxpart_pkey +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart DROP CONSTRAINT idxpart_pkey" +== 379 +-- truncate_limit: 100 +-- ok +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid LEFT JOIN..." +== 380 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 381 +-- truncate_limit: 100 +-- If the partition to be attached already has a primary key, fail if +-- it doesn't match the parent's PK. +CREATE TABLE idxpart (c1 INT PRIMARY KEY, c2 INT, c3 VARCHAR(10)) PARTITION BY RANGE(c1) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (c1 int PRIMARY KEY, c2 int, c3 varchar(10)) PARTITION BY RANGE (c1)" +== 382 +-- truncate_limit: 100 +CREATE TABLE idxpart1 (LIKE idxpart) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (LIKE idxpart)" +== 383 +-- truncate_limit: 100 +ALTER TABLE idxpart1 ADD PRIMARY KEY (c1, c2) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 ADD PRIMARY KEY (c1, c2)" +== 384 +-- truncate_limit: 100 +ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (100) TO (200)" +== 385 +-- truncate_limit: 100 +DROP TABLE idxpart, idxpart1 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart, idxpart1" +== 386 +-- truncate_limit: 100 +-- Ditto if there is some distance between the PKs (subpartitioning) +create table idxpart (a int, b int, primary key (a)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int, PRIMARY KEY (a)) PARTITION BY RANGE (a)" +== 387 +-- truncate_limit: 100 +create table idxpart1 (a int not null, b int) partition by range (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (a int NOT NULL, b int) PARTITION BY RANGE (a)" +== 388 +-- truncate_limit: 100 +create table idxpart11 (a int not null, b int primary key) +-- +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart11 (a int NOT NULL, b int PRIMARY KEY)" +== 389 +-- truncate_limit: 100 +alter table idxpart1 attach partition idxpart11 for values from (0) to (1000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart1 ATTACH PARTITION idxpart11 FOR VALUES FROM (0) TO (1000)" +== 390 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (0) to (10000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (0) TO (10000)" +== 391 +-- truncate_limit: 100 +drop table idxpart, idxpart1, idxpart11 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +TABLE: name="idxpart11" schema="" table="idxpart11" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart, idxpart1, idxpart11" +== 392 +-- truncate_limit: 100 +-- If a partitioned table has a constraint whose index is not valid, +-- attaching a missing partition makes it valid. +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 393 +-- truncate_limit: 100 +create table idxpart0 (like idxpart) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart0 (LIKE idxpart)" +== 394 +-- truncate_limit: 100 +alter table idxpart0 add primary key (a) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart0 ADD PRIMARY KEY (a)" +== 395 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart0 for values from (0) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart0 FOR VALUES FROM (0) TO (1000)" +== 396 +-- truncate_limit: 100 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY idxpart ADD PRIMARY KEY (a)" +== 397 +-- truncate_limit: 100 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid LEFT JOIN..." +== 398 +-- truncate_limit: 100 +alter index idxpart_pkey attach partition idxpart0_pkey +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_pkey ATTACH PARTITION idxpart0_pkey" +== 399 +-- truncate_limit: 100 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid LEFT JOIN..." +== 400 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 401 +-- truncate_limit: 100 +-- Related to the above scenario: ADD PRIMARY KEY on the parent mustn't +-- automatically propagate NOT NULL to child columns. +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 402 +-- truncate_limit: 100 +create table idxpart0 (like idxpart) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart0 (LIKE idxpart)" +== 403 +-- truncate_limit: 100 +alter table idxpart0 add unique (a) +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart0 ADD UNIQUE (a)" +== 404 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart0 default +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart0 DEFAULT" +== 405 +-- truncate_limit: 100 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY idxpart ADD PRIMARY KEY (a)" +== 406 +-- truncate_limit: 100 +-- fail, no not-null constraint +alter table idxpart0 alter column a set not null +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart0 ALTER COLUMN a SET NOT NULL" +== 407 +-- truncate_limit: 100 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY idxpart ADD PRIMARY KEY (a)" +== 408 +-- truncate_limit: 100 +-- now it works +alter index idxpart_pkey attach partition idxpart0_a_key +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_pkey ATTACH PARTITION idxpart0_a_key" +== 409 +-- truncate_limit: 100 +alter table idxpart0 alter column a drop not null +-- +TABLE: name="idxpart0" schema="" table="idxpart0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart0 ALTER COLUMN a DROP NOT NULL" +== 410 +-- truncate_limit: 100 +-- fail, pkey needs it +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 411 +-- truncate_limit: 100 +-- if a partition has a unique index without a constraint, does not attach +-- automatically; creates a new index instead. +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a)" +== 412 +-- truncate_limit: 100 +create table idxpart1 (a int not null, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (a int NOT NULL, b int)" +== 413 +-- truncate_limit: 100 +create unique index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON idxpart1 USING btree (a)" +== 414 +-- truncate_limit: 100 +alter table idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ADD PRIMARY KEY (a)" +== 415 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (1) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (1) TO (1000)" +== 416 +-- truncate_limit: 100 +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "con"="pg_constraint" +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid LEFT JOIN..." +== 417 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 418 +-- truncate_limit: 100 +-- Can't attach an index without a corresponding constraint +create table idxpart (a int, b int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b int) PARTITION BY RANGE (a)" +== 419 +-- truncate_limit: 100 +create table idxpart1 (a int not null, b int) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 (a int NOT NULL, b int)" +== 420 +-- truncate_limit: 100 +create unique index on idxpart1 (a) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON idxpart1 USING btree (a)" +== 421 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart1 for values from (1) to (1000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (1) TO (1000)" +== 422 +-- truncate_limit: 100 +alter table only idxpart add primary key (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY idxpart ADD PRIMARY KEY (a)" +== 423 +-- truncate_limit: 100 +alter index idxpart_pkey attach partition idxpart1_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart_pkey ATTACH PARTITION idxpart1_a_idx" +== 424 +-- truncate_limit: 100 +-- fail +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 425 +-- truncate_limit: 100 +-- Test that unique constraints are working +create table idxpart (a int, b text, primary key (a, b)) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b text, PRIMARY KEY (a, b)) PARTITION BY RANGE (a)" +== 426 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (100000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (100000)" +== 427 +-- truncate_limit: 100 +create table idxpart2 (c int, like idxpart) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 (c int, LIKE idxpart)" +== 428 +-- truncate_limit: 100 +insert into idxpart2 (c, a, b) values (42, 572814, 'inserted first') +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart2 (c, a, b) VALUES (42, 572814, 'inserted first')" +== 429 +-- truncate_limit: 100 +alter table idxpart2 drop column c +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart2 DROP c" +== 430 +-- truncate_limit: 100 +create unique index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON idxpart USING btree (a)" +== 431 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart2 for values from (100000) to (1000000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart2 FOR VALUES FROM (100000) TO (1000000)" +== 432 +-- truncate_limit: 100 +insert into idxpart values (0, 'zero'), (42, 'life'), (2^16, 'sixteen') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart VALUES (0, 'zero'), (42, 'life'), (2 ^ 16, 'sixteen')" +== 433 +-- truncate_limit: 100 +insert into idxpart select 2^g, format('two to power of %s', g) from generate_series(15, 17) g +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart SELECT 2 ^ g, format('two to power of %s', g) FROM generate_series(15, 17) g" +== 434 +-- truncate_limit: 100 +insert into idxpart values (16, 'sixteen') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart VALUES (16, 'sixteen')" +== 435 +-- truncate_limit: 100 +insert into idxpart (b, a) values ('one', 142857), ('two', 285714) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart (b, a) VALUES ('one', 142857), ('two', 285714)" +== 436 +-- truncate_limit: 100 +insert into idxpart select a * 2, b || b from idxpart where a between 2^16 and 2^19 +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart SELECT a * 2, b || b FROM idxpart WHERE a BETWEEN 2 ^ 16 AND 2 ^ 19" +== 437 +-- truncate_limit: 100 +insert into idxpart values (572814, 'five') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart VALUES (572814, 'five')" +== 438 +-- truncate_limit: 100 +insert into idxpart values (857142, 'six') +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO idxpart VALUES (857142, 'six')" +== 439 +-- truncate_limit: 100 +select tableoid::regclass, * from idxpart order by a +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM idxpart ORDER BY a" +== 440 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 441 +-- truncate_limit: 100 +-- Test some other non-btree index types +create table idxpart (a int, b text, c int[]) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int, b text, c int[]) PARTITION BY RANGE (a)" +== 442 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (100000) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (100000)" +== 443 +-- truncate_limit: 100 +set enable_seqscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 444 +-- truncate_limit: 100 +create index idxpart_brin on idxpart using brin(b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_brin ON idxpart USING brin (b)" +== 445 +-- truncate_limit: 100 +explain (costs off) select * from idxpart where b = 'abcd' +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM idxpart WHERE b = 'abcd'" +== 446 +-- truncate_limit: 100 +drop index idxpart_brin +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_brin" +== 447 +-- truncate_limit: 100 +create index idxpart_spgist on idxpart using spgist(b) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_spgist ON idxpart USING spgist (b)" +== 448 +-- truncate_limit: 100 +explain (costs off) select * from idxpart where b = 'abcd' +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM idxpart WHERE b = 'abcd'" +== 449 +-- truncate_limit: 100 +drop index idxpart_spgist +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_spgist" +== 450 +-- truncate_limit: 100 +create index idxpart_gin on idxpart using gin(c) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX idxpart_gin ON idxpart USING gin (c)" +== 451 +-- truncate_limit: 100 +explain (costs off) select * from idxpart where c @> array[42] +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=Select +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM idxpart WHERE c @> ARRAY[42]" +== 452 +-- truncate_limit: 100 +drop index idxpart_gin +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX idxpart_gin" +== 453 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 454 +-- truncate_limit: 100 +drop table idxpart +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE idxpart" +== 455 +-- truncate_limit: 100 +-- intentionally leave some objects around +create table idxpart (a int) partition by range (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart (a int) PARTITION BY RANGE (a)" +== 456 +-- truncate_limit: 100 +create table idxpart1 partition of idxpart for values from (0) to (100) +-- +TABLE: name="idxpart1" schema="" table="idxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (0) TO (100)" +== 457 +-- truncate_limit: 100 +create table idxpart2 partition of idxpart for values from (100) to (1000) + partition by range (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart2 PARTITION OF idxpart FOR VALUES FROM (100) TO (1000) PARTITION BY RANGE (a)" +== 458 +-- truncate_limit: 100 +create table idxpart21 partition of idxpart2 for values from (100) to (200) +-- +TABLE: name="idxpart21" schema="" table="idxpart21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart21 PARTITION OF idxpart2 FOR VALUES FROM (100) TO (200)" +== 459 +-- truncate_limit: 100 +create table idxpart22 partition of idxpart2 for values from (200) to (300) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart22 PARTITION OF idxpart2 FOR VALUES FROM (200) TO (300)" +== 460 +-- truncate_limit: 100 +create index on idxpart22 (a) +-- +TABLE: name="idxpart22" schema="" table="idxpart22" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart22 USING btree (a)" +== 461 +-- truncate_limit: 100 +create index on only idxpart2 (a) +-- +TABLE: name="idxpart2" schema="" table="idxpart2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON ONLY idxpart2 USING btree (a)" +== 462 +-- truncate_limit: 100 +alter index idxpart2_a_idx attach partition idxpart22_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX idxpart2_a_idx ATTACH PARTITION idxpart22_a_idx" +== 463 +-- truncate_limit: 100 +create index on idxpart (a) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON idxpart USING btree (a)" +== 464 +-- truncate_limit: 100 +create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a) +-- +TABLE: name="idxpart_another" schema="" table="idxpart_another" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart_another (a int, b int, PRIMARY KEY (a, b)) PARTITION BY RANGE (a)" +== 465 +-- truncate_limit: 100 +create table idxpart_another_1 partition of idxpart_another for values from (0) to (100) +-- +TABLE: name="idxpart_another_1" schema="" table="idxpart_another_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart_another_1 PARTITION OF idxpart_another FOR VALUES FROM (0) TO (100)" +== 466 +-- truncate_limit: 100 +create table idxpart3 (c int, b int, a int) partition by range (a) +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart3 (c int, b int, a int) PARTITION BY RANGE (a)" +== 467 +-- truncate_limit: 100 +alter table idxpart3 drop column b, drop column c +-- +TABLE: name="idxpart3" schema="" table="idxpart3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart3 DROP b, DROP c" +== 468 +-- truncate_limit: 100 +create table idxpart31 partition of idxpart3 for values from (1000) to (1200) +-- +TABLE: name="idxpart31" schema="" table="idxpart31" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart31 PARTITION OF idxpart3 FOR VALUES FROM (1000) TO (1200)" +== 469 +-- truncate_limit: 100 +create table idxpart32 partition of idxpart3 for values from (1200) to (1400) +-- +TABLE: name="idxpart32" schema="" table="idxpart32" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE idxpart32 PARTITION OF idxpart3 FOR VALUES FROM (1200) TO (1400)" +== 470 +-- truncate_limit: 100 +alter table idxpart attach partition idxpart3 for values from (1000) to (2000) +-- +TABLE: name="idxpart" schema="" table="idxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE idxpart ATTACH PARTITION idxpart3 FOR VALUES FROM (1000) TO (2000)" +== 471 +-- truncate_limit: 100 +-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade +-- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql +create schema regress_indexing +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_indexing" +== 472 +-- truncate_limit: 100 +set search_path to regress_indexing +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO regress_indexing" +== 473 +-- truncate_limit: 100 +create table pk (a int primary key) partition by range (a) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 474 +-- truncate_limit: 100 +create table pk1 partition of pk for values from (0) to (1000) +-- +TABLE: name="pk1" schema="" table="pk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (0) TO (1000)" +== 475 +-- truncate_limit: 100 +create table pk2 (b int, a int) +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk2 (b int, a int)" +== 476 +-- truncate_limit: 100 +alter table pk2 drop column b +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk2 DROP b" +== 477 +-- truncate_limit: 100 +alter table pk2 alter a set not null +-- +TABLE: name="pk2" schema="" table="pk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk2 ALTER COLUMN a SET NOT NULL" +== 478 +-- truncate_limit: 100 +alter table pk attach partition pk2 for values from (1000) to (2000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk ATTACH PARTITION pk2 FOR VALUES FROM (1000) TO (2000)" +== 479 +-- truncate_limit: 100 +create table pk3 partition of pk for values from (2000) to (3000) +-- +TABLE: name="pk3" schema="" table="pk3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk3 PARTITION OF pk FOR VALUES FROM (2000) TO (3000)" +== 480 +-- truncate_limit: 100 +create table pk4 (like pk) +-- +TABLE: name="pk4" schema="" table="pk4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk4 (LIKE pk)" +== 481 +-- truncate_limit: 100 +alter table pk attach partition pk4 for values from (3000) to (4000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk ATTACH PARTITION pk4 FOR VALUES FROM (3000) TO (4000)" +== 482 +-- truncate_limit: 100 +create table pk5 (like pk) partition by range (a) +-- +TABLE: name="pk5" schema="" table="pk5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk5 (LIKE pk) PARTITION BY RANGE (a)" +== 483 +-- truncate_limit: 100 +create table pk51 partition of pk5 for values from (4000) to (4500) +-- +TABLE: name="pk51" schema="" table="pk51" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk51 PARTITION OF pk5 FOR VALUES FROM (4000) TO (4500)" +== 484 +-- truncate_limit: 100 +create table pk52 partition of pk5 for values from (4500) to (5000) +-- +TABLE: name="pk52" schema="" table="pk52" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pk52 PARTITION OF pk5 FOR VALUES FROM (4500) TO (5000)" +== 485 +-- truncate_limit: 100 +alter table pk attach partition pk5 for values from (4000) to (5000) +-- +TABLE: name="pk" schema="" table="pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pk ATTACH PARTITION pk5 FOR VALUES FROM (4000) TO (5000)" +== 486 +-- truncate_limit: 100 +reset search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 487 +-- truncate_limit: 100 +-- Test that covering partitioned indexes work in various cases +create table covidxpart (a int, b int) partition by list (a) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE covidxpart (a int, b int) PARTITION BY LIST (a)" +== 488 +-- truncate_limit: 100 +create unique index on covidxpart (a) include (b) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON covidxpart USING btree (a) INCLUDE (b)" +== 489 +-- truncate_limit: 100 +create table covidxpart1 partition of covidxpart for values in (1) +-- +TABLE: name="covidxpart1" schema="" table="covidxpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE covidxpart1 PARTITION OF covidxpart FOR VALUES IN (1)" +== 490 +-- truncate_limit: 100 +create table covidxpart2 partition of covidxpart for values in (2) +-- +TABLE: name="covidxpart2" schema="" table="covidxpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE covidxpart2 PARTITION OF covidxpart FOR VALUES IN (2)" +== 491 +-- truncate_limit: 100 +insert into covidxpart values (1, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covidxpart VALUES (1, 1)" +== 492 +-- truncate_limit: 100 +insert into covidxpart values (1, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covidxpart VALUES (1, 1)" +== 493 +-- truncate_limit: 100 +create table covidxpart3 (b int, c int, a int) +-- +TABLE: name="covidxpart3" schema="" table="covidxpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE covidxpart3 (b int, c int, a int)" +== 494 +-- truncate_limit: 100 +alter table covidxpart3 drop c +-- +TABLE: name="covidxpart3" schema="" table="covidxpart3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE covidxpart3 DROP c" +== 495 +-- truncate_limit: 100 +alter table covidxpart attach partition covidxpart3 for values in (3) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE covidxpart ATTACH PARTITION covidxpart3 FOR VALUES IN (3)" +== 496 +-- truncate_limit: 100 +insert into covidxpart values (3, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covidxpart VALUES (3, 1)" +== 497 +-- truncate_limit: 100 +insert into covidxpart values (3, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covidxpart VALUES (3, 1)" +== 498 +-- truncate_limit: 100 +create table covidxpart4 (b int, a int) +-- +TABLE: name="covidxpart4" schema="" table="covidxpart4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE covidxpart4 (b int, a int)" +== 499 +-- truncate_limit: 100 +create unique index on covidxpart4 (a) include (b) +-- +TABLE: name="covidxpart4" schema="" table="covidxpart4" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON covidxpart4 USING btree (a) INCLUDE (b)" +== 500 +-- truncate_limit: 100 +create unique index on covidxpart4 (a) +-- +TABLE: name="covidxpart4" schema="" table="covidxpart4" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON covidxpart4 USING btree (a)" +== 501 +-- truncate_limit: 100 +alter table covidxpart attach partition covidxpart4 for values in (4) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE covidxpart ATTACH PARTITION covidxpart4 FOR VALUES IN (4)" +== 502 +-- truncate_limit: 100 +insert into covidxpart values (4, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covidxpart VALUES (4, 1)" +== 503 +-- truncate_limit: 100 +insert into covidxpart values (4, 1) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO covidxpart VALUES (4, 1)" +== 504 +-- truncate_limit: 100 +create unique index on covidxpart (b) include (a) +-- +TABLE: name="covidxpart" schema="" table="covidxpart" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON covidxpart USING btree (b) INCLUDE (a)" +== 505 +-- truncate_limit: 100 +-- should fail + +-- check that detaching a partition also detaches the primary key constraint +create table parted_pk_detach_test (a int primary key) partition by list (a) +-- +TABLE: name="parted_pk_detach_test" schema="" table="parted_pk_detach_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_pk_detach_test (a int PRIMARY KEY) PARTITION BY LIST (a)" +== 506 +-- truncate_limit: 100 +create table parted_pk_detach_test1 partition of parted_pk_detach_test for values in (1) +-- +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_pk_detach_test1 PARTITION OF parted_pk_detach_test FOR VALUES IN (1)" +== 507 +-- truncate_limit: 100 +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey +-- +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_pk_detach_test1 DROP CONSTRAINT parted_pk_detach_test1_pkey" +== 508 +-- truncate_limit: 100 +-- should fail +alter table parted_pk_detach_test detach partition parted_pk_detach_test1 +-- +TABLE: name="parted_pk_detach_test" schema="" table="parted_pk_detach_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_pk_detach_test DETACH PARTITION parted_pk_detach_test1" +== 509 +-- truncate_limit: 100 +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey +-- +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_pk_detach_test1 DROP CONSTRAINT parted_pk_detach_test1_pkey" +== 510 +-- truncate_limit: 100 +drop table parted_pk_detach_test, parted_pk_detach_test1 +-- +TABLE: name="parted_pk_detach_test" schema="" table="parted_pk_detach_test" ctx=DDL +TABLE: name="parted_pk_detach_test1" schema="" table="parted_pk_detach_test1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_pk_detach_test, parted_pk_detach_test1" +== 511 +-- truncate_limit: 100 +create table parted_uniq_detach_test (a int unique) partition by list (a) +-- +TABLE: name="parted_uniq_detach_test" schema="" table="parted_uniq_detach_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_uniq_detach_test (a int UNIQUE) PARTITION BY LIST (a)" +== 512 +-- truncate_limit: 100 +create table parted_uniq_detach_test1 partition of parted_uniq_detach_test for values in (1) +-- +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_uniq_detach_test1 PARTITION OF parted_uniq_detach_test FOR VALUES IN (1)" +== 513 +-- truncate_limit: 100 +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key +-- +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_uniq_detach_test1 DROP CONSTRAINT parted_uniq_detach_test1_a_key" +== 514 +-- truncate_limit: 100 +-- should fail +alter table parted_uniq_detach_test detach partition parted_uniq_detach_test1 +-- +TABLE: name="parted_uniq_detach_test" schema="" table="parted_uniq_detach_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_uniq_detach_test DETACH PARTITION parted_uniq_detach_test1" +== 515 +-- truncate_limit: 100 +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key +-- +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_uniq_detach_test1 DROP CONSTRAINT parted_uniq_detach_test1_a_key" +== 516 +-- truncate_limit: 100 +drop table parted_uniq_detach_test, parted_uniq_detach_test1 +-- +TABLE: name="parted_uniq_detach_test" schema="" table="parted_uniq_detach_test" ctx=DDL +TABLE: name="parted_uniq_detach_test1" schema="" table="parted_uniq_detach_test1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_uniq_detach_test, parted_uniq_detach_test1" +== 517 +-- truncate_limit: 100 +-- check that dropping a column takes with it any partitioned indexes +-- depending on it. +create table parted_index_col_drop(a int, b int, c int) + partition by list (a) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_index_col_drop (a int, b int, c int) PARTITION BY LIST (a)" +== 518 +-- truncate_limit: 100 +create table parted_index_col_drop1 partition of parted_index_col_drop + for values in (1) partition by list (a) +-- +TABLE: name="parted_index_col_drop1" schema="" table="parted_index_col_drop1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_index_col_drop1 PARTITION OF parted_index_col_drop FOR VALUES IN (1) PARTITIO..." +== 519 +-- truncate_limit: 100 +-- leave this partition without children. +create table parted_index_col_drop2 partition of parted_index_col_drop + for values in (2) partition by list (a) +-- +TABLE: name="parted_index_col_drop2" schema="" table="parted_index_col_drop2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_index_col_drop2 PARTITION OF parted_index_col_drop FOR VALUES IN (2) PARTITIO..." +== 520 +-- truncate_limit: 100 +create table parted_index_col_drop11 partition of parted_index_col_drop1 + for values in (1) +-- +TABLE: name="parted_index_col_drop11" schema="" table="parted_index_col_drop11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_index_col_drop11 PARTITION OF parted_index_col_drop1 FOR VALUES IN (1)" +== 521 +-- truncate_limit: 100 +create index on parted_index_col_drop (b) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON parted_index_col_drop USING btree (b)" +== 522 +-- truncate_limit: 100 +create index on parted_index_col_drop (c) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON parted_index_col_drop USING btree (c)" +== 523 +-- truncate_limit: 100 +create index on parted_index_col_drop (b, c) +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON parted_index_col_drop USING btree (b, c)" +== 524 +-- truncate_limit: 100 +alter table parted_index_col_drop drop column c +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_index_col_drop DROP c" +== 525 +-- truncate_limit: 100 +drop table parted_index_col_drop +-- +TABLE: name="parted_index_col_drop" schema="" table="parted_index_col_drop" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_index_col_drop" +== 526 +-- truncate_limit: 100 +-- Check that invalid indexes are not selected when attaching a partition. +create table parted_inval_tab (a int) partition by range (a) +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_inval_tab (a int) PARTITION BY RANGE (a)" +== 527 +-- truncate_limit: 100 +create index parted_inval_idx on parted_inval_tab (a) +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX parted_inval_idx ON parted_inval_tab USING btree (a)" +== 528 +-- truncate_limit: 100 +create table parted_inval_tab_1 (a int) partition by range (a) +-- +TABLE: name="parted_inval_tab_1" schema="" table="parted_inval_tab_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_inval_tab_1 (a int) PARTITION BY RANGE (a)" +== 529 +-- truncate_limit: 100 +create table parted_inval_tab_1_1 partition of parted_inval_tab_1 + for values from (0) to (10) +-- +TABLE: name="parted_inval_tab_1_1" schema="" table="parted_inval_tab_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_inval_tab_1_1 PARTITION OF parted_inval_tab_1 FOR VALUES FROM (0) TO (10)" +== 530 +-- truncate_limit: 100 +create table parted_inval_tab_1_2 partition of parted_inval_tab_1 + for values from (10) to (20) +-- +TABLE: name="parted_inval_tab_1_2" schema="" table="parted_inval_tab_1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_inval_tab_1_2 PARTITION OF parted_inval_tab_1 FOR VALUES FROM (10) TO (20)" +== 531 +-- truncate_limit: 100 +-- this creates an invalid index. +create index parted_inval_ixd_1 on only parted_inval_tab_1 (a) +-- +TABLE: name="parted_inval_tab_1" schema="" table="parted_inval_tab_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX parted_inval_ixd_1 ON ONLY parted_inval_tab_1 USING btree (a)" +== 532 +-- truncate_limit: 100 +-- this creates new indexes for all the partitions of parted_inval_tab_1, +-- discarding the invalid index created previously as what is chosen. +alter table parted_inval_tab attach partition parted_inval_tab_1 + for values from (1) to (100) +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_inval_tab ATTACH PARTITION parted_inval_tab_1 FOR VALUES FROM (1) TO (100)" +== 533 +-- truncate_limit: 100 +select indexrelid::regclass, indisvalid, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_inval%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid WHERE ......" +== 534 +-- truncate_limit: 100 +drop table parted_inval_tab +-- +TABLE: name="parted_inval_tab" schema="" table="parted_inval_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_inval_tab" +== 535 +-- truncate_limit: 100 +-- Check setup of indisvalid across a complex partition tree on index +-- creation. If one index in a partition index is invalid, so should its +-- partitioned index. +create table parted_isvalid_tab (a int, b int) partition by range (a) +-- +TABLE: name="parted_isvalid_tab" schema="" table="parted_isvalid_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_isvalid_tab (a int, b int) PARTITION BY RANGE (a)" +== 536 +-- truncate_limit: 100 +create table parted_isvalid_tab_1 partition of parted_isvalid_tab + for values from (1) to (10) partition by range (a) +-- +TABLE: name="parted_isvalid_tab_1" schema="" table="parted_isvalid_tab_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_isvalid_tab_1 PARTITION OF parted_isvalid_tab FOR VALUES FROM (1) TO (10) PAR..." +== 537 +-- truncate_limit: 100 +create table parted_isvalid_tab_2 partition of parted_isvalid_tab + for values from (10) to (20) partition by range (a) +-- +TABLE: name="parted_isvalid_tab_2" schema="" table="parted_isvalid_tab_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_isvalid_tab_2 PARTITION OF parted_isvalid_tab FOR VALUES FROM (10) TO (20) PA..." +== 538 +-- truncate_limit: 100 +create table parted_isvalid_tab_11 partition of parted_isvalid_tab_1 + for values from (1) to (5) +-- +TABLE: name="parted_isvalid_tab_11" schema="" table="parted_isvalid_tab_11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_isvalid_tab_11 PARTITION OF parted_isvalid_tab_1 FOR VALUES FROM (1) TO (5)" +== 539 +-- truncate_limit: 100 +create table parted_isvalid_tab_12 partition of parted_isvalid_tab_1 + for values from (5) to (10) +-- +TABLE: name="parted_isvalid_tab_12" schema="" table="parted_isvalid_tab_12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_isvalid_tab_12 PARTITION OF parted_isvalid_tab_1 FOR VALUES FROM (5) TO (10)" +== 540 +-- truncate_limit: 100 +-- create an invalid index on one of the partitions. +insert into parted_isvalid_tab_11 values (1, 0) +-- +TABLE: name="parted_isvalid_tab_11" schema="" table="parted_isvalid_tab_11" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_isvalid_tab_11 VALUES (1, 0)" +== 541 +-- truncate_limit: 100 +create index concurrently parted_isvalid_idx_11 on parted_isvalid_tab_11 ((a/b)) +-- +TABLE: name="parted_isvalid_tab_11" schema="" table="parted_isvalid_tab_11" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX CONCURRENTLY parted_isvalid_idx_11 ON parted_isvalid_tab_11 USING btree ((a / b))" +== 542 +-- truncate_limit: 100 +-- The previous invalid index is selected, invalidating all the indexes up to +-- the top-most parent. +create index parted_isvalid_idx on parted_isvalid_tab ((a/b)) +-- +TABLE: name="parted_isvalid_tab" schema="" table="parted_isvalid_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX parted_isvalid_idx ON parted_isvalid_tab USING btree ((a / b))" +== 543 +-- truncate_limit: 100 +select indexrelid::regclass, indisvalid, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_isvalid%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid WHERE ......" +== 544 +-- truncate_limit: 100 +drop table parted_isvalid_tab +-- +TABLE: name="parted_isvalid_tab" schema="" table="parted_isvalid_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_isvalid_tab" +== 545 +-- truncate_limit: 100 +-- Check state of replica indexes when attaching a partition. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 546 +-- truncate_limit: 100 +create table parted_replica_tab (id int not null) partition by range (id) +-- +TABLE: name="parted_replica_tab" schema="" table="parted_replica_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_replica_tab (id int NOT NULL) PARTITION BY RANGE (id)" +== 547 +-- truncate_limit: 100 +create table parted_replica_tab_1 partition of parted_replica_tab + for values from (1) to (10) partition by range (id) +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_replica_tab_1 PARTITION OF parted_replica_tab FOR VALUES FROM (1) TO (10) PAR..." +== 548 +-- truncate_limit: 100 +create table parted_replica_tab_11 partition of parted_replica_tab_1 + for values from (1) to (5) +-- +TABLE: name="parted_replica_tab_11" schema="" table="parted_replica_tab_11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_replica_tab_11 PARTITION OF parted_replica_tab_1 FOR VALUES FROM (1) TO (5)" +== 549 +-- truncate_limit: 100 +create unique index parted_replica_idx + on only parted_replica_tab using btree (id) +-- +TABLE: name="parted_replica_tab" schema="" table="parted_replica_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX parted_replica_idx ON ONLY parted_replica_tab USING btree (id)" +== 550 +-- truncate_limit: 100 +create unique index parted_replica_idx_1 + on only parted_replica_tab_1 using btree (id) +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX parted_replica_idx_1 ON ONLY parted_replica_tab_1 USING btree (id)" +== 551 +-- truncate_limit: 100 +-- This triggers an update of pg_index.indisreplident for parted_replica_idx. +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1 +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parted_replica_tab_1 REPLICA IDENTITY USING INDEX parted_replica_idx_1" +== 552 +-- truncate_limit: 100 +create unique index parted_replica_idx_11 on parted_replica_tab_11 USING btree (id) +-- +TABLE: name="parted_replica_tab_11" schema="" table="parted_replica_tab_11" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX parted_replica_idx_11 ON parted_replica_tab_11 USING btree (id)" +== 553 +-- truncate_limit: 100 +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid WHERE ......" +== 554 +-- truncate_limit: 100 +-- parted_replica_idx is not valid yet here, because parted_replica_idx_1 +-- is not valid. +alter index parted_replica_idx ATTACH PARTITION parted_replica_idx_1 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX parted_replica_idx ATTACH PARTITION parted_replica_idx_1" +== 555 +-- truncate_limit: 100 +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid WHERE ......" +== 556 +-- truncate_limit: 100 +-- parted_replica_idx becomes valid here. +alter index parted_replica_idx_1 ATTACH PARTITION parted_replica_idx_11 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX parted_replica_idx_1 ATTACH PARTITION parted_replica_idx_11" +== 557 +-- truncate_limit: 100 +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1 +-- +TABLE: name="parted_replica_tab_1" schema="" table="parted_replica_tab_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parted_replica_tab_1 REPLICA IDENTITY USING INDEX parted_replica_idx_1" +== 558 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 559 +-- truncate_limit: 100 +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C" +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "idx"="pg_index" +ALIAS: "inh"="pg_inherits" +FILTER: schema="" table="" column="indexrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_index idx LEFT JOIN pg_inherits inh ON idx.indexrelid = inh.inhrelid WHERE ......" +== 560 +-- truncate_limit: 100 +drop table parted_replica_tab +-- +TABLE: name="parted_replica_tab" schema="" table="parted_replica_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_replica_tab" diff --git a/parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json b/parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/indirect_toast.test b/parser/testdata/summary_truncate/postgres_regress/indirect_toast.test new file mode 100644 index 0000000..515743c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/indirect_toast.test @@ -0,0 +1,253 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for external toast datums +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION make_tuple_indirect (record) + RETURNS record + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 198 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +-- Other compression algorithms may cause the compressed data to be stored +-- inline. pglz guarantees that the data is externalized, so stick to it. +SET default_toast_compression = 'pglz' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_toast_compression TO pglz" +== 003 +-- truncate_limit: 100 +CREATE TABLE indtoasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE indtoasttest (descr text, cnt int DEFAULT 0, f1 text, f2 text)" +== 004 +-- truncate_limit: 100 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO indtoasttest (descr, f1, f2) VALUES (...)" +== 005 +-- truncate_limit: 100 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO indtoasttest (descr, f1, f2) VALUES (...)" +== 006 +-- truncate_limit: 100 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO indtoasttest (descr, f1, f2) VALUES (...)" +== 007 +-- truncate_limit: 100 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000)) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO indtoasttest (descr, f1, f2) VALUES (...)" +== 008 +-- truncate_limit: 100 +-- check whether indirect tuples works on the most basic level +SELECT descr, substring(make_tuple_indirect(indtoasttest)::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +FUNCTION: name="make_tuple_indirect" function="make_tuple_indirect" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT descr, \"substring\"(make_tuple_indirect(indtoasttest)::text, 1, 200) FROM indtoasttest" +== 009 +-- truncate_limit: 100 +-- modification without changing varlenas +UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET cnt = cnt + 1 RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 010 +-- truncate_limit: 100 +-- modification without modifying assigned value +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET cnt = cnt + 1, f1 = f1 RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 011 +-- truncate_limit: 100 +-- modification modifying, but effectively not changing +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET ... = ... RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 012 +-- truncate_limit: 100 +UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET ... = ... RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 013 +-- truncate_limit: 100 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT \"substring\"(indtoasttest::text, 1, 200) FROM indtoasttest" +== 014 +-- truncate_limit: 100 +-- check we didn't screw with main/toast tuple visibility +VACUUM FREEZE indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FREEZE) indtoasttest" +== 015 +-- truncate_limit: 100 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT \"substring\"(indtoasttest::text, 1, 200) FROM indtoasttest" +== 016 +-- truncate_limit: 100 +-- now create a trigger that forces all Datums to be indirect ones +CREATE FUNCTION update_using_indirect() + RETURNS trigger + LANGUAGE plpgsql AS $$ +BEGIN + NEW := make_tuple_indirect(NEW); + RETURN NEW; +END$$ +-- +FUNCTION: name="update_using_indirect" function="update_using_indirect" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION update_using_indirect() RETURNS trigger LANGUAGE plpgsql AS $$\nBEGIN\n NEW := m..." +== 017 +-- truncate_limit: 100 +CREATE TRIGGER indtoasttest_update_indirect + BEFORE INSERT OR UPDATE + ON indtoasttest + FOR EACH ROW + EXECUTE PROCEDURE update_using_indirect() +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER indtoasttest_update_indirect BEFORE INSERT OR UPDATE ON indtoasttest FOR EACH ROW ..." +== 018 +-- truncate_limit: 100 +-- modification without changing varlenas +UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET cnt = cnt + 1 RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 019 +-- truncate_limit: 100 +-- modification without modifying assigned value +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET cnt = cnt + 1, f1 = f1 RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 020 +-- truncate_limit: 100 +-- modification modifying, but effectively not changing +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET ... = ... RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 021 +-- truncate_limit: 100 +UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE indtoasttest SET ... = ... RETURNING \"substring\"(indtoasttest::text, 1, 200)" +== 022 +-- truncate_limit: 100 +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL) +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO indtoasttest (descr, f1, f2) VALUES (...)" +== 023 +-- truncate_limit: 100 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT \"substring\"(indtoasttest::text, 1, 200) FROM indtoasttest" +== 024 +-- truncate_limit: 100 +-- check we didn't screw with main/toast tuple visibility +VACUUM FREEZE indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FREEZE) indtoasttest" +== 025 +-- truncate_limit: 100 +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=Select +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT \"substring\"(indtoasttest::text, 1, 200) FROM indtoasttest" +== 026 +-- truncate_limit: 100 +DROP TABLE indtoasttest +-- +TABLE: name="indtoasttest" schema="" table="indtoasttest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE indtoasttest" +== 027 +-- truncate_limit: 100 +DROP FUNCTION update_using_indirect() +-- +FUNCTION: name="update_using_indirect" function="update_using_indirect" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION update_using_indirect()" +== 028 +-- truncate_limit: 100 +RESET default_toast_compression +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_toast_compression" diff --git a/parser/testdata/summary_truncate/postgres_regress/inet.metadata.json b/parser/testdata/summary_truncate/postgres_regress/inet.metadata.json new file mode 100644 index 0000000..1211f6e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/inet.metadata.json @@ -0,0 +1,115 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/inet.test b/parser/testdata/summary_truncate/postgres_regress/inet.test new file mode 100644 index 0000000..5b07607 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/inet.test @@ -0,0 +1,981 @@ +== 001 +-- truncate_limit: 100 +|-- +-- INET +|-- + +-- prepare the table... + +DROP TABLE INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inet_tbl" +== 002 +-- truncate_limit: 100 +CREATE TABLE INET_TBL (c cidr, i inet) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inet_tbl (c cidr, i inet)" +== 003 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.226/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('192.168.1', '192.168.1.226/24')" +== 004 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.0/26', '192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('192.168.1.0/26', '192.168.1.226')" +== 005 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.0/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('192.168.1', '192.168.1.0/24')" +== 006 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.0/25') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('192.168.1', '192.168.1.0/25')" +== 007 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.255/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('192.168.1', '192.168.1.255/24')" +== 008 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.255/25') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('192.168.1', '192.168.1.255/25')" +== 009 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10', '10.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10', '10.1.2.3/8')" +== 010 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10.0.0.0', '10.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10.0.0.0', '10.1.2.3/8')" +== 011 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10.1.2.3', '10.1.2.3/32') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10.1.2.3', '10.1.2.3/32')" +== 012 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10.1.2', '10.1.2.3/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10.1.2', '10.1.2.3/24')" +== 013 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10.1', '10.1.2.3/16') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10.1', '10.1.2.3/16')" +== 014 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10', '10.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10', '10.1.2.3/8')" +== 015 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10', '11.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10', '11.1.2.3/8')" +== 016 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10', '9.1.2.3/8')" +== 017 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10:23::f1', '10:23::f1/64') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10:23::f1', '10:23::f1/64')" +== 018 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('10:23::8000/113', '10:23::ffff') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10:23::8000/113', '10:23::ffff')" +== 019 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('::ffff:1.2.3.4', '::4.3.2.1/24') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('::ffff:1.2.3.4', '::4.3.2.1/24')" +== 020 +-- truncate_limit: 100 +-- check that CIDR rejects invalid input: +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/30', '192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('192.168.1.2/30', '192.168.1.226')" +== 021 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES ('1234::1234::1234', '::1.2.3.4') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('1234::1234::1234', '::1.2.3.4')" +== 022 +-- truncate_limit: 100 +-- check that CIDR rejects invalid input when converting from text: +INSERT INTO INET_TBL (c, i) VALUES (cidr('192.168.1.2/30'), '192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +FUNCTION: name="cidr" function="cidr" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES (cidr('192.168.1.2/30'), '192.168.1.226')" +== 023 +-- truncate_limit: 100 +INSERT INTO INET_TBL (c, i) VALUES (cidr('ffff:ffff:ffff:ffff::/24'), '::192.168.1.226') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +FUNCTION: name="cidr" function="cidr" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES (cidr('ffff:ffff:ffff:ffff::/24'), '::192.168.1.226')" +== 024 +-- truncate_limit: 100 +SELECT c AS cidr, i AS inet FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT c AS cidr, i AS inet FROM inet_tbl" +== 025 +-- truncate_limit: 100 +-- now test some support functions + +SELECT i AS inet, host(i), text(i), family(i) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="host" function="host" schema="" ctx=Call +FUNCTION: name="text" function="text" schema="" ctx=Call +FUNCTION: name="family" function="family" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i AS inet, host(i), text(i), family(i) FROM inet_tbl" +== 026 +-- truncate_limit: 100 +SELECT c AS cidr, abbrev(c) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="abbrev" function="abbrev" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c AS cidr, abbrev(c) FROM inet_tbl" +== 027 +-- truncate_limit: 100 +SELECT c AS cidr, broadcast(c), + i AS inet, broadcast(i) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="broadcast" function="broadcast" schema="" ctx=Call +FUNCTION: name="broadcast" function="broadcast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c AS cidr, broadcast(c), i AS inet, broadcast(i) FROM inet_tbl" +== 028 +-- truncate_limit: 100 +SELECT c AS cidr, network(c) AS "network(cidr)", + i AS inet, network(i) AS "network(inet)" FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="network" function="network" schema="" ctx=Call +FUNCTION: name="network" function="network" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM inet_tbl" +== 029 +-- truncate_limit: 100 +SELECT c AS cidr, masklen(c) AS "masklen(cidr)", + i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM inet_tbl" +== 030 +-- truncate_limit: 100 +SELECT c AS cidr, masklen(c) AS "masklen(cidr)", + i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL + WHERE masklen(c) <= 8 +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FUNCTION: name="masklen" function="masklen" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM inet_tbl WHERE masklen(c) <= 8" +== 031 +-- truncate_limit: 100 +SELECT c AS cidr, i AS inet FROM INET_TBL + WHERE c = i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT c AS cidr, i AS inet FROM inet_tbl WHERE c = i" +== 032 +-- truncate_limit: 100 +SELECT i, c, + i < c AS lt, i <= c AS le, i = c AS eq, + i >= c AS ge, i > c AS gt, i <> c AS ne, + i << c AS sb, i <<= c AS sbe, + i >> c AS sup, i >>= c AS spe, + i && c AS ovr + FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM inet_tbl" +== 033 +-- truncate_limit: 100 +SELECT max(i) AS max, min(i) AS min FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(i) AS max, min(i) AS min FROM inet_tbl" +== 034 +-- truncate_limit: 100 +SELECT max(c) AS max, min(c) AS min FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(c) AS max, min(c) AS min FROM inet_tbl" +== 035 +-- truncate_limit: 100 +-- check the conversion to/from text and set_netmask +SELECT set_masklen(inet(text(i)), 24) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="set_masklen" function="set_masklen" schema="" ctx=Call +FUNCTION: name="inet" function="inet" schema="" ctx=Call +FUNCTION: name="text" function="text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_masklen(inet(text(i)), 24) FROM inet_tbl" +== 036 +-- truncate_limit: 100 +-- check that btree index works correctly +CREATE INDEX inet_idx1 ON inet_tbl(i) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX inet_idx1 ON inet_tbl USING btree (i)" +== 037 +-- truncate_limit: 100 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 038 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr" +== 039 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr" +== 040 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr" +== 041 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr" +== 042 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i" +== 043 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i" +== 044 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i" +== 045 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i" +== 046 +-- truncate_limit: 100 +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 047 +-- truncate_limit: 100 +DROP INDEX inet_idx1 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX inet_idx1" +== 048 +-- truncate_limit: 100 +-- check that gist index works correctly +CREATE INDEX inet_idx2 ON inet_tbl using gist (i inet_ops) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX inet_idx2 ON inet_tbl USING gist (i inet_ops)" +== 049 +-- truncate_limit: 100 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 050 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i" +== 051 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i" +== 052 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i" +== 053 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i" +== 054 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i" +== 055 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i" +== 056 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i" +== 057 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i" +== 058 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i" +== 059 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i" +== 060 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i" +== 061 +-- truncate_limit: 100 +-- test index-only scans +EXPLAIN (COSTS OFF) +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i" +== 062 +-- truncate_limit: 100 +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i" +== 063 +-- truncate_limit: 100 +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 064 +-- truncate_limit: 100 +DROP INDEX inet_idx2 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX inet_idx2" +== 065 +-- truncate_limit: 100 +-- check that spgist index works correctly +CREATE INDEX inet_idx3 ON inet_tbl using spgist (i) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX inet_idx3 ON inet_tbl USING spgist (i)" +== 066 +-- truncate_limit: 100 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 067 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i" +== 068 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i" +== 069 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i" +== 070 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i" +== 071 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i" +== 072 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i" +== 073 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i" +== 074 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i" +== 075 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i" +== 076 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i" +== 077 +-- truncate_limit: 100 +SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i" +== 078 +-- truncate_limit: 100 +-- test index-only scans +EXPLAIN (COSTS OFF) +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i" +== 079 +-- truncate_limit: 100 +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i" +== 080 +-- truncate_limit: 100 +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 081 +-- truncate_limit: 100 +DROP INDEX inet_idx3 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX inet_idx3" +== 082 +-- truncate_limit: 100 +-- simple tests of inet boolean and arithmetic operators +SELECT i, ~i AS "~i" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT i, ~ i AS \"~i\" FROM inet_tbl" +== 083 +-- truncate_limit: 100 +SELECT i, c, i & c AS "and" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT i, c, i & c AS \"and\" FROM inet_tbl" +== 084 +-- truncate_limit: 100 +SELECT i, c, i | c AS "or" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT i, c, i | c AS \"or\" FROM inet_tbl" +== 085 +-- truncate_limit: 100 +SELECT i, i + 500 AS "i+500" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT i, i + 500 AS \"i+500\" FROM inet_tbl" +== 086 +-- truncate_limit: 100 +SELECT i, i - 500 AS "i-500" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT i, i - 500 AS \"i-500\" FROM inet_tbl" +== 087 +-- truncate_limit: 100 +SELECT i, c, i - c AS "minus" FROM inet_tbl +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT i, c, i - c AS minus FROM inet_tbl" +== 088 +-- truncate_limit: 100 +SELECT '127.0.0.1'::inet + 257 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127.0.0.1'::inet + 257" +== 089 +-- truncate_limit: 100 +SELECT ('127.0.0.1'::inet + 257) - 257 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('127.0.0.1'::inet + 257) - 257" +== 090 +-- truncate_limit: 100 +SELECT '127::1'::inet + 257 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127::1'::inet + 257" +== 091 +-- truncate_limit: 100 +SELECT ('127::1'::inet + 257) - 257 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('127::1'::inet + 257) - 257" +== 092 +-- truncate_limit: 100 +SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet + 500) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet + 500)" +== 093 +-- truncate_limit: 100 +SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet - 500) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet - 500)" +== 094 +-- truncate_limit: 100 +SELECT '127::2'::inet - ('127::2'::inet + 500) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127::2'::inet - ('127::2'::inet + 500)" +== 095 +-- truncate_limit: 100 +SELECT '127::2'::inet - ('127::2'::inet - 500) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127::2'::inet - ('127::2'::inet - 500)" +== 096 +-- truncate_limit: 100 +-- these should give overflow errors: +SELECT '127.0.0.1'::inet + 10000000000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127.0.0.1'::inet + 10000000000" +== 097 +-- truncate_limit: 100 +SELECT '127.0.0.1'::inet - 10000000000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127.0.0.1'::inet - 10000000000" +== 098 +-- truncate_limit: 100 +SELECT '126::1'::inet - '127::2'::inet +-- +STMT: SelectStmt +TRUNCATED: "SELECT '126::1'::inet - '127::2'::inet" +== 099 +-- truncate_limit: 100 +SELECT '127::1'::inet - '126::2'::inet +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127::1'::inet - '126::2'::inet" +== 100 +-- truncate_limit: 100 +-- but not these +SELECT '127::1'::inet + 10000000000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127::1'::inet + 10000000000" +== 101 +-- truncate_limit: 100 +SELECT '127::1'::inet - '127::2'::inet +-- +STMT: SelectStmt +TRUNCATED: "SELECT '127::1'::inet - '127::2'::inet" +== 102 +-- truncate_limit: 100 +-- insert one more row with addressed from different families +INSERT INTO INET_TBL (c, i) VALUES ('10', '10::/8') +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inet_tbl (c, i) VALUES ('10', '10::/8')" +== 103 +-- truncate_limit: 100 +-- now, this one should fail +SELECT inet_merge(c, i) FROM INET_TBL +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="inet_merge" function="inet_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT inet_merge(c, i) FROM inet_tbl" +== 104 +-- truncate_limit: 100 +-- fix it by inet_same_family() condition +SELECT inet_merge(c, i) FROM INET_TBL WHERE inet_same_family(c, i) +-- +TABLE: name="inet_tbl" schema="" table="inet_tbl" ctx=Select +FUNCTION: name="inet_same_family" function="inet_same_family" schema="" ctx=Call +FUNCTION: name="inet_merge" function="inet_merge" schema="" ctx=Call +FUNCTION: name="inet_same_family" function="inet_same_family" schema="" ctx=Call +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT inet_merge(c, i) FROM inet_tbl WHERE inet_same_family(c, i)" +== 105 +-- truncate_limit: 100 +-- Test inet sortsupport with a variety of boundary inputs: +SELECT a FROM (VALUES + ('0.0.0.0/0'::inet), + ('0.0.0.0/1'::inet), + ('0.0.0.0/32'::inet), + ('0.0.0.1/0'::inet), + ('0.0.0.1/1'::inet), + ('127.126.127.127/0'::inet), + ('127.127.127.127/0'::inet), + ('127.128.127.127/0'::inet), + ('192.168.1.0/24'::inet), + ('192.168.1.0/25'::inet), + ('192.168.1.1/23'::inet), + ('192.168.1.1/5'::inet), + ('192.168.1.1/6'::inet), + ('192.168.1.1/25'::inet), + ('192.168.1.2/25'::inet), + ('192.168.1.1/26'::inet), + ('192.168.1.2/26'::inet), + ('192.168.1.2/23'::inet), + ('192.168.1.255/5'::inet), + ('192.168.1.255/6'::inet), + ('192.168.1.3/1'::inet), + ('192.168.1.3/23'::inet), + ('192.168.1.4/0'::inet), + ('192.168.1.5/0'::inet), + ('255.0.0.0/0'::inet), + ('255.1.0.0/0'::inet), + ('255.2.0.0/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/15'::inet), + ('255.255.000.000/16'::inet), + ('255.255.255.254/32'::inet), + ('255.255.255.000/32'::inet), + ('255.255.255.001/31'::inet), + ('255.255.255.002/31'::inet), + ('255.255.255.003/31'::inet), + ('255.255.255.003/32'::inet), + ('255.255.255.001/32'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/1'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/31'::inet), + ('255.255.255.255/32'::inet), + ('255.255.255.253/32'::inet), + ('255.255.255.252/32'::inet), + ('255.3.0.0/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/128'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0001/128'::inet), + ('10:23::f1/64'::inet), + ('10:23::f1/65'::inet), + ('10:23::ffff'::inet), + ('127::1'::inet), + ('127::2'::inet), + ('8000:0000:0000:0000:0000:0000:0000:0000/1'::inet), + ('::1:ffff:ffff:ffff:ffff/128'::inet), + ('::2:ffff:ffff:ffff:ffff/128'::inet), + ('::4:3:2:0/24'::inet), + ('::4:3:2:1/24'::inet), + ('::4:3:2:2/24'::inet), + ('ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70'::inet), + ('ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44'::inet), + ('ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69'::inet), + ('ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73'::inet), + ('ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89'::inet), + ('ffff:8dd0:646:694c:7c16:7e35:6a26:171/104'::inet), + ('ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121'::inet), + ('ffff:90e7:e744:664:a93:8efe:1f25:7663/122'::inet), + ('ffff:9597:c69c:8b24:57a:8639:ec78:6026/111'::inet), + ('ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88'::inet), + ('ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23'::inet), + ('ffff:fffa:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffb:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffc:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffd:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffe:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffa:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffb:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffc:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffd::/128'::inet), + ('ffff:ffff:ffff:fffd:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffe::/128'::inet), + ('ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:0/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:1/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:2/24'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet) +) AS i(a) ORDER BY a +-- +STMT: SelectStmt +TRUNCATED: "SELECT a FROM (VALUES (...)) i(a) ORDER BY a" +== 106 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('1234', 'cidr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1234', 'cidr')" +== 107 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1234', 'cidr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1234', 'cidr')" +== 108 +-- truncate_limit: 100 +SELECT pg_input_is_valid('192.168.198.200/24', 'cidr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('192.168.198.200/24', 'cidr')" +== 109 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('192.168.198.200/24', 'cidr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('192.168.198.200/24', 'cidr')" +== 110 +-- truncate_limit: 100 +SELECT pg_input_is_valid('1234', 'inet') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1234', 'inet')" +== 111 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1234', 'inet') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1234', 'inet')" diff --git a/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json b/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json new file mode 100644 index 0000000..3e33966 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json @@ -0,0 +1,7 @@ +{ + "todo": [ + "001", + "002", + "003" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.test b/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.test new file mode 100644 index 0000000..4a273ae --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.test @@ -0,0 +1,39 @@ +== 001 +-- truncate_limit: 100 +-- Check that stack depth detection mechanism works and +-- max_stack_depth is not set too high. + +create function infinite_recurse() returns int as +'select infinite_recurse()' language sql +-- +FUNCTION: name="infinite_recurse" function="infinite_recurse" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION infinite_recurse() RETURNS int AS $$select infinite_recurse()$$ LANGUAGE sql" +== 002 +-- truncate_limit: 100 +-- Unfortunately, up till mid 2020 the Linux kernel had a bug in PPC64 +-- signal handling that would cause this test to crash if it happened +-- to receive an sinval catchup interrupt while the stack is deep: +-- https://bugzilla.kernel.org/show_bug.cgi?id=205183 +-- It is likely to be many years before that bug disappears from all +-- production kernels, so disable this test on such platforms. +-- (We still create the function, so as not to have a cross-platform +-- difference in the end state of the regression database.) + +SELECT version() ~ 'powerpc64[^,]*-linux-gnu' + AS skip_test +-- +FUNCTION: name="version" function="version" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT version() ~ 'powerpc64[^,]*-linux-gnu' AS skip_test" +== 003 +-- truncate_limit: 100 +-- The full error report is not very stable, so we show only SQLSTATE +-- and primary error message. + + +select infinite_recurse() +-- +FUNCTION: name="infinite_recurse" function="infinite_recurse" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT infinite_recurse()" diff --git a/parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json new file mode 100644 index 0000000..53ffb30 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json @@ -0,0 +1,681 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/inherit.test b/parser/testdata/summary_truncate/postgres_regress/inherit.test new file mode 100644 index 0000000..62bf41b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/inherit.test @@ -0,0 +1,5537 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test inheritance features +|-- +CREATE TABLE a (aa TEXT) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE a (aa text)" +== 002 +-- truncate_limit: 100 +CREATE TABLE b (bb TEXT) INHERITS (a) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE b (bb text) INHERITS (a)" +== 003 +-- truncate_limit: 100 +CREATE TABLE c (cc TEXT) INHERITS (a) +-- +TABLE: name="c" schema="" table="c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c (cc text) INHERITS (a)" +== 004 +-- truncate_limit: 100 +CREATE TABLE d (dd TEXT) INHERITS (b,c,a) +-- +TABLE: name="d" schema="" table="d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE d (dd text) INHERITS (b, c, a)" +== 005 +-- truncate_limit: 100 +INSERT INTO a(aa) VALUES('aaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (aa) VALUES ('aaa')" +== 006 +-- truncate_limit: 100 +INSERT INTO a(aa) VALUES('aaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (aa) VALUES ('aaaa')" +== 007 +-- truncate_limit: 100 +INSERT INTO a(aa) VALUES('aaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (aa) VALUES ('aaaaa')" +== 008 +-- truncate_limit: 100 +INSERT INTO a(aa) VALUES('aaaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (aa) VALUES ('aaaaaa')" +== 009 +-- truncate_limit: 100 +INSERT INTO a(aa) VALUES('aaaaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (aa) VALUES ('aaaaaaa')" +== 010 +-- truncate_limit: 100 +INSERT INTO a(aa) VALUES('aaaaaaaa') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (aa) VALUES ('aaaaaaaa')" +== 011 +-- truncate_limit: 100 +INSERT INTO b(aa) VALUES('bbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (aa) VALUES ('bbb')" +== 012 +-- truncate_limit: 100 +INSERT INTO b(aa) VALUES('bbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (aa) VALUES ('bbbb')" +== 013 +-- truncate_limit: 100 +INSERT INTO b(aa) VALUES('bbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (aa) VALUES ('bbbbb')" +== 014 +-- truncate_limit: 100 +INSERT INTO b(aa) VALUES('bbbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (aa) VALUES ('bbbbbb')" +== 015 +-- truncate_limit: 100 +INSERT INTO b(aa) VALUES('bbbbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (aa) VALUES ('bbbbbbb')" +== 016 +-- truncate_limit: 100 +INSERT INTO b(aa) VALUES('bbbbbbbb') +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (aa) VALUES ('bbbbbbbb')" +== 017 +-- truncate_limit: 100 +INSERT INTO c(aa) VALUES('ccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (aa) VALUES ('ccc')" +== 018 +-- truncate_limit: 100 +INSERT INTO c(aa) VALUES('cccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (aa) VALUES ('cccc')" +== 019 +-- truncate_limit: 100 +INSERT INTO c(aa) VALUES('ccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (aa) VALUES ('ccccc')" +== 020 +-- truncate_limit: 100 +INSERT INTO c(aa) VALUES('cccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (aa) VALUES ('cccccc')" +== 021 +-- truncate_limit: 100 +INSERT INTO c(aa) VALUES('ccccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (aa) VALUES ('ccccccc')" +== 022 +-- truncate_limit: 100 +INSERT INTO c(aa) VALUES('cccccccc') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (aa) VALUES ('cccccccc')" +== 023 +-- truncate_limit: 100 +INSERT INTO d(aa) VALUES('ddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d (aa) VALUES ('ddd')" +== 024 +-- truncate_limit: 100 +INSERT INTO d(aa) VALUES('dddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d (aa) VALUES ('dddd')" +== 025 +-- truncate_limit: 100 +INSERT INTO d(aa) VALUES('ddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d (aa) VALUES ('ddddd')" +== 026 +-- truncate_limit: 100 +INSERT INTO d(aa) VALUES('dddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d (aa) VALUES ('dddddd')" +== 027 +-- truncate_limit: 100 +INSERT INTO d(aa) VALUES('ddddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d (aa) VALUES ('ddddddd')" +== 028 +-- truncate_limit: 100 +INSERT INTO d(aa) VALUES('dddddddd') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d (aa) VALUES ('dddddddd')" +== 029 +-- truncate_limit: 100 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM a, pg_class WHERE a.tableoid = pg_class.oid" +== 030 +-- truncate_limit: 100 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM b, pg_class WHERE b.tableoid = pg_class.oid" +== 031 +-- truncate_limit: 100 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM c, pg_class WHERE c.tableoid = pg_class.oid" +== 032 +-- truncate_limit: 100 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM d, pg_class WHERE d.tableoid = pg_class.oid" +== 033 +-- truncate_limit: 100 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM ONLY a, pg_class WHERE a.tableoid = pg_class.oid" +== 034 +-- truncate_limit: 100 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM ONLY b, pg_class WHERE b.tableoid = pg_class.oid" +== 035 +-- truncate_limit: 100 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM ONLY c, pg_class WHERE c.tableoid = pg_class.oid" +== 036 +-- truncate_limit: 100 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM ONLY d, pg_class WHERE d.tableoid = pg_class.oid" +== 037 +-- truncate_limit: 100 +UPDATE a SET aa='zzzz' WHERE aa='aaaa' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE a SET aa = 'zzzz' WHERE aa = 'aaaa'" +== 038 +-- truncate_limit: 100 +UPDATE ONLY a SET aa='zzzzz' WHERE aa='aaaaa' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ONLY a SET aa = 'zzzzz' WHERE aa = 'aaaaa'" +== 039 +-- truncate_limit: 100 +UPDATE b SET aa='zzz' WHERE aa='aaa' +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE b SET aa = 'zzz' WHERE aa = 'aaa'" +== 040 +-- truncate_limit: 100 +UPDATE ONLY b SET aa='zzz' WHERE aa='aaa' +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ONLY b SET aa = 'zzz' WHERE aa = 'aaa'" +== 041 +-- truncate_limit: 100 +UPDATE a SET aa='zzzzzz' WHERE aa LIKE 'aaa%' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaa%'" +== 042 +-- truncate_limit: 100 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM a, pg_class WHERE a.tableoid = pg_class.oid" +== 043 +-- truncate_limit: 100 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM b, pg_class WHERE b.tableoid = pg_class.oid" +== 044 +-- truncate_limit: 100 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM c, pg_class WHERE c.tableoid = pg_class.oid" +== 045 +-- truncate_limit: 100 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM d, pg_class WHERE d.tableoid = pg_class.oid" +== 046 +-- truncate_limit: 100 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM ONLY a, pg_class WHERE a.tableoid = pg_class.oid" +== 047 +-- truncate_limit: 100 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM ONLY b, pg_class WHERE b.tableoid = pg_class.oid" +== 048 +-- truncate_limit: 100 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM ONLY c, pg_class WHERE c.tableoid = pg_class.oid" +== 049 +-- truncate_limit: 100 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM ONLY d, pg_class WHERE d.tableoid = pg_class.oid" +== 050 +-- truncate_limit: 100 +UPDATE b SET aa='new' +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE b SET aa = 'new'" +== 051 +-- truncate_limit: 100 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM a, pg_class WHERE a.tableoid = pg_class.oid" +== 052 +-- truncate_limit: 100 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM b, pg_class WHERE b.tableoid = pg_class.oid" +== 053 +-- truncate_limit: 100 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM c, pg_class WHERE c.tableoid = pg_class.oid" +== 054 +-- truncate_limit: 100 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM d, pg_class WHERE d.tableoid = pg_class.oid" +== 055 +-- truncate_limit: 100 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM ONLY a, pg_class WHERE a.tableoid = pg_class.oid" +== 056 +-- truncate_limit: 100 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM ONLY b, pg_class WHERE b.tableoid = pg_class.oid" +== 057 +-- truncate_limit: 100 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM ONLY c, pg_class WHERE c.tableoid = pg_class.oid" +== 058 +-- truncate_limit: 100 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM ONLY d, pg_class WHERE d.tableoid = pg_class.oid" +== 059 +-- truncate_limit: 100 +UPDATE a SET aa='new' +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE a SET aa = 'new'" +== 060 +-- truncate_limit: 100 +DELETE FROM ONLY c WHERE aa='new' +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ONLY c WHERE aa = 'new'" +== 061 +-- truncate_limit: 100 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM a, pg_class WHERE a.tableoid = pg_class.oid" +== 062 +-- truncate_limit: 100 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM b, pg_class WHERE b.tableoid = pg_class.oid" +== 063 +-- truncate_limit: 100 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM c, pg_class WHERE c.tableoid = pg_class.oid" +== 064 +-- truncate_limit: 100 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM d, pg_class WHERE d.tableoid = pg_class.oid" +== 065 +-- truncate_limit: 100 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM ONLY a, pg_class WHERE a.tableoid = pg_class.oid" +== 066 +-- truncate_limit: 100 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM ONLY b, pg_class WHERE b.tableoid = pg_class.oid" +== 067 +-- truncate_limit: 100 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM ONLY c, pg_class WHERE c.tableoid = pg_class.oid" +== 068 +-- truncate_limit: 100 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM ONLY d, pg_class WHERE d.tableoid = pg_class.oid" +== 069 +-- truncate_limit: 100 +DELETE FROM a +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM a" +== 070 +-- truncate_limit: 100 +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM a, pg_class WHERE a.tableoid = pg_class.oid" +== 071 +-- truncate_limit: 100 +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM b, pg_class WHERE b.tableoid = pg_class.oid" +== 072 +-- truncate_limit: 100 +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM c, pg_class WHERE c.tableoid = pg_class.oid" +== 073 +-- truncate_limit: 100 +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM d, pg_class WHERE d.tableoid = pg_class.oid" +== 074 +-- truncate_limit: 100 +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="a" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, a.* FROM ONLY a, pg_class WHERE a.tableoid = pg_class.oid" +== 075 +-- truncate_limit: 100 +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="b" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, b.* FROM ONLY b, pg_class WHERE b.tableoid = pg_class.oid" +== 076 +-- truncate_limit: 100 +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="c" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, c.* FROM ONLY c, pg_class WHERE c.tableoid = pg_class.oid" +== 077 +-- truncate_limit: 100 +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="d" column="tableoid" +FILTER: schema="" table="pg_class" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname, d.* FROM ONLY d, pg_class WHERE d.tableoid = pg_class.oid" +== 078 +-- truncate_limit: 100 +-- Confirm PRIMARY KEY adds NOT NULL constraint to child table +CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a) +-- +TABLE: name="z" schema="" table="z" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE z (b text, PRIMARY KEY (aa, b)) INHERITS (a)" +== 079 +-- truncate_limit: 100 +INSERT INTO z VALUES (NULL, 'text') +-- +TABLE: name="z" schema="" table="z" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO z VALUES (NULL, 'text')" +== 080 +-- truncate_limit: 100 +-- should fail + +-- Check inherited UPDATE with first child excluded +create table some_tab (f1 int, f2 int, f3 int, check (f1 < 10) no inherit) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE some_tab (f1 int, f2 int, f3 int, CHECK (f1 < 10) NO INHERIT)" +== 081 +-- truncate_limit: 100 +create table some_tab_child () inherits(some_tab) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE some_tab_child () INHERITS (some_tab)" +== 082 +-- truncate_limit: 100 +insert into some_tab_child select i, i+1, 0 from generate_series(1,1000) i +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO some_tab_child SELECT i, i + 1, 0 FROM generate_series(1, 1000) i" +== 083 +-- truncate_limit: 100 +create index on some_tab_child(f1, f2) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON some_tab_child USING btree (f1, f2)" +== 084 +-- truncate_limit: 100 +-- while at it, also check that statement-level triggers fire +create function some_tab_stmt_trig_func() returns trigger as +$$begin raise notice 'updating some_tab'; return NULL; end;$$ +language plpgsql +-- +FUNCTION: name="some_tab_stmt_trig_func" function="some_tab_stmt_trig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION some_tab_stmt_trig_func() RETURNS trigger AS $$begin raise notice 'updating some_..." +== 085 +-- truncate_limit: 100 +create trigger some_tab_stmt_trig + before update on some_tab execute function some_tab_stmt_trig_func() +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER some_tab_stmt_trig BEFORE UPDATE ON some_tab EXECUTE FUNCTION some_tab_stmt_trig_f..." +== 086 +-- truncate_limit: 100 +explain (costs off) +update some_tab set f3 = 11 where f1 = 12 and f2 = 13 +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE some_tab SET f3 = 11 WHERE f1 = 12 AND f2 = 13" +== 087 +-- truncate_limit: 100 +update some_tab set f3 = 11 where f1 = 12 and f2 = 13 +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE some_tab SET f3 = 11 WHERE f1 = 12 AND f2 = 13" +== 088 +-- truncate_limit: 100 +drop table some_tab cascade +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE some_tab CASCADE" +== 089 +-- truncate_limit: 100 +drop function some_tab_stmt_trig_func() +-- +FUNCTION: name="some_tab_stmt_trig_func" function="some_tab_stmt_trig_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION some_tab_stmt_trig_func()" +== 090 +-- truncate_limit: 100 +-- Check inherited UPDATE with all children excluded +create table some_tab (a int, b int) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE some_tab (a int, b int)" +== 091 +-- truncate_limit: 100 +create table some_tab_child () inherits (some_tab) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE some_tab_child () INHERITS (some_tab)" +== 092 +-- truncate_limit: 100 +insert into some_tab_child values(1,2) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO some_tab_child VALUES (1, 2)" +== 093 +-- truncate_limit: 100 +explain (verbose, costs off) +update some_tab set a = a + 1 where false +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE some_tab SET a = a + 1 WHERE false" +== 094 +-- truncate_limit: 100 +update some_tab set a = a + 1 where false +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE some_tab SET a = a + 1 WHERE false" +== 095 +-- truncate_limit: 100 +explain (verbose, costs off) +update some_tab set a = a + 1 where false returning b, a +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE some_tab SET a = a + 1 WHERE false RETURNING b, a" +== 096 +-- truncate_limit: 100 +update some_tab set a = a + 1 where false returning b, a +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE some_tab SET a = a + 1 WHERE false RETURNING b, a" +== 097 +-- truncate_limit: 100 +table some_tab +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM some_tab" +== 098 +-- truncate_limit: 100 +drop table some_tab cascade +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE some_tab CASCADE" +== 099 +-- truncate_limit: 100 +-- Check UPDATE with inherited target and an inherited source table +create temp table foo(f1 int, f2 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (f1 int, f2 int)" +== 100 +-- truncate_limit: 100 +create temp table foo2(f3 int) inherits (foo) +-- +TABLE: name="foo2" schema="" table="foo2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo2 (f3 int) INHERITS (foo)" +== 101 +-- truncate_limit: 100 +create temp table bar(f1 int, f2 int) +-- +TABLE: name="bar" schema="" table="bar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE bar (f1 int, f2 int)" +== 102 +-- truncate_limit: 100 +create temp table bar2(f3 int) inherits (bar) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE bar2 (f3 int) INHERITS (bar)" +== 103 +-- truncate_limit: 100 +insert into foo values(1,1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (1, 1)" +== 104 +-- truncate_limit: 100 +insert into foo values(3,3) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (3, 3)" +== 105 +-- truncate_limit: 100 +insert into foo2 values(2,2,2) +-- +TABLE: name="foo2" schema="" table="foo2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo2 VALUES (2, 2, 2)" +== 106 +-- truncate_limit: 100 +insert into foo2 values(3,3,3) +-- +TABLE: name="foo2" schema="" table="foo2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo2 VALUES (3, 3, 3)" +== 107 +-- truncate_limit: 100 +insert into bar values(1,1) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar VALUES (1, 1)" +== 108 +-- truncate_limit: 100 +insert into bar values(2,2) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar VALUES (2, 2)" +== 109 +-- truncate_limit: 100 +insert into bar values(3,3) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar VALUES (3, 3)" +== 110 +-- truncate_limit: 100 +insert into bar values(4,4) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar VALUES (4, 4)" +== 111 +-- truncate_limit: 100 +insert into bar2 values(1,1,1) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar2 VALUES (1, 1, 1)" +== 112 +-- truncate_limit: 100 +insert into bar2 values(2,2,2) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar2 VALUES (2, 2, 2)" +== 113 +-- truncate_limit: 100 +insert into bar2 values(3,3,3) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar2 VALUES (3, 3, 3)" +== 114 +-- truncate_limit: 100 +insert into bar2 values(4,4,4) +-- +TABLE: name="bar2" schema="" table="bar2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar2 VALUES (4, 4, 4)" +== 115 +-- truncate_limit: 100 +update bar set f2 = f2 + 100 where f1 in (select f1 from foo) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE bar SET f2 = f2 + 100 WHERE f1 IN (SELECT f1 FROM foo)" +== 116 +-- truncate_limit: 100 +select tableoid::regclass::text as relname, bar.* from bar order by 1,2 +-- +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text AS relname, bar.* FROM bar ORDER BY 1, 2" +== 117 +-- truncate_limit: 100 +-- Check UPDATE with inherited target and an appendrel subquery +update bar set f2 = f2 + 100 +from + ( select f1 from foo union all select f1+3 from foo ) ss +where bar.f1 = ss.f1 +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE bar SET f2 = f2 + 100 FROM (SELECT f1 FROM foo UNION ALL SELECT ... FROM foo) ss WHERE ..." +== 118 +-- truncate_limit: 100 +select tableoid::regclass::text as relname, bar.* from bar order by 1,2 +-- +TABLE: name="bar" schema="" table="bar" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text AS relname, bar.* FROM bar ORDER BY 1, 2" +== 119 +-- truncate_limit: 100 +-- Check UPDATE with *partitioned* inherited target and an appendrel subquery +create table some_tab (a int) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE some_tab (a int)" +== 120 +-- truncate_limit: 100 +insert into some_tab values (0) +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO some_tab VALUES (0)" +== 121 +-- truncate_limit: 100 +create table some_tab_child () inherits (some_tab) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE some_tab_child () INHERITS (some_tab)" +== 122 +-- truncate_limit: 100 +insert into some_tab_child values (1) +-- +TABLE: name="some_tab_child" schema="" table="some_tab_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO some_tab_child VALUES (1)" +== 123 +-- truncate_limit: 100 +create table parted_tab (a int, b char) partition by list (a) +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_tab (a int, b char(1)) PARTITION BY LIST (a)" +== 124 +-- truncate_limit: 100 +create table parted_tab_part1 partition of parted_tab for values in (1) +-- +TABLE: name="parted_tab_part1" schema="" table="parted_tab_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_tab_part1 PARTITION OF parted_tab FOR VALUES IN (1)" +== 125 +-- truncate_limit: 100 +create table parted_tab_part2 partition of parted_tab for values in (2) +-- +TABLE: name="parted_tab_part2" schema="" table="parted_tab_part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_tab_part2 PARTITION OF parted_tab FOR VALUES IN (2)" +== 126 +-- truncate_limit: 100 +create table parted_tab_part3 partition of parted_tab for values in (3) +-- +TABLE: name="parted_tab_part3" schema="" table="parted_tab_part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_tab_part3 PARTITION OF parted_tab FOR VALUES IN (3)" +== 127 +-- truncate_limit: 100 +insert into parted_tab values (1, 'a'), (2, 'a'), (3, 'a') +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_tab VALUES (1, 'a'), (2, 'a'), (3, 'a')" +== 128 +-- truncate_limit: 100 +update parted_tab set b = 'b' +from + (select a from some_tab union all select a+1 from some_tab) ss (a) +where parted_tab.a = ss.a +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE parted_tab SET ... = ... FROM (SELECT a FROM some_tab UNION ALL SELECT ... FROM some_tab) ..." +== 129 +-- truncate_limit: 100 +select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2 +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text AS relname, parted_tab.* FROM parted_tab ORDER BY 1, 2" +== 130 +-- truncate_limit: 100 +truncate parted_tab +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_tab" +== 131 +-- truncate_limit: 100 +insert into parted_tab values (1, 'a'), (2, 'a'), (3, 'a') +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_tab VALUES (1, 'a'), (2, 'a'), (3, 'a')" +== 132 +-- truncate_limit: 100 +update parted_tab set b = 'b' +from + (select 0 from parted_tab union all select 1 from parted_tab) ss (a) +where parted_tab.a = ss.a +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE parted_tab SET ... = ... FROM (SELECT 0 FROM parted_tab UNION ALL SELECT 1 FROM parted_tab..." +== 133 +-- truncate_limit: 100 +select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2 +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text AS relname, parted_tab.* FROM parted_tab ORDER BY 1, 2" +== 134 +-- truncate_limit: 100 +-- modifies partition key, but no rows will actually be updated +explain update parted_tab set a = 2 where false +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN UPDATE parted_tab SET a = 2 WHERE false" +== 135 +-- truncate_limit: 100 +drop table parted_tab +-- +TABLE: name="parted_tab" schema="" table="parted_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_tab" +== 136 +-- truncate_limit: 100 +-- Check UPDATE with multi-level partitioned inherited target +create table mlparted_tab (a int, b char, c text) partition by list (a) +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_tab (a int, b char(1), c text) PARTITION BY LIST (a)" +== 137 +-- truncate_limit: 100 +create table mlparted_tab_part1 partition of mlparted_tab for values in (1) +-- +TABLE: name="mlparted_tab_part1" schema="" table="mlparted_tab_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_tab_part1 PARTITION OF mlparted_tab FOR VALUES IN (1)" +== 138 +-- truncate_limit: 100 +create table mlparted_tab_part2 partition of mlparted_tab for values in (2) partition by list (b) +-- +TABLE: name="mlparted_tab_part2" schema="" table="mlparted_tab_part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_tab_part2 PARTITION OF mlparted_tab FOR VALUES IN (2) PARTITION BY LIST (b)" +== 139 +-- truncate_limit: 100 +create table mlparted_tab_part3 partition of mlparted_tab for values in (3) +-- +TABLE: name="mlparted_tab_part3" schema="" table="mlparted_tab_part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_tab_part3 PARTITION OF mlparted_tab FOR VALUES IN (3)" +== 140 +-- truncate_limit: 100 +create table mlparted_tab_part2a partition of mlparted_tab_part2 for values in ('a') +-- +TABLE: name="mlparted_tab_part2a" schema="" table="mlparted_tab_part2a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_tab_part2a PARTITION OF mlparted_tab_part2 FOR VALUES IN ('a')" +== 141 +-- truncate_limit: 100 +create table mlparted_tab_part2b partition of mlparted_tab_part2 for values in ('b') +-- +TABLE: name="mlparted_tab_part2b" schema="" table="mlparted_tab_part2b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_tab_part2b PARTITION OF mlparted_tab_part2 FOR VALUES IN ('b')" +== 142 +-- truncate_limit: 100 +insert into mlparted_tab values (1, 'a'), (2, 'a'), (2, 'b'), (3, 'a') +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted_tab VALUES (1, 'a'), (2, 'a'), (2, 'b'), (3, 'a')" +== 143 +-- truncate_limit: 100 +update mlparted_tab mlp set c = 'xxx' +from + (select a from some_tab union all select a+1 from some_tab) ss (a) +where (mlp.a = ss.a and mlp.b = 'b') or mlp.a = 3 +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DML +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +TABLE: name="some_tab" schema="" table="some_tab" ctx=Select +ALIAS: "mlp"="mlparted_tab" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE mlparted_tab mlp SET ... = ... FROM (SELECT a FROM some_tab UNION ALL SELECT ... FROM some..." +== 144 +-- truncate_limit: 100 +select tableoid::regclass::text as relname, mlparted_tab.* from mlparted_tab order by 1,2 +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text AS relname, mlparted_tab.* FROM mlparted_tab ORDER BY 1, 2" +== 145 +-- truncate_limit: 100 +drop table mlparted_tab +-- +TABLE: name="mlparted_tab" schema="" table="mlparted_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mlparted_tab" +== 146 +-- truncate_limit: 100 +drop table some_tab cascade +-- +TABLE: name="some_tab" schema="" table="some_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE some_tab CASCADE" +== 147 +-- truncate_limit: 100 +/* Test multiple inheritance of column defaults */ + +CREATE TABLE firstparent (tomorrow date default now()::date + 1) +-- +TABLE: name="firstparent" schema="" table="firstparent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE firstparent (tomorrow date DEFAULT now()::date + 1)" +== 148 +-- truncate_limit: 100 +CREATE TABLE secondparent (tomorrow date default now() :: date + 1) +-- +TABLE: name="secondparent" schema="" table="secondparent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE secondparent (tomorrow date DEFAULT now()::date + 1)" +== 149 +-- truncate_limit: 100 +CREATE TABLE jointchild () INHERITS (firstparent, secondparent) +-- +TABLE: name="jointchild" schema="" table="jointchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE jointchild () INHERITS (firstparent, secondparent)" +== 150 +-- truncate_limit: 100 +-- ok +CREATE TABLE thirdparent (tomorrow date default now()::date - 1) +-- +TABLE: name="thirdparent" schema="" table="thirdparent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE thirdparent (tomorrow date DEFAULT now()::date - 1)" +== 151 +-- truncate_limit: 100 +CREATE TABLE otherchild () INHERITS (firstparent, thirdparent) +-- +TABLE: name="otherchild" schema="" table="otherchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE otherchild () INHERITS (firstparent, thirdparent)" +== 152 +-- truncate_limit: 100 +-- not ok +CREATE TABLE otherchild (tomorrow date default now()) + INHERITS (firstparent, thirdparent) +-- +TABLE: name="otherchild" schema="" table="otherchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE otherchild (tomorrow date DEFAULT now()) INHERITS (firstparent, thirdparent)" +== 153 +-- truncate_limit: 100 +-- ok, child resolves ambiguous default + +DROP TABLE firstparent, secondparent, jointchild, thirdparent, otherchild +-- +TABLE: name="firstparent" schema="" table="firstparent" ctx=DDL +TABLE: name="secondparent" schema="" table="secondparent" ctx=DDL +TABLE: name="jointchild" schema="" table="jointchild" ctx=DDL +TABLE: name="thirdparent" schema="" table="thirdparent" ctx=DDL +TABLE: name="otherchild" schema="" table="otherchild" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE firstparent, secondparent, jointchild, thirdparent, otherchild" +== 154 +-- truncate_limit: 100 +-- Test changing the type of inherited columns +insert into d values('test','one','two','three') +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d VALUES ('test', 'one', 'two', 'three')" +== 155 +-- truncate_limit: 100 +alter table a alter column aa type integer using bit_length(aa) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE a ALTER COLUMN aa TYPE int USING bit_length(aa)" +== 156 +-- truncate_limit: 100 +select * from d +-- +TABLE: name="d" schema="" table="d" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM d" +== 157 +-- truncate_limit: 100 +-- The above verified that we can change the type of a multiply-inherited +-- column; but we should reject that if any definition was inherited from +-- an unrelated parent. +create temp table parent1(f1 int, f2 int) +-- +TABLE: name="parent1" schema="" table="parent1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parent1 (f1 int, f2 int)" +== 158 +-- truncate_limit: 100 +create temp table parent2(f1 int, f3 bigint) +-- +TABLE: name="parent2" schema="" table="parent2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parent2 (f1 int, f3 bigint)" +== 159 +-- truncate_limit: 100 +create temp table childtab(f4 int) inherits(parent1, parent2) +-- +TABLE: name="childtab" schema="" table="childtab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE childtab (f4 int) INHERITS (parent1, parent2)" +== 160 +-- truncate_limit: 100 +alter table parent1 alter column f1 type bigint +-- +TABLE: name="parent1" schema="" table="parent1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent1 ALTER COLUMN f1 TYPE bigint" +== 161 +-- truncate_limit: 100 +-- fail, conflict w/parent2 +alter table parent1 alter column f2 type bigint +-- +TABLE: name="parent1" schema="" table="parent1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent1 ALTER COLUMN f2 TYPE bigint" +== 162 +-- truncate_limit: 100 +-- ok + +-- Test non-inheritable parent constraints +create table p1(ff1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (ff1 int)" +== 163 +-- truncate_limit: 100 +alter table p1 add constraint p1chk check (ff1 > 0) no inherit +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 ADD CONSTRAINT p1chk CHECK (ff1 > 0) NO INHERIT" +== 164 +-- truncate_limit: 100 +alter table p1 add constraint p2chk check (ff1 > 10) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 ADD CONSTRAINT p2chk CHECK (ff1 > 10)" +== 165 +-- truncate_limit: 100 +-- connoinherit should be true for NO INHERIT constraint +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.connoinherit from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname = 'p1' order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 166 +-- truncate_limit: 100 +-- Test that child does not inherit NO INHERIT constraints +create table c1 () inherits (p1) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 () INHERITS (p1)" +== 167 +-- truncate_limit: 100 +-- Test that child does not override inheritable constraints of the parent +create table c2 (constraint p2chk check (ff1 > 10) no inherit) inherits (p1) +-- +TABLE: name="c2" schema="" table="c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c2 (CONSTRAINT p2chk CHECK (ff1 > 10) NO INHERIT) INHERITS (p1)" +== 168 +-- truncate_limit: 100 +--fails + +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 169 +-- truncate_limit: 100 +-- Tests for casting between the rowtypes of parent and child +-- tables. See the pgsql-hackers thread beginning Dec. 4/04 +create table base (i integer) +-- +TABLE: name="base" schema="" table="base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base (i int)" +== 170 +-- truncate_limit: 100 +create table derived () inherits (base) +-- +TABLE: name="derived" schema="" table="derived" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE derived () INHERITS (base)" +== 171 +-- truncate_limit: 100 +create table more_derived (like derived, b int) inherits (derived) +-- +TABLE: name="more_derived" schema="" table="more_derived" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE more_derived (LIKE derived, b int) INHERITS (derived)" +== 172 +-- truncate_limit: 100 +insert into derived (i) values (0) +-- +TABLE: name="derived" schema="" table="derived" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO derived (i) VALUES (0)" +== 173 +-- truncate_limit: 100 +select derived::base from derived +-- +TABLE: name="derived" schema="" table="derived" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT derived::base FROM derived" +== 174 +-- truncate_limit: 100 +select NULL::derived::base +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::derived::base" +== 175 +-- truncate_limit: 100 +-- remove redundant conversions. +explain (verbose on, costs off) select row(i, b)::more_derived::derived::base from more_derived +-- +TABLE: name="more_derived" schema="" table="more_derived" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE ON, COSTS OFF) SELECT ROW(i, b)::more_derived::derived::base FROM more_derived" +== 176 +-- truncate_limit: 100 +explain (verbose on, costs off) select (1, 2)::more_derived::derived::base +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE ON, COSTS OFF) SELECT (1, 2)::more_derived::derived::base" +== 177 +-- truncate_limit: 100 +drop table more_derived +-- +TABLE: name="more_derived" schema="" table="more_derived" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE more_derived" +== 178 +-- truncate_limit: 100 +drop table derived +-- +TABLE: name="derived" schema="" table="derived" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE derived" +== 179 +-- truncate_limit: 100 +drop table base +-- +TABLE: name="base" schema="" table="base" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base" +== 180 +-- truncate_limit: 100 +create table p1(ff1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (ff1 int)" +== 181 +-- truncate_limit: 100 +create table p2(f1 text) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p2 (f1 text)" +== 182 +-- truncate_limit: 100 +create function p2text(p2) returns text as 'select $1.f1' language sql +-- +FUNCTION: name="p2text" function="p2text" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION p2text(p2) RETURNS text AS $$select $1.f1$$ LANGUAGE sql" +== 183 +-- truncate_limit: 100 +create table c1(f3 int) inherits(p1,p2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 (f3 int) INHERITS (p1, p2)" +== 184 +-- truncate_limit: 100 +insert into c1 values(123456789, 'hi', 42) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c1 VALUES (123456789, 'hi', 42)" +== 185 +-- truncate_limit: 100 +select p2text(c1.*) from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=Select +FUNCTION: name="p2text" function="p2text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT p2text(c1.*) FROM c1" +== 186 +-- truncate_limit: 100 +drop function p2text(p2) +-- +FUNCTION: name="p2text" function="p2text" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION p2text(p2)" +== 187 +-- truncate_limit: 100 +drop table c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE c1" +== 188 +-- truncate_limit: 100 +drop table p2 +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p2" +== 189 +-- truncate_limit: 100 +drop table p1 +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1" +== 190 +-- truncate_limit: 100 +CREATE TABLE ac (aa TEXT) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ac (aa text)" +== 191 +-- truncate_limit: 100 +alter table ac add constraint ac_check check (aa is not null) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ac ADD CONSTRAINT ac_check CHECK (aa IS NOT NULL)" +== 192 +-- truncate_limit: 100 +CREATE TABLE bc (bb TEXT) INHERITS (ac) +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bc (bb text) INHERITS (ac)" +== 193 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 194 +-- truncate_limit: 100 +insert into ac (aa) values (NULL) +-- +TABLE: name="ac" schema="" table="ac" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ac (aa) VALUES (NULL)" +== 195 +-- truncate_limit: 100 +insert into bc (aa) values (NULL) +-- +TABLE: name="bc" schema="" table="bc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bc (aa) VALUES (NULL)" +== 196 +-- truncate_limit: 100 +alter table bc drop constraint ac_check +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bc DROP CONSTRAINT ac_check" +== 197 +-- truncate_limit: 100 +-- fail, disallowed +alter table ac drop constraint ac_check +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ac DROP CONSTRAINT ac_check" +== 198 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 199 +-- truncate_limit: 100 +-- try the unnamed-constraint case +alter table ac add check (aa is not null) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ac ADD CHECK (aa IS NOT NULL)" +== 200 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 201 +-- truncate_limit: 100 +insert into ac (aa) values (NULL) +-- +TABLE: name="ac" schema="" table="ac" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ac (aa) VALUES (NULL)" +== 202 +-- truncate_limit: 100 +insert into bc (aa) values (NULL) +-- +TABLE: name="bc" schema="" table="bc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bc (aa) VALUES (NULL)" +== 203 +-- truncate_limit: 100 +alter table bc drop constraint ac_aa_check +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bc DROP CONSTRAINT ac_aa_check" +== 204 +-- truncate_limit: 100 +-- fail, disallowed +alter table ac drop constraint ac_aa_check +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ac DROP CONSTRAINT ac_aa_check" +== 205 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 206 +-- truncate_limit: 100 +alter table ac add constraint ac_check check (aa is not null) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ac ADD CONSTRAINT ac_check CHECK (aa IS NOT NULL)" +== 207 +-- truncate_limit: 100 +alter table bc no inherit ac +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bc NO INHERIT ac" +== 208 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 209 +-- truncate_limit: 100 +alter table bc drop constraint ac_check +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bc DROP CONSTRAINT ac_check" +== 210 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 211 +-- truncate_limit: 100 +alter table ac drop constraint ac_check +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ac DROP CONSTRAINT ac_check" +== 212 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 213 +-- truncate_limit: 100 +drop table bc +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bc" +== 214 +-- truncate_limit: 100 +drop table ac +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ac" +== 215 +-- truncate_limit: 100 +create table ac (a int constraint check_a check (a <> 0)) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ac (a int CONSTRAINT check_a CHECK (a <> 0))" +== 216 +-- truncate_limit: 100 +create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac) +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bc (a int CONSTRAINT check_a CHECK (a <> 0), b int CONSTRAINT check_b CHECK (b <> 0)..." +== 217 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 218 +-- truncate_limit: 100 +drop table bc +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bc" +== 219 +-- truncate_limit: 100 +drop table ac +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ac" +== 220 +-- truncate_limit: 100 +create table ac (a int constraint check_a check (a <> 0)) +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ac (a int CONSTRAINT check_a CHECK (a <> 0))" +== 221 +-- truncate_limit: 100 +create table bc (b int constraint check_b check (b <> 0)) +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bc (b int CONSTRAINT check_b CHECK (b <> 0))" +== 222 +-- truncate_limit: 100 +create table cc (c int constraint check_c check (c <> 0)) inherits (ac, bc) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cc (c int CONSTRAINT check_c CHECK (c <> 0)) INHERITS (ac, bc)" +== 223 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 224 +-- truncate_limit: 100 +alter table cc no inherit bc +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE cc NO INHERIT bc" +== 225 +-- truncate_limit: 100 +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pgc"="pg_constraint" +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="pc" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_constraint pgc ON pgc.conrelid = pc.oid WHERE ... ORDER BY 1, 2" +== 226 +-- truncate_limit: 100 +drop table cc +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cc" +== 227 +-- truncate_limit: 100 +drop table bc +-- +TABLE: name="bc" schema="" table="bc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bc" +== 228 +-- truncate_limit: 100 +drop table ac +-- +TABLE: name="ac" schema="" table="ac" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ac" +== 229 +-- truncate_limit: 100 +create table p1(f1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int)" +== 230 +-- truncate_limit: 100 +create table p2(f2 int) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p2 (f2 int)" +== 231 +-- truncate_limit: 100 +create table c1(f3 int) inherits(p1,p2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c1 (f3 int) INHERITS (p1, p2)" +== 232 +-- truncate_limit: 100 +insert into c1 values(1,-1,2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c1 VALUES (1, -1, 2)" +== 233 +-- truncate_limit: 100 +alter table p2 add constraint cc check (f2>0) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p2 ADD CONSTRAINT cc CHECK (f2 > 0)" +== 234 +-- truncate_limit: 100 +-- fail +alter table p2 add check (f2>0) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p2 ADD CHECK (f2 > 0)" +== 235 +-- truncate_limit: 100 +-- check it without a name, too +delete from c1 +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM c1" +== 236 +-- truncate_limit: 100 +insert into c1 values(1,1,2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c1 VALUES (1, 1, 2)" +== 237 +-- truncate_limit: 100 +alter table p2 add check (f2>0) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p2 ADD CHECK (f2 > 0)" +== 238 +-- truncate_limit: 100 +insert into c1 values(1,-1,2) +-- +TABLE: name="c1" schema="" table="c1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c1 VALUES (1, -1, 2)" +== 239 +-- truncate_limit: 100 +-- fail +create table c2(f3 int) inherits(p1,p2) +-- +TABLE: name="c2" schema="" table="c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c2 (f3 int) INHERITS (p1, p2)" +== 240 +-- truncate_limit: 100 +create table c3 (f4 int) inherits(c1,c2) +-- +TABLE: name="c3" schema="" table="c3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE c3 (f4 int) INHERITS (c1, c2)" +== 241 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 242 +-- truncate_limit: 100 +drop table p2 cascade +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p2 CASCADE" +== 243 +-- truncate_limit: 100 +create table pp1 (f1 int) +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp1 (f1 int)" +== 244 +-- truncate_limit: 100 +create table cc1 (f2 text, f3 int) inherits (pp1) +-- +TABLE: name="cc1" schema="" table="cc1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cc1 (f2 text, f3 int) INHERITS (pp1)" +== 245 +-- truncate_limit: 100 +alter table pp1 add column a1 int check (a1 > 0) +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pp1 ADD COLUMN a1 int CHECK (a1 > 0)" +== 246 +-- truncate_limit: 100 +create table cc2(f4 float) inherits(pp1,cc1) +-- +TABLE: name="cc2" schema="" table="cc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cc2 (f4 double precision) INHERITS (pp1, cc1)" +== 247 +-- truncate_limit: 100 +alter table pp1 add column a2 int check (a2 > 0) +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pp1 ADD COLUMN a2 int CHECK (a2 > 0)" +== 248 +-- truncate_limit: 100 +drop table pp1 cascade +-- +TABLE: name="pp1" schema="" table="pp1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp1 CASCADE" +== 249 +-- truncate_limit: 100 +-- Test for renaming in simple multiple inheritance +CREATE TABLE inht1 (a int, b int) +-- +TABLE: name="inht1" schema="" table="inht1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inht1 (a int, b int)" +== 250 +-- truncate_limit: 100 +CREATE TABLE inhs1 (b int, c int) +-- +TABLE: name="inhs1" schema="" table="inhs1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhs1 (b int, c int)" +== 251 +-- truncate_limit: 100 +CREATE TABLE inhts (d int) INHERITS (inht1, inhs1) +-- +TABLE: name="inhts" schema="" table="inhts" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhts (d int) INHERITS (inht1, inhs1)" +== 252 +-- truncate_limit: 100 +ALTER TABLE inht1 RENAME a TO aa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE inht1 RENAME COLUMN a TO aa" +== 253 +-- truncate_limit: 100 +ALTER TABLE inht1 RENAME b TO bb +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE inht1 RENAME COLUMN b TO bb" +== 254 +-- truncate_limit: 100 +-- to be failed +ALTER TABLE inhts RENAME aa TO aaa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE inhts RENAME COLUMN aa TO aaa" +== 255 +-- truncate_limit: 100 +-- to be failed +ALTER TABLE inhts RENAME d TO dd +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE inhts RENAME COLUMN d TO dd" +== 256 +-- truncate_limit: 100 +DROP TABLE inhts +-- +TABLE: name="inhts" schema="" table="inhts" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhts" +== 257 +-- truncate_limit: 100 +-- Test for adding a column to a parent table with complex inheritance +CREATE TABLE inhta () +-- +TABLE: name="inhta" schema="" table="inhta" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhta ()" +== 258 +-- truncate_limit: 100 +CREATE TABLE inhtb () INHERITS (inhta) +-- +TABLE: name="inhtb" schema="" table="inhtb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhtb () INHERITS (inhta)" +== 259 +-- truncate_limit: 100 +CREATE TABLE inhtc () INHERITS (inhtb) +-- +TABLE: name="inhtc" schema="" table="inhtc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhtc () INHERITS (inhtb)" +== 260 +-- truncate_limit: 100 +CREATE TABLE inhtd () INHERITS (inhta, inhtb, inhtc) +-- +TABLE: name="inhtd" schema="" table="inhtd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhtd () INHERITS (inhta, inhtb, inhtc)" +== 261 +-- truncate_limit: 100 +ALTER TABLE inhta ADD COLUMN i int, ADD COLUMN j bigint DEFAULT 1 +-- +TABLE: name="inhta" schema="" table="inhta" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inhta ADD COLUMN i int, ADD COLUMN j bigint DEFAULT 1" +== 262 +-- truncate_limit: 100 +DROP TABLE inhta, inhtb, inhtc, inhtd +-- +TABLE: name="inhta" schema="" table="inhta" ctx=DDL +TABLE: name="inhtb" schema="" table="inhtb" ctx=DDL +TABLE: name="inhtc" schema="" table="inhtc" ctx=DDL +TABLE: name="inhtd" schema="" table="inhtd" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhta, inhtb, inhtc, inhtd" +== 263 +-- truncate_limit: 100 +-- Test for renaming in diamond inheritance +CREATE TABLE inht2 (x int) INHERITS (inht1) +-- +TABLE: name="inht2" schema="" table="inht2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inht2 (x int) INHERITS (inht1)" +== 264 +-- truncate_limit: 100 +CREATE TABLE inht3 (y int) INHERITS (inht1) +-- +TABLE: name="inht3" schema="" table="inht3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inht3 (y int) INHERITS (inht1)" +== 265 +-- truncate_limit: 100 +CREATE TABLE inht4 (z int) INHERITS (inht2, inht3) +-- +TABLE: name="inht4" schema="" table="inht4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inht4 (z int) INHERITS (inht2, inht3)" +== 266 +-- truncate_limit: 100 +ALTER TABLE inht1 RENAME aa TO aaa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE inht1 RENAME COLUMN aa TO aaa" +== 267 +-- truncate_limit: 100 +CREATE TABLE inhts (d int) INHERITS (inht2, inhs1) +-- +TABLE: name="inhts" schema="" table="inhts" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhts (d int) INHERITS (inht2, inhs1)" +== 268 +-- truncate_limit: 100 +ALTER TABLE inht1 RENAME aaa TO aaaa +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE inht1 RENAME COLUMN aaa TO aaaa" +== 269 +-- truncate_limit: 100 +ALTER TABLE inht1 RENAME b TO bb +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE inht1 RENAME COLUMN b TO bb" +== 270 +-- truncate_limit: 100 +-- to be failed + +WITH RECURSIVE r AS ( + SELECT 'inht1'::regclass AS inhrelid +UNION ALL + SELECT c.inhrelid FROM pg_inherits c, r WHERE r.inhrelid = c.inhparent +) +SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected + FROM (SELECT inhrelid, count(*) AS expected FROM pg_inherits + WHERE inhparent IN (SELECT inhrelid FROM r) GROUP BY inhrelid) e + JOIN pg_attribute a ON e.inhrelid = a.attrelid WHERE NOT attislocal + ORDER BY a.attrelid::regclass::name, a.attnum +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +TABLE: name="pg_inherits" schema="" table="pg_inherits" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_inherits" +CTE: "r" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="attislocal" +FILTER: schema="" table="" column="inhparent" +FILTER: schema="" table="r" column="inhrelid" +FILTER: schema="" table="c" column="inhparent" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE r AS (...) SELECT ... FROM (SELECT ... FROM pg_inherits WHERE ... GROUP BY inhreli..." +== 271 +-- truncate_limit: 100 +DROP TABLE inht1, inhs1 CASCADE +-- +TABLE: name="inht1" schema="" table="inht1" ctx=DDL +TABLE: name="inhs1" schema="" table="inhs1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inht1, inhs1 CASCADE" +== 272 +-- truncate_limit: 100 +-- Test non-inheritable indices [UNIQUE, EXCLUDE] constraints +CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE(val1, val2)) +-- +TABLE: name="test_constraints" schema="" table="test_constraints" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE (val1, val2))" +== 273 +-- truncate_limit: 100 +CREATE TABLE test_constraints_inh () INHERITS (test_constraints) +-- +TABLE: name="test_constraints_inh" schema="" table="test_constraints_inh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_constraints_inh () INHERITS (test_constraints)" +== 274 +-- truncate_limit: 100 +ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key +-- +TABLE: name="test_constraints" schema="" table="test_constraints" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key" +== 275 +-- truncate_limit: 100 +DROP TABLE test_constraints_inh +-- +TABLE: name="test_constraints_inh" schema="" table="test_constraints_inh" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_constraints_inh" +== 276 +-- truncate_limit: 100 +DROP TABLE test_constraints +-- +TABLE: name="test_constraints" schema="" table="test_constraints" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_constraints" +== 277 +-- truncate_limit: 100 +CREATE TABLE test_ex_constraints ( + c circle, + EXCLUDE USING gist (c WITH &&) +) +-- +TABLE: name="test_ex_constraints" schema="" table="test_ex_constraints" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_ex_constraints (c circle, EXCLUDE USING gist (c WITH &&))" +== 278 +-- truncate_limit: 100 +CREATE TABLE test_ex_constraints_inh () INHERITS (test_ex_constraints) +-- +TABLE: name="test_ex_constraints_inh" schema="" table="test_ex_constraints_inh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_ex_constraints_inh () INHERITS (test_ex_constraints)" +== 279 +-- truncate_limit: 100 +ALTER TABLE test_ex_constraints DROP CONSTRAINT test_ex_constraints_c_excl +-- +TABLE: name="test_ex_constraints" schema="" table="test_ex_constraints" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_ex_constraints DROP CONSTRAINT test_ex_constraints_c_excl" +== 280 +-- truncate_limit: 100 +DROP TABLE test_ex_constraints_inh +-- +TABLE: name="test_ex_constraints_inh" schema="" table="test_ex_constraints_inh" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_ex_constraints_inh" +== 281 +-- truncate_limit: 100 +DROP TABLE test_ex_constraints +-- +TABLE: name="test_ex_constraints" schema="" table="test_ex_constraints" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_ex_constraints" +== 282 +-- truncate_limit: 100 +-- Test non-inheritable foreign key constraints +CREATE TABLE test_primary_constraints(id int PRIMARY KEY) +-- +TABLE: name="test_primary_constraints" schema="" table="test_primary_constraints" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_primary_constraints (id int PRIMARY KEY)" +== 283 +-- truncate_limit: 100 +CREATE TABLE test_foreign_constraints(id1 int REFERENCES test_primary_constraints(id)) +-- +TABLE: name="test_foreign_constraints" schema="" table="test_foreign_constraints" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_foreign_constraints (id1 int REFERENCES test_primary_constraints (id))" +== 284 +-- truncate_limit: 100 +CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints) +-- +TABLE: name="test_foreign_constraints_inh" schema="" table="test_foreign_constraints_inh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints)" +== 285 +-- truncate_limit: 100 +ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey +-- +TABLE: name="test_foreign_constraints" schema="" table="test_foreign_constraints" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey" +== 286 +-- truncate_limit: 100 +DROP TABLE test_foreign_constraints_inh +-- +TABLE: name="test_foreign_constraints_inh" schema="" table="test_foreign_constraints_inh" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_foreign_constraints_inh" +== 287 +-- truncate_limit: 100 +DROP TABLE test_foreign_constraints +-- +TABLE: name="test_foreign_constraints" schema="" table="test_foreign_constraints" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_foreign_constraints" +== 288 +-- truncate_limit: 100 +DROP TABLE test_primary_constraints +-- +TABLE: name="test_primary_constraints" schema="" table="test_primary_constraints" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_primary_constraints" +== 289 +-- truncate_limit: 100 +-- Test foreign key behavior +create table inh_fk_1 (a int primary key) +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_fk_1 (a int PRIMARY KEY)" +== 290 +-- truncate_limit: 100 +insert into inh_fk_1 values (1), (2), (3) +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inh_fk_1 VALUES (1), (2), (3)" +== 291 +-- truncate_limit: 100 +create table inh_fk_2 (x int primary key, y int references inh_fk_1 on delete cascade) +-- +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_fk_2 (x int PRIMARY KEY, y int REFERENCES inh_fk_1 ON DELETE CASCADE)" +== 292 +-- truncate_limit: 100 +insert into inh_fk_2 values (11, 1), (22, 2), (33, 3) +-- +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inh_fk_2 VALUES (11, 1), (22, 2), (33, 3)" +== 293 +-- truncate_limit: 100 +create table inh_fk_2_child () inherits (inh_fk_2) +-- +TABLE: name="inh_fk_2_child" schema="" table="inh_fk_2_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_fk_2_child () INHERITS (inh_fk_2)" +== 294 +-- truncate_limit: 100 +insert into inh_fk_2_child values (111, 1), (222, 2) +-- +TABLE: name="inh_fk_2_child" schema="" table="inh_fk_2_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inh_fk_2_child VALUES (111, 1), (222, 2)" +== 295 +-- truncate_limit: 100 +delete from inh_fk_1 where a = 1 +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM inh_fk_1 WHERE a = 1" +== 296 +-- truncate_limit: 100 +select * from inh_fk_1 order by 1 +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inh_fk_1 ORDER BY 1" +== 297 +-- truncate_limit: 100 +select * from inh_fk_2 order by 1, 2 +-- +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inh_fk_2 ORDER BY 1, 2" +== 298 +-- truncate_limit: 100 +drop table inh_fk_1, inh_fk_2, inh_fk_2_child +-- +TABLE: name="inh_fk_1" schema="" table="inh_fk_1" ctx=DDL +TABLE: name="inh_fk_2" schema="" table="inh_fk_2" ctx=DDL +TABLE: name="inh_fk_2_child" schema="" table="inh_fk_2_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inh_fk_1, inh_fk_2, inh_fk_2_child" +== 299 +-- truncate_limit: 100 +-- Test that parent and child CHECK constraints can be created in either order +create table p1(f1 int) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int)" +== 300 +-- truncate_limit: 100 +create table p1_c1() inherits(p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c1 () INHERITS (p1)" +== 301 +-- truncate_limit: 100 +alter table p1 add constraint inh_check_constraint1 check (f1 > 0) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 ADD CONSTRAINT inh_check_constraint1 CHECK (f1 > 0)" +== 302 +-- truncate_limit: 100 +alter table p1_c1 add constraint inh_check_constraint1 check (f1 > 0) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1_c1 ADD CONSTRAINT inh_check_constraint1 CHECK (f1 > 0)" +== 303 +-- truncate_limit: 100 +alter table p1_c1 add constraint inh_check_constraint2 check (f1 < 10) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1_c1 ADD CONSTRAINT inh_check_constraint2 CHECK (f1 < 10)" +== 304 +-- truncate_limit: 100 +alter table p1 add constraint inh_check_constraint2 check (f1 < 10) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 ADD CONSTRAINT inh_check_constraint2 CHECK (f1 < 10)" +== 305 +-- truncate_limit: 100 +select conrelid::regclass::text as relname, conname, conislocal, coninhcount +from pg_constraint where conname like 'inh\_check\_constraint%' +order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conname LIKE E'inh\\\\_check\\\\_constraint%' ORDER BY 1, 2" +== 306 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 307 +-- truncate_limit: 100 +|-- +-- Test DROP behavior of multiply-defined CHECK constraints +|-- +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int CONSTRAINT f1_pos CHECK (f1 > 0))" +== 308 +-- truncate_limit: 100 +create table p1_c1 (f1 int constraint f1_pos CHECK (f1 > 0)) inherits (p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c1 (f1 int CONSTRAINT f1_pos CHECK (f1 > 0)) INHERITS (p1)" +== 309 +-- truncate_limit: 100 +alter table p1_c1 drop constraint f1_pos +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1_c1 DROP CONSTRAINT f1_pos" +== 310 +-- truncate_limit: 100 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 DROP CONSTRAINT f1_pos" +== 311 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 312 +-- truncate_limit: 100 +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int CONSTRAINT f1_pos CHECK (f1 > 0))" +== 313 +-- truncate_limit: 100 +create table p2(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p2 (f1 int CONSTRAINT f1_pos CHECK (f1 > 0))" +== 314 +-- truncate_limit: 100 +create table p1p2_c1 (f1 int) inherits (p1, p2) +-- +TABLE: name="p1p2_c1" schema="" table="p1p2_c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1p2_c1 (f1 int) INHERITS (p1, p2)" +== 315 +-- truncate_limit: 100 +create table p1p2_c2 (f1 int constraint f1_pos CHECK (f1 > 0)) inherits (p1, p2) +-- +TABLE: name="p1p2_c2" schema="" table="p1p2_c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1p2_c2 (f1 int CONSTRAINT f1_pos CHECK (f1 > 0)) INHERITS (p1, p2)" +== 316 +-- truncate_limit: 100 +alter table p2 drop constraint f1_pos +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p2 DROP CONSTRAINT f1_pos" +== 317 +-- truncate_limit: 100 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 DROP CONSTRAINT f1_pos" +== 318 +-- truncate_limit: 100 +drop table p1, p2 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1, p2 CASCADE" +== 319 +-- truncate_limit: 100 +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int CONSTRAINT f1_pos CHECK (f1 > 0))" +== 320 +-- truncate_limit: 100 +create table p1_c1() inherits (p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c1 () INHERITS (p1)" +== 321 +-- truncate_limit: 100 +create table p1_c2() inherits (p1) +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c2 () INHERITS (p1)" +== 322 +-- truncate_limit: 100 +create table p1_c1c2() inherits (p1_c1, p1_c2) +-- +TABLE: name="p1_c1c2" schema="" table="p1_c1c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c1c2 () INHERITS (p1_c1, p1_c2)" +== 323 +-- truncate_limit: 100 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 DROP CONSTRAINT f1_pos" +== 324 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 325 +-- truncate_limit: 100 +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1 (f1 int CONSTRAINT f1_pos CHECK (f1 > 0))" +== 326 +-- truncate_limit: 100 +create table p1_c1() inherits (p1) +-- +TABLE: name="p1_c1" schema="" table="p1_c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c1 () INHERITS (p1)" +== 327 +-- truncate_limit: 100 +create table p1_c2(constraint f1_pos CHECK (f1 > 0)) inherits (p1) +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c2 (CONSTRAINT f1_pos CHECK (f1 > 0)) INHERITS (p1)" +== 328 +-- truncate_limit: 100 +create table p1_c1c2() inherits (p1_c1, p1_c2, p1) +-- +TABLE: name="p1_c1c2" schema="" table="p1_c1c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE p1_c1c2 () INHERITS (p1_c1, p1_c2, p1)" +== 329 +-- truncate_limit: 100 +alter table p1_c2 drop constraint f1_pos +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1_c2 DROP CONSTRAINT f1_pos" +== 330 +-- truncate_limit: 100 +alter table p1 drop constraint f1_pos +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1 DROP CONSTRAINT f1_pos" +== 331 +-- truncate_limit: 100 +alter table p1_c1c2 drop constraint f1_pos +-- +TABLE: name="p1_c1c2" schema="" table="p1_c1c2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1_c1c2 DROP CONSTRAINT f1_pos" +== 332 +-- truncate_limit: 100 +alter table p1_c2 drop constraint f1_pos +-- +TABLE: name="p1_c2" schema="" table="p1_c2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE p1_c2 DROP CONSTRAINT f1_pos" +== 333 +-- truncate_limit: 100 +drop table p1 cascade +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p1 CASCADE" +== 334 +-- truncate_limit: 100 +-- Test that a valid child can have not-valid parent, but not vice versa +create table invalid_check_con(f1 int) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE invalid_check_con (f1 int)" +== 335 +-- truncate_limit: 100 +create table invalid_check_con_child() inherits(invalid_check_con) +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE invalid_check_con_child () INHERITS (invalid_check_con)" +== 336 +-- truncate_limit: 100 +alter table invalid_check_con_child add constraint inh_check_constraint check(f1 > 0) not valid +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE invalid_check_con_child ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0) NOT VALID" +== 337 +-- truncate_limit: 100 +alter table invalid_check_con add constraint inh_check_constraint check(f1 > 0) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE invalid_check_con ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0)" +== 338 +-- truncate_limit: 100 +-- fail +alter table invalid_check_con_child drop constraint inh_check_constraint +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE invalid_check_con_child DROP CONSTRAINT inh_check_constraint" +== 339 +-- truncate_limit: 100 +insert into invalid_check_con values(0) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO invalid_check_con VALUES (0)" +== 340 +-- truncate_limit: 100 +alter table invalid_check_con_child add constraint inh_check_constraint check(f1 > 0) +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE invalid_check_con_child ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0)" +== 341 +-- truncate_limit: 100 +alter table invalid_check_con add constraint inh_check_constraint check(f1 > 0) not valid +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE invalid_check_con ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0) NOT VALID" +== 342 +-- truncate_limit: 100 +insert into invalid_check_con values(0) +-- +TABLE: name="invalid_check_con" schema="" table="invalid_check_con" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO invalid_check_con VALUES (0)" +== 343 +-- truncate_limit: 100 +-- fail +insert into invalid_check_con_child values(0) +-- +TABLE: name="invalid_check_con_child" schema="" table="invalid_check_con_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO invalid_check_con_child VALUES (0)" +== 344 +-- truncate_limit: 100 +-- fail + +select conrelid::regclass::text as relname, conname, + convalidated, conislocal, coninhcount, connoinherit +from pg_constraint where conname like 'inh\_check\_constraint%' +order by 1, 2 +-- +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +FILTER: schema="" table="" column="conname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_constraint WHERE conname LIKE E'inh\\\\_check\\\\_constraint%' ORDER BY 1, 2" +== 345 +-- truncate_limit: 100 +-- We don't drop the invalid_check_con* tables, to test dump/reload with + +|-- +-- Test parameterized append plans for inheritance trees +|-- + +create temp table patest0 (id, x) as + select x, x from generate_series(0,1000) x +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE patest0(id, x) AS SELECT x, x FROM generate_series(0, 1000) x" +== 346 +-- truncate_limit: 100 +create temp table patest1() inherits (patest0) +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE patest1 () INHERITS (patest0)" +== 347 +-- truncate_limit: 100 +insert into patest1 + select x, x from generate_series(0,1000) x +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO patest1 SELECT x, x FROM generate_series(0, 1000) x" +== 348 +-- truncate_limit: 100 +create temp table patest2() inherits (patest0) +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE patest2 () INHERITS (patest0)" +== 349 +-- truncate_limit: 100 +insert into patest2 + select x, x from generate_series(0,1000) x +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO patest2 SELECT x, x FROM generate_series(0, 1000) x" +== 350 +-- truncate_limit: 100 +create index patest0i on patest0(id) +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX patest0i ON patest0 USING btree (id)" +== 351 +-- truncate_limit: 100 +create index patest1i on patest1(id) +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX patest1i ON patest1 USING btree (id)" +== 352 +-- truncate_limit: 100 +create index patest2i on patest2(id) +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX patest2i ON patest2 USING btree (id)" +== 353 +-- truncate_limit: 100 +analyze patest0 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE patest0" +== 354 +-- truncate_limit: 100 +analyze patest1 +-- +TABLE: name="patest1" schema="" table="patest1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE patest1" +== 355 +-- truncate_limit: 100 +analyze patest2 +-- +TABLE: name="patest2" schema="" table="patest2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE patest2" +== 356 +-- truncate_limit: 100 +explain (costs off) +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM patest0 JOIN (SELECT f1 FROM int4_tbl LIMIT 1) ss ON id = f1" +== 357 +-- truncate_limit: 100 +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM patest0 JOIN (SELECT f1 FROM int4_tbl LIMIT 1) ss ON id = f1" +== 358 +-- truncate_limit: 100 +drop index patest2i +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX patest2i" +== 359 +-- truncate_limit: 100 +explain (costs off) +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM patest0 JOIN (SELECT f1 FROM int4_tbl LIMIT 1) ss ON id = f1" +== 360 +-- truncate_limit: 100 +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1 +-- +TABLE: name="patest0" schema="" table="patest0" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM patest0 JOIN (SELECT f1 FROM int4_tbl LIMIT 1) ss ON id = f1" +== 361 +-- truncate_limit: 100 +drop table patest0 cascade +-- +TABLE: name="patest0" schema="" table="patest0" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE patest0 CASCADE" +== 362 +-- truncate_limit: 100 +|-- +-- Test merge-append plans for inheritance trees +|-- + +create table matest0 (id serial primary key, name text) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest0 (id serial PRIMARY KEY, name text)" +== 363 +-- truncate_limit: 100 +create table matest1 (id integer primary key) inherits (matest0) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest1 (id int PRIMARY KEY) INHERITS (matest0)" +== 364 +-- truncate_limit: 100 +create table matest2 (id integer primary key) inherits (matest0) +-- +TABLE: name="matest2" schema="" table="matest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest2 (id int PRIMARY KEY) INHERITS (matest0)" +== 365 +-- truncate_limit: 100 +create table matest3 (id integer primary key) inherits (matest0) +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest3 (id int PRIMARY KEY) INHERITS (matest0)" +== 366 +-- truncate_limit: 100 +create index matest0i on matest0 ((1-id)) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX matest0i ON matest0 USING btree ((1 - id))" +== 367 +-- truncate_limit: 100 +create index matest1i on matest1 ((1-id)) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX matest1i ON matest1 USING btree ((1 - id))" +== 368 +-- truncate_limit: 100 +-- create index matest2i on matest2 ((1-id)); -- intentionally missing +create index matest3i on matest3 ((1-id)) +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX matest3i ON matest3 USING btree ((1 - id))" +== 369 +-- truncate_limit: 100 +insert into matest1 (name) values ('Test 1') +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest1 (name) VALUES ('Test 1')" +== 370 +-- truncate_limit: 100 +insert into matest1 (name) values ('Test 2') +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest1 (name) VALUES ('Test 2')" +== 371 +-- truncate_limit: 100 +insert into matest2 (name) values ('Test 3') +-- +TABLE: name="matest2" schema="" table="matest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest2 (name) VALUES ('Test 3')" +== 372 +-- truncate_limit: 100 +insert into matest2 (name) values ('Test 4') +-- +TABLE: name="matest2" schema="" table="matest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest2 (name) VALUES ('Test 4')" +== 373 +-- truncate_limit: 100 +insert into matest3 (name) values ('Test 5') +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest3 (name) VALUES ('Test 5')" +== 374 +-- truncate_limit: 100 +insert into matest3 (name) values ('Test 6') +-- +TABLE: name="matest3" schema="" table="matest3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest3 (name) VALUES ('Test 6')" +== 375 +-- truncate_limit: 100 +set enable_indexscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 376 +-- truncate_limit: 100 +-- force use of seqscan/sort, so no merge +explain (verbose, costs off) select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM matest0 ORDER BY 1 - id" +== 377 +-- truncate_limit: 100 +select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM matest0 ORDER BY 1 - id" +== 378 +-- truncate_limit: 100 +explain (verbose, costs off) select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT min(1 - id) FROM matest0" +== 379 +-- truncate_limit: 100 +select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(1 - id) FROM matest0" +== 380 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 381 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 382 +-- truncate_limit: 100 +-- plan with fewest seqscans should be merge +set enable_parallel_append = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_append TO OFF" +== 383 +-- truncate_limit: 100 +-- Don't let parallel-append interfere +explain (verbose, costs off) select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM matest0 ORDER BY 1 - id" +== 384 +-- truncate_limit: 100 +select * from matest0 order by 1-id +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM matest0 ORDER BY 1 - id" +== 385 +-- truncate_limit: 100 +explain (verbose, costs off) select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT min(1 - id) FROM matest0" +== 386 +-- truncate_limit: 100 +select min(1-id) from matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(1 - id) FROM matest0" +== 387 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 388 +-- truncate_limit: 100 +reset enable_parallel_append +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_parallel_append" +== 389 +-- truncate_limit: 100 +explain (verbose, costs off) -- bug #18652 +select 1 - id as c from +(select id from matest3 t1 union all select id * 2 from matest3 t2) ss +order by c +-- +TABLE: name="matest3" schema="" table="matest3" ctx=Select +TABLE: name="matest3" schema="" table="matest3" ctx=Select +ALIAS: "t1"="matest3" +ALIAS: "t2"="matest3" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 - id AS c FROM (SELECT id FROM matest3 t1 UNION ALL SELECT ..." +== 390 +-- truncate_limit: 100 +select 1 - id as c from +(select id from matest3 t1 union all select id * 2 from matest3 t2) ss +order by c +-- +TABLE: name="matest3" schema="" table="matest3" ctx=Select +TABLE: name="matest3" schema="" table="matest3" ctx=Select +ALIAS: "t1"="matest3" +ALIAS: "t2"="matest3" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT id FROM matest3 t1 UNION ALL SELECT ... FROM matest3 t2) ss ORDER BY c" +== 391 +-- truncate_limit: 100 +drop table matest0 cascade +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE matest0 CASCADE" +== 392 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest0 (a int, b int, c int, d int)" +== 393 +-- truncate_limit: 100 +create table matest1 () inherits(matest0) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest1 () INHERITS (matest0)" +== 394 +-- truncate_limit: 100 +create index matest0i on matest0 (b, c) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX matest0i ON matest0 USING btree (b, c)" +== 395 +-- truncate_limit: 100 +create index matest1i on matest1 (b, c) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX matest1i ON matest1 USING btree (b, c)" +== 396 +-- truncate_limit: 100 +set enable_nestloop = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 397 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +TABLE: name="matest0" schema="" table="matest0" ctx=Select +ALIAS: "t1"="matest0" +ALIAS: "t2"="matest0" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t2" column="d" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM matest0 t1, matest0 t2 WHERE t1.b = t2.b AND t2.c = t2.d ORD..." +== 398 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 399 +-- truncate_limit: 100 +drop table matest0 cascade +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE matest0 CASCADE" +== 400 +-- truncate_limit: 100 +-- Test a MergeAppend plan where one child requires a sort +create table matest0(a int primary key) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest0 (a int PRIMARY KEY)" +== 401 +-- truncate_limit: 100 +create table matest1() inherits (matest0) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE matest1 () INHERITS (matest0)" +== 402 +-- truncate_limit: 100 +insert into matest0 select generate_series(1, 400) +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest0 SELECT generate_series(1, 400)" +== 403 +-- truncate_limit: 100 +insert into matest1 select generate_series(1, 200) +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO matest1 SELECT generate_series(1, 200)" +== 404 +-- truncate_limit: 100 +analyze matest0 +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE matest0" +== 405 +-- truncate_limit: 100 +analyze matest1 +-- +TABLE: name="matest1" schema="" table="matest1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE matest1" +== 406 +-- truncate_limit: 100 +explain (costs off) +select * from matest0 where a < 100 order by a +-- +TABLE: name="matest0" schema="" table="matest0" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM matest0 WHERE a < 100 ORDER BY a" +== 407 +-- truncate_limit: 100 +drop table matest0 cascade +-- +TABLE: name="matest0" schema="" table="matest0" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE matest0 CASCADE" +== 408 +-- truncate_limit: 100 +|-- +-- Test merge-append for UNION ALL append relations +|-- + +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 409 +-- truncate_limit: 100 +set enable_indexscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 410 +-- truncate_limit: 100 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 411 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous FROM tenk1 UNION ALL SELECT thousand, thousand FROM..." +== 412 +-- truncate_limit: 100 +explain (costs off) +SELECT thousand, tenthous, thousand+tenthous AS x FROM tenk1 +UNION ALL +SELECT 42, 42, hundred FROM tenk1 +ORDER BY thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous, thousand + tenthous AS x FROM tenk1 UNION ALL SELE..." +== 413 +-- truncate_limit: 100 +explain (costs off) +SELECT thousand, tenthous FROM tenk1 +UNION ALL +SELECT thousand, random()::integer FROM tenk1 +ORDER BY thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous FROM tenk1 UNION ALL SELECT thousand, random()::int..." +== 414 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT min(x) FROM (SELECT unique1 AS x FROM tenk1 a UNION ALL SELECT unique2..." +== 415 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT min(y) FROM (SELECT unique1 AS x, unique1 AS y FROM tenk1 a UNION ALL ..." +== 416 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x, y FROM (SELECT thousand AS x, tenthous AS y FROM tenk1 a UNION ALL ..." +== 417 +-- truncate_limit: 100 +-- 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) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ARRAY(SELECT f.i FROM ((SELECT d + g.i FROM generate_series(4, 30, 3) ..." +== 418 +-- truncate_limit: 100 +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) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 3) g(i)" +== 419 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 420 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 421 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 422 +-- truncate_limit: 100 +|-- +-- Check handling of MULTIEXPR SubPlans in inherited updates +|-- +create table inhpar(f1 int, f2 name) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhpar (f1 int, f2 name)" +== 423 +-- truncate_limit: 100 +create table inhcld(f2 name, f1 int) +-- +TABLE: name="inhcld" schema="" table="inhcld" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhcld (f2 name, f1 int)" +== 424 +-- truncate_limit: 100 +alter table inhcld inherit inhpar +-- +TABLE: name="inhcld" schema="" table="inhcld" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inhcld INHERIT inhpar" +== 425 +-- truncate_limit: 100 +insert into inhpar select x, x::text from generate_series(1,5) x +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhpar SELECT x, x::text FROM generate_series(1, 5) x" +== 426 +-- truncate_limit: 100 +insert into inhcld select x::text, x from generate_series(6,10) x +-- +TABLE: name="inhcld" schema="" table="inhcld" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhcld SELECT x::text, x FROM generate_series(6, 10) x" +== 427 +-- truncate_limit: 100 +explain (verbose, costs off) +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE inhpar i SET (f1, f2) = (SELECT i.f1, i.f2 || '-' FROM int4_t..." +== 428 +-- truncate_limit: 100 +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE inhpar i SET (f1, f2) = (SELECT i.f1, i.f2 || '-' FROM int4_tbl LIMIT 1)" +== 429 +-- truncate_limit: 100 +select * from inhpar +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inhpar" +== 430 +-- truncate_limit: 100 +drop table inhpar cascade +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhpar CASCADE" +== 431 +-- truncate_limit: 100 +|-- +-- And the same for partitioned cases +|-- +create table inhpar(f1 int primary key, f2 name) partition by range (f1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhpar (f1 int PRIMARY KEY, f2 name) PARTITION BY RANGE (f1)" +== 432 +-- truncate_limit: 100 +create table inhcld1(f2 name, f1 int primary key) +-- +TABLE: name="inhcld1" schema="" table="inhcld1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhcld1 (f2 name, f1 int PRIMARY KEY)" +== 433 +-- truncate_limit: 100 +create table inhcld2(f1 int primary key, f2 name) +-- +TABLE: name="inhcld2" schema="" table="inhcld2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inhcld2 (f1 int PRIMARY KEY, f2 name)" +== 434 +-- truncate_limit: 100 +alter table inhpar attach partition inhcld1 for values from (1) to (5) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inhpar ATTACH PARTITION inhcld1 FOR VALUES FROM (1) TO (5)" +== 435 +-- truncate_limit: 100 +alter table inhpar attach partition inhcld2 for values from (5) to (100) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inhpar ATTACH PARTITION inhcld2 FOR VALUES FROM (5) TO (100)" +== 436 +-- truncate_limit: 100 +insert into inhpar select x, x::text from generate_series(1,10) x +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhpar SELECT x, x::text FROM generate_series(1, 10) x" +== 437 +-- truncate_limit: 100 +explain (verbose, costs off) +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE inhpar i SET (f1, f2) = (SELECT i.f1, i.f2 || '-' FROM int4_t..." +== 438 +-- truncate_limit: 100 +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1) +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="inhpar" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE inhpar i SET (f1, f2) = (SELECT i.f1, i.f2 || '-' FROM int4_tbl LIMIT 1)" +== 439 +-- truncate_limit: 100 +select * from inhpar +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inhpar" +== 440 +-- truncate_limit: 100 +-- Also check ON CONFLICT +insert into inhpar as i values (3), (7) on conflict (f1) + do update set (f1, f2) = (select i.f1, i.f2 || '+') +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DML +ALIAS: "i"="inhpar" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inhpar AS i VALUES (3), (7) ON CONFLICT (f1) DO UPDATE SET (f1, f2) = (SELECT ...)" +== 441 +-- truncate_limit: 100 +select * from inhpar order by f1 +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inhpar ORDER BY f1" +== 442 +-- truncate_limit: 100 +-- tuple order might be unstable here + +drop table inhpar cascade +-- +TABLE: name="inhpar" schema="" table="inhpar" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inhpar CASCADE" +== 443 +-- truncate_limit: 100 +|-- +-- Check handling of a constant-null CHECK constraint +|-- +create table cnullparent (f1 int) +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cnullparent (f1 int)" +== 444 +-- truncate_limit: 100 +create table cnullchild (check (f1 = 1 or f1 = null)) inherits(cnullparent) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cnullchild (CHECK (f1 = 1 OR f1 = NULL)) INHERITS (cnullparent)" +== 445 +-- truncate_limit: 100 +insert into cnullchild values(1) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cnullchild VALUES (1)" +== 446 +-- truncate_limit: 100 +insert into cnullchild values(2) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cnullchild VALUES (2)" +== 447 +-- truncate_limit: 100 +insert into cnullchild values(null) +-- +TABLE: name="cnullchild" schema="" table="cnullchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cnullchild VALUES (NULL)" +== 448 +-- truncate_limit: 100 +select * from cnullparent +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cnullparent" +== 449 +-- truncate_limit: 100 +select * from cnullparent where f1 = 2 +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cnullparent WHERE f1 = 2" +== 450 +-- truncate_limit: 100 +drop table cnullparent cascade +-- +TABLE: name="cnullparent" schema="" table="cnullparent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cnullparent CASCADE" +== 451 +-- truncate_limit: 100 +|-- +-- Mixed ownership inheritance tree +|-- +create role regress_alice +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_alice" +== 452 +-- truncate_limit: 100 +create role regress_bob +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_bob" +== 453 +-- truncate_limit: 100 +grant all on schema public to regress_alice, regress_bob +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON SCHEMA public TO regress_alice, regress_bob" +== 454 +-- truncate_limit: 100 +grant regress_alice to regress_bob +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_alice TO regress_bob" +== 455 +-- truncate_limit: 100 +set session authorization regress_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alice" +== 456 +-- truncate_limit: 100 +create table inh_parent (a int not null) +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_parent (a int NOT NULL)" +== 457 +-- truncate_limit: 100 +set session authorization regress_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_bob" +== 458 +-- truncate_limit: 100 +create table inh_child () inherits (inh_parent) +-- +TABLE: name="inh_child" schema="" table="inh_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_child () INHERITS (inh_parent)" +== 459 +-- truncate_limit: 100 +set session authorization regress_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alice" +== 460 +-- truncate_limit: 100 +-- alice can't do this: she doesn't own inh_child +alter table inh_parent alter a drop not null +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inh_parent ALTER COLUMN a DROP NOT NULL" +== 461 +-- truncate_limit: 100 +set session authorization regress_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_bob" +== 462 +-- truncate_limit: 100 +alter table inh_parent alter a drop not null +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE inh_parent ALTER COLUMN a DROP NOT NULL" +== 463 +-- truncate_limit: 100 +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 464 +-- truncate_limit: 100 +drop table inh_parent, inh_child +-- +TABLE: name="inh_parent" schema="" table="inh_parent" ctx=DDL +TABLE: name="inh_child" schema="" table="inh_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inh_parent, inh_child" +== 465 +-- truncate_limit: 100 +revoke all on schema public from regress_alice, regress_bob +-- +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON SCHEMA public FROM regress_alice, regress_bob" +== 466 +-- truncate_limit: 100 +drop role regress_alice, regress_bob +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_alice, regress_bob" +== 467 +-- truncate_limit: 100 +|-- +-- Check use of temporary tables with inheritance trees +|-- +create table inh_perm_parent (a1 int) +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_perm_parent (a1 int)" +== 468 +-- truncate_limit: 100 +create temp table inh_temp_parent (a1 int) +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE inh_temp_parent (a1 int)" +== 469 +-- truncate_limit: 100 +create temp table inh_temp_child () inherits (inh_perm_parent) +-- +TABLE: name="inh_temp_child" schema="" table="inh_temp_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE inh_temp_child () INHERITS (inh_perm_parent)" +== 470 +-- truncate_limit: 100 +-- ok +create table inh_perm_child () inherits (inh_temp_parent) +-- +TABLE: name="inh_perm_child" schema="" table="inh_perm_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_perm_child () INHERITS (inh_temp_parent)" +== 471 +-- truncate_limit: 100 +-- error +create temp table inh_temp_child_2 () inherits (inh_temp_parent) +-- +TABLE: name="inh_temp_child_2" schema="" table="inh_temp_child_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE inh_temp_child_2 () INHERITS (inh_temp_parent)" +== 472 +-- truncate_limit: 100 +-- ok +insert into inh_perm_parent values (1) +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inh_perm_parent VALUES (1)" +== 473 +-- truncate_limit: 100 +insert into inh_temp_parent values (2) +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inh_temp_parent VALUES (2)" +== 474 +-- truncate_limit: 100 +insert into inh_temp_child values (3) +-- +TABLE: name="inh_temp_child" schema="" table="inh_temp_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inh_temp_child VALUES (3)" +== 475 +-- truncate_limit: 100 +insert into inh_temp_child_2 values (4) +-- +TABLE: name="inh_temp_child_2" schema="" table="inh_temp_child_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inh_temp_child_2 VALUES (4)" +== 476 +-- truncate_limit: 100 +select tableoid::regclass, a1 from inh_perm_parent +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, a1 FROM inh_perm_parent" +== 477 +-- truncate_limit: 100 +select tableoid::regclass, a1 from inh_temp_parent +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, a1 FROM inh_temp_parent" +== 478 +-- truncate_limit: 100 +drop table inh_perm_parent cascade +-- +TABLE: name="inh_perm_parent" schema="" table="inh_perm_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inh_perm_parent CASCADE" +== 479 +-- truncate_limit: 100 +drop table inh_temp_parent cascade +-- +TABLE: name="inh_temp_parent" schema="" table="inh_temp_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inh_temp_parent CASCADE" +== 480 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted (a varchar) PARTITION BY LIST (a)" +== 481 +-- truncate_limit: 100 +create table part_ab_cd partition of list_parted for values in ('ab', 'cd') +-- +TABLE: name="part_ab_cd" schema="" table="part_ab_cd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ab_cd PARTITION OF list_parted FOR VALUES IN ('ab', 'cd')" +== 482 +-- truncate_limit: 100 +create table part_ef_gh partition of list_parted for values in ('ef', 'gh') +-- +TABLE: name="part_ef_gh" schema="" table="part_ef_gh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ef_gh PARTITION OF list_parted FOR VALUES IN ('ef', 'gh')" +== 483 +-- truncate_limit: 100 +create table part_null_xy partition of list_parted for values in (null, 'xy') +-- +TABLE: name="part_null_xy" schema="" table="part_null_xy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_null_xy PARTITION OF list_parted FOR VALUES IN (NULL, 'xy')" +== 484 +-- truncate_limit: 100 +explain (costs off) select * from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM list_parted" +== 485 +-- truncate_limit: 100 +explain (costs off) select * from list_parted where a is null +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM list_parted WHERE a IS NULL" +== 486 +-- truncate_limit: 100 +explain (costs off) select * from list_parted where a is not null +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM list_parted WHERE a IS NOT NULL" +== 487 +-- truncate_limit: 100 +explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM list_parted WHERE a IN ('ab', 'cd', 'ef')" +== 488 +-- truncate_limit: 100 +explain (costs off) select * from list_parted where a = 'ab' or a in (null, 'cd') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM list_parted WHERE a = 'ab' OR a IN (NULL, 'cd')" +== 489 +-- truncate_limit: 100 +explain (costs off) select * from list_parted where a = 'ab' +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM list_parted WHERE a = 'ab'" +== 490 +-- truncate_limit: 100 +create table range_list_parted ( + a int, + b char(2) +) partition by range (a) +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_list_parted (a int, b char(2)) PARTITION BY RANGE (a)" +== 491 +-- truncate_limit: 100 +create table part_1_10 partition of range_list_parted for values from (1) to (10) partition by list (b) +-- +TABLE: name="part_1_10" schema="" table="part_1_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_1_10 PARTITION OF range_list_parted FOR VALUES FROM (1) TO (10) PARTITION BY LI..." +== 492 +-- truncate_limit: 100 +create table part_1_10_ab partition of part_1_10 for values in ('ab') +-- +TABLE: name="part_1_10_ab" schema="" table="part_1_10_ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_1_10_ab PARTITION OF part_1_10 FOR VALUES IN ('ab')" +== 493 +-- truncate_limit: 100 +create table part_1_10_cd partition of part_1_10 for values in ('cd') +-- +TABLE: name="part_1_10_cd" schema="" table="part_1_10_cd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_1_10_cd PARTITION OF part_1_10 FOR VALUES IN ('cd')" +== 494 +-- truncate_limit: 100 +create table part_10_20 partition of range_list_parted for values from (10) to (20) partition by list (b) +-- +TABLE: name="part_10_20" schema="" table="part_10_20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_10_20 PARTITION OF range_list_parted FOR VALUES FROM (10) TO (20) PARTITION BY ..." +== 495 +-- truncate_limit: 100 +create table part_10_20_ab partition of part_10_20 for values in ('ab') +-- +TABLE: name="part_10_20_ab" schema="" table="part_10_20_ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_10_20_ab PARTITION OF part_10_20 FOR VALUES IN ('ab')" +== 496 +-- truncate_limit: 100 +create table part_10_20_cd partition of part_10_20 for values in ('cd') +-- +TABLE: name="part_10_20_cd" schema="" table="part_10_20_cd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_10_20_cd PARTITION OF part_10_20 FOR VALUES IN ('cd')" +== 497 +-- truncate_limit: 100 +create table part_21_30 partition of range_list_parted for values from (21) to (30) partition by list (b) +-- +TABLE: name="part_21_30" schema="" table="part_21_30" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_21_30 PARTITION OF range_list_parted FOR VALUES FROM (21) TO (30) PARTITION BY ..." +== 498 +-- truncate_limit: 100 +create table part_21_30_ab partition of part_21_30 for values in ('ab') +-- +TABLE: name="part_21_30_ab" schema="" table="part_21_30_ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_21_30_ab PARTITION OF part_21_30 FOR VALUES IN ('ab')" +== 499 +-- truncate_limit: 100 +create table part_21_30_cd partition of part_21_30 for values in ('cd') +-- +TABLE: name="part_21_30_cd" schema="" table="part_21_30_cd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_21_30_cd PARTITION OF part_21_30 FOR VALUES IN ('cd')" +== 500 +-- truncate_limit: 100 +create table part_40_inf partition of range_list_parted for values from (40) to (maxvalue) partition by list (b) +-- +TABLE: name="part_40_inf" schema="" table="part_40_inf" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_40_inf PARTITION OF range_list_parted FOR VALUES FROM (40) TO (maxvalue) PARTIT..." +== 501 +-- truncate_limit: 100 +create table part_40_inf_ab partition of part_40_inf for values in ('ab') +-- +TABLE: name="part_40_inf_ab" schema="" table="part_40_inf_ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_40_inf_ab PARTITION OF part_40_inf FOR VALUES IN ('ab')" +== 502 +-- truncate_limit: 100 +create table part_40_inf_cd partition of part_40_inf for values in ('cd') +-- +TABLE: name="part_40_inf_cd" schema="" table="part_40_inf_cd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_40_inf_cd PARTITION OF part_40_inf FOR VALUES IN ('cd')" +== 503 +-- truncate_limit: 100 +create table part_40_inf_null partition of part_40_inf for values in (null) +-- +TABLE: name="part_40_inf_null" schema="" table="part_40_inf_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_40_inf_null PARTITION OF part_40_inf FOR VALUES IN (NULL)" +== 504 +-- truncate_limit: 100 +explain (costs off) select * from range_list_parted +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted" +== 505 +-- truncate_limit: 100 +explain (costs off) select * from range_list_parted where a = 5 +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted WHERE a = 5" +== 506 +-- truncate_limit: 100 +explain (costs off) select * from range_list_parted where b = 'ab' +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted WHERE b = 'ab'" +== 507 +-- truncate_limit: 100 +explain (costs off) select * from range_list_parted where a between 3 and 23 and b in ('ab') +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted WHERE a BETWEEN 3 AND 23 AND b IN ('ab')" +== 508 +-- truncate_limit: 100 +/* Should select no rows because range partition key cannot be null */ +explain (costs off) select * from range_list_parted where a is null +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted WHERE a IS NULL" +== 509 +-- truncate_limit: 100 +/* Should only select rows from the null-accepting partition */ +explain (costs off) select * from range_list_parted where b is null +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted WHERE b IS NULL" +== 510 +-- truncate_limit: 100 +explain (costs off) select * from range_list_parted where a is not null and a < 67 +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted WHERE a IS NOT NULL AND a < 67" +== 511 +-- truncate_limit: 100 +explain (costs off) select * from range_list_parted where a >= 30 +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_list_parted WHERE a >= 30" +== 512 +-- truncate_limit: 100 +drop table list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE list_parted" +== 513 +-- truncate_limit: 100 +drop table range_list_parted +-- +TABLE: name="range_list_parted" schema="" table="range_list_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE range_list_parted" +== 514 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted (a int, b int, c int) PARTITION BY RANGE (a, (abs(b)), c)" +== 515 +-- truncate_limit: 100 +create table mcrparted_def partition of mcrparted default +-- +TABLE: name="mcrparted_def" schema="" table="mcrparted_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted_def PARTITION OF mcrparted DEFAULT" +== 516 +-- truncate_limit: 100 +create table mcrparted0 partition of mcrparted for values from (minvalue, minvalue, minvalue) to (1, 1, 1) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted0 PARTITION OF mcrparted FOR VALUES FROM (minvalue, minvalue, minvalue) TO ..." +== 517 +-- truncate_limit: 100 +create table mcrparted1 partition of mcrparted for values from (1, 1, 1) to (10, 5, 10) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted1 PARTITION OF mcrparted FOR VALUES FROM (1, 1, 1) TO (10, 5, 10)" +== 518 +-- truncate_limit: 100 +create table mcrparted2 partition of mcrparted for values from (10, 5, 10) to (10, 10, 10) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted2 PARTITION OF mcrparted FOR VALUES FROM (10, 5, 10) TO (10, 10, 10)" +== 519 +-- truncate_limit: 100 +create table mcrparted3 partition of mcrparted for values from (11, 1, 1) to (20, 10, 10) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted3 PARTITION OF mcrparted FOR VALUES FROM (11, 1, 1) TO (20, 10, 10)" +== 520 +-- truncate_limit: 100 +create table mcrparted4 partition of mcrparted for values from (20, 10, 10) to (20, 20, 20) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted4 PARTITION OF mcrparted FOR VALUES FROM (20, 10, 10) TO (20, 20, 20)" +== 521 +-- truncate_limit: 100 +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted5 PARTITION OF mcrparted FOR VALUES FROM (20, 20, 20) TO (maxvalue, maxvalu..." +== 522 +-- truncate_limit: 100 +explain (costs off) select * from mcrparted where a = 0 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a = 0" +== 523 +-- truncate_limit: 100 +-- scans mcrparted0, mcrparted_def +explain (costs off) select * from mcrparted where a = 10 and abs(b) < 5 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a = 10 AND abs(b) < 5" +== 524 +-- truncate_limit: 100 +-- scans mcrparted1, mcrparted_def +explain (costs off) select * from mcrparted where a = 10 and abs(b) = 5 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a = 10 AND abs(b) = 5" +== 525 +-- truncate_limit: 100 +-- scans mcrparted1, mcrparted2, mcrparted_def +explain (costs off) select * from mcrparted where abs(b) = 5 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE abs(b) = 5" +== 526 +-- truncate_limit: 100 +-- scans all partitions +explain (costs off) select * from mcrparted where a > -1 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a > -1" +== 527 +-- truncate_limit: 100 +-- scans all partitions +explain (costs off) select * from mcrparted where a = 20 and abs(b) = 10 and c > 10 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a = 20 AND abs(b) = 10 AND c > 10" +== 528 +-- truncate_limit: 100 +-- scans mcrparted4 +explain (costs off) select * from mcrparted where a = 20 and c > 20 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a = 20 AND c > 20" +== 529 +-- truncate_limit: 100 +-- scans mcrparted3, mcrparte4, mcrparte5, mcrparted_def + +-- check that partitioned table Appends cope with being referenced in +-- subplans +create table parted_minmax (a int, b varchar(16)) partition by range (a) +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_minmax (a int, b varchar(16)) PARTITION BY RANGE (a)" +== 530 +-- truncate_limit: 100 +create table parted_minmax1 partition of parted_minmax for values from (1) to (10) +-- +TABLE: name="parted_minmax1" schema="" table="parted_minmax1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_minmax1 PARTITION OF parted_minmax FOR VALUES FROM (1) TO (10)" +== 531 +-- truncate_limit: 100 +create index parted_minmax1i on parted_minmax1 (a, b) +-- +TABLE: name="parted_minmax1" schema="" table="parted_minmax1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX parted_minmax1i ON parted_minmax1 USING btree (a, b)" +== 532 +-- truncate_limit: 100 +insert into parted_minmax values (1,'12345') +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_minmax VALUES (1, '12345')" +== 533 +-- truncate_limit: 100 +explain (costs off) select min(a), max(a) from parted_minmax where b = '12345' +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT min(a), max(a) FROM parted_minmax WHERE b = '12345'" +== 534 +-- truncate_limit: 100 +select min(a), max(a) from parted_minmax where b = '12345' +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT min(a), max(a) FROM parted_minmax WHERE b = '12345'" +== 535 +-- truncate_limit: 100 +drop table parted_minmax +-- +TABLE: name="parted_minmax" schema="" table="parted_minmax" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_minmax" +== 536 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX mcrparted_a_abs_c_idx ON mcrparted USING btree (a, abs(b), c)" +== 537 +-- truncate_limit: 100 +-- MergeAppend must be used when a default partition exists +explain (costs off) select * from mcrparted order by a, abs(b), c +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted ORDER BY a, abs(b), c" +== 538 +-- truncate_limit: 100 +drop table mcrparted_def +-- +TABLE: name="mcrparted_def" schema="" table="mcrparted_def" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcrparted_def" +== 539 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted ORDER BY a, abs(b), c" +== 540 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted ORDER BY a DESC, abs(b) DESC, c DESC" +== 541 +-- truncate_limit: 100 +-- check that Append plan is used containing a MergeAppend for sub-partitions +-- that are unordered. +drop table mcrparted5 +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcrparted5" +== 542 +-- truncate_limit: 100 +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) partition by list (a) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted5 PARTITION OF mcrparted FOR VALUES FROM (20, 20, 20) TO (maxvalue, maxvalu..." +== 543 +-- truncate_limit: 100 +create table mcrparted5a partition of mcrparted5 for values in(20) +-- +TABLE: name="mcrparted5a" schema="" table="mcrparted5a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted5a PARTITION OF mcrparted5 FOR VALUES IN (20)" +== 544 +-- truncate_limit: 100 +create table mcrparted5_def partition of mcrparted5 default +-- +TABLE: name="mcrparted5_def" schema="" table="mcrparted5_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted5_def PARTITION OF mcrparted5 DEFAULT" +== 545 +-- truncate_limit: 100 +explain (costs off) select * from mcrparted order by a, abs(b), c +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted ORDER BY a, abs(b), c" +== 546 +-- truncate_limit: 100 +drop table mcrparted5_def +-- +TABLE: name="mcrparted5_def" schema="" table="mcrparted5_def" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcrparted5_def" +== 547 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, abs(b) FROM mcrparted ORDER BY a, abs(b), c" +== 548 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a < 20 ORDER BY a, abs(b), c" +== 549 +-- truncate_limit: 100 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 550 +-- truncate_limit: 100 +set enable_sort to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 551 +-- truncate_limit: 100 +create table mclparted (a int) partition by list(a) +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted (a int) PARTITION BY LIST (a)" +== 552 +-- truncate_limit: 100 +create table mclparted1 partition of mclparted for values in(1) +-- +TABLE: name="mclparted1" schema="" table="mclparted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted1 PARTITION OF mclparted FOR VALUES IN (1)" +== 553 +-- truncate_limit: 100 +create table mclparted2 partition of mclparted for values in(2) +-- +TABLE: name="mclparted2" schema="" table="mclparted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted2 PARTITION OF mclparted FOR VALUES IN (2)" +== 554 +-- truncate_limit: 100 +create index on mclparted (a) +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON mclparted USING btree (a)" +== 555 +-- truncate_limit: 100 +-- Ensure an Append is used for a list partition with an order by. +explain (costs off) select * from mclparted order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted ORDER BY a" +== 556 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="mclparted3_5" schema="" table="mclparted3_5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted3_5 PARTITION OF mclparted FOR VALUES IN (3, 5)" +== 557 +-- truncate_limit: 100 +create table mclparted4 partition of mclparted for values in(4) +-- +TABLE: name="mclparted4" schema="" table="mclparted4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted4 PARTITION OF mclparted FOR VALUES IN (4)" +== 558 +-- truncate_limit: 100 +explain (costs off) select * from mclparted order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted ORDER BY a" +== 559 +-- truncate_limit: 100 +explain (costs off) select * from mclparted where a in(3,4,5) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted WHERE a IN (3, 4, 5) ORDER BY a" +== 560 +-- truncate_limit: 100 +-- Introduce a NULL and DEFAULT partition so we can test more complex cases +create table mclparted_null partition of mclparted for values in(null) +-- +TABLE: name="mclparted_null" schema="" table="mclparted_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted_null PARTITION OF mclparted FOR VALUES IN (NULL)" +== 561 +-- truncate_limit: 100 +create table mclparted_def partition of mclparted default +-- +TABLE: name="mclparted_def" schema="" table="mclparted_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted_def PARTITION OF mclparted DEFAULT" +== 562 +-- truncate_limit: 100 +-- Append can be used providing we don't scan the interleaved partition +explain (costs off) select * from mclparted where a in(1,2,4) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted WHERE a IN (1, 2, 4) ORDER BY a" +== 563 +-- truncate_limit: 100 +explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted WHERE a IN (1, 2, 4) OR a IS NULL ORDER BY a" +== 564 +-- truncate_limit: 100 +-- Test a more complex case where the NULL partition allows some other value +drop table mclparted_null +-- +TABLE: name="mclparted_null" schema="" table="mclparted_null" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mclparted_null" +== 565 +-- truncate_limit: 100 +create table mclparted_0_null partition of mclparted for values in(0,null) +-- +TABLE: name="mclparted_0_null" schema="" table="mclparted_0_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mclparted_0_null PARTITION OF mclparted FOR VALUES IN (0, NULL)" +== 566 +-- truncate_limit: 100 +-- Ensure MergeAppend is used since 0 and NULLs are in the same partition. +explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted WHERE a IN (1, 2, 4) OR a IS NULL ORDER BY a" +== 567 +-- truncate_limit: 100 +explain (costs off) select * from mclparted where a in(0,1,2,4) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted WHERE a IN (0, 1, 2, 4) ORDER BY a" +== 568 +-- truncate_limit: 100 +-- Ensure Append is used when the null partition is pruned +explain (costs off) select * from mclparted where a in(1,2,4) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted WHERE a IN (1, 2, 4) ORDER BY a" +== 569 +-- truncate_limit: 100 +-- Ensure MergeAppend is used when the default partition is not pruned +explain (costs off) select * from mclparted where a in(1,2,4,100) order by a +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mclparted WHERE a IN (1, 2, 4, 100) ORDER BY a" +== 570 +-- truncate_limit: 100 +drop table mclparted +-- +TABLE: name="mclparted" schema="" table="mclparted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mclparted" +== 571 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 572 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 573 +-- truncate_limit: 100 +-- Ensure subplans which don't have a path with the correct pathkeys get +-- sorted correctly. +drop index mcrparted_a_abs_c_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX mcrparted_a_abs_c_idx" +== 574 +-- truncate_limit: 100 +create index on mcrparted1 (a, abs(b), c) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON mcrparted1 USING btree (a, abs(b), c)" +== 575 +-- truncate_limit: 100 +create index on mcrparted2 (a, abs(b), c) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON mcrparted2 USING btree (a, abs(b), c)" +== 576 +-- truncate_limit: 100 +create index on mcrparted3 (a, abs(b), c) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON mcrparted3 USING btree (a, abs(b), c)" +== 577 +-- truncate_limit: 100 +create index on mcrparted4 (a, abs(b), c) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON mcrparted4 USING btree (a, abs(b), c)" +== 578 +-- truncate_limit: 100 +explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c limit 1 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a < 20 ORDER BY a, abs(b), c LIMIT 1" +== 579 +-- truncate_limit: 100 +set enable_bitmapscan = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO 0" +== 580 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mcrparted WHERE a = 10 ORDER BY a, abs(b), c" +== 581 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 582 +-- truncate_limit: 100 +drop table mcrparted +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcrparted" +== 583 +-- truncate_limit: 100 +-- Ensure LIST partitions allow an Append to be used instead of a MergeAppend +create table bool_lp (b bool) partition by list(b) +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_lp (b bool) PARTITION BY LIST (b)" +== 584 +-- truncate_limit: 100 +create table bool_lp_true partition of bool_lp for values in(true) +-- +TABLE: name="bool_lp_true" schema="" table="bool_lp_true" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_lp_true PARTITION OF bool_lp FOR VALUES IN (true)" +== 585 +-- truncate_limit: 100 +create table bool_lp_false partition of bool_lp for values in(false) +-- +TABLE: name="bool_lp_false" schema="" table="bool_lp_false" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_lp_false PARTITION OF bool_lp FOR VALUES IN (false)" +== 586 +-- truncate_limit: 100 +create index on bool_lp (b) +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON bool_lp USING btree (b)" +== 587 +-- truncate_limit: 100 +explain (costs off) select * from bool_lp order by b +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM bool_lp ORDER BY b" +== 588 +-- truncate_limit: 100 +drop table bool_lp +-- +TABLE: name="bool_lp" schema="" table="bool_lp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bool_lp" +== 589 +-- truncate_limit: 100 +-- Ensure const bool quals can be properly detected as redundant +create table bool_rp (b bool, a int) partition by range(b,a) +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_rp (b bool, a int) PARTITION BY RANGE (b, a)" +== 590 +-- truncate_limit: 100 +create table bool_rp_false_1k partition of bool_rp for values from (false,0) to (false,1000) +-- +TABLE: name="bool_rp_false_1k" schema="" table="bool_rp_false_1k" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_rp_false_1k PARTITION OF bool_rp FOR VALUES FROM (false, 0) TO (false, 1000)" +== 591 +-- truncate_limit: 100 +create table bool_rp_true_1k partition of bool_rp for values from (true,0) to (true,1000) +-- +TABLE: name="bool_rp_true_1k" schema="" table="bool_rp_true_1k" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_rp_true_1k PARTITION OF bool_rp FOR VALUES FROM (true, 0) TO (true, 1000)" +== 592 +-- truncate_limit: 100 +create table bool_rp_false_2k partition of bool_rp for values from (false,1000) to (false,2000) +-- +TABLE: name="bool_rp_false_2k" schema="" table="bool_rp_false_2k" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_rp_false_2k PARTITION OF bool_rp FOR VALUES FROM (false, 1000) TO (false, 2000)" +== 593 +-- truncate_limit: 100 +create table bool_rp_true_2k partition of bool_rp for values from (true,1000) to (true,2000) +-- +TABLE: name="bool_rp_true_2k" schema="" table="bool_rp_true_2k" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bool_rp_true_2k PARTITION OF bool_rp FOR VALUES FROM (true, 1000) TO (true, 2000)" +== 594 +-- truncate_limit: 100 +create index on bool_rp (b,a) +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON bool_rp USING btree (b, a)" +== 595 +-- truncate_limit: 100 +explain (costs off) select * from bool_rp where b = true order by b,a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM bool_rp WHERE b = true ORDER BY b, a" +== 596 +-- truncate_limit: 100 +explain (costs off) select * from bool_rp where b = false order by b,a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM bool_rp WHERE b = false ORDER BY b, a" +== 597 +-- truncate_limit: 100 +explain (costs off) select * from bool_rp where b = true order by a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM bool_rp WHERE b = true ORDER BY a" +== 598 +-- truncate_limit: 100 +explain (costs off) select * from bool_rp where b = false order by a +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM bool_rp WHERE b = false ORDER BY a" +== 599 +-- truncate_limit: 100 +drop table bool_rp +-- +TABLE: name="bool_rp" schema="" table="bool_rp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bool_rp" +== 600 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted (a int, b int, c int) PARTITION BY RANGE (a, b)" +== 601 +-- truncate_limit: 100 +create table range_parted1 partition of range_parted for values from (0,0) to (10,10) +-- +TABLE: name="range_parted1" schema="" table="range_parted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted1 PARTITION OF range_parted FOR VALUES FROM (0, 0) TO (10, 10)" +== 602 +-- truncate_limit: 100 +create table range_parted2 partition of range_parted for values from (10,10) to (20,20) +-- +TABLE: name="range_parted2" schema="" table="range_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted2 PARTITION OF range_parted FOR VALUES FROM (10, 10) TO (20, 20)" +== 603 +-- truncate_limit: 100 +create index on range_parted (a,b,c) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON range_parted USING btree (a, b, c)" +== 604 +-- truncate_limit: 100 +explain (costs off) select * from range_parted order by a,b,c +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_parted ORDER BY a, b, c" +== 605 +-- truncate_limit: 100 +explain (costs off) select * from range_parted order by a desc,b desc,c desc +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM range_parted ORDER BY a DESC, b DESC, c DESC" +== 606 +-- truncate_limit: 100 +drop table range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE range_parted" +== 607 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE permtest_parent (a int, b text, c text) PARTITION BY LIST (a)" +== 608 +-- truncate_limit: 100 +create table permtest_child (b text, c text, a int) partition by list (b) +-- +TABLE: name="permtest_child" schema="" table="permtest_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE permtest_child (b text, c text, a int) PARTITION BY LIST (b)" +== 609 +-- truncate_limit: 100 +create table permtest_grandchild (c text, b text, a int) +-- +TABLE: name="permtest_grandchild" schema="" table="permtest_grandchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE permtest_grandchild (c text, b text, a int)" +== 610 +-- truncate_limit: 100 +alter table permtest_child attach partition permtest_grandchild for values in ('a') +-- +TABLE: name="permtest_child" schema="" table="permtest_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE permtest_child ATTACH PARTITION permtest_grandchild FOR VALUES IN ('a')" +== 611 +-- truncate_limit: 100 +alter table permtest_parent attach partition permtest_child for values in (1) +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE permtest_parent ATTACH PARTITION permtest_child FOR VALUES IN (1)" +== 612 +-- truncate_limit: 100 +create index on permtest_parent (left(c, 3)) +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +FUNCTION: name="left" function="left" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON permtest_parent USING btree (\"left\"(c, 3))" +== 613 +-- truncate_limit: 100 +insert into permtest_parent + select 1, 'a', left(fipshash(i::text), 5) from generate_series(0, 100) i +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DML +FUNCTION: name="left" function="left" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO permtest_parent SELECT ... FROM generate_series(0, 100) i" +== 614 +-- truncate_limit: 100 +analyze permtest_parent +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE permtest_parent" +== 615 +-- truncate_limit: 100 +create role regress_no_child_access +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_no_child_access" +== 616 +-- truncate_limit: 100 +revoke all on permtest_grandchild from regress_no_child_access +-- +TABLE: name="permtest_grandchild" schema="" table="permtest_grandchild" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON permtest_grandchild FROM regress_no_child_access" +== 617 +-- truncate_limit: 100 +grant select on permtest_parent to regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON permtest_parent TO regress_no_child_access" +== 618 +-- truncate_limit: 100 +set session authorization regress_no_child_access +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_no_child_access" +== 619 +-- truncate_limit: 100 +-- 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$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM permtest_parent p1 JOIN permtest_parent p2 ON p1.a = p2.a AND p..." +== 620 +-- truncate_limit: 100 +explain (costs off) + select * from permtest_parent p1 inner join permtest_parent p2 + on p1.a = p2.a and left(p1.c, 3) ~ 'a1$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +FUNCTION: name="left" function="left" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM permtest_parent p1 JOIN permtest_parent p2 ON p1.a = p2.a AND \"..." +== 621 +-- truncate_limit: 100 +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 622 +-- truncate_limit: 100 +revoke all on permtest_parent from regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON permtest_parent FROM regress_no_child_access" +== 623 +-- truncate_limit: 100 +grant select(a,c) on permtest_parent to regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (a, c) ON permtest_parent TO regress_no_child_access" +== 624 +-- truncate_limit: 100 +set session authorization regress_no_child_access +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_no_child_access" +== 625 +-- truncate_limit: 100 +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$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p2.a, p1.c FROM permtest_parent p1 JOIN permtest_parent p2 ON p1.a = p..." +== 626 +-- truncate_limit: 100 +-- 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$' +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=Select +ALIAS: "p1"="permtest_parent" +ALIAS: "p2"="permtest_parent" +FUNCTION: name="left" function="left" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p2.a, p1.c FROM permtest_parent p1 JOIN permtest_parent p2 ON p1.a = p..." +== 627 +-- truncate_limit: 100 +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 628 +-- truncate_limit: 100 +revoke all on permtest_parent from regress_no_child_access +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON permtest_parent FROM regress_no_child_access" +== 629 +-- truncate_limit: 100 +drop role regress_no_child_access +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_no_child_access" +== 630 +-- truncate_limit: 100 +drop table permtest_parent +-- +TABLE: name="permtest_parent" schema="" table="permtest_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE permtest_parent" +== 631 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE errtst_parent (partid int NOT NULL, shdata int NOT NULL, data int NOT NULL DEFAULT 0..." +== 632 +-- truncate_limit: 100 +-- 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) +) +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE errtst_child_fastdef (partid int NOT NULL, shdata int NOT NULL, CONSTRAINT shdata_sm..." +== 633 +-- truncate_limit: 100 +-- 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) +) +-- +TABLE: name="errtst_child_plaindef" schema="" table="errtst_child_plaindef" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE errtst_child_plaindef (partid int NOT NULL, shdata int NOT NULL, data int NOT NULL D..." +== 634 +-- truncate_limit: 100 +-- 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) +) +-- +TABLE: name="errtst_child_reorder" schema="" table="errtst_child_reorder" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE errtst_child_reorder (data int NOT NULL DEFAULT 0, shdata int NOT NULL, partid int N..." +== 635 +-- truncate_limit: 100 +ALTER TABLE errtst_child_fastdef ADD COLUMN data int NOT NULL DEFAULT 0 +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE errtst_child_fastdef ADD COLUMN data int NOT NULL DEFAULT 0" +== 636 +-- truncate_limit: 100 +ALTER TABLE errtst_child_fastdef ADD CONSTRAINT errtest_child_fastdef_data_check CHECK (data < 10) +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE errtst_child_fastdef ADD CONSTRAINT errtest_child_fastdef_data_check CHECK (data < 10)" +== 637 +-- truncate_limit: 100 +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_fastdef FOR VALUES FROM (0) TO (10) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_fastdef FOR VALUES FROM (0) TO (10)" +== 638 +-- truncate_limit: 100 +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_plaindef FOR VALUES FROM (10) TO (20) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_plaindef FOR VALUES FROM (10) TO (20)" +== 639 +-- truncate_limit: 100 +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_reorder FOR VALUES FROM (20) TO (30) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_reorder FOR VALUES FROM (20) TO (30)" +== 640 +-- truncate_limit: 100 +-- insert without child check constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('0', '1', '5')" +== 641 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('10', '1', '5')" +== 642 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('20', '1', '5')" +== 643 +-- truncate_limit: 100 +-- insert with child check constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '10') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('0', '1', '10')" +== 644 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '10') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('10', '1', '10')" +== 645 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '10') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('20', '1', '10')" +== 646 +-- truncate_limit: 100 +-- insert with child not null constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', NULL) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('0', '1', NULL)" +== 647 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', NULL) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('10', '1', NULL)" +== 648 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', NULL) +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('20', '1', NULL)" +== 649 +-- truncate_limit: 100 +-- insert with shared check constraint error +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '5', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('0', '5', '5')" +== 650 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '5', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('10', '5', '5')" +== 651 +-- truncate_limit: 100 +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '5', '5') +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO errtst_parent (partid, shdata, data) VALUES ('20', '5', '5')" +== 652 +-- truncate_limit: 100 +-- within partition update without child check constraint violation +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 653 +-- truncate_limit: 100 +UPDATE errtst_parent SET data = data + 1 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET data = data + 1 WHERE partid = 0" +== 654 +-- truncate_limit: 100 +UPDATE errtst_parent SET data = data + 1 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET data = data + 1 WHERE partid = 10" +== 655 +-- truncate_limit: 100 +UPDATE errtst_parent SET data = data + 1 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET data = data + 1 WHERE partid = 20" +== 656 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 657 +-- truncate_limit: 100 +-- within partition update with child check constraint violation +UPDATE errtst_parent SET data = data + 10 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET data = data + 10 WHERE partid = 0" +== 658 +-- truncate_limit: 100 +UPDATE errtst_parent SET data = data + 10 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET data = data + 10 WHERE partid = 10" +== 659 +-- truncate_limit: 100 +UPDATE errtst_parent SET data = data + 10 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET data = data + 10 WHERE partid = 20" +== 660 +-- truncate_limit: 100 +-- direct leaf partition update, without partition id violation +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 661 +-- truncate_limit: 100 +UPDATE errtst_child_fastdef SET partid = 1 WHERE partid = 0 +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_child_fastdef SET partid = 1 WHERE partid = 0" +== 662 +-- truncate_limit: 100 +UPDATE errtst_child_plaindef SET partid = 11 WHERE partid = 10 +-- +TABLE: name="errtst_child_plaindef" schema="" table="errtst_child_plaindef" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_child_plaindef SET partid = 11 WHERE partid = 10" +== 663 +-- truncate_limit: 100 +UPDATE errtst_child_reorder SET partid = 21 WHERE partid = 20 +-- +TABLE: name="errtst_child_reorder" schema="" table="errtst_child_reorder" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_child_reorder SET partid = 21 WHERE partid = 20" +== 664 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 665 +-- truncate_limit: 100 +-- direct leaf partition update, with partition id violation +UPDATE errtst_child_fastdef SET partid = partid + 10 WHERE partid = 0 +-- +TABLE: name="errtst_child_fastdef" schema="" table="errtst_child_fastdef" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_child_fastdef SET partid = partid + 10 WHERE partid = 0" +== 666 +-- truncate_limit: 100 +UPDATE errtst_child_plaindef SET partid = partid + 10 WHERE partid = 10 +-- +TABLE: name="errtst_child_plaindef" schema="" table="errtst_child_plaindef" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_child_plaindef SET partid = partid + 10 WHERE partid = 10" +== 667 +-- truncate_limit: 100 +UPDATE errtst_child_reorder SET partid = partid + 10 WHERE partid = 20 +-- +TABLE: name="errtst_child_reorder" schema="" table="errtst_child_reorder" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_child_reorder SET partid = partid + 10 WHERE partid = 20" +== 668 +-- truncate_limit: 100 +-- partition move, without child check constraint violation +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 669 +-- truncate_limit: 100 +UPDATE errtst_parent SET partid = 10, data = data + 1 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET partid = 10, data = data + 1 WHERE partid = 0" +== 670 +-- truncate_limit: 100 +UPDATE errtst_parent SET partid = 20, data = data + 1 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET partid = 20, data = data + 1 WHERE partid = 10" +== 671 +-- truncate_limit: 100 +UPDATE errtst_parent SET partid = 0, data = data + 1 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET partid = 0, data = data + 1 WHERE partid = 20" +== 672 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 673 +-- truncate_limit: 100 +-- partition move, with child check constraint violation +UPDATE errtst_parent SET partid = 10, data = data + 10 WHERE partid = 0 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET partid = 10, data = data + 10 WHERE partid = 0" +== 674 +-- truncate_limit: 100 +UPDATE errtst_parent SET partid = 20, data = data + 10 WHERE partid = 10 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET partid = 20, data = data + 10 WHERE partid = 10" +== 675 +-- truncate_limit: 100 +UPDATE errtst_parent SET partid = 0, data = data + 10 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET partid = 0, data = data + 10 WHERE partid = 20" +== 676 +-- truncate_limit: 100 +-- partition move, without target partition +UPDATE errtst_parent SET partid = 30, data = data + 10 WHERE partid = 20 +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE errtst_parent SET partid = 30, data = data + 10 WHERE partid = 20" +== 677 +-- truncate_limit: 100 +DROP TABLE errtst_parent +-- +TABLE: name="errtst_parent" schema="" table="errtst_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE errtst_parent" diff --git a/parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json b/parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json new file mode 100644 index 0000000..f1ffe06 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json @@ -0,0 +1,8 @@ +{ + "todo": [ + "001", + "002", + "003", + "004" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/init_privs.test b/parser/testdata/summary_truncate/postgres_regress/init_privs.test new file mode 100644 index 0000000..83186f2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/init_privs.test @@ -0,0 +1,33 @@ +== 001 +-- truncate_limit: 100 +-- Test initial privileges + +-- There should always be some initial privileges, set up by initdb +SELECT count(*) > 0 FROM pg_init_privs +-- +TABLE: name="pg_init_privs" schema="" table="pg_init_privs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 FROM pg_init_privs" +== 002 +-- truncate_limit: 100 +-- Intentionally include some non-initial privs for pg_dump to dump out +GRANT SELECT ON pg_proc TO CURRENT_USER +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON pg_proc TO CURRENT_USER" +== 003 +-- truncate_limit: 100 +GRANT SELECT (prosrc) ON pg_proc TO CURRENT_USER +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (prosrc) ON pg_proc TO CURRENT_USER" +== 004 +-- truncate_limit: 100 +GRANT SELECT (rolname, rolsuper) ON pg_authid TO CURRENT_USER +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (rolname, rolsuper) ON pg_authid TO CURRENT_USER" diff --git a/parser/testdata/summary_truncate/postgres_regress/insert.metadata.json b/parser/testdata/summary_truncate/postgres_regress/insert.metadata.json new file mode 100644 index 0000000..1751d7d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/insert.metadata.json @@ -0,0 +1,391 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/insert.test b/parser/testdata/summary_truncate/postgres_regress/insert.test new file mode 100644 index 0000000..ff7dc9c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/insert.test @@ -0,0 +1,3071 @@ +== 001 +-- truncate_limit: 100 +|-- +-- insert with DEFAULT in the target_list +|-- +create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttest (col1 int4, col2 int4 NOT NULL, col3 text DEFAULT 'testing')" +== 002 +-- truncate_limit: 100 +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (col1, col2, col3) VALUES (DEFAULT, DEFAULT, DEFAULT)" +== 003 +-- truncate_limit: 100 +insert into inserttest (col2, col3) values (3, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (col2, col3) VALUES (3, DEFAULT)" +== 004 +-- truncate_limit: 100 +insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (col1, col2, col3) VALUES (DEFAULT, 5, DEFAULT)" +== 005 +-- truncate_limit: 100 +insert into inserttest values (DEFAULT, 5, 'test') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest VALUES (DEFAULT, 5, 'test')" +== 006 +-- truncate_limit: 100 +insert into inserttest values (DEFAULT, 7) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest VALUES (DEFAULT, 7)" +== 007 +-- truncate_limit: 100 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inserttest" +== 008 +-- truncate_limit: 100 +|-- +-- insert with similar expression / target_list values (all fail) +|-- +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (col1, col2, col3) VALUES (DEFAULT, DEFAULT)" +== 009 +-- truncate_limit: 100 +insert into inserttest (col1, col2, col3) values (1, 2) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (col1, col2, col3) VALUES (1, 2)" +== 010 +-- truncate_limit: 100 +insert into inserttest (col1) values (1, 2) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (col1) VALUES (1, 2)" +== 011 +-- truncate_limit: 100 +insert into inserttest (col1) values (DEFAULT, DEFAULT) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (col1) VALUES (DEFAULT, DEFAULT)" +== 012 +-- truncate_limit: 100 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inserttest" +== 013 +-- truncate_limit: 100 +|-- +-- VALUES test +|-- +insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT), + ((select 2), (select i from (values(3)) as foo (i)), 'values are fun!') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest VALUES (...)" +== 014 +-- truncate_limit: 100 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inserttest" +== 015 +-- truncate_limit: 100 +|-- +-- TOASTed value test +|-- +insert into inserttest values(30, 50, repeat('x', 10000)) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest VALUES (30, 50, repeat('x', 10000))" +== 016 +-- truncate_limit: 100 +select col1, col2, char_length(col3) from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT col1, col2, char_length(col3) FROM inserttest" +== 017 +-- truncate_limit: 100 +drop table inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttest" +== 018 +-- truncate_limit: 100 +|-- +-- tuple larger than fillfactor +|-- +CREATE TABLE large_tuple_test (a int, b text) WITH (fillfactor = 10) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE large_tuple_test (a int, b text) WITH (fillfactor=10)" +== 019 +-- truncate_limit: 100 +ALTER TABLE large_tuple_test ALTER COLUMN b SET STORAGE plain +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE large_tuple_test ALTER COLUMN b SET STORAGE plain" +== 020 +-- truncate_limit: 100 +-- create page w/ free space in range [nearlyEmptyFreeSpace, MaxHeapTupleSize) +INSERT INTO large_tuple_test (select 1, NULL) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO large_tuple_test SELECT 1, NULL" +== 021 +-- truncate_limit: 100 +-- should still fit on the page +INSERT INTO large_tuple_test (select 2, repeat('a', 1000)) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO large_tuple_test SELECT 2, repeat('a', 1000)" +== 022 +-- truncate_limit: 100 +SELECT pg_size_pretty(pg_relation_size('large_tuple_test'::regclass, 'main')) +-- +FUNCTION: name="pg_size_pretty" function="pg_size_pretty" schema="" ctx=Call +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_size_pretty(pg_relation_size('large_tuple_test'::regclass, 'main'))" +== 023 +-- truncate_limit: 100 +-- add small record to the second page +INSERT INTO large_tuple_test (select 3, NULL) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO large_tuple_test SELECT 3, NULL" +== 024 +-- truncate_limit: 100 +-- now this tuple won't fit on the second page, but the insert should +-- still succeed by extending the relation +INSERT INTO large_tuple_test (select 4, repeat('a', 8126)) +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO large_tuple_test SELECT 4, repeat('a', 8126)" +== 025 +-- truncate_limit: 100 +DROP TABLE large_tuple_test +-- +TABLE: name="large_tuple_test" schema="" table="large_tuple_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE large_tuple_test" +== 026 +-- truncate_limit: 100 +|-- +-- check indirection (field/array assignment), cf bug #14265 +|-- +-- these tests are aware that transformInsertStmt has 3 separate code paths +|-- + +create type insert_test_type as (if1 int, if2 text[]) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE insert_test_type AS (if1 int, if2 text[])" +== 027 +-- truncate_limit: 100 +create table inserttest (f1 int, f2 int[], + f3 insert_test_type, f4 insert_test_type[]) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttest (f1 int, f2 int[], f3 insert_test_type, f4 insert_test_type[])" +== 028 +-- truncate_limit: 100 +insert into inserttest (f2[1], f2[2]) values (1,2) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f2[1], f2[2]) VALUES (1, 2)" +== 029 +-- truncate_limit: 100 +insert into inserttest (f2[1], f2[2]) values (3,4), (5,6) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f2[1], f2[2]) VALUES (3, 4), (5, 6)" +== 030 +-- truncate_limit: 100 +insert into inserttest (f2[1], f2[2]) select 7,8 +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f2[1], f2[2]) SELECT 7, 8" +== 031 +-- truncate_limit: 100 +insert into inserttest (f2[1], f2[2]) values (1,default) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f2[1], f2[2]) VALUES (1, DEFAULT)" +== 032 +-- truncate_limit: 100 +-- not supported + +insert into inserttest (f3.if1, f3.if2) values (1,array['foo']) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f3.if1, f3.if2) VALUES (1, ARRAY['foo'])" +== 033 +-- truncate_limit: 100 +insert into inserttest (f3.if1, f3.if2) values (1,'{foo}'), (2,'{bar}') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f3.if1, f3.if2) VALUES (1, '{foo}'), (2, '{bar}')" +== 034 +-- truncate_limit: 100 +insert into inserttest (f3.if1, f3.if2) select 3, '{baz,quux}' +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f3.if1, f3.if2) SELECT 3, '{baz,quux}'" +== 035 +-- truncate_limit: 100 +insert into inserttest (f3.if1, f3.if2) values (1,default) +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f3.if1, f3.if2) VALUES (1, DEFAULT)" +== 036 +-- truncate_limit: 100 +-- not supported + +insert into inserttest (f3.if2[1], f3.if2[2]) values ('foo', 'bar') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f3.if2[1], f3.if2[2]) VALUES ('foo', 'bar')" +== 037 +-- truncate_limit: 100 +insert into inserttest (f3.if2[1], f3.if2[2]) values ('foo', 'bar'), ('baz', 'quux') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f3.if2[1], f3.if2[2]) VALUES ('foo', 'bar'), ('baz', 'quux')" +== 038 +-- truncate_limit: 100 +insert into inserttest (f3.if2[1], f3.if2[2]) select 'bear', 'beer' +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f3.if2[1], f3.if2[2]) SELECT 'bear', 'beer'" +== 039 +-- truncate_limit: 100 +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) values ('foo', 'bar') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f4[1].if2[1], f4[1].if2[2]) VALUES ('foo', 'bar')" +== 040 +-- truncate_limit: 100 +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) values ('foo', 'bar'), ('baz', 'quux') +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f4[1].if2[1], f4[1].if2[2]) VALUES ('foo', 'bar'), ('baz', 'quux')" +== 041 +-- truncate_limit: 100 +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) select 'bear', 'beer' +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttest (f4[1].if2[1], f4[1].if2[2]) SELECT 'bear', 'beer'" +== 042 +-- truncate_limit: 100 +select * from inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inserttest" +== 043 +-- truncate_limit: 100 +-- also check reverse-listing +create table inserttest2 (f1 bigint, f2 text) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttest2 (f1 bigint, f2 text)" +== 044 +-- truncate_limit: 100 +create rule irule1 as on insert to inserttest2 do also + insert into inserttest (f3.if2[1], f3.if2[2]) + values (new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE irule1 AS ON INSERT TO inserttest2 DO INSERT INTO inserttest (f3.if2[1], f3.if2[2]) V..." +== 045 +-- truncate_limit: 100 +create rule irule2 as on insert to inserttest2 do also + insert into inserttest (f4[1].if1, f4[1].if2[2]) + values (1,'fool'),(new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE irule2 AS ON INSERT TO inserttest2 DO INSERT INTO inserttest (f4[1].if1, f4[1].if2[2]..." +== 046 +-- truncate_limit: 100 +create rule irule3 as on insert to inserttest2 do also + insert into inserttest (f4[1].if1, f4[1].if2[2]) + select new.f1, new.f2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE irule3 AS ON INSERT TO inserttest2 DO INSERT INTO inserttest (f4[1].if1, f4[1].if2[2]..." +== 047 +-- truncate_limit: 100 +drop table inserttest2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttest2" +== 048 +-- truncate_limit: 100 +drop table inserttest +-- +TABLE: name="inserttest" schema="" table="inserttest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttest" +== 049 +-- truncate_limit: 100 +-- Make the same tests with domains over the array and composite fields + +create domain insert_pos_ints as int[] check (value[1] > 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN insert_pos_ints AS int[] CHECK (value[1] > 0)" +== 050 +-- truncate_limit: 100 +create domain insert_test_domain as insert_test_type + check ((value).if2[1] is not null) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN insert_test_domain AS insert_test_type CHECK ((value).if2[1] IS NOT NULL)" +== 051 +-- truncate_limit: 100 +create table inserttesta (f1 int, f2 insert_pos_ints) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttesta (f1 int, f2 insert_pos_ints)" +== 052 +-- truncate_limit: 100 +create table inserttestb (f3 insert_test_domain, f4 insert_test_domain[]) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttestb (f3 insert_test_domain, f4 insert_test_domain[])" +== 053 +-- truncate_limit: 100 +insert into inserttesta (f2[1], f2[2]) values (1,2) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f2[1], f2[2]) VALUES (1, 2)" +== 054 +-- truncate_limit: 100 +insert into inserttesta (f2[1], f2[2]) values (3,4), (5,6) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f2[1], f2[2]) VALUES (3, 4), (5, 6)" +== 055 +-- truncate_limit: 100 +insert into inserttesta (f2[1], f2[2]) select 7,8 +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f2[1], f2[2]) SELECT 7, 8" +== 056 +-- truncate_limit: 100 +insert into inserttesta (f2[1], f2[2]) values (1,default) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f2[1], f2[2]) VALUES (1, DEFAULT)" +== 057 +-- truncate_limit: 100 +-- not supported +insert into inserttesta (f2[1], f2[2]) values (0,2) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f2[1], f2[2]) VALUES (0, 2)" +== 058 +-- truncate_limit: 100 +insert into inserttesta (f2[1], f2[2]) values (3,4), (0,6) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f2[1], f2[2]) VALUES (3, 4), (0, 6)" +== 059 +-- truncate_limit: 100 +insert into inserttesta (f2[1], f2[2]) select 0,8 +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f2[1], f2[2]) SELECT 0, 8" +== 060 +-- truncate_limit: 100 +insert into inserttestb (f3.if1, f3.if2) values (1,array['foo']) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if1, f3.if2) VALUES (1, ARRAY['foo'])" +== 061 +-- truncate_limit: 100 +insert into inserttestb (f3.if1, f3.if2) values (1,'{foo}'), (2,'{bar}') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if1, f3.if2) VALUES (1, '{foo}'), (2, '{bar}')" +== 062 +-- truncate_limit: 100 +insert into inserttestb (f3.if1, f3.if2) select 3, '{baz,quux}' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if1, f3.if2) SELECT 3, '{baz,quux}'" +== 063 +-- truncate_limit: 100 +insert into inserttestb (f3.if1, f3.if2) values (1,default) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if1, f3.if2) VALUES (1, DEFAULT)" +== 064 +-- truncate_limit: 100 +-- not supported +insert into inserttestb (f3.if1, f3.if2) values (1,array[null]) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if1, f3.if2) VALUES (1, ARRAY[NULL])" +== 065 +-- truncate_limit: 100 +insert into inserttestb (f3.if1, f3.if2) values (1,'{null}'), (2,'{bar}') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if1, f3.if2) VALUES (1, '{null}'), (2, '{bar}')" +== 066 +-- truncate_limit: 100 +insert into inserttestb (f3.if1, f3.if2) select 3, '{null,quux}' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if1, f3.if2) SELECT 3, '{null,quux}'" +== 067 +-- truncate_limit: 100 +insert into inserttestb (f3.if2[1], f3.if2[2]) values ('foo', 'bar') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if2[1], f3.if2[2]) VALUES ('foo', 'bar')" +== 068 +-- truncate_limit: 100 +insert into inserttestb (f3.if2[1], f3.if2[2]) values ('foo', 'bar'), ('baz', 'quux') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if2[1], f3.if2[2]) VALUES ('foo', 'bar'), ('baz', 'quux')" +== 069 +-- truncate_limit: 100 +insert into inserttestb (f3.if2[1], f3.if2[2]) select 'bear', 'beer' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3.if2[1], f3.if2[2]) SELECT 'bear', 'beer'" +== 070 +-- truncate_limit: 100 +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) values (row(1,'{x}'), 'foo', 'bar') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) VALUES (ROW(1, '{x}'), 'foo', 'bar')" +== 071 +-- truncate_limit: 100 +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) values (row(1,'{x}'), 'foo', 'bar'), (row(2,'{y}'), 'baz', 'quux') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) VALUES (...)" +== 072 +-- truncate_limit: 100 +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) select row(1,'{x}')::insert_test_domain, 'bear', 'beer' +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) SELECT ..." +== 073 +-- truncate_limit: 100 +select * from inserttesta +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inserttesta" +== 074 +-- truncate_limit: 100 +select * from inserttestb +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inserttestb" +== 075 +-- truncate_limit: 100 +-- also check reverse-listing +create table inserttest2 (f1 bigint, f2 text) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttest2 (f1 bigint, f2 text)" +== 076 +-- truncate_limit: 100 +create rule irule1 as on insert to inserttest2 do also + insert into inserttestb (f3.if2[1], f3.if2[2]) + values (new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE irule1 AS ON INSERT TO inserttest2 DO INSERT INTO inserttestb (f3.if2[1], f3.if2[2]) ..." +== 077 +-- truncate_limit: 100 +create rule irule2 as on insert to inserttest2 do also + insert into inserttestb (f4[1].if1, f4[1].if2[2]) + values (1,'fool'),(new.f1,new.f2) +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE irule2 AS ON INSERT TO inserttest2 DO INSERT INTO inserttestb (f4[1].if1, f4[1].if2[2..." +== 078 +-- truncate_limit: 100 +create rule irule3 as on insert to inserttest2 do also + insert into inserttestb (f4[1].if1, f4[1].if2[2]) + select new.f1, new.f2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE irule3 AS ON INSERT TO inserttest2 DO INSERT INTO inserttestb (f4[1].if1, f4[1].if2[2..." +== 079 +-- truncate_limit: 100 +drop table inserttest2 +-- +TABLE: name="inserttest2" schema="" table="inserttest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttest2" +== 080 +-- truncate_limit: 100 +drop table inserttesta +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttesta" +== 081 +-- truncate_limit: 100 +drop table inserttestb +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttestb" +== 082 +-- truncate_limit: 100 +drop domain insert_pos_ints +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN insert_pos_ints" +== 083 +-- truncate_limit: 100 +drop domain insert_test_domain +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN insert_test_domain" +== 084 +-- truncate_limit: 100 +-- Verify that multiple inserts to subfields of a domain-over-container +-- check the domain constraints only on the finished value + +create domain insert_nnarray as int[] + check (value[1] is not null and value[2] is not null) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN insert_nnarray AS int[] CHECK (value[1] IS NOT NULL AND value[2] IS NOT NULL)" +== 085 +-- truncate_limit: 100 +create domain insert_test_domain as insert_test_type + check ((value).if1 is not null and (value).if2 is not null) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN insert_test_domain AS insert_test_type CHECK ((value).if1 IS NOT NULL AND (value).i..." +== 086 +-- truncate_limit: 100 +create table inserttesta (f1 insert_nnarray) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttesta (f1 insert_nnarray)" +== 087 +-- truncate_limit: 100 +insert into inserttesta (f1[1]) values (1) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f1[1]) VALUES (1)" +== 088 +-- truncate_limit: 100 +-- fail +insert into inserttesta (f1[1], f1[2]) values (1, 2) +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttesta (f1[1], f1[2]) VALUES (1, 2)" +== 089 +-- truncate_limit: 100 +create table inserttestb (f1 insert_test_domain) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttestb (f1 insert_test_domain)" +== 090 +-- truncate_limit: 100 +insert into inserttestb (f1.if1) values (1) +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f1.if1) VALUES (1)" +== 091 +-- truncate_limit: 100 +-- fail +insert into inserttestb (f1.if1, f1.if2) values (1, '{foo}') +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inserttestb (f1.if1, f1.if2) VALUES (1, '{foo}')" +== 092 +-- truncate_limit: 100 +drop table inserttesta +-- +TABLE: name="inserttesta" schema="" table="inserttesta" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttesta" +== 093 +-- truncate_limit: 100 +drop table inserttestb +-- +TABLE: name="inserttestb" schema="" table="inserttestb" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttestb" +== 094 +-- truncate_limit: 100 +drop domain insert_nnarray +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN insert_nnarray" +== 095 +-- truncate_limit: 100 +drop type insert_test_type cascade +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE insert_test_type CASCADE" +== 096 +-- truncate_limit: 100 +-- direct partition inserts should check partition bound constraint +create table range_parted ( + a text, + b int +) partition by range (a, (b+0)) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted (a text, b int) PARTITION BY RANGE (a, (b + 0))" +== 097 +-- truncate_limit: 100 +-- no partitions, so fail +insert into range_parted values ('a', 11) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('a', 11)" +== 098 +-- truncate_limit: 100 +create table part1 partition of range_parted for values from ('a', 1) to ('a', 10) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part1 PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('a', 10)" +== 099 +-- truncate_limit: 100 +create table part2 partition of range_parted for values from ('a', 10) to ('a', 20) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part2 PARTITION OF range_parted FOR VALUES FROM ('a', 10) TO ('a', 20)" +== 100 +-- truncate_limit: 100 +create table part3 partition of range_parted for values from ('b', 1) to ('b', 10) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part3 PARTITION OF range_parted FOR VALUES FROM ('b', 1) TO ('b', 10)" +== 101 +-- truncate_limit: 100 +create table part4 partition of range_parted for values from ('b', 10) to ('b', 20) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part4 PARTITION OF range_parted FOR VALUES FROM ('b', 10) TO ('b', 20)" +== 102 +-- truncate_limit: 100 +-- fail +insert into part1 values ('a', 11) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part1 VALUES ('a', 11)" +== 103 +-- truncate_limit: 100 +insert into part1 values ('b', 1) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part1 VALUES ('b', 1)" +== 104 +-- truncate_limit: 100 +-- ok +insert into part1 values ('a', 1) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part1 VALUES ('a', 1)" +== 105 +-- truncate_limit: 100 +-- fail +insert into part4 values ('b', 21) +-- +TABLE: name="part4" schema="" table="part4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part4 VALUES ('b', 21)" +== 106 +-- truncate_limit: 100 +insert into part4 values ('a', 10) +-- +TABLE: name="part4" schema="" table="part4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part4 VALUES ('a', 10)" +== 107 +-- truncate_limit: 100 +-- ok +insert into part4 values ('b', 10) +-- +TABLE: name="part4" schema="" table="part4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part4 VALUES ('b', 10)" +== 108 +-- truncate_limit: 100 +-- fail (partition key a has a NOT NULL constraint) +insert into part1 values (null) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part1 VALUES (NULL)" +== 109 +-- truncate_limit: 100 +-- fail (expression key (b+0) cannot be null either) +insert into part1 values (1) +-- +TABLE: name="part1" schema="" table="part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part1 VALUES (1)" +== 110 +-- truncate_limit: 100 +create table list_parted ( + a text, + b int +) partition by list (lower(a)) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted (a text, b int) PARTITION BY LIST ((lower(a)))" +== 111 +-- truncate_limit: 100 +create table part_aa_bb partition of list_parted FOR VALUES IN ('aa', 'bb') +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_aa_bb PARTITION OF list_parted FOR VALUES IN ('aa', 'bb')" +== 112 +-- truncate_limit: 100 +create table part_cc_dd partition of list_parted FOR VALUES IN ('cc', 'dd') +-- +TABLE: name="part_cc_dd" schema="" table="part_cc_dd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_cc_dd PARTITION OF list_parted FOR VALUES IN ('cc', 'dd')" +== 113 +-- truncate_limit: 100 +create table part_null partition of list_parted FOR VALUES IN (null) +-- +TABLE: name="part_null" schema="" table="part_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (NULL)" +== 114 +-- truncate_limit: 100 +-- fail +insert into part_aa_bb values ('cc', 1) +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_aa_bb VALUES ('cc', 1)" +== 115 +-- truncate_limit: 100 +insert into part_aa_bb values ('AAa', 1) +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_aa_bb VALUES ('AAa', 1)" +== 116 +-- truncate_limit: 100 +insert into part_aa_bb values (null) +-- +TABLE: name="part_aa_bb" schema="" table="part_aa_bb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_aa_bb VALUES (NULL)" +== 117 +-- truncate_limit: 100 +-- ok +insert into part_cc_dd values ('cC', 1) +-- +TABLE: name="part_cc_dd" schema="" table="part_cc_dd" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_cc_dd VALUES ('cC', 1)" +== 118 +-- truncate_limit: 100 +insert into part_null values (null, 0) +-- +TABLE: name="part_null" schema="" table="part_null" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_null VALUES (NULL, 0)" +== 119 +-- truncate_limit: 100 +-- check in case of multi-level partitioned table +create table part_ee_ff partition of list_parted for values in ('ee', 'ff') partition by range (b) +-- +TABLE: name="part_ee_ff" schema="" table="part_ee_ff" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ee_ff PARTITION OF list_parted FOR VALUES IN ('ee', 'ff') PARTITION BY RANGE (b)" +== 120 +-- truncate_limit: 100 +create table part_ee_ff1 partition of part_ee_ff for values from (1) to (10) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ee_ff1 PARTITION OF part_ee_ff FOR VALUES FROM (1) TO (10)" +== 121 +-- truncate_limit: 100 +create table part_ee_ff2 partition of part_ee_ff for values from (10) to (20) +-- +TABLE: name="part_ee_ff2" schema="" table="part_ee_ff2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ee_ff2 PARTITION OF part_ee_ff FOR VALUES FROM (10) TO (20)" +== 122 +-- truncate_limit: 100 +-- test default partition +create table part_default partition of list_parted default +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_default PARTITION OF list_parted DEFAULT" +== 123 +-- truncate_limit: 100 +-- Negative test: a row, which would fit in other partition, does not fit +-- default partition, even when inserted directly +insert into part_default values ('aa', 2) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default VALUES ('aa', 2)" +== 124 +-- truncate_limit: 100 +insert into part_default values (null, 2) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default VALUES (NULL, 2)" +== 125 +-- truncate_limit: 100 +-- ok +insert into part_default values ('Zz', 2) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default VALUES ('Zz', 2)" +== 126 +-- truncate_limit: 100 +-- test if default partition works as expected for multi-level partitioned +-- table as well as when default partition itself is further partitioned +drop table part_default +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_default" +== 127 +-- truncate_limit: 100 +create table part_xx_yy partition of list_parted for values in ('xx', 'yy') partition by list (a) +-- +TABLE: name="part_xx_yy" schema="" table="part_xx_yy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_xx_yy PARTITION OF list_parted FOR VALUES IN ('xx', 'yy') PARTITION BY LIST (a)" +== 128 +-- truncate_limit: 100 +create table part_xx_yy_p1 partition of part_xx_yy for values in ('xx') +-- +TABLE: name="part_xx_yy_p1" schema="" table="part_xx_yy_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_xx_yy_p1 PARTITION OF part_xx_yy FOR VALUES IN ('xx')" +== 129 +-- truncate_limit: 100 +create table part_xx_yy_defpart partition of part_xx_yy default +-- +TABLE: name="part_xx_yy_defpart" schema="" table="part_xx_yy_defpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_xx_yy_defpart PARTITION OF part_xx_yy DEFAULT" +== 130 +-- truncate_limit: 100 +create table part_default partition of list_parted default partition by range(b) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_default PARTITION OF list_parted DEFAULT PARTITION BY RANGE (b)" +== 131 +-- truncate_limit: 100 +create table part_default_p1 partition of part_default for values from (20) to (30) +-- +TABLE: name="part_default_p1" schema="" table="part_default_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_default_p1 PARTITION OF part_default FOR VALUES FROM (20) TO (30)" +== 132 +-- truncate_limit: 100 +create table part_default_p2 partition of part_default for values from (30) to (40) +-- +TABLE: name="part_default_p2" schema="" table="part_default_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_default_p2 PARTITION OF part_default FOR VALUES FROM (30) TO (40)" +== 133 +-- truncate_limit: 100 +-- fail +insert into part_ee_ff1 values ('EE', 11) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_ee_ff1 VALUES ('EE', 11)" +== 134 +-- truncate_limit: 100 +insert into part_default_p2 values ('gg', 43) +-- +TABLE: name="part_default_p2" schema="" table="part_default_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default_p2 VALUES ('gg', 43)" +== 135 +-- truncate_limit: 100 +-- fail (even the parent's, ie, part_ee_ff's partition constraint applies) +insert into part_ee_ff1 values ('cc', 1) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_ee_ff1 VALUES ('cc', 1)" +== 136 +-- truncate_limit: 100 +insert into part_default values ('gg', 43) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default VALUES ('gg', 43)" +== 137 +-- truncate_limit: 100 +-- ok +insert into part_ee_ff1 values ('ff', 1) +-- +TABLE: name="part_ee_ff1" schema="" table="part_ee_ff1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_ee_ff1 VALUES ('ff', 1)" +== 138 +-- truncate_limit: 100 +insert into part_ee_ff2 values ('ff', 11) +-- +TABLE: name="part_ee_ff2" schema="" table="part_ee_ff2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_ee_ff2 VALUES ('ff', 11)" +== 139 +-- truncate_limit: 100 +insert into part_default_p1 values ('cd', 25) +-- +TABLE: name="part_default_p1" schema="" table="part_default_p1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default_p1 VALUES ('cd', 25)" +== 140 +-- truncate_limit: 100 +insert into part_default_p2 values ('de', 35) +-- +TABLE: name="part_default_p2" schema="" table="part_default_p2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default_p2 VALUES ('de', 35)" +== 141 +-- truncate_limit: 100 +insert into list_parted values ('ab', 21) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES ('ab', 21)" +== 142 +-- truncate_limit: 100 +insert into list_parted values ('xx', 1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES ('xx', 1)" +== 143 +-- truncate_limit: 100 +insert into list_parted values ('yy', 2) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES ('yy', 2)" +== 144 +-- truncate_limit: 100 +select tableoid::regclass, * from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM list_parted" +== 145 +-- truncate_limit: 100 +-- Check tuple routing for partitioned tables + +-- fail +insert into range_parted values ('a', 0) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('a', 0)" +== 146 +-- truncate_limit: 100 +-- ok +insert into range_parted values ('a', 1) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('a', 1)" +== 147 +-- truncate_limit: 100 +insert into range_parted values ('a', 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('a', 10)" +== 148 +-- truncate_limit: 100 +-- fail +insert into range_parted values ('a', 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('a', 20)" +== 149 +-- truncate_limit: 100 +-- ok +insert into range_parted values ('b', 1) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('b', 1)" +== 150 +-- truncate_limit: 100 +insert into range_parted values ('b', 10) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('b', 10)" +== 151 +-- truncate_limit: 100 +-- fail (partition key (b+0) is null) +insert into range_parted values ('a') +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('a')" +== 152 +-- truncate_limit: 100 +-- Check default partition +create table part_def partition of range_parted default +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_def PARTITION OF range_parted DEFAULT" +== 153 +-- truncate_limit: 100 +-- fail +insert into part_def values ('b', 10) +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_def VALUES ('b', 10)" +== 154 +-- truncate_limit: 100 +-- ok +insert into part_def values ('c', 10) +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_def VALUES ('c', 10)" +== 155 +-- truncate_limit: 100 +insert into range_parted values (null, null) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES (NULL, NULL)" +== 156 +-- truncate_limit: 100 +insert into range_parted values ('a', null) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('a', NULL)" +== 157 +-- truncate_limit: 100 +insert into range_parted values (null, 19) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES (NULL, 19)" +== 158 +-- truncate_limit: 100 +insert into range_parted values ('b', 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('b', 20)" +== 159 +-- truncate_limit: 100 +select tableoid::regclass, * from range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM range_parted" +== 160 +-- truncate_limit: 100 +-- ok +insert into list_parted values (null, 1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES (NULL, 1)" +== 161 +-- truncate_limit: 100 +insert into list_parted (a) values ('aA') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted (a) VALUES ('aA')" +== 162 +-- truncate_limit: 100 +-- fail (partition of part_ee_ff not found in both cases) +insert into list_parted values ('EE', 0) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES ('EE', 0)" +== 163 +-- truncate_limit: 100 +insert into part_ee_ff values ('EE', 0) +-- +TABLE: name="part_ee_ff" schema="" table="part_ee_ff" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_ee_ff VALUES ('EE', 0)" +== 164 +-- truncate_limit: 100 +-- ok +insert into list_parted values ('EE', 1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES ('EE', 1)" +== 165 +-- truncate_limit: 100 +insert into part_ee_ff values ('EE', 10) +-- +TABLE: name="part_ee_ff" schema="" table="part_ee_ff" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_ee_ff VALUES ('EE', 10)" +== 166 +-- truncate_limit: 100 +select tableoid::regclass, * from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM list_parted" +== 167 +-- truncate_limit: 100 +-- some more tests to exercise tuple-routing with multi-level partitioning +create table part_gg partition of list_parted for values in ('gg') partition by range (b) +-- +TABLE: name="part_gg" schema="" table="part_gg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_gg PARTITION OF list_parted FOR VALUES IN ('gg') PARTITION BY RANGE (b)" +== 168 +-- truncate_limit: 100 +create table part_gg1 partition of part_gg for values from (minvalue) to (1) +-- +TABLE: name="part_gg1" schema="" table="part_gg1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_gg1 PARTITION OF part_gg FOR VALUES FROM (minvalue) TO (1)" +== 169 +-- truncate_limit: 100 +create table part_gg2 partition of part_gg for values from (1) to (10) partition by range (b) +-- +TABLE: name="part_gg2" schema="" table="part_gg2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_gg2 PARTITION OF part_gg FOR VALUES FROM (1) TO (10) PARTITION BY RANGE (b)" +== 170 +-- truncate_limit: 100 +create table part_gg2_1 partition of part_gg2 for values from (1) to (5) +-- +TABLE: name="part_gg2_1" schema="" table="part_gg2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_gg2_1 PARTITION OF part_gg2 FOR VALUES FROM (1) TO (5)" +== 171 +-- truncate_limit: 100 +create table part_gg2_2 partition of part_gg2 for values from (5) to (10) +-- +TABLE: name="part_gg2_2" schema="" table="part_gg2_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_gg2_2 PARTITION OF part_gg2 FOR VALUES FROM (5) TO (10)" +== 172 +-- truncate_limit: 100 +create table part_ee_ff3 partition of part_ee_ff for values from (20) to (30) partition by range (b) +-- +TABLE: name="part_ee_ff3" schema="" table="part_ee_ff3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ee_ff3 PARTITION OF part_ee_ff FOR VALUES FROM (20) TO (30) PARTITION BY RANGE (b)" +== 173 +-- truncate_limit: 100 +create table part_ee_ff3_1 partition of part_ee_ff3 for values from (20) to (25) +-- +TABLE: name="part_ee_ff3_1" schema="" table="part_ee_ff3_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ee_ff3_1 PARTITION OF part_ee_ff3 FOR VALUES FROM (20) TO (25)" +== 174 +-- truncate_limit: 100 +create table part_ee_ff3_2 partition of part_ee_ff3 for values from (25) to (30) +-- +TABLE: name="part_ee_ff3_2" schema="" table="part_ee_ff3_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_ee_ff3_2 PARTITION OF part_ee_ff3 FOR VALUES FROM (25) TO (30)" +== 175 +-- truncate_limit: 100 +truncate list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE list_parted" +== 176 +-- truncate_limit: 100 +insert into list_parted values ('aa'), ('cc') +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES ('aa'), ('cc')" +== 177 +-- truncate_limit: 100 +insert into list_parted select 'Ff', s.a from generate_series(1, 29) s(a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted SELECT 'Ff', s.a FROM generate_series(1, 29) s(a)" +== 178 +-- truncate_limit: 100 +insert into list_parted select 'gg', s.a from generate_series(1, 9) s(a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted SELECT 'gg', s.a FROM generate_series(1, 9) s(a)" +== 179 +-- truncate_limit: 100 +insert into list_parted (b) values (1) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted (b) VALUES (1)" +== 180 +-- truncate_limit: 100 +select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_parted group by 1, 2 order by 1 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM list_parted GROUP BY 1, 2 ORDER BY 1" +== 181 +-- truncate_limit: 100 +-- direct partition inserts should check hash partition bound constraint + +create table hash_parted ( + a int +) partition by hash (a part_test_int4_ops) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_parted (a int) PARTITION BY HASH (a part_test_int4_ops)" +== 182 +-- truncate_limit: 100 +create table hpart0 partition of hash_parted for values with (modulus 4, remainder 0) +-- +TABLE: name="hpart0" schema="" table="hpart0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart0 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 0)" +== 183 +-- truncate_limit: 100 +create table hpart1 partition of hash_parted for values with (modulus 4, remainder 1) +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 1)" +== 184 +-- truncate_limit: 100 +create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2) +-- +TABLE: name="hpart2" schema="" table="hpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 2)" +== 185 +-- truncate_limit: 100 +create table hpart3 partition of hash_parted for values with (modulus 4, remainder 3) +-- +TABLE: name="hpart3" schema="" table="hpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 3)" +== 186 +-- truncate_limit: 100 +insert into hash_parted values(generate_series(1,10)) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hash_parted VALUES (generate_series(1, 10))" +== 187 +-- truncate_limit: 100 +-- direct insert of values divisible by 4 - ok; +insert into hpart0 values(12),(16) +-- +TABLE: name="hpart0" schema="" table="hpart0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart0 VALUES (12), (16)" +== 188 +-- truncate_limit: 100 +-- fail; +insert into hpart0 values(11) +-- +TABLE: name="hpart0" schema="" table="hpart0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart0 VALUES (11)" +== 189 +-- truncate_limit: 100 +-- 11 % 4 -> 3 remainder i.e. valid data for hpart3 partition +insert into hpart3 values(11) +-- +TABLE: name="hpart3" schema="" table="hpart3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart3 VALUES (11)" +== 190 +-- truncate_limit: 100 +-- view data +select tableoid::regclass as part, a, a%4 as "remainder = a % 4" +from hash_parted order by part +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass AS part, a, a % 4 AS \"remainder = a % 4\" FROM hash_parted ORDER BY part" +== 191 +-- truncate_limit: 100 +-- test \d+ output on a table which has both partitioned and unpartitioned +-- partitions + +-- cleanup +drop table range_parted, list_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE range_parted, list_parted" +== 192 +-- truncate_limit: 100 +drop table hash_parted +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_parted" +== 193 +-- truncate_limit: 100 +-- test that a default partition added as the first partition accepts any value +-- including null +create table list_parted (a int) partition by list (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted (a int) PARTITION BY LIST (a)" +== 194 +-- truncate_limit: 100 +create table part_default partition of list_parted default +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_default PARTITION OF list_parted DEFAULT" +== 195 +-- truncate_limit: 100 +insert into part_default values (null) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default VALUES (NULL)" +== 196 +-- truncate_limit: 100 +insert into part_default values (1) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default VALUES (1)" +== 197 +-- truncate_limit: 100 +insert into part_default values (-1) +-- +TABLE: name="part_default" schema="" table="part_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_default VALUES (-1)" +== 198 +-- truncate_limit: 100 +select tableoid::regclass, a from list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, a FROM list_parted" +== 199 +-- truncate_limit: 100 +-- cleanup +drop table list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE list_parted" +== 200 +-- truncate_limit: 100 +-- more tests for certain multi-level partitioning scenarios +create table mlparted (a int, b int) partition by range (a, b) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted (a int, b int) PARTITION BY RANGE (a, b)" +== 201 +-- truncate_limit: 100 +create table mlparted1 (b int not null, a int not null) partition by range ((b+0)) +-- +TABLE: name="mlparted1" schema="" table="mlparted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted1 (b int NOT NULL, a int NOT NULL) PARTITION BY RANGE ((b + 0))" +== 202 +-- truncate_limit: 100 +create table mlparted11 (like mlparted1) +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted11 (LIKE mlparted1)" +== 203 +-- truncate_limit: 100 +alter table mlparted11 drop a +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted11 DROP a" +== 204 +-- truncate_limit: 100 +alter table mlparted11 add a int +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted11 ADD COLUMN a int" +== 205 +-- truncate_limit: 100 +alter table mlparted11 drop a +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted11 DROP a" +== 206 +-- truncate_limit: 100 +alter table mlparted11 add a int not null +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted11 ADD COLUMN a int NOT NULL" +== 207 +-- truncate_limit: 100 +-- attnum for key attribute 'a' is different in mlparted, mlparted1, and mlparted11 +select attrelid::regclass, attname, attnum +from pg_attribute +where attname = 'a' + and (attrelid = 'mlparted'::regclass + or attrelid = 'mlparted1'::regclass + or attrelid = 'mlparted11'::regclass) +order by attrelid::regclass::text +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +FILTER: schema="" table="" column="attname" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_attribute WHERE ... ORDER BY attrelid::regclass::text" +== 208 +-- truncate_limit: 100 +alter table mlparted1 attach partition mlparted11 for values from (2) to (5) +-- +TABLE: name="mlparted1" schema="" table="mlparted1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted1 ATTACH PARTITION mlparted11 FOR VALUES FROM (2) TO (5)" +== 209 +-- truncate_limit: 100 +alter table mlparted attach partition mlparted1 for values from (1, 2) to (1, 10) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ATTACH PARTITION mlparted1 FOR VALUES FROM (1, 2) TO (1, 10)" +== 210 +-- truncate_limit: 100 +-- check that "(1, 2)" is correctly routed to mlparted11. +insert into mlparted values (1, 2) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 2)" +== 211 +-- truncate_limit: 100 +select tableoid::regclass, * from mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM mlparted" +== 212 +-- truncate_limit: 100 +-- check that proper message is shown after failure to route through mlparted1 +insert into mlparted (a, b) values (1, 5) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted (a, b) VALUES (1, 5)" +== 213 +-- truncate_limit: 100 +truncate mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mlparted" +== 214 +-- truncate_limit: 100 +alter table mlparted add constraint check_b check (b = 3) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ADD CONSTRAINT check_b CHECK (b = 3)" +== 215 +-- truncate_limit: 100 +-- have a BR trigger modify the row such that the check_b is violated +create function mlparted11_trig_fn() +returns trigger AS +$$ +begin + NEW.b := 4; + return NEW; +end; +$$ +language plpgsql +-- +FUNCTION: name="mlparted11_trig_fn" function="mlparted11_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mlparted11_trig_fn() RETURNS trigger AS $$\nbegin\n NEW.b := 4;\n return NEW;\nend;..." +== 216 +-- truncate_limit: 100 +create trigger mlparted11_trig before insert ON mlparted11 + for each row execute procedure mlparted11_trig_fn() +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER mlparted11_trig BEFORE INSERT ON mlparted11 FOR EACH ROW EXECUTE FUNCTION mlparted..." +== 217 +-- truncate_limit: 100 +-- check that the correct row is shown when constraint check_b fails after +-- "(1, 2)" is routed to mlparted11 (actually "(1, 4)" would be shown due +-- to the BR trigger mlparted11_trig_fn) +insert into mlparted values (1, 2) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 2)" +== 218 +-- truncate_limit: 100 +drop trigger mlparted11_trig on mlparted11 +-- +TABLE: name="mlparted11" schema="" table="mlparted11" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER mlparted11_trig ON mlparted11" +== 219 +-- truncate_limit: 100 +drop function mlparted11_trig_fn() +-- +FUNCTION: name="mlparted11_trig_fn" function="mlparted11_trig_fn" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION mlparted11_trig_fn()" +== 220 +-- truncate_limit: 100 +-- check that inserting into an internal partition successfully results in +-- checking its partition constraint before inserting into the leaf partition +-- selected by tuple-routing +insert into mlparted1 (a, b) values (2, 3) +-- +TABLE: name="mlparted1" schema="" table="mlparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted1 (a, b) VALUES (2, 3)" +== 221 +-- truncate_limit: 100 +-- check routing error through a list partitioned table when the key is null +create table lparted_nonullpart (a int, b char) partition by list (b) +-- +TABLE: name="lparted_nonullpart" schema="" table="lparted_nonullpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lparted_nonullpart (a int, b char(1)) PARTITION BY LIST (b)" +== 222 +-- truncate_limit: 100 +create table lparted_nonullpart_a partition of lparted_nonullpart for values in ('a') +-- +TABLE: name="lparted_nonullpart_a" schema="" table="lparted_nonullpart_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lparted_nonullpart_a PARTITION OF lparted_nonullpart FOR VALUES IN ('a')" +== 223 +-- truncate_limit: 100 +insert into lparted_nonullpart values (1) +-- +TABLE: name="lparted_nonullpart" schema="" table="lparted_nonullpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lparted_nonullpart VALUES (1)" +== 224 +-- truncate_limit: 100 +drop table lparted_nonullpart +-- +TABLE: name="lparted_nonullpart" schema="" table="lparted_nonullpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lparted_nonullpart" +== 225 +-- truncate_limit: 100 +-- check that RETURNING works correctly with tuple-routing +alter table mlparted drop constraint check_b +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted DROP CONSTRAINT check_b" +== 226 +-- truncate_limit: 100 +create table mlparted12 partition of mlparted1 for values from (5) to (10) +-- +TABLE: name="mlparted12" schema="" table="mlparted12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted12 PARTITION OF mlparted1 FOR VALUES FROM (5) TO (10)" +== 227 +-- truncate_limit: 100 +create table mlparted2 (b int not null, a int not null) +-- +TABLE: name="mlparted2" schema="" table="mlparted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted2 (b int NOT NULL, a int NOT NULL)" +== 228 +-- truncate_limit: 100 +alter table mlparted attach partition mlparted2 for values from (1, 10) to (1, 20) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ATTACH PARTITION mlparted2 FOR VALUES FROM (1, 10) TO (1, 20)" +== 229 +-- truncate_limit: 100 +create table mlparted3 partition of mlparted for values from (1, 20) to (1, 30) +-- +TABLE: name="mlparted3" schema="" table="mlparted3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted3 PARTITION OF mlparted FOR VALUES FROM (1, 20) TO (1, 30)" +== 230 +-- truncate_limit: 100 +create table mlparted4 (like mlparted) +-- +TABLE: name="mlparted4" schema="" table="mlparted4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted4 (LIKE mlparted)" +== 231 +-- truncate_limit: 100 +alter table mlparted4 drop a +-- +TABLE: name="mlparted4" schema="" table="mlparted4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted4 DROP a" +== 232 +-- truncate_limit: 100 +alter table mlparted4 add a int not null +-- +TABLE: name="mlparted4" schema="" table="mlparted4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted4 ADD COLUMN a int NOT NULL" +== 233 +-- truncate_limit: 100 +alter table mlparted attach partition mlparted4 for values from (1, 30) to (1, 40) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ATTACH PARTITION mlparted4 FOR VALUES FROM (1, 30) TO (1, 40)" +== 234 +-- truncate_limit: 100 +with ins (a, b, c) as + (insert into mlparted (b, a) select s.a, 1 from generate_series(2, 39) s(a) returning tableoid::regclass, *) + select a, b, min(c), max(c) from ins group by a, b order by 1 +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +CTE: "ins" +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH ins(a, b, c) AS (...) SELECT a, b, min(c), max(c) FROM ins GROUP BY a, b ORDER BY 1" +== 235 +-- truncate_limit: 100 +alter table mlparted add c text +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ADD COLUMN c text" +== 236 +-- truncate_limit: 100 +create table mlparted5 (c text, a int not null, b int not null) partition by list (c) +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted5 (c text, a int NOT NULL, b int NOT NULL) PARTITION BY LIST (c)" +== 237 +-- truncate_limit: 100 +create table mlparted5a (a int not null, c text, b int not null) +-- +TABLE: name="mlparted5a" schema="" table="mlparted5a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted5a (a int NOT NULL, c text, b int NOT NULL)" +== 238 +-- truncate_limit: 100 +alter table mlparted5 attach partition mlparted5a for values in ('a') +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted5 ATTACH PARTITION mlparted5a FOR VALUES IN ('a')" +== 239 +-- truncate_limit: 100 +alter table mlparted attach partition mlparted5 for values from (1, 40) to (1, 50) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ATTACH PARTITION mlparted5 FOR VALUES FROM (1, 40) TO (1, 50)" +== 240 +-- truncate_limit: 100 +alter table mlparted add constraint check_b check (a = 1 and b < 45) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ADD CONSTRAINT check_b CHECK (a = 1 AND b < 45)" +== 241 +-- truncate_limit: 100 +insert into mlparted values (1, 45, 'a') +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 45, 'a')" +== 242 +-- truncate_limit: 100 +create function mlparted5abrtrig_func() returns trigger as $$ begin new.c = 'b'; return new; end; $$ language plpgsql +-- +FUNCTION: name="mlparted5abrtrig_func" function="mlparted5abrtrig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mlparted5abrtrig_func() RETURNS trigger AS $$ begin new.c = 'b'; return new; end;..." +== 243 +-- truncate_limit: 100 +create trigger mlparted5abrtrig before insert on mlparted5a for each row execute procedure mlparted5abrtrig_func() +-- +TABLE: name="mlparted5a" schema="" table="mlparted5a" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER mlparted5abrtrig BEFORE INSERT ON mlparted5a FOR EACH ROW EXECUTE FUNCTION mlparte..." +== 244 +-- truncate_limit: 100 +insert into mlparted5 (a, b, c) values (1, 40, 'a') +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted5 (a, b, c) VALUES (1, 40, 'a')" +== 245 +-- truncate_limit: 100 +drop table mlparted5 +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mlparted5" +== 246 +-- truncate_limit: 100 +alter table mlparted drop constraint check_b +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted DROP CONSTRAINT check_b" +== 247 +-- truncate_limit: 100 +-- Check multi-level default partition +create table mlparted_def partition of mlparted default partition by range(a) +-- +TABLE: name="mlparted_def" schema="" table="mlparted_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_def PARTITION OF mlparted DEFAULT PARTITION BY RANGE (a)" +== 248 +-- truncate_limit: 100 +create table mlparted_def1 partition of mlparted_def for values from (40) to (50) +-- +TABLE: name="mlparted_def1" schema="" table="mlparted_def1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_def1 PARTITION OF mlparted_def FOR VALUES FROM (40) TO (50)" +== 249 +-- truncate_limit: 100 +create table mlparted_def2 partition of mlparted_def for values from (50) to (60) +-- +TABLE: name="mlparted_def2" schema="" table="mlparted_def2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_def2 PARTITION OF mlparted_def FOR VALUES FROM (50) TO (60)" +== 250 +-- truncate_limit: 100 +insert into mlparted values (40, 100) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (40, 100)" +== 251 +-- truncate_limit: 100 +insert into mlparted_def1 values (42, 100) +-- +TABLE: name="mlparted_def1" schema="" table="mlparted_def1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted_def1 VALUES (42, 100)" +== 252 +-- truncate_limit: 100 +insert into mlparted_def2 values (54, 50) +-- +TABLE: name="mlparted_def2" schema="" table="mlparted_def2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted_def2 VALUES (54, 50)" +== 253 +-- truncate_limit: 100 +-- fail +insert into mlparted values (70, 100) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (70, 100)" +== 254 +-- truncate_limit: 100 +insert into mlparted_def1 values (52, 50) +-- +TABLE: name="mlparted_def1" schema="" table="mlparted_def1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted_def1 VALUES (52, 50)" +== 255 +-- truncate_limit: 100 +insert into mlparted_def2 values (34, 50) +-- +TABLE: name="mlparted_def2" schema="" table="mlparted_def2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted_def2 VALUES (34, 50)" +== 256 +-- truncate_limit: 100 +-- ok +create table mlparted_defd partition of mlparted_def default +-- +TABLE: name="mlparted_defd" schema="" table="mlparted_defd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted_defd PARTITION OF mlparted_def DEFAULT" +== 257 +-- truncate_limit: 100 +insert into mlparted values (70, 100) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (70, 100)" +== 258 +-- truncate_limit: 100 +select tableoid::regclass, * from mlparted_def +-- +TABLE: name="mlparted_def" schema="" table="mlparted_def" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM mlparted_def" +== 259 +-- truncate_limit: 100 +-- Check multi-level tuple routing with attributes dropped from the +-- top-most parent. First remove the last attribute. +alter table mlparted add d int, add e int +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ADD COLUMN d int, ADD COLUMN e int" +== 260 +-- truncate_limit: 100 +alter table mlparted drop e +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted DROP e" +== 261 +-- truncate_limit: 100 +create table mlparted5 partition of mlparted + for values from (1, 40) to (1, 50) partition by range (c) +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted5 PARTITION OF mlparted FOR VALUES FROM (1, 40) TO (1, 50) PARTITION BY RANG..." +== 262 +-- truncate_limit: 100 +create table mlparted5_ab partition of mlparted5 + for values from ('a') to ('c') partition by list (c) +-- +TABLE: name="mlparted5_ab" schema="" table="mlparted5_ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted5_ab PARTITION OF mlparted5 FOR VALUES FROM ('a') TO ('c') PARTITION BY LIST..." +== 263 +-- truncate_limit: 100 +-- This partitioned table should remain with no partitions. +create table mlparted5_cd partition of mlparted5 + for values from ('c') to ('e') partition by list (c) +-- +TABLE: name="mlparted5_cd" schema="" table="mlparted5_cd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted5_cd PARTITION OF mlparted5 FOR VALUES FROM ('c') TO ('e') PARTITION BY LIST..." +== 264 +-- truncate_limit: 100 +create table mlparted5_a partition of mlparted5_ab for values in ('a') +-- +TABLE: name="mlparted5_a" schema="" table="mlparted5_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted5_a PARTITION OF mlparted5_ab FOR VALUES IN ('a')" +== 265 +-- truncate_limit: 100 +create table mlparted5_b (d int, b int, c text, a int) +-- +TABLE: name="mlparted5_b" schema="" table="mlparted5_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mlparted5_b (d int, b int, c text, a int)" +== 266 +-- truncate_limit: 100 +alter table mlparted5_ab attach partition mlparted5_b for values in ('b') +-- +TABLE: name="mlparted5_ab" schema="" table="mlparted5_ab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted5_ab ATTACH PARTITION mlparted5_b FOR VALUES IN ('b')" +== 267 +-- truncate_limit: 100 +truncate mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mlparted" +== 268 +-- truncate_limit: 100 +insert into mlparted values (1, 2, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 2, 'a', 1)" +== 269 +-- truncate_limit: 100 +insert into mlparted values (1, 40, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 40, 'a', 1)" +== 270 +-- truncate_limit: 100 +-- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 45, 'b', 1)" +== 271 +-- truncate_limit: 100 +-- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 45, 'c', 1)" +== 272 +-- truncate_limit: 100 +-- goes to mlparted5_cd, fails +insert into mlparted values (1, 45, 'f', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 45, 'f', 1)" +== 273 +-- truncate_limit: 100 +-- goes to mlparted5, fails +select tableoid::regclass, * from mlparted order by a, b, c, d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM mlparted ORDER BY a, b, c, d" +== 274 +-- truncate_limit: 100 +alter table mlparted drop d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted DROP d" +== 275 +-- truncate_limit: 100 +truncate mlparted +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mlparted" +== 276 +-- truncate_limit: 100 +-- Remove the before last attribute. +alter table mlparted add e int, add d int +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted ADD COLUMN e int, ADD COLUMN d int" +== 277 +-- truncate_limit: 100 +alter table mlparted drop e +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted DROP e" +== 278 +-- truncate_limit: 100 +insert into mlparted values (1, 2, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 2, 'a', 1)" +== 279 +-- truncate_limit: 100 +insert into mlparted values (1, 40, 'a', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 40, 'a', 1)" +== 280 +-- truncate_limit: 100 +-- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 45, 'b', 1)" +== 281 +-- truncate_limit: 100 +-- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 45, 'c', 1)" +== 282 +-- truncate_limit: 100 +-- goes to mlparted5_cd, fails +insert into mlparted values (1, 45, 'f', 1) +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mlparted VALUES (1, 45, 'f', 1)" +== 283 +-- truncate_limit: 100 +-- goes to mlparted5, fails +select tableoid::regclass, * from mlparted order by a, b, c, d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM mlparted ORDER BY a, b, c, d" +== 284 +-- truncate_limit: 100 +alter table mlparted drop d +-- +TABLE: name="mlparted" schema="" table="mlparted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mlparted DROP d" +== 285 +-- truncate_limit: 100 +drop table mlparted5 +-- +TABLE: name="mlparted5" schema="" table="mlparted5" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mlparted5" +== 286 +-- truncate_limit: 100 +-- check that message shown after failure to find a partition shows the +-- appropriate key description (or none) in various situations +create table key_desc (a int, b int) partition by list ((a+0)) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE key_desc (a int, b int) PARTITION BY LIST ((a + 0))" +== 287 +-- truncate_limit: 100 +create table key_desc_1 partition of key_desc for values in (1) partition by range (b) +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE key_desc_1 PARTITION OF key_desc FOR VALUES IN (1) PARTITION BY RANGE (b)" +== 288 +-- truncate_limit: 100 +create user regress_insert_other_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_insert_other_user" +== 289 +-- truncate_limit: 100 +grant select (a) on key_desc_1 to regress_insert_other_user +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (a) ON key_desc_1 TO regress_insert_other_user" +== 290 +-- truncate_limit: 100 +grant insert on key_desc to regress_insert_other_user +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON key_desc TO regress_insert_other_user" +== 291 +-- truncate_limit: 100 +set role regress_insert_other_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_insert_other_user" +== 292 +-- truncate_limit: 100 +-- no key description is shown +insert into key_desc values (1, 1) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO key_desc VALUES (1, 1)" +== 293 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 294 +-- truncate_limit: 100 +grant select (b) on key_desc_1 to regress_insert_other_user +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (b) ON key_desc_1 TO regress_insert_other_user" +== 295 +-- truncate_limit: 100 +set role regress_insert_other_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_insert_other_user" +== 296 +-- truncate_limit: 100 +-- key description (b)=(1) is now shown +insert into key_desc values (1, 1) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO key_desc VALUES (1, 1)" +== 297 +-- truncate_limit: 100 +-- key description is not shown if key contains expression +insert into key_desc values (2, 1) +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO key_desc VALUES (2, 1)" +== 298 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 299 +-- truncate_limit: 100 +revoke all on key_desc from regress_insert_other_user +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON key_desc FROM regress_insert_other_user" +== 300 +-- truncate_limit: 100 +revoke all on key_desc_1 from regress_insert_other_user +-- +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON key_desc_1 FROM regress_insert_other_user" +== 301 +-- truncate_limit: 100 +drop role regress_insert_other_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_insert_other_user" +== 302 +-- truncate_limit: 100 +drop table key_desc, key_desc_1 +-- +TABLE: name="key_desc" schema="" table="key_desc" ctx=DDL +TABLE: name="key_desc_1" schema="" table="key_desc_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE key_desc, key_desc_1" +== 303 +-- truncate_limit: 100 +-- test minvalue/maxvalue restrictions +create table mcrparted (a int, b int, c int) partition by range (a, abs(b), c) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted (a int, b int, c int) PARTITION BY RANGE (a, (abs(b)), c)" +== 304 +-- truncate_limit: 100 +create table mcrparted0 partition of mcrparted for values from (minvalue, 0, 0) to (1, maxvalue, maxvalue) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted0 PARTITION OF mcrparted FOR VALUES FROM (minvalue, 0, 0) TO (1, maxvalue, ..." +== 305 +-- truncate_limit: 100 +create table mcrparted2 partition of mcrparted for values from (10, 6, minvalue) to (10, maxvalue, minvalue) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted2 PARTITION OF mcrparted FOR VALUES FROM (10, 6, minvalue) TO (10, maxvalue..." +== 306 +-- truncate_limit: 100 +create table mcrparted4 partition of mcrparted for values from (21, minvalue, 0) to (30, 20, minvalue) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted4 PARTITION OF mcrparted FOR VALUES FROM (21, minvalue, 0) TO (30, 20, minv..." +== 307 +-- truncate_limit: 100 +-- check multi-column range partitioning expression enforces the same +-- constraint as what tuple-routing would determine it to be +create table mcrparted0 partition of mcrparted for values from (minvalue, minvalue, minvalue) to (1, maxvalue, maxvalue) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted0 PARTITION OF mcrparted FOR VALUES FROM (minvalue, minvalue, minvalue) TO ..." +== 308 +-- truncate_limit: 100 +create table mcrparted1 partition of mcrparted for values from (2, 1, minvalue) to (10, 5, 10) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted1 PARTITION OF mcrparted FOR VALUES FROM (2, 1, minvalue) TO (10, 5, 10)" +== 309 +-- truncate_limit: 100 +create table mcrparted2 partition of mcrparted for values from (10, 6, minvalue) to (10, maxvalue, maxvalue) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted2 PARTITION OF mcrparted FOR VALUES FROM (10, 6, minvalue) TO (10, maxvalue..." +== 310 +-- truncate_limit: 100 +create table mcrparted3 partition of mcrparted for values from (11, 1, 1) to (20, 10, 10) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted3 PARTITION OF mcrparted FOR VALUES FROM (11, 1, 1) TO (20, 10, 10)" +== 311 +-- truncate_limit: 100 +create table mcrparted4 partition of mcrparted for values from (21, minvalue, minvalue) to (30, 20, maxvalue) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted4 PARTITION OF mcrparted FOR VALUES FROM (21, minvalue, minvalue) TO (30, 2..." +== 312 +-- truncate_limit: 100 +create table mcrparted5 partition of mcrparted for values from (30, 21, 20) to (maxvalue, maxvalue, maxvalue) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted5 PARTITION OF mcrparted FOR VALUES FROM (30, 21, 20) TO (maxvalue, maxvalu..." +== 313 +-- truncate_limit: 100 +-- null not allowed in range partition +insert into mcrparted values (null, null, null) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (NULL, NULL, NULL)" +== 314 +-- truncate_limit: 100 +-- routed to mcrparted0 +insert into mcrparted values (0, 1, 1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (0, 1, 1)" +== 315 +-- truncate_limit: 100 +insert into mcrparted0 values (0, 1, 1) +-- +TABLE: name="mcrparted0" schema="" table="mcrparted0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted0 VALUES (0, 1, 1)" +== 316 +-- truncate_limit: 100 +-- routed to mcparted1 +insert into mcrparted values (9, 1000, 1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (9, 1000, 1)" +== 317 +-- truncate_limit: 100 +insert into mcrparted1 values (9, 1000, 1) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted1 VALUES (9, 1000, 1)" +== 318 +-- truncate_limit: 100 +insert into mcrparted values (10, 5, -1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (10, 5, -1)" +== 319 +-- truncate_limit: 100 +insert into mcrparted1 values (10, 5, -1) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted1 VALUES (10, 5, -1)" +== 320 +-- truncate_limit: 100 +insert into mcrparted values (2, 1, 0) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (2, 1, 0)" +== 321 +-- truncate_limit: 100 +insert into mcrparted1 values (2, 1, 0) +-- +TABLE: name="mcrparted1" schema="" table="mcrparted1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted1 VALUES (2, 1, 0)" +== 322 +-- truncate_limit: 100 +-- routed to mcparted2 +insert into mcrparted values (10, 6, 1000) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (10, 6, 1000)" +== 323 +-- truncate_limit: 100 +insert into mcrparted2 values (10, 6, 1000) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted2 VALUES (10, 6, 1000)" +== 324 +-- truncate_limit: 100 +insert into mcrparted values (10, 1000, 1000) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (10, 1000, 1000)" +== 325 +-- truncate_limit: 100 +insert into mcrparted2 values (10, 1000, 1000) +-- +TABLE: name="mcrparted2" schema="" table="mcrparted2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted2 VALUES (10, 1000, 1000)" +== 326 +-- truncate_limit: 100 +-- no partition exists, nor does mcrparted3 accept it +insert into mcrparted values (11, 1, -1) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (11, 1, -1)" +== 327 +-- truncate_limit: 100 +insert into mcrparted3 values (11, 1, -1) +-- +TABLE: name="mcrparted3" schema="" table="mcrparted3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted3 VALUES (11, 1, -1)" +== 328 +-- truncate_limit: 100 +-- routed to mcrparted5 +insert into mcrparted values (30, 21, 20) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (30, 21, 20)" +== 329 +-- truncate_limit: 100 +insert into mcrparted5 values (30, 21, 20) +-- +TABLE: name="mcrparted5" schema="" table="mcrparted5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted5 VALUES (30, 21, 20)" +== 330 +-- truncate_limit: 100 +insert into mcrparted4 values (30, 21, 20) +-- +TABLE: name="mcrparted4" schema="" table="mcrparted4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted4 VALUES (30, 21, 20)" +== 331 +-- truncate_limit: 100 +-- error + +-- check rows +select tableoid::regclass::text, * from mcrparted order by 1 +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM mcrparted ORDER BY 1" +== 332 +-- truncate_limit: 100 +-- cleanup +drop table mcrparted +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcrparted" +== 333 +-- truncate_limit: 100 +-- check that a BR constraint can't make partition contain violating rows +create table brtrigpartcon (a int, b text) partition by list (a) +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brtrigpartcon (a int, b text) PARTITION BY LIST (a)" +== 334 +-- truncate_limit: 100 +create table brtrigpartcon1 partition of brtrigpartcon for values in (1) +-- +TABLE: name="brtrigpartcon1" schema="" table="brtrigpartcon1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brtrigpartcon1 PARTITION OF brtrigpartcon FOR VALUES IN (1)" +== 335 +-- truncate_limit: 100 +create or replace function brtrigpartcon1trigf() returns trigger as $$begin new.a := 2; return new; end$$ language plpgsql +-- +FUNCTION: name="brtrigpartcon1trigf" function="brtrigpartcon1trigf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION brtrigpartcon1trigf() RETURNS trigger AS $$begin new.a := 2; return ne..." +== 336 +-- truncate_limit: 100 +create trigger brtrigpartcon1trig before insert on brtrigpartcon1 for each row execute procedure brtrigpartcon1trigf() +-- +TABLE: name="brtrigpartcon1" schema="" table="brtrigpartcon1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER brtrigpartcon1trig BEFORE INSERT ON brtrigpartcon1 FOR EACH ROW EXECUTE FUNCTION b..." +== 337 +-- truncate_limit: 100 +insert into brtrigpartcon values (1, 'hi there') +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brtrigpartcon VALUES (1, 'hi there')" +== 338 +-- truncate_limit: 100 +insert into brtrigpartcon1 values (1, 'hi there') +-- +TABLE: name="brtrigpartcon1" schema="" table="brtrigpartcon1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brtrigpartcon1 VALUES (1, 'hi there')" +== 339 +-- truncate_limit: 100 +-- check that the message shows the appropriate column description in a +-- situation where the partitioned table is not the primary ModifyTable node +create table inserttest3 (f1 text default 'foo', f2 text default 'bar', f3 int) +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inserttest3 (f1 text DEFAULT 'foo', f2 text DEFAULT 'bar', f3 int)" +== 340 +-- truncate_limit: 100 +create role regress_coldesc_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_coldesc_role" +== 341 +-- truncate_limit: 100 +grant insert on inserttest3 to regress_coldesc_role +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON inserttest3 TO regress_coldesc_role" +== 342 +-- truncate_limit: 100 +grant insert on brtrigpartcon to regress_coldesc_role +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON brtrigpartcon TO regress_coldesc_role" +== 343 +-- truncate_limit: 100 +revoke select on brtrigpartcon from regress_coldesc_role +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select ON brtrigpartcon FROM regress_coldesc_role" +== 344 +-- truncate_limit: 100 +set role regress_coldesc_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_coldesc_role" +== 345 +-- truncate_limit: 100 +with result as (insert into brtrigpartcon values (1, 'hi there') returning 1) + insert into inserttest3 (f3) select * from result +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DML +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DML +CTE: "result" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH result AS (...) INSERT INTO inserttest3 (f3) SELECT * FROM result" +== 346 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 347 +-- truncate_limit: 100 +-- cleanup +revoke all on inserttest3 from regress_coldesc_role +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON inserttest3 FROM regress_coldesc_role" +== 348 +-- truncate_limit: 100 +revoke all on brtrigpartcon from regress_coldesc_role +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON brtrigpartcon FROM regress_coldesc_role" +== 349 +-- truncate_limit: 100 +drop role regress_coldesc_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_coldesc_role" +== 350 +-- truncate_limit: 100 +drop table inserttest3 +-- +TABLE: name="inserttest3" schema="" table="inserttest3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inserttest3" +== 351 +-- truncate_limit: 100 +drop table brtrigpartcon +-- +TABLE: name="brtrigpartcon" schema="" table="brtrigpartcon" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brtrigpartcon" +== 352 +-- truncate_limit: 100 +drop function brtrigpartcon1trigf() +-- +FUNCTION: name="brtrigpartcon1trigf" function="brtrigpartcon1trigf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION brtrigpartcon1trigf()" +== 353 +-- truncate_limit: 100 +-- check that "do nothing" BR triggers work with tuple-routing +create table donothingbrtrig_test (a int, b text) partition by list (a) +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE donothingbrtrig_test (a int, b text) PARTITION BY LIST (a)" +== 354 +-- truncate_limit: 100 +create table donothingbrtrig_test1 (b text, a int) +-- +TABLE: name="donothingbrtrig_test1" schema="" table="donothingbrtrig_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE donothingbrtrig_test1 (b text, a int)" +== 355 +-- truncate_limit: 100 +create table donothingbrtrig_test2 (c text, b text, a int) +-- +TABLE: name="donothingbrtrig_test2" schema="" table="donothingbrtrig_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE donothingbrtrig_test2 (c text, b text, a int)" +== 356 +-- truncate_limit: 100 +alter table donothingbrtrig_test2 drop column c +-- +TABLE: name="donothingbrtrig_test2" schema="" table="donothingbrtrig_test2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE donothingbrtrig_test2 DROP c" +== 357 +-- truncate_limit: 100 +create or replace function donothingbrtrig_func() returns trigger as $$begin raise notice 'b: %', new.b; return NULL; end$$ language plpgsql +-- +FUNCTION: name="donothingbrtrig_func" function="donothingbrtrig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION donothingbrtrig_func() RETURNS trigger AS $$begin raise notice 'b: %',..." +== 358 +-- truncate_limit: 100 +create trigger donothingbrtrig1 before insert on donothingbrtrig_test1 for each row execute procedure donothingbrtrig_func() +-- +TABLE: name="donothingbrtrig_test1" schema="" table="donothingbrtrig_test1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER donothingbrtrig1 BEFORE INSERT ON donothingbrtrig_test1 FOR EACH ROW EXECUTE FUNCT..." +== 359 +-- truncate_limit: 100 +create trigger donothingbrtrig2 before insert on donothingbrtrig_test2 for each row execute procedure donothingbrtrig_func() +-- +TABLE: name="donothingbrtrig_test2" schema="" table="donothingbrtrig_test2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER donothingbrtrig2 BEFORE INSERT ON donothingbrtrig_test2 FOR EACH ROW EXECUTE FUNCT..." +== 360 +-- truncate_limit: 100 +alter table donothingbrtrig_test attach partition donothingbrtrig_test1 for values in (1) +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE donothingbrtrig_test ATTACH PARTITION donothingbrtrig_test1 FOR VALUES IN (1)" +== 361 +-- truncate_limit: 100 +alter table donothingbrtrig_test attach partition donothingbrtrig_test2 for values in (2) +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE donothingbrtrig_test ATTACH PARTITION donothingbrtrig_test2 FOR VALUES IN (2)" +== 362 +-- truncate_limit: 100 +insert into donothingbrtrig_test values (1, 'foo'), (2, 'bar') +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO donothingbrtrig_test VALUES (1, 'foo'), (2, 'bar')" +== 363 +-- truncate_limit: 100 +copy donothingbrtrig_test from stdout +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY donothingbrtrig_test FROM STDIN" +== 364 +-- truncate_limit: 100 +1 baz +2 qux +select tableoid::regclass, * from donothingbrtrig_test +-- +ERROR: syntax error at or near "1" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 365 +-- truncate_limit: 100 +-- cleanup +drop table donothingbrtrig_test +-- +TABLE: name="donothingbrtrig_test" schema="" table="donothingbrtrig_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE donothingbrtrig_test" +== 366 +-- truncate_limit: 100 +drop function donothingbrtrig_func() +-- +FUNCTION: name="donothingbrtrig_func" function="donothingbrtrig_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION donothingbrtrig_func()" +== 367 +-- truncate_limit: 100 +-- check multi-column range partitioning with minvalue/maxvalue constraints +create table mcrparted (a text, b int) partition by range(a, b) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted (a text, b int) PARTITION BY RANGE (a, b)" +== 368 +-- truncate_limit: 100 +create table mcrparted1_lt_b partition of mcrparted for values from (minvalue, minvalue) to ('b', minvalue) +-- +TABLE: name="mcrparted1_lt_b" schema="" table="mcrparted1_lt_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted1_lt_b PARTITION OF mcrparted FOR VALUES FROM (minvalue, minvalue) TO ('b',..." +== 369 +-- truncate_limit: 100 +create table mcrparted2_b partition of mcrparted for values from ('b', minvalue) to ('c', minvalue) +-- +TABLE: name="mcrparted2_b" schema="" table="mcrparted2_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted2_b PARTITION OF mcrparted FOR VALUES FROM ('b', minvalue) TO ('c', minvalue)" +== 370 +-- truncate_limit: 100 +create table mcrparted3_c_to_common partition of mcrparted for values from ('c', minvalue) to ('common', minvalue) +-- +TABLE: name="mcrparted3_c_to_common" schema="" table="mcrparted3_c_to_common" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted3_c_to_common PARTITION OF mcrparted FOR VALUES FROM ('c', minvalue) TO ('c..." +== 371 +-- truncate_limit: 100 +create table mcrparted4_common_lt_0 partition of mcrparted for values from ('common', minvalue) to ('common', 0) +-- +TABLE: name="mcrparted4_common_lt_0" schema="" table="mcrparted4_common_lt_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted4_common_lt_0 PARTITION OF mcrparted FOR VALUES FROM ('common', minvalue) T..." +== 372 +-- truncate_limit: 100 +create table mcrparted5_common_0_to_10 partition of mcrparted for values from ('common', 0) to ('common', 10) +-- +TABLE: name="mcrparted5_common_0_to_10" schema="" table="mcrparted5_common_0_to_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted5_common_0_to_10 PARTITION OF mcrparted FOR VALUES FROM ('common', 0) TO ('..." +== 373 +-- truncate_limit: 100 +create table mcrparted6_common_ge_10 partition of mcrparted for values from ('common', 10) to ('common', maxvalue) +-- +TABLE: name="mcrparted6_common_ge_10" schema="" table="mcrparted6_common_ge_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted6_common_ge_10 PARTITION OF mcrparted FOR VALUES FROM ('common', 10) TO ('c..." +== 374 +-- truncate_limit: 100 +create table mcrparted7_gt_common_lt_d partition of mcrparted for values from ('common', maxvalue) to ('d', minvalue) +-- +TABLE: name="mcrparted7_gt_common_lt_d" schema="" table="mcrparted7_gt_common_lt_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted7_gt_common_lt_d PARTITION OF mcrparted FOR VALUES FROM ('common', maxvalue..." +== 375 +-- truncate_limit: 100 +create table mcrparted8_ge_d partition of mcrparted for values from ('d', minvalue) to (maxvalue, maxvalue) +-- +TABLE: name="mcrparted8_ge_d" schema="" table="mcrparted8_ge_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcrparted8_ge_d PARTITION OF mcrparted FOR VALUES FROM ('d', minvalue) TO (maxvalue,..." +== 376 +-- truncate_limit: 100 +insert into mcrparted values ('aaa', 0), ('b', 0), ('bz', 10), ('c', -10), + ('comm', -10), ('common', -10), ('common', 0), ('common', 10), + ('commons', 0), ('d', -10), ('e', 0) +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcrparted VALUES (...)" +== 377 +-- truncate_limit: 100 +select tableoid::regclass, * from mcrparted order by a, b +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM mcrparted ORDER BY a, b" +== 378 +-- truncate_limit: 100 +drop table mcrparted +-- +TABLE: name="mcrparted" schema="" table="mcrparted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcrparted" +== 379 +-- truncate_limit: 100 +-- check that wholerow vars in the RETURNING list work with partitioned tables +create table returningwrtest (a int) partition by list (a) +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE returningwrtest (a int) PARTITION BY LIST (a)" +== 380 +-- truncate_limit: 100 +create table returningwrtest1 partition of returningwrtest for values in (1) +-- +TABLE: name="returningwrtest1" schema="" table="returningwrtest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE returningwrtest1 PARTITION OF returningwrtest FOR VALUES IN (1)" +== 381 +-- truncate_limit: 100 +insert into returningwrtest values (1) returning returningwrtest +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO returningwrtest VALUES (1) RETURNING returningwrtest" +== 382 +-- truncate_limit: 100 +-- check also that the wholerow vars in RETURNING list are converted as needed +alter table returningwrtest add b text +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE returningwrtest ADD COLUMN b text" +== 383 +-- truncate_limit: 100 +create table returningwrtest2 (b text, c int, a int) +-- +TABLE: name="returningwrtest2" schema="" table="returningwrtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE returningwrtest2 (b text, c int, a int)" +== 384 +-- truncate_limit: 100 +alter table returningwrtest2 drop c +-- +TABLE: name="returningwrtest2" schema="" table="returningwrtest2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE returningwrtest2 DROP c" +== 385 +-- truncate_limit: 100 +alter table returningwrtest attach partition returningwrtest2 for values in (2) +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE returningwrtest ATTACH PARTITION returningwrtest2 FOR VALUES IN (2)" +== 386 +-- truncate_limit: 100 +insert into returningwrtest values (2, 'foo') returning returningwrtest +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO returningwrtest VALUES (2, 'foo') RETURNING returningwrtest" +== 387 +-- truncate_limit: 100 +drop table returningwrtest +-- +TABLE: name="returningwrtest" schema="" table="returningwrtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE returningwrtest" diff --git a/parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json b/parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json new file mode 100644 index 0000000..1b73a29 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json @@ -0,0 +1,261 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/insert_conflict.test b/parser/testdata/summary_truncate/postgres_regress/insert_conflict.test new file mode 100644 index 0000000..bb8930a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/insert_conflict.test @@ -0,0 +1,2205 @@ +== 001 +-- truncate_limit: 100 +|-- +-- insert...on conflict do unique index inference +|-- +create table insertconflicttest(key int4, fruit text) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE insertconflicttest (key int4, fruit text)" +== 002 +-- truncate_limit: 100 +-- These things should work through a view, as well +create view insertconflictview as select * from insertconflicttest +-- +TABLE: name="insertconflictview" schema="" table="insertconflictview" ctx=DDL +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW insertconflictview AS SELECT * FROM insertconflicttest" +== 003 +-- truncate_limit: 100 +|-- +-- Test unique index inference with operator class specifications and +-- named collations +|-- +create unique index op_index_key on insertconflicttest(key, fruit text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX op_index_key ON insertconflicttest USING btree (key, fruit text_pattern_ops)" +== 004 +-- truncate_limit: 100 +create unique index collation_index_key on insertconflicttest(key, fruit collate "C") +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX collation_index_key ON insertconflicttest USING btree (key, fruit COLLATE \"C\")" +== 005 +-- truncate_limit: 100 +create unique index both_index_key on insertconflicttest(key, fruit collate "C" text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX both_index_key ON insertconflicttest USING btree (key, fruit COLLATE \"C\" text..." +== 006 +-- truncate_limit: 100 +create unique index both_index_expr_key on insertconflicttest(key, lower(fruit) collate "C" text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX both_index_expr_key ON insertconflicttest USING btree (key, lower(fruit) COLL..." +== 007 +-- truncate_limit: 100 +-- fails +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (key) DO N..." +== 008 +-- truncate_limit: 100 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (fruit) DO..." +== 009 +-- truncate_limit: 100 +-- succeeds +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (key, frui..." +== 010 +-- truncate_limit: 100 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (fruit, ke..." +== 011 +-- truncate_limit: 100 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (lower(fru..." +== 012 +-- truncate_limit: 100 +explain (costs off) insert into insertconflictview values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing +-- +TABLE: name="insertconflictview" schema="" table="insertconflictview" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflictview VALUES (0, 'Crowberry') ON CONFLICT (lower(fru..." +== 013 +-- truncate_limit: 100 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do update set fruit = excluded.fruit + where exists (select 1 from insertconflicttest ii where ii.key = excluded.key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=Select +ALIAS: "ii"="insertconflicttest" +FILTER: schema="" table="ii" column="key" +FILTER: schema="" table="excluded" column="key" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (key, frui..." +== 014 +-- truncate_limit: 100 +-- Neither collation nor operator class specifications are required -- +-- supplying them merely *limits* matches to indexes with matching opclasses +-- used for relevant indexes +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit text_pattern_ops) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (key, frui..." +== 015 +-- truncate_limit: 100 +-- Okay, arbitrates using both index where text_pattern_ops opclass does and +-- does not appear. +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit collate "C") do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (key, frui..." +== 016 +-- truncate_limit: 100 +-- Okay, but only accepts the single index where both opclass and collation are +-- specified +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit collate "C" text_pattern_ops, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (fruit COL..." +== 017 +-- truncate_limit: 100 +-- Okay, but only accepts the single index where both opclass and collation are +-- specified (plus expression variant) +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C", key, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (lower(fru..." +== 018 +-- truncate_limit: 100 +-- Attribute appears twice, while not all attributes/expressions on attributes +-- appearing within index definition match in terms of both opclass and +-- collation. +|-- +-- Works because every attribute in inference specification needs to be +-- satisfied once or more by cataloged index attribute, and as always when an +-- attribute in the cataloged definition has a non-default opclass/collation, +-- it still satisfied some inference attribute lacking any particular +-- opclass/collation specification. +|-- +-- The implementation is liberal in accepting inference specifications on the +-- assumption that multiple inferred unique indexes will prevent problematic +-- cases. It rolls with unique indexes where attributes redundantly appear +-- multiple times, too (which is not tested here). +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit text_pattern_ops, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (fruit, ke..." +== 019 +-- truncate_limit: 100 +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C" text_pattern_ops, key, key) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (lower(fru..." +== 020 +-- truncate_limit: 100 +drop index op_index_key +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX op_index_key" +== 021 +-- truncate_limit: 100 +drop index collation_index_key +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX collation_index_key" +== 022 +-- truncate_limit: 100 +drop index both_index_key +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX both_index_key" +== 023 +-- truncate_limit: 100 +drop index both_index_expr_key +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX both_index_expr_key" +== 024 +-- truncate_limit: 100 +|-- +-- Make sure that cross matching of attribute opclass/collation does not occur +|-- +create unique index cross_match on insertconflicttest(lower(fruit) collate "C", upper(fruit) text_pattern_ops) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX cross_match ON insertconflicttest USING btree (lower(fruit) COLLATE \"C\", uppe..." +== 025 +-- truncate_limit: 100 +-- fails: +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) text_pattern_ops, upper(fruit) collate "C") do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (lower(fru..." +== 026 +-- truncate_limit: 100 +-- works: +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C", upper(fruit) text_pattern_ops) do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (lower(fru..." +== 027 +-- truncate_limit: 100 +drop index cross_match +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX cross_match" +== 028 +-- truncate_limit: 100 +|-- +-- Single key tests +|-- +create unique index key_index on insertconflicttest(key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX key_index ON insertconflicttest USING btree (key)" +== 029 +-- truncate_limit: 100 +|-- +-- Explain tests +|-- +explain (costs off) insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Bilberry') ON CONFLICT (key) DO UP..." +== 030 +-- truncate_limit: 100 +-- Should display qual actually attributable to internal sequential scan: +explain (costs off) insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Cawesh' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Bilberry') ON CONFLICT (key) DO UP..." +== 031 +-- truncate_limit: 100 +-- With EXCLUDED.* expression in scan node: +explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key) do update set fruit = excluded.fruit where excluded.fruit != 'Elderberry' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (0, 'Crowberry') ON CONFLICT (key) DO U..." +== 032 +-- truncate_limit: 100 +-- Does the same, but JSON format shows "Conflict Arbiter Index" as JSON array: +explain (costs off, format json) insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Lime' returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, FORMAT \"json\") INSERT INTO insertconflicttest VALUES (0, 'Bilberry') ON CONFL..." +== 033 +-- truncate_limit: 100 +-- Fails (no unique index inference specification, required for do update variant): +insert into insertconflicttest values (1, 'Apple') on conflict do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (1, 'Apple') ON CONFLICT DO UPDATE SET fruit = excluded.fruit" +== 034 +-- truncate_limit: 100 +-- inference succeeds: +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (1, 'Apple') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 035 +-- truncate_limit: 100 +insert into insertconflicttest values (2, 'Orange') on conflict (key, key, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, key, key) DO UPDATE SET ... = ..." +== 036 +-- truncate_limit: 100 +-- Succeed, since multi-assignment does not involve subquery: +insert into insertconflicttest +values (1, 'Apple'), (2, 'Orange') +on conflict (key) do update set (fruit, key) = (excluded.fruit, excluded.key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ..." +== 037 +-- truncate_limit: 100 +-- Give good diagnostic message when EXCLUDED.* spuriously referenced from +-- RETURNING: +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit RETURNING excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... RETURNING e..." +== 038 +-- truncate_limit: 100 +-- Only suggest
      .* column when inference element misspelled: +insert into insertconflicttest values (1, 'Apple') on conflict (keyy) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (1, 'Apple') ON CONFLICT (keyy) DO UPDATE SET ... = ..." +== 039 +-- truncate_limit: 100 +-- Have useful HINT for EXCLUDED.* RTE within UPDATE: +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruitt +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (1, 'Apple') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 040 +-- truncate_limit: 100 +-- inference fails: +insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (3, 'Kiwi') ON CONFLICT (key, fruit) DO UPDATE SET ... = ..." +== 041 +-- truncate_limit: 100 +insert into insertconflicttest values (4, 'Mango') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (4, 'Mango') ON CONFLICT (fruit, key) DO UPDATE SET ... = ..." +== 042 +-- truncate_limit: 100 +insert into insertconflicttest values (5, 'Lemon') on conflict (fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (5, 'Lemon') ON CONFLICT (fruit) DO UPDATE SET ... = ..." +== 043 +-- truncate_limit: 100 +insert into insertconflicttest values (6, 'Passionfruit') on conflict (lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (lower(fruit)) DO UPDATE SET ... = ..." +== 044 +-- truncate_limit: 100 +-- Check the target relation can be aliased +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "ict"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS ict VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ..." +== 045 +-- truncate_limit: 100 +-- ok, no reference to target table +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = ict.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "ict"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS ict VALUES (...) ON CONFLICT (key) DO UPDATE SET fruit = ict.fruit" +== 046 +-- truncate_limit: 100 +-- ok, alias +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = insertconflicttest.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "ict"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS ict VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ..." +== 047 +-- truncate_limit: 100 +-- error, references aliased away name + +-- Check helpful hint when qualifying set column with target table +insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set insertconflicttest.fruit = 'Mango' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (3, 'Kiwi') ON CONFLICT (key, fruit) DO UPDATE SET ... = ..." +== 048 +-- truncate_limit: 100 +drop index key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX key_index" +== 049 +-- truncate_limit: 100 +|-- +-- Composite key tests +|-- +create unique index comp_key_index on insertconflicttest(key, fruit) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX comp_key_index ON insertconflicttest USING btree (key, fruit)" +== 050 +-- truncate_limit: 100 +-- inference succeeds: +insert into insertconflicttest values (7, 'Raspberry') on conflict (key, fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, fruit) DO UPDATE SET ... = ..." +== 051 +-- truncate_limit: 100 +insert into insertconflicttest values (8, 'Lime') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (8, 'Lime') ON CONFLICT (fruit, key) DO UPDATE SET ... = ..." +== 052 +-- truncate_limit: 100 +-- inference fails: +insert into insertconflicttest values (9, 'Banana') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (9, 'Banana') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 053 +-- truncate_limit: 100 +insert into insertconflicttest values (10, 'Blueberry') on conflict (key, key, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, key, key) DO UPDATE SET ... = ..." +== 054 +-- truncate_limit: 100 +insert into insertconflicttest values (11, 'Cherry') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, lower(fruit)) DO UPDATE SET ... = ..." +== 055 +-- truncate_limit: 100 +insert into insertconflicttest values (12, 'Date') on conflict (lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (lower(fruit), key) DO UPDATE SET ... = ..." +== 056 +-- truncate_limit: 100 +drop index comp_key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX comp_key_index" +== 057 +-- truncate_limit: 100 +|-- +-- Partial index tests, no inference predicate specified +|-- +create unique index part_comp_key_index on insertconflicttest(key, fruit) where key < 5 +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX part_comp_key_index ON insertconflicttest USING btree (key, fruit) WHERE key < 5" +== 058 +-- truncate_limit: 100 +create unique index expr_part_comp_key_index on insertconflicttest(key, lower(fruit)) where key < 5 +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX expr_part_comp_key_index ON insertconflicttest USING btree (key, lower(fruit)..." +== 059 +-- truncate_limit: 100 +-- inference fails: +insert into insertconflicttest values (13, 'Grape') on conflict (key, fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (13, 'Grape') ON CONFLICT (key, fruit) DO UPDATE SET ... = ..." +== 060 +-- truncate_limit: 100 +insert into insertconflicttest values (14, 'Raisin') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (fruit, key) DO UPDATE SET ... = ..." +== 061 +-- truncate_limit: 100 +insert into insertconflicttest values (15, 'Cranberry') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (15, 'Cranberry') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 062 +-- truncate_limit: 100 +insert into insertconflicttest values (16, 'Melon') on conflict (key, key, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, key, key) DO UPDATE SET ... = ..." +== 063 +-- truncate_limit: 100 +insert into insertconflicttest values (17, 'Mulberry') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, lower(fruit)) DO UPDATE SET ... = ..." +== 064 +-- truncate_limit: 100 +insert into insertconflicttest values (18, 'Pineapple') on conflict (lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (lower(fruit), key) DO UPDATE SET ... = ..." +== 065 +-- truncate_limit: 100 +drop index part_comp_key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX part_comp_key_index" +== 066 +-- truncate_limit: 100 +drop index expr_part_comp_key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX expr_part_comp_key_index" +== 067 +-- truncate_limit: 100 +|-- +-- Expression index tests +|-- +create unique index expr_key_index on insertconflicttest(lower(fruit)) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX expr_key_index ON insertconflicttest USING btree (lower(fruit))" +== 068 +-- truncate_limit: 100 +-- inference succeeds: +insert into insertconflicttest values (20, 'Quince') on conflict (lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (lower(fruit)) DO UPDATE SET ... = ..." +== 069 +-- truncate_limit: 100 +insert into insertconflicttest values (21, 'Pomegranate') on conflict (lower(fruit), lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (lower(fruit), lower(fruit)) DO UPDATE SE..." +== 070 +-- truncate_limit: 100 +-- inference fails: +insert into insertconflicttest values (22, 'Apricot') on conflict (upper(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (upper(fruit)) DO UPDATE SET ... = ..." +== 071 +-- truncate_limit: 100 +insert into insertconflicttest values (23, 'Blackberry') on conflict (fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (23, 'Blackberry') ON CONFLICT (fruit) DO UPDATE SET ... = ..." +== 072 +-- truncate_limit: 100 +drop index expr_key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX expr_key_index" +== 073 +-- truncate_limit: 100 +|-- +-- Expression index tests (with regular column) +|-- +create unique index expr_comp_key_index on insertconflicttest(key, lower(fruit)) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX expr_comp_key_index ON insertconflicttest USING btree (key, lower(fruit))" +== 074 +-- truncate_limit: 100 +create unique index tricky_expr_comp_key_index on insertconflicttest(key, lower(fruit), upper(fruit)) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX tricky_expr_comp_key_index ON insertconflicttest USING btree (key, lower(frui..." +== 075 +-- truncate_limit: 100 +-- inference succeeds: +insert into insertconflicttest values (24, 'Plum') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, lower(fruit)) DO UPDATE SET ... = ..." +== 076 +-- truncate_limit: 100 +insert into insertconflicttest values (25, 'Peach') on conflict (lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (lower(fruit), key) DO UPDATE SET ... = ..." +== 077 +-- truncate_limit: 100 +-- Should not infer "tricky_expr_comp_key_index" index: +explain (costs off) insert into insertconflicttest values (26, 'Fig') on conflict (lower(fruit), key, lower(fruit), key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest VALUES (26, 'Fig') ON CONFLICT (lower(fruit), ..." +== 078 +-- truncate_limit: 100 +-- inference fails: +insert into insertconflicttest values (27, 'Prune') on conflict (key, upper(fruit)) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key, upper(fruit)) DO UPDATE SET ... = ..." +== 079 +-- truncate_limit: 100 +insert into insertconflicttest values (28, 'Redcurrant') on conflict (fruit, key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (fruit, key) DO UPDATE SET ... = ..." +== 080 +-- truncate_limit: 100 +insert into insertconflicttest values (29, 'Nectarine') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (29, 'Nectarine') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 081 +-- truncate_limit: 100 +drop index expr_comp_key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX expr_comp_key_index" +== 082 +-- truncate_limit: 100 +drop index tricky_expr_comp_key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX tricky_expr_comp_key_index" +== 083 +-- truncate_limit: 100 +|-- +-- Non-spurious duplicate violation tests +|-- +create unique index key_index on insertconflicttest(key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX key_index ON insertconflicttest USING btree (key)" +== 084 +-- truncate_limit: 100 +create unique index fruit_index on insertconflicttest(fruit) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX fruit_index ON insertconflicttest USING btree (fruit)" +== 085 +-- truncate_limit: 100 +-- succeeds, since UPDATE happens to update "fruit" to existing value: +insert into insertconflicttest values (26, 'Fig') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (26, 'Fig') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 086 +-- truncate_limit: 100 +-- fails, since UPDATE is to row with key value 26, and we're updating "fruit" +-- to a value that happens to exist in another row ('peach'): +insert into insertconflicttest values (26, 'Peach') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (26, 'Peach') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 087 +-- truncate_limit: 100 +-- succeeds, since "key" isn't repeated/referenced in UPDATE, and "fruit" +-- arbitrates that statement updates existing "Fig" row: +insert into insertconflicttest values (25, 'Fig') on conflict (fruit) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (25, 'Fig') ON CONFLICT (fruit) DO UPDATE SET ... = ..." +== 088 +-- truncate_limit: 100 +drop index key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX key_index" +== 089 +-- truncate_limit: 100 +drop index fruit_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX fruit_index" +== 090 +-- truncate_limit: 100 +|-- +-- Test partial unique index inference +|-- +create unique index partial_key_index on insertconflicttest(key) where fruit like '%berry' +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX partial_key_index ON insertconflicttest USING btree (key) WHERE ..." +== 091 +-- truncate_limit: 100 +-- Succeeds +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like '%berry' do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (key) WHERE ... DO UPDATE SET ... = ..." +== 092 +-- truncate_limit: 100 +insert into insertconflicttest as t values (23, 'Blackberry') on conflict (key) where fruit like '%berry' and t.fruit = 'inconsequential' do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "t"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS t VALUES (23, 'Blackberry') ON CONFLICT (key) WHERE ... DO NOTHING" +== 093 +-- truncate_limit: 100 +insert into insertconflictview as t values (23, 'Blackberry') on conflict (key) where fruit like '%berry' and t.fruit = 'inconsequential' do nothing +-- +TABLE: name="insertconflictview" schema="" table="insertconflictview" ctx=DML +ALIAS: "t"="insertconflictview" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflictview AS t VALUES (23, 'Blackberry') ON CONFLICT (key) WHERE ... DO NOTHING" +== 094 +-- truncate_limit: 100 +-- fails +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (23, 'Blackberry') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 095 +-- truncate_limit: 100 +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like '%berry' or fruit = 'consequential' do nothing +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (23, 'Blackberry') ON CONFLICT (key) WHERE ... DO NOTHING" +== 096 +-- truncate_limit: 100 +insert into insertconflicttest values (23, 'Blackberry') on conflict (fruit) where fruit like '%berry' do update set fruit = excluded.fruit +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest VALUES (...) ON CONFLICT (fruit) WHERE ... DO UPDATE SET ... = ..." +== 097 +-- truncate_limit: 100 +drop index partial_key_index +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX partial_key_index" +== 098 +-- truncate_limit: 100 +|-- +-- Test that wholerow references to ON CONFLICT's EXCLUDED work +|-- +create unique index plain on insertconflicttest(key) +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX plain ON insertconflicttest USING btree (key)" +== 099 +-- truncate_limit: 100 +-- Succeeds, updates existing row: +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* != excluded.* returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS i VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... WHERE ..." +== 100 +-- truncate_limit: 100 +-- No update this time, though: +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* != excluded.* returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS i VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... WHERE ..." +== 101 +-- truncate_limit: 100 +-- Predicate changed to require match rather than non-match, so updates once more: +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* = excluded.* returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS i VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... WHERE ..." +== 102 +-- truncate_limit: 100 +-- Assign: +insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text + returning * +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflicttest AS i VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... RETURN..." +== 103 +-- truncate_limit: 100 +-- deparse whole row var in WHERE and SET clauses: +explain (costs off) insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.fruit where excluded.* is null +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest AS i VALUES (23, 'Avocado') ON CONFLICT (key) ..." +== 104 +-- truncate_limit: 100 +explain (costs off) insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DML +ALIAS: "i"="insertconflicttest" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO insertconflicttest AS i VALUES (23, 'Avocado') ON CONFLICT (key) ..." +== 105 +-- truncate_limit: 100 +drop index plain +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX plain" +== 106 +-- truncate_limit: 100 +-- Cleanup +drop view insertconflictview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW insertconflictview" +== 107 +-- truncate_limit: 100 +drop table insertconflicttest +-- +TABLE: name="insertconflicttest" schema="" table="insertconflicttest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE insertconflicttest" +== 108 +-- truncate_limit: 100 +|-- +-- Verify that EXCLUDED does not allow system column references. These +-- do not make sense because EXCLUDED isn't an already stored tuple +-- (and thus doesn't have a ctid etc). +|-- +create table syscolconflicttest(key int4, data text) +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE syscolconflicttest (key int4, data text)" +== 109 +-- truncate_limit: 100 +insert into syscolconflicttest values (1) +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO syscolconflicttest VALUES (1)" +== 110 +-- truncate_limit: 100 +insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.ctid::text +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO syscolconflicttest VALUES (1) ON CONFLICT (key) DO UPDATE SET data = excluded.ctid::text" +== 111 +-- truncate_limit: 100 +drop table syscolconflicttest +-- +TABLE: name="syscolconflicttest" schema="" table="syscolconflicttest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE syscolconflicttest" +== 112 +-- truncate_limit: 100 +|-- +-- Previous tests all managed to not test any expressions requiring +-- planner preprocessing ... +|-- +create table insertconflict (a bigint, b bigint) +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE insertconflict (a bigint, b bigint)" +== 113 +-- truncate_limit: 100 +create unique index insertconflicti1 on insertconflict(coalesce(a, 0)) +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX insertconflicti1 ON insertconflict USING btree (COALESCE(a, 0))" +== 114 +-- truncate_limit: 100 +create unique index insertconflicti2 on insertconflict(b) + where coalesce(a, 1) > 0 +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX insertconflicti2 ON insertconflict USING btree (b) WHERE COALESCE(a, 1) > 0" +== 115 +-- truncate_limit: 100 +insert into insertconflict values (1, 2) +on conflict (coalesce(a, 0)) do nothing +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflict VALUES (1, 2) ON CONFLICT (COALESCE(a, 0)) DO NOTHING" +== 116 +-- truncate_limit: 100 +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 0 do nothing +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflict VALUES (1, 2) ON CONFLICT (b) WHERE COALESCE(a, 1) > 0 DO NOTHING" +== 117 +-- truncate_limit: 100 +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 1 do nothing +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflict VALUES (1, 2) ON CONFLICT (b) WHERE COALESCE(a, 1) > 1 DO NOTHING" +== 118 +-- truncate_limit: 100 +drop table insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE insertconflict" +== 119 +-- truncate_limit: 100 +|-- +-- test insertion through view +|-- + +create table insertconflict (f1 int primary key, f2 text) +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE insertconflict (f1 int PRIMARY KEY, f2 text)" +== 120 +-- truncate_limit: 100 +create view insertconflictv as + select * from insertconflict with cascaded check option +-- +TABLE: name="insertconflictv" schema="" table="insertconflictv" ctx=DDL +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW insertconflictv AS SELECT * FROM insertconflict WITH CHECK OPTION" +== 121 +-- truncate_limit: 100 +insert into insertconflictv values (1,'foo') + on conflict (f1) do update set f2 = excluded.f2 +-- +TABLE: name="insertconflictv" schema="" table="insertconflictv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflictv VALUES (1, 'foo') ON CONFLICT (f1) DO UPDATE SET f2 = excluded.f2" +== 122 +-- truncate_limit: 100 +select * from insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insertconflict" +== 123 +-- truncate_limit: 100 +insert into insertconflictv values (1,'bar') + on conflict (f1) do update set f2 = excluded.f2 +-- +TABLE: name="insertconflictv" schema="" table="insertconflictv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO insertconflictv VALUES (1, 'bar') ON CONFLICT (f1) DO UPDATE SET f2 = excluded.f2" +== 124 +-- truncate_limit: 100 +select * from insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insertconflict" +== 125 +-- truncate_limit: 100 +drop view insertconflictv +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW insertconflictv" +== 126 +-- truncate_limit: 100 +drop table insertconflict +-- +TABLE: name="insertconflict" schema="" table="insertconflict" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE insertconflict" +== 127 +-- truncate_limit: 100 +-- ****************************************************************** +-- * * +-- * Test inheritance (example taken from tutorial) * +-- * * +-- ****************************************************************** +create table cities ( + name text, + population float8, + altitude int -- (in ft) +) +-- +TABLE: name="cities" schema="" table="cities" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cities (name text, population float8, altitude int)" +== 128 +-- truncate_limit: 100 +create table capitals ( + state char(2) +) inherits (cities) +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE capitals (state char(2)) INHERITS (cities)" +== 129 +-- truncate_limit: 100 +-- Create unique indexes. Due to a general limitation of inheritance, +-- uniqueness is only enforced per-relation. Unique index inference +-- specification will do the right thing, though. +create unique index cities_names_unique on cities (name) +-- +TABLE: name="cities" schema="" table="cities" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX cities_names_unique ON cities USING btree (name)" +== 130 +-- truncate_limit: 100 +create unique index capitals_names_unique on capitals (name) +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX capitals_names_unique ON capitals USING btree (name)" +== 131 +-- truncate_limit: 100 +-- prepopulate the tables. +insert into cities values ('San Francisco', 7.24E+5, 63) +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)" +== 132 +-- truncate_limit: 100 +insert into cities values ('Las Vegas', 2.583E+5, 2174) +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)" +== 133 +-- truncate_limit: 100 +insert into cities values ('Mariposa', 1200, 1953) +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cities VALUES ('Mariposa', 1200, 1953)" +== 134 +-- truncate_limit: 100 +insert into capitals values ('Sacramento', 3.694E+5, 30, 'CA') +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO capitals VALUES ('Sacramento', 3.694E+5, 30, 'CA')" +== 135 +-- truncate_limit: 100 +insert into capitals values ('Madison', 1.913E+5, 845, 'WI') +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO capitals VALUES ('Madison', 1.913E+5, 845, 'WI')" +== 136 +-- truncate_limit: 100 +-- Tests proper for inheritance: +select * from capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM capitals" +== 137 +-- truncate_limit: 100 +-- Succeeds: +insert into cities values ('Las Vegas', 2.583E+5, 2174) on conflict do nothing +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174) ON CONFLICT DO NOTHING" +== 138 +-- truncate_limit: 100 +insert into capitals values ('Sacramento', 4664.E+5, 30, 'CA') on conflict (name) do update set population = excluded.population +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO capitals VALUES (...) ON CONFLICT (name) DO UPDATE SET population = excluded.population" +== 139 +-- truncate_limit: 100 +-- Wrong "Sacramento", so do nothing: +insert into capitals values ('Sacramento', 50, 2267, 'NE') on conflict (name) do nothing +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO capitals VALUES ('Sacramento', 50, 2267, 'NE') ON CONFLICT (name) DO NOTHING" +== 140 +-- truncate_limit: 100 +select * from capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM capitals" +== 141 +-- truncate_limit: 100 +insert into cities values ('Las Vegas', 5.83E+5, 2001) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cities VALUES ('Las Vegas', 5.83E+5, 2001) ON CONFLICT (name) DO UPDATE SET ... = ..." +== 142 +-- truncate_limit: 100 +select tableoid::regclass, * from cities +-- +TABLE: name="cities" schema="" table="cities" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM cities" +== 143 +-- truncate_limit: 100 +insert into capitals values ('Las Vegas', 5.83E+5, 2222, 'NV') on conflict (name) do update set population = excluded.population +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO capitals VALUES (...) ON CONFLICT (name) DO UPDATE SET population = excluded.population" +== 144 +-- truncate_limit: 100 +-- Capitals will contain new capital, Las Vegas: +select * from capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM capitals" +== 145 +-- truncate_limit: 100 +-- Cities contains two instances of "Las Vegas", since unique constraints don't +-- work across inheritance: +select tableoid::regclass, * from cities +-- +TABLE: name="cities" schema="" table="cities" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM cities" +== 146 +-- truncate_limit: 100 +-- This only affects "cities" version of "Las Vegas": +insert into cities values ('Las Vegas', 5.86E+5, 2223) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude +-- +TABLE: name="cities" schema="" table="cities" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cities VALUES ('Las Vegas', 5.86E+5, 2223) ON CONFLICT (name) DO UPDATE SET ... = ..." +== 147 +-- truncate_limit: 100 +select tableoid::regclass, * from cities +-- +TABLE: name="cities" schema="" table="cities" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM cities" +== 148 +-- truncate_limit: 100 +-- clean up +drop table capitals +-- +TABLE: name="capitals" schema="" table="capitals" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE capitals" +== 149 +-- truncate_limit: 100 +drop table cities +-- +TABLE: name="cities" schema="" table="cities" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cities" +== 150 +-- truncate_limit: 100 +-- Make sure a table named excluded is handled properly +create table excluded(key int primary key, data text) +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE excluded (key int PRIMARY KEY, data text)" +== 151 +-- truncate_limit: 100 +insert into excluded values(1, '1') +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO excluded VALUES (1, '1')" +== 152 +-- truncate_limit: 100 +-- error, ambiguous +insert into excluded values(1, '2') on conflict (key) do update set data = excluded.data RETURNING * +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO excluded VALUES (1, '2') ON CONFLICT (key) DO UPDATE SET ... = ... RETURNING *" +== 153 +-- truncate_limit: 100 +-- ok, aliased +insert into excluded AS target values(1, '2') on conflict (key) do update set data = excluded.data RETURNING * +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +ALIAS: "target"="excluded" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO excluded AS target VALUES (1, '2') ON CONFLICT (key) DO UPDATE SET ... = ... RETURNING *" +== 154 +-- truncate_limit: 100 +-- ok, aliased +insert into excluded AS target values(1, '2') on conflict (key) do update set data = target.data RETURNING * +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +ALIAS: "target"="excluded" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO excluded AS target VALUES (1, '2') ON CONFLICT (key) DO UPDATE SET ... = ... RETURNING *" +== 155 +-- truncate_limit: 100 +-- make sure excluded isn't a problem in returning clause +insert into excluded values(1, '2') on conflict (key) do update set data = 3 RETURNING excluded.* +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO excluded VALUES (1, '2') ON CONFLICT (key) DO UPDATE SET data = 3 RETURNING excluded.*" +== 156 +-- truncate_limit: 100 +-- clean up +drop table excluded +-- +TABLE: name="excluded" schema="" table="excluded" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE excluded" +== 157 +-- truncate_limit: 100 +-- check that references to columns after dropped columns are handled correctly +create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float) +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dropcol (key int PRIMARY KEY, drop1 int, keep1 text, drop2 numeric, keep2 double pre..." +== 158 +-- truncate_limit: 100 +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1) +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dropcol (key, drop1, keep1, drop2, keep2) VALUES (1, 1, '1', '1', 1)" +== 159 +-- truncate_limit: 100 +-- set using excluded +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 2, '2', '2', 2) on conflict(key) + do update set drop1 = excluded.drop1, keep1 = excluded.keep1, drop2 = excluded.drop2, keep2 = excluded.keep2 + where excluded.drop1 is not null and excluded.keep1 is not null and excluded.drop2 is not null and excluded.keep2 is not null + and dropcol.drop1 is not null and dropcol.keep1 is not null and dropcol.drop2 is not null and dropcol.keep2 is not null + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dropcol (...) VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... WHERE ... RETURN..." +== 160 +-- truncate_limit: 100 +-- set using existing table +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 3, '3', '3', 3) on conflict(key) + do update set drop1 = dropcol.drop1, keep1 = dropcol.keep1, drop2 = dropcol.drop2, keep2 = dropcol.keep2 + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dropcol (...) VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... RETURNING *" +== 161 +-- truncate_limit: 100 +alter table dropcol drop column drop1, drop column drop2 +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE dropcol DROP drop1, DROP drop2" +== 162 +-- truncate_limit: 100 +-- set using excluded +insert into dropcol(key, keep1, keep2) values(1, '4', 4) on conflict(key) + do update set keep1 = excluded.keep1, keep2 = excluded.keep2 + where excluded.keep1 is not null and excluded.keep2 is not null + and dropcol.keep1 is not null and dropcol.keep2 is not null + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dropcol (...) VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... WHERE ... RETURN..." +== 163 +-- truncate_limit: 100 +-- set using existing table +insert into dropcol(key, keep1, keep2) values(1, '5', 5) on conflict(key) + do update set keep1 = dropcol.keep1, keep2 = dropcol.keep2 + returning * +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO dropcol (...) VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... RETURNING *" +== 164 +-- truncate_limit: 100 +DROP TABLE dropcol +-- +TABLE: name="dropcol" schema="" table="dropcol" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE dropcol" +== 165 +-- truncate_limit: 100 +-- check handling of regular btree constraint along with gist constraint + +create table twoconstraints (f1 int unique, f2 box, + exclude using gist(f2 with &&)) +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE twoconstraints (f1 int UNIQUE, f2 box, EXCLUDE USING gist (f2 WITH &&))" +== 166 +-- truncate_limit: 100 +insert into twoconstraints values(1, '((0,0),(1,1))') +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO twoconstraints VALUES (1, '((0,0),(1,1))')" +== 167 +-- truncate_limit: 100 +insert into twoconstraints values(1, '((2,2),(3,3))') +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO twoconstraints VALUES (1, '((2,2),(3,3))')" +== 168 +-- truncate_limit: 100 +-- fail on f1 +insert into twoconstraints values(2, '((0,0),(1,2))') +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO twoconstraints VALUES (2, '((0,0),(1,2))')" +== 169 +-- truncate_limit: 100 +-- fail on f2 +insert into twoconstraints values(2, '((0,0),(1,2))') + on conflict on constraint twoconstraints_f1_key do nothing +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO twoconstraints VALUES (...) ON CONFLICT ON CONSTRAINT twoconstraints_f1_key DO NOTHING" +== 170 +-- truncate_limit: 100 +-- fail on f2 +insert into twoconstraints values(2, '((0,0),(1,2))') + on conflict on constraint twoconstraints_f2_excl do nothing +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO twoconstraints VALUES (...) ON CONFLICT ON CONSTRAINT twoconstraints_f2_excl DO NOTHING" +== 171 +-- truncate_limit: 100 +-- do nothing +select * from twoconstraints +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM twoconstraints" +== 172 +-- truncate_limit: 100 +drop table twoconstraints +-- +TABLE: name="twoconstraints" schema="" table="twoconstraints" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE twoconstraints" +== 173 +-- truncate_limit: 100 +-- check handling of self-conflicts at various isolation levels + +create table selfconflict (f1 int primary key, f2 int) +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE selfconflict (f1 int PRIMARY KEY, f2 int)" +== 174 +-- truncate_limit: 100 +begin transaction isolation level read committed +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL READ COMMITTED" +== 175 +-- truncate_limit: 100 +insert into selfconflict values (1,1), (1,2) on conflict do nothing +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selfconflict VALUES (1, 1), (1, 2) ON CONFLICT DO NOTHING" +== 176 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 177 +-- truncate_limit: 100 +begin transaction isolation level repeatable read +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL REPEATABLE READ" +== 178 +-- truncate_limit: 100 +insert into selfconflict values (2,1), (2,2) on conflict do nothing +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selfconflict VALUES (2, 1), (2, 2) ON CONFLICT DO NOTHING" +== 179 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 180 +-- truncate_limit: 100 +begin transaction isolation level serializable +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 181 +-- truncate_limit: 100 +insert into selfconflict values (3,1), (3,2) on conflict do nothing +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selfconflict VALUES (3, 1), (3, 2) ON CONFLICT DO NOTHING" +== 182 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 183 +-- truncate_limit: 100 +begin transaction isolation level read committed +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL READ COMMITTED" +== 184 +-- truncate_limit: 100 +insert into selfconflict values (4,1), (4,2) on conflict(f1) do update set f2 = 0 +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selfconflict VALUES (4, 1), (4, 2) ON CONFLICT (f1) DO UPDATE SET f2 = 0" +== 185 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 186 +-- truncate_limit: 100 +begin transaction isolation level repeatable read +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL REPEATABLE READ" +== 187 +-- truncate_limit: 100 +insert into selfconflict values (5,1), (5,2) on conflict(f1) do update set f2 = 0 +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selfconflict VALUES (5, 1), (5, 2) ON CONFLICT (f1) DO UPDATE SET f2 = 0" +== 188 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 189 +-- truncate_limit: 100 +begin transaction isolation level serializable +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 190 +-- truncate_limit: 100 +insert into selfconflict values (6,1), (6,2) on conflict(f1) do update set f2 = 0 +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selfconflict VALUES (6, 1), (6, 2) ON CONFLICT (f1) DO UPDATE SET f2 = 0" +== 191 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 192 +-- truncate_limit: 100 +select * from selfconflict +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM selfconflict" +== 193 +-- truncate_limit: 100 +drop table selfconflict +-- +TABLE: name="selfconflict" schema="" table="selfconflict" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE selfconflict" +== 194 +-- truncate_limit: 100 +-- check ON CONFLICT handling with partitioned tables +create table parted_conflict_test (a int unique, b char) partition by list (a) +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_test (a int UNIQUE, b char(1)) PARTITION BY LIST (a)" +== 195 +-- truncate_limit: 100 +create table parted_conflict_test_1 partition of parted_conflict_test (b unique) for values in (1, 2) +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_test_1 PARTITION OF parted_conflict_test (b UNIQUE) FOR VALUES IN (1..." +== 196 +-- truncate_limit: 100 +-- no indexes required here +insert into parted_conflict_test values (1, 'a') on conflict do nothing +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test VALUES (1, 'a') ON CONFLICT DO NOTHING" +== 197 +-- truncate_limit: 100 +-- index on a required, which does exist in parent +insert into parted_conflict_test values (1, 'a') on conflict (a) do nothing +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test VALUES (1, 'a') ON CONFLICT (a) DO NOTHING" +== 198 +-- truncate_limit: 100 +insert into parted_conflict_test values (1, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test VALUES (1, 'a') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 199 +-- truncate_limit: 100 +-- targeting partition directly will work +insert into parted_conflict_test_1 values (1, 'a') on conflict (a) do nothing +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test_1 VALUES (1, 'a') ON CONFLICT (a) DO NOTHING" +== 200 +-- truncate_limit: 100 +insert into parted_conflict_test_1 values (1, 'b') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test_1 VALUES (1, 'b') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 201 +-- truncate_limit: 100 +-- index on b required, which doesn't exist in parent +insert into parted_conflict_test values (2, 'b') on conflict (b) do update set a = excluded.a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test VALUES (2, 'b') ON CONFLICT (b) DO UPDATE SET a = excluded.a" +== 202 +-- truncate_limit: 100 +-- targeting partition directly will work +insert into parted_conflict_test_1 values (2, 'b') on conflict (b) do update set a = excluded.a +-- +TABLE: name="parted_conflict_test_1" schema="" table="parted_conflict_test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test_1 VALUES (2, 'b') ON CONFLICT (b) DO UPDATE SET a = excluded.a" +== 203 +-- truncate_limit: 100 +-- should see (2, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_conflict_test ORDER BY a" +== 204 +-- truncate_limit: 100 +-- now check that DO UPDATE works correctly for target partition with +-- different attribute numbers +create table parted_conflict_test_2 (b char, a int unique) +-- +TABLE: name="parted_conflict_test_2" schema="" table="parted_conflict_test_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_test_2 (b char(1), a int UNIQUE)" +== 205 +-- truncate_limit: 100 +alter table parted_conflict_test attach partition parted_conflict_test_2 for values in (3) +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_conflict_test ATTACH PARTITION parted_conflict_test_2 FOR VALUES IN (3)" +== 206 +-- truncate_limit: 100 +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_conflict_test" +== 207 +-- truncate_limit: 100 +insert into parted_conflict_test values (3, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test VALUES (3, 'a') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 208 +-- truncate_limit: 100 +insert into parted_conflict_test values (3, 'b') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test VALUES (3, 'b') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 209 +-- truncate_limit: 100 +-- should see (3, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_conflict_test ORDER BY a" +== 210 +-- truncate_limit: 100 +-- case where parent will have a dropped column, but the partition won't +alter table parted_conflict_test drop b, add b char +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_conflict_test DROP b, ADD COLUMN b char(1)" +== 211 +-- truncate_limit: 100 +create table parted_conflict_test_3 partition of parted_conflict_test for values in (4) +-- +TABLE: name="parted_conflict_test_3" schema="" table="parted_conflict_test_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_test_3 PARTITION OF parted_conflict_test FOR VALUES IN (4)" +== 212 +-- truncate_limit: 100 +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_conflict_test" +== 213 +-- truncate_limit: 100 +insert into parted_conflict_test (a, b) values (4, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test (a, b) VALUES (4, 'a') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 214 +-- truncate_limit: 100 +insert into parted_conflict_test (a, b) values (4, 'b') on conflict (a) do update set b = excluded.b where parted_conflict_test.b = 'a' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test (...) VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... WHERE..." +== 215 +-- truncate_limit: 100 +-- should see (4, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_conflict_test ORDER BY a" +== 216 +-- truncate_limit: 100 +-- case with multi-level partitioning +create table parted_conflict_test_4 partition of parted_conflict_test for values in (5) partition by list (a) +-- +TABLE: name="parted_conflict_test_4" schema="" table="parted_conflict_test_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_test_4 PARTITION OF parted_conflict_test FOR VALUES IN (5) PARTITION..." +== 217 +-- truncate_limit: 100 +create table parted_conflict_test_4_1 partition of parted_conflict_test_4 for values in (5) +-- +TABLE: name="parted_conflict_test_4_1" schema="" table="parted_conflict_test_4_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_test_4_1 PARTITION OF parted_conflict_test_4 FOR VALUES IN (5)" +== 218 +-- truncate_limit: 100 +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_conflict_test" +== 219 +-- truncate_limit: 100 +insert into parted_conflict_test (a, b) values (5, 'a') on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test (a, b) VALUES (5, 'a') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 220 +-- truncate_limit: 100 +insert into parted_conflict_test (a, b) values (5, 'b') on conflict (a) do update set b = excluded.b where parted_conflict_test.b = 'a' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test (...) VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... WHERE..." +== 221 +-- truncate_limit: 100 +-- should see (5, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_conflict_test ORDER BY a" +== 222 +-- truncate_limit: 100 +-- test with multiple rows +truncate parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_conflict_test" +== 223 +-- truncate_limit: 100 +insert into parted_conflict_test (a, b) values (1, 'a'), (2, 'a'), (4, 'a') on conflict (a) do update set b = excluded.b where excluded.b = 'b' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test (...) VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... WHERE..." +== 224 +-- truncate_limit: 100 +insert into parted_conflict_test (a, b) values (1, 'b'), (2, 'c'), (4, 'b') on conflict (a) do update set b = excluded.b where excluded.b = 'b' +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_test (...) VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... WHERE..." +== 225 +-- truncate_limit: 100 +-- should see (1, 'b'), (2, 'a'), (4, 'b') +select * from parted_conflict_test order by a +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_conflict_test ORDER BY a" +== 226 +-- truncate_limit: 100 +drop table parted_conflict_test +-- +TABLE: name="parted_conflict_test" schema="" table="parted_conflict_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_conflict_test" +== 227 +-- truncate_limit: 100 +-- test behavior of inserting a conflicting tuple into an intermediate +-- partitioning level +create table parted_conflict (a int primary key, b text) partition by range (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict (a int PRIMARY KEY, b text) PARTITION BY RANGE (a)" +== 228 +-- truncate_limit: 100 +create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_1 PARTITION OF parted_conflict FOR VALUES FROM (0) TO (1000) PARTITI..." +== 229 +-- truncate_limit: 100 +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500) +-- +TABLE: name="parted_conflict_1_1" schema="" table="parted_conflict_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_1_1 PARTITION OF parted_conflict_1 FOR VALUES FROM (0) TO (500)" +== 230 +-- truncate_limit: 100 +insert into parted_conflict values (40, 'forty') +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict VALUES (40, 'forty')" +== 231 +-- truncate_limit: 100 +insert into parted_conflict_1 values (40, 'cuarenta') + on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_1 VALUES (40, 'cuarenta') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 232 +-- truncate_limit: 100 +drop table parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_conflict" +== 233 +-- truncate_limit: 100 +-- same thing, but this time try to use an index that's created not in the +-- partition +create table parted_conflict (a int, b text) partition by range (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict (a int, b text) PARTITION BY RANGE (a)" +== 234 +-- truncate_limit: 100 +create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_1 PARTITION OF parted_conflict FOR VALUES FROM (0) TO (1000) PARTITI..." +== 235 +-- truncate_limit: 100 +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500) +-- +TABLE: name="parted_conflict_1_1" schema="" table="parted_conflict_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_1_1 PARTITION OF parted_conflict_1 FOR VALUES FROM (0) TO (500)" +== 236 +-- truncate_limit: 100 +create unique index on only parted_conflict_1 (a) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON ONLY parted_conflict_1 USING btree (a)" +== 237 +-- truncate_limit: 100 +create unique index on only parted_conflict (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON ONLY parted_conflict USING btree (a)" +== 238 +-- truncate_limit: 100 +alter index parted_conflict_a_idx attach partition parted_conflict_1_a_idx +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX parted_conflict_a_idx ATTACH PARTITION parted_conflict_1_a_idx" +== 239 +-- truncate_limit: 100 +insert into parted_conflict values (40, 'forty') +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict VALUES (40, 'forty')" +== 240 +-- truncate_limit: 100 +insert into parted_conflict_1 values (40, 'cuarenta') + on conflict (a) do update set b = excluded.b +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict_1 VALUES (40, 'cuarenta') ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 241 +-- truncate_limit: 100 +drop table parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_conflict" +== 242 +-- truncate_limit: 100 +-- test whole-row Vars in ON CONFLICT expressions +create table parted_conflict (a int, b text, c int) partition by range (a) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict (a int, b text, c int) PARTITION BY RANGE (a)" +== 243 +-- truncate_limit: 100 +create table parted_conflict_1 (drp text, c int, a int, b text) +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_conflict_1 (drp text, c int, a int, b text)" +== 244 +-- truncate_limit: 100 +alter table parted_conflict_1 drop column drp +-- +TABLE: name="parted_conflict_1" schema="" table="parted_conflict_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_conflict_1 DROP drp" +== 245 +-- truncate_limit: 100 +create unique index on parted_conflict (a, b) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON parted_conflict USING btree (a, b)" +== 246 +-- truncate_limit: 100 +alter table parted_conflict attach partition parted_conflict_1 for values from (0) to (1000) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_conflict ATTACH PARTITION parted_conflict_1 FOR VALUES FROM (0) TO (1000)" +== 247 +-- truncate_limit: 100 +truncate parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_conflict" +== 248 +-- truncate_limit: 100 +insert into parted_conflict values (50, 'cincuenta', 1) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict VALUES (50, 'cincuenta', 1)" +== 249 +-- truncate_limit: 100 +insert into parted_conflict values (50, 'cincuenta', 2) + on conflict (a, b) do update set (a, b, c) = row(excluded.*) + where parted_conflict = (50, text 'cincuenta', 1) and + excluded = (50, text 'cincuenta', 2) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict VALUES (...) ON CONFLICT (a, b) DO UPDATE SET ... = ... WHERE ..." +== 250 +-- truncate_limit: 100 +-- should see (50, 'cincuenta', 2) +select * from parted_conflict order by a +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted_conflict ORDER BY a" +== 251 +-- truncate_limit: 100 +-- test with statement level triggers +create or replace function parted_conflict_update_func() returns trigger as $$ +declare + r record; +begin + for r in select * from inserted loop + raise notice 'a = %, b = %, c = %', r.a, r.b, r.c; + end loop; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="parted_conflict_update_func" function="parted_conflict_update_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION parted_conflict_update_func() RETURNS trigger AS $$\ndeclare\n r reco..." +== 252 +-- truncate_limit: 100 +create trigger parted_conflict_update + after update on parted_conflict + referencing new table as inserted + for each statement + execute procedure parted_conflict_update_func() +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_conflict_update AFTER UPDATE ON parted_conflict REFERENCING NEW TABLE inser..." +== 253 +-- truncate_limit: 100 +truncate parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted_conflict" +== 254 +-- truncate_limit: 100 +insert into parted_conflict values (0, 'cero', 1) +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict VALUES (0, 'cero', 1)" +== 255 +-- truncate_limit: 100 +insert into parted_conflict values(0, 'cero', 1) + on conflict (a,b) do update set c = parted_conflict.c + 1 +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_conflict VALUES (0, 'cero', 1) ON CONFLICT (a, b) DO UPDATE SET ... = ..." +== 256 +-- truncate_limit: 100 +drop table parted_conflict +-- +TABLE: name="parted_conflict" schema="" table="parted_conflict" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_conflict" +== 257 +-- truncate_limit: 100 +drop function parted_conflict_update_func() +-- +FUNCTION: name="parted_conflict_update_func" function="parted_conflict_update_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION parted_conflict_update_func()" diff --git a/parser/testdata/summary_truncate/postgres_regress/int2.metadata.json b/parser/testdata/summary_truncate/postgres_regress/int2.metadata.json new file mode 100644 index 0000000..f476ef8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/int2.metadata.json @@ -0,0 +1,80 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/int2.test b/parser/testdata/summary_truncate/postgres_regress/int2.test new file mode 100644 index 0000000..0e5bf38 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/int2.test @@ -0,0 +1,590 @@ +== 001 +-- truncate_limit: 100 +|-- +-- INT2 +|-- + +-- int2_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO INT2_TBL(f1) VALUES ('34.5') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('34.5')" +== 002 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES ('100000') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('100000')" +== 003 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES ('asdf') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('asdf')" +== 004 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES (' ') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES (' ')" +== 005 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES ('- 1234') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('- 1234')" +== 006 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES ('4 444') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('4 444')" +== 007 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES ('123 dt') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('123 dt')" +== 008 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES ('') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('')" +== 009 +-- truncate_limit: 100 +SELECT * FROM INT2_TBL +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int2_tbl" +== 010 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34', 'int2') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('34', 'int2')" +== 011 +-- truncate_limit: 100 +SELECT pg_input_is_valid('asdf', 'int2') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('asdf', 'int2')" +== 012 +-- truncate_limit: 100 +SELECT pg_input_is_valid('50000', 'int2') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('50000', 'int2')" +== 013 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('50000', 'int2') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('50000', 'int2')" +== 014 +-- truncate_limit: 100 +-- While we're here, check int2vector as well +SELECT pg_input_is_valid(' 1 3 5 ', 'int2vector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid(' 1 3 5 ', 'int2vector')" +== 015 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1 asdf', 'int2vector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1 asdf', 'int2vector')" +== 016 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('50000', 'int2vector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('50000', 'int2vector')" +== 017 +-- truncate_limit: 100 +SELECT * FROM INT2_TBL AS f(a, b) +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "f"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int2_tbl f(a, b)" +== 018 +-- truncate_limit: 100 +SELECT * FROM (TABLE int2_tbl) AS s (a, b) +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM int2_tbl) s(a, b)" +== 019 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <> int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 <> '0'::int2" +== 020 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <> int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 <> '0'::int4" +== 021 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 = int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 = '0'::int2" +== 022 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 = int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 = '0'::int4" +== 023 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 < int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 < '0'::int2" +== 024 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 < int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 < '0'::int4" +== 025 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <= int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 <= '0'::int2" +== 026 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 <= int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 <= '0'::int4" +== 027 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 > int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 > '0'::int2" +== 028 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 > int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 > '0'::int4" +== 029 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 >= int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 >= '0'::int2" +== 030 +-- truncate_limit: 100 +SELECT i.* FROM INT2_TBL i WHERE i.f1 >= int4 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE i.f1 >= '0'::int4" +== 031 +-- truncate_limit: 100 +-- positive odds +SELECT i.* FROM INT2_TBL i WHERE (i.f1 % int2 '2') = int2 '1' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE (i.f1 % '2'::int2) = '1'::int2" +== 032 +-- truncate_limit: 100 +-- any evens +SELECT i.* FROM INT2_TBL i WHERE (i.f1 % int4 '2') = int2 '0' +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int2_tbl i WHERE (i.f1 % '2'::int4) = '0'::int2" +== 033 +-- truncate_limit: 100 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 * '2'::int2 AS x FROM int2_tbl i" +== 034 +-- truncate_limit: 100 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i +WHERE abs(f1) < 16384 +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 * '2'::int2 AS x FROM int2_tbl i WHERE abs(f1) < 16384" +== 035 +-- truncate_limit: 100 +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 * '2'::int4 AS x FROM int2_tbl i" +== 036 +-- truncate_limit: 100 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 + '2'::int2 AS x FROM int2_tbl i" +== 037 +-- truncate_limit: 100 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i +WHERE f1 < 32766 +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 + '2'::int2 AS x FROM int2_tbl i WHERE f1 < 32766" +== 038 +-- truncate_limit: 100 +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 + '2'::int4 AS x FROM int2_tbl i" +== 039 +-- truncate_limit: 100 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 - '2'::int2 AS x FROM int2_tbl i" +== 040 +-- truncate_limit: 100 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i +WHERE f1 > -32767 +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 - '2'::int2 AS x FROM int2_tbl i WHERE f1 > -32767" +== 041 +-- truncate_limit: 100 +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 - '2'::int4 AS x FROM int2_tbl i" +== 042 +-- truncate_limit: 100 +SELECT i.f1, i.f1 / int2 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 / '2'::int2 AS x FROM int2_tbl i" +== 043 +-- truncate_limit: 100 +SELECT i.f1, i.f1 / int4 '2' AS x FROM INT2_TBL i +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 / '2'::int4 AS x FROM int2_tbl i" +== 044 +-- truncate_limit: 100 +-- corner cases +SELECT (-1::int2<<15)::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT ((- 1::int2) << 15)::text" +== 045 +-- truncate_limit: 100 +SELECT ((-1::int2<<15)+1::int2)::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT (((- 1::int2) << 15) + 1::int2)::text" +== 046 +-- truncate_limit: 100 +-- check sane handling of INT16_MIN overflow cases +SELECT (-32768)::int2 * (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-32768)::int2 * (-1)::int2" +== 047 +-- truncate_limit: 100 +SELECT (-32768)::int2 / (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-32768)::int2 / (-1)::int2" +== 048 +-- truncate_limit: 100 +SELECT (-32768)::int2 % (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-32768)::int2 % (-1)::int2" +== 049 +-- truncate_limit: 100 +-- check rounding when casting from float +SELECT x, x::int2 AS int2_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x, x::int2 AS int2_value FROM (VALUES (...)) t(x)" +== 050 +-- truncate_limit: 100 +-- check rounding when casting from numeric +SELECT x, x::int2 AS int2_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x, x::int2 AS int2_value FROM (VALUES (...)) t(x)" +== 051 +-- truncate_limit: 100 +-- non-decimal literals + +SELECT int2 '0b100101' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b100101'::int2" +== 052 +-- truncate_limit: 100 +SELECT int2 '0o273' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o273'::int2" +== 053 +-- truncate_limit: 100 +SELECT int2 '0x42F' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x42F'::int2" +== 054 +-- truncate_limit: 100 +SELECT int2 '0b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b'::int2" +== 055 +-- truncate_limit: 100 +SELECT int2 '0o' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o'::int2" +== 056 +-- truncate_limit: 100 +SELECT int2 '0x' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x'::int2" +== 057 +-- truncate_limit: 100 +-- cases near overflow +SELECT int2 '0b111111111111111' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b111111111111111'::int2" +== 058 +-- truncate_limit: 100 +SELECT int2 '0b1000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b1000000000000000'::int2" +== 059 +-- truncate_limit: 100 +SELECT int2 '0o77777' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o77777'::int2" +== 060 +-- truncate_limit: 100 +SELECT int2 '0o100000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o100000'::int2" +== 061 +-- truncate_limit: 100 +SELECT int2 '0x7FFF' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x7FFF'::int2" +== 062 +-- truncate_limit: 100 +SELECT int2 '0x8000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x8000'::int2" +== 063 +-- truncate_limit: 100 +SELECT int2 '-0b1000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0b1000000000000000'::int2" +== 064 +-- truncate_limit: 100 +SELECT int2 '-0b1000000000000001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0b1000000000000001'::int2" +== 065 +-- truncate_limit: 100 +SELECT int2 '-0o100000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0o100000'::int2" +== 066 +-- truncate_limit: 100 +SELECT int2 '-0o100001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0o100001'::int2" +== 067 +-- truncate_limit: 100 +SELECT int2 '-0x8000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0x8000'::int2" +== 068 +-- truncate_limit: 100 +SELECT int2 '-0x8001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0x8001'::int2" +== 069 +-- truncate_limit: 100 +-- underscores + +SELECT int2 '1_000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000'::int2" +== 070 +-- truncate_limit: 100 +SELECT int2 '1_2_3' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_2_3'::int2" +== 071 +-- truncate_limit: 100 +SELECT int2 '0xE_FF' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0xE_FF'::int2" +== 072 +-- truncate_limit: 100 +SELECT int2 '0o2_73' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o2_73'::int2" +== 073 +-- truncate_limit: 100 +SELECT int2 '0b_10_0101' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b_10_0101'::int2" +== 074 +-- truncate_limit: 100 +-- error cases +SELECT int2 '_100' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '_100'::int2" +== 075 +-- truncate_limit: 100 +SELECT int2 '100_' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100_'::int2" +== 076 +-- truncate_limit: 100 +SELECT int2 '10__000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '10__000'::int2" diff --git a/parser/testdata/summary_truncate/postgres_regress/int4.metadata.json b/parser/testdata/summary_truncate/postgres_regress/int4.metadata.json new file mode 100644 index 0000000..da94530 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/int4.metadata.json @@ -0,0 +1,98 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/int4.test b/parser/testdata/summary_truncate/postgres_regress/int4.test new file mode 100644 index 0000000..b6babbb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/int4.test @@ -0,0 +1,744 @@ +== 001 +-- truncate_limit: 100 +|-- +-- INT4 +|-- + +-- int4_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO INT4_TBL(f1) VALUES ('34.5') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES ('34.5')" +== 002 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES ('1000000000000') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES ('1000000000000')" +== 003 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES ('asdf') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES ('asdf')" +== 004 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES (' ') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES (' ')" +== 005 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES (' asdf ') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES (' asdf ')" +== 006 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES ('- 1234') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES ('- 1234')" +== 007 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES ('123 5') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES ('123 5')" +== 008 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES ('') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES ('')" +== 009 +-- truncate_limit: 100 +SELECT * FROM INT4_TBL +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl" +== 010 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34', 'int4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('34', 'int4')" +== 011 +-- truncate_limit: 100 +SELECT pg_input_is_valid('asdf', 'int4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('asdf', 'int4')" +== 012 +-- truncate_limit: 100 +SELECT pg_input_is_valid('1000000000000', 'int4') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1000000000000', 'int4')" +== 013 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1000000000000', 'int4') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1000000000000', 'int4')" +== 014 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 <> '0'::int2" +== 015 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 <> '0'::int4" +== 016 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 = int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 = '0'::int2" +== 017 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 = int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 = '0'::int4" +== 018 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 < int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 < '0'::int2" +== 019 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 < int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 < '0'::int4" +== 020 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <= int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 <= '0'::int2" +== 021 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 <= int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 <= '0'::int4" +== 022 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 > int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 > '0'::int2" +== 023 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 > int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 > '0'::int4" +== 024 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 >= int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 >= '0'::int2" +== 025 +-- truncate_limit: 100 +SELECT i.* FROM INT4_TBL i WHERE i.f1 >= int4 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE i.f1 >= '0'::int4" +== 026 +-- truncate_limit: 100 +-- positive odds +SELECT i.* FROM INT4_TBL i WHERE (i.f1 % int2 '2') = int2 '1' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE (i.f1 % '2'::int2) = '1'::int2" +== 027 +-- truncate_limit: 100 +-- any evens +SELECT i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0' +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="i" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.* FROM int4_tbl i WHERE (i.f1 % '2'::int4) = '0'::int2" +== 028 +-- truncate_limit: 100 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 * '2'::int2 AS x FROM int4_tbl i" +== 029 +-- truncate_limit: 100 +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i +WHERE abs(f1) < 1073741824 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 * '2'::int2 AS x FROM int4_tbl i WHERE abs(f1) < 1073741824" +== 030 +-- truncate_limit: 100 +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 * '2'::int4 AS x FROM int4_tbl i" +== 031 +-- truncate_limit: 100 +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i +WHERE abs(f1) < 1073741824 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 * '2'::int4 AS x FROM int4_tbl i WHERE abs(f1) < 1073741824" +== 032 +-- truncate_limit: 100 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 + '2'::int2 AS x FROM int4_tbl i" +== 033 +-- truncate_limit: 100 +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i +WHERE f1 < 2147483646 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 + '2'::int2 AS x FROM int4_tbl i WHERE f1 < 2147483646" +== 034 +-- truncate_limit: 100 +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 + '2'::int4 AS x FROM int4_tbl i" +== 035 +-- truncate_limit: 100 +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i +WHERE f1 < 2147483646 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 + '2'::int4 AS x FROM int4_tbl i WHERE f1 < 2147483646" +== 036 +-- truncate_limit: 100 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 - '2'::int2 AS x FROM int4_tbl i" +== 037 +-- truncate_limit: 100 +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i +WHERE f1 > -2147483647 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 - '2'::int2 AS x FROM int4_tbl i WHERE f1 > -2147483647" +== 038 +-- truncate_limit: 100 +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 - '2'::int4 AS x FROM int4_tbl i" +== 039 +-- truncate_limit: 100 +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i +WHERE f1 > -2147483647 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 - '2'::int4 AS x FROM int4_tbl i WHERE f1 > -2147483647" +== 040 +-- truncate_limit: 100 +SELECT i.f1, i.f1 / int2 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 / '2'::int2 AS x FROM int4_tbl i" +== 041 +-- truncate_limit: 100 +SELECT i.f1, i.f1 / int4 '2' AS x FROM INT4_TBL i +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT i.f1, i.f1 / '2'::int4 AS x FROM int4_tbl i" +== 042 +-- truncate_limit: 100 +|-- +-- more complex expressions +|-- + +-- variations on unary minus parsing +SELECT -2+3 AS one +-- +STMT: SelectStmt +TRUNCATED: "SELECT -2 + 3 AS one" +== 043 +-- truncate_limit: 100 +SELECT 4-2 AS two +-- +STMT: SelectStmt +TRUNCATED: "SELECT 4 - 2 AS two" +== 044 +-- truncate_limit: 100 +SELECT 2- -1 AS three +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 - -1 AS three" +== 045 +-- truncate_limit: 100 +SELECT 2 - -2 AS four +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 - -2 AS four" +== 046 +-- truncate_limit: 100 +SELECT int2 '2' * int2 '2' = int2 '16' / int2 '4' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('2'::int2 * '2'::int2) = ('16'::int2 / '4'::int2) AS \"true\"" +== 047 +-- truncate_limit: 100 +SELECT int4 '2' * int2 '2' = int2 '16' / int4 '4' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('2'::int4 * '2'::int2) = ('16'::int2 / '4'::int4) AS \"true\"" +== 048 +-- truncate_limit: 100 +SELECT int2 '2' * int4 '2' = int4 '16' / int2 '4' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('2'::int2 * '2'::int4) = ('16'::int4 / '4'::int2) AS \"true\"" +== 049 +-- truncate_limit: 100 +SELECT int4 '1000' < int4 '999' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1000'::int4 < '999'::int4 AS \"false\"" +== 050 +-- truncate_limit: 100 +SELECT 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 AS ten +-- +STMT: SelectStmt +TRUNCATED: "SELECT ((((((((1 + 1) + 1) + 1) + 1) + 1) + 1) + 1) + 1) + 1 AS ten" +== 051 +-- truncate_limit: 100 +SELECT 2 + 2 / 2 AS three +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 + (2 / 2) AS three" +== 052 +-- truncate_limit: 100 +SELECT (2 + 2) / 2 AS two +-- +STMT: SelectStmt +TRUNCATED: "SELECT (2 + 2) / 2 AS two" +== 053 +-- truncate_limit: 100 +-- corner case +SELECT (-1::int4<<31)::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT ((- 1::int4) << 31)::text" +== 054 +-- truncate_limit: 100 +SELECT ((-1::int4<<31)+1)::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT (((- 1::int4) << 31) + 1)::text" +== 055 +-- truncate_limit: 100 +-- check sane handling of INT_MIN overflow cases +SELECT (-2147483648)::int4 * (-1)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648)::int4 * (-1)::int4" +== 056 +-- truncate_limit: 100 +SELECT (-2147483648)::int4 / (-1)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648)::int4 / (-1)::int4" +== 057 +-- truncate_limit: 100 +SELECT (-2147483648)::int4 % (-1)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648)::int4 % (-1)::int4" +== 058 +-- truncate_limit: 100 +SELECT (-2147483648)::int4 * (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648)::int4 * (-1)::int2" +== 059 +-- truncate_limit: 100 +SELECT (-2147483648)::int4 / (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648)::int4 / (-1)::int2" +== 060 +-- truncate_limit: 100 +SELECT (-2147483648)::int4 % (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648)::int4 % (-1)::int2" +== 061 +-- truncate_limit: 100 +-- check rounding when casting from float +SELECT x, x::int4 AS int4_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x, x::int4 AS int4_value FROM (VALUES (...)) t(x)" +== 062 +-- truncate_limit: 100 +-- check rounding when casting from numeric +SELECT x, x::int4 AS int4_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x, x::int4 AS int4_value FROM (VALUES (...)) t(x)" +== 063 +-- truncate_limit: 100 +-- test gcd() +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(b, a), gcd(-b, a) +FROM (VALUES (0::int4, 0::int4), + (0::int4, 6410818::int4), + (61866666::int4, 6410818::int4), + (-61866666::int4, 6410818::int4), + ((-2147483648)::int4, 1::int4), + ((-2147483648)::int4, 2147483647::int4), + ((-2147483648)::int4, 1073741824::int4)) AS v(a, b) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, gcd(a, b), gcd(a, - b), gcd(b, a), gcd(- b, a) FROM (VALUES (...)) v(a, b)" +== 064 +-- truncate_limit: 100 +SELECT gcd((-2147483648)::int4, 0::int4) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT gcd((-2147483648)::int4, 0::int4)" +== 065 +-- truncate_limit: 100 +-- overflow +SELECT gcd((-2147483648)::int4, (-2147483648)::int4) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT gcd((-2147483648)::int4, (-2147483648)::int4)" +== 066 +-- truncate_limit: 100 +-- overflow + +-- test lcm() +SELECT a, b, lcm(a, b), lcm(a, -b), lcm(b, a), lcm(-b, a) +FROM (VALUES (0::int4, 0::int4), + (0::int4, 42::int4), + (42::int4, 42::int4), + (330::int4, 462::int4), + (-330::int4, 462::int4), + ((-2147483648)::int4, 0::int4)) AS v(a, b) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, lcm(a, b), lcm(a, - b), lcm(b, a), lcm(- b, a) FROM (VALUES (...)) v(a, b)" +== 067 +-- truncate_limit: 100 +SELECT lcm((-2147483648)::int4, 1::int4) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lcm((-2147483648)::int4, 1::int4)" +== 068 +-- truncate_limit: 100 +-- overflow +SELECT lcm(2147483647::int4, 2147483646::int4) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lcm(2147483647::int4, 2147483646::int4)" +== 069 +-- truncate_limit: 100 +-- overflow + + +-- non-decimal literals + +SELECT int4 '0b100101' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b100101'::int4" +== 070 +-- truncate_limit: 100 +SELECT int4 '0o273' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o273'::int4" +== 071 +-- truncate_limit: 100 +SELECT int4 '0x42F' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x42F'::int4" +== 072 +-- truncate_limit: 100 +SELECT int4 '0b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b'::int4" +== 073 +-- truncate_limit: 100 +SELECT int4 '0o' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o'::int4" +== 074 +-- truncate_limit: 100 +SELECT int4 '0x' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x'::int4" +== 075 +-- truncate_limit: 100 +-- cases near overflow +SELECT int4 '0b1111111111111111111111111111111' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b1111111111111111111111111111111'::int4" +== 076 +-- truncate_limit: 100 +SELECT int4 '0b10000000000000000000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b10000000000000000000000000000000'::int4" +== 077 +-- truncate_limit: 100 +SELECT int4 '0o17777777777' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o17777777777'::int4" +== 078 +-- truncate_limit: 100 +SELECT int4 '0o20000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o20000000000'::int4" +== 079 +-- truncate_limit: 100 +SELECT int4 '0x7FFFFFFF' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x7FFFFFFF'::int4" +== 080 +-- truncate_limit: 100 +SELECT int4 '0x80000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x80000000'::int4" +== 081 +-- truncate_limit: 100 +SELECT int4 '-0b10000000000000000000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0b10000000000000000000000000000000'::int4" +== 082 +-- truncate_limit: 100 +SELECT int4 '-0b10000000000000000000000000000001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0b10000000000000000000000000000001'::int4" +== 083 +-- truncate_limit: 100 +SELECT int4 '-0o20000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0o20000000000'::int4" +== 084 +-- truncate_limit: 100 +SELECT int4 '-0o20000000001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0o20000000001'::int4" +== 085 +-- truncate_limit: 100 +SELECT int4 '-0x80000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0x80000000'::int4" +== 086 +-- truncate_limit: 100 +SELECT int4 '-0x80000001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0x80000001'::int4" +== 087 +-- truncate_limit: 100 +-- underscores + +SELECT int4 '1_000_000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000_000'::int4" +== 088 +-- truncate_limit: 100 +SELECT int4 '1_2_3' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_2_3'::int4" +== 089 +-- truncate_limit: 100 +SELECT int4 '0x1EEE_FFFF' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x1EEE_FFFF'::int4" +== 090 +-- truncate_limit: 100 +SELECT int4 '0o2_73' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o2_73'::int4" +== 091 +-- truncate_limit: 100 +SELECT int4 '0b_10_0101' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b_10_0101'::int4" +== 092 +-- truncate_limit: 100 +-- error cases +SELECT int4 '_100' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '_100'::int4" +== 093 +-- truncate_limit: 100 +SELECT int4 '100_' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100_'::int4" +== 094 +-- truncate_limit: 100 +SELECT int4 '100__000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100__000'::int4" diff --git a/parser/testdata/summary_truncate/postgres_regress/int8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/int8.metadata.json new file mode 100644 index 0000000..6eafe87 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/int8.metadata.json @@ -0,0 +1,171 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/int8.test b/parser/testdata/summary_truncate/postgres_regress/int8.test new file mode 100644 index 0000000..1d76a66 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/int8.test @@ -0,0 +1,1255 @@ +== 001 +-- truncate_limit: 100 +|-- +-- INT8 +-- Test int8 64-bit integers. +|-- + +-- int8_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO INT8_TBL(q1) VALUES (' ') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl (q1) VALUES (' ')" +== 002 +-- truncate_limit: 100 +INSERT INTO INT8_TBL(q1) VALUES ('xxx') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl (q1) VALUES ('xxx')" +== 003 +-- truncate_limit: 100 +INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl (q1) VALUES ('3908203590239580293850293850329485')" +== 004 +-- truncate_limit: 100 +INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl (q1) VALUES ('-1204982019841029840928340329840934')" +== 005 +-- truncate_limit: 100 +INSERT INTO INT8_TBL(q1) VALUES ('- 123') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl (q1) VALUES ('- 123')" +== 006 +-- truncate_limit: 100 +INSERT INTO INT8_TBL(q1) VALUES (' 345 5') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl (q1) VALUES (' 345 5')" +== 007 +-- truncate_limit: 100 +INSERT INTO INT8_TBL(q1) VALUES ('') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl (q1) VALUES ('')" +== 008 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl" +== 009 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34', 'int8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('34', 'int8')" +== 010 +-- truncate_limit: 100 +SELECT pg_input_is_valid('asdf', 'int8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('asdf', 'int8')" +== 011 +-- truncate_limit: 100 +SELECT pg_input_is_valid('10000000000000000000', 'int8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('10000000000000000000', 'int8')" +== 012 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('10000000000000000000', 'int8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('10000000000000000000', 'int8')" +== 013 +-- truncate_limit: 100 +-- int8/int8 cmp +SELECT * FROM INT8_TBL WHERE q2 = 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 = 4567890123456789" +== 014 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 <> 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 <> 4567890123456789" +== 015 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 < 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 < 4567890123456789" +== 016 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 > 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 > 4567890123456789" +== 017 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 <= 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 <= 4567890123456789" +== 018 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 >= 4567890123456789 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 >= 4567890123456789" +== 019 +-- truncate_limit: 100 +-- int8/int4 cmp +SELECT * FROM INT8_TBL WHERE q2 = 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 = 456" +== 020 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 <> 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 <> 456" +== 021 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 < 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 < 456" +== 022 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 > 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 > 456" +== 023 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 <= 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 <= 456" +== 024 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 >= 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 >= 456" +== 025 +-- truncate_limit: 100 +-- int4/int8 cmp +SELECT * FROM INT8_TBL WHERE 123 = q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE 123 = q1" +== 026 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE 123 <> q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE 123 <> q1" +== 027 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE 123 < q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE 123 < q1" +== 028 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE 123 > q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE 123 > q1" +== 029 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE 123 <= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE 123 <= q1" +== 030 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE 123 >= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE 123 >= q1" +== 031 +-- truncate_limit: 100 +-- int8/int2 cmp +SELECT * FROM INT8_TBL WHERE q2 = '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 = '456'::int2" +== 032 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 <> '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 <> '456'::int2" +== 033 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 < '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 < '456'::int2" +== 034 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 > '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 > '456'::int2" +== 035 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 <= '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 <= '456'::int2" +== 036 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE q2 >= '456'::int2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q2 >= '456'::int2" +== 037 +-- truncate_limit: 100 +-- int2/int8 cmp +SELECT * FROM INT8_TBL WHERE '123'::int2 = q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE '123'::int2 = q1" +== 038 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE '123'::int2 <> q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE '123'::int2 <> q1" +== 039 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE '123'::int2 < q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE '123'::int2 < q1" +== 040 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE '123'::int2 > q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE '123'::int2 > q1" +== 041 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE '123'::int2 <= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE '123'::int2 <= q1" +== 042 +-- truncate_limit: 100 +SELECT * FROM INT8_TBL WHERE '123'::int2 >= q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE '123'::int2 >= q1" +== 043 +-- truncate_limit: 100 +SELECT q1 AS plus, -q1 AS minus FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 AS plus, - q1 AS minus FROM int8_tbl" +== 044 +-- truncate_limit: 100 +SELECT q1, q2, q1 + q2 AS plus FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1, q2, q1 + q2 AS plus FROM int8_tbl" +== 045 +-- truncate_limit: 100 +SELECT q1, q2, q1 - q2 AS minus FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1, q2, q1 - q2 AS minus FROM int8_tbl" +== 046 +-- truncate_limit: 100 +SELECT q1, q2, q1 * q2 AS multiply FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1, q2, q1 * q2 AS multiply FROM int8_tbl" +== 047 +-- truncate_limit: 100 +SELECT q1, q2, q1 * q2 AS multiply FROM INT8_TBL + WHERE q1 < 1000 or (q2 > 0 and q2 < 1000) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT q1, q2, q1 * q2 AS multiply FROM int8_tbl WHERE q1 < 1000 OR (q2 > 0 AND q2 < 1000)" +== 048 +-- truncate_limit: 100 +SELECT q1, q2, q1 / q2 AS divide, q1 % q2 AS mod FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1, q2, q1 / q2 AS divide, q1 % q2 AS mod FROM int8_tbl" +== 049 +-- truncate_limit: 100 +SELECT q1, float8(q1) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="float8" function="float8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q1, float8(q1) FROM int8_tbl" +== 050 +-- truncate_limit: 100 +SELECT q2, float8(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="float8" function="float8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q2, float8(q2) FROM int8_tbl" +== 051 +-- truncate_limit: 100 +SELECT 37 + q1 AS plus4 FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 37 + q1 AS plus4 FROM int8_tbl" +== 052 +-- truncate_limit: 100 +SELECT 37 - q1 AS minus4 FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 37 - q1 AS minus4 FROM int8_tbl" +== 053 +-- truncate_limit: 100 +SELECT 2 * q1 AS "twice int4" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 2 * q1 AS \"twice int4\" FROM int8_tbl" +== 054 +-- truncate_limit: 100 +SELECT q1 * 2 AS "twice int4" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 * 2 AS \"twice int4\" FROM int8_tbl" +== 055 +-- truncate_limit: 100 +-- int8 op int4 +SELECT q1 + 42::int4 AS "8plus4", q1 - 42::int4 AS "8minus4", q1 * 42::int4 AS "8mul4", q1 / 42::int4 AS "8div4" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl" +== 056 +-- truncate_limit: 100 +-- int4 op int8 +SELECT 246::int4 + q1 AS "4plus8", 246::int4 - q1 AS "4minus8", 246::int4 * q1 AS "4mul8", 246::int4 / q1 AS "4div8" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl" +== 057 +-- truncate_limit: 100 +-- int8 op int2 +SELECT q1 + 42::int2 AS "8plus2", q1 - 42::int2 AS "8minus2", q1 * 42::int2 AS "8mul2", q1 / 42::int2 AS "8div2" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl" +== 058 +-- truncate_limit: 100 +-- int2 op int8 +SELECT 246::int2 + q1 AS "2plus8", 246::int2 - q1 AS "2minus8", 246::int2 * q1 AS "2mul8", 246::int2 / q1 AS "2div8" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl" +== 059 +-- truncate_limit: 100 +SELECT q2, abs(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q2, abs(q2) FROM int8_tbl" +== 060 +-- truncate_limit: 100 +SELECT min(q1), min(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(q1), min(q2) FROM int8_tbl" +== 061 +-- truncate_limit: 100 +SELECT max(q1), max(q2) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(q1), max(q2) FROM int8_tbl" +== 062 +-- truncate_limit: 100 +-- TO_CHAR() +|-- +SELECT to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999') FROM int8_tbl" +== 063 +-- truncate_limit: 100 +SELECT to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl" +== 064 +-- truncate_limit: 100 +SELECT to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl" +== 065 +-- truncate_limit: 100 +SELECT to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999') + FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q1 * -1, '9999999999999999S'), to_char(q2 * -1, 'S9999999999999999') FROM int8_tbl" +== 066 +-- truncate_limit: 100 +SELECT to_char(q2, 'MI9999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'MI9999999999999999') FROM int8_tbl" +== 067 +-- truncate_limit: 100 +SELECT to_char(q2, 'FMS9999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'FMS9999999999999999') FROM int8_tbl" +== 068 +-- truncate_limit: 100 +SELECT to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'FM9999999999999999THPR') FROM int8_tbl" +== 069 +-- truncate_limit: 100 +SELECT to_char(q2, 'SG9999999999999999th') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'SG9999999999999999th') FROM int8_tbl" +== 070 +-- truncate_limit: 100 +SELECT to_char(q2, '0999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, '0999999999999999') FROM int8_tbl" +== 071 +-- truncate_limit: 100 +SELECT to_char(q2, 'S0999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'S0999999999999999') FROM int8_tbl" +== 072 +-- truncate_limit: 100 +SELECT to_char(q2, 'FM0999999999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'FM0999999999999999') FROM int8_tbl" +== 073 +-- truncate_limit: 100 +SELECT to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'FM9999999999999999.000') FROM int8_tbl" +== 074 +-- truncate_limit: 100 +SELECT to_char(q2, 'L9999999999999999.000') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'L9999999999999999.000') FROM int8_tbl" +== 075 +-- truncate_limit: 100 +SELECT to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'FM9999999999999999.999') FROM int8_tbl" +== 076 +-- truncate_limit: 100 +SELECT to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM int8_tbl" +== 077 +-- truncate_limit: 100 +SELECT to_char(q2, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl" +== 078 +-- truncate_limit: 100 +SELECT to_char(q2, '999999SG9999999999') FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(q2, '999999SG9999999999') FROM int8_tbl" +== 079 +-- truncate_limit: 100 +-- check min/max values and overflow behavior + +select '-9223372036854775808'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808'::int8" +== 080 +-- truncate_limit: 100 +select '-9223372036854775809'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775809'::int8" +== 081 +-- truncate_limit: 100 +select '9223372036854775807'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807'::int8" +== 082 +-- truncate_limit: 100 +select '9223372036854775808'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775808'::int8" +== 083 +-- truncate_limit: 100 +select -('-9223372036854775807'::int8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-9223372036854775807'::int8" +== 084 +-- truncate_limit: 100 +select -('-9223372036854775808'::int8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-9223372036854775808'::int8" +== 085 +-- truncate_limit: 100 +select 0::int8 - '-9223372036854775808'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0::int8 - '-9223372036854775808'::int8" +== 086 +-- truncate_limit: 100 +select '9223372036854775800'::int8 + '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 + '9223372036854775800'::int8" +== 087 +-- truncate_limit: 100 +select '-9223372036854775800'::int8 + '-9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775800'::int8 + '-9223372036854775800'::int8" +== 088 +-- truncate_limit: 100 +select '9223372036854775800'::int8 - '-9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 - '-9223372036854775800'::int8" +== 089 +-- truncate_limit: 100 +select '-9223372036854775800'::int8 - '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775800'::int8 - '9223372036854775800'::int8" +== 090 +-- truncate_limit: 100 +select '9223372036854775800'::int8 * '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 * '9223372036854775800'::int8" +== 091 +-- truncate_limit: 100 +select '9223372036854775800'::int8 / '0'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 / '0'::int8" +== 092 +-- truncate_limit: 100 +select '9223372036854775800'::int8 % '0'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 % '0'::int8" +== 093 +-- truncate_limit: 100 +select abs('-9223372036854775808'::int8) +-- +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT abs('-9223372036854775808'::int8)" +== 094 +-- truncate_limit: 100 +select '9223372036854775800'::int8 + '100'::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 + '100'::int4" +== 095 +-- truncate_limit: 100 +select '-9223372036854775800'::int8 - '100'::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775800'::int8 - '100'::int4" +== 096 +-- truncate_limit: 100 +select '9223372036854775800'::int8 * '100'::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 * '100'::int4" +== 097 +-- truncate_limit: 100 +select '100'::int4 + '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100'::int4 + '9223372036854775800'::int8" +== 098 +-- truncate_limit: 100 +select '-100'::int4 - '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-100'::int4 - '9223372036854775800'::int8" +== 099 +-- truncate_limit: 100 +select '100'::int4 * '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100'::int4 * '9223372036854775800'::int8" +== 100 +-- truncate_limit: 100 +select '9223372036854775800'::int8 + '100'::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 + '100'::int2" +== 101 +-- truncate_limit: 100 +select '-9223372036854775800'::int8 - '100'::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775800'::int8 - '100'::int2" +== 102 +-- truncate_limit: 100 +select '9223372036854775800'::int8 * '100'::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775800'::int8 * '100'::int2" +== 103 +-- truncate_limit: 100 +select '-9223372036854775808'::int8 / '0'::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808'::int8 / '0'::int2" +== 104 +-- truncate_limit: 100 +select '100'::int2 + '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100'::int2 + '9223372036854775800'::int8" +== 105 +-- truncate_limit: 100 +select '-100'::int2 - '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-100'::int2 - '9223372036854775800'::int8" +== 106 +-- truncate_limit: 100 +select '100'::int2 * '9223372036854775800'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100'::int2 * '9223372036854775800'::int8" +== 107 +-- truncate_limit: 100 +select '100'::int2 / '0'::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100'::int2 / '0'::int8" +== 108 +-- truncate_limit: 100 +SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 = 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT q1::int4 FROM int8_tbl WHERE q2 = 456" +== 109 +-- truncate_limit: 100 +SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 <> 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT q1::int4 FROM int8_tbl WHERE q2 <> 456" +== 110 +-- truncate_limit: 100 +SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 = 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT q1::int2 FROM int8_tbl WHERE q2 = 456" +== 111 +-- truncate_limit: 100 +SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 <> 456 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT q1::int2 FROM int8_tbl WHERE q2 <> 456" +== 112 +-- truncate_limit: 100 +SELECT CAST('42'::int2 AS int8), CAST('-37'::int2 AS int8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::int2::int8, '-37'::int2::int8" +== 113 +-- truncate_limit: 100 +SELECT CAST(q1 AS float4), CAST(q2 AS float8) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1::float4, q2::float8 FROM int8_tbl" +== 114 +-- truncate_limit: 100 +SELECT CAST('36854775807.0'::float4 AS int8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '36854775807.0'::float4::int8" +== 115 +-- truncate_limit: 100 +SELECT CAST('922337203685477580700.0'::float8 AS int8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '922337203685477580700.0'::float8::int8" +== 116 +-- truncate_limit: 100 +SELECT CAST(q1 AS oid) FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1::oid FROM int8_tbl" +== 117 +-- truncate_limit: 100 +SELECT oid::int8 FROM pg_class WHERE relname = 'pg_class' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT oid::int8 FROM pg_class WHERE relname = 'pg_class'" +== 118 +-- truncate_limit: 100 +-- bit operations + +SELECT q1, q2, q1 & q2 AS "and", q1 | q2 AS "or", q1 # q2 AS "xor", ~q1 AS "not" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1, q2, q1 & q2 AS \"and\", q1 | q2 AS \"or\", q1 # q2 AS xor, ~ q1 AS \"not\" FROM int8_tbl" +== 119 +-- truncate_limit: 100 +SELECT q1, q1 << 2 AS "shl", q1 >> 3 AS "shr" FROM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1, q1 << 2 AS shl, q1 >> 3 AS shr FROM int8_tbl" +== 120 +-- truncate_limit: 100 +-- generate_series + +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8)" +== 121 +-- truncate_limit: 100 +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 0) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 0)" +== 122 +-- truncate_limit: 100 +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 2) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 2)" +== 123 +-- truncate_limit: 100 +-- corner case +SELECT (-1::int8<<63)::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT ((- 1::int8) << 63)::text" +== 124 +-- truncate_limit: 100 +SELECT ((-1::int8<<63)+1)::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT (((- 1::int8) << 63) + 1)::text" +== 125 +-- truncate_limit: 100 +-- check sane handling of INT64_MIN overflow cases +SELECT (-9223372036854775808)::int8 * (-1)::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 * (-1)::int8" +== 126 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 / (-1)::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 / (-1)::int8" +== 127 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 % (-1)::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 % (-1)::int8" +== 128 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 * (-1)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 * (-1)::int4" +== 129 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 / (-1)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 / (-1)::int4" +== 130 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 % (-1)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 % (-1)::int4" +== 131 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 * (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 * (-1)::int2" +== 132 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 / (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 / (-1)::int2" +== 133 +-- truncate_limit: 100 +SELECT (-9223372036854775808)::int8 % (-1)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808)::int8 % (-1)::int2" +== 134 +-- truncate_limit: 100 +-- check rounding when casting from float +SELECT x, x::int8 AS int8_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x, x::int8 AS int8_value FROM (VALUES (...)) t(x)" +== 135 +-- truncate_limit: 100 +-- check rounding when casting from numeric +SELECT x, x::int8 AS int8_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x, x::int8 AS int8_value FROM (VALUES (...)) t(x)" +== 136 +-- truncate_limit: 100 +-- test gcd() +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(b, a), gcd(-b, a) +FROM (VALUES (0::int8, 0::int8), + (0::int8, 29893644334::int8), + (288484263558::int8, 29893644334::int8), + (-288484263558::int8, 29893644334::int8), + ((-9223372036854775808)::int8, 1::int8), + ((-9223372036854775808)::int8, 9223372036854775807::int8), + ((-9223372036854775808)::int8, 4611686018427387904::int8)) AS v(a, b) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, gcd(a, b), gcd(a, - b), gcd(b, a), gcd(- b, a) FROM (VALUES (...)) v(a, b)" +== 137 +-- truncate_limit: 100 +SELECT gcd((-9223372036854775808)::int8, 0::int8) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT gcd((-9223372036854775808)::int8, 0::int8)" +== 138 +-- truncate_limit: 100 +-- overflow +SELECT gcd((-9223372036854775808)::int8, (-9223372036854775808)::int8) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT gcd((-9223372036854775808)::int8, (-9223372036854775808)::int8)" +== 139 +-- truncate_limit: 100 +-- overflow + +-- test lcm() +SELECT a, b, lcm(a, b), lcm(a, -b), lcm(b, a), lcm(-b, a) +FROM (VALUES (0::int8, 0::int8), + (0::int8, 29893644334::int8), + (29893644334::int8, 29893644334::int8), + (288484263558::int8, 29893644334::int8), + (-288484263558::int8, 29893644334::int8), + ((-9223372036854775808)::int8, 0::int8)) AS v(a, b) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, lcm(a, b), lcm(a, - b), lcm(b, a), lcm(- b, a) FROM (VALUES (...)) v(a, b)" +== 140 +-- truncate_limit: 100 +SELECT lcm((-9223372036854775808)::int8, 1::int8) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lcm((-9223372036854775808)::int8, 1::int8)" +== 141 +-- truncate_limit: 100 +-- overflow +SELECT lcm(9223372036854775807::int8, 9223372036854775806::int8) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lcm((9223372036854775807)::int8, (9223372036854775806)::int8)" +== 142 +-- truncate_limit: 100 +-- overflow + + +-- non-decimal literals + +SELECT int8 '0b100101' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b100101'::int8" +== 143 +-- truncate_limit: 100 +SELECT int8 '0o273' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o273'::int8" +== 144 +-- truncate_limit: 100 +SELECT int8 '0x42F' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x42F'::int8" +== 145 +-- truncate_limit: 100 +SELECT int8 '0b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b'::int8" +== 146 +-- truncate_limit: 100 +SELECT int8 '0o' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o'::int8" +== 147 +-- truncate_limit: 100 +SELECT int8 '0x' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x'::int8" +== 148 +-- truncate_limit: 100 +-- cases near overflow +SELECT int8 '0b111111111111111111111111111111111111111111111111111111111111111' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b111111111111111111111111111111111111111111111111111111111111111'::int8" +== 149 +-- truncate_limit: 100 +SELECT int8 '0b1000000000000000000000000000000000000000000000000000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b1000000000000000000000000000000000000000000000000000000000000000'::int8" +== 150 +-- truncate_limit: 100 +SELECT int8 '0o777777777777777777777' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o777777777777777777777'::int8" +== 151 +-- truncate_limit: 100 +SELECT int8 '0o1000000000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o1000000000000000000000'::int8" +== 152 +-- truncate_limit: 100 +SELECT int8 '0x7FFFFFFFFFFFFFFF' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x7FFFFFFFFFFFFFFF'::int8" +== 153 +-- truncate_limit: 100 +SELECT int8 '0x8000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x8000000000000000'::int8" +== 154 +-- truncate_limit: 100 +SELECT int8 '-0b1000000000000000000000000000000000000000000000000000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0b1000000000000000000000000000000000000000000000000000000000000000'::int8" +== 155 +-- truncate_limit: 100 +SELECT int8 '-0b1000000000000000000000000000000000000000000000000000000000000001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0b1000000000000000000000000000000000000000000000000000000000000001'::int8" +== 156 +-- truncate_limit: 100 +SELECT int8 '-0o1000000000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0o1000000000000000000000'::int8" +== 157 +-- truncate_limit: 100 +SELECT int8 '-0o1000000000000000000001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0o1000000000000000000001'::int8" +== 158 +-- truncate_limit: 100 +SELECT int8 '-0x8000000000000000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0x8000000000000000'::int8" +== 159 +-- truncate_limit: 100 +SELECT int8 '-0x8000000000000001' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0x8000000000000001'::int8" +== 160 +-- truncate_limit: 100 +-- underscores + +SELECT int8 '1_000_000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000_000'::int8" +== 161 +-- truncate_limit: 100 +SELECT int8 '1_2_3' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_2_3'::int8" +== 162 +-- truncate_limit: 100 +SELECT int8 '0x1EEE_FFFF' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x1EEE_FFFF'::int8" +== 163 +-- truncate_limit: 100 +SELECT int8 '0o2_73' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o2_73'::int8" +== 164 +-- truncate_limit: 100 +SELECT int8 '0b_10_0101' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b_10_0101'::int8" +== 165 +-- truncate_limit: 100 +-- error cases +SELECT int8 '_100' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '_100'::int8" +== 166 +-- truncate_limit: 100 +SELECT int8 '100_' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100_'::int8" +== 167 +-- truncate_limit: 100 +SELECT int8 '100__000' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100__000'::int8" diff --git a/parser/testdata/summary_truncate/postgres_regress/interval.metadata.json b/parser/testdata/summary_truncate/postgres_regress/interval.metadata.json new file mode 100644 index 0000000..df238f5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/interval.metadata.json @@ -0,0 +1,447 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/interval.test b/parser/testdata/summary_truncate/postgres_regress/interval.test new file mode 100644 index 0000000..4eddddb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/interval.test @@ -0,0 +1,3138 @@ +== 001 +-- truncate_limit: 100 +|-- +-- INTERVAL +|-- + +SET DATESTYLE = 'ISO' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"ISO\"" +== 002 +-- truncate_limit: 100 +SET IntervalStyle to postgres +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres" +== 003 +-- truncate_limit: 100 +-- check acceptance of "time zone style" +SELECT INTERVAL '01:00' AS "One hour" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01:00'::interval AS \"One hour\"" +== 004 +-- truncate_limit: 100 +SELECT INTERVAL '+02:00' AS "Two hours" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '+02:00'::interval AS \"Two hours\"" +== 005 +-- truncate_limit: 100 +SELECT INTERVAL '-08:00' AS "Eight hours" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-08:00'::interval AS \"Eight hours\"" +== 006 +-- truncate_limit: 100 +SELECT INTERVAL '-1 +02:03' AS "22 hours ago..." +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1 +02:03'::interval AS \"22 hours ago...\"" +== 007 +-- truncate_limit: 100 +SELECT INTERVAL '-1 days +02:03' AS "22 hours ago..." +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1 days +02:03'::interval AS \"22 hours ago...\"" +== 008 +-- truncate_limit: 100 +SELECT INTERVAL '1.5 weeks' AS "Ten days twelve hours" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.5 weeks'::interval AS \"Ten days twelve hours\"" +== 009 +-- truncate_limit: 100 +SELECT INTERVAL '1.5 months' AS "One month 15 days" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.5 months'::interval AS \"One month 15 days\"" +== 010 +-- truncate_limit: 100 +SELECT INTERVAL '10 years -11 month -12 days +13:14' AS "9 years..." +-- +STMT: SelectStmt +TRUNCATED: "SELECT '10 years -11 month -12 days +13:14'::interval AS \"9 years...\"" +== 011 +-- truncate_limit: 100 +SELECT INTERVAL 'infinity' AS "eternity" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::interval AS eternity" +== 012 +-- truncate_limit: 100 +SELECT INTERVAL '-infinity' AS "beginning of time" +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::interval AS \"beginning of time\"" +== 013 +-- truncate_limit: 100 +CREATE TABLE INTERVAL_TBL (f1 interval) +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE interval_tbl (f1 interval)" +== 014 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 1 minute') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('@ 1 minute')" +== 015 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 5 hour') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('@ 5 hour')" +== 016 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 10 day') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('@ 10 day')" +== 017 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 34 year') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('@ 34 year')" +== 018 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 3 months') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('@ 3 months')" +== 019 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 14 seconds ago') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('@ 14 seconds ago')" +== 020 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('1 day 2 hours 3 minutes 4 seconds') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('1 day 2 hours 3 minutes 4 seconds')" +== 021 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('6 years') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('6 years')" +== 022 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('5 months') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('5 months')" +== 023 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('5 months 12 hours') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('5 months 12 hours')" +== 024 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('infinity') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('infinity')" +== 025 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('-infinity') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('-infinity')" +== 026 +-- truncate_limit: 100 +-- badly formatted interval +INSERT INTO INTERVAL_TBL (f1) VALUES ('badly formatted interval') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('badly formatted interval')" +== 027 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 30 eons ago') +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl (f1) VALUES ('@ 30 eons ago')" +== 028 +-- truncate_limit: 100 +-- Test non-error-throwing API +SELECT pg_input_is_valid('1.5 weeks', 'interval') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1.5 weeks', 'interval')" +== 029 +-- truncate_limit: 100 +SELECT pg_input_is_valid('garbage', 'interval') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('garbage', 'interval')" +== 030 +-- truncate_limit: 100 +SELECT pg_input_is_valid('@ 30 eons ago', 'interval') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('@ 30 eons ago', 'interval')" +== 031 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('garbage', 'interval') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('garbage', 'interval')" +== 032 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('@ 30 eons ago', 'interval') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('@ 30 eons ago', 'interval')" +== 033 +-- truncate_limit: 100 +-- test interval operators + +SELECT * FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl" +== 034 +-- truncate_limit: 100 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 <> interval '@ 10 days' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl WHERE interval_tbl.f1 <> '@ 10 days'::interval" +== 035 +-- truncate_limit: 100 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 <= interval '@ 5 hours' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl WHERE interval_tbl.f1 <= '@ 5 hours'::interval" +== 036 +-- truncate_limit: 100 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 < interval '@ 1 day' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl WHERE interval_tbl.f1 < '@ 1 day'::interval" +== 037 +-- truncate_limit: 100 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 = interval '@ 34 years' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl WHERE interval_tbl.f1 = '@ 34 years'::interval" +== 038 +-- truncate_limit: 100 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 >= interval '@ 1 month' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl WHERE interval_tbl.f1 >= '@ 1 month'::interval" +== 039 +-- truncate_limit: 100 +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 > interval '@ 3 seconds ago' +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FILTER: schema="" table="interval_tbl" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl WHERE interval_tbl.f1 > '@ 3 seconds ago'::interval" +== 040 +-- truncate_limit: 100 +SELECT r1.*, r2.* + FROM INTERVAL_TBL r1, INTERVAL_TBL r2 + WHERE r1.f1 > r2.f1 + ORDER BY r1.f1, r2.f1 +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +ALIAS: "r1"="interval_tbl" +ALIAS: "r2"="interval_tbl" +FILTER: schema="" table="r1" column="f1" +FILTER: schema="" table="r2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT r1.*, r2.* FROM interval_tbl r1, interval_tbl r2 WHERE r1.f1 > r2.f1 ORDER BY r1.f1, r2.f1" +== 041 +-- truncate_limit: 100 +-- test unary minus + +SELECT f1, -f1 FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, - f1 FROM interval_tbl" +== 042 +-- truncate_limit: 100 +SELECT -('-2147483648 months'::interval) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-2147483648 months'::interval" +== 043 +-- truncate_limit: 100 +-- should fail +SELECT -('-2147483647 months'::interval) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-2147483647 months'::interval" +== 044 +-- truncate_limit: 100 +-- ok +SELECT -('-2147483648 days'::interval) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-2147483648 days'::interval" +== 045 +-- truncate_limit: 100 +-- should fail +SELECT -('-2147483647 days'::interval) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-2147483647 days'::interval" +== 046 +-- truncate_limit: 100 +-- ok +SELECT -('-9223372036854775808 us'::interval) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-9223372036854775808 us'::interval" +== 047 +-- truncate_limit: 100 +-- should fail +SELECT -('-9223372036854775807 us'::interval) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-9223372036854775807 us'::interval" +== 048 +-- truncate_limit: 100 +-- ok +SELECT -('-2147483647 months -2147483647 days -9223372036854775807 us'::interval) +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-2147483647 months -2147483647 days -9223372036854775807 us'::interval" +== 049 +-- truncate_limit: 100 +-- should fail + +-- Test intervals that are large enough to overflow 64 bits in comparisons +CREATE TEMP TABLE INTERVAL_TBL_OF (f1 interval) +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE interval_tbl_of (f1 interval)" +== 050 +-- truncate_limit: 100 +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') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl_of (f1) VALUES (...)" +== 051 +-- truncate_limit: 100 +-- these should fail as out-of-range +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483648 days') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl_of (f1) VALUES ('2147483648 days')" +== 052 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483649 days') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl_of (f1) VALUES ('-2147483649 days')" +== 053 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483647 years') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl_of (f1) VALUES ('2147483647 years')" +== 054 +-- truncate_limit: 100 +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483648 years') +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO interval_tbl_of (f1) VALUES ('-2147483648 years')" +== 055 +-- truncate_limit: 100 +-- Test edge-case overflow detection in interval multiplication +select extract(epoch from '256 microseconds'::interval * (2^55)::float8) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '256 microseconds'::interval * (2 ^ 55)::float8)" +== 056 +-- truncate_limit: 100 +SELECT r1.*, r2.* + FROM INTERVAL_TBL_OF r1, INTERVAL_TBL_OF r2 + WHERE r1.f1 > r2.f1 + ORDER BY r1.f1, r2.f1 +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +ALIAS: "r1"="interval_tbl_of" +ALIAS: "r2"="interval_tbl_of" +FILTER: schema="" table="r1" column="f1" +FILTER: schema="" table="r2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT r1.*, r2.* FROM interval_tbl_of r1, interval_tbl_of r2 WHERE ... ORDER BY r1.f1, r2.f1" +== 057 +-- truncate_limit: 100 +CREATE INDEX ON INTERVAL_TBL_OF USING btree (f1) +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON interval_tbl_of USING btree (f1)" +== 058 +-- truncate_limit: 100 +SET enable_seqscan TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO FALSE" +== 059 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1 +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +ALIAS: "r1"="interval_tbl_of" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT f1 FROM interval_tbl_of r1 ORDER BY f1" +== 060 +-- truncate_limit: 100 +SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1 +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +ALIAS: "r1"="interval_tbl_of" +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM interval_tbl_of r1 ORDER BY f1" +== 061 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 062 +-- truncate_limit: 100 +-- subtracting about-to-overflow values should result in 0 +SELECT f1 - f1 FROM INTERVAL_TBL_OF +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 - f1 FROM interval_tbl_of" +== 063 +-- truncate_limit: 100 +DROP TABLE INTERVAL_TBL_OF +-- +TABLE: name="interval_tbl_of" schema="" table="interval_tbl_of" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE interval_tbl_of" +== 064 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE interval_muldiv_tbl (span interval)" +== 065 +-- truncate_limit: 100 +COPY INTERVAL_MULDIV_TBL FROM STDIN +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY interval_muldiv_tbl FROM STDIN" +== 066 +-- truncate_limit: 100 +SELECT span * 0.3 AS product +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT span * 0.3 AS product FROM interval_muldiv_tbl" +== 067 +-- truncate_limit: 100 +SELECT span * 8.2 AS product +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT span * 8.2 AS product FROM interval_muldiv_tbl" +== 068 +-- truncate_limit: 100 +SELECT span / 10 AS quotient +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT span / 10 AS quotient FROM interval_muldiv_tbl" +== 069 +-- truncate_limit: 100 +SELECT span / 100 AS quotient +FROM INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT span / 100 AS quotient FROM interval_muldiv_tbl" +== 070 +-- truncate_limit: 100 +DROP TABLE INTERVAL_MULDIV_TBL +-- +TABLE: name="interval_muldiv_tbl" schema="" table="interval_muldiv_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE interval_muldiv_tbl" +== 071 +-- truncate_limit: 100 +SET DATESTYLE = 'postgres' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO postgres" +== 072 +-- truncate_limit: 100 +SET IntervalStyle to postgres_verbose +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres_verbose" +== 073 +-- truncate_limit: 100 +SELECT * FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM interval_tbl" +== 074 +-- truncate_limit: 100 +-- multiplication and division overflow test cases +SELECT '3000000 months'::interval * 1000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3000000 months'::interval * 1000" +== 075 +-- truncate_limit: 100 +SELECT '3000000 months'::interval / 0.001 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3000000 months'::interval / 0.001" +== 076 +-- truncate_limit: 100 +SELECT '3000000 days'::interval * 1000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3000000 days'::interval * 1000" +== 077 +-- truncate_limit: 100 +SELECT '3000000 days'::interval / 0.001 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3000000 days'::interval / 0.001" +== 078 +-- truncate_limit: 100 +SELECT '1 month 2146410 days'::interval * 1000.5002 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 month 2146410 days'::interval * 1000.5002" +== 079 +-- truncate_limit: 100 +SELECT '4611686018427387904 usec'::interval / 0.1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4611686018427387904 usec'::interval / 0.1" +== 080 +-- truncate_limit: 100 +-- 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 where isfinite(f1) +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT avg(f1) FROM interval_tbl WHERE isfinite(f1)" +== 081 +-- truncate_limit: 100 +-- test long interval input +select '4 millenniums 5 centuries 4 decades 1 year 4 months 4 days 17 minutes 31 seconds'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4 millenniums 5 centuries 4 decades 1 year 4 months 4 days 17 minutes 31 seconds'::interval" +== 082 +-- truncate_limit: 100 +-- 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 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100000000y 10mon -1000000000d -100000h -10min -10.000001s ago'::interval" +== 083 +-- truncate_limit: 100 +-- 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" +-- +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 084 +-- truncate_limit: 100 +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" +-- +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 085 +-- truncate_limit: 100 +SELECT justify_hours(interval '2147483647 days 24 hrs') +-- +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_hours('2147483647 days 24 hrs'::interval)" +== 086 +-- truncate_limit: 100 +SELECT justify_days(interval '2147483647 months 30 days') +-- +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_days('2147483647 months 30 days'::interval)" +== 087 +-- truncate_limit: 100 +-- test justify_interval() + +SELECT justify_interval(interval '1 month -1 hour') as "1 month -1 hour" +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('1 month -1 hour'::interval) AS \"1 month -1 hour\"" +== 088 +-- truncate_limit: 100 +SELECT justify_interval(interval '2147483647 days 24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('2147483647 days 24 hrs'::interval)" +== 089 +-- truncate_limit: 100 +SELECT justify_interval(interval '-2147483648 days -24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('-2147483648 days -24 hrs'::interval)" +== 090 +-- truncate_limit: 100 +SELECT justify_interval(interval '2147483647 months 30 days') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('2147483647 months 30 days'::interval)" +== 091 +-- truncate_limit: 100 +SELECT justify_interval(interval '-2147483648 months -30 days') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('-2147483648 months -30 days'::interval)" +== 092 +-- truncate_limit: 100 +SELECT justify_interval(interval '2147483647 months 30 days -24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('2147483647 months 30 days -24 hrs'::interval)" +== 093 +-- truncate_limit: 100 +SELECT justify_interval(interval '-2147483648 months -30 days 24 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('-2147483648 months -30 days 24 hrs'::interval)" +== 094 +-- truncate_limit: 100 +SELECT justify_interval(interval '2147483647 months -30 days 1440 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('2147483647 months -30 days 1440 hrs'::interval)" +== 095 +-- truncate_limit: 100 +SELECT justify_interval(interval '-2147483648 months 30 days -1440 hrs') +-- +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT justify_interval('-2147483648 months 30 days -1440 hrs'::interval)" +== 096 +-- truncate_limit: 100 +-- test fractional second input, and detection of duplicate units +SET DATESTYLE = 'ISO' +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO \"ISO\"" +== 097 +-- truncate_limit: 100 +SET IntervalStyle TO postgres +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres" +== 098 +-- truncate_limit: 100 +SELECT '1 millisecond'::interval, '1 microsecond'::interval, + '500 seconds 99 milliseconds 51 microseconds'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 099 +-- truncate_limit: 100 +SELECT '3 days 5 milliseconds'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3 days 5 milliseconds'::interval" +== 100 +-- truncate_limit: 100 +SELECT '1 second 2 seconds'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 second 2 seconds'::interval" +== 101 +-- truncate_limit: 100 +-- error +SELECT '10 milliseconds 20 milliseconds'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT '10 milliseconds 20 milliseconds'::interval" +== 102 +-- truncate_limit: 100 +-- error +SELECT '5.5 seconds 3 milliseconds'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5.5 seconds 3 milliseconds'::interval" +== 103 +-- truncate_limit: 100 +-- error +SELECT '1:20:05 5 microseconds'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1:20:05 5 microseconds'::interval" +== 104 +-- truncate_limit: 100 +-- error +SELECT '1 day 1 day'::interval +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 day 1 day'::interval" +== 105 +-- truncate_limit: 100 +-- error +SELECT interval '1-2' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1-2'::interval" +== 106 +-- truncate_limit: 100 +-- SQL year-month literal +SELECT interval '999' second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '999'::interval second" +== 107 +-- truncate_limit: 100 +-- oversize leading field is ok +SELECT interval '999' minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '999'::interval minute" +== 108 +-- truncate_limit: 100 +SELECT interval '999' hour +-- +STMT: SelectStmt +TRUNCATED: "SELECT '999'::interval hour" +== 109 +-- truncate_limit: 100 +SELECT interval '999' day +-- +STMT: SelectStmt +TRUNCATED: "SELECT '999'::interval day" +== 110 +-- truncate_limit: 100 +SELECT interval '999' month +-- +STMT: SelectStmt +TRUNCATED: "SELECT '999'::interval month" +== 111 +-- truncate_limit: 100 +-- test SQL-spec syntaxes for restricted field sets +SELECT interval '1' year +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::interval year" +== 112 +-- truncate_limit: 100 +SELECT interval '2' month +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2'::interval month" +== 113 +-- truncate_limit: 100 +SELECT interval '3' day +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3'::interval day" +== 114 +-- truncate_limit: 100 +SELECT interval '4' hour +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4'::interval hour" +== 115 +-- truncate_limit: 100 +SELECT interval '5' minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5'::interval minute" +== 116 +-- truncate_limit: 100 +SELECT interval '6' second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '6'::interval second" +== 117 +-- truncate_limit: 100 +SELECT interval '1' year to month +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::interval year to month" +== 118 +-- truncate_limit: 100 +SELECT interval '1-2' year to month +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1-2'::interval year to month" +== 119 +-- truncate_limit: 100 +SELECT interval '1 2' day to hour +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2'::interval day to hour" +== 120 +-- truncate_limit: 100 +SELECT interval '1 2:03' day to hour +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03'::interval day to hour" +== 121 +-- truncate_limit: 100 +SELECT interval '1 2:03:04' day to hour +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04'::interval day to hour" +== 122 +-- truncate_limit: 100 +SELECT interval '1 2' day to minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2'::interval day to minute" +== 123 +-- truncate_limit: 100 +SELECT interval '1 2:03' day to minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03'::interval day to minute" +== 124 +-- truncate_limit: 100 +SELECT interval '1 2:03:04' day to minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04'::interval day to minute" +== 125 +-- truncate_limit: 100 +SELECT interval '1 2' day to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2'::interval day to second" +== 126 +-- truncate_limit: 100 +SELECT interval '1 2:03' day to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03'::interval day to second" +== 127 +-- truncate_limit: 100 +SELECT interval '1 2:03:04' day to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04'::interval day to second" +== 128 +-- truncate_limit: 100 +SELECT interval '1 2' hour to minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2'::interval hour to minute" +== 129 +-- truncate_limit: 100 +SELECT interval '1 2:03' hour to minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03'::interval hour to minute" +== 130 +-- truncate_limit: 100 +SELECT interval '1 2:03:04' hour to minute +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04'::interval hour to minute" +== 131 +-- truncate_limit: 100 +SELECT interval '1 2' hour to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2'::interval hour to second" +== 132 +-- truncate_limit: 100 +SELECT interval '1 2:03' hour to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03'::interval hour to second" +== 133 +-- truncate_limit: 100 +SELECT interval '1 2:03:04' hour to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04'::interval hour to second" +== 134 +-- truncate_limit: 100 +SELECT interval '1 2' minute to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2'::interval minute to second" +== 135 +-- truncate_limit: 100 +SELECT interval '1 2:03' minute to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03'::interval minute to second" +== 136 +-- truncate_limit: 100 +SELECT interval '1 2:03:04' minute to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04'::interval minute to second" +== 137 +-- truncate_limit: 100 +SELECT interval '1 +2:03' minute to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 +2:03'::interval minute to second" +== 138 +-- truncate_limit: 100 +SELECT interval '1 +2:03:04' minute to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 +2:03:04'::interval minute to second" +== 139 +-- truncate_limit: 100 +SELECT interval '1 -2:03' minute to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 -2:03'::interval minute to second" +== 140 +-- truncate_limit: 100 +SELECT interval '1 -2:03:04' minute to second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 -2:03:04'::interval minute to second" +== 141 +-- truncate_limit: 100 +SELECT interval '123 11' day to hour +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123 11'::interval day to hour" +== 142 +-- truncate_limit: 100 +-- ok +SELECT interval '123 11' day +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123 11'::interval day" +== 143 +-- truncate_limit: 100 +-- not ok +SELECT interval '123 11' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123 11'::interval" +== 144 +-- truncate_limit: 100 +-- not ok, too ambiguous +SELECT interval '123 2:03 -2:04' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123 2:03 -2:04'::interval" +== 145 +-- truncate_limit: 100 +-- not ok, redundant hh:mm fields + +-- test syntaxes for restricted precision +SELECT interval(0) '1 day 01:23:45.6789' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 day 01:23:45.6789'::interval(0)" +== 146 +-- truncate_limit: 100 +SELECT interval(2) '1 day 01:23:45.6789' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 day 01:23:45.6789'::interval(2)" +== 147 +-- truncate_limit: 100 +SELECT interval '12:34.5678' minute to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:34.5678'::interval minute to second(2)" +== 148 +-- truncate_limit: 100 +-- per SQL spec +SELECT interval '1.234' second +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.234'::interval second" +== 149 +-- truncate_limit: 100 +SELECT interval '1.234' second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.234'::interval second(2)" +== 150 +-- truncate_limit: 100 +SELECT interval '1 2.345' day to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2.345'::interval day to second(2)" +== 151 +-- truncate_limit: 100 +SELECT interval '1 2:03' day to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03'::interval day to second(2)" +== 152 +-- truncate_limit: 100 +SELECT interval '1 2:03.4567' day to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03.4567'::interval day to second(2)" +== 153 +-- truncate_limit: 100 +SELECT interval '1 2:03:04.5678' day to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04.5678'::interval day to second(2)" +== 154 +-- truncate_limit: 100 +SELECT interval '1 2.345' hour to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2.345'::interval hour to second(2)" +== 155 +-- truncate_limit: 100 +SELECT interval '1 2:03.45678' hour to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03.45678'::interval hour to second(2)" +== 156 +-- truncate_limit: 100 +SELECT interval '1 2:03:04.5678' hour to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04.5678'::interval hour to second(2)" +== 157 +-- truncate_limit: 100 +SELECT interval '1 2.3456' minute to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2.3456'::interval minute to second(2)" +== 158 +-- truncate_limit: 100 +SELECT interval '1 2:03.5678' minute to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03.5678'::interval minute to second(2)" +== 159 +-- truncate_limit: 100 +SELECT interval '1 2:03:04.5678' minute to second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2:03:04.5678'::interval minute to second(2)" +== 160 +-- truncate_limit: 100 +SELECT interval '2562047788:00:54.775807' second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2562047788:00:54.775807'::interval second(2)" +== 161 +-- truncate_limit: 100 +-- out of range +SELECT interval '-2562047788:00:54.775807' second(2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2562047788:00:54.775807'::interval second(2)" +== 162 +-- truncate_limit: 100 +-- out of range + +-- 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 +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM interval_tbl" +== 163 +-- truncate_limit: 100 +-- test inputting and outputting SQL standard interval literals +SET IntervalStyle TO sql_standard +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO sql_standard" +== 164 +-- truncate_limit: 100 +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" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 165 +-- truncate_limit: 100 +-- test input of some not-quite-standard interval values in the sql style +SET IntervalStyle TO postgres +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres" +== 166 +-- truncate_limit: 100 +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' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 167 +-- truncate_limit: 100 +-- cases that trigger sign-matching rules in the sql style +SELECT interval '-23 hours 45 min 12.34 sec', + interval '-1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min +12.34 sec' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 168 +-- truncate_limit: 100 +-- test output of couple non-standard interval values in the sql style +SET IntervalStyle TO sql_standard +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO sql_standard" +== 169 +-- truncate_limit: 100 +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' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 170 +-- truncate_limit: 100 +-- cases that trigger sign-matching rules in the sql style +SELECT interval '-23 hours 45 min 12.34 sec', + interval '-1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min +12.34 sec' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 171 +-- truncate_limit: 100 +-- edge case for sign-matching rules +SELECT interval '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::interval" +== 172 +-- truncate_limit: 100 +-- error + +-- test outputting iso8601 intervals +SET IntervalStyle to iso_8601 +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO iso_8601" +== 173 +-- truncate_limit: 100 +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" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 174 +-- truncate_limit: 100 +-- test inputting ISO 8601 4.4.2.1 "Format With Time Unit Designators" +SET IntervalStyle to sql_standard +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO sql_standard" +== 175 +-- truncate_limit: 100 +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" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 176 +-- truncate_limit: 100 +-- test inputting ISO 8601 4.4.2.2 "Alternative Format" +SET IntervalStyle to postgres +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres" +== 177 +-- truncate_limit: 100 +select interval 'P00021015T103020' AS "ISO8601 Basic Format", + interval 'P0002-10-15T10:30:20' AS "ISO8601 Extended Format" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 178 +-- truncate_limit: 100 +-- 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" +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 179 +-- truncate_limit: 100 +-- Check handling of fractional fields in ISO8601 format. +select interval 'P1Y0M3DT4H5M6S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P1Y0M3DT4H5M6S'::interval" +== 180 +-- truncate_limit: 100 +select interval 'P1.0Y0M3DT4H5M6S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P1.0Y0M3DT4H5M6S'::interval" +== 181 +-- truncate_limit: 100 +select interval 'P1.1Y0M3DT4H5M6S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P1.1Y0M3DT4H5M6S'::interval" +== 182 +-- truncate_limit: 100 +select interval 'P1.Y0M3DT4H5M6S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P1.Y0M3DT4H5M6S'::interval" +== 183 +-- truncate_limit: 100 +select interval 'P.1Y0M3DT4H5M6S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P.1Y0M3DT4H5M6S'::interval" +== 184 +-- truncate_limit: 100 +select interval 'P10.5e4Y' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P10.5e4Y'::interval" +== 185 +-- truncate_limit: 100 +-- not per spec, but we've historically taken it +select interval 'P.Y0M3DT4H5M6S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P.Y0M3DT4H5M6S'::interval" +== 186 +-- truncate_limit: 100 +-- error + +-- test a couple rounding cases that changed since 8.3 w/ HAVE_INT64_TIMESTAMP. +SET IntervalStyle to postgres_verbose +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres_verbose" +== 187 +-- truncate_limit: 100 +select interval '-10 mons -3 days +03:55:06.70' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-10 mons -3 days +03:55:06.70'::interval" +== 188 +-- truncate_limit: 100 +select interval '1 year 2 mons 3 days 04:05:06.699999' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 year 2 mons 3 days 04:05:06.699999'::interval" +== 189 +-- truncate_limit: 100 +select interval '0:0:0.7', interval '@ 0.70 secs', interval '0.7 seconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0:0:0.7'::interval, '@ 0.70 secs'::interval, '0.7 seconds'::interval" +== 190 +-- truncate_limit: 100 +-- test time fields using entire 64 bit microseconds range +select interval '2562047788.01521550194 hours' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2562047788.01521550194 hours'::interval" +== 191 +-- truncate_limit: 100 +select interval '-2562047788.01521550222 hours' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2562047788.01521550222 hours'::interval" +== 192 +-- truncate_limit: 100 +select interval '153722867280.912930117 minutes' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '153722867280.912930117 minutes'::interval" +== 193 +-- truncate_limit: 100 +select interval '-153722867280.912930133 minutes' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-153722867280.912930133 minutes'::interval" +== 194 +-- truncate_limit: 100 +select interval '9223372036854.775807 seconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854.775807 seconds'::interval" +== 195 +-- truncate_limit: 100 +select interval '-9223372036854.775808 seconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854.775808 seconds'::interval" +== 196 +-- truncate_limit: 100 +select interval '9223372036854775.807 milliseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775.807 milliseconds'::interval" +== 197 +-- truncate_limit: 100 +select interval '-9223372036854775.808 milliseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775.808 milliseconds'::interval" +== 198 +-- truncate_limit: 100 +select interval '9223372036854775807 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807 microseconds'::interval" +== 199 +-- truncate_limit: 100 +select interval '-9223372036854775808 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808 microseconds'::interval" +== 200 +-- truncate_limit: 100 +select interval 'PT2562047788H54.775807S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047788H54.775807S'::interval" +== 201 +-- truncate_limit: 100 +select interval 'PT-2562047788H-54.775808S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT-2562047788H-54.775808S'::interval" +== 202 +-- truncate_limit: 100 +select interval 'PT2562047788:00:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047788:00:54.775807'::interval" +== 203 +-- truncate_limit: 100 +select interval 'PT2562047788.0152155019444' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047788.0152155019444'::interval" +== 204 +-- truncate_limit: 100 +select interval 'PT-2562047788.0152155022222' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT-2562047788.0152155022222'::interval" +== 205 +-- truncate_limit: 100 +-- overflow each date/time field +select interval '2147483648 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483648 years'::interval" +== 206 +-- truncate_limit: 100 +select interval '-2147483649 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483649 years'::interval" +== 207 +-- truncate_limit: 100 +select interval '2147483648 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483648 months'::interval" +== 208 +-- truncate_limit: 100 +select interval '-2147483649 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483649 months'::interval" +== 209 +-- truncate_limit: 100 +select interval '2147483648 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483648 days'::interval" +== 210 +-- truncate_limit: 100 +select interval '-2147483649 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483649 days'::interval" +== 211 +-- truncate_limit: 100 +select interval '2562047789 hours' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2562047789 hours'::interval" +== 212 +-- truncate_limit: 100 +select interval '-2562047789 hours' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2562047789 hours'::interval" +== 213 +-- truncate_limit: 100 +select interval '153722867281 minutes' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '153722867281 minutes'::interval" +== 214 +-- truncate_limit: 100 +select interval '-153722867281 minutes' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-153722867281 minutes'::interval" +== 215 +-- truncate_limit: 100 +select interval '9223372036855 seconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036855 seconds'::interval" +== 216 +-- truncate_limit: 100 +select interval '-9223372036855 seconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036855 seconds'::interval" +== 217 +-- truncate_limit: 100 +select interval '9223372036854777 millisecond' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854777 millisecond'::interval" +== 218 +-- truncate_limit: 100 +select interval '-9223372036854777 millisecond' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854777 millisecond'::interval" +== 219 +-- truncate_limit: 100 +select interval '9223372036854775808 microsecond' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775808 microsecond'::interval" +== 220 +-- truncate_limit: 100 +select interval '-9223372036854775809 microsecond' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775809 microsecond'::interval" +== 221 +-- truncate_limit: 100 +select interval 'P2147483648' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P2147483648'::interval" +== 222 +-- truncate_limit: 100 +select interval 'P-2147483649' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-2147483649'::interval" +== 223 +-- truncate_limit: 100 +select interval 'P1-2147483647-2147483647' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P1-2147483647-2147483647'::interval" +== 224 +-- truncate_limit: 100 +select interval 'PT2562047789' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047789'::interval" +== 225 +-- truncate_limit: 100 +select interval 'PT-2562047789' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT-2562047789'::interval" +== 226 +-- truncate_limit: 100 +-- overflow with date/time unit aliases +select interval '2147483647 weeks' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 weeks'::interval" +== 227 +-- truncate_limit: 100 +select interval '-2147483648 weeks' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 weeks'::interval" +== 228 +-- truncate_limit: 100 +select interval '2147483647 decades' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 decades'::interval" +== 229 +-- truncate_limit: 100 +select interval '-2147483648 decades' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 decades'::interval" +== 230 +-- truncate_limit: 100 +select interval '2147483647 centuries' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 centuries'::interval" +== 231 +-- truncate_limit: 100 +select interval '-2147483648 centuries' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 centuries'::interval" +== 232 +-- truncate_limit: 100 +select interval '2147483647 millennium' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 millennium'::interval" +== 233 +-- truncate_limit: 100 +select interval '-2147483648 millennium' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 millennium'::interval" +== 234 +-- truncate_limit: 100 +select interval '1 week 2147483647 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 week 2147483647 days'::interval" +== 235 +-- truncate_limit: 100 +select interval '-1 week -2147483648 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1 week -2147483648 days'::interval" +== 236 +-- truncate_limit: 100 +select interval '2147483647 days 1 week' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 days 1 week'::interval" +== 237 +-- truncate_limit: 100 +select interval '-2147483648 days -1 week' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 days -1 week'::interval" +== 238 +-- truncate_limit: 100 +select interval 'P1W2147483647D' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P1W2147483647D'::interval" +== 239 +-- truncate_limit: 100 +select interval 'P-1W-2147483648D' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-1W-2147483648D'::interval" +== 240 +-- truncate_limit: 100 +select interval 'P2147483647D1W' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P2147483647D1W'::interval" +== 241 +-- truncate_limit: 100 +select interval 'P-2147483648D-1W' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-2147483648D-1W'::interval" +== 242 +-- truncate_limit: 100 +select interval '1 decade 2147483647 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 decade 2147483647 years'::interval" +== 243 +-- truncate_limit: 100 +select interval '1 century 2147483647 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 century 2147483647 years'::interval" +== 244 +-- truncate_limit: 100 +select interval '1 millennium 2147483647 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 millennium 2147483647 years'::interval" +== 245 +-- truncate_limit: 100 +select interval '-1 decade -2147483648 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1 decade -2147483648 years'::interval" +== 246 +-- truncate_limit: 100 +select interval '-1 century -2147483648 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1 century -2147483648 years'::interval" +== 247 +-- truncate_limit: 100 +select interval '-1 millennium -2147483648 years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1 millennium -2147483648 years'::interval" +== 248 +-- truncate_limit: 100 +select interval '2147483647 years 1 decade' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 years 1 decade'::interval" +== 249 +-- truncate_limit: 100 +select interval '2147483647 years 1 century' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 years 1 century'::interval" +== 250 +-- truncate_limit: 100 +select interval '2147483647 years 1 millennium' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 years 1 millennium'::interval" +== 251 +-- truncate_limit: 100 +select interval '-2147483648 years -1 decade' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 years -1 decade'::interval" +== 252 +-- truncate_limit: 100 +select interval '-2147483648 years -1 century' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 years -1 century'::interval" +== 253 +-- truncate_limit: 100 +select interval '-2147483648 years -1 millennium' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 years -1 millennium'::interval" +== 254 +-- truncate_limit: 100 +-- overflowing with fractional fields - postgres format +select interval '0.1 millennium 2147483647 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 millennium 2147483647 months'::interval" +== 255 +-- truncate_limit: 100 +select interval '0.1 centuries 2147483647 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 centuries 2147483647 months'::interval" +== 256 +-- truncate_limit: 100 +select interval '0.1 decades 2147483647 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 decades 2147483647 months'::interval" +== 257 +-- truncate_limit: 100 +select interval '0.1 yrs 2147483647 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 yrs 2147483647 months'::interval" +== 258 +-- truncate_limit: 100 +select interval '-0.1 millennium -2147483648 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.1 millennium -2147483648 months'::interval" +== 259 +-- truncate_limit: 100 +select interval '-0.1 centuries -2147483648 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.1 centuries -2147483648 months'::interval" +== 260 +-- truncate_limit: 100 +select interval '-0.1 decades -2147483648 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.1 decades -2147483648 months'::interval" +== 261 +-- truncate_limit: 100 +select interval '-0.1 yrs -2147483648 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.1 yrs -2147483648 months'::interval" +== 262 +-- truncate_limit: 100 +select interval '2147483647 months 0.1 millennium' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 months 0.1 millennium'::interval" +== 263 +-- truncate_limit: 100 +select interval '2147483647 months 0.1 centuries' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 months 0.1 centuries'::interval" +== 264 +-- truncate_limit: 100 +select interval '2147483647 months 0.1 decades' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 months 0.1 decades'::interval" +== 265 +-- truncate_limit: 100 +select interval '2147483647 months 0.1 yrs' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 months 0.1 yrs'::interval" +== 266 +-- truncate_limit: 100 +select interval '-2147483648 months -0.1 millennium' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months -0.1 millennium'::interval" +== 267 +-- truncate_limit: 100 +select interval '-2147483648 months -0.1 centuries' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months -0.1 centuries'::interval" +== 268 +-- truncate_limit: 100 +select interval '-2147483648 months -0.1 decades' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months -0.1 decades'::interval" +== 269 +-- truncate_limit: 100 +select interval '-2147483648 months -0.1 yrs' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months -0.1 yrs'::interval" +== 270 +-- truncate_limit: 100 +select interval '0.1 months 2147483647 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 months 2147483647 days'::interval" +== 271 +-- truncate_limit: 100 +select interval '-0.1 months -2147483648 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.1 months -2147483648 days'::interval" +== 272 +-- truncate_limit: 100 +select interval '2147483647 days 0.1 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 days 0.1 months'::interval" +== 273 +-- truncate_limit: 100 +select interval '-2147483648 days -0.1 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 days -0.1 months'::interval" +== 274 +-- truncate_limit: 100 +select interval '0.5 weeks 2147483647 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.5 weeks 2147483647 days'::interval" +== 275 +-- truncate_limit: 100 +select interval '-0.5 weeks -2147483648 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.5 weeks -2147483648 days'::interval" +== 276 +-- truncate_limit: 100 +select interval '2147483647 days 0.5 weeks' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 days 0.5 weeks'::interval" +== 277 +-- truncate_limit: 100 +select interval '-2147483648 days -0.5 weeks' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 days -0.5 weeks'::interval" +== 278 +-- truncate_limit: 100 +select interval '0.01 months 9223372036854775807 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.01 months 9223372036854775807 microseconds'::interval" +== 279 +-- truncate_limit: 100 +select interval '-0.01 months -9223372036854775808 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.01 months -9223372036854775808 microseconds'::interval" +== 280 +-- truncate_limit: 100 +select interval '9223372036854775807 microseconds 0.01 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807 microseconds 0.01 months'::interval" +== 281 +-- truncate_limit: 100 +select interval '-9223372036854775808 microseconds -0.01 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808 microseconds -0.01 months'::interval" +== 282 +-- truncate_limit: 100 +select interval '0.1 weeks 9223372036854775807 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 weeks 9223372036854775807 microseconds'::interval" +== 283 +-- truncate_limit: 100 +select interval '-0.1 weeks -9223372036854775808 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.1 weeks -9223372036854775808 microseconds'::interval" +== 284 +-- truncate_limit: 100 +select interval '9223372036854775807 microseconds 0.1 weeks' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807 microseconds 0.1 weeks'::interval" +== 285 +-- truncate_limit: 100 +select interval '-9223372036854775808 microseconds -0.1 weeks' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808 microseconds -0.1 weeks'::interval" +== 286 +-- truncate_limit: 100 +select interval '0.1 days 9223372036854775807 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 days 9223372036854775807 microseconds'::interval" +== 287 +-- truncate_limit: 100 +select interval '-0.1 days -9223372036854775808 microseconds' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-0.1 days -9223372036854775808 microseconds'::interval" +== 288 +-- truncate_limit: 100 +select interval '9223372036854775807 microseconds 0.1 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807 microseconds 0.1 days'::interval" +== 289 +-- truncate_limit: 100 +select interval '-9223372036854775808 microseconds -0.1 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808 microseconds -0.1 days'::interval" +== 290 +-- truncate_limit: 100 +-- overflowing with fractional fields - ISO8601 format +select interval 'P0.1Y2147483647M' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P0.1Y2147483647M'::interval" +== 291 +-- truncate_limit: 100 +select interval 'P-0.1Y-2147483648M' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-0.1Y-2147483648M'::interval" +== 292 +-- truncate_limit: 100 +select interval 'P2147483647M0.1Y' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P2147483647M0.1Y'::interval" +== 293 +-- truncate_limit: 100 +select interval 'P-2147483648M-0.1Y' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-2147483648M-0.1Y'::interval" +== 294 +-- truncate_limit: 100 +select interval 'P0.1M2147483647D' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P0.1M2147483647D'::interval" +== 295 +-- truncate_limit: 100 +select interval 'P-0.1M-2147483648D' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-0.1M-2147483648D'::interval" +== 296 +-- truncate_limit: 100 +select interval 'P2147483647D0.1M' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P2147483647D0.1M'::interval" +== 297 +-- truncate_limit: 100 +select interval 'P-2147483648D-0.1M' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-2147483648D-0.1M'::interval" +== 298 +-- truncate_limit: 100 +select interval 'P0.5W2147483647D' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P0.5W2147483647D'::interval" +== 299 +-- truncate_limit: 100 +select interval 'P-0.5W-2147483648D' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-0.5W-2147483648D'::interval" +== 300 +-- truncate_limit: 100 +select interval 'P2147483647D0.5W' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P2147483647D0.5W'::interval" +== 301 +-- truncate_limit: 100 +select interval 'P-2147483648D-0.5W' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-2147483648D-0.5W'::interval" +== 302 +-- truncate_limit: 100 +select interval 'P0.01MT2562047788H54.775807S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P0.01MT2562047788H54.775807S'::interval" +== 303 +-- truncate_limit: 100 +select interval 'P-0.01MT-2562047788H-54.775808S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-0.01MT-2562047788H-54.775808S'::interval" +== 304 +-- truncate_limit: 100 +select interval 'P0.1DT2562047788H54.775807S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P0.1DT2562047788H54.775807S'::interval" +== 305 +-- truncate_limit: 100 +select interval 'P-0.1DT-2562047788H-54.775808S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P-0.1DT-2562047788H-54.775808S'::interval" +== 306 +-- truncate_limit: 100 +select interval 'PT2562047788.1H54.775807S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047788.1H54.775807S'::interval" +== 307 +-- truncate_limit: 100 +select interval 'PT-2562047788.1H-54.775808S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT-2562047788.1H-54.775808S'::interval" +== 308 +-- truncate_limit: 100 +select interval 'PT2562047788H0.1M54.775807S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047788H0.1M54.775807S'::interval" +== 309 +-- truncate_limit: 100 +select interval 'PT-2562047788H-0.1M-54.775808S' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT-2562047788H-0.1M-54.775808S'::interval" +== 310 +-- truncate_limit: 100 +-- overflowing with fractional fields - ISO8601 alternative format +select interval 'P0.1-2147483647-00' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P0.1-2147483647-00'::interval" +== 311 +-- truncate_limit: 100 +select interval 'P00-0.1-2147483647' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P00-0.1-2147483647'::interval" +== 312 +-- truncate_limit: 100 +select interval 'P00-0.01-00T2562047788:00:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P00-0.01-00T2562047788:00:54.775807'::interval" +== 313 +-- truncate_limit: 100 +select interval 'P00-00-0.1T2562047788:00:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'P00-00-0.1T2562047788:00:54.775807'::interval" +== 314 +-- truncate_limit: 100 +select interval 'PT2562047788.1:00:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047788.1:00:54.775807'::interval" +== 315 +-- truncate_limit: 100 +select interval 'PT2562047788:01.:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'PT2562047788:01.:54.775807'::interval" +== 316 +-- truncate_limit: 100 +-- overflowing with fractional fields - SQL standard format +select interval '0.1 2562047788:0:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 2562047788:0:54.775807'::interval" +== 317 +-- truncate_limit: 100 +select interval '0.1 2562047788:0:54.775808 ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1 2562047788:0:54.775808 ago'::interval" +== 318 +-- truncate_limit: 100 +select interval '2562047788.1:0:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2562047788.1:0:54.775807'::interval" +== 319 +-- truncate_limit: 100 +select interval '2562047788.1:0:54.775808 ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2562047788.1:0:54.775808 ago'::interval" +== 320 +-- truncate_limit: 100 +select interval '2562047788:0.1:54.775807' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2562047788:0.1:54.775807'::interval" +== 321 +-- truncate_limit: 100 +select interval '2562047788:0.1:54.775808 ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2562047788:0.1:54.775808 ago'::interval" +== 322 +-- truncate_limit: 100 +-- overflowing using AGO with INT_MIN +select interval '-2147483648 months ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months ago'::interval" +== 323 +-- truncate_limit: 100 +select interval '-2147483648 days ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 days ago'::interval" +== 324 +-- truncate_limit: 100 +select interval '-9223372036854775808 microseconds ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808 microseconds ago'::interval" +== 325 +-- truncate_limit: 100 +select interval '-2147483648 months -2147483648 days -9223372036854775808 microseconds ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months -2147483648 days -9223372036854775808 microseconds ago'::interval" +== 326 +-- truncate_limit: 100 +-- overflowing using make_interval +select make_interval(years := 178956971) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := 178956971)" +== 327 +-- truncate_limit: 100 +select make_interval(years := -178956971) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := -178956971)" +== 328 +-- truncate_limit: 100 +select make_interval(years := 1, months := 2147483647) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := 1, months := 2147483647)" +== 329 +-- truncate_limit: 100 +select make_interval(years := -1, months := -2147483648) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := -1, months := -2147483648)" +== 330 +-- truncate_limit: 100 +select make_interval(weeks := 306783379) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(weeks := 306783379)" +== 331 +-- truncate_limit: 100 +select make_interval(weeks := -306783379) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(weeks := -306783379)" +== 332 +-- truncate_limit: 100 +select make_interval(weeks := 1, days := 2147483647) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(weeks := 1, days := 2147483647)" +== 333 +-- truncate_limit: 100 +select make_interval(weeks := -1, days := -2147483648) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(weeks := -1, days := -2147483648)" +== 334 +-- truncate_limit: 100 +select make_interval(secs := 1e308) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(secs := 1e308)" +== 335 +-- truncate_limit: 100 +select make_interval(secs := 1e18) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(secs := 1e18)" +== 336 +-- truncate_limit: 100 +select make_interval(secs := -1e18) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(secs := -1e18)" +== 337 +-- truncate_limit: 100 +select make_interval(mins := 1, secs := 9223372036800.0) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(mins := 1, secs := 9223372036800.0)" +== 338 +-- truncate_limit: 100 +select make_interval(mins := -1, secs := -9223372036800.0) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(mins := -1, secs := -9223372036800.0)" +== 339 +-- truncate_limit: 100 +-- test that INT_MIN number is formatted properly +SET IntervalStyle to postgres +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres" +== 340 +-- truncate_limit: 100 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483647 months -2147483648 days -9223372036854775808 us'::interval" +== 341 +-- truncate_limit: 100 +SET IntervalStyle to sql_standard +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO sql_standard" +== 342 +-- truncate_limit: 100 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483647 months -2147483648 days -9223372036854775808 us'::interval" +== 343 +-- truncate_limit: 100 +SET IntervalStyle to iso_8601 +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO iso_8601" +== 344 +-- truncate_limit: 100 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483647 months -2147483648 days -9223372036854775808 us'::interval" +== 345 +-- truncate_limit: 100 +SET IntervalStyle to postgres_verbose +-- +STMT: VariableSetStmt +TRUNCATED: "SET intervalstyle TO postgres_verbose" +== 346 +-- truncate_limit: 100 +select interval '-2147483647 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483647 months -2147483648 days -9223372036854775808 us'::interval" +== 347 +-- truncate_limit: 100 +-- check that '30 days' equals '1 month' according to the hash function +select '30 days'::interval = '1 month'::interval as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT '30 days'::interval = '1 month'::interval AS t" +== 348 +-- truncate_limit: 100 +select interval_hash('30 days'::interval) = interval_hash('1 month'::interval) as t +-- +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +FUNCTION: name="interval_hash" function="interval_hash" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT interval_hash('30 days'::interval) = interval_hash('1 month'::interval) AS t" +== 349 +-- truncate_limit: 100 +-- numeric constructor +select make_interval(years := 2) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := 2)" +== 350 +-- truncate_limit: 100 +select make_interval(years := 1, months := 6) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := 1, months := 6)" +== 351 +-- truncate_limit: 100 +select make_interval(years := 1, months := -1, weeks := 5, days := -7, hours := 25, mins := -180) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := 1, months := -1, weeks := 5, days := -7, hours := 25, mins := -180)" +== 352 +-- truncate_limit: 100 +select make_interval() = make_interval(years := 0, months := 0, weeks := 0, days := 0, mins := 0, secs := 0.0) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 353 +-- truncate_limit: 100 +select make_interval(hours := -2, mins := -10, secs := -25.3) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(hours := -2, mins := -10, secs := -25.3)" +== 354 +-- truncate_limit: 100 +select make_interval(years := 'inf'::float::int) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(years := 'inf'::double precision::int)" +== 355 +-- truncate_limit: 100 +select make_interval(months := 'NaN'::float::int) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(months := 'NaN'::double precision::int)" +== 356 +-- truncate_limit: 100 +select make_interval(secs := 'inf') +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(secs := 'inf')" +== 357 +-- truncate_limit: 100 +select make_interval(secs := 'NaN') +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(secs := 'NaN')" +== 358 +-- truncate_limit: 100 +select make_interval(secs := 7e12) +-- +FUNCTION: name="make_interval" function="make_interval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_interval(secs := 7e12)" +== 359 +-- truncate_limit: 100 +|-- +-- test EXTRACT +|-- +SELECT f1, + EXTRACT(MICROSECOND FROM f1) AS MICROSECOND, + EXTRACT(MILLISECOND FROM f1) AS MILLISECOND, + EXTRACT(SECOND FROM f1) AS SECOND, + EXTRACT(MINUTE FROM f1) AS MINUTE, + EXTRACT(HOUR FROM f1) AS HOUR, + EXTRACT(DAY FROM f1) AS DAY, + EXTRACT(MONTH FROM f1) AS MONTH, + EXTRACT(QUARTER FROM f1) AS QUARTER, + EXTRACT(YEAR FROM f1) AS YEAR, + EXTRACT(DECADE FROM f1) AS DECADE, + EXTRACT(CENTURY FROM f1) AS CENTURY, + EXTRACT(MILLENNIUM FROM f1) AS MILLENNIUM, + EXTRACT(EPOCH FROM f1) AS EPOCH + FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM interval_tbl" +== 360 +-- truncate_limit: 100 +SELECT EXTRACT(FORTNIGHT FROM INTERVAL '2 days') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('fortnight' FROM '2 days'::interval)" +== 361 +-- truncate_limit: 100 +-- error +SELECT EXTRACT(TIMEZONE FROM INTERVAL '2 days') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone' FROM '2 days'::interval)" +== 362 +-- truncate_limit: 100 +-- error + +SELECT EXTRACT(DECADE FROM INTERVAL '100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '100 y'::interval)" +== 363 +-- truncate_limit: 100 +SELECT EXTRACT(DECADE FROM INTERVAL '99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '99 y'::interval)" +== 364 +-- truncate_limit: 100 +SELECT EXTRACT(DECADE FROM INTERVAL '-99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '-99 y'::interval)" +== 365 +-- truncate_limit: 100 +SELECT EXTRACT(DECADE FROM INTERVAL '-100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('decade' FROM '-100 y'::interval)" +== 366 +-- truncate_limit: 100 +SELECT EXTRACT(CENTURY FROM INTERVAL '100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '100 y'::interval)" +== 367 +-- truncate_limit: 100 +SELECT EXTRACT(CENTURY FROM INTERVAL '99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '99 y'::interval)" +== 368 +-- truncate_limit: 100 +SELECT EXTRACT(CENTURY FROM INTERVAL '-99 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '-99 y'::interval)" +== 369 +-- truncate_limit: 100 +SELECT EXTRACT(CENTURY FROM INTERVAL '-100 y') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('century' FROM '-100 y'::interval)" +== 370 +-- truncate_limit: 100 +-- date_part implementation is mostly the same as extract, so only +-- test a few cases for additional coverage. +SELECT f1, + date_part('microsecond', f1) AS microsecond, + date_part('millisecond', f1) AS millisecond, + date_part('second', f1) AS second, + date_part('epoch', f1) AS epoch + FROM INTERVAL_TBL +-- +TABLE: name="interval_tbl" schema="" table="interval_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM interval_tbl" +== 371 +-- truncate_limit: 100 +-- internal overflow test case +SELECT extract(epoch from interval '1000000000 days') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '1000000000 days'::interval)" +== 372 +-- truncate_limit: 100 +|-- +-- test infinite intervals +|-- + +-- largest finite intervals +SELECT interval '-2147483648 months -2147483648 days -9223372036854775807 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months -2147483648 days -9223372036854775807 us'::interval" +== 373 +-- truncate_limit: 100 +SELECT interval '2147483647 months 2147483647 days 9223372036854775806 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 months 2147483647 days 9223372036854775806 us'::interval" +== 374 +-- truncate_limit: 100 +-- infinite intervals +SELECT interval '-2147483648 months -2147483648 days -9223372036854775808 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-2147483648 months -2147483648 days -9223372036854775808 us'::interval" +== 375 +-- truncate_limit: 100 +SELECT interval '2147483647 months 2147483647 days 9223372036854775807 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2147483647 months 2147483647 days 9223372036854775807 us'::interval" +== 376 +-- truncate_limit: 100 +CREATE TABLE INFINITE_INTERVAL_TBL (i interval) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE infinite_interval_tbl (i interval)" +== 377 +-- truncate_limit: 100 +INSERT INTO INFINITE_INTERVAL_TBL VALUES ('infinity'), ('-infinity'), ('1 year 2 days 3 hours') +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO infinite_interval_tbl VALUES ('infinity'), ('-infinity'), ('1 year 2 days 3 hours')" +== 378 +-- truncate_limit: 100 +SELECT i, isfinite(i) FROM INFINITE_INTERVAL_TBL +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i, isfinite(i) FROM infinite_interval_tbl" +== 379 +-- truncate_limit: 100 +-- test basic arithmetic +CREATE FUNCTION eval(expr text) +RETURNS text AS +$$ +DECLARE + result text; +BEGIN + EXECUTE 'select '||expr INTO result; + RETURN result; +EXCEPTION WHEN OTHERS THEN + RETURN SQLERRM; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="eval" function="eval" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION eval(expr text) RETURNS text AS $$\nDECLARE\n result text;\nBEGIN\n EXECUTE 'select..." +== 380 +-- truncate_limit: 100 +SELECT d AS date, i AS interval, + eval(format('date %L + interval %L', d, i)) AS plus, + eval(format('date %L - interval %L', d, i)) AS minus +FROM (VALUES (date '-infinity'), + (date '1995-08-06'), + (date 'infinity')) AS t1(d), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i) +-- +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t1(d), (VALUES (...)) t2(i)" +== 381 +-- truncate_limit: 100 +SELECT i1 AS interval1, i2 AS interval2, + eval(format('interval %L + interval %L', i1, i2)) AS plus, + eval(format('interval %L - interval %L', i1, i2)) AS minus +FROM (VALUES (interval '-infinity'), + (interval '2 months'), + (interval 'infinity')) AS t1(i1), + (VALUES (interval '-infinity'), + (interval '10 days'), + (interval 'infinity')) AS t2(i2) +-- +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t1(i1), (VALUES (...)) t2(i2)" +== 382 +-- truncate_limit: 100 +SELECT interval '2147483646 months 2147483646 days 9223372036854775806 us' + interval '1 month 1 day 1 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 383 +-- truncate_limit: 100 +SELECT interval '-2147483647 months -2147483647 days -9223372036854775807 us' + interval '-1 month -1 day -1 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 384 +-- truncate_limit: 100 +SELECT interval '2147483646 months 2147483646 days 9223372036854775806 us' - interval '-1 month -1 day -1 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 385 +-- truncate_limit: 100 +SELECT interval '-2147483647 months -2147483647 days -9223372036854775807 us' - interval '1 month 1 day 1 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 386 +-- truncate_limit: 100 +SELECT t AS timestamp, i AS interval, + eval(format('timestamp %L + interval %L', t, i)) AS plus, + eval(format('timestamp %L - interval %L', t, i)) AS minus +FROM (VALUES (timestamp '-infinity'), + (timestamp '1995-08-06 12:30:15'), + (timestamp 'infinity')) AS t1(t), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i) +-- +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t1(t), (VALUES (...)) t2(i)" +== 387 +-- truncate_limit: 100 +SELECT t AT TIME ZONE 'GMT' AS timestamptz, i AS interval, + eval(format('timestamptz %L + interval %L', t, i)) AS plus, + eval(format('timestamptz %L - interval %L', t, i)) AS minus +FROM (VALUES (timestamptz '-infinity'), + (timestamptz '1995-08-06 12:30:15 GMT'), + (timestamptz 'infinity')) AS t1(t), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="eval" function="eval" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t1(t), (VALUES (...)) t2(i)" +== 388 +-- truncate_limit: 100 +-- time +/- infinite interval not supported +SELECT time '11:27:42' + interval 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::time + 'infinity'::interval" +== 389 +-- truncate_limit: 100 +SELECT time '11:27:42' + interval '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::time + '-infinity'::interval" +== 390 +-- truncate_limit: 100 +SELECT time '11:27:42' - interval 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::time - 'infinity'::interval" +== 391 +-- truncate_limit: 100 +SELECT time '11:27:42' - interval '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::time - '-infinity'::interval" +== 392 +-- truncate_limit: 100 +SELECT timetz '11:27:42' + interval 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::timetz + 'infinity'::interval" +== 393 +-- truncate_limit: 100 +SELECT timetz '11:27:42' + interval '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::timetz + '-infinity'::interval" +== 394 +-- truncate_limit: 100 +SELECT timetz '11:27:42' - interval 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::timetz - 'infinity'::interval" +== 395 +-- truncate_limit: 100 +SELECT timetz '11:27:42' - interval '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '11:27:42'::timetz - '-infinity'::interval" +== 396 +-- truncate_limit: 100 +SELECT lhst.i lhs, + rhst.i rhs, + lhst.i < rhst.i AS lt, + lhst.i <= rhst.i AS le, + lhst.i = rhst.i AS eq, + lhst.i > rhst.i AS gt, + lhst.i >= rhst.i AS ge, + lhst.i <> rhst.i AS ne + FROM INFINITE_INTERVAL_TBL lhst CROSS JOIN INFINITE_INTERVAL_TBL rhst + WHERE NOT isfinite(lhst.i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +ALIAS: "lhst"="infinite_interval_tbl" +ALIAS: "rhst"="infinite_interval_tbl" +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="lhst" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM infinite_interval_tbl lhst CROSS JOIN infinite_interval_tbl rhst WHERE ..." +== 397 +-- truncate_limit: 100 +SELECT i AS interval, + -i AS um, + i * 2.0 AS mul, + i * -2.0 AS mul_neg, + i * 'infinity' AS mul_inf, + i * '-infinity' AS mul_inf_neg, + i / 3.0 AS div, + i / -3.0 AS div_neg + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM infinite_interval_tbl WHERE NOT isfinite(i)" +== 398 +-- truncate_limit: 100 +SELECT -interval '-2147483647 months -2147483647 days -9223372036854775807 us' +-- +STMT: SelectStmt +TRUNCATED: "SELECT - '-2147483647 months -2147483647 days -9223372036854775807 us'::interval" +== 399 +-- truncate_limit: 100 +SELECT interval 'infinity' * 'nan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::interval * 'nan'" +== 400 +-- truncate_limit: 100 +SELECT interval '-infinity' * 'nan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::interval * 'nan'" +== 401 +-- truncate_limit: 100 +SELECT interval '-1073741824 months -1073741824 days -4611686018427387904 us' * 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1073741824 months -1073741824 days -4611686018427387904 us'::interval * 2" +== 402 +-- truncate_limit: 100 +SELECT interval 'infinity' * 0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::interval * 0" +== 403 +-- truncate_limit: 100 +SELECT interval '-infinity' * 0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::interval * 0" +== 404 +-- truncate_limit: 100 +SELECT interval '0 days' * 'infinity'::float +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0 days'::interval * 'infinity'::double precision" +== 405 +-- truncate_limit: 100 +SELECT interval '0 days' * '-infinity'::float +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0 days'::interval * '-infinity'::double precision" +== 406 +-- truncate_limit: 100 +SELECT interval '5 days' * 'infinity'::float +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5 days'::interval * 'infinity'::double precision" +== 407 +-- truncate_limit: 100 +SELECT interval '5 days' * '-infinity'::float +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5 days'::interval * '-infinity'::double precision" +== 408 +-- truncate_limit: 100 +SELECT interval 'infinity' / 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::interval / 'infinity'" +== 409 +-- truncate_limit: 100 +SELECT interval 'infinity' / '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::interval / '-infinity'" +== 410 +-- truncate_limit: 100 +SELECT interval 'infinity' / 'nan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::interval / 'nan'" +== 411 +-- truncate_limit: 100 +SELECT interval '-infinity' / 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::interval / 'infinity'" +== 412 +-- truncate_limit: 100 +SELECT interval '-infinity' / '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::interval / '-infinity'" +== 413 +-- truncate_limit: 100 +SELECT interval '-infinity' / 'nan' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::interval / 'nan'" +== 414 +-- truncate_limit: 100 +SELECT interval '-1073741824 months -1073741824 days -4611686018427387904 us' / 0.5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1073741824 months -1073741824 days -4611686018427387904 us'::interval / 0.5" +== 415 +-- truncate_limit: 100 +SELECT date_bin('infinity', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('infinity', '2001-02-16 20:38:40'::timestamp, '2001-02-16 20:05:00'::timestamp)" +== 416 +-- truncate_limit: 100 +SELECT date_bin('-infinity', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('-infinity', '2001-02-16 20:38:40'::timestamp, '2001-02-16 20:05:00'::timestamp)" +== 417 +-- truncate_limit: 100 +SELECT i AS interval, date_trunc('hour', i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT i AS \"interval\", date_trunc('hour', i) FROM infinite_interval_tbl WHERE NOT isfinite(i)" +== 418 +-- truncate_limit: 100 +SELECT i AS interval, justify_days(i), justify_hours(i), justify_interval(i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i) +-- +TABLE: name="infinite_interval_tbl" schema="" table="infinite_interval_tbl" ctx=Select +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FUNCTION: name="justify_days" function="justify_days" schema="" ctx=Call +FUNCTION: name="justify_hours" function="justify_hours" schema="" ctx=Call +FUNCTION: name="justify_interval" function="justify_interval" schema="" ctx=Call +FUNCTION: name="isfinite" function="isfinite" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM infinite_interval_tbl WHERE NOT isfinite(i)" +== 419 +-- truncate_limit: 100 +SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamp) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamp)" +== 420 +-- truncate_limit: 100 +SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamp) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamp)" +== 421 +-- truncate_limit: 100 +SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamptz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamptz)" +== 422 +-- truncate_limit: 100 +SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamptz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamptz)" +== 423 +-- truncate_limit: 100 +SELECT timezone('infinity'::interval, '12:12:12'::time) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('infinity'::interval, '12:12:12'::time)" +== 424 +-- truncate_limit: 100 +SELECT timezone('-infinity'::interval, '12:12:12'::time) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('-infinity'::interval, '12:12:12'::time)" +== 425 +-- truncate_limit: 100 +SELECT timezone('infinity'::interval, '12:12:12'::timetz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('infinity'::interval, '12:12:12'::timetz)" +== 426 +-- truncate_limit: 100 +SELECT timezone('-infinity'::interval, '12:12:12'::timetz) +-- +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT timezone('-infinity'::interval, '12:12:12'::timetz)" +== 427 +-- truncate_limit: 100 +SELECT 'infinity'::interval::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::interval::time" +== 428 +-- truncate_limit: 100 +SELECT '-infinity'::interval::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::interval::time" +== 429 +-- truncate_limit: 100 +SELECT to_char('infinity'::interval, 'YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('infinity'::interval, 'YYYY')" +== 430 +-- truncate_limit: 100 +SELECT to_char('-infinity'::interval, 'YYYY') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('-infinity'::interval, 'YYYY')" +== 431 +-- truncate_limit: 100 +-- "ago" can only appear once at the end of an interval. +SELECT INTERVAL '42 days 2 seconds ago ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42 days 2 seconds ago ago'::interval" +== 432 +-- truncate_limit: 100 +SELECT INTERVAL '2 minutes ago 5 days' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2 minutes ago 5 days'::interval" +== 433 +-- truncate_limit: 100 +-- consecutive and dangling units are not allowed. +SELECT INTERVAL 'hour 5 months' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'hour 5 months'::interval" +== 434 +-- truncate_limit: 100 +SELECT INTERVAL '1 year months days 5 hours' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 year months days 5 hours'::interval" +== 435 +-- truncate_limit: 100 +-- unacceptable reserved words in interval. Only "infinity", "+infinity" and +-- "-infinity" are allowed. +SELECT INTERVAL 'now' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'now'::interval" +== 436 +-- truncate_limit: 100 +SELECT INTERVAL 'today' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'today'::interval" +== 437 +-- truncate_limit: 100 +SELECT INTERVAL 'tomorrow' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'tomorrow'::interval" +== 438 +-- truncate_limit: 100 +SELECT INTERVAL 'allballs' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'allballs'::interval" +== 439 +-- truncate_limit: 100 +SELECT INTERVAL 'epoch' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'epoch'::interval" +== 440 +-- truncate_limit: 100 +SELECT INTERVAL 'yesterday' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'yesterday'::interval" +== 441 +-- truncate_limit: 100 +-- infinity specification should be the only thing +SELECT INTERVAL 'infinity years' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity years'::interval" +== 442 +-- truncate_limit: 100 +SELECT INTERVAL 'infinity ago' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity ago'::interval" +== 443 +-- truncate_limit: 100 +SELECT INTERVAL '+infinity -infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '+infinity -infinity'::interval" diff --git a/parser/testdata/summary_truncate/postgres_regress/join.metadata.json b/parser/testdata/summary_truncate/postgres_regress/join.metadata.json new file mode 100644 index 0000000..3b007a6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/join.metadata.json @@ -0,0 +1,719 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/join.test b/parser/testdata/summary_truncate/postgres_regress/join.test new file mode 100644 index 0000000..1d38db8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/join.test @@ -0,0 +1,8796 @@ +== 001 +-- truncate_limit: 100 +|-- +-- JOIN +-- Test JOIN clauses +|-- + +CREATE TABLE J1_TBL ( + i integer, + j integer, + t text +) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j1_tbl (i int, j int, t text)" +== 002 +-- truncate_limit: 100 +CREATE TABLE J2_TBL ( + i integer, + k integer +) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j2_tbl (i int, k int)" +== 003 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (1, 4, 'one') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (1, 4, 'one')" +== 004 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (2, 3, 'two') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (2, 3, 'two')" +== 005 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (3, 2, 'three') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (3, 2, 'three')" +== 006 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (4, 1, 'four') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (4, 1, 'four')" +== 007 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (5, 0, 'five') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (5, 0, 'five')" +== 008 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (6, 6, 'six') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (6, 6, 'six')" +== 009 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (7, 7, 'seven') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (7, 7, 'seven')" +== 010 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (8, 8, 'eight') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (8, 8, 'eight')" +== 011 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (0, NULL, 'zero') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (0, NULL, 'zero')" +== 012 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (NULL, NULL, 'null') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (NULL, NULL, 'null')" +== 013 +-- truncate_limit: 100 +INSERT INTO J1_TBL VALUES (NULL, 0, 'zero') +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1_tbl VALUES (NULL, 0, 'zero')" +== 014 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (1, -1) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (1, -1)" +== 015 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (2, 2) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (2, 2)" +== 016 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (3, -3) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (3, -3)" +== 017 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (2, 4) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (2, 4)" +== 018 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (5, -5) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (5, -5)" +== 019 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (5, -5) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (5, -5)" +== 020 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (0, NULL) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (0, NULL)" +== 021 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (NULL, NULL) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (NULL, NULL)" +== 022 +-- truncate_limit: 100 +INSERT INTO J2_TBL VALUES (NULL, 0) +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2_tbl VALUES (NULL, 0)" +== 023 +-- truncate_limit: 100 +-- useful in some tests below +create temp table onerow() +-- +TABLE: name="onerow" schema="" table="onerow" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE onerow ()" +== 024 +-- truncate_limit: 100 +insert into onerow default values +-- +TABLE: name="onerow" schema="" table="onerow" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO onerow DEFAULT VALUES" +== 025 +-- truncate_limit: 100 +analyze onerow +-- +TABLE: name="onerow" schema="" table="onerow" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE onerow" +== 026 +-- truncate_limit: 100 +|-- +-- CORRELATION NAMES +-- Make sure that table/column aliases are supported +-- before diving into more complex join syntax. +|-- + +SELECT * + FROM J1_TBL AS tx +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "tx"="j1_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl tx" +== 027 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL tx +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "tx"="j1_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl tx" +== 028 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL AS t1 (a, b, c) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b, c)" +== 029 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL t1 (a, b, c) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b, c)" +== 030 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b, c), j2_tbl t2(d, e)" +== 031 +-- truncate_limit: 100 +SELECT t1.a, t2.e + FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e) + WHERE t1.a = t2.d +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="d" +STMT: SelectStmt +TRUNCATED: "SELECT t1.a, t2.e FROM j1_tbl t1(a, b, c), j2_tbl t2(d, e) WHERE t1.a = t2.d" +== 032 +-- truncate_limit: 100 +|-- +-- CROSS JOIN +-- Qualifications are not allowed on cross joins, +-- which degenerate into a standard unqualified inner join. +|-- + +SELECT * + FROM J1_TBL CROSS JOIN J2_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl CROSS JOIN j2_tbl" +== 033 +-- truncate_limit: 100 +-- ambiguous column +SELECT i, k, t + FROM J1_TBL CROSS JOIN J2_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT i, k, t FROM j1_tbl CROSS JOIN j2_tbl" +== 034 +-- truncate_limit: 100 +-- resolve previous ambiguity by specifying the table name +SELECT t1.i, k, t + FROM J1_TBL t1 CROSS JOIN J2_TBL t2 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT t1.i, k, t FROM j1_tbl t1 CROSS JOIN j2_tbl t2" +== 035 +-- truncate_limit: 100 +SELECT ii, tt, kk + FROM (J1_TBL CROSS JOIN J2_TBL) + AS tx (ii, jj, tt, ii2, kk) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ii, tt, kk FROM (j1_tbl CROSS JOIN j2_tbl ) tx(ii, jj, tt, ii2, kk)" +== 036 +-- truncate_limit: 100 +SELECT tx.ii, tx.jj, tx.kk + FROM (J1_TBL t1 (a, b, c) CROSS JOIN J2_TBL t2 (d, e)) + AS tx (ii, jj, tt, ii2, kk) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (j1_tbl t1(a, b, c) CROSS JOIN j2_tbl t2(d, e) ) tx(ii, jj, tt, ii2, kk)" +== 037 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "a"="j2_tbl" +ALIAS: "b"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl CROSS JOIN j2_tbl a CROSS JOIN j2_tbl b" +== 038 +-- truncate_limit: 100 +|-- +|-- +-- 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 * + FROM J1_TBL INNER JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl USING (i)" +== 039 +-- truncate_limit: 100 +-- Same as above, slightly different syntax +SELECT * + FROM J1_TBL JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl USING (i)" +== 040 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a) + ORDER BY a, d +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b, c) JOIN j2_tbl t2(a, d) USING (a) ORDER BY a, d" +== 041 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) + ORDER BY b, t1.a +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b, c) JOIN j2_tbl t2(a, b) USING (b) ORDER BY b, t1.a" +== 042 +-- truncate_limit: 100 +-- test join using aliases +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl USING (i) WHERE j1_tbl.t = 'one'" +== 043 +-- truncate_limit: 100 +-- ok +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl USING (i) AS x WHERE j1_tbl.t = 'one'" +== 044 +-- truncate_limit: 100 +-- ok +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (j1_tbl JOIN j2_tbl USING (i) ) x WHERE j1_tbl.t = 'one'" +== 045 +-- truncate_limit: 100 +-- error +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.i = 1 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="x" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl USING (i) AS x WHERE x.i = 1" +== 046 +-- truncate_limit: 100 +-- ok +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="x" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl USING (i) AS x WHERE x.t = 'one'" +== 047 +-- truncate_limit: 100 +-- error +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="x" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (j1_tbl JOIN j2_tbl USING (i) AS x) xx WHERE x.i = 1" +== 048 +-- truncate_limit: 100 +-- error (XXX could use better hint) +SELECT * FROM J1_TBL a1 JOIN J2_TBL a2 USING (i) AS a1 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "a1"="j1_tbl" +ALIAS: "a2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl a1 JOIN j2_tbl a2 USING (i) AS a1" +== 049 +-- truncate_limit: 100 +-- error +SELECT x.* FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT x.* FROM j1_tbl JOIN j2_tbl USING (i) AS x WHERE j1_tbl.t = 'one'" +== 050 +-- truncate_limit: 100 +SELECT ROW(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT ROW(x.*) FROM j1_tbl JOIN j2_tbl USING (i) AS x WHERE j1_tbl.t = 'one'" +== 051 +-- truncate_limit: 100 +SELECT row_to_json(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one' +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="j1_tbl" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(x.*) FROM j1_tbl JOIN j2_tbl USING (i) AS x WHERE j1_tbl.t = 'one'" +== 052 +-- truncate_limit: 100 +|-- +-- NATURAL JOIN +-- Inner equi-join on all columns with the same name +|-- + +SELECT * + FROM J1_TBL NATURAL JOIN J2_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl NATURAL JOIN j2_tbl" +== 053 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b, c) NATURAL JOIN j2_tbl t2(a, d)" +== 054 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b, c) NATURAL JOIN j2_tbl t2(d, a)" +== 055 +-- truncate_limit: 100 +-- mismatch number of columns +-- currently, Postgres will fill in with underlying names +SELECT * + FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +ALIAS: "t1"="j1_tbl" +ALIAS: "t2"="j2_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl t1(a, b) NATURAL JOIN j2_tbl t2(a)" +== 056 +-- truncate_limit: 100 +|-- +-- Inner joins (equi-joins) +|-- + +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl ON j1_tbl.i = j2_tbl.i" +== 057 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl ON j1_tbl.i = j2_tbl.k" +== 058 +-- truncate_limit: 100 +|-- +-- Non-equi-joins +|-- + +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl JOIN j2_tbl ON j1_tbl.i <= j2_tbl.k" +== 059 +-- truncate_limit: 100 +|-- +-- Outer joins +-- Note that OUTER is a noise word +|-- + +SELECT * + FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl LEFT JOIN j2_tbl USING (i) ORDER BY i, k, t" +== 060 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl LEFT JOIN j2_tbl USING (i) ORDER BY i, k, t" +== 061 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl RIGHT JOIN j2_tbl USING (i)" +== 062 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL RIGHT JOIN J2_TBL USING (i) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl RIGHT JOIN j2_tbl USING (i)" +== 063 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl FULL JOIN j2_tbl USING (i) ORDER BY i, k, t" +== 064 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL FULL JOIN J2_TBL USING (i) + ORDER BY i, k, t +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl FULL JOIN j2_tbl USING (i) ORDER BY i, k, t" +== 065 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl LEFT JOIN j2_tbl USING (i) WHERE k = 1" +== 066 +-- truncate_limit: 100 +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1) +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl LEFT JOIN j2_tbl USING (i) WHERE i = 1" +== 067 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "i4"="int4_tbl" +FILTER: schema="" table="a" column="twothousand" +FILTER: schema="" table="b" column="twothousand" +FILTER: schema="" table="a" column="fivethous" +FILTER: schema="" table="b" column="fivethous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl i4, tenk1 a WHERE EXISTS (SELECT * FROM tenk1 b WHERE ..." +== 068 +-- truncate_limit: 100 +|-- +-- More complicated constructs +|-- + +|-- +-- Multiway full join +|-- + +CREATE TABLE t1 (name TEXT, n INTEGER) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (name text, n int)" +== 069 +-- truncate_limit: 100 +CREATE TABLE t2 (name TEXT, n INTEGER) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t2 (name text, n int)" +== 070 +-- truncate_limit: 100 +CREATE TABLE t3 (name TEXT, n INTEGER) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t3 (name text, n int)" +== 071 +-- truncate_limit: 100 +INSERT INTO t1 VALUES ( 'bb', 11 ) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES ('bb', 11)" +== 072 +-- truncate_limit: 100 +INSERT INTO t2 VALUES ( 'bb', 12 ) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 VALUES ('bb', 12)" +== 073 +-- truncate_limit: 100 +INSERT INTO t2 VALUES ( 'cc', 22 ) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 VALUES ('cc', 22)" +== 074 +-- truncate_limit: 100 +INSERT INTO t2 VALUES ( 'ee', 42 ) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 VALUES ('ee', 42)" +== 075 +-- truncate_limit: 100 +INSERT INTO t3 VALUES ( 'bb', 13 ) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t3 VALUES ('bb', 13)" +== 076 +-- truncate_limit: 100 +INSERT INTO t3 VALUES ( 'cc', 23 ) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t3 VALUES ('cc', 23)" +== 077 +-- truncate_limit: 100 +INSERT INTO t3 VALUES ( 'dd', 33 ) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t3 VALUES ('dd', 33)" +== 078 +-- truncate_limit: 100 +SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name)" +== 079 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t2) s2 JOIN (SELECT * FROM t3) s3 USING (name)" +== 080 +-- truncate_limit: 100 +SELECT * FROM +(SELECT * FROM t2) as s2 +LEFT JOIN +(SELECT * FROM t3) s3 +USING (name) +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t2) s2 LEFT JOIN (SELECT * FROM t3) s3 USING (name)" +== 081 +-- truncate_limit: 100 +SELECT * FROM +(SELECT * FROM t2) as s2 +FULL JOIN +(SELECT * FROM t3) s3 +USING (name) +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t2) s2 FULL JOIN (SELECT * FROM t3) s3 USING (name)" +== 082 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t2) s2 NATURAL JOIN (SELECT name, n AS s3_n, 3 AS s3_2 FROM t3) s3" +== 083 +-- truncate_limit: 100 +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 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t2) s2 NATURAL LEFT JOIN (SELECT ... FROM t3) s3" +== 084 +-- truncate_limit: 100 +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 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t2) s2 NATURAL FULL JOIN (SELECT ... FROM t3) s3" +== 085 +-- truncate_limit: 100 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t1) s1 NATURAL JOIN (SELECT ... FROM t2) s2 NATURAL JOIN (SELECT ...." +== 086 +-- truncate_limit: 100 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t1) s1 NATURAL FULL JOIN (SELECT ... FROM t2) s2 NATURAL FULL JOIN..." +== 087 +-- truncate_limit: 100 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t1) s1 NATURAL FULL JOIN (SELECT * FROM (SELECT ... FROM t2) s2 NA..." +== 088 +-- truncate_limit: 100 +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 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t1) s1 NATURAL FULL JOIN (SELECT * FROM (SELECT ... FROM t2) s2 NA..." +== 089 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM t1) s1 FULL JOIN (SELECT name, 2 AS s2_n FROM t2) s2 ON s1_n = s2_n" +== 090 +-- truncate_limit: 100 +-- Test for propagation of nullability constraints into sub-joins + +create temp table x (x1 int, x2 int) +-- +TABLE: name="x" schema="" table="x" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE x (x1 int, x2 int)" +== 091 +-- truncate_limit: 100 +insert into x values (1,11) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO x VALUES (1, 11)" +== 092 +-- truncate_limit: 100 +insert into x values (2,22) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO x VALUES (2, 22)" +== 093 +-- truncate_limit: 100 +insert into x values (3,null) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO x VALUES (3, NULL)" +== 094 +-- truncate_limit: 100 +insert into x values (4,44) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO x VALUES (4, 44)" +== 095 +-- truncate_limit: 100 +insert into x values (5,null) +-- +TABLE: name="x" schema="" table="x" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO x VALUES (5, NULL)" +== 096 +-- truncate_limit: 100 +create temp table y (y1 int, y2 int) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE y (y1 int, y2 int)" +== 097 +-- truncate_limit: 100 +insert into y values (1,111) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y VALUES (1, 111)" +== 098 +-- truncate_limit: 100 +insert into y values (2,222) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y VALUES (2, 222)" +== 099 +-- truncate_limit: 100 +insert into y values (3,333) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y VALUES (3, 333)" +== 100 +-- truncate_limit: 100 +insert into y values (4,null) +-- +TABLE: name="y" schema="" table="y" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y VALUES (4, NULL)" +== 101 +-- truncate_limit: 100 +select * from x +-- +TABLE: name="x" schema="" table="x" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x" +== 102 +-- truncate_limit: 100 +select * from y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 103 +-- truncate_limit: 100 +select * from x left join y on (x1 = y1 and x2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 AND x2 IS NOT NULL" +== 104 +-- truncate_limit: 100 +select * from x left join y on (x1 = y1 and y2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 AND y2 IS NOT NULL" +== 105 +-- truncate_limit: 100 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 LEFT JOIN x xx(xx1, xx2) ON x1 = xx1" +== 106 +-- truncate_limit: 100 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and x2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 LEFT JOIN x xx(xx1, xx2) ON x1 = xx1 AND x2 IS NOT NULL" +== 107 +-- truncate_limit: 100 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and y2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 LEFT JOIN x xx(xx1, xx2) ON x1 = xx1 AND y2 IS NOT NULL" +== 108 +-- truncate_limit: 100 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and xx2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 LEFT JOIN x xx(xx1, xx2) ON x1 = xx1 AND xx2 IS NOT NULL" +== 109 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +FILTER: schema="" table="" column="x2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 LEFT JOIN x xx(xx1, xx2) ON x1 = xx1 WHERE x2 IS NOT NULL" +== 110 +-- truncate_limit: 100 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (y2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +FILTER: schema="" table="" column="y2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 LEFT JOIN x xx(xx1, xx2) ON x1 = xx1 WHERE y2 IS NOT NULL" +== 111 +-- truncate_limit: 100 +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (xx2 is not null) +-- +TABLE: name="x" schema="" table="x" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="x" schema="" table="x" ctx=Select +ALIAS: "xx"="x" +FILTER: schema="" table="" column="xx2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x LEFT JOIN y ON x1 = y1 LEFT JOIN x xx(xx1, xx2) ON x1 = xx1 WHERE xx2 IS NOT NULL" +== 112 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 a WHERE ..." +== 113 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "aa"="int4_tbl" +ALIAS: "b"="float8_tbl" +ALIAS: "bb"="float8_tbl" +ALIAS: "x"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="unique1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="aa" column="f1" +FILTER: schema="" table="bb" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 x WHERE ..." +== 114 +-- truncate_limit: 100 +-- try that with GEQO too +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 115 +-- truncate_limit: 100 +set geqo = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET geqo TO ON" +== 116 +-- truncate_limit: 100 +set geqo_threshold = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET geqo_threshold TO 2" +== 117 +-- truncate_limit: 100 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "aa"="int4_tbl" +ALIAS: "b"="float8_tbl" +ALIAS: "bb"="float8_tbl" +ALIAS: "x"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="unique1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="aa" column="f1" +FILTER: schema="" table="bb" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 x WHERE ..." +== 118 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 119 +-- truncate_limit: 100 +|-- +-- regression test: be sure we cope with proven-dummy append rels +|-- +explain (costs off) +select aa, bb, unique1, unique1 + from tenk1 right join b_star on aa = unique1 + where bb < bb and bb is null +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="b_star" schema="" table="b_star" ctx=Select +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT aa, bb, unique1, unique1 FROM tenk1 RIGHT JOIN b_star ON aa = unique1 ..." +== 120 +-- truncate_limit: 100 +select aa, bb, unique1, unique1 + from tenk1 right join b_star on aa = unique1 + where bb < bb and bb is null +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="b_star" schema="" table="b_star" ctx=Select +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +FILTER: schema="" table="" column="bb" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 RIGHT JOIN b_star ON aa = unique1 WHERE bb < bb AND bb IS NULL" +== 121 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +ALIAS: "i2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl i1 LEFT JOIN (int8_tbl i2 JOIN (SELECT 123 AS x) ss ON..." +== 122 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i1"="int8_tbl" +ALIAS: "i2"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl i1 LEFT JOIN (int8_tbl i2 JOIN (SELECT ...) ss ON i2.q1 = x) ON i1.q2 = i2..." +== 123 +-- truncate_limit: 100 +|-- +-- regression test: check a case where join_clause_is_movable_into() +-- used to give 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +ALIAS: "t4"="tenk1" +ALIAS: "t5"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t4" column="thousand" +FILTER: schema="" table="t5" column="unique1" +FILTER: schema="" table="ss" column="x1" +FILTER: schema="" table="t4" column="tenthous" +FILTER: schema="" table="ss" column="x2" +FILTER: schema="" table="t5" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM tenk1 t1 LEFT JOIN tenk1 t2 ON t1.unique1 = t2.unique1 JOIN tenk..." +== 124 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4a"="int4_tbl" +ALIAS: "i4b"="int4_tbl" +ALIAS: "t"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="thousand" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.f1, b.f1, t.thousand, t.tenthous FROM tenk1 t, (SELECT sum(f1) + 1 A..." +== 125 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4a"="int4_tbl" +ALIAS: "i4b"="int4_tbl" +ALIAS: "t"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="thousand" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="a" column="f1" +FILTER: schema="" table="b" column="f1" +FILTER: schema="" table="t" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t, (SELECT ... FROM int4_tbl i4a) a, (SELECT ... FROM int4_tbl i4b) b WHERE..." +== 126 +-- truncate_limit: 100 +|-- +-- checks for correct handling of quals in multiway outer joins +|-- +explain (costs off) +select t1.f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on t3.f1 > 0 + left join int4_tbl t4 on t3.f1 > 1 +where t4.f1 is null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +FILTER: schema="" table="t4" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.f1 FROM int4_tbl t1, int4_tbl t2 LEFT JOIN int4_tbl t3 ON t3.f1 > 0..." +== 127 +-- truncate_limit: 100 +select t1.f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on t3.f1 > 0 + left join int4_tbl t4 on t3.f1 > 1 +where t4.f1 is null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +FILTER: schema="" table="t4" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int4_tbl t1, int4_tbl t2 LEFT JOIN int4_tbl t3 ON t3.f1 > 0 LEFT JOIN int4_tbl t4..." +== 128 +-- truncate_limit: 100 +explain (costs off) +select * +from int4_tbl t1 left join int4_tbl t2 on true + left join int4_tbl t3 on t2.f1 > 0 + left join int4_tbl t4 on t3.f1 > 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1 LEFT JOIN int4_tbl t2 ON true LEFT JOIN int4_tbl t3..." +== 129 +-- truncate_limit: 100 +explain (costs off) +select * from onek t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join onek t3 on t2.unique1 != t3.unique1 + left join onek t4 on t3.unique1 = t4.unique1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="onek" +ALIAS: "t3"="onek" +ALIAS: "t4"="onek" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM onek t1 LEFT JOIN onek t2 ON t1.unique1 = t2.unique1 LEFT JOIN ..." +== 130 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl t1 + left join (select now() from int4_tbl t2 + left join int4_tbl t3 on t2.f1 = t3.f1 + left join int4_tbl t4 on t3.f1 = t4.f1) s on true + inner join int4_tbl t5 on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int4_tbl" +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1 LEFT JOIN (SELECT now() FROM int4_tbl t2 LEFT JOIN ..." +== 131 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on true + left join int4_tbl t4 on t2.f1 = t3.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1 LEFT JOIN int4_tbl t2 ON true LEFT JOIN int4_tbl t3..." +== 132 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on t2.f1 = t3.f1 + left join int4_tbl t4 on t3.f1 != t4.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1 LEFT JOIN int4_tbl t2 ON true LEFT JOIN int4_tbl t3..." +== 133 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl t1 + left join (int4_tbl t2 left join int4_tbl t3 on t2.f1 > 0) on t2.f1 > 1 + left join int4_tbl t4 on t2.f1 > 2 and t3.f1 > 3 +where t1.f1 = coalesce(t2.f1, 1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="t2" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1 LEFT JOIN (int4_tbl t2 LEFT JOIN int4_tbl t3 ON t2...." +== 134 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl t1 + left join ((select t2.f1 from int4_tbl t2 + left join int4_tbl t3 on t2.f1 > 0 + where t3.f1 is null) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = t1.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="tenk1" +FILTER: schema="" table="t3" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1 LEFT JOIN ((SELECT t2.f1 FROM int4_tbl t2 LEFT JOIN..." +== 135 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl t1 + left join ((select t2.f1 from int4_tbl t2 + left join int4_tbl t3 on t2.f1 > 0 + where t2.f1 <> coalesce(t3.f1, -1)) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = t1.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="tenk1" +FILTER: schema="" table="t2" column="f1" +FILTER: schema="" table="t3" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1 LEFT JOIN ((SELECT t2.f1 FROM int4_tbl t2 LEFT JOIN..." +== 136 +-- truncate_limit: 100 +explain (costs off) +select * from onek t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join onek t3 on t2.unique1 = t3.unique1 + left join onek t4 on t3.unique1 = t4.unique1 and t2.unique2 = t4.unique2 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="onek" +ALIAS: "t3"="onek" +ALIAS: "t4"="onek" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM onek t1 LEFT JOIN onek t2 ON t1.unique1 = t2.unique1 LEFT JOIN ..." +== 137 +-- truncate_limit: 100 +explain (costs off) +select * from int8_tbl t1 left join + (int8_tbl t2 left join int8_tbl t3 full join int8_tbl t4 on false on false) + left join int8_tbl t5 on t2.q1 = t5.q1 +on t2.q2 = 123 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +ALIAS: "t5"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN (int8_tbl t2 LEFT JOIN (int8_tbl t3 FULL ..." +== 138 +-- truncate_limit: 100 +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from int8_tbl t3 where t3.q1 = t2.q1 offset 0) s + on t2.q1 = 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="t3" column="q1" +FILTER: schema="" table="t2" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN int8_tbl t2 ON true LEFT JOIN LATERAL (SE..." +== 139 +-- truncate_limit: 100 +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from generate_series(t2.q1, 100)) s + on t2.q1 = 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN int8_tbl t2 ON true LEFT JOIN LATERAL (SE..." +== 140 +-- truncate_limit: 100 +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select t2.q1 from int8_tbl t3) s + on t2.q1 = 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN int8_tbl t2 ON true LEFT JOIN LATERAL (SE..." +== 141 +-- truncate_limit: 100 +explain (costs off) +select * from onek t1 + left join onek t2 on true + left join lateral + (select * from onek t3 where t3.two = t2.two offset 0) s + on t2.unique1 = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="onek" +ALIAS: "t3"="onek" +FILTER: schema="" table="t3" column="two" +FILTER: schema="" table="t2" column="two" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM onek t1 LEFT JOIN onek t2 ON true LEFT JOIN LATERAL (SELECT * F..." +== 142 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM j1_tbl FULL JOIN (SELECT * FROM j2_tbl ORDER BY j2_tbl.i DESC, ..." +== 143 +-- truncate_limit: 100 +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 +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=Select +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1_tbl FULL JOIN (SELECT * FROM j2_tbl ORDER BY j2_tbl.i DESC, j2_tbl.k ASC) j2_tbl..." +== 144 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="tenk1" +ALIAS: "y"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM (SELECT * FROM tenk1 x ORDER BY x.thousand, x.twothousan..." +== 145 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="tenk1" +ALIAS: "y"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM tenk1 x ORDER BY x.thousand, x.twothousand, x.fivethous) x LEFT JO..." +== 146 +-- truncate_limit: 100 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO 0" +== 147 +-- truncate_limit: 100 +set enable_nestloop = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO 0" +== 148 +-- truncate_limit: 100 +set enable_hashagg = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO 0" +== 149 +-- truncate_limit: 100 +|-- +-- Check that we use the pathkeys from a prefix of the group by / order by +-- clause for the join pathkeys when that prefix covers all join quals. We +-- expect this to lead to an incremental sort for the group by / order by. +|-- +explain (costs off) +select x.thousand, x.twothousand, count(*) +from tenk1 x inner join tenk1 y on x.thousand = y.thousand +group by x.thousand, x.twothousand +order by x.thousand desc, x.twothousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="tenk1" +ALIAS: "y"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x.thousand, x.twothousand, count(*) FROM tenk1 x JOIN tenk1 y ON x.tho..." +== 150 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 151 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 152 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 153 +-- truncate_limit: 100 +|-- +-- Clean up +|-- + +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1" +== 154 +-- truncate_limit: 100 +DROP TABLE t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t2" +== 155 +-- truncate_limit: 100 +DROP TABLE t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t3" +== 156 +-- truncate_limit: 100 +DROP TABLE J1_TBL +-- +TABLE: name="j1_tbl" schema="" table="j1_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j1_tbl" +== 157 +-- truncate_limit: 100 +DROP TABLE J2_TBL +-- +TABLE: name="j2_tbl" schema="" table="j2_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j2_tbl" +== 158 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (a int, b int)" +== 159 +-- truncate_limit: 100 +CREATE TEMP TABLE t2 (a int, b int) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t2 (a int, b int)" +== 160 +-- truncate_limit: 100 +CREATE TEMP TABLE t3 (x int, y int) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t3 (x int, y int)" +== 161 +-- truncate_limit: 100 +INSERT INTO t1 VALUES (5, 10) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES (5, 10)" +== 162 +-- truncate_limit: 100 +INSERT INTO t1 VALUES (15, 20) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES (15, 20)" +== 163 +-- truncate_limit: 100 +INSERT INTO t1 VALUES (100, 100) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES (100, 100)" +== 164 +-- truncate_limit: 100 +INSERT INTO t1 VALUES (200, 1000) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES (200, 1000)" +== 165 +-- truncate_limit: 100 +INSERT INTO t2 VALUES (200, 2000) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 VALUES (200, 2000)" +== 166 +-- truncate_limit: 100 +INSERT INTO t3 VALUES (5, 20) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t3 VALUES (5, 20)" +== 167 +-- truncate_limit: 100 +INSERT INTO t3 VALUES (6, 7) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t3 VALUES (6, 7)" +== 168 +-- truncate_limit: 100 +INSERT INTO t3 VALUES (7, 8) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t3 VALUES (7, 8)" +== 169 +-- truncate_limit: 100 +INSERT INTO t3 VALUES (500, 100) +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t3 VALUES (500, 100)" +== 170 +-- truncate_limit: 100 +DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "table1"="t1" +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a" +== 171 +-- truncate_limit: 100 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t3" +== 172 +-- truncate_limit: 100 +DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a" +== 173 +-- truncate_limit: 100 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t3" +== 174 +-- truncate_limit: 100 +DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y +-- +TABLE: name="t3" schema="" table="t3" ctx=DML +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "t3_other"="t3" +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y" +== 175 +-- truncate_limit: 100 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t3" +== 176 +-- truncate_limit: 100 +-- Test join against inheritance tree + +create temp table t2a () inherits (t2) +-- +TABLE: name="t2a" schema="" table="t2a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t2a () INHERITS (t2)" +== 177 +-- truncate_limit: 100 +insert into t2a values (200, 2001) +-- +TABLE: name="t2a" schema="" table="t2a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2a VALUES (200, 2001)" +== 178 +-- truncate_limit: 100 +select * from t1 left join t2 on (t1.a = t2.a) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a" +== 179 +-- truncate_limit: 100 +-- Test matching of column name with wrong alias + +select t1.x from t1 join t3 on (t1.a = t3.x) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT t1.x FROM t1 JOIN t3 ON t1.a = t3.x" +== 180 +-- truncate_limit: 100 +-- Test matching of locking clause with wrong alias + +select t1.*, t2.*, unnamed_join.* from + t1 join t2 on (t1.a = t2.a), t3 as unnamed_join + for update of unnamed_join +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 JOIN t2 ON t1.a = t2.a, t3 unnamed_join FOR UPDATE OF unnamed_join" +== 181 +-- truncate_limit: 100 +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of unnamed_join +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 JOIN t2 USING (a) AS foo, t3 unnamed_join FOR UPDATE OF unnamed_join" +== 182 +-- truncate_limit: 100 +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of foo +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +TRUNCATED: "SELECT foo.*, unnamed_join.* FROM t1 JOIN t2 USING (a) AS foo, t3 unnamed_join FOR UPDATE OF foo" +== 183 +-- truncate_limit: 100 +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of foo +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (t1 JOIN t2 USING (a) AS foo) bar, t3 unnamed_join FOR UPDATE OF foo" +== 184 +-- truncate_limit: 100 +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of bar +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "unnamed_join"="t3" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (t1 JOIN t2 USING (a) AS foo) bar, t3 unnamed_join FOR UPDATE OF bar" +== 185 +-- truncate_limit: 100 +|-- +-- regression test for 8.1 merge right join bug +|-- + +CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt1 (tt1_id int4, joincol int4)" +== 186 +-- truncate_limit: 100 +INSERT INTO tt1 VALUES (1, 11) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt1 VALUES (1, 11)" +== 187 +-- truncate_limit: 100 +INSERT INTO tt1 VALUES (2, NULL) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt1 VALUES (2, NULL)" +== 188 +-- truncate_limit: 100 +CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt2 (tt2_id int4, joincol int4)" +== 189 +-- truncate_limit: 100 +INSERT INTO tt2 VALUES (21, 11) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt2 VALUES (21, 11)" +== 190 +-- truncate_limit: 100 +INSERT INTO tt2 VALUES (22, 11) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt2 VALUES (22, 11)" +== 191 +-- truncate_limit: 100 +set enable_hashjoin to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 192 +-- truncate_limit: 100 +set enable_nestloop to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 193 +-- truncate_limit: 100 +-- these should give the same results + +select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +TABLE: name="tt2" schema="" table="tt2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tt1.*, tt2.* FROM tt1 LEFT JOIN tt2 ON tt1.joincol = tt2.joincol" +== 194 +-- truncate_limit: 100 +select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol +-- +TABLE: name="tt2" schema="" table="tt2" ctx=Select +TABLE: name="tt1" schema="" table="tt1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tt1.*, tt2.* FROM tt2 RIGHT JOIN tt1 ON tt1.joincol = tt2.joincol" +== 195 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 196 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 197 +-- truncate_limit: 100 +|-- +-- regression test for bug #18522 (merge-right-anti-join in inner_unique cases) +|-- + +create temp table tbl_ra(a int unique, b int) +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tbl_ra (a int UNIQUE, b int)" +== 198 +-- truncate_limit: 100 +insert into tbl_ra select i, i%100 from generate_series(1,1000)i +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl_ra SELECT i, i % 100 FROM generate_series(1, 1000) i" +== 199 +-- truncate_limit: 100 +create index on tbl_ra (b) +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tbl_ra USING btree (b)" +== 200 +-- truncate_limit: 100 +analyze tbl_ra +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE tbl_ra" +== 201 +-- truncate_limit: 100 +set enable_hashjoin to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 202 +-- truncate_limit: 100 +set enable_nestloop to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 203 +-- truncate_limit: 100 +-- ensure we get a merge right anti join +explain (costs off) +select * from tbl_ra t1 +where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2 +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +ALIAS: "t1"="tbl_ra" +ALIAS: "t2"="tbl_ra" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tbl_ra t1 WHERE NOT EXISTS (SELECT 1 FROM tbl_ra t2 WHERE t2.b ..." +== 204 +-- truncate_limit: 100 +-- and check we get the expected results +select * from tbl_ra t1 +where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2 +-- +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +TABLE: name="tbl_ra" schema="" table="tbl_ra" ctx=Select +ALIAS: "t1"="tbl_ra" +ALIAS: "t2"="tbl_ra" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tbl_ra t1 WHERE NOT EXISTS (SELECT 1 FROM tbl_ra t2 WHERE t2.b = t1.a) AND t1.b < 2" +== 205 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 206 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 207 +-- truncate_limit: 100 +|-- +-- regression test for bug #13908 (hash join with skew tuples & nbatch increase) +|-- + +set work_mem to '64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 208 +-- truncate_limit: 100 +set enable_mergejoin to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 209 +-- truncate_limit: 100 +set enable_memoize to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_memoize TO OFF" +== 210 +-- truncate_limit: 100 +explain (costs off) +select count(*) from tenk1 a, tenk1 b + where a.hundred = b.thousand and (b.fivethous % 10) < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="hundred" +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="b" column="fivethous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 a, tenk1 b WHERE a.hundred = b.thousand AND (b.fiv..." +== 211 +-- truncate_limit: 100 +select count(*) from tenk1 a, tenk1 b + where a.hundred = b.thousand and (b.fivethous % 10) < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="hundred" +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="b" column="fivethous" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 a, tenk1 b WHERE a.hundred = b.thousand AND (b.fivethous % 10) < 10" +== 212 +-- truncate_limit: 100 +reset work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET work_mem" +== 213 +-- truncate_limit: 100 +reset enable_mergejoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_mergejoin" +== 214 +-- truncate_limit: 100 +reset enable_memoize +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_memoize" +== 215 +-- truncate_limit: 100 +|-- +-- regression test for 8.2 bug with improper re-ordering of left joins +|-- + +create temp table tt3(f1 int, f2 text) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt3 (f1 int, f2 text)" +== 216 +-- truncate_limit: 100 +insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt3 SELECT x, repeat('xyzzy', 100) FROM generate_series(1, 10000) x" +== 217 +-- truncate_limit: 100 +analyze tt3 +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE tt3" +== 218 +-- truncate_limit: 100 +create temp table tt4(f1 int) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt4 (f1 int)" +== 219 +-- truncate_limit: 100 +insert into tt4 values (0),(1),(9999) +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt4 VALUES (0), (1), (9999)" +== 220 +-- truncate_limit: 100 +analyze tt4 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE tt4" +== 221 +-- truncate_limit: 100 +set enable_nestloop to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 222 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE COALESCE(c.f1, 0) = 0 +) AS d ON (a.f1 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +ALIAS: "a"="tt4" +ALIAS: "b"="tt3" +ALIAS: "c"="tt3" +FILTER: schema="" table="d" column="f1" +FILTER: schema="" table="c" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.f1 FROM tt4 a LEFT JOIN (SELECT b.f1 FROM tt3 b LEFT JOIN tt3 c ON b..." +== 223 +-- truncate_limit: 100 +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE COALESCE(c.f1, 0) = 0 +) AS d ON (a.f1 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1 +-- +TABLE: name="tt4" schema="" table="tt4" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +TABLE: name="tt3" schema="" table="tt3" ctx=Select +ALIAS: "a"="tt4" +ALIAS: "b"="tt3" +ALIAS: "c"="tt3" +FILTER: schema="" table="d" column="f1" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tt4 a LEFT JOIN (SELECT ... FROM tt3 b LEFT JOIN tt3 c ON b.f1 = c.f1 WHERE ...) ..." +== 224 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 225 +-- truncate_limit: 100 +|-- +-- basic semijoin and antijoin recognition tests +|-- + +explain (costs off) +select a.* from tenk1 a +where unique1 in (select unique2 from tenk1 b) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.* FROM tenk1 a WHERE unique1 IN (SELECT unique2 FROM tenk1 b)" +== 226 +-- truncate_limit: 100 +-- sadly, this is not an antijoin +explain (costs off) +select a.* from tenk1 a +where unique1 not in (select unique2 from tenk1 b) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.* FROM tenk1 a WHERE NOT unique1 IN (SELECT unique2 FROM tenk1 b)" +== 227 +-- truncate_limit: 100 +explain (costs off) +select a.* from tenk1 a +where exists (select 1 from tenk1 b where a.unique1 = b.unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.* FROM tenk1 a WHERE EXISTS (SELECT 1 FROM tenk1 b WHERE a.unique1 =..." +== 228 +-- truncate_limit: 100 +explain (costs off) +select a.* from tenk1 a +where not exists (select 1 from tenk1 b where a.unique1 = b.unique2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.* FROM tenk1 a WHERE NOT EXISTS (SELECT 1 FROM tenk1 b WHERE a.uniqu..." +== 229 +-- truncate_limit: 100 +explain (costs off) +select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2 +where b.unique2 is null +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.* FROM tenk1 a LEFT JOIN tenk1 b ON a.unique1 = b.unique2 WHERE b.un..." +== 230 +-- truncate_limit: 100 +|-- +-- regression test for proper handling of outer joins within antijoins +|-- + +create temp table tt4x(c1 int, c2 int, c3 int) +-- +TABLE: name="tt4x" schema="" table="tt4x" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt4x (c1 int, c2 int, c3 int)" +== 231 +-- truncate_limit: 100 +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 +) +-- +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +TABLE: name="tt4x" schema="" table="tt4x" ctx=Select +ALIAS: "t1"="tt4x" +ALIAS: "t2"="tt4x" +ALIAS: "t3"="tt4x" +ALIAS: "t4"="tt4x" +ALIAS: "t5"="tt4x" +FILTER: schema="" table="t1" column="c1" +FILTER: schema="" table="t2" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tt4x t1 WHERE NOT EXISTS (SELECT 1 FROM tt4x t2 LEFT JOIN tt4x ..." +== 232 +-- truncate_limit: 100 +|-- +-- regression test for problems of the sort depicted in bug #3494 +|-- + +create temp table tt5(f1 int, f2 int) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt5 (f1 int, f2 int)" +== 233 +-- truncate_limit: 100 +create temp table tt6(f1 int, f2 int) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt6 (f1 int, f2 int)" +== 234 +-- truncate_limit: 100 +insert into tt5 values(1, 10) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt5 VALUES (1, 10)" +== 235 +-- truncate_limit: 100 +insert into tt5 values(1, 11) +-- +TABLE: name="tt5" schema="" table="tt5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt5 VALUES (1, 11)" +== 236 +-- truncate_limit: 100 +insert into tt6 values(1, 9) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt6 VALUES (1, 9)" +== 237 +-- truncate_limit: 100 +insert into tt6 values(1, 2) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt6 VALUES (1, 2)" +== 238 +-- truncate_limit: 100 +insert into tt6 values(2, 9) +-- +TABLE: name="tt6" schema="" table="tt6" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt6 VALUES (2, 9)" +== 239 +-- truncate_limit: 100 +select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2 +-- +TABLE: name="tt5" schema="" table="tt5" ctx=Select +TABLE: name="tt6" schema="" table="tt6" ctx=Select +FILTER: schema="" table="tt5" column="f1" +FILTER: schema="" table="tt6" column="f1" +FILTER: schema="" table="tt5" column="f1" +FILTER: schema="" table="tt5" column="f2" +FILTER: schema="" table="tt6" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt5, tt6 WHERE tt5.f1 = tt6.f1 AND tt5.f1 = (tt5.f2 - tt6.f2)" +== 240 +-- truncate_limit: 100 +|-- +-- regression test for problems of the sort depicted in bug #3588 +|-- + +create temp table xx (pkxx int) +-- +TABLE: name="xx" schema="" table="xx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE xx (pkxx int)" +== 241 +-- truncate_limit: 100 +create temp table yy (pkyy int, pkxx int) +-- +TABLE: name="yy" schema="" table="yy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE yy (pkyy int, pkxx int)" +== 242 +-- truncate_limit: 100 +insert into xx values (1) +-- +TABLE: name="xx" schema="" table="xx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xx VALUES (1)" +== 243 +-- truncate_limit: 100 +insert into xx values (2) +-- +TABLE: name="xx" schema="" table="xx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xx VALUES (2)" +== 244 +-- truncate_limit: 100 +insert into xx values (3) +-- +TABLE: name="xx" schema="" table="xx" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xx VALUES (3)" +== 245 +-- truncate_limit: 100 +insert into yy values (101, 1) +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO yy VALUES (101, 1)" +== 246 +-- truncate_limit: 100 +insert into yy values (201, 2) +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO yy VALUES (201, 2)" +== 247 +-- truncate_limit: 100 +insert into yy values (301, NULL) +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO yy VALUES (301, NULL)" +== 248 +-- truncate_limit: 100 +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 +-- +TABLE: name="yy" schema="" table="yy" ctx=Select +TABLE: name="xx" schema="" table="xx" ctx=Select +TABLE: name="xx" schema="" table="xx" ctx=Select +TABLE: name="yy" schema="" table="yy" ctx=Select +ALIAS: "xxa"="xx" +ALIAS: "xxb"="xx" +FILTER: schema="" table="" column="pkyy" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM yy LEFT JOIN (SELECT * FROM yy WHERE ...) yya ON yy.pkyy = yya.pkyy LEFT JOIN xx ..." +== 249 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="zt1" schema="" table="zt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE zt1 (f1 int PRIMARY KEY)" +== 250 +-- truncate_limit: 100 +create temp table zt2 (f2 int primary key) +-- +TABLE: name="zt2" schema="" table="zt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE zt2 (f2 int PRIMARY KEY)" +== 251 +-- truncate_limit: 100 +create temp table zt3 (f3 int primary key) +-- +TABLE: name="zt3" schema="" table="zt3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE zt3 (f3 int PRIMARY KEY)" +== 252 +-- truncate_limit: 100 +insert into zt1 values(53) +-- +TABLE: name="zt1" schema="" table="zt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO zt1 VALUES (53)" +== 253 +-- truncate_limit: 100 +insert into zt2 values(53) +-- +TABLE: name="zt2" schema="" table="zt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO zt2 VALUES (53)" +== 254 +-- truncate_limit: 100 +select * from + zt2 left join zt3 on (f2 = f3) + left join zt1 on (f3 = f1) +where f2 = 53 +-- +TABLE: name="zt2" schema="" table="zt2" ctx=Select +TABLE: name="zt3" schema="" table="zt3" ctx=Select +TABLE: name="zt1" schema="" table="zt1" ctx=Select +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM zt2 LEFT JOIN zt3 ON f2 = f3 LEFT JOIN zt1 ON f3 = f1 WHERE f2 = 53" +== 255 +-- truncate_limit: 100 +create temp view zv1 as select *,'dummy'::text AS junk from zt1 +-- +TABLE: name="zv1" schema="" table="zv1" ctx=DDL +TABLE: name="zt1" schema="" table="zt1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW zv1 AS SELECT *, 'dummy'::text AS junk FROM zt1" +== 256 +-- truncate_limit: 100 +select * from + zt2 left join zt3 on (f2 = f3) + left join zv1 on (f3 = f1) +where f2 = 53 +-- +TABLE: name="zt2" schema="" table="zt2" ctx=Select +TABLE: name="zt3" schema="" table="zt3" ctx=Select +TABLE: name="zv1" schema="" table="zv1" ctx=Select +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM zt2 LEFT JOIN zt3 ON f2 = f3 LEFT JOIN zv1 ON f3 = f1 WHERE f2 = 53" +== 257 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +FILTER: schema="" table="a" column="ten" +FILTER: schema="" table="b" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 a LEFT JOIN tenk1 b ON a.unique2 = b.tenthous WHERE ..." +== 258 +-- truncate_limit: 100 +|-- +-- 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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="c" column="thousand" +FILTER: schema="" table="b" column="unique2" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE foo(bool) AS SELECT count(*) FROM tenk1 a LEFT JOIN tenk1 b ON a.unique2 = b.unique1 AND ..." +== 259 +-- truncate_limit: 100 +execute foo(true) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo(true)" +== 260 +-- truncate_limit: 100 +execute foo(false) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo(false)" +== 261 +-- truncate_limit: 100 +|-- +-- test for sane behavior with noncanonical merge clauses, per bug #4926 +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 262 +-- truncate_limit: 100 +set enable_mergejoin = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO 1" +== 263 +-- truncate_limit: 100 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO 0" +== 264 +-- truncate_limit: 100 +set enable_nestloop = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO 0" +== 265 +-- truncate_limit: 100 +create temp table a (i integer) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE a (i int)" +== 266 +-- truncate_limit: 100 +create temp table b (x integer, y integer) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE b (x int, y int)" +== 267 +-- truncate_limit: 100 +select * from a left join b on i = x and i = y and x = i +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM a LEFT JOIN b ON i = x AND i = y AND x = i" +== 268 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 269 +-- truncate_limit: 100 +|-- +-- test handling of merge clauses using record_ops +|-- +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 270 +-- truncate_limit: 100 +create type mycomptype as (id int, v bigint) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE mycomptype AS (id int, v bigint)" +== 271 +-- truncate_limit: 100 +create temp table tidv (idv mycomptype) +-- +TABLE: name="tidv" schema="" table="tidv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tidv (idv mycomptype)" +== 272 +-- truncate_limit: 100 +create index on tidv (idv) +-- +TABLE: name="tidv" schema="" table="tidv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON tidv USING btree (idv)" +== 273 +-- truncate_limit: 100 +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv +-- +TABLE: name="tidv" schema="" table="tidv" ctx=Select +TABLE: name="tidv" schema="" table="tidv" ctx=Select +ALIAS: "a"="tidv" +ALIAS: "b"="tidv" +FILTER: schema="" table="a" column="idv" +FILTER: schema="" table="b" column="idv" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.idv, b.idv FROM tidv a, tidv b WHERE a.idv = b.idv" +== 274 +-- truncate_limit: 100 +set enable_mergejoin = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO 0" +== 275 +-- truncate_limit: 100 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO 0" +== 276 +-- truncate_limit: 100 +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv +-- +TABLE: name="tidv" schema="" table="tidv" ctx=Select +TABLE: name="tidv" schema="" table="tidv" ctx=Select +ALIAS: "a"="tidv" +ALIAS: "b"="tidv" +FILTER: schema="" table="a" column="idv" +FILTER: schema="" table="b" column="idv" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.idv, b.idv FROM tidv a, tidv b WHERE a.idv = b.idv" +== 277 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 278 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl t1 LEFT JOIN int8_tbl t2 ON t1.q2 = t2.q1 GROUP BY t1.q2 ORDER BY 1" +== 279 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl t1 LEFT JOIN (SELECT * FROM int8_tbl) t2 ON t1.q2 = t2.q1 GROUP BY t1.q2..." +== 280 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl t1 LEFT JOIN (SELECT * FROM int8_tbl OFFSET 0) t2 ON t1.q2 = t2.q1 GROUP..." +== 281 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl t1 LEFT JOIN (SELECT ... FROM int8_tbl) t2 ON t1.q2 = t2.q1 GROUP BY t1...." +== 282 +-- truncate_limit: 100 +|-- +-- test incorrect failure to NULL pulled-up subexpressions +|-- +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 283 +-- truncate_limit: 100 +create temp table a ( + code char not null, + constraint a_pk primary key (code) +) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE a (code char(1) NOT NULL, CONSTRAINT a_pk PRIMARY KEY (code))" +== 284 +-- truncate_limit: 100 +create temp table b ( + a char not null, + num integer not null, + constraint b_pk primary key (a, num) +) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE b (a char(1) NOT NULL, num int NOT NULL, CONSTRAINT b_pk PRIMARY KEY (a, n..." +== 285 +-- truncate_limit: 100 +create temp table c ( + name char not null, + a char, + constraint c_pk primary key (name) +) +-- +TABLE: name="c" schema="" table="c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE c (name char(1) NOT NULL, a char(1), CONSTRAINT c_pk PRIMARY KEY (name))" +== 286 +-- truncate_limit: 100 +insert into a (code) values ('p') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (code) VALUES ('p')" +== 287 +-- truncate_limit: 100 +insert into a (code) values ('q') +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a (code) VALUES ('q')" +== 288 +-- truncate_limit: 100 +insert into b (a, num) values ('p', 1) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (a, num) VALUES ('p', 1)" +== 289 +-- truncate_limit: 100 +insert into b (a, num) values ('p', 2) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b (a, num) VALUES ('p', 2)" +== 290 +-- truncate_limit: 100 +insert into c (name, a) values ('A', 'p') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (name, a) VALUES ('A', 'p')" +== 291 +-- truncate_limit: 100 +insert into c (name, a) values ('B', 'q') +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (name, a) VALUES ('B', 'q')" +== 292 +-- truncate_limit: 100 +insert into c (name, a) values ('C', null) +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c (name, a) VALUES ('C', NULL)" +== 293 +-- truncate_limit: 100 +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 +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM c LEFT JOIN (SELECT ... FROM a LEFT JOIN (SELECT ... FROM b GROUP BY b.a) b_grp O..." +== 294 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 295 +-- truncate_limit: 100 +|-- +-- 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 +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ...) sub1 LEFT JOIN (SELECT ... FROM (SELECT ...) sub3 LEFT JOIN (SELECT ....." +== 296 +-- truncate_limit: 100 +-- 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 +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ...) sub1 LEFT JOIN (SELECT ... FROM (SELECT ...) sub3 LEFT JOIN (SELECT ....." +== 297 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT qq, unique1 FROM (SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a) ss1 FU..." +== 298 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="tenk1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM int8_tbl a) ss1 FULL JOIN (SELECT ... FROM int8_tbl b) ss2 USING..." +== 299 +-- truncate_limit: 100 +|-- +-- nested nestloops can require nested PlaceHolderVars +|-- + +create temp table nt1 ( + id int primary key, + a1 boolean, + a2 boolean +) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE nt1 (id int PRIMARY KEY, a1 boolean, a2 boolean)" +== 300 +-- truncate_limit: 100 +create temp table nt2 ( + id int primary key, + nt1_id int, + b1 boolean, + b2 boolean, + foreign key (nt1_id) references nt1(id) +) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE nt2 (id int PRIMARY KEY, nt1_id int, b1 boolean, b2 boolean, FOREIGN KEY (..." +== 301 +-- truncate_limit: 100 +create temp table nt3 ( + id int primary key, + nt2_id int, + c1 boolean, + foreign key (nt2_id) references nt2(id) +) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE nt3 (id int PRIMARY KEY, nt2_id int, c1 boolean, FOREIGN KEY (nt2_id) REFE..." +== 302 +-- truncate_limit: 100 +insert into nt1 values (1,true,true) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt1 VALUES (1, true, true)" +== 303 +-- truncate_limit: 100 +insert into nt1 values (2,true,false) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt1 VALUES (2, true, false)" +== 304 +-- truncate_limit: 100 +insert into nt1 values (3,false,false) +-- +TABLE: name="nt1" schema="" table="nt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt1 VALUES (3, false, false)" +== 305 +-- truncate_limit: 100 +insert into nt2 values (1,1,true,true) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt2 VALUES (1, 1, true, true)" +== 306 +-- truncate_limit: 100 +insert into nt2 values (2,2,true,false) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt2 VALUES (2, 2, true, false)" +== 307 +-- truncate_limit: 100 +insert into nt2 values (3,3,false,false) +-- +TABLE: name="nt2" schema="" table="nt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt2 VALUES (3, 3, false, false)" +== 308 +-- truncate_limit: 100 +insert into nt3 values (1,1,true) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt3 VALUES (1, 1, true)" +== 309 +-- truncate_limit: 100 +insert into nt3 values (2,2,false) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt3 VALUES (2, 2, false)" +== 310 +-- truncate_limit: 100 +insert into nt3 values (3,3,true) +-- +TABLE: name="nt3" schema="" table="nt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nt3 VALUES (3, 3, true)" +== 311 +-- truncate_limit: 100 +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 +-- +TABLE: name="nt3" schema="" table="nt3" ctx=Select +TABLE: name="nt2" schema="" table="nt2" ctx=Select +TABLE: name="nt1" schema="" table="nt1" ctx=Select +ALIAS: "nt2"="nt2" +ALIAS: "nt3"="nt3" +FILTER: schema="" table="nt3" column="id" +FILTER: schema="" table="ss2" column="b3" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT nt3.id FROM nt3 nt3 LEFT JOIN (SELECT nt2.*, nt2.b1 AND ss1.a3 AS b3 F..." +== 312 +-- truncate_limit: 100 +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 +-- +TABLE: name="nt3" schema="" table="nt3" ctx=Select +TABLE: name="nt2" schema="" table="nt2" ctx=Select +TABLE: name="nt1" schema="" table="nt1" ctx=Select +ALIAS: "nt2"="nt2" +ALIAS: "nt3"="nt3" +FILTER: schema="" table="nt3" column="id" +FILTER: schema="" table="ss2" column="b3" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM nt3 nt3 LEFT JOIN (SELECT ... FROM nt2 nt2 LEFT JOIN (SELECT ... FROM nt1) ss1 ON..." +== 313 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="ss" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN (SELECT q1 AS x, 42 AS y FROM int8_tbl t2..." +== 314 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="ss" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl t1 LEFT JOIN (SELECT ... FROM int8_tbl t2) ss ON t1.q2 = ss.x WHERE ... OR..." +== 315 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i81"="int8_tbl" +FILTER: schema="" table="i41" column="f1" +FILTER: schema="" table="ss1" column="loc" +FILTER: schema="" table="ss1" column="lat" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl i41, LATERAL (SELECT 1 AS x FROM (SELECT i41.f1 AS lat..." +== 316 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i81"="int8_tbl" +FILTER: schema="" table="i41" column="f1" +FILTER: schema="" table="ss1" column="loc" +FILTER: schema="" table="ss1" column="lat" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl i41, LATERAL (SELECT ... FROM (SELECT ... FROM int8_tbl i81, int4_tbl i42)..." +== 317 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl a FULL JOIN int4_tbl b ON true" +== 318 +-- truncate_limit: 100 +select * from int4_tbl a full join int4_tbl b on false +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl a FULL JOIN int4_tbl b ON false" +== 319 +-- truncate_limit: 100 +|-- +-- test for ability to use a cartesian join when necessary +|-- + +create temp table q1 as select 1 as q1 +-- +TABLE: name="q1" schema="" table="q1" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE q1 AS SELECT 1 AS q1" +== 320 +-- truncate_limit: 100 +create temp table q2 as select 0 as q2 +-- +TABLE: name="q2" schema="" table="q2" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE q2 AS SELECT 0 AS q2" +== 321 +-- truncate_limit: 100 +analyze q1 +-- +TABLE: name="q1" schema="" table="q1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE q1" +== 322 +-- truncate_limit: 100 +analyze q2 +-- +TABLE: name="q2" schema="" table="q2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE q2" +== 323 +-- truncate_limit: 100 +explain (costs off) +select * from + tenk1 join int4_tbl on f1 = twothousand, + q1, q2 +where q1 = thousand or q2 = thousand +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +TABLE: name="q2" schema="" table="q2" ctx=Select +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 JOIN int4_tbl ON f1 = twothousand, q1, q2 WHERE q1 = thou..." +== 324 +-- truncate_limit: 100 +explain (costs off) +select * from + tenk1 join int4_tbl on f1 = twothousand, + q1, q2 +where thousand = (q1 + q2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +TABLE: name="q2" schema="" table="q2" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 JOIN int4_tbl ON f1 = twothousand, q1, q2 WHERE thousand ..." +== 325 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="a" column="q1" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="b" column="q1" +FILTER: schema="" table="a" column="q2" +FILTER: schema="" table="b" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1, int8_tbl a, int8_tbl b WHERE thousand = a.q1 AND tenthou..." +== 326 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 FROM tenk1 t1 JOIN (i..." +== 327 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1 JOIN (int4_tbl i1 LEFT JOIN (SELECT ... FROM (SELECT ... FROM onerow) v1..." +== 328 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="i4" column="f1" +FILTER: schema="" table="t3" column="fivethous" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1 JOIN tenk1 t2 ON t1.tenthous = t2.ten JOIN (int8_tbl i8 LEFT JOIN (int4_..." +== 329 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 FROM tenk1 t1 JOIN (i..." +== 330 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="t1" column="unique2" +FILTER: schema="" table="t1" column="stringu1" +FILTER: schema="" table="t2" column="stringu2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1 JOIN (int4_tbl i1 LEFT JOIN (SELECT ... FROM (VALUES (...)) v1(x1, x2) L..." +== 331 +-- truncate_limit: 100 +-- 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 +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT 1 AS x) ss1 LEFT JOIN (SELECT 2 AS y) ss2 ON t..." +== 332 +-- truncate_limit: 100 +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 +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ...) ss1 LEFT JOIN (SELECT ...) ss2 ON true, LATERAL (SELECT ... LIMIT 1) ss3" +== 333 +-- truncate_limit: 100 +-- 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 +-- +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT 0 AS z) t1 LEFT JOIN (SELECT true AS a) t2 ON true, LAT..." +== 334 +-- truncate_limit: 100 +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 +-- +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ...) t1 LEFT JOIN (SELECT ...) t2 ON true, LATERAL (SELECT ... UNION ALL SE..." +== 335 +-- truncate_limit: 100 +-- Test PHV in a semijoin qual, which confused useless-RTE removal (bug #17700) +explain (verbose, costs off) +with ctetable as not materialized ( select 1 as f1 ) +select * from ctetable c1 +where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ) +-- +ALIAS: "c1"="ctetable" +ALIAS: "c2"="ctetable" +ALIAS: "c3"="ctetable" +CTE: "ctetable" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH ctetable AS NOT MATERIALIZED (SELECT 1 AS f1) SELECT * FROM cte..." +== 336 +-- truncate_limit: 100 +with ctetable as not materialized ( select 1 as f1 ) +select * from ctetable c1 +where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ) +-- +ALIAS: "c1"="ctetable" +ALIAS: "c2"="ctetable" +ALIAS: "c3"="ctetable" +CTE: "ctetable" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "WITH ctetable AS NOT MATERIALIZED (...) SELECT * FROM ctetable c1 WHERE ..." +== 337 +-- truncate_limit: 100 +-- Test PHV that winds up in a Result node, despite having nonempty nullingrels +explain (verbose, costs off) +select table_catalog, table_name +from int4_tbl t1 + inner join (int8_tbl t2 + left join information_schema.column_udt_usage on null) + on null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="information_schema.column_udt_usage" schema="information_schema" table="column_udt_usage" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT table_catalog, table_name FROM int4_tbl t1 JOIN (int8_tbl t2 ..." +== 338 +-- truncate_limit: 100 +-- Test handling of qual pushdown to appendrel members with non-Var outputs +explain (verbose, costs off) +select * from int4_tbl left join ( + select text 'foo' union all select text 'bar' +) ss(x) on true +where ss.x is null +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="ss" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl LEFT JOIN (SELECT 'foo'::text UNION ALL SELEC..." +== 339 +-- truncate_limit: 100 +|-- +-- test inlining of immutable functions +|-- +create function f_immutable_int4(i integer) returns integer as +$$ begin return i; end; $$ language plpgsql immutable +-- +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f_immutable_int4(i int) RETURNS int AS $$ begin return i; end; $$ LANGUAGE plpgsq..." +== 340 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1, (SELECT * FROM f_immutable_int4(1) x) x WHERE x = ..." +== 341 +-- truncate_limit: 100 +explain (verbose, costs off) +select unique1, x.* +from tenk1, (select *, random() from f_immutable_int4(1) x) x +where x = unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT unique1, x.* FROM tenk1, (SELECT *, random() FROM f_immutable..." +== 342 +-- truncate_limit: 100 +explain (costs off) +select unique1 from tenk1, f_immutable_int4(1) x where x = unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1, f_immutable_int4(1) x WHERE x = unique1" +== 343 +-- truncate_limit: 100 +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1, LATERAL f_immutable_int4(1) x WHERE x = unique1" +== 344 +-- truncate_limit: 100 +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1, LATERAL f_immutable_int4(1) x WHERE x IN (SELECT 17)" +== 345 +-- truncate_limit: 100 +explain (costs off) +select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, x FROM tenk1 JOIN f_immutable_int4(1) x ON unique1 = x" +== 346 +-- truncate_limit: 100 +explain (costs off) +select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, x FROM tenk1 LEFT JOIN f_immutable_int4(1) x ON unique1 = x" +== 347 +-- truncate_limit: 100 +explain (costs off) +select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, x FROM tenk1 RIGHT JOIN f_immutable_int4(1) x ON unique1 = x" +== 348 +-- truncate_limit: 100 +explain (costs off) +select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, x FROM tenk1 FULL JOIN f_immutable_int4(1) x ON unique1 = x" +== 349 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1, f_immutable_int4(1) x WHERE x = 42" +== 350 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="nt3" schema="" table="nt3" ctx=Select +TABLE: name="nt2" schema="" table="nt2" ctx=Select +ALIAS: "nt2"="nt2" +ALIAS: "nt3"="nt3" +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=Call +FILTER: schema="" table="nt3" column="id" +FILTER: schema="" table="ss2" column="b3" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT nt3.id FROM nt3 nt3 LEFT JOIN (SELECT nt2.*, nt2.b1 OR i4 = 42 AS b3 F..." +== 351 +-- truncate_limit: 100 +drop function f_immutable_int4(int) +-- +FUNCTION: name="f_immutable_int4" function="f_immutable_int4" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f_immutable_int4(int)" +== 352 +-- truncate_limit: 100 +-- test inlining when function returns composite + +create function mki8(bigint, bigint) returns int8_tbl as +$$select row($1,$2)::int8_tbl$$ language sql +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mki8(bigint, bigint) RETURNS int8_tbl AS $$select row($1,$2)::int8_tbl$$ LANGUAGE..." +== 353 +-- truncate_limit: 100 +create function mki4(int) returns int4_tbl as +$$select row($1)::int4_tbl$$ language sql +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mki4(int) RETURNS int4_tbl AS $$select row($1)::int4_tbl$$ LANGUAGE sql" +== 354 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from mki8(1,2) +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM mki8(1, 2)" +== 355 +-- truncate_limit: 100 +select * from mki8(1,2) +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mki8(1, 2)" +== 356 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from mki4(42) +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM mki4(42)" +== 357 +-- truncate_limit: 100 +select * from mki4(42) +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mki4(42)" +== 358 +-- truncate_limit: 100 +drop function mki8(bigint, bigint) +-- +FUNCTION: name="mki8" function="mki8" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION mki8(bigint, bigint)" +== 359 +-- truncate_limit: 100 +drop function mki4(int) +-- +FUNCTION: name="mki4" function="mki4" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION mki4(int)" +== 360 +-- truncate_limit: 100 +-- test const-folding of a whole-row Var into a per-field Var +-- (need to inline a function to reach this case, else parser does it) +create function f_field_select(t onek) returns int4 as +$$ select t.unique2; $$ language sql immutable +-- +FUNCTION: name="f_field_select" function="f_field_select" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f_field_select(t onek) RETURNS int4 AS $$ select t.unique2; $$ LANGUAGE sql IMMUT..." +== 361 +-- truncate_limit: 100 +explain (verbose, costs off) +select (t2.*).unique1, f_field_select(t2) from tenk1 t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join int8_tbl t3 on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="onek" +ALIAS: "t3"="int8_tbl" +FUNCTION: name="f_field_select" function="f_field_select" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT (t2.*).unique1, f_field_select(t2) FROM tenk1 t1 LEFT JOIN on..." +== 362 +-- truncate_limit: 100 +drop function f_field_select(t onek) +-- +FUNCTION: name="f_field_select" function="f_field_select" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f_field_select(t onek)" +== 363 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN tenk1 b ON (a.unique1 = 1 AND b.unique1 = 2) OR (a..." +== 364 +-- truncate_limit: 100 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN tenk1 b ON (a.unique1 = 1 AND b.unique1 = 2) OR (a..." +== 365 +-- truncate_limit: 100 +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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN tenk1 b ON (a.unique1 = 1 AND b.unique1 = 2) OR ((..." +== 366 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FILTER: schema="" table="t1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 t1 LEFT JOIN (tenk1 t2 JOIN tenk1 t3 ON t2.thousand = t3...." +== 367 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FILTER: schema="" table="t1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 t1 LEFT JOIN (tenk1 t2 JOIN tenk1 t3 ON t2.thousand = t3...." +== 368 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique2 LEFT JOIN ..." +== 369 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique2 LEFT JOIN tenk1 c ON a.unique2 = b...." +== 370 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b.unique1 FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique2 LEFT JOIN..." +== 371 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique2 LEFT JOIN tenk1 c ON b.unique1 = 42..." +== 372 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fault" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT unique1, q1, COALESCE(unique1, -1) + q1 AS fault FROM i..." +== 373 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fault" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM int8_tbl LEFT JOIN tenk1 ON q2 = unique2) ss WHERE ... ORDER BY fault" +== 374 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (VALUES (1, ARRAY[10, 20]), (2, ARRAY[20, 30])) v1(v1x, v1ys) L..." +== 375 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v1(v1x, v1ys) LEFT JOIN (VALUES (...)) v2(v2x, v2y) ON v2x = v1x LEF..." +== 376 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT q1, unique2, thousand, hundred FROM int8_tbl a LEFT JOIN tenk1 b ON q1..." +== 377 +-- truncate_limit: 100 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT q1, unique2, thousand, hundred FROM int8_tbl a LEFT JOIN tenk1 b ON q1 = unique2 WHERE ..." +== 378 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT f1, unique2, CASE WHEN unique2 IS NULL THEN f1 ELSE 0 END FROM int4_tb..." +== 379 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int4_tbl a LEFT JOIN tenk1 b ON f1 = unique2 WHERE ..." +== 380 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FILTER: schema="" table="a" column="unique2" +FILTER: schema="" table="b" column="twothousand" +FILTER: schema="" table="a" column="twothousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.unique1, b.unique1, c.unique1, COALESCE(b.twothousand, a.twothousand..." +== 381 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +FILTER: schema="" table="a" column="unique2" +FILTER: schema="" table="b" column="twothousand" +FILTER: schema="" table="a" column="twothousand" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 a LEFT JOIN tenk1 b ON b.thousand = a.unique1 LEFT JOIN tenk1 c ON c.unique..." +== 382 +-- truncate_limit: 100 +-- related case + +explain (costs off) +select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, + lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="t2" column="q1" +FILTER: schema="" table="t2" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN int8_tbl t2 ON t1.q2 = t2.q1, LATERAL (SE..." +== 383 +-- truncate_limit: 100 +select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, + lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FILTER: schema="" table="t2" column="q1" +FILTER: schema="" table="t2" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl t1 LEFT JOIN int8_tbl t2 ON t1.q2 = t2.q1, LATERAL (SELECT * FROM int8_tbl..." +== 384 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT foo1.join_key AS foo1_id, foo3.join_key AS foo3_id, bug_field..." +== 385 +-- truncate_limit: 100 +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) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="tenk1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) foo1(join_key) LEFT JOIN (SELECT ... FROM (SELECT ... FROM (SELECT..." +== 386 +-- truncate_limit: 100 +|-- +-- check handling of a variable-free join alias +|-- +explain (verbose, costs off) +select * from +int4_tbl i0 left join +( (select *, 123 as x from int4_tbl i1) ss1 + left join + (select *, q2 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on (i0.f1 = ss0.f1) +order by i0.f1, x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i0"="int4_tbl" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl i0 LEFT JOIN ((SELECT *, 123 AS x FROM int4_t..." +== 387 +-- truncate_limit: 100 +select * from +int4_tbl i0 left join +( (select *, 123 as x from int4_tbl i1) ss1 + left join + (select *, q2 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on (i0.f1 = ss0.f1) +order by i0.f1, x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i0"="int4_tbl" +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl i0 LEFT JOIN ((SELECT ... FROM int4_tbl i1) ss1 LEFT JOIN (SELECT ... FROM..." +== 388 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.* FROM text_tbl t1 LEFT JOIN ((SELECT *, '***'::text AS d1..." +== 389 +-- truncate_limit: 100 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM text_tbl t1 LEFT JOIN ((SELECT ... FROM int8_tbl i8b1) b1 LEFT JOIN (int8_tbl i8 ..." +== 390 +-- truncate_limit: 100 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.* FROM text_tbl t1 LEFT JOIN ((SELECT *, '***'::text AS d1..." +== 391 +-- truncate_limit: 100 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM text_tbl t1 LEFT JOIN ((SELECT ... FROM int8_tbl i8b1) b1 LEFT JOIN (int8_tbl i8 ..." +== 392 +-- truncate_limit: 100 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.* FROM text_tbl t1 LEFT JOIN ((SELECT *, '***'::text AS d1..." +== 393 +-- truncate_limit: 100 +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) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i4b2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "i8b1"="int8_tbl" +ALIAS: "i8b2"="int8_tbl" +ALIAS: "t1"="text_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM text_tbl t1 LEFT JOIN ((SELECT ... FROM int8_tbl i8b1) b1 LEFT JOIN (int8_tbl i8 ..." +== 394 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM text_tbl t1 JOIN int8_tbl i8 ON i8.q2 = 456 RIGHT JOIN..." +== 395 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM text_tbl t1 JOIN int8_tbl i8 ON i8.q2 = 456 RIGHT JOIN text_tbl t2 ON t1.f1 = 'doh!..." +== 396 +-- truncate_limit: 100 +-- check handling of a variable-free qual for a non-commutable outer join +explain (costs off) +select nspname +from (select 1 as x) ss1 +left join +( select n.nspname, c.relname + from pg_class c left join pg_namespace n on n.oid = c.relnamespace + where c.relkind = 'r' +) ss2 on false +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "n"="pg_namespace" +FILTER: schema="" table="c" column="relkind" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT nspname FROM (SELECT 1 AS x) ss1 LEFT JOIN (SELECT n.nspname, c.relnam..." +== 397 +-- truncate_limit: 100 +-- check handling of apparently-commutable outer joins with non-commutable +-- joins between them +explain (costs off) +select 1 from + int4_tbl i4 + left join int8_tbl i8 on i4.f1 is not null + left join (select 1 as a) ss1 on null + join int4_tbl i42 on ss1.a is null or i8.q1 <> i8.q2 + right join (select 2 as b) ss2 + on ss2.b < i4.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM int4_tbl i4 LEFT JOIN int8_tbl i8 ON i4.f1 IS NOT NULL LEFT JOI..." +== 398 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM text_tbl t1 LEFT JOIN int8_tbl i8 ON i8.q2 = 123, LATE..." +== 399 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM text_tbl t1 LEFT JOIN int8_tbl i8 ON i8.q2 = 123, LATERAL (SELECT ... FROM text_tbl..." +== 400 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +ALIAS: "t3"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss2" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM text_tbl t1 LEFT JOIN int8_tbl i8 ON i8.q2 = 123, LATE..." +== 401 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="text_tbl" +ALIAS: "t2"="text_tbl" +ALIAS: "t3"="text_tbl" +FILTER: schema="" table="t1" column="f1" +FILTER: schema="" table="ss2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM text_tbl t1 LEFT JOIN int8_tbl i8 ON i8.q2 = 123, LATERAL (SELECT ... FROM text_tbl..." +== 402 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "tt1"="text_tbl" +ALIAS: "tt2"="text_tbl" +ALIAS: "tt3"="text_tbl" +ALIAS: "tt4"="text_tbl" +ALIAS: "tt5"="text_tbl" +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="ss1" column="c0" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 FROM text_tbl tt1 JOIN text_tbl tt2 ON tt1.f1 = 'foo' LEFT ..." +== 403 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "tt1"="text_tbl" +ALIAS: "tt2"="text_tbl" +ALIAS: "tt3"="text_tbl" +ALIAS: "tt4"="text_tbl" +ALIAS: "tt5"="text_tbl" +FILTER: schema="" table="tt1" column="f1" +FILTER: schema="" table="ss1" column="c0" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM text_tbl tt1 JOIN text_tbl tt2 ON tt1.f1 = 'foo' LEFT JOIN text_tbl tt3 ON tt3.f1 =..." +== 404 +-- truncate_limit: 100 +explain (verbose, costs off) +select 1 from + int4_tbl as i4 + inner join + ((select 42 as n from int4_tbl x1 left join int8_tbl x2 on f1 = q1) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "x1"="int4_tbl" +ALIAS: "x2"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 FROM int4_tbl i4 JOIN ((SELECT 42 AS n FROM int4_tbl x1 LEF..." +== 405 +-- truncate_limit: 100 +select 1 from + int4_tbl as i4 + inner join + ((select 42 as n from int4_tbl x1 left join int8_tbl x2 on f1 = q1) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "x1"="int4_tbl" +ALIAS: "x2"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM int4_tbl i4 JOIN ((SELECT ... FROM int4_tbl x1 LEFT JOIN int8_tbl x2 ON f1 = q1) ss..." +== 406 +-- truncate_limit: 100 +|-- +-- check a case where we formerly generated invalid parameterized paths +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 407 +-- truncate_limit: 100 +create temp table t (a int unique) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t (a int UNIQUE)" +== 408 +-- truncate_limit: 100 +explain (costs off) +select 1 from t t1 + join lateral (select t1.a from (select 1) foo offset 0) as s1 on true + join + (select 1 from t t2 + inner join (t t3 + left join (t t4 left join t t5 on t4.a = 1) + on t3.a = t4.a) + on false + where t3.a = coalesce(t5.a,1)) as s2 + on true +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +ALIAS: "t5"="t" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t5" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM t t1 JOIN LATERAL (SELECT t1.a FROM (SELECT 1) foo OFFSET 0) s1..." +== 409 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 410 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="ss1" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT ss2.* FROM int4_tbl i41 LEFT JOIN (int8_tbl i8 JOIN (SELECT i..." +== 411 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +ALIAS: "i41"="int4_tbl" +ALIAS: "i42"="int4_tbl" +ALIAS: "i43"="int4_tbl" +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="ss1" column="c2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int4_tbl i41 LEFT JOIN (int8_tbl i8 JOIN (SELECT ... FROM int4_tbl i42, int4_tbl ..." +== 412 +-- truncate_limit: 100 +|-- +-- 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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a1"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT 1 AS id) xx LEFT JOIN (tenk1 a1 FULL JOIN (SELECT 1 AS ..." +== 413 +-- truncate_limit: 100 +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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a1"="tenk1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ...) xx LEFT JOIN (tenk1 a1 FULL JOIN (SELECT ...) yy ON a1.unique1 = yy.id..." +== 414 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl a LEFT JOIN tenk1 b ON f1 = unique2 WHERE f1 = 0" +== 415 +-- truncate_limit: 100 +explain (costs off) + select * from tenk1 a full join tenk1 b using(unique2) where unique2 = 42 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a FULL JOIN tenk1 b USING (unique2) WHERE unique2 = 42" +== 416 +-- truncate_limit: 100 +|-- +-- 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 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 417 +-- truncate_limit: 100 +set enable_nestloop to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 418 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="b" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT a.q2, b.q1 FROM int8_tbl a LEFT JOIN int8_tbl b ON a.q2 = COA..." +== 419 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="b" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT a.q2, b.q1 FROM int8_tbl a LEFT JOIN int8_tbl b ON a.q2 = COALESCE(b.q1, 1) WHERE ..." +== 420 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 421 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 422 +-- truncate_limit: 100 +|-- +-- test join strength reduction with a SubPlan providing the proof +|-- + +explain (costs off) +select a.unique1, b.unique2 + from onek a left join onek b on a.unique1 = b.unique2 + where (b.unique2, random() > 0) = any (select q1, random() > 0 from int8_tbl c where c.q1 < b.unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +ALIAS: "c"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="b" column="unique2" +FILTER: schema="" table="c" column="q1" +FILTER: schema="" table="b" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.unique1, b.unique2 FROM onek a LEFT JOIN onek b ON a.unique1 = b.uni..." +== 423 +-- truncate_limit: 100 +select a.unique1, b.unique2 + from onek a left join onek b on a.unique1 = b.unique2 + where (b.unique2, random() > 0) = any (select q1, random() > 0 from int8_tbl c where c.q1 < b.unique1) +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +ALIAS: "c"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="b" column="unique2" +FILTER: schema="" table="c" column="q1" +FILTER: schema="" table="b" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT a.unique1, b.unique2 FROM onek a LEFT JOIN onek b ON a.unique1 = b.unique2 WHERE ..." +== 424 +-- truncate_limit: 100 +|-- +-- test full-join strength reduction +|-- + +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.unique1, b.unique2 FROM onek a FULL JOIN onek b ON a.unique1 = b.uni..." +== 425 +-- truncate_limit: 100 +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek a FULL JOIN onek b ON a.unique1 = b.unique2 WHERE a.unique1 = 42" +== 426 +-- truncate_limit: 100 +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.unique1, b.unique2 FROM onek a FULL JOIN onek b ON a.unique1 = b.uni..." +== 427 +-- truncate_limit: 100 +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek a FULL JOIN onek b ON a.unique1 = b.unique2 WHERE b.unique2 = 43" +== 428 +-- truncate_limit: 100 +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 and b.unique2 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.unique1, b.unique2 FROM onek a FULL JOIN onek b ON a.unique1 = b.uni..." +== 429 +-- truncate_limit: 100 +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42 and b.unique2 = 42 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "a"="onek" +ALIAS: "b"="onek" +FILTER: schema="" table="a" column="unique1" +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT a.unique1, b.unique2 FROM onek a FULL JOIN onek b ON a.unique1 = b.unique2 WHERE ..." +== 430 +-- truncate_limit: 100 +|-- +-- test result-RTE removal underneath a full join +|-- + +explain (costs off) +select * from + (select * from int8_tbl i81 join (values(123,2)) v(v1,v2) on q2=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on q2=v1) ss2 +on true +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM int8_tbl i81 JOIN (VALUES (123, 2)) v(v1, v2) ON..." +== 431 +-- truncate_limit: 100 +select * from + (select * from int8_tbl i81 join (values(123,2)) v(v1,v2) on q2=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on q2=v1) ss2 +on true +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM int8_tbl i81 JOIN (VALUES (...)) v(v1, v2) ON q2 = v1) ss1 FULL JOIN..." +== 432 +-- truncate_limit: 100 +|-- +-- test join removal +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 433 +-- truncate_limit: 100 +CREATE TEMP TABLE a (id int PRIMARY KEY, b_id int) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE a (id int PRIMARY KEY, b_id int)" +== 434 +-- truncate_limit: 100 +CREATE TEMP TABLE b (id int PRIMARY KEY, c_id int) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE b (id int PRIMARY KEY, c_id int)" +== 435 +-- truncate_limit: 100 +CREATE TEMP TABLE c (id int PRIMARY KEY) +-- +TABLE: name="c" schema="" table="c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE c (id int PRIMARY KEY)" +== 436 +-- truncate_limit: 100 +CREATE TEMP TABLE d (a int, b int) +-- +TABLE: name="d" schema="" table="d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE d (a int, b int)" +== 437 +-- truncate_limit: 100 +INSERT INTO a VALUES (0, 0), (1, NULL) +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a VALUES (0, 0), (1, NULL)" +== 438 +-- truncate_limit: 100 +INSERT INTO b VALUES (0, 0), (1, NULL) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b VALUES (0, 0), (1, NULL)" +== 439 +-- truncate_limit: 100 +INSERT INTO c VALUES (0), (1) +-- +TABLE: name="c" schema="" table="c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO c VALUES (0), (1)" +== 440 +-- truncate_limit: 100 +INSERT INTO d VALUES (1,3), (2,2), (3,1) +-- +TABLE: name="d" schema="" table="d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO d VALUES (1, 3), (2, 2), (3, 1)" +== 441 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id" +== 442 +-- truncate_limit: 100 +explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="c" schema="" table="c" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id" +== 443 +-- truncate_limit: 100 +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) +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="c" schema="" table="c" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "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" +== 444 +-- truncate_limit: 100 +-- 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 +) +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="c" schema="" table="c" ctx=Select +FILTER: schema="" table="" column="id" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT id FROM a WHERE id IN (SELECT b.id FROM b LEFT JOIN c ON b.id = c.id)" +== 445 +-- truncate_limit: 100 +-- check optimization with oddly-nested outer joins +explain (costs off) +select a1.id from + (a a1 left join a a2 on true) + left join + (a a3 left join a a4 on a3.id = a4.id) + on a2.id = a3.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "a1"="a" +ALIAS: "a2"="a" +ALIAS: "a3"="a" +ALIAS: "a4"="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a1.id FROM a a1 LEFT JOIN a a2 ON true LEFT JOIN (a a3 LEFT JOIN a a4 ..." +== 446 +-- truncate_limit: 100 +explain (costs off) +select a1.id from + (a a1 left join a a2 on a1.id = a2.id) + left join + (a a3 left join a a4 on a3.id = a4.id) + on a2.id = a3.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "a1"="a" +ALIAS: "a2"="a" +ALIAS: "a3"="a" +ALIAS: "a4"="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a1.id FROM a a1 LEFT JOIN a a2 ON a1.id = a2.id LEFT JOIN (a a3 LEFT J..." +== 447 +-- truncate_limit: 100 +explain (costs off) +select 1 from a t1 + left join a t2 on true + inner join a t3 on true + left join a t4 on t2.id = t4.id and t2.id = t3.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "t1"="a" +ALIAS: "t2"="a" +ALIAS: "t3"="a" +ALIAS: "t4"="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM a t1 LEFT JOIN a t2 ON true JOIN a t3 ON true LEFT JOIN a t4 ON..." +== 448 +-- truncate_limit: 100 +-- another example (bug #17781) +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select null as f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int8_tbl" +ALIAS: "t6"="int4_tbl" +ALIAS: "t7"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ss1.f1 FROM int4_tbl t1 LEFT JOIN (int4_tbl t2 RIGHT JOIN int4_tbl t3 ..." +== 449 +-- truncate_limit: 100 +-- variant with Var rather than PHV coming from t6 +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int8_tbl" +ALIAS: "t6"="int4_tbl" +ALIAS: "t7"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ss1.f1 FROM int4_tbl t1 LEFT JOIN (int4_tbl t2 RIGHT JOIN int4_tbl t3 ..." +== 450 +-- truncate_limit: 100 +-- per further discussion of bug #17781 +explain (costs off) +select ss1.x +from (select f1/2 as x from int4_tbl i4 left join a on a.id = i4.f1) ss1 + right join int8_tbl i8 on true +where current_user is not null +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ss1.x FROM (SELECT f1 / 2 AS x FROM int4_tbl i4 LEFT JOIN a ON a.id = ..." +== 451 +-- truncate_limit: 100 +-- this is to add a Result node + +-- and further discussion of bug #17781 +explain (costs off) +select * +from int8_tbl t1 + left join (int8_tbl t2 left join onek t3 on t2.q1 > t3.unique1) + on t1.q2 = t2.q2 + left join onek t4 + on t2.q2 < t3.unique2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="onek" +ALIAS: "t4"="onek" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN (int8_tbl t2 LEFT JOIN onek t3 ON t2.q1 >..." +== 452 +-- truncate_limit: 100 +-- More tests of correct placement of pseudoconstant quals + +-- simple constant-false condition +explain (costs off) +select * from int8_tbl t1 left join + (int8_tbl t2 inner join int8_tbl t3 on false + left join int8_tbl t4 on t2.q2 = t4.q2) +on t1.q1 = t2.q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN (int8_tbl t2 JOIN int8_tbl t3 ON false LE..." +== 453 +-- truncate_limit: 100 +-- deduce constant-false from an EquivalenceClass +explain (costs off) +select * from int8_tbl t1 left join + (int8_tbl t2 inner join int8_tbl t3 on (t2.q1-t3.q2) = 0 and (t2.q1-t3.q2) = 1 + left join int8_tbl t4 on t2.q2 = t4.q2) +on t1.q1 = t2.q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl t1 LEFT JOIN (int8_tbl t2 JOIN int8_tbl t3 ON (t2.q1 -..." +== 454 +-- truncate_limit: 100 +-- pseudoconstant based on an outer-level Param +explain (costs off) +select exists( + select * from int8_tbl t1 left join + (int8_tbl t2 inner join int8_tbl t3 on x0.f1 = 1 + left join int8_tbl t4 on t2.q2 = t4.q2) + on t1.q1 = t2.q1 +) from int4_tbl x0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +ALIAS: "t4"="int8_tbl" +ALIAS: "x0"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT EXISTS (SELECT * FROM int8_tbl t1 LEFT JOIN (int8_tbl t2 JOIN int8_tbl..." +== 455 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT d.* FROM d LEFT JOIN (SELECT * FROM b GROUP BY b.id, b.c_id) s ON d.a ..." +== 456 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT d.* FROM d LEFT JOIN (SELECT DISTINCT * FROM b) s ON d.a = s.id AND d...." +== 457 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT d.* FROM d LEFT JOIN (SELECT * FROM b GROUP BY b.id, b.c_id) s ON d.a ..." +== 458 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT d.* FROM d LEFT JOIN (SELECT DISTINCT * FROM b) s ON d.a = s.id" +== 459 +-- truncate_limit: 100 +-- join removal is not possible here +explain (costs off) +select 1 from a t1 + left join (a t2 left join a t3 on t2.id = 1) on t2.id = 1 +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +ALIAS: "t1"="a" +ALIAS: "t2"="a" +ALIAS: "t3"="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM a t1 LEFT JOIN (a t2 LEFT JOIN a t3 ON t2.id = 1) ON t2.id = 1" +== 460 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT d.* FROM d LEFT JOIN (SELECT id FROM a UNION SELECT id FROM b) s ON d...." +== 461 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT i8.* FROM int8_tbl i8 LEFT JOIN (SELECT f1 FROM int4_tbl GROUP BY f1) ..." +== 462 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="q" column="id" +FILTER: schema="" table="gs" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM (SELECT a.id FROM a LEFT JOIN b ON a.b_id = b.id) q, LATERAL ge..." +== 463 +-- truncate_limit: 100 +-- check join removal within RHS of an outer join +explain (costs off) +select c.id, ss.a from c + left join (select d.a from onerow, d left join b on d.a = b.id) ss + on c.id = ss.a +-- +TABLE: name="c" schema="" table="c" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="d" schema="" table="d" ctx=Select +TABLE: name="b" schema="" table="b" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c.id, ss.a FROM c LEFT JOIN (SELECT d.a FROM onerow, d LEFT JOIN b ON ..." +== 464 +-- truncate_limit: 100 +CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id) +-- +TABLE: name="parted_b" schema="" table="parted_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parted_b (id int PRIMARY KEY) PARTITION BY RANGE (id)" +== 465 +-- truncate_limit: 100 +CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10) +-- +TABLE: name="parted_b1" schema="" table="parted_b1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parted_b1 PARTITION OF parted_b FOR VALUES FROM (0) TO (10)" +== 466 +-- truncate_limit: 100 +-- test join removals on a partitioned table +explain (costs off) +select a.* from a left join parted_b pb on a.b_id = pb.id +-- +TABLE: name="a" schema="" table="a" ctx=Select +TABLE: name="parted_b" schema="" table="parted_b" ctx=Select +ALIAS: "pb"="parted_b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.* FROM a LEFT JOIN parted_b pb ON a.b_id = pb.id" +== 467 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 468 +-- truncate_limit: 100 +create temp table parent (k int primary key, pd int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parent (k int PRIMARY KEY, pd int)" +== 469 +-- truncate_limit: 100 +create temp table child (k int unique, cd int) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE child (k int UNIQUE, cd int)" +== 470 +-- truncate_limit: 100 +insert into parent values (1, 10), (2, 20), (3, 30) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (1, 10), (2, 20), (3, 30)" +== 471 +-- truncate_limit: 100 +insert into child values (1, 100), (4, 400) +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child VALUES (1, 100), (4, 400)" +== 472 +-- truncate_limit: 100 +-- this case is optimizable +select p.* from parent p left join child c on (p.k = c.k) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM parent p LEFT JOIN child c ON p.k = c.k" +== 473 +-- truncate_limit: 100 +explain (costs off) + select p.* from parent p left join child c on (p.k = c.k) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p.* FROM parent p LEFT JOIN child c ON p.k = c.k" +== 474 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: SelectStmt +TRUNCATED: "SELECT p.*, linked FROM parent p LEFT JOIN (SELECT ... FROM child c) ss ON p.k = ss.k" +== 475 +-- truncate_limit: 100 +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) +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p.*, linked FROM parent p LEFT JOIN (SELECT c.*, true AS linked FROM c..." +== 476 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM parent p LEFT JOIN child c ON p.k = c.k WHERE p.k = 1 AND p.k = 2" +== 477 +-- truncate_limit: 100 +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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p.* FROM parent p LEFT JOIN child c ON p.k = c.k WHERE p.k = 1 AND p.k..." +== 478 +-- truncate_limit: 100 +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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +TABLE: name="parent" schema="" table="parent" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +ALIAS: "x"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM parent p LEFT JOIN child c ON p.k = c.k JOIN parent x ON p.k = x.k WHERE ..." +== 479 +-- truncate_limit: 100 +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 +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +TABLE: name="child" schema="" table="child" ctx=Select +TABLE: name="parent" schema="" table="parent" ctx=Select +ALIAS: "c"="child" +ALIAS: "p"="parent" +ALIAS: "x"="parent" +FILTER: schema="" table="p" column="k" +FILTER: schema="" table="p" column="k" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT p.* FROM parent p LEFT JOIN child c ON p.k = c.k JOIN parent x ON p.k ..." +== 480 +-- truncate_limit: 100 +-- bug 5255: this is not optimizable by join removal +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 481 +-- truncate_limit: 100 +CREATE TEMP TABLE a (id int PRIMARY KEY) +-- +TABLE: name="a" schema="" table="a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE a (id int PRIMARY KEY)" +== 482 +-- truncate_limit: 100 +CREATE TEMP TABLE b (id int PRIMARY KEY, a_id int) +-- +TABLE: name="b" schema="" table="b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE b (id int PRIMARY KEY, a_id int)" +== 483 +-- truncate_limit: 100 +INSERT INTO a VALUES (0), (1) +-- +TABLE: name="a" schema="" table="a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO a VALUES (0), (1)" +== 484 +-- truncate_limit: 100 +INSERT INTO b VALUES (0, 0), (1, NULL) +-- +TABLE: name="b" schema="" table="b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b VALUES (0, 0), (1, NULL)" +== 485 +-- truncate_limit: 100 +SELECT * FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0) +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="a" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM b LEFT JOIN a ON b.a_id = a.id WHERE a.id IS NULL OR a.id > 0" +== 486 +-- truncate_limit: 100 +SELECT b.* FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0) +-- +TABLE: name="b" schema="" table="b" ctx=Select +TABLE: name="a" schema="" table="a" ctx=Select +FILTER: schema="" table="a" column="id" +FILTER: schema="" table="a" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT b.* FROM b LEFT JOIN a ON b.a_id = a.id WHERE a.id IS NULL OR a.id > 0" +== 487 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 488 +-- truncate_limit: 100 +-- another join removal bug: this is not optimizable, either +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 489 +-- truncate_limit: 100 +create temp table innertab (id int8 primary key, dat1 int8) +-- +TABLE: name="innertab" schema="" table="innertab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE innertab (id int8 PRIMARY KEY, dat1 int8)" +== 490 +-- truncate_limit: 100 +insert into innertab values(123, 42) +-- +TABLE: name="innertab" schema="" table="innertab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO innertab VALUES (123, 42)" +== 491 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ...) ss1 LEFT JOIN (SELECT ... FROM int8_tbl LEFT JOIN innertab ON q2 = id)..." +== 492 +-- truncate_limit: 100 +-- join removal bug #17769: can't remove if there's a pushed-down reference +EXPLAIN (COSTS OFF) +SELECT q2 FROM + (SELECT * + FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss + WHERE COALESCE(dat1, 0) = q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +FILTER: schema="" table="" column="dat1" +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT q2 FROM (SELECT * FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss WHER..." +== 493 +-- truncate_limit: 100 +-- join removal bug #17773: otherwise-removable PHV appears in a qual condition +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q2 FROM + (SELECT q2, 'constant'::text AS x + FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss + RIGHT JOIN int4_tbl ON NULL + WHERE x >= x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT q2 FROM (SELECT q2, 'constant'::text AS x FROM int8_tbl LEFT ..." +== 494 +-- truncate_limit: 100 +-- join removal bug #17786: check that OR conditions are cleaned up +EXPLAIN (COSTS OFF) +SELECT f1, x +FROM int4_tbl + JOIN ((SELECT 42 AS x FROM int8_tbl LEFT JOIN innertab ON q1 = id) AS ss1 + RIGHT JOIN tenk1 ON NULL) + ON tenk1.unique1 = ss1.x OR tenk1.unique2 = ss1.x +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="innertab" schema="" table="innertab" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT f1, x FROM int4_tbl JOIN ((SELECT 42 AS x FROM int8_tbl LEFT JOIN inne..." +== 495 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 496 +-- truncate_limit: 100 +-- another join removal bug: we must clean up correctly when removing a PHV +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 497 +-- truncate_limit: 100 +create temp table uniquetbl (f1 text unique) +-- +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE uniquetbl (f1 text UNIQUE)" +== 498 +-- truncate_limit: 100 +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 +-- +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +ALIAS: "t1"="uniquetbl" +ALIAS: "t3"="uniquetbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM uniquetbl t1 LEFT JOIN (SELECT *, '***'::text AS d1 FROM uni..." +== 499 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "t0"="text_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "u1"="uniquetbl" +FILTER: schema="" table="ss" column="stringu2" +FILTER: schema="" table="ss" column="case1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t0.* FROM text_tbl t0 LEFT JOIN (SELECT CASE t1.ten WHEN 0 THEN 'doh!'..." +== 500 +-- truncate_limit: 100 +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 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="uniquetbl" schema="" table="uniquetbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "t0"="text_tbl" +ALIAS: "t1"="tenk1" +ALIAS: "u1"="uniquetbl" +FILTER: schema="" table="ss" column="stringu2" +FILTER: schema="" table="ss" column="case1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM text_tbl t0 LEFT JOIN (SELECT ... FROM tenk1 t1 JOIN int4_tbl i4 ON i4.f1 = t1.un..." +== 501 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 502 +-- truncate_limit: 100 +-- another join removal bug: we must clean up EquivalenceClasses too +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 503 +-- truncate_limit: 100 +create temp table t (a int unique) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t (a int UNIQUE)" +== 504 +-- truncate_limit: 100 +insert into t values (1) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1)" +== 505 +-- truncate_limit: 100 +explain (costs off) +select 1 +from t t1 + left join (select 2 as c + from t t2 left join t t3 on t2.a = t3.a) s + on true +where t1.a = s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM t t1 LEFT JOIN (SELECT 2 AS c FROM t t2 LEFT JOIN t t3 ON t2.a ..." +== 506 +-- truncate_limit: 100 +select 1 +from t t1 + left join (select 2 as c + from t t2 left join t t3 on t2.a = t3.a) s + on true +where t1.a = s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="s" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM t t1 LEFT JOIN (SELECT ... FROM t t2 LEFT JOIN t t3 ON t2.a = t3.a) s ON true WHERE..." +== 507 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 508 +-- truncate_limit: 100 +-- test cases where we can remove a join, but not a PHV computed at it +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 509 +-- truncate_limit: 100 +create temp table t (a int unique, b int) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t (a int UNIQUE, b int)" +== 510 +-- truncate_limit: 100 +insert into t values (1,1), (2,2) +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1, 1), (2, 2)" +== 511 +-- truncate_limit: 100 +explain (costs off) +select 1 +from t t1 + left join (select t2.a, 1 as c + from t t2 left join t t3 on t2.a = t3.a) s + on true + left join t t4 on true +where s.a < s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM t t1 LEFT JOIN (SELECT t2.a, 1 AS c FROM t t2 LEFT JOIN t t3 ON..." +== 512 +-- truncate_limit: 100 +explain (costs off) +select t1.a, s.* +from t t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from t t2 left join t t3 on t2.a = t3.a) s + on true + left join t t4 on true +where s.a < s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, s.* FROM t t1 LEFT JOIN LATERAL (SELECT t2.a, COALESCE(t1.a, 1) ..." +== 513 +-- truncate_limit: 100 +select t1.a, s.* +from t t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from t t2 left join t t3 on t2.a = t3.a) s + on true + left join t t4 on true +where s.a < s.c +-- +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +TABLE: name="t" schema="" table="t" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +ALIAS: "t3"="t" +ALIAS: "t4"="t" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t t1 LEFT JOIN LATERAL (SELECT ... FROM t t2 LEFT JOIN t t3 ON t2.a = t3.a) s ON ..." +== 514 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 515 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="tenk1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT i8.*, ss.v, t.unique2 FROM int8_tbl i8 LEFT JOIN int4_tbl i4 ..." +== 516 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="tenk1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl i8 LEFT JOIN int4_tbl i4 ON i4.f1 = 1 LEFT JOIN LATERAL (SELECT ...) ss ..." +== 517 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="parttbl" schema="" table="parttbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parttbl (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 518 +-- truncate_limit: 100 +create temp table parttbl1 partition of parttbl for values from (1) to (100) +-- +TABLE: name="parttbl1" schema="" table="parttbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parttbl1 PARTITION OF parttbl FOR VALUES FROM (1) TO (100)" +== 519 +-- truncate_limit: 100 +insert into parttbl values (11), (12) +-- +TABLE: name="parttbl" schema="" table="parttbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parttbl VALUES (11), (12)" +== 520 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="parttbl" schema="" table="parttbl" ctx=Select +FILTER: schema="" table="ss" column="a" +FILTER: schema="" table="ss" column="phv" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT *, 12 AS phv FROM parttbl) ss RIGHT JOIN int4_tbl ON tr..." +== 521 +-- truncate_limit: 100 +select * from + (select *, 12 as phv from parttbl) as ss + right join int4_tbl on true +where ss.a = ss.phv and f1 = 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="parttbl" schema="" table="parttbl" ctx=Select +FILTER: schema="" table="ss" column="a" +FILTER: schema="" table="ss" column="phv" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM parttbl) ss RIGHT JOIN int4_tbl ON true WHERE ..." +== 522 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl x JOIN (int4_tbl x CROSS JOIN int4_tbl y ) j ON q1 = f1" +== 523 +-- truncate_limit: 100 +-- error +select * from + int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl x JOIN (int4_tbl x CROSS JOIN int4_tbl y ) j ON q1 = y.f1" +== 524 +-- truncate_limit: 100 +-- error +select * from + int8_tbl x join (int4_tbl x cross join int4_tbl y(ff)) j on q1 = f1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl x JOIN (int4_tbl x CROSS JOIN int4_tbl y(ff) ) j ON q1 = f1" +== 525 +-- truncate_limit: 100 +-- ok + +|-- +-- Test hints given on incorrect column references are useful +|-- + +select t1.uunique1 from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +TRUNCATED: "SELECT t1.uunique1 FROM tenk1 t1 JOIN tenk2 t2 ON t1.two = t2.two" +== 526 +-- truncate_limit: 100 +-- error, prefer "t1" suggestion +select t2.uunique1 from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +TRUNCATED: "SELECT t2.uunique1 FROM tenk1 t1 JOIN tenk2 t2 ON t1.two = t2.two" +== 527 +-- truncate_limit: 100 +-- error, prefer "t2" suggestion +select uunique1 from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +TRUNCATED: "SELECT uunique1 FROM tenk1 t1 JOIN tenk2 t2 ON t1.two = t2.two" +== 528 +-- truncate_limit: 100 +-- error, suggest both at once +select ctid from + tenk1 t1 join tenk2 t2 on t1.two = t2.two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tenk1 t1 JOIN tenk2 t2 ON t1.two = t2.two" +== 529 +-- truncate_limit: 100 +-- error, need qualification + +|-- +-- 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' +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "i"="pg_index" +ALIAS: "s"="pg_stats" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stats s JOIN pg_attribute a ON s.attname = a.attname AND s.tablename = a.attre..." +== 530 +-- truncate_limit: 100 +-- Test bug in rangetable flattening +explain (verbose, costs off) +select 1 from + (select * from int8_tbl where q1 <> (select 42) offset 0) ss +where false +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 FROM (SELECT * FROM int8_tbl WHERE q1 <> (SELECT 42) OFFSET..." +== 531 +-- truncate_limit: 100 +|-- +-- Test LATERAL +|-- + +select unique2, x.* +from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="a" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2, x.* FROM tenk1 a, LATERAL (SELECT * FROM int4_tbl b WHERE f1 = a.unique1) x" +== 532 +-- truncate_limit: 100 +explain (costs off) + select unique2, x.* + from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="a" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2, x.* FROM tenk1 a, LATERAL (SELECT * FROM int4_tbl b WHERE f1 ..." +== 533 +-- truncate_limit: 100 +select unique2, x.* +from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2, x.* FROM int4_tbl x, LATERAL (SELECT unique2 FROM tenk1 WHERE f1 = unique1) ss" +== 534 +-- truncate_limit: 100 +explain (costs off) + select unique2, x.* + from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2, x.* FROM int4_tbl x, LATERAL (SELECT unique2 FROM tenk1 WHERE..." +== 535 +-- truncate_limit: 100 +explain (costs off) + select unique2, x.* + from int4_tbl x cross join lateral (select unique2 from tenk1 where f1 = unique1) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2, x.* FROM int4_tbl x CROSS JOIN LATERAL (SELECT unique2 FROM t..." +== 536 +-- truncate_limit: 100 +select unique2, x.* +from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2, x.* FROM int4_tbl x LEFT JOIN LATERAL (SELECT ... FROM tenk1 WHERE ...) ss ON true" +== 537 +-- truncate_limit: 100 +explain (costs off) + select unique2, x.* + from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "x"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2, x.* FROM int4_tbl x LEFT JOIN LATERAL (SELECT unique1, unique..." +== 538 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT *, (SELECT r FROM (SELECT q1 AS q2) x, (SELECT q2 AS r) y) FROM int8_tbl" +== 539 +-- truncate_limit: 100 +select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT *, (SELECT r FROM (SELECT q1 AS q2) x, LATERAL (SELECT q2 AS r) y) FROM int8_tbl" +== 540 +-- truncate_limit: 100 +-- lateral with function in FROM +select count(*) from tenk1 a, lateral generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 a, LATERAL generate_series(1, two) g" +== 541 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 a, lateral generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 a, LATERAL generate_series(1, two) g" +== 542 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 a cross join lateral generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 a CROSS JOIN LATERAL generate_series(1, two) g" +== 543 +-- truncate_limit: 100 +-- don't need the explicit LATERAL keyword for functions +explain (costs off) + select count(*) from tenk1 a, generate_series(1,two) g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 a, generate_series(1, two) g" +== 544 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM generate_series(100, 200) g, LATERAL (SELECT * FROM int8_tbl a ..." +== 545 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="g" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(100, 200) g, LATERAL (SELECT * FROM int8_tbl a WHERE ... UNION ALL ..." +== 546 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 a, tenk1 b JOIN LATERAL (VALUES (a.unique1)) ss(x)..." +== 547 +-- truncate_limit: 100 +select count(*) from tenk1 a, + tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 a, tenk1 b JOIN LATERAL (VALUES (a.unique1)) ss(x) ON b.unique2 = ss.x" +== 548 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 a, tenk1 b JOIN LATERAL (VALUES (a.unique1), (-1))..." +== 549 +-- truncate_limit: 100 +select count(*) from tenk1 a, + tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 a, tenk1 b JOIN LATERAL (VALUES (...)) ss(x) ON b.unique2 = ss.x" +== 550 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "x"="int8_tbl" +ALIAS: "y"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl a, int8_tbl x LEFT JOIN LATERAL (SELECT a.q1 FROM int4..." +== 551 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "x"="int8_tbl" +ALIAS: "y"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl a, int8_tbl x LEFT JOIN LATERAL (SELECT ... FROM int4_tbl y) ss(z) ON x.q2..." +== 552 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM int4_tbl) ss1 JOIN int4_tbl i4 ON x = f1, LATERAL (SELECT x) ss2(y)" +== 553 +-- truncate_limit: 100 +select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, + lateral (values(x)) ss2(y) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM int4_tbl) ss1 JOIN int4_tbl i4 ON x = f1, LATERAL (VALUES (x)) ss2(y)" +== 554 +-- truncate_limit: 100 +select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, + lateral (select x) ss2(y) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ((SELECT ... FROM int4_tbl) ss1 JOIN int4_tbl i4 ON x = f1 ) j, LATERAL (SELECT x) ..." +== 555 +-- truncate_limit: 100 +-- lateral references requiring pullup +select * from (values(1)) x(lb), + lateral generate_series(lb,4) x4 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1)) x(lb), LATERAL generate_series(lb, 4) x4" +== 556 +-- truncate_limit: 100 +select * from (select f1/1000000000 from int4_tbl) x(lb), + lateral generate_series(lb,4) x4 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT f1 / 1000000000 FROM int4_tbl) x(lb), LATERAL generate_series(lb, 4) x4" +== 557 +-- truncate_limit: 100 +select * from (values(1)) x(lb), + lateral (values(lb)) y(lbcopy) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1)) x(lb), LATERAL (VALUES (lb)) y(lbcopy)" +== 558 +-- truncate_limit: 100 +select * from (values(1)) x(lb), + lateral (select lb from int4_tbl) y(lbcopy) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1)) x(lb), LATERAL (SELECT lb FROM int4_tbl) y(lbcopy)" +== 559 +-- truncate_limit: 100 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl x LEFT JOIN (SELECT ... FROM int8_tbl) y ON x.q2 = y.q1, LATERAL (VALUES (..." +== 560 +-- truncate_limit: 100 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl x LEFT JOIN (SELECT ... FROM int8_tbl) y ON x.q2 = y.q1, LATERAL (SELECT ...." +== 561 +-- truncate_limit: 100 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT x.* FROM int8_tbl x LEFT JOIN (SELECT ... FROM int8_tbl) y ON x.q2 = y.q1, LATERAL (SELECT..." +== 562 +-- truncate_limit: 100 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +ALIAS: "z"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT v.* FROM int8_tbl x LEFT JOIN (SELECT ... FROM int8_tbl) y ON x.q2 = y.q1 LEFT JOIN int4_t..." +== 563 +-- truncate_limit: 100 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "x"="int8_tbl" +ALIAS: "z"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT v.* FROM int8_tbl x LEFT JOIN (SELECT ... FROM int8_tbl) y ON x.q2 = y.q1 LEFT JOIN int4_t..." +== 564 +-- truncate_limit: 100 +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) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +TABLE: name="onerow" schema="" table="onerow" ctx=Select +ALIAS: "x"="int8_tbl" +ALIAS: "z"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT v.* FROM int8_tbl x LEFT JOIN (SELECT ... FROM int8_tbl) y ON x.q2 = y.q1 LEFT JOIN int4_t..." +== 565 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int8_tbl a LEFT JOIN LATERAL (SELECT *, a.q2 AS x FROM..." +== 566 +-- truncate_limit: 100 +select * from + int8_tbl a left join + lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl a LEFT JOIN LATERAL (SELECT *, a.q2 AS x FROM int8_tbl b) ss ON a.q2 = ss.q1" +== 567 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int8_tbl a LEFT JOIN LATERAL (SELECT *, COALESCE(a.q2,..." +== 568 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl a LEFT JOIN LATERAL (SELECT ... FROM int8_tbl b) ss ON a.q2 = ss.q1" +== 569 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl i LEFT JOIN LATERAL (SELECT * FROM int2_tbl j..." +== 570 +-- truncate_limit: 100 +select * from int4_tbl i left join + lateral (select * from int2_tbl j where i.f1 = j.f1) k on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl i LEFT JOIN LATERAL (SELECT * FROM int2_tbl j WHERE i.f1 = j.f1) k ON true" +== 571 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl i LEFT JOIN LATERAL (SELECT COALESCE(i) FROM ..." +== 572 +-- truncate_limit: 100 +select * from int4_tbl i left join + lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "j"="int2_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="j" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl i LEFT JOIN LATERAL (SELECT ... FROM int2_tbl j WHERE i.f1 = j.f1) k ON true" +== 573 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +ALIAS: "c"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl a, LATERAL (SELECT * FROM int4_tbl b LEFT JOI..." +== 574 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +ALIAS: "c"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl a, LATERAL (SELECT * FROM int4_tbl b LEFT JOIN int8_tbl c ON b.f1 = q1 AND..." +== 575 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int8_tbl a LEFT JOIN LATERAL (SELECT b.q1 AS bq1, c.q1..." +== 576 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl a LEFT JOIN LATERAL (SELECT ... FROM int8_tbl b CROSS JOIN int8_tbl c) ss ..." +== 577 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "c"="int8_tbl" +ALIAS: "d"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int8_tbl c LEFT JOIN (int8_tbl a LEFT JOIN (SELECT q1,..." +== 578 +-- truncate_limit: 100 +-- another case requiring nested PlaceHolderVars +explain (verbose, costs off) +select * from + (select 0 as val0) as ss0 + left join (select 1 as val) as ss1 on true + left join lateral (select ss1.val as val_filtered where false) as ss2 on true +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT 0 AS val0) ss0 LEFT JOIN (SELECT 1 AS val) ss1..." +== 579 +-- truncate_limit: 100 +select * from + (select 0 as val0) as ss0 + left join (select 1 as val) as ss1 on true + left join lateral (select ss1.val as val_filtered where false) as ss2 on true +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ...) ss0 LEFT JOIN (SELECT ...) ss1 ON true LEFT JOIN LATERAL (SELECT ... W..." +== 580 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +ALIAS: "b2"="int4_tbl" +ALIAS: "c"="int8_tbl" +ALIAS: "d"="int8_tbl" +ALIAS: "i"="int4_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="ss2" column="y" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT c.*, a.*, ss1.q1, ss2.q1, ss3.* FROM int8_tbl c LEFT JOIN (in..." +== 581 +-- truncate_limit: 100 +-- 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 +-- +FILTER: schema="" table="z" column="z" +FILTER: schema="" table="x" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT 1 AS x OFFSET 0) x CROSS JOIN (SELECT 2 AS y O..." +== 582 +-- truncate_limit: 100 +-- a new postponed-quals issue (bug #17768) +explain (costs off) +select * from int4_tbl t1, + lateral (select * from int4_tbl t2 inner join int4_tbl t3 on t1.f1 = 1 + inner join (int4_tbl t4 left join int4_tbl t5 on true) on true) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "t1"="int4_tbl" +ALIAS: "t2"="int4_tbl" +ALIAS: "t3"="int4_tbl" +ALIAS: "t4"="int4_tbl" +ALIAS: "t5"="int4_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl t1, LATERAL (SELECT * FROM int4_tbl t2 JOIN int4_tbl t..." +== 583 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int8_tbl i8 LEFT JOIN LATERAL (SELECT *, i8.q2 FROM in..." +== 584 +-- truncate_limit: 100 +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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i1"="int4_tbl" +ALIAS: "i2"="int4_tbl" +ALIAS: "i8"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int8_tbl i8 LEFT JOIN LATERAL (SELECT *, i8.q2 FROM in..." +== 585 +-- truncate_limit: 100 +-- 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 +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... UNION ALL SELECT ...) q1 CROSS JOIN LATERAL (SELECT * FROM (SELECT ... ..." +== 586 +-- truncate_limit: 100 +-- check the number of columns specified +SELECT * FROM (int8_tbl i cross join int4_tbl j) ss(a,b,c,d) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +ALIAS: "j"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (int8_tbl i CROSS JOIN int4_tbl j ) ss(a, b, c, d)" +== 587 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="v" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (VALUES (0, 9998), (1, 1000)) v(id, x), LATERAL (SELEC..." +== 588 +-- truncate_limit: 100 +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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="v" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (0, 9998), (1, 1000)) v(id, x), LATERAL (SELECT f1 FROM int4_tbl WHERE ...) ss" +== 589 +-- truncate_limit: 100 +-- 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, random() > 0) = any (select q2, random() > 0 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="t1" column="q1" +FILTER: schema="" table="ss" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (VALUES (0), (1)) v(id), LATERAL (SELECT * FROM int8_t..." +== 590 +-- truncate_limit: 100 +select * from (values (0), (1)) v(id), +lateral (select * from int8_tbl t1, + lateral (select * from + (select * from int8_tbl t2 + where (q1, random() > 0) = any (select q2, random() > 0 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="t1" column="q1" +FILTER: schema="" table="ss" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(id), LATERAL (SELECT * FROM int8_tbl t1, LATERAL (SELECT * FROM (S..." +== 591 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f1, g FROM int4_tbl a, (SELECT f1 AS g) ss" +== 592 +-- truncate_limit: 100 +select f1,g from int4_tbl a, (select a.f1 as g) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f1, g FROM int4_tbl a, (SELECT a.f1 AS g) ss" +== 593 +-- truncate_limit: 100 +select f1,g from int4_tbl a cross join (select f1 as g) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f1, g FROM int4_tbl a CROSS JOIN (SELECT f1 AS g) ss" +== 594 +-- truncate_limit: 100 +select f1,g from int4_tbl a cross join (select a.f1 as g) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT f1, g FROM int4_tbl a CROSS JOIN (SELECT a.f1 AS g) ss" +== 595 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, g FROM int4_tbl a RIGHT JOIN LATERAL generate_series(0, a.f1) g ON true" +== 596 +-- truncate_limit: 100 +select f1,g from int4_tbl a full join lateral generate_series(0, a.f1) g on true +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, g FROM int4_tbl a FULL JOIN LATERAL generate_series(0, a.f1) g ON true" +== 597 +-- truncate_limit: 100 +-- check we complain about ambiguous table references +select * from + int8_tbl x cross join (int4_tbl x cross join lateral (select x.f1) ss) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "x"="int4_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl x CROSS JOIN (int4_tbl x CROSS JOIN LATERAL (SELECT x.f1) ss)" +== 598 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="int4_tbl" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM tenk1 a, LATERAL (SELECT max(a.unique1) FROM int4_tbl b) ss" +== 599 +-- truncate_limit: 100 +-- check behavior of LATERAL in UPDATE/DELETE + +create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DDL +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE xx1 AS SELECT f1 AS x1, - f1 AS x2 FROM int4_tbl" +== 600 +-- truncate_limit: 100 +-- error, can't do this: +update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE xx1 SET x2 = f1 FROM (SELECT * FROM int4_tbl WHERE f1 = x1) ss" +== 601 +-- truncate_limit: 100 +update xx1 set x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="xx1" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE xx1 SET x2 = f1 FROM (SELECT * FROM int4_tbl WHERE f1 = xx1.x1) ss" +== 602 +-- truncate_limit: 100 +-- can't do it even with LATERAL: +update xx1 set x2 = f1 from lateral (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE xx1 SET x2 = f1 FROM LATERAL (SELECT * FROM int4_tbl WHERE f1 = x1) ss" +== 603 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="xx1" schema="" table="xx1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE xx1 SET x2 = f1 FROM xx1, LATERAL (SELECT * FROM int4_tbl WHERE f1 = x1) ss" +== 604 +-- truncate_limit: 100 +-- also errors: +delete from xx1 using (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM xx1 USING (SELECT * FROM int4_tbl WHERE f1 = x1) ss" +== 605 +-- truncate_limit: 100 +delete from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="xx1" column="x1" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM xx1 USING (SELECT * FROM int4_tbl WHERE f1 = xx1.x1) ss" +== 606 +-- truncate_limit: 100 +delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss +-- +TABLE: name="xx1" schema="" table="xx1" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="x1" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM xx1 USING LATERAL (SELECT * FROM int4_tbl WHERE f1 = x1) ss" +== 607 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE join_pt1 (a int, b int, c varchar) PARTITION BY RANGE (a)" +== 608 +-- truncate_limit: 100 +create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b) +-- +TABLE: name="join_pt1p1" schema="" table="join_pt1p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE join_pt1p1 PARTITION OF join_pt1 FOR VALUES FROM (0) TO (100) PARTITION BY RANGE (b)" +== 609 +-- truncate_limit: 100 +create table join_pt1p2 partition of join_pt1 for values from (100) to (200) +-- +TABLE: name="join_pt1p2" schema="" table="join_pt1p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE join_pt1p2 PARTITION OF join_pt1 FOR VALUES FROM (100) TO (200)" +== 610 +-- truncate_limit: 100 +create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100) +-- +TABLE: name="join_pt1p1p1" schema="" table="join_pt1p1p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE join_pt1p1p1 PARTITION OF join_pt1p1 FOR VALUES FROM (0) TO (100)" +== 611 +-- truncate_limit: 100 +insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y') +-- +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO join_pt1 VALUES (1, 1, 'x'), (101, 101, 'y')" +== 612 +-- truncate_limit: 100 +create table join_ut1 (a int, b int, c varchar) +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE join_ut1 (a int, b int, c varchar)" +== 613 +-- truncate_limit: 100 +insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z') +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO join_ut1 VALUES (101, 101, 'y'), (2, 2, 'z')" +== 614 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=Select +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +ALIAS: "t1"="join_ut1" +ALIAS: "t2"="join_pt1" +ALIAS: "t3"="join_ut1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.b, ss.phv FROM join_ut1 t1 LEFT JOIN LATERAL (SELECT t2.a ..." +== 615 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=Select +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=Select +ALIAS: "t1"="join_ut1" +ALIAS: "t2"="join_pt1" +ALIAS: "t3"="join_ut1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM join_ut1 t1 LEFT JOIN LATERAL (SELECT ... FROM join_pt1 t2 JOIN join_ut1 t3 ON t2..." +== 616 +-- truncate_limit: 100 +drop table join_pt1 +-- +TABLE: name="join_pt1" schema="" table="join_pt1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE join_pt1" +== 617 +-- truncate_limit: 100 +drop table join_ut1 +-- +TABLE: name="join_ut1" schema="" table="join_ut1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE join_ut1" +== 618 +-- truncate_limit: 100 +|-- +-- test estimation behavior with multi-column foreign key and constant qual +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 619 +-- truncate_limit: 100 +create table fkest (x integer, x10 integer, x10b integer, x100 integer) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkest (x int, x10 int, x10b int, x100 int)" +== 620 +-- truncate_limit: 100 +insert into fkest select x, x/10, x/10, x/100 from generate_series(1,1000) x +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkest SELECT x, x / 10, x / 10, x / 100 FROM generate_series(1, 1000) x" +== 621 +-- truncate_limit: 100 +create unique index on fkest(x, x10, x100) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON fkest USING btree (x, x10, x100)" +== 622 +-- truncate_limit: 100 +analyze fkest +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE fkest" +== 623 +-- truncate_limit: 100 +explain (costs off) +select * from fkest f1 + join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) + join fkest f3 on f1.x = f3.x + where f1.x100 = 2 +-- +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +ALIAS: "f1"="fkest" +ALIAS: "f2"="fkest" +ALIAS: "f3"="fkest" +FILTER: schema="" table="f1" column="x100" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM fkest f1 JOIN fkest f2 ON f1.x = f2.x AND f1.x10 = f2.x10b AND ..." +== 624 +-- truncate_limit: 100 +alter table fkest add constraint fk + foreign key (x, x10b, x100) references fkest (x, x10, x100) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkest ADD CONSTRAINT fk FOREIGN KEY (x, x10b, x100) REFERENCES fkest (x, x10, x100)" +== 625 +-- truncate_limit: 100 +explain (costs off) +select * from fkest f1 + join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) + join fkest f3 on f1.x = f3.x + where f1.x100 = 2 +-- +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest" schema="" table="fkest" ctx=Select +ALIAS: "f1"="fkest" +ALIAS: "f2"="fkest" +ALIAS: "f3"="fkest" +FILTER: schema="" table="f1" column="x100" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM fkest f1 JOIN fkest f2 ON f1.x = f2.x AND f1.x10 = f2.x10b AND ..." +== 626 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 627 +-- truncate_limit: 100 +|-- +-- test that foreign key join estimation performs sanely for outer joins +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 628 +-- truncate_limit: 100 +create table fkest (a int, b int, c int unique, primary key(a,b)) +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkest (a int, b int, c int UNIQUE, PRIMARY KEY (a, b))" +== 629 +-- truncate_limit: 100 +create table fkest1 (a int, b int, primary key(a,b)) +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkest1 (a int, b int, PRIMARY KEY (a, b))" +== 630 +-- truncate_limit: 100 +insert into fkest select x/10, x%10, x from generate_series(1,1000) x +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkest SELECT x / 10, x % 10, x FROM generate_series(1, 1000) x" +== 631 +-- truncate_limit: 100 +insert into fkest1 select x/10, x%10 from generate_series(1,1000) x +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkest1 SELECT x / 10, x % 10 FROM generate_series(1, 1000) x" +== 632 +-- truncate_limit: 100 +alter table fkest1 + add constraint fkest1_a_b_fkey foreign key (a,b) references fkest +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fkest1 ADD CONSTRAINT fkest1_a_b_fkey FOREIGN KEY (a, b) REFERENCES fkest" +== 633 +-- truncate_limit: 100 +analyze fkest +-- +TABLE: name="fkest" schema="" table="fkest" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE fkest" +== 634 +-- truncate_limit: 100 +analyze fkest1 +-- +TABLE: name="fkest1" schema="" table="fkest1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE fkest1" +== 635 +-- truncate_limit: 100 +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 +-- +TABLE: name="fkest" schema="" table="fkest" ctx=Select +TABLE: name="fkest1" schema="" table="fkest1" ctx=Select +TABLE: name="fkest1" schema="" table="fkest1" ctx=Select +TABLE: name="fkest1" schema="" table="fkest1" ctx=Select +ALIAS: "f"="fkest" +ALIAS: "f1"="fkest1" +ALIAS: "f2"="fkest1" +ALIAS: "f3"="fkest1" +FILTER: schema="" table="f" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM fkest f LEFT JOIN fkest1 f1 ON f.a = f1.a AND f.b = f1.b LEFT J..." +== 636 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 637 +-- truncate_limit: 100 +|-- +-- test planner's ability to mark joins as unique +|-- + +create table j1 (id int primary key) +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j1 (id int PRIMARY KEY)" +== 638 +-- truncate_limit: 100 +create table j2 (id int primary key) +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j2 (id int PRIMARY KEY)" +== 639 +-- truncate_limit: 100 +create table j3 (id int) +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j3 (id int)" +== 640 +-- truncate_limit: 100 +insert into j1 values(1),(2),(3) +-- +TABLE: name="j1" schema="" table="j1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1 VALUES (1), (2), (3)" +== 641 +-- truncate_limit: 100 +insert into j2 values(1),(2),(3) +-- +TABLE: name="j2" schema="" table="j2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2 VALUES (1), (2), (3)" +== 642 +-- truncate_limit: 100 +insert into j3 values(1),(1) +-- +TABLE: name="j3" schema="" table="j3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j3 VALUES (1), (1)" +== 643 +-- truncate_limit: 100 +analyze j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE j1" +== 644 +-- truncate_limit: 100 +analyze j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE j2" +== 645 +-- truncate_limit: 100 +analyze j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE j3" +== 646 +-- truncate_limit: 100 +-- ensure join is properly marked as unique +explain (verbose, costs off) +select * from j1 inner join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id = j2.id" +== 647 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id > j2.id" +== 648 +-- truncate_limit: 100 +-- ensure non-unique rel is not chosen as inner +explain (verbose, costs off) +select * from j1 inner join j3 on j1.id = j3.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN j3 ON j1.id = j3.id" +== 649 +-- truncate_limit: 100 +-- ensure left join is marked as unique +explain (verbose, costs off) +select * from j1 left join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 LEFT JOIN j2 ON j1.id = j2.id" +== 650 +-- truncate_limit: 100 +-- ensure right join is marked as unique +explain (verbose, costs off) +select * from j1 right join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 RIGHT JOIN j2 ON j1.id = j2.id" +== 651 +-- truncate_limit: 100 +-- ensure full join is marked as unique +explain (verbose, costs off) +select * from j1 full join j2 on j1.id = j2.id +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 FULL JOIN j2 ON j1.id = j2.id" +== 652 +-- truncate_limit: 100 +-- a clauseless (cross) join can't be unique +explain (verbose, costs off) +select * from j1 cross join j2 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 CROSS JOIN j2" +== 653 +-- truncate_limit: 100 +-- ensure a natural join is marked as unique +explain (verbose, costs off) +select * from j1 natural join j2 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 NATURAL JOIN j2" +== 654 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN (SELECT DISTINCT id FROM j3) j3 ON j1.id = j3.id" +== 655 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN (SELECT id FROM j3 GROUP BY id) j3 ON j1.id = ..." +== 656 +-- truncate_limit: 100 +drop table j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j1" +== 657 +-- truncate_limit: 100 +drop table j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j2" +== 658 +-- truncate_limit: 100 +drop table j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j3" +== 659 +-- truncate_limit: 100 +-- test more complex permutations of unique joins + +create table j1 (id1 int, id2 int, primary key(id1,id2)) +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j1 (id1 int, id2 int, PRIMARY KEY (id1, id2))" +== 660 +-- truncate_limit: 100 +create table j2 (id1 int, id2 int, primary key(id1,id2)) +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j2 (id1 int, id2 int, PRIMARY KEY (id1, id2))" +== 661 +-- truncate_limit: 100 +create table j3 (id1 int, id2 int, primary key(id1,id2)) +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE j3 (id1 int, id2 int, PRIMARY KEY (id1, id2))" +== 662 +-- truncate_limit: 100 +insert into j1 values(1,1),(1,2) +-- +TABLE: name="j1" schema="" table="j1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j1 VALUES (1, 1), (1, 2)" +== 663 +-- truncate_limit: 100 +insert into j2 values(1,1) +-- +TABLE: name="j2" schema="" table="j2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2 VALUES (1, 1)" +== 664 +-- truncate_limit: 100 +insert into j3 values(1,1) +-- +TABLE: name="j3" schema="" table="j3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j3 VALUES (1, 1)" +== 665 +-- truncate_limit: 100 +analyze j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE j1" +== 666 +-- truncate_limit: 100 +analyze j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE j2" +== 667 +-- truncate_limit: 100 +analyze j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE j3" +== 668 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1" +== 669 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 AND j1.id2 = j2.id2" +== 670 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 WHERE j1.id2 = 1" +== 671 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 LEFT JOIN j2 ON j1.id1 = j2.id1 WHERE j1.id2 = 1" +== 672 +-- truncate_limit: 100 +create unique index j1_id2_idx on j1(id2) where id2 is not null +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX j1_id2_idx ON j1 USING btree (id2) WHERE id2 IS NOT NULL" +== 673 +-- truncate_limit: 100 +-- ensure we don't use a partial unique index as unique proofs +explain (verbose, costs off) +select * from j1 +inner join j2 on j1.id2 = j2.id2 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id2 = j2.id2" +== 674 +-- truncate_limit: 100 +drop index j1_id2_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX j1_id2_idx" +== 675 +-- truncate_limit: 100 +-- 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 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO 0" +== 676 +-- truncate_limit: 100 +set enable_hashjoin to 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO 0" +== 677 +-- truncate_limit: 100 +set enable_sort to 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO 0" +== 678 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX j1_id1_idx ON j1 USING btree (id1) WHERE (id1 % 1000) = 1" +== 679 +-- truncate_limit: 100 +create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX j2_id1_idx ON j2 USING btree (id1) WHERE (id1 % 1000) = 1" +== 680 +-- truncate_limit: 100 +-- need an additional row in j2, if we want j2_id1_idx to be preferred +insert into j2 values(1,2) +-- +TABLE: name="j2" schema="" table="j2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO j2 VALUES (1, 2)" +== 681 +-- truncate_limit: 100 +analyze j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE j2" +== 682 +-- truncate_limit: 100 +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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 AND j1.id2 = j2.id2 WHERE (j1.id1..." +== 683 +-- truncate_limit: 100 +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 +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 AND j1.id2 = j2.id2 WHERE ..." +== 684 +-- truncate_limit: 100 +-- 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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 AND j1.id2 = j2.id2 WHERE (j1.id1..." +== 685 +-- truncate_limit: 100 +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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 AND j1.id2 = j2.id2 WHERE ..." +== 686 +-- truncate_limit: 100 +-- 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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 AND j1.id2 = j2.id2 WHERE (j1.id1..." +== 687 +-- truncate_limit: 100 +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]) +-- +TABLE: name="j1" schema="" table="j1" ctx=Select +TABLE: name="j2" schema="" table="j2" ctx=Select +FILTER: schema="" table="j1" column="id1" +FILTER: schema="" table="j2" column="id1" +FILTER: schema="" table="j2" column="id1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM j1 JOIN j2 ON j1.id1 = j2.id1 AND j1.id2 = j2.id2 WHERE ..." +== 688 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 689 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 690 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 691 +-- truncate_limit: 100 +drop table j1 +-- +TABLE: name="j1" schema="" table="j1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j1" +== 692 +-- truncate_limit: 100 +drop table j2 +-- +TABLE: name="j2" schema="" table="j2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j2" +== 693 +-- truncate_limit: 100 +drop table j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j3" +== 694 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="tenk1" +ALIAS: "t3"="tenk1" +FILTER: schema="" table="t3" column="thousand" +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t3" column="tenthous" +FILTER: schema="" table="t2" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.unique1, t2.hundred FROM onek t1, tenk1 t2 WHERE EXISTS (S..." +== 695 +-- truncate_limit: 100 +-- ... unless it actually is unique +create table j3 as select unique1, tenthous from onek +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE j3 AS SELECT unique1, tenthous FROM onek" +== 696 +-- truncate_limit: 100 +vacuum analyze j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) j3" +== 697 +-- truncate_limit: 100 +create unique index on j3(unique1, tenthous) +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON j3 USING btree (unique1, tenthous)" +== 698 +-- truncate_limit: 100 +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 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="j3" schema="" table="j3" ctx=Select +ALIAS: "t1"="onek" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="j3" column="unique1" +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="j3" column="tenthous" +FILTER: schema="" table="t2" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.unique1, t2.hundred FROM onek t1, tenk1 t2 WHERE EXISTS (S..." +== 699 +-- truncate_limit: 100 +drop table j3 +-- +TABLE: name="j3" schema="" table="j3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE j3" +== 700 +-- truncate_limit: 100 +-- Exercise the "skip fetch" Bitmap Heap Scan optimization when candidate +-- tuples are discarded. This may occur when: +-- 1. A join doesn't require all inner tuples to be scanned for each outer +-- tuple, and +-- 2. The inner side is scanned using a bitmap heap scan, and +-- 3. The bitmap heap scan is eligible for the "skip fetch" optimization. +-- This optimization is usable when no data from the underlying table is +-- needed. Use a temp table so it is only visible to this backend and +-- vacuum may reliably mark all blocks in the table all visible in the +-- visibility map. +CREATE TEMP TABLE skip_fetch (a INT, b INT) WITH (fillfactor=10) +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE skip_fetch (a int, b int) WITH (fillfactor=10)" +== 701 +-- truncate_limit: 100 +INSERT INTO skip_fetch SELECT i % 3, i FROM generate_series(0,30) i +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO skip_fetch SELECT i % 3, i FROM generate_series(0, 30) i" +== 702 +-- truncate_limit: 100 +CREATE INDEX ON skip_fetch(a) +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON skip_fetch USING btree (a)" +== 703 +-- truncate_limit: 100 +VACUUM (ANALYZE) skip_fetch +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) skip_fetch" +== 704 +-- truncate_limit: 100 +SET enable_indexonlyscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO OFF" +== 705 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 706 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS NULL +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +ALIAS: "t1"="skip_fetch" +ALIAS: "t2"="skip_fetch" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a..." +== 707 +-- truncate_limit: 100 +SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS NULL +-- +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +TABLE: name="skip_fetch" schema="" table="skip_fetch" ctx=Select +ALIAS: "t1"="skip_fetch" +ALIAS: "t2"="skip_fetch" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS NULL" +== 708 +-- truncate_limit: 100 +RESET enable_indexonlyscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexonlyscan" +== 709 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 710 +-- truncate_limit: 100 +-- Test that we do not account for nullingrels when looking up statistics +CREATE TABLE group_tbl (a INT, b INT) +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE group_tbl (a int, b int)" +== 711 +-- truncate_limit: 100 +INSERT INTO group_tbl SELECT 1, 1 +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO group_tbl SELECT 1, 1" +== 712 +-- truncate_limit: 100 +CREATE STATISTICS group_tbl_stat (ndistinct) ON a, b FROM group_tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS group_tbl_stat (ndistinct) ON a, b FROM group_tbl" +== 713 +-- truncate_limit: 100 +ANALYZE group_tbl +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE group_tbl" +== 714 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT 1 FROM group_tbl t1 + LEFT JOIN (SELECT a c1, COALESCE(a) c2 FROM group_tbl t2) s ON TRUE +GROUP BY s.c1, s.c2 +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=Select +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=Select +ALIAS: "t1"="group_tbl" +ALIAS: "t2"="group_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM group_tbl t1 LEFT JOIN (SELECT a AS c1, COALESCE(a) AS c2 FROM ..." +== 715 +-- truncate_limit: 100 +DROP TABLE group_tbl +-- +TABLE: name="group_tbl" schema="" table="group_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE group_tbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json b/parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json new file mode 100644 index 0000000..5bababc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json @@ -0,0 +1,283 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/join_hash.test b/parser/testdata/summary_truncate/postgres_regress/join_hash.test new file mode 100644 index 0000000..f631d4b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/join_hash.test @@ -0,0 +1,2370 @@ +== 001 +-- truncate_limit: 100 +|-- +-- exercises for the hash join code +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 002 +-- truncate_limit: 100 +set local min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL min_parallel_table_scan_size TO 0" +== 003 +-- truncate_limit: 100 +set local parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL parallel_setup_cost TO 0" +== 004 +-- truncate_limit: 100 +set local enable_hashjoin = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_hashjoin TO ON" +== 005 +-- truncate_limit: 100 +-- Extract bucket and batch counts from an explain analyze plan. In +-- general we can't make assertions about how many batches (or +-- buckets) will be required because it can vary, but we can in some +-- special cases and we can check for growth. +create or replace function find_hash(node json) +returns json language plpgsql +as +$$ +declare + x json; + child json; +begin + if node->>'Node Type' = 'Hash' then + return node; + else + for child in select json_array_elements(node->'Plans') + loop + x := find_hash(child); + if x is not null then + return x; + end if; + end loop; + return null; + end if; +end; +$$ +-- +FUNCTION: name="find_hash" function="find_hash" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION find_hash(node pg_catalog.json) RETURNS pg_catalog.json LANGUAGE plpgs..." +== 006 +-- truncate_limit: 100 +create or replace function hash_join_batches(query text) +returns table (original int, final int) language plpgsql +as +$$ +declare + whole_plan json; + hash_node json; +begin + for whole_plan in + execute 'explain (analyze, format ''json'') ' || query + loop + hash_node := find_hash(json_extract_path(whole_plan, '0', 'Plan')); + original := hash_node->>'Original Hash Batches'; + final := hash_node->>'Hash Batches'; + return next; + end loop; +end; +$$ +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION hash_join_batches(query text) RETURNS TABLE (original int, final int) ..." +== 007 +-- truncate_limit: 100 +-- Make a simple relation with well distributed keys and correctly +-- estimated size. +create table simple as + select generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +-- +TABLE: name="simple" schema="" table="simple" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE simple AS SELECT generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'" +== 008 +-- truncate_limit: 100 +alter table simple set (parallel_workers = 2) +-- +TABLE: name="simple" schema="" table="simple" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE simple SET (parallel_workers=2)" +== 009 +-- truncate_limit: 100 +analyze simple +-- +TABLE: name="simple" schema="" table="simple" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE simple" +== 010 +-- truncate_limit: 100 +-- Make a relation whose size we will under-estimate. We want stats +-- to say 1000 rows, but actually there are 20,000 rows. +create table bigger_than_it_looks as + select generate_series(1, 20000) as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE bigger_than_it_looks AS SELECT generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaa..." +== 011 +-- truncate_limit: 100 +alter table bigger_than_it_looks set (autovacuum_enabled = 'false') +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bigger_than_it_looks SET (autovacuum_enabled=false)" +== 012 +-- truncate_limit: 100 +alter table bigger_than_it_looks set (parallel_workers = 2) +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE bigger_than_it_looks SET (parallel_workers=2)" +== 013 +-- truncate_limit: 100 +analyze bigger_than_it_looks +-- +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE bigger_than_it_looks" +== 014 +-- truncate_limit: 100 +update pg_class set reltuples = 1000 where relname = 'bigger_than_it_looks' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pg_class SET reltuples = 1000 WHERE relname = 'bigger_than_it_looks'" +== 015 +-- truncate_limit: 100 +-- Make a relation whose size we underestimate and that also has a +-- kind of skew that breaks our batching scheme. We want stats to say +-- 2 rows, but actually there are 20,000 rows with the same key. +create table extremely_skewed (id int, t text) +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE extremely_skewed (id int, t text)" +== 016 +-- truncate_limit: 100 +alter table extremely_skewed set (autovacuum_enabled = 'false') +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE extremely_skewed SET (autovacuum_enabled=false)" +== 017 +-- truncate_limit: 100 +alter table extremely_skewed set (parallel_workers = 2) +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE extremely_skewed SET (parallel_workers=2)" +== 018 +-- truncate_limit: 100 +analyze extremely_skewed +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE extremely_skewed" +== 019 +-- truncate_limit: 100 +insert into extremely_skewed + select 42 as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + from generate_series(1, 20000) +-- +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO extremely_skewed SELECT ... FROM generate_series(1, 20000)" +== 020 +-- truncate_limit: 100 +update pg_class + set reltuples = 2, relpages = pg_relation_size('extremely_skewed') / 8192 + where relname = 'extremely_skewed' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE pg_class SET ... = ... WHERE relname = 'extremely_skewed'" +== 021 +-- truncate_limit: 100 +-- Make a relation with a couple of enormous tuples. +create table wide as select generate_series(1, 2) as id, rpad('', 320000, 'x') as t +-- +TABLE: name="wide" schema="" table="wide" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="rpad" function="rpad" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE wide AS SELECT generate_series(1, 2) AS id, rpad('', 320000, 'x') AS t" +== 022 +-- truncate_limit: 100 +alter table wide set (parallel_workers = 2) +-- +TABLE: name="wide" schema="" table="wide" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE wide SET (parallel_workers=2)" +== 023 +-- truncate_limit: 100 +-- The "optimal" case: the hash table fits in memory; we plan for 1 +-- batch, we stick to that number, and peak memory usage stays within +-- our work_mem budget + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 024 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 0" +== 025 +-- truncate_limit: 100 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"4MB\"" +== 026 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 027 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 028 +-- truncate_limit: 100 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 029 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join simple s using (id);\n')" +== 030 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 031 +-- truncate_limit: 100 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 032 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 033 +-- truncate_limit: 100 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"4MB\"" +== 034 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 035 +-- truncate_limit: 100 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO OFF" +== 036 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 037 +-- truncate_limit: 100 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 038 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join simple s using (id);\n')" +== 039 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 040 +-- truncate_limit: 100 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 041 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 042 +-- truncate_limit: 100 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"4MB\"" +== 043 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 044 +-- truncate_limit: 100 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO ON" +== 045 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 046 +-- truncate_limit: 100 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 047 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join simple s using (id);\n')" +== 048 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 049 +-- truncate_limit: 100 +-- The "good" case: batches required, but we plan the right number; we +-- plan for some number of batches, and we stick to that number, and +-- peak memory usage says within our work_mem budget + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 050 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 0" +== 051 +-- truncate_limit: 100 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"128kB\"" +== 052 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 053 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 054 +-- truncate_limit: 100 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 055 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join simple s using (id);\n')" +== 056 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 057 +-- truncate_limit: 100 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 058 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 059 +-- truncate_limit: 100 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"128kB\"" +== 060 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 061 +-- truncate_limit: 100 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO OFF" +== 062 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 063 +-- truncate_limit: 100 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 064 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join simple s using (id);\n')" +== 065 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 066 +-- truncate_limit: 100 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 067 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 068 +-- truncate_limit: 100 +set local work_mem = '192kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"192kB\"" +== 069 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 070 +-- truncate_limit: 100 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO ON" +== 071 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 072 +-- truncate_limit: 100 +select count(*) from simple r join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN simple s USING (id)" +== 073 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join simple s using (id);\n')" +== 074 +-- truncate_limit: 100 +-- parallel full multi-batch hash join +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r FULL JOIN simple s USING (id)" +== 075 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 076 +-- truncate_limit: 100 +-- The "bad" case: during execution we need to increase number of +-- batches; in this case we plan for 1 batch, and increase at least a +-- couple of times, and peak memory usage stays within our work_mem +-- budget + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 077 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 0" +== 078 +-- truncate_limit: 100 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"128kB\"" +== 079 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 080 +-- truncate_limit: 100 +explain (costs off) + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN bigger_than_it_looks s USING (id)" +== 081 +-- truncate_limit: 100 +select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN bigger_than_it_looks s USING (id)" +== 082 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) FROM simple r JOIN bigger_than_it_looks s U..." +== 083 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 084 +-- truncate_limit: 100 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 085 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 086 +-- truncate_limit: 100 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"128kB\"" +== 087 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 088 +-- truncate_limit: 100 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO OFF" +== 089 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN bigger_than_it_looks s USING (id)" +== 090 +-- truncate_limit: 100 +select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN bigger_than_it_looks s USING (id)" +== 091 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join bigger_than_it_looks s u..." +== 092 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 093 +-- truncate_limit: 100 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 094 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 1" +== 095 +-- truncate_limit: 100 +set local work_mem = '192kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"192kB\"" +== 096 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 097 +-- truncate_limit: 100 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO ON" +== 098 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN bigger_than_it_looks s USING (id)" +== 099 +-- truncate_limit: 100 +select count(*) from simple r join bigger_than_it_looks s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="bigger_than_it_looks" schema="" table="bigger_than_it_looks" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="bigger_than_it_looks" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN bigger_than_it_looks s USING (id)" +== 100 +-- truncate_limit: 100 +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from simple r join bigger_than_it_looks s u..." +== 101 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 102 +-- truncate_limit: 100 +-- The "ugly" case: increasing the number of batches during execution +-- doesn't help, so stop trying to fit in work_mem and hope for the +-- best; in this case we plan for 1 batch, increases just once and +-- then stop increasing because that didn't help at all, so we blow +-- right through the work_mem budget and hope for the best... + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 103 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 0" +== 104 +-- truncate_limit: 100 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"128kB\"" +== 105 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 106 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN extremely_skewed s USING (id)" +== 107 +-- truncate_limit: 100 +select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN extremely_skewed s USING (id)" +== 108 +-- truncate_limit: 100 +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_join_batches('\n select count(*) from simple r join extremely_skewed s using (..." +== 109 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 110 +-- truncate_limit: 100 +-- parallel with parallel-oblivious hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 111 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 112 +-- truncate_limit: 100 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"128kB\"" +== 113 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 114 +-- truncate_limit: 100 +set local enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO OFF" +== 115 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN extremely_skewed s USING (id)" +== 116 +-- truncate_limit: 100 +select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN extremely_skewed s USING (id)" +== 117 +-- truncate_limit: 100 +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_join_batches('\n select count(*) from simple r join extremely_skewed s using (..." +== 118 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 119 +-- truncate_limit: 100 +-- parallel with parallel-aware hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 120 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 1" +== 121 +-- truncate_limit: 100 +set local work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"128kB\"" +== 122 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 123 +-- truncate_limit: 100 +set local enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_parallel_hash TO ON" +== 124 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r JOIN extremely_skewed s USING (id)" +== 125 +-- truncate_limit: 100 +select count(*) from simple r join extremely_skewed s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="extremely_skewed" schema="" table="extremely_skewed" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="extremely_skewed" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r JOIN extremely_skewed s USING (id)" +== 126 +-- truncate_limit: 100 +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_join_batches('\n select count(*) from simple r join extremely_skewed s using (..." +== 127 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 128 +-- truncate_limit: 100 +-- A couple of other hash join tests unrelated to work_mem management. + +-- Check that EXPLAIN ANALYZE has data even if the leader doesn't participate +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 129 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 130 +-- truncate_limit: 100 +set local work_mem = '4MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"4MB\"" +== 131 +-- truncate_limit: 100 +set local hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL hash_mem_multiplier TO 1.0" +== 132 +-- truncate_limit: 100 +set local parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL parallel_leader_participation TO OFF" +== 133 +-- truncate_limit: 100 +select * from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hash_join_batches('\n select count(*) from simple r join simple s using (id);\n')" +== 134 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 135 +-- truncate_limit: 100 +-- Exercise rescans. We'll turn off parallel_leader_participation so +-- that we can check that instrumentation comes back correctly. + +create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE join_foo AS SELECT generate_series(1, 3) AS id, 'xxxxx'::text AS t" +== 136 +-- truncate_limit: 100 +alter table join_foo set (parallel_workers = 0) +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE join_foo SET (parallel_workers=0)" +== 137 +-- truncate_limit: 100 +create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t +-- +TABLE: name="join_bar" schema="" table="join_bar" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE join_bar AS SELECT generate_series(1, 10000) AS id, 'xxxxx'::text AS t" +== 138 +-- truncate_limit: 100 +alter table join_bar set (parallel_workers = 2) +-- +TABLE: name="join_bar" schema="" table="join_bar" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE join_bar SET (parallel_workers=2)" +== 139 +-- truncate_limit: 100 +-- multi-batch with rescan, parallel-oblivious +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 140 +-- truncate_limit: 100 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO OFF" +== 141 +-- truncate_limit: 100 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 142 +-- truncate_limit: 100 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 143 +-- truncate_limit: 100 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 144 +-- truncate_limit: 100 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 145 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 146 +-- truncate_limit: 100 +set enable_material = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_material TO OFF" +== 147 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 148 +-- truncate_limit: 100 +set work_mem = '64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 149 +-- truncate_limit: 100 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO 1.0" +== 150 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM join_foo LEFT JOIN (SELECT b1.id, b1.t FROM join_bar b1 ..." +== 151 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM join_foo LEFT JOIN (SELECT ... FROM join_bar b1 JOIN join_bar b2 USING (id)) ss O..." +== 152 +-- truncate_limit: 100 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from join_foo\n left join (select b1.id, ..." +== 153 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 154 +-- truncate_limit: 100 +-- single-batch with rescan, parallel-oblivious +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 155 +-- truncate_limit: 100 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO OFF" +== 156 +-- truncate_limit: 100 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 157 +-- truncate_limit: 100 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 158 +-- truncate_limit: 100 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 159 +-- truncate_limit: 100 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 160 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 161 +-- truncate_limit: 100 +set enable_material = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_material TO OFF" +== 162 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 163 +-- truncate_limit: 100 +set work_mem = '4MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"4MB\"" +== 164 +-- truncate_limit: 100 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO 1.0" +== 165 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM join_foo LEFT JOIN (SELECT b1.id, b1.t FROM join_bar b1 ..." +== 166 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM join_foo LEFT JOIN (SELECT ... FROM join_bar b1 JOIN join_bar b2 USING (id)) ss O..." +== 167 +-- truncate_limit: 100 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from join_foo\n left join (select b1.id, ..." +== 168 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 169 +-- truncate_limit: 100 +-- multi-batch with rescan, parallel-aware +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 170 +-- truncate_limit: 100 +set enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO ON" +== 171 +-- truncate_limit: 100 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 172 +-- truncate_limit: 100 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 173 +-- truncate_limit: 100 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 174 +-- truncate_limit: 100 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 175 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 176 +-- truncate_limit: 100 +set enable_material = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_material TO OFF" +== 177 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 178 +-- truncate_limit: 100 +set work_mem = '64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 179 +-- truncate_limit: 100 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO 1.0" +== 180 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM join_foo LEFT JOIN (SELECT b1.id, b1.t FROM join_bar b1 ..." +== 181 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM join_foo LEFT JOIN (SELECT ... FROM join_bar b1 JOIN join_bar b2 USING (id)) ss O..." +== 182 +-- truncate_limit: 100 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from join_foo\n left join (select b1.id, ..." +== 183 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 184 +-- truncate_limit: 100 +-- single-batch with rescan, parallel-aware +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 185 +-- truncate_limit: 100 +set enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO ON" +== 186 +-- truncate_limit: 100 +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 187 +-- truncate_limit: 100 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 188 +-- truncate_limit: 100 +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 189 +-- truncate_limit: 100 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 190 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 191 +-- truncate_limit: 100 +set enable_material = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_material TO OFF" +== 192 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 193 +-- truncate_limit: 100 +set work_mem = '4MB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"4MB\"" +== 194 +-- truncate_limit: 100 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO 1.0" +== 195 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM join_foo LEFT JOIN (SELECT b1.id, b1.t FROM join_bar b1 ..." +== 196 +-- truncate_limit: 100 +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 +-- +TABLE: name="join_foo" schema="" table="join_foo" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +TABLE: name="join_bar" schema="" table="join_bar" ctx=Select +ALIAS: "b1"="join_bar" +ALIAS: "b2"="join_bar" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM join_foo LEFT JOIN (SELECT ... FROM join_bar b1 JOIN join_bar b2 USING (id)) ss O..." +== 197 +-- truncate_limit: 100 +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; +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select count(*) from join_foo\n left join (select b1.id, ..." +== 198 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 199 +-- truncate_limit: 100 +-- A full outer join where every record is matched. + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 200 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 0" +== 201 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r FULL JOIN simple s USING (id)" +== 202 +-- truncate_limit: 100 +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r FULL JOIN simple s USING (id)" +== 203 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 204 +-- truncate_limit: 100 +-- parallelism not possible with parallel-oblivious full hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 205 +-- truncate_limit: 100 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO OFF" +== 206 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 207 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r FULL JOIN simple s USING (id)" +== 208 +-- truncate_limit: 100 +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r FULL JOIN simple s USING (id)" +== 209 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 210 +-- truncate_limit: 100 +-- parallelism is possible with parallel-aware full hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 211 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 212 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r FULL JOIN simple s USING (id)" +== 213 +-- truncate_limit: 100 +select count(*) from simple r full outer join simple s using (id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r FULL JOIN simple s USING (id)" +== 214 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 215 +-- truncate_limit: 100 +-- A full outer join where every record is not matched. + +-- non-parallel +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 216 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 0" +== 217 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r FULL JOIN simple s ON r.id = (0 - s.id)" +== 218 +-- truncate_limit: 100 +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r FULL JOIN simple s ON r.id = (0 - s.id)" +== 219 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 220 +-- truncate_limit: 100 +-- parallelism not possible with parallel-oblivious full hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 221 +-- truncate_limit: 100 +set enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO OFF" +== 222 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 223 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r FULL JOIN simple s ON r.id = (0 - s.id)" +== 224 +-- truncate_limit: 100 +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r FULL JOIN simple s ON r.id = (0 - s.id)" +== 225 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 226 +-- truncate_limit: 100 +-- parallelism is possible with parallel-aware full hash join +savepoint settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 227 +-- truncate_limit: 100 +set local max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 2" +== 228 +-- truncate_limit: 100 +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM simple r FULL JOIN simple s ON r.id = (0 - s.id)" +== 229 +-- truncate_limit: 100 +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id) +-- +TABLE: name="simple" schema="" table="simple" ctx=Select +TABLE: name="simple" schema="" table="simple" ctx=Select +ALIAS: "r"="simple" +ALIAS: "s"="simple" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM simple r FULL JOIN simple s ON r.id = (0 - s.id)" +== 230 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 231 +-- truncate_limit: 100 +-- 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 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 232 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 233 +-- truncate_limit: 100 +set enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO ON" +== 234 +-- truncate_limit: 100 +set work_mem = '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"128kB\"" +== 235 +-- truncate_limit: 100 +set hash_mem_multiplier = 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO 1.0" +== 236 +-- truncate_limit: 100 +explain (costs off) + select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id) +-- +TABLE: name="wide" schema="" table="wide" ctx=Select +TABLE: name="wide" schema="" table="wide" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT length(max(s.t)) FROM wide LEFT JOIN (SELECT id, COALESCE(t, '') || ''..." +== 237 +-- truncate_limit: 100 +select length(max(s.t)) +from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id) +-- +TABLE: name="wide" schema="" table="wide" ctx=Select +TABLE: name="wide" schema="" table="wide" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(max(s.t)) FROM wide LEFT JOIN (SELECT ... FROM wide) s USING (id)" +== 238 +-- truncate_limit: 100 +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); +$$) +-- +FUNCTION: name="hash_join_batches" function="hash_join_batches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hash_join_batches('\n select length(max(s.t))\n from wide left join (select id, c..." +== 239 +-- truncate_limit: 100 +rollback to settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 240 +-- truncate_limit: 100 +-- Hash join reuses the HOT status bit to indicate match status. This can only +-- be guaranteed to produce correct results if all the hash join tuple match +-- bits are reset before reuse. This is done upon loading them into the +-- hashtable. +SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 241 +-- truncate_limit: 100 +SET enable_parallel_hash = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO ON" +== 242 +-- truncate_limit: 100 +SET min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 243 +-- truncate_limit: 100 +SET parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 244 +-- truncate_limit: 100 +SET parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 245 +-- truncate_limit: 100 +CREATE TABLE hjtest_matchbits_t1(id int) +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hjtest_matchbits_t1 (id int)" +== 246 +-- truncate_limit: 100 +CREATE TABLE hjtest_matchbits_t2(id int) +-- +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hjtest_matchbits_t2 (id int)" +== 247 +-- truncate_limit: 100 +INSERT INTO hjtest_matchbits_t1 VALUES (1) +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_matchbits_t1 VALUES (1)" +== 248 +-- truncate_limit: 100 +INSERT INTO hjtest_matchbits_t2 VALUES (2) +-- +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_matchbits_t2 VALUES (2)" +== 249 +-- truncate_limit: 100 +-- Update should create a HOT tuple. If this status bit isn't cleared, we won't +-- correctly emit the NULL-extended unmatching tuple in full hash join. +UPDATE hjtest_matchbits_t2 set id = 2 +-- +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hjtest_matchbits_t2 SET id = 2" +== 250 +-- truncate_limit: 100 +SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id + ORDER BY t1.id +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=Select +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=Select +ALIAS: "t1"="hjtest_matchbits_t1" +ALIAS: "t2"="hjtest_matchbits_t2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id ORDER BY t..." +== 251 +-- truncate_limit: 100 +-- Test serial full hash join. +-- Resetting parallel_setup_cost should force a serial plan. +-- Just to be safe, however, set enable_parallel_hash to off, as parallel full +-- hash joins are only supported with shared hashtables. +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 252 +-- truncate_limit: 100 +SET enable_parallel_hash = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_hash TO OFF" +== 253 +-- truncate_limit: 100 +SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id +-- +TABLE: name="hjtest_matchbits_t1" schema="" table="hjtest_matchbits_t1" ctx=Select +TABLE: name="hjtest_matchbits_t2" schema="" table="hjtest_matchbits_t2" ctx=Select +ALIAS: "t1"="hjtest_matchbits_t1" +ALIAS: "t2"="hjtest_matchbits_t2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id" +== 254 +-- truncate_limit: 100 +ROLLBACK TO settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 255 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 256 +-- truncate_limit: 100 +-- 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 +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 257 +-- truncate_limit: 100 +SET LOCAL enable_sort = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_sort TO OFF" +== 258 +-- truncate_limit: 100 +-- avoid mergejoins +SET LOCAL from_collapse_limit = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL from_collapse_limit TO 1" +== 259 +-- truncate_limit: 100 +-- allows easy changing of join order + +CREATE TABLE hjtest_1 (a text, b int, id int, c bool) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hjtest_1 (a text, b int, id int, c bool)" +== 260 +-- truncate_limit: 100 +CREATE TABLE hjtest_2 (a bool, id int, b text, c int) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hjtest_2 (a bool, id int, b text, c int)" +== 261 +-- truncate_limit: 100 +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 2, 1, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_1 (a, b, id, c) VALUES ('text', 2, 1, false)" +== 262 +-- truncate_limit: 100 +-- matches +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 2, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_1 (a, b, id, c) VALUES ('text', 1, 2, false)" +== 263 +-- truncate_limit: 100 +-- fails id join condition +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 20, 1, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_1 (a, b, id, c) VALUES ('text', 20, 1, false)" +== 264 +-- truncate_limit: 100 +-- fails < 50 +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 1, false) +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_1 (a, b, id, c) VALUES ('text', 1, 1, false)" +== 265 +-- truncate_limit: 100 +-- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 2) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_2 (a, id, b, c) VALUES (true, 1, 'another', 2)" +== 266 +-- truncate_limit: 100 +-- matches +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 3, 'another', 7) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_2 (a, id, b, c) VALUES (true, 3, 'another', 7)" +== 267 +-- truncate_limit: 100 +-- fails id join condition +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 90) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_2 (a, id, b, c) VALUES (true, 1, 'another', 90)" +== 268 +-- truncate_limit: 100 +-- fails < 55 +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 3) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_2 (a, id, b, c) VALUES (true, 1, 'another', 3)" +== 269 +-- truncate_limit: 100 +-- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'text', 1) +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hjtest_2 (a, id, b, c) VALUES (true, 1, 'text', 1)" +== 270 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT hjtest_1.a AS a1, hjtest_2.a AS a2, hjtest_1.tableoid::regcla..." +== 271 +-- truncate_limit: 100 +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 +-- +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hjtest_1, hjtest_2 WHERE ..." +== 272 +-- truncate_limit: 100 +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 +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT hjtest_1.a AS a1, hjtest_2.a AS a2, hjtest_1.tableoid::regcla..." +== 273 +-- truncate_limit: 100 +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 +-- +TABLE: name="hjtest_2" schema="" table="hjtest_2" ctx=Select +TABLE: name="hjtest_1" schema="" table="hjtest_1" ctx=Select +FILTER: schema="" table="hjtest_1" column="id" +FILTER: schema="" table="hjtest_2" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM hjtest_2, hjtest_1 WHERE ..." +== 274 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 275 +-- truncate_limit: 100 +-- Verify that we behave sanely when the inner hash keys contain parameters +-- (that is, outer or lateral references). This situation has to defeat +-- re-use of the inner hash table across rescans. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 276 +-- truncate_limit: 100 +set local enable_hashjoin = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_hashjoin TO ON" +== 277 +-- truncate_limit: 100 +explain (costs off) +select i8.q2, ss.* from +int8_tbl i8, +lateral (select t1.fivethous, i4.f1 from tenk1 t1 join int4_tbl i4 + on t1.fivethous = i4.f1+i8.q2 order by 1,2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="tenk1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT i8.q2, ss.* FROM int8_tbl i8, LATERAL (SELECT t1.fivethous, i4.f1 FROM..." +== 278 +-- truncate_limit: 100 +select i8.q2, ss.* from +int8_tbl i8, +lateral (select t1.fivethous, i4.f1 from tenk1 t1 join int4_tbl i4 + on t1.fivethous = i4.f1+i8.q2 order by 1,2) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +ALIAS: "i8"="int8_tbl" +ALIAS: "t1"="tenk1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl i8, LATERAL (SELECT ... FROM tenk1 t1 JOIN int4_tbl i4 ON t1.fivethous =..." +== 279 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/json.metadata.json b/parser/testdata/summary_truncate/postgres_regress/json.metadata.json new file mode 100644 index 0000000..15b4f09 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/json.metadata.json @@ -0,0 +1,464 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/json.test b/parser/testdata/summary_truncate/postgres_regress/json.test new file mode 100644 index 0000000..051c7d4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/json.test @@ -0,0 +1,3486 @@ +== 001 +-- truncate_limit: 100 +-- Strings. +SELECT '""'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"\"'::pg_catalog.json" +== 002 +-- truncate_limit: 100 +-- OK. +SELECT $$''$$::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''''''::pg_catalog.json" +== 003 +-- truncate_limit: 100 +-- ERROR, single quotes are not allowed +SELECT '"abc"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"abc\"'::pg_catalog.json" +== 004 +-- truncate_limit: 100 +-- OK +SELECT '"abc'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"abc'::pg_catalog.json" +== 005 +-- truncate_limit: 100 +-- ERROR, quotes not closed +SELECT '"abc +def"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"abc\ndef\"'::pg_catalog.json" +== 006 +-- truncate_limit: 100 +-- ERROR, unescaped newline in string constant +SELECT '"\n\"\\"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\n\\\\\"\\\\\\\\\"'::pg_catalog.json" +== 007 +-- truncate_limit: 100 +-- OK, legal escapes +SELECT '"\v"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\v\"'::pg_catalog.json" +== 008 +-- truncate_limit: 100 +-- ERROR, not a valid JSON escape + +-- Check fast path for longer strings (at least 16 bytes long) +SELECT ('"'||repeat('.', 12)||'abc"')::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (('\"' || repeat('.', 12)) || 'abc\"')::pg_catalog.json" +== 009 +-- truncate_limit: 100 +-- OK +SELECT ('"'||repeat('.', 12)||'abc\n"')::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (('\"' || repeat('.', 12)) || E'abc\\\\n\"')::pg_catalog.json" +== 010 +-- truncate_limit: 100 +-- OK, legal escapes + +-- see json_encoding test for input with unicode escapes + +-- Numbers. +SELECT '1'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::pg_catalog.json" +== 011 +-- truncate_limit: 100 +-- OK +SELECT '0'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0'::pg_catalog.json" +== 012 +-- truncate_limit: 100 +-- OK +SELECT '01'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01'::pg_catalog.json" +== 013 +-- truncate_limit: 100 +-- ERROR, not valid according to JSON spec +SELECT '0.1'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1'::pg_catalog.json" +== 014 +-- truncate_limit: 100 +-- OK +SELECT '9223372036854775808'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775808'::pg_catalog.json" +== 015 +-- truncate_limit: 100 +-- OK, even though it's too large for int8 +SELECT '1e100'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1e100'::pg_catalog.json" +== 016 +-- truncate_limit: 100 +-- OK +SELECT '1.3e100'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.3e100'::pg_catalog.json" +== 017 +-- truncate_limit: 100 +-- OK +SELECT '1f2'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1f2'::pg_catalog.json" +== 018 +-- truncate_limit: 100 +-- ERROR +SELECT '0.x1'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.x1'::pg_catalog.json" +== 019 +-- truncate_limit: 100 +-- ERROR +SELECT '1.3ex100'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.3ex100'::pg_catalog.json" +== 020 +-- truncate_limit: 100 +-- ERROR + +-- Arrays. +SELECT '[]'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::pg_catalog.json" +== 021 +-- truncate_limit: 100 +-- OK +SELECT '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 022 +-- truncate_limit: 100 +-- OK +SELECT '[1,2]'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2]'::pg_catalog.json" +== 023 +-- truncate_limit: 100 +-- OK +SELECT '[1,2,]'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,]'::pg_catalog.json" +== 024 +-- truncate_limit: 100 +-- ERROR, trailing comma +SELECT '[1,2'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2'::pg_catalog.json" +== 025 +-- truncate_limit: 100 +-- ERROR, no closing bracket +SELECT '[1,[2]'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,[2]'::pg_catalog.json" +== 026 +-- truncate_limit: 100 +-- ERROR, no closing bracket + +-- Objects. +SELECT '{}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::pg_catalog.json" +== 027 +-- truncate_limit: 100 +-- OK +SELECT '{"abc"}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\"}'::pg_catalog.json" +== 028 +-- truncate_limit: 100 +-- ERROR, no value +SELECT '{"abc":1}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1}'::pg_catalog.json" +== 029 +-- truncate_limit: 100 +-- OK +SELECT '{1:"abc"}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{1:\"abc\"}'::pg_catalog.json" +== 030 +-- truncate_limit: 100 +-- ERROR, keys must be strings +SELECT '{"abc",1}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\",1}'::pg_catalog.json" +== 031 +-- truncate_limit: 100 +-- ERROR, wrong separator +SELECT '{"abc"=1}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\"=1}'::pg_catalog.json" +== 032 +-- truncate_limit: 100 +-- ERROR, totally wrong separator +SELECT '{"abc"::1}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\"::1}'::pg_catalog.json" +== 033 +-- truncate_limit: 100 +-- ERROR, another wrong separator +SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1,\"def\":2,\"ghi\":[3,4],\"hij\":{\"klm\":5,\"nop\":[6]}}'::pg_catalog.json" +== 034 +-- truncate_limit: 100 +-- OK +SELECT '{"abc":1:2}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1:2}'::pg_catalog.json" +== 035 +-- truncate_limit: 100 +-- ERROR, colon in wrong spot +SELECT '{"abc":1,3}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1,3}'::pg_catalog.json" +== 036 +-- truncate_limit: 100 +-- ERROR, no value + +-- Recursion. +SET max_stack_depth = '100kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_stack_depth TO \"100kB\"" +== 037 +-- truncate_limit: 100 +SELECT repeat('[', 10000)::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT repeat('[', 10000)::pg_catalog.json" +== 038 +-- truncate_limit: 100 +SELECT repeat('{"a":', 10000)::json +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT repeat('{\"a\":', 10000)::pg_catalog.json" +== 039 +-- truncate_limit: 100 +RESET max_stack_depth +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_stack_depth" +== 040 +-- truncate_limit: 100 +-- Miscellaneous stuff. +SELECT 'true'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true'::pg_catalog.json" +== 041 +-- truncate_limit: 100 +-- OK +SELECT 'false'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'false'::pg_catalog.json" +== 042 +-- truncate_limit: 100 +-- OK +SELECT 'null'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'null'::pg_catalog.json" +== 043 +-- truncate_limit: 100 +-- OK +SELECT ' true '::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' true '::pg_catalog.json" +== 044 +-- truncate_limit: 100 +-- OK, even with extra whitespace +SELECT 'true false'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true false'::pg_catalog.json" +== 045 +-- truncate_limit: 100 +-- ERROR, too many values +SELECT 'true, false'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true, false'::pg_catalog.json" +== 046 +-- truncate_limit: 100 +-- ERROR, too many values +SELECT 'truf'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'truf'::pg_catalog.json" +== 047 +-- truncate_limit: 100 +-- ERROR, not a keyword +SELECT 'trues'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'trues'::pg_catalog.json" +== 048 +-- truncate_limit: 100 +-- ERROR, not a keyword +SELECT ''::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::pg_catalog.json" +== 049 +-- truncate_limit: 100 +-- ERROR, no value +SELECT ' '::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' '::pg_catalog.json" +== 050 +-- truncate_limit: 100 +-- ERROR, no value + +-- Multi-line JSON input to check ERROR reporting +SELECT '{ + "one": 1, + "two":"two", + "three": + true}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\n\t\t\"one\": 1,\n\t\t\"two\":\"two\",\n\t\t\"three\":\n\t\ttrue}'::pg_catalog.json" +== 051 +-- truncate_limit: 100 +-- OK +SELECT '{ + "one": 1, + "two":,"two", -- ERROR extraneous comma before field "two" + "three": + true}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 052 +-- truncate_limit: 100 +SELECT '{ + "one": 1, + "two":"two", + "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 053 +-- truncate_limit: 100 +-- ERROR missing value for last field + +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'json') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{\"a\":true}', 'json')" +== 054 +-- truncate_limit: 100 +select pg_input_is_valid('{"a":true', 'json') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{\"a\":true', 'json')" +== 055 +-- truncate_limit: 100 +select * from pg_input_error_info('{"a":true', 'json') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{\"a\":true', 'json')" +== 056 +-- truncate_limit: 100 +--constructors +-- array_to_json + +SELECT array_to_json(array(select 1 as a)) +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_json(ARRAY(SELECT 1 AS a))" +== 057 +-- truncate_limit: 100 +SELECT array_to_json(array_agg(q),false) from (select x as b, x * 2 as c from generate_series(1,3) x) q +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_json(array_agg(q), false) FROM (SELECT ... FROM generate_series(1, 3) x) q" +== 058 +-- truncate_limit: 100 +SELECT array_to_json(array_agg(q),true) from (select x as b, x * 2 as c from generate_series(1,3) x) q +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_json(array_agg(q), true) FROM (SELECT ... FROM generate_series(1, 3) x) q" +== 059 +-- truncate_limit: 100 +SELECT array_to_json(array_agg(q),false) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2) x, generate_series(4, 5) y) q" +== 060 +-- truncate_limit: 100 +SELECT array_to_json(array_agg(x),false) from generate_series(5,10) x +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_json(array_agg(x), false) FROM generate_series(5, 10) x" +== 061 +-- truncate_limit: 100 +SELECT array_to_json('{{1,5},{99,100}}'::int[]) +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_json('{{1,5},{99,100}}'::int[])" +== 062 +-- truncate_limit: 100 +-- row_to_json +SELECT row_to_json(row(1,'foo')) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ROW(1, 'foo'))" +== 063 +-- truncate_limit: 100 +SELECT row_to_json(q) +FROM (SELECT $$a$$ || x AS b, + y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT ... FROM generate_series(1, 2) x, generate_series(4, 5) y) q" +== 064 +-- truncate_limit: 100 +SELECT row_to_json(q,true) +FROM (SELECT $$a$$ || x AS b, + y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2) x, generate_series(4, 5) y) q" +== 065 +-- truncate_limit: 100 +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE rows AS SELECT x, 'txt' || x AS y FROM generate_series(1, 3) x" +== 066 +-- truncate_limit: 100 +SELECT row_to_json(q,true) +FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q, true) FROM rows q" +== 067 +-- truncate_limit: 100 +SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),false) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ROW((SELECT array_agg(x) AS d FROM generate_series(5, 10) x)), false)" +== 068 +-- truncate_limit: 100 +-- anyarray column + +analyze rows +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE rows" +== 069 +-- truncate_limit: 100 +select attname, to_json(histogram_bounds) histogram_bounds +from pg_stats +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1 +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FILTER: schema="" table="" column="tablename" +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +TRUNCATED: "SELECT attname, to_json(histogram_bounds) AS histogram_bounds FROM pg_stats WHERE ... ORDER BY 1" +== 070 +-- truncate_limit: 100 +-- to_json, timestamps + +select to_json(timestamp '2014-05-28 12:22:35.614298') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('2014-05-28 12:22:35.614298'::timestamp)" +== 071 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 072 +-- truncate_limit: 100 +SET LOCAL TIME ZONE 10.5 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO 10.5" +== 073 +-- truncate_limit: 100 +select to_json(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('2014-05-28 12:22:35.614298-04'::timestamptz)" +== 074 +-- truncate_limit: 100 +SET LOCAL TIME ZONE -8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO -8" +== 075 +-- truncate_limit: 100 +select to_json(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('2014-05-28 12:22:35.614298-04'::timestamptz)" +== 076 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 077 +-- truncate_limit: 100 +select to_json(date '2014-05-28') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('2014-05-28'::date)" +== 078 +-- truncate_limit: 100 +select to_json(date 'Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('Infinity'::date)" +== 079 +-- truncate_limit: 100 +select to_json(date '-Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('-Infinity'::date)" +== 080 +-- truncate_limit: 100 +select to_json(timestamp 'Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('Infinity'::timestamp)" +== 081 +-- truncate_limit: 100 +select to_json(timestamp '-Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('-Infinity'::timestamp)" +== 082 +-- truncate_limit: 100 +select to_json(timestamptz 'Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('Infinity'::timestamptz)" +== 083 +-- truncate_limit: 100 +select to_json(timestamptz '-Infinity') +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_json('-Infinity'::timestamptz)" +== 084 +-- truncate_limit: 100 +--json_agg + +SELECT json_agg(q) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="json_agg" function="json_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_agg(q) FROM (SELECT ... FROM generate_series(1, 2) x, generate_series(4, 5) y) q" +== 085 +-- truncate_limit: 100 +SELECT json_agg(q ORDER BY x, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="json_agg" function="json_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_agg(q ORDER BY x, y) FROM rows q" +== 086 +-- truncate_limit: 100 +UPDATE rows SET x = NULL WHERE x = 1 +-- +TABLE: name="rows" schema="" table="rows" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rows SET x = NULL WHERE x = 1" +== 087 +-- truncate_limit: 100 +SELECT json_agg(q ORDER BY x NULLS FIRST, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="json_agg" function="json_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_agg(q ORDER BY x NULLS FIRST, y) FROM rows q" +== 088 +-- truncate_limit: 100 +-- non-numeric output +SELECT row_to_json(q) +FROM (SELECT 'NaN'::float8 AS "float8field") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT 'NaN'::float8 AS float8field) q" +== 089 +-- truncate_limit: 100 +SELECT row_to_json(q) +FROM (SELECT 'Infinity'::float8 AS "float8field") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT 'Infinity'::float8 AS float8field) q" +== 090 +-- truncate_limit: 100 +SELECT row_to_json(q) +FROM (SELECT '-Infinity'::float8 AS "float8field") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT '-Infinity'::float8 AS float8field) q" +== 091 +-- truncate_limit: 100 +-- json input +SELECT row_to_json(q) +FROM (SELECT '{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::json AS "jsonfield") q +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT ...) q" +== 092 +-- truncate_limit: 100 +-- json extraction functions + +CREATE TEMP TABLE test_json ( + json_type text, + test_json json +) +-- +TABLE: name="test_json" schema="" table="test_json" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_json (json_type text, test_json pg_catalog.json)" +== 093 +-- truncate_limit: 100 +INSERT INTO test_json VALUES +('scalar','"a scalar"'), +('array','["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}]'), +('object','{"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}}') +-- +TABLE: name="test_json" schema="" table="test_json" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_json VALUES (...)" +== 094 +-- truncate_limit: 100 +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'scalar' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'x' FROM test_json WHERE json_type = 'scalar'" +== 095 +-- truncate_limit: 100 +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'x' FROM test_json WHERE json_type = 'array'" +== 096 +-- truncate_limit: 100 +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'x' FROM test_json WHERE json_type = 'object'" +== 097 +-- truncate_limit: 100 +SELECT test_json->'field2' +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'field2' FROM test_json WHERE json_type = 'object'" +== 098 +-- truncate_limit: 100 +SELECT test_json->>'field2' +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field2' FROM test_json WHERE json_type = 'object'" +== 099 +-- truncate_limit: 100 +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'scalar' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 2 FROM test_json WHERE json_type = 'scalar'" +== 100 +-- truncate_limit: 100 +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 2 FROM test_json WHERE json_type = 'array'" +== 101 +-- truncate_limit: 100 +SELECT test_json -> -1 +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> -1 FROM test_json WHERE json_type = 'array'" +== 102 +-- truncate_limit: 100 +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 2 FROM test_json WHERE json_type = 'object'" +== 103 +-- truncate_limit: 100 +SELECT test_json->>2 +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 2 FROM test_json WHERE json_type = 'array'" +== 104 +-- truncate_limit: 100 +SELECT test_json ->> 6 FROM test_json WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 6 FROM test_json WHERE json_type = 'array'" +== 105 +-- truncate_limit: 100 +SELECT test_json ->> 7 FROM test_json WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 7 FROM test_json WHERE json_type = 'array'" +== 106 +-- truncate_limit: 100 +SELECT test_json ->> 'field4' FROM test_json WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field4' FROM test_json WHERE json_type = 'object'" +== 107 +-- truncate_limit: 100 +SELECT test_json ->> 'field5' FROM test_json WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field5' FROM test_json WHERE json_type = 'object'" +== 108 +-- truncate_limit: 100 +SELECT test_json ->> 'field6' FROM test_json WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field6' FROM test_json WHERE json_type = 'object'" +== 109 +-- truncate_limit: 100 +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'scalar' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT json_object_keys(test_json) FROM test_json WHERE json_type = 'scalar'" +== 110 +-- truncate_limit: 100 +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT json_object_keys(test_json) FROM test_json WHERE json_type = 'array'" +== 111 +-- truncate_limit: 100 +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT json_object_keys(test_json) FROM test_json WHERE json_type = 'object'" +== 112 +-- truncate_limit: 100 +-- test extending object_keys resultset - initial resultset size is 256 + +select count(*) from + (select json_object_keys(json_object(array_agg(g))) + from (select unnest(array['f'||n,n::text])as g + from generate_series(1,300) as n) x ) y +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="json_object_keys" function="json_object_keys" schema="" ctx=Call +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT ... FROM (SELECT ... FROM generate_series(1, 300) n) x) y" +== 113 +-- truncate_limit: 100 +-- nulls + +select (test_json->'field3') is null as expect_false +from test_json +where json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'field3' IS NULL AS expect_false FROM test_json WHERE json_type = 'object'" +== 114 +-- truncate_limit: 100 +select (test_json->>'field3') is null as expect_true +from test_json +where json_type = 'object' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field3' IS NULL AS expect_true FROM test_json WHERE json_type = 'object'" +== 115 +-- truncate_limit: 100 +select (test_json->3) is null as expect_false +from test_json +where json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 3 IS NULL AS expect_false FROM test_json WHERE json_type = 'array'" +== 116 +-- truncate_limit: 100 +select (test_json->>3) is null as expect_true +from test_json +where json_type = 'array' +-- +TABLE: name="test_json" schema="" table="test_json" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 3 IS NULL AS expect_true FROM test_json WHERE json_type = 'array'" +== 117 +-- truncate_limit: 100 +-- corner cases + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json -> NULL::text" +== 118 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::int +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json -> NULL::int" +== 119 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json -> 1" +== 120 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> -1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json -> -1" +== 121 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json -> 'z'" +== 122 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json -> ''" +== 123 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json -> 1" +== 124 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json -> 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json -> 3" +== 125 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json -> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json -> 'z'" +== 126 +-- truncate_limit: 100 +select '{"a": "c", "b": null}'::json -> 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": \"c\", \"b\": null}'::pg_catalog.json -> 'b'" +== 127 +-- truncate_limit: 100 +select '"foo"'::json -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json -> 1" +== 128 +-- truncate_limit: 100 +select '"foo"'::json -> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json -> 'z'" +== 129 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json ->> NULL::text" +== 130 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::int +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json ->> NULL::int" +== 131 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json ->> 1" +== 132 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json ->> 'z'" +== 133 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json ->> ''" +== 134 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json ->> 1" +== 135 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json ->> 3" +== 136 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json ->> 'z'" +== 137 +-- truncate_limit: 100 +select '{"a": "c", "b": null}'::json ->> 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": \"c\", \"b\": null}'::pg_catalog.json ->> 'b'" +== 138 +-- truncate_limit: 100 +select '"foo"'::json ->> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json ->> 1" +== 139 +-- truncate_limit: 100 +select '"foo"'::json ->> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json ->> 'z'" +== 140 +-- truncate_limit: 100 +-- array length + +SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_array_length('[1,2,3,{\"f1\":1,\"f2\":[5,6]},4]')" +== 141 +-- truncate_limit: 100 +SELECT json_array_length('[]') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_array_length('[]')" +== 142 +-- truncate_limit: 100 +SELECT json_array_length('{"f1":1,"f2":[5,6]}') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_array_length('{\"f1\":1,\"f2\":[5,6]}')" +== 143 +-- truncate_limit: 100 +SELECT json_array_length('4') +-- +FUNCTION: name="json_array_length" function="json_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_array_length('4')" +== 144 +-- truncate_limit: 100 +-- each + +select json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null}') +-- +FUNCTION: name="json_each" function="json_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_each('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null}')" +== 145 +-- truncate_limit: 100 +select * from json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="json_each" function="json_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_each('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null,\"f5\":99,\"f6\":\"stringy\"}') q" +== 146 +-- truncate_limit: 100 +select json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}') +-- +FUNCTION: name="json_each_text" function="json_each_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_each_text('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null,\"f5\":\"null\"}')" +== 147 +-- truncate_limit: 100 +select * from json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="json_each_text" function="json_each_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_each_text('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null,\"f5\":99,\"f6\":\"stringy\"}') q" +== 148 +-- truncate_limit: 100 +-- extract_path, extract_path_as_text + +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f4', 'f6')" +== 149 +-- truncate_limit: 100 +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2')" +== 150 +-- truncate_limit: 100 +select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 0::text)" +== 151 +-- truncate_limit: 100 +select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 1::text)" +== 152 +-- truncate_limit: 100 +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path_text('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f4', 'f6')" +== 153 +-- truncate_limit: 100 +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path_text('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2')" +== 154 +-- truncate_limit: 100 +select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path_text('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 0::text)" +== 155 +-- truncate_limit: 100 +select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path_text('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 1::text)" +== 156 +-- truncate_limit: 100 +-- extract_path nulls + +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_false +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 157 +-- truncate_limit: 100 +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_true +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 158 +-- truncate_limit: 100 +select json_extract_path('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_false +-- +FUNCTION: name="json_extract_path" function="json_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path('{\"f2\":{\"f3\":1},\"f4\":[0,1,2,null]}', 'f4', '3') IS NULL AS expect_false" +== 159 +-- truncate_limit: 100 +select json_extract_path_text('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_true +-- +FUNCTION: name="json_extract_path_text" function="json_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_extract_path_text('{\"f2\":{\"f3\":1},\"f4\":[0,1,2,null]}', 'f4', '3') IS NULL AS expect_true" +== 160 +-- truncate_limit: 100 +-- extract_path operators + +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f4','f6'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #> ARRAY['f4', 'f6']" +== 161 +-- truncate_limit: 100 +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #> ARRAY['f2']" +== 162 +-- truncate_limit: 100 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #> ARRAY['f2', '0']" +== 163 +-- truncate_limit: 100 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','1'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #> ARRAY['f2', '1']" +== 164 +-- truncate_limit: 100 +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f4','f6'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #>> ARRAY['f4', 'f6']" +== 165 +-- truncate_limit: 100 +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #>> ARRAY['f2']" +== 166 +-- truncate_limit: 100 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #>> ARRAY['f2', '0']" +== 167 +-- truncate_limit: 100 +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','1'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::pg_catalog.json #>> ARRAY['f2', '1']" +== 168 +-- truncate_limit: 100 +-- corner cases for same +select '{"a": {"b":{"c": "foo"}}}'::json #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> '{}'" +== 169 +-- truncate_limit: 100 +select '[1,2,3]'::json #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::pg_catalog.json #> '{}'" +== 170 +-- truncate_limit: 100 +select '"foo"'::json #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json #> '{}'" +== 171 +-- truncate_limit: 100 +select '42'::json #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::pg_catalog.json #> '{}'" +== 172 +-- truncate_limit: 100 +select 'null'::json #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'null'::pg_catalog.json #> '{}'" +== 173 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> ARRAY['a']" +== 174 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', null] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> ARRAY['a', NULL]" +== 175 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', ''] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> ARRAY['a', '']" +== 176 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> ARRAY['a', 'b']" +== 177 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> ARRAY['a', 'b', 'c']" +== 178 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c','d'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> ARRAY['a', 'b', 'c', 'd']" +== 179 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','z','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #> ARRAY['a', 'z', 'c']" +== 180 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json #> ARRAY['a', '1', 'b']" +== 181 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json #> ARRAY['a', 'z', 'b']" +== 182 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json #> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json #> ARRAY['1', 'b']" +== 183 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json #> array['z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json #> ARRAY['z', 'b']" +== 184 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": null}]'::json #> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": null}]'::pg_catalog.json #> ARRAY['1', 'b']" +== 185 +-- truncate_limit: 100 +select '"foo"'::json #> array['z'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json #> ARRAY['z']" +== 186 +-- truncate_limit: 100 +select '42'::json #> array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::pg_catalog.json #> ARRAY['f2']" +== 187 +-- truncate_limit: 100 +select '42'::json #> array['0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::pg_catalog.json #> ARRAY['0']" +== 188 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> '{}'" +== 189 +-- truncate_limit: 100 +select '[1,2,3]'::json #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::pg_catalog.json #>> '{}'" +== 190 +-- truncate_limit: 100 +select '"foo"'::json #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json #>> '{}'" +== 191 +-- truncate_limit: 100 +select '42'::json #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::pg_catalog.json #>> '{}'" +== 192 +-- truncate_limit: 100 +select 'null'::json #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'null'::pg_catalog.json #>> '{}'" +== 193 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> ARRAY['a']" +== 194 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', null] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> ARRAY['a', NULL]" +== 195 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', ''] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> ARRAY['a', '']" +== 196 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> ARRAY['a', 'b']" +== 197 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> ARRAY['a', 'b', 'c']" +== 198 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c','d'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> ARRAY['a', 'b', 'c', 'd']" +== 199 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','z','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::pg_catalog.json #>> ARRAY['a', 'z', 'c']" +== 200 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json #>> ARRAY['a', '1', 'b']" +== 201 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::pg_catalog.json #>> ARRAY['a', 'z', 'b']" +== 202 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json #>> ARRAY['1', 'b']" +== 203 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::pg_catalog.json #>> ARRAY['z', 'b']" +== 204 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": null}]'::json #>> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": null}]'::pg_catalog.json #>> ARRAY['1', 'b']" +== 205 +-- truncate_limit: 100 +select '"foo"'::json #>> array['z'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::pg_catalog.json #>> ARRAY['z']" +== 206 +-- truncate_limit: 100 +select '42'::json #>> array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::pg_catalog.json #>> ARRAY['f2']" +== 207 +-- truncate_limit: 100 +select '42'::json #>> array['0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::pg_catalog.json #>> ARRAY['0']" +== 208 +-- truncate_limit: 100 +-- array_elements + +select json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') +-- +FUNCTION: name="json_array_elements" function="json_array_elements" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_array_elements('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false,\"stringy\"]')" +== 209 +-- truncate_limit: 100 +select * from json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q +-- +FUNCTION: name="json_array_elements" function="json_array_elements" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_array_elements('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false,\"stringy\"]') q" +== 210 +-- truncate_limit: 100 +select json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') +-- +FUNCTION: name="json_array_elements_text" function="json_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_array_elements_text('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false,\"stringy\"]')" +== 211 +-- truncate_limit: 100 +select * from json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q +-- +FUNCTION: name="json_array_elements_text" function="json_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_array_elements_text('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false,\"strin..." +== 212 +-- truncate_limit: 100 +-- populate_record +create type jpop as (a text, b int, c timestamp) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jpop AS (a text, b int, c timestamp)" +== 213 +-- truncate_limit: 100 +CREATE DOMAIN js_int_not_null AS int NOT NULL +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN js_int_not_null AS int NOT NULL" +== 214 +-- truncate_limit: 100 +CREATE DOMAIN js_int_array_1d AS int[] CHECK(array_length(VALUE, 1) = 3) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN js_int_array_1d AS int[] CHECK (array_length(value, 1) = 3)" +== 215 +-- truncate_limit: 100 +CREATE DOMAIN js_int_array_2d AS int[][] CHECK(array_length(VALUE, 2) = 3) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN js_int_array_2d AS int[][] CHECK (array_length(value, 2) = 3)" +== 216 +-- truncate_limit: 100 +create type j_unordered_pair as (x int, y int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE j_unordered_pair AS (x int, y int)" +== 217 +-- truncate_limit: 100 +create domain j_ordered_pair as j_unordered_pair check((value).x <= (value).y) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN j_ordered_pair AS j_unordered_pair CHECK ((value).x <= (value).y)" +== 218 +-- truncate_limit: 100 +CREATE TYPE jsrec AS ( + i int, + ia _int4, + ia1 int[], + ia2 int[][], + ia3 int[][][], + ia1d js_int_array_1d, + ia2d js_int_array_2d, + t text, + ta text[], + c char(10), + ca char(10)[], + ts timestamp, + js json, + jsb jsonb, + jsa json[], + rec jpop, + reca jpop[] +) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsrec AS (i int, ia _int4, ia1 int[], ia2 int[][], ia3 int[][][], ia1d js_int_array_1..." +== 219 +-- truncate_limit: 100 +CREATE TYPE jsrec_i_not_null AS ( + i js_int_not_null +) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsrec_i_not_null AS (i js_int_not_null)" +== 220 +-- truncate_limit: 100 +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(NULL::jpop, '{\"a\":\"blurfl\",\"x\":43.2}') q" +== 221 +-- truncate_limit: 100 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jpop, '{\"a\":\"blurfl\",\"x\":4..." +== 222 +-- truncate_limit: 100 +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(NULL::jpop, '{\"a\":\"blurfl\",\"x\":43.2}') q" +== 223 +-- truncate_limit: 100 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jpop, '{\"a\":\"blurfl\",\"x\":4..." +== 224 +-- truncate_limit: 100 +select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(NULL::jpop, '{\"a\":[100,200,false],\"x\":43.2}') q" +== 225 +-- truncate_limit: 100 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jpop, '{\"a\":[100,200,false..." +== 226 +-- truncate_limit: 100 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jpop, '{\"c\":[100,200,false..." +== 227 +-- truncate_limit: 100 +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jpop, '{}') q" +== 228 +-- truncate_limit: 100 +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"x": 43.2}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{\"x\": 43.2}') q" +== 229 +-- truncate_limit: 100 +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"i": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{\"i\": null}') q" +== 230 +-- truncate_limit: 100 +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"i": 12345}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{\"i\": 12345}') q" +== 231 +-- truncate_limit: 100 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM json_populate_record(NULL::jsrec, '{\"ia\": null}') q" +== 232 +-- truncate_limit: 100 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM json_populate_record(NULL::jsrec, '{\"ia\": 123}') q" +== 233 +-- truncate_limit: 100 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM json_populate_record(NULL::jsrec, '{\"ia\": [1, \"2\", null, 4]}') q" +== 234 +-- truncate_limit: 100 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1, 2], [3, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM json_populate_record(NULL::jsrec, '{\"ia\": [[1, 2], [3, 4]]}') q" +== 235 +-- truncate_limit: 100 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], 2]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM json_populate_record(NULL::jsrec, '{\"ia\": [[1], 2]}') q" +== 236 +-- truncate_limit: 100 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], [2, 3]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM json_populate_record(NULL::jsrec, '{\"ia\": [[1], [2, 3]]}') q" +== 237 +-- truncate_limit: 100 +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": "{1,2,3}"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM json_populate_record(NULL::jsrec, '{\"ia\": \"{1,2,3}\"}') q" +== 238 +-- truncate_limit: 100 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM json_populate_record(NULL::jsrec, '{\"ia1\": null}') q" +== 239 +-- truncate_limit: 100 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM json_populate_record(NULL::jsrec, '{\"ia1\": 123}') q" +== 240 +-- truncate_limit: 100 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM json_populate_record(NULL::jsrec, '{\"ia1\": [1, \"2\", null, 4]}') q" +== 241 +-- truncate_limit: 100 +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": [[1, 2, 3]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM json_populate_record(NULL::jsrec, '{\"ia1\": [[1, 2, 3]]}') q" +== 242 +-- truncate_limit: 100 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM json_populate_record(NULL::jsrec, '{\"ia1d\": null}') q" +== 243 +-- truncate_limit: 100 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM json_populate_record(NULL::jsrec, '{\"ia1d\": 123}') q" +== 244 +-- truncate_limit: 100 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM json_populate_record(NULL::jsrec, '{\"ia1d\": [1, \"2\", null, 4]}') q" +== 245 +-- truncate_limit: 100 +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": [1, "2", null]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM json_populate_record(NULL::jsrec, '{\"ia1d\": [1, \"2\", null]}') q" +== 246 +-- truncate_limit: 100 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM json_populate_record(NULL::jsrec, '{\"ia2\": [1, \"2\", null, 4]}') q" +== 247 +-- truncate_limit: 100 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM json_populate_record(NULL::jsrec, '{\"ia2\": [[1, 2], [null, 4]]}') q" +== 248 +-- truncate_limit: 100 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[], []]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM json_populate_record(NULL::jsrec, '{\"ia2\": [[], []]}') q" +== 249 +-- truncate_limit: 100 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], [3]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM json_populate_record(NULL::jsrec, '{\"ia2\": [[1, 2], [3]]}') q" +== 250 +-- truncate_limit: 100 +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], 3, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM json_populate_record(NULL::jsrec, '{\"ia2\": [[1, 2], 3, 4]}') q" +== 251 +-- truncate_limit: 100 +SELECT ia2d FROM json_populate_record(NULL::jsrec, '{"ia2d": [[1, "2"], [null, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2d FROM json_populate_record(NULL::jsrec, '{\"ia2d\": [[1, \"2\"], [null, 4]]}') q" +== 252 +-- truncate_limit: 100 +SELECT ia2d FROM json_populate_record(NULL::jsrec, '{"ia2d": [[1, "2", 3], [null, 5, 6]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2d FROM json_populate_record(NULL::jsrec, '{\"ia2d\": [[1, \"2\", 3], [null, 5, 6]]}') q" +== 253 +-- truncate_limit: 100 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM json_populate_record(NULL::jsrec, '{\"ia3\": [1, \"2\", null, 4]}') q" +== 254 +-- truncate_limit: 100 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM json_populate_record(NULL::jsrec, '{\"ia3\": [[1, 2], [null, 4]]}') q" +== 255 +-- truncate_limit: 100 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[], []], [[], []], [[], []] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM json_populate_record(NULL::jsrec, '{\"ia3\": [ [[], []], [[], []], [[], []] ]}') q" +== 256 +-- truncate_limit: 100 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2]], [[3, 4]] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM json_populate_record(NULL::jsrec, '{\"ia3\": [ [[1, 2]], [[3, 4]] ]}') q" +== 257 +-- truncate_limit: 100 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM json_populate_record(NULL::jsrec, '{\"ia3\": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]..." +== 258 +-- truncate_limit: 100 +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM json_populate_record(NULL::jsrec, '{\"ia3\": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [..." +== 259 +-- truncate_limit: 100 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM json_populate_record(NULL::jsrec, '{\"ta\": null}') q" +== 260 +-- truncate_limit: 100 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM json_populate_record(NULL::jsrec, '{\"ta\": 123}') q" +== 261 +-- truncate_limit: 100 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM json_populate_record(NULL::jsrec, '{\"ta\": [1, \"2\", null, 4]}') q" +== 262 +-- truncate_limit: 100 +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM json_populate_record(NULL::jsrec, '{\"ta\": [[1, 2, 3], {\"k\": \"v\"}]}') q" +== 263 +-- truncate_limit: 100 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM json_populate_record(NULL::jsrec, '{\"c\": null}') q" +== 264 +-- truncate_limit: 100 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaa"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM json_populate_record(NULL::jsrec, '{\"c\": \"aaa\"}') q" +== 265 +-- truncate_limit: 100 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaaaaaaaaa"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM json_populate_record(NULL::jsrec, '{\"c\": \"aaaaaaaaaa\"}') q" +== 266 +-- truncate_limit: 100 +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaaaaaaaaaaaa"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM json_populate_record(NULL::jsrec, '{\"c\": \"aaaaaaaaaaaaa\"}') q" +== 267 +-- truncate_limit: 100 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM json_populate_record(NULL::jsrec, '{\"ca\": null}') q" +== 268 +-- truncate_limit: 100 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM json_populate_record(NULL::jsrec, '{\"ca\": 123}') q" +== 269 +-- truncate_limit: 100 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM json_populate_record(NULL::jsrec, '{\"ca\": [1, \"2\", null, 4]}') q" +== 270 +-- truncate_limit: 100 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM json_populate_record(NULL::jsrec, '{\"ca\": [\"aaaaaaaaaaaaaaaa\"]}') q" +== 271 +-- truncate_limit: 100 +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM json_populate_record(NULL::jsrec, '{\"ca\": [[1, 2, 3], {\"k\": \"v\"}]}') q" +== 272 +-- truncate_limit: 100 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM json_populate_record(NULL::jsrec, '{\"js\": null}') q" +== 273 +-- truncate_limit: 100 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": true}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM json_populate_record(NULL::jsrec, '{\"js\": true}') q" +== 274 +-- truncate_limit: 100 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": 123.45}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM json_populate_record(NULL::jsrec, '{\"js\": 123.45}') q" +== 275 +-- truncate_limit: 100 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": "123.45"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM json_populate_record(NULL::jsrec, '{\"js\": \"123.45\"}') q" +== 276 +-- truncate_limit: 100 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": "abc"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM json_populate_record(NULL::jsrec, '{\"js\": \"abc\"}') q" +== 277 +-- truncate_limit: 100 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM json_populate_record(NULL::jsrec, '{\"js\": [123, \"123\", null, {\"key\": \"value\"}]}') q" +== 278 +-- truncate_limit: 100 +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM json_populate_record(NULL::jsrec, '{\"js\": {\"a\": \"bbb\", \"b\": null, \"c\": 123.45}}') q" +== 279 +-- truncate_limit: 100 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM json_populate_record(NULL::jsrec, '{\"jsb\": null}') q" +== 280 +-- truncate_limit: 100 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": true}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM json_populate_record(NULL::jsrec, '{\"jsb\": true}') q" +== 281 +-- truncate_limit: 100 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": 123.45}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM json_populate_record(NULL::jsrec, '{\"jsb\": 123.45}') q" +== 282 +-- truncate_limit: 100 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": "123.45"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM json_populate_record(NULL::jsrec, '{\"jsb\": \"123.45\"}') q" +== 283 +-- truncate_limit: 100 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": "abc"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM json_populate_record(NULL::jsrec, '{\"jsb\": \"abc\"}') q" +== 284 +-- truncate_limit: 100 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM json_populate_record(NULL::jsrec, '{\"jsb\": [123, \"123\", null, {\"key\": \"value\"}]}') q" +== 285 +-- truncate_limit: 100 +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM json_populate_record(NULL::jsrec, '{\"jsb\": {\"a\": \"bbb\", \"b\": null, \"c\": 123.45}}') q" +== 286 +-- truncate_limit: 100 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": null}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM json_populate_record(NULL::jsrec, '{\"jsa\": null}') q" +== 287 +-- truncate_limit: 100 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM json_populate_record(NULL::jsrec, '{\"jsa\": 123}') q" +== 288 +-- truncate_limit: 100 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": [1, "2", null, 4]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM json_populate_record(NULL::jsrec, '{\"jsa\": [1, \"2\", null, 4]}') q" +== 289 +-- truncate_limit: 100 +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": ["aaa", null, [1, 2, "3", {}], { "k" : "v" }]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM json_populate_record(NULL::jsrec, '{\"jsa\": [\"aaa\", null, [1, 2, \"3\", {}], { \"k\" :..." +== 290 +-- truncate_limit: 100 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM json_populate_record(NULL::jsrec, '{\"rec\": 123}') q" +== 291 +-- truncate_limit: 100 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": [1, 2]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM json_populate_record(NULL::jsrec, '{\"rec\": [1, 2]}') q" +== 292 +-- truncate_limit: 100 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM json_populate_record(NULL::jsrec, '{\"rec\": {\"a\": \"abc\", \"c\": \"01.02.2003\", \"x\": 4..." +== 293 +-- truncate_limit: 100 +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": "(abc,42,01.02.2003)"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM json_populate_record(NULL::jsrec, '{\"rec\": \"(abc,42,01.02.2003)\"}') q" +== 294 +-- truncate_limit: 100 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": 123}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM json_populate_record(NULL::jsrec, '{\"reca\": 123}') q" +== 295 +-- truncate_limit: 100 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": [1, 2]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM json_populate_record(NULL::jsrec, '{\"reca\": [1, 2]}') q" +== 296 +-- truncate_limit: 100 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM json_populate_record(NULL::jsrec, '{\"reca\": [{\"a\": \"abc\", \"b\": 456}, null, {\"c\": ..." +== 297 +-- truncate_limit: 100 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": ["(abc,42,01.02.2003)"]}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM json_populate_record(NULL::jsrec, '{\"reca\": [\"(abc,42,01.02.2003)\"]}') q" +== 298 +-- truncate_limit: 100 +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": "{\"(abc,42,01.02.2003)\"}"}') q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM json_populate_record(NULL::jsrec, E'{\"reca\": \"{\\\\\"(abc,42,01.02.2003)\\\\\"}\"}') q" +== 299 +-- truncate_limit: 100 +SELECT rec FROM json_populate_record( + row(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + row('x',3,'2012-12-31 15:30:56')::jpop,NULL)::jsrec, + '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}' +) q +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM json_populate_record(ROW(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NU..." +== 300 +-- truncate_limit: 100 +-- anonymous record type +SELECT json_populate_record(null::record, '{"x": 0, "y": 1}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_record(NULL::record, '{\"x\": 0, \"y\": 1}')" +== 301 +-- truncate_limit: 100 +SELECT json_populate_record(row(1,2), '{"f1": 0, "f2": 1}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_record(ROW(1, 2), '{\"f1\": 0, \"f2\": 1}')" +== 302 +-- truncate_limit: 100 +SELECT * FROM + json_populate_record(null::record, '{"x": 776}') AS (x int, y int) +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_record(NULL::record, '{\"x\": 776}') AS (x int, y int)" +== 303 +-- truncate_limit: 100 +-- composite domain +SELECT json_populate_record(null::j_ordered_pair, '{"x": 0, "y": 1}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_record(NULL::j_ordered_pair, '{\"x\": 0, \"y\": 1}')" +== 304 +-- truncate_limit: 100 +SELECT json_populate_record(row(1,2)::j_ordered_pair, '{"x": 0}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_record(ROW(1, 2)::j_ordered_pair, '{\"x\": 0}')" +== 305 +-- truncate_limit: 100 +SELECT json_populate_record(row(1,2)::j_ordered_pair, '{"x": 1, "y": 0}') +-- +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_record(ROW(1, 2)::j_ordered_pair, '{\"x\": 1, \"y\": 0}')" +== 306 +-- truncate_limit: 100 +-- populate_recordset + +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(NULL::jpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":3,\"c\":\"2012-01-2..." +== 307 +-- truncate_limit: 100 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW('def', 99, NULL)::jpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":..." +== 308 +-- truncate_limit: 100 +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(NULL::jpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":3,\"c\":\"2012-01-2..." +== 309 +-- truncate_limit: 100 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW('def', 99, NULL)::jpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":..." +== 310 +-- truncate_limit: 100 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW('def', 99, NULL)::jpop, '[{\"a\":[100,200,300],\"x\":43.2},..." +== 311 +-- truncate_limit: 100 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW('def', 99, NULL)::jpop, '[{\"c\":[100,200,300],\"x\":43.2},..." +== 312 +-- truncate_limit: 100 +create type jpop2 as (a int, b json, c int, d int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jpop2 AS (a int, b pg_catalog.json, c int, d int)" +== 313 +-- truncate_limit: 100 +select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(NULL::jpop2, '[{\"a\":2,\"c\":3,\"b\":{\"z\":4},\"d\":6}]') q" +== 314 +-- truncate_limit: 100 +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(NULL::jpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":3,\"c\":\"2012-01-2..." +== 315 +-- truncate_limit: 100 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW('def', 99, NULL)::jpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":..." +== 316 +-- truncate_limit: 100 +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW('def', 99, NULL)::jpop, '[{\"a\":[100,200,300],\"x\":43.2},..." +== 317 +-- truncate_limit: 100 +-- anonymous record type +SELECT json_populate_recordset(null::record, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_recordset(NULL::record, '[{\"x\": 0, \"y\": 1}]')" +== 318 +-- truncate_limit: 100 +SELECT json_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_recordset(ROW(1, 2), '[{\"f1\": 0, \"f2\": 1}]')" +== 319 +-- truncate_limit: 100 +SELECT i, json_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i, json_populate_recordset(ROW(i, 50), '[{\"f1\":\"42\"},{\"f2\":\"43\"}]') FROM (VALUES (...)) v(i)" +== 320 +-- truncate_limit: 100 +SELECT * FROM + json_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(NULL::record, '[{\"x\": 776}]') AS (x int, y int)" +== 321 +-- truncate_limit: 100 +-- empty array is a corner case +SELECT json_populate_recordset(null::record, '[]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_recordset(NULL::record, '[]')" +== 322 +-- truncate_limit: 100 +SELECT json_populate_recordset(row(1,2), '[]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_recordset(ROW(1, 2), '[]')" +== 323 +-- truncate_limit: 100 +SELECT * FROM json_populate_recordset(NULL::jpop,'[]') q +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(NULL::jpop, '[]') q" +== 324 +-- truncate_limit: 100 +SELECT * FROM + json_populate_recordset(null::record, '[]') AS (x int, y int) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(NULL::record, '[]') AS (x int, y int)" +== 325 +-- truncate_limit: 100 +-- composite domain +SELECT json_populate_recordset(null::j_ordered_pair, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_recordset(NULL::j_ordered_pair, '[{\"x\": 0, \"y\": 1}]')" +== 326 +-- truncate_limit: 100 +SELECT json_populate_recordset(row(1,2)::j_ordered_pair, '[{"x": 0}, {"y": 3}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_recordset(ROW(1, 2)::j_ordered_pair, '[{\"x\": 0}, {\"y\": 3}]')" +== 327 +-- truncate_limit: 100 +SELECT json_populate_recordset(row(1,2)::j_ordered_pair, '[{"x": 1, "y": 0}]') +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_populate_recordset(ROW(1, 2)::j_ordered_pair, '[{\"x\": 1, \"y\": 0}]')" +== 328 +-- truncate_limit: 100 +-- negative cases where the wrong record type is supplied +select * from json_populate_recordset(row(0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW(0::int), '[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\"}]') q (a text, b ..." +== 329 +-- truncate_limit: 100 +select * from json_populate_recordset(row(0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW(0::int, 0::int), '[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\"}]') q (a ..." +== 330 +-- truncate_limit: 100 +select * from json_populate_recordset(row(0::int,0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW(0::int, 0::int, 0::int), '[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\"}]..." +== 331 +-- truncate_limit: 100 +select * from json_populate_recordset(row(1000000000::int,50::int),'[{"b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="json_populate_recordset" function="json_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_populate_recordset(ROW(1000000000::int, 50::int), '[{\"b\":\"2\"},{\"a\":\"3\"}]') q (..." +== 332 +-- truncate_limit: 100 +-- test type info caching in json_populate_record() +CREATE TEMP TABLE jspoptest (js json) +-- +TABLE: name="jspoptest" schema="" table="jspoptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE jspoptest (js pg_catalog.json)" +== 333 +-- truncate_limit: 100 +INSERT INTO jspoptest +SELECT '{ + "jsa": [1, "2", null, 4], + "rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}, + "reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}] +}'::json +FROM generate_series(1, 3) +-- +TABLE: name="jspoptest" schema="" table="jspoptest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO jspoptest SELECT ... FROM generate_series(1, 3)" +== 334 +-- truncate_limit: 100 +SELECT (json_populate_record(NULL::jsrec, js)).* FROM jspoptest +-- +TABLE: name="jspoptest" schema="" table="jspoptest" ctx=Select +FUNCTION: name="json_populate_record" function="json_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (json_populate_record(NULL::jsrec, js)).* FROM jspoptest" +== 335 +-- truncate_limit: 100 +DROP TYPE jsrec +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE jsrec" +== 336 +-- truncate_limit: 100 +DROP TYPE jsrec_i_not_null +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE jsrec_i_not_null" +== 337 +-- truncate_limit: 100 +DROP DOMAIN js_int_not_null +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN js_int_not_null" +== 338 +-- truncate_limit: 100 +DROP DOMAIN js_int_array_1d +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN js_int_array_1d" +== 339 +-- truncate_limit: 100 +DROP DOMAIN js_int_array_2d +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN js_int_array_2d" +== 340 +-- truncate_limit: 100 +DROP DOMAIN j_ordered_pair +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN j_ordered_pair" +== 341 +-- truncate_limit: 100 +DROP TYPE j_unordered_pair +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE j_unordered_pair" +== 342 +-- truncate_limit: 100 +--json_typeof() function +select value, json_typeof(value) + from (values (json '123.4'), + (json '-1'), + (json '"foo"'), + (json 'true'), + (json 'false'), + (json 'null'), + (json '[1, 2, 3]'), + (json '[]'), + (json '{"x":"foo", "y":123}'), + (json '{}'), + (NULL::json)) + as data(value) +-- +FUNCTION: name="json_typeof" function="json_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT value, json_typeof(value) FROM (VALUES (...)) data(value)" +== 343 +-- truncate_limit: 100 +-- json_build_array, json_build_object, json_object_agg + +SELECT json_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 344 +-- truncate_limit: 100 +SELECT json_build_array('a', NULL) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array('a', NULL)" +== 345 +-- truncate_limit: 100 +-- ok +SELECT json_build_array(VARIADIC NULL::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array(VARIADIC NULL::text[])" +== 346 +-- truncate_limit: 100 +-- ok +SELECT json_build_array(VARIADIC '{}'::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array(VARIADIC '{}'::text[])" +== 347 +-- truncate_limit: 100 +-- ok +SELECT json_build_array(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array(VARIADIC '{a,b,c}'::text[])" +== 348 +-- truncate_limit: 100 +-- ok +SELECT json_build_array(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array(VARIADIC ARRAY['a', NULL]::text[])" +== 349 +-- truncate_limit: 100 +-- ok +SELECT json_build_array(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array(VARIADIC '{1,2,3,4}'::text[])" +== 350 +-- truncate_limit: 100 +-- ok +SELECT json_build_array(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array(VARIADIC '{1,2,3,4}'::int[])" +== 351 +-- truncate_limit: 100 +-- ok +SELECT json_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][])" +== 352 +-- truncate_limit: 100 +-- ok + +SELECT json_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 353 +-- truncate_limit: 100 +SELECT json_build_object( + 'a', json_build_object('b',false,'c',99), + 'd', json_build_object('e',array[9,8,7]::int[], + 'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r))) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 354 +-- truncate_limit: 100 +SELECT json_build_object('{a,b,c}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object('{a,b,c}'::text[])" +== 355 +-- truncate_limit: 100 +-- error +SELECT json_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object('{a,b,c}'::text[], '{d,e,f}'::text[])" +== 356 +-- truncate_limit: 100 +-- error, key cannot be array +SELECT json_build_object('a', 'b', 'c') +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object('a', 'b', 'c')" +== 357 +-- truncate_limit: 100 +-- error +SELECT json_build_object(NULL, 'a') +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(NULL, 'a')" +== 358 +-- truncate_limit: 100 +-- error, key cannot be NULL +SELECT json_build_object('a', NULL) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object('a', NULL)" +== 359 +-- truncate_limit: 100 +-- ok +SELECT json_build_object(VARIADIC NULL::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC NULL::text[])" +== 360 +-- truncate_limit: 100 +-- ok +SELECT json_build_object(VARIADIC '{}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC '{}'::text[])" +== 361 +-- truncate_limit: 100 +-- ok +SELECT json_build_object(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC '{a,b,c}'::text[])" +== 362 +-- truncate_limit: 100 +-- error +SELECT json_build_object(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC ARRAY['a', NULL]::text[])" +== 363 +-- truncate_limit: 100 +-- ok +SELECT json_build_object(VARIADIC ARRAY[NULL, 'a']::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC ARRAY[NULL, 'a']::text[])" +== 364 +-- truncate_limit: 100 +-- error, key cannot be NULL +SELECT json_build_object(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC '{1,2,3,4}'::text[])" +== 365 +-- truncate_limit: 100 +-- ok +SELECT json_build_object(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC '{1,2,3,4}'::int[])" +== 366 +-- truncate_limit: 100 +-- ok +SELECT json_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][])" +== 367 +-- truncate_limit: 100 +-- ok + +-- empty objects/arrays +SELECT json_build_array() +-- +FUNCTION: name="json_build_array" function="json_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_array()" +== 368 +-- truncate_limit: 100 +SELECT json_build_object() +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object()" +== 369 +-- truncate_limit: 100 +-- make sure keys are quoted +SELECT json_build_object(1,2) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(1, 2)" +== 370 +-- truncate_limit: 100 +-- keys must be scalar and not null +SELECT json_build_object(null,2) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(NULL, 2)" +== 371 +-- truncate_limit: 100 +SELECT json_build_object(r,2) FROM (SELECT 1 AS a, 2 AS b) r +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object(r, 2) FROM (SELECT 1 AS a, 2 AS b) r" +== 372 +-- truncate_limit: 100 +SELECT json_build_object(json '{"a":1,"b":2}', 3) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object('{\"a\":1,\"b\":2}'::pg_catalog.json, 3)" +== 373 +-- truncate_limit: 100 +SELECT json_build_object('{1,2,3}'::int[], 3) +-- +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_build_object('{1,2,3}'::int[], 3)" +== 374 +-- truncate_limit: 100 +CREATE TEMP TABLE foo (serial_num int, name text, type text) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (serial_num int, name text, type text)" +== 375 +-- truncate_limit: 100 +INSERT INTO foo VALUES (847001,'t15','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (847001, 't15', 'GE1043')" +== 376 +-- truncate_limit: 100 +INSERT INTO foo VALUES (847002,'t16','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (847002, 't16', 'GE1043')" +== 377 +-- truncate_limit: 100 +INSERT INTO foo VALUES (847003,'sub-alpha','GESS90') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (847003, 'sub-alpha', 'GESS90')" +== 378 +-- truncate_limit: 100 +SELECT json_build_object('turbines',json_object_agg(serial_num,json_build_object('name',name,'type',type))) +FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +FUNCTION: name="json_object_agg" function="json_object_agg" schema="" ctx=Call +FUNCTION: name="json_build_object" function="json_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM foo" +== 379 +-- truncate_limit: 100 +SELECT json_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="json_object_agg" function="json_object_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_object_agg(name, type) FROM foo" +== 380 +-- truncate_limit: 100 +INSERT INTO foo VALUES (999999, NULL, 'bar') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (999999, NULL, 'bar')" +== 381 +-- truncate_limit: 100 +SELECT json_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="json_object_agg" function="json_object_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_object_agg(name, type) FROM foo" +== 382 +-- truncate_limit: 100 +-- json_object + +-- empty object, one dimension +SELECT json_object('{}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{}')" +== 383 +-- truncate_limit: 100 +-- empty object, two dimensions +SELECT json_object('{}', '{}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{}', '{}')" +== 384 +-- truncate_limit: 100 +-- one dimension +SELECT json_object('{a,1,b,2,3,NULL,"d e f","a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{a,1,b,2,3,NULL,\"d e f\",\"a b c\"}')" +== 385 +-- truncate_limit: 100 +-- same but with two dimensions +SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{{a,1},{b,2},{3,NULL},{\"d e f\",\"a b c\"}}')" +== 386 +-- truncate_limit: 100 +-- odd number error +SELECT json_object('{a,b,c}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{a,b,c}')" +== 387 +-- truncate_limit: 100 +-- one column error +SELECT json_object('{{a},{b}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{{a},{b}}')" +== 388 +-- truncate_limit: 100 +-- too many columns error +SELECT json_object('{{a,b,c},{b,c,d}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{{a,b,c},{b,c,d}}')" +== 389 +-- truncate_limit: 100 +-- too many dimensions error +SELECT json_object('{{{a,b},{c,d}},{{b,c},{d,e}}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{{{a,b},{c,d}},{{b,c},{d,e}}}')" +== 390 +-- truncate_limit: 100 +--two argument form of json_object + +select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{a,b,c,\"d e f\"}', '{1,2,3,\"a b c\"}')" +== 391 +-- truncate_limit: 100 +-- too many dimensions +SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}', '{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 392 +-- truncate_limit: 100 +-- mismatched dimensions + +select json_object('{a,b,c,"d e f",g}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{a,b,c,\"d e f\",g}', '{1,2,3,\"a b c\"}')" +== 393 +-- truncate_limit: 100 +select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c",g}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{a,b,c,\"d e f\"}', '{1,2,3,\"a b c\",g}')" +== 394 +-- truncate_limit: 100 +-- null key error + +select json_object('{a,b,NULL,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{a,b,NULL,\"d e f\"}', '{1,2,3,\"a b c\"}')" +== 395 +-- truncate_limit: 100 +-- empty key is allowed + +select json_object('{a,b,"","d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="pg_catalog.json_object" function="json_object" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.\"json_object\"('{a,b,\"\",\"d e f\"}', '{1,2,3,\"a b c\"}')" +== 396 +-- truncate_limit: 100 +-- json_object_agg_unique requires unique keys +select json_object_agg_unique(mod(i,100), i) from generate_series(0, 199) i +-- +FUNCTION: name="json_object_agg_unique" function="json_object_agg_unique" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_object_agg_unique(mod(i, 100), i) FROM generate_series(0, 199) i" +== 397 +-- truncate_limit: 100 +-- json_to_record and json_to_recordset + +select * from json_to_record('{"a":1,"b":"foo","c":"bar"}') + as x(a int, b text, d text) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"a\":1,\"b\":\"foo\",\"c\":\"bar\"}') x (a int, b text, d text)" +== 398 +-- truncate_limit: 100 +select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') + as x(a int, b text, c boolean) +-- +FUNCTION: name="json_to_recordset" function="json_to_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_recordset('[{\"a\":1,\"b\":\"foo\",\"d\":false},{\"a\":2,\"b\":\"bar\",\"c\":true}]') x (a ..." +== 399 +-- truncate_limit: 100 +select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]') + as x(a int, b json, c boolean) +-- +FUNCTION: name="json_to_recordset" function="json_to_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_recordset('[{\"a\":1,\"b\":{\"d\":\"foo\"},\"c\":true},{\"a\":2,\"c\":false,\"b\":{\"d\":\"bar..." +== 400 +-- truncate_limit: 100 +select *, c is null as c_is_null +from json_to_record('{"a":1, "b":{"c":16, "d":2}, "x":8, "ca": ["1 2", 3], "ia": [[1,2],[3,4]], "r": {"a": "aaa", "b": 123}}'::json) + as t(a int, b json, c text, x int, ca char(5)[], ia int[][], r jpop) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM json_to_record('{\"a\":1, \"b\":{\"c\":16, \"d\":2}, \"x\":8, \"ca\": [\"1 2\", 3], \"ia\": [[1,2..." +== 401 +-- truncate_limit: 100 +select *, c is null as c_is_null +from json_to_recordset('[{"a":1, "b":{"c":16, "d":2}, "x":8}]'::json) + as t(a int, b json, c text, x int) +-- +FUNCTION: name="json_to_recordset" function="json_to_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM json_to_recordset('[{\"a\":1, \"b\":{\"c\":16, \"d\":2}, \"x\":8}]'::pg_catalog.json) t (a ..." +== 402 +-- truncate_limit: 100 +select * from json_to_record('{"ia": null}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia\": null}') x (ia _int4)" +== 403 +-- truncate_limit: 100 +select * from json_to_record('{"ia": 123}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia\": 123}') x (ia _int4)" +== 404 +-- truncate_limit: 100 +select * from json_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia\": [1, \"2\", null, 4]}') x (ia _int4)" +== 405 +-- truncate_limit: 100 +select * from json_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia\": [[1, 2], [3, 4]]}') x (ia _int4)" +== 406 +-- truncate_limit: 100 +select * from json_to_record('{"ia": [[1], 2]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia\": [[1], 2]}') x (ia _int4)" +== 407 +-- truncate_limit: 100 +select * from json_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia\": [[1], [2, 3]]}') x (ia _int4)" +== 408 +-- truncate_limit: 100 +select * from json_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia2\": [1, 2, 3]}') x (ia2 int[][])" +== 409 +-- truncate_limit: 100 +select * from json_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia2\": [[1, 2], [3, 4]]}') x (ia2 int4[][])" +== 410 +-- truncate_limit: 100 +select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"ia2\": [[[1], [2], [3]]]}') x (ia2 int4[][])" +== 411 +-- truncate_limit: 100 +select * from json_to_record('{"out": {"key": 1}}') as x(out json) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"out\": {\"key\": 1}}') x (\"out\" pg_catalog.json)" +== 412 +-- truncate_limit: 100 +select * from json_to_record('{"out": [{"key": 1}]}') as x(out json) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"out\": [{\"key\": 1}]}') x (\"out\" pg_catalog.json)" +== 413 +-- truncate_limit: 100 +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out json) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record(E'{\"out\": \"{\\\\\"key\\\\\": 1}\"}') x (\"out\" pg_catalog.json)" +== 414 +-- truncate_limit: 100 +select * from json_to_record('{"out": {"key": 1}}') as x(out jsonb) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"out\": {\"key\": 1}}') x (\"out\" jsonb)" +== 415 +-- truncate_limit: 100 +select * from json_to_record('{"out": [{"key": 1}]}') as x(out jsonb) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record('{\"out\": [{\"key\": 1}]}') x (\"out\" jsonb)" +== 416 +-- truncate_limit: 100 +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb) +-- +FUNCTION: name="json_to_record" function="json_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_to_record(E'{\"out\": \"{\\\\\"key\\\\\": 1}\"}') x (\"out\" jsonb)" +== 417 +-- truncate_limit: 100 +-- json_strip_nulls + +select json_strip_nulls(null) +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls(NULL)" +== 418 +-- truncate_limit: 100 +select json_strip_nulls('1') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls('1')" +== 419 +-- truncate_limit: 100 +select json_strip_nulls('"a string"') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls('\"a string\"')" +== 420 +-- truncate_limit: 100 +select json_strip_nulls('null') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls('null')" +== 421 +-- truncate_limit: 100 +select json_strip_nulls('[1,2,null,3,4]') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls('[1,2,null,3,4]')" +== 422 +-- truncate_limit: 100 +select json_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls('{\"a\":1,\"b\":null,\"c\":[2,null,3],\"d\":{\"e\":4,\"f\":null}}')" +== 423 +-- truncate_limit: 100 +select json_strip_nulls('[1,{"a":1,"b":null,"c":2},3]') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls('[1,{\"a\":1,\"b\":null,\"c\":2},3]')" +== 424 +-- truncate_limit: 100 +-- an empty object is not null and should not be stripped +select json_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }') +-- +FUNCTION: name="json_strip_nulls" function="json_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_strip_nulls('{\"a\": {\"b\": null, \"c\": null}, \"d\": {} }')" +== 425 +-- truncate_limit: 100 +-- json to tsvector +select to_tsvector('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 426 +-- truncate_limit: 100 +-- json to tsvector with config +select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 427 +-- truncate_limit: 100 +-- json to tsvector with stop words +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 428 +-- truncate_limit: 100 +-- json to tsvector with numeric values +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('english', '{\"a\": \"aaa in bbb ddd ccc\", \"b\": 123, \"c\": 456}'::pg_catalog.json)" +== 429 +-- truncate_limit: 100 +-- json_to_tsvector +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 430 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 431 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 432 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 433 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 434 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 435 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 436 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 437 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 438 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 439 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 440 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 441 +-- truncate_limit: 100 +-- to_tsvector corner cases +select to_tsvector('""'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('\"\"'::pg_catalog.json)" +== 442 +-- truncate_limit: 100 +select to_tsvector('{}'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('{}'::pg_catalog.json)" +== 443 +-- truncate_limit: 100 +select to_tsvector('[]'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('[]'::pg_catalog.json)" +== 444 +-- truncate_limit: 100 +select to_tsvector('null'::json) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('null'::pg_catalog.json)" +== 445 +-- truncate_limit: 100 +-- json_to_tsvector corner cases +select json_to_tsvector('""'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_to_tsvector('\"\"'::pg_catalog.json, '\"all\"')" +== 446 +-- truncate_limit: 100 +select json_to_tsvector('{}'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_to_tsvector('{}'::pg_catalog.json, '\"all\"')" +== 447 +-- truncate_limit: 100 +select json_to_tsvector('[]'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_to_tsvector('[]'::pg_catalog.json, '\"all\"')" +== 448 +-- truncate_limit: 100 +select json_to_tsvector('null'::json, '"all"') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT json_to_tsvector('null'::pg_catalog.json, '\"all\"')" +== 449 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '""') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 450 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '{}') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 451 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '[]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 452 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, 'null') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 453 +-- truncate_limit: 100 +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["all", null]') +-- +FUNCTION: name="json_to_tsvector" function="json_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 454 +-- truncate_limit: 100 +-- ts_headline for json +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 455 +-- truncate_limit: 100 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 456 +-- truncate_limit: 100 +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 457 +-- truncate_limit: 100 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 458 +-- truncate_limit: 100 +-- corner cases for ts_headline with json +select ts_headline('null'::json, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('null'::pg_catalog.json, tsquery('aaa & bbb'))" +== 459 +-- truncate_limit: 100 +select ts_headline('{}'::json, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('{}'::pg_catalog.json, tsquery('aaa & bbb'))" +== 460 +-- truncate_limit: 100 +select ts_headline('[]'::json, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('[]'::pg_catalog.json, tsquery('aaa & bbb'))" diff --git a/parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json b/parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/json_encoding.test b/parser/testdata/summary_truncate/postgres_regress/json_encoding.test new file mode 100644 index 0000000..8462576 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/json_encoding.test @@ -0,0 +1,319 @@ +== 001 +-- truncate_limit: 100 +|-- +-- encoding-sensitive tests for json and jsonb +|-- + +-- We provide expected-results files for UTF8 (json_encoding.out) +-- and for SQL_ASCII (json_encoding_1.out). Skip otherwise. +SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') + AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') AS skip_test" +== 002 +-- truncate_limit: 100 +SELECT getdatabaseencoding() +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT getdatabaseencoding()" +== 003 +-- truncate_limit: 100 +-- just to label the results files + +-- first json + +-- basic unicode input +SELECT '"\u"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u\"'::pg_catalog.json" +== 004 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '"\u00"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u00\"'::pg_catalog.json" +== 005 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '"\u000g"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u000g\"'::pg_catalog.json" +== 006 +-- truncate_limit: 100 +-- ERROR, g is not a hex digit +SELECT '"\u0000"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u0000\"'::pg_catalog.json" +== 007 +-- truncate_limit: 100 +-- OK, legal escape +SELECT '"\uaBcD"'::json +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\uaBcD\"'::pg_catalog.json" +== 008 +-- truncate_limit: 100 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs + +select json '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ud83d\\\\ude04\\\\ud83d\\\\udc36\" }'::pg_catalog.json -> 'a' AS correct_in_utf8" +== 009 +-- truncate_limit: 100 +select json '{ "a": "\ud83d\ud83d" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ud83d\\\\ud83d\" }'::pg_catalog.json -> 'a'" +== 010 +-- truncate_limit: 100 +-- 2 high surrogates in a row +select json '{ "a": "\ude04\ud83d" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ude04\\\\ud83d\" }'::pg_catalog.json -> 'a'" +== 011 +-- truncate_limit: 100 +-- surrogates in wrong order +select json '{ "a": "\ud83dX" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ud83dX\" }'::pg_catalog.json -> 'a'" +== 012 +-- truncate_limit: 100 +-- orphan high surrogate +select json '{ "a": "\ude04X" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ude04X\" }'::pg_catalog.json -> 'a'" +== 013 +-- truncate_limit: 100 +-- orphan low surrogate + +--handling of simple unicode escapes + +select json '{ "a": "the Copyright \u00a9 sign" }' as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"the Copyright \\\\u00a9 sign\" }'::pg_catalog.json AS correct_in_utf8" +== 014 +-- truncate_limit: 100 +select json '{ "a": "dollar \u0024 character" }' as correct_everywhere +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\u0024 character\" }'::pg_catalog.json AS correct_everywhere" +== 015 +-- truncate_limit: 100 +select json '{ "a": "dollar \\u0024 character" }' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\\\\\u0024 character\" }'::pg_catalog.json AS not_an_escape" +== 016 +-- truncate_limit: 100 +select json '{ "a": "null \u0000 escape" }' as not_unescaped +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\u0000 escape\" }'::pg_catalog.json AS not_unescaped" +== 017 +-- truncate_limit: 100 +select json '{ "a": "null \\u0000 escape" }' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\\\\\u0000 escape\" }'::pg_catalog.json AS not_an_escape" +== 018 +-- truncate_limit: 100 +select json '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"the Copyright \\\\u00a9 sign\" }'::pg_catalog.json ->> 'a' AS correct_in_utf8" +== 019 +-- truncate_limit: 100 +select json '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\u0024 character\" }'::pg_catalog.json ->> 'a' AS correct_everywhere" +== 020 +-- truncate_limit: 100 +select json '{ "a": "dollar \\u0024 character" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\\\\\u0024 character\" }'::pg_catalog.json ->> 'a' AS not_an_escape" +== 021 +-- truncate_limit: 100 +select json '{ "a": "null \u0000 escape" }' ->> 'a' as fails +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\u0000 escape\" }'::pg_catalog.json ->> 'a' AS fails" +== 022 +-- truncate_limit: 100 +select json '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\\\\\u0000 escape\" }'::pg_catalog.json ->> 'a' AS not_an_escape" +== 023 +-- truncate_limit: 100 +-- then jsonb + +-- basic unicode input +SELECT '"\u"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u\"'::jsonb" +== 024 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '"\u00"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u00\"'::jsonb" +== 025 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '"\u000g"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u000g\"'::jsonb" +== 026 +-- truncate_limit: 100 +-- ERROR, g is not a hex digit +SELECT '"\u0045"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u0045\"'::jsonb" +== 027 +-- truncate_limit: 100 +-- OK, legal escape +SELECT '"\u0000"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u0000\"'::jsonb" +== 028 +-- truncate_limit: 100 +-- ERROR, we don't support U+0000 +-- use octet_length here so we don't get an odd unicode char in the +-- output +SELECT octet_length('"\uaBcD"'::jsonb::text) +-- +FUNCTION: name="octet_length" function="octet_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT octet_length(E'\"\\\\uaBcD\"'::jsonb::text)" +== 029 +-- truncate_limit: 100 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs + +SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8 +-- +FUNCTION: name="octet_length" function="octet_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 030 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "\ud83d\ud83d" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ud83d\\\\ud83d\" }'::jsonb -> 'a'" +== 031 +-- truncate_limit: 100 +-- 2 high surrogates in a row +SELECT jsonb '{ "a": "\ude04\ud83d" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ude04\\\\ud83d\" }'::jsonb -> 'a'" +== 032 +-- truncate_limit: 100 +-- surrogates in wrong order +SELECT jsonb '{ "a": "\ud83dX" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ud83dX\" }'::jsonb -> 'a'" +== 033 +-- truncate_limit: 100 +-- orphan high surrogate +SELECT jsonb '{ "a": "\ude04X" }' -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"\\\\ude04X\" }'::jsonb -> 'a'" +== 034 +-- truncate_limit: 100 +-- orphan low surrogate + +-- handling of simple unicode escapes + +SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"the Copyright \\\\u00a9 sign\" }'::jsonb AS correct_in_utf8" +== 035 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "dollar \u0024 character" }' as correct_everywhere +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\u0024 character\" }'::jsonb AS correct_everywhere" +== 036 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "dollar \\u0024 character" }' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\\\\\u0024 character\" }'::jsonb AS not_an_escape" +== 037 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "null \u0000 escape" }' as fails +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\u0000 escape\" }'::jsonb AS fails" +== 038 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "null \\u0000 escape" }' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\\\\\u0000 escape\" }'::jsonb AS not_an_escape" +== 039 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"the Copyright \\\\u00a9 sign\" }'::jsonb ->> 'a' AS correct_in_utf8" +== 040 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\u0024 character\" }'::jsonb ->> 'a' AS correct_everywhere" +== 041 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "dollar \\u0024 character" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"dollar \\\\\\\\u0024 character\" }'::jsonb ->> 'a' AS not_an_escape" +== 042 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' as fails +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\u0000 escape\" }'::jsonb ->> 'a' AS fails" +== 043 +-- truncate_limit: 100 +SELECT jsonb '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{ \"a\": \"null \\\\\\\\u0000 escape\" }'::jsonb ->> 'a' AS not_an_escape" +== 044 +-- truncate_limit: 100 +-- soft error for input-time failure + +select * from pg_input_error_info('{ "a": "\ud83d\ude04\ud83d\udc36" }', 'jsonb') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info(E'{ \"a\": \"\\\\ud83d\\\\ude04\\\\ud83d\\\\udc36\" }', 'jsonb')" diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json new file mode 100644 index 0000000..4c380dc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json @@ -0,0 +1,1063 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonb.test b/parser/testdata/summary_truncate/postgres_regress/jsonb.test new file mode 100644 index 0000000..8ae12a4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonb.test @@ -0,0 +1,7703 @@ +== 001 +-- truncate_limit: 100 +-- directory paths are passed to us in environment variables + +CREATE TABLE testjsonb ( + j jsonb +) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testjsonb (j jsonb)" +== 002 +-- truncate_limit: 100 +COPY testjsonb FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +-- truncate_limit: 100 +-- Strings. +SELECT '""'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"\"'::jsonb" +== 004 +-- truncate_limit: 100 +-- OK. +SELECT $$''$$::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''''''::jsonb" +== 005 +-- truncate_limit: 100 +-- ERROR, single quotes are not allowed +SELECT '"abc"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"abc\"'::jsonb" +== 006 +-- truncate_limit: 100 +-- OK +SELECT '"abc'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"abc'::jsonb" +== 007 +-- truncate_limit: 100 +-- ERROR, quotes not closed +SELECT '"abc +def"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"abc\ndef\"'::jsonb" +== 008 +-- truncate_limit: 100 +-- ERROR, unescaped newline in string constant +SELECT '"\n\"\\"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\n\\\\\"\\\\\\\\\"'::jsonb" +== 009 +-- truncate_limit: 100 +-- OK, legal escapes +SELECT '"\v"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\v\"'::jsonb" +== 010 +-- truncate_limit: 100 +-- ERROR, not a valid JSON escape +-- see json_encoding test for input with unicode escapes + +-- Numbers. +SELECT '1'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::jsonb" +== 011 +-- truncate_limit: 100 +-- OK +SELECT '0'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0'::jsonb" +== 012 +-- truncate_limit: 100 +-- OK +SELECT '01'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '01'::jsonb" +== 013 +-- truncate_limit: 100 +-- ERROR, not valid according to JSON spec +SELECT '0.1'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.1'::jsonb" +== 014 +-- truncate_limit: 100 +-- OK +SELECT '9223372036854775808'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775808'::jsonb" +== 015 +-- truncate_limit: 100 +-- OK, even though it's too large for int8 +SELECT '1e100'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1e100'::jsonb" +== 016 +-- truncate_limit: 100 +-- OK +SELECT '1.3e100'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.3e100'::jsonb" +== 017 +-- truncate_limit: 100 +-- OK +SELECT '1f2'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1f2'::jsonb" +== 018 +-- truncate_limit: 100 +-- ERROR +SELECT '0.x1'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.x1'::jsonb" +== 019 +-- truncate_limit: 100 +-- ERROR +SELECT '1.3ex100'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.3ex100'::jsonb" +== 020 +-- truncate_limit: 100 +-- ERROR + +-- Arrays. +SELECT '[]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb" +== 021 +-- truncate_limit: 100 +-- OK +SELECT '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 022 +-- truncate_limit: 100 +-- OK +SELECT '[1,2]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2]'::jsonb" +== 023 +-- truncate_limit: 100 +-- OK +SELECT '[1,2,]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,]'::jsonb" +== 024 +-- truncate_limit: 100 +-- ERROR, trailing comma +SELECT '[1,2'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2'::jsonb" +== 025 +-- truncate_limit: 100 +-- ERROR, no closing bracket +SELECT '[1,[2]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,[2]'::jsonb" +== 026 +-- truncate_limit: 100 +-- ERROR, no closing bracket + +-- Objects. +SELECT '{}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb" +== 027 +-- truncate_limit: 100 +-- OK +SELECT '{"abc"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\"}'::jsonb" +== 028 +-- truncate_limit: 100 +-- ERROR, no value +SELECT '{"abc":1}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1}'::jsonb" +== 029 +-- truncate_limit: 100 +-- OK +SELECT '{1:"abc"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{1:\"abc\"}'::jsonb" +== 030 +-- truncate_limit: 100 +-- ERROR, keys must be strings +SELECT '{"abc",1}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\",1}'::jsonb" +== 031 +-- truncate_limit: 100 +-- ERROR, wrong separator +SELECT '{"abc"=1}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\"=1}'::jsonb" +== 032 +-- truncate_limit: 100 +-- ERROR, totally wrong separator +SELECT '{"abc"::1}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\"::1}'::jsonb" +== 033 +-- truncate_limit: 100 +-- ERROR, another wrong separator +SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1,\"def\":2,\"ghi\":[3,4],\"hij\":{\"klm\":5,\"nop\":[6]}}'::jsonb" +== 034 +-- truncate_limit: 100 +-- OK +SELECT '{"abc":1:2}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1:2}'::jsonb" +== 035 +-- truncate_limit: 100 +-- ERROR, colon in wrong spot +SELECT '{"abc":1,3}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"abc\":1,3}'::jsonb" +== 036 +-- truncate_limit: 100 +-- ERROR, no value + +-- Recursion. +SET max_stack_depth = '100kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_stack_depth TO \"100kB\"" +== 037 +-- truncate_limit: 100 +SELECT repeat('[', 10000)::jsonb +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT repeat('[', 10000)::jsonb" +== 038 +-- truncate_limit: 100 +SELECT repeat('{"a":', 10000)::jsonb +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT repeat('{\"a\":', 10000)::jsonb" +== 039 +-- truncate_limit: 100 +RESET max_stack_depth +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_stack_depth" +== 040 +-- truncate_limit: 100 +-- Miscellaneous stuff. +SELECT 'true'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true'::jsonb" +== 041 +-- truncate_limit: 100 +-- OK +SELECT 'false'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'false'::jsonb" +== 042 +-- truncate_limit: 100 +-- OK +SELECT 'null'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'null'::jsonb" +== 043 +-- truncate_limit: 100 +-- OK +SELECT ' true '::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' true '::jsonb" +== 044 +-- truncate_limit: 100 +-- OK, even with extra whitespace +SELECT 'true false'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true false'::jsonb" +== 045 +-- truncate_limit: 100 +-- ERROR, too many values +SELECT 'true, false'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true, false'::jsonb" +== 046 +-- truncate_limit: 100 +-- ERROR, too many values +SELECT 'truf'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'truf'::jsonb" +== 047 +-- truncate_limit: 100 +-- ERROR, not a keyword +SELECT 'trues'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'trues'::jsonb" +== 048 +-- truncate_limit: 100 +-- ERROR, not a keyword +SELECT ''::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::jsonb" +== 049 +-- truncate_limit: 100 +-- ERROR, no value +SELECT ' '::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' '::jsonb" +== 050 +-- truncate_limit: 100 +-- ERROR, no value + +-- Multi-line JSON input to check ERROR reporting +SELECT '{ + "one": 1, + "two":"two", + "three": + true}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\n\t\t\"one\": 1,\n\t\t\"two\":\"two\",\n\t\t\"three\":\n\t\ttrue}'::jsonb" +== 051 +-- truncate_limit: 100 +-- OK +SELECT '{ + "one": 1, + "two":,"two", -- ERROR extraneous comma before field "two" + "three": + true}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 052 +-- truncate_limit: 100 +SELECT '{ + "one": 1, + "two":"two", + "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 053 +-- truncate_limit: 100 +-- ERROR missing value for last field + +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'jsonb') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{\"a\":true}', 'jsonb')" +== 054 +-- truncate_limit: 100 +select pg_input_is_valid('{"a":true', 'jsonb') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{\"a\":true', 'jsonb')" +== 055 +-- truncate_limit: 100 +select * from pg_input_error_info('{"a":true', 'jsonb') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{\"a\":true', 'jsonb')" +== 056 +-- truncate_limit: 100 +select * from pg_input_error_info('{"a":1e1000000}', 'jsonb') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{\"a\":1e1000000}', 'jsonb')" +== 057 +-- truncate_limit: 100 +-- make sure jsonb is passed through json generators without being escaped +SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']) +-- +FUNCTION: name="array_to_json" function="array_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_json(ARRAY['{\"a\":1}'::jsonb, '{\"b\":[2,3]}'::jsonb])" +== 058 +-- truncate_limit: 100 +-- anyarray column + +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE rows AS SELECT x, 'txt' || x AS y FROM generate_series(1, 3) x" +== 059 +-- truncate_limit: 100 +analyze rows +-- +TABLE: name="rows" schema="" table="rows" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE rows" +== 060 +-- truncate_limit: 100 +select attname, to_jsonb(histogram_bounds) histogram_bounds +from pg_stats +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1 +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +FUNCTION: name="pg_my_temp_schema" function="pg_my_temp_schema" schema="" ctx=Call +FILTER: schema="" table="" column="tablename" +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +TRUNCATED: "SELECT attname, to_jsonb(histogram_bounds) AS histogram_bounds FROM pg_stats WHERE ... ORDER BY 1" +== 061 +-- truncate_limit: 100 +-- to_jsonb, timestamps + +select to_jsonb(timestamp '2014-05-28 12:22:35.614298') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('2014-05-28 12:22:35.614298'::timestamp)" +== 062 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 063 +-- truncate_limit: 100 +SET LOCAL TIME ZONE 10.5 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO 10.5" +== 064 +-- truncate_limit: 100 +select to_jsonb(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('2014-05-28 12:22:35.614298-04'::timestamptz)" +== 065 +-- truncate_limit: 100 +SET LOCAL TIME ZONE -8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO -8" +== 066 +-- truncate_limit: 100 +select to_jsonb(timestamptz '2014-05-28 12:22:35.614298-04') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('2014-05-28 12:22:35.614298-04'::timestamptz)" +== 067 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 068 +-- truncate_limit: 100 +select to_jsonb(date '2014-05-28') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('2014-05-28'::date)" +== 069 +-- truncate_limit: 100 +select to_jsonb(date 'Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('Infinity'::date)" +== 070 +-- truncate_limit: 100 +select to_jsonb(date '-Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('-Infinity'::date)" +== 071 +-- truncate_limit: 100 +select to_jsonb(timestamp 'Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('Infinity'::timestamp)" +== 072 +-- truncate_limit: 100 +select to_jsonb(timestamp '-Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('-Infinity'::timestamp)" +== 073 +-- truncate_limit: 100 +select to_jsonb(timestamptz 'Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('Infinity'::timestamptz)" +== 074 +-- truncate_limit: 100 +select to_jsonb(timestamptz '-Infinity') +-- +FUNCTION: name="to_jsonb" function="to_jsonb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_jsonb('-Infinity'::timestamptz)" +== 075 +-- truncate_limit: 100 +--jsonb_agg + +SELECT jsonb_agg(q) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q +-- +FUNCTION: name="jsonb_agg" function="jsonb_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_agg(q) FROM (SELECT ... FROM generate_series(1, 2) x, generate_series(4, 5) y) q" +== 076 +-- truncate_limit: 100 +SELECT jsonb_agg(q ORDER BY x, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="jsonb_agg" function="jsonb_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_agg(q ORDER BY x, y) FROM rows q" +== 077 +-- truncate_limit: 100 +UPDATE rows SET x = NULL WHERE x = 1 +-- +TABLE: name="rows" schema="" table="rows" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rows SET x = NULL WHERE x = 1" +== 078 +-- truncate_limit: 100 +SELECT jsonb_agg(q ORDER BY x NULLS FIRST, y) + FROM rows q +-- +TABLE: name="rows" schema="" table="rows" ctx=Select +ALIAS: "q"="rows" +FUNCTION: name="jsonb_agg" function="jsonb_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_agg(q ORDER BY x NULLS FIRST, y) FROM rows q" +== 079 +-- truncate_limit: 100 +-- jsonb extraction functions +CREATE TEMP TABLE test_jsonb ( + json_type text, + test_json jsonb +) +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_jsonb (json_type text, test_json jsonb)" +== 080 +-- truncate_limit: 100 +INSERT INTO test_jsonb VALUES +('scalar','"a scalar"'), +('array','["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}]'), +('object','{"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}}') +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb VALUES (...)" +== 081 +-- truncate_limit: 100 +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'scalar'" +== 082 +-- truncate_limit: 100 +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'array'" +== 083 +-- truncate_limit: 100 +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'object'" +== 084 +-- truncate_limit: 100 +SELECT test_json -> 'field2' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'field2' FROM test_jsonb WHERE json_type = 'object'" +== 085 +-- truncate_limit: 100 +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'scalar'" +== 086 +-- truncate_limit: 100 +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'array'" +== 087 +-- truncate_limit: 100 +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object'" +== 088 +-- truncate_limit: 100 +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'scalar'" +== 089 +-- truncate_limit: 100 +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'array'" +== 090 +-- truncate_limit: 100 +SELECT test_json -> 9 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 9 FROM test_jsonb WHERE json_type = 'array'" +== 091 +-- truncate_limit: 100 +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'object'" +== 092 +-- truncate_limit: 100 +SELECT test_json ->> 6 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 6 FROM test_jsonb WHERE json_type = 'array'" +== 093 +-- truncate_limit: 100 +SELECT test_json ->> 7 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 7 FROM test_jsonb WHERE json_type = 'array'" +== 094 +-- truncate_limit: 100 +SELECT test_json ->> 'field4' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field4' FROM test_jsonb WHERE json_type = 'object'" +== 095 +-- truncate_limit: 100 +SELECT test_json ->> 'field5' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field5' FROM test_jsonb WHERE json_type = 'object'" +== 096 +-- truncate_limit: 100 +SELECT test_json ->> 'field6' FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field6' FROM test_jsonb WHERE json_type = 'object'" +== 097 +-- truncate_limit: 100 +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'scalar'" +== 098 +-- truncate_limit: 100 +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'array'" +== 099 +-- truncate_limit: 100 +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'object'" +== 100 +-- truncate_limit: 100 +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'scalar' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FUNCTION: name="jsonb_object_keys" function="jsonb_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'scalar'" +== 101 +-- truncate_limit: 100 +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FUNCTION: name="jsonb_object_keys" function="jsonb_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'array'" +== 102 +-- truncate_limit: 100 +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FUNCTION: name="jsonb_object_keys" function="jsonb_object_keys" schema="" ctx=Call +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'object'" +== 103 +-- truncate_limit: 100 +-- nulls +SELECT (test_json->'field3') IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 'field3' IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'object'" +== 104 +-- truncate_limit: 100 +SELECT (test_json->>'field3') IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'object' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 'field3' IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'object'" +== 105 +-- truncate_limit: 100 +SELECT (test_json->3) IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json -> 3 IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'array'" +== 106 +-- truncate_limit: 100 +SELECT (test_json->>3) IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'array' +-- +TABLE: name="test_jsonb" schema="" table="test_jsonb" ctx=Select +FILTER: schema="" table="" column="json_type" +STMT: SelectStmt +TRUNCATED: "SELECT test_json ->> 3 IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'array'" +== 107 +-- truncate_limit: 100 +-- corner cases +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> null::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb -> NULL::text" +== 108 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> null::int +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb -> NULL::int" +== 109 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb -> 1" +== 110 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb -> 'z'" +== 111 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb -> ''" +== 112 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb -> 1" +== 113 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb -> 3" +== 114 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb -> 'z'" +== 115 +-- truncate_limit: 100 +select '{"a": "c", "b": null}'::jsonb -> 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": \"c\", \"b\": null}'::jsonb -> 'b'" +== 116 +-- truncate_limit: 100 +select '"foo"'::jsonb -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb -> 1" +== 117 +-- truncate_limit: 100 +select '"foo"'::jsonb -> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb -> 'z'" +== 118 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> null::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb ->> NULL::text" +== 119 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> null::int +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb ->> NULL::int" +== 120 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb ->> 1" +== 121 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb ->> 'z'" +== 122 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb ->> ''" +== 123 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb ->> 1" +== 124 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb ->> 3" +== 125 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb ->> 'z'" +== 126 +-- truncate_limit: 100 +select '{"a": "c", "b": null}'::jsonb ->> 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": \"c\", \"b\": null}'::jsonb ->> 'b'" +== 127 +-- truncate_limit: 100 +select '"foo"'::jsonb ->> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb ->> 1" +== 128 +-- truncate_limit: 100 +select '"foo"'::jsonb ->> 'z' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb ->> 'z'" +== 129 +-- truncate_limit: 100 +-- equality and inequality +SELECT '{"x":"y"}'::jsonb = '{"x":"y"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"x\":\"y\"}'::jsonb = '{\"x\":\"y\"}'::jsonb" +== 130 +-- truncate_limit: 100 +SELECT '{"x":"y"}'::jsonb = '{"x":"z"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"x\":\"y\"}'::jsonb = '{\"x\":\"z\"}'::jsonb" +== 131 +-- truncate_limit: 100 +SELECT '{"x":"y"}'::jsonb <> '{"x":"y"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"x\":\"y\"}'::jsonb <> '{\"x\":\"y\"}'::jsonb" +== 132 +-- truncate_limit: 100 +SELECT '{"x":"y"}'::jsonb <> '{"x":"z"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"x\":\"y\"}'::jsonb <> '{\"x\":\"z\"}'::jsonb" +== 133 +-- truncate_limit: 100 +-- containment +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contains('{\"a\":\"b\", \"b\":1, \"c\":null}', '{\"a\":\"b\"}')" +== 134 +-- truncate_limit: 100 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "c":null}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contains('{\"a\":\"b\", \"b\":1, \"c\":null}', '{\"a\":\"b\", \"c\":null}')" +== 135 +-- truncate_limit: 100 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "g":null}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contains('{\"a\":\"b\", \"b\":1, \"c\":null}', '{\"a\":\"b\", \"g\":null}')" +== 136 +-- truncate_limit: 100 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"g":null}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contains('{\"a\":\"b\", \"b\":1, \"c\":null}', '{\"g\":null}')" +== 137 +-- truncate_limit: 100 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"c"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contains('{\"a\":\"b\", \"b\":1, \"c\":null}', '{\"a\":\"c\"}')" +== 138 +-- truncate_limit: 100 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contains('{\"a\":\"b\", \"b\":1, \"c\":null}', '{\"a\":\"b\"}')" +== 139 +-- truncate_limit: 100 +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "c":"q"}') +-- +FUNCTION: name="jsonb_contains" function="jsonb_contains" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contains('{\"a\":\"b\", \"b\":1, \"c\":null}', '{\"a\":\"b\", \"c\":\"q\"}')" +== 140 +-- truncate_limit: 100 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b"}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"b\":1, \"c\":null}'::jsonb @> '{\"a\":\"b\"}'" +== 141 +-- truncate_limit: 100 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"b\":1, \"c\":null}'::jsonb @> '{\"a\":\"b\", \"c\":null}'" +== 142 +-- truncate_limit: 100 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "g":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"b\":1, \"c\":null}'::jsonb @> '{\"a\":\"b\", \"g\":null}'" +== 143 +-- truncate_limit: 100 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"g":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"b\":1, \"c\":null}'::jsonb @> '{\"g\":null}'" +== 144 +-- truncate_limit: 100 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"c"}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"b\":1, \"c\":null}'::jsonb @> '{\"a\":\"c\"}'" +== 145 +-- truncate_limit: 100 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b"}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"b\":1, \"c\":null}'::jsonb @> '{\"a\":\"b\"}'" +== 146 +-- truncate_limit: 100 +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "c":"q"}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"b\":1, \"c\":null}'::jsonb @> '{\"a\":\"b\", \"c\":\"q\"}'" +== 147 +-- truncate_limit: 100 +SELECT '[1,2]'::jsonb @> '[1,2,2]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2]'::jsonb @> '[1,2,2]'::jsonb" +== 148 +-- truncate_limit: 100 +SELECT '[1,1,2]'::jsonb @> '[1,2,2]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,1,2]'::jsonb @> '[1,2,2]'::jsonb" +== 149 +-- truncate_limit: 100 +SELECT '[[1,2]]'::jsonb @> '[[1,2,2]]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[[1,2]]'::jsonb @> '[[1,2,2]]'::jsonb" +== 150 +-- truncate_limit: 100 +SELECT '[1,2,2]'::jsonb <@ '[1,2]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,2]'::jsonb <@ '[1,2]'::jsonb" +== 151 +-- truncate_limit: 100 +SELECT '[1,2,2]'::jsonb <@ '[1,1,2]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,2]'::jsonb <@ '[1,1,2]'::jsonb" +== 152 +-- truncate_limit: 100 +SELECT '[[1,2,2]]'::jsonb <@ '[[1,2]]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[[1,2,2]]'::jsonb <@ '[[1,2]]'::jsonb" +== 153 +-- truncate_limit: 100 +SELECT jsonb_contained('{"a":"b"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contained('{\"a\":\"b\"}', '{\"a\":\"b\", \"b\":1, \"c\":null}')" +== 154 +-- truncate_limit: 100 +SELECT jsonb_contained('{"a":"b", "c":null}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contained('{\"a\":\"b\", \"c\":null}', '{\"a\":\"b\", \"b\":1, \"c\":null}')" +== 155 +-- truncate_limit: 100 +SELECT jsonb_contained('{"a":"b", "g":null}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contained('{\"a\":\"b\", \"g\":null}', '{\"a\":\"b\", \"b\":1, \"c\":null}')" +== 156 +-- truncate_limit: 100 +SELECT jsonb_contained('{"g":null}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contained('{\"g\":null}', '{\"a\":\"b\", \"b\":1, \"c\":null}')" +== 157 +-- truncate_limit: 100 +SELECT jsonb_contained('{"a":"c"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contained('{\"a\":\"c\"}', '{\"a\":\"b\", \"b\":1, \"c\":null}')" +== 158 +-- truncate_limit: 100 +SELECT jsonb_contained('{"a":"b"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contained('{\"a\":\"b\"}', '{\"a\":\"b\", \"b\":1, \"c\":null}')" +== 159 +-- truncate_limit: 100 +SELECT jsonb_contained('{"a":"b", "c":"q"}', '{"a":"b", "b":1, "c":null}') +-- +FUNCTION: name="jsonb_contained" function="jsonb_contained" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_contained('{\"a\":\"b\", \"c\":\"q\"}', '{\"a\":\"b\", \"b\":1, \"c\":null}')" +== 160 +-- truncate_limit: 100 +SELECT '{"a":"b"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\"}'::jsonb <@ '{\"a\":\"b\", \"b\":1, \"c\":null}'" +== 161 +-- truncate_limit: 100 +SELECT '{"a":"b", "c":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"c\":null}'::jsonb <@ '{\"a\":\"b\", \"b\":1, \"c\":null}'" +== 162 +-- truncate_limit: 100 +SELECT '{"a":"b", "g":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"g\":null}'::jsonb <@ '{\"a\":\"b\", \"b\":1, \"c\":null}'" +== 163 +-- truncate_limit: 100 +SELECT '{"g":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"g\":null}'::jsonb <@ '{\"a\":\"b\", \"b\":1, \"c\":null}'" +== 164 +-- truncate_limit: 100 +SELECT '{"a":"c"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"c\"}'::jsonb <@ '{\"a\":\"b\", \"b\":1, \"c\":null}'" +== 165 +-- truncate_limit: 100 +SELECT '{"a":"b"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\"}'::jsonb <@ '{\"a\":\"b\", \"b\":1, \"c\":null}'" +== 166 +-- truncate_limit: 100 +SELECT '{"a":"b", "c":"q"}'::jsonb <@ '{"a":"b", "b":1, "c":null}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\", \"c\":\"q\"}'::jsonb <@ '{\"a\":\"b\", \"b\":1, \"c\":null}'" +== 167 +-- truncate_limit: 100 +-- Raw scalar may contain another raw scalar, array may contain a raw scalar +SELECT '[5]'::jsonb @> '[5]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[5]'::jsonb @> '[5]'" +== 168 +-- truncate_limit: 100 +SELECT '5'::jsonb @> '5' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5'::jsonb @> '5'" +== 169 +-- truncate_limit: 100 +SELECT '[5]'::jsonb @> '5' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[5]'::jsonb @> '5'" +== 170 +-- truncate_limit: 100 +-- But a raw scalar cannot contain an array +SELECT '5'::jsonb @> '[5]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '5'::jsonb @> '[5]'" +== 171 +-- truncate_limit: 100 +-- In general, one thing should always contain itself. Test array containment: +SELECT '["9", ["7", "3"], 1]'::jsonb @> '["9", ["7", "3"], 1]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"9\", [\"7\", \"3\"], 1]'::jsonb @> '[\"9\", [\"7\", \"3\"], 1]'::jsonb" +== 172 +-- truncate_limit: 100 +SELECT '["9", ["7", "3"], ["1"]]'::jsonb @> '["9", ["7", "3"], ["1"]]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"9\", [\"7\", \"3\"], [\"1\"]]'::jsonb @> '[\"9\", [\"7\", \"3\"], [\"1\"]]'::jsonb" +== 173 +-- truncate_limit: 100 +-- array containment string matching confusion bug +SELECT '{ "name": "Bob", "tags": [ "enim", "qui"]}'::jsonb @> '{"tags":["qu"]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{ \"name\": \"Bob\", \"tags\": [ \"enim\", \"qui\"]}'::jsonb @> '{\"tags\":[\"qu\"]}'" +== 174 +-- truncate_limit: 100 +-- array length +SELECT jsonb_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_array_length('[1,2,3,{\"f1\":1,\"f2\":[5,6]},4]')" +== 175 +-- truncate_limit: 100 +SELECT jsonb_array_length('[]') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_array_length('[]')" +== 176 +-- truncate_limit: 100 +SELECT jsonb_array_length('{"f1":1,"f2":[5,6]}') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_array_length('{\"f1\":1,\"f2\":[5,6]}')" +== 177 +-- truncate_limit: 100 +SELECT jsonb_array_length('4') +-- +FUNCTION: name="jsonb_array_length" function="jsonb_array_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_array_length('4')" +== 178 +-- truncate_limit: 100 +-- each +SELECT jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null}') +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_each('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null}')" +== 179 +-- truncate_limit: 100 +SELECT jsonb_each('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 180 +-- truncate_limit: 100 +SELECT * FROM jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_each('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null,\"f5\":99,\"f6\":\"stringy\"}') q" +== 181 +-- truncate_limit: 100 +SELECT * FROM jsonb_each('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_each('{\"a\":{\"b\":\"c\",\"c\":\"b\",\"1\":\"first\"},\"b\":[1,2],\"c\":\"cc\",\"1\":\"first\",\"n\":n..." +== 182 +-- truncate_limit: 100 +SELECT jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}') +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_each_text('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null,\"f5\":\"null\"}')" +== 183 +-- truncate_limit: 100 +SELECT jsonb_each_text('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 184 +-- truncate_limit: 100 +SELECT * FROM jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_each_text('{\"f1\":[1,2,3],\"f2\":{\"f3\":1},\"f4\":null,\"f5\":99,\"f6\":\"stringy\"}') q" +== 185 +-- truncate_limit: 100 +SELECT * FROM jsonb_each_text('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q +-- +FUNCTION: name="jsonb_each_text" function="jsonb_each_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_each_text('{\"a\":{\"b\":\"c\",\"c\":\"b\",\"1\":\"first\"},\"b\":[1,2],\"c\":\"cc\",\"1\":\"first\",..." +== 186 +-- truncate_limit: 100 +-- exists +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'a') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists('{\"a\":null, \"b\":\"qq\"}', 'a')" +== 187 +-- truncate_limit: 100 +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'b') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists('{\"a\":null, \"b\":\"qq\"}', 'b')" +== 188 +-- truncate_limit: 100 +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'c') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists('{\"a\":null, \"b\":\"qq\"}', 'c')" +== 189 +-- truncate_limit: 100 +SELECT jsonb_exists('{"a":"null", "b":"qq"}', 'a') +-- +FUNCTION: name="jsonb_exists" function="jsonb_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists('{\"a\":\"null\", \"b\":\"qq\"}', 'a')" +== 190 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ? 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ? 'a'" +== 191 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ? 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ? 'b'" +== 192 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ? 'c' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ? 'c'" +== 193 +-- truncate_limit: 100 +SELECT jsonb '{"a":"null", "b":"qq"}' ? 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"null\", \"b\":\"qq\"}'::jsonb ? 'a'" +== 194 +-- truncate_limit: 100 +-- array exists - array elements should behave as keys +SELECT count(*) from testjsonb WHERE j->'array' ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE (j -> 'array') ? 'bar'" +== 195 +-- truncate_limit: 100 +-- type sensitive array exists - should return no rows (since "exists" only +-- matches strings that are either object keys or array elements) +SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE (j -> 'array') ? '5'::text" +== 196 +-- truncate_limit: 100 +-- However, a raw scalar is *contained* within the array +SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE (j -> 'array') @> '5'::jsonb" +== 197 +-- truncate_limit: 100 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['a','b']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_any('{\"a\":null, \"b\":\"qq\"}', ARRAY['a', 'b'])" +== 198 +-- truncate_limit: 100 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['b','a']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_any('{\"a\":null, \"b\":\"qq\"}', ARRAY['b', 'a'])" +== 199 +-- truncate_limit: 100 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['c','a']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_any('{\"a\":null, \"b\":\"qq\"}', ARRAY['c', 'a'])" +== 200 +-- truncate_limit: 100 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['c','d']) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_any('{\"a\":null, \"b\":\"qq\"}', ARRAY['c', 'd'])" +== 201 +-- truncate_limit: 100 +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', '{}'::text[]) +-- +FUNCTION: name="jsonb_exists_any" function="jsonb_exists_any" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_any('{\"a\":null, \"b\":\"qq\"}', '{}'::text[])" +== 202 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['a','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?| ARRAY['a', 'b']" +== 203 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['b','a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?| ARRAY['b', 'a']" +== 204 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['c','a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?| ARRAY['c', 'a']" +== 205 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['c','d'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?| ARRAY['c', 'd']" +== 206 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?| '{}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?| '{}'::text[]" +== 207 +-- truncate_limit: 100 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['a','b']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_all('{\"a\":null, \"b\":\"qq\"}', ARRAY['a', 'b'])" +== 208 +-- truncate_limit: 100 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['b','a']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_all('{\"a\":null, \"b\":\"qq\"}', ARRAY['b', 'a'])" +== 209 +-- truncate_limit: 100 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['c','a']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_all('{\"a\":null, \"b\":\"qq\"}', ARRAY['c', 'a'])" +== 210 +-- truncate_limit: 100 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['c','d']) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_all('{\"a\":null, \"b\":\"qq\"}', ARRAY['c', 'd'])" +== 211 +-- truncate_limit: 100 +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', '{}'::text[]) +-- +FUNCTION: name="jsonb_exists_all" function="jsonb_exists_all" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_exists_all('{\"a\":null, \"b\":\"qq\"}', '{}'::text[])" +== 212 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['a','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?& ARRAY['a', 'b']" +== 213 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['b','a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?& ARRAY['b', 'a']" +== 214 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['c','a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?& ARRAY['c', 'a']" +== 215 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['c','d'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?& ARRAY['c', 'd']" +== 216 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['a','a', 'b', 'b', 'b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?& ARRAY['a', 'a', 'b', 'b', 'b']" +== 217 +-- truncate_limit: 100 +SELECT jsonb '{"a":null, "b":"qq"}' ?& '{}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null, \"b\":\"qq\"}'::jsonb ?& '{}'::text[]" +== 218 +-- truncate_limit: 100 +-- typeof +SELECT jsonb_typeof('{}') AS object +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('{}') AS object" +== 219 +-- truncate_limit: 100 +SELECT jsonb_typeof('{"c":3,"p":"o"}') AS object +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('{\"c\":3,\"p\":\"o\"}') AS object" +== 220 +-- truncate_limit: 100 +SELECT jsonb_typeof('[]') AS array +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('[]') AS \"array\"" +== 221 +-- truncate_limit: 100 +SELECT jsonb_typeof('["a", 1]') AS array +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('[\"a\", 1]') AS \"array\"" +== 222 +-- truncate_limit: 100 +SELECT jsonb_typeof('null') AS "null" +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('null') AS \"null\"" +== 223 +-- truncate_limit: 100 +SELECT jsonb_typeof('1') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('1') AS number" +== 224 +-- truncate_limit: 100 +SELECT jsonb_typeof('-1') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('-1') AS number" +== 225 +-- truncate_limit: 100 +SELECT jsonb_typeof('1.0') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('1.0') AS number" +== 226 +-- truncate_limit: 100 +SELECT jsonb_typeof('1e2') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('1e2') AS number" +== 227 +-- truncate_limit: 100 +SELECT jsonb_typeof('-1.0') AS number +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('-1.0') AS number" +== 228 +-- truncate_limit: 100 +SELECT jsonb_typeof('true') AS boolean +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('true') AS \"boolean\"" +== 229 +-- truncate_limit: 100 +SELECT jsonb_typeof('false') AS boolean +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('false') AS \"boolean\"" +== 230 +-- truncate_limit: 100 +SELECT jsonb_typeof('"hello"') AS string +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('\"hello\"') AS string" +== 231 +-- truncate_limit: 100 +SELECT jsonb_typeof('"true"') AS string +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('\"true\"') AS string" +== 232 +-- truncate_limit: 100 +SELECT jsonb_typeof('"1.0"') AS string +-- +FUNCTION: name="jsonb_typeof" function="jsonb_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_typeof('\"1.0\"') AS string" +== 233 +-- truncate_limit: 100 +-- jsonb_build_array, jsonb_build_object, jsonb_object_agg + +SELECT jsonb_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 234 +-- truncate_limit: 100 +SELECT jsonb_build_array('a', NULL) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array('a', NULL)" +== 235 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_array(VARIADIC NULL::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array(VARIADIC NULL::text[])" +== 236 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_array(VARIADIC '{}'::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array(VARIADIC '{}'::text[])" +== 237 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_array(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array(VARIADIC '{a,b,c}'::text[])" +== 238 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_array(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array(VARIADIC ARRAY['a', NULL]::text[])" +== 239 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::text[])" +== 240 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::int[])" +== 241 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][])" +== 242 +-- truncate_limit: 100 +-- ok + +SELECT jsonb_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}') +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 243 +-- truncate_limit: 100 +SELECT jsonb_build_object( + 'a', jsonb_build_object('b',false,'c',99), + 'd', jsonb_build_object('e',array[9,8,7]::int[], + 'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r))) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 244 +-- truncate_limit: 100 +SELECT jsonb_build_object('{a,b,c}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object('{a,b,c}'::text[])" +== 245 +-- truncate_limit: 100 +-- error +SELECT jsonb_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object('{a,b,c}'::text[], '{d,e,f}'::text[])" +== 246 +-- truncate_limit: 100 +-- error, key cannot be array +SELECT jsonb_build_object('a', 'b', 'c') +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object('a', 'b', 'c')" +== 247 +-- truncate_limit: 100 +-- error +SELECT jsonb_build_object(NULL, 'a') +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(NULL, 'a')" +== 248 +-- truncate_limit: 100 +-- error, key cannot be NULL +SELECT jsonb_build_object('a', NULL) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object('a', NULL)" +== 249 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_object(VARIADIC NULL::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC NULL::text[])" +== 250 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_object(VARIADIC '{}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC '{}'::text[])" +== 251 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_object(VARIADIC '{a,b,c}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC '{a,b,c}'::text[])" +== 252 +-- truncate_limit: 100 +-- error +SELECT jsonb_build_object(VARIADIC ARRAY['a', NULL]::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC ARRAY['a', NULL]::text[])" +== 253 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_object(VARIADIC ARRAY[NULL, 'a']::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC ARRAY[NULL, 'a']::text[])" +== 254 +-- truncate_limit: 100 +-- error, key cannot be NULL +SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::text[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::text[])" +== 255 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::int[]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::int[])" +== 256 +-- truncate_limit: 100 +-- ok +SELECT jsonb_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][])" +== 257 +-- truncate_limit: 100 +-- ok + +-- empty objects/arrays +SELECT jsonb_build_array() +-- +FUNCTION: name="jsonb_build_array" function="jsonb_build_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_array()" +== 258 +-- truncate_limit: 100 +SELECT jsonb_build_object() +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object()" +== 259 +-- truncate_limit: 100 +-- make sure keys are quoted +SELECT jsonb_build_object(1,2) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(1, 2)" +== 260 +-- truncate_limit: 100 +-- keys must be scalar and not null +SELECT jsonb_build_object(null,2) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(NULL, 2)" +== 261 +-- truncate_limit: 100 +SELECT jsonb_build_object(r,2) FROM (SELECT 1 AS a, 2 AS b) r +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object(r, 2) FROM (SELECT 1 AS a, 2 AS b) r" +== 262 +-- truncate_limit: 100 +SELECT jsonb_build_object(json '{"a":1,"b":2}', 3) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object('{\"a\":1,\"b\":2}'::pg_catalog.json, 3)" +== 263 +-- truncate_limit: 100 +SELECT jsonb_build_object('{1,2,3}'::int[], 3) +-- +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_build_object('{1,2,3}'::int[], 3)" +== 264 +-- truncate_limit: 100 +-- handling of NULL values +SELECT jsonb_object_agg(1, NULL::jsonb) +-- +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_agg(1, NULL::jsonb)" +== 265 +-- truncate_limit: 100 +SELECT jsonb_object_agg(NULL, '{"a":1}') +-- +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_agg(NULL, '{\"a\":1}')" +== 266 +-- truncate_limit: 100 +CREATE TEMP TABLE foo (serial_num int, name text, type text) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (serial_num int, name text, type text)" +== 267 +-- truncate_limit: 100 +INSERT INTO foo VALUES (847001,'t15','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (847001, 't15', 'GE1043')" +== 268 +-- truncate_limit: 100 +INSERT INTO foo VALUES (847002,'t16','GE1043') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (847002, 't16', 'GE1043')" +== 269 +-- truncate_limit: 100 +INSERT INTO foo VALUES (847003,'sub-alpha','GESS90') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (847003, 'sub-alpha', 'GESS90')" +== 270 +-- truncate_limit: 100 +SELECT jsonb_build_object('turbines',jsonb_object_agg(serial_num,jsonb_build_object('name',name,'type',type))) +FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM foo" +== 271 +-- truncate_limit: 100 +SELECT jsonb_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_agg(name, type) FROM foo" +== 272 +-- truncate_limit: 100 +INSERT INTO foo VALUES (999999, NULL, 'bar') +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (999999, NULL, 'bar')" +== 273 +-- truncate_limit: 100 +SELECT jsonb_object_agg(name, type) FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_agg(name, type) FROM foo" +== 274 +-- truncate_limit: 100 +-- edge case for parser +SELECT jsonb_object_agg(DISTINCT 'a', 'abc') +-- +FUNCTION: name="jsonb_object_agg" function="jsonb_object_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object_agg(DISTINCT 'a', 'abc')" +== 275 +-- truncate_limit: 100 +-- jsonb_object + +-- empty object, one dimension +SELECT jsonb_object('{}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{}')" +== 276 +-- truncate_limit: 100 +-- empty object, two dimensions +SELECT jsonb_object('{}', '{}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{}', '{}')" +== 277 +-- truncate_limit: 100 +-- one dimension +SELECT jsonb_object('{a,1,b,2,3,NULL,"d e f","a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{a,1,b,2,3,NULL,\"d e f\",\"a b c\"}')" +== 278 +-- truncate_limit: 100 +-- same but with two dimensions +SELECT jsonb_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{{a,1},{b,2},{3,NULL},{\"d e f\",\"a b c\"}}')" +== 279 +-- truncate_limit: 100 +-- odd number error +SELECT jsonb_object('{a,b,c}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{a,b,c}')" +== 280 +-- truncate_limit: 100 +-- one column error +SELECT jsonb_object('{{a},{b}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{{a},{b}}')" +== 281 +-- truncate_limit: 100 +-- too many columns error +SELECT jsonb_object('{{a,b,c},{b,c,d}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{{a,b,c},{b,c,d}}')" +== 282 +-- truncate_limit: 100 +-- too many dimensions error +SELECT jsonb_object('{{{a,b},{c,d}},{{b,c},{d,e}}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{{{a,b},{c,d}},{{b,c},{d,e}}}')" +== 283 +-- truncate_limit: 100 +--two argument form of jsonb_object + +select jsonb_object('{a,b,c,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{a,b,c,\"d e f\"}', '{1,2,3,\"a b c\"}')" +== 284 +-- truncate_limit: 100 +-- too many dimensions +SELECT jsonb_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}', '{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 285 +-- truncate_limit: 100 +-- mismatched dimensions + +select jsonb_object('{a,b,c,"d e f",g}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{a,b,c,\"d e f\",g}', '{1,2,3,\"a b c\"}')" +== 286 +-- truncate_limit: 100 +select jsonb_object('{a,b,c,"d e f"}','{1,2,3,"a b c",g}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{a,b,c,\"d e f\"}', '{1,2,3,\"a b c\",g}')" +== 287 +-- truncate_limit: 100 +-- null key error + +select jsonb_object('{a,b,NULL,"d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{a,b,NULL,\"d e f\"}', '{1,2,3,\"a b c\"}')" +== 288 +-- truncate_limit: 100 +-- empty key is allowed + +select jsonb_object('{a,b,"","d e f"}','{1,2,3,"a b c"}') +-- +FUNCTION: name="jsonb_object" function="jsonb_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_object('{a,b,\"\",\"d e f\"}', '{1,2,3,\"a b c\"}')" +== 289 +-- truncate_limit: 100 +-- extract_path, extract_path_as_text +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f4', 'f6')" +== 290 +-- truncate_limit: 100 +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2')" +== 291 +-- truncate_limit: 100 +SELECT jsonb_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 0::text)" +== 292 +-- truncate_limit: 100 +SELECT jsonb_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 1::text)" +== 293 +-- truncate_limit: 100 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6') +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path_text('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f4', 'f6')" +== 294 +-- truncate_limit: 100 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2') +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path_text('{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2')" +== 295 +-- truncate_limit: 100 +SELECT jsonb_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text) +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path_text('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 0::text)" +== 296 +-- truncate_limit: 100 +SELECT jsonb_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text) +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path_text('{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}', 'f2', 1::text)" +== 297 +-- truncate_limit: 100 +-- extract_path nulls +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') IS NULL AS expect_false +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 298 +-- truncate_limit: 100 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') IS NULL AS expect_true +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 299 +-- truncate_limit: 100 +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') IS NULL AS expect_false +-- +FUNCTION: name="jsonb_extract_path" function="jsonb_extract_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_extract_path('{\"f2\":{\"f3\":1},\"f4\":[0,1,2,null]}', 'f4', '3') IS NULL AS expect_false" +== 300 +-- truncate_limit: 100 +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') IS NULL AS expect_true +-- +FUNCTION: name="jsonb_extract_path_text" function="jsonb_extract_path_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 301 +-- truncate_limit: 100 +-- extract_path operators +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f4','f6'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #> ARRAY['f4', 'f6']" +== 302 +-- truncate_limit: 100 +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #> ARRAY['f2']" +== 303 +-- truncate_limit: 100 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2','0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #> ARRAY['f2', '0']" +== 304 +-- truncate_limit: 100 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2','1'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #> ARRAY['f2', '1']" +== 305 +-- truncate_limit: 100 +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f4','f6'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #>> ARRAY['f4', 'f6']" +== 306 +-- truncate_limit: 100 +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":{\"f3\":1},\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #>> ARRAY['f2']" +== 307 +-- truncate_limit: 100 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2','0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #>> ARRAY['f2', '0']" +== 308 +-- truncate_limit: 100 +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2','1'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"f2\":[\"f3\",1],\"f4\":{\"f5\":99,\"f6\":\"stringy\"}}'::jsonb #>> ARRAY['f2', '1']" +== 309 +-- truncate_limit: 100 +-- corner cases for same +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> '{}'" +== 310 +-- truncate_limit: 100 +select '[1,2,3]'::jsonb #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::jsonb #> '{}'" +== 311 +-- truncate_limit: 100 +select '"foo"'::jsonb #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb #> '{}'" +== 312 +-- truncate_limit: 100 +select '42'::jsonb #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::jsonb #> '{}'" +== 313 +-- truncate_limit: 100 +select 'null'::jsonb #> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'null'::jsonb #> '{}'" +== 314 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> ARRAY['a']" +== 315 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a', null] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> ARRAY['a', NULL]" +== 316 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a', ''] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> ARRAY['a', '']" +== 317 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> ARRAY['a', 'b']" +== 318 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> ARRAY['a', 'b', 'c']" +== 319 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b','c','d'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> ARRAY['a', 'b', 'c', 'd']" +== 320 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','z','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #> ARRAY['a', 'z', 'c']" +== 321 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #> array['a','1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb #> ARRAY['a', '1', 'b']" +== 322 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #> array['a','z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb #> ARRAY['a', 'z', 'b']" +== 323 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb #> ARRAY['1', 'b']" +== 324 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #> array['z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb #> ARRAY['z', 'b']" +== 325 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": null}]'::jsonb #> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": null}]'::jsonb #> ARRAY['1', 'b']" +== 326 +-- truncate_limit: 100 +select '"foo"'::jsonb #> array['z'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb #> ARRAY['z']" +== 327 +-- truncate_limit: 100 +select '42'::jsonb #> array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::jsonb #> ARRAY['f2']" +== 328 +-- truncate_limit: 100 +select '42'::jsonb #> array['0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::jsonb #> ARRAY['0']" +== 329 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> '{}'" +== 330 +-- truncate_limit: 100 +select '[1,2,3]'::jsonb #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::jsonb #>> '{}'" +== 331 +-- truncate_limit: 100 +select '"foo"'::jsonb #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb #>> '{}'" +== 332 +-- truncate_limit: 100 +select '42'::jsonb #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::jsonb #>> '{}'" +== 333 +-- truncate_limit: 100 +select 'null'::jsonb #>> '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'null'::jsonb #>> '{}'" +== 334 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> ARRAY['a']" +== 335 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a', null] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> ARRAY['a', NULL]" +== 336 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a', ''] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> ARRAY['a', '']" +== 337 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> ARRAY['a', 'b']" +== 338 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> ARRAY['a', 'b', 'c']" +== 339 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b','c','d'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> ARRAY['a', 'b', 'c', 'd']" +== 340 +-- truncate_limit: 100 +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','z','c'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\":{\"c\": \"foo\"}}}'::jsonb #>> ARRAY['a', 'z', 'c']" +== 341 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #>> array['a','1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb #>> ARRAY['a', '1', 'b']" +== 342 +-- truncate_limit: 100 +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #>> array['a','z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [{\"b\": \"c\"}, {\"b\": \"cc\"}]}'::jsonb #>> ARRAY['a', 'z', 'b']" +== 343 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #>> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb #>> ARRAY['1', 'b']" +== 344 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #>> array['z','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": \"cc\"}]'::jsonb #>> ARRAY['z', 'b']" +== 345 +-- truncate_limit: 100 +select '[{"b": "c"}, {"b": null}]'::jsonb #>> array['1','b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"b\": \"c\"}, {\"b\": null}]'::jsonb #>> ARRAY['1', 'b']" +== 346 +-- truncate_limit: 100 +select '"foo"'::jsonb #>> array['z'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"foo\"'::jsonb #>> ARRAY['z']" +== 347 +-- truncate_limit: 100 +select '42'::jsonb #>> array['f2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::jsonb #>> ARRAY['f2']" +== 348 +-- truncate_limit: 100 +select '42'::jsonb #>> array['0'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::jsonb #>> ARRAY['0']" +== 349 +-- truncate_limit: 100 +-- array_elements +SELECT jsonb_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false]') +-- +FUNCTION: name="jsonb_array_elements" function="jsonb_array_elements" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_array_elements('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false]')" +== 350 +-- truncate_limit: 100 +SELECT * FROM jsonb_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false]') q +-- +FUNCTION: name="jsonb_array_elements" function="jsonb_array_elements" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_array_elements('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false]') q" +== 351 +-- truncate_limit: 100 +SELECT jsonb_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') +-- +FUNCTION: name="jsonb_array_elements_text" function="jsonb_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_array_elements_text('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false,\"stringy\"]')" +== 352 +-- truncate_limit: 100 +SELECT * FROM jsonb_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q +-- +FUNCTION: name="jsonb_array_elements_text" function="jsonb_array_elements_text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_array_elements_text('[1,true,[1,[2,3]],null,{\"f1\":1,\"f2\":[7,8,9]},false,\"stri..." +== 353 +-- truncate_limit: 100 +-- populate_record +CREATE TYPE jbpop AS (a text, b int, c timestamp) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jbpop AS (a text, b int, c timestamp)" +== 354 +-- truncate_limit: 100 +CREATE DOMAIN jsb_int_not_null AS int NOT NULL +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN jsb_int_not_null AS int NOT NULL" +== 355 +-- truncate_limit: 100 +CREATE DOMAIN jsb_int_array_1d AS int[] CHECK(array_length(VALUE, 1) = 3) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN jsb_int_array_1d AS int[] CHECK (array_length(value, 1) = 3)" +== 356 +-- truncate_limit: 100 +CREATE DOMAIN jsb_int_array_2d AS int[][] CHECK(array_length(VALUE, 2) = 3) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN jsb_int_array_2d AS int[][] CHECK (array_length(value, 2) = 3)" +== 357 +-- truncate_limit: 100 +create type jb_unordered_pair as (x int, y int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jb_unordered_pair AS (x int, y int)" +== 358 +-- truncate_limit: 100 +create domain jb_ordered_pair as jb_unordered_pair check((value).x <= (value).y) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN jb_ordered_pair AS jb_unordered_pair CHECK ((value).x <= (value).y)" +== 359 +-- truncate_limit: 100 +CREATE TYPE jsbrec AS ( + i int, + ia _int4, + ia1 int[], + ia2 int[][], + ia3 int[][][], + ia1d jsb_int_array_1d, + ia2d jsb_int_array_2d, + t text, + ta text[], + c char(10), + ca char(10)[], + ts timestamp, + js json, + jsb jsonb, + jsa json[], + rec jbpop, + reca jbpop[] +) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsbrec AS (i int, ia _int4, ia1 int[], ia2 int[][], ia3 int[][][], ia1d jsb_int_array..." +== 360 +-- truncate_limit: 100 +CREATE TYPE jsbrec_i_not_null AS ( + i jsb_int_not_null +) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsbrec_i_not_null AS (i jsb_int_not_null)" +== 361 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jbpop, '{\"a\":\"blurfl\",\"x\":43.2}') q" +== 362 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jbpop, '{\"a\":\"blurfl\",\"x\"..." +== 363 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jbpop, '{\"a\":\"blurfl\",\"x\":43.2}') q" +== 364 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jbpop, '{\"a\":\"blurfl\",\"x\"..." +== 365 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jbpop, '{\"a\":[100,200,false],\"x\":43.2}') q" +== 366 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jbpop, '{\"a\":[100,200,fal..." +== 367 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jbpop, '{\"c\":[100,200,fal..." +== 368 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop, '{}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(ROW('x', 3, '2012-12-31 15:30:56')::jbpop, '{}') q" +== 369 +-- truncate_limit: 100 +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"x": 43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{\"x\": 43.2}') q" +== 370 +-- truncate_limit: 100 +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"i": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{\"i\": null}') q" +== 371 +-- truncate_limit: 100 +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"i": 12345}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{\"i\": 12345}') q" +== 372 +-- truncate_limit: 100 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{\"ia\": null}') q" +== 373 +-- truncate_limit: 100 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{\"ia\": 123}') q" +== 374 +-- truncate_limit: 100 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{\"ia\": [1, \"2\", null, 4]}') q" +== 375 +-- truncate_limit: 100 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1, 2], [3, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{\"ia\": [[1, 2], [3, 4]]}') q" +== 376 +-- truncate_limit: 100 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{\"ia\": [[1], 2]}') q" +== 377 +-- truncate_limit: 100 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], [2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{\"ia\": [[1], [2, 3]]}') q" +== 378 +-- truncate_limit: 100 +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": "{1,2,3}"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{\"ia\": \"{1,2,3}\"}') q" +== 379 +-- truncate_limit: 100 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1\": null}') q" +== 380 +-- truncate_limit: 100 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1\": 123}') q" +== 381 +-- truncate_limit: 100 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1\": [1, \"2\", null, 4]}') q" +== 382 +-- truncate_limit: 100 +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": [[1, 2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1\": [[1, 2, 3]]}') q" +== 383 +-- truncate_limit: 100 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1d\": null}') q" +== 384 +-- truncate_limit: 100 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1d\": 123}') q" +== 385 +-- truncate_limit: 100 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1d\": [1, \"2\", null, 4]}') q" +== 386 +-- truncate_limit: 100 +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": [1, "2", null]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{\"ia1d\": [1, \"2\", null]}') q" +== 387 +-- truncate_limit: 100 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia2\": [1, \"2\", null, 4]}') q" +== 388 +-- truncate_limit: 100 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia2\": [[1, 2], [null, 4]]}') q" +== 389 +-- truncate_limit: 100 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[], []]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia2\": [[], []]}') q" +== 390 +-- truncate_limit: 100 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], [3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia2\": [[1, 2], [3]]}') q" +== 391 +-- truncate_limit: 100 +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], 3, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia2\": [[1, 2], 3, 4]}') q" +== 392 +-- truncate_limit: 100 +SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{"ia2d": [[1, "2"], [null, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{\"ia2d\": [[1, \"2\"], [null, 4]]}') q" +== 393 +-- truncate_limit: 100 +SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{"ia2d": [[1, "2", 3], [null, 5, 6]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{\"ia2d\": [[1, \"2\", 3], [null, 5, 6]]}') q" +== 394 +-- truncate_limit: 100 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia3\": [1, \"2\", null, 4]}') q" +== 395 +-- truncate_limit: 100 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [[1, 2], [null, 4]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia3\": [[1, 2], [null, 4]]}') q" +== 396 +-- truncate_limit: 100 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[], []], [[], []], [[], []] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia3\": [ [[], []], [[], []], [[], []] ]}') q" +== 397 +-- truncate_limit: 100 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2]], [[3, 4]] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia3\": [ [[1, 2]], [[3, 4]] ]}') q" +== 398 +-- truncate_limit: 100 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia3\": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]]..." +== 399 +-- truncate_limit: 100 +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{\"ia3\": [ [[1, 2], [3, 4]], [[5, 6], [7, 8],..." +== 400 +-- truncate_limit: 100 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{\"ta\": null}') q" +== 401 +-- truncate_limit: 100 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{\"ta\": 123}') q" +== 402 +-- truncate_limit: 100 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{\"ta\": [1, \"2\", null, 4]}') q" +== 403 +-- truncate_limit: 100 +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{\"ta\": [[1, 2, 3], {\"k\": \"v\"}]}') q" +== 404 +-- truncate_limit: 100 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{\"c\": null}') q" +== 405 +-- truncate_limit: 100 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{\"c\": \"aaa\"}') q" +== 406 +-- truncate_limit: 100 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaaaaaaaaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{\"c\": \"aaaaaaaaaa\"}') q" +== 407 +-- truncate_limit: 100 +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaaaaaaaaaaaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{\"c\": \"aaaaaaaaaaaaa\"}') q" +== 408 +-- truncate_limit: 100 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{\"ca\": null}') q" +== 409 +-- truncate_limit: 100 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{\"ca\": 123}') q" +== 410 +-- truncate_limit: 100 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{\"ca\": [1, \"2\", null, 4]}') q" +== 411 +-- truncate_limit: 100 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{\"ca\": [\"aaaaaaaaaaaaaaaa\"]}') q" +== 412 +-- truncate_limit: 100 +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{\"ca\": [[1, 2, 3], {\"k\": \"v\"}]}') q" +== 413 +-- truncate_limit: 100 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{\"js\": null}') q" +== 414 +-- truncate_limit: 100 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": true}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{\"js\": true}') q" +== 415 +-- truncate_limit: 100 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": 123.45}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{\"js\": 123.45}') q" +== 416 +-- truncate_limit: 100 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": "123.45"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{\"js\": \"123.45\"}') q" +== 417 +-- truncate_limit: 100 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": "abc"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{\"js\": \"abc\"}') q" +== 418 +-- truncate_limit: 100 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{\"js\": [123, \"123\", null, {\"key\": \"value\"}]}') q" +== 419 +-- truncate_limit: 100 +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{\"js\": {\"a\": \"bbb\", \"b\": null, \"c\": 123.45}}') q" +== 420 +-- truncate_limit: 100 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{\"jsb\": null}') q" +== 421 +-- truncate_limit: 100 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": true}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{\"jsb\": true}') q" +== 422 +-- truncate_limit: 100 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": 123.45}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{\"jsb\": 123.45}') q" +== 423 +-- truncate_limit: 100 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": "123.45"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{\"jsb\": \"123.45\"}') q" +== 424 +-- truncate_limit: 100 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": "abc"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{\"jsb\": \"abc\"}') q" +== 425 +-- truncate_limit: 100 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": [123, "123", null, {"key": "value"}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{\"jsb\": [123, \"123\", null, {\"key\": \"value\"}]..." +== 426 +-- truncate_limit: 100 +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": {"a": "bbb", "b": null, "c": 123.45}}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{\"jsb\": {\"a\": \"bbb\", \"b\": null, \"c\": 123.45}..." +== 427 +-- truncate_limit: 100 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{\"jsa\": null}') q" +== 428 +-- truncate_limit: 100 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{\"jsa\": 123}') q" +== 429 +-- truncate_limit: 100 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": [1, "2", null, 4]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{\"jsa\": [1, \"2\", null, 4]}') q" +== 430 +-- truncate_limit: 100 +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": ["aaa", null, [1, 2, "3", {}], { "k" : "v" }]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{\"jsa\": [\"aaa\", null, [1, 2, \"3\", {}], { \"k\"..." +== 431 +-- truncate_limit: 100 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{\"rec\": 123}') q" +== 432 +-- truncate_limit: 100 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": [1, 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{\"rec\": [1, 2]}') q" +== 433 +-- truncate_limit: 100 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{\"rec\": {\"a\": \"abc\", \"c\": \"01.02.2003\", \"x\":..." +== 434 +-- truncate_limit: 100 +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": "(abc,42,01.02.2003)"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{\"rec\": \"(abc,42,01.02.2003)\"}') q" +== 435 +-- truncate_limit: 100 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": 123}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{\"reca\": 123}') q" +== 436 +-- truncate_limit: 100 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": [1, 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{\"reca\": [1, 2]}') q" +== 437 +-- truncate_limit: 100 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM jsonb_populate_record(NULL::jsbrec, '{\"reca\": [{\"a\": \"abc\", \"b\": 456}, null, {\"c\"..." +== 438 +-- truncate_limit: 100 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": ["(abc,42,01.02.2003)"]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{\"reca\": [\"(abc,42,01.02.2003)\"]}') q" +== 439 +-- truncate_limit: 100 +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": "{\"(abc,42,01.02.2003)\"}"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reca FROM jsonb_populate_record(NULL::jsbrec, E'{\"reca\": \"{\\\\\"(abc,42,01.02.2003)\\\\\"}\"}') q" +== 440 +-- truncate_limit: 100 +SELECT rec FROM jsonb_populate_record( + row(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + row('x',3,'2012-12-31 15:30:56')::jbpop,NULL)::jsbrec, + '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}' +) q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rec FROM jsonb_populate_record(ROW(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, N..." +== 441 +-- truncate_limit: 100 +-- Tests to check soft-error support for populate_record_field() + +-- populate_scalar() +create type jsb_char2 as (a char(2)) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsb_char2 AS (a char(2))" +== 442 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aaa"}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_char2, '{\"a\": \"aaa\"}')" +== 443 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aaa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_char2, '{\"a\": \"aaa\"}') q" +== 444 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aa"}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_char2, '{\"a\": \"aa\"}')" +== 445 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aa"}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_char2, '{\"a\": \"aa\"}') q" +== 446 +-- truncate_limit: 100 +-- populate_array() +create type jsb_ia as (a int[]) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsb_ia AS (a int[])" +== 447 +-- truncate_limit: 100 +create type jsb_ia2 as (a int[][]) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsb_ia2 AS (a int[][])" +== 448 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_ia, '{"a": 43.2}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_ia, '{\"a\": 43.2}')" +== 449 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_ia, '{"a": 43.2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_ia, '{\"a\": 43.2}') q" +== 450 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_ia, '{"a": [1, 2]}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_ia, '{\"a\": [1, 2]}')" +== 451 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_ia, '{"a": [1, 2]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_ia, '{\"a\": [1, 2]}') q" +== 452 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_ia2, '{"a": [[1], [2, 3]]}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_ia2, '{\"a\": [[1], [2, 3]]}')" +== 453 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_ia2, '{"a": [[1], [2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_ia2, '{\"a\": [[1], [2, 3]]}') q" +== 454 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_ia2, '{"a": [[1, 0], [2, 3]]}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_ia2, '{\"a\": [[1, 0], [2, 3]]}')" +== 455 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_ia2, '{"a": [[1, 0], [2, 3]]}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_ia2, '{\"a\": [[1, 0], [2, 3]]}') q" +== 456 +-- truncate_limit: 100 +-- populate_domain() +create domain jsb_i_not_null as int not null +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN jsb_i_not_null AS int NOT NULL" +== 457 +-- truncate_limit: 100 +create domain jsb_i_gt_1 as int check (value > 1) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN jsb_i_gt_1 AS int CHECK (value > 1)" +== 458 +-- truncate_limit: 100 +create type jsb_i_not_null_rec as (a jsb_i_not_null) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsb_i_not_null_rec AS (a jsb_i_not_null)" +== 459 +-- truncate_limit: 100 +create type jsb_i_gt_1_rec as (a jsb_i_gt_1) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE jsb_i_gt_1_rec AS (a jsb_i_gt_1)" +== 460 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{"a": null}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{\"a\": null}')" +== 461 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_i_not_null_rec, '{"a": null}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_i_not_null_rec, '{\"a\": null}') q" +== 462 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{"a": 1}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{\"a\": 1}')" +== 463 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_i_not_null_rec, '{"a": 1}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_i_not_null_rec, '{\"a\": 1}') q" +== 464 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{"a": 1}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{\"a\": 1}')" +== 465 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{"a": 1}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{\"a\": 1}') q" +== 466 +-- truncate_limit: 100 +select jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{"a": 2}') +-- +FUNCTION: name="jsonb_populate_record_valid" function="jsonb_populate_record_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{\"a\": 2}')" +== 467 +-- truncate_limit: 100 +select * from jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{"a": 2}') q +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{\"a\": 2}') q" +== 468 +-- truncate_limit: 100 +drop type jsb_ia, jsb_ia2, jsb_char2, jsb_i_not_null_rec, jsb_i_gt_1_rec +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE jsb_ia, jsb_ia2, jsb_char2, jsb_i_not_null_rec, jsb_i_gt_1_rec" +== 469 +-- truncate_limit: 100 +drop domain jsb_i_not_null, jsb_i_gt_1 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN jsb_i_not_null, jsb_i_gt_1" +== 470 +-- truncate_limit: 100 +-- anonymous record type +SELECT jsonb_populate_record(null::record, '{"x": 0, "y": 1}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record(NULL::record, '{\"x\": 0, \"y\": 1}')" +== 471 +-- truncate_limit: 100 +SELECT jsonb_populate_record(row(1,2), '{"f1": 0, "f2": 1}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record(ROW(1, 2), '{\"f1\": 0, \"f2\": 1}')" +== 472 +-- truncate_limit: 100 +SELECT * FROM + jsonb_populate_record(null::record, '{"x": 776}') AS (x int, y int) +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_record(NULL::record, '{\"x\": 776}') AS (x int, y int)" +== 473 +-- truncate_limit: 100 +-- composite domain +SELECT jsonb_populate_record(null::jb_ordered_pair, '{"x": 0, "y": 1}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record(NULL::jb_ordered_pair, '{\"x\": 0, \"y\": 1}')" +== 474 +-- truncate_limit: 100 +SELECT jsonb_populate_record(row(1,2)::jb_ordered_pair, '{"x": 0}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record(ROW(1, 2)::jb_ordered_pair, '{\"x\": 0}')" +== 475 +-- truncate_limit: 100 +SELECT jsonb_populate_record(row(1,2)::jb_ordered_pair, '{"x": 1, "y": 0}') +-- +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_record(ROW(1, 2)::jb_ordered_pair, '{\"x\": 1, \"y\": 0}')" +== 476 +-- truncate_limit: 100 +-- populate_recordset +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(NULL::jbpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":3,\"c\":\"2012-01..." +== 477 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW('def', 99, NULL)::jbpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b..." +== 478 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(NULL::jbpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":3,\"c\":\"2012-01..." +== 479 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW('def', 99, NULL)::jbpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b..." +== 480 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW('def', 99, NULL)::jbpop, '[{\"a\":[100,200,300],\"x\":43.2..." +== 481 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW('def', 99, NULL)::jbpop, '[{\"c\":[100,200,300],\"x\":43.2..." +== 482 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(NULL::jbpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b\":3,\"c\":\"2012-01..." +== 483 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW('def', 99, NULL)::jbpop, '[{\"a\":\"blurfl\",\"x\":43.2},{\"b..." +== 484 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW('def', 99, NULL)::jbpop, '[{\"a\":[100,200,300],\"x\":43.2..." +== 485 +-- truncate_limit: 100 +-- anonymous record type +SELECT jsonb_populate_recordset(null::record, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_recordset(NULL::record, '[{\"x\": 0, \"y\": 1}]')" +== 486 +-- truncate_limit: 100 +SELECT jsonb_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_recordset(ROW(1, 2), '[{\"f1\": 0, \"f2\": 1}]')" +== 487 +-- truncate_limit: 100 +SELECT i, jsonb_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i, jsonb_populate_recordset(ROW(i, 50), '[{\"f1\":\"42\"},{\"f2\":\"43\"}]') FROM (VALUES (...)) v(i)" +== 488 +-- truncate_limit: 100 +SELECT * FROM + jsonb_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(NULL::record, '[{\"x\": 776}]') AS (x int, y int)" +== 489 +-- truncate_limit: 100 +-- empty array is a corner case +SELECT jsonb_populate_recordset(null::record, '[]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_recordset(NULL::record, '[]')" +== 490 +-- truncate_limit: 100 +SELECT jsonb_populate_recordset(row(1,2), '[]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_recordset(ROW(1, 2), '[]')" +== 491 +-- truncate_limit: 100 +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[]') q +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(NULL::jbpop, '[]') q" +== 492 +-- truncate_limit: 100 +SELECT * FROM + jsonb_populate_recordset(null::record, '[]') AS (x int, y int) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(NULL::record, '[]') AS (x int, y int)" +== 493 +-- truncate_limit: 100 +-- composite domain +SELECT jsonb_populate_recordset(null::jb_ordered_pair, '[{"x": 0, "y": 1}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_recordset(NULL::jb_ordered_pair, '[{\"x\": 0, \"y\": 1}]')" +== 494 +-- truncate_limit: 100 +SELECT jsonb_populate_recordset(row(1,2)::jb_ordered_pair, '[{"x": 0}, {"y": 3}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_recordset(ROW(1, 2)::jb_ordered_pair, '[{\"x\": 0}, {\"y\": 3}]')" +== 495 +-- truncate_limit: 100 +SELECT jsonb_populate_recordset(row(1,2)::jb_ordered_pair, '[{"x": 1, "y": 0}]') +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_populate_recordset(ROW(1, 2)::jb_ordered_pair, '[{\"x\": 1, \"y\": 0}]')" +== 496 +-- truncate_limit: 100 +-- negative cases where the wrong record type is supplied +select * from jsonb_populate_recordset(row(0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW(0::int), '[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\"}]') q (a text, b..." +== 497 +-- truncate_limit: 100 +select * from jsonb_populate_recordset(row(0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW(0::int, 0::int), '[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\"}]') q (a..." +== 498 +-- truncate_limit: 100 +select * from jsonb_populate_recordset(row(0::int,0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW(0::int, 0::int, 0::int), '[{\"a\":\"1\",\"b\":\"2\"},{\"a\":\"3\"}..." +== 499 +-- truncate_limit: 100 +select * from jsonb_populate_recordset(row(1000000000::int,50::int),'[{"b":"2"},{"a":"3"}]') q (a text, b text) +-- +FUNCTION: name="jsonb_populate_recordset" function="jsonb_populate_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_populate_recordset(ROW(1000000000::int, 50::int), '[{\"b\":\"2\"},{\"a\":\"3\"}]') q ..." +== 500 +-- truncate_limit: 100 +-- jsonb_to_record and jsonb_to_recordset + +select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}') + as x(a int, b text, d text) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"a\":1,\"b\":\"foo\",\"c\":\"bar\"}') x (a int, b text, d text)" +== 501 +-- truncate_limit: 100 +select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') + as x(a int, b text, c boolean) +-- +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_recordset('[{\"a\":1,\"b\":\"foo\",\"d\":false},{\"a\":2,\"b\":\"bar\",\"c\":true}]') x (a..." +== 502 +-- truncate_limit: 100 +select *, c is null as c_is_null +from jsonb_to_record('{"a":1, "b":{"c":16, "d":2}, "x":8, "ca": ["1 2", 3], "ia": [[1,2],[3,4]], "r": {"a": "aaa", "b": 123}}'::jsonb) + as t(a int, b jsonb, c text, x int, ca char(5)[], ia int[][], r jbpop) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM jsonb_to_record('{\"a\":1, \"b\":{\"c\":16, \"d\":2}, \"x\":8, \"ca\": [\"1 2\", 3], \"ia\": [[1,..." +== 503 +-- truncate_limit: 100 +select *, c is null as c_is_null +from jsonb_to_recordset('[{"a":1, "b":{"c":16, "d":2}, "x":8}]'::jsonb) + as t(a int, b jsonb, c text, x int) +-- +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM jsonb_to_recordset('[{\"a\":1, \"b\":{\"c\":16, \"d\":2}, \"x\":8}]'::jsonb) t (a int, b js..." +== 504 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia": null}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia\": null}') x (ia _int4)" +== 505 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia": 123}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia\": 123}') x (ia _int4)" +== 506 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia\": [1, \"2\", null, 4]}') x (ia _int4)" +== 507 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia\": [[1, 2], [3, 4]]}') x (ia _int4)" +== 508 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia": [[1], 2]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia\": [[1], 2]}') x (ia _int4)" +== 509 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia\": [[1], [2, 3]]}') x (ia _int4)" +== 510 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia2\": [1, 2, 3]}') x (ia2 int[][])" +== 511 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia2\": [[1, 2], [3, 4]]}') x (ia2 int4[][])" +== 512 +-- truncate_limit: 100 +select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"ia2\": [[[1], [2], [3]]]}') x (ia2 int4[][])" +== 513 +-- truncate_limit: 100 +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out json) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"out\": {\"key\": 1}}') x (\"out\" pg_catalog.json)" +== 514 +-- truncate_limit: 100 +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out json) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"out\": [{\"key\": 1}]}') x (\"out\" pg_catalog.json)" +== 515 +-- truncate_limit: 100 +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out json) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record(E'{\"out\": \"{\\\\\"key\\\\\": 1}\"}') x (\"out\" pg_catalog.json)" +== 516 +-- truncate_limit: 100 +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out jsonb) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"out\": {\"key\": 1}}') x (\"out\" jsonb)" +== 517 +-- truncate_limit: 100 +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out jsonb) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record('{\"out\": [{\"key\": 1}]}') x (\"out\" jsonb)" +== 518 +-- truncate_limit: 100 +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb) +-- +FUNCTION: name="jsonb_to_record" function="jsonb_to_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_to_record(E'{\"out\": \"{\\\\\"key\\\\\": 1}\"}') x (\"out\" jsonb)" +== 519 +-- truncate_limit: 100 +-- test type info caching in jsonb_populate_record() +CREATE TEMP TABLE jsbpoptest (js jsonb) +-- +TABLE: name="jsbpoptest" schema="" table="jsbpoptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE jsbpoptest (js jsonb)" +== 520 +-- truncate_limit: 100 +INSERT INTO jsbpoptest +SELECT '{ + "jsa": [1, "2", null, 4], + "rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}, + "reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}] +}'::jsonb +FROM generate_series(1, 3) +-- +TABLE: name="jsbpoptest" schema="" table="jsbpoptest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO jsbpoptest SELECT ... FROM generate_series(1, 3)" +== 521 +-- truncate_limit: 100 +SELECT (jsonb_populate_record(NULL::jsbrec, js)).* FROM jsbpoptest +-- +TABLE: name="jsbpoptest" schema="" table="jsbpoptest" ctx=Select +FUNCTION: name="jsonb_populate_record" function="jsonb_populate_record" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (jsonb_populate_record(NULL::jsbrec, js)).* FROM jsbpoptest" +== 522 +-- truncate_limit: 100 +DROP TYPE jsbrec +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE jsbrec" +== 523 +-- truncate_limit: 100 +DROP TYPE jsbrec_i_not_null +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE jsbrec_i_not_null" +== 524 +-- truncate_limit: 100 +DROP DOMAIN jsb_int_not_null +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN jsb_int_not_null" +== 525 +-- truncate_limit: 100 +DROP DOMAIN jsb_int_array_1d +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN jsb_int_array_1d" +== 526 +-- truncate_limit: 100 +DROP DOMAIN jsb_int_array_2d +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN jsb_int_array_2d" +== 527 +-- truncate_limit: 100 +DROP DOMAIN jb_ordered_pair +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN jb_ordered_pair" +== 528 +-- truncate_limit: 100 +DROP TYPE jb_unordered_pair +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE jb_unordered_pair" +== 529 +-- truncate_limit: 100 +-- indexing +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":null}'" +== 530 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":\"CC\"}'" +== 531 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":\"CC\", \"public\":true}'" +== 532 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"age\":25}'" +== 533 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"age\":25.0}'" +== 534 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ? 'public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ? 'public'" +== 535 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ? 'bar'" +== 536 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public', 'disabled']" +== 537 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public', 'disabled']" +== 538 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'" +== 539 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '\"CC\" == $.wait'" +== 540 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == \"CC\" && true == $.public'" +== 541 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'" +== 542 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'" +== 543 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'" +== 544 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'" +== 545 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'" +== 546 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'" +== 547 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'" +== 548 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'" +== 549 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (\"CC\" == @)'" +== 550 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == \"CC\" && true == @.public)'" +== 551 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'" +== 552 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'" +== 553 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$'" +== 554 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.public'" +== 555 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.bar'" +== 556 +-- truncate_limit: 100 +CREATE INDEX jidx ON testjsonb USING gin (j) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX jidx ON testjsonb USING gin (j)" +== 557 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 558 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":null}'" +== 559 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":\"CC\"}'" +== 560 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":\"CC\", \"public\":true}'" +== 561 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"age\":25}'" +== 562 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"age\":25.0}'" +== 563 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"array":["foo"]}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"array\":[\"foo\"]}'" +== 564 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"array":["bar"]}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"array\":[\"bar\"]}'" +== 565 +-- truncate_limit: 100 +-- exercise GIN_SEARCH_MODE_ALL +SELECT count(*) FROM testjsonb WHERE j @> '{}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{}'" +== 566 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ? 'public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ? 'public'" +== 567 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ? 'bar'" +== 568 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public', 'disabled']" +== 569 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled'] +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public', 'disabled']" +== 570 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'" +== 571 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'" +== 572 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'" +== 573 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'" +== 574 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '\"CC\" == $.wait'" +== 575 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == \"CC\" && true == $.public'" +== 576 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'" +== 577 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'" +== 578 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == \"foo\"'" +== 579 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == \"bar\"'" +== 580 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == \"bar\"))'" +== 581 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == \"bar\"))'" +== 582 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == \"bar\"))'" +== 583 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'" +== 584 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'" +== 585 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'" +== 586 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'" +== 587 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'" +== 588 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'" +== 589 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'" +== 590 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (\"CC\" == @)'" +== 591 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == \"CC\" && true == @.public)'" +== 592 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'" +== 593 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'" +== 594 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == \"bar\")'" +== 595 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == \"bar\")'" +== 596 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == \"bar\")'" +== 597 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$'" +== 598 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.public'" +== 599 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.bar'" +== 600 +-- truncate_limit: 100 +-- array exists - array elements should behave as keys (for GIN index scans too) +CREATE INDEX jidx_array ON testjsonb USING gin((j->'array')) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX jidx_array ON testjsonb USING gin ((j -> 'array'))" +== 601 +-- truncate_limit: 100 +SELECT count(*) from testjsonb WHERE j->'array' ? 'bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE (j -> 'array') ? 'bar'" +== 602 +-- truncate_limit: 100 +-- type sensitive array exists - should return no rows (since "exists" only +-- matches strings that are either object keys or array elements) +SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE (j -> 'array') ? '5'::text" +== 603 +-- truncate_limit: 100 +-- However, a raw scalar is *contained* within the array +SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE (j -> 'array') @> '5'::jsonb" +== 604 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 605 +-- truncate_limit: 100 +SELECT count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) wow" +== 606 +-- truncate_limit: 100 +SELECT key, count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow GROUP BY key ORDER BY count DESC, key +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="jsonb_each" function="jsonb_each" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT key, count(*) FROM (SELECT ... FROM testjsonb) wow GROUP BY key ORDER BY count DESC, key" +== 607 +-- truncate_limit: 100 +-- sort/hash +SELECT count(distinct j) FROM testjsonb +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT j) FROM testjsonb" +== 608 +-- truncate_limit: 100 +SET enable_hashagg = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 609 +-- truncate_limit: 100 +SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2 +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GRO..." +== 610 +-- truncate_limit: 100 +SET enable_hashagg = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO ON" +== 611 +-- truncate_limit: 100 +SET enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 612 +-- truncate_limit: 100 +SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2 +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GRO..." +== 613 +-- truncate_limit: 100 +SELECT distinct * FROM (values (jsonb '{}' || ''::text),('{}')) v(j) +-- +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT * FROM (VALUES ('{}'::jsonb || ''::text), ('{}')) v(j)" +== 614 +-- truncate_limit: 100 +SET enable_sort = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO ON" +== 615 +-- truncate_limit: 100 +RESET enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 616 +-- truncate_limit: 100 +RESET enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 617 +-- truncate_limit: 100 +DROP INDEX jidx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX jidx" +== 618 +-- truncate_limit: 100 +DROP INDEX jidx_array +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX jidx_array" +== 619 +-- truncate_limit: 100 +-- btree +CREATE INDEX jidx ON testjsonb USING btree (j) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX jidx ON testjsonb USING btree (j)" +== 620 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 621 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j > '{"p":1}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j > '{\"p\":1}'" +== 622 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j = '{"pos":98, "line":371, "node":"CBA", "indexed":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j = '{\"pos\":98, \"line\":371, \"node\":\"CBA\", \"indexed\":true}'" +== 623 +-- truncate_limit: 100 +--gin path opclass +DROP INDEX jidx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX jidx" +== 624 +-- truncate_limit: 100 +CREATE INDEX jidx ON testjsonb USING gin (j jsonb_path_ops) +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX jidx ON testjsonb USING gin (j jsonb_path_ops)" +== 625 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 626 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":null}'" +== 627 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":\"CC\"}'" +== 628 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"wait\":\"CC\", \"public\":true}'" +== 629 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"age\":25}'" +== 630 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{\"age\":25.0}'" +== 631 +-- truncate_limit: 100 +-- exercise GIN_SEARCH_MODE_ALL +SELECT count(*) FROM testjsonb WHERE j @> '{}' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @> '{}'" +== 632 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'" +== 633 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'" +== 634 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'" +== 635 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '\"CC\" == $.wait'" +== 636 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == \"CC\" && true == $.public'" +== 637 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'" +== 638 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'" +== 639 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == \"foo\"'" +== 640 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == \"bar\"'" +== 641 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == \"bar\"))'" +== 642 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == \"bar\"))'" +== 643 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == \"bar\"))'" +== 644 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'" +== 645 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'" +== 646 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'" +== 647 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (\"CC\" == @)'" +== 648 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == \"CC\" && true == @.public)'" +== 649 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'" +== 650 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'" +== 651 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == \"bar\")'" +== 652 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == \"bar\")'" +== 653 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == \"bar\")'" +== 654 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$'" +== 655 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.public' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.public'" +== 656 +-- truncate_limit: 100 +SELECT count(*) FROM testjsonb WHERE j @? '$.bar' +-- +TABLE: name="testjsonb" schema="" table="testjsonb" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testjsonb WHERE j @? '$.bar'" +== 657 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 658 +-- truncate_limit: 100 +DROP INDEX jidx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX jidx" +== 659 +-- truncate_limit: 100 +-- nested tests +SELECT '{"ff":{"a":12,"b":16}}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"ff\":{\"a\":12,\"b\":16}}'::jsonb" +== 660 +-- truncate_limit: 100 +SELECT '{"ff":{"a":12,"b":16},"qq":123}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"ff\":{\"a\":12,\"b\":16},\"qq\":123}'::jsonb" +== 661 +-- truncate_limit: 100 +SELECT '{"aa":["a","aaa"],"qq":{"a":12,"b":16,"c":["c1","c2"],"d":{"d1":"d1","d2":"d2","d1":"d3"}}}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 662 +-- truncate_limit: 100 +SELECT '{"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2"],"d":{"d1":"d1","d2":"d2"}}}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 663 +-- truncate_limit: 100 +SELECT '{"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2",["c3"],{"c4":4}],"d":{"d1":"d1","d2":"d2"}}}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 664 +-- truncate_limit: 100 +SELECT '{"ff":["a","aaa"]}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"ff\":[\"a\",\"aaa\"]}'::jsonb" +== 665 +-- truncate_limit: 100 +SELECT + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'ff', + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'qq', + ('{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'Y') IS NULL AS f, + ('{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb ->> 'Y') IS NULL AS t, + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'x' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 666 +-- truncate_limit: 100 +-- nested containment +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2],\"c\":\"b\"}'::jsonb @> '{\"a\":[1,2]}'" +== 667 +-- truncate_limit: 100 +SELECT '{"a":[2,1],"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[2,1],\"c\":\"b\"}'::jsonb @> '{\"a\":[1,2]}'" +== 668 +-- truncate_limit: 100 +SELECT '{"a":{"1":2},"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":{\"1\":2},\"c\":\"b\"}'::jsonb @> '{\"a\":[1,2]}'" +== 669 +-- truncate_limit: 100 +SELECT '{"a":{"2":1},"c":"b"}'::jsonb @> '{"a":[1,2]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":{\"2\":1},\"c\":\"b\"}'::jsonb @> '{\"a\":[1,2]}'" +== 670 +-- truncate_limit: 100 +SELECT '{"a":{"1":2},"c":"b"}'::jsonb @> '{"a":{"1":2}}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":{\"1\":2},\"c\":\"b\"}'::jsonb @> '{\"a\":{\"1\":2}}'" +== 671 +-- truncate_limit: 100 +SELECT '{"a":{"2":1},"c":"b"}'::jsonb @> '{"a":{"1":2}}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":{\"2\":1},\"c\":\"b\"}'::jsonb @> '{\"a\":{\"1\":2}}'" +== 672 +-- truncate_limit: 100 +SELECT '["a","b"]'::jsonb @> '["a","b","c","b"]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\"]'::jsonb @> '[\"a\",\"b\",\"c\",\"b\"]'" +== 673 +-- truncate_limit: 100 +SELECT '["a","b","c","b"]'::jsonb @> '["a","b"]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",\"b\"]'::jsonb @> '[\"a\",\"b\"]'" +== 674 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2]]'::jsonb @> '["a",[1,2]]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2]]'::jsonb @> '[\"a\",[1,2]]'" +== 675 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2]]'::jsonb @> '["b",[1,2]]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2]]'::jsonb @> '[\"b\",[1,2]]'" +== 676 +-- truncate_limit: 100 +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[1]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2],\"c\":\"b\"}'::jsonb @> '{\"a\":[1]}'" +== 677 +-- truncate_limit: 100 +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[2]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2],\"c\":\"b\"}'::jsonb @> '{\"a\":[2]}'" +== 678 +-- truncate_limit: 100 +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[3]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2],\"c\":\"b\"}'::jsonb @> '{\"a\":[3]}'" +== 679 +-- truncate_limit: 100 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"c":3}]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2,{\"c\":3,\"x\":4}],\"c\":\"b\"}'::jsonb @> '{\"a\":[{\"c\":3}]}'" +== 680 +-- truncate_limit: 100 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4}]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2,{\"c\":3,\"x\":4}],\"c\":\"b\"}'::jsonb @> '{\"a\":[{\"x\":4}]}'" +== 681 +-- truncate_limit: 100 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},3]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2,{\"c\":3,\"x\":4}],\"c\":\"b\"}'::jsonb @> '{\"a\":[{\"x\":4},3]}'" +== 682 +-- truncate_limit: 100 +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},1]}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":[1,2,{\"c\":3,\"x\":4}],\"c\":\"b\"}'::jsonb @> '{\"a\":[{\"x\":4},1]}'" +== 683 +-- truncate_limit: 100 +-- check some corner cases for indexed nested containment (bug #13756) +create temp table nestjsonb (j jsonb) +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE nestjsonb (j jsonb)" +== 684 +-- truncate_limit: 100 +insert into nestjsonb (j) values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}') +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nestjsonb (j) VALUES ('{\"a\":[[\"b\",{\"x\":1}],[\"b\",{\"x\":2}]],\"c\":3}')" +== 685 +-- truncate_limit: 100 +insert into nestjsonb (j) values ('[[14,2,3]]') +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nestjsonb (j) VALUES ('[[14,2,3]]')" +== 686 +-- truncate_limit: 100 +insert into nestjsonb (j) values ('[1,[14,2,3]]') +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nestjsonb (j) VALUES ('[1,[14,2,3]]')" +== 687 +-- truncate_limit: 100 +create index on nestjsonb using gin(j jsonb_path_ops) +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON nestjsonb USING gin (j jsonb_path_ops)" +== 688 +-- truncate_limit: 100 +set enable_seqscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 689 +-- truncate_limit: 100 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 690 +-- truncate_limit: 100 +select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nestjsonb WHERE j @> '{\"a\":[[{\"x\":2}]]}'::jsonb" +== 691 +-- truncate_limit: 100 +select * from nestjsonb where j @> '{"c":3}' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nestjsonb WHERE j @> '{\"c\":3}'" +== 692 +-- truncate_limit: 100 +select * from nestjsonb where j @> '[[14]]' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nestjsonb WHERE j @> '[[14]]'" +== 693 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 694 +-- truncate_limit: 100 +set enable_bitmapscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 695 +-- truncate_limit: 100 +select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nestjsonb WHERE j @> '{\"a\":[[{\"x\":2}]]}'::jsonb" +== 696 +-- truncate_limit: 100 +select * from nestjsonb where j @> '{"c":3}' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nestjsonb WHERE j @> '{\"c\":3}'" +== 697 +-- truncate_limit: 100 +select * from nestjsonb where j @> '[[14]]' +-- +TABLE: name="nestjsonb" schema="" table="nestjsonb" ctx=Select +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nestjsonb WHERE j @> '[[14]]'" +== 698 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 699 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 700 +-- truncate_limit: 100 +-- nested object field / array index lookup +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'n' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 'n'" +== 701 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 'a'" +== 702 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 'b'" +== 703 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'c' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 'c'" +== 704 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'd' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 'd'" +== 705 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'd' -> '1' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 'd') -> '1'" +== 706 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'e' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 'e'" +== 707 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb -> 0" +== 708 +-- truncate_limit: 100 +--expecting error + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> 0" +== 709 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> 1" +== 710 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> 2" +== 711 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> 3" +== 712 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 3 -> 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> 3) -> 1" +== 713 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> 4" +== 714 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> 5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> 5" +== 715 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> -1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> -1" +== 716 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> -5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> -5" +== 717 +-- truncate_limit: 100 +SELECT '["a","b","c",[1,2],null]'::jsonb -> -6 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\",[1,2],null]'::jsonb -> -6" +== 718 +-- truncate_limit: 100 +--nested path extraction +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{0}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{0}'" +== 719 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{a}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{a}'" +== 720 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c}'" +== 721 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,0}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c,0}'" +== 722 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,1}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c,1}'" +== 723 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,2}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c,2}'" +== 724 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,3}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c,3}'" +== 725 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-1}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c,-1}'" +== 726 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-3}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c,-3}'" +== 727 +-- truncate_limit: 100 +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-4}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\",\"c\":[1,2,3]}'::jsonb #> '{c,-4}'" +== 728 +-- truncate_limit: 100 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{0}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[0,1,2,[3,4],{\"5\":\"five\"}]'::jsonb #> '{0}'" +== 729 +-- truncate_limit: 100 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{3}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[0,1,2,[3,4],{\"5\":\"five\"}]'::jsonb #> '{3}'" +== 730 +-- truncate_limit: 100 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{4}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[0,1,2,[3,4],{\"5\":\"five\"}]'::jsonb #> '{4}'" +== 731 +-- truncate_limit: 100 +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{4,5}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[0,1,2,[3,4],{\"5\":\"five\"}]'::jsonb #> '{4,5}'" +== 732 +-- truncate_limit: 100 +--nested exists +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'n' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb ? 'n'" +== 733 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb ? 'a'" +== 734 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb ? 'b'" +== 735 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'c' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb ? 'c'" +== 736 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'd' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb ? 'd'" +== 737 +-- truncate_limit: 100 +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'e' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null,\"a\":1,\"b\":[1,2],\"c\":{\"1\":2},\"d\":{\"1\":[2,3]}}'::jsonb ? 'e'" +== 738 +-- truncate_limit: 100 +-- jsonb_strip_nulls + +select jsonb_strip_nulls(null) +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls(NULL)" +== 739 +-- truncate_limit: 100 +select jsonb_strip_nulls('1') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls('1')" +== 740 +-- truncate_limit: 100 +select jsonb_strip_nulls('"a string"') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls('\"a string\"')" +== 741 +-- truncate_limit: 100 +select jsonb_strip_nulls('null') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls('null')" +== 742 +-- truncate_limit: 100 +select jsonb_strip_nulls('[1,2,null,3,4]') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls('[1,2,null,3,4]')" +== 743 +-- truncate_limit: 100 +select jsonb_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls('{\"a\":1,\"b\":null,\"c\":[2,null,3],\"d\":{\"e\":4,\"f\":null}}')" +== 744 +-- truncate_limit: 100 +select jsonb_strip_nulls('[1,{"a":1,"b":null,"c":2},3]') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls('[1,{\"a\":1,\"b\":null,\"c\":2},3]')" +== 745 +-- truncate_limit: 100 +-- an empty object is not null and should not be stripped +select jsonb_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }') +-- +FUNCTION: name="jsonb_strip_nulls" function="jsonb_strip_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_strip_nulls('{\"a\": {\"b\": null, \"c\": null}, \"d\": {} }')" +== 746 +-- truncate_limit: 100 +select jsonb_pretty('{"a": "test", "b": [1, 2, 3], "c": "test3", "d":{"dd": "test4", "dd2":{"ddd": "test5"}}}') +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 747 +-- truncate_limit: 100 +select jsonb_pretty('[{"f1":1,"f2":null},2,null,[[{"x":true},6,7],8],3]') +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_pretty('[{\"f1\":1,\"f2\":null},2,null,[[{\"x\":true},6,7],8],3]')" +== 748 +-- truncate_limit: 100 +select jsonb_pretty('{"a":["b", "c"], "d": {"e":"f"}}') +-- +FUNCTION: name="jsonb_pretty" function="jsonb_pretty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_pretty('{\"a\":[\"b\", \"c\"], \"d\": {\"e\":\"f\"}}')" +== 749 +-- truncate_limit: 100 +select jsonb_concat('{"d": "test", "a": [1, 2]}', '{"g": "test2", "c": {"c1":1, "c2":2}}') +-- +FUNCTION: name="jsonb_concat" function="jsonb_concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_concat('{\"d\": \"test\", \"a\": [1, 2]}', '{\"g\": \"test2\", \"c\": {\"c1\":1, \"c2\":2}}')" +== 750 +-- truncate_limit: 100 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"cq":"l", "b":"g", "fg":false}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"aa\":1 , \"b\":2, \"cq\":3}'::jsonb || '{\"cq\":\"l\", \"b\":\"g\", \"fg\":false}'" +== 751 +-- truncate_limit: 100 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"aq":"l"}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"aa\":1 , \"b\":2, \"cq\":3}'::jsonb || '{\"aq\":\"l\"}'" +== 752 +-- truncate_limit: 100 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"aa":"l"}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"aa\":1 , \"b\":2, \"cq\":3}'::jsonb || '{\"aa\":\"l\"}'" +== 753 +-- truncate_limit: 100 +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"aa\":1 , \"b\":2, \"cq\":3}'::jsonb || '{}'" +== 754 +-- truncate_limit: 100 +select '["a", "b"]'::jsonb || '["c"]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\", \"b\"]'::jsonb || '[\"c\"]'" +== 755 +-- truncate_limit: 100 +select '["a", "b"]'::jsonb || '["c", "d"]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\", \"b\"]'::jsonb || '[\"c\", \"d\"]'" +== 756 +-- truncate_limit: 100 +select '["c"]' || '["a", "b"]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"c\"]' || '[\"a\", \"b\"]'::jsonb" +== 757 +-- truncate_limit: 100 +select '["a", "b"]'::jsonb || '"c"' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\", \"b\"]'::jsonb || '\"c\"'" +== 758 +-- truncate_limit: 100 +select '"c"' || '["a", "b"]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"c\"' || '[\"a\", \"b\"]'::jsonb" +== 759 +-- truncate_limit: 100 +select '[]'::jsonb || '["a"]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb || '[\"a\"]'::jsonb" +== 760 +-- truncate_limit: 100 +select '[]'::jsonb || '"a"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb || '\"a\"'::jsonb" +== 761 +-- truncate_limit: 100 +select '"b"'::jsonb || '"a"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"b\"'::jsonb || '\"a\"'::jsonb" +== 762 +-- truncate_limit: 100 +select '{}'::jsonb || '{"a":"b"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb || '{\"a\":\"b\"}'::jsonb" +== 763 +-- truncate_limit: 100 +select '[]'::jsonb || '{"a":"b"}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb || '{\"a\":\"b\"}'::jsonb" +== 764 +-- truncate_limit: 100 +select '{"a":"b"}'::jsonb || '[]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":\"b\"}'::jsonb || '[]'::jsonb" +== 765 +-- truncate_limit: 100 +select '"a"'::jsonb || '{"a":1}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"a\"'::jsonb || '{\"a\":1}'" +== 766 +-- truncate_limit: 100 +select '{"a":1}' || '"a"'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1}' || '\"a\"'::jsonb" +== 767 +-- truncate_limit: 100 +select '[3]'::jsonb || '{}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[3]'::jsonb || '{}'::jsonb" +== 768 +-- truncate_limit: 100 +select '3'::jsonb || '[]'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3'::jsonb || '[]'::jsonb" +== 769 +-- truncate_limit: 100 +select '3'::jsonb || '4'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3'::jsonb || '4'::jsonb" +== 770 +-- truncate_limit: 100 +select '3'::jsonb || '{}'::jsonb +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3'::jsonb || '{}'::jsonb" +== 771 +-- truncate_limit: 100 +select '["a", "b"]'::jsonb || '{"c":1}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\", \"b\"]'::jsonb || '{\"c\":1}'" +== 772 +-- truncate_limit: 100 +select '{"c": 1}'::jsonb || '["a", "b"]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": 1}'::jsonb || '[\"a\", \"b\"]'" +== 773 +-- truncate_limit: 100 +select '{}'::jsonb || '{"cq":"l", "b":"g", "fg":false}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb || '{\"cq\":\"l\", \"b\":\"g\", \"fg\":false}'" +== 774 +-- truncate_limit: 100 +select pg_column_size('{}'::jsonb || '{}'::jsonb) = pg_column_size('{}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_column_size('{}'::jsonb || '{}'::jsonb) = pg_column_size('{}'::jsonb)" +== 775 +-- truncate_limit: 100 +select pg_column_size('{"aa":1}'::jsonb || '{"b":2}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 776 +-- truncate_limit: 100 +select pg_column_size('{"aa":1, "b":2}'::jsonb || '{}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 777 +-- truncate_limit: 100 +select pg_column_size('{}'::jsonb || '{"aa":1, "b":2}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 778 +-- truncate_limit: 100 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'a') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete('{\"a\":1 , \"b\":2, \"c\":3}'::jsonb, 'a')" +== 779 +-- truncate_limit: 100 +select jsonb_delete('{"a":null , "b":2, "c":3}'::jsonb, 'a') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete('{\"a\":null , \"b\":2, \"c\":3}'::jsonb, 'a')" +== 780 +-- truncate_limit: 100 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'b') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete('{\"a\":1 , \"b\":2, \"c\":3}'::jsonb, 'b')" +== 781 +-- truncate_limit: 100 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'c') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete('{\"a\":1 , \"b\":2, \"c\":3}'::jsonb, 'c')" +== 782 +-- truncate_limit: 100 +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'd') +-- +FUNCTION: name="jsonb_delete" function="jsonb_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete('{\"a\":1 , \"b\":2, \"c\":3}'::jsonb, 'd')" +== 783 +-- truncate_limit: 100 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1 , \"b\":2, \"c\":3}'::jsonb - 'a'" +== 784 +-- truncate_limit: 100 +select '{"a":null , "b":2, "c":3}'::jsonb - 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":null , \"b\":2, \"c\":3}'::jsonb - 'a'" +== 785 +-- truncate_limit: 100 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1 , \"b\":2, \"c\":3}'::jsonb - 'b'" +== 786 +-- truncate_limit: 100 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'c' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1 , \"b\":2, \"c\":3}'::jsonb - 'c'" +== 787 +-- truncate_limit: 100 +select '{"a":1 , "b":2, "c":3}'::jsonb - 'd' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1 , \"b\":2, \"c\":3}'::jsonb - 'd'" +== 788 +-- truncate_limit: 100 +select pg_column_size('{"a":1 , "b":2, "c":3}'::jsonb - 'b') = pg_column_size('{"a":1, "b":2}'::jsonb) +-- +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +FUNCTION: name="pg_column_size" function="pg_column_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 789 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - 3" +== 790 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - 2" +== 791 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - 1" +== 792 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - 0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - 0" +== 793 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - -1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - -1" +== 794 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - -2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - -2" +== 795 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - -3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - -3" +== 796 +-- truncate_limit: 100 +select '["a","b","c"]'::jsonb - -4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"a\",\"b\",\"c\"]'::jsonb - -4" +== 797 +-- truncate_limit: 100 +select '{"a":1 , "b":2, "c":3}'::jsonb - '{b}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1 , \"b\":2, \"c\":3}'::jsonb - '{b}'::text[]" +== 798 +-- truncate_limit: 100 +select '{"a":1 , "b":2, "c":3}'::jsonb - '{c,b}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1 , \"b\":2, \"c\":3}'::jsonb - '{c,b}'::text[]" +== 799 +-- truncate_limit: 100 +select '{"a":1 , "b":2, "c":3}'::jsonb - '{}'::text[] +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\":1 , \"b\":2, \"c\":3}'::jsonb - '{}'::text[]" +== 800 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 801 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 802 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,1,0}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 803 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '[1,2,3]') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 804 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 805 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 806 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,1,0}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 807 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '{"1": 2}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 808 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '"test"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 809 +-- truncate_limit: 100 +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '{"f": "test"}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 810 +-- truncate_limit: 100 +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{n}') +-- +FUNCTION: name="jsonb_delete_path" function="jsonb_delete_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete_path('{\"n\":null, \"a\":1, \"b\":[1,2], \"c\":{\"1\":2}, \"d\":{\"1\":[2,3]}}', '{n}')" +== 811 +-- truncate_limit: 100 +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{b,-1}') +-- +FUNCTION: name="jsonb_delete_path" function="jsonb_delete_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete_path('{\"n\":null, \"a\":1, \"b\":[1,2], \"c\":{\"1\":2}, \"d\":{\"1\":[2,3]}}', '{b,-1}')" +== 812 +-- truncate_limit: 100 +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{d,1,0}') +-- +FUNCTION: name="jsonb_delete_path" function="jsonb_delete_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_delete_path('{\"n\":null, \"a\":1, \"b\":[1,2], \"c\":{\"1\":2}, \"d\":{\"1\":[2,3]}}', '{d,1,0}')" +== 813 +-- truncate_limit: 100 +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{n}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null, \"a\":1, \"b\":[1,2], \"c\":{\"1\":2}, \"d\":{\"1\":[2,3]}}'::jsonb #- '{n}'" +== 814 +-- truncate_limit: 100 +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null, \"a\":1, \"b\":[1,2], \"c\":{\"1\":2}, \"d\":{\"1\":[2,3]}}'::jsonb #- '{b,-1}'" +== 815 +-- truncate_limit: 100 +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1e}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null, \"a\":1, \"b\":[1,2], \"c\":{\"1\":2}, \"d\":{\"1\":[2,3]}}'::jsonb #- '{b,-1e}'" +== 816 +-- truncate_limit: 100 +-- invalid array subscript +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{d,1,0}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"n\":null, \"a\":1, \"b\":[1,2], \"c\":{\"1\":2}, \"d\":{\"1\":[2,3]}}'::jsonb #- '{d,1,0}'" +== 817 +-- truncate_limit: 100 +-- empty structure and error conditions for delete and replace + +select '"a"'::jsonb - 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"a\"'::jsonb - 'a'" +== 818 +-- truncate_limit: 100 +-- error +select '{}'::jsonb - 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb - 'a'" +== 819 +-- truncate_limit: 100 +select '[]'::jsonb - 'a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb - 'a'" +== 820 +-- truncate_limit: 100 +select '"a"'::jsonb - 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"a\"'::jsonb - 1" +== 821 +-- truncate_limit: 100 +-- error +select '{}'::jsonb - 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb - 1" +== 822 +-- truncate_limit: 100 +-- error +select '[]'::jsonb - 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb - 1" +== 823 +-- truncate_limit: 100 +select '"a"'::jsonb #- '{a}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"a\"'::jsonb #- '{a}'" +== 824 +-- truncate_limit: 100 +-- error +select '{}'::jsonb #- '{a}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb #- '{a}'" +== 825 +-- truncate_limit: 100 +select '[]'::jsonb #- '{a}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb #- '{a}'" +== 826 +-- truncate_limit: 100 +select jsonb_set('"a"','{a}','"b"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('\"a\"', '{a}', '\"b\"')" +== 827 +-- truncate_limit: 100 +--error +select jsonb_set('{}','{a}','"b"', false) +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{}', '{a}', '\"b\"', false)" +== 828 +-- truncate_limit: 100 +select jsonb_set('[]','{1}','"b"', false) +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('[]', '{1}', '\"b\"', false)" +== 829 +-- truncate_limit: 100 +select jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0}','[2,3,4]', false) +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('[{\"f1\":1,\"f2\":null},2,null,3]', '{0}', '[2,3,4]', false)" +== 830 +-- truncate_limit: 100 +-- jsonb_set adding instead of replacing + +-- prepend to array +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{b,-33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\":1,\"b\":[0,1,2],\"c\":{\"d\":4}}', '{b,-33}', '{\"foo\":123}')" +== 831 +-- truncate_limit: 100 +-- append to array +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{b,33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\":1,\"b\":[0,1,2],\"c\":{\"d\":4}}', '{b,33}', '{\"foo\":123}')" +== 832 +-- truncate_limit: 100 +-- check nesting levels addition +select jsonb_set('{"a":1,"b":[4,5,[0,1,2],6,7],"c":{"d":4}}','{b,2,33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\":1,\"b\":[4,5,[0,1,2],6,7],\"c\":{\"d\":4}}', '{b,2,33}', '{\"foo\":123}')" +== 833 +-- truncate_limit: 100 +-- add new key +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{c,e}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\":1,\"b\":[0,1,2],\"c\":{\"d\":4}}', '{c,e}', '{\"foo\":123}')" +== 834 +-- truncate_limit: 100 +-- adding doesn't do anything if elements before last aren't present +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{x,-33}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\":1,\"b\":[0,1,2],\"c\":{\"d\":4}}', '{x,-33}', '{\"foo\":123}')" +== 835 +-- truncate_limit: 100 +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{x,y}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\":1,\"b\":[0,1,2],\"c\":{\"d\":4}}', '{x,y}', '{\"foo\":123}')" +== 836 +-- truncate_limit: 100 +-- add to empty object +select jsonb_set('{}','{x}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{}', '{x}', '{\"foo\":123}')" +== 837 +-- truncate_limit: 100 +--add to empty array +select jsonb_set('[]','{0}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('[]', '{0}', '{\"foo\":123}')" +== 838 +-- truncate_limit: 100 +select jsonb_set('[]','{99}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('[]', '{99}', '{\"foo\":123}')" +== 839 +-- truncate_limit: 100 +select jsonb_set('[]','{-99}','{"foo":123}') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('[]', '{-99}', '{\"foo\":123}')" +== 840 +-- truncate_limit: 100 +select jsonb_set('{"a": [1, 2, 3]}', '{a, non_integer}', '"new_value"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\": [1, 2, 3]}', '{a, non_integer}', '\"new_value\"')" +== 841 +-- truncate_limit: 100 +select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, non_integer}', '"new_value"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\": {\"b\": [1, 2, 3]}}', '{a, b, non_integer}', '\"new_value\"')" +== 842 +-- truncate_limit: 100 +select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, NULL}', '"new_value"') +-- +FUNCTION: name="jsonb_set" function="jsonb_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set('{\"a\": {\"b\": [1, 2, 3]}}', '{a, b, NULL}', '\"new_value\"')" +== 843 +-- truncate_limit: 100 +-- jsonb_set_lax + + +-- pass though non nulls to jsonb_set +select jsonb_set_lax('{"a":1,"b":2}','{b}','5') +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set_lax('{\"a\":1,\"b\":2}', '{b}', '5')" +== 844 +-- truncate_limit: 100 +select jsonb_set_lax('{"a":1,"b":2}','{d}','6', true) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set_lax('{\"a\":1,\"b\":2}', '{d}', '6', true)" +== 845 +-- truncate_limit: 100 +-- using the default treatment +select jsonb_set_lax('{"a":1,"b":2}','{b}',null) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set_lax('{\"a\":1,\"b\":2}', '{b}', NULL)" +== 846 +-- truncate_limit: 100 +select jsonb_set_lax('{"a":1,"b":2}','{d}',null,true) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set_lax('{\"a\":1,\"b\":2}', '{d}', NULL, true)" +== 847 +-- truncate_limit: 100 +-- errors +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, true, null) +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set_lax('{\"a\":1,\"b\":2}', '{b}', NULL, true, NULL)" +== 848 +-- truncate_limit: 100 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, true, 'no_such_treatment') +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_set_lax('{\"a\":1,\"b\":2}', '{b}', NULL, true, 'no_such_treatment')" +== 849 +-- truncate_limit: 100 +-- explicit treatments +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'raise_exception') as raise_exception +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 850 +-- truncate_limit: 100 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'return_target') as return_target +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 851 +-- truncate_limit: 100 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'delete_key') as delete_key +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 852 +-- truncate_limit: 100 +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'use_json_null') as use_json_null +-- +FUNCTION: name="jsonb_set_lax" function="jsonb_set_lax" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 853 +-- truncate_limit: 100 +-- jsonb_insert +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 1}', '\"new_value\"')" +== 854 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 1}', '\"new_value\"', true)" +== 855 +-- truncate_limit: 100 +select jsonb_insert('{"a": {"b": {"c": [0, 1, "test1", "test2"]}}}', '{a, b, c, 2}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": {\"b\": {\"c\": [0, 1, \"test1\", \"test2\"]}}}', '{a, b, c, 2}', '\"new_value\"')" +== 856 +-- truncate_limit: 100 +select jsonb_insert('{"a": {"b": {"c": [0, 1, "test1", "test2"]}}}', '{a, b, c, 2}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 857 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '{"b": "value"}') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 1}', '{\"b\": \"value\"}')" +== 858 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '["value1", "value2"]') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 1}', '[\"value1\", \"value2\"]')" +== 859 +-- truncate_limit: 100 +-- edge cases +select jsonb_insert('{"a": [0,1,2]}', '{a, 0}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 0}', '\"new_value\"')" +== 860 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, 0}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 0}', '\"new_value\"', true)" +== 861 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, 2}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 2}', '\"new_value\"')" +== 862 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, 2}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 2}', '\"new_value\"', true)" +== 863 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, -1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, -1}', '\"new_value\"')" +== 864 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, -1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, -1}', '\"new_value\"', true)" +== 865 +-- truncate_limit: 100 +select jsonb_insert('[]', '{1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('[]', '{1}', '\"new_value\"')" +== 866 +-- truncate_limit: 100 +select jsonb_insert('[]', '{1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('[]', '{1}', '\"new_value\"', true)" +== 867 +-- truncate_limit: 100 +select jsonb_insert('{"a": []}', '{a, 1}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": []}', '{a, 1}', '\"new_value\"')" +== 868 +-- truncate_limit: 100 +select jsonb_insert('{"a": []}', '{a, 1}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": []}', '{a, 1}', '\"new_value\"', true)" +== 869 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, 10}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, 10}', '\"new_value\"')" +== 870 +-- truncate_limit: 100 +select jsonb_insert('{"a": [0,1,2]}', '{a, -10}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": [0,1,2]}', '{a, -10}', '\"new_value\"')" +== 871 +-- truncate_limit: 100 +-- jsonb_insert should be able to insert new value for objects, but not to replace +select jsonb_insert('{"a": {"b": "value"}}', '{a, c}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": {\"b\": \"value\"}}', '{a, c}', '\"new_value\"')" +== 872 +-- truncate_limit: 100 +select jsonb_insert('{"a": {"b": "value"}}', '{a, c}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": {\"b\": \"value\"}}', '{a, c}', '\"new_value\"', true)" +== 873 +-- truncate_limit: 100 +select jsonb_insert('{"a": {"b": "value"}}', '{a, b}', '"new_value"') +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": {\"b\": \"value\"}}', '{a, b}', '\"new_value\"')" +== 874 +-- truncate_limit: 100 +select jsonb_insert('{"a": {"b": "value"}}', '{a, b}', '"new_value"', true) +-- +FUNCTION: name="jsonb_insert" function="jsonb_insert" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_insert('{\"a\": {\"b\": \"value\"}}', '{a, b}', '\"new_value\"', true)" +== 875 +-- truncate_limit: 100 +-- jsonb subscript +select ('123'::jsonb)['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('123'::jsonb)['a']" +== 876 +-- truncate_limit: 100 +select ('123'::jsonb)[0] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('123'::jsonb)[0]" +== 877 +-- truncate_limit: 100 +select ('123'::jsonb)[NULL] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('123'::jsonb)[NULL]" +== 878 +-- truncate_limit: 100 +select ('{"a": 1}'::jsonb)['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1}'::jsonb)['a']" +== 879 +-- truncate_limit: 100 +select ('{"a": 1}'::jsonb)[0] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1}'::jsonb)[0]" +== 880 +-- truncate_limit: 100 +select ('{"a": 1}'::jsonb)['not_exist'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1}'::jsonb)['not_exist']" +== 881 +-- truncate_limit: 100 +select ('{"a": 1}'::jsonb)[NULL] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1}'::jsonb)[NULL]" +== 882 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)['a']" +== 883 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[0] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[0]" +== 884 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)['1'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)['1']" +== 885 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[1.0] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[1.0]" +== 886 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[2]" +== 887 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[3] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[3]" +== 888 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[-2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[-2]" +== 889 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[1]['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[1]['a']" +== 890 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[1][0] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[1][0]" +== 891 +-- truncate_limit: 100 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1, \"b\": \"c\", \"d\": [1, 2, 3]}'::jsonb)['b']" +== 892 +-- truncate_limit: 100 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1, \"b\": \"c\", \"d\": [1, 2, 3]}'::jsonb)['d']" +== 893 +-- truncate_limit: 100 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d'][1] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1, \"b\": \"c\", \"d\": [1, 2, 3]}'::jsonb)['d'][1]" +== 894 +-- truncate_limit: 100 +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d']['a'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1, \"b\": \"c\", \"d\": [1, 2, 3]}'::jsonb)['d']['a']" +== 895 +-- truncate_limit: 100 +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": {\"a1\": {\"a2\": \"aaa\"}}, \"b\": \"bbb\", \"c\": \"ccc\"}'::jsonb)['a']['a1']" +== 896 +-- truncate_limit: 100 +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1']['a2'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": {\"a1\": {\"a2\": \"aaa\"}}, \"b\": \"bbb\", \"c\": \"ccc\"}'::jsonb)['a']['a1']['a2']" +== 897 +-- truncate_limit: 100 +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1']['a2']['a3'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": {\"a1\": {\"a2\": \"aaa\"}}, \"b\": \"bbb\", \"c\": \"ccc\"}'::jsonb)['a']['a1']['a2']['a3']" +== 898 +-- truncate_limit: 100 +select ('{"a": ["a1", {"b1": ["aaa", "bbb", "ccc"]}], "b": "bb"}'::jsonb)['a'][1]['b1'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": [\"a1\", {\"b1\": [\"aaa\", \"bbb\", \"ccc\"]}], \"b\": \"bb\"}'::jsonb)['a'][1]['b1']" +== 899 +-- truncate_limit: 100 +select ('{"a": ["a1", {"b1": ["aaa", "bbb", "ccc"]}], "b": "bb"}'::jsonb)['a'][1]['b1'][2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": [\"a1\", {\"b1\": [\"aaa\", \"bbb\", \"ccc\"]}], \"b\": \"bb\"}'::jsonb)['a'][1]['b1'][2]" +== 900 +-- truncate_limit: 100 +-- slices are not supported +select ('{"a": 1}'::jsonb)['a':'b'] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('{\"a\": 1}'::jsonb)['a':'b']" +== 901 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[1:2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[1:2]" +== 902 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[:2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[:2]" +== 903 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[1:] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[1:]" +== 904 +-- truncate_limit: 100 +select ('[1, "2", null]'::jsonb)[:] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ('[1, \"2\", null]'::jsonb)[:]" +== 905 +-- truncate_limit: 100 +create TEMP TABLE test_jsonb_subscript ( + id int, + test_json jsonb +) +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_jsonb_subscript (id int, test_json jsonb)" +== 906 +-- truncate_limit: 100 +insert into test_jsonb_subscript values +(1, '{}'), -- empty jsonb +(2, '{"key": "value"}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{}'), (2, '{\"key\": \"value\"}')" +== 907 +-- truncate_limit: 100 +-- jsonb with data + +-- update empty jsonb +update test_jsonb_subscript set test_json['a'] = '1' where id = 1 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'] = '1' WHERE id = 1" +== 908 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 909 +-- truncate_limit: 100 +-- update jsonb with some data +update test_jsonb_subscript set test_json['a'] = '1' where id = 2 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'] = '1' WHERE id = 2" +== 910 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 911 +-- truncate_limit: 100 +-- replace jsonb +update test_jsonb_subscript set test_json['a'] = '"test"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'] = '\"test\"'" +== 912 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 913 +-- truncate_limit: 100 +-- replace by object +update test_jsonb_subscript set test_json['a'] = '{"b": 1}'::jsonb +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'] = '{\"b\": 1}'::jsonb" +== 914 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 915 +-- truncate_limit: 100 +-- replace by array +update test_jsonb_subscript set test_json['a'] = '[1, 2, 3]'::jsonb +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'] = '[1, 2, 3]'::jsonb" +== 916 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 917 +-- truncate_limit: 100 +-- use jsonb subscription in where clause +select * from test_jsonb_subscript where test_json['key'] = '"value"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FILTER: schema="" table="" column="test_json" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript WHERE test_json['key'] = '\"value\"'" +== 918 +-- truncate_limit: 100 +select * from test_jsonb_subscript where test_json['key_doesnt_exists'] = '"value"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FILTER: schema="" table="" column="test_json" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript WHERE test_json['key_doesnt_exists'] = '\"value\"'" +== 919 +-- truncate_limit: 100 +select * from test_jsonb_subscript where test_json['key'] = '"wrong_value"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FILTER: schema="" table="" column="test_json" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript WHERE test_json['key'] = '\"wrong_value\"'" +== 920 +-- truncate_limit: 100 +-- NULL +update test_jsonb_subscript set test_json[NULL] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[NULL] = '1'" +== 921 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['another_key'] = NULL +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['another_key'] = NULL" +== 922 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 923 +-- truncate_limit: 100 +-- NULL as jsonb source +insert into test_jsonb_subscript values (3, NULL) +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (3, NULL)" +== 924 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'] = '1' where id = 3 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'] = '1' WHERE id = 3" +== 925 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 926 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json = NULL where id = 3 +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json = NULL WHERE id = 3" +== 927 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[0] = '1'" +== 928 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 929 +-- truncate_limit: 100 +-- Fill the gaps logic +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 930 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '[0]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '[0]')" +== 931 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[5] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[5] = '1'" +== 932 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 933 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[-4] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[-4] = '1'" +== 934 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 935 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[-8] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[-8] = '1'" +== 936 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 937 +-- truncate_limit: 100 +-- keep consistent values position +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 938 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '[]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '[]')" +== 939 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[5] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[5] = '1'" +== 940 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 941 +-- truncate_limit: 100 +-- create the whole path +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 942 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{}')" +== 943 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][0]['b'][0]['c'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][0]['b'][0]['c'] = '1'" +== 944 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 945 +-- truncate_limit: 100 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 946 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{}')" +== 947 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][2]['b'][2]['c'][2] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][2]['b'][2]['c'][2] = '1'" +== 948 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 949 +-- truncate_limit: 100 +-- create the whole path with already existing keys +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 950 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{"b": 1}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{\"b\": 1}')" +== 951 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][0] = '2' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][0] = '2'" +== 952 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 953 +-- truncate_limit: 100 +-- the start jsonb is an object, first subscript is treated as a key +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 954 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{}')" +== 955 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[0]['a'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[0]['a'] = '1'" +== 956 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 957 +-- truncate_limit: 100 +-- the start jsonb is an array +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 958 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '[]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '[]')" +== 959 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[0]['a'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[0]['a'] = '1'" +== 960 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[2]['b'] = '2' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[2]['b'] = '2'" +== 961 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 962 +-- truncate_limit: 100 +-- overwriting an existing path +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 963 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{}')" +== 964 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a']['b'][1] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a']['b'][1] = '1'" +== 965 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a']['b'][10] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a']['b'][10] = '1'" +== 966 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 967 +-- truncate_limit: 100 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 968 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '[]') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '[]')" +== 969 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[0][0][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[0][0][0] = '1'" +== 970 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[0][0][1] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[0][0][1] = '1'" +== 971 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 972 +-- truncate_limit: 100 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 973 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{}')" +== 974 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a']['b'][10] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a']['b'][10] = '1'" +== 975 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][10][10] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][10][10] = '1'" +== 976 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 977 +-- truncate_limit: 100 +-- an empty sub element + +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 978 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{"a": {}}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{\"a\": {}}')" +== 979 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a']['b']['c'][2] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a']['b']['c'][2] = '1'" +== 980 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 981 +-- truncate_limit: 100 +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 982 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{"a": []}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{\"a\": []}')" +== 983 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][1]['c'][2] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][1]['c'][2] = '1'" +== 984 +-- truncate_limit: 100 +select * from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 985 +-- truncate_limit: 100 +-- trying replace assuming a composite object, but it's an element or a value + +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 986 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, '{"a": 1}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, '{\"a\": 1}')" +== 987 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a']['b'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a']['b'] = '1'" +== 988 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a']['b']['c'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a']['b']['c'] = '1'" +== 989 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][0] = '1'" +== 990 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][0]['c'] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][0]['c'] = '1'" +== 991 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json['a'][0][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json['a'][0][0] = '1'" +== 992 +-- truncate_limit: 100 +-- trying replace assuming a composite object, but it's a raw scalar + +delete from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM test_jsonb_subscript" +== 993 +-- truncate_limit: 100 +insert into test_jsonb_subscript values (1, 'null') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES (1, 'null')" +== 994 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[0] = '1'" +== 995 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[0][0] = '1' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[0][0] = '1'" +== 996 +-- truncate_limit: 100 +-- try some things with short-header and toasted subscript values + +drop table test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_jsonb_subscript" +== 997 +-- truncate_limit: 100 +create temp table test_jsonb_subscript ( + id text, + test_json jsonb +) +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_jsonb_subscript (id text, test_json jsonb)" +== 998 +-- truncate_limit: 100 +insert into test_jsonb_subscript values('foo', '{"foo": "bar"}') +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript VALUES ('foo', '{\"foo\": \"bar\"}')" +== 999 +-- truncate_limit: 100 +insert into test_jsonb_subscript + select s, ('{"' || s || '": "bar"}')::jsonb from repeat('xyzzy', 500) s +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_subscript SELECT ... FROM repeat('xyzzy', 500) s" +== 1000 +-- truncate_limit: 100 +select length(id), test_json[id] from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(id), test_json[id] FROM test_jsonb_subscript" +== 1001 +-- truncate_limit: 100 +update test_jsonb_subscript set test_json[id] = '"baz"' +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_jsonb_subscript SET test_json[id] = '\"baz\"'" +== 1002 +-- truncate_limit: 100 +select length(id), test_json[id] from test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(id), test_json[id] FROM test_jsonb_subscript" +== 1003 +-- truncate_limit: 100 +table test_jsonb_subscript +-- +TABLE: name="test_jsonb_subscript" schema="" table="test_jsonb_subscript" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_jsonb_subscript" +== 1004 +-- truncate_limit: 100 +-- jsonb to tsvector +select to_tsvector('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('{\"a\": \"aaa bbb ddd ccc\", \"b\": [\"eee fff ggg\"], \"c\": {\"d\": \"hhh iii\"}}'::jsonb)" +== 1005 +-- truncate_limit: 100 +-- jsonb to tsvector with config +select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1006 +-- truncate_limit: 100 +-- jsonb to tsvector with stop words +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1007 +-- truncate_limit: 100 +-- jsonb to tsvector with numeric values +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('english', '{\"a\": \"aaa in bbb ddd ccc\", \"b\": 123, \"c\": 456}'::jsonb)" +== 1008 +-- truncate_limit: 100 +-- jsonb_to_tsvector +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1009 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1010 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1011 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1012 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1013 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1014 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1015 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1016 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1017 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1018 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1019 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1020 +-- truncate_limit: 100 +-- to_tsvector corner cases +select to_tsvector('""'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('\"\"'::jsonb)" +== 1021 +-- truncate_limit: 100 +select to_tsvector('{}'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('{}'::jsonb)" +== 1022 +-- truncate_limit: 100 +select to_tsvector('[]'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('[]'::jsonb)" +== 1023 +-- truncate_limit: 100 +select to_tsvector('null'::jsonb) +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('null'::jsonb)" +== 1024 +-- truncate_limit: 100 +-- jsonb_to_tsvector corner cases +select jsonb_to_tsvector('""'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_to_tsvector('\"\"'::jsonb, '\"all\"')" +== 1025 +-- truncate_limit: 100 +select jsonb_to_tsvector('{}'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_to_tsvector('{}'::jsonb, '\"all\"')" +== 1026 +-- truncate_limit: 100 +select jsonb_to_tsvector('[]'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_to_tsvector('[]'::jsonb, '\"all\"')" +== 1027 +-- truncate_limit: 100 +select jsonb_to_tsvector('null'::jsonb, '"all"') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_to_tsvector('null'::jsonb, '\"all\"')" +== 1028 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '""') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1029 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '{}') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1030 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '[]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1031 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, 'null') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1032 +-- truncate_limit: 100 +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["all", null]') +-- +FUNCTION: name="jsonb_to_tsvector" function="jsonb_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1033 +-- truncate_limit: 100 +-- ts_headline for jsonb +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1034 +-- truncate_limit: 100 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1035 +-- truncate_limit: 100 +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1036 +-- truncate_limit: 100 +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 1037 +-- truncate_limit: 100 +-- corner cases for ts_headline with jsonb +select ts_headline('null'::jsonb, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('null'::jsonb, tsquery('aaa & bbb'))" +== 1038 +-- truncate_limit: 100 +select ts_headline('{}'::jsonb, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('{}'::jsonb, tsquery('aaa & bbb'))" +== 1039 +-- truncate_limit: 100 +select ts_headline('[]'::jsonb, tsquery('aaa & bbb')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="tsquery" function="tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('[]'::jsonb, tsquery('aaa & bbb'))" +== 1040 +-- truncate_limit: 100 +-- casts +select 'true'::jsonb::bool +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true'::jsonb::bool" +== 1041 +-- truncate_limit: 100 +select '[]'::jsonb::bool +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb::bool" +== 1042 +-- truncate_limit: 100 +select '1.0'::jsonb::float +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.0'::jsonb::double precision" +== 1043 +-- truncate_limit: 100 +select '[1.0]'::jsonb::float +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1.0]'::jsonb::double precision" +== 1044 +-- truncate_limit: 100 +select '12345'::jsonb::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345'::jsonb::int4" +== 1045 +-- truncate_limit: 100 +select '"hello"'::jsonb::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"hello\"'::jsonb::int4" +== 1046 +-- truncate_limit: 100 +select '12345'::jsonb::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345'::jsonb::numeric" +== 1047 +-- truncate_limit: 100 +select '{}'::jsonb::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb::numeric" +== 1048 +-- truncate_limit: 100 +select '12345.05'::jsonb::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.05'::jsonb::numeric" +== 1049 +-- truncate_limit: 100 +select '12345.05'::jsonb::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.05'::jsonb::float4" +== 1050 +-- truncate_limit: 100 +select '12345.05'::jsonb::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.05'::jsonb::float8" +== 1051 +-- truncate_limit: 100 +select '12345.05'::jsonb::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.05'::jsonb::int2" +== 1052 +-- truncate_limit: 100 +select '12345.05'::jsonb::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.05'::jsonb::int4" +== 1053 +-- truncate_limit: 100 +select '12345.05'::jsonb::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.05'::jsonb::int8" +== 1054 +-- truncate_limit: 100 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.0000000000000000000000000000000000000000000005'::jsonb::numeric" +== 1055 +-- truncate_limit: 100 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.0000000000000000000000000000000000000000000005'::jsonb::float4" +== 1056 +-- truncate_limit: 100 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.0000000000000000000000000000000000000000000005'::jsonb::float8" +== 1057 +-- truncate_limit: 100 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.0000000000000000000000000000000000000000000005'::jsonb::int2" +== 1058 +-- truncate_limit: 100 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.0000000000000000000000000000000000000000000005'::jsonb::int4" +== 1059 +-- truncate_limit: 100 +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345.0000000000000000000000000000000000000000000005'::jsonb::int8" diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json new file mode 100644 index 0000000..b53b6f2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json @@ -0,0 +1,825 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.test b/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.test new file mode 100644 index 0000000..75d5fb7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.test @@ -0,0 +1,5897 @@ +== 001 +-- truncate_limit: 100 +select jsonb '{"a": 12}' @? '$' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 12}'::jsonb @? '$'" +== 002 +-- truncate_limit: 100 +select jsonb '{"a": 12}' @? '1' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 12}'::jsonb @? '1'" +== 003 +-- truncate_limit: 100 +select jsonb '{"a": 12}' @? '$.a.b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 12}'::jsonb @? '$.a.b'" +== 004 +-- truncate_limit: 100 +select jsonb '{"a": 12}' @? '$.b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 12}'::jsonb @? '$.b'" +== 005 +-- truncate_limit: 100 +select jsonb '{"a": 12}' @? '$.a + 2' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 12}'::jsonb @? '$.a + 2'" +== 006 +-- truncate_limit: 100 +select jsonb '{"a": 12}' @? '$.b + 2' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 12}'::jsonb @? '$.b + 2'" +== 007 +-- truncate_limit: 100 +select jsonb '{"a": {"a": 12}}' @? '$.a.a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"a\": 12}}'::jsonb @? '$.a.a'" +== 008 +-- truncate_limit: 100 +select jsonb '{"a": {"a": 12}}' @? '$.*.a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"a\": 12}}'::jsonb @? '$.*.a'" +== 009 +-- truncate_limit: 100 +select jsonb '{"b": {"a": 12}}' @? '$.*.a' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"b\": {\"a\": 12}}'::jsonb @? '$.*.a'" +== 010 +-- truncate_limit: 100 +select jsonb '{"b": {"a": 12}}' @? '$.*.b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"b\": {\"a\": 12}}'::jsonb @? '$.*.b'" +== 011 +-- truncate_limit: 100 +select jsonb '{"b": {"a": 12}}' @? 'strict $.*.b' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"b\": {\"a\": 12}}'::jsonb @? 'strict $.*.b'" +== 012 +-- truncate_limit: 100 +select jsonb '{}' @? '$.*' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb @? '$.*'" +== 013 +-- truncate_limit: 100 +select jsonb '{"a": 1}' @? '$.*' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 1}'::jsonb @? '$.*'" +== 014 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{1}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? 'lax $.**{1}'" +== 015 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{2}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? 'lax $.**{2}'" +== 016 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{3}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? 'lax $.**{3}'" +== 017 +-- truncate_limit: 100 +select jsonb '[]' @? '$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb @? '$[*]'" +== 018 +-- truncate_limit: 100 +select jsonb '[1]' @? '$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? '$[*]'" +== 019 +-- truncate_limit: 100 +select jsonb '[1]' @? '$[1]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? '$[1]'" +== 020 +-- truncate_limit: 100 +select jsonb '[1]' @? 'strict $[1]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? 'strict $[1]'" +== 021 +-- truncate_limit: 100 +select jsonb_path_query('[1]', 'strict $[1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1]', 'strict $[1]')" +== 022 +-- truncate_limit: 100 +select jsonb_path_query('[1]', 'strict $[1]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1]', 'strict $[1]', silent := true)" +== 023 +-- truncate_limit: 100 +select jsonb '[1]' @? 'lax $[10000000000000000]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? 'lax $[10000000000000000]'" +== 024 +-- truncate_limit: 100 +select jsonb '[1]' @? 'strict $[10000000000000000]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? 'strict $[10000000000000000]'" +== 025 +-- truncate_limit: 100 +select jsonb_path_query('[1]', 'lax $[10000000000000000]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1]', 'lax $[10000000000000000]')" +== 026 +-- truncate_limit: 100 +select jsonb_path_query('[1]', 'strict $[10000000000000000]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1]', 'strict $[10000000000000000]')" +== 027 +-- truncate_limit: 100 +select jsonb '[1]' @? '$[0]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? '$[0]'" +== 028 +-- truncate_limit: 100 +select jsonb '[1]' @? '$[0.3]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? '$[0.3]'" +== 029 +-- truncate_limit: 100 +select jsonb '[1]' @? '$[0.5]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? '$[0.5]'" +== 030 +-- truncate_limit: 100 +select jsonb '[1]' @? '$[0.9]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? '$[0.9]'" +== 031 +-- truncate_limit: 100 +select jsonb '[1]' @? '$[1.2]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? '$[1.2]'" +== 032 +-- truncate_limit: 100 +select jsonb '[1]' @? 'strict $[1.2]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1]'::jsonb @? 'strict $[1.2]'" +== 033 +-- truncate_limit: 100 +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] > @.b[*])' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [1,2,3], \"b\": [3,4,5]}'::jsonb @? '$ ? (@.a[*] > @.b[*])'" +== 034 +-- truncate_limit: 100 +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [1,2,3], \"b\": [3,4,5]}'::jsonb @? '$ ? (@.a[*] >= @.b[*])'" +== 035 +-- truncate_limit: 100 +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? '$ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [1,2,3], \"b\": [3,4,\"5\"]}'::jsonb @? '$ ? (@.a[*] >= @.b[*])'" +== 036 +-- truncate_limit: 100 +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? 'strict $ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [1,2,3], \"b\": [3,4,\"5\"]}'::jsonb @? 'strict $ ? (@.a[*] >= @.b[*])'" +== 037 +-- truncate_limit: 100 +select jsonb '{"a": [1,2,3], "b": [3,4,null]}' @? '$ ? (@.a[*] >= @.b[*])' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": [1,2,3], \"b\": [3,4,null]}'::jsonb @? '$ ? (@.a[*] >= @.b[*])'" +== 038 +-- truncate_limit: 100 +select jsonb '1' @? '$ ? ((@ == "1") is unknown)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::jsonb @? '$ ? ((@ == \"1\") is unknown)'" +== 039 +-- truncate_limit: 100 +select jsonb '1' @? '$ ? ((@ == 1) is unknown)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::jsonb @? '$ ? ((@ == 1) is unknown)'" +== 040 +-- truncate_limit: 100 +select jsonb '[{"a": 1}, {"a": 2}]' @? '$[0 to 1] ? (@.a > 1)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"a\": 1}, {\"a\": 2}]'::jsonb @? '$[0 to 1] ? (@.a > 1)'" +== 041 +-- truncate_limit: 100 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => false) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_exists('[{\"a\": 1}, {\"a\": 2}, 3]', 'lax $[*].a', silent := false)" +== 042 +-- truncate_limit: 100 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_exists('[{\"a\": 1}, {\"a\": 2}, 3]', 'lax $[*].a', silent := true)" +== 043 +-- truncate_limit: 100 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => false) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_exists('[{\"a\": 1}, {\"a\": 2}, 3]', 'strict $[*].a', silent := false)" +== 044 +-- truncate_limit: 100 +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_exists('[{\"a\": 1}, {\"a\": 2}, 3]', 'strict $[*].a', silent := true)" +== 045 +-- truncate_limit: 100 +select jsonb_path_query('1', 'lax $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'lax $.a')" +== 046 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $.a')" +== 047 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $.*') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $.*')" +== 048 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $.a', silent := true)" +== 049 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $.*', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $.*', silent := true)" +== 050 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'lax $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'lax $.a')" +== 051 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.a')" +== 052 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.a', silent := true)" +== 053 +-- truncate_limit: 100 +select jsonb_path_query('{}', 'lax $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', 'lax $.a')" +== 054 +-- truncate_limit: 100 +select jsonb_path_query('{}', 'strict $.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', 'strict $.a')" +== 055 +-- truncate_limit: 100 +select jsonb_path_query('{}', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', 'strict $.a', silent := true)" +== 056 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $[1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $[1]')" +== 057 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $[*]')" +== 058 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $[1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $[1]')" +== 059 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $["a"]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $[\"a\"]')" +== 060 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $[1]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $[1]', silent := true)" +== 061 +-- truncate_limit: 100 +select jsonb_path_query('1', 'strict $[*]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'strict $[*]', silent := true)" +== 062 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $[1]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $[1]', silent := true)" +== 063 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $["a"]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $[\"a\"]', silent := true)" +== 064 +-- truncate_limit: 100 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": 12, \"b\": {\"a\": 13}}', '$.a')" +== 065 +-- truncate_limit: 100 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.b') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": 12, \"b\": {\"a\": 13}}', '$.b')" +== 066 +-- truncate_limit: 100 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.*') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": 12, \"b\": {\"a\": 13}}', '$.*')" +== 067 +-- truncate_limit: 100 +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', 'lax $.*.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": 12, \"b\": {\"a\": 13}}', 'lax $.*.a')" +== 068 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[*].a')" +== 069 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].*') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[*].*')" +== 070 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[0].a')" +== 071 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[1].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[1].a')" +== 072 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[2].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[2].a')" +== 073 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0,1].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[0,1].a')" +== 074 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[0 to 10].a')" +== 075 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10 / 0].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}]', 'lax $[0 to 10 / 0].a')" +== 076 +-- truncate_limit: 100 +select jsonb_path_query('[12, {"a": 13}, {"b": 14}, "ccc", true]', '$[2.5 - 1 to $.size() - 2]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[12, {\"a\": 13}, {\"b\": 14}, \"ccc\", true]', '$[2.5 - 1 to $.size() - 2]')" +== 077 +-- truncate_limit: 100 +select jsonb_path_query('1', 'lax $[0]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'lax $[0]')" +== 078 +-- truncate_limit: 100 +select jsonb_path_query('1', 'lax $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', 'lax $[*]')" +== 079 +-- truncate_limit: 100 +select jsonb_path_query('[1]', 'lax $[0]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1]', 'lax $[0]')" +== 080 +-- truncate_limit: 100 +select jsonb_path_query('[1]', 'lax $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1]', 'lax $[*]')" +== 081 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', 'lax $[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', 'lax $[*]')" +== 082 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', 'strict $[*].a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', 'strict $[*].a')" +== 083 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', 'strict $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', 'strict $[*].a', silent := true)" +== 084 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$[last]')" +== 085 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$[last ? (exists(last))]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$[last ? (exists(last))]')" +== 086 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $[last]')" +== 087 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $[last]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $[last]', silent := true)" +== 088 +-- truncate_limit: 100 +select jsonb_path_query('[1]', '$[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1]', '$[last]')" +== 089 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', '$[last]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', '$[last]')" +== 090 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', '$[last - 1]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', '$[last - 1]')" +== 091 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "number")]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', '$[last ? (@.type() == \"number\")]')" +== 092 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', '$[last ? (@.type() == \"string\")]')" +== 093 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,3]', '$[last ? (@.type() == \"string\")]', silent := true)" +== 094 +-- truncate_limit: 100 +select * from jsonb_path_query('{"a": 10}', '$') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{\"a\": 10}', '$')" +== 095 +-- truncate_limit: 100 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{\"a\": 10}', '$ ? (@.a < $value)')" +== 096 +-- truncate_limit: 100 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{\"a\": 10}', '$ ? (@.a < $value)', '1')" +== 097 +-- truncate_limit: 100 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '[{"value" : 13}]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{\"a\": 10}', '$ ? (@.a < $value)', '[{\"value\" : 13}]')" +== 098 +-- truncate_limit: 100 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 13}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{\"a\": 10}', '$ ? (@.a < $value)', '{\"value\" : 13}')" +== 099 +-- truncate_limit: 100 +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 8}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{\"a\": 10}', '$ ? (@.a < $value)', '{\"value\" : 8}')" +== 100 +-- truncate_limit: 100 +select * from jsonb_path_query('{"a": 10}', '$.a ? (@ < $value)', '{"value" : 13}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{\"a\": 10}', '$.a ? (@ < $value)', '{\"value\" : 13}')" +== 101 +-- truncate_limit: 100 +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[*] ? (@ < $value)', '{"value" : 13}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[10,11,12,13,14,15]', '$[*] ? (@ < $value)', '{\"value\" : 13}')" +== 102 +-- truncate_limit: 100 +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0,1] ? (@ < $x.value)', '{"x": {"value" : 13}}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[10,11,12,13,14,15]', '$[0,1] ? (@ < $x.value)', '{\"x\": {\"value\" ..." +== 103 +-- truncate_limit: 100 +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0 to 2] ? (@ < $value)', '{"value" : 15}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[10,11,12,13,14,15]', '$[0 to 2] ? (@ < $value)', '{\"value\" : 15}')" +== 104 +-- truncate_limit: 100 +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == "1")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[1,\"1\",2,\"2\",null]', '$[*] ? (@ == \"1\")')" +== 105 +-- truncate_limit: 100 +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : "1"}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[1,\"1\",2,\"2\",null]', '$[*] ? (@ == $value)', '{\"value\" : \"1\"}')" +== 106 +-- truncate_limit: 100 +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : null}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[1,\"1\",2,\"2\",null]', '$[*] ? (@ == $value)', '{\"value\" : null}')" +== 107 +-- truncate_limit: 100 +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ != null)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[1, \"2\", null]', '$[*] ? (@ != null)')" +== 108 +-- truncate_limit: 100 +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ == null)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[1, \"2\", null]', '$[*] ? (@ == null)')" +== 109 +-- truncate_limit: 100 +select * from jsonb_path_query('{}', '$ ? (@ == @)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('{}', '$ ? (@ == @)')" +== 110 +-- truncate_limit: 100 +select * from jsonb_path_query('[]', 'strict $ ? (@ == @)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM jsonb_path_query('[]', 'strict $ ? (@ == @)')" +== 111 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**')" +== 112 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{0}')" +== 113 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{0 to last}')" +== 114 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{1}')" +== 115 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{1 to last}')" +== 116 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{2}')" +== 117 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{2 to last}')" +== 118 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{3 to last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{3 to last}')" +== 119 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{last}') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{last}')" +== 120 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**.b ? (@ > 0)')" +== 121 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{0}.b ? (@ > 0)')" +== 122 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{1}.b ? (@ > 0)')" +== 123 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{0 to last}.b ? (@ > 0)')" +== 124 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{1 to last}.b ? (@ > 0)')" +== 125 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to 2}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"b\": 1}}', 'lax $.**{1 to 2}.b ? (@ > 0)')" +== 126 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"c\": {\"b\": 1}}}', 'lax $.**.b ? (@ > 0)')" +== 127 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"c\": {\"b\": 1}}}', 'lax $.**{0}.b ? (@ > 0)')" +== 128 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"c\": {\"b\": 1}}}', 'lax $.**{1}.b ? (@ > 0)')" +== 129 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"c\": {\"b\": 1}}}', 'lax $.**{0 to last}.b ? (@ > 0)')" +== 130 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to last}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"c\": {\"b\": 1}}}', 'lax $.**{1 to last}.b ? (@ > 0)')" +== 131 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to 2}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"c\": {\"b\": 1}}}', 'lax $.**{1 to 2}.b ? (@ > 0)')" +== 132 +-- truncate_limit: 100 +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{2 to 3}.b ? (@ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": {\"c\": {\"b\": 1}}}', 'lax $.**{2 to 3}.b ? (@ > 0)')" +== 133 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? '$.**.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? '$.**.b ? ( @ > 0)'" +== 134 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? '$.**{0}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? '$.**{0}.b ? ( @ > 0)'" +== 135 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? '$.**{1}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? '$.**{1}.b ? ( @ > 0)'" +== 136 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? '$.**{0 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? '$.**{0 to last}.b ? ( @ > 0)'" +== 137 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? '$.**{1 to last}.b ? ( @ > 0)'" +== 138 +-- truncate_limit: 100 +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to 2}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"b\": 1}}'::jsonb @? '$.**{1 to 2}.b ? ( @ > 0)'" +== 139 +-- truncate_limit: 100 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"c\": {\"b\": 1}}}'::jsonb @? '$.**.b ? ( @ > 0)'" +== 140 +-- truncate_limit: 100 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"c\": {\"b\": 1}}}'::jsonb @? '$.**{0}.b ? ( @ > 0)'" +== 141 +-- truncate_limit: 100 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"c\": {\"b\": 1}}}'::jsonb @? '$.**{1}.b ? ( @ > 0)'" +== 142 +-- truncate_limit: 100 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"c\": {\"b\": 1}}}'::jsonb @? '$.**{0 to last}.b ? ( @ > 0)'" +== 143 +-- truncate_limit: 100 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to last}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"c\": {\"b\": 1}}}'::jsonb @? '$.**{1 to last}.b ? ( @ > 0)'" +== 144 +-- truncate_limit: 100 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to 2}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"c\": {\"b\": 1}}}'::jsonb @? '$.**{1 to 2}.b ? ( @ > 0)'" +== 145 +-- truncate_limit: 100 +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2 to 3}.b ? ( @ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": {\"c\": {\"b\": 1}}}'::jsonb @? '$.**{2 to 3}.b ? ( @ > 0)'" +== 146 +-- truncate_limit: 100 +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"g\": {\"x\": 2}}', '$.g ? (exists (@.x))')" +== 147 +-- truncate_limit: 100 +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.y))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"g\": {\"x\": 2}}', '$.g ? (exists (@.y))')" +== 148 +-- truncate_limit: 100 +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x ? (@ >= 2) ))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"g\": {\"x\": 2}}', '$.g ? (exists (@.x ? (@ >= 2) ))')" +== 149 +-- truncate_limit: 100 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"g\": [{\"x\": 2}, {\"y\": 3}]}', 'lax $.g ? (exists (@.x))')" +== 150 +-- truncate_limit: 100 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x + "3"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"g\": [{\"x\": 2}, {\"y\": 3}]}', 'lax $.g ? (exists (@.x + \"3\"))')" +== 151 +-- truncate_limit: 100 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? ((exists (@.x + "3")) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 152 +-- truncate_limit: 100 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? (exists (@.x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"g\": [{\"x\": 2}, {\"y\": 3}]}', 'strict $.g[*] ? (exists (@.x))')" +== 153 +-- truncate_limit: 100 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? ((exists (@.x)) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 154 +-- truncate_limit: 100 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? (exists (@[*].x))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"g\": [{\"x\": 2}, {\"y\": 3}]}', 'strict $.g ? (exists (@[*].x))')" +== 155 +-- truncate_limit: 100 +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? ((exists (@[*].x)) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 156 +-- truncate_limit: 100 +--test ternary logic +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true && $y == true) || + @ == false && !($x == true && $y == true) || + @ == null && ($x == true && $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x && y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(x), (VALUES (...)) y(y)" +== 157 +-- truncate_limit: 100 +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true || $y == true) || + @ == false && !($x == true || $y == true) || + @ == null && ($x == true || $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x || y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) x(x), (VALUES (...)) y(y)" +== 158 +-- truncate_limit: 100 +select jsonb '{"a": 1, "b":1}' @? '$ ? (@.a == @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 1, \"b\":1}'::jsonb @? '$ ? (@.a == @.b)'" +== 159 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$ ? (@.a == @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 1, \"b\":1}}'::jsonb @? '$ ? (@.a == @.b)'" +== 160 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? (@.a == @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 1, \"b\":1}}'::jsonb @? '$.c ? (@.a == @.b)'" +== 161 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? ($.c.a == @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 1, \"b\":1}}'::jsonb @? '$.c ? ($.c.a == @.b)'" +== 162 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.* ? (@.a == @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 1, \"b\":1}}'::jsonb @? '$.* ? (@.a == @.b)'" +== 163 +-- truncate_limit: 100 +select jsonb '{"a": 1, "b":1}' @? '$.** ? (@.a == @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 1, \"b\":1}'::jsonb @? '$.** ? (@.a == @.b)'" +== 164 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.** ? (@.a == @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 1, \"b\":1}}'::jsonb @? '$.** ? (@.a == @.b)'" +== 165 +-- truncate_limit: 100 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == 1 + 1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"c\": {\"a\": 2, \"b\":1}}', '$.** ? (@.a == 1 + 1)')" +== 166 +-- truncate_limit: 100 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (1 + 1))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"c\": {\"a\": 2, \"b\":1}}', '$.** ? (@.a == (1 + 1))')" +== 167 +-- truncate_limit: 100 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == @.b + 1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"c\": {\"a\": 2, \"b\":1}}', '$.** ? (@.a == @.b + 1)')" +== 168 +-- truncate_limit: 100 +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (@.b + 1))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"c\": {\"a\": 2, \"b\":1}}', '$.** ? (@.a == (@.b + 1))')" +== 169 +-- truncate_limit: 100 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - 1)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": -1, \"b\":1}}'::jsonb @? '$.** ? (@.a == - 1)'" +== 170 +-- truncate_limit: 100 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -1)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": -1, \"b\":1}}'::jsonb @? '$.** ? (@.a == -1)'" +== 171 +-- truncate_limit: 100 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -@.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": -1, \"b\":1}}'::jsonb @? '$.** ? (@.a == -@.b)'" +== 172 +-- truncate_limit: 100 +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": -1, \"b\":1}}'::jsonb @? '$.** ? (@.a == - @.b)'" +== 173 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 0, \"b\":1}}'::jsonb @? '$.** ? (@.a == 1 - @.b)'" +== 174 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 2, "b":1}}' @? '$.** ? (@.a == 1 - - @.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 2, \"b\":1}}'::jsonb @? '$.** ? (@.a == 1 - - @.b)'" +== 175 +-- truncate_limit: 100 +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - +@.b)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"c\": {\"a\": 0, \"b\":1}}'::jsonb @? '$.** ? (@.a == 1 - +@.b)'" +== 176 +-- truncate_limit: 100 +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +2)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::jsonb @? '$ ? (+@[*] > +2)'" +== 177 +-- truncate_limit: 100 +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +3)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::jsonb @? '$ ? (+@[*] > +3)'" +== 178 +-- truncate_limit: 100 +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -2)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::jsonb @? '$ ? (-@[*] < -2)'" +== 179 +-- truncate_limit: 100 +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -3)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::jsonb @? '$ ? (-@[*] < -3)'" +== 180 +-- truncate_limit: 100 +select jsonb '1' @? '$ ? ($ > 0)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::jsonb @? '$ ? ($ > 0)'" +== 181 +-- truncate_limit: 100 +-- arithmetic errors +select jsonb_path_query('[1,2,0,3]', '$[*] ? (2 / @ > 0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,0,3]', '$[*] ? (2 / @ > 0)')" +== 182 +-- truncate_limit: 100 +select jsonb_path_query('[1,2,0,3]', '$[*] ? ((2 / @ > 0) is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,2,0,3]', '$[*] ? ((2 / @ > 0) is unknown)')" +== 183 +-- truncate_limit: 100 +select jsonb_path_query('0', '1 / $') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('0', '1 / $')" +== 184 +-- truncate_limit: 100 +select jsonb_path_query('0', '1 / $ + 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('0', '1 / $ + 2')" +== 185 +-- truncate_limit: 100 +select jsonb_path_query('0', '-(3 + 1 % $)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('0', '-(3 + 1 % $)')" +== 186 +-- truncate_limit: 100 +select jsonb_path_query('1', '$ + "2"') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$ + \"2\"')" +== 187 +-- truncate_limit: 100 +select jsonb_path_query('[1, 2]', '3 * $') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1, 2]', '3 * $')" +== 188 +-- truncate_limit: 100 +select jsonb_path_query('"a"', '-$') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"a\"', '-$')" +== 189 +-- truncate_limit: 100 +select jsonb_path_query('[1,"2",3]', '+$') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,\"2\",3]', '+$')" +== 190 +-- truncate_limit: 100 +select jsonb_path_query('1', '$ + "2"', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$ + \"2\"', silent := true)" +== 191 +-- truncate_limit: 100 +select jsonb_path_query('[1, 2]', '3 * $', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1, 2]', '3 * $', silent := true)" +== 192 +-- truncate_limit: 100 +select jsonb_path_query('"a"', '-$', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"a\"', '-$', silent := true)" +== 193 +-- truncate_limit: 100 +select jsonb_path_query('[1,"2",3]', '+$', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,\"2\",3]', '+$', silent := true)" +== 194 +-- truncate_limit: 100 +select jsonb '["1",2,0,3]' @? '-$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"1\",2,0,3]'::jsonb @? '-$[*]'" +== 195 +-- truncate_limit: 100 +select jsonb '[1,"2",0,3]' @? '-$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,\"2\",0,3]'::jsonb @? '-$[*]'" +== 196 +-- truncate_limit: 100 +select jsonb '["1",2,0,3]' @? 'strict -$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"1\",2,0,3]'::jsonb @? 'strict -$[*]'" +== 197 +-- truncate_limit: 100 +select jsonb '[1,"2",0,3]' @? 'strict -$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,\"2\",0,3]'::jsonb @? 'strict -$[*]'" +== 198 +-- truncate_limit: 100 +-- unwrapping of operator arguments in lax mode +select jsonb_path_query('{"a": [2]}', 'lax $.a * 3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": [2]}', 'lax $.a * 3')" +== 199 +-- truncate_limit: 100 +select jsonb_path_query('{"a": [2]}', 'lax $.a + 3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": [2]}', 'lax $.a + 3')" +== 200 +-- truncate_limit: 100 +select jsonb_path_query('{"a": [2, 3, 4]}', 'lax -$.a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": [2, 3, 4]}', 'lax -$.a')" +== 201 +-- truncate_limit: 100 +-- should fail +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": [1, 2]}', 'lax $.a * 3')" +== 202 +-- truncate_limit: 100 +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": [1, 2]}', 'lax $.a * 3', silent := true)" +== 203 +-- truncate_limit: 100 +-- extension: boolean expressions +select jsonb_path_query('2', '$ > 1') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('2', '$ > 1')" +== 204 +-- truncate_limit: 100 +select jsonb_path_query('2', '$ <= 1') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('2', '$ <= 1')" +== 205 +-- truncate_limit: 100 +select jsonb_path_query('2', '$ == "2"') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('2', '$ == \"2\"')" +== 206 +-- truncate_limit: 100 +select jsonb '2' @? '$ == "2"' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2'::jsonb @? '$ == \"2\"'" +== 207 +-- truncate_limit: 100 +select jsonb '2' @@ '$ > 1' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2'::jsonb @@ '$ > 1'" +== 208 +-- truncate_limit: 100 +select jsonb '2' @@ '$ <= 1' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2'::jsonb @@ '$ <= 1'" +== 209 +-- truncate_limit: 100 +select jsonb '2' @@ '$ == "2"' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2'::jsonb @@ '$ == \"2\"'" +== 210 +-- truncate_limit: 100 +select jsonb '2' @@ '1' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2'::jsonb @@ '1'" +== 211 +-- truncate_limit: 100 +select jsonb '{}' @@ '$' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::jsonb @@ '$'" +== 212 +-- truncate_limit: 100 +select jsonb '[]' @@ '$' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb @@ '$'" +== 213 +-- truncate_limit: 100 +select jsonb '[1,2,3]' @@ '$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[1,2,3]'::jsonb @@ '$[*]'" +== 214 +-- truncate_limit: 100 +select jsonb '[]' @@ '$[*]' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::jsonb @@ '$[*]'" +== 215 +-- truncate_limit: 100 +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{\"x\": 1}')" +== 216 +-- truncate_limit: 100 +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{\"x\": 2}')" +== 217 +-- truncate_limit: 100 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[{\"a\": 1}, {\"a\": 2}, 3]', 'lax exists($[*].a)', silent := false)" +== 218 +-- truncate_limit: 100 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[{\"a\": 1}, {\"a\": 2}, 3]', 'lax exists($[*].a)', silent := true)" +== 219 +-- truncate_limit: 100 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[{\"a\": 1}, {\"a\": 2}, 3]', 'strict exists($[*].a)', silent := false)" +== 220 +-- truncate_limit: 100 +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[{\"a\": 1}, {\"a\": 2}, 3]', 'strict exists($[*].a)', silent := true)" +== 221 +-- truncate_limit: 100 +select jsonb_path_query('[null,1,true,"a",[],{}]', '$.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[null,1,true,\"a\",[],{}]', '$.type()')" +== 222 +-- truncate_limit: 100 +select jsonb_path_query('[null,1,true,"a",[],{}]', 'lax $.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[null,1,true,\"a\",[],{}]', 'lax $.type()')" +== 223 +-- truncate_limit: 100 +select jsonb_path_query('[null,1,true,"a",[],{}]', '$[*].type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[null,1,true,\"a\",[],{}]', '$[*].type()')" +== 224 +-- truncate_limit: 100 +select jsonb_path_query('null', 'null.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', 'null.type()')" +== 225 +-- truncate_limit: 100 +select jsonb_path_query('null', 'true.type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', 'true.type()')" +== 226 +-- truncate_limit: 100 +select jsonb_path_query('null', '(123).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '(123).type()')" +== 227 +-- truncate_limit: 100 +select jsonb_path_query('null', '"123".type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '\"123\".type()')" +== 228 +-- truncate_limit: 100 +select jsonb_path_query('{"a": 2}', '($.a - 5).abs() + 10') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": 2}', '($.a - 5).abs() + 10')" +== 229 +-- truncate_limit: 100 +select jsonb_path_query('{"a": 2.5}', '-($.a * $.a).floor() % 4.3') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": 2.5}', '-($.a * $.a).floor() % 4.3')" +== 230 +-- truncate_limit: 100 +select jsonb_path_query('[1, 2, 3]', '($[*] > 2) ? (@ == true)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1, 2, 3]', '($[*] > 2) ? (@ == true)')" +== 231 +-- truncate_limit: 100 +select jsonb_path_query('[1, 2, 3]', '($[*] > 3).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1, 2, 3]', '($[*] > 3).type()')" +== 232 +-- truncate_limit: 100 +select jsonb_path_query('[1, 2, 3]', '($[*].a > 3).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1, 2, 3]', '($[*].a > 3).type()')" +== 233 +-- truncate_limit: 100 +select jsonb_path_query('[1, 2, 3]', 'strict ($[*].a > 3).type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1, 2, 3]', 'strict ($[*].a > 3).type()')" +== 234 +-- truncate_limit: 100 +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,null,true,\"11\",[],[1],[1,2,3],{},{\"a\":1,\"b\":2}]', 'strict $[*].size()')" +== 235 +-- truncate_limit: 100 +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 236 +-- truncate_limit: 100 +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'lax $[*].size()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[1,null,true,\"11\",[],[1],[1,2,3],{},{\"a\":1,\"b\":2}]', 'lax $[*].size()')" +== 237 +-- truncate_limit: 100 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].abs()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].abs()')" +== 238 +-- truncate_limit: 100 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].floor()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].floor()')" +== 239 +-- truncate_limit: 100 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling()')" +== 240 +-- truncate_limit: 100 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs()')" +== 241 +-- truncate_limit: 100 +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs().type()')" +== 242 +-- truncate_limit: 100 +select jsonb_path_query('[{},1]', '$[*].keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{},1]', '$[*].keyvalue()')" +== 243 +-- truncate_limit: 100 +select jsonb_path_query('[{},1]', '$[*].keyvalue()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{},1]', '$[*].keyvalue()', silent := true)" +== 244 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.keyvalue()')" +== 245 +-- truncate_limit: 100 +select jsonb_path_query('{"a": 1, "b": [1, 2], "c": {"a": "bbb"}}', '$.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{\"a\": 1, \"b\": [1, 2], \"c\": {\"a\": \"bbb\"}}', '$.keyvalue()')" +== 246 +-- truncate_limit: 100 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', '$[*].keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1, \"b\": [1, 2]}, {\"c\": {\"a\": \"bbb\"}}]', '$[*].keyvalue()')" +== 247 +-- truncate_limit: 100 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1, \"b\": [1, 2]}, {\"c\": {\"a\": \"bbb\"}}]', 'strict $.keyvalue()')" +== 248 +-- truncate_limit: 100 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'lax $.keyvalue()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1, \"b\": [1, 2]}, {\"c\": {\"a\": \"bbb\"}}]', 'lax $.keyvalue()')" +== 249 +-- truncate_limit: 100 +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue().a') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1, \"b\": [1, 2]}, {\"c\": {\"a\": \"bbb\"}}]', 'strict $.keyvalue().a')" +== 250 +-- truncate_limit: 100 +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue()' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 1, \"b\": [1, 2]}'::jsonb @? 'lax $.keyvalue()'" +== 251 +-- truncate_limit: 100 +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue().key' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{\"a\": 1, \"b\": [1, 2]}'::jsonb @? 'lax $.keyvalue().key'" +== 252 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.double()')" +== 253 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.double()')" +== 254 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.double()', silent := true)" +== 255 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.double()', silent := true)" +== 256 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.double()')" +== 257 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.double()')" +== 258 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.double()')" +== 259 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.double()', silent := true)" +== 260 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.double()', silent := true)" +== 261 +-- truncate_limit: 100 +select jsonb_path_query('1.23', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.23', '$.double()')" +== 262 +-- truncate_limit: 100 +select jsonb_path_query('"1.23"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23\"', '$.double()')" +== 263 +-- truncate_limit: 100 +select jsonb_path_query('"1.23aaa"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23aaa\"', '$.double()')" +== 264 +-- truncate_limit: 100 +select jsonb_path_query('1e1000', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1e1000', '$.double()')" +== 265 +-- truncate_limit: 100 +select jsonb_path_query('"nan"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"nan\"', '$.double()')" +== 266 +-- truncate_limit: 100 +select jsonb_path_query('"NaN"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"NaN\"', '$.double()')" +== 267 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.double()')" +== 268 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.double()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.double()')" +== 269 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.double()', silent := true)" +== 270 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.double()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.double()', silent := true)" +== 271 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.abs()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.abs()')" +== 272 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.floor()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.floor()')" +== 273 +-- truncate_limit: 100 +select jsonb_path_query('"1.2"', '$.ceiling()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.2\"', '$.ceiling()')" +== 274 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.abs()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.abs()', silent := true)" +== 275 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.floor()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.floor()', silent := true)" +== 276 +-- truncate_limit: 100 +select jsonb_path_query('"1.2"', '$.ceiling()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.2\"', '$.ceiling()', silent := true)" +== 277 +-- truncate_limit: 100 +select jsonb_path_query('["", "a", "abc", "abcabc"]', '$[*] ? (@ starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[\"\", \"a\", \"abc\", \"abcabc\"]', '$[*] ? (@ starts with \"abc\")')" +== 278 +-- truncate_limit: 100 +select jsonb_path_query('["", "a", "abc", "abcabc"]', 'strict $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[\"\", \"a\", \"abc\", \"abcabc\"]', 'strict $ ? (@[*] starts with \"abc\")')" +== 279 +-- truncate_limit: 100 +select jsonb_path_query('["", "a", "abd", "abdabc"]', 'strict $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[\"\", \"a\", \"abd\", \"abdabc\"]', 'strict $ ? (@[*] starts with \"abc\")')" +== 280 +-- truncate_limit: 100 +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[\"abc\", \"abcabc\", null, 1]', 'strict $ ? (@[*] starts with \"abc\")')" +== 281 +-- truncate_limit: 100 +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? ((@[*] starts with "abc") is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 282 +-- truncate_limit: 100 +select jsonb_path_query('[[null, 1, "abc", "abcabc"]]', 'lax $ ? (@[*] starts with "abc")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[[null, 1, \"abc\", \"abcabc\"]]', 'lax $ ? (@[*] starts with \"abc\")')" +== 283 +-- truncate_limit: 100 +select jsonb_path_query('[[null, 1, "abd", "abdabc"]]', 'lax $ ? ((@[*] starts with "abc") is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 284 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "abd", "abdabc"]', 'lax $[*] ? ((@ starts with "abc") is unknown)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 285 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 286 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "i")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 287 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "m")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 288 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "s")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 289 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 290 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 291 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 292 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 293 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 294 +-- truncate_limit: 100 +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 295 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.datetime()')" +== 296 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.datetime()')" +== 297 +-- truncate_limit: 100 +select jsonb_path_query('1', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$.datetime()')" +== 298 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.datetime()')" +== 299 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.datetime()')" +== 300 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.datetime()')" +== 301 +-- truncate_limit: 100 +select jsonb_path_query('"bogus"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"bogus\"', '$.datetime()')" +== 302 +-- truncate_limit: 100 +select jsonb_path_query('"12:34"', '$.datetime("aaa")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34\"', '$.datetime(\"aaa\")')" +== 303 +-- truncate_limit: 100 +select jsonb_path_query('"aaaa"', '$.datetime("HH24")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"aaaa\"', '$.datetime(\"HH24\")')" +== 304 +-- truncate_limit: 100 +select jsonb '"10-03-2017"' @? '$.datetime("dd-mm-yyyy")' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"10-03-2017\"'::jsonb @? '$.datetime(\"dd-mm-yyyy\")'" +== 305 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017\"', '$.datetime(\"dd-mm-yyyy\")')" +== 306 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017\"', '$.datetime(\"dd-mm-yyyy\").type()')" +== 307 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34\"', '$.datetime(\"dd-mm-yyyy\")')" +== 308 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34\"', '$.datetime(\"dd-mm-yyyy\").type()')" +== 309 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34"', ' $.datetime("dd-mm-yyyy HH24:MI").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34\"', ' $.datetime(\"dd-mm-yyyy HH24:MI\").type()')" +== 310 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 311 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.datetime("HH24:MI:SS").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.datetime(\"HH24:MI:SS\").type()')" +== 312 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +05:20"', '$.datetime("HH24:MI:SS TZH:TZM").type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +05:20\"', '$.datetime(\"HH24:MI:SS TZH:TZM\").type()')" +== 313 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017T12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017T12:34:56\"', E'$.datetime(\"dd-mm-yyyy\\\\\"T\\\\\"HH24:MI:SS\")')" +== 314 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017t12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017t12:34:56\"', E'$.datetime(\"dd-mm-yyyy\\\\\"T\\\\\"HH24:MI:SS\")')" +== 315 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34:56\"', E'$.datetime(\"dd-mm-yyyy\\\\\"T\\\\\"HH24:MI:SS\")')" +== 316 +-- truncate_limit: 100 +-- Test .bigint() +select jsonb_path_query('null', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.bigint()')" +== 317 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.bigint()')" +== 318 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.bigint()', silent := true)" +== 319 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.bigint()', silent := true)" +== 320 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.bigint()')" +== 321 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.bigint()')" +== 322 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.bigint()')" +== 323 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.bigint()', silent := true)" +== 324 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.bigint()', silent := true)" +== 325 +-- truncate_limit: 100 +select jsonb_path_query('"1.23"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23\"', '$.bigint()')" +== 326 +-- truncate_limit: 100 +select jsonb_path_query('"1.23aaa"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23aaa\"', '$.bigint()')" +== 327 +-- truncate_limit: 100 +select jsonb_path_query('1e1000', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1e1000', '$.bigint()')" +== 328 +-- truncate_limit: 100 +select jsonb_path_query('"nan"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"nan\"', '$.bigint()')" +== 329 +-- truncate_limit: 100 +select jsonb_path_query('"NaN"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"NaN\"', '$.bigint()')" +== 330 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.bigint()')" +== 331 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.bigint()')" +== 332 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.bigint()', silent := true)" +== 333 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.bigint()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.bigint()', silent := true)" +== 334 +-- truncate_limit: 100 +select jsonb_path_query('123', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('123', '$.bigint()')" +== 335 +-- truncate_limit: 100 +select jsonb_path_query('"123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"123\"', '$.bigint()')" +== 336 +-- truncate_limit: 100 +select jsonb_path_query('1.23', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.23', '$.bigint()')" +== 337 +-- truncate_limit: 100 +select jsonb_path_query('1.83', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.83', '$.bigint()')" +== 338 +-- truncate_limit: 100 +select jsonb_path_query('1234567890123', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234567890123', '$.bigint()')" +== 339 +-- truncate_limit: 100 +select jsonb_path_query('"1234567890123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1234567890123\"', '$.bigint()')" +== 340 +-- truncate_limit: 100 +select jsonb_path_query('12345678901234567890', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345678901234567890', '$.bigint()')" +== 341 +-- truncate_limit: 100 +select jsonb_path_query('"12345678901234567890"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12345678901234567890\"', '$.bigint()')" +== 342 +-- truncate_limit: 100 +select jsonb_path_query('"+123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"+123\"', '$.bigint()')" +== 343 +-- truncate_limit: 100 +select jsonb_path_query('-123', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('-123', '$.bigint()')" +== 344 +-- truncate_limit: 100 +select jsonb_path_query('"-123"', '$.bigint()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-123\"', '$.bigint()')" +== 345 +-- truncate_limit: 100 +select jsonb_path_query('123', '$.bigint() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('123', '$.bigint() * 2')" +== 346 +-- truncate_limit: 100 +-- Test .boolean() +select jsonb_path_query('null', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.boolean()')" +== 347 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.boolean()', silent := true)" +== 348 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.boolean()')" +== 349 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.boolean()')" +== 350 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.boolean()')" +== 351 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.boolean()', silent := true)" +== 352 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.boolean()', silent := true)" +== 353 +-- truncate_limit: 100 +select jsonb_path_query('1.23', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.23', '$.boolean()')" +== 354 +-- truncate_limit: 100 +select jsonb_path_query('"1.23"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23\"', '$.boolean()')" +== 355 +-- truncate_limit: 100 +select jsonb_path_query('"1.23aaa"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23aaa\"', '$.boolean()')" +== 356 +-- truncate_limit: 100 +select jsonb_path_query('1e1000', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1e1000', '$.boolean()')" +== 357 +-- truncate_limit: 100 +select jsonb_path_query('"nan"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"nan\"', '$.boolean()')" +== 358 +-- truncate_limit: 100 +select jsonb_path_query('"NaN"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"NaN\"', '$.boolean()')" +== 359 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.boolean()')" +== 360 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.boolean()')" +== 361 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.boolean()', silent := true)" +== 362 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.boolean()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.boolean()', silent := true)" +== 363 +-- truncate_limit: 100 +select jsonb_path_query('"100"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"100\"', '$.boolean()')" +== 364 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.boolean()')" +== 365 +-- truncate_limit: 100 +select jsonb_path_query('false', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('false', '$.boolean()')" +== 366 +-- truncate_limit: 100 +select jsonb_path_query('1', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$.boolean()')" +== 367 +-- truncate_limit: 100 +select jsonb_path_query('0', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('0', '$.boolean()')" +== 368 +-- truncate_limit: 100 +select jsonb_path_query('-1', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('-1', '$.boolean()')" +== 369 +-- truncate_limit: 100 +select jsonb_path_query('100', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('100', '$.boolean()')" +== 370 +-- truncate_limit: 100 +select jsonb_path_query('"1"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1\"', '$.boolean()')" +== 371 +-- truncate_limit: 100 +select jsonb_path_query('"0"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"0\"', '$.boolean()')" +== 372 +-- truncate_limit: 100 +select jsonb_path_query('"true"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"true\"', '$.boolean()')" +== 373 +-- truncate_limit: 100 +select jsonb_path_query('"false"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"false\"', '$.boolean()')" +== 374 +-- truncate_limit: 100 +select jsonb_path_query('"TRUE"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"TRUE\"', '$.boolean()')" +== 375 +-- truncate_limit: 100 +select jsonb_path_query('"FALSE"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"FALSE\"', '$.boolean()')" +== 376 +-- truncate_limit: 100 +select jsonb_path_query('"yes"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"yes\"', '$.boolean()')" +== 377 +-- truncate_limit: 100 +select jsonb_path_query('"NO"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"NO\"', '$.boolean()')" +== 378 +-- truncate_limit: 100 +select jsonb_path_query('"T"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"T\"', '$.boolean()')" +== 379 +-- truncate_limit: 100 +select jsonb_path_query('"f"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"f\"', '$.boolean()')" +== 380 +-- truncate_limit: 100 +select jsonb_path_query('"y"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"y\"', '$.boolean()')" +== 381 +-- truncate_limit: 100 +select jsonb_path_query('"N"', '$.boolean()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"N\"', '$.boolean()')" +== 382 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.boolean().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.boolean().type()')" +== 383 +-- truncate_limit: 100 +select jsonb_path_query('123', '$.boolean().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('123', '$.boolean().type()')" +== 384 +-- truncate_limit: 100 +select jsonb_path_query('"Yes"', '$.boolean().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"Yes\"', '$.boolean().type()')" +== 385 +-- truncate_limit: 100 +select jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_array('[1, \"yes\", false]', '$[*].boolean()')" +== 386 +-- truncate_limit: 100 +-- Test .date() +select jsonb_path_query('null', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.date()')" +== 387 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.date()')" +== 388 +-- truncate_limit: 100 +select jsonb_path_query('1', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$.date()')" +== 389 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.date()')" +== 390 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.date()')" +== 391 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.date()')" +== 392 +-- truncate_limit: 100 +select jsonb_path_query('"bogus"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"bogus\"', '$.date()')" +== 393 +-- truncate_limit: 100 +select jsonb '"2023-08-15"' @? '$.date()' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"2023-08-15\"'::jsonb @? '$.date()'" +== 394 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.date()')" +== 395 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15"', '$.date().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.date().type()')" +== 396 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.date()')" +== 397 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +05:30"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +05:30\"', '$.date()')" +== 398 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.date()')" +== 399 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.date()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.date()')" +== 400 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.date()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +05:30\"', '$.date()')" +== 401 +-- truncate_limit: 100 +-- should work + +select jsonb_path_query('"2023-08-15"', '$.date(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.date(2)')" +== 402 +-- truncate_limit: 100 +-- Test .decimal() +select jsonb_path_query('null', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.decimal()')" +== 403 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.decimal()')" +== 404 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.decimal()', silent := true)" +== 405 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.decimal()', silent := true)" +== 406 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.decimal()')" +== 407 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.decimal()')" +== 408 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.decimal()')" +== 409 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.decimal()', silent := true)" +== 410 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.decimal()', silent := true)" +== 411 +-- truncate_limit: 100 +select jsonb_path_query('1.23', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.23', '$.decimal()')" +== 412 +-- truncate_limit: 100 +select jsonb_path_query('"1.23"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23\"', '$.decimal()')" +== 413 +-- truncate_limit: 100 +select jsonb_path_query('"1.23aaa"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23aaa\"', '$.decimal()')" +== 414 +-- truncate_limit: 100 +select jsonb_path_query('1e1000', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1e1000', '$.decimal()')" +== 415 +-- truncate_limit: 100 +select jsonb_path_query('"nan"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"nan\"', '$.decimal()')" +== 416 +-- truncate_limit: 100 +select jsonb_path_query('"NaN"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"NaN\"', '$.decimal()')" +== 417 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.decimal()')" +== 418 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.decimal()')" +== 419 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.decimal()', silent := true)" +== 420 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.decimal()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.decimal()', silent := true)" +== 421 +-- truncate_limit: 100 +select jsonb_path_query('123', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('123', '$.decimal()')" +== 422 +-- truncate_limit: 100 +select jsonb_path_query('"123"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"123\"', '$.decimal()')" +== 423 +-- truncate_limit: 100 +select jsonb_path_query('12345678901234567890', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345678901234567890', '$.decimal()')" +== 424 +-- truncate_limit: 100 +select jsonb_path_query('"12345678901234567890"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12345678901234567890\"', '$.decimal()')" +== 425 +-- truncate_limit: 100 +select jsonb_path_query('"+12.3"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"+12.3\"', '$.decimal()')" +== 426 +-- truncate_limit: 100 +select jsonb_path_query('-12.3', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('-12.3', '$.decimal()')" +== 427 +-- truncate_limit: 100 +select jsonb_path_query('"-12.3"', '$.decimal()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-12.3\"', '$.decimal()')" +== 428 +-- truncate_limit: 100 +select jsonb_path_query('12.3', '$.decimal() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12.3', '$.decimal() * 2')" +== 429 +-- truncate_limit: 100 +select jsonb_path_query('12345.678', '$.decimal(6, 1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345.678', '$.decimal(6, 1)')" +== 430 +-- truncate_limit: 100 +select jsonb_path_query('12345.678', '$.decimal(6, 2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345.678', '$.decimal(6, 2)')" +== 431 +-- truncate_limit: 100 +select jsonb_path_query('1234.5678', '$.decimal(6, 2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234.5678', '$.decimal(6, 2)')" +== 432 +-- truncate_limit: 100 +select jsonb_path_query('12345.678', '$.decimal(4, 6)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345.678', '$.decimal(4, 6)')" +== 433 +-- truncate_limit: 100 +select jsonb_path_query('12345.678', '$.decimal(0, 6)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345.678', '$.decimal(0, 6)')" +== 434 +-- truncate_limit: 100 +select jsonb_path_query('12345.678', '$.decimal(1001, 6)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345.678', '$.decimal(1001, 6)')" +== 435 +-- truncate_limit: 100 +select jsonb_path_query('1234.5678', '$.decimal(+6, +2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234.5678', '$.decimal(+6, +2)')" +== 436 +-- truncate_limit: 100 +select jsonb_path_query('1234.5678', '$.decimal(+6, -2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234.5678', '$.decimal(+6, -2)')" +== 437 +-- truncate_limit: 100 +select jsonb_path_query('1234.5678', '$.decimal(-6, +2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234.5678', '$.decimal(-6, +2)')" +== 438 +-- truncate_limit: 100 +select jsonb_path_query('1234.5678', '$.decimal(6, -1001)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234.5678', '$.decimal(6, -1001)')" +== 439 +-- truncate_limit: 100 +select jsonb_path_query('1234.5678', '$.decimal(6, 1001)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234.5678', '$.decimal(6, 1001)')" +== 440 +-- truncate_limit: 100 +select jsonb_path_query('-1234.5678', '$.decimal(+6, -2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('-1234.5678', '$.decimal(+6, -2)')" +== 441 +-- truncate_limit: 100 +select jsonb_path_query('0.0123456', '$.decimal(1,2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('0.0123456', '$.decimal(1,2)')" +== 442 +-- truncate_limit: 100 +select jsonb_path_query('0.0012345', '$.decimal(2,4)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('0.0012345', '$.decimal(2,4)')" +== 443 +-- truncate_limit: 100 +select jsonb_path_query('-0.00123456', '$.decimal(2,-4)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('-0.00123456', '$.decimal(2,-4)')" +== 444 +-- truncate_limit: 100 +select jsonb_path_query('12.3', '$.decimal(12345678901,1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12.3', '$.decimal(12345678901,1)')" +== 445 +-- truncate_limit: 100 +select jsonb_path_query('12.3', '$.decimal(1,12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12.3', '$.decimal(1,12345678901)')" +== 446 +-- truncate_limit: 100 +-- Test .integer() +select jsonb_path_query('null', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.integer()')" +== 447 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.integer()')" +== 448 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.integer()', silent := true)" +== 449 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.integer()', silent := true)" +== 450 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.integer()')" +== 451 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.integer()')" +== 452 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.integer()')" +== 453 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.integer()', silent := true)" +== 454 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.integer()', silent := true)" +== 455 +-- truncate_limit: 100 +select jsonb_path_query('"1.23"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23\"', '$.integer()')" +== 456 +-- truncate_limit: 100 +select jsonb_path_query('"1.23aaa"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23aaa\"', '$.integer()')" +== 457 +-- truncate_limit: 100 +select jsonb_path_query('1e1000', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1e1000', '$.integer()')" +== 458 +-- truncate_limit: 100 +select jsonb_path_query('"nan"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"nan\"', '$.integer()')" +== 459 +-- truncate_limit: 100 +select jsonb_path_query('"NaN"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"NaN\"', '$.integer()')" +== 460 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.integer()')" +== 461 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.integer()')" +== 462 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.integer()', silent := true)" +== 463 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.integer()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.integer()', silent := true)" +== 464 +-- truncate_limit: 100 +select jsonb_path_query('123', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('123', '$.integer()')" +== 465 +-- truncate_limit: 100 +select jsonb_path_query('"123"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"123\"', '$.integer()')" +== 466 +-- truncate_limit: 100 +select jsonb_path_query('1.23', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.23', '$.integer()')" +== 467 +-- truncate_limit: 100 +select jsonb_path_query('1.83', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.83', '$.integer()')" +== 468 +-- truncate_limit: 100 +select jsonb_path_query('12345678901', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345678901', '$.integer()')" +== 469 +-- truncate_limit: 100 +select jsonb_path_query('"12345678901"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12345678901\"', '$.integer()')" +== 470 +-- truncate_limit: 100 +select jsonb_path_query('"+123"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"+123\"', '$.integer()')" +== 471 +-- truncate_limit: 100 +select jsonb_path_query('-123', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('-123', '$.integer()')" +== 472 +-- truncate_limit: 100 +select jsonb_path_query('"-123"', '$.integer()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-123\"', '$.integer()')" +== 473 +-- truncate_limit: 100 +select jsonb_path_query('123', '$.integer() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('123', '$.integer() * 2')" +== 474 +-- truncate_limit: 100 +-- Test .number() +select jsonb_path_query('null', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.number()')" +== 475 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.number()')" +== 476 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.number()', silent := true)" +== 477 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.number()', silent := true)" +== 478 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.number()')" +== 479 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.number()')" +== 480 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.number()')" +== 481 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.number()', silent := true)" +== 482 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.number()', silent := true)" +== 483 +-- truncate_limit: 100 +select jsonb_path_query('1.23', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.23', '$.number()')" +== 484 +-- truncate_limit: 100 +select jsonb_path_query('"1.23"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23\"', '$.number()')" +== 485 +-- truncate_limit: 100 +select jsonb_path_query('"1.23aaa"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23aaa\"', '$.number()')" +== 486 +-- truncate_limit: 100 +select jsonb_path_query('1e1000', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1e1000', '$.number()')" +== 487 +-- truncate_limit: 100 +select jsonb_path_query('"nan"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"nan\"', '$.number()')" +== 488 +-- truncate_limit: 100 +select jsonb_path_query('"NaN"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"NaN\"', '$.number()')" +== 489 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.number()')" +== 490 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.number()')" +== 491 +-- truncate_limit: 100 +select jsonb_path_query('"inf"', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"inf\"', '$.number()', silent := true)" +== 492 +-- truncate_limit: 100 +select jsonb_path_query('"-inf"', '$.number()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-inf\"', '$.number()', silent := true)" +== 493 +-- truncate_limit: 100 +select jsonb_path_query('123', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('123', '$.number()')" +== 494 +-- truncate_limit: 100 +select jsonb_path_query('"123"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"123\"', '$.number()')" +== 495 +-- truncate_limit: 100 +select jsonb_path_query('12345678901234567890', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12345678901234567890', '$.number()')" +== 496 +-- truncate_limit: 100 +select jsonb_path_query('"12345678901234567890"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12345678901234567890\"', '$.number()')" +== 497 +-- truncate_limit: 100 +select jsonb_path_query('"+12.3"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"+12.3\"', '$.number()')" +== 498 +-- truncate_limit: 100 +select jsonb_path_query('-12.3', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('-12.3', '$.number()')" +== 499 +-- truncate_limit: 100 +select jsonb_path_query('"-12.3"', '$.number()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"-12.3\"', '$.number()')" +== 500 +-- truncate_limit: 100 +select jsonb_path_query('12.3', '$.number() * 2') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('12.3', '$.number() * 2')" +== 501 +-- truncate_limit: 100 +-- Test .string() +select jsonb_path_query('null', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.string()')" +== 502 +-- truncate_limit: 100 +select jsonb_path_query('null', '$.string()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.string()', silent := true)" +== 503 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.string()')" +== 504 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.string()')" +== 505 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.string()')" +== 506 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.string()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.string()', silent := true)" +== 507 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.string()', silent => true) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.string()', silent := true)" +== 508 +-- truncate_limit: 100 +select jsonb_path_query('1.23', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1.23', '$.string()')" +== 509 +-- truncate_limit: 100 +select jsonb_path_query('"1.23"', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23\"', '$.string()')" +== 510 +-- truncate_limit: 100 +select jsonb_path_query('"1.23aaa"', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"1.23aaa\"', '$.string()')" +== 511 +-- truncate_limit: 100 +select jsonb_path_query('1234', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234', '$.string()')" +== 512 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.string()')" +== 513 +-- truncate_limit: 100 +select jsonb_path_query('1234', '$.string().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1234', '$.string().type()')" +== 514 +-- truncate_limit: 100 +select jsonb_path_query('[2, true]', '$.string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[2, true]', '$.string()')" +== 515 +-- truncate_limit: 100 +select jsonb_path_query_array('[1.23, "yes", false]', '$[*].string()') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_array('[1.23, \"yes\", false]', '$[*].string()')" +== 516 +-- truncate_limit: 100 +select jsonb_path_query_array('[1.23, "yes", false]', '$[*].string().type()') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_array('[1.23, \"yes\", false]', '$[*].string().type()')" +== 517 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +5:30\"', '$.timestamp().string()')" +== 518 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +5:30\"', '$.timestamp().string()')" +== 519 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.timestamp_tz().string()')" +== 520 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56\"', '$.timestamp_tz().string()')" +== 521 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +5:30\"', '$.timestamp_tz().string()')" +== 522 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.timestamp().string()')" +== 523 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +5:30\"', '$.time_tz().string()')" +== 524 +-- truncate_limit: 100 +-- this timetz usage will absorb the UTC offset of the current timezone setting +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 525 +-- truncate_limit: 100 +set local timezone = 'UTC-10' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO \"UTC-10\"" +== 526 +-- truncate_limit: 100 +select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"12:34:56\"', '$.time_tz().string()')" +== 527 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 528 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.time().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.time().string()')" +== 529 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15"', '$.date().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.date().string()')" +== 530 +-- truncate_limit: 100 +-- .string() does not react to timezone or datestyle +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 531 +-- truncate_limit: 100 +set local timezone = 'UTC' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO \"UTC\"" +== 532 +-- truncate_limit: 100 +set local datestyle = 'German' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL datestyle TO \"German\"" +== 533 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +5:30\"', '$.timestamp_tz().string()')" +== 534 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.timestamp().string()')" +== 535 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 536 +-- truncate_limit: 100 +-- Test .time() +select jsonb_path_query('null', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.time()')" +== 537 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.time()')" +== 538 +-- truncate_limit: 100 +select jsonb_path_query('1', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$.time()')" +== 539 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.time()')" +== 540 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.time()')" +== 541 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.time()')" +== 542 +-- truncate_limit: 100 +select jsonb_path_query('"bogus"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"bogus\"', '$.time()')" +== 543 +-- truncate_limit: 100 +select jsonb '"12:34:56"' @? '$.time()' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"12:34:56\"'::jsonb @? '$.time()'" +== 544 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.time()')" +== 545 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.time().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.time().type()')" +== 546 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.time()')" +== 547 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +05:30\"', '$.time()')" +== 548 +-- truncate_limit: 100 +select jsonb_path_query_tz('"12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"12:34:56 +05:30\"', '$.time()')" +== 549 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.time()')" +== 550 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789"', '$.time(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789\"', '$.time(-1)')" +== 551 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789"', '$.time(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789\"', '$.time(2.0)')" +== 552 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789"', '$.time(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789\"', '$.time(12345678901)')" +== 553 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789"', '$.time(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789\"', '$.time(0)')" +== 554 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789"', '$.time(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789\"', '$.time(2)')" +== 555 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789"', '$.time(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789\"', '$.time(5)')" +== 556 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789"', '$.time(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789\"', '$.time(10)')" +== 557 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789012"', '$.time(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789012\"', '$.time(8)')" +== 558 +-- truncate_limit: 100 +-- Test .time_tz() +select jsonb_path_query('null', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.time_tz()')" +== 559 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.time_tz()')" +== 560 +-- truncate_limit: 100 +select jsonb_path_query('1', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$.time_tz()')" +== 561 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.time_tz()')" +== 562 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.time_tz()')" +== 563 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.time_tz()')" +== 564 +-- truncate_limit: 100 +select jsonb_path_query('"bogus"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"bogus\"', '$.time_tz()')" +== 565 +-- truncate_limit: 100 +select jsonb '"12:34:56 +05:30"' @? '$.time_tz()' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"12:34:56 +05:30\"'::jsonb @? '$.time_tz()'" +== 566 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +05:30\"', '$.time_tz()')" +== 567 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +05:30"', '$.time_tz().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +05:30\"', '$.time_tz().type()')" +== 568 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.time_tz()')" +== 569 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.time_tz()')" +== 570 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789 +05:30\"', '$.time_tz(-1)')" +== 571 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789 +05:30\"', '$.time_tz(2.0)')" +== 572 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789 +05:30\"', '$.time_tz(12345678901)')" +== 573 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789 +05:30\"', '$.time_tz(0)')" +== 574 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789 +05:30\"', '$.time_tz(2)')" +== 575 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789 +05:30\"', '$.time_tz(5)')" +== 576 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789 +05:30\"', '$.time_tz(10)')" +== 577 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56.789012 +05:30"', '$.time_tz(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56.789012 +05:30\"', '$.time_tz(8)')" +== 578 +-- truncate_limit: 100 +-- Test .timestamp() +select jsonb_path_query('null', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.timestamp()')" +== 579 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.timestamp()')" +== 580 +-- truncate_limit: 100 +select jsonb_path_query('1', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$.timestamp()')" +== 581 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.timestamp()')" +== 582 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.timestamp()')" +== 583 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.timestamp()')" +== 584 +-- truncate_limit: 100 +select jsonb_path_query('"bogus"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"bogus\"', '$.timestamp()')" +== 585 +-- truncate_limit: 100 +select jsonb '"2023-08-15 12:34:56"' @? '$.timestamp()' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"2023-08-15 12:34:56\"'::jsonb @? '$.timestamp()'" +== 586 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.timestamp()')" +== 587 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.timestamp().type()')" +== 588 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.timestamp()')" +== 589 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.timestamp()')" +== 590 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +05:30\"', '$.timestamp()')" +== 591 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789\"', '$.timestamp(-1)')" +== 592 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789\"', '$.timestamp(2.0)')" +== 593 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789\"', '$.timestamp(12345678901)')" +== 594 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789\"', '$.timestamp(0)')" +== 595 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789\"', '$.timestamp(2)')" +== 596 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789\"', '$.timestamp(5)')" +== 597 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789\"', '$.timestamp(10)')" +== 598 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789012"', '$.timestamp(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789012\"', '$.timestamp(8)')" +== 599 +-- truncate_limit: 100 +-- Test .timestamp_tz() +select jsonb_path_query('null', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('null', '$.timestamp_tz()')" +== 600 +-- truncate_limit: 100 +select jsonb_path_query('true', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('true', '$.timestamp_tz()')" +== 601 +-- truncate_limit: 100 +select jsonb_path_query('1', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('1', '$.timestamp_tz()')" +== 602 +-- truncate_limit: 100 +select jsonb_path_query('[]', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', '$.timestamp_tz()')" +== 603 +-- truncate_limit: 100 +select jsonb_path_query('[]', 'strict $.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[]', 'strict $.timestamp_tz()')" +== 604 +-- truncate_limit: 100 +select jsonb_path_query('{}', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('{}', '$.timestamp_tz()')" +== 605 +-- truncate_limit: 100 +select jsonb_path_query('"bogus"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"bogus\"', '$.timestamp_tz()')" +== 606 +-- truncate_limit: 100 +select jsonb '"2023-08-15 12:34:56 +05:30"' @? '$.timestamp_tz()' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"2023-08-15 12:34:56 +05:30\"'::jsonb @? '$.timestamp_tz()'" +== 607 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp_tz()')" +== 608 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp_tz().type()')" +== 609 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15\"', '$.timestamp_tz()')" +== 610 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15\"', '$.timestamp_tz()')" +== 611 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.timestamp_tz()')" +== 612 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56 +05:30\"', '$.timestamp_tz()')" +== 613 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(-1)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789 +05:30\"', '$.timestamp_tz(-1)')" +== 614 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2.0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789 +05:30\"', '$.timestamp_tz(2.0)')" +== 615 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(12345678901)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789 +05:30\"', '$.timestamp_tz(12345678901)')" +== 616 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(0)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789 +05:30\"', '$.timestamp_tz(0)')" +== 617 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789 +05:30\"', '$.timestamp_tz(2)')" +== 618 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(5)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789 +05:30\"', '$.timestamp_tz(5)')" +== 619 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789 +05:30\"', '$.timestamp_tz(10)')" +== 620 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56.789012 +05:30"', '$.timestamp_tz(8)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56.789012 +05:30\"', '$.timestamp_tz(8)')" +== 621 +-- truncate_limit: 100 +set time zone '+00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"+00\"" +== 622 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.time()')" +== 623 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +05:30\"', '$.time()')" +== 624 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.time_tz()')" +== 625 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.time_tz()')" +== 626 +-- truncate_limit: 100 +select jsonb_path_query_tz('"12:34:56"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"12:34:56\"', '$.time_tz()')" +== 627 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp()')" +== 628 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp()')" +== 629 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.timestamp_tz()')" +== 630 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56\"', '$.timestamp_tz()')" +== 631 +-- truncate_limit: 100 +-- should work + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34\"', '$.datetime(\"dd-mm-yyyy HH24:MI\")')" +== 632 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH\")')" +== 633 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 +05\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH\")')" +== 634 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 -05\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH\")')" +== 635 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 +05:20\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH:TZM\")')" +== 636 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 -05:20\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH:TZM\")')" +== 637 +-- truncate_limit: 100 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34\"', '$.datetime(\"HH24:MI\")')" +== 638 +-- truncate_limit: 100 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34\"', '$.datetime(\"HH24:MI TZH\")')" +== 639 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 +05\"', '$.datetime(\"HH24:MI TZH\")')" +== 640 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 -05\"', '$.datetime(\"HH24:MI TZH\")')" +== 641 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 +05:20\"', '$.datetime(\"HH24:MI TZH:TZM\")')" +== 642 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 -05:20\"', '$.datetime(\"HH24:MI TZH:TZM\")')" +== 643 +-- truncate_limit: 100 +set time zone '+10' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"+10\"" +== 644 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.time()')" +== 645 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +05:30\"', '$.time()')" +== 646 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.time_tz()')" +== 647 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp()')" +== 648 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp()')" +== 649 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56\"', '$.timestamp_tz()')" +== 650 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56\"', '$.timestamp_tz()')" +== 651 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp_tz()')" +== 652 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34\"', '$.datetime(\"dd-mm-yyyy HH24:MI\")')" +== 653 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH\")')" +== 654 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 +05\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH\")')" +== 655 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 -05\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH\")')" +== 656 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 +05:20\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH:TZM\")')" +== 657 +-- truncate_limit: 100 +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"10-03-2017 12:34 -05:20\"', '$.datetime(\"dd-mm-yyyy HH24:MI TZH:TZM\")')" +== 658 +-- truncate_limit: 100 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34\"', '$.datetime(\"HH24:MI\")')" +== 659 +-- truncate_limit: 100 +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34\"', '$.datetime(\"HH24:MI TZH\")')" +== 660 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 +05\"', '$.datetime(\"HH24:MI TZH\")')" +== 661 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 -05\"', '$.datetime(\"HH24:MI TZH\")')" +== 662 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 +05:20\"', '$.datetime(\"HH24:MI TZH:TZM\")')" +== 663 +-- truncate_limit: 100 +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34 -05:20\"', '$.datetime(\"HH24:MI TZH:TZM\")')" +== 664 +-- truncate_limit: 100 +set time zone default +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO DEFAULT" +== 665 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.time()')" +== 666 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +05:30\"', '$.time()')" +== 667 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.time_tz()')" +== 668 +-- truncate_limit: 100 +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp()')" +== 669 +-- truncate_limit: 100 +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_tz('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp()')" +== 670 +-- truncate_limit: 100 +-- should work +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2023-08-15 12:34:56 +05:30\"', '$.timestamp_tz()')" +== 671 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10\"', '$.datetime().type()')" +== 672 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10\"', '$.datetime()')" +== 673 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10 12:34:56\"', '$.datetime().type()')" +== 674 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10 12:34:56\"', '$.datetime()')" +== 675 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10 12:34:56+3\"', '$.datetime().type()')" +== 676 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10 12:34:56+3\"', '$.datetime()')" +== 677 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10 12:34:56+3:10\"', '$.datetime().type()')" +== 678 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10 12:34:56+3:10\"', '$.datetime()')" +== 679 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10T12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10T12:34:56+3:10\"', '$.datetime()')" +== 680 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10t12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10t12:34:56+3:10\"', '$.datetime()')" +== 681 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10 12:34:56.789+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10 12:34:56.789+3:10\"', '$.datetime()')" +== 682 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10T12:34:56.789+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10T12:34:56.789+3:10\"', '$.datetime()')" +== 683 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10t12:34:56.789+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10t12:34:56.789+3:10\"', '$.datetime()')" +== 684 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10T12:34:56.789EST"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10T12:34:56.789EST\"', '$.datetime()')" +== 685 +-- truncate_limit: 100 +select jsonb_path_query('"2017-03-10T12:34:56.789Z"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"2017-03-10T12:34:56.789Z\"', '$.datetime()')" +== 686 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.datetime().type()')" +== 687 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56\"', '$.datetime()')" +== 688 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56+3"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56+3\"', '$.datetime().type()')" +== 689 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56+3"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56+3\"', '$.datetime()')" +== 690 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56+3:10"', '$.datetime().type()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56+3:10\"', '$.datetime().type()')" +== 691 +-- truncate_limit: 100 +select jsonb_path_query('"12:34:56+3:10"', '$.datetime()') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('\"12:34:56+3:10\"', '$.datetime()')" +== 692 +-- truncate_limit: 100 +set time zone '+00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"+00\"" +== 693 +-- truncate_limit: 100 +-- date comparison +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 694 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 695 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 696 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 697 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 698 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 699 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 700 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 701 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 702 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ == "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 703 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ >= "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 704 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ < "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 705 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ == "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 706 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ >= "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 707 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ < "2017-03-10".date())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 708 +-- truncate_limit: 100 +-- time comparison +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 709 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 710 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 711 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 712 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 713 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 714 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 715 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 716 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 717 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ == "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 718 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ >= "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 719 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ < "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 720 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00.123", "12:35:00.123", "12:36:00.1123", "12:35:00.1123+00", "12:35:00.123+01", "13:35:00.123+01", "2017-03-10 12:35:00.1", "2017-03-10 12:35:00.123+01"]', + '$[*].time(2) ? (@ >= "12:35:00.123".time(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 721 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ == "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 722 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ >= "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 723 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ < "12:35:00".time())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 724 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00.123", "12:35:00.123", "12:36:00.1123", "12:35:00.1123+00", "12:35:00.123+01", "13:35:00.123+01", "2017-03-10 12:35:00.1", "2017-03-10 12:35:00.123+01"]', + '$[*].time(2) ? (@ >= "12:35:00.123".time(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 725 +-- truncate_limit: 100 +-- timetz comparison +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 726 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 727 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 728 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 729 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 730 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 731 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 732 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 733 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 734 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ == "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 735 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ >= "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 736 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ < "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 737 +-- truncate_limit: 100 +select jsonb_path_query( + '["12:34:00.123+01", "12:35:00.123+01", "12:36:00.1123+01", "12:35:00.1123+02", "12:35:00.123-02", "10:35:00.123", "11:35:00.1", "12:35:00.123", "2017-03-10 12:35:00.123 +1"]', + '$[*].time_tz(2) ? (@ >= "12:35:00.123 +1".time_tz(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 738 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ == "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 739 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ >= "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 740 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ < "12:35:00 +1".time_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 741 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["12:34:00.123+01", "12:35:00.123+01", "12:36:00.1123+01", "12:35:00.1123+02", "12:35:00.123-02", "10:35:00.123", "11:35:00.1", "12:35:00.123", "2017-03-10 12:35:00.123 +1"]', + '$[*].time_tz(2) ? (@ >= "12:35:00.123 +1".time_tz(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 742 +-- truncate_limit: 100 +-- timestamp comparison +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 743 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 744 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 745 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 746 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 747 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 748 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ == "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 749 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ >= "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 750 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ < "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 751 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ == "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 752 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ >= "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 753 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ < "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 754 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00.123", "2017-03-10 12:35:00.123", "2017-03-10 12:36:00.1123", "2017-03-10 12:35:00.1123+01", "2017-03-10 13:35:00.123+01", "2017-03-10 12:35:00.1-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp(2) ? (@ >= "2017-03-10 12:35:00.123".timestamp(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 755 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ == "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 756 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ >= "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 757 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ < "2017-03-10 12:35:00".timestamp())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 758 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00.123", "2017-03-10 12:35:00.123", "2017-03-10 12:36:00.1123", "2017-03-10 12:35:00.1123+01", "2017-03-10 13:35:00.123+01", "2017-03-10 12:35:00.1-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp(2) ? (@ >= "2017-03-10 12:35:00.123".timestamp(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 759 +-- truncate_limit: 100 +-- timestamptz comparison +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 760 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 761 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 762 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 763 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 764 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 765 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 766 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 767 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 768 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 769 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 770 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 771 +-- truncate_limit: 100 +select jsonb_path_query( + '["2017-03-10 12:34:00.123+01", "2017-03-10 12:35:00.123+01", "2017-03-10 12:36:00.1123+01", "2017-03-10 12:35:00.1123+02", "2017-03-10 12:35:00.123-02", "2017-03-10 10:35:00.123", "2017-03-10 11:35:00.1", "2017-03-10 12:35:00.123", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz(2) ? (@ >= "2017-03-10 12:35:00.123 +1".timestamp_tz(2))') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 772 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 773 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 774 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 775 +-- truncate_limit: 100 +select jsonb_path_query_tz( + '["2017-03-10 12:34:00.123+01", "2017-03-10 12:35:00.123+01", "2017-03-10 12:36:00.1123+01", "2017-03-10 12:35:00.1123+02", "2017-03-10 12:35:00.123-02", "2017-03-10 10:35:00.123", "2017-03-10 11:35:00.1", "2017-03-10 12:35:00.123", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz(2) ? (@ >= "2017-03-10 12:35:00.123 +1".timestamp_tz(2))') +-- +FUNCTION: name="jsonb_path_query_tz" function="jsonb_path_query_tz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 776 +-- truncate_limit: 100 +-- overflow during comparison +select jsonb_path_query('"1000000-01-01"', '$.datetime() > "2020-01-01 12:00:00".datetime()'::jsonpath) +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 777 +-- truncate_limit: 100 +set time zone default +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO DEFAULT" +== 778 +-- truncate_limit: 100 +-- jsonpath operators + +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1}, {\"a\": 2}]', '$[*]')" +== 779 +-- truncate_limit: 100 +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1}, {\"a\": 2}]', '$[*] ? (@.a > 10)')" +== 780 +-- truncate_limit: 100 +SELECT jsonb_path_query('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1}]', '$undefined_var')" +== 781 +-- truncate_limit: 100 +SELECT jsonb_path_query('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_query" function="jsonb_path_query" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query('[{\"a\": 1}]', 'false')" +== 782 +-- truncate_limit: 100 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_array('[{\"a\": 1}, {\"a\": 2}, {}]', 'strict $[*].a')" +== 783 +-- truncate_limit: 100 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_array('[{\"a\": 1}, {\"a\": 2}]', '$[*].a')" +== 784 +-- truncate_limit: 100 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_array('[{\"a\": 1}, {\"a\": 2}]', '$[*].a ? (@ == 1)')" +== 785 +-- truncate_limit: 100 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_array('[{\"a\": 1}, {\"a\": 2}]', '$[*].a ? (@ > 10)')" +== 786 +-- truncate_limit: 100 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 787 +-- truncate_limit: 100 +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 788 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_first('[{\"a\": 1}, {\"a\": 2}, {}]', 'strict $[*].a')" +== 789 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a', silent => true) +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_first('[{\"a\": 1}, {\"a\": 2}, {}]', 'strict $[*].a', silent := true)" +== 790 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_first('[{\"a\": 1}, {\"a\": 2}]', '$[*].a')" +== 791 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_first('[{\"a\": 1}, {\"a\": 2}]', '$[*].a ? (@ == 1)')" +== 792 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_first('[{\"a\": 1}, {\"a\": 2}]', '$[*].a ? (@ > 10)')" +== 793 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 794 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 795 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_first('[{\"a\": 1}]', '$undefined_var')" +== 796 +-- truncate_limit: 100 +SELECT jsonb_path_query_first('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_query_first('[{\"a\": 1}]', 'false')" +== 797 +-- truncate_limit: 100 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"a\": 1}, {\"a\": 2}]'::jsonb @? '$[*].a ? (@ > 1)'" +== 798 +-- truncate_limit: 100 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*] ? (@.a > 2)' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"a\": 1}, {\"a\": 2}]'::jsonb @? '$[*] ? (@.a > 2)'" +== 799 +-- truncate_limit: 100 +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 1)') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_exists('[{\"a\": 1}, {\"a\": 2}]', '$[*].a ? (@ > 1)')" +== 800 +-- truncate_limit: 100 +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 1, "max": 4}') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 801 +-- truncate_limit: 100 +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 3, "max": 4}') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 802 +-- truncate_limit: 100 +SELECT jsonb_path_exists('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_exists('[{\"a\": 1}]', '$undefined_var')" +== 803 +-- truncate_limit: 100 +SELECT jsonb_path_exists('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_exists" function="jsonb_path_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_exists('[{\"a\": 1}]', 'false')" +== 804 +-- truncate_limit: 100 +SELECT jsonb_path_match('true', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('true', '$', silent := false)" +== 805 +-- truncate_limit: 100 +SELECT jsonb_path_match('false', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('false', '$', silent := false)" +== 806 +-- truncate_limit: 100 +SELECT jsonb_path_match('null', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('null', '$', silent := false)" +== 807 +-- truncate_limit: 100 +SELECT jsonb_path_match('1', '$', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('1', '$', silent := true)" +== 808 +-- truncate_limit: 100 +SELECT jsonb_path_match('1', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('1', '$', silent := false)" +== 809 +-- truncate_limit: 100 +SELECT jsonb_path_match('"a"', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('\"a\"', '$', silent := false)" +== 810 +-- truncate_limit: 100 +SELECT jsonb_path_match('{}', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('{}', '$', silent := false)" +== 811 +-- truncate_limit: 100 +SELECT jsonb_path_match('[true]', '$', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[true]', '$', silent := false)" +== 812 +-- truncate_limit: 100 +SELECT jsonb_path_match('{}', 'lax $.a', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('{}', 'lax $.a', silent := false)" +== 813 +-- truncate_limit: 100 +SELECT jsonb_path_match('{}', 'strict $.a', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('{}', 'strict $.a', silent := false)" +== 814 +-- truncate_limit: 100 +SELECT jsonb_path_match('{}', 'strict $.a', silent => true) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('{}', 'strict $.a', silent := true)" +== 815 +-- truncate_limit: 100 +SELECT jsonb_path_match('[true, true]', '$[*]', silent => false) +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[true, true]', '$[*]', silent := false)" +== 816 +-- truncate_limit: 100 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"a\": 1}, {\"a\": 2}]'::jsonb @@ '$[*].a > 1'" +== 817 +-- truncate_limit: 100 +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 2' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[{\"a\": 1}, {\"a\": 2}]'::jsonb @@ '$[*].a > 2'" +== 818 +-- truncate_limit: 100 +SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[{\"a\": 1}, {\"a\": 2}]', '$[*].a > 1')" +== 819 +-- truncate_limit: 100 +SELECT jsonb_path_match('[{"a": 1}]', '$undefined_var') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[{\"a\": 1}]', '$undefined_var')" +== 820 +-- truncate_limit: 100 +SELECT jsonb_path_match('[{"a": 1}]', 'false') +-- +FUNCTION: name="jsonb_path_match" function="jsonb_path_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT jsonb_path_match('[{\"a\": 1}]', 'false')" +== 821 +-- truncate_limit: 100 +-- test string comparison (Unicode codepoint collation) +WITH str(j, num) AS +( + SELECT jsonb_build_object('s', s), num + FROM unnest('{"", "a", "ab", "abc", "abcd", "b", "A", "AB", "ABC", "ABc", "ABcD", "B"}'::text[]) WITH ORDINALITY AS a(s, num) +) +SELECT + s1.j, s2.j, + jsonb_path_query_first(s1.j, '$.s < $s', vars => s2.j) lt, + jsonb_path_query_first(s1.j, '$.s <= $s', vars => s2.j) le, + jsonb_path_query_first(s1.j, '$.s == $s', vars => s2.j) eq, + jsonb_path_query_first(s1.j, '$.s >= $s', vars => s2.j) ge, + jsonb_path_query_first(s1.j, '$.s > $s', vars => s2.j) gt +FROM str s1, str s2 +ORDER BY s1.num, s2.num +-- +ALIAS: "s1"="str" +ALIAS: "s2"="str" +CTE: "str" +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_path_query_first" function="jsonb_path_query_first" schema="" ctx=Call +FUNCTION: name="jsonb_build_object" function="jsonb_build_object" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH str(j, num) AS (...) SELECT ... FROM str s1, str s2 ORDER BY s1.num, s2.num" diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json new file mode 100644 index 0000000..402e8ee --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json @@ -0,0 +1,228 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonpath.test b/parser/testdata/summary_truncate/postgres_regress/jsonpath.test new file mode 100644 index 0000000..0ef912a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonpath.test @@ -0,0 +1,1371 @@ +== 001 +-- truncate_limit: 100 +--jsonpath io + +select ''::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::jsonpath" +== 002 +-- truncate_limit: 100 +select '$'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$'::jsonpath" +== 003 +-- truncate_limit: 100 +select 'strict $'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'strict $'::jsonpath" +== 004 +-- truncate_limit: 100 +select 'lax $'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'lax $'::jsonpath" +== 005 +-- truncate_limit: 100 +select '$.a'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a'::jsonpath" +== 006 +-- truncate_limit: 100 +select '$.a.v'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.v'::jsonpath" +== 007 +-- truncate_limit: 100 +select '$.a.*'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.*'::jsonpath" +== 008 +-- truncate_limit: 100 +select '$.*[*]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.*[*]'::jsonpath" +== 009 +-- truncate_limit: 100 +select '$.a[*]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a[*]'::jsonpath" +== 010 +-- truncate_limit: 100 +select '$.a[*][*]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a[*][*]'::jsonpath" +== 011 +-- truncate_limit: 100 +select '$[*]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$[*]'::jsonpath" +== 012 +-- truncate_limit: 100 +select '$[0]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$[0]'::jsonpath" +== 013 +-- truncate_limit: 100 +select '$[*][0]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$[*][0]'::jsonpath" +== 014 +-- truncate_limit: 100 +select '$[*].a'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$[*].a'::jsonpath" +== 015 +-- truncate_limit: 100 +select '$[*][0].a.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$[*][0].a.b'::jsonpath" +== 016 +-- truncate_limit: 100 +select '$.a.**.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**.b'::jsonpath" +== 017 +-- truncate_limit: 100 +select '$.a.**{2}.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**{2}.b'::jsonpath" +== 018 +-- truncate_limit: 100 +select '$.a.**{2 to 2}.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**{2 to 2}.b'::jsonpath" +== 019 +-- truncate_limit: 100 +select '$.a.**{2 to 5}.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**{2 to 5}.b'::jsonpath" +== 020 +-- truncate_limit: 100 +select '$.a.**{0 to 5}.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**{0 to 5}.b'::jsonpath" +== 021 +-- truncate_limit: 100 +select '$.a.**{5 to last}.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**{5 to last}.b'::jsonpath" +== 022 +-- truncate_limit: 100 +select '$.a.**{last}.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**{last}.b'::jsonpath" +== 023 +-- truncate_limit: 100 +select '$.a.**{last to 5}.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a.**{last to 5}.b'::jsonpath" +== 024 +-- truncate_limit: 100 +select '$+1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$+1'::jsonpath" +== 025 +-- truncate_limit: 100 +select '$-1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$-1'::jsonpath" +== 026 +-- truncate_limit: 100 +select '$--+1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$--+1'::jsonpath" +== 027 +-- truncate_limit: 100 +select '$.a/+-1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a/+-1'::jsonpath" +== 028 +-- truncate_limit: 100 +select '1 * 2 + 4 % -3 != false'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 * 2 + 4 % -3 != false'::jsonpath" +== 029 +-- truncate_limit: 100 +select '"\b\f\r\n\t\v\"\''\\"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\b\\\\f\\\\r\\\\n\\\\t\\\\v\\\\\"\\\\''\\\\\\\\\"'::jsonpath" +== 030 +-- truncate_limit: 100 +select '"\x50\u0067\u{53}\u{051}\u{00004C}"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\x50\\\\u0067\\\\u{53}\\\\u{051}\\\\u{00004C}\"'::jsonpath" +== 031 +-- truncate_limit: 100 +select '$.foo\x50\u0067\u{53}\u{051}\u{00004C}\t\"bar'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.foo\\\\x50\\\\u0067\\\\u{53}\\\\u{051}\\\\u{00004C}\\\\t\\\\\"bar'::jsonpath" +== 032 +-- truncate_limit: 100 +select '"\z"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\z\"'::jsonpath" +== 033 +-- truncate_limit: 100 +-- unrecognized escape is just the literal char + +select '$.g ? ($.a == 1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? ($.a == 1)'::jsonpath" +== 034 +-- truncate_limit: 100 +select '$.g ? (@ == 1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@ == 1)'::jsonpath" +== 035 +-- truncate_limit: 100 +select '$.g ? (@.a == 1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.a == 1)'::jsonpath" +== 036 +-- truncate_limit: 100 +select '$.g ? (@.a == 1 || @.a == 4)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.a == 1 || @.a == 4)'::jsonpath" +== 037 +-- truncate_limit: 100 +select '$.g ? (@.a == 1 && @.a == 4)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.a == 1 && @.a == 4)'::jsonpath" +== 038 +-- truncate_limit: 100 +select '$.g ? (@.a == 1 || @.a == 4 && @.b == 7)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.a == 1 || @.a == 4 && @.b == 7)'::jsonpath" +== 039 +-- truncate_limit: 100 +select '$.g ? (@.a == 1 || !(@.a == 4) && @.b == 7)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.a == 1 || !(@.a == 4) && @.b == 7)'::jsonpath" +== 040 +-- truncate_limit: 100 +select '$.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7)'::jsonpath" +== 041 +-- truncate_limit: 100 +select '$.g ? (@.x >= @[*]?(@.a > "abc"))'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.x >= @[*]?(@.a > \"abc\"))'::jsonpath" +== 042 +-- truncate_limit: 100 +select '$.g ? ((@.x >= 123 || @.a == 4) is unknown)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? ((@.x >= 123 || @.a == 4) is unknown)'::jsonpath" +== 043 +-- truncate_limit: 100 +select '$.g ? (exists (@.x))'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (exists (@.x))'::jsonpath" +== 044 +-- truncate_limit: 100 +select '$.g ? (exists (@.x ? (@ == 14)))'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (exists (@.x ? (@ == 14)))'::jsonpath" +== 045 +-- truncate_limit: 100 +select '$.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14)))'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14)))'::jsonpath" +== 046 +-- truncate_limit: 100 +select '$.g ? (+@.x >= +-(+@.a + 2))'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (+@.x >= +-(+@.a + 2))'::jsonpath" +== 047 +-- truncate_limit: 100 +select '$a'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$a'::jsonpath" +== 048 +-- truncate_limit: 100 +select '$a.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$a.b'::jsonpath" +== 049 +-- truncate_limit: 100 +select '$a[*]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$a[*]'::jsonpath" +== 050 +-- truncate_limit: 100 +select '$.g ? (@.zip == $zip)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.g ? (@.zip == $zip)'::jsonpath" +== 051 +-- truncate_limit: 100 +select '$.a[1,2, 3 to 16]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a[1,2, 3 to 16]'::jsonpath" +== 052 +-- truncate_limit: 100 +select '$.a[$a + 1, ($b[*]) to -($[0] * 2)]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a[$a + 1, ($b[*]) to -($[0] * 2)]'::jsonpath" +== 053 +-- truncate_limit: 100 +select '$.a[$.a.size() - 3]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.a[$.a.size() - 3]'::jsonpath" +== 054 +-- truncate_limit: 100 +select 'last'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'last'::jsonpath" +== 055 +-- truncate_limit: 100 +select '"last"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"last\"'::jsonpath" +== 056 +-- truncate_limit: 100 +select '$.last'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.last'::jsonpath" +== 057 +-- truncate_limit: 100 +select '$ ? (last > 0)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (last > 0)'::jsonpath" +== 058 +-- truncate_limit: 100 +select '$[last]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$[last]'::jsonpath" +== 059 +-- truncate_limit: 100 +select '$[$[0] ? (last > 0)]'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$[$[0] ? (last > 0)]'::jsonpath" +== 060 +-- truncate_limit: 100 +select 'null.type()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'null.type()'::jsonpath" +== 061 +-- truncate_limit: 100 +select '1.type()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.type()'::jsonpath" +== 062 +-- truncate_limit: 100 +select '(1).type()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1).type()'::jsonpath" +== 063 +-- truncate_limit: 100 +select '1.2.type()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.2.type()'::jsonpath" +== 064 +-- truncate_limit: 100 +select '"aaa".type()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '\"aaa\".type()'::jsonpath" +== 065 +-- truncate_limit: 100 +select 'true.type()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'true.type()'::jsonpath" +== 066 +-- truncate_limit: 100 +select '$.double().floor().ceiling().abs()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.double().floor().ceiling().abs()'::jsonpath" +== 067 +-- truncate_limit: 100 +select '$.keyvalue().key'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.keyvalue().key'::jsonpath" +== 068 +-- truncate_limit: 100 +select '$.datetime()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.datetime()'::jsonpath" +== 069 +-- truncate_limit: 100 +select '$.datetime("datetime template")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.datetime(\"datetime template\")'::jsonpath" +== 070 +-- truncate_limit: 100 +select '$.bigint().integer().number().decimal()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.bigint().integer().number().decimal()'::jsonpath" +== 071 +-- truncate_limit: 100 +select '$.boolean()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.boolean()'::jsonpath" +== 072 +-- truncate_limit: 100 +select '$.date()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.date()'::jsonpath" +== 073 +-- truncate_limit: 100 +select '$.decimal(4,2)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.decimal(4,2)'::jsonpath" +== 074 +-- truncate_limit: 100 +select '$.string()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.string()'::jsonpath" +== 075 +-- truncate_limit: 100 +select '$.time()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.time()'::jsonpath" +== 076 +-- truncate_limit: 100 +select '$.time(6)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.time(6)'::jsonpath" +== 077 +-- truncate_limit: 100 +select '$.time_tz()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.time_tz()'::jsonpath" +== 078 +-- truncate_limit: 100 +select '$.time_tz(4)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.time_tz(4)'::jsonpath" +== 079 +-- truncate_limit: 100 +select '$.timestamp()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.timestamp()'::jsonpath" +== 080 +-- truncate_limit: 100 +select '$.timestamp(2)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.timestamp(2)'::jsonpath" +== 081 +-- truncate_limit: 100 +select '$.timestamp_tz()'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.timestamp_tz()'::jsonpath" +== 082 +-- truncate_limit: 100 +select '$.timestamp_tz(0)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$.timestamp_tz(0)'::jsonpath" +== 083 +-- truncate_limit: 100 +select '$ ? (@ starts with "abc")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ starts with \"abc\")'::jsonpath" +== 084 +-- truncate_limit: 100 +select '$ ? (@ starts with $var)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ starts with $var)'::jsonpath" +== 085 +-- truncate_limit: 100 +select '$ ? (@ like_regex "(invalid pattern")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"(invalid pattern\")'::jsonpath" +== 086 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\")'::jsonpath" +== 087 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"\")'::jsonpath" +== 088 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "i")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"i\")'::jsonpath" +== 089 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "is")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"is\")'::jsonpath" +== 090 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "isim")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"isim\")'::jsonpath" +== 091 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"xsms\")'::jsonpath" +== 092 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"q\")'::jsonpath" +== 093 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"iq\")'::jsonpath" +== 094 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"smixq\")'::jsonpath" +== 095 +-- truncate_limit: 100 +select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@ like_regex \"pattern\" flag \"a\")'::jsonpath" +== 096 +-- truncate_limit: 100 +select '$ < 1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ < 1'::jsonpath" +== 097 +-- truncate_limit: 100 +select '($ < 1) || $.a.b <= $x'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '($ < 1) || $.a.b <= $x'::jsonpath" +== 098 +-- truncate_limit: 100 +select '@ + 1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '@ + 1'::jsonpath" +== 099 +-- truncate_limit: 100 +select '($).a.b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '($).a.b'::jsonpath" +== 100 +-- truncate_limit: 100 +select '($.a.b).c.d'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '($.a.b).c.d'::jsonpath" +== 101 +-- truncate_limit: 100 +select '($.a.b + -$.x.y).c.d'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '($.a.b + -$.x.y).c.d'::jsonpath" +== 102 +-- truncate_limit: 100 +select '(-+$.a.b).c.d'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(-+$.a.b).c.d'::jsonpath" +== 103 +-- truncate_limit: 100 +select '1 + ($.a.b + 2).c.d'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 + ($.a.b + 2).c.d'::jsonpath" +== 104 +-- truncate_limit: 100 +select '1 + ($.a.b > 2).c.d'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 + ($.a.b > 2).c.d'::jsonpath" +== 105 +-- truncate_limit: 100 +select '($)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '($)'::jsonpath" +== 106 +-- truncate_limit: 100 +select '(($))'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(($))'::jsonpath" +== 107 +-- truncate_limit: 100 +select '((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c)))))'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c)))))'::jsonpath" +== 108 +-- truncate_limit: 100 +select '$ ? (@.a < 1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 1)'::jsonpath" +== 109 +-- truncate_limit: 100 +select '$ ? (@.a < -1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -1)'::jsonpath" +== 110 +-- truncate_limit: 100 +select '$ ? (@.a < +1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +1)'::jsonpath" +== 111 +-- truncate_limit: 100 +select '$ ? (@.a < .1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < .1)'::jsonpath" +== 112 +-- truncate_limit: 100 +select '$ ? (@.a < -.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -.1)'::jsonpath" +== 113 +-- truncate_limit: 100 +select '$ ? (@.a < +.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +.1)'::jsonpath" +== 114 +-- truncate_limit: 100 +select '$ ? (@.a < 0.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 0.1)'::jsonpath" +== 115 +-- truncate_limit: 100 +select '$ ? (@.a < -0.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -0.1)'::jsonpath" +== 116 +-- truncate_limit: 100 +select '$ ? (@.a < +0.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +0.1)'::jsonpath" +== 117 +-- truncate_limit: 100 +select '$ ? (@.a < 10.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 10.1)'::jsonpath" +== 118 +-- truncate_limit: 100 +select '$ ? (@.a < -10.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -10.1)'::jsonpath" +== 119 +-- truncate_limit: 100 +select '$ ? (@.a < +10.1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +10.1)'::jsonpath" +== 120 +-- truncate_limit: 100 +select '$ ? (@.a < 1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 1e1)'::jsonpath" +== 121 +-- truncate_limit: 100 +select '$ ? (@.a < -1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -1e1)'::jsonpath" +== 122 +-- truncate_limit: 100 +select '$ ? (@.a < +1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +1e1)'::jsonpath" +== 123 +-- truncate_limit: 100 +select '$ ? (@.a < .1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < .1e1)'::jsonpath" +== 124 +-- truncate_limit: 100 +select '$ ? (@.a < -.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -.1e1)'::jsonpath" +== 125 +-- truncate_limit: 100 +select '$ ? (@.a < +.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +.1e1)'::jsonpath" +== 126 +-- truncate_limit: 100 +select '$ ? (@.a < 0.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 0.1e1)'::jsonpath" +== 127 +-- truncate_limit: 100 +select '$ ? (@.a < -0.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -0.1e1)'::jsonpath" +== 128 +-- truncate_limit: 100 +select '$ ? (@.a < +0.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +0.1e1)'::jsonpath" +== 129 +-- truncate_limit: 100 +select '$ ? (@.a < 10.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 10.1e1)'::jsonpath" +== 130 +-- truncate_limit: 100 +select '$ ? (@.a < -10.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -10.1e1)'::jsonpath" +== 131 +-- truncate_limit: 100 +select '$ ? (@.a < +10.1e1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +10.1e1)'::jsonpath" +== 132 +-- truncate_limit: 100 +select '$ ? (@.a < 1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 1e-1)'::jsonpath" +== 133 +-- truncate_limit: 100 +select '$ ? (@.a < -1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -1e-1)'::jsonpath" +== 134 +-- truncate_limit: 100 +select '$ ? (@.a < +1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +1e-1)'::jsonpath" +== 135 +-- truncate_limit: 100 +select '$ ? (@.a < .1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < .1e-1)'::jsonpath" +== 136 +-- truncate_limit: 100 +select '$ ? (@.a < -.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -.1e-1)'::jsonpath" +== 137 +-- truncate_limit: 100 +select '$ ? (@.a < +.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +.1e-1)'::jsonpath" +== 138 +-- truncate_limit: 100 +select '$ ? (@.a < 0.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 0.1e-1)'::jsonpath" +== 139 +-- truncate_limit: 100 +select '$ ? (@.a < -0.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -0.1e-1)'::jsonpath" +== 140 +-- truncate_limit: 100 +select '$ ? (@.a < +0.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +0.1e-1)'::jsonpath" +== 141 +-- truncate_limit: 100 +select '$ ? (@.a < 10.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 10.1e-1)'::jsonpath" +== 142 +-- truncate_limit: 100 +select '$ ? (@.a < -10.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -10.1e-1)'::jsonpath" +== 143 +-- truncate_limit: 100 +select '$ ? (@.a < +10.1e-1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +10.1e-1)'::jsonpath" +== 144 +-- truncate_limit: 100 +select '$ ? (@.a < 1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 1e+1)'::jsonpath" +== 145 +-- truncate_limit: 100 +select '$ ? (@.a < -1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -1e+1)'::jsonpath" +== 146 +-- truncate_limit: 100 +select '$ ? (@.a < +1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +1e+1)'::jsonpath" +== 147 +-- truncate_limit: 100 +select '$ ? (@.a < .1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < .1e+1)'::jsonpath" +== 148 +-- truncate_limit: 100 +select '$ ? (@.a < -.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -.1e+1)'::jsonpath" +== 149 +-- truncate_limit: 100 +select '$ ? (@.a < +.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +.1e+1)'::jsonpath" +== 150 +-- truncate_limit: 100 +select '$ ? (@.a < 0.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 0.1e+1)'::jsonpath" +== 151 +-- truncate_limit: 100 +select '$ ? (@.a < -0.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -0.1e+1)'::jsonpath" +== 152 +-- truncate_limit: 100 +select '$ ? (@.a < +0.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +0.1e+1)'::jsonpath" +== 153 +-- truncate_limit: 100 +select '$ ? (@.a < 10.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < 10.1e+1)'::jsonpath" +== 154 +-- truncate_limit: 100 +select '$ ? (@.a < -10.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < -10.1e+1)'::jsonpath" +== 155 +-- truncate_limit: 100 +select '$ ? (@.a < +10.1e+1)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '$ ? (@.a < +10.1e+1)'::jsonpath" +== 156 +-- truncate_limit: 100 +-- numeric literals + +select '0'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0'::jsonpath" +== 157 +-- truncate_limit: 100 +select '00'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '00'::jsonpath" +== 158 +-- truncate_limit: 100 +select '0755'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0755'::jsonpath" +== 159 +-- truncate_limit: 100 +select '0.0'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.0'::jsonpath" +== 160 +-- truncate_limit: 100 +select '0.000'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.000'::jsonpath" +== 161 +-- truncate_limit: 100 +select '0.000e1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.000e1'::jsonpath" +== 162 +-- truncate_limit: 100 +select '0.000e2'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.000e2'::jsonpath" +== 163 +-- truncate_limit: 100 +select '0.000e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.000e3'::jsonpath" +== 164 +-- truncate_limit: 100 +select '0.0010'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.0010'::jsonpath" +== 165 +-- truncate_limit: 100 +select '0.0010e-1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.0010e-1'::jsonpath" +== 166 +-- truncate_limit: 100 +select '0.0010e+1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.0010e+1'::jsonpath" +== 167 +-- truncate_limit: 100 +select '0.0010e+2'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0.0010e+2'::jsonpath" +== 168 +-- truncate_limit: 100 +select '.001'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '.001'::jsonpath" +== 169 +-- truncate_limit: 100 +select '.001e1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '.001e1'::jsonpath" +== 170 +-- truncate_limit: 100 +select '1.'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.'::jsonpath" +== 171 +-- truncate_limit: 100 +select '1.e1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.e1'::jsonpath" +== 172 +-- truncate_limit: 100 +select '1a'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1a'::jsonpath" +== 173 +-- truncate_limit: 100 +select '1e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1e'::jsonpath" +== 174 +-- truncate_limit: 100 +select '1.e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.e'::jsonpath" +== 175 +-- truncate_limit: 100 +select '1.2a'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.2a'::jsonpath" +== 176 +-- truncate_limit: 100 +select '1.2e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.2e'::jsonpath" +== 177 +-- truncate_limit: 100 +select '1.2.e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.2.e'::jsonpath" +== 178 +-- truncate_limit: 100 +select '(1.2).e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1.2).e'::jsonpath" +== 179 +-- truncate_limit: 100 +select '1e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1e3'::jsonpath" +== 180 +-- truncate_limit: 100 +select '1.e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.e3'::jsonpath" +== 181 +-- truncate_limit: 100 +select '1.e3.e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.e3.e'::jsonpath" +== 182 +-- truncate_limit: 100 +select '1.e3.e4'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.e3.e4'::jsonpath" +== 183 +-- truncate_limit: 100 +select '1.2e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.2e3'::jsonpath" +== 184 +-- truncate_limit: 100 +select '1.2e3a'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.2e3a'::jsonpath" +== 185 +-- truncate_limit: 100 +select '1.2.e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1.2.e3'::jsonpath" +== 186 +-- truncate_limit: 100 +select '(1.2).e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1.2).e3'::jsonpath" +== 187 +-- truncate_limit: 100 +select '1..e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1..e'::jsonpath" +== 188 +-- truncate_limit: 100 +select '1..e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1..e3'::jsonpath" +== 189 +-- truncate_limit: 100 +select '(1.).e'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1.).e'::jsonpath" +== 190 +-- truncate_limit: 100 +select '(1.).e3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1.).e3'::jsonpath" +== 191 +-- truncate_limit: 100 +select '1?(2>3)'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1?(2>3)'::jsonpath" +== 192 +-- truncate_limit: 100 +-- nondecimal +select '0b100101'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b100101'::jsonpath" +== 193 +-- truncate_limit: 100 +select '0o273'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o273'::jsonpath" +== 194 +-- truncate_limit: 100 +select '0x42F'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x42F'::jsonpath" +== 195 +-- truncate_limit: 100 +-- error cases +select '0b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b'::jsonpath" +== 196 +-- truncate_limit: 100 +select '1b'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1b'::jsonpath" +== 197 +-- truncate_limit: 100 +select '0b0x'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b0x'::jsonpath" +== 198 +-- truncate_limit: 100 +select '0o'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o'::jsonpath" +== 199 +-- truncate_limit: 100 +select '1o'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1o'::jsonpath" +== 200 +-- truncate_limit: 100 +select '0o0x'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o0x'::jsonpath" +== 201 +-- truncate_limit: 100 +select '0x'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x'::jsonpath" +== 202 +-- truncate_limit: 100 +select '1x'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1x'::jsonpath" +== 203 +-- truncate_limit: 100 +select '0x0y'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x0y'::jsonpath" +== 204 +-- truncate_limit: 100 +-- underscores +select '1_000_000'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000_000'::jsonpath" +== 205 +-- truncate_limit: 100 +select '1_2_3'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_2_3'::jsonpath" +== 206 +-- truncate_limit: 100 +select '0x1EEE_FFFF'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x1EEE_FFFF'::jsonpath" +== 207 +-- truncate_limit: 100 +select '0o2_73'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o2_73'::jsonpath" +== 208 +-- truncate_limit: 100 +select '0b10_0101'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b10_0101'::jsonpath" +== 209 +-- truncate_limit: 100 +select '1_000.000_005'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000.000_005'::jsonpath" +== 210 +-- truncate_limit: 100 +select '1_000.'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000.'::jsonpath" +== 211 +-- truncate_limit: 100 +select '.000_005'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '.000_005'::jsonpath" +== 212 +-- truncate_limit: 100 +select '1_000.5e0_1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000.5e0_1'::jsonpath" +== 213 +-- truncate_limit: 100 +-- error cases +select '_100'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '_100'::jsonpath" +== 214 +-- truncate_limit: 100 +select '100_'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100_'::jsonpath" +== 215 +-- truncate_limit: 100 +select '100__000'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '100__000'::jsonpath" +== 216 +-- truncate_limit: 100 +select '_1_000.5'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '_1_000.5'::jsonpath" +== 217 +-- truncate_limit: 100 +select '1_000_.5'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000_.5'::jsonpath" +== 218 +-- truncate_limit: 100 +select '1_000._5'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000._5'::jsonpath" +== 219 +-- truncate_limit: 100 +select '1_000.5_'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000.5_'::jsonpath" +== 220 +-- truncate_limit: 100 +select '1_000.5e_1'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1_000.5e_1'::jsonpath" +== 221 +-- truncate_limit: 100 +-- underscore after prefix not allowed in JavaScript (but allowed in SQL) +select '0b_10_0101'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0b_10_0101'::jsonpath" +== 222 +-- truncate_limit: 100 +select '0o_273'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0o_273'::jsonpath" +== 223 +-- truncate_limit: 100 +select '0x_42F'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0x_42F'::jsonpath" +== 224 +-- truncate_limit: 100 +-- test non-error-throwing API + +SELECT str as jsonpath, + pg_input_is_valid(str,'jsonpath') as ok, + errinfo.sql_error_code, + errinfo.message, + errinfo.detail, + errinfo.hint +FROM unnest(ARRAY['$ ? (@ like_regex "pattern" flag "smixq")'::text, + '$ ? (@ like_regex "pattern" flag "a")', + '@ + 1', + '00', + '1a']) str, + LATERAL pg_input_error_info(str, 'jsonpath') as errinfo +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY['$ ? (@ like_regex \"pattern\" flag \"smixq\")'::text, '$ ? (@ like_rege..." diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json new file mode 100644 index 0000000..efb3a10 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json @@ -0,0 +1,36 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.test b/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.test new file mode 100644 index 0000000..e9069c5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.test @@ -0,0 +1,235 @@ +== 001 +-- truncate_limit: 100 +|-- +-- encoding-sensitive tests for jsonpath +|-- + +-- We provide expected-results files for UTF8 (jsonpath_encoding.out) +-- and for SQL_ASCII (jsonpath_encoding_1.out). Skip otherwise. +SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') + AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') AS skip_test" +== 002 +-- truncate_limit: 100 +SELECT getdatabaseencoding() +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT getdatabaseencoding()" +== 003 +-- truncate_limit: 100 +-- just to label the results files + +-- checks for double-quoted values + +-- basic unicode input +SELECT '"\u"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u\"'::jsonpath" +== 004 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '"\u00"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u00\"'::jsonpath" +== 005 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '"\u000g"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u000g\"'::jsonpath" +== 006 +-- truncate_limit: 100 +-- ERROR, g is not a hex digit +SELECT '"\u0000"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\u0000\"'::jsonpath" +== 007 +-- truncate_limit: 100 +-- OK, legal escape +SELECT '"\uaBcD"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\uaBcD\"'::jsonpath" +== 008 +-- truncate_limit: 100 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs +select '"\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\ud83d\\\\ude04\\\\ud83d\\\\udc36\"'::jsonpath AS correct_in_utf8" +== 009 +-- truncate_limit: 100 +select '"\ud83d\ud83d"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\ud83d\\\\ud83d\"'::jsonpath" +== 010 +-- truncate_limit: 100 +-- 2 high surrogates in a row +select '"\ude04\ud83d"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\ude04\\\\ud83d\"'::jsonpath" +== 011 +-- truncate_limit: 100 +-- surrogates in wrong order +select '"\ud83dX"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\ud83dX\"'::jsonpath" +== 012 +-- truncate_limit: 100 +-- orphan high surrogate +select '"\ude04X"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"\\\\ude04X\"'::jsonpath" +== 013 +-- truncate_limit: 100 +-- orphan low surrogate + +--handling of simple unicode escapes +select '"the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"the Copyright \\\\u00a9 sign\"'::jsonpath AS correct_in_utf8" +== 014 +-- truncate_limit: 100 +select '"dollar \u0024 character"'::jsonpath as correct_everywhere +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"dollar \\\\u0024 character\"'::jsonpath AS correct_everywhere" +== 015 +-- truncate_limit: 100 +select '"dollar \\u0024 character"'::jsonpath as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"dollar \\\\\\\\u0024 character\"'::jsonpath AS not_an_escape" +== 016 +-- truncate_limit: 100 +select '"null \u0000 escape"'::jsonpath as not_unescaped +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"null \\\\u0000 escape\"'::jsonpath AS not_unescaped" +== 017 +-- truncate_limit: 100 +select '"null \\u0000 escape"'::jsonpath as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\"null \\\\\\\\u0000 escape\"'::jsonpath AS not_an_escape" +== 018 +-- truncate_limit: 100 +-- checks for quoted key names + +-- basic unicode input +SELECT '$."\u"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\u\"'::jsonpath" +== 019 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '$."\u00"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\u00\"'::jsonpath" +== 020 +-- truncate_limit: 100 +-- ERROR, incomplete escape +SELECT '$."\u000g"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\u000g\"'::jsonpath" +== 021 +-- truncate_limit: 100 +-- ERROR, g is not a hex digit +SELECT '$."\u0000"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\u0000\"'::jsonpath" +== 022 +-- truncate_limit: 100 +-- OK, legal escape +SELECT '$."\uaBcD"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\uaBcD\"'::jsonpath" +== 023 +-- truncate_limit: 100 +-- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs +select '$."\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\ud83d\\\\ude04\\\\ud83d\\\\udc36\"'::jsonpath AS correct_in_utf8" +== 024 +-- truncate_limit: 100 +select '$."\ud83d\ud83d"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\ud83d\\\\ud83d\"'::jsonpath" +== 025 +-- truncate_limit: 100 +-- 2 high surrogates in a row +select '$."\ude04\ud83d"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\ude04\\\\ud83d\"'::jsonpath" +== 026 +-- truncate_limit: 100 +-- surrogates in wrong order +select '$."\ud83dX"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\ud83dX\"'::jsonpath" +== 027 +-- truncate_limit: 100 +-- orphan high surrogate +select '$."\ude04X"'::jsonpath +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"\\\\ude04X\"'::jsonpath" +== 028 +-- truncate_limit: 100 +-- orphan low surrogate + +--handling of simple unicode escapes +select '$."the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"the Copyright \\\\u00a9 sign\"'::jsonpath AS correct_in_utf8" +== 029 +-- truncate_limit: 100 +select '$."dollar \u0024 character"'::jsonpath as correct_everywhere +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"dollar \\\\u0024 character\"'::jsonpath AS correct_everywhere" +== 030 +-- truncate_limit: 100 +select '$."dollar \\u0024 character"'::jsonpath as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"dollar \\\\\\\\u0024 character\"'::jsonpath AS not_an_escape" +== 031 +-- truncate_limit: 100 +select '$."null \u0000 escape"'::jsonpath as not_unescaped +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"null \\\\u0000 escape\"'::jsonpath AS not_unescaped" +== 032 +-- truncate_limit: 100 +select '$."null \\u0000 escape"'::jsonpath as not_an_escape +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'$.\"null \\\\\\\\u0000 escape\"'::jsonpath AS not_an_escape" diff --git a/parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json b/parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json new file mode 100644 index 0000000..48ba122 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json @@ -0,0 +1,128 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/largeobject.test b/parser/testdata/summary_truncate/postgres_regress/largeobject.test new file mode 100644 index 0000000..e16546b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/largeobject.test @@ -0,0 +1,996 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test large object support +|-- + +-- directory paths are passed to us in environment variables + +-- ensure consistent test output regardless of the default bytea format +SET bytea_output TO escape +-- +STMT: VariableSetStmt +TRUNCATED: "SET bytea_output TO escape" +== 002 +-- truncate_limit: 100 +-- Test ALTER LARGE OBJECT OWNER +CREATE ROLE regress_lo_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_lo_user" +== 003 +-- truncate_limit: 100 +SELECT lo_create(42) +-- +FUNCTION: name="lo_create" function="lo_create" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_create(42)" +== 004 +-- truncate_limit: 100 +ALTER LARGE OBJECT 42 OWNER TO regress_lo_user +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER LARGE OBJECT 42 OWNER TO regress_lo_user" +== 005 +-- truncate_limit: 100 +-- Test GRANT, COMMENT as non-superuser +SET SESSION AUTHORIZATION regress_lo_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_lo_user" +== 006 +-- truncate_limit: 100 +GRANT SELECT ON LARGE OBJECT 42 TO public +-- +STMT: GrantStmt +TRUNCATED: "GRANT select ON LARGE OBJECT 42 TO public" +== 007 +-- truncate_limit: 100 +COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer'" +== 008 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 009 +-- truncate_limit: 100 +-- Test psql's \lo_list et al (we assume no other LOs exist yet) + +-- Load a file +CREATE TABLE lotest_stash_values (loid oid, fd integer) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lotest_stash_values (loid oid, fd int)" +== 010 +-- truncate_limit: 100 +-- lo_creat(mode integer) returns oid +-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times +-- returns the large object id +INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_creat" function="lo_creat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42)" +== 011 +-- truncate_limit: 100 +-- NOTE: large objects require transactions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 012 +-- truncate_limit: 100 +-- lo_open(lobjId oid, mode integer) returns integer +-- The mode parameter to lo_open uses two constants: +-- INV_WRITE = 0x20000 +-- INV_READ = 0x40000 +-- The return value is a file descriptor-like value which remains valid for the +-- transaction. +UPDATE lotest_stash_values SET fd = lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE lotest_stash_values SET fd = lo_open(loid, (x'20000' | x'40000')::int)" +== 013 +-- truncate_limit: 100 +-- loread/lowrite names are wonky, different from other functions which are lo_* +-- lowrite(fd integer, data bytea) returns integer +-- the integer is the number of bytes written +SELECT lowrite(fd, ' +I wandered lonely as a cloud +That floats on high o''er vales and hills, +When all at once I saw a crowd, +A host, of golden daffodils; +Beside the lake, beneath the trees, +Fluttering and dancing in the breeze. + +Continuous as the stars that shine +And twinkle on the milky way, +They stretched in never-ending line +Along the margin of a bay: +Ten thousand saw I at a glance, +Tossing their heads in sprightly dance. + +The waves beside them danced; but they +Out-did the sparkling waves in glee: +A poet could not but be gay, +In such a jocund company: +I gazed--and gazed--but little thought +What wealth the show to me had brought: + +For oft, when on my couch I lie +In vacant or in pensive mood, +They flash upon that inward eye +Which is the bliss of solitude; +And then my heart with pleasure fills, +And dances with the daffodils. + + -- William Wordsworth +') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM lotest_stash_values" +== 014 +-- truncate_limit: 100 +-- lo_close(fd integer) returns integer +-- return value is 0 for success, or <0 for error (actually only -1, but...) +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_close(fd) FROM lotest_stash_values" +== 015 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 016 +-- truncate_limit: 100 +-- Copy to another large object. +-- Note: we intentionally don't remove the object created here; +-- it's left behind to help test pg_dump. + +SELECT lo_from_bytea(0, lo_get(loid)) AS newloid FROM lotest_stash_values + +-- Add a comment to it, as well, for pg_dump/pg_upgrade testing. +COMMENT ON LARGE OBJECT :newloid IS 'I Wandered Lonely as a Cloud' +-- +ERROR: syntax error at or near "ON" +CURSORPOS: 289 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 017 +-- truncate_limit: 100 +-- Read out a portion +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 018 +-- truncate_limit: 100 +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE lotest_stash_values SET fd = lo_open(loid, (x'20000' | x'40000')::int)" +== 019 +-- truncate_limit: 100 +-- lo_lseek(fd integer, offset integer, whence integer) returns integer +-- offset is in bytes, whence is one of three values: +-- SEEK_SET (= 0) meaning relative to beginning +-- SEEK_CUR (= 1) meaning relative to current position +-- SEEK_END (= 2) meaning relative to end (offset better be negative) +-- returns current position in file +SELECT lo_lseek(fd, 104, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, 104, 0) FROM lotest_stash_values" +== 020 +-- truncate_limit: 100 +-- loread/lowrite names are wonky, different from other functions which are lo_* +-- loread(fd integer, len integer) returns bytea +SELECT loread(fd, 28) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT loread(fd, 28) FROM lotest_stash_values" +== 021 +-- truncate_limit: 100 +SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values" +== 022 +-- truncate_limit: 100 +SELECT lowrite(fd, 'n') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lowrite(fd, 'n') FROM lotest_stash_values" +== 023 +-- truncate_limit: 100 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell(fd) FROM lotest_stash_values" +== 024 +-- truncate_limit: 100 +SELECT lo_lseek(fd, -744, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, -744, 2) FROM lotest_stash_values" +== 025 +-- truncate_limit: 100 +SELECT loread(fd, 28) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT loread(fd, 28) FROM lotest_stash_values" +== 026 +-- truncate_limit: 100 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_close(fd) FROM lotest_stash_values" +== 027 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 028 +-- truncate_limit: 100 +-- Test resource management +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 029 +-- truncate_limit: 100 +SELECT lo_open(loid, x'40000'::int) from lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_open(loid, x'40000'::int) FROM lotest_stash_values" +== 030 +-- truncate_limit: 100 +ABORT +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 031 +-- truncate_limit: 100 +DO :'dobody' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 4 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 032 +-- truncate_limit: 100 +-- Test truncation. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 033 +-- truncate_limit: 100 +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE lotest_stash_values SET fd = lo_open(loid, (x'20000' | x'40000')::int)" +== 034 +-- truncate_limit: 100 +SELECT lo_truncate(fd, 11) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_truncate(fd, 11) FROM lotest_stash_values" +== 035 +-- truncate_limit: 100 +SELECT loread(fd, 15) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT loread(fd, 15) FROM lotest_stash_values" +== 036 +-- truncate_limit: 100 +SELECT lo_truncate(fd, 10000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_truncate(fd, 10000) FROM lotest_stash_values" +== 037 +-- truncate_limit: 100 +SELECT loread(fd, 10) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT loread(fd, 10) FROM lotest_stash_values" +== 038 +-- truncate_limit: 100 +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values" +== 039 +-- truncate_limit: 100 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell(fd) FROM lotest_stash_values" +== 040 +-- truncate_limit: 100 +SELECT lo_truncate(fd, 5000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_truncate(fd, 5000) FROM lotest_stash_values" +== 041 +-- truncate_limit: 100 +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values" +== 042 +-- truncate_limit: 100 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell(fd) FROM lotest_stash_values" +== 043 +-- truncate_limit: 100 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_close(fd) FROM lotest_stash_values" +== 044 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 045 +-- truncate_limit: 100 +-- Test 64-bit large object functions. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 046 +-- truncate_limit: 100 +UPDATE lotest_stash_values SET fd = lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE lotest_stash_values SET fd = lo_open(loid, (x'20000' | x'40000')::int)" +== 047 +-- truncate_limit: 100 +SELECT lo_lseek64(fd, 4294967296, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek64(fd, 4294967296, 0) FROM lotest_stash_values" +== 048 +-- truncate_limit: 100 +SELECT lowrite(fd, 'offset:4GB') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lowrite(fd, 'offset:4GB') FROM lotest_stash_values" +== 049 +-- truncate_limit: 100 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell64(fd) FROM lotest_stash_values" +== 050 +-- truncate_limit: 100 +SELECT lo_lseek64(fd, -10, 1) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek64(fd, -10, 1) FROM lotest_stash_values" +== 051 +-- truncate_limit: 100 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell64(fd) FROM lotest_stash_values" +== 052 +-- truncate_limit: 100 +SELECT loread(fd, 10) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT loread(fd, 10) FROM lotest_stash_values" +== 053 +-- truncate_limit: 100 +SELECT lo_truncate64(fd, 5000000000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate64" function="lo_truncate64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_truncate64(fd, 5000000000) FROM lotest_stash_values" +== 054 +-- truncate_limit: 100 +SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values" +== 055 +-- truncate_limit: 100 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell64(fd) FROM lotest_stash_values" +== 056 +-- truncate_limit: 100 +SELECT lo_truncate64(fd, 3000000000) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_truncate64" function="lo_truncate64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_truncate64(fd, 3000000000) FROM lotest_stash_values" +== 057 +-- truncate_limit: 100 +SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek64" function="lo_lseek64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values" +== 058 +-- truncate_limit: 100 +SELECT lo_tell64(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell64" function="lo_tell64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell64(fd) FROM lotest_stash_values" +== 059 +-- truncate_limit: 100 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_close(fd) FROM lotest_stash_values" +== 060 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 061 +-- truncate_limit: 100 +-- lo_unlink(lobjId oid) returns integer +-- return value appears to always be 1 +SELECT lo_unlink(loid) from lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_unlink(loid) FROM lotest_stash_values" +== 062 +-- truncate_limit: 100 +TRUNCATE lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE lotest_stash_values" +== 063 +-- truncate_limit: 100 +INSERT INTO lotest_stash_values (loid) SELECT lo_import(:'filename') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 064 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 065 +-- truncate_limit: 100 +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)) +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DML +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE lotest_stash_values SET fd = lo_open(loid, (x'20000' | x'40000')::int)" +== 066 +-- truncate_limit: 100 +-- verify length of large object +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values" +== 067 +-- truncate_limit: 100 +-- with the default BLCKSZ, LOBLKSIZE = 2048, so this positions us for a block +-- edge case +SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values" +== 068 +-- truncate_limit: 100 +-- this should get half of the value from page 0 and half from page 1 of the +-- large object +SELECT loread(fd, 36) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT loread(fd, 36) FROM lotest_stash_values" +== 069 +-- truncate_limit: 100 +SELECT lo_tell(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_tell" function="lo_tell" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_tell(fd) FROM lotest_stash_values" +== 070 +-- truncate_limit: 100 +SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values" +== 071 +-- truncate_limit: 100 +SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values" +== 072 +-- truncate_limit: 100 +SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_lseek" function="lo_lseek" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values" +== 073 +-- truncate_limit: 100 +SELECT loread(fd, 36) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="loread" function="loread" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT loread(fd, 36) FROM lotest_stash_values" +== 074 +-- truncate_limit: 100 +SELECT lo_close(fd) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_close" function="lo_close" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_close(fd) FROM lotest_stash_values" +== 075 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 076 +-- truncate_limit: 100 +SELECT lo_export(loid, :'filename') FROM lotest_stash_values +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +-- truncate_limit: 100 +-- just make sure \lo_export does not barf + +-- This is a hack to test that export/import are reversible +-- This uses knowledge about the inner workings of large object mechanism +-- which should not be used outside it. This makes it a HACK +SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values) +EXCEPT +SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 393 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 078 +-- truncate_limit: 100 +SELECT lo_unlink(loid) FROM lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=Select +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_unlink(loid) FROM lotest_stash_values" +== 079 +-- truncate_limit: 100 +TRUNCATE lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE lotest_stash_values" +== 080 +-- truncate_limit: 100 +SELECT lo_from_bytea(0, lo_get(:newloid_1)) AS newloid_2 + +SELECT fipshash(lo_get(:newloid_1)) = fipshash(lo_get(:newloid_2)) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 081 +-- truncate_limit: 100 +SELECT lo_get(:newloid_1, 0, 20) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 082 +-- truncate_limit: 100 +SELECT lo_get(:newloid_1, 10, 20) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 083 +-- truncate_limit: 100 +SELECT lo_put(:newloid_1, 5, decode('afafafaf', 'hex')) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 084 +-- truncate_limit: 100 +SELECT lo_get(:newloid_1, 0, 20) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 085 +-- truncate_limit: 100 +SELECT lo_put(:newloid_1, 4294967310, 'foo') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 086 +-- truncate_limit: 100 +SELECT lo_get(:newloid_1) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 087 +-- truncate_limit: 100 +SELECT lo_get(:newloid_1, 4294967294, 100) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 088 +-- truncate_limit: 100 +-- This object is left in the database for pg_dump test purposes +SELECT lo_from_bytea(0, E'\\xdeadbeef') AS newloid + +SET bytea_output TO hex +-- +ERROR: syntax error at or near "SET" +CURSORPOS: 118 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 089 +-- truncate_limit: 100 +SELECT lo_get(:newloid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 090 +-- truncate_limit: 100 +-- Create one more object that we leave behind for testing pg_dump/pg_upgrade; +-- this one intentionally has an OID in the system range +SELECT lo_create(2121) +-- +FUNCTION: name="lo_create" function="lo_create" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_create(2121)" +== 091 +-- truncate_limit: 100 +COMMENT ON LARGE OBJECT 2121 IS 'testing comments' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON LARGE OBJECT 2121 IS 'testing comments'" +== 092 +-- truncate_limit: 100 +-- Test writes on large objects in read-only transactions +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 093 +-- truncate_limit: 100 +-- INV_READ ... ok +SELECT lo_open(2121, x'40000'::int) +-- +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_open(2121, x'40000'::int)" +== 094 +-- truncate_limit: 100 +-- INV_WRITE ... error +SELECT lo_open(2121, x'20000'::int) +-- +FUNCTION: name="lo_open" function="lo_open" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_open(2121, x'20000'::int)" +== 095 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 096 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 097 +-- truncate_limit: 100 +SELECT lo_create(42) +-- +FUNCTION: name="lo_create" function="lo_create" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_create(42)" +== 098 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 099 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 100 +-- truncate_limit: 100 +SELECT lo_creat(42) +-- +FUNCTION: name="lo_creat" function="lo_creat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_creat(42)" +== 101 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 102 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 103 +-- truncate_limit: 100 +SELECT lo_unlink(42) +-- +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_unlink(42)" +== 104 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 105 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 106 +-- truncate_limit: 100 +SELECT lowrite(42, 'x') +-- +FUNCTION: name="lowrite" function="lowrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lowrite(42, 'x')" +== 107 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 108 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 109 +-- truncate_limit: 100 +SELECT lo_import(:'filename') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 18 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 110 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 111 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 112 +-- truncate_limit: 100 +SELECT lo_truncate(42, 0) +-- +FUNCTION: name="lo_truncate" function="lo_truncate" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_truncate(42, 0)" +== 113 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 114 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 115 +-- truncate_limit: 100 +SELECT lo_truncate64(42, 0) +-- +FUNCTION: name="lo_truncate64" function="lo_truncate64" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_truncate64(42, 0)" +== 116 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 117 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 118 +-- truncate_limit: 100 +SELECT lo_from_bytea(0, 'x') +-- +FUNCTION: name="lo_from_bytea" function="lo_from_bytea" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_from_bytea(0, 'x')" +== 119 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 120 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 121 +-- truncate_limit: 100 +SELECT lo_put(42, 0, 'x') +-- +FUNCTION: name="lo_put" function="lo_put" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lo_put(42, 0, 'x')" +== 122 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 123 +-- truncate_limit: 100 +-- Clean up +DROP TABLE lotest_stash_values +-- +TABLE: name="lotest_stash_values" schema="" table="lotest_stash_values" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lotest_stash_values" +== 124 +-- truncate_limit: 100 +DROP ROLE regress_lo_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_lo_user" diff --git a/parser/testdata/summary_truncate/postgres_regress/limit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/limit.metadata.json new file mode 100644 index 0000000..fb87925 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/limit.metadata.json @@ -0,0 +1,84 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/limit.test b/parser/testdata/summary_truncate/postgres_regress/limit.test new file mode 100644 index 0000000..60320e4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/limit.test @@ -0,0 +1,667 @@ +== 001 +-- truncate_limit: 100 +|-- +-- LIMIT +-- Check the LIMIT/OFFSET feature of SELECT +|-- + +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 50 + ORDER BY unique1 LIMIT 2 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE unique1 > 50 ORDER BY unique1 LIMIT 2" +== 002 +-- truncate_limit: 100 +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 60 + ORDER BY unique1 LIMIT 5 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE unique1 > 60 ORDER BY unique1 LIMIT 5" +== 003 +-- truncate_limit: 100 +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 60 AND unique1 < 63 + ORDER BY unique1 LIMIT 5 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE unique1 > 60 AND unique1 < 63 ORDER BY unique1 LIMIT 5" +== 004 +-- truncate_limit: 100 +SELECT ''::text AS three, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 100 + ORDER BY unique1 LIMIT 3 OFFSET 20 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE unique1 > 100 ORDER BY unique1 LIMIT 3 OFFSET 20" +== 005 +-- truncate_limit: 100 +SELECT ''::text AS zero, unique1, unique2, stringu1 + FROM onek WHERE unique1 < 50 + ORDER BY unique1 DESC LIMIT 8 OFFSET 99 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE unique1 < 50 ORDER BY unique1 DESC LIMIT 8 OFFSET 99" +== 006 +-- truncate_limit: 100 +SELECT ''::text AS eleven, unique1, unique2, stringu1 + FROM onek WHERE unique1 < 50 + ORDER BY unique1 DESC LIMIT 20 OFFSET 39 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE unique1 < 50 ORDER BY unique1 DESC LIMIT 20 OFFSET 39" +== 007 +-- truncate_limit: 100 +SELECT ''::text AS ten, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 OFFSET 990 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ''::text AS ten, unique1, unique2, stringu1 FROM onek ORDER BY unique1 OFFSET 990" +== 008 +-- truncate_limit: 100 +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 OFFSET 990 LIMIT 5 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek ORDER BY unique1 LIMIT 5 OFFSET 990" +== 009 +-- truncate_limit: 100 +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 LIMIT 5 OFFSET 900 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek ORDER BY unique1 LIMIT 5 OFFSET 900" +== 010 +-- truncate_limit: 100 +-- Test null limit and offset. The planner would discard a simple null +-- constant, so to ensure executor is exercised, do this: +select * from int8_tbl limit (case when random() < 0.5 then null::bigint end) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl LIMIT CASE WHEN random() < 0.5 THEN NULL::bigint END" +== 011 +-- truncate_limit: 100 +select * from int8_tbl offset (case when random() < 0.5 then null::bigint end) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl OFFSET CASE WHEN random() < 0.5 THEN NULL::bigint END" +== 012 +-- truncate_limit: 100 +-- Test assorted cases involving backwards fetch from a LIMIT plan node +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 013 +-- truncate_limit: 100 +declare c1 cursor for select * from int8_tbl limit 10 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM int8_tbl LIMIT 10" +== 014 +-- truncate_limit: 100 +fetch all in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c1" +== 015 +-- truncate_limit: 100 +fetch 1 in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 016 +-- truncate_limit: 100 +fetch backward 1 in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c1" +== 017 +-- truncate_limit: 100 +fetch backward all in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c1" +== 018 +-- truncate_limit: 100 +fetch backward 1 in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c1" +== 019 +-- truncate_limit: 100 +fetch all in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c1" +== 020 +-- truncate_limit: 100 +declare c2 cursor for select * from int8_tbl limit 3 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c2 CURSOR FOR SELECT * FROM int8_tbl LIMIT 3" +== 021 +-- truncate_limit: 100 +fetch all in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c2" +== 022 +-- truncate_limit: 100 +fetch 1 in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c2" +== 023 +-- truncate_limit: 100 +fetch backward 1 in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c2" +== 024 +-- truncate_limit: 100 +fetch backward all in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c2" +== 025 +-- truncate_limit: 100 +fetch backward 1 in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c2" +== 026 +-- truncate_limit: 100 +fetch all in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c2" +== 027 +-- truncate_limit: 100 +declare c3 cursor for select * from int8_tbl offset 3 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c3 CURSOR FOR SELECT * FROM int8_tbl OFFSET 3" +== 028 +-- truncate_limit: 100 +fetch all in c3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c3" +== 029 +-- truncate_limit: 100 +fetch 1 in c3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c3" +== 030 +-- truncate_limit: 100 +fetch backward 1 in c3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c3" +== 031 +-- truncate_limit: 100 +fetch backward all in c3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c3" +== 032 +-- truncate_limit: 100 +fetch backward 1 in c3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c3" +== 033 +-- truncate_limit: 100 +fetch all in c3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c3" +== 034 +-- truncate_limit: 100 +declare c4 cursor for select * from int8_tbl offset 10 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c4 CURSOR FOR SELECT * FROM int8_tbl OFFSET 10" +== 035 +-- truncate_limit: 100 +fetch all in c4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c4" +== 036 +-- truncate_limit: 100 +fetch 1 in c4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c4" +== 037 +-- truncate_limit: 100 +fetch backward 1 in c4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c4" +== 038 +-- truncate_limit: 100 +fetch backward all in c4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c4" +== 039 +-- truncate_limit: 100 +fetch backward 1 in c4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c4" +== 040 +-- truncate_limit: 100 +fetch all in c4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c4" +== 041 +-- truncate_limit: 100 +declare c5 cursor for select * from int8_tbl order by q1 fetch first 2 rows with ties +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c5 CURSOR FOR SELECT * FROM int8_tbl ORDER BY q1 FETCH FIRST 2 ROWS WITH TIES" +== 042 +-- truncate_limit: 100 +fetch all in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c5" +== 043 +-- truncate_limit: 100 +fetch 1 in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c5" +== 044 +-- truncate_limit: 100 +fetch backward 1 in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c5" +== 045 +-- truncate_limit: 100 +fetch backward 1 in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c5" +== 046 +-- truncate_limit: 100 +fetch all in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c5" +== 047 +-- truncate_limit: 100 +fetch backward all in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c5" +== 048 +-- truncate_limit: 100 +fetch all in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c5" +== 049 +-- truncate_limit: 100 +fetch backward all in c5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c5" +== 050 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 051 +-- truncate_limit: 100 +-- Stress test for variable LIMIT in conjunction with bounded-heap sorting + +SELECT + (SELECT n + FROM (VALUES (1)) AS x, + (SELECT n FROM generate_series(1,10) AS n + ORDER BY n LIMIT 1 OFFSET s-1) AS y) AS z + FROM generate_series(1,10) AS s +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 10) s" +== 052 +-- truncate_limit: 100 +|-- +-- Test behavior of volatile and set-returning functions in conjunction +-- with ORDER BY and LIMIT. +|-- + +create temp sequence testseq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE testseq" +== 053 +-- truncate_limit: 100 +explain (verbose, costs off) +select unique1, unique2, nextval('testseq') + from tenk1 order by unique2 limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT unique1, unique2, nextval('testseq') FROM tenk1 ORDER BY uniq..." +== 054 +-- truncate_limit: 100 +select unique1, unique2, nextval('testseq') + from tenk1 order by unique2 limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2, nextval('testseq') FROM tenk1 ORDER BY unique2 LIMIT 10" +== 055 +-- truncate_limit: 100 +select currval('testseq') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('testseq')" +== 056 +-- truncate_limit: 100 +explain (verbose, costs off) +select unique1, unique2, nextval('testseq') + from tenk1 order by tenthous limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT unique1, unique2, nextval('testseq') FROM tenk1 ORDER BY tent..." +== 057 +-- truncate_limit: 100 +select unique1, unique2, nextval('testseq') + from tenk1 order by tenthous limit 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2, nextval('testseq') FROM tenk1 ORDER BY tenthous LIMIT 10" +== 058 +-- truncate_limit: 100 +select currval('testseq') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('testseq')" +== 059 +-- truncate_limit: 100 +explain (verbose, costs off) +select unique1, unique2, generate_series(1,10) + from tenk1 order by unique2 limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT unique1, unique2, generate_series(1, 10) FROM tenk1 ORDER BY ..." +== 060 +-- truncate_limit: 100 +select unique1, unique2, generate_series(1,10) + from tenk1 order by unique2 limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2, generate_series(1, 10) FROM tenk1 ORDER BY unique2 LIMIT 7" +== 061 +-- truncate_limit: 100 +explain (verbose, costs off) +select unique1, unique2, generate_series(1,10) + from tenk1 order by tenthous limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT unique1, unique2, generate_series(1, 10) FROM tenk1 ORDER BY ..." +== 062 +-- truncate_limit: 100 +select unique1, unique2, generate_series(1,10) + from tenk1 order by tenthous limit 7 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2, generate_series(1, 10) FROM tenk1 ORDER BY tenthous LIMIT 7" +== 063 +-- truncate_limit: 100 +-- use of random() is to keep planner from folding the expressions together +explain (verbose, costs off) +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT generate_series(0, 2) AS s1, generate_series((random() * .1):..." +== 064 +-- truncate_limit: 100 +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(0, 2) AS s1, generate_series((random() * .1)::int, 2) AS s2" +== 065 +-- truncate_limit: 100 +explain (verbose, costs off) +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +order by s2 desc +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT generate_series(0, 2) AS s1, generate_series((random() * .1):..." +== 066 +-- truncate_limit: 100 +select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 +order by s2 desc +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(0, 2) AS s1, generate_series((random() * .1)::int, 2) AS s2 ORDER BY s2 DESC" +== 067 +-- truncate_limit: 100 +-- test for failure to set all aggregates' aggtranstype +explain (verbose, costs off) +select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2 + from tenk1 group by thousand order by thousand limit 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT sum(tenthous) AS s1, sum(tenthous) + (random() * 0) AS s2 FRO..." +== 068 +-- truncate_limit: 100 +select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2 + from tenk1 group by thousand order by thousand limit 3 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 GROUP BY thousand ORDER BY thousand LIMIT 3" +== 069 +-- truncate_limit: 100 +|-- +-- FETCH FIRST +-- Check the WITH TIES clause +|-- + +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 2 ROW WITH TIES +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST 2 ROWS WITH TIES" +== 070 +-- truncate_limit: 100 +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST ROWS WITH TIES +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST 1 ROWS WITH TIES" +== 071 +-- truncate_limit: 100 +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 1 ROW WITH TIES +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST 1 ROWS WITH TIES" +== 072 +-- truncate_limit: 100 +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 2 ROW ONLY +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand LIMIT 2" +== 073 +-- truncate_limit: 100 +-- SKIP LOCKED and WITH TIES are incompatible +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 1 ROW WITH TIES FOR UPDATE SKIP LOCKED +-- +ERROR: SKIP LOCKED and WITH TIES options cannot be used together +FILENAME: gram.y +FUNCNAME: insertSelectOptions +== 074 +-- truncate_limit: 100 +-- should fail +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 50 + FETCH FIRST 2 ROW WITH TIES +-- +ERROR: WITH TIES cannot be specified without ORDER BY clause +FILENAME: gram.y +FUNCNAME: insertSelectOptions +== 075 +-- truncate_limit: 100 +-- test ruleutils +CREATE VIEW limit_thousand_v_1 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST 5 ROWS WITH TIES OFFSET 10 +-- +TABLE: name="limit_thousand_v_1" schema="" table="limit_thousand_v_1" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW limit_thousand_v_1 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousan..." +== 076 +-- truncate_limit: 100 +CREATE VIEW limit_thousand_v_2 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand OFFSET 10 FETCH FIRST 5 ROWS ONLY +-- +TABLE: name="limit_thousand_v_2" schema="" table="limit_thousand_v_2" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW limit_thousand_v_2 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousan..." +== 077 +-- truncate_limit: 100 +CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST NULL ROWS WITH TIES +-- +TABLE: name="limit_thousand_v_3" schema="" table="limit_thousand_v_3" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousan..." +== 078 +-- truncate_limit: 100 +-- fails +CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST (NULL+1) ROWS WITH TIES +-- +TABLE: name="limit_thousand_v_3" schema="" table="limit_thousand_v_3" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousan..." +== 079 +-- truncate_limit: 100 +CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST (5::bigint) ROWS WITH TIES +-- +TABLE: name="limit_thousand_v_4" schema="" table="limit_thousand_v_4" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousan..." +== 080 +-- truncate_limit: 100 +CREATE VIEW limit_thousand_v_5 AS SELECT thousand FROM onek WHERE thousand < 995 + ORDER BY thousand FETCH FIRST NULL ROWS ONLY +-- +TABLE: name="limit_thousand_v_5" schema="" table="limit_thousand_v_5" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="thousand" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW limit_thousand_v_5 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousan..." diff --git a/parser/testdata/summary_truncate/postgres_regress/line.metadata.json b/parser/testdata/summary_truncate/postgres_regress/line.metadata.json new file mode 100644 index 0000000..bfeb57a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/line.metadata.json @@ -0,0 +1,39 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/line.test b/parser/testdata/summary_truncate/postgres_regress/line.test new file mode 100644 index 0000000..61f7138 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/line.test @@ -0,0 +1,282 @@ +== 001 +-- truncate_limit: 100 +|-- +-- LINE +-- Infinite lines +|-- + +--DROP TABLE LINE_TBL; +CREATE TABLE LINE_TBL (s line) +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE line_tbl (s line)" +== 002 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{0,-1,5}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{0,-1,5}')" +== 003 +-- truncate_limit: 100 +-- A == 0 +INSERT INTO LINE_TBL VALUES ('{1,0,5}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{1,0,5}')" +== 004 +-- truncate_limit: 100 +-- B == 0 +INSERT INTO LINE_TBL VALUES ('{0,3,0}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{0,3,0}')" +== 005 +-- truncate_limit: 100 +-- A == C == 0 +INSERT INTO LINE_TBL VALUES (' (0,0), (6,6)') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES (' (0,0), (6,6)')" +== 006 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('10,-10 ,-5,-4') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('10,-10 ,-5,-4')" +== 007 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('[-1e6,2e2,3e5, -4e1]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('[-1e6,2e2,3e5, -4e1]')" +== 008 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{3,NaN,5}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{3,NaN,5}')" +== 009 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{NaN,NaN,NaN}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{NaN,NaN,NaN}')" +== 010 +-- truncate_limit: 100 +-- horizontal +INSERT INTO LINE_TBL VALUES ('[(1,3),(2,3)]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('[(1,3),(2,3)]')" +== 011 +-- truncate_limit: 100 +-- vertical +INSERT INTO LINE_TBL VALUES (line(point '(3,1)', point '(3,2)')) +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +FUNCTION: name="line" function="line" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES (line( point '(3,1)', point '(3,2)'))" +== 012 +-- truncate_limit: 100 +-- bad values for parser testing +INSERT INTO LINE_TBL VALUES ('{}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{}')" +== 013 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{0') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{0')" +== 014 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{0,0}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{0,0}')" +== 015 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{0,0,1') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{0,0,1')" +== 016 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{0,0,1}') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{0,0,1}')" +== 017 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('{0,0,1} x') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('{0,0,1} x')" +== 018 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('(3asdf,2 ,3,4r2)')" +== 019 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('[1,2,3, 4') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('[1,2,3, 4')" +== 020 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('[(,2),(3,4)]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('[(,2),(3,4)]')" +== 021 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('[(1,2),(3,4)')" +== 022 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES ('[(1,2),(1,2)]') +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES ('[(1,2),(1,2)]')" +== 023 +-- truncate_limit: 100 +INSERT INTO LINE_TBL VALUES (line(point '(1,0)', point '(1,0)')) +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=DML +FUNCTION: name="line" function="line" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO line_tbl VALUES (line( point '(1,0)', point '(1,0)'))" +== 024 +-- truncate_limit: 100 +select * from LINE_TBL +-- +TABLE: name="line_tbl" schema="" table="line_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM line_tbl" +== 025 +-- truncate_limit: 100 +select '{nan, 1, nan}'::line = '{nan, 1, nan}'::line as true, + '{nan, 1, nan}'::line = '{nan, 2, nan}'::line as false +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 026 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('{1, 1}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{1, 1}', 'line')" +== 027 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('{1, 1}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{1, 1}', 'line')" +== 028 +-- truncate_limit: 100 +SELECT pg_input_is_valid('{0, 0, 0}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{0, 0, 0}', 'line')" +== 029 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('{0, 0, 0}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{0, 0, 0}', 'line')" +== 030 +-- truncate_limit: 100 +SELECT pg_input_is_valid('{1, 1, a}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{1, 1, a}', 'line')" +== 031 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('{1, 1, a}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{1, 1, a}', 'line')" +== 032 +-- truncate_limit: 100 +SELECT pg_input_is_valid('{1, 1, 1e400}', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{1, 1, 1e400}', 'line')" +== 033 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('{1, 1, 1e400}', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{1, 1, 1e400}', 'line')" +== 034 +-- truncate_limit: 100 +SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line')" +== 035 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(1, 1), (1, 1e400)', 'line') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(1, 1), (1, 1e400)', 'line')" diff --git a/parser/testdata/summary_truncate/postgres_regress/lock.metadata.json b/parser/testdata/summary_truncate/postgres_regress/lock.metadata.json new file mode 100644 index 0000000..507be8d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/lock.metadata.json @@ -0,0 +1,135 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/lock.test b/parser/testdata/summary_truncate/postgres_regress/lock.test new file mode 100644 index 0000000..b197969 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/lock.test @@ -0,0 +1,986 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test the LOCK statement +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +-- Setup +CREATE SCHEMA lock_schema1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA lock_schema1" +== 002 +-- truncate_limit: 100 +SET search_path = lock_schema1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO lock_schema1" +== 003 +-- truncate_limit: 100 +CREATE TABLE lock_tbl1 (a BIGINT) +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lock_tbl1 (a bigint)" +== 004 +-- truncate_limit: 100 +CREATE TABLE lock_tbl1a (a BIGINT) +-- +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lock_tbl1a (a bigint)" +== 005 +-- truncate_limit: 100 +CREATE VIEW lock_view1 AS SELECT * FROM lock_tbl1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view1 AS SELECT * FROM lock_tbl1" +== 006 +-- truncate_limit: 100 +CREATE VIEW lock_view2(a,b) AS SELECT * FROM lock_tbl1, lock_tbl1a +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view2 (a, b) AS SELECT * FROM lock_tbl1, lock_tbl1a" +== 007 +-- truncate_limit: 100 +CREATE VIEW lock_view3 AS SELECT * from lock_view2 +-- +TABLE: name="lock_view3" schema="" table="lock_view3" ctx=DDL +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view3 AS SELECT * FROM lock_view2" +== 008 +-- truncate_limit: 100 +CREATE VIEW lock_view4 AS SELECT (select a from lock_tbl1a limit 1) from lock_tbl1 +-- +TABLE: name="lock_view4" schema="" table="lock_view4" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view4 AS SELECT (SELECT a FROM lock_tbl1a LIMIT 1) FROM lock_tbl1" +== 009 +-- truncate_limit: 100 +CREATE VIEW lock_view5 AS SELECT * from lock_tbl1 where a in (select * from lock_tbl1a) +-- +TABLE: name="lock_view5" schema="" table="lock_view5" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view5 AS SELECT * FROM lock_tbl1 WHERE a IN (SELECT * FROM lock_tbl1a)" +== 010 +-- truncate_limit: 100 +CREATE VIEW lock_view6 AS SELECT * from (select * from lock_tbl1) sub +-- +TABLE: name="lock_view6" schema="" table="lock_view6" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view6 AS SELECT * FROM (SELECT * FROM lock_tbl1) sub" +== 011 +-- truncate_limit: 100 +CREATE ROLE regress_rol_lock1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rol_lock1" +== 012 +-- truncate_limit: 100 +ALTER ROLE regress_rol_lock1 SET search_path = lock_schema1 +-- +STMT: AlterRoleSetStmt +TRUNCATED: "ALTER ROLE regress_rol_lock1 SET search_path TO lock_schema1" +== 013 +-- truncate_limit: 100 +GRANT USAGE ON SCHEMA lock_schema1 TO regress_rol_lock1 +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON SCHEMA lock_schema1 TO regress_rol_lock1" +== 014 +-- truncate_limit: 100 +-- Try all valid lock options; also try omitting the optional TABLE keyword. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 015 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE" +== 016 +-- truncate_limit: 100 +LOCK lock_tbl1 IN ROW SHARE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN ROW SHARE MODE" +== 017 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE" +== 018 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN SHARE UPDATE EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN SHARE UPDATE EXCLUSIVE MODE" +== 019 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN SHARE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN SHARE MODE" +== 020 +-- truncate_limit: 100 +LOCK lock_tbl1 IN SHARE ROW EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN SHARE ROW EXCLUSIVE MODE" +== 021 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE" +== 022 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1" +== 023 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 024 +-- truncate_limit: 100 +-- Try using NOWAIT along with valid options. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 025 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE NOWAIT" +== 026 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN ROW SHARE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN ROW SHARE MODE NOWAIT" +== 027 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE NOWAIT" +== 028 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN SHARE UPDATE EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN SHARE UPDATE EXCLUSIVE MODE NOWAIT" +== 029 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN SHARE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN SHARE MODE NOWAIT" +== 030 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN SHARE ROW EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN SHARE ROW EXCLUSIVE MODE NOWAIT" +== 031 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE NOWAIT" +== 032 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE NOWAIT +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1 NOWAIT" +== 033 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 034 +-- truncate_limit: 100 +-- Verify that we can lock views. +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 035 +-- truncate_limit: 100 +LOCK TABLE lock_view1 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view1 IN EXCLUSIVE MODE" +== 036 +-- truncate_limit: 100 +-- lock_view1 and lock_tbl1 are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 037 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 038 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 039 +-- truncate_limit: 100 +LOCK TABLE lock_view2 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view2 IN EXCLUSIVE MODE" +== 040 +-- truncate_limit: 100 +-- lock_view1, lock_tbl1, and lock_tbl1a are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 041 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 042 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 043 +-- truncate_limit: 100 +LOCK TABLE lock_view3 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view3" schema="" table="lock_view3" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view3 IN EXCLUSIVE MODE" +== 044 +-- truncate_limit: 100 +-- lock_view3, lock_view2, lock_tbl1, and lock_tbl1a are locked recursively. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 045 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 046 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 047 +-- truncate_limit: 100 +LOCK TABLE lock_view4 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view4" schema="" table="lock_view4" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view4 IN EXCLUSIVE MODE" +== 048 +-- truncate_limit: 100 +-- lock_view4, lock_tbl1, and lock_tbl1a are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 049 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 050 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 051 +-- truncate_limit: 100 +LOCK TABLE lock_view5 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view5" schema="" table="lock_view5" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view5 IN EXCLUSIVE MODE" +== 052 +-- truncate_limit: 100 +-- lock_view5, lock_tbl1, and lock_tbl1a are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 053 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 054 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 055 +-- truncate_limit: 100 +LOCK TABLE lock_view6 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view6" schema="" table="lock_view6" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view6 IN EXCLUSIVE MODE" +== 056 +-- truncate_limit: 100 +-- lock_view6 an lock_tbl1 are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 057 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 058 +-- truncate_limit: 100 +-- Verify that we cope with infinite recursion in view definitions. +CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3 +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +TABLE: name="lock_view3" schema="" table="lock_view3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW lock_view2 AS SELECT * FROM lock_view3" +== 059 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 060 +-- truncate_limit: 100 +LOCK TABLE lock_view2 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view2 IN EXCLUSIVE MODE" +== 061 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 062 +-- truncate_limit: 100 +CREATE VIEW lock_view7 AS SELECT * from lock_view2 +-- +TABLE: name="lock_view7" schema="" table="lock_view7" ctx=DDL +TABLE: name="lock_view2" schema="" table="lock_view2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view7 AS SELECT * FROM lock_view2" +== 063 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 064 +-- truncate_limit: 100 +LOCK TABLE lock_view7 IN EXCLUSIVE MODE +-- +TABLE: name="lock_view7" schema="" table="lock_view7" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view7 IN EXCLUSIVE MODE" +== 065 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 066 +-- truncate_limit: 100 +-- Verify that we can lock a table with inheritance children. +CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1) +-- +TABLE: name="lock_tbl2" schema="" table="lock_tbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lock_tbl2 (b bigint) INHERITS (lock_tbl1)" +== 067 +-- truncate_limit: 100 +CREATE TABLE lock_tbl3 () INHERITS (lock_tbl2) +-- +TABLE: name="lock_tbl3" schema="" table="lock_tbl3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lock_tbl3 () INHERITS (lock_tbl2)" +== 068 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 069 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 * IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1" +== 070 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 071 +-- truncate_limit: 100 +-- Child tables are locked without granting explicit permission to do so as +-- long as we have permission to lock the parent. +GRANT UPDATE ON TABLE lock_tbl1 TO regress_rol_lock1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON lock_tbl1 TO regress_rol_lock1" +== 072 +-- truncate_limit: 100 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_lock1" +== 073 +-- truncate_limit: 100 +-- fail when child locked directly +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 074 +-- truncate_limit: 100 +LOCK TABLE lock_tbl2 +-- +TABLE: name="lock_tbl2" schema="" table="lock_tbl2" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl2" +== 075 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 076 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 077 +-- truncate_limit: 100 +LOCK TABLE lock_tbl1 * IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_tbl1" +== 078 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 079 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 080 +-- truncate_limit: 100 +LOCK TABLE ONLY lock_tbl1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE ONLY lock_tbl1" +== 081 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 082 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 083 +-- truncate_limit: 100 +REVOKE UPDATE ON TABLE lock_tbl1 FROM regress_rol_lock1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE update ON lock_tbl1 FROM regress_rol_lock1" +== 084 +-- truncate_limit: 100 +-- Tables referred to by views are locked without explicit permission to do so +-- as long as we have permission to lock the view itself. +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_lock1" +== 085 +-- truncate_limit: 100 +-- fail without permissions on the view +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 086 +-- truncate_limit: 100 +LOCK TABLE lock_view1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view1" +== 087 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 088 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 089 +-- truncate_limit: 100 +GRANT UPDATE ON TABLE lock_view1 TO regress_rol_lock1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON lock_view1 TO regress_rol_lock1" +== 090 +-- truncate_limit: 100 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_lock1" +== 091 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 092 +-- truncate_limit: 100 +LOCK TABLE lock_view1 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view1" +== 093 +-- truncate_limit: 100 +-- lock_view1 and lock_tbl1 (plus children lock_tbl2 and lock_tbl3) are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'AccessExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 094 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 095 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 096 +-- truncate_limit: 100 +REVOKE UPDATE ON TABLE lock_view1 FROM regress_rol_lock1 +-- +TABLE: name="lock_view1" schema="" table="lock_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE update ON lock_view1 FROM regress_rol_lock1" +== 097 +-- truncate_limit: 100 +-- Tables referred to by security invoker views require explicit permission to +-- be locked. +CREATE VIEW lock_view8 WITH (security_invoker) AS SELECT * FROM lock_tbl1 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW lock_view8 WITH (security_invoker) AS SELECT * FROM lock_tbl1" +== 098 +-- truncate_limit: 100 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_lock1" +== 099 +-- truncate_limit: 100 +-- fail without permissions on the view +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 100 +-- truncate_limit: 100 +LOCK TABLE lock_view8 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view8" +== 101 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 102 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 103 +-- truncate_limit: 100 +GRANT UPDATE ON TABLE lock_view8 TO regress_rol_lock1 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON lock_view8 TO regress_rol_lock1" +== 104 +-- truncate_limit: 100 +SET ROLE regress_rol_lock1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rol_lock1" +== 105 +-- truncate_limit: 100 +-- fail without permissions on the table referenced by the view +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 106 +-- truncate_limit: 100 +LOCK TABLE lock_view8 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view8" +== 107 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 108 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 109 +-- truncate_limit: 100 +GRANT UPDATE ON TABLE lock_tbl1 TO regress_rol_lock1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON lock_tbl1 TO regress_rol_lock1" +== 110 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 111 +-- truncate_limit: 100 +LOCK TABLE lock_view8 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE lock_view8" +== 112 +-- truncate_limit: 100 +-- lock_view8 and lock_tbl1 (plus children lock_tbl2 and lock_tbl3) are locked. +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'AccessExclusiveLock' + order by relname +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "l"="pg_locks" +FILTER: schema="" table="l" column="relation" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_locks l, pg_class c WHERE ... ORDER BY relname" +== 113 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 114 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 115 +-- truncate_limit: 100 +REVOKE UPDATE ON TABLE lock_view8 FROM regress_rol_lock1 +-- +TABLE: name="lock_view8" schema="" table="lock_view8" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE update ON lock_view8 FROM regress_rol_lock1" +== 116 +-- truncate_limit: 100 +|-- +-- Clean up +|-- +DROP VIEW lock_view8 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW lock_view8" +== 117 +-- truncate_limit: 100 +DROP VIEW lock_view7 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW lock_view7" +== 118 +-- truncate_limit: 100 +DROP VIEW lock_view6 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW lock_view6" +== 119 +-- truncate_limit: 100 +DROP VIEW lock_view5 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW lock_view5" +== 120 +-- truncate_limit: 100 +DROP VIEW lock_view4 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW lock_view4" +== 121 +-- truncate_limit: 100 +DROP VIEW lock_view3 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW lock_view3 CASCADE" +== 122 +-- truncate_limit: 100 +DROP VIEW lock_view1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW lock_view1" +== 123 +-- truncate_limit: 100 +DROP TABLE lock_tbl3 +-- +TABLE: name="lock_tbl3" schema="" table="lock_tbl3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lock_tbl3" +== 124 +-- truncate_limit: 100 +DROP TABLE lock_tbl2 +-- +TABLE: name="lock_tbl2" schema="" table="lock_tbl2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lock_tbl2" +== 125 +-- truncate_limit: 100 +DROP TABLE lock_tbl1 +-- +TABLE: name="lock_tbl1" schema="" table="lock_tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lock_tbl1" +== 126 +-- truncate_limit: 100 +DROP TABLE lock_tbl1a +-- +TABLE: name="lock_tbl1a" schema="" table="lock_tbl1a" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lock_tbl1a" +== 127 +-- truncate_limit: 100 +DROP SCHEMA lock_schema1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA lock_schema1 CASCADE" +== 128 +-- truncate_limit: 100 +DROP ROLE regress_rol_lock1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_rol_lock1" +== 129 +-- truncate_limit: 100 +-- atomic ops tests +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 130 +-- truncate_limit: 100 +CREATE FUNCTION test_atomic_ops() + RETURNS bool + AS :'regresslib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 59 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 131 +-- truncate_limit: 100 +SELECT test_atomic_ops() +-- +FUNCTION: name="test_atomic_ops" function="test_atomic_ops" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_atomic_ops()" diff --git a/parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json b/parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json new file mode 100644 index 0000000..e71b2c2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json @@ -0,0 +1,20 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/lseg.test b/parser/testdata/summary_truncate/postgres_regress/lseg.test new file mode 100644 index 0000000..e7be2ec --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/lseg.test @@ -0,0 +1,139 @@ +== 001 +-- truncate_limit: 100 +|-- +-- LSEG +-- Line segments +|-- + +--DROP TABLE LSEG_TBL; +CREATE TABLE LSEG_TBL (s lseg) +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lseg_tbl (s lseg)" +== 002 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[(1,2),(3,4)]')" +== 003 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('(0,0),(6,6)') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('(0,0),(6,6)')" +== 004 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('10,-10 ,-3,-4') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('10,-10 ,-3,-4')" +== 005 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('[-1e6,2e2,3e5, -4e1]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[-1e6,2e2,3e5, -4e1]')" +== 006 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES (lseg(point(11, 22), point(33,44))) +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +FUNCTION: name="lseg" function="lseg" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES (lseg(point(11, 22), point(33, 44)))" +== 007 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('[(-10,2),(-10,3)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[(-10,2),(-10,3)]')" +== 008 +-- truncate_limit: 100 +-- vertical +INSERT INTO LSEG_TBL VALUES ('[(0,-20),(30,-20)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[(0,-20),(30,-20)]')" +== 009 +-- truncate_limit: 100 +-- horizontal +INSERT INTO LSEG_TBL VALUES ('[(NaN,1),(NaN,90)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[(NaN,1),(NaN,90)]')" +== 010 +-- truncate_limit: 100 +-- NaN + +-- bad values for parser testing +INSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('(3asdf,2 ,3,4r2)')" +== 011 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('[1,2,3, 4') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[1,2,3, 4')" +== 012 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('[(,2),(3,4)]') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[(,2),(3,4)]')" +== 013 +-- truncate_limit: 100 +INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)') +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lseg_tbl VALUES ('[(1,2),(3,4)')" +== 014 +-- truncate_limit: 100 +select * from LSEG_TBL +-- +TABLE: name="lseg_tbl" schema="" table="lseg_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM lseg_tbl" +== 015 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('[(1,2),(3)]', 'lseg') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('[(1,2),(3)]', 'lseg')" +== 016 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'lseg') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'lseg')" diff --git a/parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json b/parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json new file mode 100644 index 0000000..bfeb57a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json @@ -0,0 +1,39 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/macaddr.test b/parser/testdata/summary_truncate/postgres_regress/macaddr.test new file mode 100644 index 0000000..9a866fc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/macaddr.test @@ -0,0 +1,285 @@ +== 001 +-- truncate_limit: 100 +|-- +-- macaddr +|-- + +CREATE TABLE macaddr_data (a int, b macaddr) +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE macaddr_data (a int, b macaddr)" +== 002 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (1, '08:00:2b:01:02:03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (1, '08:00:2b:01:02:03')" +== 003 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (2, '08-00-2b-01-02-03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (2, '08-00-2b-01-02-03')" +== 004 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (3, '08002b:010203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (3, '08002b:010203')" +== 005 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (4, '08002b-010203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (4, '08002b-010203')" +== 006 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (5, '0800.2b01.0203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (5, '0800.2b01.0203')" +== 007 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (6, '0800-2b01-0203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (6, '0800-2b01-0203')" +== 008 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (7, '08002b010203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (7, '08002b010203')" +== 009 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (8, '0800:2b01:0203') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (8, '0800:2b01:0203')" +== 010 +-- truncate_limit: 100 +-- invalid +INSERT INTO macaddr_data VALUES (9, 'not even close') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (9, 'not even close')" +== 011 +-- truncate_limit: 100 +-- invalid + +INSERT INTO macaddr_data VALUES (10, '08:00:2b:01:02:04') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (10, '08:00:2b:01:02:04')" +== 012 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (11, '08:00:2b:01:02:02') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (11, '08:00:2b:01:02:02')" +== 013 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (12, '08:00:2a:01:02:03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (12, '08:00:2a:01:02:03')" +== 014 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (13, '08:00:2c:01:02:03') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (13, '08:00:2c:01:02:03')" +== 015 +-- truncate_limit: 100 +INSERT INTO macaddr_data VALUES (14, '08:00:2a:01:02:04') +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr_data VALUES (14, '08:00:2a:01:02:04')" +== 016 +-- truncate_limit: 100 +SELECT * FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM macaddr_data" +== 017 +-- truncate_limit: 100 +CREATE INDEX macaddr_data_btree ON macaddr_data USING btree (b) +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX macaddr_data_btree ON macaddr_data USING btree (b)" +== 018 +-- truncate_limit: 100 +CREATE INDEX macaddr_data_hash ON macaddr_data USING hash (b) +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX macaddr_data_hash ON macaddr_data USING hash (b)" +== 019 +-- truncate_limit: 100 +SELECT a, b, trunc(b) FROM macaddr_data ORDER BY 2, 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, trunc(b) FROM macaddr_data ORDER BY 2, 1" +== 020 +-- truncate_limit: 100 +SELECT b < '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b < '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1" +== 021 +-- truncate_limit: 100 +-- true +SELECT b > '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b > '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1" +== 022 +-- truncate_limit: 100 +-- false +SELECT b > '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b > '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1" +== 023 +-- truncate_limit: 100 +-- false +SELECT b <= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b <= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1" +== 024 +-- truncate_limit: 100 +-- true +SELECT b >= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b >= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1" +== 025 +-- truncate_limit: 100 +-- false +SELECT b = '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b = '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1" +== 026 +-- truncate_limit: 100 +-- true +SELECT b <> '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b <> '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1" +== 027 +-- truncate_limit: 100 +-- true +SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1 +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1" +== 028 +-- truncate_limit: 100 +-- false + +SELECT ~b FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ~ b FROM macaddr_data" +== 029 +-- truncate_limit: 100 +SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data" +== 030 +-- truncate_limit: 100 +SELECT b | '01:02:03:04:05:06' FROM macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b | '01:02:03:04:05:06' FROM macaddr_data" +== 031 +-- truncate_limit: 100 +DROP TABLE macaddr_data +-- +TABLE: name="macaddr_data" schema="" table="macaddr_data" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE macaddr_data" +== 032 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('08:00:2b:01:02:ZZ', 'macaddr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('08:00:2b:01:02:ZZ', 'macaddr')" +== 033 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:ZZ', 'macaddr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('08:00:2b:01:02:ZZ', 'macaddr')" +== 034 +-- truncate_limit: 100 +SELECT pg_input_is_valid('08:00:2b:01:02:', 'macaddr') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('08:00:2b:01:02:', 'macaddr')" +== 035 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:', 'macaddr') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('08:00:2b:01:02:', 'macaddr')" diff --git a/parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json new file mode 100644 index 0000000..fb72ee9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json @@ -0,0 +1,75 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/macaddr8.test b/parser/testdata/summary_truncate/postgres_regress/macaddr8.test new file mode 100644 index 0000000..ed76ca3 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/macaddr8.test @@ -0,0 +1,560 @@ +== 001 +-- truncate_limit: 100 +|-- +-- macaddr8 +|-- + +-- test various cases of valid and invalid input +-- valid +SELECT '08:00:2b:01:02:03 '::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00:2b:01:02:03 '::macaddr8" +== 002 +-- truncate_limit: 100 +SELECT ' 08:00:2b:01:02:03 '::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 08:00:2b:01:02:03 '::macaddr8" +== 003 +-- truncate_limit: 100 +SELECT ' 08:00:2b:01:02:03'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 08:00:2b:01:02:03'::macaddr8" +== 004 +-- truncate_limit: 100 +SELECT '08:00:2b:01:02:03:04:05 '::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00:2b:01:02:03:04:05 '::macaddr8" +== 005 +-- truncate_limit: 100 +SELECT ' 08:00:2b:01:02:03:04:05 '::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 08:00:2b:01:02:03:04:05 '::macaddr8" +== 006 +-- truncate_limit: 100 +SELECT ' 08:00:2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 08:00:2b:01:02:03:04:05'::macaddr8" +== 007 +-- truncate_limit: 100 +SELECT '123 08:00:2b:01:02:03'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123 08:00:2b:01:02:03'::macaddr8" +== 008 +-- truncate_limit: 100 +-- invalid +SELECT '08:00:2b:01:02:03 123'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00:2b:01:02:03 123'::macaddr8" +== 009 +-- truncate_limit: 100 +-- invalid +SELECT '123 08:00:2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123 08:00:2b:01:02:03:04:05'::macaddr8" +== 010 +-- truncate_limit: 100 +-- invalid +SELECT '08:00:2b:01:02:03:04:05 123'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00:2b:01:02:03:04:05 123'::macaddr8" +== 011 +-- truncate_limit: 100 +-- invalid +SELECT '08:00:2b:01:02:03:04:05:06:07'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00:2b:01:02:03:04:05:06:07'::macaddr8" +== 012 +-- truncate_limit: 100 +-- invalid +SELECT '08-00-2b-01-02-03-04-05-06-07'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08-00-2b-01-02-03-04-05-06-07'::macaddr8" +== 013 +-- truncate_limit: 100 +-- invalid +SELECT '08002b:01020304050607'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08002b:01020304050607'::macaddr8" +== 014 +-- truncate_limit: 100 +-- invalid +SELECT '08002b01020304050607'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08002b01020304050607'::macaddr8" +== 015 +-- truncate_limit: 100 +-- invalid +SELECT '0z002b0102030405'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0z002b0102030405'::macaddr8" +== 016 +-- truncate_limit: 100 +-- invalid +SELECT '08002b010203xyza'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08002b010203xyza'::macaddr8" +== 017 +-- truncate_limit: 100 +-- invalid + +SELECT '08:00-2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00-2b:01:02:03:04:05'::macaddr8" +== 018 +-- truncate_limit: 100 +-- invalid +SELECT '08:00-2b:01:02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00-2b:01:02:03:04:05'::macaddr8" +== 019 +-- truncate_limit: 100 +-- invalid +SELECT '08:00:2b:01.02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00:2b:01.02:03:04:05'::macaddr8" +== 020 +-- truncate_limit: 100 +-- invalid +SELECT '08:00:2b:01.02:03:04:05'::macaddr8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '08:00:2b:01.02:03:04:05'::macaddr8" +== 021 +-- truncate_limit: 100 +-- invalid + +-- test converting a MAC address to modified EUI-64 for inclusion +-- in an ipv6 address +SELECT macaddr8_set7bit('00:08:2b:01:02:03'::macaddr8) +-- +FUNCTION: name="macaddr8_set7bit" function="macaddr8_set7bit" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT macaddr8_set7bit('00:08:2b:01:02:03'::macaddr8)" +== 022 +-- truncate_limit: 100 +CREATE TABLE macaddr8_data (a int, b macaddr8) +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE macaddr8_data (a int, b macaddr8)" +== 023 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (1, '08:00:2b:01:02:03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (1, '08:00:2b:01:02:03')" +== 024 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (2, '08-00-2b-01-02-03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (2, '08-00-2b-01-02-03')" +== 025 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (3, '08002b:010203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (3, '08002b:010203')" +== 026 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (4, '08002b-010203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (4, '08002b-010203')" +== 027 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (5, '0800.2b01.0203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (5, '0800.2b01.0203')" +== 028 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (6, '0800-2b01-0203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (6, '0800-2b01-0203')" +== 029 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (7, '08002b010203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (7, '08002b010203')" +== 030 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (8, '0800:2b01:0203') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (8, '0800:2b01:0203')" +== 031 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (9, 'not even close') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (9, 'not even close')" +== 032 +-- truncate_limit: 100 +-- invalid + +INSERT INTO macaddr8_data VALUES (10, '08:00:2b:01:02:04') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (10, '08:00:2b:01:02:04')" +== 033 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (11, '08:00:2b:01:02:02') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (11, '08:00:2b:01:02:02')" +== 034 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (12, '08:00:2a:01:02:03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (12, '08:00:2a:01:02:03')" +== 035 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (13, '08:00:2c:01:02:03') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (13, '08:00:2c:01:02:03')" +== 036 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (14, '08:00:2a:01:02:04') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (14, '08:00:2a:01:02:04')" +== 037 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (15, '08:00:2b:01:02:03:04:05') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (15, '08:00:2b:01:02:03:04:05')" +== 038 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (16, '08-00-2b-01-02-03-04-05') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (16, '08-00-2b-01-02-03-04-05')" +== 039 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (17, '08002b:0102030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (17, '08002b:0102030405')" +== 040 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (18, '08002b-0102030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (18, '08002b-0102030405')" +== 041 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (19, '0800.2b01.0203.0405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (19, '0800.2b01.0203.0405')" +== 042 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (20, '08002b01:02030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (20, '08002b01:02030405')" +== 043 +-- truncate_limit: 100 +INSERT INTO macaddr8_data VALUES (21, '08002b0102030405') +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO macaddr8_data VALUES (21, '08002b0102030405')" +== 044 +-- truncate_limit: 100 +SELECT * FROM macaddr8_data ORDER BY 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM macaddr8_data ORDER BY 1" +== 045 +-- truncate_limit: 100 +CREATE INDEX macaddr8_data_btree ON macaddr8_data USING btree (b) +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX macaddr8_data_btree ON macaddr8_data USING btree (b)" +== 046 +-- truncate_limit: 100 +CREATE INDEX macaddr8_data_hash ON macaddr8_data USING hash (b) +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX macaddr8_data_hash ON macaddr8_data USING hash (b)" +== 047 +-- truncate_limit: 100 +SELECT a, b, trunc(b) FROM macaddr8_data ORDER BY 2, 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, trunc(b) FROM macaddr8_data ORDER BY 2, 1" +== 048 +-- truncate_limit: 100 +SELECT b < '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b < '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1" +== 049 +-- truncate_limit: 100 +-- true +SELECT b > '08:00:2b:ff:fe:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b > '08:00:2b:ff:fe:01:02:04' FROM macaddr8_data WHERE a = 1" +== 050 +-- truncate_limit: 100 +-- false +SELECT b > '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b > '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1" +== 051 +-- truncate_limit: 100 +-- false +SELECT b::macaddr <= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b::macaddr <= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1" +== 052 +-- truncate_limit: 100 +-- true +SELECT b::macaddr >= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b::macaddr >= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1" +== 053 +-- truncate_limit: 100 +-- false +SELECT b = '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b = '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1" +== 054 +-- truncate_limit: 100 +-- true +SELECT b::macaddr <> '08:00:2b:01:02:04'::macaddr FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b::macaddr <> '08:00:2b:01:02:04'::macaddr FROM macaddr8_data WHERE a = 1" +== 055 +-- truncate_limit: 100 +-- true +SELECT b::macaddr <> '08:00:2b:01:02:03'::macaddr FROM macaddr8_data WHERE a = 1 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b::macaddr <> '08:00:2b:01:02:03'::macaddr FROM macaddr8_data WHERE a = 1" +== 056 +-- truncate_limit: 100 +-- false + +SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15" +== 057 +-- truncate_limit: 100 +-- true +SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15" +== 058 +-- truncate_limit: 100 +-- false +SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15" +== 059 +-- truncate_limit: 100 +-- false +SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15" +== 060 +-- truncate_limit: 100 +-- true +SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15" +== 061 +-- truncate_limit: 100 +-- false +SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15" +== 062 +-- truncate_limit: 100 +-- true +SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15" +== 063 +-- truncate_limit: 100 +-- true +SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15 +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15" +== 064 +-- truncate_limit: 100 +-- false + +SELECT ~b FROM macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ~ b FROM macaddr8_data" +== 065 +-- truncate_limit: 100 +SELECT b & '00:00:00:ff:ff:ff' FROM macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b & '00:00:00:ff:ff:ff' FROM macaddr8_data" +== 066 +-- truncate_limit: 100 +SELECT b | '01:02:03:04:05:06' FROM macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b | '01:02:03:04:05:06' FROM macaddr8_data" +== 067 +-- truncate_limit: 100 +DROP TABLE macaddr8_data +-- +TABLE: name="macaddr8_data" schema="" table="macaddr8_data" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE macaddr8_data" +== 068 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8')" +== 069 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:ZZ', 'macaddr8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:ZZ', 'macaddr8')" +== 070 +-- truncate_limit: 100 +SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8')" +== 071 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:', 'macaddr8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:', 'macaddr8')" diff --git a/parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json b/parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json new file mode 100644 index 0000000..e71b2c2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json @@ -0,0 +1,20 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/maintain_every.test b/parser/testdata/summary_truncate/postgres_regress/maintain_every.test new file mode 100644 index 0000000..1a061c6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/maintain_every.test @@ -0,0 +1,118 @@ +== 001 +-- truncate_limit: 100 +-- Test maintenance commands that visit every eligible relation. Run as a +-- non-superuser, to skip other users' tables. + +CREATE ROLE regress_maintain +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_maintain" +== 002 +-- truncate_limit: 100 +SET ROLE regress_maintain +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_maintain" +== 003 +-- truncate_limit: 100 +-- Test database-wide ANALYZE ("use_own_xacts" mode) setting relhassubclass=f +-- for non-partitioning inheritance, w/ ON COMMIT DELETE ROWS building an +-- empty index. +CREATE TEMP TABLE past_inh_db_other () +-- +TABLE: name="past_inh_db_other" schema="" table="past_inh_db_other" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE past_inh_db_other ()" +== 004 +-- truncate_limit: 100 +-- need 2 tables for "use_own_xacts" +CREATE TEMP TABLE past_inh_db_parent () ON COMMIT DELETE ROWS +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE past_inh_db_parent () ON COMMIT DELETE ROWS" +== 005 +-- truncate_limit: 100 +CREATE TEMP TABLE past_inh_db_child () INHERITS (past_inh_db_parent) +-- +TABLE: name="past_inh_db_child" schema="" table="past_inh_db_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE past_inh_db_child () INHERITS (past_inh_db_parent)" +== 006 +-- truncate_limit: 100 +CREATE INDEX ON past_inh_db_parent ((1)) +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON past_inh_db_parent USING btree ((1))" +== 007 +-- truncate_limit: 100 +ANALYZE past_inh_db_parent +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE past_inh_db_parent" +== 008 +-- truncate_limit: 100 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltuples, relhassubclass FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass" +== 009 +-- truncate_limit: 100 +DROP TABLE past_inh_db_child +-- +TABLE: name="past_inh_db_child" schema="" table="past_inh_db_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE past_inh_db_child" +== 010 +-- truncate_limit: 100 +SET client_min_messages = error +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO error" +== 011 +-- truncate_limit: 100 +-- hide WARNINGs for other users' tables +ANALYZE +-- +STMT: VacuumStmt +TRUNCATED: "ANALYZE" +== 012 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 013 +-- truncate_limit: 100 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltuples, relhassubclass FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass" +== 014 +-- truncate_limit: 100 +DROP TABLE past_inh_db_parent, past_inh_db_other +-- +TABLE: name="past_inh_db_parent" schema="" table="past_inh_db_parent" ctx=DDL +TABLE: name="past_inh_db_other" schema="" table="past_inh_db_other" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE past_inh_db_parent, past_inh_db_other" +== 015 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 016 +-- truncate_limit: 100 +DROP ROLE regress_maintain +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_maintain" diff --git a/parser/testdata/summary_truncate/postgres_regress/matview.metadata.json b/parser/testdata/summary_truncate/postgres_regress/matview.metadata.json new file mode 100644 index 0000000..784b93c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/matview.metadata.json @@ -0,0 +1,183 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/matview.test b/parser/testdata/summary_truncate/postgres_regress/matview.test new file mode 100644 index 0000000..3aada45 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/matview.test @@ -0,0 +1,1474 @@ +== 001 +-- truncate_limit: 100 +-- create a table to use as a basis for views and materialized views in various combinations +CREATE TABLE mvtest_t (id int NOT NULL PRIMARY KEY, type text NOT NULL, amt numeric NOT NULL) +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mvtest_t (id int NOT NULL PRIMARY KEY, type text NOT NULL, amt numeric NOT NULL)" +== 002 +-- truncate_limit: 100 +INSERT INTO mvtest_t VALUES + (1, 'x', 2), + (2, 'x', 3), + (3, 'y', 5), + (4, 'y', 7), + (5, 'z', 11) +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mvtest_t VALUES (1, 'x', 2), (2, 'x', 3), (3, 'y', 5), (4, 'y', 7), (5, 'z', 11)" +== 003 +-- truncate_limit: 100 +-- we want a view based on the table, too, since views present additional challenges +CREATE VIEW mvtest_tv AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type +-- +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=DDL +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mvtest_tv AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type" +== 004 +-- truncate_limit: 100 +SELECT * FROM mvtest_tv ORDER BY type +-- +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tv ORDER BY type" +== 005 +-- truncate_limit: 100 +-- create a materialized view with no data, and confirm correct behavior +EXPLAIN (costs off) + CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type WITH NO DATA +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mv..." +== 006 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type WITH NO DATA +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type..." +== 007 +-- truncate_limit: 100 +SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass" +== 008 +-- truncate_limit: 100 +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tm ORDER BY type" +== 009 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_tm +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_tm" +== 010 +-- truncate_limit: 100 +SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass" +== 011 +-- truncate_limit: 100 +CREATE UNIQUE INDEX mvtest_tm_type ON mvtest_tm (type) +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX mvtest_tm_type ON mvtest_tm USING btree (type)" +== 012 +-- truncate_limit: 100 +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tm ORDER BY type" +== 013 +-- truncate_limit: 100 +-- create various views +EXPLAIN (costs off) + CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=DDL +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type" +== 014 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=DDL +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type" +== 015 +-- truncate_limit: 100 +SELECT * FROM mvtest_tvm +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvm" +== 016 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_tmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=DDL +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_tmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tm" +== 017 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_tvmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tvm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_tvmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tvm" +== 018 +-- truncate_limit: 100 +CREATE UNIQUE INDEX mvtest_tvmm_expr ON mvtest_tvmm ((grandtot > 0)) +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX mvtest_tvmm_expr ON mvtest_tvmm USING btree ((grandtot > 0))" +== 019 +-- truncate_limit: 100 +CREATE UNIQUE INDEX mvtest_tvmm_pred ON mvtest_tvmm (grandtot) WHERE grandtot < 0 +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX mvtest_tvmm_pred ON mvtest_tvmm USING btree (grandtot) WHERE grandtot < 0" +== 020 +-- truncate_limit: 100 +CREATE VIEW mvtest_tvv AS SELECT sum(totamt) AS grandtot FROM mvtest_tv +-- +TABLE: name="mvtest_tvv" schema="" table="mvtest_tvv" ctx=DDL +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mvtest_tvv AS SELECT sum(totamt) AS grandtot FROM mvtest_tv" +== 021 +-- truncate_limit: 100 +EXPLAIN (costs off) + CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=DDL +TABLE: name="mvtest_tvv" schema="" table="mvtest_tvv" ctx=Select +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv" +== 022 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=DDL +TABLE: name="mvtest_tvv" schema="" table="mvtest_tvv" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv" +== 023 +-- truncate_limit: 100 +CREATE VIEW mvtest_tvvmv AS SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvmv" schema="" table="mvtest_tvvmv" ctx=DDL +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mvtest_tvvmv AS SELECT * FROM mvtest_tvvm" +== 024 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_bb AS SELECT * FROM mvtest_tvvmv +-- +TABLE: name="mvtest_bb" schema="" table="mvtest_bb" ctx=DDL +TABLE: name="mvtest_tvvmv" schema="" table="mvtest_tvvmv" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_bb AS SELECT * FROM mvtest_tvvmv" +== 025 +-- truncate_limit: 100 +CREATE INDEX mvtest_aa ON mvtest_bb (grandtot) +-- +TABLE: name="mvtest_bb" schema="" table="mvtest_bb" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX mvtest_aa ON mvtest_bb USING btree (grandtot)" +== 026 +-- truncate_limit: 100 +-- check that plans seem reasonable + +-- test schema behavior +CREATE SCHEMA mvtest_mvschema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA mvtest_mvschema" +== 027 +-- truncate_limit: 100 +ALTER MATERIALIZED VIEW mvtest_tvm SET SCHEMA mvtest_mvschema +-- +STMT: AlterObjectSchemaStmt +TRUNCATED: "ALTER MATERIALIZED VIEW mvtest_tvm SET SCHEMA mvtest_mvschema" +== 028 +-- truncate_limit: 100 +SET search_path = mvtest_mvschema, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO mvtest_mvschema, public" +== 029 +-- truncate_limit: 100 +-- modify the underlying table data +INSERT INTO mvtest_t VALUES (6, 'z', 13) +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mvtest_t VALUES (6, 'z', 13)" +== 030 +-- truncate_limit: 100 +-- confirm pre- and post-refresh contents of fairly simple materialized views +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tm ORDER BY type" +== 031 +-- truncate_limit: 100 +SELECT * FROM mvtest_tvm ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvm ORDER BY type" +== 032 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tm +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tm" +== 033 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_tvm +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_tvm" +== 034 +-- truncate_limit: 100 +SELECT * FROM mvtest_tm ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tm ORDER BY type" +== 035 +-- truncate_limit: 100 +SELECT * FROM mvtest_tvm ORDER BY type +-- +TABLE: name="mvtest_tvm" schema="" table="mvtest_tvm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvm ORDER BY type" +== 036 +-- truncate_limit: 100 +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 037 +-- truncate_limit: 100 +-- confirm pre- and post-refresh contents of nested materialized views +EXPLAIN (costs off) + SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mvtest_tmm" +== 038 +-- truncate_limit: 100 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mvtest_tvmm" +== 039 +-- truncate_limit: 100 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mvtest_tvvm" +== 040 +-- truncate_limit: 100 +SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tmm" +== 041 +-- truncate_limit: 100 +SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvmm" +== 042 +-- truncate_limit: 100 +SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvvm" +== 043 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_tmm" +== 044 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm" +== 045 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_tvmm" +== 046 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_tvvm" +== 047 +-- truncate_limit: 100 +EXPLAIN (costs off) + SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mvtest_tmm" +== 048 +-- truncate_limit: 100 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mvtest_tvmm" +== 049 +-- truncate_limit: 100 +EXPLAIN (costs off) + SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mvtest_tvvm" +== 050 +-- truncate_limit: 100 +SELECT * FROM mvtest_tmm +-- +TABLE: name="mvtest_tmm" schema="" table="mvtest_tmm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tmm" +== 051 +-- truncate_limit: 100 +SELECT * FROM mvtest_tvmm +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvmm" +== 052 +-- truncate_limit: 100 +SELECT * FROM mvtest_tvvm +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvvm" +== 053 +-- truncate_limit: 100 +-- test diemv when the mv does not exist +DROP MATERIALIZED VIEW IF EXISTS no_such_mv +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW IF EXISTS no_such_mv" +== 054 +-- truncate_limit: 100 +-- make sure invalid combination of options is prohibited +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm WITH NO DATA +-- +TABLE: name="mvtest_tvmm" schema="" table="mvtest_tvmm" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm WITH NO DATA" +== 055 +-- truncate_limit: 100 +-- no tuple locks on materialized views +SELECT * FROM mvtest_tvvm FOR SHARE +-- +TABLE: name="mvtest_tvvm" schema="" table="mvtest_tvvm" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_tvvm FOR SHARE" +== 056 +-- truncate_limit: 100 +-- test join of mv and view +SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM mvtest_tm m LEFT JOIN mvtest_tv v USING (type) ORDER BY type +-- +TABLE: name="mvtest_tm" schema="" table="mvtest_tm" ctx=Select +TABLE: name="mvtest_tv" schema="" table="mvtest_tv" ctx=Select +ALIAS: "m"="mvtest_tm" +ALIAS: "v"="mvtest_tv" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM mvtest_tm m LEFT JOIN mvtest_tv v USING (type) ORDER BY type" +== 057 +-- truncate_limit: 100 +-- make sure that dependencies are reported properly when they block the drop +DROP TABLE mvtest_t +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mvtest_t" +== 058 +-- truncate_limit: 100 +-- make sure dependencies are dropped and reported +-- and make sure that transactional behavior is correct on rollback +-- incidentally leaving some interesting materialized views for pg_dump testing +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 059 +-- truncate_limit: 100 +DROP TABLE mvtest_t CASCADE +-- +TABLE: name="mvtest_t" schema="" table="mvtest_t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mvtest_t CASCADE" +== 060 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 061 +-- truncate_limit: 100 +-- some additional tests not using base tables +CREATE VIEW mvtest_vt1 AS SELECT 1 moo +-- +TABLE: name="mvtest_vt1" schema="" table="mvtest_vt1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mvtest_vt1 AS SELECT 1 AS moo" +== 062 +-- truncate_limit: 100 +CREATE VIEW mvtest_vt2 AS SELECT moo, 2*moo FROM mvtest_vt1 UNION ALL SELECT moo, 3*moo FROM mvtest_vt1 +-- +TABLE: name="mvtest_vt2" schema="" table="mvtest_vt2" ctx=DDL +TABLE: name="mvtest_vt1" schema="" table="mvtest_vt1" ctx=Select +TABLE: name="mvtest_vt1" schema="" table="mvtest_vt1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW mvtest_vt2 AS SELECT moo, 2 * moo FROM mvtest_vt1 UNION ALL SELECT moo, 3 * moo FROM ..." +== 063 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM mvtest_vt2 UNION ALL SELECT moo, 3*moo FROM mvtest_vt2 +-- +TABLE: name="mv_test2" schema="" table="mv_test2" ctx=DDL +TABLE: name="mvtest_vt2" schema="" table="mvtest_vt2" ctx=Select +TABLE: name="mvtest_vt2" schema="" table="mvtest_vt2" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2 * moo FROM mvtest_vt2 UNION ALL SELECT moo, 3 ..." +== 064 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mv_test3 AS SELECT * FROM mv_test2 WHERE moo = 12345 +-- +TABLE: name="mv_test3" schema="" table="mv_test3" ctx=DDL +TABLE: name="mv_test2" schema="" table="mv_test2" ctx=Select +FILTER: schema="" table="" column="moo" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mv_test3 AS SELECT * FROM mv_test2 WHERE moo = 12345" +== 065 +-- truncate_limit: 100 +SELECT relispopulated FROM pg_class WHERE oid = 'mv_test3'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relispopulated FROM pg_class WHERE oid = 'mv_test3'::regclass" +== 066 +-- truncate_limit: 100 +DROP VIEW mvtest_vt1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW mvtest_vt1 CASCADE" +== 067 +-- truncate_limit: 100 +-- test that duplicate values on unique index prevent refresh +CREATE TABLE mvtest_foo(a, b) AS VALUES(1, 10) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE mvtest_foo(a, b) AS VALUES (1, 10)" +== 068 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_foo +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_foo" +== 069 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON mvtest_mv(a) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON mvtest_mv USING btree (a)" +== 070 +-- truncate_limit: 100 +INSERT INTO mvtest_foo SELECT * FROM mvtest_foo +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DML +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mvtest_foo SELECT * FROM mvtest_foo" +== 071 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_mv" +== 072 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv" +== 073 +-- truncate_limit: 100 +DROP TABLE mvtest_foo CASCADE +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mvtest_foo CASCADE" +== 074 +-- truncate_limit: 100 +-- make sure that all columns covered by unique indexes works +CREATE TABLE mvtest_foo(a, b, c) AS VALUES(1, 2, 3) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE mvtest_foo(a, b, c) AS VALUES (1, 2, 3)" +== 075 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_foo +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_foo" +== 076 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON mvtest_mv (a) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON mvtest_mv USING btree (a)" +== 077 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON mvtest_mv (b) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON mvtest_mv USING btree (b)" +== 078 +-- truncate_limit: 100 +CREATE UNIQUE INDEX on mvtest_mv (c) +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON mvtest_mv USING btree (c)" +== 079 +-- truncate_limit: 100 +INSERT INTO mvtest_foo VALUES(2, 3, 4) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mvtest_foo VALUES (2, 3, 4)" +== 080 +-- truncate_limit: 100 +INSERT INTO mvtest_foo VALUES(3, 4, 5) +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mvtest_foo VALUES (3, 4, 5)" +== 081 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_mv" +== 082 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv +-- +TABLE: name="mvtest_mv" schema="" table="mvtest_mv" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv" +== 083 +-- truncate_limit: 100 +DROP TABLE mvtest_foo CASCADE +-- +TABLE: name="mvtest_foo" schema="" table="mvtest_foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mvtest_foo CASCADE" +== 084 +-- truncate_limit: 100 +-- allow subquery to reference unpopulated matview if WITH NO DATA is specified +CREATE MATERIALIZED VIEW mvtest_mv1 AS SELECT 1 AS col1 WITH NO DATA +-- +TABLE: name="mvtest_mv1" schema="" table="mvtest_mv1" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv1 AS SELECT 1 AS col1 WITH NO DATA" +== 085 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_mv2 AS SELECT * FROM mvtest_mv1 + WHERE col1 = (SELECT LEAST(col1) FROM mvtest_mv1) WITH NO DATA +-- +TABLE: name="mvtest_mv2" schema="" table="mvtest_mv2" ctx=DDL +TABLE: name="mvtest_mv1" schema="" table="mvtest_mv1" ctx=Select +TABLE: name="mvtest_mv1" schema="" table="mvtest_mv1" ctx=Select +FILTER: schema="" table="" column="col1" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv2 AS SELECT * FROM mvtest_mv1 WHERE col1 = (SELECT LEAST(col1) ..." +== 086 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW mvtest_mv1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW mvtest_mv1 CASCADE" +== 087 +-- truncate_limit: 100 +-- make sure that types with unusual equality tests work +CREATE TABLE mvtest_boxes (id serial primary key, b box) +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mvtest_boxes (id serial PRIMARY KEY, b box)" +== 088 +-- truncate_limit: 100 +INSERT INTO mvtest_boxes (b) VALUES + ('(32,32),(31,31)'), + ('(2.0000004,2.0000004),(1,1)'), + ('(1.9999996,1.9999996),(1,1)') +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mvtest_boxes (b) VALUES (...)" +== 089 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_boxmv AS SELECT * FROM mvtest_boxes +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=DDL +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_boxmv AS SELECT * FROM mvtest_boxes" +== 090 +-- truncate_limit: 100 +CREATE UNIQUE INDEX mvtest_boxmv_id ON mvtest_boxmv (id) +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX mvtest_boxmv_id ON mvtest_boxmv USING btree (id)" +== 091 +-- truncate_limit: 100 +UPDATE mvtest_boxes SET b = '(2,2),(1,1)' WHERE id = 2 +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE mvtest_boxes SET b = '(2,2),(1,1)' WHERE id = 2" +== 092 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_boxmv +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_boxmv" +== 093 +-- truncate_limit: 100 +SELECT * FROM mvtest_boxmv ORDER BY id +-- +TABLE: name="mvtest_boxmv" schema="" table="mvtest_boxmv" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_boxmv ORDER BY id" +== 094 +-- truncate_limit: 100 +DROP TABLE mvtest_boxes CASCADE +-- +TABLE: name="mvtest_boxes" schema="" table="mvtest_boxes" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mvtest_boxes CASCADE" +== 095 +-- truncate_limit: 100 +-- make sure that column names are handled correctly +CREATE TABLE mvtest_v (i int, j int) +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mvtest_v (i int, j int)" +== 096 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj, kk) AS SELECT i, j FROM mvtest_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_v(ii, jj, kk) AS SELECT i, j FROM mvtest_v" +== 097 +-- truncate_limit: 100 +-- error +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj) AS SELECT i, j FROM mvtest_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_v(ii, jj) AS SELECT i, j FROM mvtest_v" +== 098 +-- truncate_limit: 100 +-- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_2 (ii) AS SELECT i, j FROM mvtest_v +-- +TABLE: name="mvtest_mv_v_2" schema="" table="mvtest_mv_v_2" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_v_2(ii) AS SELECT i, j FROM mvtest_v" +== 099 +-- truncate_limit: 100 +-- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj, kk) AS SELECT i, j FROM mvtest_v WITH NO DATA +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_v_3(ii, jj, kk) AS SELECT i, j FROM mvtest_v WITH NO DATA" +== 100 +-- truncate_limit: 100 +-- error +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj) AS SELECT i, j FROM mvtest_v WITH NO DATA +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_v_3(ii, jj) AS SELECT i, j FROM mvtest_v WITH NO DATA" +== 101 +-- truncate_limit: 100 +-- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_4 (ii) AS SELECT i, j FROM mvtest_v WITH NO DATA +-- +TABLE: name="mvtest_mv_v_4" schema="" table="mvtest_mv_v_4" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_v_4(ii) AS SELECT i, j FROM mvtest_v WITH NO DATA" +== 102 +-- truncate_limit: 100 +-- ok +ALTER TABLE mvtest_v RENAME COLUMN i TO x +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE mvtest_v RENAME COLUMN i TO x" +== 103 +-- truncate_limit: 100 +INSERT INTO mvtest_v values (1, 2) +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mvtest_v VALUES (1, 2)" +== 104 +-- truncate_limit: 100 +CREATE UNIQUE INDEX mvtest_mv_v_ii ON mvtest_mv_v (ii) +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX mvtest_mv_v_ii ON mvtest_mv_v USING btree (ii)" +== 105 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_mv_v" +== 106 +-- truncate_limit: 100 +UPDATE mvtest_v SET j = 3 WHERE x = 1 +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE mvtest_v SET j = 3 WHERE x = 1" +== 107 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_v" +== 108 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_mv_v_2 +-- +TABLE: name="mvtest_mv_v_2" schema="" table="mvtest_mv_v_2" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_mv_v_2" +== 109 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_mv_v_3 +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_mv_v_3" +== 110 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_mv_v_4 +-- +TABLE: name="mvtest_mv_v_4" schema="" table="mvtest_mv_v_4" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_mv_v_4" +== 111 +-- truncate_limit: 100 +SELECT * FROM mvtest_v +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_v" +== 112 +-- truncate_limit: 100 +SELECT * FROM mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_mv_v" +== 113 +-- truncate_limit: 100 +SELECT * FROM mvtest_mv_v_2 +-- +TABLE: name="mvtest_mv_v_2" schema="" table="mvtest_mv_v_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_mv_v_2" +== 114 +-- truncate_limit: 100 +SELECT * FROM mvtest_mv_v_3 +-- +TABLE: name="mvtest_mv_v_3" schema="" table="mvtest_mv_v_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_mv_v_3" +== 115 +-- truncate_limit: 100 +SELECT * FROM mvtest_mv_v_4 +-- +TABLE: name="mvtest_mv_v_4" schema="" table="mvtest_mv_v_4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_mv_v_4" +== 116 +-- truncate_limit: 100 +DROP TABLE mvtest_v CASCADE +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mvtest_v CASCADE" +== 117 +-- truncate_limit: 100 +-- Check that unknown literals are converted to "text" in CREATE MATVIEW, +-- so that we don't end up with unknown-type columns. +CREATE MATERIALIZED VIEW mv_unspecified_types AS + SELECT 42 as i, 42.5 as num, 'foo' as u, 'foo'::unknown as u2, null as n +-- +TABLE: name="mv_unspecified_types" schema="" table="mv_unspecified_types" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mv_unspecified_types AS SELECT 42 AS i, 42.5 AS num, 'foo' AS u, 'foo'::..." +== 118 +-- truncate_limit: 100 +SELECT * FROM mv_unspecified_types +-- +TABLE: name="mv_unspecified_types" schema="" table="mv_unspecified_types" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mv_unspecified_types" +== 119 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW mv_unspecified_types +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW mv_unspecified_types" +== 120 +-- truncate_limit: 100 +-- make sure that create WITH NO DATA does not plan the query (bug #13907) +create materialized view mvtest_error as select 1/0 as x +-- +TABLE: name="mvtest_error" schema="" table="mvtest_error" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_error AS SELECT 1 / 0 AS x" +== 121 +-- truncate_limit: 100 +-- fail +create materialized view mvtest_error as select 1/0 as x with no data +-- +TABLE: name="mvtest_error" schema="" table="mvtest_error" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_error AS SELECT 1 / 0 AS x WITH NO DATA" +== 122 +-- truncate_limit: 100 +refresh materialized view mvtest_error +-- +TABLE: name="mvtest_error" schema="" table="mvtest_error" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_error" +== 123 +-- truncate_limit: 100 +-- fail here +drop materialized view mvtest_error +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW mvtest_error" +== 124 +-- truncate_limit: 100 +-- make sure that matview rows can be referenced as source rows (bug #9398) +CREATE TABLE mvtest_v AS SELECT generate_series(1,10) AS a +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE mvtest_v AS SELECT generate_series(1, 10) AS a" +== 125 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_mv_v AS SELECT a FROM mvtest_v WHERE a <= 5 +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=DDL +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +FILTER: schema="" table="" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_v AS SELECT a FROM mvtest_v WHERE a <= 5" +== 126 +-- truncate_limit: 100 +DELETE FROM mvtest_v WHERE EXISTS ( SELECT * FROM mvtest_mv_v WHERE mvtest_mv_v.a = mvtest_v.a ) +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DML +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=Select +FILTER: schema="" table="mvtest_mv_v" column="a" +FILTER: schema="" table="mvtest_v" column="a" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM mvtest_v WHERE EXISTS (SELECT * FROM mvtest_mv_v WHERE mvtest_mv_v.a = mvtest_v.a)" +== 127 +-- truncate_limit: 100 +SELECT * FROM mvtest_v +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_v" +== 128 +-- truncate_limit: 100 +SELECT * FROM mvtest_mv_v +-- +TABLE: name="mvtest_mv_v" schema="" table="mvtest_mv_v" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest_mv_v" +== 129 +-- truncate_limit: 100 +DROP TABLE mvtest_v CASCADE +-- +TABLE: name="mvtest_v" schema="" table="mvtest_v" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mvtest_v CASCADE" +== 130 +-- truncate_limit: 100 +-- make sure running as superuser works when MV owned by another role (bug #11208) +CREATE ROLE regress_user_mvtest +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_user_mvtest" +== 131 +-- truncate_limit: 100 +SET ROLE regress_user_mvtest +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_user_mvtest" +== 132 +-- truncate_limit: 100 +-- this test case also checks for ambiguity in the queries issued by +-- refresh_by_match_merge(), by choosing column names that intentionally +-- duplicate all the aliases used in those queries +CREATE TABLE mvtest_foo_data AS SELECT i, + i+1 AS tid, + fipshash(random()::text) AS mv, + fipshash(random()::text) AS newdata, + fipshash(random()::text) AS newdata2, + fipshash(random()::text) AS diff + FROM generate_series(1, 10) i +-- +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=DDL +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE mvtest_foo_data AS SELECT i, i + 1 AS tid, fipshash(random()::text) AS mv, fipshash(..." +== 133 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data" +== 134 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data" +== 135 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW IF NOT EXISTS mvtest_mv_foo AS SELECT * FROM mvtest_foo_data +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +TABLE: name="mvtest_foo_data" schema="" table="mvtest_foo_data" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW IF NOT EXISTS mvtest_mv_foo AS SELECT * FROM mvtest_foo_data" +== 136 +-- truncate_limit: 100 +CREATE UNIQUE INDEX ON mvtest_mv_foo (i) +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON mvtest_mv_foo USING btree (i)" +== 137 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 138 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW mvtest_mv_foo +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW mvtest_mv_foo" +== 139 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_foo +-- +TABLE: name="mvtest_mv_foo" schema="" table="mvtest_mv_foo" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_foo" +== 140 +-- truncate_limit: 100 +DROP OWNED BY regress_user_mvtest CASCADE +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_user_mvtest CASCADE" +== 141 +-- truncate_limit: 100 +DROP ROLE regress_user_mvtest +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_user_mvtest" +== 142 +-- truncate_limit: 100 +-- Concurrent refresh requires a unique index on the materialized +-- view. Test what happens if it's dropped during the refresh. +SET search_path = mvtest_mvschema, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO mvtest_mvschema, public" +== 143 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION mvtest_drop_the_index() + RETURNS bool AS $$ +BEGIN + EXECUTE 'DROP INDEX IF EXISTS mvtest_mvschema.mvtest_drop_idx'; + RETURN true; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="mvtest_drop_the_index" function="mvtest_drop_the_index" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION mvtest_drop_the_index() RETURNS bool AS $$\nBEGIN\n EXECUTE 'DROP INDEX..." +== 144 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW drop_idx_matview AS + SELECT 1 as i WHERE mvtest_drop_the_index() +-- +TABLE: name="drop_idx_matview" schema="" table="drop_idx_matview" ctx=DDL +FUNCTION: name="mvtest_drop_the_index" function="mvtest_drop_the_index" schema="" ctx=Call +FUNCTION: name="mvtest_drop_the_index" function="mvtest_drop_the_index" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW drop_idx_matview AS SELECT 1 AS i WHERE mvtest_drop_the_index()" +== 145 +-- truncate_limit: 100 +CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i) +-- +TABLE: name="drop_idx_matview" schema="" table="drop_idx_matview" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview USING btree (i)" +== 146 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview +-- +TABLE: name="drop_idx_matview" schema="" table="drop_idx_matview" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview" +== 147 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW drop_idx_matview +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW drop_idx_matview" +== 148 +-- truncate_limit: 100 +-- clean up +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 149 +-- truncate_limit: 100 +-- make sure that create WITH NO DATA works via SPI +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 150 +-- truncate_limit: 100 +CREATE FUNCTION mvtest_func() + RETURNS void AS $$ +BEGIN + CREATE MATERIALIZED VIEW mvtest1 AS SELECT 1 AS x; + CREATE MATERIALIZED VIEW mvtest2 AS SELECT 1 AS x WITH NO DATA; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="mvtest_func" function="mvtest_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mvtest_func() RETURNS void AS $$\nBEGIN\n CREATE MATERIALIZED VIEW mvtest1 AS SELE..." +== 151 +-- truncate_limit: 100 +SELECT mvtest_func() +-- +FUNCTION: name="mvtest_func" function="mvtest_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mvtest_func()" +== 152 +-- truncate_limit: 100 +SELECT * FROM mvtest1 +-- +TABLE: name="mvtest1" schema="" table="mvtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest1" +== 153 +-- truncate_limit: 100 +SELECT * FROM mvtest2 +-- +TABLE: name="mvtest2" schema="" table="mvtest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mvtest2" +== 154 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 155 +-- truncate_limit: 100 +-- INSERT privileges if relation owner is not allowed to insert. +CREATE SCHEMA matview_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA matview_schema" +== 156 +-- truncate_limit: 100 +CREATE USER regress_matview_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_matview_user" +== 157 +-- truncate_limit: 100 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_matview_user + REVOKE INSERT ON TABLES FROM regress_matview_user +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_matview_user REVOKE insert ON TABLES FROM regress_matvi..." +== 158 +-- truncate_limit: 100 +GRANT ALL ON SCHEMA matview_schema TO public +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON SCHEMA matview_schema TO public" +== 159 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_matview_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_matview_user" +== 160 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW matview_schema.mv_withdata1 (a) AS + SELECT generate_series(1, 10) WITH DATA +-- +TABLE: name="matview_schema.mv_withdata1" schema="matview_schema" table="mv_withdata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW matview_schema.mv_withdata1(a) AS SELECT generate_series(1, 10)" +== 161 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_schema.mv_withdata2 (a) AS + SELECT generate_series(1, 10) WITH DATA +-- +TABLE: name="matview_schema.mv_withdata2" schema="matview_schema" table="mv_withdata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE MATERIALIZED VIEW matview_schema.mv_..." +== 162 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW matview_schema.mv_withdata2 +-- +TABLE: name="matview_schema.mv_withdata2" schema="matview_schema" table="mv_withdata2" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW matview_schema.mv_withdata2" +== 163 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW matview_schema.mv_nodata1 (a) AS + SELECT generate_series(1, 10) WITH NO DATA +-- +TABLE: name="matview_schema.mv_nodata1" schema="matview_schema" table="mv_nodata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW matview_schema.mv_nodata1(a) AS SELECT generate_series(1, 10) WITH NO DATA" +== 164 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_schema.mv_nodata2 (a) AS + SELECT generate_series(1, 10) WITH NO DATA +-- +TABLE: name="matview_schema.mv_nodata2" schema="matview_schema" table="mv_nodata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE MATERIALIZED VIEW matview_schema.mv_..." +== 165 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW matview_schema.mv_nodata2 +-- +TABLE: name="matview_schema.mv_nodata2" schema="matview_schema" table="mv_nodata2" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW matview_schema.mv_nodata2" +== 166 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 167 +-- truncate_limit: 100 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_matview_user + GRANT INSERT ON TABLES TO regress_matview_user +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_matview_user GRANT insert ON TABLES TO regress_matview_..." +== 168 +-- truncate_limit: 100 +DROP SCHEMA matview_schema CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA matview_schema CASCADE" +== 169 +-- truncate_limit: 100 +DROP USER regress_matview_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_matview_user" +== 170 +-- truncate_limit: 100 +-- CREATE MATERIALIZED VIEW ... IF NOT EXISTS +CREATE MATERIALIZED VIEW matview_ine_tab AS SELECT 1 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW matview_ine_tab AS SELECT 1" +== 171 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW matview_ine_tab AS SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW matview_ine_tab AS SELECT 1 / 0" +== 172 +-- truncate_limit: 100 +-- error +CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS SELECT 1 / 0" +== 173 +-- truncate_limit: 100 +-- ok +CREATE MATERIALIZED VIEW matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW matview_ine_tab AS SELECT 1 / 0 WITH NO DATA" +== 174 +-- truncate_limit: 100 +-- error +CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS SELECT 1 / 0 WITH NO DATA" +== 175 +-- truncate_limit: 100 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_ine_tab AS + SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE MATERIALIZED VIEW matview_ine_tab AS..." +== 176 +-- truncate_limit: 100 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE MATERIALIZED VIEW IF NOT EXISTS matv..." +== 177 +-- truncate_limit: 100 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE MATERIALIZED VIEW matview_ine_tab AS..." +== 178 +-- truncate_limit: 100 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS + SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="matview_ine_tab" schema="" table="matview_ine_tab" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE MATERIALIZED VIEW IF NOT EXISTS matv..." +== 179 +-- truncate_limit: 100 +-- ok +DROP MATERIALIZED VIEW matview_ine_tab +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW matview_ine_tab" diff --git a/parser/testdata/summary_truncate/postgres_regress/md5.metadata.json b/parser/testdata/summary_truncate/postgres_regress/md5.metadata.json new file mode 100644 index 0000000..5a08d01 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/md5.metadata.json @@ -0,0 +1,18 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/md5.test b/parser/testdata/summary_truncate/postgres_regress/md5.test new file mode 100644 index 0000000..3bee282 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/md5.test @@ -0,0 +1,107 @@ +== 001 +-- truncate_limit: 100 +|-- +-- MD5 test suite - from IETF RFC 1321 +-- (see: https://www.rfc-editor.org/rfc/rfc1321) +|-- + +-- (The md5() function will error in OpenSSL FIPS mode. By keeping +-- this test in a separate file, it is easier to manage variant +-- results.) + +select md5('') = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('') = 'd41d8cd98f00b204e9800998ecf8427e' AS \"TRUE\"" +== 002 +-- truncate_limit: 100 +select md5('a') = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('a') = '0cc175b9c0f1b6a831c399e269772661' AS \"TRUE\"" +== 003 +-- truncate_limit: 100 +select md5('abc') = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('abc') = '900150983cd24fb0d6963f7d28e17f72' AS \"TRUE\"" +== 004 +-- truncate_limit: 100 +select md5('message digest') = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('message digest') = 'f96b697d7cb7938d525a2f31aaf161d0' AS \"TRUE\"" +== 005 +-- truncate_limit: 100 +select md5('abcdefghijklmnopqrstuvwxyz') = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('abcdefghijklmnopqrstuvwxyz') = 'c3fcd3d76192e4007dfb496cca67e13b' AS \"TRUE\"" +== 006 +-- truncate_limit: 100 +select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 007 +-- truncate_limit: 100 +select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 008 +-- truncate_limit: 100 +select md5(''::bytea) = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5(''::bytea) = 'd41d8cd98f00b204e9800998ecf8427e' AS \"TRUE\"" +== 009 +-- truncate_limit: 100 +select md5('a'::bytea) = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('a'::bytea) = '0cc175b9c0f1b6a831c399e269772661' AS \"TRUE\"" +== 010 +-- truncate_limit: 100 +select md5('abc'::bytea) = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('abc'::bytea) = '900150983cd24fb0d6963f7d28e17f72' AS \"TRUE\"" +== 011 +-- truncate_limit: 100 +select md5('message digest'::bytea) = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('message digest'::bytea) = 'f96b697d7cb7938d525a2f31aaf161d0' AS \"TRUE\"" +== 012 +-- truncate_limit: 100 +select md5('abcdefghijklmnopqrstuvwxyz'::bytea) = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT md5('abcdefghijklmnopqrstuvwxyz'::bytea) = 'c3fcd3d76192e4007dfb496cca67e13b' AS \"TRUE\"" +== 013 +-- truncate_limit: 100 +select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'::bytea) = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 014 +-- truncate_limit: 100 +select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890'::bytea) = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE" +-- +FUNCTION: name="md5" function="md5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." diff --git a/parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json b/parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json new file mode 100644 index 0000000..abfc1a2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json @@ -0,0 +1,73 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/memoize.test b/parser/testdata/summary_truncate/postgres_regress/memoize.test new file mode 100644 index 0000000..3fc49ae --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/memoize.test @@ -0,0 +1,648 @@ +== 001 +-- truncate_limit: 100 +-- Perform tests on the Memoize node. + +-- The cache hits/misses/evictions from the Memoize node can vary between +-- machines. Let's just replace the number with an 'N'. In order to allow us +-- to perform validation when the measure was zero, we replace a zero value +-- with "Zero". All other numbers are replaced with 'N'. +create function explain_memoize(query text, hide_hitmiss bool) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + query) + loop + if hide_hitmiss = true then + ln := regexp_replace(ln, 'Hits: 0', 'Hits: Zero'); + ln := regexp_replace(ln, 'Hits: \d+', 'Hits: N'); + ln := regexp_replace(ln, 'Misses: 0', 'Misses: Zero'); + ln := regexp_replace(ln, 'Misses: \d+', 'Misses: N'); + end if; + ln := regexp_replace(ln, 'Evictions: 0', 'Evictions: Zero'); + ln := regexp_replace(ln, 'Evictions: \d+', 'Evictions: N'); + ln := regexp_replace(ln, 'Memory Usage: \d+', 'Memory Usage: N'); + ln := regexp_replace(ln, 'Heap Fetches: \d+', 'Heap Fetches: N'); + ln := regexp_replace(ln, 'loops=\d+', 'loops=N'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_memoize(query text, hide_hitmiss bool) RETURNS SETOF text LANGUAGE plpgsq..." +== 002 +-- truncate_limit: 100 +-- Ensure we get a memoize node on the inner side of the nested loop +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 003 +-- truncate_limit: 100 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 004 +-- truncate_limit: 100 +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.twenty +WHERE t2.unique1 < 1000;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 005 +-- truncate_limit: 100 +-- And check we get the expected results. +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.twenty +WHERE t2.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1 JOIN tenk1 t2 ON t1.unique1 = t2.twenty WHERE t2.unique1 < 1000" +== 006 +-- truncate_limit: 100 +-- Try with LATERAL joins +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 + WHERE t1.twenty = t2.unique1 OFFSET 0) t2 +WHERE t1.unique1 < 1000;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 007 +-- truncate_limit: 100 +-- And check we get the expected results. +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 + WHERE t1.twenty = t2.unique1 OFFSET 0) t2 +WHERE t1.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1, LATERAL (SELECT ... FROM tenk1 t2 WHERE ... OFFSET 0) t2 WHERE ..." +== 008 +-- truncate_limit: 100 +-- Try with LATERAL joins +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t2.t1two) FROM tenk1 t1 LEFT JOIN +LATERAL ( + SELECT t1.two as t1two, * FROM tenk1 t2 WHERE t2.unique1 < 4 OFFSET 0 +) t2 +ON t1.two = t2.two +WHERE t1.unique1 < 10;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 009 +-- truncate_limit: 100 +-- And check we get the expected results. +SELECT COUNT(*),AVG(t2.t1two) FROM tenk1 t1 LEFT JOIN +LATERAL ( + SELECT t1.two as t1two, * FROM tenk1 t2 WHERE t2.unique1 < 4 OFFSET 0 +) t2 +ON t1.two = t2.two +WHERE t1.unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1 LEFT JOIN LATERAL (SELECT ... FROM tenk1 t2 WHERE ... OFFSET 0) t2 ON t1..." +== 010 +-- truncate_limit: 100 +SET enable_mergejoin TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 011 +-- truncate_limit: 100 +-- Test for varlena datatype with expr evaluation +CREATE TABLE expr_key (x numeric, t text) +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE expr_key (x numeric, t text)" +== 012 +-- truncate_limit: 100 +INSERT INTO expr_key (x, t) +SELECT d1::numeric, d1::text FROM ( + SELECT round((d / pi())::numeric, 7) AS d1 FROM generate_series(1, 20) AS d +) t +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DML +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="pi" function="pi" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO expr_key (x, t) SELECT ... FROM (SELECT ... FROM generate_series(1, 20) d) t" +== 013 +-- truncate_limit: 100 +-- duplicate rows so we get some cache hits +INSERT INTO expr_key SELECT * FROM expr_key +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DML +TABLE: name="expr_key" schema="" table="expr_key" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO expr_key SELECT * FROM expr_key" +== 014 +-- truncate_limit: 100 +CREATE INDEX expr_key_idx_x_t ON expr_key (x, t) +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX expr_key_idx_x_t ON expr_key USING btree (x, t)" +== 015 +-- truncate_limit: 100 +VACUUM ANALYZE expr_key +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) expr_key" +== 016 +-- truncate_limit: 100 +-- Ensure we get we get a cache miss and hit for each of the 20 distinct values +SELECT explain_memoize(' +SELECT * FROM expr_key t1 INNER JOIN expr_key t2 +ON t1.x = t2.t::numeric AND t1.t::numeric = t2.x;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 017 +-- truncate_limit: 100 +DROP TABLE expr_key +-- +TABLE: name="expr_key" schema="" table="expr_key" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE expr_key" +== 018 +-- truncate_limit: 100 +-- Reduce work_mem and hash_mem_multiplier so that we see some cache evictions +SET work_mem TO '64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 019 +-- truncate_limit: 100 +SET hash_mem_multiplier TO 1.0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET hash_mem_multiplier TO 1.0" +== 020 +-- truncate_limit: 100 +-- Ensure we get some evictions. We're unable to validate the hits and misses +-- here as the number of entries that fit in the cache at once will vary +-- between different machines. +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.thousand +WHERE t2.unique1 < 1200;', true) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 021 +-- truncate_limit: 100 +CREATE TABLE flt (f float) +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE flt (f double precision)" +== 022 +-- truncate_limit: 100 +CREATE INDEX flt_f_idx ON flt (f) +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX flt_f_idx ON flt USING btree (f)" +== 023 +-- truncate_limit: 100 +INSERT INTO flt VALUES('-0.0'::float),('+0.0'::float) +-- +TABLE: name="flt" schema="" table="flt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO flt VALUES ('-0.0'::double precision), ('+0.0'::double precision)" +== 024 +-- truncate_limit: 100 +ANALYZE flt +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE flt" +== 025 +-- truncate_limit: 100 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 026 +-- truncate_limit: 100 +-- Ensure memoize operates in logical mode +SELECT explain_memoize(' +SELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f = f2.f;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_memoize('\nSELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f = f2.f;', false)" +== 027 +-- truncate_limit: 100 +-- Ensure memoize operates in binary mode +SELECT explain_memoize(' +SELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f >= f2.f;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_memoize('\nSELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f >= f2.f;', false)" +== 028 +-- truncate_limit: 100 +DROP TABLE flt +-- +TABLE: name="flt" schema="" table="flt" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE flt" +== 029 +-- truncate_limit: 100 +-- Exercise Memoize in binary mode with a large fixed width type and a +-- varlena type. +CREATE TABLE strtest (n name, t text) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE strtest (n name, t text)" +== 030 +-- truncate_limit: 100 +CREATE INDEX strtest_n_idx ON strtest (n) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX strtest_n_idx ON strtest USING btree (n)" +== 031 +-- truncate_limit: 100 +CREATE INDEX strtest_t_idx ON strtest (t) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX strtest_t_idx ON strtest USING btree (t)" +== 032 +-- truncate_limit: 100 +INSERT INTO strtest VALUES('one','one'),('two','two'),('three',repeat(fipshash('three'),100)) +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO strtest VALUES ('one', 'one'), ('two', 'two'), ('three', repeat(fipshash('three'), 100))" +== 033 +-- truncate_limit: 100 +-- duplicate rows so we get some cache hits +INSERT INTO strtest SELECT * FROM strtest +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DML +TABLE: name="strtest" schema="" table="strtest" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO strtest SELECT * FROM strtest" +== 034 +-- truncate_limit: 100 +ANALYZE strtest +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE strtest" +== 035 +-- truncate_limit: 100 +-- Ensure we get 3 hits and 3 misses +SELECT explain_memoize(' +SELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.n >= s2.n;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_memoize('\nSELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.n >= s2.n;', false)" +== 036 +-- truncate_limit: 100 +-- Ensure we get 3 hits and 3 misses +SELECT explain_memoize(' +SELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.t >= s2.t;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_memoize('\nSELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.t >= s2.t;', false)" +== 037 +-- truncate_limit: 100 +DROP TABLE strtest +-- +TABLE: name="strtest" schema="" table="strtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE strtest" +== 038 +-- truncate_limit: 100 +-- Ensure memoize works with partitionwise join +SET enable_partitionwise_join TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO ON" +== 039 +-- truncate_limit: 100 +CREATE TABLE prt (a int) PARTITION BY RANGE(a) +-- +TABLE: name="prt" schema="" table="prt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt (a int) PARTITION BY RANGE (a)" +== 040 +-- truncate_limit: 100 +CREATE TABLE prt_p1 PARTITION OF prt FOR VALUES FROM (0) TO (10) +-- +TABLE: name="prt_p1" schema="" table="prt_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt_p1 PARTITION OF prt FOR VALUES FROM (0) TO (10)" +== 041 +-- truncate_limit: 100 +CREATE TABLE prt_p2 PARTITION OF prt FOR VALUES FROM (10) TO (20) +-- +TABLE: name="prt_p2" schema="" table="prt_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt_p2 PARTITION OF prt FOR VALUES FROM (10) TO (20)" +== 042 +-- truncate_limit: 100 +INSERT INTO prt VALUES (0), (0), (0), (0) +-- +TABLE: name="prt" schema="" table="prt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt VALUES (0), (0), (0), (0)" +== 043 +-- truncate_limit: 100 +INSERT INTO prt VALUES (10), (10), (10), (10) +-- +TABLE: name="prt" schema="" table="prt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt VALUES (10), (10), (10), (10)" +== 044 +-- truncate_limit: 100 +CREATE INDEX iprt_p1_a ON prt_p1 (a) +-- +TABLE: name="prt_p1" schema="" table="prt_p1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt_p1_a ON prt_p1 USING btree (a)" +== 045 +-- truncate_limit: 100 +CREATE INDEX iprt_p2_a ON prt_p2 (a) +-- +TABLE: name="prt_p2" schema="" table="prt_p2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt_p2_a ON prt_p2 USING btree (a)" +== 046 +-- truncate_limit: 100 +ANALYZE prt +-- +TABLE: name="prt" schema="" table="prt" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt" +== 047 +-- truncate_limit: 100 +SELECT explain_memoize(' +SELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_memoize('\nSELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false)" +== 048 +-- truncate_limit: 100 +-- Ensure memoize works with parameterized union-all Append path +SET enable_partitionwise_join TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO OFF" +== 049 +-- truncate_limit: 100 +SELECT explain_memoize(' +SELECT * FROM prt_p1 t1 INNER JOIN +(SELECT * FROM prt_p1 UNION ALL SELECT * FROM prt_p2) t2 +ON t1.a = t2.a;', false) +-- +FUNCTION: name="explain_memoize" function="explain_memoize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 050 +-- truncate_limit: 100 +DROP TABLE prt +-- +TABLE: name="prt" schema="" table="prt" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt" +== 051 +-- truncate_limit: 100 +RESET enable_partitionwise_join +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_partitionwise_join" +== 052 +-- truncate_limit: 100 +-- Exercise Memoize code that flushes the cache when a parameter changes which +-- is not part of the cache key. + +-- Ensure we get a Memoize plan +EXPLAIN (COSTS OFF) +SELECT unique1 FROM tenk1 t0 +WHERE unique1 < 3 + AND EXISTS ( + SELECT 1 FROM tenk1 t1 + INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred + WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t0"="tenk1" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="t0" column="ten" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t0" column="two" +FILTER: schema="" table="t2" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 t0 WHERE unique1 < 3 AND EXISTS (SELECT 1 FROM tenk..." +== 053 +-- truncate_limit: 100 +-- Ensure the above query returns the correct result +SELECT unique1 FROM tenk1 t0 +WHERE unique1 < 3 + AND EXISTS ( + SELECT 1 FROM tenk1 t1 + INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred + WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t0"="tenk1" +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="t0" column="ten" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t0" column="two" +FILTER: schema="" table="t2" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 t0 WHERE ..." +== 054 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 055 +-- truncate_limit: 100 +RESET enable_mergejoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_mergejoin" +== 056 +-- truncate_limit: 100 +RESET work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET work_mem" +== 057 +-- truncate_limit: 100 +RESET hash_mem_multiplier +-- +STMT: VariableSetStmt +TRUNCATED: "RESET hash_mem_multiplier" +== 058 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 059 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 060 +-- truncate_limit: 100 +-- Test parallel plans with Memoize +SET min_parallel_table_scan_size TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 061 +-- truncate_limit: 100 +SET parallel_setup_cost TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 062 +-- truncate_limit: 100 +SET parallel_tuple_cost TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 063 +-- truncate_limit: 100 +SET max_parallel_workers_per_gather TO 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 064 +-- truncate_limit: 100 +-- Ensure we get a parallel plan. +EXPLAIN (COSTS OFF) +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 WHERE t1.twenty = t2.unique1) t2 +WHERE t1.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t2" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*), avg(t2.unique1) FROM tenk1 t1, LATERAL (SELECT t2.unique1 FR..." +== 065 +-- truncate_limit: 100 +-- And ensure the parallel plan gives us the correct results. +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 WHERE t1.twenty = t2.unique1) t2 +WHERE t1.unique1 < 1000 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="unique1" +FILTER: schema="" table="t1" column="twenty" +FILTER: schema="" table="t2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1, LATERAL (SELECT ... FROM tenk1 t2 WHERE ...) t2 WHERE t1.unique1 < 1000" +== 066 +-- truncate_limit: 100 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers_per_gather" +== 067 +-- truncate_limit: 100 +RESET parallel_tuple_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_tuple_cost" +== 068 +-- truncate_limit: 100 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 069 +-- truncate_limit: 100 +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_table_scan_size" diff --git a/parser/testdata/summary_truncate/postgres_regress/merge.metadata.json b/parser/testdata/summary_truncate/postgres_regress/merge.metadata.json new file mode 100644 index 0000000..168c3f9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/merge.metadata.json @@ -0,0 +1,576 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/merge.test b/parser/testdata/summary_truncate/postgres_regress/merge.test new file mode 100644 index 0000000..fad8862 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/merge.test @@ -0,0 +1,5210 @@ +== 001 +-- truncate_limit: 100 +|-- +-- MERGE +|-- + +CREATE USER regress_merge_privs +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_merge_privs" +== 002 +-- truncate_limit: 100 +CREATE USER regress_merge_no_privs +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_merge_no_privs" +== 003 +-- truncate_limit: 100 +CREATE USER regress_merge_none +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_merge_none" +== 004 +-- truncate_limit: 100 +DROP TABLE IF EXISTS target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE IF EXISTS target" +== 005 +-- truncate_limit: 100 +DROP TABLE IF EXISTS source +-- +TABLE: name="source" schema="" table="source" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE IF EXISTS source" +== 006 +-- truncate_limit: 100 +CREATE TABLE target (tid integer, balance integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE target (tid int, balance int) WITH (autovacuum_enabled=off)" +== 007 +-- truncate_limit: 100 +CREATE TABLE source (sid integer, delta integer) -- no index + WITH (autovacuum_enabled=off) +-- +TABLE: name="source" schema="" table="source" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE source (sid int, delta int) WITH (autovacuum_enabled=off)" +== 008 +-- truncate_limit: 100 +INSERT INTO target VALUES (1, 10) +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO target VALUES (1, 10)" +== 009 +-- truncate_limit: 100 +INSERT INTO target VALUES (2, 20) +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO target VALUES (2, 20)" +== 010 +-- truncate_limit: 100 +INSERT INTO target VALUES (3, 30) +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO target VALUES (3, 30)" +== 011 +-- truncate_limit: 100 +SELECT t.ctid is not null as matched, t.*, s.* FROM source s FULL OUTER JOIN target t ON s.sid = t.tid ORDER BY t.tid, s.sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +TABLE: name="target" schema="" table="target" ctx=Select +ALIAS: "s"="source" +ALIAS: "t"="target" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM source s FULL JOIN target t ON s.sid = t.tid ORDER BY t.tid, s.sid" +== 012 +-- truncate_limit: 100 +ALTER TABLE target OWNER TO regress_merge_privs +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE target OWNER TO regress_merge_privs" +== 013 +-- truncate_limit: 100 +ALTER TABLE source OWNER TO regress_merge_privs +-- +TABLE: name="source" schema="" table="source" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE source OWNER TO regress_merge_privs" +== 014 +-- truncate_limit: 100 +CREATE TABLE target2 (tid integer, balance integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE target2 (tid int, balance int) WITH (autovacuum_enabled=off)" +== 015 +-- truncate_limit: 100 +CREATE TABLE source2 (sid integer, delta integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="source2" schema="" table="source2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE source2 (sid int, delta int) WITH (autovacuum_enabled=off)" +== 016 +-- truncate_limit: 100 +ALTER TABLE target2 OWNER TO regress_merge_no_privs +-- +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE target2 OWNER TO regress_merge_no_privs" +== 017 +-- truncate_limit: 100 +ALTER TABLE source2 OWNER TO regress_merge_no_privs +-- +TABLE: name="source2" schema="" table="source2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE source2 OWNER TO regress_merge_no_privs" +== 018 +-- truncate_limit: 100 +GRANT INSERT ON target TO regress_merge_no_privs +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON target TO regress_merge_no_privs" +== 019 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_merge_privs +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_merge_privs" +== 020 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DELETE" +== 021 +-- truncate_limit: 100 +|-- +-- Errors +|-- +MERGE INTO target t RANDOMWORD +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +ERROR: syntax error at or near "RANDOMWORD" +CURSORPOS: 37 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 022 +-- truncate_limit: 100 +-- MATCHED/INSERT error +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + INSERT DEFAULT VALUES +-- +ERROR: syntax error at or near "INSERT" +CURSORPOS: 99 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 023 +-- truncate_limit: 100 +-- NOT MATCHED BY SOURCE/INSERT error +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE THEN + INSERT DEFAULT VALUES +-- +ERROR: syntax error at or near "INSERT" +CURSORPOS: 127 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +-- truncate_limit: 100 +-- incorrectly specifying INTO target +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT INTO target DEFAULT VALUES +-- +ERROR: syntax error at or near "INTO" +CURSORPOS: 124 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 025 +-- truncate_limit: 100 +-- Multiple VALUES clause +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (1,1), (2,2) +-- +ERROR: syntax error at or near "," +CURSORPOS: 124 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +-- truncate_limit: 100 +-- SELECT query for INSERT +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT SELECT (1, 1) +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 113 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 027 +-- truncate_limit: 100 +-- NOT MATCHED/UPDATE +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + UPDATE SET balance = 0 +-- +ERROR: syntax error at or near "UPDATE" +CURSORPOS: 101 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 028 +-- truncate_limit: 100 +-- NOT MATCHED BY TARGET/UPDATE +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED BY TARGET THEN + UPDATE SET balance = 0 +-- +ERROR: syntax error at or near "UPDATE" +CURSORPOS: 121 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 029 +-- truncate_limit: 100 +-- UPDATE tablename +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE target SET balance = 0 +-- +ERROR: syntax error at or near "target" +CURSORPOS: 102 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 030 +-- truncate_limit: 100 +-- source and target names the same +MERGE INTO target +USING target +ON tid = tid +WHEN MATCHED THEN DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO target USING target ON tid = tid WHEN MATCHED THEN DO NOTHING" +== 031 +-- truncate_limit: 100 +-- used in a CTE without RETURNING +WITH foo AS ( + MERGE INTO target USING source ON (true) + WHEN MATCHED THEN DELETE +) SELECT * FROM foo +-- +TABLE: name="target" schema="" table="target" ctx=DML +CTE: "foo" +STMT: SelectStmt +STMT: MergeStmt +TRUNCATED: "WITH foo AS (MERGE INTO target USING source ON true WHEN MATCHED THEN DELETE) SELECT * FROM foo" +== 032 +-- truncate_limit: 100 +-- used in COPY without RETURNING +COPY ( + MERGE INTO target USING source ON (true) + WHEN MATCHED THEN DELETE +) TO stdout +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: CopyStmt +TRUNCATED: "COPY (MERGE INTO target USING source ON true WHEN MATCHED THEN DELETE) TO STDOUT" +== 033 +-- truncate_limit: 100 +-- unsupported relation types +-- materialized view +CREATE MATERIALIZED VIEW mv AS SELECT * FROM target +-- +TABLE: name="mv" schema="" table="mv" ctx=DDL +TABLE: name="target" schema="" table="target" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mv AS SELECT * FROM target" +== 034 +-- truncate_limit: 100 +MERGE INTO mv t +USING source s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="mv" schema="" table="mv" ctx=DML +ALIAS: "t"="mv" +STMT: MergeStmt +TRUNCATED: "MERGE INTO mv t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT DEFAULT VALUES" +== 035 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW mv +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW mv" +== 036 +-- truncate_limit: 100 +-- permissions + +SET SESSION AUTHORIZATION regress_merge_none +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_merge_none" +== 037 +-- truncate_limit: 100 +MERGE INTO target +USING (SELECT 1) +ON true +WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target USING (SELECT 1) ON true WHEN MATCHED THEN DO NOTHING" +== 038 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_merge_privs +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_merge_privs" +== 039 +-- truncate_limit: 100 +MERGE INTO target +USING source2 +ON target.tid = source2.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO target USING source2 ON target.tid = source2.sid WHEN MATCHED THEN UPDATE SET balance = 0" +== 040 +-- truncate_limit: 100 +GRANT INSERT ON target TO regress_merge_no_privs +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON target TO regress_merge_no_privs" +== 041 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_merge_no_privs +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_merge_no_privs" +== 042 +-- truncate_limit: 100 +MERGE INTO target +USING source2 +ON target.tid = source2.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO target USING source2 ON target.tid = source2.sid WHEN MATCHED THEN UPDATE SET balance = 0" +== 043 +-- truncate_limit: 100 +GRANT UPDATE ON target2 TO regress_merge_privs +-- +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON target2 TO regress_merge_privs" +== 044 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_merge_privs +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_merge_privs" +== 045 +-- truncate_limit: 100 +MERGE INTO target2 +USING source +ON target2.tid = source.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target2" schema="" table="target2" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO target2 USING source ON target2.tid = source.sid WHEN MATCHED THEN DELETE" +== 046 +-- truncate_limit: 100 +MERGE INTO target2 +USING source +ON target2.tid = source.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target2" schema="" table="target2" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO target2 USING source ON target2.tid = source.sid WHEN NOT MATCHED THEN INSERT DEFAULT ..." +== 047 +-- truncate_limit: 100 +-- check if the target can be accessed from source relation subquery; we should +-- not be able to do so +MERGE INTO target t +USING (SELECT * FROM source WHERE t.tid > sid) s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="t" column="tid" +FILTER: schema="" table="" column="sid" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target t USING (SELECT * FROM source WHERE ...) s ON t.tid = s.sid WHEN NOT MATCHED TH..." +== 048 +-- truncate_limit: 100 +|-- +-- initial tests +|-- +-- zero rows in source has no effect +MERGE INTO target +USING source +ON target.tid = source.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO target USING source ON target.tid = source.sid WHEN MATCHED THEN UPDATE SET balance = 0" +== 049 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = 0" +== 050 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DELETE" +== 051 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 052 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT DEFAULT VALUES" +== 053 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 054 +-- truncate_limit: 100 +-- insert some non-matching source rows to work from +INSERT INTO source VALUES (4, 40) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (4, 40)" +== 055 +-- truncate_limit: 100 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM source ORDER BY sid" +== 056 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 057 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN DO NOTHING" +== 058 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = 0" +== 059 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DELETE" +== 060 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 061 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT DEFAULT VALUES +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT DEFAULT VALUES" +== 062 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 063 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 064 +-- truncate_limit: 100 +-- DELETE/INSERT not matched by source/target +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 065 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE THEN + DELETE +WHEN NOT MATCHED BY TARGET THEN + INSERT VALUES (s.sid, s.delta) +RETURNING merge_action(), t.* +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED BY SOURCE THEN DELETE WHEN N..." +== 066 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 067 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 068 +-- truncate_limit: 100 +-- index plans +INSERT INTO target SELECT generate_series(1000,2500), 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO target SELECT generate_series(1000, 2500), 0" +== 069 +-- truncate_limit: 100 +ALTER TABLE target ADD PRIMARY KEY (tid) +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE target ADD PRIMARY KEY (tid)" +== 070 +-- truncate_limit: 100 +ANALYZE target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE target" +== 071 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE ..." +== 072 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DELETE" +== 073 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, NULL) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: ExplainStmt +STMT: MergeStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INS..." +== 074 +-- truncate_limit: 100 +DELETE FROM target WHERE tid > 100 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM target WHERE tid > 100" +== 075 +-- truncate_limit: 100 +ANALYZE target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE target" +== 076 +-- truncate_limit: 100 +-- insert some matching source rows to work from +INSERT INTO source VALUES (2, 5) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (2, 5)" +== 077 +-- truncate_limit: 100 +INSERT INTO source VALUES (3, 20) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (3, 20)" +== 078 +-- truncate_limit: 100 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM source ORDER BY sid" +== 079 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 080 +-- truncate_limit: 100 +-- equivalent of an UPDATE join +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 081 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = 0" +== 082 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 083 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 084 +-- truncate_limit: 100 +-- equivalent of a DELETE join +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 085 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DELETE" +== 086 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 087 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 088 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 089 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DO NOTHING" +== 090 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 091 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 092 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 093 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, NULL) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT VALUES (4, NULL)" +== 094 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 095 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 096 +-- truncate_limit: 100 +-- duplicate source row causes multiple target row update ERROR +INSERT INTO source VALUES (2, 5) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (2, 5)" +== 097 +-- truncate_limit: 100 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM source ORDER BY sid" +== 098 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 099 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 100 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = 0" +== 101 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 102 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 103 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DELETE" +== 104 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 105 +-- truncate_limit: 100 +-- remove duplicate MATCHED data from source data +DELETE FROM source WHERE sid = 2 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM source WHERE sid = 2" +== 106 +-- truncate_limit: 100 +INSERT INTO source VALUES (2, 5) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (2, 5)" +== 107 +-- truncate_limit: 100 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM source ORDER BY sid" +== 108 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 109 +-- truncate_limit: 100 +-- duplicate source row on INSERT should fail because of target_pkey +INSERT INTO source VALUES (4, 40) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (4, 40)" +== 110 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 111 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, NULL) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT VALUES (4, NULL)" +== 112 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 113 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 114 +-- truncate_limit: 100 +-- remove duplicate NOT MATCHED data from source data +DELETE FROM source WHERE sid = 4 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM source WHERE sid = 4" +== 115 +-- truncate_limit: 100 +INSERT INTO source VALUES (4, 40) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (4, 40)" +== 116 +-- truncate_limit: 100 +SELECT * FROM source ORDER BY sid +-- +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM source ORDER BY sid" +== 117 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 118 +-- truncate_limit: 100 +-- remove constraints +alter table target drop CONSTRAINT target_pkey +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE target DROP CONSTRAINT target_pkey" +== 119 +-- truncate_limit: 100 +alter table target alter column tid drop not null +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE target ALTER COLUMN tid DROP NOT NULL" +== 120 +-- truncate_limit: 100 +-- multiple actions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 121 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (4, 4) +WHEN MATCHED THEN + UPDATE SET balance = 0 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT VALUES (4, 4) WH..." +== 122 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 123 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 124 +-- truncate_limit: 100 +-- should be equivalent +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 125 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = 0 +WHEN NOT MATCHED THEN + INSERT VALUES (4, 4) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = 0 WHEN..." +== 126 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 127 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 128 +-- truncate_limit: 100 +-- column references +-- do a simple equivalent of an UPDATE join +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 129 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = t.balance + s.delta +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = t.bala..." +== 130 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 131 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 132 +-- truncate_limit: 100 +-- do a simple equivalent of an INSERT SELECT +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 133 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT VALUES (s.sid, s..." +== 134 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 135 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 136 +-- truncate_limit: 100 +-- and again with duplicate source rows +INSERT INTO source VALUES (5, 50) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (5, 50)" +== 137 +-- truncate_limit: 100 +INSERT INTO source VALUES (5, 50) +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO source VALUES (5, 50)" +== 138 +-- truncate_limit: 100 +-- do a simple equivalent of an INSERT SELECT +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 139 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT VALUES (s.sid, s..." +== 140 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 141 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 142 +-- truncate_limit: 100 +-- removing duplicate source rows +DELETE FROM source WHERE sid = 5 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM source WHERE sid = 5" +== 143 +-- truncate_limit: 100 +-- and again with explicitly identified column list +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 144 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT (tid, balance) V..." +== 145 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 146 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 147 +-- truncate_limit: 100 +-- and again with a subtle error: referring to non-existent target row for NOT MATCHED +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (t.tid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT (tid, balance) V..." +== 148 +-- truncate_limit: 100 +-- and again with a constant ON clause +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 149 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON (SELECT true) +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (t.tid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target t USING source s ON (SELECT ...) WHEN NOT MATCHED THEN INSERT (tid, balance) VA..." +== 150 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 151 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 152 +-- truncate_limit: 100 +-- now the classic UPSERT +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 153 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = t.balance + s.delta +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = t.bala..." +== 154 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 155 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 156 +-- truncate_limit: 100 +-- unreachable WHEN clause should ERROR +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 157 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN /* Terminal WHEN clause for MATCHED */ + DELETE +WHEN MATCHED THEN + UPDATE SET balance = t.balance - s.delta +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED THEN DELETE WHEN MATCHED THEN UP..." +== 158 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 159 +-- truncate_limit: 100 +-- conditional WHEN clause +CREATE TABLE wq_target (tid integer not null, balance integer DEFAULT -1) + WITH (autovacuum_enabled=off) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE wq_target (tid int NOT NULL, balance int DEFAULT -1) WITH (autovacuum_enabled=off)" +== 160 +-- truncate_limit: 100 +CREATE TABLE wq_source (balance integer, sid integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="wq_source" schema="" table="wq_source" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE wq_source (balance int, sid int) WITH (autovacuum_enabled=off)" +== 161 +-- truncate_limit: 100 +INSERT INTO wq_source (sid, balance) VALUES (1, 100) +-- +TABLE: name="wq_source" schema="" table="wq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wq_source (sid, balance) VALUES (1, 100)" +== 162 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 163 +-- truncate_limit: 100 +-- try a simple INSERT with default values first +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT (tid) VALU..." +== 164 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 165 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 166 +-- truncate_limit: 100 +-- this time with a FALSE condition +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND FALSE THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED AND false THEN INSERT ..." +== 167 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 168 +-- truncate_limit: 100 +-- this time with an actual condition which returns false +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND s.balance <> 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED AND s.balance <> 100 T..." +== 169 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 170 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 171 +-- truncate_limit: 100 +-- and now with a condition which returns true +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND s.balance = 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED AND s.balance = 100 TH..." +== 172 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 173 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 174 +-- truncate_limit: 100 +-- conditions in the NOT MATCHED clause can only refer to source columns +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 175 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND t.balance = 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED AND t.balance = 100 TH..." +== 176 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 177 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 178 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED AND s.balance = 100 THEN + INSERT (tid) VALUES (s.sid) +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED AND s.balance = 100 TH..." +== 179 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 180 +-- truncate_limit: 100 +-- conditions in NOT MATCHED BY SOURCE clause can only refer to target columns +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE AND s.balance = 100 THEN + DELETE +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED BY SOURCE AND s.balanc..." +== 181 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN NOT MATCHED BY SOURCE AND t.balance = 100 THEN + DELETE +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN NOT MATCHED BY SOURCE AND t.balanc..." +== 182 +-- truncate_limit: 100 +-- conditions in MATCHED clause can refer to both source and target +SELECT * FROM wq_source +-- +TABLE: name="wq_source" schema="" table="wq_source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_source" +== 183 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND s.balance = 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND s.balance = 100 THEN U..." +== 184 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 185 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.balance = 100 THEN U..." +== 186 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 187 +-- truncate_limit: 100 +-- check if AND works +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 99 AND s.balance > 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.balance = 99 AND s.b..." +== 188 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 189 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 99 AND s.balance = 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.balance = 99 AND s.b..." +== 190 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 191 +-- truncate_limit: 100 +-- check if OR works +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 99 OR s.balance > 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.balance = 99 OR s.ba..." +== 192 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 193 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance = 199 OR s.balance > 100 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.balance = 199 OR s.b..." +== 194 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 195 +-- truncate_limit: 100 +-- check source-side whole-row references +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 196 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON (t.tid = s.sid) +WHEN matched and t = s or t.tid = s.sid THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t = s OR t.tid = s.sid..." +== 197 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 198 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 199 +-- truncate_limit: 100 +-- check if subqueries work in the conditions? +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.balance > (SELECT max(balance) FROM target) THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +TABLE: name="target" schema="" table="target" ctx=Select +ALIAS: "t"="wq_target" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.balance > (SELECT ....." +== 200 +-- truncate_limit: 100 +-- check if we can access system columns in the conditions +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.xmin = t.xmax THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.xmin = t.xmax THEN U..." +== 201 +-- truncate_limit: 100 +MERGE INTO wq_target t +USING wq_source s ON t.tid = s.sid +WHEN MATCHED AND t.tableoid >= 0 THEN + UPDATE SET balance = t.balance + s.balance +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DML +ALIAS: "t"="wq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO wq_target t USING wq_source s ON t.tid = s.sid WHEN MATCHED AND t.tableoid >= 0 THEN U..." +== 202 +-- truncate_limit: 100 +SELECT * FROM wq_target +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wq_target" +== 203 +-- truncate_limit: 100 +DROP TABLE wq_target, wq_source +-- +TABLE: name="wq_target" schema="" table="wq_target" ctx=DDL +TABLE: name="wq_source" schema="" table="wq_source" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE wq_target, wq_source" +== 204 +-- truncate_limit: 100 +-- test triggers +create or replace function merge_trigfunc () returns trigger +language plpgsql as +$$ +DECLARE + line text; +BEGIN + SELECT INTO line format('%s %s %s trigger%s', + TG_WHEN, TG_OP, TG_LEVEL, CASE + WHEN TG_OP = 'INSERT' AND TG_LEVEL = 'ROW' + THEN format(' row: %s', NEW) + WHEN TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW' + THEN format(' row: %s -> %s', OLD, NEW) + WHEN TG_OP = 'DELETE' AND TG_LEVEL = 'ROW' + THEN format(' row: %s', OLD) + END); + + RAISE NOTICE '%', line; + IF (TG_WHEN = 'BEFORE' AND TG_LEVEL = 'ROW') THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + ELSE + RETURN NULL; + END IF; +END; +$$ +-- +FUNCTION: name="merge_trigfunc" function="merge_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION merge_trigfunc() RETURNS trigger LANGUAGE plpgsql AS $$\nDECLARE\n\tline ..." +== 205 +-- truncate_limit: 100 +CREATE TRIGGER merge_bsi BEFORE INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_bsi BEFORE INSERT ON target EXECUTE FUNCTION merge_trigfunc()" +== 206 +-- truncate_limit: 100 +CREATE TRIGGER merge_bsu BEFORE UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_bsu BEFORE UPDATE ON target EXECUTE FUNCTION merge_trigfunc()" +== 207 +-- truncate_limit: 100 +CREATE TRIGGER merge_bsd BEFORE DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_bsd BEFORE DELETE ON target EXECUTE FUNCTION merge_trigfunc()" +== 208 +-- truncate_limit: 100 +CREATE TRIGGER merge_asi AFTER INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_asi AFTER INSERT ON target EXECUTE FUNCTION merge_trigfunc()" +== 209 +-- truncate_limit: 100 +CREATE TRIGGER merge_asu AFTER UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_asu AFTER UPDATE ON target EXECUTE FUNCTION merge_trigfunc()" +== 210 +-- truncate_limit: 100 +CREATE TRIGGER merge_asd AFTER DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_asd AFTER DELETE ON target EXECUTE FUNCTION merge_trigfunc()" +== 211 +-- truncate_limit: 100 +CREATE TRIGGER merge_bri BEFORE INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_bri BEFORE INSERT ON target FOR EACH ROW EXECUTE FUNCTION merge_trigfunc()" +== 212 +-- truncate_limit: 100 +CREATE TRIGGER merge_bru BEFORE UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_bru BEFORE UPDATE ON target FOR EACH ROW EXECUTE FUNCTION merge_trigfunc()" +== 213 +-- truncate_limit: 100 +CREATE TRIGGER merge_brd BEFORE DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_brd BEFORE DELETE ON target FOR EACH ROW EXECUTE FUNCTION merge_trigfunc()" +== 214 +-- truncate_limit: 100 +CREATE TRIGGER merge_ari AFTER INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_ari AFTER INSERT ON target FOR EACH ROW EXECUTE FUNCTION merge_trigfunc()" +== 215 +-- truncate_limit: 100 +CREATE TRIGGER merge_aru AFTER UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_aru AFTER UPDATE ON target FOR EACH ROW EXECUTE FUNCTION merge_trigfunc()" +== 216 +-- truncate_limit: 100 +CREATE TRIGGER merge_ard AFTER DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc () +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_ard AFTER DELETE ON target FOR EACH ROW EXECUTE FUNCTION merge_trigfunc()" +== 217 +-- truncate_limit: 100 +-- now the classic UPSERT, with a DELETE +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 218 +-- truncate_limit: 100 +UPDATE target SET balance = 0 WHERE tid = 3 +-- +TABLE: name="target" schema="" table="target" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE target SET balance = 0 WHERE tid = 3" +== 219 +-- truncate_limit: 100 +--EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND t.balance > s.delta THEN + UPDATE SET balance = t.balance - s.delta +WHEN MATCHED THEN + DELETE +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED AND t.balance > s.delta THEN UPD..." +== 220 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 221 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 222 +-- truncate_limit: 100 +-- UPSERT with UPDATE/DELETE when not matched by source +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 223 +-- truncate_limit: 100 +DELETE FROM SOURCE WHERE sid = 2 +-- +TABLE: name="source" schema="" table="source" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM source WHERE sid = 2" +== 224 +-- truncate_limit: 100 +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND t.balance > s.delta THEN + UPDATE SET balance = t.balance - s.delta +WHEN MATCHED THEN + UPDATE SET balance = 0 +WHEN NOT MATCHED THEN + INSERT VALUES (s.sid, s.delta) +WHEN NOT MATCHED BY SOURCE AND tid = 1 THEN + UPDATE SET balance = 0 +WHEN NOT MATCHED BY SOURCE THEN + DELETE +RETURNING merge_action(), t.* +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t USING source s ON t.tid = s.sid WHEN MATCHED AND t.balance > s.delta THEN UPD..." +== 225 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 226 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 227 +-- truncate_limit: 100 +-- Test behavior of triggers that turn UPDATE/DELETE into no-ops +create or replace function skip_merge_op() returns trigger +language plpgsql as +$$ +BEGIN + RETURN NULL; +END; +$$ +-- +FUNCTION: name="skip_merge_op" function="skip_merge_op" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION skip_merge_op() RETURNS trigger LANGUAGE plpgsql AS $$\nBEGIN\n\tRETURN N..." +== 228 +-- truncate_limit: 100 +SELECT * FROM target full outer join source on (sid = tid) +-- +TABLE: name="target" schema="" table="target" ctx=Select +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target FULL JOIN source ON sid = tid" +== 229 +-- truncate_limit: 100 +create trigger merge_skip BEFORE INSERT OR UPDATE or DELETE + ON target FOR EACH ROW EXECUTE FUNCTION skip_merge_op() +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_skip BEFORE INSERT OR DELETE OR UPDATE ON target FOR EACH ROW EXECUTE FUNCTI..." +== 230 +-- truncate_limit: 100 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND s.sid = 3 THEN UPDATE SET balance = t.balance + s.delta +WHEN MATCHED THEN DELETE +WHEN NOT MATCHED THEN INSERT VALUES (sid, delta); +IF FOUND THEN + RAISE NOTICE 'Found'; +ELSE + RAISE NOTICE 'Not found'; +END IF; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n result integer;\nBEGIN\nMERGE INTO target t\nUSING source AS s\nON t.tid = s.sid\nWHEN..." +== 231 +-- truncate_limit: 100 +SELECT * FROM target FULL OUTER JOIN source ON (sid = tid) +-- +TABLE: name="target" schema="" table="target" ctx=Select +TABLE: name="source" schema="" table="source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target FULL JOIN source ON sid = tid" +== 232 +-- truncate_limit: 100 +DROP TRIGGER merge_skip ON target +-- +TABLE: name="target" schema="" table="target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER merge_skip ON target" +== 233 +-- truncate_limit: 100 +DROP FUNCTION skip_merge_op() +-- +FUNCTION: name="skip_merge_op" function="skip_merge_op" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION skip_merge_op()" +== 234 +-- truncate_limit: 100 +-- test from PL/pgSQL +-- make sure MERGE INTO isn't interpreted to mean returning variables like SELECT INTO +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 235 +-- truncate_limit: 100 +DO LANGUAGE plpgsql $$ +BEGIN +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND t.balance > s.delta THEN + UPDATE SET balance = t.balance - s.delta; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO LANGUAGE plpgsql $$\nBEGIN\nMERGE INTO target t\nUSING source AS s\nON t.tid = s.sid\nWHEN MATCHED ..." +== 236 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 237 +-- truncate_limit: 100 +--source constants +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 238 +-- truncate_limit: 100 +MERGE INTO target t +USING (SELECT 9 AS sid, 57 AS delta) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target t USING (SELECT ...) s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT (tid, bala..." +== 239 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 240 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 241 +-- truncate_limit: 100 +--source query +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 242 +-- truncate_limit: 100 +MERGE INTO target t +USING (SELECT sid, delta FROM source WHERE delta > 0) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="" column="delta" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target t USING (SELECT ... FROM source WHERE ...) s ON t.tid = s.sid WHEN NOT MATCHED ..." +== 243 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 244 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 245 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 246 +-- truncate_limit: 100 +MERGE INTO target t +USING (SELECT sid, delta as newname FROM source WHERE delta > 0) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.newname) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="" column="delta" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target t USING (SELECT ... FROM source WHERE ...) s ON t.tid = s.sid WHEN NOT MATCHED ..." +== 247 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 248 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 249 +-- truncate_limit: 100 +--self-merge +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 250 +-- truncate_limit: 100 +MERGE INTO target t1 +USING target t2 +ON t1.tid = t2.tid +WHEN MATCHED THEN + UPDATE SET balance = t1.balance + t2.balance +WHEN NOT MATCHED THEN + INSERT VALUES (t2.tid, t2.balance) +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t1"="target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO target t1 USING target t2 ON t1.tid = t2.tid WHEN MATCHED THEN UPDATE SET balance = t1..." +== 251 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 252 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 253 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 254 +-- truncate_limit: 100 +MERGE INTO target t +USING (SELECT tid as sid, balance as delta FROM target WHERE balance > 0) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="target" schema="" table="target" ctx=Select +ALIAS: "t"="target" +FILTER: schema="" table="" column="balance" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target t USING (SELECT ... FROM target WHERE ...) s ON t.tid = s.sid WHEN NOT MATCHED ..." +== 255 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 256 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 257 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 258 +-- truncate_limit: 100 +MERGE INTO target t +USING +(SELECT sid, max(delta) AS delta + FROM source + GROUP BY sid + HAVING count(*) = 1 + ORDER BY sid ASC) AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + INSERT (tid, balance) VALUES (s.sid, s.delta) +-- +TABLE: name="target" schema="" table="target" ctx=DML +TABLE: name="source" schema="" table="source" ctx=Select +ALIAS: "t"="target" +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO target t USING (SELECT ... FROM source GROUP BY sid HAVING count(*) = 1 ORDER BY sid A..." +== 259 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 260 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 261 +-- truncate_limit: 100 +-- plpgsql parameters and results +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 262 +-- truncate_limit: 100 +CREATE FUNCTION merge_func (p_id integer, p_bal integer) +RETURNS INTEGER +LANGUAGE plpgsql +AS $$ +DECLARE + result integer; +BEGIN +MERGE INTO target t +USING (SELECT p_id AS sid) AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = t.balance - p_bal; +IF FOUND THEN + GET DIAGNOSTICS result := ROW_COUNT; +END IF; +RETURN result; +END; +$$ +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION merge_func(p_id int, p_bal int) RETURNS int LANGUAGE plpgsql AS $$\nDECLARE\n resul..." +== 263 +-- truncate_limit: 100 +SELECT merge_func(3, 4) +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT merge_func(3, 4)" +== 264 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 265 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 266 +-- truncate_limit: 100 +-- PREPARE +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 267 +-- truncate_limit: 100 +prepare foom as merge into target t using (select 1 as sid) s on (t.tid = s.sid) when matched then update set balance = 1 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: PrepareStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "PREPARE foom AS MERGE INTO target t USING (SELECT 1 AS sid) s ON t.tid = s.sid WHEN MATCHED THEN ..." +== 268 +-- truncate_limit: 100 +execute foom +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foom" +== 269 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 270 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 271 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 272 +-- truncate_limit: 100 +PREPARE foom2 (integer, integer) AS +MERGE INTO target t +USING (SELECT 1) s +ON t.tid = $1 +WHEN MATCHED THEN +UPDATE SET balance = $2 +-- +TABLE: name="target" schema="" table="target" ctx=DML +ALIAS: "t"="target" +STMT: PrepareStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "PREPARE foom2(int, int) AS MERGE INTO target t USING (SELECT 1) s ON t.tid = $1 WHEN MATCHED THEN..." +== 273 +-- truncate_limit: 100 +--EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) +execute foom2 (1, 1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foom2(1, 1)" +== 274 +-- truncate_limit: 100 +SELECT * FROM target ORDER BY tid +-- +TABLE: name="target" schema="" table="target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM target ORDER BY tid" +== 275 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 276 +-- truncate_limit: 100 +-- subqueries in source relation + +CREATE TABLE sq_target (tid integer NOT NULL, balance integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sq_target (tid int NOT NULL, balance int) WITH (autovacuum_enabled=off)" +== 277 +-- truncate_limit: 100 +CREATE TABLE sq_source (delta integer, sid integer, balance integer DEFAULT 0) + WITH (autovacuum_enabled=off) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sq_source (delta int, sid int, balance int DEFAULT 0) WITH (autovacuum_enabled=off)" +== 278 +-- truncate_limit: 100 +INSERT INTO sq_target(tid, balance) VALUES (1,100), (2,200), (3,300) +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sq_target (tid, balance) VALUES (1, 100), (2, 200), (3, 300)" +== 279 +-- truncate_limit: 100 +INSERT INTO sq_source(sid, delta) VALUES (1,10), (2,20), (4,40) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sq_source (sid, delta) VALUES (1, 10), (2, 20), (4, 40)" +== 280 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 281 +-- truncate_limit: 100 +MERGE INTO sq_target t +USING (SELECT * FROM sq_source) s +ON tid = sid +WHEN MATCHED AND t.balance > delta THEN + UPDATE SET balance = t.balance + delta +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_source" schema="" table="sq_source" ctx=Select +ALIAS: "t"="sq_target" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO sq_target t USING (SELECT * FROM sq_source) s ON tid = sid WHEN MATCHED AND t.balance ..." +== 282 +-- truncate_limit: 100 +SELECT * FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target" +== 283 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 284 +-- truncate_limit: 100 +-- try a view +CREATE VIEW v AS SELECT * FROM sq_source WHERE sid < 2 +-- +TABLE: name="v" schema="" table="v" ctx=DDL +TABLE: name="sq_source" schema="" table="sq_source" ctx=Select +FILTER: schema="" table="" column="sid" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v AS SELECT * FROM sq_source WHERE sid < 2" +== 285 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 286 +-- truncate_limit: 100 +MERGE INTO sq_target +USING v +ON tid = sid +WHEN MATCHED THEN + UPDATE SET balance = v.balance + delta +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO sq_target USING v ON tid = sid WHEN MATCHED THEN UPDATE SET balance = v.balance + delta" +== 287 +-- truncate_limit: 100 +SELECT * FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target" +== 288 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 289 +-- truncate_limit: 100 +-- ambiguous reference to a column +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 290 +-- truncate_limit: 100 +MERGE INTO sq_target +USING v +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO sq_target USING v ON tid = sid WHEN MATCHED AND tid >= 2 THEN UPDATE SET balance = bal..." +== 291 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 292 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 293 +-- truncate_limit: 100 +INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10)" +== 294 +-- truncate_limit: 100 +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +ALIAS: "t"="sq_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO sq_target t USING v ON tid = sid WHEN MATCHED AND tid >= 2 THEN UPDATE SET balance = t..." +== 295 +-- truncate_limit: 100 +SELECT * FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target" +== 296 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 297 +-- truncate_limit: 100 +-- CTEs +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 298 +-- truncate_limit: 100 +INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10) +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10)" +== 299 +-- truncate_limit: 100 +WITH targq AS ( + SELECT * FROM v +) +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="v" schema="" table="v" ctx=Select +ALIAS: "t"="sq_target" +CTE: "targq" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "WITH targq AS (...) MERGE INTO sq_target t USING v ON tid = sid WHEN MATCHED AND tid >= 2 THEN UP..." +== 300 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 301 +-- truncate_limit: 100 +-- RETURNING +SELECT * FROM sq_source ORDER BY sid +-- +TABLE: name="sq_source" schema="" table="sq_source" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_source ORDER BY sid" +== 302 +-- truncate_limit: 100 +SELECT * FROM sq_target ORDER BY tid +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target ORDER BY tid" +== 303 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 304 +-- truncate_limit: 100 +CREATE TABLE merge_actions(action text, abbrev text) +-- +TABLE: name="merge_actions" schema="" table="merge_actions" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE merge_actions (action text, abbrev text)" +== 305 +-- truncate_limit: 100 +INSERT INTO merge_actions VALUES ('INSERT', 'ins'), ('UPDATE', 'upd'), ('DELETE', 'del') +-- +TABLE: name="merge_actions" schema="" table="merge_actions" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO merge_actions VALUES ('INSERT', 'ins'), ('UPDATE', 'upd'), ('DELETE', 'del')" +== 306 +-- truncate_limit: 100 +MERGE INTO sq_target t +USING sq_source s +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE +RETURNING (SELECT abbrev FROM merge_actions + WHERE action = merge_action()) AS action, + t.*, + CASE merge_action() + WHEN 'INSERT' THEN 'Inserted '||t + WHEN 'UPDATE' THEN 'Added '||delta||' to balance' + WHEN 'DELETE' THEN 'Removed '||t + END AS description +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="merge_actions" schema="" table="merge_actions" ctx=Select +ALIAS: "t"="sq_target" +FILTER: schema="" table="" column="action" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO sq_target t USING sq_source s ON tid = sid WHEN MATCHED AND tid >= 2 THEN UPDATE SET b..." +== 307 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 308 +-- truncate_limit: 100 +-- error when using merge_action() outside MERGE +SELECT merge_action() FROM sq_target +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT merge_action() FROM sq_target" +== 309 +-- truncate_limit: 100 +UPDATE sq_target SET balance = balance + 1 RETURNING merge_action() +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE sq_target SET balance = balance + 1 RETURNING merge_action()" +== 310 +-- truncate_limit: 100 +-- RETURNING in CTEs +CREATE TABLE sq_target_merge_log (tid integer NOT NULL, last_change text) +-- +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sq_target_merge_log (tid int NOT NULL, last_change text)" +== 311 +-- truncate_limit: 100 +INSERT INTO sq_target_merge_log VALUES (1, 'Original value') +-- +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sq_target_merge_log VALUES (1, 'Original value')" +== 312 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 313 +-- truncate_limit: 100 +WITH m AS ( + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action() AS action, t.*, + CASE merge_action() + WHEN 'INSERT' THEN 'Inserted '||t + WHEN 'UPDATE' THEN 'Added '||delta||' to balance' + WHEN 'DELETE' THEN 'Removed '||t + END AS description +), m2 AS ( + MERGE INTO sq_target_merge_log l + USING m + ON l.tid = m.tid + WHEN MATCHED THEN + UPDATE SET last_change = description + WHEN NOT MATCHED THEN + INSERT VALUES (m.tid, description) + RETURNING action, merge_action() AS log_action, l.* +) +SELECT * FROM m2 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DML +ALIAS: "l"="sq_target_merge_log" +ALIAS: "t"="sq_target" +CTE: "m" +CTE: "m2" +STMT: SelectStmt +STMT: MergeStmt +TRUNCATED: "WITH m AS (...), m2 AS (...) SELECT * FROM m2" +== 314 +-- truncate_limit: 100 +SELECT * FROM sq_target_merge_log ORDER BY tid +-- +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target_merge_log ORDER BY tid" +== 315 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 316 +-- truncate_limit: 100 +-- COPY (MERGE ... RETURNING) TO ... +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 317 +-- truncate_limit: 100 +COPY ( + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.* +) TO stdout +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +ALIAS: "t"="sq_target" +STMT: CopyStmt +TRUNCATED: "COPY (MERGE INTO sq_target t USING sq_source s ON tid = sid WHEN MATCHED AND tid >= 2 THEN UPDATE..." +== 318 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 319 +-- truncate_limit: 100 +-- SQL function with MERGE ... RETURNING +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 320 +-- truncate_limit: 100 +CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, + OUT action text, OUT tid int, OUT new_balance int) +LANGUAGE sql AS +$$ + MERGE INTO sq_target t + USING (VALUES ($1, $2, $3)) AS v(sid, balance, delta) + ON tid = v.sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + v.delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (v.balance + v.delta, v.sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.*; +$$ +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, OUT action text, OUT tid in..." +== 321 +-- truncate_limit: 100 +SELECT m.* +FROM (VALUES (1, 0, 0), (3, 0, 20), (4, 100, 10)) AS v(sid, balance, delta), +LATERAL (SELECT action, tid, new_balance FROM merge_into_sq_target(sid, balance, delta)) m +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT m.* FROM (VALUES (...)) v(sid, balance, delta), LATERAL (SELECT ... FROM merge_into_sq_tar..." +== 322 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 323 +-- truncate_limit: 100 +-- SQL SRF with MERGE ... RETURNING +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 324 +-- truncate_limit: 100 +CREATE FUNCTION merge_sq_source_into_sq_target() +RETURNS TABLE (action text, tid int, balance int) +LANGUAGE sql AS +$$ + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.*; +$$ +-- +FUNCTION: name="merge_sq_source_into_sq_target" function="merge_sq_source_into_sq_target" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION merge_sq_source_into_sq_target() RETURNS TABLE (action text, tid int, balance int..." +== 325 +-- truncate_limit: 100 +SELECT * FROM merge_sq_source_into_sq_target() +-- +FUNCTION: name="merge_sq_source_into_sq_target" function="merge_sq_source_into_sq_target" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM merge_sq_source_into_sq_target()" +== 326 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 327 +-- truncate_limit: 100 +-- PL/pgSQL function with MERGE ... RETURNING ... INTO +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 328 +-- truncate_limit: 100 +CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, + OUT r_action text, OUT r_tid int, OUT r_balance int) +LANGUAGE plpgsql AS +$$ +BEGIN + MERGE INTO sq_target t + USING (VALUES ($1, $2, $3)) AS v(sid, balance, delta) + ON tid = v.sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + v.delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (v.balance + v.delta, v.sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.* INTO r_action, r_tid, r_balance; +END; +$$ +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, OUT r_action text, OUT r_ti..." +== 329 +-- truncate_limit: 100 +SELECT m.* +FROM (VALUES (1, 0, 0), (3, 0, 20), (4, 100, 10)) AS v(sid, balance, delta), +LATERAL (SELECT r_action, r_tid, r_balance FROM merge_into_sq_target(sid, balance, delta)) m +-- +FUNCTION: name="merge_into_sq_target" function="merge_into_sq_target" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT m.* FROM (VALUES (...)) v(sid, balance, delta), LATERAL (SELECT ... FROM merge_into_sq_tar..." +== 330 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 331 +-- truncate_limit: 100 +-- EXPLAIN +CREATE TABLE ex_mtarget (a int, b int) + WITH (autovacuum_enabled=off) +-- +TABLE: name="ex_mtarget" schema="" table="ex_mtarget" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ex_mtarget (a int, b int) WITH (autovacuum_enabled=off)" +== 332 +-- truncate_limit: 100 +CREATE TABLE ex_msource (a int, b int) + WITH (autovacuum_enabled=off) +-- +TABLE: name="ex_msource" schema="" table="ex_msource" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ex_msource (a int, b int) WITH (autovacuum_enabled=off)" +== 333 +-- truncate_limit: 100 +INSERT INTO ex_mtarget SELECT i, i*10 FROM generate_series(1,100,2) i +-- +TABLE: name="ex_mtarget" schema="" table="ex_mtarget" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ex_mtarget SELECT i, i * 10 FROM generate_series(1, 100, 2) i" +== 334 +-- truncate_limit: 100 +INSERT INTO ex_msource SELECT i, i*10 FROM generate_series(1,100,1) i +-- +TABLE: name="ex_msource" schema="" table="ex_msource" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ex_msource SELECT i, i * 10 FROM generate_series(1, 100, 1) i" +== 335 +-- truncate_limit: 100 +CREATE FUNCTION explain_merge(query text) RETURNS SETOF text +LANGUAGE plpgsql AS +$$ +DECLARE ln text; +BEGIN + FOR ln IN + EXECUTE 'explain (analyze, timing off, summary off, costs off) ' || + query + LOOP + ln := regexp_replace(ln, '(Memory( Usage)?|Buckets|Batches): \S*', '\1: xxx', 'g'); + RETURN NEXT ln; + END LOOP; +END; +$$ +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_merge(query text) RETURNS SETOF text LANGUAGE plpgsql AS $$\nDECLARE ln te..." +== 336 +-- truncate_limit: 100 +-- only updates +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED THEN + UPDATE SET b = t.b + 1') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 337 +-- truncate_limit: 100 +-- only updates to selected tuples +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 338 +-- truncate_limit: 100 +-- updates + deletes +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1 +WHEN MATCHED AND t.a >= 10 AND t.a <= 20 THEN + DELETE') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 339 +-- truncate_limit: 100 +-- only inserts +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED AND s.a < 10 THEN + INSERT VALUES (a, b)') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 340 +-- truncate_limit: 100 +-- all three +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1 +WHEN MATCHED AND t.a >= 30 AND t.a <= 40 THEN + DELETE +WHEN NOT MATCHED AND s.a < 20 THEN + INSERT VALUES (a, b)') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 341 +-- truncate_limit: 100 +-- not matched by source +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED BY SOURCE and t.a < 10 THEN + DELETE') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 342 +-- truncate_limit: 100 +-- not matched by source and target +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED BY SOURCE AND t.a < 10 THEN + DELETE +WHEN NOT MATCHED BY TARGET AND s.a < 20 THEN + INSERT VALUES (a, b)') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 343 +-- truncate_limit: 100 +-- nothing +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a AND t.a < -1000 +WHEN MATCHED AND t.a < 10 THEN + DO NOTHING') +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 344 +-- truncate_limit: 100 +DROP TABLE ex_msource, ex_mtarget +-- +TABLE: name="ex_msource" schema="" table="ex_msource" ctx=DDL +TABLE: name="ex_mtarget" schema="" table="ex_mtarget" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ex_msource, ex_mtarget" +== 345 +-- truncate_limit: 100 +DROP FUNCTION explain_merge(text) +-- +FUNCTION: name="explain_merge" function="explain_merge" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION explain_merge(text)" +== 346 +-- truncate_limit: 100 +-- EXPLAIN SubPlans and InitPlans +CREATE TABLE src (a int, b int, c int, d int) +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE src (a int, b int, c int, d int)" +== 347 +-- truncate_limit: 100 +CREATE TABLE tgt (a int, b int, c int, d int) +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tgt (a int, b int, c int, d int)" +== 348 +-- truncate_limit: 100 +CREATE TABLE ref (ab int, cd int) +-- +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref (ab int, cd int)" +== 349 +-- truncate_limit: 100 +EXPLAIN (verbose, costs off) +MERGE INTO tgt t +USING (SELECT *, (SELECT count(*) FROM ref r + WHERE r.ab = s.a + s.b + AND r.cd = s.c - s.d) cnt + FROM src s) s +ON t.a = s.a AND t.b < s.cnt +WHEN MATCHED AND t.c > s.cnt THEN + UPDATE SET (b, c) = (SELECT s.b, s.cnt) +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DML +TABLE: name="src" schema="" table="src" ctx=Select +TABLE: name="ref" schema="" table="ref" ctx=Select +ALIAS: "r"="ref" +ALIAS: "s"="src" +ALIAS: "t"="tgt" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="r" column="ab" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="r" column="cd" +FILTER: schema="" table="s" column="c" +FILTER: schema="" table="s" column="d" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) MERGE INTO tgt t USING (SELECT *, (SELECT count(*) FROM ref r WHERE ..." +== 350 +-- truncate_limit: 100 +DROP TABLE src, tgt, ref +-- +TABLE: name="src" schema="" table="src" ctx=DDL +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +TABLE: name="ref" schema="" table="ref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE src, tgt, ref" +== 351 +-- truncate_limit: 100 +-- Subqueries +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 352 +-- truncate_limit: 100 +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED THEN + UPDATE SET balance = (SELECT count(*) FROM sq_target) +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +ALIAS: "t"="sq_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO sq_target t USING v ON tid = sid WHEN MATCHED THEN UPDATE SET balance = (SELECT ... FR..." +== 353 +-- truncate_limit: 100 +SELECT * FROM sq_target WHERE tid = 1 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +FILTER: schema="" table="" column="tid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target WHERE tid = 1" +== 354 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 355 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 356 +-- truncate_limit: 100 +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED AND (SELECT count(*) > 0 FROM sq_target) THEN + UPDATE SET balance = 42 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +ALIAS: "t"="sq_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO sq_target t USING v ON tid = sid WHEN MATCHED AND (SELECT ... FROM sq_target) THEN UPD..." +== 357 +-- truncate_limit: 100 +SELECT * FROM sq_target WHERE tid = 1 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +FILTER: schema="" table="" column="tid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target WHERE tid = 1" +== 358 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 359 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 360 +-- truncate_limit: 100 +MERGE INTO sq_target t +USING v +ON tid = sid AND (SELECT count(*) > 0 FROM sq_target) +WHEN MATCHED THEN + UPDATE SET balance = 42 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DML +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +ALIAS: "t"="sq_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO sq_target t USING v ON tid = sid AND (SELECT ... FROM sq_target) WHEN MATCHED THEN UPD..." +== 361 +-- truncate_limit: 100 +SELECT * FROM sq_target WHERE tid = 1 +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=Select +FILTER: schema="" table="" column="tid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sq_target WHERE tid = 1" +== 362 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 363 +-- truncate_limit: 100 +DROP TABLE sq_target, sq_target_merge_log, sq_source CASCADE +-- +TABLE: name="sq_target" schema="" table="sq_target" ctx=DDL +TABLE: name="sq_target_merge_log" schema="" table="sq_target_merge_log" ctx=DDL +TABLE: name="sq_source" schema="" table="sq_source" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sq_target, sq_target_merge_log, sq_source CASCADE" +== 364 +-- truncate_limit: 100 +CREATE TABLE pa_target (tid integer, balance float, val text) + PARTITION BY LIST (tid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_target (tid int, balance double precision, val text) PARTITION BY LIST (tid)" +== 365 +-- truncate_limit: 100 +CREATE TABLE part1 PARTITION OF pa_target FOR VALUES IN (1,4) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part1 PARTITION OF pa_target FOR VALUES IN (1, 4) WITH (autovacuum_enabled=off)" +== 366 +-- truncate_limit: 100 +CREATE TABLE part2 PARTITION OF pa_target FOR VALUES IN (2,5,6) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part2 PARTITION OF pa_target FOR VALUES IN (2, 5, 6) WITH (autovacuum_enabled=off)" +== 367 +-- truncate_limit: 100 +CREATE TABLE part3 PARTITION OF pa_target FOR VALUES IN (3,8,9) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part3 PARTITION OF pa_target FOR VALUES IN (3, 8, 9) WITH (autovacuum_enabled=off)" +== 368 +-- truncate_limit: 100 +CREATE TABLE part4 PARTITION OF pa_target DEFAULT + WITH (autovacuum_enabled=off) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part4 PARTITION OF pa_target DEFAULT WITH (autovacuum_enabled=off)" +== 369 +-- truncate_limit: 100 +CREATE TABLE pa_source (sid integer, delta float) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_source (sid int, delta double precision)" +== 370 +-- truncate_limit: 100 +-- insert many rows to the source table +INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1, 14) id" +== 371 +-- truncate_limit: 100 +-- insert a few rows in the target table (odd numbered tid) +INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,15,2) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1, 15, 2) id" +== 372 +-- truncate_limit: 100 +-- try simple MERGE +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 373 +-- truncate_limit: 100 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source' +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid WHEN MATCHED THEN UPDATE SET balance = ..." +== 374 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 375 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 376 +-- truncate_limit: 100 +-- same with a constant qual +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 377 +-- truncate_limit: 100 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND tid = 1 + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source' +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid AND tid = 1 WHEN MATCHED THEN UPDATE SE..." +== 378 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 379 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 380 +-- truncate_limit: 100 +-- try updating the partition key column +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 381 +-- truncate_limit: 100 +CREATE FUNCTION merge_func() RETURNS integer LANGUAGE plpgsql AS $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET tid = 1, val = val || ' not matched by source'; +IF FOUND THEN + GET DIAGNOSTICS result := ROW_COUNT; +END IF; +RETURN result; +END; +$$ +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION merge_func() RETURNS int LANGUAGE plpgsql AS $$\nDECLARE\n result integer;\nBEGIN\nM..." +== 382 +-- truncate_limit: 100 +SELECT merge_func() +-- +FUNCTION: name="merge_func" function="merge_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT merge_func()" +== 383 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 384 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 385 +-- truncate_limit: 100 +-- update partition key to partition not initially scanned +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 386 +-- truncate_limit: 100 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND t.tid = 1 + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + RETURNING merge_action(), t.* +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid AND t.tid = 1 WHEN MATCHED THEN UPDATE ..." +== 387 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid" +== 388 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 389 +-- truncate_limit: 100 +-- bug #18871: ExecInitPartitionInfo()'s handling of DO NOTHING actions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 390 +-- truncate_limit: 100 +TRUNCATE pa_target +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE pa_target" +== 391 +-- truncate_limit: 100 +MERGE INTO pa_target t + USING (VALUES (10, 100)) AS s(sid, delta) + ON t.tid = s.sid + WHEN NOT MATCHED THEN + INSERT VALUES (1, 10, 'inserted by merge') + WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO pa_target t USING (VALUES (...)) s(sid, delta) ON t.tid = s.sid WHEN NOT MATCHED THEN ..." +== 392 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 393 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 394 +-- truncate_limit: 100 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_target CASCADE" +== 395 +-- truncate_limit: 100 +-- The target table is partitioned in the same way, but this time by attaching +-- partitions which have columns in different order, dropped columns etc. +CREATE TABLE pa_target (tid integer, balance float, val text) + PARTITION BY LIST (tid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_target (tid int, balance double precision, val text) PARTITION BY LIST (tid)" +== 396 +-- truncate_limit: 100 +CREATE TABLE part1 (tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part1" schema="" table="part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part1 (tid int, balance double precision, val text) WITH (autovacuum_enabled=off)" +== 397 +-- truncate_limit: 100 +CREATE TABLE part2 (balance float, tid integer, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part2" schema="" table="part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part2 (balance double precision, tid int, val text) WITH (autovacuum_enabled=off)" +== 398 +-- truncate_limit: 100 +CREATE TABLE part3 (tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part3" schema="" table="part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part3 (tid int, balance double precision, val text) WITH (autovacuum_enabled=off)" +== 399 +-- truncate_limit: 100 +CREATE TABLE part4 (extraid text, tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part4 (extraid text, tid int, balance double precision, val text) WITH (autovacuum_e..." +== 400 +-- truncate_limit: 100 +ALTER TABLE part4 DROP COLUMN extraid +-- +TABLE: name="part4" schema="" table="part4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part4 DROP extraid" +== 401 +-- truncate_limit: 100 +ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1, 4)" +== 402 +-- truncate_limit: 100 +ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2, 5, 6)" +== 403 +-- truncate_limit: 100 +ALTER TABLE pa_target ATTACH PARTITION part3 FOR VALUES IN (3,8,9) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pa_target ATTACH PARTITION part3 FOR VALUES IN (3, 8, 9)" +== 404 +-- truncate_limit: 100 +ALTER TABLE pa_target ATTACH PARTITION part4 DEFAULT +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pa_target ATTACH PARTITION part4 DEFAULT" +== 405 +-- truncate_limit: 100 +-- insert a few rows in the target table (odd numbered tid) +INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,15,2) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1, 15, 2) id" +== 406 +-- truncate_limit: 100 +-- try simple MERGE +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 407 +-- truncate_limit: 100 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n result integer;\nBEGIN\nMERGE INTO pa_target t\n USING pa_source s\n ON t.tid = s.s..." +== 408 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 409 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 410 +-- truncate_limit: 100 +-- same with a constant qual +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 411 +-- truncate_limit: 100 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND tid IN (1, 5) + WHEN MATCHED AND tid % 5 = 0 THEN DELETE + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source' +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid AND tid IN (1, 5) WHEN MATCHED AND (tid..." +== 412 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 413 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 414 +-- truncate_limit: 100 +-- try updating the partition key column +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 415 +-- truncate_limit: 100 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET tid = 1, val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n result integer;\nBEGIN\nMERGE INTO pa_target t\n USING pa_source s\n ON t.tid = s.s..." +== 416 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 417 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 418 +-- truncate_limit: 100 +-- as above, but blocked by BEFORE DELETE ROW trigger +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 419 +-- truncate_limit: 100 +CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS + $$ BEGIN RETURN NULL; END; $$ +-- +FUNCTION: name="trig_fn" function="trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RETURN NULL; END; $$" +== 420 +-- truncate_limit: 100 +CREATE TRIGGER del_trig BEFORE DELETE ON pa_target + FOR EACH ROW EXECUTE PROCEDURE trig_fn() +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER del_trig BEFORE DELETE ON pa_target FOR EACH ROW EXECUTE FUNCTION trig_fn()" +== 421 +-- truncate_limit: 100 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n result integer;\nBEGIN\nMERGE INTO pa_target t\n USING pa_source s\n ON t.tid = s.s..." +== 422 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 423 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 424 +-- truncate_limit: 100 +-- as above, but blocked by BEFORE INSERT ROW trigger +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 425 +-- truncate_limit: 100 +CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS + $$ BEGIN RETURN NULL; END; $$ +-- +FUNCTION: name="trig_fn" function="trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RETURN NULL; END; $$" +== 426 +-- truncate_limit: 100 +CREATE TRIGGER ins_trig BEFORE INSERT ON pa_target + FOR EACH ROW EXECUTE PROCEDURE trig_fn() +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER ins_trig BEFORE INSERT ON pa_target FOR EACH ROW EXECUTE FUNCTION trig_fn()" +== 427 +-- truncate_limit: 100 +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n result integer;\nBEGIN\nMERGE INTO pa_target t\n USING pa_source s\n ON t.tid = s.s..." +== 428 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid, val +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid, val" +== 429 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 430 +-- truncate_limit: 100 +-- test RLS enforcement +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 431 +-- truncate_limit: 100 +ALTER TABLE pa_target ENABLE ROW LEVEL SECURITY +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pa_target ENABLE ROW LEVEL SECURITY" +== 432 +-- truncate_limit: 100 +ALTER TABLE pa_target FORCE ROW LEVEL SECURITY +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pa_target FORCE ROW LEVEL SECURITY" +== 433 +-- truncate_limit: 100 +CREATE POLICY pa_target_pol ON pa_target USING (tid != 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY pa_target_pol ON pa_target TO public USING (tid <> 0)" +== 434 +-- truncate_limit: 100 +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid AND t.tid IN (1,2,3,4) + WHEN MATCHED THEN + UPDATE SET tid = tid - 1 +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid AND t.tid IN (1, 2, 3, 4) WHEN MATCHED ..." +== 435 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 436 +-- truncate_limit: 100 +DROP TABLE pa_source +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_source" +== 437 +-- truncate_limit: 100 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_target CASCADE" +== 438 +-- truncate_limit: 100 +-- Sub-partitioning +CREATE TABLE pa_target (logts timestamp, tid integer, balance float, val text) + PARTITION BY RANGE (logts) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_target (logts timestamp, tid int, balance double precision, val text) PARTITION B..." +== 439 +-- truncate_limit: 100 +CREATE TABLE part_m01 PARTITION OF pa_target + FOR VALUES FROM ('2017-01-01') TO ('2017-02-01') + PARTITION BY LIST (tid) +-- +TABLE: name="part_m01" schema="" table="part_m01" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_m01 PARTITION OF pa_target FOR VALUES FROM ('2017-01-01') TO ('2017-02-01') PAR..." +== 440 +-- truncate_limit: 100 +CREATE TABLE part_m01_odd PARTITION OF part_m01 + FOR VALUES IN (1,3,5,7,9) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m01_odd" schema="" table="part_m01_odd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_m01_odd PARTITION OF part_m01 FOR VALUES IN (1, 3, 5, 7, 9) WITH (autovacuum_en..." +== 441 +-- truncate_limit: 100 +CREATE TABLE part_m01_even PARTITION OF part_m01 + FOR VALUES IN (2,4,6,8) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m01_even" schema="" table="part_m01_even" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_m01_even PARTITION OF part_m01 FOR VALUES IN (2, 4, 6, 8) WITH (autovacuum_enab..." +== 442 +-- truncate_limit: 100 +CREATE TABLE part_m02 PARTITION OF pa_target + FOR VALUES FROM ('2017-02-01') TO ('2017-03-01') + PARTITION BY LIST (tid) +-- +TABLE: name="part_m02" schema="" table="part_m02" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_m02 PARTITION OF pa_target FOR VALUES FROM ('2017-02-01') TO ('2017-03-01') PAR..." +== 443 +-- truncate_limit: 100 +CREATE TABLE part_m02_odd PARTITION OF part_m02 + FOR VALUES IN (1,3,5,7,9) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m02_odd" schema="" table="part_m02_odd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_m02_odd PARTITION OF part_m02 FOR VALUES IN (1, 3, 5, 7, 9) WITH (autovacuum_en..." +== 444 +-- truncate_limit: 100 +CREATE TABLE part_m02_even PARTITION OF part_m02 + FOR VALUES IN (2,4,6,8) WITH (autovacuum_enabled=off) +-- +TABLE: name="part_m02_even" schema="" table="part_m02_even" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_m02_even PARTITION OF part_m02 FOR VALUES IN (2, 4, 6, 8) WITH (autovacuum_enab..." +== 445 +-- truncate_limit: 100 +CREATE TABLE pa_source (sid integer, delta float) + WITH (autovacuum_enabled=off) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_source (sid int, delta double precision) WITH (autovacuum_enabled=off)" +== 446 +-- truncate_limit: 100 +-- insert many rows to the source table +INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1, 14) id" +== 447 +-- truncate_limit: 100 +-- insert a few rows in the target table (odd numbered tid) +INSERT INTO pa_target SELECT '2017-01-31', id, id * 100, 'initial' FROM generate_series(1,9,3) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pa_target SELECT '2017-01-31', id, id * 100, 'initial' FROM generate_series(1, 9, 3) id" +== 448 +-- truncate_limit: 100 +INSERT INTO pa_target SELECT '2017-02-28', id, id * 100, 'initial' FROM generate_series(2,9,3) AS id +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pa_target SELECT '2017-02-28', id, id * 100, 'initial' FROM generate_series(2, 9, 3) id" +== 449 +-- truncate_limit: 100 +-- try simple MERGE +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 450 +-- truncate_limit: 100 +MERGE INTO pa_target t + USING (SELECT '2017-01-15' AS slogts, * FROM pa_source WHERE sid < 10) s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (slogts::timestamp, sid, delta, 'inserted by merge') + RETURNING merge_action(), t.* +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +TABLE: name="pa_source" schema="" table="pa_source" ctx=Select +ALIAS: "t"="pa_target" +FILTER: schema="" table="" column="sid" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO pa_target t USING (SELECT ... FROM pa_source WHERE ...) s ON t.tid = s.sid WHEN MATCHE..." +== 451 +-- truncate_limit: 100 +SELECT * FROM pa_target ORDER BY tid +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target ORDER BY tid" +== 452 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 453 +-- truncate_limit: 100 +DROP TABLE pa_source +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_source" +== 454 +-- truncate_limit: 100 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_target CASCADE" +== 455 +-- truncate_limit: 100 +-- Partitioned table with primary key + +CREATE TABLE pa_target (tid integer PRIMARY KEY) PARTITION BY LIST (tid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_target (tid int PRIMARY KEY) PARTITION BY LIST (tid)" +== 456 +-- truncate_limit: 100 +CREATE TABLE pa_targetp PARTITION OF pa_target DEFAULT +-- +TABLE: name="pa_targetp" schema="" table="pa_targetp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_targetp PARTITION OF pa_target DEFAULT" +== 457 +-- truncate_limit: 100 +CREATE TABLE pa_source (sid integer) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pa_source (sid int)" +== 458 +-- truncate_limit: 100 +INSERT INTO pa_source VALUES (1), (2) +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pa_source VALUES (1), (2)" +== 459 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: ExplainStmt +STMT: MergeStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid WHEN NOT M..." +== 460 +-- truncate_limit: 100 +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT VALUES (s...." +== 461 +-- truncate_limit: 100 +TABLE pa_target +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pa_target" +== 462 +-- truncate_limit: 100 +-- Partition-less partitioned table +-- (the bug we are checking for appeared only if table had partitions before) + +DROP TABLE pa_targetp +-- +TABLE: name="pa_targetp" schema="" table="pa_targetp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_targetp" +== 463 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: ExplainStmt +STMT: MergeStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid WHEN NOT M..." +== 464 +-- truncate_limit: 100 +MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid + WHEN NOT MATCHED THEN INSERT VALUES (s.sid) +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DML +ALIAS: "t"="pa_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO pa_target t USING pa_source s ON t.tid = s.sid WHEN NOT MATCHED THEN INSERT VALUES (s...." +== 465 +-- truncate_limit: 100 +DROP TABLE pa_source +-- +TABLE: name="pa_source" schema="" table="pa_source" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_source" +== 466 +-- truncate_limit: 100 +DROP TABLE pa_target CASCADE +-- +TABLE: name="pa_target" schema="" table="pa_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pa_target CASCADE" +== 467 +-- truncate_limit: 100 +-- some complex joins on the source side + +CREATE TABLE cj_target (tid integer, balance float, val text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cj_target (tid int, balance double precision, val text) WITH (autovacuum_enabled=off)" +== 468 +-- truncate_limit: 100 +CREATE TABLE cj_source1 (sid1 integer, scat integer, delta integer) + WITH (autovacuum_enabled=off) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cj_source1 (sid1 int, scat int, delta int) WITH (autovacuum_enabled=off)" +== 469 +-- truncate_limit: 100 +CREATE TABLE cj_source2 (sid2 integer, sval text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cj_source2 (sid2 int, sval text) WITH (autovacuum_enabled=off)" +== 470 +-- truncate_limit: 100 +INSERT INTO cj_source1 VALUES (1, 10, 100) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cj_source1 VALUES (1, 10, 100)" +== 471 +-- truncate_limit: 100 +INSERT INTO cj_source1 VALUES (1, 20, 200) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cj_source1 VALUES (1, 20, 200)" +== 472 +-- truncate_limit: 100 +INSERT INTO cj_source1 VALUES (2, 20, 300) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cj_source1 VALUES (2, 20, 300)" +== 473 +-- truncate_limit: 100 +INSERT INTO cj_source1 VALUES (3, 10, 400) +-- +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cj_source1 VALUES (3, 10, 400)" +== 474 +-- truncate_limit: 100 +INSERT INTO cj_source2 VALUES (1, 'initial source2') +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cj_source2 VALUES (1, 'initial source2')" +== 475 +-- truncate_limit: 100 +INSERT INTO cj_source2 VALUES (2, 'initial source2') +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cj_source2 VALUES (2, 'initial source2')" +== 476 +-- truncate_limit: 100 +INSERT INTO cj_source2 VALUES (3, 'initial source2') +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cj_source2 VALUES (3, 'initial source2')" +== 477 +-- truncate_limit: 100 +-- source relation is an unaliased join +MERGE INTO cj_target t +USING cj_source1 s1 + INNER JOIN cj_source2 s2 ON sid1 = sid2 +ON t.tid = sid1 +WHEN NOT MATCHED THEN + INSERT VALUES (sid1, delta, sval) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO cj_target t USING cj_source1 s1 JOIN cj_source2 s2 ON sid1 = sid2 ON t.tid = sid1 WHEN..." +== 478 +-- truncate_limit: 100 +-- try accessing columns from either side of the source join +MERGE INTO cj_target t +USING cj_source2 s2 + INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 +ON t.tid = sid1 +WHEN NOT MATCHED THEN + INSERT VALUES (sid2, delta, sval) +WHEN MATCHED THEN + DELETE +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO cj_target t USING cj_source2 s2 JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 ON t.t..." +== 479 +-- truncate_limit: 100 +-- some simple expressions in INSERT targetlist +MERGE INTO cj_target t +USING cj_source2 s2 + INNER JOIN cj_source1 s1 ON sid1 = sid2 +ON t.tid = sid1 +WHEN NOT MATCHED THEN + INSERT VALUES (sid2, delta + scat, sval) +WHEN MATCHED THEN + UPDATE SET val = val || ' updated by merge' +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO cj_target t USING cj_source2 s2 JOIN cj_source1 s1 ON sid1 = sid2 ON t.tid = sid1 WHEN..." +== 480 +-- truncate_limit: 100 +MERGE INTO cj_target t +USING cj_source2 s2 + INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 +ON t.tid = sid1 +WHEN MATCHED THEN + UPDATE SET val = val || ' ' || delta::text +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO cj_target t USING cj_source2 s2 JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 ON t.t..." +== 481 +-- truncate_limit: 100 +SELECT * FROM cj_target +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cj_target" +== 482 +-- truncate_limit: 100 +-- try it with an outer join and PlaceHolderVar +MERGE INTO cj_target t +USING (SELECT *, 'join input'::text AS phv FROM cj_source1) fj + FULL JOIN cj_source2 fj2 ON fj.scat = fj2.sid2 * 10 +ON t.tid = fj.scat +WHEN NOT MATCHED THEN + INSERT (tid, balance, val) VALUES (fj.scat, fj.delta, fj.phv) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=Select +ALIAS: "t"="cj_target" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO cj_target t USING (SELECT ... FROM cj_source1) fj FULL JOIN cj_source2 fj2 ON fj.scat ..." +== 483 +-- truncate_limit: 100 +SELECT * FROM cj_target +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cj_target" +== 484 +-- truncate_limit: 100 +ALTER TABLE cj_source1 RENAME COLUMN sid1 TO sid +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE cj_source1 RENAME COLUMN sid1 TO sid" +== 485 +-- truncate_limit: 100 +ALTER TABLE cj_source2 RENAME COLUMN sid2 TO sid +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE cj_source2 RENAME COLUMN sid2 TO sid" +== 486 +-- truncate_limit: 100 +TRUNCATE cj_target +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE cj_target" +== 487 +-- truncate_limit: 100 +MERGE INTO cj_target t +USING cj_source1 s1 + INNER JOIN cj_source2 s2 ON s1.sid = s2.sid +ON t.tid = s1.sid +WHEN NOT MATCHED THEN + INSERT VALUES (s2.sid, delta, sval) +-- +TABLE: name="cj_target" schema="" table="cj_target" ctx=DML +ALIAS: "t"="cj_target" +STMT: MergeStmt +TRUNCATED: "MERGE INTO cj_target t USING cj_source1 s1 JOIN cj_source2 s2 ON s1.sid = s2.sid ON t.tid = s1.si..." +== 488 +-- truncate_limit: 100 +DROP TABLE cj_source2, cj_source1, cj_target +-- +TABLE: name="cj_source2" schema="" table="cj_source2" ctx=DDL +TABLE: name="cj_source1" schema="" table="cj_source1" ctx=DDL +TABLE: name="cj_target" schema="" table="cj_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cj_source2, cj_source1, cj_target" +== 489 +-- truncate_limit: 100 +-- Function scans +CREATE TABLE fs_target (a int, b int, c text) + WITH (autovacuum_enabled=off) +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fs_target (a int, b int, c text) WITH (autovacuum_enabled=off)" +== 490 +-- truncate_limit: 100 +MERGE INTO fs_target t +USING generate_series(1,100,1) AS id +ON t.a = id +WHEN MATCHED THEN + UPDATE SET b = b + id +WHEN NOT MATCHED THEN + INSERT VALUES (id, -1) +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DML +ALIAS: "t"="fs_target" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +TRUNCATED: "MERGE INTO fs_target t USING generate_series(1, 100, 1) id ON t.a = id WHEN MATCHED THEN UPDATE S..." +== 491 +-- truncate_limit: 100 +MERGE INTO fs_target t +USING generate_series(1,100,2) AS id +ON t.a = id +WHEN MATCHED THEN + UPDATE SET b = b + id, c = 'updated '|| id.*::text +WHEN NOT MATCHED THEN + INSERT VALUES (id, -1, 'inserted ' || id.*::text) +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DML +ALIAS: "t"="fs_target" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +TRUNCATED: "MERGE INTO fs_target t USING generate_series(1, 100, 2) id ON t.a = id WHEN MATCHED THEN UPDATE S..." +== 492 +-- truncate_limit: 100 +SELECT count(*) FROM fs_target +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM fs_target" +== 493 +-- truncate_limit: 100 +DROP TABLE fs_target +-- +TABLE: name="fs_target" schema="" table="fs_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fs_target" +== 494 +-- truncate_limit: 100 +-- SERIALIZABLE test +-- handled in isolation tests + +-- Inheritance-based partitioning +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE measurement (city_id int NOT NULL, logdate date NOT NULL, peaktemp int, unitsales in..." +== 495 +-- truncate_limit: 100 +CREATE TABLE measurement_y2006m02 ( + CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' ) +) INHERITS (measurement) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement_y2006m02" schema="" table="measurement_y2006m02" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE measurement_y2006m02 (CHECK (logdate >= '2006-02-01'::date AND logdate < '2006-03-01..." +== 496 +-- truncate_limit: 100 +CREATE TABLE measurement_y2006m03 ( + CHECK ( logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' ) +) INHERITS (measurement) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement_y2006m03" schema="" table="measurement_y2006m03" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE measurement_y2006m03 (CHECK (logdate >= '2006-03-01'::date AND logdate < '2006-04-01..." +== 497 +-- truncate_limit: 100 +CREATE TABLE measurement_y2007m01 ( + filler text, + peaktemp int, + logdate date not null, + city_id int not null, + unitsales int + CHECK ( logdate >= DATE '2007-01-01' AND logdate < DATE '2007-02-01') +) WITH (autovacuum_enabled=off) +-- +TABLE: name="measurement_y2007m01" schema="" table="measurement_y2007m01" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE measurement_y2007m01 (filler text, peaktemp int, logdate date NOT NULL, city_id int ..." +== 498 +-- truncate_limit: 100 +ALTER TABLE measurement_y2007m01 DROP COLUMN filler +-- +TABLE: name="measurement_y2007m01" schema="" table="measurement_y2007m01" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE measurement_y2007m01 DROP filler" +== 499 +-- truncate_limit: 100 +ALTER TABLE measurement_y2007m01 INHERIT measurement +-- +TABLE: name="measurement_y2007m01" schema="" table="measurement_y2007m01" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE measurement_y2007m01 INHERIT measurement" +== 500 +-- truncate_limit: 100 +INSERT INTO measurement VALUES (0, '2005-07-21', 5, 15) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO measurement VALUES (0, '2005-07-21', 5, 15)" +== 501 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION measurement_insert_trigger() +RETURNS TRIGGER AS $$ +BEGIN + IF ( NEW.logdate >= DATE '2006-02-01' AND + NEW.logdate < DATE '2006-03-01' ) THEN + INSERT INTO measurement_y2006m02 VALUES (NEW.*); + ELSIF ( NEW.logdate >= DATE '2006-03-01' AND + NEW.logdate < DATE '2006-04-01' ) THEN + INSERT INTO measurement_y2006m03 VALUES (NEW.*); + ELSIF ( NEW.logdate >= DATE '2007-01-01' AND + NEW.logdate < DATE '2007-02-01' ) THEN + INSERT INTO measurement_y2007m01 (city_id, logdate, peaktemp, unitsales) + VALUES (NEW.*); + ELSE + RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!'; + END IF; + RETURN NULL; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="measurement_insert_trigger" function="measurement_insert_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION measurement_insert_trigger() RETURNS trigger AS $$\nBEGIN\n IF ( NEW...." +== 502 +-- truncate_limit: 100 +CREATE TRIGGER insert_measurement_trigger + BEFORE INSERT ON measurement + FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger() +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER insert_measurement_trigger BEFORE INSERT ON measurement FOR EACH ROW EXECUTE FUNCT..." +== 503 +-- truncate_limit: 100 +INSERT INTO measurement VALUES (1, '2006-02-10', 35, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO measurement VALUES (1, '2006-02-10', 35, 10)" +== 504 +-- truncate_limit: 100 +INSERT INTO measurement VALUES (1, '2006-02-16', 45, 20) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO measurement VALUES (1, '2006-02-16', 45, 20)" +== 505 +-- truncate_limit: 100 +INSERT INTO measurement VALUES (1, '2006-03-17', 25, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO measurement VALUES (1, '2006-03-17', 25, 10)" +== 506 +-- truncate_limit: 100 +INSERT INTO measurement VALUES (1, '2006-03-27', 15, 40) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO measurement VALUES (1, '2006-03-27', 15, 40)" +== 507 +-- truncate_limit: 100 +INSERT INTO measurement VALUES (1, '2007-01-15', 10, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO measurement VALUES (1, '2007-01-15', 10, 10)" +== 508 +-- truncate_limit: 100 +INSERT INTO measurement VALUES (1, '2007-01-17', 10, 10) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO measurement VALUES (1, '2007-01-17', 10, 10)" +== 509 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate" +== 510 +-- truncate_limit: 100 +CREATE TABLE new_measurement (LIKE measurement) WITH (autovacuum_enabled=off) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE new_measurement (LIKE measurement) WITH (autovacuum_enabled=off)" +== 511 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (0, '2005-07-21', 25, 20) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (0, '2005-07-21', 25, 20)" +== 512 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (1, '2006-03-01', 20, 10) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (1, '2006-03-01', 20, 10)" +== 513 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (1, '2006-02-16', 50, 10) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (1, '2006-02-16', 50, 10)" +== 514 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (2, '2006-02-10', 20, 20) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (2, '2006-02-10', 20, 20)" +== 515 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (1, '2006-03-27', NULL, NULL) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (1, '2006-03-27', NULL, NULL)" +== 516 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (1, '2007-01-17', NULL, NULL) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (1, '2007-01-17', NULL, NULL)" +== 517 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (1, '2007-01-15', 5, NULL) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (1, '2007-01-15', 5, NULL)" +== 518 +-- truncate_limit: 100 +INSERT INTO new_measurement VALUES (1, '2007-01-16', 10, 10) +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO new_measurement VALUES (1, '2007-01-16', 10, 10)" +== 519 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 520 +-- truncate_limit: 100 +MERGE INTO ONLY measurement m + USING new_measurement nm ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE +WHEN MATCHED THEN UPDATE + SET peaktemp = greatest(m.peaktemp, nm.peaktemp), + unitsales = m.unitsales + coalesce(nm.unitsales, 0) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id, logdate, peaktemp, unitsales) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +TRUNCATED: "MERGE INTO ONLY measurement m USING new_measurement nm ON m.city_id = nm.city_id AND m.logdate = ..." +== 521 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate, peaktemp +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate, peaktemp" +== 522 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 523 +-- truncate_limit: 100 +MERGE into measurement m + USING new_measurement nm ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE +WHEN MATCHED THEN UPDATE + SET peaktemp = greatest(m.peaktemp, nm.peaktemp), + unitsales = m.unitsales + coalesce(nm.unitsales, 0) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id, logdate, peaktemp, unitsales) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +TRUNCATED: "MERGE INTO measurement m USING new_measurement nm ON m.city_id = nm.city_id AND m.logdate = nm.lo..." +== 524 +-- truncate_limit: 100 +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate" +== 525 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 526 +-- truncate_limit: 100 +MERGE INTO new_measurement nm + USING ONLY measurement m ON + (nm.city_id = m.city_id and nm.logdate=m.logdate) +WHEN MATCHED THEN DELETE +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +ALIAS: "nm"="new_measurement" +STMT: MergeStmt +TRUNCATED: "MERGE INTO new_measurement nm USING ONLY measurement m ON nm.city_id = m.city_id AND nm.logdate =..." +== 527 +-- truncate_limit: 100 +SELECT * FROM new_measurement ORDER BY city_id, logdate +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM new_measurement ORDER BY city_id, logdate" +== 528 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 529 +-- truncate_limit: 100 +MERGE INTO new_measurement nm + USING measurement m ON + (nm.city_id = m.city_id and nm.logdate=m.logdate) +WHEN MATCHED THEN DELETE +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DML +ALIAS: "nm"="new_measurement" +STMT: MergeStmt +TRUNCATED: "MERGE INTO new_measurement nm USING measurement m ON nm.city_id = m.city_id AND nm.logdate = m.lo..." +== 530 +-- truncate_limit: 100 +SELECT * FROM new_measurement ORDER BY city_id, logdate +-- +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM new_measurement ORDER BY city_id, logdate" +== 531 +-- truncate_limit: 100 +-- MERGE into inheritance root table +DROP TRIGGER insert_measurement_trigger ON measurement +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER insert_measurement_trigger ON measurement" +== 532 +-- truncate_limit: 100 +ALTER TABLE measurement ADD CONSTRAINT mcheck CHECK (city_id = 0) NO INHERIT +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE measurement ADD CONSTRAINT mcheck CHECK (city_id = 0) NO INHERIT" +== 533 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO measurement m USING (VALUES (1, '01-17-2007'::date)) nm(city_id, l..." +== 534 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 535 +-- truncate_limit: 100 +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO measurement m USING (VALUES (...)) nm(city_id, logdate) ON m.city_id = nm.city_id AND ..." +== 536 +-- truncate_limit: 100 +SELECT * FROM ONLY measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY measurement ORDER BY city_id, logdate" +== 537 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 538 +-- truncate_limit: 100 +ALTER TABLE measurement ENABLE ROW LEVEL SECURITY +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE measurement ENABLE ROW LEVEL SECURITY" +== 539 +-- truncate_limit: 100 +ALTER TABLE measurement FORCE ROW LEVEL SECURITY +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE measurement FORCE ROW LEVEL SECURITY" +== 540 +-- truncate_limit: 100 +CREATE POLICY measurement_p ON measurement USING (peaktemp IS NOT NULL) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY measurement_p ON measurement TO public USING (peaktemp IS NOT NULL)" +== 541 +-- truncate_limit: 100 +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, NULL, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO measurement m USING (VALUES (...)) nm(city_id, logdate) ON m.city_id = nm.city_id AND ..." +== 542 +-- truncate_limit: 100 +-- should fail + +MERGE INTO measurement m + USING (VALUES (1, '01-17-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 100) +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO measurement m USING (VALUES (...)) nm(city_id, logdate) ON m.city_id = nm.city_id AND ..." +== 543 +-- truncate_limit: 100 +-- ok +SELECT * FROM ONLY measurement ORDER BY city_id, logdate +-- +TABLE: name="measurement" schema="" table="measurement" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY measurement ORDER BY city_id, logdate" +== 544 +-- truncate_limit: 100 +MERGE INTO measurement m + USING (VALUES (1, '01-18-2007'::date)) nm(city_id, logdate) ON + (m.city_id = nm.city_id and m.logdate=nm.logdate) +WHEN NOT MATCHED THEN INSERT + (city_id, logdate, peaktemp, unitsales) + VALUES (city_id - 1, logdate, 25, 200) +RETURNING merge_action(), m.* +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DML +ALIAS: "m"="measurement" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO measurement m USING (VALUES (...)) nm(city_id, logdate) ON m.city_id = nm.city_id AND ..." +== 545 +-- truncate_limit: 100 +DROP TABLE measurement, new_measurement CASCADE +-- +TABLE: name="measurement" schema="" table="measurement" ctx=DDL +TABLE: name="new_measurement" schema="" table="new_measurement" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE measurement, new_measurement CASCADE" +== 546 +-- truncate_limit: 100 +DROP FUNCTION measurement_insert_trigger() +-- +FUNCTION: name="measurement_insert_trigger" function="measurement_insert_trigger" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION measurement_insert_trigger()" +== 547 +-- truncate_limit: 100 +|-- +-- test non-strict join clause +|-- +CREATE TABLE src (a int, b text) +-- +TABLE: name="src" schema="" table="src" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE src (a int, b text)" +== 548 +-- truncate_limit: 100 +INSERT INTO src VALUES (1, 'src row') +-- +TABLE: name="src" schema="" table="src" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO src VALUES (1, 'src row')" +== 549 +-- truncate_limit: 100 +CREATE TABLE tgt (a int, b text) +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tgt (a int, b text)" +== 550 +-- truncate_limit: 100 +INSERT INTO tgt VALUES (NULL, 'tgt row') +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tgt VALUES (NULL, 'tgt row')" +== 551 +-- truncate_limit: 100 +MERGE INTO tgt USING src ON tgt.a IS NOT DISTINCT FROM src.a + WHEN MATCHED THEN UPDATE SET a = src.a, b = src.b + WHEN NOT MATCHED BY SOURCE THEN DELETE + RETURNING merge_action(), src.*, tgt.* +-- +TABLE: name="tgt" schema="" table="tgt" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO tgt USING src ON tgt.a IS NOT DISTINCT FROM src.a WHEN MATCHED THEN UPDATE SET a = src..." +== 552 +-- truncate_limit: 100 +SELECT * FROM tgt +-- +TABLE: name="tgt" schema="" table="tgt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tgt" +== 553 +-- truncate_limit: 100 +DROP TABLE src, tgt +-- +TABLE: name="src" schema="" table="src" ctx=DDL +TABLE: name="tgt" schema="" table="tgt" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE src, tgt" +== 554 +-- truncate_limit: 100 +|-- +-- test for bug #18634 (wrong varnullingrels error) +|-- +CREATE TABLE bug18634t (a int, b int, c text) +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bug18634t (a int, b int, c text)" +== 555 +-- truncate_limit: 100 +INSERT INTO bug18634t VALUES(1, 10, 'tgt1'), (2, 20, 'tgt2') +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bug18634t VALUES (1, 10, 'tgt1'), (2, 20, 'tgt2')" +== 556 +-- truncate_limit: 100 +CREATE VIEW bug18634v AS + SELECT * FROM bug18634t WHERE EXISTS (SELECT 1 FROM bug18634t) +-- +TABLE: name="bug18634v" schema="" table="bug18634v" ctx=DDL +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=Select +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW bug18634v AS SELECT * FROM bug18634t WHERE EXISTS (SELECT 1 FROM bug18634t)" +== 557 +-- truncate_limit: 100 +CREATE TABLE bug18634s (a int, b int, c text) +-- +TABLE: name="bug18634s" schema="" table="bug18634s" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bug18634s (a int, b int, c text)" +== 558 +-- truncate_limit: 100 +INSERT INTO bug18634s VALUES (1, 2, 'src1') +-- +TABLE: name="bug18634s" schema="" table="bug18634s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bug18634s VALUES (1, 2, 'src1')" +== 559 +-- truncate_limit: 100 +MERGE INTO bug18634v t USING bug18634s s ON s.a = t.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED BY SOURCE THEN DELETE + RETURNING merge_action(), s.c, t.* +-- +TABLE: name="bug18634v" schema="" table="bug18634v" ctx=DML +ALIAS: "t"="bug18634v" +STMT: MergeStmt +TRUNCATED: "MERGE INTO bug18634v t USING bug18634s s ON s.a = t.a WHEN MATCHED THEN UPDATE SET b = s.b WHEN N..." +== 560 +-- truncate_limit: 100 +SELECT * FROM bug18634t +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bug18634t" +== 561 +-- truncate_limit: 100 +DROP TABLE bug18634t CASCADE +-- +TABLE: name="bug18634t" schema="" table="bug18634t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bug18634t CASCADE" +== 562 +-- truncate_limit: 100 +DROP TABLE bug18634s +-- +TABLE: name="bug18634s" schema="" table="bug18634s" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bug18634s" +== 563 +-- truncate_limit: 100 +-- prepare + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 564 +-- truncate_limit: 100 +-- try a system catalog +MERGE INTO pg_class c +USING (SELECT 'pg_depend'::regclass AS oid) AS j +ON j.oid = c.oid +WHEN MATCHED THEN + UPDATE SET reltuples = reltuples + 1 +RETURNING j.oid +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DML +ALIAS: "c"="pg_class" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO pg_class c USING (SELECT ...) j ON j.oid = c.oid WHEN MATCHED THEN UPDATE SET reltuple..." +== 565 +-- truncate_limit: 100 +CREATE VIEW classv AS SELECT * FROM pg_class +-- +TABLE: name="classv" schema="" table="classv" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW classv AS SELECT * FROM pg_class" +== 566 +-- truncate_limit: 100 +MERGE INTO classv c +USING pg_namespace n +ON n.oid = c.relnamespace +WHEN MATCHED AND c.oid = 'pg_depend'::regclass THEN + UPDATE SET reltuples = reltuples - 1 +RETURNING c.oid +-- +TABLE: name="classv" schema="" table="classv" ctx=DML +ALIAS: "c"="classv" +STMT: MergeStmt +TRUNCATED: "MERGE INTO classv c USING pg_namespace n ON n.oid = c.relnamespace WHEN MATCHED AND c.oid = 'pg_d..." +== 567 +-- truncate_limit: 100 +DROP TABLE target, target2 +-- +TABLE: name="target" schema="" table="target" ctx=DDL +TABLE: name="target2" schema="" table="target2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE target, target2" +== 568 +-- truncate_limit: 100 +DROP TABLE source, source2 +-- +TABLE: name="source" schema="" table="source" ctx=DDL +TABLE: name="source2" schema="" table="source2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE source, source2" +== 569 +-- truncate_limit: 100 +DROP FUNCTION merge_trigfunc() +-- +FUNCTION: name="merge_trigfunc" function="merge_trigfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION merge_trigfunc()" +== 570 +-- truncate_limit: 100 +DROP USER regress_merge_privs +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_merge_privs" +== 571 +-- truncate_limit: 100 +DROP USER regress_merge_no_privs +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_merge_no_privs" +== 572 +-- truncate_limit: 100 +DROP USER regress_merge_none +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_merge_none" diff --git a/parser/testdata/summary_truncate/postgres_regress/misc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/misc.metadata.json new file mode 100644 index 0000000..6a71114 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/misc.metadata.json @@ -0,0 +1,65 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/misc.test b/parser/testdata/summary_truncate/postgres_regress/misc.test new file mode 100644 index 0000000..05c7f05 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/misc.test @@ -0,0 +1,636 @@ +== 001 +-- truncate_limit: 100 +|-- +-- MISC +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION overpaid(emp) + RETURNS bool + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 144 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +CREATE FUNCTION reverse_name(name) + RETURNS name + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 58 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +-- truncate_limit: 100 +|-- +-- BTREE +|-- +UPDATE onek + SET unique1 = onek.unique1 + 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE onek SET unique1 = onek.unique1 + 1" +== 004 +-- truncate_limit: 100 +UPDATE onek + SET unique1 = onek.unique1 - 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE onek SET unique1 = onek.unique1 - 1" +== 005 +-- truncate_limit: 100 +|-- +-- BTREE partial +|-- +-- UPDATE onek2 +-- SET unique1 = onek2.unique1 + 1; + +--UPDATE onek2 +-- SET unique1 = onek2.unique1 - 1; + +|-- +-- BTREE shutting out non-functional updates +|-- +-- the following two tests seem to take a long time on some +-- systems. This non-func update stuff needs to be examined +-- more closely. - jolly (2/22/96) +|-- +SELECT two, stringu1, ten, string4 + INTO TABLE tmp + FROM onek +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: SelectStmt +TRUNCATED: "SELECT two, stringu1, ten, string4 INTO tmp FROM onek" +== 006 +-- truncate_limit: 100 +UPDATE tmp + SET stringu1 = reverse_name(onek.stringu1) + FROM onek + WHERE onek.stringu1 = 'JBAAAA' and + onek.stringu1 = tmp.stringu1 +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +TABLE: name="onek" schema="" table="onek" ctx=Select +FUNCTION: name="reverse_name" function="reverse_name" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE tmp SET stringu1 = reverse_name(onek.stringu1) FROM onek WHERE ..." +== 007 +-- truncate_limit: 100 +UPDATE tmp + SET stringu1 = reverse_name(onek2.stringu1) + FROM onek2 + WHERE onek2.stringu1 = 'JCAAAA' and + onek2.stringu1 = tmp.stringu1 +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DML +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FUNCTION: name="reverse_name" function="reverse_name" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE tmp SET stringu1 = reverse_name(onek2.stringu1) FROM onek2 WHERE ..." +== 008 +-- truncate_limit: 100 +DROP TABLE tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tmp" +== 009 +-- truncate_limit: 100 +--UPDATE person* +-- SET age = age + 1; + +--UPDATE person* +-- SET age = age + 3 +-- WHERE name = 'linda'; + +|-- +-- copy +|-- +COPY onek TO :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 138 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 010 +-- truncate_limit: 100 +CREATE TEMP TABLE onek_copy (LIKE onek) +-- +TABLE: name="onek_copy" schema="" table="onek_copy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE onek_copy (LIKE onek)" +== 011 +-- truncate_limit: 100 +COPY onek_copy FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- truncate_limit: 100 +SELECT * FROM onek EXCEPT ALL SELECT * FROM onek_copy +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek_copy" schema="" table="onek_copy" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek EXCEPT ALL SELECT * FROM onek_copy" +== 013 +-- truncate_limit: 100 +SELECT * FROM onek_copy EXCEPT ALL SELECT * FROM onek +-- +TABLE: name="onek_copy" schema="" table="onek_copy" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek_copy EXCEPT ALL SELECT * FROM onek" +== 014 +-- truncate_limit: 100 +COPY BINARY stud_emp TO :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 015 +-- truncate_limit: 100 +CREATE TEMP TABLE stud_emp_copy (LIKE stud_emp) +-- +TABLE: name="stud_emp_copy" schema="" table="stud_emp_copy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE stud_emp_copy (LIKE stud_emp)" +== 016 +-- truncate_limit: 100 +COPY BINARY stud_emp_copy FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 017 +-- truncate_limit: 100 +SELECT * FROM stud_emp_copy +-- +TABLE: name="stud_emp_copy" schema="" table="stud_emp_copy" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM stud_emp_copy" +== 018 +-- truncate_limit: 100 +|-- +-- test data for postquel functions +|-- + +CREATE TABLE hobbies_r ( + name text, + person text +) +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hobbies_r (name text, person text)" +== 019 +-- truncate_limit: 100 +CREATE TABLE equipment_r ( + name text, + hobby text +) +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE equipment_r (name text, hobby text)" +== 020 +-- truncate_limit: 100 +INSERT INTO hobbies_r (name, person) + SELECT 'posthacking', p.name + FROM person* p + WHERE p.name = 'mike' or p.name = 'jeff' +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DML +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FILTER: schema="" table="p" column="name" +FILTER: schema="" table="p" column="name" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hobbies_r (name, person) SELECT 'posthacking', p.name FROM person p WHERE ..." +== 021 +-- truncate_limit: 100 +INSERT INTO hobbies_r (name, person) + SELECT 'basketball', p.name + FROM person p + WHERE p.name = 'joe' or p.name = 'sally' +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DML +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FILTER: schema="" table="p" column="name" +FILTER: schema="" table="p" column="name" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hobbies_r (name, person) SELECT 'basketball', p.name FROM person p WHERE ..." +== 022 +-- truncate_limit: 100 +INSERT INTO hobbies_r (name) VALUES ('skywalking') +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hobbies_r (name) VALUES ('skywalking')" +== 023 +-- truncate_limit: 100 +INSERT INTO equipment_r (name, hobby) VALUES ('advil', 'posthacking') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO equipment_r (name, hobby) VALUES ('advil', 'posthacking')" +== 024 +-- truncate_limit: 100 +INSERT INTO equipment_r (name, hobby) VALUES ('peet''s coffee', 'posthacking') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO equipment_r (name, hobby) VALUES ('peet''s coffee', 'posthacking')" +== 025 +-- truncate_limit: 100 +INSERT INTO equipment_r (name, hobby) VALUES ('hightops', 'basketball') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO equipment_r (name, hobby) VALUES ('hightops', 'basketball')" +== 026 +-- truncate_limit: 100 +INSERT INTO equipment_r (name, hobby) VALUES ('guts', 'skywalking') +-- +TABLE: name="equipment_r" schema="" table="equipment_r" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO equipment_r (name, hobby) VALUES ('guts', 'skywalking')" +== 027 +-- truncate_limit: 100 +|-- +-- postquel functions +|-- + +CREATE FUNCTION hobbies(person) + RETURNS setof hobbies_r + AS 'select * from hobbies_r where person = $1.name' + LANGUAGE SQL +-- +FUNCTION: name="hobbies" function="hobbies" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION hobbies(person) RETURNS SETOF hobbies_r AS $$select * from hobbies_r where person..." +== 028 +-- truncate_limit: 100 +CREATE FUNCTION hobby_construct(text, text) + RETURNS hobbies_r + AS 'select $1 as name, $2 as hobby' + LANGUAGE SQL +-- +FUNCTION: name="hobby_construct" function="hobby_construct" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION hobby_construct(text, text) RETURNS hobbies_r AS $$select $1 as name, $2 as hobby..." +== 029 +-- truncate_limit: 100 +CREATE FUNCTION hobby_construct_named(name text, hobby text) + RETURNS hobbies_r + AS 'select name, hobby' + LANGUAGE SQL +-- +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION hobby_construct_named(name text, hobby text) RETURNS hobbies_r AS $$select name, ..." +== 030 +-- truncate_limit: 100 +CREATE FUNCTION hobbies_by_name(hobbies_r.name%TYPE) + RETURNS hobbies_r.person%TYPE + AS 'select person from hobbies_r where name = $1' + LANGUAGE SQL +-- +FUNCTION: name="hobbies_by_name" function="hobbies_by_name" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION hobbies_by_name(hobbies_r.name%type) RETURNS hobbies_r.person%type AS $$select pe..." +== 031 +-- truncate_limit: 100 +CREATE FUNCTION equipment(hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = $1.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment" function="equipment" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION equipment(hobbies_r) RETURNS SETOF equipment_r AS $$select * from equipment_r whe..." +== 032 +-- truncate_limit: 100 +CREATE FUNCTION equipment_named(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = equipment_named.hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named" function="equipment_named" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION equipment_named(hobby hobbies_r) RETURNS SETOF equipment_r AS $$select * from equ..." +== 033 +-- truncate_limit: 100 +CREATE FUNCTION equipment_named_ambiguous_1a(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = equipment_named_ambiguous_1a.hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_1a" function="equipment_named_ambiguous_1a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION equipment_named_ambiguous_1a(hobby hobbies_r) RETURNS SETOF equipment_r AS $$sele..." +== 034 +-- truncate_limit: 100 +CREATE FUNCTION equipment_named_ambiguous_1b(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_1b" function="equipment_named_ambiguous_1b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION equipment_named_ambiguous_1b(hobby hobbies_r) RETURNS SETOF equipment_r AS $$sele..." +== 035 +-- truncate_limit: 100 +CREATE FUNCTION equipment_named_ambiguous_1c(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = hobby.name' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_1c" function="equipment_named_ambiguous_1c" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION equipment_named_ambiguous_1c(hobby hobbies_r) RETURNS SETOF equipment_r AS $$sele..." +== 036 +-- truncate_limit: 100 +CREATE FUNCTION equipment_named_ambiguous_2a(hobby text) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = equipment_named_ambiguous_2a.hobby' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_2a" function="equipment_named_ambiguous_2a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION equipment_named_ambiguous_2a(hobby text) RETURNS SETOF equipment_r AS $$select * ..." +== 037 +-- truncate_limit: 100 +CREATE FUNCTION equipment_named_ambiguous_2b(hobby text) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = hobby' + LANGUAGE SQL +-- +FUNCTION: name="equipment_named_ambiguous_2b" function="equipment_named_ambiguous_2b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION equipment_named_ambiguous_2b(hobby text) RETURNS SETOF equipment_r AS $$select * ..." +== 038 +-- truncate_limit: 100 +|-- +-- mike does post_hacking, +-- joe and sally play basketball, and +-- everyone else does nothing. +|-- +SELECT p.name, name(p.hobbies) FROM ONLY person p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT p.name, name(p.hobbies) FROM ONLY person p" +== 039 +-- truncate_limit: 100 +|-- +-- as above, but jeff also does post_hacking. +|-- +SELECT p.name, name(p.hobbies) FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT p.name, name(p.hobbies) FROM person p" +== 040 +-- truncate_limit: 100 +|-- +-- the next two queries demonstrate how functions generate bogus duplicates. +-- this is a "feature" .. +|-- +SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r + ORDER BY 1,2 +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r ORDER BY 1, 2" +== 041 +-- truncate_limit: 100 +SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r" +== 042 +-- truncate_limit: 100 +|-- +-- mike needs advil and peet's coffee, +-- joe and sally need hightops, and +-- everyone else is fine. +|-- +SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p" +== 043 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person p" +== 044 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p" +== 045 +-- truncate_limit: 100 +SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person p" +== 046 +-- truncate_limit: 100 +SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p" +== 047 +-- truncate_limit: 100 +SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="name" function="name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person p" +== 048 +-- truncate_limit: 100 +SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="hobby_construct" function="hobby_construct" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment(hobby_construct('skywalking'::text, 'mer'::text)))" +== 049 +-- truncate_limit: 100 +SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment(hobby_construct_named('skywalking'::text, 'mer'::text)))" +== 050 +-- truncate_limit: 100 +SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named" function="equipment_named" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment_named(hobby_construct_named('skywalking'::text, 'mer'::text)))" +== 051 +-- truncate_limit: 100 +SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_1a" function="equipment_named_ambiguous_1a" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment_named_ambiguous_1a(hobby_construct_named('skywalking'::text, 'mer'::text)))" +== 052 +-- truncate_limit: 100 +SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_1b" function="equipment_named_ambiguous_1b" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment_named_ambiguous_1b(hobby_construct_named('skywalking'::text, 'mer'::text)))" +== 053 +-- truncate_limit: 100 +SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_1c" function="equipment_named_ambiguous_1c" schema="" ctx=Call +FUNCTION: name="hobby_construct_named" function="hobby_construct_named" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment_named_ambiguous_1c(hobby_construct_named('skywalking'::text, 'mer'::text)))" +== 054 +-- truncate_limit: 100 +SELECT name(equipment_named_ambiguous_2a(text 'skywalking')) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_2a" function="equipment_named_ambiguous_2a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment_named_ambiguous_2a('skywalking'::text))" +== 055 +-- truncate_limit: 100 +SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment_named_ambiguous_2b" function="equipment_named_ambiguous_2b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment_named_ambiguous_2b('skywalking'::text))" +== 056 +-- truncate_limit: 100 +SELECT hobbies_by_name('basketball') +-- +FUNCTION: name="hobbies_by_name" function="hobbies_by_name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT hobbies_by_name('basketball')" +== 057 +-- truncate_limit: 100 +SELECT name, overpaid(emp.*) FROM emp +-- +TABLE: name="emp" schema="" table="emp" ctx=Select +FUNCTION: name="overpaid" function="overpaid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name, overpaid(emp.*) FROM emp" +== 058 +-- truncate_limit: 100 +|-- +-- Try a few cases with SQL-spec row constructor expressions +|-- +SELECT * FROM equipment(ROW('skywalking', 'mer')) +-- +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM equipment(ROW('skywalking', 'mer'))" +== 059 +-- truncate_limit: 100 +SELECT name(equipment(ROW('skywalking', 'mer'))) +-- +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT name(equipment(ROW('skywalking', 'mer')))" +== 060 +-- truncate_limit: 100 +SELECT *, name(equipment(h.*)) FROM hobbies_r h +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +ALIAS: "h"="hobbies_r" +FUNCTION: name="name" function="name" schema="" ctx=Call +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, name(equipment(h.*)) FROM hobbies_r h" +== 061 +-- truncate_limit: 100 +SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h +-- +TABLE: name="hobbies_r" schema="" table="hobbies_r" ctx=Select +ALIAS: "h"="hobbies_r" +FUNCTION: name="equipment" function="equipment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, (equipment(h.*::hobbies_r)).name FROM hobbies_r h" diff --git a/parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json b/parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json new file mode 100644 index 0000000..b6ecb7b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json @@ -0,0 +1,123 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/misc_functions.test b/parser/testdata/summary_truncate/postgres_regress/misc_functions.test new file mode 100644 index 0000000..8105691 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/misc_functions.test @@ -0,0 +1,1011 @@ +== 001 +-- truncate_limit: 100 +-- directory paths and dlsuffix are passed to us in environment variables + + +|-- +-- num_nulls() +|-- + +SELECT num_nonnulls(NULL) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(NULL)" +== 002 +-- truncate_limit: 100 +SELECT num_nonnulls('1') +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls('1')" +== 003 +-- truncate_limit: 100 +SELECT num_nonnulls(NULL::text) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(NULL::text)" +== 004 +-- truncate_limit: 100 +SELECT num_nonnulls(NULL::text, NULL::int) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(NULL::text, NULL::int)" +== 005 +-- truncate_limit: 100 +SELECT num_nonnulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(1, 2, NULL::text, NULL::point, '', '9'::int8, 1.0 / NULL)" +== 006 +-- truncate_limit: 100 +SELECT num_nonnulls(VARIADIC '{1,2,NULL,3}'::int[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(VARIADIC '{1,2,NULL,3}'::int[])" +== 007 +-- truncate_limit: 100 +SELECT num_nonnulls(VARIADIC '{"1","2","3","4"}'::text[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(VARIADIC '{\"1\",\"2\",\"3\",\"4\"}'::text[])" +== 008 +-- truncate_limit: 100 +SELECT num_nonnulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i)) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(VARIADIC ARRAY(SELECT ... FROM generate_series(1, 100) i))" +== 009 +-- truncate_limit: 100 +SELECT num_nulls(NULL) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(NULL)" +== 010 +-- truncate_limit: 100 +SELECT num_nulls('1') +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls('1')" +== 011 +-- truncate_limit: 100 +SELECT num_nulls(NULL::text) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(NULL::text)" +== 012 +-- truncate_limit: 100 +SELECT num_nulls(NULL::text, NULL::int) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(NULL::text, NULL::int)" +== 013 +-- truncate_limit: 100 +SELECT num_nulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(1, 2, NULL::text, NULL::point, '', '9'::int8, 1.0 / NULL)" +== 014 +-- truncate_limit: 100 +SELECT num_nulls(VARIADIC '{1,2,NULL,3}'::int[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(VARIADIC '{1,2,NULL,3}'::int[])" +== 015 +-- truncate_limit: 100 +SELECT num_nulls(VARIADIC '{"1","2","3","4"}'::text[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(VARIADIC '{\"1\",\"2\",\"3\",\"4\"}'::text[])" +== 016 +-- truncate_limit: 100 +SELECT num_nulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i)) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i))" +== 017 +-- truncate_limit: 100 +-- special cases +SELECT num_nonnulls(VARIADIC NULL::text[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(VARIADIC NULL::text[])" +== 018 +-- truncate_limit: 100 +SELECT num_nonnulls(VARIADIC '{}'::int[]) +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls(VARIADIC '{}'::int[])" +== 019 +-- truncate_limit: 100 +SELECT num_nulls(VARIADIC NULL::text[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(VARIADIC NULL::text[])" +== 020 +-- truncate_limit: 100 +SELECT num_nulls(VARIADIC '{}'::int[]) +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls(VARIADIC '{}'::int[])" +== 021 +-- truncate_limit: 100 +-- should fail, one or more arguments is required +SELECT num_nonnulls() +-- +FUNCTION: name="num_nonnulls" function="num_nonnulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nonnulls()" +== 022 +-- truncate_limit: 100 +SELECT num_nulls() +-- +FUNCTION: name="num_nulls" function="num_nulls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT num_nulls()" +== 023 +-- truncate_limit: 100 +|-- +-- canonicalize_path() +|-- + +CREATE FUNCTION test_canonicalize_path(text) + RETURNS text + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 98 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/')" +== 025 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/./abc/def/') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/./abc/def/')" +== 026 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/./../abc/def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/./../abc/def')" +== 027 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/./../../abc/def/') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/./../../abc/def/')" +== 028 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/abc/.././def/ghi') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/abc/.././def/ghi')" +== 029 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/abc/./../def/ghi//') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/abc/./../def/ghi//')" +== 030 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/abc/def/../..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/abc/def/../..')" +== 031 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/abc/def/../../..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/abc/def/../../..')" +== 032 +-- truncate_limit: 100 +SELECT test_canonicalize_path('/abc/def/../../../../ghi/jkl') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('/abc/def/../../../../ghi/jkl')" +== 033 +-- truncate_limit: 100 +SELECT test_canonicalize_path('.') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('.')" +== 034 +-- truncate_limit: 100 +SELECT test_canonicalize_path('./') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('./')" +== 035 +-- truncate_limit: 100 +SELECT test_canonicalize_path('./abc/..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('./abc/..')" +== 036 +-- truncate_limit: 100 +SELECT test_canonicalize_path('abc/../') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('abc/../')" +== 037 +-- truncate_limit: 100 +SELECT test_canonicalize_path('abc/../def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('abc/../def')" +== 038 +-- truncate_limit: 100 +SELECT test_canonicalize_path('..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('..')" +== 039 +-- truncate_limit: 100 +SELECT test_canonicalize_path('../abc/def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('../abc/def')" +== 040 +-- truncate_limit: 100 +SELECT test_canonicalize_path('../abc/..') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('../abc/..')" +== 041 +-- truncate_limit: 100 +SELECT test_canonicalize_path('../abc/../def') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('../abc/../def')" +== 042 +-- truncate_limit: 100 +SELECT test_canonicalize_path('../abc/../../def/ghi') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('../abc/../../def/ghi')" +== 043 +-- truncate_limit: 100 +SELECT test_canonicalize_path('./abc/./def/.') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('./abc/./def/.')" +== 044 +-- truncate_limit: 100 +SELECT test_canonicalize_path('./abc/././def/.') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('./abc/././def/.')" +== 045 +-- truncate_limit: 100 +SELECT test_canonicalize_path('./abc/./def/.././ghi/../../../jkl/mno') +-- +FUNCTION: name="test_canonicalize_path" function="test_canonicalize_path" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_canonicalize_path('./abc/./def/.././ghi/../../../jkl/mno')" +== 046 +-- truncate_limit: 100 +|-- +-- pg_log_backend_memory_contexts() +|-- +-- Memory contexts are logged and they are not returned to the function. +-- Furthermore, their contents can vary depending on the timing. However, +-- we can at least verify that the code doesn't fail, and that the +-- permissions are set properly. +|-- + +SELECT pg_log_backend_memory_contexts(pg_backend_pid()) +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_log_backend_memory_contexts(pg_backend_pid())" +== 047 +-- truncate_limit: 100 +SELECT pg_log_backend_memory_contexts(pid) FROM pg_stat_activity + WHERE backend_type = 'checkpointer' +-- +TABLE: name="pg_stat_activity" schema="" table="pg_stat_activity" ctx=Select +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=Call +FILTER: schema="" table="" column="backend_type" +STMT: SelectStmt +TRUNCATED: "SELECT pg_log_backend_memory_contexts(pid) FROM pg_stat_activity WHERE backend_type = 'checkpointer'" +== 048 +-- truncate_limit: 100 +CREATE ROLE regress_log_memory +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_log_memory" +== 049 +-- truncate_limit: 100 +SELECT has_function_privilege('regress_log_memory', + 'pg_log_backend_memory_contexts(integer)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 050 +-- truncate_limit: 100 +-- no + +GRANT EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) + TO regress_log_memory +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT execute ON FUNCTION pg_log_backend_memory_contexts(int) TO regress_log_memory" +== 051 +-- truncate_limit: 100 +SELECT has_function_privilege('regress_log_memory', + 'pg_log_backend_memory_contexts(integer)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 052 +-- truncate_limit: 100 +-- yes + +SET ROLE regress_log_memory +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_log_memory" +== 053 +-- truncate_limit: 100 +SELECT pg_log_backend_memory_contexts(pg_backend_pid()) +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_log_backend_memory_contexts(pg_backend_pid())" +== 054 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 055 +-- truncate_limit: 100 +REVOKE EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) + FROM regress_log_memory +-- +FUNCTION: name="pg_log_backend_memory_contexts" function="pg_log_backend_memory_contexts" schema="" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE execute ON FUNCTION pg_log_backend_memory_contexts(int) FROM regress_log_memory" +== 056 +-- truncate_limit: 100 +DROP ROLE regress_log_memory +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_log_memory" +== 057 +-- truncate_limit: 100 +|-- +-- Test some built-in SRFs +|-- +-- The outputs of these are variable, so we can't just print their results +-- directly, but we can at least verify that the code doesn't fail. +|-- +select setting as segsize +from pg_settings where name = 'wal_segment_size' + +select count(*) > 0 as ok from pg_ls_waldir() +-- +ERROR: syntax error at or near "select" +CURSORPOS: 256 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 058 +-- truncate_limit: 100 +-- Test ProjectSet as well as FunctionScan +select count(*) > 0 as ok from (select pg_ls_waldir()) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_waldir" function="pg_ls_waldir" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM (SELECT pg_ls_waldir()) ss" +== 059 +-- truncate_limit: 100 +-- Test not-run-to-completion cases. +select * from pg_ls_waldir() limit 0 +-- +FUNCTION: name="pg_ls_waldir" function="pg_ls_waldir" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_ls_waldir() LIMIT 0" +== 060 +-- truncate_limit: 100 +select count(*) > 0 as ok from (select * from pg_ls_waldir() limit 1) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_waldir" function="pg_ls_waldir" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM (SELECT * FROM pg_ls_waldir() LIMIT 1) ss" +== 061 +-- truncate_limit: 100 +select (w).size = :segsize as ok +from (select pg_ls_waldir() w) ss where length((w).name) = 24 limit 1 +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 062 +-- truncate_limit: 100 +select count(*) >= 0 as ok from pg_ls_archive_statusdir() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_archive_statusdir" function="pg_ls_archive_statusdir" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) >= 0 AS ok FROM pg_ls_archive_statusdir()" +== 063 +-- truncate_limit: 100 +-- pg_read_file() +select length(pg_read_file('postmaster.pid')) > 20 +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(pg_read_file('postmaster.pid')) > 20" +== 064 +-- truncate_limit: 100 +select length(pg_read_file('postmaster.pid', 1, 20)) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(pg_read_file('postmaster.pid', 1, 20))" +== 065 +-- truncate_limit: 100 +-- Test missing_ok +select pg_read_file('does not exist') +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_file('does not exist')" +== 066 +-- truncate_limit: 100 +-- error +select pg_read_file('does not exist', true) IS NULL +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_file('does not exist', true) IS NULL" +== 067 +-- truncate_limit: 100 +-- ok +-- Test invalid argument +select pg_read_file('does not exist', 0, -1) +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_file('does not exist', 0, -1)" +== 068 +-- truncate_limit: 100 +-- error +select pg_read_file('does not exist', 0, -1, true) +-- +FUNCTION: name="pg_read_file" function="pg_read_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_file('does not exist', 0, -1, true)" +== 069 +-- truncate_limit: 100 +-- error + +-- pg_read_binary_file() +select length(pg_read_binary_file('postmaster.pid')) > 20 +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(pg_read_binary_file('postmaster.pid')) > 20" +== 070 +-- truncate_limit: 100 +select length(pg_read_binary_file('postmaster.pid', 1, 20)) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(pg_read_binary_file('postmaster.pid', 1, 20))" +== 071 +-- truncate_limit: 100 +-- Test missing_ok +select pg_read_binary_file('does not exist') +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_binary_file('does not exist')" +== 072 +-- truncate_limit: 100 +-- error +select pg_read_binary_file('does not exist', true) IS NULL +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_binary_file('does not exist', true) IS NULL" +== 073 +-- truncate_limit: 100 +-- ok +-- Test invalid argument +select pg_read_binary_file('does not exist', 0, -1) +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_binary_file('does not exist', 0, -1)" +== 074 +-- truncate_limit: 100 +-- error +select pg_read_binary_file('does not exist', 0, -1, true) +-- +FUNCTION: name="pg_read_binary_file" function="pg_read_binary_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_read_binary_file('does not exist', 0, -1, true)" +== 075 +-- truncate_limit: 100 +-- error + +-- pg_stat_file() +select size > 20, isdir from pg_stat_file('postmaster.pid') +-- +FUNCTION: name="pg_stat_file" function="pg_stat_file" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT size > 20, isdir FROM pg_stat_file('postmaster.pid')" +== 076 +-- truncate_limit: 100 +-- pg_ls_dir() +select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1 +-- +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT pg_ls_dir('.') AS a) a WHERE a = 'base' LIMIT 1" +== 077 +-- truncate_limit: 100 +-- Test missing_ok (second argument) +select pg_ls_dir('does not exist', false, false) +-- +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_ls_dir('does not exist', false, false)" +== 078 +-- truncate_limit: 100 +-- error +select pg_ls_dir('does not exist', true, false) +-- +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_ls_dir('does not exist', true, false)" +== 079 +-- truncate_limit: 100 +-- ok +-- Test include_dot_dirs (third argument) +select count(*) = 1 as dot_found + from pg_ls_dir('.', false, true) as ls where ls = '.' +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +FILTER: schema="" table="" column="ls" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) = 1 AS dot_found FROM pg_ls_dir('.', false, true) ls WHERE ls = '.'" +== 080 +-- truncate_limit: 100 +select count(*) = 1 as dot_found + from pg_ls_dir('.', false, false) as ls where ls = '.' +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_ls_dir" function="pg_ls_dir" schema="" ctx=Call +FILTER: schema="" table="" column="ls" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) = 1 AS dot_found FROM pg_ls_dir('.', false, false) ls WHERE ls = '.'" +== 081 +-- truncate_limit: 100 +-- pg_timezone_names() +select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1 +-- +FUNCTION: name="pg_timezone_names" function="pg_timezone_names" schema="" ctx=Call +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT (pg_timezone_names()).name) ptn WHERE name = 'UTC' LIMIT 1" +== 082 +-- truncate_limit: 100 +-- pg_tablespace_databases() +select count(*) > 0 from + (select pg_tablespace_databases(oid) as pts from pg_tablespace + where spcname = 'pg_default') pts + join pg_database db on pts.pts = db.oid +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "db"="pg_database" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_tablespace_databases" function="pg_tablespace_databases" schema="" ctx=Call +FILTER: schema="" table="" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM pg_tablespace WHERE ...) pts JOIN pg_database db ON pts.pts = db..." +== 083 +-- truncate_limit: 100 +|-- +-- Test replication slot directory functions +|-- +CREATE ROLE regress_slot_dir_funcs +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_slot_dir_funcs" +== 084 +-- truncate_limit: 100 +-- Not available by default. +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalsnapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_slot_dir_funcs', 'pg_ls_logicalsnapdir()', 'EXECUTE')" +== 085 +-- truncate_limit: 100 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalmapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_slot_dir_funcs', 'pg_ls_logicalmapdir()', 'EXECUTE')" +== 086 +-- truncate_limit: 100 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_replslotdir(text)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_slot_dir_funcs', 'pg_ls_replslotdir(text)', 'EXECUTE')" +== 087 +-- truncate_limit: 100 +GRANT pg_monitor TO regress_slot_dir_funcs +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_monitor TO regress_slot_dir_funcs" +== 088 +-- truncate_limit: 100 +-- Role is now part of pg_monitor, so these are available. +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalsnapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_slot_dir_funcs', 'pg_ls_logicalsnapdir()', 'EXECUTE')" +== 089 +-- truncate_limit: 100 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalmapdir()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_slot_dir_funcs', 'pg_ls_logicalmapdir()', 'EXECUTE')" +== 090 +-- truncate_limit: 100 +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_replslotdir(text)', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_slot_dir_funcs', 'pg_ls_replslotdir(text)', 'EXECUTE')" +== 091 +-- truncate_limit: 100 +DROP ROLE regress_slot_dir_funcs +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_slot_dir_funcs" +== 092 +-- truncate_limit: 100 +|-- +-- Test adding a support function to a subject function +|-- + +CREATE FUNCTION my_int_eq(int, int) RETURNS bool + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$int4eq$$ +-- +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION my_int_eq(int, int) RETURNS bool LANGUAGE internal RETURNS NULL ON NULL INPUT IMM..." +== 093 +-- truncate_limit: 100 +-- By default, planner does not think that's selective +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FILTER: schema="" table="a" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 WHERE my_int_eq(a..." +== 094 +-- truncate_limit: 100 +-- With support function that knows it's int4eq, we get a different plan +CREATE FUNCTION test_support_func(internal) + RETURNS internal + AS :'regresslib', 'test_support_func' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 146 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 095 +-- truncate_limit: 100 +ALTER FUNCTION my_int_eq(int, int) SUPPORT test_support_func +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION my_int_eq(int, int) SUPPORT test_support_func" +== 096 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FUNCTION: name="my_int_eq" function="my_int_eq" schema="" ctx=Call +FILTER: schema="" table="a" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 WHERE my_int_eq(a..." +== 097 +-- truncate_limit: 100 +-- Also test non-default rowcount estimate +CREATE FUNCTION my_gen_series(int, int) RETURNS SETOF integer + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$generate_series_int4$$ + SUPPORT test_support_func +-- +FUNCTION: name="my_gen_series" function="my_gen_series" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION my_gen_series(int, int) RETURNS SETOF int LANGUAGE internal RETURNS NULL ON NULL ..." +== 098 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,1000) g ON a.unique1 = g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="my_gen_series" function="my_gen_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN my_gen_series(1, 1000) g ON a.unique1 = g" +== 099 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +FUNCTION: name="my_gen_series" function="my_gen_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN my_gen_series(1, 10) g ON a.unique1 = g" +== 100 +-- truncate_limit: 100 +-- Test functions for control data +SELECT count(*) > 0 AS ok FROM pg_control_checkpoint() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_checkpoint" function="pg_control_checkpoint" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM pg_control_checkpoint()" +== 101 +-- truncate_limit: 100 +SELECT count(*) > 0 AS ok FROM pg_control_init() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_init" function="pg_control_init" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM pg_control_init()" +== 102 +-- truncate_limit: 100 +SELECT count(*) > 0 AS ok FROM pg_control_recovery() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_recovery" function="pg_control_recovery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM pg_control_recovery()" +== 103 +-- truncate_limit: 100 +SELECT count(*) > 0 AS ok FROM pg_control_system() +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_control_system" function="pg_control_system" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM pg_control_system()" +== 104 +-- truncate_limit: 100 +-- pg_split_walfile_name, pg_walfile_name & pg_walfile_name_offset +SELECT * FROM pg_split_walfile_name(NULL) +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_split_walfile_name(NULL)" +== 105 +-- truncate_limit: 100 +SELECT * FROM pg_split_walfile_name('invalid') +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_split_walfile_name('invalid')" +== 106 +-- truncate_limit: 100 +SELECT segment_number > 0 AS ok_segment_number, timeline_id + FROM pg_split_walfile_name('000000010000000100000000') +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_split_walfile_name('000000010000000100000000')" +== 107 +-- truncate_limit: 100 +SELECT segment_number > 0 AS ok_segment_number, timeline_id + FROM pg_split_walfile_name('ffffffFF00000001000000af') +-- +FUNCTION: name="pg_split_walfile_name" function="pg_split_walfile_name" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_split_walfile_name('ffffffFF00000001000000af')" +== 108 +-- truncate_limit: 100 +SELECT setting::int8 AS segment_size +FROM pg_settings +WHERE name = 'wal_segment_size' +SELECT segment_number, file_offset +FROM pg_walfile_name_offset('0/0'::pg_lsn + :segment_size), + pg_split_walfile_name(file_name) +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 87 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 109 +-- truncate_limit: 100 +SELECT segment_number, file_offset +FROM pg_walfile_name_offset('0/0'::pg_lsn + :segment_size + 1), + pg_split_walfile_name(file_name) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 80 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 110 +-- truncate_limit: 100 +SELECT segment_number, file_offset = :segment_size - 1 +FROM pg_walfile_name_offset('0/0'::pg_lsn + :segment_size - 1), + pg_split_walfile_name(file_name) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 38 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 111 +-- truncate_limit: 100 +-- pg_current_logfile +CREATE ROLE regress_current_logfile +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_current_logfile" +== 112 +-- truncate_limit: 100 +-- not available by default +SELECT has_function_privilege('regress_current_logfile', + 'pg_current_logfile()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_current_logfile', 'pg_current_logfile()', 'EXECUTE')" +== 113 +-- truncate_limit: 100 +GRANT pg_monitor TO regress_current_logfile +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_monitor TO regress_current_logfile" +== 114 +-- truncate_limit: 100 +-- role has privileges of pg_monitor and can execute the function +SELECT has_function_privilege('regress_current_logfile', + 'pg_current_logfile()', 'EXECUTE') +-- +FUNCTION: name="has_function_privilege" function="has_function_privilege" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT has_function_privilege('regress_current_logfile', 'pg_current_logfile()', 'EXECUTE')" +== 115 +-- truncate_limit: 100 +DROP ROLE regress_current_logfile +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_current_logfile" +== 116 +-- truncate_limit: 100 +-- pg_column_toast_chunk_id +CREATE TABLE test_chunk_id (a TEXT, b TEXT STORAGE EXTERNAL) +-- +TABLE: name="test_chunk_id" schema="" table="test_chunk_id" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_chunk_id (a text, b text STORAGE external)" +== 117 +-- truncate_limit: 100 +INSERT INTO test_chunk_id VALUES ('x', repeat('x', 8192)) +-- +TABLE: name="test_chunk_id" schema="" table="test_chunk_id" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_chunk_id VALUES ('x', repeat('x', 8192))" +== 118 +-- truncate_limit: 100 +SELECT t.relname AS toastrel FROM pg_class c + LEFT JOIN pg_class t ON c.reltoastrelid = t.oid + WHERE c.relname = 'test_chunk_id' +SELECT pg_column_toast_chunk_id(a) IS NULL, + pg_column_toast_chunk_id(b) IN (SELECT chunk_id FROM pg_toast.:toastrel) + FROM test_chunk_id +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 132 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 119 +-- truncate_limit: 100 +DROP TABLE test_chunk_id +-- +TABLE: name="test_chunk_id" schema="" table="test_chunk_id" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_chunk_id" diff --git a/parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json new file mode 100644 index 0000000..e8e06a4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json @@ -0,0 +1,9 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/misc_sanity.test b/parser/testdata/summary_truncate/postgres_regress/misc_sanity.test new file mode 100644 index 0000000..95573e8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/misc_sanity.test @@ -0,0 +1,128 @@ +== 001 +-- truncate_limit: 100 +|-- +-- MISC_SANITY +-- Sanity checks for common errors in making system tables that don't fit +-- comfortably into either opr_sanity or type_sanity. +|-- +-- Every test failure in this file should be closely inspected. +-- The description of the failing test should be read carefully before +-- adjusting the expected output. In most cases, the queries should +-- not find *any* matching entries. +|-- +-- NB: run this test early, because some later tests create bogus entries. + + +-- **************** pg_depend **************** + +-- Look for illegal values in pg_depend fields. + +SELECT * +FROM pg_depend as d1 +WHERE refclassid = 0 OR refobjid = 0 OR + classid = 0 OR objid = 0 OR + deptype NOT IN ('a', 'e', 'i', 'n', 'x', 'P', 'S') +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=Select +ALIAS: "d1"="pg_depend" +FILTER: schema="" table="" column="refclassid" +FILTER: schema="" table="" column="refobjid" +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +FILTER: schema="" table="" column="deptype" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_depend d1 WHERE ..." +== 002 +-- truncate_limit: 100 +-- **************** pg_shdepend **************** + +-- Look for illegal values in pg_shdepend fields. + +SELECT * +FROM pg_shdepend as d1 +WHERE refclassid = 0 OR refobjid = 0 OR + classid = 0 OR objid = 0 OR + deptype NOT IN ('a', 'i', 'o', 'r', 't') +-- +TABLE: name="pg_shdepend" schema="" table="pg_shdepend" ctx=Select +ALIAS: "d1"="pg_shdepend" +FILTER: schema="" table="" column="refclassid" +FILTER: schema="" table="" column="refobjid" +FILTER: schema="" table="" column="classid" +FILTER: schema="" table="" column="objid" +FILTER: schema="" table="" column="deptype" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_shdepend d1 WHERE ..." +== 003 +-- truncate_limit: 100 +-- **************** pg_class **************** + +-- Look for system tables with varlena columns but no toast table. All +-- system tables with toastable columns should have toast tables, with +-- the following exceptions: +-- 1. pg_class, pg_attribute, and pg_index, due to fear of recursive +-- dependencies as toast tables depend on them. +-- 2. pg_largeobject and pg_largeobject_metadata. Large object catalogs +-- and toast tables are mutually exclusive and large object data is handled +-- as user data by pg_upgrade, which would cause failures. + +SELECT relname, attname, atttypid::regtype +FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid +WHERE c.oid < 16384 AND + reltoastrelid = 0 AND + relkind = 'r' AND + attstorage != 'p' +ORDER BY 1, 2 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="reltoastrelid" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="attstorage" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid WHERE ... ORDER BY 1, 2" +== 004 +-- truncate_limit: 100 +-- system catalogs without primary keys +|-- +-- Current exceptions: +-- * pg_depend, pg_shdepend don't have a unique key +SELECT relname +FROM pg_class +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'r' + AND pg_class.oid NOT IN (SELECT indrelid FROM pg_index WHERE indisprimary) +ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="pg_class" column="oid" +FILTER: schema="" table="" column="indisprimary" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE ... ORDER BY 1" +== 005 +-- truncate_limit: 100 +-- system catalog unique indexes not wrapped in a constraint +-- (There should be none.) +SELECT relname +FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'i' + AND i.indisunique + AND c.oid NOT IN (SELECT conindid FROM pg_constraint) +ORDER BY 1 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="i" column="indisunique" +FILTER: schema="" table="c" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid WHERE ... ORDER BY 1" diff --git a/parser/testdata/summary_truncate/postgres_regress/money.metadata.json b/parser/testdata/summary_truncate/postgres_regress/money.metadata.json new file mode 100644 index 0000000..c169184 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/money.metadata.json @@ -0,0 +1,113 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/money.test b/parser/testdata/summary_truncate/postgres_regress/money.test new file mode 100644 index 0000000..00d4342 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/money.test @@ -0,0 +1,743 @@ +== 001 +-- truncate_limit: 100 +|-- +-- MONEY +|-- +-- Note that we assume lc_monetary has been set to C. +|-- + +CREATE TABLE money_data (m money) +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE money_data (m money)" +== 002 +-- truncate_limit: 100 +INSERT INTO money_data VALUES ('123') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO money_data VALUES ('123')" +== 003 +-- truncate_limit: 100 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM money_data" +== 004 +-- truncate_limit: 100 +SELECT m + '123' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m + '123' FROM money_data" +== 005 +-- truncate_limit: 100 +SELECT m + '123.45' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m + '123.45' FROM money_data" +== 006 +-- truncate_limit: 100 +SELECT m - '123.45' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m - '123.45' FROM money_data" +== 007 +-- truncate_limit: 100 +SELECT m / '2'::money FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m / '2'::money FROM money_data" +== 008 +-- truncate_limit: 100 +SELECT m * 2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m * 2 FROM money_data" +== 009 +-- truncate_limit: 100 +SELECT 2 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 2 * m FROM money_data" +== 010 +-- truncate_limit: 100 +SELECT m / 2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m / 2 FROM money_data" +== 011 +-- truncate_limit: 100 +SELECT m * 2::int2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m * 2::int2 FROM money_data" +== 012 +-- truncate_limit: 100 +SELECT 2::int2 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 2::int2 * m FROM money_data" +== 013 +-- truncate_limit: 100 +SELECT m / 2::int2 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m / 2::int2 FROM money_data" +== 014 +-- truncate_limit: 100 +SELECT m * 2::int8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m * 2::int8 FROM money_data" +== 015 +-- truncate_limit: 100 +SELECT 2::int8 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 2::int8 * m FROM money_data" +== 016 +-- truncate_limit: 100 +SELECT m / 2::int8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m / 2::int8 FROM money_data" +== 017 +-- truncate_limit: 100 +SELECT m * 2::float8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m * 2::float8 FROM money_data" +== 018 +-- truncate_limit: 100 +SELECT 2::float8 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 2::float8 * m FROM money_data" +== 019 +-- truncate_limit: 100 +SELECT m / 2::float8 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m / 2::float8 FROM money_data" +== 020 +-- truncate_limit: 100 +SELECT m * 2::float4 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m * 2::float4 FROM money_data" +== 021 +-- truncate_limit: 100 +SELECT 2::float4 * m FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 2::float4 * m FROM money_data" +== 022 +-- truncate_limit: 100 +SELECT m / 2::float4 FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m / 2::float4 FROM money_data" +== 023 +-- truncate_limit: 100 +-- All true +SELECT m = '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m = '$123.00' FROM money_data" +== 024 +-- truncate_limit: 100 +SELECT m != '$124.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m <> '$124.00' FROM money_data" +== 025 +-- truncate_limit: 100 +SELECT m <= '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m <= '$123.00' FROM money_data" +== 026 +-- truncate_limit: 100 +SELECT m >= '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m >= '$123.00' FROM money_data" +== 027 +-- truncate_limit: 100 +SELECT m < '$124.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m < '$124.00' FROM money_data" +== 028 +-- truncate_limit: 100 +SELECT m > '$122.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m > '$122.00' FROM money_data" +== 029 +-- truncate_limit: 100 +-- All false +SELECT m = '$123.01' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m = '$123.01' FROM money_data" +== 030 +-- truncate_limit: 100 +SELECT m != '$123.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m <> '$123.00' FROM money_data" +== 031 +-- truncate_limit: 100 +SELECT m <= '$122.99' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m <= '$122.99' FROM money_data" +== 032 +-- truncate_limit: 100 +SELECT m >= '$123.01' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m >= '$123.01' FROM money_data" +== 033 +-- truncate_limit: 100 +SELECT m > '$124.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m > '$124.00' FROM money_data" +== 034 +-- truncate_limit: 100 +SELECT m < '$122.00' FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT m < '$122.00' FROM money_data" +== 035 +-- truncate_limit: 100 +SELECT cashlarger(m, '$124.00') FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cashlarger" function="cashlarger" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cashlarger(m, '$124.00') FROM money_data" +== 036 +-- truncate_limit: 100 +SELECT cashsmaller(m, '$124.00') FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cashsmaller" function="cashsmaller" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cashsmaller(m, '$124.00') FROM money_data" +== 037 +-- truncate_limit: 100 +SELECT cash_words(m) FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cash_words" function="cash_words" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cash_words(m) FROM money_data" +== 038 +-- truncate_limit: 100 +SELECT cash_words(m + '1.23') FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +FUNCTION: name="cash_words" function="cash_words" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cash_words(m + '1.23') FROM money_data" +== 039 +-- truncate_limit: 100 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM money_data" +== 040 +-- truncate_limit: 100 +INSERT INTO money_data VALUES ('$123.45') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO money_data VALUES ('$123.45')" +== 041 +-- truncate_limit: 100 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM money_data" +== 042 +-- truncate_limit: 100 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM money_data" +== 043 +-- truncate_limit: 100 +INSERT INTO money_data VALUES ('$123.451') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO money_data VALUES ('$123.451')" +== 044 +-- truncate_limit: 100 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM money_data" +== 045 +-- truncate_limit: 100 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM money_data" +== 046 +-- truncate_limit: 100 +INSERT INTO money_data VALUES ('$123.454') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO money_data VALUES ('$123.454')" +== 047 +-- truncate_limit: 100 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM money_data" +== 048 +-- truncate_limit: 100 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM money_data" +== 049 +-- truncate_limit: 100 +INSERT INTO money_data VALUES ('$123.455') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO money_data VALUES ('$123.455')" +== 050 +-- truncate_limit: 100 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM money_data" +== 051 +-- truncate_limit: 100 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM money_data" +== 052 +-- truncate_limit: 100 +INSERT INTO money_data VALUES ('$123.456') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO money_data VALUES ('$123.456')" +== 053 +-- truncate_limit: 100 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM money_data" +== 054 +-- truncate_limit: 100 +DELETE FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM money_data" +== 055 +-- truncate_limit: 100 +INSERT INTO money_data VALUES ('$123.459') +-- +TABLE: name="money_data" schema="" table="money_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO money_data VALUES ('$123.459')" +== 056 +-- truncate_limit: 100 +SELECT * FROM money_data +-- +TABLE: name="money_data" schema="" table="money_data" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM money_data" +== 057 +-- truncate_limit: 100 +-- input checks +SELECT '1234567890'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1234567890'::money" +== 058 +-- truncate_limit: 100 +SELECT '12345678901234567'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345678901234567'::money" +== 059 +-- truncate_limit: 100 +SELECT '123456789012345678'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '123456789012345678'::money" +== 060 +-- truncate_limit: 100 +SELECT '9223372036854775807'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '9223372036854775807'::money" +== 061 +-- truncate_limit: 100 +SELECT '-12345'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-12345'::money" +== 062 +-- truncate_limit: 100 +SELECT '-1234567890'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1234567890'::money" +== 063 +-- truncate_limit: 100 +SELECT '-12345678901234567'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-12345678901234567'::money" +== 064 +-- truncate_limit: 100 +SELECT '-123456789012345678'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-123456789012345678'::money" +== 065 +-- truncate_limit: 100 +SELECT '-9223372036854775808'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-9223372036854775808'::money" +== 066 +-- truncate_limit: 100 +-- special characters +SELECT '(1)'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1)'::money" +== 067 +-- truncate_limit: 100 +SELECT '($123,456.78)'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '($123,456.78)'::money" +== 068 +-- truncate_limit: 100 +-- test non-error-throwing API +SELECT pg_input_is_valid('\x0001', 'money') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid(E'\\\\x0001', 'money')" +== 069 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('\x0001', 'money') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info(E'\\\\x0001', 'money')" +== 070 +-- truncate_limit: 100 +SELECT pg_input_is_valid('192233720368547758.07', 'money') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('192233720368547758.07', 'money')" +== 071 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('192233720368547758.07', 'money') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('192233720368547758.07', 'money')" +== 072 +-- truncate_limit: 100 +-- documented minimums and maximums +SELECT '-92233720368547758.08'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-92233720368547758.08'::money" +== 073 +-- truncate_limit: 100 +SELECT '92233720368547758.07'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '92233720368547758.07'::money" +== 074 +-- truncate_limit: 100 +SELECT '-92233720368547758.09'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-92233720368547758.09'::money" +== 075 +-- truncate_limit: 100 +SELECT '92233720368547758.08'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '92233720368547758.08'::money" +== 076 +-- truncate_limit: 100 +-- rounding +SELECT '-92233720368547758.085'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-92233720368547758.085'::money" +== 077 +-- truncate_limit: 100 +SELECT '92233720368547758.075'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '92233720368547758.075'::money" +== 078 +-- truncate_limit: 100 +-- rounding vs. truncation in division +SELECT '878.08'::money / 11::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '878.08'::money / 11::float8" +== 079 +-- truncate_limit: 100 +SELECT '878.08'::money / 11::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '878.08'::money / 11::float4" +== 080 +-- truncate_limit: 100 +SELECT '878.08'::money / 11::bigint +-- +STMT: SelectStmt +TRUNCATED: "SELECT '878.08'::money / 11::bigint" +== 081 +-- truncate_limit: 100 +SELECT '878.08'::money / 11::int +-- +STMT: SelectStmt +TRUNCATED: "SELECT '878.08'::money / 11::int" +== 082 +-- truncate_limit: 100 +SELECT '878.08'::money / 11::smallint +-- +STMT: SelectStmt +TRUNCATED: "SELECT '878.08'::money / 11::smallint" +== 083 +-- truncate_limit: 100 +-- check for precision loss in division +SELECT '90000000000000099.00'::money / 10::bigint +-- +STMT: SelectStmt +TRUNCATED: "SELECT '90000000000000099.00'::money / 10::bigint" +== 084 +-- truncate_limit: 100 +SELECT '90000000000000099.00'::money / 10::int +-- +STMT: SelectStmt +TRUNCATED: "SELECT '90000000000000099.00'::money / 10::int" +== 085 +-- truncate_limit: 100 +SELECT '90000000000000099.00'::money / 10::smallint +-- +STMT: SelectStmt +TRUNCATED: "SELECT '90000000000000099.00'::money / 10::smallint" +== 086 +-- truncate_limit: 100 +-- Cast int4/int8/numeric to money +SELECT 1234567890::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1234567890::money" +== 087 +-- truncate_limit: 100 +SELECT 12345678901234567::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (12345678901234567)::money" +== 088 +-- truncate_limit: 100 +SELECT (-12345)::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-12345)::money" +== 089 +-- truncate_limit: 100 +SELECT (-1234567890)::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-1234567890)::money" +== 090 +-- truncate_limit: 100 +SELECT (-12345678901234567)::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-12345678901234567)::money" +== 091 +-- truncate_limit: 100 +SELECT 1234567890::int4::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1234567890::int4::money" +== 092 +-- truncate_limit: 100 +SELECT 12345678901234567::int8::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (12345678901234567)::int8::money" +== 093 +-- truncate_limit: 100 +SELECT 12345678901234567::numeric::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (12345678901234567)::numeric::money" +== 094 +-- truncate_limit: 100 +SELECT (-1234567890)::int4::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-1234567890)::int4::money" +== 095 +-- truncate_limit: 100 +SELECT (-12345678901234567)::int8::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-12345678901234567)::int8::money" +== 096 +-- truncate_limit: 100 +SELECT (-12345678901234567)::numeric::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-12345678901234567)::numeric::money" +== 097 +-- truncate_limit: 100 +-- Cast from money to numeric +SELECT '12345678901234567'::money::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12345678901234567'::money::numeric" +== 098 +-- truncate_limit: 100 +SELECT '-12345678901234567'::money::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-12345678901234567'::money::numeric" +== 099 +-- truncate_limit: 100 +SELECT '92233720368547758.07'::money::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '92233720368547758.07'::money::numeric" +== 100 +-- truncate_limit: 100 +SELECT '-92233720368547758.08'::money::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-92233720368547758.08'::money::numeric" +== 101 +-- truncate_limit: 100 +-- overflow checks +SELECT '92233720368547758.07'::money + '0.01'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '92233720368547758.07'::money + '0.01'::money" +== 102 +-- truncate_limit: 100 +SELECT '-92233720368547758.08'::money - '0.01'::money +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-92233720368547758.08'::money - '0.01'::money" +== 103 +-- truncate_limit: 100 +SELECT '92233720368547758.07'::money * 2::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '92233720368547758.07'::money * 2::float8" +== 104 +-- truncate_limit: 100 +SELECT '-1'::money / 1.175494e-38::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-1'::money / (1.175494e-38)::float4" +== 105 +-- truncate_limit: 100 +SELECT '92233720368547758.07'::money * 2::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '92233720368547758.07'::money * 2::int4" +== 106 +-- truncate_limit: 100 +SELECT '1'::money / 0::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::money / 0::int2" +== 107 +-- truncate_limit: 100 +SELECT '42'::money * 'inf'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::money * 'inf'::float8" +== 108 +-- truncate_limit: 100 +SELECT '42'::money * '-inf'::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::money * '-inf'::float8" +== 109 +-- truncate_limit: 100 +SELECT '42'::money * 'nan'::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::money * 'nan'::float4" diff --git a/parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json new file mode 100644 index 0000000..6769ac6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json @@ -0,0 +1,609 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/multirangetypes.test b/parser/testdata/summary_truncate/postgres_regress/multirangetypes.test new file mode 100644 index 0000000..016032c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/multirangetypes.test @@ -0,0 +1,5296 @@ +== 001 +-- truncate_limit: 100 +-- Tests for multirange data types. + +|-- +-- test input parser +|-- + +-- negative tests; should fail +select ''::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::textmultirange" +== 002 +-- truncate_limit: 100 +select '{,}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{,}'::textmultirange" +== 003 +-- truncate_limit: 100 +select '{(,)}.'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(,)}.'::textmultirange" +== 004 +-- truncate_limit: 100 +select '{[a,c),}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,c),}'::textmultirange" +== 005 +-- truncate_limit: 100 +select '{,[a,c)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{,[a,c)}'::textmultirange" +== 006 +-- truncate_limit: 100 +select '{-[a,z)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{-[a,z)}'::textmultirange" +== 007 +-- truncate_limit: 100 +select '{[a,z) - }'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,z) - }'::textmultirange" +== 008 +-- truncate_limit: 100 +select '{(",a)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(\",a)}'::textmultirange" +== 009 +-- truncate_limit: 100 +select '{(,,a)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(,,a)}'::textmultirange" +== 010 +-- truncate_limit: 100 +select '{(),a)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(),a)}'::textmultirange" +== 011 +-- truncate_limit: 100 +select '{(a,))}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(a,))}'::textmultirange" +== 012 +-- truncate_limit: 100 +select '{(],a)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(],a)}'::textmultirange" +== 013 +-- truncate_limit: 100 +select '{(a,])}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(a,])}'::textmultirange" +== 014 +-- truncate_limit: 100 +select '{[z,a]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[z,a]}'::textmultirange" +== 015 +-- truncate_limit: 100 +-- should succeed +select '{}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{}'::textmultirange" +== 016 +-- truncate_limit: 100 +select ' {} '::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' {} '::textmultirange" +== 017 +-- truncate_limit: 100 +select ' { empty, empty } '::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' { empty, empty } '::textmultirange" +== 018 +-- truncate_limit: 100 +select ' {( " a " " a ", " z " " z " ) }'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' {( \" a \" \" a \", \" z \" \" z \" ) }'::textmultirange" +== 019 +-- truncate_limit: 100 +select textrange('\\\\', repeat('a', 200))::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange(E'\\\\\\\\\\\\\\\\', repeat('a', 200))::textmultirange" +== 020 +-- truncate_limit: 100 +select '{(,z)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(,z)}'::textmultirange" +== 021 +-- truncate_limit: 100 +select '{(a,)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(a,)}'::textmultirange" +== 022 +-- truncate_limit: 100 +select '{[,z]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[,z]}'::textmultirange" +== 023 +-- truncate_limit: 100 +select '{[a,]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,]}'::textmultirange" +== 024 +-- truncate_limit: 100 +select '{(,)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(,)}'::textmultirange" +== 025 +-- truncate_limit: 100 +select '{[ , ]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[ , ]}'::textmultirange" +== 026 +-- truncate_limit: 100 +select '{["",""]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[\"\",\"\"]}'::textmultirange" +== 027 +-- truncate_limit: 100 +select '{[",",","]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[\",\",\",\"]}'::textmultirange" +== 028 +-- truncate_limit: 100 +select '{["\\","\\"]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{[\"\\\\\\\\\",\"\\\\\\\\\"]}'::textmultirange" +== 029 +-- truncate_limit: 100 +select '{["""","\""]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{[\"\"\"\",\"\\\\\"\"]}'::textmultirange" +== 030 +-- truncate_limit: 100 +select '{(\\,a)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'{(\\\\\\\\,a)}'::textmultirange" +== 031 +-- truncate_limit: 100 +select '{((,z)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{((,z)}'::textmultirange" +== 032 +-- truncate_limit: 100 +select '{([,z)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{([,z)}'::textmultirange" +== 033 +-- truncate_limit: 100 +select '{(!,()}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(!,()}'::textmultirange" +== 034 +-- truncate_limit: 100 +select '{(!,[)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(!,[)}'::textmultirange" +== 035 +-- truncate_limit: 100 +select '{[a,a]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,a]}'::textmultirange" +== 036 +-- truncate_limit: 100 +select '{[a,a],[a,b]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,a],[a,b]}'::textmultirange" +== 037 +-- truncate_limit: 100 +select '{[a,b), [b,e]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,b), [b,e]}'::textmultirange" +== 038 +-- truncate_limit: 100 +select '{[a,d), [b,f]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,d), [b,f]}'::textmultirange" +== 039 +-- truncate_limit: 100 +select '{[a,a],[b,b]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,a],[b,b]}'::textmultirange" +== 040 +-- truncate_limit: 100 +-- without canonicalization, we can't join these: +select '{[a,a], [b,b]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,a], [b,b]}'::textmultirange" +== 041 +-- truncate_limit: 100 +-- with canonicalization, we can join these: +select '{[1,2], [3,4]}'::int4multirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,2], [3,4]}'::int4multirange" +== 042 +-- truncate_limit: 100 +select '{[a,a], [b,b], [c,c]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,a], [b,b], [c,c]}'::textmultirange" +== 043 +-- truncate_limit: 100 +select '{[a,d], [b,e]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,d], [b,e]}'::textmultirange" +== 044 +-- truncate_limit: 100 +select '{[a,d), [d,e)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,d), [d,e)}'::textmultirange" +== 045 +-- truncate_limit: 100 +-- these are allowed but normalize to empty: +select '{[a,a)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[a,a)}'::textmultirange" +== 046 +-- truncate_limit: 100 +select '{(a,a]}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(a,a]}'::textmultirange" +== 047 +-- truncate_limit: 100 +select '{(a,a)}'::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(a,a)}'::textmultirange" +== 048 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +select pg_input_is_valid('{[1,2], [4,5]}', 'int4multirange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{[1,2], [4,5]}', 'int4multirange')" +== 049 +-- truncate_limit: 100 +select pg_input_is_valid('{[1,2], [4,5]', 'int4multirange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{[1,2], [4,5]', 'int4multirange')" +== 050 +-- truncate_limit: 100 +select * from pg_input_error_info('{[1,2], [4,5]', 'int4multirange') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{[1,2], [4,5]', 'int4multirange')" +== 051 +-- truncate_limit: 100 +select pg_input_is_valid('{[1,2], [4,zed]}', 'int4multirange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('{[1,2], [4,zed]}', 'int4multirange')" +== 052 +-- truncate_limit: 100 +select * from pg_input_error_info('{[1,2], [4,zed]}', 'int4multirange') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('{[1,2], [4,zed]}', 'int4multirange')" +== 053 +-- truncate_limit: 100 +|-- +-- test the constructor +--- +select textmultirange() +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textmultirange()" +== 054 +-- truncate_limit: 100 +select textmultirange(textrange('a', 'c')) +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textmultirange(textrange('a', 'c'))" +== 055 +-- truncate_limit: 100 +select textmultirange(textrange('a', 'c'), textrange('f', 'g')) +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textmultirange(textrange('a', 'c'), textrange('f', 'g'))" +== 056 +-- truncate_limit: 100 +select textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd')) +-- +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textmultirange(textrange(E'\\\\\\\\\\\\\\\\', repeat('a', 200)), textrange('c', 'd'))" +== 057 +-- truncate_limit: 100 +|-- +-- test casts, both a built-in range type and a user-defined one: +|-- +select 'empty'::int4range::int4multirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::int4range::int4multirange" +== 058 +-- truncate_limit: 100 +select int4range(1, 3)::int4multirange +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(1, 3)::int4multirange" +== 059 +-- truncate_limit: 100 +select int4range(1, null)::int4multirange +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(1, NULL)::int4multirange" +== 060 +-- truncate_limit: 100 +select int4range(null, null)::int4multirange +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(NULL, NULL)::int4multirange" +== 061 +-- truncate_limit: 100 +select 'empty'::textrange::textmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::textrange::textmultirange" +== 062 +-- truncate_limit: 100 +select textrange('a', 'c')::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange('a', 'c')::textmultirange" +== 063 +-- truncate_limit: 100 +select textrange('a', null)::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange('a', NULL)::textmultirange" +== 064 +-- truncate_limit: 100 +select textrange(null, null)::textmultirange +-- +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange(NULL, NULL)::textmultirange" +== 065 +-- truncate_limit: 100 +|-- +-- test unnest(multirange) function +|-- +select unnest(int4multirange(int4range('5', '6'), int4range('1', '2'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(int4multirange(int4range('5', '6'), int4range('1', '2')))" +== 066 +-- truncate_limit: 100 +select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e')))" +== 067 +-- truncate_limit: 100 +select unnest(textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="textmultirange" function="textmultirange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(textmultirange(textrange(E'\\\\\\\\\\\\\\\\', repeat('a', 200)), textrange('c', 'd')))" +== 068 +-- truncate_limit: 100 +|-- +-- create some test data and test the operators +|-- + +CREATE TABLE nummultirange_test (nmr NUMMULTIRANGE) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nummultirange_test (nmr nummultirange)" +== 069 +-- truncate_limit: 100 +CREATE INDEX nummultirange_test_btree ON nummultirange_test(nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX nummultirange_test_btree ON nummultirange_test USING btree (nmr)" +== 070 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES('{}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES ('{}')" +== 071 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES('{[,)}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES ('{[,)}')" +== 072 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES('{[3,]}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES ('{[3,]}')" +== 073 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES('{[,), [3,]}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES ('{[,), [3,]}')" +== 074 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES('{[, 5)}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES ('{[, 5)}')" +== 075 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES(nummultirange()) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES (nummultirange())" +== 076 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES(nummultirange(variadic '{}'::numrange[])) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES (nummultirange(VARIADIC '{}'::numrange[]))" +== 077 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.1, 2.2))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES (nummultirange(numrange(1.1, 2.2)))" +== 078 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES('{empty}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES ('{empty}')" +== 079 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES (nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9)))" +== 080 +-- truncate_limit: 100 +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test VALUES (nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1)))" +== 081 +-- truncate_limit: 100 +SELECT nmr, isempty(nmr), lower(nmr), upper(nmr) FROM nummultirange_test ORDER BY nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="isempty" function="isempty" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nmr, isempty(nmr), lower(nmr), upper(nmr) FROM nummultirange_test ORDER BY nmr" +== 082 +-- truncate_limit: 100 +SELECT nmr, lower_inc(nmr), lower_inf(nmr), upper_inc(nmr), upper_inf(nmr) FROM nummultirange_test ORDER BY nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="lower_inc" function="lower_inc" schema="" ctx=Call +FUNCTION: name="lower_inf" function="lower_inf" schema="" ctx=Call +FUNCTION: name="upper_inc" function="upper_inc" schema="" ctx=Call +FUNCTION: name="upper_inf" function="upper_inf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM nummultirange_test ORDER BY nmr" +== 083 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr = '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr = '{}'" +== 084 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr = '{(,5)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr = '{(,5)}'" +== 085 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr = '{[3,)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr = '{[3,)}'" +== 086 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7]}'" +== 087 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7],[1.9,2.1)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7],[1.9,2.1)}'" +== 088 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr < '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr < '{}'" +== 089 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr < '{[-1000.0, -1000.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr < '{[-1000.0, -1000.0]}'" +== 090 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr < '{[0.0, 1.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr < '{[0.0, 1.0]}'" +== 091 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr < '{[1000.0, 1001.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr < '{[1000.0, 1001.0]}'" +== 092 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr <= '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr <= '{}'" +== 093 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr <= '{[3,)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr <= '{[3,)}'" +== 094 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr >= '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr >= '{}'" +== 095 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr >= '{[3,)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr >= '{[3,)}'" +== 096 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr > '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr > '{}'" +== 097 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr > '{[-1000.0, -1000.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr > '{[-1000.0, -1000.0]}'" +== 098 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr > '{[0.0, 1.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr > '{[0.0, 1.0]}'" +== 099 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr > '{[1000.0, 1001.0]}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr > '{[1000.0, 1001.0]}'" +== 100 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr <> '{}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr <> '{}'" +== 101 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr <> '{(,5)}' +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr <> '{(,5)}'" +== 102 +-- truncate_limit: 100 +select nummultirange(numrange(2.0, 1.0)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(2.0, 1.0))" +== 103 +-- truncate_limit: 100 +select nummultirange(numrange(5.0, 6.0), numrange(1.0, 2.0)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(5.0, 6.0), numrange(1.0, 2.0))" +== 104 +-- truncate_limit: 100 +analyze nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE nummultirange_test" +== 105 +-- truncate_limit: 100 +-- overlaps +SELECT * FROM nummultirange_test WHERE range_overlaps_multirange(numrange(4.0, 4.2), nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_overlaps_multirange" function="range_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_overlaps_multirange" function="range_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE range_overlaps_multirange(numrange(4.0, 4.2), nmr)" +== 106 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) && nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) && nmr" +== 107 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE multirange_overlaps_range(nmr, numrange(4.0, 4.2)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_overlaps_range" function="multirange_overlaps_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange_overlaps_range" function="multirange_overlaps_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE multirange_overlaps_range(nmr, numrange(4.0, 4.2))" +== 108 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr && numrange(4.0, 4.2) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr && numrange(4.0, 4.2)" +== 109 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE multirange_overlaps_multirange(nmr, nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0))) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_overlaps_multirange" function="multirange_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange_overlaps_multirange" function="multirange_overlaps_multirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE ..." +== 110 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0))" +== 111 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0))" +== 112 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0), numrange(8.0, 9.0)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0), numrange(8.0, 9.0))" +== 113 +-- truncate_limit: 100 +-- mr contains x +SELECT * FROM nummultirange_test WHERE multirange_contains_elem(nmr, 4.0) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contains_elem" function="multirange_contains_elem" schema="" ctx=Call +FUNCTION: name="multirange_contains_elem" function="multirange_contains_elem" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE multirange_contains_elem(nmr, 4.0)" +== 114 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr @> 4.0 +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr @> 4.0" +== 115 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE multirange_contains_range(nmr, numrange(4.0, 4.2)) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contains_range" function="multirange_contains_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange_contains_range" function="multirange_contains_range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE multirange_contains_range(nmr, numrange(4.0, 4.2))" +== 116 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr @> numrange(4.0, 4.2) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr @> numrange(4.0, 4.2)" +== 117 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE multirange_contains_multirange(nmr, '{[4.0,4.2), [6.0, 8.0)}') +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contains_multirange" function="multirange_contains_multirange" schema="" ctx=Call +FUNCTION: name="multirange_contains_multirange" function="multirange_contains_multirange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE ..." +== 118 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE nmr @> '{[4.0,4.2), [6.0, 8.0)}'::nummultirange +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE nmr @> '{[4.0,4.2), [6.0, 8.0)}'::nummultirange" +== 119 +-- truncate_limit: 100 +-- x is contained by mr +SELECT * FROM nummultirange_test WHERE elem_contained_by_multirange(4.0, nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="elem_contained_by_multirange" function="elem_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="elem_contained_by_multirange" function="elem_contained_by_multirange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE elem_contained_by_multirange(4.0, nmr)" +== 120 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE 4.0 <@ nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE 4.0 <@ nmr" +== 121 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE range_contained_by_multirange(numrange(4.0, 4.2), nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_contained_by_multirange" function="range_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_contained_by_multirange" function="range_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE range_contained_by_multirange(numrange(4.0, 4.2), nmr)" +== 122 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) <@ nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) <@ nmr" +== 123 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE multirange_contained_by_multirange('{[4.0,4.2), [6.0, 8.0)}', nmr) +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="multirange_contained_by_multirange" function="multirange_contained_by_multirange" schema="" ctx=Call +FUNCTION: name="multirange_contained_by_multirange" function="multirange_contained_by_multirange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE ..." +== 124 +-- truncate_limit: 100 +SELECT * FROM nummultirange_test WHERE '{[4.0,4.2), [6.0, 8.0)}'::nummultirange <@ nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test WHERE '{[4.0,4.2), [6.0, 8.0)}'::nummultirange <@ nmr" +== 125 +-- truncate_limit: 100 +-- overlaps +SELECT 'empty'::numrange && nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange && nummultirange()" +== 126 +-- truncate_limit: 100 +SELECT 'empty'::numrange && nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange && nummultirange(numrange(1, 2))" +== 127 +-- truncate_limit: 100 +SELECT nummultirange() && 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() && 'empty'::numrange" +== 128 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) && 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) && 'empty'::numrange" +== 129 +-- truncate_limit: 100 +SELECT nummultirange() && nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() && nummultirange()" +== 130 +-- truncate_limit: 100 +SELECT nummultirange() && nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() && nummultirange(numrange(1, 2))" +== 131 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) && nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) && nummultirange()" +== 132 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(7,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) && nummultirange(numrange(1, 2), numrange(7, 8))" +== 133 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(7,8)) && nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(7, 8)) && nummultirange(numrange(3, 4))" +== 134 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(3.5,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) && nummultirange(numrange(1, 2), numrange(3.5, 8))" +== 135 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(3.5, 8)) && numrange(3, 4)" +== 136 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(3.5, 8)) && nummultirange(numrange(3, 4))" +== 137 +-- truncate_limit: 100 +select '{(10,20),(30,40),(50,60)}'::nummultirange && '(42,92)'::numrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(10,20),(30,40),(50,60)}'::nummultirange && '(42,92)'::numrange" +== 138 +-- truncate_limit: 100 +-- contains +SELECT nummultirange() @> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() @> nummultirange()" +== 139 +-- truncate_limit: 100 +SELECT nummultirange() @> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() @> 'empty'::numrange" +== 140 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,null)) @> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, NULL)) @> numrange(1, 2)" +== 141 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,null)) @> numrange(null,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, NULL)) @> numrange(NULL, 2)" +== 142 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,null)) @> numrange(2,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, NULL)) @> numrange(2, NULL)" +== 143 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,5)) @> numrange(null,3) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, 5)) @> numrange(NULL, 3)" +== 144 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,5)) @> numrange(null,8) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, 5)) @> numrange(NULL, 8)" +== 145 +-- truncate_limit: 100 +SELECT nummultirange(numrange(5,null)) @> numrange(8,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(5, NULL)) @> numrange(8, NULL)" +== 146 +-- truncate_limit: 100 +SELECT nummultirange(numrange(5,null)) @> numrange(3,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(5, NULL)) @> numrange(3, NULL)" +== 147 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5)) @> numrange(8,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5)) @> numrange(8, 9)" +== 148 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5)) @> numrange(3,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5)) @> numrange(3, 9)" +== 149 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5)) @> numrange(1,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5)) @> numrange(1, 4)" +== 150 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5)) @> numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5)) @> numrange(1, 5)" +== 151 +-- truncate_limit: 100 +SELECT nummultirange(numrange(-4,-2), numrange(1,5)) @> numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(-4, -2), numrange(1, 5)) @> numrange(1, 5)" +== 152 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5), numrange(8, 9)) @> numrange(1, 5)" +== 153 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(6,7) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5), numrange(8, 9)) @> numrange(6, 7)" +== 154 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5), numrange(6,9)) @> numrange(6,7) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5), numrange(6, 9)) @> numrange(6, 7)" +== 155 +-- truncate_limit: 100 +SELECT '{[1,5)}'::nummultirange @> '{[1,5)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5)}'::nummultirange @> '{[1,5)}'" +== 156 +-- truncate_limit: 100 +SELECT '{[-4,-2), [1,5)}'::nummultirange @> '{[1,5)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[-4,-2), [1,5)}'::nummultirange @> '{[1,5)}'" +== 157 +-- truncate_limit: 100 +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[1,5)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5), [8,9)}'::nummultirange @> '{[1,5)}'" +== 158 +-- truncate_limit: 100 +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[6,7)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5), [8,9)}'::nummultirange @> '{[6,7)}'" +== 159 +-- truncate_limit: 100 +SELECT '{[1,5), [6,9)}'::nummultirange @> '{[6,7)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5), [6,9)}'::nummultirange @> '{[6,7)}'" +== 160 +-- truncate_limit: 100 +select '{(10,20),(30,40),(50,60)}'::nummultirange @> '(52,56)'::numrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(10,20),(30,40),(50,60)}'::nummultirange @> '(52,56)'::numrange" +== 161 +-- truncate_limit: 100 +SELECT numrange(null,null) @> nummultirange(numrange(1,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, NULL) @> nummultirange(numrange(1, 2))" +== 162 +-- truncate_limit: 100 +SELECT numrange(null,null) @> nummultirange(numrange(null,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, NULL) @> nummultirange(numrange(NULL, 2))" +== 163 +-- truncate_limit: 100 +SELECT numrange(null,null) @> nummultirange(numrange(2,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, NULL) @> nummultirange(numrange(2, NULL))" +== 164 +-- truncate_limit: 100 +SELECT numrange(null,5) @> nummultirange(numrange(null,3)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, 5) @> nummultirange(numrange(NULL, 3))" +== 165 +-- truncate_limit: 100 +SELECT numrange(null,5) @> nummultirange(numrange(null,8)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, 5) @> nummultirange(numrange(NULL, 8))" +== 166 +-- truncate_limit: 100 +SELECT numrange(5,null) @> nummultirange(numrange(8,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(5, NULL) @> nummultirange(numrange(8, NULL))" +== 167 +-- truncate_limit: 100 +SELECT numrange(5,null) @> nummultirange(numrange(3,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(5, NULL) @> nummultirange(numrange(3, NULL))" +== 168 +-- truncate_limit: 100 +SELECT numrange(1,5) @> nummultirange(numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 5) @> nummultirange(numrange(8, 9))" +== 169 +-- truncate_limit: 100 +SELECT numrange(1,5) @> nummultirange(numrange(3,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 5) @> nummultirange(numrange(3, 9))" +== 170 +-- truncate_limit: 100 +SELECT numrange(1,5) @> nummultirange(numrange(1,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 5) @> nummultirange(numrange(1, 4))" +== 171 +-- truncate_limit: 100 +SELECT numrange(1,5) @> nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 5) @> nummultirange(numrange(1, 5))" +== 172 +-- truncate_limit: 100 +SELECT numrange(1,9) @> nummultirange(numrange(-4,-2), numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 9) @> nummultirange(numrange(-4, -2), numrange(1, 5))" +== 173 +-- truncate_limit: 100 +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 9) @> nummultirange(numrange(1, 5), numrange(8, 9))" +== 174 +-- truncate_limit: 100 +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 9) @> nummultirange(numrange(1, 5), numrange(6, 9))" +== 175 +-- truncate_limit: 100 +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,10)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 9) @> nummultirange(numrange(1, 5), numrange(6, 10))" +== 176 +-- truncate_limit: 100 +SELECT '{[1,9)}' @> '{[1,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,9)}' @> '{[1,5)}'::nummultirange" +== 177 +-- truncate_limit: 100 +SELECT '{[1,9)}' @> '{[-4,-2), [1,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,9)}' @> '{[-4,-2), [1,5)}'::nummultirange" +== 178 +-- truncate_limit: 100 +SELECT '{[1,9)}' @> '{[1,5), [8,9)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,9)}' @> '{[1,5), [8,9)}'::nummultirange" +== 179 +-- truncate_limit: 100 +SELECT '{[1,9)}' @> '{[1,5), [6,9)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,9)}' @> '{[1,5), [6,9)}'::nummultirange" +== 180 +-- truncate_limit: 100 +SELECT '{[1,9)}' @> '{[1,5), [6,10)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,9)}' @> '{[1,5), [6,10)}'::nummultirange" +== 181 +-- truncate_limit: 100 +-- is contained by +SELECT nummultirange() <@ nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() <@ nummultirange()" +== 182 +-- truncate_limit: 100 +SELECT 'empty'::numrange <@ nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange <@ nummultirange()" +== 183 +-- truncate_limit: 100 +SELECT numrange(1,2) <@ nummultirange(numrange(null,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) <@ nummultirange(numrange(NULL, NULL))" +== 184 +-- truncate_limit: 100 +SELECT numrange(null,2) <@ nummultirange(numrange(null,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, 2) <@ nummultirange(numrange(NULL, NULL))" +== 185 +-- truncate_limit: 100 +SELECT numrange(2,null) <@ nummultirange(numrange(null,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(2, NULL) <@ nummultirange(numrange(NULL, NULL))" +== 186 +-- truncate_limit: 100 +SELECT numrange(null,3) <@ nummultirange(numrange(null,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, 3) <@ nummultirange(numrange(NULL, 5))" +== 187 +-- truncate_limit: 100 +SELECT numrange(null,8) <@ nummultirange(numrange(null,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(NULL, 8) <@ nummultirange(numrange(NULL, 5))" +== 188 +-- truncate_limit: 100 +SELECT numrange(8,null) <@ nummultirange(numrange(5,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(8, NULL) <@ nummultirange(numrange(5, NULL))" +== 189 +-- truncate_limit: 100 +SELECT numrange(3,null) <@ nummultirange(numrange(5,null)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, NULL) <@ nummultirange(numrange(5, NULL))" +== 190 +-- truncate_limit: 100 +SELECT numrange(8,9) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(8, 9) <@ nummultirange(numrange(1, 5))" +== 191 +-- truncate_limit: 100 +SELECT numrange(3,9) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 9) <@ nummultirange(numrange(1, 5))" +== 192 +-- truncate_limit: 100 +SELECT numrange(1,4) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 4) <@ nummultirange(numrange(1, 5))" +== 193 +-- truncate_limit: 100 +SELECT numrange(1,5) <@ nummultirange(numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 5) <@ nummultirange(numrange(1, 5))" +== 194 +-- truncate_limit: 100 +SELECT numrange(1,5) <@ nummultirange(numrange(-4,-2), numrange(1,5)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 5) <@ nummultirange(numrange(-4, -2), numrange(1, 5))" +== 195 +-- truncate_limit: 100 +SELECT numrange(1,5) <@ nummultirange(numrange(1,5), numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 5) <@ nummultirange(numrange(1, 5), numrange(8, 9))" +== 196 +-- truncate_limit: 100 +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(8,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(6, 7) <@ nummultirange(numrange(1, 5), numrange(8, 9))" +== 197 +-- truncate_limit: 100 +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(6,9)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(6, 7) <@ nummultirange(numrange(1, 5), numrange(6, 9))" +== 198 +-- truncate_limit: 100 +SELECT '{[1,5)}' <@ '{[1,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5)}' <@ '{[1,5)}'::nummultirange" +== 199 +-- truncate_limit: 100 +SELECT '{[1,5)}' <@ '{[-4,-2), [1,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5)}' <@ '{[-4,-2), [1,5)}'::nummultirange" +== 200 +-- truncate_limit: 100 +SELECT '{[1,5)}' <@ '{[1,5), [8,9)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5)}' <@ '{[1,5), [8,9)}'::nummultirange" +== 201 +-- truncate_limit: 100 +SELECT '{[6,7)}' <@ '{[1,5), [8,9)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[6,7)}' <@ '{[1,5), [8,9)}'::nummultirange" +== 202 +-- truncate_limit: 100 +SELECT '{[6,7)}' <@ '{[1,5), [6,9)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[6,7)}' <@ '{[1,5), [6,9)}'::nummultirange" +== 203 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) <@ numrange(null,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) <@ numrange(NULL, NULL)" +== 204 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,2)) <@ numrange(null,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, 2)) <@ numrange(NULL, NULL)" +== 205 +-- truncate_limit: 100 +SELECT nummultirange(numrange(2,null)) <@ numrange(null,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(2, NULL)) <@ numrange(NULL, NULL)" +== 206 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,3)) <@ numrange(null,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, 3)) <@ numrange(NULL, 5)" +== 207 +-- truncate_limit: 100 +SELECT nummultirange(numrange(null,8)) <@ numrange(null,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(NULL, 8)) <@ numrange(NULL, 5)" +== 208 +-- truncate_limit: 100 +SELECT nummultirange(numrange(8,null)) <@ numrange(5,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(8, NULL)) <@ numrange(5, NULL)" +== 209 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,null)) <@ numrange(5,null) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, NULL)) <@ numrange(5, NULL)" +== 210 +-- truncate_limit: 100 +SELECT nummultirange(numrange(8,9)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(8, 9)) <@ numrange(1, 5)" +== 211 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,9)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 9)) <@ numrange(1, 5)" +== 212 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,4)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 4)) <@ numrange(1, 5)" +== 213 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5)) <@ numrange(1,5) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5)) <@ numrange(1, 5)" +== 214 +-- truncate_limit: 100 +SELECT nummultirange(numrange(-4,-2), numrange(1,5)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(-4, -2), numrange(1, 5)) <@ numrange(1, 9)" +== 215 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5), numrange(8,9)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5), numrange(8, 9)) <@ numrange(1, 9)" +== 216 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5), numrange(6,9)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5), numrange(6, 9)) <@ numrange(1, 9)" +== 217 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,5), numrange(6,10)) <@ numrange(1,9) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 5), numrange(6, 10)) <@ numrange(1, 9)" +== 218 +-- truncate_limit: 100 +SELECT '{[1,5)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5)}'::nummultirange <@ '{[1,9)}'" +== 219 +-- truncate_limit: 100 +SELECT '{[-4,-2), [1,5)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[-4,-2), [1,5)}'::nummultirange <@ '{[1,9)}'" +== 220 +-- truncate_limit: 100 +SELECT '{[1,5), [8,9)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5), [8,9)}'::nummultirange <@ '{[1,9)}'" +== 221 +-- truncate_limit: 100 +SELECT '{[1,5), [6,9)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5), [6,9)}'::nummultirange <@ '{[1,9)}'" +== 222 +-- truncate_limit: 100 +SELECT '{[1,5), [6,10)}'::nummultirange <@ '{[1,9)}' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,5), [6,10)}'::nummultirange <@ '{[1,9)}'" +== 223 +-- truncate_limit: 100 +-- overleft +SELECT 'empty'::numrange &< nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange &< nummultirange()" +== 224 +-- truncate_limit: 100 +SELECT 'empty'::numrange &< nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange &< nummultirange(numrange(1, 2))" +== 225 +-- truncate_limit: 100 +SELECT nummultirange() &< 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() &< 'empty'::numrange" +== 226 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) &< 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) &< 'empty'::numrange" +== 227 +-- truncate_limit: 100 +SELECT nummultirange() &< nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() &< nummultirange()" +== 228 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) &< nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) &< nummultirange()" +== 229 +-- truncate_limit: 100 +SELECT nummultirange() &< nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() &< nummultirange(numrange(1, 2))" +== 230 +-- truncate_limit: 100 +SELECT numrange(6,7) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(6, 7) &< nummultirange(numrange(3, 4))" +== 231 +-- truncate_limit: 100 +SELECT numrange(1,2) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) &< nummultirange(numrange(3, 4))" +== 232 +-- truncate_limit: 100 +SELECT numrange(1,4) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 4) &< nummultirange(numrange(3, 4))" +== 233 +-- truncate_limit: 100 +SELECT numrange(1,6) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 6) &< nummultirange(numrange(3, 4))" +== 234 +-- truncate_limit: 100 +SELECT numrange(3.5,6) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3.5, 6) &< nummultirange(numrange(3, 4))" +== 235 +-- truncate_limit: 100 +SELECT nummultirange(numrange(6,7)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(6, 7)) &< numrange(3, 4)" +== 236 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) &< numrange(3, 4)" +== 237 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,4)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 4)) &< numrange(3, 4)" +== 238 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,6)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 6)) &< numrange(3, 4)" +== 239 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3.5,6)) &< numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3.5, 6)) &< numrange(3, 4)" +== 240 +-- truncate_limit: 100 +SELECT nummultirange(numrange(6,7)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(6, 7)) &< nummultirange(numrange(3, 4))" +== 241 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) &< nummultirange(numrange(3, 4))" +== 242 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,4)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 4)) &< nummultirange(numrange(3, 4))" +== 243 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,6)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 6)) &< nummultirange(numrange(3, 4))" +== 244 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3.5,6)) &< nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3.5, 6)) &< nummultirange(numrange(3, 4))" +== 245 +-- truncate_limit: 100 +-- overright +SELECT nummultirange() &> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() &> 'empty'::numrange" +== 246 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) &> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) &> 'empty'::numrange" +== 247 +-- truncate_limit: 100 +SELECT 'empty'::numrange &> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange &> nummultirange()" +== 248 +-- truncate_limit: 100 +SELECT 'empty'::numrange &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange &> nummultirange(numrange(1, 2))" +== 249 +-- truncate_limit: 100 +SELECT nummultirange() &> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() &> nummultirange()" +== 250 +-- truncate_limit: 100 +SELECT nummultirange() &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() &> nummultirange(numrange(1, 2))" +== 251 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) &> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) &> nummultirange()" +== 252 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> numrange(6,7) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> numrange(6, 7)" +== 253 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> numrange(1, 2)" +== 254 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> numrange(1,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> numrange(1, 4)" +== 255 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> numrange(1,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> numrange(1, 6)" +== 256 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> numrange(3.5,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> numrange(3.5, 6)" +== 257 +-- truncate_limit: 100 +SELECT numrange(3,4) &> nummultirange(numrange(6,7)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 4) &> nummultirange(numrange(6, 7))" +== 258 +-- truncate_limit: 100 +SELECT numrange(3,4) &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 4) &> nummultirange(numrange(1, 2))" +== 259 +-- truncate_limit: 100 +SELECT numrange(3,4) &> nummultirange(numrange(1,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 4) &> nummultirange(numrange(1, 4))" +== 260 +-- truncate_limit: 100 +SELECT numrange(3,4) &> nummultirange(numrange(1,6)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 4) &> nummultirange(numrange(1, 6))" +== 261 +-- truncate_limit: 100 +SELECT numrange(3,4) &> nummultirange(numrange(3.5,6)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 4) &> nummultirange(numrange(3.5, 6))" +== 262 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(6,7)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> nummultirange(numrange(6, 7))" +== 263 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> nummultirange(numrange(1, 2))" +== 264 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> nummultirange(numrange(1, 4))" +== 265 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,6)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> nummultirange(numrange(1, 6))" +== 266 +-- truncate_limit: 100 +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(3.5,6)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) &> nummultirange(numrange(3.5, 6))" +== 267 +-- truncate_limit: 100 +-- meets +SELECT 'empty'::numrange -|- nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange -|- nummultirange()" +== 268 +-- truncate_limit: 100 +SELECT 'empty'::numrange -|- nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange -|- nummultirange(numrange(1, 2))" +== 269 +-- truncate_limit: 100 +SELECT nummultirange() -|- 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() -|- 'empty'::numrange" +== 270 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) -|- 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) -|- 'empty'::numrange" +== 271 +-- truncate_limit: 100 +SELECT nummultirange() -|- nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() -|- nummultirange()" +== 272 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) -|- nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) -|- nummultirange()" +== 273 +-- truncate_limit: 100 +SELECT nummultirange() -|- nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() -|- nummultirange(numrange(1, 2))" +== 274 +-- truncate_limit: 100 +SELECT numrange(1,2) -|- nummultirange(numrange(2,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) -|- nummultirange(numrange(2, 4))" +== 275 +-- truncate_limit: 100 +SELECT numrange(1,2) -|- nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) -|- nummultirange(numrange(3, 4))" +== 276 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) -|- numrange(2,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) -|- numrange(2, 4)" +== 277 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) -|- numrange(3,4) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) -|- numrange(3, 4)" +== 278 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) -|- nummultirange(numrange(2, 4))" +== 279 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) -|- nummultirange(numrange(3, 4))" +== 280 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(5, 6)) -|- nummultirange(numrange(3, 4))" +== 281 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(6,7)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(5, 6)) -|- nummultirange(numrange(6, 7))" +== 282 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(8,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(5, 6)) -|- nummultirange(numrange(8, 9))" +== 283 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4), numrange(6,7)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) -|- nummultirange(numrange(2, 4), numrange(6, 7))" +== 284 +-- truncate_limit: 100 +-- strictly left +select 'empty'::numrange << nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange << nummultirange()" +== 285 +-- truncate_limit: 100 +select numrange(1,2) << nummultirange() +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) << nummultirange()" +== 286 +-- truncate_limit: 100 +select numrange(1,2) << nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) << nummultirange(numrange(3, 4))" +== 287 +-- truncate_limit: 100 +select numrange(1,2) << nummultirange(numrange(0,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) << nummultirange(numrange(0, 4))" +== 288 +-- truncate_limit: 100 +select numrange(1,2) << nummultirange(numrange(0,4), numrange(7,8)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) << nummultirange(numrange(0, 4), numrange(7, 8))" +== 289 +-- truncate_limit: 100 +select nummultirange() << 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() << 'empty'::numrange" +== 290 +-- truncate_limit: 100 +select nummultirange() << numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() << numrange(1, 2)" +== 291 +-- truncate_limit: 100 +select nummultirange(numrange(3,4)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) << numrange(3, 6)" +== 292 +-- truncate_limit: 100 +select nummultirange(numrange(0,2)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(0, 2)) << numrange(3, 6)" +== 293 +-- truncate_limit: 100 +select nummultirange(numrange(0,2), numrange(7,8)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(0, 2), numrange(7, 8)) << numrange(3, 6)" +== 294 +-- truncate_limit: 100 +select nummultirange(numrange(-4,-2), numrange(0,2)) << numrange(3,6) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(-4, -2), numrange(0, 2)) << numrange(3, 6)" +== 295 +-- truncate_limit: 100 +select nummultirange() << nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() << nummultirange()" +== 296 +-- truncate_limit: 100 +select nummultirange() << nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() << nummultirange(numrange(1, 2))" +== 297 +-- truncate_limit: 100 +select nummultirange(numrange(1,2)) << nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) << nummultirange()" +== 298 +-- truncate_limit: 100 +select nummultirange(numrange(1,2)) << nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) << nummultirange(numrange(1, 2))" +== 299 +-- truncate_limit: 100 +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) << nummultirange(numrange(3, 4))" +== 300 +-- truncate_limit: 100 +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4), numrange(7,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) << nummultirange(numrange(3, 4), numrange(7, 8))" +== 301 +-- truncate_limit: 100 +select nummultirange(numrange(1,2), numrange(4,5)) << nummultirange(numrange(3,4), numrange(7,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 302 +-- truncate_limit: 100 +-- strictly right +select nummultirange() >> 'empty'::numrange +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() >> 'empty'::numrange" +== 303 +-- truncate_limit: 100 +select nummultirange() >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() >> numrange(1, 2)" +== 304 +-- truncate_limit: 100 +select nummultirange(numrange(3,4)) >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) >> numrange(1, 2)" +== 305 +-- truncate_limit: 100 +select nummultirange(numrange(0,4)) >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(0, 4)) >> numrange(1, 2)" +== 306 +-- truncate_limit: 100 +select nummultirange(numrange(0,4), numrange(7,8)) >> numrange(1,2) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(0, 4), numrange(7, 8)) >> numrange(1, 2)" +== 307 +-- truncate_limit: 100 +select 'empty'::numrange >> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'empty'::numrange >> nummultirange()" +== 308 +-- truncate_limit: 100 +select numrange(1,2) >> nummultirange() +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1, 2) >> nummultirange()" +== 309 +-- truncate_limit: 100 +select numrange(3,6) >> nummultirange(numrange(3,4)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 6) >> nummultirange(numrange(3, 4))" +== 310 +-- truncate_limit: 100 +select numrange(3,6) >> nummultirange(numrange(0,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 6) >> nummultirange(numrange(0, 2))" +== 311 +-- truncate_limit: 100 +select numrange(3,6) >> nummultirange(numrange(0,2), numrange(7,8)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 6) >> nummultirange(numrange(0, 2), numrange(7, 8))" +== 312 +-- truncate_limit: 100 +select numrange(3,6) >> nummultirange(numrange(-4,-2), numrange(0,2)) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3, 6) >> nummultirange(numrange(-4, -2), numrange(0, 2))" +== 313 +-- truncate_limit: 100 +select nummultirange() >> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() >> nummultirange()" +== 314 +-- truncate_limit: 100 +select nummultirange(numrange(1,2)) >> nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) >> nummultirange()" +== 315 +-- truncate_limit: 100 +select nummultirange() >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() >> nummultirange(numrange(1, 2))" +== 316 +-- truncate_limit: 100 +select nummultirange(numrange(1,2)) >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) >> nummultirange(numrange(1, 2))" +== 317 +-- truncate_limit: 100 +select nummultirange(numrange(3,4)) >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4)) >> nummultirange(numrange(1, 2))" +== 318 +-- truncate_limit: 100 +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(3, 4), numrange(7, 8)) >> nummultirange(numrange(1, 2))" +== 319 +-- truncate_limit: 100 +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2), numrange(4,5)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 320 +-- truncate_limit: 100 +-- union +SELECT nummultirange() + nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() + nummultirange()" +== 321 +-- truncate_limit: 100 +SELECT nummultirange() + nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() + nummultirange(numrange(1, 2))" +== 322 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) + nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) + nummultirange()" +== 323 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) + nummultirange(numrange(1, 2))" +== 324 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) + nummultirange(numrange(2, 4))" +== 325 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) + nummultirange(numrange(3, 4))" +== 326 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) + nummultirange(numrange(2, 4))" +== 327 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) + nummultirange(numrange(3, 4))" +== 328 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(0,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) + nummultirange(numrange(0, 9))" +== 329 +-- truncate_limit: 100 +-- merge +SELECT range_merge(nummultirange()) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_merge(nummultirange())" +== 330 +-- truncate_limit: 100 +SELECT range_merge(nummultirange(numrange(1,2))) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_merge(nummultirange(numrange(1, 2)))" +== 331 +-- truncate_limit: 100 +SELECT range_merge(nummultirange(numrange(1,2), numrange(7,8))) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_merge(nummultirange(numrange(1, 2), numrange(7, 8)))" +== 332 +-- truncate_limit: 100 +-- minus +SELECT nummultirange() - nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() - nummultirange()" +== 333 +-- truncate_limit: 100 +SELECT nummultirange() - nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() - nummultirange(numrange(1, 2))" +== 334 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) - nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) - nummultirange()" +== 335 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(3,4)) - nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(3, 4)) - nummultirange()" +== 336 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) - nummultirange(numrange(1, 2))" +== 337 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) - nummultirange(numrange(2, 4))" +== 338 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) - nummultirange(numrange(3, 4))" +== 339 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 4)) - nummultirange(numrange(1, 2))" +== 340 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(2,3)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 4)) - nummultirange(numrange(2, 3))" +== 341 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,8)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 4)) - nummultirange(numrange(0, 8))" +== 342 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 4)) - nummultirange(numrange(0, 2))" +== 343 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(0,2), numrange(3,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 8)) - nummultirange(numrange(0, 2), numrange(3, 4))" +== 344 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(2,3), numrange(5,null)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 8)) - nummultirange(numrange(2, 3), numrange(5, NULL))" +== 345 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) - nummultirange(numrange(-2, 0))" +== 346 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(2,4)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) - nummultirange(numrange(2, 4))" +== 347 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(3,5)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) - nummultirange(numrange(3, 5))" +== 348 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(0,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) - nummultirange(numrange(0, 9))" +== 349 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,3), numrange(4,5)) - nummultirange(numrange(2,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 3), numrange(4, 5)) - nummultirange(numrange(2, 9))" +== 350 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(8,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2), numrange(4, 5)) - nummultirange(numrange(8, 9))" +== 351 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0), numrange(8,9)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 352 +-- truncate_limit: 100 +-- intersection +SELECT nummultirange() * nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() * nummultirange()" +== 353 +-- truncate_limit: 100 +SELECT nummultirange() * nummultirange(numrange(1,2)) +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange() * nummultirange(numrange(1, 2))" +== 354 +-- truncate_limit: 100 +SELECT nummultirange(numrange(1,2)) * nummultirange() +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nummultirange(numrange(1, 2)) * nummultirange()" +== 355 +-- truncate_limit: 100 +SELECT '{[1,3)}'::nummultirange * '{[1,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,3)}'::nummultirange * '{[1,5)}'::nummultirange" +== 356 +-- truncate_limit: 100 +SELECT '{[1,3)}'::nummultirange * '{[0,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,3)}'::nummultirange * '{[0,5)}'::nummultirange" +== 357 +-- truncate_limit: 100 +SELECT '{[1,3)}'::nummultirange * '{[0,2)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,3)}'::nummultirange * '{[0,2)}'::nummultirange" +== 358 +-- truncate_limit: 100 +SELECT '{[1,3)}'::nummultirange * '{[2,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,3)}'::nummultirange * '{[2,5)}'::nummultirange" +== 359 +-- truncate_limit: 100 +SELECT '{[1,4)}'::nummultirange * '{[2,3)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,4)}'::nummultirange * '{[2,3)}'::nummultirange" +== 360 +-- truncate_limit: 100 +SELECT '{[1,4)}'::nummultirange * '{[0,2), [3,5)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,4)}'::nummultirange * '{[0,2), [3,5)}'::nummultirange" +== 361 +-- truncate_limit: 100 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,8), [9,12)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,8), [9,12)}'::nummultirange" +== 362 +-- truncate_limit: 100 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[9,12)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,4), [7,10)}'::nummultirange * '{[9,12)}'::nummultirange" +== 363 +-- truncate_limit: 100 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[-5,-4), [5,6), [9,12)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,4), [7,10)}'::nummultirange * '{[-5,-4), [5,6), [9,12)}'::nummultirange" +== 364 +-- truncate_limit: 100 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange" +== 365 +-- truncate_limit: 100 +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange" +== 366 +-- truncate_limit: 100 +-- test GiST index +create table test_multirange_gist(mr int4multirange) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_multirange_gist (mr int4multirange)" +== 367 +-- truncate_limit: 100 +insert into test_multirange_gist select int4multirange(int4range(g, g+10),int4range(g+20, g+30),int4range(g+40, g+50)) from generate_series(1,2000) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_multirange_gist SELECT ... FROM generate_series(1, 2000) g" +== 368 +-- truncate_limit: 100 +insert into test_multirange_gist select '{}'::int4multirange from generate_series(1,500) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_multirange_gist SELECT '{}'::int4multirange FROM generate_series(1, 500) g" +== 369 +-- truncate_limit: 100 +insert into test_multirange_gist select int4multirange(int4range(g, g+10000)) from generate_series(1,1000) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_multirange_gist SELECT ... FROM generate_series(1, 1000) g" +== 370 +-- truncate_limit: 100 +insert into test_multirange_gist select int4multirange(int4range(NULL, g*10, '(]'), int4range(g*10, g*20, '(]')) from generate_series(1,100) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_multirange_gist SELECT ... FROM generate_series(1, 100) g" +== 371 +-- truncate_limit: 100 +insert into test_multirange_gist select int4multirange(int4range(g*10, g*20, '(]'), int4range(g*20, NULL, '(]')) from generate_series(1,100) g +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DML +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_multirange_gist SELECT ... FROM generate_series(1, 100) g" +== 372 +-- truncate_limit: 100 +create index test_mulrirange_gist_idx on test_multirange_gist using gist (mr) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_mulrirange_gist_idx ON test_multirange_gist USING gist (mr)" +== 373 +-- truncate_limit: 100 +-- test statistics and selectivity estimation as well +|-- +-- We don't check the accuracy of selectivity estimation, but at least check +-- it doesn't fall. +analyze test_multirange_gist +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE test_multirange_gist" +== 374 +-- truncate_limit: 100 +-- first, verify non-indexed results +SET enable_seqscan = t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO t" +== 375 +-- truncate_limit: 100 +SET enable_indexscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO f" +== 376 +-- truncate_limit: 100 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO f" +== 377 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr = '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr = '{}'::int4multirange" +== 378 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> 'empty'::int4range" +== 379 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && 'empty'::int4range" +== 380 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ 'empty'::int4range" +== 381 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr << 'empty'::int4range" +== 382 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr >> 'empty'::int4range" +== 383 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &< 'empty'::int4range" +== 384 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &> 'empty'::int4range" +== 385 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr -|- 'empty'::int4range" +== 386 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> '{}'::int4multirange" +== 387 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> '{}'::int4multirange" +== 388 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && '{}'::int4multirange" +== 389 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ '{}'::int4multirange" +== 390 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr << '{}'::int4multirange" +== 391 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr >> '{}'::int4multirange" +== 392 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &< '{}'::int4multirange" +== 393 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &> '{}'::int4multirange" +== 394 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr -|- '{}'::int4multirange" +== 395 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 396 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> 10 +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> 10" +== 397 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> int4range(10, 20)" +== 398 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && int4range(10, 20)" +== 399 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ int4range(10,50) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ int4range(10, 50)" +== 400 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr << int4range(100, 500)" +== 401 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr >> int4range(100, 500)" +== 402 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &< int4range(100, 500)" +== 403 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &> int4range(100, 500)" +== 404 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr -|- int4range(100, 500)" +== 405 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> '{}'::int4multirange" +== 406 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 407 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && '{(10,20),(30,40),(50,60)}'::int4multirange" +== 408 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange" +== 409 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 410 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 411 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 412 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 413 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 414 +-- truncate_limit: 100 +-- now check same queries using index +SET enable_seqscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO f" +== 415 +-- truncate_limit: 100 +SET enable_indexscan = t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO t" +== 416 +-- truncate_limit: 100 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO f" +== 417 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr = '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr = '{}'::int4multirange" +== 418 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> 'empty'::int4range" +== 419 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && 'empty'::int4range" +== 420 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ 'empty'::int4range" +== 421 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr << 'empty'::int4range" +== 422 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr >> 'empty'::int4range" +== 423 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &< 'empty'::int4range" +== 424 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &> 'empty'::int4range" +== 425 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr -|- 'empty'::int4range" +== 426 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> '{}'::int4multirange" +== 427 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> '{}'::int4multirange" +== 428 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && '{}'::int4multirange" +== 429 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ '{}'::int4multirange" +== 430 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr << '{}'::int4multirange" +== 431 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr >> '{}'::int4multirange" +== 432 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &< '{}'::int4multirange" +== 433 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &> '{}'::int4multirange" +== 434 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr -|- '{}'::int4multirange" +== 435 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> 'empty'::int4range +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> 'empty'::int4range" +== 436 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 437 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> 10 +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> 10" +== 438 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> int4range(10, 20)" +== 439 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && int4range(10,20) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && int4range(10, 20)" +== 440 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ int4range(10,50) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ int4range(10, 50)" +== 441 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr << int4range(100, 500)" +== 442 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr >> int4range(100, 500)" +== 443 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &< int4range(100, 500)" +== 444 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr &> int4range(100, 500)" +== 445 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- int4range(100,500) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr -|- int4range(100, 500)" +== 446 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr @> '{}'::int4multirange" +== 447 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 448 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr && '{(10,20),(30,40),(50,60)}'::int4multirange" +== 449 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange" +== 450 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 451 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 452 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 453 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 454 +-- truncate_limit: 100 +select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="mr" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_multirange_gist WHERE ..." +== 455 +-- truncate_limit: 100 +drop table test_multirange_gist +-- +TABLE: name="test_multirange_gist" schema="" table="test_multirange_gist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_multirange_gist" +== 456 +-- truncate_limit: 100 +|-- +-- range_agg function +|-- +create table reservations ( room_id integer not null, booked_during daterange ) +-- +TABLE: name="reservations" schema="" table="reservations" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE reservations (room_id int NOT NULL, booked_during daterange)" +== 457 +-- truncate_limit: 100 +insert into reservations values +-- 1: has a meets and a gap +(1, daterange('2018-07-01', '2018-07-07')), +(1, daterange('2018-07-07', '2018-07-14')), +(1, daterange('2018-07-20', '2018-07-22')), +-- 2: just a single row +(2, daterange('2018-07-01', '2018-07-03')), +-- 3: one null range +(3, NULL), +-- 4: two null ranges +(4, NULL), +(4, NULL), +-- 5: a null range and a non-null range +(5, NULL), +(5, daterange('2018-07-01', '2018-07-03')), +-- 6: has overlap +(6, daterange('2018-07-01', '2018-07-07')), +(6, daterange('2018-07-05', '2018-07-10')), +-- 7: two ranges that meet: no gap or overlap +(7, daterange('2018-07-01', '2018-07-07')), +(7, daterange('2018-07-07', '2018-07-14')), +-- 8: an empty range +(8, 'empty'::daterange) +-- +TABLE: name="reservations" schema="" table="reservations" ctx=DML +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO reservations VALUES (...)" +== 458 +-- truncate_limit: 100 +SELECT room_id, range_agg(booked_during) +FROM reservations +GROUP BY room_id +ORDER BY room_id +-- +TABLE: name="reservations" schema="" table="reservations" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT room_id, range_agg(booked_during) FROM reservations GROUP BY room_id ORDER BY room_id" +== 459 +-- truncate_limit: 100 +-- range_agg on a custom range type too +SELECT range_agg(r) +FROM (VALUES + ('[a,c]'::textrange), + ('[b,b]'::textrange), + ('[c,f]'::textrange), + ('[g,h)'::textrange), + ('[h,j)'::textrange) + ) t(r) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(r) FROM (VALUES (...)) t(r)" +== 460 +-- truncate_limit: 100 +-- range_agg with multirange inputs +select range_agg(nmr) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM nummultirange_test" +== 461 +-- truncate_limit: 100 +select range_agg(nmr) from nummultirange_test where false +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM nummultirange_test WHERE false" +== 462 +-- truncate_limit: 100 +select range_agg(null::nummultirange) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(NULL::nummultirange) FROM nummultirange_test" +== 463 +-- truncate_limit: 100 +select range_agg(nmr) from (values ('{}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM (VALUES ('{}'::nummultirange)) t(nmr)" +== 464 +-- truncate_limit: 100 +select range_agg(nmr) from (values ('{}'::nummultirange), ('{}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM (VALUES ('{}'::nummultirange), ('{}'::nummultirange)) t(nmr)" +== 465 +-- truncate_limit: 100 +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM (VALUES ('{[1,2]}'::nummultirange)) t(nmr)" +== 466 +-- truncate_limit: 100 +select range_agg(nmr) from (values ('{[1,2], [5,6]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM (VALUES ('{[1,2], [5,6]}'::nummultirange)) t(nmr)" +== 467 +-- truncate_limit: 100 +select range_agg(nmr) from (values ('{[1,2], [2,3]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM (VALUES ('{[1,2], [2,3]}'::nummultirange)) t(nmr)" +== 468 +-- truncate_limit: 100 +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[5,6]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM (VALUES ('{[1,2]}'::nummultirange), ('{[5,6]}'::nummultirange)) t(nmr)" +== 469 +-- truncate_limit: 100 +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[2,3]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_agg" function="range_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_agg(nmr) FROM (VALUES ('{[1,2]}'::nummultirange), ('{[2,3]}'::nummultirange)) t(nmr)" +== 470 +-- truncate_limit: 100 +|-- +-- range_intersect_agg function +|-- +select range_intersect_agg(nmr) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM nummultirange_test" +== 471 +-- truncate_limit: 100 +select range_intersect_agg(nmr) from nummultirange_test where false +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM nummultirange_test WHERE false" +== 472 +-- truncate_limit: 100 +select range_intersect_agg(null::nummultirange) from nummultirange_test +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(NULL::nummultirange) FROM nummultirange_test" +== 473 +-- truncate_limit: 100 +select range_intersect_agg(nmr) from (values ('{[1,3]}'::nummultirange), ('{[6,12]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM (VALUES (...)) t(nmr)" +== 474 +-- truncate_limit: 100 +select range_intersect_agg(nmr) from (values ('{[1,6]}'::nummultirange), ('{[3,12]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM (VALUES (...)) t(nmr)" +== 475 +-- truncate_limit: 100 +select range_intersect_agg(nmr) from (values ('{[1,6], [10,12]}'::nummultirange), ('{[4,14]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM (VALUES (...)) t(nmr)" +== 476 +-- truncate_limit: 100 +-- test with just one input: +select range_intersect_agg(nmr) from (values ('{}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM (VALUES ('{}'::nummultirange)) t(nmr)" +== 477 +-- truncate_limit: 100 +select range_intersect_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM (VALUES ('{[1,2]}'::nummultirange)) t(nmr)" +== 478 +-- truncate_limit: 100 +select range_intersect_agg(nmr) from (values ('{[1,6], [10,12]}'::nummultirange)) t(nmr) +-- +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM (VALUES ('{[1,6], [10,12]}'::nummultirange)) t(nmr)" +== 479 +-- truncate_limit: 100 +select range_intersect_agg(nmr) from nummultirange_test where nmr @> 4.0 +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nmr) FROM nummultirange_test WHERE nmr @> 4.0" +== 480 +-- truncate_limit: 100 +create table nummultirange_test2(nmr nummultirange) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE nummultirange_test2 (nmr nummultirange)" +== 481 +-- truncate_limit: 100 +create index nummultirange_test2_hash_idx on nummultirange_test2 using hash (nmr) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX nummultirange_test2_hash_idx ON nummultirange_test2 USING hash (nmr)" +== 482 +-- truncate_limit: 100 +INSERT INTO nummultirange_test2 VALUES('{[, 5)}') +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test2 VALUES ('{[, 5)}')" +== 483 +-- truncate_limit: 100 +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test2 VALUES (nummultirange(numrange(1.1, 2.2)))" +== 484 +-- truncate_limit: 100 +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test2 VALUES (nummultirange(numrange(1.1, 2.2)))" +== 485 +-- truncate_limit: 100 +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2,'()'))) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test2 VALUES (nummultirange(numrange(1.1, 2.2, '()')))" +== 486 +-- truncate_limit: 100 +INSERT INTO nummultirange_test2 VALUES('{}') +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO nummultirange_test2 VALUES ('{}')" +== 487 +-- truncate_limit: 100 +select * from nummultirange_test2 where nmr = '{}' +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test2 WHERE nmr = '{}'" +== 488 +-- truncate_limit: 100 +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.2)) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test2 WHERE nmr = nummultirange(numrange(1.1, 2.2))" +== 489 +-- truncate_limit: 100 +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.3)) +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nmr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test2 WHERE nmr = nummultirange(numrange(1.1, 2.3))" +== 490 +-- truncate_limit: 100 +set enable_nestloop=t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO t" +== 491 +-- truncate_limit: 100 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO f" +== 492 +-- truncate_limit: 100 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO f" +== 493 +-- truncate_limit: 100 +select * from nummultirange_test natural join nummultirange_test2 order by nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test NATURAL JOIN nummultirange_test2 ORDER BY nmr" +== 494 +-- truncate_limit: 100 +set enable_nestloop=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO f" +== 495 +-- truncate_limit: 100 +set enable_hashjoin=t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO t" +== 496 +-- truncate_limit: 100 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO f" +== 497 +-- truncate_limit: 100 +select * from nummultirange_test natural join nummultirange_test2 order by nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test NATURAL JOIN nummultirange_test2 ORDER BY nmr" +== 498 +-- truncate_limit: 100 +set enable_nestloop=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO f" +== 499 +-- truncate_limit: 100 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO f" +== 500 +-- truncate_limit: 100 +set enable_mergejoin=t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO t" +== 501 +-- truncate_limit: 100 +select * from nummultirange_test natural join nummultirange_test2 order by nmr +-- +TABLE: name="nummultirange_test" schema="" table="nummultirange_test" ctx=Select +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nummultirange_test NATURAL JOIN nummultirange_test2 ORDER BY nmr" +== 502 +-- truncate_limit: 100 +set enable_nestloop to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO DEFAULT" +== 503 +-- truncate_limit: 100 +set enable_hashjoin to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO DEFAULT" +== 504 +-- truncate_limit: 100 +set enable_mergejoin to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO DEFAULT" +== 505 +-- truncate_limit: 100 +DROP TABLE nummultirange_test2 +-- +TABLE: name="nummultirange_test2" schema="" table="nummultirange_test2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE nummultirange_test2" +== 506 +-- truncate_limit: 100 +|-- +-- Test user-defined multirange of floats +|-- + +select '{[123.001, 5.e9)}'::float8multirange @> 888.882::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[123.001, 5.e9)}'::float8multirange @> (888.882)::float8" +== 507 +-- truncate_limit: 100 +create table float8multirange_test(f8mr float8multirange, i int) +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE float8multirange_test (f8mr float8multirange, i int)" +== 508 +-- truncate_limit: 100 +insert into float8multirange_test values(float8multirange(float8range(-100.00007, '1.111113e9')), 42) +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=DML +FUNCTION: name="float8multirange" function="float8multirange" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8multirange_test VALUES (...)" +== 509 +-- truncate_limit: 100 +select * from float8multirange_test +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float8multirange_test" +== 510 +-- truncate_limit: 100 +drop table float8multirange_test +-- +TABLE: name="float8multirange_test" schema="" table="float8multirange_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE float8multirange_test" +== 511 +-- truncate_limit: 100 +|-- +-- Test multirange types over domains +|-- + +create domain mydomain as int4 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN mydomain AS int4" +== 512 +-- truncate_limit: 100 +create type mydomainrange as range(subtype=mydomain) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE mydomainrange AS RANGE (subtype = mydomain)" +== 513 +-- truncate_limit: 100 +select '{[4,50)}'::mydomainmultirange @> 7::mydomain +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[4,50)}'::mydomainmultirange @> 7::mydomain" +== 514 +-- truncate_limit: 100 +drop domain mydomain cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN mydomain CASCADE" +== 515 +-- truncate_limit: 100 +|-- +-- Test domains over multirange types +|-- + +create domain restrictedmultirange as int4multirange check (upper(value) < 10) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN restrictedmultirange AS int4multirange CHECK (upper(value) < 10)" +== 516 +-- truncate_limit: 100 +select '{[4,5)}'::restrictedmultirange @> 7 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[4,5)}'::restrictedmultirange @> 7" +== 517 +-- truncate_limit: 100 +select '{[4,50)}'::restrictedmultirange @> 7 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{[4,50)}'::restrictedmultirange @> 7" +== 518 +-- truncate_limit: 100 +-- should fail +drop domain restrictedmultirange +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN restrictedmultirange" +== 519 +-- truncate_limit: 100 +--- +-- Check automatic naming of multiranges +--- + +create type intr as range(subtype=int) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE intr AS RANGE (subtype = int)" +== 520 +-- truncate_limit: 100 +select intr_multirange(intr(1,10)) +-- +FUNCTION: name="intr_multirange" function="intr_multirange" schema="" ctx=Call +FUNCTION: name="intr" function="intr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT intr_multirange(intr(1, 10))" +== 521 +-- truncate_limit: 100 +drop type intr +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE intr" +== 522 +-- truncate_limit: 100 +create type intmultirange as (x int, y int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE intmultirange AS (x int, y int)" +== 523 +-- truncate_limit: 100 +create type intrange as range(subtype=int) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE intrange AS RANGE (subtype = int)" +== 524 +-- truncate_limit: 100 +-- should fail +drop type intmultirange +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE intmultirange" +== 525 +-- truncate_limit: 100 +create type intr_multirange as (x int, y int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE intr_multirange AS (x int, y int)" +== 526 +-- truncate_limit: 100 +create type intr as range(subtype=int) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE intr AS RANGE (subtype = int)" +== 527 +-- truncate_limit: 100 +-- should fail +drop type intr_multirange +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE intr_multirange" +== 528 +-- truncate_limit: 100 +|-- +-- Test multiple multirange types over the same subtype and manual naming of +-- the multirange type. +|-- + +-- should fail +create type textrange1 as range(subtype=text, multirange_type_name=int, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange1 AS RANGE (subtype = text, multirange_type_name = int, \"collation\" = \"C\")" +== 529 +-- truncate_limit: 100 +-- should pass +create type textrange1 as range(subtype=text, multirange_type_name=multirange_of_text, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange1 AS RANGE (subtype = text, multirange_type_name = multirange_of_text, \"coll..." +== 530 +-- truncate_limit: 100 +-- should pass, because existing _textrange1 is automatically renamed +create type textrange2 as range(subtype=text, multirange_type_name=_textrange1, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange2 AS RANGE (subtype = text, multirange_type_name = _textrange1, \"collation\" ..." +== 531 +-- truncate_limit: 100 +select multirange_of_text(textrange2('a','Z')) +-- +FUNCTION: name="multirange_of_text" function="multirange_of_text" schema="" ctx=Call +FUNCTION: name="textrange2" function="textrange2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT multirange_of_text(textrange2('a', 'Z'))" +== 532 +-- truncate_limit: 100 +-- should fail +select multirange_of_text(textrange1('a','Z')) @> 'b'::text +-- +FUNCTION: name="multirange_of_text" function="multirange_of_text" schema="" ctx=Call +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT multirange_of_text(textrange1('a', 'Z')) @> 'b'::text" +== 533 +-- truncate_limit: 100 +select unnest(multirange_of_text(textrange1('a','b'), textrange1('d','e'))) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="multirange_of_text" function="multirange_of_text" schema="" ctx=Call +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(multirange_of_text(textrange1('a', 'b'), textrange1('d', 'e')))" +== 534 +-- truncate_limit: 100 +select _textrange1(textrange2('a','z')) @> 'b'::text +-- +FUNCTION: name="_textrange1" function="_textrange1" schema="" ctx=Call +FUNCTION: name="textrange2" function="textrange2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT _textrange1(textrange2('a', 'z')) @> 'b'::text" +== 535 +-- truncate_limit: 100 +drop type textrange1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange1" +== 536 +-- truncate_limit: 100 +drop type textrange2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange2" +== 537 +-- truncate_limit: 100 +|-- +-- Multiranges don't have their own ownership or permissions. +|-- +create type textrange1 as range(subtype=text, multirange_type_name=multitextrange1, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange1 AS RANGE (subtype = text, multirange_type_name = multitextrange1, \"collati..." +== 538 +-- truncate_limit: 100 +create role regress_multirange_owner +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_multirange_owner" +== 539 +-- truncate_limit: 100 +alter type multitextrange1 owner to regress_multirange_owner +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TYPE multitextrange1 OWNER TO regress_multirange_owner" +== 540 +-- truncate_limit: 100 +-- fail +alter type textrange1 owner to regress_multirange_owner +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TYPE textrange1 OWNER TO regress_multirange_owner" +== 541 +-- truncate_limit: 100 +set role regress_multirange_owner +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_multirange_owner" +== 542 +-- truncate_limit: 100 +revoke usage on type multitextrange1 from public +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE multitextrange1 FROM public" +== 543 +-- truncate_limit: 100 +-- fail +revoke usage on type textrange1 from public +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE textrange1 FROM public" +== 544 +-- truncate_limit: 100 +create temp table test1(f1 multitextrange1[]) +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test1 (f1 multitextrange1[])" +== 545 +-- truncate_limit: 100 +revoke usage on type textrange1 from regress_multirange_owner +-- +STMT: GrantStmt +TRUNCATED: "REVOKE usage ON TYPE textrange1 FROM regress_multirange_owner" +== 546 +-- truncate_limit: 100 +create temp table test2(f1 multitextrange1[]) +-- +TABLE: name="test2" schema="" table="test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test2 (f1 multitextrange1[])" +== 547 +-- truncate_limit: 100 +-- fail + +drop table test1 +-- +TABLE: name="test1" schema="" table="test1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test1" +== 548 +-- truncate_limit: 100 +drop type textrange1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange1" +== 549 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 550 +-- truncate_limit: 100 +drop role regress_multirange_owner +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_multirange_owner" +== 551 +-- truncate_limit: 100 +|-- +-- Test polymorphic type system +|-- + +create function anyarray_anymultirange_func(a anyarray, r anymultirange) + returns anyelement as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyarray_anymultirange_func(a anyarray, r anymultirange) RETURNS anyelement AS $$..." +== 552 +-- truncate_limit: 100 +select anyarray_anymultirange_func(ARRAY[1,2], int4multirange(int4range(10,20))) +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anyarray_anymultirange_func(ARRAY[1, 2], int4multirange(int4range(10, 20)))" +== 553 +-- truncate_limit: 100 +-- should fail +select anyarray_anymultirange_func(ARRAY[1,2], nummultirange(numrange(10,20))) +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anyarray_anymultirange_func(ARRAY[1, 2], nummultirange(numrange(10, 20)))" +== 554 +-- truncate_limit: 100 +drop function anyarray_anymultirange_func(anyarray, anymultirange) +-- +FUNCTION: name="anyarray_anymultirange_func" function="anyarray_anymultirange_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyarray_anymultirange_func(anyarray, anymultirange)" +== 555 +-- truncate_limit: 100 +-- should fail +create function bogus_func(anyelement) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bogus_func(anyelement) RETURNS anymultirange AS $$select int4multirange(int4range..." +== 556 +-- truncate_limit: 100 +-- should fail +create function bogus_func(int) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bogus_func(int) RETURNS anymultirange AS $$select int4multirange(int4range(1,10))..." +== 557 +-- truncate_limit: 100 +create function range_add_bounds(anymultirange) + returns anyelement as 'select lower($1) + upper($1)' language sql +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION range_add_bounds(anymultirange) RETURNS anyelement AS $$select lower($1) + upper(..." +== 558 +-- truncate_limit: 100 +select range_add_bounds(int4multirange(int4range(1, 17))) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_add_bounds(int4multirange(int4range(1, 17)))" +== 559 +-- truncate_limit: 100 +select range_add_bounds(nummultirange(numrange(1.0001, 123.123))) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_add_bounds(nummultirange(numrange(1.0001, 123.123)))" +== 560 +-- truncate_limit: 100 +create function multirangetypes_sql(q anymultirange, b anyarray, out c anyelement) + as $$ select upper($1) + $2[1] $$ + language sql +-- +FUNCTION: name="multirangetypes_sql" function="multirangetypes_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION multirangetypes_sql(q anymultirange, b anyarray, OUT c anyelement) AS $$ select u..." +== 561 +-- truncate_limit: 100 +select multirangetypes_sql(int4multirange(int4range(1,10)), ARRAY[2,20]) +-- +FUNCTION: name="multirangetypes_sql" function="multirangetypes_sql" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT multirangetypes_sql(int4multirange(int4range(1, 10)), ARRAY[2, 20])" +== 562 +-- truncate_limit: 100 +select multirangetypes_sql(nummultirange(numrange(1,10)), ARRAY[2,20]) +-- +FUNCTION: name="multirangetypes_sql" function="multirangetypes_sql" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT multirangetypes_sql(nummultirange(numrange(1, 10)), ARRAY[2, 20])" +== 563 +-- truncate_limit: 100 +-- match failure + +create function anycompatiblearray_anycompatiblemultirange_func(a anycompatiblearray, mr anycompatiblemultirange) + returns anycompatible as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anycompatiblearray_anycompatiblemultirange_func(a anycompatiblearray, mr anycompa..." +== 564 +-- truncate_limit: 100 +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anycompatiblearray_anycompatiblemultirange_func(ARRAY[1, 2], multirange(int4range(10, 20)))" +== 565 +-- truncate_limit: 100 +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(numrange(10,20))) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anycompatiblearray_anycompatiblemultirange_func(ARRAY[1, 2], multirange(numrange(10, 20)))" +== 566 +-- truncate_limit: 100 +-- should fail +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1.1,2], multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anycompatiblearray_anycompatiblemultirange_func(ARRAY[1.1, 2], multirange(int4range(10, 20)))" +== 567 +-- truncate_limit: 100 +drop function anycompatiblearray_anycompatiblemultirange_func(anycompatiblearray, anycompatiblemultirange) +-- +FUNCTION: name="anycompatiblearray_anycompatiblemultirange_func" function="anycompatiblearray_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anycompatiblearray_anycompatiblemultirange_func(anycompatiblearray, anycompatiblemu..." +== 568 +-- truncate_limit: 100 +create function anycompatiblerange_anycompatiblemultirange_func(r anycompatiblerange, mr anycompatiblemultirange) + returns anycompatible as 'select lower($1) + lower($2);' language sql +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anycompatiblerange_anycompatiblemultirange_func(r anycompatiblerange, mr anycompa..." +== 569 +-- truncate_limit: 100 +select anycompatiblerange_anycompatiblemultirange_func(int4range(1,2), multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 570 +-- truncate_limit: 100 +-- should fail +select anycompatiblerange_anycompatiblemultirange_func(numrange(1,2), multirange(int4range(10,20))) +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 571 +-- truncate_limit: 100 +drop function anycompatiblerange_anycompatiblemultirange_func(anycompatiblerange, anycompatiblemultirange) +-- +FUNCTION: name="anycompatiblerange_anycompatiblemultirange_func" function="anycompatiblerange_anycompatiblemultirange_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anycompatiblerange_anycompatiblemultirange_func(anycompatiblerange, anycompatiblemu..." +== 572 +-- truncate_limit: 100 +-- should fail +create function bogus_func(anycompatible) + returns anycompatiblerange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bogus_func(anycompatible) RETURNS anycompatiblerange AS $$select int4range(1,10)$..." +== 573 +-- truncate_limit: 100 +|-- +-- Arrays of multiranges +|-- + +select ARRAY[nummultirange(numrange(1.1, 1.2)), nummultirange(numrange(12.3, 155.5))] +-- +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="nummultirange" function="nummultirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[nummultirange(numrange(1.1, 1.2)), nummultirange(numrange(12.3, 155.5))]" +== 574 +-- truncate_limit: 100 +create table i8mr_array (f1 int, f2 int8multirange[]) +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE i8mr_array (f1 int, f2 int8multirange[])" +== 575 +-- truncate_limit: 100 +insert into i8mr_array values (42, array[int8multirange(int8range(1,10)), int8multirange(int8range(2,20))]) +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=DML +FUNCTION: name="int8multirange" function="int8multirange" schema="" ctx=Call +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +FUNCTION: name="int8multirange" function="int8multirange" schema="" ctx=Call +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO i8mr_array VALUES (...)" +== 576 +-- truncate_limit: 100 +select * from i8mr_array +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM i8mr_array" +== 577 +-- truncate_limit: 100 +drop table i8mr_array +-- +TABLE: name="i8mr_array" schema="" table="i8mr_array" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE i8mr_array" +== 578 +-- truncate_limit: 100 +|-- +-- Multiranges of arrays +|-- + +select arraymultirange(arrayrange(ARRAY[1,2], ARRAY[2,1])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT arraymultirange(arrayrange(ARRAY[1, 2], ARRAY[2, 1]))" +== 579 +-- truncate_limit: 100 +select arraymultirange(arrayrange(ARRAY[2,1], ARRAY[1,2])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT arraymultirange(arrayrange(ARRAY[2, 1], ARRAY[1, 2]))" +== 580 +-- truncate_limit: 100 +-- fail + +select array[1,1] <@ arraymultirange(arrayrange(array[1,2], array[2,1])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 1] <@ arraymultirange(arrayrange(ARRAY[1, 2], ARRAY[2, 1]))" +== 581 +-- truncate_limit: 100 +select array[1,3] <@ arraymultirange(arrayrange(array[1,2], array[2,1])) +-- +FUNCTION: name="arraymultirange" function="arraymultirange" schema="" ctx=Call +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 3] <@ arraymultirange(arrayrange(ARRAY[1, 2], ARRAY[2, 1]))" +== 582 +-- truncate_limit: 100 +|-- +-- Ranges of composites +|-- + +create type two_ints as (a int, b int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE two_ints AS (a int, b int)" +== 583 +-- truncate_limit: 100 +create type two_ints_range as range (subtype = two_ints) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE two_ints_range AS RANGE (subtype = two_ints)" +== 584 +-- truncate_limit: 100 +-- with debug_parallel_query on, this exercises tqueue.c's range remapping +select *, row_to_json(upper(t)) as u from + (values (two_ints_multirange(two_ints_range(row(1,2), row(3,4)))), + (two_ints_multirange(two_ints_range(row(5,6), row(7,8))))) v(t) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="two_ints_multirange" function="two_ints_multirange" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +FUNCTION: name="two_ints_multirange" function="two_ints_multirange" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, row_to_json(upper(t)) AS u FROM (VALUES (...)) v(t)" +== 585 +-- truncate_limit: 100 +drop type two_ints cascade +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE two_ints CASCADE" +== 586 +-- truncate_limit: 100 +|-- +-- Check behavior when subtype lacks a hash function +|-- + +set enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 587 +-- truncate_limit: 100 +-- try to make it pick a hash setop implementation + +select '{(01,10)}'::varbitmultirange except select '{(10,11)}'::varbitmultirange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{(01,10)}'::varbitmultirange EXCEPT SELECT '{(10,11)}'::varbitmultirange" +== 588 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 589 +-- truncate_limit: 100 +|-- +-- OUT/INOUT/TABLE functions +|-- + +-- infer anymultirange from anymultirange +create function mr_outparam_succeed(i anymultirange, out r anymultirange, out t text) + as $$ select $1, 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed" function="mr_outparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_outparam_succeed(i anymultirange, OUT r anymultirange, OUT t text) AS $$ selec..." +== 590 +-- truncate_limit: 100 +select * from mr_outparam_succeed(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_outparam_succeed" function="mr_outparam_succeed" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mr_outparam_succeed(int4multirange(int4range(1, 2)))" +== 591 +-- truncate_limit: 100 +-- infer anyarray from anymultirange +create function mr_outparam_succeed2(i anymultirange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed2" function="mr_outparam_succeed2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_outparam_succeed2(i anymultirange, OUT r anyarray, OUT t text) AS $$ select AR..." +== 592 +-- truncate_limit: 100 +select * from mr_outparam_succeed2(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_outparam_succeed2" function="mr_outparam_succeed2" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mr_outparam_succeed2(int4multirange(int4range(1, 2)))" +== 593 +-- truncate_limit: 100 +-- infer anyrange from anymultirange +create function mr_outparam_succeed3(i anymultirange, out r anyrange, out t text) + as $$ select range_merge($1), 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed3" function="mr_outparam_succeed3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_outparam_succeed3(i anymultirange, OUT r anyrange, OUT t text) AS $$ select ra..." +== 594 +-- truncate_limit: 100 +select * from mr_outparam_succeed3(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_outparam_succeed3" function="mr_outparam_succeed3" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mr_outparam_succeed3(int4multirange(int4range(1, 2)))" +== 595 +-- truncate_limit: 100 +-- infer anymultirange from anyrange +create function mr_outparam_succeed4(i anyrange, out r anymultirange, out t text) + as $$ select multirange($1), 'foo'::text $$ language sql +-- +FUNCTION: name="mr_outparam_succeed4" function="mr_outparam_succeed4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_outparam_succeed4(i anyrange, OUT r anymultirange, OUT t text) AS $$ select mu..." +== 596 +-- truncate_limit: 100 +select * from mr_outparam_succeed4(int4range(1,2)) +-- +FUNCTION: name="mr_outparam_succeed4" function="mr_outparam_succeed4" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mr_outparam_succeed4(int4range(1, 2))" +== 597 +-- truncate_limit: 100 +-- infer anyelement from anymultirange +create function mr_inoutparam_succeed(out i anyelement, inout r anymultirange) + as $$ select upper($1), $1 $$ language sql +-- +FUNCTION: name="mr_inoutparam_succeed" function="mr_inoutparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_inoutparam_succeed(OUT i anyelement, INOUT r anymultirange) AS $$ select upper..." +== 598 +-- truncate_limit: 100 +select * from mr_inoutparam_succeed(int4multirange(int4range(1,2))) +-- +FUNCTION: name="mr_inoutparam_succeed" function="mr_inoutparam_succeed" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mr_inoutparam_succeed(int4multirange(int4range(1, 2)))" +== 599 +-- truncate_limit: 100 +-- infer anyelement+anymultirange from anyelement+anymultirange +create function mr_table_succeed(i anyelement, r anymultirange) returns table(i anyelement, r anymultirange) + as $$ select $1, $2 $$ language sql +-- +FUNCTION: name="mr_table_succeed" function="mr_table_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_table_succeed(i anyelement, r anymultirange) RETURNS TABLE (i anyelement, r an..." +== 600 +-- truncate_limit: 100 +select * from mr_table_succeed(123, int4multirange(int4range(1,11))) +-- +FUNCTION: name="mr_table_succeed" function="mr_table_succeed" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM mr_table_succeed(123, int4multirange(int4range(1, 11)))" +== 601 +-- truncate_limit: 100 +-- use anymultirange in plpgsql +create function mr_polymorphic(i anyrange) returns anymultirange + as $$ begin return multirange($1); end; $$ language plpgsql +-- +FUNCTION: name="mr_polymorphic" function="mr_polymorphic" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_polymorphic(i anyrange) RETURNS anymultirange AS $$ begin return multirange($1..." +== 602 +-- truncate_limit: 100 +select mr_polymorphic(int4range(1, 4)) +-- +FUNCTION: name="mr_polymorphic" function="mr_polymorphic" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mr_polymorphic(int4range(1, 4))" +== 603 +-- truncate_limit: 100 +-- should fail +create function mr_outparam_fail(i anyelement, out r anymultirange, out t text) + as $$ select '[1,10]', 'foo' $$ language sql +-- +FUNCTION: name="mr_outparam_fail" function="mr_outparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_outparam_fail(i anyelement, OUT r anymultirange, OUT t text) AS $$ select '[1,..." +== 604 +-- truncate_limit: 100 +--should fail +create function mr_inoutparam_fail(inout i anyelement, out r anymultirange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="mr_inoutparam_fail" function="mr_inoutparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_inoutparam_fail(INOUT i anyelement, OUT r anymultirange) AS $$ select $1, '[1,..." +== 605 +-- truncate_limit: 100 +--should fail +create function mr_table_fail(i anyelement) returns table(i anyelement, r anymultirange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="mr_table_fail" function="mr_table_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mr_table_fail(i anyelement) RETURNS TABLE (i anyelement, r anymultirange) AS $$ s..." diff --git a/parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json new file mode 100644 index 0000000..4739b17 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json @@ -0,0 +1,15 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/mvcc.test b/parser/testdata/summary_truncate/postgres_regress/mvcc.test new file mode 100644 index 0000000..600c577 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/mvcc.test @@ -0,0 +1,100 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Verify that index scans encountering dead rows produced by an +-- aborted subtransaction of the current transaction can utilize the +-- kill_prior_tuple optimization +|-- +-- NB: The table size is currently *not* expected to stay the same, we +-- don't have logic to trigger opportunistic pruning in cases like +-- this. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 002 +-- truncate_limit: 100 +SET LOCAL enable_seqscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO FALSE" +== 003 +-- truncate_limit: 100 +SET LOCAL enable_indexonlyscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexonlyscan TO FALSE" +== 004 +-- truncate_limit: 100 +SET LOCAL enable_bitmapscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_bitmapscan TO FALSE" +== 005 +-- truncate_limit: 100 +-- Can't easily use a unique index, since dead tuples can be found +-- independent of the kill_prior_tuples optimization. +CREATE TABLE clean_aborted_self(key int, data text) +-- +TABLE: name="clean_aborted_self" schema="" table="clean_aborted_self" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE clean_aborted_self (key int, data text)" +== 006 +-- truncate_limit: 100 +CREATE INDEX clean_aborted_self_key ON clean_aborted_self(key) +-- +TABLE: name="clean_aborted_self" schema="" table="clean_aborted_self" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX clean_aborted_self_key ON clean_aborted_self USING btree (key)" +== 007 +-- truncate_limit: 100 +INSERT INTO clean_aborted_self (key, data) VALUES (-1, 'just to allocate metapage') +-- +TABLE: name="clean_aborted_self" schema="" table="clean_aborted_self" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO clean_aborted_self (key, data) VALUES (-1, 'just to allocate metapage')" +== 008 +-- truncate_limit: 100 +-- save index size from before the changes, for comparison +SELECT pg_relation_size('clean_aborted_self_key') AS clean_aborted_self_key_before +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_relation_size('clean_aborted_self_key') AS clean_aborted_self_key_before" +== 009 +-- truncate_limit: 100 +DO $$ +BEGIN + -- iterate often enough to see index growth even on larger-than-default page sizes + FOR i IN 1..100 LOOP + BEGIN + -- perform index scan over all the inserted keys to get them to be seen as dead + IF EXISTS(SELECT * FROM clean_aborted_self WHERE key > 0 AND key < 100) THEN + RAISE data_corrupted USING MESSAGE = 'these rows should not exist'; + END IF; + INSERT INTO clean_aborted_self SELECT g.i, 'rolling back in a sec' FROM generate_series(1, 100) g(i); + -- just some error that's not normally thrown + RAISE reading_sql_data_not_permitted USING MESSAGE = 'round and round again'; + EXCEPTION WHEN reading_sql_data_not_permitted THEN END; + END LOOP; +END;$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n -- iterate often enough to see index growth even on larger-than-default page size..." +== 010 +-- truncate_limit: 100 +-- show sizes only if they differ +SELECT :clean_aborted_self_key_before AS size_before, pg_relation_size('clean_aborted_self_key') size_after +WHERE :clean_aborted_self_key_before != pg_relation_size('clean_aborted_self_key') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 011 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/name.metadata.json b/parser/testdata/summary_truncate/postgres_regress/name.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/name.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/name.test b/parser/testdata/summary_truncate/postgres_regress/name.test new file mode 100644 index 0000000..2caa6bc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/name.test @@ -0,0 +1,330 @@ +== 001 +-- truncate_limit: 100 +|-- +-- NAME +-- all inputs are silently truncated at NAMEDATALEN-1 (63) characters +|-- + +-- fixed-length by reference +SELECT name 'name string' = name 'name string' AS "True" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'name string'::name = 'name string'::name AS \"True\"" +== 002 +-- truncate_limit: 100 +SELECT name 'name string' = name 'name string ' AS "False" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'name string'::name = 'name string '::name AS \"False\"" +== 003 +-- truncate_limit: 100 +|-- +|-- +|-- + +CREATE TABLE NAME_TBL(f1 name) +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE name_tbl (f1 name)" +== 004 +-- truncate_limit: 100 +INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO name_tbl (f1) VALUES (...)" +== 005 +-- truncate_limit: 100 +INSERT INTO NAME_TBL(f1) VALUES ('1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO name_tbl (f1) VALUES (...)" +== 006 +-- truncate_limit: 100 +INSERT INTO NAME_TBL(f1) VALUES ('asdfghjkl;') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO name_tbl (f1) VALUES ('asdfghjkl;')" +== 007 +-- truncate_limit: 100 +INSERT INTO NAME_TBL(f1) VALUES ('343f%2a') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO name_tbl (f1) VALUES ('343f%2a')" +== 008 +-- truncate_limit: 100 +INSERT INTO NAME_TBL(f1) VALUES ('d34aaasdf') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO name_tbl (f1) VALUES ('d34aaasdf')" +== 009 +-- truncate_limit: 100 +INSERT INTO NAME_TBL(f1) VALUES ('') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO name_tbl (f1) VALUES ('')" +== 010 +-- truncate_limit: 100 +INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ') +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO name_tbl (f1) VALUES (...)" +== 011 +-- truncate_limit: 100 +SELECT * FROM NAME_TBL +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM name_tbl" +== 012 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 <> '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE ..." +== 013 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE ..." +== 014 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 < '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE ..." +== 015 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 <= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE ..." +== 016 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 > '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE ..." +== 017 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 >= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE ..." +== 018 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE c.f1 ~ '.*'" +== 019 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 !~ '.*' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE c.f1 !~ '.*'" +== 020 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '[0-9]' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE c.f1 ~ '[0-9]'" +== 021 +-- truncate_limit: 100 +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*asdf.*' +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=Select +ALIAS: "c"="name_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.f1 FROM name_tbl c WHERE c.f1 ~ '.*asdf.*'" +== 022 +-- truncate_limit: 100 +DROP TABLE NAME_TBL +-- +TABLE: name="name_tbl" schema="" table="name_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE name_tbl" +== 023 +-- truncate_limit: 100 +DO $$ +DECLARE r text[]; +BEGIN + r := parse_ident('Schemax.Tabley'); + RAISE NOTICE '%', format('%I.%I', r[1], r[2]); + r := parse_ident('"SchemaX"."TableY"'); + RAISE NOTICE '%', format('%I.%I', r[1], r[2]); +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE r text[];\nBEGIN\n r := parse_ident('Schemax.Tabley');\n RAISE NOTICE '%', format('%..." +== 024 +-- truncate_limit: 100 +SELECT parse_ident('foo.boo') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('foo.boo')" +== 025 +-- truncate_limit: 100 +SELECT parse_ident('foo.boo[]') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('foo.boo[]')" +== 026 +-- truncate_limit: 100 +-- should fail +SELECT parse_ident('foo.boo[]', strict => false) +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('foo.boo[]', strict := false)" +== 027 +-- truncate_limit: 100 +-- ok + +-- should fail +SELECT parse_ident(' ') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident(' ')" +== 028 +-- truncate_limit: 100 +SELECT parse_ident(' .aaa') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident(' .aaa')" +== 029 +-- truncate_limit: 100 +SELECT parse_ident(' aaa . ') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident(' aaa . ')" +== 030 +-- truncate_limit: 100 +SELECT parse_ident('aaa.a%b') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('aaa.a%b')" +== 031 +-- truncate_limit: 100 +SELECT parse_ident(E'X\rXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('X\rXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')" +== 032 +-- truncate_limit: 100 +SELECT length(a[1]), length(a[2]) from parse_ident('"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy') as a +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM parse_ident('\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..." +== 033 +-- truncate_limit: 100 +SELECT parse_ident(' first . " second " ." third ". " ' || repeat('x',66) || '"') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident((' first . \" second \" .\" third \". \" ' || repeat('x', 66)) || '\"')" +== 034 +-- truncate_limit: 100 +SELECT parse_ident(' first . " second " ." third ". " ' || repeat('x',66) || '"')::name[] +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident((' first . \" second \" .\" third \". \" ' || repeat('x', 66)) || '\"')::name[]" +== 035 +-- truncate_limit: 100 +SELECT parse_ident(E'"c".X XXXX\002XXXXXX') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('\"c\".X XXXX\x02XXXXXX')" +== 036 +-- truncate_limit: 100 +SELECT parse_ident('1020') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('1020')" +== 037 +-- truncate_limit: 100 +SELECT parse_ident('10.20') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('10.20')" +== 038 +-- truncate_limit: 100 +SELECT parse_ident('.') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('.')" +== 039 +-- truncate_limit: 100 +SELECT parse_ident('.1020') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('.1020')" +== 040 +-- truncate_limit: 100 +SELECT parse_ident('xxx.1020') +-- +FUNCTION: name="parse_ident" function="parse_ident" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT parse_ident('xxx.1020')" diff --git a/parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json b/parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json new file mode 100644 index 0000000..6e8763d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json @@ -0,0 +1,46 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/namespace.test b/parser/testdata/summary_truncate/postgres_regress/namespace.test new file mode 100644 index 0000000..aa02241 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/namespace.test @@ -0,0 +1,332 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Regression tests for schemas (namespaces) +|-- + +-- set the whitespace-only search_path to test that the +-- GUC list syntax is preserved during a schema creation +SELECT pg_catalog.set_config('search_path', ' ', false) +-- +FUNCTION: name="pg_catalog.set_config" function="set_config" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.set_config('search_path', ' ', false)" +== 002 +-- truncate_limit: 100 +CREATE SCHEMA test_ns_schema_1 + CREATE UNIQUE INDEX abc_a_idx ON abc (a) + + CREATE VIEW abc_view AS + SELECT a+1 AS a, b+1 AS b FROM abc + + CREATE TABLE abc ( + a serial, + b int UNIQUE + ) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_ns_schema_1 CREATE UNIQUE INDEX abc_a_idx ON abc USING btree (a) CREATE VIEW a..." +== 003 +-- truncate_limit: 100 +-- verify that the correct search_path restored on abort +SET search_path to public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO public" +== 004 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 005 +-- truncate_limit: 100 +SET search_path to public, test_ns_schema_1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO public, test_ns_schema_1" +== 006 +-- truncate_limit: 100 +CREATE SCHEMA test_ns_schema_2 + CREATE VIEW abc_view AS SELECT c FROM abc +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_ns_schema_2 CREATE VIEW abc_view AS SELECT c FROM abc" +== 007 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 008 +-- truncate_limit: 100 +SHOW search_path +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW search_path" +== 009 +-- truncate_limit: 100 +-- verify that the correct search_path preserved +-- after creating the schema and on commit +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 010 +-- truncate_limit: 100 +SET search_path to public, test_ns_schema_1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO public, test_ns_schema_1" +== 011 +-- truncate_limit: 100 +CREATE SCHEMA test_ns_schema_2 + CREATE VIEW abc_view AS SELECT a FROM abc +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_ns_schema_2 CREATE VIEW abc_view AS SELECT a FROM abc" +== 012 +-- truncate_limit: 100 +SHOW search_path +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW search_path" +== 013 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 014 +-- truncate_limit: 100 +SHOW search_path +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW search_path" +== 015 +-- truncate_limit: 100 +DROP SCHEMA test_ns_schema_2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_ns_schema_2 CASCADE" +== 016 +-- truncate_limit: 100 +-- verify that the objects were created +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE ...)" +== 017 +-- truncate_limit: 100 +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO test_ns_schema_1.abc DEFAULT VALUES" +== 018 +-- truncate_limit: 100 +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO test_ns_schema_1.abc DEFAULT VALUES" +== 019 +-- truncate_limit: 100 +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO test_ns_schema_1.abc DEFAULT VALUES" +== 020 +-- truncate_limit: 100 +SELECT * FROM test_ns_schema_1.abc +-- +TABLE: name="test_ns_schema_1.abc" schema="test_ns_schema_1" table="abc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_ns_schema_1.abc" +== 021 +-- truncate_limit: 100 +SELECT * FROM test_ns_schema_1.abc_view +-- +TABLE: name="test_ns_schema_1.abc_view" schema="test_ns_schema_1" table="abc_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_ns_schema_1.abc_view" +== 022 +-- truncate_limit: 100 +ALTER SCHEMA test_ns_schema_1 RENAME TO test_ns_schema_renamed +-- +STMT: RenameStmt +TRUNCATED: "ALTER SCHEMA test_ns_schema_1 RENAME TO test_ns_schema_renamed" +== 023 +-- truncate_limit: 100 +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE ...)" +== 024 +-- truncate_limit: 100 +-- test IF NOT EXISTS cases +CREATE SCHEMA test_ns_schema_renamed +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_ns_schema_renamed" +== 025 +-- truncate_limit: 100 +-- fail, already exists +CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed" +== 026 +-- truncate_limit: 100 +-- ok with notice +CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed -- fail, disallowed + CREATE TABLE abc ( + a serial, + b int UNIQUE + ) +-- +ERROR: CREATE SCHEMA IF NOT EXISTS cannot include schema elements +CURSORPOS: 97 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 027 +-- truncate_limit: 100 +DROP SCHEMA test_ns_schema_renamed CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_ns_schema_renamed CASCADE" +== 028 +-- truncate_limit: 100 +-- verify that the objects were dropped +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_renamed') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relnamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE ...)" +== 029 +-- truncate_limit: 100 +|-- +-- Verify that search_path is set to a safe value during maintenance +-- commands. +|-- + +CREATE SCHEMA test_maint_search_path +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA test_maint_search_path" +== 030 +-- truncate_limit: 100 +SET search_path = test_maint_search_path +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO test_maint_search_path" +== 031 +-- truncate_limit: 100 +CREATE FUNCTION fn(INT) RETURNS INT IMMUTABLE LANGUAGE plpgsql AS $$ + BEGIN + RAISE NOTICE 'current search_path: %', current_setting('search_path'); + RETURN $1; + END; +$$ +-- +FUNCTION: name="fn" function="fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fn(int) RETURNS int IMMUTABLE LANGUAGE plpgsql AS $$\n BEGIN\n RAISE NOTICE 'cu..." +== 032 +-- truncate_limit: 100 +CREATE TABLE test_maint(i INT) +-- +TABLE: name="test_maint" schema="" table="test_maint" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_maint (i int)" +== 033 +-- truncate_limit: 100 +INSERT INTO test_maint VALUES (1), (2) +-- +TABLE: name="test_maint" schema="" table="test_maint" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_maint VALUES (1), (2)" +== 034 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW test_maint_mv AS SELECT fn(i) FROM test_maint +-- +TABLE: name="test_maint_mv" schema="" table="test_maint_mv" ctx=DDL +TABLE: name="test_maint" schema="" table="test_maint" ctx=Select +FUNCTION: name="fn" function="fn" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW test_maint_mv AS SELECT fn(i) FROM test_maint" +== 035 +-- truncate_limit: 100 +-- the following commands should see search_path as pg_catalog, pg_temp + +CREATE INDEX test_maint_idx ON test_maint_search_path.test_maint (fn(i)) +-- +TABLE: name="test_maint_search_path.test_maint" schema="test_maint_search_path" table="test_maint" ctx=DDL +FUNCTION: name="fn" function="fn" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_maint_idx ON test_maint_search_path.test_maint USING btree (fn(i))" +== 036 +-- truncate_limit: 100 +REINDEX TABLE test_maint_search_path.test_maint +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX TABLE test_maint_search_path.test_maint" +== 037 +-- truncate_limit: 100 +ANALYZE test_maint_search_path.test_maint +-- +TABLE: name="test_maint_search_path.test_maint" schema="test_maint_search_path" table="test_maint" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE test_maint_search_path.test_maint" +== 038 +-- truncate_limit: 100 +VACUUM FULL test_maint_search_path.test_maint +-- +TABLE: name="test_maint_search_path.test_maint" schema="test_maint_search_path" table="test_maint" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) test_maint_search_path.test_maint" +== 039 +-- truncate_limit: 100 +CLUSTER test_maint_search_path.test_maint USING test_maint_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER test_maint_search_path.test_maint USING test_maint_idx" +== 040 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW test_maint_search_path.test_maint_mv +-- +TABLE: name="test_maint_search_path.test_maint_mv" schema="test_maint_search_path" table="test_maint_mv" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW test_maint_search_path.test_maint_mv" +== 041 +-- truncate_limit: 100 +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 042 +-- truncate_limit: 100 +DROP SCHEMA test_maint_search_path CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA test_maint_search_path CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json b/parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json new file mode 100644 index 0000000..e7297cf --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json @@ -0,0 +1,1022 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/numeric.test b/parser/testdata/summary_truncate/postgres_regress/numeric.test new file mode 100644 index 0000000..21f629a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/numeric.test @@ -0,0 +1,8275 @@ +== 001 +-- truncate_limit: 100 +|-- +-- NUMERIC +|-- + +CREATE TABLE num_data (id int4, val numeric(210,10)) +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_data (id int4, val numeric(210, 10))" +== 002 +-- truncate_limit: 100 +CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(210, 10))" +== 003 +-- truncate_limit: 100 +CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(210, 10))" +== 004 +-- truncate_limit: 100 +CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(210, 10))" +== 005 +-- truncate_limit: 100 +CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(210, 10))" +== 006 +-- truncate_limit: 100 +CREATE TABLE num_exp_sqrt (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_sqrt (id int4, expected numeric(210, 10))" +== 007 +-- truncate_limit: 100 +CREATE TABLE num_exp_ln (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_ln (id int4, expected numeric(210, 10))" +== 008 +-- truncate_limit: 100 +CREATE TABLE num_exp_log10 (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_log10 (id int4, expected numeric(210, 10))" +== 009 +-- truncate_limit: 100 +CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(210,10)) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(210, 10))" +== 010 +-- truncate_limit: 100 +CREATE TABLE num_result (id1 int4, id2 int4, result numeric(210,10)) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_result (id1 int4, id2 int4, result numeric(210, 10))" +== 011 +-- truncate_limit: 100 +-- ****************************** +-- * The following EXPECTED results are computed by bc(1) +-- * with a scale of 200 +-- ****************************** + +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 012 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,0,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 0, '0')" +== 013 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,0,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 0, '0')" +== 014 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 0, '0')" +== 015 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 0, 'NaN')" +== 016 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,1,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 1, '0')" +== 017 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,1,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 1, '0')" +== 018 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 1, '0')" +== 019 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 1, 'NaN')" +== 020 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,2,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 2, '-34338492.215397047')" +== 021 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,2,'34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 2, '34338492.215397047')" +== 022 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,2,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 2, '0')" +== 023 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,2,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 2, '0')" +== 024 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,3,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 3, '4.31')" +== 025 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,3,'-4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 3, '-4.31')" +== 026 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,3,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 3, '0')" +== 027 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,3,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 3, '0')" +== 028 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,4,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 4, '7799461.4119')" +== 029 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,4,'-7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 4, '-7799461.4119')" +== 030 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,4,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 4, '0')" +== 031 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,4,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 4, '0')" +== 032 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,5,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 5, '16397.038491')" +== 033 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,5,'-16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 5, '-16397.038491')" +== 034 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,5,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 5, '0')" +== 035 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,5,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 5, '0')" +== 036 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,6,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 6, '93901.57763026')" +== 037 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,6,'-93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 6, '-93901.57763026')" +== 038 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,6,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 6, '0')" +== 039 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,6,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 6, '0')" +== 040 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,7,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 7, '-83028485')" +== 041 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,7,'83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 7, '83028485')" +== 042 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,7,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 7, '0')" +== 043 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,7,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 7, '0')" +== 044 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,8,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 8, '74881')" +== 045 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,8,'-74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 8, '-74881')" +== 046 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,8,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 8, '0')" +== 047 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,8,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 8, '0')" +== 048 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,9,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 9, '-24926804.045047420')" +== 049 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,9,'24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 9, '24926804.045047420')" +== 050 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,9,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 9, '0')" +== 051 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,9,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 9, '0')" +== 052 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,0,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 0, '0')" +== 053 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,0,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 0, '0')" +== 054 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 0, '0')" +== 055 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 0, 'NaN')" +== 056 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,1,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 1, '0')" +== 057 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,1,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 1, '0')" +== 058 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 1, '0')" +== 059 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 1, 'NaN')" +== 060 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,2,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 2, '-34338492.215397047')" +== 061 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,2,'34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 2, '34338492.215397047')" +== 062 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,2,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 2, '0')" +== 063 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,2,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 2, '0')" +== 064 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,3,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 3, '4.31')" +== 065 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,3,'-4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 3, '-4.31')" +== 066 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,3,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 3, '0')" +== 067 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,3,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 3, '0')" +== 068 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,4,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 4, '7799461.4119')" +== 069 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,4,'-7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 4, '-7799461.4119')" +== 070 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,4,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 4, '0')" +== 071 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,4,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 4, '0')" +== 072 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,5,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 5, '16397.038491')" +== 073 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,5,'-16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 5, '-16397.038491')" +== 074 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,5,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 5, '0')" +== 075 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,5,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 5, '0')" +== 076 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,6,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 6, '93901.57763026')" +== 077 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,6,'-93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 6, '-93901.57763026')" +== 078 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,6,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 6, '0')" +== 079 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,6,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 6, '0')" +== 080 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,7,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 7, '-83028485')" +== 081 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,7,'83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 7, '83028485')" +== 082 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,7,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 7, '0')" +== 083 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,7,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 7, '0')" +== 084 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,8,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 8, '74881')" +== 085 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,8,'-74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 8, '-74881')" +== 086 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,8,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 8, '0')" +== 087 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,8,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 8, '0')" +== 088 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,9,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (1, 9, '-24926804.045047420')" +== 089 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,9,'24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 9, '24926804.045047420')" +== 090 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,9,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 9, '0')" +== 091 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,9,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 9, '0')" +== 092 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,0,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 0, '-34338492.215397047')" +== 093 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,0,'-34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 0, '-34338492.215397047')" +== 094 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 0, '0')" +== 095 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 0, 'NaN')" +== 096 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,1,'-34338492.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 1, '-34338492.215397047')" +== 097 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,1,'-34338492.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 1, '-34338492.215397047')" +== 098 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 1, '0')" +== 099 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 1, 'NaN')" +== 100 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,2,'-68676984.430794094') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 2, '-68676984.430794094')" +== 101 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,2,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 2, '0')" +== 102 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,2,'1179132047626883.596862135856320209') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 2, '1179132047626883.596862135856320209')" +== 103 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,2,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 2, '1.00000000000000000000')" +== 104 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,3,'-34338487.905397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 3, '-34338487.905397047')" +== 105 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,3,'-34338496.525397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 3, '-34338496.525397047')" +== 106 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,3,'-147998901.44836127257') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 3, '-147998901.44836127257')" +== 107 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,3,'-7967167.56737750510440835266') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 3, '-7967167.56737750510440835266')" +== 108 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,4,'-26539030.803497047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 4, '-26539030.803497047')" +== 109 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,4,'-42137953.627297047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 4, '-42137953.627297047')" +== 110 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,4,'-267821744976817.8111137106593') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 4, '-267821744976817.8111137106593')" +== 111 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,4,'-4.40267480046830116685') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 4, '-4.40267480046830116685')" +== 112 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,5,'-34322095.176906047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 5, '-34322095.176906047')" +== 113 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,5,'-34354889.253888047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 5, '-34354889.253888047')" +== 114 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,5,'-563049578578.769242506736077') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 5, '-563049578578.769242506736077')" +== 115 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,5,'-2094.18866914563535496429') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 5, '-2094.18866914563535496429')" +== 116 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,6,'-34244590.637766787') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 6, '-34244590.637766787')" +== 117 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,6,'-34432393.793027307') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 6, '-34432393.793027307')" +== 118 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,6,'-3224438592470.18449811926184222') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 6, '-3224438592470.18449811926184222')" +== 119 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,6,'-365.68599891479766440940') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 6, '-365.68599891479766440940')" +== 120 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,7,'-117366977.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 7, '-117366977.215397047')" +== 121 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,7,'48689992.784602953') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 7, '48689992.784602953')" +== 122 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,7,'2851072985828710.485883795') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 7, '2851072985828710.485883795')" +== 123 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,7,'.41357483778485235518') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 7, '.41357483778485235518')" +== 124 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,8,'-34263611.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 8, '-34263611.215397047')" +== 125 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,8,'-34413373.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 8, '-34413373.215397047')" +== 126 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,8,'-2571300635581.146276407') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 8, '-2571300635581.146276407')" +== 127 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,8,'-458.57416721727870888476') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 8, '-458.57416721727870888476')" +== 128 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,9,'-59265296.260444467') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (2, 9, '-59265296.260444467')" +== 129 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,9,'-9411688.170349627') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 9, '-9411688.170349627')" +== 130 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,9,'855948866655588.453741509242968740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 9, '855948866655588.453741509242968740')" +== 131 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,9,'1.37757299946438931811') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 9, '1.37757299946438931811')" +== 132 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,0,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 0, '4.31')" +== 133 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,0,'4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 0, '4.31')" +== 134 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 0, '0')" +== 135 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 0, 'NaN')" +== 136 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,1,'4.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 1, '4.31')" +== 137 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,1,'4.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 1, '4.31')" +== 138 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 1, '0')" +== 139 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 1, 'NaN')" +== 140 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,2,'-34338487.905397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 2, '-34338487.905397047')" +== 141 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,2,'34338496.525397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 2, '34338496.525397047')" +== 142 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,2,'-147998901.44836127257') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 2, '-147998901.44836127257')" +== 143 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,2,'-.00000012551512084352') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 2, '-.00000012551512084352')" +== 144 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,3,'8.62') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 3, '8.62')" +== 145 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,3,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 3, '0')" +== 146 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,3,'18.5761') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 3, '18.5761')" +== 147 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,3,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 3, '1.00000000000000000000')" +== 148 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,4,'7799465.7219') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 4, '7799465.7219')" +== 149 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,4,'-7799457.1019') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 4, '-7799457.1019')" +== 150 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,4,'33615678.685289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 4, '33615678.685289')" +== 151 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,4,'.00000055260225961552') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 4, '.00000055260225961552')" +== 152 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,5,'16401.348491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 5, '16401.348491')" +== 153 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,5,'-16392.728491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 5, '-16392.728491')" +== 154 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,5,'70671.23589621') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 5, '70671.23589621')" +== 155 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,5,'.00026285234387695504') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 5, '.00026285234387695504')" +== 156 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,6,'93905.88763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 6, '93905.88763026')" +== 157 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,6,'-93897.26763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 6, '-93897.26763026')" +== 158 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,6,'404715.7995864206') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 6, '404715.7995864206')" +== 159 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,6,'.00004589912234457595') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 6, '.00004589912234457595')" +== 160 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,7,'-83028480.69') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 7, '-83028480.69')" +== 161 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,7,'83028489.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 7, '83028489.31')" +== 162 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,7,'-357852770.35') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 7, '-357852770.35')" +== 163 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,7,'-.00000005190989574240') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 7, '-.00000005190989574240')" +== 164 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,8,'74885.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 8, '74885.31')" +== 165 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,8,'-74876.69') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 8, '-74876.69')" +== 166 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,8,'322737.11') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 8, '322737.11')" +== 167 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,8,'.00005755799201399553') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 8, '.00005755799201399553')" +== 168 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,9,'-24926799.735047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (3, 9, '-24926799.735047420')" +== 169 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,9,'24926808.355047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 9, '24926808.355047420')" +== 170 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,9,'-107434525.43415438020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 9, '-107434525.43415438020')" +== 171 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,9,'-.00000017290624149854') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 9, '-.00000017290624149854')" +== 172 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,0,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 0, '7799461.4119')" +== 173 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,0,'7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 0, '7799461.4119')" +== 174 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 0, '0')" +== 175 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 0, 'NaN')" +== 176 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,1,'7799461.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 1, '7799461.4119')" +== 177 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,1,'7799461.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 1, '7799461.4119')" +== 178 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 1, '0')" +== 179 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 1, 'NaN')" +== 180 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,2,'-26539030.803497047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 2, '-26539030.803497047')" +== 181 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,2,'42137953.627297047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 2, '42137953.627297047')" +== 182 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,2,'-267821744976817.8111137106593') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 2, '-267821744976817.8111137106593')" +== 183 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,2,'-.22713465002993920385') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 2, '-.22713465002993920385')" +== 184 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,3,'7799465.7219') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 3, '7799465.7219')" +== 185 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,3,'7799457.1019') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 3, '7799457.1019')" +== 186 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,3,'33615678.685289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 3, '33615678.685289')" +== 187 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,3,'1809619.81714617169373549883') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 3, '1809619.81714617169373549883')" +== 188 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,4,'15598922.8238') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 4, '15598922.8238')" +== 189 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,4,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 4, '0')" +== 190 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,4,'60831598315717.14146161') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 4, '60831598315717.14146161')" +== 191 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,4,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 4, '1.00000000000000000000')" +== 192 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,5,'7815858.450391') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 5, '7815858.450391')" +== 193 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,5,'7783064.373409') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 5, '7783064.373409')" +== 194 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,5,'127888068979.9935054429') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 5, '127888068979.9935054429')" +== 195 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,5,'475.66281046305802686061') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 5, '475.66281046305802686061')" +== 196 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,6,'7893362.98953026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 6, '7893362.98953026')" +== 197 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,6,'7705559.83426974') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 6, '7705559.83426974')" +== 198 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,6,'732381731243.745115764094') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 6, '732381731243.745115764094')" +== 199 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,6,'83.05996138436129499606') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 6, '83.05996138436129499606')" +== 200 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,7,'-75229023.5881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 7, '-75229023.5881')" +== 201 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,7,'90827946.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 7, '90827946.4119')" +== 202 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,7,'-647577464846017.9715') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 7, '-647577464846017.9715')" +== 203 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,7,'-.09393717604145131637') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 7, '-.09393717604145131637')" +== 204 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,8,'7874342.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 8, '7874342.4119')" +== 205 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,8,'7724580.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 8, '7724580.4119')" +== 206 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,8,'584031469984.4839') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 8, '584031469984.4839')" +== 207 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,8,'104.15808298366741897143') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 8, '104.15808298366741897143')" +== 208 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,9,'-17127342.633147420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (4, 9, '-17127342.633147420')" +== 209 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,9,'32726265.456947420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 9, '32726265.456947420')" +== 210 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,9,'-194415646271340.1815956522980') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 9, '-194415646271340.1815956522980')" +== 211 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,9,'-.31289456112403769409') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 9, '-.31289456112403769409')" +== 212 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,0,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 0, '16397.038491')" +== 213 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,0,'16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 0, '16397.038491')" +== 214 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 0, '0')" +== 215 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 0, 'NaN')" +== 216 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,1,'16397.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 1, '16397.038491')" +== 217 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,1,'16397.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 1, '16397.038491')" +== 218 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 1, '0')" +== 219 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 1, 'NaN')" +== 220 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,2,'-34322095.176906047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 2, '-34322095.176906047')" +== 221 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,2,'34354889.253888047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 2, '34354889.253888047')" +== 222 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,2,'-563049578578.769242506736077') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 2, '-563049578578.769242506736077')" +== 223 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,2,'-.00047751189505192446') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 2, '-.00047751189505192446')" +== 224 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,3,'16401.348491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 3, '16401.348491')" +== 225 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,3,'16392.728491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 3, '16392.728491')" +== 226 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,3,'70671.23589621') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 3, '70671.23589621')" +== 227 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,3,'3804.41728329466357308584') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 3, '3804.41728329466357308584')" +== 228 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,4,'7815858.450391') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 4, '7815858.450391')" +== 229 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,4,'-7783064.373409') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 4, '-7783064.373409')" +== 230 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,4,'127888068979.9935054429') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 4, '127888068979.9935054429')" +== 231 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,4,'.00210232958726897192') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 4, '.00210232958726897192')" +== 232 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,5,'32794.076982') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 5, '32794.076982')" +== 233 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,5,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 5, '0')" +== 234 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,5,'268862871.275335557081') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 5, '268862871.275335557081')" +== 235 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,5,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 5, '1.00000000000000000000')" +== 236 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,6,'110298.61612126') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 6, '110298.61612126')" +== 237 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,6,'-77504.53913926') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 6, '-77504.53913926')" +== 238 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,6,'1539707782.76899778633766') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 6, '1539707782.76899778633766')" +== 239 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,6,'.17461941433576102689') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 6, '.17461941433576102689')" +== 240 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,7,'-83012087.961509') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 7, '-83012087.961509')" +== 241 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,7,'83044882.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 7, '83044882.038491')" +== 242 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,7,'-1361421264394.416135') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 7, '-1361421264394.416135')" +== 243 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,7,'-.00019748690453643710') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 7, '-.00019748690453643710')" +== 244 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,8,'91278.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 8, '91278.038491')" +== 245 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,8,'-58483.961509') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 8, '-58483.961509')" +== 246 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,8,'1227826639.244571') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 8, '1227826639.244571')" +== 247 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,8,'.21897461960978085228') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 8, '.21897461960978085228')" +== 248 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,9,'-24910407.006556420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (5, 9, '-24910407.006556420')" +== 249 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,9,'24943201.083538420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 9, '24943201.083538420')" +== 250 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,9,'-408725765384.257043660243220') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 9, '-408725765384.257043660243220')" +== 251 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,9,'-.00065780749354660427') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 9, '-.00065780749354660427')" +== 252 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,0,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 0, '93901.57763026')" +== 253 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,0,'93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 0, '93901.57763026')" +== 254 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 0, '0')" +== 255 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 0, 'NaN')" +== 256 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,1,'93901.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 1, '93901.57763026')" +== 257 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,1,'93901.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 1, '93901.57763026')" +== 258 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 1, '0')" +== 259 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 1, 'NaN')" +== 260 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,2,'-34244590.637766787') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 2, '-34244590.637766787')" +== 261 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,2,'34432393.793027307') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 2, '34432393.793027307')" +== 262 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,2,'-3224438592470.18449811926184222') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 2, '-3224438592470.18449811926184222')" +== 263 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,2,'-.00273458651128995823') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 2, '-.00273458651128995823')" +== 264 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,3,'93905.88763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 3, '93905.88763026')" +== 265 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,3,'93897.26763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 3, '93897.26763026')" +== 266 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,3,'404715.7995864206') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 3, '404715.7995864206')" +== 267 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,3,'21786.90896293735498839907') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 3, '21786.90896293735498839907')" +== 268 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,4,'7893362.98953026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 4, '7893362.98953026')" +== 269 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,4,'-7705559.83426974') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 4, '-7705559.83426974')" +== 270 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,4,'732381731243.745115764094') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 4, '732381731243.745115764094')" +== 271 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,4,'.01203949512295682469') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 4, '.01203949512295682469')" +== 272 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,5,'110298.61612126') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 5, '110298.61612126')" +== 273 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,5,'77504.53913926') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 5, '77504.53913926')" +== 274 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,5,'1539707782.76899778633766') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 5, '1539707782.76899778633766')" +== 275 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,5,'5.72674008674192359679') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 5, '5.72674008674192359679')" +== 276 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,6,'187803.15526052') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 6, '187803.15526052')" +== 277 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,6,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 6, '0')" +== 278 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,6,'8817506281.4517452372676676') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 6, '8817506281.4517452372676676')" +== 279 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,6,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 6, '1.00000000000000000000')" +== 280 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,7,'-82934583.42236974') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 7, '-82934583.42236974')" +== 281 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,7,'83122386.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 7, '83122386.57763026')" +== 282 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,7,'-7796505729750.37795610') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 7, '-7796505729750.37795610')" +== 283 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,7,'-.00113095617281538980') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 7, '-.00113095617281538980')" +== 284 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,8,'168782.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 8, '168782.57763026')" +== 285 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,8,'19020.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 8, '19020.57763026')" +== 286 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,8,'7031444034.53149906') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 8, '7031444034.53149906')" +== 287 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,8,'1.25401073209839612184') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 8, '1.25401073209839612184')" +== 288 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,9,'-24832902.467417160') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (6, 9, '-24832902.467417160')" +== 289 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,9,'25020705.622677680') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 9, '25020705.622677680')" +== 290 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,9,'-2340666225110.29929521292692920') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 9, '-2340666225110.29929521292692920')" +== 291 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,9,'-.00376709254265256789') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 9, '-.00376709254265256789')" +== 292 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,0,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 0, '-83028485')" +== 293 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,0,'-83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 0, '-83028485')" +== 294 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 0, '0')" +== 295 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 0, 'NaN')" +== 296 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,1,'-83028485') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 1, '-83028485')" +== 297 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,1,'-83028485') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 1, '-83028485')" +== 298 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 1, '0')" +== 299 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 1, 'NaN')" +== 300 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,2,'-117366977.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 2, '-117366977.215397047')" +== 301 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,2,'-48689992.784602953') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 2, '-48689992.784602953')" +== 302 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,2,'2851072985828710.485883795') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 2, '2851072985828710.485883795')" +== 303 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,2,'2.41794207151503385700') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 2, '2.41794207151503385700')" +== 304 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,3,'-83028480.69') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 3, '-83028480.69')" +== 305 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,3,'-83028489.31') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 3, '-83028489.31')" +== 306 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,3,'-357852770.35') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 3, '-357852770.35')" +== 307 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,3,'-19264149.65197215777262180974') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 3, '-19264149.65197215777262180974')" +== 308 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,4,'-75229023.5881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 4, '-75229023.5881')" +== 309 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,4,'-90827946.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 4, '-90827946.4119')" +== 310 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,4,'-647577464846017.9715') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 4, '-647577464846017.9715')" +== 311 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,4,'-10.64541262725136247686') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 4, '-10.64541262725136247686')" +== 312 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,5,'-83012087.961509') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 5, '-83012087.961509')" +== 313 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,5,'-83044882.038491') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 5, '-83044882.038491')" +== 314 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,5,'-1361421264394.416135') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 5, '-1361421264394.416135')" +== 315 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,5,'-5063.62688881730941836574') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 5, '-5063.62688881730941836574')" +== 316 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,6,'-82934583.42236974') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 6, '-82934583.42236974')" +== 317 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,6,'-83122386.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 6, '-83122386.57763026')" +== 318 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,6,'-7796505729750.37795610') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 6, '-7796505729750.37795610')" +== 319 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,6,'-884.20756174009028770294') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 6, '-884.20756174009028770294')" +== 320 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,7,'-166056970') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 7, '-166056970')" +== 321 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,7,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 7, '0')" +== 322 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,7,'6893729321395225') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 7, '6893729321395225')" +== 323 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,7,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 7, '1.00000000000000000000')" +== 324 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,8,'-82953604') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 8, '-82953604')" +== 325 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,8,'-83103366') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 8, '-83103366')" +== 326 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,8,'-6217255985285') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 8, '-6217255985285')" +== 327 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,8,'-1108.80577182462841041118') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 8, '-1108.80577182462841041118')" +== 328 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,9,'-107955289.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 9, '-107955289.045047420')" +== 329 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,9,'-58101680.954952580') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 9, '-58101680.954952580')" +== 330 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,9,'2069634775752159.035758700') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 9, '2069634775752159.035758700')" +== 331 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,9,'3.33089171198810413382') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 9, '3.33089171198810413382')" +== 332 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,0,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 0, '74881')" +== 333 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,0,'74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 0, '74881')" +== 334 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 0, '0')" +== 335 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 0, 'NaN')" +== 336 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,1,'74881') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 1, '74881')" +== 337 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,1,'74881') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 1, '74881')" +== 338 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 1, '0')" +== 339 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 1, 'NaN')" +== 340 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,2,'-34263611.215397047') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 2, '-34263611.215397047')" +== 341 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,2,'34413373.215397047') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 2, '34413373.215397047')" +== 342 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,2,'-2571300635581.146276407') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 2, '-2571300635581.146276407')" +== 343 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,2,'-.00218067233500788615') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 2, '-.00218067233500788615')" +== 344 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,3,'74885.31') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 3, '74885.31')" +== 345 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,3,'74876.69') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 3, '74876.69')" +== 346 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,3,'322737.11') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 3, '322737.11')" +== 347 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,3,'17373.78190255220417633410') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 3, '17373.78190255220417633410')" +== 348 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,4,'7874342.4119') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 4, '7874342.4119')" +== 349 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,4,'-7724580.4119') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 4, '-7724580.4119')" +== 350 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,4,'584031469984.4839') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 4, '584031469984.4839')" +== 351 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,4,'.00960079113741758956') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 4, '.00960079113741758956')" +== 352 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,5,'91278.038491') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 5, '91278.038491')" +== 353 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,5,'58483.961509') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 5, '58483.961509')" +== 354 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,5,'1227826639.244571') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 5, '1227826639.244571')" +== 355 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,5,'4.56673929509287019456') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 5, '4.56673929509287019456')" +== 356 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,6,'168782.57763026') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 6, '168782.57763026')" +== 357 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,6,'-19020.57763026') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 6, '-19020.57763026')" +== 358 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,6,'7031444034.53149906') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 6, '7031444034.53149906')" +== 359 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,6,'.79744134113322314424') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 6, '.79744134113322314424')" +== 360 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,7,'-82953604') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 7, '-82953604')" +== 361 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,7,'83103366') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 7, '83103366')" +== 362 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,7,'-6217255985285') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 7, '-6217255985285')" +== 363 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,7,'-.00090187120721280172') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 7, '-.00090187120721280172')" +== 364 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,8,'149762') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 8, '149762')" +== 365 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,8,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 8, '0')" +== 366 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,8,'5607164161') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 8, '5607164161')" +== 367 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,8,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 8, '1.00000000000000000000')" +== 368 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,9,'-24851923.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (8, 9, '-24851923.045047420')" +== 369 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,9,'25001685.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 9, '25001685.045047420')" +== 370 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,9,'-1866544013697.195857020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 9, '-1866544013697.195857020')" +== 371 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,9,'-.00300403532938582735') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 9, '-.00300403532938582735')" +== 372 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,0,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 0, '-24926804.045047420')" +== 373 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,0,'-24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 0, '-24926804.045047420')" +== 374 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 0, '0')" +== 375 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 0, 'NaN')" +== 376 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,1,'-24926804.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 1, '-24926804.045047420')" +== 377 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,1,'-24926804.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 1, '-24926804.045047420')" +== 378 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 1, '0')" +== 379 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,1,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 1, 'NaN')" +== 380 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,2,'-59265296.260444467') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 2, '-59265296.260444467')" +== 381 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,2,'9411688.170349627') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 2, '9411688.170349627')" +== 382 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,2,'855948866655588.453741509242968740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 2, '855948866655588.453741509242968740')" +== 383 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,2,'.72591434384152961526') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 2, '.72591434384152961526')" +== 384 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,3,'-24926799.735047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 3, '-24926799.735047420')" +== 385 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,3,'-24926808.355047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 3, '-24926808.355047420')" +== 386 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,3,'-107434525.43415438020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 3, '-107434525.43415438020')" +== 387 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,3,'-5783481.21694835730858468677') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 3, '-5783481.21694835730858468677')" +== 388 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,4,'-17127342.633147420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 4, '-17127342.633147420')" +== 389 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,4,'-32726265.456947420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 4, '-32726265.456947420')" +== 390 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,4,'-194415646271340.1815956522980') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 4, '-194415646271340.1815956522980')" +== 391 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,4,'-3.19596478892958416484') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 4, '-3.19596478892958416484')" +== 392 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,5,'-24910407.006556420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 5, '-24910407.006556420')" +== 393 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,5,'-24943201.083538420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 5, '-24943201.083538420')" +== 394 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,5,'-408725765384.257043660243220') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 5, '-408725765384.257043660243220')" +== 395 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,5,'-1520.20159364322004505807') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 5, '-1520.20159364322004505807')" +== 396 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,6,'-24832902.467417160') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 6, '-24832902.467417160')" +== 397 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,6,'-25020705.622677680') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 6, '-25020705.622677680')" +== 398 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,6,'-2340666225110.29929521292692920') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 6, '-2340666225110.29929521292692920')" +== 399 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,6,'-265.45671195426965751280') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 6, '-265.45671195426965751280')" +== 400 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,7,'-107955289.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 7, '-107955289.045047420')" +== 401 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,7,'58101680.954952580') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 7, '58101680.954952580')" +== 402 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,7,'2069634775752159.035758700') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 7, '2069634775752159.035758700')" +== 403 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,7,'.30021990699995814689') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 7, '.30021990699995814689')" +== 404 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,8,'-24851923.045047420') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 8, '-24851923.045047420')" +== 405 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,8,'-25001685.045047420') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 8, '-25001685.045047420')" +== 406 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,8,'-1866544013697.195857020') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 8, '-1866544013697.195857020')" +== 407 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,8,'-332.88556569820675471748') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 8, '-332.88556569820675471748')" +== 408 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,9,'-49853608.090094840') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (9, 9, '-49853608.090094840')" +== 409 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,9,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 9, '0')" +== 410 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,9,'621345559900192.420120630048656400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 9, '621345559900192.420120630048656400')" +== 411 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,9,'1.00000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 9, '1.00000000000000000000')" +== 412 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 413 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 414 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (0,'0') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (0, '0')" +== 415 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (1,'0') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (1, '0')" +== 416 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (2,'5859.90547836712524903505') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (2, '5859.90547836712524903505')" +== 417 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (3,'2.07605394920266944396') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (3, '2.07605394920266944396')" +== 418 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (4,'2792.75158435189147418923') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (4, '2792.75158435189147418923')" +== 419 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (5,'128.05092147657509145473') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (5, '128.05092147657509145473')" +== 420 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (6,'306.43364311096782703406') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (6, '306.43364311096782703406')" +== 421 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (7,'9111.99676251039939975230') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (7, '9111.99676251039939975230')" +== 422 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (8,'273.64392922189960397542') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (8, '273.64392922189960397542')" +== 423 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (9,'4992.67503899937593364766') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (9, '4992.67503899937593364766')" +== 424 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 425 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 426 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (0, 'NaN')" +== 427 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (1,'NaN') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (1, 'NaN')" +== 428 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (2,'17.35177750493897715514') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (2, '17.35177750493897715514')" +== 429 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (3,'1.46093790411565641971') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (3, '1.46093790411565641971')" +== 430 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (4,'15.86956523951936572464') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (4, '15.86956523951936572464')" +== 431 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (5,'9.70485601768871834038') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (5, '9.70485601768871834038')" +== 432 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (6,'11.45000246622944403127') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (6, '11.45000246622944403127')" +== 433 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (7,'18.23469429965478772991') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (7, '18.23469429965478772991')" +== 434 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (8,'11.22365546576315513668') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (8, '11.22365546576315513668')" +== 435 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (9,'17.03145425013166006962') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (9, '17.03145425013166006962')" +== 436 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 437 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 438 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (0,'NaN') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (0, 'NaN')" +== 439 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (1,'NaN') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (1, 'NaN')" +== 440 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (2,'7.53578122160797276459') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (2, '7.53578122160797276459')" +== 441 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (3,'.63447727016073160075') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (3, '.63447727016073160075')" +== 442 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (4,'6.89206461372691743345') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (4, '6.89206461372691743345')" +== 443 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (5,'4.21476541614777768626') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (5, '4.21476541614777768626')" +== 444 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (6,'4.97267288886207207671') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (6, '4.97267288886207207671')" +== 445 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (7,'7.91922711353275546914') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (7, '7.91922711353275546914')" +== 446 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (8,'4.87437163556421004138') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (8, '4.87437163556421004138')" +== 447 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (9,'7.39666659961986567059') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (9, '7.39666659961986567059')" +== 448 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 449 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 450 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (0, 'NaN')" +== 451 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (1,'NaN') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (1, 'NaN')" +== 452 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (2,'224790267919917955.13261618583642653184') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (2, '224790267919917955.13261618583642653184')" +== 453 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (3,'28.90266599445155957393') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (3, '28.90266599445155957393')" +== 454 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (4,'7405685069594999.07733999469386277636') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (4, '7405685069594999.07733999469386277636')" +== 455 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (5,'5068226527.32127265408584640098') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (5, '5068226527.32127265408584640098')" +== 456 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (6,'281839893606.99372343357047819067') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (6, '281839893606.99372343357047819067')" +== 457 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (7,'1716699575118597095.42330819910640247627') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (7, '1716699575118597095.42330819910640247627')" +== 458 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (8,'167361463828.07491320069016125952') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (8, '167361463828.07491320069016125952')" +== 459 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (9,'107511333880052007.04141124673540337457') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (9, '107511333880052007.04141124673540337457')" +== 460 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 461 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 462 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (0, '0') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (0, '0')" +== 463 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (1, '0') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (1, '0')" +== 464 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (2, '-34338492.215397047') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (2, '-34338492.215397047')" +== 465 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (3, '4.31') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (3, '4.31')" +== 466 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (4, '7799461.4119') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (4, '7799461.4119')" +== 467 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (5, '16397.038491') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (5, '16397.038491')" +== 468 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (6, '93901.57763026') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (6, '93901.57763026')" +== 469 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (7, '-83028485') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (7, '-83028485')" +== 470 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (8, '74881') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (8, '74881')" +== 471 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (9, '-24926804.045047420') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (9, '-24926804.045047420')" +== 472 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 473 +-- truncate_limit: 100 +-- ****************************** +-- * Create indices for faster checks +-- ****************************** + +CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add (id1, id2) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add USING btree (id1, id2)" +== 474 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub (id1, id2) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub USING btree (id1, id2)" +== 475 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div (id1, id2) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div USING btree (id1, id2)" +== 476 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul (id1, id2) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul USING btree (id1, id2)" +== 477 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt (id) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt USING btree (id)" +== 478 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln (id) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln USING btree (id)" +== 479 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 (id) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 USING btree (id)" +== 480 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln (id) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln USING btree (id)" +== 481 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_add +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_add" +== 482 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_sub +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_sub" +== 483 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_div +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_div" +== 484 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_mul +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_mul" +== 485 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_sqrt +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_sqrt" +== 486 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_ln +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_ln" +== 487 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_log10 +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_log10" +== 488 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_power_10_ln +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_power_10_ln" +== 489 +-- truncate_limit: 100 +-- ****************************** +-- * Now check the behaviour of the NUMERIC type +-- ****************************** + +-- ****************************** +-- * Addition check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 490 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val FROM num_data t1, num_data t2" +== 491 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_add t2 WHERE ..." +== 492 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 493 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) FROM num_data t1, num_data t2" +== 494 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 10) as expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 10) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_add t2 WHERE ..." +== 495 +-- truncate_limit: 100 +-- ****************************** +-- * Subtraction check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 496 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val FROM num_data t1, num_data t2" +== 497 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_sub t2 WHERE ..." +== 498 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 499 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) FROM num_data t1, num_data t2" +== 500 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 40) + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 40) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_sub t2 WHERE ..." +== 501 +-- truncate_limit: 100 +-- ****************************** +-- * Multiply check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 502 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val FROM num_data t1, num_data t2" +== 503 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_mul t2 WHERE ..." +== 504 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 505 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) FROM num_data t1, num_data t2" +== 506 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 30) as expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 30) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_mul t2 WHERE ..." +== 507 +-- truncate_limit: 100 +-- ****************************** +-- * Division check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 508 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val / t2.val + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT ... FROM num_data t1, num_data t2 WHERE t2.val <> '0.0'" +== 509 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_div t2 WHERE ..." +== 510 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 511 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val / t2.val, 80) + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT ... FROM num_data t1, num_data t2 WHERE t2.val <> '0.0'" +== 512 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 80) as expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 80) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_div t2 WHERE ..." +== 513 +-- truncate_limit: 100 +-- ****************************** +-- * Square root check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 514 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, SQRT(ABS(val)) + FROM num_data +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT id, 0, sqrt(abs(val)) FROM num_data" +== 515 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_sqrt t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sqrt" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_sqrt t2 WHERE ..." +== 516 +-- truncate_limit: 100 +-- ****************************** +-- * Natural logarithm check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 517 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, LN(ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT id, 0, ln(abs(val)) FROM num_data WHERE val <> '0.0'" +== 518 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_ln t2 WHERE ..." +== 519 +-- truncate_limit: 100 +-- ****************************** +-- * Logarithm base 10 check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 520 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, LOG(numeric '10', ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT id, 0, log('10'::numeric, abs(val)) FROM num_data WHERE val <> '0.0'" +== 521 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_log10 t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_log10" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_log10 t2 WHERE ..." +== 522 +-- truncate_limit: 100 +-- ****************************** +-- * POWER(10, LN(value)) check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 523 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, POWER(numeric '10', LN(ABS(round(val,200)))) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="power" function="power" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT ... FROM num_data WHERE val <> '0.0'" +== 524 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_power_10_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_power_10_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_power_10_ln t2 WHERE ..." +== 525 +-- truncate_limit: 100 +-- ****************************** +-- * Check behavior with Inf and NaN inputs. It's easiest to handle these +-- * separately from the num_data framework used above, because some input +-- * combinations will throw errors. +-- ****************************** + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('inf'),('-inf'),('nan')) +SELECT x1, x2, + x1 + x2 AS sum, + x1 - x2 AS diff, + x1 * x2 AS prod +FROM v AS v1(x1), v AS v2(x2) +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (...) SELECT ... FROM v v1(x1), v v2(x2)" +== 526 +-- truncate_limit: 100 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('inf'),('-inf'),('nan')) +SELECT x1, x2, + x1 / x2 AS quot, + x1 % x2 AS mod, + div(x1, x2) AS div +FROM v AS v1(x1), v AS v2(x2) WHERE x2 != 0 +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +FUNCTION: name="div" function="div" schema="" ctx=Call +FILTER: schema="" table="" column="x2" +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (...) SELECT ... FROM v v1(x1), v v2(x2) WHERE x2 <> 0" +== 527 +-- truncate_limit: 100 +SELECT 'inf'::numeric / '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'inf'::numeric / '0'" +== 528 +-- truncate_limit: 100 +SELECT '-inf'::numeric / '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-inf'::numeric / '0'" +== 529 +-- truncate_limit: 100 +SELECT 'nan'::numeric / '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::numeric / '0'" +== 530 +-- truncate_limit: 100 +SELECT '0'::numeric / '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0'::numeric / '0'" +== 531 +-- truncate_limit: 100 +SELECT 'inf'::numeric % '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'inf'::numeric % '0'" +== 532 +-- truncate_limit: 100 +SELECT '-inf'::numeric % '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-inf'::numeric % '0'" +== 533 +-- truncate_limit: 100 +SELECT 'nan'::numeric % '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'nan'::numeric % '0'" +== 534 +-- truncate_limit: 100 +SELECT '0'::numeric % '0' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0'::numeric % '0'" +== 535 +-- truncate_limit: 100 +SELECT div('inf'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div('inf'::numeric, '0')" +== 536 +-- truncate_limit: 100 +SELECT div('-inf'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div('-inf'::numeric, '0')" +== 537 +-- truncate_limit: 100 +SELECT div('nan'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div('nan'::numeric, '0')" +== 538 +-- truncate_limit: 100 +SELECT div('0'::numeric, '0') +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div('0'::numeric, '0')" +== 539 +-- truncate_limit: 100 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('inf'),('-inf'),('nan')) +SELECT x, -x as minusx, abs(x), floor(x), ceil(x), sign(x), numeric_inc(x) as inc +FROM v +-- +CTE: "v" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="floor" function="floor" schema="" ctx=Call +FUNCTION: name="ceil" function="ceil" schema="" ctx=Call +FUNCTION: name="sign" function="sign" schema="" ctx=Call +FUNCTION: name="numeric_inc" function="numeric_inc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (...) SELECT ... FROM v" +== 540 +-- truncate_limit: 100 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('inf'),('-inf'),('nan')) +SELECT x, round(x), round(x,1) as round1, trunc(x), trunc(x,1) as trunc1 +FROM v +-- +CTE: "v" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (...) SELECT x, round(x), round(x, 1) AS round1, trunc(x), trunc(x, 1) AS trunc1 FROM v" +== 541 +-- truncate_limit: 100 +-- the large values fall into the numeric abbreviation code's maximal classes +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('1e340'),('-1e340'), + ('inf'),('-inf'),('nan'), + ('inf'),('-inf'),('nan')) +SELECT substring(x::text, 1, 32) +FROM v ORDER BY x +-- +CTE: "v" +FUNCTION: name="substring" function="substring" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (VALUES (...)) SELECT \"substring\"(x::text, 1, 32) FROM v ORDER BY x" +== 542 +-- truncate_limit: 100 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('4.2'),('inf'),('nan')) +SELECT x, sqrt(x) +FROM v +-- +CTE: "v" +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (VALUES ('0'::numeric), ('1'), ('4.2'), ('inf'), ('nan')) SELECT x, sqrt(x) FROM v" +== 543 +-- truncate_limit: 100 +SELECT sqrt('-1'::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt('-1'::numeric)" +== 544 +-- truncate_limit: 100 +SELECT sqrt('-inf'::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt('-inf'::numeric)" +== 545 +-- truncate_limit: 100 +WITH v(x) AS + (VALUES('1'::numeric),('4.2'),('inf'),('nan')) +SELECT x, + log(x), + log10(x), + ln(x) +FROM v +-- +CTE: "v" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log10" function="log10" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (VALUES (...)) SELECT x, log(x), log10(x), ln(x) FROM v" +== 546 +-- truncate_limit: 100 +SELECT ln('0'::numeric) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln('0'::numeric)" +== 547 +-- truncate_limit: 100 +SELECT ln('-1'::numeric) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln('-1'::numeric)" +== 548 +-- truncate_limit: 100 +SELECT ln('-inf'::numeric) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln('-inf'::numeric)" +== 549 +-- truncate_limit: 100 +WITH v(x) AS + (VALUES('2'::numeric),('4.2'),('inf'),('nan')) +SELECT x1, x2, + log(x1, x2) +FROM v AS v1(x1), v AS v2(x2) +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (VALUES (...)) SELECT x1, x2, log(x1, x2) FROM v v1(x1), v v2(x2)" +== 550 +-- truncate_limit: 100 +SELECT log('0'::numeric, '10') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log('0'::numeric, '10')" +== 551 +-- truncate_limit: 100 +SELECT log('10'::numeric, '0') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log('10'::numeric, '0')" +== 552 +-- truncate_limit: 100 +SELECT log('-inf'::numeric, '10') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log('-inf'::numeric, '10')" +== 553 +-- truncate_limit: 100 +SELECT log('10'::numeric, '-inf') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log('10'::numeric, '-inf')" +== 554 +-- truncate_limit: 100 +SELECT log('inf'::numeric, '0') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log('inf'::numeric, '0')" +== 555 +-- truncate_limit: 100 +SELECT log('inf'::numeric, '-inf') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log('inf'::numeric, '-inf')" +== 556 +-- truncate_limit: 100 +SELECT log('-inf'::numeric, 'inf') +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log('-inf'::numeric, 'inf')" +== 557 +-- truncate_limit: 100 +WITH v(x) AS + (VALUES('0'::numeric),('1'),('2'),('4.2'),('inf'),('nan')) +SELECT x1, x2, + power(x1, x2) +FROM v AS v1(x1), v AS v2(x2) WHERE x1 != 0 OR x2 >= 0 +-- +ALIAS: "v1"="v" +ALIAS: "v2"="v" +CTE: "v" +FUNCTION: name="power" function="power" schema="" ctx=Call +FILTER: schema="" table="" column="x1" +FILTER: schema="" table="" column="x2" +STMT: SelectStmt +TRUNCATED: "WITH v(x) AS (...) SELECT x1, x2, power(x1, x2) FROM v v1(x1), v v2(x2) WHERE x1 <> 0 OR x2 >= 0" +== 558 +-- truncate_limit: 100 +SELECT power('0'::numeric, '-1') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('0'::numeric, '-1')" +== 559 +-- truncate_limit: 100 +SELECT power('0'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('0'::numeric, '-inf')" +== 560 +-- truncate_limit: 100 +SELECT power('-1'::numeric, 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-1'::numeric, 'inf')" +== 561 +-- truncate_limit: 100 +SELECT power('-2'::numeric, '3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-2'::numeric, '3')" +== 562 +-- truncate_limit: 100 +SELECT power('-2'::numeric, '3.3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-2'::numeric, '3.3')" +== 563 +-- truncate_limit: 100 +SELECT power('-2'::numeric, '-1') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-2'::numeric, '-1')" +== 564 +-- truncate_limit: 100 +SELECT power('-2'::numeric, '-1.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-2'::numeric, '-1.5')" +== 565 +-- truncate_limit: 100 +SELECT power('-2'::numeric, 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-2'::numeric, 'inf')" +== 566 +-- truncate_limit: 100 +SELECT power('-2'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-2'::numeric, '-inf')" +== 567 +-- truncate_limit: 100 +SELECT power('inf'::numeric, '-2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('inf'::numeric, '-2')" +== 568 +-- truncate_limit: 100 +SELECT power('inf'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('inf'::numeric, '-inf')" +== 569 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, '2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, '2')" +== 570 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, '3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, '3')" +== 571 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, '4.5') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, '4.5')" +== 572 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, '-2') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, '-2')" +== 573 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, '-3') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, '-3')" +== 574 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, '0') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, '0')" +== 575 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, 'inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, 'inf')" +== 576 +-- truncate_limit: 100 +SELECT power('-inf'::numeric, '-inf') +-- +FUNCTION: name="power" function="power" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT power('-inf'::numeric, '-inf')" +== 577 +-- truncate_limit: 100 +-- ****************************** +-- * miscellaneous checks for things that have been broken in the past... +-- ****************************** +-- numeric AVG used to fail on some platforms +SELECT AVG(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(val) FROM num_data" +== 578 +-- truncate_limit: 100 +SELECT MAX(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(val) FROM num_data" +== 579 +-- truncate_limit: 100 +SELECT MIN(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(val) FROM num_data" +== 580 +-- truncate_limit: 100 +SELECT STDDEV(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stddev(val) FROM num_data" +== 581 +-- truncate_limit: 100 +SELECT VARIANCE(val) FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT variance(val) FROM num_data" +== 582 +-- truncate_limit: 100 +-- Check for appropriate rounding and overflow +CREATE TABLE fract_only (id int, val numeric(4,4)) +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fract_only (id int, val numeric(4, 4))" +== 583 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (1, '0.0') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (1, '0.0')" +== 584 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (2, '0.1') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (2, '0.1')" +== 585 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (3, '1.0') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (3, '1.0')" +== 586 +-- truncate_limit: 100 +-- should fail +INSERT INTO fract_only VALUES (4, '-0.9999') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (4, '-0.9999')" +== 587 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (5, '0.99994') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (5, '0.99994')" +== 588 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (6, '0.99995') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (6, '0.99995')" +== 589 +-- truncate_limit: 100 +-- should fail +INSERT INTO fract_only VALUES (7, '0.00001') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (7, '0.00001')" +== 590 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (8, '0.00017') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (8, '0.00017')" +== 591 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (9, 'NaN') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (9, 'NaN')" +== 592 +-- truncate_limit: 100 +INSERT INTO fract_only VALUES (10, 'Inf') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (10, 'Inf')" +== 593 +-- truncate_limit: 100 +-- should fail +INSERT INTO fract_only VALUES (11, '-Inf') +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_only VALUES (11, '-Inf')" +== 594 +-- truncate_limit: 100 +-- should fail +SELECT * FROM fract_only +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fract_only" +== 595 +-- truncate_limit: 100 +DROP TABLE fract_only +-- +TABLE: name="fract_only" schema="" table="fract_only" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fract_only" +== 596 +-- truncate_limit: 100 +-- Check conversion to integers +SELECT (-9223372036854775808.5)::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808.5)::int8" +== 597 +-- truncate_limit: 100 +-- should fail +SELECT (-9223372036854775808.4)::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-9223372036854775808.4)::int8" +== 598 +-- truncate_limit: 100 +-- ok +SELECT 9223372036854775807.4::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (9223372036854775807.4)::int8" +== 599 +-- truncate_limit: 100 +-- ok +SELECT 9223372036854775807.5::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (9223372036854775807.5)::int8" +== 600 +-- truncate_limit: 100 +-- should fail +SELECT (-2147483648.5)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648.5)::int4" +== 601 +-- truncate_limit: 100 +-- should fail +SELECT (-2147483648.4)::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-2147483648.4)::int4" +== 602 +-- truncate_limit: 100 +-- ok +SELECT 2147483647.4::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (2147483647.4)::int4" +== 603 +-- truncate_limit: 100 +-- ok +SELECT 2147483647.5::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (2147483647.5)::int4" +== 604 +-- truncate_limit: 100 +-- should fail +SELECT (-32768.5)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-32768.5)::int2" +== 605 +-- truncate_limit: 100 +-- should fail +SELECT (-32768.4)::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (-32768.4)::int2" +== 606 +-- truncate_limit: 100 +-- ok +SELECT 32767.4::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (32767.4)::int2" +== 607 +-- truncate_limit: 100 +-- ok +SELECT 32767.5::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (32767.5)::int2" +== 608 +-- truncate_limit: 100 +-- should fail + +-- Check inf/nan conversion behavior +SELECT 'NaN'::float8::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::float8::numeric" +== 609 +-- truncate_limit: 100 +SELECT 'Infinity'::float8::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::float8::numeric" +== 610 +-- truncate_limit: 100 +SELECT '-Infinity'::float8::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-Infinity'::float8::numeric" +== 611 +-- truncate_limit: 100 +SELECT 'NaN'::numeric::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric::float8" +== 612 +-- truncate_limit: 100 +SELECT 'Infinity'::numeric::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::numeric::float8" +== 613 +-- truncate_limit: 100 +SELECT '-Infinity'::numeric::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-Infinity'::numeric::float8" +== 614 +-- truncate_limit: 100 +SELECT 'NaN'::float4::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::float4::numeric" +== 615 +-- truncate_limit: 100 +SELECT 'Infinity'::float4::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::float4::numeric" +== 616 +-- truncate_limit: 100 +SELECT '-Infinity'::float4::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-Infinity'::float4::numeric" +== 617 +-- truncate_limit: 100 +SELECT 'NaN'::numeric::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric::float4" +== 618 +-- truncate_limit: 100 +SELECT 'Infinity'::numeric::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::numeric::float4" +== 619 +-- truncate_limit: 100 +SELECT '-Infinity'::numeric::float4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-Infinity'::numeric::float4" +== 620 +-- truncate_limit: 100 +SELECT '42'::int2::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '42'::int2::numeric" +== 621 +-- truncate_limit: 100 +SELECT 'NaN'::numeric::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric::int2" +== 622 +-- truncate_limit: 100 +SELECT 'Infinity'::numeric::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::numeric::int2" +== 623 +-- truncate_limit: 100 +SELECT '-Infinity'::numeric::int2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-Infinity'::numeric::int2" +== 624 +-- truncate_limit: 100 +SELECT 'NaN'::numeric::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric::int4" +== 625 +-- truncate_limit: 100 +SELECT 'Infinity'::numeric::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::numeric::int4" +== 626 +-- truncate_limit: 100 +SELECT '-Infinity'::numeric::int4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-Infinity'::numeric::int4" +== 627 +-- truncate_limit: 100 +SELECT 'NaN'::numeric::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric::int8" +== 628 +-- truncate_limit: 100 +SELECT 'Infinity'::numeric::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Infinity'::numeric::int8" +== 629 +-- truncate_limit: 100 +SELECT '-Infinity'::numeric::int8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-Infinity'::numeric::int8" +== 630 +-- truncate_limit: 100 +-- Simple check that ceil(), floor(), and round() work correctly +CREATE TABLE ceil_floor_round (a numeric) +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ceil_floor_round (a numeric)" +== 631 +-- truncate_limit: 100 +INSERT INTO ceil_floor_round VALUES ('-5.5') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ceil_floor_round VALUES ('-5.5')" +== 632 +-- truncate_limit: 100 +INSERT INTO ceil_floor_round VALUES ('-5.499999') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ceil_floor_round VALUES ('-5.499999')" +== 633 +-- truncate_limit: 100 +INSERT INTO ceil_floor_round VALUES ('9.5') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ceil_floor_round VALUES ('9.5')" +== 634 +-- truncate_limit: 100 +INSERT INTO ceil_floor_round VALUES ('9.4999999') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ceil_floor_round VALUES ('9.4999999')" +== 635 +-- truncate_limit: 100 +INSERT INTO ceil_floor_round VALUES ('0.0') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ceil_floor_round VALUES ('0.0')" +== 636 +-- truncate_limit: 100 +INSERT INTO ceil_floor_round VALUES ('0.0000001') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ceil_floor_round VALUES ('0.0000001')" +== 637 +-- truncate_limit: 100 +INSERT INTO ceil_floor_round VALUES ('-0.000001') +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ceil_floor_round VALUES ('-0.000001')" +== 638 +-- truncate_limit: 100 +SELECT a, ceil(a), ceiling(a), floor(a), round(a) FROM ceil_floor_round +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=Select +FUNCTION: name="ceil" function="ceil" schema="" ctx=Call +FUNCTION: name="ceiling" function="ceiling" schema="" ctx=Call +FUNCTION: name="floor" function="floor" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, ceil(a), ceiling(a), floor(a), round(a) FROM ceil_floor_round" +== 639 +-- truncate_limit: 100 +DROP TABLE ceil_floor_round +-- +TABLE: name="ceil_floor_round" schema="" table="ceil_floor_round" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ceil_floor_round" +== 640 +-- truncate_limit: 100 +-- Check rounding, it should round ties away from zero. +SELECT i as pow, + round((-2.5 * 10 ^ i)::numeric, -i), + round((-1.5 * 10 ^ i)::numeric, -i), + round((-0.5 * 10 ^ i)::numeric, -i), + round((0.5 * 10 ^ i)::numeric, -i), + round((1.5 * 10 ^ i)::numeric, -i), + round((2.5 * 10 ^ i)::numeric, -i) +FROM generate_series(-5,5) AS t(i) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(-5, 5) t(i)" +== 641 +-- truncate_limit: 100 +-- Check limits of rounding before the decimal point +SELECT round(4.4e131071, -131071) = 4e131071 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(4.4e131071, -131071) = 4e131071" +== 642 +-- truncate_limit: 100 +SELECT round(4.5e131071, -131071) = 5e131071 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(4.5e131071, -131071) = 5e131071" +== 643 +-- truncate_limit: 100 +SELECT round(4.5e131071, -131072) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(4.5e131071, -131072)" +== 644 +-- truncate_limit: 100 +-- loses all digits +SELECT round(5.5e131071, -131072) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(5.5e131071, -131072)" +== 645 +-- truncate_limit: 100 +-- rounds up and overflows +SELECT round(5.5e131071, -131073) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(5.5e131071, -131073)" +== 646 +-- truncate_limit: 100 +-- loses all digits +SELECT round(5.5e131071, -1000000) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(5.5e131071, -1000000)" +== 647 +-- truncate_limit: 100 +-- loses all digits + +-- Check limits of rounding after the decimal point +SELECT round(5e-16383, 1000000) = 5e-16383 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(5e-16383, 1000000) = 5e-16383" +== 648 +-- truncate_limit: 100 +SELECT round(5e-16383, 16383) = 5e-16383 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(5e-16383, 16383) = 5e-16383" +== 649 +-- truncate_limit: 100 +SELECT round(5e-16383, 16382) = 1e-16382 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(5e-16383, 16382) = 1e-16382" +== 650 +-- truncate_limit: 100 +SELECT round(5e-16383, 16381) = 0 +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(5e-16383, 16381) = 0" +== 651 +-- truncate_limit: 100 +-- Check limits of trunc() before the decimal point +SELECT trunc(9.9e131071, -131071) = 9e131071 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trunc(9.9e131071, -131071) = 9e131071" +== 652 +-- truncate_limit: 100 +SELECT trunc(9.9e131071, -131072) +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trunc(9.9e131071, -131072)" +== 653 +-- truncate_limit: 100 +-- loses all digits +SELECT trunc(9.9e131071, -131073) +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trunc(9.9e131071, -131073)" +== 654 +-- truncate_limit: 100 +-- loses all digits +SELECT trunc(9.9e131071, -1000000) +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trunc(9.9e131071, -1000000)" +== 655 +-- truncate_limit: 100 +-- loses all digits + +-- Check limits of trunc() after the decimal point +SELECT trunc(5e-16383, 1000000) = 5e-16383 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trunc(5e-16383, 1000000) = 5e-16383" +== 656 +-- truncate_limit: 100 +SELECT trunc(5e-16383, 16383) = 5e-16383 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trunc(5e-16383, 16383) = 5e-16383" +== 657 +-- truncate_limit: 100 +SELECT trunc(5e-16383, 16382) = 0 +-- +FUNCTION: name="trunc" function="trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trunc(5e-16383, 16382) = 0" +== 658 +-- truncate_limit: 100 +-- Testing for width_bucket(). For convenience, we test both the +-- numeric and float8 versions of the function in this file. + +-- errors +SELECT width_bucket(5.0, 3.0, 4.0, 0) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(5.0, 3.0, 4.0, 0)" +== 659 +-- truncate_limit: 100 +SELECT width_bucket(5.0, 3.0, 4.0, -5) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(5.0, 3.0, 4.0, -5)" +== 660 +-- truncate_limit: 100 +SELECT width_bucket(3.5, 3.0, 3.0, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(3.5, 3.0, 3.0, 888)" +== 661 +-- truncate_limit: 100 +SELECT width_bucket(5.0::float8, 3.0::float8, 4.0::float8, 0) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket((5.0)::float8, (3.0)::float8, (4.0)::float8, 0)" +== 662 +-- truncate_limit: 100 +SELECT width_bucket(5.0::float8, 3.0::float8, 4.0::float8, -5) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket((5.0)::float8, (3.0)::float8, (4.0)::float8, -5)" +== 663 +-- truncate_limit: 100 +SELECT width_bucket(3.5::float8, 3.0::float8, 3.0::float8, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket((3.5)::float8, (3.0)::float8, (3.0)::float8, 888)" +== 664 +-- truncate_limit: 100 +SELECT width_bucket('NaN', 3.0, 4.0, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket('NaN', 3.0, 4.0, 888)" +== 665 +-- truncate_limit: 100 +SELECT width_bucket(0::float8, 'NaN', 4.0::float8, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(0::float8, 'NaN', (4.0)::float8, 888)" +== 666 +-- truncate_limit: 100 +SELECT width_bucket(2.0, 3.0, '-inf', 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(2.0, 3.0, '-inf', 888)" +== 667 +-- truncate_limit: 100 +SELECT width_bucket(0::float8, '-inf', 4.0::float8, 888) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(0::float8, '-inf', (4.0)::float8, 888)" +== 668 +-- truncate_limit: 100 +-- normal operation +CREATE TABLE width_bucket_test (operand_num numeric, operand_f8 float8) +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE width_bucket_test (operand_num numeric, operand_f8 float8)" +== 669 +-- truncate_limit: 100 +COPY width_bucket_test (operand_num) FROM stdin +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY width_bucket_test(operand_num) FROM STDIN" +== 670 +-- truncate_limit: 100 +UPDATE width_bucket_test SET operand_f8 = operand_num::float8 +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE width_bucket_test SET operand_f8 = operand_num::float8" +== 671 +-- truncate_limit: 100 +SELECT + operand_num, + width_bucket(operand_num, 0, 10, 5) AS wb_1, + width_bucket(operand_f8, 0, 10, 5) AS wb_1f, + width_bucket(operand_num, 10, 0, 5) AS wb_2, + width_bucket(operand_f8, 10, 0, 5) AS wb_2f, + width_bucket(operand_num, 2, 8, 4) AS wb_3, + width_bucket(operand_f8, 2, 8, 4) AS wb_3f, + width_bucket(operand_num, 5.0, 5.5, 20) AS wb_4, + width_bucket(operand_f8, 5.0, 5.5, 20) AS wb_4f, + width_bucket(operand_num, -25, 25, 10) AS wb_5, + width_bucket(operand_f8, -25, 25, 10) AS wb_5f + FROM width_bucket_test +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=Select +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM width_bucket_test" +== 672 +-- truncate_limit: 100 +-- Check positive and negative infinity: we require +-- finite bucket bounds, but allow an infinite operand +SELECT width_bucket(0.0::numeric, 'Infinity'::numeric, 5, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket((0.0)::numeric, 'Infinity'::numeric, 5, 10)" +== 673 +-- truncate_limit: 100 +-- error +SELECT width_bucket(0.0::numeric, 5, '-Infinity'::numeric, 20) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket((0.0)::numeric, 5, '-Infinity'::numeric, 20)" +== 674 +-- truncate_limit: 100 +-- error +SELECT width_bucket('Infinity'::numeric, 1, 10, 10), + width_bucket('-Infinity'::numeric, 1, 10, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket('Infinity'::numeric, 1, 10, 10), width_bucket('-Infinity'::numeric, 1, 10, 10)" +== 675 +-- truncate_limit: 100 +SELECT width_bucket(0.0::float8, 'Infinity'::float8, 5, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket((0.0)::float8, 'Infinity'::float8, 5, 10)" +== 676 +-- truncate_limit: 100 +-- error +SELECT width_bucket(0.0::float8, 5, '-Infinity'::float8, 20) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket((0.0)::float8, 5, '-Infinity'::float8, 20)" +== 677 +-- truncate_limit: 100 +-- error +SELECT width_bucket('Infinity'::float8, 1, 10, 10), + width_bucket('-Infinity'::float8, 1, 10, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket('Infinity'::float8, 1, 10, 10), width_bucket('-Infinity'::float8, 1, 10, 10)" +== 678 +-- truncate_limit: 100 +DROP TABLE width_bucket_test +-- +TABLE: name="width_bucket_test" schema="" table="width_bucket_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE width_bucket_test" +== 679 +-- truncate_limit: 100 +-- Simple test for roundoff error when results should be exact +SELECT x, width_bucket(x::float8, 10, 100, 9) as flt, + width_bucket(x::numeric, 10, 100, 9) as num +FROM generate_series(0, 110, 10) x +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(0, 110, 10) x" +== 680 +-- truncate_limit: 100 +SELECT x, width_bucket(x::float8, 100, 10, 9) as flt, + width_bucket(x::numeric, 100, 10, 9) as num +FROM generate_series(0, 110, 10) x +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(0, 110, 10) x" +== 681 +-- truncate_limit: 100 +-- Another roundoff-error hazard +SELECT width_bucket(0, -1e100::numeric, 1, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(0, - (1e100)::numeric, 1, 10)" +== 682 +-- truncate_limit: 100 +SELECT width_bucket(0, -1e100::float8, 1, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(0, - (1e100)::float8, 1, 10)" +== 683 +-- truncate_limit: 100 +SELECT width_bucket(1, 1e100::numeric, 0, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(1, (1e100)::numeric, 0, 10)" +== 684 +-- truncate_limit: 100 +SELECT width_bucket(1, 1e100::float8, 0, 10) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(1, (1e100)::float8, 0, 10)" +== 685 +-- truncate_limit: 100 +-- Check cases that could trigger overflow or underflow within the calculation +SELECT oper, low, high, cnt, width_bucket(oper, low, high, cnt) +FROM + (SELECT 1.797e+308::float8 AS big, 5e-324::float8 AS tiny) as v, + LATERAL (VALUES + (10.5::float8, -big, big, 1), + (10.5::float8, -big, big, 2), + (10.5::float8, -big, big, 3), + (big / 4, -big / 2, big / 2, 10), + (10.5::float8, big, -big, 1), + (10.5::float8, big, -big, 2), + (10.5::float8, big, -big, 3), + (big / 4, big / 2, -big / 2, 10), + (0, 0, tiny, 4), + (tiny, 0, tiny, 4), + (0, 0, 1, 2147483647), + (1, 1, 0, 2147483647) + ) as sample(oper, low, high, cnt) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ...) v, LATERAL (VALUES (...)) sample(oper, low, high, cnt)" +== 686 +-- truncate_limit: 100 +-- These fail because the result would be out of int32 range: +SELECT width_bucket(1::float8, 0, 1, 2147483647) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(1::float8, 0, 1, 2147483647)" +== 687 +-- truncate_limit: 100 +SELECT width_bucket(0::float8, 1, 0, 2147483647) +-- +FUNCTION: name="width_bucket" function="width_bucket" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT width_bucket(0::float8, 1, 0, 2147483647)" +== 688 +-- truncate_limit: 100 +|-- +-- TO_CHAR() +|-- +SELECT to_char(val, '9G999G999G999G999G999') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, '9G999G999G999G999G999') FROM num_data" +== 689 +-- truncate_limit: 100 +SELECT to_char(val, '9G999G999G999G999G999D999G999G999G999G999') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, '9G999G999G999G999G999D999G999G999G999G999') FROM num_data" +== 690 +-- truncate_limit: 100 +SELECT to_char(val, '9999999999999999.999999999999999PR') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, '9999999999999999.999999999999999PR') FROM num_data" +== 691 +-- truncate_limit: 100 +SELECT to_char(val, '9999999999999999.999999999999999S') + FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, '9999999999999999.999999999999999S') FROM num_data" +== 692 +-- truncate_limit: 100 +SELECT to_char(val, 'MI9999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'MI9999999999999999.999999999999999') FROM num_data" +== 693 +-- truncate_limit: 100 +SELECT to_char(val, 'FMS9999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FMS9999999999999999.999999999999999') FROM num_data" +== 694 +-- truncate_limit: 100 +SELECT to_char(val, 'FM9999999999999999.999999999999999THPR') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM9999999999999999.999999999999999THPR') FROM num_data" +== 695 +-- truncate_limit: 100 +SELECT to_char(val, 'SG9999999999999999.999999999999999th') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'SG9999999999999999.999999999999999th') FROM num_data" +== 696 +-- truncate_limit: 100 +SELECT to_char(val, '0999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, '0999999999999999.999999999999999') FROM num_data" +== 697 +-- truncate_limit: 100 +SELECT to_char(val, 'S0999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'S0999999999999999.999999999999999') FROM num_data" +== 698 +-- truncate_limit: 100 +SELECT to_char(val, 'FM0999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM0999999999999999.999999999999999') FROM num_data" +== 699 +-- truncate_limit: 100 +SELECT to_char(val, 'FM9999999999999999.099999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM9999999999999999.099999999999999') FROM num_data" +== 700 +-- truncate_limit: 100 +SELECT to_char(val, 'FM9999999999990999.990999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM9999999999990999.990999999999999') FROM num_data" +== 701 +-- truncate_limit: 100 +SELECT to_char(val, 'FM0999999999999999.999909999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM0999999999999999.999909999999999') FROM num_data" +== 702 +-- truncate_limit: 100 +SELECT to_char(val, 'FM9999999990999999.099999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM9999999990999999.099999999999999') FROM num_data" +== 703 +-- truncate_limit: 100 +SELECT to_char(val, 'L9999999999999999.099999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'L9999999999999999.099999999999999') FROM num_data" +== 704 +-- truncate_limit: 100 +SELECT to_char(val, 'FM9999999999999999.99999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM9999999999999999.99999999999999') FROM num_data" +== 705 +-- truncate_limit: 100 +SELECT to_char(val, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_data" +== 706 +-- truncate_limit: 100 +SELECT to_char(val, 'FMS 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_data" +== 707 +-- truncate_limit: 100 +SELECT to_char(val, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_data" +== 708 +-- truncate_limit: 100 +SELECT to_char(val, '999999SG9999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, '999999SG9999999999') FROM num_data" +== 709 +-- truncate_limit: 100 +SELECT to_char(val, 'FM9999999999999999.999999999999999') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, 'FM9999999999999999.999999999999999') FROM num_data" +== 710 +-- truncate_limit: 100 +SELECT to_char(val, '9.999EEEE') FROM num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(val, '9.999EEEE') FROM num_data" +== 711 +-- truncate_limit: 100 +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, '9.999EEEE') as numeric, + to_char(val::float8, '9.999EEEE') as float8, + to_char(val::float4, '9.999EEEE') as float4 +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(val) AS (...) SELECT ... FROM v" +== 712 +-- truncate_limit: 100 +WITH v(exp) AS + (VALUES(-16379),(-16378),(-1234),(-789),(-45),(-5),(-4),(-3),(-2),(-1),(0), + (1),(2),(3),(4),(5),(38),(275),(2345),(45678),(131070),(131071)) +SELECT exp, + to_char(('1.2345e'||exp)::numeric, '9.999EEEE') as numeric +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(exp) AS (...) SELECT ... FROM v" +== 713 +-- truncate_limit: 100 +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, 'MI9999999999.99') as numeric, + to_char(val::float8, 'MI9999999999.99') as float8, + to_char(val::float4, 'MI9999999999.99') as float4 +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(val) AS (...) SELECT ... FROM v" +== 714 +-- truncate_limit: 100 +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, 'MI99.99') as numeric, + to_char(val::float8, 'MI99.99') as float8, + to_char(val::float4, 'MI99.99') as float4 +FROM v +-- +CTE: "v" +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH v(val) AS (...) SELECT ... FROM v" +== 715 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'FM999.9') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, 'FM999.9')" +== 716 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'FM999.') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, 'FM999.')" +== 717 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'FM999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, 'FM999')" +== 718 +-- truncate_limit: 100 +SELECT to_char('12345678901'::float8, 'FM9999999999D9999900000000000000000') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('12345678901'::float8, 'FM9999999999D9999900000000000000000')" +== 719 +-- truncate_limit: 100 +-- Check parsing of literal text in a format string +SELECT to_char('100'::numeric, 'foo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, 'foo999')" +== 720 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f\oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\\\\oo999')" +== 721 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f\\oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\\\\\\\\oo999')" +== 722 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f\"oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\\\\\"oo999')" +== 723 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f\\"oo999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\\\\\\\\\"oo999')" +== 724 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f"ool"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, 'f\"ool\"999')" +== 725 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f"\ool"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\"\\\\ool\"999')" +== 726 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f"\\ool"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\"\\\\\\\\ool\"999')" +== 727 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f"ool\"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\"ool\\\\\"999')" +== 728 +-- truncate_limit: 100 +SELECT to_char('100'::numeric, 'f"ool\\"999') +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char('100'::numeric, E'f\"ool\\\\\\\\\"999')" +== 729 +-- truncate_limit: 100 +-- TO_NUMBER() +|-- +SET lc_numeric = 'C' +-- +STMT: VariableSetStmt +TRUNCATED: "SET lc_numeric TO \"C\"" +== 730 +-- truncate_limit: 100 +SELECT to_number('-34,338,492', '99G999G999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('-34,338,492', '99G999G999')" +== 731 +-- truncate_limit: 100 +SELECT to_number('-34,338,492.654,878', '99G999G999D999G999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('-34,338,492.654,878', '99G999G999D999G999')" +== 732 +-- truncate_limit: 100 +SELECT to_number('<564646.654564>', '999999.999999PR') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('<564646.654564>', '999999.999999PR')" +== 733 +-- truncate_limit: 100 +SELECT to_number('0.00001-', '9.999999S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('0.00001-', '9.999999S')" +== 734 +-- truncate_limit: 100 +SELECT to_number('5.01-', 'FM9.999999S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('5.01-', 'FM9.999999S')" +== 735 +-- truncate_limit: 100 +SELECT to_number('5.01-', 'FM9.999999MI') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('5.01-', 'FM9.999999MI')" +== 736 +-- truncate_limit: 100 +SELECT to_number('5 4 4 4 4 8 . 7 8', '9 9 9 9 9 9 . 9 9') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('5 4 4 4 4 8 . 7 8', '9 9 9 9 9 9 . 9 9')" +== 737 +-- truncate_limit: 100 +SELECT to_number('.01', 'FM9.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('.01', 'FM9.99')" +== 738 +-- truncate_limit: 100 +SELECT to_number('.0', '99999999.99999999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('.0', '99999999.99999999')" +== 739 +-- truncate_limit: 100 +SELECT to_number('0', '99.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('0', '99.99')" +== 740 +-- truncate_limit: 100 +SELECT to_number('.-01', 'S99.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('.-01', 'S99.99')" +== 741 +-- truncate_limit: 100 +SELECT to_number('.01-', '99.99S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('.01-', '99.99S')" +== 742 +-- truncate_limit: 100 +SELECT to_number(' . 0 1-', ' 9 9 . 9 9 S') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number(' . 0 1-', ' 9 9 . 9 9 S')" +== 743 +-- truncate_limit: 100 +SELECT to_number('34,50','999,99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('34,50', '999,99')" +== 744 +-- truncate_limit: 100 +SELECT to_number('123,000','999G') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('123,000', '999G')" +== 745 +-- truncate_limit: 100 +SELECT to_number('123456','999G999') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('123456', '999G999')" +== 746 +-- truncate_limit: 100 +SELECT to_number('$1234.56','L9,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('$1234.56', 'L9,999.99')" +== 747 +-- truncate_limit: 100 +SELECT to_number('$1234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('$1234.56', 'L99,999.99')" +== 748 +-- truncate_limit: 100 +SELECT to_number('$1,234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('$1,234.56', 'L99,999.99')" +== 749 +-- truncate_limit: 100 +SELECT to_number('1234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('1234.56', 'L99,999.99')" +== 750 +-- truncate_limit: 100 +SELECT to_number('1,234.56','L99,999.99') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('1,234.56', 'L99,999.99')" +== 751 +-- truncate_limit: 100 +SELECT to_number('42nd', '99th') +-- +FUNCTION: name="to_number" function="to_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_number('42nd', '99th')" +== 752 +-- truncate_limit: 100 +RESET lc_numeric +-- +STMT: VariableSetStmt +TRUNCATED: "RESET lc_numeric" +== 753 +-- truncate_limit: 100 +|-- +-- Input syntax +|-- + +CREATE TABLE num_input_test (n1 numeric) +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_input_test (n1 numeric)" +== 754 +-- truncate_limit: 100 +-- good inputs +INSERT INTO num_input_test(n1) VALUES (' 123') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' 123')" +== 755 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' 3245874 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' 3245874 ')" +== 756 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' -93853') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' -93853')" +== 757 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('555.50') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('555.50')" +== 758 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('-555.50') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('-555.50')" +== 759 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('NaN ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('NaN ')" +== 760 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' nan') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' nan')" +== 761 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' inf ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' inf ')" +== 762 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' +inf ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' +inf ')" +== 763 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' -inf ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' -inf ')" +== 764 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' Infinity ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' Infinity ')" +== 765 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' +inFinity ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' +inFinity ')" +== 766 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' -INFINITY ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' -INFINITY ')" +== 767 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('12_000_000_000') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('12_000_000_000')" +== 768 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('12_000.123_456') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('12_000.123_456')" +== 769 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('23_000_000_000e-1_0') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('23_000_000_000e-1_0')" +== 770 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('.000_000_000_123e1_0') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('.000_000_000_123e1_0')" +== 771 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('.000_000_000_123e+1_1') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('.000_000_000_123e+1_1')" +== 772 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0b10001110111100111100001001010') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0b10001110111100111100001001010')" +== 773 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' -0B_1010_1011_0101_0100_1010_1001_1000_1100_1110_1011_0001_1111_0000_1010_1101_0010 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (...)" +== 774 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' +0o112402761777 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' +0o112402761777 ')" +== 775 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('-0O0012_5524_5230_6334_3167_0261') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('-0O0012_5524_5230_6334_3167_0261')" +== 776 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('-0x0000000000000000000000000deadbeef') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('-0x0000000000000000000000000deadbeef')" +== 777 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' 0X_30b1_F33a_6DF0_bD4E_64DF_9BdA_7D15 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' 0X_30b1_F33a_6DF0_bD4E_64DF_9BdA_7D15 ')" +== 778 +-- truncate_limit: 100 +-- bad inputs +INSERT INTO num_input_test(n1) VALUES (' ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' ')" +== 779 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' 1234 %') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' 1234 %')" +== 780 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('xyz') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('xyz')" +== 781 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('- 1234') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('- 1234')" +== 782 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('5 . 0') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('5 . 0')" +== 783 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('5. 0 ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('5. 0 ')" +== 784 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('')" +== 785 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES (' N aN ') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES (' N aN ')" +== 786 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('+NaN') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('+NaN')" +== 787 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('-NaN') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('-NaN')" +== 788 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('+ infinity') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('+ infinity')" +== 789 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('_123') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('_123')" +== 790 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('123_') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('123_')" +== 791 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('12__34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('12__34')" +== 792 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('123_.456') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('123_.456')" +== 793 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('123._456') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('123._456')" +== 794 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('1.2e_34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('1.2e_34')" +== 795 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('1.2e34_') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('1.2e34_')" +== 796 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('1.2e3__4') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('1.2e3__4')" +== 797 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0b1112') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0b1112')" +== 798 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0c1112') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0c1112')" +== 799 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0o12345678') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0o12345678')" +== 800 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0x1eg') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0x1eg')" +== 801 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0x12.34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0x12.34')" +== 802 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0x__1234') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0x__1234')" +== 803 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0x1234_') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0x1234_')" +== 804 +-- truncate_limit: 100 +INSERT INTO num_input_test(n1) VALUES ('0x12__34') +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_input_test (n1) VALUES ('0x12__34')" +== 805 +-- truncate_limit: 100 +SELECT * FROM num_input_test +-- +TABLE: name="num_input_test" schema="" table="num_input_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM num_input_test" +== 806 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('34.5', 'numeric') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('34.5', 'numeric')" +== 807 +-- truncate_limit: 100 +SELECT pg_input_is_valid('34xyz', 'numeric') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('34xyz', 'numeric')" +== 808 +-- truncate_limit: 100 +SELECT pg_input_is_valid('1e400000', 'numeric') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1e400000', 'numeric')" +== 809 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1e400000', 'numeric') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1e400000', 'numeric')" +== 810 +-- truncate_limit: 100 +SELECT pg_input_is_valid('1234.567', 'numeric(8,4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1234.567', 'numeric(8,4)')" +== 811 +-- truncate_limit: 100 +SELECT pg_input_is_valid('1234.567', 'numeric(7,4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1234.567', 'numeric(7,4)')" +== 812 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1234.567', 'numeric(7,4)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1234.567', 'numeric(7,4)')" +== 813 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('0x1234.567', 'numeric') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('0x1234.567', 'numeric')" +== 814 +-- truncate_limit: 100 +|-- +-- Test precision and scale typemods +|-- + +CREATE TABLE num_typemod_test ( + millions numeric(3, -6), + thousands numeric(3, -3), + units numeric(3, 0), + thousandths numeric(3, 3), + millionths numeric(3, 6) +) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_typemod_test (millions numeric(3, -6), thousands numeric(3, -3), units numeric(3..." +== 815 +-- truncate_limit: 100 +-- rounding of valid inputs +INSERT INTO num_typemod_test VALUES (123456, 123, 0.123, 0.000123, 0.000000123) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (123456, 123, 0.123, 0.000123, 0.000000123)" +== 816 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES (654321, 654, 0.654, 0.000654, 0.000000654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (654321, 654, 0.654, 0.000654, 0.000000654)" +== 817 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES (2345678, 2345, 2.345, 0.002345, 0.000002345) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (2345678, 2345, 2.345, 0.002345, 0.000002345)" +== 818 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES (7654321, 7654, 7.654, 0.007654, 0.000007654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (7654321, 7654, 7.654, 0.007654, 0.000007654)" +== 819 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES (12345678, 12345, 12.345, 0.012345, 0.000012345) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (12345678, 12345, 12.345, 0.012345, 0.000012345)" +== 820 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES (87654321, 87654, 87.654, 0.087654, 0.000087654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (87654321, 87654, 87.654, 0.087654, 0.000087654)" +== 821 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES (123456789, 123456, 123.456, 0.123456, 0.000123456) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (123456789, 123456, 123.456, 0.123456, 0.000123456)" +== 822 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES (987654321, 987654, 987.654, 0.987654, 0.000987654) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES (987654321, 987654, 987.654, 0.987654, 0.000987654)" +== 823 +-- truncate_limit: 100 +INSERT INTO num_typemod_test VALUES ('NaN', 'NaN', 'NaN', 'NaN', 'NaN') +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test VALUES ('NaN', 'NaN', 'NaN', 'NaN', 'NaN')" +== 824 +-- truncate_limit: 100 +SELECT scale(millions), * FROM num_typemod_test ORDER BY millions +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=Select +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(millions), * FROM num_typemod_test ORDER BY millions" +== 825 +-- truncate_limit: 100 +-- invalid inputs +INSERT INTO num_typemod_test (millions) VALUES ('inf') +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test (millions) VALUES ('inf')" +== 826 +-- truncate_limit: 100 +INSERT INTO num_typemod_test (millions) VALUES (999500000) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test (millions) VALUES (999500000)" +== 827 +-- truncate_limit: 100 +INSERT INTO num_typemod_test (thousands) VALUES (999500) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test (thousands) VALUES (999500)" +== 828 +-- truncate_limit: 100 +INSERT INTO num_typemod_test (units) VALUES (999.5) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test (units) VALUES (999.5)" +== 829 +-- truncate_limit: 100 +INSERT INTO num_typemod_test (thousandths) VALUES (0.9995) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test (thousandths) VALUES (0.9995)" +== 830 +-- truncate_limit: 100 +INSERT INTO num_typemod_test (millionths) VALUES (0.0009995) +-- +TABLE: name="num_typemod_test" schema="" table="num_typemod_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_typemod_test (millionths) VALUES (0.0009995)" +== 831 +-- truncate_limit: 100 +|-- +-- Test some corner cases for multiplication +|-- + +select 4790999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 832 +-- truncate_limit: 100 +select 4789999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 833 +-- truncate_limit: 100 +select 4770999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 834 +-- truncate_limit: 100 +select 4769999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 835 +-- truncate_limit: 100 +select trim_scale((0.1 - 2e-16383) * (0.1 - 3e-16383)) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale((0.1 - 2e-16383) * (0.1 - 3e-16383))" +== 836 +-- truncate_limit: 100 +|-- +-- Test some corner cases for division +|-- + +select 999999999999999999999::numeric/1000000000000000000000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (999999999999999999999)::numeric / 1000000000000000000000" +== 837 +-- truncate_limit: 100 +select div(999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div((999999999999999999999)::numeric, 1000000000000000000000)" +== 838 +-- truncate_limit: 100 +select mod(999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mod((999999999999999999999)::numeric, 1000000000000000000000)" +== 839 +-- truncate_limit: 100 +select div(-9999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div(- (9999999999999999999999)::numeric, 1000000000000000000000)" +== 840 +-- truncate_limit: 100 +select mod(-9999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mod(- (9999999999999999999999)::numeric, 1000000000000000000000)" +== 841 +-- truncate_limit: 100 +select div(-9999999999999999999999::numeric,1000000000000000000000)*1000000000000000000000 + mod(-9999999999999999999999::numeric,1000000000000000000000) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 842 +-- truncate_limit: 100 +select mod (70.0,70) +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mod(70.0, 70)" +== 843 +-- truncate_limit: 100 +select div (70.0,70) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div(70.0, 70)" +== 844 +-- truncate_limit: 100 +select 70.0 / 70 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 70.0 / 70" +== 845 +-- truncate_limit: 100 +select 12345678901234567890 % 123 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 12345678901234567890 % 123" +== 846 +-- truncate_limit: 100 +select 12345678901234567890 / 123 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 12345678901234567890 / 123" +== 847 +-- truncate_limit: 100 +select div(12345678901234567890, 123) +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT div(12345678901234567890, 123)" +== 848 +-- truncate_limit: 100 +select div(12345678901234567890, 123) * 123 + 12345678901234567890 % 123 +-- +FUNCTION: name="div" function="div" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (div(12345678901234567890, 123) * 123) + (12345678901234567890 % 123)" +== 849 +-- truncate_limit: 100 +|-- +-- Test some corner cases for square root +|-- + +select sqrt(1.000000000000003::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((1.000000000000003)::numeric)" +== 850 +-- truncate_limit: 100 +select sqrt(1.000000000000004::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((1.000000000000004)::numeric)" +== 851 +-- truncate_limit: 100 +select sqrt(96627521408608.56340355805::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((96627521408608.56340355805)::numeric)" +== 852 +-- truncate_limit: 100 +select sqrt(96627521408608.56340355806::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((96627521408608.56340355806)::numeric)" +== 853 +-- truncate_limit: 100 +select sqrt(515549506212297735.073688290367::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((515549506212297735.073688290367)::numeric)" +== 854 +-- truncate_limit: 100 +select sqrt(515549506212297735.073688290368::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((515549506212297735.073688290368)::numeric)" +== 855 +-- truncate_limit: 100 +select sqrt(8015491789940783531003294973900306::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((8015491789940783531003294973900306)::numeric)" +== 856 +-- truncate_limit: 100 +select sqrt(8015491789940783531003294973900307::numeric) +-- +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sqrt((8015491789940783531003294973900307)::numeric)" +== 857 +-- truncate_limit: 100 +|-- +-- Test code path for raising to integer powers +|-- + +select 10.0 ^ -2147483648 as rounds_to_zero +-- +STMT: SelectStmt +TRUNCATED: "SELECT 10.0 ^ -2147483648 AS rounds_to_zero" +== 858 +-- truncate_limit: 100 +select 10.0 ^ -2147483647 as rounds_to_zero +-- +STMT: SelectStmt +TRUNCATED: "SELECT 10.0 ^ -2147483647 AS rounds_to_zero" +== 859 +-- truncate_limit: 100 +select 10.0 ^ 2147483647 as overflows +-- +STMT: SelectStmt +TRUNCATED: "SELECT 10.0 ^ 2147483647 AS overflows" +== 860 +-- truncate_limit: 100 +select 117743296169.0 ^ 1000000000 as overflows +-- +STMT: SelectStmt +TRUNCATED: "SELECT 117743296169.0 ^ 1000000000 AS overflows" +== 861 +-- truncate_limit: 100 +-- cases that used to return inaccurate results +select 3.789 ^ 21.0000000000000000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3.789 ^ 21.0000000000000000" +== 862 +-- truncate_limit: 100 +select 3.789 ^ 35.0000000000000000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3.789 ^ 35.0000000000000000" +== 863 +-- truncate_limit: 100 +select 1.2 ^ 345 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1.2 ^ 345" +== 864 +-- truncate_limit: 100 +select 0.12 ^ (-20) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0.12 ^ -20" +== 865 +-- truncate_limit: 100 +select 1.000000000123 ^ (-2147483648) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1.000000000123 ^ -2147483648" +== 866 +-- truncate_limit: 100 +select coalesce(nullif(0.9999999999 ^ 23300000000000, 0), 0) as rounds_to_zero +-- +STMT: SelectStmt +TRUNCATED: "SELECT COALESCE(NULLIF(0.9999999999 ^ 23300000000000, 0), 0) AS rounds_to_zero" +== 867 +-- truncate_limit: 100 +select round(((1 - 1.500012345678e-1000) ^ 1.45e1003) * 1e1000) +-- +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(((1 - 1.500012345678e-1000) ^ 1.45e1003) * 1e1000)" +== 868 +-- truncate_limit: 100 +-- cases that used to error out +select 0.12 ^ (-25) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0.12 ^ -25" +== 869 +-- truncate_limit: 100 +select 0.5678 ^ (-85) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0.5678 ^ -85" +== 870 +-- truncate_limit: 100 +select coalesce(nullif(0.9999999999 ^ 70000000000000, 0), 0) as underflows +-- +STMT: SelectStmt +TRUNCATED: "SELECT COALESCE(NULLIF(0.9999999999 ^ 70000000000000, 0), 0) AS underflows" +== 871 +-- truncate_limit: 100 +-- negative base to integer powers +select (-1.0) ^ 2147483646 +-- +STMT: SelectStmt +TRUNCATED: "SELECT -1.0 ^ 2147483646" +== 872 +-- truncate_limit: 100 +select (-1.0) ^ 2147483647 +-- +STMT: SelectStmt +TRUNCATED: "SELECT -1.0 ^ 2147483647" +== 873 +-- truncate_limit: 100 +select (-1.0) ^ 2147483648 +-- +STMT: SelectStmt +TRUNCATED: "SELECT -1.0 ^ 2147483648" +== 874 +-- truncate_limit: 100 +select (-1.0) ^ 1000000000000000 +-- +STMT: SelectStmt +TRUNCATED: "SELECT -1.0 ^ 1000000000000000" +== 875 +-- truncate_limit: 100 +select (-1.0) ^ 1000000000000001 +-- +STMT: SelectStmt +TRUNCATED: "SELECT -1.0 ^ 1000000000000001" +== 876 +-- truncate_limit: 100 +-- integer powers of 10 +select n, 10.0 ^ n as "10^n", (10.0 ^ n) * (10.0 ^ (-n)) = 1 as ok +from generate_series(-20, 20) n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(-20, 20) n" +== 877 +-- truncate_limit: 100 +|-- +-- Tests for raising to non-integer powers +|-- + +-- special cases +select 0.0 ^ 0.0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0.0 ^ 0.0" +== 878 +-- truncate_limit: 100 +select (-12.34) ^ 0.0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT -12.34 ^ 0.0" +== 879 +-- truncate_limit: 100 +select 12.34 ^ 0.0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 12.34 ^ 0.0" +== 880 +-- truncate_limit: 100 +select 0.0 ^ 12.34 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0.0 ^ 12.34" +== 881 +-- truncate_limit: 100 +-- NaNs +select 'NaN'::numeric ^ 'NaN'::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric ^ 'NaN'::numeric" +== 882 +-- truncate_limit: 100 +select 'NaN'::numeric ^ 0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric ^ 0" +== 883 +-- truncate_limit: 100 +select 'NaN'::numeric ^ 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'NaN'::numeric ^ 1" +== 884 +-- truncate_limit: 100 +select 0 ^ 'NaN'::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0 ^ 'NaN'::numeric" +== 885 +-- truncate_limit: 100 +select 1 ^ 'NaN'::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 ^ 'NaN'::numeric" +== 886 +-- truncate_limit: 100 +-- invalid inputs +select 0.0 ^ (-12.34) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0.0 ^ -12.34" +== 887 +-- truncate_limit: 100 +select (-12.34) ^ 1.2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT -12.34 ^ 1.2" +== 888 +-- truncate_limit: 100 +-- cases that used to generate inaccurate results +select 32.1 ^ 9.8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 32.1 ^ 9.8" +== 889 +-- truncate_limit: 100 +select 32.1 ^ (-9.8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 32.1 ^ -9.8" +== 890 +-- truncate_limit: 100 +select 12.3 ^ 45.6 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 12.3 ^ 45.6" +== 891 +-- truncate_limit: 100 +select 12.3 ^ (-45.6) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 12.3 ^ -45.6" +== 892 +-- truncate_limit: 100 +-- big test +select 1.234 ^ 5678 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1.234 ^ 5678" +== 893 +-- truncate_limit: 100 +|-- +-- Tests for EXP() +|-- + +-- special cases +select exp(0.0) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(0.0)" +== 894 +-- truncate_limit: 100 +select exp(1.0) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(1.0)" +== 895 +-- truncate_limit: 100 +select exp(1.0::numeric(71,70)) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp((1.0)::numeric(71, 70))" +== 896 +-- truncate_limit: 100 +select exp('nan'::numeric) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp('nan'::numeric)" +== 897 +-- truncate_limit: 100 +select exp('inf'::numeric) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp('inf'::numeric)" +== 898 +-- truncate_limit: 100 +select exp('-inf'::numeric) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp('-inf'::numeric)" +== 899 +-- truncate_limit: 100 +select coalesce(nullif(exp(-5000::numeric), 0), 0) as rounds_to_zero +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT COALESCE(NULLIF(exp(- 5000::numeric), 0), 0) AS rounds_to_zero" +== 900 +-- truncate_limit: 100 +select coalesce(nullif(exp(-10000::numeric), 0), 0) as underflows +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT COALESCE(NULLIF(exp(- 10000::numeric), 0), 0) AS underflows" +== 901 +-- truncate_limit: 100 +-- cases that used to generate inaccurate results +select exp(32.999) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(32.999)" +== 902 +-- truncate_limit: 100 +select exp(-32.999) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(-32.999)" +== 903 +-- truncate_limit: 100 +select exp(123.456) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(123.456)" +== 904 +-- truncate_limit: 100 +select exp(-123.456) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(-123.456)" +== 905 +-- truncate_limit: 100 +-- big test +select exp(1234.5678) +-- +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exp(1234.5678)" +== 906 +-- truncate_limit: 100 +|-- +-- Tests for generate_series +|-- +select * from generate_series(0.0::numeric, 4.0::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series((0.0)::numeric, (4.0)::numeric)" +== 907 +-- truncate_limit: 100 +select * from generate_series(0.1::numeric, 4.0::numeric, 1.3::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series((0.1)::numeric, (4.0)::numeric, (1.3)::numeric)" +== 908 +-- truncate_limit: 100 +select * from generate_series(4.0::numeric, -1.5::numeric, -2.2::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series((4.0)::numeric, - (1.5)::numeric, - (2.2)::numeric)" +== 909 +-- truncate_limit: 100 +-- Trigger errors +select * from generate_series(-100::numeric, 100::numeric, 0::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(- 100::numeric, 100::numeric, 0::numeric)" +== 910 +-- truncate_limit: 100 +select * from generate_series(-100::numeric, 100::numeric, 'nan'::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(- 100::numeric, 100::numeric, 'nan'::numeric)" +== 911 +-- truncate_limit: 100 +select * from generate_series('nan'::numeric, 100::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('nan'::numeric, 100::numeric, 10::numeric)" +== 912 +-- truncate_limit: 100 +select * from generate_series(0::numeric, 'nan'::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(0::numeric, 'nan'::numeric, 10::numeric)" +== 913 +-- truncate_limit: 100 +select * from generate_series('inf'::numeric, 'inf'::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('inf'::numeric, 'inf'::numeric, 10::numeric)" +== 914 +-- truncate_limit: 100 +select * from generate_series(0::numeric, 'inf'::numeric, 10::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(0::numeric, 'inf'::numeric, 10::numeric)" +== 915 +-- truncate_limit: 100 +select * from generate_series(0::numeric, '42'::numeric, '-inf'::numeric) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(0::numeric, '42'::numeric, '-inf'::numeric)" +== 916 +-- truncate_limit: 100 +-- Checks maximum, output is truncated +select (i / (10::numeric ^ 131071))::numeric(1,0) + from generate_series(6 * (10::numeric ^ 131071), + 9 * (10::numeric ^ 131071), + 10::numeric ^ 131071) as a(i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(6 * (10::numeric ^ 131071), 9 * (10::numeric ^ 131071), 10::numer..." +== 917 +-- truncate_limit: 100 +-- Check usage with variables +select * from generate_series(1::numeric, 3::numeric) i, generate_series(i,3) j +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(1::numeric, 3::numeric) i, generate_series(i, 3) j" +== 918 +-- truncate_limit: 100 +select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,i) j +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(1::numeric, 3::numeric) i, generate_series(1, i) j" +== 919 +-- truncate_limit: 100 +select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,5,i) j +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(1::numeric, 3::numeric) i, generate_series(1, 5, i) j" +== 920 +-- truncate_limit: 100 +|-- +-- Tests for LN() +|-- + +-- Invalid inputs +select ln(-12.34) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(-12.34)" +== 921 +-- truncate_limit: 100 +select ln(0.0) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(0.0)" +== 922 +-- truncate_limit: 100 +-- Some random tests +select ln(1.2345678e-28) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(1.2345678e-28)" +== 923 +-- truncate_limit: 100 +select ln(0.0456789) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(0.0456789)" +== 924 +-- truncate_limit: 100 +select ln(0.349873948359354029493948309745709580730482050975) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(0.349873948359354029493948309745709580730482050975)" +== 925 +-- truncate_limit: 100 +select ln(0.99949452) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(0.99949452)" +== 926 +-- truncate_limit: 100 +select ln(1.00049687395) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(1.00049687395)" +== 927 +-- truncate_limit: 100 +select ln(1234.567890123456789) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(1234.567890123456789)" +== 928 +-- truncate_limit: 100 +select ln(5.80397490724e5) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(5.80397490724e5)" +== 929 +-- truncate_limit: 100 +select ln(9.342536355e34) +-- +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ln(9.342536355e34)" +== 930 +-- truncate_limit: 100 +|-- +-- Tests for LOG() (base 10) +|-- + +-- invalid inputs +select log(-12.34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(-12.34)" +== 931 +-- truncate_limit: 100 +select log(0.0) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(0.0)" +== 932 +-- truncate_limit: 100 +-- some random tests +select log(1.234567e-89) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(1.234567e-89)" +== 933 +-- truncate_limit: 100 +select log(3.4634998359873254962349856073435545) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(3.4634998359873254962349856073435545)" +== 934 +-- truncate_limit: 100 +select log(9.999999999999999999) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(9.999999999999999999)" +== 935 +-- truncate_limit: 100 +select log(10.00000000000000000) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(10.00000000000000000)" +== 936 +-- truncate_limit: 100 +select log(10.00000000000000001) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(10.00000000000000001)" +== 937 +-- truncate_limit: 100 +select log(590489.45235237) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(590489.45235237)" +== 938 +-- truncate_limit: 100 +|-- +-- Tests for LOG() (arbitrary base) +|-- + +-- invalid inputs +select log(-12.34, 56.78) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(-12.34, 56.78)" +== 939 +-- truncate_limit: 100 +select log(-12.34, -56.78) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(-12.34, -56.78)" +== 940 +-- truncate_limit: 100 +select log(12.34, -56.78) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(12.34, -56.78)" +== 941 +-- truncate_limit: 100 +select log(0.0, 12.34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(0.0, 12.34)" +== 942 +-- truncate_limit: 100 +select log(12.34, 0.0) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(12.34, 0.0)" +== 943 +-- truncate_limit: 100 +select log(1.0, 12.34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(1.0, 12.34)" +== 944 +-- truncate_limit: 100 +-- some random tests +select log(1.23e-89, 6.4689e45) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(1.23e-89, 6.4689e45)" +== 945 +-- truncate_limit: 100 +select log(0.99923, 4.58934e34) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(0.99923, 4.58934e34)" +== 946 +-- truncate_limit: 100 +select log(1.000016, 8.452010e18) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(1.000016, 8.452010e18)" +== 947 +-- truncate_limit: 100 +select log(3.1954752e47, 9.4792021e-73) +-- +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT log(3.1954752e47, 9.4792021e-73)" +== 948 +-- truncate_limit: 100 +|-- +-- Tests for scale() +|-- + +select scale(numeric 'NaN') +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale('NaN'::numeric)" +== 949 +-- truncate_limit: 100 +select scale(numeric 'inf') +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale('inf'::numeric)" +== 950 +-- truncate_limit: 100 +select scale(NULL::numeric) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(NULL::numeric)" +== 951 +-- truncate_limit: 100 +select scale(1.12) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(1.12)" +== 952 +-- truncate_limit: 100 +select scale(0) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(0)" +== 953 +-- truncate_limit: 100 +select scale(0.00) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(0.00)" +== 954 +-- truncate_limit: 100 +select scale(1.12345) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(1.12345)" +== 955 +-- truncate_limit: 100 +select scale(110123.12475871856128) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(110123.12475871856128)" +== 956 +-- truncate_limit: 100 +select scale(-1123.12471856128) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(-1123.12471856128)" +== 957 +-- truncate_limit: 100 +select scale(-13.000000000000000) +-- +FUNCTION: name="scale" function="scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT scale(-13.000000000000000)" +== 958 +-- truncate_limit: 100 +|-- +-- Tests for min_scale() +|-- + +select min_scale(numeric 'NaN') is NULL +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale('NaN'::numeric) IS NULL" +== 959 +-- truncate_limit: 100 +-- should be true +select min_scale(numeric 'inf') is NULL +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale('inf'::numeric) IS NULL" +== 960 +-- truncate_limit: 100 +-- should be true +select min_scale(0) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(0)" +== 961 +-- truncate_limit: 100 +-- no digits +select min_scale(0.00) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(0.00)" +== 962 +-- truncate_limit: 100 +-- no digits again +select min_scale(1.0) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1.0)" +== 963 +-- truncate_limit: 100 +-- no scale +select min_scale(1.1) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1.1)" +== 964 +-- truncate_limit: 100 +-- scale 1 +select min_scale(1.12) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1.12)" +== 965 +-- truncate_limit: 100 +-- scale 2 +select min_scale(1.123) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1.123)" +== 966 +-- truncate_limit: 100 +-- scale 3 +select min_scale(1.1234) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1.1234)" +== 967 +-- truncate_limit: 100 +-- scale 4, filled digit +select min_scale(1.12345) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1.12345)" +== 968 +-- truncate_limit: 100 +-- scale 5, 2 NDIGITS +select min_scale(1.1000) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1.1000)" +== 969 +-- truncate_limit: 100 +-- 1 pos in NDIGITS +select min_scale(1e100) +-- +FUNCTION: name="min_scale" function="min_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min_scale(1e100)" +== 970 +-- truncate_limit: 100 +-- very big number + +|-- +-- Tests for trim_scale() +|-- + +select trim_scale(numeric 'NaN') +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale('NaN'::numeric)" +== 971 +-- truncate_limit: 100 +select trim_scale(numeric 'inf') +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale('inf'::numeric)" +== 972 +-- truncate_limit: 100 +select trim_scale(1.120) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(1.120)" +== 973 +-- truncate_limit: 100 +select trim_scale(0) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(0)" +== 974 +-- truncate_limit: 100 +select trim_scale(0.00) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(0.00)" +== 975 +-- truncate_limit: 100 +select trim_scale(1.1234500) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(1.1234500)" +== 976 +-- truncate_limit: 100 +select trim_scale(110123.12475871856128000) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(110123.12475871856128000)" +== 977 +-- truncate_limit: 100 +select trim_scale(-1123.124718561280000000) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(-1123.124718561280000000)" +== 978 +-- truncate_limit: 100 +select trim_scale(-13.00000000000000000000) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(-13.00000000000000000000)" +== 979 +-- truncate_limit: 100 +select trim_scale(1e100) +-- +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(1e100)" +== 980 +-- truncate_limit: 100 +|-- +-- Tests for SUM() +|-- + +-- cases that need carry propagation +SELECT SUM(9999::numeric) FROM generate_series(1, 100000) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(9999::numeric) FROM generate_series(1, 100000)" +== 981 +-- truncate_limit: 100 +SELECT SUM((-9999)::numeric) FROM generate_series(1, 100000) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum((-9999)::numeric) FROM generate_series(1, 100000)" +== 982 +-- truncate_limit: 100 +|-- +-- Tests for VARIANCE() +|-- +CREATE TABLE num_variance (a numeric) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_variance (a numeric)" +== 983 +-- truncate_limit: 100 +INSERT INTO num_variance VALUES (0) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_variance VALUES (0)" +== 984 +-- truncate_limit: 100 +INSERT INTO num_variance VALUES (3e-500) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_variance VALUES (3e-500)" +== 985 +-- truncate_limit: 100 +INSERT INTO num_variance VALUES (-3e-500) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_variance VALUES (-3e-500)" +== 986 +-- truncate_limit: 100 +INSERT INTO num_variance VALUES (4e-500 - 1e-16383) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_variance VALUES (4e-500 - 1e-16383)" +== 987 +-- truncate_limit: 100 +INSERT INTO num_variance VALUES (-4e-500 + 1e-16383) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_variance VALUES (-4e-500 + 1e-16383)" +== 988 +-- truncate_limit: 100 +-- variance is just under 12.5e-1000 and so should round down to 12e-1000 +SELECT trim_scale(variance(a) * 1e1000) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(variance(a) * 1e1000) FROM num_variance" +== 989 +-- truncate_limit: 100 +-- check that parallel execution produces the same result +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 990 +-- truncate_limit: 100 +ALTER TABLE num_variance SET (parallel_workers = 4) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE num_variance SET (parallel_workers=4)" +== 991 +-- truncate_limit: 100 +SET LOCAL parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL parallel_setup_cost TO 0" +== 992 +-- truncate_limit: 100 +SET LOCAL max_parallel_workers_per_gather = 4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 4" +== 993 +-- truncate_limit: 100 +SELECT trim_scale(variance(a) * 1e1000) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT trim_scale(variance(a) * 1e1000) FROM num_variance" +== 994 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 995 +-- truncate_limit: 100 +-- case where sum of squares would overflow but variance does not +DELETE FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_variance" +== 996 +-- truncate_limit: 100 +INSERT INTO num_variance SELECT 9e131071 + x FROM generate_series(1, 5) x +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_variance SELECT 9e131071 + x FROM generate_series(1, 5) x" +== 997 +-- truncate_limit: 100 +SELECT variance(a) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT variance(a) FROM num_variance" +== 998 +-- truncate_limit: 100 +-- check that parallel execution produces the same result +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 999 +-- truncate_limit: 100 +ALTER TABLE num_variance SET (parallel_workers = 4) +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE num_variance SET (parallel_workers=4)" +== 1000 +-- truncate_limit: 100 +SET LOCAL parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL parallel_setup_cost TO 0" +== 1001 +-- truncate_limit: 100 +SET LOCAL max_parallel_workers_per_gather = 4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL max_parallel_workers_per_gather TO 4" +== 1002 +-- truncate_limit: 100 +SELECT variance(a) FROM num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=Select +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT variance(a) FROM num_variance" +== 1003 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 1004 +-- truncate_limit: 100 +DROP TABLE num_variance +-- +TABLE: name="num_variance" schema="" table="num_variance" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_variance" +== 1005 +-- truncate_limit: 100 +|-- +-- Tests for GCD() +|-- +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(-b, a), gcd(-b, -a) +FROM (VALUES (0::numeric, 0::numeric), + (0::numeric, numeric 'NaN'), + (0::numeric, 46375::numeric), + (433125::numeric, 46375::numeric), + (43312.5::numeric, 4637.5::numeric), + (4331.250::numeric, 463.75000::numeric), + ('inf', '0'), + ('inf', '42'), + ('inf', 'inf') + ) AS v(a, b) +-- +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +FUNCTION: name="gcd" function="gcd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, gcd(a, b), gcd(a, - b), gcd(- b, a), gcd(- b, - a) FROM (VALUES (...)) v(a, b)" +== 1006 +-- truncate_limit: 100 +|-- +-- Tests for LCM() +|-- +SELECT a,b, lcm(a, b), lcm(a, -b), lcm(-b, a), lcm(-b, -a) +FROM (VALUES (0::numeric, 0::numeric), + (0::numeric, numeric 'NaN'), + (0::numeric, 13272::numeric), + (13272::numeric, 13272::numeric), + (423282::numeric, 13272::numeric), + (42328.2::numeric, 1327.2::numeric), + (4232.820::numeric, 132.72000::numeric), + ('inf', '0'), + ('inf', '42'), + ('inf', 'inf') + ) AS v(a, b) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, lcm(a, b), lcm(a, - b), lcm(- b, a), lcm(- b, - a) FROM (VALUES (...)) v(a, b)" +== 1007 +-- truncate_limit: 100 +SELECT lcm(9999 * (10::numeric)^131068 + (10::numeric^131068 - 1), 2) +-- +FUNCTION: name="lcm" function="lcm" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lcm((9999 * (10::numeric ^ 131068)) + ((10::numeric ^ 131068) - 1), 2)" +== 1008 +-- truncate_limit: 100 +-- overflow + +|-- +-- Tests for factorial +|-- +SELECT factorial(4) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT factorial(4)" +== 1009 +-- truncate_limit: 100 +SELECT factorial(15) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT factorial(15)" +== 1010 +-- truncate_limit: 100 +SELECT factorial(100000) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT factorial(100000)" +== 1011 +-- truncate_limit: 100 +SELECT factorial(0) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT factorial(0)" +== 1012 +-- truncate_limit: 100 +SELECT factorial(-4) +-- +FUNCTION: name="factorial" function="factorial" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT factorial(-4)" +== 1013 +-- truncate_limit: 100 +|-- +-- Tests for pg_lsn() +|-- +SELECT pg_lsn(23783416::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_lsn(23783416::numeric)" +== 1014 +-- truncate_limit: 100 +SELECT pg_lsn(0::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_lsn(0::numeric)" +== 1015 +-- truncate_limit: 100 +SELECT pg_lsn(18446744073709551615::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_lsn((18446744073709551615)::numeric)" +== 1016 +-- truncate_limit: 100 +SELECT pg_lsn(-1::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_lsn(- 1::numeric)" +== 1017 +-- truncate_limit: 100 +SELECT pg_lsn(18446744073709551616::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_lsn((18446744073709551616)::numeric)" +== 1018 +-- truncate_limit: 100 +SELECT pg_lsn('NaN'::numeric) +-- +FUNCTION: name="pg_lsn" function="pg_lsn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_lsn('NaN'::numeric)" diff --git a/parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json b/parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json new file mode 100644 index 0000000..05e97cf --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json @@ -0,0 +1,556 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/numeric_big.test b/parser/testdata/summary_truncate/postgres_regress/numeric_big.test new file mode 100644 index 0000000..dc6c96c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/numeric_big.test @@ -0,0 +1,5284 @@ +== 001 +-- truncate_limit: 100 +-- ****************************** +-- * Test suite for the Postgres NUMERIC data type +-- ****************************** + +-- Must drop tables created by short numeric test. +DROP TABLE num_data +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_data" +== 002 +-- truncate_limit: 100 +DROP TABLE num_exp_add +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_add" +== 003 +-- truncate_limit: 100 +DROP TABLE num_exp_sub +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_sub" +== 004 +-- truncate_limit: 100 +DROP TABLE num_exp_div +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_div" +== 005 +-- truncate_limit: 100 +DROP TABLE num_exp_mul +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_mul" +== 006 +-- truncate_limit: 100 +DROP TABLE num_exp_sqrt +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_sqrt" +== 007 +-- truncate_limit: 100 +DROP TABLE num_exp_ln +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_ln" +== 008 +-- truncate_limit: 100 +DROP TABLE num_exp_log10 +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_log10" +== 009 +-- truncate_limit: 100 +DROP TABLE num_exp_power_10_ln +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_exp_power_10_ln" +== 010 +-- truncate_limit: 100 +DROP TABLE num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE num_result" +== 011 +-- truncate_limit: 100 +CREATE TABLE num_data (id int4, val numeric(1000,800)) +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_data (id int4, val numeric(1000, 800))" +== 012 +-- truncate_limit: 100 +CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(1000, 800))" +== 013 +-- truncate_limit: 100 +CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(1000, 800))" +== 014 +-- truncate_limit: 100 +CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(1000, 800))" +== 015 +-- truncate_limit: 100 +CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(1000, 800))" +== 016 +-- truncate_limit: 100 +CREATE TABLE num_exp_sqrt (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_sqrt (id int4, expected numeric(1000, 800))" +== 017 +-- truncate_limit: 100 +CREATE TABLE num_exp_ln (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_ln (id int4, expected numeric(1000, 800))" +== 018 +-- truncate_limit: 100 +CREATE TABLE num_exp_log10 (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_log10 (id int4, expected numeric(1000, 800))" +== 019 +-- truncate_limit: 100 +CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(1000,800)) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(1000, 800))" +== 020 +-- truncate_limit: 100 +CREATE TABLE num_result (id1 int4, id2 int4, result numeric(1000,800)) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE num_result (id1 int4, id2 int4, result numeric(1000, 800))" +== 021 +-- truncate_limit: 100 +-- ****************************** +-- * The following EXPECTED results are computed by bc(1) +-- * with a scale of 1000 +-- ****************************** + +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 022 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,0,'0') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 0, '0')" +== 023 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,0,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 0, '0')" +== 024 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 0, '0')" +== 025 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 0, 'NaN')" +== 026 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,1,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 027 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,1,'-85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 028 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,1,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 1, '0')" +== 029 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,1,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 1, '0')" +== 030 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,2,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 031 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,2,'994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 032 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,2,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 2, '0')" +== 033 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,2,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 2, '0')" +== 034 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,3,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 035 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,3,'60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 036 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,3,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 3, '0')" +== 037 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,3,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 3, '0')" +== 038 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,4,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 039 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,4,'-5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 040 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,4,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 4, '0')" +== 041 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,4,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 4, '0')" +== 042 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,5,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 043 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,5,'652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 044 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,5,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 5, '0')" +== 045 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,5,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 5, '0')" +== 046 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,6,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 047 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,6,'-.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 048 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,6,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 6, '0')" +== 049 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,6,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 6, '0')" +== 050 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,7,'-818934540071845742') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (0, 7, '-818934540071845742')" +== 051 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,7,'818934540071845742') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (0, 7, '818934540071845742')" +== 052 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,7,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 7, '0')" +== 053 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,7,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 7, '0')" +== 054 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,8,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 055 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,8,'-8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 056 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,8,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 8, '0')" +== 057 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,8,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 8, '0')" +== 058 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (0,9,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 059 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (0,9,'-54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 060 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (0,9,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (0, 9, '0')" +== 061 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (0,9,'0') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (0, 9, '0')" +== 062 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,0,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 063 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,0,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 064 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (1, 0, '0')" +== 065 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (1, 0, 'NaN')" +== 066 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,1,'170486.79080049955252152479695727201571965474311716541919780029226071455736587237347615553466832461907447637054203186991790701615551214692555785671028648640897898741246882118067609728317430043806625387779037980513762118868084887015059202190301421555269486602797852927777567694581746398790609996101506730430853942556475840126871131898407356048450541232591147357021858041662012293323494543567675306406079659294204054863522259037763051870433216859794083051717080761509518250300466106939998045710070') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 067 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,1,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (1, 1, '0')" +== 068 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,1,'7266436459.363324713115467666113895787027372854351303425444968800459979742082292257107107767894843498525848597439323325297125474674300428669958003640228730876886174255457103020291514229439701871032118057857763809224712818579091741996335014138185389554630910658876423205103697147288306070059640369158894028731728589073730895396494400175420670713113234800826523252075036892246807434088405522834549449664122407363485486902219500109237667016524913027290777216477989904700729228025571098410870506256758678625928245828210775042611512394316804583459576285681159178280400209217948833631961377519855502763611693070238579591463373484424582723121059964236704135695706864890193388054537703767833595331866551990460050750959493829603581882430597105627056085260296454181999581594565113210481151487049158699087454047624433576922179904629') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 069 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,1,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 070 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,2,'-994877526002806872754342148663997.64812998474240514147207095573950146764154822009863493316394610578375247334825932838513167168342610420582834742950389452212867974756590355021495169819086060202117180229196935525386766373096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 071 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,2,'994877526002806872754342148834484.43893048429492666626902822775522112238466538551783273345620682034111834572173548391979999630250058057637037929942180153828419189449146140692523818459983958943364062347264545253704196416903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 072 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,2,'-84806738323879544552397401815149740513.8505875535743013876823142649666132764556588225959336097903898464616542203793600590311980154402068027051522932586050753865288419084437796768749509032177577451738712965496693249429231838833655025794915864261585848007162358912070811805298210095333433397862313304655108809804359760907473898420016370058274978588765092161529583480924554820756527238472641797198545539410039895140087686344382628317530286295498797849942258314364503000942821309916954725689781458590617068629906894951122301020797266469357701283289275708774593896770378558232444454118891917258610753077932026885574920166837998049508644891327208474213193224700658584824407382455480657734911543930195324144216374573825') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 073 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,2,'-.000000000000000000000000000085682300757901809257711279577127388124986344391495296640171942990079130291883279872719240502687189411421655284515420074848478500192127657883342858267913417679786356766341637336955924836847768457039175660279784295612167899455618405343686908907695358239088351870495830739180518509859269437015797489301844593920484927630172344269378248455657186218762679357609204333669024237648538465053048724383898528808961206696787294681884412485427843796696788390072124570957047672341581447744981862017791206857428430183366004980966398716823512288330174863890117558744630102020144500158878244146399686532935435591262767487823942606452349972401012308378888947381934278131785907155692007064636085000405504866631011593239041758448995933095907216863744502344014999804306234830774259496097549717476344048') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 074 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,3,'-60302029489319384367663884408085672236.83687099063256754698860828386302509843815398979402006244388708674093244201278399438376682321121138429850885935540924586964982855913223221441591310211730902799041126800414795030815514254713522692405212716783388698431088814919226444677188004928663343696636297536500970117716818423689175692808344185016908913828066250587407384563498516598672584120143890364303296142744031320345312431817858545326010704685255237541162931904446804064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 075 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,3,'60302029489319384367663884408085842723.62767149018508907178556555587874475318127115521321786273614780129829831438626014991843514783028586066905089122532715288580534070605779007112619958852628801540288008918482404759132944298520148080184250697297150817299173701934285646867489426483932830299434150464278537812298564822479785688909850915447762856384542090714278516461905872647123125352735037721325154184406043613668806975385533851732090363979459292404685190942209855935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 076 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,3,'-5140349743195574373979577554212527512597024.162480344833040409158673429491690439298506850052285119390701002577176786023622062742050099464897084793357329597395417632908812044304066963549928478520702505283307379218587635434673128958824348493758429380623577527186462464399974242800361134191519694694139153279582776168995426125926314513926640766117733774558011741611075336271613675760116784769700605008122422944290652448956922432960815546502965310676913079866511016221573557684245901002643719965652152439520727383305120298495304784052489867651462175349450610643411043707261107569691076730261762793560088893354750383257372118118753366377402045596735023445172252225346164608897913115394905485106225627590643805003075069931177395059698550161546962768768895596088478488887530518018212441345360153523733317120037436403475909117998647781920105313938836144009539683') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 077 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,3,'-.000000000000000000000000000000001413607404628860353773457807436398753936801768769045711604884548436548520368932184112069166807060840219636509423284498981041814526856251281381511288768719259120481595036745286884246627534964287523188738499223075292690431699417313258943941279343383979626641848305343592679057491670166887054819766294147341982669243114259272404203080347707713358471397866402657818267495050115642987782080912962056565478445923456884713049272637646637760989004917643369240372476411912794578381690666695711891846833983534126217706309741885844723208036219144146342212915129560758201609824034610223907791643110990898577049488934294259106725414517181607988173722432655731491050637087261030314548853334338835938120502930424813699221083197863303458179445322810087784892821862085562891180364134284641396475') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 078 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,4,'5329378275943663322300488.64471790965256505869684245785528331091076155554650629138833809683459634328609777839510066435612911583108717191216693735823717997111970662575497378762952496582183738308720094529950793570383580785385569873278068217936841324404119828637880370718028782103860007754579779716996004352284614661690063919125301052941328989181561787543541920734755989452320799185700078241880935083616978140555713297241612718277766918005268951861880490889884082730841740604517529391011862694381726143520658746305661338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 079 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,4,'-5329378275943663322130001.85391741010004353389988518583956365616764439012730849109607738227723047091262162286043233973705463946054514004224903034208166782419414876904468730122054597840936856190652484801633363526576955397606531892764306099068756437389060626447578949162759295501062154826802212022414257953494004665588557188694447110384853149054690655645134564686305448219729651828678220200218922790293483596988037990835533058983562863141746692824117439019450865871047657552800448629502344444081260036580660700595591338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 080 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,4,'454294299613767152878025320780.534199313974295807138790763501115780294529340799108297697573066187975311338382917022391830256203305238757334106943821060545424417350991354829668286194840925251162479496893943917530660694097932059166013476064988623431110002057735318529554555260199417935495388243829261809007709919225000608711536928171687251088217591210419208480251102484043683131687013687838713055660405381318396419588727500715930145098362997142075433472039319292466570912777345841400769387321465602989947078951135489852486382469990409873227894248208197179481868230244584527040573428134962626267135732247029762468417273891700661832893497067151409134724061246612631376075173287264787886064622106855886785805818642123776489793586531950438285720668411465570116161790343538663297713926678759640594912243360541590368666922379919514826022141331900181') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 081 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,4,'.000000000000000000015994998100440878014888861029956505927201309704413242103407885948184870841766875212766910686894450511886242468216220470061916924303252919423028993720180330014505454865704155281502763018913215741264982350384245753394656021401865680441649920273268554396350483440173848850052788410943178207336328451359951614056237100465802151856198860908371340425459435127133071447273887829397881221098443685586506647314622864702873235212396755866459409263439958011711379929751157260020133239574261188528305921244365838405372320186907437842180388704854605498842516581811515413843298370501194935797268161171428747542997504369133579105180311662221854071962295818264211400101689450830279979372422749150894553349570063000769685274875561760334738424509532610467832951796852051505383374693614022043010735004494395190') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 082 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,5,'-652670387.03916046850422757312745971450663862747133703839829692066597367760104802542475264601221776157515632293978442027199108085723617181683235487266149426304575903892721468296143475297345699313102262188759506518376019936160961709578829069446312051432780603656651983414612264636232727512091101057374054475214114364113300402823059519499217878746766275164739724770556122895799337810694888119810524986616938847385753562624139431982468828696587199570410008890188532132652095915565323400735066310142303225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 083 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,5,'652840873.82996096805674909792441698652235828221445420381749472095823439215841389779822880154688608619423079931032645214190898787339168396375791272937178074945473802633968350414211085025663129356908887576538544498889782055029046596593888271636613472988050090259449836342389832330814473910881711053475561205644968306669776242949930651397625234795216816397330872127577980937461350104018382663378200293023018506679957617487661691020231880567020416430204091941905612894161614165865789507675064355852373225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 084 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,5,'-55643106304872.575994253221940844841058071061962511162776681458310912066379595519265546225338405882027547140476045378015935579066580347282075024392379464189067155567624835346798806677988850250198082355055954078446421075165109896091047534711081616362392995575466807084807876544560268050611445006601394735810211678919646667455478469014906335433468365011768049600750224822391684377238242162320161552720449713229523135506671063115436813348612986916614320012995541575293478341408982118538094438068036422562665160411591652618670802973618768526197813319204816293073794413317669922144705633308090832805914096147659820167569140291210526520361556881576175809360614782817717579318298657744021133210954279487777567785280633309576696708168342539425395482429923273623865667723482418178781573723597156804085501875735112311466228778929147929') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 085 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,5,'-.000130590057635351941758745900947472461593749814351229292370661147301124533787181489468804246182606762727711479707901680546780430454163647774077629503207962424213266902732555945190365467801995495570282501722505521485829885605904543846887348545254658726343578684749830307120625129857380290225370772763609458975555029415082569247186899112975387051141777417911244576134390940441209829852154391377911942082738699481875795620569383196133124499983396562167632007454221121465745085962247988140942672429187053671899537331280701003778040796615094903602095098880716919238394057384949891444700347825726273725378453454782330181608182747900774711384845635284701538541452235224216112380245660177463043471814071809869894647262285332580556739424040615194137651616350340752691170045698234853734471923738591898290468792787543896') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 086 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,6,'85243.44233732197133191329295927531563604777955507322414928382967007765263923984471408038635831036097817458527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 087 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,6,'85243.34846317758118961150399799670008360696356209219504851646259063690472663252876207514831001425809630178527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 088 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,6,'4001.075404054519813215296429095020391062109905613738157927030437221793757373268325953178030040276107574363822832168160758728653712686313134828282109532831190239521843808940611025488601517574653932032236616573457735900045655665690517797280666732780030171712864961531623060353548802466577910774711998056232872212688464691036260746751992072745518373073825852119460094113694393273456369345499434994672730920070410547163082189385645712866100999708173472360864669110044660667614583576570496399103026286828660558854973376227247132815728164629722965145778698957093136175449225024685874279280018547740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 089 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,6,'1816120.848909727306817960620941575637231136442992819290405125420545200026620306446043740992108329883383706060582482495616151605111275635501481354526017831484915013545483361715432312183101964395505340188909970344423950565285639911521082834494088840596716495422427543520536844348040681236845850482165744696068209384509064196671206362539077218412355776790921130042376467606683622970728503408501481791356294886150690067651815776445750760428874351556866105285911902433352126498951242195408782804314174041618879250740246352525074791310920062276490422853700893340860452528740673590486626464460321410814395342850270921486724297414692313177440726749004398703147904603937755702369682956482832074779404350351752662820773690162594400557957241676636030332988289683112176900913522668426137377289536793838959751008646843014106876005') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 090 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,7,'-818934540071760498.60459975022373923760152136399214017262844141729040109985386964272131706381326192223266583769046276181472898406504104649192224392653722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 091 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,7,'818934540071930985.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 092 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,7,'-69808760806266041400340.70700818693892852138813934414383886494691670042143650609934777814995087699409404201920249076407981012095999320858479644760715204999741683528746097757549835956359129287002171391961763797857794730120426599135099619822532290339000466211195776337667123320942107370731349851576864242697412616810236323676004067839744992733887503405311090677026008324895177587064547630828026123718296429295638934384446325302964896473296829265805737112709269803814942537657996725913938408781715328945194948010970') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 093 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,7,'-.000000000000104090609479936344103210175655521317012597986331111866307697262848964666360492361638117930801818899121383806224630563676018240181412174154250663423230239912527388431901852952893943812666142740182651125508583527237123596541789628675379232473721293630968882045044077795828674268595016625198802475186587918019739056755398151182369187670251750080227679555002307777300392769289647975058449905106584837938556260801229545589323224752038795423164214112897202147313792076165011373139219134850954217300915326944185918762838321705825423789073869940092569940135329697980600082436317664012683589681419530904283106912171330819469065141821685734295058255484933744156717782754922568796985634397878149984177882018261742637463462647452140104146195353696596211873925359508622779658904411330975862442989437933211964821') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 094 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,8,'8497071467.03603749330791582407836434318377133169438097066269854720538319012928851657498035372443556191720308219530866834905045144302106406146277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 095 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,8,'-8496900980.24523699375539429928140707116805167695126380524350074691312247557192264420150419818976723729812860582476663647913254442686555191453722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 096 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,8,'724311956372274.0135050255361637906710330203036651743488213007179039756514944640108625580172737414192938789413338554327986697518463087452612658955180411327002900979574347739956600177846996063741787205122007268468674386396156638261992679442768654367111433834151087792255469957061758837789341439211010331332174981459471333376067541234901538285101103690622656631026001337239036711179989456674399137008584021283568040818388709554256523118702728176420022080138548890713013682480239784198421500241995499841675772793497485550923152267616622892846304530712344886979674416990935007952941652591352603797627920865960622077762568060903908151958000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 097 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,8,'.000010032191786198542900505683562217892317481076466949299850809276743457759270150820565375820388277409258249926696079166209409657808406245382887790534127749833677458375931047385994887406206232330491317602830654688957983804698568410728278089250379255157030886262396950539100566975000094268415749476738358914633948867977798590927055566888255636132486899287919515638902721543629183577900872078173883974905921239149419877613723476347774771230668479296621531969573505480695490386225866950545725121902534610730154727385072738079149623798073810167706094070842646222833137345669922898403368997676634709281456818189049718956207208697021706186341405575300648248555331280690778367620868775005181264547924615247991795542738868003191757946979714250339430363902549866892041102771965653407197094250270379367437342632741280710') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 098 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (1,9,'54948723.74225051983134098996071145685528795757427462111901537365053896571438476055974853245403475510333627298551845046116291696445177112567064282766115207407461565363967417615506303416694032848457927390574251904212425813072768882213388082765916956736282110801611726537663292922699021333445658549608928179155685881583228490235606377831724593358583903616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 099 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (1,9,'-54778236.95145002027881946516375418483956830283115745569981757335827825115701888818627237691936643048426179661497641859124500994829625897874508497095086558766563666622720535497438693688376602804651302002795213923698663694204683995198328880575615535181012624198813873609885725228117274934655048553507421448724831939026752650108735245933317237310133362383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 100 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (1,9,'4676749348240.390309875431213992853550297086049749814750492488995108783145961719774217441193547534210468967573344456866203963659951312519988497979489304488948342258375915152429008993288817366720647491166024151209542534474867042837694499222928509320280684557676243780452100132238968233413333851595648146954975713386711764268506890884764704949969602122157394714663532141060559896359465918874990769222345665160127552795532197771168442486088776803398878354288847069602460071745966589164282641033852314335279121191855487126430176047553895892632834940595958394834437871886013513058514896870683979585091413977173250824451205330441299000850618134248917380244749589254309567551846327349592529960432446947239714236828401206843011440433362544797025114476612133622499094287321570559088587999417440664282418005102546343020409520421747216') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 101 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (1,9,'.001553736563217204408368240901181555234014339476186598647410198373122572205209277343865051610898136462487966496673511261433286284257044548634547569923035899634327495195510767312478861719221916387940027268721306540663743713345337497285507595251328382906111997524508729275471287648008479480805967901972481289402930660848950039779707354469389216931774094174326513465502460315792834278614886136688161679443873815113442220055827192996984074129528034845339130162104547166079591654852164993577408422015514100323825529286511720963047269483211930770803479398243069649400360625259869765138545866815758888670363356947311319523139395191102286838888146829667276592755438606664644975648828848738708349790766370694194763606850690923803984129157519048493985198591771429264967247245289970213262206709011468289046840862597010969') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 102 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,0,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 103 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,0,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 104 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (2, 0, '0')" +== 105 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (2, 0, 'NaN')" +== 106 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,1,'-994877526002806872754342148663997.64812998474240514147207095573950146764154822009863493316394610578375247334825932838513167168342610420582834742950389452212867974756590355021495169819086060202117180229196935525386766373096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 107 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,1,'-994877526002806872754342148834484.43893048429492666626902822775522112238466538551783273345620682034111834572173548391979999630250058057637037929942180153828419189449146140692523818459983958943364062347264545253704196416903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 108 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,1,'-84806738323879544552397401815149740513.8505875535743013876823142649666132764556588225959336097903898464616542203793600590311980154402068027051522932586050753865288419084437796768749509032177577451738712965496693249429231838833655025794915864261585848007162358912070811805298210095333433397862313304655108809804359760907473898420016370058274978588765092161529583480924554820756527238472641797198545539410039895140087686344382628317530286295498797849942258314364503000942821309916954725689781458590617068629906894951122301020797266469357701283289275708774593896770378558232444454118891917258610753077932026885574920166837998049508644891327208474213193224700658584824407382455480657734911543930195324144216374573825') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 109 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,1,'-11671021799770914903865020509.301561107153561058074179843542446420696517132461554451075945807420674211966679216615407057626541711186781735967334896541890595771915856783008831770988426637435694856170266346306640678577376310547806764332837625966429200996250687908930748245035578756314083608655163891041399241377675534416837659335561005203219889972336214863417948542956735403991871098341470996860469878038840964359144637726669728240650066795729910649523281308716277906908340457162235831526838308777581569974551673352306004330423694524256415657620427590352277556907586751621496248973165690360552007637570957980230685679819820147036159174977086193494572117089582758015847544798464543446227632367713941117001423437766840744488426025388612316819120660814681298624293065972395923651314350558006567251033289878238407790871784676348196394482477767774') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 110 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,2,'-1989755052005613745508684297498482.08706046903733180774109918349472259002621360561646766662015292612487081906999481230493166798592668478219872672892569606041287164205736495714018988279070019145481242576461480779090962790') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 111 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,2,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (2, 2, '0')" +== 112 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,2,'989781291745465665243281323944996915810556285052564220274237162526.1617859904902612197894543199389468971679632139059029459520163585971122643624316475417489000981872666677202334180945949860058384424993911721081868337499377890298636260338063268639283065887210924895929155083478140340889209440025415565915964293989840603863813531303253038823629712989041722072693449251635519992922148998556112923060331794396659338057474019846675262291146025') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 113 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,2,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 114 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,3,'-60303024366845387174536638750234506721.2758014749274942132576365116182462208228193753118527959000939070820507877345194783035668195137119648748792386548310474079340204536236936213411512867171486174240518914767934028451971067161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 115 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,3,'60301034611793381560791130065937008239.1887410058901624055165373281235236307966057696953851292799409809571799686645246659986351515277852800926805119259053513475211488115663286642009614039264484259692394657121785950542874788161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 116 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,3,'59993133911282372667149627097418449223835595194300848703012380022306762.154418449236691515146061305380465061074531890529497774836941002526095632166401249277270674802626154774328055399254982998368191676630276960361274433270795772477146870294928855773172789856196219950097157391050424577381777627004101100872747943673762087675405200265837631665464736842180920496158545887039337399558993437594084473932658319914390365451919627956823980800124880375978662052111797881386060353490432427832058851094210488804887183034572364751639107535041308434932952695103493677600969712634416241541391613699710826602011076372592299807609658979777598672141389319098817824624950794758296679318319299142035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 117 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,3,'.000016498242835741013709859217005931279826178662180173096568520102488480129191427472581644597420895622947234184547373944996197105916093347103336318249582032230903680989710242610024298937774441533502282949127537125997753002819456724709929935850697744632904111143787011103837624936502324835260843148595669524694347566421203164808527739207590986975750648112133699756328511947175496694080071202064255118777680958612315513441989609682655431197367166056616661045712867189326408877133865572680407329449150282415810958772293869902662884761202424695742898573841869524376684740249281181605067345203479719345061595919652192297531638467223956758315591610733251562492794891852151639643060692698365496208796638230566761231611376199140556503620471090364900792180618741355091923808605890415081571900697282725022629812561702118') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 118 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,4,'-994877520673428596810678826533995.79421257464236160757218576989993781147390382997132644206786872350652200243563770552469933194637146474528320738725486418004701192337175478117026439697031462361180324038544450723753402846519731908503949116978812841497201119103409772457270340059605961197538918709309004130294868847110690336360689446090125918336908930881873778405661757289469281163974774492810850778950071063044769131228124355961427111369335109426492177657001035045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 119 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,4,'-994877531332185148698005470964486.29284789439497020016891341359478477855230977564514122455228420261834881663435710678023233603955522003691551934167083188036585971868561017596992548582038556784300918537917030055337559943480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 120 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,4,'-5302078674303935968062773235453828254014583744527466365136.236414807326868572353809920518232561005161225922028750078608989965741402418802255050636954800114792425419735155504035469350521800895164087027043476055514245942961100610551646034472084954313670284875310691807937254054948742125729353864014122131419164449567115006621212424805182687707372956385102095255735458593389920872596796806885847543910224476727171570873698525606016990229936284811067826588349092841322512643043008589065847223683467371925773023109720951609815041012521485326120380123169545818055967455575736140138663815073081494226676896278654189873597341203197903408668523514375373841493189836809506003729379742035629498519683885268256481104619815130659628225053833297766479068686119691010593208135616363994230674606991733148502293102108193522604968743948323130517040609601859735899914987426089053869350663') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 121 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,4,'-186677971.517539861245390308778107722315862721823627804195528485535806132067679059453022306691281662574091826898288146790399178357754908901382135796783067563944022498807930452234032896817601590728156392188660701355670595952594500812333935362955625137944589981298793332621503315902294100258945995827423279442031218510259915311555745581797315793010762585658196457363672908315687720174516274528662385172326028870945153551774300419158584379602045442200523311437013776079979639415633358878239012925000523542907592866797199229858272764668664323316251874027468128770456766875866492004650352654523634716923150212263912760225390093339729495231675627059805624175587380165509763048913150826017167286786277908970769297060278191518730887417202276531151575412404467497036737825989088867451153485938272367300939127313445244028528055624') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 122 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,5,'-994877526002806872754342801504871.47809095279915423939648794226185974985600242391612965412218049794216637114648812993201775787765690351615479957141288239552036371132381627958673244764559862836085530643408020551049895730005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 123 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,5,'-994877526002806872754341495993610.60896951623817756834461124123286284017021118170033801249797242818270444792350668237291391010826978126604392715751281366489250793073354867755345743514510156309395711933053460228041067059994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 124 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,5,'649411906691138274293985410502516861224852.2323455192714410716272307781034189160865613770320102043319541634113746032638191509585045862973333645830298922352816245477556264222094036953195419857712804755170632292914187367964994214922001758104594052499795564860466055599417895782179851297585155129541589802249540436678824225950907268084876110445460948679383611117263673106597132046331719468816839434908155684738864149955129235751738204036443603521478609787295079710078973503970964790273461142497259987849074597264522099648376356902360358310245001183020992360260836105404118742418040965190000718736837422434593694808973939805954329718232693154128543253581495885789333274488461716809104532693754070810202831113003978085636579574171344721710232931261731022478029314435363413498991740750878099825781577297965642009156858479681236085226911858782115') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 125 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,5,'1524119409495532727030986.638577103454261465522025182901477334004986357902177024959076085490119358611626688213654669281670407680244740174673394111775678935383154847014211641601227316639834450258566053805263858706381900273201146454036688771735398324537667996974210741719621449948660517037619359095556637235980122706739013220201060795557114248610410815988952748489854367480813823114296393315170621979351958306734282429929421779129764262568942699813166237466796852578307944635545174715298176546980314973426586923195248536376403319094417073026382024413817222396402299695717290716014320518777088811749776114378145110676170242861393274018655137797545194817703831240390631723050378397773341835222892981773205967439339460305257986693600088957772328044922955990976285151896366292514128607363007421484320868718566256882080399264346243272770200676') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 126 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,6,'-994877526002806872754342148749240.99659316232359475297606895243958507460511031229368344962653674268847910587702140353344168594152240599109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 127 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,6,'-994877526002806872754342148749241.09046730671373705476503023105513751542110329332278421699361618343639171319297340877148998204440427879109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 128 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,6,'-46696638263247522384986521136500.479312417066793299922708112595886608370451213741279484136907754744903470430131032928908162742687359367826808123516519335458861613010646992354378739165872253762686683966945711430182491860196341344982195078000259063231136011430995647812149294224699587849791008794261026932467933475782780') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 129 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,6,'-21195986018643887410662481595901800.342199657994285865579781485758715114242459388977583220756870314514884887803267837816669111279417861218648323488364513921592045485003563036021370174294475403630933854767386355037781881144701319212711655881277140183173924089814927297045029394618083349813549439341772734606115369911736164723942330187830605893993276674913563980890459604886172701331890746621222114280438198802989678877404376001410627722336243835841751052795437979198996482216031399073597399901975686733315751292369326904428230195579137225651689857057115970784985439417129044974524632220457594191305254649113470116960582543784928547885740020507755033347968928034294570497118410435615856155184563329718831512839630769097935523279881940380220955993456451396417879773380305142918906742431812580562496634831735169817705720949712410595406012323294829461') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 130 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,7,'-994877526002807691688882220594983.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 131 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,7,'-994877526002806053819802076903499.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 132 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,7,'814739569184924399102711674444306584731316176345067.39834031417849342571224916231092924046722938910652929295271097903377854123984307101079073134405782275535446337229706620713104545454319555885847481531722101704765783025789147453570970090') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 133 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,7,'1214843772391778.127361407585140553741220126410637250571020684739034685508176000812180032686291124045768750332493129822580347351032145964983629059968936201592138368806173099130176852606440296388856520582890650384142745607345709716826703676313341953999327129144154152914234659001555055379537780751567782847296067128932113870102563522810980359433259696591977617184951677390423898232135100000764121508662830515405980450892222598485287609657612482190264517684867291774820716746063133066053446257163185646067618679478975882247893469409405379034723543061767846895135644429012095930584952053545016706315299076691015196261253199176743281648949731423486208098120903720124071047872917636988241710583721537777321338769039241700203546247947405745989053846970910400831817998342969657501678430211657755864160072525313889413731419647001970593') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 134 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,8,'-994877526002806872754333651763017.40289299098701084219066388457144979069028441485513418625082363021182982914675513019536443438529749838106171095037135009526312783302868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 135 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,8,'-994877526002806872754350645735464.68416747805032096555043529892327279933592919076133348036932929591304098992323968210956723360062918640113701577855434596514974380902868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 136 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,8,'-8453460632655529853033389979024265783461224.3195241893307807116624750282852146303290708492834695194274289713076935297734670940696121761483641291930931061232942894577813178566088927221374036301485916497770984757492912292002695944367308880163698595015497307574177176409203214324418237020500352652934909632442547242092296504047310806151851207329042221920888326000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 137 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,8,'-117085929036205907700251.219065234073336548829793284434494573185718678644093751558890746941383215425734761534822966779511801033216479269605150574332107020180872343673157350081102818832254463561564431056604957702984438484261858890324442581609284935850435611342611117035589511568432559140282381526487115307554496353616929034919886387903446436924514812698404129456069856633480965357915969548215985452939172313964007318881987188665231550330515412104367728617802960792164260429920719961650164518261501571220901151359208484337831586551714193024143212288426326740373893030225940355268499071669300664200888186064836443459131985786957267268845966279576380786883200277187591448294590370986026461176853573555996139940001165172158855197070946665074838360933025833716166930231164328918316437195201546383664484983447934244744303265471044295601062898') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 138 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (2,9,'-994877526002806872754342093885760.69667996446358567630831677089993316481039076439881735980566785462673358516198695146576524119916430759085192883825888457383242076882081857926408611052522393579396644731758241837010163568445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 139 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (2,9,'-994877526002806872754342203612721.39038050457374613143278241259478942521582284121765030681448507149813723390800786083916642678676237719134679789066681148658045087323654637787610377226547625566084597844703238942080799221554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 140 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (2,9,'-54582443595378013373024060492546032003692.4875677735896411267274323339692558458420972958075073392126734000341372096298914875892612108329218081214550050039133117695428196702128258481789017059073444323729583900855712795086447886053552786449313809589992185978097430132940882612817775035217244553616977182049775786664446683332098226841743818600819221587510039430478859412452506872131851471967577741190323481953867845129745440745526578327709351120432530702446916035797432129052518980799424635406993848916727957825620638983706180841278402925286540375225365057191075559133035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 141 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (2,9,'-18133693300409132895168796.074616314168631402221003009151140409826855230810646429042722071403306917323628118792142878282108022292754325022530103525285999179488507720688317761243448898240836430183645778132937666952111134601563043980164547020295727057908447220163534134835130866457657964382363853570827467081988390359191484798677813656413640874450449802233520570178139244957518604566383671867773821069602665918688868868894979351219381089954104823746091972754649316823714354000113723793845707472924569647945844436702275724514171940901057842455729977729388911537391920702753167125695758365521631000334183494148229356487592577177344247694925635113222720411958290166668659311154664393442690740373285505786584987609789805525300762074682544164213490532272590665630428583216403362629445153016404037983825555019274338559686335405719430737559715778') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 142 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,0,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 143 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,0,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 144 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (3, 0, '0')" +== 145 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (3, 0, 'NaN')" +== 146 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,1,'-60302029489319384367663884408085672236.83687099063256754698860828386302509843815398979402006244388708674093244201278399438376682321121138429850885935540924586964982855913223221441591310211730902799041126800414795030815514254713522692405212716783388698431088814919226444677188004928663343696636297536500970117716818423689175692808344185016908913828066250587407384563498516598672584120143890364303296142744031320345312431817858545326010704685255237541162931904446804064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 147 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,1,'-60302029489319384367663884408085842723.62767149018508907178556555587874475318127115521321786273614780129829831438626014991843514783028586066905089122532715288580534070605779007112619958852628801540288008918482404759132944298520148080184250697297150817299173701934285646867489426483932830299434150464278537812298564822479785688909850915447762856384542090714278516461905872647123125352735037721325154184406043613668806975385533851732090363979459292404685190942209855935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 148 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,1,'-5140349743195574373979577554212527512597024.162480344833040409158673429491690439298506850052285119390701002577176786023622062742050099464897084793357329597395417632908812044304066963549928478520702505283307379218587635434673128958824348493758429380623577527186462464399974242800361134191519694694139153279582776168995426125926314513926640766117733774558011741611075336271613675760116784769700605008122422944290652448956922432960815546502965310676913079866511016221573557684245901002643719965652152439520727383305120298495304784052489867651462175349450610643411043707261107569691076730261762793560088893354750383257372118118753366377402045596735023445172252225346164608897913115394905485106225627590643805003075069931177395059698550161546962768768895596088478488887530518018212441345360153523733317120037436403475909117998647781920105313938836144009539683') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 149 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,1,'-707409990019504668223608170643582.082425157530076679823177950190511141917761066423266390864536360056345386873500583953954967225431526056199231768143978526582904071798714789552447782850723926323452633811653766838064983821149041415149067433978085927687765773012158659685363079191901396502099956189371719135315616249471739677995520904113581848295732911534266040260836644379296158092198514963023001686666281725991605685524015227112003429486755206848316731257322742428352116058878710728614841247581716185886403744830796740424927494009978599974431617064012221450054532987372285996679180090592706458366967534834069977644215413076082570497451654516268857039718730203921980307096740864747006176117071983875364434497517026142488015705391255750729200497229031250705777282987863242056223584453312226818451807347197583925624299372040413470456696588043062815') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 150 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,2,'-60303024366845387174536638750234506721.2758014749274942132576365116182462208228193753118527959000939070820507877345194783035668195137119648748792386548310474079340204536236936213411512867171486174240518914767934028451971067161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 151 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,2,'-60301034611793381560791130065937008239.1887410058901624055165373281235236307966057696953851292799409809571799686645246659986351515277852800926805119259053513475211488115663286642009614039264484259692394657121785950542874788161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 152 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,2,'59993133911282372667149627097418449223835595194300848703012380022306762.154418449236691515146061305380465061074531890529497774836941002526095632166401249277270674802626154774328055399254982998368191676630276960361274433270795772477146870294928855773172789856196219950097157391050424577381777627004101100872747943673762087675405200265837631665464736842180920496158545887039337399558993437594084473932658319914390365451919627956823980800124880375978662052111797881386060353490432427832058851094210488804887183034572364751639107535041308434932952695103493677600969712634416241541391613699710826602011076372592299807609658979777598672141389319098817824624950794758296679318319299142035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 153 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,2,'60612.515523995516156897729403721504966784736064970538891936016753206905080265887046037910122269129293912171105589512464185386239562077778499936203155976336284324712221812806801062157592930664021782540155687632208890794166119782594464410498356083266087045927038416810562596141871858142749062925965665039981381277808608946877852933015970874447235220989360704166270479475802673572039541121473138382812420076284458769543418652217394352637294823914346726065145538710933281768776286965107974980550163605068693568717671571780028113969794125200592691656568731359981803586296135840575095063824258761205175762907549288801963550628589530419118771779395037240198270853609924445368393952404606326559485235840170339343865253618184271158932135392539396160392488927771488269959497352568205940636180870805982484030168838833607478593') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 154 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,3,'-120604058978638768735327768816171514960.4645424808176566187741738397417698516194251450072379251800348880392307563990441443022019710414972449675597505807363987554551692651900222855421126906435970433932913571889719978994845855323367077258946341408053951573026251685351209154467743141259617399607044800077950793001538324616896138171819510046467177021260834130168590102540438924579570947287892808562845032715007493401411940720339239705810106866471452994584812284665666') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 155 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,3,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (3, 3, '0')" +== 156 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,3,'3636334760530744652235488357607657374520053530993537920755375319352615385278.023608692512217812784472508939511216316773023870624171279878340621219698109986095090336065266376220109007718694455520948311677863167090936408887147442375455695868593092154861636486745490748828207939155392396090682312136290864359484540126174821846208064763823279315343506148025281475729723686566174395516982893064510403581479746673749128344955124070957545815390178764940816628194640888255387443237798761377617383817511745005525149990207764725040109364671749403389999498572538135588695345112358160274671918953118753964073105250116426665508214894805722798842017943220605600452911496071424281587802689830031742105619630787641205011894680546049982654601956546154572720177337696285354350903475239411654436042931409507429892682706228354459580412759920815932840348933425754970917910500027837428631661182510071352138858') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 157 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,3,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 158 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,4,'-60302029489314054989387940744763542234.98295358053252401308872309802346144227050959966671157134780970446370197110016237152333448347415674483796371931316021552756816073493808344537122580089676304958104270609762310229182150728136567294798680824019082599362332377530165818229609055765904048195574142709698758095302560470195171027219786996322461803443213101532716728918363951912367135900414238535625075942525108530051828834829820554490477645701692374399416239080329365045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 159 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,4,'-60302029489324713745939828071407972725.48158890028513260568545074171830840934891554534052635383222518357552878529888177277886748756734050012959603126757618322788700853025193884017088688974683399381224865109134889560766307825097103477790782590061456916367930139323346273315068375646692125800496305291080749834712822775973790354498408104142209966769395239768969172107040437333428573572464689550003374384624966403962290572373571842567623422963022155546431883766327294954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 160 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,4,'-321372325955692885069615337209737469749246561535004445508427591.072860243358366933071485495726715620133686420023451450292996945184959542770492705998350644739298629407567812798540119555932604687814429669592481327761428042980782672136901602006622227365754036664912989085940235439697789102358431343119457114603363936544931303133371137532006899162833369543279729021228901466728220729625107362063321334489394782322741444425117731922691457341543446841167138481424319752111748042440994701571955325673470021626946676976482516292402239416632497972073915818846704053624707839813514171497746804751780741682011937606462260710753056669269928580460921188286249923152921382198282201761171043384698319895970192114563900025573490442674225227682235790590616707857188385274186584856872573669591460447105688151281208238908470285147895678001948902280493477604361481216667716971590499226735103039') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 161 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,4,'-11315021446594.877643290091276308982961654569173523687151347727612592478433578066762912541361898899908505997444632820107356713116459078630334224890355872486337973552333755378190316811715776951317058334754704988120078733912131691682869448731717816749620336196719541702138949084375907248656748314375183301372633028246109596775255074617515860012417935744433243071057057560464360663978361945666099558526069794464437818864063206829678640156992474597480916575712563493776637239091589972373682399519931569163592317107392231951775499293572134702843085474656152913351183535194499521618027894129537558509428098859715020703897463518891082573242502356303078754574312965093639182648263511466558336912294702019648266054331227425119096294871153811412169351624751542166779635702042223762951850816568617453355571302500885410532963789364822647') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 162 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,5,'-60302029489319384367663884408738513110.66683195868931664491302527038538338065260819361151478340212147889934633981101279593065290940544218360883531149731823374304151252289014494378769385157204705433009477214625880056478643611622410268943757215673170753460135411513114716313801477916713433956086133878890802448531292334570886746283905390661877220497842493537338035961123751393889400517474762491881277080205381424363695095196058838349029211365212855028824622924678684631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 163 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,5,'-60302029489319384367663884407433001849.79771052212833997386114856935638647096681695139572314177791340913988441658803134837154906163605506135872443908341816501241365674229987734175441883907154998906319658504271319733469814941611260503645706198407368762270127105340397375230875953495882740039984314121888705481484090911598074635434289709802794549714765847764347865064280637851906308955404165593747173246944693509650424312007333558709071857299501674917023499921977975368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 164 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,5,'39362489275784146262776411377472433635883331946.794473520543457442955620133347015506556162839462623905489255080102447195050109095701660164272430316804466254467810714209179752718730906325952685817112992943656292503112803950215110778476301809440329937774061163668461957943313261962261081942055908935814323069621279128270849852239727888939033546870208376394878842958202403235309372240005941467570230067124830916866857395233038346727879951123599893174252558078732888910139309038957525961212820831321973219557165558911222848692996406741318948607549825343491479728117062814094258484536263158005174429922237853707635743736923521032098496725445243775790161216159399180889906705265012270270348146530113428221072591696851818281866095288773371414866822270689959827332258348570976075184933893434327278299820594014788148344260948638847457822697682605612771344335201258128') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 165 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,5,'92380711368470856513514428781.033155715252174277753317877861994356621252232374386687048394529670637693505779282500567256835271428113529026462111032257747830329068594622091282098767000694818101994264352932243278144124687156236926607422077479412495979777588932692081795130282128890441931602671468684153168580234070246201722180460130467506344034452687371838907269162119534950946217165384250603250357360223255177692065141037447374172264943732616165429783010079281851748804739433821308362193703012671569249508710820679009084891198169587484117171861141580870066764275087111843275285564262902405980617569581840831518012986031156042600391943605532635833608358301306456966765206853910579231447150839538731157206153540873916893579943906851149770881336811951119112558311734171557608362620988555075663589827484854016702489324791126228380209309587206299') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 166 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,6,'-60302029489319384367663884408085757480.1853341682137571584926062805631087054017160819890685789064777236456590745415460695320768374693076860837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 167 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,6,'-60302029489319384367663884408085757480.2792083126038994602815675591786611462177090630181693462735571643935716818574980747701251335721895588837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 168 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,6,'-2830400711649493468815157129316992649.40542786074520931471973065281957756940496588853021620372179463538053123396140685749478530925306163968207226329985017644835203709485594362663495728106061878665324856417118064730721101615473194292620972173690618491026470353143141125614124440035267592258385099934706896692953497971326605145704135723011753705907329979207428661473172503098296622281647255008204864404416199384701720347319806375450632245634238172654086373193251877533131784268854289406126119630708578053354762596511353053106459297339360827562281168219966099848212') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 169 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,6,'-1284742031601444539630782308463065726620.121021225455596762466053504195700643301310745151565435123335541550963124666304408503436412726848834604336377169205828654564329888653766451656774534718709065521243637375270687684572524302099749018591530352756390467862377335526634920857924031482455373589053524922608255779040656019538392173139295812160325688504210040741075388404155144782519528791757450256668977268409265390016721724966592135644698341754332845002439113523127047593325646484654291494607100188094186116001064043796216982681807318598789324900462932294782971663150070521334398542559480877366424630693734132836518604260869235580641521264976411493166969530737254118968281271908306432918913600567757535151861421384835424322504855607676315840963696944683182767935565256136130185809101891760917733694553800748568697830680328155128016670099315391685422333') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 170 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,7,'-60302029489319384368482818948157603222.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 171 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,7,'-60302029489319384366844949868013911738.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 172 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,7,'49383414785234649002982046297226894664526726187218771083.0993243619030008310875293647868815940421844461627295157812843657782639833900543200310573708100000958929315945039020410482966753145208427035917753919085618457760620513481628641658765820294863970581642745379331727722585319163262763708386199720411053619449096019862596221607526610103408936214184850115071874430846697061554769773328338028749631552202705583855831155461651414320570061181212214810086436100771547030013079997847086') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 173 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,7,'73634737013325927185.787791148221519354461791539553527545166847382784629235192342551464898036004011575416717008403527685470842765455409054592207142526523023201841973047779202013398235864494503216973882479116841765663948294836180515686647139678530220909072497288527276378202532400736141014848907023234659020093073127450778982904578906877634654521825977382116752537063128793631412296206704078569268566614023846282524151679028060869175439188773864994186109445961525301841201265289707928211114515861536069733921800160245586536759625418951427346236213019358749196674633237197452976517130405065120577692737021174118093373953642724512531935525024447977867020930500433287279183436509990047372809400167546185096048971157700858970777301410692908939206693154161335335755844997198191427289546263182822280127912118140820265025555165337881999926') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 174 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,8,'-60302029489319384367663884399588771256.5916339968771732477072012126949734214868901845505193155307646111690097978112797961939995859130827784737422228762767014427842766445950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 175 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,8,'-60302029489319384367663884416582743703.8729084839404833710669726270467964301325349604567186096492702768702209585877643481082023851284144664938175277044596973126708926205950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 176 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,8,'-512385513828318260570283740065493064477880918352.732624553690077857674083796435724202494963885926573907185100543184828131859183999195040110586155435203949963570735841632689374488877298209082579317039061893012560130258753218955057387206477423088065663401594359617882154814262843273526859406265633827109554791772242178864873774889091687515990672487380368975556580539271333144212685871370972163560839446696514092637412587953506052848750866803569213269271165856310101244342151576488190595936869490659700946174362872797854591188391982770203203644172999264143929484089237665313698600170041324566984832357000400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 177 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,8,'-7096872691348467943606706217.907270287823269424282176534343841939501231816905820949045946136373255017076943323578903040918266385724756894003692978391468202345397178445216069294845721607024056189567609414049207292919519881725733381453217071918292453682942046440563446278374996563501512335133749731529362537349288419883140401056747081065947774593869673146309163791076953204291951821124894409171722911526435445719071769008713367057971351892550570642991097981458696464929009464411568672010548002196406312721789582428747564855324072212842315229302959908665089850886951261233852165624100634055045684536311382452553544676139507899503993644452161529145849579200003677255968757773363970434791501820320494192909660871475590637419913907191608957830524390049664686282439567943053924245852983990958276537000732363895444894582579142752920882750130052682') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 178 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (3,9,'-60302029489319384367663884408030893999.8854209703537480818248540990234567956069965340942024890856088355839135538265116174644003927269495876835324407641642359213535695803871472434650475144516723617632059130297610134243891145006222068960999879308472500422640481972089756410157246974765071949782242392661524488959954348903412713930092273629207697480131360047867213863018127928853922173643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 179 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (3,9,'-60302029489319384367663884408140620960.5791215104639085369493197407183130560124286109130354360944260524553172025725325268378015783145476572840273098165721628341015996848028750420770651761919246816300854441592109844750954710317145008297946462099581451150385769713261452744310496166494545449824802407416426304041583975713483424241727236417259479541129474082301376239522310995725648773643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 180 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (3,9,'-3308379209762459471107480259839508279070920437.883503980178028214343751083865562028455061662673132221930429904398963590401793045470444301883103141901787466923883803951815572606105617157736442670792467625964359169270739534412932791178258858918086886061702512427989129732248215348301444245772127142869263635282888226326427510486246184233225114523636171202034558843515894542952126988613018789833835507734620046994907453602573865012044120483116345444810078666601100257620969379968264504287700045822481492526688635364586344704730579892342786173395802035361824932075736340405960099542224953439044947229246847140957298841482874444906129049023002897135347878048572628834749795298712449864571996898774444932083319581439741625832405434317985988163261591679157437224404970927012111196724239860528859217322132733404472897289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 181 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (3,9,'-1099128766678422054524173986658.839339966689456265703816212189145237878729886466041806078542573981227645802109969871638687985985845489422516004202630099080709709893022100481258818112345013009059633421290241583864468453396484606925071369550998772875840640325758308835852391176503689677263605949075815552026731067384737231681068134099746550363063940273625924224721503126912810251607546172009765059506591787282558727077669973711491157840340631805422942099954647016059576777054339588421998882440726473698513560202030309804089250300097589174314677765341104767702983421063649104691583044460507666600260994707192787133590502137391691330098102374713996115782701417107878938473243874299874872852713499024851414757892169376458916467621226859152075901273014182163212783658933754507272478777304254191033562324994395916168496097385872331012258027431094381') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 182 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,0,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 183 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,0,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 184 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (4, 0, '0')" +== 185 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (4, 0, 'NaN')" +== 186 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,1,'5329378275943663322300488.64471790965256505869684245785528331091076155554650629138833809683459634328609777839510066435612911583108717191216693735823717997111970662575497378762952496582183738308720094529950793570383580785385569873278068217936841324404119828637880370718028782103860007754579779716996004352284614661690063919125301052941328989181561787543541920734755989452320799185700078241880935083616978140555713297241612718277766918005268951861880490889884082730841740604517529391011862694381726143520658746305661338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 187 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,1,'5329378275943663322130001.85391741010004353389988518583956365616764439012730849109607738227723047091262162286043233973705463946054514004224903034208166782419414876904468730122054597840936856190652484801633363526576955397606531892764306099068756437389060626447578949162759295501062154826802212022414257953494004665588557188694447110384853149054690655645134564686305448219729651828678220200218922790293483596988037990835533058983562863141746692824117439019450865871047657552800448629502344444081260036580660700595591338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 188 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,1,'454294299613767152878025320780.534199313974295807138790763501115780294529340799108297697573066187975311338382917022391830256203305238757334106943821060545424417350991354829668286194840925251162479496893943917530660694097932059166013476064988623431110002057735318529554555260199417935495388243829261809007709919225000608711536928171687251088217591210419208480251102484043683131687013687838713055660405381318396419588727500715930145098362997142075433472039319292466570912777345841400769387321465602989947078951135489852486382469990409873227894248208197179481868230244584527040573428134962626267135732247029762468417273891700661832893497067151409134724061246612631376075173287264787886064622106855886785805818642123776489793586531950438285720668411465570116161790343538663297713926678759640594912243360541590368666922379919514826022141331900181') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 189 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,1,'62519544780217042176.800424689664850775296526267109332647921183817056683200043718160298562843864918741523494444361916531159341418970534833628106062976341639276761669219281771109561175175033739624472497927501467465456946098280878993371659461957361369508794842102784763955539708800574418468150309301129490186416766691183270872711413796386178009615777589066235359283212636467980113350635181915492452697347977967985810294150853782607014649150457138118264698071689065469752702524632313088938504181640435324554007553994564705401249228914199354821595855823113730697333390936834057091883654016371107974899726642500486005445063301647520527084320363513388355471718583708935211830796440056542408492723718088396437530207347815505844074508948817594746824098278470533148171941442049323578854023683167934569551595335539887777638716651319134577441') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 190 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,2,'-994877520673428596810678826533995.79421257464236160757218576989993781147390382997132644206786872350652200243563770552469933194637146474528320738725486418004701192337175478117026439697031462361180324038544450723753402846519731908503949116978812841497201119103409772457270340059605961197538918709309004130294868847110690336360689446090125918336908930881873778405661757289469281163974774492810850778950071063044769131228124355961427111369335109426492177657001035045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 191 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,2,'994877531332185148698005470964486.29284789439497020016891341359478477855230977564514122455228420261834881663435710678023233603955522003691551934167083188036585971868561017596992548582038556784300918537917030055337559943480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 192 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,2,'-5302078674303935968062773235453828254014583744527466365136.236414807326868572353809920518232561005161225922028750078608989965741402418802255050636954800114792425419735155504035469350521800895164087027043476055514245942961100610551646034472084954313670284875310691807937254054948742125729353864014122131419164449567115006621212424805182687707372956385102095255735458593389920872596796806885847543910224476727171570873698525606016990229936284811067826588349092841322512643043008589065847223683467371925773023109720951609815041012521485326120380123169545818055967455575736140138663815073081494226676896278654189873597341203197903408668523514375373841493189836809506003729379742035629498519683885268256481104619815130659628225053833297766479068686119691010593208135616363994230674606991733148502293102108193522604968743948323130517040609601859735899914987426089053869350663') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 193 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,2,'-.000000005356818439105666775800262590702859770599410113087721172791624002387236505438218124867814437523686300450045582100868990117124343222534568799037421944272316277130975314766456260710406160143182498931595199129228915695802952695510723443157825968340043198200740606202264287904755124946591110599335909404657109057432686191440989434662797205973563889238804413861126260401987949920244286377128599413927273444061572120561496904543200956508673923547626768641271397088562966176629018606103663605145666976048261236691866387601532424530473754175270500777679603569715192364542901360534980926452487443629100484491344001509360344122933911316486556042277769848194790964257060927912344609376571637126617813506411190014141992988288983968823792971270853369317867326071952900448455162898476163801382836761898292684175721846') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 194 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,3,'-60302029489314054989387940744763542234.98295358053252401308872309802346144227050959966671157134780970446370197110016237152333448347415674483796371931316021552756816073493808344537122580089676304958104270609762310229182150728136567294798680824019082599362332377530165818229609055765904048195574142709698758095302560470195171027219786996322461803443213101532716728918363951912367135900414238535625075942525108530051828834829820554490477645701692374399416239080329365045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 195 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,3,'60302029489324713745939828071407972725.48158890028513260568545074171830840934891554534052635383222518357552878529888177277886748756734050012959603126757618322788700853025193884017088688974683399381224865109134889560766307825097103477790782590061456916367930139323346273315068375646692125800496305291080749834712822775973790354498408104142209966769395239768969172107040437333428573572464689550003374384624966403962290572373571842567623422963022155546431883766327294954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 196 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,3,'-321372325955692885069615337209737469749246561535004445508427591.072860243358366933071485495726715620133686420023451450292996945184959542770492705998350644739298629407567812798540119555932604687814429669592481327761428042980782672136901602006622227365754036664912989085940235439697789102358431343119457114603363936544931303133371137532006899162833369543279729021228901466728220729625107362063321334489394782322741444425117731922691457341543446841167138481424319752111748042440994701571955325673470021626946676976482516292402239416632497972073915818846704053624707839813514171497746804751780741682011937606462260710753056669269928580460921188286249923152921382198282201761171043384698319895970192114563900025573490442674225227682235790590616707857188385274186584856872573669591460447105688151281208238908470285147895678001948902280493477604361481216667716971590499226735103039') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 197 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,3,'-.000000000000088378091435340426596348183959201660680284222502095357746364378698792730669202270228092348823133529449019715406417264278615046537007844589547485282959556860316942508808911542109265489435572674031608663747132688980867386885961271358592278360097086532747883342438036287136994589308551796702164612609710942175900921197001888540314760352113821737014875886635147123114456910985089625906448913621495025509697742196814421833448856595853403450682101743559369637786458968714240975228615283970739279506239628546165569688434254286341567486905374255702980370754235630955328837646999003123103831262789115646588779721625156078607919060762857866951417867378220773543985422722165221371084387943737083254760594128718841665355053236168688218864433967871311858292181233490194833547273501436630325295640020916257836404') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 198 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,4,'10658756551887326644430490.49863531975260859259672764369484696707840594567381478248441547911182681419871940125553300409318375529163231195441596770031884779531385539479966108885007094423120594499372579331584157096960536182992101766042374317005597761793180455085459319880788077604922162581381991739410262305778619327278621107819748163326182138236252443188676485421061437672050451014378298442099857873910461737543751288077145777261329781147015644685997929909334948601889398157317978020514207138462986180101319446901252677846098070081948065342276861225678086539994965165526535072979009589652953672647099592770056310833870145919866630936137861378128966356409101651457894504881209406948099561100916885616958192984693820003384717017236405797029790907178714') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 199 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,4,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (4, 4, '0')" +== 200 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,4,'28402272808100253242547006276715304015308580784958.804614276533085644370816876160290159450291717634111299841065255625515058118012211808741402904995080624675460593676923639082981788732031193774047612589113654423166826140872334380708795266307037944059108148612979119729408762532396036043629484049508789880964586236575769826806092391573178899640321403656891487586452524427223891405519836671312830183895761747460911777623703557946796784873885800089025388390522992806365773290733075927321101736155663727528284512100509273076328103465333687228713897893434161293693971954442699482857938492961830350598789444266860160794913830991304996676299650460125000959751177037694425217989910261807246272771711816326991282202653917488360776928533800529297474279497910326579608191975246060946079639658615178160271122713225105861574160788280907842327681375920919676063500116492292319') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 201 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,4,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 202 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,5,'5329378275943662669459614.81475694159581596077242547133292502869630735172901157043010370467618244548786897684821457816189831652076071977025794948484549600736179389638319303817478693948215387894509009504287664213474693208847025374388286162907794727810231557001266897729978691844410171412189947386181530441402903608214502713480332746271552746231631136145916685939539173054989927058122097304419584979598595477177513004218594211597809300517607260841648610322863666300637648662611916496850248528515936635845594390453288113296413254893687029540384176335735114863908372780241463999450547422213639667099644505472777149095004849805371205203850993689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 203 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,5,'5329378275943663974970875.68387837815679263182430217236192193838209859394480321205431177443564436871085042440731842593128543877087159218415801821547335178795206149841646805067528400474905206604863569827296492883485842974145076391654088154097803033982948898084192422150809385760511991169192044353228731864375715719064118394339415417054629392004621307042759799481522264617060523956256201137680272894311866260366238283858551565663520480629408383844349319586471282301251749494706061523663958609947049544255725056447964564549684815188261035801892684889942971676086592385285071073528462167439314005547455087297279161738865296114495425732286867689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 204 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,5,'-3478781676337858247983014311182511.567538638808357215203593479841446379226774481291286361639429856698999485760647422501864626078375852610019829111004807806660731243672830787729048847342063218718651165150612717759770504648306347926061960607388621011846314969634048226452709389995594961695723139571002939804473057725442880410434039783304583526414509590532906062732322732569475349107437896717416548237633532805602064623969799081086996320156575550896200848758685986331692388099427314008504506503745527468550106879602399030419569897808150076298414568875477195447656904373310322813412927463518325927626891046356679526447117311923853482118502868148386882363449163182892615259995945992014431502761210899772725227648729095696228388558331052524469604046072203605897109629560683446827492904111565278516043939137760721315953500281379039771826554155511347152') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 205 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,5,'-8164430956184510.184223536017248184022252663660196916321116266103608317725855237211273642694947892658721606226082017525816544904635887836163201565923338826779819876742736219975639586566502584026349778499211535661173597356253186281116862244165796632756909578140184577853088376334255860281874385669242675881761388233070861374295536603371778669602656670852115614651462552069294889723058758969660566508798011830996965570446030123780674316363670374970480994905368006454513642480180066435609577311074332150098288374616437489163254821095377348025470309665651059603665062887597814064136313866690824972464351274062540825405003954064175728198182815347642172934453828192850870808373638597839434504241236228591053696481146252072190903430582534862988719805163692697482513169856291048966811374872266165034373412719593685881972700171726777938') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 206 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,6,'5329378275943663322215245.29625473207137544719284446115519970394719946335145777492574745992986971075733570324679065009803281404581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 207 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,6,'5329378275943663322215245.20238058768123314540388318253964726313120648232235700755866801918195710344138369800874235399515094124581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 208 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,6,'250145412892811547138949.592621291590152419206270097656346630226508074074623894951308487425470437268130465956063593951784820669318897182831355375451719125809800516979013437732298382708070979871283132689492336823087794373113039154669229889503700598930220858275174342776478898670277868700384853696009897221747924643343353942154528501454689084608965009561564638167714973711022212547096732831847202912862290958304510651828842182545311077713664465815992616213663619529378061133917572474298028065850515876361609671565914027186063801852554353160801534696062207299890867876199323530337336273950892723090754719547285920090419070001019943385293110663922226230169381423410428577990604776655422105400452217085311617728003688836185608912367677734364834577573255789160419371322775733777518997638403409000055707558465286469808848200141192627396502735') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 209 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,6,'113543048739697485358574290.758354267447744932153707340542459183720907885610125346262898114677742971240785031722334497858930434531517077525413654346644836353208132641713415396062580605566225794048569430676355036264762949452090151450855446984773994337170590068740235544320694721909983307239491151139099779296496785240814600627140543144068640768857707110930453204162312973998304574796413938461971472337040811785231390930046688391955000749644938061585377150632133417156866197053052425576957646564943278156977176976876921235395711611898108821587442609611001702344783440618040704066809035404237786023075676374788819144406909313755996914145273176359246052899650387182222905558751208368173052381982668563471143298720677965028880626152749773712037769548408324298835212547215352657271696665387200792785056233953536347605130973626194099064678842085') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 210 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,7,'5329377457009123250369503.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 211 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,7,'5329379094878203394060987.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 212 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,7,'-4364411947278810125327066890819882483326918.05664098958260550284395870948992407314161088028674246708928421994893923699743452802989464864039994566042797942433140378990308345483670828497915478397481687305406460330009319949623844175096007381662809083363069100235985794575399268709260901964834244796150883807308976949196661411035264619638771824190014274817662519438658481432363824187693821267613212631153175155634316128036152465184903927860719447693468054624663668062006049759837326188252927823612718163916100588143128358998656306593393889422386501730237442526450419990376323903182669190482615734972147533221144682538647497701130447816148459762464395194383090936159579764712919396391813914821973715879062992249315474841639591907249142779103650773383644785606333916967894') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 213 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,7,'-6507697.520580964829176145824902679560705744817573189143227837387224410616222039115571544850095278317993922427931439719549137387753697989249394347047436951117850128104928719365703899136632100669607126357491484781141296021264049762417528697619931558728863308905257358126654378784709213859234056696519305650316810797382293500878834933984458810656133463638442959750083607649924453935287420620424368291770694630751828333903156364366745210911640207075765008558904788350844410055253643515389003711759818446776538393914018427075074171758415188027562645239606914126802490579848138218395145734902830046359100742374008993296019987093605275289913663224324033923096998194326249508491872193747944673057257521552387923218450155737056841633810711295424578984452176016198348344913655301417872189073133147510027427530833694019910340299') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 214 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,8,'5329378275943671819201468.88995490340795935797824952902333498786202536079000703830146057240651898748760197658486790165425772165585380839129948178510273188565692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 215 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,8,'5329378275943654825229021.60868041634464923461847811467151197921638058488380774418295490670530782671111742467066510243892603363577850356311648591521611590965692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 216 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,8,'45283653791262997781451381354094822.762732909505051438036873220502792213670540454778361182993875916509061144859281577740137081988678361247725064336120451090222456518107029158304937620179032477664627949959143233370320432203497828243297406462513350790251761540074946469824444452248386782451723637769289822576372357189700319768797708375563651655860093365309717823602754924352327588945034832436331911584742966378275504545736896430718939807674966738116698454215555860047859161126694019895490767779791933882712567492115664113775047192011252893773389940988533801360010782816196288710063568554147458866942816721046004257953642508395867837127678980002737669139369781058046396738606563716339660654364541530532834806205571191828994250708412638796240377704994928921528330863683630622922959130920715261879547446054261914770022377059156125037157979236658010950') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 217 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,8,'627208063620965.397582272040628872773601055303353339700043792111288801181637510303989399395425313995651311362368773096988861977687484912995632130587762386590996099363383976320342247076516604162469063709298438133327434461462906199160715395064249299615054970359309619951777972710299484596875999967582794277241285253106817446259313281064844416249524876385699646393555435017820686376877981018047574348711991428666249794623006175739581915209218834701034964043360823844816042368184094857692062884223864639972005010863342567608351008172649209459933114800143792514183138995700133608613158857147417653998048890116531052767737435620558349226865105888201598712435680481803901906613772821370519525404423549161696526405320391828194356063547089626322474164332505209233143121068245585662919687001395119229263995765376465304715643388771609446') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 218 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (4,9,'5329378275943663377078725.59616792993138452386059664269485161374191901124632386474661634799161523147237015531446709484039091244606359050341194730653343894986479159670583937529516163204904273806158788218327396375034882788180783796976731912141525319602448709213495905899041406302673881364465504945113279286939663215197485367850132991968081639290297033476859158044889351836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 219 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (4,9,'5329378275943663267351764.90246738982122406873613100099999535333648693442749091773779913112021158272634924594106590925279284284556872145100402039378540884544906379809382171355490931218216320693213791113256760721925653394811317969065642404864072442190731745871963413981746671302248281216916486794296983018838956112081135739969615171358100498945955409711817327376172085836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 220 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (4,9,'292388240303165948041827159734686.255558469787242316676287235194652580157149226950109397295920730296960145548003120827363226435916209781396711693581454960342091452830648929118261388933297036933167543189308061917640517578583521401267417187854611829815212778183983326568586118831109538377828156118900313778053576483381085207892754728937946691892849474364477434665960112125254104966566712906532318984871145605839506991591027939136026602051635433295687547552796828217859648186757719639965988287173297286034098497871707197092627676226053609131138590878743560287292934815277894463305001278326023708395571840850120055316276256138004565442099731931051413153564744766098053176049414330146267604802971221161572130161432525297614616942172815141372973870720928125699420370428856022295499447755488148545048400795053604349570217878099721865670458104653570360') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 221 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (4,9,'97138902640718538.241246716463110895614166618530828908023040947887095196830690221211560526562522274118188963051412359798837957512805692731972838989047910709158995922699598619854907969493232150042212406549916252602794415099066259707018021422154933830674786488990033885447289593742424717170197810316367637885248684134204152352748803532396210051700193575105804898183523770153431536054848843504020390623875664696278263569145547515663340450903772852615789980257449146000410036925975898331113013857953289990299253584950458042598491897496393582249411290555264437893099880371008957017323366523688894303458743415715114628052487518110654201696604914159777300997374156315186315524817636714210119873791848535246674326877611945112249137224923201544452904111118569299934059002046318394345055859769572070097973298522564724884895879226870720839') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 222 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,0,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 223 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,0,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 224 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (5, 0, '0')" +== 225 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (5, 0, 'NaN')" +== 226 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,1,'-652670387.03916046850422757312745971450663862747133703839829692066597367760104802542475264601221776157515632293978442027199108085723617181683235487266149426304575903892721468296143475297345699313102262188759506518376019936160961709578829069446312051432780603656651983414612264636232727512091101057374054475214114364113300402823059519499217878746766275164739724770556122895799337810694888119810524986616938847385753562624139431982468828696587199570410008890188532132652095915565323400735066310142303225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 227 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,1,'-652840873.82996096805674909792441698652235828221445420381749472095823439215841389779822880154688608619423079931032645214190898787339168396375791272937178074945473802633968350414211085025663129356908887576538544498889782055029046596593888271636613472988050090259449836342389832330814473910881711053475561205644968306669776242949930651397625234795216816397330872127577980937461350104018382663378200293023018506679957617487661691020231880567020416430204091941905612894161614165865789507675064355852373225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 228 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,1,'-55643106304872.575994253221940844841058071061962511162776681458310912066379595519265546225338405882027547140476045378015935579066580347282075024392379464189067155567624835346798806677988850250198082355055954078446421075165109896091047534711081616362392995575466807084807876544560268050611445006601394735810211678919646667455478469014906335433468365011768049600750224822391684377238242162320161552720449713229523135506671063115436813348612986916614320012995541575293478341408982118538094438068036422562665160411591652618670802973618768526197813319204816293073794413317669922144705633308090832805914096147659820167569140291210526520361556881576175809360614782817717579318298657744021133210954279487777567785280633309576696708168342539425395482429923273623865667723482418178781573723597156804085501875735112311466228778929147929') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 229 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,1,'-7657.550797567691019915353529993301413746369700087741672762343206271266232635965032053368224472333368713006346867984576168784127503674579531243603836945595880917241997606783133673324236134063757452734295148763280059050480246827193380861494669624151921824660313516974440913733511526807313019192263170823268678149435664224184903925632177789052038092611394447709922076676981043877747276056677801802695466205531230350209787298926245402046182150996849906836743231861317120171583577624262765589605263477198809166390259128339127005924586833372241946051704497188891325715185091060185547236923494393813210904033520844572880475265306843414506359253445517738473745552980984097762509546161690823646176501838559393690565709795724159196133663168004773260451322595899506776323262195323943138344537866088159583331807728944620284996') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 230 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,2,'-994877526002806872754342801504871.47809095279915423939648794226185974985600242391612965412218049794216637114648812993201775787765690351615479957141288239552036371132381627958673244764559862836085530643408020551049895730005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 231 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,2,'994877526002806872754341495993610.60896951623817756834461124123286284017021118170033801249797242818270444792350668237291391010826978126604392715751281366489250793073354867755345743514510156309395711933053460228041067059994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 232 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,2,'649411906691138274293985410502516861224852.2323455192714410716272307781034189160865613770320102043319541634113746032638191509585045862973333645830298922352816245477556264222094036953195419857712804755170632292914187367964994214922001758104594052499795564860466055599417895782179851297585155129541589802249540436678824225950907268084876110445460948679383611117263673106597132046331719468816839434908155684738864149955129235751738204036443603521478609787295079710078973503970964790273461142497259987849074597264522099648376356902360358310245001183020992360260836105404118742418040965190000718736837422434593694808973939805954329718232693154128543253581495885789333274488461716809104532693754070810202831113003978085636579574171344721710232931261731022478029314435363413498991740750878099825781577297965642009156858479681236085226911858782115') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 233 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,2,'.000000000000000000000000656116570506105776235076334177868550033347254561166417969910286926369599900073757929714260350320362090452092025380232792749476245042480546813848702351830607516880397305138543526307608094143028291193163613755680419049060162928958489964834941920423432354996040147818253087783193280640282263490705632002572757216731766513434035163528102590524432221718194164133959630768718395847710529339782880381264265894322494716854757290930538739000043383104085867828258790010654331660516512156519838978751447311068903958136482041673109857552178367614498426226323001399275980281507353231821022591045797658991388304873240910526149138339658220844723880158150606035181559877351791752701872877147074033569061408920725522180134133183999181370354585872214368766629114773129541658653693832843354053701079334077') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 234 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,3,'-60302029489319384367663884408738513110.66683195868931664491302527038538338065260819361151478340212147889934633981101279593065290940544218360883531149731823374304151252289014494378769385157204705433009477214625880056478643611622410268943757215673170753460135411513114716313801477916713433956086133878890802448531292334570886746283905390661877220497842493537338035961123751393889400517474762491881277080205381424363695095196058838349029211365212855028824622924678684631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 235 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,3,'60302029489319384367663884407433001849.79771052212833997386114856935638647096681695139572314177791340913988441658803134837154906163605506135872443908341816501241365674229987734175441883907154998906319658504271319733469814941611260503645706198407368762270127105340397375230875953495882740039984314121888705481484090911598074635434289709802794549714765847764347865064280637851906308955404165593747173246944693509650424312007333558709071857299501674917023499921977975368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 236 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,3,'39362489275784146262776411377472433635883331946.794473520543457442955620133347015506556162839462623905489255080102447195050109095701660164272430316804466254467810714209179752718730906325952685817112992943656292503112803950215110778476301809440329937774061163668461957943313261962261081942055908935814323069621279128270849852239727888939033546870208376394878842958202403235309372240005941467570230067124830916866857395233038346727879951123599893174252558078732888910139309038957525961212820831321973219557165558911222848692996406741318948607549825343491479728117062814094258484536263158005174429922237853707635743736923521032098496725445243775790161216159399180889906705265012270270348146530113428221072591696851818281866095288773371414866822270689959827332258348570976075184933893434327278299820594014788148344260948638847457822697682605612771344335201258128') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 237 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,3,'.000000000000000000000000000010824770508763323320533297369674519056450544793568147911931789010432012750062661590994728968589403602468229106206242395792957238667714358401601098858606386995096923432407249369639633268143022787987190106724545750803196130511146323174462918572423414631798141263222875752767731279138952850500369328934959764805948568471324562210715908420467881411844098258193571194910997918428786213948547748701831331312040839544355427357749520227124858111324859160114175254197992204974033767300989488517391063188153561391320190653403747521648794370679322504188364455328709488846777004202196382575648619395139553279192346251133156445942281048959845827006761160755031086836046398020850814350246219929303018051720203943879538087954853996826539712240458022307680912400297508925714946398031304516583939283') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 238 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,4,'5329378275943662669459614.81475694159581596077242547133292502869630735172901157043010370467618244548786897684821457816189831652076071977025794948484549600736179389638319303817478693948215387894509009504287664213474693208847025374388286162907794727810231557001266897729978691844410171412189947386181530441402903608214502713480332746271552746231631136145916685939539173054989927058122097304419584979598595477177513004218594211597809300517607260841648610322863666300637648662611916496850248528515936635845594390453288113296413254893687029540384176335735114863908372780241463999450547422213639667099644505472777149095004849805371205203850993689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 239 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,4,'-5329378275943663974970875.68387837815679263182430217236192193838209859394480321205431177443564436871085042440731842593128543877087159218415801821547335178795206149841646805067528400474905206604863569827296492883485842974145076391654088154097803033982948898084192422150809385760511991169192044353228731864375715719064118394339415417054629392004621307042759799481522264617060523956256201137680272894311866260366238283858551565663520480629408383844349319586471282301251749494706061523663958609947049544255725056447964564549684815188261035801892684889942971676086592385285071073528462167439314005547455087297279161738865296114495425732286867689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 240 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,4,'-3478781676337858247983014311182511.567538638808357215203593479841446379226774481291286361639429856698999485760647422501864626078375852610019829111004807806660731243672830787729048847342063218718651165150612717759770504648306347926061960607388621011846314969634048226452709389995594961695723139571002939804473057725442880410434039783304583526414509590532906062732322732569475349107437896717416548237633532805602064623969799081086996320156575550896200848758685986331692388099427314008504506503745527468550106879602399030419569897808150076298414568875477195447656904373310322813412927463518325927626891046356679526447117311923853482118502868148386882363449163182892615259995945992014431502761210899772725227648729095696228388558331052524469604046072203605897109629560683446827492904111565278516043939137760721315953500281379039771826554155511347152') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 241 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,4,'-.000000000000000122482510461124748279475400009367345900846466958806966807399903713411658400733717078392550780910604704603123670767210550800752620037863340961255721285160854785449315208955654408132775022766783343331151895973970395232686910362226184006990485313002943710214511418310741271074710741339586430026286272098156531835438969774325517509155992092194349661122678547097423264670055720422496527272118788005921590521726691666219504214087867030003203385360001614199656989667055583749577099440092378355805901262289841168751608673297446473709956390142112843400255748161809121986096092991616144443486023218404881798896685413932215981950393130292001833627899480153863300557853617312991880655905907971211246077450786084079040513198340644157868678782195341316027563717617074364438885981635394382733697473265872796207') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 242 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,5,'-1305511260.86912143656097667105187670102899690968579124221579164162420806975946192322298144755910384776938712225011087241390006873062785578059026760203327501250049706526689818710354560323008828670011149765298051017265801991190008306172717341082925524420830693916101819757002096967047201422972812110849615680859082670783076645772990170896843113541983091562070596898134103833260687914713270783188725279639957354065711180111801123002700709263607616000614100832094145026813710081431112908410130665994676451253271560294574006261508508554207856812178219605043607074077914745225674338447810581824502012643860446309124220528435874') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 243 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,5,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (5, 5, '0')" +== 244 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,5,'426089913064020811.057708378200224487694731586862745370027417544052374884336177893807736467646454486029424673621605232432043672119510371547153895504456723242262639262542904151307250842477327375961936454637964429999741717244285121019840463692418987118402683746281993192269229200465080358289645050337976214115902915692028162689089167194843185708212911364017271332623359100711545479273675423617018342297822477514128997410642005300368966199980354369928371655155437291469427189561877718971914040675572136507472590254222870537216617260612835805368361975725573009455402822669103118872235140158440342063571894152305875004532651814592458133460160514384171804043127771746596286988679698684698755896736275307574630777027620558428909546664763675431701332632828281070572045822129984625797185173815273651376003614106277727279230096226977335510') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 245 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,5,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 246 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,6,'-652755630.38762364608541718463145771120672223443489913059334543712856431450577465795351472116052777583325262472505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 247 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,6,'-652755630.48149779047555948642041898982227467525089211162244620449564375525368726526946672639857607193613449752505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 248 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,6,'-30638438.151446159804025029882398388155309149089870990062944469684482366692824338098201222171115395923414887930224163525189097571163687285244255335505387733673499447610577050114902372990462064696637481657064525319516004273769831260452832960893174173254560250804003884280384718123289136453955482855362019158401218620018346500189769819687260476334734259702665316562988639223597110627626759216850014150105605927773639897638043177685498804811787888811168524202700283461266793154726325540776914500415140842975457394524215869103737379109516024460317825645645301237375972914247141703084877141866316168268901439172491577729880760950895760711857112463508064820414904611059588717092145484656103798852859978690742216940980929562068') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 249 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,6,'-13907037655.047994416383638650569341223199042786813441967582376077478024677494832069402897226848055043557486983268019376307288565911231748501636517992289743940159005664424461285010295150828744259113760652210086696250085454819340987566229400805422509198052317518991183515696724846560872057916862620762789778660622787735923967096950195583369113574365386627110408307941105082873469072519133330718161987781080307947247163619814890462416622144825161521790673339279047700672881113718394727610096366361422482794458375587355933614201638489194194834709433413694420512869179976485096875057742460003147602405353823942488343056906912173170809084207937229591627643451380735179767199816663168139837088183577975769442341678933576388936845704303859241320794255052627716474860113993958556604381707826493168941926878481079724185426298004604') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 250 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,7,'-818934540724601372.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 251 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,7,'818934539419090111.56543928171951166447406164948550154515710437889210417918789596512026903838850927622044807611530643887494456379304996563468607210970486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 252 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,7,'534564131989234694540350103.27821462973515555648644772098605028371173048154132108733819196629002548296868548691993248746628993380136454426833349407578676005545111508293942736555269938962058196496152360848131645787941032968937794930046928523006455386861100809286408671908320322523368135203881520526880998279355848280412933152306299256343179622513731096363088094541514890135766460631462465021694553063366717467560655272004461368865264059368514271105464855575429914212085797297268595943955105608543373940035636033207568676745293499106348500559628723682588033431457023964317090780615020801564861497990103549650624438425421690193862533733474254') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 253 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,7,'.000000000797079129642393611556079160915147221153735075943759104977169600937534508973732991117540626046659124172765761873705978811124901421049332579161931652390647472911517923131800238903184679028518657818755558526885018755394697157094867449047655737107085020874974955627907737126958129710597811740696534189608639914753884882702680512272194316887744972931453458445314561564591875764930680945589486999586667912816485821717403892703364322658245615895415781719033810595358092343690359557942948213374234065052300866661453767599465059289920067095083062096458980564265691295895672503728815182981118876144075942348853666085714846210822847053889733510154276933759200630639642310562242207518883342516103725757482864105340008709446643820864294556778969997115586027866760708448174502158738150605938364482719960251612464993') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 254 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,8,'7844230593.20607652525116672615394735666141304947992676684520382624714879797087461877675155217754947572297228288498221620714146356962938009770486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 255 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,8,'-9149741854.07519796181214339720582405769040995916571800906099546787135686773033654199973299973665332349235940513509308862104153230025723587829513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 256 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,8,'-5546455599206321494.0676583421119904300307105296377723816472192007866147764761501865875232824814135783697976183493106885436876081315217834621720906478074798596116645640251460842350553806256223963023430631066024389364515688765194373161385579258482225808660340732705687558150699172147896486727530192499184101617379930846663835628510376484675411350654979679181852179924386290069790336316958202582966248703889464308649631486542724072047294216362186036638115240070658004553260251510288423749333873893917690832829128021808383128393431810674177390352413548658782609064839524756041501835115152819802758773711821322162752064589750295542985780512921839490040396053737870038534216948323935020460307350020911362024271167085905714873548388570602799432705061561572854498075600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 257 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,8,'-.076822018213756690975099471985461347542955923191183223634407380481978143225129486622351714276452369661632980197282261508936298649901018470846144321441236073683990324039849865750139470288565622579952182053792815638469841531577235191276257498209844422440366423136595067535337374223115507557306455001792362506235886189722508617024948653046102060677266555476719102193278190540414934812073355995577639986512222998268934000209944414236509139290657402937840986061987219441410741189615344050459067454369371094189930607834375561948483494321255500497786795636801854613881105643003358210407867114145806225724880370339074242480071595684502491827709175732777776915682786771730423733673667248186336046898260378049328204094804755195626798951644386924178161926128482002518979482630732440619051262620098544265763306253807191182') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 258 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (5,9,'-597892150.08771044822540810796370552966707032464017958269847934730769542644402913723848026909285133109089452632480800168074607090893991283808726990171062867538012237270000932798704781608969096508450960185964292594677356241956277714380500188870696516251767979457838109804726539408115452577436052503866633026489282425086547752714324273565900641436632912781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 259 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (5,9,'-707619110.78141098833556856308817117136192658504561165951731229431651264331543278598450117846625251667849259592530287073315399782168794294250299770032264633712037469256688885911649778714039732161560189579333758422588445749233730591792217152212229008169062714458263709952275557558931748845536759606982982654369800245696528893058665897330942472105350178781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 260 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (5,9,'-35812445701642379.972368737320206275515144213236752803936806738624588812089615098329765811617509505790110909629109400553415312470540217508070421816878544125783329593128638405659896184248784794258084116406472768709113030915308410565617764394827427154923321461158387012978726512246146545834669665093228316853342805604075936530371665576147966721599968786161939347726656168798065647411457701453987215491345496003650288850096338695703984042549594979897253521041581573388369367579323607093487743440894765114619634001789457486407909224339065748496715380572175183589195611952939575073075140094901024063428239223964510824958346570603142906309198033196987949067156046076497974760641964978711558209708743776024313916111738542765749928287600981397080809041007714387564206594515733287925008053261840295560398311905155157989225181164097547541') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 261 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (5,9,'-11.897816658873986795664687519069203701902563457968097729876034796143085813450454323128600602495745166997629078984618283588337379184733369491549230343315369634754204412939757136108898254582353378508832611703989221079986765793923635928759179573599208612516427628403686659479459867527627014558600521732194240404211484706621458983727740143568799713006127585168144158660566534382037451913967363675002134687952374080694449905223371627606557311710348820900963340884001770733452314715448053233208783321215998063958966729954113843581448912079950334969908657535514847005768455377990262943747367245613296497099716892292154137652893990339292671106003657659470243633112063075297194691349631518467702876183897580432003030164590920118726657290102377710611324297862045849839571689192181090062958059281673245670440852080202548743') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 262 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,0,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 263 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,0,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 264 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (6, 0, '0')" +== 265 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (6, 0, 'NaN')" +== 266 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,1,'85243.44233732197133191329295927531563604777955507322414928382967007765263923984471408038635831036097817458527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 267 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,1,'-85243.34846317758118961150399799670008360696356209219504851646259063690472663252876207514831001425809630178527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 268 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,1,'4001.075404054519813215296429095020391062109905613738157927030437221793757373268325953178030040276107574363822832168160758728653712686313134828282109532831190239521843808940611025488601517574653932032236616573457735900045655665690517797280666732780030171712864961531623060353548802466577910774711998056232872212688464691036260746751992072745518373073825852119460094113694393273456369345499434994672730920070410547163082189385645712866100999708173472360864669110044660667614583576570496399103026286828660558854973376227247132815728164629722965145778698957093136175449225024685874279280018547740') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 269 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,1,'.000000550624150700285432940805295709861455424264970126953321538967550091614148982212874391026630805836518138806917934859138493583812313778188030836027246840794439412443826640206464415527687555214009725107630387889854278497875708390050387195108441635824296563108288712340902423706104029452615686971019125750530034798026103476074158922893374911891438688457439945897348811702908216883650280617098402133628688982793791562476980709924382381505517834196446365877784931355599480881104446907801805570471686295270927836995181422963320376948188855989986414581755633425437161760674162177776773597848142496583128607548351599750592863590334617838124741567654525843413232313914310487355539260264225486180000012813397807525203822863232682089295055713257835007742845010741137213301116647610033909062369843750685396196342928455') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 270 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,2,'-994877526002806872754342148749240.99659316232359475297606895243958507460511031229368344962653674268847910587702140353344168594152240599109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 271 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,2,'994877526002806872754342148749241.09046730671373705476503023105513751542110329332278421699361618343639171319297340877148998204440427879109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 272 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,2,'-46696638263247522384986521136500.479312417066793299922708112595886608370451213741279484136907754744903470430131032928908162742687359367826808123516519335458861613010646992354378739165872253762686683966945711430182491860196341344982195078000259063231136011430995647812149294224699587849791008794261026932467933475782780') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 273 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,2,'-.000000000000000000000000000000000047178744084866106587600962473825168237820701199970144691815329658682341685812472535816245052671243808078367856957579485152424914481414614360809698177236664771558713606961423658442962083541733004775309314926918118528217478256885324362912426275407382550929085958089798861918760121727491366034496581249711153289495601712583077918760003840368008056353090552282274780428335438032908213783490070198414584291402513547386013689752310173492320159738977752795528725029134841933604057954874523842273790958618375118974623107241366036640538085329921129023905888674299774726871808862832797230915933851225308164365269753526489223540580759951230801125605963901491073619448437890841032149898629231552019804656219062534881074125995130202820302133432951999011667568746004715268323913437054078537') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 274 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,3,'-60302029489319384367663884408085757480.1853341682137571584926062805631087054017160819890685789064777236456590745415460695320768374693076860837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 275 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,3,'60302029489319384367663884408085757480.2792083126038994602815675591786611462177090630181693462735571643935716818574980747701251335721895588837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 276 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,3,'-2830400711649493468815157129316992649.40542786074520931471973065281957756940496588853021620372179463538053123396140685749478530925306163968207226329985017644835203709485594362663495728106061878665324856417118064730721101615473194292620972173690618491026470353143141125614124440035267592258385099934706896692953497971326605145704135723011753705907329979207428661473172503098296622281647255008204864404416199384701720347319806375450632245634238172654086373193251877533131784268854289406126119630708578053354762596511353053106459297339360827562281168219966099848212') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 277 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,3,'-.000000000000000000000000000000000000000778366376597400971124059102619954214055884926284646546105035591052258074563706355894551049631537984053410850060739107742208523938741961208742831871056600773325053133977559789796700130019975964192371715826863472981072974742704091801166438465082519558956925444635729210849210496466189037623555622901738570979273502405907969114110345815802999687171113749364073269902319653450479463404003706147915064100959774312307195946966281098140229199529866429134937742584938255441169541436021827079647129394362379406256722903991353136733939395366152312959281905058592776286736536360235356737359904478313225848562436632109470589310799000750518904145312512621838935796912993778920622238202744037977772169066929474233952081158212174549695244127987299282384885288897893503991509410567351494') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 278 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,4,'5329378275943663322215245.29625473207137544719284446115519970394719946335145777492574745992986971075733570324679065009803281404581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 279 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,4,'-5329378275943663322215245.20238058768123314540388318253964726313120648232235700755866801918195710344138369800874235399515094124581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 280 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,4,'250145412892811547138949.592621291590152419206270097656346630226508074074623894951308487425470437268130465956063593951784820669318897182831355375451719125809800516979013437732298382708070979871283132689492336823087794373113039154669229889503700598930220858275174342776478898670277868700384853696009897221747924643343353942154528501454689084608965009561564638167714973711022212547096732831847202912862290958304510651828842182545311077713664465815992616213663619529378061133917572474298028065850515876361609671565914027186063801852554353160801534696062207299890867876199323530337336273950892723090754719547285920090419070001019943385293110663922226230169381423410428577990604776655422105400452217085311617728003688836185608912367677734364834577573255789160419371322775733777518997638403409000055707558465286469808848200141192627396502735') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 281 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,4,'.000000000000000000000000008807232244507937251856465017967626593430084223212999583902527587737263981869382895220711835510154989851222501080395520249593128253795609198666884523792646863341248402687314509176781281863891589925961900674092953408613128961234166906173266411035009516545964362406728942021813644419154548354247112601793685146960840364604115937119024575638240439041250900118977183124605578660115160551830946251713350556181960983267689939549506518185340972020820080460565392359379680036788592213479105831301723237102710863182596413567756605711230290883888612188805367801369264231165178487334557824054205160222371548005742602736713668548450400926514169967213301919971189065307721110805424950794015852531342286935114651278691214233054575660712537044810163930633456573860895791198853393107188289695511873068') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 282 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,5,'-652755630.38762364608541718463145771120672223443489913059334543712856431450577465795351472116052777583325262472505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 283 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,5,'652755630.48149779047555948642041898982227467525089211162244620449564375525368726526946672639857607193613449752505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 284 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,5,'-30638438.151446159804025029882398388155309149089870990062944469684482366692824338098201222171115395923414887930224163525189097571163687285244255335505387733673499447610577050114902372990462064696637481657064525319516004273769831260452832960893174173254560250804003884280384718123289136453955482855362019158401218620018346500189769819687260476334734259702665316562988639223597110627626759216850014150105605927773639897638043177685498804811787888811168524202700283461266793154726325540776914500415140842975457394524215869103737379109516024460317825645645301237375972914247141703084877141866316168268901439172491577729880760950895760711857112463508064820414904611059588717092145484656103798852859978690742216940980929562068') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 285 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,5,'-.000000000071906039575366987930696117572143566208825430801491864851999044659045681114433294052065377679745375399878664822361548237094424148992770296383642432040129230180142339557437679166815114510467763288057917694948929009212876391059413439647163295629904270262780935228234994930653489111444964446097124407804311494588517082748514970905563707392765567625639455978464081409330528324962333492925267647686759704415549221137291475247571296491073010175087298752769122449499990102435819414671847617062560524758344361194566796343756743243766853291113852464023843527189221162680613675369708907935197867458588904367993736363321133720345058432019986643353417257503619558797249295232894674255060861358071309619524800424087896023710729815248847792174290644245138831518072176198607255346603270853333176255533974364728342822') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 286 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,6,'.0938741443901423017889612786155524408159929810291007673670794407479126073159520052380482961028818728') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 287 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,6,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (6, 6, '0')" +== 288 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,6,'.00220308874624532134736695825088747995945783791378828770826401323533973395137378460250799184832278118133622563295093909508983301127615815865216895482784469538070133388154961402881325731054433770884496') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 289 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,6,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 290 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,7,'-818934540071845741.9530629278049288491055193606922237795920035094854496163164602796260436963420239973809758519485590636') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 291 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,7,'818934540071845742.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 292 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,7,'-38438389630389612.0042045464692275627184627672063157323631169405883031379129843031477339360597564128205768842448328088') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 293 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,7,'-.000000000000000000057314803440765029050667129936880528769333499793237773980613524885506515999851858649385968476426313207429914995755091541422893944525222307473169425244462149015717526718376299808423552027796204632286454853167559026787019718806449038446612978917236245943248168920696452018925986743620392955122431521581268518101342690974749463089739042586011924590503136498488946387508310209984849243014542648765897536338824721211252335866349509669538308454367849024503312249951727948786393404944555844863805495937835281927012430439403132382055464307180153473189842433614777883826783689904293115204700185380661601223693428304020047393499702811581067120117405280772944184877279069842269329959037186324135435468322336398566440055479142909170224780318371473684868152271947368867666706912563225912012901437076773416') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 294 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,8,'8496986223.68757431572672621257436634648368772473081887846765003074279255322456188404621827857612554765910678041003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 295 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,8,'-8496986223.59370017133658391078540506786813528391482589743854926337571311247664927673026627333807725155622490761003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 296 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,8,'398823655.819545574205652791249227663407026876411660299394659390409794761643751582473390322547798567169668246138880832642141417531427935520467563318363116897177899262525720710134129529640376020947774470933902793259531840625444267816319963200') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 297 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,8,'.000000000005523967081937952184172713994498918048454262874017009201501812494019618863622631634736130436187167745347383745890248619882896153083428308074678908731005176810208100004498415662458272149380846809398637385270265351808328466537502823071145089961996689711299405627596294988646826454676198092260759424935699382655736524042353938814268760468122584678267125994645166955751211397353140569987758938572953312303398024147927938612934833827734142292697389251052485981023756760420972614486278837214553818521196182883489483756785207650821722660455451660719560529693418375773124813290305501923899840247103166971466167032437598057958226806335324315214908788839919408525748236713611579486768218564733151121028172253396652755590051310396973181595992981076269789287489208817712754098019817792758730835341151711523474207') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 298 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (6,9,'54863480.39378734225015137845671346015520435061071252892396685718794832880965812803098645730572474084523997120024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 299 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (6,9,'-54863480.29991319786000907666775218153965190979471954789486608982086888806174552071503445206767644474235809840024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 300 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (6,9,'2575131.137912978352131546639620215541477987701194164886305951830806120142596646541302305984776928560906754259789485960991272272782091464270104432109904222200473616116525297615725803495463468272171161659654385929185160689572943852767523792651123455283534072794326647404332228203001469884016996499768656263775233430922446983838511590562929268821678518640501686017030536100955531423152839988008496919169395159653034847677470665418765966542111749439412') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 301 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (6,9,'.000000000855524875533453524582534418967571681572635027972658867593464437484123442242521660317156546196609749230372398872487667521984251509483676665788527375343148382604836976332389890799079878151841905152004537926201190193814594954194044560537664560344224646197027029681984683465852110060077865421064400958821808374370779297676624123638191407441015008434084079839721156870032377372497814037418047056438760664237367081226979226606227037631073946209105678283624370820396871058367779887709720661001099338250009251834581804647326512873792849059661525874160414378459696930831877643599421297749483849526695657467708603491876916749718079725746259119898269814551222336219537198318796277931946529242436502235147453584237994498566122973953203597470078105606906752099294162422474758048436539653041606499637623370030079916') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 302 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,0,'-818934540071845742') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 0, '-818934540071845742')" +== 303 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,0,'-818934540071845742') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 0, '-818934540071845742')" +== 304 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 0, '0')" +== 305 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (7, 0, 'NaN')" +== 306 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,1,'-818934540071760498.60459975022373923760152136399214017262844141729040109985386964272131706381326192223266583769046276181472898406504104649192224392653722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 307 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,1,'-818934540071930985.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 308 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,1,'-69808760806266041400340.70700818693892852138813934414383886494691670042143650609934777814995087699409404201920249076407981012095999320858479644760715204999741683528746097757549835956359129287002171391961763797857794730120426599135099619822532290339000466211195776337667123320942107370731349851576864242697412616810236323676004067839744992733887503405311090677026008324895177587064547630828026123718296429295638934384446325302964896473296829265805737112709269803814942537657996725913938408781715328945194948010970') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 309 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,1,'-9607014551997.140858001442365669993007297071681832468350855627077185145567261170534005832165603932891201648027598773639089125980996652005412450490063683624648655909636499261774535015914730479401090227915382926027949990128880284298688443593909017437720828163877690126019616194376778317148693270900349151496295698078575648169637635898560612738481294674167553369445426793073304518646116539082953755973571046622684332425840412198776081251646424875405772676893185726872613804612566569794177506268399878105117763696990094108960076591684779180089885283939385808214239337829666227427148603057941899878123459708920227867371285837642561064461118016739395972994827327543594846953341750907541716807985738518071480209106185726125017342997283356926976052909493074301401955202616191210810331245427141945840542129607439703255628683506772979') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 310 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,2,'-994877526002807691688882220594983.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 311 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,2,'994877526002806053819802076903499.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 312 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,2,'814739569184924399102711674444306584731316176345067.39834031417849342571224916231092924046722938910652929295271097903377854123984307101079073134405782275535446337229706620713104545454319555885847481531722101704765783025789147453570970090') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 313 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,2,'.000000000000000823151110229758332661330617426417726331211894330147399760458555778324097596176117291103184653828305857999638466183347321835058943563347767579219763002258622507889760416640758842509635599414768344140175277742935564567127659688612699366182158030839083982896107176174766408199870924563237827899202849733606842856491701660599599211106794572237923985121475458446997860253437578966578617985764298513928307852082168209458400544457824307270777530312648199364084272310536024283945598340590403612752287693234647719354745060851129534452514828239800716088248915975054881011343555492596002595181046121935660176097475159074973635534016835214952415720717896518544064238656360099884889450237541254761746029507300068198731306211736696956568648033834554273602524147075895460874922913883751452403825099444642503437') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 314 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,3,'-60302029489319384368482818948157603222.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 315 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,3,'60302029489319384366844949868013911738.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 316 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,3,'49383414785234649002982046297226894664526726187218771083.0993243619030008310875293647868815940421844461627295157812843657782639833900543200310573708100000958929315945039020410482966753145208427035917753919085618457760620513481628641658765820294863970581642745379331727722585319163262763708386199720411053619449096019862596221607526610103408936214184850115071874430846697061554769773328338028749631552202705583855831155461651414320570061181212214810086436100771547030013079997847086') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 317 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,3,'.000000000000000000013580546907080371873577430837141172674171921610919544849037647398734065712983603204704663262116138799357430947986241590690589753181299773842880079777640016786921825609617596862828930939366173224366864448436461306602680780407912534492687474933386043505172346330210659476505435994582446405414027199938970759003336829722057241708213838318628292667946636226143164221380503228191376939596663443230082698085439531600756771639601022064620204571458766303985028143400866776954225590745596639602613498355332049777798367675438365442468743270334407716567057368347458892075084694158566383133325959042076573734408841629149903649365079563374278550978052491499304166424686842598833319515705663176855033865872333988551611996194856472662292344160194821687681312501127516922809221030420253714666026321243515830') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 318 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,4,'5329377457009123250369503.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 319 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,4,'-5329379094878203394060987.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 320 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,4,'-4364411947278810125327066890819882483326918.05664098958260550284395870948992407314161088028674246708928421994893923699743452802989464864039994566042797942433140378990308345483670828497915478397481687305406460330009319949623844175096007381662809083363069100235985794575399268709260901964834244796150883807308976949196661411035264619638771824190014274817662519438658481432363824187693821267613212631153175155634316128036152465184903927860719447693468054624663668062006049759837326188252927823612718163916100588143128358998656306593393889422386501730237442526450419990376323903182669190482615734972147533221144682538647497701130447816148459762464395194383090936159579764712919396391813914821973715879062992249315474841639591907249142779103650773383644785606333916967894') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 321 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,4,'-.000000153664179510102140733858340480800294287837601105047285453457000254577644933901525444082336054243749405512900867540483190494113677173628646221933766421338612376123824684592850465460156248403574333545090544920568230979754949827013129083778435107488003838746926270955224758508832133483591156567868631938590248213604979638895901933775098150684618378235712437137852195098700137765601802898366867034641606131280434771339920637353140131159441790904703083143627590062236537714415872864218260252838432414759890832271190606933534662897006726154587341385852258168335058931957995901987808602365467861573344491265289043037273815504867254228957776127752540924854546837197432384563153608878864912196453587628891285275067452280357349897203095502806923463147414086919014592380804424300739713935051357374227246098303140106') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 322 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,5,'-818934540724601372.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 323 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,5,'-818934539419090111.56543928171951166447406164948550154515710437889210417918789596512026903838850927622044807611530643887494456379304996563468607210970486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 324 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,5,'534564131989234694540350103.27821462973515555648644772098605028371173048154132108733819196629002548296868548691993248746628993380136454426833349407578676005545111508293942736555269938962058196496152360848131645787941032968937794930046928523006455386861100809286408671908320322523368135203881520526880998279355848280412933152306299256343179622513731096363088094541514890135766460631462465021694553063366717467560655272004461368865264059368514271105464855575429914212085797297268595943955105608543373940035636033207568676745293499106348500559628723682588033431457023964317090780615020801564861497990103549650624438425421690193862533733474254') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 325 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,5,'1254580584.048971438599349046867230181719371038956756285986415773300837165755558702217197735811549684202279755101552533605390208155708695952004683670878589028717509749282693444655857296902117478518511492735290086040573521482737598395369632843374456793385511847676556826348943588519880411018079886373631771830925920986588708409208527042927229627786932908015502292313887561198156623702404977221789649731458241770690830680067801377815840764873662400590343236662968218256211697981048576328148435241545372543075051594952109757428031762469834781538302930957095080167901199455226976113347018972534334210416375400979738414416582588689496706548495076287263281908191770792203069614447622517839588243746755480572371988630084226963919158931419126724681617069720048557166545204944250492282054791996953359013543036918134163144772567093') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 326 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,6,'-818934540071845741.9530629278049288491055193606922237795920035094854496163164602796260436963420239973809758519485590636') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 327 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,6,'-818934540071845742.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 328 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,6,'-38438389630389612.0042045464692275627184627672063157323631169405883031379129843031477339360597564128205768842448328088') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 329 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,6,'-17447499423661151023.558342555162228919125358089491573318627107322332520978657843895009110781773496490472817700487707134216424855867015781267287628022535529641238372370292374146871103236048507252055787621394728096799222976387108688980537900309311204203302960751747509648304056939321473462375648710590981564101023812800603438271190184064874290215309040519813024962909469701968804925443161094255632624090623433640078421818321246597728308302979223833487133268472455479442002005374793705431817866798804822885690193667521606781156962792120052947767160957903073698536973292205899421787948529970837601521657406211962967291912148632072929662185840265855612193255596825032457033402506154930851214421895488796227471490998190312007513478459049382774782886773158311656817014322925167278223360446454868236479549745612973293185989975394307678926') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 330 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,7,'-1637869080143691484') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (7, 7, '-1637869080143691484')" +== 331 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,7,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (7, 7, '0')" +== 332 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,7,'670653780922685519356619170643530564') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (7, 7, '670653780922685519356619170643530564')" +== 333 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,7,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 334 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,8,'-818934531574859518.35936275646834493832011429282408849567717761204690035294074716714939441961175772404289860039233415598996234758590850206505669201200') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 335 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,8,'-818934548568831965.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 336 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,8,'-6958475505053954666339703437.48985528725312694198056665033448258303533387675711770743843194274181580881296671866212320171337132096489224277825857521033238709600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 337 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,8,'-96379412.478435590945480884955616049873645089637121682284625533034225619945532704111492738646389632607594293500930307222576571876059094206480673293295865214240456906965855425738072430281475736130342229749511650392658808510082775031098547507966544723255869156056349218776847523349173551313282283869146710349521487706884633419341568648959204688757523312579312713453540395840470692533267158388401676533369105590789036132185107859069994833345453200014884023709597817280132465224778002071890368479648934317322270613208789859930618055792958996389145963056607200020526949699302565905917600478429628844015684879886549766473809801710003649193772354147104446894109928903223843036925147624639466770660174828940577089095480826473544099693433597812637069287644606693066736302793687011165899362920686114156254982709172925265118077531') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 338 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (7,9,'-818934540016982261.65314972994491977243776717915257186979728396159058352649559139156429817562698954531329940720620096519975256547379603654362598494779213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 339 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (7,9,'-818934540126709222.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 340 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (7,9,'-44929599044588573810654775.83678007633232843418115790847152455559258007804727916986432256198687661496804050903769496933400455947645400628259699874770581538122521805603947464462448454681701547899144129061961394870320463199545502030106801911915987309444301341575451240764927967432593181449618816978119423290767783843864768557371257918447461479570164065303599994081990686') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 341 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (7,9,'-14926769772.797708334489652004325241753714626257641081061212878627972973992233480868793527325656854681817156284203427388055525855608883067129036717726368707982450450575794623567027457808927082390474261155500697096284790656757163047499531247323702909360444831707029353441147768321257650234732286165724178549576948957405037843360446785505536809409054071975214796532504678683693402401018726571884721963641317944453797513145055081061680091585467186975354801535734149952115333241283186621720677488342266420359417174224757781125498130120775969091933838082305123652811689513300403051544682523761263183781206840940347226802620226164265210810994106136738030959199259066517106713585343004140573604437146025585149934286364795122716971496775012412420105368351774715982565252533025207453326002101655121126631180162560463548157187175671') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 342 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,0,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 343 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,0,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 344 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (8, 0, '0')" +== 345 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (8, 0, 'NaN')" +== 346 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,1,'8497071467.03603749330791582407836434318377133169438097066269854720538319012928851657498035372443556191720308219530866834905045144302106406146277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 347 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,1,'8496900980.24523699375539429928140707116805167695126380524350074691312247557192264420150419818976723729812860582476663647913254442686555191453722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 348 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,1,'724311956372274.0135050255361637906710330203036651743488213007179039756514944640108625580172737414192938789413338554327986697518463087452612658955180411327002900979574347739956600177846996063741787205122007268468674386396156638261992679442768654367111433834151087792255469957061758837789341439211010331332174981459471333376067541234901538285101103690622656631026001337239036711179989456674399137008584021283568040818388709554256523118702728176420022080138548890713013682480239784198421500241995499841675772793497485550923152267616622892846304530712344886979674416990935007952941652591352603797627920865960622077762568060903908151958000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 349 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,1,'99679.115123747637190903598543851248555278745675862923884476564848911494649941770503156134872464666625927195645517181131678518619856156844072856993813601495176097972982587061507650426363887871820112714099226501603733968262566093655417466145183587899155614471697804006772915054739361437054029183182533671508695646413074668188590846200362324428338974890534273352188276373478524543505805545661569395314989170104140776362043880099775594658817242753124957385625811310332354760117110779649164022618274859298031549851269619167173746259018497289174255201452265070501056913033329291819570027877856677145579673495987354805150868813877928857472561883332547900866904764950837506993759536410161752469488392566682723027340638271076406246129989851281210810196699482980833204884400423019400653089825859983062096326294783573417554749') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 350 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,2,'-994877526002806872754333651763017.40289299098701084219066388457144979069028441485513418625082363021182982914675513019536443438529749838106171095037135009526312783302868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 351 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,2,'994877526002806872754350645735464.68416747805032096555043529892327279933592919076133348036932929591304098992323968210956723360062918640113701577855434596514974380902868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 352 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,2,'-8453460632655529853033389979024265783461224.3195241893307807116624750282852146303290708492834695194274289713076935297734670940696121761483641291930931061232942894577813178566088927221374036301485916497770984757492912292002695944367308880163698595015497307574177176409203214324418237020500352652934909632442547242092296504047310806151851207329042221920888326000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 353 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,2,'-.000000000000000000000008540735921314463871578184793632135730756619558669911183806487803411545406462244216408739432325839683804021466133071768612386706692296158696852363349481716813410857655324486448455846562309041306880675446880859847445987588059144788756984750993583865748280824370754934966494724951583311563735533173023858438364336214213295786266815116844775733072416507474834701984381586060478606371028156925222726225495235702395502085206072985373035972506738983640539009567237336002073370431753469632428303255926718930619221521257726366850472572830063284204851204189447233044832163423057501488364913539948261528280564870049935369825245920984413480757133585498984374354957754078525161296201228031555280486615145365039415418251448980923331334883673792135893857917681235883506783408111446970710546686739582471') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 354 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,3,'-60302029489319384367663884399588771256.5916339968771732477072012126949734214868901845505193155307646111690097978112797961939995859130827784737422228762767014427842766445950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 355 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,3,'60302029489319384367663884416582743703.8729084839404833710669726270467964301325349604567186096492702768702209585877643481082023851284144664938175277044596973126708926205950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 356 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,3,'-512385513828318260570283740065493064477880918352.732624553690077857674083796435724202494963885926573907185100543184828131859183999195040110586155435203949963570735841632689374488877298209082579317039061893012560130258753218955057387206477423088065663401594359617882154814262843273526859406265633827109554791772242178864873774889091687515990672487380368975556580539271333144212685871370972163560839446696514092637412587953506052848750866803569213269271165856310101244342151576488190595936869490659700946174362872797854591188391982770203203644172999264143929484089237665313698600170041324566984832357000400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 357 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,3,'-.000000000000000000000000000140907135225782279761112255989433531718277338909398600029580768021365259747075253760824424092983497958717844671162530550507041138147836569244869107757945370200122955794509365120853536859837243314494576053441804831018954867623755033888264275704547752628348151132333655667171970175829826792355986148522268067032057293494927558322394395160508723637192234110428953945018965078022622950949911124494740703606109543716688008516750321047603009424529696862953094999450658951089435460411028678817795100630449046993274191915359520936265372754315076684798942557329584282177053819106884196674660057281227248874819417305259132106690385871316407455034281900110779740008476645291647094776093567400422266906817555937149628005629880142615126571231411138926043531449659320501743591992888328328980526602') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 358 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,4,'5329378275943671819201468.88995490340795935797824952902333498786202536079000703830146057240651898748760197658486790165425772165585380839129948178510273188565692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 359 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,4,'-5329378275943654825229021.60868041634464923461847811467151197921638058488380774418295490670530782671111742467066510243892603363577850356311648591521611590965692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 360 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,4,'45283653791262997781451381354094822.762732909505051438036873220502792213670540454778361182993875916509061144859281577740137081988678361247725064336120451090222456518107029158304937620179032477664627949959143233370320432203497828243297406462513350790251761540074946469824444452248386782451723637769289822576372357189700319768797708375563651655860093365309717823602754924352327588945034832436331911584742966378275504545736896430718939807674966738116698454215555860047859161126694019895490767779791933882712567492115664113775047192011252893773389940988533801360010782816196288710063568554147458866942816721046004257953642508395867837127678980002737669139369781058046396738606563716339660654364541530532834806205571191828994250708412638796240377704994928921528330863683630622922959130920715261879547446054261914770022377059156125037157979236658010950') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 361 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,4,'.000000000000001594367257057971052149628499448029056279649281098852958322409409919964709324200796473211884339143791758566019217634542932882694487712398244322522748736692741288668885362384266615527166964187404128216235057387796054457728789109537338988453837993084016408244895452291151218602815057669592284587317035387004942691671916981967449109983992675125005085762403043329820872839739877674121174083273716295673230993049263574856197011389828478636779342320299895806297835595427859271617831720398457416685435560152182883615601663820189195644140652141180949257192740185075408019971747810015931542757445763460947106918998459997631117642552273815713467150465548031203738878873114842844016176922502916339025283749846225376341878386377192605865913018132981323065698049618379727531925408677611856682983907951667054819') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 362 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,5,'7844230593.20607652525116672615394735666141304947992676684520382624714879797087461877675155217754947572297228288498221620714146356962938009770486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 363 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,5,'9149741854.07519796181214339720582405769040995916571800906099546787135686773033654199973299973665332349235940513509308862104153230025723587829513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 364 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,5,'-5546455599206321494.0676583421119904300307105296377723816472192007866147764761501865875232824814135783697976183493106885436876081315217834621720906478074798596116645640251460842350553806256223963023430631066024389364515688765194373161385579258482225808660340732705687558150699172147896486727530192499184101617379930846663835628510376484675411350654979679181852179924386290069790336316958202582966248703889464308649631486542724072047294216362186036638115240070658004553260251510288423749333873893917690832829128021808383128393431810674177390352413548658782609064839524756041501835115152819802758773711821322162752064589750295542985780512921839490040396053737870038534216948323935020460307350020911362024271167085905714873548388570602799432705061561572854498075600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 365 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,5,'-13.017101389051085341042057308965769356145255575582875626848796382322826525772114256699384710400140437710569924703769685567402446691691210934185000959063158239023412379691360587119206695513775971704926722817528818197919265145207032750407924774510773427697188520818450702875142190949766251178733262143962213111236591970766836685919581025629742334704854852196126735685421250263035895756028805974153787560164935038227108975229771590754808331856162035119882347418116049174638416621093907738608991987582465865527947015457540650512339263071898410531735438556948115098562123055444965056347091625748703503220861221718449714020622377233272042277814766996198081939221253025243417993701684007826177845003391944496774674489538520354606358872276671998045196738090133576377830721671972381371985771591052597345572374064920279182') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 366 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,6,'8496986223.68757431572672621257436634648368772473081887846765003074279255322456188404621827857612554765910678041003765241409149793494330798800') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 367 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,6,'8496986223.59370017133658391078540506786813528391482589743854926337571311247664927673026627333807725155622490761003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 368 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,6,'398823655.819545574205652791249227663407026876411660299394659390409794761643751582473390322547798567169668246138880832642141417531427935520467563318363116897177899262525720710134129529640376020947774470933902793259531840625444267816319963200') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 369 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,6,'181029319177.110996740664566780784253502559986936959009611748146099327460471609593148344991059106574612143724330935988823134137686051475120980257829276671900076859337187540608483895641504622910361858962883971613675309676443079313179200981488761707281247447120551917205792352229666049191991270809865110506639390610910481490688182068719005593641339338678014189749279508731647492051879768743158839680867283217578754666643688259810863605002821607490100820241093473083445658378988069593782353275713240897038366242558466047071334385431080003439842348547427066389352198560236731403235927478177780757802759046212921140424771887928786549573201311120885052685761195784207710933764480136690216943336587118385525047554334029388869436622866247240903231799829259264158812528305210833683370536416861544931420820452512390255774498188962903') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 370 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,7,'-818934531574859518.35936275646834493832011429282408849567717761204690035294074716714939441961175772404289860039233415598996234758590850206505669201200') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 371 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,7,'818934548568831965.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 372 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,7,'-6958475505053954666339703437.48985528725312694198056665033448258303533387675711770743843194274181580881296671866212320171337132096489224277825857521033238709600') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 373 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,7,'-.000000010375659845651632013446652385870617923988120764298690164486716047614260682259722116360931978511176121353975789418625836899338225571166376573732227571704071000348895791547943896682585450808398324252224265156214259224488248639550967292466343168350213394398101712526534464002532408445204630441167137710565437434313424987517531891145368203998329086865151248833625645567863740298397742783405267970015165358620026813812552194344790169289440822038223606218360105618852154152168496637886434061050281055613760360200323363465925493033734895631921307644481639236601187225135325401868178006133838932915485272554505684060229409404902185944047523033315868230944723282246159741659387362889777495094736963530708159604929268812778894177095572578862150793098548829744006499229853198046828954650334595737117597239208825268') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 374 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,8,'16993972447.28127448706331012335977141435182300864564477590619929411850566570121116077648455191420279921533168802007530482818299586988661597600') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 375 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,8,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (8, 8, '0')" +== 376 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,8,'72198774884738777393.8687539247642452953425155400068591498151280875559609979248583367700231031634872342122563819478919600402159024059794279536786611373504966204744811722007869415559012475160471227957857756325962941799428857291371597146319816910515366298862558849452235442246081440000') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 377 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,8,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 378 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (8,9,'8551849703.98748751358673528924211852802333963452553842636251612056366144128630740476125273064380199240146487881028508694029546139131732304020786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 379 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (8,9,'8442122743.29378697347657483411765288632848337412010634954368317355484422441490375601523182127040080681386680920979021788788753447856929293579213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 380 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (8,9,'466174236688165594.9218054325256670866060556227711696100465581464881295978997280335378678072434776702952026828137140986670189756965420183565968027969700090735690246176791371115610886533930223141650377886909408268207750238603105232560663571044993507074695683027062426288270199495225881785499139012931143826099668999261931834700467395442768201666740663642498098541516326470052372008385656719236306238735524802875519713512894448940917708118676095378518264553310312628830009314653641136566040400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 381 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (8,9,'154.875085756903716715488911525453064308758123952566428258639786597308109810869086867746263482721081985848551254298524280231489145092826397833394044637104667137816928932471315095067524966582810436282901424423215992139000153713476369887383242289102867530775908269805285313842050961754114751975054515055089553180717444020378611767296609130477264722612784088270193199394531972594028420402254831778715196248487757266330454269044609134602570688339750190391651801546906342796660819535014295618246236706572780627362908121159003488810140236665846928586992082180006454824311789091323774002510945263351862712964422865623934112293184149374573706760114682326698881257123280119140924775171374360283137569618025005229268057970275164869735173660958715166148344076027212231446680947914004346760896298312286730627916684448923824769') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 382 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,0,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 383 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,0,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 384 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,0,'0') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (9, 0, '0')" +== 385 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,0,'NaN') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (9, 0, 'NaN')" +== 386 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,1,'54948723.74225051983134098996071145685528795757427462111901537365053896571438476055974853245403475510333627298551845046116291696445177112567064282766115207407461565363967417615506303416694032848457927390574251904212425813072768882213388082765916956736282110801611726537663292922699021333445658549608928179155685881583228490235606377831724593358583903616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 387 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,1,'54778236.95145002027881946516375418483956830283115745569981757335827825115701888818627237691936643048426179661497641859124500994829625897874508497095086558766563666622720535497438693688376602804651302002795213923698663694204683995198328880575615535181012624198813873609885725228117274934655048553507421448724831939026752650108735245933317237310133362383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 388 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,1,'4676749348240.390309875431213992853550297086049749814750492488995108783145961719774217441193547534210468967573344456866203963659951312519988497979489304488948342258375915152429008993288817366720647491166024151209542534474867042837694499222928509320280684557676243780452100132238968233413333851595648146954975713386711764268506890884764704949969602122157394714663532141060559896359465918874990769222345665160127552795532197771168442486088776803398878354288847069602460071745966589164282641033852314335279121191855487126430176047553895892632834940595958394834437871886013513058514896870683979585091413977173250824451205330441299000850618134248917380244749589254309567551846327349592529960432446947239714236828401206843011440433362544797025114476612133622499094287321570559088587999417440664282418005102546343020409520421747216') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 389 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,1,'643.609749344751131516972294140174556703217311736700045690413622699888869645595256683013323517984528456698303984909359393772036036540901870537096836621035845014213031549051156299974682317824766457362427063305495772666640279328909129870227828460705733995380145417663304348663705694070309475835826101153850359826502235923289787750107778906593010060115662191620280031872002110849782776325630424918493602259707267214006217268630948545349980430128422952869610116216278256812581821942763705098526140427280008360043829906543029486315209818099697988089748683904695870401517598840185535891464842870210715421728852789815860153472208176465166954851895457846723102438114697692610933532992841803219018495137378534010155991355251803548866919409031477821173935696065078362044927492034445482457329200246282082707380974745411383781') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 390 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,2,'-994877526002806872754342093885760.69667996446358567630831677089993316481039076439881735980566785462673358516198695146576524119916430759085192883825888457383242076882081857926408611052522393579396644731758241837010163568445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 391 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,2,'994877526002806872754342203612721.39038050457374613143278241259478942521582284121765030681448507149813723390800786083916642678676237719134679789066681148658045087323654637787610377226547625566084597844703238942080799221554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 392 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,2,'-54582443595378013373024060492546032003692.4875677735896411267274323339692558458420972958075073392126734000341372096298914875892612108329218081214550050039133117695428196702128258481789017059073444323729583900855712795086447886053552786449313809589992185978097430132940882612817775035217244553616977182049775786664446683332098226841743818600819221587510039430478859412452506872131851471967577741190323481953867845129745440745526578327709351120432530702446916035797432129052518980799424635406993848916727957825620638983706180841278402925286540375225365057191075559133035') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 393 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,2,'-.000000000000000000000000055145964114074763360265614481666934002579974728749248345352023099030383962250681574081874554842623852433135871821620640200582985140388676650602814646133317791813938390695683843848260103199745295436998313216878337673674660966362155480524935736646623766057029148471463569162153009963312016563281545776175277904913263614668092319707343286073000287493274965714031678784835459999763925833141049057636632430975424499618419962303087175237320046300285962065818926167792812657620724550768858763098967149546312995222223400007044549870620849992226072041407997925405957501929449911416474388622107825120486594723448780503829317691081601820425151593487431389373265285594626753418140874747955925763163132984655078996173911578832035721963554569605730262976354029623260224710106409129114204296314733036') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 394 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,3,'-60302029489319384367663884408030893999.8854209703537480818248540990234567956069965340942024890856088355839135538265116174644003927269495876835324407641642359213535695803871472434650475144516723617632059130297610134243891145006222068960999879308472500422640481972089756410157246974765071949782242392661524488959954348903412713930092273629207697480131360047867213863018127928853922173643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 395 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,3,'60302029489319384367663884408140620960.5791215104639085369493197407183130560124286109130354360944260524553172025725325268378015783145476572840273098165721628341015996848028750420770651761919246816300854441592109844750954710317145008297946462099581451150385769713261452744310496166494545449824802407416426304041583975713483424241727236417259479541129474082301376239522310995725648773643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 396 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,3,'-3308379209762459471107480259839508279070920437.883503980178028214343751083865562028455061662673132221930429904398963590401793045470444301883103141901787466923883803951815572606105617157736442670792467625964359169270739534412932791178258858918086886061702512427989129732248215348301444245772127142869263635282888226326427510486246184233225114523636171202034558843515894542952126988613018789833835507734620046994907453602573865012044120483116345444810078666601100257620969379968264504287700045822481492526688635364586344704730579892342786173395802035361824932075736340405960099542224953439044947229246847140957298841482874444906129049023002897135347878048572628834749795298712449864571996898774444932083319581439741625832405434317985988163261591679157437224404970927012111196724239860528859217322132733404472897289') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 397 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,3,'-.000000000000000000000000000000909811507365065002714756487495210579371808512079908127938523896001746219475805196061435010714649189975968123072269549018826343830061696154665503565341929634172463095299662727352635590451263034658630449260378893723785917860125051787451512267088404686342938118993621396641623525252649748977992770709930435013456855344203854749977414354164157192885125263071636468941596567220391082793700307461350484216679632552883058303710297475827456761138832914743429330069022439380297715971317819244718196187172770061156794130040674050533617155253444764036426045091327368023602807193742585178432544430741520636125146531502042579276206322507516332917325631822606079220413965396706334639331097621824106950192993127113903265025719013680733760540930122186345919977470628988674677630636632053583144327') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 398 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,4,'5329378275943663377078725.59616792993138452386059664269485161374191901124632386474661634799161523147237015531446709484039091244606359050341194730653343894986479159670583937529516163204904273806158788218327396375034882788180783796976731912141525319602448709213495905899041406302673881364465504945113279286939663215197485367850132991968081639290297033476859158044889351836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 399 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,4,'-5329378275943663267351764.90246738982122406873613100099999535333648693442749091773779913112021158272634924594106590925279284284556872145100402039378540884544906379809382171355490931218216320693213791113256760721925653394811317969065642404864072442190731745871963413981746671302248281216916486794296983018838956112081135739969615171358100498945955409711817327376172085836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 400 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,4,'292388240303165948041827159734686.255558469787242316676287235194652580157149226950109397295920730296960145548003120827363226435916209781396711693581454960342091452830648929118261388933297036933167543189308061917640517578583521401267417187854611829815212778183983326568586118831109538377828156118900313778053576483381085207892754728937946691892849474364477434665960112125254104966566712906532318984871145605839506991591027939136026602051635433295687547552796828217859648186757719639965988287173297286034098497871707197092627676226053609131138590878743560287292934815277894463305001278326023708395571840850120055316276256138004565442099731931051413153564744766098053176049414330146267604802971221161572130161432525297614616942172815141372973870720928125699420370428856022295499447755488148545048400795053604349570217878099721865670458104653570360') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 401 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,4,'.000000000000000010294536718194523982241053267404812827031741197656209184880073175960433631103885281961037127283726462743623757855378209281373475473018922090781553213750339001555832360656399849031527008437303091226051008068950896796359518673740801770866360774945096397034708173365378527676779736929035450380795854046109380272505550244458858231227568118355064007614608452292270378691774826689216790090661497154742954386244856792006376222923780801296832612827123778915598893970651480451509706836620045721191411824060983487064555397842027454385628620582036592315345973096405447742002746762099231557054678593446667904250189208490698468539396733604833688133512716508825505666644390119877423938820483653319376926639295680552194966870285838815705038244628263602997511842285889300557188773128635554621378148419364876651') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 402 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,5,'-597892150.08771044822540810796370552966707032464017958269847934730769542644402913723848026909285133109089452632480800168074607090893991283808726990171062867538012237270000932798704781608969096508450960185964292594677356241956277714380500188870696516251767979457838109804726539408115452577436052503866633026489282425086547752714324273565900641436632912781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 403 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,5,'707619110.78141098833556856308817117136192658504561165951731229431651264331543278598450117846625251667849259592530287073315399782168794294250299770032264633712037469256688885911649778714039732161560189579333758422588445749233730591792217152212229008169062714458263709952275557558931748845536759606982982654369800245696528893058665897330942472105350178781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 404 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,5,'-35812445701642379.972368737320206275515144213236752803936806738624588812089615098329765811617509505790110909629109400553415312470540217508070421816878544125783329593128638405659896184248784794258084116406472768709113030915308410565617764394827427154923321461158387012978726512246146545834669665093228316853342805604075936530371665576147966721599968786161939347726656168798065647411457701453987215491345496003650288850096338695703984042549594979897253521041581573388369367579323607093487743440894765114619634001789457486407909224339065748496715380572175183589195611952939575073075140094901024063428239223964510824958346570603142906309198033196987949067156046076497974760641964978711558209708743776024313916111738542765749928287600981397080809041007714387564206594515733287925008053261840295560398311905155157989225181164097547541') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 405 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,5,'-.084049034261605466896663277055600903951276881294745183935726262038673990196778002490449355450474227878560465916800470848046625257516764244432096856845087412397406701521972651300484716852035267197801389708234913163750232707469240634303111868882057393120649919262424619226282082184091177505826009374043368623853156698509808569378758387708910629731005691079770517679511879694426434724918004419953301426679939010592502325130576915399009756468717124460489039474155719834555522581553817856854607844133431854471292027873672356863673617090151801474016666978499651970627896504709551656249007718965259502928591648533670568214972768900993459927860068104745163979267716597907297073374689384723943955361288974065531322408839914599555769945298758102515352082822617428033648130099822033393662643586331479103933840387663729387') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 406 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,6,'54863480.39378734225015137845671346015520435061071252892396685718794832880965812803098645730572474084523997120024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 407 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,6,'54863480.29991319786000907666775218153965190979471954789486608982086888806174552071503445206767644474235809840024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 408 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,6,'2575131.137912978352131546639620215541477987701194164886305951830806120142596646541302305984776928560906754259789485960991272272782091464270104432109904222200473616116525297615725803495463468272171161659654385929185160689572943852767523792651123455283534072794326647404332228203001469884016996499768656263775233430922446983838511590562929268821678518640501686017030536100955531423152839988008496919169395159653034847677470665418765966542111749439412') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 409 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,6,'1168873084.346566233232746391559830634361431940000227460271861554316197556566224118756340501278103405856646766537018954185964066240457859194626558143313125824412559635129130086906976028635444060218797992547370132082916380788496584864016645155338102476357490305222392452114945853620686975383081427840791892729407194179236897452655907829255937027286698570784397487382242990326347080472574546312522326038419753951437799831430690304084087684303035538181812523230890783372773953961677974396907303758903934808035747944477277528267001070234880092255363221274303820343225415479126819937070570562654065195009839593938440374000473302075568746771126391307584779249330981594640387657042725725493800876630516005713789705652827210295338592985225924959199657729900181287069808881130884115897407246324220524401243575641227725030779990490') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 410 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,7,'-818934540016982261.65314972994491977243776717915257186979728396159058352649559139156429817562698954531329940720620096519975256547379603654362598494779213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 411 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,7,'818934540126709222.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 412 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,7,'-44929599044588573810654775.83678007633232843418115790847152455559258007804727916986432256198687661496804050903769496933400455947645400628259699874770581538122521805603947464462448454681701547899144129061961394870320463199545502030106801911915987309444301341575451240764927967432593181449618816978119423290767783843864768557371257918447461479570164065303599994081990686') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 413 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,7,'-.000000000066993731076524206362744068866774567920404984046399050881532938231826344009126898802592302273719505485084766150904380671495128604515800845609713368334606489445184535043833069145643553083555507533900955661105251251918425885537513359541698046533092111969478225528665278023069818968531644884466229545497943710817187632203193468836772459599856856811131193744272314519908999458320275710240994009061040198159739169960258978462113813370513611735006229733329565083659159456172425715216475781507996483885669437855000029758892126410922067202159414570164537031153818197618428471046051340835826664787585016361564969663413176434498159140395476980277574789931364078570781760777773379636490084338326576889857824344578398580499610233575273027387501809967324874264742269453420400624883982643066864175851881870402856698') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 414 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,8,'8551849703.98748751358673528924211852802333963452553842636251612056366144128630740476125273064380199240146487881028508694029546139131732304020786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 415 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,8,'-8442122743.29378697347657483411765288632848337412010634954368317355484422441490375601523182127040080681386680920979021788788753447856929293579213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (...)" +== 416 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,8,'466174236688165594.9218054325256670866060556227711696100465581464881295978997280335378678072434776702952026828137140986670189756965420183565968027969700090735690246176791371115610886533930223141650377886909408268207750238603105232560663571044993507074695683027062426288270199495225881785499139012931143826099668999261931834700467395442768201666740663642498098541516326470052372008385656719236306238735524802875519713512894448940917708118676095378518264553310312628830009314653641136566040400') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 417 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,8,'.006456816440893715330247418029019114736889626790871612141686117271826070935285769018710680035004320626745647926106882508048159628931624522666638442625219959259156539178378186912871506893482633695438850964052285542425753626455183282159259999492971992739484319464700978750304962671213318202670228197968646486740006148091321740497272644910882302412140576608739962605210964504469426861972705740810533465451230811358870068391007718532021526225893542801514255726272411690175555142385382688220121052891017808391607717500701760375927811435030512071347521837090721052128992926357375527600337655573639413811262412492632491693179011503973930804928749370652038245414768103001067902012962988384812280453070895781287237746786414435546976395632454474312533482077585837153357017362048554313154580576238549196250793055676215164') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 418 +-- truncate_limit: 100 +INSERT INTO num_exp_add VALUES (9,9,'109726960.69370054011016045512446564169485626040543207681883294700881721687140364874602090937340118558759806960049486905240792691274803010441572779861201766174025231986687953112944997105070635653109229393369465827911089507277452877411716963341532491917294735000425600147549018150816296268100707103116349627880517820609981140344341623765041830668717266') +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_add VALUES (...)" +== 419 +-- truncate_limit: 100 +INSERT INTO num_exp_sub VALUES (9,9,'0') +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sub VALUES (9, 9, '0')" +== 420 +-- truncate_limit: 100 +INSERT INTO num_exp_mul VALUES (9,9,'3010001475769225.8286280957637941018500905354415197182850820227163907782811814730309044010416886791014702373809932926301368137684091094408663914110947072451332976891128659038142954192986392936981664792370678656287232795203974766040821110221158579481177539669363513848425151485663431478439528936592701070340012569297177488556353760756495238304538439278682066056721729656193616571456456325016960870401748115848423105783116854283646624807603476682295234280408938557209608025246638166902335016025467565869375885610813662767004038102486303756741615124814580306266901273803721191779461890468156043551004644728343579032524687612403663816107770451694666844862368101122025340182510019516924578414085461628689') +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_mul VALUES (...)" +== 421 +-- truncate_limit: 100 +INSERT INTO num_exp_div VALUES (9,9,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_div VALUES (...)" +== 422 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 423 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 424 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (0,'0') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (0, '0')" +== 425 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (1,'291.964716019333021494947753821238960905461614737525349376826064492714634914263808902604580614735501799528494357560837535773816469841426747889103714048646989532842972129124080559131220979335403729022278994440514872845756198274805589586120535745968205107562348427941379641465378272611453955517402598409789621997041856848783989993820946766177453801729783316269310186191833995557234577548740940419224137195404391193633808203715191863638616433190672511651125299379882126530500870287424768024674231651229908224729856278167033444719242144302972892419034855417126978468296581589282861879645409909873113678361180607775255758820910366926076380306290306477790931129670172989289536405788838857428768869345763784112862591549008321546447442552533919976570125718481191724503352619626562352280522949665158335559389298720990302071') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 426 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (2,'31541679188064906.712574384704440356216787857626740375004266523720148374188511622980520374202725176835435173058936870163875556102907654264048353814040480579464700545975346621546520503928314632418705230212623378642743044255181848913683862360044189531298446109955034944189751302497670367665492719604026161836224535961347218522748523360100432275693829501972749859329753224444694962089604095212784768854310289429208671271394086829270986183171968944659703708706544668326267327938226750760690620258967209626420981505237183055363540806281098871221581265173394406715458619627534396065960117454160969749739483126059760636526242783235685190739315590041294766649891987044641492234243404608847939002062827210734973778130441825067858641461599799772535304379732674727995848518807202053316225824685704785148921785964036119338754973714515974054') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 427 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (3,'7765438138915239878.949520541017683429203286303188179443533225547096446554008374834292278237558244698868300666061834105683999048386497322007336816482648302911579331582895326423063492240235074387242190187374869842856897538718280497895072291181675294000739548676781615025944675912072664211455701112700937190832332966000160156597821149428032612782336278939437593991008833233156511435294360065004167893309428565243314846456225604669764879344135321428948841659419438769652686215993544390780212859309497190065178705035652106614050448518931820975038314187040226298661787490226917902356569717171481159691409131778764973037046501816919243659681416263730519167614043077472097520207347950292377914586524327206547377189493301153212000966249655331053184913579513686655963686155890934436604123384536027235444923674128269748280097789270784333442') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 428 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (4,'2308544622905.016172868282330339228589083058636874526727829838244942341440716909466939214393597311710652963849541394758298277969240038668406494621950956862959196896847352631445328917063551082418729435554972200530109505384839391233286173517804321019323644218483570886304028175359854335870835404627608254205407525763332087823548640923282031978903399118139052814618531713327991857575390136755426466065839913887477577516426991104516201265995293600539957187007068885368699949673989051443005684755994465547159213587471972139403333249259808344536605314911144950465968669770276463111776581675944967401948957460097365849699783091843609965345747287667911324039374314413430490112443463386381631812537639503425989372084906324702158112088898424705684574998783112519152403201231176840068666882123684602080460378627639651465436618032671756') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 429 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (5,'25549.082770905117529972076915050747181125832857399138345044265535151111965091602789684342996759657333588444489085160336703294705499665424408218434077722506748278242942379566431768762487954917389137120540138359870652558814224523699917122023018717544160579704907452934297025088008618627873220397030397424422097405152321366495319708580932627092620533785271831833326130796638935296720064431288560292191928489034307645738331451165431755179025359993690642194334018457793169983249853388987495489562746304107188105521296156525984787815685365255240654972150342496329030279439124533240114879332406941960563154881888172285475336782757262639979527682925214971861707635327995621436598536743180180978457735632181738067997521785965451385630326464388080990200265186437768409003553910194212076755448477164192901658547251079126833187') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 430 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (6,'.216649653115510782473161631235601739254284877523828136703593069337209747459679979369185882839688430004369697316986054374456779366220242645866798278985273820408495361607183119980716020227424205519727777568954933592987351750339481522149106749713967143685591960510946511796062486795368200503801097611436787402191532618456991115230272084771674098613479989808680789347124789253499967359190605681912854639520917409710307182238065185749856554472717209097115325999946728168357936779767099041518574001682560265549916593333117469681763348860131760281253987626822958726920016922608371657319505153308390495179319529587670415367205193280809809356733443291197315823747505896510820272670040485083775482983378341120809542502350385555577946098824446199419354197416933858522419312733314383889554606932774046771497129486979593226') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 431 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (7,'904950020.759072496304165474991957396337281699986101765045213964054286624338102141970514306010139529492299343393832200631760194440206005974547202512275476562767685193838576516154915404389465528270010938533075930081897392863141132529694804621418663424569202655893682412466871297412964570322984865326770090075582481194532433411398133265643849129084449161396724635797324126396071308557057830046688990212282866035593809633839882468628249964862932050189148498591642162462777480125024786829078066012617362076651920045684345679767223337287825546294839320770903419463644110383560050404456170063805115223954191445548226706113970164823214416171441655706141596091717118495955441099867737827763335880891937222647408575142200256804313345924443344596462585960919126827045197885802122062165934504665811115031150357820196176799560314653') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 432 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (8,'92179.098626752893864900181023972781406074846653380680747862421481598042923358730531575438403865501429843141967819802251116774924400485954931201776260931315313253827346015775662310076094882239170765060649024538403329505426563390044695320714825481746233901773893996663258170360232639353378395244461670781152793416950717050461856097473105730100523010642696332151571372764781034028324977128554099993021459338419164426784774496292405945103200724413639660488309795423335142455569853549710795692020963174011003447023610692365550245567840477105794884132665155376243735213346877116105595296043532605899184658904822980397411096930267453332143879534914237169761039374689145860503772331147367757318826885494994339695470190886515765452545019167989882527248872835783707554463866334705735781549392895480816605355996057201589681125') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 433 +-- truncate_limit: 100 +INSERT INTO num_exp_sqrt VALUES (9,'7406.988615277484686670011157489572203134420118818648711986549881046321377798441006745317356200279801348355202517703531020643333388857073977704009782384103170022716610432579974132111487533733493986910583223121269323909760573942980360508642443245341392335557152177332615977623338526935953706604224108508582338123915133189529507760875123300397933931420500010248194253078118618381590347297853307090813639981736227771834732256867579490224181748450683295253634852775448770576585177080941820456051588076218688792321741398867304684922665590162004919486643750098085197190000638539994723704724550600891137853975703823903659121582583388450687255538838161486019214242094423895463814933532217776443473765708693285683261505695170847285063013324823850724236845500162436661946026097459146424122412596018946436589967013641971183281') +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_sqrt VALUES (...)" +== 434 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 435 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 436 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (0, 'NaN')" +== 437 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (1,'11.353265918833698201334218522735144514838241118349715803442713722607336732214173255618762341321138898556011520430414052782971985419141860417968593746833898952016980791997105866598425597066404919489902082738711038276194174786383758877067916049129476352925010880025206629976454341252818402788928939407784629386362069592202090897264194883276572978998896242281239126931595483958092059051047739223830394259082355969005503976135238921488192773135287876801394308064862257453262299764712613486466254696464150007113953810688169396432889052881763511661127351872408811370081346456019961324265446884877073712053408327408917588393884214304220369626106333713688792094943405258431214313197283237071070354654837081449831786573831004911008790533179001070424813584405346221388686999574752038655226138085374176702005198770598232862') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 438 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (2,'75.980172429959420723484178622920965327708652620924912610122049843800380131746381968266727388919414524075492921510147435877107720844487333947572033626887969846858337336557672107987074468763307953130616555202495401302128216460637786993535376622372745654109623249396257174895352222213037880060756992073605135503615371392439827458529942230210514752764526895030759481226199720092008002458654297737883219558685499445394647863430593136350562417924068100891680398878483362058595716232013516337079804607378041880078724811071904523716775991447489914128580100888252698281559809224785596795038122963619830942475652745611551345360922016753939774272970008770647516790944335173711498988149783075646985898883858697162003144539047532603946093022417842140993960433780913606807466518632121884254341907122163281927271483110212890483') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 439 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (3,'86.992429107491709045555322727377654177072455841678650084144967727028762699430180506209786297136121512625728883607972513154010138109866327600596617277403558404624813332464431424791338402731178416819791932126837396086742033973404980654712734845137075562739300866280737071167943367603243180515859476717635339619107593771719314284984269343476343816253634799874584843436046260962736006310389088154751401911743739429257286834178656182340416539923956100441369280015412718483971113838923221170027312390404790743389872757674342133486652087007983701950040432125562287337697971646750563062524010514537132255605131615248097901911480464339325353279118429890601202554448469387179349495284716473293965884844451619766312048304583068386805927433174443889441171878078987788018564357316138422561213329104267180509029624308926098065') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 440 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (4,'56.935276817066740776567329017240462885579486075188456418197311631774373422196025180114152248099799048545382060930401786002025479108787121595516444894009593031141335985913019897883627990503003577804436730367402618412514152465206336556967419434371593632864308139215157721913158949066717186782560422199668568894551013785702491365073449320535603830475158258853167712460432995074161536886421366716995573365924430692151761737886552457036412140640821310927642146210426044265504978418405684030862182425702683702307323138985481047994648222224089112998195621687911787785594701557252468626097576375468916953563766801336922479861708649876362257086586679701715813254414915314296890025577780265459584203893089574567331742100451277992780400302806430264717887468808962517029442262560742822875484362427192693300423729233467613910') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 441 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (5,'20.296713391219923821414834924710998522858242536565236229645868008008504475111229451635162536658197320282791428572861452713483981402773630985812066048575864982038046409484905688236579134672910905547858248343712686247795669280482288748331949478864729205285910525962001251260319741279139167559906461672936902355959755164523720443059989357054368460911050707727029320725144824995614445423492687177126412520389766864793826362309254124276325522276592246655562770110024099522184080118637524912964002223613671995639705240767929562023556724031894855094820328152633412077228479168557819219970917880393852962560319397442566813746504969336443969816954424715197797253670026862362130664772772977978222813915593329422557592316429203293264572088112274848838446633519530653849595288125585730314673691986554304725866754516304420665') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 442 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (6,'-3.058947463851998053084898503420969773173569760507671013593014983772013099601022840164736581595033399273677583253456908293015637115395777673836877852797643436458673662566205707359569792482081945396989472318998080581824382006377064185813936544714612287417301161454496258176319380348780934551188852900784476213986897306897793456700682073399936398243222895442594762628402487110466705108765286617060826203345783502301472192906817785365563881556293576463515218574477264521950513789471494214626744754200844840310516235570475410854073969787604451971790833680742315518808178608136598148628107328076871698598743664423452623124027059698038466681488746505289551548778131621576387262707147068500249466398507704796800459013580425992071957391417767257856002976954566094297724379688683375704613872658653366052459242767328235849') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 443 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (7,'41.246780548917246608934265057073076900048579756649769602488660179351587788197892095257027979113051775079905924990472069951828742350559917110289416201523653941731339141666097617614477426376799479821365070373247490598890520285155435501242427296281987676879064510605563522117334502131946383957407685328562874307957108543536378261847119286989184256009392692140821396916222386573424618796707564187152459973446833193743614720624765332006827171872712331032607870580880807058576154429597725560836582655488602546786785520452359711161305828045237044625934404295366273012300148250900116489718279757540843657039519736455668388572899273464839528462223812926410544976290646668870192676914370659142463304861500879195867873346447316374869974900582948166687948531910220128160490935170837209017355954301127162240133341813847180541') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 444 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (8,'22.862977375646110045361670561177818139082238721442691850491173190000619222046296383571431877856442345505931635735363450488731186880557789439424987680284612480261693386095598289519783790826332183796775862215503493910816035128476952347072320869461206895223935484838130924268616681347949695029657753251443811448783435000569829291535036468240771401957519222523032235686030017496209956550934543164421459898155836108824017735809352580723262896259290484291175350770265895317482371895188221452083719817251845416195168686335127805092334984596224320638378502008767433534450949989322562311171685891891122105437154553106840103473941148230953978989145470651955269817951560544095229079088083494695756914405635176899994279484466773598435268700064279990885608144109747858515514066444373797446449729058958270758597627587968112958') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 445 +-- truncate_limit: 100 +INSERT INTO num_exp_ln VALUES (9,'17.820358481980064387183481028572263407130633079314879566896470101569251997264841660326428805413719418277889123643557369421967068805165885825106611310020187894256310674762734896979157570968168599492401269694048046876387337971177513661006711375440365724346137980004810780215236524986274043416621637509807126148966029923572853117418545426960105154053049098579812135003711132897895016476695223444397389521434633067499404903493027304737402519428197015899833229473322655155458942323004249812974150129789653469524573801259946118454333405580647485894435301530550214095993989552176497867244278699359917247910082169086524111229983698975613609318418313798992088206507831757327320958918656453341769110558376097374227592021075267882222057385413453949580066342977546145482215220982989992069525148522710254796105001938615214263') +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_ln VALUES (...)" +== 446 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 447 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 448 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (0,'NaN') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (0, 'NaN')" +== 449 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (1,'4.930660740129727276654889314296515979425461685461970306647398411855044094312185293195497201658739777714943974003690119189101973212927970410047992001003936259467465542044528955416040460487922970233600641954269411521809500203864460110903973264337093883907933081597350982496469748131390809569321256206859934619579029279954574676601709408712255490686948453752571699579252140062805776361984468580258289509013081691778727372026090522694670379557247829136504595898935235926069699309392675806881162434168418505908116911054206058735257796918687777716036307205415038158583184624809880157060625643069601549803887864772092583549388533013233603450097615537162442973385137488450178790573546382354482351187412256794374383453695483855501587939419102008302408157959291557415763034668013452188944554607063362933134950906875499201') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 450 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (2,'32.997769620388965086774969704518222090258389987679691893351902336370051104718852164011301929506188893338106627980171059175447833290713847317665944354651476245003161501753612545484635275306181777040447675475670149066399611203341262105766118892586541910243351018829302798733989560900125591073082441126709911019648451232244139674063434385451279378543163944005973452562993913383659295688375546058256196254319767218634546732685705517341998116744642480938405113447415486950667007645850519659606476727681944251201236366198374488204017630268083077471516734133869728427050843306716313813724061560369884508660845630727190444623729815564381063131729592825825486515070406390371638817503915214206586939112681762984038333298146999891250107667687034785493312416966635780188163871680959873288697497561452228182734430749066579749') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 451 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (3,'37.780331928743475574895606142114739140772838801045013007323050327909196792739138159615327729728110344767302636436234256468332011934881494997184865617793179255006442447189720642997935223133982347184994174261506212652322213673745795726283311685835974151422721233207287206894148660531800622455957268888702309499182978182878524951883775154983702898237404558813230370364953160102391101897560104513279410610948028599674950811462114131673380477843456965645417025376374320207504913806546872166094337441573669261285052323206348035827948287081776955945081345131570610652073053464020209215624179904586956137079321655773178387441622685682721151900601340680061607114354850640946256225260430676099781727317540719923791064452012925902993317349390523278687089530234444415688602090547516647302454865526291471706301790881694022223') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 452 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (4,'24.726676547286224970759328746582840552419566534667446425423046931401641497155587075591229106937829957279943690528061985864558314570189069764367933957499905044566413640017549478921384160584906257607957223101377816440084188042395098536074479064548620374152344954289432050971466476174493306432228880930006524504974367146536665170956555486181410864034862861231267121149652317599303804477688621597163730470970207231328339082779056152481480926452142005969020950341307977091850953883445808399574256295803245530993204179747743812544604144379381347499056545148243304041538981954204310612049423688645476667184129189153715486929216331980316967699254518020077226689317148303152585009031597809279387172427408557115400021035692880631275593381822805377317270568779655383061987766693697518921188619814204902583361096973421134004') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 453 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (5,'8.814750626578650238811431417807018895270298639823442501111235973209197727215795256506525221092818797578008152140054383421240180435087611869193019443372556081555311825248667278358330916098378127100899126895012782320751838528480712942601038190627182482614147263228588284866661508052724762701223357327343090598060805245853527435948381893458352744679795853650453594546267600486696643924152372736774331080527157374379043696696647158270918245668579680394279565181670004245143555617589138267976417280970718829942998800499312890580011246294669585429723974582350357991472101919333996770115834067969654217063942059882195268353998096891812525364797586486311202350700339609637274043915687880562465121559531284337603363356183320193656553931871200575467929714875483123706358278876389849119105053294688326141759401230994901405') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 454 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (6,'-1.328484003982869642690619298690906747763234110040562640557173509402512757735587333095924652711056556491908059708986413635120656426593745303715671199761364516107844087845783714418487426723538440387069985879601248897538855843115404484229652166941838283489828419407478748732927617251897244190697443966424660881366993754577233476597163021768156814527570512834684713730559883782625870597080940193303268818336816535968869931456641949301731046034660616615392129109391145214470757259042172416816936479713743188047425796931722546185493217275537303458837771965375448968719169174136287532752370175863826715450565025635651343928205805494319778539652563499901671319955144823432132740582617949774638538594081514904904341299199113721131520557004571803778698005652464301037962272085633628653321081368256925971558076970172779715') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 455 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (7,'17.913249188669140643510654105014358282516966474257460687880559542190804665566625978925406311113121982595279826214959603627387555578965653325278444455875162277940655989601428868642914577248262147833499137348602966573601719040813549936948178463592211685237720748377879836890106515699728652218324794927458352954247096536337594789471529493944292143186953509162522579060020018226817623648563806559917579317916242706559131476179714031602207057714677845347616752450567251644277767418397621490301286115159509360375419599968738067461569666699939732107480135216621373057421990702923042287910730395998082514702629760389192370666675364405730936537832803383367187639209534697198515928978064543150195911463663617683085348965065679311986715357338675515370634753254774665197233934933271954463040729779956682570415317734489164385') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 456 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (8,'9.929264914121995501917993119394933531225401243275938207624866270551448544301376913376130982251708700134720886862945040266148728213253651323129942781577143957084726727561987639140151337848818195806259935747329665025823709044567138449084349729747202164413995795609659711723455165142329822773177102845804114214340046404641970845707372809306219463962664551623665322610139794354769767829380018857313559373283673392337954610346290037758389035140213224696023751541663171574697035012610534455189013755134090933979479069288110010954211669067225249755249337768792642303351914884187159646984708862430789018895140670365476746734456807215043628059581947593694929159076346249490593187993386780521089745819640214783614157516171005086731241769146397577246387886107367648843380733370112546792442909347322732196805316614555689762') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 457 +-- truncate_limit: 100 +INSERT INTO num_exp_log10 VALUES (9,'7.739283354261751283625223433456284905560931805428759681411970457812279544250432389511382263439324085689734710188041049046660480575958686859942980599595036769090747781359217248301544587434077376812293034848418204834388504169166350770257248896025815531248627658465029806509131631454856186387892627989218208026727504548130018922325585619738185507999433763118148418722504204066578294826264005398891049629199412773138457218976050467479292777172717500219850781664314597312411301296201533610562886229900497272268364496763758868455934979903774531992886483396489868888731578355541611359130188566524240259770918423445785338175040098706500034487703124623745259139247432324145633151895802637182446905097253961951018926565652497920605819785424451050191604602898777804133717341512568151920576684198443843944721398831404081859') +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_log10 VALUES (...)" +== 458 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 459 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 460 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (0,'NaN') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (0, 'NaN')" +== 461 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (1,'225561990715.277245515991117670624124484084762557459065170589803293759247930753528436379932442146759103295277479258327642314622036941865221478746258727236601688778946696303277607709407496616423493315166963938393760548678730128692212077086588682984700837334554241405763691119669847463520746595280034536307041368063462023793177898200220207765205127584303464304601759554817607633012272490650155253979182893585119965271975927569080191838676053084168631217591768468344106219831174026139608715965691941366334940196517120885214887008671956523579678156919416435031020452971977153991139145404842034138317592877675821045409772456977018293365238179815614004574330200783530118851005077771478448804470170641452481992602803877112958872108069738434946694089025321283178188028224338756015337492913115267362635647236447601252924834642796058') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 462 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (2,'9553718264533556311125292459627965006385666643531070061102266984368939757379.536714147420215784125170401370065894858487440153494392538261078415409784085960333028254155527328359894197540839556987826344995348426293585457768226283066583722499658006242709930685932246087653832230889613022921575445199055131152661556678809191264086381976922223866204038615136758192929883317207903579770917317641181652055458721731297347443662717939116561947785705140374908203404860090658919334137955075887697259604047657534191202566335372150375993361370075961180728155127447781364264047857624746079509591666068708743260905728661917791822925979235918475633100283148558978385583805341715868143937062092264994833222352433299015979561976964779350640064096690062929265992966564232453102431600199173711947391200249130712039686700111791790265309426741120465259677894665532560198051256215915373145226284270408649736509') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 463 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (3,'982718444846268846508445482774217796844461660819285525931206164100817251856409365450682.362683768066405322653747385034480250394145008573806022660379219602846285813744865438912887625784087005970975437905783802114553690522787857272953842288090141945268495451006273685577260054069522075046955466204804067271437138871789034722069934693546671607506851844248427950939791205412350536883779850165603116191193657054604569586553874805856647223849267039531773072343908345333155562072887754900969504551717514980465801806565999410206735831440712124661645970935112535081991606671600328471264697018198676317466846450405861359235297846597981143547119390922405594115478086038680663368675222949247096131378724350715530605691796680604309063173515781378545860473572389718345696107553363715518601596249508215455106779522851210398208919496668879040223859884166805448827948087400426315425231119801173387715922086154065273') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 464 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (4,'861542720105376650266753999919217194383259935058507531116.774511336660822591851369622743235084609149542494189385785321912210129989390054947787009383210009523204976629456268332186620016067379702483800883493431423160815760933380418976582725913410929214462739708321325884209636272001805871036779154087677637129248122540412937033791526383240502286607736226090213753913654673523613612439527815137888202973659987501649474772884055648603290154867585312925699571949539600328906295652872654314913539778815035321695215634102441494403825526533235061083947035338872599854931230001361227174477274708230470794066733245241594719912710139298949856243576688344051439047966427547889756037265151798639614843866387316916203238068277912991427278268083231579195846744438643659745041780103653332041031419793815914447232121937821142169172566753399257291244398531365781832297786941359729799400') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 465 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (5,'198021976607570296508.271597639984889464620426933601643322058775615235389194561064983706229795978402690473201671702614911129095149240715527556855309177671128442458698638704394974473956869419481315262823632891676087912529523219333012290621046361106033860210270638559271706082115529424772192777643046125905852037759566224116373416253787241195450409652089019290072319861181399387753223422998872180810295299831487867222464355713552301775702554189470264147325049133532522718679336524769566984150923939420759804463781082299907043016120177416779442865059261387111806785876531152192378576258351599534512031062777609734092707165605364139201322351960602280089186180302246827234844736393745487324460438448807241887783263546165171099497316415863122023114646876909575845860402164818094500541234974716577550807551946414081410743197768993152975501') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 466 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (6,'.000873076977206566818052116526263730226812004454463281371489634779519089200224205946321120805055212090024554381349223642352209212670470260295303361873760972918129853308169576675500721645609379420329169271088810484607337679253503247351324049221970104335289487989027621978310506220905131150125321713385148268584530413680037620544212746920563790371941626294733473967065607791756894237438288480748407449237446113996117912144587258434808327522518688617394025018756570740098795745692805352377041347367240475846033282850136270250633825482156304826383360291164928049344226886150285595932088884965511963310715773499733217615863523253012606066583814112265708693122563204149232245895551314975524172504103194858904869273185785182598234060315036187756490539352752560361560286717869643902435677448962235275054804452967413005') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 467 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (7,'176514565873872717825163931126806100435750.096278384530154766967061948052237623936423931849868926020451465515367348890410352640552194499619062823622476972850692557798609619250753020363520533767813563613425606228355802781302735485038377521515850536680425059519814786118919994914180918228654298075183514200191737597656810036850772127169441661576862538643715648802139886576391427423689320082366572297580054381937437005879583216745596935643579262248665490169331304003204939561361718554509909313409421397022626924406091551900222555950699170864234411017062042057683304265485826061096835531732950909546314722726990314852356462874701181085379772134121978510387397276859318242238150439474660772561390798432890789762504242822787017140808209820627435991445529404692793744568204608385843245177656436105160780897472099970336514833257055017279707999437302548655364559') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 468 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (8,'72941951052009383458167.300747500436981484566111756088702608000390737594784514635592222758882092500858797317505303492923829092720870826490477962201959426813271424853341826896270963213736922458746003100613943600855942721319226948714369219316345322636075285343544788982588956431405042577296229122673590336976893594798942025893296105815818487227300314490440902574022885833779324177053242170024559675073866612316965636832258283516275906085642459351367507561963945012828379111856700009391438637054015804558386733558956649061672420804826896303889067785497738203077050774825608647969196321506624991188638449047860249367840775936911749905927108478444112230174584693363226143549933224252679398881354887872642908328737917862751077365602631600279486028043329404269490375935308156815477700961014566228692743960491745353377403533037122586797765130') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 469 +-- truncate_limit: 100 +INSERT INTO num_exp_power_10_ln VALUES (9,'661239032819374816.097553651299556484820492272269662685578275493609248662925676004753503494252951243895572437264999063878330704584509915845096232798927524470286655554736724913758600775591269525423912692080421094644542553026831758426157681271572808657664918053119324646138457659418857926209701677786068580819823633713337632456905824562235373422309621872998037966404189020165296080436871220718574009921789858751384547836431858428729570977259373272041837411903005303672798845573379758630607982213326716018594073712340609488043353995410508475153538231445235003980586600882223782814368245305160648543466496726973755388826656879616734762068443462618454921858705377028522664844761719759342490380417060255776725333319537746890406213693117052223545525717132695297770810635066731941724108167146710297146989770382041617889670713111888375717') +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_exp_power_10_ln VALUES (...)" +== 470 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 471 +-- truncate_limit: 100 +BEGIN TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 472 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (0, '0') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (0, '0')" +== 473 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (1, '85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 474 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (2, '-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 475 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (3, '-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 476 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (4, '5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 477 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (5, '-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 478 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (6, '0.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 479 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (7, '-818934540071845742') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (7, '-818934540071845742')" +== 480 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (8, '8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 481 +-- truncate_limit: 100 +INSERT INTO num_data VALUES (9, '054863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633') +-- +TABLE: name="num_data" schema="" table="num_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_data VALUES (...)" +== 482 +-- truncate_limit: 100 +COMMIT TRANSACTION +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 483 +-- truncate_limit: 100 +-- ****************************** +-- * Create indices for faster checks +-- ****************************** + +CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add (id1, id2) +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add USING btree (id1, id2)" +== 484 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub (id1, id2) +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub USING btree (id1, id2)" +== 485 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div (id1, id2) +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div USING btree (id1, id2)" +== 486 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul (id1, id2) +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul USING btree (id1, id2)" +== 487 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt (id) +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt USING btree (id)" +== 488 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln (id) +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln USING btree (id)" +== 489 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 (id) +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 USING btree (id)" +== 490 +-- truncate_limit: 100 +CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln (id) +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln USING btree (id)" +== 491 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_add +-- +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_add" +== 492 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_sub +-- +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_sub" +== 493 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_div +-- +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_div" +== 494 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_mul +-- +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_mul" +== 495 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_sqrt +-- +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_sqrt" +== 496 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_ln +-- +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_ln" +== 497 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_log10 +-- +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_log10" +== 498 +-- truncate_limit: 100 +VACUUM ANALYZE num_exp_power_10_ln +-- +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) num_exp_power_10_ln" +== 499 +-- truncate_limit: 100 +-- ****************************** +-- * Now check the behaviour of the NUMERIC type +-- ****************************** + +-- ****************************** +-- * Addition check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 500 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val FROM num_data t1, num_data t2" +== 501 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_add t2 WHERE ..." +== 502 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 503 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) FROM num_data t1, num_data t2" +== 504 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 10) as expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 10) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_add" schema="" table="num_exp_add" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_add" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_add t2 WHERE ..." +== 505 +-- truncate_limit: 100 +-- ****************************** +-- * Subtraction check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 506 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val FROM num_data t1, num_data t2" +== 507 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_sub t2 WHERE ..." +== 508 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 509 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) FROM num_data t1, num_data t2" +== 510 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 40) + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 40) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sub" schema="" table="num_exp_sub" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sub" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_sub t2 WHERE ..." +== 511 +-- truncate_limit: 100 +-- ****************************** +-- * Multiply check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 512 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val FROM num_data t1, num_data t2" +== 513 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_mul t2 WHERE ..." +== 514 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 515 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) + FROM num_data t1, num_data t2 +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) FROM num_data t1, num_data t2" +== 516 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 30) as expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 30) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_mul" schema="" table="num_exp_mul" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_mul" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_mul t2 WHERE ..." +== 517 +-- truncate_limit: 100 +-- ****************************** +-- * Division check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 518 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, t1.val / t2.val + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT ... FROM num_data t1, num_data t2 WHERE t2.val <> '0.0'" +== 519 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.id2, t1.result, t2.expected FROM num_result t1, num_exp_div t2 WHERE ..." +== 520 +-- truncate_limit: 100 +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 521 +-- truncate_limit: 100 +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val / t2.val, 80) + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +TABLE: name="num_data" schema="" table="num_data" ctx=Select +ALIAS: "t1"="num_data" +ALIAS: "t2"="num_data" +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t2" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT ... FROM num_data t1, num_data t2 WHERE t2.val <> '0.0'" +== 522 +-- truncate_limit: 100 +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 80) as expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 80) +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_div" schema="" table="num_exp_div" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_div" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id1" +FILTER: schema="" table="t1" column="id2" +FILTER: schema="" table="t2" column="id2" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM num_result t1, num_exp_div t2 WHERE ..." +== 523 +-- truncate_limit: 100 +-- ****************************** +-- * Square root check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 524 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, SQRT(ABS(val)) + FROM num_data +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="sqrt" function="sqrt" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT id, 0, sqrt(abs(val)) FROM num_data" +== 525 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_sqrt t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_sqrt" schema="" table="num_exp_sqrt" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_sqrt" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_sqrt t2 WHERE ..." +== 526 +-- truncate_limit: 100 +-- ****************************** +-- * Natural logarithm check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 527 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, LN(ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT id, 0, ln(abs(val)) FROM num_data WHERE val <> '0.0'" +== 528 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_ln" schema="" table="num_exp_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_ln t2 WHERE ..." +== 529 +-- truncate_limit: 100 +-- ****************************** +-- * Logarithm base 10 check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 530 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, LOG('10'::numeric, ABS(val)) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT id, 0, log('10'::numeric, abs(val)) FROM num_data WHERE val <> '0.0'" +== 531 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_log10 t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_log10" schema="" table="num_exp_log10" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_log10" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_log10 t2 WHERE ..." +== 532 +-- truncate_limit: 100 +-- ****************************** +-- * POW(10, LN(value)) check +-- ****************************** +DELETE FROM num_result +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM num_result" +== 533 +-- truncate_limit: 100 +INSERT INTO num_result SELECT id, 0, POW(numeric '10', LN(ABS(round(val,1000)))) + FROM num_data + WHERE val != '0.0' +-- +TABLE: name="num_result" schema="" table="num_result" ctx=DML +TABLE: name="num_data" schema="" table="num_data" ctx=Select +FUNCTION: name="pow" function="pow" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FILTER: schema="" table="" column="val" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO num_result SELECT ... FROM num_data WHERE val <> '0.0'" +== 534 +-- truncate_limit: 100 +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_power_10_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected +-- +TABLE: name="num_result" schema="" table="num_result" ctx=Select +TABLE: name="num_exp_power_10_ln" schema="" table="num_exp_power_10_ln" ctx=Select +ALIAS: "t1"="num_result" +ALIAS: "t2"="num_exp_power_10_ln" +FILTER: schema="" table="t1" column="id1" +FILTER: schema="" table="t2" column="id" +FILTER: schema="" table="t1" column="result" +FILTER: schema="" table="t2" column="expected" +STMT: SelectStmt +TRUNCATED: "SELECT t1.id1, t1.result, t2.expected FROM num_result t1, num_exp_power_10_ln t2 WHERE ..." +== 535 +-- truncate_limit: 100 +|-- +-- Test code path for raising to integer powers +|-- + +-- base less than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for p in {-20..20} +-- do +-- b="0.084738" +-- r=$(bc -ql <<< "scale=500 ; $b^$p" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(0.084738, -20, 2744326694304960114888.785913), +(0.084738, -19, 232548755422013710215.445941), +(0.084738, -18, 19705716436950597776.236458), +(0.084738, -17, 1669822999434319754.362725), +(0.084738, -16, 141497461326065387.345189), +(0.084738, -15, 11990211877848128.792857), +(0.084738, -14, 1016026574105094.737649), +(0.084738, -13, 86096059836517.517879), +(0.084738, -12, 7295607918426.821430), +(0.084738, -11, 618215223791.651994), +(0.084738, -10, 52386321633.657007), +(0.084738, -9, 4439112122.5928274), +(0.084738, -8, 376161483.04427101), +(0.084738, -7, 31875171.750205437), +(0.084738, -6, 2701038.3037689083), +(0.084738, -5, 228880.58378476975), +(0.084738, -4, 19394.882908753819), +(0.084738, -3, 1643.4835879219811), +(0.084738, -2, 139.26551227333284), +(0.084738, -1, 11.801080979017678), +(0.084738, 0, 1), +(0.084738, 1, .084738), +(0.084738, 2, .007180528644), +(0.084738, 3, .000608463636235272), +(0.084738, 4, .00005155999160730448), +(0.084738, 5, .000004369090568819767), +(0.084738, 6, .0000003702279966206494), +(0.084738, 7, .00000003137237997764059), +(0.084738, 8, .000000002658432734545308), +(0.084738, 9, .0000000002252702730599003), +(0.084738, 10, .00000000001908895239854983), +(0.084738, 11, .000000000001617559648348316), +(0.084738, 12, .0000000000001370687694817396), +(0.084738, 13, .00000000000001161493338834365), +(0.084738, 14, .0000000000000009842262254614642), +(0.084738, 15, .00000000000000008340136189315355), +(0.084738, 16, .000000000000000007067264604102046), +(0.084738, 17, .0000000000000000005988658680223991), +(0.084738, 18, .00000000000000000005074669592448206), +(0.084738, 19, .000000000000000000004300173519248761), +(0.084738, 20, .0000000000000000000003643881036741015)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH t(b, p, bc_result) AS (...) SELECT ... FROM t" +== 536 +-- truncate_limit: 100 +-- base greater than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for p in {-20..20} +-- do +-- b="37.821637" +-- r=$(bc -ql <<< "scale=500 ; $b^$p" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(37.821637, -20, .00000000000000000000000000000002787363175065101), +(37.821637, -19, .000000000000000000000000000001054226381944797), +(37.821637, -18, .00000000000000000000000000003987256753373947), +(37.821637, -17, .000000000000000000000000001508045775519079), +(37.821637, -16, .00000000000000000000000005703675990106610), +(37.821637, -15, .000000000000000000000002157223628634278), +(37.821637, -14, .00000000000000000000008158972901002847), +(37.821637, -13, .000000000000000000003085857113545666), +(37.821637, -12, .0000000000000000001167121675823920), +(37.821637, -11, .000000000000000004414245235784397), +(37.821637, -10, .0000000000000001669539809368169), +(37.821637, -9, .000000000000006314472862697207), +(37.821637, -8, .0000000000002388237004592846), +(37.821637, -7, .000000000009032703305767796), +(37.821637, -6, .0000000003416316255594496), +(37.821637, -5, .00000001292106732962942), +(37.821637, -4, .0000004886959181938034), +(37.821637, -3, .00001848327962130773), +(37.821637, -2, .0006990678924065984), +(37.821637, -1, .02643989206495742), +(37.821637, 0, 1), +(37.821637, 1, 37.821637), +(37.821637, 2, 1430.476225359769), +(37.821637, 3, 54102.952532687378), +(37.821637, 4, 2046262.2313195326), +(37.821637, 5, 77392987.319777394), +(37.821637, 6, 2927129472.7542235), +(37.821637, 7, 110708828370.511632), +(37.821637, 8, 4187189119324.792454), +(37.821637, 9, 158366346921451.985294), +(37.821637, 10, 5989674486279224.500736), +(37.821637, 11, 226539294168214309.708325), +(37.821637, 12, 8568086950266418559.993831), +(37.821637, 13, 324059074417413536066.149409), +(37.821637, 14, 12256444679171401239980.310926), +(37.821637, 15, 463558801566202198479885.206986), +(37.821637, 16, 17532552720991931019508170.100286), +(37.821637, 17, 663109844696719094948877928.067252), +(37.821637, 18, 25079899837245684700124994552.671731), +(37.821637, 19, 948562867640665366544581398598.127577), +(37.821637, 20, 35876200451584291931921101974730.690104)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH t(b, p, bc_result) AS (...) SELECT ... FROM t" +== 537 +-- truncate_limit: 100 +|-- +-- Tests for raising to non-integer powers +|-- + +-- base less than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for n in {-20..20} +-- do +-- b="0.06933247" +-- p="$n.342987" +-- r=$(bc -ql <<< "scale=500 ; e($p*l($b))" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(0.06933247, -20.342987, 379149253615977128356318.39406340), +(0.06933247, -19.342987, 26287354251852125772450.59436685), +(0.06933247, -18.342987, 1822567200045909954554.65766042), +(0.06933247, -17.342987, 126363085720167050546.86216560), +(0.06933247, -16.342987, 8761064849800910427.02880469), +(0.06933247, -15.342987, 607426265866876128.15466179), +(0.06933247, -14.342987, 42114363355427213.14899924), +(0.06933247, -13.342987, 2919892833909256.59283660), +(0.06933247, -12.342987, 202443382310228.51544515), +(0.06933247, -11.342987, 14035899730722.44924025), +(0.06933247, -10.342987, 973143597003.32229028), +(0.06933247, -9.342987, 67470449244.92493259), +(0.06933247, -8.342987, 4677892898.16028054), +(0.06933247, -7.342987, 324329869.02491071), +(0.06933247, -6.342987, 22486590.914273551), +(0.06933247, -5.342987, 1559050.8899661435), +(0.06933247, -4.342987, 108092.84905705095), +(0.06933247, -3.342987, 7494.3442144625131), +(0.06933247, -2.342987, 519.60139541889576), +(0.06933247, -1.342987, 36.025248159838727), +(0.06933247, 0.342987, .40036522320023350), +(0.06933247, 1.342987, .02775830982657349), +(0.06933247, 2.342987, .001924552183301612), +(0.06933247, 3.342987, .0001334339565121935), +(0.06933247, 4.342987, .000009251305786862961), +(0.06933247, 5.342987, .0000006414158809285026), +(0.06933247, 6.342987, .00000004447094732199898), +(0.06933247, 7.342987, .000000003083280621074075), +(0.06933247, 8.342987, .0000000002137714611621997), +(0.06933247, 9.342987, .00000000001482130341788437), +(0.06933247, 10.342987, .000000000001027597574581366), +(0.06933247, 11.342987, .00000000000007124587801173530), +(0.06933247, 12.342987, .000000000000004939652699872298), +(0.06933247, 13.342987, .0000000000000003424783226243151), +(0.06933247, 14.342987, .00000000000000002374486802900065), +(0.06933247, 15.342987, .000000000000000001646290350274646), +(0.06933247, 16.342987, .0000000000000000001141413763217064), +(0.06933247, 17.342987, .000000000000000000007913703549583420), +(0.06933247, 18.342987, .0000000000000000000005486766139403860), +(0.06933247, 19.342987, .00000000000000000000003804110487572339), +(0.06933247, 20.342987, .000000000000000000000002637483762562946)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH t(b, p, bc_result) AS (...) SELECT ... FROM t" +== 538 +-- truncate_limit: 100 +-- base greater than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of POW(): +|-- +-- for n in {-20..20} +-- do +-- b="27.234987" +-- p="$n.230957" +-- r=$(bc -ql <<< "scale=500 ; e($p*l($b))" | head -n 1) +-- echo "($b, $p, $r)," +-- done + +WITH t(b, p, bc_result) AS (VALUES +(27.234987, -20.230957, .000000000000000000000000000009247064512095633), +(27.234987, -19.230957, .0000000000000000000000000002518436817750859), +(27.234987, -18.230957, .000000000000000000000000006858959399176602), +(27.234987, -17.230957, .0000000000000000000000001868036700701026), +(27.234987, -16.230957, .000000000000000000000005087595525911532), +(27.234987, -15.230957, .0000000000000000000001385605980094587), +(27.234987, -14.230957, .000000000000000000003773696085499835), +(27.234987, -13.230957, .0000000000000000001027765638305389), +(27.234987, -12.230957, .000000000000000002799118379829397), +(27.234987, -11.230957, .00000000000000007623395268611469), +(27.234987, -10.230957, .000000000000002076230710364949), +(27.234987, -9.230957, .00000000000005654611640579014), +(27.234987, -8.230957, .000000000001540032745212181), +(27.234987, -7.230957, .00000000004194277179542807), +(27.234987, -6.230957, .000000001142310844592450), +(27.234987, -5.230957, .00000003111082100243440), +(27.234987, -4.230957, .0000008473028055606278), +(27.234987, -3.230957, .00002307628089450723), +(27.234987, -2.230957, .0006284822101702527), +(27.234987, -1.230957, .01711670482371810), +(27.234987, 0.230957, 2.1451253063142300), +(27.234987, 1.230957, 58.422459830839071), +(27.234987, 2.230957, 1591.1349340009243), +(27.234987, 3.230957, 43334.539242761031), +(27.234987, 4.230957, 1180215.6129275865), +(27.234987, 5.230957, 32143156.875279851), +(27.234987, 6.230957, 875418459.63720737), +(27.234987, 7.230957, 23842010367.779367), +(27.234987, 8.230957, 649336842420.336290), +(27.234987, 9.230957, 17684680461938.907402), +(27.234987, 10.230957, 481642042480060.137900), +(27.234987, 11.230957, 13117514765597885.614921), +(27.234987, 12.230957, 357255344113366461.949871), +(27.234987, 13.230957, 9729844652608062117.440722), +(27.234987, 14.230957, 264992192625800087863.690528), +(27.234987, 15.230957, 7217058921265161257566.469315), +(27.234987, 16.230957, 196556505898890690402726.443417), +(27.234987, 17.230957, 5353213882921711267539279.451015), +(27.234987, 18.230957, 145794710509592328389185797.837767), +(27.234987, 19.230957, 3970717045397510438979206144.696206), +(27.234987, 20.230957, 108142427112079606637962972621.121293)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH t(b, p, bc_result) AS (...) SELECT ... FROM t" +== 539 +-- truncate_limit: 100 +-- Inputs close to overflow +|-- +-- bc(1) results computed with a scale of 2700 and truncated to 4 decimal +-- places. + +WITH t(b, p, bc_result) AS (VALUES +(0.12, -2829.8369, 58463948950011752465280493160293790845494328939320966633018493248607815580903065923369555885857984675501574162389726507612128133630191173383130639968378879506624785786843501848666498440326970769604109017960864573408272864266102690849952650095786874354625921641729880352858506454246180842452983243549491658464046163869265572232996388827878976066830374513768599285647145439771472435206769249126377164951470622827631950210853282324510655982757098065657709137845327135766013147354253426364240746381620690117663724329288646510198895137275207992825719846135857839292915100523542874885080351683587865157015032404901182924720371819942957083390475846809517968191151435281268695782594904484795360890092607679215675240583291240729468370895035823777914792823688291214492607109455017754453939895630226174304357121900605689015734289765672740769194115142607443713769825894380064727556869268488695795705030158832909348803019429370973064732712469794182891757241046263341655894972953512257981661670321890336672832647028099324621932563236459127918144141230217523147304565594514812518826936144181257723061181656522095236928347413997136815409159361412494284201481609684892562646522086577634100783077813105675590737823924220663206479031113753135119759722725207724879578900186075841393115040465401462266086907464970054073340036852442184414587772177753008511913377364966775792477387717262694468450099866775550614257191941835797445874557362115814601886902749237439492398087966544817154173072811937702110580330775581851211123491341435883319798273456296794954514173820352334127081705706502510709179711510240917772628308487366740741280043704807717608366220401933596364641284631036907635403895053036499618723044314773148779735006542501244942039455169872946018271985844759209768927953340447524637670938413827595013338859796135512187473850161303598087634723542727044978083220970836296653305188470017342167913572166172051819741354902582606590658382067039498769674611071582171914886494269818475850690414812481252963932223686078322390396586222238852602472958831686564971334200490182175112490433364675164900946902818404704835106260174052265784055642968397240262737313737007322288203637798365320295080314524864099419556398713380156353062937736280885716820226469419928595465390700629307079710611273715705695938635644841913194091407807776191951797748706106000922803167645881087385311847268311361092838264814899353459146959869764278464187826798546290981492648723002412475976344071283321798061003719251864595518596639432393032991023409676558943539937377229130132816883146259468718344018277257037013406135980469482324577407154032999045733141275895.3432), +(1.2, 32908.8896, 58463467728170833376633133695001863276259293590926929026251227859007891876739460057725441400966420577009060860805883032969522911803372870882799865787473726926215148161529632590083389287080925059682489116446754279752928005457087175157581627230586554364417068189211136840990661174760199073702207450133797324318403866058202372178813998850887986769280847189341565507156189065295823921162851958925352114220880236114784962150135485415106748467247897246441194126125699204912883449386043559785865023459356275014504597646990160571664166410683323036984805434677654413174177920726210827006973855410386789516533036723888687725436216478665958434776205940192130053647653715221076841771578099896259902368829351569726536927952661429685419815305418450230567773264738536471211804481206474781470237730069753206249915908804615495060673071058534441654604668770343616386612119048579369195201590008082689834456232255266932976831478404670192731621439902738547169253818323045451045749609624500171633897705543164388470746657118050314064066768449450440405619135824055131398727045420324382226572368236570500391463795989258779677208133531636928003546809249007993065200108076924439703799231711400266122025052209803513232429907231051873161206025860851056337427740362763618748092029386371493898291580557004812947013231371383576580415676519066503391905962989205397824064923920045371823949776899815750413244195402085917098964452866825666226141169411712884994564949174271056284898570445214367063763956186792886147126466387576513166370247576466566827375268334148320298849218878848928271566491769458471357076035396330179659440244425914213309776100351793665960978678576150833311810944729586040624059867137538839913141142139636023129691775489034134511666020819676247950267220131499463010350308195762769192775344260909521732256844149916046793599150786757764962585268686580124987490115873389726527572428003433405659445349155536369077209682951123806333170190998931670309088422483075609203671527331975811507450670132060984691061148836994322505371265263690017938762760088575875666254883673433331627055180154954694693433502522592907190906966067656027637884202418119121728966267936832338377284832958974299187166554160783467156478554899314000348357280306042140481751668215838656488457943830180819301102535170705017482946779698265096226184239631924271857062033454725540956591929965181603262502135610768915716020374362368495244256420143645126927013882334008435586481691725030031204304273292938132599127402133470745819213047706793887965197191137237066440328777206799072470374264316425913530947082957300047105685634407092811630672103242089966046839626911122.7149)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH t(b, p, bc_result) AS (...) SELECT ... FROM t" +== 540 +-- truncate_limit: 100 +|-- +-- Tests for EXP() +|-- + +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of EXP(): +|-- +-- for n in {-20..20} +-- do +-- x="$n.29837" +-- r=$(bc -ql <<< "scale=500 ; e($x)" | head -n 1) +-- echo "($x, $r)," +-- done + +WITH t(x, bc_result) AS (VALUES +(-20.29837, .000000001529431101152222), +(-19.29837, .000000004157424770142192), +(-18.29837, .00000001130105220586304), +(-17.29837, .00000003071944485366452), +(-16.29837, .00000008350410872606600), +(-15.29837, .0000002269877013517336), +(-14.29837, .0000006170165438681061), +(-13.29837, .000001677224859055276), +(-12.29837, .000004559169856609741), +(-11.29837, .00001239310857408049), +(-10.29837, .00003368796183504298), +(-9.29837, .00009157337449401917), +(-8.29837, .0002489222398577673), +(-7.29837, .0006766408013046928), +(-6.29837, .001839300394580514), +(-5.29837, .004999736839665763), +(-4.29837, .01359069379834070), +(-3.29837, .03694333598818056), +(-2.29837, .1004223988993283), +(-1.29837, .2729763820983097), +(0.29837, 1.3476603299656679), +(1.29837, 3.6633205858807959), +(2.29837, 9.9579377804197108), +(3.29837, 27.068481317440698), +(4.29837, 73.579760889182206), +(5.29837, 200.01052696742555), +(6.29837, 543.68498095607070), +(7.29837, 1477.8890041389891), +(8.29837, 4017.3188244304487), +(9.29837, 10920.204759575742), +(10.29837, 29684.194161006717), +(11.29837, 80690.005580314652), +(12.29837, 219338.17590722828), +(13.29837, 596222.97785597218), +(14.29837, 1620702.0864156289), +(15.29837, 4405525.0308492653), +(16.29837, 11975458.636179032), +(17.29837, 32552671.598188404), +(18.29837, 88487335.673150406), +(19.29837, 240533516.60908059), +(20.29837, 653837887.33381570)) +SELECT x, bc_result, exp(x), exp(x)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="exp" function="exp" schema="" ctx=Call +FUNCTION: name="exp" function="exp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT x, bc_result, exp(x), exp(x) - bc_result AS diff FROM t" +== 541 +-- truncate_limit: 100 +|-- +-- Tests for LN() +|-- + +-- input very small +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(10^-$p)" | head -n 1) +-- echo "('1.0e-$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', -2.3025850929940457), +('1.0e-2', -4.6051701859880914), +('1.0e-3', -6.9077552789821371), +('1.0e-4', -9.2103403719761827), +('1.0e-5', -11.512925464970228), +('1.0e-6', -13.815510557964274), +('1.0e-7', -16.118095650958320), +('1.0e-8', -18.420680743952365), +('1.0e-9', -20.723265836946411), +('1.0e-10', -23.025850929940457), +('1.0e-11', -25.328436022934503), +('1.0e-12', -27.631021115928548), +('1.0e-13', -29.933606208922594), +('1.0e-14', -32.236191301916640), +('1.0e-15', -34.5387763949106853), +('1.0e-16', -36.84136148790473094), +('1.0e-17', -39.143946580898776628), +('1.0e-18', -41.4465316738928223123), +('1.0e-19', -43.74911676688686799634), +('1.0e-20', -46.051701859880913680360), +('1.0e-21', -48.3542869528749593643778), +('1.0e-22', -50.65687204586900504839581), +('1.0e-23', -52.959457138863050732413803), +('1.0e-24', -55.2620422318570964164317949), +('1.0e-25', -57.56462732485114210044978637), +('1.0e-26', -59.867212417845187784467777822), +('1.0e-27', -62.1697975108392334684857692765), +('1.0e-28', -64.47238260383327915250376073116), +('1.0e-29', -66.774967696827324836521752185847), +('1.0e-30', -69.0775527898213705205397436405309), +('1.0e-31', -71.38013788281541620455773509521529), +('1.0e-32', -73.682722975809461888575726549899655), +('1.0e-33', -75.9853080688035075725937180045840189), +('1.0e-34', -78.28789316179755325661170945926838306), +('1.0e-35', -80.590478254791598940629700913952747266), +('1.0e-36', -82.8930633477856446246476923686371114736), +('1.0e-37', -85.19564844077969030866568382332147568124), +('1.0e-38', -87.498233533773735992683675278005839888842), +('1.0e-39', -89.8008186267677816767016667326902040964430), +('1.0e-40', -92.10340371976182736071965818737456830404406)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 542 +-- truncate_limit: 100 +-- input very close to but smaller than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1-10^-$p)" | head -n 1) +-- echo "('1.0e-$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', -.10536051565782630), +('1.0e-2', -.010050335853501441), +('1.0e-3', -.0010005003335835335), +('1.0e-4', -.00010000500033335834), +('1.0e-5', -.000010000050000333336), +('1.0e-6', -.0000010000005000003333), +('1.0e-7', -.00000010000000500000033), +('1.0e-8', -.000000010000000050000000), +('1.0e-9', -.0000000010000000005000000), +('1.0e-10', -.00000000010000000000500000), +('1.0e-11', -.000000000010000000000050000), +('1.0e-12', -.0000000000010000000000005000), +('1.0e-13', -.00000000000010000000000000500), +('1.0e-14', -.000000000000010000000000000050), +('1.0e-15', -.0000000000000010000000000000005), +('1.0e-16', -.00000000000000010000000000000001), +('1.0e-17', -.000000000000000010000000000000000), +('1.0e-18', -.0000000000000000010000000000000000), +('1.0e-19', -.00000000000000000010000000000000000), +('1.0e-20', -.000000000000000000010000000000000000), +('1.0e-21', -.0000000000000000000010000000000000000), +('1.0e-22', -.00000000000000000000010000000000000000), +('1.0e-23', -.000000000000000000000010000000000000000), +('1.0e-24', -.0000000000000000000000010000000000000000), +('1.0e-25', -.00000000000000000000000010000000000000000), +('1.0e-26', -.000000000000000000000000010000000000000000), +('1.0e-27', -.0000000000000000000000000010000000000000000), +('1.0e-28', -.00000000000000000000000000010000000000000000), +('1.0e-29', -.000000000000000000000000000010000000000000000), +('1.0e-30', -.0000000000000000000000000000010000000000000000), +('1.0e-31', -.00000000000000000000000000000010000000000000000), +('1.0e-32', -.000000000000000000000000000000010000000000000000), +('1.0e-33', -.0000000000000000000000000000000010000000000000000), +('1.0e-34', -.00000000000000000000000000000000010000000000000000), +('1.0e-35', -.000000000000000000000000000000000010000000000000000), +('1.0e-36', -.0000000000000000000000000000000000010000000000000000), +('1.0e-37', -.00000000000000000000000000000000000010000000000000000), +('1.0e-38', -.000000000000000000000000000000000000010000000000000000), +('1.0e-39', -.0000000000000000000000000000000000000010000000000000000), +('1.0e-40', -.00000000000000000000000000000000000000010000000000000000)) +SELECT '1-'||x, bc_result, ln(1.0-x::numeric), ln(1.0-x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 543 +-- truncate_limit: 100 +-- input very close to but larger than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1+10^-$p)" | head -n 1) +-- echo "('1.0e-$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', .09531017980432486), +('1.0e-2', .009950330853168083), +('1.0e-3', .0009995003330835332), +('1.0e-4', .00009999500033330834), +('1.0e-5', .000009999950000333331), +('1.0e-6', .0000009999995000003333), +('1.0e-7', .00000009999999500000033), +('1.0e-8', .000000009999999950000000), +('1.0e-9', .0000000009999999995000000), +('1.0e-10', .00000000009999999999500000), +('1.0e-11', .000000000009999999999950000), +('1.0e-12', .0000000000009999999999995000), +('1.0e-13', .00000000000009999999999999500), +('1.0e-14', .000000000000009999999999999950), +('1.0e-15', .0000000000000009999999999999995), +('1.0e-16', .00000000000000010000000000000000), +('1.0e-17', .000000000000000010000000000000000), +('1.0e-18', .0000000000000000010000000000000000), +('1.0e-19', .00000000000000000010000000000000000), +('1.0e-20', .000000000000000000010000000000000000), +('1.0e-21', .0000000000000000000010000000000000000), +('1.0e-22', .00000000000000000000010000000000000000), +('1.0e-23', .000000000000000000000010000000000000000), +('1.0e-24', .0000000000000000000000010000000000000000), +('1.0e-25', .00000000000000000000000010000000000000000), +('1.0e-26', .000000000000000000000000010000000000000000), +('1.0e-27', .0000000000000000000000000010000000000000000), +('1.0e-28', .00000000000000000000000000010000000000000000), +('1.0e-29', .000000000000000000000000000010000000000000000), +('1.0e-30', .0000000000000000000000000000010000000000000000), +('1.0e-31', .00000000000000000000000000000010000000000000000), +('1.0e-32', .000000000000000000000000000000010000000000000000), +('1.0e-33', .0000000000000000000000000000000010000000000000000), +('1.0e-34', .00000000000000000000000000000000010000000000000000), +('1.0e-35', .000000000000000000000000000000000010000000000000000), +('1.0e-36', .0000000000000000000000000000000000010000000000000000), +('1.0e-37', .00000000000000000000000000000000000010000000000000000), +('1.0e-38', .000000000000000000000000000000000000010000000000000000), +('1.0e-39', .0000000000000000000000000000000000000010000000000000000), +('1.0e-40', .00000000000000000000000000000000000000010000000000000000)) +SELECT '1+'||x, bc_result, ln(1.0+x::numeric), ln(1.0+x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 544 +-- truncate_limit: 100 +-- input very large +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(10^$p)" | head -n 1) +-- echo "('1.0e$p', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e1', 2.3025850929940457), +('1.0e2', 4.6051701859880914), +('1.0e3', 6.9077552789821371), +('1.0e4', 9.2103403719761827), +('1.0e5', 11.512925464970228), +('1.0e6', 13.815510557964274), +('1.0e7', 16.118095650958320), +('1.0e8', 18.420680743952365), +('1.0e9', 20.723265836946411), +('1.0e10', 23.025850929940457), +('1.0e11', 25.328436022934503), +('1.0e12', 27.631021115928548), +('1.0e13', 29.933606208922594), +('1.0e14', 32.236191301916640), +('1.0e15', 34.538776394910685), +('1.0e16', 36.841361487904731), +('1.0e17', 39.143946580898777), +('1.0e18', 41.446531673892822), +('1.0e19', 43.749116766886868), +('1.0e20', 46.051701859880914), +('1.0e21', 48.354286952874959), +('1.0e22', 50.656872045869005), +('1.0e23', 52.959457138863051), +('1.0e24', 55.262042231857096), +('1.0e25', 57.564627324851142), +('1.0e26', 59.867212417845188), +('1.0e27', 62.169797510839233), +('1.0e28', 64.472382603833279), +('1.0e29', 66.774967696827325), +('1.0e30', 69.077552789821371), +('1.0e31', 71.380137882815416), +('1.0e32', 73.682722975809462), +('1.0e33', 75.985308068803508), +('1.0e34', 78.287893161797553), +('1.0e35', 80.590478254791599), +('1.0e36', 82.893063347785645), +('1.0e37', 85.195648440779690), +('1.0e38', 87.498233533773736), +('1.0e39', 89.800818626767782), +('1.0e40', 92.103403719761827)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 545 +-- truncate_limit: 100 +-- input huge +|-- +-- bc(1) results computed with a scale of 1000 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..10} +-- do +-- l=$(bc -ql <<< "scale=1000 ; l(10^${p}00)" | head -n 1) +-- echo "('1.0e${p}00', $l)," +-- done + +WITH t(x, bc_result) AS (VALUES +('1.0e100', 230.25850929940457), +('1.0e200', 460.51701859880914), +('1.0e300', 690.77552789821371), +('1.0e400', 921.03403719761827), +('1.0e500', 1151.2925464970228), +('1.0e600', 1381.5510557964274), +('1.0e700', 1611.8095650958320), +('1.0e800', 1842.0680743952365), +('1.0e900', 2072.3265836946411), +('1.0e1000', 2302.5850929940457)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="ln" function="ln" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 546 +-- truncate_limit: 100 +-- inputs with 1000 decimal places +|-- +-- bc(1) results computed with a scale of 2000 and rounded to 1000 decimal +-- places + +WITH t(x, bc_result) AS (VALUES +(484990182159328900690402236933516249572671683638747490717351807610531884491845416923860371219625151551889257298200816555016472471293780254009492949585031653913930735918829139712249577547959394351523545901788627247613322896296041868431769047433229466634098452564756860190085118463828382895145244362033728480588969626012192733802377468089120757046364393407262957242230928854711898925295251902007136232994524624903257456111389508582206404271734668422903183500589303866613158037169610592539145461637447957948521714058034772237111009429638870236361143304703683377693378577075353794118557951847394763531830696578809001981568860219578880229402696449243344235099860421846016326538272155937175661905904288335499593232232926636205909086901191153907183842087577811871344870731324067822883041265129394268082883745408414994.8967939438561591657171240282983703914075472645212002662497023142663831371447287624846942598424990784971781730103682951722370983277124599054059027055336437808366784501932987082321905202623642371063626378290734289114618092750984153422293450048717769065428713836637664433167768445609659527458911187829232316677137895259433038764404970599325009178297626038331436654541552998098529141205301472138026818453893127265938030066392881979113522757891639646670670272542401773230506961559808927249585675430838495658225557294666522469887436551840596777627408780618586500922973500018513068499587683746133637919751545157547095670767246977244726331271787622126889459658539988980096764323712767863722912919120929339399753431689512753214200090670880647731689804555417871258907716687575767185444541243606329768784843125926070743277339790277626515824924290352180761378846035233155198504033292692893297993698953705472933411199778880561376633444249703838589180474329586470353212010427945060694794274109764269805332803290229, + 1864.3702986939570026328504202935192533137907736189919154633800554877738455118081651650863235106905871352085850240570561347180517240105510505203972860921397909573687877993477806728098306202020229409548306695695574102950949468160529713610952021974630774784174851619325758380143625473386495586347322798415543385655090746985183329114860118551572428921774322172798724455202876781611633419444058398798142214904998877857425038669920064728855823072107227506485770367799671977282350083029452784747350395161797215115525867416898416360638482342253129160308632504217096916335590470843180746834864303790913372081974355613359678634194879425862536147988835528973291020680020540866655622823550861337486588647231688134992810403147262346312159819432914207194632564009749236609081399504118359354620598232725290537215007867979331582119891661859015726276335168158288396939655310210558566592649049602925182137256134162660116182293851038854455437841571331011002023088829768308520393956515509475418031437505751407687618234418262), +(87190145885430429849953615409019208993240447426362428988181639909267773304254748257120061524000254226856815085523676417146197197996896030672521334101413071112068202429835905642444187493717977611730127126387257253646790849384975208460867137315507010888782632024640844766297185244443116696943912406389670302370461137850160539373600494054874979342373255280815156048999900951842673141766630630919020492255966628630634124452614590400422133958133100159154995520080124736657520969784129924799670552560034302960877087853678350801769339861812435411200669026902417951572668727488315537985378304242438181615160041688723201917323705450185975141141262578884689500612295576288125956289035673242989906973367691922065122033180281670221390667818909912035903387888639331486823729897326624516015340.0330856710565117793999512551468220085711713631167607285185762046751452975325645379302403715842570486302993296501788672462090620871511446272026693318239212657949496275318383141403236705902077406660768573015707706831878445598837931116223956945944726162551477136715847593742032488181481888084716920605114101902724395659898621880016853548602514706686907951229872573180602614761229992106144727082722940736406782659562775289407005631298246624198606031298081220736931229256511054595028182057216042683060059115371651410352645266000330509331097811566633211452233019461903115970558624057877018778178814946285827512359903934291318219271464841957435711594154280905473802599888081783098187210283997106131616471807951265003903143099667366508222327805543948921694362089860577380749774036318574113007382111997454202845559941557812813566442364810680529092880773126707073967537693927177460459341763934709686530005721141046645111784404932103241501569571235364365556796422998363930810983452790309019295181282099408260156, + 1793.5767085750017553306932533574391150814202249805881581227430032600579405884415934520704053351781361105595296647510475380766428668443641914861849764330704062323054023252886955844207807229267936432730818329225450152491146839618683772020068682795388746108876393249306737841247788224204701299467519965182171772253974884845661168860422489046657965359832930382114760565628765599962013955588754803194908990025689040598990346417563277021386852342928910383706995866844541160576254266641602065102228267316550706943783591722246885978355472097314691737807509436806788803362444745551013400341861820755594413819894154786253014501454443272120342005711761286524843010157182464200556865694401941794983935172457481497909987740544409272349152397774548604845897687504977786762391359552407068124283290504752932824699865504970420939586707791994870941813718246825616335675307740641350673558328821461530563823677144691877374809441673507467507447891562257806191361453045937798278733402269265623588493124129181374135958668436774), +(93936642222690597390233191619858485419795942047468396309991947772747208870873993801669373075421461116465960407843923269693395211616591453397070258466704654943689268224479477016161636938138334729982904232438440955361656138189836032891825113139184685132178764873033678116450665758561650355252211196676137179184043639278410827092182700922151290703747496962700158844772453483316974221113826173404445159281421213715669245417896170368554410830320000019029956317336703559699859949692222685614036912057150632902650913831404804982509990655560731349634628713944739168096272097122388116038119844786988276635032016787352796502360718569977397214936366251320294621522016.6483354941025384161536675750898007896744690911429670830432784905421638721478353275821072200938900938046264210604940707974410950770029535636602548377806284157951164875821446035013896786653932045182167021839184824627082391478016195098055107001433336586881395912782883663046617432598969149948351689103230162742769845955320418573803127107923535948653168889411316007796459064267436246637115946581149511513369842911210359447262641996566147462977170742544980481275049898092152042927981394239266559286915303786701737610786594006685748456635797125029722684151298695274097006242412384086302106763844070230264910503179385988626477852818174114043927841085089058972074427820150462261941575665882880501074676800316585217150509780489224388148722603385921057007086785238310735038314861960410473809826927329368597558806004392175746233568789445929554890241140656324160187253042639339549705859147930476532359840809944163908006480881926041259363654863689570520534301207043189181147254153307163555433328278834311658232337, + 1510.4332713542154696529645934345554302578243896764921637693542962119938599884313210100957753316832762996428481801312323020427109678979117469716796746760060470871840325255146954580681101106876674367471955788143763250819168311353856748872452260808797135108102729064040463343792765872545182299889360257515315869180266759715933989413256377582681707188367254513700731642913479683031478361835565783219287780434673712341147656477670848734998849030451414278832848680301511646182446524915091598080243532068451726548537866633622180283865668708517173065893429240665300584705585310049892047293928733753369421499719516009692095913169665213597158441636480707309244604139865130782756488091268094213446272360006907802989573582755585110277620911226015342778471352130366770729972784317323917141031824334355639769512749560550167491709646539950725523461943580211843652293561678342656010571108219244870234329176123205423872844099992204896411752620881541000940129833754169391528449211839693800724450201835161044717173715867437)) +SELECT trim_scale(ln(x::numeric)-bc_result) AS diff FROM t +-- +CTE: "t" +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="ln" function="ln" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (VALUES (...)) SELECT trim_scale(ln(x::numeric) - bc_result) AS diff FROM t" +== 547 +-- truncate_limit: 100 +|-- +-- Tests for LOG() (base 10) +|-- + +-- input very small, exact result known +WITH t(x) AS (SELECT '1e-'||n FROM generate_series(1, 100) g(n)) +SELECT x, log(x::numeric) FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x) AS (SELECT '1e-' || n FROM generate_series(1, 100) g(n)) SELECT x, log(x::numeric) FROM t" +== 548 +-- truncate_limit: 100 +-- input very small, non-exact results +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..50..7} +-- do +-- for d in {9..1..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l($d*10^-$p) / l(10)" | head -n 1) +-- echo "('${d}.0e-$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', -.04575749056067513), +('6.0e-1', -.2218487496163564), +('3.0e-1', -.5228787452803376), +('9.0e-8', -7.045757490560675), +('6.0e-8', -7.221848749616356), +('3.0e-8', -7.522878745280338), +('9.0e-15', -14.0457574905606751), +('6.0e-15', -14.2218487496163564), +('3.0e-15', -14.5228787452803376), +('9.0e-22', -21.04575749056067512540994), +('6.0e-22', -21.22184874961635636749123), +('3.0e-22', -21.52287874528033756270497), +('9.0e-29', -28.045757490560675125409944193490), +('6.0e-29', -28.221848749616356367491233202020), +('3.0e-29', -28.522878745280337562704972096745), +('9.0e-36', -35.0457574905606751254099441934897693816), +('6.0e-36', -35.2218487496163563674912332020203916640), +('3.0e-36', -35.5228787452803375627049720967448846908), +('9.0e-43', -42.04575749056067512540994419348976938159974227), +('6.0e-43', -42.22184874961635636749123320202039166403168125), +('3.0e-43', -42.52287874528033756270497209674488469079987114), +('9.0e-50', -49.045757490560675125409944193489769381599742271618608), +('6.0e-50', -49.221848749616356367491233202020391664031681254347196), +('3.0e-50', -49.522878745280337562704972096744884690799871135809304)) +SELECT x, bc_result, log(x::numeric), log(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 549 +-- truncate_limit: 100 +-- input very close to but smaller than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40..7} +-- do +-- for d in {9..1..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1-$d*10^-$p) / l(10)" | head -n 1) +-- echo "('${d}.0e-$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', -1.0000000000000000), +('6.0e-1', -.3979400086720376), +('3.0e-1', -.1549019599857432), +('9.0e-8', -.000000039086505130185422), +('6.0e-8', -.000000026057669695925208), +('3.0e-8', -.000000013028834652530076), +('9.0e-15', -.0000000000000039086503371292840), +('6.0e-15', -.0000000000000026057668914195188), +('3.0e-15', -.0000000000000013028834457097574), +('9.0e-22', -.00000000000000000000039086503371292664), +('6.0e-22', -.00000000000000000000026057668914195110), +('3.0e-22', -.00000000000000000000013028834457097555), +('9.0e-29', -.000000000000000000000000000039086503371292664), +('6.0e-29', -.000000000000000000000000000026057668914195110), +('3.0e-29', -.000000000000000000000000000013028834457097555), +('9.0e-36', -.0000000000000000000000000000000000039086503371292664), +('6.0e-36', -.0000000000000000000000000000000000026057668914195110), +('3.0e-36', -.0000000000000000000000000000000000013028834457097555)) +SELECT '1-'||x, bc_result, log(1.0-x::numeric), log(1.0-x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 550 +-- truncate_limit: 100 +-- input very close to but larger than 1 +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {1..40..7} +-- do +-- for d in {9..1..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l(1+$d*10^-$p) / l(10)" | head -n 1) +-- echo "('${d}.0e-$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', .2787536009528290), +('6.0e-1', .2041199826559248), +('3.0e-1', .1139433523068368), +('9.0e-8', .000000039086501612400118), +('6.0e-8', .000000026057668132465074), +('3.0e-8', .000000013028834261665042), +('9.0e-15', .0000000000000039086503371292489), +('6.0e-15', .0000000000000026057668914195031), +('3.0e-15', .0000000000000013028834457097535), +('9.0e-22', .00000000000000000000039086503371292664), +('6.0e-22', .00000000000000000000026057668914195110), +('3.0e-22', .00000000000000000000013028834457097555), +('9.0e-29', .000000000000000000000000000039086503371292664), +('6.0e-29', .000000000000000000000000000026057668914195110), +('3.0e-29', .000000000000000000000000000013028834457097555), +('9.0e-36', .0000000000000000000000000000000000039086503371292664), +('6.0e-36', .0000000000000000000000000000000000026057668914195110), +('3.0e-36', .0000000000000000000000000000000000013028834457097555)) +SELECT '1+'||x, bc_result, log(1.0+x::numeric), log(1.0+x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" +== 551 +-- truncate_limit: 100 +-- input very large, exact result known +WITH t(x) AS (SELECT '1e'||n FROM generate_series(1, 100) g(n)) +SELECT x, log(x::numeric) FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x) AS (SELECT '1e' || n FROM generate_series(1, 100) g(n)) SELECT x, log(x::numeric) FROM t" +== 552 +-- truncate_limit: 100 +-- input very large, non-exact results +|-- +-- bc(1) results computed with a scale of 500 and truncated using the script +-- below, and then rounded by hand to match the precision of LN(): +|-- +-- for p in {10..50..7} +-- do +-- for d in {2..9..3} +-- do +-- l=$(bc -ql <<< "scale=500 ; l($d*10^$p) / l(10)" | head -n 1) +-- echo "('${d}.0e$p', $l)," +-- done +-- done + +WITH t(x, bc_result) AS (VALUES +('2.0e10', 10.301029995663981), +('5.0e10', 10.698970004336019), +('8.0e10', 10.903089986991944), +('2.0e17', 17.301029995663981), +('5.0e17', 17.698970004336019), +('8.0e17', 17.903089986991944), +('2.0e24', 24.301029995663981), +('5.0e24', 24.698970004336019), +('8.0e24', 24.903089986991944), +('2.0e31', 31.301029995663981), +('5.0e31', 31.698970004336019), +('8.0e31', 31.903089986991944), +('2.0e38', 38.301029995663981), +('5.0e38', 38.698970004336019), +('8.0e38', 38.903089986991944), +('2.0e45', 45.30102999566398), +('5.0e45', 45.69897000433602), +('8.0e45', 45.90308998699194)) +SELECT x, bc_result, log(x::numeric), log(x::numeric)-bc_result AS diff FROM t +-- +CTE: "t" +FUNCTION: name="log" function="log" schema="" ctx=Call +FUNCTION: name="log" function="log" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH t(x, bc_result) AS (...) SELECT ... FROM t" diff --git a/parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json b/parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/numerology.test b/parser/testdata/summary_truncate/postgres_regress/numerology.test new file mode 100644 index 0000000..a9585ea --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/numerology.test @@ -0,0 +1,201 @@ +== 001 +-- truncate_limit: 100 +|-- +-- NUMEROLOGY +-- Test various combinations of numeric types and functions. +|-- + + +|-- +-- numeric literals +|-- + +SELECT 0b100101; +SELECT 0o273; +SELECT 0x42F; + +-- cases near int4 overflow +SELECT 0b1111111111111111111111111111111; +SELECT 0b10000000000000000000000000000000; +SELECT 0o17777777777; +SELECT 0o20000000000; +SELECT 0x7FFFFFFF; +SELECT 0x80000000; + +SELECT -0b10000000000000000000000000000000; +SELECT -0b10000000000000000000000000000001; +SELECT -0o20000000000; +SELECT -0o20000000001; +SELECT -0x80000000; +SELECT -0x80000001; + +-- cases near int8 overflow +SELECT 0b111111111111111111111111111111111111111111111111111111111111111; +SELECT 0b1000000000000000000000000000000000000000000000000000000000000000; +SELECT 0o777777777777777777777; +SELECT 0o1000000000000000000000; +SELECT 0x7FFFFFFFFFFFFFFF; +SELECT 0x8000000000000000; + +SELECT -0b1000000000000000000000000000000000000000000000000000000000000000; +SELECT -0b1000000000000000000000000000000000000000000000000000000000000001; +SELECT -0o1000000000000000000000; +SELECT -0o1000000000000000000001; +SELECT -0x8000000000000000; +SELECT -0x8000000000000001; + +-- error cases +SELECT 123abc; +SELECT 0x0o; +SELECT 0.a; +SELECT 0.0a; +SELECT .0a; +SELECT 0.0e1a; +SELECT 0.0e; +SELECT 0.0e+a; +PREPARE p1 AS SELECT $1a; + +SELECT 0b; +SELECT 1b; +SELECT 0b0x; + +SELECT 0o; +SELECT 1o; +SELECT 0o0x; + +SELECT 0x; +SELECT 1x; +SELECT 0x0y; + +-- underscores +SELECT 1_000_000; +SELECT 1_2_3; +SELECT 0x1EEE_FFFF; +SELECT 0o2_73; +SELECT 0b_10_0101; + +SELECT 1_000.000_005; +SELECT 1_000.; +SELECT .000_005; +SELECT 1_000.5e0_1; + +DO $$ +DECLARE + i int; +BEGIN + FOR i IN 1_001..1_003 LOOP + RAISE NOTICE 'i = %', i; + END LOOP; +END $$; + +-- error cases +SELECT _100; +SELECT 100_; +SELECT 100__000; + +SELECT _1_000.5; +SELECT 1_000_.5; +SELECT 1_000._5; +SELECT 1_000.5_; +SELECT 1_000.5e_1; + +PREPARE p1 AS SELECT $0_1; + +|-- +-- Test implicit type conversions +-- This fails for Postgres v6.1 (and earlier?) +-- so let's try explicit conversions for now - tgl 97/05/07 +|-- + +CREATE TABLE TEMP_FLOAT (f1 FLOAT8); + +INSERT INTO TEMP_FLOAT (f1) + SELECT float8(f1) FROM INT4_TBL; + +INSERT INTO TEMP_FLOAT (f1) + SELECT float8(f1) FROM INT2_TBL; + +SELECT f1 FROM TEMP_FLOAT + ORDER BY f1; + +-- int4 + +CREATE TABLE TEMP_INT4 (f1 INT4); + +INSERT INTO TEMP_INT4 (f1) + SELECT int4(f1) FROM FLOAT8_TBL + WHERE (f1 > -2147483647) AND (f1 < 2147483647); + +INSERT INTO TEMP_INT4 (f1) + SELECT int4(f1) FROM INT2_TBL; + +SELECT f1 FROM TEMP_INT4 + ORDER BY f1; + +-- int2 + +CREATE TABLE TEMP_INT2 (f1 INT2); + +INSERT INTO TEMP_INT2 (f1) + SELECT int2(f1) FROM FLOAT8_TBL + WHERE (f1 >= -32767) AND (f1 <= 32767); + +INSERT INTO TEMP_INT2 (f1) + SELECT int2(f1) FROM INT4_TBL + WHERE (f1 >= -32767) AND (f1 <= 32767); + +SELECT f1 FROM TEMP_INT2 + ORDER BY f1; + +|-- +-- Group-by combinations +|-- + +CREATE TABLE TEMP_GROUP (f1 INT4, f2 INT4, f3 FLOAT8); + +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; + +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; + +-- 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; + +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; + +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; + +DROP TABLE TEMP_INT2; + +DROP TABLE TEMP_INT4; + +DROP TABLE TEMP_FLOAT; + +DROP TABLE TEMP_GROUP; +-- +ERROR: trailing junk after numeric literal at or near "123abc" +CURSORPOS: 1124 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json b/parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json new file mode 100644 index 0000000..5c84308 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json @@ -0,0 +1,85 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/object_address.test b/parser/testdata/summary_truncate/postgres_regress/object_address.test new file mode 100644 index 0000000..1a96a25 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/object_address.test @@ -0,0 +1,741 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test for pg_get_object_address +|-- + +-- Clean up in case a prior regression run failed +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 002 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_addr_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_addr_user" +== 003 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 004 +-- truncate_limit: 100 +CREATE USER regress_addr_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_addr_user" +== 005 +-- truncate_limit: 100 +-- Test generic object addressing/identification functions +CREATE SCHEMA addr_nsp +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA addr_nsp" +== 006 +-- truncate_limit: 100 +SET search_path TO 'addr_nsp' +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO addr_nsp" +== 007 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER addr_fdw +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER addr_fdw" +== 008 +-- truncate_limit: 100 +CREATE SERVER addr_fserv FOREIGN DATA WRAPPER addr_fdw +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER addr_fserv FOREIGN DATA WRAPPER addr_fdw" +== 009 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY addr_ts_dict (template=simple) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY addr_ts_dict (template = simple)" +== 010 +-- truncate_limit: 100 +CREATE TEXT SEARCH CONFIGURATION addr_ts_conf (copy=english) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION addr_ts_conf (copy = english)" +== 011 +-- truncate_limit: 100 +CREATE TEXT SEARCH TEMPLATE addr_ts_temp (lexize=dsimple_lexize) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH TEMPLATE addr_ts_temp (lexize = dsimple_lexize)" +== 012 +-- truncate_limit: 100 +CREATE TEXT SEARCH PARSER addr_ts_prs + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH PARSER addr_ts_prs (start = prsd_start, gettoken = prsd_nexttoken, \"end\" = prs..." +== 013 +-- truncate_limit: 100 +CREATE TABLE addr_nsp.gentable ( + a serial primary key CONSTRAINT a_chk CHECK (a > 0), + b text DEFAULT 'hello' +) +-- +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE addr_nsp.gentable (a serial PRIMARY KEY CONSTRAINT a_chk CHECK (a > 0), b text DEFAU..." +== 014 +-- truncate_limit: 100 +CREATE TABLE addr_nsp.parttable ( + a int PRIMARY KEY +) PARTITION BY RANGE (a) +-- +TABLE: name="addr_nsp.parttable" schema="addr_nsp" table="parttable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE addr_nsp.parttable (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 015 +-- truncate_limit: 100 +CREATE VIEW addr_nsp.genview AS SELECT * from addr_nsp.gentable +-- +TABLE: name="addr_nsp.genview" schema="addr_nsp" table="genview" ctx=DDL +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW addr_nsp.genview AS SELECT * FROM addr_nsp.gentable" +== 016 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW addr_nsp.genmatview AS SELECT * FROM addr_nsp.gentable +-- +TABLE: name="addr_nsp.genmatview" schema="addr_nsp" table="genmatview" ctx=DDL +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW addr_nsp.genmatview AS SELECT * FROM addr_nsp.gentable" +== 017 +-- truncate_limit: 100 +CREATE TYPE addr_nsp.gencomptype AS (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE addr_nsp.gencomptype AS (a int)" +== 018 +-- truncate_limit: 100 +CREATE TYPE addr_nsp.genenum AS ENUM ('one', 'two') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE addr_nsp.genenum AS ENUM ('one', 'two')" +== 019 +-- truncate_limit: 100 +CREATE FOREIGN TABLE addr_nsp.genftable (a int) SERVER addr_fserv +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE addr_nsp.genftable (a int) SERVER addr_fserv" +== 020 +-- truncate_limit: 100 +CREATE AGGREGATE addr_nsp.genaggr(int4) (sfunc = int4pl, stype = int4) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE addr_nsp.genaggr (int4) (sfunc = int4pl, stype = int4)" +== 021 +-- truncate_limit: 100 +CREATE DOMAIN addr_nsp.gendomain AS int4 CONSTRAINT domconstr CHECK (value > 0) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN addr_nsp.gendomain AS int4 CONSTRAINT domconstr CHECK (value > 0)" +== 022 +-- truncate_limit: 100 +CREATE FUNCTION addr_nsp.trig() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN END; $$ +-- +FUNCTION: name="addr_nsp.trig" function="trig" schema="addr_nsp" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION addr_nsp.trig() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN END; $$" +== 023 +-- truncate_limit: 100 +CREATE TRIGGER t BEFORE INSERT ON addr_nsp.gentable FOR EACH ROW EXECUTE PROCEDURE addr_nsp.trig() +-- +TABLE: name="addr_nsp.gentable" schema="addr_nsp" table="gentable" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER t BEFORE INSERT ON addr_nsp.gentable FOR EACH ROW EXECUTE FUNCTION addr_nsp.trig()" +== 024 +-- truncate_limit: 100 +CREATE POLICY genpol ON addr_nsp.gentable +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY genpol ON addr_nsp.gentable TO public" +== 025 +-- truncate_limit: 100 +CREATE PROCEDURE addr_nsp.proc(int4) LANGUAGE SQL AS $$ $$ +-- +FUNCTION: name="addr_nsp.proc" function="proc" schema="addr_nsp" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE PROCEDURE addr_nsp.proc(int4) LANGUAGE sql AS $$ $$" +== 026 +-- truncate_limit: 100 +CREATE SERVER "integer" FOREIGN DATA WRAPPER addr_fdw +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER \"integer\" FOREIGN DATA WRAPPER addr_fdw" +== 027 +-- truncate_limit: 100 +CREATE USER MAPPING FOR regress_addr_user SERVER "integer" +-- +STMT: CreateUserMappingStmt +TRUNCATED: "CREATE USER MAPPING FOR regress_addr_user SERVER \"integer\"" +== 028 +-- truncate_limit: 100 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user IN SCHEMA public GRANT ALL ON TABLES TO regress_addr_user +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user IN SCHEMA public GRANT ALL ON TABLES TO regre..." +== 029 +-- truncate_limit: 100 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE DELETE ON TABLES FROM regress_addr_user +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE delete ON TABLES FROM regress_addr_user" +== 030 +-- truncate_limit: 100 +-- this transform would be quite unsafe to leave lying around, +-- except that the SQL language pays no attention to transforms: +CREATE TRANSFORM FOR int LANGUAGE SQL ( + FROM SQL WITH FUNCTION prsd_lextype(internal), + TO SQL WITH FUNCTION int4recv(internal)) +-- +STMT: CreateTransformStmt +TRUNCATED: "CREATE TRANSFORM FOR int LANGUAGE sql (FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH..." +== 031 +-- truncate_limit: 100 +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 032 +-- truncate_limit: 100 +CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable" +== 033 +-- truncate_limit: 100 +CREATE PUBLICATION addr_pub_schema FOR TABLES IN SCHEMA addr_nsp +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION addr_pub_schema FOR TABLES IN SCHEMA addr_nsp" +== 034 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 035 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_na..." +== 036 +-- truncate_limit: 100 +CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable" +== 037 +-- truncate_limit: 100 +-- test some error cases +SELECT pg_get_object_address('stone', '{}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('stone', '{}', '{}')" +== 038 +-- truncate_limit: 100 +SELECT pg_get_object_address('table', '{}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('table', '{}', '{}')" +== 039 +-- truncate_limit: 100 +SELECT pg_get_object_address('table', '{NULL}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('table', '{NULL}', '{}')" +== 040 +-- truncate_limit: 100 +-- unrecognized object types +DO $$ +DECLARE + objtype text; +BEGIN + FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'), + ('toast table column'), ('view column'), ('materialized view column') + LOOP + BEGIN + PERFORM pg_get_object_address(objtype, '{one}', '{}'); + EXCEPTION WHEN invalid_parameter_value THEN + RAISE WARNING 'error for %: %', objtype, sqlerrm; + END; + END LOOP; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n objtype text;\nBEGIN\n FOR objtype IN VALUES ('toast table'), ('index column')..." +== 041 +-- truncate_limit: 100 +-- miscellaneous other errors +select * from pg_get_object_address('operator of access method', '{btree,integer_ops,1}', '{int4,bool}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_get_object_address('operator of access method', '{btree,integer_ops,1}', '{int4,..." +== 042 +-- truncate_limit: 100 +select * from pg_get_object_address('operator of access method', '{btree,integer_ops,99}', '{int4,int4}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_get_object_address('operator of access method', '{btree,integer_ops,99}', '{int4..." +== 043 +-- truncate_limit: 100 +select * from pg_get_object_address('function of access method', '{btree,integer_ops,1}', '{int4,bool}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_get_object_address('function of access method', '{btree,integer_ops,1}', '{int4,..." +== 044 +-- truncate_limit: 100 +select * from pg_get_object_address('function of access method', '{btree,integer_ops,99}', '{int4,int4}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_get_object_address('function of access method', '{btree,integer_ops,99}', '{int4..." +== 045 +-- truncate_limit: 100 +DO $$ +DECLARE + objtype text; + names text[]; + args text[]; +BEGIN + FOR objtype IN VALUES + ('table'), ('index'), ('sequence'), ('view'), + ('materialized view'), ('foreign table'), + ('table column'), ('foreign table column'), + ('aggregate'), ('function'), ('procedure'), ('type'), ('cast'), + ('table constraint'), ('domain constraint'), ('conversion'), ('default value'), + ('operator'), ('operator class'), ('operator family'), ('rule'), ('trigger'), + ('text search parser'), ('text search dictionary'), + ('text search template'), ('text search configuration'), + ('policy'), ('user mapping'), ('default acl'), ('transform'), + ('operator of access method'), ('function of access method'), + ('publication namespace'), ('publication relation') + LOOP + FOR names IN VALUES ('{eins}'), ('{addr_nsp, zwei}'), ('{eins, zwei, drei}') + LOOP + FOR args IN VALUES ('{}'), ('{integer}') + LOOP + BEGIN + PERFORM pg_get_object_address(objtype, names, args); + EXCEPTION WHEN OTHERS THEN + RAISE WARNING 'error for %,%,%: %', objtype, names, args, sqlerrm; + END; + END LOOP; + END LOOP; + END LOOP; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n objtype text;\n names text[];\n args text[];\nBEGIN\n FOR objtype IN ..." +== 046 +-- truncate_limit: 100 +-- these object types cannot be qualified names +SELECT pg_get_object_address('language', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('language', '{one}', '{}')" +== 047 +-- truncate_limit: 100 +SELECT pg_get_object_address('language', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('language', '{one,two}', '{}')" +== 048 +-- truncate_limit: 100 +SELECT pg_get_object_address('large object', '{123}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('large object', '{123}', '{}')" +== 049 +-- truncate_limit: 100 +SELECT pg_get_object_address('large object', '{123,456}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('large object', '{123,456}', '{}')" +== 050 +-- truncate_limit: 100 +SELECT pg_get_object_address('large object', '{blargh}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('large object', '{blargh}', '{}')" +== 051 +-- truncate_limit: 100 +SELECT pg_get_object_address('schema', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('schema', '{one}', '{}')" +== 052 +-- truncate_limit: 100 +SELECT pg_get_object_address('schema', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('schema', '{one,two}', '{}')" +== 053 +-- truncate_limit: 100 +SELECT pg_get_object_address('role', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('role', '{one}', '{}')" +== 054 +-- truncate_limit: 100 +SELECT pg_get_object_address('role', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('role', '{one,two}', '{}')" +== 055 +-- truncate_limit: 100 +SELECT pg_get_object_address('database', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('database', '{one}', '{}')" +== 056 +-- truncate_limit: 100 +SELECT pg_get_object_address('database', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('database', '{one,two}', '{}')" +== 057 +-- truncate_limit: 100 +SELECT pg_get_object_address('tablespace', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('tablespace', '{one}', '{}')" +== 058 +-- truncate_limit: 100 +SELECT pg_get_object_address('tablespace', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('tablespace', '{one,two}', '{}')" +== 059 +-- truncate_limit: 100 +SELECT pg_get_object_address('foreign-data wrapper', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('foreign-data wrapper', '{one}', '{}')" +== 060 +-- truncate_limit: 100 +SELECT pg_get_object_address('foreign-data wrapper', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('foreign-data wrapper', '{one,two}', '{}')" +== 061 +-- truncate_limit: 100 +SELECT pg_get_object_address('server', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('server', '{one}', '{}')" +== 062 +-- truncate_limit: 100 +SELECT pg_get_object_address('server', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('server', '{one,two}', '{}')" +== 063 +-- truncate_limit: 100 +SELECT pg_get_object_address('extension', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('extension', '{one}', '{}')" +== 064 +-- truncate_limit: 100 +SELECT pg_get_object_address('extension', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('extension', '{one,two}', '{}')" +== 065 +-- truncate_limit: 100 +SELECT pg_get_object_address('event trigger', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('event trigger', '{one}', '{}')" +== 066 +-- truncate_limit: 100 +SELECT pg_get_object_address('event trigger', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('event trigger', '{one,two}', '{}')" +== 067 +-- truncate_limit: 100 +SELECT pg_get_object_address('access method', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('access method', '{one}', '{}')" +== 068 +-- truncate_limit: 100 +SELECT pg_get_object_address('access method', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('access method', '{one,two}', '{}')" +== 069 +-- truncate_limit: 100 +SELECT pg_get_object_address('publication', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('publication', '{one}', '{}')" +== 070 +-- truncate_limit: 100 +SELECT pg_get_object_address('publication', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('publication', '{one,two}', '{}')" +== 071 +-- truncate_limit: 100 +SELECT pg_get_object_address('subscription', '{one}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('subscription', '{one}', '{}')" +== 072 +-- truncate_limit: 100 +SELECT pg_get_object_address('subscription', '{one,two}', '{}') +-- +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_object_address('subscription', '{one,two}', '{}')" +== 073 +-- truncate_limit: 100 +-- Make sure that NULL handling is correct. + +-- Temporarily disable fancy output, so as future additions never create +-- a large amount of diffs. + +-- test successful cases +WITH objects (type, name, args) AS (VALUES + ('table', '{addr_nsp, gentable}'::text[], '{}'::text[]), + ('table', '{addr_nsp, parttable}'::text[], '{}'::text[]), + ('index', '{addr_nsp, gentable_pkey}', '{}'), + ('index', '{addr_nsp, parttable_pkey}', '{}'), + ('sequence', '{addr_nsp, gentable_a_seq}', '{}'), + -- toast table + ('view', '{addr_nsp, genview}', '{}'), + ('materialized view', '{addr_nsp, genmatview}', '{}'), + ('foreign table', '{addr_nsp, genftable}', '{}'), + ('table column', '{addr_nsp, gentable, b}', '{}'), + ('foreign table column', '{addr_nsp, genftable, a}', '{}'), + ('aggregate', '{addr_nsp, genaggr}', '{int4}'), + ('function', '{pg_catalog, pg_identify_object}', '{pg_catalog.oid, pg_catalog.oid, int4}'), + ('procedure', '{addr_nsp, proc}', '{int4}'), + ('type', '{pg_catalog._int4}', '{}'), + ('type', '{addr_nsp.gendomain}', '{}'), + ('type', '{addr_nsp.gencomptype}', '{}'), + ('type', '{addr_nsp.genenum}', '{}'), + ('cast', '{int8}', '{int4}'), + ('collation', '{default}', '{}'), + ('table constraint', '{addr_nsp, gentable, a_chk}', '{}'), + ('domain constraint', '{addr_nsp.gendomain}', '{domconstr}'), + ('conversion', '{pg_catalog, koi8_r_to_mic}', '{}'), + ('default value', '{addr_nsp, gentable, b}', '{}'), + ('language', '{plpgsql}', '{}'), + -- large object + ('operator', '{+}', '{int4, int4}'), + ('operator class', '{btree, int4_ops}', '{}'), + ('operator family', '{btree, integer_ops}', '{}'), + ('operator of access method', '{btree,integer_ops,1}', '{integer,integer}'), + ('function of access method', '{btree,integer_ops,2}', '{integer,integer}'), + ('rule', '{addr_nsp, genview, _RETURN}', '{}'), + ('trigger', '{addr_nsp, gentable, t}', '{}'), + ('schema', '{addr_nsp}', '{}'), + ('text search parser', '{addr_ts_prs}', '{}'), + ('text search dictionary', '{addr_ts_dict}', '{}'), + ('text search template', '{addr_ts_temp}', '{}'), + ('text search configuration', '{addr_ts_conf}', '{}'), + ('role', '{regress_addr_user}', '{}'), + -- database + -- tablespace + ('foreign-data wrapper', '{addr_fdw}', '{}'), + ('server', '{addr_fserv}', '{}'), + ('user mapping', '{regress_addr_user}', '{integer}'), + ('default acl', '{regress_addr_user,public}', '{r}'), + ('default acl', '{regress_addr_user}', '{r}'), + -- extension + -- event trigger + ('policy', '{addr_nsp, gentable, genpol}', '{}'), + ('transform', '{int}', '{sql}'), + ('access method', '{btree}', '{}'), + ('publication', '{addr_pub}', '{}'), + ('publication namespace', '{addr_nsp}', '{addr_pub_schema}'), + ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), + ('subscription', '{regress_addr_sub}', '{}'), + ('statistics object', '{addr_nsp, gentable_stat}', '{}') + ) +SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, + -- test roundtrip through pg_identify_object_as_address + ROW(pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)) = + ROW(pg_identify_object(addr2.classid, addr2.objid, addr2.objsubid)) AS roundtrip +FROM objects, + pg_get_object_address(type, name, args) AS addr1, + pg_identify_object_as_address(classid, objid, objsubid) AS ioa (typ, nms, args), + pg_get_object_address(typ, nms, ioa.args) AS addr2 +ORDER BY addr1.classid, addr1.objid, addr1.objsubid +-- +CTE: "objects" +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +FUNCTION: name="pg_identify_object_as_address" function="pg_identify_object_as_address" schema="" ctx=Call +FUNCTION: name="pg_get_object_address" function="pg_get_object_address" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH objects(type, name, args) AS (...) SELECT ... FROM objects, pg_get_object_address(type, name..." +== 074 +-- truncate_limit: 100 +--- +--- Cleanup resources +--- +DROP FOREIGN DATA WRAPPER addr_fdw CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER addr_fdw CASCADE" +== 075 +-- truncate_limit: 100 +DROP PUBLICATION addr_pub +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION addr_pub" +== 076 +-- truncate_limit: 100 +DROP PUBLICATION addr_pub_schema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION addr_pub_schema" +== 077 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_addr_sub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_addr_sub" +== 078 +-- truncate_limit: 100 +DROP SCHEMA addr_nsp CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA addr_nsp CASCADE" +== 079 +-- truncate_limit: 100 +DROP OWNED BY regress_addr_user +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_addr_user" +== 080 +-- truncate_limit: 100 +DROP USER regress_addr_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_addr_user" +== 081 +-- truncate_limit: 100 +|-- +-- Checks for invalid objects +|-- + +-- Keep this list in the same order as getObjectIdentityParts() +-- in objectaddress.c. +WITH objects (classid, objid, objsubid) AS (VALUES + ('pg_class'::regclass, 0, 0), -- no relation + ('pg_class'::regclass, 'pg_class'::regclass, 100), -- no column for relation + ('pg_proc'::regclass, 0, 0), -- no function + ('pg_type'::regclass, 0, 0), -- no type + ('pg_cast'::regclass, 0, 0), -- no cast + ('pg_collation'::regclass, 0, 0), -- no collation + ('pg_constraint'::regclass, 0, 0), -- no constraint + ('pg_conversion'::regclass, 0, 0), -- no conversion + ('pg_attrdef'::regclass, 0, 0), -- no default attribute + ('pg_language'::regclass, 0, 0), -- no language + ('pg_largeobject'::regclass, 0, 0), -- no large object, no error + ('pg_operator'::regclass, 0, 0), -- no operator + ('pg_opclass'::regclass, 0, 0), -- no opclass, no need to check for no access method + ('pg_opfamily'::regclass, 0, 0), -- no opfamily + ('pg_am'::regclass, 0, 0), -- no access method + ('pg_amop'::regclass, 0, 0), -- no AM operator + ('pg_amproc'::regclass, 0, 0), -- no AM proc + ('pg_rewrite'::regclass, 0, 0), -- no rewrite + ('pg_trigger'::regclass, 0, 0), -- no trigger + ('pg_namespace'::regclass, 0, 0), -- no schema + ('pg_statistic_ext'::regclass, 0, 0), -- no statistics + ('pg_ts_parser'::regclass, 0, 0), -- no TS parser + ('pg_ts_dict'::regclass, 0, 0), -- no TS dictionary + ('pg_ts_template'::regclass, 0, 0), -- no TS template + ('pg_ts_config'::regclass, 0, 0), -- no TS configuration + ('pg_authid'::regclass, 0, 0), -- no role + ('pg_auth_members'::regclass, 0, 0), -- no role membership + ('pg_database'::regclass, 0, 0), -- no database + ('pg_tablespace'::regclass, 0, 0), -- no tablespace + ('pg_foreign_data_wrapper'::regclass, 0, 0), -- no FDW + ('pg_foreign_server'::regclass, 0, 0), -- no server + ('pg_user_mapping'::regclass, 0, 0), -- no user mapping + ('pg_default_acl'::regclass, 0, 0), -- no default ACL + ('pg_extension'::regclass, 0, 0), -- no extension + ('pg_event_trigger'::regclass, 0, 0), -- no event trigger + ('pg_parameter_acl'::regclass, 0, 0), -- no parameter ACL + ('pg_policy'::regclass, 0, 0), -- no policy + ('pg_publication'::regclass, 0, 0), -- no publication + ('pg_publication_namespace'::regclass, 0, 0), -- no publication namespace + ('pg_publication_rel'::regclass, 0, 0), -- no publication relation + ('pg_subscription'::regclass, 0, 0), -- no subscription + ('pg_transform'::regclass, 0, 0) -- no transformation + ) +SELECT ROW(pg_identify_object(objects.classid, objects.objid, objects.objsubid)) + AS ident, + ROW(pg_identify_object_as_address(objects.classid, objects.objid, objects.objsubid)) + AS addr, + pg_describe_object(objects.classid, objects.objid, objects.objsubid) + AS descr +FROM objects +ORDER BY objects.classid, objects.objid, objects.objsubid +-- +CTE: "objects" +FUNCTION: name="pg_identify_object" function="pg_identify_object" schema="" ctx=Call +FUNCTION: name="pg_identify_object_as_address" function="pg_identify_object_as_address" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH objects(classid, objid, objsubid) AS (...) SELECT ... FROM objects ORDER BY objects.classid,..." diff --git a/parser/testdata/summary_truncate/postgres_regress/oid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/oid.metadata.json new file mode 100644 index 0000000..6a83420 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/oid.metadata.json @@ -0,0 +1,41 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/oid.test b/parser/testdata/summary_truncate/postgres_regress/oid.test new file mode 100644 index 0000000..be0324e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/oid.test @@ -0,0 +1,297 @@ +== 001 +-- truncate_limit: 100 +|-- +-- OID +|-- + +CREATE TABLE OID_TBL(f1 oid) +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE oid_tbl (f1 oid)" +== 002 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('1234') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('1234')" +== 003 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('1235') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('1235')" +== 004 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('987') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('987')" +== 005 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('-1040') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('-1040')" +== 006 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('99999999') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('99999999')" +== 007 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('5 ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('5 ')" +== 008 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES (' 10 ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES (' 10 ')" +== 009 +-- truncate_limit: 100 +-- leading/trailing hard tab is also allowed +INSERT INTO OID_TBL(f1) VALUES (' 15 ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('\t 15 \t ')" +== 010 +-- truncate_limit: 100 +-- bad inputs +INSERT INTO OID_TBL(f1) VALUES ('') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('')" +== 011 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES (' ') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES (' ')" +== 012 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('asdfasd') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('asdfasd')" +== 013 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('99asdfasd') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('99asdfasd')" +== 014 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('5 d') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('5 d')" +== 015 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES (' 5d') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES (' 5d')" +== 016 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('5 5') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('5 5')" +== 017 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES (' - 500') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES (' - 500')" +== 018 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('32958209582039852935') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('32958209582039852935')" +== 019 +-- truncate_limit: 100 +INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385') +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO oid_tbl (f1) VALUES ('-23582358720398502385')" +== 020 +-- truncate_limit: 100 +SELECT * FROM OID_TBL +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM oid_tbl" +== 021 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('1234', 'oid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1234', 'oid')" +== 022 +-- truncate_limit: 100 +SELECT pg_input_is_valid('01XYZ', 'oid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('01XYZ', 'oid')" +== 023 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('01XYZ', 'oid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('01XYZ', 'oid')" +== 024 +-- truncate_limit: 100 +SELECT pg_input_is_valid('9999999999', 'oid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('9999999999', 'oid')" +== 025 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('9999999999', 'oid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('9999999999', 'oid')" +== 026 +-- truncate_limit: 100 +-- While we're here, check oidvector as well +SELECT pg_input_is_valid(' 1 2 4 ', 'oidvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid(' 1 2 4 ', 'oidvector')" +== 027 +-- truncate_limit: 100 +SELECT pg_input_is_valid('01 01XYZ', 'oidvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('01 01XYZ', 'oidvector')" +== 028 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('01 01XYZ', 'oidvector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('01 01XYZ', 'oidvector')" +== 029 +-- truncate_limit: 100 +SELECT pg_input_is_valid('01 9999999999', 'oidvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('01 9999999999', 'oidvector')" +== 030 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('01 9999999999', 'oidvector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('01 9999999999', 'oidvector')" +== 031 +-- truncate_limit: 100 +SELECT o.* FROM OID_TBL o WHERE o.f1 = 1234 +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT o.* FROM oid_tbl o WHERE o.f1 = 1234" +== 032 +-- truncate_limit: 100 +SELECT o.* FROM OID_TBL o WHERE o.f1 <> '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT o.* FROM oid_tbl o WHERE o.f1 <> '1234'" +== 033 +-- truncate_limit: 100 +SELECT o.* FROM OID_TBL o WHERE o.f1 <= '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT o.* FROM oid_tbl o WHERE o.f1 <= '1234'" +== 034 +-- truncate_limit: 100 +SELECT o.* FROM OID_TBL o WHERE o.f1 < '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT o.* FROM oid_tbl o WHERE o.f1 < '1234'" +== 035 +-- truncate_limit: 100 +SELECT o.* FROM OID_TBL o WHERE o.f1 >= '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT o.* FROM oid_tbl o WHERE o.f1 >= '1234'" +== 036 +-- truncate_limit: 100 +SELECT o.* FROM OID_TBL o WHERE o.f1 > '1234' +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=Select +ALIAS: "o"="oid_tbl" +FILTER: schema="" table="o" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT o.* FROM oid_tbl o WHERE o.f1 > '1234'" +== 037 +-- truncate_limit: 100 +DROP TABLE OID_TBL +-- +TABLE: name="oid_tbl" schema="" table="oid_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE oid_tbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json b/parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/oidjoins.test b/parser/testdata/summary_truncate/postgres_regress/oidjoins.test new file mode 100644 index 0000000..e8bba2a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/oidjoins.test @@ -0,0 +1,54 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Verify system catalog foreign key relationships +|-- +DO $doblock$ +declare + fk record; + nkeys integer; + cmd text; + err record; +begin + for fk in select * from pg_get_catalog_foreign_keys() + loop + raise notice 'checking % % => % %', + fk.fktable, fk.fkcols, fk.pktable, fk.pkcols; + nkeys := array_length(fk.fkcols, 1); + cmd := 'SELECT ctid'; + for i in 1 .. nkeys loop + cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); + end loop; + if fk.is_array then + cmd := cmd || ' FROM (SELECT ctid'; + for i in 1 .. nkeys-1 loop + cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); + end loop; + cmd := cmd || ', unnest(' || quote_ident(fk.fkcols[nkeys]); + cmd := cmd || ') as ' || quote_ident(fk.fkcols[nkeys]); + cmd := cmd || ' FROM ' || fk.fktable::text || ') fk WHERE '; + else + cmd := cmd || ' FROM ' || fk.fktable::text || ' fk WHERE '; + end if; + if fk.is_opt then + for i in 1 .. nkeys loop + cmd := cmd || quote_ident(fk.fkcols[i]) || ' != 0 AND '; + end loop; + end if; + cmd := cmd || 'NOT EXISTS(SELECT 1 FROM ' || fk.pktable::text || ' pk WHERE '; + for i in 1 .. nkeys loop + if i > 1 then cmd := cmd || ' AND '; end if; + cmd := cmd || 'pk.' || quote_ident(fk.pkcols[i]); + cmd := cmd || ' = fk.' || quote_ident(fk.fkcols[i]); + end loop; + cmd := cmd || ')'; + -- raise notice 'cmd = %', cmd; + for err in execute cmd loop + raise warning 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err; + end loop; + end loop; +end +$doblock$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare\n fk record;\n nkeys integer;\n cmd text;\n err record;\nbegin\n for fk in select * ..." diff --git a/parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json new file mode 100644 index 0000000..304478c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json @@ -0,0 +1,134 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/opr_sanity.test b/parser/testdata/summary_truncate/postgres_regress/opr_sanity.test new file mode 100644 index 0000000..e3c6866 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/opr_sanity.test @@ -0,0 +1,3449 @@ +== 001 +-- truncate_limit: 100 +|-- +-- OPR_SANITY +-- Sanity checks for common errors in making operator/procedure system tables: +-- pg_operator, pg_proc, pg_cast, pg_conversion, pg_aggregate, pg_am, +-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index. +|-- +-- Every test failure in this file should be closely inspected. +-- The description of the failing test should be read carefully before +-- adjusting the expected output. In most cases, the queries should +-- not find *any* matching entries. +|-- +-- NB: we assume the oidjoins test will have caught any dangling links, +-- that is OID or REGPROC fields that are not zero and do not match some +-- row in the linked-to table. However, if we want to enforce that a link +-- field can't be 0, we have to check it here. +|-- +-- NB: run this test earlier than the create_operator test, because +-- that test creates some bogus operators... + + +-- **************** pg_proc **************** + +-- Look for illegal values in pg_proc fields. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prolang = 0 OR p1.prorettype = 0 OR + p1.pronargs < 0 OR + p1.pronargdefaults < 0 OR + p1.pronargdefaults > p1.pronargs OR + array_lower(p1.proargtypes, 1) != 0 OR + array_upper(p1.proargtypes, 1) != p1.pronargs-1 OR + 0::oid = ANY (p1.proargtypes) OR + procost <= 0 OR + CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END OR + prokind NOT IN ('f', 'a', 'w', 'p') OR + provolatile NOT IN ('i', 's', 'v') OR + proparallel NOT IN ('s', 'r', 'u') +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="pronargdefaults" +FILTER: schema="" table="p1" column="pronargdefaults" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="" column="procost" +FILTER: schema="" table="" column="proretset" +FILTER: schema="" table="" column="prorows" +FILTER: schema="" table="" column="prorows" +FILTER: schema="" table="" column="prokind" +FILTER: schema="" table="" column="provolatile" +FILTER: schema="" table="" column="proparallel" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 002 +-- truncate_limit: 100 +-- prosrc should never be null; it can be empty only if prosqlbody isn't null +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prosrc IS NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prosrc" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE prosrc IS NULL" +== 003 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE (prosrc = '' OR prosrc = '-') AND prosqlbody IS NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prosrc" +FILTER: schema="" table="" column="prosrc" +FILTER: schema="" table="" column="prosqlbody" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE (prosrc = '' OR prosrc = '-') AND prosqlbody IS NULL" +== 004 +-- truncate_limit: 100 +-- proretset should only be set for normal functions +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE proretset AND prokind != 'f' +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="proretset" +FILTER: schema="" table="" column="prokind" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE proretset AND prokind <> 'f'" +== 005 +-- truncate_limit: 100 +-- currently, no built-in functions should be SECURITY DEFINER; +-- this might change in future, but there will probably never be many. +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE prosecdef +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prosecdef" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE prosecdef ORDER BY 1" +== 006 +-- truncate_limit: 100 +-- pronargdefaults should be 0 iff proargdefaults is null +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE (pronargdefaults <> 0) != (proargdefaults IS NOT NULL) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="pronargdefaults" +FILTER: schema="" table="" column="proargdefaults" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 007 +-- truncate_limit: 100 +-- probin should be non-empty for C functions, null everywhere else +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prolang = 13 AND (probin IS NULL OR probin = '' OR probin = '-') +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prolang" +FILTER: schema="" table="" column="probin" +FILTER: schema="" table="" column="probin" +FILTER: schema="" table="" column="probin" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 008 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prolang != 13 AND probin IS NOT NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="prolang" +FILTER: schema="" table="" column="probin" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE prolang <> 13 AND probin IS NOT NULL" +== 009 +-- truncate_limit: 100 +-- Look for conflicting proc definitions (same names and input datatypes). +-- (This test should be dead code now that we have the unique index +-- pg_proc_proname_args_nsp_index, but I'll leave it in anyway.) + +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.proname = p2.proname AND + p1.pronargs = p2.pronargs AND + p1.proargtypes = p2.proargtypes +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="proname" +FILTER: schema="" table="p2" column="proname" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname, p2.oid, p2.proname FROM pg_proc p1, pg_proc p2 WHERE ..." +== 010 +-- truncate_limit: 100 +-- Considering only built-in procs (prolang = 12), look for multiple uses +-- of the same internal function (ie, matching prosrc fields). It's OK to +-- have several entries with different pronames for the same internal function, +-- but conflicts in the number of arguments and other critical items should +-- be complained of. (We don't check data types here; see next query.) +-- Note: ignore aggregate functions here, since they all point to the same +-- dummy built-in function. + +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid < p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + (p1.prokind != 'a' OR p2.prokind != 'a') AND + (p1.prolang != p2.prolang OR + p1.prokind != p2.prokind OR + p1.prosecdef != p2.prosecdef OR + p1.proleakproof != p2.proleakproof OR + p1.proisstrict != p2.proisstrict OR + p1.proretset != p2.proretset OR + p1.provolatile != p2.provolatile OR + p1.pronargs != p2.pronargs) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosecdef" +FILTER: schema="" table="p2" column="prosecdef" +FILTER: schema="" table="p1" column="proleakproof" +FILTER: schema="" table="p2" column="proleakproof" +FILTER: schema="" table="p1" column="proisstrict" +FILTER: schema="" table="p2" column="proisstrict" +FILTER: schema="" table="p1" column="proretset" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p1" column="provolatile" +FILTER: schema="" table="p2" column="provolatile" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p2" column="pronargs" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname, p2.oid, p2.proname FROM pg_proc p1, pg_proc p2 WHERE ..." +== 011 +-- truncate_limit: 100 +-- Look for uses of different type OIDs in the argument/result type fields +-- for different aliases of the same built-in function. +-- This indicates that the types are being presumed to be binary-equivalent, +-- or that the built-in function is prepared to deal with different types. +-- That's not wrong, necessarily, but we make lists of all the types being +-- so treated. Note that the expected output of this part of the test will +-- need to be modified whenever new pairs of types are made binary-equivalent, +-- or when new polymorphic built-in functions are added! +-- Note: ignore aggregate functions here, since they all point to the same +-- dummy built-in function. Likewise, ignore range and multirange constructor +-- functions. + +SELECT DISTINCT p1.prorettype::regtype, p2.prorettype::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.prorettype < p2.prorettype) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p2" column="prorettype" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 012 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[0]::regtype, p2.proargtypes[0]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.proargtypes[0] < p2.proargtypes[0]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 013 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[1]::regtype, p2.proargtypes[1]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.proargtypes[1] < p2.proargtypes[1]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 014 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[2]::regtype, p2.proargtypes[2]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[2] < p2.proargtypes[2]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 015 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[3]::regtype, p2.proargtypes[3]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[3] < p2.proargtypes[3]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 016 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[4]::regtype, p2.proargtypes[4]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[4] < p2.proargtypes[4]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 017 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[5]::regtype, p2.proargtypes[5]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[5] < p2.proargtypes[5]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 018 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[6]::regtype, p2.proargtypes[6]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[6] < p2.proargtypes[6]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 019 +-- truncate_limit: 100 +SELECT DISTINCT p1.proargtypes[7]::regtype, p2.proargtypes[7]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[7] < p2.proargtypes[7]) +ORDER BY 1, 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosrc" +FILTER: schema="" table="p2" column="prosrc" +FILTER: schema="" table="p1" column="prolang" +FILTER: schema="" table="p2" column="prolang" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1, 2" +== 020 +-- truncate_limit: 100 +-- Look for functions that return type "internal" and do not have any +-- "internal" argument. Such a function would be a security hole since +-- it might be used to call an internal function from an SQL command. +-- As of 7.3 this query should find only internal_in, which is safe because +-- it always throws an error when called. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'internal'::regtype AND NOT + 'internal'::regtype = ANY (p1.proargtypes) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 021 +-- truncate_limit: 100 +-- Look for functions that return a polymorphic type and do not have any +-- polymorphic argument. Calls of such functions would be unresolvable +-- at parse time. As of 9.6 this query should find only some input functions +-- and GiST support functions associated with these pseudotypes. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN + ('anyelement'::regtype, 'anyarray'::regtype, 'anynonarray'::regtype, + 'anyenum'::regtype) + AND NOT + ('anyelement'::regtype = ANY (p1.proargtypes) OR + 'anyarray'::regtype = ANY (p1.proargtypes) OR + 'anynonarray'::regtype = ANY (p1.proargtypes) OR + 'anyenum'::regtype = ANY (p1.proargtypes) OR + 'anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ... ORDER BY 2" +== 022 +-- truncate_limit: 100 +-- anyrange and anymultirange are tighter than the rest, can only resolve +-- from each other + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN ('anyrange'::regtype, 'anymultirange'::regtype) + AND NOT + ('anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ... ORDER BY 2" +== 023 +-- truncate_limit: 100 +-- similarly for the anycompatible family + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN + ('anycompatible'::regtype, 'anycompatiblearray'::regtype, + 'anycompatiblenonarray'::regtype) + AND NOT + ('anycompatible'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblearray'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblenonarray'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblerange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ... ORDER BY 2" +== 024 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'anycompatiblerange'::regtype + AND NOT + 'anycompatiblerange'::regtype = ANY (p1.proargtypes) +ORDER BY 2 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ... ORDER BY 2" +== 025 +-- truncate_limit: 100 +-- Look for functions that accept cstring and are neither datatype input +-- functions nor encoding conversion functions. It's almost never a good +-- idea to use cstring input for a function meant to be called from SQL; +-- text should be used instead, because cstring lacks suitable casts. +-- As of 9.6 this query should find only cstring_out and cstring_send. +-- However, we must manually exclude shell_in, which might or might not be +-- rejected by the EXISTS clause depending on whether there are currently +-- any shell types. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE 'cstring'::regtype = ANY (p1.proargtypes) + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid) + AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid) + AND p1.oid != 'shell_in(cstring)'::regprocedure +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="" column="conproc" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ... ORDER BY 1" +== 026 +-- truncate_limit: 100 +-- Likewise, look for functions that return cstring and aren't datatype output +-- functions nor typmod output functions. +-- As of 9.6 this query should find only cstring_in and cstring_recv. +-- However, we must manually exclude shell_out. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'cstring'::regtype + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid) + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid) + AND p1.oid != 'shell_out(void)'::regprocedure +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="" column="typmodout" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ... ORDER BY 1" +== 027 +-- truncate_limit: 100 +-- Check for length inconsistencies between the various argument-info arrays. + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND + array_length(proallargtypes,1) < array_length(proargtypes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 028 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargmodes IS NOT NULL AND + array_length(proargmodes,1) < array_length(proargtypes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 029 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargnames IS NOT NULL AND + array_length(proargnames,1) < array_length(proargtypes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 030 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND proargmodes IS NOT NULL AND + array_length(proallargtypes,1) <> array_length(proargmodes,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargmodes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 031 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND proargnames IS NOT NULL AND + array_length(proallargtypes,1) <> array_length(proargnames,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargnames" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 032 +-- truncate_limit: 100 +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargmodes IS NOT NULL AND proargnames IS NOT NULL AND + array_length(proargmodes,1) <> array_length(proargnames,1) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargnames" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargnames" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE ..." +== 033 +-- truncate_limit: 100 +-- Check that proallargtypes matches proargtypes +SELECT p1.oid, p1.proname, p1.proargtypes, p1.proallargtypes, p1.proargmodes +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND + ARRAY(SELECT unnest(proargtypes)) <> + ARRAY(SELECT proallargtypes[i] + FROM generate_series(1, array_length(proallargtypes, 1)) g(i) + WHERE proargmodes IS NULL OR proargmodes[i] IN ('i', 'b', 'v')) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="proallargtypes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_proc p1 WHERE ..." +== 034 +-- truncate_limit: 100 +-- Check for type of the variadic array parameter's elements. +-- provariadic should be ANYOID if the type of the last element is ANYOID, +-- ANYELEMENTOID if the type of the last element is ANYARRAYOID, +-- ANYCOMPATIBLEOID if the type of the last element is ANYCOMPATIBLEARRAYOID, +-- and otherwise the element type corresponding to the array type. + +SELECT oid::regprocedure, provariadic::regtype, proargtypes::regtype[] +FROM pg_proc +WHERE provariadic != 0 +AND case proargtypes[array_length(proargtypes, 1)-1] + WHEN '"any"'::regtype THEN '"any"'::regtype + WHEN 'anyarray'::regtype THEN 'anyelement'::regtype + WHEN 'anycompatiblearray'::regtype THEN 'anycompatible'::regtype + ELSE (SELECT t.oid + FROM pg_type t + WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1]) + END != provariadic +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t"="pg_type" +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FUNCTION: name="array_length" function="array_length" schema="" ctx=Call +FILTER: schema="" table="" column="provariadic" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="t" column="typarray" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT oid::regprocedure, provariadic::regtype, proargtypes::regtype[] FROM pg_proc WHERE ..." +== 035 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="proargmodes" +FILTER: schema="" table="" column="provariadic" +STMT: SelectStmt +TRUNCATED: "SELECT oid::regprocedure, proargmodes, provariadic FROM pg_proc WHERE ..." +== 036 +-- truncate_limit: 100 +-- Check for prosupport functions with the wrong signature +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p2.oid = p1.prosupport AND + (p2.prorettype != 'internal'::regtype OR p2.proretset OR p2.pronargs != 1 + OR p2.proargtypes[0] != 'internal'::regtype) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="prosupport" +FILTER: schema="" table="p2" column="prorettype" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname, p2.oid, p2.proname FROM pg_proc p1, pg_proc p2 WHERE ..." +== 037 +-- truncate_limit: 100 +-- Insist that all built-in pg_proc entries have descriptions +SELECT p1.oid, p1.proname +FROM pg_proc as p1 LEFT JOIN pg_description as d + ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0 +WHERE d.classoid IS NULL AND p1.oid <= 9999 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "d"="pg_description" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="d" column="classoid" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_proc p1 LEFT JOIN pg_description d ON p1.tableoid = d.classoid AND p1.oid = d...." +== 038 +-- truncate_limit: 100 +-- List of built-in leakproof functions +|-- +-- Leakproof functions should only be added after carefully +-- scrutinizing all possibly executed codepaths for possible +-- information leaks. Don't add functions here unless you know what a +-- leakproof function is. If unsure, don't mark it as such. + +-- temporarily disable fancy output, so catalog changes create less diff noise + +SELECT p1.oid::regprocedure +FROM pg_proc p1 JOIN pg_namespace pn + ON pronamespace = pn.oid +WHERE nspname = 'pg_catalog' AND proleakproof +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "pn"="pg_namespace" +FILTER: schema="" table="" column="nspname" +FILTER: schema="" table="" column="proleakproof" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_proc p1 JOIN pg_namespace pn ON pronamespace = pn.oid WHERE ... ORDER BY 1" +== 039 +-- truncate_limit: 100 +-- restore normal output mode + +-- List of functions used by libpq's fe-lobj.c +|-- +-- If the output of this query changes, you probably broke libpq. +-- lo_initialize() assumes that there will be at most one match for +-- each listed name. +select proname, oid from pg_catalog.pg_proc +where proname in ( + 'lo_open', + 'lo_close', + 'lo_creat', + 'lo_create', + 'lo_unlink', + 'lo_lseek', + 'lo_lseek64', + 'lo_tell', + 'lo_tell64', + 'lo_truncate', + 'lo_truncate64', + 'loread', + 'lowrite') +and pronamespace = (select oid from pg_catalog.pg_namespace + where nspname = 'pg_catalog') +order by 1 +-- +TABLE: name="pg_catalog.pg_proc" schema="pg_catalog" table="pg_proc" ctx=Select +TABLE: name="pg_catalog.pg_namespace" schema="pg_catalog" table="pg_namespace" ctx=Select +FILTER: schema="" table="" column="proname" +FILTER: schema="" table="" column="pronamespace" +FILTER: schema="" table="" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT proname, oid FROM pg_catalog.pg_proc WHERE ... ORDER BY 1" +== 040 +-- truncate_limit: 100 +-- Check that all immutable functions are marked parallel safe +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE provolatile = 'i' AND proparallel = 'u' +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="" column="provolatile" +FILTER: schema="" table="" column="proparallel" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid, p1.proname FROM pg_proc p1 WHERE provolatile = 'i' AND proparallel = 'u'" +== 041 +-- truncate_limit: 100 +-- **************** pg_cast **************** + +-- Catch bogus values in pg_cast columns (other than cases detected by +-- oidjoins test). + +SELECT * +FROM pg_cast c +WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i') + OR castmethod NOT IN ('f', 'b' ,'i') +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +FILTER: schema="" table="" column="castcontext" +FILTER: schema="" table="" column="castmethod" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_cast c WHERE ..." +== 042 +-- truncate_limit: 100 +-- Check that castfunc is nonzero only for cast methods that need a function, +-- and zero otherwise + +SELECT * +FROM pg_cast c +WHERE (castmethod = 'f' AND castfunc = 0) + OR (castmethod IN ('b', 'i') AND castfunc <> 0) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +FILTER: schema="" table="" column="castmethod" +FILTER: schema="" table="" column="castfunc" +FILTER: schema="" table="" column="castmethod" +FILTER: schema="" table="" column="castfunc" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_cast c WHERE ..." +== 043 +-- truncate_limit: 100 +-- Look for casts to/from the same type that aren't length coercion functions. +-- (We assume they are length coercions if they take multiple arguments.) +-- Such entries are not necessarily harmful, but they are useless. + +SELECT * +FROM pg_cast c +WHERE castsource = casttarget AND castfunc = 0 +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +FILTER: schema="" table="" column="castfunc" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_cast c WHERE castsource = casttarget AND castfunc = 0" +== 044 +-- truncate_limit: 100 +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="c" column="castfunc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="" column="castsource" +FILTER: schema="" table="" column="casttarget" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM pg_cast c, pg_proc p WHERE ..." +== 045 +-- truncate_limit: 100 +-- Look for cast functions that don't have the right signature. The +-- argument and result types in pg_proc must be the same as, or binary +-- compatible with, what it says in pg_cast. +-- As a special case, we allow casts from CHAR(n) that use functions +-- declared to take TEXT. This does not pass the binary-coercibility test +-- because CHAR(n)-to-TEXT normally invokes rtrim(). However, the results +-- are the same, so long as the function is one that ignores trailing blanks. + +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND + (p.pronargs < 1 OR p.pronargs > 3 + OR NOT (binary_coercible(c.castsource, p.proargtypes[0]) + OR (c.castsource = 'character'::regtype AND + p.proargtypes[0] = 'text'::regtype)) + OR NOT binary_coercible(p.prorettype, c.casttarget)) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "p"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="c" column="castfunc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="c" column="castsource" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="c" column="castsource" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="c" column="casttarget" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM pg_cast c, pg_proc p WHERE ..." +== 046 +-- truncate_limit: 100 +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND + ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR + (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype)) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="c" column="castfunc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM pg_cast c, pg_proc p WHERE ..." +== 047 +-- truncate_limit: 100 +-- Look for binary compatible casts that do not have the reverse +-- direction registered as well, or where the reverse direction is not +-- also binary compatible. This is legal, but usually not intended. + +-- As of 7.4, this finds the casts from text and varchar to bpchar, because +-- those are binary-compatible while the reverse way goes through rtrim(). + +-- As of 8.2, this finds the cast from cidr to inet, because that is a +-- trivial binary coercion while the other way goes through inet_to_cidr(). + +-- As of 8.3, this finds the casts from xml to text, varchar, and bpchar, +-- because those are binary-compatible while the reverse goes through +-- texttoxml(), which does an XML syntax check. + +-- As of 9.1, this finds the cast from pg_node_tree to text, which we +-- intentionally do not provide a reverse pathway for. + +SELECT castsource::regtype, casttarget::regtype, castfunc, castcontext +FROM pg_cast c +WHERE c.castmethod = 'b' AND + NOT EXISTS (SELECT 1 FROM pg_cast k + WHERE k.castmethod = 'b' AND + k.castsource = c.casttarget AND + k.casttarget = c.castsource) +-- +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +TABLE: name="pg_cast" schema="" table="pg_cast" ctx=Select +ALIAS: "c"="pg_cast" +ALIAS: "k"="pg_cast" +FILTER: schema="" table="c" column="castmethod" +FILTER: schema="" table="k" column="castmethod" +FILTER: schema="" table="k" column="castsource" +FILTER: schema="" table="c" column="casttarget" +FILTER: schema="" table="k" column="casttarget" +FILTER: schema="" table="c" column="castsource" +STMT: SelectStmt +TRUNCATED: "SELECT castsource::regtype, casttarget::regtype, castfunc, castcontext FROM pg_cast c WHERE ..." +== 048 +-- truncate_limit: 100 +-- **************** pg_conversion **************** + +-- Look for illegal values in pg_conversion fields. + +SELECT c.oid, c.conname +FROM pg_conversion as c +WHERE c.conproc = 0 OR + pg_encoding_to_char(conforencoding) = '' OR + pg_encoding_to_char(contoencoding) = '' +-- +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "c"="pg_conversion" +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FILTER: schema="" table="c" column="conproc" +FILTER: schema="" table="" column="conforencoding" +FILTER: schema="" table="" column="contoencoding" +STMT: SelectStmt +TRUNCATED: "SELECT c.oid, c.conname FROM pg_conversion c WHERE ..." +== 049 +-- truncate_limit: 100 +-- Look for conprocs that don't have the expected signature. + +SELECT p.oid, p.proname, c.oid, c.conname +FROM pg_proc p, pg_conversion c +WHERE p.oid = c.conproc AND + (p.prorettype != 'int4'::regtype OR p.proretset OR + p.pronargs != 6 OR + p.proargtypes[0] != 'int4'::regtype OR + p.proargtypes[1] != 'int4'::regtype OR + p.proargtypes[2] != 'cstring'::regtype OR + p.proargtypes[3] != 'internal'::regtype OR + p.proargtypes[4] != 'int4'::regtype OR + p.proargtypes[5] != 'bool'::regtype) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "c"="pg_conversion" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="c" column="conproc" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="proretset" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p.oid, p.proname, c.oid, c.conname FROM pg_proc p, pg_conversion c WHERE ..." +== 050 +-- truncate_limit: 100 +-- Check for conprocs that don't perform the specific conversion that +-- pg_conversion alleges they do, by trying to invoke each conversion +-- on some simple ASCII data. (The conproc should throw an error if +-- it doesn't accept the encodings that are passed to it.) +-- Unfortunately, we can't test non-default conprocs this way, because +-- there is no way to ask convert() to invoke them, and we cannot call +-- them directly from SQL. But there are no non-default built-in +-- conversions anyway. +-- (Similarly, this doesn't cope with any search path issues.) + +SELECT c.oid, c.conname +FROM pg_conversion as c +WHERE condefault AND + convert('ABC'::bytea, pg_encoding_to_char(conforencoding), + pg_encoding_to_char(contoencoding)) != 'ABC' +-- +TABLE: name="pg_conversion" schema="" table="pg_conversion" ctx=Select +ALIAS: "c"="pg_conversion" +FUNCTION: name="convert" function="convert" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="convert" function="convert" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FUNCTION: name="pg_encoding_to_char" function="pg_encoding_to_char" schema="" ctx=Call +FILTER: schema="" table="" column="condefault" +FILTER: schema="" table="" column="conforencoding" +FILTER: schema="" table="" column="contoencoding" +STMT: SelectStmt +TRUNCATED: "SELECT c.oid, c.conname FROM pg_conversion c WHERE ..." +== 051 +-- truncate_limit: 100 +-- **************** pg_operator **************** + +-- Look for illegal values in pg_operator fields. + +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 +WHERE (o1.oprkind != 'b' AND o1.oprkind != 'l') OR + o1.oprresult = 0 OR o1.oprcode = 0 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprcode" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname FROM pg_operator o1 WHERE ..." +== 052 +-- truncate_limit: 100 +-- Look for missing or unwanted operand types + +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 +WHERE (o1.oprleft = 0 and o1.oprkind != 'l') OR + (o1.oprleft != 0 and o1.oprkind = 'l') OR + o1.oprright = 0 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname FROM pg_operator o1 WHERE ..." +== 053 +-- truncate_limit: 100 +-- Look for conflicting operator definitions (same names and input datatypes). + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oid != o2.oid AND + o1.oprname = o2.oprname AND + o1.oprkind = o2.oprkind AND + o1.oprleft = o2.oprleft AND + o1.oprright = o2.oprright +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprname" +FILTER: schema="" table="o2" column="oprname" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o2" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o2" column="oprleft" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="o2" column="oprright" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode FROM pg_operator o1, pg_operator o2 WHERE ..." +== 054 +-- truncate_limit: 100 +-- Look for commutative operators that don't commute. +-- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x. +-- We expect that B will always say that B.oprcom = A as well; that's not +-- inherently essential, but it would be inefficient not to mark it so. + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprcom = o2.oid AND + (o1.oprkind != 'b' OR + o1.oprleft != o2.oprright OR + o1.oprright != o2.oprleft OR + o1.oprresult != o2.oprresult OR + o1.oid != o2.oprcom) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o2" column="oprright" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="o2" column="oprleft" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o2" column="oprresult" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oprcom" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode FROM pg_operator o1, pg_operator o2 WHERE ..." +== 055 +-- truncate_limit: 100 +-- Look for negatory operators that don't agree. +-- DEFINITIONAL NOTE: If A.oprnegate = B, then both A and B must yield +-- boolean results, and (x A y) == ! (x B y), or the equivalent for +-- single-operand operators. +-- We expect that B will always say that B.oprnegate = A as well; that's not +-- inherently essential, but it would be inefficient not to mark it so. +-- Also, A and B had better not be the same operator. + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprnegate = o2.oid AND + (o1.oprkind != o2.oprkind OR + o1.oprleft != o2.oprleft OR + o1.oprright != o2.oprright OR + o1.oprresult != 'bool'::regtype OR + o2.oprresult != 'bool'::regtype OR + o1.oid != o2.oprnegate OR + o1.oid = o2.oid) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprnegate" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o2" column="oprkind" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="o2" column="oprleft" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="o2" column="oprright" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o2" column="oprresult" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oprnegate" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o2" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode FROM pg_operator o1, pg_operator o2 WHERE ..." +== 056 +-- truncate_limit: 100 +-- Make a list of the names of operators that are claimed to be commutator +-- pairs. This list will grow over time, but before accepting a new entry +-- make sure you didn't link the wrong operators. + +SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2 +FROM pg_operator o1, pg_operator o2 +WHERE o1.oprcom = o2.oid AND o1.oprname <= o2.oprname +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprname" +FILTER: schema="" table="o2" column="oprname" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_operator o1, pg_operator o2 WHERE ... ORDER BY 1, 2" +== 057 +-- truncate_limit: 100 +-- Likewise for negator pairs. + +SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2 +FROM pg_operator o1, pg_operator o2 +WHERE o1.oprnegate = o2.oid AND o1.oprname <= o2.oprname +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprnegate" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprname" +FILTER: schema="" table="o2" column="oprname" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_operator o1, pg_operator o2 WHERE ... ORDER BY 1, 2" +== 058 +-- truncate_limit: 100 +-- A mergejoinable or hashjoinable operator must be binary, must return +-- boolean, and must have a commutator (itself, unless it's a cross-type +-- operator). + +SELECT o1.oid, o1.oprname FROM pg_operator AS o1 +WHERE (o1.oprcanmerge OR o1.oprcanhash) AND NOT + (o1.oprkind = 'b' AND o1.oprresult = 'bool'::regtype AND o1.oprcom != 0) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprcom" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname FROM pg_operator o1 WHERE ..." +== 059 +-- truncate_limit: 100 +-- What's more, the commutator had better be mergejoinable/hashjoinable too. + +SELECT o1.oid, o1.oprname, o2.oid, o2.oprname +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprcom = o2.oid AND + (o1.oprcanmerge != o2.oprcanmerge OR + o1.oprcanhash != o2.oprcanhash) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="o2" column="oprcanmerge" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="o2" column="oprcanhash" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, o2.oid, o2.oprname FROM pg_operator o1, pg_operator o2 WHERE ..." +== 060 +-- truncate_limit: 100 +-- Mergejoinable operators should appear as equality members of btree index +-- opfamilies. + +SELECT o1.oid, o1.oprname +FROM pg_operator AS o1 +WHERE o1.oprcanmerge AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + amopopr = o1.oid AND amopstrategy = 3) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname FROM pg_operator o1 WHERE ..." +== 061 +-- truncate_limit: 100 +-- And the converse. + +SELECT o1.oid, o1.oprname, p.amopfamily +FROM pg_operator AS o1, pg_amop p +WHERE amopopr = o1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopstrategy = 3 + AND NOT o1.oprcanmerge +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p"="pg_amop" +FILTER: schema="" table="" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, p.amopfamily FROM pg_operator o1, pg_amop p WHERE ..." +== 062 +-- truncate_limit: 100 +-- Hashable operators should appear as members of hash index opfamilies. + +SELECT o1.oid, o1.oprname +FROM pg_operator AS o1 +WHERE o1.oprcanhash AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND + amopopr = o1.oid AND amopstrategy = 1) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname FROM pg_operator o1 WHERE ..." +== 063 +-- truncate_limit: 100 +-- And the converse. + +SELECT o1.oid, o1.oprname, p.amopfamily +FROM pg_operator AS o1, pg_amop p +WHERE amopopr = o1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') + AND NOT o1.oprcanhash +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p"="pg_amop" +FILTER: schema="" table="" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, p.amopfamily FROM pg_operator o1, pg_amop p WHERE ..." +== 064 +-- truncate_limit: 100 +-- Check that each operator defined in pg_operator matches its oprcode entry +-- in pg_proc. Easiest to do this separately for each oprkind. + +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + o1.oprkind = 'b' AND + (p1.pronargs != 2 + OR NOT binary_coercible(p1.prorettype, o1.oprresult) + OR NOT binary_coercible(o1.oprleft, p1.proargtypes[0]) + OR NOT binary_coercible(o1.oprright, p1.proargtypes[1])) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprleft" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, p1.oid, p1.proname FROM pg_operator o1, pg_proc p1 WHERE ..." +== 065 +-- truncate_limit: 100 +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + o1.oprkind = 'l' AND + (p1.pronargs != 1 + OR NOT binary_coercible(p1.prorettype, o1.oprresult) + OR NOT binary_coercible(o1.oprright, p1.proargtypes[0]) + OR o1.oprleft != 0) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="o1" column="oprright" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="o1" column="oprleft" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, p1.oid, p1.proname FROM pg_operator o1, pg_proc p1 WHERE ..." +== 066 +-- truncate_limit: 100 +-- If the operator is mergejoinable or hashjoinable, its underlying function +-- should not be volatile. + +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + (o1.oprcanmerge OR o1.oprcanhash) AND + p1.provolatile = 'v' +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprcanmerge" +FILTER: schema="" table="o1" column="oprcanhash" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, p1.oid, p1.proname FROM pg_operator o1, pg_proc p1 WHERE ..." +== 067 +-- truncate_limit: 100 +-- If oprrest is set, the operator must return boolean, +-- and it must link to a proc with the right signature +-- to be a restriction selectivity estimator. +-- The proc signature we want is: float8 proc(internal, oid, internal, int4) + +SELECT o1.oid, o1.oprname, p2.oid, p2.proname +FROM pg_operator AS o1, pg_proc AS p2 +WHERE o1.oprrest = p2.oid AND + (o1.oprresult != 'bool'::regtype OR + p2.prorettype != 'float8'::regtype OR p2.proretset OR + p2.pronargs != 4 OR + p2.proargtypes[0] != 'internal'::regtype OR + p2.proargtypes[1] != 'oid'::regtype OR + p2.proargtypes[2] != 'internal'::regtype OR + p2.proargtypes[3] != 'int4'::regtype) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprrest" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="p2" column="prorettype" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, p2.oid, p2.proname FROM pg_operator o1, pg_proc p2 WHERE ..." +== 068 +-- truncate_limit: 100 +-- If oprjoin is set, the operator must be a binary boolean op, +-- and it must link to a proc with the right signature +-- to be a join selectivity estimator. +-- The proc signature we want is: float8 proc(internal, oid, internal, int2, internal) +-- (Note: the old signature with only 4 args is still allowed, but no core +-- estimator should be using it.) + +SELECT o1.oid, o1.oprname, p2.oid, p2.proname +FROM pg_operator AS o1, pg_proc AS p2 +WHERE o1.oprjoin = p2.oid AND + (o1.oprkind != 'b' OR o1.oprresult != 'bool'::regtype OR + p2.prorettype != 'float8'::regtype OR p2.proretset OR + p2.pronargs != 5 OR + p2.proargtypes[0] != 'internal'::regtype OR + p2.proargtypes[1] != 'oid'::regtype OR + p2.proargtypes[2] != 'internal'::regtype OR + p2.proargtypes[3] != 'int2'::regtype OR + p2.proargtypes[4] != 'internal'::regtype) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprjoin" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o1" column="oprkind" +FILTER: schema="" table="o1" column="oprresult" +FILTER: schema="" table="p2" column="prorettype" +FILTER: schema="" table="p2" column="proretset" +FILTER: schema="" table="p2" column="pronargs" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT o1.oid, o1.oprname, p2.oid, p2.proname FROM pg_operator o1, pg_proc p2 WHERE ..." +== 069 +-- truncate_limit: 100 +-- Insist that all built-in pg_operator entries have descriptions +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 LEFT JOIN pg_description as d + ON o1.tableoid = d.classoid and o1.oid = d.objoid and d.objsubid = 0 +WHERE d.classoid IS NULL AND o1.oid <= 9999 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "d"="pg_description" +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="d" column="classoid" +FILTER: schema="" table="o1" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator o1 LEFT JOIN pg_description d ON o1.tableoid = d.classoid AND o1.oid ..." +== 070 +-- truncate_limit: 100 +-- Check that operators' underlying functions have suitable comments, +-- namely 'implementation of XXX operator'. (Note: it's not necessary to +-- put such comments into pg_proc.dat; initdb will generate them as needed.) +-- In some cases involving legacy names for operators, there are multiple +-- operators referencing the same pg_proc entry, so ignore operators whose +-- comments say they are deprecated. +-- We also have a few functions that are both operator support and meant to +-- be called directly; those should have comments matching their operator. +WITH funcdescs AS ( + SELECT p.oid as p_oid, proname, o.oid as o_oid, + pd.description as prodesc, + 'implementation of ' || oprname || ' operator' as expecteddesc, + od.description as oprdesc + FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid + LEFT JOIN pg_description pd ON + (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0) + LEFT JOIN pg_description od ON + (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0) + WHERE o.oid <= 9999 +) +SELECT * FROM funcdescs + WHERE prodesc IS DISTINCT FROM expecteddesc + AND oprdesc NOT LIKE 'deprecated%' + AND prodesc IS DISTINCT FROM oprdesc +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "o"="pg_operator" +ALIAS: "od"="pg_description" +ALIAS: "p"="pg_proc" +ALIAS: "pd"="pg_description" +CTE: "funcdescs" +FILTER: schema="" table="" column="prodesc" +FILTER: schema="" table="" column="expecteddesc" +FILTER: schema="" table="" column="oprdesc" +FILTER: schema="" table="" column="prodesc" +FILTER: schema="" table="" column="oprdesc" +FILTER: schema="" table="o" column="oid" +STMT: SelectStmt +TRUNCATED: "WITH funcdescs AS (...) SELECT * FROM funcdescs WHERE ..." +== 071 +-- truncate_limit: 100 +-- Show all the operator-implementation functions that have their own +-- comments. This should happen only in cases where the function and +-- operator syntaxes are both documented at the user level. +-- This should be a pretty short list; it's mostly legacy cases. +WITH funcdescs AS ( + SELECT p.oid as p_oid, proname, o.oid as o_oid, + pd.description as prodesc, + 'implementation of ' || oprname || ' operator' as expecteddesc, + od.description as oprdesc + FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid + LEFT JOIN pg_description pd ON + (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0) + LEFT JOIN pg_description od ON + (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0) + WHERE o.oid <= 9999 +) +SELECT p_oid, proname, prodesc FROM funcdescs + WHERE prodesc IS DISTINCT FROM expecteddesc + AND oprdesc NOT LIKE 'deprecated%' +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +TABLE: name="pg_description" schema="" table="pg_description" ctx=Select +ALIAS: "o"="pg_operator" +ALIAS: "od"="pg_description" +ALIAS: "p"="pg_proc" +ALIAS: "pd"="pg_description" +CTE: "funcdescs" +FILTER: schema="" table="" column="prodesc" +FILTER: schema="" table="" column="expecteddesc" +FILTER: schema="" table="" column="oprdesc" +FILTER: schema="" table="o" column="oid" +STMT: SelectStmt +TRUNCATED: "WITH funcdescs AS (...) SELECT p_oid, proname, prodesc FROM funcdescs WHERE ... ORDER BY 1" +== 072 +-- truncate_limit: 100 +-- Operators that are commutator pairs should have identical volatility +-- and leakproofness markings on their implementation functions. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprcom = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprcom" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o2" column="oprcode" +FILTER: schema="" table="p1" column="provolatile" +FILTER: schema="" table="p2" column="provolatile" +FILTER: schema="" table="p1" column="proleakproof" +FILTER: schema="" table="p2" column="proleakproof" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator o1, pg_operator o2, pg_proc p1, pg_proc p2 WHERE ..." +== 073 +-- truncate_limit: 100 +-- Likewise for negator pairs. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprnegate = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "o1"="pg_operator" +ALIAS: "o2"="pg_operator" +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FILTER: schema="" table="o1" column="oprnegate" +FILTER: schema="" table="o2" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="o2" column="oprcode" +FILTER: schema="" table="p1" column="provolatile" +FILTER: schema="" table="p2" column="provolatile" +FILTER: schema="" table="p1" column="proleakproof" +FILTER: schema="" table="p2" column="proleakproof" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_operator o1, pg_operator o2, pg_proc p1, pg_proc p2 WHERE ..." +== 074 +-- truncate_limit: 100 +-- Btree comparison operators' functions should have the same volatility +-- and leakproofness markings as the associated comparison support function. +SELECT pp.oid::regprocedure as proc, pp.provolatile as vp, pp.proleakproof as lp, + po.oid::regprocedure as opr, po.provolatile as vo, po.proleakproof as lo +FROM pg_proc pp, pg_proc po, pg_operator o, pg_amproc ap, pg_amop ao +WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND + ao.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + ao.amopfamily = ap.amprocfamily AND + ao.amoplefttype = ap.amproclefttype AND + ao.amoprighttype = ap.amprocrighttype AND + ap.amprocnum = 1 AND + (pp.provolatile != po.provolatile OR + pp.proleakproof != po.proleakproof) +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "ao"="pg_amop" +ALIAS: "ap"="pg_amproc" +ALIAS: "o"="pg_operator" +ALIAS: "po"="pg_proc" +ALIAS: "pp"="pg_proc" +FILTER: schema="" table="pp" column="oid" +FILTER: schema="" table="ap" column="amproc" +FILTER: schema="" table="po" column="oid" +FILTER: schema="" table="o" column="oprcode" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="ao" column="amopopr" +FILTER: schema="" table="ao" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_proc pp, pg_proc po, pg_operator o, pg_amproc ap, pg_amop ao WHERE ... ORDER BY 1" +== 075 +-- truncate_limit: 100 +-- **************** pg_aggregate **************** + +-- Look for illegal values in pg_aggregate fields. + +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggfnoid = 0 OR aggtransfn = 0 OR + aggkind NOT IN ('n', 'o', 'h') OR + aggnumdirectargs < 0 OR + (aggkind = 'n' AND aggnumdirectargs > 0) OR + aggfinalmodify NOT IN ('r', 's', 'w') OR + aggmfinalmodify NOT IN ('r', 's', 'w') OR + aggtranstype = 0 OR aggtransspace < 0 OR aggmtransspace < 0 +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +FILTER: schema="" table="" column="aggfnoid" +FILTER: schema="" table="" column="aggtransfn" +FILTER: schema="" table="" column="aggkind" +FILTER: schema="" table="" column="aggnumdirectargs" +FILTER: schema="" table="" column="aggkind" +FILTER: schema="" table="" column="aggnumdirectargs" +FILTER: schema="" table="" column="aggfinalmodify" +FILTER: schema="" table="" column="aggmfinalmodify" +FILTER: schema="" table="" column="aggtranstype" +FILTER: schema="" table="" column="aggtransspace" +FILTER: schema="" table="" column="aggmtransspace" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, aggfnoid::oid FROM pg_aggregate a WHERE ..." +== 076 +-- truncate_limit: 100 +-- Make sure the matching pg_proc entry is sensible, too. + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + (p.prokind != 'a' OR p.proretset OR p.pronargs < a.aggnumdirectargs) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="prokind" +FILTER: schema="" table="p" column="proretset" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid::oid, p.proname FROM pg_aggregate a, pg_proc p WHERE ..." +== 077 +-- truncate_limit: 100 +-- Make sure there are no prokind = PROKIND_AGGREGATE pg_proc entries without matches. + +SELECT oid, proname +FROM pg_proc as p +WHERE p.prokind = 'a' AND + NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid) +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="p" column="prokind" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT oid, proname FROM pg_proc p WHERE ..." +== 078 +-- truncate_limit: 100 +-- If there is no finalfn then the output type must be the transtype. + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggfinalfn" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggtranstype" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid::oid, p.proname FROM pg_aggregate a, pg_proc p WHERE ..." +== 079 +-- truncate_limit: 100 +-- Cross-check transfn against its entry in pg_proc. +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggtranstype) + OR NOT binary_coercible(a.aggtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + OR (p.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[3], ptr.proargtypes[4])) + -- we could carry the check further, but 4 args is enough for now + OR (p.pronargs > 4) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proretset" +FILTER: schema="" table="ptr" column="pronargs" +FILTER: schema="" table="a" column="aggkind" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="ptr" column="prorettype" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc ptr WHERE ..." +== 080 +-- truncate_limit: 100 +-- Cross-check finalfn (if present) against its entry in pg_proc. + +SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn +WHERE a.aggfnoid = p.oid AND + a.aggfinalfn = pfn.oid AND + (pfn.proretset OR + NOT binary_coercible(pfn.prorettype, p.prorettype) OR + NOT binary_coercible(a.aggtranstype, pfn.proargtypes[0]) OR + CASE WHEN a.aggfinalextra THEN pfn.pronargs != p.pronargs + 1 + ELSE pfn.pronargs != a.aggnumdirectargs + 1 END + OR (pfn.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1])) + OR (pfn.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) + OR (pfn.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "pfn"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggfinalfn" +FILTER: schema="" table="pfn" column="oid" +FILTER: schema="" table="pfn" column="proretset" +FILTER: schema="" table="pfn" column="prorettype" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="a" column="aggfinalextra" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc pfn WHERE ..." +== 081 +-- truncate_limit: 100 +-- If transfn is strict then either initval should be non-NULL, or +-- input type should match transtype so that the first non-null input +-- can be assigned as the state value. + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggtransfn = ptr.oid AND ptr.proisstrict AND + a.agginitval IS NULL AND + NOT binary_coercible(p.proargtypes[0], a.aggtranstype) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proisstrict" +FILTER: schema="" table="a" column="agginitval" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="a" column="aggtranstype" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc ptr WHERE ..." +== 082 +-- truncate_limit: 100 +-- Check for inconsistent specifications of moving-aggregate columns. + +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggmtranstype != 0 AND + (aggmtransfn = 0 OR aggminvtransfn = 0) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +FILTER: schema="" table="" column="aggmtranstype" +FILTER: schema="" table="" column="aggmtransfn" +FILTER: schema="" table="" column="aggminvtransfn" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, aggfnoid::oid FROM pg_aggregate a WHERE ..." +== 083 +-- truncate_limit: 100 +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggmtranstype = 0 AND + (aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR + aggmtransspace != 0 OR aggminitval IS NOT NULL) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +FILTER: schema="" table="" column="aggmtranstype" +FILTER: schema="" table="" column="aggmtransfn" +FILTER: schema="" table="" column="aggminvtransfn" +FILTER: schema="" table="" column="aggmfinalfn" +FILTER: schema="" table="" column="aggmtransspace" +FILTER: schema="" table="" column="aggminitval" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, aggfnoid::oid FROM pg_aggregate a WHERE ..." +== 084 +-- truncate_limit: 100 +-- If there is no mfinalfn then the output type must be the mtranstype. + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn != 0 AND + a.aggmfinalfn = 0 AND p.prorettype != a.aggmtranstype +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="a" column="aggmfinalfn" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid::oid, p.proname FROM pg_aggregate a, pg_proc p WHERE ..." +== 085 +-- truncate_limit: 100 +-- Cross-check mtransfn (if present) against its entry in pg_proc. +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proretset" +FILTER: schema="" table="ptr" column="pronargs" +FILTER: schema="" table="a" column="aggkind" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="ptr" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc ptr WHERE ..." +== 086 +-- truncate_limit: 100 +-- Cross-check minvtransfn (if present) against its entry in pg_proc. +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggminvtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggminvtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proretset" +FILTER: schema="" table="ptr" column="pronargs" +FILTER: schema="" table="a" column="aggkind" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="ptr" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="ptr" column="proargtypes" +FILTER: schema="" table="p" column="pronargs" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc ptr WHERE ..." +== 087 +-- truncate_limit: 100 +-- Cross-check mfinalfn (if present) against its entry in pg_proc. + +SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn +WHERE a.aggfnoid = p.oid AND + a.aggmfinalfn = pfn.oid AND + (pfn.proretset OR + NOT binary_coercible(pfn.prorettype, p.prorettype) OR + NOT binary_coercible(a.aggmtranstype, pfn.proargtypes[0]) OR + CASE WHEN a.aggmfinalextra THEN pfn.pronargs != p.pronargs + 1 + ELSE pfn.pronargs != a.aggnumdirectargs + 1 END + OR (pfn.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1])) + OR (pfn.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) + OR (pfn.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) + ) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "pfn"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmfinalfn" +FILTER: schema="" table="pfn" column="oid" +FILTER: schema="" table="pfn" column="proretset" +FILTER: schema="" table="pfn" column="prorettype" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="a" column="aggmtranstype" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="a" column="aggmfinalextra" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="a" column="aggnumdirectargs" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="pfn" column="proargtypes" +FILTER: schema="" table="pfn" column="pronargs" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc pfn WHERE ..." +== 088 +-- truncate_limit: 100 +-- If mtransfn is strict then either minitval should be non-NULL, or +-- input type should match mtranstype so that the first non-null input +-- can be assigned as the state value. + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND ptr.proisstrict AND + a.aggminitval IS NULL AND + NOT binary_coercible(p.proargtypes[0], a.aggmtranstype) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="ptr" column="proisstrict" +FILTER: schema="" table="a" column="aggminitval" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="a" column="aggmtranstype" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc ptr WHERE ..." +== 089 +-- truncate_limit: 100 +-- mtransfn and minvtransfn should have same strictness setting. + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname, iptr.oid, iptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr, pg_proc AS iptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND + a.aggminvtransfn = iptr.oid AND + ptr.proisstrict != iptr.proisstrict +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "iptr"="pg_proc" +ALIAS: "p"="pg_proc" +ALIAS: "ptr"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggmtransfn" +FILTER: schema="" table="ptr" column="oid" +FILTER: schema="" table="a" column="aggminvtransfn" +FILTER: schema="" table="iptr" column="oid" +FILTER: schema="" table="ptr" column="proisstrict" +FILTER: schema="" table="iptr" column="proisstrict" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_proc p, pg_proc ptr, pg_proc iptr WHERE ..." +== 090 +-- truncate_limit: 100 +-- Check that all combine functions have signature +-- combine(transtype, transtype) returns transtype + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggcombinefn = p.oid AND + (p.pronargs != 2 OR + p.prorettype != p.proargtypes[0] OR + p.prorettype != p.proargtypes[1] OR + NOT binary_coercible(a.aggtranstype, p.proargtypes[0])) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="aggcombinefn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid, p.proname FROM pg_aggregate a, pg_proc p WHERE ..." +== 091 +-- truncate_limit: 100 +-- Check that no combine function for an INTERNAL transtype is strict. + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggcombinefn = p.oid AND + a.aggtranstype = 'internal'::regtype AND p.proisstrict +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggcombinefn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggtranstype" +FILTER: schema="" table="p" column="proisstrict" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid, p.proname FROM pg_aggregate a, pg_proc p WHERE ..." +== 092 +-- truncate_limit: 100 +-- serialize/deserialize functions should be specified only for aggregates +-- with transtype internal and a combine function, and we should have both +-- or neither of them. + +SELECT aggfnoid, aggtranstype, aggserialfn, aggdeserialfn +FROM pg_aggregate +WHERE (aggserialfn != 0 OR aggdeserialfn != 0) + AND (aggtranstype != 'internal'::regtype OR aggcombinefn = 0 OR + aggserialfn = 0 OR aggdeserialfn = 0) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +FILTER: schema="" table="" column="aggserialfn" +FILTER: schema="" table="" column="aggdeserialfn" +FILTER: schema="" table="" column="aggtranstype" +FILTER: schema="" table="" column="aggcombinefn" +FILTER: schema="" table="" column="aggserialfn" +FILTER: schema="" table="" column="aggdeserialfn" +STMT: SelectStmt +TRUNCATED: "SELECT aggfnoid, aggtranstype, aggserialfn, aggdeserialfn FROM pg_aggregate WHERE ..." +== 093 +-- truncate_limit: 100 +-- Check that all serialization functions have signature +-- serialize(internal) returns bytea +-- Also insist that they be strict; it's wasteful to run them on NULLs. + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggserialfn = p.oid AND + (p.prorettype != 'bytea'::regtype OR p.pronargs != 1 OR + p.proargtypes[0] != 'internal'::regtype OR + NOT p.proisstrict) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggserialfn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proisstrict" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid, p.proname FROM pg_aggregate a, pg_proc p WHERE ..." +== 094 +-- truncate_limit: 100 +-- Check that all deserialization functions have signature +-- deserialize(bytea, internal) returns internal +-- Also insist that they be strict; it's wasteful to run them on NULLs. + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggdeserialfn = p.oid AND + (p.prorettype != 'internal'::regtype OR p.pronargs != 2 OR + p.proargtypes[0] != 'bytea'::regtype OR + p.proargtypes[1] != 'internal'::regtype OR + NOT p.proisstrict) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggdeserialfn" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="p" column="prorettype" +FILTER: schema="" table="p" column="pronargs" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="p" column="proisstrict" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid, p.proname FROM pg_aggregate a, pg_proc p WHERE ..." +== 095 +-- truncate_limit: 100 +-- Check that aggregates which have the same transition function also have +-- the same combine, serialization, and deserialization functions. +-- While that isn't strictly necessary, it's fishy if they don't. + +SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn, + b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn +FROM + pg_aggregate a, pg_aggregate b +WHERE + a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND + (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn + OR a.aggdeserialfn != b.aggdeserialfn) +-- +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "b"="pg_aggregate" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="b" column="aggfnoid" +FILTER: schema="" table="a" column="aggtransfn" +FILTER: schema="" table="b" column="aggtransfn" +FILTER: schema="" table="a" column="aggcombinefn" +FILTER: schema="" table="b" column="aggcombinefn" +FILTER: schema="" table="a" column="aggserialfn" +FILTER: schema="" table="b" column="aggserialfn" +FILTER: schema="" table="a" column="aggdeserialfn" +FILTER: schema="" table="b" column="aggdeserialfn" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_aggregate a, pg_aggregate b WHERE ..." +== 096 +-- truncate_limit: 100 +-- Cross-check aggsortop (if present) against pg_operator. +-- We expect to find entries for bool_and, bool_or, every, max, and min. + +SELECT DISTINCT proname, oprname +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_operator o, pg_aggregate a, pg_proc p WHERE ... ORDER BY 1, 2" +== 097 +-- truncate_limit: 100 +-- Check datatypes match + +SELECT a.aggfnoid::oid, o.oid +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + (oprkind != 'b' OR oprresult != 'boolean'::regtype + OR oprleft != p.proargtypes[0] OR oprright != p.proargtypes[0]) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="oprkind" +FILTER: schema="" table="" column="oprresult" +FILTER: schema="" table="" column="oprleft" +FILTER: schema="" table="p" column="proargtypes" +FILTER: schema="" table="" column="oprright" +FILTER: schema="" table="p" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid::oid, o.oid FROM pg_operator o, pg_aggregate a, pg_proc p WHERE ..." +== 098 +-- truncate_limit: 100 +-- Check operator is a suitable btree opfamily member + +SELECT a.aggfnoid::oid, o.oid +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + NOT EXISTS(SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopopr = o.oid + AND amoplefttype = o.oprleft + AND amoprighttype = o.oprright) +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT a.aggfnoid::oid, o.oid FROM pg_operator o, pg_aggregate a, pg_proc p WHERE ..." +== 099 +-- truncate_limit: 100 +-- Check correspondence of btree strategies and names + +SELECT DISTINCT proname, oprname, amopstrategy +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p, + pg_amop as ao +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + amopopr = o.oid AND + amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') +ORDER BY 1, 2 +-- +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "ao"="pg_amop" +ALIAS: "o"="pg_operator" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="a" column="aggfnoid" +FILTER: schema="" table="p" column="oid" +FILTER: schema="" table="a" column="aggsortop" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="amopopr" +FILTER: schema="" table="o" column="oid" +FILTER: schema="" table="" column="amopmethod" +FILTER: schema="" table="" column="amname" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_operator o, pg_aggregate a, pg_proc p, pg_amop ao WHERE ... OR..." +== 100 +-- truncate_limit: 100 +-- Check that there are not aggregates with the same name and different +-- numbers of arguments. While not technically wrong, we have a project policy +-- to avoid this because it opens the door for confusion in connection with +-- ORDER BY: novices frequently put the ORDER BY in the wrong place. +-- See the fate of the single-argument form of string_agg() for history. +-- (Note: we don't forbid users from creating such aggregates; the policy is +-- just to think twice before creating built-in aggregates like this.) +-- The only aggregates that should show up here are count(x) and count(*). + +SELECT p1.oid::regprocedure, p2.oid::regprocedure +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid < p2.oid AND p1.proname = p2.proname AND + p1.prokind = 'a' AND p2.prokind = 'a' AND + array_dims(p1.proargtypes) != array_dims(p2.proargtypes) +ORDER BY 1 +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="proname" +FILTER: schema="" table="p2" column="proname" +FILTER: schema="" table="p1" column="prokind" +FILTER: schema="" table="p2" column="prokind" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p2" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT p1.oid::regprocedure, p2.oid::regprocedure FROM pg_proc p1, pg_proc p2 WHERE ... ORDER BY 1" +== 101 +-- truncate_limit: 100 +-- For the same reason, built-in aggregates with default arguments are no good. + +SELECT oid, proname +FROM pg_proc AS p +WHERE prokind = 'a' AND proargdefaults IS NOT NULL +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p"="pg_proc" +FILTER: schema="" table="" column="prokind" +FILTER: schema="" table="" column="proargdefaults" +STMT: SelectStmt +TRUNCATED: "SELECT oid, proname FROM pg_proc p WHERE prokind = 'a' AND proargdefaults IS NOT NULL" +== 102 +-- truncate_limit: 100 +-- For the same reason, we avoid creating built-in variadic aggregates, except +-- that variadic ordered-set aggregates are OK (since they have special syntax +-- that is not subject to the misplaced ORDER BY issue). + +SELECT p.oid, proname +FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid +WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n' +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_aggregate" schema="" table="pg_aggregate" ctx=Select +ALIAS: "a"="pg_aggregate" +ALIAS: "p"="pg_proc" +FILTER: schema="" table="" column="prokind" +FILTER: schema="" table="" column="provariadic" +FILTER: schema="" table="a" column="aggkind" +STMT: SelectStmt +TRUNCATED: "SELECT p.oid, proname FROM pg_proc p JOIN pg_aggregate a ON a.aggfnoid = p.oid WHERE ..." +== 103 +-- truncate_limit: 100 +-- **************** pg_opfamily **************** + +-- Look for illegal values in pg_opfamily fields + +SELECT f.oid +FROM pg_opfamily as f +WHERE f.opfmethod = 0 OR f.opfnamespace = 0 +-- +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +ALIAS: "f"="pg_opfamily" +FILTER: schema="" table="f" column="opfmethod" +FILTER: schema="" table="f" column="opfnamespace" +STMT: SelectStmt +TRUNCATED: "SELECT f.oid FROM pg_opfamily f WHERE f.opfmethod = 0 OR f.opfnamespace = 0" +== 104 +-- truncate_limit: 100 +-- Look for opfamilies having no opclasses. While most validation of +-- opfamilies is now handled by AM-specific amvalidate functions, that's +-- driven from pg_opclass entries below, so an empty opfamily would not +-- get noticed. + +SELECT oid, opfname FROM pg_opfamily f +WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid) +-- +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "f"="pg_opfamily" +FILTER: schema="" table="" column="opcfamily" +FILTER: schema="" table="f" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT oid, opfname FROM pg_opfamily f WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE ...)" +== 105 +-- truncate_limit: 100 +-- **************** pg_opclass **************** + +-- Look for illegal values in pg_opclass fields + +SELECT c1.oid +FROM pg_opclass AS c1 +WHERE c1.opcmethod = 0 OR c1.opcnamespace = 0 OR c1.opcfamily = 0 + OR c1.opcintype = 0 +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "c1"="pg_opclass" +FILTER: schema="" table="c1" column="opcmethod" +FILTER: schema="" table="c1" column="opcnamespace" +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="c1" column="opcintype" +STMT: SelectStmt +TRUNCATED: "SELECT c1.oid FROM pg_opclass c1 WHERE ..." +== 106 +-- truncate_limit: 100 +-- opcmethod must match owning opfamily's opfmethod + +SELECT c1.oid, f1.oid +FROM pg_opclass AS c1, pg_opfamily AS f1 +WHERE c1.opcfamily = f1.oid AND c1.opcmethod != f1.opfmethod +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +ALIAS: "c1"="pg_opclass" +ALIAS: "f1"="pg_opfamily" +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="f1" column="oid" +FILTER: schema="" table="c1" column="opcmethod" +FILTER: schema="" table="f1" column="opfmethod" +STMT: SelectStmt +TRUNCATED: "SELECT c1.oid, f1.oid FROM pg_opclass c1, pg_opfamily f1 WHERE ..." +== 107 +-- truncate_limit: 100 +-- There should not be multiple entries in pg_opclass with opcdefault true +-- and the same opcmethod/opcintype combination. + +SELECT c1.oid, c2.oid +FROM pg_opclass AS c1, pg_opclass AS c2 +WHERE c1.oid != c2.oid AND + c1.opcmethod = c2.opcmethod AND c1.opcintype = c2.opcintype AND + c1.opcdefault AND c2.opcdefault +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "c1"="pg_opclass" +ALIAS: "c2"="pg_opclass" +FILTER: schema="" table="c1" column="oid" +FILTER: schema="" table="c2" column="oid" +FILTER: schema="" table="c1" column="opcmethod" +FILTER: schema="" table="c2" column="opcmethod" +FILTER: schema="" table="c1" column="opcintype" +FILTER: schema="" table="c2" column="opcintype" +FILTER: schema="" table="c1" column="opcdefault" +FILTER: schema="" table="c2" column="opcdefault" +STMT: SelectStmt +TRUNCATED: "SELECT c1.oid, c2.oid FROM pg_opclass c1, pg_opclass c2 WHERE ..." +== 108 +-- truncate_limit: 100 +-- Ask access methods to validate opclasses +-- (this replaces a lot of SQL-level checks that used to be done in this file) + +SELECT oid, opcname FROM pg_opclass WHERE NOT amvalidate(oid) +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +FUNCTION: name="amvalidate" function="amvalidate" schema="" ctx=Call +FUNCTION: name="amvalidate" function="amvalidate" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT oid, opcname FROM pg_opclass WHERE NOT amvalidate(oid)" +== 109 +-- truncate_limit: 100 +-- **************** pg_am **************** + +-- Look for illegal values in pg_am fields + +SELECT a1.oid, a1.amname +FROM pg_am AS a1 +WHERE a1.amhandler = 0 +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "a1"="pg_am" +FILTER: schema="" table="a1" column="amhandler" +STMT: SelectStmt +TRUNCATED: "SELECT a1.oid, a1.amname FROM pg_am a1 WHERE a1.amhandler = 0" +== 110 +-- truncate_limit: 100 +-- Check for index amhandler functions with the wrong signature + +SELECT a1.oid, a1.amname, p1.oid, p1.proname +FROM pg_am AS a1, pg_proc AS p1 +WHERE p1.oid = a1.amhandler AND a1.amtype = 'i' AND + (p1.prorettype != 'index_am_handler'::regtype + OR p1.proretset + OR p1.pronargs != 1 + OR p1.proargtypes[0] != 'internal'::regtype) +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_am" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amhandler" +FILTER: schema="" table="a1" column="amtype" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT a1.oid, a1.amname, p1.oid, p1.proname FROM pg_am a1, pg_proc p1 WHERE ..." +== 111 +-- truncate_limit: 100 +-- Check for table amhandler functions with the wrong signature + +SELECT a1.oid, a1.amname, p1.oid, p1.proname +FROM pg_am AS a1, pg_proc AS p1 +WHERE p1.oid = a1.amhandler AND a1.amtype = 't' AND + (p1.prorettype != 'table_am_handler'::regtype + OR p1.proretset + OR p1.pronargs != 1 + OR p1.proargtypes[0] != 'internal'::regtype) +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_am" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amhandler" +FILTER: schema="" table="a1" column="amtype" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT a1.oid, a1.amname, p1.oid, p1.proname FROM pg_am a1, pg_proc p1 WHERE ..." +== 112 +-- truncate_limit: 100 +-- **************** pg_amop **************** + +-- Look for illegal values in pg_amop fields + +SELECT a1.amopfamily, a1.amopstrategy +FROM pg_amop as a1 +WHERE a1.amopfamily = 0 OR a1.amoplefttype = 0 OR a1.amoprighttype = 0 + OR a1.amopopr = 0 OR a1.amopmethod = 0 OR a1.amopstrategy < 1 +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +ALIAS: "a1"="pg_amop" +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="a1" column="amoplefttype" +FILTER: schema="" table="a1" column="amoprighttype" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="a1" column="amopmethod" +FILTER: schema="" table="a1" column="amopstrategy" +STMT: SelectStmt +TRUNCATED: "SELECT a1.amopfamily, a1.amopstrategy FROM pg_amop a1 WHERE ..." +== 113 +-- truncate_limit: 100 +SELECT a1.amopfamily, a1.amopstrategy +FROM pg_amop as a1 +WHERE NOT ((a1.amoppurpose = 's' AND a1.amopsortfamily = 0) OR + (a1.amoppurpose = 'o' AND a1.amopsortfamily <> 0)) +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +ALIAS: "a1"="pg_amop" +FILTER: schema="" table="a1" column="amoppurpose" +FILTER: schema="" table="a1" column="amopsortfamily" +FILTER: schema="" table="a1" column="amoppurpose" +FILTER: schema="" table="a1" column="amopsortfamily" +STMT: SelectStmt +TRUNCATED: "SELECT a1.amopfamily, a1.amopstrategy FROM pg_amop a1 WHERE ..." +== 114 +-- truncate_limit: 100 +-- amopmethod must match owning opfamily's opfmethod + +SELECT a1.oid, f1.oid +FROM pg_amop AS a1, pg_opfamily AS f1 +WHERE a1.amopfamily = f1.oid AND a1.amopmethod != f1.opfmethod +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "f1"="pg_opfamily" +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="f1" column="oid" +FILTER: schema="" table="a1" column="amopmethod" +FILTER: schema="" table="f1" column="opfmethod" +STMT: SelectStmt +TRUNCATED: "SELECT a1.oid, f1.oid FROM pg_amop a1, pg_opfamily f1 WHERE ..." +== 115 +-- truncate_limit: 100 +-- Make a list of all the distinct operator names being used in particular +-- strategy slots. This is a bit hokey, since the list might need to change +-- in future releases, but it's an effective way of spotting mistakes such as +-- swapping two operators within a family. + +SELECT DISTINCT amopmethod, amopstrategy, oprname +FROM pg_amop a1 LEFT JOIN pg_operator o1 ON amopopr = o1.oid +ORDER BY 1, 2, 3 +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM pg_amop a1 LEFT JOIN pg_operator o1 ON amopopr = o1.oid ORDER BY ..." +== 116 +-- truncate_limit: 100 +-- Check that all opclass search operators have selectivity estimators. +-- This is not absolutely required, but it seems a reasonable thing +-- to insist on for all standard datatypes. + +SELECT a1.amopfamily, a1.amopopr, o1.oid, o1.oprname +FROM pg_amop AS a1, pg_operator AS o1 +WHERE a1.amopopr = o1.oid AND a1.amoppurpose = 's' AND + (o1.oprrest = 0 OR o1.oprjoin = 0) +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="a1" column="amoppurpose" +FILTER: schema="" table="o1" column="oprrest" +FILTER: schema="" table="o1" column="oprjoin" +STMT: SelectStmt +TRUNCATED: "SELECT a1.amopfamily, a1.amopopr, o1.oid, o1.oprname FROM pg_amop a1, pg_operator o1 WHERE ..." +== 117 +-- truncate_limit: 100 +-- Check that each opclass in an opfamily has associated operators, that is +-- ones whose oprleft matches opcintype (possibly by coercion). + +SELECT c1.opcname, c1.opcfamily +FROM pg_opclass AS c1 +WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS a1 + WHERE a1.amopfamily = c1.opcfamily + AND binary_coercible(c1.opcintype, a1.amoplefttype)) +-- +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "c1"="pg_opclass" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="c1" column="opcintype" +FILTER: schema="" table="a1" column="amoplefttype" +STMT: SelectStmt +TRUNCATED: "SELECT c1.opcname, c1.opcfamily FROM pg_opclass c1 WHERE ..." +== 118 +-- truncate_limit: 100 +-- Check that each operator listed in pg_amop has an associated opclass, +-- that is one whose opcintype matches oprleft (possibly by coercion). +-- Otherwise the operator is useless because it cannot be matched to an index. +-- (In principle it could be useful to list such operators in multiple-datatype +-- btree opfamilies, but in practice you'd expect there to be an opclass for +-- every datatype the family knows about.) + +SELECT a1.amopfamily, a1.amopstrategy, a1.amopopr +FROM pg_amop AS a1 +WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS c1 + WHERE c1.opcfamily = a1.amopfamily + AND binary_coercible(c1.opcintype, a1.amoplefttype)) +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "c1"="pg_opclass" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="c1" column="opcfamily" +FILTER: schema="" table="a1" column="amopfamily" +FILTER: schema="" table="c1" column="opcintype" +FILTER: schema="" table="a1" column="amoplefttype" +STMT: SelectStmt +TRUNCATED: "SELECT a1.amopfamily, a1.amopstrategy, a1.amopopr FROM pg_amop a1 WHERE ..." +== 119 +-- truncate_limit: 100 +-- Operators that are primary members of opclasses must be immutable (else +-- it suggests that the index ordering isn't fixed). Operators that are +-- cross-type members need only be stable, since they are just shorthands +-- for index probe queries. + +SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc +FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1 +WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND + a1.amoplefttype = a1.amoprighttype AND + p1.provolatile != 'i' +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amoplefttype" +FILTER: schema="" table="a1" column="amoprighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_amop a1, pg_operator o1, pg_proc p1 WHERE ..." +== 120 +-- truncate_limit: 100 +SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc +FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1 +WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND + a1.amoplefttype != a1.amoprighttype AND + p1.provolatile = 'v' +-- +TABLE: name="pg_amop" schema="" table="pg_amop" ctx=Select +TABLE: name="pg_operator" schema="" table="pg_operator" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amop" +ALIAS: "o1"="pg_operator" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amopopr" +FILTER: schema="" table="o1" column="oid" +FILTER: schema="" table="o1" column="oprcode" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amoplefttype" +FILTER: schema="" table="a1" column="amoprighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_amop a1, pg_operator o1, pg_proc p1 WHERE ..." +== 121 +-- truncate_limit: 100 +-- **************** pg_amproc **************** + +-- Look for illegal values in pg_amproc fields + +SELECT a1.amprocfamily, a1.amprocnum +FROM pg_amproc as a1 +WHERE a1.amprocfamily = 0 OR a1.amproclefttype = 0 OR a1.amprocrighttype = 0 + OR a1.amprocnum < 0 OR a1.amproc = 0 +-- +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +ALIAS: "a1"="pg_amproc" +FILTER: schema="" table="a1" column="amprocfamily" +FILTER: schema="" table="a1" column="amproclefttype" +FILTER: schema="" table="a1" column="amprocrighttype" +FILTER: schema="" table="a1" column="amprocnum" +FILTER: schema="" table="a1" column="amproc" +STMT: SelectStmt +TRUNCATED: "SELECT a1.amprocfamily, a1.amprocnum FROM pg_amproc a1 WHERE ..." +== 122 +-- truncate_limit: 100 +-- Support routines that are primary members of opfamilies must be immutable +-- (else it suggests that the index ordering isn't fixed). But cross-type +-- members need only be stable, since they are just shorthands +-- for index probe queries. + +SELECT a1.amprocfamily, a1.amproc, p1.prosrc +FROM pg_amproc AS a1, pg_proc AS p1 +WHERE a1.amproc = p1.oid AND + a1.amproclefttype = a1.amprocrighttype AND + p1.provolatile != 'i' +-- +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amproc" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amproc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amproclefttype" +FILTER: schema="" table="a1" column="amprocrighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT a1.amprocfamily, a1.amproc, p1.prosrc FROM pg_amproc a1, pg_proc p1 WHERE ..." +== 123 +-- truncate_limit: 100 +SELECT a1.amprocfamily, a1.amproc, p1.prosrc +FROM pg_amproc AS a1, pg_proc AS p1 +WHERE a1.amproc = p1.oid AND + a1.amproclefttype != a1.amprocrighttype AND + p1.provolatile = 'v' +-- +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "a1"="pg_amproc" +ALIAS: "p1"="pg_proc" +FILTER: schema="" table="a1" column="amproc" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="a1" column="amproclefttype" +FILTER: schema="" table="a1" column="amprocrighttype" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT a1.amprocfamily, a1.amproc, p1.prosrc FROM pg_amproc a1, pg_proc p1 WHERE ..." +== 124 +-- truncate_limit: 100 +-- Almost all of the core distribution's Btree opclasses can use one of the +-- two generic "equalimage" functions as their support function 4. Look for +-- opclasses that don't allow deduplication unconditionally here. +|-- +-- Newly added Btree opclasses don't have to support deduplication. It will +-- usually be trivial to add support, though. Note that the expected output +-- of this part of the test will need to be updated when a new opclass cannot +-- support deduplication (by using btequalimage). +SELECT amp.amproc::regproc AS proc, opf.opfname AS opfamily_name, + opc.opcname AS opclass_name, opc.opcintype::regtype AS opcintype +FROM pg_am AS am +JOIN pg_opclass AS opc ON opc.opcmethod = am.oid +JOIN pg_opfamily AS opf ON opc.opcfamily = opf.oid +LEFT JOIN pg_amproc AS amp ON amp.amprocfamily = opf.oid AND + amp.amproclefttype = opc.opcintype AND amp.amprocnum = 4 +WHERE am.amname = 'btree' AND + amp.amproc IS DISTINCT FROM 'btequalimage'::regproc +ORDER BY 1, 2, 3 +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_opfamily" schema="" table="pg_opfamily" ctx=Select +TABLE: name="pg_amproc" schema="" table="pg_amproc" ctx=Select +ALIAS: "am"="pg_am" +ALIAS: "amp"="pg_amproc" +ALIAS: "opc"="pg_opclass" +ALIAS: "opf"="pg_opfamily" +FILTER: schema="" table="am" column="amname" +FILTER: schema="" table="amp" column="amproc" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_am am JOIN pg_opclass opc ON opc.opcmethod = am.oid JOIN pg_opfamily opf ON op..." +== 125 +-- truncate_limit: 100 +-- **************** pg_index **************** + +-- Look for illegal values in pg_index fields. + +SELECT indexrelid, indrelid +FROM pg_index +WHERE indexrelid = 0 OR indrelid = 0 OR + indnatts <= 0 OR indnatts > 32 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FILTER: schema="" table="" column="indexrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indnatts" +STMT: SelectStmt +TRUNCATED: "SELECT indexrelid, indrelid FROM pg_index WHERE ..." +== 126 +-- truncate_limit: 100 +-- oidvector and int2vector fields should be of length indnatts. + +SELECT indexrelid, indrelid +FROM pg_index +WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR + array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR + array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR + array_lower(indoption, 1) != 0 OR array_upper(indoption, 1) != indnatts-1 +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_lower" function="array_lower" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FILTER: schema="" table="" column="indkey" +FILTER: schema="" table="" column="indkey" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indclass" +FILTER: schema="" table="" column="indclass" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indcollation" +FILTER: schema="" table="" column="indcollation" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indoption" +FILTER: schema="" table="" column="indoption" +FILTER: schema="" table="" column="indnatts" +STMT: SelectStmt +TRUNCATED: "SELECT indexrelid, indrelid FROM pg_index WHERE ..." +== 127 +-- truncate_limit: 100 +-- Check that opclasses and collations match the underlying columns. +-- (As written, this test ignores expression indexes.) + +SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname +FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index) ss, + pg_attribute a, + pg_opclass opc +WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND + (NOT binary_coercible(atttypid, opcintype) OR icoll != attcollation) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "opc"="pg_opclass" +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="binary_coercible" function="binary_coercible" schema="" ctx=Call +FILTER: schema="" table="a" column="attrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="" column="ikey" +FILTER: schema="" table="opc" column="oid" +FILTER: schema="" table="" column="iclass" +FILTER: schema="" table="" column="atttypid" +FILTER: schema="" table="" column="opcintype" +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="attcollation" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM pg_index) ss, pg_attribute a, pg_opclass opc WHERE ..." +== 128 +-- truncate_limit: 100 +-- For system catalogs, be even tighter: nearly all indexes should be +-- exact type matches not binary-coercible matches. At this writing +-- the only exception is an OID index on a regproc column. + +SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname +FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index + WHERE indrelid < 16384) ss, + pg_attribute a, + pg_opclass opc +WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND + (opcintype != atttypid OR icoll != attcollation) +ORDER BY 1 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "opc"="pg_opclass" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="a" column="attrelid" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="" column="ikey" +FILTER: schema="" table="opc" column="oid" +FILTER: schema="" table="" column="iclass" +FILTER: schema="" table="" column="opcintype" +FILTER: schema="" table="" column="atttypid" +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="attcollation" +FILTER: schema="" table="" column="indrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM pg_index WHERE ...) ss, pg_attribute a, pg_opclass opc WHERE ......" +== 129 +-- truncate_limit: 100 +-- Check for system catalogs with collation-sensitive ordering. This is not +-- a representational error in pg_index, but simply wrong catalog design. +-- It's bad because we expect to be able to clone template0 and assign the +-- copy a different database collation. It would especially not work for +-- shared catalogs. + +SELECT relname, attname, attcollation +FROM pg_class c, pg_attribute a +WHERE c.oid = attrelid AND c.oid < 16384 AND + c.relkind != 'v' AND -- we don't care about columns in views + attcollation != 0 AND + attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="attrelid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="c" column="relkind" +FILTER: schema="" table="" column="attcollation" +FILTER: schema="" table="" column="attcollation" +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, attname, attcollation FROM pg_class c, pg_attribute a WHERE ..." +== 130 +-- truncate_limit: 100 +-- Double-check that collation-sensitive indexes have "C" collation, too. + +SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll +FROM (SELECT indexrelid, indrelid, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index + WHERE indrelid < 16384) ss +WHERE icoll != 0 AND + icoll != (SELECT oid FROM pg_collation WHERE collname = 'C') +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +TABLE: name="pg_collation" schema="" table="pg_collation" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="icoll" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="collname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM pg_index WHERE ...) ss WHERE ..." diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json new file mode 100644 index 0000000..e6f6795 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json @@ -0,0 +1,139 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.test b/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.test new file mode 100644 index 0000000..5f69390 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.test @@ -0,0 +1,1402 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PARTITION_AGGREGATE +-- Test partitionwise aggregation on partitioned tables +|-- +-- Note: to ensure plan stability, it's a good idea to make the partitions of +-- any one partitioned table in this test all have different numbers of rows. +|-- + +-- Enable partitionwise aggregate, which by default is disabled. +SET enable_partitionwise_aggregate TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_aggregate TO TRUE" +== 002 +-- truncate_limit: 100 +-- Enable partitionwise join, which by default is disabled. +SET enable_partitionwise_join TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO TRUE" +== 003 +-- truncate_limit: 100 +-- Disable parallel plans. +SET max_parallel_workers_per_gather TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 0" +== 004 +-- truncate_limit: 100 +-- Disable incremental sort, which can influence selected plans due to fuzz factor. +SET enable_incremental_sort TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_incremental_sort TO OFF" +== 005 +-- truncate_limit: 100 +|-- +-- Tests for list partitioned tables. +|-- +CREATE TABLE pagg_tab (a int, b int, c text, d int) PARTITION BY LIST(c) +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab (a int, b int, c text, d int) PARTITION BY LIST (c)" +== 006 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_p1 PARTITION OF pagg_tab FOR VALUES IN ('0000', '0001', '0002', '0003', '0004') +-- +TABLE: name="pagg_tab_p1" schema="" table="pagg_tab_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_p1 PARTITION OF pagg_tab FOR VALUES IN ('0000', '0001', '0002', '0003', '00..." +== 007 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_p2 PARTITION OF pagg_tab FOR VALUES IN ('0005', '0006', '0007', '0008') +-- +TABLE: name="pagg_tab_p2" schema="" table="pagg_tab_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_p2 PARTITION OF pagg_tab FOR VALUES IN ('0005', '0006', '0007', '0008')" +== 008 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_p3 PARTITION OF pagg_tab FOR VALUES IN ('0009', '0010', '0011') +-- +TABLE: name="pagg_tab_p3" schema="" table="pagg_tab_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_p3 PARTITION OF pagg_tab FOR VALUES IN ('0009', '0010', '0011')" +== 009 +-- truncate_limit: 100 +INSERT INTO pagg_tab SELECT i % 20, i % 30, to_char(i % 12, 'FM0000'), i % 30 FROM generate_series(0, 2999) i +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_tab SELECT ... FROM generate_series(0, 2999) i" +== 010 +-- truncate_limit: 100 +ANALYZE pagg_tab +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab" +== 011 +-- truncate_limit: 100 +-- When GROUP BY clause matches; full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c H..." +== 012 +-- truncate_limit: 100 +SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3" +== 013 +-- truncate_limit: 100 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a H..." +== 014 +-- truncate_limit: 100 +SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3" +== 015 +-- truncate_limit: 100 +-- Check with multiple columns in GROUP BY +EXPLAIN (COSTS OFF) +SELECT a, c, count(*) FROM pagg_tab GROUP BY a, c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, c, count(*) FROM pagg_tab GROUP BY a, c" +== 016 +-- truncate_limit: 100 +-- Check with multiple columns in GROUP BY, order in GROUP BY is reversed +EXPLAIN (COSTS OFF) +SELECT a, c, count(*) FROM pagg_tab GROUP BY c, a +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, c, count(*) FROM pagg_tab GROUP BY c, a" +== 017 +-- truncate_limit: 100 +-- Check with multiple columns in GROUP BY, order in target-list is reversed +EXPLAIN (COSTS OFF) +SELECT c, a, count(*) FROM pagg_tab GROUP BY a, c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c, a, count(*) FROM pagg_tab GROUP BY a, c" +== 018 +-- truncate_limit: 100 +-- Test when input relation for grouping is dummy +EXPLAIN (COSTS OFF) +SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c" +== 019 +-- truncate_limit: 100 +SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c" +== 020 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c" +== 021 +-- truncate_limit: 100 +SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c" +== 022 +-- truncate_limit: 100 +-- Test GroupAggregate paths by disabling hash aggregates. +SET enable_hashagg TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 023 +-- truncate_limit: 100 +-- When GROUP BY clause matches full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 1..." +== 024 +-- truncate_limit: 100 +SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3" +== 025 +-- truncate_limit: 100 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 1..." +== 026 +-- truncate_limit: 100 +SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3" +== 027 +-- truncate_limit: 100 +-- Test partitionwise grouping without any aggregates +EXPLAIN (COSTS OFF) +SELECT c FROM pagg_tab GROUP BY c ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c FROM pagg_tab GROUP BY c ORDER BY 1" +== 028 +-- truncate_limit: 100 +SELECT c FROM pagg_tab GROUP BY c ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT c FROM pagg_tab GROUP BY c ORDER BY 1" +== 029 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1" +== 030 +-- truncate_limit: 100 +SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1" +== 031 +-- truncate_limit: 100 +RESET enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 032 +-- truncate_limit: 100 +-- ROLLUP, partitionwise aggregation does not apply +EXPLAIN (COSTS OFF) +SELECT c, sum(a) FROM pagg_tab GROUP BY rollup(c) ORDER BY 1, 2 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c, sum(a) FROM pagg_tab GROUP BY ROLLUP (c) ORDER BY 1, 2" +== 033 +-- truncate_limit: 100 +-- ORDERED SET within the aggregate. +-- Full aggregation; since all the rows that belong to the same group come +-- from the same partition, having an ORDER BY within the aggregate doesn't +-- make any difference. +EXPLAIN (COSTS OFF) +SELECT c, sum(b order by a) FROM pagg_tab GROUP BY c ORDER BY 1, 2 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT c, sum(b ORDER BY a) FROM pagg_tab GROUP BY c ORDER BY 1, 2" +== 034 +-- truncate_limit: 100 +-- Since GROUP BY clause does not match with PARTITION KEY; we need to do +-- partial aggregation. However, ORDERED SET are not partial safe and thus +-- partitionwise aggregation plan is not generated. +EXPLAIN (COSTS OFF) +SELECT a, sum(b order by a) FROM pagg_tab GROUP BY a ORDER BY 1, 2 +-- +TABLE: name="pagg_tab" schema="" table="pagg_tab" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b ORDER BY a) FROM pagg_tab GROUP BY a ORDER BY 1, 2" +== 035 +-- truncate_limit: 100 +-- JOIN query + +CREATE TABLE pagg_tab1(x int, y int) PARTITION BY RANGE(x) +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab1 (x int, y int) PARTITION BY RANGE (x)" +== 036 +-- truncate_limit: 100 +CREATE TABLE pagg_tab1_p1 PARTITION OF pagg_tab1 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="pagg_tab1_p1" schema="" table="pagg_tab1_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab1_p1 PARTITION OF pagg_tab1 FOR VALUES FROM (0) TO (10)" +== 037 +-- truncate_limit: 100 +CREATE TABLE pagg_tab1_p2 PARTITION OF pagg_tab1 FOR VALUES FROM (10) TO (20) +-- +TABLE: name="pagg_tab1_p2" schema="" table="pagg_tab1_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab1_p2 PARTITION OF pagg_tab1 FOR VALUES FROM (10) TO (20)" +== 038 +-- truncate_limit: 100 +CREATE TABLE pagg_tab1_p3 PARTITION OF pagg_tab1 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="pagg_tab1_p3" schema="" table="pagg_tab1_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab1_p3 PARTITION OF pagg_tab1 FOR VALUES FROM (20) TO (30)" +== 039 +-- truncate_limit: 100 +CREATE TABLE pagg_tab2(x int, y int) PARTITION BY RANGE(y) +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab2 (x int, y int) PARTITION BY RANGE (y)" +== 040 +-- truncate_limit: 100 +CREATE TABLE pagg_tab2_p1 PARTITION OF pagg_tab2 FOR VALUES FROM (0) TO (10) +-- +TABLE: name="pagg_tab2_p1" schema="" table="pagg_tab2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab2_p1 PARTITION OF pagg_tab2 FOR VALUES FROM (0) TO (10)" +== 041 +-- truncate_limit: 100 +CREATE TABLE pagg_tab2_p2 PARTITION OF pagg_tab2 FOR VALUES FROM (10) TO (20) +-- +TABLE: name="pagg_tab2_p2" schema="" table="pagg_tab2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab2_p2 PARTITION OF pagg_tab2 FOR VALUES FROM (10) TO (20)" +== 042 +-- truncate_limit: 100 +CREATE TABLE pagg_tab2_p3 PARTITION OF pagg_tab2 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="pagg_tab2_p3" schema="" table="pagg_tab2_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab2_p3 PARTITION OF pagg_tab2 FOR VALUES FROM (20) TO (30)" +== 043 +-- truncate_limit: 100 +INSERT INTO pagg_tab1 SELECT i % 30, i % 20 FROM generate_series(0, 299, 2) i +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_tab1 SELECT i % 30, i % 20 FROM generate_series(0, 299, 2) i" +== 044 +-- truncate_limit: 100 +INSERT INTO pagg_tab2 SELECT i % 20, i % 30 FROM generate_series(0, 299, 3) i +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_tab2 SELECT i % 20, i % 30 FROM generate_series(0, 299, 3) i" +== 045 +-- truncate_limit: 100 +ANALYZE pagg_tab1 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab1" +== 046 +-- truncate_limit: 100 +ANALYZE pagg_tab2 +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab2" +== 047 +-- truncate_limit: 100 +-- When GROUP BY clause matches; full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x =..." +== 048 +-- truncate_limit: 100 +SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3" +== 049 +-- truncate_limit: 100 +-- Check with whole-row reference; partitionwise aggregation does not apply +EXPLAIN (COSTS OFF) +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x ..." +== 050 +-- truncate_limit: 100 +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3" +== 051 +-- truncate_limit: 100 +-- GROUP BY having other matching key +EXPLAIN (COSTS OFF) +SELECT t2.y, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t2.y ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t2.y, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x =..." +== 052 +-- truncate_limit: 100 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +-- Also test GroupAggregate paths by disabling hash aggregates. +SET enable_hashagg TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 053 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x =..." +== 054 +-- truncate_limit: 100 +SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "t1"="pagg_tab1" +ALIAS: "t2"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="x" +FILTER: schema="" table="t2" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab1 t1, pagg_tab2 t2 WHERE ... GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY..." +== 055 +-- truncate_limit: 100 +RESET enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 056 +-- truncate_limit: 100 +-- Check with LEFT/RIGHT/FULL OUTER JOINs which produces NULL values for +-- aggregation + +-- LEFT JOIN, should produce partial partitionwise aggregation plan as +-- GROUP BY is on nullable column +EXPLAIN (COSTS OFF) +SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROU..." +== 057 +-- truncate_limit: 100 +SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST" +== 058 +-- truncate_limit: 100 +-- RIGHT JOIN, should produce full partitionwise aggregation plan as +-- GROUP BY is on non-nullable column +EXPLAIN (COSTS OFF) +SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GRO..." +== 059 +-- truncate_limit: 100 +SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST" +== 060 +-- truncate_limit: 100 +-- FULL JOIN, should produce partial partitionwise aggregation plan as +-- GROUP BY is on nullable column +EXPLAIN (COSTS OFF) +SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL JOIN pagg_tab2 b ON a.x = b.y GROU..." +== 061 +-- truncate_limit: 100 +SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +ALIAS: "a"="pagg_tab1" +ALIAS: "b"="pagg_tab2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab1 a FULL JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST" +== 062 +-- truncate_limit: 100 +-- LEFT JOIN, with dummy relation on right side, ideally +-- should produce full partitionwise aggregation plan as GROUP BY is on +-- non-nullable columns. +-- But right now we are unable to do partitionwise join in this case. +EXPLAIN (COSTS OFF) +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT ..." +== 063 +-- truncate_limit: 100 +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM pagg_tab1 WHERE ...) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE ....." +== 064 +-- truncate_limit: 100 +-- FULL JOIN, with dummy relations on both sides, ideally +-- should produce partial partitionwise aggregation plan as GROUP BY is on +-- nullable columns. +-- But right now we are unable to do partitionwise join in this case. +EXPLAIN (COSTS OFF) +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL ..." +== 065 +-- truncate_limit: 100 +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="a" column="x" +FILTER: schema="" table="b" column="y" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM pagg_tab1 WHERE ...) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE ....." +== 066 +-- truncate_limit: 100 +-- Empty join relation because of empty outer side, no partitionwise agg plan +EXPLAIN (COSTS OFF) +SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +ALIAS: "b"="pagg_tab2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2..." +== 067 +-- truncate_limit: 100 +SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2 +-- +TABLE: name="pagg_tab2" schema="" table="pagg_tab2" ctx=Select +TABLE: name="pagg_tab1" schema="" table="pagg_tab1" ctx=Select +ALIAS: "b"="pagg_tab2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM pagg_tab1 WHERE ...) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY..." +== 068 +-- truncate_limit: 100 +-- Partition by multiple columns + +CREATE TABLE pagg_tab_m (a int, b int, c int) PARTITION BY RANGE(a, ((a+b)/2)) +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_m (a int, b int, c int) PARTITION BY RANGE (a, ((a + b) / 2))" +== 069 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_m_p1 PARTITION OF pagg_tab_m FOR VALUES FROM (0, 0) TO (12, 12) +-- +TABLE: name="pagg_tab_m_p1" schema="" table="pagg_tab_m_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_m_p1 PARTITION OF pagg_tab_m FOR VALUES FROM (0, 0) TO (12, 12)" +== 070 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_m_p2 PARTITION OF pagg_tab_m FOR VALUES FROM (12, 12) TO (22, 22) +-- +TABLE: name="pagg_tab_m_p2" schema="" table="pagg_tab_m_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_m_p2 PARTITION OF pagg_tab_m FOR VALUES FROM (12, 12) TO (22, 22)" +== 071 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_m_p3 PARTITION OF pagg_tab_m FOR VALUES FROM (22, 22) TO (30, 30) +-- +TABLE: name="pagg_tab_m_p3" schema="" table="pagg_tab_m_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_m_p3 PARTITION OF pagg_tab_m FOR VALUES FROM (22, 22) TO (30, 30)" +== 072 +-- truncate_limit: 100 +INSERT INTO pagg_tab_m SELECT i % 30, i % 40, i % 50 FROM generate_series(0, 2999) i +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_tab_m SELECT i % 30, i % 40, i % 50 FROM generate_series(0, 2999) i" +== 073 +-- truncate_limit: 100 +ANALYZE pagg_tab_m +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab_m" +== 074 +-- truncate_limit: 100 +-- Partial aggregation as GROUP BY clause does not match with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) <..." +== 075 +-- truncate_limit: 100 +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3" +== 076 +-- truncate_limit: 100 +-- Full aggregation as GROUP BY clause matches with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a + b) / 2 HA..." +== 077 +-- truncate_limit: 100 +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab_m GROUP BY a, (a + b) / 2 HAVING sum(b) < 50 ORDER BY 1, 2, 3" +== 078 +-- truncate_limit: 100 +-- Full aggregation as PARTITION KEY is part of GROUP BY clause +EXPLAIN (COSTS OFF) +SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a + b) / 2, 2..." +== 079 +-- truncate_limit: 100 +SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_m" schema="" table="pagg_tab_m" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab_m GROUP BY (a + b) / 2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY..." +== 080 +-- truncate_limit: 100 +-- Test with multi-level partitioning scheme + +CREATE TABLE pagg_tab_ml (a int, b int, c text) PARTITION BY RANGE(a) +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml (a int, b int, c text) PARTITION BY RANGE (a)" +== 081 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_ml_p1 PARTITION OF pagg_tab_ml FOR VALUES FROM (0) TO (12) +-- +TABLE: name="pagg_tab_ml_p1" schema="" table="pagg_tab_ml_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml_p1 PARTITION OF pagg_tab_ml FOR VALUES FROM (0) TO (12)" +== 082 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_ml_p2 PARTITION OF pagg_tab_ml FOR VALUES FROM (12) TO (20) PARTITION BY LIST (c) +-- +TABLE: name="pagg_tab_ml_p2" schema="" table="pagg_tab_ml_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml_p2 PARTITION OF pagg_tab_ml FOR VALUES FROM (12) TO (20) PARTITION BY LI..." +== 083 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_ml_p2_s1 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0000', '0001', '0002') +-- +TABLE: name="pagg_tab_ml_p2_s1" schema="" table="pagg_tab_ml_p2_s1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml_p2_s1 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0000', '0001', '0002')" +== 084 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_ml_p2_s2 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0003') +-- +TABLE: name="pagg_tab_ml_p2_s2" schema="" table="pagg_tab_ml_p2_s2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml_p2_s2 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0003')" +== 085 +-- truncate_limit: 100 +-- This level of partitioning has different column positions than the parent +CREATE TABLE pagg_tab_ml_p3(b int, c text, a int) PARTITION BY RANGE (b) +-- +TABLE: name="pagg_tab_ml_p3" schema="" table="pagg_tab_ml_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml_p3 (b int, c text, a int) PARTITION BY RANGE (b)" +== 086 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_ml_p3_s1(c text, a int, b int) +-- +TABLE: name="pagg_tab_ml_p3_s1" schema="" table="pagg_tab_ml_p3_s1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml_p3_s1 (c text, a int, b int)" +== 087 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_ml_p3_s2 PARTITION OF pagg_tab_ml_p3 FOR VALUES FROM (7) TO (10) +-- +TABLE: name="pagg_tab_ml_p3_s2" schema="" table="pagg_tab_ml_p3_s2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_ml_p3_s2 PARTITION OF pagg_tab_ml_p3 FOR VALUES FROM (7) TO (10)" +== 088 +-- truncate_limit: 100 +ALTER TABLE pagg_tab_ml_p3 ATTACH PARTITION pagg_tab_ml_p3_s1 FOR VALUES FROM (0) TO (7) +-- +TABLE: name="pagg_tab_ml_p3" schema="" table="pagg_tab_ml_p3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pagg_tab_ml_p3 ATTACH PARTITION pagg_tab_ml_p3_s1 FOR VALUES FROM (0) TO (7)" +== 089 +-- truncate_limit: 100 +ALTER TABLE pagg_tab_ml ATTACH PARTITION pagg_tab_ml_p3 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pagg_tab_ml ATTACH PARTITION pagg_tab_ml_p3 FOR VALUES FROM (20) TO (30)" +== 090 +-- truncate_limit: 100 +INSERT INTO pagg_tab_ml SELECT i % 30, i % 10, to_char(i % 4, 'FM0000') FROM generate_series(0, 29999) i +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_tab_ml SELECT ... FROM generate_series(0, 29999) i" +== 091 +-- truncate_limit: 100 +ANALYZE pagg_tab_ml +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab_ml" +== 092 +-- truncate_limit: 100 +-- For Parallel Append +SET max_parallel_workers_per_gather TO 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 093 +-- truncate_limit: 100 +SET parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 094 +-- truncate_limit: 100 +-- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY +-- for level 1 only. For subpartitions, GROUP BY clause does not match with +-- PARTITION KEY, but still we do not see a partial aggregation as array_agg() +-- is not partial agg safe. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), array_agg(DISTINCT c), count(*) FROM pagg_tab_ml GROUP BY a..." +== 095 +-- truncate_limit: 100 +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3" +== 096 +-- truncate_limit: 100 +-- Without ORDER BY clause, to test Gather at top-most path +EXPLAIN (COSTS OFF) +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), array_agg(DISTINCT c), count(*) FROM pagg_tab_ml GROUP BY a..." +== 097 +-- truncate_limit: 100 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 098 +-- truncate_limit: 100 +-- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY +-- for level 1 only. For subpartitions, GROUP BY clause does not match with +-- PARTITION KEY, thus we will have a partial aggregation for them. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDE..." +== 099 +-- truncate_limit: 100 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3" +== 100 +-- truncate_limit: 100 +-- Partial aggregation at all levels as GROUP BY clause does not match with +-- PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3" +== 101 +-- truncate_limit: 100 +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3" +== 102 +-- truncate_limit: 100 +-- Full aggregation at all levels as GROUP BY clause matches with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > ..." +== 103 +-- truncate_limit: 100 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3" +== 104 +-- truncate_limit: 100 +-- Parallelism within partitionwise aggregates + +SET min_parallel_table_scan_size TO '8kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO \"8kB\"" +== 105 +-- truncate_limit: 100 +SET parallel_setup_cost TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 106 +-- truncate_limit: 100 +-- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY +-- for level 1 only. For subpartitions, GROUP BY clause does not match with +-- PARTITION KEY, thus we will have a partial aggregation for them. +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDE..." +== 107 +-- truncate_limit: 100 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3" +== 108 +-- truncate_limit: 100 +-- Partial aggregation at all levels as GROUP BY clause does not match with +-- PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3" +== 109 +-- truncate_limit: 100 +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3" +== 110 +-- truncate_limit: 100 +-- Full aggregation at all levels as GROUP BY clause matches with PARTITION KEY +EXPLAIN (COSTS OFF) +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > ..." +== 111 +-- truncate_limit: 100 +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_ml" schema="" table="pagg_tab_ml" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3" +== 112 +-- truncate_limit: 100 +-- Parallelism within partitionwise aggregates (single level) + +-- Add few parallel setup cost, so that we will see a plan which gathers +-- partially created paths even for full aggregation and sticks a single Gather +-- followed by finalization step. +-- Without this, the cost of doing partial aggregation + Gather + finalization +-- for each partition and then Append over it turns out to be same and this +-- wins as we add it first. This parallel_setup_cost plays a vital role in +-- costing such plans. +SET parallel_setup_cost TO 10 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 10" +== 113 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_para(x int, y int) PARTITION BY RANGE(x) +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_para (x int, y int) PARTITION BY RANGE (x)" +== 114 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_para_p1 PARTITION OF pagg_tab_para FOR VALUES FROM (0) TO (12) +-- +TABLE: name="pagg_tab_para_p1" schema="" table="pagg_tab_para_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_para_p1 PARTITION OF pagg_tab_para FOR VALUES FROM (0) TO (12)" +== 115 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_para_p2 PARTITION OF pagg_tab_para FOR VALUES FROM (12) TO (22) +-- +TABLE: name="pagg_tab_para_p2" schema="" table="pagg_tab_para_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_para_p2 PARTITION OF pagg_tab_para FOR VALUES FROM (12) TO (22)" +== 116 +-- truncate_limit: 100 +CREATE TABLE pagg_tab_para_p3 PARTITION OF pagg_tab_para FOR VALUES FROM (22) TO (30) +-- +TABLE: name="pagg_tab_para_p3" schema="" table="pagg_tab_para_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pagg_tab_para_p3 PARTITION OF pagg_tab_para FOR VALUES FROM (22) TO (30)" +== 117 +-- truncate_limit: 100 +INSERT INTO pagg_tab_para SELECT i % 30, i % 20 FROM generate_series(0, 29999) i +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pagg_tab_para SELECT i % 30, i % 20 FROM generate_series(0, 29999) i" +== 118 +-- truncate_limit: 100 +ANALYZE pagg_tab_para +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab_para" +== 119 +-- truncate_limit: 100 +-- When GROUP BY clause matches; full aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y..." +== 120 +-- truncate_limit: 100 +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3" +== 121 +-- truncate_limit: 100 +-- When GROUP BY clause does not match; partial aggregation is performed for each partition. +EXPLAIN (COSTS OFF) +SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x..." +== 122 +-- truncate_limit: 100 +SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3" +== 123 +-- truncate_limit: 100 +-- Test when parent can produce parallel paths but not any (or some) of its children +-- (Use one more aggregate to tilt the cost estimates for the plan we want) +ALTER TABLE pagg_tab_para_p1 SET (parallel_workers = 0) +-- +TABLE: name="pagg_tab_para_p1" schema="" table="pagg_tab_para_p1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pagg_tab_para_p1 SET (parallel_workers=0)" +== 124 +-- truncate_limit: 100 +ALTER TABLE pagg_tab_para_p3 SET (parallel_workers = 0) +-- +TABLE: name="pagg_tab_para_p3" schema="" table="pagg_tab_para_p3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pagg_tab_para_p3 SET (parallel_workers=0)" +== 125 +-- truncate_limit: 100 +ANALYZE pagg_tab_para +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab_para" +== 126 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x, sum(y), avg(y), sum(x + y), count(*) FROM pagg_tab_para GROUP BY x ..." +== 127 +-- truncate_limit: 100 +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3" +== 128 +-- truncate_limit: 100 +ALTER TABLE pagg_tab_para_p2 SET (parallel_workers = 0) +-- +TABLE: name="pagg_tab_para_p2" schema="" table="pagg_tab_para_p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pagg_tab_para_p2 SET (parallel_workers=0)" +== 129 +-- truncate_limit: 100 +ANALYZE pagg_tab_para +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pagg_tab_para" +== 130 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x, sum(y), avg(y), sum(x + y), count(*) FROM pagg_tab_para GROUP BY x ..." +== 131 +-- truncate_limit: 100 +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3" +== 132 +-- truncate_limit: 100 +-- Reset parallelism parameters to get partitionwise aggregation plan. +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_table_scan_size" +== 133 +-- truncate_limit: 100 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 134 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y..." +== 135 +-- truncate_limit: 100 +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3 +-- +TABLE: name="pagg_tab_para" schema="" table="pagg_tab_para" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3" diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json new file mode 100644 index 0000000..2ff9db8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json @@ -0,0 +1,77 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_info.test b/parser/testdata/summary_truncate/postgres_regress/partition_info.test new file mode 100644 index 0000000..fec655c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_info.test @@ -0,0 +1,571 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for functions providing information about partitions +|-- +SELECT * FROM pg_partition_tree(NULL) +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_tree(NULL)" +== 002 +-- truncate_limit: 100 +SELECT * FROM pg_partition_tree(0) +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_tree(0)" +== 003 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors(NULL) +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors(NULL)" +== 004 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors(0) +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors(0)" +== 005 +-- truncate_limit: 100 +SELECT pg_partition_root(NULL) +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root(NULL)" +== 006 +-- truncate_limit: 100 +SELECT pg_partition_root(0) +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root(0)" +== 007 +-- truncate_limit: 100 +-- Test table partition trees +CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a) +-- +TABLE: name="ptif_test" schema="" table="ptif_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_test (a int, b int) PARTITION BY RANGE (a)" +== 008 +-- truncate_limit: 100 +CREATE TABLE ptif_test0 PARTITION OF ptif_test + FOR VALUES FROM (minvalue) TO (0) PARTITION BY list (b) +-- +TABLE: name="ptif_test0" schema="" table="ptif_test0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_test0 PARTITION OF ptif_test FOR VALUES FROM (minvalue) TO (0) PARTITION BY LIS..." +== 009 +-- truncate_limit: 100 +CREATE TABLE ptif_test01 PARTITION OF ptif_test0 FOR VALUES IN (1) +-- +TABLE: name="ptif_test01" schema="" table="ptif_test01" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_test01 PARTITION OF ptif_test0 FOR VALUES IN (1)" +== 010 +-- truncate_limit: 100 +CREATE TABLE ptif_test1 PARTITION OF ptif_test + FOR VALUES FROM (0) TO (100) PARTITION BY list (b) +-- +TABLE: name="ptif_test1" schema="" table="ptif_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_test1 PARTITION OF ptif_test FOR VALUES FROM (0) TO (100) PARTITION BY LIST (b)" +== 011 +-- truncate_limit: 100 +CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1) +-- +TABLE: name="ptif_test11" schema="" table="ptif_test11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1)" +== 012 +-- truncate_limit: 100 +CREATE TABLE ptif_test2 PARTITION OF ptif_test + FOR VALUES FROM (100) TO (200) +-- +TABLE: name="ptif_test2" schema="" table="ptif_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_test2 PARTITION OF ptif_test FOR VALUES FROM (100) TO (200)" +== 013 +-- truncate_limit: 100 +-- This partitioned table should remain with no partitions. +CREATE TABLE ptif_test3 PARTITION OF ptif_test + FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b) +-- +TABLE: name="ptif_test3" schema="" table="ptif_test3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_test3 PARTITION OF ptif_test FOR VALUES FROM (200) TO (maxvalue) PARTITION BY L..." +== 014 +-- truncate_limit: 100 +-- Test pg_partition_root for tables +SELECT pg_partition_root('ptif_test') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test')" +== 015 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test0') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test0')" +== 016 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test01') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test01')" +== 017 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test3') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test3')" +== 018 +-- truncate_limit: 100 +-- Test index partition tree +CREATE INDEX ptif_test_index ON ONLY ptif_test (a) +-- +TABLE: name="ptif_test" schema="" table="ptif_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptif_test_index ON ONLY ptif_test USING btree (a)" +== 019 +-- truncate_limit: 100 +CREATE INDEX ptif_test0_index ON ONLY ptif_test0 (a) +-- +TABLE: name="ptif_test0" schema="" table="ptif_test0" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptif_test0_index ON ONLY ptif_test0 USING btree (a)" +== 020 +-- truncate_limit: 100 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test0_index +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test0_index" +== 021 +-- truncate_limit: 100 +CREATE INDEX ptif_test01_index ON ptif_test01 (a) +-- +TABLE: name="ptif_test01" schema="" table="ptif_test01" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptif_test01_index ON ptif_test01 USING btree (a)" +== 022 +-- truncate_limit: 100 +ALTER INDEX ptif_test0_index ATTACH PARTITION ptif_test01_index +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX ptif_test0_index ATTACH PARTITION ptif_test01_index" +== 023 +-- truncate_limit: 100 +CREATE INDEX ptif_test1_index ON ONLY ptif_test1 (a) +-- +TABLE: name="ptif_test1" schema="" table="ptif_test1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptif_test1_index ON ONLY ptif_test1 USING btree (a)" +== 024 +-- truncate_limit: 100 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test1_index +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test1_index" +== 025 +-- truncate_limit: 100 +CREATE INDEX ptif_test11_index ON ptif_test11 (a) +-- +TABLE: name="ptif_test11" schema="" table="ptif_test11" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptif_test11_index ON ptif_test11 USING btree (a)" +== 026 +-- truncate_limit: 100 +ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index" +== 027 +-- truncate_limit: 100 +CREATE INDEX ptif_test2_index ON ptif_test2 (a) +-- +TABLE: name="ptif_test2" schema="" table="ptif_test2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptif_test2_index ON ptif_test2 USING btree (a)" +== 028 +-- truncate_limit: 100 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index" +== 029 +-- truncate_limit: 100 +CREATE INDEX ptif_test3_index ON ptif_test3 (a) +-- +TABLE: name="ptif_test3" schema="" table="ptif_test3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ptif_test3_index ON ptif_test3 USING btree (a)" +== 030 +-- truncate_limit: 100 +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index" +== 031 +-- truncate_limit: 100 +-- Test pg_partition_root for indexes +SELECT pg_partition_root('ptif_test_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test_index')" +== 032 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test0_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test0_index')" +== 033 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test01_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test01_index')" +== 034 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test3_index') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test3_index')" +== 035 +-- truncate_limit: 100 +-- List all tables members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT relid, parentrelid, level, isleaf FROM pg_partition_tree('ptif_test')" +== 036 +-- truncate_limit: 100 +-- List tables from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('ptif_test0') p JOIN pg_class c ON p.relid = c.oid" +== 037 +-- truncate_limit: 100 +-- List from leaf table +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('ptif_test01') p JOIN pg_class c ON p.relid = c.oid" +== 038 +-- truncate_limit: 100 +-- List from partitioned table with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('ptif_test3') p JOIN pg_class c ON p.relid = c.oid" +== 039 +-- truncate_limit: 100 +-- List all ancestors of root and leaf tables +SELECT * FROM pg_partition_ancestors('ptif_test01') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_test01')" +== 040 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors('ptif_test') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_test')" +== 041 +-- truncate_limit: 100 +-- List all members using pg_partition_root with leaf table reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01')) p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree(pg_partition_root('ptif_test01')) p JOIN pg_class c ON p.relid ..." +== 042 +-- truncate_limit: 100 +-- List all indexes members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test_index') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT relid, parentrelid, level, isleaf FROM pg_partition_tree('ptif_test_index')" +== 043 +-- truncate_limit: 100 +-- List indexes from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0_index') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('ptif_test0_index') p JOIN pg_class c ON p.relid = c.oid" +== 044 +-- truncate_limit: 100 +-- List from leaf index +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01_index') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('ptif_test01_index') p JOIN pg_class c ON p.relid = c.oid" +== 045 +-- truncate_limit: 100 +-- List from partitioned index with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3_index') p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('ptif_test3_index') p JOIN pg_class c ON p.relid = c.oid" +== 046 +-- truncate_limit: 100 +-- List all members using pg_partition_root with leaf index reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p + JOIN pg_class c ON (p.relid = c.oid) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p JOIN pg_class c ON p...." +== 047 +-- truncate_limit: 100 +-- List all ancestors of root and leaf indexes +SELECT * FROM pg_partition_ancestors('ptif_test01_index') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_test01_index')" +== 048 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors('ptif_test_index') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_test_index')" +== 049 +-- truncate_limit: 100 +DROP TABLE ptif_test +-- +TABLE: name="ptif_test" schema="" table="ptif_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ptif_test" +== 050 +-- truncate_limit: 100 +-- Table that is not part of any partition tree is not listed. +CREATE TABLE ptif_normal_table(a int) +-- +TABLE: name="ptif_normal_table" schema="" table="ptif_normal_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_normal_table (a int)" +== 051 +-- truncate_limit: 100 +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_normal_table') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT relid, parentrelid, level, isleaf FROM pg_partition_tree('ptif_normal_table')" +== 052 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors('ptif_normal_table') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_normal_table')" +== 053 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_normal_table') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_normal_table')" +== 054 +-- truncate_limit: 100 +DROP TABLE ptif_normal_table +-- +TABLE: name="ptif_normal_table" schema="" table="ptif_normal_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ptif_normal_table" +== 055 +-- truncate_limit: 100 +-- Various partitioning-related functions return empty/NULL if passed relations +-- of types that cannot be part of a partition tree; for example, views, +-- materialized views, legacy inheritance children or parents, etc. +CREATE VIEW ptif_test_view AS SELECT 1 +-- +TABLE: name="ptif_test_view" schema="" table="ptif_test_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ptif_test_view AS SELECT 1" +== 056 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW ptif_test_matview AS SELECT 1 +-- +TABLE: name="ptif_test_matview" schema="" table="ptif_test_matview" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW ptif_test_matview AS SELECT 1" +== 057 +-- truncate_limit: 100 +CREATE TABLE ptif_li_parent () +-- +TABLE: name="ptif_li_parent" schema="" table="ptif_li_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_li_parent ()" +== 058 +-- truncate_limit: 100 +CREATE TABLE ptif_li_child () INHERITS (ptif_li_parent) +-- +TABLE: name="ptif_li_child" schema="" table="ptif_li_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ptif_li_child () INHERITS (ptif_li_parent)" +== 059 +-- truncate_limit: 100 +SELECT * FROM pg_partition_tree('ptif_test_view') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_tree('ptif_test_view')" +== 060 +-- truncate_limit: 100 +SELECT * FROM pg_partition_tree('ptif_test_matview') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_tree('ptif_test_matview')" +== 061 +-- truncate_limit: 100 +SELECT * FROM pg_partition_tree('ptif_li_parent') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_tree('ptif_li_parent')" +== 062 +-- truncate_limit: 100 +SELECT * FROM pg_partition_tree('ptif_li_child') +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_tree('ptif_li_child')" +== 063 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors('ptif_test_view') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_test_view')" +== 064 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors('ptif_test_matview') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_test_matview')" +== 065 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors('ptif_li_parent') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_li_parent')" +== 066 +-- truncate_limit: 100 +SELECT * FROM pg_partition_ancestors('ptif_li_child') +-- +FUNCTION: name="pg_partition_ancestors" function="pg_partition_ancestors" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_partition_ancestors('ptif_li_child')" +== 067 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test_view') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test_view')" +== 068 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_test_matview') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_test_matview')" +== 069 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_li_parent') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_li_parent')" +== 070 +-- truncate_limit: 100 +SELECT pg_partition_root('ptif_li_child') +-- +FUNCTION: name="pg_partition_root" function="pg_partition_root" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_partition_root('ptif_li_child')" +== 071 +-- truncate_limit: 100 +DROP VIEW ptif_test_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW ptif_test_view" +== 072 +-- truncate_limit: 100 +DROP MATERIALIZED VIEW ptif_test_matview +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW ptif_test_matview" +== 073 +-- truncate_limit: 100 +DROP TABLE ptif_li_parent, ptif_li_child +-- +TABLE: name="ptif_li_parent" schema="" table="ptif_li_parent" ctx=DDL +TABLE: name="ptif_li_child" schema="" table="ptif_li_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ptif_li_parent, ptif_li_child" diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json new file mode 100644 index 0000000..6fa7813 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json @@ -0,0 +1,604 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_join.test b/parser/testdata/summary_truncate/postgres_regress/partition_join.test new file mode 100644 index 0000000..4052a50 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_join.test @@ -0,0 +1,6115 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PARTITION_JOIN +-- Test partitionwise join between partitioned tables +|-- + +-- Enable partitionwise join, which by default is disabled. +SET enable_partitionwise_join to true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO TRUE" +== 002 +-- truncate_limit: 100 +|-- +-- partitioned by a single column +|-- +CREATE TABLE prt1 (a int, b int, c varchar) PARTITION BY RANGE(a) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1 (a int, b int, c varchar) PARTITION BY RANGE (a)" +== 003 +-- truncate_limit: 100 +CREATE TABLE prt1_p1 PARTITION OF prt1 FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt1_p1" schema="" table="prt1_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_p1 PARTITION OF prt1 FOR VALUES FROM (0) TO (250)" +== 004 +-- truncate_limit: 100 +CREATE TABLE prt1_p3 PARTITION OF prt1 FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt1_p3" schema="" table="prt1_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_p3 PARTITION OF prt1 FOR VALUES FROM (500) TO (600)" +== 005 +-- truncate_limit: 100 +CREATE TABLE prt1_p2 PARTITION OF prt1 FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt1_p2" schema="" table="prt1_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_p2 PARTITION OF prt1 FOR VALUES FROM (250) TO (500)" +== 006 +-- truncate_limit: 100 +INSERT INTO prt1 SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 2 = 0 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt1 SELECT ... FROM generate_series(0, 599) i WHERE (i % 2) = 0" +== 007 +-- truncate_limit: 100 +CREATE INDEX iprt1_p1_a on prt1_p1(a) +-- +TABLE: name="prt1_p1" schema="" table="prt1_p1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt1_p1_a ON prt1_p1 USING btree (a)" +== 008 +-- truncate_limit: 100 +CREATE INDEX iprt1_p2_a on prt1_p2(a) +-- +TABLE: name="prt1_p2" schema="" table="prt1_p2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt1_p2_a ON prt1_p2 USING btree (a)" +== 009 +-- truncate_limit: 100 +CREATE INDEX iprt1_p3_a on prt1_p3(a) +-- +TABLE: name="prt1_p3" schema="" table="prt1_p3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt1_p3_a ON prt1_p3 USING btree (a)" +== 010 +-- truncate_limit: 100 +ANALYZE prt1 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1" +== 011 +-- truncate_limit: 100 +CREATE TABLE prt2 (a int, b int, c varchar) PARTITION BY RANGE(b) +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2 (a int, b int, c varchar) PARTITION BY RANGE (b)" +== 012 +-- truncate_limit: 100 +CREATE TABLE prt2_p1 PARTITION OF prt2 FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt2_p1" schema="" table="prt2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_p1 PARTITION OF prt2 FOR VALUES FROM (0) TO (250)" +== 013 +-- truncate_limit: 100 +CREATE TABLE prt2_p2 PARTITION OF prt2 FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt2_p2" schema="" table="prt2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_p2 PARTITION OF prt2 FOR VALUES FROM (250) TO (500)" +== 014 +-- truncate_limit: 100 +CREATE TABLE prt2_p3 PARTITION OF prt2 FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt2_p3" schema="" table="prt2_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_p3 PARTITION OF prt2 FOR VALUES FROM (500) TO (600)" +== 015 +-- truncate_limit: 100 +INSERT INTO prt2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 3 = 0 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2 SELECT ... FROM generate_series(0, 599) i WHERE (i % 3) = 0" +== 016 +-- truncate_limit: 100 +CREATE INDEX iprt2_p1_b on prt2_p1(b) +-- +TABLE: name="prt2_p1" schema="" table="prt2_p1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt2_p1_b ON prt2_p1 USING btree (b)" +== 017 +-- truncate_limit: 100 +CREATE INDEX iprt2_p2_b on prt2_p2(b) +-- +TABLE: name="prt2_p2" schema="" table="prt2_p2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt2_p2_b ON prt2_p2 USING btree (b)" +== 018 +-- truncate_limit: 100 +CREATE INDEX iprt2_p3_b on prt2_p3(b) +-- +TABLE: name="prt2_p3" schema="" table="prt2_p3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt2_p3_b ON prt2_p3 USING btree (b)" +== 019 +-- truncate_limit: 100 +ANALYZE prt2 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2" +== 020 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1...." +== 021 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE ... ORDER BY t1.a, t2.b" +== 022 +-- truncate_limit: 100 +-- left outer join, 3-way +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 t1 LEFT JOIN prt1 t2 ON t1.a = t2.a LEFT JOIN prt1 ..." +== 023 +-- truncate_limit: 100 +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM prt1 t1 LEFT JOIN prt1 t2 ON t1.a = t2.a LEFT JOIN prt1 t3 ON t2.a = t3.a" +== 024 +-- truncate_limit: 100 +-- left outer join, with whole-row reference; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 OR..." +== 025 +-- truncate_limit: 100 +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b" +== 026 +-- truncate_limit: 100 +-- right outer join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b ..." +== 027 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b" +== 028 +-- truncate_limit: 100 +-- full outer join, with placeholder vars +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 AS phv, * FROM prt1 WHERE prt1...." +== 029 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM prt1 WHERE ...) t1 FULL JOIN (SELECT ... FROM prt2 WHERE ...) t2..." +== 030 +-- truncate_limit: 100 +-- Join with pruned partitions from joining relations +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1...." +== 031 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE ... ORDER BY t1.a, t2.b" +== 032 +-- truncate_limit: 100 +-- Currently we can't do partitioned join if nullable-side partitions are pruned +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT..." +== 033 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM prt1 WHERE ...) t1 LEFT JOIN (SELECT * FROM prt2 WHERE ...) t2 ON ..." +== 034 +-- truncate_limit: 100 +-- Currently we can't do partitioned join if nullable-side partitions are pruned +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL..." +== 035 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM prt1 WHERE ...) t1 FULL JOIN (SELECT * FROM prt2 WHERE ...) t2 ON ..." +== 036 +-- truncate_limit: 100 +-- Semi-join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a =..." +== 037 +-- truncate_limit: 100 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1 t1 WHERE ... ORDER BY t1.a" +== 038 +-- truncate_limit: 100 +-- Anti-join with aggregates +EXPLAIN (COSTS OFF) +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXIS..." +== 039 +-- truncate_limit: 100 +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE ..." +== 040 +-- truncate_limit: 100 +-- lateral reference +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM prt1 t1 LEFT JOIN LATERAL (SELECT t2.a AS t2a, t3.a AS t3a, LEA..." +== 041 +-- truncate_limit: 100 +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM prt1 t1 LEFT JOIN LATERAL (SELECT ... FROM prt1 t2 JOIN prt2 t3 ON t2.a = t3.b) ss ..." +== 042 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="ss" column="t2b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL (SELECT t2.a AS t2..." +== 043 +-- truncate_limit: 100 +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="ss" column="t2b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 t1 LEFT JOIN LATERAL (SELECT ... FROM prt1 t2 JOIN prt2 t3 ON t2.a = t3.b) s..." +== 044 +-- truncate_limit: 100 +-- lateral reference in sample scan +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 JOIN LATERAL + (SELECT * FROM prt1 t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM prt1 t1 JOIN LATERAL (SELECT * FROM prt1 t2 TABLESAMPLE system(..." +== 045 +-- truncate_limit: 100 +-- lateral reference in scan's restriction clauses +EXPLAIN (COSTS OFF) +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL (SELECT t1.b AS t1b, t2.* FROM..." +== 046 +-- truncate_limit: 100 +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL (SELECT ... FROM prt2 t2) s ON t1.a = s.b WHERE ..." +== 047 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL (SELECT t1.b AS t1b, t2.* FROM..." +== 048 +-- truncate_limit: 100 +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL (SELECT ... FROM prt2 t2) s ON t1.a = s.b WHERE ..." +== 049 +-- truncate_limit: 100 +-- bug with inadequate sort key representation +SET enable_partitionwise_aggregate TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_aggregate TO TRUE" +== 050 +-- truncate_limit: 100 +SET enable_hashjoin TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO FALSE" +== 051 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b FROM prt1 FULL JOIN prt2 p2(b, a, c) USING (a, b) WHERE a BETWEEN..." +== 052 +-- truncate_limit: 100 +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM prt1 FULL JOIN prt2 p2(b, a, c) USING (a, b) WHERE ... GROUP BY 1, 2 ORDER BY 1, 2" +== 053 +-- truncate_limit: 100 +RESET enable_partitionwise_aggregate +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_partitionwise_aggregate" +== 054 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 055 +-- truncate_limit: 100 +-- bug in freeing the SpecialJoinInfo of a child-join +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 JOIN prt1 t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM prt1 t3) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt1" +ALIAS: "t3"="prt1" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM prt1 t1 JOIN prt1 t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FRO..." +== 056 +-- truncate_limit: 100 +|-- +-- partitioned by expression +|-- +CREATE TABLE prt1_e (a int, b int, c int) PARTITION BY RANGE(((a + b)/2)) +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_e (a int, b int, c int) PARTITION BY RANGE (((a + b) / 2))" +== 057 +-- truncate_limit: 100 +CREATE TABLE prt1_e_p1 PARTITION OF prt1_e FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt1_e_p1" schema="" table="prt1_e_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_e_p1 PARTITION OF prt1_e FOR VALUES FROM (0) TO (250)" +== 058 +-- truncate_limit: 100 +CREATE TABLE prt1_e_p2 PARTITION OF prt1_e FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt1_e_p2" schema="" table="prt1_e_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_e_p2 PARTITION OF prt1_e FOR VALUES FROM (250) TO (500)" +== 059 +-- truncate_limit: 100 +CREATE TABLE prt1_e_p3 PARTITION OF prt1_e FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt1_e_p3" schema="" table="prt1_e_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_e_p3 PARTITION OF prt1_e FOR VALUES FROM (500) TO (600)" +== 060 +-- truncate_limit: 100 +INSERT INTO prt1_e SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt1_e SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i" +== 061 +-- truncate_limit: 100 +CREATE INDEX iprt1_e_p1_ab2 on prt1_e_p1(((a+b)/2)) +-- +TABLE: name="prt1_e_p1" schema="" table="prt1_e_p1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt1_e_p1_ab2 ON prt1_e_p1 USING btree (((a + b) / 2))" +== 062 +-- truncate_limit: 100 +CREATE INDEX iprt1_e_p2_ab2 on prt1_e_p2(((a+b)/2)) +-- +TABLE: name="prt1_e_p2" schema="" table="prt1_e_p2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt1_e_p2_ab2 ON prt1_e_p2 USING btree (((a + b) / 2))" +== 063 +-- truncate_limit: 100 +CREATE INDEX iprt1_e_p3_ab2 on prt1_e_p3(((a+b)/2)) +-- +TABLE: name="prt1_e_p3" schema="" table="prt1_e_p3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX iprt1_e_p3_ab2 ON prt1_e_p3 USING btree (((a + b) / 2))" +== 064 +-- truncate_limit: 100 +ANALYZE prt1_e +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_e" +== 065 +-- truncate_limit: 100 +CREATE TABLE prt2_e (a int, b int, c int) PARTITION BY RANGE(((b + a)/2)) +-- +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_e (a int, b int, c int) PARTITION BY RANGE (((b + a) / 2))" +== 066 +-- truncate_limit: 100 +CREATE TABLE prt2_e_p1 PARTITION OF prt2_e FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt2_e_p1" schema="" table="prt2_e_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_e_p1 PARTITION OF prt2_e FOR VALUES FROM (0) TO (250)" +== 067 +-- truncate_limit: 100 +CREATE TABLE prt2_e_p2 PARTITION OF prt2_e FOR VALUES FROM (250) TO (500) +-- +TABLE: name="prt2_e_p2" schema="" table="prt2_e_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_e_p2 PARTITION OF prt2_e FOR VALUES FROM (250) TO (500)" +== 068 +-- truncate_limit: 100 +CREATE TABLE prt2_e_p3 PARTITION OF prt2_e FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt2_e_p3" schema="" table="prt2_e_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_e_p3 PARTITION OF prt2_e FOR VALUES FROM (500) TO (600)" +== 069 +-- truncate_limit: 100 +INSERT INTO prt2_e SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i +-- +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_e SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i" +== 070 +-- truncate_limit: 100 +ANALYZE prt2_e +-- +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_e" +== 071 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=Select +ALIAS: "t1"="prt1_e" +ALIAS: "t2"="prt2_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE ((t1.a + t1.b) ..." +== 072 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +TABLE: name="prt2_e" schema="" table="prt2_e" ctx=Select +ALIAS: "t1"="prt1_e" +ALIAS: "t2"="prt2_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE ... ORDER BY t1.a, t2.b" +== 073 +-- truncate_limit: 100 +|-- +-- N-way join +|-- +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_..." +== 074 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 t1, prt2 t2, prt1_e t3 WHERE ... ORDER BY t1.a, t2.b" +== 075 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1 LEFT JOIN prt2 ..." +== 076 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b LEFT JOIN prt1_e t3 ON t1.a = ((t3.a + t..." +== 077 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1 LEFT JOIN prt2 ..." +== 078 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b RIGHT JOIN prt1_e t3 ON t1.a = ((t3.a + ..." +== 079 +-- truncate_limit: 100 +|-- +-- 3-way full join +|-- +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 FULL JOIN prt2 p2(b, a, c) USING (a, b) FULL JOIN p..." +== 080 +-- truncate_limit: 100 +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 FULL JOIN prt2 p2(b, a, c) USING (a, b) FULL JOIN prt2 p3(b, a, c) USING (a,..." +== 081 +-- truncate_limit: 100 +|-- +-- 4-way full join +|-- +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +ALIAS: "p4"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 FULL JOIN prt2 p2(b, a, c) USING (a, b) FULL JOIN p..." +== 082 +-- truncate_limit: 100 +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "p2"="prt2" +ALIAS: "p3"="prt2" +ALIAS: "p4"="prt1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 FULL JOIN prt2 p2(b, a, c) USING (a, b) FULL JOIN prt2 p3(b, a, c) USING (a,..." +== 083 +-- truncate_limit: 100 +-- Cases with non-nullable expressions in subquery results; +-- make sure these go to null as expected +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t3" column="phv" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +FILTER: schema="" table="prt1_e" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM (SELECT 50 AS phv..." +== 084 +-- truncate_limit: 100 +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="t3" column="b" +FILTER: schema="" table="t3" column="phv" +FILTER: schema="" table="prt1" column="b" +FILTER: schema="" table="prt2" column="a" +FILTER: schema="" table="prt1_e" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM prt1 WHERE ...) t1 FULL JOIN (SELECT ... FROM prt2 WHERE ...) t2..." +== 085 +-- truncate_limit: 100 +-- Semi-join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt2" +ALIAS: "t2"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 W..." +== 086 +-- truncate_limit: 100 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt2" +ALIAS: "t2"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1 t1 WHERE ... ORDER BY t1.a" +== 087 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b I..." +== 088 +-- truncate_limit: 100 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1 t1 WHERE ... ORDER BY t1.a" +== 089 +-- truncate_limit: 100 +-- test merge joins +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 090 +-- truncate_limit: 100 +SET enable_nestloop TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 091 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b I..." +== 092 +-- truncate_limit: 100 +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1_e" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1 t1 WHERE ... ORDER BY t1.a" +== 093 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1 LEFT JOIN prt2 ..." +== 094 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1_e" schema="" table="prt1_e" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1_e" +FILTER: schema="" table="t3" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b RIGHT JOIN prt1_e t3 ON t1.a = ((t3.a + ..." +== 095 +-- truncate_limit: 100 +-- MergeAppend on nullable column +-- This should generate a partitionwise join, but currently fails to +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELEC..." +== 096 +-- truncate_limit: 100 +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM prt1 WHERE ...) t1 LEFT JOIN (SELECT * FROM prt2 WHERE ...) t2 ON ..." +== 097 +-- truncate_limit: 100 +-- merge join when expression with whole-row reference needs to be sorted; +-- partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="" column="t1" +FILTER: schema="" table="" column="t2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = ..." +== 098 +-- truncate_limit: 100 +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="" column="t1" +FILTER: schema="" table="" column="t2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a" +== 099 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 100 +-- truncate_limit: 100 +RESET enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 101 +-- truncate_limit: 100 +|-- +-- partitioned by multiple columns +|-- +CREATE TABLE prt1_m (a int, b int, c int) PARTITION BY RANGE(a, ((a + b)/2)) +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_m (a int, b int, c int) PARTITION BY RANGE (a, ((a + b) / 2))" +== 102 +-- truncate_limit: 100 +CREATE TABLE prt1_m_p1 PARTITION OF prt1_m FOR VALUES FROM (0, 0) TO (250, 250) +-- +TABLE: name="prt1_m_p1" schema="" table="prt1_m_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_m_p1 PARTITION OF prt1_m FOR VALUES FROM (0, 0) TO (250, 250)" +== 103 +-- truncate_limit: 100 +CREATE TABLE prt1_m_p2 PARTITION OF prt1_m FOR VALUES FROM (250, 250) TO (500, 500) +-- +TABLE: name="prt1_m_p2" schema="" table="prt1_m_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_m_p2 PARTITION OF prt1_m FOR VALUES FROM (250, 250) TO (500, 500)" +== 104 +-- truncate_limit: 100 +CREATE TABLE prt1_m_p3 PARTITION OF prt1_m FOR VALUES FROM (500, 500) TO (600, 600) +-- +TABLE: name="prt1_m_p3" schema="" table="prt1_m_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_m_p3 PARTITION OF prt1_m FOR VALUES FROM (500, 500) TO (600, 600)" +== 105 +-- truncate_limit: 100 +INSERT INTO prt1_m SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt1_m SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i" +== 106 +-- truncate_limit: 100 +ANALYZE prt1_m +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_m" +== 107 +-- truncate_limit: 100 +CREATE TABLE prt2_m (a int, b int, c int) PARTITION BY RANGE(((b + a)/2), b) +-- +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_m (a int, b int, c int) PARTITION BY RANGE (((b + a) / 2), b)" +== 108 +-- truncate_limit: 100 +CREATE TABLE prt2_m_p1 PARTITION OF prt2_m FOR VALUES FROM (0, 0) TO (250, 250) +-- +TABLE: name="prt2_m_p1" schema="" table="prt2_m_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_m_p1 PARTITION OF prt2_m FOR VALUES FROM (0, 0) TO (250, 250)" +== 109 +-- truncate_limit: 100 +CREATE TABLE prt2_m_p2 PARTITION OF prt2_m FOR VALUES FROM (250, 250) TO (500, 500) +-- +TABLE: name="prt2_m_p2" schema="" table="prt2_m_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_m_p2 PARTITION OF prt2_m FOR VALUES FROM (250, 250) TO (500, 500)" +== 110 +-- truncate_limit: 100 +CREATE TABLE prt2_m_p3 PARTITION OF prt2_m FOR VALUES FROM (500, 500) TO (600, 600) +-- +TABLE: name="prt2_m_p3" schema="" table="prt2_m_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_m_p3 PARTITION OF prt2_m FOR VALUES FROM (500, 500) TO (600, 600)" +== 111 +-- truncate_limit: 100 +INSERT INTO prt2_m SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i +-- +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_m SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i" +== 112 +-- truncate_limit: 100 +ANALYZE prt2_m +-- +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_m" +== 113 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +FILTER: schema="" table="prt1_m" column="c" +FILTER: schema="" table="prt2_m" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) ..." +== 114 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +FILTER: schema="" table="prt1_m" column="c" +FILTER: schema="" table="prt2_m" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM prt1_m WHERE ...) t1 FULL JOIN (SELECT * FROM prt2_m WHERE ...) t2..." +== 115 +-- truncate_limit: 100 +|-- +-- tests for list partitioned tables. +|-- +CREATE TABLE plt1 (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1 (a int, b int, c text) PARTITION BY LIST (c)" +== 116 +-- truncate_limit: 100 +CREATE TABLE plt1_p1 PARTITION OF plt1 FOR VALUES IN ('0000', '0003', '0004', '0010') +-- +TABLE: name="plt1_p1" schema="" table="plt1_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_p1 PARTITION OF plt1 FOR VALUES IN ('0000', '0003', '0004', '0010')" +== 117 +-- truncate_limit: 100 +CREATE TABLE plt1_p2 PARTITION OF plt1 FOR VALUES IN ('0001', '0005', '0002', '0009') +-- +TABLE: name="plt1_p2" schema="" table="plt1_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_p2 PARTITION OF plt1 FOR VALUES IN ('0001', '0005', '0002', '0009')" +== 118 +-- truncate_limit: 100 +CREATE TABLE plt1_p3 PARTITION OF plt1 FOR VALUES IN ('0006', '0007', '0008', '0011') +-- +TABLE: name="plt1_p3" schema="" table="plt1_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_p3 PARTITION OF plt1 FOR VALUES IN ('0006', '0007', '0008', '0011')" +== 119 +-- truncate_limit: 100 +INSERT INTO plt1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1 SELECT i, i, to_char(i / 50, 'FM0000') FROM generate_series(0, 599, 2) i" +== 120 +-- truncate_limit: 100 +ANALYZE plt1 +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1" +== 121 +-- truncate_limit: 100 +CREATE TABLE plt2 (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2 (a int, b int, c text) PARTITION BY LIST (c)" +== 122 +-- truncate_limit: 100 +CREATE TABLE plt2_p1 PARTITION OF plt2 FOR VALUES IN ('0000', '0003', '0004', '0010') +-- +TABLE: name="plt2_p1" schema="" table="plt2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_p1 PARTITION OF plt2 FOR VALUES IN ('0000', '0003', '0004', '0010')" +== 123 +-- truncate_limit: 100 +CREATE TABLE plt2_p2 PARTITION OF plt2 FOR VALUES IN ('0001', '0005', '0002', '0009') +-- +TABLE: name="plt2_p2" schema="" table="plt2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_p2 PARTITION OF plt2 FOR VALUES IN ('0001', '0005', '0002', '0009')" +== 124 +-- truncate_limit: 100 +CREATE TABLE plt2_p3 PARTITION OF plt2 FOR VALUES IN ('0006', '0007', '0008', '0011') +-- +TABLE: name="plt2_p3" schema="" table="plt2_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_p3 PARTITION OF plt2 FOR VALUES IN ('0006', '0007', '0008', '0011')" +== 125 +-- truncate_limit: 100 +INSERT INTO plt2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2 SELECT i, i, to_char(i / 50, 'FM0000') FROM generate_series(0, 599, 3) i" +== 126 +-- truncate_limit: 100 +ANALYZE plt2 +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2" +== 127 +-- truncate_limit: 100 +|-- +-- list partitioned by expression +|-- +CREATE TABLE plt1_e (a int, b int, c text) PARTITION BY LIST(ltrim(c, 'A')) +-- +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_e (a int, b int, c text) PARTITION BY LIST ((ltrim(c, 'A')))" +== 128 +-- truncate_limit: 100 +CREATE TABLE plt1_e_p1 PARTITION OF plt1_e FOR VALUES IN ('0000', '0003', '0004', '0010') +-- +TABLE: name="plt1_e_p1" schema="" table="plt1_e_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_e_p1 PARTITION OF plt1_e FOR VALUES IN ('0000', '0003', '0004', '0010')" +== 129 +-- truncate_limit: 100 +CREATE TABLE plt1_e_p2 PARTITION OF plt1_e FOR VALUES IN ('0001', '0005', '0002', '0009') +-- +TABLE: name="plt1_e_p2" schema="" table="plt1_e_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_e_p2 PARTITION OF plt1_e FOR VALUES IN ('0001', '0005', '0002', '0009')" +== 130 +-- truncate_limit: 100 +CREATE TABLE plt1_e_p3 PARTITION OF plt1_e FOR VALUES IN ('0006', '0007', '0008', '0011') +-- +TABLE: name="plt1_e_p3" schema="" table="plt1_e_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_e_p3 PARTITION OF plt1_e FOR VALUES IN ('0006', '0007', '0008', '0011')" +== 131 +-- truncate_limit: 100 +INSERT INTO plt1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_e SELECT i, i, 'A' || to_char(i / 50, 'FM0000') FROM generate_series(0, 599, 2) i" +== 132 +-- truncate_limit: 100 +ANALYZE plt1_e +-- +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_e" +== 133 +-- truncate_limit: 100 +-- test partition matching with N-way join +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="plt1" schema="" table="plt1" ctx=Select +TABLE: name="plt2" schema="" table="plt2" ctx=Select +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=Select +ALIAS: "t1"="plt1" +ALIAS: "t2"="plt2" +ALIAS: "t3"="plt1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1,..." +== 134 +-- truncate_limit: 100 +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="plt1" schema="" table="plt1" ctx=Select +TABLE: name="plt2" schema="" table="plt2" ctx=Select +TABLE: name="plt1_e" schema="" table="plt1_e" ctx=Select +ALIAS: "t1"="plt1" +ALIAS: "t2"="plt2" +ALIAS: "t3"="plt1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1 t1, plt2 t2, plt1_e t3 WHERE ... GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2..." +== 135 +-- truncate_limit: 100 +-- joins where one of the relations is proven empty +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a = 1 AND t1.a = 2 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1...." +== 136 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 LEFT JOIN prt2 t2 ON t1.a = t2.b +-- +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t2"="prt2" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2)..." +== 137 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b, prt1 t3 WHERE t2.b = t3.a +-- +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t2"="prt2" +ALIAS: "t3"="prt1" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t3" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2)..." +== 138 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 FULL JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt2" schema="" table="prt2" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t2"="prt2" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2)..." +== 139 +-- truncate_limit: 100 +|-- +-- tests for hash partitioned tables. +|-- +CREATE TABLE pht1 (a int, b int, c text) PARTITION BY HASH(c) +-- +TABLE: name="pht1" schema="" table="pht1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1 (a int, b int, c text) PARTITION BY HASH (c)" +== 140 +-- truncate_limit: 100 +CREATE TABLE pht1_p1 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 0) +-- +TABLE: name="pht1_p1" schema="" table="pht1_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1_p1 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 0)" +== 141 +-- truncate_limit: 100 +CREATE TABLE pht1_p2 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 1) +-- +TABLE: name="pht1_p2" schema="" table="pht1_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1_p2 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 1)" +== 142 +-- truncate_limit: 100 +CREATE TABLE pht1_p3 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="pht1_p3" schema="" table="pht1_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1_p3 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 2)" +== 143 +-- truncate_limit: 100 +INSERT INTO pht1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="pht1" schema="" table="pht1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pht1 SELECT i, i, to_char(i / 50, 'FM0000') FROM generate_series(0, 599, 2) i" +== 144 +-- truncate_limit: 100 +ANALYZE pht1 +-- +TABLE: name="pht1" schema="" table="pht1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pht1" +== 145 +-- truncate_limit: 100 +CREATE TABLE pht2 (a int, b int, c text) PARTITION BY HASH(c) +-- +TABLE: name="pht2" schema="" table="pht2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht2 (a int, b int, c text) PARTITION BY HASH (c)" +== 146 +-- truncate_limit: 100 +CREATE TABLE pht2_p1 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 0) +-- +TABLE: name="pht2_p1" schema="" table="pht2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht2_p1 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 0)" +== 147 +-- truncate_limit: 100 +CREATE TABLE pht2_p2 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 1) +-- +TABLE: name="pht2_p2" schema="" table="pht2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht2_p2 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 1)" +== 148 +-- truncate_limit: 100 +CREATE TABLE pht2_p3 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="pht2_p3" schema="" table="pht2_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht2_p3 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 2)" +== 149 +-- truncate_limit: 100 +INSERT INTO pht2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i +-- +TABLE: name="pht2" schema="" table="pht2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pht2 SELECT i, i, to_char(i / 50, 'FM0000') FROM generate_series(0, 599, 3) i" +== 150 +-- truncate_limit: 100 +ANALYZE pht2 +-- +TABLE: name="pht2" schema="" table="pht2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pht2" +== 151 +-- truncate_limit: 100 +|-- +-- hash partitioned by expression +|-- +CREATE TABLE pht1_e (a int, b int, c text) PARTITION BY HASH(ltrim(c, 'A')) +-- +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1_e (a int, b int, c text) PARTITION BY HASH ((ltrim(c, 'A')))" +== 152 +-- truncate_limit: 100 +CREATE TABLE pht1_e_p1 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 0) +-- +TABLE: name="pht1_e_p1" schema="" table="pht1_e_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1_e_p1 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 0)" +== 153 +-- truncate_limit: 100 +CREATE TABLE pht1_e_p2 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 1) +-- +TABLE: name="pht1_e_p2" schema="" table="pht1_e_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1_e_p2 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 1)" +== 154 +-- truncate_limit: 100 +CREATE TABLE pht1_e_p3 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 2) +-- +TABLE: name="pht1_e_p3" schema="" table="pht1_e_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pht1_e_p3 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 2)" +== 155 +-- truncate_limit: 100 +INSERT INTO pht1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 299, 2) i +-- +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pht1_e SELECT i, i, 'A' || to_char(i / 50, 'FM0000') FROM generate_series(0, 299, 2) i" +== 156 +-- truncate_limit: 100 +ANALYZE pht1_e +-- +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pht1_e" +== 157 +-- truncate_limit: 100 +-- test partition matching with N-way join +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="pht1" schema="" table="pht1" ctx=Select +TABLE: name="pht2" schema="" table="pht2" ctx=Select +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=Select +ALIAS: "t1"="pht1" +ALIAS: "t2"="pht2" +ALIAS: "t3"="pht1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1,..." +== 158 +-- truncate_limit: 100 +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c +-- +TABLE: name="pht1" schema="" table="pht1" ctx=Select +TABLE: name="pht2" schema="" table="pht2" ctx=Select +TABLE: name="pht1_e" schema="" table="pht1_e" ctx=Select +ALIAS: "t1"="pht1" +ALIAS: "t2"="pht2" +ALIAS: "t3"="pht1_e" +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="ltrim" function="ltrim" schema="" ctx=Call +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t3" column="c" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pht1 t1, pht2 t2, pht1_e t3 WHERE ... GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2..." +== 159 +-- truncate_limit: 100 +-- test default partition behavior for range +ALTER TABLE prt1 DETACH PARTITION prt1_p3 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt1 DETACH PARTITION prt1_p3" +== 160 +-- truncate_limit: 100 +ALTER TABLE prt1 ATTACH PARTITION prt1_p3 DEFAULT +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt1 ATTACH PARTITION prt1_p3 DEFAULT" +== 161 +-- truncate_limit: 100 +ANALYZE prt1 +-- +TABLE: name="prt1" schema="" table="prt1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1" +== 162 +-- truncate_limit: 100 +ALTER TABLE prt2 DETACH PARTITION prt2_p3 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt2 DETACH PARTITION prt2_p3" +== 163 +-- truncate_limit: 100 +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 DEFAULT +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt2 ATTACH PARTITION prt2_p3 DEFAULT" +== 164 +-- truncate_limit: 100 +ANALYZE prt2 +-- +TABLE: name="prt2" schema="" table="prt2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2" +== 165 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1...." +== 166 +-- truncate_limit: 100 +-- test default partition behavior for list +ALTER TABLE plt1 DETACH PARTITION plt1_p3 +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt1 DETACH PARTITION plt1_p3" +== 167 +-- truncate_limit: 100 +ALTER TABLE plt1 ATTACH PARTITION plt1_p3 DEFAULT +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt1 ATTACH PARTITION plt1_p3 DEFAULT" +== 168 +-- truncate_limit: 100 +ANALYZE plt1 +-- +TABLE: name="plt1" schema="" table="plt1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1" +== 169 +-- truncate_limit: 100 +ALTER TABLE plt2 DETACH PARTITION plt2_p3 +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2 DETACH PARTITION plt2_p3" +== 170 +-- truncate_limit: 100 +ALTER TABLE plt2 ATTACH PARTITION plt2_p3 DEFAULT +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2 ATTACH PARTITION plt2_p3 DEFAULT" +== 171 +-- truncate_limit: 100 +ANALYZE plt2 +-- +TABLE: name="plt2" schema="" table="plt2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2" +== 172 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), t1.c, t2.c FROM plt1 t1 RIGHT JOIN plt2 t2 ON t1.c = t2.c WHERE t1.a % 25 = 0 GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c +-- +TABLE: name="plt1" schema="" table="plt1" ctx=Select +TABLE: name="plt2" schema="" table="plt2" ctx=Select +ALIAS: "t1"="plt1" +ALIAS: "t2"="plt2" +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT avg(t1.a), avg(t2.b), t1.c, t2.c FROM plt1 t1 RIGHT JOIN plt2 t2 ON t1..." +== 173 +-- truncate_limit: 100 +|-- +-- multiple levels of partitioning +|-- +CREATE TABLE prt1_l (a int, b int, c varchar) PARTITION BY RANGE(a) +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l (a int, b int, c varchar) PARTITION BY RANGE (a)" +== 174 +-- truncate_limit: 100 +CREATE TABLE prt1_l_p1 PARTITION OF prt1_l FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt1_l_p1" schema="" table="prt1_l_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l_p1 PARTITION OF prt1_l FOR VALUES FROM (0) TO (250)" +== 175 +-- truncate_limit: 100 +CREATE TABLE prt1_l_p2 PARTITION OF prt1_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c) +-- +TABLE: name="prt1_l_p2" schema="" table="prt1_l_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l_p2 PARTITION OF prt1_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c)" +== 176 +-- truncate_limit: 100 +CREATE TABLE prt1_l_p2_p1 PARTITION OF prt1_l_p2 FOR VALUES IN ('0000', '0001') +-- +TABLE: name="prt1_l_p2_p1" schema="" table="prt1_l_p2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l_p2_p1 PARTITION OF prt1_l_p2 FOR VALUES IN ('0000', '0001')" +== 177 +-- truncate_limit: 100 +CREATE TABLE prt1_l_p2_p2 PARTITION OF prt1_l_p2 FOR VALUES IN ('0002', '0003') +-- +TABLE: name="prt1_l_p2_p2" schema="" table="prt1_l_p2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l_p2_p2 PARTITION OF prt1_l_p2 FOR VALUES IN ('0002', '0003')" +== 178 +-- truncate_limit: 100 +CREATE TABLE prt1_l_p3 PARTITION OF prt1_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (b) +-- +TABLE: name="prt1_l_p3" schema="" table="prt1_l_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l_p3 PARTITION OF prt1_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (b)" +== 179 +-- truncate_limit: 100 +CREATE TABLE prt1_l_p3_p1 PARTITION OF prt1_l_p3 FOR VALUES FROM (0) TO (13) +-- +TABLE: name="prt1_l_p3_p1" schema="" table="prt1_l_p3_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l_p3_p1 PARTITION OF prt1_l_p3 FOR VALUES FROM (0) TO (13)" +== 180 +-- truncate_limit: 100 +CREATE TABLE prt1_l_p3_p2 PARTITION OF prt1_l_p3 FOR VALUES FROM (13) TO (25) +-- +TABLE: name="prt1_l_p3_p2" schema="" table="prt1_l_p3_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_l_p3_p2 PARTITION OF prt1_l_p3 FOR VALUES FROM (13) TO (25)" +== 181 +-- truncate_limit: 100 +INSERT INTO prt1_l SELECT i, i % 25, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt1_l SELECT i, i % 25, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 2) i" +== 182 +-- truncate_limit: 100 +ANALYZE prt1_l +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_l" +== 183 +-- truncate_limit: 100 +CREATE TABLE prt2_l (a int, b int, c varchar) PARTITION BY RANGE(b) +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l (a int, b int, c varchar) PARTITION BY RANGE (b)" +== 184 +-- truncate_limit: 100 +CREATE TABLE prt2_l_p1 PARTITION OF prt2_l FOR VALUES FROM (0) TO (250) +-- +TABLE: name="prt2_l_p1" schema="" table="prt2_l_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l_p1 PARTITION OF prt2_l FOR VALUES FROM (0) TO (250)" +== 185 +-- truncate_limit: 100 +CREATE TABLE prt2_l_p2 PARTITION OF prt2_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c) +-- +TABLE: name="prt2_l_p2" schema="" table="prt2_l_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l_p2 PARTITION OF prt2_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c)" +== 186 +-- truncate_limit: 100 +CREATE TABLE prt2_l_p2_p1 PARTITION OF prt2_l_p2 FOR VALUES IN ('0000', '0001') +-- +TABLE: name="prt2_l_p2_p1" schema="" table="prt2_l_p2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l_p2_p1 PARTITION OF prt2_l_p2 FOR VALUES IN ('0000', '0001')" +== 187 +-- truncate_limit: 100 +CREATE TABLE prt2_l_p2_p2 PARTITION OF prt2_l_p2 FOR VALUES IN ('0002', '0003') +-- +TABLE: name="prt2_l_p2_p2" schema="" table="prt2_l_p2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l_p2_p2 PARTITION OF prt2_l_p2 FOR VALUES IN ('0002', '0003')" +== 188 +-- truncate_limit: 100 +CREATE TABLE prt2_l_p3 PARTITION OF prt2_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (a) +-- +TABLE: name="prt2_l_p3" schema="" table="prt2_l_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l_p3 PARTITION OF prt2_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (a)" +== 189 +-- truncate_limit: 100 +CREATE TABLE prt2_l_p3_p1 PARTITION OF prt2_l_p3 FOR VALUES FROM (0) TO (13) +-- +TABLE: name="prt2_l_p3_p1" schema="" table="prt2_l_p3_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l_p3_p1 PARTITION OF prt2_l_p3 FOR VALUES FROM (0) TO (13)" +== 190 +-- truncate_limit: 100 +CREATE TABLE prt2_l_p3_p2 PARTITION OF prt2_l_p3 FOR VALUES FROM (13) TO (25) +-- +TABLE: name="prt2_l_p3_p2" schema="" table="prt2_l_p3_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_l_p3_p2 PARTITION OF prt2_l_p3 FOR VALUES FROM (13) TO (25)" +== 191 +-- truncate_limit: 100 +INSERT INTO prt2_l SELECT i % 25, i, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 3) i +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_l SELECT i % 25, i, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 3) i" +== 192 +-- truncate_limit: 100 +ANALYZE prt2_l +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_l" +== 193 +-- truncate_limit: 100 +-- inner join, qual covering only top-level partitions +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND..." +== 194 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE ... ORDER BY t1.a, t2.b" +== 195 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2..." +== 196 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE ... ORDER BY t..." +== 197 +-- truncate_limit: 100 +-- right join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t..." +== 198 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="t2" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE ... ORDER BY ..." +== 199 +-- truncate_limit: 100 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +FILTER: schema="" table="prt1_l" column="b" +FILTER: schema="" table="prt2_l" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) ..." +== 200 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +FILTER: schema="" table="prt1_l" column="b" +FILTER: schema="" table="prt2_l" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM prt1_l WHERE ...) t1 FULL JOIN (SELECT * FROM prt2_l WHERE ...) t2..." +== 201 +-- truncate_limit: 100 +-- lateral partitionwise join +EXPLAIN (COSTS OFF) +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt1_l" +ALIAS: "t3"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM prt1_l t1 LEFT JOIN LATERAL (SELECT t2.a AS t2a, t2.c AS t2c, t..." +== 202 +-- truncate_limit: 100 +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt1_l" +ALIAS: "t3"="prt2_l" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM prt1_l t1 LEFT JOIN LATERAL (SELECT ... FROM prt1_l t2 JOIN prt2_l t3 ON t2.a = t3...." +== 203 +-- truncate_limit: 100 +-- partitionwise join with lateral reference in sample scan +EXPLAIN (COSTS OFF) +SELECT * FROM prt1_l t1 JOIN LATERAL + (SELECT * FROM prt1_l t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a AND t1.b = s.b AND t1.c = s.c +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt1_l" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM prt1_l t1 JOIN LATERAL (SELECT * FROM prt1_l t2 TABLESAMPLE sys..." +== 204 +-- truncate_limit: 100 +-- partitionwise join with lateral reference in scan's restriction clauses +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1_l t1 LEFT JOIN LATERAL (SELECT t1.b AS t1b, t2.* FR..." +== 205 +-- truncate_limit: 100 +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +ALIAS: "t1"="prt1_l" +ALIAS: "t2"="prt2_l" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="s" column="t1b" +FILTER: schema="" table="s" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_l t1 LEFT JOIN LATERAL (SELECT ... FROM prt2_l t2) s ON t1.a = s.b AND t1.b ..." +== 206 +-- truncate_limit: 100 +-- join with one side empty +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c +-- +TABLE: name="prt2_l" schema="" table="prt2_l" ctx=Select +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=Select +ALIAS: "t2"="prt2_l" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = ..." +== 207 +-- truncate_limit: 100 +-- Test case to verify proper handling of subqueries in a partitioned delete. +-- The weird-looking lateral join is just there to force creation of a +-- nestloop parameter within the subquery, which exposes the problem if the +-- planner fails to make multiple copies of the subquery as appropriate. +EXPLAIN (COSTS OFF) +DELETE FROM prt1_l +WHERE EXISTS ( + SELECT 1 + FROM int4_tbl, + LATERAL (SELECT int4_tbl.f1 FROM int8_tbl LIMIT 2) ss + WHERE prt1_l.c IS NULL) +-- +TABLE: name="prt1_l" schema="" table="prt1_l" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="prt1_l" column="c" +STMT: ExplainStmt +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM prt1_l WHERE EXISTS (SELECT 1 FROM int4_tbl, LATERAL (SELECT int4..." +== 208 +-- truncate_limit: 100 +|-- +-- negative testcases +|-- +CREATE TABLE prt1_n (a int, b int, c varchar) PARTITION BY RANGE(c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_n (a int, b int, c varchar) PARTITION BY RANGE (c)" +== 209 +-- truncate_limit: 100 +CREATE TABLE prt1_n_p1 PARTITION OF prt1_n FOR VALUES FROM ('0000') TO ('0250') +-- +TABLE: name="prt1_n_p1" schema="" table="prt1_n_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_n_p1 PARTITION OF prt1_n FOR VALUES FROM ('0000') TO ('0250')" +== 210 +-- truncate_limit: 100 +CREATE TABLE prt1_n_p2 PARTITION OF prt1_n FOR VALUES FROM ('0250') TO ('0500') +-- +TABLE: name="prt1_n_p2" schema="" table="prt1_n_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_n_p2 PARTITION OF prt1_n FOR VALUES FROM ('0250') TO ('0500')" +== 211 +-- truncate_limit: 100 +INSERT INTO prt1_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 499, 2) i +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt1_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 499, 2) i" +== 212 +-- truncate_limit: 100 +ANALYZE prt1_n +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_n" +== 213 +-- truncate_limit: 100 +CREATE TABLE prt2_n (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_n (a int, b int, c text) PARTITION BY LIST (c)" +== 214 +-- truncate_limit: 100 +CREATE TABLE prt2_n_p1 PARTITION OF prt2_n FOR VALUES IN ('0000', '0003', '0004', '0010', '0006', '0007') +-- +TABLE: name="prt2_n_p1" schema="" table="prt2_n_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_n_p1 PARTITION OF prt2_n FOR VALUES IN ('0000', '0003', '0004', '0010', '0006',..." +== 215 +-- truncate_limit: 100 +CREATE TABLE prt2_n_p2 PARTITION OF prt2_n FOR VALUES IN ('0001', '0005', '0002', '0009', '0008', '0011') +-- +TABLE: name="prt2_n_p2" schema="" table="prt2_n_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_n_p2 PARTITION OF prt2_n FOR VALUES IN ('0001', '0005', '0002', '0009', '0008',..." +== 216 +-- truncate_limit: 100 +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_n SELECT i, i, to_char(i / 50, 'FM0000') FROM generate_series(0, 599, 2) i" +== 217 +-- truncate_limit: 100 +ANALYZE prt2_n +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_n" +== 218 +-- truncate_limit: 100 +CREATE TABLE prt3_n (a int, b int, c text) PARTITION BY LIST(c) +-- +TABLE: name="prt3_n" schema="" table="prt3_n" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt3_n (a int, b int, c text) PARTITION BY LIST (c)" +== 219 +-- truncate_limit: 100 +CREATE TABLE prt3_n_p1 PARTITION OF prt3_n FOR VALUES IN ('0000', '0004', '0006', '0007') +-- +TABLE: name="prt3_n_p1" schema="" table="prt3_n_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt3_n_p1 PARTITION OF prt3_n FOR VALUES IN ('0000', '0004', '0006', '0007')" +== 220 +-- truncate_limit: 100 +CREATE TABLE prt3_n_p2 PARTITION OF prt3_n FOR VALUES IN ('0001', '0002', '0008', '0010') +-- +TABLE: name="prt3_n_p2" schema="" table="prt3_n_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt3_n_p2 PARTITION OF prt3_n FOR VALUES IN ('0001', '0002', '0008', '0010')" +== 221 +-- truncate_limit: 100 +CREATE TABLE prt3_n_p3 PARTITION OF prt3_n FOR VALUES IN ('0003', '0005', '0009', '0011') +-- +TABLE: name="prt3_n_p3" schema="" table="prt3_n_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt3_n_p3 PARTITION OF prt3_n FOR VALUES IN ('0003', '0005', '0009', '0011')" +== 222 +-- truncate_limit: 100 +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_n SELECT i, i, to_char(i / 50, 'FM0000') FROM generate_series(0, 599, 2) i" +== 223 +-- truncate_limit: 100 +ANALYZE prt3_n +-- +TABLE: name="prt3_n" schema="" table="prt3_n" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt3_n" +== 224 +-- truncate_limit: 100 +CREATE TABLE prt4_n (a int, b int, c text) PARTITION BY RANGE(a) +-- +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt4_n (a int, b int, c text) PARTITION BY RANGE (a)" +== 225 +-- truncate_limit: 100 +CREATE TABLE prt4_n_p1 PARTITION OF prt4_n FOR VALUES FROM (0) TO (300) +-- +TABLE: name="prt4_n_p1" schema="" table="prt4_n_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt4_n_p1 PARTITION OF prt4_n FOR VALUES FROM (0) TO (300)" +== 226 +-- truncate_limit: 100 +CREATE TABLE prt4_n_p2 PARTITION OF prt4_n FOR VALUES FROM (300) TO (500) +-- +TABLE: name="prt4_n_p2" schema="" table="prt4_n_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt4_n_p2 PARTITION OF prt4_n FOR VALUES FROM (300) TO (500)" +== 227 +-- truncate_limit: 100 +CREATE TABLE prt4_n_p3 PARTITION OF prt4_n FOR VALUES FROM (500) TO (600) +-- +TABLE: name="prt4_n_p3" schema="" table="prt4_n_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt4_n_p3 PARTITION OF prt4_n FOR VALUES FROM (500) TO (600)" +== 228 +-- truncate_limit: 100 +INSERT INTO prt4_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 599, 2) i +-- +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt4_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 599, 2) i" +== 229 +-- truncate_limit: 100 +ANALYZE prt4_n +-- +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt4_n" +== 230 +-- truncate_limit: 100 +-- partitionwise join can not be applied if the partition ranges differ +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2 WHERE t1.a = t2.a +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt4_n" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2 WHERE t1.a = t2.a" +== 231 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2, prt2 t3 WHERE t1.a = t2.a and t1.a = t3.b +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt4_n" schema="" table="prt4_n" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt4_n" +ALIAS: "t3"="prt2" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t3" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2, prt2 t3 WHERE t1.a = t..." +== 232 +-- truncate_limit: 100 +-- partitionwise join can not be applied if there are no equi-join conditions +-- between partition keys +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 LEFT JOIN prt2 t2 ON (t1.a < t2.b) +-- +TABLE: name="prt1" schema="" table="prt1" ctx=Select +TABLE: name="prt2" schema="" table="prt2" ctx=Select +ALIAS: "t1"="prt1" +ALIAS: "t2"="prt2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a < t2.b" +== 233 +-- truncate_limit: 100 +-- equi-join with join condition on partial keys does not qualify for +-- partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1, prt2_m t2 WHERE t1.a = (t2.b + t2.a)/2 +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +ALIAS: "t1"="prt1_m" +ALIAS: "t2"="prt2_m" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1, prt2_m t2 WHERE t1.a = ((t2.b +..." +== 234 +-- truncate_limit: 100 +-- equi-join between out-of-order partition key columns does not qualify for +-- partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.a = t2.b +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +ALIAS: "t1"="prt1_m" +ALIAS: "t2"="prt2_m" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.a = t2.b" +== 235 +-- truncate_limit: 100 +-- equi-join between non-key columns does not qualify for partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.c = t2.c +-- +TABLE: name="prt1_m" schema="" table="prt1_m" ctx=Select +TABLE: name="prt2_m" schema="" table="prt2_m" ctx=Select +ALIAS: "t1"="prt1_m" +ALIAS: "t2"="prt2_m" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.c = t2.c" +== 236 +-- truncate_limit: 100 +-- partitionwise join can not be applied for a join between list and range +-- partitioned tables +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 LEFT JOIN prt2_n t2 ON (t1.c = t2.c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=Select +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=Select +ALIAS: "t1"="prt1_n" +ALIAS: "t2"="prt2_n" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 LEFT JOIN prt2_n t2 ON t1.c = t2.c" +== 237 +-- truncate_limit: 100 +-- partitionwise join can not be applied between tables with different +-- partition lists +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 JOIN prt2_n t2 ON (t1.c = t2.c) JOIN plt1 t3 ON (t1.c = t3.c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=Select +TABLE: name="prt2_n" schema="" table="prt2_n" ctx=Select +TABLE: name="plt1" schema="" table="plt1" ctx=Select +ALIAS: "t1"="prt1_n" +ALIAS: "t2"="prt2_n" +ALIAS: "t3"="plt1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 JOIN prt2_n t2 ON t1.c = t2.c JO..." +== 238 +-- truncate_limit: 100 +-- partitionwise join can not be applied for a join between key column and +-- non-key column +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON (t1.c = t2.c) +-- +TABLE: name="prt1_n" schema="" table="prt1_n" ctx=Select +TABLE: name="prt1" schema="" table="prt1" ctx=Select +ALIAS: "t1"="prt1_n" +ALIAS: "t2"="prt1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON t1.c = t2.c" +== 239 +-- truncate_limit: 100 +|-- +-- Test some other plan types in a partitionwise join (unfortunately, +-- we need larger tables to get the planner to choose these plan types) +|-- +create temp table prtx1 (a integer, b integer, c integer) + partition by range (a) +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx1 (a int, b int, c int) PARTITION BY RANGE (a)" +== 240 +-- truncate_limit: 100 +create temp table prtx1_1 partition of prtx1 for values from (1) to (11) +-- +TABLE: name="prtx1_1" schema="" table="prtx1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx1_1 PARTITION OF prtx1 FOR VALUES FROM (1) TO (11)" +== 241 +-- truncate_limit: 100 +create temp table prtx1_2 partition of prtx1 for values from (11) to (21) +-- +TABLE: name="prtx1_2" schema="" table="prtx1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx1_2 PARTITION OF prtx1 FOR VALUES FROM (11) TO (21)" +== 242 +-- truncate_limit: 100 +create temp table prtx1_3 partition of prtx1 for values from (21) to (31) +-- +TABLE: name="prtx1_3" schema="" table="prtx1_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx1_3 PARTITION OF prtx1 FOR VALUES FROM (21) TO (31)" +== 243 +-- truncate_limit: 100 +create temp table prtx2 (a integer, b integer, c integer) + partition by range (a) +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx2 (a int, b int, c int) PARTITION BY RANGE (a)" +== 244 +-- truncate_limit: 100 +create temp table prtx2_1 partition of prtx2 for values from (1) to (11) +-- +TABLE: name="prtx2_1" schema="" table="prtx2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx2_1 PARTITION OF prtx2 FOR VALUES FROM (1) TO (11)" +== 245 +-- truncate_limit: 100 +create temp table prtx2_2 partition of prtx2 for values from (11) to (21) +-- +TABLE: name="prtx2_2" schema="" table="prtx2_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx2_2 PARTITION OF prtx2 FOR VALUES FROM (11) TO (21)" +== 246 +-- truncate_limit: 100 +create temp table prtx2_3 partition of prtx2 for values from (21) to (31) +-- +TABLE: name="prtx2_3" schema="" table="prtx2_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE prtx2_3 PARTITION OF prtx2 FOR VALUES FROM (21) TO (31)" +== 247 +-- truncate_limit: 100 +insert into prtx1 select 1 + i%30, i, i + from generate_series(1,1000) i +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prtx1 SELECT 1 + (i % 30), i, i FROM generate_series(1, 1000) i" +== 248 +-- truncate_limit: 100 +insert into prtx2 select 1 + i%30, i, i + from generate_series(1,500) i, generate_series(1,10) j +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prtx2 SELECT 1 + (i % 30), i, i FROM generate_series(1, 500) i, generate_series(1, 10) j" +== 249 +-- truncate_limit: 100 +create index on prtx2 (b) +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON prtx2 USING btree (b)" +== 250 +-- truncate_limit: 100 +create index on prtx2 (c) +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON prtx2 USING btree (c)" +== 251 +-- truncate_limit: 100 +analyze prtx1 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prtx1" +== 252 +-- truncate_limit: 100 +analyze prtx2 +-- +TABLE: name="prtx2" schema="" table="prtx2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prtx2" +== 253 +-- truncate_limit: 100 +explain (costs off) +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM prtx1 WHERE NOT EXISTS (SELECT 1 FROM prtx2 WHERE prtx2.a = prt..." +== 254 +-- truncate_limit: 100 +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM prtx1 WHERE NOT EXISTS (SELECT 1 FROM prtx2 WHERE ...) AND a < 20 AND c = 120" +== 255 +-- truncate_limit: 100 +explain (costs off) +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM prtx1 WHERE NOT EXISTS (SELECT 1 FROM prtx2 WHERE prtx2.a = prt..." +== 256 +-- truncate_limit: 100 +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91 +-- +TABLE: name="prtx1" schema="" table="prtx1" ctx=Select +TABLE: name="prtx2" schema="" table="prtx2" ctx=Select +FILTER: schema="" table="prtx2" column="a" +FILTER: schema="" table="prtx1" column="a" +FILTER: schema="" table="prtx2" column="b" +FILTER: schema="" table="prtx1" column="b" +FILTER: schema="" table="prtx2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM prtx1 WHERE NOT EXISTS (SELECT 1 FROM prtx2 WHERE ...) AND a < 20 AND c = 91" +== 257 +-- truncate_limit: 100 +|-- +-- Test advanced partition-matching algorithm for partitioned join +|-- + +-- Tests for range-partitioned tables +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a)" +== 258 +-- truncate_limit: 100 +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200) +-- +TABLE: name="prt1_adv_p1" schema="" table="prt1_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200)" +== 259 +-- truncate_limit: 100 +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt1_adv_p2" schema="" table="prt1_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300)" +== 260 +-- truncate_limit: 100 +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400)" +== 261 +-- truncate_limit: 100 +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX prt1_adv_a_idx ON prt1_adv USING btree (a)" +== 262 +-- truncate_limit: 100 +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i" +== 263 +-- truncate_limit: 100 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_adv" +== 264 +-- truncate_limit: 100 +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b)" +== 265 +-- truncate_limit: 100 +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (150) +-- +TABLE: name="prt2_adv_p1" schema="" table="prt2_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (150)" +== 266 +-- truncate_limit: 100 +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt2_adv_p2" schema="" table="prt2_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (300)" +== 267 +-- truncate_limit: 100 +CREATE TABLE prt2_adv_p3 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (500) +-- +TABLE: name="prt2_adv_p3" schema="" table="prt2_adv_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_p3 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (500)" +== 268 +-- truncate_limit: 100 +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX prt2_adv_b_idx ON prt2_adv USING btree (b)" +== 269 +-- truncate_limit: 100 +INSERT INTO prt2_adv_p1 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 149) i +-- +TABLE: name="prt2_adv_p1" schema="" table="prt2_adv_p1" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_adv_p1 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 149) i" +== 270 +-- truncate_limit: 100 +INSERT INTO prt2_adv_p2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(200, 299) i +-- +TABLE: name="prt2_adv_p2" schema="" table="prt2_adv_p2" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_adv_p2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(200, 299) i" +== 271 +-- truncate_limit: 100 +INSERT INTO prt2_adv_p3 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i +-- +TABLE: name="prt2_adv_p3" schema="" table="prt2_adv_p3" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_adv_p3 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i" +== 272 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 273 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 274 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b" +== 275 +-- truncate_limit: 100 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1..." +== 276 +-- truncate_limit: 100 +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1_adv t1 WHERE ... ORDER BY t1.a" +== 277 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON t1.a ..." +== 278 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b" +== 279 +-- truncate_limit: 100 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHER..." +== 280 +-- truncate_limit: 100 +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1_adv t1 WHERE ... ORDER BY t1.a" +== 281 +-- truncate_limit: 100 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 AS phv, * FROM prt1_adv WHERE ..." +== 282 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM prt1_adv WHERE ...) t1 FULL JOIN (SELECT ... FROM prt2_adv WHERE..." +== 283 +-- truncate_limit: 100 +-- Test cases where one side has an extra partition +CREATE TABLE prt2_adv_extra PARTITION OF prt2_adv FOR VALUES FROM (500) TO (MAXVALUE) +-- +TABLE: name="prt2_adv_extra" schema="" table="prt2_adv_extra" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_extra PARTITION OF prt2_adv FOR VALUES FROM (500) TO (maxvalue)" +== 284 +-- truncate_limit: 100 +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(500, 599) i +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(500, 599) i" +== 285 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 286 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 287 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b" +== 288 +-- truncate_limit: 100 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1..." +== 289 +-- truncate_limit: 100 +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1_adv t1 WHERE ... ORDER BY t1.a" +== 290 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON t1.a ..." +== 291 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b" +== 292 +-- truncate_limit: 100 +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.b, t1.c, t2.a, t2.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.b, t1.c, t2.a, t2.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON t1.b ..." +== 293 +-- truncate_limit: 100 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHER..." +== 294 +-- truncate_limit: 100 +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM prt1_adv t1 WHERE ... ORDER BY t1.a" +== 295 +-- truncate_limit: 100 +-- anti join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt1_adv t2 WHERE t1.b = t2.a) AND t1.a = 0 ORDER BY t1.b +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt1_adv t2 WHER..." +== 296 +-- truncate_limit: 100 +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 AS phv, * FROM prt1_adv WHERE ..." +== 297 +-- truncate_limit: 100 +-- 3-way join where not every pair of relations can do partitioned join +EXPLAIN (COSTS OFF) +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +ALIAS: "t3"="prt1_adv" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv..." +== 298 +-- truncate_limit: 100 +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +ALIAS: "t1"="prt2_adv" +ALIAS: "t2"="prt1_adv" +ALIAS: "t3"="prt1_adv" +FILTER: schema="" table="t1" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON t1.b = t2.a JOIN prt1_adv t3 ON t1.b = t3.a ..." +== 299 +-- truncate_limit: 100 +DROP TABLE prt2_adv_extra +-- +TABLE: name="prt2_adv_extra" schema="" table="prt2_adv_extra" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt2_adv_extra" +== 300 +-- truncate_limit: 100 +-- Test cases where a partition on one side matches multiple partitions on +-- the other side; we currently can't do partitioned join in such cases +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3 +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3" +== 301 +-- truncate_limit: 100 +-- Split prt2_adv_p3 into two partitions so that prt1_adv_p3 matches both +CREATE TABLE prt2_adv_p3_1 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (375) +-- +TABLE: name="prt2_adv_p3_1" schema="" table="prt2_adv_p3_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_p3_1 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (375)" +== 302 +-- truncate_limit: 100 +CREATE TABLE prt2_adv_p3_2 PARTITION OF prt2_adv FOR VALUES FROM (375) TO (500) +-- +TABLE: name="prt2_adv_p3_2" schema="" table="prt2_adv_p3_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_p3_2 PARTITION OF prt2_adv FOR VALUES FROM (375) TO (500)" +== 303 +-- truncate_limit: 100 +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i" +== 304 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 305 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 306 +-- truncate_limit: 100 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1..." +== 307 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON t1.a ..." +== 308 +-- truncate_limit: 100 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHER..." +== 309 +-- truncate_limit: 100 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +FILTER: schema="" table="t1" column="phv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="phv" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="prt1_adv" column="b" +FILTER: schema="" table="prt2_adv" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 AS phv, * FROM prt1_adv WHERE ..." +== 310 +-- truncate_limit: 100 +DROP TABLE prt2_adv_p3_1 +-- +TABLE: name="prt2_adv_p3_1" schema="" table="prt2_adv_p3_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt2_adv_p3_1" +== 311 +-- truncate_limit: 100 +DROP TABLE prt2_adv_p3_2 +-- +TABLE: name="prt2_adv_p3_2" schema="" table="prt2_adv_p3_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt2_adv_p3_2" +== 312 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 313 +-- truncate_limit: 100 +-- Test default partitions +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p1 +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p1" +== 314 +-- truncate_limit: 100 +-- Change prt1_adv_p1 to the default partition +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p1 DEFAULT +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p1 DEFAULT" +== 315 +-- truncate_limit: 100 +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p3 +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p3" +== 316 +-- truncate_limit: 100 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_adv" +== 317 +-- truncate_limit: 100 +-- We can do partitioned join even if only one of relations has the default +-- partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 318 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b" +== 319 +-- truncate_limit: 100 +-- Restore prt1_adv_p3 +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p3 FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p3 FOR VALUES FROM (300) TO (400)" +== 320 +-- truncate_limit: 100 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_adv" +== 321 +-- truncate_limit: 100 +-- Restore prt2_adv_p3 +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 FOR VALUES FROM (350) TO (500) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 FOR VALUES FROM (350) TO (500)" +== 322 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 323 +-- truncate_limit: 100 +-- Partitioned join can't be applied because the default partition of prt1_adv +-- matches prt2_adv_p1 and prt2_adv_p3 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 324 +-- truncate_limit: 100 +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3 +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3" +== 325 +-- truncate_limit: 100 +-- Change prt2_adv_p3 to the default partition +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 DEFAULT +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 DEFAULT" +== 326 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 327 +-- truncate_limit: 100 +-- Partitioned join can't be applied because the default partition of prt1_adv +-- matches prt2_adv_p1 and prt2_adv_p3 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 328 +-- truncate_limit: 100 +DROP TABLE prt1_adv_p3 +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt1_adv_p3" +== 329 +-- truncate_limit: 100 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_adv" +== 330 +-- truncate_limit: 100 +DROP TABLE prt2_adv_p3 +-- +TABLE: name="prt2_adv_p3" schema="" table="prt2_adv_p3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt2_adv_p3" +== 331 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 332 +-- truncate_limit: 100 +CREATE TABLE prt3_adv (a int, b int, c varchar) PARTITION BY RANGE (a) +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt3_adv (a int, b int, c varchar) PARTITION BY RANGE (a)" +== 333 +-- truncate_limit: 100 +CREATE TABLE prt3_adv_p1 PARTITION OF prt3_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt3_adv_p1" schema="" table="prt3_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt3_adv_p1 PARTITION OF prt3_adv FOR VALUES FROM (200) TO (300)" +== 334 +-- truncate_limit: 100 +CREATE TABLE prt3_adv_p2 PARTITION OF prt3_adv FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt3_adv_p2" schema="" table="prt3_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt3_adv_p2 PARTITION OF prt3_adv FOR VALUES FROM (300) TO (400)" +== 335 +-- truncate_limit: 100 +CREATE INDEX prt3_adv_a_idx ON prt3_adv (a) +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX prt3_adv_a_idx ON prt3_adv USING btree (a)" +== 336 +-- truncate_limit: 100 +INSERT INTO prt3_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(200, 399) i +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt3_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(200, 399) i" +== 337 +-- truncate_limit: 100 +ANALYZE prt3_adv +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt3_adv" +== 338 +-- truncate_limit: 100 +-- 3-way join to test the default partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +ALIAS: "t3"="prt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv..." +== 339 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +ALIAS: "t3"="prt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON t1.a = t2.b LEFT JOIN prt3_adv t3 ON t1.a = ..." +== 340 +-- truncate_limit: 100 +DROP TABLE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt1_adv" +== 341 +-- truncate_limit: 100 +DROP TABLE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt2_adv" +== 342 +-- truncate_limit: 100 +DROP TABLE prt3_adv +-- +TABLE: name="prt3_adv" schema="" table="prt3_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt3_adv" +== 343 +-- truncate_limit: 100 +-- Test interaction of partitioned join with partition pruning +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a)" +== 344 +-- truncate_limit: 100 +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200) +-- +TABLE: name="prt1_adv_p1" schema="" table="prt1_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200)" +== 345 +-- truncate_limit: 100 +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300) +-- +TABLE: name="prt1_adv_p2" schema="" table="prt1_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300)" +== 346 +-- truncate_limit: 100 +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400) +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400)" +== 347 +-- truncate_limit: 100 +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a) +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX prt1_adv_a_idx ON prt1_adv USING btree (a)" +== 348 +-- truncate_limit: 100 +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i" +== 349 +-- truncate_limit: 100 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_adv" +== 350 +-- truncate_limit: 100 +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b)" +== 351 +-- truncate_limit: 100 +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (200) +-- +TABLE: name="prt2_adv_p1" schema="" table="prt2_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (200)" +== 352 +-- truncate_limit: 100 +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (400) +-- +TABLE: name="prt2_adv_p2" schema="" table="prt2_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (400)" +== 353 +-- truncate_limit: 100 +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b) +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX prt2_adv_b_idx ON prt2_adv USING btree (b)" +== 354 +-- truncate_limit: 100 +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 399) i +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 399) i" +== 355 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 356 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 357 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2.b WHERE ... ORDER BY t1.a, t2.b" +== 358 +-- truncate_limit: 100 +DROP TABLE prt1_adv_p3 +-- +TABLE: name="prt1_adv_p3" schema="" table="prt1_adv_p3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt1_adv_p3" +== 359 +-- truncate_limit: 100 +CREATE TABLE prt1_adv_default PARTITION OF prt1_adv DEFAULT +-- +TABLE: name="prt1_adv_default" schema="" table="prt1_adv_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt1_adv_default PARTITION OF prt1_adv DEFAULT" +== 360 +-- truncate_limit: 100 +ANALYZE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt1_adv" +== 361 +-- truncate_limit: 100 +CREATE TABLE prt2_adv_default PARTITION OF prt2_adv DEFAULT +-- +TABLE: name="prt2_adv_default" schema="" table="prt2_adv_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE prt2_adv_default PARTITION OF prt2_adv DEFAULT" +== 362 +-- truncate_limit: 100 +ANALYZE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE prt2_adv" +== 363 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2...." +== 364 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=Select +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=Select +ALIAS: "t1"="prt1_adv" +ALIAS: "t2"="prt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM prt1_adv t1 JOIN prt2_adv t2 ON t1.a = t2.b WHERE ... ORDER BY t1.a, t2.b" +== 365 +-- truncate_limit: 100 +DROP TABLE prt1_adv +-- +TABLE: name="prt1_adv" schema="" table="prt1_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt1_adv" +== 366 +-- truncate_limit: 100 +DROP TABLE prt2_adv +-- +TABLE: name="prt2_adv" schema="" table="prt2_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prt2_adv" +== 367 +-- truncate_limit: 100 +-- Tests for list-partitioned tables +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 368 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001', '0003') +-- +TABLE: name="plt1_adv_p1" schema="" table="plt1_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001', '0003')" +== 369 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt1_adv_p2" schema="" table="plt1_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0004', '0006')" +== 370 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0008', '0009') +-- +TABLE: name="plt1_adv_p3" schema="" table="plt1_adv_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0008', '0009')" +== 371 +-- truncate_limit: 100 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9)" +== 372 +-- truncate_limit: 100 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_adv" +== 373 +-- truncate_limit: 100 +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 374 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002', '0003') +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002', '0003')" +== 375 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt2_adv_p2" schema="" table="plt2_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0006')" +== 376 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0007', '0009') +-- +TABLE: name="plt2_adv_p3" schema="" table="plt2_adv_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0007', '0009')" +== 377 +-- truncate_limit: 100 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9)" +== 378 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 379 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 380 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 381 +-- truncate_limit: 100 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1..." +== 382 +-- truncate_limit: 100 +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM plt1_adv t1 WHERE ... ORDER BY t1.a" +== 383 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 384 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 385 +-- truncate_limit: 100 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHER..." +== 386 +-- truncate_limit: 100 +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM plt1_adv t1 WHERE ... ORDER BY t1.a" +== 387 +-- truncate_limit: 100 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a ..." +== 388 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 389 +-- truncate_limit: 100 +-- Test cases where one side has an extra partition +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN ('0000') +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN ('0000')" +== 390 +-- truncate_limit: 100 +INSERT INTO plt2_adv_extra VALUES (0, 0, '0000') +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv_extra VALUES (0, 0, '0000')" +== 391 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 392 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 393 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 394 +-- truncate_limit: 100 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1..." +== 395 +-- truncate_limit: 100 +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM plt1_adv t1 WHERE ... ORDER BY t1.a" +== 396 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 397 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 398 +-- truncate_limit: 100 +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt2_adv t1 LEFT JOIN plt1_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt2_adv" +ALIAS: "t2"="plt1_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt2_adv t1 LEFT JOIN plt1_adv t2 ON t1.a ..." +== 399 +-- truncate_limit: 100 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHER..." +== 400 +-- truncate_limit: 100 +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM plt1_adv t1 WHERE ... ORDER BY t1.a" +== 401 +-- truncate_limit: 100 +-- anti join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt1_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt2_adv" +ALIAS: "t2"="plt1_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt1_adv t2 WHER..." +== 402 +-- truncate_limit: 100 +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a ..." +== 403 +-- truncate_limit: 100 +DROP TABLE plt2_adv_extra +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_extra" +== 404 +-- truncate_limit: 100 +-- Test cases where a partition on one side matches multiple partitions on +-- the other side; we currently can't do partitioned join in such cases +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2 +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2" +== 405 +-- truncate_limit: 100 +-- Split plt2_adv_p2 into two partitions so that plt1_adv_p2 matches both +CREATE TABLE plt2_adv_p2_1 PARTITION OF plt2_adv FOR VALUES IN ('0004') +-- +TABLE: name="plt2_adv_p2_1" schema="" table="plt2_adv_p2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p2_1 PARTITION OF plt2_adv FOR VALUES IN ('0004')" +== 406 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p2_2 PARTITION OF plt2_adv FOR VALUES IN ('0006') +-- +TABLE: name="plt2_adv_p2_2" schema="" table="plt2_adv_p2_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p2_2 PARTITION OF plt2_adv FOR VALUES IN ('0006')" +== 407 +-- truncate_limit: 100 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6)" +== 408 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 409 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 410 +-- truncate_limit: 100 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1..." +== 411 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 412 +-- truncate_limit: 100 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHER..." +== 413 +-- truncate_limit: 100 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a ..." +== 414 +-- truncate_limit: 100 +DROP TABLE plt2_adv_p2_1 +-- +TABLE: name="plt2_adv_p2_1" schema="" table="plt2_adv_p2_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_p2_1" +== 415 +-- truncate_limit: 100 +DROP TABLE plt2_adv_p2_2 +-- +TABLE: name="plt2_adv_p2_2" schema="" table="plt2_adv_p2_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_p2_2" +== 416 +-- truncate_limit: 100 +-- Restore plt2_adv_p2 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006')" +== 417 +-- truncate_limit: 100 +-- Test NULL partitions +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1 +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1" +== 418 +-- truncate_limit: 100 +-- Change plt1_adv_p1 to the NULL partition +CREATE TABLE plt1_adv_p1_null PARTITION OF plt1_adv FOR VALUES IN (NULL, '0001', '0003') +-- +TABLE: name="plt1_adv_p1_null" schema="" table="plt1_adv_p1_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p1_null PARTITION OF plt1_adv FOR VALUES IN (NULL, '0001', '0003')" +== 419 +-- truncate_limit: 100 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3)" +== 420 +-- truncate_limit: 100 +INSERT INTO plt1_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_adv VALUES (-1, -1, NULL)" +== 421 +-- truncate_limit: 100 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_adv" +== 422 +-- truncate_limit: 100 +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p3 +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p3" +== 423 +-- truncate_limit: 100 +-- Change plt2_adv_p3 to the NULL partition +CREATE TABLE plt2_adv_p3_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0007', '0009') +-- +TABLE: name="plt2_adv_p3_null" schema="" table="plt2_adv_p3_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p3_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0007', '0009')" +== 424 +-- truncate_limit: 100 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (7, 9) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (7, 9)" +== 425 +-- truncate_limit: 100 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv VALUES (-1, -1, NULL)" +== 426 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 427 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 428 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 429 +-- truncate_limit: 100 +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1..." +== 430 +-- truncate_limit: 100 +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM plt1_adv t1 WHERE ... ORDER BY t1.a" +== 431 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 432 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 433 +-- truncate_limit: 100 +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHER..." +== 434 +-- truncate_limit: 100 +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t2" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT t1.* FROM plt1_adv t1 WHERE ... ORDER BY t1.a" +== 435 +-- truncate_limit: 100 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a ..." +== 436 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 437 +-- truncate_limit: 100 +DROP TABLE plt1_adv_p1_null +-- +TABLE: name="plt1_adv_p1_null" schema="" table="plt1_adv_p1_null" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt1_adv_p1_null" +== 438 +-- truncate_limit: 100 +-- Restore plt1_adv_p1 +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 FOR VALUES IN ('0001', '0003') +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 FOR VALUES IN ('0001', '0003')" +== 439 +-- truncate_limit: 100 +-- Add to plt1_adv the extra NULL partition containing only NULL values as the +-- key values +CREATE TABLE plt1_adv_extra PARTITION OF plt1_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt1_adv_extra" schema="" table="plt1_adv_extra" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_extra PARTITION OF plt1_adv FOR VALUES IN (NULL)" +== 440 +-- truncate_limit: 100 +INSERT INTO plt1_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_adv VALUES (-1, -1, NULL)" +== 441 +-- truncate_limit: 100 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_adv" +== 442 +-- truncate_limit: 100 +DROP TABLE plt2_adv_p3_null +-- +TABLE: name="plt2_adv_p3_null" schema="" table="plt2_adv_p3_null" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_p3_null" +== 443 +-- truncate_limit: 100 +-- Restore plt2_adv_p3 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p3 FOR VALUES IN ('0007', '0009') +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p3 FOR VALUES IN ('0007', '0009')" +== 444 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 445 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 446 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 447 +-- truncate_limit: 100 +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 448 +-- truncate_limit: 100 +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a ..." +== 449 +-- truncate_limit: 100 +-- Add to plt2_adv the extra NULL partition containing only NULL values as the +-- key values +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN (NULL)" +== 450 +-- truncate_limit: 100 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv VALUES (-1, -1, NULL)" +== 451 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 452 +-- truncate_limit: 100 +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 453 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 454 +-- truncate_limit: 100 +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 455 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 456 +-- truncate_limit: 100 +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a ..." +== 457 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 458 +-- truncate_limit: 100 +-- 3-way join to test the NULL partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt1_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv..." +== 459 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt1_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c LEFT JOIN plt1_a..." +== 460 +-- truncate_limit: 100 +DROP TABLE plt1_adv_extra +-- +TABLE: name="plt1_adv_extra" schema="" table="plt1_adv_extra" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt1_adv_extra" +== 461 +-- truncate_limit: 100 +DROP TABLE plt2_adv_extra +-- +TABLE: name="plt2_adv_extra" schema="" table="plt2_adv_extra" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_extra" +== 462 +-- truncate_limit: 100 +-- Test default partitions +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1 +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1" +== 463 +-- truncate_limit: 100 +-- Change plt1_adv_p1 to the default partition +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 DEFAULT +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 DEFAULT" +== 464 +-- truncate_limit: 100 +DROP TABLE plt1_adv_p3 +-- +TABLE: name="plt1_adv_p3" schema="" table="plt1_adv_p3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt1_adv_p3" +== 465 +-- truncate_limit: 100 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_adv" +== 466 +-- truncate_limit: 100 +DROP TABLE plt2_adv_p3 +-- +TABLE: name="plt2_adv_p3" schema="" table="plt2_adv_p3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_p3" +== 467 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 468 +-- truncate_limit: 100 +-- We can do partitioned join even if only one of relations has the default +-- partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 469 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 470 +-- truncate_limit: 100 +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2 +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2" +== 471 +-- truncate_limit: 100 +-- Change plt2_adv_p2 to contain '0005' in addition to '0004' and '0006' as +-- the key values +CREATE TABLE plt2_adv_p2_ext PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005', '0006') +-- +TABLE: name="plt2_adv_p2_ext" schema="" table="plt2_adv_p2_ext" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p2_ext PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005', '0006')" +== 472 +-- truncate_limit: 100 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 5, 6) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (4, 5, 6)" +== 473 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 474 +-- truncate_limit: 100 +-- Partitioned join can't be applied because the default partition of plt1_adv +-- matches plt2_adv_p1 and plt2_adv_p2_ext +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 475 +-- truncate_limit: 100 +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2_ext +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2_ext" +== 476 +-- truncate_limit: 100 +-- Change plt2_adv_p2_ext to the default partition +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2_ext DEFAULT +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2_ext DEFAULT" +== 477 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 478 +-- truncate_limit: 100 +-- Partitioned join can't be applied because the default partition of plt1_adv +-- matches plt2_adv_p1 and plt2_adv_p2_ext +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 479 +-- truncate_limit: 100 +DROP TABLE plt2_adv_p2_ext +-- +TABLE: name="plt2_adv_p2_ext" schema="" table="plt2_adv_p2_ext" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_p2_ext" +== 480 +-- truncate_limit: 100 +-- Restore plt2_adv_p2 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006')" +== 481 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 482 +-- truncate_limit: 100 +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 483 +-- truncate_limit: 100 +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0004', '0006') +-- +TABLE: name="plt3_adv_p1" schema="" table="plt3_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0004', '0006')" +== 484 +-- truncate_limit: 100 +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0007', '0009') +-- +TABLE: name="plt3_adv_p2" schema="" table="plt3_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0007', '0009')" +== 485 +-- truncate_limit: 100 +INSERT INTO plt3_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6, 7, 9) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt3_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6, 7, 9)" +== 486 +-- truncate_limit: 100 +ANALYZE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt3_adv" +== 487 +-- truncate_limit: 100 +-- 3-way join to test the default partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv..." +== 488 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c LEFT JOIN plt3_a..." +== 489 +-- truncate_limit: 100 +-- Test cases where one side has the default partition while the other side +-- has the NULL partition +DROP TABLE plt2_adv_p1 +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_p1" +== 490 +-- truncate_limit: 100 +-- Add the NULL partition to plt2_adv +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0001', '0003') +-- +TABLE: name="plt2_adv_p1_null" schema="" table="plt2_adv_p1_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0001', '0003')" +== 491 +-- truncate_limit: 100 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3)" +== 492 +-- truncate_limit: 100 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv VALUES (-1, -1, NULL)" +== 493 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 494 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 495 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 496 +-- truncate_limit: 100 +DROP TABLE plt2_adv_p1_null +-- +TABLE: name="plt2_adv_p1_null" schema="" table="plt2_adv_p1_null" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv_p1_null" +== 497 +-- truncate_limit: 100 +-- Add the NULL partition that contains only NULL values as the key values +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt2_adv_p1_null" schema="" table="plt2_adv_p1_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL)" +== 498 +-- truncate_limit: 100 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv VALUES (-1, -1, NULL)" +== 499 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 500 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 501 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 502 +-- truncate_limit: 100 +DROP TABLE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt1_adv" +== 503 +-- truncate_limit: 100 +DROP TABLE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv" +== 504 +-- truncate_limit: 100 +DROP TABLE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt3_adv" +== 505 +-- truncate_limit: 100 +-- Test interaction of partitioned join with partition pruning +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 506 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001') +-- +TABLE: name="plt1_adv_p1" schema="" table="plt1_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001')" +== 507 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0002') +-- +TABLE: name="plt1_adv_p2" schema="" table="plt1_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0002')" +== 508 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0003') +-- +TABLE: name="plt1_adv_p3" schema="" table="plt1_adv_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0003')" +== 509 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p4 PARTITION OF plt1_adv FOR VALUES IN (NULL, '0004', '0005') +-- +TABLE: name="plt1_adv_p4" schema="" table="plt1_adv_p4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p4 PARTITION OF plt1_adv FOR VALUES IN (NULL, '0004', '0005')" +== 510 +-- truncate_limit: 100 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5)" +== 511 +-- truncate_limit: 100 +INSERT INTO plt1_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_adv VALUES (-1, -1, NULL)" +== 512 +-- truncate_limit: 100 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_adv" +== 513 +-- truncate_limit: 100 +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 514 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0001', '0002') +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0001', '0002')" +== 515 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN (NULL) +-- +TABLE: name="plt2_adv_p2" schema="" table="plt2_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN (NULL)" +== 516 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0003') +-- +TABLE: name="plt2_adv_p3" schema="" table="plt2_adv_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0003')" +== 517 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p4 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005') +-- +TABLE: name="plt2_adv_p4" schema="" table="plt2_adv_p4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p4 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005')" +== 518 +-- truncate_limit: 100 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv SELECT ... FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5)" +== 519 +-- truncate_limit: 100 +INSERT INTO plt2_adv VALUES (-1, -1, NULL) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv VALUES (-1, -1, NULL)" +== 520 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 521 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 522 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 523 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 524 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 525 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_default PARTITION OF plt1_adv DEFAULT +-- +TABLE: name="plt1_adv_default" schema="" table="plt1_adv_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_default PARTITION OF plt1_adv DEFAULT" +== 526 +-- truncate_limit: 100 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_adv" +== 527 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_default PARTITION OF plt2_adv DEFAULT +-- +TABLE: name="plt2_adv_default" schema="" table="plt2_adv_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_default PARTITION OF plt2_adv DEFAULT" +== 528 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 529 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2...." +== 530 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a" +== 531 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a ..." +== 532 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +FILTER: schema="" table="t1" column="c" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER ..." +== 533 +-- truncate_limit: 100 +DROP TABLE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt1_adv" +== 534 +-- truncate_limit: 100 +DROP TABLE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv" +== 535 +-- truncate_limit: 100 +-- Test the process_outer_partition() code path +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 536 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0000', '0001', '0002') +-- +TABLE: name="plt1_adv_p1" schema="" table="plt1_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0000', '0001', '0002')" +== 537 +-- truncate_limit: 100 +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0003', '0004') +-- +TABLE: name="plt1_adv_p2" schema="" table="plt1_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0003', '0004')" +== 538 +-- truncate_limit: 100 +INSERT INTO plt1_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt1_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i" +== 539 +-- truncate_limit: 100 +ANALYZE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt1_adv" +== 540 +-- truncate_limit: 100 +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 541 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002') +-- +TABLE: name="plt2_adv_p1" schema="" table="plt2_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002')" +== 542 +-- truncate_limit: 100 +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0003', '0004') +-- +TABLE: name="plt2_adv_p2" schema="" table="plt2_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0003', '0004')" +== 543 +-- truncate_limit: 100 +INSERT INTO plt2_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (2, 3, 4) +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt2_adv SELECT ... FROM generate_series(0, 24) i WHERE i % 5 IN (2, 3, 4)" +== 544 +-- truncate_limit: 100 +ANALYZE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt2_adv" +== 545 +-- truncate_limit: 100 +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c)" +== 546 +-- truncate_limit: 100 +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0001') +-- +TABLE: name="plt3_adv_p1" schema="" table="plt3_adv_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0001')" +== 547 +-- truncate_limit: 100 +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0003', '0004') +-- +TABLE: name="plt3_adv_p2" schema="" table="plt3_adv_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0003', '0004')" +== 548 +-- truncate_limit: 100 +INSERT INTO plt3_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (1, 3, 4) +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO plt3_adv SELECT ... FROM generate_series(0, 24) i WHERE i % 5 IN (1, 3, 4)" +== 549 +-- truncate_limit: 100 +ANALYZE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE plt3_adv" +== 550 +-- truncate_limit: 100 +-- This tests that when merging partitions from plt1_adv and plt2_adv in +-- merge_list_bounds(), process_outer_partition() returns an already-assigned +-- merged partition when re-called with plt1_adv_p1 for the second list value +-- '0001' of that partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv..." +== 551 +-- truncate_limit: 100 +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=Select +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=Select +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=Select +ALIAS: "t1"="plt1_adv" +ALIAS: "t2"="plt2_adv" +ALIAS: "t3"="plt3_adv" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t1" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON t1.c = t2.c FULL JOIN plt3_adv t3 ON t1.c = ..." +== 552 +-- truncate_limit: 100 +DROP TABLE plt1_adv +-- +TABLE: name="plt1_adv" schema="" table="plt1_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt1_adv" +== 553 +-- truncate_limit: 100 +DROP TABLE plt2_adv +-- +TABLE: name="plt2_adv" schema="" table="plt2_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt2_adv" +== 554 +-- truncate_limit: 100 +DROP TABLE plt3_adv +-- +TABLE: name="plt3_adv" schema="" table="plt3_adv" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE plt3_adv" +== 555 +-- truncate_limit: 100 +-- Tests for multi-level partitioned tables +CREATE TABLE alpha (a double precision, b int, c text) PARTITION BY RANGE (a) +-- +TABLE: name="alpha" schema="" table="alpha" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha (a double precision, b int, c text) PARTITION BY RANGE (a)" +== 556 +-- truncate_limit: 100 +CREATE TABLE alpha_neg PARTITION OF alpha FOR VALUES FROM ('-Infinity') TO (0) PARTITION BY RANGE (b) +-- +TABLE: name="alpha_neg" schema="" table="alpha_neg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_neg PARTITION OF alpha FOR VALUES FROM ('-Infinity') TO (0) PARTITION BY RANGE..." +== 557 +-- truncate_limit: 100 +CREATE TABLE alpha_pos PARTITION OF alpha FOR VALUES FROM (0) TO (10.0) PARTITION BY LIST (c) +-- +TABLE: name="alpha_pos" schema="" table="alpha_pos" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_pos PARTITION OF alpha FOR VALUES FROM (0) TO (10.0) PARTITION BY LIST (c)" +== 558 +-- truncate_limit: 100 +CREATE TABLE alpha_neg_p1 PARTITION OF alpha_neg FOR VALUES FROM (100) TO (200) +-- +TABLE: name="alpha_neg_p1" schema="" table="alpha_neg_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_neg_p1 PARTITION OF alpha_neg FOR VALUES FROM (100) TO (200)" +== 559 +-- truncate_limit: 100 +CREATE TABLE alpha_neg_p2 PARTITION OF alpha_neg FOR VALUES FROM (200) TO (300) +-- +TABLE: name="alpha_neg_p2" schema="" table="alpha_neg_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_neg_p2 PARTITION OF alpha_neg FOR VALUES FROM (200) TO (300)" +== 560 +-- truncate_limit: 100 +CREATE TABLE alpha_neg_p3 PARTITION OF alpha_neg FOR VALUES FROM (300) TO (400) +-- +TABLE: name="alpha_neg_p3" schema="" table="alpha_neg_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_neg_p3 PARTITION OF alpha_neg FOR VALUES FROM (300) TO (400)" +== 561 +-- truncate_limit: 100 +CREATE TABLE alpha_pos_p1 PARTITION OF alpha_pos FOR VALUES IN ('0001', '0003') +-- +TABLE: name="alpha_pos_p1" schema="" table="alpha_pos_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_pos_p1 PARTITION OF alpha_pos FOR VALUES IN ('0001', '0003')" +== 562 +-- truncate_limit: 100 +CREATE TABLE alpha_pos_p2 PARTITION OF alpha_pos FOR VALUES IN ('0004', '0006') +-- +TABLE: name="alpha_pos_p2" schema="" table="alpha_pos_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_pos_p2 PARTITION OF alpha_pos FOR VALUES IN ('0004', '0006')" +== 563 +-- truncate_limit: 100 +CREATE TABLE alpha_pos_p3 PARTITION OF alpha_pos FOR VALUES IN ('0008', '0009') +-- +TABLE: name="alpha_pos_p3" schema="" table="alpha_pos_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alpha_pos_p3 PARTITION OF alpha_pos FOR VALUES IN ('0008', '0009')" +== 564 +-- truncate_limit: 100 +INSERT INTO alpha_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9) +-- +TABLE: name="alpha_neg" schema="" table="alpha_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alpha_neg SELECT ... FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9)" +== 565 +-- truncate_limit: 100 +INSERT INTO alpha_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9) +-- +TABLE: name="alpha_pos" schema="" table="alpha_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alpha_pos SELECT ... FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9)" +== 566 +-- truncate_limit: 100 +ANALYZE alpha +-- +TABLE: name="alpha" schema="" table="alpha" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE alpha" +== 567 +-- truncate_limit: 100 +CREATE TABLE beta (a double precision, b int, c text) PARTITION BY RANGE (a) +-- +TABLE: name="beta" schema="" table="beta" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta (a double precision, b int, c text) PARTITION BY RANGE (a)" +== 568 +-- truncate_limit: 100 +CREATE TABLE beta_neg PARTITION OF beta FOR VALUES FROM (-10.0) TO (0) PARTITION BY RANGE (b) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_neg PARTITION OF beta FOR VALUES FROM (-10.0) TO (0) PARTITION BY RANGE (b)" +== 569 +-- truncate_limit: 100 +CREATE TABLE beta_pos PARTITION OF beta FOR VALUES FROM (0) TO ('Infinity') PARTITION BY LIST (c) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_pos PARTITION OF beta FOR VALUES FROM (0) TO ('Infinity') PARTITION BY LIST (c)" +== 570 +-- truncate_limit: 100 +CREATE TABLE beta_neg_p1 PARTITION OF beta_neg FOR VALUES FROM (100) TO (150) +-- +TABLE: name="beta_neg_p1" schema="" table="beta_neg_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_neg_p1 PARTITION OF beta_neg FOR VALUES FROM (100) TO (150)" +== 571 +-- truncate_limit: 100 +CREATE TABLE beta_neg_p2 PARTITION OF beta_neg FOR VALUES FROM (200) TO (300) +-- +TABLE: name="beta_neg_p2" schema="" table="beta_neg_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_neg_p2 PARTITION OF beta_neg FOR VALUES FROM (200) TO (300)" +== 572 +-- truncate_limit: 100 +CREATE TABLE beta_neg_p3 PARTITION OF beta_neg FOR VALUES FROM (350) TO (500) +-- +TABLE: name="beta_neg_p3" schema="" table="beta_neg_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_neg_p3 PARTITION OF beta_neg FOR VALUES FROM (350) TO (500)" +== 573 +-- truncate_limit: 100 +CREATE TABLE beta_pos_p1 PARTITION OF beta_pos FOR VALUES IN ('0002', '0003') +-- +TABLE: name="beta_pos_p1" schema="" table="beta_pos_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_pos_p1 PARTITION OF beta_pos FOR VALUES IN ('0002', '0003')" +== 574 +-- truncate_limit: 100 +CREATE TABLE beta_pos_p2 PARTITION OF beta_pos FOR VALUES IN ('0004', '0006') +-- +TABLE: name="beta_pos_p2" schema="" table="beta_pos_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_pos_p2 PARTITION OF beta_pos FOR VALUES IN ('0004', '0006')" +== 575 +-- truncate_limit: 100 +CREATE TABLE beta_pos_p3 PARTITION OF beta_pos FOR VALUES IN ('0007', '0009') +-- +TABLE: name="beta_pos_p3" schema="" table="beta_pos_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE beta_pos_p3 PARTITION OF beta_pos FOR VALUES IN ('0007', '0009')" +== 576 +-- truncate_limit: 100 +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO beta_neg SELECT ... FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9)" +== 577 +-- truncate_limit: 100 +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO beta_neg SELECT ... FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9)" +== 578 +-- truncate_limit: 100 +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_neg" schema="" table="beta_neg" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO beta_neg SELECT ... FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9)" +== 579 +-- truncate_limit: 100 +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO beta_pos SELECT ... FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9)" +== 580 +-- truncate_limit: 100 +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO beta_pos SELECT ... FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9)" +== 581 +-- truncate_limit: 100 +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9) +-- +TABLE: name="beta_pos" schema="" table="beta_pos" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO beta_pos SELECT ... FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9)" +== 582 +-- truncate_limit: 100 +ANALYZE beta +-- +TABLE: name="beta" schema="" table="beta" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE beta" +== 583 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.*, t2.* FROM alpha t1 JOIN beta t2 ON t1.a = t2.a AND t1.b = t2.b W..." +== 584 +-- truncate_limit: 100 +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM alpha t1 JOIN beta t2 ON t1.a = t2.a AND t1.b = t2.b WHERE ... ORDER BY t1.a, t1.b" +== 585 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.*, t2.* FROM alpha t1 JOIN beta t2 ON t1.a = t2.a AND t1.c = t2.c W..." +== 586 +-- truncate_limit: 100 +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM alpha t1 JOIN beta t2 ON t1.a = t2.a AND t1.c = t2.c WHERE ... ORDER BY t1.a, t1...." +== 587 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.*, t2.* FROM alpha t1 JOIN beta t2 ON t1.a = t2.a AND t1.b = t2.b A..." +== 588 +-- truncate_limit: 100 +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b +-- +TABLE: name="alpha" schema="" table="alpha" ctx=Select +TABLE: name="beta" schema="" table="beta" ctx=Select +ALIAS: "t1"="alpha" +ALIAS: "t2"="beta" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t1" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM alpha t1 JOIN beta t2 ON t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c WHERE ... OR..." +== 589 +-- truncate_limit: 100 +-- partitionwise join with fractional paths +CREATE TABLE fract_t (id BIGINT, PRIMARY KEY (id)) PARTITION BY RANGE (id) +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fract_t (id bigint, PRIMARY KEY (id)) PARTITION BY RANGE (id)" +== 590 +-- truncate_limit: 100 +CREATE TABLE fract_t0 PARTITION OF fract_t FOR VALUES FROM ('0') TO ('1000') +-- +TABLE: name="fract_t0" schema="" table="fract_t0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fract_t0 PARTITION OF fract_t FOR VALUES FROM ('0') TO ('1000')" +== 591 +-- truncate_limit: 100 +CREATE TABLE fract_t1 PARTITION OF fract_t FOR VALUES FROM ('1000') TO ('2000') +-- +TABLE: name="fract_t1" schema="" table="fract_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fract_t1 PARTITION OF fract_t FOR VALUES FROM ('1000') TO ('2000')" +== 592 +-- truncate_limit: 100 +-- insert data +INSERT INTO fract_t (id) (SELECT generate_series(0, 1999)) +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fract_t (id) SELECT generate_series(0, 1999)" +== 593 +-- truncate_limit: 100 +ANALYZE fract_t +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE fract_t" +== 594 +-- truncate_limit: 100 +-- verify plan; nested index only scans +SET max_parallel_workers_per_gather = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 0" +== 595 +-- truncate_limit: 100 +SET enable_partitionwise_join = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partitionwise_join TO ON" +== 596 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id ASC LIMIT 10 +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +ALIAS: "x"="fract_t" +ALIAS: "y"="fract_t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id..." +== 597 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id DESC LIMIT 10 +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +TABLE: name="fract_t" schema="" table="fract_t" ctx=Select +ALIAS: "x"="fract_t" +ALIAS: "y"="fract_t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id..." +== 598 +-- truncate_limit: 100 +-- cleanup +DROP TABLE fract_t +-- +TABLE: name="fract_t" schema="" table="fract_t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fract_t" +== 599 +-- truncate_limit: 100 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers_per_gather" +== 600 +-- truncate_limit: 100 +RESET enable_partitionwise_join +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_partitionwise_join" diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json new file mode 100644 index 0000000..6644147 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json @@ -0,0 +1,702 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_prune.test b/parser/testdata/summary_truncate/postgres_regress/partition_prune.test new file mode 100644 index 0000000..13b75fe --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/partition_prune.test @@ -0,0 +1,6029 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test partitioning planner code +|-- + +-- Force generic plans to be used for all prepared statements in this file. +set plan_cache_mode = force_generic_plan +-- +STMT: VariableSetStmt +TRUNCATED: "SET plan_cache_mode TO force_generic_plan" +== 002 +-- truncate_limit: 100 +create table lp (a char) partition by list (a) +-- +TABLE: name="lp" schema="" table="lp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lp (a char(1)) PARTITION BY LIST (a)" +== 003 +-- truncate_limit: 100 +create table lp_default partition of lp default +-- +TABLE: name="lp_default" schema="" table="lp_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lp_default PARTITION OF lp DEFAULT" +== 004 +-- truncate_limit: 100 +create table lp_ef partition of lp for values in ('e', 'f') +-- +TABLE: name="lp_ef" schema="" table="lp_ef" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lp_ef PARTITION OF lp FOR VALUES IN ('e', 'f')" +== 005 +-- truncate_limit: 100 +create table lp_ad partition of lp for values in ('a', 'd') +-- +TABLE: name="lp_ad" schema="" table="lp_ad" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lp_ad PARTITION OF lp FOR VALUES IN ('a', 'd')" +== 006 +-- truncate_limit: 100 +create table lp_bc partition of lp for values in ('b', 'c') +-- +TABLE: name="lp_bc" schema="" table="lp_bc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lp_bc PARTITION OF lp FOR VALUES IN ('b', 'c')" +== 007 +-- truncate_limit: 100 +create table lp_g partition of lp for values in ('g') +-- +TABLE: name="lp_g" schema="" table="lp_g" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lp_g PARTITION OF lp FOR VALUES IN ('g')" +== 008 +-- truncate_limit: 100 +create table lp_null partition of lp for values in (null) +-- +TABLE: name="lp_null" schema="" table="lp_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lp_null PARTITION OF lp FOR VALUES IN (NULL)" +== 009 +-- truncate_limit: 100 +explain (costs off) select * from lp +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp" +== 010 +-- truncate_limit: 100 +explain (costs off) select * from lp where a > 'a' and a < 'd' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a > 'a' AND a < 'd'" +== 011 +-- truncate_limit: 100 +explain (costs off) select * from lp where a > 'a' and a <= 'd' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a > 'a' AND a <= 'd'" +== 012 +-- truncate_limit: 100 +explain (costs off) select * from lp where a = 'a' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a = 'a'" +== 013 +-- truncate_limit: 100 +explain (costs off) select * from lp where 'a' = a +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE 'a' = a" +== 014 +-- truncate_limit: 100 +/* commuted */ +explain (costs off) select * from lp where a is not null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a IS NOT NULL" +== 015 +-- truncate_limit: 100 +explain (costs off) select * from lp where a is null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a IS NULL" +== 016 +-- truncate_limit: 100 +explain (costs off) select * from lp where a = 'a' or a = 'c' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a = 'a' OR a = 'c'" +== 017 +-- truncate_limit: 100 +explain (costs off) select * from lp where a is not null and (a = 'a' or a = 'c') +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a IS NOT NULL AND (a = 'a' OR a = 'c')" +== 018 +-- truncate_limit: 100 +explain (costs off) select * from lp where a <> 'g' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a <> 'g'" +== 019 +-- truncate_limit: 100 +explain (costs off) select * from lp where a <> 'a' and a <> 'd' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a <> 'a' AND a <> 'd'" +== 020 +-- truncate_limit: 100 +explain (costs off) select * from lp where a not in ('a', 'd') +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a NOT IN ('a', 'd')" +== 021 +-- truncate_limit: 100 +-- collation matches the partitioning collation, pruning works +create table coll_pruning (a text collate "C") partition by list (a) +-- +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning (a text COLLATE \"C\") PARTITION BY LIST (a)" +== 022 +-- truncate_limit: 100 +create table coll_pruning_a partition of coll_pruning for values in ('a') +-- +TABLE: name="coll_pruning_a" schema="" table="coll_pruning_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning_a PARTITION OF coll_pruning FOR VALUES IN ('a')" +== 023 +-- truncate_limit: 100 +create table coll_pruning_b partition of coll_pruning for values in ('b') +-- +TABLE: name="coll_pruning_b" schema="" table="coll_pruning_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning_b PARTITION OF coll_pruning FOR VALUES IN ('b')" +== 024 +-- truncate_limit: 100 +create table coll_pruning_def partition of coll_pruning default +-- +TABLE: name="coll_pruning_def" schema="" table="coll_pruning_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning_def PARTITION OF coll_pruning DEFAULT" +== 025 +-- truncate_limit: 100 +explain (costs off) select * from coll_pruning where a collate "C" = 'a' collate "C" +-- +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coll_pruning WHERE a COLLATE \"C\" = 'a' COLLATE \"C\"" +== 026 +-- truncate_limit: 100 +-- collation doesn't match the partitioning collation, no pruning occurs +explain (costs off) select * from coll_pruning where a collate "POSIX" = 'a' collate "POSIX" +-- +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coll_pruning WHERE a COLLATE \"POSIX\" = 'a' COLLATE \"POSIX\"" +== 027 +-- truncate_limit: 100 +create table rlp (a int, b varchar) partition by range (a) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp (a int, b varchar) PARTITION BY RANGE (a)" +== 028 +-- truncate_limit: 100 +create table rlp_default partition of rlp default partition by list (a) +-- +TABLE: name="rlp_default" schema="" table="rlp_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp_default PARTITION OF rlp DEFAULT PARTITION BY LIST (a)" +== 029 +-- truncate_limit: 100 +create table rlp_default_default partition of rlp_default default +-- +TABLE: name="rlp_default_default" schema="" table="rlp_default_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp_default_default PARTITION OF rlp_default DEFAULT" +== 030 +-- truncate_limit: 100 +create table rlp_default_10 partition of rlp_default for values in (10) +-- +TABLE: name="rlp_default_10" schema="" table="rlp_default_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp_default_10 PARTITION OF rlp_default FOR VALUES IN (10)" +== 031 +-- truncate_limit: 100 +create table rlp_default_30 partition of rlp_default for values in (30) +-- +TABLE: name="rlp_default_30" schema="" table="rlp_default_30" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp_default_30 PARTITION OF rlp_default FOR VALUES IN (30)" +== 032 +-- truncate_limit: 100 +create table rlp_default_null partition of rlp_default for values in (null) +-- +TABLE: name="rlp_default_null" schema="" table="rlp_default_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp_default_null PARTITION OF rlp_default FOR VALUES IN (NULL)" +== 033 +-- truncate_limit: 100 +create table rlp1 partition of rlp for values from (minvalue) to (1) +-- +TABLE: name="rlp1" schema="" table="rlp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp1 PARTITION OF rlp FOR VALUES FROM (minvalue) TO (1)" +== 034 +-- truncate_limit: 100 +create table rlp2 partition of rlp for values from (1) to (10) +-- +TABLE: name="rlp2" schema="" table="rlp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp2 PARTITION OF rlp FOR VALUES FROM (1) TO (10)" +== 035 +-- truncate_limit: 100 +create table rlp3 (b varchar, a int) partition by list (b varchar_ops) +-- +TABLE: name="rlp3" schema="" table="rlp3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp3 (b varchar, a int) PARTITION BY LIST (b varchar_ops)" +== 036 +-- truncate_limit: 100 +create table rlp3_default partition of rlp3 default +-- +TABLE: name="rlp3_default" schema="" table="rlp3_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp3_default PARTITION OF rlp3 DEFAULT" +== 037 +-- truncate_limit: 100 +create table rlp3abcd partition of rlp3 for values in ('ab', 'cd') +-- +TABLE: name="rlp3abcd" schema="" table="rlp3abcd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp3abcd PARTITION OF rlp3 FOR VALUES IN ('ab', 'cd')" +== 038 +-- truncate_limit: 100 +create table rlp3efgh partition of rlp3 for values in ('ef', 'gh') +-- +TABLE: name="rlp3efgh" schema="" table="rlp3efgh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp3efgh PARTITION OF rlp3 FOR VALUES IN ('ef', 'gh')" +== 039 +-- truncate_limit: 100 +create table rlp3nullxy partition of rlp3 for values in (null, 'xy') +-- +TABLE: name="rlp3nullxy" schema="" table="rlp3nullxy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp3nullxy PARTITION OF rlp3 FOR VALUES IN (NULL, 'xy')" +== 040 +-- truncate_limit: 100 +alter table rlp attach partition rlp3 for values from (15) to (20) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rlp ATTACH PARTITION rlp3 FOR VALUES FROM (15) TO (20)" +== 041 +-- truncate_limit: 100 +create table rlp4 partition of rlp for values from (20) to (30) partition by range (a) +-- +TABLE: name="rlp4" schema="" table="rlp4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp4 PARTITION OF rlp FOR VALUES FROM (20) TO (30) PARTITION BY RANGE (a)" +== 042 +-- truncate_limit: 100 +create table rlp4_default partition of rlp4 default +-- +TABLE: name="rlp4_default" schema="" table="rlp4_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp4_default PARTITION OF rlp4 DEFAULT" +== 043 +-- truncate_limit: 100 +create table rlp4_1 partition of rlp4 for values from (20) to (25) +-- +TABLE: name="rlp4_1" schema="" table="rlp4_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp4_1 PARTITION OF rlp4 FOR VALUES FROM (20) TO (25)" +== 044 +-- truncate_limit: 100 +create table rlp4_2 partition of rlp4 for values from (25) to (29) +-- +TABLE: name="rlp4_2" schema="" table="rlp4_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp4_2 PARTITION OF rlp4 FOR VALUES FROM (25) TO (29)" +== 045 +-- truncate_limit: 100 +create table rlp5 partition of rlp for values from (31) to (maxvalue) partition by range (a) +-- +TABLE: name="rlp5" schema="" table="rlp5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp5 PARTITION OF rlp FOR VALUES FROM (31) TO (maxvalue) PARTITION BY RANGE (a)" +== 046 +-- truncate_limit: 100 +create table rlp5_default partition of rlp5 default +-- +TABLE: name="rlp5_default" schema="" table="rlp5_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp5_default PARTITION OF rlp5 DEFAULT" +== 047 +-- truncate_limit: 100 +create table rlp5_1 partition of rlp5 for values from (31) to (40) +-- +TABLE: name="rlp5_1" schema="" table="rlp5_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rlp5_1 PARTITION OF rlp5 FOR VALUES FROM (31) TO (40)" +== 048 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a < 1 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a < 1" +== 049 +-- truncate_limit: 100 +explain (costs off) select * from rlp where 1 > a +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE 1 > a" +== 050 +-- truncate_limit: 100 +/* commuted */ +explain (costs off) select * from rlp where a <= 1 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a <= 1" +== 051 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 1 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 1" +== 052 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 1::bigint +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 1::bigint" +== 053 +-- truncate_limit: 100 +/* same as above */ +explain (costs off) select * from rlp where a = 1::numeric +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 1::numeric" +== 054 +-- truncate_limit: 100 +/* no pruning */ +explain (costs off) select * from rlp where a <= 10 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a <= 10" +== 055 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a > 10 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a > 10" +== 056 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a < 15 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a < 15" +== 057 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a <= 15 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a <= 15" +== 058 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a > 15 and b = 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a > 15 AND b = 'ab'" +== 059 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 16 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 16" +== 060 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 16 and b in ('not', 'in', 'here') +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 16 AND b IN ('not', 'in', 'here')" +== 061 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 16 and b < 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 16 AND b < 'ab'" +== 062 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 16 and b <= 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 16 AND b <= 'ab'" +== 063 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 16 and b is null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 16 AND b IS NULL" +== 064 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 16 and b is not null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 16 AND b IS NOT NULL" +== 065 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a is null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a IS NULL" +== 066 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a is not null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a IS NOT NULL" +== 067 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a > 30 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a > 30" +== 068 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 30 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 30" +== 069 +-- truncate_limit: 100 +/* only default is scanned */ +explain (costs off) select * from rlp where a <= 31 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a <= 31" +== 070 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 1 or a = 7 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 1 OR a = 7" +== 071 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 1 or b = 'ab' +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 1 OR b = 'ab'" +== 072 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a > 20 and a < 27 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a > 20 AND a < 27" +== 073 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a = 29 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 29" +== 074 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a >= 29 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a >= 29" +== 075 +-- truncate_limit: 100 +explain (costs off) select * from rlp where a < 1 or (a > 20 and a < 25) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a < 1 OR (a > 20 AND a < 25)" +== 076 +-- truncate_limit: 100 +-- where clause contradicts sub-partition's constraint +explain (costs off) select * from rlp where a = 20 or a = 40 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 20 OR a = 40" +== 077 +-- truncate_limit: 100 +explain (costs off) select * from rlp3 where a = 20 +-- +TABLE: name="rlp3" schema="" table="rlp3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp3 WHERE a = 20" +== 078 +-- truncate_limit: 100 +/* empty */ + +-- redundant clauses are eliminated +explain (costs off) select * from rlp where a > 1 and a = 10 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a > 1 AND a = 10" +== 079 +-- truncate_limit: 100 +/* only default */ +explain (costs off) select * from rlp where a > 1 and a >=15 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a > 1 AND a >= 15" +== 080 +-- truncate_limit: 100 +/* rlp3 onwards, including default */ +explain (costs off) select * from rlp where a = 1 and a = 3 +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 1 AND a = 3" +== 081 +-- truncate_limit: 100 +/* empty */ +explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = 15) +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE (a = 1 AND a = 3) OR (a > 1 AND a = 15)" +== 082 +-- truncate_limit: 100 +-- multi-column keys +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p (a int, b int, c int) PARTITION BY RANGE (a, (abs(b)), c)" +== 083 +-- truncate_limit: 100 +create table mc3p_default partition of mc3p default +-- +TABLE: name="mc3p_default" schema="" table="mc3p_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p_default PARTITION OF mc3p DEFAULT" +== 084 +-- truncate_limit: 100 +create table mc3p0 partition of mc3p for values from (minvalue, minvalue, minvalue) to (1, 1, 1) +-- +TABLE: name="mc3p0" schema="" table="mc3p0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p0 PARTITION OF mc3p FOR VALUES FROM (minvalue, minvalue, minvalue) TO (1, 1, 1)" +== 085 +-- truncate_limit: 100 +create table mc3p1 partition of mc3p for values from (1, 1, 1) to (10, 5, 10) +-- +TABLE: name="mc3p1" schema="" table="mc3p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p1 PARTITION OF mc3p FOR VALUES FROM (1, 1, 1) TO (10, 5, 10)" +== 086 +-- truncate_limit: 100 +create table mc3p2 partition of mc3p for values from (10, 5, 10) to (10, 10, 10) +-- +TABLE: name="mc3p2" schema="" table="mc3p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p2 PARTITION OF mc3p FOR VALUES FROM (10, 5, 10) TO (10, 10, 10)" +== 087 +-- truncate_limit: 100 +create table mc3p3 partition of mc3p for values from (10, 10, 10) to (10, 10, 20) +-- +TABLE: name="mc3p3" schema="" table="mc3p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p3 PARTITION OF mc3p FOR VALUES FROM (10, 10, 10) TO (10, 10, 20)" +== 088 +-- truncate_limit: 100 +create table mc3p4 partition of mc3p for values from (10, 10, 20) to (10, maxvalue, maxvalue) +-- +TABLE: name="mc3p4" schema="" table="mc3p4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p4 PARTITION OF mc3p FOR VALUES FROM (10, 10, 20) TO (10, maxvalue, maxvalue)" +== 089 +-- truncate_limit: 100 +create table mc3p5 partition of mc3p for values from (11, 1, 1) to (20, 10, 10) +-- +TABLE: name="mc3p5" schema="" table="mc3p5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p5 PARTITION OF mc3p FOR VALUES FROM (11, 1, 1) TO (20, 10, 10)" +== 090 +-- truncate_limit: 100 +create table mc3p6 partition of mc3p for values from (20, 10, 10) to (20, 20, 20) +-- +TABLE: name="mc3p6" schema="" table="mc3p6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p6 PARTITION OF mc3p FOR VALUES FROM (20, 10, 10) TO (20, 20, 20)" +== 091 +-- truncate_limit: 100 +create table mc3p7 partition of mc3p for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) +-- +TABLE: name="mc3p7" schema="" table="mc3p7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p7 PARTITION OF mc3p FOR VALUES FROM (20, 20, 20) TO (maxvalue, maxvalue, maxvalue)" +== 092 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 1" +== 093 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 1 and abs(b) < 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 1 AND abs(b) < 1" +== 094 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 1 and abs(b) = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 1 AND abs(b) = 1" +== 095 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 1 and abs(b) = 1 and c < 8 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 1 AND abs(b) = 1 AND c < 8" +== 096 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 10 and abs(b) between 5 and 35 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 10 AND abs(b) BETWEEN 5 AND 35" +== 097 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a > 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a > 10" +== 098 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a >= 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a >= 10" +== 099 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a < 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a < 10" +== 100 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a <= 10 and abs(b) < 10 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a <= 10 AND abs(b) < 10" +== 101 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 11 and abs(b) = 0 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 11 AND abs(b) = 0" +== 102 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 20 and abs(b) = 10 and c = 100 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 20 AND abs(b) = 10 AND c = 100" +== 103 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a > 20 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a > 20" +== 104 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a >= 20 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a >= 20" +== 105 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE (a = 1 AND abs(b) = 1 AND c = 1) OR (a = 10 AND abs(..." +== 106 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) or a < 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE (a = 1 AND abs(b) = 1 AND c = 1) OR (a = 10 AND abs(..." +== 107 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) or a < 1 or a = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE (a = 1 AND abs(b) = 1 AND c = 1) OR (a = 10 AND abs(..." +== 108 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where a = 1 or abs(b) = 1 or c = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE a = 1 OR abs(b) = 1 OR c = 1" +== 109 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1) or (a = 10 and abs(b) = 10) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE (a = 1 AND abs(b) = 1) OR (a = 10 AND abs(b) = 10)" +== 110 +-- truncate_limit: 100 +explain (costs off) select * from mc3p where (a = 1 and abs(b) = 1) or (a = 10 and abs(b) = 9) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc3p WHERE (a = 1 AND abs(b) = 1) OR (a = 10 AND abs(b) = 9)" +== 111 +-- truncate_limit: 100 +-- a simpler multi-column keys case +create table mc2p (a int, b int) partition by range (a, b) +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p (a int, b int) PARTITION BY RANGE (a, b)" +== 112 +-- truncate_limit: 100 +create table mc2p_default partition of mc2p default +-- +TABLE: name="mc2p_default" schema="" table="mc2p_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p_default PARTITION OF mc2p DEFAULT" +== 113 +-- truncate_limit: 100 +create table mc2p0 partition of mc2p for values from (minvalue, minvalue) to (1, minvalue) +-- +TABLE: name="mc2p0" schema="" table="mc2p0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p0 PARTITION OF mc2p FOR VALUES FROM (minvalue, minvalue) TO (1, minvalue)" +== 114 +-- truncate_limit: 100 +create table mc2p1 partition of mc2p for values from (1, minvalue) to (1, 1) +-- +TABLE: name="mc2p1" schema="" table="mc2p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p1 PARTITION OF mc2p FOR VALUES FROM (1, minvalue) TO (1, 1)" +== 115 +-- truncate_limit: 100 +create table mc2p2 partition of mc2p for values from (1, 1) to (2, minvalue) +-- +TABLE: name="mc2p2" schema="" table="mc2p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p2 PARTITION OF mc2p FOR VALUES FROM (1, 1) TO (2, minvalue)" +== 116 +-- truncate_limit: 100 +create table mc2p3 partition of mc2p for values from (2, minvalue) to (2, 1) +-- +TABLE: name="mc2p3" schema="" table="mc2p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p3 PARTITION OF mc2p FOR VALUES FROM (2, minvalue) TO (2, 1)" +== 117 +-- truncate_limit: 100 +create table mc2p4 partition of mc2p for values from (2, 1) to (2, maxvalue) +-- +TABLE: name="mc2p4" schema="" table="mc2p4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p4 PARTITION OF mc2p FOR VALUES FROM (2, 1) TO (2, maxvalue)" +== 118 +-- truncate_limit: 100 +create table mc2p5 partition of mc2p for values from (2, maxvalue) to (maxvalue, maxvalue) +-- +TABLE: name="mc2p5" schema="" table="mc2p5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc2p5 PARTITION OF mc2p FOR VALUES FROM (2, maxvalue) TO (maxvalue, maxvalue)" +== 119 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where a < 2 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a < 2" +== 120 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where a = 2 and b < 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a = 2 AND b < 1" +== 121 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where a > 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a > 1" +== 122 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where a = 1 and b > 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a = 1 AND b > 1" +== 123 +-- truncate_limit: 100 +-- all partitions but the default one should be pruned +explain (costs off) select * from mc2p where a = 1 and b is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a = 1 AND b IS NULL" +== 124 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where a is null and b is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a IS NULL AND b IS NULL" +== 125 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where a is null and b = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a IS NULL AND b = 1" +== 126 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where a is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE a IS NULL" +== 127 +-- truncate_limit: 100 +explain (costs off) select * from mc2p where b is null +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p WHERE b IS NULL" +== 128 +-- truncate_limit: 100 +-- boolean partitioning +create table boolpart (a bool) partition by list (a) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolpart (a bool) PARTITION BY LIST (a)" +== 129 +-- truncate_limit: 100 +create table boolpart_default partition of boolpart default +-- +TABLE: name="boolpart_default" schema="" table="boolpart_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolpart_default PARTITION OF boolpart DEFAULT" +== 130 +-- truncate_limit: 100 +create table boolpart_t partition of boolpart for values in ('true') +-- +TABLE: name="boolpart_t" schema="" table="boolpart_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolpart_t PARTITION OF boolpart FOR VALUES IN ('true')" +== 131 +-- truncate_limit: 100 +create table boolpart_f partition of boolpart for values in ('false') +-- +TABLE: name="boolpart_f" schema="" table="boolpart_f" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolpart_f PARTITION OF boolpart FOR VALUES IN ('false')" +== 132 +-- truncate_limit: 100 +insert into boolpart values (true), (false), (null) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO boolpart VALUES (true), (false), (NULL)" +== 133 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a in (true, false) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IN (true, false)" +== 134 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a = false" +== 135 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where not a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE NOT a = false" +== 136 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is true or a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS TRUE OR a IS NOT TRUE" +== 137 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT TRUE" +== 138 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT TRUE AND a IS NOT FALSE" +== 139 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS UNKNOWN" +== 140 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT UNKNOWN" +== 141 +-- truncate_limit: 100 +select * from boolpart where a in (true, false) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IN (true, false)" +== 142 +-- truncate_limit: 100 +select * from boolpart where a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a = false" +== 143 +-- truncate_limit: 100 +select * from boolpart where not a = false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE NOT a = false" +== 144 +-- truncate_limit: 100 +select * from boolpart where a is true or a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS TRUE OR a IS NOT TRUE" +== 145 +-- truncate_limit: 100 +select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS NOT TRUE" +== 146 +-- truncate_limit: 100 +select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS NOT TRUE AND a IS NOT FALSE" +== 147 +-- truncate_limit: 100 +select * from boolpart where a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS UNKNOWN" +== 148 +-- truncate_limit: 100 +select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS NOT UNKNOWN" +== 149 +-- truncate_limit: 100 +-- try some other permutations with a NULL partition instead of a DEFAULT +delete from boolpart where a is null +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM boolpart WHERE a IS NULL" +== 150 +-- truncate_limit: 100 +create table boolpart_null partition of boolpart for values in (null) +-- +TABLE: name="boolpart_null" schema="" table="boolpart_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolpart_null PARTITION OF boolpart FOR VALUES IN (NULL)" +== 151 +-- truncate_limit: 100 +insert into boolpart values(null) +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO boolpart VALUES (NULL)" +== 152 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT TRUE" +== 153 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT TRUE AND a IS NOT FALSE" +== 154 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT FALSE" +== 155 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT UNKNOWN" +== 156 +-- truncate_limit: 100 +select * from boolpart where a is not true +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS NOT TRUE" +== 157 +-- truncate_limit: 100 +select * from boolpart where a is not true and a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS NOT TRUE AND a IS NOT FALSE" +== 158 +-- truncate_limit: 100 +select * from boolpart where a is not false +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS NOT FALSE" +== 159 +-- truncate_limit: 100 +select * from boolpart where a is not unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM boolpart WHERE a IS NOT UNKNOWN" +== 160 +-- truncate_limit: 100 +-- check that all partitions are pruned when faced with conflicting clauses +explain (costs off) select * from boolpart where a is not unknown and a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS NOT UNKNOWN AND a IS UNKNOWN" +== 161 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is false and a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS FALSE AND a IS UNKNOWN" +== 162 +-- truncate_limit: 100 +explain (costs off) select * from boolpart where a is true and a is unknown +-- +TABLE: name="boolpart" schema="" table="boolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolpart WHERE a IS TRUE AND a IS UNKNOWN" +== 163 +-- truncate_limit: 100 +-- inverse boolean partitioning - a seemingly unlikely design, but we've got +-- code for it, so we'd better test it. +create table iboolpart (a bool) partition by list ((not a)) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iboolpart (a bool) PARTITION BY LIST ((NOT a))" +== 164 +-- truncate_limit: 100 +create table iboolpart_default partition of iboolpart default +-- +TABLE: name="iboolpart_default" schema="" table="iboolpart_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iboolpart_default PARTITION OF iboolpart DEFAULT" +== 165 +-- truncate_limit: 100 +create table iboolpart_f partition of iboolpart for values in ('true') +-- +TABLE: name="iboolpart_f" schema="" table="iboolpart_f" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iboolpart_f PARTITION OF iboolpart FOR VALUES IN ('true')" +== 166 +-- truncate_limit: 100 +create table iboolpart_t partition of iboolpart for values in ('false') +-- +TABLE: name="iboolpart_t" schema="" table="iboolpart_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iboolpart_t PARTITION OF iboolpart FOR VALUES IN ('false')" +== 167 +-- truncate_limit: 100 +insert into iboolpart values (true), (false), (null) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iboolpart VALUES (true), (false), (NULL)" +== 168 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where a in (true, false) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE a IN (true, false)" +== 169 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE a = false" +== 170 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where not a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE NOT a = false" +== 171 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where a is true or a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE a IS TRUE OR a IS NOT TRUE" +== 172 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE a IS NOT TRUE" +== 173 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where a is not true and a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE a IS NOT TRUE AND a IS NOT FALSE" +== 174 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where a is unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE a IS UNKNOWN" +== 175 +-- truncate_limit: 100 +explain (costs off) select * from iboolpart where a is not unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM iboolpart WHERE a IS NOT UNKNOWN" +== 176 +-- truncate_limit: 100 +select * from iboolpart where a in (true, false) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IN (true, false)" +== 177 +-- truncate_limit: 100 +select * from iboolpart where a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a = false" +== 178 +-- truncate_limit: 100 +select * from iboolpart where not a = false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE NOT a = false" +== 179 +-- truncate_limit: 100 +select * from iboolpart where a is true or a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS TRUE OR a IS NOT TRUE" +== 180 +-- truncate_limit: 100 +select * from iboolpart where a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS NOT TRUE" +== 181 +-- truncate_limit: 100 +select * from iboolpart where a is not true and a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS NOT TRUE AND a IS NOT FALSE" +== 182 +-- truncate_limit: 100 +select * from iboolpart where a is unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS UNKNOWN" +== 183 +-- truncate_limit: 100 +select * from iboolpart where a is not unknown +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS NOT UNKNOWN" +== 184 +-- truncate_limit: 100 +-- Try some other permutations with a NULL partition instead of a DEFAULT +delete from iboolpart where a is null +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM iboolpart WHERE a IS NULL" +== 185 +-- truncate_limit: 100 +create table iboolpart_null partition of iboolpart for values in (null) +-- +TABLE: name="iboolpart_null" schema="" table="iboolpart_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iboolpart_null PARTITION OF iboolpart FOR VALUES IN (NULL)" +== 186 +-- truncate_limit: 100 +insert into iboolpart values(null) +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iboolpart VALUES (NULL)" +== 187 +-- truncate_limit: 100 +-- Pruning shouldn't take place for these. Just check the result is correct +select * from iboolpart where a is not true +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS NOT TRUE" +== 188 +-- truncate_limit: 100 +select * from iboolpart where a is not true and a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS NOT TRUE AND a IS NOT FALSE" +== 189 +-- truncate_limit: 100 +select * from iboolpart where a is not false +-- +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM iboolpart WHERE a IS NOT FALSE" +== 190 +-- truncate_limit: 100 +create table boolrangep (a bool, b bool, c int) partition by range (a,b,c) +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolrangep (a bool, b bool, c int) PARTITION BY RANGE (a, b, c)" +== 191 +-- truncate_limit: 100 +create table boolrangep_tf partition of boolrangep for values from ('true', 'false', 0) to ('true', 'false', 100) +-- +TABLE: name="boolrangep_tf" schema="" table="boolrangep_tf" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolrangep_tf PARTITION OF boolrangep FOR VALUES FROM ('true', 'false', 0) TO ('true..." +== 192 +-- truncate_limit: 100 +create table boolrangep_ft partition of boolrangep for values from ('false', 'true', 0) to ('false', 'true', 100) +-- +TABLE: name="boolrangep_ft" schema="" table="boolrangep_ft" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolrangep_ft PARTITION OF boolrangep FOR VALUES FROM ('false', 'true', 0) TO ('fals..." +== 193 +-- truncate_limit: 100 +create table boolrangep_ff1 partition of boolrangep for values from ('false', 'false', 0) to ('false', 'false', 50) +-- +TABLE: name="boolrangep_ff1" schema="" table="boolrangep_ff1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolrangep_ff1 PARTITION OF boolrangep FOR VALUES FROM ('false', 'false', 0) TO ('fa..." +== 194 +-- truncate_limit: 100 +create table boolrangep_ff2 partition of boolrangep for values from ('false', 'false', 50) to ('false', 'false', 100) +-- +TABLE: name="boolrangep_ff2" schema="" table="boolrangep_ff2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolrangep_ff2 PARTITION OF boolrangep FOR VALUES FROM ('false', 'false', 50) TO ('f..." +== 195 +-- truncate_limit: 100 +create table boolrangep_null partition of boolrangep default +-- +TABLE: name="boolrangep_null" schema="" table="boolrangep_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolrangep_null PARTITION OF boolrangep DEFAULT" +== 196 +-- truncate_limit: 100 +-- try a more complex case that's been known to trip up pruning in the past +explain (costs off) select * from boolrangep where not a and not b and c = 25 +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolrangep WHERE NOT a AND NOT b AND c = 25" +== 197 +-- truncate_limit: 100 +-- ensure we prune boolrangep_tf +explain (costs off) select * from boolrangep where a is not true and not b and c = 25 +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolrangep WHERE a IS NOT TRUE AND NOT b AND c = 25" +== 198 +-- truncate_limit: 100 +-- ensure we prune everything apart from boolrangep_tf and boolrangep_null +explain (costs off) select * from boolrangep where a is not false and not b and c = 25 +-- +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM boolrangep WHERE a IS NOT FALSE AND NOT b AND c = 25" +== 199 +-- truncate_limit: 100 +-- test scalar-to-array operators +create table coercepart (a varchar) partition by list (a) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coercepart (a varchar) PARTITION BY LIST (a)" +== 200 +-- truncate_limit: 100 +create table coercepart_ab partition of coercepart for values in ('ab') +-- +TABLE: name="coercepart_ab" schema="" table="coercepart_ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coercepart_ab PARTITION OF coercepart FOR VALUES IN ('ab')" +== 201 +-- truncate_limit: 100 +create table coercepart_bc partition of coercepart for values in ('bc') +-- +TABLE: name="coercepart_bc" schema="" table="coercepart_bc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coercepart_bc PARTITION OF coercepart FOR VALUES IN ('bc')" +== 202 +-- truncate_limit: 100 +create table coercepart_cd partition of coercepart for values in ('cd') +-- +TABLE: name="coercepart_cd" schema="" table="coercepart_cd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coercepart_cd PARTITION OF coercepart FOR VALUES IN ('cd')" +== 203 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a in ('ab', to_char(125, '999')) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a IN ('ab', to_char(125, '999'))" +== 204 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a ~ any ('{ab}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a ~ ANY('{ab}')" +== 205 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a !~ all ('{ab}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a !~ ALL('{ab}')" +== 206 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a ~ any ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a ~ ANY('{ab,bc}')" +== 207 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a !~ all ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a !~ ALL('{ab,bc}')" +== 208 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a = any ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a = ANY('{ab,bc}')" +== 209 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a = any ('{ab,null}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a = ANY('{ab,null}')" +== 210 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a = any (null::text[]) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a = ANY(NULL::text[])" +== 211 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a = all ('{ab}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a = ALL('{ab}')" +== 212 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a = all ('{ab,bc}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a = ALL('{ab,bc}')" +== 213 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a = all ('{ab,null}') +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a = ALL('{ab,null}')" +== 214 +-- truncate_limit: 100 +explain (costs off) select * from coercepart where a = all (null::text[]) +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coercepart WHERE a = ALL(NULL::text[])" +== 215 +-- truncate_limit: 100 +drop table coercepart +-- +TABLE: name="coercepart" schema="" table="coercepart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE coercepart" +== 216 +-- truncate_limit: 100 +CREATE TABLE part (a INT, b INT) PARTITION BY LIST (a) +-- +TABLE: name="part" schema="" table="part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part (a int, b int) PARTITION BY LIST (a)" +== 217 +-- truncate_limit: 100 +CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2) +-- +TABLE: name="part_p1" schema="" table="part_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2, -1, 0, 1, 2)" +== 218 +-- truncate_limit: 100 +CREATE TABLE part_p2 PARTITION OF part DEFAULT PARTITION BY RANGE(a) +-- +TABLE: name="part_p2" schema="" table="part_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_p2 PARTITION OF part DEFAULT PARTITION BY RANGE (a)" +== 219 +-- truncate_limit: 100 +CREATE TABLE part_p2_p1 PARTITION OF part_p2 DEFAULT +-- +TABLE: name="part_p2_p1" schema="" table="part_p2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_p2_p1 PARTITION OF part_p2 DEFAULT" +== 220 +-- truncate_limit: 100 +CREATE TABLE part_rev (b INT, c INT, a INT) +-- +TABLE: name="part_rev" schema="" table="part_rev" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_rev (b int, c int, a int)" +== 221 +-- truncate_limit: 100 +ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3) +-- +TABLE: name="part" schema="" table="part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3)" +== 222 +-- truncate_limit: 100 +-- fail +ALTER TABLE part_rev DROP COLUMN c +-- +TABLE: name="part_rev" schema="" table="part_rev" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_rev DROP c" +== 223 +-- truncate_limit: 100 +ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3) +-- +TABLE: name="part" schema="" table="part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3)" +== 224 +-- truncate_limit: 100 +-- now it's ok +INSERT INTO part VALUES (-1,-1), (1,1), (2,NULL), (NULL,-2),(NULL,NULL) +-- +TABLE: name="part" schema="" table="part" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part VALUES (-1, -1), (1, 1), (2, NULL), (NULL, -2), (NULL, NULL)" +== 225 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT tableoid::regclass as part, a, b FROM part WHERE a IS NULL ORDER BY 1, 2, 3 +-- +TABLE: name="part" schema="" table="part" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT tableoid::regclass AS part, a, b FROM part WHERE a IS NULL ORDER BY 1,..." +== 226 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM part p(x) ORDER BY x +-- +TABLE: name="part" schema="" table="part" ctx=Select +ALIAS: "p"="part" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM part p(x) ORDER BY x" +== 227 +-- truncate_limit: 100 +|-- +-- some more cases +|-- + +|-- +-- pruning for partitioned table appearing inside a sub-query +|-- +-- pruning won't work for mc3p, because some keys are Params +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = t1.b and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +ALIAS: "t1"="mc2p" +ALIAS: "t2"="mc3p" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p t1, LATERAL (SELECT count(*) FROM mc3p t2 WHERE t2.a = t1...." +== 228 +-- truncate_limit: 100 +-- pruning should work fine, because values for a prefix of keys (a, b) are +-- available +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.c = t1.b and abs(t2.b) = 1 and t2.a = 1) s where t1.a = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +ALIAS: "t1"="mc2p" +ALIAS: "t2"="mc3p" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="c" +FILTER: schema="" table="t1" column="b" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p t1, LATERAL (SELECT count(*) FROM mc3p t2 WHERE t2.c = t1...." +== 229 +-- truncate_limit: 100 +-- also here, because values for all keys are provided +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = 1 and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1 +-- +TABLE: name="mc2p" schema="" table="mc2p" ctx=Select +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +ALIAS: "t1"="mc2p" +ALIAS: "t2"="mc3p" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t2" column="a" +FILTER: schema="" table="t2" column="b" +FILTER: schema="" table="t2" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM mc2p t1, LATERAL (SELECT count(*) FROM mc3p t2 WHERE t2.a = 1 A..." +== 230 +-- truncate_limit: 100 +|-- +-- pruning with clauses containing <> operator +|-- + +-- doesn't prune range partitions +create table rp (a int) partition by range (a) +-- +TABLE: name="rp" schema="" table="rp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp (a int) PARTITION BY RANGE (a)" +== 231 +-- truncate_limit: 100 +create table rp0 partition of rp for values from (minvalue) to (1) +-- +TABLE: name="rp0" schema="" table="rp0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp0 PARTITION OF rp FOR VALUES FROM (minvalue) TO (1)" +== 232 +-- truncate_limit: 100 +create table rp1 partition of rp for values from (1) to (2) +-- +TABLE: name="rp1" schema="" table="rp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp1 PARTITION OF rp FOR VALUES FROM (1) TO (2)" +== 233 +-- truncate_limit: 100 +create table rp2 partition of rp for values from (2) to (maxvalue) +-- +TABLE: name="rp2" schema="" table="rp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp2 PARTITION OF rp FOR VALUES FROM (2) TO (maxvalue)" +== 234 +-- truncate_limit: 100 +explain (costs off) select * from rp where a <> 1 +-- +TABLE: name="rp" schema="" table="rp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rp WHERE a <> 1" +== 235 +-- truncate_limit: 100 +explain (costs off) select * from rp where a <> 1 and a <> 2 +-- +TABLE: name="rp" schema="" table="rp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rp WHERE a <> 1 AND a <> 2" +== 236 +-- truncate_limit: 100 +-- null partition should be eliminated due to strict <> clause. +explain (costs off) select * from lp where a <> 'a' +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a <> 'a'" +== 237 +-- truncate_limit: 100 +-- ensure we detect contradictions in clauses; a can't be NULL and NOT NULL. +explain (costs off) select * from lp where a <> 'a' and a is null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE a <> 'a' AND a IS NULL" +== 238 +-- truncate_limit: 100 +explain (costs off) select * from lp where (a <> 'a' and a <> 'd') or a is null +-- +TABLE: name="lp" schema="" table="lp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lp WHERE (a <> 'a' AND a <> 'd') OR a IS NULL" +== 239 +-- truncate_limit: 100 +-- check that it also works for a partitioned table that's not root, +-- which in this case are partitions of rlp that are themselves +-- list-partitioned on b +explain (costs off) select * from rlp where a = 15 and b <> 'ab' and b <> 'cd' and b <> 'xy' and b is not null +-- +TABLE: name="rlp" schema="" table="rlp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rlp WHERE a = 15 AND b <> 'ab' AND b <> 'cd' AND b <> 'xy' AND ..." +== 240 +-- truncate_limit: 100 +|-- +-- different collations for different keys with same expression +|-- +create table coll_pruning_multi (a text) partition by range (substr(a, 1) collate "POSIX", substr(a, 1) collate "C") +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning_multi (a text) PARTITION BY RANGE ((substr(a, 1)) COLLATE \"POSIX\", (sub..." +== 241 +-- truncate_limit: 100 +create table coll_pruning_multi1 partition of coll_pruning_multi for values from ('a', 'a') to ('a', 'e') +-- +TABLE: name="coll_pruning_multi1" schema="" table="coll_pruning_multi1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning_multi1 PARTITION OF coll_pruning_multi FOR VALUES FROM ('a', 'a') TO ('..." +== 242 +-- truncate_limit: 100 +create table coll_pruning_multi2 partition of coll_pruning_multi for values from ('a', 'e') to ('a', 'z') +-- +TABLE: name="coll_pruning_multi2" schema="" table="coll_pruning_multi2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning_multi2 PARTITION OF coll_pruning_multi FOR VALUES FROM ('a', 'e') TO ('..." +== 243 +-- truncate_limit: 100 +create table coll_pruning_multi3 partition of coll_pruning_multi for values from ('b', 'a') to ('b', 'e') +-- +TABLE: name="coll_pruning_multi3" schema="" table="coll_pruning_multi3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE coll_pruning_multi3 PARTITION OF coll_pruning_multi FOR VALUES FROM ('b', 'a') TO ('..." +== 244 +-- truncate_limit: 100 +-- no pruning, because no value for the leading key +explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'e' collate "C" +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coll_pruning_multi WHERE substr(a, 1) = 'e' COLLATE \"C\"" +== 245 +-- truncate_limit: 100 +-- pruning, with a value provided for the leading key +explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'a' collate "POSIX" +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coll_pruning_multi WHERE substr(a, 1) = 'a' COLLATE \"POSIX\"" +== 246 +-- truncate_limit: 100 +-- pruning, with values provided for both keys +explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'e' collate "C" and substr(a, 1) = 'a' collate "POSIX" +-- +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM coll_pruning_multi WHERE substr(a, 1) = 'e' COLLATE \"C\" AND sub..." +== 247 +-- truncate_limit: 100 +|-- +-- LIKE operators don't prune +|-- +create table like_op_noprune (a text) partition by list (a) +-- +TABLE: name="like_op_noprune" schema="" table="like_op_noprune" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE like_op_noprune (a text) PARTITION BY LIST (a)" +== 248 +-- truncate_limit: 100 +create table like_op_noprune1 partition of like_op_noprune for values in ('ABC') +-- +TABLE: name="like_op_noprune1" schema="" table="like_op_noprune1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE like_op_noprune1 PARTITION OF like_op_noprune FOR VALUES IN ('ABC')" +== 249 +-- truncate_limit: 100 +create table like_op_noprune2 partition of like_op_noprune for values in ('BCD') +-- +TABLE: name="like_op_noprune2" schema="" table="like_op_noprune2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE like_op_noprune2 PARTITION OF like_op_noprune FOR VALUES IN ('BCD')" +== 250 +-- truncate_limit: 100 +explain (costs off) select * from like_op_noprune where a like '%BC' +-- +TABLE: name="like_op_noprune" schema="" table="like_op_noprune" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM like_op_noprune WHERE a LIKE '%BC'" +== 251 +-- truncate_limit: 100 +|-- +-- tests wherein clause value requires a cross-type comparison function +|-- +create table lparted_by_int2 (a smallint) partition by list (a) +-- +TABLE: name="lparted_by_int2" schema="" table="lparted_by_int2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lparted_by_int2 (a smallint) PARTITION BY LIST (a)" +== 252 +-- truncate_limit: 100 +create table lparted_by_int2_1 partition of lparted_by_int2 for values in (1) +-- +TABLE: name="lparted_by_int2_1" schema="" table="lparted_by_int2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lparted_by_int2_1 PARTITION OF lparted_by_int2 FOR VALUES IN (1)" +== 253 +-- truncate_limit: 100 +create table lparted_by_int2_16384 partition of lparted_by_int2 for values in (16384) +-- +TABLE: name="lparted_by_int2_16384" schema="" table="lparted_by_int2_16384" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lparted_by_int2_16384 PARTITION OF lparted_by_int2 FOR VALUES IN (16384)" +== 254 +-- truncate_limit: 100 +explain (costs off) select * from lparted_by_int2 where a = 100_000_000_000_000 +-- +TABLE: name="lparted_by_int2" schema="" table="lparted_by_int2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM lparted_by_int2 WHERE a = 100_000_000_000_000" +== 255 +-- truncate_limit: 100 +create table rparted_by_int2 (a smallint) partition by range (a) +-- +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rparted_by_int2 (a smallint) PARTITION BY RANGE (a)" +== 256 +-- truncate_limit: 100 +create table rparted_by_int2_1 partition of rparted_by_int2 for values from (1) to (10) +-- +TABLE: name="rparted_by_int2_1" schema="" table="rparted_by_int2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rparted_by_int2_1 PARTITION OF rparted_by_int2 FOR VALUES FROM (1) TO (10)" +== 257 +-- truncate_limit: 100 +create table rparted_by_int2_16384 partition of rparted_by_int2 for values from (10) to (16384) +-- +TABLE: name="rparted_by_int2_16384" schema="" table="rparted_by_int2_16384" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rparted_by_int2_16384 PARTITION OF rparted_by_int2 FOR VALUES FROM (10) TO (16384)" +== 258 +-- truncate_limit: 100 +-- all partitions pruned +explain (costs off) select * from rparted_by_int2 where a > 100_000_000_000_000 +-- +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rparted_by_int2 WHERE a > 100_000_000_000_000" +== 259 +-- truncate_limit: 100 +create table rparted_by_int2_maxvalue partition of rparted_by_int2 for values from (16384) to (maxvalue) +-- +TABLE: name="rparted_by_int2_maxvalue" schema="" table="rparted_by_int2_maxvalue" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rparted_by_int2_maxvalue PARTITION OF rparted_by_int2 FOR VALUES FROM (16384) TO (ma..." +== 260 +-- truncate_limit: 100 +-- all partitions but rparted_by_int2_maxvalue pruned +explain (costs off) select * from rparted_by_int2 where a > 100_000_000_000_000 +-- +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rparted_by_int2 WHERE a > 100_000_000_000_000" +== 261 +-- truncate_limit: 100 +drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2 +-- +TABLE: name="lp" schema="" table="lp" ctx=DDL +TABLE: name="coll_pruning" schema="" table="coll_pruning" ctx=DDL +TABLE: name="rlp" schema="" table="rlp" ctx=DDL +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +TABLE: name="mc2p" schema="" table="mc2p" ctx=DDL +TABLE: name="boolpart" schema="" table="boolpart" ctx=DDL +TABLE: name="iboolpart" schema="" table="iboolpart" ctx=DDL +TABLE: name="boolrangep" schema="" table="boolrangep" ctx=DDL +TABLE: name="rp" schema="" table="rp" ctx=DDL +TABLE: name="coll_pruning_multi" schema="" table="coll_pruning_multi" ctx=DDL +TABLE: name="like_op_noprune" schema="" table="like_op_noprune" ctx=DDL +TABLE: name="lparted_by_int2" schema="" table="lparted_by_int2" ctx=DDL +TABLE: name="rparted_by_int2" schema="" table="rparted_by_int2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_m..." +== 262 +-- truncate_limit: 100 +-- check that AlternativeSubPlan within a pruning expression gets cleaned up + +create table asptab (id int primary key) partition by range (id) +-- +TABLE: name="asptab" schema="" table="asptab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE asptab (id int PRIMARY KEY) PARTITION BY RANGE (id)" +== 263 +-- truncate_limit: 100 +create table asptab0 partition of asptab for values from (0) to (1) +-- +TABLE: name="asptab0" schema="" table="asptab0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE asptab0 PARTITION OF asptab FOR VALUES FROM (0) TO (1)" +== 264 +-- truncate_limit: 100 +create table asptab1 partition of asptab for values from (1) to (2) +-- +TABLE: name="asptab1" schema="" table="asptab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE asptab1 PARTITION OF asptab FOR VALUES FROM (1) TO (2)" +== 265 +-- truncate_limit: 100 +explain (costs off) +select * from + (select exists (select 1 from int4_tbl tinner where f1 = touter.f1) as b + from int4_tbl touter) ss, + asptab +where asptab.id > ss.b::int +-- +TABLE: name="asptab" schema="" table="asptab" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "tinner"="int4_tbl" +ALIAS: "touter"="int4_tbl" +FILTER: schema="" table="asptab" column="id" +FILTER: schema="" table="ss" column="b" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="touter" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT EXISTS (SELECT 1 FROM int4_tbl tinner WHERE f1 = touter..." +== 266 +-- truncate_limit: 100 +drop table asptab +-- +TABLE: name="asptab" schema="" table="asptab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE asptab" +== 267 +-- truncate_limit: 100 +|-- +-- Test Partition pruning for HASH partitioning +|-- +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different machines. See the definitions of +-- part_test_int4_ops and part_test_text_ops in test_setup.sql. +|-- + +create table hp (a int, b text, c int) + partition by hash (a part_test_int4_ops, b part_test_text_ops) +-- +TABLE: name="hp" schema="" table="hp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp (a int, b text, c int) PARTITION BY HASH (a part_test_int4_ops, b part_test_text_..." +== 268 +-- truncate_limit: 100 +create table hp0 partition of hp for values with (modulus 4, remainder 0) +-- +TABLE: name="hp0" schema="" table="hp0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp0 PARTITION OF hp FOR VALUES WITH (MODULUS 4, REMAINDER 0)" +== 269 +-- truncate_limit: 100 +create table hp3 partition of hp for values with (modulus 4, remainder 3) +-- +TABLE: name="hp3" schema="" table="hp3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp3 PARTITION OF hp FOR VALUES WITH (MODULUS 4, REMAINDER 3)" +== 270 +-- truncate_limit: 100 +create table hp1 partition of hp for values with (modulus 4, remainder 1) +-- +TABLE: name="hp1" schema="" table="hp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp1 PARTITION OF hp FOR VALUES WITH (MODULUS 4, REMAINDER 1)" +== 271 +-- truncate_limit: 100 +create table hp2 partition of hp for values with (modulus 4, remainder 2) +-- +TABLE: name="hp2" schema="" table="hp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp2 PARTITION OF hp FOR VALUES WITH (MODULUS 4, REMAINDER 2)" +== 272 +-- truncate_limit: 100 +insert into hp values (null, null, 0) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hp VALUES (NULL, NULL, 0)" +== 273 +-- truncate_limit: 100 +insert into hp values (1, null, 1) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hp VALUES (1, NULL, 1)" +== 274 +-- truncate_limit: 100 +insert into hp values (1, 'xxx', 2) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hp VALUES (1, 'xxx', 2)" +== 275 +-- truncate_limit: 100 +insert into hp values (null, 'xxx', 3) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hp VALUES (NULL, 'xxx', 3)" +== 276 +-- truncate_limit: 100 +insert into hp values (2, 'xxx', 4) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hp VALUES (2, 'xxx', 4)" +== 277 +-- truncate_limit: 100 +insert into hp values (1, 'abcde', 5) +-- +TABLE: name="hp" schema="" table="hp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hp VALUES (1, 'abcde', 5)" +== 278 +-- truncate_limit: 100 +select tableoid::regclass, * from hp order by c +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM hp ORDER BY c" +== 279 +-- truncate_limit: 100 +-- partial keys won't prune, nor would non-equality conditions +explain (costs off) select * from hp where a = 1 +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 1" +== 280 +-- truncate_limit: 100 +explain (costs off) select * from hp where b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE b = 'xxx'" +== 281 +-- truncate_limit: 100 +explain (costs off) select * from hp where a is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a IS NULL" +== 282 +-- truncate_limit: 100 +explain (costs off) select * from hp where b is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE b IS NULL" +== 283 +-- truncate_limit: 100 +explain (costs off) select * from hp where a < 1 and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a < 1 AND b = 'xxx'" +== 284 +-- truncate_limit: 100 +explain (costs off) select * from hp where a <> 1 and b = 'yyy' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a <> 1 AND b = 'yyy'" +== 285 +-- truncate_limit: 100 +explain (costs off) select * from hp where a <> 1 and b <> 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a <> 1 AND b <> 'xxx'" +== 286 +-- truncate_limit: 100 +-- pruning should work if either a value or a IS NULL clause is provided for +-- each of the keys +explain (costs off) select * from hp where a is null and b is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a IS NULL AND b IS NULL" +== 287 +-- truncate_limit: 100 +explain (costs off) select * from hp where a = 1 and b is null +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 1 AND b IS NULL" +== 288 +-- truncate_limit: 100 +explain (costs off) select * from hp where a = 1 and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 1 AND b = 'xxx'" +== 289 +-- truncate_limit: 100 +explain (costs off) select * from hp where a is null and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a IS NULL AND b = 'xxx'" +== 290 +-- truncate_limit: 100 +explain (costs off) select * from hp where a = 2 and b = 'xxx' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 2 AND b = 'xxx'" +== 291 +-- truncate_limit: 100 +explain (costs off) select * from hp where a = 1 and b = 'abcde' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 1 AND b = 'abcde'" +== 292 +-- truncate_limit: 100 +explain (costs off) select * from hp where (a = 1 and b = 'abcde') or (a = 2 and b = 'xxx') or (a is null and b is null) +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE (a = 1 AND b = 'abcde') OR (a = 2 AND b = 'xxx') OR (a..." +== 293 +-- truncate_limit: 100 +-- test pruning when not all the partitions exist +drop table hp1 +-- +TABLE: name="hp1" schema="" table="hp1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hp1" +== 294 +-- truncate_limit: 100 +drop table hp3 +-- +TABLE: name="hp3" schema="" table="hp3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hp3" +== 295 +-- truncate_limit: 100 +explain (costs off) select * from hp where a = 1 and b = 'abcde' +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 1 AND b = 'abcde'" +== 296 +-- truncate_limit: 100 +explain (costs off) select * from hp where a = 1 and b = 'abcde' and + (c = 2 or c = 3) +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 1 AND b = 'abcde' AND (c = 2 OR c = 3)" +== 297 +-- truncate_limit: 100 +drop table hp2 +-- +TABLE: name="hp2" schema="" table="hp2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hp2" +== 298 +-- truncate_limit: 100 +explain (costs off) select * from hp where a = 1 and b = 'abcde' and + (c = 2 or c = 3) +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp WHERE a = 1 AND b = 'abcde' AND (c = 2 OR c = 3)" +== 299 +-- truncate_limit: 100 +|-- +-- Test runtime partition pruning +|-- +create table ab (a int not null, b int not null) partition by list (a) +-- +TABLE: name="ab" schema="" table="ab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab (a int NOT NULL, b int NOT NULL) PARTITION BY LIST (a)" +== 300 +-- truncate_limit: 100 +create table ab_a2 partition of ab for values in(2) partition by list (b) +-- +TABLE: name="ab_a2" schema="" table="ab_a2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a2 PARTITION OF ab FOR VALUES IN (2) PARTITION BY LIST (b)" +== 301 +-- truncate_limit: 100 +create table ab_a2_b1 partition of ab_a2 for values in (1) +-- +TABLE: name="ab_a2_b1" schema="" table="ab_a2_b1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a2_b1 PARTITION OF ab_a2 FOR VALUES IN (1)" +== 302 +-- truncate_limit: 100 +create table ab_a2_b2 partition of ab_a2 for values in (2) +-- +TABLE: name="ab_a2_b2" schema="" table="ab_a2_b2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a2_b2 PARTITION OF ab_a2 FOR VALUES IN (2)" +== 303 +-- truncate_limit: 100 +create table ab_a2_b3 partition of ab_a2 for values in (3) +-- +TABLE: name="ab_a2_b3" schema="" table="ab_a2_b3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a2_b3 PARTITION OF ab_a2 FOR VALUES IN (3)" +== 304 +-- truncate_limit: 100 +create table ab_a1 partition of ab for values in(1) partition by list (b) +-- +TABLE: name="ab_a1" schema="" table="ab_a1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a1 PARTITION OF ab FOR VALUES IN (1) PARTITION BY LIST (b)" +== 305 +-- truncate_limit: 100 +create table ab_a1_b1 partition of ab_a1 for values in (1) +-- +TABLE: name="ab_a1_b1" schema="" table="ab_a1_b1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a1_b1 PARTITION OF ab_a1 FOR VALUES IN (1)" +== 306 +-- truncate_limit: 100 +create table ab_a1_b2 partition of ab_a1 for values in (2) +-- +TABLE: name="ab_a1_b2" schema="" table="ab_a1_b2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a1_b2 PARTITION OF ab_a1 FOR VALUES IN (2)" +== 307 +-- truncate_limit: 100 +create table ab_a1_b3 partition of ab_a1 for values in (3) +-- +TABLE: name="ab_a1_b3" schema="" table="ab_a1_b3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a1_b3 PARTITION OF ab_a1 FOR VALUES IN (3)" +== 308 +-- truncate_limit: 100 +create table ab_a3 partition of ab for values in(3) partition by list (b) +-- +TABLE: name="ab_a3" schema="" table="ab_a3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a3 PARTITION OF ab FOR VALUES IN (3) PARTITION BY LIST (b)" +== 309 +-- truncate_limit: 100 +create table ab_a3_b1 partition of ab_a3 for values in (1) +-- +TABLE: name="ab_a3_b1" schema="" table="ab_a3_b1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a3_b1 PARTITION OF ab_a3 FOR VALUES IN (1)" +== 310 +-- truncate_limit: 100 +create table ab_a3_b2 partition of ab_a3 for values in (2) +-- +TABLE: name="ab_a3_b2" schema="" table="ab_a3_b2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a3_b2 PARTITION OF ab_a3 FOR VALUES IN (2)" +== 311 +-- truncate_limit: 100 +create table ab_a3_b3 partition of ab_a3 for values in (3) +-- +TABLE: name="ab_a3_b3" schema="" table="ab_a3_b3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab_a3_b3 PARTITION OF ab_a3 FOR VALUES IN (3)" +== 312 +-- truncate_limit: 100 +-- Disallow index only scans as concurrent transactions may stop visibility +-- bits being set causing "Heap Fetches" to be unstable in the EXPLAIN ANALYZE +-- output. +set enable_indexonlyscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO OFF" +== 313 +-- truncate_limit: 100 +prepare ab_q1 (int, int, int) as +select * from ab where a between $1 and $2 and b <= $3 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ab_q1(int, int, int) AS SELECT * FROM ab WHERE a BETWEEN $1 AND $2 AND b <= $3" +== 314 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2, 3) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ab_q1(2, 2, 3)" +== 315 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (1, 2, 3) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ab_q1(1, 2, 3)" +== 316 +-- truncate_limit: 100 +deallocate ab_q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ab_q1" +== 317 +-- truncate_limit: 100 +-- Runtime pruning after optimizer pruning +prepare ab_q1 (int, int) as +select a from ab where a between $1 and $2 and b < 3 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ab_q1(int, int) AS SELECT a FROM ab WHERE a BETWEEN $1 AND $2 AND b < 3" +== 318 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ab_q1(2, 2)" +== 319 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 4) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ab_q1(2, 4)" +== 320 +-- truncate_limit: 100 +-- Ensure a mix of PARAM_EXTERN and PARAM_EXEC Params work together at +-- different levels of partitioning. +prepare ab_q2 (int, int) as +select a from ab where a between $1 and $2 and b < (select 3) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ab_q2(int, int) AS SELECT a FROM ab WHERE a BETWEEN $1 AND $2 AND b < (SELECT 3)" +== 321 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ab_q2(2, 2)" +== 322 +-- truncate_limit: 100 +-- As above, but swap the PARAM_EXEC Param to the first partition level +prepare ab_q3 (int, int) as +select a from ab where b between $1 and $2 and a < (select 3) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ab_q3(int, int) AS SELECT a FROM ab WHERE b BETWEEN $1 AND $2 AND a < (SELECT 3)" +== 323 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ab_q3(2, 2)" +== 324 +-- truncate_limit: 100 +|-- +-- Test runtime pruning with hash partitioned tables +|-- + +-- recreate partitions dropped above +create table hp1 partition of hp for values with (modulus 4, remainder 1) +-- +TABLE: name="hp1" schema="" table="hp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp1 PARTITION OF hp FOR VALUES WITH (MODULUS 4, REMAINDER 1)" +== 325 +-- truncate_limit: 100 +create table hp2 partition of hp for values with (modulus 4, remainder 2) +-- +TABLE: name="hp2" schema="" table="hp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp2 PARTITION OF hp FOR VALUES WITH (MODULUS 4, REMAINDER 2)" +== 326 +-- truncate_limit: 100 +create table hp3 partition of hp for values with (modulus 4, remainder 3) +-- +TABLE: name="hp3" schema="" table="hp3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp3 PARTITION OF hp FOR VALUES WITH (MODULUS 4, REMAINDER 3)" +== 327 +-- truncate_limit: 100 +-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual +prepare hp_q1 (text) as +select * from hp where a is null and b = $1 +-- +TABLE: name="hp" schema="" table="hp" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE hp_q1(text) AS SELECT * FROM hp WHERE a IS NULL AND b = $1" +== 328 +-- truncate_limit: 100 +explain (costs off) execute hp_q1('xxx') +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE hp_q1('xxx')" +== 329 +-- truncate_limit: 100 +deallocate hp_q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE hp_q1" +== 330 +-- truncate_limit: 100 +drop table hp +-- +TABLE: name="hp" schema="" table="hp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hp" +== 331 +-- truncate_limit: 100 +-- Test a backwards Append scan +create table list_part (a int) partition by list (a) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_part (a int) PARTITION BY LIST (a)" +== 332 +-- truncate_limit: 100 +create table list_part1 partition of list_part for values in (1) +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_part1 PARTITION OF list_part FOR VALUES IN (1)" +== 333 +-- truncate_limit: 100 +create table list_part2 partition of list_part for values in (2) +-- +TABLE: name="list_part2" schema="" table="list_part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_part2 PARTITION OF list_part FOR VALUES IN (2)" +== 334 +-- truncate_limit: 100 +create table list_part3 partition of list_part for values in (3) +-- +TABLE: name="list_part3" schema="" table="list_part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_part3 PARTITION OF list_part FOR VALUES IN (3)" +== 335 +-- truncate_limit: 100 +create table list_part4 partition of list_part for values in (4) +-- +TABLE: name="list_part4" schema="" table="list_part4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_part4 PARTITION OF list_part FOR VALUES IN (4)" +== 336 +-- truncate_limit: 100 +insert into list_part select generate_series(1,4) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_part SELECT generate_series(1, 4)" +== 337 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 338 +-- truncate_limit: 100 +-- Don't select an actual value out of the table as the order of the Append's +-- subnodes may not be stable. +declare cur SCROLL CURSOR for select 1 from list_part where a > (select 1) and a < (select 4) +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE cur SCROLL CURSOR FOR SELECT 1 FROM list_part WHERE a > (SELECT 1) AND a < (SELECT 4)" +== 339 +-- truncate_limit: 100 +-- move beyond the final row +move 3 from cur +-- +STMT: FetchStmt +TRUNCATED: "MOVE FORWARD 3 cur" +== 340 +-- truncate_limit: 100 +-- Ensure we get two rows. +fetch backward all from cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL cur" +== 341 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 342 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 343 +-- truncate_limit: 100 +-- Test run-time pruning using stable functions +create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable +-- +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION list_part_fn(int) RETURNS int AS $$ begin return $1; end;$$ LANGUAGE plpgsql STABLE" +== 344 +-- truncate_limit: 100 +-- Ensure pruning works using a stable function containing no Vars +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=Select +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM list_part WHERE a = list_part..." +== 345 +-- truncate_limit: 100 +-- Ensure pruning does not take place when the function has a Var parameter +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(a) +-- +TABLE: name="list_part" schema="" table="list_part" ctx=Select +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM list_part WHERE a = list_part..." +== 346 +-- truncate_limit: 100 +-- Ensure pruning does not take place when the expression contains a Var. +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) + a +-- +TABLE: name="list_part" schema="" table="list_part" ctx=Select +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FUNCTION: name="list_part_fn" function="list_part_fn" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM list_part WHERE a = (list_par..." +== 347 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 348 +-- truncate_limit: 100 +drop table list_part +-- +TABLE: name="list_part" schema="" table="list_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE list_part" +== 349 +-- truncate_limit: 100 +-- Parallel append + +-- Parallel queries won't necessarily get as many workers as the planner +-- asked for. This affects not only the "Workers Launched:" field of EXPLAIN +-- results, but also row counts and loop counts for parallel scans, Gathers, +-- and everything in between. This function filters out the values we can't +-- rely on to be stable. +-- This removes enough info that you might wonder why bother with EXPLAIN +-- ANALYZE at all. The answer is that we need to see '(never executed)' +-- notations because that's the only way to verify runtime pruning. +create function explain_parallel_append(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + $1) + loop + ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N'); + ln := regexp_replace(ln, 'actual rows=\d+ loops=\d+', 'actual rows=N loops=N'); + ln := regexp_replace(ln, 'Rows Removed by Filter: \d+', 'Rows Removed by Filter: N'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_parallel_append(text) RETURNS SETOF text LANGUAGE plpgsql AS $$\ndeclare\n ..." +== 350 +-- truncate_limit: 100 +prepare ab_q4 (int, int) as +select avg(a) from ab where a between $1 and $2 and b < 4 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ab_q4(int, int) AS SELECT avg(a) FROM ab WHERE a BETWEEN $1 AND $2 AND b < 4" +== 351 +-- truncate_limit: 100 +-- Encourage use of parallel plans +set parallel_setup_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 352 +-- truncate_limit: 100 +set parallel_tuple_cost = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 353 +-- truncate_limit: 100 +set min_parallel_table_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 354 +-- truncate_limit: 100 +set max_parallel_workers_per_gather = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 355 +-- truncate_limit: 100 +select explain_parallel_append('execute ab_q4 (2, 2)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_parallel_append('execute ab_q4 (2, 2)')" +== 356 +-- truncate_limit: 100 +-- Test run-time pruning with IN lists. +prepare ab_q5 (int, int, int) as +select avg(a) from ab where a in($1,$2,$3) and b < 4 +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ab_q5(int, int, int) AS SELECT avg(a) FROM ab WHERE a IN ($1, $2, $3) AND b < 4" +== 357 +-- truncate_limit: 100 +select explain_parallel_append('execute ab_q5 (1, 1, 1)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_parallel_append('execute ab_q5 (1, 1, 1)')" +== 358 +-- truncate_limit: 100 +select explain_parallel_append('execute ab_q5 (2, 3, 3)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_parallel_append('execute ab_q5 (2, 3, 3)')" +== 359 +-- truncate_limit: 100 +-- Try some params whose values do not belong to any partition. +select explain_parallel_append('execute ab_q5 (33, 44, 55)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_parallel_append('execute ab_q5 (33, 44, 55)')" +== 360 +-- truncate_limit: 100 +-- Test Parallel Append with PARAM_EXEC Params +select explain_parallel_append('select count(*) from ab where (a = (select 1) or a = (select 3)) and b = 2') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 361 +-- truncate_limit: 100 +-- Test pruning during parallel nested loop query +create table lprt_a (a int not null) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE lprt_a (a int NOT NULL)" +== 362 +-- truncate_limit: 100 +-- Insert some values we won't find in ab +insert into lprt_a select 0 from generate_series(1,100) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lprt_a SELECT 0 FROM generate_series(1, 100)" +== 363 +-- truncate_limit: 100 +-- and insert some values that we should find. +insert into lprt_a values(1),(1) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lprt_a VALUES (1), (1)" +== 364 +-- truncate_limit: 100 +analyze lprt_a +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE lprt_a" +== 365 +-- truncate_limit: 100 +create index ab_a2_b1_a_idx on ab_a2_b1 (a) +-- +TABLE: name="ab_a2_b1" schema="" table="ab_a2_b1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a2_b1_a_idx ON ab_a2_b1 USING btree (a)" +== 366 +-- truncate_limit: 100 +create index ab_a2_b2_a_idx on ab_a2_b2 (a) +-- +TABLE: name="ab_a2_b2" schema="" table="ab_a2_b2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a2_b2_a_idx ON ab_a2_b2 USING btree (a)" +== 367 +-- truncate_limit: 100 +create index ab_a2_b3_a_idx on ab_a2_b3 (a) +-- +TABLE: name="ab_a2_b3" schema="" table="ab_a2_b3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a2_b3_a_idx ON ab_a2_b3 USING btree (a)" +== 368 +-- truncate_limit: 100 +create index ab_a1_b1_a_idx on ab_a1_b1 (a) +-- +TABLE: name="ab_a1_b1" schema="" table="ab_a1_b1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a1_b1_a_idx ON ab_a1_b1 USING btree (a)" +== 369 +-- truncate_limit: 100 +create index ab_a1_b2_a_idx on ab_a1_b2 (a) +-- +TABLE: name="ab_a1_b2" schema="" table="ab_a1_b2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a1_b2_a_idx ON ab_a1_b2 USING btree (a)" +== 370 +-- truncate_limit: 100 +create index ab_a1_b3_a_idx on ab_a1_b3 (a) +-- +TABLE: name="ab_a1_b3" schema="" table="ab_a1_b3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a1_b3_a_idx ON ab_a1_b3 USING btree (a)" +== 371 +-- truncate_limit: 100 +create index ab_a3_b1_a_idx on ab_a3_b1 (a) +-- +TABLE: name="ab_a3_b1" schema="" table="ab_a3_b1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a3_b1_a_idx ON ab_a3_b1 USING btree (a)" +== 372 +-- truncate_limit: 100 +create index ab_a3_b2_a_idx on ab_a3_b2 (a) +-- +TABLE: name="ab_a3_b2" schema="" table="ab_a3_b2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a3_b2_a_idx ON ab_a3_b2 USING btree (a)" +== 373 +-- truncate_limit: 100 +create index ab_a3_b3_a_idx on ab_a3_b3 (a) +-- +TABLE: name="ab_a3_b3" schema="" table="ab_a3_b3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ab_a3_b3_a_idx ON ab_a3_b3 USING btree (a)" +== 374 +-- truncate_limit: 100 +set enable_hashjoin = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO 0" +== 375 +-- truncate_limit: 100 +set enable_mergejoin = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO 0" +== 376 +-- truncate_limit: 100 +set enable_memoize = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_memoize TO 0" +== 377 +-- truncate_limit: 100 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(0, 0, 1)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 378 +-- truncate_limit: 100 +-- Ensure the same partitions are pruned when we make the nested loop +-- parameter an Expr rather than a plain Param. +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a + 0 where a.a in(0, 0, 1)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 379 +-- truncate_limit: 100 +insert into lprt_a values(3),(3) +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO lprt_a VALUES (3), (3)" +== 380 +-- truncate_limit: 100 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 3)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 381 +-- truncate_limit: 100 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 382 +-- truncate_limit: 100 +delete from lprt_a where a = 1 +-- +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM lprt_a WHERE a = 1" +== 383 +-- truncate_limit: 100 +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 384 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 385 +-- truncate_limit: 100 +reset enable_mergejoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_mergejoin" +== 386 +-- truncate_limit: 100 +reset enable_memoize +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_memoize" +== 387 +-- truncate_limit: 100 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 388 +-- truncate_limit: 100 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_tuple_cost" +== 389 +-- truncate_limit: 100 +reset min_parallel_table_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_table_scan_size" +== 390 +-- truncate_limit: 100 +reset max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers_per_gather" +== 391 +-- truncate_limit: 100 +-- Test run-time partition pruning with an initplan +explain (analyze, costs off, summary off, timing off) +select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=Select +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM ab WHERE a = (SELECT max(a) F..." +== 392 +-- truncate_limit: 100 +-- Test run-time partition pruning with UNION ALL parents +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM (SELECT * FROM ab WHERE a = 1..." +== 393 +-- truncate_limit: 100 +-- A case containing a UNION ALL with a non-partitioned child. +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM ((SELECT * FROM ab WHERE a = ..." +== 394 +-- truncate_limit: 100 +-- Another UNION ALL test, but containing a mix of exec init and exec run-time pruning. +create table xy_1 (x int, y int) +-- +TABLE: name="xy_1" schema="" table="xy_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE xy_1 (x int, y int)" +== 395 +-- truncate_limit: 100 +insert into xy_1 values(100,-10) +-- +TABLE: name="xy_1" schema="" table="xy_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xy_1 VALUES (100, -10)" +== 396 +-- truncate_limit: 100 +set enable_bitmapscan = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO 0" +== 397 +-- truncate_limit: 100 +set enable_indexscan = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO 0" +== 398 +-- truncate_limit: 100 +prepare ab_q6 as +select * from ( + select tableoid::regclass,a,b from ab +union all + select tableoid::regclass,x,y from xy_1 +union all + select tableoid::regclass,a,b from ab +) ab where a = $1 and b = (select -10) +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +TABLE: name="xy_1" schema="" table="xy_1" ctx=Select +TABLE: name="ab" schema="" table="ab" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ab_q6 AS SELECT * FROM ((SELECT tableoid::regclass, a, b FROM ab UNION ALL SELECT tableoi..." +== 399 +-- truncate_limit: 100 +-- Ensure the xy_1 subplan is not pruned. +explain (analyze, costs off, summary off, timing off) execute ab_q6(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ab_q6(1)" +== 400 +-- truncate_limit: 100 +-- Ensure we see just the xy_1 row. +execute ab_q6(100) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE ab_q6(100)" +== 401 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 402 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 403 +-- truncate_limit: 100 +deallocate ab_q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ab_q1" +== 404 +-- truncate_limit: 100 +deallocate ab_q2 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ab_q2" +== 405 +-- truncate_limit: 100 +deallocate ab_q3 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ab_q3" +== 406 +-- truncate_limit: 100 +deallocate ab_q4 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ab_q4" +== 407 +-- truncate_limit: 100 +deallocate ab_q5 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ab_q5" +== 408 +-- truncate_limit: 100 +deallocate ab_q6 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ab_q6" +== 409 +-- truncate_limit: 100 +-- UPDATE on a partition subtree has been seen to have problems. +insert into ab values (1,2) +-- +TABLE: name="ab" schema="" table="ab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ab VALUES (1, 2)" +== 410 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab where ab.a = 1 and ab.a = ab_a1.a +-- +TABLE: name="ab_a1" schema="" table="ab_a1" ctx=DML +TABLE: name="ab" schema="" table="ab" ctx=Select +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) UPDATE ab_a1 SET b = 3 FROM ab WHERE ab.a =..." +== 411 +-- truncate_limit: 100 +table ab +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ab" +== 412 +-- truncate_limit: 100 +-- Test UPDATE where source relation has run-time pruning enabled +truncate ab +-- +TABLE: name="ab" schema="" table="ab" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ab" +== 413 +-- truncate_limit: 100 +insert into ab values (1, 1), (1, 2), (1, 3), (2, 1) +-- +TABLE: name="ab" schema="" table="ab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ab VALUES (1, 1), (1, 2), (1, 3), (2, 1)" +== 414 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab_a2 where ab_a2.b = (select 1) +-- +TABLE: name="ab_a1" schema="" table="ab_a1" ctx=DML +TABLE: name="ab_a2" schema="" table="ab_a2" ctx=Select +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) UPDATE ab_a1 SET b = 3 FROM ab_a2 WHERE ab_..." +== 415 +-- truncate_limit: 100 +select tableoid::regclass, * from ab +-- +TABLE: name="ab" schema="" table="ab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM ab" +== 416 +-- truncate_limit: 100 +drop table ab, lprt_a +-- +TABLE: name="ab" schema="" table="ab" ctx=DDL +TABLE: name="lprt_a" schema="" table="lprt_a" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ab, lprt_a" +== 417 +-- truncate_limit: 100 +-- Join +create table tbl1(col1 int) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl1 (col1 int)" +== 418 +-- truncate_limit: 100 +insert into tbl1 values (501), (505) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl1 VALUES (501), (505)" +== 419 +-- truncate_limit: 100 +-- Basic table +create table tprt (col1 int) partition by range (col1) +-- +TABLE: name="tprt" schema="" table="tprt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tprt (col1 int) PARTITION BY RANGE (col1)" +== 420 +-- truncate_limit: 100 +create table tprt_1 partition of tprt for values from (1) to (501) +-- +TABLE: name="tprt_1" schema="" table="tprt_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tprt_1 PARTITION OF tprt FOR VALUES FROM (1) TO (501)" +== 421 +-- truncate_limit: 100 +create table tprt_2 partition of tprt for values from (501) to (1001) +-- +TABLE: name="tprt_2" schema="" table="tprt_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tprt_2 PARTITION OF tprt FOR VALUES FROM (501) TO (1001)" +== 422 +-- truncate_limit: 100 +create table tprt_3 partition of tprt for values from (1001) to (2001) +-- +TABLE: name="tprt_3" schema="" table="tprt_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tprt_3 PARTITION OF tprt FOR VALUES FROM (1001) TO (2001)" +== 423 +-- truncate_limit: 100 +create table tprt_4 partition of tprt for values from (2001) to (3001) +-- +TABLE: name="tprt_4" schema="" table="tprt_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tprt_4 PARTITION OF tprt FOR VALUES FROM (2001) TO (3001)" +== 424 +-- truncate_limit: 100 +create table tprt_5 partition of tprt for values from (3001) to (4001) +-- +TABLE: name="tprt_5" schema="" table="tprt_5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tprt_5 PARTITION OF tprt FOR VALUES FROM (3001) TO (4001)" +== 425 +-- truncate_limit: 100 +create table tprt_6 partition of tprt for values from (4001) to (5001) +-- +TABLE: name="tprt_6" schema="" table="tprt_6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tprt_6 PARTITION OF tprt FOR VALUES FROM (4001) TO (5001)" +== 426 +-- truncate_limit: 100 +create index tprt1_idx on tprt_1 (col1) +-- +TABLE: name="tprt_1" schema="" table="tprt_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tprt1_idx ON tprt_1 USING btree (col1)" +== 427 +-- truncate_limit: 100 +create index tprt2_idx on tprt_2 (col1) +-- +TABLE: name="tprt_2" schema="" table="tprt_2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tprt2_idx ON tprt_2 USING btree (col1)" +== 428 +-- truncate_limit: 100 +create index tprt3_idx on tprt_3 (col1) +-- +TABLE: name="tprt_3" schema="" table="tprt_3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tprt3_idx ON tprt_3 USING btree (col1)" +== 429 +-- truncate_limit: 100 +create index tprt4_idx on tprt_4 (col1) +-- +TABLE: name="tprt_4" schema="" table="tprt_4" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tprt4_idx ON tprt_4 USING btree (col1)" +== 430 +-- truncate_limit: 100 +create index tprt5_idx on tprt_5 (col1) +-- +TABLE: name="tprt_5" schema="" table="tprt_5" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tprt5_idx ON tprt_5 USING btree (col1)" +== 431 +-- truncate_limit: 100 +create index tprt6_idx on tprt_6 (col1) +-- +TABLE: name="tprt_6" schema="" table="tprt_6" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tprt6_idx ON tprt_6 USING btree (col1)" +== 432 +-- truncate_limit: 100 +insert into tprt values (10), (20), (501), (502), (505), (1001), (4500) +-- +TABLE: name="tprt" schema="" table="tprt" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tprt VALUES (10), (20), (501), (502), (505), (1001), (4500)" +== 433 +-- truncate_limit: 100 +set enable_hashjoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 434 +-- truncate_limit: 100 +set enable_mergejoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 435 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 > tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM tbl1 JOIN tprt ON tbl1.col1 >..." +== 436 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 = tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM tbl1 JOIN tprt ON tbl1.col1 =..." +== 437 +-- truncate_limit: 100 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 > tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tbl1 JOIN tprt ON tbl1.col1 > tprt.col1 ORDER BY tbl1.col1, tprt.col1" +== 438 +-- truncate_limit: 100 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tbl1 JOIN tprt ON tbl1.col1 = tprt.col1 ORDER BY tbl1.col1, tprt.col1" +== 439 +-- truncate_limit: 100 +-- Multiple partitions +insert into tbl1 values (1001), (1010), (1011) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl1 VALUES (1001), (1010), (1011)" +== 440 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM tbl1 JOIN tprt ON tbl1.col1 >..." +== 441 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM tbl1 JOIN tprt ON tbl1.col1 =..." +== 442 +-- truncate_limit: 100 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 > tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tbl1 JOIN tprt ON tbl1.col1 > tprt.col1 ORDER BY tbl1.col1, tprt.col1" +== 443 +-- truncate_limit: 100 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tbl1 JOIN tprt ON tbl1.col1 = tprt.col1 ORDER BY tbl1.col1, tprt.col1" +== 444 +-- truncate_limit: 100 +-- Last partition +delete from tbl1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tbl1" +== 445 +-- truncate_limit: 100 +insert into tbl1 values (4400) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl1 VALUES (4400)" +== 446 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 < tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM tbl1 JOIN tprt ON tbl1.col1 <..." +== 447 +-- truncate_limit: 100 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 < tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tbl1 JOIN tprt ON tbl1.col1 < tprt.col1 ORDER BY tbl1.col1, tprt.col1" +== 448 +-- truncate_limit: 100 +-- No matching partition +delete from tbl1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tbl1" +== 449 +-- truncate_limit: 100 +insert into tbl1 values (10000) +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tbl1 VALUES (10000)" +== 450 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from tbl1 join tprt on tbl1.col1 = tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM tbl1 JOIN tprt ON tbl1.col1 =..." +== 451 +-- truncate_limit: 100 +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1 +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=Select +TABLE: name="tprt" schema="" table="tprt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tbl1 JOIN tprt ON tbl1.col1 = tprt.col1 ORDER BY tbl1.col1, tprt.col1" +== 452 +-- truncate_limit: 100 +drop table tbl1, tprt +-- +TABLE: name="tbl1" schema="" table="tbl1" ctx=DDL +TABLE: name="tprt" schema="" table="tprt" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbl1, tprt" +== 453 +-- truncate_limit: 100 +-- Test with columns defined in varying orders between each level +create table part_abc (a int not null, b int not null, c int not null) partition by list (a) +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_abc (a int NOT NULL, b int NOT NULL, c int NOT NULL) PARTITION BY LIST (a)" +== 454 +-- truncate_limit: 100 +create table part_bac (b int not null, a int not null, c int not null) partition by list (b) +-- +TABLE: name="part_bac" schema="" table="part_bac" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_bac (b int NOT NULL, a int NOT NULL, c int NOT NULL) PARTITION BY LIST (b)" +== 455 +-- truncate_limit: 100 +create table part_cab (c int not null, a int not null, b int not null) partition by list (c) +-- +TABLE: name="part_cab" schema="" table="part_cab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_cab (c int NOT NULL, a int NOT NULL, b int NOT NULL) PARTITION BY LIST (c)" +== 456 +-- truncate_limit: 100 +create table part_abc_p1 (a int not null, b int not null, c int not null) +-- +TABLE: name="part_abc_p1" schema="" table="part_abc_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_abc_p1 (a int NOT NULL, b int NOT NULL, c int NOT NULL)" +== 457 +-- truncate_limit: 100 +alter table part_abc attach partition part_bac for values in(1) +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_abc ATTACH PARTITION part_bac FOR VALUES IN (1)" +== 458 +-- truncate_limit: 100 +alter table part_bac attach partition part_cab for values in(2) +-- +TABLE: name="part_bac" schema="" table="part_bac" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_bac ATTACH PARTITION part_cab FOR VALUES IN (2)" +== 459 +-- truncate_limit: 100 +alter table part_cab attach partition part_abc_p1 for values in(3) +-- +TABLE: name="part_cab" schema="" table="part_cab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_cab ATTACH PARTITION part_abc_p1 FOR VALUES IN (3)" +== 460 +-- truncate_limit: 100 +prepare part_abc_q1 (int, int, int) as +select * from part_abc where a = $1 and b = $2 and c = $3 +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE part_abc_q1(int, int, int) AS SELECT * FROM part_abc WHERE a = $1 AND b = $2 AND c = $3" +== 461 +-- truncate_limit: 100 +-- Single partition should be scanned. +explain (analyze, costs off, summary off, timing off) execute part_abc_q1 (1, 2, 3) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE part_abc_q1(1, 2, 3)" +== 462 +-- truncate_limit: 100 +deallocate part_abc_q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE part_abc_q1" +== 463 +-- truncate_limit: 100 +drop table part_abc +-- +TABLE: name="part_abc" schema="" table="part_abc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_abc" +== 464 +-- truncate_limit: 100 +-- Ensure that an Append node properly handles a sub-partitioned table +-- matching without any of its leaf partitions matching the clause. +create table listp (a int, b int) partition by list (a) +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp (a int, b int) PARTITION BY LIST (a)" +== 465 +-- truncate_limit: 100 +create table listp_1 partition of listp for values in(1) partition by list (b) +-- +TABLE: name="listp_1" schema="" table="listp_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp_1 PARTITION OF listp FOR VALUES IN (1) PARTITION BY LIST (b)" +== 466 +-- truncate_limit: 100 +create table listp_1_1 partition of listp_1 for values in(1) +-- +TABLE: name="listp_1_1" schema="" table="listp_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp_1_1 PARTITION OF listp_1 FOR VALUES IN (1)" +== 467 +-- truncate_limit: 100 +create table listp_2 partition of listp for values in(2) partition by list (b) +-- +TABLE: name="listp_2" schema="" table="listp_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp_2 PARTITION OF listp FOR VALUES IN (2) PARTITION BY LIST (b)" +== 468 +-- truncate_limit: 100 +create table listp_2_1 partition of listp_2 for values in(2) +-- +TABLE: name="listp_2_1" schema="" table="listp_2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp_2_1 PARTITION OF listp_2 FOR VALUES IN (2)" +== 469 +-- truncate_limit: 100 +select * from listp where b = 1 +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM listp WHERE b = 1" +== 470 +-- truncate_limit: 100 +-- Ensure that an Append node properly can handle selection of all first level +-- partitions before finally detecting the correct set of 2nd level partitions +-- which match the given parameter. +prepare q1 (int,int) as select * from listp where b in ($1,$2) +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q1(int, int) AS SELECT * FROM listp WHERE b IN ($1, $2)" +== 471 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute q1 (1,1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE q1(1, 1)" +== 472 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute q1 (2,2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE q1(2, 2)" +== 473 +-- truncate_limit: 100 +-- Try with no matching partitions. +explain (analyze, costs off, summary off, timing off) execute q1 (0,0) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE q1(0, 0)" +== 474 +-- truncate_limit: 100 +deallocate q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q1" +== 475 +-- truncate_limit: 100 +-- Test more complex cases where a not-equal condition further eliminates partitions. +prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q1(int, int, int, int) AS SELECT * FROM listp WHERE b IN ($1, $2) AND $3 <> b AND $4 <> b" +== 476 +-- truncate_limit: 100 +-- Both partitions allowed by IN clause, but one disallowed by <> clause +explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE q1(1, 2, 2, 0)" +== 477 +-- truncate_limit: 100 +-- Both partitions allowed by IN clause, then both excluded again by <> clauses. +explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE q1(1, 2, 2, 1)" +== 478 +-- truncate_limit: 100 +-- Ensure Params that evaluate to NULL properly prune away all partitions +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select null::int) +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM listp WHERE a = (SELECT NULL:..." +== 479 +-- truncate_limit: 100 +drop table listp +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE listp" +== 480 +-- truncate_limit: 100 +|-- +-- check that stable query clauses are only used in run-time pruning +|-- +create table stable_qual_pruning (a timestamp) partition by range (a) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stable_qual_pruning (a timestamp) PARTITION BY RANGE (a)" +== 481 +-- truncate_limit: 100 +create table stable_qual_pruning1 partition of stable_qual_pruning + for values from ('2000-01-01') to ('2000-02-01') +-- +TABLE: name="stable_qual_pruning1" schema="" table="stable_qual_pruning1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stable_qual_pruning1 PARTITION OF stable_qual_pruning FOR VALUES FROM ('2000-01-01')..." +== 482 +-- truncate_limit: 100 +create table stable_qual_pruning2 partition of stable_qual_pruning + for values from ('2000-02-01') to ('2000-03-01') +-- +TABLE: name="stable_qual_pruning2" schema="" table="stable_qual_pruning2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stable_qual_pruning2 PARTITION OF stable_qual_pruning FOR VALUES FROM ('2000-02-01')..." +== 483 +-- truncate_limit: 100 +create table stable_qual_pruning3 partition of stable_qual_pruning + for values from ('3000-02-01') to ('3000-03-01') +-- +TABLE: name="stable_qual_pruning3" schema="" table="stable_qual_pruning3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stable_qual_pruning3 PARTITION OF stable_qual_pruning FOR VALUES FROM ('3000-02-01')..." +== 484 +-- truncate_limit: 100 +-- comparison against a stable value requires run-time pruning +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < localtimestamp +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a <..." +== 485 +-- truncate_limit: 100 +-- timestamp < timestamptz comparison is only stable, not immutable +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < '2000-02-01'::timestamptz +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a <..." +== 486 +-- truncate_limit: 100 +-- check ScalarArrayOp cases +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamp[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a =..." +== 487 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamp[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a =..." +== 488 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', localtimestamp]::timestamp[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a =..." +== 489 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a =..." +== 490 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a =..." +== 491 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(null::timestamptz[]) +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM stable_qual_pruning WHERE a =..." +== 492 +-- truncate_limit: 100 +drop table stable_qual_pruning +-- +TABLE: name="stable_qual_pruning" schema="" table="stable_qual_pruning" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE stable_qual_pruning" +== 493 +-- truncate_limit: 100 +|-- +-- Check that pruning with composite range partitioning works correctly when +-- it must ignore clauses for trailing keys once it has seen a clause with +-- non-inclusive operator for an earlier key +|-- +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p (a int, b int, c int) PARTITION BY RANGE (a, (abs(b)), c)" +== 494 +-- truncate_limit: 100 +create table mc3p0 partition of mc3p + for values from (0, 0, 0) to (0, maxvalue, maxvalue) +-- +TABLE: name="mc3p0" schema="" table="mc3p0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p0 PARTITION OF mc3p FOR VALUES FROM (0, 0, 0) TO (0, maxvalue, maxvalue)" +== 495 +-- truncate_limit: 100 +create table mc3p1 partition of mc3p + for values from (1, 1, 1) to (2, minvalue, minvalue) +-- +TABLE: name="mc3p1" schema="" table="mc3p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p1 PARTITION OF mc3p FOR VALUES FROM (1, 1, 1) TO (2, minvalue, minvalue)" +== 496 +-- truncate_limit: 100 +create table mc3p2 partition of mc3p + for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue) +-- +TABLE: name="mc3p2" schema="" table="mc3p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mc3p2 PARTITION OF mc3p FOR VALUES FROM (2, minvalue, minvalue) TO (3, maxvalue, max..." +== 497 +-- truncate_limit: 100 +insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mc3p VALUES (0, 1, 1), (1, 1, 1), (2, 1, 1)" +== 498 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from mc3p where a < 3 and abs(b) = 1 +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM mc3p WHERE a < 3 AND abs(b) = 1" +== 499 +-- truncate_limit: 100 +|-- +-- Check that pruning with composite range partitioning works correctly when +-- a combination of runtime parameters is specified, not all of whose values +-- are available at the same time +|-- +prepare ps1 as + select * from mc3p where a = $1 and abs(b) < (select 3) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ps1 AS SELECT * FROM mc3p WHERE a = $1 AND abs(b) < (SELECT 3)" +== 500 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +execute ps1(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ps1(1)" +== 501 +-- truncate_limit: 100 +deallocate ps1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ps1" +== 502 +-- truncate_limit: 100 +prepare ps2 as + select * from mc3p where a <= $1 and abs(b) < (select 3) +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ps2 AS SELECT * FROM mc3p WHERE a <= $1 AND abs(b) < (SELECT 3)" +== 503 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +execute ps2(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE ps2(1)" +== 504 +-- truncate_limit: 100 +deallocate ps2 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ps2" +== 505 +-- truncate_limit: 100 +drop table mc3p +-- +TABLE: name="mc3p" schema="" table="mc3p" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mc3p" +== 506 +-- truncate_limit: 100 +-- Ensure runtime pruning works with initplans params with boolean types +create table boolvalues (value bool not null) +-- +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolvalues (value bool NOT NULL)" +== 507 +-- truncate_limit: 100 +insert into boolvalues values('t'),('f') +-- +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO boolvalues VALUES ('t'), ('f')" +== 508 +-- truncate_limit: 100 +create table boolp (a bool) partition by list (a) +-- +TABLE: name="boolp" schema="" table="boolp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolp (a bool) PARTITION BY LIST (a)" +== 509 +-- truncate_limit: 100 +create table boolp_t partition of boolp for values in('t') +-- +TABLE: name="boolp_t" schema="" table="boolp_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolp_t PARTITION OF boolp FOR VALUES IN ('t')" +== 510 +-- truncate_limit: 100 +create table boolp_f partition of boolp for values in('f') +-- +TABLE: name="boolp_f" schema="" table="boolp_f" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE boolp_f PARTITION OF boolp FOR VALUES IN ('f')" +== 511 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from boolp where a = (select value from boolvalues where value) +-- +TABLE: name="boolp" schema="" table="boolp" ctx=Select +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="value" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM boolp WHERE a = (SELECT value..." +== 512 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from boolp where a = (select value from boolvalues where not value) +-- +TABLE: name="boolp" schema="" table="boolp" ctx=Select +TABLE: name="boolvalues" schema="" table="boolvalues" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="value" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM boolp WHERE a = (SELECT value..." +== 513 +-- truncate_limit: 100 +drop table boolp +-- +TABLE: name="boolp" schema="" table="boolp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE boolp" +== 514 +-- truncate_limit: 100 +|-- +-- Test run-time pruning of MergeAppend subnodes +|-- +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 515 +-- truncate_limit: 100 +set enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 516 +-- truncate_limit: 100 +create table ma_test (a int, b int) partition by range (a) +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ma_test (a int, b int) PARTITION BY RANGE (a)" +== 517 +-- truncate_limit: 100 +create table ma_test_p1 partition of ma_test for values from (0) to (10) +-- +TABLE: name="ma_test_p1" schema="" table="ma_test_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ma_test_p1 PARTITION OF ma_test FOR VALUES FROM (0) TO (10)" +== 518 +-- truncate_limit: 100 +create table ma_test_p2 partition of ma_test for values from (10) to (20) +-- +TABLE: name="ma_test_p2" schema="" table="ma_test_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ma_test_p2 PARTITION OF ma_test FOR VALUES FROM (10) TO (20)" +== 519 +-- truncate_limit: 100 +create table ma_test_p3 partition of ma_test for values from (20) to (30) +-- +TABLE: name="ma_test_p3" schema="" table="ma_test_p3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ma_test_p3 PARTITION OF ma_test FOR VALUES FROM (20) TO (30)" +== 520 +-- truncate_limit: 100 +insert into ma_test select x,x from generate_series(0,29) t(x) +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ma_test SELECT x, x FROM generate_series(0, 29) t(x)" +== 521 +-- truncate_limit: 100 +create index on ma_test (b) +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON ma_test USING btree (b)" +== 522 +-- truncate_limit: 100 +analyze ma_test +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ma_test" +== 523 +-- truncate_limit: 100 +prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE mt_q1(int) AS SELECT a FROM ma_test WHERE a >= $1 AND (a % 10) = 5 ORDER BY b" +== 524 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute mt_q1(15) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE mt_q1(15)" +== 525 +-- truncate_limit: 100 +execute mt_q1(15) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE mt_q1(15)" +== 526 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) execute mt_q1(25) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE mt_q1(25)" +== 527 +-- truncate_limit: 100 +execute mt_q1(25) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE mt_q1(25)" +== 528 +-- truncate_limit: 100 +-- Ensure MergeAppend behaves correctly when no subplans match +explain (analyze, costs off, summary off, timing off) execute mt_q1(35) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE mt_q1(35)" +== 529 +-- truncate_limit: 100 +execute mt_q1(35) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE mt_q1(35)" +== 530 +-- truncate_limit: 100 +deallocate mt_q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE mt_q1" +== 531 +-- truncate_limit: 100 +prepare mt_q2 (int) as select * from ma_test where a >= $1 order by b limit 1 +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=Select +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE mt_q2(int) AS SELECT * FROM ma_test WHERE a >= $1 ORDER BY b LIMIT 1" +== 532 +-- truncate_limit: 100 +-- Ensure output list looks sane when the MergeAppend has no subplans. +explain (analyze, verbose, costs off, summary off, timing off) execute mt_q2 (35) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, VERBOSE, COSTS OFF, SUMMARY OFF, TIMING OFF) EXECUTE mt_q2(35)" +== 533 +-- truncate_limit: 100 +deallocate mt_q2 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE mt_q2" +== 534 +-- truncate_limit: 100 +-- ensure initplan params properly prune partitions +explain (analyze, costs off, summary off, timing off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=Select +TABLE: name="ma_test_p2" schema="" table="ma_test_p2" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM ma_test WHERE a >= (SELECT mi..." +== 535 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 536 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 537 +-- truncate_limit: 100 +drop table ma_test +-- +TABLE: name="ma_test" schema="" table="ma_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ma_test" +== 538 +-- truncate_limit: 100 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexonlyscan" +== 539 +-- truncate_limit: 100 +|-- +-- check that pruning works properly when the partition key is of a +-- pseudotype +|-- + +-- array type list partition key +create table pp_arrpart (a int[]) partition by list (a) +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_arrpart (a int[]) PARTITION BY LIST (a)" +== 540 +-- truncate_limit: 100 +create table pp_arrpart1 partition of pp_arrpart for values in ('{1}') +-- +TABLE: name="pp_arrpart1" schema="" table="pp_arrpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_arrpart1 PARTITION OF pp_arrpart FOR VALUES IN ('{1}')" +== 541 +-- truncate_limit: 100 +create table pp_arrpart2 partition of pp_arrpart for values in ('{2, 3}', '{4, 5}') +-- +TABLE: name="pp_arrpart2" schema="" table="pp_arrpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_arrpart2 PARTITION OF pp_arrpart FOR VALUES IN ('{2, 3}', '{4, 5}')" +== 542 +-- truncate_limit: 100 +explain (costs off) select * from pp_arrpart where a = '{1}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_arrpart WHERE a = '{1}'" +== 543 +-- truncate_limit: 100 +explain (costs off) select * from pp_arrpart where a = '{1, 2}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_arrpart WHERE a = '{1, 2}'" +== 544 +-- truncate_limit: 100 +explain (costs off) select * from pp_arrpart where a in ('{4, 5}', '{1}') +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_arrpart WHERE a IN ('{4, 5}', '{1}')" +== 545 +-- truncate_limit: 100 +explain (costs off) update pp_arrpart set a = a where a = '{1}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE pp_arrpart SET a = a WHERE a = '{1}'" +== 546 +-- truncate_limit: 100 +explain (costs off) delete from pp_arrpart where a = '{1}' +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM pp_arrpart WHERE a = '{1}'" +== 547 +-- truncate_limit: 100 +drop table pp_arrpart +-- +TABLE: name="pp_arrpart" schema="" table="pp_arrpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp_arrpart" +== 548 +-- truncate_limit: 100 +-- array type hash partition key +create table pph_arrpart (a int[]) partition by hash (a) +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pph_arrpart (a int[]) PARTITION BY HASH (a)" +== 549 +-- truncate_limit: 100 +create table pph_arrpart1 partition of pph_arrpart for values with (modulus 2, remainder 0) +-- +TABLE: name="pph_arrpart1" schema="" table="pph_arrpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pph_arrpart1 PARTITION OF pph_arrpart FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 550 +-- truncate_limit: 100 +create table pph_arrpart2 partition of pph_arrpart for values with (modulus 2, remainder 1) +-- +TABLE: name="pph_arrpart2" schema="" table="pph_arrpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pph_arrpart2 PARTITION OF pph_arrpart FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 551 +-- truncate_limit: 100 +insert into pph_arrpart values ('{1}'), ('{1, 2}'), ('{4, 5}') +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pph_arrpart VALUES ('{1}'), ('{1, 2}'), ('{4, 5}')" +== 552 +-- truncate_limit: 100 +select tableoid::regclass, * from pph_arrpart order by 1 +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM pph_arrpart ORDER BY 1" +== 553 +-- truncate_limit: 100 +explain (costs off) select * from pph_arrpart where a = '{1}' +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pph_arrpart WHERE a = '{1}'" +== 554 +-- truncate_limit: 100 +explain (costs off) select * from pph_arrpart where a = '{1, 2}' +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pph_arrpart WHERE a = '{1, 2}'" +== 555 +-- truncate_limit: 100 +explain (costs off) select * from pph_arrpart where a in ('{4, 5}', '{1}') +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pph_arrpart WHERE a IN ('{4, 5}', '{1}')" +== 556 +-- truncate_limit: 100 +drop table pph_arrpart +-- +TABLE: name="pph_arrpart" schema="" table="pph_arrpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pph_arrpart" +== 557 +-- truncate_limit: 100 +-- enum type list partition key +create type pp_colors as enum ('green', 'blue', 'black') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE pp_colors AS ENUM ('green', 'blue', 'black')" +== 558 +-- truncate_limit: 100 +create table pp_enumpart (a pp_colors) partition by list (a) +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_enumpart (a pp_colors) PARTITION BY LIST (a)" +== 559 +-- truncate_limit: 100 +create table pp_enumpart_green partition of pp_enumpart for values in ('green') +-- +TABLE: name="pp_enumpart_green" schema="" table="pp_enumpart_green" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_enumpart_green PARTITION OF pp_enumpart FOR VALUES IN ('green')" +== 560 +-- truncate_limit: 100 +create table pp_enumpart_blue partition of pp_enumpart for values in ('blue') +-- +TABLE: name="pp_enumpart_blue" schema="" table="pp_enumpart_blue" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_enumpart_blue PARTITION OF pp_enumpart FOR VALUES IN ('blue')" +== 561 +-- truncate_limit: 100 +explain (costs off) select * from pp_enumpart where a = 'blue' +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_enumpart WHERE a = 'blue'" +== 562 +-- truncate_limit: 100 +explain (costs off) select * from pp_enumpart where a = 'black' +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_enumpart WHERE a = 'black'" +== 563 +-- truncate_limit: 100 +drop table pp_enumpart +-- +TABLE: name="pp_enumpart" schema="" table="pp_enumpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp_enumpart" +== 564 +-- truncate_limit: 100 +drop type pp_colors +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE pp_colors" +== 565 +-- truncate_limit: 100 +-- record type as partition key +create type pp_rectype as (a int, b int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE pp_rectype AS (a int, b int)" +== 566 +-- truncate_limit: 100 +create table pp_recpart (a pp_rectype) partition by list (a) +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_recpart (a pp_rectype) PARTITION BY LIST (a)" +== 567 +-- truncate_limit: 100 +create table pp_recpart_11 partition of pp_recpart for values in ('(1,1)') +-- +TABLE: name="pp_recpart_11" schema="" table="pp_recpart_11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_recpart_11 PARTITION OF pp_recpart FOR VALUES IN ('(1,1)')" +== 568 +-- truncate_limit: 100 +create table pp_recpart_23 partition of pp_recpart for values in ('(2,3)') +-- +TABLE: name="pp_recpart_23" schema="" table="pp_recpart_23" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_recpart_23 PARTITION OF pp_recpart FOR VALUES IN ('(2,3)')" +== 569 +-- truncate_limit: 100 +explain (costs off) select * from pp_recpart where a = '(1,1)'::pp_rectype +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_recpart WHERE a = '(1,1)'::pp_rectype" +== 570 +-- truncate_limit: 100 +explain (costs off) select * from pp_recpart where a = '(1,2)'::pp_rectype +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_recpart WHERE a = '(1,2)'::pp_rectype" +== 571 +-- truncate_limit: 100 +drop table pp_recpart +-- +TABLE: name="pp_recpart" schema="" table="pp_recpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp_recpart" +== 572 +-- truncate_limit: 100 +drop type pp_rectype +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE pp_rectype" +== 573 +-- truncate_limit: 100 +-- range type partition key +create table pp_intrangepart (a int4range) partition by list (a) +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_intrangepart (a int4range) PARTITION BY LIST (a)" +== 574 +-- truncate_limit: 100 +create table pp_intrangepart12 partition of pp_intrangepart for values in ('[1,2]') +-- +TABLE: name="pp_intrangepart12" schema="" table="pp_intrangepart12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_intrangepart12 PARTITION OF pp_intrangepart FOR VALUES IN ('[1,2]')" +== 575 +-- truncate_limit: 100 +create table pp_intrangepart2inf partition of pp_intrangepart for values in ('[2,)') +-- +TABLE: name="pp_intrangepart2inf" schema="" table="pp_intrangepart2inf" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_intrangepart2inf PARTITION OF pp_intrangepart FOR VALUES IN ('[2,)')" +== 576 +-- truncate_limit: 100 +explain (costs off) select * from pp_intrangepart where a = '[1,2]'::int4range +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_intrangepart WHERE a = '[1,2]'::int4range" +== 577 +-- truncate_limit: 100 +explain (costs off) select * from pp_intrangepart where a = '(1,2)'::int4range +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_intrangepart WHERE a = '(1,2)'::int4range" +== 578 +-- truncate_limit: 100 +drop table pp_intrangepart +-- +TABLE: name="pp_intrangepart" schema="" table="pp_intrangepart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp_intrangepart" +== 579 +-- truncate_limit: 100 +|-- +-- Ensure the enable_partition_prune GUC properly disables partition pruning. +|-- + +create table pp_lp (a int, value int) partition by list (a) +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_lp (a int, value int) PARTITION BY LIST (a)" +== 580 +-- truncate_limit: 100 +create table pp_lp1 partition of pp_lp for values in(1) +-- +TABLE: name="pp_lp1" schema="" table="pp_lp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_lp1 PARTITION OF pp_lp FOR VALUES IN (1)" +== 581 +-- truncate_limit: 100 +create table pp_lp2 partition of pp_lp for values in(2) +-- +TABLE: name="pp_lp2" schema="" table="pp_lp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pp_lp2 PARTITION OF pp_lp FOR VALUES IN (2)" +== 582 +-- truncate_limit: 100 +explain (costs off) select * from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_lp WHERE a = 1" +== 583 +-- truncate_limit: 100 +explain (costs off) update pp_lp set value = 10 where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE pp_lp SET value = 10 WHERE a = 1" +== 584 +-- truncate_limit: 100 +explain (costs off) delete from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM pp_lp WHERE a = 1" +== 585 +-- truncate_limit: 100 +set enable_partition_pruning = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partition_pruning TO OFF" +== 586 +-- truncate_limit: 100 +set constraint_exclusion = 'partition' +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO partition" +== 587 +-- truncate_limit: 100 +-- this should not affect the result. + +explain (costs off) select * from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_lp WHERE a = 1" +== 588 +-- truncate_limit: 100 +explain (costs off) update pp_lp set value = 10 where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE pp_lp SET value = 10 WHERE a = 1" +== 589 +-- truncate_limit: 100 +explain (costs off) delete from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM pp_lp WHERE a = 1" +== 590 +-- truncate_limit: 100 +set constraint_exclusion = 'off' +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO OFF" +== 591 +-- truncate_limit: 100 +-- this should not affect the result. + +explain (costs off) select * from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_lp WHERE a = 1" +== 592 +-- truncate_limit: 100 +explain (costs off) update pp_lp set value = 10 where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE pp_lp SET value = 10 WHERE a = 1" +== 593 +-- truncate_limit: 100 +explain (costs off) delete from pp_lp where a = 1 +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM pp_lp WHERE a = 1" +== 594 +-- truncate_limit: 100 +drop table pp_lp +-- +TABLE: name="pp_lp" schema="" table="pp_lp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp_lp" +== 595 +-- truncate_limit: 100 +-- Ensure enable_partition_prune does not affect non-partitioned tables. + +create table inh_lp (a int, value int) +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_lp (a int, value int)" +== 596 +-- truncate_limit: 100 +create table inh_lp1 (a int, value int, check(a = 1)) inherits (inh_lp) +-- +TABLE: name="inh_lp1" schema="" table="inh_lp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_lp1 (a int, value int, CHECK (a = 1)) INHERITS (inh_lp)" +== 597 +-- truncate_limit: 100 +create table inh_lp2 (a int, value int, check(a = 2)) inherits (inh_lp) +-- +TABLE: name="inh_lp2" schema="" table="inh_lp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE inh_lp2 (a int, value int, CHECK (a = 2)) INHERITS (inh_lp)" +== 598 +-- truncate_limit: 100 +set constraint_exclusion = 'partition' +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO partition" +== 599 +-- truncate_limit: 100 +-- inh_lp2 should be removed in the following 3 cases. +explain (costs off) select * from inh_lp where a = 1 +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM inh_lp WHERE a = 1" +== 600 +-- truncate_limit: 100 +explain (costs off) update inh_lp set value = 10 where a = 1 +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE inh_lp SET value = 10 WHERE a = 1" +== 601 +-- truncate_limit: 100 +explain (costs off) delete from inh_lp where a = 1 +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM inh_lp WHERE a = 1" +== 602 +-- truncate_limit: 100 +-- Ensure we don't exclude normal relations when we only expect to exclude +-- inheritance children +explain (costs off) update inh_lp1 set value = 10 where a = 2 +-- +TABLE: name="inh_lp1" schema="" table="inh_lp1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE inh_lp1 SET value = 10 WHERE a = 2" +== 603 +-- truncate_limit: 100 +drop table inh_lp cascade +-- +TABLE: name="inh_lp" schema="" table="inh_lp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE inh_lp CASCADE" +== 604 +-- truncate_limit: 100 +reset enable_partition_pruning +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_partition_pruning" +== 605 +-- truncate_limit: 100 +reset constraint_exclusion +-- +STMT: VariableSetStmt +TRUNCATED: "RESET constraint_exclusion" +== 606 +-- truncate_limit: 100 +-- Check pruning for a partition tree containing only temporary relations +create temp table pp_temp_parent (a int) partition by list (a) +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pp_temp_parent (a int) PARTITION BY LIST (a)" +== 607 +-- truncate_limit: 100 +create temp table pp_temp_part_1 partition of pp_temp_parent for values in (1) +-- +TABLE: name="pp_temp_part_1" schema="" table="pp_temp_part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pp_temp_part_1 PARTITION OF pp_temp_parent FOR VALUES IN (1)" +== 608 +-- truncate_limit: 100 +create temp table pp_temp_part_def partition of pp_temp_parent default +-- +TABLE: name="pp_temp_part_def" schema="" table="pp_temp_part_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pp_temp_part_def PARTITION OF pp_temp_parent DEFAULT" +== 609 +-- truncate_limit: 100 +explain (costs off) select * from pp_temp_parent where true +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_temp_parent WHERE true" +== 610 +-- truncate_limit: 100 +explain (costs off) select * from pp_temp_parent where a = 2 +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pp_temp_parent WHERE a = 2" +== 611 +-- truncate_limit: 100 +drop table pp_temp_parent +-- +TABLE: name="pp_temp_parent" schema="" table="pp_temp_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pp_temp_parent" +== 612 +-- truncate_limit: 100 +-- Stress run-time partition pruning a bit more, per bug reports +create temp table p (a int, b int, c int) partition by list (a) +-- +TABLE: name="p" schema="" table="p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE p (a int, b int, c int) PARTITION BY LIST (a)" +== 613 +-- truncate_limit: 100 +create temp table p1 partition of p for values in (1) +-- +TABLE: name="p1" schema="" table="p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE p1 PARTITION OF p FOR VALUES IN (1)" +== 614 +-- truncate_limit: 100 +create temp table p2 partition of p for values in (2) +-- +TABLE: name="p2" schema="" table="p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE p2 PARTITION OF p FOR VALUES IN (2)" +== 615 +-- truncate_limit: 100 +create temp table q (a int, b int, c int) partition by list (a) +-- +TABLE: name="q" schema="" table="q" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE q (a int, b int, c int) PARTITION BY LIST (a)" +== 616 +-- truncate_limit: 100 +create temp table q1 partition of q for values in (1) partition by list (b) +-- +TABLE: name="q1" schema="" table="q1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE q1 PARTITION OF q FOR VALUES IN (1) PARTITION BY LIST (b)" +== 617 +-- truncate_limit: 100 +create temp table q11 partition of q1 for values in (1) partition by list (c) +-- +TABLE: name="q11" schema="" table="q11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE q11 PARTITION OF q1 FOR VALUES IN (1) PARTITION BY LIST (c)" +== 618 +-- truncate_limit: 100 +create temp table q111 partition of q11 for values in (1) +-- +TABLE: name="q111" schema="" table="q111" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE q111 PARTITION OF q11 FOR VALUES IN (1)" +== 619 +-- truncate_limit: 100 +create temp table q2 partition of q for values in (2) partition by list (b) +-- +TABLE: name="q2" schema="" table="q2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE q2 PARTITION OF q FOR VALUES IN (2) PARTITION BY LIST (b)" +== 620 +-- truncate_limit: 100 +create temp table q21 partition of q2 for values in (1) +-- +TABLE: name="q21" schema="" table="q21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE q21 PARTITION OF q2 FOR VALUES IN (1)" +== 621 +-- truncate_limit: 100 +create temp table q22 partition of q2 for values in (2) +-- +TABLE: name="q22" schema="" table="q22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE q22 PARTITION OF q2 FOR VALUES IN (2)" +== 622 +-- truncate_limit: 100 +insert into q22 values (2, 2, 3) +-- +TABLE: name="q22" schema="" table="q22" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO q22 VALUES (2, 2, 3)" +== 623 +-- truncate_limit: 100 +explain (costs off) +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1) +-- +TABLE: name="p" schema="" table="p" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ((SELECT * FROM p UNION ALL SELECT * FROM q1) UNION ALL SELECT ..." +== 624 +-- truncate_limit: 100 +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1) +-- +TABLE: name="p" schema="" table="p" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="s" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ((SELECT * FROM p UNION ALL SELECT * FROM q1) UNION ALL SELECT ...) s(a, b, c) WHER..." +== 625 +-- truncate_limit: 100 +prepare q (int, int) as +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = $1 and s.b = $2 and s.c = (select 1) +-- +TABLE: name="p" schema="" table="p" ctx=Select +TABLE: name="q1" schema="" table="q1" ctx=Select +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="s" column="b" +FILTER: schema="" table="s" column="c" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q(int, int) AS SELECT * FROM ((SELECT * FROM p UNION ALL SELECT * FROM q1) UNION ALL SELE..." +== 626 +-- truncate_limit: 100 +explain (costs off) execute q (1, 1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE q(1, 1)" +== 627 +-- truncate_limit: 100 +execute q (1, 1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q(1, 1)" +== 628 +-- truncate_limit: 100 +drop table p, q +-- +TABLE: name="p" schema="" table="p" ctx=DDL +TABLE: name="q" schema="" table="q" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE p, q" +== 629 +-- truncate_limit: 100 +-- Ensure run-time pruning works correctly when we match a partitioned table +-- on the first level but find no matching partitions on the second level. +create table listp (a int, b int) partition by list (a) +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp (a int, b int) PARTITION BY LIST (a)" +== 630 +-- truncate_limit: 100 +create table listp1 partition of listp for values in(1) +-- +TABLE: name="listp1" schema="" table="listp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp1 PARTITION OF listp FOR VALUES IN (1)" +== 631 +-- truncate_limit: 100 +create table listp2 partition of listp for values in(2) partition by list(b) +-- +TABLE: name="listp2" schema="" table="listp2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp2 PARTITION OF listp FOR VALUES IN (2) PARTITION BY LIST (b)" +== 632 +-- truncate_limit: 100 +create table listp2_10 partition of listp2 for values in (10) +-- +TABLE: name="listp2_10" schema="" table="listp2_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp2_10 PARTITION OF listp2 FOR VALUES IN (10)" +== 633 +-- truncate_limit: 100 +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select 2) and b <> 10 +-- +TABLE: name="listp" schema="" table="listp" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) SELECT * FROM listp WHERE a = (SELECT 2) AN..." +== 634 +-- truncate_limit: 100 +|-- +-- check that a partition directly accessed in a query is excluded with +-- constraint_exclusion = on +|-- + +-- turn off partition pruning, so that it doesn't interfere +set enable_partition_pruning to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_partition_pruning TO OFF" +== 635 +-- truncate_limit: 100 +-- setting constraint_exclusion to 'partition' disables exclusion +set constraint_exclusion to 'partition' +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO partition" +== 636 +-- truncate_limit: 100 +explain (costs off) select * from listp1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM listp1 WHERE a = 2" +== 637 +-- truncate_limit: 100 +explain (costs off) update listp1 set a = 1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE listp1 SET a = 1 WHERE a = 2" +== 638 +-- truncate_limit: 100 +-- constraint exclusion enabled +set constraint_exclusion to 'on' +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO ON" +== 639 +-- truncate_limit: 100 +explain (costs off) select * from listp1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM listp1 WHERE a = 2" +== 640 +-- truncate_limit: 100 +explain (costs off) update listp1 set a = 1 where a = 2 +-- +TABLE: name="listp1" schema="" table="listp1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE listp1 SET a = 1 WHERE a = 2" +== 641 +-- truncate_limit: 100 +reset constraint_exclusion +-- +STMT: VariableSetStmt +TRUNCATED: "RESET constraint_exclusion" +== 642 +-- truncate_limit: 100 +reset enable_partition_pruning +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_partition_pruning" +== 643 +-- truncate_limit: 100 +drop table listp +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE listp" +== 644 +-- truncate_limit: 100 +-- Ensure run-time pruning works correctly for nested Append nodes +set parallel_setup_cost to 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 645 +-- truncate_limit: 100 +set parallel_tuple_cost to 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 646 +-- truncate_limit: 100 +create table listp (a int) partition by list(a) +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp (a int) PARTITION BY LIST (a)" +== 647 +-- truncate_limit: 100 +create table listp_12 partition of listp for values in(1,2) partition by list(a) +-- +TABLE: name="listp_12" schema="" table="listp_12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp_12 PARTITION OF listp FOR VALUES IN (1, 2) PARTITION BY LIST (a)" +== 648 +-- truncate_limit: 100 +create table listp_12_1 partition of listp_12 for values in(1) +-- +TABLE: name="listp_12_1" schema="" table="listp_12_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp_12_1 PARTITION OF listp_12 FOR VALUES IN (1)" +== 649 +-- truncate_limit: 100 +create table listp_12_2 partition of listp_12 for values in(2) +-- +TABLE: name="listp_12_2" schema="" table="listp_12_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE listp_12_2 PARTITION OF listp_12 FOR VALUES IN (2)" +== 650 +-- truncate_limit: 100 +-- Force the 2nd subnode of the Append to be non-parallel. This results in +-- a nested Append node because the mixed parallel / non-parallel paths cannot +-- be pulled into the top-level Append. +alter table listp_12_1 set (parallel_workers = 0) +-- +TABLE: name="listp_12_1" schema="" table="listp_12_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE listp_12_1 SET (parallel_workers=0)" +== 651 +-- truncate_limit: 100 +-- Ensure that listp_12_2 is not scanned. (The nested Append is not seen in +-- the plan as it's pulled in setref.c due to having just a single subnode). +select explain_parallel_append('select * from listp where a = (select 1);') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT explain_parallel_append('select * from listp where a = (select 1);')" +== 652 +-- truncate_limit: 100 +-- Like the above but throw some more complexity at the planner by adding +-- a UNION ALL. We expect both sides of the union not to scan the +-- non-required partitions. +select explain_parallel_append( +'select * from listp where a = (select 1) + union all +select * from listp where a = (select 2);') +-- +FUNCTION: name="explain_parallel_append" function="explain_parallel_append" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 653 +-- truncate_limit: 100 +drop table listp +-- +TABLE: name="listp" schema="" table="listp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE listp" +== 654 +-- truncate_limit: 100 +reset parallel_tuple_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_tuple_cost" +== 655 +-- truncate_limit: 100 +reset parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 656 +-- truncate_limit: 100 +-- Test case for run-time pruning with a nested Merge Append +set enable_sort to 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO 0" +== 657 +-- truncate_limit: 100 +create table rangep (a int, b int) partition by range (a) +-- +TABLE: name="rangep" schema="" table="rangep" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rangep (a int, b int) PARTITION BY RANGE (a)" +== 658 +-- truncate_limit: 100 +create table rangep_0_to_100 partition of rangep for values from (0) to (100) partition by list (b) +-- +TABLE: name="rangep_0_to_100" schema="" table="rangep_0_to_100" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rangep_0_to_100 PARTITION OF rangep FOR VALUES FROM (0) TO (100) PARTITION BY LIST (b)" +== 659 +-- truncate_limit: 100 +-- We need 3 sub-partitions. 1 to validate pruning worked and another two +-- because a single remaining partition would be pulled up to the main Append. +create table rangep_0_to_100_1 partition of rangep_0_to_100 for values in(1) +-- +TABLE: name="rangep_0_to_100_1" schema="" table="rangep_0_to_100_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rangep_0_to_100_1 PARTITION OF rangep_0_to_100 FOR VALUES IN (1)" +== 660 +-- truncate_limit: 100 +create table rangep_0_to_100_2 partition of rangep_0_to_100 for values in(2) +-- +TABLE: name="rangep_0_to_100_2" schema="" table="rangep_0_to_100_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rangep_0_to_100_2 PARTITION OF rangep_0_to_100 FOR VALUES IN (2)" +== 661 +-- truncate_limit: 100 +create table rangep_0_to_100_3 partition of rangep_0_to_100 for values in(3) +-- +TABLE: name="rangep_0_to_100_3" schema="" table="rangep_0_to_100_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rangep_0_to_100_3 PARTITION OF rangep_0_to_100 FOR VALUES IN (3)" +== 662 +-- truncate_limit: 100 +create table rangep_100_to_200 partition of rangep for values from (100) to (200) +-- +TABLE: name="rangep_100_to_200" schema="" table="rangep_100_to_200" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rangep_100_to_200 PARTITION OF rangep FOR VALUES FROM (100) TO (200)" +== 663 +-- truncate_limit: 100 +create index on rangep (a) +-- +TABLE: name="rangep" schema="" table="rangep" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON rangep USING btree (a)" +== 664 +-- truncate_limit: 100 +-- Ensure run-time pruning works on the nested Merge Append +explain (analyze on, costs off, timing off, summary off) +select * from rangep where b IN((select 1),(select 2)) order by a +-- +TABLE: name="rangep" schema="" table="rangep" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT * FROM rangep WHERE b IN ((SELECT..." +== 665 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 666 +-- truncate_limit: 100 +drop table rangep +-- +TABLE: name="rangep" schema="" table="rangep" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rangep" +== 667 +-- truncate_limit: 100 +|-- +-- Check that gen_prune_steps_from_opexps() works well for various cases of +-- clauses for different partition keys +|-- + +create table rp_prefix_test1 (a int, b varchar) partition by range(a, b) +-- +TABLE: name="rp_prefix_test1" schema="" table="rp_prefix_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test1 (a int, b varchar) PARTITION BY RANGE (a, b)" +== 668 +-- truncate_limit: 100 +create table rp_prefix_test1_p1 partition of rp_prefix_test1 for values from (1, 'a') to (1, 'b') +-- +TABLE: name="rp_prefix_test1_p1" schema="" table="rp_prefix_test1_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test1_p1 PARTITION OF rp_prefix_test1 FOR VALUES FROM (1, 'a') TO (1, 'b')" +== 669 +-- truncate_limit: 100 +create table rp_prefix_test1_p2 partition of rp_prefix_test1 for values from (2, 'a') to (2, 'b') +-- +TABLE: name="rp_prefix_test1_p2" schema="" table="rp_prefix_test1_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test1_p2 PARTITION OF rp_prefix_test1 FOR VALUES FROM (2, 'a') TO (2, 'b')" +== 670 +-- truncate_limit: 100 +-- Don't call get_steps_using_prefix() with the last partition key b plus +-- an empty prefix +explain (costs off) select * from rp_prefix_test1 where a <= 1 and b = 'a' +-- +TABLE: name="rp_prefix_test1" schema="" table="rp_prefix_test1" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rp_prefix_test1 WHERE a <= 1 AND b = 'a'" +== 671 +-- truncate_limit: 100 +create table rp_prefix_test2 (a int, b int, c int) partition by range(a, b, c) +-- +TABLE: name="rp_prefix_test2" schema="" table="rp_prefix_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test2 (a int, b int, c int) PARTITION BY RANGE (a, b, c)" +== 672 +-- truncate_limit: 100 +create table rp_prefix_test2_p1 partition of rp_prefix_test2 for values from (1, 1, 0) to (1, 1, 10) +-- +TABLE: name="rp_prefix_test2_p1" schema="" table="rp_prefix_test2_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test2_p1 PARTITION OF rp_prefix_test2 FOR VALUES FROM (1, 1, 0) TO (1, 1, 10)" +== 673 +-- truncate_limit: 100 +create table rp_prefix_test2_p2 partition of rp_prefix_test2 for values from (2, 2, 0) to (2, 2, 10) +-- +TABLE: name="rp_prefix_test2_p2" schema="" table="rp_prefix_test2_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test2_p2 PARTITION OF rp_prefix_test2 FOR VALUES FROM (2, 2, 0) TO (2, 2, 10)" +== 674 +-- truncate_limit: 100 +-- Don't call get_steps_using_prefix() with the last partition key c plus +-- an invalid prefix (ie, b = 1) +explain (costs off) select * from rp_prefix_test2 where a <= 1 and b = 1 and c >= 0 +-- +TABLE: name="rp_prefix_test2" schema="" table="rp_prefix_test2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rp_prefix_test2 WHERE a <= 1 AND b = 1 AND c >= 0" +== 675 +-- truncate_limit: 100 +create table rp_prefix_test3 (a int, b int, c int, d int) partition by range(a, b, c, d) +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test3 (a int, b int, c int, d int) PARTITION BY RANGE (a, b, c, d)" +== 676 +-- truncate_limit: 100 +create table rp_prefix_test3_p1 partition of rp_prefix_test3 for values from (1, 1, 1, 0) to (1, 1, 1, 10) +-- +TABLE: name="rp_prefix_test3_p1" schema="" table="rp_prefix_test3_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test3_p1 PARTITION OF rp_prefix_test3 FOR VALUES FROM (1, 1, 1, 0) TO (1, ..." +== 677 +-- truncate_limit: 100 +create table rp_prefix_test3_p2 partition of rp_prefix_test3 for values from (2, 2, 2, 0) to (2, 2, 2, 10) +-- +TABLE: name="rp_prefix_test3_p2" schema="" table="rp_prefix_test3_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rp_prefix_test3_p2 PARTITION OF rp_prefix_test3 FOR VALUES FROM (2, 2, 2, 0) TO (2, ..." +== 678 +-- truncate_limit: 100 +-- Test that get_steps_using_prefix() handles a prefix that contains multiple +-- clauses for the partition key b (ie, b >= 1 and b >= 2) +explain (costs off) select * from rp_prefix_test3 where a >= 1 and b >= 1 and b >= 2 and c >= 2 and d >= 0 +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rp_prefix_test3 WHERE a >= 1 AND b >= 1 AND b >= 2 AND c >= 2 A..." +== 679 +-- truncate_limit: 100 +-- Test that get_steps_using_prefix() handles a prefix that contains multiple +-- clauses for the partition key b (ie, b >= 1 and b = 2) (This also tests +-- that the caller arranges clauses in that prefix in the required order) +explain (costs off) select * from rp_prefix_test3 where a >= 1 and b >= 1 and b = 2 and c = 2 and d >= 0 +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="d" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rp_prefix_test3 WHERE a >= 1 AND b >= 1 AND b = 2 AND c = 2 AND..." +== 680 +-- truncate_limit: 100 +drop table rp_prefix_test1 +-- +TABLE: name="rp_prefix_test1" schema="" table="rp_prefix_test1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rp_prefix_test1" +== 681 +-- truncate_limit: 100 +drop table rp_prefix_test2 +-- +TABLE: name="rp_prefix_test2" schema="" table="rp_prefix_test2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rp_prefix_test2" +== 682 +-- truncate_limit: 100 +drop table rp_prefix_test3 +-- +TABLE: name="rp_prefix_test3" schema="" table="rp_prefix_test3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rp_prefix_test3" +== 683 +-- truncate_limit: 100 +|-- +-- Test that get_steps_using_prefix() handles IS NULL clauses correctly +|-- +create table hp_prefix_test (a int, b int, c int, d int) + partition by hash (a part_test_int4_ops, b part_test_int4_ops, c part_test_int4_ops, d part_test_int4_ops) +-- +TABLE: name="hp_prefix_test" schema="" table="hp_prefix_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp_prefix_test (a int, b int, c int, d int) PARTITION BY HASH (a part_test_int4_ops,..." +== 684 +-- truncate_limit: 100 +-- create 8 partitions +select 'create table hp_prefix_test_p' || x::text || ' partition of hp_prefix_test for values with (modulus 8, remainder ' || x::text || ');' +from generate_Series(0,7) x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(0, 7) x" +== 685 +-- truncate_limit: 100 +-- insert 16 rows, one row for each test to perform. +insert into hp_prefix_test +select + case a when 0 then null else 1 end, + case b when 0 then null else 2 end, + case c when 0 then null else 3 end, + case d when 0 then null else 4 end +from + generate_series(0,1) a, + generate_series(0,1) b, + generate_Series(0,1) c, + generate_Series(0,1) d +-- +TABLE: name="hp_prefix_test" schema="" table="hp_prefix_test" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hp_prefix_test SELECT ... FROM generate_series(0, 1) a, generate_series(0, 1) b, gene..." +== 686 +-- truncate_limit: 100 +-- Ensure partition pruning works correctly for each combination of IS NULL +-- and equality quals. This may seem a little excessive, but there have been +-- a number of bugs in this area over the years. We make use of row only +-- output to reduce the size of the expected results. +select + 'explain (costs off) select tableoid::regclass,* from hp_prefix_test where ' || + string_agg(c.colname || case when g.s & (1 << c.colpos) = 0 then ' is null' else ' = ' || (colpos+1)::text end, ' and ' order by c.colpos) +from (values('a',0),('b',1),('c',2),('d',3)) c(colname, colpos), generate_Series(0,15) g(s) +group by g.s +order by g.s +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) c(colname, colpos), generate_series(0, 15) g(s) GROUP BY g.s ORDER..." +== 687 +-- truncate_limit: 100 +-- And ensure we get exactly 1 row from each. Again, all 16 possible combinations. +select + 'select tableoid::regclass,* from hp_prefix_test where ' || + string_agg(c.colname || case when g.s & (1 << c.colpos) = 0 then ' is null' else ' = ' || (colpos+1)::text end, ' and ' order by c.colpos) +from (values('a',0),('b',1),('c',2),('d',3)) c(colname, colpos), generate_Series(0,15) g(s) +group by g.s +order by g.s +-- +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) c(colname, colpos), generate_series(0, 15) g(s) GROUP BY g.s ORDER..." +== 688 +-- truncate_limit: 100 +drop table hp_prefix_test +-- +TABLE: name="hp_prefix_test" schema="" table="hp_prefix_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hp_prefix_test" +== 689 +-- truncate_limit: 100 +|-- +-- Check that gen_partprune_steps() detects self-contradiction from clauses +-- regardless of the order of the clauses (Here we use a custom operator to +-- prevent the equivclass.c machinery from reordering the clauses) +|-- + +create operator === ( + leftarg = int4, + rightarg = int4, + procedure = int4eq, + commutator = ===, + hashes +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR === (leftarg = int4, rightarg = int4, procedure = int4eq, commutator = ===, hashes)" +== 690 +-- truncate_limit: 100 +create operator class part_test_int4_ops2 +for type int4 +using hash as +operator 1 ===, +function 2 part_hashint4_noop(int4, int8) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS part_test_int4_ops2 FOR TYPE int4 USING hash AS OPERATOR 1 ===, FUNCTION 2 ..." +== 691 +-- truncate_limit: 100 +create table hp_contradict_test (a int, b int) partition by hash (a part_test_int4_ops2, b part_test_int4_ops2) +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp_contradict_test (a int, b int) PARTITION BY HASH (a part_test_int4_ops2, b part_t..." +== 692 +-- truncate_limit: 100 +create table hp_contradict_test_p1 partition of hp_contradict_test for values with (modulus 2, remainder 0) +-- +TABLE: name="hp_contradict_test_p1" schema="" table="hp_contradict_test_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp_contradict_test_p1 PARTITION OF hp_contradict_test FOR VALUES WITH (MODULUS 2, RE..." +== 693 +-- truncate_limit: 100 +create table hp_contradict_test_p2 partition of hp_contradict_test for values with (modulus 2, remainder 1) +-- +TABLE: name="hp_contradict_test_p2" schema="" table="hp_contradict_test_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hp_contradict_test_p2 PARTITION OF hp_contradict_test FOR VALUES WITH (MODULUS 2, RE..." +== 694 +-- truncate_limit: 100 +explain (costs off) select * from hp_contradict_test where a is null and a === 1 and b === 1 +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp_contradict_test WHERE a IS NULL AND a === 1 AND b === 1" +== 695 +-- truncate_limit: 100 +explain (costs off) select * from hp_contradict_test where a === 1 and b === 1 and a is null +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM hp_contradict_test WHERE a === 1 AND b === 1 AND a IS NULL" +== 696 +-- truncate_limit: 100 +drop table hp_contradict_test +-- +TABLE: name="hp_contradict_test" schema="" table="hp_contradict_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hp_contradict_test" +== 697 +-- truncate_limit: 100 +drop operator class part_test_int4_ops2 using hash +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS part_test_int4_ops2 USING hash" +== 698 +-- truncate_limit: 100 +drop operator ===(int4, int4) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR ===(int4, int4)" diff --git a/parser/testdata/summary_truncate/postgres_regress/password.metadata.json b/parser/testdata/summary_truncate/postgres_regress/password.metadata.json new file mode 100644 index 0000000..fbb3e40 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/password.metadata.json @@ -0,0 +1,55 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/password.test b/parser/testdata/summary_truncate/postgres_regress/password.test new file mode 100644 index 0000000..7c39fca --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/password.test @@ -0,0 +1,376 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for password types +|-- + +-- Tests for GUC password_encryption +SET password_encryption = 'novalue' +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO novalue" +== 002 +-- truncate_limit: 100 +-- error +SET password_encryption = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO TRUE" +== 003 +-- truncate_limit: 100 +-- error +SET password_encryption = 'md5' +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO md5" +== 004 +-- truncate_limit: 100 +-- ok +SET password_encryption = 'scram-sha-256' +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO \"scram-sha-256\"" +== 005 +-- truncate_limit: 100 +-- ok + +-- consistency of password entries +SET password_encryption = 'md5' +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO md5" +== 006 +-- truncate_limit: 100 +CREATE ROLE regress_passwd1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd1" +== 007 +-- truncate_limit: 100 +ALTER ROLE regress_passwd1 PASSWORD 'role_pwd1' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd1 WITH PASSWORD 'role_pwd1'" +== 008 +-- truncate_limit: 100 +CREATE ROLE regress_passwd2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd2" +== 009 +-- truncate_limit: 100 +ALTER ROLE regress_passwd2 PASSWORD 'role_pwd2' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd2 WITH PASSWORD 'role_pwd2'" +== 010 +-- truncate_limit: 100 +SET password_encryption = 'scram-sha-256' +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO \"scram-sha-256\"" +== 011 +-- truncate_limit: 100 +CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd3 WITH PASSWORD 'role_pwd3'" +== 012 +-- truncate_limit: 100 +CREATE ROLE regress_passwd4 PASSWORD NULL +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd4 WITH PASSWORD NULL" +== 013 +-- truncate_limit: 100 +-- check list of created entries +|-- +-- The scram secret will look something like: +-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo= +|-- +-- Since the salt is random, the exact value stored will be different on every test +-- run. Use a regular expression to mask the changing parts. +SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname LIKE 'regress_passwd%' ORDER BY rolname, rolpassword" +== 014 +-- truncate_limit: 100 +-- Rename a role +ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new +-- +STMT: RenameStmt +TRUNCATED: "ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new" +== 015 +-- truncate_limit: 100 +-- md5 entry should have been removed +SELECT rolname, rolpassword + FROM pg_authid + WHERE rolname LIKE 'regress_passwd2_new' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT rolname, rolpassword FROM pg_authid WHERE ... ORDER BY rolname, rolpassword" +== 016 +-- truncate_limit: 100 +ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2" +== 017 +-- truncate_limit: 100 +-- Change passwords with ALTER USER. With plaintext or already-encrypted +-- passwords. +SET password_encryption = 'md5' +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO md5" +== 018 +-- truncate_limit: 100 +-- encrypt with MD5 +ALTER ROLE regress_passwd2 PASSWORD 'foo' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd2 WITH PASSWORD 'foo'" +== 019 +-- truncate_limit: 100 +-- already encrypted, use as they are +ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd1 WITH PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70'" +== 020 +-- truncate_limit: 100 +ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd3 WITH PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbV..." +== 021 +-- truncate_limit: 100 +SET password_encryption = 'scram-sha-256' +-- +STMT: VariableSetStmt +TRUNCATED: "SET password_encryption TO \"scram-sha-256\"" +== 022 +-- truncate_limit: 100 +-- create SCRAM secret +ALTER ROLE regress_passwd4 PASSWORD 'foo' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd4 WITH PASSWORD 'foo'" +== 023 +-- truncate_limit: 100 +-- already encrypted with MD5, use as it is +CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd5 WITH PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023'" +== 024 +-- truncate_limit: 100 +-- This looks like a valid SCRAM-SHA-256 secret, but it is not +-- so it should be hashed with SCRAM-SHA-256. +CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd6 WITH PASSWORD 'SCRAM-SHA-256$1234'" +== 025 +-- truncate_limit: 100 +-- These may look like valid MD5 secrets, but they are not, so they +-- should be hashed with SCRAM-SHA-256. +-- trailing garbage at the end +CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd7 WITH PASSWORD 'md5012345678901234567890123456789zz'" +== 026 +-- truncate_limit: 100 +-- invalid length +CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd8 WITH PASSWORD 'md501234567890123456789012345678901zz'" +== 027 +-- truncate_limit: 100 +-- Changing the SCRAM iteration count +SET scram_iterations = 1024 +-- +STMT: VariableSetStmt +TRUNCATED: "SET scram_iterations TO 1024" +== 028 +-- truncate_limit: 100 +CREATE ROLE regress_passwd9 PASSWORD 'alterediterationcount' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd9 WITH PASSWORD 'alterediterationcount'" +== 029 +-- truncate_limit: 100 +SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname LIKE 'regress_passwd%' ORDER BY rolname, rolpassword" +== 030 +-- truncate_limit: 100 +-- An empty password is not allowed, in any form +CREATE ROLE regress_passwd_empty PASSWORD '' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd_empty WITH PASSWORD ''" +== 031 +-- truncate_limit: 100 +ALTER ROLE regress_passwd_empty PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd_empty WITH PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a'" +== 032 +-- truncate_limit: 100 +ALTER ROLE regress_passwd_empty PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27ZFKbZ2nV+vtnYM995pDh9ca6WSi120=:qVV5NeluNfUPkwm7Vqat25RjSPLkGeoZBQs6wVv+um4=' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_passwd_empty WITH PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27Z..." +== 033 +-- truncate_limit: 100 +SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT rolpassword FROM pg_authid WHERE rolname = 'regress_passwd_empty'" +== 034 +-- truncate_limit: 100 +-- Test with invalid stored and server keys. +|-- +-- The first is valid, to act as a control. The others have too long +-- stored/server keys. They will be re-hashed. +CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd_sha_len0 WITH PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky..." +== 035 +-- truncate_limit: 100 +CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd_sha_len1 WITH PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky..." +== 036 +-- truncate_limit: 100 +CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=' +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_passwd_sha_len2 WITH PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky..." +== 037 +-- truncate_limit: 100 +-- Check that the invalid secrets were re-hashed. A re-hashed secret +-- should not contain the original salt. +SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed + FROM pg_authid + WHERE rolname LIKE 'regress_passwd_sha_len%' + ORDER BY rolname +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname LIKE 'regress_passwd_sha_len%' ORDER BY rolname" +== 038 +-- truncate_limit: 100 +DROP ROLE regress_passwd1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd1" +== 039 +-- truncate_limit: 100 +DROP ROLE regress_passwd2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd2" +== 040 +-- truncate_limit: 100 +DROP ROLE regress_passwd3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd3" +== 041 +-- truncate_limit: 100 +DROP ROLE regress_passwd4 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd4" +== 042 +-- truncate_limit: 100 +DROP ROLE regress_passwd5 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd5" +== 043 +-- truncate_limit: 100 +DROP ROLE regress_passwd6 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd6" +== 044 +-- truncate_limit: 100 +DROP ROLE regress_passwd7 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd7" +== 045 +-- truncate_limit: 100 +DROP ROLE regress_passwd8 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd8" +== 046 +-- truncate_limit: 100 +DROP ROLE regress_passwd9 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd9" +== 047 +-- truncate_limit: 100 +DROP ROLE regress_passwd_empty +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd_empty" +== 048 +-- truncate_limit: 100 +DROP ROLE regress_passwd_sha_len0 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd_sha_len0" +== 049 +-- truncate_limit: 100 +DROP ROLE regress_passwd_sha_len1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd_sha_len1" +== 050 +-- truncate_limit: 100 +DROP ROLE regress_passwd_sha_len2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_passwd_sha_len2" +== 051 +-- truncate_limit: 100 +-- all entries should have been removed +SELECT rolname, rolpassword + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT rolname, rolpassword FROM pg_authid WHERE ... ORDER BY rolname, rolpassword" diff --git a/parser/testdata/summary_truncate/postgres_regress/path.metadata.json b/parser/testdata/summary_truncate/postgres_regress/path.metadata.json new file mode 100644 index 0000000..880b1d2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/path.metadata.json @@ -0,0 +1,27 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/path.test b/parser/testdata/summary_truncate/postgres_regress/path.test new file mode 100644 index 0000000..04137c6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/path.test @@ -0,0 +1,193 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PATH +|-- + +--DROP TABLE PATH_TBL; + +CREATE TABLE PATH_TBL (f1 path) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE path_tbl (f1 path)" +== 002 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('[(1,2),(3,4)]')" +== 003 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES (' ( ( 1 , 2 ) , ( 3 , 4 ) ) ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES (' ( ( 1 , 2 ) , ( 3 , 4 ) ) ')" +== 004 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('[ (0,0),(3,0),(4,5),(1,6) ]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('[ (0,0),(3,0),(4,5),(1,6) ]')" +== 005 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('((1,2) ,(3,4 ))') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('((1,2) ,(3,4 ))')" +== 006 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('1,2 ,3,4 ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('1,2 ,3,4 ')" +== 007 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES (' [1,2,3, 4] ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES (' [1,2,3, 4] ')" +== 008 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('((10,20))') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('((10,20))')" +== 009 +-- truncate_limit: 100 +-- Only one point + +INSERT INTO PATH_TBL VALUES ('[ 11,12,13,14 ]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('[ 11,12,13,14 ]')" +== 010 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('( 11,12,13,14) ') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('( 11,12,13,14) ')" +== 011 +-- truncate_limit: 100 +-- bad values for parser testing +INSERT INTO PATH_TBL VALUES ('[]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('[]')" +== 012 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('[(,2),(3,4)]')" +== 013 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('[(1,2),(3,4)')" +== 014 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('(1,2,3,4') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('(1,2,3,4')" +== 015 +-- truncate_limit: 100 +INSERT INTO PATH_TBL VALUES ('(1,2),(3,4)]') +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO path_tbl VALUES ('(1,2),(3,4)]')" +== 016 +-- truncate_limit: 100 +SELECT f1 AS open_path FROM PATH_TBL WHERE isopen(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FUNCTION: name="isopen" function="isopen" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS open_path FROM path_tbl WHERE isopen(f1)" +== 017 +-- truncate_limit: 100 +SELECT f1 AS closed_path FROM PATH_TBL WHERE isclosed(f1) +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FUNCTION: name="isclosed" function="isclosed" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS closed_path FROM path_tbl WHERE isclosed(f1)" +== 018 +-- truncate_limit: 100 +SELECT pclose(f1) AS closed_path FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="pclose" function="pclose" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pclose(f1) AS closed_path FROM path_tbl" +== 019 +-- truncate_limit: 100 +SELECT popen(f1) AS open_path FROM PATH_TBL +-- +TABLE: name="path_tbl" schema="" table="path_tbl" ctx=Select +FUNCTION: name="popen" function="popen" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT popen(f1) AS open_path FROM path_tbl" +== 020 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('[(1,2),(3)]', 'path') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('[(1,2),(3)]', 'path')" +== 021 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'path') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'path')" +== 022 +-- truncate_limit: 100 +SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path')" +== 023 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('[(1,2,6),(3,4,6)]', 'path') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('[(1,2,6),(3,4,6)]', 'path')" diff --git a/parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json b/parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json new file mode 100644 index 0000000..442b788 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json @@ -0,0 +1,35 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/pg_lsn.test b/parser/testdata/summary_truncate/postgres_regress/pg_lsn.test new file mode 100644 index 0000000..622ef60 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/pg_lsn.test @@ -0,0 +1,243 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PG_LSN +|-- + +CREATE TABLE PG_LSN_TBL (f1 pg_lsn) +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pg_lsn_tbl (f1 pg_lsn)" +== 002 +-- truncate_limit: 100 +-- Largest and smallest input +INSERT INTO PG_LSN_TBL VALUES ('0/0') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pg_lsn_tbl VALUES ('0/0')" +== 003 +-- truncate_limit: 100 +INSERT INTO PG_LSN_TBL VALUES ('FFFFFFFF/FFFFFFFF') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pg_lsn_tbl VALUES ('FFFFFFFF/FFFFFFFF')" +== 004 +-- truncate_limit: 100 +-- Incorrect input +INSERT INTO PG_LSN_TBL VALUES ('G/0') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pg_lsn_tbl VALUES ('G/0')" +== 005 +-- truncate_limit: 100 +INSERT INTO PG_LSN_TBL VALUES ('-1/0') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pg_lsn_tbl VALUES ('-1/0')" +== 006 +-- truncate_limit: 100 +INSERT INTO PG_LSN_TBL VALUES (' 0/12345678') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pg_lsn_tbl VALUES (' 0/12345678')" +== 007 +-- truncate_limit: 100 +INSERT INTO PG_LSN_TBL VALUES ('ABCD/') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pg_lsn_tbl VALUES ('ABCD/')" +== 008 +-- truncate_limit: 100 +INSERT INTO PG_LSN_TBL VALUES ('/ABCD') +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pg_lsn_tbl VALUES ('/ABCD')" +== 009 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('16AE7F7', 'pg_lsn') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('16AE7F7', 'pg_lsn')" +== 010 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('16AE7F7', 'pg_lsn') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('16AE7F7', 'pg_lsn')" +== 011 +-- truncate_limit: 100 +-- Min/Max aggregation +SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(f1), max(f1) FROM pg_lsn_tbl" +== 012 +-- truncate_limit: 100 +DROP TABLE PG_LSN_TBL +-- +TABLE: name="pg_lsn_tbl" schema="" table="pg_lsn_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pg_lsn_tbl" +== 013 +-- truncate_limit: 100 +-- Operators +SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn" +== 014 +-- truncate_limit: 100 +SELECT '0/16AE7F8'::pg_lsn != '0/16AE7F7' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F8'::pg_lsn <> '0/16AE7F7'" +== 015 +-- truncate_limit: 100 +SELECT '0/16AE7F7' < '0/16AE7F8'::pg_lsn +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F7' < '0/16AE7F8'::pg_lsn" +== 016 +-- truncate_limit: 100 +SELECT '0/16AE7F8' > pg_lsn '0/16AE7F7' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F8' > '0/16AE7F7'::pg_lsn" +== 017 +-- truncate_limit: 100 +SELECT '0/16AE7F7'::pg_lsn - '0/16AE7F8'::pg_lsn +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F7'::pg_lsn - '0/16AE7F8'::pg_lsn" +== 018 +-- truncate_limit: 100 +SELECT '0/16AE7F8'::pg_lsn - '0/16AE7F7'::pg_lsn +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F8'::pg_lsn - '0/16AE7F7'::pg_lsn" +== 019 +-- truncate_limit: 100 +SELECT '0/16AE7F7'::pg_lsn + 16::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F7'::pg_lsn + 16::numeric" +== 020 +-- truncate_limit: 100 +SELECT 16::numeric + '0/16AE7F7'::pg_lsn +-- +STMT: SelectStmt +TRUNCATED: "SELECT 16::numeric + '0/16AE7F7'::pg_lsn" +== 021 +-- truncate_limit: 100 +SELECT '0/16AE7F7'::pg_lsn - 16::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F7'::pg_lsn - 16::numeric" +== 022 +-- truncate_limit: 100 +SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 1::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 1::numeric" +== 023 +-- truncate_limit: 100 +SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 2::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 2::numeric" +== 024 +-- truncate_limit: 100 +-- out of range error +SELECT '0/1'::pg_lsn - 1::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/1'::pg_lsn - 1::numeric" +== 025 +-- truncate_limit: 100 +SELECT '0/1'::pg_lsn - 2::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/1'::pg_lsn - 2::numeric" +== 026 +-- truncate_limit: 100 +-- out of range error +SELECT '0/0'::pg_lsn + ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/0'::pg_lsn + ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn)" +== 027 +-- truncate_limit: 100 +SELECT 'FFFFFFFF/FFFFFFFF'::pg_lsn - ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'FFFFFFFF/FFFFFFFF'::pg_lsn - ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn)" +== 028 +-- truncate_limit: 100 +SELECT '0/16AE7F7'::pg_lsn + 'NaN'::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F7'::pg_lsn + 'NaN'::numeric" +== 029 +-- truncate_limit: 100 +SELECT '0/16AE7F7'::pg_lsn - 'NaN'::numeric +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0/16AE7F7'::pg_lsn - 'NaN'::numeric" +== 030 +-- truncate_limit: 100 +-- Check btree and hash opclasses +EXPLAIN (COSTS OFF) +SELECT DISTINCT (i || '/' || j)::pg_lsn f + FROM generate_series(1, 10) i, + generate_series(1, 10) j, + generate_series(1, 5) k + WHERE i <= 10 AND j > 0 AND j <= 10 + ORDER BY f +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +FILTER: schema="" table="" column="j" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT ((i || '/') || j)::pg_lsn AS f FROM generate_series(1, 10) i,..." +== 031 +-- truncate_limit: 100 +SELECT DISTINCT (i || '/' || j)::pg_lsn f + FROM generate_series(1, 10) i, + generate_series(1, 10) j, + generate_series(1, 5) k + WHERE i <= 10 AND j > 0 AND j <= 10 + ORDER BY f +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ... AS ... FROM generate_series(1, 10) i, generate_series(1, 10) j, generate_seri..." diff --git a/parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json b/parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json new file mode 100644 index 0000000..ba349a5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json @@ -0,0 +1,101 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/plancache.test b/parser/testdata/summary_truncate/postgres_regress/plancache.test new file mode 100644 index 0000000..d778179 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/plancache.test @@ -0,0 +1,753 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests to exercise the plan caching/invalidation mechanism +|-- + +CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE pcachetest AS SELECT * FROM int8_tbl" +== 002 +-- truncate_limit: 100 +-- create and use a cached plan +PREPARE prepstmt AS SELECT * FROM pcachetest +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE prepstmt AS SELECT * FROM pcachetest" +== 003 +-- truncate_limit: 100 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt" +== 004 +-- truncate_limit: 100 +-- and one with parameters +PREPARE prepstmt2(bigint) AS SELECT * FROM pcachetest WHERE q1 = $1 +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE prepstmt2(bigint) AS SELECT * FROM pcachetest WHERE q1 = $1" +== 005 +-- truncate_limit: 100 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt2(123)" +== 006 +-- truncate_limit: 100 +-- invalidate the plans and see what happens +DROP TABLE pcachetest +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pcachetest" +== 007 +-- truncate_limit: 100 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt" +== 008 +-- truncate_limit: 100 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt2(123)" +== 009 +-- truncate_limit: 100 +-- recreate the temp table (this demonstrates that the raw plan is +-- purely textual and doesn't depend on OIDs, for instance) +CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2 +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2" +== 010 +-- truncate_limit: 100 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt" +== 011 +-- truncate_limit: 100 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt2(123)" +== 012 +-- truncate_limit: 100 +-- prepared statements should prevent change in output tupdesc, +-- since clients probably aren't expecting that to change on the fly +ALTER TABLE pcachetest ADD COLUMN q3 bigint +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pcachetest ADD COLUMN q3 bigint" +== 013 +-- truncate_limit: 100 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt" +== 014 +-- truncate_limit: 100 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt2(123)" +== 015 +-- truncate_limit: 100 +-- but we're nice guys and will let you undo your mistake +ALTER TABLE pcachetest DROP COLUMN q3 +-- +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pcachetest DROP q3" +== 016 +-- truncate_limit: 100 +EXECUTE prepstmt +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt" +== 017 +-- truncate_limit: 100 +EXECUTE prepstmt2(123) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE prepstmt2(123)" +== 018 +-- truncate_limit: 100 +-- Try it with a view, which isn't directly used in the resulting plan +-- but should trigger invalidation anyway +CREATE TEMP VIEW pcacheview AS + SELECT * FROM pcachetest +-- +TABLE: name="pcacheview" schema="" table="pcacheview" ctx=DDL +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW pcacheview AS SELECT * FROM pcachetest" +== 019 +-- truncate_limit: 100 +PREPARE vprep AS SELECT * FROM pcacheview +-- +TABLE: name="pcacheview" schema="" table="pcacheview" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE vprep AS SELECT * FROM pcacheview" +== 020 +-- truncate_limit: 100 +EXECUTE vprep +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE vprep" +== 021 +-- truncate_limit: 100 +CREATE OR REPLACE TEMP VIEW pcacheview AS + SELECT q1, q2/2 AS q2 FROM pcachetest +-- +TABLE: name="pcacheview" schema="" table="pcacheview" ctx=DDL +TABLE: name="pcachetest" schema="" table="pcachetest" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW pcacheview AS SELECT q1, q2 / 2 AS q2 FROM pcachetest" +== 022 +-- truncate_limit: 100 +EXECUTE vprep +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE vprep" +== 023 +-- truncate_limit: 100 +-- Check basic SPI plan invalidation + +create function cache_test(int) returns int as $$ +declare total int; +begin + create temp table t1(f1 int); + insert into t1 values($1); + insert into t1 values(11); + insert into t1 values(12); + insert into t1 values(13); + select sum(f1) into total from t1; + drop table t1; + return total; +end +$$ language plpgsql +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION cache_test(int) RETURNS int AS $$\ndeclare total int;\nbegin\n\tcreate temp table t1(..." +== 024 +-- truncate_limit: 100 +select cache_test(1) +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cache_test(1)" +== 025 +-- truncate_limit: 100 +select cache_test(2) +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cache_test(2)" +== 026 +-- truncate_limit: 100 +select cache_test(3) +-- +FUNCTION: name="cache_test" function="cache_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cache_test(3)" +== 027 +-- truncate_limit: 100 +-- Check invalidation of plpgsql "simple expression" + +create temp view v1 as + select 2+2 as f1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v1 AS SELECT 2 + 2 AS f1" +== 028 +-- truncate_limit: 100 +create function cache_test_2() returns int as $$ +begin + return f1 from v1; +end$$ language plpgsql +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION cache_test_2() RETURNS int AS $$\nbegin\n\treturn f1 from v1;\nend$$ LANGUAGE plpgsql" +== 029 +-- truncate_limit: 100 +select cache_test_2() +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cache_test_2()" +== 030 +-- truncate_limit: 100 +create or replace temp view v1 as + select 2+2+4 as f1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v1 AS SELECT (2 + 2) + 4 AS f1" +== 031 +-- truncate_limit: 100 +select cache_test_2() +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cache_test_2()" +== 032 +-- truncate_limit: 100 +create or replace temp view v1 as + select 2+2+4+(select max(unique1) from tenk1) as f1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v1 AS SELECT ((2 + 2) + 4) + (SELECT max(unique1) FROM tenk1) AS f1" +== 033 +-- truncate_limit: 100 +select cache_test_2() +-- +FUNCTION: name="cache_test_2" function="cache_test_2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cache_test_2()" +== 034 +-- truncate_limit: 100 +--- Check that change of search_path is honored when re-using cached plan + +create schema s1 + create table abc (f1 int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA s1 CREATE TABLE abc (f1 int)" +== 035 +-- truncate_limit: 100 +create schema s2 + create table abc (f1 int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA s2 CREATE TABLE abc (f1 int)" +== 036 +-- truncate_limit: 100 +insert into s1.abc values(123) +-- +TABLE: name="s1.abc" schema="s1" table="abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO s1.abc VALUES (123)" +== 037 +-- truncate_limit: 100 +insert into s2.abc values(456) +-- +TABLE: name="s2.abc" schema="s2" table="abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO s2.abc VALUES (456)" +== 038 +-- truncate_limit: 100 +set search_path = s1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO s1" +== 039 +-- truncate_limit: 100 +prepare p1 as select f1 from abc +-- +TABLE: name="abc" schema="" table="abc" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE p1 AS SELECT f1 FROM abc" +== 040 +-- truncate_limit: 100 +execute p1 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p1" +== 041 +-- truncate_limit: 100 +set search_path = s2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO s2" +== 042 +-- truncate_limit: 100 +select f1 from abc +-- +TABLE: name="abc" schema="" table="abc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM abc" +== 043 +-- truncate_limit: 100 +execute p1 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p1" +== 044 +-- truncate_limit: 100 +alter table s1.abc add column f2 float8 +-- +TABLE: name="s1.abc" schema="s1" table="abc" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE s1.abc ADD COLUMN f2 float8" +== 045 +-- truncate_limit: 100 +-- force replan + +execute p1 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p1" +== 046 +-- truncate_limit: 100 +drop schema s1 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA s1 CASCADE" +== 047 +-- truncate_limit: 100 +drop schema s2 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA s2 CASCADE" +== 048 +-- truncate_limit: 100 +reset search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 049 +-- truncate_limit: 100 +-- Check that invalidation deals with regclass constants + +create temp sequence seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE seq" +== 050 +-- truncate_limit: 100 +prepare p2 as select nextval('seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE p2 AS SELECT nextval('seq')" +== 051 +-- truncate_limit: 100 +execute p2 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p2" +== 052 +-- truncate_limit: 100 +drop sequence seq +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE seq" +== 053 +-- truncate_limit: 100 +create temp sequence seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE seq" +== 054 +-- truncate_limit: 100 +execute p2 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p2" +== 055 +-- truncate_limit: 100 +-- Check DDL via SPI, immediately followed by SPI plan re-use +-- (bug in original coding) + +create function cachebug() returns void as $$ +declare r int; +begin + drop table if exists temptable cascade; + create temp table temptable as select * from generate_series(1,3) as f1; + create temp view vv as select * from temptable; + for r in select * from vv loop + raise notice '%', r; + end loop; +end$$ language plpgsql +-- +FUNCTION: name="cachebug" function="cachebug" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION cachebug() RETURNS void AS $$\ndeclare r int;\nbegin\n drop table if exists temptab..." +== 056 +-- truncate_limit: 100 +select cachebug() +-- +FUNCTION: name="cachebug" function="cachebug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cachebug()" +== 057 +-- truncate_limit: 100 +select cachebug() +-- +FUNCTION: name="cachebug" function="cachebug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cachebug()" +== 058 +-- truncate_limit: 100 +-- Check that addition or removal of any partition is correctly dealt with by +-- default partition table when it is being used in prepared statement. +create table pc_list_parted (a int) partition by list(a) +-- +TABLE: name="pc_list_parted" schema="" table="pc_list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pc_list_parted (a int) PARTITION BY LIST (a)" +== 059 +-- truncate_limit: 100 +create table pc_list_part_null partition of pc_list_parted for values in (null) +-- +TABLE: name="pc_list_part_null" schema="" table="pc_list_part_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pc_list_part_null PARTITION OF pc_list_parted FOR VALUES IN (NULL)" +== 060 +-- truncate_limit: 100 +create table pc_list_part_1 partition of pc_list_parted for values in (1) +-- +TABLE: name="pc_list_part_1" schema="" table="pc_list_part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pc_list_part_1 PARTITION OF pc_list_parted FOR VALUES IN (1)" +== 061 +-- truncate_limit: 100 +create table pc_list_part_def partition of pc_list_parted default +-- +TABLE: name="pc_list_part_def" schema="" table="pc_list_part_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pc_list_part_def PARTITION OF pc_list_parted DEFAULT" +== 062 +-- truncate_limit: 100 +prepare pstmt_def_insert (int) as insert into pc_list_part_def values($1) +-- +TABLE: name="pc_list_part_def" schema="" table="pc_list_part_def" ctx=DML +STMT: PrepareStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "PREPARE pstmt_def_insert(int) AS INSERT INTO pc_list_part_def VALUES ($1)" +== 063 +-- truncate_limit: 100 +-- should fail +execute pstmt_def_insert(null) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE pstmt_def_insert(NULL)" +== 064 +-- truncate_limit: 100 +execute pstmt_def_insert(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE pstmt_def_insert(1)" +== 065 +-- truncate_limit: 100 +create table pc_list_part_2 partition of pc_list_parted for values in (2) +-- +TABLE: name="pc_list_part_2" schema="" table="pc_list_part_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pc_list_part_2 PARTITION OF pc_list_parted FOR VALUES IN (2)" +== 066 +-- truncate_limit: 100 +execute pstmt_def_insert(2) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE pstmt_def_insert(2)" +== 067 +-- truncate_limit: 100 +alter table pc_list_parted detach partition pc_list_part_null +-- +TABLE: name="pc_list_parted" schema="" table="pc_list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pc_list_parted DETACH PARTITION pc_list_part_null" +== 068 +-- truncate_limit: 100 +-- should be ok +execute pstmt_def_insert(null) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE pstmt_def_insert(NULL)" +== 069 +-- truncate_limit: 100 +drop table pc_list_part_1 +-- +TABLE: name="pc_list_part_1" schema="" table="pc_list_part_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pc_list_part_1" +== 070 +-- truncate_limit: 100 +-- should be ok +execute pstmt_def_insert(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE pstmt_def_insert(1)" +== 071 +-- truncate_limit: 100 +drop table pc_list_parted, pc_list_part_null +-- +TABLE: name="pc_list_parted" schema="" table="pc_list_parted" ctx=DDL +TABLE: name="pc_list_part_null" schema="" table="pc_list_part_null" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pc_list_parted, pc_list_part_null" +== 072 +-- truncate_limit: 100 +deallocate pstmt_def_insert +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE pstmt_def_insert" +== 073 +-- truncate_limit: 100 +-- Test plan_cache_mode + +create table test_mode (a int) +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_mode (a int)" +== 074 +-- truncate_limit: 100 +insert into test_mode select 1 from generate_series(1,1000) union all select 2 +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_mode SELECT 1 FROM generate_series(1, 1000) UNION ALL SELECT 2" +== 075 +-- truncate_limit: 100 +create index on test_mode (a) +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_mode USING btree (a)" +== 076 +-- truncate_limit: 100 +analyze test_mode +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE test_mode" +== 077 +-- truncate_limit: 100 +prepare test_mode_pp (int) as select count(*) from test_mode where a = $1 +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE test_mode_pp(int) AS SELECT count(*) FROM test_mode WHERE a = $1" +== 078 +-- truncate_limit: 100 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT name, generic_plans, custom_plans FROM pg_prepared_statements WHERE name = 'test_mode_pp'" +== 079 +-- truncate_limit: 100 +-- up to 5 executions, custom plan is used +set plan_cache_mode to auto +-- +STMT: VariableSetStmt +TRUNCATED: "SET plan_cache_mode TO auto" +== 080 +-- truncate_limit: 100 +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE test_mode_pp(2)" +== 081 +-- truncate_limit: 100 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT name, generic_plans, custom_plans FROM pg_prepared_statements WHERE name = 'test_mode_pp'" +== 082 +-- truncate_limit: 100 +-- force generic plan +set plan_cache_mode to force_generic_plan +-- +STMT: VariableSetStmt +TRUNCATED: "SET plan_cache_mode TO force_generic_plan" +== 083 +-- truncate_limit: 100 +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE test_mode_pp(2)" +== 084 +-- truncate_limit: 100 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT name, generic_plans, custom_plans FROM pg_prepared_statements WHERE name = 'test_mode_pp'" +== 085 +-- truncate_limit: 100 +-- get to generic plan by 5 executions +set plan_cache_mode to auto +-- +STMT: VariableSetStmt +TRUNCATED: "SET plan_cache_mode TO auto" +== 086 +-- truncate_limit: 100 +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE test_mode_pp(1)" +== 087 +-- truncate_limit: 100 +-- 1x +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE test_mode_pp(1)" +== 088 +-- truncate_limit: 100 +-- 2x +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE test_mode_pp(1)" +== 089 +-- truncate_limit: 100 +-- 3x +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE test_mode_pp(1)" +== 090 +-- truncate_limit: 100 +-- 4x +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT name, generic_plans, custom_plans FROM pg_prepared_statements WHERE name = 'test_mode_pp'" +== 091 +-- truncate_limit: 100 +execute test_mode_pp(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE test_mode_pp(1)" +== 092 +-- truncate_limit: 100 +-- 5x +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT name, generic_plans, custom_plans FROM pg_prepared_statements WHERE name = 'test_mode_pp'" +== 093 +-- truncate_limit: 100 +-- we should now get a really bad plan +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE test_mode_pp(2)" +== 094 +-- truncate_limit: 100 +-- but we can force a custom plan +set plan_cache_mode to force_custom_plan +-- +STMT: VariableSetStmt +TRUNCATED: "SET plan_cache_mode TO force_custom_plan" +== 095 +-- truncate_limit: 100 +explain (costs off) execute test_mode_pp(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE test_mode_pp(2)" +== 096 +-- truncate_limit: 100 +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp' +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT name, generic_plans, custom_plans FROM pg_prepared_statements WHERE name = 'test_mode_pp'" +== 097 +-- truncate_limit: 100 +drop table test_mode +-- +TABLE: name="test_mode" schema="" table="test_mode" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_mode" diff --git a/parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json b/parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json new file mode 100644 index 0000000..35fd146 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json @@ -0,0 +1,945 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/plpgsql.test b/parser/testdata/summary_truncate/postgres_regress/plpgsql.test new file mode 100644 index 0000000..b3f6193 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/plpgsql.test @@ -0,0 +1,9894 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PLPGSQL +|-- +-- Scenario: +|-- +-- A building with a modern TP cable installation where any +-- of the wall connectors can be used to plug in phones, +-- ethernet interfaces or local office hubs. The backside +-- of the wall connectors is wired to one of several patch- +-- fields in the building. +|-- +-- In the patchfields, there are hubs and all the slots +-- representing the wall connectors. In addition there are +-- slots that can represent a phone line from the central +-- phone system. +|-- +-- Triggers ensure consistency of the patching information. +|-- +-- Functions are used to build up powerful views that let +-- you look behind the wall when looking at a patchfield +-- or into a room. +|-- + + +create table Room ( + roomno char(8), + comment text +) +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE room (roomno char(8), comment text)" +== 002 +-- truncate_limit: 100 +create unique index Room_rno on Room using btree (roomno bpchar_ops) +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX room_rno ON room USING btree (roomno bpchar_ops)" +== 003 +-- truncate_limit: 100 +create table WSlot ( + slotname char(20), + roomno char(8), + slotlink char(20), + backlink char(20) +) +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE wslot (slotname char(20), roomno char(8), slotlink char(20), backlink char(20))" +== 004 +-- truncate_limit: 100 +create unique index WSlot_name on WSlot using btree (slotname bpchar_ops) +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX wslot_name ON wslot USING btree (slotname bpchar_ops)" +== 005 +-- truncate_limit: 100 +create table PField ( + name text, + comment text +) +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pfield (name text, comment text)" +== 006 +-- truncate_limit: 100 +create unique index PField_name on PField using btree (name text_ops) +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX pfield_name ON pfield USING btree (name text_ops)" +== 007 +-- truncate_limit: 100 +create table PSlot ( + slotname char(20), + pfname text, + slotlink char(20), + backlink char(20) +) +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pslot (slotname char(20), pfname text, slotlink char(20), backlink char(20))" +== 008 +-- truncate_limit: 100 +create unique index PSlot_name on PSlot using btree (slotname bpchar_ops) +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX pslot_name ON pslot USING btree (slotname bpchar_ops)" +== 009 +-- truncate_limit: 100 +create table PLine ( + slotname char(20), + phonenumber char(20), + comment text, + backlink char(20) +) +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pline (slotname char(20), phonenumber char(20), comment text, backlink char(20))" +== 010 +-- truncate_limit: 100 +create unique index PLine_name on PLine using btree (slotname bpchar_ops) +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX pline_name ON pline USING btree (slotname bpchar_ops)" +== 011 +-- truncate_limit: 100 +create table Hub ( + name char(14), + comment text, + nslots integer +) +-- +TABLE: name="hub" schema="" table="hub" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hub (name char(14), comment text, nslots int)" +== 012 +-- truncate_limit: 100 +create unique index Hub_name on Hub using btree (name bpchar_ops) +-- +TABLE: name="hub" schema="" table="hub" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX hub_name ON hub USING btree (name bpchar_ops)" +== 013 +-- truncate_limit: 100 +create table HSlot ( + slotname char(20), + hubname char(14), + slotno integer, + slotlink char(20) +) +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hslot (slotname char(20), hubname char(14), slotno int, slotlink char(20))" +== 014 +-- truncate_limit: 100 +create unique index HSlot_name on HSlot using btree (slotname bpchar_ops) +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX hslot_name ON hslot USING btree (slotname bpchar_ops)" +== 015 +-- truncate_limit: 100 +create index HSlot_hubname on HSlot using btree (hubname bpchar_ops) +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hslot_hubname ON hslot USING btree (hubname bpchar_ops)" +== 016 +-- truncate_limit: 100 +create table System ( + name text, + comment text +) +-- +TABLE: name="system" schema="" table="system" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE system (name text, comment text)" +== 017 +-- truncate_limit: 100 +create unique index System_name on System using btree (name text_ops) +-- +TABLE: name="system" schema="" table="system" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX system_name ON system USING btree (name text_ops)" +== 018 +-- truncate_limit: 100 +create table IFace ( + slotname char(20), + sysname text, + ifname text, + slotlink char(20) +) +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iface (slotname char(20), sysname text, ifname text, slotlink char(20))" +== 019 +-- truncate_limit: 100 +create unique index IFace_name on IFace using btree (slotname bpchar_ops) +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX iface_name ON iface USING btree (slotname bpchar_ops)" +== 020 +-- truncate_limit: 100 +create table PHone ( + slotname char(20), + comment text, + slotlink char(20) +) +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE phone (slotname char(20), comment text, slotlink char(20))" +== 021 +-- truncate_limit: 100 +create unique index PHone_name on PHone using btree (slotname bpchar_ops) +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX phone_name ON phone USING btree (slotname bpchar_ops)" +== 022 +-- truncate_limit: 100 +-- ************************************************************ +-- * +-- * Trigger procedures and functions for the patchfield +-- * test of PL/pgSQL +-- * +-- ************************************************************ + + +-- ************************************************************ +-- * AFTER UPDATE on Room +-- * - If room no changes let wall slots follow +-- ************************************************************ +create function tg_room_au() returns trigger as ' +begin + if new.roomno != old.roomno then + update WSlot set roomno = new.roomno where roomno = old.roomno; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_room_au" function="tg_room_au" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_room_au() RETURNS trigger AS $$\nbegin\n if new.roomno != old.roomno then\n ..." +== 023 +-- truncate_limit: 100 +create trigger tg_room_au after update + on Room for each row execute procedure tg_room_au() +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_room_au AFTER UPDATE ON room FOR EACH ROW EXECUTE FUNCTION tg_room_au()" +== 024 +-- truncate_limit: 100 +-- ************************************************************ +-- * AFTER DELETE on Room +-- * - delete wall slots in this room +-- ************************************************************ +create function tg_room_ad() returns trigger as ' +begin + delete from WSlot where roomno = old.roomno; + return old; +end; +' language plpgsql +-- +FUNCTION: name="tg_room_ad" function="tg_room_ad" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_room_ad() RETURNS trigger AS $$\nbegin\n delete from WSlot where roomno = old..." +== 025 +-- truncate_limit: 100 +create trigger tg_room_ad after delete + on Room for each row execute procedure tg_room_ad() +-- +TABLE: name="room" schema="" table="room" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_room_ad AFTER DELETE ON room FOR EACH ROW EXECUTE FUNCTION tg_room_ad()" +== 026 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on WSlot +-- * - Check that room exists +-- ************************************************************ +create function tg_wslot_biu() returns trigger as $$ +begin + if count(*) = 0 from Room where roomno = new.roomno then + raise exception 'Room % does not exist', new.roomno; + end if; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="tg_wslot_biu" function="tg_wslot_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_wslot_biu() RETURNS trigger AS $$\nbegin\n if count(*) = 0 from Room where ro..." +== 027 +-- truncate_limit: 100 +create trigger tg_wslot_biu before insert or update + on WSlot for each row execute procedure tg_wslot_biu() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_wslot_biu BEFORE INSERT OR UPDATE ON wslot FOR EACH ROW EXECUTE FUNCTION tg_wsl..." +== 028 +-- truncate_limit: 100 +-- ************************************************************ +-- * AFTER UPDATE on PField +-- * - Let PSlots of this field follow +-- ************************************************************ +create function tg_pfield_au() returns trigger as ' +begin + if new.name != old.name then + update PSlot set pfname = new.name where pfname = old.name; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_pfield_au" function="tg_pfield_au" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_pfield_au() RETURNS trigger AS $$\nbegin\n if new.name != old.name then\n ..." +== 029 +-- truncate_limit: 100 +create trigger tg_pfield_au after update + on PField for each row execute procedure tg_pfield_au() +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_pfield_au AFTER UPDATE ON pfield FOR EACH ROW EXECUTE FUNCTION tg_pfield_au()" +== 030 +-- truncate_limit: 100 +-- ************************************************************ +-- * AFTER DELETE on PField +-- * - Remove all slots of this patchfield +-- ************************************************************ +create function tg_pfield_ad() returns trigger as ' +begin + delete from PSlot where pfname = old.name; + return old; +end; +' language plpgsql +-- +FUNCTION: name="tg_pfield_ad" function="tg_pfield_ad" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_pfield_ad() RETURNS trigger AS $$\nbegin\n delete from PSlot where pfname = o..." +== 031 +-- truncate_limit: 100 +create trigger tg_pfield_ad after delete + on PField for each row execute procedure tg_pfield_ad() +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_pfield_ad AFTER DELETE ON pfield FOR EACH ROW EXECUTE FUNCTION tg_pfield_ad()" +== 032 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on PSlot +-- * - Ensure that our patchfield does exist +-- ************************************************************ +create function tg_pslot_biu() returns trigger as $proc$ +declare + pfrec record; + ps alias for new; +begin + select into pfrec * from PField where name = ps.pfname; + if not found then + raise exception $$Patchfield "%" does not exist$$, ps.pfname; + end if; + return ps; +end; +$proc$ language plpgsql +-- +FUNCTION: name="tg_pslot_biu" function="tg_pslot_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_pslot_biu() RETURNS trigger AS '\ndeclare\n pfrec\trecord;\n ps ali..." +== 033 +-- truncate_limit: 100 +create trigger tg_pslot_biu before insert or update + on PSlot for each row execute procedure tg_pslot_biu() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_pslot_biu BEFORE INSERT OR UPDATE ON pslot FOR EACH ROW EXECUTE FUNCTION tg_psl..." +== 034 +-- truncate_limit: 100 +-- ************************************************************ +-- * AFTER UPDATE on System +-- * - If system name changes let interfaces follow +-- ************************************************************ +create function tg_system_au() returns trigger as ' +begin + if new.name != old.name then + update IFace set sysname = new.name where sysname = old.name; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_system_au" function="tg_system_au" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_system_au() RETURNS trigger AS $$\nbegin\n if new.name != old.name then\n ..." +== 035 +-- truncate_limit: 100 +create trigger tg_system_au after update + on System for each row execute procedure tg_system_au() +-- +TABLE: name="system" schema="" table="system" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_system_au AFTER UPDATE ON system FOR EACH ROW EXECUTE FUNCTION tg_system_au()" +== 036 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on IFace +-- * - set the slotname to IF.sysname.ifname +-- ************************************************************ +create function tg_iface_biu() returns trigger as $$ +declare + sname text; + sysrec record; +begin + select into sysrec * from system where name = new.sysname; + if not found then + raise exception $q$system "%" does not exist$q$, new.sysname; + end if; + sname := 'IF.' || new.sysname; + sname := sname || '.'; + sname := sname || new.ifname; + if length(sname) > 20 then + raise exception 'IFace slotname "%" too long (20 char max)', sname; + end if; + new.slotname := sname; + return new; +end; +$$ language plpgsql +-- +FUNCTION: name="tg_iface_biu" function="tg_iface_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_iface_biu() RETURNS trigger AS $$\ndeclare\n sname\ttext;\n sysrec\trecord;\nb..." +== 037 +-- truncate_limit: 100 +create trigger tg_iface_biu before insert or update + on IFace for each row execute procedure tg_iface_biu() +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_iface_biu BEFORE INSERT OR UPDATE ON iface FOR EACH ROW EXECUTE FUNCTION tg_ifa..." +== 038 +-- truncate_limit: 100 +-- ************************************************************ +-- * AFTER INSERT or UPDATE or DELETE on Hub +-- * - insert/delete/rename slots as required +-- ************************************************************ +create function tg_hub_a() returns trigger as ' +declare + hname text; + dummy integer; +begin + if tg_op = ''INSERT'' then + dummy := tg_hub_adjustslots(new.name, 0, new.nslots); + return new; + end if; + if tg_op = ''UPDATE'' then + if new.name != old.name then + update HSlot set hubname = new.name where hubname = old.name; + end if; + dummy := tg_hub_adjustslots(new.name, old.nslots, new.nslots); + return new; + end if; + if tg_op = ''DELETE'' then + dummy := tg_hub_adjustslots(old.name, old.nslots, 0); + return old; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_hub_a" function="tg_hub_a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_hub_a() RETURNS trigger AS $$\ndeclare\n hname\ttext;\n dummy\tinteger;\nbegin..." +== 039 +-- truncate_limit: 100 +create trigger tg_hub_a after insert or update or delete + on Hub for each row execute procedure tg_hub_a() +-- +TABLE: name="hub" schema="" table="hub" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_hub_a AFTER INSERT OR DELETE OR UPDATE ON hub FOR EACH ROW EXECUTE FUNCTION tg_..." +== 040 +-- truncate_limit: 100 +-- ************************************************************ +-- * Support function to add/remove slots of Hub +-- ************************************************************ +create function tg_hub_adjustslots(hname bpchar, + oldnslots integer, + newnslots integer) +returns integer as ' +begin + if newnslots = oldnslots then + return 0; + end if; + if newnslots < oldnslots then + delete from HSlot where hubname = hname and slotno > newnslots; + return 0; + end if; + for i in oldnslots + 1 .. newnslots loop + insert into HSlot (slotname, hubname, slotno, slotlink) + values (''HS.dummy'', hname, i, ''''); + end loop; + return 0; +end +' language plpgsql +-- +FUNCTION: name="tg_hub_adjustslots" function="tg_hub_adjustslots" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_hub_adjustslots(hname bpchar, oldnslots int, newnslots int) RETURNS int AS $$\n..." +== 041 +-- truncate_limit: 100 +-- Test comments +COMMENT ON FUNCTION tg_hub_adjustslots_wrong(bpchar, integer, integer) IS 'function with args' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON FUNCTION tg_hub_adjustslots_wrong(bpchar, int, int) IS 'function with args'" +== 042 +-- truncate_limit: 100 +COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS 'function with args' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, int, int) IS 'function with args'" +== 043 +-- truncate_limit: 100 +COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, int, int) IS NULL" +== 044 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on HSlot +-- * - prevent from manual manipulation +-- * - set the slotname to HS.hubname.slotno +-- ************************************************************ +create function tg_hslot_biu() returns trigger as ' +declare + sname text; + xname HSlot.slotname%TYPE; + hubrec record; +begin + select into hubrec * from Hub where name = new.hubname; + if not found then + raise exception ''no manual manipulation of HSlot''; + end if; + if new.slotno < 1 or new.slotno > hubrec.nslots then + raise exception ''no manual manipulation of HSlot''; + end if; + if tg_op = ''UPDATE'' and new.hubname != old.hubname then + if count(*) > 0 from Hub where name = old.hubname then + raise exception ''no manual manipulation of HSlot''; + end if; + end if; + sname := ''HS.'' || trim(new.hubname); + sname := sname || ''.''; + sname := sname || new.slotno::text; + if length(sname) > 20 then + raise exception ''HSlot slotname "%" too long (20 char max)'', sname; + end if; + new.slotname := sname; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_hslot_biu" function="tg_hslot_biu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_hslot_biu() RETURNS trigger AS $$\ndeclare\n sname\ttext;\n xname\tHSlot.slot..." +== 045 +-- truncate_limit: 100 +create trigger tg_hslot_biu before insert or update + on HSlot for each row execute procedure tg_hslot_biu() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_hslot_biu BEFORE INSERT OR UPDATE ON hslot FOR EACH ROW EXECUTE FUNCTION tg_hsl..." +== 046 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE DELETE on HSlot +-- * - prevent from manual manipulation +-- ************************************************************ +create function tg_hslot_bd() returns trigger as ' +declare + hubrec record; +begin + select into hubrec * from Hub where name = old.hubname; + if not found then + return old; + end if; + if old.slotno > hubrec.nslots then + return old; + end if; + raise exception ''no manual manipulation of HSlot''; +end; +' language plpgsql +-- +FUNCTION: name="tg_hslot_bd" function="tg_hslot_bd" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_hslot_bd() RETURNS trigger AS $$\ndeclare\n hubrec\trecord;\nbegin\n select i..." +== 047 +-- truncate_limit: 100 +create trigger tg_hslot_bd before delete + on HSlot for each row execute procedure tg_hslot_bd() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_hslot_bd BEFORE DELETE ON hslot FOR EACH ROW EXECUTE FUNCTION tg_hslot_bd()" +== 048 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE INSERT on all slots +-- * - Check name prefix +-- ************************************************************ +create function tg_chkslotname() returns trigger as ' +begin + if substr(new.slotname, 1, 2) != tg_argv[0] then + raise exception ''slotname must begin with %'', tg_argv[0]; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_chkslotname" function="tg_chkslotname" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_chkslotname() RETURNS trigger AS $$\nbegin\n if substr(new.slotname, 1, 2) !=..." +== 049 +-- truncate_limit: 100 +create trigger tg_chkslotname before insert + on PSlot for each row execute procedure tg_chkslotname('PS') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotname BEFORE INSERT ON pslot FOR EACH ROW EXECUTE FUNCTION tg_chkslotname..." +== 050 +-- truncate_limit: 100 +create trigger tg_chkslotname before insert + on WSlot for each row execute procedure tg_chkslotname('WS') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotname BEFORE INSERT ON wslot FOR EACH ROW EXECUTE FUNCTION tg_chkslotname..." +== 051 +-- truncate_limit: 100 +create trigger tg_chkslotname before insert + on PLine for each row execute procedure tg_chkslotname('PL') +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotname BEFORE INSERT ON pline FOR EACH ROW EXECUTE FUNCTION tg_chkslotname..." +== 052 +-- truncate_limit: 100 +create trigger tg_chkslotname before insert + on IFace for each row execute procedure tg_chkslotname('IF') +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotname BEFORE INSERT ON iface FOR EACH ROW EXECUTE FUNCTION tg_chkslotname..." +== 053 +-- truncate_limit: 100 +create trigger tg_chkslotname before insert + on PHone for each row execute procedure tg_chkslotname('PH') +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotname BEFORE INSERT ON phone FOR EACH ROW EXECUTE FUNCTION tg_chkslotname..." +== 054 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on all slots with slotlink +-- * - Set slotlink to empty string if NULL value given +-- ************************************************************ +create function tg_chkslotlink() returns trigger as ' +begin + if new.slotlink isnull then + new.slotlink := ''''; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_chkslotlink" function="tg_chkslotlink" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_chkslotlink() RETURNS trigger AS $$\nbegin\n if new.slotlink isnull then\n ..." +== 055 +-- truncate_limit: 100 +create trigger tg_chkslotlink before insert or update + on PSlot for each row execute procedure tg_chkslotlink() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotlink BEFORE INSERT OR UPDATE ON pslot FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 056 +-- truncate_limit: 100 +create trigger tg_chkslotlink before insert or update + on WSlot for each row execute procedure tg_chkslotlink() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotlink BEFORE INSERT OR UPDATE ON wslot FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 057 +-- truncate_limit: 100 +create trigger tg_chkslotlink before insert or update + on IFace for each row execute procedure tg_chkslotlink() +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotlink BEFORE INSERT OR UPDATE ON iface FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 058 +-- truncate_limit: 100 +create trigger tg_chkslotlink before insert or update + on HSlot for each row execute procedure tg_chkslotlink() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotlink BEFORE INSERT OR UPDATE ON hslot FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 059 +-- truncate_limit: 100 +create trigger tg_chkslotlink before insert or update + on PHone for each row execute procedure tg_chkslotlink() +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkslotlink BEFORE INSERT OR UPDATE ON phone FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 060 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE INSERT or UPDATE on all slots with backlink +-- * - Set backlink to empty string if NULL value given +-- ************************************************************ +create function tg_chkbacklink() returns trigger as ' +begin + if new.backlink isnull then + new.backlink := ''''; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_chkbacklink" function="tg_chkbacklink" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_chkbacklink() RETURNS trigger AS $$\nbegin\n if new.backlink isnull then\n ..." +== 061 +-- truncate_limit: 100 +create trigger tg_chkbacklink before insert or update + on PSlot for each row execute procedure tg_chkbacklink() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkbacklink BEFORE INSERT OR UPDATE ON pslot FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 062 +-- truncate_limit: 100 +create trigger tg_chkbacklink before insert or update + on WSlot for each row execute procedure tg_chkbacklink() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkbacklink BEFORE INSERT OR UPDATE ON wslot FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 063 +-- truncate_limit: 100 +create trigger tg_chkbacklink before insert or update + on PLine for each row execute procedure tg_chkbacklink() +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_chkbacklink BEFORE INSERT OR UPDATE ON pline FOR EACH ROW EXECUTE FUNCTION tg_c..." +== 064 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE UPDATE on PSlot +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_pslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PSlot where slotname = old.slotname; + insert into PSlot ( + slotname, + pfname, + slotlink, + backlink + ) values ( + new.slotname, + new.pfname, + new.slotlink, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_pslot_bu" function="tg_pslot_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_pslot_bu() RETURNS trigger AS $$\nbegin\n if new.slotname != old.slotname the..." +== 065 +-- truncate_limit: 100 +create trigger tg_pslot_bu before update + on PSlot for each row execute procedure tg_pslot_bu() +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_pslot_bu BEFORE UPDATE ON pslot FOR EACH ROW EXECUTE FUNCTION tg_pslot_bu()" +== 066 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE UPDATE on WSlot +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_wslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from WSlot where slotname = old.slotname; + insert into WSlot ( + slotname, + roomno, + slotlink, + backlink + ) values ( + new.slotname, + new.roomno, + new.slotlink, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_wslot_bu" function="tg_wslot_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_wslot_bu() RETURNS trigger AS $$\nbegin\n if new.slotname != old.slotname the..." +== 067 +-- truncate_limit: 100 +create trigger tg_wslot_bu before update + on WSlot for each row execute procedure tg_Wslot_bu() +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_wslot_bu BEFORE UPDATE ON wslot FOR EACH ROW EXECUTE FUNCTION tg_wslot_bu()" +== 068 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE UPDATE on PLine +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_pline_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PLine where slotname = old.slotname; + insert into PLine ( + slotname, + phonenumber, + comment, + backlink + ) values ( + new.slotname, + new.phonenumber, + new.comment, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_pline_bu" function="tg_pline_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_pline_bu() RETURNS trigger AS $$\nbegin\n if new.slotname != old.slotname the..." +== 069 +-- truncate_limit: 100 +create trigger tg_pline_bu before update + on PLine for each row execute procedure tg_pline_bu() +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_pline_bu BEFORE UPDATE ON pline FOR EACH ROW EXECUTE FUNCTION tg_pline_bu()" +== 070 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE UPDATE on IFace +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_iface_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from IFace where slotname = old.slotname; + insert into IFace ( + slotname, + sysname, + ifname, + slotlink + ) values ( + new.slotname, + new.sysname, + new.ifname, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_iface_bu" function="tg_iface_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_iface_bu() RETURNS trigger AS $$\nbegin\n if new.slotname != old.slotname the..." +== 071 +-- truncate_limit: 100 +create trigger tg_iface_bu before update + on IFace for each row execute procedure tg_iface_bu() +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_iface_bu BEFORE UPDATE ON iface FOR EACH ROW EXECUTE FUNCTION tg_iface_bu()" +== 072 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE UPDATE on HSlot +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_hslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname or new.hubname != old.hubname then + delete from HSlot where slotname = old.slotname; + insert into HSlot ( + slotname, + hubname, + slotno, + slotlink + ) values ( + new.slotname, + new.hubname, + new.slotno, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_hslot_bu" function="tg_hslot_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_hslot_bu() RETURNS trigger AS $$\nbegin\n if new.slotname != old.slotname or ..." +== 073 +-- truncate_limit: 100 +create trigger tg_hslot_bu before update + on HSlot for each row execute procedure tg_hslot_bu() +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_hslot_bu BEFORE UPDATE ON hslot FOR EACH ROW EXECUTE FUNCTION tg_hslot_bu()" +== 074 +-- truncate_limit: 100 +-- ************************************************************ +-- * BEFORE UPDATE on PHone +-- * - do delete/insert instead of update if name changes +-- ************************************************************ +create function tg_phone_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PHone where slotname = old.slotname; + insert into PHone ( + slotname, + comment, + slotlink + ) values ( + new.slotname, + new.comment, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql +-- +FUNCTION: name="tg_phone_bu" function="tg_phone_bu" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_phone_bu() RETURNS trigger AS $$\nbegin\n if new.slotname != old.slotname the..." +== 075 +-- truncate_limit: 100 +create trigger tg_phone_bu before update + on PHone for each row execute procedure tg_phone_bu() +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_phone_bu BEFORE UPDATE ON phone FOR EACH ROW EXECUTE FUNCTION tg_phone_bu()" +== 076 +-- truncate_limit: 100 +-- ************************************************************ +-- * AFTER INSERT or UPDATE or DELETE on slot with backlink +-- * - Ensure that the opponent correctly points back to us +-- ************************************************************ +create function tg_backlink_a() returns trigger as ' +declare + dummy integer; +begin + if tg_op = ''INSERT'' then + if new.backlink != '''' then + dummy := tg_backlink_set(new.backlink, new.slotname); + end if; + return new; + end if; + if tg_op = ''UPDATE'' then + if new.backlink != old.backlink then + if old.backlink != '''' then + dummy := tg_backlink_unset(old.backlink, old.slotname); + end if; + if new.backlink != '''' then + dummy := tg_backlink_set(new.backlink, new.slotname); + end if; + else + if new.slotname != old.slotname and new.backlink != '''' then + dummy := tg_slotlink_set(new.backlink, new.slotname); + end if; + end if; + return new; + end if; + if tg_op = ''DELETE'' then + if old.backlink != '''' then + dummy := tg_backlink_unset(old.backlink, old.slotname); + end if; + return old; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_backlink_a" function="tg_backlink_a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_backlink_a() RETURNS trigger AS $$\ndeclare\n dummy\tinteger;\nbegin\n if tg_..." +== 077 +-- truncate_limit: 100 +create trigger tg_backlink_a after insert or update or delete + on PSlot for each row execute procedure tg_backlink_a('PS') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_backlink_a AFTER INSERT OR DELETE OR UPDATE ON pslot FOR EACH ROW EXECUTE FUNCT..." +== 078 +-- truncate_limit: 100 +create trigger tg_backlink_a after insert or update or delete + on WSlot for each row execute procedure tg_backlink_a('WS') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_backlink_a AFTER INSERT OR DELETE OR UPDATE ON wslot FOR EACH ROW EXECUTE FUNCT..." +== 079 +-- truncate_limit: 100 +create trigger tg_backlink_a after insert or update or delete + on PLine for each row execute procedure tg_backlink_a('PL') +-- +TABLE: name="pline" schema="" table="pline" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_backlink_a AFTER INSERT OR DELETE OR UPDATE ON pline FOR EACH ROW EXECUTE FUNCT..." +== 080 +-- truncate_limit: 100 +-- ************************************************************ +-- * Support function to set the opponents backlink field +-- * if it does not already point to the requested slot +-- ************************************************************ +create function tg_backlink_set(myname bpchar, blname bpchar) +returns integer as ' +declare + mytype char(2); + link char(4); + rec record; +begin + mytype := substr(myname, 1, 2); + link := mytype || substr(blname, 1, 2); + if link = ''PLPL'' then + raise exception + ''backlink between two phone lines does not make sense''; + end if; + if link in (''PLWS'', ''WSPL'') then + raise exception + ''direct link of phone line to wall slot not permitted''; + end if; + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update PSlot set backlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update WSlot set backlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PL'' then + select into rec * from PLine where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update PLine set backlink = blname where slotname = myname; + end if; + return 0; + end if; + raise exception ''illegal backlink beginning with %'', mytype; +end; +' language plpgsql +-- +FUNCTION: name="tg_backlink_set" function="tg_backlink_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_backlink_set(myname bpchar, blname bpchar) RETURNS int AS $$\ndeclare\n mytyp..." +== 081 +-- truncate_limit: 100 +-- ************************************************************ +-- * Support function to clear out the backlink field if +-- * it still points to specific slot +-- ************************************************************ +create function tg_backlink_unset(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + rec record; +begin + mytype := substr(myname, 1, 2); + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update PSlot set backlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update WSlot set backlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PL'' then + select into rec * from PLine where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update PLine set backlink = '''' where slotname = myname; + end if; + return 0; + end if; +end +' language plpgsql +-- +FUNCTION: name="tg_backlink_unset" function="tg_backlink_unset" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_backlink_unset(bpchar, bpchar) RETURNS int AS $$\ndeclare\n myname\talias for ..." +== 082 +-- truncate_limit: 100 +-- ************************************************************ +-- * AFTER INSERT or UPDATE or DELETE on slot with slotlink +-- * - Ensure that the opponent correctly points back to us +-- ************************************************************ +create function tg_slotlink_a() returns trigger as ' +declare + dummy integer; +begin + if tg_op = ''INSERT'' then + if new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + return new; + end if; + if tg_op = ''UPDATE'' then + if new.slotlink != old.slotlink then + if old.slotlink != '''' then + dummy := tg_slotlink_unset(old.slotlink, old.slotname); + end if; + if new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + else + if new.slotname != old.slotname and new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + end if; + return new; + end if; + if tg_op = ''DELETE'' then + if old.slotlink != '''' then + dummy := tg_slotlink_unset(old.slotlink, old.slotname); + end if; + return old; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_slotlink_a" function="tg_slotlink_a" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_slotlink_a() RETURNS trigger AS $$\ndeclare\n dummy\tinteger;\nbegin\n if tg_..." +== 083 +-- truncate_limit: 100 +create trigger tg_slotlink_a after insert or update or delete + on PSlot for each row execute procedure tg_slotlink_a('PS') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_slotlink_a AFTER INSERT OR DELETE OR UPDATE ON pslot FOR EACH ROW EXECUTE FUNCT..." +== 084 +-- truncate_limit: 100 +create trigger tg_slotlink_a after insert or update or delete + on WSlot for each row execute procedure tg_slotlink_a('WS') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_slotlink_a AFTER INSERT OR DELETE OR UPDATE ON wslot FOR EACH ROW EXECUTE FUNCT..." +== 085 +-- truncate_limit: 100 +create trigger tg_slotlink_a after insert or update or delete + on IFace for each row execute procedure tg_slotlink_a('IF') +-- +TABLE: name="iface" schema="" table="iface" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_slotlink_a AFTER INSERT OR DELETE OR UPDATE ON iface FOR EACH ROW EXECUTE FUNCT..." +== 086 +-- truncate_limit: 100 +create trigger tg_slotlink_a after insert or update or delete + on HSlot for each row execute procedure tg_slotlink_a('HS') +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_slotlink_a AFTER INSERT OR DELETE OR UPDATE ON hslot FOR EACH ROW EXECUTE FUNCT..." +== 087 +-- truncate_limit: 100 +create trigger tg_slotlink_a after insert or update or delete + on PHone for each row execute procedure tg_slotlink_a('PH') +-- +TABLE: name="phone" schema="" table="phone" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_slotlink_a AFTER INSERT OR DELETE OR UPDATE ON phone FOR EACH ROW EXECUTE FUNCT..." +== 088 +-- truncate_limit: 100 +-- ************************************************************ +-- * Support function to set the opponents slotlink field +-- * if it does not already point to the requested slot +-- ************************************************************ +create function tg_slotlink_set(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + link char(4); + rec record; +begin + mytype := substr(myname, 1, 2); + link := mytype || substr(blname, 1, 2); + if link = ''PHPH'' then + raise exception + ''slotlink between two phones does not make sense''; + end if; + if link in (''PHHS'', ''HSPH'') then + raise exception + ''link of phone to hub does not make sense''; + end if; + if link in (''PHIF'', ''IFPH'') then + raise exception + ''link of phone to hub does not make sense''; + end if; + if link in (''PSWS'', ''WSPS'') then + raise exception + ''slotlink from patchslot to wallslot not permitted''; + end if; + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update PSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update WSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''IF'' then + select into rec * from IFace where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update IFace set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''HS'' then + select into rec * from HSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update HSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PH'' then + select into rec * from PHone where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update PHone set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + raise exception ''illegal slotlink beginning with %'', mytype; +end; +' language plpgsql +-- +FUNCTION: name="tg_slotlink_set" function="tg_slotlink_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_slotlink_set(bpchar, bpchar) RETURNS int AS $$\ndeclare\n myname\talias for $1..." +== 089 +-- truncate_limit: 100 +-- ************************************************************ +-- * Support function to clear out the slotlink field if +-- * it still points to specific slot +-- ************************************************************ +create function tg_slotlink_unset(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + rec record; +begin + mytype := substr(myname, 1, 2); + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update PSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update WSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''IF'' then + select into rec * from IFace where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update IFace set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''HS'' then + select into rec * from HSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update HSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PH'' then + select into rec * from PHone where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update PHone set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; +end; +' language plpgsql +-- +FUNCTION: name="tg_slotlink_unset" function="tg_slotlink_unset" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tg_slotlink_unset(bpchar, bpchar) RETURNS int AS $$\ndeclare\n myname\talias for ..." +== 090 +-- truncate_limit: 100 +-- ************************************************************ +-- * Describe the backside of a patchfield slot +-- ************************************************************ +create function pslot_backlink_view(bpchar) +returns text as ' +<> +declare + rec record; + bltype char(2); + retval text; +begin + select into rec * from PSlot where slotname = $1; + if not found then + return ''''; + end if; + if rec.backlink = '''' then + return ''-''; + end if; + bltype := substr(rec.backlink, 1, 2); + if bltype = ''PL'' then + declare + rec record; + begin + select into rec * from PLine where slotname = "outer".rec.backlink; + retval := ''Phone line '' || trim(rec.phonenumber); + if rec.comment != '''' then + retval := retval || '' (''; + retval := retval || rec.comment; + retval := retval || '')''; + end if; + return retval; + end; + end if; + if bltype = ''WS'' then + select into rec * from WSlot where slotname = rec.backlink; + retval := trim(rec.slotname) || '' in room ''; + retval := retval || trim(rec.roomno); + retval := retval || '' -> ''; + return retval || wslot_slotlink_view(rec.slotname); + end if; + return rec.backlink; +end; +' language plpgsql +-- +FUNCTION: name="pslot_backlink_view" function="pslot_backlink_view" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pslot_backlink_view(bpchar) RETURNS text AS $$\n<>\ndeclare\n rec\t\trecord;..." +== 091 +-- truncate_limit: 100 +-- ************************************************************ +-- * Describe the front of a patchfield slot +-- ************************************************************ +create function pslot_slotlink_view(bpchar) +returns text as ' +declare + psrec record; + sltype char(2); + retval text; +begin + select into psrec * from PSlot where slotname = $1; + if not found then + return ''''; + end if; + if psrec.slotlink = '''' then + return ''-''; + end if; + sltype := substr(psrec.slotlink, 1, 2); + if sltype = ''PS'' then + retval := trim(psrec.slotlink) || '' -> ''; + return retval || pslot_backlink_view(psrec.slotlink); + end if; + if sltype = ''HS'' then + retval := comment from Hub H, HSlot HS + where HS.slotname = psrec.slotlink + and H.name = HS.hubname; + retval := retval || '' slot ''; + retval := retval || slotno::text from HSlot + where slotname = psrec.slotlink; + return retval; + end if; + return psrec.slotlink; +end; +' language plpgsql +-- +FUNCTION: name="pslot_slotlink_view" function="pslot_slotlink_view" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pslot_slotlink_view(bpchar) RETURNS text AS $$\ndeclare\n psrec\trecord;\n slty..." +== 092 +-- truncate_limit: 100 +-- ************************************************************ +-- * Describe the front of a wall connector slot +-- ************************************************************ +create function wslot_slotlink_view(bpchar) +returns text as ' +declare + rec record; + sltype char(2); + retval text; +begin + select into rec * from WSlot where slotname = $1; + if not found then + return ''''; + end if; + if rec.slotlink = '''' then + return ''-''; + end if; + sltype := substr(rec.slotlink, 1, 2); + if sltype = ''PH'' then + select into rec * from PHone where slotname = rec.slotlink; + retval := ''Phone '' || trim(rec.slotname); + if rec.comment != '''' then + retval := retval || '' (''; + retval := retval || rec.comment; + retval := retval || '')''; + end if; + return retval; + end if; + if sltype = ''IF'' then + declare + syrow System%RowType; + ifrow IFace%ROWTYPE; + begin + select into ifrow * from IFace where slotname = rec.slotlink; + select into syrow * from System where name = ifrow.sysname; + retval := syrow.name || '' IF ''; + retval := retval || ifrow.ifname; + if syrow.comment != '''' then + retval := retval || '' (''; + retval := retval || syrow.comment; + retval := retval || '')''; + end if; + return retval; + end; + end if; + return rec.slotlink; +end; +' language plpgsql +-- +FUNCTION: name="wslot_slotlink_view" function="wslot_slotlink_view" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION wslot_slotlink_view(bpchar) RETURNS text AS $$\ndeclare\n rec\t\trecord;\n sltyp..." +== 093 +-- truncate_limit: 100 +-- ************************************************************ +-- * View of a patchfield describing backside and patches +-- ************************************************************ +create view Pfield_v1 as select PF.pfname, PF.slotname, + pslot_backlink_view(PF.slotname) as backside, + pslot_slotlink_view(PF.slotname) as patch + from PSlot PF +-- +TABLE: name="pfield_v1" schema="" table="pfield_v1" ctx=DDL +TABLE: name="pslot" schema="" table="pslot" ctx=Select +ALIAS: "pf"="pslot" +FUNCTION: name="pslot_backlink_view" function="pslot_backlink_view" schema="" ctx=Call +FUNCTION: name="pslot_slotlink_view" function="pslot_slotlink_view" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW pfield_v1 AS SELECT pf.pfname, pf.slotname, pslot_backlink_view(pf.slotname) AS backs..." +== 094 +-- truncate_limit: 100 +|-- +-- First we build the house - so we create the rooms +|-- +insert into Room values ('001', 'Entrance') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('001', 'Entrance')" +== 095 +-- truncate_limit: 100 +insert into Room values ('002', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('002', 'Office')" +== 096 +-- truncate_limit: 100 +insert into Room values ('003', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('003', 'Office')" +== 097 +-- truncate_limit: 100 +insert into Room values ('004', 'Technical') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('004', 'Technical')" +== 098 +-- truncate_limit: 100 +insert into Room values ('101', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('101', 'Office')" +== 099 +-- truncate_limit: 100 +insert into Room values ('102', 'Conference') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('102', 'Conference')" +== 100 +-- truncate_limit: 100 +insert into Room values ('103', 'Restroom') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('103', 'Restroom')" +== 101 +-- truncate_limit: 100 +insert into Room values ('104', 'Technical') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('104', 'Technical')" +== 102 +-- truncate_limit: 100 +insert into Room values ('105', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('105', 'Office')" +== 103 +-- truncate_limit: 100 +insert into Room values ('106', 'Office') +-- +TABLE: name="room" schema="" table="room" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO room VALUES ('106', 'Office')" +== 104 +-- truncate_limit: 100 +|-- +-- Second we install the wall connectors +|-- +insert into WSlot values ('WS.001.1a', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.001.1a', '001', '', '')" +== 105 +-- truncate_limit: 100 +insert into WSlot values ('WS.001.1b', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.001.1b', '001', '', '')" +== 106 +-- truncate_limit: 100 +insert into WSlot values ('WS.001.2a', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.001.2a', '001', '', '')" +== 107 +-- truncate_limit: 100 +insert into WSlot values ('WS.001.2b', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.001.2b', '001', '', '')" +== 108 +-- truncate_limit: 100 +insert into WSlot values ('WS.001.3a', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.001.3a', '001', '', '')" +== 109 +-- truncate_limit: 100 +insert into WSlot values ('WS.001.3b', '001', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.001.3b', '001', '', '')" +== 110 +-- truncate_limit: 100 +insert into WSlot values ('WS.002.1a', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.002.1a', '002', '', '')" +== 111 +-- truncate_limit: 100 +insert into WSlot values ('WS.002.1b', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.002.1b', '002', '', '')" +== 112 +-- truncate_limit: 100 +insert into WSlot values ('WS.002.2a', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.002.2a', '002', '', '')" +== 113 +-- truncate_limit: 100 +insert into WSlot values ('WS.002.2b', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.002.2b', '002', '', '')" +== 114 +-- truncate_limit: 100 +insert into WSlot values ('WS.002.3a', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.002.3a', '002', '', '')" +== 115 +-- truncate_limit: 100 +insert into WSlot values ('WS.002.3b', '002', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.002.3b', '002', '', '')" +== 116 +-- truncate_limit: 100 +insert into WSlot values ('WS.003.1a', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.003.1a', '003', '', '')" +== 117 +-- truncate_limit: 100 +insert into WSlot values ('WS.003.1b', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.003.1b', '003', '', '')" +== 118 +-- truncate_limit: 100 +insert into WSlot values ('WS.003.2a', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.003.2a', '003', '', '')" +== 119 +-- truncate_limit: 100 +insert into WSlot values ('WS.003.2b', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.003.2b', '003', '', '')" +== 120 +-- truncate_limit: 100 +insert into WSlot values ('WS.003.3a', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.003.3a', '003', '', '')" +== 121 +-- truncate_limit: 100 +insert into WSlot values ('WS.003.3b', '003', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.003.3b', '003', '', '')" +== 122 +-- truncate_limit: 100 +insert into WSlot values ('WS.101.1a', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.101.1a', '101', '', '')" +== 123 +-- truncate_limit: 100 +insert into WSlot values ('WS.101.1b', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.101.1b', '101', '', '')" +== 124 +-- truncate_limit: 100 +insert into WSlot values ('WS.101.2a', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.101.2a', '101', '', '')" +== 125 +-- truncate_limit: 100 +insert into WSlot values ('WS.101.2b', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.101.2b', '101', '', '')" +== 126 +-- truncate_limit: 100 +insert into WSlot values ('WS.101.3a', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.101.3a', '101', '', '')" +== 127 +-- truncate_limit: 100 +insert into WSlot values ('WS.101.3b', '101', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.101.3b', '101', '', '')" +== 128 +-- truncate_limit: 100 +insert into WSlot values ('WS.102.1a', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.102.1a', '102', '', '')" +== 129 +-- truncate_limit: 100 +insert into WSlot values ('WS.102.1b', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.102.1b', '102', '', '')" +== 130 +-- truncate_limit: 100 +insert into WSlot values ('WS.102.2a', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.102.2a', '102', '', '')" +== 131 +-- truncate_limit: 100 +insert into WSlot values ('WS.102.2b', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.102.2b', '102', '', '')" +== 132 +-- truncate_limit: 100 +insert into WSlot values ('WS.102.3a', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.102.3a', '102', '', '')" +== 133 +-- truncate_limit: 100 +insert into WSlot values ('WS.102.3b', '102', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.102.3b', '102', '', '')" +== 134 +-- truncate_limit: 100 +insert into WSlot values ('WS.105.1a', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.105.1a', '105', '', '')" +== 135 +-- truncate_limit: 100 +insert into WSlot values ('WS.105.1b', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.105.1b', '105', '', '')" +== 136 +-- truncate_limit: 100 +insert into WSlot values ('WS.105.2a', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.105.2a', '105', '', '')" +== 137 +-- truncate_limit: 100 +insert into WSlot values ('WS.105.2b', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.105.2b', '105', '', '')" +== 138 +-- truncate_limit: 100 +insert into WSlot values ('WS.105.3a', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.105.3a', '105', '', '')" +== 139 +-- truncate_limit: 100 +insert into WSlot values ('WS.105.3b', '105', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.105.3b', '105', '', '')" +== 140 +-- truncate_limit: 100 +insert into WSlot values ('WS.106.1a', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.106.1a', '106', '', '')" +== 141 +-- truncate_limit: 100 +insert into WSlot values ('WS.106.1b', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.106.1b', '106', '', '')" +== 142 +-- truncate_limit: 100 +insert into WSlot values ('WS.106.2a', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.106.2a', '106', '', '')" +== 143 +-- truncate_limit: 100 +insert into WSlot values ('WS.106.2b', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.106.2b', '106', '', '')" +== 144 +-- truncate_limit: 100 +insert into WSlot values ('WS.106.3a', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.106.3a', '106', '', '')" +== 145 +-- truncate_limit: 100 +insert into WSlot values ('WS.106.3b', '106', '', '') +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wslot VALUES ('WS.106.3b', '106', '', '')" +== 146 +-- truncate_limit: 100 +|-- +-- Now create the patch fields and their slots +|-- +insert into PField values ('PF0_1', 'Wallslots basement') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pfield VALUES ('PF0_1', 'Wallslots basement')" +== 147 +-- truncate_limit: 100 +|-- +-- The cables for these will be made later, so they are unconnected for now +|-- +insert into PSlot values ('PS.base.a1', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.a1', 'PF0_1', '', '')" +== 148 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.a2', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.a2', 'PF0_1', '', '')" +== 149 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.a3', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.a3', 'PF0_1', '', '')" +== 150 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.a4', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.a4', 'PF0_1', '', '')" +== 151 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.a5', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.a5', 'PF0_1', '', '')" +== 152 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.a6', 'PF0_1', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.a6', 'PF0_1', '', '')" +== 153 +-- truncate_limit: 100 +|-- +-- These are already wired to the wall connectors +|-- +insert into PSlot values ('PS.base.b1', 'PF0_1', '', 'WS.002.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.b1', 'PF0_1', '', 'WS.002.1a')" +== 154 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.b2', 'PF0_1', '', 'WS.002.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.b2', 'PF0_1', '', 'WS.002.1b')" +== 155 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.b3', 'PF0_1', '', 'WS.002.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.b3', 'PF0_1', '', 'WS.002.2a')" +== 156 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.b4', 'PF0_1', '', 'WS.002.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.b4', 'PF0_1', '', 'WS.002.2b')" +== 157 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.b5', 'PF0_1', '', 'WS.002.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.b5', 'PF0_1', '', 'WS.002.3a')" +== 158 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.b6', 'PF0_1', '', 'WS.002.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.b6', 'PF0_1', '', 'WS.002.3b')" +== 159 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.c1', 'PF0_1', '', 'WS.003.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.c1', 'PF0_1', '', 'WS.003.1a')" +== 160 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.c2', 'PF0_1', '', 'WS.003.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.c2', 'PF0_1', '', 'WS.003.1b')" +== 161 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.c3', 'PF0_1', '', 'WS.003.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.c3', 'PF0_1', '', 'WS.003.2a')" +== 162 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.c4', 'PF0_1', '', 'WS.003.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.c4', 'PF0_1', '', 'WS.003.2b')" +== 163 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.c5', 'PF0_1', '', 'WS.003.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.c5', 'PF0_1', '', 'WS.003.3a')" +== 164 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.c6', 'PF0_1', '', 'WS.003.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.c6', 'PF0_1', '', 'WS.003.3b')" +== 165 +-- truncate_limit: 100 +|-- +-- This patchfield will be renamed later into PF0_2 - so its +-- slots references in pfname should follow +|-- +insert into PField values ('PF0_X', 'Phonelines basement') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pfield VALUES ('PF0_X', 'Phonelines basement')" +== 166 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.ta1', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.ta1', 'PF0_X', '', '')" +== 167 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.ta2', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.ta2', 'PF0_X', '', '')" +== 168 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.ta3', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.ta3', 'PF0_X', '', '')" +== 169 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.ta4', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.ta4', 'PF0_X', '', '')" +== 170 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.ta5', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.ta5', 'PF0_X', '', '')" +== 171 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.ta6', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.ta6', 'PF0_X', '', '')" +== 172 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.tb1', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.tb1', 'PF0_X', '', '')" +== 173 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.tb2', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.tb2', 'PF0_X', '', '')" +== 174 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.tb3', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.tb3', 'PF0_X', '', '')" +== 175 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.tb4', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.tb4', 'PF0_X', '', '')" +== 176 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.tb5', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.tb5', 'PF0_X', '', '')" +== 177 +-- truncate_limit: 100 +insert into PSlot values ('PS.base.tb6', 'PF0_X', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.base.tb6', 'PF0_X', '', '')" +== 178 +-- truncate_limit: 100 +insert into PField values ('PF1_1', 'Wallslots first floor') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pfield VALUES ('PF1_1', 'Wallslots first floor')" +== 179 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.a1', 'PF1_1', '', 'WS.101.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.a1', 'PF1_1', '', 'WS.101.1a')" +== 180 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.a2', 'PF1_1', '', 'WS.101.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.a2', 'PF1_1', '', 'WS.101.1b')" +== 181 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.a3', 'PF1_1', '', 'WS.101.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.a3', 'PF1_1', '', 'WS.101.2a')" +== 182 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.a4', 'PF1_1', '', 'WS.101.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.a4', 'PF1_1', '', 'WS.101.2b')" +== 183 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.a5', 'PF1_1', '', 'WS.101.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.a5', 'PF1_1', '', 'WS.101.3a')" +== 184 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.a6', 'PF1_1', '', 'WS.101.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.a6', 'PF1_1', '', 'WS.101.3b')" +== 185 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.b1', 'PF1_1', '', 'WS.102.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.b1', 'PF1_1', '', 'WS.102.1a')" +== 186 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.b2', 'PF1_1', '', 'WS.102.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.b2', 'PF1_1', '', 'WS.102.1b')" +== 187 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.b3', 'PF1_1', '', 'WS.102.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.b3', 'PF1_1', '', 'WS.102.2a')" +== 188 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.b4', 'PF1_1', '', 'WS.102.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.b4', 'PF1_1', '', 'WS.102.2b')" +== 189 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.b5', 'PF1_1', '', 'WS.102.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.b5', 'PF1_1', '', 'WS.102.3a')" +== 190 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.b6', 'PF1_1', '', 'WS.102.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.b6', 'PF1_1', '', 'WS.102.3b')" +== 191 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.c1', 'PF1_1', '', 'WS.105.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.c1', 'PF1_1', '', 'WS.105.1a')" +== 192 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.c2', 'PF1_1', '', 'WS.105.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.c2', 'PF1_1', '', 'WS.105.1b')" +== 193 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.c3', 'PF1_1', '', 'WS.105.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.c3', 'PF1_1', '', 'WS.105.2a')" +== 194 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.c4', 'PF1_1', '', 'WS.105.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.c4', 'PF1_1', '', 'WS.105.2b')" +== 195 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.c5', 'PF1_1', '', 'WS.105.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.c5', 'PF1_1', '', 'WS.105.3a')" +== 196 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.c6', 'PF1_1', '', 'WS.105.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.c6', 'PF1_1', '', 'WS.105.3b')" +== 197 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.d1', 'PF1_1', '', 'WS.106.1a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.d1', 'PF1_1', '', 'WS.106.1a')" +== 198 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.d2', 'PF1_1', '', 'WS.106.1b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.d2', 'PF1_1', '', 'WS.106.1b')" +== 199 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.d3', 'PF1_1', '', 'WS.106.2a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.d3', 'PF1_1', '', 'WS.106.2a')" +== 200 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.d4', 'PF1_1', '', 'WS.106.2b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.d4', 'PF1_1', '', 'WS.106.2b')" +== 201 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.d5', 'PF1_1', '', 'WS.106.3a') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.d5', 'PF1_1', '', 'WS.106.3a')" +== 202 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.d6', 'PF1_1', '', 'WS.106.3b') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.d6', 'PF1_1', '', 'WS.106.3b')" +== 203 +-- truncate_limit: 100 +|-- +-- Now we wire the wall connectors 1a-2a in room 001 to the +-- patchfield. In the second update we make an error, and +-- correct it after +|-- +update PSlot set backlink = 'WS.001.1a' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET backlink = 'WS.001.1a' WHERE slotname = 'PS.base.a1'" +== 204 +-- truncate_limit: 100 +update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET backlink = 'WS.001.1b' WHERE slotname = 'PS.base.a3'" +== 205 +-- truncate_limit: 100 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wslot WHERE roomno = '001' ORDER BY slotname" +== 206 +-- truncate_limit: 100 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pslot WHERE slotname ~ 'PS.base.a' ORDER BY slotname" +== 207 +-- truncate_limit: 100 +update PSlot set backlink = 'WS.001.2a' where slotname = 'PS.base.a3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET backlink = 'WS.001.2a' WHERE slotname = 'PS.base.a3'" +== 208 +-- truncate_limit: 100 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wslot WHERE roomno = '001' ORDER BY slotname" +== 209 +-- truncate_limit: 100 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pslot WHERE slotname ~ 'PS.base.a' ORDER BY slotname" +== 210 +-- truncate_limit: 100 +update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a2' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET backlink = 'WS.001.1b' WHERE slotname = 'PS.base.a2'" +== 211 +-- truncate_limit: 100 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wslot WHERE roomno = '001' ORDER BY slotname" +== 212 +-- truncate_limit: 100 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pslot WHERE slotname ~ 'PS.base.a' ORDER BY slotname" +== 213 +-- truncate_limit: 100 +|-- +-- Same procedure for 2b-3b but this time updating the WSlot instead +-- of the PSlot. Due to the triggers the result is the same: +-- WSlot and corresponding PSlot point to each other. +|-- +update WSlot set backlink = 'PS.base.a4' where slotname = 'WS.001.2b' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE wslot SET backlink = 'PS.base.a4' WHERE slotname = 'WS.001.2b'" +== 214 +-- truncate_limit: 100 +update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3a' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE wslot SET backlink = 'PS.base.a6' WHERE slotname = 'WS.001.3a'" +== 215 +-- truncate_limit: 100 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wslot WHERE roomno = '001' ORDER BY slotname" +== 216 +-- truncate_limit: 100 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pslot WHERE slotname ~ 'PS.base.a' ORDER BY slotname" +== 217 +-- truncate_limit: 100 +update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3b' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE wslot SET backlink = 'PS.base.a6' WHERE slotname = 'WS.001.3b'" +== 218 +-- truncate_limit: 100 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wslot WHERE roomno = '001' ORDER BY slotname" +== 219 +-- truncate_limit: 100 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pslot WHERE slotname ~ 'PS.base.a' ORDER BY slotname" +== 220 +-- truncate_limit: 100 +update WSlot set backlink = 'PS.base.a5' where slotname = 'WS.001.3a' +-- +TABLE: name="wslot" schema="" table="wslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE wslot SET backlink = 'PS.base.a5' WHERE slotname = 'WS.001.3a'" +== 221 +-- truncate_limit: 100 +select * from WSlot where roomno = '001' order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +FILTER: schema="" table="" column="roomno" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wslot WHERE roomno = '001' ORDER BY slotname" +== 222 +-- truncate_limit: 100 +select * from PSlot where slotname ~ 'PS.base.a' order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +FILTER: schema="" table="" column="slotname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pslot WHERE slotname ~ 'PS.base.a' ORDER BY slotname" +== 223 +-- truncate_limit: 100 +insert into PField values ('PF1_2', 'Phonelines first floor') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pfield VALUES ('PF1_2', 'Phonelines first floor')" +== 224 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.ta1', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.ta1', 'PF1_2', '', '')" +== 225 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.ta2', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.ta2', 'PF1_2', '', '')" +== 226 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.ta3', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.ta3', 'PF1_2', '', '')" +== 227 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.ta4', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.ta4', 'PF1_2', '', '')" +== 228 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.ta5', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.ta5', 'PF1_2', '', '')" +== 229 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.ta6', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.ta6', 'PF1_2', '', '')" +== 230 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.tb1', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.tb1', 'PF1_2', '', '')" +== 231 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.tb2', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.tb2', 'PF1_2', '', '')" +== 232 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.tb3', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.tb3', 'PF1_2', '', '')" +== 233 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.tb4', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.tb4', 'PF1_2', '', '')" +== 234 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.tb5', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.tb5', 'PF1_2', '', '')" +== 235 +-- truncate_limit: 100 +insert into PSlot values ('PS.first.tb6', 'PF1_2', '', '') +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pslot VALUES ('PS.first.tb6', 'PF1_2', '', '')" +== 236 +-- truncate_limit: 100 +|-- +-- Fix the wrong name for patchfield PF0_2 +|-- +update PField set name = 'PF0_2' where name = 'PF0_X' +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pfield SET name = 'PF0_2' WHERE name = 'PF0_X'" +== 237 +-- truncate_limit: 100 +select * from PSlot order by slotname +-- +TABLE: name="pslot" schema="" table="pslot" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pslot ORDER BY slotname" +== 238 +-- truncate_limit: 100 +select * from WSlot order by slotname +-- +TABLE: name="wslot" schema="" table="wslot" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM wslot ORDER BY slotname" +== 239 +-- truncate_limit: 100 +|-- +-- Install the central phone system and create the phone numbers. +-- They are wired on insert to the patchfields. Again the +-- triggers automatically tell the PSlots to update their +-- backlink field. +|-- +insert into PLine values ('PL.001', '-0', 'Central call', 'PS.base.ta1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.001', '-0', 'Central call', 'PS.base.ta1')" +== 240 +-- truncate_limit: 100 +insert into PLine values ('PL.002', '-101', '', 'PS.base.ta2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.002', '-101', '', 'PS.base.ta2')" +== 241 +-- truncate_limit: 100 +insert into PLine values ('PL.003', '-102', '', 'PS.base.ta3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.003', '-102', '', 'PS.base.ta3')" +== 242 +-- truncate_limit: 100 +insert into PLine values ('PL.004', '-103', '', 'PS.base.ta5') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.004', '-103', '', 'PS.base.ta5')" +== 243 +-- truncate_limit: 100 +insert into PLine values ('PL.005', '-104', '', 'PS.base.ta6') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.005', '-104', '', 'PS.base.ta6')" +== 244 +-- truncate_limit: 100 +insert into PLine values ('PL.006', '-106', '', 'PS.base.tb2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.006', '-106', '', 'PS.base.tb2')" +== 245 +-- truncate_limit: 100 +insert into PLine values ('PL.007', '-108', '', 'PS.base.tb3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.007', '-108', '', 'PS.base.tb3')" +== 246 +-- truncate_limit: 100 +insert into PLine values ('PL.008', '-109', '', 'PS.base.tb4') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.008', '-109', '', 'PS.base.tb4')" +== 247 +-- truncate_limit: 100 +insert into PLine values ('PL.009', '-121', '', 'PS.base.tb5') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.009', '-121', '', 'PS.base.tb5')" +== 248 +-- truncate_limit: 100 +insert into PLine values ('PL.010', '-122', '', 'PS.base.tb6') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.010', '-122', '', 'PS.base.tb6')" +== 249 +-- truncate_limit: 100 +insert into PLine values ('PL.015', '-134', '', 'PS.first.ta1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.015', '-134', '', 'PS.first.ta1')" +== 250 +-- truncate_limit: 100 +insert into PLine values ('PL.016', '-137', '', 'PS.first.ta3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.016', '-137', '', 'PS.first.ta3')" +== 251 +-- truncate_limit: 100 +insert into PLine values ('PL.017', '-139', '', 'PS.first.ta4') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.017', '-139', '', 'PS.first.ta4')" +== 252 +-- truncate_limit: 100 +insert into PLine values ('PL.018', '-362', '', 'PS.first.tb1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.018', '-362', '', 'PS.first.tb1')" +== 253 +-- truncate_limit: 100 +insert into PLine values ('PL.019', '-363', '', 'PS.first.tb2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.019', '-363', '', 'PS.first.tb2')" +== 254 +-- truncate_limit: 100 +insert into PLine values ('PL.020', '-364', '', 'PS.first.tb3') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.020', '-364', '', 'PS.first.tb3')" +== 255 +-- truncate_limit: 100 +insert into PLine values ('PL.021', '-365', '', 'PS.first.tb5') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.021', '-365', '', 'PS.first.tb5')" +== 256 +-- truncate_limit: 100 +insert into PLine values ('PL.022', '-367', '', 'PS.first.tb6') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.022', '-367', '', 'PS.first.tb6')" +== 257 +-- truncate_limit: 100 +insert into PLine values ('PL.028', '-501', 'Fax entrance', 'PS.base.ta2') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.028', '-501', 'Fax entrance', 'PS.base.ta2')" +== 258 +-- truncate_limit: 100 +insert into PLine values ('PL.029', '-502', 'Fax first floor', 'PS.first.ta1') +-- +TABLE: name="pline" schema="" table="pline" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pline VALUES ('PL.029', '-502', 'Fax first floor', 'PS.first.ta1')" +== 259 +-- truncate_limit: 100 +|-- +-- Buy some phones, plug them into the wall and patch the +-- phone lines to the corresponding patchfield slots. +|-- +insert into PHone values ('PH.hc001', 'Hicom standard', 'WS.001.1a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO phone VALUES ('PH.hc001', 'Hicom standard', 'WS.001.1a')" +== 260 +-- truncate_limit: 100 +update PSlot set slotlink = 'PS.base.ta1' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET slotlink = 'PS.base.ta1' WHERE slotname = 'PS.base.a1'" +== 261 +-- truncate_limit: 100 +insert into PHone values ('PH.hc002', 'Hicom standard', 'WS.002.1a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO phone VALUES ('PH.hc002', 'Hicom standard', 'WS.002.1a')" +== 262 +-- truncate_limit: 100 +update PSlot set slotlink = 'PS.base.ta5' where slotname = 'PS.base.b1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET slotlink = 'PS.base.ta5' WHERE slotname = 'PS.base.b1'" +== 263 +-- truncate_limit: 100 +insert into PHone values ('PH.hc003', 'Hicom standard', 'WS.002.2a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO phone VALUES ('PH.hc003', 'Hicom standard', 'WS.002.2a')" +== 264 +-- truncate_limit: 100 +update PSlot set slotlink = 'PS.base.tb2' where slotname = 'PS.base.b3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET slotlink = 'PS.base.tb2' WHERE slotname = 'PS.base.b3'" +== 265 +-- truncate_limit: 100 +insert into PHone values ('PH.fax001', 'Canon fax', 'WS.001.2a') +-- +TABLE: name="phone" schema="" table="phone" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO phone VALUES ('PH.fax001', 'Canon fax', 'WS.001.2a')" +== 266 +-- truncate_limit: 100 +update PSlot set slotlink = 'PS.base.ta2' where slotname = 'PS.base.a3' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET slotlink = 'PS.base.ta2' WHERE slotname = 'PS.base.a3'" +== 267 +-- truncate_limit: 100 +|-- +-- Install a hub at one of the patchfields, plug a computers +-- ethernet interface into the wall and patch it to the hub. +|-- +insert into Hub values ('base.hub1', 'Patchfield PF0_1 hub', 16) +-- +TABLE: name="hub" schema="" table="hub" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hub VALUES ('base.hub1', 'Patchfield PF0_1 hub', 16)" +== 268 +-- truncate_limit: 100 +insert into System values ('orion', 'PC') +-- +TABLE: name="system" schema="" table="system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO system VALUES ('orion', 'PC')" +== 269 +-- truncate_limit: 100 +insert into IFace values ('IF', 'orion', 'eth0', 'WS.002.1b') +-- +TABLE: name="iface" schema="" table="iface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iface VALUES ('IF', 'orion', 'eth0', 'WS.002.1b')" +== 270 +-- truncate_limit: 100 +update PSlot set slotlink = 'HS.base.hub1.1' where slotname = 'PS.base.b2' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET slotlink = 'HS.base.hub1.1' WHERE slotname = 'PS.base.b2'" +== 271 +-- truncate_limit: 100 +|-- +-- Now we take a look at the patchfield +|-- +select * from PField_v1 where pfname = 'PF0_1' order by slotname +-- +TABLE: name="pfield_v1" schema="" table="pfield_v1" ctx=Select +FILTER: schema="" table="" column="pfname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pfield_v1 WHERE pfname = 'PF0_1' ORDER BY slotname" +== 272 +-- truncate_limit: 100 +select * from PField_v1 where pfname = 'PF0_2' order by slotname +-- +TABLE: name="pfield_v1" schema="" table="pfield_v1" ctx=Select +FILTER: schema="" table="" column="pfname" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pfield_v1 WHERE pfname = 'PF0_2' ORDER BY slotname" +== 273 +-- truncate_limit: 100 +|-- +-- Finally we want errors +|-- +insert into PField values ('PF1_1', 'should fail due to unique index') +-- +TABLE: name="pfield" schema="" table="pfield" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pfield VALUES ('PF1_1', 'should fail due to unique index')" +== 274 +-- truncate_limit: 100 +update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET backlink = 'WS.not.there' WHERE slotname = 'PS.base.a1'" +== 275 +-- truncate_limit: 100 +update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET backlink = 'XX.illegal' WHERE slotname = 'PS.base.a1'" +== 276 +-- truncate_limit: 100 +update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET slotlink = 'PS.not.there' WHERE slotname = 'PS.base.a1'" +== 277 +-- truncate_limit: 100 +update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1' +-- +TABLE: name="pslot" schema="" table="pslot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pslot SET slotlink = 'XX.illegal' WHERE slotname = 'PS.base.a1'" +== 278 +-- truncate_limit: 100 +insert into HSlot values ('HS', 'base.hub1', 1, '') +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hslot VALUES ('HS', 'base.hub1', 1, '')" +== 279 +-- truncate_limit: 100 +insert into HSlot values ('HS', 'base.hub1', 20, '') +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hslot VALUES ('HS', 'base.hub1', 20, '')" +== 280 +-- truncate_limit: 100 +delete from HSlot +-- +TABLE: name="hslot" schema="" table="hslot" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM hslot" +== 281 +-- truncate_limit: 100 +insert into IFace values ('IF', 'notthere', 'eth0', '') +-- +TABLE: name="iface" schema="" table="iface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iface VALUES ('IF', 'notthere', 'eth0', '')" +== 282 +-- truncate_limit: 100 +insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', '') +-- +TABLE: name="iface" schema="" table="iface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iface VALUES ('IF', 'orion', 'ethernet_interface_name_too_long', '')" +== 283 +-- truncate_limit: 100 +|-- +-- The following tests are unrelated to the scenario outlined above; +-- they merely exercise specific parts of PL/pgSQL +|-- + +|-- +-- Test recursion, per bug report 7-Sep-01 +|-- +CREATE FUNCTION recursion_test(int,int) RETURNS text AS ' +DECLARE rslt text; +BEGIN + IF $1 <= 0 THEN + rslt = CAST($2 AS TEXT); + ELSE + rslt = CAST($1 AS TEXT) || '','' || recursion_test($1 - 1, $2); + END IF; + RETURN rslt; +END;' LANGUAGE plpgsql +-- +FUNCTION: name="recursion_test" function="recursion_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION recursion_test(int, int) RETURNS text AS $$\nDECLARE rslt text;\nBEGIN\n IF $1 <=..." +== 284 +-- truncate_limit: 100 +SELECT recursion_test(4,3) +-- +FUNCTION: name="recursion_test" function="recursion_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT recursion_test(4, 3)" +== 285 +-- truncate_limit: 100 +|-- +-- Test the FOUND magic variable +|-- +CREATE TABLE found_test_tbl (a int) +-- +TABLE: name="found_test_tbl" schema="" table="found_test_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE found_test_tbl (a int)" +== 286 +-- truncate_limit: 100 +create function test_found() + returns boolean as ' + declare + begin + insert into found_test_tbl values (1); + if FOUND then + insert into found_test_tbl values (2); + end if; + + update found_test_tbl set a = 100 where a = 1; + if FOUND then + insert into found_test_tbl values (3); + end if; + + delete from found_test_tbl where a = 9999; -- matches no rows + if not FOUND then + insert into found_test_tbl values (4); + end if; + + for i in 1 .. 10 loop + -- no need to do anything + end loop; + if FOUND then + insert into found_test_tbl values (5); + end if; + + -- never executes the loop + for i in 2 .. 1 loop + -- no need to do anything + end loop; + if not FOUND then + insert into found_test_tbl values (6); + end if; + return true; + end;' language plpgsql +-- +FUNCTION: name="test_found" function="test_found" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_found() RETURNS boolean AS $$\n declare\n begin\n insert into found_test_tbl..." +== 287 +-- truncate_limit: 100 +select test_found() +-- +FUNCTION: name="test_found" function="test_found" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_found()" +== 288 +-- truncate_limit: 100 +select * from found_test_tbl +-- +TABLE: name="found_test_tbl" schema="" table="found_test_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM found_test_tbl" +== 289 +-- truncate_limit: 100 +|-- +-- Test set-returning functions for PL/pgSQL +|-- + +create function test_table_func_rec() returns setof found_test_tbl as ' +DECLARE + rec RECORD; +BEGIN + FOR rec IN select * from found_test_tbl LOOP + RETURN NEXT rec; + END LOOP; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_table_func_rec" function="test_table_func_rec" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_table_func_rec() RETURNS SETOF found_test_tbl AS $$\nDECLARE\n\trec RECORD;\nBEG..." +== 290 +-- truncate_limit: 100 +select * from test_table_func_rec() +-- +FUNCTION: name="test_table_func_rec" function="test_table_func_rec" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_table_func_rec()" +== 291 +-- truncate_limit: 100 +create function test_table_func_row() returns setof found_test_tbl as ' +DECLARE + row found_test_tbl%ROWTYPE; +BEGIN + FOR row IN select * from found_test_tbl LOOP + RETURN NEXT row; + END LOOP; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_table_func_row" function="test_table_func_row" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_table_func_row() RETURNS SETOF found_test_tbl AS $$\nDECLARE\n\trow found_test_..." +== 292 +-- truncate_limit: 100 +select * from test_table_func_row() +-- +FUNCTION: name="test_table_func_row" function="test_table_func_row" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_table_func_row()" +== 293 +-- truncate_limit: 100 +create function test_ret_set_scalar(int,int) returns setof int as ' +DECLARE + i int; +BEGIN + FOR i IN $1 .. $2 LOOP + RETURN NEXT i + 1; + END LOOP; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_ret_set_scalar" function="test_ret_set_scalar" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_ret_set_scalar(int, int) RETURNS SETOF int AS $$\nDECLARE\n\ti int;\nBEGIN\n\tFOR ..." +== 294 +-- truncate_limit: 100 +select * from test_ret_set_scalar(1,10) +-- +FUNCTION: name="test_ret_set_scalar" function="test_ret_set_scalar" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_ret_set_scalar(1, 10)" +== 295 +-- truncate_limit: 100 +create function test_ret_set_rec_dyn(int) returns setof record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN NEXT retval; + RETURN NEXT retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN NEXT retval; + RETURN NEXT retval; + END IF; + RETURN; +END;' language plpgsql +-- +FUNCTION: name="test_ret_set_rec_dyn" function="test_ret_set_rec_dyn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_ret_set_rec_dyn(int) RETURNS SETOF record AS $$\nDECLARE\n\tretval RECORD;\nBEGI..." +== 296 +-- truncate_limit: 100 +SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int) +-- +FUNCTION: name="test_ret_set_rec_dyn" function="test_ret_set_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int)" +== 297 +-- truncate_limit: 100 +SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text) +-- +FUNCTION: name="test_ret_set_rec_dyn" function="test_ret_set_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text)" +== 298 +-- truncate_limit: 100 +create function test_ret_rec_dyn(int) returns record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN retval; + END IF; +END;' language plpgsql +-- +FUNCTION: name="test_ret_rec_dyn" function="test_ret_rec_dyn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_ret_rec_dyn(int) RETURNS record AS $$\nDECLARE\n\tretval RECORD;\nBEGIN\n\tIF $1 >..." +== 299 +-- truncate_limit: 100 +SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int) +-- +FUNCTION: name="test_ret_rec_dyn" function="test_ret_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int)" +== 300 +-- truncate_limit: 100 +SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text) +-- +FUNCTION: name="test_ret_rec_dyn" function="test_ret_rec_dyn" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text)" +== 301 +-- truncate_limit: 100 +|-- +-- Test some simple polymorphism cases. +|-- + +create function f1(x anyelement) returns anyelement as $$ +begin + return x + 1; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anyelement) RETURNS anyelement AS $$\nbegin\n return x + 1;\nend$$ LANGUAGE pl..." +== 302 +-- truncate_limit: 100 +select f1(42) as int, f1(4.5) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(42) AS \"int\", f1(4.5) AS num" +== 303 +-- truncate_limit: 100 +select f1(point(3,4)) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(point(3, 4))" +== 304 +-- truncate_limit: 100 +-- fail for lack of + operator + +drop function f1(x anyelement) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anyelement)" +== 305 +-- truncate_limit: 100 +create function f1(x anyelement) returns anyarray as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anyelement) RETURNS anyarray AS $$\nbegin\n return array[x + 1, x + 2];\nend$$..." +== 306 +-- truncate_limit: 100 +select f1(42) as int, f1(4.5) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(42) AS \"int\", f1(4.5) AS num" +== 307 +-- truncate_limit: 100 +drop function f1(x anyelement) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anyelement)" +== 308 +-- truncate_limit: 100 +create function f1(x anyarray) returns anyelement as $$ +begin + return x[1]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anyarray) RETURNS anyelement AS $$\nbegin\n return x[1];\nend$$ LANGUAGE plpgsql" +== 309 +-- truncate_limit: 100 +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(ARRAY[2, 4]) AS \"int\", f1(ARRAY[4.5, 7.7]) AS num" +== 310 +-- truncate_limit: 100 +select f1(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(stavalues1) FROM pg_statistic" +== 311 +-- truncate_limit: 100 +-- fail, can't infer element type + +drop function f1(x anyarray) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anyarray)" +== 312 +-- truncate_limit: 100 +create function f1(x anyarray) returns anyarray as $$ +begin + return x; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anyarray) RETURNS anyarray AS $$\nbegin\n return x;\nend$$ LANGUAGE plpgsql" +== 313 +-- truncate_limit: 100 +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(ARRAY[2, 4]) AS \"int\", f1(ARRAY[4.5, 7.7]) AS num" +== 314 +-- truncate_limit: 100 +select f1(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(stavalues1) FROM pg_statistic" +== 315 +-- truncate_limit: 100 +-- fail, can't infer element type + +drop function f1(x anyarray) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anyarray)" +== 316 +-- truncate_limit: 100 +-- fail, can't infer type: +create function f1(x anyelement) returns anyrange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anyelement) RETURNS anyrange AS $$\nbegin\n return array[x + 1, x + 2];\nend$$..." +== 317 +-- truncate_limit: 100 +create function f1(x anyrange) returns anyarray as $$ +begin + return array[lower(x), upper(x)]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anyrange) RETURNS anyarray AS $$\nbegin\n return array[lower(x), upper(x)];\ne..." +== 318 +-- truncate_limit: 100 +select f1(int4range(42, 49)) as int, f1(float8range(4.5, 7.8)) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(int4range(42, 49)) AS \"int\", f1(float8range(4.5, 7.8)) AS num" +== 319 +-- truncate_limit: 100 +drop function f1(x anyrange) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anyrange)" +== 320 +-- truncate_limit: 100 +create function f1(x anycompatible, y anycompatible) returns anycompatiblearray as $$ +begin + return array[x, y]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anycompatible, y anycompatible) RETURNS anycompatiblearray AS $$\nbegin\n ret..." +== 321 +-- truncate_limit: 100 +select f1(2, 4) as int, f1(2, 4.5) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(2, 4) AS \"int\", f1(2, 4.5) AS num" +== 322 +-- truncate_limit: 100 +drop function f1(x anycompatible, y anycompatible) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anycompatible, y anycompatible)" +== 323 +-- truncate_limit: 100 +create function f1(x anycompatiblerange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ +begin + return array[lower(x), upper(x), y, z]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anycompatiblerange, y anycompatible, z anycompatible) RETURNS anycompatiblea..." +== 324 +-- truncate_limit: 100 +select f1(int4range(42, 49), 11, 2::smallint) as int, f1(float8range(4.5, 7.8), 7.8, 11::real) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 325 +-- truncate_limit: 100 +select f1(int4range(42, 49), 11, 4.5) as fail +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(int4range(42, 49), 11, 4.5) AS fail" +== 326 +-- truncate_limit: 100 +-- range type doesn't fit + +drop function f1(x anycompatiblerange, y anycompatible, z anycompatible) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anycompatiblerange, y anycompatible, z anycompatible)" +== 327 +-- truncate_limit: 100 +-- fail, can't infer type: +create function f1(x anycompatible) returns anycompatiblerange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anycompatible) RETURNS anycompatiblerange AS $$\nbegin\n return array[x + 1, ..." +== 328 +-- truncate_limit: 100 +create function f1(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ +begin + return x; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(x anycompatiblerange, y anycompatiblearray) RETURNS anycompatiblerange AS $$\nb..." +== 329 +-- truncate_limit: 100 +select f1(int4range(42, 49), array[11]) as int, f1(float8range(4.5, 7.8), array[7]) as num +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(int4range(42, 49), ARRAY[11]) AS \"int\", f1(float8range(4.5, 7.8), ARRAY[7]) AS num" +== 330 +-- truncate_limit: 100 +drop function f1(x anycompatiblerange, y anycompatiblearray) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(x anycompatiblerange, y anycompatiblearray)" +== 331 +-- truncate_limit: 100 +create function f1(a anyelement, b anyarray, + c anycompatible, d anycompatible, + OUT x anyarray, OUT y anycompatiblearray) +as $$ +begin + x := a || b; + y := array[c, d]; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(a anyelement, b anyarray, c anycompatible, d anycompatible, OUT x anyarray, OU..." +== 332 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM f1(11, ARRAY[1, 2], 42, 34.5)" +== 333 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2], point(1,2), point(3,4)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM f1(11, ARRAY[1, 2], point(1, 2), point(3, 4))" +== 334 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, '{1,2}', point(1,2), '(3,4)') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM f1(11, '{1,2}', point(1, 2), '(3,4)')" +== 335 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2.2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM f1(11, ARRAY[1, 2.2], 42, 34.5)" +== 336 +-- truncate_limit: 100 +-- fail + +drop function f1(a anyelement, b anyarray, + c anycompatible, d anycompatible) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(a anyelement, b anyarray, c anycompatible, d anycompatible)" +== 337 +-- truncate_limit: 100 +|-- +-- Test handling of OUT parameters, including polymorphic cases. +-- Note that RETURN is optional with OUT params; we try both ways. +|-- + +-- wrong way to do it: +create function f1(in i int, out j int) returns int as $$ +begin + return i+1; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(IN i int, OUT j int) RETURNS int AS $$\nbegin\n return i+1;\nend$$ LANGUAGE plpgsql" +== 338 +-- truncate_limit: 100 +create function f1(in i int, out j int) as $$ +begin + j := i+1; + return; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(IN i int, OUT j int) AS $$\nbegin\n j := i+1;\n return;\nend$$ LANGUAGE plpgsql" +== 339 +-- truncate_limit: 100 +select f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(42)" +== 340 +-- truncate_limit: 100 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM f1(42)" +== 341 +-- truncate_limit: 100 +create or replace function f1(inout i int) as $$ +begin + i := i+1; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION f1(INOUT i int) AS $$\nbegin\n i := i+1;\nend$$ LANGUAGE plpgsql" +== 342 +-- truncate_limit: 100 +select f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(42)" +== 343 +-- truncate_limit: 100 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM f1(42)" +== 344 +-- truncate_limit: 100 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(int)" +== 345 +-- truncate_limit: 100 +create function f1(in i int, out j int) returns setof int as $$ +begin + j := i+1; + return next; + j := i+2; + return next; + return; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(IN i int, OUT j int) RETURNS SETOF int AS $$\nbegin\n j := i+1;\n return next;\n..." +== 346 +-- truncate_limit: 100 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM f1(42)" +== 347 +-- truncate_limit: 100 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(int)" +== 348 +-- truncate_limit: 100 +create function f1(in i int, out j int, out k text) as $$ +begin + j := i; + j := j+1; + k := 'foo'; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(IN i int, OUT j int, OUT k text) AS $$\nbegin\n j := i;\n j := j+1;\n k := 'foo..." +== 349 +-- truncate_limit: 100 +select f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1(42)" +== 350 +-- truncate_limit: 100 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM f1(42)" +== 351 +-- truncate_limit: 100 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(int)" +== 352 +-- truncate_limit: 100 +create function f1(in i int, out j int, out k text) returns setof record as $$ +begin + j := i+1; + k := 'foo'; + return next; + j := j+1; + k := 'foot'; + return next; +end$$ language plpgsql +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1(IN i int, OUT j int, OUT k text) RETURNS SETOF record AS $$\nbegin\n j := i+1;\n..." +== 353 +-- truncate_limit: 100 +select * from f1(42) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM f1(42)" +== 354 +-- truncate_limit: 100 +drop function f1(int) +-- +FUNCTION: name="f1" function="f1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f1(int)" +== 355 +-- truncate_limit: 100 +create function duplic(in i anyelement, out j anyelement, out k anyarray) as $$ +begin + j := i; + k := array[j,j]; + return; +end$$ language plpgsql +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION duplic(IN i anyelement, OUT j anyelement, OUT k anyarray) AS $$\nbegin\n j := i;\n ..." +== 356 +-- truncate_limit: 100 +select * from duplic(42) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM duplic(42)" +== 357 +-- truncate_limit: 100 +select * from duplic('foo'::text) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM duplic('foo'::text)" +== 358 +-- truncate_limit: 100 +drop function duplic(anyelement) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION duplic(anyelement)" +== 359 +-- truncate_limit: 100 +create function duplic(in i anycompatiblerange, out j anycompatible, out k anycompatiblearray) as $$ +begin + j := lower(i); + k := array[lower(i),upper(i)]; + return; +end$$ language plpgsql +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION duplic(IN i anycompatiblerange, OUT j anycompatible, OUT k anycompatiblearray) AS..." +== 360 +-- truncate_limit: 100 +select * from duplic(int4range(42,49)) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM duplic(int4range(42, 49))" +== 361 +-- truncate_limit: 100 +select * from duplic(textrange('aaa', 'bbb')) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM duplic(textrange('aaa', 'bbb'))" +== 362 +-- truncate_limit: 100 +drop function duplic(anycompatiblerange) +-- +FUNCTION: name="duplic" function="duplic" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION duplic(anycompatiblerange)" +== 363 +-- truncate_limit: 100 +|-- +-- test PERFORM +|-- + +create table perform_test ( + a INT, + b INT +) +-- +TABLE: name="perform_test" schema="" table="perform_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE perform_test (a int, b int)" +== 364 +-- truncate_limit: 100 +create function perform_simple_func(int) returns boolean as ' +BEGIN + IF $1 < 20 THEN + INSERT INTO perform_test VALUES ($1, $1 + 10); + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;' language plpgsql +-- +FUNCTION: name="perform_simple_func" function="perform_simple_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION perform_simple_func(int) RETURNS boolean AS $$\nBEGIN\n\tIF $1 < 20 THEN\n\t\tINSERT IN..." +== 365 +-- truncate_limit: 100 +create function perform_test_func() returns void as ' +BEGIN + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + PERFORM perform_simple_func(5); + + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + PERFORM perform_simple_func(50); + + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + RETURN; +END;' language plpgsql +-- +FUNCTION: name="perform_test_func" function="perform_test_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION perform_test_func() RETURNS void AS $$\nBEGIN\n\tIF FOUND then\n\t\tINSERT INTO perform..." +== 366 +-- truncate_limit: 100 +SELECT perform_test_func() +-- +FUNCTION: name="perform_test_func" function="perform_test_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT perform_test_func()" +== 367 +-- truncate_limit: 100 +SELECT * FROM perform_test +-- +TABLE: name="perform_test" schema="" table="perform_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM perform_test" +== 368 +-- truncate_limit: 100 +drop table perform_test +-- +TABLE: name="perform_test" schema="" table="perform_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE perform_test" +== 369 +-- truncate_limit: 100 +|-- +-- Test proper snapshot handling in simple expressions +|-- + +create temp table users(login text, id serial) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE users (login text, id serial)" +== 370 +-- truncate_limit: 100 +create function sp_id_user(a_login text) returns int as $$ +declare x int; +begin + select into x id from users where login = a_login; + if found then return x; end if; + return 0; +end$$ language plpgsql stable +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sp_id_user(a_login text) RETURNS int AS $$\ndeclare x int;\nbegin\n select into x i..." +== 371 +-- truncate_limit: 100 +insert into users values('user1') +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users VALUES ('user1')" +== 372 +-- truncate_limit: 100 +select sp_id_user('user1') +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_id_user('user1')" +== 373 +-- truncate_limit: 100 +select sp_id_user('userx') +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_id_user('userx')" +== 374 +-- truncate_limit: 100 +create function sp_add_user(a_login text) returns int as $$ +declare my_id_user int; +begin + my_id_user = sp_id_user( a_login ); + IF my_id_user > 0 THEN + RETURN -1; -- error code for existing user + END IF; + INSERT INTO users ( login ) VALUES ( a_login ); + my_id_user = sp_id_user( a_login ); + IF my_id_user = 0 THEN + RETURN -2; -- error code for insertion failure + END IF; + RETURN my_id_user; +end$$ language plpgsql +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sp_add_user(a_login text) RETURNS int AS $$\ndeclare my_id_user int;\nbegin\n my_id..." +== 375 +-- truncate_limit: 100 +select sp_add_user('user1') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_add_user('user1')" +== 376 +-- truncate_limit: 100 +select sp_add_user('user2') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_add_user('user2')" +== 377 +-- truncate_limit: 100 +select sp_add_user('user2') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_add_user('user2')" +== 378 +-- truncate_limit: 100 +select sp_add_user('user3') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_add_user('user3')" +== 379 +-- truncate_limit: 100 +select sp_add_user('user3') +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_add_user('user3')" +== 380 +-- truncate_limit: 100 +drop function sp_add_user(text) +-- +FUNCTION: name="sp_add_user" function="sp_add_user" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sp_add_user(text)" +== 381 +-- truncate_limit: 100 +drop function sp_id_user(text) +-- +FUNCTION: name="sp_id_user" function="sp_id_user" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sp_id_user(text)" +== 382 +-- truncate_limit: 100 +|-- +-- tests for refcursors +|-- +create table rc_test (a int, b int) +-- +TABLE: name="rc_test" schema="" table="rc_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rc_test (a int, b int)" +== 383 +-- truncate_limit: 100 +copy rc_test from stdin +-- +TABLE: name="rc_test" schema="" table="rc_test" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY rc_test FROM STDIN" +== 384 +-- truncate_limit: 100 +create function return_unnamed_refcursor() returns refcursor as $$ +declare + rc refcursor; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="return_unnamed_refcursor" function="return_unnamed_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION return_unnamed_refcursor() RETURNS refcursor AS $$\ndeclare\n rc refcursor;\nbegi..." +== 385 +-- truncate_limit: 100 +create function use_refcursor(rc refcursor) returns int as $$ +declare + rc refcursor; + x record; +begin + rc := return_unnamed_refcursor(); + fetch next from rc into x; + return x.a; +end +$$ language plpgsql +-- +FUNCTION: name="use_refcursor" function="use_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION use_refcursor(rc refcursor) RETURNS int AS $$\ndeclare\n rc refcursor;\n x rec..." +== 386 +-- truncate_limit: 100 +select use_refcursor(return_unnamed_refcursor()) +-- +FUNCTION: name="use_refcursor" function="use_refcursor" schema="" ctx=Call +FUNCTION: name="return_unnamed_refcursor" function="return_unnamed_refcursor" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT use_refcursor(return_unnamed_refcursor())" +== 387 +-- truncate_limit: 100 +create function return_refcursor(rc refcursor) returns refcursor as $$ +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="return_refcursor" function="return_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION return_refcursor(rc refcursor) RETURNS refcursor AS $$\nbegin\n open rc for sele..." +== 388 +-- truncate_limit: 100 +create function refcursor_test1(refcursor) returns refcursor as $$ +begin + perform return_refcursor($1); + return $1; +end +$$ language plpgsql +-- +FUNCTION: name="refcursor_test1" function="refcursor_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION refcursor_test1(refcursor) RETURNS refcursor AS $$\nbegin\n perform return_refcu..." +== 389 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 390 +-- truncate_limit: 100 +select refcursor_test1('test1') +-- +FUNCTION: name="refcursor_test1" function="refcursor_test1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT refcursor_test1('test1')" +== 391 +-- truncate_limit: 100 +fetch next in test1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH test1" +== 392 +-- truncate_limit: 100 +select refcursor_test1('test2') +-- +FUNCTION: name="refcursor_test1" function="refcursor_test1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT refcursor_test1('test2')" +== 393 +-- truncate_limit: 100 +fetch all from test2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL test2" +== 394 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 395 +-- truncate_limit: 100 +-- should fail +fetch next from test1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH test1" +== 396 +-- truncate_limit: 100 +create function refcursor_test2(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; + nonsense record; +begin + open c1($1, $2); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="refcursor_test2" function="refcursor_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION refcursor_test2(int, int) RETURNS boolean AS $$\ndeclare\n c1 cursor (param1 int..." +== 397 +-- truncate_limit: 100 +select refcursor_test2(20000, 20000) as "Should be false", + refcursor_test2(20, 20) as "Should be true" +-- +FUNCTION: name="refcursor_test2" function="refcursor_test2" schema="" ctx=Call +FUNCTION: name="refcursor_test2" function="refcursor_test2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 398 +-- truncate_limit: 100 +-- should fail +create function constant_refcursor() returns refcursor as $$ +declare + rc constant refcursor; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION constant_refcursor() RETURNS refcursor AS $$\ndeclare\n rc constant refcursor;\nb..." +== 399 +-- truncate_limit: 100 +select constant_refcursor() +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT constant_refcursor()" +== 400 +-- truncate_limit: 100 +-- but it's okay like this +create or replace function constant_refcursor() returns refcursor as $$ +declare + rc constant refcursor := 'my_cursor_name'; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION constant_refcursor() RETURNS refcursor AS $$\ndeclare\n rc constant r..." +== 401 +-- truncate_limit: 100 +select constant_refcursor() +-- +FUNCTION: name="constant_refcursor" function="constant_refcursor" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT constant_refcursor()" +== 402 +-- truncate_limit: 100 +|-- +-- tests for cursors with named parameter arguments +|-- +create function namedparmcursor_test1(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param12 int) for select * from rc_test where a > param1 and b > param12; + nonsense record; +begin + open c1(param12 := $2, param1 := $1); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test1" function="namedparmcursor_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test1(int, int) RETURNS boolean AS $$\ndeclare\n c1 cursor (para..." +== 403 +-- truncate_limit: 100 +select namedparmcursor_test1(20000, 20000) as "Should be false", + namedparmcursor_test1(20, 20) as "Should be true" +-- +FUNCTION: name="namedparmcursor_test1" function="namedparmcursor_test1" schema="" ctx=Call +FUNCTION: name="namedparmcursor_test1" function="namedparmcursor_test1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 404 +-- truncate_limit: 100 +-- mixing named and positional argument notations +create function namedparmcursor_test2(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; + nonsense record; +begin + open c1(param1 := $1, $2); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test2" function="namedparmcursor_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test2(int, int) RETURNS boolean AS $$\ndeclare\n c1 cursor (para..." +== 405 +-- truncate_limit: 100 +select namedparmcursor_test2(20, 20) +-- +FUNCTION: name="namedparmcursor_test2" function="namedparmcursor_test2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT namedparmcursor_test2(20, 20)" +== 406 +-- truncate_limit: 100 +-- mixing named and positional: param2 is given twice, once in named notation +-- and second time in positional notation. Should throw an error at parse time +create function namedparmcursor_test3() returns void as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; +begin + open c1(param2 := 20, 21); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test3" function="namedparmcursor_test3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test3() RETURNS void AS $$\ndeclare\n c1 cursor (param1 int, par..." +== 407 +-- truncate_limit: 100 +-- mixing named and positional: same as previous test, but param1 is duplicated +create function namedparmcursor_test4() returns void as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; +begin + open c1(20, param1 := 21); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test4" function="namedparmcursor_test4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test4() RETURNS void AS $$\ndeclare\n c1 cursor (param1 int, par..." +== 408 +-- truncate_limit: 100 +-- duplicate named parameter, should throw an error at parse time +create function namedparmcursor_test5() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77, p2 := 42); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test5" function="namedparmcursor_test5" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test5() RETURNS void AS $$\ndeclare\n c1 cursor (p1 int, p2 int) f..." +== 409 +-- truncate_limit: 100 +-- not enough parameters, should throw an error at parse time +create function namedparmcursor_test6() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77); +end +$$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test6" function="namedparmcursor_test6" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test6() RETURNS void AS $$\ndeclare\n c1 cursor (p1 int, p2 int) f..." +== 410 +-- truncate_limit: 100 +-- division by zero runtime error, the context given in the error message +-- should be sensible +create function namedparmcursor_test7() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77, p1 := 42/0); +end $$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test7" function="namedparmcursor_test7" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test7() RETURNS void AS $$\ndeclare\n c1 cursor (p1 int, p2 int) f..." +== 411 +-- truncate_limit: 100 +select namedparmcursor_test7() +-- +FUNCTION: name="namedparmcursor_test7" function="namedparmcursor_test7" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT namedparmcursor_test7()" +== 412 +-- truncate_limit: 100 +-- check that line comments work correctly within the argument list +-- (this used to require a special hack in the code; it no longer does, +-- but let's keep the test anyway) +create function namedparmcursor_test8() returns int4 as $$ +declare + c1 cursor (p1 int, p2 int) for + select count(*) from tenk1 where thousand = p1 and tenthous = p2; + n int4; +begin + open c1 (77 -- test + , 42); + fetch c1 into n; + return n; +end $$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test8" function="namedparmcursor_test8" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test8() RETURNS int4 AS $$\ndeclare\n c1 cursor (p1 int, p2 int) f..." +== 413 +-- truncate_limit: 100 +select namedparmcursor_test8() +-- +FUNCTION: name="namedparmcursor_test8" function="namedparmcursor_test8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT namedparmcursor_test8()" +== 414 +-- truncate_limit: 100 +-- cursor parameter name can match plpgsql variable or unreserved keyword +create function namedparmcursor_test9(p1 int) returns int4 as $$ +declare + c1 cursor (p1 int, p2 int, debug int) for + select count(*) from tenk1 where thousand = p1 and tenthous = p2 + and four = debug; + p2 int4 := 1006; + n int4; +begin + open c1 (p1 := p1, p2 := p2, debug := 2); + fetch c1 into n; + return n; +end $$ language plpgsql +-- +FUNCTION: name="namedparmcursor_test9" function="namedparmcursor_test9" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namedparmcursor_test9(p1 int) RETURNS int4 AS $$\ndeclare\n c1 cursor (p1 int, p2 ..." +== 415 +-- truncate_limit: 100 +select namedparmcursor_test9(6) +-- +FUNCTION: name="namedparmcursor_test9" function="namedparmcursor_test9" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT namedparmcursor_test9(6)" +== 416 +-- truncate_limit: 100 +|-- +-- tests for "raise" processing +|-- +create function raise_test1(int) returns int as $$ +begin + raise notice 'This message has too many parameters!', $1; + return $1; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test1" function="raise_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION raise_test1(int) RETURNS int AS $$\nbegin\n raise notice 'This message has too m..." +== 417 +-- truncate_limit: 100 +create function raise_test2(int) returns int as $$ +begin + raise notice 'This message has too few parameters: %, %, %', $1, $1; + return $1; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test2" function="raise_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION raise_test2(int) RETURNS int AS $$\nbegin\n raise notice 'This message has too f..." +== 418 +-- truncate_limit: 100 +create function raise_test3(int) returns int as $$ +begin + raise notice 'This message has no parameters (despite having %% signs in it)!'; + return $1; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test3" function="raise_test3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION raise_test3(int) RETURNS int AS $$\nbegin\n raise notice 'This message has no pa..." +== 419 +-- truncate_limit: 100 +select raise_test3(1) +-- +FUNCTION: name="raise_test3" function="raise_test3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test3(1)" +== 420 +-- truncate_limit: 100 +-- Test re-RAISE inside a nested exception block. This case is allowed +-- by Oracle's PL/SQL but was handled differently by PG before 9.1. + +CREATE FUNCTION reraise_test() RETURNS void AS $$ +BEGIN + BEGIN + RAISE syntax_error; + EXCEPTION + WHEN syntax_error THEN + BEGIN + raise notice 'exception % thrown in inner block, reraising', sqlerrm; + RAISE; + EXCEPTION + WHEN OTHERS THEN + raise notice 'RIGHT - exception % caught in inner block', sqlerrm; + END; + END; +EXCEPTION + WHEN OTHERS THEN + raise notice 'WRONG - exception % caught in outer block', sqlerrm; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="reraise_test" function="reraise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION reraise_test() RETURNS void AS $$\nBEGIN\n BEGIN\n RAISE syntax_error;\n EX..." +== 421 +-- truncate_limit: 100 +SELECT reraise_test() +-- +FUNCTION: name="reraise_test" function="reraise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reraise_test()" +== 422 +-- truncate_limit: 100 +|-- +-- reject function definitions that contain malformed SQL queries at +-- compile-time, where possible +|-- +create function bad_sql1() returns int as $$ +declare a int; +begin + a := 5; + Johnny Yuma; + a := 10; + return a; +end$$ language plpgsql +-- +FUNCTION: name="bad_sql1" function="bad_sql1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bad_sql1() RETURNS int AS $$\ndeclare a int;\nbegin\n a := 5;\n Johnny Yuma;\n ..." +== 423 +-- truncate_limit: 100 +create function bad_sql2() returns int as $$ +declare r record; +begin + for r in select I fought the law, the law won LOOP + raise notice 'in loop'; + end loop; + return 5; +end;$$ language plpgsql +-- +FUNCTION: name="bad_sql2" function="bad_sql2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bad_sql2() RETURNS int AS $$\ndeclare r record;\nbegin\n for r in select I fought..." +== 424 +-- truncate_limit: 100 +-- a RETURN expression is mandatory, except for void-returning +-- functions, where it is not allowed +create function missing_return_expr() returns int as $$ +begin + return ; +end;$$ language plpgsql +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION missing_return_expr() RETURNS int AS $$\nbegin\n return ;\nend;$$ LANGUAGE plpgsql" +== 425 +-- truncate_limit: 100 +create function void_return_expr() returns void as $$ +begin + return 5; +end;$$ language plpgsql +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION void_return_expr() RETURNS void AS $$\nbegin\n return 5;\nend;$$ LANGUAGE plpgsql" +== 426 +-- truncate_limit: 100 +-- VOID functions are allowed to omit RETURN +create function void_return_expr() returns void as $$ +begin + perform 2+2; +end;$$ language plpgsql +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION void_return_expr() RETURNS void AS $$\nbegin\n perform 2+2;\nend;$$ LANGUAGE plpgsql" +== 427 +-- truncate_limit: 100 +select void_return_expr() +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT void_return_expr()" +== 428 +-- truncate_limit: 100 +-- but ordinary functions are not +create function missing_return_expr() returns int as $$ +begin + perform 2+2; +end;$$ language plpgsql +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION missing_return_expr() RETURNS int AS $$\nbegin\n perform 2+2;\nend;$$ LANGUAGE pl..." +== 429 +-- truncate_limit: 100 +select missing_return_expr() +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT missing_return_expr()" +== 430 +-- truncate_limit: 100 +drop function void_return_expr() +-- +FUNCTION: name="void_return_expr" function="void_return_expr" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION void_return_expr()" +== 431 +-- truncate_limit: 100 +drop function missing_return_expr() +-- +FUNCTION: name="missing_return_expr" function="missing_return_expr" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION missing_return_expr()" +== 432 +-- truncate_limit: 100 +|-- +-- EXECUTE ... INTO test +|-- + +create table eifoo (i integer, y integer) +-- +TABLE: name="eifoo" schema="" table="eifoo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE eifoo (i int, y int)" +== 433 +-- truncate_limit: 100 +create type eitype as (i integer, y integer) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE eitype AS (i int, y int)" +== 434 +-- truncate_limit: 100 +create or replace function execute_into_test(varchar) returns record as $$ +declare + _r record; + _rt eifoo%rowtype; + _v eitype; + i int; + j int; + k int; +begin + execute 'insert into '||$1||' values(10,15)'; + execute 'select (row).* from (select row(10,1)::eifoo) s' into _r; + raise notice '% %', _r.i, _r.y; + execute 'select * from '||$1||' limit 1' into _rt; + raise notice '% %', _rt.i, _rt.y; + execute 'select *, 20 from '||$1||' limit 1' into i, j, k; + raise notice '% % %', i, j, k; + execute 'select 1,2' into _v; + return _v; +end; $$ language plpgsql +-- +FUNCTION: name="execute_into_test" function="execute_into_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION execute_into_test(varchar) RETURNS record AS $$\ndeclare\n _r record;..." +== 435 +-- truncate_limit: 100 +select execute_into_test('eifoo') +-- +FUNCTION: name="execute_into_test" function="execute_into_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT execute_into_test('eifoo')" +== 436 +-- truncate_limit: 100 +drop table eifoo cascade +-- +TABLE: name="eifoo" schema="" table="eifoo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE eifoo CASCADE" +== 437 +-- truncate_limit: 100 +drop type eitype cascade +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE eitype CASCADE" +== 438 +-- truncate_limit: 100 +|-- +-- SQLSTATE and SQLERRM test +|-- + +create function excpt_test1() returns void as $$ +begin + raise notice '% %', sqlstate, sqlerrm; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test1" function="excpt_test1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION excpt_test1() RETURNS void AS $$\nbegin\n raise notice '% %', sqlstate, sqlerrm;..." +== 439 +-- truncate_limit: 100 +-- should fail: SQLSTATE and SQLERRM are only in defined EXCEPTION +-- blocks +select excpt_test1() +-- +FUNCTION: name="excpt_test1" function="excpt_test1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT excpt_test1()" +== 440 +-- truncate_limit: 100 +create function excpt_test2() returns void as $$ +begin + begin + begin + raise notice '% %', sqlstate, sqlerrm; + end; + end; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test2" function="excpt_test2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION excpt_test2() RETURNS void AS $$\nbegin\n begin\n begin\n raise ..." +== 441 +-- truncate_limit: 100 +-- should fail +select excpt_test2() +-- +FUNCTION: name="excpt_test2" function="excpt_test2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT excpt_test2()" +== 442 +-- truncate_limit: 100 +create function excpt_test3() returns void as $$ +begin + begin + raise exception 'user exception'; + exception when others then + raise notice 'caught exception % %', sqlstate, sqlerrm; + begin + raise notice '% %', sqlstate, sqlerrm; + perform 10/0; + exception + when substring_error then + -- this exception handler shouldn't be invoked + raise notice 'unexpected exception: % %', sqlstate, sqlerrm; + when division_by_zero then + raise notice 'caught exception % %', sqlstate, sqlerrm; + end; + raise notice '% %', sqlstate, sqlerrm; + end; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test3" function="excpt_test3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION excpt_test3() RETURNS void AS $$\nbegin\n begin\n raise exception 'user ex..." +== 443 +-- truncate_limit: 100 +select excpt_test3() +-- +FUNCTION: name="excpt_test3" function="excpt_test3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT excpt_test3()" +== 444 +-- truncate_limit: 100 +create function excpt_test4() returns text as $$ +begin + begin perform 1/0; + exception when others then return sqlerrm; end; +end; $$ language plpgsql +-- +FUNCTION: name="excpt_test4" function="excpt_test4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION excpt_test4() RETURNS text AS $$\nbegin\n\tbegin perform 1/0;\n\texception when others..." +== 445 +-- truncate_limit: 100 +select excpt_test4() +-- +FUNCTION: name="excpt_test4" function="excpt_test4" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT excpt_test4()" +== 446 +-- truncate_limit: 100 +drop function excpt_test1() +-- +FUNCTION: name="excpt_test1" function="excpt_test1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION excpt_test1()" +== 447 +-- truncate_limit: 100 +drop function excpt_test2() +-- +FUNCTION: name="excpt_test2" function="excpt_test2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION excpt_test2()" +== 448 +-- truncate_limit: 100 +drop function excpt_test3() +-- +FUNCTION: name="excpt_test3" function="excpt_test3" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION excpt_test3()" +== 449 +-- truncate_limit: 100 +drop function excpt_test4() +-- +FUNCTION: name="excpt_test4" function="excpt_test4" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION excpt_test4()" +== 450 +-- truncate_limit: 100 +-- parameters of raise stmt can be expressions +create function raise_exprs() returns void as $$ +declare + a integer[] = '{10,20,30}'; + c varchar = 'xyz'; + i integer; +begin + i := 2; + raise notice '%; %; %; %; %; %', a, a[i], c, (select c || 'abc'), row(10,'aaa',NULL,30), NULL; +end;$$ language plpgsql +-- +FUNCTION: name="raise_exprs" function="raise_exprs" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION raise_exprs() RETURNS void AS $$\ndeclare\n a integer[] = '{10,20,30}';\n c va..." +== 451 +-- truncate_limit: 100 +select raise_exprs() +-- +FUNCTION: name="raise_exprs" function="raise_exprs" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_exprs()" +== 452 +-- truncate_limit: 100 +drop function raise_exprs() +-- +FUNCTION: name="raise_exprs" function="raise_exprs" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION raise_exprs()" +== 453 +-- truncate_limit: 100 +-- regression test: verify that multiple uses of same plpgsql datum within +-- a SQL command all get mapped to the same $n parameter. The return value +-- of the SELECT is not important, we only care that it doesn't fail with +-- a complaint about an ungrouped column reference. +create function multi_datum_use(p1 int) returns bool as $$ +declare + x int; + y int; +begin + select into x,y unique1/p1, unique1/$1 from tenk1 group by unique1/p1; + return x = y; +end$$ language plpgsql +-- +FUNCTION: name="multi_datum_use" function="multi_datum_use" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION multi_datum_use(p1 int) RETURNS bool AS $$\ndeclare\n x int;\n y int;\nbegin\n sele..." +== 454 +-- truncate_limit: 100 +select multi_datum_use(42) +-- +FUNCTION: name="multi_datum_use" function="multi_datum_use" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT multi_datum_use(42)" +== 455 +-- truncate_limit: 100 +|-- +-- Test STRICT limiter in both planned and EXECUTE invocations. +-- Note that a data-modifying query is quasi strict (disallow multi rows) +-- by default in the planned case, but not in EXECUTE. +|-- + +create temp table foo (f1 int, f2 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (f1 int, f2 int)" +== 456 +-- truncate_limit: 100 +insert into foo values (1,2), (3,4) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (1, 2), (3, 4)" +== 457 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + insert into foo values(5,6) returning * into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should wo..." +== 458 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 459 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail due to implicit strict + insert into foo values(7,8),(9,10) returning * into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should fa..." +== 460 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 461 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + execute 'insert into foo values(5,6) returning *' into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should wo..." +== 462 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 463 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- this should work since EXECUTE isn't as picky + execute 'insert into foo values(7,8),(9,10) returning *' into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- this shou..." +== 464 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 465 +-- truncate_limit: 100 +select * from foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 466 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + select * from foo where f1 = 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should wo..." +== 467 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 468 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, no rows + select * from foo where f1 = 0 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should fa..." +== 469 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 470 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, too many rows + select * from foo where f1 > 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should fa..." +== 471 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 472 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + execute 'select * from foo where f1 = 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should wo..." +== 473 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 474 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, no rows + execute 'select * from foo where f1 = 0' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should fa..." +== 475 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 476 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, too many rows + execute 'select * from foo where f1 > 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- should fa..." +== 477 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 478 +-- truncate_limit: 100 +drop function stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION stricttest()" +== 479 +-- truncate_limit: 100 +-- test printing parameters after failure due to STRICT + +set plpgsql.print_strict_params to true +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.print_strict_params\" TO TRUE" +== 480 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- no rows + select * from foo where f1 = p1 and f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare\nx record;\np1 int := 2;\np3 text..." +== 481 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 482 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := $a$'Valame Dios!' dijo Sancho; 'no le dije yo a vuestra merced que mirase bien lo que hacia?'$a$; +begin + -- no rows + select * from foo where f1 = p1 and f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare\nx record;\np1 int := 2;\np3 text..." +== 483 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 484 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare\nx record;\np1 int := 2;\np3 text..." +== 485 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 486 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows, no params + select * from foo where f1 > 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- too many ..." +== 487 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 488 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- no rows + execute 'select * from foo where f1 = $1 or f1::text = $2' using 0, 'foo' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- no rows\n ..." +== 489 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 490 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows + execute 'select * from foo where f1 > $1' using 1 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- too many ..." +== 491 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 492 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows, no parameters + execute 'select * from foo where f1 > 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\ndeclare x record;\nbegin\n -- too many ..." +== 493 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 494 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +-- override the global +#print_strict_params off +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\n-- override the global\n#print_strict_p..." +== 495 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 496 +-- truncate_limit: 100 +reset plpgsql.print_strict_params +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.print_strict_params\"" +== 497 +-- truncate_limit: 100 +create or replace function stricttest() returns void as $$ +-- override the global +#print_strict_params on +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stricttest() RETURNS void AS $$\n-- override the global\n#print_strict_p..." +== 498 +-- truncate_limit: 100 +select stricttest() +-- +FUNCTION: name="stricttest" function="stricttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stricttest()" +== 499 +-- truncate_limit: 100 +-- test warnings and errors +set plpgsql.extra_warnings to 'all' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_warnings\" TO \"all\"" +== 500 +-- truncate_limit: 100 +set plpgsql.extra_warnings to 'none' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_warnings\" TO \"none\"" +== 501 +-- truncate_limit: 100 +set plpgsql.extra_errors to 'all' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_errors\" TO \"all\"" +== 502 +-- truncate_limit: 100 +set plpgsql.extra_errors to 'none' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_errors\" TO \"none\"" +== 503 +-- truncate_limit: 100 +-- test warnings when shadowing a variable + +set plpgsql.extra_warnings to 'shadowed_variables' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_warnings\" TO shadowed_variables" +== 504 +-- truncate_limit: 100 +-- simple shadowing of input and output parameters +create or replace function shadowtest(in1 int) + returns table (out1 int) as $$ +declare +in1 int; +out1 int; +begin +end +$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION shadowtest(in1 int) RETURNS TABLE (out1 int) AS $$\ndeclare\nin1 int;\nou..." +== 505 +-- truncate_limit: 100 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT shadowtest(1)" +== 506 +-- truncate_limit: 100 +set plpgsql.extra_warnings to 'shadowed_variables' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_warnings\" TO shadowed_variables" +== 507 +-- truncate_limit: 100 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT shadowtest(1)" +== 508 +-- truncate_limit: 100 +create or replace function shadowtest(in1 int) + returns table (out1 int) as $$ +declare +in1 int; +out1 int; +begin +end +$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION shadowtest(in1 int) RETURNS TABLE (out1 int) AS $$\ndeclare\nin1 int;\nou..." +== 509 +-- truncate_limit: 100 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT shadowtest(1)" +== 510 +-- truncate_limit: 100 +drop function shadowtest(int) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION shadowtest(int)" +== 511 +-- truncate_limit: 100 +-- shadowing in a second DECLARE block +create or replace function shadowtest() + returns void as $$ +declare +f1 int; +begin + declare + f1 int; + begin + end; +end$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION shadowtest() RETURNS void AS $$\ndeclare\nf1 int;\nbegin\n\tdeclare\n\tf1 int..." +== 512 +-- truncate_limit: 100 +drop function shadowtest() +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION shadowtest()" +== 513 +-- truncate_limit: 100 +-- several levels of shadowing +create or replace function shadowtest(in1 int) + returns void as $$ +declare +in1 int; +begin + declare + in1 int; + begin + end; +end$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION shadowtest(in1 int) RETURNS void AS $$\ndeclare\nin1 int;\nbegin\n\tdeclare..." +== 514 +-- truncate_limit: 100 +drop function shadowtest(int) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION shadowtest(int)" +== 515 +-- truncate_limit: 100 +-- shadowing in cursor definitions +create or replace function shadowtest() + returns void as $$ +declare +f1 int; +c1 cursor (f1 int) for select 1; +begin +end$$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION shadowtest() RETURNS void AS $$\ndeclare\nf1 int;\nc1 cursor (f1 int) for..." +== 516 +-- truncate_limit: 100 +drop function shadowtest() +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION shadowtest()" +== 517 +-- truncate_limit: 100 +-- test errors when shadowing a variable + +set plpgsql.extra_errors to 'shadowed_variables' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_errors\" TO shadowed_variables" +== 518 +-- truncate_limit: 100 +create or replace function shadowtest(f1 int) + returns boolean as $$ +declare f1 int; begin return 1; end $$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION shadowtest(f1 int) RETURNS boolean AS $$\ndeclare f1 int; begin return ..." +== 519 +-- truncate_limit: 100 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT shadowtest(1)" +== 520 +-- truncate_limit: 100 +reset plpgsql.extra_errors +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.extra_errors\"" +== 521 +-- truncate_limit: 100 +reset plpgsql.extra_warnings +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.extra_warnings\"" +== 522 +-- truncate_limit: 100 +create or replace function shadowtest(f1 int) + returns boolean as $$ +declare f1 int; begin return 1; end $$ language plpgsql +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION shadowtest(f1 int) RETURNS boolean AS $$\ndeclare f1 int; begin return ..." +== 523 +-- truncate_limit: 100 +select shadowtest(1) +-- +FUNCTION: name="shadowtest" function="shadowtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT shadowtest(1)" +== 524 +-- truncate_limit: 100 +-- runtime extra checks +set plpgsql.extra_warnings to 'too_many_rows' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_warnings\" TO too_many_rows" +== 525 +-- truncate_limit: 100 +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare x int;\nbegin\n select v from generate_series(1,2) g(v) into x;\nend;\n$$" +== 526 +-- truncate_limit: 100 +set plpgsql.extra_errors to 'too_many_rows' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_errors\" TO too_many_rows" +== 527 +-- truncate_limit: 100 +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare x int;\nbegin\n select v from generate_series(1,2) g(v) into x;\nend;\n$$" +== 528 +-- truncate_limit: 100 +reset plpgsql.extra_errors +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.extra_errors\"" +== 529 +-- truncate_limit: 100 +reset plpgsql.extra_warnings +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.extra_warnings\"" +== 530 +-- truncate_limit: 100 +set plpgsql.extra_warnings to 'strict_multi_assignment' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_warnings\" TO strict_multi_assignment" +== 531 +-- truncate_limit: 100 +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare\n x int;\n y int;\nbegin\n select 1 into x, y;\n select 1,2 into x, y;\n select 1,2,..." +== 532 +-- truncate_limit: 100 +set plpgsql.extra_errors to 'strict_multi_assignment' +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.extra_errors\" TO strict_multi_assignment" +== 533 +-- truncate_limit: 100 +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare\n x int;\n y int;\nbegin\n select 1 into x, y;\n select 1,2 into x, y;\n select 1,2,..." +== 534 +-- truncate_limit: 100 +create table test_01(a int, b int, c int) +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_01 (a int, b int, c int)" +== 535 +-- truncate_limit: 100 +alter table test_01 drop column a +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_01 DROP a" +== 536 +-- truncate_limit: 100 +-- the check is active only when source table is not empty +insert into test_01 values(10,20) +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_01 VALUES (10, 20)" +== 537 +-- truncate_limit: 100 +do $$ +declare + x int; + y int; +begin + select * from test_01 into x, y; -- should be ok + raise notice 'ok'; + select * from test_01 into x; -- should to fail +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare\n x int;\n y int;\nbegin\n select * from test_01 into x, y; -- should be ok\n raise ..." +== 538 +-- truncate_limit: 100 +do $$ +declare + t test_01; +begin + select 1, 2 into t; -- should be ok + raise notice 'ok'; + select 1, 2, 3 into t; -- should fail; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare\n t test_01;\nbegin\n select 1, 2 into t; -- should be ok\n raise notice 'ok';\n se..." +== 539 +-- truncate_limit: 100 +do $$ +declare + t test_01; +begin + select 1 into t; -- should fail; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare\n t test_01;\nbegin\n select 1 into t; -- should fail;\nend;\n$$" +== 540 +-- truncate_limit: 100 +drop table test_01 +-- +TABLE: name="test_01" schema="" table="test_01" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_01" +== 541 +-- truncate_limit: 100 +reset plpgsql.extra_errors +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.extra_errors\"" +== 542 +-- truncate_limit: 100 +reset plpgsql.extra_warnings +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.extra_warnings\"" +== 543 +-- truncate_limit: 100 +-- test scrollable cursor support + +create function sc_test() returns setof integer as $$ +declare + c scroll cursor for select f1 from int4_tbl; + x integer; +begin + open c; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sc_test() RETURNS SETOF int AS $$\ndeclare\n c scroll cursor for select f1 from in..." +== 544 +-- truncate_limit: 100 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sc_test()" +== 545 +-- truncate_limit: 100 +create or replace function sc_test() returns setof integer as $$ +declare + c no scroll cursor for select f1 from int4_tbl; + x integer; +begin + open c; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION sc_test() RETURNS SETOF int AS $$\ndeclare\n c no scroll cursor for sel..." +== 546 +-- truncate_limit: 100 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sc_test()" +== 547 +-- truncate_limit: 100 +-- fails because of NO SCROLL specification + +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for select f1 from int4_tbl; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION sc_test() RETURNS SETOF int AS $$\ndeclare\n c refcursor;\n x integer;\n..." +== 548 +-- truncate_limit: 100 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sc_test()" +== 549 +-- truncate_limit: 100 +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for execute 'select f1 from int4_tbl'; + fetch last from c into x; + while found loop + return next x; + fetch relative -2 from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION sc_test() RETURNS SETOF int AS $$\ndeclare\n c refcursor;\n x integer;\n..." +== 550 +-- truncate_limit: 100 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sc_test()" +== 551 +-- truncate_limit: 100 +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for execute 'select f1 from int4_tbl'; + fetch last from c into x; + while found loop + return next x; + move backward 2 from c; + fetch relative -1 from c into x; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION sc_test() RETURNS SETOF int AS $$\ndeclare\n c refcursor;\n x integer;\n..." +== 552 +-- truncate_limit: 100 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sc_test()" +== 553 +-- truncate_limit: 100 +create or replace function sc_test() returns setof integer as $$ +declare + c cursor for select * from generate_series(1, 10); + x integer; +begin + open c; + loop + move relative 2 in c; + if not found then + exit; + end if; + fetch next from c into x; + if found then + return next x; + end if; + end loop; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION sc_test() RETURNS SETOF int AS $$\ndeclare\n c cursor for select * from..." +== 554 +-- truncate_limit: 100 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sc_test()" +== 555 +-- truncate_limit: 100 +create or replace function sc_test() returns setof integer as $$ +declare + c cursor for select * from generate_series(1, 10); + x integer; +begin + open c; + move forward all in c; + fetch backward from c into x; + if found then + return next x; + end if; + close c; +end; +$$ language plpgsql +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION sc_test() RETURNS SETOF int AS $$\ndeclare\n c cursor for select * from..." +== 556 +-- truncate_limit: 100 +select * from sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sc_test()" +== 557 +-- truncate_limit: 100 +drop function sc_test() +-- +FUNCTION: name="sc_test" function="sc_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sc_test()" +== 558 +-- truncate_limit: 100 +-- test qualified variable names + +create function pl_qual_names (param1 int) returns void as $$ +<> +declare + param1 int := 1; +begin + <> + declare + param1 int := 2; + begin + raise notice 'param1 = %', param1; + raise notice 'pl_qual_names.param1 = %', pl_qual_names.param1; + raise notice 'outerblock.param1 = %', outerblock.param1; + raise notice 'innerblock.param1 = %', innerblock.param1; + end; +end; +$$ language plpgsql +-- +FUNCTION: name="pl_qual_names" function="pl_qual_names" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pl_qual_names(param1 int) RETURNS void AS $$\n<>\ndeclare\n param1 int ..." +== 559 +-- truncate_limit: 100 +select pl_qual_names(42) +-- +FUNCTION: name="pl_qual_names" function="pl_qual_names" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pl_qual_names(42)" +== 560 +-- truncate_limit: 100 +drop function pl_qual_names(int) +-- +FUNCTION: name="pl_qual_names" function="pl_qual_names" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION pl_qual_names(int)" +== 561 +-- truncate_limit: 100 +-- tests for RETURN QUERY +create function ret_query1(out int, out int) returns setof record as $$ +begin + $1 := -1; + $2 := -2; + return next; + return query select x + 1, x * 10 from generate_series(0, 10) s (x); + return next; +end; +$$ language plpgsql +-- +FUNCTION: name="ret_query1" function="ret_query1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ret_query1(OUT int, OUT int) RETURNS SETOF record AS $$\nbegin\n $1 := -1;\n $..." +== 562 +-- truncate_limit: 100 +select * from ret_query1() +-- +FUNCTION: name="ret_query1" function="ret_query1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ret_query1()" +== 563 +-- truncate_limit: 100 +create type record_type as (x text, y int, z boolean) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE record_type AS (x text, y int, z boolean)" +== 564 +-- truncate_limit: 100 +create or replace function ret_query2(lim int) returns setof record_type as $$ +begin + return query select fipshash(s.x::text), s.x, s.x > 0 + from generate_series(-8, lim) s (x) where s.x % 2 = 0; +end; +$$ language plpgsql +-- +FUNCTION: name="ret_query2" function="ret_query2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION ret_query2(lim int) RETURNS SETOF record_type AS $$\nbegin\n return q..." +== 565 +-- truncate_limit: 100 +select * from ret_query2(8) +-- +FUNCTION: name="ret_query2" function="ret_query2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ret_query2(8)" +== 566 +-- truncate_limit: 100 +-- test EXECUTE USING +create function exc_using(int, text) returns int as $$ +declare i int; +begin + for i in execute 'select * from generate_series(1,$1)' using $1+1 loop + raise notice '%', i; + end loop; + execute 'select $2 + $2*3 + length($1)' into i using $2,$1; + return i; +end +$$ language plpgsql +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION exc_using(int, text) RETURNS int AS $$\ndeclare i int;\nbegin\n for i in execute 's..." +== 567 +-- truncate_limit: 100 +select exc_using(5, 'foobar') +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exc_using(5, 'foobar')" +== 568 +-- truncate_limit: 100 +drop function exc_using(int, text) +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION exc_using(int, text)" +== 569 +-- truncate_limit: 100 +create or replace function exc_using(int) returns void as $$ +declare + c refcursor; + i int; +begin + open c for execute 'select * from generate_series(1,$1)' using $1+1; + loop + fetch c into i; + exit when not found; + raise notice '%', i; + end loop; + close c; + return; +end; +$$ language plpgsql +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION exc_using(int) RETURNS void AS $$\ndeclare\n c refcursor;\n i int;\nbegi..." +== 570 +-- truncate_limit: 100 +select exc_using(5) +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT exc_using(5)" +== 571 +-- truncate_limit: 100 +drop function exc_using(int) +-- +FUNCTION: name="exc_using" function="exc_using" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION exc_using(int)" +== 572 +-- truncate_limit: 100 +-- test FOR-over-cursor + +create or replace function forc01() returns void as $$ +declare + c cursor(r1 integer, r2 integer) + for select * from generate_series(r1,r2) i; + c2 cursor + for select * from generate_series(41,43) i; +begin + -- assign portal names to cursors to get stable output + c := 'c'; + c2 := 'c2'; + for r in c(5,7) loop + raise notice '% from %', r.i, c; + end loop; + -- again, to test if cursor was closed properly + for r in c(9,10) loop + raise notice '% from %', r.i, c; + end loop; + -- and test a parameterless cursor + for r in c2 loop + raise notice '% from %', r.i, c2; + end loop; + -- and try it with a hand-assigned name + raise notice 'after loop, c2 = %', c2; + c2 := 'special_name'; + for r in c2 loop + raise notice '% from %', r.i, c2; + end loop; + raise notice 'after loop, c2 = %', c2; + -- and try it with a generated name + -- (which we can't show in the output because it's variable) + c2 := null; + for r in c2 loop + raise notice '%', r.i; + end loop; + raise notice 'after loop, c2 = %', c2; + return; +end; +$$ language plpgsql +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION forc01() RETURNS void AS $$\ndeclare\n c cursor(r1 integer, r2 integer)..." +== 573 +-- truncate_limit: 100 +select forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT forc01()" +== 574 +-- truncate_limit: 100 +-- try updating the cursor's current row + +create temp table forc_test as + select n as i, n as j from generate_series(1,10) n +-- +TABLE: name="forc_test" schema="" table="forc_test" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE forc_test AS SELECT n AS i, n AS j FROM generate_series(1, 10) n" +== 575 +-- truncate_limit: 100 +create or replace function forc01() returns void as $$ +declare + c cursor for select * from forc_test; +begin + for r in c loop + raise notice '%, %', r.i, r.j; + update forc_test set i = i * 100, j = r.j * 2 where current of c; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION forc01() RETURNS void AS $$\ndeclare\n c cursor for select * from forc_..." +== 576 +-- truncate_limit: 100 +select forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT forc01()" +== 577 +-- truncate_limit: 100 +select * from forc_test +-- +TABLE: name="forc_test" schema="" table="forc_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM forc_test" +== 578 +-- truncate_limit: 100 +-- same, with a cursor whose portal name doesn't match variable name +create or replace function forc01() returns void as $$ +declare + c refcursor := 'fooled_ya'; + r record; +begin + open c for select * from forc_test; + loop + fetch c into r; + exit when not found; + raise notice '%, %', r.i, r.j; + update forc_test set i = i * 100, j = r.j * 2 where current of c; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION forc01() RETURNS void AS $$\ndeclare\n c refcursor := 'fooled_ya';\n r ..." +== 579 +-- truncate_limit: 100 +select forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT forc01()" +== 580 +-- truncate_limit: 100 +select * from forc_test +-- +TABLE: name="forc_test" schema="" table="forc_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM forc_test" +== 581 +-- truncate_limit: 100 +drop function forc01() +-- +FUNCTION: name="forc01" function="forc01" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION forc01()" +== 582 +-- truncate_limit: 100 +-- it's okay to re-use a cursor variable name, even when bound + +do $$ +declare cnt int := 0; + c1 cursor for select * from forc_test; +begin + for r1 in c1 loop + declare c1 cursor for select * from forc_test; + begin + for r2 in c1 loop + cnt := cnt + 1; + end loop; + end; + end loop; + raise notice 'cnt = %', cnt; +end $$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare cnt int := 0;\n c1 cursor for select * from forc_test;\nbegin\n for r1 in c1 loop\n ..." +== 583 +-- truncate_limit: 100 +-- fail because cursor has no query bound to it + +create or replace function forc_bad() returns void as $$ +declare + c refcursor; +begin + for r in c loop + raise notice '%', r.i; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="forc_bad" function="forc_bad" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION forc_bad() RETURNS void AS $$\ndeclare\n c refcursor;\nbegin\n for r in ..." +== 584 +-- truncate_limit: 100 +-- test RETURN QUERY EXECUTE + +create or replace function return_dquery() +returns setof int as $$ +begin + return query execute 'select * from (values(10),(20)) f'; + return query execute 'select * from (values($1),($2)) f' using 40,50; +end; +$$ language plpgsql +-- +FUNCTION: name="return_dquery" function="return_dquery" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION return_dquery() RETURNS SETOF int AS $$\nbegin\n return query execute '..." +== 585 +-- truncate_limit: 100 +select * from return_dquery() +-- +FUNCTION: name="return_dquery" function="return_dquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM return_dquery()" +== 586 +-- truncate_limit: 100 +drop function return_dquery() +-- +FUNCTION: name="return_dquery" function="return_dquery" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION return_dquery()" +== 587 +-- truncate_limit: 100 +-- test RETURN QUERY with dropped columns + +create table tabwithcols(a int, b int, c int, d int) +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tabwithcols (a int, b int, c int, d int)" +== 588 +-- truncate_limit: 100 +insert into tabwithcols values(10,20,30,40),(50,60,70,80) +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tabwithcols VALUES (10, 20, 30, 40), (50, 60, 70, 80)" +== 589 +-- truncate_limit: 100 +create or replace function returnqueryf() +returns setof tabwithcols as $$ +begin + return query select * from tabwithcols; + return query execute 'select * from tabwithcols'; +end; +$$ language plpgsql +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION returnqueryf() RETURNS SETOF tabwithcols AS $$\nbegin\n return query se..." +== 590 +-- truncate_limit: 100 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM returnqueryf()" +== 591 +-- truncate_limit: 100 +alter table tabwithcols drop column b +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tabwithcols DROP b" +== 592 +-- truncate_limit: 100 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM returnqueryf()" +== 593 +-- truncate_limit: 100 +alter table tabwithcols drop column d +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tabwithcols DROP d" +== 594 +-- truncate_limit: 100 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM returnqueryf()" +== 595 +-- truncate_limit: 100 +alter table tabwithcols add column d int +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tabwithcols ADD COLUMN d int" +== 596 +-- truncate_limit: 100 +select * from returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM returnqueryf()" +== 597 +-- truncate_limit: 100 +drop function returnqueryf() +-- +FUNCTION: name="returnqueryf" function="returnqueryf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION returnqueryf()" +== 598 +-- truncate_limit: 100 +drop table tabwithcols +-- +TABLE: name="tabwithcols" schema="" table="tabwithcols" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tabwithcols" +== 599 +-- truncate_limit: 100 +|-- +-- Tests for composite-type results +|-- + +create type compostype as (x int, y varchar) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE compostype AS (x int, y varchar)" +== 600 +-- truncate_limit: 100 +-- test: use of variable of composite type in return statement +create or replace function compos() returns compostype as $$ +declare + v compostype; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS compostype AS $$\ndeclare\n v compostype;\nbegin\n v :=..." +== 601 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 602 +-- truncate_limit: 100 +-- test: use of variable of record type in return statement +create or replace function compos() returns compostype as $$ +declare + v record; +begin + v := (1, 'hello'::varchar); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS compostype AS $$\ndeclare\n v record;\nbegin\n v := (1,..." +== 603 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 604 +-- truncate_limit: 100 +-- test: use of row expr in return statement +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello'::varchar); +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS compostype AS $$\nbegin\n return (1, 'hello'::varchar)..." +== 605 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 606 +-- truncate_limit: 100 +-- this does not work currently (no implicit casting) +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello'); +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS compostype AS $$\nbegin\n return (1, 'hello');\nend;\n$$..." +== 607 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 608 +-- truncate_limit: 100 +-- ... but this does +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello')::compostype; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS compostype AS $$\nbegin\n return (1, 'hello')::compost..." +== 609 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 610 +-- truncate_limit: 100 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION compos()" +== 611 +-- truncate_limit: 100 +-- test: return a row expr as record. +create or replace function composrec() returns record as $$ +declare + v record; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION composrec() RETURNS record AS $$\ndeclare\n v record;\nbegin\n v := (1, ..." +== 612 +-- truncate_limit: 100 +select composrec() +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT composrec()" +== 613 +-- truncate_limit: 100 +-- test: return row expr in return statement. +create or replace function composrec() returns record as $$ +begin + return (1, 'hello'); +end; +$$ language plpgsql +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION composrec() RETURNS record AS $$\nbegin\n return (1, 'hello');\nend;\n$$ ..." +== 614 +-- truncate_limit: 100 +select composrec() +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT composrec()" +== 615 +-- truncate_limit: 100 +drop function composrec() +-- +FUNCTION: name="composrec" function="composrec" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION composrec()" +== 616 +-- truncate_limit: 100 +-- test: row expr in RETURN NEXT statement. +create or replace function compos() returns setof compostype as $$ +begin + for i in 1..3 + loop + return next (1, 'hello'::varchar); + end loop; + return next null::compostype; + return next (2, 'goodbye')::compostype; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS SETOF compostype AS $$\nbegin\n for i in 1..3\n loop\n ..." +== 617 +-- truncate_limit: 100 +select * from compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM compos()" +== 618 +-- truncate_limit: 100 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION compos()" +== 619 +-- truncate_limit: 100 +-- test: use invalid expr in return statement. +create or replace function compos() returns compostype as $$ +begin + return 1 + 1; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS compostype AS $$\nbegin\n return 1 + 1;\nend;\n$$ LANGUA..." +== 620 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 621 +-- truncate_limit: 100 +-- RETURN variable is a different code path ... +create or replace function compos() returns compostype as $$ +declare x int := 42; +begin + return x; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS compostype AS $$\ndeclare x int := 42;\nbegin\n return ..." +== 622 +-- truncate_limit: 100 +select * from compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM compos()" +== 623 +-- truncate_limit: 100 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION compos()" +== 624 +-- truncate_limit: 100 +-- test: invalid use of composite variable in scalar-returning function +create or replace function compos() returns int as $$ +declare + v compostype; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS int AS $$\ndeclare\n v compostype;\nbegin\n v := (1, 'h..." +== 625 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 626 +-- truncate_limit: 100 +-- test: invalid use of composite expression in scalar-returning function +create or replace function compos() returns int as $$ +begin + return (1, 'hello')::compostype; +end; +$$ language plpgsql +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION compos() RETURNS int AS $$\nbegin\n return (1, 'hello')::compostype;\nen..." +== 627 +-- truncate_limit: 100 +select compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT compos()" +== 628 +-- truncate_limit: 100 +drop function compos() +-- +FUNCTION: name="compos" function="compos" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION compos()" +== 629 +-- truncate_limit: 100 +drop type compostype +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE compostype" +== 630 +-- truncate_limit: 100 +|-- +-- Tests for 8.4's new RAISE features +|-- + +create or replace function raise_test() returns void as $$ +begin + raise notice '% % %', 1, 2, 3 + using errcode = '55001', detail = 'some detail info', hint = 'some hint'; + raise '% % %', 1, 2, 3 + using errcode = 'division_by_zero', detail = 'some detail info'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise notice '% % %', 1, 2, 3\n..." +== 631 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 632 +-- truncate_limit: 100 +-- Since we can't actually see the thrown SQLSTATE in default psql output, +-- test it like this; this also tests re-RAISE + +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = 'division_by_zero', detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise 'check me'\n using er..." +== 633 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 634 +-- truncate_limit: 100 +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = '1234F', detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise 'check me'\n using er..." +== 635 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 636 +-- truncate_limit: 100 +-- SQLSTATE specification in WHEN +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = '1234F', detail = 'some detail info'; + exception + when sqlstate '1234F' then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise 'check me'\n using er..." +== 637 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 638 +-- truncate_limit: 100 +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise division_by_zero using d..." +== 639 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 640 +-- truncate_limit: 100 +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise division_by_zero;\nend;\n$..." +== 641 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 642 +-- truncate_limit: 100 +create or replace function raise_test() returns void as $$ +begin + raise sqlstate '1234F'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise sqlstate '1234F';\nend;\n$..." +== 643 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 644 +-- truncate_limit: 100 +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using message = 'custom' || ' message'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise division_by_zero using m..." +== 645 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 646 +-- truncate_limit: 100 +create or replace function raise_test() returns void as $$ +begin + raise using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise using message = 'custom'..." +== 647 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 648 +-- truncate_limit: 100 +-- conflict on message +create or replace function raise_test() returns void as $$ +begin + raise notice 'some message' using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise notice 'some message' us..." +== 649 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 650 +-- truncate_limit: 100 +-- conflict on errcode +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise division_by_zero using m..." +== 651 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 652 +-- truncate_limit: 100 +-- nothing to re-RAISE +create or replace function raise_test() returns void as $$ +begin + raise; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise;\nend;\n$$ LANGUAGE plpgsql" +== 653 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 654 +-- truncate_limit: 100 +-- test access to exception data +create function zero_divide() returns int as $$ +declare v int := 0; +begin + return 10 / v; +end; +$$ language plpgsql parallel safe +-- +FUNCTION: name="zero_divide" function="zero_divide" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION zero_divide() RETURNS int AS $$\ndeclare v int := 0;\nbegin\n return 10 / v;\nend;\n$..." +== 655 +-- truncate_limit: 100 +create or replace function raise_test() returns void as $$ +begin + raise exception 'custom exception' + using detail = 'some detail of custom exception', + hint = 'some hint related to custom exception'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n raise exception 'custom except..." +== 656 +-- truncate_limit: 100 +create function stacked_diagnostics_test() returns void as $$ +declare _sqlstate text; + _message text; + _context text; +begin + perform zero_divide(); +exception when others then + get stacked diagnostics + _sqlstate = returned_sqlstate, + _message = message_text, + _context = pg_exception_context; + raise notice 'sqlstate: %, message: %, context: [%]', + _sqlstate, _message, replace(_context, E'\n', ' <- '); +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION stacked_diagnostics_test() RETURNS void AS $$\ndeclare _sqlstate text;\n _me..." +== 657 +-- truncate_limit: 100 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stacked_diagnostics_test()" +== 658 +-- truncate_limit: 100 +create or replace function stacked_diagnostics_test() returns void as $$ +declare _detail text; + _hint text; + _message text; +begin + perform raise_test(); +exception when others then + get stacked diagnostics + _message = message_text, + _detail = pg_exception_detail, + _hint = pg_exception_hint; + raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint; +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stacked_diagnostics_test() RETURNS void AS $$\ndeclare _detail text;\n ..." +== 659 +-- truncate_limit: 100 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stacked_diagnostics_test()" +== 660 +-- truncate_limit: 100 +-- fail, cannot use stacked diagnostics statement outside handler +create or replace function stacked_diagnostics_test() returns void as $$ +declare _detail text; + _hint text; + _message text; +begin + get stacked diagnostics + _message = message_text, + _detail = pg_exception_detail, + _hint = pg_exception_hint; + raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint; +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stacked_diagnostics_test() RETURNS void AS $$\ndeclare _detail text;\n ..." +== 661 +-- truncate_limit: 100 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stacked_diagnostics_test()" +== 662 +-- truncate_limit: 100 +drop function stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION stacked_diagnostics_test()" +== 663 +-- truncate_limit: 100 +-- Test that an error recovery subtransaction is parallel safe + +create function error_trap_test() returns text as $$ +begin + perform zero_divide(); + return 'no error detected!'; +exception when division_by_zero then + return 'division_by_zero detected'; +end; +$$ language plpgsql parallel safe +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION error_trap_test() RETURNS text AS $$\nbegin\n perform zero_divide();\n return 'no ..." +== 664 +-- truncate_limit: 100 +set debug_parallel_query to on +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO ON" +== 665 +-- truncate_limit: 100 +explain (verbose, costs off) select error_trap_test() +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT error_trap_test()" +== 666 +-- truncate_limit: 100 +select error_trap_test() +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT error_trap_test()" +== 667 +-- truncate_limit: 100 +reset debug_parallel_query +-- +STMT: VariableSetStmt +TRUNCATED: "RESET debug_parallel_query" +== 668 +-- truncate_limit: 100 +drop function error_trap_test() +-- +FUNCTION: name="error_trap_test" function="error_trap_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION error_trap_test()" +== 669 +-- truncate_limit: 100 +drop function zero_divide() +-- +FUNCTION: name="zero_divide" function="zero_divide" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION zero_divide()" +== 670 +-- truncate_limit: 100 +-- check cases where implicit SQLSTATE variable could be confused with +-- SQLSTATE as a keyword, cf bug #5524 +create or replace function raise_test() returns void as $$ +begin + perform 1/0; +exception + when sqlstate '22012' then + raise notice using message = sqlstate; + raise sqlstate '22012' using message = 'substitute message'; +end; +$$ language plpgsql +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION raise_test() RETURNS void AS $$\nbegin\n perform 1/0;\nexception\n when ..." +== 671 +-- truncate_limit: 100 +select raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT raise_test()" +== 672 +-- truncate_limit: 100 +drop function raise_test() +-- +FUNCTION: name="raise_test" function="raise_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION raise_test()" +== 673 +-- truncate_limit: 100 +-- test passing column_name, constraint_name, datatype_name, table_name +-- and schema_name error fields + +create or replace function stacked_diagnostics_test() returns void as $$ +declare _column_name text; + _constraint_name text; + _datatype_name text; + _table_name text; + _schema_name text; +begin + raise exception using + column = '>>some column name<<', + constraint = '>>some constraint name<<', + datatype = '>>some datatype name<<', + table = '>>some table name<<', + schema = '>>some schema name<<'; +exception when others then + get stacked diagnostics + _column_name = column_name, + _constraint_name = constraint_name, + _datatype_name = pg_datatype_name, + _table_name = table_name, + _schema_name = schema_name; + raise notice 'column %, constraint %, type %, table %, schema %', + _column_name, _constraint_name, _datatype_name, _table_name, _schema_name; +end; +$$ language plpgsql +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION stacked_diagnostics_test() RETURNS void AS $$\ndeclare _column_name tex..." +== 674 +-- truncate_limit: 100 +select stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stacked_diagnostics_test()" +== 675 +-- truncate_limit: 100 +drop function stacked_diagnostics_test() +-- +FUNCTION: name="stacked_diagnostics_test" function="stacked_diagnostics_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION stacked_diagnostics_test()" +== 676 +-- truncate_limit: 100 +-- test variadic functions + +create or replace function vari(variadic int[]) +returns void as $$ +begin + for i in array_lower($1,1)..array_upper($1,1) loop + raise notice '%', $1[i]; + end loop; end; +$$ language plpgsql +-- +FUNCTION: name="vari" function="vari" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION vari(VARIADIC int[]) RETURNS void AS $$\nbegin\n for i in array_lower($..." +== 677 +-- truncate_limit: 100 +select vari(1,2,3,4,5) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT vari(1, 2, 3, 4, 5)" +== 678 +-- truncate_limit: 100 +select vari(3,4,5) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT vari(3, 4, 5)" +== 679 +-- truncate_limit: 100 +select vari(variadic array[5,6,7]) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT vari(VARIADIC ARRAY[5, 6, 7])" +== 680 +-- truncate_limit: 100 +drop function vari(int[]) +-- +FUNCTION: name="vari" function="vari" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION vari(int[])" +== 681 +-- truncate_limit: 100 +-- coercion test +create or replace function pleast(variadic numeric[]) +returns numeric as $$ +declare aux numeric = $1[array_lower($1,1)]; +begin + for i in array_lower($1,1)+1..array_upper($1,1) loop + if $1[i] < aux then aux := $1[i]; end if; + end loop; + return aux; +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION pleast(VARIADIC numeric[]) RETURNS numeric AS $$\ndeclare aux numeric =..." +== 682 +-- truncate_limit: 100 +select pleast(10,1,2,3,-16) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pleast(10, 1, 2, 3, -16)" +== 683 +-- truncate_limit: 100 +select pleast(10.2,2.2,-1.1) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pleast(10.2, 2.2, -1.1)" +== 684 +-- truncate_limit: 100 +select pleast(10.2,10, -20) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pleast(10.2, 10, -20)" +== 685 +-- truncate_limit: 100 +select pleast(10,20, -1.0) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pleast(10, 20, -1.0)" +== 686 +-- truncate_limit: 100 +-- in case of conflict, non-variadic version is preferred +create or replace function pleast(numeric) +returns numeric as $$ +begin + raise notice 'non-variadic function called'; + return $1; +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION pleast(numeric) RETURNS numeric AS $$\nbegin\n raise notice 'non-variad..." +== 687 +-- truncate_limit: 100 +select pleast(10) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pleast(10)" +== 688 +-- truncate_limit: 100 +drop function pleast(numeric[]) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION pleast(numeric[])" +== 689 +-- truncate_limit: 100 +drop function pleast(numeric) +-- +FUNCTION: name="pleast" function="pleast" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION pleast(numeric)" +== 690 +-- truncate_limit: 100 +-- test table functions + +create function tftest(int) returns table(a int, b int) as $$ +begin + return query select $1, $1+i from generate_series(1,5) g(i); +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tftest(int) RETURNS TABLE (a int, b int) AS $$\nbegin\n return query select $1, $1..." +== 691 +-- truncate_limit: 100 +select * from tftest(10) +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tftest(10)" +== 692 +-- truncate_limit: 100 +create or replace function tftest(a1 int) returns table(a int, b int) as $$ +begin + a := a1; b := a1 + 1; + return next; + a := a1 * 10; b := a1 * 10 + 1; + return next; +end; +$$ language plpgsql immutable strict +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION tftest(a1 int) RETURNS TABLE (a int, b int) AS $$\nbegin\n a := a1; b :..." +== 693 +-- truncate_limit: 100 +select * from tftest(10) +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tftest(10)" +== 694 +-- truncate_limit: 100 +drop function tftest(int) +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION tftest(int)" +== 695 +-- truncate_limit: 100 +create function rttest() +returns setof int as $$ +declare rc int; +begin + return query values(10),(20); + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query select * from (values(10),(20)) f(a) where false; + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query execute 'values(10),(20)'; + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query execute 'select * from (values(10),(20)) f(a) where false'; + get diagnostics rc = row_count; + raise notice '% %', found, rc; +end; +$$ language plpgsql +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rttest() RETURNS SETOF int AS $$\ndeclare rc int;\nbegin\n return query values(10),..." +== 696 +-- truncate_limit: 100 +select * from rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rttest()" +== 697 +-- truncate_limit: 100 +-- check some error cases, too + +create or replace function rttest() +returns setof int as $$ +begin + return query select 10 into no_such_table; +end; +$$ language plpgsql +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rttest() RETURNS SETOF int AS $$\nbegin\n return query select 10 into n..." +== 698 +-- truncate_limit: 100 +select * from rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rttest()" +== 699 +-- truncate_limit: 100 +create or replace function rttest() +returns setof int as $$ +begin + return query execute 'select 10 into no_such_table'; +end; +$$ language plpgsql +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rttest() RETURNS SETOF int AS $$\nbegin\n return query execute 'select ..." +== 700 +-- truncate_limit: 100 +select * from rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rttest()" +== 701 +-- truncate_limit: 100 +select * from no_such_table +-- +TABLE: name="no_such_table" schema="" table="no_such_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM no_such_table" +== 702 +-- truncate_limit: 100 +drop function rttest() +-- +FUNCTION: name="rttest" function="rttest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rttest()" +== 703 +-- truncate_limit: 100 +-- Test for proper cleanup at subtransaction exit. This example +-- exposed a bug in PG 8.2. + +CREATE FUNCTION leaker_1(fail BOOL) RETURNS INTEGER AS $$ +DECLARE + v_var INTEGER; +BEGIN + BEGIN + v_var := (leaker_2(fail)).error_code; + EXCEPTION + WHEN others THEN RETURN 0; + END; + RETURN 1; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION leaker_1(fail bool) RETURNS int AS $$\nDECLARE\n v_var INTEGER;\nBEGIN\n BEGIN\n ..." +== 704 +-- truncate_limit: 100 +CREATE FUNCTION leaker_2(fail BOOL, OUT error_code INTEGER, OUT new_id INTEGER) + RETURNS RECORD AS $$ +BEGIN + IF fail THEN + RAISE EXCEPTION 'fail ...'; + END IF; + error_code := 1; + new_id := 1; + RETURN; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="leaker_2" function="leaker_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION leaker_2(fail bool, OUT error_code int, OUT new_id int) RETURNS record AS $$\nBEGI..." +== 705 +-- truncate_limit: 100 +SELECT * FROM leaker_1(false) +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM leaker_1(false)" +== 706 +-- truncate_limit: 100 +SELECT * FROM leaker_1(true) +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM leaker_1(true)" +== 707 +-- truncate_limit: 100 +DROP FUNCTION leaker_1(bool) +-- +FUNCTION: name="leaker_1" function="leaker_1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION leaker_1(bool)" +== 708 +-- truncate_limit: 100 +DROP FUNCTION leaker_2(bool) +-- +FUNCTION: name="leaker_2" function="leaker_2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION leaker_2(bool)" +== 709 +-- truncate_limit: 100 +-- Test for appropriate cleanup of non-simple expression evaluations +-- (bug in all versions prior to August 2010) + +CREATE FUNCTION nonsimple_expr_test() RETURNS text[] AS $$ +DECLARE + arr text[]; + lr text; + i integer; +BEGIN + arr := array[array['foo','bar'], array['baz', 'quux']]; + lr := 'fool'; + i := 1; + -- use sub-SELECTs to make expressions non-simple + arr[(SELECT i)][(SELECT i+1)] := (SELECT lr); + RETURN arr; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION nonsimple_expr_test() RETURNS text[] AS $$\nDECLARE\n arr text[];\n lr text;\n i i..." +== 710 +-- truncate_limit: 100 +SELECT nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nonsimple_expr_test()" +== 711 +-- truncate_limit: 100 +DROP FUNCTION nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION nonsimple_expr_test()" +== 712 +-- truncate_limit: 100 +CREATE FUNCTION nonsimple_expr_test() RETURNS integer AS $$ +declare + i integer NOT NULL := 0; +begin + begin + i := (SELECT NULL::integer); -- should throw error + exception + WHEN OTHERS THEN + i := (SELECT 1::integer); + end; + return i; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION nonsimple_expr_test() RETURNS int AS $$\ndeclare\n i integer NOT NULL := 0;\nbegin..." +== 713 +-- truncate_limit: 100 +SELECT nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nonsimple_expr_test()" +== 714 +-- truncate_limit: 100 +DROP FUNCTION nonsimple_expr_test() +-- +FUNCTION: name="nonsimple_expr_test" function="nonsimple_expr_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION nonsimple_expr_test()" +== 715 +-- truncate_limit: 100 +|-- +-- Test cases involving recursion and error recovery in simple expressions +-- (bugs in all versions before October 2010). The problems are most +-- easily exposed by mutual recursion between plpgsql and sql functions. +|-- + +create function recurse(float8) returns float8 as +$$ +begin + if ($1 > 0) then + return sql_recurse($1 - 1); + else + return $1; + end if; +end; +$$ language plpgsql +-- +FUNCTION: name="recurse" function="recurse" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION recurse(float8) RETURNS float8 AS $$\nbegin\n if ($1 > 0) then\n return sql_recu..." +== 716 +-- truncate_limit: 100 +-- "limit" is to prevent this from being inlined +create function sql_recurse(float8) returns float8 as +$$ select recurse($1) limit 1; $$ language sql +-- +FUNCTION: name="sql_recurse" function="sql_recurse" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sql_recurse(float8) RETURNS float8 AS $$ select recurse($1) limit 1; $$ LANGUAGE sql" +== 717 +-- truncate_limit: 100 +select recurse(10) +-- +FUNCTION: name="recurse" function="recurse" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT recurse(10)" +== 718 +-- truncate_limit: 100 +create function error1(text) returns text language sql as +$$ SELECT relname::text FROM pg_class c WHERE c.oid = $1::regclass $$ +-- +FUNCTION: name="error1" function="error1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION error1(text) RETURNS text LANGUAGE sql AS $$ SELECT relname::text FROM pg_class c..." +== 719 +-- truncate_limit: 100 +create function error2(p_name_table text) returns text language plpgsql as $$ +begin + return error1(p_name_table); +end$$ +-- +FUNCTION: name="error2" function="error2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION error2(p_name_table text) RETURNS text LANGUAGE plpgsql AS $$\nbegin\n return erro..." +== 720 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 721 +-- truncate_limit: 100 +create table public.stuffs (stuff text) +-- +TABLE: name="public.stuffs" schema="public" table="stuffs" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE public.stuffs (stuff text)" +== 722 +-- truncate_limit: 100 +SAVEPOINT a +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT a" +== 723 +-- truncate_limit: 100 +select error2('nonexistent.stuffs') +-- +FUNCTION: name="error2" function="error2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT error2('nonexistent.stuffs')" +== 724 +-- truncate_limit: 100 +ROLLBACK TO a +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT a" +== 725 +-- truncate_limit: 100 +select error2('public.stuffs') +-- +FUNCTION: name="error2" function="error2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT error2('public.stuffs')" +== 726 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 727 +-- truncate_limit: 100 +drop function error2(p_name_table text) +-- +FUNCTION: name="error2" function="error2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION error2(p_name_table text)" +== 728 +-- truncate_limit: 100 +drop function error1(text) +-- +FUNCTION: name="error1" function="error1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION error1(text)" +== 729 +-- truncate_limit: 100 +-- Test for proper handling of cast-expression caching + +create function sql_to_date(integer) returns date as $$ +select $1::text::date +$$ language sql immutable strict +-- +FUNCTION: name="sql_to_date" function="sql_to_date" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sql_to_date(int) RETURNS date AS $$\nselect $1::text::date\n$$ LANGUAGE sql IMMUTAB..." +== 730 +-- truncate_limit: 100 +create cast (integer as date) with function sql_to_date(integer) as assignment +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (int AS date) WITH FUNCTION sql_to_date(int) AS ASSIGNMENT" +== 731 +-- truncate_limit: 100 +create function cast_invoker(integer) returns date as $$ +begin + return $1; +end$$ language plpgsql +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION cast_invoker(int) RETURNS date AS $$\nbegin\n return $1;\nend$$ LANGUAGE plpgsql" +== 732 +-- truncate_limit: 100 +select cast_invoker(20150717) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(20150717)" +== 733 +-- truncate_limit: 100 +select cast_invoker(20150718) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(20150718)" +== 734 +-- truncate_limit: 100 +-- second call crashed in pre-release 9.5 + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 735 +-- truncate_limit: 100 +select cast_invoker(20150717) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(20150717)" +== 736 +-- truncate_limit: 100 +select cast_invoker(20150718) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(20150718)" +== 737 +-- truncate_limit: 100 +savepoint s1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT s1" +== 738 +-- truncate_limit: 100 +select cast_invoker(20150718) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(20150718)" +== 739 +-- truncate_limit: 100 +select cast_invoker(-1) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(-1)" +== 740 +-- truncate_limit: 100 +-- fails +rollback to savepoint s1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT s1" +== 741 +-- truncate_limit: 100 +select cast_invoker(20150719) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(20150719)" +== 742 +-- truncate_limit: 100 +select cast_invoker(20150720) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cast_invoker(20150720)" +== 743 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 744 +-- truncate_limit: 100 +drop function cast_invoker(integer) +-- +FUNCTION: name="cast_invoker" function="cast_invoker" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION cast_invoker(int)" +== 745 +-- truncate_limit: 100 +drop function sql_to_date(integer) cascade +-- +FUNCTION: name="sql_to_date" function="sql_to_date" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sql_to_date(int) CASCADE" +== 746 +-- truncate_limit: 100 +-- Test handling of cast cache inside DO blocks +-- (to check the original crash case, this must be a cast not previously +-- used in this session) + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 747 +-- truncate_limit: 100 +do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$ +-- +STMT: DoStmt +TRUNCATED: "DO $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$" +== 748 +-- truncate_limit: 100 +do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$ +-- +STMT: DoStmt +TRUNCATED: "DO $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$" +== 749 +-- truncate_limit: 100 +end +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 750 +-- truncate_limit: 100 +-- Test for consistent reporting of error context + +create function fail() returns int language plpgsql as $$ +begin + return 1/0; +end +$$ +-- +FUNCTION: name="fail" function="fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fail() RETURNS int LANGUAGE plpgsql AS $$\nbegin\n return 1/0;\nend\n$$" +== 751 +-- truncate_limit: 100 +select fail() +-- +FUNCTION: name="fail" function="fail" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT fail()" +== 752 +-- truncate_limit: 100 +select fail() +-- +FUNCTION: name="fail" function="fail" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT fail()" +== 753 +-- truncate_limit: 100 +drop function fail() +-- +FUNCTION: name="fail" function="fail" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION fail()" +== 754 +-- truncate_limit: 100 +-- Test handling of string literals. + +set standard_conforming_strings = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET standard_conforming_strings TO OFF" +== 755 +-- truncate_limit: 100 +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz'; + return 'foo\\bar\041baz'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION strtest() RETURNS text AS $$\nbegin\n raise notice 'foo\\\\bar\\041baz';\n ..." +== 756 +-- truncate_limit: 100 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strtest()" +== 757 +-- truncate_limit: 100 +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION strtest() RETURNS text AS $$\nbegin\n raise notice E'foo\\\\bar\\041baz';\n..." +== 758 +-- truncate_limit: 100 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strtest()" +== 759 +-- truncate_limit: 100 +set standard_conforming_strings = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET standard_conforming_strings TO ON" +== 760 +-- truncate_limit: 100 +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz\'; + return 'foo\\bar\041baz\'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION strtest() RETURNS text AS $$\nbegin\n raise notice 'foo\\\\bar\\041baz\\';\n..." +== 761 +-- truncate_limit: 100 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strtest()" +== 762 +-- truncate_limit: 100 +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION strtest() RETURNS text AS $$\nbegin\n raise notice E'foo\\\\bar\\041baz';\n..." +== 763 +-- truncate_limit: 100 +select strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strtest()" +== 764 +-- truncate_limit: 100 +drop function strtest() +-- +FUNCTION: name="strtest" function="strtest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION strtest()" +== 765 +-- truncate_limit: 100 +-- Test anonymous code blocks. + +DO $$ +DECLARE r record; +BEGIN + FOR r IN SELECT rtrim(roomno) AS roomno, comment FROM Room ORDER BY roomno + LOOP + RAISE NOTICE '%, %', r.roomno, r.comment; + END LOOP; +END$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE r record;\nBEGIN\n FOR r IN SELECT rtrim(roomno) AS roomno, comment FROM Room ORDE..." +== 766 +-- truncate_limit: 100 +-- these are to check syntax error reporting +DO LANGUAGE plpgsql $$begin return 1; end$$ +-- +STMT: DoStmt +TRUNCATED: "DO LANGUAGE plpgsql $$begin return 1; end$$" +== 767 +-- truncate_limit: 100 +DO $$ +DECLARE r record; +BEGIN + FOR r IN SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno + LOOP + RAISE NOTICE '%, %', r.roomno, r.comment; + END LOOP; +END$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE r record;\nBEGIN\n FOR r IN SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY..." +== 768 +-- truncate_limit: 100 +-- Check handling of errors thrown from/into anonymous code blocks. +do $outer$ +begin + for i in 1..10 loop + begin + execute $ex$ + do $$ + declare x int = 0; + begin + x := 1 / x; + end; + $$; + $ex$; + exception when division_by_zero then + raise notice 'caught division by zero'; + end; + end loop; +end; +$outer$ +-- +STMT: DoStmt +TRUNCATED: "DO $outer$\nbegin\n for i in 1..10 loop\n begin\n execute $ex$\n do $$\n declare x int ..." +== 769 +-- truncate_limit: 100 +-- Check variable scoping -- a var is not available in its own or prior +-- default expressions, but it is available in later ones. + +do $$ +declare x int := x + 1; -- error +begin + raise notice 'x = %', x; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare x int := x + 1; -- error\nbegin\n raise notice 'x = %', x;\nend;\n$$" +== 770 +-- truncate_limit: 100 +do $$ +declare y int := x + 1; -- error + x int := 42; +begin + raise notice 'x = %, y = %', x, y; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare y int := x + 1; -- error\n x int := 42;\nbegin\n raise notice 'x = %, y = %',..." +== 771 +-- truncate_limit: 100 +do $$ +declare x int := 42; + y int := x + 1; +begin + raise notice 'x = %, y = %', x, y; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare x int := 42;\n y int := x + 1;\nbegin\n raise notice 'x = %, y = %', x, y;\nend..." +== 772 +-- truncate_limit: 100 +do $$ +declare x int := 42; +begin + declare y int := x + 1; + x int := x + 2; + z int := x * 10; + begin + raise notice 'x = %, y = %, z = %', x, y, z; + end; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare x int := 42;\nbegin\n declare y int := x + 1;\n x int := x + 2;\n z ..." +== 773 +-- truncate_limit: 100 +-- Check handling of conflicts between plpgsql vars and table columns. + +set plpgsql.variable_conflict = error +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.variable_conflict\" TO error" +== 774 +-- truncate_limit: 100 +create function conflict_test() returns setof int8_tbl as $$ +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION conflict_test() RETURNS SETOF int8_tbl AS $$\ndeclare r record;\n q1 bigint := 42;..." +== 775 +-- truncate_limit: 100 +select * from conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM conflict_test()" +== 776 +-- truncate_limit: 100 +create or replace function conflict_test() returns setof int8_tbl as $$ +#variable_conflict use_variable +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION conflict_test() RETURNS SETOF int8_tbl AS $$\n#variable_conflict use_va..." +== 777 +-- truncate_limit: 100 +select * from conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM conflict_test()" +== 778 +-- truncate_limit: 100 +create or replace function conflict_test() returns setof int8_tbl as $$ +#variable_conflict use_column +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION conflict_test() RETURNS SETOF int8_tbl AS $$\n#variable_conflict use_co..." +== 779 +-- truncate_limit: 100 +select * from conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM conflict_test()" +== 780 +-- truncate_limit: 100 +drop function conflict_test() +-- +FUNCTION: name="conflict_test" function="conflict_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION conflict_test()" +== 781 +-- truncate_limit: 100 +-- Check that an unreserved keyword can be used as a variable name + +create function unreserved_test() returns int as $$ +declare + forward int := 21; +begin + forward := forward * 2; + return forward; +end +$$ language plpgsql +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION unreserved_test() RETURNS int AS $$\ndeclare\n forward int := 21;\nbegin\n forward ..." +== 782 +-- truncate_limit: 100 +select unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unreserved_test()" +== 783 +-- truncate_limit: 100 +create or replace function unreserved_test() returns int as $$ +declare + return int := 42; +begin + return := return + 1; + return return; +end +$$ language plpgsql +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION unreserved_test() RETURNS int AS $$\ndeclare\n return int := 42;\nbegin\n..." +== 784 +-- truncate_limit: 100 +select unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unreserved_test()" +== 785 +-- truncate_limit: 100 +create or replace function unreserved_test() returns int as $$ +declare + comment int := 21; +begin + comment := comment * 2; + comment on function unreserved_test() is 'this is a test'; + return comment; +end +$$ language plpgsql +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION unreserved_test() RETURNS int AS $$\ndeclare\n comment int := 21;\nbegin..." +== 786 +-- truncate_limit: 100 +select unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unreserved_test()" +== 787 +-- truncate_limit: 100 +select obj_description('unreserved_test()'::regprocedure, 'pg_proc') +-- +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT obj_description('unreserved_test()'::regprocedure, 'pg_proc')" +== 788 +-- truncate_limit: 100 +drop function unreserved_test() +-- +FUNCTION: name="unreserved_test" function="unreserved_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION unreserved_test()" +== 789 +-- truncate_limit: 100 +|-- +-- Test FOREACH over arrays +|-- + +create function foreach_test(anyarray) +returns void as $$ +declare x int; +begin + foreach x in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION foreach_test(anyarray) RETURNS void AS $$\ndeclare x int;\nbegin\n foreach x in arr..." +== 790 +-- truncate_limit: 100 +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[1, 2, 3, 4])" +== 791 +-- truncate_limit: 100 +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[1, 2], ARRAY[3, 4]])" +== 792 +-- truncate_limit: 100 +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION foreach_test(anyarray) RETURNS void AS $$\ndeclare x int;\nbegin\n forea..." +== 793 +-- truncate_limit: 100 +-- should fail +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[1, 2, 3, 4])" +== 794 +-- truncate_limit: 100 +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[1, 2], ARRAY[3, 4]])" +== 795 +-- truncate_limit: 100 +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int[]; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION foreach_test(anyarray) RETURNS void AS $$\ndeclare x int[];\nbegin\n for..." +== 796 +-- truncate_limit: 100 +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[1, 2, 3, 4])" +== 797 +-- truncate_limit: 100 +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[1, 2], ARRAY[3, 4]])" +== 798 +-- truncate_limit: 100 +-- higher level of slicing +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int[]; +begin + foreach x slice 2 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION foreach_test(anyarray) RETURNS void AS $$\ndeclare x int[];\nbegin\n for..." +== 799 +-- truncate_limit: 100 +-- should fail +select foreach_test(ARRAY[1,2,3,4]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[1, 2, 3, 4])" +== 800 +-- truncate_limit: 100 +-- ok +select foreach_test(ARRAY[[1,2],[3,4]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[1, 2], ARRAY[3, 4]])" +== 801 +-- truncate_limit: 100 +select foreach_test(ARRAY[[[1,2]],[[3,4]]]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[ARRAY[1, 2]], ARRAY[ARRAY[3, 4]]])" +== 802 +-- truncate_limit: 100 +create type xy_tuple AS (x int, y int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE xy_tuple AS (x int, y int)" +== 803 +-- truncate_limit: 100 +-- iteration over array of records +create or replace function foreach_test(anyarray) +returns void as $$ +declare r record; +begin + foreach r in array $1 + loop + raise notice '%', r; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION foreach_test(anyarray) RETURNS void AS $$\ndeclare r record;\nbegin\n fo..." +== 804 +-- truncate_limit: 100 +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[(10, 20), (40, 69), (35, 78)]::xy_tuple[])" +== 805 +-- truncate_limit: 100 +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[(10, 20), (40, 69)], ARRAY[(35, 78), (88, 76)]]::xy_tuple[])" +== 806 +-- truncate_limit: 100 +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int; y int; +begin + foreach x, y in array $1 + loop + raise notice 'x = %, y = %', x, y; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION foreach_test(anyarray) RETURNS void AS $$\ndeclare x int; y int;\nbegin\n..." +== 807 +-- truncate_limit: 100 +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[(10, 20), (40, 69), (35, 78)]::xy_tuple[])" +== 808 +-- truncate_limit: 100 +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[(10, 20), (40, 69)], ARRAY[(35, 78), (88, 76)]]::xy_tuple[])" +== 809 +-- truncate_limit: 100 +-- slicing over array of composite types +create or replace function foreach_test(anyarray) +returns void as $$ +declare x xy_tuple[]; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION foreach_test(anyarray) RETURNS void AS $$\ndeclare x xy_tuple[];\nbegin\n..." +== 810 +-- truncate_limit: 100 +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[(10, 20), (40, 69), (35, 78)]::xy_tuple[])" +== 811 +-- truncate_limit: 100 +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT foreach_test(ARRAY[ARRAY[(10, 20), (40, 69)], ARRAY[(35, 78), (88, 76)]]::xy_tuple[])" +== 812 +-- truncate_limit: 100 +drop function foreach_test(anyarray) +-- +FUNCTION: name="foreach_test" function="foreach_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION foreach_test(anyarray)" +== 813 +-- truncate_limit: 100 +drop type xy_tuple +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE xy_tuple" +== 814 +-- truncate_limit: 100 +|-- +-- Assorted tests for array subscript assignment +|-- + +create temp table rtype (id int, ar text[]) +-- +TABLE: name="rtype" schema="" table="rtype" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE rtype (id int, ar text[])" +== 815 +-- truncate_limit: 100 +create function arrayassign1() returns text[] language plpgsql as $$ +declare + r record; +begin + r := row(12, '{foo,bar,baz}')::rtype; + r.ar[2] := 'replace'; + return r.ar; +end$$ +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION arrayassign1() RETURNS text[] LANGUAGE plpgsql AS $$\ndeclare\n r record;\nbegin\n r..." +== 816 +-- truncate_limit: 100 +select arrayassign1() +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT arrayassign1()" +== 817 +-- truncate_limit: 100 +select arrayassign1() +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT arrayassign1()" +== 818 +-- truncate_limit: 100 +-- try again to exercise internal caching + +create domain orderedarray as int[2] + constraint sorted check (value[1] < value[2]) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN orderedarray AS int[2] CONSTRAINT sorted CHECK (value[1] < value[2])" +== 819 +-- truncate_limit: 100 +select '{1,2}'::orderedarray +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{1,2}'::orderedarray" +== 820 +-- truncate_limit: 100 +select '{2,1}'::orderedarray +-- +STMT: SelectStmt +TRUNCATED: "SELECT '{2,1}'::orderedarray" +== 821 +-- truncate_limit: 100 +-- fail + +create function testoa(x1 int, x2 int, x3 int) returns orderedarray +language plpgsql as $$ +declare res orderedarray; +begin + res := array[x1, x2]; + res[2] := x3; + return res; +end$$ +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testoa(x1 int, x2 int, x3 int) RETURNS orderedarray LANGUAGE plpgsql AS $$\ndeclar..." +== 822 +-- truncate_limit: 100 +select testoa(1,2,3) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testoa(1, 2, 3)" +== 823 +-- truncate_limit: 100 +select testoa(1,2,3) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testoa(1, 2, 3)" +== 824 +-- truncate_limit: 100 +-- try again to exercise internal caching +select testoa(2,1,3) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testoa(2, 1, 3)" +== 825 +-- truncate_limit: 100 +-- fail at initial assign +select testoa(1,2,1) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testoa(1, 2, 1)" +== 826 +-- truncate_limit: 100 +-- fail at update + +drop function arrayassign1() +-- +FUNCTION: name="arrayassign1" function="arrayassign1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION arrayassign1()" +== 827 +-- truncate_limit: 100 +drop function testoa(x1 int, x2 int, x3 int) +-- +FUNCTION: name="testoa" function="testoa" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testoa(x1 int, x2 int, x3 int)" +== 828 +-- truncate_limit: 100 +|-- +-- Test handling of expanded arrays +|-- + +create function returns_rw_array(int) returns int[] +language plpgsql as $$ + declare r int[]; + begin r := array[$1, $1]; return r; end; +$$ stable +-- +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION returns_rw_array(int) RETURNS int[] LANGUAGE plpgsql AS $$\n declare r int[];\n b..." +== 829 +-- truncate_limit: 100 +create function consumes_rw_array(int[]) returns int +language plpgsql as $$ + begin return $1[1]; end; +$$ stable +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION consumes_rw_array(int[]) RETURNS int LANGUAGE plpgsql AS $$\n begin return $1[1];..." +== 830 +-- truncate_limit: 100 +select consumes_rw_array(returns_rw_array(42)) +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT consumes_rw_array(returns_rw_array(42))" +== 831 +-- truncate_limit: 100 +-- bug #14174 +explain (verbose, costs off) +select i, a from + (select returns_rw_array(1) as a offset 0) ss, + lateral consumes_rw_array(a) i +-- +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT i, a FROM (SELECT returns_rw_array(1) AS a OFFSET 0) ss, LATE..." +== 832 +-- truncate_limit: 100 +select i, a from + (select returns_rw_array(1) as a offset 0) ss, + lateral consumes_rw_array(a) i +-- +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i, a FROM (SELECT returns_rw_array(1) AS a OFFSET 0) ss, LATERAL consumes_rw_array(a) i" +== 833 +-- truncate_limit: 100 +explain (verbose, costs off) +select consumes_rw_array(a), a from returns_rw_array(1) a +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT consumes_rw_array(a), a FROM returns_rw_array(1) a" +== 834 +-- truncate_limit: 100 +select consumes_rw_array(a), a from returns_rw_array(1) a +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT consumes_rw_array(a), a FROM returns_rw_array(1) a" +== 835 +-- truncate_limit: 100 +explain (verbose, costs off) +select consumes_rw_array(a), a from + (values (returns_rw_array(1)), (returns_rw_array(2))) v(a) +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT consumes_rw_array(a), a FROM (VALUES (returns_rw_array(1)), (..." +== 836 +-- truncate_limit: 100 +select consumes_rw_array(a), a from + (values (returns_rw_array(1)), (returns_rw_array(2))) v(a) +-- +FUNCTION: name="consumes_rw_array" function="consumes_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +FUNCTION: name="returns_rw_array" function="returns_rw_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT consumes_rw_array(a), a FROM (VALUES (returns_rw_array(1)), (returns_rw_array(2))) v(a)" +== 837 +-- truncate_limit: 100 +do $$ +declare a int[] := array[1,2]; +begin + a := a || 3; + raise notice 'a = %', a; +end$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare a int[] := array[1,2];\nbegin\n a := a || 3;\n raise notice 'a = %', a;\nend$$" +== 838 +-- truncate_limit: 100 +|-- +-- Test access to call stack +|-- + +create function inner_func(int) +returns int as $$ +declare _context text; +begin + get diagnostics _context = pg_context; + raise notice '***%***', _context; + -- lets do it again, just for fun.. + get diagnostics _context = pg_context; + raise notice '***%***', _context; + raise notice 'lets make sure we didnt break anything'; + return 2 * $1; +end; +$$ language plpgsql +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION inner_func(int) RETURNS int AS $$\ndeclare _context text;\nbegin\n get diagnostics ..." +== 839 +-- truncate_limit: 100 +create or replace function outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into inner_func()'; + myresult := inner_func($1); + raise notice 'inner_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION outer_func(int) RETURNS int AS $$\ndeclare\n myresult int;\nbegin\n rais..." +== 840 +-- truncate_limit: 100 +create or replace function outer_outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into outer_func()'; + myresult := outer_func($1); + raise notice 'outer_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION outer_outer_func(int) RETURNS int AS $$\ndeclare\n myresult int;\nbegin\n..." +== 841 +-- truncate_limit: 100 +select outer_outer_func(10) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT outer_outer_func(10)" +== 842 +-- truncate_limit: 100 +-- repeated call should work +select outer_outer_func(20) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT outer_outer_func(20)" +== 843 +-- truncate_limit: 100 +drop function outer_outer_func(int) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION outer_outer_func(int)" +== 844 +-- truncate_limit: 100 +drop function outer_func(int) +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION outer_func(int)" +== 845 +-- truncate_limit: 100 +drop function inner_func(int) +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION inner_func(int)" +== 846 +-- truncate_limit: 100 +-- access to call stack from exception +create function inner_func(int) +returns int as $$ +declare + _context text; + sx int := 5; +begin + begin + perform sx / 0; + exception + when division_by_zero then + get diagnostics _context = pg_context; + raise notice '***%***', _context; + end; + + -- lets do it again, just for fun.. + get diagnostics _context = pg_context; + raise notice '***%***', _context; + raise notice 'lets make sure we didnt break anything'; + return 2 * $1; +end; +$$ language plpgsql +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION inner_func(int) RETURNS int AS $$\ndeclare\n _context text;\n sx int := 5;\nbegin\n ..." +== 847 +-- truncate_limit: 100 +create or replace function outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into inner_func()'; + myresult := inner_func($1); + raise notice 'inner_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION outer_func(int) RETURNS int AS $$\ndeclare\n myresult int;\nbegin\n rais..." +== 848 +-- truncate_limit: 100 +create or replace function outer_outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into outer_func()'; + myresult := outer_func($1); + raise notice 'outer_func() done'; + return myresult; +end; +$$ language plpgsql +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION outer_outer_func(int) RETURNS int AS $$\ndeclare\n myresult int;\nbegin\n..." +== 849 +-- truncate_limit: 100 +select outer_outer_func(10) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT outer_outer_func(10)" +== 850 +-- truncate_limit: 100 +-- repeated call should work +select outer_outer_func(20) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT outer_outer_func(20)" +== 851 +-- truncate_limit: 100 +drop function outer_outer_func(int) +-- +FUNCTION: name="outer_outer_func" function="outer_outer_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION outer_outer_func(int)" +== 852 +-- truncate_limit: 100 +drop function outer_func(int) +-- +FUNCTION: name="outer_func" function="outer_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION outer_func(int)" +== 853 +-- truncate_limit: 100 +drop function inner_func(int) +-- +FUNCTION: name="inner_func" function="inner_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION inner_func(int)" +== 854 +-- truncate_limit: 100 +-- Test pg_routine_oid +create function current_function(text) +returns regprocedure as $$ +declare + fn_oid regprocedure; +begin + get diagnostics fn_oid = pg_routine_oid; + return fn_oid; +end; +$$ language plpgsql +-- +FUNCTION: name="current_function" function="current_function" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION current_function(text) RETURNS regprocedure AS $$\ndeclare\n fn_oid regprocedure;\n..." +== 855 +-- truncate_limit: 100 +select current_function('foo') +-- +FUNCTION: name="current_function" function="current_function" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_function('foo')" +== 856 +-- truncate_limit: 100 +drop function current_function(text) +-- +FUNCTION: name="current_function" function="current_function" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION current_function(text)" +== 857 +-- truncate_limit: 100 +-- shouldn't fail in DO, even though there's no useful data +do $$ +declare + fn_oid oid; +begin + get diagnostics fn_oid = pg_routine_oid; + raise notice 'pg_routine_oid = %', fn_oid; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare\n fn_oid oid;\nbegin\n get diagnostics fn_oid = pg_routine_oid;\n raise notice 'pg_r..." +== 858 +-- truncate_limit: 100 +|-- +-- Test ASSERT +|-- + +do $$ +begin + assert 1=1; -- should succeed +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nbegin\n assert 1=1; -- should succeed\nend;\n$$" +== 859 +-- truncate_limit: 100 +do $$ +begin + assert 1=0; -- should fail +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nbegin\n assert 1=0; -- should fail\nend;\n$$" +== 860 +-- truncate_limit: 100 +do $$ +begin + assert NULL; -- should fail +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nbegin\n assert NULL; -- should fail\nend;\n$$" +== 861 +-- truncate_limit: 100 +-- check controlling GUC +set plpgsql.check_asserts = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET \"plpgsql.check_asserts\" TO OFF" +== 862 +-- truncate_limit: 100 +do $$ +begin + assert 1=0; -- won't be tested +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nbegin\n assert 1=0; -- won't be tested\nend;\n$$" +== 863 +-- truncate_limit: 100 +reset plpgsql.check_asserts +-- +STMT: VariableSetStmt +TRUNCATED: "RESET \"plpgsql.check_asserts\"" +== 864 +-- truncate_limit: 100 +-- test custom message +do $$ +declare var text := 'some value'; +begin + assert 1=0, format('assertion failed, var = "%s"', var); +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare var text := 'some value';\nbegin\n assert 1=0, format('assertion failed, var = \"%s\"'..." +== 865 +-- truncate_limit: 100 +-- ensure assertions are not trapped by 'others' +do $$ +begin + assert 1=0, 'unhandled assertion'; +exception when others then + null; -- do nothing +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nbegin\n assert 1=0, 'unhandled assertion';\nexception when others then\n null; -- do nothing..." +== 866 +-- truncate_limit: 100 +-- Test use of plpgsql in a domain check constraint (cf. bug #14414) + +create function plpgsql_domain_check(val int) returns boolean as $$ +begin return val > 0; end +$$ language plpgsql immutable +-- +FUNCTION: name="plpgsql_domain_check" function="plpgsql_domain_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION plpgsql_domain_check(val int) RETURNS boolean AS $$\nbegin return val > 0; end\n$$ ..." +== 867 +-- truncate_limit: 100 +create domain plpgsql_domain as integer check(plpgsql_domain_check(value)) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN plpgsql_domain AS int CHECK (plpgsql_domain_check(value))" +== 868 +-- truncate_limit: 100 +do $$ +declare v_test plpgsql_domain; +begin + v_test := 1; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare v_test plpgsql_domain;\nbegin\n v_test := 1;\nend;\n$$" +== 869 +-- truncate_limit: 100 +do $$ +declare v_test plpgsql_domain := 1; +begin + v_test := 0; -- fail +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare v_test plpgsql_domain := 1;\nbegin\n v_test := 0; -- fail\nend;\n$$" +== 870 +-- truncate_limit: 100 +-- Test handling of expanded array passed to a domain constraint (bug #14472) + +create function plpgsql_arr_domain_check(val int[]) returns boolean as $$ +begin return val[1] > 0; end +$$ language plpgsql immutable +-- +FUNCTION: name="plpgsql_arr_domain_check" function="plpgsql_arr_domain_check" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION plpgsql_arr_domain_check(val int[]) RETURNS boolean AS $$\nbegin return val[1] > 0..." +== 871 +-- truncate_limit: 100 +create domain plpgsql_arr_domain as int[] check(plpgsql_arr_domain_check(value)) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN plpgsql_arr_domain AS int[] CHECK (plpgsql_arr_domain_check(value))" +== 872 +-- truncate_limit: 100 +do $$ +declare v_test plpgsql_arr_domain; +begin + v_test := array[1]; + v_test := v_test || 2; +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare v_test plpgsql_arr_domain;\nbegin\n v_test := array[1];\n v_test := v_test || 2;\nend..." +== 873 +-- truncate_limit: 100 +do $$ +declare v_test plpgsql_arr_domain := array[1]; +begin + v_test := 0 || v_test; -- fail +end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\ndeclare v_test plpgsql_arr_domain := array[1];\nbegin\n v_test := 0 || v_test; -- fail\nend;\n$$" +== 874 +-- truncate_limit: 100 +|-- +-- test usage of transition tables in AFTER triggers +|-- + +CREATE TABLE transition_table_base (id int PRIMARY KEY, val text) +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE transition_table_base (id int PRIMARY KEY, val text)" +== 875 +-- truncate_limit: 100 +CREATE FUNCTION transition_table_base_ins_func() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +DECLARE + t text; + l text; +BEGIN + t = ''; + FOR l IN EXECUTE + $q$ + EXPLAIN (TIMING off, COSTS off, VERBOSE on) + SELECT * FROM newtable + $q$ LOOP + t = t || l || E'\n'; + END LOOP; + + RAISE INFO '%', t; + RETURN new; +END; +$$ +-- +FUNCTION: name="transition_table_base_ins_func" function="transition_table_base_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION transition_table_base_ins_func() RETURNS trigger LANGUAGE plpgsql AS $$\nDECLARE\n ..." +== 876 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_base_ins_trig + AFTER INSERT ON transition_table_base + REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_ins_func() +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_base_ins_trig AFTER INSERT ON transition_table_base REFERENCING O..." +== 877 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_base_ins_trig + AFTER INSERT ON transition_table_base + REFERENCING NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_ins_func() +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_base_ins_trig AFTER INSERT ON transition_table_base REFERENCING N..." +== 878 +-- truncate_limit: 100 +INSERT INTO transition_table_base VALUES (1, 'One'), (2, 'Two') +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_base VALUES (1, 'One'), (2, 'Two')" +== 879 +-- truncate_limit: 100 +INSERT INTO transition_table_base VALUES (3, 'Three'), (4, 'Four') +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_base VALUES (3, 'Three'), (4, 'Four')" +== 880 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION transition_table_base_upd_func() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +DECLARE + t text; + l text; +BEGIN + t = ''; + FOR l IN EXECUTE + $q$ + EXPLAIN (TIMING off, COSTS off, VERBOSE on) + SELECT * FROM oldtable ot FULL JOIN newtable nt USING (id) + $q$ LOOP + t = t || l || E'\n'; + END LOOP; + + RAISE INFO '%', t; + RETURN new; +END; +$$ +-- +FUNCTION: name="transition_table_base_upd_func" function="transition_table_base_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION transition_table_base_upd_func() RETURNS trigger LANGUAGE plpgsql AS $..." +== 881 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_base_upd_trig + AFTER UPDATE ON transition_table_base + REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_upd_func() +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_base_upd_trig AFTER UPDATE ON transition_table_base REFERENCING O..." +== 882 +-- truncate_limit: 100 +UPDATE transition_table_base + SET val = '*' || val || '*' + WHERE id BETWEEN 2 AND 3 +-- +TABLE: name="transition_table_base" schema="" table="transition_table_base" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE transition_table_base SET val = ('*' || val) || '*' WHERE id BETWEEN 2 AND 3" +== 883 +-- truncate_limit: 100 +CREATE TABLE transition_table_level1 +( + level1_no serial NOT NULL , + level1_node_name varchar(255), + PRIMARY KEY (level1_no) +) WITHOUT OIDS +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE transition_table_level1 (level1_no serial NOT NULL, level1_node_name varchar(255), P..." +== 884 +-- truncate_limit: 100 +CREATE TABLE transition_table_level2 +( + level2_no serial NOT NULL , + parent_no int NOT NULL, + level1_node_name varchar(255), + PRIMARY KEY (level2_no) +) WITHOUT OIDS +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE transition_table_level2 (level2_no serial NOT NULL, parent_no int NOT NULL, level1_n..." +== 885 +-- truncate_limit: 100 +CREATE TABLE transition_table_status +( + level int NOT NULL, + node_no int NOT NULL, + status int, + PRIMARY KEY (level, node_no) +) WITHOUT OIDS +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE transition_table_status (level int NOT NULL, node_no int NOT NULL, status int, PRIMA..." +== 886 +-- truncate_limit: 100 +CREATE FUNCTION transition_table_level1_ri_parent_del_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + DECLARE n bigint; + BEGIN + PERFORM FROM p JOIN transition_table_level2 c ON c.parent_no = p.level1_no; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level1_ri_parent_del_func" function="transition_table_level1_ri_parent_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION transition_table_level1_ri_parent_del_func() RETURNS trigger LANGUAGE plpgsql AS ..." +== 887 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_level1_ri_parent_del_trigger + AFTER DELETE ON transition_table_level1 + REFERENCING OLD TABLE AS p + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level1_ri_parent_del_func() +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_level1_ri_parent_del_trigger AFTER DELETE ON transition_table_lev..." +== 888 +-- truncate_limit: 100 +CREATE FUNCTION transition_table_level1_ri_parent_upd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + DECLARE + x int; + BEGIN + WITH p AS (SELECT level1_no, sum(delta) cnt + FROM (SELECT level1_no, 1 AS delta FROM i + UNION ALL + SELECT level1_no, -1 AS delta FROM d) w + GROUP BY level1_no + HAVING sum(delta) < 0) + SELECT level1_no + FROM p JOIN transition_table_level2 c ON c.parent_no = p.level1_no + INTO x; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level1_ri_parent_upd_func" function="transition_table_level1_ri_parent_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION transition_table_level1_ri_parent_upd_func() RETURNS trigger LANGUAGE plpgsql AS ..." +== 889 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_level1_ri_parent_upd_trigger + AFTER UPDATE ON transition_table_level1 + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level1_ri_parent_upd_func() +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_level1_ri_parent_upd_trigger AFTER UPDATE ON transition_table_lev..." +== 890 +-- truncate_limit: 100 +CREATE FUNCTION transition_table_level2_ri_child_insupd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + BEGIN + PERFORM FROM i + LEFT JOIN transition_table_level1 p + ON p.level1_no IS NOT NULL AND p.level1_no = i.parent_no + WHERE p.level1_no IS NULL; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level2_ri_child_insupd_func" function="transition_table_level2_ri_child_insupd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION transition_table_level2_ri_child_insupd_func() RETURNS trigger LANGUAGE plpgsql A..." +== 891 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_level2_ri_child_ins_trigger + AFTER INSERT ON transition_table_level2 + REFERENCING NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_ri_child_insupd_func() +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_level2_ri_child_ins_trigger AFTER INSERT ON transition_table_leve..." +== 892 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_level2_ri_child_upd_trigger + AFTER UPDATE ON transition_table_level2 + REFERENCING NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_ri_child_insupd_func() +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_level2_ri_child_upd_trigger AFTER UPDATE ON transition_table_leve..." +== 893 +-- truncate_limit: 100 +-- create initial test data +INSERT INTO transition_table_level1 (level1_no) + SELECT generate_series(1,200) +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_level1 (level1_no) SELECT generate_series(1, 200)" +== 894 +-- truncate_limit: 100 +ANALYZE transition_table_level1 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE transition_table_level1" +== 895 +-- truncate_limit: 100 +INSERT INTO transition_table_level2 (level2_no, parent_no) + SELECT level2_no, level2_no / 50 + 1 AS parent_no + FROM generate_series(1,9999) level2_no +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_level2 (...) SELECT ... FROM generate_series(1, 9999) level2_no" +== 896 +-- truncate_limit: 100 +ANALYZE transition_table_level2 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE transition_table_level2" +== 897 +-- truncate_limit: 100 +INSERT INTO transition_table_status (level, node_no, status) + SELECT 1, level1_no, 0 FROM transition_table_level1 +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DML +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_status (level, node_no, status) SELECT ... FROM transition_table_level1" +== 898 +-- truncate_limit: 100 +INSERT INTO transition_table_status (level, node_no, status) + SELECT 2, level2_no, 0 FROM transition_table_level2 +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DML +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_status (level, node_no, status) SELECT ... FROM transition_table_level2" +== 899 +-- truncate_limit: 100 +ANALYZE transition_table_status +-- +TABLE: name="transition_table_status" schema="" table="transition_table_status" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE transition_table_status" +== 900 +-- truncate_limit: 100 +INSERT INTO transition_table_level1(level1_no) + SELECT generate_series(201,1000) +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_level1 (level1_no) SELECT generate_series(201, 1000)" +== 901 +-- truncate_limit: 100 +ANALYZE transition_table_level1 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE transition_table_level1" +== 902 +-- truncate_limit: 100 +-- behave reasonably if someone tries to modify a transition table +CREATE FUNCTION transition_table_level2_bad_usage_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + BEGIN + INSERT INTO dx VALUES (1000000, 1000000, 'x'); + RETURN NULL; + END; +$$ +-- +FUNCTION: name="transition_table_level2_bad_usage_func" function="transition_table_level2_bad_usage_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION transition_table_level2_bad_usage_func() RETURNS trigger LANGUAGE plpgsql AS $$\n ..." +== 903 +-- truncate_limit: 100 +CREATE TRIGGER transition_table_level2_bad_usage_trigger + AFTER DELETE ON transition_table_level2 + REFERENCING OLD TABLE AS dx + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_bad_usage_func() +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER transition_table_level2_bad_usage_trigger AFTER DELETE ON transition_table_level2 ..." +== 904 +-- truncate_limit: 100 +DELETE FROM transition_table_level2 + WHERE level2_no BETWEEN 301 AND 305 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM transition_table_level2 WHERE level2_no BETWEEN 301 AND 305" +== 905 +-- truncate_limit: 100 +DROP TRIGGER transition_table_level2_bad_usage_trigger + ON transition_table_level2 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER transition_table_level2_bad_usage_trigger ON transition_table_level2" +== 906 +-- truncate_limit: 100 +-- attempt modifications which would break RI (should all fail) +DELETE FROM transition_table_level1 + WHERE level1_no = 25 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM transition_table_level1 WHERE level1_no = 25" +== 907 +-- truncate_limit: 100 +UPDATE transition_table_level1 SET level1_no = -1 + WHERE level1_no = 30 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE transition_table_level1 SET level1_no = -1 WHERE level1_no = 30" +== 908 +-- truncate_limit: 100 +INSERT INTO transition_table_level2 (level2_no, parent_no) + VALUES (10000, 10000) +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO transition_table_level2 (level2_no, parent_no) VALUES (10000, 10000)" +== 909 +-- truncate_limit: 100 +UPDATE transition_table_level2 SET parent_no = 2000 + WHERE level2_no = 40 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE transition_table_level2 SET parent_no = 2000 WHERE level2_no = 40" +== 910 +-- truncate_limit: 100 +-- attempt modifications which would not break RI (should all succeed) +DELETE FROM transition_table_level1 + WHERE level1_no BETWEEN 201 AND 1000 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM transition_table_level1 WHERE level1_no BETWEEN 201 AND 1000" +== 911 +-- truncate_limit: 100 +DELETE FROM transition_table_level1 + WHERE level1_no BETWEEN 100000000 AND 100000010 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM transition_table_level1 WHERE level1_no BETWEEN 100000000 AND 100000010" +== 912 +-- truncate_limit: 100 +SELECT count(*) FROM transition_table_level1 +-- +TABLE: name="transition_table_level1" schema="" table="transition_table_level1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM transition_table_level1" +== 913 +-- truncate_limit: 100 +DELETE FROM transition_table_level2 + WHERE level2_no BETWEEN 211 AND 220 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM transition_table_level2 WHERE level2_no BETWEEN 211 AND 220" +== 914 +-- truncate_limit: 100 +SELECT count(*) FROM transition_table_level2 +-- +TABLE: name="transition_table_level2" schema="" table="transition_table_level2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM transition_table_level2" +== 915 +-- truncate_limit: 100 +CREATE TABLE alter_table_under_transition_tables +( + id int PRIMARY KEY, + name text +) +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE alter_table_under_transition_tables (id int PRIMARY KEY, name text)" +== 916 +-- truncate_limit: 100 +CREATE FUNCTION alter_table_under_transition_tables_upd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ +BEGIN + RAISE WARNING 'old table = %, new table = %', + (SELECT string_agg(id || '=' || name, ',') FROM d), + (SELECT string_agg(id || '=' || name, ',') FROM i); + RAISE NOTICE 'one = %', (SELECT 1 FROM alter_table_under_transition_tables LIMIT 1); + RETURN NULL; +END; +$$ +-- +FUNCTION: name="alter_table_under_transition_tables_upd_func" function="alter_table_under_transition_tables_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION alter_table_under_transition_tables_upd_func() RETURNS trigger LANGUAGE plpgsql A..." +== 917 +-- truncate_limit: 100 +-- should fail, TRUNCATE is not compatible with transition tables +CREATE TRIGGER alter_table_under_transition_tables_upd_trigger + AFTER TRUNCATE OR UPDATE ON alter_table_under_transition_tables + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + alter_table_under_transition_tables_upd_func() +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER alter_table_under_transition_tables_upd_trigger AFTER UPDATE OR TRUNCATE ON alter_..." +== 918 +-- truncate_limit: 100 +-- should work +CREATE TRIGGER alter_table_under_transition_tables_upd_trigger + AFTER UPDATE ON alter_table_under_transition_tables + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + alter_table_under_transition_tables_upd_func() +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER alter_table_under_transition_tables_upd_trigger AFTER UPDATE ON alter_table_under_..." +== 919 +-- truncate_limit: 100 +INSERT INTO alter_table_under_transition_tables + VALUES (1, '1'), (2, '2'), (3, '3') +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO alter_table_under_transition_tables VALUES (1, '1'), (2, '2'), (3, '3')" +== 920 +-- truncate_limit: 100 +UPDATE alter_table_under_transition_tables + SET name = name || name +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE alter_table_under_transition_tables SET name = name || name" +== 921 +-- truncate_limit: 100 +-- now change 'name' to an integer to see what happens... +ALTER TABLE alter_table_under_transition_tables + ALTER COLUMN name TYPE int USING name::integer +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alter_table_under_transition_tables ALTER COLUMN name TYPE int USING name::int" +== 922 +-- truncate_limit: 100 +UPDATE alter_table_under_transition_tables + SET name = (name::text || name::text)::integer +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE alter_table_under_transition_tables SET name = (name::text || name::text)::int" +== 923 +-- truncate_limit: 100 +-- now drop column 'name' +ALTER TABLE alter_table_under_transition_tables + DROP column name +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE alter_table_under_transition_tables DROP name" +== 924 +-- truncate_limit: 100 +UPDATE alter_table_under_transition_tables + SET id = id +-- +TABLE: name="alter_table_under_transition_tables" schema="" table="alter_table_under_transition_tables" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE alter_table_under_transition_tables SET id = id" +== 925 +-- truncate_limit: 100 +|-- +-- Test multiple reference to a transition table +|-- + +CREATE TABLE multi_test (i int) +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE multi_test (i int)" +== 926 +-- truncate_limit: 100 +INSERT INTO multi_test VALUES (1) +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO multi_test VALUES (1)" +== 927 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION multi_test_trig() RETURNS trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'count = %', (SELECT COUNT(*) FROM new_test); + RAISE NOTICE 'count union = %', + (SELECT COUNT(*) + FROM (SELECT * FROM new_test UNION ALL SELECT * FROM new_test) ss); + RETURN NULL; +END$$ +-- +FUNCTION: name="multi_test_trig" function="multi_test_trig" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION multi_test_trig() RETURNS trigger LANGUAGE plpgsql AS $$\nBEGIN\n RAI..." +== 928 +-- truncate_limit: 100 +CREATE TRIGGER my_trigger AFTER UPDATE ON multi_test + REFERENCING NEW TABLE AS new_test OLD TABLE as old_test + FOR EACH STATEMENT EXECUTE PROCEDURE multi_test_trig() +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_trigger AFTER UPDATE ON multi_test REFERENCING NEW TABLE new_test OLD TABLE old..." +== 929 +-- truncate_limit: 100 +UPDATE multi_test SET i = i +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE multi_test SET i = i" +== 930 +-- truncate_limit: 100 +DROP TABLE multi_test +-- +TABLE: name="multi_test" schema="" table="multi_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE multi_test" +== 931 +-- truncate_limit: 100 +DROP FUNCTION multi_test_trig() +-- +FUNCTION: name="multi_test_trig" function="multi_test_trig" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION multi_test_trig()" +== 932 +-- truncate_limit: 100 +|-- +-- Check type parsing and record fetching from partitioned tables +|-- + +CREATE TABLE partitioned_table (a int, b text) PARTITION BY LIST (a) +-- +TABLE: name="partitioned_table" schema="" table="partitioned_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE partitioned_table (a int, b text) PARTITION BY LIST (a)" +== 933 +-- truncate_limit: 100 +CREATE TABLE pt_part1 PARTITION OF partitioned_table FOR VALUES IN (1) +-- +TABLE: name="pt_part1" schema="" table="pt_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt_part1 PARTITION OF partitioned_table FOR VALUES IN (1)" +== 934 +-- truncate_limit: 100 +CREATE TABLE pt_part2 PARTITION OF partitioned_table FOR VALUES IN (2) +-- +TABLE: name="pt_part2" schema="" table="pt_part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pt_part2 PARTITION OF partitioned_table FOR VALUES IN (2)" +== 935 +-- truncate_limit: 100 +INSERT INTO partitioned_table VALUES (1, 'Row 1') +-- +TABLE: name="partitioned_table" schema="" table="partitioned_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO partitioned_table VALUES (1, 'Row 1')" +== 936 +-- truncate_limit: 100 +INSERT INTO partitioned_table VALUES (2, 'Row 2') +-- +TABLE: name="partitioned_table" schema="" table="partitioned_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO partitioned_table VALUES (2, 'Row 2')" +== 937 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION get_from_partitioned_table(partitioned_table.a%type) +RETURNS partitioned_table AS $$ +DECLARE + a_val partitioned_table.a%TYPE; + result partitioned_table%ROWTYPE; +BEGIN + a_val := $1; + SELECT * INTO result FROM partitioned_table WHERE a = a_val; + RETURN result; +END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="get_from_partitioned_table" function="get_from_partitioned_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION get_from_partitioned_table(partitioned_table.a%type) RETURNS partition..." +== 938 +-- truncate_limit: 100 +SELECT * FROM get_from_partitioned_table(1) AS t +-- +FUNCTION: name="get_from_partitioned_table" function="get_from_partitioned_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM get_from_partitioned_table(1) t" +== 939 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION list_partitioned_table() +RETURNS SETOF public.partitioned_table.a%TYPE AS $$ +DECLARE + row public.partitioned_table%ROWTYPE; + a_val public.partitioned_table.a%TYPE; +BEGIN + FOR row IN SELECT * FROM public.partitioned_table ORDER BY a LOOP + a_val := row.a; + RETURN NEXT a_val; + END LOOP; + RETURN; +END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="list_partitioned_table" function="list_partitioned_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION list_partitioned_table() RETURNS SETOF public.partitioned_table.a%type..." +== 940 +-- truncate_limit: 100 +SELECT * FROM list_partitioned_table() AS t +-- +FUNCTION: name="list_partitioned_table" function="list_partitioned_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM list_partitioned_table() t" +== 941 +-- truncate_limit: 100 +|-- +-- Check argument name is used instead of $n in error message +|-- +CREATE FUNCTION fx(x WSlot) RETURNS void AS $$ +BEGIN + GET DIAGNOSTICS x = ROW_COUNT; + RETURN; +END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="fx" function="fx" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fx(x wslot) RETURNS void AS $$\nBEGIN\n GET DIAGNOSTICS x = ROW_COUNT;\n RETURN;\nE..." diff --git a/parser/testdata/summary_truncate/postgres_regress/point.metadata.json b/parser/testdata/summary_truncate/postgres_regress/point.metadata.json new file mode 100644 index 0000000..e74143a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/point.metadata.json @@ -0,0 +1,47 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/point.test b/parser/testdata/summary_truncate/postgres_regress/point.test new file mode 100644 index 0000000..4796b85 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/point.test @@ -0,0 +1,394 @@ +== 001 +-- truncate_limit: 100 +|-- +-- POINT +|-- + +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO 0" +== 002 +-- truncate_limit: 100 +-- point_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. + +INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES ('asdfasdf')" +== 003 +-- truncate_limit: 100 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES ('(10.0 10.0)')" +== 004 +-- truncate_limit: 100 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 10.0) x') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES ('(10.0, 10.0) x')" +== 005 +-- truncate_limit: 100 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES ('(10.0,10.0')" +== 006 +-- truncate_limit: 100 +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 1e+500)') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES ('(10.0, 1e+500)')" +== 007 +-- truncate_limit: 100 +-- Out of range + + +SELECT * FROM POINT_TBL +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM point_tbl" +== 008 +-- truncate_limit: 100 +-- left of +SELECT p.* FROM POINT_TBL p WHERE p.f1 << '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'" +== 009 +-- truncate_limit: 100 +-- right of +SELECT p.* FROM POINT_TBL p WHERE '(0.0,0.0)' >> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE '(0.0,0.0)' >> p.f1" +== 010 +-- truncate_limit: 100 +-- above +SELECT p.* FROM POINT_TBL p WHERE '(0.0,0.0)' |>> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE '(0.0,0.0)' |>> p.f1" +== 011 +-- truncate_limit: 100 +-- below +SELECT p.* FROM POINT_TBL p WHERE p.f1 <<| '(0.0, 0.0)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)'" +== 012 +-- truncate_limit: 100 +-- equal +SELECT p.* FROM POINT_TBL p WHERE p.f1 ~= '(5.1, 34.5)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE p.f1 ~= '(5.1, 34.5)'" +== 013 +-- truncate_limit: 100 +-- point in box +SELECT p.* FROM POINT_TBL p + WHERE p.f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE p.f1 <@ '(0,0,100,100)'::box" +== 014 +-- truncate_limit: 100 +SELECT p.* FROM POINT_TBL p + WHERE box '(0,0,100,100)' @> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE '(0,0,100,100)'::box @> p.f1" +== 015 +-- truncate_limit: 100 +SELECT p.* FROM POINT_TBL p + WHERE not p.f1 <@ box '(0,0,100,100)' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE NOT p.f1 <@ '(0,0,100,100)'::box" +== 016 +-- truncate_limit: 100 +SELECT p.* FROM POINT_TBL p + WHERE p.f1 <@ path '[(0,0),(-10,0),(-10,10)]' +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE p.f1 <@ '[(0,0),(-10,0),(-10,10)]'::path" +== 017 +-- truncate_limit: 100 +SELECT p.* FROM POINT_TBL p + WHERE not box '(0,0,100,100)' @> p.f1 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +FILTER: schema="" table="p" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p.* FROM point_tbl p WHERE NOT '(0,0,100,100)'::box @> p.f1" +== 018 +-- truncate_limit: 100 +SELECT p.f1, p.f1 <-> point '(0,0)' AS dist + FROM POINT_TBL p + ORDER BY dist +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT p.f1, p.f1 <-> point '(0,0)' AS dist FROM point_tbl p ORDER BY dist" +== 019 +-- truncate_limit: 100 +SELECT 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] +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM point_tbl p1, point_tbl p2 ORDER BY dist, p1.f1[0], p2.f1[0]" +== 020 +-- truncate_limit: 100 +SELECT p1.f1 AS point1, p2.f1 AS point2 + FROM POINT_TBL p1, POINT_TBL p2 + WHERE (p1.f1 <-> p2.f1) > 3 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT p1.f1 AS point1, p2.f1 AS point2 FROM point_tbl p1, point_tbl p2 WHERE (p1.f1 <-> p2.f1) > 3" +== 021 +-- truncate_limit: 100 +-- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 +SELECT 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] +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM point_tbl p1, point_tbl p2 WHERE ... ORDER BY distance, p1.f1[0], p2.f1[0]" +== 022 +-- truncate_limit: 100 +-- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 +SELECT 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 +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=Select +ALIAS: "p1"="point_tbl" +ALIAS: "p2"="point_tbl" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +FILTER: schema="" table="p1" column="f1" +FILTER: schema="" table="p2" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM point_tbl p1, point_tbl p2 WHERE ... ORDER BY distance" +== 023 +-- truncate_limit: 100 +-- Test that GiST indexes provide same behavior as sequential scan +CREATE TEMP TABLE point_gist_tbl(f1 point) +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE point_gist_tbl (f1 point)" +== 024 +-- truncate_limit: 100 +INSERT INTO point_gist_tbl SELECT '(0,0)' FROM generate_series(0,1000) +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_gist_tbl SELECT '(0,0)' FROM generate_series(0, 1000)" +== 025 +-- truncate_limit: 100 +CREATE INDEX point_gist_tbl_index ON point_gist_tbl USING gist (f1) +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX point_gist_tbl_index ON point_gist_tbl USING gist (f1)" +== 026 +-- truncate_limit: 100 +INSERT INTO point_gist_tbl VALUES ('(0.0000009,0.0000009)') +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_gist_tbl VALUES ('(0.0000009,0.0000009)')" +== 027 +-- truncate_limit: 100 +SET enable_seqscan TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO TRUE" +== 028 +-- truncate_limit: 100 +SET enable_indexscan TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO FALSE" +== 029 +-- truncate_limit: 100 +SET enable_bitmapscan TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO FALSE" +== 030 +-- truncate_limit: 100 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point" +== 031 +-- truncate_limit: 100 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box" +== 032 +-- truncate_limit: 100 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point" +== 033 +-- truncate_limit: 100 +SET enable_seqscan TO false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO FALSE" +== 034 +-- truncate_limit: 100 +SET enable_indexscan TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO TRUE" +== 035 +-- truncate_limit: 100 +SET enable_bitmapscan TO true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO TRUE" +== 036 +-- truncate_limit: 100 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point" +== 037 +-- truncate_limit: 100 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box" +== 038 +-- truncate_limit: 100 +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point +-- +TABLE: name="point_gist_tbl" schema="" table="point_gist_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point" +== 039 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 040 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 041 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 042 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('1,y', 'point') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('1,y', 'point')" +== 043 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('1,y', 'point') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('1,y', 'point')" diff --git a/parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json b/parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json new file mode 100644 index 0000000..7d59f7e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json @@ -0,0 +1,66 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/polygon.test b/parser/testdata/summary_truncate/postgres_regress/polygon.test new file mode 100644 index 0000000..6a665bb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/polygon.test @@ -0,0 +1,568 @@ +== 001 +-- truncate_limit: 100 +|-- +-- POLYGON +|-- +-- polygon logic +|-- + +CREATE TABLE POLYGON_TBL(f1 polygon) +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE polygon_tbl (f1 polygon)" +== 002 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(2.0,0.0),(2.0,4.0),(0.0,0.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(2.0,0.0),(2.0,4.0),(0.0,0.0)')" +== 003 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(3.0,1.0),(3.0,3.0),(1.0,0.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(3.0,1.0),(3.0,3.0),(1.0,0.0)')" +== 004 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(3,4),(5,6),(7,8)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(1,2),(3,4),(5,6),(7,8)')" +== 005 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(7,8),(5,6),(3,4),(1,2)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(7,8),(5,6),(3,4),(1,2)')" +== 006 +-- truncate_limit: 100 +-- Reverse +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(7,8),(5,6),(3,-4)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(1,2),(7,8),(5,6),(3,-4)')" +== 007 +-- truncate_limit: 100 +-- degenerate polygons +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,0.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(0.0,0.0)')" +== 008 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,1.0),(0.0,1.0)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(0.0,1.0),(0.0,1.0)')" +== 009 +-- truncate_limit: 100 +-- bad polygon input strings +INSERT INTO POLYGON_TBL(f1) VALUES ('0.0') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('0.0')" +== 010 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0 0.0') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(0.0 0.0')" +== 011 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2)') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(0,1,2)')" +== 012 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2,3') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('(0,1,2,3')" +== 013 +-- truncate_limit: 100 +INSERT INTO POLYGON_TBL(f1) VALUES ('asdf') +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO polygon_tbl (f1) VALUES ('asdf')" +== 014 +-- truncate_limit: 100 +SELECT * FROM POLYGON_TBL +-- +TABLE: name="polygon_tbl" schema="" table="polygon_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM polygon_tbl" +== 015 +-- truncate_limit: 100 +|-- +-- Test the SP-GiST index +|-- + +CREATE TABLE quad_poly_tbl (id int, p polygon) +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE quad_poly_tbl (id int, p polygon)" +== 016 +-- truncate_limit: 100 +INSERT INTO quad_poly_tbl + SELECT (x - 1) * 100 + y, polygon(circle(point(x * 10, y * 10), 1 + (x + y) % 10)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DML +FUNCTION: name="polygon" function="polygon" schema="" ctx=Call +FUNCTION: name="circle" function="circle" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_poly_tbl SELECT ... FROM generate_series(1, 100) x, generate_series(1, 100) y" +== 017 +-- truncate_limit: 100 +INSERT INTO quad_poly_tbl + SELECT i, polygon '((200, 300),(210, 310),(230, 290))' + FROM generate_series(10001, 11000) AS i +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_poly_tbl SELECT ... FROM generate_series(10001, 11000) i" +== 018 +-- truncate_limit: 100 +INSERT INTO quad_poly_tbl + VALUES + (11001, NULL), + (11002, NULL), + (11003, NULL) +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quad_poly_tbl VALUES (11001, NULL), (11002, NULL), (11003, NULL)" +== 019 +-- truncate_limit: 100 +CREATE INDEX quad_poly_tbl_idx ON quad_poly_tbl USING spgist(p) +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX quad_poly_tbl_idx ON quad_poly_tbl USING spgist (p)" +== 020 +-- truncate_limit: 100 +-- get reference results for ORDER BY distance from seq scan +SET enable_seqscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 021 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 022 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 023 +-- truncate_limit: 100 +CREATE TEMP TABLE quad_poly_tbl_ord_seq2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl_ord_seq2" schema="" table="quad_poly_tbl_ord_seq2" ctx=DDL +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_poly_tbl_ord_seq2 AS SELECT rank() OVER (ORDER BY p <-> point '123,4..." +== 024 +-- truncate_limit: 100 +-- check results from index scan +SET enable_seqscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 025 +-- truncate_limit: 100 +SET enable_indexscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 026 +-- truncate_limit: 100 +SET enable_bitmapscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 027 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p << polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p << '((300,300),(400,600),(600,500)..." +== 028 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p << polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p << '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 029 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p &< polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p &< '((300,300),(400,600),(600,500)..." +== 030 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p &< polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p &< '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 031 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p && polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p && '((300,300),(400,600),(600,500)..." +== 032 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p && polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p && '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 033 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p &> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p &> '((300,300),(400,600),(600,500)..." +== 034 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p &> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p &> '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 035 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p >> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p >> '((300,300),(400,600),(600,500)..." +== 036 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p >> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p >> '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 037 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p <<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p <<| '((300,300),(400,600),(600,500..." +== 038 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p <<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p <<| '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 039 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p &<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p &<| '((300,300),(400,600),(600,500..." +== 040 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p &<| polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p &<| '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 041 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p |&> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p |&> '((300,300),(400,600),(600,500..." +== 042 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p |&> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p |&> '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 043 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p |>> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p |>> '((300,300),(400,600),(600,500..." +== 044 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p |>> polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p |>> '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 045 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p <@ '((300,300),(400,600),(600,500)..." +== 046 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p <@ '((300,300),(400,600),(600,500),(700,200))'::polygon" +== 047 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p @> polygon '((340,550),(343,552),(341,553))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p @> '((340,550),(343,552),(341,553)..." +== 048 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p @> polygon '((340,550),(343,552),(341,553))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p @> '((340,550),(343,552),(341,553))'::polygon" +== 049 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p ~= '((200, 300),(210, 310),(230, 2..." +== 050 +-- truncate_limit: 100 +SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM quad_poly_tbl WHERE p ~= '((200, 300),(210, 310),(230, 290))'::polygon" +== 051 +-- truncate_limit: 100 +-- test ORDER BY distance +SET enable_indexscan = ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 052 +-- truncate_limit: 100 +SET enable_bitmapscan = OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 053 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT rank() OVER (ORDER BY p <-> point '123,456') AS n, p <-> point '123,..." +== 054 +-- truncate_limit: 100 +CREATE TEMP TABLE quad_poly_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))' +-- +TABLE: name="quad_poly_tbl_ord_idx2" schema="" table="quad_poly_tbl_ord_idx2" ctx=DDL +TABLE: name="quad_poly_tbl" schema="" table="quad_poly_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="p" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE quad_poly_tbl_ord_idx2 AS SELECT rank() OVER (ORDER BY p <-> point '123,4..." +== 055 +-- truncate_limit: 100 +SELECT * +FROM quad_poly_tbl_ord_seq2 seq FULL JOIN quad_poly_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 +-- +TABLE: name="quad_poly_tbl_ord_seq2" schema="" table="quad_poly_tbl_ord_seq2" ctx=Select +TABLE: name="quad_poly_tbl_ord_idx2" schema="" table="quad_poly_tbl_ord_idx2" ctx=Select +ALIAS: "idx"="quad_poly_tbl_ord_idx2" +ALIAS: "seq"="quad_poly_tbl_ord_seq2" +FILTER: schema="" table="seq" column="id" +FILTER: schema="" table="idx" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quad_poly_tbl_ord_seq2 seq FULL JOIN quad_poly_tbl_ord_idx2 idx ON seq.n = idx.n AN..." +== 056 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 057 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 058 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 059 +-- truncate_limit: 100 +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('(2.0,0.8,0.1)', 'polygon') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(2.0,0.8,0.1)', 'polygon')" +== 060 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(2.0,0.8,0.1)', 'polygon') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(2.0,0.8,0.1)', 'polygon')" +== 061 +-- truncate_limit: 100 +SELECT pg_input_is_valid('(2.0,xyz)', 'polygon') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(2.0,xyz)', 'polygon')" +== 062 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(2.0,xyz)', 'polygon') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(2.0,xyz)', 'polygon')" diff --git a/parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json b/parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json new file mode 100644 index 0000000..835764e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json @@ -0,0 +1,427 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/polymorphism.test b/parser/testdata/summary_truncate/postgres_regress/polymorphism.test new file mode 100644 index 0000000..30e49f2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/polymorphism.test @@ -0,0 +1,3658 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for polymorphic SQL functions and aggregates based on them. +-- Tests for other features related to function-calling have snuck in, too. +|-- + +create function polyf(x anyelement) returns anyelement as $$ + select x + 1 +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anyelement) RETURNS anyelement AS $$\n select x + 1\n$$ LANGUAGE sql" +== 002 +-- truncate_limit: 100 +select polyf(42) as int, polyf(4.5) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(42) AS \"int\", polyf(4.5) AS num" +== 003 +-- truncate_limit: 100 +select polyf(point(3,4)) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(point(3, 4))" +== 004 +-- truncate_limit: 100 +-- fail for lack of + operator + +drop function polyf(x anyelement) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anyelement)" +== 005 +-- truncate_limit: 100 +create function polyf(x anyelement) returns anyarray as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anyelement) RETURNS anyarray AS $$\n select array[x + 1, x + 2]\n$$ LANGUA..." +== 006 +-- truncate_limit: 100 +select polyf(42) as int, polyf(4.5) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(42) AS \"int\", polyf(4.5) AS num" +== 007 +-- truncate_limit: 100 +drop function polyf(x anyelement) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anyelement)" +== 008 +-- truncate_limit: 100 +create function polyf(x anyarray) returns anyelement as $$ + select x[1] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anyarray) RETURNS anyelement AS $$\n select x[1]\n$$ LANGUAGE sql" +== 009 +-- truncate_limit: 100 +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(ARRAY[2, 4]) AS \"int\", polyf(ARRAY[4.5, 7.7]) AS num" +== 010 +-- truncate_limit: 100 +select polyf(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(stavalues1) FROM pg_statistic" +== 011 +-- truncate_limit: 100 +-- fail, can't infer element type + +drop function polyf(x anyarray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anyarray)" +== 012 +-- truncate_limit: 100 +create function polyf(x anyarray) returns anyarray as $$ + select x +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anyarray) RETURNS anyarray AS $$\n select x\n$$ LANGUAGE sql" +== 013 +-- truncate_limit: 100 +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(ARRAY[2, 4]) AS \"int\", polyf(ARRAY[4.5, 7.7]) AS num" +== 014 +-- truncate_limit: 100 +select polyf(stavalues1) from pg_statistic +-- +TABLE: name="pg_statistic" schema="" table="pg_statistic" ctx=Select +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(stavalues1) FROM pg_statistic" +== 015 +-- truncate_limit: 100 +-- fail, can't infer element type + +drop function polyf(x anyarray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anyarray)" +== 016 +-- truncate_limit: 100 +-- fail, can't infer type: +create function polyf(x anyelement) returns anyrange as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anyelement) RETURNS anyrange AS $$\n select array[x + 1, x + 2]\n$$ LANGUA..." +== 017 +-- truncate_limit: 100 +create function polyf(x anyrange) returns anyarray as $$ + select array[lower(x), upper(x)] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anyrange) RETURNS anyarray AS $$\n select array[lower(x), upper(x)]\n$$ LA..." +== 018 +-- truncate_limit: 100 +select polyf(int4range(42, 49)) as int, polyf(float8range(4.5, 7.8)) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4range(42, 49)) AS \"int\", polyf(float8range(4.5, 7.8)) AS num" +== 019 +-- truncate_limit: 100 +drop function polyf(x anyrange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anyrange)" +== 020 +-- truncate_limit: 100 +create function polyf(x anycompatible, y anycompatible) returns anycompatiblearray as $$ + select array[x, y] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anycompatible, y anycompatible) RETURNS anycompatiblearray AS $$\n select..." +== 021 +-- truncate_limit: 100 +select polyf(2, 4) as int, polyf(2, 4.5) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(2, 4) AS \"int\", polyf(2, 4.5) AS num" +== 022 +-- truncate_limit: 100 +drop function polyf(x anycompatible, y anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anycompatible, y anycompatible)" +== 023 +-- truncate_limit: 100 +create function polyf(x anycompatiblerange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ + select array[lower(x), upper(x), y, z] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anycompatiblerange, y anycompatible, z anycompatible) RETURNS anycompatib..." +== 024 +-- truncate_limit: 100 +select polyf(int4range(42, 49), 11, 2::smallint) as int, polyf(float8range(4.5, 7.8), 7.8, 11::real) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 025 +-- truncate_limit: 100 +select polyf(int4range(42, 49), 11, 4.5) as fail +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4range(42, 49), 11, 4.5) AS fail" +== 026 +-- truncate_limit: 100 +-- range type doesn't fit + +drop function polyf(x anycompatiblerange, y anycompatible, z anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anycompatiblerange, y anycompatible, z anycompatible)" +== 027 +-- truncate_limit: 100 +create function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ + select array[lower(x), upper(x), y, z] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anycompatiblemultirange, y anycompatible, z anycompatible) RETURNS anycom..." +== 028 +-- truncate_limit: 100 +select polyf(multirange(int4range(42, 49)), 11, 2::smallint) as int, polyf(multirange(float8range(4.5, 7.8)), 7.8, 11::real) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 029 +-- truncate_limit: 100 +select polyf(multirange(int4range(42, 49)), 11, 4.5) as fail +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(multirange(int4range(42, 49)), 11, 4.5) AS fail" +== 030 +-- truncate_limit: 100 +-- range type doesn't fit + +drop function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anycompatiblemultirange, y anycompatible, z anycompatible)" +== 031 +-- truncate_limit: 100 +-- fail, can't infer type: +create function polyf(x anycompatible) returns anycompatiblerange as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anycompatible) RETURNS anycompatiblerange AS $$\n select array[x + 1, x +..." +== 032 +-- truncate_limit: 100 +create function polyf(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ + select x +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anycompatiblerange, y anycompatiblearray) RETURNS anycompatiblerange AS $..." +== 033 +-- truncate_limit: 100 +select polyf(int4range(42, 49), array[11]) as int, polyf(float8range(4.5, 7.8), array[7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4range(42, 49), ARRAY[11]) AS \"int\", polyf(float8range(4.5, 7.8), ARRAY[7]) AS num" +== 034 +-- truncate_limit: 100 +drop function polyf(x anycompatiblerange, y anycompatiblearray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anycompatiblerange, y anycompatiblearray)" +== 035 +-- truncate_limit: 100 +-- fail, can't infer type: +create function polyf(x anycompatible) returns anycompatiblemultirange as $$ + select array[x + 1, x + 2] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anycompatible) RETURNS anycompatiblemultirange AS $$\n select array[x + 1..." +== 036 +-- truncate_limit: 100 +create function polyf(x anycompatiblemultirange, y anycompatiblearray) returns anycompatiblemultirange as $$ + select x +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(x anycompatiblemultirange, y anycompatiblearray) RETURNS anycompatiblemulti..." +== 037 +-- truncate_limit: 100 +select polyf(multirange(int4range(42, 49)), array[11]) as int, polyf(multirange(float8range(4.5, 7.8)), array[7]) as num +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 038 +-- truncate_limit: 100 +drop function polyf(x anycompatiblemultirange, y anycompatiblearray) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(x anycompatiblemultirange, y anycompatiblearray)" +== 039 +-- truncate_limit: 100 +create function polyf(a anyelement, b anyarray, + c anycompatible, d anycompatible, + OUT x anyarray, OUT y anycompatiblearray) +as $$ + select a || b, array[c, d] +$$ language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(a anyelement, b anyarray, c anycompatible, d anycompatible, OUT x anyarray,..." +== 040 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM polyf(11, ARRAY[1, 2], 42, 34.5)" +== 041 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2], point(1,2), point(3,4)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM polyf(11, ARRAY[1, 2], point(1, 2), point(3, 4))" +== 042 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, '{1,2}', point(1,2), '(3,4)') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM polyf(11, '{1,2}', point(1, 2), '(3,4)')" +== 043 +-- truncate_limit: 100 +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2.2], 42, 34.5) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x), y, pg_typeof(y) FROM polyf(11, ARRAY[1, 2.2], 42, 34.5)" +== 044 +-- truncate_limit: 100 +-- fail + +drop function polyf(a anyelement, b anyarray, + c anycompatible, d anycompatible) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(a anyelement, b anyarray, c anycompatible, d anycompatible)" +== 045 +-- truncate_limit: 100 +create function polyf(anyrange) returns anymultirange +as 'select multirange($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(anyrange) RETURNS anymultirange AS $$select multirange($1);$$ LANGUAGE sql" +== 046 +-- truncate_limit: 100 +select polyf(int4range(1,10)) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4range(1, 10))" +== 047 +-- truncate_limit: 100 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(NULL)" +== 048 +-- truncate_limit: 100 +drop function polyf(anyrange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(anyrange)" +== 049 +-- truncate_limit: 100 +create function polyf(anymultirange) returns anyelement +as 'select lower($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(anymultirange) RETURNS anyelement AS $$select lower($1);$$ LANGUAGE sql" +== 050 +-- truncate_limit: 100 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4multirange(int4range(1, 10), int4range(20, 30)))" +== 051 +-- truncate_limit: 100 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(NULL)" +== 052 +-- truncate_limit: 100 +drop function polyf(anymultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(anymultirange)" +== 053 +-- truncate_limit: 100 +create function polyf(anycompatiblerange) returns anycompatiblemultirange +as 'select multirange($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(anycompatiblerange) RETURNS anycompatiblemultirange AS $$select multirange(..." +== 054 +-- truncate_limit: 100 +select polyf(int4range(1,10)) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4range(1, 10))" +== 055 +-- truncate_limit: 100 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(NULL)" +== 056 +-- truncate_limit: 100 +drop function polyf(anycompatiblerange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(anycompatiblerange)" +== 057 +-- truncate_limit: 100 +create function polyf(anymultirange) returns anyrange +as 'select range_merge($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(anymultirange) RETURNS anyrange AS $$select range_merge($1);$$ LANGUAGE sql" +== 058 +-- truncate_limit: 100 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4multirange(int4range(1, 10), int4range(20, 30)))" +== 059 +-- truncate_limit: 100 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(NULL)" +== 060 +-- truncate_limit: 100 +drop function polyf(anymultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(anymultirange)" +== 061 +-- truncate_limit: 100 +create function polyf(anycompatiblemultirange) returns anycompatiblerange +as 'select range_merge($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(anycompatiblemultirange) RETURNS anycompatiblerange AS $$select range_merge..." +== 062 +-- truncate_limit: 100 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4multirange(int4range(1, 10), int4range(20, 30)))" +== 063 +-- truncate_limit: 100 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(NULL)" +== 064 +-- truncate_limit: 100 +drop function polyf(anycompatiblemultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(anycompatiblemultirange)" +== 065 +-- truncate_limit: 100 +create function polyf(anycompatiblemultirange) returns anycompatible +as 'select lower($1);' language sql +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION polyf(anycompatiblemultirange) RETURNS anycompatible AS $$select lower($1);$$ LAN..." +== 066 +-- truncate_limit: 100 +select polyf(int4multirange(int4range(1,10), int4range(20,30))) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(int4multirange(int4range(1, 10), int4range(20, 30)))" +== 067 +-- truncate_limit: 100 +select polyf(null) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT polyf(NULL)" +== 068 +-- truncate_limit: 100 +drop function polyf(anycompatiblemultirange) +-- +FUNCTION: name="polyf" function="polyf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION polyf(anycompatiblemultirange)" +== 069 +-- truncate_limit: 100 +|-- +-- Polymorphic aggregate tests +|-- +-- Legend: +----------- +-- A = type is ANY +-- P = type is polymorphic +-- N = type is non-polymorphic +-- B = aggregate base type +-- S = aggregate state type +-- R = aggregate return type +-- 1 = arg1 of a function +-- 2 = arg2 of a function +-- ag = aggregate +-- tf = trans (state) function +-- ff = final function +-- rt = return type of a function +-- -> = implies +-- => = allowed +-- !> = not allowed +-- E = exists +-- NE = not-exists +|-- +-- Possible states: +-- ---------------- +-- B = (A || P || N) +-- when (B = A) -> (tf2 = NE) +-- S = (P || N) +-- ff = (E || NE) +-- tf1 = (P || N) +-- tf2 = (NE || P || N) +-- R = (P || N) + +-- create functions for use as tf and ff with the needed combinations of +-- argument polymorphism, but within the constraints of valid aggregate +-- functions, i.e. tf arg1 and tf return type must match + +-- polymorphic single arg transfn +CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="stfp" function="stfp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS $$select $1$$ LANGUAGE sql" +== 070 +-- truncate_limit: 100 +-- non-polymorphic single arg transfn +CREATE FUNCTION stfnp(int[]) RETURNS int[] AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="stfnp" function="stfnp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION stfnp(int[]) RETURNS int[] AS $$select $1$$ LANGUAGE sql" +== 071 +-- truncate_limit: 100 +-- dual polymorphic transfn +CREATE FUNCTION tfp(anyarray,anyelement) RETURNS anyarray AS +'select $1 || $2' LANGUAGE SQL +-- +FUNCTION: name="tfp" function="tfp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tfp(anyarray, anyelement) RETURNS anyarray AS $$select $1 || $2$$ LANGUAGE sql" +== 072 +-- truncate_limit: 100 +-- dual non-polymorphic transfn +CREATE FUNCTION tfnp(int[],int) RETURNS int[] AS +'select $1 || $2' LANGUAGE SQL +-- +FUNCTION: name="tfnp" function="tfnp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tfnp(int[], int) RETURNS int[] AS $$select $1 || $2$$ LANGUAGE sql" +== 073 +-- truncate_limit: 100 +-- arg1 only polymorphic transfn +CREATE FUNCTION tf1p(anyarray,int) RETURNS anyarray AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="tf1p" function="tf1p" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tf1p(anyarray, int) RETURNS anyarray AS $$select $1$$ LANGUAGE sql" +== 074 +-- truncate_limit: 100 +-- arg2 only polymorphic transfn +CREATE FUNCTION tf2p(int[],anyelement) RETURNS int[] AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="tf2p" function="tf2p" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tf2p(int[], anyelement) RETURNS int[] AS $$select $1$$ LANGUAGE sql" +== 075 +-- truncate_limit: 100 +-- multi-arg polymorphic +CREATE FUNCTION sum3(anyelement,anyelement,anyelement) returns anyelement AS +'select $1+$2+$3' language sql strict +-- +FUNCTION: name="sum3" function="sum3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sum3(anyelement, anyelement, anyelement) RETURNS anyelement AS $$select $1+$2+$3$..." +== 076 +-- truncate_limit: 100 +-- finalfn polymorphic +CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS +'select $1' LANGUAGE SQL +-- +FUNCTION: name="ffp" function="ffp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS $$select $1$$ LANGUAGE sql" +== 077 +-- truncate_limit: 100 +-- finalfn non-polymorphic +CREATE FUNCTION ffnp(int[]) returns int[] as +'select $1' LANGUAGE SQL +-- +FUNCTION: name="ffnp" function="ffnp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ffnp(int[]) RETURNS int[] AS $$select $1$$ LANGUAGE sql" +== 078 +-- truncate_limit: 100 +-- Try to cover all the possible states: +|-- +-- Note: in Cases 1 & 2, we are trying to return P. Therefore, if the transfn +-- is stfnp, tfnp, or tf2p, we must use ffp as finalfn, because stfnp, tfnp, +-- and tf2p do not return P. Conversely, in Cases 3 & 4, we are trying to +-- return N. Therefore, if the transfn is stfp, tfp, or tf1p, we must use ffnp +-- as finalfn, because stfp, tfp, and tf1p do not return N. +|-- +-- Case1 (R = P) && (B = A) +-- ------------------------ +-- S tf1 +-- ------- +-- N N +-- should CREATE +CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp01a (*) (sfunc = stfnp, stype = int4[], finalfunc = ffp, initcond = '{}')" +== 079 +-- truncate_limit: 100 +-- P N +-- should ERROR: stfnp(anyarray) not matched by stfnp(int[]) +CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp02a (*) (sfunc = stfnp, stype = anyarray, finalfunc = ffp, initcond = '{}')" +== 080 +-- truncate_limit: 100 +-- N P +-- should CREATE +CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp03a (*) (sfunc = stfp, stype = int4[], finalfunc = ffp, initcond = '{}')" +== 081 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp03b (*) (sfunc = stfp, stype = int4[], initcond = '{}')" +== 082 +-- truncate_limit: 100 +-- P P +-- should ERROR: we have no way to resolve S +CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp04a (*) (sfunc = stfp, stype = anyarray, finalfunc = ffp, initcond = '{}')" +== 083 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp04b (*) (sfunc = stfp, stype = anyarray, initcond = '{}')" +== 084 +-- truncate_limit: 100 +-- Case2 (R = P) && ((B = P) || (B = N)) +-- ------------------------------------- +-- S tf1 B tf2 +-- ----------------------- +-- N N N N +-- should CREATE +CREATE AGGREGATE myaggp05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp05a (basetype = int, sfunc = tfnp, stype = int[], finalfunc = ffp, initcon..." +== 085 +-- truncate_limit: 100 +-- N N N P +-- should CREATE +CREATE AGGREGATE myaggp06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp06a (basetype = int, sfunc = tf2p, stype = int[], finalfunc = ffp, initcon..." +== 086 +-- truncate_limit: 100 +-- N N P N +-- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int) +CREATE AGGREGATE myaggp07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp07a (basetype = anyelement, sfunc = tfnp, stype = int[], finalfunc = ffp, ..." +== 087 +-- truncate_limit: 100 +-- N N P P +-- should CREATE +CREATE AGGREGATE myaggp08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp08a (basetype = anyelement, sfunc = tf2p, stype = int[], finalfunc = ffp, ..." +== 088 +-- truncate_limit: 100 +-- N P N N +-- should CREATE +CREATE AGGREGATE myaggp09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp09a (basetype = int, sfunc = tf1p, stype = int[], finalfunc = ffp, initcon..." +== 089 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp09b(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp09b (basetype = int, sfunc = tf1p, stype = int[], initcond = '{}')" +== 090 +-- truncate_limit: 100 +-- N P N P +-- should CREATE +CREATE AGGREGATE myaggp10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp10a (basetype = int, sfunc = tfp, stype = int[], finalfunc = ffp, initcond..." +== 091 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp10b(BASETYPE = int, SFUNC = tfp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp10b (basetype = int, sfunc = tfp, stype = int[], initcond = '{}')" +== 092 +-- truncate_limit: 100 +-- N P P N +-- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int) +CREATE AGGREGATE myaggp11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp11a (basetype = anyelement, sfunc = tf1p, stype = int[], finalfunc = ffp, ..." +== 093 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp11b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp11b (basetype = anyelement, sfunc = tf1p, stype = int[], initcond = '{}')" +== 094 +-- truncate_limit: 100 +-- N P P P +-- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement) +CREATE AGGREGATE myaggp12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp12a (basetype = anyelement, sfunc = tfp, stype = int[], finalfunc = ffp, i..." +== 095 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp12b(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp12b (basetype = anyelement, sfunc = tfp, stype = int[], initcond = '{}')" +== 096 +-- truncate_limit: 100 +-- P N N N +-- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp13a (basetype = int, sfunc = tfnp, stype = anyarray, finalfunc = ffp, init..." +== 097 +-- truncate_limit: 100 +-- P N N P +-- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp14a (basetype = int, sfunc = tf2p, stype = anyarray, finalfunc = ffp, init..." +== 098 +-- truncate_limit: 100 +-- P N P N +-- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp15a (basetype = anyelement, sfunc = tfnp, stype = anyarray, finalfunc = ff..." +== 099 +-- truncate_limit: 100 +-- P N P P +-- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggp16a(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp16a (basetype = anyelement, sfunc = tf2p, stype = anyarray, finalfunc = ff..." +== 100 +-- truncate_limit: 100 +-- P P N N +-- should ERROR: we have no way to resolve S +CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp17a (basetype = int, sfunc = tf1p, stype = anyarray, finalfunc = ffp, init..." +== 101 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp17b (basetype = int, sfunc = tf1p, stype = anyarray, initcond = '{}')" +== 102 +-- truncate_limit: 100 +-- P P N P +-- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) +CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp18a (basetype = int, sfunc = tfp, stype = anyarray, finalfunc = ffp, initc..." +== 103 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp18b (basetype = int, sfunc = tfp, stype = anyarray, initcond = '{}')" +== 104 +-- truncate_limit: 100 +-- P P P N +-- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) +CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp19a (basetype = anyelement, sfunc = tf1p, stype = anyarray, finalfunc = ff..." +== 105 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp19b(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp19b (basetype = anyelement, sfunc = tf1p, stype = anyarray, initcond = '{}')" +== 106 +-- truncate_limit: 100 +-- P P P P +-- should CREATE +CREATE AGGREGATE myaggp20a(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp20a (basetype = anyelement, sfunc = tfp, stype = anyarray, finalfunc = ffp..." +== 107 +-- truncate_limit: 100 +CREATE AGGREGATE myaggp20b(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggp20b (basetype = anyelement, sfunc = tfp, stype = anyarray, initcond = '{}')" +== 108 +-- truncate_limit: 100 +-- Case3 (R = N) && (B = A) +-- ------------------------ +-- S tf1 +-- ------- +-- N N +-- should CREATE +CREATE AGGREGATE myaggn01a(*) (SFUNC = stfnp, STYPE = int4[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn01a (*) (sfunc = stfnp, stype = int4[], finalfunc = ffnp, initcond = '{}')" +== 109 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn01b (*) (sfunc = stfnp, stype = int4[], initcond = '{}')" +== 110 +-- truncate_limit: 100 +-- P N +-- should ERROR: stfnp(anyarray) not matched by stfnp(int[]) +CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn02a (*) (sfunc = stfnp, stype = anyarray, finalfunc = ffnp, initcond = '{}')" +== 111 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn02b (*) (sfunc = stfnp, stype = anyarray, initcond = '{}')" +== 112 +-- truncate_limit: 100 +-- N P +-- should CREATE +CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn03a (*) (sfunc = stfp, stype = int4[], finalfunc = ffnp, initcond = '{}')" +== 113 +-- truncate_limit: 100 +-- P P +-- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) +CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn04a (*) (sfunc = stfp, stype = anyarray, finalfunc = ffnp, initcond = '{}')" +== 114 +-- truncate_limit: 100 +-- Case4 (R = N) && ((B = P) || (B = N)) +-- ------------------------------------- +-- S tf1 B tf2 +-- ----------------------- +-- N N N N +-- should CREATE +CREATE AGGREGATE myaggn05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn05a (basetype = int, sfunc = tfnp, stype = int[], finalfunc = ffnp, initco..." +== 115 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn05b(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn05b (basetype = int, sfunc = tfnp, stype = int[], initcond = '{}')" +== 116 +-- truncate_limit: 100 +-- N N N P +-- should CREATE +CREATE AGGREGATE myaggn06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn06a (basetype = int, sfunc = tf2p, stype = int[], finalfunc = ffnp, initco..." +== 117 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn06b(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn06b (basetype = int, sfunc = tf2p, stype = int[], initcond = '{}')" +== 118 +-- truncate_limit: 100 +-- N N P N +-- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int) +CREATE AGGREGATE myaggn07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn07a (basetype = anyelement, sfunc = tfnp, stype = int[], finalfunc = ffnp,..." +== 119 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn07b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn07b (basetype = anyelement, sfunc = tfnp, stype = int[], initcond = '{}')" +== 120 +-- truncate_limit: 100 +-- N N P P +-- should CREATE +CREATE AGGREGATE myaggn08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn08a (basetype = anyelement, sfunc = tf2p, stype = int[], finalfunc = ffnp,..." +== 121 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn08b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn08b (basetype = anyelement, sfunc = tf2p, stype = int[], initcond = '{}')" +== 122 +-- truncate_limit: 100 +-- N P N N +-- should CREATE +CREATE AGGREGATE myaggn09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn09a (basetype = int, sfunc = tf1p, stype = int[], finalfunc = ffnp, initco..." +== 123 +-- truncate_limit: 100 +-- N P N P +-- should CREATE +CREATE AGGREGATE myaggn10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn10a (basetype = int, sfunc = tfp, stype = int[], finalfunc = ffnp, initcon..." +== 124 +-- truncate_limit: 100 +-- N P P N +-- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int) +CREATE AGGREGATE myaggn11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn11a (basetype = anyelement, sfunc = tf1p, stype = int[], finalfunc = ffnp,..." +== 125 +-- truncate_limit: 100 +-- N P P P +-- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement) +CREATE AGGREGATE myaggn12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn12a (basetype = anyelement, sfunc = tfp, stype = int[], finalfunc = ffnp, ..." +== 126 +-- truncate_limit: 100 +-- P N N N +-- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn13a (basetype = int, sfunc = tfnp, stype = anyarray, finalfunc = ffnp, ini..." +== 127 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn13b (basetype = int, sfunc = tfnp, stype = anyarray, initcond = '{}')" +== 128 +-- truncate_limit: 100 +-- P N N P +-- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn14a (basetype = int, sfunc = tf2p, stype = anyarray, finalfunc = ffnp, ini..." +== 129 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn14b (basetype = int, sfunc = tf2p, stype = anyarray, initcond = '{}')" +== 130 +-- truncate_limit: 100 +-- P N P N +-- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) +CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn15a (basetype = anyelement, sfunc = tfnp, stype = anyarray, finalfunc = ff..." +== 131 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn15b(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn15b (basetype = anyelement, sfunc = tfnp, stype = anyarray, initcond = '{}')" +== 132 +-- truncate_limit: 100 +-- P N P P +-- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement) +CREATE AGGREGATE myaggn16a(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn16a (basetype = anyelement, sfunc = tf2p, stype = anyarray, finalfunc = ff..." +== 133 +-- truncate_limit: 100 +CREATE AGGREGATE myaggn16b(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn16b (basetype = anyelement, sfunc = tf2p, stype = anyarray, initcond = '{}')" +== 134 +-- truncate_limit: 100 +-- P P N N +-- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) +CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn17a (basetype = int, sfunc = tf1p, stype = anyarray, finalfunc = ffnp, ini..." +== 135 +-- truncate_limit: 100 +-- P P N P +-- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) +CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn18a (basetype = int, sfunc = tfp, stype = anyarray, finalfunc = ffnp, init..." +== 136 +-- truncate_limit: 100 +-- P P P N +-- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) +CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn19a (basetype = anyelement, sfunc = tf1p, stype = anyarray, finalfunc = ff..." +== 137 +-- truncate_limit: 100 +-- P P P P +-- should ERROR: ffnp(anyarray) not matched by ffnp(int[]) +CREATE AGGREGATE myaggn20a(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE myaggn20a (basetype = anyelement, sfunc = tfp, stype = anyarray, finalfunc = ffn..." +== 138 +-- truncate_limit: 100 +-- multi-arg polymorphic +CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3, + STYPE = anyelement, INITCOND = '0') +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE mysum2 (anyelement, anyelement) (sfunc = sum3, stype = anyelement, initcond = '0')" +== 139 +-- truncate_limit: 100 +-- create test data for polymorphic aggregates +create temp table t(f1 int, f2 int[], f3 text) +-- +TABLE: name="t" schema="" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t (f1 int, f2 int[], f3 text)" +== 140 +-- truncate_limit: 100 +insert into t values(1,array[1],'a') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1, ARRAY[1], 'a')" +== 141 +-- truncate_limit: 100 +insert into t values(1,array[11],'b') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1, ARRAY[11], 'b')" +== 142 +-- truncate_limit: 100 +insert into t values(1,array[111],'c') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (1, ARRAY[111], 'c')" +== 143 +-- truncate_limit: 100 +insert into t values(2,array[2],'a') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (2, ARRAY[2], 'a')" +== 144 +-- truncate_limit: 100 +insert into t values(2,array[22],'b') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (2, ARRAY[22], 'b')" +== 145 +-- truncate_limit: 100 +insert into t values(2,array[222],'c') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (2, ARRAY[222], 'c')" +== 146 +-- truncate_limit: 100 +insert into t values(3,array[3],'a') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (3, ARRAY[3], 'a')" +== 147 +-- truncate_limit: 100 +insert into t values(3,array[3],'b') +-- +TABLE: name="t" schema="" table="t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t VALUES (3, ARRAY[3], 'b')" +== 148 +-- truncate_limit: 100 +-- test the successfully created polymorphic aggregates +select f3, myaggp01a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp01a" function="myaggp01a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp01a(*) FROM t GROUP BY f3 ORDER BY f3" +== 149 +-- truncate_limit: 100 +select f3, myaggp03a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp03a" function="myaggp03a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp03a(*) FROM t GROUP BY f3 ORDER BY f3" +== 150 +-- truncate_limit: 100 +select f3, myaggp03b(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp03b" function="myaggp03b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp03b(*) FROM t GROUP BY f3 ORDER BY f3" +== 151 +-- truncate_limit: 100 +select f3, myaggp05a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp05a" function="myaggp05a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp05a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 152 +-- truncate_limit: 100 +select f3, myaggp06a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp06a" function="myaggp06a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp06a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 153 +-- truncate_limit: 100 +select f3, myaggp08a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp08a" function="myaggp08a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp08a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 154 +-- truncate_limit: 100 +select f3, myaggp09a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp09a" function="myaggp09a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp09a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 155 +-- truncate_limit: 100 +select f3, myaggp09b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp09b" function="myaggp09b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp09b(f1) FROM t GROUP BY f3 ORDER BY f3" +== 156 +-- truncate_limit: 100 +select f3, myaggp10a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp10a" function="myaggp10a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp10a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 157 +-- truncate_limit: 100 +select f3, myaggp10b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp10b" function="myaggp10b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp10b(f1) FROM t GROUP BY f3 ORDER BY f3" +== 158 +-- truncate_limit: 100 +select f3, myaggp20a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp20a" function="myaggp20a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp20a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 159 +-- truncate_limit: 100 +select f3, myaggp20b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggp20b" function="myaggp20b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggp20b(f1) FROM t GROUP BY f3 ORDER BY f3" +== 160 +-- truncate_limit: 100 +select f3, myaggn01a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn01a" function="myaggn01a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn01a(*) FROM t GROUP BY f3 ORDER BY f3" +== 161 +-- truncate_limit: 100 +select f3, myaggn01b(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn01b" function="myaggn01b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn01b(*) FROM t GROUP BY f3 ORDER BY f3" +== 162 +-- truncate_limit: 100 +select f3, myaggn03a(*) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn03a" function="myaggn03a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn03a(*) FROM t GROUP BY f3 ORDER BY f3" +== 163 +-- truncate_limit: 100 +select f3, myaggn05a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn05a" function="myaggn05a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn05a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 164 +-- truncate_limit: 100 +select f3, myaggn05b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn05b" function="myaggn05b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn05b(f1) FROM t GROUP BY f3 ORDER BY f3" +== 165 +-- truncate_limit: 100 +select f3, myaggn06a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn06a" function="myaggn06a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn06a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 166 +-- truncate_limit: 100 +select f3, myaggn06b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn06b" function="myaggn06b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn06b(f1) FROM t GROUP BY f3 ORDER BY f3" +== 167 +-- truncate_limit: 100 +select f3, myaggn08a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn08a" function="myaggn08a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn08a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 168 +-- truncate_limit: 100 +select f3, myaggn08b(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn08b" function="myaggn08b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn08b(f1) FROM t GROUP BY f3 ORDER BY f3" +== 169 +-- truncate_limit: 100 +select f3, myaggn09a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn09a" function="myaggn09a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn09a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 170 +-- truncate_limit: 100 +select f3, myaggn10a(f1) from t group by f3 order by f3 +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="myaggn10a" function="myaggn10a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f3, myaggn10a(f1) FROM t GROUP BY f3 ORDER BY f3" +== 171 +-- truncate_limit: 100 +select mysum2(f1, f1 + 1) from t +-- +TABLE: name="t" schema="" table="t" ctx=Select +FUNCTION: name="mysum2" function="mysum2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT mysum2(f1, f1 + 1) FROM t" +== 172 +-- truncate_limit: 100 +-- test inlining of polymorphic SQL functions +create function bleat(int) returns int as $$ +begin + raise notice 'bleat %', $1; + return $1; +end$$ language plpgsql +-- +FUNCTION: name="bleat" function="bleat" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bleat(int) RETURNS int AS $$\nbegin\n raise notice 'bleat %', $1;\n return $1;\nend..." +== 173 +-- truncate_limit: 100 +create function sql_if(bool, anyelement, anyelement) returns anyelement as $$ +select case when $1 then $2 else $3 end $$ language sql +-- +FUNCTION: name="sql_if" function="sql_if" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sql_if(bool, anyelement, anyelement) RETURNS anyelement AS $$\nselect case when $1..." +== 174 +-- truncate_limit: 100 +-- Note this would fail with integer overflow, never mind wrong bleat() output, +-- if the CASE expression were not successfully inlined +select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="sql_if" function="sql_if" schema="" ctx=Call +FUNCTION: name="bleat" function="bleat" schema="" ctx=Call +FUNCTION: name="bleat" function="bleat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) FROM int4_tbl" +== 175 +-- truncate_limit: 100 +select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="sql_if" function="sql_if" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q2, sql_if(q2 > 0, q2, q2 + 1) FROM int8_tbl" +== 176 +-- truncate_limit: 100 +-- another sort of polymorphic aggregate + +CREATE AGGREGATE array_larger_accum (anyarray) +( + sfunc = array_larger, + stype = anyarray, + initcond = '{}' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE array_larger_accum (anyarray) (sfunc = array_larger, stype = anyarray, initcond ..." +== 177 +-- truncate_limit: 100 +SELECT array_larger_accum(i) +FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) as t(i) +-- +FUNCTION: name="array_larger_accum" function="array_larger_accum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_larger_accum(i) FROM (VALUES (ARRAY[1, 2]), (ARRAY[3, 4])) t(i)" +== 178 +-- truncate_limit: 100 +SELECT array_larger_accum(i) +FROM (VALUES (ARRAY[row(1,2),row(3,4)]), (ARRAY[row(5,6),row(7,8)])) as t(i) +-- +FUNCTION: name="array_larger_accum" function="array_larger_accum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_larger_accum(i) FROM (VALUES (...)) t(i)" +== 179 +-- truncate_limit: 100 +-- another kind of polymorphic aggregate + +create function add_group(grp anyarray, ad anyelement, size integer) + returns anyarray + as $$ +begin + if grp is null then + return array[ad]; + end if; + if array_upper(grp, 1) < size then + return grp || ad; + end if; + return grp; +end; +$$ + language plpgsql immutable +-- +FUNCTION: name="add_group" function="add_group" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION add_group(grp anyarray, ad anyelement, size int) RETURNS anyarray AS $$\nbegin\n i..." +== 180 +-- truncate_limit: 100 +create aggregate build_group(anyelement, integer) ( + SFUNC = add_group, + STYPE = anyarray +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE build_group (anyelement, int) (sfunc = add_group, stype = anyarray)" +== 181 +-- truncate_limit: 100 +select build_group(q1,3) from int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="build_group" function="build_group" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT build_group(q1, 3) FROM int8_tbl" +== 182 +-- truncate_limit: 100 +-- this should fail because stype isn't compatible with arg +create aggregate build_group(int8, integer) ( + SFUNC = add_group, + STYPE = int2[] +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE build_group (int8, int) (sfunc = add_group, stype = int2[])" +== 183 +-- truncate_limit: 100 +-- but we can make a non-poly agg from a poly sfunc if types are OK +create aggregate build_group(int8, integer) ( + SFUNC = add_group, + STYPE = int8[] +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE build_group (int8, int) (sfunc = add_group, stype = int8[])" +== 184 +-- truncate_limit: 100 +-- check proper resolution of data types for polymorphic transfn/finalfn + +create function first_el_transfn(anyarray, anyelement) returns anyarray as +'select $1 || $2' language sql immutable +-- +FUNCTION: name="first_el_transfn" function="first_el_transfn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION first_el_transfn(anyarray, anyelement) RETURNS anyarray AS $$select $1 || $2$$ LA..." +== 185 +-- truncate_limit: 100 +create function first_el(anyarray) returns anyelement as +'select $1[1]' language sql strict immutable +-- +FUNCTION: name="first_el" function="first_el" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION first_el(anyarray) RETURNS anyelement AS $$select $1[1]$$ LANGUAGE sql RETURNS NU..." +== 186 +-- truncate_limit: 100 +create aggregate first_el_agg_f8(float8) ( + SFUNC = array_append, + STYPE = float8[], + FINALFUNC = first_el +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE first_el_agg_f8 (float8) (sfunc = array_append, stype = float8[], finalfunc = fi..." +== 187 +-- truncate_limit: 100 +create aggregate first_el_agg_any(anyelement) ( + SFUNC = first_el_transfn, + STYPE = anyarray, + FINALFUNC = first_el +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE first_el_agg_any (anyelement) (sfunc = first_el_transfn, stype = anyarray, final..." +== 188 +-- truncate_limit: 100 +select first_el_agg_f8(x::float8) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_f8" function="first_el_agg_f8" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT first_el_agg_f8(x::float8) FROM generate_series(1, 10) x" +== 189 +-- truncate_limit: 100 +select first_el_agg_any(x) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_any" function="first_el_agg_any" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT first_el_agg_any(x) FROM generate_series(1, 10) x" +== 190 +-- truncate_limit: 100 +select first_el_agg_f8(x::float8) over(order by x) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_f8" function="first_el_agg_f8" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT first_el_agg_f8(x::float8) OVER (ORDER BY x) FROM generate_series(1, 10) x" +== 191 +-- truncate_limit: 100 +select first_el_agg_any(x) over(order by x) from generate_series(1,10) x +-- +FUNCTION: name="first_el_agg_any" function="first_el_agg_any" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT first_el_agg_any(x) OVER (ORDER BY x) FROM generate_series(1, 10) x" +== 192 +-- truncate_limit: 100 +-- check that we can apply functions taking ANYARRAY to pg_stats +select distinct array_ndims(histogram_bounds) from pg_stats +where histogram_bounds is not null +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="array_ndims" function="array_ndims" schema="" ctx=Call +FILTER: schema="" table="" column="histogram_bounds" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT array_ndims(histogram_bounds) FROM pg_stats WHERE histogram_bounds IS NOT NULL" +== 193 +-- truncate_limit: 100 +-- such functions must protect themselves if varying element type isn't OK +-- (WHERE clause here is to avoid possibly getting a collation error instead) +select max(histogram_bounds) from pg_stats where tablename = 'pg_am' +-- +TABLE: name="pg_stats" schema="" table="pg_stats" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT max(histogram_bounds) FROM pg_stats WHERE tablename = 'pg_am'" +== 194 +-- truncate_limit: 100 +-- another corner case is the input functions for polymorphic pseudotypes +select array_in('{1,2,3}','int4'::regtype,-1) +-- +FUNCTION: name="array_in" function="array_in" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_in('{1,2,3}', 'int4'::regtype, -1)" +== 195 +-- truncate_limit: 100 +-- this has historically worked +select * from array_in('{1,2,3}','int4'::regtype,-1) +-- +FUNCTION: name="array_in" function="array_in" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_in('{1,2,3}', 'int4'::regtype, -1)" +== 196 +-- truncate_limit: 100 +-- this not +select anyrange_in('[10,20)','int4range'::regtype,-1) +-- +FUNCTION: name="anyrange_in" function="anyrange_in" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anyrange_in('[10,20)', 'int4range'::regtype, -1)" +== 197 +-- truncate_limit: 100 +-- test variadic polymorphic functions + +create function myleast(variadic anyarray) returns anyelement as $$ + select min($1[i]) from generate_subscripts($1,1) g(i) +$$ language sql immutable strict +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION myleast(VARIADIC anyarray) RETURNS anyelement AS $$\n select min($1[i]) from gene..." +== 198 +-- truncate_limit: 100 +select myleast(10, 1, 20, 33) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myleast(10, 1, 20, 33)" +== 199 +-- truncate_limit: 100 +select myleast(1.1, 0.22, 0.55) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myleast(1.1, 0.22, 0.55)" +== 200 +-- truncate_limit: 100 +select myleast('z'::text) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myleast('z'::text)" +== 201 +-- truncate_limit: 100 +select myleast() +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myleast()" +== 202 +-- truncate_limit: 100 +-- fail + +-- test with variadic call parameter +select myleast(variadic array[1,2,3,4,-1]) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myleast(VARIADIC ARRAY[1, 2, 3, 4, -1])" +== 203 +-- truncate_limit: 100 +select myleast(variadic array[1.1, -5.5]) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myleast(VARIADIC ARRAY[1.1, -5.5])" +== 204 +-- truncate_limit: 100 +--test with empty variadic call parameter +select myleast(variadic array[]::int[]) +-- +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT myleast(VARIADIC ARRAY[]::int[])" +== 205 +-- truncate_limit: 100 +-- an example with some ordinary arguments too +create function concat(text, variadic anyarray) returns text as $$ + select array_to_string($2, $1); +$$ language sql immutable strict +-- +FUNCTION: name="concat" function="concat" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION concat(text, VARIADIC anyarray) RETURNS text AS $$\n select array_to_string($2, $..." +== 206 +-- truncate_limit: 100 +select concat('%', 1, 2, 3, 4, 5) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat('%', 1, 2, 3, 4, 5)" +== 207 +-- truncate_limit: 100 +select concat('|', 'a'::text, 'b', 'c') +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat('|', 'a'::text, 'b', 'c')" +== 208 +-- truncate_limit: 100 +select concat('|', variadic array[1,2,33]) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat('|', VARIADIC ARRAY[1, 2, 33])" +== 209 +-- truncate_limit: 100 +select concat('|', variadic array[]::int[]) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat('|', VARIADIC ARRAY[]::int[])" +== 210 +-- truncate_limit: 100 +drop function concat(text, anyarray) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION concat(text, anyarray)" +== 211 +-- truncate_limit: 100 +-- mix variadic with anyelement +create function formarray(anyelement, variadic anyarray) returns anyarray as $$ + select array_prepend($1, $2); +$$ language sql immutable strict +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION formarray(anyelement, VARIADIC anyarray) RETURNS anyarray AS $$\n select array_pr..." +== 212 +-- truncate_limit: 100 +select formarray(1,2,3,4,5) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT formarray(1, 2, 3, 4, 5)" +== 213 +-- truncate_limit: 100 +select formarray(1.1, variadic array[1.2,55.5]) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT formarray(1.1, VARIADIC ARRAY[1.2, 55.5])" +== 214 +-- truncate_limit: 100 +select formarray(1.1, array[1.2,55.5]) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT formarray(1.1, ARRAY[1.2, 55.5])" +== 215 +-- truncate_limit: 100 +-- fail without variadic +select formarray(1, 'x'::text) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT formarray(1, 'x'::text)" +== 216 +-- truncate_limit: 100 +-- fail, type mismatch +select formarray(1, variadic array['x'::text]) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT formarray(1, VARIADIC ARRAY['x'::text])" +== 217 +-- truncate_limit: 100 +-- fail, type mismatch + +drop function formarray(anyelement, variadic anyarray) +-- +FUNCTION: name="formarray" function="formarray" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION formarray(anyelement, VARIADIC anyarray)" +== 218 +-- truncate_limit: 100 +-- test pg_typeof() function +select pg_typeof(null) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(NULL)" +== 219 +-- truncate_limit: 100 +-- unknown +select pg_typeof(0) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(0)" +== 220 +-- truncate_limit: 100 +-- integer +select pg_typeof(0.0) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(0.0)" +== 221 +-- truncate_limit: 100 +-- numeric +select pg_typeof(1+1 = 2) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof((1 + 1) = 2)" +== 222 +-- truncate_limit: 100 +-- boolean +select pg_typeof('x') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof('x')" +== 223 +-- truncate_limit: 100 +-- unknown +select pg_typeof('' || '') +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof('' || '')" +== 224 +-- truncate_limit: 100 +-- text +select pg_typeof(pg_typeof(0)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(pg_typeof(0))" +== 225 +-- truncate_limit: 100 +-- regtype +select pg_typeof(array[1.2,55.5]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(ARRAY[1.2, 55.5])" +== 226 +-- truncate_limit: 100 +-- numeric[] +select pg_typeof(myleast(10, 1, 20, 33)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="myleast" function="myleast" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(myleast(10, 1, 20, 33))" +== 227 +-- truncate_limit: 100 +-- polymorphic input + +-- test functions with default parameters + +-- test basic functionality +create function dfunc(a int = 1, int = 2) returns int as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a int = 1, int = 2) RETURNS int AS $$\n select $1 + $2;\n$$ LANGUAGE sql" +== 228 +-- truncate_limit: 100 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 229 +-- truncate_limit: 100 +select dfunc(10) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10)" +== 230 +-- truncate_limit: 100 +select dfunc(10, 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10, 20)" +== 231 +-- truncate_limit: 100 +select dfunc(10, 20, 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10, 20, 30)" +== 232 +-- truncate_limit: 100 +-- fail + +drop function dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc()" +== 233 +-- truncate_limit: 100 +-- fail +drop function dfunc(int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int)" +== 234 +-- truncate_limit: 100 +-- fail +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int)" +== 235 +-- truncate_limit: 100 +-- ok + +-- fail: defaults must be at end of argument list +create function dfunc(a int = 1, b int) returns int as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a int = 1, b int) RETURNS int AS $$\n select $1 + $2;\n$$ LANGUAGE sql" +== 236 +-- truncate_limit: 100 +-- however, this should work: +create function dfunc(a int = 1, out sum int, b int = 2) as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a int = 1, OUT sum int, b int = 2) AS $$\n select $1 + $2;\n$$ LANGUAGE sql" +== 237 +-- truncate_limit: 100 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 238 +-- truncate_limit: 100 +-- verify it lists properly + +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int)" +== 239 +-- truncate_limit: 100 +-- check implicit coercion +create function dfunc(a int DEFAULT 1.0, int DEFAULT '-1') returns int as $$ + select $1 + $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a int = 1.0, int = '-1') RETURNS int AS $$\n select $1 + $2;\n$$ LANGUAGE sql" +== 240 +-- truncate_limit: 100 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 241 +-- truncate_limit: 100 +create function dfunc(a text DEFAULT 'Hello', b text DEFAULT 'World') returns text as $$ + select $1 || ', ' || $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a text = 'Hello', b text = 'World') RETURNS text AS $$\n select $1 || ', ' ..." +== 242 +-- truncate_limit: 100 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 243 +-- truncate_limit: 100 +-- fail: which dfunc should be called? int or text +select dfunc('Hi') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('Hi')" +== 244 +-- truncate_limit: 100 +-- ok +select dfunc('Hi', 'City') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('Hi', 'City')" +== 245 +-- truncate_limit: 100 +-- ok +select dfunc(0) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(0)" +== 246 +-- truncate_limit: 100 +-- ok +select dfunc(10, 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10, 20)" +== 247 +-- truncate_limit: 100 +-- ok + +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int)" +== 248 +-- truncate_limit: 100 +drop function dfunc(text, text) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(text, text)" +== 249 +-- truncate_limit: 100 +create function dfunc(int = 1, int = 2) returns int as $$ + select 2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(int = 1, int = 2) RETURNS int AS $$\n select 2;\n$$ LANGUAGE sql" +== 250 +-- truncate_limit: 100 +create function dfunc(int = 1, int = 2, int = 3, int = 4) returns int as $$ + select 4; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(int = 1, int = 2, int = 3, int = 4) RETURNS int AS $$\n select 4;\n$$ LANGUA..." +== 251 +-- truncate_limit: 100 +-- Now, dfunc(nargs = 2) and dfunc(nargs = 4) are ambiguous when called +-- with 0 to 2 arguments. + +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 252 +-- truncate_limit: 100 +-- fail +select dfunc(1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(1)" +== 253 +-- truncate_limit: 100 +-- fail +select dfunc(1, 2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(1, 2)" +== 254 +-- truncate_limit: 100 +-- fail +select dfunc(1, 2, 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(1, 2, 3)" +== 255 +-- truncate_limit: 100 +-- ok +select dfunc(1, 2, 3, 4) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(1, 2, 3, 4)" +== 256 +-- truncate_limit: 100 +-- ok + +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int)" +== 257 +-- truncate_limit: 100 +drop function dfunc(int, int, int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int, int, int)" +== 258 +-- truncate_limit: 100 +-- default values are not allowed for output parameters +create function dfunc(out int = 20) returns int as $$ + select 1; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(OUT int = 20) RETURNS int AS $$\n select 1;\n$$ LANGUAGE sql" +== 259 +-- truncate_limit: 100 +-- polymorphic parameter test +create function dfunc(anyelement = 'World'::text) returns text as $$ + select 'Hello, ' || $1::text; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(anyelement = 'World'::text) RETURNS text AS $$\n select 'Hello, ' || $1::te..." +== 260 +-- truncate_limit: 100 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 261 +-- truncate_limit: 100 +select dfunc(0) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(0)" +== 262 +-- truncate_limit: 100 +select dfunc(to_date('20081215','YYYYMMDD')) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(to_date('20081215', 'YYYYMMDD'))" +== 263 +-- truncate_limit: 100 +select dfunc('City'::text) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('City'::text)" +== 264 +-- truncate_limit: 100 +drop function dfunc(anyelement) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(anyelement)" +== 265 +-- truncate_limit: 100 +-- check defaults for variadics + +create function dfunc(a variadic int[]) returns int as +$$ select array_upper($1, 1) $$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(VARIADIC a int[]) RETURNS int AS $$ select array_upper($1, 1) $$ LANGUAGE sql" +== 266 +-- truncate_limit: 100 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 267 +-- truncate_limit: 100 +-- fail +select dfunc(10) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10)" +== 268 +-- truncate_limit: 100 +select dfunc(10,20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10, 20)" +== 269 +-- truncate_limit: 100 +create or replace function dfunc(a variadic int[] default array[]::int[]) returns int as +$$ select array_upper($1, 1) $$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dfunc(VARIADIC a int[] = ARRAY[]::int[]) RETURNS int AS $$ select arra..." +== 270 +-- truncate_limit: 100 +select dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc()" +== 271 +-- truncate_limit: 100 +-- now ok +select dfunc(10) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10)" +== 272 +-- truncate_limit: 100 +select dfunc(10,20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(10, 20)" +== 273 +-- truncate_limit: 100 +-- can't remove the default once it exists +create or replace function dfunc(a variadic int[]) returns int as +$$ select array_upper($1, 1) $$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dfunc(VARIADIC a int[]) RETURNS int AS $$ select array_upper($1, 1) $$..." +== 274 +-- truncate_limit: 100 +drop function dfunc(a variadic int[]) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(VARIADIC a int[])" +== 275 +-- truncate_limit: 100 +-- Ambiguity should be reported only if there's not a better match available + +create function dfunc(int = 1, int = 2, int = 3) returns int as $$ + select 3; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(int = 1, int = 2, int = 3) RETURNS int AS $$\n select 3;\n$$ LANGUAGE sql" +== 276 +-- truncate_limit: 100 +create function dfunc(int = 1, int = 2) returns int as $$ + select 2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(int = 1, int = 2) RETURNS int AS $$\n select 2;\n$$ LANGUAGE sql" +== 277 +-- truncate_limit: 100 +create function dfunc(text) returns text as $$ + select $1; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(text) RETURNS text AS $$\n select $1;\n$$ LANGUAGE sql" +== 278 +-- truncate_limit: 100 +-- dfunc(narg=2) and dfunc(narg=3) are ambiguous +select dfunc(1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(1)" +== 279 +-- truncate_limit: 100 +-- fail + +-- but this works since the ambiguous functions aren't preferred anyway +select dfunc('Hi') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('Hi')" +== 280 +-- truncate_limit: 100 +drop function dfunc(int, int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int, int)" +== 281 +-- truncate_limit: 100 +drop function dfunc(int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int)" +== 282 +-- truncate_limit: 100 +drop function dfunc(text) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(text)" +== 283 +-- truncate_limit: 100 +|-- +-- Tests for named- and mixed-notation function calling +|-- + +create function dfunc(a int, b int, c int = 0, d int = 0) + returns table (a int, b int, c int, d int) as $$ + select $1, $2, $3, $4; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a int, b int, c int = 0, d int = 0) RETURNS TABLE (a int, b int, c int, d i..." +== 284 +-- truncate_limit: 100 +select (dfunc(10,20,30)).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (dfunc(10, 20, 30)).*" +== 285 +-- truncate_limit: 100 +select (dfunc(a := 10, b := 20, c := 30)).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (dfunc(a := 10, b := 20, c := 30)).*" +== 286 +-- truncate_limit: 100 +select * from dfunc(a := 10, b := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(a := 10, b := 20)" +== 287 +-- truncate_limit: 100 +select * from dfunc(b := 10, a := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(b := 10, a := 20)" +== 288 +-- truncate_limit: 100 +select * from dfunc(0) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(0)" +== 289 +-- truncate_limit: 100 +-- fail +select * from dfunc(1,2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(1, 2)" +== 290 +-- truncate_limit: 100 +select * from dfunc(1,2,c := 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(1, 2, c := 3)" +== 291 +-- truncate_limit: 100 +select * from dfunc(1,2,d := 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(1, 2, d := 3)" +== 292 +-- truncate_limit: 100 +select * from dfunc(x := 20, b := 10, x := 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(x := 20, b := 10, x := 30)" +== 293 +-- truncate_limit: 100 +-- fail, duplicate name +select * from dfunc(10, b := 20, 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(10, b := 20, 30)" +== 294 +-- truncate_limit: 100 +-- fail, named args must be last +select * from dfunc(x := 10, b := 20, c := 30) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(x := 10, b := 20, c := 30)" +== 295 +-- truncate_limit: 100 +-- fail, unknown param +select * from dfunc(10, 10, a := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(10, 10, a := 20)" +== 296 +-- truncate_limit: 100 +-- fail, a overlaps positional parameter +select * from dfunc(1,c := 2,d := 3) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(1, c := 2, d := 3)" +== 297 +-- truncate_limit: 100 +-- fail, no value for b + +drop function dfunc(int, int, int, int) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(int, int, int, int)" +== 298 +-- truncate_limit: 100 +-- test with different parameter types +create function dfunc(a varchar, b numeric, c date = current_date) + returns table (a varchar, b numeric, c date) as $$ + select $1, $2, $3; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a varchar, b numeric, c date = current_date) RETURNS TABLE (a varchar, b nu..." +== 299 +-- truncate_limit: 100 +select (dfunc('Hello World', 20, '2009-07-25'::date)).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (dfunc('Hello World', 20, '2009-07-25'::date)).*" +== 300 +-- truncate_limit: 100 +select * from dfunc('Hello World', 20, '2009-07-25'::date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc('Hello World', 20, '2009-07-25'::date)" +== 301 +-- truncate_limit: 100 +select * from dfunc(c := '2009-07-25'::date, a := 'Hello World', b := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(c := '2009-07-25'::date, a := 'Hello World', b := 20)" +== 302 +-- truncate_limit: 100 +select * from dfunc('Hello World', b := 20, c := '2009-07-25'::date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc('Hello World', b := 20, c := '2009-07-25'::date)" +== 303 +-- truncate_limit: 100 +select * from dfunc('Hello World', c := '2009-07-25'::date, b := 20) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc('Hello World', c := '2009-07-25'::date, b := 20)" +== 304 +-- truncate_limit: 100 +select * from dfunc('Hello World', c := 20, b := '2009-07-25'::date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc('Hello World', c := 20, b := '2009-07-25'::date)" +== 305 +-- truncate_limit: 100 +-- fail + +drop function dfunc(varchar, numeric, date) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(varchar, numeric, date)" +== 306 +-- truncate_limit: 100 +-- test out parameters with named params +create function dfunc(a varchar = 'def a', out _a varchar, c numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a varchar = 'def a', OUT _a varchar, c numeric = NULL, OUT _c numeric) RETU..." +== 307 +-- truncate_limit: 100 +select (dfunc()).* +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (dfunc()).*" +== 308 +-- truncate_limit: 100 +select * from dfunc() +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc()" +== 309 +-- truncate_limit: 100 +select * from dfunc('Hello', 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc('Hello', 100)" +== 310 +-- truncate_limit: 100 +select * from dfunc(a := 'Hello', c := 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(a := 'Hello', c := 100)" +== 311 +-- truncate_limit: 100 +select * from dfunc(c := 100, a := 'Hello') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(c := 100, a := 'Hello')" +== 312 +-- truncate_limit: 100 +select * from dfunc('Hello') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc('Hello')" +== 313 +-- truncate_limit: 100 +select * from dfunc('Hello', c := 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc('Hello', c := 100)" +== 314 +-- truncate_limit: 100 +select * from dfunc(c := 100) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfunc(c := 100)" +== 315 +-- truncate_limit: 100 +-- fail, can no longer change an input parameter's name +create or replace function dfunc(a varchar = 'def a', out _a varchar, x numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dfunc(a varchar = 'def a', OUT _a varchar, x numeric = NULL, OUT _c nu..." +== 316 +-- truncate_limit: 100 +create or replace function dfunc(a varchar = 'def a', out _a varchar, numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dfunc(a varchar = 'def a', OUT _a varchar, numeric = NULL, OUT _c nume..." +== 317 +-- truncate_limit: 100 +drop function dfunc(varchar, numeric) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(varchar, numeric)" +== 318 +-- truncate_limit: 100 +--fail, named parameters are not unique +create function testpolym(a int, a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpolym(a int, a int) RETURNS int AS $$ select 1;$$ LANGUAGE sql" +== 319 +-- truncate_limit: 100 +create function testpolym(int, out a int, out a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpolym(int, OUT a int, OUT a int) RETURNS int AS $$ select 1;$$ LANGUAGE sql" +== 320 +-- truncate_limit: 100 +create function testpolym(out a int, inout a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpolym(OUT a int, INOUT a int) RETURNS int AS $$ select 1;$$ LANGUAGE sql" +== 321 +-- truncate_limit: 100 +create function testpolym(a int, inout a int) returns int as $$ select 1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpolym(a int, INOUT a int) RETURNS int AS $$ select 1;$$ LANGUAGE sql" +== 322 +-- truncate_limit: 100 +-- valid +create function testpolym(a int, out a int) returns int as $$ select $1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpolym(a int, OUT a int) RETURNS int AS $$ select $1;$$ LANGUAGE sql" +== 323 +-- truncate_limit: 100 +select testpolym(37) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testpolym(37)" +== 324 +-- truncate_limit: 100 +drop function testpolym(int) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testpolym(int)" +== 325 +-- truncate_limit: 100 +create function testpolym(a int) returns table(a int) as $$ select $1;$$ language sql +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpolym(a int) RETURNS TABLE (a int) AS $$ select $1;$$ LANGUAGE sql" +== 326 +-- truncate_limit: 100 +select * from testpolym(37) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testpolym(37)" +== 327 +-- truncate_limit: 100 +drop function testpolym(int) +-- +FUNCTION: name="testpolym" function="testpolym" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testpolym(int)" +== 328 +-- truncate_limit: 100 +-- test polymorphic params and defaults +create function dfunc(a anyelement, b anyelement = null, flag bool = true) +returns anyelement as $$ + select case when $3 then $1 else $2 end; +$$ language sql +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dfunc(a anyelement, b anyelement = NULL, flag bool = true) RETURNS anyelement AS ..." +== 329 +-- truncate_limit: 100 +select dfunc(1,2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(1, 2)" +== 330 +-- truncate_limit: 100 +select dfunc('a'::text, 'b') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b')" +== 331 +-- truncate_limit: 100 +-- positional notation with default + +select dfunc(a := 1, b := 2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 1, b := 2)" +== 332 +-- truncate_limit: 100 +select dfunc(a := 'a'::text, b := 'b') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, b := 'b')" +== 333 +-- truncate_limit: 100 +select dfunc(a := 'a'::text, b := 'b', flag := false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, b := 'b', flag := false)" +== 334 +-- truncate_limit: 100 +-- named notation + +select dfunc(b := 'b'::text, a := 'a') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(b := 'b'::text, a := 'a')" +== 335 +-- truncate_limit: 100 +-- named notation with default +select dfunc(a := 'a'::text, flag := true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, flag := true)" +== 336 +-- truncate_limit: 100 +-- named notation with default +select dfunc(a := 'a'::text, flag := false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, flag := false)" +== 337 +-- truncate_limit: 100 +-- named notation with default +select dfunc(b := 'b'::text, a := 'a', flag := true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(b := 'b'::text, a := 'a', flag := true)" +== 338 +-- truncate_limit: 100 +-- named notation + +select dfunc('a'::text, 'b', false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', false)" +== 339 +-- truncate_limit: 100 +-- full positional notation +select dfunc('a'::text, 'b', flag := false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', flag := false)" +== 340 +-- truncate_limit: 100 +-- mixed notation +select dfunc('a'::text, 'b', true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', true)" +== 341 +-- truncate_limit: 100 +-- full positional notation +select dfunc('a'::text, 'b', flag := true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', flag := true)" +== 342 +-- truncate_limit: 100 +-- mixed notation + +-- ansi/sql syntax +select dfunc(a => 1, b => 2) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 1, b := 2)" +== 343 +-- truncate_limit: 100 +select dfunc(a => 'a'::text, b => 'b') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, b := 'b')" +== 344 +-- truncate_limit: 100 +select dfunc(a => 'a'::text, b => 'b', flag => false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, b := 'b', flag := false)" +== 345 +-- truncate_limit: 100 +-- named notation + +select dfunc(b => 'b'::text, a => 'a') +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(b := 'b'::text, a := 'a')" +== 346 +-- truncate_limit: 100 +-- named notation with default +select dfunc(a => 'a'::text, flag => true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, flag := true)" +== 347 +-- truncate_limit: 100 +-- named notation with default +select dfunc(a => 'a'::text, flag => false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 'a'::text, flag := false)" +== 348 +-- truncate_limit: 100 +-- named notation with default +select dfunc(b => 'b'::text, a => 'a', flag => true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(b := 'b'::text, a := 'a', flag := true)" +== 349 +-- truncate_limit: 100 +-- named notation + +select dfunc('a'::text, 'b', false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', false)" +== 350 +-- truncate_limit: 100 +-- full positional notation +select dfunc('a'::text, 'b', flag => false) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', flag := false)" +== 351 +-- truncate_limit: 100 +-- mixed notation +select dfunc('a'::text, 'b', true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', true)" +== 352 +-- truncate_limit: 100 +-- full positional notation +select dfunc('a'::text, 'b', flag => true) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc('a'::text, 'b', flag := true)" +== 353 +-- truncate_limit: 100 +-- mixed notation + +-- this tests lexer edge cases around => +select dfunc(a =>-1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := -1)" +== 354 +-- truncate_limit: 100 +select dfunc(a =>+1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := + 1)" +== 355 +-- truncate_limit: 100 +select dfunc(a =>/**/1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 1)" +== 356 +-- truncate_limit: 100 +select dfunc(a =>--comment to be removed by psql + 1) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dfunc(a := 1)" +== 357 +-- truncate_limit: 100 +-- need DO to protect the -- from psql +do $$ + declare r integer; + begin + select dfunc(a=>-- comment + 1) into r; + raise info 'r = %', r; + end; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\n declare r integer;\n begin\n select dfunc(a=>-- comment\n 1) into r;\n raise info..." +== 358 +-- truncate_limit: 100 +-- check reverse-listing of named-arg calls +CREATE VIEW dfview AS + SELECT q1, q2, + dfunc(q1,q2, flag := q1>q2) as c3, + dfunc(q1, flag := q1 q2) AS c3, dfunc(q1, flag := q1 <..." +== 359 +-- truncate_limit: 100 +select * from dfview +-- +TABLE: name="dfview" schema="" table="dfview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dfview" +== 360 +-- truncate_limit: 100 +drop view dfview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW dfview" +== 361 +-- truncate_limit: 100 +drop function dfunc(anyelement, anyelement, bool) +-- +FUNCTION: name="dfunc" function="dfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dfunc(anyelement, anyelement, bool)" +== 362 +-- truncate_limit: 100 +|-- +-- Tests for ANYCOMPATIBLE polymorphism family +|-- + +create function anyctest(anycompatible, anycompatible) +returns anycompatible as $$ + select greatest($1, $2) +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatible, anycompatible) RETURNS anycompatible AS $$\n select great..." +== 363 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12) x" +== 364 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12.3) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12.3) x" +== 365 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, point(1,2)) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, point(1, 2)) x" +== 366 +-- truncate_limit: 100 +-- fail +select x, pg_typeof(x) from anyctest('11', '12.3') x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest('11', '12.3') x" +== 367 +-- truncate_limit: 100 +-- defaults to text + +drop function anyctest(anycompatible, anycompatible) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatible, anycompatible)" +== 368 +-- truncate_limit: 100 +create function anyctest(anycompatible, anycompatible) +returns anycompatiblearray as $$ + select array[$1, $2] +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatible, anycompatible) RETURNS anycompatiblearray AS $$\n select ..." +== 369 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12) x" +== 370 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12.3) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12.3) x" +== 371 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, array[1,2]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, ARRAY[1, 2]) x" +== 372 +-- truncate_limit: 100 +-- fail + +drop function anyctest(anycompatible, anycompatible) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatible, anycompatible)" +== 373 +-- truncate_limit: 100 +create function anyctest(anycompatible, anycompatiblearray) +returns anycompatiblearray as $$ + select array[$1] || $2 +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatible, anycompatiblearray) RETURNS anycompatiblearray AS $$\n se..." +== 374 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, array[12]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, ARRAY[12]) x" +== 375 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, array[12.3]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, ARRAY[12.3]) x" +== 376 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(12.3, array[13]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(12.3, ARRAY[13]) x" +== 377 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(12.3, '{13,14.4}') x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(12.3, '{13,14.4}') x" +== 378 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, array[point(1,2)]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, ARRAY[point(1, 2)]) x" +== 379 +-- truncate_limit: 100 +-- fail +select x, pg_typeof(x) from anyctest(11, 12) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12) x" +== 380 +-- truncate_limit: 100 +-- fail + +drop function anyctest(anycompatible, anycompatiblearray) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatible, anycompatiblearray)" +== 381 +-- truncate_limit: 100 +create function anyctest(anycompatible, anycompatiblerange) +returns anycompatiblerange as $$ + select $2 +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatible, anycompatiblerange) RETURNS anycompatiblerange AS $$\n se..." +== 382 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, int4range(4,7)) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, int4range(4, 7)) x" +== 383 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, numrange(4,7)) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, numrange(4, 7)) x" +== 384 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12) x" +== 385 +-- truncate_limit: 100 +-- fail +select x, pg_typeof(x) from anyctest(11.2, int4range(4,7)) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11.2, int4range(4, 7)) x" +== 386 +-- truncate_limit: 100 +-- fail +select x, pg_typeof(x) from anyctest(11.2, '[4,7)') x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11.2, '[4,7)') x" +== 387 +-- truncate_limit: 100 +-- fail + +drop function anyctest(anycompatible, anycompatiblerange) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatible, anycompatiblerange)" +== 388 +-- truncate_limit: 100 +create function anyctest(anycompatiblerange, anycompatiblerange) +returns anycompatible as $$ + select lower($1) + upper($2) +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatiblerange, anycompatiblerange) RETURNS anycompatible AS $$\n se..." +== 389 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(int4range(11,12), int4range(4,7)) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(int4range(11, 12), int4range(4, 7)) x" +== 390 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(int4range(11,12), numrange(4,7)) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(int4range(11, 12), numrange(4, 7)) x" +== 391 +-- truncate_limit: 100 +-- fail + +drop function anyctest(anycompatiblerange, anycompatiblerange) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatiblerange, anycompatiblerange)" +== 392 +-- truncate_limit: 100 +-- fail, can't infer result type: +create function anyctest(anycompatible) +returns anycompatiblerange as $$ + select $1 +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatible) RETURNS anycompatiblerange AS $$\n select $1\n$$ LANGUAGE sql" +== 393 +-- truncate_limit: 100 +create function anyctest(anycompatible, anycompatiblemultirange) +returns anycompatiblemultirange as $$ + select $2 +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatible, anycompatiblemultirange) RETURNS anycompatiblemultirange ..." +== 394 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, multirange(int4range(4,7))) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, multirange(int4range(4, 7))) x" +== 395 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, multirange(numrange(4,7))) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, multirange(numrange(4, 7))) x" +== 396 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12) x" +== 397 +-- truncate_limit: 100 +-- fail +select x, pg_typeof(x) from anyctest(11.2, multirange(int4range(4,7))) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11.2, multirange(int4range(4, 7))) x" +== 398 +-- truncate_limit: 100 +-- fail +select x, pg_typeof(x) from anyctest(11.2, '{[4,7)}') x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11.2, '{[4,7)}') x" +== 399 +-- truncate_limit: 100 +-- fail + +drop function anyctest(anycompatible, anycompatiblemultirange) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatible, anycompatiblemultirange)" +== 400 +-- truncate_limit: 100 +create function anyctest(anycompatiblemultirange, anycompatiblemultirange) +returns anycompatible as $$ + select lower($1) + upper($2) +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatiblemultirange, anycompatiblemultirange) RETURNS anycompatible ..." +== 401 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(multirange(int4range(11,12)), multirange(int4range(4,7))) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(multirange(int4range(11, 12)), multirange(int4range(4, 7))) x" +== 402 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(multirange(int4range(11,12)), multirange(numrange(4,7))) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="multirange" function="multirange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(multirange(int4range(11, 12)), multirange(numrange(4, 7))) x" +== 403 +-- truncate_limit: 100 +-- fail + +drop function anyctest(anycompatiblemultirange, anycompatiblemultirange) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatiblemultirange, anycompatiblemultirange)" +== 404 +-- truncate_limit: 100 +-- fail, can't infer result type: +create function anyctest(anycompatible) +returns anycompatiblemultirange as $$ + select $1 +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatible) RETURNS anycompatiblemultirange AS $$\n select $1\n$$ LANG..." +== 405 +-- truncate_limit: 100 +create function anyctest(anycompatiblenonarray, anycompatiblenonarray) +returns anycompatiblearray as $$ + select array[$1, $2] +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(anycompatiblenonarray, anycompatiblenonarray) RETURNS anycompatiblearray..." +== 406 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12) x" +== 407 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12.3) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12.3) x" +== 408 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(array[11], array[1,2]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(ARRAY[11], ARRAY[1, 2]) x" +== 409 +-- truncate_limit: 100 +-- fail + +drop function anyctest(anycompatiblenonarray, anycompatiblenonarray) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(anycompatiblenonarray, anycompatiblenonarray)" +== 410 +-- truncate_limit: 100 +create function anyctest(a anyelement, b anyarray, + c anycompatible, d anycompatible) +returns anycompatiblearray as $$ + select array[c, d] +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(a anyelement, b anyarray, c anycompatible, d anycompatible) RETURNS anyc..." +== 411 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, array[1, 2], 42, 34.5) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, ARRAY[1, 2], 42, 34.5) x" +== 412 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, array[1, 2], point(1,2), point(3,4)) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, ARRAY[1, 2], point(1, 2), point(3, 4)) x" +== 413 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, '{1,2}', point(1,2), '(3,4)') x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, '{1,2}', point(1, 2), '(3,4)') x" +== 414 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, array[1, 2.2], 42, 34.5) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, ARRAY[1, 2.2], 42, 34.5) x" +== 415 +-- truncate_limit: 100 +-- fail + +drop function anyctest(a anyelement, b anyarray, + c anycompatible, d anycompatible) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(a anyelement, b anyarray, c anycompatible, d anycompatible)" +== 416 +-- truncate_limit: 100 +create function anyctest(variadic anycompatiblearray) +returns anycompatiblearray as $$ + select $1 +$$ language sql +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyctest(VARIADIC anycompatiblearray) RETURNS anycompatiblearray AS $$\n select $..." +== 417 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12) x" +== 418 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, 12.2) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, 12.2) x" +== 419 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, '12') x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, '12') x" +== 420 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(11, '12.2') x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(11, '12.2') x" +== 421 +-- truncate_limit: 100 +-- fail +select x, pg_typeof(x) from anyctest(variadic array[11, 12]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(VARIADIC ARRAY[11, 12]) x" +== 422 +-- truncate_limit: 100 +select x, pg_typeof(x) from anyctest(variadic array[11, 12.2]) x +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, pg_typeof(x) FROM anyctest(VARIADIC ARRAY[11, 12.2]) x" +== 423 +-- truncate_limit: 100 +drop function anyctest(variadic anycompatiblearray) +-- +FUNCTION: name="anyctest" function="anyctest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyctest(VARIADIC anycompatiblearray)" diff --git a/parser/testdata/summary_truncate/postgres_regress/portals.metadata.json b/parser/testdata/summary_truncate/postgres_regress/portals.metadata.json new file mode 100644 index 0000000..f599902 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/portals.metadata.json @@ -0,0 +1,353 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/portals.test b/parser/testdata/summary_truncate/postgres_regress/portals.test new file mode 100644 index 0000000..e636128 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/portals.test @@ -0,0 +1,2323 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Cursor regression tests +|-- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 002 +-- truncate_limit: 100 +DECLARE foo1 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo1 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 003 +-- truncate_limit: 100 +DECLARE foo2 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo2 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 004 +-- truncate_limit: 100 +DECLARE foo3 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo3 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 005 +-- truncate_limit: 100 +DECLARE foo4 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo4 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 006 +-- truncate_limit: 100 +DECLARE foo5 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo5 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 007 +-- truncate_limit: 100 +DECLARE foo6 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo6 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 008 +-- truncate_limit: 100 +DECLARE foo7 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo7 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 009 +-- truncate_limit: 100 +DECLARE foo8 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo8 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 010 +-- truncate_limit: 100 +DECLARE foo9 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo9 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 011 +-- truncate_limit: 100 +DECLARE foo10 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo10 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 012 +-- truncate_limit: 100 +DECLARE foo11 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo11 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 013 +-- truncate_limit: 100 +DECLARE foo12 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo12 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 014 +-- truncate_limit: 100 +DECLARE foo13 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo13 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 015 +-- truncate_limit: 100 +DECLARE foo14 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo14 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 016 +-- truncate_limit: 100 +DECLARE foo15 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo15 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 017 +-- truncate_limit: 100 +DECLARE foo16 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo16 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 018 +-- truncate_limit: 100 +DECLARE foo17 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo17 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 019 +-- truncate_limit: 100 +DECLARE foo18 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo18 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 020 +-- truncate_limit: 100 +DECLARE foo19 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo19 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 021 +-- truncate_limit: 100 +DECLARE foo20 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo20 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 022 +-- truncate_limit: 100 +DECLARE foo21 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo21 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 023 +-- truncate_limit: 100 +DECLARE foo22 SCROLL CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo22 SCROLL CURSOR FOR SELECT * FROM tenk2" +== 024 +-- truncate_limit: 100 +DECLARE foo23 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo23 SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 025 +-- truncate_limit: 100 +FETCH 1 in foo1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo1" +== 026 +-- truncate_limit: 100 +FETCH 2 in foo2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 2 foo2" +== 027 +-- truncate_limit: 100 +FETCH 3 in foo3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 3 foo3" +== 028 +-- truncate_limit: 100 +FETCH 4 in foo4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 4 foo4" +== 029 +-- truncate_limit: 100 +FETCH 5 in foo5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 5 foo5" +== 030 +-- truncate_limit: 100 +FETCH 6 in foo6 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 6 foo6" +== 031 +-- truncate_limit: 100 +FETCH 7 in foo7 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 7 foo7" +== 032 +-- truncate_limit: 100 +FETCH 8 in foo8 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 8 foo8" +== 033 +-- truncate_limit: 100 +FETCH 9 in foo9 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 9 foo9" +== 034 +-- truncate_limit: 100 +FETCH 10 in foo10 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 10 foo10" +== 035 +-- truncate_limit: 100 +FETCH 11 in foo11 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 11 foo11" +== 036 +-- truncate_limit: 100 +FETCH 12 in foo12 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 12 foo12" +== 037 +-- truncate_limit: 100 +FETCH 13 in foo13 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 13 foo13" +== 038 +-- truncate_limit: 100 +FETCH 14 in foo14 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 14 foo14" +== 039 +-- truncate_limit: 100 +FETCH 15 in foo15 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 15 foo15" +== 040 +-- truncate_limit: 100 +FETCH 16 in foo16 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 16 foo16" +== 041 +-- truncate_limit: 100 +FETCH 17 in foo17 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 17 foo17" +== 042 +-- truncate_limit: 100 +FETCH 18 in foo18 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 18 foo18" +== 043 +-- truncate_limit: 100 +FETCH 19 in foo19 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 19 foo19" +== 044 +-- truncate_limit: 100 +FETCH 20 in foo20 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 20 foo20" +== 045 +-- truncate_limit: 100 +FETCH 21 in foo21 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 21 foo21" +== 046 +-- truncate_limit: 100 +FETCH 22 in foo22 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 22 foo22" +== 047 +-- truncate_limit: 100 +FETCH 23 in foo23 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 23 foo23" +== 048 +-- truncate_limit: 100 +FETCH backward 1 in foo23 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR foo23" +== 049 +-- truncate_limit: 100 +FETCH backward 2 in foo22 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 2 foo22" +== 050 +-- truncate_limit: 100 +FETCH backward 3 in foo21 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 3 foo21" +== 051 +-- truncate_limit: 100 +FETCH backward 4 in foo20 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 4 foo20" +== 052 +-- truncate_limit: 100 +FETCH backward 5 in foo19 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 5 foo19" +== 053 +-- truncate_limit: 100 +FETCH backward 6 in foo18 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 6 foo18" +== 054 +-- truncate_limit: 100 +FETCH backward 7 in foo17 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 7 foo17" +== 055 +-- truncate_limit: 100 +FETCH backward 8 in foo16 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 8 foo16" +== 056 +-- truncate_limit: 100 +FETCH backward 9 in foo15 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 9 foo15" +== 057 +-- truncate_limit: 100 +FETCH backward 10 in foo14 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 10 foo14" +== 058 +-- truncate_limit: 100 +FETCH backward 11 in foo13 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 11 foo13" +== 059 +-- truncate_limit: 100 +FETCH backward 12 in foo12 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 12 foo12" +== 060 +-- truncate_limit: 100 +FETCH backward 13 in foo11 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 13 foo11" +== 061 +-- truncate_limit: 100 +FETCH backward 14 in foo10 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 14 foo10" +== 062 +-- truncate_limit: 100 +FETCH backward 15 in foo9 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 15 foo9" +== 063 +-- truncate_limit: 100 +FETCH backward 16 in foo8 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 16 foo8" +== 064 +-- truncate_limit: 100 +FETCH backward 17 in foo7 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 17 foo7" +== 065 +-- truncate_limit: 100 +FETCH backward 18 in foo6 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 18 foo6" +== 066 +-- truncate_limit: 100 +FETCH backward 19 in foo5 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 19 foo5" +== 067 +-- truncate_limit: 100 +FETCH backward 20 in foo4 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 20 foo4" +== 068 +-- truncate_limit: 100 +FETCH backward 21 in foo3 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 21 foo3" +== 069 +-- truncate_limit: 100 +FETCH backward 22 in foo2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 22 foo2" +== 070 +-- truncate_limit: 100 +FETCH backward 23 in foo1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD 23 foo1" +== 071 +-- truncate_limit: 100 +CLOSE foo1 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo1" +== 072 +-- truncate_limit: 100 +CLOSE foo2 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo2" +== 073 +-- truncate_limit: 100 +CLOSE foo3 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo3" +== 074 +-- truncate_limit: 100 +CLOSE foo4 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo4" +== 075 +-- truncate_limit: 100 +CLOSE foo5 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo5" +== 076 +-- truncate_limit: 100 +CLOSE foo6 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo6" +== 077 +-- truncate_limit: 100 +CLOSE foo7 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo7" +== 078 +-- truncate_limit: 100 +CLOSE foo8 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo8" +== 079 +-- truncate_limit: 100 +CLOSE foo9 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo9" +== 080 +-- truncate_limit: 100 +CLOSE foo10 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo10" +== 081 +-- truncate_limit: 100 +CLOSE foo11 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo11" +== 082 +-- truncate_limit: 100 +CLOSE foo12 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo12" +== 083 +-- truncate_limit: 100 +-- leave some cursors open, to test that auto-close works. + +-- record this in the system view as well (don't query the time field there +-- however) +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors ORDER BY 1 +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors ORDER BY 1" +== 084 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 085 +-- truncate_limit: 100 +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors" +== 086 +-- truncate_limit: 100 +|-- +-- NO SCROLL disallows backward fetching +|-- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 087 +-- truncate_limit: 100 +DECLARE foo24 NO SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo24 NO SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 088 +-- truncate_limit: 100 +FETCH 1 FROM foo24 +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo24" +== 089 +-- truncate_limit: 100 +FETCH BACKWARD 1 FROM foo24 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR foo24" +== 090 +-- truncate_limit: 100 +-- should fail + +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 091 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 092 +-- truncate_limit: 100 +DECLARE foo24 NO SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo24 NO SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2" +== 093 +-- truncate_limit: 100 +FETCH 1 FROM foo24 +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo24" +== 094 +-- truncate_limit: 100 +FETCH ABSOLUTE 2 FROM foo24 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ABSOLUTE 2 foo24" +== 095 +-- truncate_limit: 100 +-- allowed + +FETCH ABSOLUTE 1 FROM foo24 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FIRST foo24" +== 096 +-- truncate_limit: 100 +-- should fail + +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 097 +-- truncate_limit: 100 +|-- +-- Cursors outside transaction blocks +|-- + + +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors" +== 098 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 099 +-- truncate_limit: 100 +DECLARE foo25 SCROLL CURSOR WITH HOLD FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo25 SCROLL CURSOR WITH HOLD FOR SELECT * FROM tenk2" +== 100 +-- truncate_limit: 100 +FETCH FROM foo25 +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo25" +== 101 +-- truncate_limit: 100 +FETCH FROM foo25 +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo25" +== 102 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 103 +-- truncate_limit: 100 +FETCH FROM foo25 +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo25" +== 104 +-- truncate_limit: 100 +FETCH BACKWARD FROM foo25 +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR foo25" +== 105 +-- truncate_limit: 100 +FETCH ABSOLUTE -1 FROM foo25 +-- +STMT: FetchStmt +TRUNCATED: "FETCH LAST foo25" +== 106 +-- truncate_limit: 100 +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors" +== 107 +-- truncate_limit: 100 +CLOSE foo25 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo25" +== 108 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 109 +-- truncate_limit: 100 +DECLARE foo25ns NO SCROLL CURSOR WITH HOLD FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo25ns NO SCROLL CURSOR WITH HOLD FOR SELECT * FROM tenk2" +== 110 +-- truncate_limit: 100 +FETCH FROM foo25ns +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo25ns" +== 111 +-- truncate_limit: 100 +FETCH FROM foo25ns +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo25ns" +== 112 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 113 +-- truncate_limit: 100 +FETCH FROM foo25ns +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo25ns" +== 114 +-- truncate_limit: 100 +FETCH ABSOLUTE 4 FROM foo25ns +-- +STMT: FetchStmt +TRUNCATED: "FETCH ABSOLUTE 4 foo25ns" +== 115 +-- truncate_limit: 100 +FETCH ABSOLUTE 4 FROM foo25ns +-- +STMT: FetchStmt +TRUNCATED: "FETCH ABSOLUTE 4 foo25ns" +== 116 +-- truncate_limit: 100 +-- fail + +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors" +== 117 +-- truncate_limit: 100 +CLOSE foo25ns +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo25ns" +== 118 +-- truncate_limit: 100 +|-- +-- ROLLBACK should close holdable cursors +|-- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 119 +-- truncate_limit: 100 +DECLARE foo26 CURSOR WITH HOLD FOR SELECT * FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo26 CURSOR WITH HOLD FOR SELECT * FROM tenk1 ORDER BY unique2" +== 120 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 121 +-- truncate_limit: 100 +-- should fail +FETCH FROM foo26 +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo26" +== 122 +-- truncate_limit: 100 +|-- +-- Parameterized DECLARE needs to insert param values into the cursor portal +|-- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 123 +-- truncate_limit: 100 +CREATE FUNCTION declares_cursor(text) + RETURNS void + AS 'DECLARE c CURSOR FOR SELECT stringu1 FROM tenk1 WHERE stringu1 LIKE $1;' + LANGUAGE SQL +-- +FUNCTION: name="declares_cursor" function="declares_cursor" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION declares_cursor(text) RETURNS void AS $$DECLARE c CURSOR FOR SELECT stringu1 FROM..." +== 124 +-- truncate_limit: 100 +SELECT declares_cursor('AB%') +-- +FUNCTION: name="declares_cursor" function="declares_cursor" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT declares_cursor('AB%')" +== 125 +-- truncate_limit: 100 +FETCH ALL FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c" +== 126 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 127 +-- truncate_limit: 100 +|-- +-- Test behavior of both volatile and stable functions inside a cursor; +-- in particular we want to see what happens during commit of a holdable +-- cursor +|-- + +create temp table tt1(f1 int) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt1 (f1 int)" +== 128 +-- truncate_limit: 100 +create function count_tt1_v() returns int8 as +'select count(*) from tt1' language sql volatile +-- +FUNCTION: name="count_tt1_v" function="count_tt1_v" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION count_tt1_v() RETURNS int8 AS $$select count(*) from tt1$$ LANGUAGE sql VOLATILE" +== 129 +-- truncate_limit: 100 +create function count_tt1_s() returns int8 as +'select count(*) from tt1' language sql stable +-- +FUNCTION: name="count_tt1_s" function="count_tt1_s" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION count_tt1_s() RETURNS int8 AS $$select count(*) from tt1$$ LANGUAGE sql STABLE" +== 130 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 131 +-- truncate_limit: 100 +insert into tt1 values(1) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt1 VALUES (1)" +== 132 +-- truncate_limit: 100 +declare c1 cursor for select count_tt1_v(), count_tt1_s() +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT count_tt1_v(), count_tt1_s()" +== 133 +-- truncate_limit: 100 +insert into tt1 values(2) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt1 VALUES (2)" +== 134 +-- truncate_limit: 100 +fetch all from c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c1" +== 135 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 136 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 137 +-- truncate_limit: 100 +insert into tt1 values(1) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt1 VALUES (1)" +== 138 +-- truncate_limit: 100 +declare c2 cursor with hold for select count_tt1_v(), count_tt1_s() +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c2 CURSOR WITH HOLD FOR SELECT count_tt1_v(), count_tt1_s()" +== 139 +-- truncate_limit: 100 +insert into tt1 values(2) +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt1 VALUES (2)" +== 140 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 141 +-- truncate_limit: 100 +delete from tt1 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tt1" +== 142 +-- truncate_limit: 100 +fetch all from c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c2" +== 143 +-- truncate_limit: 100 +drop function count_tt1_v() +-- +FUNCTION: name="count_tt1_v" function="count_tt1_v" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION count_tt1_v()" +== 144 +-- truncate_limit: 100 +drop function count_tt1_s() +-- +FUNCTION: name="count_tt1_s" function="count_tt1_s" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION count_tt1_s()" +== 145 +-- truncate_limit: 100 +-- Create a cursor with the BINARY option and check the pg_cursors view +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 146 +-- truncate_limit: 100 +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors" +== 147 +-- truncate_limit: 100 +DECLARE bc BINARY CURSOR FOR SELECT * FROM tenk1 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE bc BINARY CURSOR FOR SELECT * FROM tenk1" +== 148 +-- truncate_limit: 100 +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors ORDER BY 1 +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors ORDER BY 1" +== 149 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 150 +-- truncate_limit: 100 +-- We should not see the portal that is created internally to +-- implement EXECUTE in pg_cursors +PREPARE cprep AS + SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE cprep AS SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors" +== 151 +-- truncate_limit: 100 +EXECUTE cprep +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE cprep" +== 152 +-- truncate_limit: 100 +-- test CLOSE ALL; +SELECT name FROM pg_cursors ORDER BY 1 +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_cursors ORDER BY 1" +== 153 +-- truncate_limit: 100 +CLOSE ALL +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE ALL" +== 154 +-- truncate_limit: 100 +SELECT name FROM pg_cursors ORDER BY 1 +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_cursors ORDER BY 1" +== 155 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 156 +-- truncate_limit: 100 +DECLARE foo1 CURSOR WITH HOLD FOR SELECT 1 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo1 CURSOR WITH HOLD FOR SELECT 1" +== 157 +-- truncate_limit: 100 +DECLARE foo2 CURSOR WITHOUT HOLD FOR SELECT 1 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo2 CURSOR FOR SELECT 1" +== 158 +-- truncate_limit: 100 +SELECT name FROM pg_cursors ORDER BY 1 +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_cursors ORDER BY 1" +== 159 +-- truncate_limit: 100 +CLOSE ALL +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE ALL" +== 160 +-- truncate_limit: 100 +SELECT name FROM pg_cursors ORDER BY 1 +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name FROM pg_cursors ORDER BY 1" +== 161 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 162 +-- truncate_limit: 100 +|-- +-- Tests for updatable cursors +|-- + +CREATE TEMP TABLE uctest(f1 int, f2 text) +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE uctest (f1 int, f2 text)" +== 163 +-- truncate_limit: 100 +INSERT INTO uctest VALUES (1, 'one'), (2, 'two'), (3, 'three') +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uctest VALUES (1, 'one'), (2, 'two'), (3, 'three')" +== 164 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 165 +-- truncate_limit: 100 +-- Check DELETE WHERE CURRENT +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 166 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest" +== 167 +-- truncate_limit: 100 +FETCH 2 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 2 c1" +== 168 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c1" +== 169 +-- truncate_limit: 100 +-- should show deletion +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 170 +-- truncate_limit: 100 +-- cursor did not move +FETCH ALL FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c1" +== 171 +-- truncate_limit: 100 +-- cursor is insensitive +MOVE BACKWARD ALL IN c1 +-- +STMT: FetchStmt +TRUNCATED: "MOVE BACKWARD ALL c1" +== 172 +-- truncate_limit: 100 +FETCH ALL FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c1" +== 173 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 174 +-- truncate_limit: 100 +-- should still see deletion +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 175 +-- truncate_limit: 100 +-- Check UPDATE WHERE CURRENT; this time use FOR UPDATE +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 176 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest FOR UPDATE +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest FOR UPDATE" +== 177 +-- truncate_limit: 100 +FETCH c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 178 +-- truncate_limit: 100 +UPDATE uctest SET f1 = 8 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = 8 WHERE CURRENT OF c1" +== 179 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 180 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 181 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 182 +-- truncate_limit: 100 +-- Check repeated-update and update-then-delete cases +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 183 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest" +== 184 +-- truncate_limit: 100 +FETCH c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 185 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 186 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 187 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 188 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 189 +-- truncate_limit: 100 +-- insensitive cursor should not show effects of updates or deletes +FETCH RELATIVE 0 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH RELATIVE 0 c1" +== 190 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c1" +== 191 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 192 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c1" +== 193 +-- truncate_limit: 100 +-- no-op +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 194 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 195 +-- truncate_limit: 100 +-- no-op +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 196 +-- truncate_limit: 100 +FETCH RELATIVE 0 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH RELATIVE 0 c1" +== 197 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 198 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 199 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 200 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest FOR UPDATE +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest FOR UPDATE" +== 201 +-- truncate_limit: 100 +FETCH c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 202 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 203 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 204 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 205 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 206 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c1" +== 207 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 208 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c1" +== 209 +-- truncate_limit: 100 +-- no-op +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 210 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 211 +-- truncate_limit: 100 +-- no-op +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 212 +-- truncate_limit: 100 +--- FOR UPDATE cursors can't currently scroll back, so this is an error: +FETCH RELATIVE 0 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH RELATIVE 0 c1" +== 213 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 214 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 215 +-- truncate_limit: 100 +-- Check insensitive cursor with INSERT +-- (The above tests don't test the SQL notion of an insensitive cursor +-- correctly, because per SQL standard, changes from WHERE CURRENT OF +-- commands should be visible in the cursor. So here we make the +-- changes with a command that is independent of the cursor.) +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 216 +-- truncate_limit: 100 +DECLARE c1 INSENSITIVE CURSOR FOR SELECT * FROM uctest +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 INSENSITIVE CURSOR FOR SELECT * FROM uctest" +== 217 +-- truncate_limit: 100 +INSERT INTO uctest VALUES (10, 'ten') +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uctest VALUES (10, 'ten')" +== 218 +-- truncate_limit: 100 +FETCH NEXT FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 219 +-- truncate_limit: 100 +FETCH NEXT FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 220 +-- truncate_limit: 100 +FETCH NEXT FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 221 +-- truncate_limit: 100 +-- insert not visible +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 222 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 223 +-- truncate_limit: 100 +DELETE FROM uctest WHERE f1 = 10 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE f1 = 10" +== 224 +-- truncate_limit: 100 +-- restore test table state + +-- Check inheritance cases +CREATE TEMP TABLE ucchild () inherits (uctest) +-- +TABLE: name="ucchild" schema="" table="ucchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE ucchild () INHERITS (uctest)" +== 225 +-- truncate_limit: 100 +INSERT INTO ucchild values(100, 'hundred') +-- +TABLE: name="ucchild" schema="" table="ucchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ucchild VALUES (100, 'hundred')" +== 226 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 227 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 228 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest FOR UPDATE +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest FOR UPDATE" +== 229 +-- truncate_limit: 100 +FETCH 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 230 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 231 +-- truncate_limit: 100 +FETCH 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 232 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 233 +-- truncate_limit: 100 +FETCH 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 234 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 235 +-- truncate_limit: 100 +FETCH 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 236 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 237 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 238 +-- truncate_limit: 100 +-- Can update from a self-join, but only if FOR UPDATE says which to use +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 239 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest a, uctest b WHERE a.f1 = b.f1 + 5 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest a, uctest b WHERE a.f1 = (b.f1 + 5)" +== 240 +-- truncate_limit: 100 +FETCH 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 241 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 242 +-- truncate_limit: 100 +-- fail +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 243 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 244 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest a, uctest b WHERE a.f1 = b.f1 + 5 FOR UPDATE +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest a, uctest b WHERE a.f1 = (b.f1 + 5) FOR UPDATE" +== 245 +-- truncate_limit: 100 +FETCH 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 246 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 247 +-- truncate_limit: 100 +-- fail +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 248 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 249 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest a, uctest b WHERE a.f1 = b.f1 + 5 FOR SHARE OF a +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest a, uctest b WHERE a.f1 = (b.f1 + 5) FOR SHARE OF a" +== 250 +-- truncate_limit: 100 +FETCH 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 251 +-- truncate_limit: 100 +UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE uctest SET f1 = f1 + 10 WHERE CURRENT OF c1" +== 252 +-- truncate_limit: 100 +SELECT * FROM uctest +-- +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uctest" +== 253 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 254 +-- truncate_limit: 100 +-- Check various error cases + +DELETE FROM uctest WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c1" +== 255 +-- truncate_limit: 100 +-- fail, no such cursor +DECLARE cx CURSOR WITH HOLD FOR SELECT * FROM uctest +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE cx CURSOR WITH HOLD FOR SELECT * FROM uctest" +== 256 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF cx +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF cx" +== 257 +-- truncate_limit: 100 +-- fail, can't use held cursor +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 258 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT * FROM tenk2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT * FROM tenk2" +== 259 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c" +== 260 +-- truncate_limit: 100 +-- fail, cursor on wrong table +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 261 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 262 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT * FROM tenk2 FOR SHARE +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT * FROM tenk2 FOR SHARE" +== 263 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c" +== 264 +-- truncate_limit: 100 +-- fail, cursor on wrong table +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 265 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 266 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT * FROM tenk1 JOIN tenk2 USING (unique1) +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT * FROM tenk1 JOIN tenk2 USING (unique1)" +== 267 +-- truncate_limit: 100 +DELETE FROM tenk1 WHERE CURRENT OF c +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tenk1 WHERE CURRENT OF c" +== 268 +-- truncate_limit: 100 +-- fail, cursor is on a join +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 269 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 270 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT f1,count(*) FROM uctest GROUP BY f1 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT f1, count(*) FROM uctest GROUP BY f1" +== 271 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c" +== 272 +-- truncate_limit: 100 +-- fail, cursor is on aggregation +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 273 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 274 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM uctest +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM uctest" +== 275 +-- truncate_limit: 100 +DELETE FROM uctest WHERE CURRENT OF c1 +-- +TABLE: name="uctest" schema="" table="uctest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uctest WHERE CURRENT OF c1" +== 276 +-- truncate_limit: 100 +-- fail, no current row +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 277 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 278 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT MIN(f1) FROM uctest FOR UPDATE +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT min(f1) FROM uctest FOR UPDATE" +== 279 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 280 +-- truncate_limit: 100 +-- WHERE CURRENT OF may someday work with views, but today is not that day. +-- For now, just make sure it errors out cleanly. +CREATE TEMP VIEW ucview AS SELECT * FROM uctest +-- +TABLE: name="ucview" schema="" table="ucview" ctx=DDL +TABLE: name="uctest" schema="" table="uctest" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW ucview AS SELECT * FROM uctest" +== 281 +-- truncate_limit: 100 +CREATE RULE ucrule AS ON DELETE TO ucview DO INSTEAD + DELETE FROM uctest WHERE f1 = OLD.f1 +-- +TABLE: name="ucview" schema="" table="ucview" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE ucrule AS ON DELETE TO ucview DO INSTEAD DELETE FROM uctest WHERE f1 = old.f1" +== 282 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 283 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT * FROM ucview +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT * FROM ucview" +== 284 +-- truncate_limit: 100 +FETCH FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 285 +-- truncate_limit: 100 +DELETE FROM ucview WHERE CURRENT OF c1 +-- +TABLE: name="ucview" schema="" table="ucview" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ucview WHERE CURRENT OF c1" +== 286 +-- truncate_limit: 100 +-- fail, views not supported +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 287 +-- truncate_limit: 100 +-- Check WHERE CURRENT OF with an index-only scan +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 288 +-- truncate_limit: 100 +EXPLAIN (costs off) +DECLARE c1 CURSOR FOR SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA' +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c1 CURSOR FOR SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA'" +== 289 +-- truncate_limit: 100 +DECLARE c1 CURSOR FOR SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA' +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 CURSOR FOR SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA'" +== 290 +-- truncate_limit: 100 +FETCH FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH c1" +== 291 +-- truncate_limit: 100 +DELETE FROM onek WHERE CURRENT OF c1 +-- +TABLE: name="onek" schema="" table="onek" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM onek WHERE CURRENT OF c1" +== 292 +-- truncate_limit: 100 +SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA' +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA'" +== 293 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 294 +-- truncate_limit: 100 +-- Check behavior with rewinding to a previous child scan node, +-- as per bug #15395 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 295 +-- truncate_limit: 100 +CREATE TABLE current_check (currentid int, payload text) +-- +TABLE: name="current_check" schema="" table="current_check" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE current_check (currentid int, payload text)" +== 296 +-- truncate_limit: 100 +CREATE TABLE current_check_1 () INHERITS (current_check) +-- +TABLE: name="current_check_1" schema="" table="current_check_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE current_check_1 () INHERITS (current_check)" +== 297 +-- truncate_limit: 100 +CREATE TABLE current_check_2 () INHERITS (current_check) +-- +TABLE: name="current_check_2" schema="" table="current_check_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE current_check_2 () INHERITS (current_check)" +== 298 +-- truncate_limit: 100 +INSERT INTO current_check_1 SELECT i, 'p' || i FROM generate_series(1,9) i +-- +TABLE: name="current_check_1" schema="" table="current_check_1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO current_check_1 SELECT i, 'p' || i FROM generate_series(1, 9) i" +== 299 +-- truncate_limit: 100 +INSERT INTO current_check_2 SELECT i, 'P' || i FROM generate_series(10,19) i +-- +TABLE: name="current_check_2" schema="" table="current_check_2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO current_check_2 SELECT i, 'P' || i FROM generate_series(10, 19) i" +== 300 +-- truncate_limit: 100 +DECLARE c1 SCROLL CURSOR FOR SELECT * FROM current_check +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 SCROLL CURSOR FOR SELECT * FROM current_check" +== 301 +-- truncate_limit: 100 +-- This tests the fetch-backwards code path +FETCH ABSOLUTE 12 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ABSOLUTE 12 c1" +== 302 +-- truncate_limit: 100 +FETCH ABSOLUTE 8 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ABSOLUTE 8 c1" +== 303 +-- truncate_limit: 100 +DELETE FROM current_check WHERE CURRENT OF c1 RETURNING * +-- +TABLE: name="current_check" schema="" table="current_check" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM current_check WHERE CURRENT OF c1 RETURNING *" +== 304 +-- truncate_limit: 100 +-- This tests the ExecutorRewind code path +FETCH ABSOLUTE 13 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ABSOLUTE 13 c1" +== 305 +-- truncate_limit: 100 +FETCH ABSOLUTE 1 FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH FIRST c1" +== 306 +-- truncate_limit: 100 +DELETE FROM current_check WHERE CURRENT OF c1 RETURNING * +-- +TABLE: name="current_check" schema="" table="current_check" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM current_check WHERE CURRENT OF c1 RETURNING *" +== 307 +-- truncate_limit: 100 +SELECT * FROM current_check +-- +TABLE: name="current_check" schema="" table="current_check" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM current_check" +== 308 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 309 +-- truncate_limit: 100 +-- Make sure snapshot management works okay, per bug report in +-- 235395b90909301035v7228ce63q392931f15aa74b31@mail.gmail.com +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 310 +-- truncate_limit: 100 +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE" +== 311 +-- truncate_limit: 100 +CREATE TABLE cursor (a int) +-- +TABLE: name="cursor" schema="" table="cursor" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cursor (a int)" +== 312 +-- truncate_limit: 100 +INSERT INTO cursor VALUES (1) +-- +TABLE: name="cursor" schema="" table="cursor" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cursor VALUES (1)" +== 313 +-- truncate_limit: 100 +DECLARE c1 NO SCROLL CURSOR FOR SELECT * FROM cursor FOR UPDATE +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 NO SCROLL CURSOR FOR SELECT * FROM cursor FOR UPDATE" +== 314 +-- truncate_limit: 100 +UPDATE cursor SET a = 2 +-- +TABLE: name="cursor" schema="" table="cursor" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE cursor SET a = 2" +== 315 +-- truncate_limit: 100 +FETCH ALL FROM c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c1" +== 316 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 317 +-- truncate_limit: 100 +DROP TABLE cursor +-- +TABLE: name="cursor" schema="" table="cursor" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cursor" +== 318 +-- truncate_limit: 100 +-- Check rewinding a cursor containing a stable function in LIMIT, +-- per bug report in 8336843.9833.1399385291498.JavaMail.root@quick +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 319 +-- truncate_limit: 100 +create function nochange(int) returns int + as 'select $1 limit 1' language sql stable +-- +FUNCTION: name="nochange" function="nochange" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION nochange(int) RETURNS int AS $$select $1 limit 1$$ LANGUAGE sql STABLE" +== 320 +-- truncate_limit: 100 +declare c cursor for select * from int8_tbl limit nochange(3) +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT * FROM int8_tbl LIMIT nochange(3)" +== 321 +-- truncate_limit: 100 +fetch all from c +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c" +== 322 +-- truncate_limit: 100 +move backward all in c +-- +STMT: FetchStmt +TRUNCATED: "MOVE BACKWARD ALL c" +== 323 +-- truncate_limit: 100 +fetch all from c +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c" +== 324 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 325 +-- truncate_limit: 100 +-- Check handling of non-backwards-scan-capable plans with scroll cursors +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 326 +-- truncate_limit: 100 +explain (costs off) declare c1 cursor for select (select 42) as x +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c1 CURSOR FOR SELECT (SELECT 42) AS x" +== 327 +-- truncate_limit: 100 +explain (costs off) declare c1 scroll cursor for select (select 42) as x +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c1 SCROLL CURSOR FOR SELECT (SELECT 42) AS x" +== 328 +-- truncate_limit: 100 +declare c1 scroll cursor for select (select 42) as x +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 SCROLL CURSOR FOR SELECT (SELECT 42) AS x" +== 329 +-- truncate_limit: 100 +fetch all in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c1" +== 330 +-- truncate_limit: 100 +fetch backward all in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c1" +== 331 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 332 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 333 +-- truncate_limit: 100 +explain (costs off) declare c2 cursor for select generate_series(1,3) as g +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c2 CURSOR FOR SELECT generate_series(1, 3) AS g" +== 334 +-- truncate_limit: 100 +explain (costs off) declare c2 scroll cursor for select generate_series(1,3) as g +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c2 SCROLL CURSOR FOR SELECT generate_series(1, 3) AS g" +== 335 +-- truncate_limit: 100 +declare c2 scroll cursor for select generate_series(1,3) as g +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c2 SCROLL CURSOR FOR SELECT generate_series(1, 3) AS g" +== 336 +-- truncate_limit: 100 +fetch all in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c2" +== 337 +-- truncate_limit: 100 +fetch backward all in c2 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c2" +== 338 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 339 +-- truncate_limit: 100 +-- Check fetching of toasted datums via cursors. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 340 +-- truncate_limit: 100 +-- Other compression algorithms may cause the compressed data to be stored +-- inline. Use pglz to ensure consistent results. +set default_toast_compression = 'pglz' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_toast_compression TO pglz" +== 341 +-- truncate_limit: 100 +create table toasted_data (f1 int[]) +-- +TABLE: name="toasted_data" schema="" table="toasted_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE toasted_data (f1 int[])" +== 342 +-- truncate_limit: 100 +insert into toasted_data + select array_agg(i) from generate_series(12345678, 12345678 + 1000) i +-- +TABLE: name="toasted_data" schema="" table="toasted_data" ctx=DML +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO toasted_data SELECT array_agg(i) FROM generate_series(12345678, 12345678 + 1000) i" +== 343 +-- truncate_limit: 100 +declare local_portal cursor for select * from toasted_data +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE local_portal CURSOR FOR SELECT * FROM toasted_data" +== 344 +-- truncate_limit: 100 +fetch all in local_portal +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL local_portal" +== 345 +-- truncate_limit: 100 +declare held_portal cursor with hold for select * from toasted_data +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE held_portal CURSOR WITH HOLD FOR SELECT * FROM toasted_data" +== 346 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 347 +-- truncate_limit: 100 +drop table toasted_data +-- +TABLE: name="toasted_data" schema="" table="toasted_data" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE toasted_data" +== 348 +-- truncate_limit: 100 +fetch all in held_portal +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL held_portal" +== 349 +-- truncate_limit: 100 +reset default_toast_compression +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_toast_compression" diff --git a/parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json b/parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json new file mode 100644 index 0000000..66f0b1d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json @@ -0,0 +1,45 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/portals_p2.test b/parser/testdata/summary_truncate/postgres_regress/portals_p2.test new file mode 100644 index 0000000..d417434 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/portals_p2.test @@ -0,0 +1,263 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PORTALS_P2 +|-- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 002 +-- truncate_limit: 100 +DECLARE foo13 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 50 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo13 CURSOR FOR SELECT * FROM onek WHERE unique1 = 50" +== 003 +-- truncate_limit: 100 +DECLARE foo14 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 51 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo14 CURSOR FOR SELECT * FROM onek WHERE unique1 = 51" +== 004 +-- truncate_limit: 100 +DECLARE foo15 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 52 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo15 CURSOR FOR SELECT * FROM onek WHERE unique1 = 52" +== 005 +-- truncate_limit: 100 +DECLARE foo16 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 53 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo16 CURSOR FOR SELECT * FROM onek WHERE unique1 = 53" +== 006 +-- truncate_limit: 100 +DECLARE foo17 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 54 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo17 CURSOR FOR SELECT * FROM onek WHERE unique1 = 54" +== 007 +-- truncate_limit: 100 +DECLARE foo18 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 55 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo18 CURSOR FOR SELECT * FROM onek WHERE unique1 = 55" +== 008 +-- truncate_limit: 100 +DECLARE foo19 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 56 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo19 CURSOR FOR SELECT * FROM onek WHERE unique1 = 56" +== 009 +-- truncate_limit: 100 +DECLARE foo20 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 57 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo20 CURSOR FOR SELECT * FROM onek WHERE unique1 = 57" +== 010 +-- truncate_limit: 100 +DECLARE foo21 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 58 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo21 CURSOR FOR SELECT * FROM onek WHERE unique1 = 58" +== 011 +-- truncate_limit: 100 +DECLARE foo22 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 59 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo22 CURSOR FOR SELECT * FROM onek WHERE unique1 = 59" +== 012 +-- truncate_limit: 100 +DECLARE foo23 CURSOR FOR + SELECT * FROM onek WHERE unique1 = 60 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo23 CURSOR FOR SELECT * FROM onek WHERE unique1 = 60" +== 013 +-- truncate_limit: 100 +DECLARE foo24 CURSOR FOR + SELECT * FROM onek2 WHERE unique1 = 50 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo24 CURSOR FOR SELECT * FROM onek2 WHERE unique1 = 50" +== 014 +-- truncate_limit: 100 +DECLARE foo25 CURSOR FOR + SELECT * FROM onek2 WHERE unique1 = 60 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo25 CURSOR FOR SELECT * FROM onek2 WHERE unique1 = 60" +== 015 +-- truncate_limit: 100 +FETCH all in foo13 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo13" +== 016 +-- truncate_limit: 100 +FETCH all in foo14 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo14" +== 017 +-- truncate_limit: 100 +FETCH all in foo15 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo15" +== 018 +-- truncate_limit: 100 +FETCH all in foo16 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo16" +== 019 +-- truncate_limit: 100 +FETCH all in foo17 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo17" +== 020 +-- truncate_limit: 100 +FETCH all in foo18 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo18" +== 021 +-- truncate_limit: 100 +FETCH all in foo19 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo19" +== 022 +-- truncate_limit: 100 +FETCH all in foo20 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo20" +== 023 +-- truncate_limit: 100 +FETCH all in foo21 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo21" +== 024 +-- truncate_limit: 100 +FETCH all in foo22 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo22" +== 025 +-- truncate_limit: 100 +FETCH all in foo23 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo23" +== 026 +-- truncate_limit: 100 +FETCH all in foo24 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo24" +== 027 +-- truncate_limit: 100 +FETCH all in foo25 +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL foo25" +== 028 +-- truncate_limit: 100 +CLOSE foo13 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo13" +== 029 +-- truncate_limit: 100 +CLOSE foo14 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo14" +== 030 +-- truncate_limit: 100 +CLOSE foo15 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo15" +== 031 +-- truncate_limit: 100 +CLOSE foo16 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo16" +== 032 +-- truncate_limit: 100 +CLOSE foo17 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo17" +== 033 +-- truncate_limit: 100 +CLOSE foo18 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo18" +== 034 +-- truncate_limit: 100 +CLOSE foo19 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo19" +== 035 +-- truncate_limit: 100 +CLOSE foo20 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo20" +== 036 +-- truncate_limit: 100 +CLOSE foo21 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo21" +== 037 +-- truncate_limit: 100 +CLOSE foo22 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo22" +== 038 +-- truncate_limit: 100 +CLOSE foo23 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo23" +== 039 +-- truncate_limit: 100 +CLOSE foo24 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo24" +== 040 +-- truncate_limit: 100 +CLOSE foo25 +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE foo25" +== 041 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" diff --git a/parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json new file mode 100644 index 0000000..6e8763d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json @@ -0,0 +1,46 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/predicate.test b/parser/testdata/summary_truncate/postgres_regress/predicate.test new file mode 100644 index 0000000..578683c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/predicate.test @@ -0,0 +1,515 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for predicate handling +|-- + +|-- +-- Test that restrictions that are always true are ignored, and that are always +-- false are replaced with constant-FALSE +|-- +-- Currently we only check for NullTest quals and OR clauses that include +-- NullTest quals. We may extend it in the future. +|-- +CREATE TABLE pred_tab (a int NOT NULL, b int, c int NOT NULL) +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pred_tab (a int NOT NULL, b int, c int NOT NULL)" +== 002 +-- truncate_limit: 100 +|-- +-- Test restriction clauses +|-- + +-- Ensure the IS_NOT_NULL qual is ignored when the column is non-nullable +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.a IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.a IS NOT NULL" +== 003 +-- truncate_limit: 100 +-- Ensure the IS_NOT_NULL qual is not ignored on a nullable column +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.b IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.b IS NOT NULL" +== 004 +-- truncate_limit: 100 +-- Ensure the IS_NULL qual is reduced to constant-FALSE for non-nullable +-- columns +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.a IS NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.a IS NULL" +== 005 +-- truncate_limit: 100 +-- Ensure the IS_NULL qual is not reduced to constant-FALSE on nullable +-- columns +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.b IS NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.b IS NULL" +== 006 +-- truncate_limit: 100 +|-- +-- Tests for OR clauses in restriction clauses +|-- + +-- Ensure the OR clause is ignored when an OR branch is always true +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.a IS NOT NULL OR t.b = 1 +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="a" +FILTER: schema="" table="t" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.a IS NOT NULL OR t.b = 1" +== 007 +-- truncate_limit: 100 +-- Ensure the OR clause is not ignored for NullTests that can't be proven +-- always true +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.b IS NOT NULL OR t.a = 1 +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="b" +FILTER: schema="" table="t" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.b IS NOT NULL OR t.a = 1" +== 008 +-- truncate_limit: 100 +-- Ensure the OR clause is reduced to constant-FALSE when all branches are +-- provably false +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.a IS NULL OR t.c IS NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="a" +FILTER: schema="" table="t" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.a IS NULL OR t.c IS NULL" +== 009 +-- truncate_limit: 100 +-- Ensure the OR clause is not reduced to constant-FALSE when not all branches +-- are provably false +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t WHERE t.b IS NULL OR t.c IS NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t"="pred_tab" +FILTER: schema="" table="t" column="b" +FILTER: schema="" table="t" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t WHERE t.b IS NULL OR t.c IS NULL" +== 010 +-- truncate_limit: 100 +|-- +-- Test join clauses +|-- + +-- Ensure the IS_NOT_NULL qual is ignored, since a) it's on a NOT NULL column, +-- and b) its Var is not nullable by any outer joins +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON t1.a IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON t1.a IS NOT NULL" +== 011 +-- truncate_limit: 100 +-- Ensure the IS_NOT_NULL qual is not ignored when columns are made nullable +-- by an outer join +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + FULL JOIN pred_tab t2 ON t1.a = t2.a + LEFT JOIN pred_tab t3 ON t2.a IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 FULL JOIN pred_tab t2 ON t1.a = t2.a LEFT JOIN pred..." +== 012 +-- truncate_limit: 100 +-- Ensure the IS_NULL qual is reduced to constant-FALSE, since a) it's on a NOT +-- NULL column, and b) its Var is not nullable by any outer joins +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON t1.a IS NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON t1.a IS NULL" +== 013 +-- truncate_limit: 100 +-- Ensure the IS_NULL qual is not reduced to constant-FALSE when the column is +-- nullable by an outer join +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON t1.a = 1 + LEFT JOIN pred_tab t3 ON t2.a IS NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON t1.a = 1 LEFT JOIN pred_ta..." +== 014 +-- truncate_limit: 100 +|-- +-- Tests for OR clauses in join clauses +|-- + +-- Ensure the OR clause is ignored when an OR branch is provably always true +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON t1.a IS NOT NULL OR t2.b = 1 +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON t1.a IS NOT NULL OR t2.b = 1" +== 015 +-- truncate_limit: 100 +-- Ensure the NullTest is not ignored when the column is nullable by an outer +-- join +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + FULL JOIN pred_tab t2 ON t1.a = t2.a + LEFT JOIN pred_tab t3 ON t2.a IS NOT NULL OR t2.b = 1 +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 FULL JOIN pred_tab t2 ON t1.a = t2.a LEFT JOIN pred..." +== 016 +-- truncate_limit: 100 +-- Ensure the OR clause is reduced to constant-FALSE when all OR branches are +-- provably false +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON (t1.a IS NULL OR t1.c IS NULL) +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON t1.a IS NULL OR t1.c IS NULL" +== 017 +-- truncate_limit: 100 +-- Ensure the OR clause is not reduced to constant-FALSE when a column is +-- made nullable from an outer join +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON t1.a = 1 + LEFT JOIN pred_tab t3 ON t2.a IS NULL OR t2.c IS NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON t1.a = 1 LEFT JOIN pred_ta..." +== 018 +-- truncate_limit: 100 +DROP TABLE pred_tab +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pred_tab" +== 019 +-- truncate_limit: 100 +-- Validate we handle IS NULL and IS NOT NULL quals correctly with inheritance +-- parents. +CREATE TABLE pred_parent (a int) +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pred_parent (a int)" +== 020 +-- truncate_limit: 100 +CREATE TABLE pred_child () INHERITS (pred_parent) +-- +TABLE: name="pred_child" schema="" table="pred_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pred_child () INHERITS (pred_parent)" +== 021 +-- truncate_limit: 100 +ALTER TABLE ONLY pred_parent ALTER a SET NOT NULL +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY pred_parent ALTER COLUMN a SET NOT NULL" +== 022 +-- truncate_limit: 100 +-- Ensure that the scan on pred_child contains the IS NOT NULL qual. +EXPLAIN (COSTS OFF) +SELECT * FROM pred_parent WHERE a IS NOT NULL +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_parent WHERE a IS NOT NULL" +== 023 +-- truncate_limit: 100 +-- Ensure we only scan pred_child and not pred_parent +EXPLAIN (COSTS OFF) +SELECT * FROM pred_parent WHERE a IS NULL +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_parent WHERE a IS NULL" +== 024 +-- truncate_limit: 100 +ALTER TABLE pred_parent ALTER a DROP NOT NULL +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pred_parent ALTER COLUMN a DROP NOT NULL" +== 025 +-- truncate_limit: 100 +ALTER TABLE pred_child ALTER a SET NOT NULL +-- +TABLE: name="pred_child" schema="" table="pred_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pred_child ALTER COLUMN a SET NOT NULL" +== 026 +-- truncate_limit: 100 +-- Ensure the IS NOT NULL qual is removed from the pred_child scan. +EXPLAIN (COSTS OFF) +SELECT * FROM pred_parent WHERE a IS NOT NULL +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_parent WHERE a IS NOT NULL" +== 027 +-- truncate_limit: 100 +-- Ensure we only scan pred_parent and not pred_child +EXPLAIN (COSTS OFF) +SELECT * FROM pred_parent WHERE a IS NULL +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_parent WHERE a IS NULL" +== 028 +-- truncate_limit: 100 +DROP TABLE pred_parent, pred_child +-- +TABLE: name="pred_parent" schema="" table="pred_parent" ctx=DDL +TABLE: name="pred_child" schema="" table="pred_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pred_parent, pred_child" +== 029 +-- truncate_limit: 100 +-- Validate we do not reduce a clone clause to a constant true or false +CREATE TABLE pred_tab (a int, b int) +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pred_tab (a int, b int)" +== 030 +-- truncate_limit: 100 +CREATE TABLE pred_tab_notnull (a int, b int NOT NULL) +-- +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pred_tab_notnull (a int, b int NOT NULL)" +== 031 +-- truncate_limit: 100 +INSERT INTO pred_tab VALUES (1, 1) +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pred_tab VALUES (1, 1)" +== 032 +-- truncate_limit: 100 +INSERT INTO pred_tab VALUES (2, 2) +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pred_tab VALUES (2, 2)" +== 033 +-- truncate_limit: 100 +INSERT INTO pred_tab_notnull VALUES (2, 2) +-- +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pred_tab_notnull VALUES (2, 2)" +== 034 +-- truncate_limit: 100 +INSERT INTO pred_tab_notnull VALUES (3, 3) +-- +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pred_tab_notnull VALUES (3, 3)" +== 035 +-- truncate_limit: 100 +ANALYZE pred_tab +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pred_tab" +== 036 +-- truncate_limit: 100 +ANALYZE pred_tab_notnull +-- +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pred_tab_notnull" +== 037 +-- truncate_limit: 100 +-- Ensure the IS_NOT_NULL qual is not reduced to constant true and removed +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON TRUE + LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN pred_tab t4 ON t3.b IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab_notnull" +ALIAS: "t4"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON true LEFT JOIN pred_tab_no..." +== 038 +-- truncate_limit: 100 +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON TRUE + LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN pred_tab t4 ON t3.b IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab_notnull" +ALIAS: "t4"="pred_tab" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON true LEFT JOIN pred_tab_notnull t3 ON t2.a = t..." +== 039 +-- truncate_limit: 100 +-- Ensure the IS_NULL qual is not reduced to constant false +EXPLAIN (COSTS OFF) +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON TRUE + LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN pred_tab t4 ON t3.b IS NULL AND t3.a IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab_notnull" +ALIAS: "t4"="pred_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON true LEFT JOIN pred_tab_no..." +== 040 +-- truncate_limit: 100 +SELECT * FROM pred_tab t1 + LEFT JOIN pred_tab t2 ON TRUE + LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN pred_tab t4 ON t3.b IS NULL AND t3.a IS NOT NULL +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=Select +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=Select +ALIAS: "t1"="pred_tab" +ALIAS: "t2"="pred_tab" +ALIAS: "t3"="pred_tab_notnull" +ALIAS: "t4"="pred_tab" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pred_tab t1 LEFT JOIN pred_tab t2 ON true LEFT JOIN pred_tab_notnull t3 ON t2.a = t..." +== 041 +-- truncate_limit: 100 +DROP TABLE pred_tab +-- +TABLE: name="pred_tab" schema="" table="pred_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pred_tab" +== 042 +-- truncate_limit: 100 +DROP TABLE pred_tab_notnull +-- +TABLE: name="pred_tab_notnull" schema="" table="pred_tab_notnull" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pred_tab_notnull" diff --git a/parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json b/parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json new file mode 100644 index 0000000..daef5f1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json @@ -0,0 +1,37 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/prepare.test b/parser/testdata/summary_truncate/postgres_regress/prepare.test new file mode 100644 index 0000000..63ca131 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/prepare.test @@ -0,0 +1,268 @@ +== 001 +-- truncate_limit: 100 +-- Regression tests for prepareable statements. We query the content +-- of the pg_prepared_statements view as prepared statements are +-- created and removed. + +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements" +== 002 +-- truncate_limit: 100 +PREPARE q1 AS SELECT 1 AS a +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q1 AS SELECT 1 AS a" +== 003 +-- truncate_limit: 100 +EXECUTE q1 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q1" +== 004 +-- truncate_limit: 100 +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements" +== 005 +-- truncate_limit: 100 +-- should fail +PREPARE q1 AS SELECT 2 +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q1 AS SELECT 2" +== 006 +-- truncate_limit: 100 +-- should succeed +DEALLOCATE q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q1" +== 007 +-- truncate_limit: 100 +PREPARE q1 AS SELECT 2 +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q1 AS SELECT 2" +== 008 +-- truncate_limit: 100 +EXECUTE q1 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q1" +== 009 +-- truncate_limit: 100 +PREPARE q2 AS SELECT 2 AS b +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q2 AS SELECT 2 AS b" +== 010 +-- truncate_limit: 100 +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements" +== 011 +-- truncate_limit: 100 +-- sql92 syntax +DEALLOCATE PREPARE q1 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q1" +== 012 +-- truncate_limit: 100 +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements" +== 013 +-- truncate_limit: 100 +DEALLOCATE PREPARE q2 +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q2" +== 014 +-- truncate_limit: 100 +-- the view should return the empty set again +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements" +== 015 +-- truncate_limit: 100 +-- parameterized queries +PREPARE q2(text) AS + SELECT datname, datistemplate, datallowconn + FROM pg_database WHERE datname = $1 +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FILTER: schema="" table="" column="datname" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q2(text) AS SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname = $1" +== 016 +-- truncate_limit: 100 +EXECUTE q2('postgres') +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q2('postgres')" +== 017 +-- truncate_limit: 100 +PREPARE q3(text, int, float, boolean, smallint) AS + SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR + ten = $3::bigint OR true = $4 OR odd = $5::int) + ORDER BY unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="string4" +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="ten" +FILTER: schema="" table="" column="odd" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q3(text, int, double precision, boolean, smallint) AS SELECT * FROM tenk1 WHERE string4 =..." +== 018 +-- truncate_limit: 100 +EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q3('AAAAxx', 5::smallint, (10.5)::double precision, false, 4::bigint)" +== 019 +-- truncate_limit: 100 +-- too few params +EXECUTE q3('bool') +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q3('bool')" +== 020 +-- truncate_limit: 100 +-- too many params +EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q3('bytea', 5::smallint, (10.5)::double precision, false, 4::bigint, true)" +== 021 +-- truncate_limit: 100 +-- wrong param types +EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea') +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q3(5::smallint, (10.5)::double precision, false, 4::bigint, 'bytea')" +== 022 +-- truncate_limit: 100 +-- invalid type +PREPARE q4(nonexistenttype) AS SELECT $1 +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q4(nonexistenttype) AS SELECT $1" +== 023 +-- truncate_limit: 100 +-- create table as execute +PREPARE q5(int, text) AS + SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 + ORDER BY unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="stringu1" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q5(int, text) AS SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 ORDER BY unique1" +== 024 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA') +-- +TABLE: name="q5_prep_results" schema="" table="q5_prep_results" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA')" +== 025 +-- truncate_limit: 100 +SELECT * FROM q5_prep_results +-- +TABLE: name="q5_prep_results" schema="" table="q5_prep_results" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM q5_prep_results" +== 026 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') + WITH NO DATA +-- +TABLE: name="q5_prep_nodata" schema="" table="q5_prep_nodata" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') WITH NO DATA" +== 027 +-- truncate_limit: 100 +SELECT * FROM q5_prep_nodata +-- +TABLE: name="q5_prep_nodata" schema="" table="q5_prep_nodata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM q5_prep_nodata" +== 028 +-- truncate_limit: 100 +-- unknown or unspecified parameter types: should succeed +PREPARE q6 AS + SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="stringu1" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q6 AS SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2" +== 029 +-- truncate_limit: 100 +PREPARE q7(unknown) AS + SELECT * FROM road WHERE thepath = $1 +-- +TABLE: name="road" schema="" table="road" ctx=Select +FILTER: schema="" table="" column="thepath" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q7(unknown) AS SELECT * FROM road WHERE thepath = $1" +== 030 +-- truncate_limit: 100 +-- DML statements +PREPARE q8 AS + UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DML +STMT: PrepareStmt +STMT: UpdateStmt +TRUNCATED: "PREPARE q8 AS UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1" +== 031 +-- truncate_limit: 100 +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements + ORDER BY name +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements ORDER BY name" +== 032 +-- truncate_limit: 100 +-- test DEALLOCATE ALL; +DEALLOCATE ALL +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ALL" +== 033 +-- truncate_limit: 100 +SELECT name, statement, parameter_types FROM pg_prepared_statements + ORDER BY name +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, statement, parameter_types FROM pg_prepared_statements ORDER BY name" diff --git a/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json b/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json new file mode 100644 index 0000000..449cbc1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json @@ -0,0 +1,87 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.test b/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.test new file mode 100644 index 0000000..a65c4d1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.test @@ -0,0 +1,605 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PREPARED TRANSACTIONS (two-phase commit) +|-- +-- We can't readily test persistence of prepared xacts within the +-- regression script framework, unfortunately. Note that a crash +-- isn't really needed ... stopping and starting the postmaster would +-- be enough, but we can't even do that here. + + +-- create a simple table that we'll use in the tests +CREATE TABLE pxtest1 (foobar VARCHAR(10)) +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pxtest1 (foobar varchar(10))" +== 002 +-- truncate_limit: 100 +INSERT INTO pxtest1 VALUES ('aaa') +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest1 VALUES ('aaa')" +== 003 +-- truncate_limit: 100 +-- Test PREPARE TRANSACTION +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 004 +-- truncate_limit: 100 +UPDATE pxtest1 SET foobar = 'bbb' WHERE foobar = 'aaa' +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pxtest1 SET foobar = 'bbb' WHERE foobar = 'aaa'" +== 005 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 006 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_foo1' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_foo1'" +== 007 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 008 +-- truncate_limit: 100 +-- Test pg_prepared_xacts system view +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 009 +-- truncate_limit: 100 +-- Test ROLLBACK PREPARED +ROLLBACK PREPARED 'regress_foo1' +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK PREPARED 'regress_foo1'" +== 010 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 011 +-- truncate_limit: 100 +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 012 +-- truncate_limit: 100 +-- Test COMMIT PREPARED +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 013 +-- truncate_limit: 100 +INSERT INTO pxtest1 VALUES ('ddd') +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest1 VALUES ('ddd')" +== 014 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 015 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_foo2' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_foo2'" +== 016 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 017 +-- truncate_limit: 100 +COMMIT PREPARED 'regress_foo2' +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT PREPARED 'regress_foo2'" +== 018 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 019 +-- truncate_limit: 100 +-- Test duplicate gids +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 020 +-- truncate_limit: 100 +UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd' +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd'" +== 021 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 022 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_foo3' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_foo3'" +== 023 +-- truncate_limit: 100 +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 024 +-- truncate_limit: 100 +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 025 +-- truncate_limit: 100 +INSERT INTO pxtest1 VALUES ('fff') +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest1 VALUES ('fff')" +== 026 +-- truncate_limit: 100 +-- This should fail, because the gid foo3 is already in use +PREPARE TRANSACTION 'regress_foo3' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_foo3'" +== 027 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 028 +-- truncate_limit: 100 +ROLLBACK PREPARED 'regress_foo3' +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK PREPARED 'regress_foo3'" +== 029 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 030 +-- truncate_limit: 100 +-- Test serialization failure (SSI) +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 031 +-- truncate_limit: 100 +UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd' +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd'" +== 032 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 033 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_foo4' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_foo4'" +== 034 +-- truncate_limit: 100 +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 035 +-- truncate_limit: 100 +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 036 +-- truncate_limit: 100 +SELECT * FROM pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest1" +== 037 +-- truncate_limit: 100 +-- This should fail, because the two transactions have a write-skew anomaly +INSERT INTO pxtest1 VALUES ('fff') +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest1 VALUES ('fff')" +== 038 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_foo5' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_foo5'" +== 039 +-- truncate_limit: 100 +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 040 +-- truncate_limit: 100 +ROLLBACK PREPARED 'regress_foo4' +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK PREPARED 'regress_foo4'" +== 041 +-- truncate_limit: 100 +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 042 +-- truncate_limit: 100 +-- Clean up +DROP TABLE pxtest1 +-- +TABLE: name="pxtest1" schema="" table="pxtest1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pxtest1" +== 043 +-- truncate_limit: 100 +-- Test detection of session-level and xact-level locks on same object +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 044 +-- truncate_limit: 100 +SELECT pg_advisory_lock(1) +-- +FUNCTION: name="pg_advisory_lock" function="pg_advisory_lock" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_advisory_lock(1)" +== 045 +-- truncate_limit: 100 +SELECT pg_advisory_xact_lock_shared(1) +-- +FUNCTION: name="pg_advisory_xact_lock_shared" function="pg_advisory_xact_lock_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_advisory_xact_lock_shared(1)" +== 046 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_foo6' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_foo6'" +== 047 +-- truncate_limit: 100 +-- fails + +-- Test subtransactions +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 048 +-- truncate_limit: 100 +CREATE TABLE pxtest2 (a int) +-- +TABLE: name="pxtest2" schema="" table="pxtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pxtest2 (a int)" +== 049 +-- truncate_limit: 100 +INSERT INTO pxtest2 VALUES (1) +-- +TABLE: name="pxtest2" schema="" table="pxtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest2 VALUES (1)" +== 050 +-- truncate_limit: 100 +SAVEPOINT a +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT a" +== 051 +-- truncate_limit: 100 +INSERT INTO pxtest2 VALUES (2) +-- +TABLE: name="pxtest2" schema="" table="pxtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest2 VALUES (2)" +== 052 +-- truncate_limit: 100 +ROLLBACK TO a +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT a" +== 053 +-- truncate_limit: 100 +SAVEPOINT b +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT b" +== 054 +-- truncate_limit: 100 +INSERT INTO pxtest2 VALUES (3) +-- +TABLE: name="pxtest2" schema="" table="pxtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest2 VALUES (3)" +== 055 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_sub1' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_sub1'" +== 056 +-- truncate_limit: 100 +CREATE TABLE pxtest3(fff int) +-- +TABLE: name="pxtest3" schema="" table="pxtest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pxtest3 (fff int)" +== 057 +-- truncate_limit: 100 +-- Test shared invalidation +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 058 +-- truncate_limit: 100 +DROP TABLE pxtest3 +-- +TABLE: name="pxtest3" schema="" table="pxtest3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pxtest3" +== 059 +-- truncate_limit: 100 +CREATE TABLE pxtest4 (a int) +-- +TABLE: name="pxtest4" schema="" table="pxtest4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pxtest4 (a int)" +== 060 +-- truncate_limit: 100 +INSERT INTO pxtest4 VALUES (1) +-- +TABLE: name="pxtest4" schema="" table="pxtest4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest4 VALUES (1)" +== 061 +-- truncate_limit: 100 +INSERT INTO pxtest4 VALUES (2) +-- +TABLE: name="pxtest4" schema="" table="pxtest4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pxtest4 VALUES (2)" +== 062 +-- truncate_limit: 100 +DECLARE foo CURSOR FOR SELECT * FROM pxtest4 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo CURSOR FOR SELECT * FROM pxtest4" +== 063 +-- truncate_limit: 100 +-- Fetch 1 tuple, keeping the cursor open + FETCH 1 FROM foo +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo" +== 064 +-- truncate_limit: 100 +PREPARE TRANSACTION 'regress_sub2' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'regress_sub2'" +== 065 +-- truncate_limit: 100 +-- No such cursor +FETCH 1 FROM foo +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo" +== 066 +-- truncate_limit: 100 +-- Table doesn't exist, the creation hasn't been committed yet +SELECT * FROM pxtest2 +-- +TABLE: name="pxtest2" schema="" table="pxtest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest2" +== 067 +-- truncate_limit: 100 +-- There should be two prepared transactions +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 068 +-- truncate_limit: 100 +-- pxtest3 should be locked because of the pending DROP +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 069 +-- truncate_limit: 100 +lock table pxtest3 in access share mode nowait +-- +TABLE: name="pxtest3" schema="" table="pxtest3" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE pxtest3 IN ACCESS SHARE MODE NOWAIT" +== 070 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 071 +-- truncate_limit: 100 +-- Disconnect, we will continue testing in a different backend + +-- There should still be two prepared transactions +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 072 +-- truncate_limit: 100 +-- pxtest3 should still be locked because of the pending DROP +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 073 +-- truncate_limit: 100 +lock table pxtest3 in access share mode nowait +-- +TABLE: name="pxtest3" schema="" table="pxtest3" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE pxtest3 IN ACCESS SHARE MODE NOWAIT" +== 074 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 075 +-- truncate_limit: 100 +-- Commit table creation +COMMIT PREPARED 'regress_sub1' +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT PREPARED 'regress_sub1'" +== 076 +-- truncate_limit: 100 +SELECT * FROM pxtest2 +-- +TABLE: name="pxtest2" schema="" table="pxtest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest2" +== 077 +-- truncate_limit: 100 +-- There should be one prepared transaction +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 078 +-- truncate_limit: 100 +-- Commit table drop +COMMIT PREPARED 'regress_sub2' +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT PREPARED 'regress_sub2'" +== 079 +-- truncate_limit: 100 +SELECT * FROM pxtest3 +-- +TABLE: name="pxtest3" schema="" table="pxtest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pxtest3" +== 080 +-- truncate_limit: 100 +-- There should be no prepared transactions +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FILTER: schema="" table="" column="gid" +STMT: SelectStmt +TRUNCATED: "SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid" +== 081 +-- truncate_limit: 100 +-- Clean up +DROP TABLE pxtest2 +-- +TABLE: name="pxtest2" schema="" table="pxtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pxtest2" +== 082 +-- truncate_limit: 100 +DROP TABLE pxtest3 +-- +TABLE: name="pxtest3" schema="" table="pxtest3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pxtest3" +== 083 +-- truncate_limit: 100 +-- will still be there if prepared xacts are disabled +DROP TABLE pxtest4 +-- +TABLE: name="pxtest4" schema="" table="pxtest4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pxtest4" diff --git a/parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json b/parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json new file mode 100644 index 0000000..302fef8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json @@ -0,0 +1,335 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/privileges.test b/parser/testdata/summary_truncate/postgres_regress/privileges.test new file mode 100644 index 0000000..1dba999 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/privileges.test @@ -0,0 +1,2542 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test access privileges +|-- + +-- Clean up in case a prior regression run failed + +-- Suppress NOTICE messages when users/groups don't exist +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 002 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_group1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_group1" +== 003 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_group2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_group2" +== 004 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_user1" +== 005 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_user2" +== 006 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_user3" +== 007 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_user4 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_user4" +== 008 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_user5 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_user5" +== 009 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_user6 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_user6" +== 010 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_priv_user7 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_priv_user7" +== 011 +-- truncate_limit: 100 +SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid +-- +TABLE: name="pg_largeobject_metadata" schema="" table="pg_largeobject_metadata" ctx=Select +FUNCTION: name="lo_unlink" function="lo_unlink" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid" +== 012 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 013 +-- truncate_limit: 100 +-- test proper begins here + +CREATE USER regress_priv_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user1" +== 014 +-- truncate_limit: 100 +CREATE USER regress_priv_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user2" +== 015 +-- truncate_limit: 100 +CREATE USER regress_priv_user3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user3" +== 016 +-- truncate_limit: 100 +CREATE USER regress_priv_user4 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user4" +== 017 +-- truncate_limit: 100 +CREATE USER regress_priv_user5 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user5" +== 018 +-- truncate_limit: 100 +CREATE USER regress_priv_user5 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user5" +== 019 +-- truncate_limit: 100 +-- duplicate +CREATE USER regress_priv_user6 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user6" +== 020 +-- truncate_limit: 100 +CREATE USER regress_priv_user7 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user7" +== 021 +-- truncate_limit: 100 +CREATE USER regress_priv_user8 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user8" +== 022 +-- truncate_limit: 100 +CREATE USER regress_priv_user9 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user9" +== 023 +-- truncate_limit: 100 +CREATE USER regress_priv_user10 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user10" +== 024 +-- truncate_limit: 100 +CREATE ROLE regress_priv_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_priv_role" +== 025 +-- truncate_limit: 100 +-- circular ADMIN OPTION grants should be disallowed +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION" +== 026 +-- truncate_limit: 100 +GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION GRANTED BY regress_priv_user2 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION GRANTED BY regress_priv_user2" +== 027 +-- truncate_limit: 100 +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION GRANTED BY regress_priv_user3 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION GRANTED BY regress_priv_user3" +== 028 +-- truncate_limit: 100 +-- need CASCADE to revoke grant or admin option if dependent grants exist +REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2" +== 029 +-- truncate_limit: 100 +-- fail +REVOKE regress_priv_user1 FROM regress_priv_user2 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE regress_priv_user1 FROM regress_priv_user2" +== 030 +-- truncate_limit: 100 +-- fail +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +STMT: SelectStmt +TRUNCATED: "SELECT member::regrole, admin_option FROM pg_auth_members WHERE ..." +== 031 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 032 +-- truncate_limit: 100 +REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2 CASCADE +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2 CASCADE" +== 033 +-- truncate_limit: 100 +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +STMT: SelectStmt +TRUNCATED: "SELECT member::regrole, admin_option FROM pg_auth_members WHERE ..." +== 034 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 035 +-- truncate_limit: 100 +REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE" +== 036 +-- truncate_limit: 100 +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +STMT: SelectStmt +TRUNCATED: "SELECT member::regrole, admin_option FROM pg_auth_members WHERE ..." +== 037 +-- truncate_limit: 100 +-- inferred grantor must be a role with ADMIN OPTION +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION" +== 038 +-- truncate_limit: 100 +GRANT regress_priv_user2 TO regress_priv_user3 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user2 TO regress_priv_user3" +== 039 +-- truncate_limit: 100 +SET ROLE regress_priv_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_priv_user3" +== 040 +-- truncate_limit: 100 +GRANT regress_priv_user1 TO regress_priv_user4 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user4" +== 041 +-- truncate_limit: 100 +SELECT grantor::regrole FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole and member = 'regress_priv_user4'::regrole +-- +TABLE: name="pg_auth_members" schema="" table="pg_auth_members" ctx=Select +FILTER: schema="" table="" column="roleid" +FILTER: schema="" table="" column="member" +STMT: SelectStmt +TRUNCATED: "SELECT grantor::regrole FROM pg_auth_members WHERE ..." +== 042 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 043 +-- truncate_limit: 100 +REVOKE regress_priv_user2 FROM regress_priv_user3 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE regress_priv_user2 FROM regress_priv_user3" +== 044 +-- truncate_limit: 100 +REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE" +== 045 +-- truncate_limit: 100 +-- test GRANTED BY with DROP OWNED and REASSIGN OWNED +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION" +== 046 +-- truncate_limit: 100 +GRANT regress_priv_user1 TO regress_priv_user3 GRANTED BY regress_priv_user2 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user3 GRANTED BY regress_priv_user2" +== 047 +-- truncate_limit: 100 +DROP ROLE regress_priv_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user2" +== 048 +-- truncate_limit: 100 +-- fail, dependency +REASSIGN OWNED BY regress_priv_user2 TO regress_priv_user4 +-- +STMT: ReassignOwnedStmt +TRUNCATED: "REASSIGN OWNED BY regress_priv_user2 TO regress_priv_user4" +== 049 +-- truncate_limit: 100 +DROP ROLE regress_priv_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user2" +== 050 +-- truncate_limit: 100 +-- still fail, REASSIGN OWNED doesn't help +DROP OWNED BY regress_priv_user2 +-- +STMT: DropOwnedStmt +TRUNCATED: "DROP OWNED BY regress_priv_user2" +== 051 +-- truncate_limit: 100 +DROP ROLE regress_priv_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user2" +== 052 +-- truncate_limit: 100 +-- ok now, DROP OWNED does the job + +-- test that removing granted role or grantee role removes dependency +GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION" +== 053 +-- truncate_limit: 100 +GRANT regress_priv_user1 TO regress_priv_user4 GRANTED BY regress_priv_user3 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user4 GRANTED BY regress_priv_user3" +== 054 +-- truncate_limit: 100 +DROP ROLE regress_priv_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user3" +== 055 +-- truncate_limit: 100 +-- should fail, dependency +DROP ROLE regress_priv_user4 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user4" +== 056 +-- truncate_limit: 100 +-- ok +DROP ROLE regress_priv_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user3" +== 057 +-- truncate_limit: 100 +-- ok now +GRANT regress_priv_user1 TO regress_priv_user5 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user5 WITH ADMIN OPTION" +== 058 +-- truncate_limit: 100 +GRANT regress_priv_user1 TO regress_priv_user6 GRANTED BY regress_priv_user5 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user1 TO regress_priv_user6 GRANTED BY regress_priv_user5" +== 059 +-- truncate_limit: 100 +DROP ROLE regress_priv_user5 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user5" +== 060 +-- truncate_limit: 100 +-- should fail, dependency +DROP ROLE regress_priv_user1, regress_priv_user5 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user1, regress_priv_user5" +== 061 +-- truncate_limit: 100 +-- ok, despite order + +-- recreate the roles we just dropped +CREATE USER regress_priv_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user1" +== 062 +-- truncate_limit: 100 +CREATE USER regress_priv_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user2" +== 063 +-- truncate_limit: 100 +CREATE USER regress_priv_user3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user3" +== 064 +-- truncate_limit: 100 +CREATE USER regress_priv_user4 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user4" +== 065 +-- truncate_limit: 100 +CREATE USER regress_priv_user5 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_priv_user5" +== 066 +-- truncate_limit: 100 +GRANT pg_read_all_data TO regress_priv_user6 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_read_all_data TO regress_priv_user6" +== 067 +-- truncate_limit: 100 +GRANT pg_write_all_data TO regress_priv_user7 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_write_all_data TO regress_priv_user7" +== 068 +-- truncate_limit: 100 +GRANT pg_read_all_settings TO regress_priv_user8 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_read_all_settings TO regress_priv_user8 WITH ADMIN OPTION" +== 069 +-- truncate_limit: 100 +GRANT regress_priv_user9 TO regress_priv_user8 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user9 TO regress_priv_user8" +== 070 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user8" +== 071 +-- truncate_limit: 100 +GRANT pg_read_all_settings TO regress_priv_user9 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_read_all_settings TO regress_priv_user9 WITH ADMIN OPTION" +== 072 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user9 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user9" +== 073 +-- truncate_limit: 100 +GRANT pg_read_all_settings TO regress_priv_user10 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_read_all_settings TO regress_priv_user10" +== 074 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user8" +== 075 +-- truncate_limit: 100 +REVOKE pg_read_all_settings FROM regress_priv_user10 GRANTED BY regress_priv_user9 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE pg_read_all_settings FROM regress_priv_user10 GRANTED BY regress_priv_user9" +== 076 +-- truncate_limit: 100 +REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user9 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user9" +== 077 +-- truncate_limit: 100 +REVOKE pg_read_all_settings FROM regress_priv_user9 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE pg_read_all_settings FROM regress_priv_user9" +== 078 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 079 +-- truncate_limit: 100 +REVOKE regress_priv_user9 FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE regress_priv_user9 FROM regress_priv_user8" +== 080 +-- truncate_limit: 100 +REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user8" +== 081 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user8" +== 082 +-- truncate_limit: 100 +SET ROLE pg_read_all_settings +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO pg_read_all_settings" +== 083 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 084 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 085 +-- truncate_limit: 100 +REVOKE SET OPTION FOR pg_read_all_settings FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE SET OPTION FOR pg_read_all_settings FROM regress_priv_user8" +== 086 +-- truncate_limit: 100 +GRANT pg_read_all_stats TO regress_priv_user8 WITH SET FALSE +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT pg_read_all_stats TO regress_priv_user8 WITH SET FALSE" +== 087 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user8" +== 088 +-- truncate_limit: 100 +SET ROLE pg_read_all_settings +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO pg_read_all_settings" +== 089 +-- truncate_limit: 100 +-- fail, no SET option any more +SET ROLE pg_read_all_stats +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO pg_read_all_stats" +== 090 +-- truncate_limit: 100 +-- fail, granted without SET option +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 091 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 092 +-- truncate_limit: 100 +-- test interaction of SET SESSION AUTHORIZATION and SET ROLE, +-- as well as propagation of these settings to parallel workers +GRANT regress_priv_user9 TO regress_priv_user8 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_user9 TO regress_priv_user8" +== 093 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user8 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user8" +== 094 +-- truncate_limit: 100 +SET ROLE regress_priv_user9 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_priv_user9" +== 095 +-- truncate_limit: 100 +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 0" +== 096 +-- truncate_limit: 100 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_role, current_user, current_setting('role') AS role" +== 097 +-- truncate_limit: 100 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 1" +== 098 +-- truncate_limit: 100 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_role, current_user, current_setting('role') AS role" +== 099 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 100 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user10 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user10" +== 101 +-- truncate_limit: 100 +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 0" +== 102 +-- truncate_limit: 100 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_role, current_user, current_setting('role') AS role" +== 103 +-- truncate_limit: 100 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 1" +== 104 +-- truncate_limit: 100 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_role, current_user, current_setting('role') AS role" +== 105 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 106 +-- truncate_limit: 100 +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 0" +== 107 +-- truncate_limit: 100 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_role, current_user, current_setting('role') AS role" +== 108 +-- truncate_limit: 100 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 1" +== 109 +-- truncate_limit: 100 +SELECT session_user, current_role, current_user, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_role, current_user, current_setting('role') AS role" +== 110 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 111 +-- truncate_limit: 100 +-- session_user at this point is installation-dependent +SET debug_parallel_query = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 0" +== 112 +-- truncate_limit: 100 +SELECT session_user = current_role as c_r_ok, session_user = current_user as c_u_ok, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 113 +-- truncate_limit: 100 +SET debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 1" +== 114 +-- truncate_limit: 100 +SELECT session_user = current_role as c_r_ok, session_user = current_user as c_u_ok, current_setting('role') as role +-- +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 115 +-- truncate_limit: 100 +RESET debug_parallel_query +-- +STMT: VariableSetStmt +TRUNCATED: "RESET debug_parallel_query" +== 116 +-- truncate_limit: 100 +REVOKE pg_read_all_settings FROM regress_priv_user8 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE pg_read_all_settings FROM regress_priv_user8" +== 117 +-- truncate_limit: 100 +DROP USER regress_priv_user10 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user10" +== 118 +-- truncate_limit: 100 +DROP USER regress_priv_user9 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user9" +== 119 +-- truncate_limit: 100 +DROP USER regress_priv_user8 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_user8" +== 120 +-- truncate_limit: 100 +CREATE GROUP regress_priv_group1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE GROUP regress_priv_group1" +== 121 +-- truncate_limit: 100 +CREATE GROUP regress_priv_group2 WITH ADMIN regress_priv_user1 USER regress_priv_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE GROUP regress_priv_group2 WITH ADMIN regress_priv_user1 ROLE regress_priv_user2" +== 122 +-- truncate_limit: 100 +ALTER GROUP regress_priv_group1 ADD USER regress_priv_user4 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER GROUP regress_priv_group1 ADD USER regress_priv_user4" +== 123 +-- truncate_limit: 100 +GRANT regress_priv_group2 TO regress_priv_user2 GRANTED BY regress_priv_user1 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_group2 TO regress_priv_user2 GRANTED BY regress_priv_user1" +== 124 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user3" +== 125 +-- truncate_limit: 100 +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2" +== 126 +-- truncate_limit: 100 +-- fail +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2" +== 127 +-- truncate_limit: 100 +-- fail +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 128 +-- truncate_limit: 100 +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2" +== 129 +-- truncate_limit: 100 +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2" +== 130 +-- truncate_limit: 100 +-- duplicate +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2" +== 131 +-- truncate_limit: 100 +ALTER USER regress_priv_user2 PASSWORD 'verysecret' +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_priv_user2 WITH PASSWORD 'verysecret'" +== 132 +-- truncate_limit: 100 +-- not permitted +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 133 +-- truncate_limit: 100 +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2 +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2" +== 134 +-- truncate_limit: 100 +REVOKE ADMIN OPTION FOR regress_priv_group2 FROM regress_priv_user1 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR regress_priv_group2 FROM regress_priv_user1" +== 135 +-- truncate_limit: 100 +GRANT regress_priv_group2 TO regress_priv_user4 WITH ADMIN OPTION +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_group2 TO regress_priv_user4 WITH ADMIN OPTION" +== 136 +-- truncate_limit: 100 +-- prepare non-leakproof function for later +CREATE FUNCTION leak(integer,integer) RETURNS boolean + AS 'int4lt' + LANGUAGE internal IMMUTABLE STRICT +-- +FUNCTION: name="leak" function="leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION leak(int, int) RETURNS boolean AS $$int4lt$$ LANGUAGE internal IMMUTABLE RETURNS ..." +== 137 +-- truncate_limit: 100 +-- but deliberately not LEAKPROOF +ALTER FUNCTION leak(integer,integer) OWNER TO regress_priv_user1 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER FUNCTION leak(int, int) OWNER TO regress_priv_user1" +== 138 +-- truncate_limit: 100 +-- test owner privileges + +GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY regress_priv_role +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY regress_priv_role" +== 139 +-- truncate_limit: 100 +-- error, doesn't have ADMIN OPTION +GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY CURRENT_ROLE +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY CURRENT_ROLE" +== 140 +-- truncate_limit: 100 +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY foo +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY foo" +== 141 +-- truncate_limit: 100 +-- error +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY regress_priv_user2 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY regress_priv_user2" +== 142 +-- truncate_limit: 100 +-- warning, noop +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_USER +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_USER" +== 143 +-- truncate_limit: 100 +REVOKE regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_ROLE +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_ROLE" +== 144 +-- truncate_limit: 100 +DROP ROLE regress_priv_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_priv_role" +== 145 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 146 +-- truncate_limit: 100 +SELECT session_user, current_user +-- +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_user" +== 147 +-- truncate_limit: 100 +CREATE TABLE atest1 ( a int, b text ) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atest1 (a int, b text)" +== 148 +-- truncate_limit: 100 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1" +== 149 +-- truncate_limit: 100 +INSERT INTO atest1 VALUES (1, 'one') +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest1 VALUES (1, 'one')" +== 150 +-- truncate_limit: 100 +DELETE FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atest1" +== 151 +-- truncate_limit: 100 +UPDATE atest1 SET a = 1 WHERE b = 'blech' +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atest1 SET a = 1 WHERE b = 'blech'" +== 152 +-- truncate_limit: 100 +TRUNCATE atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE atest1" +== 153 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 154 +-- truncate_limit: 100 +LOCK atest1 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE atest1" +== 155 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 156 +-- truncate_limit: 100 +REVOKE ALL ON atest1 FROM PUBLIC +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON atest1 FROM public" +== 157 +-- truncate_limit: 100 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1" +== 158 +-- truncate_limit: 100 +GRANT ALL ON atest1 TO regress_priv_user2 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON atest1 TO regress_priv_user2" +== 159 +-- truncate_limit: 100 +GRANT SELECT ON atest1 TO regress_priv_user3, regress_priv_user4 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON atest1 TO regress_priv_user3, regress_priv_user4" +== 160 +-- truncate_limit: 100 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1" +== 161 +-- truncate_limit: 100 +CREATE TABLE atest2 (col1 varchar(10), col2 boolean) +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atest2 (col1 varchar(10), col2 boolean)" +== 162 +-- truncate_limit: 100 +GRANT SELECT ON atest2 TO regress_priv_user2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON atest2 TO regress_priv_user2" +== 163 +-- truncate_limit: 100 +GRANT UPDATE ON atest2 TO regress_priv_user3 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON atest2 TO regress_priv_user3" +== 164 +-- truncate_limit: 100 +GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER" +== 165 +-- truncate_limit: 100 +GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT truncate ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE" +== 166 +-- truncate_limit: 100 +GRANT TRUNCATE ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT truncate ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5" +== 167 +-- truncate_limit: 100 +-- error + + +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user2" +== 168 +-- truncate_limit: 100 +SELECT session_user, current_user +-- +STMT: SelectStmt +TRUNCATED: "SELECT session_user, current_user" +== 169 +-- truncate_limit: 100 +-- try various combinations of queries on atest1 and atest2 + +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1" +== 170 +-- truncate_limit: 100 +-- ok +SELECT * FROM atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest2" +== 171 +-- truncate_limit: 100 +-- ok +INSERT INTO atest1 VALUES (2, 'two') +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest1 VALUES (2, 'two')" +== 172 +-- truncate_limit: 100 +-- ok +INSERT INTO atest2 VALUES ('foo', true) +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest2 VALUES ('foo', true)" +== 173 +-- truncate_limit: 100 +-- fail +INSERT INTO atest1 SELECT 1, b FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest1 SELECT 1, b FROM atest1" +== 174 +-- truncate_limit: 100 +-- ok +UPDATE atest1 SET a = 1 WHERE a = 2 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atest1 SET a = 1 WHERE a = 2" +== 175 +-- truncate_limit: 100 +-- ok +UPDATE atest2 SET col2 = NOT col2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atest2 SET col2 = NOT col2" +== 176 +-- truncate_limit: 100 +-- fail +SELECT * FROM atest1 FOR UPDATE +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1 FOR UPDATE" +== 177 +-- truncate_limit: 100 +-- ok +SELECT * FROM atest2 FOR UPDATE +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest2 FOR UPDATE" +== 178 +-- truncate_limit: 100 +-- fail +DELETE FROM atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atest2" +== 179 +-- truncate_limit: 100 +-- fail +TRUNCATE atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE atest2" +== 180 +-- truncate_limit: 100 +-- fail +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 181 +-- truncate_limit: 100 +LOCK atest2 IN ACCESS EXCLUSIVE MODE +-- +TABLE: name="atest2" schema="" table="atest2" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE atest2" +== 182 +-- truncate_limit: 100 +-- fail +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 183 +-- truncate_limit: 100 +COPY atest2 FROM stdin +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY atest2 FROM STDIN" +== 184 +-- truncate_limit: 100 +-- fail +GRANT ALL ON atest1 TO PUBLIC +-- +TABLE: name="atest1" schema="" table="atest1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON atest1 TO public" +== 185 +-- truncate_limit: 100 +-- fail + +-- checks in subquery, both ok +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest2" schema="" table="atest2" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1 WHERE b IN (SELECT col1 FROM atest2)" +== 186 +-- truncate_limit: 100 +SELECT * FROM atest1 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1" +== 187 +-- truncate_limit: 100 +-- ok + + +-- test leaky-function protections in selfuncs + +-- regress_priv_user1 will own a table and provide views for it. +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 188 +-- truncate_limit: 100 +CREATE TABLE atest12 as + SELECT x AS a, 10001 - x AS b FROM generate_series(1,10000) x +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE atest12 AS SELECT x AS a, 10001 - x AS b FROM generate_series(1, 10000) x" +== 189 +-- truncate_limit: 100 +CREATE INDEX ON atest12 (a) +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON atest12 USING btree (a)" +== 190 +-- truncate_limit: 100 +CREATE INDEX ON atest12 (abs(a)) +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +FUNCTION: name="abs" function="abs" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON atest12 USING btree (abs(a))" +== 191 +-- truncate_limit: 100 +-- results below depend on having quite accurate stats for atest12, so... +ALTER TABLE atest12 SET (autovacuum_enabled = off) +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE atest12 SET (autovacuum_enabled=off)" +== 192 +-- truncate_limit: 100 +SET default_statistics_target = 10000 +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_statistics_target TO 10000" +== 193 +-- truncate_limit: 100 +VACUUM ANALYZE atest12 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) atest12" +== 194 +-- truncate_limit: 100 +RESET default_statistics_target +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_statistics_target" +== 195 +-- truncate_limit: 100 +CREATE OPERATOR <<< (procedure = leak, leftarg = integer, rightarg = integer, + restrict = scalarltsel) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR <<< (procedure = leak, leftarg = int, rightarg = int, restrict = scalarltsel)" +== 196 +-- truncate_limit: 100 +-- views with leaky operator +CREATE VIEW atest12v AS + SELECT * FROM atest12 WHERE b <<< 5 +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=DDL +TABLE: name="atest12" schema="" table="atest12" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW atest12v AS SELECT * FROM atest12 WHERE b <<< 5" +== 197 +-- truncate_limit: 100 +CREATE VIEW atest12sbv WITH (security_barrier=true) AS + SELECT * FROM atest12 WHERE b <<< 5 +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=DDL +TABLE: name="atest12" schema="" table="atest12" ctx=Select +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW atest12sbv WITH (security_barrier=true) AS SELECT * FROM atest12 WHERE b <<< 5" +== 198 +-- truncate_limit: 100 +-- This plan should use nestloop, knowing that few rows will be selected. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b" +== 199 +-- truncate_limit: 100 +-- And this one. +EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=Select +TABLE: name="atest12" schema="" table="atest12" ctx=Select +ALIAS: "x"="atest12" +ALIAS: "y"="atest12" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y WHERE x.a = y.b AND abs(y.a) <<< 5" +== 200 +-- truncate_limit: 100 +-- This should also be a nestloop, but the security barrier forces the inner +-- scan to be materialized +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +ALIAS: "x"="atest12sbv" +ALIAS: "y"="atest12sbv" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b" +== 201 +-- truncate_limit: 100 +-- Check if regress_priv_user2 can break security. +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user2" +== 202 +-- truncate_limit: 100 +CREATE FUNCTION leak2(integer,integer) RETURNS boolean + AS $$begin raise notice 'leak % %', $1, $2; return $1 > $2; end$$ + LANGUAGE plpgsql immutable +-- +FUNCTION: name="leak2" function="leak2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION leak2(int, int) RETURNS boolean AS $$begin raise notice 'leak % %', $1, $2; retur..." +== 203 +-- truncate_limit: 100 +CREATE OPERATOR >>> (procedure = leak2, leftarg = integer, rightarg = integer, + restrict = scalargtsel) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR >>> (procedure = leak2, leftarg = int, rightarg = int, restrict = scalargtsel)" +== 204 +-- truncate_limit: 100 +-- These should not show any "leak" notices before failing. +EXPLAIN (COSTS OFF) SELECT * FROM atest12 WHERE a >>> 0 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12 WHERE a >>> 0" +== 205 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM atest12v WHERE a >>> 0 +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12v WHERE a >>> 0" +== 206 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv WHERE a >>> 0 +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv WHERE a >>> 0" +== 207 +-- truncate_limit: 100 +-- Now regress_priv_user1 grants access to regress_priv_user2 via the views. +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 208 +-- truncate_limit: 100 +GRANT SELECT ON atest12v TO PUBLIC +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON atest12v TO public" +== 209 +-- truncate_limit: 100 +GRANT SELECT ON atest12sbv TO PUBLIC +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON atest12sbv TO public" +== 210 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user2" +== 211 +-- truncate_limit: 100 +-- These plans should continue to use a nestloop, since they execute with the +-- privileges of the view owner. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b" +== 212 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +ALIAS: "x"="atest12sbv" +ALIAS: "y"="atest12sbv" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b" +== 213 +-- truncate_limit: 100 +-- A non-security barrier view does not guard against information leakage. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b AND abs(y.a) <<< 5" +== 214 +-- truncate_limit: 100 +-- But a security barrier view isolates the leaky operator. +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +TABLE: name="atest12sbv" schema="" table="atest12sbv" ctx=Select +ALIAS: "x"="atest12sbv" +ALIAS: "y"="atest12sbv" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b AND abs(y.a) <<< 5" +== 215 +-- truncate_limit: 100 +-- Now regress_priv_user1 grants sufficient access to regress_priv_user2. +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 216 +-- truncate_limit: 100 +GRANT SELECT (a, b) ON atest12 TO PUBLIC +-- +TABLE: name="atest12" schema="" table="atest12" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (a, b) ON atest12 TO public" +== 217 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user2" +== 218 +-- truncate_limit: 100 +-- regress_priv_user2 should continue to get a good row estimate. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b +-- +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +TABLE: name="atest12v" schema="" table="atest12v" ctx=Select +ALIAS: "x"="atest12v" +ALIAS: "y"="atest12v" +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b" +== 219 +-- truncate_limit: 100 +-- But not for this, due to lack of table-wide permissions needed +-- to make use of the expression index's statistics. +EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y + WHERE x.a = y.b and abs(y.a) <<< 5 +-- +TABLE: name="atest12" schema="" table="atest12" ctx=Select +TABLE: name="atest12" schema="" table="atest12" ctx=Select +ALIAS: "x"="atest12" +ALIAS: "y"="atest12" +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="b" +FILTER: schema="" table="y" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y WHERE x.a = y.b AND abs(y.a) <<< 5" +== 220 +-- truncate_limit: 100 +-- clean up (regress_priv_user1's objects are all dropped later) +DROP FUNCTION leak2(integer, integer) CASCADE +-- +FUNCTION: name="leak2" function="leak2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION leak2(int, int) CASCADE" +== 221 +-- truncate_limit: 100 +-- groups + +SET SESSION AUTHORIZATION regress_priv_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user3" +== 222 +-- truncate_limit: 100 +CREATE TABLE atest3 (one int, two int, three int) +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atest3 (one int, two int, three int)" +== 223 +-- truncate_limit: 100 +GRANT DELETE ON atest3 TO GROUP regress_priv_group2 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT delete ON atest3 TO regress_priv_group2" +== 224 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 225 +-- truncate_limit: 100 +SELECT * FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest3" +== 226 +-- truncate_limit: 100 +-- fail +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atest3" +== 227 +-- truncate_limit: 100 +-- ok + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 228 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 229 +-- truncate_limit: 100 +ALTER ROLE regress_priv_user1 NOINHERIT +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_priv_user1 WITH NOINHERIT" +== 230 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 231 +-- truncate_limit: 100 +SAVEPOINT s1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT s1" +== 232 +-- truncate_limit: 100 +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atest3" +== 233 +-- truncate_limit: 100 +-- ok because grant-level option is unchanged +ROLLBACK TO s1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT s1" +== 234 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 235 +-- truncate_limit: 100 +GRANT regress_priv_group2 TO regress_priv_user1 WITH INHERIT FALSE +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_priv_group2 TO regress_priv_user1 WITH INHERIT FALSE" +== 236 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 237 +-- truncate_limit: 100 +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atest3" +== 238 +-- truncate_limit: 100 +-- fail +ROLLBACK TO s1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT s1" +== 239 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 240 +-- truncate_limit: 100 +REVOKE INHERIT OPTION FOR regress_priv_group2 FROM regress_priv_user1 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE INHERIT OPTION FOR regress_priv_group2 FROM regress_priv_user1" +== 241 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 242 +-- truncate_limit: 100 +DELETE FROM atest3 +-- +TABLE: name="atest3" schema="" table="atest3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM atest3" +== 243 +-- truncate_limit: 100 +-- also fail +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 244 +-- truncate_limit: 100 +-- views + +SET SESSION AUTHORIZATION regress_priv_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user3" +== 245 +-- truncate_limit: 100 +CREATE VIEW atestv1 AS SELECT * FROM atest1 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=DDL +TABLE: name="atest1" schema="" table="atest1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW atestv1 AS SELECT * FROM atest1" +== 246 +-- truncate_limit: 100 +-- ok +/* The next *should* fail, but it's not implemented that way yet. */ +CREATE VIEW atestv2 AS SELECT * FROM atest2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=DDL +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW atestv2 AS SELECT * FROM atest2" +== 247 +-- truncate_limit: 100 +CREATE VIEW atestv3 AS SELECT * FROM atest3 +-- +TABLE: name="atestv3" schema="" table="atestv3" ctx=DDL +TABLE: name="atest3" schema="" table="atest3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW atestv3 AS SELECT * FROM atest3" +== 248 +-- truncate_limit: 100 +-- ok +/* Empty view is a corner case that failed in 9.2. */ +CREATE VIEW atestv0 AS SELECT 0 as x WHERE false +-- +TABLE: name="atestv0" schema="" table="atestv0" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW atestv0 AS SELECT 0 AS x WHERE false" +== 249 +-- truncate_limit: 100 +-- ok + +SELECT * FROM atestv1 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv1" +== 250 +-- truncate_limit: 100 +-- ok +SELECT * FROM atestv2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv2" +== 251 +-- truncate_limit: 100 +-- fail +GRANT SELECT ON atestv1, atestv3 TO regress_priv_user4 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=DDL +TABLE: name="atestv3" schema="" table="atestv3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON atestv1, atestv3 TO regress_priv_user4" +== 252 +-- truncate_limit: 100 +GRANT SELECT ON atestv2 TO regress_priv_user2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON atestv2 TO regress_priv_user2" +== 253 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user4" +== 254 +-- truncate_limit: 100 +SELECT * FROM atestv1 +-- +TABLE: name="atestv1" schema="" table="atestv1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv1" +== 255 +-- truncate_limit: 100 +-- ok +SELECT * FROM atestv2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv2" +== 256 +-- truncate_limit: 100 +-- fail +SELECT * FROM atestv3 +-- +TABLE: name="atestv3" schema="" table="atestv3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv3" +== 257 +-- truncate_limit: 100 +-- ok +SELECT * FROM atestv0 +-- +TABLE: name="atestv0" schema="" table="atestv0" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv0" +== 258 +-- truncate_limit: 100 +-- fail + +-- Appendrels excluded by constraints failed to check permissions in 8.4-9.2. +select * from + ((select a.q1 as x from int8_tbl a offset 0) + union all + (select b.q2 as x from int8_tbl b offset 0)) ss +where false +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ((SELECT ... FROM int8_tbl a OFFSET 0) UNION ALL (SELECT ... FROM int8_tbl b OFFSET..." +== 259 +-- truncate_limit: 100 +set constraint_exclusion = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO ON" +== 260 +-- truncate_limit: 100 +select * from + ((select a.q1 as x, random() from int8_tbl a where q1 > 0) + union all + (select b.q2 as x, random() from int8_tbl b where q2 > 0)) ss +where x < 0 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM int8_tbl a WHERE ... UNION ALL SELECT ... FROM int8_tbl b WHERE ....." +== 261 +-- truncate_limit: 100 +reset constraint_exclusion +-- +STMT: VariableSetStmt +TRUNCATED: "RESET constraint_exclusion" +== 262 +-- truncate_limit: 100 +CREATE VIEW atestv4 AS SELECT * FROM atestv3 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=DDL +TABLE: name="atestv3" schema="" table="atestv3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW atestv4 AS SELECT * FROM atestv3" +== 263 +-- truncate_limit: 100 +-- nested view +SELECT * FROM atestv4 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv4" +== 264 +-- truncate_limit: 100 +-- ok +GRANT SELECT ON atestv4 TO regress_priv_user2 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON atestv4 TO regress_priv_user2" +== 265 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user2" +== 266 +-- truncate_limit: 100 +-- Two complex cases: + +SELECT * FROM atestv3 +-- +TABLE: name="atestv3" schema="" table="atestv3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv3" +== 267 +-- truncate_limit: 100 +-- fail +SELECT * FROM atestv4 +-- +TABLE: name="atestv4" schema="" table="atestv4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv4" +== 268 +-- truncate_limit: 100 +-- ok (even though regress_priv_user2 cannot access underlying atestv3) + +SELECT * FROM atest2 +-- +TABLE: name="atest2" schema="" table="atest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest2" +== 269 +-- truncate_limit: 100 +-- ok +SELECT * FROM atestv2 +-- +TABLE: name="atestv2" schema="" table="atestv2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atestv2" +== 270 +-- truncate_limit: 100 +-- fail (even though regress_priv_user2 can access underlying atest2) + +-- Test column level permissions + +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 271 +-- truncate_limit: 100 +CREATE TABLE atest5 (one int, two int unique, three int, four int unique) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atest5 (one int, two int UNIQUE, three int, four int UNIQUE)" +== 272 +-- truncate_limit: 100 +CREATE TABLE atest6 (one int, two int, blue int) +-- +TABLE: name="atest6" schema="" table="atest6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE atest6 (one int, two int, blue int)" +== 273 +-- truncate_limit: 100 +GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regress_priv_user4 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (one), insert (two), update (three) ON atest5 TO regress_priv_user4" +== 274 +-- truncate_limit: 100 +GRANT ALL (one) ON atest5 TO regress_priv_user3 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL (one) ON atest5 TO regress_priv_user3" +== 275 +-- truncate_limit: 100 +INSERT INTO atest5 VALUES (1,2,3) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest5 VALUES (1, 2, 3)" +== 276 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user4" +== 277 +-- truncate_limit: 100 +SELECT * FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest5" +== 278 +-- truncate_limit: 100 +-- fail +SELECT one FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT one FROM atest5" +== 279 +-- truncate_limit: 100 +-- ok +COPY atest5 (one) TO stdout +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY atest5(one) TO STDOUT" +== 280 +-- truncate_limit: 100 +-- ok +SELECT two FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT two FROM atest5" +== 281 +-- truncate_limit: 100 +-- fail +COPY atest5 (two) TO stdout +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY atest5(two) TO STDOUT" +== 282 +-- truncate_limit: 100 +-- fail +SELECT atest5 FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atest5 FROM atest5" +== 283 +-- truncate_limit: 100 +-- fail +COPY atest5 (one,two) TO stdout +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY atest5(one, two) TO STDOUT" +== 284 +-- truncate_limit: 100 +-- fail +SELECT 1 FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM atest5" +== 285 +-- truncate_limit: 100 +-- ok +SELECT 1 FROM atest5 a JOIN atest5 b USING (one) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM atest5 a JOIN atest5 b USING (one)" +== 286 +-- truncate_limit: 100 +-- ok +SELECT 1 FROM atest5 a JOIN atest5 b USING (two) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM atest5 a JOIN atest5 b USING (two)" +== 287 +-- truncate_limit: 100 +-- fail +SELECT 1 FROM atest5 a NATURAL JOIN atest5 b +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM atest5 a NATURAL JOIN atest5 b" +== 288 +-- truncate_limit: 100 +-- fail +SELECT * FROM (atest5 a JOIN atest5 b USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (atest5 a JOIN atest5 b USING (one) ) j" +== 289 +-- truncate_limit: 100 +-- fail +SELECT j.* FROM (atest5 a JOIN atest5 b USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT j.* FROM (atest5 a JOIN atest5 b USING (one) ) j" +== 290 +-- truncate_limit: 100 +-- fail +SELECT (j.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT j.* IS NULL FROM (atest5 a JOIN atest5 b USING (one) ) j" +== 291 +-- truncate_limit: 100 +-- fail +SELECT one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT one FROM (atest5 a JOIN atest5 b(one, x, y, z) USING (one) ) j" +== 292 +-- truncate_limit: 100 +-- ok +SELECT j.one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT j.one FROM (atest5 a JOIN atest5 b(one, x, y, z) USING (one) ) j" +== 293 +-- truncate_limit: 100 +-- ok +SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT two FROM (atest5 a JOIN atest5 b(one, x, y, z) USING (one) ) j" +== 294 +-- truncate_limit: 100 +-- fail +SELECT j.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT j.two FROM (atest5 a JOIN atest5 b(one, x, y, z) USING (one) ) j" +== 295 +-- truncate_limit: 100 +-- fail +SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT y FROM (atest5 a JOIN atest5 b(one, x, y, z) USING (one) ) j" +== 296 +-- truncate_limit: 100 +-- fail +SELECT j.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT j.y FROM (atest5 a JOIN atest5 b(one, x, y, z) USING (one) ) j" +== 297 +-- truncate_limit: 100 +-- fail +SELECT * FROM (atest5 a JOIN atest5 b USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest5 a JOIN atest5 b USING (one)" +== 298 +-- truncate_limit: 100 +-- fail +SELECT a.* FROM (atest5 a JOIN atest5 b USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT a.* FROM atest5 a JOIN atest5 b USING (one)" +== 299 +-- truncate_limit: 100 +-- fail +SELECT (a.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT a.* IS NULL FROM atest5 a JOIN atest5 b USING (one)" +== 300 +-- truncate_limit: 100 +-- fail +SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT two FROM atest5 a JOIN atest5 b(one, x, y, z) USING (one)" +== 301 +-- truncate_limit: 100 +-- fail +SELECT a.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT a.two FROM atest5 a JOIN atest5 b(one, x, y, z) USING (one)" +== 302 +-- truncate_limit: 100 +-- fail +SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT y FROM atest5 a JOIN atest5 b(one, x, y, z) USING (one)" +== 303 +-- truncate_limit: 100 +-- fail +SELECT b.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT b.y FROM atest5 a JOIN atest5 b(one, x, y, z) USING (one)" +== 304 +-- truncate_limit: 100 +-- fail +SELECT y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT y FROM atest5 a LEFT JOIN atest5 b(one, x, y, z) USING (one)" +== 305 +-- truncate_limit: 100 +-- fail +SELECT b.y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT b.y FROM atest5 a LEFT JOIN atest5 b(one, x, y, z) USING (one)" +== 306 +-- truncate_limit: 100 +-- fail +SELECT y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT y FROM atest5 a FULL JOIN atest5 b(one, x, y, z) USING (one)" +== 307 +-- truncate_limit: 100 +-- fail +SELECT b.y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +ALIAS: "a"="atest5" +ALIAS: "b"="atest5" +STMT: SelectStmt +TRUNCATED: "SELECT b.y FROM atest5 a FULL JOIN atest5 b(one, x, y, z) USING (one)" +== 308 +-- truncate_limit: 100 +-- fail +SELECT 1 FROM atest5 WHERE two = 2 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +FILTER: schema="" table="" column="two" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM atest5 WHERE two = 2" +== 309 +-- truncate_limit: 100 +-- fail +SELECT * FROM atest1, atest5 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM atest1, atest5" +== 310 +-- truncate_limit: 100 +-- fail +SELECT atest1.* FROM atest1, atest5 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atest1.* FROM atest1, atest5" +== 311 +-- truncate_limit: 100 +-- ok +SELECT atest1.*,atest5.one FROM atest1, atest5 +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atest1.*, atest5.one FROM atest1, atest5" +== 312 +-- truncate_limit: 100 +-- ok +SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.two) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atest1.*, atest5.one FROM atest1 JOIN atest5 ON atest1.a = atest5.two" +== 313 +-- truncate_limit: 100 +-- fail +SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.one) +-- +TABLE: name="atest1" schema="" table="atest1" ctx=Select +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT atest1.*, atest5.one FROM atest1 JOIN atest5 ON atest1.a = atest5.one" +== 314 +-- truncate_limit: 100 +-- ok +SELECT one, two FROM atest5 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT one, two FROM atest5" +== 315 +-- truncate_limit: 100 +-- fail + +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 316 +-- truncate_limit: 100 +GRANT SELECT (one,two) ON atest6 TO regress_priv_user4 +-- +TABLE: name="atest6" schema="" table="atest6" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (one, two) ON atest6 TO regress_priv_user4" +== 317 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user4" +== 318 +-- truncate_limit: 100 +SELECT one, two FROM atest5 NATURAL JOIN atest6 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest6" schema="" table="atest6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT one, two FROM atest5 NATURAL JOIN atest6" +== 319 +-- truncate_limit: 100 +-- fail still + +SET SESSION AUTHORIZATION regress_priv_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user1" +== 320 +-- truncate_limit: 100 +GRANT SELECT (two) ON atest5 TO regress_priv_user4 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (two) ON atest5 TO regress_priv_user4" +== 321 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_priv_user4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_priv_user4" +== 322 +-- truncate_limit: 100 +SELECT one, two FROM atest5 NATURAL JOIN atest6 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +TABLE: name="atest6" schema="" table="atest6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT one, two FROM atest5 NATURAL JOIN atest6" +== 323 +-- truncate_limit: 100 +-- ok now + +-- test column-level privileges for INSERT and UPDATE +INSERT INTO atest5 (two) VALUES (3) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest5 (two) VALUES (3)" +== 324 +-- truncate_limit: 100 +-- ok +COPY atest5 FROM stdin +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY atest5 FROM STDIN" +== 325 +-- truncate_limit: 100 +-- fail +COPY atest5 (two) FROM stdin +-- +TABLE: name="atest5" schema="" table="atest5" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY atest5(two) FROM STDIN" +== 326 +-- truncate_limit: 100 +-- ok +1 +INSERT INTO atest5 (three) VALUES (4) +-- +ERROR: syntax error at or near "1" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 327 +-- truncate_limit: 100 +-- fail +INSERT INTO atest5 VALUES (5,5,5) +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest5 VALUES (5, 5, 5)" +== 328 +-- truncate_limit: 100 +-- fail +UPDATE atest5 SET three = 10 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atest5 SET three = 10" +== 329 +-- truncate_limit: 100 +-- ok +UPDATE atest5 SET one = 8 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atest5 SET one = 8" +== 330 +-- truncate_limit: 100 +-- fail +UPDATE atest5 SET three = 5, one = 2 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE atest5 SET three = 5, one = 2" +== 331 +-- truncate_limit: 100 +-- fail +-- Check that column level privs are enforced in RETURNING +-- Ok. +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 +-- +TABLE: name="atest5" schema="" table="atest5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO atest5 (two) VALUES (6) ON CONFLICT (two) DO UPDATE SET three = 10" diff --git a/parser/testdata/summary_truncate/postgres_regress/psql.metadata.json b/parser/testdata/summary_truncate/postgres_regress/psql.metadata.json new file mode 100644 index 0000000..0612d4a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/psql.metadata.json @@ -0,0 +1,200 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/psql.test b/parser/testdata/summary_truncate/postgres_regress/psql.test new file mode 100644 index 0000000..8426bc8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/psql.test @@ -0,0 +1,1410 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for psql features that aren't closely connected to any +-- specific server features +|-- + +-- \set + +-- fail: invalid name +-- fail: invalid value for special variable +-- check handling of built-in boolean variable + +-- ; + +SELECT 1 as one, 2 as two +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one, 2 AS two" +== 002 +-- truncate_limit: 100 +SELECT 3 as three, 4 as four \gx + +-- \gx should work in FETCH_COUNT mode too + +SELECT 1 as one, 2 as two +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +-- truncate_limit: 100 +SELECT 3 as three, 4 as four \gx + + +-- ; + +SELECT 1 as one, 2 as two \g (format=csv csv_fieldsep='\t') +SELECT 1 as one, 2 as two \gx (title='foo bar') + +-- \bind (extended query protocol) + +SELECT 1 \bind +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +SELECT $1 \bind 'foo' +-- +ERROR: syntax error at or near "\" +CURSORPOS: 11 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- truncate_limit: 100 +SELECT $1, $2 \bind 'foo' 'bar' +-- +ERROR: syntax error at or near "\" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- truncate_limit: 100 +-- errors +-- parse error +SELECT foo \bind +-- +ERROR: syntax error at or near "\" +CURSORPOS: 37 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- truncate_limit: 100 +-- tcop error +SELECT 1 \ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- truncate_limit: 100 +SELECT 2 \bind +-- +ERROR: syntax error at or near "\" +CURSORPOS: 10 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- truncate_limit: 100 +-- bind error +SELECT $1, $2 \bind 'foo' +-- +ERROR: syntax error at or near "\" +CURSORPOS: 29 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 010 +-- truncate_limit: 100 +-- ; + +select 10 as test01, 20 as test02, 'Hello' as test03 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 10 AS test01, 20 AS test02, 'Hello' AS test03" +== 011 +-- truncate_limit: 100 +-- should fail: bad variable name +select 10 as "bad name" + +select 97 as "EOF", 'ok' as _foo +-- +ERROR: syntax error at or near "select" +CURSORPOS: 60 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 012 +-- truncate_limit: 100 +-- multiple backslash commands in one line +select 1 as x, 2 as y +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS x, 2 AS y" +== 013 +-- truncate_limit: 100 +select 3 as x, 4 as y +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3 AS x, 4 AS y" +== 014 +-- truncate_limit: 100 +select 5 as x, 6 as y +-- +STMT: SelectStmt +TRUNCATED: "SELECT 5 AS x, 6 AS y" +== 015 +-- truncate_limit: 100 +select 7 as x, 8 as y +-- +STMT: SelectStmt +TRUNCATED: "SELECT 7 AS x, 8 AS y" +== 016 +-- truncate_limit: 100 +-- NULL should unset the variable +select 1 as var1, NULL as var2, 3 as var3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS var1, NULL AS var2, 3 AS var3" +== 017 +-- truncate_limit: 100 +-- ; +select 10 as test01, 20 as test02 from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 10 AS test01, 20 AS test02 FROM generate_series(1, 3)" +== 018 +-- truncate_limit: 100 +select 10 as test01, 20 as test02 from generate_series(1,0) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 10 AS test01, 20 AS test02 FROM generate_series(1, 0)" +== 019 +-- truncate_limit: 100 +-- ; +select a from generate_series(1, 10) as a where a = 11 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM generate_series(1, 10) a WHERE a = 11" +== 020 +-- truncate_limit: 100 +-- ; + +select 1 as x, 2 as y +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS x, 2 AS y" +== 021 +-- truncate_limit: 100 +select 3 as x, 4 as y +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3 AS x, 4 AS y" +== 022 +-- truncate_limit: 100 +select 10 as test01, 20 as test02 from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 10 AS test01, 20 AS test02 FROM generate_series(1, 3)" +== 023 +-- truncate_limit: 100 +select 10 as test01, 20 as test02 from generate_series(1,0) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 10 AS test01, 20 AS test02 FROM generate_series(1, 0)" +== 024 +-- truncate_limit: 100 +-- ; + +SELECT + NULL AS zero, + 1 AS one, + 2.0 AS two, + 'three' AS three, + $1 AS four, + sin($2) as five, + 'foo'::varchar(4) as six, + CURRENT_DATE AS now + +-- should work with tuple-returning utilities, such as EXECUTE +PREPARE test AS SELECT 1 AS first, 2 AS second +-- +ERROR: syntax error at or near "PREPARE" +CURSORPOS: 239 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 025 +-- truncate_limit: 100 +EXECUTE test +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE test" +== 026 +-- truncate_limit: 100 +EXPLAIN EXECUTE test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN EXECUTE test" +== 027 +-- truncate_limit: 100 +-- should fail cleanly - syntax error +SELECT 1 + +-- +ERROR: syntax error at end of input +CURSORPOS: 49 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 028 +-- truncate_limit: 100 +-- check behavior with empty results +SELECT +-- +STMT: SelectStmt +TRUNCATED: "SELECT" +== 029 +-- truncate_limit: 100 +CREATE TABLE bububu(a int) +-- +TABLE: name="bububu" schema="" table="bububu" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bububu (a int)" +== 030 +-- truncate_limit: 100 +-- subject command should not have executed +TABLE bububu +-- +TABLE: name="bububu" schema="" table="bububu" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bububu" +== 031 +-- truncate_limit: 100 +-- fail + +-- query buffer should remain unchanged +SELECT 1 AS x, 'Hello', 2 AS y, true AS "dirty\name" + +-- all on one line +SELECT 3 AS x, 'Hello', 4 AS y, true AS "dirty\name" +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 123 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 032 +-- truncate_limit: 100 +-- test for server bug #17983 with empty statement in aborted transaction +set search_path = default +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO DEFAULT" +== 033 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 034 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 035 +-- truncate_limit: 100 +-- ; + +create temporary table gexec_test(a int, b text, c date, d float) +-- +TABLE: name="gexec_test" schema="" table="gexec_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE gexec_test (a int, b text, c date, d double precision)" +== 036 +-- truncate_limit: 100 +select format('create index on gexec_test(%I)', attname) +from pg_attribute +where attrelid = 'gexec_test'::regclass and attnum > 0 +order by attnum + +-- ; +-- (though the fetch limit applies to the executed queries not the meta query) + +select 'select 1 as ones', 'select x.y, x.y*2 as double from generate_series(1,4) as x(y)' +union all +select 'drop table gexec_test', NULL +union all +select 'drop table gexec_test', 'select ''2000-01-01''::date as party_over' + + +-- \setenv, \getenv + +-- ensure MYVAR isn't set +-- in which case, reading it doesn't change the target +-- now set it + +-- show all pset options + +-- test multi-line headers, wrapping, and newline indicators +-- in aligned, unaligned, and wrapped formats +prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab + +c", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a +bc" from generate_series(1,10) as n(n) group by n>1 order by n>1 +-- +ERROR: syntax error at or near "select" +CURSORPOS: 233 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 037 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 038 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 039 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 040 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 041 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 042 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 043 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 044 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 045 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 046 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 047 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 048 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 049 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 050 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 051 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 052 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 053 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 054 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 055 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 056 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 057 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 058 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 059 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 060 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 061 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 062 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 063 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 064 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 065 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 066 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 067 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 068 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 069 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 070 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 071 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 072 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 073 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 074 +-- truncate_limit: 100 +-- test single-line header and data +prepare q as select repeat('x',2*n) as "0123456789abcdef", repeat('y',20-2*n) as "0123456789" from generate_series(1,10) as n +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q AS SELECT repeat('x', 2 * n) AS \"0123456789abcdef\", repeat('y', 20 - (2 * n)) AS \"01234..." +== 075 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 076 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 077 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 078 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 079 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 080 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 081 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 082 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 083 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 084 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 085 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 086 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 087 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 088 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 089 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 090 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 091 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 092 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 093 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 094 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 095 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 096 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 097 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 098 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 099 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 100 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 101 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 102 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 103 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 104 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 105 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 106 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 107 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 108 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 109 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 110 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 111 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 112 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 113 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 114 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 115 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 116 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 117 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 118 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 119 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 120 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 121 +-- truncate_limit: 100 +-- support table for output-format tests (useful to create a footer) + +create table psql_serial_tab (id serial) +-- +TABLE: name="psql_serial_tab" schema="" table="psql_serial_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE psql_serial_tab (id serial)" +== 122 +-- truncate_limit: 100 +-- test header/footer/tuples_only behavior in aligned/unaligned/wrapped cases + + +-- empty table is a special case for this format +select 1 where false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 WHERE false" +== 123 +-- truncate_limit: 100 +-- check conditional am display + +CREATE SCHEMA tableam_display +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA tableam_display" +== 124 +-- truncate_limit: 100 +CREATE ROLE regress_display_role +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_display_role" +== 125 +-- truncate_limit: 100 +ALTER SCHEMA tableam_display OWNER TO regress_display_role +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SCHEMA tableam_display OWNER TO regress_display_role" +== 126 +-- truncate_limit: 100 +SET search_path TO tableam_display +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO tableam_display" +== 127 +-- truncate_limit: 100 +CREATE ACCESS METHOD heap_psql TYPE TABLE HANDLER heap_tableam_handler +-- +STMT: CreateAmStmt +TRUNCATED: "CREATE ACCESS METHOD heap_psql TYPE TABLE HANDLER heap_tableam_handler" +== 128 +-- truncate_limit: 100 +SET ROLE TO regress_display_role +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_display_role" +== 129 +-- truncate_limit: 100 +-- Use only relations with a physical size of zero. +CREATE TABLE tbl_heap_psql(f1 int, f2 char(100)) using heap_psql +-- +TABLE: name="tbl_heap_psql" schema="" table="tbl_heap_psql" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_heap_psql (f1 int, f2 char(100)) USING heap_psql" +== 130 +-- truncate_limit: 100 +CREATE TABLE tbl_heap(f1 int, f2 char(100)) using heap +-- +TABLE: name="tbl_heap" schema="" table="tbl_heap" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbl_heap (f1 int, f2 char(100)) USING heap" +== 131 +-- truncate_limit: 100 +CREATE VIEW view_heap_psql AS SELECT f1 from tbl_heap_psql +-- +TABLE: name="view_heap_psql" schema="" table="view_heap_psql" ctx=DDL +TABLE: name="tbl_heap_psql" schema="" table="tbl_heap_psql" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_heap_psql AS SELECT f1 FROM tbl_heap_psql" +== 132 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW mat_view_heap_psql USING heap_psql AS SELECT f1 from tbl_heap_psql +-- +TABLE: name="mat_view_heap_psql" schema="" table="mat_view_heap_psql" ctx=DDL +TABLE: name="tbl_heap_psql" schema="" table="tbl_heap_psql" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW mat_view_heap_psql USING heap_psql AS SELECT f1 FROM tbl_heap_psql" +== 133 +-- truncate_limit: 100 +-- AM is displayed for tables, indexes and materialized views. +-- But not for views and sequences. +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 134 +-- truncate_limit: 100 +RESET search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 135 +-- truncate_limit: 100 +DROP SCHEMA tableam_display CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA tableam_display CASCADE" +== 136 +-- truncate_limit: 100 +DROP ACCESS METHOD heap_psql +-- +STMT: DropStmt +TRUNCATED: "DROP ACCESS METHOD heap_psql" +== 137 +-- truncate_limit: 100 +DROP ROLE regress_display_role +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_display_role" +== 138 +-- truncate_limit: 100 +-- test numericlocale (as best we can without control of psql's locale) + + +select n, -n as m, n * 111 as x, '1e90'::float8 as f +from generate_series(0,3) n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT n, - n AS m, n * 111 AS x, '1e90'::float8 AS f FROM generate_series(0, 3) n" +== 139 +-- truncate_limit: 100 +-- test asciidoc output format + + + +prepare q as + select 'some|text' as "a|title", ' ' as "empty ", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q AS SELECT 'some|text' AS \"a|title\", ' ' AS \"empty \", n AS \"int\" FROM generate_se..." +== 140 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 141 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 142 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 143 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 144 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 145 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 146 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 147 +-- truncate_limit: 100 +-- test csv output format + + + +prepare q as + select 'some"text' as "a""title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q AS SELECT 'some\"text' AS \"a\"\"title\", ' \n' AS junk, ' ' AS empty, n AS \"int..." +== 148 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 149 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 150 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 151 +-- truncate_limit: 100 +-- special cases +select 'comma,comma' as comma, 'semi;semi' as semi +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'comma,comma' AS comma, 'semi;semi' AS semi" +== 152 +-- truncate_limit: 100 +select 'comma,comma' as comma, 'semi;semi' as semi +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'comma,comma' AS comma, 'semi;semi' AS semi" +== 153 +-- truncate_limit: 100 +select '\.' as data +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\.' AS data" +== 154 +-- truncate_limit: 100 +select '\' as d1, '' as d2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\' AS d1, '' AS d2" +== 155 +-- truncate_limit: 100 +-- illegal csv separators + + +-- test html output format + + + +prepare q as + select 'some"text' as "a&title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q AS SELECT 'some\"text' AS \"a&title\", ' \n' AS junk, ' ' AS empty, n AS \"int\"..." +== 156 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 157 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 158 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 159 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 160 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 161 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 162 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 163 +-- truncate_limit: 100 +-- test latex output format + + + +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q AS SELECT E'some\\\\more_text' AS \"a$title\", ' #%&^~|\n{bar}' AS junk, ' ' AS empt..." +== 164 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 165 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 166 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 167 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 168 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 169 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 170 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 171 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 172 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 173 +-- truncate_limit: 100 +-- test latex-longtable output format + + + +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q AS SELECT E'some\\\\more_text' AS \"a$title\", ' #%&^~|\n{bar}' AS junk, ' ' AS empt..." +== 174 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 175 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 176 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 177 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 178 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 179 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 180 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 181 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 182 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 183 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 184 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 185 +-- truncate_limit: 100 +-- test troff-ms output format + + + +prepare q as + select 'some\text' as "a\title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE q AS SELECT E'some\\\\text' AS \"a\\title\", ' \n' AS junk, ' ' AS empty, n AS \"in..." +== 186 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 187 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 188 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 189 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 190 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 191 +-- truncate_limit: 100 +execute q +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE q" +== 192 +-- truncate_limit: 100 +deallocate q +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE q" +== 193 +-- truncate_limit: 100 +-- check ambiguous format requests + + +-- clean up after output format tests + +drop table psql_serial_tab +-- +TABLE: name="psql_serial_tab" schema="" table="psql_serial_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE psql_serial_tab" +== 194 +-- truncate_limit: 100 +-- \echo and allied features + + + + + +-- tests for \if ... \endif + + select 'okay' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'okay'" +== 195 +-- truncate_limit: 100 +select 'still okay' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'still okay'" +== 196 +-- truncate_limit: 100 +not okay +-- +ERROR: syntax error at or near "not" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json b/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json new file mode 100644 index 0000000..5e6664a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json @@ -0,0 +1,12 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.test b/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.test new file mode 100644 index 0000000..f50a4c0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.test @@ -0,0 +1,158 @@ +== 001 +-- truncate_limit: 100 +|-- +-- \crosstabview +|-- + +CREATE TABLE ctv_data (v, h, c, i, d) AS +VALUES + ('v1','h2','foo', 3, '2015-04-01'::date), + ('v2','h1','bar', 3, '2015-01-02'), + ('v1','h0','baz', NULL, '2015-07-12'), + ('v0','h4','qux', 4, '2015-07-15'), + ('v0','h4','dbl', -3, '2014-12-15'), + ('v0',NULL,'qux', 5, '2014-07-15'), + ('v1','h2','quux',7, '2015-04-04') +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctv_data(v, h, c, i, d) AS VALUES ('v1', 'h2', 'foo', 3, '2015-04-01'::date), ('v2',..." +== 002 +-- truncate_limit: 100 +-- make plans more stable +ANALYZE ctv_data +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ctv_data" +== 003 +-- truncate_limit: 100 +-- running \crosstabview after query uses query in buffer +SELECT v, EXTRACT(year FROM d), count(*) + FROM ctv_data + GROUP BY 1, 2 + ORDER BY 1, 2 +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT v, extract ('year' FROM d), count(*) FROM ctv_data GROUP BY 1, 2 ORDER BY 1, 2" +== 004 +-- truncate_limit: 100 +-- basic usage with 3 columns + +-- ordered months in horizontal header, quoted column name +SELECT v, to_char(d, 'Mon') AS "month name", EXTRACT(month FROM d) AS num, + count(*) FROM ctv_data GROUP BY 1,2,3 ORDER BY 1 + +-- ordered months in vertical header, ordered years in horizontal header +SELECT EXTRACT(year FROM d) AS year, to_char(d,'Mon') AS """month"" name", + EXTRACT(month FROM d) AS month, + format('sum=%s avg=%s', sum(i), avg(i)::numeric(2,1)) + FROM ctv_data + GROUP BY EXTRACT(year FROM d), to_char(d,'Mon'), EXTRACT(month FROM d) +ORDER BY month + +-- combine contents vertically into the same cell (V/H duplicates) +SELECT v, h, string_agg(c, E'\n') FROM ctv_data GROUP BY v, h ORDER BY 1,2,3 + +-- horizontal ASC order from window function +SELECT v,h, string_agg(c, E'\n') AS c, row_number() OVER(ORDER BY h) AS r +FROM ctv_data GROUP BY v, h ORDER BY 1,3,2 + +-- horizontal DESC order from window function +SELECT v, h, string_agg(c, E'\n') AS c, row_number() OVER(ORDER BY h DESC) AS r +FROM ctv_data GROUP BY v, h ORDER BY 1,3,2 + +-- horizontal ASC order from window function, NULLs pushed rightmost +SELECT v,h, string_agg(c, E'\n') AS c, row_number() OVER(ORDER BY h NULLS LAST) AS r +FROM ctv_data GROUP BY v, h ORDER BY 1,3,2 + +-- only null, no column name, 2 columns: error +SELECT null,null \crosstabview + +-- only null, no column name, 3 columns: works +SELECT null,null,null \crosstabview + +-- null display +SELECT v,h, string_agg(i::text, E'\n') AS i FROM ctv_data +GROUP BY v, h ORDER BY h,v + +-- refer to columns by position +SELECT v,h,string_agg(i::text, E'\n'), string_agg(c, E'\n') +FROM ctv_data GROUP BY v, h ORDER BY h,v + +-- refer to columns by positions and names mixed +SELECT v,h, string_agg(i::text, E'\n') AS i, string_agg(c, E'\n') AS c +FROM ctv_data GROUP BY v, h ORDER BY h,v + +-- refer to columns by quoted names, check downcasing of unquoted name +SELECT 1 as "22", 2 as b, 3 as "Foo" + +-- error: bad column name +SELECT v,h,c,i FROM ctv_data + +-- error: need to quote name +SELECT 1 as "22", 2 as b, 3 as "Foo" + +-- error: need to not quote name +SELECT 1 as "22", 2 as b, 3 as "Foo" + +-- error: bad column number +SELECT v,h,i,c FROM ctv_data + +-- error: same H and V columns +SELECT v,h,i,c FROM ctv_data + +-- error: too many columns +SELECT a,a,1 FROM generate_series(1,3000) AS a + +-- error: only one column +SELECT 1 \crosstabview + +DROP TABLE ctv_data +-- +ERROR: syntax error at or near "SELECT" +CURSORPOS: 291 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- truncate_limit: 100 +-- check error reporting (bug #14476) +CREATE TABLE ctv_data (x int, y int, v text) +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctv_data (x int, y int, v text)" +== 006 +-- truncate_limit: 100 +INSERT INTO ctv_data SELECT 1, x, '*' || x FROM generate_series(1,10) x +-- +TABLE: name="ctv_data" schema="" table="ctv_data" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ctv_data SELECT 1, x, '*' || x FROM generate_series(1, 10) x" +== 007 +-- truncate_limit: 100 +SELECT * FROM ctv_data \crosstabview + +INSERT INTO ctv_data VALUES (1, 10, '*') +-- +ERROR: syntax error at or near "\" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- truncate_limit: 100 +-- duplicate data to cause error +SELECT * FROM ctv_data \crosstabview + +DROP TABLE ctv_data +-- +ERROR: syntax error at or near "\" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary_truncate/postgres_regress/publication.metadata.json b/parser/testdata/summary_truncate/postgres_regress/publication.metadata.json new file mode 100644 index 0000000..8cf9d31 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/publication.metadata.json @@ -0,0 +1,659 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/publication.test b/parser/testdata/summary_truncate/postgres_regress/publication.test new file mode 100644 index 0000000..0172704 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/publication.test @@ -0,0 +1,4537 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PUBLICATION +|-- +CREATE ROLE regress_publication_user LOGIN SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_publication_user WITH LOGIN SUPERUSER" +== 002 +-- truncate_limit: 100 +CREATE ROLE regress_publication_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_publication_user2" +== 003 +-- truncate_limit: 100 +CREATE ROLE regress_publication_user_dummy LOGIN NOSUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_publication_user_dummy WITH LOGIN NOSUPERUSER" +== 004 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION 'regress_publication_user' +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_publication_user" +== 005 +-- truncate_limit: 100 +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 006 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_default +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_default" +== 007 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 008 +-- truncate_limit: 100 +COMMENT ON PUBLICATION testpub_default IS 'test publication' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON PUBLICATION testpub_default IS 'test publication'" +== 009 +-- truncate_limit: 100 +SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p +-- +TABLE: name="pg_publication" schema="" table="pg_publication" ctx=Select +ALIAS: "p"="pg_publication" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p" +== 010 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 011 +-- truncate_limit: 100 +CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert)" +== 012 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 013 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default SET (publish = update) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default SET (publish = update)" +== 014 +-- truncate_limit: 100 +-- error cases +CREATE PUBLICATION testpub_xxx WITH (foo) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_xxx WITH (foo)" +== 015 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum')" +== 016 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = 'true', publish_via_partition_root = '0') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = true, publish_via_partition_roo..." +== 017 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete') +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete')" +== 018 +-- truncate_limit: 100 +--- adding tables +CREATE SCHEMA pub_test +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pub_test" +== 019 +-- truncate_limit: 100 +CREATE TABLE testpub_tbl1 (id serial primary key, data text) +-- +TABLE: name="testpub_tbl1" schema="" table="testpub_tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl1 (id serial PRIMARY KEY, data text)" +== 020 +-- truncate_limit: 100 +CREATE TABLE pub_test.testpub_nopk (foo int, bar int) +-- +TABLE: name="pub_test.testpub_nopk" schema="pub_test" table="testpub_nopk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_test.testpub_nopk (foo int, bar int)" +== 021 +-- truncate_limit: 100 +CREATE VIEW testpub_view AS SELECT 1 +-- +TABLE: name="testpub_view" schema="" table="testpub_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW testpub_view AS SELECT 1" +== 022 +-- truncate_limit: 100 +CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a)" +== 023 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 024 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert')" +== 025 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 026 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update') +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update')" +== 027 +-- truncate_limit: 100 +CREATE TABLE testpub_tbl2 (id serial primary key, data text) +-- +TABLE: name="testpub_tbl2" schema="" table="testpub_tbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl2 (id serial PRIMARY KEY, data text)" +== 028 +-- truncate_limit: 100 +-- fail - can't add to for all tables publication +ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2" +== 029 +-- truncate_limit: 100 +-- fail - can't drop from all tables publication +ALTER PUBLICATION testpub_foralltables DROP TABLE testpub_tbl2 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_foralltables DROP TABLE testpub_tbl2" +== 030 +-- truncate_limit: 100 +-- fail - can't add to for all tables publication +ALTER PUBLICATION testpub_foralltables SET TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_foralltables SET TABLE pub_test.testpub_nopk" +== 031 +-- truncate_limit: 100 +-- fail - can't add schema to 'FOR ALL TABLES' publication +ALTER PUBLICATION testpub_foralltables ADD TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_foralltables ADD TABLES IN SCHEMA pub_test" +== 032 +-- truncate_limit: 100 +-- fail - can't drop schema from 'FOR ALL TABLES' publication +ALTER PUBLICATION testpub_foralltables DROP TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_foralltables DROP TABLES IN SCHEMA pub_test" +== 033 +-- truncate_limit: 100 +-- fail - can't set schema to 'FOR ALL TABLES' publication +ALTER PUBLICATION testpub_foralltables SET TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_foralltables SET TABLES IN SCHEMA pub_test" +== 034 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 035 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1" +== 036 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 037 +-- truncate_limit: 100 +-- should be able to add schema to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable ADD TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLES IN SCHEMA pub_test" +== 038 +-- truncate_limit: 100 +-- should be able to drop schema from 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable DROP TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable DROP TABLES IN SCHEMA pub_test" +== 039 +-- truncate_limit: 100 +-- should be able to set schema to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test" +== 040 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 041 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test" +== 042 +-- truncate_limit: 100 +-- should be able to create publication with schema and table of the same +-- schema +CREATE PUBLICATION testpub_for_tbl_schema FOR TABLES IN SCHEMA pub_test, TABLE pub_test.testpub_nopk +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_for_tbl_schema FOR TABLES IN SCHEMA pub_test, TABLE pub_test.testpub_nopk" +== 043 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 044 +-- truncate_limit: 100 +-- weird parser corner case +CREATE PUBLICATION testpub_parsertst FOR TABLE pub_test.testpub_nopk, CURRENT_SCHEMA +-- +ERROR: invalid table name +CURSORPOS: 99 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 045 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_parsertst FOR TABLES IN SCHEMA foo, test.foo +-- +ERROR: invalid schema name +CURSORPOS: 64 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 046 +-- truncate_limit: 100 +-- should be able to add a table of the same schema to the schema publication +ALTER PUBLICATION testpub_forschema ADD TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forschema ADD TABLE pub_test.testpub_nopk" +== 047 +-- truncate_limit: 100 +-- should be able to drop the table +ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk" +== 048 +-- truncate_limit: 100 +-- fail - can't drop a table from the schema publication which isn't in the +-- publication +ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk" +== 049 +-- truncate_limit: 100 +-- should be able to set table to schema publication +ALTER PUBLICATION testpub_forschema SET TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forschema SET TABLE pub_test.testpub_nopk" +== 050 +-- truncate_limit: 100 +SELECT pubname, puballtables FROM pg_publication WHERE pubname = 'testpub_foralltables' +-- +TABLE: name="pg_publication" schema="" table="pg_publication" ctx=Select +FILTER: schema="" table="" column="pubname" +STMT: SelectStmt +TRUNCATED: "SELECT pubname, puballtables FROM pg_publication WHERE pubname = 'testpub_foralltables'" +== 051 +-- truncate_limit: 100 +DROP TABLE testpub_tbl2 +-- +TABLE: name="testpub_tbl2" schema="" table="testpub_tbl2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl2" +== 052 +-- truncate_limit: 100 +DROP PUBLICATION testpub_foralltables, testpub_fortable, testpub_forschema, testpub_for_tbl_schema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_foralltables, testpub_fortable, testpub_forschema, testpub_for_tbl_schema" +== 053 +-- truncate_limit: 100 +CREATE TABLE testpub_tbl3 (a int) +-- +TABLE: name="testpub_tbl3" schema="" table="testpub_tbl3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl3 (a int)" +== 054 +-- truncate_limit: 100 +CREATE TABLE testpub_tbl3a (b text) INHERITS (testpub_tbl3) +-- +TABLE: name="testpub_tbl3a" schema="" table="testpub_tbl3a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl3a (b text) INHERITS (testpub_tbl3)" +== 055 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 056 +-- truncate_limit: 100 +CREATE PUBLICATION testpub3 FOR TABLE testpub_tbl3 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub3 FOR TABLE testpub_tbl3" +== 057 +-- truncate_limit: 100 +CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3" +== 058 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 059 +-- truncate_limit: 100 +DROP TABLE testpub_tbl3, testpub_tbl3a +-- +TABLE: name="testpub_tbl3" schema="" table="testpub_tbl3" ctx=DDL +TABLE: name="testpub_tbl3a" schema="" table="testpub_tbl3a" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl3, testpub_tbl3a" +== 060 +-- truncate_limit: 100 +DROP PUBLICATION testpub3, testpub4 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub3, testpub4" +== 061 +-- truncate_limit: 100 +-- Tests for partitioned tables +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 062 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_forparted +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forparted" +== 063 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_forparted1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forparted1" +== 064 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 065 +-- truncate_limit: 100 +CREATE TABLE testpub_parted1 (LIKE testpub_parted) +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_parted1 (LIKE testpub_parted)" +== 066 +-- truncate_limit: 100 +CREATE TABLE testpub_parted2 (LIKE testpub_parted) +-- +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_parted2 (LIKE testpub_parted)" +== 067 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_forparted1 SET (publish='insert') +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forparted1 SET (publish = 'insert')" +== 068 +-- truncate_limit: 100 +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted1 FOR VALUES IN (1) +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted1 FOR VALUES IN (1)" +== 069 +-- truncate_limit: 100 +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted2 FOR VALUES IN (2) +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted2 FOR VALUES IN (2)" +== 070 +-- truncate_limit: 100 +-- works despite missing REPLICA IDENTITY, because updates are not replicated +UPDATE testpub_parted1 SET a = 1 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_parted1 SET a = 1" +== 071 +-- truncate_limit: 100 +-- only parent is listed as being in publication, not the partition +ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted" +== 072 +-- truncate_limit: 100 +-- works despite missing REPLICA IDENTITY, because no actual update happened +UPDATE testpub_parted SET a = 1 WHERE false +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_parted SET a = 1 WHERE false" +== 073 +-- truncate_limit: 100 +-- should now fail, because parent's publication replicates updates +UPDATE testpub_parted1 SET a = 1 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_parted1 SET a = 1" +== 074 +-- truncate_limit: 100 +ALTER TABLE testpub_parted DETACH PARTITION testpub_parted1 +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_parted DETACH PARTITION testpub_parted1" +== 075 +-- truncate_limit: 100 +-- works again, because parent's publication is no longer considered +UPDATE testpub_parted1 SET a = 1 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_parted1 SET a = 1" +== 076 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_forparted SET (publish_via_partition_root = true) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forparted SET (publish_via_partition_root = true)" +== 077 +-- truncate_limit: 100 +-- still fail, because parent's publication replicates updates +UPDATE testpub_parted2 SET a = 2 +-- +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_parted2 SET a = 2" +== 078 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted" +== 079 +-- truncate_limit: 100 +-- works again, because update is no longer replicated +UPDATE testpub_parted2 SET a = 2 +-- +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_parted2 SET a = 2" +== 080 +-- truncate_limit: 100 +DROP TABLE testpub_parted1, testpub_parted2 +-- +TABLE: name="testpub_parted1" schema="" table="testpub_parted1" ctx=DDL +TABLE: name="testpub_parted2" schema="" table="testpub_parted2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_parted1, testpub_parted2" +== 081 +-- truncate_limit: 100 +DROP PUBLICATION testpub_forparted, testpub_forparted1 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_forparted, testpub_forparted1" +== 082 +-- truncate_limit: 100 +-- Tests for row filters +CREATE TABLE testpub_rf_tbl1 (a integer, b text) +-- +TABLE: name="testpub_rf_tbl1" schema="" table="testpub_rf_tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_rf_tbl1 (a int, b text)" +== 083 +-- truncate_limit: 100 +CREATE TABLE testpub_rf_tbl2 (c text, d integer) +-- +TABLE: name="testpub_rf_tbl2" schema="" table="testpub_rf_tbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_rf_tbl2 (c text, d int)" +== 084 +-- truncate_limit: 100 +CREATE TABLE testpub_rf_tbl3 (e integer) +-- +TABLE: name="testpub_rf_tbl3" schema="" table="testpub_rf_tbl3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_rf_tbl3 (e int)" +== 085 +-- truncate_limit: 100 +CREATE TABLE testpub_rf_tbl4 (g text) +-- +TABLE: name="testpub_rf_tbl4" schema="" table="testpub_rf_tbl4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_rf_tbl4 (g text)" +== 086 +-- truncate_limit: 100 +CREATE TABLE testpub_rf_tbl5 (a xml) +-- +TABLE: name="testpub_rf_tbl5" schema="" table="testpub_rf_tbl5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_rf_tbl5 (a xml)" +== 087 +-- truncate_limit: 100 +CREATE SCHEMA testpub_rf_schema1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA testpub_rf_schema1" +== 088 +-- truncate_limit: 100 +CREATE TABLE testpub_rf_schema1.testpub_rf_tbl5 (h integer) +-- +TABLE: name="testpub_rf_schema1.testpub_rf_tbl5" schema="testpub_rf_schema1" table="testpub_rf_tbl5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_rf_schema1.testpub_rf_tbl5 (h int)" +== 089 +-- truncate_limit: 100 +CREATE SCHEMA testpub_rf_schema2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA testpub_rf_schema2" +== 090 +-- truncate_limit: 100 +CREATE TABLE testpub_rf_schema2.testpub_rf_tbl6 (i integer) +-- +TABLE: name="testpub_rf_schema2.testpub_rf_tbl6" schema="testpub_rf_schema2" table="testpub_rf_tbl6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_rf_schema2.testpub_rf_tbl6 (i int)" +== 091 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 092 +-- truncate_limit: 100 +-- Firstly, test using the option publish='insert' because the row filter +-- validation of referenced columns is less strict than for delete/update. +CREATE PUBLICATION testpub5 FOR TABLE testpub_rf_tbl1, testpub_rf_tbl2 WHERE (c <> 'test' AND d < 5) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub5 FOR TABLE testpub_rf_tbl1, TABLE testpub_rf_tbl2 WHERE (c <> 'test' A..." +== 093 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 094 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl3 WHERE (e > 1000 AND e < 2000) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl3 WHERE (e > 1000 AND e < 2000)" +== 095 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl2 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl2" +== 096 +-- truncate_limit: 100 +-- remove testpub_rf_tbl1 and add testpub_rf_tbl3 again (another WHERE expression) +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e > 300 AND e < 500) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e > 300 AND e < 500)" +== 097 +-- truncate_limit: 100 +-- test \d (now it displays filter information) +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 098 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_rf_yes FOR TABLE testpub_rf_tbl1 WHERE (a > 1) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_rf_yes FOR TABLE testpub_rf_tbl1 WHERE (a > 1) WITH (publish = 'insert')" +== 099 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_rf_no FOR TABLE testpub_rf_tbl1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_rf_no FOR TABLE testpub_rf_tbl1" +== 100 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 101 +-- truncate_limit: 100 +DROP PUBLICATION testpub_rf_yes, testpub_rf_no +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_rf_yes, testpub_rf_no" +== 102 +-- truncate_limit: 100 +-- some more syntax tests to exercise other parser pathways +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 103 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_syntax1 FOR TABLE testpub_rf_tbl1, ONLY testpub_rf_tbl3 WHERE (e < 999) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_syntax1 FOR TABLE testpub_rf_tbl1, TABLE ONLY testpub_rf_tbl3 WHERE (e..." +== 104 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 105 +-- truncate_limit: 100 +DROP PUBLICATION testpub_syntax1 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_syntax1" +== 106 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 107 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_syntax2 FOR TABLE testpub_rf_tbl1, testpub_rf_schema1.testpub_rf_tbl5 WHERE (h < 999) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_syntax2 FOR TABLE testpub_rf_tbl1, TABLE testpub_rf_schema1.testpub_rf..." +== 108 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 109 +-- truncate_limit: 100 +DROP PUBLICATION testpub_syntax2 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_syntax2" +== 110 +-- truncate_limit: 100 +-- fail - schemas don't allow WHERE clause +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 111 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_syntax3 FOR TABLES IN SCHEMA testpub_rf_schema1 WHERE (a = 123) +-- +ERROR: syntax error at or near "WHERE" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 112 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_syntax3 FOR TABLES IN SCHEMA testpub_rf_schema1, testpub_rf_schema1 WHERE (a = 123) +-- +ERROR: WHERE clause not allowed for schema +CURSORPOS: 77 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 113 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 114 +-- truncate_limit: 100 +-- fail - duplicate tables are not allowed if that table has any WHERE clause +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 115 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1 WHERE (a = 1), testpub_rf_tbl1 WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1 WHERE (a = 1), TABLE testpub_rf_tbl1 WI..." +== 116 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1, testpub_rf_tbl1 WHERE (a = 2) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1, TABLE testpub_rf_tbl1 WHERE (a = 2) WI..." +== 117 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 118 +-- truncate_limit: 100 +-- fail - publication WHERE clause must be boolean +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (1234) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (1234)" +== 119 +-- truncate_limit: 100 +-- fail - aggregate functions not allowed in WHERE clause +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e < AVG(e)) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e < avg(e))" +== 120 +-- truncate_limit: 100 +-- fail - user-defined operators are not allowed +CREATE FUNCTION testpub_rf_func1(integer, integer) RETURNS boolean AS $$ SELECT hashint4($1) > $2 $$ LANGUAGE SQL +-- +FUNCTION: name="testpub_rf_func1" function="testpub_rf_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpub_rf_func1(int, int) RETURNS boolean AS $$ SELECT hashint4($1) > $2 $$ LANG..." +== 121 +-- truncate_limit: 100 +CREATE OPERATOR =#> (PROCEDURE = testpub_rf_func1, LEFTARG = integer, RIGHTARG = integer) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR =#> (procedure = testpub_rf_func1, leftarg = int, rightarg = int)" +== 122 +-- truncate_limit: 100 +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl3 WHERE (e =#> 27) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl3 WHERE (e =#> 27)" +== 123 +-- truncate_limit: 100 +-- fail - user-defined functions are not allowed +CREATE FUNCTION testpub_rf_func2() RETURNS integer AS $$ BEGIN RETURN 123; END; $$ LANGUAGE plpgsql +-- +FUNCTION: name="testpub_rf_func2" function="testpub_rf_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testpub_rf_func2() RETURNS int AS $$ BEGIN RETURN 123; END; $$ LANGUAGE plpgsql" +== 124 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a >= testpub_rf_func2()) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a >= testpub_rf_func2())" +== 125 +-- truncate_limit: 100 +-- fail - non-immutable functions are not allowed. random() is volatile. +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a < random()) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a < random())" +== 126 +-- truncate_limit: 100 +-- fail - user-defined collations are not allowed +CREATE COLLATION user_collation FROM "C" +-- +STMT: DefineStmt +TRUNCATED: "CREATE COLLATION user_collation FROM \"C\"" +== 127 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (b < '2' COLLATE user_collation) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (b < '2' COLLATE user_collation)" +== 128 +-- truncate_limit: 100 +-- ok - NULLIF is allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (NULLIF(1,2) = a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((NULLIF(1, 2)) = a)" +== 129 +-- truncate_limit: 100 +-- ok - built-in operators are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS NULL) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS NULL)" +== 130 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((a > 5) IS FALSE) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a > 5 IS FALSE)" +== 131 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS DISTINCT FROM 5) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS DISTINCT FROM 5)" +== 132 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((a, a + 1) < (2, 3)) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((a, a + 1) < (2, 3))" +== 133 +-- truncate_limit: 100 +-- ok - built-in type coercions between two binary compatible datatypes are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (b::varchar < '2') +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (b::varchar < '2')" +== 134 +-- truncate_limit: 100 +-- ok - immutable built-in functions are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl4 WHERE (length(g) < 6) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl4 WHERE (length(g) < 6)" +== 135 +-- truncate_limit: 100 +-- fail - user-defined types are not allowed +CREATE TYPE rf_bug_status AS ENUM ('new', 'open', 'closed') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE rf_bug_status AS ENUM ('new', 'open', 'closed')" +== 136 +-- truncate_limit: 100 +CREATE TABLE rf_bug (id serial, description text, status rf_bug_status) +-- +TABLE: name="rf_bug" schema="" table="rf_bug" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_bug (id serial, description text, status rf_bug_status)" +== 137 +-- truncate_limit: 100 +CREATE PUBLICATION testpub6 FOR TABLE rf_bug WHERE (status = 'open') WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6 FOR TABLE rf_bug WHERE (status = 'open') WITH (publish = 'insert')" +== 138 +-- truncate_limit: 100 +DROP TABLE rf_bug +-- +TABLE: name="rf_bug" schema="" table="rf_bug" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rf_bug" +== 139 +-- truncate_limit: 100 +DROP TYPE rf_bug_status +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE rf_bug_status" +== 140 +-- truncate_limit: 100 +-- fail - row filter expression is not simple +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE (a IN (SELECT generate_series(1,5))) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE (a IN (SELECT generate_series(1, 5)))" +== 141 +-- truncate_limit: 100 +-- fail - system columns are not allowed +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE ('(0,1)'::tid = ctid) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE ('(0,1)'::tid = ctid)" +== 142 +-- truncate_limit: 100 +-- ok - conditional expressions are allowed +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (a IS DOCUMENT) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (a IS DOCUMENT)" +== 143 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (xmlexists('//foo[text() = ''bar'']' PASSING BY VALUE a)) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (xmlexists ('//foo[text() = ''bar'']' ..." +== 144 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (NULLIF(1, 2) = a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((NULLIF(1, 2)) = a)" +== 145 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (CASE a WHEN 5 THEN true ELSE false END) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (CASE a WHEN 5 THEN true ELSE false END)" +== 146 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (COALESCE(b, 'foo') = 'foo') +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (COALESCE(b, 'foo') = 'foo')" +== 147 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (GREATEST(a, 10) > 10) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (GREATEST(a, 10) > 10)" +== 148 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IN (2, 4, 6)) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IN (2, 4, 6))" +== 149 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ARRAY[a] <@ ARRAY[2, 4, 6]) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ARRAY[a] <@ ARRAY[2, 4, 6])" +== 150 +-- truncate_limit: 100 +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ROW(a, 2) IS NULL) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ROW(a, 2) IS NULL)" +== 151 +-- truncate_limit: 100 +-- fail - WHERE not allowed in DROP +ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl1 WHERE (e < 27) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl1 WHERE (e < 27)" +== 152 +-- truncate_limit: 100 +-- fail - cannot ALTER SET table which is a member of a pre-existing schema +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 153 +-- truncate_limit: 100 +CREATE PUBLICATION testpub6 FOR TABLES IN SCHEMA testpub_rf_schema2 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6 FOR TABLES IN SCHEMA testpub_rf_schema2" +== 154 +-- truncate_limit: 100 +-- should be able to set publication with schema and table of the same schema +ALTER PUBLICATION testpub6 SET TABLES IN SCHEMA testpub_rf_schema2, TABLE testpub_rf_schema2.testpub_rf_tbl6 WHERE (i < 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLES IN SCHEMA testpub_rf_schema2, TABLE testpub_rf_schema2.test..." +== 155 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 156 +-- truncate_limit: 100 +DROP TABLE testpub_rf_tbl1 +-- +TABLE: name="testpub_rf_tbl1" schema="" table="testpub_rf_tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_rf_tbl1" +== 157 +-- truncate_limit: 100 +DROP TABLE testpub_rf_tbl2 +-- +TABLE: name="testpub_rf_tbl2" schema="" table="testpub_rf_tbl2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_rf_tbl2" +== 158 +-- truncate_limit: 100 +DROP TABLE testpub_rf_tbl3 +-- +TABLE: name="testpub_rf_tbl3" schema="" table="testpub_rf_tbl3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_rf_tbl3" +== 159 +-- truncate_limit: 100 +DROP TABLE testpub_rf_tbl4 +-- +TABLE: name="testpub_rf_tbl4" schema="" table="testpub_rf_tbl4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_rf_tbl4" +== 160 +-- truncate_limit: 100 +DROP TABLE testpub_rf_tbl5 +-- +TABLE: name="testpub_rf_tbl5" schema="" table="testpub_rf_tbl5" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_rf_tbl5" +== 161 +-- truncate_limit: 100 +DROP TABLE testpub_rf_schema1.testpub_rf_tbl5 +-- +TABLE: name="testpub_rf_schema1.testpub_rf_tbl5" schema="testpub_rf_schema1" table="testpub_rf_tbl5" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_rf_schema1.testpub_rf_tbl5" +== 162 +-- truncate_limit: 100 +DROP TABLE testpub_rf_schema2.testpub_rf_tbl6 +-- +TABLE: name="testpub_rf_schema2.testpub_rf_tbl6" schema="testpub_rf_schema2" table="testpub_rf_tbl6" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_rf_schema2.testpub_rf_tbl6" +== 163 +-- truncate_limit: 100 +DROP SCHEMA testpub_rf_schema1 +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA testpub_rf_schema1" +== 164 +-- truncate_limit: 100 +DROP SCHEMA testpub_rf_schema2 +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA testpub_rf_schema2" +== 165 +-- truncate_limit: 100 +DROP PUBLICATION testpub5 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub5" +== 166 +-- truncate_limit: 100 +DROP PUBLICATION testpub6 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub6" +== 167 +-- truncate_limit: 100 +DROP OPERATOR =#>(integer, integer) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR =#>(int, int)" +== 168 +-- truncate_limit: 100 +DROP FUNCTION testpub_rf_func1(integer, integer) +-- +FUNCTION: name="testpub_rf_func1" function="testpub_rf_func1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testpub_rf_func1(int, int)" +== 169 +-- truncate_limit: 100 +DROP FUNCTION testpub_rf_func2() +-- +FUNCTION: name="testpub_rf_func2" function="testpub_rf_func2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testpub_rf_func2()" +== 170 +-- truncate_limit: 100 +DROP COLLATION user_collation +-- +STMT: DropStmt +TRUNCATED: "DROP COLLATION user_collation" +== 171 +-- truncate_limit: 100 +-- ====================================================== +-- More row filter tests for validating column references +CREATE TABLE rf_tbl_abcd_nopk(a int, b int, c int, d int) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_nopk (a int, b int, c int, d int)" +== 172 +-- truncate_limit: 100 +CREATE TABLE rf_tbl_abcd_pk(a int, b int, c int, d int, PRIMARY KEY(a,b)) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_pk (a int, b int, c int, d int, PRIMARY KEY (a, b))" +== 173 +-- truncate_limit: 100 +CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION by RANGE (a) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION BY RANGE (a)" +== 174 +-- truncate_limit: 100 +CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY) +-- +TABLE: name="rf_tbl_abcd_part_pk_1" schema="" table="rf_tbl_abcd_part_pk_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY)" +== 175 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10)" +== 176 +-- truncate_limit: 100 +-- Case 1. REPLICA IDENTITY DEFAULT (means use primary key or nothing) +-- 1a. REPLICA IDENTITY is DEFAULT and table has a PK. +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 177 +-- truncate_limit: 100 +CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk WHERE (a > 99) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk WHERE (a > 99)" +== 178 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 179 +-- truncate_limit: 100 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 180 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (b > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (b > 99)" +== 181 +-- truncate_limit: 100 +-- ok - "b" is a PK col +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 182 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99)" +== 183 +-- truncate_limit: 100 +-- fail - "c" is not part of the PK +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 184 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (d > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (d > 99)" +== 185 +-- truncate_limit: 100 +-- fail - "d" is not part of the PK +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 186 +-- truncate_limit: 100 +-- 1b. REPLICA IDENTITY is DEFAULT and table has no PK +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99)" +== 187 +-- truncate_limit: 100 +-- fail - "a" is not part of REPLICA IDENTITY +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 188 +-- truncate_limit: 100 +-- Case 2. REPLICA IDENTITY FULL +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL" +== 189 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL" +== 190 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99)" +== 191 +-- truncate_limit: 100 +-- ok - "c" is in REPLICA IDENTITY now even though not in PK +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 192 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99)" +== 193 +-- truncate_limit: 100 +-- ok - "a" is in REPLICA IDENTITY now +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 194 +-- truncate_limit: 100 +-- Case 3. REPLICA IDENTITY NOTHING +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING" +== 195 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING" +== 196 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99)" +== 197 +-- truncate_limit: 100 +-- fail - "a" is in PK but it is not part of REPLICA IDENTITY NOTHING +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 198 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99)" +== 199 +-- truncate_limit: 100 +-- fail - "c" is not in PK and not in REPLICA IDENTITY NOTHING +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 200 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99)" +== 201 +-- truncate_limit: 100 +-- fail - "a" is not in REPLICA IDENTITY NOTHING +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 202 +-- truncate_limit: 100 +-- Case 4. REPLICA IDENTITY INDEX +ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL" +== 203 +-- truncate_limit: 100 +CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk(c) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk USING btree (c)" +== 204 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c" +== 205 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL" +== 206 +-- truncate_limit: 100 +CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk(c) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk USING btree (c)" +== 207 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c" +== 208 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99)" +== 209 +-- truncate_limit: 100 +-- fail - "a" is in PK but it is not part of REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 210 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99)" +== 211 +-- truncate_limit: 100 +-- ok - "c" is not in PK but it is part of REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 212 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99)" +== 213 +-- truncate_limit: 100 +-- fail - "a" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 214 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (c > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (c > 99)" +== 215 +-- truncate_limit: 100 +-- ok - "c" is part of REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 216 +-- truncate_limit: 100 +-- Tests for partitioned table + +-- set PUBLISH_VIA_PARTITION_ROOT to false and test row filter for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 217 +-- truncate_limit: 100 +-- fail - cannot use row filter for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99)" +== 218 +-- truncate_limit: 100 +-- ok - can use row filter for partition +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (a > 99)" +== 219 +-- truncate_limit: 100 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 220 +-- truncate_limit: 100 +-- set PUBLISH_VIA_PARTITION_ROOT to true and test row filter for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 1)" +== 221 +-- truncate_limit: 100 +-- ok - can use row filter for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99)" +== 222 +-- truncate_limit: 100 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 223 +-- truncate_limit: 100 +-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any row filter is +-- used for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 224 +-- truncate_limit: 100 +-- remove partitioned table's row filter +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk" +== 225 +-- truncate_limit: 100 +-- ok - we don't have row filter for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 226 +-- truncate_limit: 100 +-- Now change the root filter to use a column "b" +-- (which is not in the replica identity) +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99)" +== 227 +-- truncate_limit: 100 +-- ok - we don't have row filter for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 228 +-- truncate_limit: 100 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 229 +-- truncate_limit: 100 +-- set PUBLISH_VIA_PARTITION_ROOT to true +-- can use row filter for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 1)" +== 230 +-- truncate_limit: 100 +-- ok - can use row filter for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (b > 99) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (b > 99)" +== 231 +-- truncate_limit: 100 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 232 +-- truncate_limit: 100 +DROP PUBLICATION testpub6 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub6" +== 233 +-- truncate_limit: 100 +DROP TABLE rf_tbl_abcd_pk +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rf_tbl_abcd_pk" +== 234 +-- truncate_limit: 100 +DROP TABLE rf_tbl_abcd_nopk +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rf_tbl_abcd_nopk" +== 235 +-- truncate_limit: 100 +DROP TABLE rf_tbl_abcd_part_pk +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rf_tbl_abcd_part_pk" +== 236 +-- truncate_limit: 100 +-- ====================================================== + +-- fail - duplicate tables are not allowed if that table has any column lists +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 237 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1 (a), testpub_tbl1 WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1(a), TABLE testpub_tbl1 WITH (publish = 'in..." +== 238 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1, testpub_tbl1 (a) WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1, TABLE testpub_tbl1(a) WITH (publish = 'in..." +== 239 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 240 +-- truncate_limit: 100 +-- test for column lists +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 241 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1" +== 242 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_fortable_insert WITH (publish = 'insert') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortable_insert WITH (publish = 'insert')" +== 243 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 244 +-- truncate_limit: 100 +CREATE TABLE testpub_tbl5 (a int PRIMARY KEY, b text, c text, + d int generated always as (a + length(b)) stored) +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl5 (a int PRIMARY KEY, b text, c text, d int GENERATED ALWAYS AS (a + leng..." +== 245 +-- truncate_limit: 100 +-- error: column "x" does not exist +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, x) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5(a, x)" +== 246 +-- truncate_limit: 100 +-- error: replica identity "a" not included in the column list +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (b, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5(b, c)" +== 247 +-- truncate_limit: 100 +UPDATE testpub_tbl5 SET a = 1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl5 SET a = 1" +== 248 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5" +== 249 +-- truncate_limit: 100 +-- error: generated column "d" can't be in list +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, d) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5(a, d)" +== 250 +-- truncate_limit: 100 +-- error: system attributes "ctid" not allowed in column list +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, ctid) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5(a, ctid)" +== 251 +-- truncate_limit: 100 +-- ok +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5(a, c)" +== 252 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl5 DROP COLUMN c +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl5 DROP c" +== 253 +-- truncate_limit: 100 +-- no dice +-- ok: for insert-only publication, any column list is acceptable +ALTER PUBLICATION testpub_fortable_insert ADD TABLE testpub_tbl5 (b, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable_insert ADD TABLE testpub_tbl5(b, c)" +== 254 +-- truncate_limit: 100 +/* not all replica identities are good enough */ +CREATE UNIQUE INDEX testpub_tbl5_b_key ON testpub_tbl5 (b, c) +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX testpub_tbl5_b_key ON testpub_tbl5 USING btree (b, c)" +== 255 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl5 ALTER b SET NOT NULL, ALTER c SET NOT NULL +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl5 ALTER COLUMN b SET NOT NULL, ALTER COLUMN c SET NOT NULL" +== 256 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key" +== 257 +-- truncate_limit: 100 +-- error: replica identity (b,c) is not covered by column list (a, c) +UPDATE testpub_tbl5 SET a = 1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl5 SET a = 1" +== 258 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5" +== 259 +-- truncate_limit: 100 +-- error: change the replica identity to "b", and column list to (a, c) +-- then update fails, because (a, c) does not cover replica identity +ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key" +== 260 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5(a, c)" +== 261 +-- truncate_limit: 100 +UPDATE testpub_tbl5 SET a = 1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl5 SET a = 1" +== 262 +-- truncate_limit: 100 +/* But if upd/del are not published, it works OK */ +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 263 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_table_ins WITH (publish = 'insert, truncate') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_table_ins WITH (publish = 'insert, truncate')" +== 264 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 265 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_table_ins ADD TABLE testpub_tbl5 (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_table_ins ADD TABLE testpub_tbl5(a)" +== 266 +-- truncate_limit: 100 +-- ok + +-- error: cannot work with deferrable primary keys +CREATE TABLE testpub_tbl5d (a int PRIMARY KEY DEFERRABLE) +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl5d (a int PRIMARY KEY DEFERRABLE)" +== 267 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5d +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5d" +== 268 +-- truncate_limit: 100 +UPDATE testpub_tbl5d SET a = 1 +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl5d SET a = 1" +== 269 +-- truncate_limit: 100 +/* but works fine with FULL replica identity */ +ALTER TABLE testpub_tbl5d REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl5d REPLICA IDENTITY FULL" +== 270 +-- truncate_limit: 100 +UPDATE testpub_tbl5d SET a = 1 +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl5d SET a = 1" +== 271 +-- truncate_limit: 100 +DROP TABLE testpub_tbl5d +-- +TABLE: name="testpub_tbl5d" schema="" table="testpub_tbl5d" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl5d" +== 272 +-- truncate_limit: 100 +-- tests with REPLICA IDENTITY FULL +CREATE TABLE testpub_tbl6 (a int, b text, c text) +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl6 (a int, b text, c text)" +== 273 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl6 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl6 REPLICA IDENTITY FULL" +== 274 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6 (a, b, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6(a, b, c)" +== 275 +-- truncate_limit: 100 +UPDATE testpub_tbl6 SET a = 1 +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl6 SET a = 1" +== 276 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl6 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl6" +== 277 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6" +== 278 +-- truncate_limit: 100 +-- ok +UPDATE testpub_tbl6 SET a = 1 +-- +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl6 SET a = 1" +== 279 +-- truncate_limit: 100 +-- make sure changing the column list is propagated to the catalog +CREATE TABLE testpub_tbl7 (a int primary key, b text, c text) +-- +TABLE: name="testpub_tbl7" schema="" table="testpub_tbl7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl7 (a int PRIMARY KEY, b text, c text)" +== 280 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl7 (a, b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl7(a, b)" +== 281 +-- truncate_limit: 100 +-- ok: the column list is the same, we should skip this table (or at least not fail) +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7 (a, b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7(a, b)" +== 282 +-- truncate_limit: 100 +-- ok: the column list changes, make sure the catalog gets updated +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7 (a, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7(a, c)" +== 283 +-- truncate_limit: 100 +-- column list for partitioned tables has to cover replica identities for +-- all child relations +CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a)" +== 284 +-- truncate_limit: 100 +-- first partition has replica identity "a" +CREATE TABLE testpub_tbl8_0 PARTITION OF testpub_tbl8 FOR VALUES WITH (modulus 2, remainder 0) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl8_0 PARTITION OF testpub_tbl8 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 285 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a)" +== 286 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey" +== 287 +-- truncate_limit: 100 +-- second partition has replica identity "b" +CREATE TABLE testpub_tbl8_1 PARTITION OF testpub_tbl8 FOR VALUES WITH (modulus 2, remainder 1) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl8_1 PARTITION OF testpub_tbl8 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 288 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (b) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (b)" +== 289 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey" +== 290 +-- truncate_limit: 100 +-- ok: column list covers both "a" and "b" +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 291 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_col_list FOR TABLE testpub_tbl8 (a, b) WITH (publish_via_partition_root = 'true') +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_col_list FOR TABLE testpub_tbl8(a, b) WITH (publish_via_partition_root..." +== 292 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 293 +-- truncate_limit: 100 +-- ok: the same thing, but try plain ADD TABLE +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8" +== 294 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8(a, b)" +== 295 +-- truncate_limit: 100 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl8 SET a = 1" +== 296 +-- truncate_limit: 100 +-- failure: column list does not cover replica identity for the second partition +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8" +== 297 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8(a, c)" +== 298 +-- truncate_limit: 100 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl8 SET a = 1" +== 299 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8" +== 300 +-- truncate_limit: 100 +-- failure: one of the partitions has REPLICA IDENTITY FULL +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL" +== 301 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8(a, c)" +== 302 +-- truncate_limit: 100 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl8 SET a = 1" +== 303 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8" +== 304 +-- truncate_limit: 100 +-- add table and then try changing replica identity +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey" +== 305 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8(a, b)" +== 306 +-- truncate_limit: 100 +-- failure: replica identity full can't be used with a column list +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL" +== 307 +-- truncate_limit: 100 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl8 SET a = 1" +== 308 +-- truncate_limit: 100 +-- failure: replica identity has to be covered by the column list +ALTER TABLE testpub_tbl8_1 DROP CONSTRAINT testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 DROP CONSTRAINT testpub_tbl8_1_pkey" +== 309 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c)" +== 310 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey" +== 311 +-- truncate_limit: 100 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl8 SET a = 1" +== 312 +-- truncate_limit: 100 +DROP TABLE testpub_tbl8 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl8" +== 313 +-- truncate_limit: 100 +-- column list for partitioned tables has to cover replica identities for +-- all child relations +CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a)" +== 314 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8(a, b)" +== 315 +-- truncate_limit: 100 +-- first partition has replica identity "a" +CREATE TABLE testpub_tbl8_0 (a int, b text, c text) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl8_0 (a int, b text, c text)" +== 316 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a) +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a)" +== 317 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey" +== 318 +-- truncate_limit: 100 +-- second partition has replica identity "b" +CREATE TABLE testpub_tbl8_1 (a int, b text, c text) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl8_1 (a int, b text, c text)" +== 319 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c) +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c)" +== 320 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey +-- +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey" +== 321 +-- truncate_limit: 100 +-- ok: attaching first partition works, because (a) is in column list +ALTER TABLE testpub_tbl8 ATTACH PARTITION testpub_tbl8_0 FOR VALUES WITH (modulus 2, remainder 0) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8 ATTACH PARTITION testpub_tbl8_0 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 322 +-- truncate_limit: 100 +-- failure: second partition has replica identity (c), which si not in column list +ALTER TABLE testpub_tbl8 ATTACH PARTITION testpub_tbl8_1 FOR VALUES WITH (modulus 2, remainder 1) +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8 ATTACH PARTITION testpub_tbl8_1 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 323 +-- truncate_limit: 100 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl8 SET a = 1" +== 324 +-- truncate_limit: 100 +-- failure: changing replica identity to FULL for partition fails, because +-- of the column list on the parent +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY FULL +-- +TABLE: name="testpub_tbl8_0" schema="" table="testpub_tbl8_0" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY FULL" +== 325 +-- truncate_limit: 100 +UPDATE testpub_tbl8 SET a = 1 +-- +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl8 SET a = 1" +== 326 +-- truncate_limit: 100 +-- test that using column list for table is disallowed if any schemas are +-- part of the publication +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 327 +-- truncate_limit: 100 +-- failure - cannot use column list and schema together +CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a)" +== 328 +-- truncate_limit: 100 +-- ok - only publish schema +CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public" +== 329 +-- truncate_limit: 100 +-- failure - add a table with column list when there is already a schema in the +-- publication +ALTER PUBLICATION testpub_tbl9 ADD TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_tbl9 ADD TABLE public.testpub_tbl7(a)" +== 330 +-- truncate_limit: 100 +-- ok - only publish table with column list +ALTER PUBLICATION testpub_tbl9 SET TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_tbl9 SET TABLE public.testpub_tbl7(a)" +== 331 +-- truncate_limit: 100 +-- failure - specify a schema when there is already a column list in the +-- publication +ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public" +== 332 +-- truncate_limit: 100 +-- failure - cannot SET column list and schema together +ALTER PUBLICATION testpub_tbl9 SET TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_tbl9 SET TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a)" +== 333 +-- truncate_limit: 100 +-- ok - drop table +ALTER PUBLICATION testpub_tbl9 DROP TABLE public.testpub_tbl7 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_tbl9 DROP TABLE public.testpub_tbl7" +== 334 +-- truncate_limit: 100 +-- failure - cannot ADD column list and schema together +ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a)" +== 335 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 336 +-- truncate_limit: 100 +DROP TABLE testpub_tbl5, testpub_tbl6, testpub_tbl7, testpub_tbl8, testpub_tbl8_1 +-- +TABLE: name="testpub_tbl5" schema="" table="testpub_tbl5" ctx=DDL +TABLE: name="testpub_tbl6" schema="" table="testpub_tbl6" ctx=DDL +TABLE: name="testpub_tbl7" schema="" table="testpub_tbl7" ctx=DDL +TABLE: name="testpub_tbl8" schema="" table="testpub_tbl8" ctx=DDL +TABLE: name="testpub_tbl8_1" schema="" table="testpub_tbl8_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl5, testpub_tbl6, testpub_tbl7, testpub_tbl8, testpub_tbl8_1" +== 337 +-- truncate_limit: 100 +DROP PUBLICATION testpub_table_ins, testpub_fortable, testpub_fortable_insert, testpub_col_list, testpub_tbl9 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_table_ins, testpub_fortable, testpub_fortable_insert, testpub_col_list, ..." +== 338 +-- truncate_limit: 100 +-- ====================================================== + +-- Test combination of column list and row filter +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 339 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_both_filters +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_both_filters" +== 340 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 341 +-- truncate_limit: 100 +CREATE TABLE testpub_tbl_both_filters (a int, b int, c int, PRIMARY KEY (a,c)) +-- +TABLE: name="testpub_tbl_both_filters" schema="" table="testpub_tbl_both_filters" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl_both_filters (a int, b int, c int, PRIMARY KEY (a, c))" +== 342 +-- truncate_limit: 100 +ALTER TABLE testpub_tbl_both_filters REPLICA IDENTITY USING INDEX testpub_tbl_both_filters_pkey +-- +TABLE: name="testpub_tbl_both_filters" schema="" table="testpub_tbl_both_filters" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testpub_tbl_both_filters REPLICA IDENTITY USING INDEX testpub_tbl_both_filters_pkey" +== 343 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_both_filters ADD TABLE testpub_tbl_both_filters (a,c) WHERE (c != 1) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_both_filters ADD TABLE testpub_tbl_both_filters(a, c) WHERE (c <> 1)" +== 344 +-- truncate_limit: 100 +DROP TABLE testpub_tbl_both_filters +-- +TABLE: name="testpub_tbl_both_filters" schema="" table="testpub_tbl_both_filters" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl_both_filters" +== 345 +-- truncate_limit: 100 +DROP PUBLICATION testpub_both_filters +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_both_filters" +== 346 +-- truncate_limit: 100 +-- ====================================================== + +-- More column list tests for validating column references +CREATE TABLE rf_tbl_abcd_nopk(a int, b int, c int, d int) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_nopk (a int, b int, c int, d int)" +== 347 +-- truncate_limit: 100 +CREATE TABLE rf_tbl_abcd_pk(a int, b int, c int, d int, PRIMARY KEY(a,b)) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_pk (a int, b int, c int, d int, PRIMARY KEY (a, b))" +== 348 +-- truncate_limit: 100 +CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION by RANGE (a) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION BY RANGE (a)" +== 349 +-- truncate_limit: 100 +CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY) +-- +TABLE: name="rf_tbl_abcd_part_pk_1" schema="" table="rf_tbl_abcd_part_pk_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY)" +== 350 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10) +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10)" +== 351 +-- truncate_limit: 100 +-- Case 1. REPLICA IDENTITY DEFAULT (means use primary key or nothing) + +-- 1a. REPLICA IDENTITY is DEFAULT and table has a PK. +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 352 +-- truncate_limit: 100 +CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk (a, b) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk(a, b)" +== 353 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 354 +-- truncate_limit: 100 +-- ok - (a,b) covers all PK cols +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 355 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a, b, c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(a, b, c)" +== 356 +-- truncate_limit: 100 +-- ok - (a,b,c) covers all PK cols +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 357 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(a)" +== 358 +-- truncate_limit: 100 +-- fail - "b" is missing from the column list +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 359 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(b)" +== 360 +-- truncate_limit: 100 +-- fail - "a" is missing from the column list +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 361 +-- truncate_limit: 100 +-- 1b. REPLICA IDENTITY is DEFAULT and table has no PK +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk(a)" +== 362 +-- truncate_limit: 100 +-- ok - there's no replica identity, so any column list works +-- note: it fails anyway, just a bit later because UPDATE requires RI +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 363 +-- truncate_limit: 100 +-- Case 2. REPLICA IDENTITY FULL +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL" +== 364 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL" +== 365 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(c)" +== 366 +-- truncate_limit: 100 +-- fail - with REPLICA IDENTITY FULL no column list is allowed +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 367 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a, b, c, d) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk(a, b, c, d)" +== 368 +-- truncate_limit: 100 +-- fail - with REPLICA IDENTITY FULL no column list is allowed +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 369 +-- truncate_limit: 100 +-- Case 3. REPLICA IDENTITY NOTHING +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING" +== 370 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING" +== 371 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(a)" +== 372 +-- truncate_limit: 100 +-- ok - REPLICA IDENTITY NOTHING means all column lists are valid +-- it still fails later because without RI we can't replicate updates +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 373 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a, b, c, d) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(a, b, c, d)" +== 374 +-- truncate_limit: 100 +-- ok - REPLICA IDENTITY NOTHING means all column lists are valid +-- it still fails later because without RI we can't replicate updates +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 375 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (d) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk(d)" +== 376 +-- truncate_limit: 100 +-- ok - REPLICA IDENTITY NOTHING means all column lists are valid +-- it still fails later because without RI we can't replicate updates +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 377 +-- truncate_limit: 100 +-- Case 4. REPLICA IDENTITY INDEX +ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL" +== 378 +-- truncate_limit: 100 +CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk(c) +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk USING btree (c)" +== 379 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c" +== 380 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL" +== 381 +-- truncate_limit: 100 +CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk(c) +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk USING btree (c)" +== 382 +-- truncate_limit: 100 +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c" +== 383 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(a)" +== 384 +-- truncate_limit: 100 +-- fail - column list "a" does not cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 385 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk(c)" +== 386 +-- truncate_limit: 100 +-- ok - column list "c" does cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_pk SET a = 1" +== 387 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk(a)" +== 388 +-- truncate_limit: 100 +-- fail - column list "a" does not cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 389 +-- truncate_limit: 100 +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (c) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk(c)" +== 390 +-- truncate_limit: 100 +-- ok - column list "c" does cover the REPLICA IDENTITY INDEX on "c" +UPDATE rf_tbl_abcd_nopk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_nopk SET a = 1" +== 391 +-- truncate_limit: 100 +-- Tests for partitioned table + +-- set PUBLISH_VIA_PARTITION_ROOT to false and test column list for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 392 +-- truncate_limit: 100 +-- fail - cannot use column list for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk(a)" +== 393 +-- truncate_limit: 100 +-- ok - can use column list for partition +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1(a)" +== 394 +-- truncate_limit: 100 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 395 +-- truncate_limit: 100 +-- set PUBLISH_VIA_PARTITION_ROOT to true and test column list for partitioned +-- table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 1)" +== 396 +-- truncate_limit: 100 +-- ok - can use column list for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk(a)" +== 397 +-- truncate_limit: 100 +-- ok - "a" is a PK col +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 398 +-- truncate_limit: 100 +-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any column list is +-- used for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 399 +-- truncate_limit: 100 +-- remove partitioned table's column list +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk" +== 400 +-- truncate_limit: 100 +-- ok - we don't have column list for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 401 +-- truncate_limit: 100 +-- Now change the root column list to use a column "b" +-- (which is not in the replica identity) +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1(b)" +== 402 +-- truncate_limit: 100 +-- ok - we don't have column list for partitioned table. +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 0)" +== 403 +-- truncate_limit: 100 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 404 +-- truncate_limit: 100 +-- set PUBLISH_VIA_PARTITION_ROOT to true +-- can use column list for partitioned table +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET (publish_via_partition_root = 1)" +== 405 +-- truncate_limit: 100 +-- ok - can use column list for partitioned table +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (b) +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk(b)" +== 406 +-- truncate_limit: 100 +-- fail - "b" is not in REPLICA IDENTITY INDEX +UPDATE rf_tbl_abcd_part_pk SET a = 1 +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rf_tbl_abcd_part_pk SET a = 1" +== 407 +-- truncate_limit: 100 +DROP PUBLICATION testpub6 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub6" +== 408 +-- truncate_limit: 100 +DROP TABLE rf_tbl_abcd_pk +-- +TABLE: name="rf_tbl_abcd_pk" schema="" table="rf_tbl_abcd_pk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rf_tbl_abcd_pk" +== 409 +-- truncate_limit: 100 +DROP TABLE rf_tbl_abcd_nopk +-- +TABLE: name="rf_tbl_abcd_nopk" schema="" table="rf_tbl_abcd_nopk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rf_tbl_abcd_nopk" +== 410 +-- truncate_limit: 100 +DROP TABLE rf_tbl_abcd_part_pk +-- +TABLE: name="rf_tbl_abcd_part_pk" schema="" table="rf_tbl_abcd_part_pk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rf_tbl_abcd_part_pk" +== 411 +-- truncate_limit: 100 +-- ====================================================== + +-- Test cache invalidation FOR ALL TABLES publication +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 412 +-- truncate_limit: 100 +CREATE TABLE testpub_tbl4(a int) +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_tbl4 (a int)" +== 413 +-- truncate_limit: 100 +INSERT INTO testpub_tbl4 values(1) +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testpub_tbl4 VALUES (1)" +== 414 +-- truncate_limit: 100 +UPDATE testpub_tbl4 set a = 2 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl4 SET a = 2" +== 415 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_foralltables FOR ALL TABLES +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_foralltables FOR ALL TABLES" +== 416 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 417 +-- truncate_limit: 100 +-- fail missing REPLICA IDENTITY +UPDATE testpub_tbl4 set a = 3 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl4 SET a = 3" +== 418 +-- truncate_limit: 100 +DROP PUBLICATION testpub_foralltables +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_foralltables" +== 419 +-- truncate_limit: 100 +-- should pass after dropping the publication +UPDATE testpub_tbl4 set a = 3 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE testpub_tbl4 SET a = 3" +== 420 +-- truncate_limit: 100 +DROP TABLE testpub_tbl4 +-- +TABLE: name="testpub_tbl4" schema="" table="testpub_tbl4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl4" +== 421 +-- truncate_limit: 100 +-- fail - view +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view" +== 422 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE testpub_temptbl(a int) +-- +TABLE: name="testpub_temptbl" schema="" table="testpub_temptbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE testpub_temptbl (a int)" +== 423 +-- truncate_limit: 100 +-- fail - temporary table +CREATE PUBLICATION testpub_fortemptbl FOR TABLE testpub_temptbl +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortemptbl FOR TABLE testpub_temptbl" +== 424 +-- truncate_limit: 100 +DROP TABLE testpub_temptbl +-- +TABLE: name="testpub_temptbl" schema="" table="testpub_temptbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_temptbl" +== 425 +-- truncate_limit: 100 +CREATE UNLOGGED TABLE testpub_unloggedtbl(a int) +-- +TABLE: name="testpub_unloggedtbl" schema="" table="testpub_unloggedtbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE testpub_unloggedtbl (a int)" +== 426 +-- truncate_limit: 100 +-- fail - unlogged table +CREATE PUBLICATION testpub_forunloggedtbl FOR TABLE testpub_unloggedtbl +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forunloggedtbl FOR TABLE testpub_unloggedtbl" +== 427 +-- truncate_limit: 100 +DROP TABLE testpub_unloggedtbl +-- +TABLE: name="testpub_unloggedtbl" schema="" table="testpub_unloggedtbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_unloggedtbl" +== 428 +-- truncate_limit: 100 +-- fail - system table +CREATE PUBLICATION testpub_forsystemtbl FOR TABLE pg_publication +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forsystemtbl FOR TABLE pg_publication" +== 429 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 430 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1, pub_test.testpub_nopk +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1, TABLE pub_test.testpub_nopk" +== 431 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 432 +-- truncate_limit: 100 +-- fail - already added +ALTER PUBLICATION testpub_fortbl ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_fortbl ADD TABLE testpub_tbl1" +== 433 +-- truncate_limit: 100 +-- fail - already added +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1" +== 434 +-- truncate_limit: 100 +-- fail - view +ALTER PUBLICATION testpub_default ADD TABLE testpub_view +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default ADD TABLE testpub_view" +== 435 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default ADD TABLE testpub_tbl1" +== 436 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default SET TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default SET TABLE testpub_tbl1" +== 437 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_nopk" +== 438 +-- truncate_limit: 100 +ALTER PUBLICATION testpib_ins_trunct ADD TABLE pub_test.testpub_nopk, testpub_tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpib_ins_trunct ADD TABLE pub_test.testpub_nopk, TABLE testpub_tbl1" +== 439 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default DROP TABLE testpub_tbl1, pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default DROP TABLE testpub_tbl1, TABLE pub_test.testpub_nopk" +== 440 +-- truncate_limit: 100 +-- fail - nonexistent +ALTER PUBLICATION testpub_default DROP TABLE pub_test.testpub_nopk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default DROP TABLE pub_test.testpub_nopk" +== 441 +-- truncate_limit: 100 +-- verify relation cache invalidation when a primary key is added using +-- an existing index +CREATE TABLE pub_test.testpub_addpk (id int not null, data int) +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_test.testpub_addpk (id int NOT NULL, data int)" +== 442 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_addpk +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_addpk" +== 443 +-- truncate_limit: 100 +INSERT INTO pub_test.testpub_addpk VALUES(1, 11) +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pub_test.testpub_addpk VALUES (1, 11)" +== 444 +-- truncate_limit: 100 +CREATE UNIQUE INDEX testpub_addpk_id_idx ON pub_test.testpub_addpk(id) +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX testpub_addpk_id_idx ON pub_test.testpub_addpk USING btree (id)" +== 445 +-- truncate_limit: 100 +-- fail: +UPDATE pub_test.testpub_addpk SET id = 2 +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_test.testpub_addpk SET id = 2" +== 446 +-- truncate_limit: 100 +ALTER TABLE pub_test.testpub_addpk ADD PRIMARY KEY USING INDEX testpub_addpk_id_idx +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE pub_test.testpub_addpk ADD PRIMARY KEY USING INDEX testpub_addpk_id_idx" +== 447 +-- truncate_limit: 100 +-- now it should work: +UPDATE pub_test.testpub_addpk SET id = 2 +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_test.testpub_addpk SET id = 2" +== 448 +-- truncate_limit: 100 +DROP TABLE pub_test.testpub_addpk +-- +TABLE: name="pub_test.testpub_addpk" schema="pub_test" table="testpub_addpk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pub_test.testpub_addpk" +== 449 +-- truncate_limit: 100 +-- permissions +SET ROLE regress_publication_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user2" +== 450 +-- truncate_limit: 100 +CREATE PUBLICATION testpub2 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub2" +== 451 +-- truncate_limit: 100 +-- fail + +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user" +== 452 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE regression TO regress_publication_user2 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_publication_user2" +== 453 +-- truncate_limit: 100 +SET ROLE regress_publication_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user2" +== 454 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 455 +-- truncate_limit: 100 +CREATE PUBLICATION testpub2 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub2" +== 456 +-- truncate_limit: 100 +-- ok +CREATE PUBLICATION testpub3 FOR TABLES IN SCHEMA pub_test +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub3 FOR TABLES IN SCHEMA pub_test" +== 457 +-- truncate_limit: 100 +-- fail +CREATE PUBLICATION testpub3 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub3" +== 458 +-- truncate_limit: 100 +-- ok +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 459 +-- truncate_limit: 100 +ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1" +== 460 +-- truncate_limit: 100 +-- fail +ALTER PUBLICATION testpub3 ADD TABLES IN SCHEMA pub_test +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub3 ADD TABLES IN SCHEMA pub_test" +== 461 +-- truncate_limit: 100 +-- fail + +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user" +== 462 +-- truncate_limit: 100 +GRANT regress_publication_user TO regress_publication_user2 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_publication_user TO regress_publication_user2" +== 463 +-- truncate_limit: 100 +SET ROLE regress_publication_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user2" +== 464 +-- truncate_limit: 100 +ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1" +== 465 +-- truncate_limit: 100 +-- ok + +DROP PUBLICATION testpub2 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub2" +== 466 +-- truncate_limit: 100 +DROP PUBLICATION testpub3 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub3" +== 467 +-- truncate_limit: 100 +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user" +== 468 +-- truncate_limit: 100 +CREATE ROLE regress_publication_user3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_publication_user3" +== 469 +-- truncate_limit: 100 +GRANT regress_publication_user2 TO regress_publication_user3 +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_publication_user2 TO regress_publication_user3" +== 470 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 471 +-- truncate_limit: 100 +CREATE PUBLICATION testpub4 FOR TABLES IN SCHEMA pub_test +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub4 FOR TABLES IN SCHEMA pub_test" +== 472 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 473 +-- truncate_limit: 100 +ALTER PUBLICATION testpub4 OWNER TO regress_publication_user3 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER PUBLICATION testpub4 OWNER TO regress_publication_user3" +== 474 +-- truncate_limit: 100 +SET ROLE regress_publication_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user3" +== 475 +-- truncate_limit: 100 +-- fail - new owner must be superuser +ALTER PUBLICATION testpub4 owner to regress_publication_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER PUBLICATION testpub4 OWNER TO regress_publication_user2" +== 476 +-- truncate_limit: 100 +-- fail +ALTER PUBLICATION testpub4 owner to regress_publication_user +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER PUBLICATION testpub4 OWNER TO regress_publication_user" +== 477 +-- truncate_limit: 100 +-- ok + +SET ROLE regress_publication_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user" +== 478 +-- truncate_limit: 100 +DROP PUBLICATION testpub4 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub4" +== 479 +-- truncate_limit: 100 +DROP ROLE regress_publication_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_publication_user3" +== 480 +-- truncate_limit: 100 +REVOKE CREATE ON DATABASE regression FROM regress_publication_user2 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE create ON DATABASE regression FROM regress_publication_user2" +== 481 +-- truncate_limit: 100 +DROP TABLE testpub_parted +-- +TABLE: name="testpub_parted" schema="" table="testpub_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_parted" +== 482 +-- truncate_limit: 100 +DROP TABLE testpub_tbl1 +-- +TABLE: name="testpub_tbl1" schema="" table="testpub_tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_tbl1" +== 483 +-- truncate_limit: 100 +-- fail - must be owner of publication +SET ROLE regress_publication_user_dummy +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_publication_user_dummy" +== 484 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default RENAME TO testpub_dummy +-- +STMT: RenameStmt +TRUNCATED: "ALTER PUBLICATION testpub_default RENAME TO testpub_dummy" +== 485 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 486 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default RENAME TO testpub_foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER PUBLICATION testpub_default RENAME TO testpub_foo" +== 487 +-- truncate_limit: 100 +-- rename back to keep the rest simple +ALTER PUBLICATION testpub_foo RENAME TO testpub_default +-- +STMT: RenameStmt +TRUNCATED: "ALTER PUBLICATION testpub_foo RENAME TO testpub_default" +== 488 +-- truncate_limit: 100 +ALTER PUBLICATION testpub_default OWNER TO regress_publication_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER PUBLICATION testpub_default OWNER TO regress_publication_user2" +== 489 +-- truncate_limit: 100 +-- adding schemas and tables +CREATE SCHEMA pub_test1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pub_test1" +== 490 +-- truncate_limit: 100 +CREATE SCHEMA pub_test2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pub_test2" +== 491 +-- truncate_limit: 100 +CREATE SCHEMA pub_test3 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pub_test3" +== 492 +-- truncate_limit: 100 +CREATE SCHEMA "CURRENT_SCHEMA" +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA \"CURRENT_SCHEMA\"" +== 493 +-- truncate_limit: 100 +CREATE TABLE pub_test1.tbl (id int, data text) +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_test1.tbl (id int, data text)" +== 494 +-- truncate_limit: 100 +CREATE TABLE pub_test1.tbl1 (id serial primary key, data text) +-- +TABLE: name="pub_test1.tbl1" schema="pub_test1" table="tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_test1.tbl1 (id serial PRIMARY KEY, data text)" +== 495 +-- truncate_limit: 100 +CREATE TABLE pub_test2.tbl1 (id serial primary key, data text) +-- +TABLE: name="pub_test2.tbl1" schema="pub_test2" table="tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_test2.tbl1 (id serial PRIMARY KEY, data text)" +== 496 +-- truncate_limit: 100 +CREATE TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"(id int) +-- +TABLE: name="\"CURRENT_SCHEMA\".\"CURRENT_SCHEMA\"" schema="CURRENT_SCHEMA" table="CURRENT_SCHEMA" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE \"CURRENT_SCHEMA\".\"CURRENT_SCHEMA\" (id int)" +== 497 +-- truncate_limit: 100 +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 498 +-- truncate_limit: 100 +CREATE PUBLICATION testpub1_forschema FOR TABLES IN SCHEMA pub_test1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub1_forschema FOR TABLES IN SCHEMA pub_test1" +== 499 +-- truncate_limit: 100 +CREATE PUBLICATION testpub2_forschema FOR TABLES IN SCHEMA pub_test1, pub_test2, pub_test3 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub2_forschema FOR TABLES IN SCHEMA pub_test1, TABLES IN SCHEMA pub_test2,..." +== 500 +-- truncate_limit: 100 +-- check create publication on CURRENT_SCHEMA +CREATE PUBLICATION testpub3_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub3_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA" +== 501 +-- truncate_limit: 100 +CREATE PUBLICATION testpub4_forschema FOR TABLES IN SCHEMA "CURRENT_SCHEMA" +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub4_forschema FOR TABLES IN SCHEMA \"CURRENT_SCHEMA\"" +== 502 +-- truncate_limit: 100 +CREATE PUBLICATION testpub5_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA, "CURRENT_SCHEMA" +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub5_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA, TABLES IN SCHEMA \"CURR..." +== 503 +-- truncate_limit: 100 +CREATE PUBLICATION testpub6_forschema FOR TABLES IN SCHEMA "CURRENT_SCHEMA", CURRENT_SCHEMA +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub6_forschema FOR TABLES IN SCHEMA \"CURRENT_SCHEMA\", TABLES IN SCHEMA CUR..." +== 504 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_fortable FOR TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA" +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortable FOR TABLE \"CURRENT_SCHEMA\".\"CURRENT_SCHEMA\"" +== 505 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 506 +-- truncate_limit: 100 +-- check create publication on CURRENT_SCHEMA where search_path is not set +SET SEARCH_PATH='' +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO ''" +== 507 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA" +== 508 +-- truncate_limit: 100 +RESET SEARCH_PATH +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 509 +-- truncate_limit: 100 +-- check create publication on CURRENT_SCHEMA where TABLE/TABLES in SCHEMA +-- is not specified +CREATE PUBLICATION testpub_forschema1 FOR CURRENT_SCHEMA +-- +ERROR: invalid publication object list +CURSORPOS: 138 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 510 +-- truncate_limit: 100 +-- check create publication on CURRENT_SCHEMA along with FOR TABLE +CREATE PUBLICATION testpub_forschema1 FOR TABLE CURRENT_SCHEMA +-- +ERROR: syntax error at or near "CURRENT_SCHEMA" +CURSORPOS: 116 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 511 +-- truncate_limit: 100 +-- check create publication on a schema that does not exist +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA non_existent_schema +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA non_existent_schema" +== 512 +-- truncate_limit: 100 +-- check create publication on a system schema +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pg_catalog +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pg_catalog" +== 513 +-- truncate_limit: 100 +-- check create publication on an object which is not schema +CREATE PUBLICATION testpub1_forschema1 FOR TABLES IN SCHEMA testpub_view +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub1_forschema1 FOR TABLES IN SCHEMA testpub_view" +== 514 +-- truncate_limit: 100 +-- dropping the schema should reflect the change in publication +DROP SCHEMA pub_test3 +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA pub_test3" +== 515 +-- truncate_limit: 100 +-- renaming the schema should reflect the change in publication +ALTER SCHEMA pub_test1 RENAME to pub_test1_renamed +-- +STMT: RenameStmt +TRUNCATED: "ALTER SCHEMA pub_test1 RENAME TO pub_test1_renamed" +== 516 +-- truncate_limit: 100 +ALTER SCHEMA pub_test1_renamed RENAME to pub_test1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER SCHEMA pub_test1_renamed RENAME TO pub_test1" +== 517 +-- truncate_limit: 100 +-- alter publication add schema +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test2 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test2" +== 518 +-- truncate_limit: 100 +-- add non existent schema +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA non_existent_schema +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA non_existent_schema" +== 519 +-- truncate_limit: 100 +-- add a schema which is already added to the publication +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test1" +== 520 +-- truncate_limit: 100 +-- alter publication drop schema +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2" +== 521 +-- truncate_limit: 100 +-- drop schema that is not present in the publication +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2" +== 522 +-- truncate_limit: 100 +-- drop a schema that does not exist in the system +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA non_existent_schema +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA non_existent_schema" +== 523 +-- truncate_limit: 100 +-- drop all schemas +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1" +== 524 +-- truncate_limit: 100 +-- alter publication set multiple schema +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test2 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, TABLES IN SCHEMA pub_test2" +== 525 +-- truncate_limit: 100 +-- alter publication set non-existent schema +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA non_existent_schema +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA non_existent_schema" +== 526 +-- truncate_limit: 100 +-- alter publication set it duplicate schemas should set the schemas after +-- removing the duplicate schemas +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, TABLES IN SCHEMA pub_test1" +== 527 +-- truncate_limit: 100 +-- Verify that it fails to add a schema with a column specification +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA foo (a, b) +-- +ERROR: syntax error at or near "(" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 528 +-- truncate_limit: 100 +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA foo, bar (a, b) +-- +ERROR: column specification not allowed for schema +CURSORPOS: 64 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 529 +-- truncate_limit: 100 +-- cleanup pub_test1 schema for invalidation tests +ALTER PUBLICATION testpub2_forschema DROP TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub2_forschema DROP TABLES IN SCHEMA pub_test1" +== 530 +-- truncate_limit: 100 +DROP PUBLICATION testpub3_forschema, testpub4_forschema, testpub5_forschema, testpub6_forschema, testpub_fortable +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub3_forschema, testpub4_forschema, testpub5_forschema, testpub6_forschema, ..." +== 531 +-- truncate_limit: 100 +DROP SCHEMA "CURRENT_SCHEMA" CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA \"CURRENT_SCHEMA\" CASCADE" +== 532 +-- truncate_limit: 100 +-- verify relation cache invalidations through update statement for the +-- default REPLICA IDENTITY on the relation, if schema is part of the +-- publication then update will fail because relation's relreplident +-- option will be set, if schema is not part of the publication then update +-- will be successful. +INSERT INTO pub_test1.tbl VALUES(1, 'test') +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pub_test1.tbl VALUES (1, 'test')" +== 533 +-- truncate_limit: 100 +-- fail +UPDATE pub_test1.tbl SET id = 2 +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_test1.tbl SET id = 2" +== 534 +-- truncate_limit: 100 +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1" +== 535 +-- truncate_limit: 100 +-- success +UPDATE pub_test1.tbl SET id = 2 +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_test1.tbl SET id = 2" +== 536 +-- truncate_limit: 100 +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1" +== 537 +-- truncate_limit: 100 +-- fail +UPDATE pub_test1.tbl SET id = 2 +-- +TABLE: name="pub_test1.tbl" schema="pub_test1" table="tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_test1.tbl SET id = 2" +== 538 +-- truncate_limit: 100 +-- verify invalidation of partition table having parent and child tables in +-- different schema +CREATE SCHEMA pub_testpart1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pub_testpart1" +== 539 +-- truncate_limit: 100 +CREATE SCHEMA pub_testpart2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pub_testpart2" +== 540 +-- truncate_limit: 100 +CREATE TABLE pub_testpart1.parent1 (a int) partition by list (a) +-- +TABLE: name="pub_testpart1.parent1" schema="pub_testpart1" table="parent1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_testpart1.parent1 (a int) PARTITION BY LIST (a)" +== 541 +-- truncate_limit: 100 +CREATE TABLE pub_testpart2.child_parent1 partition of pub_testpart1.parent1 for values in (1) +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_testpart2.child_parent1 PARTITION OF pub_testpart1.parent1 FOR VALUES IN (1)" +== 542 +-- truncate_limit: 100 +INSERT INTO pub_testpart2.child_parent1 values(1) +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pub_testpart2.child_parent1 VALUES (1)" +== 543 +-- truncate_limit: 100 +UPDATE pub_testpart2.child_parent1 set a = 1 +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_testpart2.child_parent1 SET a = 1" +== 544 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 545 +-- truncate_limit: 100 +CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart1" +== 546 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 547 +-- truncate_limit: 100 +-- fail +UPDATE pub_testpart1.parent1 set a = 1 +-- +TABLE: name="pub_testpart1.parent1" schema="pub_testpart1" table="parent1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_testpart1.parent1 SET a = 1" +== 548 +-- truncate_limit: 100 +UPDATE pub_testpart2.child_parent1 set a = 1 +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_testpart2.child_parent1 SET a = 1" +== 549 +-- truncate_limit: 100 +DROP PUBLICATION testpubpart_forschema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpubpart_forschema" +== 550 +-- truncate_limit: 100 +-- verify invalidation of partition tables for schema publication that has +-- parent and child tables of different partition hierarchies +CREATE TABLE pub_testpart2.parent2 (a int) partition by list (a) +-- +TABLE: name="pub_testpart2.parent2" schema="pub_testpart2" table="parent2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_testpart2.parent2 (a int) PARTITION BY LIST (a)" +== 551 +-- truncate_limit: 100 +CREATE TABLE pub_testpart1.child_parent2 partition of pub_testpart2.parent2 for values in (1) +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pub_testpart1.child_parent2 PARTITION OF pub_testpart2.parent2 FOR VALUES IN (1)" +== 552 +-- truncate_limit: 100 +INSERT INTO pub_testpart1.child_parent2 values(1) +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pub_testpart1.child_parent2 VALUES (1)" +== 553 +-- truncate_limit: 100 +UPDATE pub_testpart1.child_parent2 set a = 1 +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_testpart1.child_parent2 SET a = 1" +== 554 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 555 +-- truncate_limit: 100 +CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart2 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart2" +== 556 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 557 +-- truncate_limit: 100 +-- fail +UPDATE pub_testpart2.child_parent1 set a = 1 +-- +TABLE: name="pub_testpart2.child_parent1" schema="pub_testpart2" table="child_parent1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_testpart2.child_parent1 SET a = 1" +== 558 +-- truncate_limit: 100 +UPDATE pub_testpart2.parent2 set a = 1 +-- +TABLE: name="pub_testpart2.parent2" schema="pub_testpart2" table="parent2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_testpart2.parent2 SET a = 1" +== 559 +-- truncate_limit: 100 +UPDATE pub_testpart1.child_parent2 set a = 1 +-- +TABLE: name="pub_testpart1.child_parent2" schema="pub_testpart1" table="child_parent2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pub_testpart1.child_parent2 SET a = 1" +== 560 +-- truncate_limit: 100 +-- alter publication set 'TABLES IN SCHEMA' on an empty publication. +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 561 +-- truncate_limit: 100 +CREATE PUBLICATION testpub3_forschema +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub3_forschema" +== 562 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 563 +-- truncate_limit: 100 +ALTER PUBLICATION testpub3_forschema SET TABLES IN SCHEMA pub_test1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION testpub3_forschema SET TABLES IN SCHEMA pub_test1" +== 564 +-- truncate_limit: 100 +-- create publication including both 'FOR TABLE' and 'FOR TABLES IN SCHEMA' +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 565 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_forschema_fortable FOR TABLES IN SCHEMA pub_test1, TABLE pub_test2.tbl1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_forschema_fortable FOR TABLES IN SCHEMA pub_test1, TABLE pub_test2.tbl1" +== 566 +-- truncate_limit: 100 +CREATE PUBLICATION testpub_fortable_forschema FOR TABLE pub_test2.tbl1, TABLES IN SCHEMA pub_test1 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION testpub_fortable_forschema FOR TABLE pub_test2.tbl1, TABLES IN SCHEMA pub_test1" +== 567 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 568 +-- truncate_limit: 100 +-- fail specifying table without any of 'FOR TABLES IN SCHEMA' or +--'FOR TABLE' or 'FOR ALL TABLES' +CREATE PUBLICATION testpub_error FOR pub_test2.tbl1 +-- +ERROR: invalid publication object list +CURSORPOS: 138 +FILENAME: gram.y +FUNCNAME: preprocess_pubobj_list +== 569 +-- truncate_limit: 100 +DROP VIEW testpub_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW testpub_view" +== 570 +-- truncate_limit: 100 +DROP PUBLICATION testpub_default +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_default" +== 571 +-- truncate_limit: 100 +DROP PUBLICATION testpib_ins_trunct +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpib_ins_trunct" +== 572 +-- truncate_limit: 100 +DROP PUBLICATION testpub_fortbl +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_fortbl" +== 573 +-- truncate_limit: 100 +DROP PUBLICATION testpub1_forschema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub1_forschema" +== 574 +-- truncate_limit: 100 +DROP PUBLICATION testpub2_forschema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub2_forschema" +== 575 +-- truncate_limit: 100 +DROP PUBLICATION testpub3_forschema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub3_forschema" +== 576 +-- truncate_limit: 100 +DROP PUBLICATION testpub_forschema_fortable +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_forschema_fortable" +== 577 +-- truncate_limit: 100 +DROP PUBLICATION testpub_fortable_forschema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpub_fortable_forschema" +== 578 +-- truncate_limit: 100 +DROP PUBLICATION testpubpart_forschema +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION testpubpart_forschema" +== 579 +-- truncate_limit: 100 +DROP SCHEMA pub_test CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA pub_test CASCADE" +== 580 +-- truncate_limit: 100 +DROP SCHEMA pub_test1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA pub_test1 CASCADE" +== 581 +-- truncate_limit: 100 +DROP SCHEMA pub_test2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA pub_test2 CASCADE" +== 582 +-- truncate_limit: 100 +DROP SCHEMA pub_testpart1 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA pub_testpart1 CASCADE" +== 583 +-- truncate_limit: 100 +DROP SCHEMA pub_testpart2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA pub_testpart2 CASCADE" +== 584 +-- truncate_limit: 100 +-- Test the list of partitions published with or without +-- 'PUBLISH_VIA_PARTITION_ROOT' parameter +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 585 +-- truncate_limit: 100 +CREATE SCHEMA sch1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA sch1" +== 586 +-- truncate_limit: 100 +CREATE SCHEMA sch2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA sch2" +== 587 +-- truncate_limit: 100 +CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a) +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE (a)" +== 588 +-- truncate_limit: 100 +CREATE TABLE sch2.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10) +-- +TABLE: name="sch2.tbl1_part1" schema="sch2" table="tbl1_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sch2.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) TO (10)" +== 589 +-- truncate_limit: 100 +-- Schema publication that does not include the schema that has the parent table +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (publish_via_partition_root = 1)" +== 590 +-- truncate_limit: 100 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_publication_tables" +== 591 +-- truncate_limit: 100 +DROP PUBLICATION pub +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub" +== 592 +-- truncate_limit: 100 +-- Table publication that does not include the parent table +CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (publish_via_partition_root = 1)" +== 593 +-- truncate_limit: 100 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_publication_tables" +== 594 +-- truncate_limit: 100 +-- Table publication that includes both the parent table and the child table +ALTER PUBLICATION pub ADD TABLE sch1.tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION pub ADD TABLE sch1.tbl1" +== 595 +-- truncate_limit: 100 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_publication_tables" +== 596 +-- truncate_limit: 100 +DROP PUBLICATION pub +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub" +== 597 +-- truncate_limit: 100 +-- Schema publication that does not include the schema that has the parent table +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (publish_via_partition_root = 0)" +== 598 +-- truncate_limit: 100 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_publication_tables" +== 599 +-- truncate_limit: 100 +DROP PUBLICATION pub +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub" +== 600 +-- truncate_limit: 100 +-- Table publication that does not include the parent table +CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=0) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (publish_via_partition_root = 0)" +== 601 +-- truncate_limit: 100 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_publication_tables" +== 602 +-- truncate_limit: 100 +-- Table publication that includes both the parent table and the child table +ALTER PUBLICATION pub ADD TABLE sch1.tbl1 +-- +STMT: AlterPublicationStmt +TRUNCATED: "ALTER PUBLICATION pub ADD TABLE sch1.tbl1" +== 603 +-- truncate_limit: 100 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_publication_tables" +== 604 +-- truncate_limit: 100 +DROP PUBLICATION pub +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub" +== 605 +-- truncate_limit: 100 +DROP TABLE sch2.tbl1_part1 +-- +TABLE: name="sch2.tbl1_part1" schema="sch2" table="tbl1_part1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sch2.tbl1_part1" +== 606 +-- truncate_limit: 100 +DROP TABLE sch1.tbl1 +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sch1.tbl1" +== 607 +-- truncate_limit: 100 +CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a) +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE (a)" +== 608 +-- truncate_limit: 100 +CREATE TABLE sch1.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10) +-- +TABLE: name="sch1.tbl1_part1" schema="sch1" table="tbl1_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sch1.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) TO (10)" +== 609 +-- truncate_limit: 100 +CREATE TABLE sch1.tbl1_part2 PARTITION OF sch1.tbl1 FOR VALUES FROM (10) to (20) +-- +TABLE: name="sch1.tbl1_part2" schema="sch1" table="tbl1_part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sch1.tbl1_part2 PARTITION OF sch1.tbl1 FOR VALUES FROM (10) TO (20)" +== 610 +-- truncate_limit: 100 +CREATE TABLE sch1.tbl1_part3 (a int) PARTITION BY RANGE(a) +-- +TABLE: name="sch1.tbl1_part3" schema="sch1" table="tbl1_part3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sch1.tbl1_part3 (a int) PARTITION BY RANGE (a)" +== 611 +-- truncate_limit: 100 +ALTER TABLE sch1.tbl1 ATTACH PARTITION sch1.tbl1_part3 FOR VALUES FROM (20) to (30) +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE sch1.tbl1 ATTACH PARTITION sch1.tbl1_part3 FOR VALUES FROM (20) TO (30)" +== 612 +-- truncate_limit: 100 +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch1 WITH (PUBLISH_VIA_PARTITION_ROOT=1) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch1 WITH (publish_via_partition_root = 1)" +== 613 +-- truncate_limit: 100 +SELECT * FROM pg_publication_tables +-- +TABLE: name="pg_publication_tables" schema="" table="pg_publication_tables" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_publication_tables" +== 614 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 615 +-- truncate_limit: 100 +DROP PUBLICATION pub +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub" +== 616 +-- truncate_limit: 100 +DROP TABLE sch1.tbl1 +-- +TABLE: name="sch1.tbl1" schema="sch1" table="tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sch1.tbl1" +== 617 +-- truncate_limit: 100 +DROP SCHEMA sch1 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA sch1 CASCADE" +== 618 +-- truncate_limit: 100 +DROP SCHEMA sch2 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA sch2 CASCADE" +== 619 +-- truncate_limit: 100 +-- Test that the INSERT ON CONFLICT command correctly checks REPLICA IDENTITY +-- when the target table is published. +CREATE TABLE testpub_insert_onconfl_no_ri (a int unique, b int) +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_insert_onconfl_no_ri (a int UNIQUE, b int)" +== 620 +-- truncate_limit: 100 +CREATE TABLE testpub_insert_onconfl_parted (a int unique, b int) PARTITION by RANGE (a) +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_insert_onconfl_parted (a int UNIQUE, b int) PARTITION BY RANGE (a)" +== 621 +-- truncate_limit: 100 +CREATE TABLE testpub_insert_onconfl_part_no_ri PARTITION OF testpub_insert_onconfl_parted FOR VALUES FROM (1) TO (10) +-- +TABLE: name="testpub_insert_onconfl_part_no_ri" schema="" table="testpub_insert_onconfl_part_no_ri" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_insert_onconfl_part_no_ri PARTITION OF testpub_insert_onconfl_parted FOR VAL..." +== 622 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 623 +-- truncate_limit: 100 +CREATE PUBLICATION pub1 FOR ALL TABLES +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub1 FOR ALL TABLES" +== 624 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 625 +-- truncate_limit: 100 +-- fail - missing REPLICA IDENTITY +INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2 +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2" +== 626 +-- truncate_limit: 100 +-- ok - no updates +INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT DO NOTHING +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT DO NOTHING" +== 627 +-- truncate_limit: 100 +-- fail - missing REPLICA IDENTITY in partition testpub_insert_onconfl_no_ri +INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2 +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2" +== 628 +-- truncate_limit: 100 +-- ok - no updates +INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT DO NOTHING +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT DO NOTHING" +== 629 +-- truncate_limit: 100 +DROP PUBLICATION pub1 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub1" +== 630 +-- truncate_limit: 100 +DROP TABLE testpub_insert_onconfl_no_ri +-- +TABLE: name="testpub_insert_onconfl_no_ri" schema="" table="testpub_insert_onconfl_no_ri" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_insert_onconfl_no_ri" +== 631 +-- truncate_limit: 100 +DROP TABLE testpub_insert_onconfl_parted +-- +TABLE: name="testpub_insert_onconfl_parted" schema="" table="testpub_insert_onconfl_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_insert_onconfl_parted" +== 632 +-- truncate_limit: 100 +-- Test that the MERGE command correctly checks REPLICA IDENTITY when the +-- target table is published. +CREATE TABLE testpub_merge_no_ri (a int, b int) +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_merge_no_ri (a int, b int)" +== 633 +-- truncate_limit: 100 +CREATE TABLE testpub_merge_pk (a int primary key, b int) +-- +TABLE: name="testpub_merge_pk" schema="" table="testpub_merge_pk" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testpub_merge_pk (a int PRIMARY KEY, b int)" +== 634 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 635 +-- truncate_limit: 100 +CREATE PUBLICATION pub1 FOR ALL TABLES +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION pub1 FOR ALL TABLES" +== 636 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 637 +-- truncate_limit: 100 +-- fail - missing REPLICA IDENTITY +MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 + WHEN MATCHED THEN UPDATE SET b = s.b +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 WHEN MATCHED THEN UPDATE SET ..." +== 638 +-- truncate_limit: 100 +-- fail - missing REPLICA IDENTITY +MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 + WHEN MATCHED THEN DELETE +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 WHEN MATCHED THEN DELETE" +== 639 +-- truncate_limit: 100 +-- ok - insert and do nothing are not restricted +MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN INSERT (a, b) VALUES (0, 0) +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO testpub_merge_no_ri USING testpub_merge_pk s ON s.a >= 1 WHEN MATCHED THEN DO NOTHING ..." +== 640 +-- truncate_limit: 100 +-- ok - REPLICA IDENTITY is DEFAULT and table has a PK +MERGE INTO testpub_merge_pk USING testpub_merge_no_ri s ON s.a >= 1 + WHEN MATCHED AND s.a > 0 THEN UPDATE SET b = s.b + WHEN MATCHED THEN DELETE +-- +TABLE: name="testpub_merge_pk" schema="" table="testpub_merge_pk" ctx=DML +STMT: MergeStmt +TRUNCATED: "MERGE INTO testpub_merge_pk USING testpub_merge_no_ri s ON s.a >= 1 WHEN MATCHED AND s.a > 0 THEN..." +== 641 +-- truncate_limit: 100 +DROP PUBLICATION pub1 +-- +STMT: DropStmt +TRUNCATED: "DROP PUBLICATION pub1" +== 642 +-- truncate_limit: 100 +DROP TABLE testpub_merge_no_ri +-- +TABLE: name="testpub_merge_no_ri" schema="" table="testpub_merge_no_ri" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_merge_no_ri" +== 643 +-- truncate_limit: 100 +DROP TABLE testpub_merge_pk +-- +TABLE: name="testpub_merge_pk" schema="" table="testpub_merge_pk" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testpub_merge_pk" +== 644 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 645 +-- truncate_limit: 100 +DROP ROLE regress_publication_user, regress_publication_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_publication_user, regress_publication_user2" +== 646 +-- truncate_limit: 100 +DROP ROLE regress_publication_user_dummy +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_publication_user_dummy" +== 647 +-- truncate_limit: 100 +-- stage objects for pg_dump tests +CREATE SCHEMA pubme CREATE TABLE t0 (c int, d int) CREATE TABLE t1 (c int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pubme CREATE TABLE t0 (c int, d int) CREATE TABLE t1 (c int)" +== 648 +-- truncate_limit: 100 +CREATE SCHEMA pubme2 CREATE TABLE t0 (c int, d int) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA pubme2 CREATE TABLE t0 (c int, d int)" +== 649 +-- truncate_limit: 100 +SET client_min_messages = 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 650 +-- truncate_limit: 100 +CREATE PUBLICATION dump_pub_qual_1ct FOR + TABLE ONLY pubme.t0 (c, d) WHERE (c > 0) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION dump_pub_qual_1ct FOR TABLE ONLY pubme.t0(c, d) WHERE (c > 0)" +== 651 +-- truncate_limit: 100 +CREATE PUBLICATION dump_pub_qual_2ct FOR + TABLE ONLY pubme.t0 (c) WHERE (c > 0), + TABLE ONLY pubme.t1 (c) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION dump_pub_qual_2ct FOR TABLE ONLY pubme.t0(c) WHERE (c > 0), TABLE ONLY pubme.t..." +== 652 +-- truncate_limit: 100 +CREATE PUBLICATION dump_pub_nsp_1ct FOR + TABLES IN SCHEMA pubme +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION dump_pub_nsp_1ct FOR TABLES IN SCHEMA pubme" +== 653 +-- truncate_limit: 100 +CREATE PUBLICATION dump_pub_nsp_2ct FOR + TABLES IN SCHEMA pubme, + TABLES IN SCHEMA pubme2 +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION dump_pub_nsp_2ct FOR TABLES IN SCHEMA pubme, TABLES IN SCHEMA pubme2" +== 654 +-- truncate_limit: 100 +CREATE PUBLICATION dump_pub_all FOR + TABLE ONLY pubme.t0, + TABLE ONLY pubme.t1 WHERE (c < 0), + TABLES IN SCHEMA pubme, + TABLES IN SCHEMA pubme2 + WITH (publish_via_partition_root = true) +-- +STMT: CreatePublicationStmt +TRUNCATED: "CREATE PUBLICATION dump_pub_all FOR TABLE ONLY pubme.t0, TABLE ONLY pubme.t1 WHERE (c < 0), TABLE..." +== 655 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" diff --git a/parser/testdata/summary_truncate/postgres_regress/random.metadata.json b/parser/testdata/summary_truncate/postgres_regress/random.metadata.json new file mode 100644 index 0000000..634de79 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/random.metadata.json @@ -0,0 +1,52 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/random.test b/parser/testdata/summary_truncate/postgres_regress/random.test new file mode 100644 index 0000000..b0907de --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/random.test @@ -0,0 +1,610 @@ +== 001 +-- truncate_limit: 100 +|-- +-- RANDOM +-- Test random() and allies +|-- +-- Tests in this file may have a small probability of failure, +-- since we are dealing with randomness. Try to keep the failure +-- risk for any one test case under 1e-9. +|-- + +-- There should be no duplicates in 1000 random() values. +-- (Assuming 52 random bits in the float8 results, we could +-- take as many as 3000 values and still have less than 1e-9 chance +-- of failure, per https://en.wikipedia.org/wiki/Birthday_problem) +SELECT r, count(*) +FROM (SELECT random() r FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT r, count(*) FROM (SELECT ... FROM generate_series(1, 1000)) ss GROUP BY r HAVING count(*) > 1" +== 002 +-- truncate_limit: 100 +-- The range should be [0, 1). We can expect that at least one out of 2000 +-- random values is in the lowest or highest 1% of the range with failure +-- probability less than about 1e-9. + +SELECT count(*) FILTER (WHERE r < 0 OR r >= 1) AS out_of_range, + (count(*) FILTER (WHERE r < 0.01)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 0.99)) > 0 AS has_large +FROM (SELECT random() r FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2000)) ss" +== 003 +-- truncate_limit: 100 +-- Check for uniform distribution using the Kolmogorov-Smirnov test. + +CREATE FUNCTION ks_test_uniform_random() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random() r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ks_test_uniform_random() RETURNS boolean AS $$\nDECLARE\n n int := 1000; --..." +== 004 +-- truncate_limit: 100 +-- As written, ks_test_uniform_random() returns true about 99.9% +-- of the time. To get down to a roughly 1e-9 test failure rate, +-- just run it 3 times and accept if any one of them passes. +SELECT ks_test_uniform_random() OR + ks_test_uniform_random() OR + ks_test_uniform_random() AS uniform +-- +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random" function="ks_test_uniform_random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ks_test_uniform_random() OR ks_test_uniform_random() OR ks_test_uniform_random() AS uniform" +== 005 +-- truncate_limit: 100 +-- now test random_normal() + +-- As above, there should be no duplicates in 1000 random_normal() values. +SELECT r, count(*) +FROM (SELECT random_normal() r FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT r, count(*) FROM (SELECT ... FROM generate_series(1, 1000)) ss GROUP BY r HAVING count(*) > 1" +== 006 +-- truncate_limit: 100 +-- ... unless we force the range (standard deviation) to zero. +-- This is a good place to check that the mean input does something, too. +SELECT r, count(*) +FROM (SELECT random_normal(10, 0) r FROM generate_series(1, 100)) ss +GROUP BY r +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT r, count(*) FROM (SELECT ... FROM generate_series(1, 100)) ss GROUP BY r" +== 007 +-- truncate_limit: 100 +SELECT r, count(*) +FROM (SELECT random_normal(-10, 0) r FROM generate_series(1, 100)) ss +GROUP BY r +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT r, count(*) FROM (SELECT ... FROM generate_series(1, 100)) ss GROUP BY r" +== 008 +-- truncate_limit: 100 +-- Check standard normal distribution using the Kolmogorov-Smirnov test. + +CREATE FUNCTION ks_test_normal_random() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random_normal() r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs((1+erf(r/sqrt(2)))/2 - i/n)) < c / sqrt(n) + FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ks_test_normal_random() RETURNS boolean AS $$\nDECLARE\n n int := 1000; -- ..." +== 009 +-- truncate_limit: 100 +-- As above, ks_test_normal_random() returns true about 99.9% +-- of the time, so try it 3 times and accept if any test passes. +SELECT ks_test_normal_random() OR + ks_test_normal_random() OR + ks_test_normal_random() AS standard_normal +-- +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=Call +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=Call +FUNCTION: name="ks_test_normal_random" function="ks_test_normal_random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 010 +-- truncate_limit: 100 +-- Test random(min, max) + +-- invalid range bounds +SELECT random(1, 0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(1, 0)" +== 011 +-- truncate_limit: 100 +SELECT random(1000000000001, 1000000000000) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(1000000000001, 1000000000000)" +== 012 +-- truncate_limit: 100 +SELECT random(-2.0, -3.0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(-2.0, -3.0)" +== 013 +-- truncate_limit: 100 +SELECT random('NaN'::numeric, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random('NaN'::numeric, 10)" +== 014 +-- truncate_limit: 100 +SELECT random('-Inf'::numeric, 0) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random('-Inf'::numeric, 0)" +== 015 +-- truncate_limit: 100 +SELECT random(0, 'NaN'::numeric) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(0, 'NaN'::numeric)" +== 016 +-- truncate_limit: 100 +SELECT random(0, 'Inf'::numeric) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(0, 'Inf'::numeric)" +== 017 +-- truncate_limit: 100 +-- empty range is OK +SELECT random(101, 101) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(101, 101)" +== 018 +-- truncate_limit: 100 +SELECT random(1000000000001, 1000000000001) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(1000000000001, 1000000000001)" +== 019 +-- truncate_limit: 100 +SELECT random(3.14, 3.14) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(3.14, 3.14)" +== 020 +-- truncate_limit: 100 +-- There should be no triple duplicates in 1000 full-range 32-bit random() +-- values. (Each of the C(1000, 3) choices of triplets from the 1000 values +-- has a probability of 1/(2^32)^2 of being a triple duplicate, so the +-- average number of triple duplicates is 1000 * 999 * 998 / 6 / 2^64, which +-- is roughly 9e-12.) +SELECT r, count(*) +FROM (SELECT random(-2147483648, 2147483647) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 2 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT r, count(*) FROM (SELECT ... FROM generate_series(1, 1000)) ss GROUP BY r HAVING count(*) > 2" +== 021 +-- truncate_limit: 100 +-- There should be no duplicates in 1000 full-range 64-bit random() values. +SELECT r, count(*) +FROM (SELECT random_normal(-9223372036854775808, 9223372036854775807) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT r, count(*) FROM (SELECT ... FROM generate_series(1, 1000)) ss GROUP BY r HAVING count(*) > 1" +== 022 +-- truncate_limit: 100 +-- There should be no duplicates in 1000 15-digit random() numeric values. +SELECT r, count(*) +FROM (SELECT random_normal(0, 1 - 1e-15) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1 +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT r, count(*) FROM (SELECT ... FROM generate_series(1, 1000)) ss GROUP BY r HAVING count(*) > 1" +== 023 +-- truncate_limit: 100 +-- Expect at least one out of 2000 random values to be in the lowest and +-- highest 1% of the range. +SELECT (count(*) FILTER (WHERE r < -2104533975)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 2104533974)) > 0 AS has_large +FROM (SELECT random(-2147483648, 2147483647) r FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2000)) ss" +== 024 +-- truncate_limit: 100 +SELECT count(*) FILTER (WHERE r < -1500000000 OR r > 1500000000) AS out_of_range, + (count(*) FILTER (WHERE r < -1470000000)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1470000000)) > 0 AS has_large +FROM (SELECT random(-1500000000, 1500000000) r FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2000)) ss" +== 025 +-- truncate_limit: 100 +SELECT (count(*) FILTER (WHERE r < -9038904596117680292)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 9038904596117680291)) > 0 AS has_large +FROM (SELECT random(-9223372036854775808, 9223372036854775807) r + FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2000)) ss" +== 026 +-- truncate_limit: 100 +SELECT count(*) FILTER (WHERE r < -1500000000000000 OR r > 1500000000000000) AS out_of_range, + (count(*) FILTER (WHERE r < -1470000000000000)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1470000000000000)) > 0 AS has_large +FROM (SELECT random(-1500000000000000, 1500000000000000) r + FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2000)) ss" +== 027 +-- truncate_limit: 100 +SELECT count(*) FILTER (WHERE r < -1.5 OR r > 1.5) AS out_of_range, + (count(*) FILTER (WHERE r < -1.47)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1.47)) > 0 AS has_large +FROM (SELECT random(-1.500000000000000, 1.500000000000000) r + FROM generate_series(1, 2000)) ss +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 2000)) ss" +== 028 +-- truncate_limit: 100 +-- Every possible value should occur at least once in 2500 random() values +-- chosen from a range with 100 distinct values. +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(-50, 49) r FROM generate_series(1, 2500)) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(r), max(r), count(r) FROM (SELECT DISTINCT ... AS ... FROM generate_series(1, 2500))" +== 029 +-- truncate_limit: 100 +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(123000000000, 123000000099) r + FROM generate_series(1, 2500)) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(r), max(r), count(r) FROM (SELECT DISTINCT ... AS ... FROM generate_series(1, 2500))" +== 030 +-- truncate_limit: 100 +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(-0.5, 0.49) r FROM generate_series(1, 2500)) +-- +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(r), max(r), count(r) FROM (SELECT DISTINCT ... AS ... FROM generate_series(1, 2500))" +== 031 +-- truncate_limit: 100 +-- Check for uniform distribution using the Kolmogorov-Smirnov test. + +CREATE FUNCTION ks_test_uniform_random_int_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 999999) / 1000000.0 r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ks_test_uniform_random_int_in_range() RETURNS boolean AS $$\nDECLARE\n n int := 10..." +== 032 +-- truncate_limit: 100 +SELECT ks_test_uniform_random_int_in_range() OR + ks_test_uniform_random_int_in_range() OR + ks_test_uniform_random_int_in_range() AS uniform_int +-- +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_int_in_range" function="ks_test_uniform_random_int_in_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 033 +-- truncate_limit: 100 +CREATE FUNCTION ks_test_uniform_random_bigint_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 999999999999) / 1000000000000.0 r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ks_test_uniform_random_bigint_in_range() RETURNS boolean AS $$\nDECLARE\n n int :=..." +== 034 +-- truncate_limit: 100 +SELECT ks_test_uniform_random_bigint_in_range() OR + ks_test_uniform_random_bigint_in_range() OR + ks_test_uniform_random_bigint_in_range() AS uniform_bigint +-- +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_bigint_in_range" function="ks_test_uniform_random_bigint_in_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 035 +-- truncate_limit: 100 +CREATE FUNCTION ks_test_uniform_random_numeric_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 0.999999) r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION ks_test_uniform_random_numeric_in_range() RETURNS boolean AS $$\nDECLARE\n n int :..." +== 036 +-- truncate_limit: 100 +SELECT ks_test_uniform_random_numeric_in_range() OR + ks_test_uniform_random_numeric_in_range() OR + ks_test_uniform_random_numeric_in_range() AS uniform_numeric +-- +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=Call +FUNCTION: name="ks_test_uniform_random_numeric_in_range" function="ks_test_uniform_random_numeric_in_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 037 +-- truncate_limit: 100 +-- setseed() should produce a reproducible series of random() values. + +SELECT setseed(0.5) +-- +FUNCTION: name="setseed" function="setseed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setseed(0.5)" +== 038 +-- truncate_limit: 100 +SELECT random() FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random() FROM generate_series(1, 10)" +== 039 +-- truncate_limit: 100 +-- Likewise for random_normal(); however, since its implementation relies +-- on libm functions that have different roundoff behaviors on different +-- machines, we have to round off the results a bit to get consistent output. +SET extra_float_digits = -1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO -1" +== 040 +-- truncate_limit: 100 +SELECT random_normal() FROM generate_series(1, 10) +-- +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random_normal() FROM generate_series(1, 10)" +== 041 +-- truncate_limit: 100 +SELECT random_normal(mean => 1, stddev => 0.1) r FROM generate_series(1, 10) +-- +FUNCTION: name="random_normal" function="random_normal" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random_normal(mean := 1, stddev := 0.1) AS r FROM generate_series(1, 10)" +== 042 +-- truncate_limit: 100 +-- Reproducible random(min, max) values. +SELECT random(1, 6) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(1, 6) FROM generate_series(1, 10)" +== 043 +-- truncate_limit: 100 +SELECT random(-2147483648, 2147483647) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(-2147483648, 2147483647) FROM generate_series(1, 10)" +== 044 +-- truncate_limit: 100 +SELECT random(-9223372036854775808, 9223372036854775807) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(-9223372036854775808, 9223372036854775807) FROM generate_series(1, 10)" +== 045 +-- truncate_limit: 100 +SELECT random(-1e30, 1e30) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(-1e30, 1e30) FROM generate_series(1, 10)" +== 046 +-- truncate_limit: 100 +SELECT random(-0.4, 0.4) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(-0.4, 0.4) FROM generate_series(1, 10)" +== 047 +-- truncate_limit: 100 +SELECT random(0, 1 - 1e-30) FROM generate_series(1, 10) +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT random(0, 1 - 1e-30) FROM generate_series(1, 10)" +== 048 +-- truncate_limit: 100 +SELECT n, random(0, trim_scale(abs(1 - 10.0^(-n)))) FROM generate_series(-20, 20) n +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="trim_scale" function="trim_scale" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT n, random(0, trim_scale(abs(1 - (10.0 ^ (- n))))) FROM generate_series(-20, 20) n" diff --git a/parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json new file mode 100644 index 0000000..526d3ef --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json @@ -0,0 +1,432 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/rangefuncs.test b/parser/testdata/summary_truncate/postgres_regress/rangefuncs.test new file mode 100644 index 0000000..5f1b5ea --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rangefuncs.test @@ -0,0 +1,3413 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE rngfunc2(rngfuncid int, f2 int) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rngfunc2 (rngfuncid int, f2 int)" +== 002 +-- truncate_limit: 100 +INSERT INTO rngfunc2 VALUES(1, 11) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rngfunc2 VALUES (1, 11)" +== 003 +-- truncate_limit: 100 +INSERT INTO rngfunc2 VALUES(2, 22) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rngfunc2 VALUES (2, 22)" +== 004 +-- truncate_limit: 100 +INSERT INTO rngfunc2 VALUES(1, 111) +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rngfunc2 VALUES (1, 111)" +== 005 +-- truncate_limit: 100 +CREATE FUNCTION rngfunct(int) returns setof rngfunc2 as 'SELECT * FROM rngfunc2 WHERE rngfuncid = $1 ORDER BY f2;' LANGUAGE SQL +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rngfunct(int) RETURNS SETOF rngfunc2 AS $$SELECT * FROM rngfunc2 WHERE rngfuncid ..." +== 006 +-- truncate_limit: 100 +-- function with ORDINALITY +select * from rngfunct(1) with ordinality as z(a,b,ord) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunct(1) WITH ORDINALITY z(a, b, ord)" +== 007 +-- truncate_limit: 100 +select * from rngfunct(1) with ordinality as z(a,b,ord) where b > 100 +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunct(1) WITH ORDINALITY z(a, b, ord) WHERE b > 100" +== 008 +-- truncate_limit: 100 +-- ordinal 2, not 1 +-- ordinality vs. column names and types +select a,b,ord from rngfunct(1) with ordinality as z(a,b,ord) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, ord FROM rngfunct(1) WITH ORDINALITY z(a, b, ord)" +== 009 +-- truncate_limit: 100 +select a,ord from unnest(array['a','b']) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, ord FROM unnest(ARRAY['a', 'b']) WITH ORDINALITY z(a, ord)" +== 010 +-- truncate_limit: 100 +select * from unnest(array['a','b']) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest(ARRAY['a', 'b']) WITH ORDINALITY z(a, ord)" +== 011 +-- truncate_limit: 100 +select a,ord from unnest(array[1.0::float8]) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, ord FROM unnest(ARRAY[(1.0)::float8]) WITH ORDINALITY z(a, ord)" +== 012 +-- truncate_limit: 100 +select * from unnest(array[1.0::float8]) with ordinality as z(a,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest(ARRAY[(1.0)::float8]) WITH ORDINALITY z(a, ord)" +== 013 +-- truncate_limit: 100 +select row_to_json(s.*) from generate_series(11,14) with ordinality s +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(s.*) FROM generate_series(11, 14) WITH ORDINALITY s" +== 014 +-- truncate_limit: 100 +-- ordinality vs. views +create temporary view vw_ord as select * from (values (1)) v(n) join rngfunct(1) with ordinality as z(a,b,ord) on (n=ord) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW vw_ord AS SELECT * FROM (VALUES (1)) v(n) JOIN rngfunct(1) WITH ORDINALITY ..." +== 015 +-- truncate_limit: 100 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_ord" +== 016 +-- truncate_limit: 100 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_views WHERE viewname = 'vw_ord'" +== 017 +-- truncate_limit: 100 +drop view vw_ord +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_ord" +== 018 +-- truncate_limit: 100 +-- multiple functions +select * from rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (rngfunct(1) , rngfunct(2) ) WITH ORDINALITY z(a, b, c, d, ord)" +== 019 +-- truncate_limit: 100 +create temporary view vw_ord as select * from (values (1)) v(n) join rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord) on (n=ord) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW vw_ord AS SELECT * FROM (VALUES (1)) v(n) JOIN ROWS FROM (rngfunct(1) , rng..." +== 020 +-- truncate_limit: 100 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_ord" +== 021 +-- truncate_limit: 100 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_views WHERE viewname = 'vw_ord'" +== 022 +-- truncate_limit: 100 +drop view vw_ord +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_ord" +== 023 +-- truncate_limit: 100 +-- expansions of unnest() +select * from unnest(array[10,20],array['foo','bar'],array[1.0]) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest(ARRAY[10, 20], ARRAY['foo', 'bar'], ARRAY[1.0])" +== 024 +-- truncate_limit: 100 +select * from unnest(array[10,20],array['foo','bar'],array[1.0]) with ordinality as z(a,b,c,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest(ARRAY[10, 20], ARRAY['foo', 'bar'], ARRAY[1.0]) WITH ORDINALITY z(a, b, c, ord)" +== 025 +-- truncate_limit: 100 +select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) with ordinality as z(a,b,c,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (unnest(ARRAY[10, 20], ARRAY['foo', 'bar'], ARRAY[1.0]) ) WITH ORDINALITY..." +== 026 +-- truncate_limit: 100 +select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(101,102)) with ordinality as z(a,b,c,ord) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (unnest(ARRAY[10, 20], ARRAY['foo', 'bar']) , generate_series(101, 102) )..." +== 027 +-- truncate_limit: 100 +create temporary view vw_ord as select * from unnest(array[10,20],array['foo','bar'],array[1.0]) as z(a,b,c) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW vw_ord AS SELECT * FROM unnest(ARRAY[10, 20], ARRAY['foo', 'bar'], ARRAY[1...." +== 028 +-- truncate_limit: 100 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_ord" +== 029 +-- truncate_limit: 100 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_views WHERE viewname = 'vw_ord'" +== 030 +-- truncate_limit: 100 +drop view vw_ord +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_ord" +== 031 +-- truncate_limit: 100 +create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) as z(a,b,c) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW vw_ord AS SELECT * FROM ROWS FROM (unnest(ARRAY[10, 20], ARRAY['foo', 'bar'..." +== 032 +-- truncate_limit: 100 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_ord" +== 033 +-- truncate_limit: 100 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_views WHERE viewname = 'vw_ord'" +== 034 +-- truncate_limit: 100 +drop view vw_ord +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_ord" +== 035 +-- truncate_limit: 100 +create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(1,2)) as z(a,b,c) +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=DDL +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW vw_ord AS SELECT * FROM ROWS FROM (unnest(ARRAY[10, 20], ARRAY['foo', 'bar'..." +== 036 +-- truncate_limit: 100 +select * from vw_ord +-- +TABLE: name="vw_ord" schema="" table="vw_ord" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_ord" +== 037 +-- truncate_limit: 100 +select definition from pg_views where viewname='vw_ord' +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="viewname" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_views WHERE viewname = 'vw_ord'" +== 038 +-- truncate_limit: 100 +drop view vw_ord +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_ord" +== 039 +-- truncate_limit: 100 +-- ordinality and multiple functions vs. rewind and reverse scan +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 040 +-- truncate_limit: 100 +declare rf_cur scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o) +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE rf_cur SCROLL CURSOR FOR SELECT * FROM ROWS FROM (generate_series(1, 5) , generate_series..." +== 041 +-- truncate_limit: 100 +fetch all from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL rf_cur" +== 042 +-- truncate_limit: 100 +fetch backward all from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL rf_cur" +== 043 +-- truncate_limit: 100 +fetch all from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL rf_cur" +== 044 +-- truncate_limit: 100 +fetch next from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH rf_cur" +== 045 +-- truncate_limit: 100 +fetch next from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH rf_cur" +== 046 +-- truncate_limit: 100 +fetch prior from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR rf_cur" +== 047 +-- truncate_limit: 100 +fetch absolute 1 from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH FIRST rf_cur" +== 048 +-- truncate_limit: 100 +fetch next from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH rf_cur" +== 049 +-- truncate_limit: 100 +fetch next from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH rf_cur" +== 050 +-- truncate_limit: 100 +fetch next from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH rf_cur" +== 051 +-- truncate_limit: 100 +fetch prior from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR rf_cur" +== 052 +-- truncate_limit: 100 +fetch prior from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR rf_cur" +== 053 +-- truncate_limit: 100 +fetch prior from rf_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR rf_cur" +== 054 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 055 +-- truncate_limit: 100 +-- function with implicit LATERAL +select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) z where rngfunc2.f2 = z.f2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="rngfunc2" column="f2" +FILTER: schema="" table="z" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc2, rngfunct(rngfunc2.rngfuncid) z WHERE rngfunc2.f2 = z.f2" +== 056 +-- truncate_limit: 100 +-- function with implicit LATERAL and explicit ORDINALITY +select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) with ordinality as z(rngfuncid,f2,ord) where rngfunc2.f2 = z.f2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="rngfunc2" column="f2" +FILTER: schema="" table="z" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc2, rngfunct(rngfunc2.rngfuncid) WITH ORDINALITY z(rngfuncid, f2, ord) WHERE ..." +== 057 +-- truncate_limit: 100 +-- function in subselect +select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="z" column="rngfuncid" +FILTER: schema="" table="rngfunc2" column="rngfuncid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc2 WHERE ... ORDER BY 1, 2" +== 058 +-- truncate_limit: 100 +-- function in subselect +select * from rngfunc2 where f2 in (select f2 from rngfunct(1) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="z" column="rngfuncid" +FILTER: schema="" table="rngfunc2" column="rngfuncid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc2 WHERE f2 IN (SELECT f2 FROM rngfunct(1) z WHERE ...) ORDER BY 1, 2" +== 059 +-- truncate_limit: 100 +-- function in subselect +select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = 1) ORDER BY 1,2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=Select +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="z" column="rngfuncid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc2 WHERE ... ORDER BY 1, 2" +== 060 +-- truncate_limit: 100 +-- nested functions +select rngfunct.rngfuncid, rngfunct.f2 from rngfunct(sin(pi()/2)::int) ORDER BY 1,2 +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=Call +FUNCTION: name="sin" function="sin" schema="" ctx=Call +FUNCTION: name="pi" function="pi" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rngfunct.rngfuncid, rngfunct.f2 FROM rngfunct(sin(pi() / 2)::int) ORDER BY 1, 2" +== 061 +-- truncate_limit: 100 +CREATE TABLE rngfunc (rngfuncid int, rngfuncsubid int, rngfuncname text, primary key(rngfuncid,rngfuncsubid)) +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rngfunc (rngfuncid int, rngfuncsubid int, rngfuncname text, PRIMARY KEY (rngfuncid, ..." +== 062 +-- truncate_limit: 100 +INSERT INTO rngfunc VALUES(1,1,'Joe') +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rngfunc VALUES (1, 1, 'Joe')" +== 063 +-- truncate_limit: 100 +INSERT INTO rngfunc VALUES(1,2,'Ed') +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rngfunc VALUES (1, 2, 'Ed')" +== 064 +-- truncate_limit: 100 +INSERT INTO rngfunc VALUES(2,1,'Mary') +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rngfunc VALUES (2, 1, 'Mary')" +== 065 +-- truncate_limit: 100 +-- sql, proretset = f, prorettype = b +CREATE FUNCTION getrngfunc1(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc1(int) RETURNS int AS $$SELECT $1;$$ LANGUAGE sql" +== 066 +-- truncate_limit: 100 +SELECT * FROM getrngfunc1(1) AS t1 +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc1(1) t1" +== 067 +-- truncate_limit: 100 +SELECT * FROM getrngfunc1(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc1(1) WITH ORDINALITY t1(v, o)" +== 068 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1)" +== 069 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 070 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 071 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) WITH ORDINALITY as t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) WITH ORDINALITY t1(v, o)" +== 072 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 073 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 074 +-- truncate_limit: 100 +-- sql, proretset = t, prorettype = b +CREATE FUNCTION getrngfunc2(int) RETURNS setof int AS 'SELECT rngfuncid FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc2(int) RETURNS SETOF int AS $$SELECT rngfuncid FROM rngfunc WHERE rngfu..." +== 075 +-- truncate_limit: 100 +SELECT * FROM getrngfunc2(1) AS t1 +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc2(1) t1" +== 076 +-- truncate_limit: 100 +SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc2(1) WITH ORDINALITY t1(v, o)" +== 077 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1)" +== 078 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 079 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 080 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) WITH ORDINALITY t1(v, o)" +== 081 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 082 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 083 +-- truncate_limit: 100 +-- sql, proretset = t, prorettype = b +CREATE FUNCTION getrngfunc3(int) RETURNS setof text AS 'SELECT rngfuncname FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc3(int) RETURNS SETOF text AS $$SELECT rngfuncname FROM rngfunc WHERE rn..." +== 084 +-- truncate_limit: 100 +SELECT * FROM getrngfunc3(1) AS t1 +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc3(1) t1" +== 085 +-- truncate_limit: 100 +SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc3(1) WITH ORDINALITY t1(v, o)" +== 086 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1)" +== 087 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 088 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 089 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) WITH ORDINALITY t1(v, o)" +== 090 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 091 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 092 +-- truncate_limit: 100 +-- sql, proretset = f, prorettype = c +CREATE FUNCTION getrngfunc4(int) RETURNS rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc4(int) RETURNS rngfunc AS $$SELECT * FROM rngfunc WHERE rngfuncid = $1;..." +== 093 +-- truncate_limit: 100 +SELECT * FROM getrngfunc4(1) AS t1 +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc4(1) t1" +== 094 +-- truncate_limit: 100 +SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc4(1) WITH ORDINALITY t1(a, b, c, o)" +== 095 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1)" +== 096 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 097 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 098 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) WITH ORDINALITY t1(a, b, c, o)" +== 099 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 100 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 101 +-- truncate_limit: 100 +-- sql, proretset = t, prorettype = c +CREATE FUNCTION getrngfunc5(int) RETURNS setof rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc5(int) RETURNS SETOF rngfunc AS $$SELECT * FROM rngfunc WHERE rngfuncid..." +== 102 +-- truncate_limit: 100 +SELECT * FROM getrngfunc5(1) AS t1 +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc5(1) t1" +== 103 +-- truncate_limit: 100 +SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc5(1) WITH ORDINALITY t1(a, b, c, o)" +== 104 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1)" +== 105 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 106 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 107 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) WITH ORDINALITY t1(a, b, c, o)" +== 108 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 109 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 110 +-- truncate_limit: 100 +-- sql, proretset = f, prorettype = record +CREATE FUNCTION getrngfunc6(int) RETURNS RECORD AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc6(int) RETURNS record AS $$SELECT * FROM rngfunc WHERE rngfuncid = $1;$..." +== 111 +-- truncate_limit: 100 +SELECT * FROM getrngfunc6(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc6(1) t1 (rngfuncid int, rngfuncsubid int, rngfuncname text)" +== 112 +-- truncate_limit: 100 +SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text)) W..." +== 113 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc6(1) AS +(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rn..." +== 114 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 115 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 116 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS + SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) + WITH ORDINALITY +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM ROWS FROM (getrngfunc6(1) AS (rngfuncid int, rngfuncsu..." +== 117 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 118 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 119 +-- truncate_limit: 100 +-- sql, proretset = t, prorettype = record +CREATE FUNCTION getrngfunc7(int) RETURNS setof record AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc7(int) RETURNS SETOF record AS $$SELECT * FROM rngfunc WHERE rngfuncid ..." +== 120 +-- truncate_limit: 100 +SELECT * FROM getrngfunc7(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc7(1) t1 (rngfuncid int, rngfuncsubid int, rngfuncname text)" +== 121 +-- truncate_limit: 100 +SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text)) W..." +== 122 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc7(1) AS +(rngfuncid int, rngfuncsubid int, rngfuncname text) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rn..." +== 123 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 124 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 125 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS + SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) + WITH ORDINALITY +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM ROWS FROM (getrngfunc7(1) AS (rngfuncid int, rngfuncsu..." +== 126 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 127 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 128 +-- truncate_limit: 100 +-- plpgsql, proretset = f, prorettype = b +CREATE FUNCTION getrngfunc8(int) RETURNS int AS 'DECLARE rngfuncint int; BEGIN SELECT rngfuncid into rngfuncint FROM rngfunc WHERE rngfuncid = $1; RETURN rngfuncint; END;' LANGUAGE plpgsql +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc8(int) RETURNS int AS $$DECLARE rngfuncint int; BEGIN SELECT rngfuncid ..." +== 129 +-- truncate_limit: 100 +SELECT * FROM getrngfunc8(1) AS t1 +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc8(1) t1" +== 130 +-- truncate_limit: 100 +SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o) +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc8(1) WITH ORDINALITY t1(v, o)" +== 131 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1)" +== 132 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 133 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 134 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) WITH ORDINALITY t1(v, o)" +== 135 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 136 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 137 +-- truncate_limit: 100 +-- plpgsql, proretset = f, prorettype = c +CREATE FUNCTION getrngfunc9(int) RETURNS rngfunc AS 'DECLARE rngfunctup rngfunc%ROWTYPE; BEGIN SELECT * into rngfunctup FROM rngfunc WHERE rngfuncid = $1; RETURN rngfunctup; END;' LANGUAGE plpgsql +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION getrngfunc9(int) RETURNS rngfunc AS $$DECLARE rngfunctup rngfunc%ROWTYPE; BEGIN S..." +== 138 +-- truncate_limit: 100 +SELECT * FROM getrngfunc9(1) AS t1 +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc9(1) t1" +== 139 +-- truncate_limit: 100 +SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM getrngfunc9(1) WITH ORDINALITY t1(a, b, c, o)" +== 140 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1)" +== 141 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 142 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 143 +-- truncate_limit: 100 +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o) +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=DDL +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) WITH ORDINALITY t1(a, b, c, o)" +== 144 +-- truncate_limit: 100 +SELECT * FROM vw_getrngfunc +-- +TABLE: name="vw_getrngfunc" schema="" table="vw_getrngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_getrngfunc" +== 145 +-- truncate_limit: 100 +DROP VIEW vw_getrngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_getrngfunc" +== 146 +-- truncate_limit: 100 +-- mix 'n match kinds, to exercise expandRTE and related logic + +select * from rows from(getrngfunc1(1),getrngfunc2(1),getrngfunc3(1),getrngfunc4(1),getrngfunc5(1), + getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc8(1),getrngfunc9(1)) + with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u) +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (getrngfunc1(1) , getrngfunc2(1) , getrngfunc3(1) , getrngfunc4(1) , getr..." +== 147 +-- truncate_limit: 100 +select * from rows from(getrngfunc9(1),getrngfunc8(1), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc5(1),getrngfunc4(1),getrngfunc3(1),getrngfunc2(1),getrngfunc1(1)) + with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u) +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=Call +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=Call +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=Call +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=Call +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=Call +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=Call +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (getrngfunc9(1) , getrngfunc8(1) , getrngfunc7(1) AS (rngfuncid int, rngf..." +== 148 +-- truncate_limit: 100 +create temporary view vw_rngfunc as + select * from rows from(getrngfunc9(1), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc1(1)) + with ordinality as t1(a,b,c,d,e,f,g,n) +-- +TABLE: name="vw_rngfunc" schema="" table="vw_rngfunc" ctx=DDL +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=Call +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=Call +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW vw_rngfunc AS SELECT * FROM ROWS FROM (getrngfunc9(1) , getrngfunc7(1) AS (..." +== 149 +-- truncate_limit: 100 +select * from vw_rngfunc +-- +TABLE: name="vw_rngfunc" schema="" table="vw_rngfunc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vw_rngfunc" +== 150 +-- truncate_limit: 100 +select pg_get_viewdef('vw_rngfunc') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vw_rngfunc')" +== 151 +-- truncate_limit: 100 +drop view vw_rngfunc +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vw_rngfunc" +== 152 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc1(int) +-- +FUNCTION: name="getrngfunc1" function="getrngfunc1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc1(int)" +== 153 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc2(int) +-- +FUNCTION: name="getrngfunc2" function="getrngfunc2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc2(int)" +== 154 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc3(int) +-- +FUNCTION: name="getrngfunc3" function="getrngfunc3" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc3(int)" +== 155 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc4(int) +-- +FUNCTION: name="getrngfunc4" function="getrngfunc4" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc4(int)" +== 156 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc5(int) +-- +FUNCTION: name="getrngfunc5" function="getrngfunc5" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc5(int)" +== 157 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc6(int) +-- +FUNCTION: name="getrngfunc6" function="getrngfunc6" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc6(int)" +== 158 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc7(int) +-- +FUNCTION: name="getrngfunc7" function="getrngfunc7" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc7(int)" +== 159 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc8(int) +-- +FUNCTION: name="getrngfunc8" function="getrngfunc8" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc8(int)" +== 160 +-- truncate_limit: 100 +DROP FUNCTION getrngfunc9(int) +-- +FUNCTION: name="getrngfunc9" function="getrngfunc9" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION getrngfunc9(int)" +== 161 +-- truncate_limit: 100 +DROP FUNCTION rngfunct(int) +-- +FUNCTION: name="rngfunct" function="rngfunct" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunct(int)" +== 162 +-- truncate_limit: 100 +DROP TABLE rngfunc2 +-- +TABLE: name="rngfunc2" schema="" table="rngfunc2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rngfunc2" +== 163 +-- truncate_limit: 100 +DROP TABLE rngfunc +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rngfunc" +== 164 +-- truncate_limit: 100 +-- Rescan tests -- +CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq1" +== 165 +-- truncate_limit: 100 +CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq2 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq2" +== 166 +-- truncate_limit: 100 +CREATE TYPE rngfunc_rescan_t AS (i integer, s bigint) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE rngfunc_rescan_t AS (i int, s bigint)" +== 167 +-- truncate_limit: 100 +CREATE FUNCTION rngfunc_sql(int,int) RETURNS setof rngfunc_rescan_t AS 'SELECT i, nextval(''rngfunc_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rngfunc_sql(int, int) RETURNS SETOF rngfunc_rescan_t AS $$SELECT i, nextval('rngf..." +== 168 +-- truncate_limit: 100 +-- plpgsql functions use materialize mode +CREATE FUNCTION rngfunc_mat(int,int) RETURNS setof rngfunc_rescan_t AS 'begin for i in $1..$2 loop return next (i, nextval(''rngfunc_rescan_seq2'')); end loop; end;' LANGUAGE plpgsql +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rngfunc_mat(int, int) RETURNS SETOF rngfunc_rescan_t AS $$begin for i in $1..$2 l..." +== 169 +-- truncate_limit: 100 +--invokes ExecReScanFunctionScan - all these cases should materialize the function only once +-- LEFT JOIN on a condition that the planner can't prove to be true is used to ensure the function +-- is on the inner path of a nestloop join + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 170 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r) LEFT JOIN rngfunc_sql(11, 13) ON (r + i) < 100" +== 171 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 172 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r) LEFT JOIN rngfunc_sql(11, 13) WITH ORDINALITY f(i, s, o) ON (r ..." +== 173 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 174 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r) LEFT JOIN rngfunc_mat(11, 13) ON (r + i) < 100" +== 175 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 176 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100 +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r) LEFT JOIN rngfunc_mat(11, 13) WITH ORDINALITY f(i, s, o) ON (r ..." +== 177 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 178 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( rngfunc_sql(11,13), rngfunc_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100 +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r) LEFT JOIN ROWS FROM (rngfunc_sql(11, 13) , rngfunc_mat(11, 13) ..." +== 179 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) f(i) ON (r+i)<100 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r) LEFT JOIN generate_series(11, 13) f(i) ON (r + i) < 100" +== 180 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) WITH ORDINALITY AS f(i,o) ON (r+i)<100 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r) LEFT JOIN generate_series(11, 13) WITH ORDINALITY f(i, o) ON (r..." +== 181 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) f(i) ON (r+i)<100 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r) LEFT JOIN unnest(ARRAY[10, 20, 30]) f(i) ON (r + i) < 100" +== 182 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) WITH ORDINALITY AS f(i,o) ON (r+i)<100 +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r) LEFT JOIN unnest(ARRAY[10, 20, 30]) WITH ORDINALITY f(i, o) ON ..." +== 183 +-- truncate_limit: 100 +--invokes ExecReScanFunctionScan with chgParam != NULL (using implied LATERAL) + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 184 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_sql(10 + r, 13)" +== 185 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 186 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_sql(10 + r, 13) WITH ORDINALITY f(i, s, o)" +== 187 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 188 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_sql(11, 10 + r)" +== 189 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 190 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_sql(11, 10 + r) WITH ORDINALITY f(i, s, o)" +== 191 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 192 +-- truncate_limit: 100 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (11, 12), (13, 15), (16, 20)) v(r1, r2), rngfunc_sql(r1, r2)" +== 193 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 194 +-- truncate_limit: 100 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r1, r2), rngfunc_sql(r1, r2) WITH ORDINALITY f(i, s, o)" +== 195 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 196 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_mat(10 + r, 13)" +== 197 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 198 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_mat(10 + r, 13) WITH ORDINALITY f(i, s, o)" +== 199 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 200 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_mat(11, 10 + r)" +== 201 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 202 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), rngfunc_mat(11, 10 + r) WITH ORDINALITY f(i, s, o)" +== 203 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 204 +-- truncate_limit: 100 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (11, 12), (13, 15), (16, 20)) v(r1, r2), rngfunc_mat(r1, r2)" +== 205 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 206 +-- truncate_limit: 100 +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2) WITH ORDINALITY AS f(i,s,o) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r1, r2), rngfunc_mat(r1, r2) WITH ORDINALITY f(i, s, o)" +== 207 +-- truncate_limit: 100 +-- selective rescan of multiple functions: + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 208 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(11,11), rngfunc_mat(10+r,13) ) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r), ROWS FROM (rngfunc_sql(11, 11) , rngfunc_mat(10 + r, 13) )" +== 209 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 210 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(11,11) ) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r), ROWS FROM (rngfunc_sql(10 + r, 13) , rngfunc_mat(11, 11) )" +== 211 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 212 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(10+r,13) ) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r), ROWS FROM (rngfunc_sql(10 + r, 13) , rngfunc_mat(10 + r, 13) )" +== 213 +-- truncate_limit: 100 +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('rngfunc_rescan_seq1', 1, false), setval('rngfunc_rescan_seq2', 1, false)" +== 214 +-- truncate_limit: 100 +SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( rngfunc_sql(10+r1,13), rngfunc_mat(10+r2,13) ) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=Call +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(1, 2) r1, generate_series(r1, 3) r2, ROWS FROM (rngfunc_sql(10 + r1..." +== 215 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) f(i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), generate_series(10 + r, 20 - r) f(i)" +== 216 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) WITH ORDINALITY AS f(i,o) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), generate_series(10 + r, 20 - r) WITH ORDINALITY f(i, o)" +== 217 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), unnest(array[r*10,r*20,r*30]) f(i) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (1), (2), (3)) v(r), unnest(ARRAY[r * 10, r * 20, r * 30]) f(i)" +== 218 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v(r), unnest(array[r*10,r*20,r*30]) WITH ORDINALITY AS f(i,o) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(r), unnest(ARRAY[r * 10, r * 20, r * 30]) WITH ORDINALITY f(i, o)" +== 219 +-- truncate_limit: 100 +-- deep nesting + +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(21,23) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v1(r1), LATERAL (SELECT ... FROM (VALUES (...)) v2(r2) LEFT JOIN gen..." +== 220 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(20+r1,23) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v1(r1), LATERAL (SELECT ... FROM (VALUES (...)) v2(r2) LEFT JOIN gen..." +== 221 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(r2,r2+3) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v1(r1), LATERAL (SELECT ... FROM (VALUES (...)) v2(r2) LEFT JOIN gen..." +== 222 +-- truncate_limit: 100 +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(r1,2+r2/5) f(i) ON ((r2+i)<100) OFFSET 0) s1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v1(r1), LATERAL (SELECT ... FROM (VALUES (...)) v2(r2) LEFT JOIN gen..." +== 223 +-- truncate_limit: 100 +-- check handling of FULL JOIN with multiple lateral references (bug #15741) + +SELECT * +FROM (VALUES (1),(2)) v1(r1) + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, v1.r1) AS gs1 + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, gs1) AS gs2 + LEFT JOIN generate_series(1, gs2) AS gs3 ON TRUE + ) AS ss1 ON TRUE + FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE + ) AS ss0 ON TRUE +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v1(r1) LEFT JOIN LATERAL (SELECT * FROM generate_series(1, v1.r1) gs..." +== 224 +-- truncate_limit: 100 +DROP FUNCTION rngfunc_sql(int,int) +-- +FUNCTION: name="rngfunc_sql" function="rngfunc_sql" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunc_sql(int, int)" +== 225 +-- truncate_limit: 100 +DROP FUNCTION rngfunc_mat(int,int) +-- +FUNCTION: name="rngfunc_mat" function="rngfunc_mat" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunc_mat(int, int)" +== 226 +-- truncate_limit: 100 +DROP SEQUENCE rngfunc_rescan_seq1 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE rngfunc_rescan_seq1" +== 227 +-- truncate_limit: 100 +DROP SEQUENCE rngfunc_rescan_seq2 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE rngfunc_rescan_seq2" +== 228 +-- truncate_limit: 100 +|-- +-- Test cases involving OUT parameters +|-- + +CREATE FUNCTION rngfunc(in f1 int, out f2 int) +AS 'select $1+1' LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rngfunc(IN f1 int, OUT f2 int) AS $$select $1+1$$ LANGUAGE sql" +== 229 +-- truncate_limit: 100 +SELECT rngfunc(42) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rngfunc(42)" +== 230 +-- truncate_limit: 100 +SELECT * FROM rngfunc(42) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc(42)" +== 231 +-- truncate_limit: 100 +SELECT * FROM rngfunc(42) AS p(x) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc(42) p(x)" +== 232 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfunc(IN f1 int, OUT f2 int) RETURNS int AS $$select $1+1$$ LANGUAGE..." +== 233 +-- truncate_limit: 100 +-- error, wrong result type +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS float +AS 'select $1+1' LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfunc(IN f1 int, OUT f2 int) RETURNS double precision AS $$select $1..." +== 234 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfunc(IN f1 int, OUT f2 int, OUT f3 text) RETURNS int AS $$select $1..." +== 235 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) +RETURNS record +AS 'select $1+1' LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfunc(IN f1 int, OUT f2 int, OUT f3 text) RETURNS record AS $$select..." +== 236 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION rngfuncr(in f1 int, out f2 int, out text) +AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfuncr(IN f1 int, OUT f2 int, OUT text) AS $$select $1-1, $1::text |..." +== 237 +-- truncate_limit: 100 +SELECT f1, rngfuncr(f1) FROM int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, rngfuncr(f1) FROM int4_tbl" +== 238 +-- truncate_limit: 100 +SELECT * FROM rngfuncr(42) +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncr(42)" +== 239 +-- truncate_limit: 100 +SELECT * FROM rngfuncr(42) AS p(a,b) +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncr(42) p(a, b)" +== 240 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION rngfuncb(in f1 int, inout f2 int, out text) +AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfuncb(IN f1 int, INOUT f2 int, OUT text) AS $$select $2-1, $1::text..." +== 241 +-- truncate_limit: 100 +SELECT f1, rngfuncb(f1, f1/2) FROM int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, rngfuncb(f1, f1 / 2) FROM int4_tbl" +== 242 +-- truncate_limit: 100 +SELECT * FROM rngfuncb(42, 99) +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncb(42, 99)" +== 243 +-- truncate_limit: 100 +SELECT * FROM rngfuncb(42, 99) AS p(a,b) +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncb(42, 99) p(a, b)" +== 244 +-- truncate_limit: 100 +-- Can reference function with or without OUT params for DROP, etc +DROP FUNCTION rngfunc(int) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunc(int)" +== 245 +-- truncate_limit: 100 +DROP FUNCTION rngfuncr(in f2 int, out f1 int, out text) +-- +FUNCTION: name="rngfuncr" function="rngfuncr" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfuncr(IN f2 int, OUT f1 int, OUT text)" +== 246 +-- truncate_limit: 100 +DROP FUNCTION rngfuncb(in f1 int, inout f2 int) +-- +FUNCTION: name="rngfuncb" function="rngfuncb" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfuncb(IN f1 int, INOUT f2 int)" +== 247 +-- truncate_limit: 100 +|-- +-- 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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dup(f1 anyelement, OUT f2 anyelement, OUT f3 anyarray) AS $$select $1, array[$1,$..." +== 248 +-- truncate_limit: 100 +SELECT dup(22) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(22)" +== 249 +-- truncate_limit: 100 +SELECT dup('xyz') +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup('xyz')" +== 250 +-- truncate_limit: 100 +-- fails +SELECT dup('xyz'::text) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup('xyz'::text)" +== 251 +-- truncate_limit: 100 +SELECT * FROM dup('xyz'::text) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM dup('xyz'::text)" +== 252 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dup(INOUT f2 anyelement, OUT f3 anyarray) AS $$select $1, array[$1,$1]..." +== 253 +-- truncate_limit: 100 +DROP FUNCTION dup(anyelement) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dup(anyelement)" +== 254 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dup(INOUT f2 anyelement, OUT f3 anyarray) AS $$select $1, array[$1,$1]..." +== 255 +-- truncate_limit: 100 +SELECT dup(22) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(22)" +== 256 +-- truncate_limit: 100 +DROP FUNCTION dup(anyelement) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dup(anyelement)" +== 257 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="bad" function="bad" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bad(f1 int, OUT f2 anyelement, OUT f3 anyarray) AS $$select $1, array[$1,$1]$$ LA..." +== 258 +-- truncate_limit: 100 +CREATE FUNCTION dup (f1 anycompatible, f2 anycompatiblearray, f3 out anycompatible, f4 out anycompatiblearray) +AS 'select $1, $2' LANGUAGE sql +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dup(f1 anycompatible, f2 anycompatiblearray, OUT f3 anycompatible, OUT f4 anycomp..." +== 259 +-- truncate_limit: 100 +SELECT dup(22, array[44]) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(22, ARRAY[44])" +== 260 +-- truncate_limit: 100 +SELECT dup(4.5, array[44]) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(4.5, ARRAY[44])" +== 261 +-- truncate_limit: 100 +SELECT dup(22, array[44::bigint]) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(22, ARRAY[44::bigint])" +== 262 +-- truncate_limit: 100 +SELECT *, pg_typeof(f3), pg_typeof(f4) FROM dup(22, array[44::bigint]) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="dup" function="dup" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, pg_typeof(f3), pg_typeof(f4) FROM dup(22, ARRAY[44::bigint])" +== 263 +-- truncate_limit: 100 +DROP FUNCTION dup(f1 anycompatible, f2 anycompatiblearray) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dup(f1 anycompatible, f2 anycompatiblearray)" +== 264 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dup(f1 anycompatiblerange, OUT f2 anycompatible, OUT f3 anycompatiblearray, OUT f..." +== 265 +-- truncate_limit: 100 +SELECT dup(int4range(4,7)) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(int4range(4, 7))" +== 266 +-- truncate_limit: 100 +SELECT dup(numrange(4,7)) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(numrange(4, 7))" +== 267 +-- truncate_limit: 100 +SELECT dup(textrange('aaa', 'bbb')) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dup(textrange('aaa', 'bbb'))" +== 268 +-- truncate_limit: 100 +DROP FUNCTION dup(f1 anycompatiblerange) +-- +FUNCTION: name="dup" function="dup" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dup(f1 anycompatiblerange)" +== 269 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="bad" function="bad" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bad(f1 anyarray, OUT f2 anycompatible, OUT f3 anycompatiblearray) AS $$select $1,..." +== 270 +-- truncate_limit: 100 +|-- +-- table functions +|-- + +CREATE OR REPLACE FUNCTION rngfunc() +RETURNS TABLE(a int) +AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfunc() RETURNS TABLE (a int) AS $$ SELECT a FROM generate_series(1,..." +== 271 +-- truncate_limit: 100 +SELECT * FROM rngfunc() +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc()" +== 272 +-- truncate_limit: 100 +DROP FUNCTION rngfunc() +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunc()" +== 273 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfunc(int) RETURNS TABLE (a int, b int) AS $$ SELECT a, b\n F..." +== 274 +-- truncate_limit: 100 +SELECT * FROM rngfunc(3) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc(3)" +== 275 +-- truncate_limit: 100 +DROP FUNCTION rngfunc(int) +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunc(int)" +== 276 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfunc() RETURNS TABLE (a varchar(5)) AS $$ SELECT 'hello'::varchar(5..." +== 277 +-- truncate_limit: 100 +SELECT * FROM rngfunc() GROUP BY 1 +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfunc() GROUP BY 1" +== 278 +-- truncate_limit: 100 +DROP FUNCTION rngfunc() +-- +FUNCTION: name="rngfunc" function="rngfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunc()" +== 279 +-- truncate_limit: 100 +|-- +-- some tests on SQL functions with RETURNING +|-- + +create temp table tt(f1 serial, data text) +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt (f1 serial, data text)" +== 280 +-- truncate_limit: 100 +create function insert_tt(text) returns int as +$$ insert into tt(data) values($1) returning f1 $$ +language sql +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION insert_tt(text) RETURNS int AS $$ insert into tt(data) values($1) returning f1 $$..." +== 281 +-- truncate_limit: 100 +select insert_tt('foo') +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT insert_tt('foo')" +== 282 +-- truncate_limit: 100 +select insert_tt('bar') +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT insert_tt('bar')" +== 283 +-- truncate_limit: 100 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt" +== 284 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION insert_tt(text) RETURNS int AS $$ insert into tt(data) values($1),($1|..." +== 285 +-- truncate_limit: 100 +select insert_tt('fool') +-- +FUNCTION: name="insert_tt" function="insert_tt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT insert_tt('fool')" +== 286 +-- truncate_limit: 100 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt" +== 287 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION insert_tt2(text, text) RETURNS SETOF int AS $$ insert into tt(data) va..." +== 288 +-- truncate_limit: 100 +select insert_tt2('foolish','barrish') +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT insert_tt2('foolish', 'barrish')" +== 289 +-- truncate_limit: 100 +select * from insert_tt2('baz','quux') +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM insert_tt2('baz', 'quux')" +== 290 +-- truncate_limit: 100 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt" +== 291 +-- truncate_limit: 100 +-- limit doesn't prevent execution to completion +select insert_tt2('foolish','barrish') limit 1 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT insert_tt2('foolish', 'barrish') LIMIT 1" +== 292 +-- truncate_limit: 100 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt" +== 293 +-- truncate_limit: 100 +-- triggers will fire, too +create function noticetrigger() returns trigger as $$ +begin + raise notice 'noticetrigger % %', new.f1, new.data; + return null; +end $$ language plpgsql +-- +FUNCTION: name="noticetrigger" function="noticetrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION noticetrigger() RETURNS trigger AS $$\nbegin\n raise notice 'noticetrigger % %', n..." +== 294 +-- truncate_limit: 100 +create trigger tnoticetrigger after insert on tt for each row +execute procedure noticetrigger() +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tnoticetrigger AFTER INSERT ON tt FOR EACH ROW EXECUTE FUNCTION noticetrigger()" +== 295 +-- truncate_limit: 100 +select insert_tt2('foolme','barme') limit 1 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT insert_tt2('foolme', 'barme') LIMIT 1" +== 296 +-- truncate_limit: 100 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt" +== 297 +-- truncate_limit: 100 +-- and rules work +create temp table tt_log(f1 int, data text) +-- +TABLE: name="tt_log" schema="" table="tt_log" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt_log (f1 int, data text)" +== 298 +-- truncate_limit: 100 +create rule insert_tt_rule as on insert to tt do also + insert into tt_log values(new.*) +-- +TABLE: name="tt" schema="" table="tt" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE insert_tt_rule AS ON INSERT TO tt DO INSERT INTO tt_log VALUES (new.*)" +== 299 +-- truncate_limit: 100 +select insert_tt2('foollog','barlog') limit 1 +-- +FUNCTION: name="insert_tt2" function="insert_tt2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT insert_tt2('foollog', 'barlog') LIMIT 1" +== 300 +-- truncate_limit: 100 +select * from tt +-- +TABLE: name="tt" schema="" table="tt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt" +== 301 +-- truncate_limit: 100 +-- note that nextval() gets executed a second time in the rule expansion, +-- which is expected. +select * from tt_log +-- +TABLE: name="tt_log" schema="" table="tt_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tt_log" +== 302 +-- truncate_limit: 100 +-- 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 $$ +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rngfunc1(n int, OUT a text, OUT b text) RETURNS SETOF record LANGUAGE sql AS $$ s..." +== 303 +-- truncate_limit: 100 +set work_mem='64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 304 +-- truncate_limit: 100 +select t.a, t, t.a from rngfunc1(10000) t limit 1 +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT t.a, t, t.a FROM rngfunc1(10000) t LIMIT 1" +== 305 +-- truncate_limit: 100 +reset work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET work_mem" +== 306 +-- truncate_limit: 100 +select t.a, t, t.a from rngfunc1(10000) t limit 1 +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT t.a, t, t.a FROM rngfunc1(10000) t LIMIT 1" +== 307 +-- truncate_limit: 100 +drop function rngfunc1(n integer) +-- +FUNCTION: name="rngfunc1" function="rngfunc1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfunc1(n int)" +== 308 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION array_to_set(anyarray) RETURNS SETOF record AS $$\n select i AS \"index\", $1[i] AS..." +== 309 +-- truncate_limit: 100 +select array_to_set(array['one', 'two']) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_set(ARRAY['one', 'two'])" +== 310 +-- truncate_limit: 100 +select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 int, f2 text)" +== 311 +-- truncate_limit: 100 +select * from array_to_set(array['one', 'two']) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_to_set(ARRAY['one', 'two'])" +== 312 +-- truncate_limit: 100 +-- fail +-- 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) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 numeric(4, 2), f2 text)" +== 313 +-- truncate_limit: 100 +-- 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) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 point, f2 text)" +== 314 +-- truncate_limit: 100 +-- 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) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 numeric(4, 2),..." +== 315 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION array_to_set(anyarray) RETURNS SETOF record AS $$\n select i AS \"index..." +== 316 +-- truncate_limit: 100 +select array_to_set(array['one', 'two']) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_set(ARRAY['one', 'two'])" +== 317 +-- truncate_limit: 100 +select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 int, f2 text)" +== 318 +-- truncate_limit: 100 +select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 numeric(4, 2), f2 text)" +== 319 +-- truncate_limit: 100 +select * from array_to_set(array['one', 'two']) as t(f1 point,f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 point, f2 text)" +== 320 +-- truncate_limit: 100 +explain (verbose, costs off) + select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text) +-- +FUNCTION: name="array_to_set" function="array_to_set" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM array_to_set(ARRAY['one', 'two']) t (f1 numeric(4, 2),..." +== 321 +-- truncate_limit: 100 +create temp table rngfunc(f1 int8, f2 int8) +-- +TABLE: name="rngfunc" schema="" table="rngfunc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE rngfunc (f1 int8, f2 int8)" +== 322 +-- truncate_limit: 100 +create function testrngfunc() returns record as $$ + insert into rngfunc values (1,2) returning *; +$$ language sql +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testrngfunc() RETURNS record AS $$\n insert into rngfunc values (1,2) returning *..." +== 323 +-- truncate_limit: 100 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testrngfunc()" +== 324 +-- truncate_limit: 100 +select * from testrngfunc() as t(f1 int8,f2 int8) +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc() t (f1 int8, f2 int8)" +== 325 +-- truncate_limit: 100 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc()" +== 326 +-- truncate_limit: 100 +-- fail + +drop function testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testrngfunc()" +== 327 +-- truncate_limit: 100 +create function testrngfunc() returns setof record as $$ + insert into rngfunc values (1,2), (3,4) returning *; +$$ language sql +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testrngfunc() RETURNS SETOF record AS $$\n insert into rngfunc values (1,2), (3,4..." +== 328 +-- truncate_limit: 100 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testrngfunc()" +== 329 +-- truncate_limit: 100 +select * from testrngfunc() as t(f1 int8,f2 int8) +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc() t (f1 int8, f2 int8)" +== 330 +-- truncate_limit: 100 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc()" +== 331 +-- truncate_limit: 100 +-- fail + +drop function testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testrngfunc()" +== 332 +-- truncate_limit: 100 +-- Check that typmod imposed by a composite type is honored +create type rngfunc_type as (f1 numeric(35,6), f2 numeric(35,2)) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE rngfunc_type AS (f1 numeric(35, 6), f2 numeric(35, 2))" +== 333 +-- truncate_limit: 100 +create function testrngfunc() returns rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql immutable +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testrngfunc() RETURNS rngfunc_type AS $$\n select 7.136178319899999964, 7.1361783..." +== 334 +-- truncate_limit: 100 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT testrngfunc()" +== 335 +-- truncate_limit: 100 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testrngfunc()" +== 336 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM testrngfunc()" +== 337 +-- truncate_limit: 100 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc()" +== 338 +-- truncate_limit: 100 +create or replace function testrngfunc() returns rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql volatile +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION testrngfunc() RETURNS rngfunc_type AS $$\n select 7.136178319899999964..." +== 339 +-- truncate_limit: 100 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT testrngfunc()" +== 340 +-- truncate_limit: 100 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testrngfunc()" +== 341 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM testrngfunc()" +== 342 +-- truncate_limit: 100 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc()" +== 343 +-- truncate_limit: 100 +drop function testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION testrngfunc()" +== 344 +-- truncate_limit: 100 +create function testrngfunc() returns setof rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql immutable +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION testrngfunc() RETURNS SETOF rngfunc_type AS $$\n select 7.136178319899999964, 7.1..." +== 345 +-- truncate_limit: 100 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT testrngfunc()" +== 346 +-- truncate_limit: 100 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testrngfunc()" +== 347 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM testrngfunc()" +== 348 +-- truncate_limit: 100 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc()" +== 349 +-- truncate_limit: 100 +create or replace function testrngfunc() returns setof rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql volatile +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION testrngfunc() RETURNS SETOF rngfunc_type AS $$\n select 7.136178319899..." +== 350 +-- truncate_limit: 100 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT testrngfunc()" +== 351 +-- truncate_limit: 100 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testrngfunc()" +== 352 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM testrngfunc()" +== 353 +-- truncate_limit: 100 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc()" +== 354 +-- truncate_limit: 100 +create or replace function testrngfunc() returns setof rngfunc_type as $$ + select 1, 2 union select 3, 4 order by 1; +$$ language sql immutable +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION testrngfunc() RETURNS SETOF rngfunc_type AS $$\n select 1, 2 union sel..." +== 355 +-- truncate_limit: 100 +explain (verbose, costs off) +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT testrngfunc()" +== 356 +-- truncate_limit: 100 +select testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT testrngfunc()" +== 357 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM testrngfunc()" +== 358 +-- truncate_limit: 100 +select * from testrngfunc() +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc()" +== 359 +-- truncate_limit: 100 +-- Check a couple of error cases while we're here +select * from testrngfunc() as t(f1 int8,f2 int8) +-- +FUNCTION: name="testrngfunc" function="testrngfunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testrngfunc() t (f1 int8, f2 int8)" +== 360 +-- truncate_limit: 100 +-- fail, composite result +select * from pg_get_keywords() as t(f1 int8,f2 int8) +-- +FUNCTION: name="pg_get_keywords" function="pg_get_keywords" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_get_keywords() t (f1 int8, f2 int8)" +== 361 +-- truncate_limit: 100 +-- fail, OUT params +select * from sin(3) as t(f1 int8,f2 int8) +-- +FUNCTION: name="sin" function="sin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM sin(3) t (f1 int8, f2 int8)" +== 362 +-- truncate_limit: 100 +-- fail, scalar result type + +drop type rngfunc_type cascade +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE rngfunc_type CASCADE" +== 363 +-- truncate_limit: 100 +|-- +-- 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) +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE users (userid text, seq int, email text, todrop bool, moredrop int, enable..." +== 364 +-- truncate_limit: 100 +insert into users values ('id',1,'email',true,11,true) +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users VALUES ('id', 1, 'email', true, 11, true)" +== 365 +-- truncate_limit: 100 +insert into users values ('id2',2,'email2',true,12,true) +-- +TABLE: name="users" schema="" table="users" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO users VALUES ('id2', 2, 'email2', true, 12, true)" +== 366 +-- truncate_limit: 100 +alter table users drop column todrop +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE users DROP todrop" +== 367 +-- truncate_limit: 100 +create or replace function get_first_user() returns users as +$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$ +language sql stable +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION get_first_user() RETURNS users AS $$ SELECT * FROM users ORDER BY user..." +== 368 +-- truncate_limit: 100 +SELECT get_first_user() +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT get_first_user()" +== 369 +-- truncate_limit: 100 +SELECT * FROM get_first_user() +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM get_first_user()" +== 370 +-- truncate_limit: 100 +create or replace function get_users() returns setof users as +$$ SELECT * FROM users ORDER BY userid; $$ +language sql stable +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION get_users() RETURNS SETOF users AS $$ SELECT * FROM users ORDER BY use..." +== 371 +-- truncate_limit: 100 +SELECT get_users() +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT get_users()" +== 372 +-- truncate_limit: 100 +SELECT * FROM get_users() +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM get_users()" +== 373 +-- truncate_limit: 100 +SELECT * FROM get_users() WITH ORDINALITY +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM get_users() WITH ORDINALITY" +== 374 +-- truncate_limit: 100 +-- make sure ordinality copes + +-- multiple functions vs. dropped columns +SELECT * FROM ROWS FROM(generate_series(10,11), get_users()) WITH ORDINALITY +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (generate_series(10, 11) , get_users() ) WITH ORDINALITY" +== 375 +-- truncate_limit: 100 +SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ROWS FROM (get_users() , generate_series(10, 11) ) WITH ORDINALITY" +== 376 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="usersview" schema="" table="usersview" ctx=DDL +FUNCTION: name="get_users" function="get_users" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW usersview AS SELECT * FROM ROWS FROM (get_users() , generate_series(10, 11)..." +== 377 +-- truncate_limit: 100 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM usersview" +== 378 +-- truncate_limit: 100 +alter table users add column junk text +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE users ADD COLUMN junk text" +== 379 +-- truncate_limit: 100 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM usersview" +== 380 +-- truncate_limit: 100 +alter table users drop column moredrop +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE users DROP moredrop" +== 381 +-- truncate_limit: 100 +-- fail, view has reference + +-- We used to have a bug that would allow the above to succeed, posing +-- hazards for later execution of the view. Check that the internal +-- defenses for those hazards haven't bit-rotted, in case some other +-- bug with similar symptoms emerges. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 382 +-- truncate_limit: 100 +-- destroy the dependency entry that prevents the DROP: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'usersview'::regclass and rulename = '_RETURN') + and refobjsubid = 5 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM pg_depend WHERE ... RETURNING pg_describe_object(classid, objid, objsubid) AS obj, pg..." +== 383 +-- truncate_limit: 100 +alter table users drop column moredrop +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE users DROP moredrop" +== 384 +-- truncate_limit: 100 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM usersview" +== 385 +-- truncate_limit: 100 +-- expect clean failure +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 386 +-- truncate_limit: 100 +alter table users alter column seq type numeric +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE users ALTER COLUMN seq TYPE numeric" +== 387 +-- truncate_limit: 100 +-- fail, view has reference + +-- likewise, check we don't crash if the dependency goes wrong +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 388 +-- truncate_limit: 100 +-- destroy the dependency entry that prevents the ALTER: +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'usersview'::regclass and rulename = '_RETURN') + and refobjsubid = 2 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype +-- +TABLE: name="pg_depend" schema="" table="pg_depend" ctx=DML +TABLE: name="pg_rewrite" schema="" table="pg_rewrite" ctx=Select +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FILTER: schema="" table="" column="ev_class" +FILTER: schema="" table="" column="rulename" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM pg_depend WHERE ... RETURNING pg_describe_object(classid, objid, objsubid) AS obj, pg..." +== 389 +-- truncate_limit: 100 +alter table users alter column seq type numeric +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE users ALTER COLUMN seq TYPE numeric" +== 390 +-- truncate_limit: 100 +select * from usersview +-- +TABLE: name="usersview" schema="" table="usersview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM usersview" +== 391 +-- truncate_limit: 100 +-- expect clean failure +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 392 +-- truncate_limit: 100 +drop view usersview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW usersview" +== 393 +-- truncate_limit: 100 +drop function get_first_user() +-- +FUNCTION: name="get_first_user" function="get_first_user" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION get_first_user()" +== 394 +-- truncate_limit: 100 +drop function get_users() +-- +FUNCTION: name="get_users" function="get_users" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION get_users()" +== 395 +-- truncate_limit: 100 +drop table users +-- +TABLE: name="users" schema="" table="users" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE users" +== 396 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfuncbar() RETURNS SETOF text AS $$ select 'foo'::varchar union all ..." +== 397 +-- truncate_limit: 100 +select rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rngfuncbar()" +== 398 +-- truncate_limit: 100 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncbar()" +== 399 +-- truncate_limit: 100 +-- this function is now inlinable, too: +explain (verbose, costs off) select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM rngfuncbar()" +== 400 +-- truncate_limit: 100 +drop function rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfuncbar()" +== 401 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfuncbar(OUT int, OUT numeric) AS $$ select (1, 2.1) $$ LANGUAGE sql" +== 402 +-- truncate_limit: 100 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncbar()" +== 403 +-- truncate_limit: 100 +create or replace function rngfuncbar(out integer, out numeric) as +$$ select (1, 2) $$ language sql +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfuncbar(OUT int, OUT numeric) AS $$ select (1, 2) $$ LANGUAGE sql" +== 404 +-- truncate_limit: 100 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncbar()" +== 405 +-- truncate_limit: 100 +-- fail + +create or replace function rngfuncbar(out integer, out numeric) as +$$ select (1, 2.1, 3) $$ language sql +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION rngfuncbar(OUT int, OUT numeric) AS $$ select (1, 2.1, 3) $$ LANGUAGE sql" +== 406 +-- truncate_limit: 100 +select * from rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rngfuncbar()" +== 407 +-- truncate_limit: 100 +-- fail + +drop function rngfuncbar() +-- +FUNCTION: name="rngfuncbar" function="rngfuncbar" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rngfuncbar()" +== 408 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="extractq2" function="extractq2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION extractq2(t int8_tbl) RETURNS int8 AS $$\n select t.q2\n$$ LANGUAGE sql IMMUTABLE" +== 409 +-- truncate_limit: 100 +explain (verbose, costs off) +select x from int8_tbl, extractq2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2" function="extractq2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT x FROM int8_tbl, extractq2(int8_tbl) f(x)" +== 410 +-- truncate_limit: 100 +select x from int8_tbl, extractq2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2" function="extractq2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x FROM int8_tbl, extractq2(int8_tbl) f(x)" +== 411 +-- truncate_limit: 100 +create function extractq2_2(t int8_tbl) returns table(ret1 int8) as $$ + select extractq2(t) offset 0 +$$ language sql immutable +-- +FUNCTION: name="extractq2_2" function="extractq2_2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION extractq2_2(t int8_tbl) RETURNS TABLE (ret1 int8) AS $$\n select extractq2(t) off..." +== 412 +-- truncate_limit: 100 +explain (verbose, costs off) +select x from int8_tbl, extractq2_2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2" function="extractq2_2" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT x FROM int8_tbl, extractq2_2(int8_tbl) f(x)" +== 413 +-- truncate_limit: 100 +select x from int8_tbl, extractq2_2(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2" function="extractq2_2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x FROM int8_tbl, extractq2_2(int8_tbl) f(x)" +== 414 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="extractq2_2_opt" function="extractq2_2_opt" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION extractq2_2_opt(t int8_tbl) RETURNS TABLE (ret1 int8) AS $$\n select extractq2(t)..." +== 415 +-- truncate_limit: 100 +explain (verbose, costs off) +select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2_opt" function="extractq2_2_opt" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT x FROM int8_tbl, extractq2_2_opt(int8_tbl) f(x)" +== 416 +-- truncate_limit: 100 +select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="extractq2_2_opt" function="extractq2_2_opt" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x FROM int8_tbl, extractq2_2_opt(int8_tbl) f(x)" +== 417 +-- truncate_limit: 100 +-- check handling of nulls in SRF results (bug #7808) + +create type rngfunc2 as (a integer, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE rngfunc2 AS (a int, b text)" +== 418 +-- truncate_limit: 100 +select *, row_to_json(u) from unnest(array[(1,'foo')::rngfunc2, null::rngfunc2]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, row_to_json(u) FROM unnest(ARRAY[(1, 'foo')::rngfunc2, NULL::rngfunc2]) u" +== 419 +-- truncate_limit: 100 +select *, row_to_json(u) from unnest(array[null::rngfunc2, null::rngfunc2]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, row_to_json(u) FROM unnest(ARRAY[NULL::rngfunc2, NULL::rngfunc2]) u" +== 420 +-- truncate_limit: 100 +select *, row_to_json(u) from unnest(array[null::rngfunc2, (1,'foo')::rngfunc2, null::rngfunc2]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, row_to_json(u) FROM unnest(ARRAY[NULL::rngfunc2, (1, 'foo')::rngfunc2, NULL::rngfunc2]) u" +== 421 +-- truncate_limit: 100 +select *, row_to_json(u) from unnest(array[]::rngfunc2[]) u +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, row_to_json(u) FROM unnest(ARRAY[]::rngfunc2[]) u" +== 422 +-- truncate_limit: 100 +drop type rngfunc2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE rngfunc2" +== 423 +-- truncate_limit: 100 +-- 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) +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT jsonb_path_query_array(module -> 'lectures', '..." +== 424 +-- truncate_limit: 100 +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) +-- +FUNCTION: name="jsonb_path_query_array" function="jsonb_path_query_array" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="jsonb_to_recordset" function="jsonb_to_recordset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM unnest(ARRAY['{\"lectures\": [{\"id\": \"1\"}]}'::jsonb]) unnested_modul..." +== 425 +-- truncate_limit: 100 +-- check detection of mismatching record types with a const-folded expression + +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int) +-- +CTE: "a" +STMT: SelectStmt +TRUNCATED: "WITH a(b) AS (VALUES (ROW(1, 2, 3))) SELECT * FROM a, COALESCE(b) c (d int, e int)" +== 426 +-- truncate_limit: 100 +-- fail +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int, f int, g int) +-- +CTE: "a" +STMT: SelectStmt +TRUNCATED: "WITH a(b) AS (VALUES (ROW(1, 2, 3))) SELECT * FROM a, COALESCE(b) c (d int, e int, f int, g int)" +== 427 +-- truncate_limit: 100 +-- fail +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int, f float) +-- +CTE: "a" +STMT: SelectStmt +TRUNCATED: "WITH a(b) AS (VALUES (...)) SELECT * FROM a, COALESCE(b) c (d int, e int, f double precision)" +== 428 +-- truncate_limit: 100 +-- fail +select * from int8_tbl, coalesce(row(1)) as (a int, b int) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl, COALESCE(ROW(1)) AS (a int, b int)" diff --git a/parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json new file mode 100644 index 0000000..fa6f7df --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json @@ -0,0 +1,411 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/rangetypes.test b/parser/testdata/summary_truncate/postgres_regress/rangetypes.test new file mode 100644 index 0000000..051c790 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rangetypes.test @@ -0,0 +1,3616 @@ +== 001 +-- truncate_limit: 100 +-- Tests for range data types. + +|-- +-- test input parser +-- (type textrange was already made in test_setup.sql) +|-- + +-- negative tests; should fail +select ''::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::textrange" +== 002 +-- truncate_limit: 100 +select '-[a,z)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-[a,z)'::textrange" +== 003 +-- truncate_limit: 100 +select '[a,z) - '::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[a,z) - '::textrange" +== 004 +-- truncate_limit: 100 +select '(",a)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(\",a)'::textrange" +== 005 +-- truncate_limit: 100 +select '(,,a)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(,,a)'::textrange" +== 006 +-- truncate_limit: 100 +select '(),a)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(),a)'::textrange" +== 007 +-- truncate_limit: 100 +select '(a,))'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(a,))'::textrange" +== 008 +-- truncate_limit: 100 +select '(],a)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(],a)'::textrange" +== 009 +-- truncate_limit: 100 +select '(a,])'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(a,])'::textrange" +== 010 +-- truncate_limit: 100 +select '[z,a]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[z,a]'::textrange" +== 011 +-- truncate_limit: 100 +-- should succeed +select ' empty '::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' empty '::textrange" +== 012 +-- truncate_limit: 100 +select ' ( empty, empty ) '::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' ( empty, empty ) '::textrange" +== 013 +-- truncate_limit: 100 +select ' ( " a " " a ", " z " " z " ) '::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' ( \" a \" \" a \", \" z \" \" z \" ) '::textrange" +== 014 +-- truncate_limit: 100 +select '(a,)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(a,)'::textrange" +== 015 +-- truncate_limit: 100 +select '[,z]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[,z]'::textrange" +== 016 +-- truncate_limit: 100 +select '[a,]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[a,]'::textrange" +== 017 +-- truncate_limit: 100 +select '(,)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(,)'::textrange" +== 018 +-- truncate_limit: 100 +select '[ , ]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[ , ]'::textrange" +== 019 +-- truncate_limit: 100 +select '["",""]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\"\",\"\"]'::textrange" +== 020 +-- truncate_limit: 100 +select '[",",","]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[\",\",\",\"]'::textrange" +== 021 +-- truncate_limit: 100 +select '["\\","\\"]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'[\"\\\\\\\\\",\"\\\\\\\\\"]'::textrange" +== 022 +-- truncate_limit: 100 +select '(\\,a)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'(\\\\\\\\,a)'::textrange" +== 023 +-- truncate_limit: 100 +select '((,z)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '((,z)'::textrange" +== 024 +-- truncate_limit: 100 +select '([,z)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '([,z)'::textrange" +== 025 +-- truncate_limit: 100 +select '(!,()'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(!,()'::textrange" +== 026 +-- truncate_limit: 100 +select '(!,[)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(!,[)'::textrange" +== 027 +-- truncate_limit: 100 +select '[a,a]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[a,a]'::textrange" +== 028 +-- truncate_limit: 100 +-- these are allowed but normalize to empty: +select '[a,a)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[a,a)'::textrange" +== 029 +-- truncate_limit: 100 +select '(a,a]'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(a,a]'::textrange" +== 030 +-- truncate_limit: 100 +select '(a,a)'::textrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(a,a)'::textrange" +== 031 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +select pg_input_is_valid('(1,4)', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,4)', 'int4range')" +== 032 +-- truncate_limit: 100 +select pg_input_is_valid('(1,4', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,4', 'int4range')" +== 033 +-- truncate_limit: 100 +select * from pg_input_error_info('(1,4', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(1,4', 'int4range')" +== 034 +-- truncate_limit: 100 +select pg_input_is_valid('(4,1)', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(4,1)', 'int4range')" +== 035 +-- truncate_limit: 100 +select * from pg_input_error_info('(4,1)', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(4,1)', 'int4range')" +== 036 +-- truncate_limit: 100 +select pg_input_is_valid('(4,zed)', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(4,zed)', 'int4range')" +== 037 +-- truncate_limit: 100 +select * from pg_input_error_info('(4,zed)', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(4,zed)', 'int4range')" +== 038 +-- truncate_limit: 100 +select pg_input_is_valid('[1,2147483647]', 'int4range') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('[1,2147483647]', 'int4range')" +== 039 +-- truncate_limit: 100 +select * from pg_input_error_info('[1,2147483647]', 'int4range') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('[1,2147483647]', 'int4range')" +== 040 +-- truncate_limit: 100 +select pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange')" +== 041 +-- truncate_limit: 100 +select * from pg_input_error_info('[2000-01-01,5874897-12-31]', 'daterange') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('[2000-01-01,5874897-12-31]', 'daterange')" +== 042 +-- truncate_limit: 100 +|-- +-- create some test data and test the operators +|-- + +CREATE TABLE numrange_test (nr NUMRANGE) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE numrange_test (nr numrange)" +== 043 +-- truncate_limit: 100 +create index numrange_test_btree on numrange_test(nr) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX numrange_test_btree ON numrange_test USING btree (nr)" +== 044 +-- truncate_limit: 100 +INSERT INTO numrange_test VALUES('[,)') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test VALUES ('[,)')" +== 045 +-- truncate_limit: 100 +INSERT INTO numrange_test VALUES('[3,]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test VALUES ('[3,]')" +== 046 +-- truncate_limit: 100 +INSERT INTO numrange_test VALUES('[, 5)') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test VALUES ('[, 5)')" +== 047 +-- truncate_limit: 100 +INSERT INTO numrange_test VALUES(numrange(1.1, 2.2)) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test VALUES (numrange(1.1, 2.2))" +== 048 +-- truncate_limit: 100 +INSERT INTO numrange_test VALUES('empty') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test VALUES ('empty')" +== 049 +-- truncate_limit: 100 +INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]')) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test VALUES (numrange(1.7, 1.7, '[]'))" +== 050 +-- truncate_limit: 100 +SELECT nr, isempty(nr), lower(nr), upper(nr) FROM numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="isempty" function="isempty" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nr, isempty(nr), lower(nr), upper(nr) FROM numrange_test" +== 051 +-- truncate_limit: 100 +SELECT nr, lower_inc(nr), lower_inf(nr), upper_inc(nr), upper_inf(nr) FROM numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="lower_inc" function="lower_inc" schema="" ctx=Call +FUNCTION: name="lower_inf" function="lower_inf" schema="" ctx=Call +FUNCTION: name="upper_inc" function="upper_inc" schema="" ctx=Call +FUNCTION: name="upper_inf" function="upper_inf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nr, lower_inc(nr), lower_inf(nr), upper_inc(nr), upper_inf(nr) FROM numrange_test" +== 052 +-- truncate_limit: 100 +SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91)) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9, 1.91))" +== 053 +-- truncate_limit: 100 +SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr @> numrange(1.0, 10000.1)" +== 054 +-- truncate_limit: 100 +SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr) +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7, -10000.1), nr)" +== 055 +-- truncate_limit: 100 +SELECT * FROM numrange_test WHERE 1.9 <@ nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE 1.9 <@ nr" +== 056 +-- truncate_limit: 100 +select * from numrange_test where nr = 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr = 'empty'" +== 057 +-- truncate_limit: 100 +select * from numrange_test where nr = '(1.1, 2.2)' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr = '(1.1, 2.2)'" +== 058 +-- truncate_limit: 100 +select * from numrange_test where nr = '[1.1, 2.2)' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr = '[1.1, 2.2)'" +== 059 +-- truncate_limit: 100 +select * from numrange_test where nr < 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr < 'empty'" +== 060 +-- truncate_limit: 100 +select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr < numrange(-1000.0, -1000.0, '[]')" +== 061 +-- truncate_limit: 100 +select * from numrange_test where nr < numrange(0.0, 1.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr < numrange(0.0, 1.0, '[]')" +== 062 +-- truncate_limit: 100 +select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr < numrange(1000.0, 1001.0, '[]')" +== 063 +-- truncate_limit: 100 +select * from numrange_test where nr <= 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr <= 'empty'" +== 064 +-- truncate_limit: 100 +select * from numrange_test where nr >= 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr >= 'empty'" +== 065 +-- truncate_limit: 100 +select * from numrange_test where nr > 'empty' +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr > 'empty'" +== 066 +-- truncate_limit: 100 +select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr > numrange(-1001.0, -1000.0, '[]')" +== 067 +-- truncate_limit: 100 +select * from numrange_test where nr > numrange(0.0, 1.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr > numrange(0.0, 1.0, '[]')" +== 068 +-- truncate_limit: 100 +select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]') +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test WHERE nr > numrange(1000.0, 1000.0, '[]')" +== 069 +-- truncate_limit: 100 +select numrange(2.0, 1.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(2.0, 1.0)" +== 070 +-- truncate_limit: 100 +select numrange(2.0, 3.0) -|- numrange(3.0, 4.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(2.0, 3.0) -|- numrange(3.0, 4.0)" +== 071 +-- truncate_limit: 100 +select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0)) +-- +FUNCTION: name="range_adjacent" function="range_adjacent" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0))" +== 072 +-- truncate_limit: 100 +select range_adjacent(numrange(2.0, 3.0), numrange(3.1, null)) +-- +FUNCTION: name="range_adjacent" function="range_adjacent" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_adjacent(numrange(2.0, 3.0), numrange(3.1, NULL))" +== 073 +-- truncate_limit: 100 +select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()')" +== 074 +-- truncate_limit: 100 +select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) -|- numrange(2.0, 3.0, '[]')" +== 075 +-- truncate_limit: 100 +select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]')) +-- +FUNCTION: name="range_adjacent" function="range_adjacent" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]'))" +== 076 +-- truncate_limit: 100 +select numrange(1.1, 3.3) <@ numrange(0.1,10.1) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.1, 3.3) <@ numrange(0.1, 10.1)" +== 077 +-- truncate_limit: 100 +select numrange(0.1, 10.1) <@ numrange(1.1,3.3) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(0.1, 10.1) <@ numrange(1.1, 3.3)" +== 078 +-- truncate_limit: 100 +select numrange(1.1, 2.2) - numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.1, 2.2) - numrange(2.0, 3.0)" +== 079 +-- truncate_limit: 100 +select numrange(1.1, 2.2) - numrange(2.2, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.1, 2.2) - numrange(2.2, 3.0)" +== 080 +-- truncate_limit: 100 +select numrange(1.1, 2.2,'[]') - numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.1, 2.2, '[]') - numrange(2.0, 3.0)" +== 081 +-- truncate_limit: 100 +select range_minus(numrange(10.1,12.2,'[]'), numrange(110.0,120.2,'(]')) +-- +FUNCTION: name="range_minus" function="range_minus" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_minus(numrange(10.1, 12.2, '[]'), numrange(110.0, 120.2, '(]'))" +== 082 +-- truncate_limit: 100 +select range_minus(numrange(10.1,12.2,'[]'), numrange(0.0,120.2,'(]')) +-- +FUNCTION: name="range_minus" function="range_minus" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_minus(numrange(10.1, 12.2, '[]'), numrange(0.0, 120.2, '(]'))" +== 083 +-- truncate_limit: 100 +select numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5)" +== 084 +-- truncate_limit: 100 +select numrange(1.0, 2.0) << numrange(3.0, 4.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) << numrange(3.0, 4.0)" +== 085 +-- truncate_limit: 100 +select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 3.0, '[]') << numrange(3.0, 4.0, '[]')" +== 086 +-- truncate_limit: 100 +select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()') +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 3.0, '()') << numrange(3.0, 4.0, '()')" +== 087 +-- truncate_limit: 100 +select numrange(1.0, 2.0) >> numrange(3.0, 4.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) >> numrange(3.0, 4.0)" +== 088 +-- truncate_limit: 100 +select numrange(3.0, 70.0) &< numrange(6.6, 100.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(3.0, 70.0) &< numrange(6.6, 100.0)" +== 089 +-- truncate_limit: 100 +select numrange(1.1, 2.2) < numrange(1.0, 200.2) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.1, 2.2) < numrange(1.0, 200.2)" +== 090 +-- truncate_limit: 100 +select numrange(1.1, 2.2) < numrange(1.1, 1.2) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.1, 2.2) < numrange(1.1, 1.2)" +== 091 +-- truncate_limit: 100 +select numrange(1.0, 2.0) + numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) + numrange(2.0, 3.0)" +== 092 +-- truncate_limit: 100 +select numrange(1.0, 2.0) + numrange(1.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) + numrange(1.5, 3.0)" +== 093 +-- truncate_limit: 100 +select numrange(1.0, 2.0) + numrange(2.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) + numrange(2.5, 3.0)" +== 094 +-- truncate_limit: 100 +-- should fail + +select range_merge(numrange(1.0, 2.0), numrange(2.0, 3.0)) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_merge(numrange(1.0, 2.0), numrange(2.0, 3.0))" +== 095 +-- truncate_limit: 100 +select range_merge(numrange(1.0, 2.0), numrange(1.5, 3.0)) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_merge(numrange(1.0, 2.0), numrange(1.5, 3.0))" +== 096 +-- truncate_limit: 100 +select range_merge(numrange(1.0, 2.0), numrange(2.5, 3.0)) +-- +FUNCTION: name="range_merge" function="range_merge" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_merge(numrange(1.0, 2.0), numrange(2.5, 3.0))" +== 097 +-- truncate_limit: 100 +-- shouldn't fail + +select numrange(1.0, 2.0) * numrange(2.0, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) * numrange(2.0, 3.0)" +== 098 +-- truncate_limit: 100 +select numrange(1.0, 2.0) * numrange(1.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) * numrange(1.5, 3.0)" +== 099 +-- truncate_limit: 100 +select numrange(1.0, 2.0) * numrange(2.5, 3.0) +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numrange(1.0, 2.0) * numrange(2.5, 3.0)" +== 100 +-- truncate_limit: 100 +select range_intersect_agg(nr) from numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nr) FROM numrange_test" +== 101 +-- truncate_limit: 100 +select range_intersect_agg(nr) from numrange_test where false +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nr) FROM numrange_test WHERE false" +== 102 +-- truncate_limit: 100 +select range_intersect_agg(nr) from numrange_test where nr @> 4.0 +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +FUNCTION: name="range_intersect_agg" function="range_intersect_agg" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT range_intersect_agg(nr) FROM numrange_test WHERE nr @> 4.0" +== 103 +-- truncate_limit: 100 +analyze numrange_test +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE numrange_test" +== 104 +-- truncate_limit: 100 +create table numrange_test2(nr numrange) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE numrange_test2 (nr numrange)" +== 105 +-- truncate_limit: 100 +create index numrange_test2_hash_idx on numrange_test2 using hash (nr) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX numrange_test2_hash_idx ON numrange_test2 USING hash (nr)" +== 106 +-- truncate_limit: 100 +INSERT INTO numrange_test2 VALUES('[, 5)') +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test2 VALUES ('[, 5)')" +== 107 +-- truncate_limit: 100 +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test2 VALUES (numrange(1.1, 2.2))" +== 108 +-- truncate_limit: 100 +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test2 VALUES (numrange(1.1, 2.2))" +== 109 +-- truncate_limit: 100 +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()')) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test2 VALUES (numrange(1.1, 2.2, '()'))" +== 110 +-- truncate_limit: 100 +INSERT INTO numrange_test2 VALUES('empty') +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numrange_test2 VALUES ('empty')" +== 111 +-- truncate_limit: 100 +select * from numrange_test2 where nr = 'empty'::numrange +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test2 WHERE nr = 'empty'::numrange" +== 112 +-- truncate_limit: 100 +select * from numrange_test2 where nr = numrange(1.1, 2.2) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test2 WHERE nr = numrange(1.1, 2.2)" +== 113 +-- truncate_limit: 100 +select * from numrange_test2 where nr = numrange(1.1, 2.3) +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test2 WHERE nr = numrange(1.1, 2.3)" +== 114 +-- truncate_limit: 100 +set enable_nestloop=t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO t" +== 115 +-- truncate_limit: 100 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO f" +== 116 +-- truncate_limit: 100 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO f" +== 117 +-- truncate_limit: 100 +select * from numrange_test natural join numrange_test2 order by nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test NATURAL JOIN numrange_test2 ORDER BY nr" +== 118 +-- truncate_limit: 100 +set enable_nestloop=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO f" +== 119 +-- truncate_limit: 100 +set enable_hashjoin=t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO t" +== 120 +-- truncate_limit: 100 +set enable_mergejoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO f" +== 121 +-- truncate_limit: 100 +select * from numrange_test natural join numrange_test2 order by nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test NATURAL JOIN numrange_test2 ORDER BY nr" +== 122 +-- truncate_limit: 100 +set enable_nestloop=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO f" +== 123 +-- truncate_limit: 100 +set enable_hashjoin=f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO f" +== 124 +-- truncate_limit: 100 +set enable_mergejoin=t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO t" +== 125 +-- truncate_limit: 100 +select * from numrange_test natural join numrange_test2 order by nr +-- +TABLE: name="numrange_test" schema="" table="numrange_test" ctx=Select +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numrange_test NATURAL JOIN numrange_test2 ORDER BY nr" +== 126 +-- truncate_limit: 100 +set enable_nestloop to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO DEFAULT" +== 127 +-- truncate_limit: 100 +set enable_hashjoin to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO DEFAULT" +== 128 +-- truncate_limit: 100 +set enable_mergejoin to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO DEFAULT" +== 129 +-- truncate_limit: 100 +-- keep numrange_test around to help exercise dump/reload +DROP TABLE numrange_test2 +-- +TABLE: name="numrange_test2" schema="" table="numrange_test2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE numrange_test2" +== 130 +-- truncate_limit: 100 +|-- +-- Apply a subset of the above tests on a collatable type, too +|-- + +CREATE TABLE textrange_test (tr textrange) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE textrange_test (tr textrange)" +== 131 +-- truncate_limit: 100 +create index textrange_test_btree on textrange_test(tr) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX textrange_test_btree ON textrange_test USING btree (tr)" +== 132 +-- truncate_limit: 100 +INSERT INTO textrange_test VALUES('[,)') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO textrange_test VALUES ('[,)')" +== 133 +-- truncate_limit: 100 +INSERT INTO textrange_test VALUES('["a",]') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO textrange_test VALUES ('[\"a\",]')" +== 134 +-- truncate_limit: 100 +INSERT INTO textrange_test VALUES('[,"q")') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO textrange_test VALUES ('[,\"q\")')" +== 135 +-- truncate_limit: 100 +INSERT INTO textrange_test VALUES(textrange('b', 'g')) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO textrange_test VALUES (textrange('b', 'g'))" +== 136 +-- truncate_limit: 100 +INSERT INTO textrange_test VALUES('empty') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO textrange_test VALUES ('empty')" +== 137 +-- truncate_limit: 100 +INSERT INTO textrange_test VALUES(textrange('d', 'd', '[]')) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=DML +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO textrange_test VALUES (textrange('d', 'd', '[]'))" +== 138 +-- truncate_limit: 100 +SELECT tr, isempty(tr), lower(tr), upper(tr) FROM textrange_test +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="isempty" function="isempty" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tr, isempty(tr), lower(tr), upper(tr) FROM textrange_test" +== 139 +-- truncate_limit: 100 +SELECT tr, lower_inc(tr), lower_inf(tr), upper_inc(tr), upper_inf(tr) FROM textrange_test +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="lower_inc" function="lower_inc" schema="" ctx=Call +FUNCTION: name="lower_inf" function="lower_inf" schema="" ctx=Call +FUNCTION: name="upper_inc" function="upper_inc" schema="" ctx=Call +FUNCTION: name="upper_inf" function="upper_inf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tr, lower_inc(tr), lower_inf(tr), upper_inc(tr), upper_inf(tr) FROM textrange_test" +== 140 +-- truncate_limit: 100 +SELECT * FROM textrange_test WHERE range_contains(tr, textrange('f', 'fx')) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="range_contains" function="range_contains" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE range_contains(tr, textrange('f', 'fx'))" +== 141 +-- truncate_limit: 100 +SELECT * FROM textrange_test WHERE tr @> textrange('a', 'z') +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE tr @> textrange('a', 'z')" +== 142 +-- truncate_limit: 100 +SELECT * FROM textrange_test WHERE range_contained_by(textrange('0','9'), tr) +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FUNCTION: name="range_contained_by" function="range_contained_by" schema="" ctx=Call +FUNCTION: name="textrange" function="textrange" schema="" ctx=Call +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE range_contained_by(textrange('0', '9'), tr)" +== 143 +-- truncate_limit: 100 +SELECT * FROM textrange_test WHERE 'e'::text <@ tr +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE 'e'::text <@ tr" +== 144 +-- truncate_limit: 100 +select * from textrange_test where tr = 'empty' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE tr = 'empty'" +== 145 +-- truncate_limit: 100 +select * from textrange_test where tr = '("b","g")' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE tr = '(\"b\",\"g\")'" +== 146 +-- truncate_limit: 100 +select * from textrange_test where tr = '["b","g")' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE tr = '[\"b\",\"g\")'" +== 147 +-- truncate_limit: 100 +select * from textrange_test where tr < 'empty' +-- +TABLE: name="textrange_test" schema="" table="textrange_test" ctx=Select +FILTER: schema="" table="" column="tr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM textrange_test WHERE tr < 'empty'" +== 148 +-- truncate_limit: 100 +-- test canonical form for int4range +select int4range(1, 10, '[]') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(1, 10, '[]')" +== 149 +-- truncate_limit: 100 +select int4range(1, 10, '[)') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(1, 10, '[)')" +== 150 +-- truncate_limit: 100 +select int4range(1, 10, '(]') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(1, 10, '(]')" +== 151 +-- truncate_limit: 100 +select int4range(1, 10, '()') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(1, 10, '()')" +== 152 +-- truncate_limit: 100 +select int4range(1, 2, '()') +-- +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4range(1, 2, '()')" +== 153 +-- truncate_limit: 100 +-- test canonical form for daterange +select daterange('2000-01-10'::date, '2000-01-20'::date, '[]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-10'::date, '2000-01-20'::date, '[]')" +== 154 +-- truncate_limit: 100 +select daterange('2000-01-10'::date, '2000-01-20'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-10'::date, '2000-01-20'::date, '[)')" +== 155 +-- truncate_limit: 100 +select daterange('2000-01-10'::date, '2000-01-20'::date, '(]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-10'::date, '2000-01-20'::date, '(]')" +== 156 +-- truncate_limit: 100 +select daterange('2000-01-10'::date, '2000-01-20'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-10'::date, '2000-01-20'::date, '()')" +== 157 +-- truncate_limit: 100 +select daterange('2000-01-10'::date, '2000-01-11'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-10'::date, '2000-01-11'::date, '()')" +== 158 +-- truncate_limit: 100 +select daterange('2000-01-10'::date, '2000-01-11'::date, '(]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-10'::date, '2000-01-11'::date, '(]')" +== 159 +-- truncate_limit: 100 +select daterange('-infinity'::date, '2000-01-01'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('-infinity'::date, '2000-01-01'::date, '()')" +== 160 +-- truncate_limit: 100 +select daterange('-infinity'::date, '2000-01-01'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('-infinity'::date, '2000-01-01'::date, '[)')" +== 161 +-- truncate_limit: 100 +select daterange('2000-01-01'::date, 'infinity'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-01'::date, 'infinity'::date, '[)')" +== 162 +-- truncate_limit: 100 +select daterange('2000-01-01'::date, 'infinity'::date, '[]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT daterange('2000-01-01'::date, 'infinity'::date, '[]')" +== 163 +-- truncate_limit: 100 +-- test GiST index that's been built incrementally +create table test_range_gist(ir int4range) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_range_gist (ir int4range)" +== 164 +-- truncate_limit: 100 +create index test_range_gist_idx on test_range_gist using gist (ir) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_range_gist_idx ON test_range_gist USING gist (ir)" +== 165 +-- truncate_limit: 100 +insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_gist SELECT int4range(g, g + 10) FROM generate_series(1, 2000) g" +== 166 +-- truncate_limit: 100 +insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_gist SELECT 'empty'::int4range FROM generate_series(1, 500) g" +== 167 +-- truncate_limit: 100 +insert into test_range_gist select int4range(g, g+10000) from generate_series(1,1000) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_gist SELECT int4range(g, g + 10000) FROM generate_series(1, 1000) g" +== 168 +-- truncate_limit: 100 +insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_gist SELECT 'empty'::int4range FROM generate_series(1, 500) g" +== 169 +-- truncate_limit: 100 +insert into test_range_gist select int4range(NULL,g*10,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_gist SELECT int4range(NULL, g * 10, '(]') FROM generate_series(1, 100) g" +== 170 +-- truncate_limit: 100 +insert into test_range_gist select int4range(g*10,NULL,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_gist SELECT int4range(g * 10, NULL, '(]') FROM generate_series(1, 100) g" +== 171 +-- truncate_limit: 100 +insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_gist SELECT int4range(g, g + 10) FROM generate_series(1, 2000) g" +== 172 +-- truncate_limit: 100 +-- test statistics and selectivity estimation as well +|-- +-- We don't check the accuracy of selectivity estimation, but at least check +-- it doesn't fall. +analyze test_range_gist +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE test_range_gist" +== 173 +-- truncate_limit: 100 +-- first, verify non-indexed results +SET enable_seqscan = t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO t" +== 174 +-- truncate_limit: 100 +SET enable_indexscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO f" +== 175 +-- truncate_limit: 100 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO f" +== 176 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> 'empty'::int4range" +== 177 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir = int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir = int4range(10, 20)" +== 178 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> 10 +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> 10" +== 179 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> int4range(10, 20)" +== 180 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir && int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir && int4range(10, 20)" +== 181 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir <@ int4range(10, 50)" +== 182 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir << int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir << int4range(100, 500)" +== 183 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir >> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir >> int4range(100, 500)" +== 184 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &< int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir &< int4range(100, 500)" +== 185 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir &> int4range(100, 500)" +== 186 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir -|- int4range(100, 500)" +== 187 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> '{}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> '{}'::int4multirange" +== 188 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 189 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir && '{(10,20),(30,40),(50,60)}'::int4multirange" +== 190 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange" +== 191 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 192 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 193 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 194 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 195 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 196 +-- truncate_limit: 100 +-- now check same queries using index +SET enable_seqscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO f" +== 197 +-- truncate_limit: 100 +SET enable_indexscan = t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO t" +== 198 +-- truncate_limit: 100 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO f" +== 199 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> 'empty'::int4range" +== 200 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir = int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir = int4range(10, 20)" +== 201 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> 10 +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> 10" +== 202 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> int4range(10, 20)" +== 203 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir && int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir && int4range(10, 20)" +== 204 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir <@ int4range(10, 50)" +== 205 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir << int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir << int4range(100, 500)" +== 206 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir >> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir >> int4range(100, 500)" +== 207 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &< int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir &< int4range(100, 500)" +== 208 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir &> int4range(100, 500)" +== 209 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir -|- int4range(100, 500)" +== 210 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> '{}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> '{}'::int4multirange" +== 211 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 212 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir && '{(10,20),(30,40),(50,60)}'::int4multirange" +== 213 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange" +== 214 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 215 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 216 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 217 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 218 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 219 +-- truncate_limit: 100 +-- now check same queries using a bulk-loaded index +drop index test_range_gist_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX test_range_gist_idx" +== 220 +-- truncate_limit: 100 +create index test_range_gist_idx on test_range_gist using gist (ir) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_range_gist_idx ON test_range_gist USING gist (ir)" +== 221 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> 'empty'::int4range" +== 222 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir = int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir = int4range(10, 20)" +== 223 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> 10 +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> 10" +== 224 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> int4range(10, 20)" +== 225 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir && int4range(10,20) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir && int4range(10, 20)" +== 226 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir <@ int4range(10, 50)" +== 227 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir << int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir << int4range(100, 500)" +== 228 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir >> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir >> int4range(100, 500)" +== 229 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &< int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir &< int4range(100, 500)" +== 230 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &> int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir &> int4range(100, 500)" +== 231 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir -|- int4range(100, 500)" +== 232 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> '{}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir @> '{}'::int4multirange" +== 233 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 234 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir && '{(10,20),(30,40),(50,60)}'::int4multirange" +== 235 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange" +== 236 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 237 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 238 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 239 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 240 +-- truncate_limit: 100 +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)) +-- +TABLE: name="test_range_gist" schema="" table="test_range_gist" ctx=Select +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4multirange" function="int4multirange" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_gist WHERE ..." +== 241 +-- truncate_limit: 100 +-- test SP-GiST index that's been built incrementally +create table test_range_spgist(ir int4range) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_range_spgist (ir int4range)" +== 242 +-- truncate_limit: 100 +create index test_range_spgist_idx on test_range_spgist using spgist (ir) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_range_spgist_idx ON test_range_spgist USING spgist (ir)" +== 243 +-- truncate_limit: 100 +insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_spgist SELECT int4range(g, g + 10) FROM generate_series(1, 2000) g" +== 244 +-- truncate_limit: 100 +insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_spgist SELECT 'empty'::int4range FROM generate_series(1, 500) g" +== 245 +-- truncate_limit: 100 +insert into test_range_spgist select int4range(g, g+10000) from generate_series(1,1000) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_spgist SELECT int4range(g, g + 10000) FROM generate_series(1, 1000) g" +== 246 +-- truncate_limit: 100 +insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_spgist SELECT 'empty'::int4range FROM generate_series(1, 500) g" +== 247 +-- truncate_limit: 100 +insert into test_range_spgist select int4range(NULL,g*10,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_spgist SELECT int4range(NULL, g * 10, '(]') FROM generate_series(1, 100) g" +== 248 +-- truncate_limit: 100 +insert into test_range_spgist select int4range(g*10,NULL,'(]') from generate_series(1,100) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_spgist SELECT int4range(g * 10, NULL, '(]') FROM generate_series(1, 100) g" +== 249 +-- truncate_limit: 100 +insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_spgist SELECT int4range(g, g + 10) FROM generate_series(1, 2000) g" +== 250 +-- truncate_limit: 100 +-- first, verify non-indexed results +SET enable_seqscan = t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO t" +== 251 +-- truncate_limit: 100 +SET enable_indexscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO f" +== 252 +-- truncate_limit: 100 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO f" +== 253 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> 'empty'::int4range" +== 254 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir = int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir = int4range(10, 20)" +== 255 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> 10 +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> 10" +== 256 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> int4range(10, 20)" +== 257 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir && int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir && int4range(10, 20)" +== 258 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir <@ int4range(10, 50)" +== 259 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir << int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir << int4range(100, 500)" +== 260 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir >> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir >> int4range(100, 500)" +== 261 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir &< int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir &< int4range(100, 500)" +== 262 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir &> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir &> int4range(100, 500)" +== 263 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir -|- int4range(100, 500)" +== 264 +-- truncate_limit: 100 +-- now check same queries using index +SET enable_seqscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO f" +== 265 +-- truncate_limit: 100 +SET enable_indexscan = t +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO t" +== 266 +-- truncate_limit: 100 +SET enable_bitmapscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO f" +== 267 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> 'empty'::int4range" +== 268 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir = int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir = int4range(10, 20)" +== 269 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> 10 +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> 10" +== 270 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> int4range(10, 20)" +== 271 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir && int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir && int4range(10, 20)" +== 272 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir <@ int4range(10, 50)" +== 273 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir << int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir << int4range(100, 500)" +== 274 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir >> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir >> int4range(100, 500)" +== 275 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir &< int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir &< int4range(100, 500)" +== 276 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir &> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir &> int4range(100, 500)" +== 277 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir -|- int4range(100, 500)" +== 278 +-- truncate_limit: 100 +-- now check same queries using a bulk-loaded index +drop index test_range_spgist_idx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX test_range_spgist_idx" +== 279 +-- truncate_limit: 100 +create index test_range_spgist_idx on test_range_spgist using spgist (ir) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_range_spgist_idx ON test_range_spgist USING spgist (ir)" +== 280 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> 'empty'::int4range +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> 'empty'::int4range" +== 281 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir = int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir = int4range(10, 20)" +== 282 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> 10 +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> 10" +== 283 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir @> int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir @> int4range(10, 20)" +== 284 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir && int4range(10,20) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir && int4range(10, 20)" +== 285 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir <@ int4range(10,50) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir <@ int4range(10, 50)" +== 286 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir << int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir << int4range(100, 500)" +== 287 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir >> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir >> int4range(100, 500)" +== 288 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir &< int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir &< int4range(100, 500)" +== 289 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir &> int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir &> int4range(100, 500)" +== 290 +-- truncate_limit: 100 +select count(*) from test_range_spgist where ir -|- int4range(100,500) +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_spgist WHERE ir -|- int4range(100, 500)" +== 291 +-- truncate_limit: 100 +-- test index-only scans +explain (costs off) +select ir from test_range_spgist where ir -|- int4range(10,20) order by ir +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ir FROM test_range_spgist WHERE ir -|- int4range(10, 20) ORDER BY ir" +== 292 +-- truncate_limit: 100 +select ir from test_range_spgist where ir -|- int4range(10,20) order by ir +-- +TABLE: name="test_range_spgist" schema="" table="test_range_spgist" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="ir" +STMT: SelectStmt +TRUNCATED: "SELECT ir FROM test_range_spgist WHERE ir -|- int4range(10, 20) ORDER BY ir" +== 293 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 294 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 295 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 296 +-- truncate_limit: 100 +-- test elem <@ range operator +create table test_range_elem(i int4) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_range_elem (i int4)" +== 297 +-- truncate_limit: 100 +create index test_range_elem_idx on test_range_elem (i) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_range_elem_idx ON test_range_elem USING btree (i)" +== 298 +-- truncate_limit: 100 +insert into test_range_elem select i from generate_series(1,100) i +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_elem SELECT i FROM generate_series(1, 100) i" +== 299 +-- truncate_limit: 100 +SET enable_seqscan = f +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO f" +== 300 +-- truncate_limit: 100 +select count(*) from test_range_elem where i <@ int4range(10,50) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_elem WHERE i <@ int4range(10, 50)" +== 301 +-- truncate_limit: 100 +-- also test spgist index on anyrange expression +create index on test_range_elem using spgist(int4range(i,i+10)) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_range_elem USING spgist (int4range(i, i + 10))" +== 302 +-- truncate_limit: 100 +explain (costs off) +select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_range_elem WHERE int4range(i, i + 10) <@ int4range(..." +== 303 +-- truncate_limit: 100 +select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30) +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=Select +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_range_elem WHERE int4range(i, i + 10) <@ int4range(10, 30)" +== 304 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 305 +-- truncate_limit: 100 +drop table test_range_elem +-- +TABLE: name="test_range_elem" schema="" table="test_range_elem" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_range_elem" +== 306 +-- truncate_limit: 100 +|-- +-- Btree_gist is not included by default, so to test exclusion +-- constraints with range types, use singleton int ranges for the "=" +-- portion of the constraint. +|-- + +create table test_range_excl( + room int4range, + speaker int4range, + during tsrange, + exclude using gist (room with =, during with &&), + exclude using gist (speaker with =, during with &&) +) +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_range_excl (room int4range, speaker int4range, during tsrange, EXCLUDE USING gi..." +== 307 +-- truncate_limit: 100 +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:00, 2010-01-02 11:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_excl VALUES (...)" +== 308 +-- truncate_limit: 100 +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(2, 2, '[]'), '[2010-01-02 11:00, 2010-01-02 12:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_excl VALUES (...)" +== 309 +-- truncate_limit: 100 +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_excl VALUES (...)" +== 310 +-- truncate_limit: 100 +insert into test_range_excl + values(int4range(124, 124, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:10)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_excl VALUES (...)" +== 311 +-- truncate_limit: 100 +insert into test_range_excl + values(int4range(125, 125, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)') +-- +TABLE: name="test_range_excl" schema="" table="test_range_excl" ctx=DML +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_range_excl VALUES (...)" +== 312 +-- truncate_limit: 100 +-- test bigint ranges +select int8range(10000000000::int8, 20000000000::int8,'(]') +-- +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int8range((10000000000)::int8, (20000000000)::int8, '(]')" +== 313 +-- truncate_limit: 100 +-- test tstz ranges +set timezone to '-08' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-08\"" +== 314 +-- truncate_limit: 100 +select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange" +== 315 +-- truncate_limit: 100 +-- should fail +select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange" +== 316 +-- truncate_limit: 100 +set timezone to default +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO DEFAULT" +== 317 +-- truncate_limit: 100 +|-- +-- Test user-defined range of floats +-- (type float8range was already made in test_setup.sql) +|-- + +--should fail +create type bogus_float8range as range (subtype=float8, subtype_diff=float4mi) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE bogus_float8range AS RANGE (subtype = float8, subtype_diff = float4mi)" +== 318 +-- truncate_limit: 100 +select '[123.001, 5.e9)'::float8range @> 888.882::float8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[123.001, 5.e9)'::float8range @> (888.882)::float8" +== 319 +-- truncate_limit: 100 +create table float8range_test(f8r float8range, i int) +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE float8range_test (f8r float8range, i int)" +== 320 +-- truncate_limit: 100 +insert into float8range_test values(float8range(-100.00007, '1.111113e9'), 42) +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=DML +FUNCTION: name="float8range" function="float8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8range_test VALUES (float8range(-100.00007, '1.111113e9'), 42)" +== 321 +-- truncate_limit: 100 +select * from float8range_test +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float8range_test" +== 322 +-- truncate_limit: 100 +drop table float8range_test +-- +TABLE: name="float8range_test" schema="" table="float8range_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE float8range_test" +== 323 +-- truncate_limit: 100 +|-- +-- Test range types over domains +|-- + +create domain mydomain as int4 +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN mydomain AS int4" +== 324 +-- truncate_limit: 100 +create type mydomainrange as range(subtype=mydomain) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE mydomainrange AS RANGE (subtype = mydomain)" +== 325 +-- truncate_limit: 100 +select '[4,50)'::mydomainrange @> 7::mydomain +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[4,50)'::mydomainrange @> 7::mydomain" +== 326 +-- truncate_limit: 100 +drop domain mydomain +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN mydomain" +== 327 +-- truncate_limit: 100 +-- fail +drop domain mydomain cascade +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN mydomain CASCADE" +== 328 +-- truncate_limit: 100 +|-- +-- Test domains over range types +|-- + +create domain restrictedrange as int4range check (upper(value) < 10) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN restrictedrange AS int4range CHECK (upper(value) < 10)" +== 329 +-- truncate_limit: 100 +select '[4,5)'::restrictedrange @> 7 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[4,5)'::restrictedrange @> 7" +== 330 +-- truncate_limit: 100 +select '[4,50)'::restrictedrange @> 7 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[4,50)'::restrictedrange @> 7" +== 331 +-- truncate_limit: 100 +-- should fail +drop domain restrictedrange +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN restrictedrange" +== 332 +-- truncate_limit: 100 +|-- +-- Test multiple range types over the same subtype +|-- + +create type textrange1 as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange1 AS RANGE (subtype = text, \"collation\" = \"C\")" +== 333 +-- truncate_limit: 100 +create type textrange2 as range(subtype=text, collation="C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange2 AS RANGE (subtype = text, \"collation\" = \"C\")" +== 334 +-- truncate_limit: 100 +select textrange1('a','Z') @> 'b'::text +-- +FUNCTION: name="textrange1" function="textrange1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange1('a', 'Z') @> 'b'::text" +== 335 +-- truncate_limit: 100 +select textrange2('a','z') @> 'b'::text +-- +FUNCTION: name="textrange2" function="textrange2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT textrange2('a', 'z') @> 'b'::text" +== 336 +-- truncate_limit: 100 +drop type textrange1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange1" +== 337 +-- truncate_limit: 100 +drop type textrange2 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange2" +== 338 +-- truncate_limit: 100 +|-- +-- Test polymorphic type system +|-- + +create function anyarray_anyrange_func(a anyarray, r anyrange) + returns anyelement as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anyarray_anyrange_func(a anyarray, r anyrange) RETURNS anyelement AS $$select $1[..." +== 339 +-- truncate_limit: 100 +select anyarray_anyrange_func(ARRAY[1,2], int4range(10,20)) +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anyarray_anyrange_func(ARRAY[1, 2], int4range(10, 20))" +== 340 +-- truncate_limit: 100 +-- should fail +select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20)) +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anyarray_anyrange_func(ARRAY[1, 2], numrange(10, 20))" +== 341 +-- truncate_limit: 100 +drop function anyarray_anyrange_func(anyarray, anyrange) +-- +FUNCTION: name="anyarray_anyrange_func" function="anyarray_anyrange_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anyarray_anyrange_func(anyarray, anyrange)" +== 342 +-- truncate_limit: 100 +-- should fail +create function bogus_func(anyelement) + returns anyrange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bogus_func(anyelement) RETURNS anyrange AS $$select int4range(1,10)$$ LANGUAGE sql" +== 343 +-- truncate_limit: 100 +-- should fail +create function bogus_func(int) + returns anyrange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bogus_func(int) RETURNS anyrange AS $$select int4range(1,10)$$ LANGUAGE sql" +== 344 +-- truncate_limit: 100 +create function range_add_bounds(anyrange) + returns anyelement as 'select lower($1) + upper($1)' language sql +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION range_add_bounds(anyrange) RETURNS anyelement AS $$select lower($1) + upper($1)$$..." +== 345 +-- truncate_limit: 100 +select range_add_bounds(int4range(1, 17)) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_add_bounds(int4range(1, 17))" +== 346 +-- truncate_limit: 100 +select range_add_bounds(numrange(1.0001, 123.123)) +-- +FUNCTION: name="range_add_bounds" function="range_add_bounds" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT range_add_bounds(numrange(1.0001, 123.123))" +== 347 +-- truncate_limit: 100 +create function rangetypes_sql(q anyrange, b anyarray, out c anyelement) + as $$ select upper($1) + $2[1] $$ + language sql +-- +FUNCTION: name="rangetypes_sql" function="rangetypes_sql" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rangetypes_sql(q anyrange, b anyarray, OUT c anyelement) AS $$ select upper($1) +..." +== 348 +-- truncate_limit: 100 +select rangetypes_sql(int4range(1,10), ARRAY[2,20]) +-- +FUNCTION: name="rangetypes_sql" function="rangetypes_sql" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rangetypes_sql(int4range(1, 10), ARRAY[2, 20])" +== 349 +-- truncate_limit: 100 +select rangetypes_sql(numrange(1,10), ARRAY[2,20]) +-- +FUNCTION: name="rangetypes_sql" function="rangetypes_sql" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rangetypes_sql(numrange(1, 10), ARRAY[2, 20])" +== 350 +-- truncate_limit: 100 +-- match failure + +create function anycompatiblearray_anycompatiblerange_func(a anycompatiblearray, r anycompatiblerange) + returns anycompatible as 'select $1[1] + lower($2);' language sql +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION anycompatiblearray_anycompatiblerange_func(a anycompatiblearray, r anycompatibler..." +== 351 +-- truncate_limit: 100 +select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], int4range(10,20)) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anycompatiblearray_anycompatiblerange_func(ARRAY[1, 2], int4range(10, 20))" +== 352 +-- truncate_limit: 100 +select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], numrange(10,20)) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anycompatiblearray_anycompatiblerange_func(ARRAY[1, 2], numrange(10, 20))" +== 353 +-- truncate_limit: 100 +-- should fail +select anycompatiblearray_anycompatiblerange_func(ARRAY[1.1,2], int4range(10,20)) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT anycompatiblearray_anycompatiblerange_func(ARRAY[1.1, 2], int4range(10, 20))" +== 354 +-- truncate_limit: 100 +drop function anycompatiblearray_anycompatiblerange_func(anycompatiblearray, anycompatiblerange) +-- +FUNCTION: name="anycompatiblearray_anycompatiblerange_func" function="anycompatiblearray_anycompatiblerange_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION anycompatiblearray_anycompatiblerange_func(anycompatiblearray, anycompatiblerange)" +== 355 +-- truncate_limit: 100 +-- should fail +create function bogus_func(anycompatible) + returns anycompatiblerange as 'select int4range(1,10)' language sql +-- +FUNCTION: name="bogus_func" function="bogus_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bogus_func(anycompatible) RETURNS anycompatiblerange AS $$select int4range(1,10)$..." +== 356 +-- truncate_limit: 100 +|-- +-- Arrays of ranges +|-- + +select ARRAY[numrange(1.1, 1.2), numrange(12.3, 155.5)] +-- +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +FUNCTION: name="numrange" function="numrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[numrange(1.1, 1.2), numrange(12.3, 155.5)]" +== 357 +-- truncate_limit: 100 +create table i8r_array (f1 int, f2 int8range[]) +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE i8r_array (f1 int, f2 int8range[])" +== 358 +-- truncate_limit: 100 +insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]) +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=DML +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +FUNCTION: name="int8range" function="int8range" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO i8r_array VALUES (42, ARRAY[int8range(1, 10), int8range(2, 20)])" +== 359 +-- truncate_limit: 100 +select * from i8r_array +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM i8r_array" +== 360 +-- truncate_limit: 100 +drop table i8r_array +-- +TABLE: name="i8r_array" schema="" table="i8r_array" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE i8r_array" +== 361 +-- truncate_limit: 100 +|-- +-- Ranges of arrays +|-- + +create type arrayrange as range (subtype=int4[]) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE arrayrange AS RANGE (subtype = int4[])" +== 362 +-- truncate_limit: 100 +select arrayrange(ARRAY[1,2], ARRAY[2,1]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT arrayrange(ARRAY[1, 2], ARRAY[2, 1])" +== 363 +-- truncate_limit: 100 +select arrayrange(ARRAY[2,1], ARRAY[1,2]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT arrayrange(ARRAY[2, 1], ARRAY[1, 2])" +== 364 +-- truncate_limit: 100 +-- fail + +select array[1,1] <@ arrayrange(array[1,2], array[2,1]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 1] <@ arrayrange(ARRAY[1, 2], ARRAY[2, 1])" +== 365 +-- truncate_limit: 100 +select array[1,3] <@ arrayrange(array[1,2], array[2,1]) +-- +FUNCTION: name="arrayrange" function="arrayrange" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[1, 3] <@ arrayrange(ARRAY[1, 2], ARRAY[2, 1])" +== 366 +-- truncate_limit: 100 +|-- +-- Ranges of composites +|-- + +create type two_ints as (a int, b int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE two_ints AS (a int, b int)" +== 367 +-- truncate_limit: 100 +create type two_ints_range as range (subtype = two_ints) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE two_ints_range AS RANGE (subtype = two_ints)" +== 368 +-- truncate_limit: 100 +-- with debug_parallel_query on, this exercises tqueue.c's range remapping +select *, row_to_json(upper(t)) as u from + (values (two_ints_range(row(1,2), row(3,4))), + (two_ints_range(row(5,6), row(7,8)))) v(t) +-- +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +FUNCTION: name="two_ints_range" function="two_ints_range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, row_to_json(upper(t)) AS u FROM (VALUES (...)) v(t)" +== 369 +-- truncate_limit: 100 +-- this must be rejected to avoid self-inclusion issues: +alter type two_ints add attribute c two_ints_range +-- +TABLE: name="two_ints" schema="" table="two_ints" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TYPE two_ints ADD ATTRIBUTE c two_ints_range" +== 370 +-- truncate_limit: 100 +drop type two_ints cascade +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE two_ints CASCADE" +== 371 +-- truncate_limit: 100 +|-- +-- Check behavior when subtype lacks a hash function +|-- + +create type varbitrange as range (subtype = varbit) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE varbitrange AS RANGE (subtype = varbit)" +== 372 +-- truncate_limit: 100 +set enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 373 +-- truncate_limit: 100 +-- try to make it pick a hash setop implementation + +select '(01,10)'::varbitrange except select '(10,11)'::varbitrange +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(01,10)'::varbitrange EXCEPT SELECT '(10,11)'::varbitrange" +== 374 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 375 +-- truncate_limit: 100 +|-- +-- OUT/INOUT/TABLE functions +|-- + +-- infer anyrange from anyrange +create function outparam_succeed(i anyrange, out r anyrange, out t text) + as $$ select $1, 'foo'::text $$ language sql +-- +FUNCTION: name="outparam_succeed" function="outparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION outparam_succeed(i anyrange, OUT r anyrange, OUT t text) AS $$ select $1, 'foo'::..." +== 376 +-- truncate_limit: 100 +select * from outparam_succeed(int4range(1,2)) +-- +FUNCTION: name="outparam_succeed" function="outparam_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM outparam_succeed(int4range(1, 2))" +== 377 +-- truncate_limit: 100 +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 +-- +FUNCTION: name="outparam2_succeed" function="outparam2_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION outparam2_succeed(r anyrange, OUT lu anyarray, OUT ul anyarray) AS $$ select arra..." +== 378 +-- truncate_limit: 100 +select * from outparam2_succeed(int4range(1,11)) +-- +FUNCTION: name="outparam2_succeed" function="outparam2_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM outparam2_succeed(int4range(1, 11))" +== 379 +-- truncate_limit: 100 +-- infer anyarray from anyrange +create function outparam_succeed2(i anyrange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql +-- +FUNCTION: name="outparam_succeed2" function="outparam_succeed2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION outparam_succeed2(i anyrange, OUT r anyarray, OUT t text) AS $$ select ARRAY[uppe..." +== 380 +-- truncate_limit: 100 +select * from outparam_succeed2(int4range(int4range(1,2))) +-- +FUNCTION: name="outparam_succeed2" function="outparam_succeed2" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM outparam_succeed2(int4range(int4range(1, 2)))" +== 381 +-- truncate_limit: 100 +-- infer anyelement from anyrange +create function inoutparam_succeed(out i anyelement, inout r anyrange) + as $$ select upper($1), $1 $$ language sql +-- +FUNCTION: name="inoutparam_succeed" function="inoutparam_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION inoutparam_succeed(OUT i anyelement, INOUT r anyrange) AS $$ select upper($1), $1..." +== 382 +-- truncate_limit: 100 +select * from inoutparam_succeed(int4range(1,2)) +-- +FUNCTION: name="inoutparam_succeed" function="inoutparam_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM inoutparam_succeed(int4range(1, 2))" +== 383 +-- truncate_limit: 100 +create function table_succeed(r anyrange) + returns table(l anyelement, u anyelement) + as $$ select lower($1), upper($1) $$ + language sql +-- +FUNCTION: name="table_succeed" function="table_succeed" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION table_succeed(r anyrange) RETURNS TABLE (l anyelement, u anyelement) AS $$ select..." +== 384 +-- truncate_limit: 100 +select * from table_succeed(int4range(1,11)) +-- +FUNCTION: name="table_succeed" function="table_succeed" schema="" ctx=Call +FUNCTION: name="int4range" function="int4range" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM table_succeed(int4range(1, 11))" +== 385 +-- truncate_limit: 100 +-- should fail +create function outparam_fail(i anyelement, out r anyrange, out t text) + as $$ select '[1,10]', 'foo' $$ language sql +-- +FUNCTION: name="outparam_fail" function="outparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION outparam_fail(i anyelement, OUT r anyrange, OUT t text) AS $$ select '[1,10]', 'f..." +== 386 +-- truncate_limit: 100 +--should fail +create function inoutparam_fail(inout i anyelement, out r anyrange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="inoutparam_fail" function="inoutparam_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION inoutparam_fail(INOUT i anyelement, OUT r anyrange) AS $$ select $1, '[1,10]' $$ ..." +== 387 +-- truncate_limit: 100 +--should fail +create function table_fail(i anyelement) returns table(i anyelement, r anyrange) + as $$ select $1, '[1,10]' $$ language sql +-- +FUNCTION: name="table_fail" function="table_fail" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION table_fail(i anyelement) RETURNS TABLE (i anyelement, r anyrange) AS $$ select $1..." +== 388 +-- truncate_limit: 100 +|-- +-- Test support functions +|-- + +-- empty range +explain (verbose, costs off) +select current_date <@ daterange 'empty' +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ 'empty'::daterange" +== 389 +-- truncate_limit: 100 +-- unbounded range +explain (verbose, costs off) +select current_date <@ daterange(NULL, NULL) +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ daterange(NULL, NULL)" +== 390 +-- truncate_limit: 100 +-- only lower bound present +explain (verbose, costs off) +select current_date <@ daterange('2000-01-01', NULL, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ daterange('2000-01-01', NULL, '[)')" +== 391 +-- truncate_limit: 100 +-- only upper bound present +explain (verbose, costs off) +select current_date <@ daterange(NULL, '2000-01-01', '(]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ daterange(NULL, '2000-01-01', '(]')" +== 392 +-- truncate_limit: 100 +-- lower range "-Infinity" excluded +explain (verbose, costs off) +select current_date <@ daterange('-Infinity', '1997-04-10'::date, '()') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ daterange('-Infinity', '1997-04-10'::date, '()')" +== 393 +-- truncate_limit: 100 +-- lower range "-Infinity" included +explain (verbose, costs off) +select current_date <@ daterange('-Infinity', '1997-04-10'::date, '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ daterange('-Infinity', '1997-04-10'::date, '[)')" +== 394 +-- truncate_limit: 100 +-- upper range "Infinity" excluded +explain (verbose, costs off) +select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[)') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ daterange('2002-09-25'::date, 'Infinity', '[)')" +== 395 +-- truncate_limit: 100 +-- upper range "Infinity" included +explain (verbose, costs off) +select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[]') +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT current_date <@ daterange('2002-09-25'::date, 'Infinity', '[]')" +== 396 +-- truncate_limit: 100 +-- should also work if we use "@>" +explain (verbose, costs off) +select daterange('-Infinity', '1997-04-10'::date, '()') @> current_date +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT daterange('-Infinity', '1997-04-10'::date, '()') @> current_date" +== 397 +-- truncate_limit: 100 +explain (verbose, costs off) +select daterange('2002-09-25'::date, 'Infinity', '[]') @> current_date +-- +FUNCTION: name="daterange" function="daterange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT daterange('2002-09-25'::date, 'Infinity', '[]') @> current_date" +== 398 +-- truncate_limit: 100 +-- Check that volatile cases are not optimized +explain (verbose, costs off) +select now() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00') +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="tstzrange" function="tstzrange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT now() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00')" +== 399 +-- truncate_limit: 100 +explain (verbose, costs off) -- unsafe! +select clock_timestamp() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00') +-- +FUNCTION: name="clock_timestamp" function="clock_timestamp" schema="" ctx=Call +FUNCTION: name="tstzrange" function="tstzrange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT clock_timestamp() <@ tstzrange('2024-01-20 00:00', '2024-01-2..." +== 400 +-- truncate_limit: 100 +explain (verbose, costs off) +select clock_timestamp() <@ tstzrange('2024-01-20 00:00', NULL) +-- +FUNCTION: name="clock_timestamp" function="clock_timestamp" schema="" ctx=Call +FUNCTION: name="tstzrange" function="tstzrange" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT clock_timestamp() <@ tstzrange('2024-01-20 00:00', NULL)" +== 401 +-- truncate_limit: 100 +-- test a custom range type with a non-default operator class +create type textrange_supp as range ( + subtype = text, + subtype_opclass = text_pattern_ops +) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange_supp AS RANGE (subtype = text, subtype_opclass = text_pattern_ops)" +== 402 +-- truncate_limit: 100 +create temp table text_support_test (t text collate "C") +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE text_support_test (t text COLLATE \"C\")" +== 403 +-- truncate_limit: 100 +insert into text_support_test values ('a'), ('c'), ('d'), ('ch') +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO text_support_test VALUES ('a'), ('c'), ('d'), ('ch')" +== 404 +-- truncate_limit: 100 +explain (costs off) +select * from text_support_test where t <@ textrange_supp('a', 'd') +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=Select +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM text_support_test WHERE t <@ textrange_supp('a', 'd')" +== 405 +-- truncate_limit: 100 +select * from text_support_test where t <@ textrange_supp('a', 'd') +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=Select +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FUNCTION: name="textrange_supp" function="textrange_supp" schema="" ctx=Call +FILTER: schema="" table="" column="t" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM text_support_test WHERE t <@ textrange_supp('a', 'd')" +== 406 +-- truncate_limit: 100 +drop table text_support_test +-- +TABLE: name="text_support_test" schema="" table="text_support_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE text_support_test" +== 407 +-- truncate_limit: 100 +drop type textrange_supp +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE textrange_supp" diff --git a/parser/testdata/summary_truncate/postgres_regress/regex.metadata.json b/parser/testdata/summary_truncate/postgres_regress/regex.metadata.json new file mode 100644 index 0000000..60e76e3 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/regex.metadata.json @@ -0,0 +1,109 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/regex.test b/parser/testdata/summary_truncate/postgres_regress/regex.test new file mode 100644 index 0000000..16f88ea --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/regex.test @@ -0,0 +1,737 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Regular expression tests +|-- + +-- Don't want to have to double backslashes in regexes +set standard_conforming_strings = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET standard_conforming_strings TO ON" +== 002 +-- truncate_limit: 100 +-- Test simple quantified backrefs +select 'bbbbb' ~ '^([bc])\1*$' as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbbbb' ~ E'^([bc])\\\\1*$' AS t" +== 003 +-- truncate_limit: 100 +select 'ccc' ~ '^([bc])\1*$' as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'ccc' ~ E'^([bc])\\\\1*$' AS t" +== 004 +-- truncate_limit: 100 +select 'xxx' ~ '^([bc])\1*$' as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'xxx' ~ E'^([bc])\\\\1*$' AS f" +== 005 +-- truncate_limit: 100 +select 'bbc' ~ '^([bc])\1*$' as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bbc' ~ E'^([bc])\\\\1*$' AS f" +== 006 +-- truncate_limit: 100 +select 'b' ~ '^([bc])\1*$' as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'b' ~ E'^([bc])\\\\1*$' AS t" +== 007 +-- truncate_limit: 100 +-- Test quantified backref within a larger expression +select 'abc abc abc' ~ '^(\w+)( \1)+$' as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc abc abc' ~ E'^(\\\\w+)( \\\\1)+$' AS t" +== 008 +-- truncate_limit: 100 +select 'abc abd abc' ~ '^(\w+)( \1)+$' as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc abd abc' ~ E'^(\\\\w+)( \\\\1)+$' AS f" +== 009 +-- truncate_limit: 100 +select 'abc abc abd' ~ '^(\w+)( \1)+$' as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc abc abd' ~ E'^(\\\\w+)( \\\\1)+$' AS f" +== 010 +-- truncate_limit: 100 +select 'abc abc abc' ~ '^(.+)( \1)+$' as t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc abc abc' ~ E'^(.+)( \\\\1)+$' AS t" +== 011 +-- truncate_limit: 100 +select 'abc abd abc' ~ '^(.+)( \1)+$' as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc abd abc' ~ E'^(.+)( \\\\1)+$' AS f" +== 012 +-- truncate_limit: 100 +select 'abc abc abd' ~ '^(.+)( \1)+$' as f +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'abc abc abd' ~ E'^(.+)( \\\\1)+$' AS f" +== 013 +-- truncate_limit: 100 +-- Test some cases that crashed in 9.2beta1 due to pmatch[] array overrun +select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)') +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('asd TO foo' FROM ' TO (([a-z0-9._]+|\"([^\"]+|\"\")+\")+)')" +== 014 +-- truncate_limit: 100 +select substring('a' from '((a))+') +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('a' FROM '((a))+')" +== 015 +-- truncate_limit: 100 +select substring('a' from '((a)+)') +-- +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT SUBSTRING('a' FROM '((a)+)')" +== 016 +-- truncate_limit: 100 +-- Test regexp_match() +select regexp_match('abc', '') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_match('abc', '')" +== 017 +-- truncate_limit: 100 +select regexp_match('abc', 'bc') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_match('abc', 'bc')" +== 018 +-- truncate_limit: 100 +select regexp_match('abc', 'd') is null +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_match('abc', 'd') IS NULL" +== 019 +-- truncate_limit: 100 +select regexp_match('abc', '(B)(c)', 'i') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_match('abc', '(B)(c)', 'i')" +== 020 +-- truncate_limit: 100 +select regexp_match('abc', 'Bd', 'ig') +-- +FUNCTION: name="regexp_match" function="regexp_match" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_match('abc', 'Bd', 'ig')" +== 021 +-- truncate_limit: 100 +-- error + +-- Test lookahead constraints +select regexp_matches('ab', 'a(?=b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('ab', 'a(?=b)b*')" +== 022 +-- truncate_limit: 100 +select regexp_matches('a', 'a(?=b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('a', 'a(?=b)b*')" +== 023 +-- truncate_limit: 100 +select regexp_matches('abc', 'a(?=b)b*(?=c)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('abc', 'a(?=b)b*(?=c)c*')" +== 024 +-- truncate_limit: 100 +select regexp_matches('ab', 'a(?=b)b*(?=c)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('ab', 'a(?=b)b*(?=c)c*')" +== 025 +-- truncate_limit: 100 +select regexp_matches('ab', 'a(?!b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('ab', 'a(?!b)b*')" +== 026 +-- truncate_limit: 100 +select regexp_matches('a', 'a(?!b)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('a', 'a(?!b)b*')" +== 027 +-- truncate_limit: 100 +select regexp_matches('b', '(?=b)b') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('b', '(?=b)b')" +== 028 +-- truncate_limit: 100 +select regexp_matches('a', '(?=b)b') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('a', '(?=b)b')" +== 029 +-- truncate_limit: 100 +-- Test lookbehind constraints +select regexp_matches('abb', '(?<=a)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('abb', '(?<=a)b*')" +== 030 +-- truncate_limit: 100 +select regexp_matches('a', 'a(?<=a)b*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('a', 'a(?<=a)b*')" +== 031 +-- truncate_limit: 100 +select regexp_matches('abc', 'a(?<=a)b*(?<=b)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('abc', 'a(?<=a)b*(?<=b)c*')" +== 032 +-- truncate_limit: 100 +select regexp_matches('ab', 'a(?<=a)b*(?<=b)c*') +-- +FUNCTION: name="regexp_matches" function="regexp_matches" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT regexp_matches('ab', 'a(?<=a)b*(?<=b)c*')" +== 033 +-- truncate_limit: 100 +select regexp_matches('ab', 'a*(? 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_relation_size('reloptions_test') > 0" +== 037 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = + (SELECT reltoastrelid FROM pg_class + WHERE oid = 'reloptions_test'::regclass) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE ...)" +== 038 +-- truncate_limit: 100 +ALTER TABLE reloptions_test RESET (vacuum_truncate) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE reloptions_test RESET (vacuum_truncate)" +== 039 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass" +== 040 +-- truncate_limit: 100 +INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL)" +== 041 +-- truncate_limit: 100 +-- Do an aggressive vacuum to prevent page-skipping. +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test" +== 042 +-- truncate_limit: 100 +SELECT pg_relation_size('reloptions_test') = 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_relation_size('reloptions_test') = 0" +== 043 +-- truncate_limit: 100 +-- Test toast.* options +DROP TABLE reloptions_test +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE reloptions_test" +== 044 +-- truncate_limit: 100 +CREATE TABLE reloptions_test (s VARCHAR) + WITH (toast.autovacuum_vacuum_cost_delay = 23) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE reloptions_test (s varchar) WITH (toast.autovacuum_vacuum_cost_delay=23)" +== 045 +-- truncate_limit: 100 +SELECT reltoastrelid as toast_oid + FROM pg_class WHERE oid = 'reloptions_test'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltoastrelid AS toast_oid FROM pg_class WHERE oid = 'reloptions_test'::regclass" +== 046 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = :toast_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 45 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 047 +-- truncate_limit: 100 +ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay=24)" +== 048 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = :toast_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 45 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 049 +-- truncate_limit: 100 +ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay)" +== 050 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = :toast_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 45 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 051 +-- truncate_limit: 100 +-- Fail on non-existent options in toast namespace +CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42) +-- +TABLE: name="reloptions_test2" schema="" table="reloptions_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option=42)" +== 052 +-- truncate_limit: 100 +-- Mix TOAST & heap +DROP TABLE reloptions_test +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE reloptions_test" +== 053 +-- truncate_limit: 100 +CREATE TABLE reloptions_test (s VARCHAR) WITH + (toast.autovacuum_vacuum_cost_delay = 23, + autovacuum_vacuum_cost_delay = 24, fillfactor = 40) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE reloptions_test (s varchar) WITH (toast.autovacuum_vacuum_cost_delay=23, autovacuum_..." +== 054 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass" +== 055 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = ( + SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reloptions FROM pg_class WHERE oid = (SELECT reltoastrelid FROM pg_class WHERE ...)" +== 056 +-- truncate_limit: 100 +|-- +-- CREATE INDEX, ALTER INDEX for btrees +|-- + +CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX reloptions_test_idx ON reloptions_test USING btree (s) WITH (fillfactor=30)" +== 057 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass" +== 058 +-- truncate_limit: 100 +-- Fail when option and namespace do not exist +CREATE INDEX reloptions_test_idx ON reloptions_test (s) + WITH (not_existing_option=2) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX reloptions_test_idx ON reloptions_test USING btree (s) WITH (not_existing_option=2)" +== 059 +-- truncate_limit: 100 +CREATE INDEX reloptions_test_idx ON reloptions_test (s) + WITH (not_existing_ns.fillfactor=2) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX reloptions_test_idx ON reloptions_test USING btree (s) WITH (not_existing_ns.fillfac..." +== 060 +-- truncate_limit: 100 +-- Check allowed ranges +CREATE INDEX reloptions_test_idx2 ON reloptions_test (s) WITH (fillfactor=1) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX reloptions_test_idx2 ON reloptions_test USING btree (s) WITH (fillfactor=1)" +== 061 +-- truncate_limit: 100 +CREATE INDEX reloptions_test_idx2 ON reloptions_test (s) WITH (fillfactor=130) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX reloptions_test_idx2 ON reloptions_test USING btree (s) WITH (fillfactor=130)" +== 062 +-- truncate_limit: 100 +-- Check ALTER +ALTER INDEX reloptions_test_idx SET (fillfactor=40) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX reloptions_test_idx SET (fillfactor=40)" +== 063 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass" +== 064 +-- truncate_limit: 100 +-- Check ALTER on empty reloption list +CREATE INDEX reloptions_test_idx3 ON reloptions_test (s) +-- +TABLE: name="reloptions_test" schema="" table="reloptions_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX reloptions_test_idx3 ON reloptions_test USING btree (s)" +== 065 +-- truncate_limit: 100 +ALTER INDEX reloptions_test_idx3 SET (fillfactor=40) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX reloptions_test_idx3 SET (fillfactor=40)" +== 066 +-- truncate_limit: 100 +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx3'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx3'::regclass" diff --git a/parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json new file mode 100644 index 0000000..dc9d431 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json @@ -0,0 +1,60 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/replica_identity.test b/parser/testdata/summary_truncate/postgres_regress/replica_identity.test new file mode 100644 index 0000000..2bbb96f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/replica_identity.test @@ -0,0 +1,454 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE test_replica_identity ( + id serial primary key, + keya text not null, + keyb text not null, + nonkey text, + CONSTRAINT test_replica_identity_unique_defer UNIQUE (keya, keyb) DEFERRABLE, + CONSTRAINT test_replica_identity_unique_nondefer UNIQUE (keya, keyb) +) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_replica_identity (id serial PRIMARY KEY, keya text NOT NULL, keyb text NOT NULL..." +== 002 +-- truncate_limit: 100 +CREATE TABLE test_replica_identity_othertable (id serial primary key) +-- +TABLE: name="test_replica_identity_othertable" schema="" table="test_replica_identity_othertable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_replica_identity_othertable (id serial PRIMARY KEY)" +== 003 +-- truncate_limit: 100 +CREATE TABLE test_replica_identity_t3 (id serial constraint pk primary key deferrable) +-- +TABLE: name="test_replica_identity_t3" schema="" table="test_replica_identity_t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_replica_identity_t3 (id serial CONSTRAINT pk PRIMARY KEY DEFERRABLE)" +== 004 +-- truncate_limit: 100 +CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_replica_identity_keyab ON test_replica_identity USING btree (keya, keyb)" +== 005 +-- truncate_limit: 100 +CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity (keya, keyb) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity USING btree (keya, k..." +== 006 +-- truncate_limit: 100 +CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity (keya, nonkey) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity USING btree (keya, nonkey)" +== 007 +-- truncate_limit: 100 +CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey)" +== 008 +-- truncate_limit: 100 +CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, keyb, (3)) +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity USING btree (keya, keyb, ..." +== 009 +-- truncate_limit: 100 +CREATE UNIQUE INDEX test_replica_identity_partial ON test_replica_identity (keya, keyb) WHERE keyb != '3' +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX test_replica_identity_partial ON test_replica_identity USING btree (keya, key..." +== 010 +-- truncate_limit: 100 +-- default is 'd'/DEFAULT for user created tables +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass" +== 011 +-- truncate_limit: 100 +-- but 'none' for system tables +SELECT relreplident FROM pg_class WHERE oid = 'pg_class'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'pg_class'::regclass" +== 012 +-- truncate_limit: 100 +SELECT relreplident FROM pg_class WHERE oid = 'pg_constraint'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'pg_constraint'::regclass" +== 013 +-- truncate_limit: 100 +---- +-- Make sure we detect ineligible indexes +---- + +-- fail, not unique +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab" +== 014 +-- truncate_limit: 100 +-- fail, not a candidate key, nullable column +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_nonkey +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_nonkey" +== 015 +-- truncate_limit: 100 +-- fail, hash indexes cannot do uniqueness +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_hash +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_hash" +== 016 +-- truncate_limit: 100 +-- fail, expression index +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_expr +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_expr" +== 017 +-- truncate_limit: 100 +-- fail, partial index +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_partial +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_partial" +== 018 +-- truncate_limit: 100 +-- fail, not our index +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_othertable_pkey +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_othertable_pkey" +== 019 +-- truncate_limit: 100 +-- fail, deferrable +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_defer +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_defer" +== 020 +-- truncate_limit: 100 +-- fail, deferrable +ALTER TABLE test_replica_identity_t3 REPLICA IDENTITY USING INDEX pk +-- +TABLE: name="test_replica_identity_t3" schema="" table="test_replica_identity_t3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity_t3 REPLICA IDENTITY USING INDEX pk" +== 021 +-- truncate_limit: 100 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass" +== 022 +-- truncate_limit: 100 +---- +-- Make sure index cases succeed +---- + +-- succeed, primary key +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_pkey +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_pkey" +== 023 +-- truncate_limit: 100 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass" +== 024 +-- truncate_limit: 100 +-- succeed, nondeferrable unique constraint over nonnullable cols +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer" +== 025 +-- truncate_limit: 100 +-- succeed unique index over nonnullable cols +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key" +== 026 +-- truncate_limit: 100 +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key" +== 027 +-- truncate_limit: 100 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass" +== 028 +-- truncate_limit: 100 +SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="indisreplident" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident" +== 029 +-- truncate_limit: 100 +---- +-- Make sure non index cases work +---- +ALTER TABLE test_replica_identity REPLICA IDENTITY DEFAULT +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY DEFAULT" +== 030 +-- truncate_limit: 100 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass" +== 031 +-- truncate_limit: 100 +SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident +-- +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="" column="indisreplident" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident" +== 032 +-- truncate_limit: 100 +ALTER TABLE test_replica_identity REPLICA IDENTITY FULL +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY FULL" +== 033 +-- truncate_limit: 100 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass" +== 034 +-- truncate_limit: 100 +ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING" +== 035 +-- truncate_limit: 100 +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass" +== 036 +-- truncate_limit: 100 +--- +-- Test that ALTER TABLE rewrite preserves nondefault replica identity +--- + +-- constraint variant +CREATE TABLE test_replica_identity2 (id int UNIQUE NOT NULL) +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_replica_identity2 (id int UNIQUE NOT NULL)" +== 037 +-- truncate_limit: 100 +ALTER TABLE test_replica_identity2 REPLICA IDENTITY USING INDEX test_replica_identity2_id_key +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity2 REPLICA IDENTITY USING INDEX test_replica_identity2_id_key" +== 038 +-- truncate_limit: 100 +ALTER TABLE test_replica_identity2 ALTER COLUMN id TYPE bigint +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity2 ALTER COLUMN id TYPE bigint" +== 039 +-- truncate_limit: 100 +-- straight index variant +CREATE TABLE test_replica_identity3 (id int NOT NULL) +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_replica_identity3 (id int NOT NULL)" +== 040 +-- truncate_limit: 100 +CREATE UNIQUE INDEX test_replica_identity3_id_key ON test_replica_identity3 (id) +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX test_replica_identity3_id_key ON test_replica_identity3 USING btree (id)" +== 041 +-- truncate_limit: 100 +ALTER TABLE test_replica_identity3 REPLICA IDENTITY USING INDEX test_replica_identity3_id_key +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity3 REPLICA IDENTITY USING INDEX test_replica_identity3_id_key" +== 042 +-- truncate_limit: 100 +ALTER TABLE test_replica_identity3 ALTER COLUMN id TYPE bigint +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity3 ALTER COLUMN id TYPE bigint" +== 043 +-- truncate_limit: 100 +-- ALTER TABLE DROP NOT NULL is not allowed for columns part of an index +-- used as replica identity. +ALTER TABLE test_replica_identity3 ALTER COLUMN id DROP NOT NULL +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_replica_identity3 ALTER COLUMN id DROP NOT NULL" +== 044 +-- truncate_limit: 100 +|-- +-- Test that replica identity can be set on an index that's not yet valid. +-- (This matches the way pg_dump will try to dump a partitioned table.) +|-- +CREATE TABLE test_replica_identity4(id integer NOT NULL) PARTITION BY LIST (id) +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_replica_identity4 (id int NOT NULL) PARTITION BY LIST (id)" +== 045 +-- truncate_limit: 100 +CREATE TABLE test_replica_identity4_1(id integer NOT NULL) +-- +TABLE: name="test_replica_identity4_1" schema="" table="test_replica_identity4_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_replica_identity4_1 (id int NOT NULL)" +== 046 +-- truncate_limit: 100 +ALTER TABLE ONLY test_replica_identity4 + ATTACH PARTITION test_replica_identity4_1 FOR VALUES IN (1) +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_replica_identity4 ATTACH PARTITION test_replica_identity4_1 FOR VALUES IN (1)" +== 047 +-- truncate_limit: 100 +ALTER TABLE ONLY test_replica_identity4 + ADD CONSTRAINT test_replica_identity4_pkey PRIMARY KEY (id) +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_replica_identity4 ADD CONSTRAINT test_replica_identity4_pkey PRIMARY KEY (id)" +== 048 +-- truncate_limit: 100 +ALTER TABLE ONLY test_replica_identity4 + REPLICA IDENTITY USING INDEX test_replica_identity4_pkey +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_replica_identity4 REPLICA IDENTITY USING INDEX test_replica_identity4_pkey" +== 049 +-- truncate_limit: 100 +ALTER TABLE ONLY test_replica_identity4_1 + ADD CONSTRAINT test_replica_identity4_1_pkey PRIMARY KEY (id) +-- +TABLE: name="test_replica_identity4_1" schema="" table="test_replica_identity4_1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY test_replica_identity4_1 ADD CONSTRAINT test_replica_identity4_1_pkey PRIMARY KE..." +== 050 +-- truncate_limit: 100 +ALTER INDEX test_replica_identity4_pkey + ATTACH PARTITION test_replica_identity4_1_pkey +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX test_replica_identity4_pkey ATTACH PARTITION test_replica_identity4_1_pkey" +== 051 +-- truncate_limit: 100 +DROP TABLE test_replica_identity +-- +TABLE: name="test_replica_identity" schema="" table="test_replica_identity" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_replica_identity" +== 052 +-- truncate_limit: 100 +DROP TABLE test_replica_identity2 +-- +TABLE: name="test_replica_identity2" schema="" table="test_replica_identity2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_replica_identity2" +== 053 +-- truncate_limit: 100 +DROP TABLE test_replica_identity3 +-- +TABLE: name="test_replica_identity3" schema="" table="test_replica_identity3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_replica_identity3" +== 054 +-- truncate_limit: 100 +DROP TABLE test_replica_identity4 +-- +TABLE: name="test_replica_identity4" schema="" table="test_replica_identity4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_replica_identity4" +== 055 +-- truncate_limit: 100 +DROP TABLE test_replica_identity_othertable +-- +TABLE: name="test_replica_identity_othertable" schema="" table="test_replica_identity_othertable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_replica_identity_othertable" +== 056 +-- truncate_limit: 100 +DROP TABLE test_replica_identity_t3 +-- +TABLE: name="test_replica_identity_t3" schema="" table="test_replica_identity_t3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_replica_identity_t3" diff --git a/parser/testdata/summary_truncate/postgres_regress/returning.metadata.json b/parser/testdata/summary_truncate/postgres_regress/returning.metadata.json new file mode 100644 index 0000000..2be5689 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/returning.metadata.json @@ -0,0 +1,81 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/returning.test b/parser/testdata/summary_truncate/postgres_regress/returning.test new file mode 100644 index 0000000..53e56ea --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/returning.test @@ -0,0 +1,645 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test INSERT/UPDATE/DELETE RETURNING +|-- + +-- Simple cases + +CREATE TEMP TABLE foo (f1 serial, f2 text, f3 int default 42) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (f1 serial, f2 text, f3 int DEFAULT 42)" +== 002 +-- truncate_limit: 100 +INSERT INTO foo (f2,f3) + VALUES ('test', DEFAULT), ('More', 11), (upper('more'), 7+9) + RETURNING *, f1+f3 AS sum +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo (f2, f3) VALUES (...) RETURNING *, f1 + f3 AS sum" +== 003 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 004 +-- truncate_limit: 100 +UPDATE foo SET f2 = lower(f2), f3 = DEFAULT RETURNING foo.*, f1+f3 AS sum13 +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f2 = lower(f2), f3 = DEFAULT RETURNING foo.*, f1 + f3 AS sum13" +== 005 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 006 +-- truncate_limit: 100 +DELETE FROM foo WHERE f1 > 2 RETURNING f3, f2, f1, least(f1,f3) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM foo WHERE f1 > 2 RETURNING f3, f2, f1, LEAST(f1, f3)" +== 007 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 008 +-- truncate_limit: 100 +-- Subplans and initplans in the RETURNING list + +INSERT INTO foo SELECT f1+10, f2, f3+99 FROM foo + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo SELECT ... FROM foo RETURNING *, f1 + 112 IN (SELECT q1 FROM int8_tbl) AS subplan..." +== 009 +-- truncate_limit: 100 +UPDATE foo SET f3 = f3 * 2 + WHERE f1 > 10 + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE foo SET ... = ... WHERE ... RETURNING *, f1 + 112 IN (SELECT q1 FROM int8_tbl) AS subplan,..." +== 010 +-- truncate_limit: 100 +DELETE FROM foo + WHERE f1 > 10 + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM foo WHERE ... RETURNING *, f1 + 112 IN (SELECT q1 FROM int8_tbl) AS subplan, EXISTS (..." +== 011 +-- truncate_limit: 100 +-- Joins + +UPDATE foo SET f3 = f3*2 + FROM int4_tbl i + WHERE foo.f1 + 123455 = i.f1 + RETURNING foo.*, i.f1 as "i.f1" +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f3 = f3 * 2 FROM int4_tbl i WHERE ... RETURNING foo.*, i.f1 AS \"i.f1\"" +== 012 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 013 +-- truncate_limit: 100 +DELETE FROM foo + USING int4_tbl i + WHERE foo.f1 + 123455 = i.f1 + RETURNING foo.*, i.f1 as "i.f1" +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +STMT: DeleteStmt +TRUNCATED: "DELETE FROM foo USING int4_tbl i WHERE (foo.f1 + 123455) = i.f1 RETURNING foo.*, i.f1 AS \"i.f1\"" +== 014 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 015 +-- truncate_limit: 100 +-- Check inheritance cases + +CREATE TEMP TABLE foochild (fc int) INHERITS (foo) +-- +TABLE: name="foochild" schema="" table="foochild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foochild (fc int) INHERITS (foo)" +== 016 +-- truncate_limit: 100 +INSERT INTO foochild VALUES(123,'child',999,-123) +-- +TABLE: name="foochild" schema="" table="foochild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foochild VALUES (123, 'child', 999, -123)" +== 017 +-- truncate_limit: 100 +ALTER TABLE foo ADD COLUMN f4 int8 DEFAULT 99 +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE foo ADD COLUMN f4 int8 DEFAULT 99" +== 018 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 019 +-- truncate_limit: 100 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foochild" +== 020 +-- truncate_limit: 100 +UPDATE foo SET f4 = f4 + f3 WHERE f4 = 99 RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f4 = f4 + f3 WHERE f4 = 99 RETURNING *" +== 021 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 022 +-- truncate_limit: 100 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foochild" +== 023 +-- truncate_limit: 100 +UPDATE foo SET f3 = f3*2 + FROM int8_tbl i + WHERE foo.f1 = i.q2 + RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f3 = f3 * 2 FROM int8_tbl i WHERE foo.f1 = i.q2 RETURNING *" +== 024 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 025 +-- truncate_limit: 100 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foochild" +== 026 +-- truncate_limit: 100 +DELETE FROM foo + USING int8_tbl i + WHERE foo.f1 = i.q2 + RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +STMT: DeleteStmt +TRUNCATED: "DELETE FROM foo USING int8_tbl i WHERE foo.f1 = i.q2 RETURNING *" +== 027 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 028 +-- truncate_limit: 100 +SELECT * FROM foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foochild" +== 029 +-- truncate_limit: 100 +DROP TABLE foochild +-- +TABLE: name="foochild" schema="" table="foochild" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE foochild" +== 030 +-- truncate_limit: 100 +-- Rules and views + +CREATE TEMP VIEW voo AS SELECT f1, f2 FROM foo +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW voo AS SELECT f1, f2 FROM foo" +== 031 +-- truncate_limit: 100 +CREATE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE voo_i AS ON INSERT TO voo DO INSTEAD INSERT INTO foo VALUES (new.*, 57)" +== 032 +-- truncate_limit: 100 +INSERT INTO voo VALUES(11,'zit') +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO voo VALUES (11, 'zit')" +== 033 +-- truncate_limit: 100 +-- fails: +INSERT INTO voo VALUES(12,'zoo') RETURNING *, f1*2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO voo VALUES (12, 'zoo') RETURNING *, f1 * 2" +== 034 +-- truncate_limit: 100 +-- fails, incompatible list: +CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) RETURNING * +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD INSERT INTO foo VALUES (new.*, 57) RE..." +== 035 +-- truncate_limit: 100 +CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) RETURNING f1, f2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD INSERT INTO foo VALUES (new.*, 57) RE..." +== 036 +-- truncate_limit: 100 +-- should still work +INSERT INTO voo VALUES(13,'zit2') +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO voo VALUES (13, 'zit2')" +== 037 +-- truncate_limit: 100 +-- works now +INSERT INTO voo VALUES(14,'zoo2') RETURNING * +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO voo VALUES (14, 'zoo2') RETURNING *" +== 038 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 039 +-- truncate_limit: 100 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM voo" +== 040 +-- truncate_limit: 100 +CREATE OR REPLACE RULE voo_u AS ON UPDATE TO voo DO INSTEAD + UPDATE foo SET f1 = new.f1, f2 = new.f2 WHERE f1 = old.f1 + RETURNING f1, f2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE voo_u AS ON UPDATE TO voo DO INSTEAD UPDATE foo SET f1 = new.f1, f2 = new...." +== 041 +-- truncate_limit: 100 +update voo set f1 = f1 + 1 where f2 = 'zoo2' +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE voo SET f1 = f1 + 1 WHERE f2 = 'zoo2'" +== 042 +-- truncate_limit: 100 +update voo set f1 = f1 + 1 where f2 = 'zoo2' RETURNING *, f1*2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE voo SET f1 = f1 + 1 WHERE f2 = 'zoo2' RETURNING *, f1 * 2" +== 043 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 044 +-- truncate_limit: 100 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM voo" +== 045 +-- truncate_limit: 100 +CREATE OR REPLACE RULE voo_d AS ON DELETE TO voo DO INSTEAD + DELETE FROM foo WHERE f1 = old.f1 + RETURNING f1, f2 +-- +TABLE: name="voo" schema="" table="voo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE voo_d AS ON DELETE TO voo DO INSTEAD DELETE FROM foo WHERE f1 = old.f1 RET..." +== 046 +-- truncate_limit: 100 +DELETE FROM foo WHERE f1 = 13 +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM foo WHERE f1 = 13" +== 047 +-- truncate_limit: 100 +DELETE FROM foo WHERE f2 = 'zit' RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM foo WHERE f2 = 'zit' RETURNING *" +== 048 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 049 +-- truncate_limit: 100 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM voo" +== 050 +-- truncate_limit: 100 +-- Check use of a whole-row variable for an un-flattenable view +CREATE TEMP VIEW foo_v AS SELECT * FROM foo OFFSET 0 +-- +TABLE: name="foo_v" schema="" table="foo_v" ctx=DDL +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW foo_v AS SELECT * FROM foo OFFSET 0" +== 051 +-- truncate_limit: 100 +UPDATE foo SET f2 = foo_v.f2 FROM foo_v WHERE foo_v.f1 = foo.f1 + RETURNING foo_v +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +TABLE: name="foo_v" schema="" table="foo_v" ctx=Select +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f2 = foo_v.f2 FROM foo_v WHERE foo_v.f1 = foo.f1 RETURNING foo_v" +== 052 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 053 +-- truncate_limit: 100 +-- Check use of a whole-row variable for an inlined set-returning function +CREATE FUNCTION foo_f() RETURNS SETOF foo AS + $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION foo_f() RETURNS SETOF foo AS $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE" +== 054 +-- truncate_limit: 100 +UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 + RETURNING foo_f +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 RETURNING foo_f" +== 055 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 056 +-- truncate_limit: 100 +DROP FUNCTION foo_f() +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION foo_f()" +== 057 +-- truncate_limit: 100 +-- As above, but SRF is defined to return a composite type +CREATE TYPE foo_t AS (f1 int, f2 text, f3 int, f4 int8) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE foo_t AS (f1 int, f2 text, f3 int, f4 int8)" +== 058 +-- truncate_limit: 100 +CREATE FUNCTION foo_f() RETURNS SETOF foo_t AS + $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION foo_f() RETURNS SETOF foo_t AS $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE" +== 059 +-- truncate_limit: 100 +UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 + RETURNING foo_f +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 RETURNING foo_f" +== 060 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 061 +-- truncate_limit: 100 +DROP FUNCTION foo_f() +-- +FUNCTION: name="foo_f" function="foo_f" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION foo_f()" +== 062 +-- truncate_limit: 100 +DROP TYPE foo_t +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE foo_t" +== 063 +-- truncate_limit: 100 +-- Try a join case + +CREATE TEMP TABLE joinme (f2j text, other int) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE joinme (f2j text, other int)" +== 064 +-- truncate_limit: 100 +INSERT INTO joinme VALUES('more', 12345) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO joinme VALUES ('more', 12345)" +== 065 +-- truncate_limit: 100 +INSERT INTO joinme VALUES('zoo2', 54321) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO joinme VALUES ('zoo2', 54321)" +== 066 +-- truncate_limit: 100 +INSERT INTO joinme VALUES('other', 0) +-- +TABLE: name="joinme" schema="" table="joinme" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO joinme VALUES ('other', 0)" +== 067 +-- truncate_limit: 100 +CREATE TEMP VIEW joinview AS + SELECT foo.*, other FROM foo JOIN joinme ON (f2 = f2j) +-- +TABLE: name="joinview" schema="" table="joinview" ctx=DDL +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="joinme" schema="" table="joinme" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW joinview AS SELECT foo.*, other FROM foo JOIN joinme ON f2 = f2j" +== 068 +-- truncate_limit: 100 +SELECT * FROM joinview +-- +TABLE: name="joinview" schema="" table="joinview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM joinview" +== 069 +-- truncate_limit: 100 +CREATE RULE joinview_u AS ON UPDATE TO joinview DO INSTEAD + UPDATE foo SET f1 = new.f1, f3 = new.f3 + FROM joinme WHERE f2 = f2j AND f2 = old.f2 + RETURNING foo.*, other +-- +TABLE: name="joinview" schema="" table="joinview" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE joinview_u AS ON UPDATE TO joinview DO INSTEAD UPDATE foo SET f1 = new.f1, f3 = new.f..." +== 070 +-- truncate_limit: 100 +UPDATE joinview SET f1 = f1 + 1 WHERE f3 = 57 RETURNING *, other + 1 +-- +TABLE: name="joinview" schema="" table="joinview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE joinview SET f1 = f1 + 1 WHERE f3 = 57 RETURNING *, other + 1" +== 071 +-- truncate_limit: 100 +SELECT * FROM joinview +-- +TABLE: name="joinview" schema="" table="joinview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM joinview" +== 072 +-- truncate_limit: 100 +SELECT * FROM foo +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo" +== 073 +-- truncate_limit: 100 +SELECT * FROM voo +-- +TABLE: name="voo" schema="" table="voo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM voo" +== 074 +-- truncate_limit: 100 +-- Check aliased target relation +INSERT INTO foo AS bar DEFAULT VALUES RETURNING * +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt +TRUNCATED: "INSERT INTO foo AS bar DEFAULT VALUES RETURNING *" +== 075 +-- truncate_limit: 100 +-- ok +INSERT INTO foo AS bar DEFAULT VALUES RETURNING foo.* +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt +TRUNCATED: "INSERT INTO foo AS bar DEFAULT VALUES RETURNING foo.*" +== 076 +-- truncate_limit: 100 +-- fails, wrong name +INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.* +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt +TRUNCATED: "INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.*" +== 077 +-- truncate_limit: 100 +-- ok +INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.f3 +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +ALIAS: "bar"="foo" +STMT: InsertStmt +TRUNCATED: "INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.f3" diff --git a/parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json new file mode 100644 index 0000000..fb87925 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json @@ -0,0 +1,84 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/roleattributes.test b/parser/testdata/summary_truncate/postgres_regress/roleattributes.test new file mode 100644 index 0000000..d5b7a32 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/roleattributes.test @@ -0,0 +1,553 @@ +== 001 +-- truncate_limit: 100 +-- default for superuser is false +CREATE ROLE regress_test_def_superuser +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_def_superuser" +== 002 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_superuser'" +== 003 +-- truncate_limit: 100 +CREATE ROLE regress_test_superuser WITH SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_superuser WITH SUPERUSER" +== 004 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_superuser'" +== 005 +-- truncate_limit: 100 +ALTER ROLE regress_test_superuser WITH NOSUPERUSER +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_superuser WITH NOSUPERUSER" +== 006 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_superuser'" +== 007 +-- truncate_limit: 100 +ALTER ROLE regress_test_superuser WITH SUPERUSER +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_superuser WITH SUPERUSER" +== 008 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_superuser'" +== 009 +-- truncate_limit: 100 +-- default for inherit is true +CREATE ROLE regress_test_def_inherit +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_def_inherit" +== 010 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_inherit'" +== 011 +-- truncate_limit: 100 +CREATE ROLE regress_test_inherit WITH NOINHERIT +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_inherit WITH NOINHERIT" +== 012 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_inherit'" +== 013 +-- truncate_limit: 100 +ALTER ROLE regress_test_inherit WITH INHERIT +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_inherit WITH INHERIT" +== 014 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_inherit'" +== 015 +-- truncate_limit: 100 +ALTER ROLE regress_test_inherit WITH NOINHERIT +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_inherit WITH NOINHERIT" +== 016 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_inherit'" +== 017 +-- truncate_limit: 100 +-- default for create role is false +CREATE ROLE regress_test_def_createrole +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_def_createrole" +== 018 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_createrole'" +== 019 +-- truncate_limit: 100 +CREATE ROLE regress_test_createrole WITH CREATEROLE +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_createrole WITH CREATEROLE" +== 020 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_createrole'" +== 021 +-- truncate_limit: 100 +ALTER ROLE regress_test_createrole WITH NOCREATEROLE +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_createrole WITH NOCREATEROLE" +== 022 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_createrole'" +== 023 +-- truncate_limit: 100 +ALTER ROLE regress_test_createrole WITH CREATEROLE +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_createrole WITH CREATEROLE" +== 024 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_createrole'" +== 025 +-- truncate_limit: 100 +-- default for create database is false +CREATE ROLE regress_test_def_createdb +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_def_createdb" +== 026 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_createdb'" +== 027 +-- truncate_limit: 100 +CREATE ROLE regress_test_createdb WITH CREATEDB +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_createdb WITH CREATEDB" +== 028 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_createdb'" +== 029 +-- truncate_limit: 100 +ALTER ROLE regress_test_createdb WITH NOCREATEDB +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_createdb WITH NOCREATEDB" +== 030 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_createdb'" +== 031 +-- truncate_limit: 100 +ALTER ROLE regress_test_createdb WITH CREATEDB +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_createdb WITH CREATEDB" +== 032 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_createdb'" +== 033 +-- truncate_limit: 100 +-- default for can login is false for role +CREATE ROLE regress_test_def_role_canlogin +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_def_role_canlogin" +== 034 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin'" +== 035 +-- truncate_limit: 100 +CREATE ROLE regress_test_role_canlogin WITH LOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_role_canlogin WITH LOGIN" +== 036 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'" +== 037 +-- truncate_limit: 100 +ALTER ROLE regress_test_role_canlogin WITH NOLOGIN +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_role_canlogin WITH NOLOGIN" +== 038 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'" +== 039 +-- truncate_limit: 100 +ALTER ROLE regress_test_role_canlogin WITH LOGIN +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_role_canlogin WITH LOGIN" +== 040 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'" +== 041 +-- truncate_limit: 100 +-- default for can login is true for user +CREATE USER regress_test_def_user_canlogin +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_test_def_user_canlogin" +== 042 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin'" +== 043 +-- truncate_limit: 100 +CREATE USER regress_test_user_canlogin WITH NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_test_user_canlogin WITH NOLOGIN" +== 044 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'" +== 045 +-- truncate_limit: 100 +ALTER USER regress_test_user_canlogin WITH LOGIN +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_user_canlogin WITH LOGIN" +== 046 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'" +== 047 +-- truncate_limit: 100 +ALTER USER regress_test_user_canlogin WITH NOLOGIN +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_user_canlogin WITH NOLOGIN" +== 048 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'" +== 049 +-- truncate_limit: 100 +-- default for replication is false +CREATE ROLE regress_test_def_replication +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_def_replication" +== 050 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_replication'" +== 051 +-- truncate_limit: 100 +CREATE ROLE regress_test_replication WITH REPLICATION +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_replication WITH REPLICATION" +== 052 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_replication'" +== 053 +-- truncate_limit: 100 +ALTER ROLE regress_test_replication WITH NOREPLICATION +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_replication WITH NOREPLICATION" +== 054 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_replication'" +== 055 +-- truncate_limit: 100 +ALTER ROLE regress_test_replication WITH REPLICATION +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_replication WITH REPLICATION" +== 056 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_replication'" +== 057 +-- truncate_limit: 100 +-- default for bypassrls is false +CREATE ROLE regress_test_def_bypassrls +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_def_bypassrls" +== 058 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls'" +== 059 +-- truncate_limit: 100 +CREATE ROLE regress_test_bypassrls WITH BYPASSRLS +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_test_bypassrls WITH BYPASSRLS" +== 060 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_bypassrls'" +== 061 +-- truncate_limit: 100 +ALTER ROLE regress_test_bypassrls WITH NOBYPASSRLS +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_bypassrls WITH NOBYPASSRLS" +== 062 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_bypassrls'" +== 063 +-- truncate_limit: 100 +ALTER ROLE regress_test_bypassrls WITH BYPASSRLS +-- +STMT: AlterRoleStmt +TRUNCATED: "ALTER ROLE regress_test_bypassrls WITH BYPASSRLS" +== 064 +-- truncate_limit: 100 +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls' +-- +TABLE: name="pg_authid" schema="" table="pg_authid" ctx=Select +FILTER: schema="" table="" column="rolname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_authid WHERE rolname = 'regress_test_bypassrls'" +== 065 +-- truncate_limit: 100 +-- clean up roles +DROP ROLE regress_test_def_superuser +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_superuser" +== 066 +-- truncate_limit: 100 +DROP ROLE regress_test_superuser +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_superuser" +== 067 +-- truncate_limit: 100 +DROP ROLE regress_test_def_inherit +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_inherit" +== 068 +-- truncate_limit: 100 +DROP ROLE regress_test_inherit +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_inherit" +== 069 +-- truncate_limit: 100 +DROP ROLE regress_test_def_createrole +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_createrole" +== 070 +-- truncate_limit: 100 +DROP ROLE regress_test_createrole +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_createrole" +== 071 +-- truncate_limit: 100 +DROP ROLE regress_test_def_createdb +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_createdb" +== 072 +-- truncate_limit: 100 +DROP ROLE regress_test_createdb +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_createdb" +== 073 +-- truncate_limit: 100 +DROP ROLE regress_test_def_role_canlogin +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_role_canlogin" +== 074 +-- truncate_limit: 100 +DROP ROLE regress_test_role_canlogin +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_role_canlogin" +== 075 +-- truncate_limit: 100 +DROP USER regress_test_def_user_canlogin +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_user_canlogin" +== 076 +-- truncate_limit: 100 +DROP USER regress_test_user_canlogin +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_user_canlogin" +== 077 +-- truncate_limit: 100 +DROP ROLE regress_test_def_replication +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_replication" +== 078 +-- truncate_limit: 100 +DROP ROLE regress_test_replication +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_replication" +== 079 +-- truncate_limit: 100 +DROP ROLE regress_test_def_bypassrls +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_def_bypassrls" +== 080 +-- truncate_limit: 100 +DROP ROLE regress_test_bypassrls +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_test_bypassrls" diff --git a/parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json new file mode 100644 index 0000000..dcaa437 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json @@ -0,0 +1,779 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/rowsecurity.test b/parser/testdata/summary_truncate/postgres_regress/rowsecurity.test new file mode 100644 index 0000000..ab90e30 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rowsecurity.test @@ -0,0 +1,6370 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test of Row-level security feature +|-- + +-- Clean up in case a prior regression run failed + +-- Suppress NOTICE messages when users/groups don't exist +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 002 +-- truncate_limit: 100 +DROP USER IF EXISTS regress_rls_alice +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_rls_alice" +== 003 +-- truncate_limit: 100 +DROP USER IF EXISTS regress_rls_bob +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_rls_bob" +== 004 +-- truncate_limit: 100 +DROP USER IF EXISTS regress_rls_carol +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_rls_carol" +== 005 +-- truncate_limit: 100 +DROP USER IF EXISTS regress_rls_dave +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_rls_dave" +== 006 +-- truncate_limit: 100 +DROP USER IF EXISTS regress_rls_exempt_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_rls_exempt_user" +== 007 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_rls_group1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_rls_group1" +== 008 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_rls_group2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_rls_group2" +== 009 +-- truncate_limit: 100 +DROP SCHEMA IF EXISTS regress_rls_schema CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA IF EXISTS regress_rls_schema CASCADE" +== 010 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 011 +-- truncate_limit: 100 +-- initial setup +CREATE USER regress_rls_alice NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_rls_alice WITH NOLOGIN" +== 012 +-- truncate_limit: 100 +CREATE USER regress_rls_bob NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_rls_bob WITH NOLOGIN" +== 013 +-- truncate_limit: 100 +CREATE USER regress_rls_carol NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_rls_carol WITH NOLOGIN" +== 014 +-- truncate_limit: 100 +CREATE USER regress_rls_dave NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_rls_dave WITH NOLOGIN" +== 015 +-- truncate_limit: 100 +CREATE USER regress_rls_exempt_user BYPASSRLS NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_rls_exempt_user WITH BYPASSRLS NOLOGIN" +== 016 +-- truncate_limit: 100 +CREATE ROLE regress_rls_group1 NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rls_group1 WITH NOLOGIN" +== 017 +-- truncate_limit: 100 +CREATE ROLE regress_rls_group2 NOLOGIN +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_rls_group2 WITH NOLOGIN" +== 018 +-- truncate_limit: 100 +GRANT regress_rls_group1 TO regress_rls_bob +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_rls_group1 TO regress_rls_bob" +== 019 +-- truncate_limit: 100 +GRANT regress_rls_group2 TO regress_rls_carol +-- +STMT: GrantRoleStmt +TRUNCATED: "GRANT regress_rls_group2 TO regress_rls_carol" +== 020 +-- truncate_limit: 100 +CREATE SCHEMA regress_rls_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_rls_schema" +== 021 +-- truncate_limit: 100 +GRANT ALL ON SCHEMA regress_rls_schema to public +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON SCHEMA regress_rls_schema TO public" +== 022 +-- truncate_limit: 100 +SET search_path = regress_rls_schema +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO regress_rls_schema" +== 023 +-- truncate_limit: 100 +-- setup of malicious function +CREATE OR REPLACE FUNCTION f_leak(text) RETURNS bool + COST 0.0000001 LANGUAGE plpgsql + AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END' +-- +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION f_leak(text) RETURNS bool COST 0.0000001 LANGUAGE plpgsql AS $$BEGIN R..." +== 024 +-- truncate_limit: 100 +GRANT EXECUTE ON FUNCTION f_leak(text) TO public +-- +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT execute ON FUNCTION f_leak(text) TO public" +== 025 +-- truncate_limit: 100 +-- BASIC Row-Level Security Scenario + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 026 +-- truncate_limit: 100 +CREATE TABLE uaccount ( + pguser name primary key, + seclv int +) +-- +TABLE: name="uaccount" schema="" table="uaccount" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE uaccount (pguser name PRIMARY KEY, seclv int)" +== 027 +-- truncate_limit: 100 +GRANT SELECT ON uaccount TO public +-- +TABLE: name="uaccount" schema="" table="uaccount" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON uaccount TO public" +== 028 +-- truncate_limit: 100 +INSERT INTO uaccount VALUES + ('regress_rls_alice', 99), + ('regress_rls_bob', 1), + ('regress_rls_carol', 2), + ('regress_rls_dave', 3) +-- +TABLE: name="uaccount" schema="" table="uaccount" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uaccount VALUES (...)" +== 029 +-- truncate_limit: 100 +CREATE TABLE category ( + cid int primary key, + cname text +) +-- +TABLE: name="category" schema="" table="category" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE category (cid int PRIMARY KEY, cname text)" +== 030 +-- truncate_limit: 100 +GRANT ALL ON category TO public +-- +TABLE: name="category" schema="" table="category" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON category TO public" +== 031 +-- truncate_limit: 100 +INSERT INTO category VALUES + (11, 'novel'), + (22, 'science fiction'), + (33, 'technology'), + (44, 'manga') +-- +TABLE: name="category" schema="" table="category" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO category VALUES (...)" +== 032 +-- truncate_limit: 100 +CREATE TABLE document ( + did int primary key, + cid int references category(cid), + dlevel int not null, + dauthor name, + dtitle text +) +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE document (did int PRIMARY KEY, cid int REFERENCES category (cid), dlevel int NOT NUL..." +== 033 +-- truncate_limit: 100 +GRANT ALL ON document TO public +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON document TO public" +== 034 +-- truncate_limit: 100 +INSERT INTO document VALUES + ( 1, 11, 1, 'regress_rls_bob', 'my first novel'), + ( 2, 11, 2, 'regress_rls_bob', 'my second novel'), + ( 3, 22, 2, 'regress_rls_bob', 'my science fiction'), + ( 4, 44, 1, 'regress_rls_bob', 'my first manga'), + ( 5, 44, 2, 'regress_rls_bob', 'my second manga'), + ( 6, 22, 1, 'regress_rls_carol', 'great science fiction'), + ( 7, 33, 2, 'regress_rls_carol', 'great technology book'), + ( 8, 44, 1, 'regress_rls_carol', 'great manga'), + ( 9, 22, 1, 'regress_rls_dave', 'awesome science fiction'), + (10, 33, 2, 'regress_rls_dave', 'awesome technology book') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...)" +== 035 +-- truncate_limit: 100 +ALTER TABLE document ENABLE ROW LEVEL SECURITY +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE document ENABLE ROW LEVEL SECURITY" +== 036 +-- truncate_limit: 100 +-- user's security level must be higher than or equal to document's +CREATE POLICY p1 ON document AS PERMISSIVE + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON document TO public USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser ..." +== 037 +-- truncate_limit: 100 +-- try to create a policy of bogus type +CREATE POLICY p1 ON document AS UGLY + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)) +-- +ERROR: unrecognized row security option "ugly" +CURSORPOS: 73 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 038 +-- truncate_limit: 100 +-- but Dave isn't allowed to anything at cid 50 or above +-- this is to make sure that we sort the policies by name first +-- when applying WITH CHECK, a later INSERT by Dave should fail due +-- to p1r first +CREATE POLICY p2r ON document AS RESTRICTIVE TO regress_rls_dave + USING (cid <> 44 AND cid < 50) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2r ON document AS RESTRICTIVE TO regress_rls_dave USING (cid <> 44 AND cid < 50)" +== 039 +-- truncate_limit: 100 +-- and Dave isn't allowed to see manga documents +CREATE POLICY p1r ON document AS RESTRICTIVE TO regress_rls_dave + USING (cid <> 44) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1r ON document AS RESTRICTIVE TO regress_rls_dave USING (cid <> 44)" +== 040 +-- truncate_limit: 100 +SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename = 'document' ORDER BY policyname +-- +TABLE: name="pg_policies" schema="" table="pg_policies" ctx=Select +FILTER: schema="" table="" column="schemaname" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_policies WHERE ... ORDER BY policyname" +== 041 +-- truncate_limit: 100 +-- viewpoint from regress_rls_bob +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 042 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 043 +-- truncate_limit: 100 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did" +== 044 +-- truncate_limit: 100 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did" +== 045 +-- truncate_limit: 100 +-- try a sampled version +SELECT * FROM document TABLESAMPLE BERNOULLI(50) REPEATABLE(0) + WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document TABLESAMPLE bernoulli(50) REPEATABLE (0) WHERE f_leak(dtitle) ORDER BY did" +== 046 +-- truncate_limit: 100 +-- viewpoint from regress_rls_carol +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 047 +-- truncate_limit: 100 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did" +== 048 +-- truncate_limit: 100 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did" +== 049 +-- truncate_limit: 100 +-- try a sampled version +SELECT * FROM document TABLESAMPLE BERNOULLI(50) REPEATABLE(0) + WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document TABLESAMPLE bernoulli(50) REPEATABLE (0) WHERE f_leak(dtitle) ORDER BY did" +== 050 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle)" +== 051 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle)" +== 052 +-- truncate_limit: 100 +-- viewpoint from regress_rls_dave +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_dave" +== 053 +-- truncate_limit: 100 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did" +== 054 +-- truncate_limit: 100 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did" +== 055 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle)" +== 056 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle)" +== 057 +-- truncate_limit: 100 +-- 44 would technically fail for both p2r and p1r, but we should get an error +-- back from p1r for this because it sorts first +INSERT INTO document VALUES (100, 44, 1, 'regress_rls_dave', 'testing sorting of policies') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (100, 44, 1, 'regress_rls_dave', 'testing sorting of policies')" +== 058 +-- truncate_limit: 100 +-- fail +-- Just to see a p2r error +INSERT INTO document VALUES (100, 55, 1, 'regress_rls_dave', 'testing sorting of policies') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (100, 55, 1, 'regress_rls_dave', 'testing sorting of policies')" +== 059 +-- truncate_limit: 100 +-- fail + +-- only owner can change policies +ALTER POLICY p1 ON document USING (true) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY p1 ON document USING (true)" +== 060 +-- truncate_limit: 100 +--fail +DROP POLICY p1 ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p1 ON document" +== 061 +-- truncate_limit: 100 +--fail + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 062 +-- truncate_limit: 100 +ALTER POLICY p1 ON document USING (dauthor = current_user) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY p1 ON document USING (dauthor = current_user)" +== 063 +-- truncate_limit: 100 +-- viewpoint from regress_rls_bob again +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 064 +-- truncate_limit: 100 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did" +== 065 +-- truncate_limit: 100 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER by did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did" +== 066 +-- truncate_limit: 100 +-- viewpoint from rls_regres_carol again +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 067 +-- truncate_limit: 100 +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did" +== 068 +-- truncate_limit: 100 +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER by did +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did" +== 069 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle)" +== 070 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle)" +== 071 +-- truncate_limit: 100 +-- interaction of FK/PK constraints +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 072 +-- truncate_limit: 100 +CREATE POLICY p2 ON category + USING (CASE WHEN current_user = 'regress_rls_bob' THEN cid IN (11, 33) + WHEN current_user = 'regress_rls_carol' THEN cid IN (22, 44) + ELSE false END) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON category TO public USING (CASE WHEN current_user = 'regress_rls_bob' THEN cid..." +== 073 +-- truncate_limit: 100 +ALTER TABLE category ENABLE ROW LEVEL SECURITY +-- +TABLE: name="category" schema="" table="category" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE category ENABLE ROW LEVEL SECURITY" +== 074 +-- truncate_limit: 100 +-- cannot delete PK referenced by invisible FK +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 075 +-- truncate_limit: 100 +SELECT * FROM document d FULL OUTER JOIN category c on d.cid = c.cid ORDER BY d.did, c.cid +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "c"="category" +ALIAS: "d"="document" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document d FULL JOIN category c ON d.cid = c.cid ORDER BY d.did, c.cid" +== 076 +-- truncate_limit: 100 +DELETE FROM category WHERE cid = 33 +-- +TABLE: name="category" schema="" table="category" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM category WHERE cid = 33" +== 077 +-- truncate_limit: 100 +-- fails with FK violation + +-- can insert FK referencing invisible PK +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 078 +-- truncate_limit: 100 +SELECT * FROM document d FULL OUTER JOIN category c on d.cid = c.cid ORDER BY d.did, c.cid +-- +TABLE: name="document" schema="" table="document" ctx=Select +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "c"="category" +ALIAS: "d"="document" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document d FULL JOIN category c ON d.cid = c.cid ORDER BY d.did, c.cid" +== 079 +-- truncate_limit: 100 +INSERT INTO document VALUES (11, 33, 1, current_user, 'hoge') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (11, 33, 1, current_user, 'hoge')" +== 080 +-- truncate_limit: 100 +-- UNIQUE or PRIMARY KEY constraint violation DOES reveal presence of row +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 081 +-- truncate_limit: 100 +INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga')" +== 082 +-- truncate_limit: 100 +-- Must fail with unique violation, revealing presence of did we can't see +SELECT * FROM document WHERE did = 8 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE did = 8" +== 083 +-- truncate_limit: 100 +-- and confirm we can't see it + +-- RLS policies are checked before constraints +INSERT INTO document VALUES (8, 44, 1, 'regress_rls_carol', 'my third manga') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (8, 44, 1, 'regress_rls_carol', 'my third manga')" +== 084 +-- truncate_limit: 100 +-- Should fail with RLS check violation, not duplicate key violation +UPDATE document SET did = 8, dauthor = 'regress_rls_carol' WHERE did = 5 +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE document SET did = 8, dauthor = 'regress_rls_carol' WHERE did = 5" +== 085 +-- truncate_limit: 100 +-- Should fail with RLS check violation, not duplicate key violation + +-- database superuser does bypass RLS policy when enabled +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 086 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 087 +-- truncate_limit: 100 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document" +== 088 +-- truncate_limit: 100 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM category" +== 089 +-- truncate_limit: 100 +-- database superuser does bypass RLS policy when disabled +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 090 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 091 +-- truncate_limit: 100 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document" +== 092 +-- truncate_limit: 100 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM category" +== 093 +-- truncate_limit: 100 +-- database non-superuser with bypass privilege can bypass RLS policy when disabled +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_exempt_user" +== 094 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 095 +-- truncate_limit: 100 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document" +== 096 +-- truncate_limit: 100 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM category" +== 097 +-- truncate_limit: 100 +-- RLS policy does not apply to table owner when RLS enabled. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 098 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 099 +-- truncate_limit: 100 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document" +== 100 +-- truncate_limit: 100 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM category" +== 101 +-- truncate_limit: 100 +-- RLS policy does not apply to table owner when RLS disabled. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 102 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 103 +-- truncate_limit: 100 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document" +== 104 +-- truncate_limit: 100 +SELECT * FROM category +-- +TABLE: name="category" schema="" table="category" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM category" +== 105 +-- truncate_limit: 100 +|-- +-- Table inheritance and RLS policy +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 106 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 107 +-- truncate_limit: 100 +CREATE TABLE t1 (id int not null primary key, a int, junk1 text, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int, junk1 text, b text)" +== 108 +-- truncate_limit: 100 +ALTER TABLE t1 DROP COLUMN junk1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t1 DROP junk1" +== 109 +-- truncate_limit: 100 +-- just a disturbing factor +GRANT ALL ON t1 TO public +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON t1 TO public" +== 110 +-- truncate_limit: 100 +COPY t1 FROM stdin WITH +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY t1 FROM STDIN" +== 111 +-- truncate_limit: 100 +CREATE TABLE t2 (c float) INHERITS (t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t2 (c double precision) INHERITS (t1)" +== 112 +-- truncate_limit: 100 +GRANT ALL ON t2 TO public +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON t2 TO public" +== 113 +-- truncate_limit: 100 +COPY t2 FROM stdin +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY t2 FROM STDIN" +== 114 +-- truncate_limit: 100 +CREATE TABLE t3 (id int not null primary key, c text, b text, a int) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t3 (id int NOT NULL PRIMARY KEY, c text, b text, a int)" +== 115 +-- truncate_limit: 100 +ALTER TABLE t3 INHERIT t1 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t3 INHERIT t1" +== 116 +-- truncate_limit: 100 +GRANT ALL ON t3 TO public +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON t3 TO public" +== 117 +-- truncate_limit: 100 +COPY t3(id, a,b,c) FROM stdin +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY t3(id, a, b, c) FROM STDIN" +== 118 +-- truncate_limit: 100 +CREATE POLICY p1 ON t1 FOR ALL TO PUBLIC USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON t1 TO public USING ((a % 2) = 0)" +== 119 +-- truncate_limit: 100 +-- be even number +CREATE POLICY p2 ON t2 FOR ALL TO PUBLIC USING (a % 2 = 1) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON t2 TO public USING ((a % 2) = 1)" +== 120 +-- truncate_limit: 100 +-- be odd number + +ALTER TABLE t1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t1 ENABLE ROW LEVEL SECURITY" +== 121 +-- truncate_limit: 100 +ALTER TABLE t2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t2 ENABLE ROW LEVEL SECURITY" +== 122 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 123 +-- truncate_limit: 100 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 124 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1" +== 125 +-- truncate_limit: 100 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 WHERE f_leak(b)" +== 126 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b)" +== 127 +-- truncate_limit: 100 +-- reference to system column +SELECT tableoid::regclass, * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM t1" +== 128 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1" +== 129 +-- truncate_limit: 100 +-- reference to whole-row reference +SELECT *, t1 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT *, t1 FROM t1" +== 130 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1" +== 131 +-- truncate_limit: 100 +-- for share/update lock +SELECT * FROM t1 FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 FOR SHARE" +== 132 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE" +== 133 +-- truncate_limit: 100 +SELECT * FROM t1 WHERE f_leak(b) FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 WHERE f_leak(b) FOR SHARE" +== 134 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE" +== 135 +-- truncate_limit: 100 +-- union all query +SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3" +== 136 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regc..." +== 137 +-- truncate_limit: 100 +-- superuser is allowed to bypass RLS checks +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 138 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 139 +-- truncate_limit: 100 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 WHERE f_leak(b)" +== 140 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b)" +== 141 +-- truncate_limit: 100 +-- non-superuser with bypass privilege can bypass RLS policy when disabled +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_exempt_user" +== 142 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 143 +-- truncate_limit: 100 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 WHERE f_leak(b)" +== 144 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b)" +== 145 +-- truncate_limit: 100 +|-- +-- Partitioned Tables +|-- + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 146 +-- truncate_limit: 100 +CREATE TABLE part_document ( + did int, + cid int, + dlevel int not null, + dauthor name, + dtitle text +) PARTITION BY RANGE (cid) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_document (did int, cid int, dlevel int NOT NULL, dauthor name, dtitle text) PAR..." +== 147 +-- truncate_limit: 100 +GRANT ALL ON part_document TO public +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON part_document TO public" +== 148 +-- truncate_limit: 100 +-- Create partitions for document categories +CREATE TABLE part_document_fiction PARTITION OF part_document FOR VALUES FROM (11) to (12) +-- +TABLE: name="part_document_fiction" schema="" table="part_document_fiction" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_document_fiction PARTITION OF part_document FOR VALUES FROM (11) TO (12)" +== 149 +-- truncate_limit: 100 +CREATE TABLE part_document_satire PARTITION OF part_document FOR VALUES FROM (55) to (56) +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_document_satire PARTITION OF part_document FOR VALUES FROM (55) TO (56)" +== 150 +-- truncate_limit: 100 +CREATE TABLE part_document_nonfiction PARTITION OF part_document FOR VALUES FROM (99) to (100) +-- +TABLE: name="part_document_nonfiction" schema="" table="part_document_nonfiction" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_document_nonfiction PARTITION OF part_document FOR VALUES FROM (99) TO (100)" +== 151 +-- truncate_limit: 100 +GRANT ALL ON part_document_fiction TO public +-- +TABLE: name="part_document_fiction" schema="" table="part_document_fiction" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON part_document_fiction TO public" +== 152 +-- truncate_limit: 100 +GRANT ALL ON part_document_satire TO public +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON part_document_satire TO public" +== 153 +-- truncate_limit: 100 +GRANT ALL ON part_document_nonfiction TO public +-- +TABLE: name="part_document_nonfiction" schema="" table="part_document_nonfiction" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON part_document_nonfiction TO public" +== 154 +-- truncate_limit: 100 +INSERT INTO part_document VALUES + ( 1, 11, 1, 'regress_rls_bob', 'my first novel'), + ( 2, 11, 2, 'regress_rls_bob', 'my second novel'), + ( 3, 99, 2, 'regress_rls_bob', 'my science textbook'), + ( 4, 55, 1, 'regress_rls_bob', 'my first satire'), + ( 5, 99, 2, 'regress_rls_bob', 'my history book'), + ( 6, 11, 1, 'regress_rls_carol', 'great science fiction'), + ( 7, 99, 2, 'regress_rls_carol', 'great technology book'), + ( 8, 55, 2, 'regress_rls_carol', 'great satire'), + ( 9, 11, 1, 'regress_rls_dave', 'awesome science fiction'), + (10, 99, 2, 'regress_rls_dave', 'awesome technology book') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_document VALUES (...)" +== 155 +-- truncate_limit: 100 +ALTER TABLE part_document ENABLE ROW LEVEL SECURITY +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_document ENABLE ROW LEVEL SECURITY" +== 156 +-- truncate_limit: 100 +-- Create policy on parent +-- user's security level must be higher than or equal to document's +CREATE POLICY pp1 ON part_document AS PERMISSIVE + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY pp1 ON part_document TO public USING (dlevel <= (SELECT seclv FROM uaccount WHERE p..." +== 157 +-- truncate_limit: 100 +-- Dave is only allowed to see cid < 55 +CREATE POLICY pp1r ON part_document AS RESTRICTIVE TO regress_rls_dave + USING (cid < 55) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY pp1r ON part_document AS RESTRICTIVE TO regress_rls_dave USING (cid < 55)" +== 158 +-- truncate_limit: 100 +SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename like '%part_document%' ORDER BY policyname +-- +TABLE: name="pg_policies" schema="" table="pg_policies" ctx=Select +FILTER: schema="" table="" column="schemaname" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_policies WHERE ... ORDER BY policyname" +== 159 +-- truncate_limit: 100 +-- viewpoint from regress_rls_bob +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 160 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 161 +-- truncate_limit: 100 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 162 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle)" +== 163 +-- truncate_limit: 100 +-- viewpoint from regress_rls_carol +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 164 +-- truncate_limit: 100 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 165 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle)" +== 166 +-- truncate_limit: 100 +-- viewpoint from regress_rls_dave +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_dave" +== 167 +-- truncate_limit: 100 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 168 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle)" +== 169 +-- truncate_limit: 100 +-- pp1 ERROR +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_dave', 'testing pp1') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_dave', 'testing pp1')" +== 170 +-- truncate_limit: 100 +-- fail +-- pp1r ERROR +INSERT INTO part_document VALUES (100, 99, 1, 'regress_rls_dave', 'testing pp1r') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_document VALUES (100, 99, 1, 'regress_rls_dave', 'testing pp1r')" +== 171 +-- truncate_limit: 100 +-- fail + +-- Show that RLS policy does not apply for direct inserts to children +-- This should fail with RLS POLICY pp1r violation. +INSERT INTO part_document VALUES (100, 55, 1, 'regress_rls_dave', 'testing RLS with partitions') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_document VALUES (100, 55, 1, 'regress_rls_dave', 'testing RLS with partitions')" +== 172 +-- truncate_limit: 100 +-- fail +-- But this should succeed. +INSERT INTO part_document_satire VALUES (100, 55, 1, 'regress_rls_dave', 'testing RLS with partitions') +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_document_satire VALUES (...)" +== 173 +-- truncate_limit: 100 +-- success +-- We still cannot see the row using the parent +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 174 +-- truncate_limit: 100 +-- But we can if we look directly +SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did" +== 175 +-- truncate_limit: 100 +-- Turn on RLS and create policy on child to show RLS is checked before constraints +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 176 +-- truncate_limit: 100 +ALTER TABLE part_document_satire ENABLE ROW LEVEL SECURITY +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_document_satire ENABLE ROW LEVEL SECURITY" +== 177 +-- truncate_limit: 100 +CREATE POLICY pp3 ON part_document_satire AS RESTRICTIVE + USING (cid < 55) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY pp3 ON part_document_satire AS RESTRICTIVE TO public USING (cid < 55)" +== 178 +-- truncate_limit: 100 +-- This should fail with RLS violation now. +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_dave" +== 179 +-- truncate_limit: 100 +INSERT INTO part_document_satire VALUES (101, 55, 1, 'regress_rls_dave', 'testing RLS with partitions') +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_document_satire VALUES (...)" +== 180 +-- truncate_limit: 100 +-- fail +-- And now we cannot see directly into the partition either, due to RLS +SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did" +== 181 +-- truncate_limit: 100 +-- The parent looks same as before +-- viewpoint from regress_rls_dave +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 182 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle)" +== 183 +-- truncate_limit: 100 +-- viewpoint from regress_rls_carol +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 184 +-- truncate_limit: 100 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 185 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle)" +== 186 +-- truncate_limit: 100 +-- only owner can change policies +ALTER POLICY pp1 ON part_document USING (true) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY pp1 ON part_document USING (true)" +== 187 +-- truncate_limit: 100 +--fail +DROP POLICY pp1 ON part_document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY pp1 ON part_document" +== 188 +-- truncate_limit: 100 +--fail + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 189 +-- truncate_limit: 100 +ALTER POLICY pp1 ON part_document USING (dauthor = current_user) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY pp1 ON part_document USING (dauthor = current_user)" +== 190 +-- truncate_limit: 100 +-- viewpoint from regress_rls_bob again +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 191 +-- truncate_limit: 100 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 192 +-- truncate_limit: 100 +-- viewpoint from rls_regres_carol again +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 193 +-- truncate_limit: 100 +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did" +== 194 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle) +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="dtitle" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle)" +== 195 +-- truncate_limit: 100 +-- database superuser does bypass RLS policy when enabled +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 196 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 197 +-- truncate_limit: 100 +SELECT * FROM part_document ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document ORDER BY did" +== 198 +-- truncate_limit: 100 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document_satire ORDER BY did" +== 199 +-- truncate_limit: 100 +-- database non-superuser with bypass privilege can bypass RLS policy when disabled +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_exempt_user" +== 200 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 201 +-- truncate_limit: 100 +SELECT * FROM part_document ORDER BY did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document ORDER BY did" +== 202 +-- truncate_limit: 100 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document_satire ORDER BY did" +== 203 +-- truncate_limit: 100 +-- RLS policy does not apply to table owner when RLS enabled. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 204 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 205 +-- truncate_limit: 100 +SELECT * FROM part_document ORDER by did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document ORDER BY did" +== 206 +-- truncate_limit: 100 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document_satire ORDER BY did" +== 207 +-- truncate_limit: 100 +-- When RLS disabled, other users get ERROR. +SET SESSION AUTHORIZATION regress_rls_dave +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_dave" +== 208 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 209 +-- truncate_limit: 100 +SELECT * FROM part_document ORDER by did +-- +TABLE: name="part_document" schema="" table="part_document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document ORDER BY did" +== 210 +-- truncate_limit: 100 +SELECT * FROM part_document_satire ORDER by did +-- +TABLE: name="part_document_satire" schema="" table="part_document_satire" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM part_document_satire ORDER BY did" +== 211 +-- truncate_limit: 100 +-- Check behavior with a policy that uses a SubPlan not an InitPlan. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 212 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 213 +-- truncate_limit: 100 +CREATE POLICY pp3 ON part_document AS RESTRICTIVE + USING ((SELECT dlevel <= seclv FROM uaccount WHERE pguser = current_user)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY pp3 ON part_document AS RESTRICTIVE TO public USING ((SELECT dlevel <= seclv FROM u..." +== 214 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 215 +-- truncate_limit: 100 +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_carol', 'testing pp3') +-- +TABLE: name="part_document" schema="" table="part_document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_carol', 'testing pp3')" +== 216 +-- truncate_limit: 100 +-- fail + +----- Dependencies ----- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 217 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 218 +-- truncate_limit: 100 +CREATE TABLE dependee (x integer, y integer) +-- +TABLE: name="dependee" schema="" table="dependee" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dependee (x int, y int)" +== 219 +-- truncate_limit: 100 +CREATE TABLE dependent (x integer, y integer) +-- +TABLE: name="dependent" schema="" table="dependent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE dependent (x int, y int)" +== 220 +-- truncate_limit: 100 +CREATE POLICY d1 ON dependent FOR ALL + TO PUBLIC + USING (x = (SELECT d.x FROM dependee d WHERE d.y = y)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY d1 ON dependent TO public USING (x = (SELECT d.x FROM dependee d WHERE d.y = y))" +== 221 +-- truncate_limit: 100 +DROP TABLE dependee +-- +TABLE: name="dependee" schema="" table="dependee" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE dependee" +== 222 +-- truncate_limit: 100 +-- Should fail without CASCADE due to dependency on row security qual? + +DROP TABLE dependee CASCADE +-- +TABLE: name="dependee" schema="" table="dependee" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE dependee CASCADE" +== 223 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM dependent +-- +TABLE: name="dependent" schema="" table="dependent" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM dependent" +== 224 +-- truncate_limit: 100 +-- After drop, should be unqualified + +----- RECURSION ---- + +|-- +-- Simple recursion +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 225 +-- truncate_limit: 100 +CREATE TABLE rec1 (x integer, y integer) +-- +TABLE: name="rec1" schema="" table="rec1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rec1 (x int, y int)" +== 226 +-- truncate_limit: 100 +CREATE POLICY r1 ON rec1 USING (x = (SELECT r.x FROM rec1 r WHERE y = r.y)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY r1 ON rec1 TO public USING (x = (SELECT r.x FROM rec1 r WHERE y = r.y))" +== 227 +-- truncate_limit: 100 +ALTER TABLE rec1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="rec1" schema="" table="rec1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rec1 ENABLE ROW LEVEL SECURITY" +== 228 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 229 +-- truncate_limit: 100 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rec1" +== 230 +-- truncate_limit: 100 +-- fail, direct recursion + +|-- +-- Mutual recursion +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 231 +-- truncate_limit: 100 +CREATE TABLE rec2 (a integer, b integer) +-- +TABLE: name="rec2" schema="" table="rec2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rec2 (a int, b int)" +== 232 +-- truncate_limit: 100 +ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2 WHERE b = y)) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2 WHERE b = y))" +== 233 +-- truncate_limit: 100 +CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1 WHERE y = b)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY r2 ON rec2 TO public USING (a = (SELECT x FROM rec1 WHERE y = b))" +== 234 +-- truncate_limit: 100 +ALTER TABLE rec2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="rec2" schema="" table="rec2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rec2 ENABLE ROW LEVEL SECURITY" +== 235 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 236 +-- truncate_limit: 100 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rec1" +== 237 +-- truncate_limit: 100 +-- fail, mutual recursion + +|-- +-- Mutual recursion via views +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 238 +-- truncate_limit: 100 +CREATE VIEW rec1v AS SELECT * FROM rec1 +-- +TABLE: name="rec1v" schema="" table="rec1v" ctx=DDL +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rec1v AS SELECT * FROM rec1" +== 239 +-- truncate_limit: 100 +CREATE VIEW rec2v AS SELECT * FROM rec2 +-- +TABLE: name="rec2v" schema="" table="rec2v" ctx=DDL +TABLE: name="rec2" schema="" table="rec2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rec2v AS SELECT * FROM rec2" +== 240 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 241 +-- truncate_limit: 100 +ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y)) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y))" +== 242 +-- truncate_limit: 100 +ALTER POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b)) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b))" +== 243 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 244 +-- truncate_limit: 100 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rec1" +== 245 +-- truncate_limit: 100 +-- fail, mutual recursion via views + +|-- +-- Mutual recursion via .s.b views +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 246 +-- truncate_limit: 100 +DROP VIEW rec1v, rec2v CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rec1v, rec2v CASCADE" +== 247 +-- truncate_limit: 100 +CREATE VIEW rec1v WITH (security_barrier) AS SELECT * FROM rec1 +-- +TABLE: name="rec1v" schema="" table="rec1v" ctx=DDL +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rec1v WITH (security_barrier) AS SELECT * FROM rec1" +== 248 +-- truncate_limit: 100 +CREATE VIEW rec2v WITH (security_barrier) AS SELECT * FROM rec2 +-- +TABLE: name="rec2v" schema="" table="rec2v" ctx=DDL +TABLE: name="rec2" schema="" table="rec2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rec2v WITH (security_barrier) AS SELECT * FROM rec2" +== 249 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 250 +-- truncate_limit: 100 +CREATE POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY r1 ON rec1 TO public USING (x = (SELECT a FROM rec2v WHERE b = y))" +== 251 +-- truncate_limit: 100 +CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY r2 ON rec2 TO public USING (a = (SELECT x FROM rec1v WHERE y = b))" +== 252 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 253 +-- truncate_limit: 100 +SELECT * FROM rec1 +-- +TABLE: name="rec1" schema="" table="rec1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rec1" +== 254 +-- truncate_limit: 100 +-- fail, mutual recursion via s.b. views + +|-- +-- recursive RLS and VIEWs in policy +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 255 +-- truncate_limit: 100 +CREATE TABLE s1 (a int, b text) +-- +TABLE: name="s1" schema="" table="s1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE s1 (a int, b text)" +== 256 +-- truncate_limit: 100 +INSERT INTO s1 (SELECT x, public.fipshash(x::text) FROM generate_series(-10,10) x) +-- +TABLE: name="s1" schema="" table="s1" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO s1 SELECT x, public.fipshash(x::text) FROM generate_series(-10, 10) x" +== 257 +-- truncate_limit: 100 +CREATE TABLE s2 (x int, y text) +-- +TABLE: name="s2" schema="" table="s2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE s2 (x int, y text)" +== 258 +-- truncate_limit: 100 +INSERT INTO s2 (SELECT x, public.fipshash(x::text) FROM generate_series(-6,6) x) +-- +TABLE: name="s2" schema="" table="s2" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO s2 SELECT x, public.fipshash(x::text) FROM generate_series(-6, 6) x" +== 259 +-- truncate_limit: 100 +GRANT SELECT ON s1, s2 TO regress_rls_bob +-- +TABLE: name="s1" schema="" table="s1" ctx=DDL +TABLE: name="s2" schema="" table="s2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON s1, s2 TO regress_rls_bob" +== 260 +-- truncate_limit: 100 +CREATE POLICY p1 ON s1 USING (a in (select x from s2 where y like '%2f%')) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON s1 TO public USING (a IN (SELECT x FROM s2 WHERE y LIKE '%2f%'))" +== 261 +-- truncate_limit: 100 +CREATE POLICY p2 ON s2 USING (x in (select a from s1 where b like '%22%')) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON s2 TO public USING (x IN (SELECT a FROM s1 WHERE b LIKE '%22%'))" +== 262 +-- truncate_limit: 100 +CREATE POLICY p3 ON s1 FOR INSERT WITH CHECK (a = (SELECT a FROM s1)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3 ON s1 FOR INSERT TO public WITH CHECK (a = (SELECT a FROM s1))" +== 263 +-- truncate_limit: 100 +ALTER TABLE s1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="s1" schema="" table="s1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE s1 ENABLE ROW LEVEL SECURITY" +== 264 +-- truncate_limit: 100 +ALTER TABLE s2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="s2" schema="" table="s2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE s2 ENABLE ROW LEVEL SECURITY" +== 265 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 266 +-- truncate_limit: 100 +CREATE VIEW v2 AS SELECT * FROM s2 WHERE y like '%af%' +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="s2" schema="" table="s2" ctx=Select +FILTER: schema="" table="" column="y" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v2 AS SELECT * FROM s2 WHERE y LIKE '%af%'" +== 267 +-- truncate_limit: 100 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM s1 WHERE f_leak(b)" +== 268 +-- truncate_limit: 100 +-- fail (infinite recursion) + +INSERT INTO s1 VALUES (1, 'foo') +-- +TABLE: name="s1" schema="" table="s1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO s1 VALUES (1, 'foo')" +== 269 +-- truncate_limit: 100 +-- fail (infinite recursion) + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 270 +-- truncate_limit: 100 +DROP POLICY p3 on s1 +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p3 ON s1" +== 271 +-- truncate_limit: 100 +ALTER POLICY p2 ON s2 USING (x % 2 = 0) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY p2 ON s2 USING ((x % 2) = 0)" +== 272 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 273 +-- truncate_limit: 100 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM s1 WHERE f_leak(b)" +== 274 +-- truncate_limit: 100 +-- OK +EXPLAIN (COSTS OFF) SELECT * FROM only s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM ONLY s1 WHERE f_leak(b)" +== 275 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 276 +-- truncate_limit: 100 +ALTER POLICY p1 ON s1 USING (a in (select x from v2)) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY p1 ON s1 USING (a IN (SELECT x FROM v2))" +== 277 +-- truncate_limit: 100 +-- using VIEW in RLS policy +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 278 +-- truncate_limit: 100 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM s1 WHERE f_leak(b)" +== 279 +-- truncate_limit: 100 +-- OK +EXPLAIN (COSTS OFF) SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM s1 WHERE f_leak(b)" +== 280 +-- truncate_limit: 100 +SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%' +-- +TABLE: name="s2" schema="" table="s2" ctx=Select +TABLE: name="s1" schema="" table="s1" ctx=Select +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT x FROM s1 LIMIT 1) AS xx, * FROM s2 WHERE y LIKE '%28%'" +== 281 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%' +-- +TABLE: name="s2" schema="" table="s2" ctx=Select +TABLE: name="s1" schema="" table="s1" ctx=Select +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT (SELECT x FROM s1 LIMIT 1) AS xx, * FROM s2 WHERE y LIKE '%28%'" +== 282 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 283 +-- truncate_limit: 100 +ALTER POLICY p2 ON s2 USING (x in (select a from s1 where b like '%d2%')) +-- +STMT: AlterPolicyStmt +TRUNCATED: "ALTER POLICY p2 ON s2 USING (x IN (SELECT a FROM s1 WHERE b LIKE '%d2%'))" +== 284 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 285 +-- truncate_limit: 100 +SELECT * FROM s1 WHERE f_leak(b) +-- +TABLE: name="s1" schema="" table="s1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM s1 WHERE f_leak(b)" +== 286 +-- truncate_limit: 100 +-- fail (infinite recursion via view) + +-- prepared statement with regress_rls_alice privilege +PREPARE p1(int) AS SELECT * FROM t1 WHERE a <= $1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE p1(int) AS SELECT * FROM t1 WHERE a <= $1" +== 287 +-- truncate_limit: 100 +EXECUTE p1(2) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p1(2)" +== 288 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE p1(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE p1(2)" +== 289 +-- truncate_limit: 100 +-- superuser is allowed to bypass RLS checks +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 290 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 291 +-- truncate_limit: 100 +SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 WHERE f_leak(b)" +== 292 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b)" +== 293 +-- truncate_limit: 100 +-- plan cache should be invalidated +EXECUTE p1(2) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p1(2)" +== 294 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE p1(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE p1(2)" +== 295 +-- truncate_limit: 100 +PREPARE p2(int) AS SELECT * FROM t1 WHERE a = $1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE p2(int) AS SELECT * FROM t1 WHERE a = $1" +== 296 +-- truncate_limit: 100 +EXECUTE p2(2) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p2(2)" +== 297 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE p2(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE p2(2)" +== 298 +-- truncate_limit: 100 +-- also, case when privilege switch from superuser +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 299 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 300 +-- truncate_limit: 100 +EXECUTE p2(2) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p2(2)" +== 301 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE p2(2) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE p2(2)" +== 302 +-- truncate_limit: 100 +|-- +-- UPDATE / DELETE and Row-level security +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 303 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) UPDATE t1 SET b = b || b WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE t1 SET b = b || b WHERE f_leak(b)" +== 304 +-- truncate_limit: 100 +UPDATE t1 SET b = b || b WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t1 SET b = b || b WHERE f_leak(b)" +== 305 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE ONLY t1 SET b = b || '_updt' WHERE f_leak(b)" +== 306 +-- truncate_limit: 100 +UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE ONLY t1 SET b = b || '_updt' WHERE f_leak(b)" +== 307 +-- truncate_limit: 100 +-- returning clause with system column +UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE ONLY t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1" +== 308 +-- truncate_limit: 100 +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING * +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t1 SET b = b WHERE f_leak(b) RETURNING *" +== 309 +-- truncate_limit: 100 +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1" +== 310 +-- truncate_limit: 100 +-- updates with from clause +EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t3 +WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t3" schema="" table="t3" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE t2 SET b = t2.b FROM t3 WHERE t2.a = 3 AND t3.a = 2 AND f_leak(t2.b) A..." +== 311 +-- truncate_limit: 100 +UPDATE t2 SET b=t2.b FROM t3 +WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t3" schema="" table="t3" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t2 SET b = t2.b FROM t3 WHERE t2.a = 3 AND t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b)" +== 312 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) UPDATE t1 SET b=t1.b FROM t2 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE t1 SET b = t1.b FROM t2 WHERE t1.a = 3 AND t2.a = 3 AND f_leak(t1.b) A..." +== 313 +-- truncate_limit: 100 +UPDATE t1 SET b=t1.b FROM t2 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t1 SET b = t1.b FROM t2 WHERE t1.a = 3 AND t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b)" +== 314 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t1 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE t2 SET b = t2.b FROM t1 WHERE t1.a = 3 AND t2.a = 3 AND f_leak(t1.b) A..." +== 315 +-- truncate_limit: 100 +UPDATE t2 SET b=t2.b FROM t1 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t2 SET b = t2.b FROM t1 WHERE t1.a = 3 AND t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b)" +== 316 +-- truncate_limit: 100 +-- updates with from clause self join +EXPLAIN (COSTS OFF) UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 +WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b +AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "t2_1"="t2" +ALIAS: "t2_2"="t2" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 WHERE t2_1.a = 3 AND t2_2.a = t2_1..." +== 317 +-- truncate_limit: 100 +UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 +WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b +AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t2" schema="" table="t2" ctx=Select +ALIAS: "t2_1"="t2" +ALIAS: "t2_2"="t2" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 WHERE ... RETURNING *, t2_1, t2_2" +== 318 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 +WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b +AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "t1_1"="t1" +ALIAS: "t1_2"="t1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 WHERE t1_1.a = 4 AND t1_2.a = t1_1..." +== 319 +-- truncate_limit: 100 +UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 +WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b +AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "t1_1"="t1" +ALIAS: "t1_2"="t1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 WHERE ... RETURNING *, t1_1, t1_2" +== 320 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 321 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 322 +-- truncate_limit: 100 +SELECT * FROM t1 ORDER BY a,b +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 ORDER BY a, b" +== 323 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 324 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 325 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) DELETE FROM only t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM ONLY t1 WHERE f_leak(b)" +== 326 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b)" +== 327 +-- truncate_limit: 100 +DELETE FROM only t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ONLY t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1" +== 328 +-- truncate_limit: 100 +DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1" +== 329 +-- truncate_limit: 100 +|-- +-- S.b. view on top of Row-level security +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 330 +-- truncate_limit: 100 +CREATE TABLE b1 (a int, b text) +-- +TABLE: name="b1" schema="" table="b1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE b1 (a int, b text)" +== 331 +-- truncate_limit: 100 +INSERT INTO b1 (SELECT x, public.fipshash(x::text) FROM generate_series(-10,10) x) +-- +TABLE: name="b1" schema="" table="b1" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO b1 SELECT x, public.fipshash(x::text) FROM generate_series(-10, 10) x" +== 332 +-- truncate_limit: 100 +CREATE POLICY p1 ON b1 USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON b1 TO public USING ((a % 2) = 0)" +== 333 +-- truncate_limit: 100 +ALTER TABLE b1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="b1" schema="" table="b1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE b1 ENABLE ROW LEVEL SECURITY" +== 334 +-- truncate_limit: 100 +GRANT ALL ON b1 TO regress_rls_bob +-- +TABLE: name="b1" schema="" table="b1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON b1 TO regress_rls_bob" +== 335 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 336 +-- truncate_limit: 100 +CREATE VIEW bv1 WITH (security_barrier) AS SELECT * FROM b1 WHERE a > 0 WITH CHECK OPTION +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DDL +TABLE: name="b1" schema="" table="b1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW bv1 WITH (security_barrier) AS SELECT * FROM b1 WHERE a > 0 WITH CHECK OPTION" +== 337 +-- truncate_limit: 100 +GRANT ALL ON bv1 TO regress_rls_carol +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON bv1 TO regress_rls_carol" +== 338 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 339 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM bv1 WHERE f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM bv1 WHERE f_leak(b)" +== 340 +-- truncate_limit: 100 +SELECT * FROM bv1 WHERE f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bv1 WHERE f_leak(b)" +== 341 +-- truncate_limit: 100 +INSERT INTO bv1 VALUES (-1, 'xxx') +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bv1 VALUES (-1, 'xxx')" +== 342 +-- truncate_limit: 100 +-- should fail view WCO +INSERT INTO bv1 VALUES (11, 'xxx') +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bv1 VALUES (11, 'xxx')" +== 343 +-- truncate_limit: 100 +-- should fail RLS check +INSERT INTO bv1 VALUES (12, 'xxx') +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bv1 VALUES (12, 'xxx')" +== 344 +-- truncate_limit: 100 +-- ok + +EXPLAIN (COSTS OFF) UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b)" +== 345 +-- truncate_limit: 100 +UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b)" +== 346 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) DELETE FROM bv1 WHERE a = 6 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM bv1 WHERE a = 6 AND f_leak(b)" +== 347 +-- truncate_limit: 100 +DELETE FROM bv1 WHERE a = 6 AND f_leak(b) +-- +TABLE: name="bv1" schema="" table="bv1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM bv1 WHERE a = 6 AND f_leak(b)" +== 348 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 349 +-- truncate_limit: 100 +SELECT * FROM b1 +-- +TABLE: name="b1" schema="" table="b1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM b1" +== 350 +-- truncate_limit: 100 +|-- +-- INSERT ... ON CONFLICT DO UPDATE and Row-level security +|-- + +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 351 +-- truncate_limit: 100 +DROP POLICY p1 ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p1 ON document" +== 352 +-- truncate_limit: 100 +DROP POLICY p1r ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p1r ON document" +== 353 +-- truncate_limit: 100 +CREATE POLICY p1 ON document FOR SELECT USING (true) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON document FOR SELECT TO public USING (true)" +== 354 +-- truncate_limit: 100 +CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON document FOR INSERT TO public WITH CHECK (dauthor = current_user)" +== 355 +-- truncate_limit: 100 +CREATE POLICY p3 ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3 ON document FOR UPDATE TO public USING (cid = (SELECT cid FROM category WHERE cn..." +== 356 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 357 +-- truncate_limit: 100 +-- Exists... +SELECT * FROM document WHERE did = 2 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE did = 2" +== 358 +-- truncate_limit: 100 +-- ...so violates actual WITH CHECK OPTION within UPDATE (not INSERT, since +-- alternative UPDATE path happens to be taken): +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_carol', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, dauthor = EXCLUDED.dauthor +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ..." +== 359 +-- truncate_limit: 100 +-- Violates USING qual for UPDATE policy p3. +|-- +-- UPDATE path is taken, but UPDATE fails purely because *existing* row to be +-- updated is not a "novel"/cid 11 (row is not leaked, even though we have +-- SELECT privileges sufficient to see the row in this instance): +INSERT INTO document VALUES (33, 22, 1, 'regress_rls_bob', 'okay science fiction') +-- +TABLE: name="document" schema="" table="document" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (33, 22, 1, 'regress_rls_bob', 'okay science fiction')" +== 360 +-- truncate_limit: 100 +-- preparation for next statement +INSERT INTO document VALUES (33, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'Some novel, replaces sci-fi') -- takes UPDATE path + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET dtitle = excluded.dtitle" +== 361 +-- truncate_limit: 100 +-- Fine (we UPDATE, since INSERT WCOs and UPDATE security barrier quals + WCOs +-- not violated): +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 362 +-- truncate_limit: 100 +-- Fine (we INSERT, so "cid = 33" ("technology") isn't evaluated): +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 363 +-- truncate_limit: 100 +-- Fine (same query, but we UPDATE, so "cid = 33", ("technology") is not the +-- case in respect of *existing* tuple): +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 364 +-- truncate_limit: 100 +-- Same query a third time, but now fails due to existing tuple finally not +-- passing quals: +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 365 +-- truncate_limit: 100 +-- Don't fail just because INSERT doesn't satisfy WITH CHECK option that +-- originated as a barrier/USING() qual from the UPDATE. Note that the UPDATE +-- path *isn't* taken, and so UPDATE-related policy does not apply: +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 366 +-- truncate_limit: 100 +-- But this time, the same statement fails, because the UPDATE path is taken, +-- and updating the row just inserted falls afoul of security barrier qual +-- (enforced as WCO) -- what we might have updated target tuple to is +-- irrelevant, in fact. +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 367 +-- truncate_limit: 100 +-- Test default USING qual enforced as WCO +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 368 +-- truncate_limit: 100 +DROP POLICY p1 ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p1 ON document" +== 369 +-- truncate_limit: 100 +DROP POLICY p2 ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p2 ON document" +== 370 +-- truncate_limit: 100 +DROP POLICY p3 ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p3 ON document" +== 371 +-- truncate_limit: 100 +CREATE POLICY p3_with_default ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3_with_default ON document FOR UPDATE TO public USING (cid = (SELECT cid FROM cate..." +== 372 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 373 +-- truncate_limit: 100 +-- Just because WCO-style enforcement of USING quals occurs with +-- existing/target tuple does not mean that the implementation can be allowed +-- to fail to also enforce this qual against the final tuple appended to +-- relation (since in the absence of an explicit WCO, this is also interpreted +-- as an UPDATE/ALL WCO in general). +|-- +-- UPDATE path is taken here (fails due to existing tuple). Note that this is +-- not reported as a "USING expression", because it's an RLS UPDATE check that originated as +-- a USING qual for the purposes of RLS in general, as opposed to an explicit +-- USING qual that is ordinarily a security barrier. We leave it up to the +-- UPDATE to make this fail: +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 374 +-- truncate_limit: 100 +-- UPDATE path is taken here. Existing tuple passes, since its cid +-- corresponds to "novel", but default USING qual is enforced against +-- post-UPDATE tuple too (as always when updating with a policy that lacks an +-- explicit WCO), and so this fails: +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET cid = EXCLUDED.cid, dtitle = EXCLUDED.dtitle RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET ... = ... RETURNING *" +== 375 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 376 +-- truncate_limit: 100 +DROP POLICY p3_with_default ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p3_with_default ON document" +== 377 +-- truncate_limit: 100 +|-- +-- Test ALL policies with ON CONFLICT DO UPDATE (much the same as existing UPDATE +-- tests) +|-- +CREATE POLICY p3_with_all ON document FOR ALL + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3_with_all ON document TO public USING (cid = (SELECT cid FROM category WHERE cnam..." +== 378 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 379 +-- truncate_limit: 100 +-- Fails, since ALL WCO is enforced in insert path: +INSERT INTO document VALUES (80, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_carol', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET dtitle = excluded.dtitle, cid = 33" +== 380 +-- truncate_limit: 100 +-- Fails, since ALL policy USING qual is enforced (existing, target tuple is in +-- violation, since it has the "manga" cid): +INSERT INTO document VALUES (4, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET dtitle = excluded.dtitle" +== 381 +-- truncate_limit: 100 +-- Fails, since ALL WCO are enforced: +INSERT INTO document VALUES (1, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dauthor = 'regress_rls_carol' +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +FILTER: schema="" table="" column="cname" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO document VALUES (...) ON CONFLICT (did) DO UPDATE SET dauthor = 'regress_rls_carol'" +== 382 +-- truncate_limit: 100 +|-- +-- MERGE +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 383 +-- truncate_limit: 100 +DROP POLICY p3_with_all ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p3_with_all ON document" +== 384 +-- truncate_limit: 100 +ALTER TABLE document ADD COLUMN dnotes text DEFAULT '' +-- +TABLE: name="document" schema="" table="document" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE document ADD COLUMN dnotes text DEFAULT ''" +== 385 +-- truncate_limit: 100 +-- all documents are readable +CREATE POLICY p1 ON document FOR SELECT USING (true) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON document FOR SELECT TO public USING (true)" +== 386 +-- truncate_limit: 100 +-- one may insert documents only authored by them +CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON document FOR INSERT TO public WITH CHECK (dauthor = current_user)" +== 387 +-- truncate_limit: 100 +-- one may only update documents in 'novel' category and new dlevel must be > 0 +CREATE POLICY p3 ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dlevel > 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3 ON document FOR UPDATE TO public USING (cid = (SELECT cid FROM category WHERE cn..." +== 388 +-- truncate_limit: 100 +-- one may only delete documents in 'manga' category +CREATE POLICY p4 ON document FOR DELETE + USING (cid = (SELECT cid from category WHERE cname = 'manga')) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p4 ON document FOR DELETE TO public USING (cid = (SELECT cid FROM category WHERE cn..." +== 389 +-- truncate_limit: 100 +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document" +== 390 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 391 +-- truncate_limit: 100 +-- Fails, since update violates WITH CHECK qual on dlevel +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge1 ', dlevel = 0 +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 392 +-- truncate_limit: 100 +-- Should be OK since USING and WITH CHECK quals pass +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge2 ' +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 393 +-- truncate_limit: 100 +-- Even when dlevel is updated explicitly, but to the existing value +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge3 ', dlevel = 1 +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 394 +-- truncate_limit: 100 +-- There is a MATCH for did = 3, but UPDATE's USING qual does not allow +-- updating an item in category 'science fiction' +MERGE INTO document d +USING (SELECT 3 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 395 +-- truncate_limit: 100 +-- The same thing with DELETE action, but fails again because no permissions +-- to delete items in 'science fiction' category that did 3 belongs to. +MERGE INTO document d +USING (SELECT 3 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT 3 AS sdid) s ON did = s.sdid WHEN MATCHED THEN DELETE" +== 396 +-- truncate_limit: 100 +-- Document with did 4 belongs to 'manga' category which is allowed for +-- deletion. But this fails because the UPDATE action is matched first and +-- UPDATE policy does not allow updation in the category. +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes = '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED AND dnotes = '' THEN UPDA..." +== 397 +-- truncate_limit: 100 +-- UPDATE action is not matched this time because of the WHEN qual. +-- DELETE still fails because role regress_rls_bob does not have SELECT +-- privileges on 'manga' category row in the category table. +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes <> '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED AND dnotes <> '' THEN UPD..." +== 398 +-- truncate_limit: 100 +-- OK if DELETE is replaced with DO NOTHING +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes <> '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DO NOTHING +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED AND dnotes <> '' THEN UPD..." +== 399 +-- truncate_limit: 100 +SELECT * FROM document WHERE did = 4 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE did = 4" +== 400 +-- truncate_limit: 100 +-- Switch to regress_rls_carol role and try the DELETE again. It should succeed +-- this time +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 401 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 402 +-- truncate_limit: 100 +MERGE INTO document d +USING (SELECT 4 as sdid) s +ON did = s.sdid +WHEN MATCHED AND dnotes <> '' THEN + UPDATE SET dnotes = dnotes || ' notes added by merge ' +WHEN MATCHED THEN + DELETE +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED AND dnotes <> '' THEN UPD..." +== 403 +-- truncate_limit: 100 +-- Switch back to regress_rls_bob role +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 404 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 405 +-- truncate_limit: 100 +-- Try INSERT action. This fails because we are trying to insert +-- dauthor = regress_rls_dave and INSERT's WITH CHECK does not allow +-- that +MERGE INTO document d +USING (SELECT 12 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + DELETE +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_dave', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN DELETE WHEN NOT MATC..." +== 406 +-- truncate_limit: 100 +-- This should be fine +MERGE INTO document d +USING (SELECT 12 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + DELETE +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN DELETE WHEN NOT MATC..." +== 407 +-- truncate_limit: 100 +-- ok +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge4 ' +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 408 +-- truncate_limit: 100 +-- drop and create a new SELECT policy which prevents us from reading +-- any document except with category 'novel' +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 409 +-- truncate_limit: 100 +DROP POLICY p1 ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p1 ON document" +== 410 +-- truncate_limit: 100 +CREATE POLICY p1 ON document FOR SELECT + USING (cid = (SELECT cid from category WHERE cname = 'novel')) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON document FOR SELECT TO public USING (cid = (SELECT cid FROM category WHERE cn..." +== 411 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 412 +-- truncate_limit: 100 +-- MERGE can no longer see the matching row and hence attempts the +-- NOT MATCHED action, which results in unique key violation +MERGE INTO document d +USING (SELECT 7 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge5 ' +WHEN NOT MATCHED THEN + INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 413 +-- truncate_limit: 100 +-- UPDATE action fails if new row is not visible +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge6 ', + cid = (SELECT cid from category WHERE cname = 'technology') +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "d"="document" +FILTER: schema="" table="" column="cname" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 414 +-- truncate_limit: 100 +-- but OK if new row is visible +MERGE INTO document d +USING (SELECT 1 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge7 ', + cid = (SELECT cid from category WHERE cname = 'novel') +-- +TABLE: name="document" schema="" table="document" ctx=DML +TABLE: name="category" schema="" table="category" ctx=Select +ALIAS: "d"="document" +FILTER: schema="" table="" column="cname" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 415 +-- truncate_limit: 100 +-- OK to insert a new row that is not visible +MERGE INTO document d +USING (SELECT 13 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge8 ' +WHEN NOT MATCHED THEN + INSERT VALUES (13, 44, 1, 'regress_rls_bob', 'new manga') +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 416 +-- truncate_limit: 100 +SELECT * FROM document WHERE did = 13 +-- +TABLE: name="document" schema="" table="document" ctx=Select +FILTER: schema="" table="" column="did" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document WHERE did = 13" +== 417 +-- truncate_limit: 100 +-- but not OK if RETURNING is used +MERGE INTO document d +USING (SELECT 14 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge9 ' +WHEN NOT MATCHED THEN + INSERT VALUES (14, 44, 1, 'regress_rls_bob', 'new manga') +RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 418 +-- truncate_limit: 100 +-- but OK if new row is visible +MERGE INTO document d +USING (SELECT 14 as sdid) s +ON did = s.sdid +WHEN MATCHED THEN + UPDATE SET dnotes = dnotes || ' notes added by merge10 ' +WHEN NOT MATCHED THEN + INSERT VALUES (14, 11, 1, 'regress_rls_bob', 'new novel') +RETURNING * +-- +TABLE: name="document" schema="" table="document" ctx=DML +ALIAS: "d"="document" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO document d USING (SELECT ...) s ON did = s.sdid WHEN MATCHED THEN UPDATE SET dnotes = ..." +== 419 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 420 +-- truncate_limit: 100 +-- drop the restrictive SELECT policy so that we can look at the +-- final state of the table +DROP POLICY p1 ON document +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p1 ON document" +== 421 +-- truncate_limit: 100 +-- Just check everything went per plan +SELECT * FROM document +-- +TABLE: name="document" schema="" table="document" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM document" +== 422 +-- truncate_limit: 100 +|-- +-- ROLE/GROUP +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 423 +-- truncate_limit: 100 +CREATE TABLE z1 (a int, b text) +-- +TABLE: name="z1" schema="" table="z1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE z1 (a int, b text)" +== 424 +-- truncate_limit: 100 +CREATE TABLE z2 (a int, b text) +-- +TABLE: name="z2" schema="" table="z2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE z2 (a int, b text)" +== 425 +-- truncate_limit: 100 +GRANT SELECT ON z1,z2 TO regress_rls_group1, regress_rls_group2, + regress_rls_bob, regress_rls_carol +-- +TABLE: name="z1" schema="" table="z1" ctx=DDL +TABLE: name="z2" schema="" table="z2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON z1, z2 TO regress_rls_group1, regress_rls_group2, regress_rls_bob, regress_rls_carol" +== 426 +-- truncate_limit: 100 +INSERT INTO z1 VALUES + (1, 'aba'), + (2, 'bbb'), + (3, 'ccc'), + (4, 'dad') +-- +TABLE: name="z1" schema="" table="z1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO z1 VALUES (1, 'aba'), (2, 'bbb'), (3, 'ccc'), (4, 'dad')" +== 427 +-- truncate_limit: 100 +CREATE POLICY p1 ON z1 TO regress_rls_group1 USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON z1 TO regress_rls_group1 USING ((a % 2) = 0)" +== 428 +-- truncate_limit: 100 +CREATE POLICY p2 ON z1 TO regress_rls_group2 USING (a % 2 = 1) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON z1 TO regress_rls_group2 USING ((a % 2) = 1)" +== 429 +-- truncate_limit: 100 +ALTER TABLE z1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="z1" schema="" table="z1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE z1 ENABLE ROW LEVEL SECURITY" +== 430 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 431 +-- truncate_limit: 100 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM z1 WHERE f_leak(b)" +== 432 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b)" +== 433 +-- truncate_limit: 100 +PREPARE plancache_test AS SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE plancache_test AS SELECT * FROM z1 WHERE f_leak(b)" +== 434 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test" +== 435 +-- truncate_limit: 100 +PREPARE plancache_test2 AS WITH q AS MATERIALIZED (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2 +-- +TABLE: name="z2" schema="" table="z2" ctx=Select +TABLE: name="z1" schema="" table="z1" ctx=Select +CTE: "q" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE plancache_test2 AS WITH q AS MATERIALIZED (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FRO..." +== 436 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test2" +== 437 +-- truncate_limit: 100 +PREPARE plancache_test3 AS WITH q AS MATERIALIZED (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +TABLE: name="z2" schema="" table="z2" ctx=Select +CTE: "q" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="z1" column="b" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE plancache_test3 AS WITH q AS MATERIALIZED (SELECT * FROM z2) SELECT * FROM q, z1 WHERE f_..." +== 438 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test3" +== 439 +-- truncate_limit: 100 +SET ROLE regress_rls_group1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rls_group1" +== 440 +-- truncate_limit: 100 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM z1 WHERE f_leak(b)" +== 441 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b)" +== 442 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test" +== 443 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test2" +== 444 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test3" +== 445 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 446 +-- truncate_limit: 100 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM z1 WHERE f_leak(b)" +== 447 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b)" +== 448 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test" +== 449 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test2" +== 450 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test3" +== 451 +-- truncate_limit: 100 +SET ROLE regress_rls_group2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rls_group2" +== 452 +-- truncate_limit: 100 +SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM z1 WHERE f_leak(b)" +== 453 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b)" +== 454 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test" +== 455 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test2 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test2" +== 456 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE plancache_test3 +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE plancache_test3" +== 457 +-- truncate_limit: 100 +|-- +-- Views should follow policy for view owner. +|-- +-- View and Table owner are the same. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 458 +-- truncate_limit: 100 +CREATE VIEW rls_view AS SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rls_view AS SELECT * FROM z1 WHERE f_leak(b)" +== 459 +-- truncate_limit: 100 +GRANT SELECT ON rls_view TO regress_rls_bob +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rls_view TO regress_rls_bob" +== 460 +-- truncate_limit: 100 +-- Query as role that is not owner of view or table. Should return all records. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 461 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 462 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 463 +-- truncate_limit: 100 +-- Query as view/table owner. Should return all records. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 464 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 465 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 466 +-- truncate_limit: 100 +DROP VIEW rls_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rls_view" +== 467 +-- truncate_limit: 100 +-- View and Table owners are different. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 468 +-- truncate_limit: 100 +CREATE VIEW rls_view AS SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rls_view AS SELECT * FROM z1 WHERE f_leak(b)" +== 469 +-- truncate_limit: 100 +GRANT SELECT ON rls_view TO regress_rls_alice +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rls_view TO regress_rls_alice" +== 470 +-- truncate_limit: 100 +-- Query as role that is not owner of view but is owner of table. +-- Should return records based on view owner policies. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 471 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 472 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 473 +-- truncate_limit: 100 +-- Query as role that is not owner of table but is owner of view. +-- Should return records based on view owner policies. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 474 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 475 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 476 +-- truncate_limit: 100 +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 477 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 478 +-- truncate_limit: 100 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 479 +-- truncate_limit: 100 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 480 +-- truncate_limit: 100 +GRANT SELECT ON rls_view TO regress_rls_carol +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rls_view TO regress_rls_carol" +== 481 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 482 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 483 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 484 +-- truncate_limit: 100 +-- Policy requiring access to another table. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 485 +-- truncate_limit: 100 +CREATE TABLE z1_blacklist (a int) +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE z1_blacklist (a int)" +== 486 +-- truncate_limit: 100 +INSERT INTO z1_blacklist VALUES (3), (4) +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO z1_blacklist VALUES (3), (4)" +== 487 +-- truncate_limit: 100 +CREATE POLICY p3 ON z1 AS RESTRICTIVE USING (a NOT IN (SELECT a FROM z1_blacklist)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3 ON z1 AS RESTRICTIVE TO public USING (NOT a IN (SELECT a FROM z1_blacklist))" +== 488 +-- truncate_limit: 100 +-- Query as role that is not owner of table but is owner of view without permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 489 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 490 +-- truncate_limit: 100 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 491 +-- truncate_limit: 100 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 492 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 493 +-- truncate_limit: 100 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 494 +-- truncate_limit: 100 +--fail - permission denied. + +-- Query as role that is not owner of table but is owner of view with permissions. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 495 +-- truncate_limit: 100 +GRANT SELECT ON z1_blacklist TO regress_rls_bob +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON z1_blacklist TO regress_rls_bob" +== 496 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 497 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 498 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 499 +-- truncate_limit: 100 +-- Query as role that is not the owner of the table or view with permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 500 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 501 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 502 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 503 +-- truncate_limit: 100 +REVOKE SELECT ON z1_blacklist FROM regress_rls_bob +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select ON z1_blacklist FROM regress_rls_bob" +== 504 +-- truncate_limit: 100 +DROP POLICY p3 ON z1 +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p3 ON z1" +== 505 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 506 +-- truncate_limit: 100 +DROP VIEW rls_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rls_view" +== 507 +-- truncate_limit: 100 +|-- +-- Security invoker views should follow policy for current user. +|-- +-- View and table owner are the same. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 508 +-- truncate_limit: 100 +CREATE VIEW rls_view WITH (security_invoker) AS + SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rls_view WITH (security_invoker) AS SELECT * FROM z1 WHERE f_leak(b)" +== 509 +-- truncate_limit: 100 +GRANT SELECT ON rls_view TO regress_rls_bob +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rls_view TO regress_rls_bob" +== 510 +-- truncate_limit: 100 +GRANT SELECT ON rls_view TO regress_rls_carol +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rls_view TO regress_rls_carol" +== 511 +-- truncate_limit: 100 +-- Query as table owner. Should return all records. +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 512 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 513 +-- truncate_limit: 100 +-- Queries as other users. +-- Should return records based on current user's policies. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 514 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 515 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 516 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 517 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 518 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 519 +-- truncate_limit: 100 +-- View and table owners are different. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 520 +-- truncate_limit: 100 +DROP VIEW rls_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rls_view" +== 521 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 522 +-- truncate_limit: 100 +CREATE VIEW rls_view WITH (security_invoker) AS + SELECT * FROM z1 WHERE f_leak(b) +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +TABLE: name="z1" schema="" table="z1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rls_view WITH (security_invoker) AS SELECT * FROM z1 WHERE f_leak(b)" +== 523 +-- truncate_limit: 100 +GRANT SELECT ON rls_view TO regress_rls_alice +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rls_view TO regress_rls_alice" +== 524 +-- truncate_limit: 100 +GRANT SELECT ON rls_view TO regress_rls_carol +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rls_view TO regress_rls_carol" +== 525 +-- truncate_limit: 100 +-- Query as table owner. Should return all records. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 526 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 527 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 528 +-- truncate_limit: 100 +-- Queries as other users. +-- Should return records based on current user's policies. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 529 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 530 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 531 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 532 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 533 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 534 +-- truncate_limit: 100 +-- Policy requiring access to another table. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 535 +-- truncate_limit: 100 +CREATE POLICY p3 ON z1 AS RESTRICTIVE USING (a NOT IN (SELECT a FROM z1_blacklist)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3 ON z1 AS RESTRICTIVE TO public USING (NOT a IN (SELECT a FROM z1_blacklist))" +== 536 +-- truncate_limit: 100 +-- Query as role that is not owner of table but is owner of view without permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 537 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 538 +-- truncate_limit: 100 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 539 +-- truncate_limit: 100 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 540 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 541 +-- truncate_limit: 100 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 542 +-- truncate_limit: 100 +--fail - permission denied. + +-- Query as role that is not owner of table but is owner of view with permissions. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 543 +-- truncate_limit: 100 +GRANT SELECT ON z1_blacklist TO regress_rls_bob +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON z1_blacklist TO regress_rls_bob" +== 544 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 545 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 546 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 547 +-- truncate_limit: 100 +-- Query as role that is not the owner of the table or view without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 548 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 549 +-- truncate_limit: 100 +--fail - permission denied. +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 550 +-- truncate_limit: 100 +--fail - permission denied. + +-- Query as role that is not the owner of the table or view with permissions. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 551 +-- truncate_limit: 100 +GRANT SELECT ON z1_blacklist TO regress_rls_carol +-- +TABLE: name="z1_blacklist" schema="" table="z1_blacklist" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON z1_blacklist TO regress_rls_carol" +== 552 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 553 +-- truncate_limit: 100 +SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rls_view" +== 554 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_view +-- +TABLE: name="rls_view" schema="" table="rls_view" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_view" +== 555 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 556 +-- truncate_limit: 100 +DROP VIEW rls_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rls_view" +== 557 +-- truncate_limit: 100 +|-- +-- Command specific +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 558 +-- truncate_limit: 100 +CREATE TABLE x1 (a int, b text, c text) +-- +TABLE: name="x1" schema="" table="x1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE x1 (a int, b text, c text)" +== 559 +-- truncate_limit: 100 +GRANT ALL ON x1 TO PUBLIC +-- +TABLE: name="x1" schema="" table="x1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON x1 TO public" +== 560 +-- truncate_limit: 100 +INSERT INTO x1 VALUES + (1, 'abc', 'regress_rls_bob'), + (2, 'bcd', 'regress_rls_bob'), + (3, 'cde', 'regress_rls_carol'), + (4, 'def', 'regress_rls_carol'), + (5, 'efg', 'regress_rls_bob'), + (6, 'fgh', 'regress_rls_bob'), + (7, 'fgh', 'regress_rls_carol'), + (8, 'fgh', 'regress_rls_carol') +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO x1 VALUES (...)" +== 561 +-- truncate_limit: 100 +CREATE POLICY p0 ON x1 FOR ALL USING (c = current_user) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p0 ON x1 TO public USING (c = current_user)" +== 562 +-- truncate_limit: 100 +CREATE POLICY p1 ON x1 FOR SELECT USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON x1 FOR SELECT TO public USING ((a % 2) = 0)" +== 563 +-- truncate_limit: 100 +CREATE POLICY p2 ON x1 FOR INSERT WITH CHECK (a % 2 = 1) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON x1 FOR INSERT TO public WITH CHECK ((a % 2) = 1)" +== 564 +-- truncate_limit: 100 +CREATE POLICY p3 ON x1 FOR UPDATE USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3 ON x1 FOR UPDATE TO public USING ((a % 2) = 0)" +== 565 +-- truncate_limit: 100 +CREATE POLICY p4 ON x1 FOR DELETE USING (a < 8) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p4 ON x1 FOR DELETE TO public USING (a < 8)" +== 566 +-- truncate_limit: 100 +ALTER TABLE x1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="x1" schema="" table="x1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE x1 ENABLE ROW LEVEL SECURITY" +== 567 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 568 +-- truncate_limit: 100 +SELECT * FROM x1 WHERE f_leak(b) ORDER BY a ASC +-- +TABLE: name="x1" schema="" table="x1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x1 WHERE f_leak(b) ORDER BY a ASC" +== 569 +-- truncate_limit: 100 +UPDATE x1 SET b = b || '_updt' WHERE f_leak(b) RETURNING * +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE x1 SET b = b || '_updt' WHERE f_leak(b) RETURNING *" +== 570 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 571 +-- truncate_limit: 100 +SELECT * FROM x1 WHERE f_leak(b) ORDER BY a ASC +-- +TABLE: name="x1" schema="" table="x1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM x1 WHERE f_leak(b) ORDER BY a ASC" +== 572 +-- truncate_limit: 100 +UPDATE x1 SET b = b || '_updt' WHERE f_leak(b) RETURNING * +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE x1 SET b = b || '_updt' WHERE f_leak(b) RETURNING *" +== 573 +-- truncate_limit: 100 +DELETE FROM x1 WHERE f_leak(b) RETURNING * +-- +TABLE: name="x1" schema="" table="x1" ctx=DML +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM x1 WHERE f_leak(b) RETURNING *" +== 574 +-- truncate_limit: 100 +|-- +-- Duplicate Policy Names +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 575 +-- truncate_limit: 100 +CREATE TABLE y1 (a int, b text) +-- +TABLE: name="y1" schema="" table="y1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE y1 (a int, b text)" +== 576 +-- truncate_limit: 100 +CREATE TABLE y2 (a int, b text) +-- +TABLE: name="y2" schema="" table="y2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE y2 (a int, b text)" +== 577 +-- truncate_limit: 100 +GRANT ALL ON y1, y2 TO regress_rls_bob +-- +TABLE: name="y1" schema="" table="y1" ctx=DDL +TABLE: name="y2" schema="" table="y2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON y1, y2 TO regress_rls_bob" +== 578 +-- truncate_limit: 100 +CREATE POLICY p1 ON y1 FOR ALL USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON y1 TO public USING ((a % 2) = 0)" +== 579 +-- truncate_limit: 100 +CREATE POLICY p2 ON y1 FOR SELECT USING (a > 2) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON y1 FOR SELECT TO public USING (a > 2)" +== 580 +-- truncate_limit: 100 +CREATE POLICY p1 ON y1 FOR SELECT USING (a % 2 = 1) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON y1 FOR SELECT TO public USING ((a % 2) = 1)" +== 581 +-- truncate_limit: 100 +--fail +CREATE POLICY p1 ON y2 FOR ALL USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON y2 TO public USING ((a % 2) = 0)" +== 582 +-- truncate_limit: 100 +--OK + +ALTER TABLE y1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="y1" schema="" table="y1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE y1 ENABLE ROW LEVEL SECURITY" +== 583 +-- truncate_limit: 100 +ALTER TABLE y2 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="y2" schema="" table="y2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE y2 ENABLE ROW LEVEL SECURITY" +== 584 +-- truncate_limit: 100 +|-- +-- Expression structure with SBV +|-- +-- Create view as table owner. RLS should NOT be applied. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 585 +-- truncate_limit: 100 +CREATE VIEW rls_sbv WITH (security_barrier) AS + SELECT * FROM y1 WHERE f_leak(b) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=DDL +TABLE: name="y1" schema="" table="y1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rls_sbv WITH (security_barrier) AS SELECT * FROM y1 WHERE f_leak(b)" +== 586 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_sbv WHERE (a = 1) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_sbv WHERE a = 1" +== 587 +-- truncate_limit: 100 +DROP VIEW rls_sbv +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rls_sbv" +== 588 +-- truncate_limit: 100 +-- Create view as role that does not own table. RLS should be applied. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 589 +-- truncate_limit: 100 +CREATE VIEW rls_sbv WITH (security_barrier) AS + SELECT * FROM y1 WHERE f_leak(b) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=DDL +TABLE: name="y1" schema="" table="y1" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rls_sbv WITH (security_barrier) AS SELECT * FROM y1 WHERE f_leak(b)" +== 590 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM rls_sbv WHERE (a = 1) +-- +TABLE: name="rls_sbv" schema="" table="rls_sbv" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rls_sbv WHERE a = 1" +== 591 +-- truncate_limit: 100 +DROP VIEW rls_sbv +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rls_sbv" +== 592 +-- truncate_limit: 100 +|-- +-- Expression structure +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 593 +-- truncate_limit: 100 +INSERT INTO y2 (SELECT x, public.fipshash(x::text) FROM generate_series(0,20) x) +-- +TABLE: name="y2" schema="" table="y2" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y2 SELECT x, public.fipshash(x::text) FROM generate_series(0, 20) x" +== 594 +-- truncate_limit: 100 +CREATE POLICY p2 ON y2 USING (a % 3 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON y2 TO public USING ((a % 3) = 0)" +== 595 +-- truncate_limit: 100 +CREATE POLICY p3 ON y2 USING (a % 4 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p3 ON y2 TO public USING ((a % 4) = 0)" +== 596 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 597 +-- truncate_limit: 100 +SELECT * FROM y2 WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y2 WHERE f_leak(b)" +== 598 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak(b)" +== 599 +-- truncate_limit: 100 +|-- +-- Qual push-down of leaky functions, when not referring to table +|-- +SELECT * FROM y2 WHERE f_leak('abc') +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y2 WHERE f_leak('abc')" +== 600 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak('abc') +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak('abc')" +== 601 +-- truncate_limit: 100 +CREATE TABLE test_qual_pushdown ( + abc text +) +-- +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_qual_pushdown (abc text)" +== 602 +-- truncate_limit: 100 +INSERT INTO test_qual_pushdown VALUES ('abc'),('def') +-- +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_qual_pushdown VALUES ('abc'), ('def')" +== 603 +-- truncate_limit: 100 +SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="abc" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y2 JOIN test_qual_pushdown ON b = abc WHERE f_leak(abc)" +== 604 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="abc" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON b = abc WHERE f_leak(abc)" +== 605 +-- truncate_limit: 100 +SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y2 JOIN test_qual_pushdown ON b = abc WHERE f_leak(b)" +== 606 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b) +-- +TABLE: name="y2" schema="" table="y2" ctx=Select +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON b = abc WHERE f_leak(b)" +== 607 +-- truncate_limit: 100 +DROP TABLE test_qual_pushdown +-- +TABLE: name="test_qual_pushdown" schema="" table="test_qual_pushdown" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_qual_pushdown" +== 608 +-- truncate_limit: 100 +|-- +-- Plancache invalidate on user change. +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 609 +-- truncate_limit: 100 +DROP TABLE t1 CASCADE +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1 CASCADE" +== 610 +-- truncate_limit: 100 +CREATE TABLE t1 (a integer) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (a int)" +== 611 +-- truncate_limit: 100 +GRANT SELECT ON t1 TO regress_rls_bob, regress_rls_carol +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON t1 TO regress_rls_bob, regress_rls_carol" +== 612 +-- truncate_limit: 100 +CREATE POLICY p1 ON t1 TO regress_rls_bob USING ((a % 2) = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON t1 TO regress_rls_bob USING ((a % 2) = 0)" +== 613 +-- truncate_limit: 100 +CREATE POLICY p2 ON t1 TO regress_rls_carol USING ((a % 4) = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p2 ON t1 TO regress_rls_carol USING ((a % 4) = 0)" +== 614 +-- truncate_limit: 100 +ALTER TABLE t1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t1 ENABLE ROW LEVEL SECURITY" +== 615 +-- truncate_limit: 100 +-- Prepare as regress_rls_bob +SET ROLE regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rls_bob" +== 616 +-- truncate_limit: 100 +PREPARE role_inval AS SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE role_inval AS SELECT * FROM t1" +== 617 +-- truncate_limit: 100 +-- Check plan +EXPLAIN (COSTS OFF) EXECUTE role_inval +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE role_inval" +== 618 +-- truncate_limit: 100 +-- Change to regress_rls_carol +SET ROLE regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rls_carol" +== 619 +-- truncate_limit: 100 +-- Check plan- should be different +EXPLAIN (COSTS OFF) EXECUTE role_inval +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE role_inval" +== 620 +-- truncate_limit: 100 +-- Change back to regress_rls_bob +SET ROLE regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_rls_bob" +== 621 +-- truncate_limit: 100 +-- Check plan- should be back to original +EXPLAIN (COSTS OFF) EXECUTE role_inval +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE role_inval" +== 622 +-- truncate_limit: 100 +|-- +-- CTE and RLS +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 623 +-- truncate_limit: 100 +DROP TABLE t1 CASCADE +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1 CASCADE" +== 624 +-- truncate_limit: 100 +CREATE TABLE t1 (a integer, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (a int, b text)" +== 625 +-- truncate_limit: 100 +CREATE POLICY p1 ON t1 USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON t1 TO public USING ((a % 2) = 0)" +== 626 +-- truncate_limit: 100 +ALTER TABLE t1 ENABLE ROW LEVEL SECURITY +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t1 ENABLE ROW LEVEL SECURITY" +== 627 +-- truncate_limit: 100 +GRANT ALL ON t1 TO regress_rls_bob +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON t1 TO regress_rls_bob" +== 628 +-- truncate_limit: 100 +INSERT INTO t1 (SELECT x, public.fipshash(x::text) FROM generate_series(0,20) x) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 SELECT x, public.fipshash(x::text) FROM generate_series(0, 20) x" +== 629 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 630 +-- truncate_limit: 100 +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +CTE: "cte1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1" +== 631 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +CTE: "cte1" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1" +== 632 +-- truncate_limit: 100 +WITH cte1 AS (UPDATE t1 SET a = a + 1 RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: UpdateStmt +TRUNCATED: "WITH cte1 AS (UPDATE t1 SET a = a + 1 RETURNING *) SELECT * FROM cte1" +== 633 +-- truncate_limit: 100 +--fail +WITH cte1 AS (UPDATE t1 SET a = a RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: UpdateStmt +TRUNCATED: "WITH cte1 AS (UPDATE t1 SET a = a RETURNING *) SELECT * FROM cte1" +== 634 +-- truncate_limit: 100 +--ok + +WITH cte1 AS (INSERT INTO t1 VALUES (21, 'Fail') RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH cte1 AS (INSERT INTO t1 VALUES (21, 'Fail') RETURNING *) SELECT * FROM cte1" +== 635 +-- truncate_limit: 100 +--fail +WITH cte1 AS (INSERT INTO t1 VALUES (20, 'Success') RETURNING *) SELECT * FROM cte1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +CTE: "cte1" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH cte1 AS (INSERT INTO t1 VALUES (20, 'Success') RETURNING *) SELECT * FROM cte1" +== 636 +-- truncate_limit: 100 +--ok + +|-- +-- Rename Policy +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 637 +-- truncate_limit: 100 +ALTER POLICY p1 ON t1 RENAME TO p1 +-- +STMT: RenameStmt +TRUNCATED: "ALTER POLICY p1 ON t1 RENAME TO p1" +== 638 +-- truncate_limit: 100 +--fail + +SELECT polname, relname + FROM pg_policy pol + JOIN pg_class pc ON (pc.oid = pol.polrelid) + WHERE relname = 't1' +-- +TABLE: name="pg_policy" schema="" table="pg_policy" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pol"="pg_policy" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_policy pol JOIN pg_class pc ON pc.oid = pol.polrelid WHERE relname = 't1'" +== 639 +-- truncate_limit: 100 +ALTER POLICY p1 ON t1 RENAME TO p2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER POLICY p1 ON t1 RENAME TO p2" +== 640 +-- truncate_limit: 100 +--ok + +SELECT polname, relname + FROM pg_policy pol + JOIN pg_class pc ON (pc.oid = pol.polrelid) + WHERE relname = 't1' +-- +TABLE: name="pg_policy" schema="" table="pg_policy" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "pc"="pg_class" +ALIAS: "pol"="pg_policy" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_policy pol JOIN pg_class pc ON pc.oid = pol.polrelid WHERE relname = 't1'" +== 641 +-- truncate_limit: 100 +|-- +-- Check INSERT SELECT +|-- +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 642 +-- truncate_limit: 100 +CREATE TABLE t2 (a integer, b text) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t2 (a int, b text)" +== 643 +-- truncate_limit: 100 +INSERT INTO t2 (SELECT * FROM t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 SELECT * FROM t1" +== 644 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) INSERT INTO t2 (SELECT * FROM t1) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO t2 SELECT * FROM t1" +== 645 +-- truncate_limit: 100 +SELECT * FROM t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t2" +== 646 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t2" +== 647 +-- truncate_limit: 100 +CREATE TABLE t3 AS SELECT * FROM t1 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE t3 AS SELECT * FROM t1" +== 648 +-- truncate_limit: 100 +SELECT * FROM t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t3" +== 649 +-- truncate_limit: 100 +SELECT * INTO t4 FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t4" schema="" table="t4" ctx=DDL +STMT: SelectStmt +TRUNCATED: "SELECT * INTO t4 FROM t1" +== 650 +-- truncate_limit: 100 +SELECT * FROM t4 +-- +TABLE: name="t4" schema="" table="t4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t4" +== 651 +-- truncate_limit: 100 +|-- +-- RLS with JOIN +|-- +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 652 +-- truncate_limit: 100 +CREATE TABLE blog (id integer, author text, post text) +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE blog (id int, author text, post text)" +== 653 +-- truncate_limit: 100 +CREATE TABLE comment (blog_id integer, message text) +-- +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE comment (blog_id int, message text)" +== 654 +-- truncate_limit: 100 +GRANT ALL ON blog, comment TO regress_rls_bob +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON blog, comment TO regress_rls_bob" +== 655 +-- truncate_limit: 100 +CREATE POLICY blog_1 ON blog USING (id % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY blog_1 ON blog TO public USING ((id % 2) = 0)" +== 656 +-- truncate_limit: 100 +ALTER TABLE blog ENABLE ROW LEVEL SECURITY +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE blog ENABLE ROW LEVEL SECURITY" +== 657 +-- truncate_limit: 100 +INSERT INTO blog VALUES + (1, 'alice', 'blog #1'), + (2, 'bob', 'blog #1'), + (3, 'alice', 'blog #2'), + (4, 'alice', 'blog #3'), + (5, 'john', 'blog #1') +-- +TABLE: name="blog" schema="" table="blog" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO blog VALUES (...)" +== 658 +-- truncate_limit: 100 +INSERT INTO comment VALUES + (1, 'cool blog'), + (1, 'fun blog'), + (3, 'crazy blog'), + (5, 'what?'), + (4, 'insane!'), + (2, 'who did it?') +-- +TABLE: name="comment" schema="" table="comment" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO comment VALUES (...)" +== 659 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 660 +-- truncate_limit: 100 +-- Check RLS JOIN with Non-RLS. +SELECT id, author, message FROM blog JOIN comment ON id = blog_id +-- +TABLE: name="blog" schema="" table="blog" ctx=Select +TABLE: name="comment" schema="" table="comment" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, author, message FROM blog JOIN comment ON id = blog_id" +== 661 +-- truncate_limit: 100 +-- Check Non-RLS JOIN with RLS. +SELECT id, author, message FROM comment JOIN blog ON id = blog_id +-- +TABLE: name="comment" schema="" table="comment" ctx=Select +TABLE: name="blog" schema="" table="blog" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, author, message FROM comment JOIN blog ON id = blog_id" +== 662 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 663 +-- truncate_limit: 100 +CREATE POLICY comment_1 ON comment USING (blog_id < 4) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY comment_1 ON comment TO public USING (blog_id < 4)" +== 664 +-- truncate_limit: 100 +ALTER TABLE comment ENABLE ROW LEVEL SECURITY +-- +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE comment ENABLE ROW LEVEL SECURITY" +== 665 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 666 +-- truncate_limit: 100 +-- Check RLS JOIN RLS +SELECT id, author, message FROM blog JOIN comment ON id = blog_id +-- +TABLE: name="blog" schema="" table="blog" ctx=Select +TABLE: name="comment" schema="" table="comment" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, author, message FROM blog JOIN comment ON id = blog_id" +== 667 +-- truncate_limit: 100 +SELECT id, author, message FROM comment JOIN blog ON id = blog_id +-- +TABLE: name="comment" schema="" table="comment" ctx=Select +TABLE: name="blog" schema="" table="blog" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id, author, message FROM comment JOIN blog ON id = blog_id" +== 668 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 669 +-- truncate_limit: 100 +DROP TABLE blog, comment +-- +TABLE: name="blog" schema="" table="blog" ctx=DDL +TABLE: name="comment" schema="" table="comment" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE blog, comment" +== 670 +-- truncate_limit: 100 +|-- +-- Default Deny Policy +|-- +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 671 +-- truncate_limit: 100 +DROP POLICY p2 ON t1 +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY p2 ON t1" +== 672 +-- truncate_limit: 100 +ALTER TABLE t1 OWNER TO regress_rls_alice +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t1 OWNER TO regress_rls_alice" +== 673 +-- truncate_limit: 100 +-- Check that default deny does not apply to superuser. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 674 +-- truncate_limit: 100 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 675 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1" +== 676 +-- truncate_limit: 100 +-- Check that default deny does not apply to table owner. +SET SESSION AUTHORIZATION regress_rls_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_alice" +== 677 +-- truncate_limit: 100 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 678 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1" +== 679 +-- truncate_limit: 100 +-- Check that default deny applies to non-owner/non-superuser when RLS on. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 680 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 681 +-- truncate_limit: 100 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 682 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1" +== 683 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 684 +-- truncate_limit: 100 +SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 685 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM t1" +== 686 +-- truncate_limit: 100 +|-- +-- COPY TO/FROM +|-- + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 687 +-- truncate_limit: 100 +DROP TABLE copy_t CASCADE +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE copy_t CASCADE" +== 688 +-- truncate_limit: 100 +CREATE TABLE copy_t (a integer, b text) +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE copy_t (a int, b text)" +== 689 +-- truncate_limit: 100 +CREATE POLICY p1 ON copy_t USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON copy_t TO public USING ((a % 2) = 0)" +== 690 +-- truncate_limit: 100 +ALTER TABLE copy_t ENABLE ROW LEVEL SECURITY +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE copy_t ENABLE ROW LEVEL SECURITY" +== 691 +-- truncate_limit: 100 +GRANT ALL ON copy_t TO regress_rls_bob, regress_rls_exempt_user +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON copy_t TO regress_rls_bob, regress_rls_exempt_user" +== 692 +-- truncate_limit: 100 +INSERT INTO copy_t (SELECT x, public.fipshash(x::text) FROM generate_series(0,10) x) +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copy_t SELECT x, public.fipshash(x::text) FROM generate_series(0, 10) x" +== 693 +-- truncate_limit: 100 +-- Check COPY TO as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 694 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 695 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 696 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 697 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 698 +-- truncate_limit: 100 +-- Check COPY TO as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 699 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 700 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 701 +-- truncate_limit: 100 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 702 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 703 +-- truncate_limit: 100 +--ok + +-- Check COPY TO as user with permissions and BYPASSRLS +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_exempt_user" +== 704 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 705 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 706 +-- truncate_limit: 100 +--ok +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 707 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 708 +-- truncate_limit: 100 +--ok + +-- Check COPY TO as user without permissions. SET row_security TO OFF; +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 709 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 710 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 711 +-- truncate_limit: 100 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 712 +-- truncate_limit: 100 +COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY (SELECT * FROM copy_t ORDER BY a ASC) TO STDOUT WITH (DELIMITER ',')" +== 713 +-- truncate_limit: 100 +--fail - permission denied + +-- Check COPY relation TO; keep it just one row to avoid reordering issues +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 714 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 715 +-- truncate_limit: 100 +CREATE TABLE copy_rel_to (a integer, b text) +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE copy_rel_to (a int, b text)" +== 716 +-- truncate_limit: 100 +CREATE POLICY p1 ON copy_rel_to USING (a % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY p1 ON copy_rel_to TO public USING ((a % 2) = 0)" +== 717 +-- truncate_limit: 100 +ALTER TABLE copy_rel_to ENABLE ROW LEVEL SECURITY +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE copy_rel_to ENABLE ROW LEVEL SECURITY" +== 718 +-- truncate_limit: 100 +GRANT ALL ON copy_rel_to TO regress_rls_bob, regress_rls_exempt_user +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON copy_rel_to TO regress_rls_bob, regress_rls_exempt_user" +== 719 +-- truncate_limit: 100 +INSERT INTO copy_rel_to VALUES (1, public.fipshash('1')) +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=DML +FUNCTION: name="public.fipshash" function="fipshash" schema="public" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copy_rel_to VALUES (1, public.fipshash('1'))" +== 720 +-- truncate_limit: 100 +-- Check COPY TO as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 721 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 722 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 723 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 724 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 725 +-- truncate_limit: 100 +-- Check COPY TO as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 726 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 727 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 728 +-- truncate_limit: 100 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 729 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 730 +-- truncate_limit: 100 +--ok + +-- Check COPY TO as user with permissions and BYPASSRLS +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_exempt_user" +== 731 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 732 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 733 +-- truncate_limit: 100 +--ok +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 734 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 735 +-- truncate_limit: 100 +--ok + +-- Check COPY TO as user without permissions. SET row_security TO OFF; +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 736 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 737 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 738 +-- truncate_limit: 100 +--fail - permission denied +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 739 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 740 +-- truncate_limit: 100 +--fail - permission denied + +-- Check behavior with a child table. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 741 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 742 +-- truncate_limit: 100 +CREATE TABLE copy_rel_to_child () INHERITS (copy_rel_to) +-- +TABLE: name="copy_rel_to_child" schema="" table="copy_rel_to_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE copy_rel_to_child () INHERITS (copy_rel_to)" +== 743 +-- truncate_limit: 100 +INSERT INTO copy_rel_to_child VALUES (1, 'one'), (2, 'two') +-- +TABLE: name="copy_rel_to_child" schema="" table="copy_rel_to_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO copy_rel_to_child VALUES (1, 'one'), (2, 'two')" +== 744 +-- truncate_limit: 100 +-- Check COPY TO as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 745 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 746 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 747 +-- truncate_limit: 100 +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 748 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 749 +-- truncate_limit: 100 +-- Check COPY TO as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 750 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 751 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 752 +-- truncate_limit: 100 +--fail - would be affected by RLS +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 753 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 754 +-- truncate_limit: 100 +--ok + +-- Check COPY TO as user with permissions and BYPASSRLS +SET SESSION AUTHORIZATION regress_rls_exempt_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_exempt_user" +== 755 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 756 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 757 +-- truncate_limit: 100 +--ok +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 758 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 759 +-- truncate_limit: 100 +--ok + +-- Check COPY TO as user without permissions. SET row_security TO OFF; +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 760 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 761 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 762 +-- truncate_limit: 100 +--fail - permission denied +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 763 +-- truncate_limit: 100 +COPY copy_rel_to TO STDOUT WITH DELIMITER ',' +-- +TABLE: name="copy_rel_to" schema="" table="copy_rel_to" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_rel_to TO STDOUT WITH (DELIMITER ',')" +== 764 +-- truncate_limit: 100 +--fail - permission denied + +-- Check COPY FROM as Superuser/owner. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 765 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 766 +-- truncate_limit: 100 +COPY copy_t FROM STDIN +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_t FROM STDIN" +== 767 +-- truncate_limit: 100 +--ok +1 abc +2 bcd +3 cde +4 def +SET row_security TO ON +-- +ERROR: syntax error at or near "1" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 768 +-- truncate_limit: 100 +-- Check COPY FROM as user with permissions. +SET SESSION AUTHORIZATION regress_rls_bob +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_bob" +== 769 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 770 +-- truncate_limit: 100 +COPY copy_t FROM STDIN +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_t FROM STDIN" +== 771 +-- truncate_limit: 100 +--fail - would be affected by RLS. +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" +== 772 +-- truncate_limit: 100 +-- Check COPY FROM as user without permissions. +SET SESSION AUTHORIZATION regress_rls_carol +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rls_carol" +== 773 +-- truncate_limit: 100 +SET row_security TO OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO OFF" +== 774 +-- truncate_limit: 100 +COPY copy_t FROM STDIN +-- +TABLE: name="copy_t" schema="" table="copy_t" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY copy_t FROM STDIN" +== 775 +-- truncate_limit: 100 +--fail - permission denied. +SET row_security TO ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET row_security TO ON" diff --git a/parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json new file mode 100644 index 0000000..e9da7a5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json @@ -0,0 +1,241 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/rowtypes.test b/parser/testdata/summary_truncate/postgres_regress/rowtypes.test new file mode 100644 index 0000000..be476f8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rowtypes.test @@ -0,0 +1,1898 @@ +== 001 +-- truncate_limit: 100 +|-- +-- ROWTYPES +|-- + +-- Make both a standalone composite type and a table rowtype + +create type complex as (r float8, i float8) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE complex AS (r float8, i float8)" +== 002 +-- truncate_limit: 100 +create temp table fullname (first text, last text) +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE fullname (first text, last text)" +== 003 +-- truncate_limit: 100 +-- Nested composite + +create type quad as (c1 complex, c2 complex) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE quad AS (c1 complex, c2 complex)" +== 004 +-- truncate_limit: 100 +-- Some simple tests of I/O conversions and row construction + +select (1.1,2.2)::complex, row((3.3,4.4),(5.5,null))::quad +-- +STMT: SelectStmt +TRUNCATED: "SELECT (1.1, 2.2)::complex, ROW((3.3, 4.4), (5.5, NULL))::quad" +== 005 +-- truncate_limit: 100 +select row('Joe', 'Blow')::fullname, '(Joe,Blow)'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW('Joe', 'Blow')::fullname, '(Joe,Blow)'::fullname" +== 006 +-- truncate_limit: 100 +select '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname" +== 007 +-- truncate_limit: 100 +select '(Joe,"von""Blow")'::fullname, E'(Joe,d\\\\Blow)'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(Joe,\"von\"\"Blow\")'::fullname, E'(Joe,d\\\\\\\\Blow)'::fullname" +== 008 +-- truncate_limit: 100 +select '(Joe,"Blow,Jr")'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(Joe,\"Blow,Jr\")'::fullname" +== 009 +-- truncate_limit: 100 +select '(Joe,)'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(Joe,)'::fullname" +== 010 +-- truncate_limit: 100 +-- ok, null 2nd column +select '(Joe)'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(Joe)'::fullname" +== 011 +-- truncate_limit: 100 +-- bad +select '(Joe,,)'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(Joe,,)'::fullname" +== 012 +-- truncate_limit: 100 +-- bad +select '[]'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '[]'::fullname" +== 013 +-- truncate_limit: 100 +-- bad +select ' (Joe,Blow) '::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' (Joe,Blow) '::fullname" +== 014 +-- truncate_limit: 100 +-- ok, extra whitespace +select '(Joe,Blow) /'::fullname +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(Joe,Blow) /'::fullname" +== 015 +-- truncate_limit: 100 +-- bad + +-- test non-error-throwing API +SELECT pg_input_is_valid('(1,2)', 'complex') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,2)', 'complex')" +== 016 +-- truncate_limit: 100 +SELECT pg_input_is_valid('(1,2', 'complex') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,2', 'complex')" +== 017 +-- truncate_limit: 100 +SELECT pg_input_is_valid('(1,zed)', 'complex') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(1,zed)', 'complex')" +== 018 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(1,zed)', 'complex') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(1,zed)', 'complex')" +== 019 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(1,1e400)', 'complex')" +== 020 +-- truncate_limit: 100 +create temp table quadtable(f1 int, q quad) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE quadtable (f1 int, q quad)" +== 021 +-- truncate_limit: 100 +insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quadtable VALUES (1, ((3.3, 4.4), (5.5, 6.6)))" +== 022 +-- truncate_limit: 100 +insert into quadtable values (2, ((null,4.4),(5.5,6.6))) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quadtable VALUES (2, ((NULL, 4.4), (5.5, 6.6)))" +== 023 +-- truncate_limit: 100 +select * from quadtable +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quadtable" +== 024 +-- truncate_limit: 100 +select f1, q.c1 from quadtable +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, q.c1 FROM quadtable" +== 025 +-- truncate_limit: 100 +-- fails, q is a table reference + +select f1, (q).c1, (qq.q).c1.i from quadtable qq +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +ALIAS: "qq"="quadtable" +STMT: SelectStmt +TRUNCATED: "SELECT f1, (q).c1, (qq.q).c1.i FROM quadtable qq" +== 026 +-- truncate_limit: 100 +create temp table people (fn fullname, bd date) +-- +TABLE: name="people" schema="" table="people" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE people (fn fullname, bd date)" +== 027 +-- truncate_limit: 100 +insert into people values ('(Joe,Blow)', '1984-01-10') +-- +TABLE: name="people" schema="" table="people" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO people VALUES ('(Joe,Blow)', '1984-01-10')" +== 028 +-- truncate_limit: 100 +select * from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM people" +== 029 +-- truncate_limit: 100 +-- at the moment this will not work due to ALTER TABLE inadequacy: +alter table fullname add column suffix text default '' +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fullname ADD COLUMN suffix text DEFAULT ''" +== 030 +-- truncate_limit: 100 +-- but this should work: +alter table fullname add column suffix text default null +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fullname ADD COLUMN suffix text DEFAULT NULL" +== 031 +-- truncate_limit: 100 +select * from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM people" +== 032 +-- truncate_limit: 100 +-- test insertion/updating of subfields +update people set fn.suffix = 'Jr' +-- +TABLE: name="people" schema="" table="people" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE people SET fn.suffix = 'Jr'" +== 033 +-- truncate_limit: 100 +select * from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM people" +== 034 +-- truncate_limit: 100 +insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66) +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO quadtable (f1, q.c1.r, q.c2.i) VALUES (44, 55, 66)" +== 035 +-- truncate_limit: 100 +update quadtable set q.c1.r = 12 where f1 = 2 +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE quadtable SET q.c1.r = 12 WHERE f1 = 2" +== 036 +-- truncate_limit: 100 +update quadtable set q.c1 = 12 +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE quadtable SET q.c1 = 12" +== 037 +-- truncate_limit: 100 +-- error, type mismatch + +select * from quadtable +-- +TABLE: name="quadtable" schema="" table="quadtable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM quadtable" +== 038 +-- truncate_limit: 100 +-- The object here is to ensure that toasted references inside +-- composite values don't cause problems. The large f1 value will +-- be toasted inside pp, it must still work after being copied to people. + +create temp table pp (f1 text) +-- +TABLE: name="pp" schema="" table="pp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pp (f1 text)" +== 039 +-- truncate_limit: 100 +insert into pp values (repeat('abcdefghijkl', 100000)) +-- +TABLE: name="pp" schema="" table="pp" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pp VALUES (repeat('abcdefghijkl', 100000))" +== 040 +-- truncate_limit: 100 +insert into people select ('Jim', f1, null)::fullname, current_date from pp +-- +TABLE: name="people" schema="" table="people" ctx=DML +TABLE: name="pp" schema="" table="pp" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO people SELECT ('Jim', f1, NULL)::fullname, current_date FROM pp" +== 041 +-- truncate_limit: 100 +select (fn).first, substr((fn).last, 1, 20), length((fn).last) from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (fn).first, substr((fn).last, 1, 20), length((fn).last) FROM people" +== 042 +-- truncate_limit: 100 +-- try an update on a toasted composite value, too +update people set fn.first = 'Jack' +-- +TABLE: name="people" schema="" table="people" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE people SET fn.first = 'Jack'" +== 043 +-- truncate_limit: 100 +select (fn).first, substr((fn).last, 1, 20), length((fn).last) from people +-- +TABLE: name="people" schema="" table="people" ctx=Select +FUNCTION: name="substr" function="substr" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (fn).first, substr((fn).last, 1, 20), length((fn).last) FROM people" +== 044 +-- truncate_limit: 100 +-- Test row comparison semantics. Prior to PG 8.2 we did this in a totally +-- non-spec-compliant way. + +select ROW(1,2) < ROW(1,3) as true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) < ROW(1, 3) AS \"true\"" +== 045 +-- truncate_limit: 100 +select ROW(1,2) < ROW(1,1) as false +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) < ROW(1, 1) AS \"false\"" +== 046 +-- truncate_limit: 100 +select ROW(1,2) < ROW(1,NULL) as null +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) < ROW(1, NULL) AS \"null\"" +== 047 +-- truncate_limit: 100 +select ROW(1,2,3) < ROW(1,3,NULL) as true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2, 3) < ROW(1, 3, NULL) AS \"true\"" +== 048 +-- truncate_limit: 100 +-- the NULL is not examined +select ROW(11,'ABC') < ROW(11,'DEF') as true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(11, 'ABC') < ROW(11, 'DEF') AS \"true\"" +== 049 +-- truncate_limit: 100 +select ROW(11,'ABC') > ROW(11,'DEF') as false +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(11, 'ABC') > ROW(11, 'DEF') AS \"false\"" +== 050 +-- truncate_limit: 100 +select ROW(12,'ABC') > ROW(11,'DEF') as true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(12, 'ABC') > ROW(11, 'DEF') AS \"true\"" +== 051 +-- truncate_limit: 100 +-- = and <> have different NULL-behavior than < etc +select ROW(1,2,3) < ROW(1,NULL,4) as null +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2, 3) < ROW(1, NULL, 4) AS \"null\"" +== 052 +-- truncate_limit: 100 +select ROW(1,2,3) = ROW(1,NULL,4) as false +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2, 3) = ROW(1, NULL, 4) AS \"false\"" +== 053 +-- truncate_limit: 100 +select ROW(1,2,3) <> ROW(1,NULL,4) as true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2, 3) <> ROW(1, NULL, 4) AS \"true\"" +== 054 +-- truncate_limit: 100 +-- We allow operators beyond the six standard ones, if they have btree +-- operator classes. +select ROW('ABC','DEF') ~<=~ ROW('DEF','ABC') as true +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW('ABC', 'DEF') ~<=~ ROW('DEF', 'ABC') AS \"true\"" +== 055 +-- truncate_limit: 100 +select ROW('ABC','DEF') ~>=~ ROW('DEF','ABC') as false +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW('ABC', 'DEF') ~>=~ ROW('DEF', 'ABC') AS \"false\"" +== 056 +-- truncate_limit: 100 +select ROW('ABC','DEF') ~~ ROW('DEF','ABC') as fail +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW('ABC', 'DEF') ~~ ROW('DEF', 'ABC') AS fail" +== 057 +-- truncate_limit: 100 +-- Comparisons of ROW() expressions can cope with some type mismatches +select ROW(1,2) = ROW(1,2::int8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) = ROW(1, 2::int8)" +== 058 +-- truncate_limit: 100 +select ROW(1,2) in (ROW(3,4), ROW(1,2)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) IN (ROW(3, 4), ROW(1, 2))" +== 059 +-- truncate_limit: 100 +select ROW(1,2) in (ROW(3,4), ROW(1,2::int8)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) IN (ROW(3, 4), ROW(1, 2::int8))" +== 060 +-- truncate_limit: 100 +-- Check row comparison with a subselect +select unique1, unique2 from tenk1 +where (unique1, unique2) < any (select ten, ten from tenk1 where hundred < 3) + and unique1 <= 20 +order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM tenk1 WHERE ... ORDER BY 1" +== 061 +-- truncate_limit: 100 +-- Also check row comparison with an indexable condition +explain (costs off) +select thousand, tenthous from tenk1 +where (thousand, tenthous) >= (997, 5000) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous FROM tenk1 WHERE (thousand, tenthous) >= (997, 5000..." +== 062 +-- truncate_limit: 100 +select thousand, tenthous from tenk1 +where (thousand, tenthous) >= (997, 5000) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT thousand, tenthous FROM tenk1 WHERE ... ORDER BY thousand, tenthous" +== 063 +-- truncate_limit: 100 +explain (costs off) +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous, four FROM tenk1 WHERE (thousand, tenthous, four) >..." +== 064 +-- truncate_limit: 100 +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT thousand, tenthous, four FROM tenk1 WHERE ... ORDER BY thousand, tenthous" +== 065 +-- truncate_limit: 100 +explain (costs off) +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, tenthous FROM tenk1 WHERE (998, 5000) < (thousand, tenthous)..." +== 066 +-- truncate_limit: 100 +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT thousand, tenthous FROM tenk1 WHERE ... ORDER BY thousand, tenthous" +== 067 +-- truncate_limit: 100 +explain (costs off) +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT thousand, hundred FROM tenk1 WHERE (998, 5000) < (thousand, hundred) O..." +== 068 +-- truncate_limit: 100 +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT thousand, hundred FROM tenk1 WHERE ... ORDER BY thousand, hundred" +== 069 +-- truncate_limit: 100 +-- Test case for bug #14010: indexed row comparisons fail with nulls +create temp table test_table (a text, b text) +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_table (a text, b text)" +== 070 +-- truncate_limit: 100 +insert into test_table values ('a', 'b') +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_table VALUES ('a', 'b')" +== 071 +-- truncate_limit: 100 +insert into test_table select 'a', null from generate_series(1,1000) +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_table SELECT 'a', NULL FROM generate_series(1, 1000)" +== 072 +-- truncate_limit: 100 +insert into test_table values ('b', 'a') +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_table VALUES ('b', 'a')" +== 073 +-- truncate_limit: 100 +create index on test_table (a,b) +-- +TABLE: name="test_table" schema="" table="test_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_table USING btree (a, b)" +== 074 +-- truncate_limit: 100 +set enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 075 +-- truncate_limit: 100 +explain (costs off) +select a,b from test_table where (a,b) > ('a','a') order by a,b +-- +TABLE: name="test_table" schema="" table="test_table" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT a, b FROM test_table WHERE (a, b) > ('a', 'a') ORDER BY a, b" +== 076 +-- truncate_limit: 100 +select a,b from test_table where (a,b) > ('a','a') order by a,b +-- +TABLE: name="test_table" schema="" table="test_table" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM test_table WHERE (a, b) > ('a', 'a') ORDER BY a, b" +== 077 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 078 +-- truncate_limit: 100 +-- Check row comparisons with IN +select * from int8_tbl i8 where i8 in (row(123,456)) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="" column="i8" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl i8 WHERE i8 IN (ROW(123, 456))" +== 079 +-- truncate_limit: 100 +-- fail, type mismatch + +explain (costs off) +select * from int8_tbl i8 +where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="" column="i8" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl i8 WHERE i8 IN (ROW(123, 456)::int8_tbl, '(45678901234..." +== 080 +-- truncate_limit: 100 +select * from int8_tbl i8 +where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +FILTER: schema="" table="" column="i8" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl i8 WHERE i8 IN (ROW(123, 456)::int8_tbl, '(4567890123456789,123)')" +== 081 +-- truncate_limit: 100 +-- Check ability to select columns from an anonymous rowtype +select (row(1, 2.0)).f1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (ROW(1, 2.0)).f1" +== 082 +-- truncate_limit: 100 +select (row(1, 2.0)).f2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (ROW(1, 2.0)).f2" +== 083 +-- truncate_limit: 100 +select (row(1, 2.0)).nosuch +-- +STMT: SelectStmt +TRUNCATED: "SELECT (ROW(1, 2.0)).nosuch" +== 084 +-- truncate_limit: 100 +-- fail +select (row(1, 2.0)).* +-- +STMT: SelectStmt +TRUNCATED: "SELECT (ROW(1, 2.0)).*" +== 085 +-- truncate_limit: 100 +select (r).f1 from (select row(1, 2.0) as r) ss +-- +STMT: SelectStmt +TRUNCATED: "SELECT (r).f1 FROM (SELECT ROW(1, 2.0) AS r) ss" +== 086 +-- truncate_limit: 100 +select (r).f3 from (select row(1, 2.0) as r) ss +-- +STMT: SelectStmt +TRUNCATED: "SELECT (r).f3 FROM (SELECT ROW(1, 2.0) AS r) ss" +== 087 +-- truncate_limit: 100 +-- fail +select (r).* from (select row(1, 2.0) as r) ss +-- +STMT: SelectStmt +TRUNCATED: "SELECT (r).* FROM (SELECT ROW(1, 2.0) AS r) ss" +== 088 +-- truncate_limit: 100 +-- Check some corner cases involving empty rowtypes +select ROW() +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW()" +== 089 +-- truncate_limit: 100 +select ROW() IS NULL +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW() IS NULL" +== 090 +-- truncate_limit: 100 +select ROW() = ROW() +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW() = ROW()" +== 091 +-- truncate_limit: 100 +-- Check ability to create arrays of anonymous rowtypes +select array[ row(1,2), row(3,4), row(5,6) ] +-- +STMT: SelectStmt +TRUNCATED: "SELECT ARRAY[ROW(1, 2), ROW(3, 4), ROW(5, 6)]" +== 092 +-- truncate_limit: 100 +-- Check ability to compare an anonymous row to elements of an array +select row(1,1.1) = any (array[ row(7,7.7), row(1,1.1), row(0,0.0) ]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 1.1) = ANY(ARRAY[ROW(7, 7.7), ROW(1, 1.1), ROW(0, 0.0)])" +== 093 +-- truncate_limit: 100 +select row(1,1.1) = any (array[ row(7,7.7), row(1,1.0), row(0,0.0) ]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 1.1) = ANY(ARRAY[ROW(7, 7.7), ROW(1, 1.0), ROW(0, 0.0)])" +== 094 +-- truncate_limit: 100 +-- Check behavior with a non-comparable rowtype +create type cantcompare as (p point, r float8) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE cantcompare AS (p point, r float8)" +== 095 +-- truncate_limit: 100 +create temp table cc (f1 cantcompare) +-- +TABLE: name="cc" schema="" table="cc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE cc (f1 cantcompare)" +== 096 +-- truncate_limit: 100 +insert into cc values('("(1,2)",3)') +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cc VALUES ('(\"(1,2)\",3)')" +== 097 +-- truncate_limit: 100 +insert into cc values('("(4,5)",6)') +-- +TABLE: name="cc" schema="" table="cc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cc VALUES ('(\"(4,5)\",6)')" +== 098 +-- truncate_limit: 100 +select * from cc order by f1 +-- +TABLE: name="cc" schema="" table="cc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cc ORDER BY f1" +== 099 +-- truncate_limit: 100 +-- fail, but should complain about cantcompare + +|-- +-- Tests for record_{eq,cmp} +|-- + +create type testtype1 as (a int, b int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype1 AS (a int, b int)" +== 100 +-- truncate_limit: 100 +-- all true +select row(1, 2)::testtype1 < row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 < ROW(1, 3)::testtype1" +== 101 +-- truncate_limit: 100 +select row(1, 2)::testtype1 <= row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 <= ROW(1, 3)::testtype1" +== 102 +-- truncate_limit: 100 +select row(1, 2)::testtype1 = row(1, 2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 = ROW(1, 2)::testtype1" +== 103 +-- truncate_limit: 100 +select row(1, 2)::testtype1 <> row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 <> ROW(1, 3)::testtype1" +== 104 +-- truncate_limit: 100 +select row(1, 3)::testtype1 >= row(1, 2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 3)::testtype1 >= ROW(1, 2)::testtype1" +== 105 +-- truncate_limit: 100 +select row(1, 3)::testtype1 > row(1, 2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 3)::testtype1 > ROW(1, 2)::testtype1" +== 106 +-- truncate_limit: 100 +-- all false +select row(1, -2)::testtype1 < row(1, -3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 < ROW(1, -3)::testtype1" +== 107 +-- truncate_limit: 100 +select row(1, -2)::testtype1 <= row(1, -3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 <= ROW(1, -3)::testtype1" +== 108 +-- truncate_limit: 100 +select row(1, -2)::testtype1 = row(1, -3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 = ROW(1, -3)::testtype1" +== 109 +-- truncate_limit: 100 +select row(1, -2)::testtype1 <> row(1, -2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 <> ROW(1, -2)::testtype1" +== 110 +-- truncate_limit: 100 +select row(1, -3)::testtype1 >= row(1, -2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -3)::testtype1 >= ROW(1, -2)::testtype1" +== 111 +-- truncate_limit: 100 +select row(1, -3)::testtype1 > row(1, -2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -3)::testtype1 > ROW(1, -2)::testtype1" +== 112 +-- truncate_limit: 100 +-- true, but see *< below +select row(1, -2)::testtype1 < row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 < ROW(1, 3)::testtype1" +== 113 +-- truncate_limit: 100 +-- mismatches +create type testtype3 as (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype3 AS (a int, b text)" +== 114 +-- truncate_limit: 100 +select row(1, 2)::testtype1 < row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 < ROW(1, 'abc')::testtype3" +== 115 +-- truncate_limit: 100 +select row(1, 2)::testtype1 <> row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 <> ROW(1, 'abc')::testtype3" +== 116 +-- truncate_limit: 100 +create type testtype5 as (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype5 AS (a int)" +== 117 +-- truncate_limit: 100 +select row(1, 2)::testtype1 < row(1)::testtype5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 < ROW(1)::testtype5" +== 118 +-- truncate_limit: 100 +select row(1, 2)::testtype1 <> row(1)::testtype5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 <> ROW(1)::testtype5" +== 119 +-- truncate_limit: 100 +-- non-comparable types +create type testtype6 as (a int, b point) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype6 AS (a int, b point)" +== 120 +-- truncate_limit: 100 +select row(1, '(1,2)')::testtype6 < row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, '(1,2)')::testtype6 < ROW(1, '(1,3)')::testtype6" +== 121 +-- truncate_limit: 100 +select row(1, '(1,2)')::testtype6 <> row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, '(1,2)')::testtype6 <> ROW(1, '(1,3)')::testtype6" +== 122 +-- truncate_limit: 100 +drop type testtype1, testtype3, testtype5, testtype6 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE testtype1, testtype3, testtype5, testtype6" +== 123 +-- truncate_limit: 100 +|-- +-- Tests for record_image_{eq,cmp} +|-- + +create type testtype1 as (a int, b int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype1 AS (a int, b int)" +== 124 +-- truncate_limit: 100 +-- all true +select row(1, 2)::testtype1 *< row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *< ROW(1, 3)::testtype1" +== 125 +-- truncate_limit: 100 +select row(1, 2)::testtype1 *<= row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *<= ROW(1, 3)::testtype1" +== 126 +-- truncate_limit: 100 +select row(1, 2)::testtype1 *= row(1, 2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *= ROW(1, 2)::testtype1" +== 127 +-- truncate_limit: 100 +select row(1, 2)::testtype1 *<> row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *<> ROW(1, 3)::testtype1" +== 128 +-- truncate_limit: 100 +select row(1, 3)::testtype1 *>= row(1, 2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 3)::testtype1 *>= ROW(1, 2)::testtype1" +== 129 +-- truncate_limit: 100 +select row(1, 3)::testtype1 *> row(1, 2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 3)::testtype1 *> ROW(1, 2)::testtype1" +== 130 +-- truncate_limit: 100 +-- all false +select row(1, -2)::testtype1 *< row(1, -3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 *< ROW(1, -3)::testtype1" +== 131 +-- truncate_limit: 100 +select row(1, -2)::testtype1 *<= row(1, -3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 *<= ROW(1, -3)::testtype1" +== 132 +-- truncate_limit: 100 +select row(1, -2)::testtype1 *= row(1, -3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 *= ROW(1, -3)::testtype1" +== 133 +-- truncate_limit: 100 +select row(1, -2)::testtype1 *<> row(1, -2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 *<> ROW(1, -2)::testtype1" +== 134 +-- truncate_limit: 100 +select row(1, -3)::testtype1 *>= row(1, -2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -3)::testtype1 *>= ROW(1, -2)::testtype1" +== 135 +-- truncate_limit: 100 +select row(1, -3)::testtype1 *> row(1, -2)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -3)::testtype1 *> ROW(1, -2)::testtype1" +== 136 +-- truncate_limit: 100 +-- This returns the "wrong" order because record_image_cmp works on +-- unsigned datums without knowing about the actual data type. +select row(1, -2)::testtype1 *< row(1, 3)::testtype1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, -2)::testtype1 *< ROW(1, 3)::testtype1" +== 137 +-- truncate_limit: 100 +-- other types +create type testtype2 as (a smallint, b bool) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype2 AS (a smallint, b bool)" +== 138 +-- truncate_limit: 100 +-- byval different sizes +select row(1, true)::testtype2 *< row(2, true)::testtype2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, true)::testtype2 *< ROW(2, true)::testtype2" +== 139 +-- truncate_limit: 100 +select row(-2, true)::testtype2 *< row(-1, true)::testtype2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(-2, true)::testtype2 *< ROW(-1, true)::testtype2" +== 140 +-- truncate_limit: 100 +select row(0, false)::testtype2 *< row(0, true)::testtype2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(0, false)::testtype2 *< ROW(0, true)::testtype2" +== 141 +-- truncate_limit: 100 +select row(0, false)::testtype2 *<> row(0, true)::testtype2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(0, false)::testtype2 *<> ROW(0, true)::testtype2" +== 142 +-- truncate_limit: 100 +create type testtype3 as (a int, b text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype3 AS (a int, b text)" +== 143 +-- truncate_limit: 100 +-- variable length +select row(1, 'abc')::testtype3 *< row(1, 'abd')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 'abc')::testtype3 *< ROW(1, 'abd')::testtype3" +== 144 +-- truncate_limit: 100 +select row(1, 'abc')::testtype3 *< row(1, 'abcd')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 'abc')::testtype3 *< ROW(1, 'abcd')::testtype3" +== 145 +-- truncate_limit: 100 +select row(1, 'abc')::testtype3 *> row(1, 'abd')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 'abc')::testtype3 *> ROW(1, 'abd')::testtype3" +== 146 +-- truncate_limit: 100 +select row(1, 'abc')::testtype3 *<> row(1, 'abd')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 'abc')::testtype3 *<> ROW(1, 'abd')::testtype3" +== 147 +-- truncate_limit: 100 +create type testtype4 as (a int, b point) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype4 AS (a int, b point)" +== 148 +-- truncate_limit: 100 +-- by ref, fixed length +select row(1, '(1,2)')::testtype4 *< row(1, '(1,3)')::testtype4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, '(1,2)')::testtype4 *< ROW(1, '(1,3)')::testtype4" +== 149 +-- truncate_limit: 100 +select row(1, '(1,2)')::testtype4 *<> row(1, '(1,3)')::testtype4 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, '(1,2)')::testtype4 *<> ROW(1, '(1,3)')::testtype4" +== 150 +-- truncate_limit: 100 +-- mismatches +select row(1, 2)::testtype1 *< row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *< ROW(1, 'abc')::testtype3" +== 151 +-- truncate_limit: 100 +select row(1, 2)::testtype1 *<> row(1, 'abc')::testtype3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *<> ROW(1, 'abc')::testtype3" +== 152 +-- truncate_limit: 100 +create type testtype5 as (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype5 AS (a int)" +== 153 +-- truncate_limit: 100 +select row(1, 2)::testtype1 *< row(1)::testtype5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *< ROW(1)::testtype5" +== 154 +-- truncate_limit: 100 +select row(1, 2)::testtype1 *<> row(1)::testtype5 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2)::testtype1 *<> ROW(1)::testtype5" +== 155 +-- truncate_limit: 100 +-- non-comparable types +create type testtype6 as (a int, b point) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE testtype6 AS (a int, b point)" +== 156 +-- truncate_limit: 100 +select row(1, '(1,2)')::testtype6 *< row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, '(1,2)')::testtype6 *< ROW(1, '(1,3)')::testtype6" +== 157 +-- truncate_limit: 100 +select row(1, '(1,2)')::testtype6 *>= row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, '(1,2)')::testtype6 *>= ROW(1, '(1,3)')::testtype6" +== 158 +-- truncate_limit: 100 +select row(1, '(1,2)')::testtype6 *<> row(1, '(1,3)')::testtype6 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, '(1,2)')::testtype6 *<> ROW(1, '(1,3)')::testtype6" +== 159 +-- truncate_limit: 100 +-- anonymous rowtypes in coldeflists +select q.a, q.b = row(2), q.c = array[row(3)], q.d = row(row(4)) from + unnest(array[row(1, row(2), array[row(3)], row(row(4))), + row(2, row(3), array[row(4)], row(row(5)))]) + as q(a int, b record, c record[], d record) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest(ARRAY[ROW(1, ROW(2), ARRAY[ROW(3)], ROW(ROW(4))), ROW(2, ROW(3), ARRAY[ROW..." +== 160 +-- truncate_limit: 100 +drop type testtype1, testtype2, testtype3, testtype4, testtype5, testtype6 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE testtype1, testtype2, testtype3, testtype4, testtype5, testtype6" +== 161 +-- truncate_limit: 100 +|-- +-- Test case derived from bug #5716: check multiple uses of a rowtype result +|-- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 162 +-- truncate_limit: 100 +CREATE TABLE price ( + id SERIAL PRIMARY KEY, + active BOOLEAN NOT NULL, + price NUMERIC +) +-- +TABLE: name="price" schema="" table="price" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE price (id serial PRIMARY KEY, active boolean NOT NULL, price numeric)" +== 163 +-- truncate_limit: 100 +CREATE TYPE price_input AS ( + id INTEGER, + price NUMERIC +) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE price_input AS (id int, price numeric)" +== 164 +-- truncate_limit: 100 +CREATE TYPE price_key AS ( + id INTEGER +) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE price_key AS (id int)" +== 165 +-- truncate_limit: 100 +CREATE FUNCTION price_key_from_table(price) RETURNS price_key AS $$ + SELECT $1.id +$$ LANGUAGE SQL +-- +FUNCTION: name="price_key_from_table" function="price_key_from_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION price_key_from_table(price) RETURNS price_key AS $$\n SELECT $1.id\n$$ LANGUAGE sql" +== 166 +-- truncate_limit: 100 +CREATE FUNCTION price_key_from_input(price_input) RETURNS price_key AS $$ + SELECT $1.id +$$ LANGUAGE SQL +-- +FUNCTION: name="price_key_from_input" function="price_key_from_input" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION price_key_from_input(price_input) RETURNS price_key AS $$\n SELECT $1.id\n$$ LAN..." +== 167 +-- truncate_limit: 100 +insert into price values (1,false,42), (10,false,100), (11,true,17.99) +-- +TABLE: name="price" schema="" table="price" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO price VALUES (1, false, 42), (10, false, 100), (11, true, 17.99)" +== 168 +-- truncate_limit: 100 +UPDATE price + SET active = true, price = input_prices.price + FROM unnest(ARRAY[(10, 123.00), (11, 99.99)]::price_input[]) input_prices + WHERE price_key_from_table(price.*) = price_key_from_input(input_prices.*) +-- +TABLE: name="price" schema="" table="price" ctx=DML +FUNCTION: name="price_key_from_table" function="price_key_from_table" schema="" ctx=Call +FUNCTION: name="price_key_from_input" function="price_key_from_input" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE price SET ... = ... FROM unnest(ARRAY[(10, 123.00), (11, 99.99)]::price_input[]) input_pri..." +== 169 +-- truncate_limit: 100 +select * from price +-- +TABLE: name="price" schema="" table="price" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM price" +== 170 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 171 +-- truncate_limit: 100 +|-- +-- Test case derived from bug #9085: check * qualification of composite +-- parameters for SQL functions +|-- + +create temp table compos (f1 int, f2 text) +-- +TABLE: name="compos" schema="" table="compos" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE compos (f1 int, f2 text)" +== 172 +-- truncate_limit: 100 +create function fcompos1(v compos) returns void as $$ +insert into compos values (v); -- fail +$$ language sql +-- +FUNCTION: name="fcompos1" function="fcompos1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fcompos1(v compos) RETURNS void AS $$\ninsert into compos values (v); -- fail\n$$ ..." +== 173 +-- truncate_limit: 100 +create function fcompos1(v compos) returns void as $$ +insert into compos values (v.*); +$$ language sql +-- +FUNCTION: name="fcompos1" function="fcompos1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fcompos1(v compos) RETURNS void AS $$\ninsert into compos values (v.*);\n$$ LANGUAG..." +== 174 +-- truncate_limit: 100 +create function fcompos2(v compos) returns void as $$ +select fcompos1(v); +$$ language sql +-- +FUNCTION: name="fcompos2" function="fcompos2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fcompos2(v compos) RETURNS void AS $$\nselect fcompos1(v);\n$$ LANGUAGE sql" +== 175 +-- truncate_limit: 100 +create function fcompos3(v compos) returns void as $$ +select fcompos1(fcompos3.v.*); +$$ language sql +-- +FUNCTION: name="fcompos3" function="fcompos3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fcompos3(v compos) RETURNS void AS $$\nselect fcompos1(fcompos3.v.*);\n$$ LANGUAGE sql" +== 176 +-- truncate_limit: 100 +select fcompos1(row(1,'one')) +-- +FUNCTION: name="fcompos1" function="fcompos1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT fcompos1(ROW(1, 'one'))" +== 177 +-- truncate_limit: 100 +select fcompos2(row(2,'two')) +-- +FUNCTION: name="fcompos2" function="fcompos2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT fcompos2(ROW(2, 'two'))" +== 178 +-- truncate_limit: 100 +select fcompos3(row(3,'three')) +-- +FUNCTION: name="fcompos3" function="fcompos3" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT fcompos3(ROW(3, 'three'))" +== 179 +-- truncate_limit: 100 +select * from compos +-- +TABLE: name="compos" schema="" table="compos" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM compos" +== 180 +-- truncate_limit: 100 +|-- +-- We allow I/O conversion casts from composite types to strings to be +-- invoked via cast syntax, but not functional syntax. This is because +-- the latter is too prone to be invoked unintentionally. +|-- +select cast (fullname as text) from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT fullname::text FROM fullname" +== 181 +-- truncate_limit: 100 +select fullname::text from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT fullname::text FROM fullname" +== 182 +-- truncate_limit: 100 +select text(fullname) from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +FUNCTION: name="text" function="text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT text(fullname) FROM fullname" +== 183 +-- truncate_limit: 100 +-- error +select fullname.text from fullname +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT fullname.text FROM fullname" +== 184 +-- truncate_limit: 100 +-- error +-- same, but RECORD instead of named composite type: +select cast (row('Jim', 'Beam') as text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW('Jim', 'Beam')::text" +== 185 +-- truncate_limit: 100 +select (row('Jim', 'Beam'))::text +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW('Jim', 'Beam')::text" +== 186 +-- truncate_limit: 100 +select text(row('Jim', 'Beam')) +-- +FUNCTION: name="text" function="text" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT text(ROW('Jim', 'Beam'))" +== 187 +-- truncate_limit: 100 +-- error +select (row('Jim', 'Beam')).text +-- +STMT: SelectStmt +TRUNCATED: "SELECT (ROW('Jim', 'Beam')).text" +== 188 +-- truncate_limit: 100 +-- error + +|-- +-- Check the equivalence of functional and column notation +|-- +insert into fullname values ('Joe', 'Blow') +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fullname VALUES ('Joe', 'Blow')" +== 189 +-- truncate_limit: 100 +select f.last from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +STMT: SelectStmt +TRUNCATED: "SELECT f.last FROM fullname f" +== 190 +-- truncate_limit: 100 +select last(f) from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +FUNCTION: name="last" function="last" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT last(f) FROM fullname f" +== 191 +-- truncate_limit: 100 +create function longname(fullname) returns text language sql +as $$select $1.first || ' ' || $1.last$$ +-- +FUNCTION: name="longname" function="longname" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION longname(fullname) RETURNS text LANGUAGE sql AS $$select $1.first || ' ' || $1.la..." +== 192 +-- truncate_limit: 100 +select f.longname from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +STMT: SelectStmt +TRUNCATED: "SELECT f.longname FROM fullname f" +== 193 +-- truncate_limit: 100 +select longname(f) from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +FUNCTION: name="longname" function="longname" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT longname(f) FROM fullname f" +== 194 +-- truncate_limit: 100 +-- Starting in v11, the notational form does matter if there's ambiguity +alter table fullname add column longname text +-- +TABLE: name="fullname" schema="" table="fullname" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE fullname ADD COLUMN longname text" +== 195 +-- truncate_limit: 100 +select f.longname from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +STMT: SelectStmt +TRUNCATED: "SELECT f.longname FROM fullname f" +== 196 +-- truncate_limit: 100 +select longname(f) from fullname f +-- +TABLE: name="fullname" schema="" table="fullname" ctx=Select +ALIAS: "f"="fullname" +FUNCTION: name="longname" function="longname" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT longname(f) FROM fullname f" +== 197 +-- truncate_limit: 100 +|-- +-- Test that composite values are seen to have the correct column names +-- (bug #11210 and other reports) +|-- + +select row_to_json(i) from int8_tbl i +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(i) FROM int8_tbl i" +== 198 +-- truncate_limit: 100 +-- since "i" is of type "int8_tbl", attaching aliases doesn't change anything: +select row_to_json(i) from int8_tbl i(x,y) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i"="int8_tbl" +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(i) FROM int8_tbl i(x, y)" +== 199 +-- truncate_limit: 100 +-- in these examples, we'll report the exposed column names of the subselect: +select row_to_json(ss) from + (select q1, q2 from int8_tbl) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ss) FROM (SELECT q1, q2 FROM int8_tbl) ss" +== 200 +-- truncate_limit: 100 +select row_to_json(ss) from + (select q1, q2 from int8_tbl offset 0) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ss) FROM (SELECT q1, q2 FROM int8_tbl OFFSET 0) ss" +== 201 +-- truncate_limit: 100 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ss) FROM (SELECT q1 AS a, q2 AS b FROM int8_tbl) ss" +== 202 +-- truncate_limit: 100 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl offset 0) as ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ss) FROM (SELECT q1 AS a, q2 AS b FROM int8_tbl OFFSET 0) ss" +== 203 +-- truncate_limit: 100 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl) as ss(x,y) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ss) FROM (SELECT q1 AS a, q2 AS b FROM int8_tbl) ss(x, y)" +== 204 +-- truncate_limit: 100 +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl offset 0) as ss(x,y) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(ss) FROM (SELECT q1 AS a, q2 AS b FROM int8_tbl OFFSET 0) ss(x, y)" +== 205 +-- truncate_limit: 100 +explain (costs off) +select row_to_json(q) from + (select thousand, tenthous from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT row_to_json(q) FROM (SELECT thousand, tenthous FROM tenk1 WHERE thousa..." +== 206 +-- truncate_limit: 100 +select row_to_json(q) from + (select thousand, tenthous from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT thousand, tenthous FROM tenk1 WHERE ... OFFSET 0) q" +== 207 +-- truncate_limit: 100 +select row_to_json(q) from + (select thousand as x, tenthous as y from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT thousand AS x, tenthous AS y FROM tenk1 WHERE ... OFFSET 0) q" +== 208 +-- truncate_limit: 100 +select row_to_json(q) from + (select thousand as x, tenthous as y from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q(a,b) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +FILTER: schema="" table="" column="tenthous" +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(q) FROM (SELECT ... FROM tenk1 WHERE ... OFFSET 0) q(a, b)" +== 209 +-- truncate_limit: 100 +create temp table tt1 as select * from int8_tbl limit 2 +-- +TABLE: name="tt1" schema="" table="tt1" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt1 AS SELECT * FROM int8_tbl LIMIT 2" +== 210 +-- truncate_limit: 100 +create temp table tt2 () inherits(tt1) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt2 () INHERITS (tt1)" +== 211 +-- truncate_limit: 100 +insert into tt2 values(0,0) +-- +TABLE: name="tt2" schema="" table="tt2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt2 VALUES (0, 0)" +== 212 +-- truncate_limit: 100 +select row_to_json(r) from (select q2,q1 from tt1 offset 0) r +-- +TABLE: name="tt1" schema="" table="tt1" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(r) FROM (SELECT q2, q1 FROM tt1 OFFSET 0) r" +== 213 +-- truncate_limit: 100 +-- check no-op rowtype conversions +create temp table tt3 () inherits(tt2) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tt3 () INHERITS (tt2)" +== 214 +-- truncate_limit: 100 +insert into tt3 values(33,44) +-- +TABLE: name="tt3" schema="" table="tt3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tt3 VALUES (33, 44)" +== 215 +-- truncate_limit: 100 +select row_to_json(tt3::tt2::tt1) from tt3 +-- +TABLE: name="tt3" schema="" table="tt3" ctx=Select +FUNCTION: name="row_to_json" function="row_to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT row_to_json(tt3::tt2::tt1) FROM tt3" +== 216 +-- truncate_limit: 100 +|-- +-- IS [NOT] NULL should not recurse into nested composites (bug #14235) +|-- + +explain (verbose, costs off) +select r, r is null as isnull, r is not null as isnotnull +from (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT r, r IS NULL AS \"isnull\", r IS NOT NULL AS isnotnull FROM (VA..." +== 217 +-- truncate_limit: 100 +select r, r is null as isnull, r is not null as isnotnull +from (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b) +-- +STMT: SelectStmt +TRUNCATED: "SELECT r, r IS NULL AS \"isnull\", r IS NOT NULL AS isnotnull FROM (VALUES (...)) r(a, b)" +== 218 +-- truncate_limit: 100 +explain (verbose, costs off) +with r(a,b) as materialized + (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) +select r, r is null as isnull, r is not null as isnotnull from r +-- +CTE: "r" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH r(a, b) AS MATERIALIZED (VALUES (1, ROW(1, 2)), (1, ROW(NULL, N..." +== 219 +-- truncate_limit: 100 +with r(a,b) as materialized + (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) +select r, r is null as isnull, r is not null as isnotnull from r +-- +CTE: "r" +STMT: SelectStmt +TRUNCATED: "WITH r(a, b) AS MATERIALIZED (...) SELECT ... FROM r" +== 220 +-- truncate_limit: 100 +|-- +-- Check parsing of indirect references to composite values (bug #18077) +|-- +explain (verbose, costs off) +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select * from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH cte(c) AS MATERIALIZED (SELECT ROW(1, 2)), cte2(c) AS (SELECT *..." +== 221 +-- truncate_limit: 100 +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select * from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: SelectStmt +TRUNCATED: "WITH cte(c) AS MATERIALIZED (...), cte2(c) AS (...) SELECT * FROM cte2 t WHERE ..." +== 222 +-- truncate_limit: 100 +-- Also check deparsing of such cases +create view composite_v as +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select 1 as one from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null +-- +TABLE: name="composite_v" schema="" table="composite_v" ctx=DDL +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW composite_v AS WITH cte(c) AS MATERIALIZED (SELECT ROW(1, 2)), cte2(c) AS (SELECT * F..." +== 223 +-- truncate_limit: 100 +select pg_get_viewdef('composite_v', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('composite_v', true)" +== 224 +-- truncate_limit: 100 +drop view composite_v +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW composite_v" +== 225 +-- truncate_limit: 100 +|-- +-- Check cases where the composite comes from a proven-dummy rel (bug #18576) +|-- +explain (verbose, costs off) +select (ss.a).x, (ss.a).n from + (select information_schema._pg_expandarray(array[1,2]) AS a) ss +-- +FUNCTION: name="information_schema._pg_expandarray" function="_pg_expandarray" schema="information_schema" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT (ss.a).x, (ss.a).n FROM (SELECT information_schema._pg_expand..." +== 226 +-- truncate_limit: 100 +explain (verbose, costs off) +select (ss.a).x, (ss.a).n from + (select information_schema._pg_expandarray(array[1,2]) AS a) ss +where false +-- +FUNCTION: name="information_schema._pg_expandarray" function="_pg_expandarray" schema="information_schema" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT (ss.a).x, (ss.a).n FROM (SELECT information_schema._pg_expand..." +== 227 +-- truncate_limit: 100 +explain (verbose, costs off) +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select (c).f1 from cte2 as t +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH cte(c) AS MATERIALIZED (SELECT ROW(1, 2)), cte2(c) AS (SELECT *..." +== 228 +-- truncate_limit: 100 +explain (verbose, costs off) +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select (c).f1 from cte2 as t +where false +-- +ALIAS: "t"="cte2" +CTE: "cte" +CTE: "cte2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH cte(c) AS MATERIALIZED (SELECT ROW(1, 2)), cte2(c) AS (SELECT *..." +== 229 +-- truncate_limit: 100 +|-- +-- Tests for component access / FieldSelect +|-- +CREATE TABLE compositetable(a text, b text) +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE compositetable (a text, b text)" +== 230 +-- truncate_limit: 100 +INSERT INTO compositetable(a, b) VALUES('fa', 'fb') +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO compositetable (a, b) VALUES ('fa', 'fb')" +== 231 +-- truncate_limit: 100 +-- composite type columns can't directly be accessed (error) +SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s" +== 232 +-- truncate_limit: 100 +-- but can be accessed with proper parens +SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s" +== 233 +-- truncate_limit: 100 +-- system columns can't be accessed in composite types (error) +SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s" +== 234 +-- truncate_limit: 100 +-- accessing non-existing column in NULL datum errors out +SELECT (NULL::compositetable).nonexistent +-- +STMT: SelectStmt +TRUNCATED: "SELECT (NULL::compositetable).nonexistent" +== 235 +-- truncate_limit: 100 +-- existing column in a NULL composite yield NULL +SELECT (NULL::compositetable).a +-- +STMT: SelectStmt +TRUNCATED: "SELECT (NULL::compositetable).a" +== 236 +-- truncate_limit: 100 +-- oids can't be accessed in composite types (error) +SELECT (NULL::compositetable).oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT (NULL::compositetable).oid" +== 237 +-- truncate_limit: 100 +DROP TABLE compositetable +-- +TABLE: name="compositetable" schema="" table="compositetable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE compositetable" diff --git a/parser/testdata/summary_truncate/postgres_regress/rules.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rules.metadata.json new file mode 100644 index 0000000..75d8f0c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rules.metadata.json @@ -0,0 +1,624 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/rules.test b/parser/testdata/summary_truncate/postgres_regress/rules.test new file mode 100644 index 0000000..3a55ea9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/rules.test @@ -0,0 +1,5245 @@ +== 001 +-- truncate_limit: 100 +|-- +-- RULES +-- From Jan's original setup_ruletest.sql and run_ruletest.sql +-- - thomas 1998-09-13 +|-- + +|-- +-- Tables and rules for the view test +|-- +create table rtest_t1 (a int4, b int4) +-- +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t1 (a int4, b int4)" +== 002 +-- truncate_limit: 100 +create table rtest_t2 (a int4, b int4) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t2 (a int4, b int4)" +== 003 +-- truncate_limit: 100 +create table rtest_t3 (a int4, b int4) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t3 (a int4, b int4)" +== 004 +-- truncate_limit: 100 +create view rtest_v1 as select * from rtest_t1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rtest_v1 AS SELECT * FROM rtest_t1" +== 005 +-- truncate_limit: 100 +create rule rtest_v1_ins as on insert to rtest_v1 do instead + insert into rtest_t1 values (new.a, new.b) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_v1_ins AS ON INSERT TO rtest_v1 DO INSTEAD INSERT INTO rtest_t1 VALUES (new.a, ..." +== 006 +-- truncate_limit: 100 +create rule rtest_v1_upd as on update to rtest_v1 do instead + update rtest_t1 set a = new.a, b = new.b + where a = old.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_v1_upd AS ON UPDATE TO rtest_v1 DO INSTEAD UPDATE rtest_t1 SET a = new.a, b = n..." +== 007 +-- truncate_limit: 100 +create rule rtest_v1_del as on delete to rtest_v1 do instead + delete from rtest_t1 where a = old.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_v1_del AS ON DELETE TO rtest_v1 DO INSTEAD DELETE FROM rtest_t1 WHERE a = old.a" +== 008 +-- truncate_limit: 100 +-- Test comments +COMMENT ON RULE rtest_v1_bad ON rtest_v1 IS 'bad rule' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON RULE rtest_v1_bad ON rtest_v1 IS 'bad rule'" +== 009 +-- truncate_limit: 100 +COMMENT ON RULE rtest_v1_del ON rtest_v1 IS 'delete rule' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON RULE rtest_v1_del ON rtest_v1 IS 'delete rule'" +== 010 +-- truncate_limit: 100 +COMMENT ON RULE rtest_v1_del ON rtest_v1 IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON RULE rtest_v1_del ON rtest_v1 IS NULL" +== 011 +-- truncate_limit: 100 +|-- +-- Tables and rules for the constraint update/delete test +|-- +-- Note: +-- Now that we have multiple action rule support, we check +-- both possible syntaxes to define them (The last action +-- can but must not have a semicolon at the end). +|-- +create table rtest_system (sysname text, sysdesc text) +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_system (sysname text, sysdesc text)" +== 012 +-- truncate_limit: 100 +create table rtest_interface (sysname text, ifname text) +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_interface (sysname text, ifname text)" +== 013 +-- truncate_limit: 100 +create table rtest_person (pname text, pdesc text) +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_person (pname text, pdesc text)" +== 014 +-- truncate_limit: 100 +create table rtest_admin (pname text, sysname text) +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_admin (pname text, sysname text)" +== 015 +-- truncate_limit: 100 +create rule rtest_sys_upd as on update to rtest_system do also ( + update rtest_interface set sysname = new.sysname + where sysname = old.sysname; + update rtest_admin set sysname = new.sysname + where sysname = old.sysname + ) +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_sys_upd AS ON UPDATE TO rtest_system DO (UPDATE rtest_interface SET sysname = n..." +== 016 +-- truncate_limit: 100 +create rule rtest_sys_del as on delete to rtest_system do also ( + delete from rtest_interface where sysname = old.sysname; + delete from rtest_admin where sysname = old.sysname; + ) +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_sys_del AS ON DELETE TO rtest_system DO (DELETE FROM rtest_interface WHERE sysn..." +== 017 +-- truncate_limit: 100 +create rule rtest_pers_upd as on update to rtest_person do also + update rtest_admin set pname = new.pname where pname = old.pname +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_pers_upd AS ON UPDATE TO rtest_person DO UPDATE rtest_admin SET pname = new.pna..." +== 018 +-- truncate_limit: 100 +create rule rtest_pers_del as on delete to rtest_person do also + delete from rtest_admin where pname = old.pname +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_pers_del AS ON DELETE TO rtest_person DO DELETE FROM rtest_admin WHERE pname = ..." +== 019 +-- truncate_limit: 100 +|-- +-- Tables and rules for the logging test +|-- +create table rtest_emp (ename char(20), salary numeric) +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_emp (ename char(20), salary numeric)" +== 020 +-- truncate_limit: 100 +create table rtest_emplog (ename char(20), who name, action char(10), newsal numeric, oldsal numeric) +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_emplog (ename char(20), who name, action char(10), newsal numeric, oldsal nume..." +== 021 +-- truncate_limit: 100 +create table rtest_empmass (ename char(20), salary numeric) +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_empmass (ename char(20), salary numeric)" +== 022 +-- truncate_limit: 100 +create rule rtest_emp_ins as on insert to rtest_emp do + insert into rtest_emplog values (new.ename, current_user, + 'hired', new.salary, '0.00') +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog VALUES (new.ename..." +== 023 +-- truncate_limit: 100 +create rule rtest_emp_upd as on update to rtest_emp where new.salary != old.salary do + insert into rtest_emplog values (new.ename, current_user, + 'honored', new.salary, old.salary) +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE ... DO INSERT INTO rtest_emplog VALUES ..." +== 024 +-- truncate_limit: 100 +create rule rtest_emp_del as on delete to rtest_emp do + insert into rtest_emplog values (old.ename, current_user, + 'fired', '0.00', old.salary) +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog VALUES (old.ename..." +== 025 +-- truncate_limit: 100 +|-- +-- Tables and rules for the multiple cascaded qualified instead +-- rule test +|-- +create table rtest_t4 (a int4, b text) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t4 (a int4, b text)" +== 026 +-- truncate_limit: 100 +create table rtest_t5 (a int4, b text) +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t5 (a int4, b text)" +== 027 +-- truncate_limit: 100 +create table rtest_t6 (a int4, b text) +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t6 (a int4, b text)" +== 028 +-- truncate_limit: 100 +create table rtest_t7 (a int4, b text) +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t7 (a int4, b text)" +== 029 +-- truncate_limit: 100 +create table rtest_t8 (a int4, b text) +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t8 (a int4, b text)" +== 030 +-- truncate_limit: 100 +create table rtest_t9 (a int4, b text) +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_t9 (a int4, b text)" +== 031 +-- truncate_limit: 100 +create rule rtest_t4_ins1 as on insert to rtest_t4 + where new.a >= 10 and new.a < 20 do instead + insert into rtest_t5 values (new.a, new.b) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_t4_ins1 AS ON INSERT TO rtest_t4 WHERE ... DO INSTEAD INSERT INTO rtest_t5 VALU..." +== 032 +-- truncate_limit: 100 +create rule rtest_t4_ins2 as on insert to rtest_t4 + where new.a >= 20 and new.a < 30 do + insert into rtest_t6 values (new.a, new.b) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_t4_ins2 AS ON INSERT TO rtest_t4 WHERE ... DO INSERT INTO rtest_t6 VALUES (new...." +== 033 +-- truncate_limit: 100 +create rule rtest_t5_ins as on insert to rtest_t5 + where new.a > 15 do + insert into rtest_t7 values (new.a, new.b) +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_t5_ins AS ON INSERT TO rtest_t5 WHERE ... DO INSERT INTO rtest_t7 VALUES (new.a..." +== 034 +-- truncate_limit: 100 +create rule rtest_t6_ins as on insert to rtest_t6 + where new.a > 25 do instead + insert into rtest_t8 values (new.a, new.b) +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_t6_ins AS ON INSERT TO rtest_t6 WHERE ... DO INSTEAD INSERT INTO rtest_t8 VALUE..." +== 035 +-- truncate_limit: 100 +|-- +-- Tables and rules for the rule fire order test +|-- +-- As of PG 7.3, the rules should fire in order by name, regardless +-- of INSTEAD attributes or creation order. +|-- +create table rtest_order1 (a int4) +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_order1 (a int4)" +== 036 +-- truncate_limit: 100 +create table rtest_order2 (a int4, b int4, c text) +-- +TABLE: name="rtest_order2" schema="" table="rtest_order2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_order2 (a int4, b int4, c text)" +== 037 +-- truncate_limit: 100 +create sequence rtest_seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE rtest_seq" +== 038 +-- truncate_limit: 100 +create rule rtest_order_r3 as on insert to rtest_order1 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 3 - this should run 3rd') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_order_r3 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 VALUE..." +== 039 +-- truncate_limit: 100 +create rule rtest_order_r4 as on insert to rtest_order1 + where a < 100 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 4 - this should run 4th') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_order_r4 AS ON INSERT TO rtest_order1 WHERE ... DO INSTEAD INSERT INTO rtest_or..." +== 040 +-- truncate_limit: 100 +create rule rtest_order_r2 as on insert to rtest_order1 do + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 2 - this should run 2nd') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_order_r2 AS ON INSERT TO rtest_order1 DO INSERT INTO rtest_order2 VALUES (new.a..." +== 041 +-- truncate_limit: 100 +create rule rtest_order_r1 as on insert to rtest_order1 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 1 - this should run 1st') +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_order_r1 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 VALUE..." +== 042 +-- truncate_limit: 100 +|-- +-- Tables and rules for the instead nothing test +|-- +create table rtest_nothn1 (a int4, b text) +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_nothn1 (a int4, b text)" +== 043 +-- truncate_limit: 100 +create table rtest_nothn2 (a int4, b text) +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_nothn2 (a int4, b text)" +== 044 +-- truncate_limit: 100 +create table rtest_nothn3 (a int4, b text) +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_nothn3 (a int4, b text)" +== 045 +-- truncate_limit: 100 +create table rtest_nothn4 (a int4, b text) +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_nothn4 (a int4, b text)" +== 046 +-- truncate_limit: 100 +create rule rtest_nothn_r1 as on insert to rtest_nothn1 + where new.a >= 10 and new.a < 20 do instead nothing +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_nothn_r1 AS ON INSERT TO rtest_nothn1 WHERE ... DO INSTEAD NOTHING" +== 047 +-- truncate_limit: 100 +create rule rtest_nothn_r2 as on insert to rtest_nothn1 + where new.a >= 30 and new.a < 40 do instead nothing +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_nothn_r2 AS ON INSERT TO rtest_nothn1 WHERE ... DO INSTEAD NOTHING" +== 048 +-- truncate_limit: 100 +create rule rtest_nothn_r3 as on insert to rtest_nothn2 + where new.a >= 100 do instead + insert into rtest_nothn3 values (new.a, new.b) +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_nothn_r3 AS ON INSERT TO rtest_nothn2 WHERE ... DO INSTEAD INSERT INTO rtest_no..." +== 049 +-- truncate_limit: 100 +create rule rtest_nothn_r4 as on insert to rtest_nothn2 + do instead nothing +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rtest_nothn_r4 AS ON INSERT TO rtest_nothn2 DO INSTEAD NOTHING" +== 050 +-- truncate_limit: 100 +|-- +-- Tests on a view that is select * of a table +-- and has insert/update/delete instead rules to +-- behave close like the real table. +|-- + +|-- +-- We need test date later +|-- +insert into rtest_t2 values (1, 21) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t2 VALUES (1, 21)" +== 051 +-- truncate_limit: 100 +insert into rtest_t2 values (2, 22) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t2 VALUES (2, 22)" +== 052 +-- truncate_limit: 100 +insert into rtest_t2 values (3, 23) +-- +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t2 VALUES (3, 23)" +== 053 +-- truncate_limit: 100 +insert into rtest_t3 values (1, 31) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t3 VALUES (1, 31)" +== 054 +-- truncate_limit: 100 +insert into rtest_t3 values (2, 32) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t3 VALUES (2, 32)" +== 055 +-- truncate_limit: 100 +insert into rtest_t3 values (3, 33) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t3 VALUES (3, 33)" +== 056 +-- truncate_limit: 100 +insert into rtest_t3 values (4, 34) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t3 VALUES (4, 34)" +== 057 +-- truncate_limit: 100 +insert into rtest_t3 values (5, 35) +-- +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t3 VALUES (5, 35)" +== 058 +-- truncate_limit: 100 +-- insert values +insert into rtest_v1 values (1, 11) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 VALUES (1, 11)" +== 059 +-- truncate_limit: 100 +insert into rtest_v1 values (2, 12) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 VALUES (2, 12)" +== 060 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 061 +-- truncate_limit: 100 +-- delete with constant expression +delete from rtest_v1 where a = 1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_v1 WHERE a = 1" +== 062 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 063 +-- truncate_limit: 100 +insert into rtest_v1 values (1, 11) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 VALUES (1, 11)" +== 064 +-- truncate_limit: 100 +delete from rtest_v1 where b = 12 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_v1 WHERE b = 12" +== 065 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 066 +-- truncate_limit: 100 +insert into rtest_v1 values (2, 12) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 VALUES (2, 12)" +== 067 +-- truncate_limit: 100 +insert into rtest_v1 values (2, 13) +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 VALUES (2, 13)" +== 068 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 069 +-- truncate_limit: 100 +** Remember the delete rule on rtest_v1: It says +** DO INSTEAD DELETE FROM rtest_t1 WHERE a = old.a +** So this time both rows with a = 2 must get deleted +delete from rtest_v1 where b = 12 +-- +ERROR: syntax error at or near "**" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 070 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 071 +-- truncate_limit: 100 +delete from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_v1" +== 072 +-- truncate_limit: 100 +-- insert select +insert into rtest_v1 select * from rtest_t2 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 SELECT * FROM rtest_t2" +== 073 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 074 +-- truncate_limit: 100 +delete from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_v1" +== 075 +-- truncate_limit: 100 +-- same with swapped targetlist +insert into rtest_v1 (b, a) select b, a from rtest_t2 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 (b, a) SELECT b, a FROM rtest_t2" +== 076 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 077 +-- truncate_limit: 100 +-- now with only one target attribute +insert into rtest_v1 (a) select a from rtest_t3 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 (a) SELECT a FROM rtest_t3" +== 078 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 079 +-- truncate_limit: 100 +select * from rtest_v1 where b isnull +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1 WHERE b IS NULL" +== 080 +-- truncate_limit: 100 +-- let attribute a differ (must be done on rtest_t1 - see above) +update rtest_t1 set a = a + 10 where b isnull +-- +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_t1 SET a = a + 10 WHERE b IS NULL" +== 081 +-- truncate_limit: 100 +delete from rtest_v1 where b isnull +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_v1 WHERE b IS NULL" +== 082 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 083 +-- truncate_limit: 100 +-- now updates with constant expression +update rtest_v1 set b = 42 where a = 2 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_v1 SET b = 42 WHERE a = 2" +== 084 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 085 +-- truncate_limit: 100 +update rtest_v1 set b = 99 where b = 42 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_v1 SET b = 99 WHERE b = 42" +== 086 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 087 +-- truncate_limit: 100 +update rtest_v1 set b = 88 where b < 50 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_v1 SET b = 88 WHERE b < 50" +== 088 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 089 +-- truncate_limit: 100 +delete from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_v1" +== 090 +-- truncate_limit: 100 +insert into rtest_v1 select rtest_t2.a, rtest_t3.b + from rtest_t2, rtest_t3 + where rtest_t2.a = rtest_t3.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +FILTER: schema="" table="rtest_t2" column="a" +FILTER: schema="" table="rtest_t3" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 SELECT rtest_t2.a, rtest_t3.b FROM rtest_t2, rtest_t3 WHERE ..." +== 091 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 092 +-- truncate_limit: 100 +-- updates in a mergejoin +update rtest_v1 set b = rtest_t2.b from rtest_t2 where rtest_v1.a = rtest_t2.a +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t2" schema="" table="rtest_t2" ctx=Select +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_v1 SET b = rtest_t2.b FROM rtest_t2 WHERE rtest_v1.a = rtest_t2.a" +== 093 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 094 +-- truncate_limit: 100 +insert into rtest_v1 select * from rtest_t3 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_v1 SELECT * FROM rtest_t3" +== 095 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 096 +-- truncate_limit: 100 +update rtest_t1 set a = a + 10 where b > 30 +-- +TABLE: name="rtest_t1" schema="" table="rtest_t1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_t1 SET a = a + 10 WHERE b > 30" +== 097 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 098 +-- truncate_limit: 100 +update rtest_v1 set a = rtest_t3.a + 20 from rtest_t3 where rtest_v1.b = rtest_t3.b +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=DML +TABLE: name="rtest_t3" schema="" table="rtest_t3" ctx=Select +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_v1 SET a = rtest_t3.a + 20 FROM rtest_t3 WHERE rtest_v1.b = rtest_t3.b" +== 099 +-- truncate_limit: 100 +select * from rtest_v1 +-- +TABLE: name="rtest_v1" schema="" table="rtest_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_v1" +== 100 +-- truncate_limit: 100 +|-- +-- Test for constraint updates/deletes +|-- +insert into rtest_system values ('orion', 'Linux Jan Wieck') +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_system VALUES ('orion', 'Linux Jan Wieck')" +== 101 +-- truncate_limit: 100 +insert into rtest_system values ('notjw', 'WinNT Jan Wieck (notebook)') +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_system VALUES ('notjw', 'WinNT Jan Wieck (notebook)')" +== 102 +-- truncate_limit: 100 +insert into rtest_system values ('neptun', 'Fileserver') +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_system VALUES ('neptun', 'Fileserver')" +== 103 +-- truncate_limit: 100 +insert into rtest_interface values ('orion', 'eth0') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_interface VALUES ('orion', 'eth0')" +== 104 +-- truncate_limit: 100 +insert into rtest_interface values ('orion', 'eth1') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_interface VALUES ('orion', 'eth1')" +== 105 +-- truncate_limit: 100 +insert into rtest_interface values ('notjw', 'eth0') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_interface VALUES ('notjw', 'eth0')" +== 106 +-- truncate_limit: 100 +insert into rtest_interface values ('neptun', 'eth0') +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_interface VALUES ('neptun', 'eth0')" +== 107 +-- truncate_limit: 100 +insert into rtest_person values ('jw', 'Jan Wieck') +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_person VALUES ('jw', 'Jan Wieck')" +== 108 +-- truncate_limit: 100 +insert into rtest_person values ('bm', 'Bruce Momjian') +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_person VALUES ('bm', 'Bruce Momjian')" +== 109 +-- truncate_limit: 100 +insert into rtest_admin values ('jw', 'orion') +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_admin VALUES ('jw', 'orion')" +== 110 +-- truncate_limit: 100 +insert into rtest_admin values ('jw', 'notjw') +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_admin VALUES ('jw', 'notjw')" +== 111 +-- truncate_limit: 100 +insert into rtest_admin values ('bm', 'neptun') +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_admin VALUES ('bm', 'neptun')" +== 112 +-- truncate_limit: 100 +update rtest_system set sysname = 'pluto' where sysname = 'neptun' +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_system SET sysname = 'pluto' WHERE sysname = 'neptun'" +== 113 +-- truncate_limit: 100 +select * from rtest_interface +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_interface" +== 114 +-- truncate_limit: 100 +select * from rtest_admin +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_admin" +== 115 +-- truncate_limit: 100 +update rtest_person set pname = 'jwieck' where pdesc = 'Jan Wieck' +-- +TABLE: name="rtest_person" schema="" table="rtest_person" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_person SET pname = 'jwieck' WHERE pdesc = 'Jan Wieck'" +== 116 +-- truncate_limit: 100 +-- Note: use ORDER BY here to ensure consistent output across all systems. +-- The above UPDATE affects two rows with equal keys, so they could be +-- updated in either order depending on the whim of the local qsort(). + +select * from rtest_admin order by pname, sysname +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_admin ORDER BY pname, sysname" +== 117 +-- truncate_limit: 100 +delete from rtest_system where sysname = 'orion' +-- +TABLE: name="rtest_system" schema="" table="rtest_system" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_system WHERE sysname = 'orion'" +== 118 +-- truncate_limit: 100 +select * from rtest_interface +-- +TABLE: name="rtest_interface" schema="" table="rtest_interface" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_interface" +== 119 +-- truncate_limit: 100 +select * from rtest_admin +-- +TABLE: name="rtest_admin" schema="" table="rtest_admin" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_admin" +== 120 +-- truncate_limit: 100 +|-- +-- Rule qualification test +|-- +insert into rtest_emp values ('wiecc', '5000.00') +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_emp VALUES ('wiecc', '5000.00')" +== 121 +-- truncate_limit: 100 +insert into rtest_emp values ('gates', '80000.00') +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_emp VALUES ('gates', '80000.00')" +== 122 +-- truncate_limit: 100 +update rtest_emp set ename = 'wiecx' where ename = 'wiecc' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_emp SET ename = 'wiecx' WHERE ename = 'wiecc'" +== 123 +-- truncate_limit: 100 +update rtest_emp set ename = 'wieck', salary = '6000.00' where ename = 'wiecx' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_emp SET ename = 'wieck', salary = '6000.00' WHERE ename = 'wiecx'" +== 124 +-- truncate_limit: 100 +update rtest_emp set salary = '7000.00' where ename = 'wieck' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_emp SET salary = '7000.00' WHERE ename = 'wieck'" +== 125 +-- truncate_limit: 100 +delete from rtest_emp where ename = 'gates' +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_emp WHERE ename = 'gates'" +== 126 +-- truncate_limit: 100 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM rtest_emplog ORDER BY ename, action, newsal" +== 127 +-- truncate_limit: 100 +insert into rtest_empmass values ('meyer', '4000.00') +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_empmass VALUES ('meyer', '4000.00')" +== 128 +-- truncate_limit: 100 +insert into rtest_empmass values ('maier', '5000.00') +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_empmass VALUES ('maier', '5000.00')" +== 129 +-- truncate_limit: 100 +insert into rtest_empmass values ('mayr', '6000.00') +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_empmass VALUES ('mayr', '6000.00')" +== 130 +-- truncate_limit: 100 +insert into rtest_emp select * from rtest_empmass +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_emp SELECT * FROM rtest_empmass" +== 131 +-- truncate_limit: 100 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM rtest_emplog ORDER BY ename, action, newsal" +== 132 +-- truncate_limit: 100 +update rtest_empmass set salary = salary + '1000.00' +-- +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_empmass SET salary = salary + '1000.00'" +== 133 +-- truncate_limit: 100 +update rtest_emp set salary = rtest_empmass.salary from rtest_empmass where rtest_emp.ename = rtest_empmass.ename +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=Select +STMT: UpdateStmt +TRUNCATED: "UPDATE rtest_emp SET salary = rtest_empmass.salary FROM rtest_empmass WHERE ..." +== 134 +-- truncate_limit: 100 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM rtest_emplog ORDER BY ename, action, newsal" +== 135 +-- truncate_limit: 100 +delete from rtest_emp using rtest_empmass where rtest_emp.ename = rtest_empmass.ename +-- +TABLE: name="rtest_emp" schema="" table="rtest_emp" ctx=DML +TABLE: name="rtest_empmass" schema="" table="rtest_empmass" ctx=Select +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_emp USING rtest_empmass WHERE rtest_emp.ename = rtest_empmass.ename" +== 136 +-- truncate_limit: 100 +select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal +-- +TABLE: name="rtest_emplog" schema="" table="rtest_emplog" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM rtest_emplog ORDER BY ename, action, newsal" +== 137 +-- truncate_limit: 100 +|-- +-- Multiple cascaded qualified instead rule test +|-- +insert into rtest_t4 values (1, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (1, 'Record should go to rtest_t4')" +== 138 +-- truncate_limit: 100 +insert into rtest_t4 values (2, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (2, 'Record should go to rtest_t4')" +== 139 +-- truncate_limit: 100 +insert into rtest_t4 values (10, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (10, 'Record should go to rtest_t5')" +== 140 +-- truncate_limit: 100 +insert into rtest_t4 values (15, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (15, 'Record should go to rtest_t5')" +== 141 +-- truncate_limit: 100 +insert into rtest_t4 values (19, 'Record should go to rtest_t5 and t7') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (19, 'Record should go to rtest_t5 and t7')" +== 142 +-- truncate_limit: 100 +insert into rtest_t4 values (20, 'Record should go to rtest_t4 and t6') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (20, 'Record should go to rtest_t4 and t6')" +== 143 +-- truncate_limit: 100 +insert into rtest_t4 values (26, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (26, 'Record should go to rtest_t4 and t8')" +== 144 +-- truncate_limit: 100 +insert into rtest_t4 values (28, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (28, 'Record should go to rtest_t4 and t8')" +== 145 +-- truncate_limit: 100 +insert into rtest_t4 values (30, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (30, 'Record should go to rtest_t4')" +== 146 +-- truncate_limit: 100 +insert into rtest_t4 values (40, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 VALUES (40, 'Record should go to rtest_t4')" +== 147 +-- truncate_limit: 100 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t4" +== 148 +-- truncate_limit: 100 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t5" +== 149 +-- truncate_limit: 100 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t6" +== 150 +-- truncate_limit: 100 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t7" +== 151 +-- truncate_limit: 100 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t8" +== 152 +-- truncate_limit: 100 +delete from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_t4" +== 153 +-- truncate_limit: 100 +delete from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_t5" +== 154 +-- truncate_limit: 100 +delete from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_t6" +== 155 +-- truncate_limit: 100 +delete from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_t7" +== 156 +-- truncate_limit: 100 +delete from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_t8" +== 157 +-- truncate_limit: 100 +insert into rtest_t9 values (1, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (1, 'Record should go to rtest_t4')" +== 158 +-- truncate_limit: 100 +insert into rtest_t9 values (2, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (2, 'Record should go to rtest_t4')" +== 159 +-- truncate_limit: 100 +insert into rtest_t9 values (10, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (10, 'Record should go to rtest_t5')" +== 160 +-- truncate_limit: 100 +insert into rtest_t9 values (15, 'Record should go to rtest_t5') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (15, 'Record should go to rtest_t5')" +== 161 +-- truncate_limit: 100 +insert into rtest_t9 values (19, 'Record should go to rtest_t5 and t7') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (19, 'Record should go to rtest_t5 and t7')" +== 162 +-- truncate_limit: 100 +insert into rtest_t9 values (20, 'Record should go to rtest_t4 and t6') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (20, 'Record should go to rtest_t4 and t6')" +== 163 +-- truncate_limit: 100 +insert into rtest_t9 values (26, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (26, 'Record should go to rtest_t4 and t8')" +== 164 +-- truncate_limit: 100 +insert into rtest_t9 values (28, 'Record should go to rtest_t4 and t8') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (28, 'Record should go to rtest_t4 and t8')" +== 165 +-- truncate_limit: 100 +insert into rtest_t9 values (30, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (30, 'Record should go to rtest_t4')" +== 166 +-- truncate_limit: 100 +insert into rtest_t9 values (40, 'Record should go to rtest_t4') +-- +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t9 VALUES (40, 'Record should go to rtest_t4')" +== 167 +-- truncate_limit: 100 +insert into rtest_t4 select * from rtest_t9 where a < 20 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 SELECT * FROM rtest_t9 WHERE a < 20" +== 168 +-- truncate_limit: 100 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t4" +== 169 +-- truncate_limit: 100 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t5" +== 170 +-- truncate_limit: 100 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t6" +== 171 +-- truncate_limit: 100 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t7" +== 172 +-- truncate_limit: 100 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t8" +== 173 +-- truncate_limit: 100 +insert into rtest_t4 select * from rtest_t9 where b ~ 'and t8' +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=Select +FILTER: schema="" table="" column="b" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 SELECT * FROM rtest_t9 WHERE b ~ 'and t8'" +== 174 +-- truncate_limit: 100 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t4" +== 175 +-- truncate_limit: 100 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t5" +== 176 +-- truncate_limit: 100 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t6" +== 177 +-- truncate_limit: 100 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t7" +== 178 +-- truncate_limit: 100 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t8" +== 179 +-- truncate_limit: 100 +insert into rtest_t4 select a + 1, b from rtest_t9 where a in (20, 30, 40) +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=DML +TABLE: name="rtest_t9" schema="" table="rtest_t9" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_t4 SELECT a + 1, b FROM rtest_t9 WHERE a IN (20, 30, 40)" +== 180 +-- truncate_limit: 100 +select * from rtest_t4 +-- +TABLE: name="rtest_t4" schema="" table="rtest_t4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t4" +== 181 +-- truncate_limit: 100 +select * from rtest_t5 +-- +TABLE: name="rtest_t5" schema="" table="rtest_t5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t5" +== 182 +-- truncate_limit: 100 +select * from rtest_t6 +-- +TABLE: name="rtest_t6" schema="" table="rtest_t6" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t6" +== 183 +-- truncate_limit: 100 +select * from rtest_t7 +-- +TABLE: name="rtest_t7" schema="" table="rtest_t7" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t7" +== 184 +-- truncate_limit: 100 +select * from rtest_t8 +-- +TABLE: name="rtest_t8" schema="" table="rtest_t8" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_t8" +== 185 +-- truncate_limit: 100 +|-- +-- Check that the ordering of rules fired is correct +|-- +insert into rtest_order1 values (1) +-- +TABLE: name="rtest_order1" schema="" table="rtest_order1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_order1 VALUES (1)" +== 186 +-- truncate_limit: 100 +select * from rtest_order2 +-- +TABLE: name="rtest_order2" schema="" table="rtest_order2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_order2" +== 187 +-- truncate_limit: 100 +|-- +-- Check if instead nothing w/without qualification works +|-- +insert into rtest_nothn1 values (1, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (1, 'want this')" +== 188 +-- truncate_limit: 100 +insert into rtest_nothn1 values (2, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (2, 'want this')" +== 189 +-- truncate_limit: 100 +insert into rtest_nothn1 values (10, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (10, 'don''t want this')" +== 190 +-- truncate_limit: 100 +insert into rtest_nothn1 values (19, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (19, 'don''t want this')" +== 191 +-- truncate_limit: 100 +insert into rtest_nothn1 values (20, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (20, 'want this')" +== 192 +-- truncate_limit: 100 +insert into rtest_nothn1 values (29, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (29, 'want this')" +== 193 +-- truncate_limit: 100 +insert into rtest_nothn1 values (30, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (30, 'don''t want this')" +== 194 +-- truncate_limit: 100 +insert into rtest_nothn1 values (39, 'don''t want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (39, 'don''t want this')" +== 195 +-- truncate_limit: 100 +insert into rtest_nothn1 values (40, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (40, 'want this')" +== 196 +-- truncate_limit: 100 +insert into rtest_nothn1 values (50, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (50, 'want this')" +== 197 +-- truncate_limit: 100 +insert into rtest_nothn1 values (60, 'want this') +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 VALUES (60, 'want this')" +== 198 +-- truncate_limit: 100 +select * from rtest_nothn1 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_nothn1" +== 199 +-- truncate_limit: 100 +insert into rtest_nothn2 values (10, 'too small') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn2 VALUES (10, 'too small')" +== 200 +-- truncate_limit: 100 +insert into rtest_nothn2 values (50, 'too small') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn2 VALUES (50, 'too small')" +== 201 +-- truncate_limit: 100 +insert into rtest_nothn2 values (100, 'OK') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn2 VALUES (100, 'OK')" +== 202 +-- truncate_limit: 100 +insert into rtest_nothn2 values (200, 'OK') +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn2 VALUES (200, 'OK')" +== 203 +-- truncate_limit: 100 +select * from rtest_nothn2 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_nothn2" +== 204 +-- truncate_limit: 100 +select * from rtest_nothn3 +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_nothn3" +== 205 +-- truncate_limit: 100 +delete from rtest_nothn1 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_nothn1" +== 206 +-- truncate_limit: 100 +delete from rtest_nothn2 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_nothn2" +== 207 +-- truncate_limit: 100 +delete from rtest_nothn3 +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_nothn3" +== 208 +-- truncate_limit: 100 +insert into rtest_nothn4 values (1, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (1, 'want this')" +== 209 +-- truncate_limit: 100 +insert into rtest_nothn4 values (2, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (2, 'want this')" +== 210 +-- truncate_limit: 100 +insert into rtest_nothn4 values (10, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (10, 'don''t want this')" +== 211 +-- truncate_limit: 100 +insert into rtest_nothn4 values (19, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (19, 'don''t want this')" +== 212 +-- truncate_limit: 100 +insert into rtest_nothn4 values (20, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (20, 'want this')" +== 213 +-- truncate_limit: 100 +insert into rtest_nothn4 values (29, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (29, 'want this')" +== 214 +-- truncate_limit: 100 +insert into rtest_nothn4 values (30, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (30, 'don''t want this')" +== 215 +-- truncate_limit: 100 +insert into rtest_nothn4 values (39, 'don''t want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (39, 'don''t want this')" +== 216 +-- truncate_limit: 100 +insert into rtest_nothn4 values (40, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (40, 'want this')" +== 217 +-- truncate_limit: 100 +insert into rtest_nothn4 values (50, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (50, 'want this')" +== 218 +-- truncate_limit: 100 +insert into rtest_nothn4 values (60, 'want this') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (60, 'want this')" +== 219 +-- truncate_limit: 100 +insert into rtest_nothn1 select * from rtest_nothn4 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=DML +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn1 SELECT * FROM rtest_nothn4" +== 220 +-- truncate_limit: 100 +select * from rtest_nothn1 +-- +TABLE: name="rtest_nothn1" schema="" table="rtest_nothn1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_nothn1" +== 221 +-- truncate_limit: 100 +delete from rtest_nothn4 +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_nothn4" +== 222 +-- truncate_limit: 100 +insert into rtest_nothn4 values (10, 'too small') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (10, 'too small')" +== 223 +-- truncate_limit: 100 +insert into rtest_nothn4 values (50, 'too small') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (50, 'too small')" +== 224 +-- truncate_limit: 100 +insert into rtest_nothn4 values (100, 'OK') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (100, 'OK')" +== 225 +-- truncate_limit: 100 +insert into rtest_nothn4 values (200, 'OK') +-- +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn4 VALUES (200, 'OK')" +== 226 +-- truncate_limit: 100 +insert into rtest_nothn2 select * from rtest_nothn4 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=DML +TABLE: name="rtest_nothn4" schema="" table="rtest_nothn4" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_nothn2 SELECT * FROM rtest_nothn4" +== 227 +-- truncate_limit: 100 +select * from rtest_nothn2 +-- +TABLE: name="rtest_nothn2" schema="" table="rtest_nothn2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_nothn2" +== 228 +-- truncate_limit: 100 +select * from rtest_nothn3 +-- +TABLE: name="rtest_nothn3" schema="" table="rtest_nothn3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_nothn3" +== 229 +-- truncate_limit: 100 +create table rtest_view1 (a int4, b text, v bool) +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_view1 (a int4, b text, v bool)" +== 230 +-- truncate_limit: 100 +create table rtest_view2 (a int4) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_view2 (a int4)" +== 231 +-- truncate_limit: 100 +create table rtest_view3 (a int4, b text) +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_view3 (a int4, b text)" +== 232 +-- truncate_limit: 100 +create table rtest_view4 (a int4, b text, c int4) +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_view4 (a int4, b text, c int4)" +== 233 +-- truncate_limit: 100 +create view rtest_vview1 as select a, b from rtest_view1 X + where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a) +-- +TABLE: name="rtest_vview1" schema="" table="rtest_vview1" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=Select +ALIAS: "x"="rtest_view1" +ALIAS: "y"="rtest_view2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="y" column="a" +FILTER: schema="" table="x" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rtest_vview1 AS SELECT a, b FROM rtest_view1 x WHERE 0 < (SELECT count(*) FROM rtest_..." +== 234 +-- truncate_limit: 100 +create view rtest_vview2 as select a, b from rtest_view1 where v +-- +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +FILTER: schema="" table="" column="v" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rtest_vview2 AS SELECT a, b FROM rtest_view1 WHERE v" +== 235 +-- truncate_limit: 100 +create view rtest_vview3 as select a, b from rtest_vview2 X + where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a) +-- +TABLE: name="rtest_vview3" schema="" table="rtest_vview3" ctx=DDL +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=Select +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=Select +ALIAS: "x"="rtest_vview2" +ALIAS: "y"="rtest_view2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="y" column="a" +FILTER: schema="" table="x" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rtest_vview3 AS SELECT a, b FROM rtest_vview2 x WHERE 0 < (SELECT count(*) FROM rtest..." +== 236 +-- truncate_limit: 100 +create view rtest_vview4 as select X.a, X.b, count(Y.a) as refcount + from rtest_view1 X, rtest_view2 Y + where X.a = Y.a + group by X.a, X.b +-- +TABLE: name="rtest_vview4" schema="" table="rtest_vview4" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=Select +ALIAS: "x"="rtest_view1" +ALIAS: "y"="rtest_view2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rtest_vview4 AS SELECT x.a, x.b, count(y.a) AS refcount FROM rtest_view1 x, rtest_vie..." +== 237 +-- truncate_limit: 100 +create function rtest_viewfunc1(int4) returns int4 as + 'select count(*)::int4 from rtest_view2 where a = $1' + language sql +-- +FUNCTION: name="rtest_viewfunc1" function="rtest_viewfunc1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rtest_viewfunc1(int4) RETURNS int4 AS $$select count(*)::int4 from rtest_view2 wh..." +== 238 +-- truncate_limit: 100 +create view rtest_vview5 as select a, b, rtest_viewfunc1(a) as refcount + from rtest_view1 +-- +TABLE: name="rtest_vview5" schema="" table="rtest_vview5" ctx=DDL +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=Select +FUNCTION: name="rtest_viewfunc1" function="rtest_viewfunc1" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rtest_vview5 AS SELECT a, b, rtest_viewfunc1(a) AS refcount FROM rtest_view1" +== 239 +-- truncate_limit: 100 +insert into rtest_view1 values (1, 'item 1', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (1, 'item 1', 't')" +== 240 +-- truncate_limit: 100 +insert into rtest_view1 values (2, 'item 2', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (2, 'item 2', 't')" +== 241 +-- truncate_limit: 100 +insert into rtest_view1 values (3, 'item 3', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (3, 'item 3', 't')" +== 242 +-- truncate_limit: 100 +insert into rtest_view1 values (4, 'item 4', 'f') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (4, 'item 4', 'f')" +== 243 +-- truncate_limit: 100 +insert into rtest_view1 values (5, 'item 5', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (5, 'item 5', 't')" +== 244 +-- truncate_limit: 100 +insert into rtest_view1 values (6, 'item 6', 'f') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (6, 'item 6', 'f')" +== 245 +-- truncate_limit: 100 +insert into rtest_view1 values (7, 'item 7', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (7, 'item 7', 't')" +== 246 +-- truncate_limit: 100 +insert into rtest_view1 values (8, 'item 8', 't') +-- +TABLE: name="rtest_view1" schema="" table="rtest_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view1 VALUES (8, 'item 8', 't')" +== 247 +-- truncate_limit: 100 +insert into rtest_view2 values (2) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (2)" +== 248 +-- truncate_limit: 100 +insert into rtest_view2 values (2) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (2)" +== 249 +-- truncate_limit: 100 +insert into rtest_view2 values (4) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (4)" +== 250 +-- truncate_limit: 100 +insert into rtest_view2 values (5) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (5)" +== 251 +-- truncate_limit: 100 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (7)" +== 252 +-- truncate_limit: 100 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (7)" +== 253 +-- truncate_limit: 100 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (7)" +== 254 +-- truncate_limit: 100 +insert into rtest_view2 values (7) +-- +TABLE: name="rtest_view2" schema="" table="rtest_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view2 VALUES (7)" +== 255 +-- truncate_limit: 100 +select * from rtest_vview1 +-- +TABLE: name="rtest_vview1" schema="" table="rtest_vview1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_vview1" +== 256 +-- truncate_limit: 100 +select * from rtest_vview2 +-- +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_vview2" +== 257 +-- truncate_limit: 100 +select * from rtest_vview3 +-- +TABLE: name="rtest_vview3" schema="" table="rtest_vview3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_vview3" +== 258 +-- truncate_limit: 100 +select * from rtest_vview4 order by a, b +-- +TABLE: name="rtest_vview4" schema="" table="rtest_vview4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_vview4 ORDER BY a, b" +== 259 +-- truncate_limit: 100 +select * from rtest_vview5 +-- +TABLE: name="rtest_vview5" schema="" table="rtest_vview5" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_vview5" +== 260 +-- truncate_limit: 100 +insert into rtest_view3 select * from rtest_vview1 where a < 7 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +TABLE: name="rtest_vview1" schema="" table="rtest_vview1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view3 SELECT * FROM rtest_vview1 WHERE a < 7" +== 261 +-- truncate_limit: 100 +select * from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_view3" +== 262 +-- truncate_limit: 100 +delete from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_view3" +== 263 +-- truncate_limit: 100 +insert into rtest_view3 select * from rtest_vview2 where a != 5 and b !~ '2' +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +TABLE: name="rtest_vview2" schema="" table="rtest_vview2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view3 SELECT * FROM rtest_vview2 WHERE a <> 5 AND b !~ '2'" +== 264 +-- truncate_limit: 100 +select * from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_view3" +== 265 +-- truncate_limit: 100 +delete from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_view3" +== 266 +-- truncate_limit: 100 +insert into rtest_view3 select * from rtest_vview3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +TABLE: name="rtest_vview3" schema="" table="rtest_vview3" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view3 SELECT * FROM rtest_vview3" +== 267 +-- truncate_limit: 100 +select * from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_view3" +== 268 +-- truncate_limit: 100 +delete from rtest_view3 +-- +TABLE: name="rtest_view3" schema="" table="rtest_view3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_view3" +== 269 +-- truncate_limit: 100 +insert into rtest_view4 select * from rtest_vview4 where 3 > refcount +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +TABLE: name="rtest_vview4" schema="" table="rtest_vview4" ctx=Select +FILTER: schema="" table="" column="refcount" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view4 SELECT * FROM rtest_vview4 WHERE 3 > refcount" +== 270 +-- truncate_limit: 100 +select * from rtest_view4 order by a, b +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_view4 ORDER BY a, b" +== 271 +-- truncate_limit: 100 +delete from rtest_view4 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_view4" +== 272 +-- truncate_limit: 100 +insert into rtest_view4 select * from rtest_vview5 where a > 2 and refcount = 0 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +TABLE: name="rtest_vview5" schema="" table="rtest_vview5" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="refcount" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_view4 SELECT * FROM rtest_vview5 WHERE a > 2 AND refcount = 0" +== 273 +-- truncate_limit: 100 +select * from rtest_view4 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_view4" +== 274 +-- truncate_limit: 100 +delete from rtest_view4 +-- +TABLE: name="rtest_view4" schema="" table="rtest_view4" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rtest_view4" +== 275 +-- truncate_limit: 100 +|-- +-- Test for computations in views +|-- +create table rtest_comp ( + part text, + unit char(4), + size float +) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_comp (part text, unit char(4), size double precision)" +== 276 +-- truncate_limit: 100 +create table rtest_unitfact ( + unit char(4), + factor float +) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rtest_unitfact (unit char(4), factor double precision)" +== 277 +-- truncate_limit: 100 +create view rtest_vcomp as + select X.part, (X.size * Y.factor) as size_in_cm + from rtest_comp X, rtest_unitfact Y + where X.unit = Y.unit +-- +TABLE: name="rtest_vcomp" schema="" table="rtest_vcomp" ctx=DDL +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=Select +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=Select +ALIAS: "x"="rtest_comp" +ALIAS: "y"="rtest_unitfact" +FILTER: schema="" table="x" column="unit" +FILTER: schema="" table="y" column="unit" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rtest_vcomp AS SELECT x.part, x.size * y.factor AS size_in_cm FROM rtest_comp x, rtes..." +== 278 +-- truncate_limit: 100 +insert into rtest_unitfact values ('m', 100.0) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_unitfact VALUES ('m', 100.0)" +== 279 +-- truncate_limit: 100 +insert into rtest_unitfact values ('cm', 1.0) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_unitfact VALUES ('cm', 1.0)" +== 280 +-- truncate_limit: 100 +insert into rtest_unitfact values ('inch', 2.54) +-- +TABLE: name="rtest_unitfact" schema="" table="rtest_unitfact" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_unitfact VALUES ('inch', 2.54)" +== 281 +-- truncate_limit: 100 +insert into rtest_comp values ('p1', 'm', 5.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_comp VALUES ('p1', 'm', 5.0)" +== 282 +-- truncate_limit: 100 +insert into rtest_comp values ('p2', 'm', 3.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_comp VALUES ('p2', 'm', 3.0)" +== 283 +-- truncate_limit: 100 +insert into rtest_comp values ('p3', 'cm', 5.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_comp VALUES ('p3', 'cm', 5.0)" +== 284 +-- truncate_limit: 100 +insert into rtest_comp values ('p4', 'cm', 15.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_comp VALUES ('p4', 'cm', 15.0)" +== 285 +-- truncate_limit: 100 +insert into rtest_comp values ('p5', 'inch', 7.0) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_comp VALUES ('p5', 'inch', 7.0)" +== 286 +-- truncate_limit: 100 +insert into rtest_comp values ('p6', 'inch', 4.4) +-- +TABLE: name="rtest_comp" schema="" table="rtest_comp" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rtest_comp VALUES ('p6', 'inch', 4.4)" +== 287 +-- truncate_limit: 100 +select * from rtest_vcomp order by part +-- +TABLE: name="rtest_vcomp" schema="" table="rtest_vcomp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_vcomp ORDER BY part" +== 288 +-- truncate_limit: 100 +select * from rtest_vcomp where size_in_cm > 10.0 order by size_in_cm using > +-- +TABLE: name="rtest_vcomp" schema="" table="rtest_vcomp" ctx=Select +FILTER: schema="" table="" column="size_in_cm" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rtest_vcomp WHERE size_in_cm > 10.0 ORDER BY size_in_cm USING >" +== 289 +-- truncate_limit: 100 +|-- +-- In addition run the (slightly modified) queries from the +-- programmers manual section on the rule system. +|-- +CREATE TABLE shoe_data ( + shoename char(10), -- primary key + sh_avail integer, -- available # of pairs + slcolor char(10), -- preferred shoelace color + slminlen float, -- minimum shoelace length + slmaxlen float, -- maximum shoelace length + slunit char(8) -- length unit +) +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE shoe_data (shoename char(10), sh_avail int, slcolor char(10), slminlen double precis..." +== 290 +-- truncate_limit: 100 +CREATE TABLE shoelace_data ( + sl_name char(10), -- primary key + sl_avail integer, -- available # of pairs + sl_color char(10), -- shoelace color + sl_len float, -- shoelace length + sl_unit char(8) -- length unit +) +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE shoelace_data (sl_name char(10), sl_avail int, sl_color char(10), sl_len double prec..." +== 291 +-- truncate_limit: 100 +CREATE TABLE unit ( + un_name char(8), -- the primary key + un_fact float -- factor to transform to cm +) +-- +TABLE: name="unit" schema="" table="unit" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unit (un_name char(8), un_fact double precision)" +== 292 +-- truncate_limit: 100 +CREATE VIEW shoe AS + SELECT sh.shoename, + sh.sh_avail, + sh.slcolor, + sh.slminlen, + sh.slminlen * un.un_fact AS slminlen_cm, + sh.slmaxlen, + sh.slmaxlen * un.un_fact AS slmaxlen_cm, + sh.slunit + FROM shoe_data sh, unit un + WHERE sh.slunit = un.un_name +-- +TABLE: name="shoe" schema="" table="shoe" ctx=DDL +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=Select +TABLE: name="unit" schema="" table="unit" ctx=Select +ALIAS: "sh"="shoe_data" +ALIAS: "un"="unit" +FILTER: schema="" table="sh" column="slunit" +FILTER: schema="" table="un" column="un_name" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW shoe AS SELECT sh.shoename, sh.sh_avail, sh.slcolor, sh.slminlen, sh.slminlen * un.un..." +== 293 +-- truncate_limit: 100 +CREATE VIEW shoelace AS + SELECT s.sl_name, + s.sl_avail, + s.sl_color, + s.sl_len, + s.sl_unit, + s.sl_len * u.un_fact AS sl_len_cm + FROM shoelace_data s, unit u + WHERE s.sl_unit = u.un_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=Select +TABLE: name="unit" schema="" table="unit" ctx=Select +ALIAS: "s"="shoelace_data" +ALIAS: "u"="unit" +FILTER: schema="" table="s" column="sl_unit" +FILTER: schema="" table="u" column="un_name" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW shoelace AS SELECT s.sl_name, s.sl_avail, s.sl_color, s.sl_len, s.sl_unit, s.sl_len *..." +== 294 +-- truncate_limit: 100 +CREATE VIEW shoe_ready AS + SELECT rsh.shoename, + rsh.sh_avail, + rsl.sl_name, + rsl.sl_avail, + int4smaller(rsh.sh_avail, rsl.sl_avail) AS total_avail + FROM shoe rsh, shoelace rsl + WHERE rsl.sl_color = rsh.slcolor + AND rsl.sl_len_cm >= rsh.slminlen_cm + AND rsl.sl_len_cm <= rsh.slmaxlen_cm +-- +TABLE: name="shoe_ready" schema="" table="shoe_ready" ctx=DDL +TABLE: name="shoe" schema="" table="shoe" ctx=Select +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +ALIAS: "rsh"="shoe" +ALIAS: "rsl"="shoelace" +FUNCTION: name="int4smaller" function="int4smaller" schema="" ctx=Call +FILTER: schema="" table="rsl" column="sl_color" +FILTER: schema="" table="rsh" column="slcolor" +FILTER: schema="" table="rsl" column="sl_len_cm" +FILTER: schema="" table="rsh" column="slminlen_cm" +FILTER: schema="" table="rsl" column="sl_len_cm" +FILTER: schema="" table="rsh" column="slmaxlen_cm" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW shoe_ready AS SELECT rsh.shoename, rsh.sh_avail, rsl.sl_name, rsl.sl_avail, int4small..." +== 295 +-- truncate_limit: 100 +INSERT INTO unit VALUES ('cm', 1.0) +-- +TABLE: name="unit" schema="" table="unit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unit VALUES ('cm', 1.0)" +== 296 +-- truncate_limit: 100 +INSERT INTO unit VALUES ('m', 100.0) +-- +TABLE: name="unit" schema="" table="unit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unit VALUES ('m', 100.0)" +== 297 +-- truncate_limit: 100 +INSERT INTO unit VALUES ('inch', 2.54) +-- +TABLE: name="unit" schema="" table="unit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO unit VALUES ('inch', 2.54)" +== 298 +-- truncate_limit: 100 +INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm')" +== 299 +-- truncate_limit: 100 +INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch')" +== 300 +-- truncate_limit: 100 +INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm')" +== 301 +-- truncate_limit: 100 +INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch') +-- +TABLE: name="shoe_data" schema="" table="shoe_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch')" +== 302 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm')" +== 303 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm')" +== 304 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0, 'inch')" +== 305 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0, 'inch')" +== 306 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0, 'm')" +== 307 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9, 'm')" +== 308 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60, 'cm')" +== 309 +-- truncate_limit: 100 +INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch') +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40, 'inch')" +== 310 +-- truncate_limit: 100 +-- SELECTs in doc +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace ORDER BY sl_name" +== 311 +-- truncate_limit: 100 +SELECT * FROM shoe_ready WHERE total_avail >= 2 ORDER BY 1 +-- +TABLE: name="shoe_ready" schema="" table="shoe_ready" ctx=Select +FILTER: schema="" table="" column="total_avail" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoe_ready WHERE total_avail >= 2 ORDER BY 1" +== 312 +-- truncate_limit: 100 +CREATE TABLE shoelace_log ( + sl_name char(10), -- shoelace changed + sl_avail integer, -- new available value + log_who name, -- who did it + log_when timestamp -- when + ) +-- +TABLE: name="shoelace_log" schema="" table="shoelace_log" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE shoelace_log (sl_name char(10), sl_avail int, log_who name, log_when timestamp)" +== 313 +-- truncate_limit: 100 +-- Want "log_who" to be CURRENT_USER, +-- but that is non-portable for the regression test +-- - thomas 1999-02-21 + + CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data + WHERE NEW.sl_avail != OLD.sl_avail + DO INSERT INTO shoelace_log VALUES ( + NEW.sl_name, + NEW.sl_avail, + 'Al Bundy', + 'epoch' + ) +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE ... DO INSERT INTO shoelace_log VALU..." +== 314 +-- truncate_limit: 100 +UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7' +-- +TABLE: name="shoelace_data" schema="" table="shoelace_data" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7'" +== 315 +-- truncate_limit: 100 +SELECT * FROM shoelace_log +-- +TABLE: name="shoelace_log" schema="" table="shoelace_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace_log" +== 316 +-- truncate_limit: 100 +CREATE RULE shoelace_ins AS ON INSERT TO shoelace + DO INSTEAD + INSERT INTO shoelace_data VALUES ( + NEW.sl_name, + NEW.sl_avail, + NEW.sl_color, + NEW.sl_len, + NEW.sl_unit) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE shoelace_ins AS ON INSERT TO shoelace DO INSTEAD INSERT INTO shoelace_data VALUES (ne..." +== 317 +-- truncate_limit: 100 +CREATE RULE shoelace_upd AS ON UPDATE TO shoelace + DO INSTEAD + UPDATE shoelace_data SET + sl_name = NEW.sl_name, + sl_avail = NEW.sl_avail, + sl_color = NEW.sl_color, + sl_len = NEW.sl_len, + sl_unit = NEW.sl_unit + WHERE sl_name = OLD.sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE shoelace_upd AS ON UPDATE TO shoelace DO INSTEAD UPDATE shoelace_data SET sl_name = n..." +== 318 +-- truncate_limit: 100 +CREATE RULE shoelace_del AS ON DELETE TO shoelace + DO INSTEAD + DELETE FROM shoelace_data + WHERE sl_name = OLD.sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE shoelace_del AS ON DELETE TO shoelace DO INSTEAD DELETE FROM shoelace_data WHERE sl_n..." +== 319 +-- truncate_limit: 100 +CREATE TABLE shoelace_arrive ( + arr_name char(10), + arr_quant integer + ) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE shoelace_arrive (arr_name char(10), arr_quant int)" +== 320 +-- truncate_limit: 100 +CREATE TABLE shoelace_ok ( + ok_name char(10), + ok_quant integer + ) +-- +TABLE: name="shoelace_ok" schema="" table="shoelace_ok" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE shoelace_ok (ok_name char(10), ok_quant int)" +== 321 +-- truncate_limit: 100 +CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok + DO INSTEAD + UPDATE shoelace SET + sl_avail = sl_avail + NEW.ok_quant + WHERE sl_name = NEW.ok_name +-- +TABLE: name="shoelace_ok" schema="" table="shoelace_ok" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok DO INSTEAD UPDATE shoelace SET sl_avail =..." +== 322 +-- truncate_limit: 100 +INSERT INTO shoelace_arrive VALUES ('sl3', 10) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_arrive VALUES ('sl3', 10)" +== 323 +-- truncate_limit: 100 +INSERT INTO shoelace_arrive VALUES ('sl6', 20) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_arrive VALUES ('sl6', 20)" +== 324 +-- truncate_limit: 100 +INSERT INTO shoelace_arrive VALUES ('sl8', 20) +-- +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_arrive VALUES ('sl8', 20)" +== 325 +-- truncate_limit: 100 +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace ORDER BY sl_name" +== 326 +-- truncate_limit: 100 +insert into shoelace_ok select * from shoelace_arrive +-- +TABLE: name="shoelace_ok" schema="" table="shoelace_ok" ctx=DML +TABLE: name="shoelace_arrive" schema="" table="shoelace_arrive" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace_ok SELECT * FROM shoelace_arrive" +== 327 +-- truncate_limit: 100 +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace ORDER BY sl_name" +== 328 +-- truncate_limit: 100 +SELECT * FROM shoelace_log ORDER BY sl_name +-- +TABLE: name="shoelace_log" schema="" table="shoelace_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace_log ORDER BY sl_name" +== 329 +-- truncate_limit: 100 +CREATE VIEW shoelace_obsolete AS + SELECT * FROM shoelace WHERE NOT EXISTS + (SELECT shoename FROM shoe WHERE slcolor = sl_color) +-- +TABLE: name="shoelace_obsolete" schema="" table="shoelace_obsolete" ctx=DDL +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +TABLE: name="shoe" schema="" table="shoe" ctx=Select +FILTER: schema="" table="" column="slcolor" +FILTER: schema="" table="" column="sl_color" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW shoelace_obsolete AS SELECT * FROM shoelace WHERE NOT EXISTS (SELECT shoename FROM sh..." +== 330 +-- truncate_limit: 100 +CREATE VIEW shoelace_candelete AS + SELECT * FROM shoelace_obsolete WHERE sl_avail = 0 +-- +TABLE: name="shoelace_candelete" schema="" table="shoelace_candelete" ctx=DDL +TABLE: name="shoelace_obsolete" schema="" table="shoelace_obsolete" ctx=Select +FILTER: schema="" table="" column="sl_avail" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW shoelace_candelete AS SELECT * FROM shoelace_obsolete WHERE sl_avail = 0" +== 331 +-- truncate_limit: 100 +insert into shoelace values ('sl9', 0, 'pink', 35.0, 'inch', 0.0) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace VALUES ('sl9', 0, 'pink', 35.0, 'inch', 0.0)" +== 332 +-- truncate_limit: 100 +insert into shoelace values ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0)" +== 333 +-- truncate_limit: 100 +-- Unsupported (even though a similar updatable view construct is) +insert into shoelace values ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0) + on conflict do nothing +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0) ON CONFLICT DO NOTHING" +== 334 +-- truncate_limit: 100 +SELECT * FROM shoelace_obsolete ORDER BY sl_len_cm +-- +TABLE: name="shoelace_obsolete" schema="" table="shoelace_obsolete" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace_obsolete ORDER BY sl_len_cm" +== 335 +-- truncate_limit: 100 +SELECT * FROM shoelace_candelete +-- +TABLE: name="shoelace_candelete" schema="" table="shoelace_candelete" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace_candelete" +== 336 +-- truncate_limit: 100 +DELETE FROM shoelace WHERE EXISTS + (SELECT * FROM shoelace_candelete + WHERE sl_name = shoelace.sl_name) +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +TABLE: name="shoelace_candelete" schema="" table="shoelace_candelete" ctx=Select +FILTER: schema="" table="" column="sl_name" +FILTER: schema="" table="shoelace" column="sl_name" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM shoelace WHERE EXISTS (SELECT * FROM shoelace_candelete WHERE ...)" +== 337 +-- truncate_limit: 100 +SELECT * FROM shoelace ORDER BY sl_name +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoelace ORDER BY sl_name" +== 338 +-- truncate_limit: 100 +SELECT * FROM shoe ORDER BY shoename +-- +TABLE: name="shoe" schema="" table="shoe" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shoe ORDER BY shoename" +== 339 +-- truncate_limit: 100 +SELECT count(*) FROM shoe +-- +TABLE: name="shoe" schema="" table="shoe" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM shoe" +== 340 +-- truncate_limit: 100 +|-- +-- Simple test of qualified ON INSERT ... this did not work in 7.0 ... +|-- +create table rules_foo (f1 int) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_foo (f1 int)" +== 341 +-- truncate_limit: 100 +create table rules_foo2 (f1 int) +-- +TABLE: name="rules_foo2" schema="" table="rules_foo2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_foo2 (f1 int)" +== 342 +-- truncate_limit: 100 +create rule rules_foorule as on insert to rules_foo where f1 < 100 +do instead nothing +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rules_foorule AS ON INSERT TO rules_foo WHERE f1 < 100 DO INSTEAD NOTHING" +== 343 +-- truncate_limit: 100 +insert into rules_foo values(1) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rules_foo VALUES (1)" +== 344 +-- truncate_limit: 100 +insert into rules_foo values(1001) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rules_foo VALUES (1001)" +== 345 +-- truncate_limit: 100 +select * from rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rules_foo" +== 346 +-- truncate_limit: 100 +drop rule rules_foorule on rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE rules_foorule ON rules_foo" +== 347 +-- truncate_limit: 100 +-- this should fail because f1 is not exposed for unqualified reference: +create rule rules_foorule as on insert to rules_foo where f1 < 100 +do instead insert into rules_foo2 values (f1) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rules_foorule AS ON INSERT TO rules_foo WHERE ... DO INSTEAD INSERT INTO rules_foo2 V..." +== 348 +-- truncate_limit: 100 +-- this is the correct way: +create rule rules_foorule as on insert to rules_foo where f1 < 100 +do instead insert into rules_foo2 values (new.f1) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rules_foorule AS ON INSERT TO rules_foo WHERE ... DO INSTEAD INSERT INTO rules_foo2 V..." +== 349 +-- truncate_limit: 100 +insert into rules_foo values(2) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rules_foo VALUES (2)" +== 350 +-- truncate_limit: 100 +insert into rules_foo values(100) +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rules_foo VALUES (100)" +== 351 +-- truncate_limit: 100 +select * from rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rules_foo" +== 352 +-- truncate_limit: 100 +select * from rules_foo2 +-- +TABLE: name="rules_foo2" schema="" table="rules_foo2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rules_foo2" +== 353 +-- truncate_limit: 100 +drop rule rules_foorule on rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE rules_foorule ON rules_foo" +== 354 +-- truncate_limit: 100 +drop table rules_foo +-- +TABLE: name="rules_foo" schema="" table="rules_foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rules_foo" +== 355 +-- truncate_limit: 100 +drop table rules_foo2 +-- +TABLE: name="rules_foo2" schema="" table="rules_foo2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rules_foo2" +== 356 +-- truncate_limit: 100 +|-- +-- Test rules containing INSERT ... SELECT, which is a very ugly special +-- case as of 7.1. Example is based on bug report from Joel Burton. +|-- +create table pparent (pid int, txt text) +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pparent (pid int, txt text)" +== 357 +-- truncate_limit: 100 +insert into pparent values (1,'parent1') +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pparent VALUES (1, 'parent1')" +== 358 +-- truncate_limit: 100 +insert into pparent values (2,'parent2') +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pparent VALUES (2, 'parent2')" +== 359 +-- truncate_limit: 100 +create table cchild (pid int, descrip text) +-- +TABLE: name="cchild" schema="" table="cchild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cchild (pid int, descrip text)" +== 360 +-- truncate_limit: 100 +insert into cchild values (1,'descrip1') +-- +TABLE: name="cchild" schema="" table="cchild" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO cchild VALUES (1, 'descrip1')" +== 361 +-- truncate_limit: 100 +create view vview as + select pparent.pid, txt, descrip from + pparent left join cchild using (pid) +-- +TABLE: name="vview" schema="" table="vview" ctx=DDL +TABLE: name="pparent" schema="" table="pparent" ctx=Select +TABLE: name="cchild" schema="" table="cchild" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vview AS SELECT pparent.pid, txt, descrip FROM pparent LEFT JOIN cchild USING (pid)" +== 362 +-- truncate_limit: 100 +create rule rrule as + on update to vview do instead +( + insert into cchild (pid, descrip) + select old.pid, new.descrip where old.descrip isnull; + update cchild set descrip = new.descrip where cchild.pid = old.pid; +) +-- +TABLE: name="vview" schema="" table="vview" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rrule AS ON UPDATE TO vview DO INSTEAD (INSERT INTO cchild (pid, descrip) SELECT old...." +== 363 +-- truncate_limit: 100 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vview" +== 364 +-- truncate_limit: 100 +update vview set descrip='test1' where pid=1 +-- +TABLE: name="vview" schema="" table="vview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE vview SET descrip = 'test1' WHERE pid = 1" +== 365 +-- truncate_limit: 100 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vview" +== 366 +-- truncate_limit: 100 +update vview set descrip='test2' where pid=2 +-- +TABLE: name="vview" schema="" table="vview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE vview SET descrip = 'test2' WHERE pid = 2" +== 367 +-- truncate_limit: 100 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vview" +== 368 +-- truncate_limit: 100 +update vview set descrip='test3' where pid=3 +-- +TABLE: name="vview" schema="" table="vview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE vview SET descrip = 'test3' WHERE pid = 3" +== 369 +-- truncate_limit: 100 +select * from vview +-- +TABLE: name="vview" schema="" table="vview" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vview" +== 370 +-- truncate_limit: 100 +select * from cchild +-- +TABLE: name="cchild" schema="" table="cchild" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM cchild" +== 371 +-- truncate_limit: 100 +drop rule rrule on vview +-- +TABLE: name="vview" schema="" table="vview" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE rrule ON vview" +== 372 +-- truncate_limit: 100 +drop view vview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vview" +== 373 +-- truncate_limit: 100 +drop table pparent +-- +TABLE: name="pparent" schema="" table="pparent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pparent" +== 374 +-- truncate_limit: 100 +drop table cchild +-- +TABLE: name="cchild" schema="" table="cchild" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE cchild" +== 375 +-- truncate_limit: 100 +|-- +-- Check that ruleutils are working +|-- + +-- temporarily disable fancy output, so view changes create less diff noise + +SELECT viewname, definition FROM pg_views +WHERE schemaname = 'pg_catalog' +ORDER BY viewname +-- +TABLE: name="pg_views" schema="" table="pg_views" ctx=Select +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +TRUNCATED: "SELECT viewname, definition FROM pg_views WHERE schemaname = 'pg_catalog' ORDER BY viewname" +== 376 +-- truncate_limit: 100 +SELECT tablename, rulename, definition FROM pg_rules +WHERE schemaname = 'pg_catalog' +ORDER BY tablename, rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="schemaname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_rules WHERE schemaname = 'pg_catalog' ORDER BY tablename, rulename" +== 377 +-- truncate_limit: 100 +-- restore normal output mode + +|-- +-- CREATE OR REPLACE RULE +|-- + +CREATE TABLE ruletest_tbl (a int, b int) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ruletest_tbl (a int, b int)" +== 378 +-- truncate_limit: 100 +CREATE TABLE ruletest_tbl2 (a int, b int) +-- +TABLE: name="ruletest_tbl2" schema="" table="ruletest_tbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ruletest_tbl2 (a int, b int)" +== 379 +-- truncate_limit: 100 +CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl + DO INSTEAD INSERT INTO ruletest_tbl2 VALUES (10, 10) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl DO INSTEAD INSERT INTO ruletest_tbl2 V..." +== 380 +-- truncate_limit: 100 +INSERT INTO ruletest_tbl VALUES (99, 99) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest_tbl VALUES (99, 99)" +== 381 +-- truncate_limit: 100 +CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl + DO INSTEAD INSERT INTO ruletest_tbl2 VALUES (1000, 1000) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl DO INSTEAD INSERT INTO ruletest_tbl2 V..." +== 382 +-- truncate_limit: 100 +INSERT INTO ruletest_tbl VALUES (99, 99) +-- +TABLE: name="ruletest_tbl" schema="" table="ruletest_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest_tbl VALUES (99, 99)" +== 383 +-- truncate_limit: 100 +SELECT * FROM ruletest_tbl2 +-- +TABLE: name="ruletest_tbl2" schema="" table="ruletest_tbl2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ruletest_tbl2" +== 384 +-- truncate_limit: 100 +-- Check that rewrite rules splitting one INSERT into multiple +-- conditional statements does not disable FK checking. +create table rule_and_refint_t1 ( + id1a integer, + id1b integer, + + primary key (id1a, id1b) +) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_and_refint_t1 (id1a int, id1b int, PRIMARY KEY (id1a, id1b))" +== 385 +-- truncate_limit: 100 +create table rule_and_refint_t2 ( + id2a integer, + id2c integer, + + primary key (id2a, id2c) +) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_and_refint_t2 (id2a int, id2c int, PRIMARY KEY (id2a, id2c))" +== 386 +-- truncate_limit: 100 +create table rule_and_refint_t3 ( + id3a integer, + id3b integer, + id3c integer, + data text, + + primary key (id3a, id3b, id3c), + + foreign key (id3a, id3b) references rule_and_refint_t1 (id1a, id1b), + foreign key (id3a, id3c) references rule_and_refint_t2 (id2a, id2c) +) +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_and_refint_t3 (id3a int, id3b int, id3c int, data text, PRIMARY KEY (id3a, id3b..." +== 387 +-- truncate_limit: 100 +insert into rule_and_refint_t1 values (1, 11) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t1 VALUES (1, 11)" +== 388 +-- truncate_limit: 100 +insert into rule_and_refint_t1 values (1, 12) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t1 VALUES (1, 12)" +== 389 +-- truncate_limit: 100 +insert into rule_and_refint_t1 values (2, 21) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t1 VALUES (2, 21)" +== 390 +-- truncate_limit: 100 +insert into rule_and_refint_t1 values (2, 22) +-- +TABLE: name="rule_and_refint_t1" schema="" table="rule_and_refint_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t1 VALUES (2, 22)" +== 391 +-- truncate_limit: 100 +insert into rule_and_refint_t2 values (1, 11) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t2 VALUES (1, 11)" +== 392 +-- truncate_limit: 100 +insert into rule_and_refint_t2 values (1, 12) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t2 VALUES (1, 12)" +== 393 +-- truncate_limit: 100 +insert into rule_and_refint_t2 values (2, 21) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t2 VALUES (2, 21)" +== 394 +-- truncate_limit: 100 +insert into rule_and_refint_t2 values (2, 22) +-- +TABLE: name="rule_and_refint_t2" schema="" table="rule_and_refint_t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t2 VALUES (2, 22)" +== 395 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 11, 11, 'row1') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 11, 11, 'row1')" +== 396 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 11, 12, 'row2') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 11, 12, 'row2')" +== 397 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 12, 11, 'row3') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 12, 11, 'row3')" +== 398 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 12, 12, 'row4') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 12, 12, 'row4')" +== 399 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 11, 13, 'row5') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 11, 13, 'row5')" +== 400 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 13, 11, 'row6') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 13, 11, 'row6')" +== 401 +-- truncate_limit: 100 +-- Ordinary table +insert into rule_and_refint_t3 values (1, 13, 11, 'row6') + on conflict do nothing +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 13, 11, 'row6') ON CONFLICT DO NOTHING" +== 402 +-- truncate_limit: 100 +-- rule not fired, so fk violation +insert into rule_and_refint_t3 values (1, 13, 11, 'row6') + on conflict (id3a, id3b, id3c) do update + set id3b = excluded.id3b +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (...) ON CONFLICT (id3a, id3b, id3c) DO UPDATE SET ... = ..." +== 403 +-- truncate_limit: 100 +-- rule fired, so unsupported +insert into shoelace values ('sl9', 0, 'pink', 35.0, 'inch', 0.0) + on conflict (sl_name) do update + set sl_avail = excluded.sl_avail +-- +TABLE: name="shoelace" schema="" table="shoelace" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shoelace VALUES (...) ON CONFLICT (sl_name) DO UPDATE SET sl_avail = excluded.sl_avail" +== 404 +-- truncate_limit: 100 +create rule rule_and_refint_t3_ins as on insert to rule_and_refint_t3 + where (exists (select 1 from rule_and_refint_t3 + where (((rule_and_refint_t3.id3a = new.id3a) + and (rule_and_refint_t3.id3b = new.id3b)) + and (rule_and_refint_t3.id3c = new.id3c)))) + do instead update rule_and_refint_t3 set data = new.data + where (((rule_and_refint_t3.id3a = new.id3a) + and (rule_and_refint_t3.id3b = new.id3b)) + and (rule_and_refint_t3.id3c = new.id3c)) +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rule_and_refint_t3_ins AS ON INSERT TO rule_and_refint_t3 WHERE ... DO INSTEAD UPDATE..." +== 405 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 11, 13, 'row7') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 11, 13, 'row7')" +== 406 +-- truncate_limit: 100 +insert into rule_and_refint_t3 values (1, 13, 11, 'row8') +-- +TABLE: name="rule_and_refint_t3" schema="" table="rule_and_refint_t3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_and_refint_t3 VALUES (1, 13, 11, 'row8')" +== 407 +-- truncate_limit: 100 +|-- +-- disallow dropping a view's rule (bug #5072) +|-- + +create view rules_fooview as select 'rules_foo'::text +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rules_fooview AS SELECT 'rules_foo'::text" +== 408 +-- truncate_limit: 100 +drop rule "_RETURN" on rules_fooview +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE \"_RETURN\" ON rules_fooview" +== 409 +-- truncate_limit: 100 +drop view rules_fooview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rules_fooview" +== 410 +-- truncate_limit: 100 +|-- +-- We used to allow converting a table to a view by creating a "_RETURN" +-- rule for it, but no more. +|-- + +create table rules_fooview (x int, y text) +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_fooview (x int, y text)" +== 411 +-- truncate_limit: 100 +create rule "_RETURN" as on select to rules_fooview do instead + select 1 as x, 'aaa'::text as y +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE \"_RETURN\" AS ON SELECT TO rules_fooview DO INSTEAD SELECT 1 AS x, 'aaa'::text AS y" +== 412 +-- truncate_limit: 100 +drop table rules_fooview +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rules_fooview" +== 413 +-- truncate_limit: 100 +-- likewise, converting a partitioned table or partition to view is not allowed +create table rules_fooview (x int, y text) partition by list (x) +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_fooview (x int, y text) PARTITION BY LIST (x)" +== 414 +-- truncate_limit: 100 +create rule "_RETURN" as on select to rules_fooview do instead + select 1 as x, 'aaa'::text as y +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE \"_RETURN\" AS ON SELECT TO rules_fooview DO INSTEAD SELECT 1 AS x, 'aaa'::text AS y" +== 415 +-- truncate_limit: 100 +create table rules_fooview_part partition of rules_fooview for values in (1) +-- +TABLE: name="rules_fooview_part" schema="" table="rules_fooview_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_fooview_part PARTITION OF rules_fooview FOR VALUES IN (1)" +== 416 +-- truncate_limit: 100 +create rule "_RETURN" as on select to rules_fooview_part do instead + select 1 as x, 'aaa'::text as y +-- +TABLE: name="rules_fooview_part" schema="" table="rules_fooview_part" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE \"_RETURN\" AS ON SELECT TO rules_fooview_part DO INSTEAD SELECT 1 AS x, 'aaa'::text AS y" +== 417 +-- truncate_limit: 100 +drop table rules_fooview +-- +TABLE: name="rules_fooview" schema="" table="rules_fooview" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rules_fooview" +== 418 +-- truncate_limit: 100 +|-- +-- check for planner problems with complex inherited UPDATES +|-- + +create table id (id serial primary key, name text) +-- +TABLE: name="id" schema="" table="id" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE id (id serial PRIMARY KEY, name text)" +== 419 +-- truncate_limit: 100 +-- currently, must respecify PKEY for each inherited subtable +create table test_1 (id integer primary key) inherits (id) +-- +TABLE: name="test_1" schema="" table="test_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_1 (id int PRIMARY KEY) INHERITS (id)" +== 420 +-- truncate_limit: 100 +create table test_2 (id integer primary key) inherits (id) +-- +TABLE: name="test_2" schema="" table="test_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_2 (id int PRIMARY KEY) INHERITS (id)" +== 421 +-- truncate_limit: 100 +create table test_3 (id integer primary key) inherits (id) +-- +TABLE: name="test_3" schema="" table="test_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_3 (id int PRIMARY KEY) INHERITS (id)" +== 422 +-- truncate_limit: 100 +insert into test_1 (name) values ('Test 1') +-- +TABLE: name="test_1" schema="" table="test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_1 (name) VALUES ('Test 1')" +== 423 +-- truncate_limit: 100 +insert into test_1 (name) values ('Test 2') +-- +TABLE: name="test_1" schema="" table="test_1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_1 (name) VALUES ('Test 2')" +== 424 +-- truncate_limit: 100 +insert into test_2 (name) values ('Test 3') +-- +TABLE: name="test_2" schema="" table="test_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_2 (name) VALUES ('Test 3')" +== 425 +-- truncate_limit: 100 +insert into test_2 (name) values ('Test 4') +-- +TABLE: name="test_2" schema="" table="test_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_2 (name) VALUES ('Test 4')" +== 426 +-- truncate_limit: 100 +insert into test_3 (name) values ('Test 5') +-- +TABLE: name="test_3" schema="" table="test_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_3 (name) VALUES ('Test 5')" +== 427 +-- truncate_limit: 100 +insert into test_3 (name) values ('Test 6') +-- +TABLE: name="test_3" schema="" table="test_3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_3 (name) VALUES ('Test 6')" +== 428 +-- truncate_limit: 100 +create view id_ordered as select * from id order by id +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DDL +TABLE: name="id" schema="" table="id" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW id_ordered AS SELECT * FROM id ORDER BY id" +== 429 +-- truncate_limit: 100 +create rule update_id_ordered as on update to id_ordered + do instead update id set name = new.name where id = old.id +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE update_id_ordered AS ON UPDATE TO id_ordered DO INSTEAD UPDATE id SET name = new.name..." +== 430 +-- truncate_limit: 100 +select * from id_ordered +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM id_ordered" +== 431 +-- truncate_limit: 100 +update id_ordered set name = 'update 2' where id = 2 +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE id_ordered SET name = 'update 2' WHERE id = 2" +== 432 +-- truncate_limit: 100 +update id_ordered set name = 'update 4' where id = 4 +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE id_ordered SET name = 'update 4' WHERE id = 4" +== 433 +-- truncate_limit: 100 +update id_ordered set name = 'update 5' where id = 5 +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE id_ordered SET name = 'update 5' WHERE id = 5" +== 434 +-- truncate_limit: 100 +select * from id_ordered +-- +TABLE: name="id_ordered" schema="" table="id_ordered" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM id_ordered" +== 435 +-- truncate_limit: 100 +drop table id cascade +-- +TABLE: name="id" schema="" table="id" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE id CASCADE" +== 436 +-- truncate_limit: 100 +|-- +-- check corner case where an entirely-dummy subplan is created by +-- constraint exclusion +|-- + +create temp table t1 (a integer primary key) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (a int PRIMARY KEY)" +== 437 +-- truncate_limit: 100 +create temp table t1_1 (check (a >= 0 and a < 10)) inherits (t1) +-- +TABLE: name="t1_1" schema="" table="t1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1_1 (CHECK (a >= 0 AND a < 10)) INHERITS (t1)" +== 438 +-- truncate_limit: 100 +create temp table t1_2 (check (a >= 10 and a < 20)) inherits (t1) +-- +TABLE: name="t1_2" schema="" table="t1_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1_2 (CHECK (a >= 10 AND a < 20)) INHERITS (t1)" +== 439 +-- truncate_limit: 100 +create rule t1_ins_1 as on insert to t1 + where new.a >= 0 and new.a < 10 + do instead + insert into t1_1 values (new.a) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE t1_ins_1 AS ON INSERT TO t1 WHERE ... DO INSTEAD INSERT INTO t1_1 VALUES (new.a)" +== 440 +-- truncate_limit: 100 +create rule t1_ins_2 as on insert to t1 + where new.a >= 10 and new.a < 20 + do instead + insert into t1_2 values (new.a) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE t1_ins_2 AS ON INSERT TO t1 WHERE ... DO INSTEAD INSERT INTO t1_2 VALUES (new.a)" +== 441 +-- truncate_limit: 100 +create rule t1_upd_1 as on update to t1 + where old.a >= 0 and old.a < 10 + do instead + update t1_1 set a = new.a where a = old.a +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE t1_upd_1 AS ON UPDATE TO t1 WHERE ... DO INSTEAD UPDATE t1_1 SET a = new.a WHERE a = ..." +== 442 +-- truncate_limit: 100 +create rule t1_upd_2 as on update to t1 + where old.a >= 10 and old.a < 20 + do instead + update t1_2 set a = new.a where a = old.a +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE t1_upd_2 AS ON UPDATE TO t1 WHERE ... DO INSTEAD UPDATE t1_2 SET a = new.a WHERE a = ..." +== 443 +-- truncate_limit: 100 +set constraint_exclusion = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET constraint_exclusion TO ON" +== 444 +-- truncate_limit: 100 +insert into t1 select * from generate_series(5,19,1) g +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 SELECT * FROM generate_series(5, 19, 1) g" +== 445 +-- truncate_limit: 100 +update t1 set a = 4 where a = 5 +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE t1 SET a = 4 WHERE a = 5" +== 446 +-- truncate_limit: 100 +select * from only t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY t1" +== 447 +-- truncate_limit: 100 +select * from only t1_1 +-- +TABLE: name="t1_1" schema="" table="t1_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY t1_1" +== 448 +-- truncate_limit: 100 +select * from only t1_2 +-- +TABLE: name="t1_2" schema="" table="t1_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY t1_2" +== 449 +-- truncate_limit: 100 +reset constraint_exclusion +-- +STMT: VariableSetStmt +TRUNCATED: "RESET constraint_exclusion" +== 450 +-- truncate_limit: 100 +-- test FOR UPDATE in rules + +create table rules_base(f1 int, f2 int) +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_base (f1 int, f2 int)" +== 451 +-- truncate_limit: 100 +insert into rules_base values(1,2), (11,12) +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rules_base VALUES (1, 2), (11, 12)" +== 452 +-- truncate_limit: 100 +create rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 1 for update +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r1 AS ON UPDATE TO rules_base DO INSTEAD SELECT * FROM rules_base WHERE f1 = 1 FOR UP..." +== 453 +-- truncate_limit: 100 +update rules_base set f2 = f2 + 1 +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rules_base SET f2 = f2 + 1" +== 454 +-- truncate_limit: 100 +create or replace rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 11 for update of rules_base +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE r1 AS ON UPDATE TO rules_base DO INSTEAD SELECT * FROM rules_base WHERE f1..." +== 455 +-- truncate_limit: 100 +update rules_base set f2 = f2 + 1 +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rules_base SET f2 = f2 + 1" +== 456 +-- truncate_limit: 100 +create or replace rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 11 for update of old +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE r1 AS ON UPDATE TO rules_base DO INSTEAD SELECT * FROM rules_base WHERE f1..." +== 457 +-- truncate_limit: 100 +-- error +drop table rules_base +-- +TABLE: name="rules_base" schema="" table="rules_base" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rules_base" +== 458 +-- truncate_limit: 100 +-- test various flavors of pg_get_viewdef() + +select pg_get_viewdef('shoe'::regclass) as unpretty +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('shoe'::regclass) AS unpretty" +== 459 +-- truncate_limit: 100 +select pg_get_viewdef('shoe'::regclass,true) as pretty +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('shoe'::regclass, true) AS pretty" +== 460 +-- truncate_limit: 100 +select pg_get_viewdef('shoe'::regclass,0) as prettier +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('shoe'::regclass, 0) AS prettier" +== 461 +-- truncate_limit: 100 +|-- +-- check multi-row VALUES in rules +|-- + +create table rules_src(f1 int, f2 int default 0) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_src (f1 int, f2 int DEFAULT 0)" +== 462 +-- truncate_limit: 100 +create table rules_log(f1 int, f2 int, tag text, id serial) +-- +TABLE: name="rules_log" schema="" table="rules_log" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_log (f1 int, f2 int, tag text, id serial)" +== 463 +-- truncate_limit: 100 +insert into rules_src values(1,2), (11,12) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rules_src VALUES (1, 2), (11, 12)" +== 464 +-- truncate_limit: 100 +create rule r1 as on update to rules_src do also + insert into rules_log values(old.*, 'old', default), (new.*, 'new', default) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r1 AS ON UPDATE TO rules_src DO INSERT INTO rules_log VALUES (old.*, 'old', DEFAULT),..." +== 465 +-- truncate_limit: 100 +update rules_src set f2 = f2 + 1 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rules_src SET f2 = f2 + 1" +== 466 +-- truncate_limit: 100 +update rules_src set f2 = f2 * 10 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rules_src SET f2 = f2 * 10" +== 467 +-- truncate_limit: 100 +select * from rules_src +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rules_src" +== 468 +-- truncate_limit: 100 +select * from rules_log +-- +TABLE: name="rules_log" schema="" table="rules_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rules_log" +== 469 +-- truncate_limit: 100 +create rule r2 as on update to rules_src do also + values(old.*, 'old'), (new.*, 'new') +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r2 AS ON UPDATE TO rules_src DO VALUES (old.*, 'old'), (new.*, 'new')" +== 470 +-- truncate_limit: 100 +update rules_src set f2 = f2 / 10 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rules_src SET f2 = f2 / 10" +== 471 +-- truncate_limit: 100 +create rule r3 as on insert to rules_src do also + insert into rules_log values(null, null, '-', default), (new.*, 'new', default) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r3 AS ON INSERT TO rules_src DO INSERT INTO rules_log VALUES (NULL, NULL, '-', DEFAUL..." +== 472 +-- truncate_limit: 100 +insert into rules_src values(22,23), (33,default) +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rules_src VALUES (22, 23), (33, DEFAULT)" +== 473 +-- truncate_limit: 100 +select * from rules_src +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rules_src" +== 474 +-- truncate_limit: 100 +select * from rules_log +-- +TABLE: name="rules_log" schema="" table="rules_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rules_log" +== 475 +-- truncate_limit: 100 +create rule r4 as on delete to rules_src do notify rules_src_deletion +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r4 AS ON DELETE TO rules_src DO NOTIFY rules_src_deletion" +== 476 +-- truncate_limit: 100 +|-- +-- Ensure an aliased target relation for insert is correctly deparsed. +|-- +create rule r5 as on insert to rules_src do instead insert into rules_log AS trgt SELECT NEW.* RETURNING trgt.f1, trgt.f2 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r5 AS ON INSERT TO rules_src DO INSTEAD INSERT INTO rules_log AS trgt SELECT new.* RE..." +== 477 +-- truncate_limit: 100 +create rule r6 as on update to rules_src do instead UPDATE rules_log AS trgt SET tag = 'updated' WHERE trgt.f1 = new.f1 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r6 AS ON UPDATE TO rules_src DO INSTEAD UPDATE rules_log trgt SET tag = 'updated' WHE..." +== 478 +-- truncate_limit: 100 +|-- +-- Check deparse disambiguation of INSERT/UPDATE/DELETE targets. +|-- +create rule r7 as on delete to rules_src do instead + with wins as (insert into int4_tbl as trgt values (0) returning *), + wupd as (update int4_tbl trgt set f1 = f1+1 returning *), + wdel as (delete from int4_tbl trgt where f1 = 0 returning *) + insert into rules_log AS trgt select old.* from wins, wupd, wdel + returning trgt.f1, trgt.f2 +-- +TABLE: name="rules_src" schema="" table="rules_src" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r7 AS ON DELETE TO rules_src DO INSTEAD WITH wins AS (INSERT INTO int4_tbl AS trgt VA..." +== 479 +-- truncate_limit: 100 +-- check display of all rules added above + +|-- +-- Also check multiassignment deparsing. +|-- +create table rule_t1(f1 int, f2 int) +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_t1 (f1 int, f2 int)" +== 480 +-- truncate_limit: 100 +create table rule_dest(f1 int, f2 int[], tag text) +-- +TABLE: name="rule_dest" schema="" table="rule_dest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_dest (f1 int, f2 int[], tag text)" +== 481 +-- truncate_limit: 100 +create rule rr as on update to rule_t1 do instead UPDATE rule_dest trgt + SET (f2[1], f1, tag) = (SELECT new.f2, new.f1, 'updated'::varchar) + WHERE trgt.f1 = new.f1 RETURNING new.* +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rr AS ON UPDATE TO rule_t1 DO INSTEAD UPDATE rule_dest trgt SET (f2[1], f1, tag) = (S..." +== 482 +-- truncate_limit: 100 +drop table rule_t1, rule_dest +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +TABLE: name="rule_dest" schema="" table="rule_dest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rule_t1, rule_dest" +== 483 +-- truncate_limit: 100 +|-- +-- Test implicit LATERAL references to old/new in rules +|-- +CREATE TABLE rule_t1(a int, b text DEFAULT 'xxx', c int) +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_t1 (a int, b text DEFAULT 'xxx', c int)" +== 484 +-- truncate_limit: 100 +CREATE VIEW rule_v1 AS SELECT * FROM rule_t1 +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rule_v1 AS SELECT * FROM rule_t1" +== 485 +-- truncate_limit: 100 +CREATE RULE v1_ins AS ON INSERT TO rule_v1 + DO ALSO INSERT INTO rule_t1 + SELECT * FROM (SELECT a + 10 FROM rule_t1 WHERE a = NEW.a) tt +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE v1_ins AS ON INSERT TO rule_v1 DO INSERT INTO rule_t1 SELECT * FROM (SELECT a + 10 FR..." +== 486 +-- truncate_limit: 100 +CREATE RULE v1_upd AS ON UPDATE TO rule_v1 + DO ALSO UPDATE rule_t1 t + SET c = tt.a * 10 + FROM (SELECT a FROM rule_t1 WHERE a = OLD.a) tt WHERE t.a = tt.a +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE v1_upd AS ON UPDATE TO rule_v1 DO UPDATE rule_t1 t SET c = tt.a * 10 FROM (SELECT a F..." +== 487 +-- truncate_limit: 100 +INSERT INTO rule_v1 VALUES (1, 'a'), (2, 'b') +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_v1 VALUES (1, 'a'), (2, 'b')" +== 488 +-- truncate_limit: 100 +UPDATE rule_v1 SET b = upper(b) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE rule_v1 SET b = upper(b)" +== 489 +-- truncate_limit: 100 +SELECT * FROM rule_t1 +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rule_t1" +== 490 +-- truncate_limit: 100 +DROP TABLE rule_t1 CASCADE +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rule_t1 CASCADE" +== 491 +-- truncate_limit: 100 +|-- +-- check alter rename rule +|-- +CREATE TABLE rule_t1 (a INT) +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_t1 (a int)" +== 492 +-- truncate_limit: 100 +CREATE VIEW rule_v1 AS SELECT * FROM rule_t1 +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rule_v1 AS SELECT * FROM rule_t1" +== 493 +-- truncate_limit: 100 +CREATE RULE InsertRule AS + ON INSERT TO rule_v1 + DO INSTEAD + INSERT INTO rule_t1 VALUES(new.a) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE insertrule AS ON INSERT TO rule_v1 DO INSTEAD INSERT INTO rule_t1 VALUES (new.a)" +== 494 +-- truncate_limit: 100 +ALTER RULE InsertRule ON rule_v1 RENAME to NewInsertRule +-- +STMT: RenameStmt +TRUNCATED: "ALTER RULE insertrule ON rule_v1 RENAME TO newinsertrule" +== 495 +-- truncate_limit: 100 +INSERT INTO rule_v1 VALUES(1) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rule_v1 VALUES (1)" +== 496 +-- truncate_limit: 100 +SELECT * FROM rule_v1 +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rule_v1" +== 497 +-- truncate_limit: 100 +|-- +-- error conditions for alter rename rule +|-- +ALTER RULE InsertRule ON rule_v1 RENAME TO NewInsertRule +-- +STMT: RenameStmt +TRUNCATED: "ALTER RULE insertrule ON rule_v1 RENAME TO newinsertrule" +== 498 +-- truncate_limit: 100 +-- doesn't exist +ALTER RULE NewInsertRule ON rule_v1 RENAME TO "_RETURN" +-- +STMT: RenameStmt +TRUNCATED: "ALTER RULE newinsertrule ON rule_v1 RENAME TO \"_RETURN\"" +== 499 +-- truncate_limit: 100 +-- already exists +ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc +-- +STMT: RenameStmt +TRUNCATED: "ALTER RULE \"_RETURN\" ON rule_v1 RENAME TO abc" +== 500 +-- truncate_limit: 100 +-- ON SELECT rule cannot be renamed + +DROP VIEW rule_v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rule_v1" +== 501 +-- truncate_limit: 100 +DROP TABLE rule_t1 +-- +TABLE: name="rule_t1" schema="" table="rule_t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rule_t1" +== 502 +-- truncate_limit: 100 +|-- +-- check display of VALUES in view definitions +|-- +create view rule_v1 as values(1,2) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rule_v1 AS VALUES (1, 2)" +== 503 +-- truncate_limit: 100 +alter table rule_v1 rename column column2 to q2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE rule_v1 RENAME COLUMN column2 TO q2" +== 504 +-- truncate_limit: 100 +drop view rule_v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rule_v1" +== 505 +-- truncate_limit: 100 +create view rule_v1(x) as values(1,2) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rule_v1 (x) AS VALUES (1, 2)" +== 506 +-- truncate_limit: 100 +drop view rule_v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rule_v1" +== 507 +-- truncate_limit: 100 +create view rule_v1(x) as select * from (values(1,2)) v +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rule_v1 (x) AS SELECT * FROM (VALUES (1, 2)) v" +== 508 +-- truncate_limit: 100 +drop view rule_v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rule_v1" +== 509 +-- truncate_limit: 100 +create view rule_v1(x) as select * from (values(1,2)) v(q,w) +-- +TABLE: name="rule_v1" schema="" table="rule_v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rule_v1 (x) AS SELECT * FROM (VALUES (1, 2)) v(q, w)" +== 510 +-- truncate_limit: 100 +drop view rule_v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rule_v1" +== 511 +-- truncate_limit: 100 +|-- +-- Check DO INSTEAD rules with ON CONFLICT +|-- +CREATE TABLE hats ( + hat_name char(10) primary key, + hat_color char(10) -- hat color +) +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hats (hat_name char(10) PRIMARY KEY, hat_color char(10))" +== 512 +-- truncate_limit: 100 +CREATE TABLE hat_data ( + hat_name char(10), + hat_color char(10) -- hat color +) +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hat_data (hat_name char(10), hat_color char(10))" +== 513 +-- truncate_limit: 100 +create unique index hat_data_unique_idx + on hat_data (hat_name COLLATE "C" bpchar_pattern_ops) +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX hat_data_unique_idx ON hat_data USING btree (hat_name COLLATE \"C\" bpchar_patt..." +== 514 +-- truncate_limit: 100 +-- DO NOTHING with ON CONFLICT +CREATE RULE hat_nosert AS ON INSERT TO hats + DO INSTEAD + INSERT INTO hat_data VALUES ( + NEW.hat_name, + NEW.hat_color) + ON CONFLICT (hat_name COLLATE "C" bpchar_pattern_ops) WHERE hat_color = 'green' + DO NOTHING + RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE hat_nosert AS ON INSERT TO hats DO INSTEAD INSERT INTO hat_data VALUES (new.hat_name,..." +== 515 +-- truncate_limit: 100 +SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename" +== 516 +-- truncate_limit: 100 +-- Works (projects row) +INSERT INTO hats VALUES ('h7', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hats VALUES ('h7', 'black') RETURNING *" +== 517 +-- truncate_limit: 100 +-- Works (does nothing) +INSERT INTO hats VALUES ('h7', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hats VALUES ('h7', 'black') RETURNING *" +== 518 +-- truncate_limit: 100 +SELECT tablename, rulename, definition FROM pg_rules + WHERE tablename = 'hats' +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT tablename, rulename, definition FROM pg_rules WHERE tablename = 'hats'" +== 519 +-- truncate_limit: 100 +DROP RULE hat_nosert ON hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE hat_nosert ON hats" +== 520 +-- truncate_limit: 100 +-- DO NOTHING without ON CONFLICT +CREATE RULE hat_nosert_all AS ON INSERT TO hats + DO INSTEAD + INSERT INTO hat_data VALUES ( + NEW.hat_name, + NEW.hat_color) + ON CONFLICT + DO NOTHING + RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE hat_nosert_all AS ON INSERT TO hats DO INSTEAD INSERT INTO hat_data VALUES (new.hat_n..." +== 521 +-- truncate_limit: 100 +SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename" +== 522 +-- truncate_limit: 100 +DROP RULE hat_nosert_all ON hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE hat_nosert_all ON hats" +== 523 +-- truncate_limit: 100 +-- Works (does nothing) +INSERT INTO hats VALUES ('h7', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hats VALUES ('h7', 'black') RETURNING *" +== 524 +-- truncate_limit: 100 +-- DO UPDATE with a WHERE clause +CREATE RULE hat_upsert AS ON INSERT TO hats + DO INSTEAD + INSERT INTO hat_data VALUES ( + NEW.hat_name, + NEW.hat_color) + ON CONFLICT (hat_name) + DO UPDATE + SET hat_name = hat_data.hat_name, hat_color = excluded.hat_color + WHERE excluded.hat_color <> 'forbidden' AND hat_data.* != excluded.* + RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE hat_upsert AS ON INSERT TO hats DO INSTEAD INSERT INTO hat_data VALUES (new.hat_name,..." +== 525 +-- truncate_limit: 100 +SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename" +== 526 +-- truncate_limit: 100 +-- Works (does upsert) +INSERT INTO hats VALUES ('h8', 'black') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hats VALUES ('h8', 'black') RETURNING *" +== 527 +-- truncate_limit: 100 +SELECT * FROM hat_data WHERE hat_name = 'h8' +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hat_data WHERE hat_name = 'h8'" +== 528 +-- truncate_limit: 100 +INSERT INTO hats VALUES ('h8', 'white') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hats VALUES ('h8', 'white') RETURNING *" +== 529 +-- truncate_limit: 100 +SELECT * FROM hat_data WHERE hat_name = 'h8' +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hat_data WHERE hat_name = 'h8'" +== 530 +-- truncate_limit: 100 +INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING *" +== 531 +-- truncate_limit: 100 +SELECT * FROM hat_data WHERE hat_name = 'h8' +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hat_data WHERE hat_name = 'h8'" +== 532 +-- truncate_limit: 100 +SELECT tablename, rulename, definition FROM pg_rules + WHERE tablename = 'hats' +-- +TABLE: name="pg_rules" schema="" table="pg_rules" ctx=Select +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT tablename, rulename, definition FROM pg_rules WHERE tablename = 'hats'" +== 533 +-- truncate_limit: 100 +-- ensure explain works for on insert conflict rules +explain (costs off) INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING *" +== 534 +-- truncate_limit: 100 +-- ensure upserting into a rule, with a CTE (different offsets!) works +WITH data(hat_name, hat_color) AS MATERIALIZED ( + VALUES ('h8', 'green'), + ('h9', 'blue'), + ('h7', 'forbidden') +) +INSERT INTO hats + SELECT * FROM data +RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +CTE: "data" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH data(hat_name, hat_color) AS MATERIALIZED (...) INSERT INTO hats SELECT * FROM data RETURNING *" +== 535 +-- truncate_limit: 100 +EXPLAIN (costs off) +WITH data(hat_name, hat_color) AS MATERIALIZED ( + VALUES ('h8', 'green'), + ('h9', 'blue'), + ('h7', 'forbidden') +) +INSERT INTO hats + SELECT * FROM data +RETURNING * +-- +TABLE: name="hats" schema="" table="hats" ctx=DML +CTE: "data" +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) WITH data(hat_name, hat_color) AS MATERIALIZED (VALUES ('h8', 'green'), ('h9'..." +== 536 +-- truncate_limit: 100 +SELECT * FROM hat_data WHERE hat_name IN ('h8', 'h9', 'h7') ORDER BY hat_name +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=Select +FILTER: schema="" table="" column="hat_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM hat_data WHERE hat_name IN ('h8', 'h9', 'h7') ORDER BY hat_name" +== 537 +-- truncate_limit: 100 +DROP RULE hat_upsert ON hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE hat_upsert ON hats" +== 538 +-- truncate_limit: 100 +drop table hats +-- +TABLE: name="hats" schema="" table="hats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hats" +== 539 +-- truncate_limit: 100 +drop table hat_data +-- +TABLE: name="hat_data" schema="" table="hat_data" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hat_data" +== 540 +-- truncate_limit: 100 +-- test for pg_get_functiondef properly regurgitating SET parameters +-- Note that the function is kept around to stress pg_dump. +CREATE FUNCTION func_with_set_params() RETURNS integer + AS 'select 1;' + LANGUAGE SQL + SET search_path TO PG_CATALOG + SET extra_float_digits TO 2 + SET work_mem TO '4MB' + SET datestyle to iso, mdy + SET local_preload_libraries TO "Mixed/Case", 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' + IMMUTABLE STRICT +-- +FUNCTION: name="func_with_set_params" function="func_with_set_params" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION func_with_set_params() RETURNS int AS $$select 1;$$ LANGUAGE sql SET search_path ..." +== 541 +-- truncate_limit: 100 +SELECT pg_get_functiondef('func_with_set_params()'::regprocedure) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef('func_with_set_params()'::regprocedure)" +== 542 +-- truncate_limit: 100 +-- tests for pg_get_*def with invalid objects +SELECT pg_get_constraintdef(0) +-- +FUNCTION: name="pg_get_constraintdef" function="pg_get_constraintdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_constraintdef(0)" +== 543 +-- truncate_limit: 100 +SELECT pg_get_functiondef(0) +-- +FUNCTION: name="pg_get_functiondef" function="pg_get_functiondef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_functiondef(0)" +== 544 +-- truncate_limit: 100 +SELECT pg_get_indexdef(0) +-- +FUNCTION: name="pg_get_indexdef" function="pg_get_indexdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_indexdef(0)" +== 545 +-- truncate_limit: 100 +SELECT pg_get_ruledef(0) +-- +FUNCTION: name="pg_get_ruledef" function="pg_get_ruledef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_ruledef(0)" +== 546 +-- truncate_limit: 100 +SELECT pg_get_statisticsobjdef(0) +-- +FUNCTION: name="pg_get_statisticsobjdef" function="pg_get_statisticsobjdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_statisticsobjdef(0)" +== 547 +-- truncate_limit: 100 +SELECT pg_get_triggerdef(0) +-- +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_triggerdef(0)" +== 548 +-- truncate_limit: 100 +SELECT pg_get_viewdef(0) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef(0)" +== 549 +-- truncate_limit: 100 +SELECT pg_get_function_arguments(0) +-- +FUNCTION: name="pg_get_function_arguments" function="pg_get_function_arguments" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_function_arguments(0)" +== 550 +-- truncate_limit: 100 +SELECT pg_get_function_identity_arguments(0) +-- +FUNCTION: name="pg_get_function_identity_arguments" function="pg_get_function_identity_arguments" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_function_identity_arguments(0)" +== 551 +-- truncate_limit: 100 +SELECT pg_get_function_result(0) +-- +FUNCTION: name="pg_get_function_result" function="pg_get_function_result" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_function_result(0)" +== 552 +-- truncate_limit: 100 +SELECT pg_get_function_arg_default(0, 0) +-- +FUNCTION: name="pg_get_function_arg_default" function="pg_get_function_arg_default" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_function_arg_default(0, 0)" +== 553 +-- truncate_limit: 100 +SELECT pg_get_function_arg_default('pg_class'::regclass, 0) +-- +FUNCTION: name="pg_get_function_arg_default" function="pg_get_function_arg_default" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_function_arg_default('pg_class'::regclass, 0)" +== 554 +-- truncate_limit: 100 +SELECT pg_get_partkeydef(0) +-- +FUNCTION: name="pg_get_partkeydef" function="pg_get_partkeydef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_partkeydef(0)" +== 555 +-- truncate_limit: 100 +-- test rename for a rule defined on a partitioned table +CREATE TABLE rules_parted_table (a int) PARTITION BY LIST (a) +-- +TABLE: name="rules_parted_table" schema="" table="rules_parted_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_parted_table (a int) PARTITION BY LIST (a)" +== 556 +-- truncate_limit: 100 +CREATE TABLE rules_parted_table_1 PARTITION OF rules_parted_table FOR VALUES IN (1) +-- +TABLE: name="rules_parted_table_1" schema="" table="rules_parted_table_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rules_parted_table_1 PARTITION OF rules_parted_table FOR VALUES IN (1)" +== 557 +-- truncate_limit: 100 +CREATE RULE rules_parted_table_insert AS ON INSERT to rules_parted_table + DO INSTEAD INSERT INTO rules_parted_table_1 VALUES (NEW.*) +-- +TABLE: name="rules_parted_table" schema="" table="rules_parted_table" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rules_parted_table_insert AS ON INSERT TO rules_parted_table DO INSTEAD INSERT INTO r..." +== 558 +-- truncate_limit: 100 +ALTER RULE rules_parted_table_insert ON rules_parted_table RENAME TO rules_parted_table_insert_redirect +-- +STMT: RenameStmt +TRUNCATED: "ALTER RULE rules_parted_table_insert ON rules_parted_table RENAME TO rules_parted_table_insert_re..." +== 559 +-- truncate_limit: 100 +DROP TABLE rules_parted_table +-- +TABLE: name="rules_parted_table" schema="" table="rules_parted_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE rules_parted_table" +== 560 +-- truncate_limit: 100 +|-- +-- test MERGE +|-- +CREATE TABLE rule_merge1 (a int, b text) +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_merge1 (a int, b text)" +== 561 +-- truncate_limit: 100 +CREATE TABLE rule_merge2 (a int, b text) +-- +TABLE: name="rule_merge2" schema="" table="rule_merge2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE rule_merge2 (a int, b text)" +== 562 +-- truncate_limit: 100 +CREATE RULE rule1 AS ON INSERT TO rule_merge1 + DO INSTEAD INSERT INTO rule_merge2 VALUES (NEW.*) +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rule1 AS ON INSERT TO rule_merge1 DO INSTEAD INSERT INTO rule_merge2 VALUES (new.*)" +== 563 +-- truncate_limit: 100 +CREATE RULE rule2 AS ON UPDATE TO rule_merge1 + DO INSTEAD UPDATE rule_merge2 SET a = NEW.a, b = NEW.b + WHERE a = OLD.a +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rule2 AS ON UPDATE TO rule_merge1 DO INSTEAD UPDATE rule_merge2 SET a = new.a, b = ne..." +== 564 +-- truncate_limit: 100 +CREATE RULE rule3 AS ON DELETE TO rule_merge1 + DO INSTEAD DELETE FROM rule_merge2 WHERE a = OLD.a +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rule3 AS ON DELETE TO rule_merge1 DO INSTEAD DELETE FROM rule_merge2 WHERE a = old.a" +== 565 +-- truncate_limit: 100 +-- MERGE not supported for table with rules +MERGE INTO rule_merge1 t USING (SELECT 1 AS a) s + ON t.a = s.a + WHEN MATCHED AND t.a < 2 THEN + UPDATE SET b = b || ' updated by merge' + WHEN MATCHED AND t.a > 2 THEN + DELETE + WHEN NOT MATCHED THEN + INSERT VALUES (s.a, '') +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DML +ALIAS: "t"="rule_merge1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rule_merge1 t USING (SELECT ...) s ON t.a = s.a WHEN MATCHED AND t.a < 2 THEN UPDATE S..." +== 566 +-- truncate_limit: 100 +-- should be ok with the other table though +MERGE INTO rule_merge2 t USING (SELECT 1 AS a) s + ON t.a = s.a + WHEN MATCHED AND t.a < 2 THEN + UPDATE SET b = b || ' updated by merge' + WHEN MATCHED AND t.a > 2 THEN + DELETE + WHEN NOT MATCHED THEN + INSERT VALUES (s.a, '') +-- +TABLE: name="rule_merge2" schema="" table="rule_merge2" ctx=DML +ALIAS: "t"="rule_merge2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rule_merge2 t USING (SELECT ...) s ON t.a = s.a WHEN MATCHED AND t.a < 2 THEN UPDATE S..." +== 567 +-- truncate_limit: 100 +-- also ok if the rules are disabled +ALTER TABLE rule_merge1 DISABLE RULE rule1 +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rule_merge1 DISABLE RULE rule1" +== 568 +-- truncate_limit: 100 +ALTER TABLE rule_merge1 DISABLE RULE rule2 +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rule_merge1 DISABLE RULE rule2" +== 569 +-- truncate_limit: 100 +ALTER TABLE rule_merge1 DISABLE RULE rule3 +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE rule_merge1 DISABLE RULE rule3" +== 570 +-- truncate_limit: 100 +MERGE INTO rule_merge1 t USING (SELECT 1 AS a) s + ON t.a = s.a + WHEN MATCHED AND t.a < 2 THEN + UPDATE SET b = b || ' updated by merge' + WHEN MATCHED AND t.a > 2 THEN + DELETE + WHEN NOT MATCHED THEN + INSERT VALUES (s.a, '') +-- +TABLE: name="rule_merge1" schema="" table="rule_merge1" ctx=DML +ALIAS: "t"="rule_merge1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rule_merge1 t USING (SELECT ...) s ON t.a = s.a WHEN MATCHED AND t.a < 2 THEN UPDATE S..." +== 571 +-- truncate_limit: 100 +-- test deparsing +CREATE TABLE sf_target(id int, data text, filling int[]) +-- +TABLE: name="sf_target" schema="" table="sf_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sf_target (id int, data text, filling int[])" +== 572 +-- truncate_limit: 100 +CREATE FUNCTION merge_sf_test() + RETURNS TABLE(action text, a int, b text, id int, data text, filling int[]) + LANGUAGE sql +BEGIN ATOMIC + MERGE INTO sf_target t + USING rule_merge1 s + ON (s.a = t.id) +WHEN MATCHED + AND (s.a + t.id) = 42 + THEN UPDATE SET data = repeat(t.data, s.a) || s.b, id = length(s.b) +WHEN NOT MATCHED + AND (s.b IS NOT NULL) + THEN INSERT (data, id) + VALUES (s.b, s.a) +WHEN MATCHED + AND length(s.b || t.data) > 10 + THEN UPDATE SET data = s.b +WHEN MATCHED + AND s.a > 200 + THEN UPDATE SET filling[s.a] = t.id +WHEN MATCHED + AND s.a > 100 + THEN DELETE +WHEN MATCHED + THEN DO NOTHING +WHEN NOT MATCHED + AND s.a > 200 + THEN INSERT DEFAULT VALUES +WHEN NOT MATCHED + AND s.a > 100 + THEN INSERT (id, data) OVERRIDING USER VALUE + VALUES (s.a, DEFAULT) +WHEN NOT MATCHED + AND s.a > 0 + THEN INSERT + VALUES (s.a, s.b, DEFAULT) +WHEN NOT MATCHED + THEN INSERT (filling[1], id) + VALUES (s.a, s.a) +RETURNING + merge_action() AS action, * +-- +ERROR: syntax error at end of input +CURSORPOS: 982 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 573 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 574 +-- truncate_limit: 100 +CREATE FUNCTION merge_sf_test2() + RETURNS void + LANGUAGE sql +BEGIN ATOMIC + MERGE INTO sf_target t + USING rule_merge1 s + ON (s.a = t.id) +WHEN NOT MATCHED + THEN INSERT (data, id) + VALUES (s.a, s.a) +WHEN MATCHED + THEN UPDATE SET data = s.b +WHEN NOT MATCHED BY SOURCE + THEN DELETE +-- +ERROR: syntax error at end of input +CURSORPOS: 289 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 575 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 576 +-- truncate_limit: 100 +DROP FUNCTION merge_sf_test +-- +FUNCTION: name="merge_sf_test" function="merge_sf_test" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION merge_sf_test" +== 577 +-- truncate_limit: 100 +DROP FUNCTION merge_sf_test2 +-- +FUNCTION: name="merge_sf_test2" function="merge_sf_test2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION merge_sf_test2" +== 578 +-- truncate_limit: 100 +DROP TABLE sf_target +-- +TABLE: name="sf_target" schema="" table="sf_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sf_target" +== 579 +-- truncate_limit: 100 +|-- +-- Test enabling/disabling +|-- +CREATE TABLE ruletest1 (a int) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ruletest1 (a int)" +== 580 +-- truncate_limit: 100 +CREATE TABLE ruletest2 (b int) +-- +TABLE: name="ruletest2" schema="" table="ruletest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ruletest2 (b int)" +== 581 +-- truncate_limit: 100 +CREATE RULE rule1 AS ON INSERT TO ruletest1 + DO INSTEAD INSERT INTO ruletest2 VALUES (NEW.*) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rule1 AS ON INSERT TO ruletest1 DO INSTEAD INSERT INTO ruletest2 VALUES (new.*)" +== 582 +-- truncate_limit: 100 +INSERT INTO ruletest1 VALUES (1) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest1 VALUES (1)" +== 583 +-- truncate_limit: 100 +ALTER TABLE ruletest1 DISABLE RULE rule1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ruletest1 DISABLE RULE rule1" +== 584 +-- truncate_limit: 100 +INSERT INTO ruletest1 VALUES (2) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest1 VALUES (2)" +== 585 +-- truncate_limit: 100 +ALTER TABLE ruletest1 ENABLE RULE rule1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ruletest1 ENABLE RULE rule1" +== 586 +-- truncate_limit: 100 +SET session_replication_role = replica +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_replication_role TO replica" +== 587 +-- truncate_limit: 100 +INSERT INTO ruletest1 VALUES (3) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest1 VALUES (3)" +== 588 +-- truncate_limit: 100 +ALTER TABLE ruletest1 ENABLE REPLICA RULE rule1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ruletest1 ENABLE REPLICA RULE rule1" +== 589 +-- truncate_limit: 100 +INSERT INTO ruletest1 VALUES (4) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest1 VALUES (4)" +== 590 +-- truncate_limit: 100 +RESET session_replication_role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_replication_role" +== 591 +-- truncate_limit: 100 +INSERT INTO ruletest1 VALUES (5) +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest1 VALUES (5)" +== 592 +-- truncate_limit: 100 +SELECT * FROM ruletest1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ruletest1" +== 593 +-- truncate_limit: 100 +SELECT * FROM ruletest2 +-- +TABLE: name="ruletest2" schema="" table="ruletest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ruletest2" +== 594 +-- truncate_limit: 100 +DROP TABLE ruletest1 +-- +TABLE: name="ruletest1" schema="" table="ruletest1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ruletest1" +== 595 +-- truncate_limit: 100 +DROP TABLE ruletest2 +-- +TABLE: name="ruletest2" schema="" table="ruletest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ruletest2" +== 596 +-- truncate_limit: 100 +|-- +-- Test non-SELECT rule on security invoker view. +-- Should use view owner's permissions. +|-- +CREATE USER regress_rule_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_rule_user1" +== 597 +-- truncate_limit: 100 +CREATE TABLE ruletest_t1 (x int) +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ruletest_t1 (x int)" +== 598 +-- truncate_limit: 100 +CREATE TABLE ruletest_t2 (x int) +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ruletest_t2 (x int)" +== 599 +-- truncate_limit: 100 +CREATE VIEW ruletest_v1 WITH (security_invoker=true) AS + SELECT * FROM ruletest_t1 +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DDL +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ruletest_v1 WITH (security_invoker=true) AS SELECT * FROM ruletest_t1" +== 600 +-- truncate_limit: 100 +GRANT INSERT ON ruletest_v1 TO regress_rule_user1 +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON ruletest_v1 TO regress_rule_user1" +== 601 +-- truncate_limit: 100 +CREATE RULE rule1 AS ON INSERT TO ruletest_v1 + DO INSTEAD INSERT INTO ruletest_t2 VALUES (NEW.*) +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rule1 AS ON INSERT TO ruletest_v1 DO INSTEAD INSERT INTO ruletest_t2 VALUES (new.*)" +== 602 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rule_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rule_user1" +== 603 +-- truncate_limit: 100 +INSERT INTO ruletest_v1 VALUES (1) +-- +TABLE: name="ruletest_v1" schema="" table="ruletest_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ruletest_v1 VALUES (1)" +== 604 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 605 +-- truncate_limit: 100 +-- Test that main query's relation's permissions are checked before +-- the rule action's relation's. +CREATE TABLE ruletest_t3 (x int) +-- +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ruletest_t3 (x int)" +== 606 +-- truncate_limit: 100 +CREATE RULE rule2 AS ON UPDATE TO ruletest_t1 + DO INSTEAD INSERT INTO ruletest_t2 VALUES (OLD.*) +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rule2 AS ON UPDATE TO ruletest_t1 DO INSTEAD INSERT INTO ruletest_t2 VALUES (old.*)" +== 607 +-- truncate_limit: 100 +REVOKE ALL ON ruletest_t2 FROM regress_rule_user1 +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON ruletest_t2 FROM regress_rule_user1" +== 608 +-- truncate_limit: 100 +REVOKE ALL ON ruletest_t3 FROM regress_rule_user1 +-- +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON ruletest_t3 FROM regress_rule_user1" +== 609 +-- truncate_limit: 100 +ALTER TABLE ruletest_t1 OWNER TO regress_rule_user1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ruletest_t1 OWNER TO regress_rule_user1" +== 610 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_rule_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_rule_user1" +== 611 +-- truncate_limit: 100 +UPDATE ruletest_t1 t1 SET x = 0 FROM ruletest_t3 t3 WHERE t1.x = t3.x +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DML +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=Select +ALIAS: "t1"="ruletest_t1" +ALIAS: "t3"="ruletest_t3" +STMT: UpdateStmt +TRUNCATED: "UPDATE ruletest_t1 t1 SET x = 0 FROM ruletest_t3 t3 WHERE t1.x = t3.x" +== 612 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 613 +-- truncate_limit: 100 +SELECT * FROM ruletest_t1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ruletest_t1" +== 614 +-- truncate_limit: 100 +SELECT * FROM ruletest_t2 +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ruletest_t2" +== 615 +-- truncate_limit: 100 +DROP VIEW ruletest_v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW ruletest_v1" +== 616 +-- truncate_limit: 100 +DROP RULE rule2 ON ruletest_t1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE rule2 ON ruletest_t1" +== 617 +-- truncate_limit: 100 +DROP TABLE ruletest_t3 +-- +TABLE: name="ruletest_t3" schema="" table="ruletest_t3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ruletest_t3" +== 618 +-- truncate_limit: 100 +DROP TABLE ruletest_t2 +-- +TABLE: name="ruletest_t2" schema="" table="ruletest_t2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ruletest_t2" +== 619 +-- truncate_limit: 100 +DROP TABLE ruletest_t1 +-- +TABLE: name="ruletest_t1" schema="" table="ruletest_t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ruletest_t1" +== 620 +-- truncate_limit: 100 +DROP USER regress_rule_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_rule_user1" diff --git a/parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json new file mode 100644 index 0000000..3e33966 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json @@ -0,0 +1,7 @@ +{ + "todo": [ + "001", + "002", + "003" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/sanity_check.test b/parser/testdata/summary_truncate/postgres_regress/sanity_check.test new file mode 100644 index 0000000..380c8ce --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sanity_check.test @@ -0,0 +1,55 @@ +== 001 +-- truncate_limit: 100 +VACUUM +-- +STMT: VacuumStmt +TRUNCATED: "VACUUM" +== 002 +-- truncate_limit: 100 +|-- +-- Sanity check: every system catalog that has OIDs should have +-- a unique index on OID. This ensures that the OIDs will be unique, +-- even after the OID counter wraps around. +-- We exclude non-system tables from the check by looking at nspname. +|-- +SELECT relname, nspname + FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a ON (attrelid = c.oid AND attname = 'oid') + WHERE relkind = 'r' and c.oid < 16384 + AND ((nspname ~ '^pg_') IS NOT FALSE) + AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid + AND indkey[0] = a.attnum AND indnatts = 1 + AND indisunique AND indimmediate) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_namespace" schema="" table="pg_namespace" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +ALIAS: "n"="pg_namespace" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="nspname" +FILTER: schema="" table="" column="indrelid" +FILTER: schema="" table="c" column="oid" +FILTER: schema="" table="" column="indkey" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="" column="indnatts" +FILTER: schema="" table="" column="indisunique" +FILTER: schema="" table="" column="indimmediate" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a O..." +== 003 +-- truncate_limit: 100 +-- check that relations without storage don't have relfilenode +SELECT relname, relkind + FROM pg_class + WHERE relkind IN ('v', 'c', 'f', 'p', 'I') + AND relfilenode <> 0 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relfilenode" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relkind FROM pg_class WHERE ..." diff --git a/parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json b/parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/security_label.test b/parser/testdata/summary_truncate/postgres_regress/security_label.test new file mode 100644 index 0000000..146c9eb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/security_label.test @@ -0,0 +1,198 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test for facilities of security label +|-- + +-- initial setups +SET client_min_messages TO 'warning' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO warning" +== 002 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_seclabel_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_seclabel_user1" +== 003 +-- truncate_limit: 100 +DROP ROLE IF EXISTS regress_seclabel_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_seclabel_user2" +== 004 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 005 +-- truncate_limit: 100 +CREATE USER regress_seclabel_user1 WITH CREATEROLE +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_seclabel_user1 WITH CREATEROLE" +== 006 +-- truncate_limit: 100 +CREATE USER regress_seclabel_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_seclabel_user2" +== 007 +-- truncate_limit: 100 +CREATE TABLE seclabel_tbl1 (a int, b text) +-- +TABLE: name="seclabel_tbl1" schema="" table="seclabel_tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE seclabel_tbl1 (a int, b text)" +== 008 +-- truncate_limit: 100 +CREATE TABLE seclabel_tbl2 (x int, y text) +-- +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE seclabel_tbl2 (x int, y text)" +== 009 +-- truncate_limit: 100 +CREATE VIEW seclabel_view1 AS SELECT * FROM seclabel_tbl2 +-- +TABLE: name="seclabel_view1" schema="" table="seclabel_view1" ctx=DDL +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW seclabel_view1 AS SELECT * FROM seclabel_tbl2" +== 010 +-- truncate_limit: 100 +CREATE FUNCTION seclabel_four() RETURNS integer AS $$SELECT 4$$ language sql +-- +FUNCTION: name="seclabel_four" function="seclabel_four" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION seclabel_four() RETURNS int AS $$SELECT 4$$ LANGUAGE sql" +== 011 +-- truncate_limit: 100 +CREATE DOMAIN seclabel_domain AS text +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN seclabel_domain AS text" +== 012 +-- truncate_limit: 100 +ALTER TABLE seclabel_tbl1 OWNER TO regress_seclabel_user1 +-- +TABLE: name="seclabel_tbl1" schema="" table="seclabel_tbl1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE seclabel_tbl1 OWNER TO regress_seclabel_user1" +== 013 +-- truncate_limit: 100 +ALTER TABLE seclabel_tbl2 OWNER TO regress_seclabel_user2 +-- +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE seclabel_tbl2 OWNER TO regress_seclabel_user2" +== 014 +-- truncate_limit: 100 +|-- +-- Test of SECURITY LABEL statement without a plugin +|-- +SECURITY LABEL ON TABLE seclabel_tbl1 IS 'classified' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL ON TABLE seclabel_tbl1 IS 'classified'" +== 015 +-- truncate_limit: 100 +-- fail +SECURITY LABEL FOR 'dummy' ON TABLE seclabel_tbl1 IS 'classified' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL FOR dummy ON TABLE seclabel_tbl1 IS 'classified'" +== 016 +-- truncate_limit: 100 +-- fail +SECURITY LABEL ON TABLE seclabel_tbl1 IS '...invalid label...' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL ON TABLE seclabel_tbl1 IS '...invalid label...'" +== 017 +-- truncate_limit: 100 +-- fail +SECURITY LABEL ON TABLE seclabel_tbl3 IS 'unclassified' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL ON TABLE seclabel_tbl3 IS 'unclassified'" +== 018 +-- truncate_limit: 100 +-- fail + +SECURITY LABEL ON ROLE regress_seclabel_user1 IS 'classified' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL ON ROLE regress_seclabel_user1 IS 'classified'" +== 019 +-- truncate_limit: 100 +-- fail +SECURITY LABEL FOR 'dummy' ON ROLE regress_seclabel_user1 IS 'classified' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL FOR dummy ON ROLE regress_seclabel_user1 IS 'classified'" +== 020 +-- truncate_limit: 100 +-- fail +SECURITY LABEL ON ROLE regress_seclabel_user1 IS '...invalid label...' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL ON ROLE regress_seclabel_user1 IS '...invalid label...'" +== 021 +-- truncate_limit: 100 +-- fail +SECURITY LABEL ON ROLE regress_seclabel_user3 IS 'unclassified' +-- +STMT: SecLabelStmt +TRUNCATED: "SECURITY LABEL ON ROLE regress_seclabel_user3 IS 'unclassified'" +== 022 +-- truncate_limit: 100 +-- fail + +-- clean up objects +DROP FUNCTION seclabel_four() +-- +FUNCTION: name="seclabel_four" function="seclabel_four" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION seclabel_four()" +== 023 +-- truncate_limit: 100 +DROP DOMAIN seclabel_domain +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN seclabel_domain" +== 024 +-- truncate_limit: 100 +DROP VIEW seclabel_view1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW seclabel_view1" +== 025 +-- truncate_limit: 100 +DROP TABLE seclabel_tbl1 +-- +TABLE: name="seclabel_tbl1" schema="" table="seclabel_tbl1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE seclabel_tbl1" +== 026 +-- truncate_limit: 100 +DROP TABLE seclabel_tbl2 +-- +TABLE: name="seclabel_tbl2" schema="" table="seclabel_tbl2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE seclabel_tbl2" +== 027 +-- truncate_limit: 100 +DROP USER regress_seclabel_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_seclabel_user1" +== 028 +-- truncate_limit: 100 +DROP USER regress_seclabel_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_seclabel_user2" diff --git a/parser/testdata/summary_truncate/postgres_regress/select.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select.metadata.json new file mode 100644 index 0000000..8e8d1f7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select.metadata.json @@ -0,0 +1,91 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select.test b/parser/testdata/summary_truncate/postgres_regress/select.test new file mode 100644 index 0000000..275377d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select.test @@ -0,0 +1,811 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SELECT +|-- + +-- btree index +-- awk '{if($1<10){print;}else{next;}}' onek.data | sort +0n -1 +|-- +SELECT * FROM onek + WHERE onek.unique1 < 10 + ORDER BY onek.unique1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek WHERE onek.unique1 < 10 ORDER BY onek.unique1" +== 002 +-- truncate_limit: 100 +|-- +-- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 +|-- +SELECT onek.unique1, onek.stringu1 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using > +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT onek.unique1, onek.stringu1 FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 USING >" +== 003 +-- truncate_limit: 100 +|-- +-- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 +|-- +SELECT onek.unique1, onek.stringu1 FROM onek + WHERE onek.unique1 > 980 + ORDER BY stringu1 using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT onek.unique1, onek.stringu1 FROM onek WHERE onek.unique1 > 980 ORDER BY stringu1 USING <" +== 004 +-- truncate_limit: 100 +|-- +-- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | +-- sort +1d -2 +0nr -1 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 > 980 + ORDER BY string4 using <, unique1 using > +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE onek.unique1 > 980 ORDER BY string4 USING <, unique1 USING >" +== 005 +-- truncate_limit: 100 +|-- +-- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | +-- sort +1dr -2 +0n -1 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 > 980 + ORDER BY string4 using >, unique1 using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE onek.unique1 > 980 ORDER BY string4 USING >, unique1 USING <" +== 006 +-- truncate_limit: 100 +|-- +-- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | +-- sort +0nr -1 +1d -2 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using >, string4 using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 USING >, string4 USING <" +== 007 +-- truncate_limit: 100 +|-- +-- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | +-- sort +0n -1 +1dr -2 +|-- +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using <, string4 using > +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 USING <, string4 USING >" +== 008 +-- truncate_limit: 100 +|-- +-- test partial btree indexes +|-- +-- As of 7.2, planner probably won't pick an indexscan without stats, +-- so ANALYZE first. Also, we want to prevent it from picking a bitmapscan +-- followed by sort, because that could hide index ordering problems. +|-- +ANALYZE onek2 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE onek2" +== 009 +-- truncate_limit: 100 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 010 +-- truncate_limit: 100 +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 011 +-- truncate_limit: 100 +SET enable_sort TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 012 +-- truncate_limit: 100 +|-- +-- awk '{if($1<10){print $0;}else{next;}}' onek.data | sort +0n -1 +|-- +SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10" +== 013 +-- truncate_limit: 100 +|-- +-- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 +|-- +SELECT onek2.unique1, onek2.stringu1 FROM onek2 + WHERE onek2.unique1 < 20 + ORDER BY unique1 using > +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT onek2.unique1, onek2.stringu1 FROM onek2 WHERE onek2.unique1 < 20 ORDER BY unique1 USING >" +== 014 +-- truncate_limit: 100 +|-- +-- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 +|-- +SELECT onek2.unique1, onek2.stringu1 FROM onek2 + WHERE onek2.unique1 > 980 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT onek2.unique1, onek2.stringu1 FROM onek2 WHERE onek2.unique1 > 980" +== 015 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 016 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 017 +-- truncate_limit: 100 +RESET enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 018 +-- truncate_limit: 100 +|-- +-- awk '{print $1,$2;}' person.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - student.data | +-- awk 'BEGIN{FS=" ";}{if(NF!=2){print $4,$5;}else{print;}}' - stud_emp.data +|-- +-- SELECT name, age FROM person*; ??? check if different +SELECT p.name, p.age FROM person* p +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +STMT: SelectStmt +TRUNCATED: "SELECT p.name, p.age FROM person p" +== 019 +-- truncate_limit: 100 +|-- +-- awk '{print $1,$2;}' person.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data | +-- awk '{if(NF!=2){print $3,$2;}else{print;}}' - student.data | +-- awk 'BEGIN{FS=" ";}{if(NF!=1){print $4,$5;}else{print;}}' - stud_emp.data | +-- sort +1nr -2 +|-- +SELECT p.name, p.age FROM person* p ORDER BY age using >, name +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +STMT: SelectStmt +TRUNCATED: "SELECT p.name, p.age FROM person p ORDER BY age USING >, name" +== 020 +-- truncate_limit: 100 +|-- +-- Test some cases involving whole-row Var referencing a subquery +|-- +select foo from (select 1 offset 0) as foo +-- +STMT: SelectStmt +TRUNCATED: "SELECT foo FROM (SELECT 1 OFFSET 0) foo" +== 021 +-- truncate_limit: 100 +select foo from (select null offset 0) as foo +-- +STMT: SelectStmt +TRUNCATED: "SELECT foo FROM (SELECT NULL OFFSET 0) foo" +== 022 +-- truncate_limit: 100 +select foo from (select 'xyzzy',1,null offset 0) as foo +-- +STMT: SelectStmt +TRUNCATED: "SELECT foo FROM (SELECT 'xyzzy', 1, NULL OFFSET 0) foo" +== 023 +-- truncate_limit: 100 +|-- +-- Test VALUES lists +|-- +select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) + WHERE onek.unique1 = v.i and onek.stringu1 = v.j +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +FILTER: schema="" table="v" column="i" +FILTER: schema="" table="onek" column="stringu1" +FILTER: schema="" table="v" column="j" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek, (VALUES (...)) v(i, j) WHERE onek.unique1 = v.i AND onek.stringu1 = v.j" +== 024 +-- truncate_limit: 100 +-- a more complex case +-- looks like we're coding lisp :-) +select * from onek, + (values ((select i from + (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i) + order by i asc limit 1))) bar (i) + where onek.unique1 = bar.i +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="onek" column="unique1" +FILTER: schema="" table="bar" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek, (VALUES (...)) bar(i) WHERE onek.unique1 = bar.i" +== 025 +-- truncate_limit: 100 +-- try VALUES in a subquery +select * from onek + where (unique1,ten) in (values (1,1), (20,0), (99,9), (17,99)) + order by unique1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="ten" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek WHERE (unique1, ten) IN (VALUES (...)) ORDER BY unique1" +== 026 +-- truncate_limit: 100 +-- VALUES is also legal as a standalone query or a set-operation member +VALUES (1,2), (3,4+4), (7,77.7) +-- +STMT: SelectStmt +TRUNCATED: "VALUES (1, 2), (3, 4 + 4), (7, 77.7)" +== 027 +-- truncate_limit: 100 +VALUES (1,2), (3,4+4), (7,77.7) +UNION ALL +SELECT 2+2, 57 +UNION ALL +TABLE int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "(VALUES (1, 2), (3, 4 + 4), (7, 77.7) UNION ALL SELECT 2 + 2, 57) UNION ALL SELECT * FROM int8_tbl" +== 028 +-- truncate_limit: 100 +-- corner case: VALUES with no columns +CREATE TEMP TABLE nocols() +-- +TABLE: name="nocols" schema="" table="nocols" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE nocols ()" +== 029 +-- truncate_limit: 100 +INSERT INTO nocols DEFAULT VALUES +-- +TABLE: name="nocols" schema="" table="nocols" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO nocols DEFAULT VALUES" +== 030 +-- truncate_limit: 100 +SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v +-- +TABLE: name="nocols" schema="" table="nocols" ctx=Select +ALIAS: "n"="nocols" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nocols n, LATERAL (VALUES (n.*)) v" +== 031 +-- truncate_limit: 100 +|-- +-- Test ORDER BY options +|-- + +CREATE TEMP TABLE foo (f1 int) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (f1 int)" +== 032 +-- truncate_limit: 100 +INSERT INTO foo VALUES (42),(3),(10),(7),(null),(null),(1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (42), (3), (10), (7), (NULL), (NULL), (1)" +== 033 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1" +== 034 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 ASC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 ASC" +== 035 +-- truncate_limit: 100 +-- same thing +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 NULLS FIRST" +== 036 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC" +== 037 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC NULLS LAST" +== 038 +-- truncate_limit: 100 +-- check if indexscans do the right things +CREATE INDEX fooi ON foo (f1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fooi ON foo USING btree (f1)" +== 039 +-- truncate_limit: 100 +SET enable_sort = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO FALSE" +== 040 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1" +== 041 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 NULLS FIRST" +== 042 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC" +== 043 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC NULLS LAST" +== 044 +-- truncate_limit: 100 +DROP INDEX fooi +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX fooi" +== 045 +-- truncate_limit: 100 +CREATE INDEX fooi ON foo (f1 DESC) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fooi ON foo USING btree (f1 DESC)" +== 046 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1" +== 047 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 NULLS FIRST" +== 048 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC" +== 049 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC NULLS LAST" +== 050 +-- truncate_limit: 100 +DROP INDEX fooi +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX fooi" +== 051 +-- truncate_limit: 100 +CREATE INDEX fooi ON foo (f1 DESC NULLS LAST) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fooi ON foo USING btree (f1 DESC NULLS LAST)" +== 052 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1" +== 053 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 NULLS FIRST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 NULLS FIRST" +== 054 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC" +== 055 +-- truncate_limit: 100 +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo ORDER BY f1 DESC NULLS LAST" +== 056 +-- truncate_limit: 100 +|-- +-- Test planning of some cases with partial indexes +|-- + +-- partial index is usable +explain (costs off) +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM onek2 WHERE unique2 = 11 AND stringu1 = 'ATAAAA'" +== 057 +-- truncate_limit: 100 +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek2 WHERE unique2 = 11 AND stringu1 = 'ATAAAA'" +== 058 +-- truncate_limit: 100 +-- actually run the query with an analyze to use the partial index +explain (costs off, analyze on, timing off, summary off) +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, ANALYZE ON, TIMING OFF, SUMMARY OFF) SELECT * FROM onek2 WHERE unique2 = 11 A..." +== 059 +-- truncate_limit: 100 +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 = 'ATAAAA'" +== 060 +-- truncate_limit: 100 +select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 = 'ATAAAA'" +== 061 +-- truncate_limit: 100 +-- partial index predicate implies clause, so no need for retest +explain (costs off) +select * from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B'" +== 062 +-- truncate_limit: 100 +select * from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B'" +== 063 +-- truncate_limit: 100 +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B'" +== 064 +-- truncate_limit: 100 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B'" +== 065 +-- truncate_limit: 100 +-- but if it's an update target, must retest anyway +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B' FOR UPDATE" +== 066 +-- truncate_limit: 100 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B' FOR UPDATE" +== 067 +-- truncate_limit: 100 +-- partial index is not applicable +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'C' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'C'" +== 068 +-- truncate_limit: 100 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'C' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'C'" +== 069 +-- truncate_limit: 100 +-- partial index implies clause, but bitmap scan must recheck predicate anyway +SET enable_indexscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 070 +-- truncate_limit: 100 +explain (costs off) +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B'" +== 071 +-- truncate_limit: 100 +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT unique2 FROM onek2 WHERE unique2 = 11 AND stringu1 < 'B'" +== 072 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 073 +-- truncate_limit: 100 +-- check multi-index cases too +explain (costs off) +select unique1, unique2 from onek2 + where (unique2 = 11 or unique1 = 0) and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, unique2 FROM onek2 WHERE (unique2 = 11 OR unique1 = 0) AND st..." +== 074 +-- truncate_limit: 100 +select unique1, unique2 from onek2 + where (unique2 = 11 or unique1 = 0) and stringu1 < 'B' +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek2 WHERE (unique2 = 11 OR unique1 = 0) AND stringu1 < 'B'" +== 075 +-- truncate_limit: 100 +explain (costs off) +select unique1, unique2 from onek2 + where (unique2 = 11 and stringu1 < 'B') or unique1 = 0 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1, unique2 FROM onek2 WHERE (unique2 = 11 AND stringu1 < 'B') OR..." +== 076 +-- truncate_limit: 100 +select unique1, unique2 from onek2 + where (unique2 = 11 and stringu1 < 'B') or unique1 = 0 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="stringu1" +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT unique1, unique2 FROM onek2 WHERE (unique2 = 11 AND stringu1 < 'B') OR unique1 = 0" +== 077 +-- truncate_limit: 100 +|-- +-- Test some corner cases that have been known to confuse the planner +|-- + +-- ORDER BY on a constant doesn't really need any sorting +SELECT 1 AS x ORDER BY x +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS x ORDER BY x" +== 078 +-- truncate_limit: 100 +-- But ORDER BY on a set-valued expression does +create function sillysrf(int) returns setof int as + 'values (1),(10),(2),($1)' language sql immutable +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sillysrf(int) RETURNS SETOF int AS $$values (1),(10),(2),($1)$$ LANGUAGE sql IMMU..." +== 079 +-- truncate_limit: 100 +select sillysrf(42) +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sillysrf(42)" +== 080 +-- truncate_limit: 100 +select sillysrf(-1) order by 1 +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sillysrf(-1) ORDER BY 1" +== 081 +-- truncate_limit: 100 +drop function sillysrf(int) +-- +FUNCTION: name="sillysrf" function="sillysrf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sillysrf(int)" +== 082 +-- truncate_limit: 100 +-- 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 +-- +FILTER: schema="" table="" column="k" +FILTER: schema="" table="" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (2), (NULL), (1)) v(k) WHERE k = k ORDER BY k" +== 083 +-- truncate_limit: 100 +select * from (values (2),(null),(1)) v(k) where k = k +-- +FILTER: schema="" table="" column="k" +FILTER: schema="" table="" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (2), (NULL), (1)) v(k) WHERE k = k" +== 084 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="list_parted_tbl" schema="" table="list_parted_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted_tbl (a int, b int) PARTITION BY LIST (a)" +== 085 +-- truncate_limit: 100 +create table list_parted_tbl1 partition of list_parted_tbl + for values in (1) partition by list(b) +-- +TABLE: name="list_parted_tbl1" schema="" table="list_parted_tbl1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted_tbl1 PARTITION OF list_parted_tbl FOR VALUES IN (1) PARTITION BY LIST (b)" +== 086 +-- truncate_limit: 100 +explain (costs off) select * from list_parted_tbl +-- +TABLE: name="list_parted_tbl" schema="" table="list_parted_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM list_parted_tbl" +== 087 +-- truncate_limit: 100 +drop table list_parted_tbl +-- +TABLE: name="list_parted_tbl" schema="" table="list_parted_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE list_parted_tbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json new file mode 100644 index 0000000..f476ef8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json @@ -0,0 +1,80 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select_distinct.test b/parser/testdata/summary_truncate/postgres_regress/select_distinct.test new file mode 100644 index 0000000..03242fb --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_distinct.test @@ -0,0 +1,639 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SELECT_DISTINCT +|-- + +|-- +-- awk '{print $3;}' onek.data | sort -n | uniq +|-- +SELECT DISTINCT two FROM onek ORDER BY 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT two FROM onek ORDER BY 1" +== 002 +-- truncate_limit: 100 +|-- +-- awk '{print $5;}' onek.data | sort -n | uniq +|-- +SELECT DISTINCT ten FROM onek ORDER BY 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ten FROM onek ORDER BY 1" +== 003 +-- truncate_limit: 100 +|-- +-- awk '{print $16;}' onek.data | sort -d | uniq +|-- +SELECT DISTINCT string4 FROM onek ORDER BY 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT string4 FROM onek ORDER BY 1" +== 004 +-- truncate_limit: 100 +|-- +-- awk '{print $3,$16,$5;}' onek.data | sort -d | uniq | +-- sort +0n -1 +1d -2 +2n -3 +|-- +SELECT DISTINCT two, string4, ten + FROM onek + ORDER BY two using <, string4 using <, ten using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT two, string4, ten FROM onek ORDER BY two USING <, string4 USING <, ten USING <" +== 005 +-- truncate_limit: 100 +|-- +-- awk '{print $2;}' person.data | +-- awk '{if(NF!=1){print $2;}else{print;}}' - emp.data | +-- awk '{if(NF!=1){print $2;}else{print;}}' - student.data | +-- awk 'BEGIN{FS=" ";}{if(NF!=1){print $5;}else{print;}}' - stud_emp.data | +-- sort -n -r | uniq +|-- +SELECT DISTINCT p.age FROM person* p ORDER BY age using > +-- +TABLE: name="person" schema="" table="person" ctx=Select +ALIAS: "p"="person" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT p.age FROM person p ORDER BY age USING >" +== 006 +-- truncate_limit: 100 +|-- +-- Check mentioning same column more than once +|-- + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT count(*) FROM + (SELECT DISTINCT two, four, two FROM tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM (SELECT DISTINCT two, four, two FROM tenk1) ss" +== 007 +-- truncate_limit: 100 +SELECT count(*) FROM + (SELECT DISTINCT two, four, two FROM tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT DISTINCT two, four, two FROM tenk1) ss" +== 008 +-- truncate_limit: 100 +|-- +-- 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' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 009 +-- truncate_limit: 100 +-- Produce results with sorting. + +SET enable_hashagg=FALSE +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 010 +-- truncate_limit: 100 +SET jit_above_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO 0" +== 011 +-- truncate_limit: 100 +EXPLAIN (costs off) +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT g % 1000 FROM generate_series(0, 9999) g" +== 012 +-- truncate_limit: 100 +CREATE TABLE distinct_group_1 AS +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE distinct_group_1 AS SELECT DISTINCT g % 1000 FROM generate_series(0, 9999) g" +== 013 +-- truncate_limit: 100 +SET jit_above_cost TO DEFAULT +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO DEFAULT" +== 014 +-- truncate_limit: 100 +CREATE TABLE distinct_group_2 AS +SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g +-- +TABLE: name="distinct_group_2" schema="" table="distinct_group_2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE distinct_group_2 AS SELECT DISTINCT (g % 1000)::text FROM generate_series(0, 9999) g" +== 015 +-- truncate_limit: 100 +SET enable_seqscan = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO 0" +== 016 +-- truncate_limit: 100 +-- Check to see we get an incremental sort plan +EXPLAIN (costs off) +SELECT DISTINCT hundred, two FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT hundred, two FROM tenk1" +== 017 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 018 +-- truncate_limit: 100 +SET enable_hashagg=TRUE +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO TRUE" +== 019 +-- truncate_limit: 100 +-- Produce results with hash aggregation. + +SET enable_sort=FALSE +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO FALSE" +== 020 +-- truncate_limit: 100 +SET jit_above_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO 0" +== 021 +-- truncate_limit: 100 +EXPLAIN (costs off) +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT g % 1000 FROM generate_series(0, 9999) g" +== 022 +-- truncate_limit: 100 +CREATE TABLE distinct_hash_1 AS +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE distinct_hash_1 AS SELECT DISTINCT g % 1000 FROM generate_series(0, 9999) g" +== 023 +-- truncate_limit: 100 +SET jit_above_cost TO DEFAULT +-- +STMT: VariableSetStmt +TRUNCATED: "SET jit_above_cost TO DEFAULT" +== 024 +-- truncate_limit: 100 +CREATE TABLE distinct_hash_2 AS +SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g +-- +TABLE: name="distinct_hash_2" schema="" table="distinct_hash_2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE distinct_hash_2 AS SELECT DISTINCT (g % 1000)::text FROM generate_series(0, 9999) g" +== 025 +-- truncate_limit: 100 +SET enable_sort=TRUE +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO TRUE" +== 026 +-- truncate_limit: 100 +SET work_mem TO DEFAULT +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO DEFAULT" +== 027 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) UNION ALL (SELECT * FROM di..." +== 028 +-- truncate_limit: 100 +(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) + UNION ALL +(SELECT * FROM distinct_group_1 EXCEPT SELECT * FROM distinct_hash_1) +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=Select +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) UNION ALL (SELECT * FROM di..." +== 029 +-- truncate_limit: 100 +DROP TABLE distinct_hash_1 +-- +TABLE: name="distinct_hash_1" schema="" table="distinct_hash_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE distinct_hash_1" +== 030 +-- truncate_limit: 100 +DROP TABLE distinct_hash_2 +-- +TABLE: name="distinct_hash_2" schema="" table="distinct_hash_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE distinct_hash_2" +== 031 +-- truncate_limit: 100 +DROP TABLE distinct_group_1 +-- +TABLE: name="distinct_group_1" schema="" table="distinct_group_1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE distinct_group_1" +== 032 +-- truncate_limit: 100 +DROP TABLE distinct_group_2 +-- +TABLE: name="distinct_group_2" schema="" table="distinct_group_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE distinct_group_2" +== 033 +-- truncate_limit: 100 +-- Test parallel DISTINCT +SET parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 034 +-- truncate_limit: 100 +SET parallel_setup_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 035 +-- truncate_limit: 100 +SET min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 036 +-- truncate_limit: 100 +SET max_parallel_workers_per_gather=2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 037 +-- truncate_limit: 100 +-- Ensure we get a parallel plan +EXPLAIN (costs off) +SELECT DISTINCT four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT four FROM tenk1" +== 038 +-- truncate_limit: 100 +-- Ensure the parallel plan produces the correct results +SELECT DISTINCT four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT four FROM tenk1" +== 039 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION distinct_func(a INT) RETURNS INT AS $$ + BEGIN + RETURN a; + END; +$$ LANGUAGE plpgsql PARALLEL UNSAFE +-- +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION distinct_func(a int) RETURNS int AS $$\n BEGIN\n RETURN a;\n END;\n$$..." +== 040 +-- truncate_limit: 100 +-- Ensure we don't do parallel distinct with a parallel unsafe function +EXPLAIN (COSTS OFF) +SELECT DISTINCT distinct_func(1) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT distinct_func(1) FROM tenk1" +== 041 +-- truncate_limit: 100 +-- make the function parallel safe +CREATE OR REPLACE FUNCTION distinct_func(a INT) RETURNS INT AS $$ + BEGIN + RETURN a; + END; +$$ LANGUAGE plpgsql PARALLEL SAFE +-- +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION distinct_func(a int) RETURNS int AS $$\n BEGIN\n RETURN a;\n END;\n$$..." +== 042 +-- truncate_limit: 100 +-- Ensure we do parallel distinct now that the function is parallel safe +EXPLAIN (COSTS OFF) +SELECT DISTINCT distinct_func(1) FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="distinct_func" function="distinct_func" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT distinct_func(1) FROM tenk1" +== 043 +-- truncate_limit: 100 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers_per_gather" +== 044 +-- truncate_limit: 100 +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_table_scan_size" +== 045 +-- truncate_limit: 100 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 046 +-- truncate_limit: 100 +RESET parallel_tuple_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_tuple_cost" +== 047 +-- truncate_limit: 100 +|-- +-- Test the planner's ability to use a LIMIT 1 instead of a Unique node when +-- all of the distinct_pathkeys have been marked as redundant +|-- + +-- Ensure we get a plan with a Limit 1 +EXPLAIN (COSTS OFF) +SELECT DISTINCT four FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT four FROM tenk1 WHERE four = 0" +== 048 +-- truncate_limit: 100 +-- Ensure the above gives us the correct result +SELECT DISTINCT four FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT four FROM tenk1 WHERE four = 0" +== 049 +-- truncate_limit: 100 +-- Ensure we get a plan with a Limit 1 +EXPLAIN (COSTS OFF) +SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="two" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0" +== 050 +-- truncate_limit: 100 +-- Ensure no rows are returned +SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="two" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0" +== 051 +-- truncate_limit: 100 +-- Ensure we get a plan with a Limit 1 when the SELECT list contains constants +EXPLAIN (COSTS OFF) +SELECT DISTINCT four,1,2,3 FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT four, 1, 2, 3 FROM tenk1 WHERE four = 0" +== 052 +-- truncate_limit: 100 +-- Ensure we only get 1 row +SELECT DISTINCT four,1,2,3 FROM tenk1 WHERE four = 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT four, 1, 2, 3 FROM tenk1 WHERE four = 0" +== 053 +-- truncate_limit: 100 +SET parallel_setup_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 054 +-- truncate_limit: 100 +SET min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 055 +-- truncate_limit: 100 +SET max_parallel_workers_per_gather=2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 2" +== 056 +-- truncate_limit: 100 +-- Ensure we get a plan with a Limit 1 in both partial distinct and final +-- distinct +EXPLAIN (COSTS OFF) +SELECT DISTINCT four FROM tenk1 WHERE four = 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT four FROM tenk1 WHERE four = 10" +== 057 +-- truncate_limit: 100 +RESET max_parallel_workers_per_gather +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers_per_gather" +== 058 +-- truncate_limit: 100 +RESET min_parallel_table_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_table_scan_size" +== 059 +-- truncate_limit: 100 +RESET parallel_setup_cost +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_setup_cost" +== 060 +-- truncate_limit: 100 +|-- +-- Also, some tests of IS DISTINCT FROM, which doesn't quite deserve its +-- very own regression file. +|-- + +CREATE TEMP TABLE disttable (f1 integer) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE disttable (f1 int)" +== 061 +-- truncate_limit: 100 +INSERT INTO DISTTABLE VALUES(1) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO disttable VALUES (1)" +== 062 +-- truncate_limit: 100 +INSERT INTO DISTTABLE VALUES(2) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO disttable VALUES (2)" +== 063 +-- truncate_limit: 100 +INSERT INTO DISTTABLE VALUES(3) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO disttable VALUES (3)" +== 064 +-- truncate_limit: 100 +INSERT INTO DISTTABLE VALUES(NULL) +-- +TABLE: name="disttable" schema="" table="disttable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO disttable VALUES (NULL)" +== 065 +-- truncate_limit: 100 +-- basic cases +SELECT f1, f1 IS DISTINCT FROM 2 as "not 2" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1 IS DISTINCT FROM 2 AS \"not 2\" FROM disttable" +== 066 +-- truncate_limit: 100 +SELECT f1, f1 IS DISTINCT FROM NULL as "not null" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1 IS DISTINCT FROM NULL AS \"not null\" FROM disttable" +== 067 +-- truncate_limit: 100 +SELECT f1, f1 IS DISTINCT FROM f1 as "false" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1 IS DISTINCT FROM f1 AS \"false\" FROM disttable" +== 068 +-- truncate_limit: 100 +SELECT f1, f1 IS DISTINCT FROM f1+1 as "not null" FROM disttable +-- +TABLE: name="disttable" schema="" table="disttable" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1, f1 IS DISTINCT FROM (f1 + 1) AS \"not null\" FROM disttable" +== 069 +-- truncate_limit: 100 +-- check that optimizer constant-folds it properly +SELECT 1 IS DISTINCT FROM 2 as "yes" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 IS DISTINCT FROM 2 AS yes" +== 070 +-- truncate_limit: 100 +SELECT 2 IS DISTINCT FROM 2 as "no" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 IS DISTINCT FROM 2 AS no" +== 071 +-- truncate_limit: 100 +SELECT 2 IS DISTINCT FROM null as "yes" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 IS DISTINCT FROM NULL AS yes" +== 072 +-- truncate_limit: 100 +SELECT null IS DISTINCT FROM null as "no" +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL IS DISTINCT FROM NULL AS no" +== 073 +-- truncate_limit: 100 +-- negated form +SELECT 1 IS NOT DISTINCT FROM 2 as "no" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 IS NOT DISTINCT FROM 2 AS no" +== 074 +-- truncate_limit: 100 +SELECT 2 IS NOT DISTINCT FROM 2 as "yes" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 IS NOT DISTINCT FROM 2 AS yes" +== 075 +-- truncate_limit: 100 +SELECT 2 IS NOT DISTINCT FROM null as "no" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 IS NOT DISTINCT FROM NULL AS no" +== 076 +-- truncate_limit: 100 +SELECT null IS NOT DISTINCT FROM null as "yes" +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL IS NOT DISTINCT FROM NULL AS yes" diff --git a/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json new file mode 100644 index 0000000..5e6664a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json @@ -0,0 +1,12 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.test b/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.test new file mode 100644 index 0000000..2de8bee --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.test @@ -0,0 +1,94 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SELECT_DISTINCT_ON +|-- + +SELECT DISTINCT ON (string4) string4, two, ten + FROM onek + ORDER BY string4 using <, two using >, ten using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (string4) ... AS ... FROM onek ORDER BY string4 USING <, two USING >, ten USING <" +== 002 +-- truncate_limit: 100 +-- this will fail due to conflict of ordering requirements +SELECT DISTINCT ON (string4, ten) string4, two, ten + FROM onek + ORDER BY string4 using <, two using <, ten using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (string4, ten) ... AS ... FROM onek ORDER BY string4 USING <, two USING <, ten..." +== 003 +-- truncate_limit: 100 +SELECT DISTINCT ON (string4, ten) string4, ten, two + FROM onek + ORDER BY string4 using <, ten using >, two using < +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (string4, ten) ... AS ... FROM onek ORDER BY string4 USING <, ten USING >, two..." +== 004 +-- truncate_limit: 100 +-- bug #5049: early 8.4.x chokes on volatile DISTINCT ON clauses +select distinct on (1) floor(random()) as r, f1 from int4_tbl order by 1,2 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="floor" function="floor" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (1) floor(random()) AS r, f1 FROM int4_tbl ORDER BY 1, 2" +== 005 +-- truncate_limit: 100 +|-- +-- Test the planner's ability to use a LIMIT 1 instead of a Unique node when +-- all of the distinct_pathkeys have been marked as redundant +|-- + +-- Ensure we also get a LIMIT plan with DISTINCT ON +EXPLAIN (COSTS OFF) +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT ON (four) four, two FROM tenk1 WHERE four = 0 ORDER BY 1" +== 006 +-- truncate_limit: 100 +-- and check the result of the above query is correct +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (four) four, two FROM tenk1 WHERE four = 0 ORDER BY 1" +== 007 +-- truncate_limit: 100 +-- Ensure a Sort -> Limit is used when the ORDER BY contains additional cols +EXPLAIN (COSTS OFF) +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1,2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT ON (four) four, two FROM tenk1 WHERE four = 0 ORDER BY 1, 2" +== 008 +-- truncate_limit: 100 +-- Same again but use a column that is indexed so that we get an index scan +-- then a limit +EXPLAIN (COSTS OFF) +SELECT DISTINCT ON (four) four,hundred + FROM tenk1 WHERE four = 0 ORDER BY 1,2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT ON (four) four, hundred FROM tenk1 WHERE four = 0 ORDER BY 1, 2" diff --git a/parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json new file mode 100644 index 0000000..880b1d2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json @@ -0,0 +1,27 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select_having.test b/parser/testdata/summary_truncate/postgres_regress/select_having.test new file mode 100644 index 0000000..336b52b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_having.test @@ -0,0 +1,212 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SELECT_HAVING +|-- + +-- load test data +CREATE TABLE test_having (a int, b int, c char(8), d char) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_having (a int, b int, c char(8), d char(1))" +== 002 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (0, 1, 'XXXX', 'A') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (0, 1, 'XXXX', 'A')" +== 003 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (1, 2, 'AAAA', 'b') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (1, 2, 'AAAA', 'b')" +== 004 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (2, 2, 'AAAA', 'c') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (2, 2, 'AAAA', 'c')" +== 005 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (3, 3, 'BBBB', 'D') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (3, 3, 'BBBB', 'D')" +== 006 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (4, 3, 'BBBB', 'e') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (4, 3, 'BBBB', 'e')" +== 007 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (5, 3, 'bbbb', 'F') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (5, 3, 'bbbb', 'F')" +== 008 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (6, 4, 'cccc', 'g') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (6, 4, 'cccc', 'g')" +== 009 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (7, 4, 'cccc', 'h') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (7, 4, 'cccc', 'h')" +== 010 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (8, 4, 'CCCC', 'I') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (8, 4, 'CCCC', 'I')" +== 011 +-- truncate_limit: 100 +INSERT INTO test_having VALUES (9, 4, 'CCCC', 'j') +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_having VALUES (9, 4, 'CCCC', 'j')" +== 012 +-- truncate_limit: 100 +SELECT b, c FROM test_having + GROUP BY b, c HAVING count(*) = 1 ORDER BY b, c +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT b, c FROM test_having GROUP BY b, c HAVING count(*) = 1 ORDER BY b, c" +== 013 +-- truncate_limit: 100 +-- HAVING is effectively equivalent to WHERE in this case +SELECT b, c FROM test_having + GROUP BY b, c HAVING b = 3 ORDER BY b, c +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT b, c FROM test_having GROUP BY b, c HAVING b = 3 ORDER BY b, c" +== 014 +-- truncate_limit: 100 +SELECT lower(c), count(c) FROM test_having + GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a) + ORDER BY lower(c) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_having GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a) ORDER BY low..." +== 015 +-- truncate_limit: 100 +SELECT c, max(a) FROM test_having + GROUP BY c HAVING count(*) > 2 OR min(a) = max(a) + ORDER BY c +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c, max(a) FROM test_having GROUP BY c HAVING count(*) > 2 OR min(a) = max(a) ORDER BY c" +== 016 +-- truncate_limit: 100 +-- test degenerate cases involving HAVING without GROUP BY +-- Per SQL spec, these should generate 0 or 1 row, even without aggregates + +SELECT min(a), max(a) FROM test_having HAVING min(a) = max(a) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(a), max(a) FROM test_having HAVING min(a) = max(a)" +== 017 +-- truncate_limit: 100 +SELECT min(a), max(a) FROM test_having HAVING min(a) < max(a) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(a), max(a) FROM test_having HAVING min(a) < max(a)" +== 018 +-- truncate_limit: 100 +-- errors: ungrouped column references +SELECT a FROM test_having HAVING min(a) < max(a) +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a FROM test_having HAVING min(a) < max(a)" +== 019 +-- truncate_limit: 100 +SELECT 1 AS one FROM test_having HAVING a > 1 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one FROM test_having HAVING a > 1" +== 020 +-- truncate_limit: 100 +-- the really degenerate case: need not scan table at all +SELECT 1 AS one FROM test_having HAVING 1 > 2 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one FROM test_having HAVING 1 > 2" +== 021 +-- truncate_limit: 100 +SELECT 1 AS one FROM test_having HAVING 1 < 2 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one FROM test_having HAVING 1 < 2" +== 022 +-- truncate_limit: 100 +-- and just to prove that we aren't scanning the table: +SELECT 1 AS one FROM test_having WHERE 1/a = 1 HAVING 1 < 2 +-- +TABLE: name="test_having" schema="" table="test_having" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one FROM test_having WHERE (1 / a) = 1 HAVING 1 < 2" +== 023 +-- truncate_limit: 100 +DROP TABLE test_having +-- +TABLE: name="test_having" schema="" table="test_having" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_having" diff --git a/parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select_implicit.test b/parser/testdata/summary_truncate/postgres_regress/select_implicit.test new file mode 100644 index 0000000..8d0f38d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_implicit.test @@ -0,0 +1,472 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SELECT_IMPLICIT +-- Test cases for queries with ordering terms missing from the target list. +-- This used to be called "junkfilter.sql". +-- The parser uses the term "resjunk" to handle these cases. +-- - thomas 1998-07-09 +|-- + +-- load test data +CREATE TABLE test_missing_target (a int, b int, c char(8), d char) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_missing_target (a int, b int, c char(8), d char(1))" +== 002 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (0, 1, 'XXXX', 'A') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (0, 1, 'XXXX', 'A')" +== 003 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (1, 2, 'ABAB', 'b') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (1, 2, 'ABAB', 'b')" +== 004 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (2, 2, 'ABAB', 'c') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (2, 2, 'ABAB', 'c')" +== 005 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (3, 3, 'BBBB', 'D') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (3, 3, 'BBBB', 'D')" +== 006 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (4, 3, 'BBBB', 'e') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (4, 3, 'BBBB', 'e')" +== 007 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (5, 3, 'bbbb', 'F') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (5, 3, 'bbbb', 'F')" +== 008 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (6, 4, 'cccc', 'g') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (6, 4, 'cccc', 'g')" +== 009 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (7, 4, 'cccc', 'h') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (7, 4, 'cccc', 'h')" +== 010 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (8, 4, 'CCCC', 'I') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (8, 4, 'CCCC', 'I')" +== 011 +-- truncate_limit: 100 +INSERT INTO test_missing_target VALUES (9, 4, 'CCCC', 'j') +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_missing_target VALUES (9, 4, 'CCCC', 'j')" +== 012 +-- truncate_limit: 100 +-- w/ existing GROUP BY target +SELECT c, count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c, count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c" +== 013 +-- truncate_limit: 100 +-- w/o existing GROUP BY target using a relation name in GROUP BY clause +SELECT count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c" +== 014 +-- truncate_limit: 100 +-- w/o existing GROUP BY target and w/o existing a different ORDER BY target +-- failure expected +SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b" +== 015 +-- truncate_limit: 100 +-- w/o existing GROUP BY target and w/o existing same ORDER BY target +SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b" +== 016 +-- truncate_limit: 100 +-- w/ existing GROUP BY target using a relation name in target +SELECT test_missing_target.b, count(*) + FROM test_missing_target GROUP BY b ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT test_missing_target.b, count(*) FROM test_missing_target GROUP BY b ORDER BY b" +== 017 +-- truncate_limit: 100 +-- w/o existing GROUP BY target +SELECT c FROM test_missing_target ORDER BY a +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT c FROM test_missing_target ORDER BY a" +== 018 +-- truncate_limit: 100 +-- w/o existing ORDER BY target +SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b desc +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b DESC" +== 019 +-- truncate_limit: 100 +-- group using reference number +SELECT count(*) FROM test_missing_target ORDER BY 1 desc +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_missing_target ORDER BY 1 DESC" +== 020 +-- truncate_limit: 100 +-- order using reference number +SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1" +== 021 +-- truncate_limit: 100 +-- group using reference number out of range +-- failure expected +SELECT c, count(*) FROM test_missing_target GROUP BY 3 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT c, count(*) FROM test_missing_target GROUP BY 3" +== 022 +-- truncate_limit: 100 +-- group w/o existing GROUP BY and ORDER BY target under ambiguous condition +-- failure expected +SELECT count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY b ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_missing_target x, test_missing_target y WHERE ... GROUP BY b ORDER BY b" +== 023 +-- truncate_limit: 100 +-- order w/ target under ambiguous condition +-- failure NOT expected +SELECT a, a FROM test_missing_target + ORDER BY a +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, a FROM test_missing_target ORDER BY a" +== 024 +-- truncate_limit: 100 +-- order expression w/ target under ambiguous condition +-- failure NOT expected +SELECT a/2, a/2 FROM test_missing_target + ORDER BY a/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a / 2, a / 2 FROM test_missing_target ORDER BY a / 2" +== 025 +-- truncate_limit: 100 +-- group expression w/ target under ambiguous condition +-- failure NOT expected +SELECT a/2, a/2 FROM test_missing_target + GROUP BY a/2 ORDER BY a/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a / 2, a / 2 FROM test_missing_target GROUP BY a / 2 ORDER BY a / 2" +== 026 +-- truncate_limit: 100 +-- group w/ existing GROUP BY target under ambiguous condition +SELECT x.b, count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_missing_target x, test_missing_target y WHERE ... GROUP BY x.b ORDER BY x.b" +== 027 +-- truncate_limit: 100 +-- group w/o existing GROUP BY target under ambiguous condition +SELECT count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_missing_target x, test_missing_target y WHERE ... GROUP BY x.b ORDER BY x.b" +== 028 +-- truncate_limit: 100 +-- group w/o existing GROUP BY target under ambiguous condition +-- into a table +CREATE TABLE test_missing_target2 AS +SELECT count(*) +FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b +-- +TABLE: name="test_missing_target2" schema="" table="test_missing_target2" ctx=DDL +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_missing_target2 AS SELECT count(*) FROM test_missing_target x, test_missing_tar..." +== 029 +-- truncate_limit: 100 +SELECT * FROM test_missing_target2 +-- +TABLE: name="test_missing_target2" schema="" table="test_missing_target2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_missing_target2" +== 030 +-- truncate_limit: 100 +-- Functions and expressions + +-- w/ existing GROUP BY target +SELECT a%2, count(b) FROM test_missing_target +GROUP BY test_missing_target.a%2 +ORDER BY test_missing_target.a%2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_missing_target GROUP BY test_missing_target.a % 2 ORDER BY test_missing_targ..." +== 031 +-- truncate_limit: 100 +-- w/o existing GROUP BY target using a relation name in GROUP BY clause +SELECT count(c) FROM test_missing_target +GROUP BY lower(test_missing_target.c) +ORDER BY lower(test_missing_target.c) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_missing_target GROUP BY lower(test_missing_target.c) ORDER BY lower(test_mis..." +== 032 +-- truncate_limit: 100 +-- w/o existing GROUP BY target and w/o existing a different ORDER BY target +-- failure expected +SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b" +== 033 +-- truncate_limit: 100 +-- w/o existing GROUP BY target and w/o existing same ORDER BY target +SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(b) FROM test_missing_target GROUP BY b / 2 ORDER BY b / 2" +== 034 +-- truncate_limit: 100 +-- w/ existing GROUP BY target using a relation name in target +SELECT lower(test_missing_target.c), count(c) + FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c)" +== 035 +-- truncate_limit: 100 +-- w/o existing GROUP BY target +SELECT a FROM test_missing_target ORDER BY upper(d) +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a FROM test_missing_target ORDER BY upper(d)" +== 036 +-- truncate_limit: 100 +-- w/o existing ORDER BY target +SELECT count(b) FROM test_missing_target + GROUP BY (b + 1) / 2 ORDER BY (b + 1) / 2 desc +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(b) FROM test_missing_target GROUP BY (b + 1) / 2 ORDER BY (b + 1) / 2 DESC" +== 037 +-- truncate_limit: 100 +-- group w/o existing GROUP BY and ORDER BY target under ambiguous condition +-- failure expected +SELECT count(x.a) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY b/2 ORDER BY b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_missing_target x, test_missing_target y WHERE ... GROUP BY b / 2 ORDER BY b / 2" +== 038 +-- truncate_limit: 100 +-- group w/ existing GROUP BY target under ambiguous condition +SELECT x.b/2, count(x.b) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 ORDER BY x.b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_missing_target x, test_missing_target y WHERE ... GROUP BY x.b / 2 ORDER BY ..." +== 039 +-- truncate_limit: 100 +-- group w/o existing GROUP BY target under ambiguous condition +-- failure expected due to ambiguous b in count(b) +SELECT count(b) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(b) FROM test_missing_target x, test_missing_target y WHERE x.a = y.a GROUP BY x.b / 2" +== 040 +-- truncate_limit: 100 +-- group w/o existing GROUP BY target under ambiguous condition +-- into a table +CREATE TABLE test_missing_target3 AS +SELECT count(x.b) +FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 ORDER BY x.b/2 +-- +TABLE: name="test_missing_target3" schema="" table="test_missing_target3" ctx=DDL +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=Select +ALIAS: "x"="test_missing_target" +ALIAS: "y"="test_missing_target" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="x" column="a" +FILTER: schema="" table="y" column="a" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_missing_target3 AS SELECT count(x.b) FROM test_missing_target x, test_missing_t..." +== 041 +-- truncate_limit: 100 +SELECT * FROM test_missing_target3 +-- +TABLE: name="test_missing_target3" schema="" table="test_missing_target3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM test_missing_target3" +== 042 +-- truncate_limit: 100 +-- Cleanup +DROP TABLE test_missing_target +-- +TABLE: name="test_missing_target" schema="" table="test_missing_target" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_missing_target" +== 043 +-- truncate_limit: 100 +DROP TABLE test_missing_target2 +-- +TABLE: name="test_missing_target2" schema="" table="test_missing_target2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_missing_target2" +== 044 +-- truncate_limit: 100 +DROP TABLE test_missing_target3 +-- +TABLE: name="test_missing_target3" schema="" table="test_missing_target3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_missing_target3" diff --git a/parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json new file mode 100644 index 0000000..0a7b0c8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json @@ -0,0 +1,71 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select_into.test b/parser/testdata/summary_truncate/postgres_regress/select_into.test new file mode 100644 index 0000000..dce605d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_into.test @@ -0,0 +1,583 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SELECT_INTO +|-- + +SELECT * + INTO TABLE sitmp1 + FROM onek + WHERE onek.unique1 < 2 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +FILTER: schema="" table="onek" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT * INTO sitmp1 FROM onek WHERE onek.unique1 < 2" +== 002 +-- truncate_limit: 100 +DROP TABLE sitmp1 +-- +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sitmp1" +== 003 +-- truncate_limit: 100 +SELECT * + INTO TABLE sitmp1 + FROM onek2 + WHERE onek2.unique1 < 2 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=Select +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +FILTER: schema="" table="onek2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT * INTO sitmp1 FROM onek2 WHERE onek2.unique1 < 2" +== 004 +-- truncate_limit: 100 +DROP TABLE sitmp1 +-- +TABLE: name="sitmp1" schema="" table="sitmp1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sitmp1" +== 005 +-- truncate_limit: 100 +|-- +-- SELECT INTO and INSERT permission, if owner is not allowed to insert. +|-- +CREATE SCHEMA selinto_schema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA selinto_schema" +== 006 +-- truncate_limit: 100 +CREATE USER regress_selinto_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_selinto_user" +== 007 +-- truncate_limit: 100 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + REVOKE INSERT ON TABLES FROM regress_selinto_user +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user REVOKE insert ON TABLES FROM regress_selin..." +== 008 +-- truncate_limit: 100 +GRANT ALL ON SCHEMA selinto_schema TO public +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON SCHEMA selinto_schema TO public" +== 009 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_selinto_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_selinto_user" +== 010 +-- truncate_limit: 100 +-- WITH DATA, passes. +CREATE TABLE selinto_schema.tbl_withdata1 (a) + AS SELECT generate_series(1,3) WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata1" schema="selinto_schema" table="tbl_withdata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE selinto_schema.tbl_withdata1(a) AS SELECT generate_series(1, 3)" +== 011 +-- truncate_limit: 100 +INSERT INTO selinto_schema.tbl_withdata1 VALUES (4) +-- +TABLE: name="selinto_schema.tbl_withdata1" schema="selinto_schema" table="tbl_withdata1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO selinto_schema.tbl_withdata1 VALUES (4)" +== 012 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_withdata2 (a) AS + SELECT generate_series(1,3) WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata2" schema="selinto_schema" table="tbl_withdata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE selinto_schema.tbl_withdata2(a..." +== 013 +-- truncate_limit: 100 +-- WITH NO DATA, passes. +CREATE TABLE selinto_schema.tbl_nodata1 (a) AS + SELECT generate_series(1,3) WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata1" schema="selinto_schema" table="tbl_nodata1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE selinto_schema.tbl_nodata1(a) AS SELECT generate_series(1, 3) WITH NO DATA" +== 014 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_nodata2 (a) AS + SELECT generate_series(1,3) WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata2" schema="selinto_schema" table="tbl_nodata2" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE selinto_schema.tbl_nodata2(a) ..." +== 015 +-- truncate_limit: 100 +-- EXECUTE and WITH DATA, passes. +PREPARE data_sel AS SELECT generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE data_sel AS SELECT generate_series(1, 3)" +== 016 +-- truncate_limit: 100 +CREATE TABLE selinto_schema.tbl_withdata3 (a) AS + EXECUTE data_sel WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata3" schema="selinto_schema" table="tbl_withdata3" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TABLE selinto_schema.tbl_withdata3(a) AS EXECUTE data_sel" +== 017 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_withdata4 (a) AS + EXECUTE data_sel WITH DATA +-- +TABLE: name="selinto_schema.tbl_withdata4" schema="selinto_schema" table="tbl_withdata4" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE selinto_schema.tbl_withdata4(a..." +== 018 +-- truncate_limit: 100 +-- EXECUTE and WITH NO DATA, passes. +CREATE TABLE selinto_schema.tbl_nodata3 (a) AS + EXECUTE data_sel WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata3" schema="selinto_schema" table="tbl_nodata3" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TABLE selinto_schema.tbl_nodata3(a) AS EXECUTE data_sel WITH NO DATA" +== 019 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_nodata4 (a) AS + EXECUTE data_sel WITH NO DATA +-- +TABLE: name="selinto_schema.tbl_nodata4" schema="selinto_schema" table="tbl_nodata4" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE selinto_schema.tbl_nodata4(a) ..." +== 020 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 021 +-- truncate_limit: 100 +ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + GRANT INSERT ON TABLES TO regress_selinto_user +-- +STMT: AlterDefaultPrivilegesStmt +TRUNCATED: "ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user GRANT insert ON TABLES TO regress_selinto_..." +== 022 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_selinto_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_selinto_user" +== 023 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 024 +-- truncate_limit: 100 +DEALLOCATE data_sel +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE data_sel" +== 025 +-- truncate_limit: 100 +DROP SCHEMA selinto_schema CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA selinto_schema CASCADE" +== 026 +-- truncate_limit: 100 +DROP USER regress_selinto_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_selinto_user" +== 027 +-- truncate_limit: 100 +-- Tests for WITH NO DATA and column name consistency +CREATE TABLE ctas_base (i int, j int) +-- +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ctas_base (i int, j int)" +== 028 +-- truncate_limit: 100 +INSERT INTO ctas_base VALUES (1, 2) +-- +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ctas_base VALUES (1, 2)" +== 029 +-- truncate_limit: 100 +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_nodata(ii, jj, kk) AS SELECT i, j FROM ctas_base" +== 030 +-- truncate_limit: 100 +-- Error +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base WITH NO DATA +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_nodata(ii, jj, kk) AS SELECT i, j FROM ctas_base WITH NO DATA" +== 031 +-- truncate_limit: 100 +-- Error +CREATE TABLE ctas_nodata (ii, jj) AS SELECT i, j FROM ctas_base +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_nodata(ii, jj) AS SELECT i, j FROM ctas_base" +== 032 +-- truncate_limit: 100 +-- OK +CREATE TABLE ctas_nodata_2 (ii, jj) AS SELECT i, j FROM ctas_base WITH NO DATA +-- +TABLE: name="ctas_nodata_2" schema="" table="ctas_nodata_2" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_nodata_2(ii, jj) AS SELECT i, j FROM ctas_base WITH NO DATA" +== 033 +-- truncate_limit: 100 +-- OK +CREATE TABLE ctas_nodata_3 (ii) AS SELECT i, j FROM ctas_base +-- +TABLE: name="ctas_nodata_3" schema="" table="ctas_nodata_3" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_nodata_3(ii) AS SELECT i, j FROM ctas_base" +== 034 +-- truncate_limit: 100 +-- OK +CREATE TABLE ctas_nodata_4 (ii) AS SELECT i, j FROM ctas_base WITH NO DATA +-- +TABLE: name="ctas_nodata_4" schema="" table="ctas_nodata_4" ctx=DDL +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_nodata_4(ii) AS SELECT i, j FROM ctas_base WITH NO DATA" +== 035 +-- truncate_limit: 100 +-- OK +SELECT * FROM ctas_nodata +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ctas_nodata" +== 036 +-- truncate_limit: 100 +SELECT * FROM ctas_nodata_2 +-- +TABLE: name="ctas_nodata_2" schema="" table="ctas_nodata_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ctas_nodata_2" +== 037 +-- truncate_limit: 100 +SELECT * FROM ctas_nodata_3 +-- +TABLE: name="ctas_nodata_3" schema="" table="ctas_nodata_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ctas_nodata_3" +== 038 +-- truncate_limit: 100 +SELECT * FROM ctas_nodata_4 +-- +TABLE: name="ctas_nodata_4" schema="" table="ctas_nodata_4" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ctas_nodata_4" +== 039 +-- truncate_limit: 100 +DROP TABLE ctas_base +-- +TABLE: name="ctas_base" schema="" table="ctas_base" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ctas_base" +== 040 +-- truncate_limit: 100 +DROP TABLE ctas_nodata +-- +TABLE: name="ctas_nodata" schema="" table="ctas_nodata" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ctas_nodata" +== 041 +-- truncate_limit: 100 +DROP TABLE ctas_nodata_2 +-- +TABLE: name="ctas_nodata_2" schema="" table="ctas_nodata_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ctas_nodata_2" +== 042 +-- truncate_limit: 100 +DROP TABLE ctas_nodata_3 +-- +TABLE: name="ctas_nodata_3" schema="" table="ctas_nodata_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ctas_nodata_3" +== 043 +-- truncate_limit: 100 +DROP TABLE ctas_nodata_4 +-- +TABLE: name="ctas_nodata_4" schema="" table="ctas_nodata_4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ctas_nodata_4" +== 044 +-- truncate_limit: 100 +|-- +-- CREATE TABLE AS/SELECT INTO as last command in a SQL function +-- have been known to cause problems +|-- +CREATE FUNCTION make_table() RETURNS VOID +AS $$ + CREATE TABLE created_table AS SELECT * FROM int8_tbl; +$$ LANGUAGE SQL +-- +FUNCTION: name="make_table" function="make_table" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION make_table() RETURNS void AS $$\n CREATE TABLE created_table AS SELECT * FROM int..." +== 045 +-- truncate_limit: 100 +SELECT make_table() +-- +FUNCTION: name="make_table" function="make_table" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_table()" +== 046 +-- truncate_limit: 100 +SELECT * FROM created_table +-- +TABLE: name="created_table" schema="" table="created_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM created_table" +== 047 +-- truncate_limit: 100 +-- Try EXPLAIN ANALYZE SELECT INTO and EXPLAIN ANALYZE CREATE TABLE AS +-- WITH NO DATA, but hide the outputs since they won't be stable. +DO $$ +BEGIN + EXECUTE 'EXPLAIN ANALYZE SELECT * INTO TABLE easi FROM int8_tbl'; + EXECUTE 'EXPLAIN ANALYZE CREATE TABLE easi2 AS SELECT * FROM int8_tbl WITH NO DATA'; +END$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n\tEXECUTE 'EXPLAIN ANALYZE SELECT * INTO TABLE easi FROM int8_tbl';\n\tEXECUTE 'EXPLAIN ..." +== 048 +-- truncate_limit: 100 +DROP TABLE created_table +-- +TABLE: name="created_table" schema="" table="created_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE created_table" +== 049 +-- truncate_limit: 100 +DROP TABLE easi, easi2 +-- +TABLE: name="easi" schema="" table="easi" ctx=DDL +TABLE: name="easi2" schema="" table="easi2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE easi, easi2" +== 050 +-- truncate_limit: 100 +|-- +-- Disallowed uses of SELECT ... INTO. All should fail +|-- +DECLARE foo CURSOR FOR SELECT 1 INTO int4_tbl +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo CURSOR FOR SELECT 1 INTO int4_tbl" +== 051 +-- truncate_limit: 100 +COPY (SELECT 1 INTO frak UNION SELECT 2) TO 'blob' +-- +TABLE: name="frak" schema="" table="frak" ctx=DDL +STMT: CopyStmt +TRUNCATED: "COPY (SELECT 1 INTO frak UNION SELECT 2) TO 'blob'" +== 052 +-- truncate_limit: 100 +SELECT * FROM (SELECT 1 INTO f) bar +-- +TABLE: name="f" schema="" table="f" ctx=DDL +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 1 INTO f) bar" +== 053 +-- truncate_limit: 100 +CREATE VIEW foo AS SELECT 1 INTO int4_tbl +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW foo AS SELECT 1 INTO int4_tbl" +== 054 +-- truncate_limit: 100 +INSERT INTO int4_tbl SELECT 1 INTO f +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +TABLE: name="f" schema="" table="f" ctx=DDL +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl SELECT 1 INTO f" +== 055 +-- truncate_limit: 100 +-- Test CREATE TABLE AS ... IF NOT EXISTS +CREATE TABLE ctas_ine_tbl AS SELECT 1 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_ine_tbl AS SELECT 1" +== 056 +-- truncate_limit: 100 +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0" +== 057 +-- truncate_limit: 100 +-- error +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0" +== 058 +-- truncate_limit: 100 +-- ok +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA" +== 059 +-- truncate_limit: 100 +-- error +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA" +== 060 +-- truncate_limit: 100 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0" +== 061 +-- truncate_limit: 100 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS ..." +== 062 +-- truncate_limit: 100 +-- ok +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 ..." +== 063 +-- truncate_limit: 100 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS ..." +== 064 +-- truncate_limit: 100 +-- ok +PREPARE ctas_ine_query AS SELECT 1 / 0 +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ctas_ine_query AS SELECT 1 / 0" +== 065 +-- truncate_limit: 100 +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE ctas_ine_tbl AS EXECUTE ctas_ine_query +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE ctas_ine_tbl AS EXECUTE ctas_i..." +== 066 +-- truncate_limit: 100 +-- error +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS EXECUTE ctas_ine_query +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS ..." +== 067 +-- truncate_limit: 100 +-- ok +DROP TABLE ctas_ine_tbl +-- +TABLE: name="ctas_ine_tbl" schema="" table="ctas_ine_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ctas_ine_tbl" diff --git a/parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json new file mode 100644 index 0000000..60ff1c2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json @@ -0,0 +1,239 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select_parallel.test b/parser/testdata/summary_truncate/postgres_regress/select_parallel.test new file mode 100644 index 0000000..4ac0caa --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_parallel.test @@ -0,0 +1,2010 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PARALLEL +|-- + +create function sp_parallel_restricted(int) returns int as + $$begin return $1; end$$ language plpgsql parallel restricted +-- +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sp_parallel_restricted(int) RETURNS int AS $$begin return $1; end$$ LANGUAGE plpg..." +== 002 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 003 +-- truncate_limit: 100 +-- encourage use of parallel plans +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 004 +-- truncate_limit: 100 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 005 +-- truncate_limit: 100 +set min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 006 +-- truncate_limit: 100 +set max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 4" +== 007 +-- truncate_limit: 100 +-- Parallel Append with partial-subplans +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT round(avg(aa)), sum(aa) FROM a_star" +== 008 +-- truncate_limit: 100 +select round(avg(aa)), sum(aa) from a_star a1 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a1"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(avg(aa)), sum(aa) FROM a_star a1" +== 009 +-- truncate_limit: 100 +-- Parallel Append with both partial and non-partial subplans +alter table c_star set (parallel_workers = 0) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c_star SET (parallel_workers=0)" +== 010 +-- truncate_limit: 100 +alter table d_star set (parallel_workers = 0) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE d_star SET (parallel_workers=0)" +== 011 +-- truncate_limit: 100 +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT round(avg(aa)), sum(aa) FROM a_star" +== 012 +-- truncate_limit: 100 +select round(avg(aa)), sum(aa) from a_star a2 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a2"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(avg(aa)), sum(aa) FROM a_star a2" +== 013 +-- truncate_limit: 100 +-- Parallel Append with only non-partial subplans +alter table a_star set (parallel_workers = 0) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE a_star SET (parallel_workers=0)" +== 014 +-- truncate_limit: 100 +alter table b_star set (parallel_workers = 0) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE b_star SET (parallel_workers=0)" +== 015 +-- truncate_limit: 100 +alter table e_star set (parallel_workers = 0) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE e_star SET (parallel_workers=0)" +== 016 +-- truncate_limit: 100 +alter table f_star set (parallel_workers = 0) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE f_star SET (parallel_workers=0)" +== 017 +-- truncate_limit: 100 +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT round(avg(aa)), sum(aa) FROM a_star" +== 018 +-- truncate_limit: 100 +select round(avg(aa)), sum(aa) from a_star a3 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a3"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(avg(aa)), sum(aa) FROM a_star a3" +== 019 +-- truncate_limit: 100 +-- Disable Parallel Append +alter table a_star reset (parallel_workers) +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE a_star RESET (parallel_workers)" +== 020 +-- truncate_limit: 100 +alter table b_star reset (parallel_workers) +-- +TABLE: name="b_star" schema="" table="b_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE b_star RESET (parallel_workers)" +== 021 +-- truncate_limit: 100 +alter table c_star reset (parallel_workers) +-- +TABLE: name="c_star" schema="" table="c_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE c_star RESET (parallel_workers)" +== 022 +-- truncate_limit: 100 +alter table d_star reset (parallel_workers) +-- +TABLE: name="d_star" schema="" table="d_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE d_star RESET (parallel_workers)" +== 023 +-- truncate_limit: 100 +alter table e_star reset (parallel_workers) +-- +TABLE: name="e_star" schema="" table="e_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE e_star RESET (parallel_workers)" +== 024 +-- truncate_limit: 100 +alter table f_star reset (parallel_workers) +-- +TABLE: name="f_star" schema="" table="f_star" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE f_star RESET (parallel_workers)" +== 025 +-- truncate_limit: 100 +set enable_parallel_append to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_parallel_append TO OFF" +== 026 +-- truncate_limit: 100 +explain (costs off) + select round(avg(aa)), sum(aa) from a_star +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT round(avg(aa)), sum(aa) FROM a_star" +== 027 +-- truncate_limit: 100 +select round(avg(aa)), sum(aa) from a_star a4 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=Select +ALIAS: "a4"="a_star" +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT round(avg(aa)), sum(aa) FROM a_star a4" +== 028 +-- truncate_limit: 100 +reset enable_parallel_append +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_parallel_append" +== 029 +-- truncate_limit: 100 +-- Parallel Append that runs serially +create function sp_test_func() returns setof text as +$$ select 'foo'::varchar union all select 'bar'::varchar $$ +language sql stable +-- +FUNCTION: name="sp_test_func" function="sp_test_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sp_test_func() RETURNS SETOF text AS $$ select 'foo'::varchar union all select 'b..." +== 030 +-- truncate_limit: 100 +select sp_test_func() order by 1 +-- +FUNCTION: name="sp_test_func" function="sp_test_func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sp_test_func() ORDER BY 1" +== 031 +-- truncate_limit: 100 +-- Parallel Append is not to be used when the subpath depends on the outer param +create table part_pa_test(a int, b int) partition by range(a) +-- +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_pa_test (a int, b int) PARTITION BY RANGE (a)" +== 032 +-- truncate_limit: 100 +create table part_pa_test_p1 partition of part_pa_test for values from (minvalue) to (0) +-- +TABLE: name="part_pa_test_p1" schema="" table="part_pa_test_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_pa_test_p1 PARTITION OF part_pa_test FOR VALUES FROM (minvalue) TO (0)" +== 033 +-- truncate_limit: 100 +create table part_pa_test_p2 partition of part_pa_test for values from (0) to (maxvalue) +-- +TABLE: name="part_pa_test_p2" schema="" table="part_pa_test_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_pa_test_p2 PARTITION OF part_pa_test FOR VALUES FROM (0) TO (maxvalue)" +== 034 +-- truncate_limit: 100 +explain (costs off) + select (select max((select pa1.b from part_pa_test pa1 where pa1.a = pa2.a))) + from part_pa_test pa2 +-- +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=Select +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=Select +ALIAS: "pa1"="part_pa_test" +ALIAS: "pa2"="part_pa_test" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="pa1" column="a" +FILTER: schema="" table="pa2" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT (SELECT max((SELECT pa1.b FROM part_pa_test pa1 WHERE pa1.a = pa2.a)))..." +== 035 +-- truncate_limit: 100 +drop table part_pa_test +-- +TABLE: name="part_pa_test" schema="" table="part_pa_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE part_pa_test" +== 036 +-- truncate_limit: 100 +-- test with leader participation disabled +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 037 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE stringu1 = 'GRAAAA'" +== 038 +-- truncate_limit: 100 +select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 WHERE stringu1 = 'GRAAAA'" +== 039 +-- truncate_limit: 100 +-- 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 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers TO 0" +== 040 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE stringu1 = 'GRAAAA'" +== 041 +-- truncate_limit: 100 +select count(*) from tenk1 where stringu1 = 'GRAAAA' +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 WHERE stringu1 = 'GRAAAA'" +== 042 +-- truncate_limit: 100 +reset max_parallel_workers +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers" +== 043 +-- truncate_limit: 100 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_leader_participation" +== 044 +-- truncate_limit: 100 +-- test that parallel_restricted function doesn't run in worker +alter table tenk1 set (parallel_workers = 4) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk1 SET (parallel_workers=4)" +== 045 +-- truncate_limit: 100 +explain (verbose, costs off) +select sp_parallel_restricted(unique1) from tenk1 + where stringu1 = 'GRAAAA' order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=Call +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT sp_parallel_restricted(unique1) FROM tenk1 WHERE stringu1 = '..." +== 046 +-- truncate_limit: 100 +-- test parallel plan when group by expression is in target list. +explain (costs off) + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT length(stringu1) FROM tenk1 GROUP BY length(stringu1)" +== 047 +-- truncate_limit: 100 +select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(stringu1) FROM tenk1 GROUP BY length(stringu1)" +== 048 +-- truncate_limit: 100 +explain (costs off) + select stringu1, count(*) from tenk1 group by stringu1 order by stringu1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT stringu1, count(*) FROM tenk1 GROUP BY stringu1 ORDER BY stringu1" +== 049 +-- truncate_limit: 100 +-- 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)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=Call +FUNCTION: name="sp_parallel_restricted" function="sp_parallel_restricted" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(sp_parallel_restricted(unique1)) FROM tenk1 GROUP BY sp_parallel_r..." +== 050 +-- truncate_limit: 100 +-- test prepared statement +prepare tenk1_count(integer) As select count((unique1)) from tenk1 where hundred > $1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE tenk1_count(int) AS SELECT count(unique1) FROM tenk1 WHERE hundred > $1" +== 051 +-- truncate_limit: 100 +explain (costs off) execute tenk1_count(1) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE tenk1_count(1)" +== 052 +-- truncate_limit: 100 +execute tenk1_count(1) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE tenk1_count(1)" +== 053 +-- truncate_limit: 100 +deallocate tenk1_count +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE tenk1_count" +== 054 +-- truncate_limit: 100 +-- test parallel plans for queries containing un-correlated subplans. +alter table tenk2 set (parallel_workers = 0) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 SET (parallel_workers=0)" +== 055 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 where (two, four) not in + (select hundred, thousand from tenk2 where thousand > 100) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="two" +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE NOT (two, four) IN (SELECT hundred, thousand..." +== 056 +-- truncate_limit: 100 +select count(*) from tenk1 where (two, four) not in + (select hundred, thousand from tenk2 where thousand > 100) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="two" +FILTER: schema="" table="" column="four" +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 WHERE NOT (two, four) IN (SELECT ... FROM tenk2 WHERE thousand > 100)" +== 057 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE NOT (unique1 + random())::int IN (SELECT ten FROM t..." +== 058 +-- truncate_limit: 100 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 RESET (parallel_workers)" +== 059 +-- truncate_limit: 100 +-- test parallel plan for a query containing initplan. +set enable_indexscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 060 +-- truncate_limit: 100 +set enable_indexonlyscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO OFF" +== 061 +-- truncate_limit: 100 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 062 +-- truncate_limit: 100 +alter table tenk2 set (parallel_workers = 2) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 SET (parallel_workers=2)" +== 063 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 + where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE tenk1.unique1 = (SELECT max(tenk2.unique1) F..." +== 064 +-- truncate_limit: 100 +select count(*) from tenk1 + where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 WHERE tenk1.unique1 = (SELECT max(tenk2.unique1) FROM tenk2)" +== 065 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 066 +-- truncate_limit: 100 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexonlyscan" +== 067 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 068 +-- truncate_limit: 100 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 RESET (parallel_workers)" +== 069 +-- truncate_limit: 100 +-- test parallel index scans. +set enable_seqscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 070 +-- truncate_limit: 100 +set enable_bitmapscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 071 +-- truncate_limit: 100 +set random_page_cost = 2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET random_page_cost TO 2" +== 072 +-- truncate_limit: 100 +explain (costs off) + select count((unique1)) from tenk1 where hundred > 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(unique1) FROM tenk1 WHERE hundred > 1" +== 073 +-- truncate_limit: 100 +select count((unique1)) from tenk1 where hundred > 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT count(unique1) FROM tenk1 WHERE hundred > 1" +== 074 +-- truncate_limit: 100 +-- Parallel ScalarArrayOp index scan +explain (costs off) + select count((unique1)) from tenk1 + where hundred = any ((select array_agg(i) from generate_series(1, 100, 15) i)::int[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(unique1) FROM tenk1 WHERE hundred = ANY((SELECT array_agg(i) FRO..." +== 075 +-- truncate_limit: 100 +select count((unique1)) from tenk1 +where hundred = any ((select array_agg(i) from generate_series(1, 100, 15) i)::int[]) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT count(unique1) FROM tenk1 WHERE ..." +== 076 +-- truncate_limit: 100 +-- test parallel index-only scans. +explain (costs off) + select count(*) from tenk1 where thousand > 95 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE thousand > 95" +== 077 +-- truncate_limit: 100 +select count(*) from tenk1 where thousand > 95 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 WHERE thousand > 95" +== 078 +-- truncate_limit: 100 +-- test rescan cases too +set enable_material = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_material TO FALSE" +== 079 +-- truncate_limit: 100 +explain (costs off) +select * from + (select count(unique1) from tenk1 where hundred > 10) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT count(unique1) FROM tenk1 WHERE hundred > 10) ss RIGHT ..." +== 080 +-- truncate_limit: 100 +select * from + (select count(unique1) from tenk1 where hundred > 10) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM tenk1 WHERE ...) ss RIGHT JOIN (VALUES (1), (2), (3)) v(x) ON true" +== 081 +-- truncate_limit: 100 +explain (costs off) +select * from + (select count(*) from tenk1 where thousand > 99) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT count(*) FROM tenk1 WHERE thousand > 99) ss RIGHT JOIN ..." +== 082 +-- truncate_limit: 100 +select * from + (select count(*) from tenk1 where thousand > 99) ss + right join (values (1),(2),(3)) v(x) on true +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT count(*) FROM tenk1 WHERE ...) ss RIGHT JOIN (VALUES (...)) v(x) ON true" +== 083 +-- truncate_limit: 100 +-- test rescans for a Limit node with a parallel node beneath it. +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 084 +-- truncate_limit: 100 +set enable_indexonlyscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO OFF" +== 085 +-- truncate_limit: 100 +set enable_indexscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 086 +-- truncate_limit: 100 +alter table tenk1 set (parallel_workers = 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk1 SET (parallel_workers=0)" +== 087 +-- truncate_limit: 100 +alter table tenk2 set (parallel_workers = 1) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 SET (parallel_workers=1)" +== 088 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 LEFT JOIN (SELECT tenk2.unique1 FROM tenk2 ORDER B..." +== 089 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 LEFT JOIN (SELECT ... FROM tenk2 ORDER BY 1 LIMIT 1000) ss ON tenk1.unique1..." +== 090 +-- truncate_limit: 100 +--reset the value of workers for each table as it was before this test. +alter table tenk1 set (parallel_workers = 4) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk1 SET (parallel_workers=4)" +== 091 +-- truncate_limit: 100 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 RESET (parallel_workers)" +== 092 +-- truncate_limit: 100 +reset enable_material +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_material" +== 093 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 094 +-- truncate_limit: 100 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexonlyscan" +== 095 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 096 +-- truncate_limit: 100 +-- test parallel bitmap heap scan. +set enable_seqscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 097 +-- truncate_limit: 100 +set enable_indexscan to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 098 +-- truncate_limit: 100 +set enable_hashjoin to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 099 +-- truncate_limit: 100 +set enable_mergejoin to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_mergejoin TO OFF" +== 100 +-- truncate_limit: 100 +set enable_material to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_material TO OFF" +== 101 +-- truncate_limit: 100 +-- test prefetching, if the platform allows it +DO $$ +BEGIN + SET effective_io_concurrency = 50; +EXCEPTION WHEN invalid_parameter_value THEN +END $$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nBEGIN\n SET effective_io_concurrency = 50;\nEXCEPTION WHEN invalid_parameter_value THEN\nEND $$" +== 102 +-- truncate_limit: 100 +set work_mem='64kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET work_mem TO \"64kB\"" +== 103 +-- truncate_limit: 100 +--set small work mem to force lossy pages +explain (costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="hundred" +FILTER: schema="" table="tenk2" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1, tenk2 WHERE tenk1.hundred > 1 AND tenk2.thousand = 0" +== 104 +-- truncate_limit: 100 +select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="hundred" +FILTER: schema="" table="tenk2" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1, tenk2 WHERE tenk1.hundred > 1 AND tenk2.thousand = 0" +== 105 +-- truncate_limit: 100 +create table bmscantest (a int, t text) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bmscantest (a int, t text)" +== 106 +-- truncate_limit: 100 +insert into bmscantest select r, 'fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' FROM generate_series(1,100000) r +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bmscantest SELECT ... FROM generate_series(1, 100000) r" +== 107 +-- truncate_limit: 100 +create index i_bmtest ON bmscantest(a) +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX i_bmtest ON bmscantest USING btree (a)" +== 108 +-- truncate_limit: 100 +select count(*) from bmscantest where a>1 +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM bmscantest WHERE a > 1" +== 109 +-- truncate_limit: 100 +-- test accumulation of stats for parallel nodes +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 110 +-- truncate_limit: 100 +alter table tenk2 set (parallel_workers = 0) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 SET (parallel_workers=0)" +== 111 +-- truncate_limit: 100 +explain (analyze, timing off, summary off, costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 + and tenk2.thousand=0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="hundred" +FILTER: schema="" table="tenk2" column="thousand" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, SUMMARY OFF, COSTS OFF) SELECT count(*) FROM tenk1, tenk2 WHERE ten..." +== 112 +-- truncate_limit: 100 +alter table tenk2 reset (parallel_workers) +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tenk2 RESET (parallel_workers)" +== 113 +-- truncate_limit: 100 +reset work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET work_mem" +== 114 +-- truncate_limit: 100 +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; +$$ +-- +FUNCTION: name="explain_parallel_sort_stats" function="explain_parallel_sort_stats" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_parallel_sort_stats() RETURNS SETOF text LANGUAGE plpgsql AS $$\ndeclare l..." +== 115 +-- truncate_limit: 100 +select * from explain_parallel_sort_stats() +-- +FUNCTION: name="explain_parallel_sort_stats" function="explain_parallel_sort_stats" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM explain_parallel_sort_stats()" +== 116 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 117 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 118 +-- truncate_limit: 100 +reset enable_mergejoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_mergejoin" +== 119 +-- truncate_limit: 100 +reset enable_material +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_material" +== 120 +-- truncate_limit: 100 +reset effective_io_concurrency +-- +STMT: VariableSetStmt +TRUNCATED: "RESET effective_io_concurrency" +== 121 +-- truncate_limit: 100 +drop table bmscantest +-- +TABLE: name="bmscantest" schema="" table="bmscantest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE bmscantest" +== 122 +-- truncate_limit: 100 +drop function explain_parallel_sort_stats() +-- +FUNCTION: name="explain_parallel_sort_stats" function="explain_parallel_sort_stats" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION explain_parallel_sort_stats()" +== 123 +-- truncate_limit: 100 +-- test parallel merge join path. +set enable_hashjoin to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 124 +-- truncate_limit: 100 +set enable_nestloop to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_nestloop TO OFF" +== 125 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="tenk2" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1, tenk2 WHERE tenk1.unique1 = tenk2.unique1" +== 126 +-- truncate_limit: 100 +select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="tenk1" column="unique1" +FILTER: schema="" table="tenk2" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1, tenk2 WHERE tenk1.unique1 = tenk2.unique1" +== 127 +-- truncate_limit: 100 +reset enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 128 +-- truncate_limit: 100 +reset enable_nestloop +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_nestloop" +== 129 +-- truncate_limit: 100 +-- test gather merge +set enable_hashagg = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 130 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 GROUP BY twenty" +== 131 +-- truncate_limit: 100 +select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 GROUP BY twenty" +== 132 +-- truncate_limit: 100 +--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 +-- +FUNCTION: name="sp_simple_func" function="sp_simple_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sp_simple_func(var1 int) RETURNS int AS $$\nbegin\n return var1 + 10;\nend;\n$..." +== 133 +-- truncate_limit: 100 +explain (costs off, verbose) + select ten, sp_simple_func(ten) from tenk1 where ten < 100 order by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sp_simple_func" function="sp_simple_func" schema="" ctx=Call +FILTER: schema="" table="" column="ten" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT ten, sp_simple_func(ten) FROM tenk1 WHERE ten < 100 ORDER BY ten" +== 134 +-- truncate_limit: 100 +drop function sp_simple_func(integer) +-- +FUNCTION: name="sp_simple_func" function="sp_simple_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION sp_simple_func(int)" +== 135 +-- truncate_limit: 100 +-- test handling of SRFs in targetlist (bug in 10.0) + +explain (costs off) + select count(*), generate_series(1,2) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*), generate_series(1, 2) FROM tenk1 GROUP BY twenty" +== 136 +-- truncate_limit: 100 +select count(*), generate_series(1,2) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*), generate_series(1, 2) FROM tenk1 GROUP BY twenty" +== 137 +-- truncate_limit: 100 +-- test gather merge with parallel leader participation disabled +set parallel_leader_participation = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 138 +-- truncate_limit: 100 +explain (costs off) + select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 GROUP BY twenty" +== 139 +-- truncate_limit: 100 +select count(*) from tenk1 group by twenty +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 GROUP BY twenty" +== 140 +-- truncate_limit: 100 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_leader_participation" +== 141 +-- truncate_limit: 100 +--test rescan behavior of gather merge +set enable_material = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_material TO FALSE" +== 142 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT string4, count(unique2) FROM tenk1 GROUP BY string4 ORD..." +== 143 +-- truncate_limit: 100 +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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM tenk1 GROUP BY string4 ORDER BY string4) ss RIGHT JOIN (VALUES (....." +== 144 +-- truncate_limit: 100 +reset enable_material +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_material" +== 145 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 146 +-- truncate_limit: 100 +-- check parallelized int8 aggregate (bug #14897) +explain (costs off) +select avg(unique1::int8) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT avg(unique1::int8) FROM tenk1" +== 147 +-- truncate_limit: 100 +select avg(unique1::int8) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT avg(unique1::int8) FROM tenk1" +== 148 +-- truncate_limit: 100 +-- gather merge test with a LIMIT +explain (costs off) + select fivethous from tenk1 order by fivethous limit 4 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT fivethous FROM tenk1 ORDER BY fivethous LIMIT 4" +== 149 +-- truncate_limit: 100 +select fivethous from tenk1 order by fivethous limit 4 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT fivethous FROM tenk1 ORDER BY fivethous LIMIT 4" +== 150 +-- truncate_limit: 100 +-- gather merge test with 0 worker +set max_parallel_workers = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers TO 0" +== 151 +-- truncate_limit: 100 +explain (costs off) + select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT string4 FROM tenk1 ORDER BY string4 LIMIT 5" +== 152 +-- truncate_limit: 100 +select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT string4 FROM tenk1 ORDER BY string4 LIMIT 5" +== 153 +-- truncate_limit: 100 +-- 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 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_leader_participation TO OFF" +== 154 +-- truncate_limit: 100 +explain (costs off) + select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT string4 FROM tenk1 ORDER BY string4 LIMIT 5" +== 155 +-- truncate_limit: 100 +select string4 from tenk1 order by string4 limit 5 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT string4 FROM tenk1 ORDER BY string4 LIMIT 5" +== 156 +-- truncate_limit: 100 +reset parallel_leader_participation +-- +STMT: VariableSetStmt +TRUNCATED: "RESET parallel_leader_participation" +== 157 +-- truncate_limit: 100 +reset max_parallel_workers +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_workers" +== 158 +-- truncate_limit: 100 +create function parallel_safe_volatile(a int) returns int as + $$ begin return a; end; $$ parallel safe volatile language plpgsql +-- +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION parallel_safe_volatile(a int) RETURNS int AS $$ begin return a; end; $$ PARALLEL ..." +== 159 +-- truncate_limit: 100 +-- Test gather merge atop of a sort of a partial path +explain (costs off) +select * from tenk1 where four = 2 +order by four, hundred, parallel_safe_volatile(thousand) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=Call +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE four = 2 ORDER BY four, hundred, parallel_safe_vola..." +== 160 +-- truncate_limit: 100 +-- Test gather merge atop of an incremental sort a of partial path +set min_parallel_index_scan_size = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_index_scan_size TO 0" +== 161 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 162 +-- truncate_limit: 100 +explain (costs off) +select * from tenk1 where four = 2 +order by four, hundred, parallel_safe_volatile(thousand) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=Call +FILTER: schema="" table="" column="four" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE four = 2 ORDER BY four, hundred, parallel_safe_vola..." +== 163 +-- truncate_limit: 100 +reset min_parallel_index_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_index_scan_size" +== 164 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 165 +-- truncate_limit: 100 +-- Test GROUP BY with a gather merge path atop of a sort of a partial path +explain (costs off) +select count(*) from tenk1 +group by twenty, parallel_safe_volatile(two) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 GROUP BY twenty, parallel_safe_volatile(two)" +== 166 +-- truncate_limit: 100 +drop function parallel_safe_volatile(int) +-- +FUNCTION: name="parallel_safe_volatile" function="parallel_safe_volatile" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION parallel_safe_volatile(int)" +== 167 +-- truncate_limit: 100 +SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 168 +-- truncate_limit: 100 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL debug_parallel_query TO 1" +== 169 +-- truncate_limit: 100 +explain (costs off) + select stringu1::int2 from tenk1 where unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT stringu1::int2 FROM tenk1 WHERE unique1 = 1" +== 170 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 171 +-- truncate_limit: 100 +-- 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; +$$ +-- +FUNCTION: name="make_record" function="make_record" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION make_record(n int) RETURNS record LANGUAGE plpgsql PARALLEL safe AS $$\nBEGIN\n RE..." +== 172 +-- truncate_limit: 100 +SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 173 +-- truncate_limit: 100 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL debug_parallel_query TO 1" +== 174 +-- truncate_limit: 100 +SELECT make_record(x) FROM (SELECT generate_series(1, 5) x) ss ORDER BY x +-- +FUNCTION: name="make_record" function="make_record" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_record(x) FROM (SELECT generate_series(1, 5) AS x) ss ORDER BY x" +== 175 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 176 +-- truncate_limit: 100 +DROP function make_record(n int) +-- +FUNCTION: name="make_record" function="make_record" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION make_record(n int)" +== 177 +-- truncate_limit: 100 +-- test the sanity of parallel query after the active role is dropped. +drop role if exists regress_parallel_worker +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE IF EXISTS regress_parallel_worker" +== 178 +-- truncate_limit: 100 +create role regress_parallel_worker +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_parallel_worker" +== 179 +-- truncate_limit: 100 +set role regress_parallel_worker +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_parallel_worker" +== 180 +-- truncate_limit: 100 +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 181 +-- truncate_limit: 100 +drop role regress_parallel_worker +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_parallel_worker" +== 182 +-- truncate_limit: 100 +set debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 1" +== 183 +-- truncate_limit: 100 +select count(*) from tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1" +== 184 +-- truncate_limit: 100 +reset debug_parallel_query +-- +STMT: VariableSetStmt +TRUNCATED: "RESET debug_parallel_query" +== 185 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 186 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +FILTER: schema="" table="" column="two" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT count(*) FROM tenk1 a WHERE (unique1, two) IN (SELECT unique1..." +== 187 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="two" +FILTER: schema="" table="" column="stringu1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a WHERE two IN (SELECT two FROM tenk1 b WHERE stringu1 LI..." +== 188 +-- truncate_limit: 100 +-- to increase the parallel query test coverage +SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 189 +-- truncate_limit: 100 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL debug_parallel_query TO 1" +== 190 +-- truncate_limit: 100 +EXPLAIN (analyze, timing off, summary off, costs off) SELECT * FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (ANALYZE, TIMING OFF, SUMMARY OFF, COSTS OFF) SELECT * FROM tenk1" +== 191 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 192 +-- truncate_limit: 100 +-- provoke error in worker +-- (make the error message long enough to require multiple bufferloads) +SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 193 +-- truncate_limit: 100 +SET LOCAL debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL debug_parallel_query TO 1" +== 194 +-- truncate_limit: 100 +select (stringu1 || repeat('abcd', 5000))::int2 from tenk1 where unique1 = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT (stringu1 || repeat('abcd', 5000))::int2 FROM tenk1 WHERE unique1 = 1" +== 195 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 196 +-- truncate_limit: 100 +-- test interaction with set-returning functions +SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT settings" +== 197 +-- truncate_limit: 100 +-- multiple subqueries under a single Gather node +-- must set parallel_setup_cost > 0 to discourage multiple Gather nodes +SET LOCAL parallel_setup_cost = 10 +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL parallel_setup_cost TO 10" +== 198 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1 +UNION ALL +SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="tenthous" +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="tenthous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE fivethous = (tenthous + 1) UNION ALL SELECT u..." +== 199 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT settings +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT settings" +== 200 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="fivethous" +FILTER: schema="" table="" column="fivethous" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 WHERE fivethous = (SELECT unique1 FROM tenk1 WHERE ..." +== 201 +-- truncate_limit: 100 +-- test interaction with SRFs +SELECT * FROM information_schema.foreign_data_wrapper_options +ORDER BY 1, 2, 3 +-- +TABLE: name="information_schema.foreign_data_wrapper_options" schema="information_schema" table="foreign_data_wrapper_options" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3" +== 202 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT generate_series(1, two), array(select generate_series(1, two)) + FROM tenk1 ORDER BY tenthous +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT generate_series(1, two), ARRAY(SELECT generate_series(1, two)..." +== 203 +-- truncate_limit: 100 +-- must disallow pushing sort below gather when pathkey contains an SRF +EXPLAIN (VERBOSE, COSTS OFF) +SELECT unnest(ARRAY[]::integer[]) + 1 AS pathkey + FROM tenk1 t1 JOIN tenk1 t2 ON TRUE + ORDER BY pathkey +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT unnest(ARRAY[]::int[]) + 1 AS pathkey FROM tenk1 t1 JOIN tenk..." +== 204 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="make_some_array" function="make_some_array" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION make_some_array(int, int) RETURNS int[] AS $$declare x int[];\n begin\n x[1] :=..." +== 205 +-- truncate_limit: 100 +CREATE TABLE fooarr(f1 text, f2 int[], f3 text) +-- +TABLE: name="fooarr" schema="" table="fooarr" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fooarr (f1 text, f2 int[], f3 text)" +== 206 +-- truncate_limit: 100 +INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one') +-- +TABLE: name="fooarr" schema="" table="fooarr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fooarr VALUES ('1', ARRAY[1, 2], 'one')" +== 207 +-- truncate_limit: 100 +PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2 +-- +TABLE: name="fooarr" schema="" table="fooarr" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2" +== 208 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2)) +-- +STMT: ExplainStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1, 2))" +== 209 +-- truncate_limit: 100 +EXECUTE pstmt('1', make_some_array(1,2)) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE pstmt('1', make_some_array(1, 2))" +== 210 +-- truncate_limit: 100 +DEALLOCATE pstmt +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE pstmt" +== 211 +-- truncate_limit: 100 +-- test interaction between subquery and partial_paths +CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1 +-- +TABLE: name="tenk1_vw_sec" schema="" table="tenk1_vw_sec" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1" +== 212 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT 1 FROM tenk1_vw_sec + WHERE (SELECT sum(f1) FROM int4_tbl WHERE f1 < unique1) < 100 +-- +TABLE: name="tenk1_vw_sec" schema="" table="tenk1_vw_sec" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM tenk1_vw_sec WHERE (SELECT sum(f1) FROM int4_tbl WHERE f1 < uni..." +== 213 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 214 +-- truncate_limit: 100 +-- test that function option SET ROLE works in parallel workers. +create role regress_parallel_worker +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_parallel_worker" +== 215 +-- truncate_limit: 100 +create function set_and_report_role() returns text as + $$ select current_setting('role') $$ language sql parallel safe + set role = regress_parallel_worker +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION set_and_report_role() RETURNS text AS $$ select current_setting('role') $$ LANGUA..." +== 216 +-- truncate_limit: 100 +create function set_role_and_error(int) returns int as + $$ select 1 / $1 $$ language sql parallel safe + set role = regress_parallel_worker +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION set_role_and_error(int) RETURNS int AS $$ select 1 / $1 $$ LANGUAGE sql PARALLEL ..." +== 217 +-- truncate_limit: 100 +set debug_parallel_query = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 0" +== 218 +-- truncate_limit: 100 +select set_and_report_role() +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_and_report_role()" +== 219 +-- truncate_limit: 100 +select set_role_and_error(0) +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_role_and_error(0)" +== 220 +-- truncate_limit: 100 +set debug_parallel_query = 1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO 1" +== 221 +-- truncate_limit: 100 +select set_and_report_role() +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_and_report_role()" +== 222 +-- truncate_limit: 100 +select set_role_and_error(0) +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_role_and_error(0)" +== 223 +-- truncate_limit: 100 +reset debug_parallel_query +-- +STMT: VariableSetStmt +TRUNCATED: "RESET debug_parallel_query" +== 224 +-- truncate_limit: 100 +drop function set_and_report_role() +-- +FUNCTION: name="set_and_report_role" function="set_and_report_role" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION set_and_report_role()" +== 225 +-- truncate_limit: 100 +drop function set_role_and_error(int) +-- +FUNCTION: name="set_role_and_error" function="set_role_and_error" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION set_role_and_error(int)" +== 226 +-- truncate_limit: 100 +drop role regress_parallel_worker +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_parallel_worker" +== 227 +-- truncate_limit: 100 +-- don't freeze in ParallelFinish while holding an LWLock +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 228 +-- truncate_limit: 100 +CREATE FUNCTION my_cmp (int4, int4) +RETURNS int LANGUAGE sql AS +$$ + SELECT + CASE WHEN $1 < $2 THEN -1 + WHEN $1 > $2 THEN 1 + ELSE 0 + END; +$$ +-- +FUNCTION: name="my_cmp" function="my_cmp" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION my_cmp(int4, int4) RETURNS int LANGUAGE sql AS $$\n\tSELECT\n\t\tCASE WHEN $1 < $2 THE..." +== 229 +-- truncate_limit: 100 +CREATE TABLE parallel_hang (i int4) +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parallel_hang (i int4)" +== 230 +-- truncate_limit: 100 +INSERT INTO parallel_hang + (SELECT * FROM generate_series(1, 400) gs) +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parallel_hang SELECT * FROM generate_series(1, 400) gs" +== 231 +-- truncate_limit: 100 +CREATE OPERATOR CLASS int4_custom_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4, int4), OPERATOR 2 <= (int4, int4), + OPERATOR 3 = (int4, int4), OPERATOR 4 >= (int4, int4), + OPERATOR 5 > (int4, int4), FUNCTION 1 my_cmp(int4, int4) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS int4_custom_ops FOR TYPE int4 USING btree AS OPERATOR 1 <(int4, int4), OPER..." +== 232 +-- truncate_limit: 100 +CREATE UNIQUE INDEX parallel_hang_idx + ON parallel_hang + USING btree (i int4_custom_ops) +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX parallel_hang_idx ON parallel_hang USING btree (i int4_custom_ops)" +== 233 +-- truncate_limit: 100 +SET debug_parallel_query = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET debug_parallel_query TO ON" +== 234 +-- truncate_limit: 100 +DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420 +-- +TABLE: name="parallel_hang" schema="" table="parallel_hang" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420" +== 235 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json new file mode 100644 index 0000000..f37dd99 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json @@ -0,0 +1,56 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/select_views.test b/parser/testdata/summary_truncate/postgres_regress/select_views.test new file mode 100644 index 0000000..8a95967 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/select_views.test @@ -0,0 +1,553 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SELECT_VIEWS +-- test the views defined in CREATE_VIEWS +|-- + +SELECT * FROM street +-- +TABLE: name="street" schema="" table="street" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM street" +== 002 +-- truncate_limit: 100 +SELECT name, #thepath FROM iexit ORDER BY name COLLATE "C", 2 +-- +TABLE: name="iexit" schema="" table="iexit" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT name, # thepath FROM iexit ORDER BY name COLLATE \"C\", 2" +== 003 +-- truncate_limit: 100 +SELECT * FROM toyemp WHERE name = 'sharon' +-- +TABLE: name="toyemp" schema="" table="toyemp" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM toyemp WHERE name = 'sharon'" +== 004 +-- truncate_limit: 100 +|-- +-- Test for Leaky view scenario +|-- +CREATE ROLE regress_alice +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_alice" +== 005 +-- truncate_limit: 100 +CREATE FUNCTION f_leak (text) + RETURNS bool LANGUAGE 'plpgsql' COST 0.0000001 + AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END' +-- +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f_leak(text) RETURNS bool LANGUAGE plpgsql COST 0.0000001 AS $$BEGIN RAISE NOTICE..." +== 006 +-- truncate_limit: 100 +CREATE TABLE customer ( + cid int primary key, + name text not null, + tel text, + passwd text +) +-- +TABLE: name="customer" schema="" table="customer" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE customer (cid int PRIMARY KEY, name text NOT NULL, tel text, passwd text)" +== 007 +-- truncate_limit: 100 +CREATE TABLE credit_card ( + cid int references customer(cid), + cnum text, + climit int +) +-- +TABLE: name="credit_card" schema="" table="credit_card" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE credit_card (cid int REFERENCES customer (cid), cnum text, climit int)" +== 008 +-- truncate_limit: 100 +CREATE TABLE credit_usage ( + cid int references customer(cid), + ymd date, + usage int +) +-- +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE credit_usage (cid int REFERENCES customer (cid), ymd date, usage int)" +== 009 +-- truncate_limit: 100 +INSERT INTO customer + VALUES (101, 'regress_alice', '+81-12-3456-7890', 'passwd123'), + (102, 'regress_bob', '+01-234-567-8901', 'beafsteak'), + (103, 'regress_eve', '+49-8765-43210', 'hamburger') +-- +TABLE: name="customer" schema="" table="customer" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO customer VALUES (...)" +== 010 +-- truncate_limit: 100 +INSERT INTO credit_card + VALUES (101, '1111-2222-3333-4444', 4000), + (102, '5555-6666-7777-8888', 3000), + (103, '9801-2345-6789-0123', 2000) +-- +TABLE: name="credit_card" schema="" table="credit_card" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO credit_card VALUES (...)" +== 011 +-- truncate_limit: 100 +INSERT INTO credit_usage + VALUES (101, '2011-09-15', 120), + (101, '2011-10-05', 90), + (101, '2011-10-18', 110), + (101, '2011-10-21', 200), + (101, '2011-11-10', 80), + (102, '2011-09-22', 300), + (102, '2011-10-12', 120), + (102, '2011-10-28', 200), + (103, '2011-10-15', 480) +-- +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO credit_usage VALUES (...)" +== 012 +-- truncate_limit: 100 +CREATE VIEW my_property_normal AS + SELECT * FROM customer WHERE name = current_user +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +FILTER: schema="" table="" column="name" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW my_property_normal AS SELECT * FROM customer WHERE name = current_user" +== 013 +-- truncate_limit: 100 +CREATE VIEW my_property_secure WITH (security_barrier) AS + SELECT * FROM customer WHERE name = current_user +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +FILTER: schema="" table="" column="name" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW my_property_secure WITH (security_barrier) AS SELECT * FROM customer WHERE name = cur..." +== 014 +-- truncate_limit: 100 +CREATE VIEW my_credit_card_normal AS + SELECT * FROM customer l NATURAL JOIN credit_card r + WHERE l.name = current_user +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +TABLE: name="credit_card" schema="" table="credit_card" ctx=Select +ALIAS: "l"="customer" +ALIAS: "r"="credit_card" +FILTER: schema="" table="l" column="name" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW my_credit_card_normal AS SELECT * FROM customer l NATURAL JOIN credit_card r WHERE l...." +== 015 +-- truncate_limit: 100 +CREATE VIEW my_credit_card_secure WITH (security_barrier) AS + SELECT * FROM customer l NATURAL JOIN credit_card r + WHERE l.name = current_user +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=DDL +TABLE: name="customer" schema="" table="customer" ctx=Select +TABLE: name="credit_card" schema="" table="credit_card" ctx=Select +ALIAS: "l"="customer" +ALIAS: "r"="credit_card" +FILTER: schema="" table="l" column="name" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW my_credit_card_secure WITH (security_barrier) AS SELECT * FROM customer l NATURAL JOI..." +== 016 +-- truncate_limit: 100 +CREATE VIEW my_credit_card_usage_normal AS + SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=DDL +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=Select +ALIAS: "l"="my_credit_card_secure" +ALIAS: "r"="credit_usage" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW my_credit_card_usage_normal AS SELECT * FROM my_credit_card_secure l NATURAL JOIN cre..." +== 017 +-- truncate_limit: 100 +CREATE VIEW my_credit_card_usage_secure WITH (security_barrier) AS + SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=DDL +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +TABLE: name="credit_usage" schema="" table="credit_usage" ctx=Select +ALIAS: "l"="my_credit_card_secure" +ALIAS: "r"="credit_usage" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW my_credit_card_usage_secure WITH (security_barrier) AS SELECT * FROM my_credit_card_s..." +== 018 +-- truncate_limit: 100 +GRANT SELECT ON my_property_normal TO public +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON my_property_normal TO public" +== 019 +-- truncate_limit: 100 +GRANT SELECT ON my_property_secure TO public +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON my_property_secure TO public" +== 020 +-- truncate_limit: 100 +GRANT SELECT ON my_credit_card_normal TO public +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON my_credit_card_normal TO public" +== 021 +-- truncate_limit: 100 +GRANT SELECT ON my_credit_card_secure TO public +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON my_credit_card_secure TO public" +== 022 +-- truncate_limit: 100 +GRANT SELECT ON my_credit_card_usage_normal TO public +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON my_credit_card_usage_normal TO public" +== 023 +-- truncate_limit: 100 +GRANT SELECT ON my_credit_card_usage_secure TO public +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON my_credit_card_usage_secure TO public" +== 024 +-- truncate_limit: 100 +|-- +-- Run leaky view scenarios +|-- +SET SESSION AUTHORIZATION regress_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alice" +== 025 +-- truncate_limit: 100 +|-- +-- scenario: if a qualifier with tiny-cost is given, it shall be launched +-- prior to the security policy of the view. +|-- +SELECT * FROM my_property_normal WHERE f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_property_normal WHERE f_leak(passwd)" +== 026 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal WHERE f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal WHERE f_leak(passwd)" +== 027 +-- truncate_limit: 100 +SELECT * FROM my_property_secure WHERE f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_property_secure WHERE f_leak(passwd)" +== 028 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd)" +== 029 +-- truncate_limit: 100 +|-- +-- scenario: qualifiers can be pushed down if they contain leaky functions, +-- provided they aren't passed data from inside the view. +|-- +SELECT * FROM my_property_normal v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +ALIAS: "v"="my_property_normal" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_property_normal v WHERE f_leak('passwd') AND f_leak(passwd)" +== 030 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +ALIAS: "v"="my_property_normal" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v WHERE f_leak('passwd') AND f_leak(passwd)" +== 031 +-- truncate_limit: 100 +SELECT * FROM my_property_secure v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +ALIAS: "v"="my_property_secure" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_property_secure v WHERE f_leak('passwd') AND f_leak(passwd)" +== 032 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v + WHERE f_leak('passwd') AND f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +ALIAS: "v"="my_property_secure" +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v WHERE f_leak('passwd') AND f_leak(passwd)" +== 033 +-- truncate_limit: 100 +|-- +-- scenario: if a qualifier references only one-side of a particular join- +-- tree, it shall be distributed to the most deep scan plan as +-- possible as we can. +|-- +SELECT * FROM my_credit_card_normal WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_credit_card_normal WHERE f_leak(cnum)" +== 034 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_normal WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_normal" schema="" table="my_credit_card_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_normal WHERE f_leak(cnum)" +== 035 +-- truncate_limit: 100 +SELECT * FROM my_credit_card_secure WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_credit_card_secure WHERE f_leak(cnum)" +== 036 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum) +-- +TABLE: name="my_credit_card_secure" schema="" table="my_credit_card_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum)" +== 037 +-- truncate_limit: 100 +|-- +-- scenario: an external qualifier can be pushed-down by in-front-of the +-- views with "security_barrier" attribute, except for operators +-- implemented with leakproof functions. +|-- +SELECT * FROM my_credit_card_usage_normal + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_credit_card_usage_normal WHERE ..." +== 038 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_normal + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_normal" schema="" table="my_credit_card_usage_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_normal WHERE f_leak(cnum) AND ymd >= '2011..." +== 039 +-- truncate_limit: 100 +SELECT * FROM my_credit_card_usage_secure + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_credit_card_usage_secure WHERE ..." +== 040 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_secure + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01' +-- +TABLE: name="my_credit_card_usage_secure" schema="" table="my_credit_card_usage_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="cnum" +FILTER: schema="" table="" column="ymd" +FILTER: schema="" table="" column="ymd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_secure WHERE f_leak(cnum) AND ymd >= '2011..." +== 041 +-- truncate_limit: 100 +|-- +-- Test for the case when security_barrier gets changed between rewriter +-- and planner stage. +|-- +PREPARE p1 AS SELECT * FROM my_property_normal WHERE f_leak(passwd) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE p1 AS SELECT * FROM my_property_normal WHERE f_leak(passwd)" +== 042 +-- truncate_limit: 100 +PREPARE p2 AS SELECT * FROM my_property_secure WHERE f_leak(passwd) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=Select +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FUNCTION: name="f_leak" function="f_leak" schema="" ctx=Call +FILTER: schema="" table="" column="passwd" +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE p2 AS SELECT * FROM my_property_secure WHERE f_leak(passwd)" +== 043 +-- truncate_limit: 100 +EXECUTE p1 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p1" +== 044 +-- truncate_limit: 100 +EXECUTE p2 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p2" +== 045 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 046 +-- truncate_limit: 100 +ALTER VIEW my_property_normal SET (security_barrier=true) +-- +TABLE: name="my_property_normal" schema="" table="my_property_normal" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW my_property_normal SET (security_barrier=true)" +== 047 +-- truncate_limit: 100 +ALTER VIEW my_property_secure SET (security_barrier=false) +-- +TABLE: name="my_property_secure" schema="" table="my_property_secure" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW my_property_secure SET (security_barrier=false)" +== 048 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_alice +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_alice" +== 049 +-- truncate_limit: 100 +EXECUTE p1 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p1" +== 050 +-- truncate_limit: 100 +-- To be perform as a view with security-barrier +EXECUTE p2 +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE p2" +== 051 +-- truncate_limit: 100 +-- To be perform as a view without security-barrier + +-- Cleanup. +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 052 +-- truncate_limit: 100 +DROP ROLE regress_alice +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_alice" diff --git a/parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json new file mode 100644 index 0000000..38ac4c2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json @@ -0,0 +1,264 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/sequence.test b/parser/testdata/summary_truncate/postgres_regress/sequence.test new file mode 100644 index 0000000..43624b6 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sequence.test @@ -0,0 +1,1834 @@ +== 001 +-- truncate_limit: 100 +|-- +-- CREATE SEQUENCE +|-- + +-- various error cases +CREATE SEQUENCE sequence_testx INCREMENT BY 0 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx INCREMENT 0" +== 002 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx INCREMENT BY -1 MINVALUE 20 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx INCREMENT -1 MINVALUE 20" +== 003 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx INCREMENT BY 1 MAXVALUE -20 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx INCREMENT 1 MAXVALUE -20" +== 004 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx INCREMENT BY -1 START 10 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx INCREMENT -1 START 10" +== 005 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx INCREMENT BY 1 START -10 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx INCREMENT 1 START -10" +== 006 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx CACHE 0 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx CACHE 0" +== 007 +-- truncate_limit: 100 +-- OWNED BY errors +CREATE SEQUENCE sequence_testx OWNED BY nobody +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx OWNED BY nobody" +== 008 +-- truncate_limit: 100 +-- nonsense word +CREATE SEQUENCE sequence_testx OWNED BY pg_class_oid_index.oid +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx OWNED BY pg_class_oid_index.oid" +== 009 +-- truncate_limit: 100 +-- not a table +CREATE SEQUENCE sequence_testx OWNED BY pg_class.relname +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx OWNED BY pg_class.relname" +== 010 +-- truncate_limit: 100 +-- not same schema +CREATE TABLE sequence_test_table (a int) +-- +TABLE: name="sequence_test_table" schema="" table="sequence_test_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sequence_test_table (a int)" +== 011 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx OWNED BY sequence_test_table.b +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx OWNED BY sequence_test_table.b" +== 012 +-- truncate_limit: 100 +-- wrong column +DROP TABLE sequence_test_table +-- +TABLE: name="sequence_test_table" schema="" table="sequence_test_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sequence_test_table" +== 013 +-- truncate_limit: 100 +-- sequence data types +CREATE SEQUENCE sequence_test5 AS integer +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test5 AS int" +== 014 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test6 AS smallint +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test6 AS smallint" +== 015 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test7 AS bigint +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test7 AS bigint" +== 016 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test8 AS integer MAXVALUE 100000 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test8 AS int MAXVALUE 100000" +== 017 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test9 AS integer INCREMENT BY -1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test9 AS int INCREMENT -1" +== 018 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test10 AS integer MINVALUE -100000 START 1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test10 AS int MINVALUE -100000 START 1" +== 019 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test11 AS smallint +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test11 AS smallint" +== 020 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test12 AS smallint INCREMENT -1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test12 AS smallint INCREMENT -1" +== 021 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test13 AS smallint MINVALUE -32768 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test13 AS smallint MINVALUE -32768" +== 022 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test14 AS smallint MAXVALUE 32767 INCREMENT -1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test14 AS smallint MAXVALUE 32767 INCREMENT -1" +== 023 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx AS text +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx AS text" +== 024 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx AS nosuchtype +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx AS nosuchtype" +== 025 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx AS smallint MAXVALUE 100000 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx AS smallint MAXVALUE 100000" +== 026 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_testx AS smallint MINVALUE -100000 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_testx AS smallint MINVALUE -100000" +== 027 +-- truncate_limit: 100 +ALTER SEQUENCE sequence_test5 AS smallint +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test5 AS smallint" +== 028 +-- truncate_limit: 100 +-- success, max will be adjusted +ALTER SEQUENCE sequence_test8 AS smallint +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test8 AS smallint" +== 029 +-- truncate_limit: 100 +-- fail, max has to be adjusted +ALTER SEQUENCE sequence_test8 AS smallint MAXVALUE 20000 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test8 AS smallint MAXVALUE 20000" +== 030 +-- truncate_limit: 100 +-- ok now +ALTER SEQUENCE sequence_test9 AS smallint +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test9 AS smallint" +== 031 +-- truncate_limit: 100 +-- success, min will be adjusted +ALTER SEQUENCE sequence_test10 AS smallint +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test10 AS smallint" +== 032 +-- truncate_limit: 100 +-- fail, min has to be adjusted +ALTER SEQUENCE sequence_test10 AS smallint MINVALUE -20000 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test10 AS smallint MINVALUE -20000" +== 033 +-- truncate_limit: 100 +-- ok now + +ALTER SEQUENCE sequence_test11 AS int +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test11 AS int" +== 034 +-- truncate_limit: 100 +-- max will be adjusted +ALTER SEQUENCE sequence_test12 AS int +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test12 AS int" +== 035 +-- truncate_limit: 100 +-- min will be adjusted +ALTER SEQUENCE sequence_test13 AS int +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test13 AS int" +== 036 +-- truncate_limit: 100 +-- min and max will be adjusted +ALTER SEQUENCE sequence_test14 AS int +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test14 AS int" +== 037 +-- truncate_limit: 100 +-- min and max will be adjusted + +--- +--- test creation of SERIAL column +--- + +CREATE TABLE serialTest1 (f1 text, f2 serial) +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE serialtest1 (f1 text, f2 serial)" +== 038 +-- truncate_limit: 100 +INSERT INTO serialTest1 VALUES ('foo') +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest1 VALUES ('foo')" +== 039 +-- truncate_limit: 100 +INSERT INTO serialTest1 VALUES ('bar') +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest1 VALUES ('bar')" +== 040 +-- truncate_limit: 100 +INSERT INTO serialTest1 VALUES ('force', 100) +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest1 VALUES ('force', 100)" +== 041 +-- truncate_limit: 100 +INSERT INTO serialTest1 VALUES ('wrong', NULL) +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest1 VALUES ('wrong', NULL)" +== 042 +-- truncate_limit: 100 +SELECT * FROM serialTest1 +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM serialtest1" +== 043 +-- truncate_limit: 100 +SELECT pg_get_serial_sequence('serialTest1', 'f2') +-- +FUNCTION: name="pg_get_serial_sequence" function="pg_get_serial_sequence" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_serial_sequence('serialTest1', 'f2')" +== 044 +-- truncate_limit: 100 +-- test smallserial / bigserial +CREATE TABLE serialTest2 (f1 text, f2 serial, f3 smallserial, f4 serial2, + f5 bigserial, f6 serial8) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE serialtest2 (f1 text, f2 serial, f3 smallserial, f4 serial2, f5 bigserial, f6 serial8)" +== 045 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1) + VALUES ('test_defaults') +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1) VALUES ('test_defaults')" +== 046 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f2, f3, f4, f5, f6) + VALUES ('test_max_vals', 2147483647, 32767, 32767, 9223372036854775807, + 9223372036854775807), + ('test_min_vals', -2147483648, -32768, -32768, -9223372036854775808, + -9223372036854775808) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f2, f3, f4, f5, f6) VALUES (...)" +== 047 +-- truncate_limit: 100 +-- All these INSERTs should fail: +INSERT INTO serialTest2 (f1, f3) + VALUES ('bogus', -32769) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f3) VALUES ('bogus', -32769)" +== 048 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f4) + VALUES ('bogus', -32769) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f4) VALUES ('bogus', -32769)" +== 049 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f3) + VALUES ('bogus', 32768) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f3) VALUES ('bogus', 32768)" +== 050 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f4) + VALUES ('bogus', 32768) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f4) VALUES ('bogus', 32768)" +== 051 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f5) + VALUES ('bogus', -9223372036854775809) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f5) VALUES ('bogus', -9223372036854775809)" +== 052 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f6) + VALUES ('bogus', -9223372036854775809) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f6) VALUES ('bogus', -9223372036854775809)" +== 053 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f5) + VALUES ('bogus', 9223372036854775808) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f5) VALUES ('bogus', 9223372036854775808)" +== 054 +-- truncate_limit: 100 +INSERT INTO serialTest2 (f1, f6) + VALUES ('bogus', 9223372036854775808) +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest2 (f1, f6) VALUES ('bogus', 9223372036854775808)" +== 055 +-- truncate_limit: 100 +SELECT * FROM serialTest2 ORDER BY f2 ASC +-- +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM serialtest2 ORDER BY f2 ASC" +== 056 +-- truncate_limit: 100 +SELECT nextval('serialTest2_f2_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('serialTest2_f2_seq')" +== 057 +-- truncate_limit: 100 +SELECT nextval('serialTest2_f3_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('serialTest2_f3_seq')" +== 058 +-- truncate_limit: 100 +SELECT nextval('serialTest2_f4_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('serialTest2_f4_seq')" +== 059 +-- truncate_limit: 100 +SELECT nextval('serialTest2_f5_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('serialTest2_f5_seq')" +== 060 +-- truncate_limit: 100 +SELECT nextval('serialTest2_f6_seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('serialTest2_f6_seq')" +== 061 +-- truncate_limit: 100 +-- basic sequence operations using both text and oid references +CREATE SEQUENCE sequence_test +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test" +== 062 +-- truncate_limit: 100 +CREATE SEQUENCE IF NOT EXISTS sequence_test +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE IF NOT EXISTS sequence_test" +== 063 +-- truncate_limit: 100 +SELECT nextval('sequence_test'::text) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test'::text)" +== 064 +-- truncate_limit: 100 +SELECT nextval('sequence_test'::regclass) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test'::regclass)" +== 065 +-- truncate_limit: 100 +SELECT currval('sequence_test'::text) +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('sequence_test'::text)" +== 066 +-- truncate_limit: 100 +SELECT currval('sequence_test'::regclass) +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('sequence_test'::regclass)" +== 067 +-- truncate_limit: 100 +SELECT setval('sequence_test'::text, 32) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test'::text, 32)" +== 068 +-- truncate_limit: 100 +SELECT nextval('sequence_test'::regclass) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test'::regclass)" +== 069 +-- truncate_limit: 100 +SELECT setval('sequence_test'::text, 99, false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test'::text, 99, false)" +== 070 +-- truncate_limit: 100 +SELECT nextval('sequence_test'::regclass) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test'::regclass)" +== 071 +-- truncate_limit: 100 +SELECT setval('sequence_test'::regclass, 32) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test'::regclass, 32)" +== 072 +-- truncate_limit: 100 +SELECT nextval('sequence_test'::text) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test'::text)" +== 073 +-- truncate_limit: 100 +SELECT setval('sequence_test'::regclass, 99, false) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test'::regclass, 99, false)" +== 074 +-- truncate_limit: 100 +SELECT nextval('sequence_test'::text) +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test'::text)" +== 075 +-- truncate_limit: 100 +DISCARD SEQUENCES +-- +STMT: DiscardStmt +TRUNCATED: "DISCARD SEQUENCES" +== 076 +-- truncate_limit: 100 +SELECT currval('sequence_test'::regclass) +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('sequence_test'::regclass)" +== 077 +-- truncate_limit: 100 +DROP SEQUENCE sequence_test +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE sequence_test" +== 078 +-- truncate_limit: 100 +-- renaming sequences +CREATE SEQUENCE foo_seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE foo_seq" +== 079 +-- truncate_limit: 100 +ALTER TABLE foo_seq RENAME TO foo_seq_new +-- +TABLE: name="foo_seq" schema="" table="foo_seq" ctx=DDL +TABLE: name="foo_seq_new" schema="" table="foo_seq_new" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE foo_seq RENAME TO foo_seq_new" +== 080 +-- truncate_limit: 100 +SELECT * FROM foo_seq_new +-- +TABLE: name="foo_seq_new" schema="" table="foo_seq_new" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo_seq_new" +== 081 +-- truncate_limit: 100 +SELECT nextval('foo_seq_new') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('foo_seq_new')" +== 082 +-- truncate_limit: 100 +SELECT nextval('foo_seq_new') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('foo_seq_new')" +== 083 +-- truncate_limit: 100 +-- log_cnt can be higher if there is a checkpoint just at the right +-- time, so just test for the expected range +SELECT last_value, log_cnt IN (31, 32) AS log_cnt_ok, is_called FROM foo_seq_new +-- +TABLE: name="foo_seq_new" schema="" table="foo_seq_new" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT last_value, log_cnt IN (31, 32) AS log_cnt_ok, is_called FROM foo_seq_new" +== 084 +-- truncate_limit: 100 +DROP SEQUENCE foo_seq_new +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE foo_seq_new" +== 085 +-- truncate_limit: 100 +-- renaming serial sequences +ALTER TABLE serialtest1_f2_seq RENAME TO serialtest1_f2_foo +-- +TABLE: name="serialtest1_f2_seq" schema="" table="serialtest1_f2_seq" ctx=DDL +TABLE: name="serialtest1_f2_foo" schema="" table="serialtest1_f2_foo" ctx=DDL +STMT: RenameStmt +TRUNCATED: "ALTER TABLE serialtest1_f2_seq RENAME TO serialtest1_f2_foo" +== 086 +-- truncate_limit: 100 +INSERT INTO serialTest1 VALUES ('more') +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serialtest1 VALUES ('more')" +== 087 +-- truncate_limit: 100 +SELECT * FROM serialTest1 +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM serialtest1" +== 088 +-- truncate_limit: 100 +|-- +-- Check dependencies of serial and ordinary sequences +|-- +CREATE TEMP SEQUENCE myseq2 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE myseq2" +== 089 +-- truncate_limit: 100 +CREATE TEMP SEQUENCE myseq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE myseq3" +== 090 +-- truncate_limit: 100 +CREATE TEMP TABLE t1 ( + f1 serial, + f2 int DEFAULT nextval('myseq2'), + f3 int DEFAULT nextval('myseq3'::text) +) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (f1 serial, f2 int DEFAULT nextval('myseq2'), f3 int DEFAULT nextval('m..." +== 091 +-- truncate_limit: 100 +-- Both drops should fail, but with different error messages: +DROP SEQUENCE t1_f1_seq +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE t1_f1_seq" +== 092 +-- truncate_limit: 100 +DROP SEQUENCE myseq2 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE myseq2" +== 093 +-- truncate_limit: 100 +-- This however will work: +DROP SEQUENCE myseq3 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE myseq3" +== 094 +-- truncate_limit: 100 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1" +== 095 +-- truncate_limit: 100 +-- Fails because no longer existent: +DROP SEQUENCE t1_f1_seq +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE t1_f1_seq" +== 096 +-- truncate_limit: 100 +-- Now OK: +DROP SEQUENCE myseq2 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE myseq2" +== 097 +-- truncate_limit: 100 +|-- +-- Alter sequence +|-- + +ALTER SEQUENCE IF EXISTS sequence_test2 RESTART WITH 24 + INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE IF EXISTS sequence_test2 RESTART 24 INCREMENT 4 MAXVALUE 36 MINVALUE 5 CYCLE" +== 098 +-- truncate_limit: 100 +ALTER SEQUENCE serialTest1 CYCLE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE serialtest1 CYCLE" +== 099 +-- truncate_limit: 100 +-- error, not a sequence + +CREATE SEQUENCE sequence_test2 START WITH 32 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test2 START 32" +== 100 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test4 INCREMENT BY -1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test4 INCREMENT -1" +== 101 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 102 +-- truncate_limit: 100 +SELECT nextval('sequence_test4') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test4')" +== 103 +-- truncate_limit: 100 +ALTER SEQUENCE sequence_test2 RESTART +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test2 RESTART" +== 104 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 105 +-- truncate_limit: 100 +ALTER SEQUENCE sequence_test2 RESTART WITH 0 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test2 RESTART 0" +== 106 +-- truncate_limit: 100 +-- error +ALTER SEQUENCE sequence_test4 RESTART WITH 40 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test4 RESTART 40" +== 107 +-- truncate_limit: 100 +-- error + +-- test CYCLE and NO CYCLE +ALTER SEQUENCE sequence_test2 RESTART WITH 24 + INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test2 RESTART 24 INCREMENT 4 MAXVALUE 36 MINVALUE 5 CYCLE" +== 108 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 109 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 110 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 111 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 112 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 113 +-- truncate_limit: 100 +-- cycled + +ALTER SEQUENCE sequence_test2 RESTART WITH 24 + NO CYCLE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test2 RESTART 24 NO CYCLE" +== 114 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 115 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 116 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 117 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 118 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 119 +-- truncate_limit: 100 +-- error + +ALTER SEQUENCE sequence_test2 RESTART WITH -24 START WITH -24 + INCREMENT BY -4 MINVALUE -36 MAXVALUE -5 CYCLE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test2 RESTART -24 START -24 INCREMENT -4 MINVALUE -36 MAXVALUE -5 CYCLE" +== 120 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 121 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 122 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 123 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 124 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 125 +-- truncate_limit: 100 +-- cycled + +ALTER SEQUENCE sequence_test2 RESTART WITH -24 + NO CYCLE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test2 RESTART -24 NO CYCLE" +== 126 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 127 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 128 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 129 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 130 +-- truncate_limit: 100 +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 131 +-- truncate_limit: 100 +-- error + +-- reset +ALTER SEQUENCE IF EXISTS sequence_test2 RESTART WITH 32 START WITH 32 + INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE IF EXISTS sequence_test2 RESTART 32 START 32 INCREMENT 4 MAXVALUE 36 MINVALUE 5 CYCLE" +== 132 +-- truncate_limit: 100 +SELECT setval('sequence_test2', -100) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test2', -100)" +== 133 +-- truncate_limit: 100 +-- error +SELECT setval('sequence_test2', 100) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test2', 100)" +== 134 +-- truncate_limit: 100 +-- error +SELECT setval('sequence_test2', 5) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test2', 5)" +== 135 +-- truncate_limit: 100 +CREATE SEQUENCE sequence_test3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE sequence_test3" +== 136 +-- truncate_limit: 100 +-- not read from, to test is_called + + +-- Information schema +SELECT * FROM information_schema.sequences + WHERE sequence_name ~ ANY(ARRAY['sequence_test', 'serialtest']) + ORDER BY sequence_name ASC +-- +TABLE: name="information_schema.sequences" schema="information_schema" table="sequences" ctx=Select +FILTER: schema="" table="" column="sequence_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.sequences WHERE ... ORDER BY sequence_name ASC" +== 137 +-- truncate_limit: 100 +SELECT schemaname, sequencename, start_value, min_value, max_value, increment_by, cycle, cache_size, last_value +FROM pg_sequences +WHERE sequencename ~ ANY(ARRAY['sequence_test', 'serialtest']) + ORDER BY sequencename ASC +-- +TABLE: name="pg_sequences" schema="" table="pg_sequences" ctx=Select +FILTER: schema="" table="" column="sequencename" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_sequences WHERE ... ORDER BY sequencename ASC" +== 138 +-- truncate_limit: 100 +SELECT * FROM pg_sequence_parameters('sequence_test4'::regclass) +-- +FUNCTION: name="pg_sequence_parameters" function="pg_sequence_parameters" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_sequence_parameters('sequence_test4'::regclass)" +== 139 +-- truncate_limit: 100 +-- Test comments +COMMENT ON SEQUENCE asdf IS 'won''t work' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON SEQUENCE asdf IS 'won''t work'" +== 140 +-- truncate_limit: 100 +COMMENT ON SEQUENCE sequence_test2 IS 'will work' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON SEQUENCE sequence_test2 IS 'will work'" +== 141 +-- truncate_limit: 100 +COMMENT ON SEQUENCE sequence_test2 IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON SEQUENCE sequence_test2 IS NULL" +== 142 +-- truncate_limit: 100 +-- Test lastval() +CREATE SEQUENCE seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq" +== 143 +-- truncate_limit: 100 +SELECT nextval('seq') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq')" +== 144 +-- truncate_limit: 100 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 145 +-- truncate_limit: 100 +SELECT setval('seq', 99) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('seq', 99)" +== 146 +-- truncate_limit: 100 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 147 +-- truncate_limit: 100 +DISCARD SEQUENCES +-- +STMT: DiscardStmt +TRUNCATED: "DISCARD SEQUENCES" +== 148 +-- truncate_limit: 100 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 149 +-- truncate_limit: 100 +CREATE SEQUENCE seq2 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq2" +== 150 +-- truncate_limit: 100 +SELECT nextval('seq2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq2')" +== 151 +-- truncate_limit: 100 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 152 +-- truncate_limit: 100 +DROP SEQUENCE seq2 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE seq2" +== 153 +-- truncate_limit: 100 +-- should fail +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 154 +-- truncate_limit: 100 +-- unlogged sequences +-- (more tests in src/test/recovery/) +CREATE UNLOGGED SEQUENCE sequence_test_unlogged +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE UNLOGGED SEQUENCE sequence_test_unlogged" +== 155 +-- truncate_limit: 100 +ALTER SEQUENCE sequence_test_unlogged SET LOGGED +-- +TABLE: name="sequence_test_unlogged" schema="" table="sequence_test_unlogged" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER SEQUENCE sequence_test_unlogged SET LOGGED" +== 156 +-- truncate_limit: 100 +ALTER SEQUENCE sequence_test_unlogged SET UNLOGGED +-- +TABLE: name="sequence_test_unlogged" schema="" table="sequence_test_unlogged" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER SEQUENCE sequence_test_unlogged SET UNLOGGED" +== 157 +-- truncate_limit: 100 +DROP SEQUENCE sequence_test_unlogged +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE sequence_test_unlogged" +== 158 +-- truncate_limit: 100 +-- Test sequences in read-only transactions +CREATE TEMPORARY SEQUENCE sequence_test_temp1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE sequence_test_temp1" +== 159 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 160 +-- truncate_limit: 100 +SELECT nextval('sequence_test_temp1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test_temp1')" +== 161 +-- truncate_limit: 100 +-- ok +SELECT nextval('sequence_test2') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('sequence_test2')" +== 162 +-- truncate_limit: 100 +-- error +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 163 +-- truncate_limit: 100 +START TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ ONLY" +== 164 +-- truncate_limit: 100 +SELECT setval('sequence_test_temp1', 1) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test_temp1', 1)" +== 165 +-- truncate_limit: 100 +-- ok +SELECT setval('sequence_test2', 1) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('sequence_test2', 1)" +== 166 +-- truncate_limit: 100 +-- error +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 167 +-- truncate_limit: 100 +-- privileges tests + +CREATE USER regress_seq_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_seq_user" +== 168 +-- truncate_limit: 100 +-- nextval +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 169 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 170 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 171 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 172 +-- truncate_limit: 100 +GRANT SELECT ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON seq3 TO regress_seq_user" +== 173 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 174 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 175 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 176 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 177 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 178 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 179 +-- truncate_limit: 100 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON seq3 TO regress_seq_user" +== 180 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 181 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 182 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 183 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 184 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 185 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 186 +-- truncate_limit: 100 +GRANT USAGE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT usage ON seq3 TO regress_seq_user" +== 187 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 188 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 189 +-- truncate_limit: 100 +-- currval +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 190 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 191 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 192 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 193 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 194 +-- truncate_limit: 100 +GRANT SELECT ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON seq3 TO regress_seq_user" +== 195 +-- truncate_limit: 100 +SELECT currval('seq3') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('seq3')" +== 196 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 197 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 198 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 199 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 200 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 201 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 202 +-- truncate_limit: 100 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON seq3 TO regress_seq_user" +== 203 +-- truncate_limit: 100 +SELECT currval('seq3') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('seq3')" +== 204 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 205 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 206 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 207 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 208 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 209 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 210 +-- truncate_limit: 100 +GRANT USAGE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT usage ON seq3 TO regress_seq_user" +== 211 +-- truncate_limit: 100 +SELECT currval('seq3') +-- +FUNCTION: name="currval" function="currval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currval('seq3')" +== 212 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 213 +-- truncate_limit: 100 +-- lastval +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 214 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 215 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 216 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 217 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 218 +-- truncate_limit: 100 +GRANT SELECT ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON seq3 TO regress_seq_user" +== 219 +-- truncate_limit: 100 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 220 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 221 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 222 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 223 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 224 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 225 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 226 +-- truncate_limit: 100 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON seq3 TO regress_seq_user" +== 227 +-- truncate_limit: 100 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 228 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 229 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 230 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 231 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 232 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 233 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 234 +-- truncate_limit: 100 +GRANT USAGE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT usage ON seq3 TO regress_seq_user" +== 235 +-- truncate_limit: 100 +SELECT lastval() +-- +FUNCTION: name="lastval" function="lastval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT lastval()" +== 236 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 237 +-- truncate_limit: 100 +-- setval +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 238 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 239 +-- truncate_limit: 100 +CREATE SEQUENCE seq3 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE seq3" +== 240 +-- truncate_limit: 100 +REVOKE ALL ON seq3 FROM regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON seq3 FROM regress_seq_user" +== 241 +-- truncate_limit: 100 +SAVEPOINT save +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT save" +== 242 +-- truncate_limit: 100 +SELECT setval('seq3', 5) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('seq3', 5)" +== 243 +-- truncate_limit: 100 +ROLLBACK TO save +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT save" +== 244 +-- truncate_limit: 100 +GRANT UPDATE ON seq3 TO regress_seq_user +-- +TABLE: name="seq3" schema="" table="seq3" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON seq3 TO regress_seq_user" +== 245 +-- truncate_limit: 100 +SELECT setval('seq3', 5) +-- +FUNCTION: name="setval" function="setval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setval('seq3', 5)" +== 246 +-- truncate_limit: 100 +SELECT nextval('seq3') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('seq3')" +== 247 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 248 +-- truncate_limit: 100 +-- ALTER SEQUENCE +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 249 +-- truncate_limit: 100 +SET LOCAL SESSION AUTHORIZATION regress_seq_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL session_authorization TO regress_seq_user" +== 250 +-- truncate_limit: 100 +ALTER SEQUENCE sequence_test2 START WITH 1 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE sequence_test2 START 1" +== 251 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 252 +-- truncate_limit: 100 +-- Sequences should get wiped out as well: +DROP TABLE serialTest1, serialTest2 +-- +TABLE: name="serialtest1" schema="" table="serialtest1" ctx=DDL +TABLE: name="serialtest2" schema="" table="serialtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE serialtest1, serialtest2" +== 253 +-- truncate_limit: 100 +-- Make sure sequences are gone: +SELECT * FROM information_schema.sequences WHERE sequence_name IN + ('sequence_test2', 'serialtest2_f2_seq', 'serialtest2_f3_seq', + 'serialtest2_f4_seq', 'serialtest2_f5_seq', 'serialtest2_f6_seq') + ORDER BY sequence_name ASC +-- +TABLE: name="information_schema.sequences" schema="information_schema" table="sequences" ctx=Select +FILTER: schema="" table="" column="sequence_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.sequences WHERE ... ORDER BY sequence_name ASC" +== 254 +-- truncate_limit: 100 +DROP USER regress_seq_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_seq_user" +== 255 +-- truncate_limit: 100 +DROP SEQUENCE seq +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE seq" +== 256 +-- truncate_limit: 100 +-- cache tests +CREATE SEQUENCE test_seq1 CACHE 10 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE test_seq1 CACHE 10" +== 257 +-- truncate_limit: 100 +SELECT nextval('test_seq1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('test_seq1')" +== 258 +-- truncate_limit: 100 +SELECT nextval('test_seq1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('test_seq1')" +== 259 +-- truncate_limit: 100 +SELECT nextval('test_seq1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('test_seq1')" +== 260 +-- truncate_limit: 100 +DROP SEQUENCE test_seq1 +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE test_seq1" diff --git a/parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json new file mode 100644 index 0000000..442b788 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json @@ -0,0 +1,35 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/spgist.test b/parser/testdata/summary_truncate/postgres_regress/spgist.test new file mode 100644 index 0000000..9ba0142 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/spgist.test @@ -0,0 +1,301 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test SP-GiST indexes. +|-- +-- There are other tests to test different SP-GiST opclasses. This is for +-- testing SP-GiST code itself. + +create table spgist_point_tbl(id int4, p point) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE spgist_point_tbl (id int4, p point)" +== 002 +-- truncate_limit: 100 +create index spgist_point_idx on spgist_point_tbl using spgist(p) with (fillfactor = 75) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_point_idx ON spgist_point_tbl USING spgist (p) WITH (fillfactor=75)" +== 003 +-- truncate_limit: 100 +-- Test vacuum-root operation. It gets invoked when the root is also a leaf, +-- i.e. the index is very small. +insert into spgist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10) g +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_point_tbl (id, p) SELECT g, point(g * 10, g * 10) FROM generate_series(1, 10) g" +== 004 +-- truncate_limit: 100 +delete from spgist_point_tbl where id < 5 +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM spgist_point_tbl WHERE id < 5" +== 005 +-- truncate_limit: 100 +vacuum spgist_point_tbl +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM spgist_point_tbl" +== 006 +-- truncate_limit: 100 +-- Insert more data, to make the index a few levels deep. +insert into spgist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10000) g +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_point_tbl (id, p) SELECT ... FROM generate_series(1, 10000) g" +== 007 +-- truncate_limit: 100 +insert into spgist_point_tbl (id, p) +select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_point_tbl (id, p) SELECT ... FROM generate_series(1, 10000) g" +== 008 +-- truncate_limit: 100 +-- To test vacuum, delete some entries from all over the index. +delete from spgist_point_tbl where id % 2 = 1 +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM spgist_point_tbl WHERE (id % 2) = 1" +== 009 +-- truncate_limit: 100 +-- And also delete some concentration of values. (SP-GiST doesn't currently +-- attempt to delete pages even when they become empty, but if it did, this +-- would exercise it) +delete from spgist_point_tbl where id < 10000 +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM spgist_point_tbl WHERE id < 10000" +== 010 +-- truncate_limit: 100 +vacuum spgist_point_tbl +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM spgist_point_tbl" +== 011 +-- truncate_limit: 100 +-- Test rescan paths (cf. bug #15378) +-- use box and && rather than point, so that rescan happens when the +-- traverse stack is non-empty + +create table spgist_box_tbl(id serial, b box) +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE spgist_box_tbl (id serial, b box)" +== 012 +-- truncate_limit: 100 +insert into spgist_box_tbl(b) +select box(point(i,j),point(i+s,j+s)) + from generate_series(1,100,5) i, + generate_series(1,100,5) j, + generate_series(1,10) s +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_box_tbl (...) SELECT ... FROM generate_series(1, 100, 5) i, generate_series(1,..." +== 013 +-- truncate_limit: 100 +create index spgist_box_idx on spgist_box_tbl using spgist (b) +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_box_idx ON spgist_box_tbl USING spgist (b)" +== 014 +-- truncate_limit: 100 +select count(*) + from (values (point(5,5)),(point(8,8)),(point(12,12))) v(p) + where exists(select * from spgist_box_tbl b where b.b && box(v.p,v.p)) +-- +TABLE: name="spgist_box_tbl" schema="" table="spgist_box_tbl" ctx=Select +ALIAS: "b"="spgist_box_tbl" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="box" function="box" schema="" ctx=Call +FILTER: schema="" table="b" column="b" +FILTER: schema="" table="v" column="p" +FILTER: schema="" table="v" column="p" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (VALUES (...)) v(p) WHERE EXISTS (SELECT * FROM spgist_box_tbl b WHERE ...)" +== 015 +-- truncate_limit: 100 +-- The point opclass's choose method only uses the spgMatchNode action, +-- so the other actions are not tested by the above. Create an index using +-- text opclass, which uses the others actions. + +create table spgist_text_tbl(id int4, t text) +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE spgist_text_tbl (id int4, t text)" +== 016 +-- truncate_limit: 100 +create index spgist_text_idx on spgist_text_tbl using spgist(t) +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_text_idx ON spgist_text_tbl USING spgist (t)" +== 017 +-- truncate_limit: 100 +insert into spgist_text_tbl (id, t) +select g, 'f' || repeat('o', 100) || g from generate_series(1, 10000) g +union all +select g, 'baaaaaaaaaaaaaar' || g from generate_series(1, 1000) g +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_text_tbl (...) SELECT ... FROM generate_series(1, 10000) g UNION ALL SELECT ....." +== 018 +-- truncate_limit: 100 +-- Do a lot of insertions that have to split an existing node. Hopefully +-- one of these will cause the page to run out of space, causing the inner +-- tuple to be moved to another page. +insert into spgist_text_tbl (id, t) +select -g, 'f' || repeat('o', 100-g) || 'surprise' from generate_series(1, 100) g +-- +TABLE: name="spgist_text_tbl" schema="" table="spgist_text_tbl" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_text_tbl (id, t) SELECT ... FROM generate_series(1, 100) g" +== 019 +-- truncate_limit: 100 +-- Test out-of-range fillfactor values +create index spgist_point_idx2 on spgist_point_tbl using spgist(p) with (fillfactor = 9) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_point_idx2 ON spgist_point_tbl USING spgist (p) WITH (fillfactor=9)" +== 020 +-- truncate_limit: 100 +create index spgist_point_idx2 on spgist_point_tbl using spgist(p) with (fillfactor = 101) +-- +TABLE: name="spgist_point_tbl" schema="" table="spgist_point_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_point_idx2 ON spgist_point_tbl USING spgist (p) WITH (fillfactor=101)" +== 021 +-- truncate_limit: 100 +-- Modify fillfactor in existing index +alter index spgist_point_idx set (fillfactor = 90) +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX spgist_point_idx SET (fillfactor=90)" +== 022 +-- truncate_limit: 100 +reindex index spgist_point_idx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX INDEX spgist_point_idx" +== 023 +-- truncate_limit: 100 +-- Test index over a domain +create domain spgist_text as varchar +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN spgist_text AS varchar" +== 024 +-- truncate_limit: 100 +create table spgist_domain_tbl (f1 spgist_text) +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE spgist_domain_tbl (f1 spgist_text)" +== 025 +-- truncate_limit: 100 +create index spgist_domain_idx on spgist_domain_tbl using spgist(f1) +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_domain_idx ON spgist_domain_tbl USING spgist (f1)" +== 026 +-- truncate_limit: 100 +insert into spgist_domain_tbl values('fee'), ('fi'), ('fo'), ('fum') +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_domain_tbl VALUES ('fee'), ('fi'), ('fo'), ('fum')" +== 027 +-- truncate_limit: 100 +explain (costs off) +select * from spgist_domain_tbl where f1 = 'fo' +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM spgist_domain_tbl WHERE f1 = 'fo'" +== 028 +-- truncate_limit: 100 +select * from spgist_domain_tbl where f1 = 'fo' +-- +TABLE: name="spgist_domain_tbl" schema="" table="spgist_domain_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM spgist_domain_tbl WHERE f1 = 'fo'" +== 029 +-- truncate_limit: 100 +-- test an unlogged table, mostly to get coverage of spgistbuildempty +create unlogged table spgist_unlogged_tbl(id serial, b box) +-- +TABLE: name="spgist_unlogged_tbl" schema="" table="spgist_unlogged_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE UNLOGGED TABLE spgist_unlogged_tbl (id serial, b box)" +== 030 +-- truncate_limit: 100 +create index spgist_unlogged_idx on spgist_unlogged_tbl using spgist (b) +-- +TABLE: name="spgist_unlogged_tbl" schema="" table="spgist_unlogged_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_unlogged_idx ON spgist_unlogged_tbl USING spgist (b)" +== 031 +-- truncate_limit: 100 +insert into spgist_unlogged_tbl(b) +select box(point(i,j)) + from generate_series(1,100,5) i, + generate_series(1,10,5) j +-- +TABLE: name="spgist_unlogged_tbl" schema="" table="spgist_unlogged_tbl" ctx=DML +FUNCTION: name="box" function="box" schema="" ctx=Call +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO spgist_unlogged_tbl (...) SELECT ... FROM generate_series(1, 100, 5) i, generate_seri..." diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json new file mode 100644 index 0000000..78efa1d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json @@ -0,0 +1,223 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson.test b/parser/testdata/summary_truncate/postgres_regress/sqljson.test new file mode 100644 index 0000000..388cf9d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson.test @@ -0,0 +1,1596 @@ +== 001 +-- truncate_limit: 100 +-- JSON() +SELECT JSON() +-- +ERROR: syntax error at or near ")" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +SELECT JSON(NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON(NULL )" +== 003 +-- truncate_limit: 100 +SELECT JSON('{ "a" : 1 } ') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON('{ \"a\" : 1 } ' )" +== 004 +-- truncate_limit: 100 +SELECT JSON('{ "a" : 1 } ' FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON('{ \"a\" : 1 } ' FORMAT JSON )" +== 005 +-- truncate_limit: 100 +SELECT JSON('{ "a" : 1 } ' FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON('{ \"a\" : 1 } ' FORMAT JSON ENCODING utf8 )" +== 006 +-- truncate_limit: 100 +SELECT JSON('{ "a" : 1 } '::bytea FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON('{ \"a\" : 1 } '::bytea FORMAT JSON ENCODING utf8 )" +== 007 +-- truncate_limit: 100 +SELECT pg_typeof(JSON('{ "a" : 1 } ')) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(JSON('{ \"a\" : 1 } ' ))" +== 008 +-- truncate_limit: 100 +SELECT JSON(' 1 '::json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON(' 1 '::pg_catalog.json )" +== 009 +-- truncate_limit: 100 +SELECT JSON(' 1 '::jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON(' 1 '::jsonb )" +== 010 +-- truncate_limit: 100 +SELECT JSON(' 1 '::json WITH UNIQUE KEYS) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON(' 1 '::pg_catalog.json WITH UNIQUE KEYS)" +== 011 +-- truncate_limit: 100 +SELECT JSON(123) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON(123 )" +== 012 +-- truncate_limit: 100 +SELECT JSON('{"a": 1, "a": 2}') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON('{\"a\": 1, \"a\": 2}' )" +== 013 +-- truncate_limit: 100 +SELECT JSON('{"a": 1, "a": 2}' WITH UNIQUE KEYS) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON('{\"a\": 1, \"a\": 2}' WITH UNIQUE KEYS)" +== 014 +-- truncate_limit: 100 +SELECT JSON('{"a": 1, "a": 2}' WITHOUT UNIQUE KEYS) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON('{\"a\": 1, \"a\": 2}' )" +== 015 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123') +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' )" +== 016 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' FORMAT JSON) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' FORMAT JSON )" +== 017 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123'::bytea FORMAT JSON) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123'::bytea FORMAT JSON )" +== 018 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123'::bytea FORMAT JSON ENCODING UTF8) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123'::bytea FORMAT JSON ENCODING utf8 )" +== 019 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITH UNIQUE KEYS) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITH UNIQUE KEYS)" +== 020 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITHOUT UNIQUE KEYS) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' )" +== 021 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123') +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' )" +== 022 +-- truncate_limit: 100 +SELECT pg_typeof(JSON('123')) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(JSON('123' ))" +== 023 +-- truncate_limit: 100 +-- JSON_SCALAR() +SELECT JSON_SCALAR() +-- +ERROR: syntax error at or near ")" +CURSORPOS: 37 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 024 +-- truncate_limit: 100 +SELECT JSON_SCALAR(NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR(NULL)" +== 025 +-- truncate_limit: 100 +SELECT JSON_SCALAR(NULL::int) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR(NULL::int)" +== 026 +-- truncate_limit: 100 +SELECT JSON_SCALAR(123) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR(123)" +== 027 +-- truncate_limit: 100 +SELECT JSON_SCALAR(123.45) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR(123.45)" +== 028 +-- truncate_limit: 100 +SELECT JSON_SCALAR(123.45::numeric) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR((123.45)::numeric)" +== 029 +-- truncate_limit: 100 +SELECT JSON_SCALAR(true) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR(true)" +== 030 +-- truncate_limit: 100 +SELECT JSON_SCALAR(false) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR(false)" +== 031 +-- truncate_limit: 100 +SELECT JSON_SCALAR(' 123.45') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR(' 123.45')" +== 032 +-- truncate_limit: 100 +SELECT JSON_SCALAR('2020-06-07'::date) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR('2020-06-07'::date)" +== 033 +-- truncate_limit: 100 +SELECT JSON_SCALAR('2020-06-07 01:02:03'::timestamp) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR('2020-06-07 01:02:03'::timestamp)" +== 034 +-- truncate_limit: 100 +SELECT JSON_SCALAR('{}'::json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR('{}'::pg_catalog.json)" +== 035 +-- truncate_limit: 100 +SELECT JSON_SCALAR('{}'::jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SCALAR('{}'::jsonb)" +== 036 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123)" +== 037 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR('123') +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR('123')" +== 038 +-- truncate_limit: 100 +-- JSON_SERIALIZE() +SELECT JSON_SERIALIZE() +-- +ERROR: syntax error at or near ")" +CURSORPOS: 43 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE(NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE(NULL )" +== 040 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE(JSON('{ "a" : 1 } ')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE(JSON('{ \"a\" : 1 } ' ) )" +== 041 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE('{ "a" : 1 } ') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('{ \"a\" : 1 } ' )" +== 042 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE('1') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('1' )" +== 043 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE('1' FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('1' FORMAT JSON )" +== 044 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING bytea) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('{ \"a\" : 1 } ' RETURNING bytea )" +== 045 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('{ \"a\" : 1 } ' RETURNING varchar )" +== 046 +-- truncate_limit: 100 +SELECT pg_typeof(JSON_SERIALIZE(NULL)) +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_typeof(JSON_SERIALIZE(NULL ))" +== 047 +-- truncate_limit: 100 +-- only string types or bytea allowed +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('{ \"a\" : 1 } ' RETURNING jsonb )" +== 048 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}') +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}' )" +== 049 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}' RETURNING bytea) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}' RETURNING bytea )" +== 050 +-- truncate_limit: 100 +-- JSON_OBJECT() +SELECT JSON_OBJECT() +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT()" +== 051 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING pg_catalog.json)" +== 052 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING json FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING pg_catalog.json FORMAT JSON)" +== 053 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING jsonb)" +== 054 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING jsonb FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING jsonb FORMAT JSON)" +== 055 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING text)" +== 056 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING text FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING text FORMAT JSON)" +== 057 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING text FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING text FORMAT JSON ENCODING utf8)" +== 058 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING text FORMAT JSON ENCODING INVALID_ENCODING) +-- +ERROR: unrecognized JSON encoding: invalid_encoding +FILENAME: gram.y +FUNCNAME: base_yyparse +== 059 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING bytea) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING bytea)" +== 060 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING bytea FORMAT JSON)" +== 061 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING bytea FORMAT JSON ENCODING utf8)" +== 062 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF16) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING bytea FORMAT JSON ENCODING utf16)" +== 063 +-- truncate_limit: 100 +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF32) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT( RETURNING bytea FORMAT JSON ENCODING utf32)" +== 064 +-- truncate_limit: 100 +SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON)" +== 065 +-- truncate_limit: 100 +SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON ENCODING utf8)" +== 066 +-- truncate_limit: 100 +SELECT JSON_OBJECT('foo': NULL::json FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('foo': NULL::pg_catalog.json FORMAT JSON)" +== 067 +-- truncate_limit: 100 +SELECT JSON_OBJECT('foo': NULL::json FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('foo': NULL::pg_catalog.json FORMAT JSON ENCODING utf8)" +== 068 +-- truncate_limit: 100 +SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON)" +== 069 +-- truncate_limit: 100 +SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON ENCODING utf8)" +== 070 +-- truncate_limit: 100 +SELECT JSON_OBJECT(NULL: 1) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(NULL: 1)" +== 071 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': 2 + 3) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': 2 + 3)" +== 072 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a' VALUE 2 + 3) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': 2 + 3)" +== 073 +-- truncate_limit: 100 +--SELECT JSON_OBJECT(KEY 'a' VALUE 2 + 3); +SELECT JSON_OBJECT('a' || 2: 1) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a' || 2: 1)" +== 074 +-- truncate_limit: 100 +SELECT JSON_OBJECT(('a' || 2) VALUE 1) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a' || 2: 1)" +== 075 +-- truncate_limit: 100 +--SELECT JSON_OBJECT('a' || 2 VALUE 1); +--SELECT JSON_OBJECT(KEY 'a' || 2 VALUE 1); +SELECT JSON_OBJECT('a': 2::text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': 2::text)" +== 076 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a' VALUE 2::text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': 2::text)" +== 077 +-- truncate_limit: 100 +--SELECT JSON_OBJECT(KEY 'a' VALUE 2::text); +SELECT JSON_OBJECT(1::text: 2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1::text: 2)" +== 078 +-- truncate_limit: 100 +SELECT JSON_OBJECT((1::text) VALUE 2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1::text: 2)" +== 079 +-- truncate_limit: 100 +--SELECT JSON_OBJECT(1::text VALUE 2); +--SELECT JSON_OBJECT(KEY 1::text VALUE 2); +SELECT JSON_OBJECT(json '[1]': 123) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('[1]'::pg_catalog.json: 123)" +== 080 +-- truncate_limit: 100 +SELECT JSON_OBJECT(ARRAY[1,2,3]: 'aaa') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(ARRAY[1, 2, 3]: 'aaa')" +== 081 +-- truncate_limit: 100 +SELECT JSON_OBJECT( + 'a': '123', + 1.23: 123, + 'c': json '[ 1,true,{ } ]', + 'd': jsonb '{ "x" : 123.45 }' +) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 082 +-- truncate_limit: 100 +SELECT JSON_OBJECT( + 'a': '123', + 1.23: 123, + 'c': json '[ 1,true,{ } ]', + 'd': jsonb '{ "x" : 123.45 }' + RETURNING jsonb +) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 083 +-- truncate_limit: 100 +/* +SELECT JSON_OBJECT( + 'a': '123', + KEY 1.23 VALUE 123, + 'c' VALUE json '[1, true, {}]' +); +*/ + +SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa'))" +== 084 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa' RETURNING jsonb)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa' RETURNING jsonb))" +== 085 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text))" +== 086 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text) FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text) FORMAT JSON)" +== 087 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea))" +== 088 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea) FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea) FORMAT JSON)" +== 089 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2)" +== 090 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2 NULL ON NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2)" +== 091 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2 ABSENT ON NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2 ABSENT ON NULL)" +== 092 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, repeat('x', 1000): 1, 2: repeat('a', 100) WITH UNIQUE) +-- +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, repeat('x', 1000): 1, 2: repeat('a', 100) WITH UNIQUE)" +== 093 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '1': NULL WITH UNIQUE) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '1': NULL WITH UNIQUE)" +== 094 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE)" +== 095 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '1': NULL NULL ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '1': NULL WITH UNIQUE RETURNING jsonb)" +== 096 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE RETURNING jsonb)" +== 097 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 NULL ON NULL WITH UNIQUE) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 WITH UNIQUE)" +== 098 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE)" +== 099 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITHOUT UNIQUE) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL)" +== 100 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE RETURNING jsonb)" +== 101 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITHOUT UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL RETURNING jsonb)" +== 102 +-- truncate_limit: 100 +SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, 4: NULL, '5': 'a' ABSENT ON NULL WITH UNIQUE RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 103 +-- truncate_limit: 100 +-- BUG: https://postgr.es/m/CADXhmgTJtJZK9A3Na_ry%2BXrq-ghjcejBRhcRMzWZvbd__QdgJA%40mail.gmail.com +-- datum_to_jsonb_internal() didn't catch keys that are casts instead of a simple scalar +CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral')" +== 104 +-- truncate_limit: 100 +CREATE FUNCTION mood_to_json(mood) RETURNS json AS $$ + SELECT to_json($1::text); +$$ LANGUAGE sql IMMUTABLE +-- +FUNCTION: name="mood_to_json" function="mood_to_json" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mood_to_json(mood) RETURNS pg_catalog.json AS $$\n SELECT to_json($1::text);\n$$ L..." +== 105 +-- truncate_limit: 100 +CREATE CAST (mood AS json) WITH FUNCTION mood_to_json(mood) AS IMPLICIT +-- +STMT: CreateCastStmt +TRUNCATED: "CREATE CAST (mood AS pg_catalog.json) WITH FUNCTION mood_to_json(mood) AS IMPLICIT" +== 106 +-- truncate_limit: 100 +SELECT JSON_OBJECT('happy'::mood: '123'::jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('happy'::mood: '123'::jsonb)" +== 107 +-- truncate_limit: 100 +DROP CAST (mood AS json) +-- +STMT: DropStmt +TRUNCATED: "DROP CAST (mood AS pg_catalog.json)" +== 108 +-- truncate_limit: 100 +DROP FUNCTION mood_to_json +-- +FUNCTION: name="mood_to_json" function="mood_to_json" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION mood_to_json" +== 109 +-- truncate_limit: 100 +DROP TYPE mood +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE mood" +== 110 +-- truncate_limit: 100 +-- JSON_ARRAY() +SELECT JSON_ARRAY() +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY()" +== 111 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING pg_catalog.json)" +== 112 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING json FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING pg_catalog.json FORMAT JSON)" +== 113 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING jsonb)" +== 114 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING jsonb FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING jsonb FORMAT JSON)" +== 115 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING text)" +== 116 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING text FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING text FORMAT JSON)" +== 117 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING text FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING text FORMAT JSON ENCODING utf8)" +== 118 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING text FORMAT JSON ENCODING INVALID_ENCODING) +-- +ERROR: unrecognized JSON encoding: invalid_encoding +FILENAME: gram.y +FUNCNAME: base_yyparse +== 119 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING bytea) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING bytea)" +== 120 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING bytea FORMAT JSON)" +== 121 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF8) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING bytea FORMAT JSON ENCODING utf8)" +== 122 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF16) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING bytea FORMAT JSON ENCODING utf16)" +== 123 +-- truncate_limit: 100 +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF32) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY( RETURNING bytea FORMAT JSON ENCODING utf32)" +== 124 +-- truncate_limit: 100 +SELECT JSON_ARRAY('aaa', 111, true, array[1,2,3], NULL, json '{"a": [1]}', jsonb '["a",3]') +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 125 +-- truncate_limit: 100 +SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL)" +== 126 +-- truncate_limit: 100 +SELECT JSON_ARRAY('a', NULL, 'b' ABSENT ON NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY('a', NULL, 'b')" +== 127 +-- truncate_limit: 100 +SELECT JSON_ARRAY(NULL, NULL, 'b' ABSENT ON NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(NULL, NULL, 'b')" +== 128 +-- truncate_limit: 100 +SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL RETURNING jsonb)" +== 129 +-- truncate_limit: 100 +SELECT JSON_ARRAY('a', NULL, 'b' ABSENT ON NULL RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY('a', NULL, 'b' RETURNING jsonb)" +== 130 +-- truncate_limit: 100 +SELECT JSON_ARRAY(NULL, NULL, 'b' ABSENT ON NULL RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(NULL, NULL, 'b' RETURNING jsonb)" +== 131 +-- truncate_limit: 100 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' RETURNING text)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(JSON_ARRAY('{ \"a\" : 123 }' RETURNING text))" +== 132 +-- truncate_limit: 100 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' FORMAT JSON RETURNING text)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(JSON_ARRAY('{ \"a\" : 123 }' FORMAT JSON RETURNING text))" +== 133 +-- truncate_limit: 100 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' FORMAT JSON RETURNING text) FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(JSON_ARRAY('{ \"a\" : 123 }' FORMAT JSON RETURNING text) FORMAT JSON)" +== 134 +-- truncate_limit: 100 +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i))" +== 135 +-- truncate_limit: 100 +SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(SELECT i FROM (VALUES (...)) foo(i))" +== 136 +-- truncate_limit: 100 +SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i) RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(SELECT i FROM (VALUES (...)) foo(i) RETURNING jsonb)" +== 137 +-- truncate_limit: 100 +--SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i) NULL ON NULL); +--SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i) NULL ON NULL RETURNING jsonb); +SELECT JSON_ARRAY(SELECT i FROM (VALUES (3), (1), (NULL), (2)) foo(i) ORDER BY i) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(SELECT i FROM (VALUES (3), (1), (NULL), (2)) foo(i) ORDER BY i)" +== 138 +-- truncate_limit: 100 +SELECT JSON_ARRAY(WITH x AS (SELECT 1) VALUES (TRUE)) +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(WITH x AS (SELECT 1) VALUES (true))" +== 139 +-- truncate_limit: 100 +-- Should fail +SELECT JSON_ARRAY(SELECT FROM (VALUES (1)) foo(i)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(SELECT FROM (VALUES (1)) foo(i))" +== 140 +-- truncate_limit: 100 +SELECT JSON_ARRAY(SELECT i, i FROM (VALUES (1)) foo(i)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(SELECT i, i FROM (VALUES (1)) foo(i))" +== 141 +-- truncate_limit: 100 +SELECT JSON_ARRAY(SELECT * FROM (VALUES (1, 2)) foo(i, j)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(SELECT * FROM (VALUES (1, 2)) foo(i, j))" +== 142 +-- truncate_limit: 100 +-- JSON_ARRAYAGG() +SELECT JSON_ARRAYAGG(i) IS NULL, + JSON_ARRAYAGG(i RETURNING jsonb) IS NULL +FROM generate_series(1, 0) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 0) i" +== 143 +-- truncate_limit: 100 +SELECT JSON_ARRAYAGG(i), + JSON_ARRAYAGG(i RETURNING jsonb) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAYAGG(i), JSON_ARRAYAGG(i RETURNING jsonb) FROM generate_series(1, 5) i" +== 144 +-- truncate_limit: 100 +SELECT JSON_ARRAYAGG(i ORDER BY i DESC) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAYAGG(i ORDER BY i DESC) FROM generate_series(1, 5) i" +== 145 +-- truncate_limit: 100 +SELECT JSON_ARRAYAGG(i::text::json) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAYAGG(i::text::pg_catalog.json) FROM generate_series(1, 5) i" +== 146 +-- truncate_limit: 100 +SELECT JSON_ARRAYAGG(JSON_ARRAY(i, i + 1 RETURNING text) FORMAT JSON) +FROM generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAYAGG(JSON_ARRAY(i, i + 1 RETURNING text) FORMAT JSON) FROM generate_series(1, 5) i" +== 147 +-- truncate_limit: 100 +SELECT JSON_ARRAYAGG(NULL), + JSON_ARRAYAGG(NULL RETURNING jsonb) +FROM generate_series(1, 5) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAYAGG(NULL), JSON_ARRAYAGG(NULL RETURNING jsonb) FROM generate_series(1, 5)" +== 148 +-- truncate_limit: 100 +SELECT JSON_ARRAYAGG(NULL NULL ON NULL), + JSON_ARRAYAGG(NULL NULL ON NULL RETURNING jsonb) +FROM generate_series(1, 5) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 5)" +== 149 +-- truncate_limit: 100 +SELECT + JSON_ARRAYAGG(bar) as no_options, + JSON_ARRAYAGG(bar RETURNING jsonb) as returning_jsonb, + JSON_ARRAYAGG(bar ABSENT ON NULL) as absent_on_null, + JSON_ARRAYAGG(bar ABSENT ON NULL RETURNING jsonb) as absentonnull_returning_jsonb, + JSON_ARRAYAGG(bar NULL ON NULL) as null_on_null, + JSON_ARRAYAGG(bar NULL ON NULL RETURNING jsonb) as nullonnull_returning_jsonb, + JSON_ARRAYAGG(foo) as row_no_options, + JSON_ARRAYAGG(foo RETURNING jsonb) as row_returning_jsonb, + JSON_ARRAYAGG(foo ORDER BY bar) FILTER (WHERE bar > 2) as row_filtered_agg, + JSON_ARRAYAGG(foo ORDER BY bar RETURNING jsonb) FILTER (WHERE bar > 2) as row_filtered_agg_returning_jsonb +FROM + (VALUES (NULL), (3), (1), (NULL), (NULL), (5), (2), (4), (NULL)) foo(bar) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) foo(bar)" +== 150 +-- truncate_limit: 100 +SELECT + bar, JSON_ARRAYAGG(bar) FILTER (WHERE bar > 2) OVER (PARTITION BY foo.bar % 2) +FROM + (VALUES (NULL), (3), (1), (NULL), (NULL), (5), (2), (4), (NULL), (5), (4)) foo(bar) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) foo(bar)" +== 151 +-- truncate_limit: 100 +-- JSON_OBJECTAGG() +SELECT JSON_OBJECTAGG('key': 1) IS NULL, + JSON_OBJECTAGG('key': 1 RETURNING jsonb) IS NULL +WHERE FALSE +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... WHERE false" +== 152 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(NULL: 1) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(NULL: 1)" +== 153 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(NULL: 1 RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(NULL: 1 RETURNING jsonb)" +== 154 +-- truncate_limit: 100 +SELECT + JSON_OBJECTAGG(i: i), +-- JSON_OBJECTAGG(i VALUE i), +-- JSON_OBJECTAGG(KEY i VALUE i), + JSON_OBJECTAGG(i: i RETURNING jsonb) +FROM + generate_series(1, 5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(i: i), JSON_OBJECTAGG(i: i RETURNING jsonb) FROM generate_series(1, 5) i" +== 155 +-- truncate_limit: 100 +SELECT + JSON_OBJECTAGG(k: v), + JSON_OBJECTAGG(k: v NULL ON NULL), + JSON_OBJECTAGG(k: v ABSENT ON NULL), + JSON_OBJECTAGG(k: v RETURNING jsonb), + JSON_OBJECTAGG(k: v NULL ON NULL RETURNING jsonb), + JSON_OBJECTAGG(k: v ABSENT ON NULL RETURNING jsonb) +FROM + (VALUES (1, 1), (1, NULL), (2, NULL), (3, 3)) foo(k, v) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) foo(k, v)" +== 156 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(k: v WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(k: v WITH UNIQUE) FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v)" +== 157 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE) FROM (VALUES (...)) foo(k, v)" +== 158 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (0, NULL), (3, NULL), (2, 2), (4, NULL)) foo(k, v) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE) FROM (VALUES (...)) foo(k, v)" +== 159 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(k: v WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(k: v WITH UNIQUE RETURNING jsonb) FROM (VALUES (...)) foo(k, v)" +== 160 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE RETURNING jsonb) FROM (VALUES (...)) foo(k, v)" +== 161 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (0, NULL),(4, null), (5, null),(6, null),(2, 2)) foo(k, v) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE RETURNING jsonb) FROM (VALUES (...)) foo(k, v)" +== 162 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(mod(i,100): (i)::text FORMAT JSON WITH UNIQUE) +FROM generate_series(0, 199) i +-- +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECTAGG(mod(i, 100): i::text FORMAT JSON WITH UNIQUE) FROM generate_series(0, 199) i" +== 163 +-- truncate_limit: 100 +-- Test JSON_OBJECT deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('foo': '1' FORMAT JSON, 'bar': 'baz' RETURNING pg..." +== 164 +-- truncate_limit: 100 +CREATE VIEW json_object_view AS +SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json) +-- +TABLE: name="json_object_view" schema="" table="json_object_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_object_view AS SELECT JSON_OBJECT('foo': '1' FORMAT JSON, 'bar': 'baz' RETURNING..." +== 165 +-- truncate_limit: 100 +DROP VIEW json_object_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW json_object_view" +== 166 +-- truncate_limit: 100 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v WITH UNIQUE KEYS) OVER (ORDER BY k) +FROM (VALUES (1,1), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) a(k, v)" +== 167 +-- truncate_limit: 100 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v WITH UNIQUE KEYS) OVER (ORDER BY k) +FROM (VALUES (1,1), (1,2), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) a(k, v)" +== 168 +-- truncate_limit: 100 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL WITH UNIQUE KEYS) + OVER (ORDER BY k) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) a(k, v)" +== 169 +-- truncate_limit: 100 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL) +OVER (ORDER BY k) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) a(k, v)" +== 170 +-- truncate_limit: 100 +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL) +OVER (ORDER BY k RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v) +-- +FUNCTION: name="to_json" function="to_json" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) a(k, v)" +== 171 +-- truncate_limit: 100 +-- Test JSON_ARRAY deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING json) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING pg_catalog.json)" +== 172 +-- truncate_limit: 100 +CREATE VIEW json_array_view AS +SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING json) +-- +TABLE: name="json_array_view" schema="" table="json_array_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_array_view AS SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING pg_catalog.json)" +== 173 +-- truncate_limit: 100 +DROP VIEW json_array_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW json_array_view" +== 174 +-- truncate_limit: 100 +-- Test JSON_OBJECTAGG deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE..." +== 175 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) OVER (PARTITION BY i % 2) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE..." +== 176 +-- truncate_limit: 100 +CREATE VIEW json_objectagg_view AS +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +TABLE: name="json_objectagg_view" schema="" table="json_objectagg_view" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_objectagg_view AS SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH ..." +== 177 +-- truncate_limit: 100 +DROP VIEW json_objectagg_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW json_objectagg_view" +== 178 +-- truncate_limit: 100 +-- Test JSON_ARRAYAGG deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RE..." +== 179 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) OVER (PARTITION BY i % 2) +FROM generate_series(1,5) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RE..." +== 180 +-- truncate_limit: 100 +CREATE VIEW json_arrayagg_view AS +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i +-- +TABLE: name="json_arrayagg_view" schema="" table="json_arrayagg_view" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_arrayagg_view AS SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NU..." +== 181 +-- truncate_limit: 100 +DROP VIEW json_arrayagg_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW json_arrayagg_view" +== 182 +-- truncate_limit: 100 +-- Test JSON_ARRAY(subquery) deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING jsonb) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i..." +== 183 +-- truncate_limit: 100 +CREATE VIEW json_array_subquery_view AS +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING jsonb) +-- +TABLE: name="json_array_subquery_view" schema="" table="json_array_subquery_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_array_subquery_view AS SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL),..." +== 184 +-- truncate_limit: 100 +DROP VIEW json_array_subquery_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW json_array_subquery_view" +== 185 +-- truncate_limit: 100 +-- IS JSON predicate +SELECT NULL IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL IS JSON" +== 186 +-- truncate_limit: 100 +SELECT NULL IS NOT JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT NOT NULL IS JSON" +== 187 +-- truncate_limit: 100 +SELECT NULL::json IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::pg_catalog.json IS JSON" +== 188 +-- truncate_limit: 100 +SELECT NULL::jsonb IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::jsonb IS JSON" +== 189 +-- truncate_limit: 100 +SELECT NULL::text IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::text IS JSON" +== 190 +-- truncate_limit: 100 +SELECT NULL::bytea IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::bytea IS JSON" +== 191 +-- truncate_limit: 100 +SELECT NULL::int IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT NULL::int IS JSON" +== 192 +-- truncate_limit: 100 +SELECT '' IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT '' IS JSON" +== 193 +-- truncate_limit: 100 +SELECT bytea '\x00' IS JSON +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'\\\\x00'::bytea IS JSON" +== 194 +-- truncate_limit: 100 +CREATE TABLE test_is_json (js text) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_is_json (js text)" +== 195 +-- truncate_limit: 100 +INSERT INTO test_is_json VALUES + (NULL), + (''), + ('123'), + ('"aaa "'), + ('true'), + ('null'), + ('[]'), + ('[1, "2", {}]'), + ('{}'), + ('{ "a": 1, "b": null }'), + ('{ "a": 1, "a": null }'), + ('{ "a": 1, "b": [{ "a": 1 }, { "a": 2 }] }'), + ('{ "a": 1, "b": [{ "a": 1, "b": 0, "a": 2 }] }'), + ('aaa'), + ('{a:1}'), + ('["a",]') +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_is_json VALUES (...)" +== 196 +-- truncate_limit: 100 +SELECT + js, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + test_is_json +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_is_json" +== 197 +-- truncate_limit: 100 +SELECT + js, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + (SELECT js::json FROM test_is_json WHERE js IS JSON) foo(js) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +FILTER: schema="" table="" column="js" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM test_is_json WHERE ...) foo(js)" +== 198 +-- truncate_limit: 100 +SELECT + js0, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + (SELECT js, js::bytea FROM test_is_json WHERE js IS JSON) foo(js0, js) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +FILTER: schema="" table="" column="js" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM test_is_json WHERE ...) foo(js0, js)" +== 199 +-- truncate_limit: 100 +SELECT + js, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON WITH UNIQUE KEYS "WITH UNIQUE" +FROM + (SELECT js::jsonb FROM test_is_json WHERE js IS JSON) foo(js) +-- +TABLE: name="test_is_json" schema="" table="test_is_json" ctx=Select +FILTER: schema="" table="" column="js" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM test_is_json WHERE ...) foo(js)" +== 200 +-- truncate_limit: 100 +-- Test IS JSON deparsing +EXPLAIN (VERBOSE, COSTS OFF) +SELECT '1' IS JSON AS "any", ('1' || i) IS JSON SCALAR AS "scalar", '[]' IS NOT JSON ARRAY AS "array", '{}' IS JSON OBJECT WITH UNIQUE AS "object" FROM generate_series(1, 3) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT '1' IS JSON AS \"any\", '1' || i IS JSON SCALAR AS scalar, NOT ..." +== 201 +-- truncate_limit: 100 +CREATE VIEW is_json_view AS +SELECT '1' IS JSON AS "any", ('1' || i) IS JSON SCALAR AS "scalar", '[]' IS NOT JSON ARRAY AS "array", '{}' IS JSON OBJECT WITH UNIQUE AS "object" FROM generate_series(1, 3) i +-- +TABLE: name="is_json_view" schema="" table="is_json_view" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW is_json_view AS SELECT '1' IS JSON AS \"any\", '1' || i IS JSON SCALAR AS scalar, NOT '..." +== 202 +-- truncate_limit: 100 +DROP VIEW is_json_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW is_json_view" +== 203 +-- truncate_limit: 100 +-- Test implicit coercion to a fixed-length type specified in RETURNING +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar(2)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('{ \"a\" : 1 } ' RETURNING varchar(2) )" +== 204 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING varchar(2))) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING varchar(2)))" +== 205 +-- truncate_limit: 100 +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' RETURNING varchar(2))) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_ARRAY(JSON_ARRAY('{ \"a\" : 123 }' RETURNING varchar(2)))" +== 206 +-- truncate_limit: 100 +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING varchar(2)) FROM generate_series(1,1) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 1) i" +== 207 +-- truncate_limit: 100 +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING varchar(2)) FROM generate_series(1, 1) i +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 1) i" +== 208 +-- truncate_limit: 100 +-- Now try domain over fixed-length type +CREATE DOMAIN sqljson_char2 AS char(2) CHECK (VALUE NOT IN ('12')) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN sqljson_char2 AS char(2) CHECK (value NOT IN ('12'))" +== 209 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE('123' RETURNING sqljson_char2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('123' RETURNING sqljson_char2 )" +== 210 +-- truncate_limit: 100 +SELECT JSON_SERIALIZE('12' RETURNING sqljson_char2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_SERIALIZE('12' RETURNING sqljson_char2 )" +== 211 +-- truncate_limit: 100 +-- Bug #18657: JsonValueExpr.raw_expr was not initialized in ExecInitExprRec() +-- causing the Aggrefs contained in it to also not be initialized, which led +-- to a crash in ExecBuildAggTrans() as mentioned in the bug report: +-- https://postgr.es/m/18657-1b90ccce2b16bdb8@postgresql.org +CREATE FUNCTION volatile_one() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql VOLATILE +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION volatile_one() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql VOLATILE" +== 212 +-- truncate_limit: 100 +CREATE FUNCTION stable_one() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql STABLE +-- +FUNCTION: name="stable_one" function="stable_one" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION stable_one() RETURNS int AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql STABLE" +== 213 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': volatile_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': volatile_one() RETURNING..." +== 214 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': volatile_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': volatile_one() RETURNING text) FORMAT JSON)" +== 215 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': stable_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="stable_one" function="stable_one" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': stable_one() RETURNING t..." +== 216 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': stable_one() RETURNING text) FORMAT JSON) +-- +FUNCTION: name="stable_one" function="stable_one" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': stable_one() RETURNING text) FORMAT JSON)" +== 217 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT..." +== 218 +-- truncate_limit: 100 +SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON)" +== 219 +-- truncate_limit: 100 +DROP FUNCTION volatile_one, stable_one +-- +FUNCTION: name="volatile_one" function="volatile_one" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION volatile_one, stable_one" diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json new file mode 100644 index 0000000..17a73dc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json @@ -0,0 +1,121 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.test b/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.test new file mode 100644 index 0000000..003d2d2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.test @@ -0,0 +1,1143 @@ +== 001 +-- truncate_limit: 100 +-- JSON_TABLE + +-- Should fail (JSON_TABLE can be used only in FROM clause) +SELECT JSON_TABLE('[]', '$') +-- +ERROR: syntax error at or near "(" +CURSORPOS: 93 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +-- Only allow EMPTY and ERROR for ON ERROR +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]' , 'strict $.a' COLUMNS (js2 int PATH '$')DEFAULT 1 ON ERROR)" +== 003 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') NULL ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]' , 'strict $.a' COLUMNS (js2 int PATH '$')NULL ON ERROR)" +== 004 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') EMPTY ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]' , 'strict $.a' COLUMNS (js2 int PATH '$')EMPTY ARRAY ON ERROR)" +== 005 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]' , 'strict $.a' COLUMNS (js2 int PATH '$')ERROR ON ERROR)" +== 006 +-- truncate_limit: 100 +-- Column and path names must be distinct +SELECT * FROM JSON_TABLE(jsonb'"1.23"', '$.a' as js2 COLUMNS (js2 int path '$')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"1.23\"'::jsonb , '$.a' AS js2 COLUMNS (js2 int PATH '$'))" +== 007 +-- truncate_limit: 100 +-- Should fail (no columns) +SELECT * FROM JSON_TABLE(NULL, '$' COLUMNS ()) +-- +ERROR: syntax error at or near ")" +CURSORPOS: 73 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE (NULL::jsonb, '$' COLUMNS (v1 timestamp)) AS f (v1, v2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE(NULL::jsonb , '$' COLUMNS (v1 timestamp )) f(v1, v2)" +== 009 +-- truncate_limit: 100 +--duplicated column name +SELECT * FROM JSON_TABLE(jsonb'"1.23"', '$.a' COLUMNS (js2 int path '$', js2 int path '$')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"1.23\"'::jsonb , '$.a' COLUMNS (js2 int PATH '$', js2 int PATH '$'))" +== 010 +-- truncate_limit: 100 +--return composite data type. +create type comp as (a int, b int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE comp AS (a int, b int)" +== 011 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '{"rec": "(1,2)"}', '$' COLUMNS (id FOR ORDINALITY, comp comp path '$.rec' omit quotes)) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('{\"rec\": \"(1,2)\"}'::jsonb , '$' COLUMNS (id FOR ORDINALITY, comp comp P..." +== 012 +-- truncate_limit: 100 +drop type comp +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE comp" +== 013 +-- truncate_limit: 100 +-- NULL => empty table +SELECT * FROM JSON_TABLE(NULL::jsonb, '$' COLUMNS (foo int)) bar +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE(NULL::jsonb , '$' COLUMNS (foo int )) bar" +== 014 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb'"1.23"', 'strict $.a' COLUMNS (js2 int PATH '$')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"1.23\"'::jsonb , 'strict $.a' COLUMNS (js2 int PATH '$'))" +== 015 +-- truncate_limit: 100 +|-- +SELECT * FROM JSON_TABLE(jsonb '123', '$' + COLUMNS (item int PATH '$', foo int)) bar +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('123'::jsonb , '$' COLUMNS (item int PATH '$', foo int )) bar" +== 016 +-- truncate_limit: 100 +-- JSON_TABLE: basic functionality +CREATE DOMAIN jsonb_test_domain AS text CHECK (value <> 'foo') +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN jsonb_test_domain AS text CHECK (value <> 'foo')" +== 017 +-- truncate_limit: 100 +CREATE TEMP TABLE json_table_test (js) AS + (VALUES + ('1'), + ('[]'), + ('{}'), + ('[1, 1.23, "2", "aaaaaaa", "foo", null, false, true, {"aaa": 123}, "[1,2]", "\"str\""]') + ) +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE json_table_test(js) AS VALUES ('1'), ('[]'), ('{}'), (E'[1, 1.23, \"2\", \"aa..." +== 018 +-- truncate_limit: 100 +-- Regular "unformatted" columns +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$', + "char(4)" char(4) PATH '$', + "bool" bool PATH '$', + "numeric" numeric PATH '$', + "domain" jsonb_test_domain PATH '$', + js json PATH '$', + jb jsonb PATH '$' + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_table_test vals LEFT JOIN JSON_TABLE(vals.js::jsonb , 'lax $[*]' COLUMNS (id ..." +== 019 +-- truncate_limit: 100 +-- "formatted" columns +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + jst text FORMAT JSON PATH '$', + jsc char(4) FORMAT JSON PATH '$', + jsv varchar(4) FORMAT JSON PATH '$', + jsb jsonb FORMAT JSON PATH '$', + jsbq jsonb FORMAT JSON PATH '$' OMIT QUOTES + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_table_test vals LEFT JOIN JSON_TABLE(vals.js::jsonb , 'lax $[*]' COLUMNS (id ..." +== 020 +-- truncate_limit: 100 +-- EXISTS columns +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + exists1 bool EXISTS PATH '$.aaa', + exists2 int EXISTS PATH '$.aaa', + exists3 int EXISTS PATH 'strict $.aaa' UNKNOWN ON ERROR, + exists4 text EXISTS PATH 'strict $.aaa' FALSE ON ERROR + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_table_test vals LEFT JOIN JSON_TABLE(vals.js::jsonb , 'lax $[*]' COLUMNS (id ..." +== 021 +-- truncate_limit: 100 +-- Other miscellaneous checks +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + aaa int, -- "aaa" has implicit path '$."aaa"' + aaa1 int PATH '$.aaa', + js2 json PATH '$', + jsb2w jsonb PATH '$' WITH WRAPPER, + jsb2q jsonb PATH '$' OMIT QUOTES, + ia int[] PATH '$', + ta text[] PATH '$', + jba jsonb[] PATH '$' + ) + ) jt + ON true +-- +TABLE: name="json_table_test" schema="" table="json_table_test" ctx=Select +ALIAS: "vals"="json_table_test" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_table_test vals LEFT JOIN JSON_TABLE(vals.js::jsonb , 'lax $[*]' COLUMNS (id ..." +== 022 +-- truncate_limit: 100 +-- Test using casts in DEFAULT .. ON ERROR expression +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT '"foo1"'::jsonb::text ON EMPTY)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('{\"d1\": \"H\"}'::jsonb , '$' COLUMNS (js1 jsonb_test_domain PATH '$.a2' DE..." +== 023 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo'::jsonb_test_domain ON EMPTY)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('{\"d1\": \"H\"}'::jsonb , '$' COLUMNS (js1 jsonb_test_domain PATH '$.a2' DE..." +== 024 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo1'::jsonb_test_domain ON EMPTY)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('{\"d1\": \"H\"}'::jsonb , '$' COLUMNS (js1 jsonb_test_domain PATH '$.a2' DE..." +== 025 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.d1' DEFAULT 'foo2'::jsonb_test_domain ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('{\"d1\": \"foo\"}'::jsonb , '$' COLUMNS (js1 jsonb_test_domain PATH '$.d1' ..." +== 026 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' + COLUMNS (js1 oid[] PATH '$.d2' DEFAULT '{1}'::int[]::oid[] ON EMPTY)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('{\"d1\": \"foo\"}'::jsonb , '$' COLUMNS (js1 oid[] PATH '$.d2' DEFAULT '{1}..." +== 027 +-- truncate_limit: 100 +-- JSON_TABLE: Test backward parsing + +CREATE VIEW jsonb_table_view2 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + "int" int PATH '$', + "text" text PATH '$', + "char(4)" char(4) PATH '$', + "bool" bool PATH '$', + "numeric" numeric PATH '$', + "domain" jsonb_test_domain PATH '$')) +-- +TABLE: name="jsonb_table_view2" schema="" table="jsonb_table_view2" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW jsonb_table_view2 AS SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' PASSING 1 + ..." +== 028 +-- truncate_limit: 100 +CREATE VIEW jsonb_table_view3 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + js json PATH '$', + jb jsonb PATH '$', + jst text FORMAT JSON PATH '$', + jsc char(4) FORMAT JSON PATH '$', + jsv varchar(4) FORMAT JSON PATH '$')) +-- +TABLE: name="jsonb_table_view3" schema="" table="jsonb_table_view3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW jsonb_table_view3 AS SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' PASSING 1 + ..." +== 029 +-- truncate_limit: 100 +CREATE VIEW jsonb_table_view4 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + jsb jsonb FORMAT JSON PATH '$', + jsbq jsonb FORMAT JSON PATH '$' OMIT QUOTES, + aaa int, -- implicit path '$."aaa"', + aaa1 int PATH '$.aaa')) +-- +TABLE: name="jsonb_table_view4" schema="" table="jsonb_table_view4" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW jsonb_table_view4 AS SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' PASSING 1 + ..." +== 030 +-- truncate_limit: 100 +CREATE VIEW jsonb_table_view5 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + exists1 bool EXISTS PATH '$.aaa', + exists2 int EXISTS PATH '$.aaa' TRUE ON ERROR, + exists3 text EXISTS PATH 'strict $.aaa' UNKNOWN ON ERROR)) +-- +TABLE: name="jsonb_table_view5" schema="" table="jsonb_table_view5" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW jsonb_table_view5 AS SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' PASSING 1 + ..." +== 031 +-- truncate_limit: 100 +CREATE VIEW jsonb_table_view6 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + js2 json PATH '$', + jsb2w jsonb PATH '$' WITH WRAPPER, + jsb2q jsonb PATH '$' OMIT QUOTES, + ia int[] PATH '$', + ta text[] PATH '$', + jba jsonb[] PATH '$')) +-- +TABLE: name="jsonb_table_view6" schema="" table="jsonb_table_view6" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW jsonb_table_view6 AS SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' PASSING 1 + ..." +== 032 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view2 +-- +TABLE: name="jsonb_table_view2" schema="" table="jsonb_table_view2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view2" +== 033 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view3 +-- +TABLE: name="jsonb_table_view3" schema="" table="jsonb_table_view3" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view3" +== 034 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view4 +-- +TABLE: name="jsonb_table_view4" schema="" table="jsonb_table_view4" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view4" +== 035 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view5 +-- +TABLE: name="jsonb_table_view5" schema="" table="jsonb_table_view5" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view5" +== 036 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view6 +-- +TABLE: name="jsonb_table_view6" schema="" table="jsonb_table_view6" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM jsonb_table_view6" +== 037 +-- truncate_limit: 100 +-- JSON_TABLE() with alias +EXPLAIN (COSTS OFF, VERBOSE) +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$' + )) json_table_func +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' PASSING 1 + 2 A..." +== 038 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF, FORMAT JSON, VERBOSE) +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$' + )) json_table_func +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, FORMAT \"json\", VERBOSE) SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' P..." +== 039 +-- truncate_limit: 100 +DROP VIEW jsonb_table_view2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW jsonb_table_view2" +== 040 +-- truncate_limit: 100 +DROP VIEW jsonb_table_view3 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW jsonb_table_view3" +== 041 +-- truncate_limit: 100 +DROP VIEW jsonb_table_view4 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW jsonb_table_view4" +== 042 +-- truncate_limit: 100 +DROP VIEW jsonb_table_view5 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW jsonb_table_view5" +== 043 +-- truncate_limit: 100 +DROP VIEW jsonb_table_view6 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW jsonb_table_view6" +== 044 +-- truncate_limit: 100 +DROP DOMAIN jsonb_test_domain +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN jsonb_test_domain" +== 045 +-- truncate_limit: 100 +-- JSON_TABLE: only one FOR ORDINALITY columns allowed +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (id FOR ORDINALITY, id2 FOR ORDINALITY, a int PATH '$.a' ERROR ON EMPTY)) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (id FOR ORDINALITY, id2 FOR ORDINALITY, a int..." +== 046 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (id FOR ORDINALITY, a int PATH '$' ERROR ON EMPTY)) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (id FOR ORDINALITY, a int PATH '$' ERROR ON EM..." +== 047 +-- truncate_limit: 100 +-- JSON_TABLE: ON EMPTY/ON ERROR behavior +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js), + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$')) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) vals(js), JSON_TABLE(vals.js::jsonb , '$' COLUMNS (a int PATH '$')) jt" +== 048 +-- truncate_limit: 100 +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js) + LEFT OUTER JOIN + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$' ERROR ON ERROR)) jt + ON true +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) vals(js) LEFT JOIN JSON_TABLE(vals.js::jsonb , '$' COLUMNS (a int PA..." +== 049 +-- truncate_limit: 100 +-- TABLE-level ERROR ON ERROR is not propagated to columns +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js) + LEFT OUTER JOIN + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$' ERROR ON ERROR)) jt + ON true +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) vals(js) LEFT JOIN JSON_TABLE(vals.js::jsonb , '$' COLUMNS (a int PA..." +== 050 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH '$.a' ERROR ON EMPTY)) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (a int PATH '$.a' ERROR ON EMPTY)) jt" +== 051 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'strict $.a' ERROR ON ERROR) ERROR ON ERROR) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (a int PATH 'strict $.a' ERROR ON ERROR)ERROR O..." +== 052 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'lax $.a' ERROR ON EMPTY) ERROR ON ERROR) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (a int PATH 'lax $.a' ERROR ON EMPTY)ERROR ON E..." +== 053 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH '$' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a int PATH '$' DEFAULT 1 ON EMPTY DEFAULT 2 ..." +== 054 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a int PATH 'strict $.a' DEFAULT 1 ON EMPTY D..." +== 055 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a int PATH 'lax $.a' DEFAULT 1 ON EMPTY DEFA..." +== 056 +-- truncate_limit: 100 +-- JSON_TABLE: EXISTS PATH types +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$.a' ERROR ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a int4 EXISTS PATH '$.a' ERROR ON ERROR))" +== 057 +-- truncate_limit: 100 +-- ok; can cast to int4 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$' ERROR ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a int4 EXISTS PATH '$' ERROR ON ERROR))" +== 058 +-- truncate_limit: 100 +-- ok; can cast to int4 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int2 EXISTS PATH '$.a')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a int2 EXISTS PATH '$.a'))" +== 059 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int8 EXISTS PATH '$.a')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a int8 EXISTS PATH '$.a'))" +== 060 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a float4 EXISTS PATH '$.a')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a float4 EXISTS PATH '$.a'))" +== 061 +-- truncate_limit: 100 +-- Default FALSE (ON ERROR) doesn't fit char(3) +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(3) EXISTS PATH '$.a')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a char(3) EXISTS PATH '$.a'))" +== 062 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(3) EXISTS PATH '$.a' ERROR ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a char(3) EXISTS PATH '$.a' ERROR ON ERROR))" +== 063 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(5) EXISTS PATH '$.a' ERROR ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a char(5) EXISTS PATH '$.a' ERROR ON ERROR))" +== 064 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a json EXISTS PATH '$.a')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a pg_catalog.json EXISTS PATH '$.a'))" +== 065 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a jsonb EXISTS PATH '$.a')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a jsonb EXISTS PATH '$.a'))" +== 066 +-- truncate_limit: 100 +-- EXISTS PATH domain over int +CREATE DOMAIN dint4 AS int +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN dint4 AS int" +== 067 +-- truncate_limit: 100 +CREATE DOMAIN dint4_0 AS int CHECK (VALUE <> 0 ) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN dint4_0 AS int CHECK (value <> 0)" +== 068 +-- truncate_limit: 100 +SELECT a, a::bool FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a dint4 EXISTS PATH '$.a' )) +-- +STMT: SelectStmt +TRUNCATED: "SELECT a, a::bool FROM JSON_TABLE('\"a\"'::jsonb , '$' COLUMNS (a dint4 EXISTS PATH '$.a'))" +== 069 +-- truncate_limit: 100 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT a, a::bool FROM JSON_TABLE('{\"a\":1}'::jsonb , '$' COLUMNS (a dint4_0 EXISTS PATH '$.b'))" +== 070 +-- truncate_limit: 100 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' ERROR ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM JSON_TABLE('{\"a\":1}'::jsonb , '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' ERROR ON E..." +== 071 +-- truncate_limit: 100 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' FALSE ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM JSON_TABLE('{\"a\":1}'::jsonb , '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' FALSE ON E..." +== 072 +-- truncate_limit: 100 +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' TRUE ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM JSON_TABLE('{\"a\":1}'::jsonb , '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' TRUE ON ER..." +== 073 +-- truncate_limit: 100 +DROP DOMAIN dint4, dint4_0 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN dint4, dint4_0" +== 074 +-- truncate_limit: 100 +-- JSON_TABLE: WRAPPER/QUOTES clauses on scalar columns +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' KEEP QUOTES ON SCALAR STRING)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text PATH '$' KEEP QUOTES))" +== 075 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' OMIT QUOTES ON SCALAR STRING)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text PATH '$' OMIT QUOTES))" +== 076 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' KEEP QUOTES)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text FORMAT JSON PATH '$' KEEP QUOT..." +== 077 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' OMIT QUOTES)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text FORMAT JSON PATH '$' OMIT QUOT..." +== 078 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITHOUT WRAPPER KEEP QUOTES)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text FORMAT JSON PATH '$' WITHOUT W..." +== 079 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' WITHOUT WRAPPER OMIT QUOTES)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text PATH '$' WITHOUT WRAPPER OMIT ..." +== 080 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITH WRAPPER)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text FORMAT JSON PATH '$' WITH UNCO..." +== 081 +-- truncate_limit: 100 +-- Error: OMIT QUOTES should not be specified when WITH WRAPPER is present +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' WITH WRAPPER OMIT QUOTES)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text PATH '$' WITH UNCONDITIONAL WR..." +== 082 +-- truncate_limit: 100 +-- But KEEP QUOTES (the default) is fine +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITH WRAPPER KEEP QUOTES)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('\"world\"'::jsonb , '$' COLUMNS (item text FORMAT JSON PATH '$' WITH UNCO..." +== 083 +-- truncate_limit: 100 +-- Test PASSING args +SELECT * +FROM JSON_TABLE( + jsonb '[1,2,3]', + '$[*] ? (@ < $x)' + PASSING 3 AS x + COLUMNS (y text FORMAT JSON PATH '$') + ) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[1,2,3]'::jsonb , '$[*] ? (@ < $x)' PASSING 3 AS x COLUMNS (y text FOR..." +== 084 +-- truncate_limit: 100 +-- PASSING arguments are also passed to column paths +SELECT * +FROM JSON_TABLE( + jsonb '[1,2,3]', + '$[*] ? (@ < $x)' + PASSING 10 AS x, 3 AS y + COLUMNS (a text FORMAT JSON PATH '$ ? (@ < $y)') + ) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[1,2,3]'::jsonb , '$[*] ? (@ < $x)' PASSING 10 AS x, 3 AS y COLUMNS (..." +== 085 +-- truncate_limit: 100 +-- Should fail (not supported) +SELECT * FROM JSON_TABLE(jsonb '{"a": 123}', '$' || '.' || 'a' COLUMNS (foo int)) +-- +ERROR: only string constants are supported in JSON_TABLE path specification +CURSORPOS: 77 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 086 +-- truncate_limit: 100 +-- JsonPathQuery() error message mentioning column name +SELECT * FROM JSON_TABLE('{"a": [{"b": "1"}, {"b": "2"}]}', '$' COLUMNS (b json path '$.a[*].b' ERROR ON ERROR)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('{\"a\": [{\"b\": \"1\"}, {\"b\": \"2\"}]}' , '$' COLUMNS (b pg_catalog.json PATH ..." +== 087 +-- truncate_limit: 100 +-- JSON_TABLE: nested paths + +-- Duplicate path names +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' AS a + COLUMNS ( + b int, + NESTED PATH '$' AS a + COLUMNS ( + c int + ) + ) +) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]'::jsonb , '$' AS a COLUMNS (b int , NESTED PATH '$' AS a COLUMNS (c ..." +== 088 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' AS a + COLUMNS ( + b int, + NESTED PATH '$' AS n_a + COLUMNS ( + c int + ) + ) +) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]'::jsonb , '$' AS a COLUMNS (b int , NESTED PATH '$' AS n_a COLUMNS (..." +== 089 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' + COLUMNS ( + b int, + NESTED PATH '$' AS b + COLUMNS ( + c int + ) + ) +) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]'::jsonb , '$' COLUMNS (b int , NESTED PATH '$' AS b COLUMNS (c int )..." +== 090 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' + COLUMNS ( + NESTED PATH '$' AS a + COLUMNS ( + b int + ), + NESTED PATH '$' + COLUMNS ( + NESTED PATH '$' AS a + COLUMNS ( + c int + ) + ) + ) +) jt +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('[]'::jsonb , '$' COLUMNS (NESTED PATH '$' AS a COLUMNS (b int ), NESTED..." +== 091 +-- truncate_limit: 100 +-- JSON_TABLE: plan execution + +CREATE TEMP TABLE jsonb_table_test (js jsonb) +-- +TABLE: name="jsonb_table_test" schema="" table="jsonb_table_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE jsonb_table_test (js jsonb)" +== 092 +-- truncate_limit: 100 +INSERT INTO jsonb_table_test +VALUES ( + '[ + {"a": 1, "b": [], "c": []}, + {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, + {"a": 3, "b": [1, 2], "c": []}, + {"x": "4", "b": [1, 2], "c": 123} + ]' +) +-- +TABLE: name="jsonb_table_test" schema="" table="jsonb_table_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO jsonb_table_test VALUES (...)" +== 093 +-- truncate_limit: 100 +select + jt.* +from + jsonb_table_test jtt, + json_table ( + jtt.js,'strict $[*]' as p + columns ( + n for ordinality, + a int path 'lax $.a' default -1 on empty, + nested path 'strict $.b[*]' as pb columns (b_id for ordinality, b int path '$' ), + nested path 'strict $.c[*]' as pc columns (c_id for ordinality, c int path '$' ) + ) + ) jt +-- +TABLE: name="jsonb_table_test" schema="" table="jsonb_table_test" ctx=Select +ALIAS: "jtt"="jsonb_table_test" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM jsonb_table_test jtt, JSON_TABLE(jtt.js , 'strict $[*]' AS p COLUMNS (n FOR ORDI..." +== 094 +-- truncate_limit: 100 +-- PASSING arguments are passed to nested paths and their columns' paths +SELECT * +FROM + generate_series(1, 3) x, + generate_series(1, 3) y, + JSON_TABLE(jsonb + '[[1,2,3],[2,3,4,5],[3,4,5,6]]', + 'strict $[*] ? (@[*] <= $x)' + PASSING x AS x, y AS y + COLUMNS ( + y text FORMAT JSON PATH '$', + NESTED PATH 'strict $[*] ? (@ == $y)' + COLUMNS ( + z int PATH '$' + ) + ) + ) jt +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(1, 3) x, generate_series(1, 3) y, JSON_TABLE('[[1,2,3],[2,3,4,5],[3..." +== 095 +-- truncate_limit: 100 +-- JSON_TABLE: Test backward parsing with nested paths + +CREATE VIEW jsonb_table_view_nested AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + NESTED PATH '$[1]' AS p1 COLUMNS ( + a1 int, + NESTED PATH '$[*]' AS "p1 1" COLUMNS ( + a11 text + ), + b1 text + ), + NESTED PATH '$[2]' AS p2 COLUMNS ( + NESTED PATH '$[*]' AS "p2:1" COLUMNS ( + a21 text + ), + NESTED PATH '$[*]' AS p22 COLUMNS ( + a22 text + ) + ) + ) + ) +-- +TABLE: name="jsonb_table_view_nested" schema="" table="jsonb_table_view_nested" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW jsonb_table_view_nested AS SELECT * FROM JSON_TABLE('null'::jsonb , 'lax $[*]' PASSIN..." +== 096 +-- truncate_limit: 100 +DROP VIEW jsonb_table_view_nested +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW jsonb_table_view_nested" +== 097 +-- truncate_limit: 100 +CREATE TABLE s (js jsonb) +-- +TABLE: name="s" schema="" table="s" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE s (js jsonb)" +== 098 +-- truncate_limit: 100 +INSERT INTO s VALUES + ('{"a":{"za":[{"z1": [11,2222]},{"z21": [22, 234,2345]},{"z22": [32, 204,145]}]},"c": 3}'), + ('{"a":{"za":[{"z1": [21,4222]},{"z21": [32, 134,1345]}]},"c": 10}') +-- +TABLE: name="s" schema="" table="s" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO s VALUES (...)" +== 099 +-- truncate_limit: 100 +-- error +SELECT sub.* FROM s, + JSON_TABLE(js, '$' PASSING 32 AS x, 13 AS y COLUMNS ( + xx int path '$.c', + NESTED PATH '$.a.za[1]' columns (NESTED PATH '$.z21[*]' COLUMNS (z21 int path '$?(@ >= $"x")' ERROR ON ERROR)) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM s, JSON_TABLE(js , '$' PASSING 32 AS x, 13 AS y COLUMNS (xx int PATH '$.c', NES..." +== 100 +-- truncate_limit: 100 +-- Parent columns xx1, xx appear before NESTED ones +SELECT sub.* FROM s, + (VALUES (23)) x(x), generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y COLUMNS ( + NESTED PATH '$.a.za[2]' COLUMNS ( + NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$')), + NESTED PATH '$.a.za[1]' columns (d int[] PATH '$.z21'), + NESTED PATH '$.a.za[0]' columns (NESTED PATH '$.z1[*]' as z1 COLUMNS (a int PATH '$')), + xx1 int PATH '$.c', + NESTED PATH '$.a.za[1]' columns (NESTED PATH '$.z21[*]' as z21 COLUMNS (b int PATH '$')), + xx int PATH '$.c' + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM s, (VALUES (23)) x(x), generate_series(13, 13) y, JSON_TABLE(js , '$' AS c1 PASSI..." +== 101 +-- truncate_limit: 100 +-- Test applying PASSING variables at different nesting levels +SELECT sub.* FROM s, + (VALUES (23)) x(x), generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[0].z1[*]' COLUMNS (NESTED PATH '$ ?(@ >= ($"x" -2))' COLUMNS (a int PATH '$')), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' COLUMNS (b int PATH '$')) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM s, (VALUES (23)) x(x), generate_series(13, 13) y, JSON_TABLE(js , '$' AS c1 PASSI..." +== 102 +-- truncate_limit: 100 +-- Test applying PASSING variable to paths all the levels +SELECT sub.* FROM s, + (VALUES (23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[1]' + COLUMNS (NESTED PATH '$.z21[*]' COLUMNS (b int PATH '$')), + NESTED PATH '$.a.za[1] ? (@.z21[*] >= ($"x"-1))' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" + 3))' as z22 COLUMNS (a int PATH '$ ? (@ >= ($"y" + 12))')), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (c int PATH '$ ? (@ > ($"x" +111))')) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM s, (VALUES (23)) x(x), generate_series(13, 13) y, JSON_TABLE(js , '$' AS c1 PASSI..." +== 103 +-- truncate_limit: 100 +----- test on empty behavior +SELECT sub.* FROM s, + (values(23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[2]' COLUMNS (NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$')), + NESTED PATH '$.a.za[1]' COLUMNS (d json PATH '$ ? (@.z21[*] == ($"x" -1))'), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' as z1 COLUMNS (a int PATH '$')), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (b int PATH '$ ? (@ > ($"x" +111))' DEFAULT 0 ON EMPTY)) + )) sub +-- +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM s, (VALUES (23)) x(x), generate_series(13, 13) y, JSON_TABLE(js , '$' AS c1 PASSI..." +== 104 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW jsonb_table_view7 AS +SELECT sub.* FROM s, + (values(23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[2]' COLUMNS (NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$' WITHOUT WRAPPER OMIT QUOTES)), + NESTED PATH '$.a.za[1]' COLUMNS (d json PATH '$ ? (@.z21[*] == ($"x" -1))' WITH WRAPPER), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' as z1 COLUMNS (a int PATH '$' KEEP QUOTES)), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (b int PATH '$ ? (@ > ($"x" +111))' DEFAULT 0 ON EMPTY)) + )) sub +-- +TABLE: name="jsonb_table_view7" schema="" table="jsonb_table_view7" ctx=DDL +TABLE: name="s" schema="" table="s" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW jsonb_table_view7 AS SELECT sub.* FROM s, (VALUES (23)) x(x), generate_ser..." +== 105 +-- truncate_limit: 100 +DROP VIEW jsonb_table_view7 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW jsonb_table_view7" +== 106 +-- truncate_limit: 100 +DROP TABLE s +-- +TABLE: name="s" schema="" table="s" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE s" +== 107 +-- truncate_limit: 100 +-- Prevent ON EMPTY specification on EXISTS columns +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty object on empty)) +-- +ERROR: syntax error at or near "empty" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 108 +-- truncate_limit: 100 +-- Test ON ERROR / EMPTY value validity for the function and column types; +-- all fail +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int) NULL ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (a int )NULL ON ERROR)" +== 109 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int true on empty)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (a int TRUE ON EMPTY))" +== 110 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int omit quotes true on error)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (a int OMIT QUOTES TRUE ON ERROR))" +== 111 +-- truncate_limit: 100 +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty object on error)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM JSON_TABLE('1'::jsonb , '$' COLUMNS (a int EXISTS EMPTY OBJECT ON ERROR))" +== 112 +-- truncate_limit: 100 +-- Test JSON_TABLE() column deparsing -- don't emit default ON ERROR / EMPTY +-- behavior +CREATE VIEW json_table_view8 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$')) +-- +TABLE: name="json_table_view8" schema="" table="json_table_view8" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_table_view8 AS SELECT * FROM JSON_TABLE('\"a\"' , '$' COLUMNS (a text PATH '$'))" +== 113 +-- truncate_limit: 100 +CREATE VIEW json_table_view9 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR) +-- +TABLE: name="json_table_view9" schema="" table="json_table_view9" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_table_view9 AS SELECT * FROM JSON_TABLE('\"a\"' , '$' COLUMNS (a text PATH '$')ERR..." +== 114 +-- truncate_limit: 100 +DROP VIEW json_table_view8, json_table_view9 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW json_table_view8, json_table_view9" +== 115 +-- truncate_limit: 100 +-- Test JSON_TABLE() deparsing -- don't emit default ON ERROR behavior +CREATE VIEW json_table_view8 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ON ERROR) +-- +TABLE: name="json_table_view8" schema="" table="json_table_view8" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_table_view8 AS SELECT * FROM JSON_TABLE('\"a\"' , '$' COLUMNS (a text PATH '$')EMP..." +== 116 +-- truncate_limit: 100 +CREATE VIEW json_table_view9 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ARRAY ON ERROR) +-- +TABLE: name="json_table_view9" schema="" table="json_table_view9" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW json_table_view9 AS SELECT * FROM JSON_TABLE('\"a\"' , '$' COLUMNS (a text PATH '$')EMP..." +== 117 +-- truncate_limit: 100 +DROP VIEW json_table_view8, json_table_view9 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW json_table_view8, json_table_view9" diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json new file mode 100644 index 0000000..b0ece40 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json @@ -0,0 +1,314 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.test b/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.test new file mode 100644 index 0000000..17c5e3b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.test @@ -0,0 +1,2075 @@ +== 001 +-- truncate_limit: 100 +-- JSON_EXISTS +SELECT JSON_EXISTS(NULL::jsonb, '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS(NULL::jsonb , '$')" +== 002 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '[]', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('[]'::jsonb , '$')" +== 003 +-- truncate_limit: 100 +SELECT JSON_EXISTS(JSON_OBJECT(RETURNING jsonb), '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS(JSON_OBJECT( RETURNING jsonb) , '$')" +== 004 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '1', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , '$')" +== 005 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb 'null', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('null'::jsonb , '$')" +== 006 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '[]', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('[]'::jsonb , '$')" +== 007 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '1', '$.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , '$.a')" +== 008 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '1', 'strict $.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , 'strict $.a')" +== 009 +-- truncate_limit: 100 +-- FALSE on error +SELECT JSON_EXISTS(jsonb '1', 'strict $.a' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , 'strict $.a' ERROR ON ERROR)" +== 010 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb 'null', '$.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('null'::jsonb , '$.a')" +== 011 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '[]', '$.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('[]'::jsonb , '$.a')" +== 012 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '[1, "aaa", {"a": 1}]', 'strict $.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('[1, \"aaa\", {\"a\": 1}]'::jsonb , 'strict $.a')" +== 013 +-- truncate_limit: 100 +-- FALSE on error +SELECT JSON_EXISTS(jsonb '[1, "aaa", {"a": 1}]', 'lax $.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('[1, \"aaa\", {\"a\": 1}]'::jsonb , 'lax $.a')" +== 014 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{}', '$.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{}'::jsonb , '$.a')" +== 015 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{"b": 1, "a": 2}', '$.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"b\": 1, \"a\": 2}'::jsonb , '$.a')" +== 016 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '1', '$.a.b') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , '$.a.b')" +== 017 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{"a": {"b": 1}}', '$.a.b') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": {\"b\": 1}}'::jsonb , '$.a.b')" +== 018 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.a.b') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": 1, \"b\": 2}'::jsonb , '$.a.b')" +== 019 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x)' PASSING 1 AS x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": 1, \"b\": 2}'::jsonb , '$.* ? (@ > $x)' PASSING 1 AS x)" +== 020 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x)' PASSING '1' AS x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": 1, \"b\": 2}'::jsonb , '$.* ? (@ > $x)' PASSING '1' AS x)" +== 021 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 2 AS y) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": 1, \"b\": 2}'::jsonb , '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 2 AS y)" +== 022 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 1 AS y) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": 1, \"b\": 2}'::jsonb , '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 1 AS y)" +== 023 +-- truncate_limit: 100 +-- extension: boolean expressions +SELECT JSON_EXISTS(jsonb '1', '$ > 2') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , '$ > 2')" +== 024 +-- truncate_limit: 100 +SELECT JSON_EXISTS(jsonb '1', '$.a > 2' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , '$.a > 2' ERROR ON ERROR)" +== 025 +-- truncate_limit: 100 +-- JSON_VALUE +SELECT JSON_VALUE(NULL::jsonb, '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE(NULL::jsonb , '$')" +== 026 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('null'::jsonb , '$')" +== 027 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING int) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('null'::jsonb , '$' RETURNING int )" +== 028 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'true', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('true'::jsonb , '$')" +== 029 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'true', '$' RETURNING bool) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('true'::jsonb , '$' RETURNING bool )" +== 030 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '123', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$')" +== 031 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING int) + 234 +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$' RETURNING int ) + 234" +== 032 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$' RETURNING text )" +== 033 +-- truncate_limit: 100 +/* jsonb bytea ??? */ +SELECT JSON_VALUE(jsonb '123', '$' RETURNING bytea ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$' RETURNING bytea ERROR ON ERROR)" +== 034 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1.23', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1.23'::jsonb , '$')" +== 035 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1.23', '$' RETURNING int) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1.23'::jsonb , '$' RETURNING int )" +== 036 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"1.23"', '$' RETURNING numeric) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"1.23\"'::jsonb , '$' RETURNING numeric )" +== 037 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"1.23"', '$' RETURNING int ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"1.23\"'::jsonb , '$' RETURNING int ERROR ON ERROR)" +== 038 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$')" +== 039 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING text )" +== 040 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(5)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING char(5) )" +== 041 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2) ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING char(2) ERROR ON ERROR)" +== 042 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING char(2) )" +== 043 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING char(3) ERROR ON ERROR)" +== 044 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING pg_catalog.json )" +== 045 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING jsonb )" +== 046 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING pg_catalog.json ERROR ON ERROR)" +== 047 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING jsonb ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING jsonb ERROR ON ERROR)" +== 048 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"\"aaa\""', '$' RETURNING json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE(E'\"\\\\\"aaa\\\\\"\"'::jsonb , '$' RETURNING pg_catalog.json )" +== 049 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"\"aaa\""', '$' RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE(E'\"\\\\\"aaa\\\\\"\"'::jsonb , '$' RETURNING jsonb )" +== 050 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING int )" +== 051 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING int ERROR ON ERROR)" +== 052 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int DEFAULT 111 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"'::jsonb , '$' RETURNING int DEFAULT 111 ON ERROR)" +== 053 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"123"', '$' RETURNING int) + 234 +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"123\"'::jsonb , '$' RETURNING int ) + 234" +== 054 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"2017-02-20"', '$' RETURNING date) + 9 +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"2017-02-20\"'::jsonb , '$' RETURNING date ) + 9" +== 055 +-- truncate_limit: 100 +-- Test NULL checks execution in domain types +CREATE DOMAIN sqljsonb_int_not_null AS int NOT NULL +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN sqljsonb_int_not_null AS int NOT NULL" +== 056 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('null'::jsonb , '$' RETURNING sqljsonb_int_not_null )" +== 057 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('null'::jsonb , '$' RETURNING sqljsonb_int_not_null ERROR ON ERROR)" +== 058 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null DEFAULT 2 ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 059 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT 2 ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 060 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT NULL ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 061 +-- truncate_limit: 100 +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple')" +== 062 +-- truncate_limit: 100 +CREATE DOMAIN rgb AS rainbow CHECK (VALUE IN ('red', 'green', 'blue')) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN rgb AS rainbow CHECK (value IN ('red', 'green', 'blue'))" +== 063 +-- truncate_limit: 100 +SELECT JSON_VALUE('"purple"'::jsonb, 'lax $[*]' RETURNING rgb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"purple\"'::jsonb , 'lax $[*]' RETURNING rgb )" +== 064 +-- truncate_limit: 100 +SELECT JSON_VALUE('"purple"'::jsonb, 'lax $[*]' RETURNING rgb ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"purple\"'::jsonb , 'lax $[*]' RETURNING rgb ERROR ON ERROR)" +== 065 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '[]', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[]'::jsonb , '$')" +== 066 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '[]', '$' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[]'::jsonb , '$' ERROR ON ERROR)" +== 067 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{}', '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{}'::jsonb , '$')" +== 068 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{}', '$' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{}'::jsonb , '$' ERROR ON ERROR)" +== 069 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', '$.a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , '$.a')" +== 070 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'strict $.a' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'strict $.a' ERROR ON ERROR)" +== 071 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'strict $.a' DEFAULT 'error' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'strict $.a' DEFAULT 'error' ON ERROR)" +== 072 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'lax $.a' ERROR ON ERROR)" +== 073 +-- truncate_limit: 100 +-- NULL ON EMPTY +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'lax $.a' ERROR ON EMPTY ERROR ON ERROR)" +== 074 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'strict $.*' DEFAULT 2 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'strict $.*' DEFAULT 2 ON ERROR)" +== 075 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT 2 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'lax $.a' DEFAULT 2 ON ERROR)" +== 076 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'lax $.a' DEFAULT '2' ON EMPTY)" +== 077 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' NULL ON EMPTY DEFAULT '2' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'lax $.a' NULL ON EMPTY DEFAULT '2' ON ERROR)" +== 078 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY DEFAULT '3' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'lax $.a' DEFAULT '2' ON EMPTY DEFAULT '3' ON ERROR)" +== 079 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY DEFAULT '3' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , 'lax $.a' ERROR ON EMPTY DEFAULT '3' ON ERROR)" +== 080 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[1,2]'::jsonb , '$[*]' ERROR ON ERROR)" +== 081 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' DEFAULT '0' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[1,2]'::jsonb , '$[*]' DEFAULT '0' ON ERROR)" +== 082 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[\" \"]'::jsonb , '$[*]' RETURNING int ERROR ON ERROR)" +== 083 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[\" \"]'::jsonb , '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR)" +== 084 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[\"1\"]'::jsonb , '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR)" +== 085 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[\"1\"]'::jsonb , '$[*]' RETURNING int FORMAT JSON )" +== 086 +-- truncate_limit: 100 +-- RETURNING FORMAT not allowed + +-- RETUGNING pseudo-types not allowed +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING record) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('[\"1\"]'::jsonb , '$[*]' RETURNING record )" +== 087 +-- truncate_limit: 100 +SELECT + x, + JSON_VALUE( + jsonb '{"a": 1, "b": 2}', + '$.* ? (@ > $x)' PASSING x AS x + RETURNING int + DEFAULT -1 ON EMPTY + DEFAULT -2 ON ERROR + ) y +FROM + generate_series(0, 2) x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(0, 2) x" +== 088 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('null'::jsonb , '$a' PASSING point ' (1, 2 )' AS a)" +== 089 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a RETURNING point) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('null'::jsonb , '$a' PASSING point ' (1, 2 )' AS a RETURNING point )" +== 090 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a RETURNING point ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 091 +-- truncate_limit: 100 +-- Test PASSING and RETURNING date/time types +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('null'::jsonb , '$ts' PASSING '2018-02-21 12:34:56 +10'::timestamptz AS ts)" +== 092 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamptz) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 093 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamp) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 094 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING date '2018-02-21 12:34:56 +10' AS ts RETURNING date) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 095 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING time '2018-02-21 12:34:56 +10' AS ts RETURNING time) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 096 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timetz '2018-02-21 12:34:56 +10' AS ts RETURNING timetz) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 097 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamp '2018-02-21 12:34:56 +10' AS ts RETURNING timestamp) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 098 +-- truncate_limit: 100 +-- Also test RETURNING json[b] +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 099 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 100 +-- truncate_limit: 100 +-- Test that numeric JSON values are coerced uniformly +select json_value('{"a": 1.234}', '$.a' returning int error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": 1.234}' , '$.a' RETURNING int ERROR ON ERROR)" +== 101 +-- truncate_limit: 100 +select json_value('{"a": "1.234"}', '$.a' returning int error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": \"1.234\"}' , '$.a' RETURNING int ERROR ON ERROR)" +== 102 +-- truncate_limit: 100 +-- JSON_QUERY + +SELECT JSON_VALUE(NULL::jsonb, '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE(NULL::jsonb , '$')" +== 103 +-- truncate_limit: 100 +SELECT + JSON_QUERY(js, '$') AS "unspec", + JSON_QUERY(js, '$' WITHOUT WRAPPER) AS "without", + JSON_QUERY(js, '$' WITH CONDITIONAL WRAPPER) AS "with cond", + JSON_QUERY(js, '$' WITH UNCONDITIONAL ARRAY WRAPPER) AS "with uncond", + JSON_QUERY(js, '$' WITH ARRAY WRAPPER) AS "with" +FROM + (VALUES + (jsonb 'null'), + ('12.3'), + ('true'), + ('"aaa"'), + ('[1, null, "2"]'), + ('{"a": 1, "b": [2]}') + ) foo(js) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) foo(js)" +== 104 +-- truncate_limit: 100 +SELECT + JSON_QUERY(js, 'strict $[*]') AS "unspec", + JSON_QUERY(js, 'strict $[*]' WITHOUT WRAPPER) AS "without", + JSON_QUERY(js, 'strict $[*]' WITH CONDITIONAL WRAPPER) AS "with cond", + JSON_QUERY(js, 'strict $[*]' WITH UNCONDITIONAL ARRAY WRAPPER) AS "with uncond", + JSON_QUERY(js, 'strict $[*]' WITH ARRAY WRAPPER) AS "with" +FROM + (VALUES + (jsonb '1'), + ('[]'), + ('[null]'), + ('[12.3]'), + ('[true]'), + ('["aaa"]'), + ('[[1, 2, 3]]'), + ('[{"a": 1, "b": [2]}]'), + ('[1, "2", null, [3]]') + ) foo(js) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) foo(js)" +== 105 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING text )" +== 106 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text KEEP QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING text KEEP QUOTES)" +== 107 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text KEEP QUOTES ON SCALAR STRING) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING text KEEP QUOTES)" +== 108 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text OMIT QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING text OMIT QUOTES)" +== 109 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text OMIT QUOTES ON SCALAR STRING) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING text OMIT QUOTES)" +== 110 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' OMIT QUOTES ERROR ON ERROR)" +== 111 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING json OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING pg_catalog.json OMIT QUOTES ERROR ON ERROR)" +== 112 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING bytea FORMAT JSON OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING bytea FORMAT JSON OMIT QUOTES ERROR ON ERROR)" +== 113 +-- truncate_limit: 100 +-- Behavior when a RETURNING type has typmod != -1 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING char(3) ERROR ON ERROR)" +== 114 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING char(3) )" +== 115 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$' RETURNING char(3) OMIT QUOTES ERROR ON ERROR)" +== 116 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT 'bb' ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"aaa\"'::jsonb , '$.a' RETURNING char(2) OMIT QUOTES DEFAULT 'bb' ON EMPTY)" +== 117 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT '"bb"'::jsonb ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 118 +-- truncate_limit: 100 +-- OMIT QUOTES behavior should not be specified when WITH WRAPPER used: +-- Should fail +SELECT JSON_QUERY(jsonb '[1]', '$' WITH WRAPPER OMIT QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1]'::jsonb , '$' WITH UNCONDITIONAL WRAPPER OMIT QUOTES)" +== 119 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER OMIT QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1]'::jsonb , '$' WITH CONDITIONAL WRAPPER OMIT QUOTES)" +== 120 +-- truncate_limit: 100 +-- Should succeed +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH CONDITIONAL WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[\"1\"]'::jsonb , '$[*]' WITH CONDITIONAL WRAPPER KEEP QUOTES)" +== 121 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH UNCONDITIONAL WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[\"1\"]'::jsonb , '$[*]' WITH UNCONDITIONAL WRAPPER KEEP QUOTES)" +== 122 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[\"1\"]'::jsonb , '$[*]' WITH UNCONDITIONAL WRAPPER KEEP QUOTES)" +== 123 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITHOUT WRAPPER OMIT QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[\"1\"]'::jsonb , '$[*]' WITHOUT WRAPPER OMIT QUOTES)" +== 124 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITHOUT WRAPPER KEEP QUOTES) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[\"1\"]'::jsonb , '$[*]' WITHOUT WRAPPER KEEP QUOTES)" +== 125 +-- truncate_limit: 100 +-- test QUOTES behavior. +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] omit quotes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"rec\": \"{1,2,3}\"}'::jsonb , '$.rec' RETURNING int[] OMIT QUOTES)" +== 126 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] keep quotes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"rec\": \"{1,2,3}\"}'::jsonb , '$.rec' RETURNING int[] KEEP QUOTES)" +== 127 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] keep quotes error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"rec\": \"{1,2,3}\"}'::jsonb , '$.rec' RETURNING int[] KEEP QUOTES ERROR ON ERROR)" +== 128 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range omit quotes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"rec\": \"[1,2]\"}'::jsonb , '$.rec' RETURNING int4range OMIT QUOTES)" +== 129 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"rec\": \"[1,2]\"}'::jsonb , '$.rec' RETURNING int4range KEEP QUOTES)" +== 130 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 131 +-- truncate_limit: 100 +CREATE DOMAIN qf_char_domain AS char(1) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN qf_char_domain AS char(1)" +== 132 +-- truncate_limit: 100 +CREATE DOMAIN qf_jsonb_domain AS jsonb +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN qf_jsonb_domain AS jsonb" +== 133 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_char_domain OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"1\"'::jsonb , '$' RETURNING qf_char_domain OMIT QUOTES ERROR ON ERROR)" +== 134 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_jsonb_domain OMIT QUOTES ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"1\"'::jsonb , '$' RETURNING qf_jsonb_domain OMIT QUOTES ERROR ON ERROR)" +== 135 +-- truncate_limit: 100 +DROP DOMAIN qf_char_domain, qf_jsonb_domain +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN qf_char_domain, qf_jsonb_domain" +== 136 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]')" +== 137 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' NULL ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' NULL ON EMPTY)" +== 138 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' EMPTY ARRAY ON EMPTY)" +== 139 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ARRAY ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' EMPTY ARRAY ON EMPTY)" +== 140 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY OBJECT ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' EMPTY OBJECT ON EMPTY)" +== 141 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' ERROR ON EMPTY)" +== 142 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' DEFAULT '"empty"' ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' DEFAULT '\"empty\"' ON EMPTY)" +== 143 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY NULL ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' ERROR ON EMPTY NULL ON ERROR)" +== 144 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY EMPTY ARRAY ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' ERROR ON EMPTY EMPTY ARRAY ON ERROR)" +== 145 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' ERROR ON EMPTY EMPTY OBJECT ON ERROR)" +== 146 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' ERROR ON EMPTY ERROR ON ERROR)" +== 147 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[]'::jsonb , '$[*]' ERROR ON ERROR)" +== 148 +-- truncate_limit: 100 +-- NULL ON EMPTY + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$[*]' ERROR ON ERROR)" +== 149 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' DEFAULT '"empty"' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$[*]' DEFAULT '\"empty\"' ON ERROR)" +== 150 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING pg_catalog.json )" +== 151 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING json FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING pg_catalog.json FORMAT JSON )" +== 152 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING jsonb )" +== 153 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING jsonb FORMAT JSON )" +== 154 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING text )" +== 155 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(10)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING char(10) )" +== 156 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING text FORMAT JSON )" +== 157 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING bytea )" +== 158 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea FORMAT JSON) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$' RETURNING bytea FORMAT JSON )" +== 159 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING bytea EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$[*]' RETURNING bytea EMPTY OBJECT ON ERROR)" +== 160 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING bytea FORMAT JSON EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$[*]' RETURNING bytea FORMAT JSON EMPTY OBJECT ON ERROR)" +== 161 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING json EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$[*]' RETURNING pg_catalog.json EMPTY OBJECT ON ERROR)" +== 162 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING jsonb EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2]'::jsonb , '$[*]' RETURNING jsonb EMPTY OBJECT ON ERROR)" +== 163 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[3,4]', '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[3,4]'::jsonb , '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR)" +== 164 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"[3,4]"', '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"[3,4]\"'::jsonb , '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR)" +== 165 +-- truncate_limit: 100 +-- Coercion fails with quotes on +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int2 error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING int2 ERROR ON ERROR)" +== 166 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int4 error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING int4 ERROR ON ERROR)" +== 167 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int8 error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING int8 ERROR ON ERROR)" +== 168 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING bool error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING bool ERROR ON ERROR)" +== 169 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING numeric error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING numeric ERROR ON ERROR)" +== 170 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING real error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING real ERROR ON ERROR)" +== 171 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING float8 error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING float8 ERROR ON ERROR)" +== 172 +-- truncate_limit: 100 +-- Fine with OMIT QUOTES +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int2 omit quotes error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING int2 OMIT QUOTES ERROR ON ERROR)" +== 173 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING float8 omit quotes error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"123.1\"'::jsonb , '$' RETURNING float8 OMIT QUOTES ERROR ON ERROR)" +== 174 +-- truncate_limit: 100 +-- RETUGNING pseudo-types not allowed +SELECT JSON_QUERY(jsonb '[3,4]', '$[*]' RETURNING anyarray EMPTY OBJECT ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[3,4]'::jsonb , '$[*]' RETURNING anyarray EMPTY OBJECT ON ERROR)" +== 175 +-- truncate_limit: 100 +SELECT + x, y, + JSON_QUERY( + jsonb '[1,2,3,4,5,null]', + '$[*] ? (@ >= $x && @ <= $y)' + PASSING x AS x, y AS y + WITH CONDITIONAL WRAPPER + EMPTY ARRAY ON EMPTY + ) list +FROM + generate_series(0, 4) x, + generate_series(0, 4) y +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(0, 4) x, generate_series(0, 4) y" +== 176 +-- truncate_limit: 100 +-- record type returning with quotes behavior. +CREATE TYPE comp_abc AS (a text, b int, c timestamp) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE comp_abc AS (a text, b int, c timestamp)" +== 177 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc omit quotes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"rec\": \"(abc,42,01.02.2003)\"}'::jsonb , '$.rec' RETURNING comp_abc OMIT QUOTES)" +== 178 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc keep quotes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"rec\": \"(abc,42,01.02.2003)\"}'::jsonb , '$.rec' RETURNING comp_abc KEEP QUOTES)" +== 179 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc keep quotes error on error) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 180 +-- truncate_limit: 100 +DROP TYPE comp_abc +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE comp_abc" +== 181 +-- truncate_limit: 100 +-- Extension: record types returning +CREATE TYPE sqljsonb_rec AS (a int, t text, js json, jb jsonb, jsa json[]) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE sqljsonb_rec AS (a int, t text, js pg_catalog.json, jb jsonb, jsa pg_catalog.json[])" +== 182 +-- truncate_limit: 100 +CREATE TYPE sqljsonb_reca AS (reca sqljsonb_rec[]) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE sqljsonb_reca AS (reca sqljsonb_rec[])" +== 183 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 184 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[{"a": "a", "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 185 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[{"a": "a", "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 186 +-- truncate_limit: 100 +SELECT * FROM unnest((JSON_QUERY(jsonb '{"jsa": [{"a": 1, "b": ["foo"]}, {"a": 2, "c": {}}, 123]}', '$' RETURNING sqljsonb_rec)).jsa) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((JSON_QUERY('{\"jsa\": [{\"a\": 1, \"b\": [\"foo\"]}, {\"a\": 2, \"c\": {}}, 123]}'::js..." +== 187 +-- truncate_limit: 100 +SELECT * FROM unnest((JSON_QUERY(jsonb '{"reca": [{"a": 1, "t": ["foo", []]}, {"a": 2, "jb": [{}, true]}]}', '$' RETURNING sqljsonb_reca)).reca) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest((JSON_QUERY('{\"reca\": [{\"a\": 1, \"t\": [\"foo\", []]}, {\"a\": 2, \"jb\": [{}, true]..." +== 188 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING jsonpath) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 189 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING jsonpath ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 190 +-- truncate_limit: 100 +-- Extension: array types returning +SELECT JSON_QUERY(jsonb '[1,2,null,"3"]', '$[*]' RETURNING int[] WITH WRAPPER) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2,null,\"3\"]'::jsonb , '$[*]' RETURNING int[] WITH UNCONDITIONAL WRAPPER)" +== 191 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2,null,"a"]', '$[*]' RETURNING int[] WITH WRAPPER ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 192 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '[1,2,null,"a"]', '$[*]' RETURNING int[] WITH WRAPPER) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('[1,2,null,\"a\"]'::jsonb , '$[*]' RETURNING int[] WITH UNCONDITIONAL WRAPPER)" +== 193 +-- truncate_limit: 100 +SELECT * FROM unnest(JSON_QUERY(jsonb '[{"a": 1, "t": ["foo", []]}, {"a": 2, "jb": [{}, true]}]', '$' RETURNING sqljsonb_rec[])) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest(JSON_QUERY('[{\"a\": 1, \"t\": [\"foo\", []]}, {\"a\": 2, \"jb\": [{}, true]}]'::jsonb..." +== 194 +-- truncate_limit: 100 +-- Extension: domain types returning +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.a' RETURNING sqljsonb_int_not_null) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"a\": 1}'::jsonb , '$.a' RETURNING sqljsonb_int_not_null )" +== 195 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.b' RETURNING sqljsonb_int_not_null) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"a\": 1}'::jsonb , '$.b' RETURNING sqljsonb_int_not_null )" +== 196 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.b' RETURNING sqljsonb_int_not_null ERROR ON EMPTY ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 197 +-- truncate_limit: 100 +-- Test timestamptz passing and output +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('null'::jsonb , '$ts' PASSING '2018-02-21 12:34:56 +10'::timestamptz AS ts)" +== 198 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING json) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 199 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING jsonb) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 200 +-- truncate_limit: 100 +-- Test constraints + +CREATE TABLE test_jsonb_constraints ( + js text, + i int, + x jsonb DEFAULT JSON_QUERY(jsonb '[1,2]', '$[*]' WITH WRAPPER) + CONSTRAINT test_jsonb_constraint1 + CHECK (js IS JSON) + CONSTRAINT test_jsonb_constraint2 + CHECK (JSON_EXISTS(js::jsonb, '$.a' PASSING i + 5 AS int, i::text AS "TXT", array[1,2,3] as arr)) + CONSTRAINT test_jsonb_constraint3 + CHECK (JSON_VALUE(js::jsonb, '$.a' RETURNING int DEFAULT '12' ON EMPTY ERROR ON ERROR) > i) + CONSTRAINT test_jsonb_constraint4 + CHECK (JSON_QUERY(js::jsonb, '$.a' WITH CONDITIONAL WRAPPER EMPTY OBJECT ON ERROR) = jsonb '[10]') + CONSTRAINT test_jsonb_constraint5 + CHECK (JSON_QUERY(js::jsonb, '$.a' RETURNING char(5) OMIT QUOTES EMPTY ARRAY ON EMPTY) > 'a' COLLATE "C") +) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_jsonb_constraints (js text, i int, x jsonb DEFAULT (JSON_QUERY('[1,2]'::jsonb ,..." +== 201 +-- truncate_limit: 100 +SELECT check_clause +FROM information_schema.check_constraints +WHERE constraint_name LIKE 'test_jsonb_constraint%' +ORDER BY 1 +-- +TABLE: name="information_schema.check_constraints" schema="information_schema" table="check_constraints" ctx=Select +FILTER: schema="" table="" column="constraint_name" +STMT: SelectStmt +TRUNCATED: "SELECT check_clause FROM information_schema.check_constraints WHERE ... ORDER BY 1" +== 202 +-- truncate_limit: 100 +SELECT pg_get_expr(adbin, adrelid) +FROM pg_attrdef +WHERE adrelid = 'test_jsonb_constraints'::regclass +ORDER BY 1 +-- +TABLE: name="pg_attrdef" schema="" table="pg_attrdef" ctx=Select +FUNCTION: name="pg_get_expr" function="pg_get_expr" schema="" ctx=Call +FILTER: schema="" table="" column="adrelid" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_expr(adbin, adrelid) FROM pg_attrdef WHERE ... ORDER BY 1" +== 203 +-- truncate_limit: 100 +INSERT INTO test_jsonb_constraints VALUES ('', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_constraints VALUES ('', 1)" +== 204 +-- truncate_limit: 100 +INSERT INTO test_jsonb_constraints VALUES ('1', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_constraints VALUES ('1', 1)" +== 205 +-- truncate_limit: 100 +INSERT INTO test_jsonb_constraints VALUES ('[]') +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_constraints VALUES ('[]')" +== 206 +-- truncate_limit: 100 +INSERT INTO test_jsonb_constraints VALUES ('{"b": 1}', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_constraints VALUES ('{\"b\": 1}', 1)" +== 207 +-- truncate_limit: 100 +INSERT INTO test_jsonb_constraints VALUES ('{"a": 1}', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_constraints VALUES ('{\"a\": 1}', 1)" +== 208 +-- truncate_limit: 100 +INSERT INTO test_jsonb_constraints VALUES ('{"a": 10}', 1) +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_jsonb_constraints VALUES ('{\"a\": 10}', 1)" +== 209 +-- truncate_limit: 100 +DROP TABLE test_jsonb_constraints +-- +TABLE: name="test_jsonb_constraints" schema="" table="test_jsonb_constraints" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_jsonb_constraints" +== 210 +-- truncate_limit: 100 +-- Test mutabilily of query functions +CREATE TABLE test_jsonb_mutability(js jsonb, b int) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_jsonb_mutability (js jsonb, b int)" +== 211 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$')))" +== 212 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a[0]')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a[0]')))" +== 213 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.time()')))" +== 214 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.date()')))" +== 215 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time_tz()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.time_tz()')))" +== 216 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.timestamp()')))" +== 217 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp_tz()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.timestamp_tz()')))" +== 218 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.date() < $.time_tz(..." +== 219 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.date() < $.time())')))" +== 220 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.time() < $.time())')))" +== 221 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.time() < $.time_tz(..." +== 222 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.timestamp_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.timestamp() < $.tim..." +== 223 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.timestamp_tz())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.timestamp_tz() < $...." +== 224 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.time() < $.datetime..." +== 225 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.date() < $.datetime..." +== 226 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.timestamp() < $.dat..." +== 227 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.timestamp() < $.dat..." +== 228 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.timestamp_tz() < $...." +== 229 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.timestamp_tz() < $...." +== 230 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.date() < $x' PASSING '12:3..." +== 231 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '1234'::int AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.date() < $x' PASSING '1234..." +== 232 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp(2) < $.timestamp(3))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.timestamp(2) < $.ti..." +== 233 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime()')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.datetime()')))" +== 234 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@ < $.datetime())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@ < $.datetime())')))" +== 235 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime())')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.datetime() < $.date..." +== 236 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.datetime() < $.date..." +== 237 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("HH:MI TZH"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.datetime(\"HH:MI TZH..." +== 238 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI") < $.datetime("YY-MM-DD HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.datetime(\"HH:MI\") <..." +== 239 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("YY-MM-DD HH:MI"))')) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.a ? (@.datetime(\"HH:MI TZH..." +== 240 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $x' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.datetime(\"HH:MI TZH\") < $x..." +== 241 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $y' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.datetime(\"HH:MI TZH\") < $y..." +== 242 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '12:34'::timetz AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.datetime() < $x' PASSING '..." +== 243 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '1234'::int AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.datetime() < $x' PASSING '..." +== 244 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() ? (@ == $x)' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.datetime() ? (@ == $x)' PA..." +== 245 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("YY-MM-DD") ? (@ == $x)' PASSING '2020-07-14'::date AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$.datetime(\"YY-MM-DD\") ? (@ ..." +== 246 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$[1, $.a ? (@.datetime() == ..." +== 247 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, 0 to $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$[1, 0 to $.a ? (@.datetime(..." +== 248 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime("HH:MI") == $x)]' PASSING '12:34'::time AS x)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_QUERY(js , '$[1, $.a ? (@.datetime(\"HH:M..." +== 249 +-- truncate_limit: 100 +CREATE INDEX ON test_jsonb_mutability (JSON_VALUE(js, '$' DEFAULT random()::int ON ERROR)) +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON test_jsonb_mutability USING btree ((JSON_VALUE(js , '$' DEFAULT random()::int ON ..." +== 250 +-- truncate_limit: 100 +-- DEFAULT expression +CREATE OR REPLACE FUNCTION ret_setint() RETURNS SETOF integer AS +$$ +BEGIN + RETURN QUERY EXECUTE 'select 1 union all select 1'; +END; +$$ +LANGUAGE plpgsql IMMUTABLE +-- +FUNCTION: name="ret_setint" function="ret_setint" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION ret_setint() RETURNS SETOF int AS $$\nBEGIN\n RETURN QUERY EXECUTE 's..." +== 251 +-- truncate_limit: 100 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT ret_setint() ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +FUNCTION: name="ret_setint" function="ret_setint" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY(js , '$' RETURNING int DEFAULT ret_setint() ON ERROR) FROM test_jsonb_mutability" +== 252 +-- truncate_limit: 100 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT b + 1 ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY(js , '$' RETURNING int DEFAULT b + 1 ON ERROR) FROM test_jsonb_mutability" +== 253 +-- truncate_limit: 100 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT sum(1) over() ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM test_jsonb_mutability" +== 254 +-- truncate_limit: 100 +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT (SELECT 1) ON ERROR) FROM test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY(js , '$' RETURNING int DEFAULT (SELECT 1) ON ERROR) FROM test_jsonb_mutability" +== 255 +-- truncate_limit: 100 +DROP TABLE test_jsonb_mutability +-- +TABLE: name="test_jsonb_mutability" schema="" table="test_jsonb_mutability" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_jsonb_mutability" +== 256 +-- truncate_limit: 100 +DROP FUNCTION ret_setint +-- +FUNCTION: name="ret_setint" function="ret_setint" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION ret_setint" +== 257 +-- truncate_limit: 100 +CREATE DOMAIN queryfuncs_test_domain AS text CHECK (value <> 'foo') +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN queryfuncs_test_domain AS text CHECK (value <> 'foo')" +== 258 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo'::queryfuncs_test_domain ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 259 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo1'::queryfuncs_test_domain ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 260 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT '"foo1"'::jsonb::text ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 261 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{"d1": "foo"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo1'::queryfuncs_test_domain ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 262 +-- truncate_limit: 100 +-- Check the cases where a coercion-related expression is masking an +-- unsupported expressions + +-- CoerceViaIO +SELECT JSON_QUERY('"a"', '$.a' RETURNING int DEFAULT (SELECT '"1"')::jsonb ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"a\"' , '$.a' RETURNING int DEFAULT (SELECT '\"1\"')::jsonb ON ERROR)" +== 263 +-- truncate_limit: 100 +-- CoerceToDomain +SELECT JSON_QUERY('"a"', '$.a' RETURNING queryfuncs_test_domain DEFAULT (select '"1"')::queryfuncs_test_domain ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 264 +-- truncate_limit: 100 +-- RelabelType +SELECT JSON_QUERY('"a"', '$.a' RETURNING int DEFAULT (SELECT 1)::oid::int ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"a\"' , '$.a' RETURNING int DEFAULT (SELECT 1)::oid::int ON ERROR)" +== 265 +-- truncate_limit: 100 +-- ArrayCoerceExpr +SELECT JSON_QUERY('"a"', '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::oid[]::int[] ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"a\"' , '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::oid[]::int[] ON ERROR)" +== 266 +-- truncate_limit: 100 +-- CollateExpr +SELECT JSON_QUERY('"a"', '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::text COLLATE "C" ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('\"a\"' , '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::text COLLATE \"C\" ON ERROR)" +== 267 +-- truncate_limit: 100 +-- ConvertRowtypeExpr +CREATE TABLE someparent (a int) +-- +TABLE: name="someparent" schema="" table="someparent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE someparent (a int)" +== 268 +-- truncate_limit: 100 +CREATE TABLE somechild () INHERITS (someparent) +-- +TABLE: name="somechild" schema="" table="somechild" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE somechild () INHERITS (someparent)" +== 269 +-- truncate_limit: 100 +SELECT JSON_QUERY('"a"', '$.a' RETURNING someparent DEFAULT (SELECT '(1)')::somechild::someparent ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 270 +-- truncate_limit: 100 +DROP DOMAIN queryfuncs_test_domain +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN queryfuncs_test_domain" +== 271 +-- truncate_limit: 100 +DROP TABLE someparent, somechild +-- +TABLE: name="someparent" schema="" table="someparent" ctx=DDL +TABLE: name="somechild" schema="" table="somechild" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE someparent, somechild" +== 272 +-- truncate_limit: 100 +-- Extension: non-constant JSON path +SELECT JSON_EXISTS(jsonb '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": 123}'::jsonb , ('$' || '.') || 'a')" +== 273 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": 123}'::jsonb , ('$' || '.') || 'a')" +== 274 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' DEFAULT 'foo' ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('{\"a\": 123}'::jsonb , ('$' || '.') || 'b' DEFAULT 'foo' ON EMPTY)" +== 275 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"a\": 123}'::jsonb , ('$' || '.') || 'a')" +== 276 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a' WITH WRAPPER) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"a\": 123}'::jsonb , ('$' || '.') || 'a' WITH UNCONDITIONAL WRAPPER)" +== 277 +-- truncate_limit: 100 +-- Should fail (invalid path) +SELECT JSON_QUERY(jsonb '{"a": 123}', 'error' || ' ' || 'error') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('{\"a\": 123}'::jsonb , ('error' || ' ') || 'error')" +== 278 +-- truncate_limit: 100 +-- Non-jsonb inputs automatically coerced to jsonb +SELECT JSON_EXISTS(json '{"a": 123}', '$' || '.' || 'a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('{\"a\": 123}'::pg_catalog.json , ('$' || '.') || 'a')" +== 279 +-- truncate_limit: 100 +SELECT JSON_QUERY(NULL FORMAT JSON, '$') +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY(NULL FORMAT JSON , '$')" +== 280 +-- truncate_limit: 100 +-- Test non-const jsonpath +CREATE TEMP TABLE jsonpaths (path) AS SELECT '$' +-- +TABLE: name="jsonpaths" schema="" table="jsonpaths" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE jsonpaths(path) AS SELECT '$'" +== 281 +-- truncate_limit: 100 +SELECT json_value('"aaa"', path RETURNING json) FROM jsonpaths +-- +TABLE: name="jsonpaths" schema="" table="jsonpaths" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"aaa\"' , path RETURNING pg_catalog.json ) FROM jsonpaths" +== 282 +-- truncate_limit: 100 +-- Test PASSING argument parsing +SELECT JSON_QUERY(jsonb 'null', '$xyz' PASSING 1 AS xy) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('null'::jsonb , '$xyz' PASSING 1 AS xy)" +== 283 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb 'null', '$xy' PASSING 1 AS xyz) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('null'::jsonb , '$xy' PASSING 1 AS xyz)" +== 284 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb 'null', '$xyz' PASSING 1 AS xyz) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('null'::jsonb , '$xyz' PASSING 1 AS xyz)" +== 285 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS Xyz) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('null'::jsonb , '$Xyz' PASSING 1 AS xyz)" +== 286 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS "Xyz") +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('null'::jsonb , '$Xyz' PASSING 1 AS \"Xyz\")" +== 287 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb 'null', '$"Xyz"' PASSING 1 AS "Xyz") +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('null'::jsonb , '$\"Xyz\"' PASSING 1 AS \"Xyz\")" +== 288 +-- truncate_limit: 100 +-- Test ON ERROR / EMPTY value validity for the function; all fail. +SELECT JSON_EXISTS(jsonb '1', '$' DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_EXISTS('1'::jsonb , '$' DEFAULT 1 ON ERROR)" +== 289 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1', '$' EMPTY ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1'::jsonb , '$' EMPTY ARRAY ON ERROR)" +== 290 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '1', '$' TRUE ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('1'::jsonb , '$' TRUE ON ERROR)" +== 291 +-- truncate_limit: 100 +-- Test implicit coercion to a domain over fixed-length type specified in +-- RETURNING +CREATE DOMAIN queryfuncs_char2 AS char(2) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN queryfuncs_char2 AS char(2)" +== 292 +-- truncate_limit: 100 +CREATE DOMAIN queryfuncs_char2_chk AS char(2) CHECK (VALUE NOT IN ('12')) +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN queryfuncs_char2_chk AS char(2) CHECK (value NOT IN ('12'))" +== 293 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('123'::jsonb , '$' RETURNING queryfuncs_char2 ERROR ON ERROR)" +== 294 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT '1' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('123'::jsonb , '$' RETURNING queryfuncs_char2 DEFAULT '1' ON ERROR)" +== 295 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('123'::jsonb , '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR)" +== 296 +-- truncate_limit: 100 +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT '1' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_QUERY('123'::jsonb , '$' RETURNING queryfuncs_char2_chk DEFAULT '1' ON ERROR)" +== 297 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$' RETURNING queryfuncs_char2 ERROR ON ERROR)" +== 298 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$' RETURNING queryfuncs_char2 DEFAULT 1 ON ERROR)" +== 299 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR)" +== 300 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('123'::jsonb , '$' RETURNING queryfuncs_char2_chk DEFAULT 1 ON ERROR)" +== 301 +-- truncate_limit: 100 +DROP DOMAIN queryfuncs_char2, queryfuncs_char2_chk +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN queryfuncs_char2, queryfuncs_char2_chk" +== 302 +-- truncate_limit: 100 +-- Test coercion to domain over another fixed-length type of the ON ERROR / +-- EMPTY expressions. Ask user to cast the DEFAULT expression explicitly if +-- automatic casting cannot be done, for example, from int to bit(2). +CREATE DOMAIN queryfuncs_d_varbit3 AS varbit(3) CHECK (VALUE <> '01') +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN queryfuncs_d_varbit3 AS varbit(3) CHECK (value <> '01')" +== 303 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '111111' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1234'::jsonb , '$' RETURNING queryfuncs_d_varbit3 DEFAULT '111111' ON ERROR)" +== 304 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '010' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1234'::jsonb , '$' RETURNING queryfuncs_d_varbit3 DEFAULT '010' ON ERROR)" +== 305 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '01' ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1234'::jsonb , '$' RETURNING queryfuncs_d_varbit3 DEFAULT '01' ON ERROR)" +== 306 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"111"', '$' RETURNING bit(2) ERROR ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"111\"'::jsonb , '$' RETURNING pg_catalog.bit(2) ERROR ON ERROR)" +== 307 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING bit(3) DEFAULT 1 ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('1234'::jsonb , '$' RETURNING pg_catalog.bit(3) DEFAULT 1 ON ERROR)" +== 308 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING bit(3) DEFAULT 1::bit(3) ON ERROR) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 309 +-- truncate_limit: 100 +SELECT JSON_VALUE(jsonb '"111"', '$.a' RETURNING bit(3) DEFAULT '1111' ON EMPTY) +-- +STMT: SelectStmt +TRUNCATED: "SELECT JSON_VALUE('\"111\"'::jsonb , '$.a' RETURNING pg_catalog.bit(3) DEFAULT '1111' ON EMPTY)" +== 310 +-- truncate_limit: 100 +DROP DOMAIN queryfuncs_d_varbit3 +-- +STMT: DropStmt +TRUNCATED: "DROP DOMAIN queryfuncs_d_varbit3" diff --git a/parser/testdata/summary_truncate/postgres_regress/stats.metadata.json b/parser/testdata/summary_truncate/postgres_regress/stats.metadata.json new file mode 100644 index 0000000..5fff658 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/stats.metadata.json @@ -0,0 +1,451 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/stats.test b/parser/testdata/summary_truncate/postgres_regress/stats.test new file mode 100644 index 0000000..a091102 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/stats.test @@ -0,0 +1,3593 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test cumulative stats system +|-- +-- Must be run after tenk2 has been created (by create_table), +-- populated (by create_misc) and indexed (by create_index). +|-- + +-- conditio sine qua non +SHOW track_counts +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW track_counts" +== 002 +-- truncate_limit: 100 +-- must be on + +-- ensure that both seqscan and indexscan plans are allowed +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 003 +-- truncate_limit: 100 +SET enable_indexscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 004 +-- truncate_limit: 100 +-- for the moment, we don't want index-only scans here +SET enable_indexonlyscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO OFF" +== 005 +-- truncate_limit: 100 +-- not enabled by default, but we want to test it... +SET track_functions TO 'all' +-- +STMT: VariableSetStmt +TRUNCATED: "SET track_functions TO \"all\"" +== 006 +-- truncate_limit: 100 +-- record dboid for later use +SELECT oid AS dboid from pg_database where datname = current_database() +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +TRUNCATED: "SELECT oid AS dboid FROM pg_database WHERE datname = current_database()" +== 007 +-- truncate_limit: 100 +-- save counters +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 008 +-- truncate_limit: 100 +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL stats_fetch_consistency TO snapshot" +== 009 +-- truncate_limit: 100 +CREATE TABLE prevstats AS +SELECT t.seq_scan, t.seq_tup_read, t.idx_scan, t.idx_tup_fetch, + (b.heap_blks_read + b.heap_blks_hit) AS heap_blks, + (b.idx_blks_read + b.idx_blks_hit) AS idx_blks, + pg_stat_get_snapshot_timestamp() as snap_ts + FROM pg_catalog.pg_stat_user_tables AS t, + pg_catalog.pg_statio_user_tables AS b + WHERE t.relname='tenk2' AND b.relname='tenk2' +-- +TABLE: name="prevstats" schema="" table="prevstats" ctx=DDL +TABLE: name="pg_catalog.pg_stat_user_tables" schema="pg_catalog" table="pg_stat_user_tables" ctx=Select +TABLE: name="pg_catalog.pg_statio_user_tables" schema="pg_catalog" table="pg_statio_user_tables" ctx=Select +ALIAS: "b"="pg_catalog.pg_statio_user_tables" +ALIAS: "t"="pg_catalog.pg_stat_user_tables" +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +FILTER: schema="" table="t" column="relname" +FILTER: schema="" table="b" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE prevstats AS SELECT t.seq_scan, t.seq_tup_read, t.idx_scan, t.idx_tup_fetch, b.heap_..." +== 010 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 011 +-- truncate_limit: 100 +-- test effects of TRUNCATE on n_live_tup/n_dead_tup counters +CREATE TABLE trunc_stats_test(id serial) +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_stats_test (id serial)" +== 012 +-- truncate_limit: 100 +CREATE TABLE trunc_stats_test1(id serial, stuff text) +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_stats_test1 (id serial, stuff text)" +== 013 +-- truncate_limit: 100 +CREATE TABLE trunc_stats_test2(id serial) +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_stats_test2 (id serial)" +== 014 +-- truncate_limit: 100 +CREATE TABLE trunc_stats_test3(id serial, stuff text) +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_stats_test3 (id serial, stuff text)" +== 015 +-- truncate_limit: 100 +CREATE TABLE trunc_stats_test4(id serial) +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_stats_test4 (id serial)" +== 016 +-- truncate_limit: 100 +-- check that n_live_tup is reset to 0 after truncate +INSERT INTO trunc_stats_test DEFAULT VALUES +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test DEFAULT VALUES" +== 017 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test DEFAULT VALUES +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test DEFAULT VALUES" +== 018 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test DEFAULT VALUES +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test DEFAULT VALUES" +== 019 +-- truncate_limit: 100 +TRUNCATE trunc_stats_test +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_stats_test" +== 020 +-- truncate_limit: 100 +-- test involving a truncate in a transaction; 4 ins but only 1 live +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test1 DEFAULT VALUES" +== 021 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test1 DEFAULT VALUES" +== 022 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test1 DEFAULT VALUES" +== 023 +-- truncate_limit: 100 +UPDATE trunc_stats_test1 SET id = id + 10 WHERE id IN (1, 2) +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trunc_stats_test1 SET id = id + 10 WHERE id IN (1, 2)" +== 024 +-- truncate_limit: 100 +DELETE FROM trunc_stats_test1 WHERE id = 3 +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trunc_stats_test1 WHERE id = 3" +== 025 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 026 +-- truncate_limit: 100 +UPDATE trunc_stats_test1 SET id = id + 100 +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trunc_stats_test1 SET id = id + 100" +== 027 +-- truncate_limit: 100 +TRUNCATE trunc_stats_test1 +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_stats_test1" +== 028 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test1 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test1 DEFAULT VALUES" +== 029 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 030 +-- truncate_limit: 100 +-- use a savepoint: 1 insert, 1 live +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 031 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test2 DEFAULT VALUES" +== 032 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test2 DEFAULT VALUES" +== 033 +-- truncate_limit: 100 +SAVEPOINT p1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT p1" +== 034 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test2 DEFAULT VALUES" +== 035 +-- truncate_limit: 100 +TRUNCATE trunc_stats_test2 +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_stats_test2" +== 036 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test2 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test2 DEFAULT VALUES" +== 037 +-- truncate_limit: 100 +RELEASE SAVEPOINT p1 +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE p1" +== 038 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 039 +-- truncate_limit: 100 +-- rollback a savepoint: this should count 4 inserts and have 2 +-- live tuples after commit (and 2 dead ones due to aborted subxact) +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 040 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test3 DEFAULT VALUES" +== 041 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test3 DEFAULT VALUES" +== 042 +-- truncate_limit: 100 +SAVEPOINT p1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT p1" +== 043 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test3 DEFAULT VALUES" +== 044 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test3 DEFAULT VALUES" +== 045 +-- truncate_limit: 100 +TRUNCATE trunc_stats_test3 +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_stats_test3" +== 046 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test3 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test3 DEFAULT VALUES" +== 047 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT p1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT p1" +== 048 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 049 +-- truncate_limit: 100 +-- rollback a truncate: this should count 2 inserts and produce 2 dead tuples +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 050 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test4 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test4 DEFAULT VALUES" +== 051 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test4 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test4 DEFAULT VALUES" +== 052 +-- truncate_limit: 100 +TRUNCATE trunc_stats_test4 +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_stats_test4" +== 053 +-- truncate_limit: 100 +INSERT INTO trunc_stats_test4 DEFAULT VALUES +-- +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trunc_stats_test4 DEFAULT VALUES" +== 054 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 055 +-- truncate_limit: 100 +-- do a seqscan +SELECT count(*) FROM tenk2 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk2" +== 056 +-- truncate_limit: 100 +-- do an indexscan +-- make sure it is not a bitmap scan, which might skip fetching heap tuples +SET enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 057 +-- truncate_limit: 100 +SELECT count(*) FROM tenk2 WHERE unique1 = 1 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk2 WHERE unique1 = 1" +== 058 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 059 +-- truncate_limit: 100 +-- ensure pending stats are flushed +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 060 +-- truncate_limit: 100 +-- check effects +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 061 +-- truncate_limit: 100 +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL stats_fetch_consistency TO snapshot" +== 062 +-- truncate_limit: 100 +SELECT relname, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup + FROM pg_stat_user_tables + WHERE relname like 'trunc_stats_test%' order by relname +-- +TABLE: name="pg_stat_user_tables" schema="" table="pg_stat_user_tables" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_user_tables WHERE relname LIKE 'trunc_stats_test%' ORDER BY relname" +== 063 +-- truncate_limit: 100 +SELECT st.seq_scan >= pr.seq_scan + 1, + st.seq_tup_read >= pr.seq_tup_read + cl.reltuples, + st.idx_scan >= pr.idx_scan + 1, + st.idx_tup_fetch >= pr.idx_tup_fetch + 1 + FROM pg_stat_user_tables AS st, pg_class AS cl, prevstats AS pr + WHERE st.relname='tenk2' AND cl.relname='tenk2' +-- +TABLE: name="pg_stat_user_tables" schema="" table="pg_stat_user_tables" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="prevstats" schema="" table="prevstats" ctx=Select +ALIAS: "cl"="pg_class" +ALIAS: "pr"="prevstats" +ALIAS: "st"="pg_stat_user_tables" +FILTER: schema="" table="st" column="relname" +FILTER: schema="" table="cl" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_user_tables st, pg_class cl, prevstats pr WHERE ..." +== 064 +-- truncate_limit: 100 +SELECT st.heap_blks_read + st.heap_blks_hit >= pr.heap_blks + cl.relpages, + st.idx_blks_read + st.idx_blks_hit >= pr.idx_blks + 1 + FROM pg_statio_user_tables AS st, pg_class AS cl, prevstats AS pr + WHERE st.relname='tenk2' AND cl.relname='tenk2' +-- +TABLE: name="pg_statio_user_tables" schema="" table="pg_statio_user_tables" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="prevstats" schema="" table="prevstats" ctx=Select +ALIAS: "cl"="pg_class" +ALIAS: "pr"="prevstats" +ALIAS: "st"="pg_statio_user_tables" +FILTER: schema="" table="st" column="relname" +FILTER: schema="" table="cl" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_statio_user_tables st, pg_class cl, prevstats pr WHERE ..." +== 065 +-- truncate_limit: 100 +SELECT pr.snap_ts < pg_stat_get_snapshot_timestamp() as snapshot_newer +FROM prevstats AS pr +-- +TABLE: name="prevstats" schema="" table="prevstats" ctx=Select +ALIAS: "pr"="prevstats" +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pr.snap_ts < pg_stat_get_snapshot_timestamp() AS snapshot_newer FROM prevstats pr" +== 066 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 067 +-- truncate_limit: 100 +---- +-- Basic tests for track_functions +--- +CREATE FUNCTION stats_test_func1() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$ +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION stats_test_func1() RETURNS void LANGUAGE plpgsql AS $$BEGIN END;$$" +== 068 +-- truncate_limit: 100 +SELECT 'stats_test_func1()'::regprocedure::oid AS stats_test_func1_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'stats_test_func1()'::regprocedure::oid AS stats_test_func1_oid" +== 069 +-- truncate_limit: 100 +CREATE FUNCTION stats_test_func2() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$ +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION stats_test_func2() RETURNS void LANGUAGE plpgsql AS $$BEGIN END;$$" +== 070 +-- truncate_limit: 100 +SELECT 'stats_test_func2()'::regprocedure::oid AS stats_test_func2_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'stats_test_func2()'::regprocedure::oid AS stats_test_func2_oid" +== 071 +-- truncate_limit: 100 +-- test that stats are accumulated +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 072 +-- truncate_limit: 100 +SET LOCAL stats_fetch_consistency = none +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL stats_fetch_consistency TO \"none\"" +== 073 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 074 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +-- truncate_limit: 100 +SELECT stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func1()" +== 076 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +-- truncate_limit: 100 +SELECT stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func1()" +== 078 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 079 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 080 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 081 +-- truncate_limit: 100 +-- Verify that function stats are not transactional + +-- rolled back savepoint in committing transaction +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 082 +-- truncate_limit: 100 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func2()" +== 083 +-- truncate_limit: 100 +SAVEPOINT foo +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT foo" +== 084 +-- truncate_limit: 100 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func2()" +== 085 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT foo +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT foo" +== 086 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_function_calls(:stats_test_func2_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 087 +-- truncate_limit: 100 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func2()" +== 088 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 089 +-- truncate_limit: 100 +-- rolled back transaction +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 090 +-- truncate_limit: 100 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func2()" +== 091 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 092 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 093 +-- truncate_limit: 100 +-- check collected stats +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 92 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 094 +-- truncate_limit: 100 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func2_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 095 +-- truncate_limit: 100 +-- check that a rolled back drop function stats leaves stats alive +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 096 +-- truncate_limit: 100 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 097 +-- truncate_limit: 100 +DROP FUNCTION stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION stats_test_func1()" +== 098 +-- truncate_limit: 100 +-- shouldn't be visible via view +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 100 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 099 +-- truncate_limit: 100 +-- but still via oid access +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 100 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 101 +-- truncate_limit: 100 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 102 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 103 +-- truncate_limit: 100 +-- check that function dropped in main transaction leaves no stats behind +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 104 +-- truncate_limit: 100 +DROP FUNCTION stats_test_func1() +-- +FUNCTION: name="stats_test_func1" function="stats_test_func1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION stats_test_func1()" +== 105 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 106 +-- truncate_limit: 100 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func1_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 107 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(:stats_test_func1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 108 +-- truncate_limit: 100 +-- check that function dropped in a subtransaction leaves no stats behind +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 109 +-- truncate_limit: 100 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func2()" +== 110 +-- truncate_limit: 100 +SAVEPOINT a +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT a" +== 111 +-- truncate_limit: 100 +SELECT stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT stats_test_func2()" +== 112 +-- truncate_limit: 100 +SAVEPOINT b +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT b" +== 113 +-- truncate_limit: 100 +DROP FUNCTION stats_test_func2() +-- +FUNCTION: name="stats_test_func2" function="stats_test_func2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION stats_test_func2()" +== 114 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 115 +-- truncate_limit: 100 +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = :stats_test_func2_oid +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 116 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(:stats_test_func2_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 35 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 117 +-- truncate_limit: 100 +-- Check that stats for relations are dropped. For that we need to access stats +-- by oid after the DROP TABLE. Save oids. +CREATE TABLE drop_stats_test() +-- +TABLE: name="drop_stats_test" schema="" table="drop_stats_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE drop_stats_test ()" +== 118 +-- truncate_limit: 100 +INSERT INTO drop_stats_test DEFAULT VALUES +-- +TABLE: name="drop_stats_test" schema="" table="drop_stats_test" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO drop_stats_test DEFAULT VALUES" +== 119 +-- truncate_limit: 100 +SELECT 'drop_stats_test'::regclass::oid AS drop_stats_test_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'drop_stats_test'::regclass::oid AS drop_stats_test_oid" +== 120 +-- truncate_limit: 100 +CREATE TABLE drop_stats_test_xact() +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE drop_stats_test_xact ()" +== 121 +-- truncate_limit: 100 +INSERT INTO drop_stats_test_xact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO drop_stats_test_xact DEFAULT VALUES" +== 122 +-- truncate_limit: 100 +SELECT 'drop_stats_test_xact'::regclass::oid AS drop_stats_test_xact_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'drop_stats_test_xact'::regclass::oid AS drop_stats_test_xact_oid" +== 123 +-- truncate_limit: 100 +CREATE TABLE drop_stats_test_subxact() +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE drop_stats_test_subxact ()" +== 124 +-- truncate_limit: 100 +INSERT INTO drop_stats_test_subxact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO drop_stats_test_subxact DEFAULT VALUES" +== 125 +-- truncate_limit: 100 +SELECT 'drop_stats_test_subxact'::regclass::oid AS drop_stats_test_subxact_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'drop_stats_test_subxact'::regclass::oid AS drop_stats_test_subxact_oid" +== 126 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 127 +-- truncate_limit: 100 +SELECT pg_stat_get_live_tuples(:drop_stats_test_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 128 +-- truncate_limit: 100 +DROP TABLE drop_stats_test +-- +TABLE: name="drop_stats_test" schema="" table="drop_stats_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE drop_stats_test" +== 129 +-- truncate_limit: 100 +SELECT pg_stat_get_live_tuples(:drop_stats_test_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 130 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 131 +-- truncate_limit: 100 +-- check that rollback protects against having stats dropped and that local +-- modifications don't pose a problem +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 146 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 132 +-- truncate_limit: 100 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 133 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 134 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 135 +-- truncate_limit: 100 +INSERT INTO drop_stats_test_xact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO drop_stats_test_xact DEFAULT VALUES" +== 136 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 137 +-- truncate_limit: 100 +DROP TABLE drop_stats_test_xact +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE drop_stats_test_xact" +== 138 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 139 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 140 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 141 +-- truncate_limit: 100 +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 142 +-- truncate_limit: 100 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 143 +-- truncate_limit: 100 +-- transactional drop +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 144 +-- truncate_limit: 100 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 145 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 146 +-- truncate_limit: 100 +INSERT INTO drop_stats_test_xact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO drop_stats_test_xact DEFAULT VALUES" +== 147 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 148 +-- truncate_limit: 100 +DROP TABLE drop_stats_test_xact +-- +TABLE: name="drop_stats_test_xact" schema="" table="drop_stats_test_xact" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE drop_stats_test_xact" +== 149 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 150 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 151 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 152 +-- truncate_limit: 100 +SELECT pg_stat_get_live_tuples(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 153 +-- truncate_limit: 100 +SELECT pg_stat_get_tuples_inserted(:drop_stats_test_xact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 36 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 154 +-- truncate_limit: 100 +-- savepoint rollback (2 levels) +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 155 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 156 +-- truncate_limit: 100 +INSERT INTO drop_stats_test_subxact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO drop_stats_test_subxact DEFAULT VALUES" +== 157 +-- truncate_limit: 100 +SAVEPOINT sp1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp1" +== 158 +-- truncate_limit: 100 +INSERT INTO drop_stats_test_subxact DEFAULT VALUES +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO drop_stats_test_subxact DEFAULT VALUES" +== 159 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 160 +-- truncate_limit: 100 +SAVEPOINT sp2 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp2" +== 161 +-- truncate_limit: 100 +DROP TABLE drop_stats_test_subxact +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE drop_stats_test_subxact" +== 162 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT sp2 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT sp2" +== 163 +-- truncate_limit: 100 +SELECT pg_stat_get_xact_tuples_inserted(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 41 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 164 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 165 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 166 +-- truncate_limit: 100 +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 167 +-- truncate_limit: 100 +-- savepoint rolback (1 level) +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 168 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 169 +-- truncate_limit: 100 +SAVEPOINT sp1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp1" +== 170 +-- truncate_limit: 100 +DROP TABLE drop_stats_test_subxact +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE drop_stats_test_subxact" +== 171 +-- truncate_limit: 100 +SAVEPOINT sp2 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp2" +== 172 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT sp1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT sp1" +== 173 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 174 +-- truncate_limit: 100 +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 175 +-- truncate_limit: 100 +-- and now actually drop +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 57 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 176 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 177 +-- truncate_limit: 100 +SAVEPOINT sp1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp1" +== 178 +-- truncate_limit: 100 +DROP TABLE drop_stats_test_subxact +-- +TABLE: name="drop_stats_test_subxact" schema="" table="drop_stats_test_subxact" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE drop_stats_test_subxact" +== 179 +-- truncate_limit: 100 +SAVEPOINT sp2 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp2" +== 180 +-- truncate_limit: 100 +RELEASE SAVEPOINT sp1 +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE sp1" +== 181 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 182 +-- truncate_limit: 100 +SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 183 +-- truncate_limit: 100 +DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4 +-- +TABLE: name="trunc_stats_test" schema="" table="trunc_stats_test" ctx=DDL +TABLE: name="trunc_stats_test1" schema="" table="trunc_stats_test1" ctx=DDL +TABLE: name="trunc_stats_test2" schema="" table="trunc_stats_test2" ctx=DDL +TABLE: name="trunc_stats_test3" schema="" table="trunc_stats_test3" ctx=DDL +TABLE: name="trunc_stats_test4" schema="" table="trunc_stats_test4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats..." +== 184 +-- truncate_limit: 100 +DROP TABLE prevstats +-- +TABLE: name="prevstats" schema="" table="prevstats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE prevstats" +== 185 +-- truncate_limit: 100 +----- +-- Test that last_seq_scan, last_idx_scan are correctly maintained +|-- +-- Perform test using a temporary table. That way autovacuum etc won't +-- interfere. To be able to check that timestamps increase, we sleep for 100ms +-- between tests, assuming that there aren't systems with a coarser timestamp +-- granularity. +----- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 186 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE test_last_scan(idx_col int primary key, noidx_col int) +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_last_scan (idx_col int PRIMARY KEY, noidx_col int)" +== 187 +-- truncate_limit: 100 +INSERT INTO test_last_scan(idx_col, noidx_col) VALUES(1, 1) +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_last_scan (idx_col, noidx_col) VALUES (1, 1)" +== 188 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 189 +-- truncate_limit: 100 +SELECT last_seq_scan, last_idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +TRUNCATED: "SELECT last_seq_scan, last_idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass" +== 190 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 191 +-- truncate_limit: 100 +SELECT pg_stat_reset_single_table_counters('test_last_scan'::regclass) +-- +FUNCTION: name="pg_stat_reset_single_table_counters" function="pg_stat_reset_single_table_counters" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_single_table_counters('test_last_scan'::regclass)" +== 192 +-- truncate_limit: 100 +SELECT seq_scan, idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +TRUNCATED: "SELECT seq_scan, idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass" +== 193 +-- truncate_limit: 100 +-- ensure we start out with exactly one index and sequential scan +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 194 +-- truncate_limit: 100 +SET LOCAL enable_seqscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO ON" +== 195 +-- truncate_limit: 100 +SET LOCAL enable_indexscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO ON" +== 196 +-- truncate_limit: 100 +SET LOCAL enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_bitmapscan TO OFF" +== 197 +-- truncate_limit: 100 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_last_scan WHERE noidx_col = 1" +== 198 +-- truncate_limit: 100 +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_last_scan WHERE noidx_col = 1" +== 199 +-- truncate_limit: 100 +SET LOCAL enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO OFF" +== 200 +-- truncate_limit: 100 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_last_scan WHERE idx_col = 1" +== 201 +-- truncate_limit: 100 +SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_last_scan WHERE idx_col = 1" +== 202 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 203 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 204 +-- truncate_limit: 100 +-- fetch timestamps from before the next test +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass" +== 205 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 206 +-- truncate_limit: 100 +-- assume a minimum timestamp granularity of 100ms + +-- cause one sequential scan +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 207 +-- truncate_limit: 100 +SET LOCAL enable_seqscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO ON" +== 208 +-- truncate_limit: 100 +SET LOCAL enable_indexscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO OFF" +== 209 +-- truncate_limit: 100 +SET LOCAL enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_bitmapscan TO OFF" +== 210 +-- truncate_limit: 100 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_last_scan WHERE noidx_col = 1" +== 211 +-- truncate_limit: 100 +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="noidx_col" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_last_scan WHERE noidx_col = 1" +== 212 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 213 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 214 +-- truncate_limit: 100 +-- check that just sequential scan stats were incremented +SELECT seq_scan, :'test_last_seq' < last_seq_scan AS seq_ok, idx_scan, :'test_last_idx' = last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +ERROR: syntax error at or near ":" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 215 +-- truncate_limit: 100 +-- fetch timestamps from before the next test +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass" +== 216 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 217 +-- truncate_limit: 100 +-- cause one index scan +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 218 +-- truncate_limit: 100 +SET LOCAL enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO OFF" +== 219 +-- truncate_limit: 100 +SET LOCAL enable_indexscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO ON" +== 220 +-- truncate_limit: 100 +SET LOCAL enable_bitmapscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_bitmapscan TO OFF" +== 221 +-- truncate_limit: 100 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_last_scan WHERE idx_col = 1" +== 222 +-- truncate_limit: 100 +SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_last_scan WHERE idx_col = 1" +== 223 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 224 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 225 +-- truncate_limit: 100 +-- check that just index scan stats were incremented +SELECT seq_scan, :'test_last_seq' = last_seq_scan AS seq_ok, idx_scan, :'test_last_idx' < last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +ERROR: syntax error at or near ":" +CURSORPOS: 71 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 226 +-- truncate_limit: 100 +-- fetch timestamps from before the next test +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass" +== 227 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 228 +-- truncate_limit: 100 +-- cause one bitmap index scan +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 229 +-- truncate_limit: 100 +SET LOCAL enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_seqscan TO OFF" +== 230 +-- truncate_limit: 100 +SET LOCAL enable_indexscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO OFF" +== 231 +-- truncate_limit: 100 +SET LOCAL enable_bitmapscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_bitmapscan TO ON" +== 232 +-- truncate_limit: 100 +EXPLAIN (COSTS off) SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_last_scan WHERE idx_col = 1" +== 233 +-- truncate_limit: 100 +SELECT count(*) FROM test_last_scan WHERE idx_col = 1 +-- +TABLE: name="test_last_scan" schema="" table="test_last_scan" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="idx_col" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_last_scan WHERE idx_col = 1" +== 234 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 235 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 236 +-- truncate_limit: 100 +-- check that just index scan stats were incremented +SELECT seq_scan, :'test_last_seq' = last_seq_scan AS seq_ok, idx_scan, :'test_last_idx' < last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass +-- +ERROR: syntax error at or near ":" +CURSORPOS: 71 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 237 +-- truncate_limit: 100 +----- +-- Test reset of some stats for shared table +----- + +-- This updates the comment of the database currently in use in +-- pg_shdescription with a fake value, then sets it back to its +-- original value. +SELECT shobj_description(d.oid, 'pg_database') as description_before + FROM pg_database d WHERE datname = current_database() +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=Select +ALIAS: "d"="pg_database" +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FUNCTION: name="shobj_description" function="shobj_description" schema="" ctx=Call +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_database d WHERE datname = current_database()" +== 238 +-- truncate_limit: 100 +-- force some stats in pg_shdescription. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 239 +-- truncate_limit: 100 +SELECT current_database() as datname +-- +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT current_database() AS datname" +== 240 +-- truncate_limit: 100 +COMMENT ON DATABASE :"datname" IS 'This is a test comment' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 241 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 242 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 243 +-- truncate_limit: 100 +-- check that the stats are reset. +SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables + WHERE relid = 'pg_shdescription'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_all_tables WHERE relid = 'pg_shdescription'::regclass" +== 244 +-- truncate_limit: 100 +SELECT pg_stat_reset_single_table_counters('pg_shdescription'::regclass) +-- +FUNCTION: name="pg_stat_reset_single_table_counters" function="pg_stat_reset_single_table_counters" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_single_table_counters('pg_shdescription'::regclass)" +== 245 +-- truncate_limit: 100 +SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables + WHERE relid = 'pg_shdescription'::regclass +-- +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +FILTER: schema="" table="" column="relid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_all_tables WHERE relid = 'pg_shdescription'::regclass" +== 246 +-- truncate_limit: 100 +-- set back comment + COMMENT ON DATABASE :"datname" IS :'description_before' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 43 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 247 +-- truncate_limit: 100 +COMMENT ON DATABASE :"datname" IS NULL +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 248 +-- truncate_limit: 100 +----- +-- Test that various stats views are being properly populated +----- + +-- Test that sessions is incremented when a new session is started in pg_stat_database +SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +TABLE: name="pg_stat_database" schema="" table="pg_stat_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +TRUNCATED: "SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT ...)" +== 249 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 250 +-- truncate_limit: 100 +SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 251 +-- truncate_limit: 100 +-- Test pg_stat_checkpointer checkpointer-related stats, together with pg_stat_wal +SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer +-- +TABLE: name="pg_stat_checkpointer" schema="" table="pg_stat_checkpointer" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer" +== 252 +-- truncate_limit: 100 +-- Test pg_stat_wal (and make a temp table so our temp schema exists) +SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal +-- +TABLE: name="pg_stat_wal" schema="" table="pg_stat_wal" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal" +== 253 +-- truncate_limit: 100 +CREATE TEMP TABLE test_stats_temp AS SELECT 17 +-- +TABLE: name="test_stats_temp" schema="" table="test_stats_temp" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_stats_temp AS SELECT 17" +== 254 +-- truncate_limit: 100 +DROP TABLE test_stats_temp +-- +TABLE: name="test_stats_temp" schema="" table="test_stats_temp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_stats_temp" +== 255 +-- truncate_limit: 100 +-- Checkpoint twice: The checkpointer reports stats after reporting completion +-- of the checkpoint. But after a second checkpoint we'll see at least the +-- results of the first. +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 256 +-- truncate_limit: 100 +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 257 +-- truncate_limit: 100 +SELECT num_requested > :rqst_ckpts_before FROM pg_stat_checkpointer +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 258 +-- truncate_limit: 100 +SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 259 +-- truncate_limit: 100 +-- Test pg_stat_get_backend_idset() and some allied functions. +-- In particular, verify that their notion of backend ID matches +-- our temp schema index. +SELECT (current_schemas(true))[1] = ('pg_temp_' || beid::text) AS match +FROM pg_stat_get_backend_idset() beid +WHERE pg_stat_get_backend_pid(beid) = pg_backend_pid() +-- +FUNCTION: name="pg_stat_get_backend_pid" function="pg_stat_get_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="current_schemas" function="current_schemas" schema="" ctx=Call +FUNCTION: name="pg_stat_get_backend_idset" function="pg_stat_get_backend_idset" schema="" ctx=Call +FUNCTION: name="pg_stat_get_backend_pid" function="pg_stat_get_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="beid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_get_backend_idset() beid WHERE ..." +== 260 +-- truncate_limit: 100 +----- +-- Test that resetting stats works for reset timestamp +----- + +-- Test that reset_slru with a specified SLRU works. +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp'" +== 261 +-- truncate_limit: 100 +SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'notify' +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'notify'" +== 262 +-- truncate_limit: 100 +SELECT pg_stat_reset_slru('commit_timestamp') +-- +FUNCTION: name="pg_stat_reset_slru" function="pg_stat_reset_slru" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_slru('commit_timestamp')" +== 263 +-- truncate_limit: 100 +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 264 +-- truncate_limit: 100 +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp'" +== 265 +-- truncate_limit: 100 +-- Test that multiple SLRUs are reset when no specific SLRU provided to reset function +SELECT pg_stat_reset_slru() +-- +FUNCTION: name="pg_stat_reset_slru" function="pg_stat_reset_slru" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_slru()" +== 266 +-- truncate_limit: 100 +SELECT stats_reset > :'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'commit_timestamp' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 267 +-- truncate_limit: 100 +SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'notify' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 268 +-- truncate_limit: 100 +-- Test that reset_shared with archiver specified as the stats type works +SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver +-- +TABLE: name="pg_stat_archiver" schema="" table="pg_stat_archiver" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver" +== 269 +-- truncate_limit: 100 +SELECT pg_stat_reset_shared('archiver') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('archiver')" +== 270 +-- truncate_limit: 100 +SELECT stats_reset > :'archiver_reset_ts'::timestamptz FROM pg_stat_archiver +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 271 +-- truncate_limit: 100 +-- Test that reset_shared with bgwriter specified as the stats type works +SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter +-- +TABLE: name="pg_stat_bgwriter" schema="" table="pg_stat_bgwriter" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter" +== 272 +-- truncate_limit: 100 +SELECT pg_stat_reset_shared('bgwriter') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('bgwriter')" +== 273 +-- truncate_limit: 100 +SELECT stats_reset > :'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 274 +-- truncate_limit: 100 +-- Test that reset_shared with checkpointer specified as the stats type works +SELECT stats_reset AS checkpointer_reset_ts FROM pg_stat_checkpointer +-- +TABLE: name="pg_stat_checkpointer" schema="" table="pg_stat_checkpointer" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS checkpointer_reset_ts FROM pg_stat_checkpointer" +== 275 +-- truncate_limit: 100 +SELECT pg_stat_reset_shared('checkpointer') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('checkpointer')" +== 276 +-- truncate_limit: 100 +SELECT stats_reset > :'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpointer +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 277 +-- truncate_limit: 100 +-- Test that reset_shared with recovery_prefetch specified as the stats type works +SELECT stats_reset AS recovery_prefetch_reset_ts FROM pg_stat_recovery_prefetch +-- +TABLE: name="pg_stat_recovery_prefetch" schema="" table="pg_stat_recovery_prefetch" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS recovery_prefetch_reset_ts FROM pg_stat_recovery_prefetch" +== 278 +-- truncate_limit: 100 +SELECT pg_stat_reset_shared('recovery_prefetch') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('recovery_prefetch')" +== 279 +-- truncate_limit: 100 +SELECT stats_reset > :'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_recovery_prefetch +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 280 +-- truncate_limit: 100 +-- Test that reset_shared with slru specified as the stats type works +SELECT max(stats_reset) AS slru_reset_ts FROM pg_stat_slru +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(stats_reset) AS slru_reset_ts FROM pg_stat_slru" +== 281 +-- truncate_limit: 100 +SELECT pg_stat_reset_shared('slru') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('slru')" +== 282 +-- truncate_limit: 100 +SELECT max(stats_reset) > :'slru_reset_ts'::timestamptz FROM pg_stat_slru +-- +ERROR: syntax error at or near ":" +CURSORPOS: 27 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 283 +-- truncate_limit: 100 +-- Test that reset_shared with wal specified as the stats type works +SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal +-- +TABLE: name="pg_stat_wal" schema="" table="pg_stat_wal" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal" +== 284 +-- truncate_limit: 100 +SELECT pg_stat_reset_shared('wal') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('wal')" +== 285 +-- truncate_limit: 100 +SELECT stats_reset > :'wal_reset_ts'::timestamptz FROM pg_stat_wal +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 286 +-- truncate_limit: 100 +-- Test error case for reset_shared with unknown stats type +SELECT pg_stat_reset_shared('unknown') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('unknown')" +== 287 +-- truncate_limit: 100 +-- Test that reset works for pg_stat_database + +-- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to +SELECT pg_stat_reset() +-- +FUNCTION: name="pg_stat_reset" function="pg_stat_reset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset()" +== 288 +-- truncate_limit: 100 +SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +TABLE: name="pg_stat_database" schema="" table="pg_stat_database" ctx=Select +FUNCTION: name="current_database" function="current_database" schema="" ctx=Call +FILTER: schema="" table="" column="datname" +STMT: SelectStmt +TRUNCATED: "SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database())" +== 289 +-- truncate_limit: 100 +SELECT pg_stat_reset() +-- +FUNCTION: name="pg_stat_reset" function="pg_stat_reset" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset()" +== 290 +-- truncate_limit: 100 +SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database()) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 291 +-- truncate_limit: 100 +---- +-- pg_stat_get_snapshot_timestamp behavior +---- +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 292 +-- truncate_limit: 100 +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL stats_fetch_consistency TO snapshot" +== 293 +-- truncate_limit: 100 +-- no snapshot yet, return NULL +SELECT pg_stat_get_snapshot_timestamp() +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp()" +== 294 +-- truncate_limit: 100 +-- any attempt at accessing stats will build snapshot +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_function_calls(0)" +== 295 +-- truncate_limit: 100 +SELECT pg_stat_get_snapshot_timestamp() >= NOW() +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp() >= now()" +== 296 +-- truncate_limit: 100 +-- shows NULL again after clearing +SELECT pg_stat_clear_snapshot() +-- +FUNCTION: name="pg_stat_clear_snapshot" function="pg_stat_clear_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_clear_snapshot()" +== 297 +-- truncate_limit: 100 +SELECT pg_stat_get_snapshot_timestamp() +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp()" +== 298 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 299 +-- truncate_limit: 100 +---- +-- Changing stats_fetch_consistency in a transaction. +---- +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 300 +-- truncate_limit: 100 +-- Stats filled under the cache mode +SET LOCAL stats_fetch_consistency = cache +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL stats_fetch_consistency TO cache" +== 301 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_function_calls(0)" +== 302 +-- truncate_limit: 100 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok" +== 303 +-- truncate_limit: 100 +-- Success in accessing pre-existing snapshot data. +SET LOCAL stats_fetch_consistency = snapshot +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL stats_fetch_consistency TO snapshot" +== 304 +-- truncate_limit: 100 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok" +== 305 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_function_calls(0)" +== 306 +-- truncate_limit: 100 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok" +== 307 +-- truncate_limit: 100 +-- Snapshot cleared. +SET LOCAL stats_fetch_consistency = none +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL stats_fetch_consistency TO \"none\"" +== 308 +-- truncate_limit: 100 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok" +== 309 +-- truncate_limit: 100 +SELECT pg_stat_get_function_calls(0) +-- +FUNCTION: name="pg_stat_get_function_calls" function="pg_stat_get_function_calls" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_function_calls(0)" +== 310 +-- truncate_limit: 100 +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok +-- +FUNCTION: name="pg_stat_get_snapshot_timestamp" function="pg_stat_get_snapshot_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok" +== 311 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 312 +-- truncate_limit: 100 +---- +-- pg_stat_have_stats behavior +---- +-- fixed-numbered stats exist +SELECT pg_stat_have_stats('bgwriter', 0, 0) +-- +FUNCTION: name="pg_stat_have_stats" function="pg_stat_have_stats" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_have_stats('bgwriter', 0, 0)" +== 313 +-- truncate_limit: 100 +-- unknown stats kinds error out +SELECT pg_stat_have_stats('zaphod', 0, 0) +-- +FUNCTION: name="pg_stat_have_stats" function="pg_stat_have_stats" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_have_stats('zaphod', 0, 0)" +== 314 +-- truncate_limit: 100 +-- db stats have objoid 0 +SELECT pg_stat_have_stats('database', :dboid, 1) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 315 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('database', :dboid, 0) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 316 +-- truncate_limit: 100 +-- pg_stat_have_stats returns true for committed index creation +CREATE table stats_test_tab1 as select generate_series(1,10) a +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE stats_test_tab1 AS SELECT generate_series(1, 10) AS a" +== 317 +-- truncate_limit: 100 +CREATE index stats_test_idx1 on stats_test_tab1(a) +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX stats_test_idx1 ON stats_test_tab1 USING btree (a)" +== 318 +-- truncate_limit: 100 +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid" +== 319 +-- truncate_limit: 100 +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 320 +-- truncate_limit: 100 +select a from stats_test_tab1 where a = 3 +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM stats_test_tab1 WHERE a = 3" +== 321 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 322 +-- truncate_limit: 100 +-- pg_stat_have_stats returns false for dropped index with stats +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 104 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 323 +-- truncate_limit: 100 +DROP index stats_test_idx1 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX stats_test_idx1" +== 324 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 325 +-- truncate_limit: 100 +-- pg_stat_have_stats returns false for rolled back index creation +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 326 +-- truncate_limit: 100 +CREATE index stats_test_idx1 on stats_test_tab1(a) +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX stats_test_idx1 ON stats_test_tab1 USING btree (a)" +== 327 +-- truncate_limit: 100 +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid" +== 328 +-- truncate_limit: 100 +select a from stats_test_tab1 where a = 3 +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM stats_test_tab1 WHERE a = 3" +== 329 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 330 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 331 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 332 +-- truncate_limit: 100 +-- pg_stat_have_stats returns true for reindex CONCURRENTLY +CREATE index stats_test_idx1 on stats_test_tab1(a) +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX stats_test_idx1 ON stats_test_tab1 USING btree (a)" +== 333 +-- truncate_limit: 100 +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid" +== 334 +-- truncate_limit: 100 +select a from stats_test_tab1 where a = 3 +-- +TABLE: name="stats_test_tab1" schema="" table="stats_test_tab1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM stats_test_tab1 WHERE a = 3" +== 335 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 336 +-- truncate_limit: 100 +REINDEX index CONCURRENTLY stats_test_idx1 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (CONCURRENTLY) INDEX stats_test_idx1" +== 337 +-- truncate_limit: 100 +-- false for previous oid +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 65 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 338 +-- truncate_limit: 100 +-- true for new oid +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid" +== 339 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 340 +-- truncate_limit: 100 +-- pg_stat_have_stats returns true for a rolled back drop index with stats +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 341 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 342 +-- truncate_limit: 100 +DROP index stats_test_idx1 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX stats_test_idx1" +== 343 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 344 +-- truncate_limit: 100 +SELECT pg_stat_have_stats('relation', :dboid, :stats_test_idx1_oid) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 39 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 345 +-- truncate_limit: 100 +-- put enable_seqscan back to on +SET enable_seqscan TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 346 +-- truncate_limit: 100 +-- ensure that stats accessors handle NULL input correctly +SELECT pg_stat_get_replication_slot(NULL) +-- +FUNCTION: name="pg_stat_get_replication_slot" function="pg_stat_get_replication_slot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_replication_slot(NULL)" +== 347 +-- truncate_limit: 100 +SELECT pg_stat_get_subscription_stats(NULL) +-- +FUNCTION: name="pg_stat_get_subscription_stats" function="pg_stat_get_subscription_stats" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_subscription_stats(NULL)" +== 348 +-- truncate_limit: 100 +-- Test that the following operations are tracked in pg_stat_io: +-- - reads of target blocks into shared buffers +-- - writes of shared buffers to permanent storage +-- - extends of relations using shared buffers +-- - fsyncs done to ensure the durability of data dirtying shared buffers +-- - shared buffer hits + +-- There is no test for blocks evicted from shared buffers, because we cannot +-- be sure of the state of shared buffers at the point the test is run. + +-- Create a regular table and insert some data to generate IOCONTEXT_NORMAL +-- extends. +SELECT sum(extends) AS io_sum_shared_before_extends + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'normal' AND object = 'relation'" +== 349 +-- truncate_limit: 100 +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs FROM pg_stat_io WHERE object = 'relation'" +== 350 +-- truncate_limit: 100 +CREATE TABLE test_io_shared(a int) +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_io_shared (a int)" +== 351 +-- truncate_limit: 100 +INSERT INTO test_io_shared SELECT i FROM generate_series(1,100)i +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_io_shared SELECT i FROM generate_series(1, 100) i" +== 352 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 353 +-- truncate_limit: 100 +SELECT sum(extends) AS io_sum_shared_after_extends + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'normal' AND object = 'relation'" +== 354 +-- truncate_limit: 100 +SELECT :io_sum_shared_after_extends > :io_sum_shared_before_extends +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 355 +-- truncate_limit: 100 +-- After a checkpoint, there should be some additional IOCONTEXT_NORMAL writes +-- and fsyncs. +-- See comment above for rationale for two explicit CHECKPOINTs. +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 356 +-- truncate_limit: 100 +CHECKPOINT +-- +STMT: CheckPointStmt +TRUNCATED: "CHECKPOINT" +== 357 +-- truncate_limit: 100 +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs FROM pg_stat_io WHERE object = 'relation'" +== 358 +-- truncate_limit: 100 +SELECT :io_sum_shared_after_writes > :io_sum_shared_before_writes +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 359 +-- truncate_limit: 100 +SELECT current_setting('fsync') = 'off' + OR :io_sum_shared_after_fsyncs > :io_sum_shared_before_fsyncs +-- +ERROR: syntax error at or near ":" +CURSORPOS: 46 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 360 +-- truncate_limit: 100 +-- Change the tablespace so that the table is rewritten directly, then SELECT +-- from it to cause it to be read back into shared buffers. +SELECT sum(reads) AS io_sum_shared_before_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(reads) AS io_sum_shared_before_reads FROM pg_stat_io WHERE ..." +== 361 +-- truncate_limit: 100 +-- Do this in a transaction to prevent spurious failures due to concurrent accesses to our newly +-- rewritten table, e.g. by autovacuum. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 362 +-- truncate_limit: 100 +ALTER TABLE test_io_shared SET TABLESPACE regress_tblspace +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_io_shared SET TABLESPACE regress_tblspace" +== 363 +-- truncate_limit: 100 +-- SELECT from the table so that the data is read into shared buffers and +-- context 'normal', object 'relation' reads are counted. +SELECT COUNT(*) FROM test_io_shared +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_io_shared" +== 364 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 365 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 366 +-- truncate_limit: 100 +SELECT sum(reads) AS io_sum_shared_after_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(reads) AS io_sum_shared_after_reads FROM pg_stat_io WHERE ..." +== 367 +-- truncate_limit: 100 +SELECT :io_sum_shared_after_reads > :io_sum_shared_before_reads +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 368 +-- truncate_limit: 100 +SELECT sum(hits) AS io_sum_shared_before_hits + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(hits) AS io_sum_shared_before_hits FROM pg_stat_io WHERE ..." +== 369 +-- truncate_limit: 100 +-- Select from the table again to count hits. +-- Ensure we generate hits by forcing a nested loop self-join with no +-- materialize node. The outer side's buffer will stay pinned, preventing its +-- eviction, while we loop through the inner side and generate hits. +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 370 +-- truncate_limit: 100 +SET LOCAL enable_nestloop TO on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_nestloop TO ON" +== 371 +-- truncate_limit: 100 +SET LOCAL enable_mergejoin TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_mergejoin TO OFF" +== 372 +-- truncate_limit: 100 +SET LOCAL enable_hashjoin TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_hashjoin TO OFF" +== 373 +-- truncate_limit: 100 +SET LOCAL enable_material TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_material TO OFF" +== 374 +-- truncate_limit: 100 +-- ensure plan stays as we expect it to +EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM test_io_shared t1 INNER JOIN test_io_shared t2 USING (a) +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +ALIAS: "t1"="test_io_shared" +ALIAS: "t2"="test_io_shared" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_io_shared t1 JOIN test_io_shared t2 USING (a)" +== 375 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_io_shared t1 INNER JOIN test_io_shared t2 USING (a) +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=Select +ALIAS: "t1"="test_io_shared" +ALIAS: "t2"="test_io_shared" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_io_shared t1 JOIN test_io_shared t2 USING (a)" +== 376 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 377 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 378 +-- truncate_limit: 100 +SELECT sum(hits) AS io_sum_shared_after_hits + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(hits) AS io_sum_shared_after_hits FROM pg_stat_io WHERE ..." +== 379 +-- truncate_limit: 100 +SELECT :io_sum_shared_after_hits > :io_sum_shared_before_hits +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 380 +-- truncate_limit: 100 +DROP TABLE test_io_shared +-- +TABLE: name="test_io_shared" schema="" table="test_io_shared" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE test_io_shared" +== 381 +-- truncate_limit: 100 +-- Test that the follow IOCONTEXT_LOCAL IOOps are tracked in pg_stat_io: +-- - eviction of local buffers in order to reuse them +-- - reads of temporary table blocks into local buffers +-- - writes of local buffers to permanent storage +-- - extends of temporary tables + +-- Set temp_buffers to its minimum so that we can trigger writes with fewer +-- inserted tuples. Do so in a new session in case temporary tables have been +-- accessed by previous tests in this session. +SET temp_buffers TO 100 +-- +STMT: VariableSetStmt +TRUNCATED: "SET temp_buffers TO 100" +== 382 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE test_io_local(a int, b TEXT) +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_io_local (a int, b text)" +== 383 +-- truncate_limit: 100 +SELECT sum(extends) AS extends, sum(evictions) AS evictions, sum(writes) AS writes + FROM pg_stat_io + WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation'" +== 384 +-- truncate_limit: 100 +-- Insert tuples into the temporary table, generating extends in the stats. +-- Insert enough values that we need to reuse and write out dirty local +-- buffers, generating evictions and writes. +INSERT INTO test_io_local SELECT generate_series(1, 5000) as id, repeat('a', 200) +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_io_local SELECT generate_series(1, 5000) AS id, repeat('a', 200)" +== 385 +-- truncate_limit: 100 +-- Ensure the table is large enough to exceed our temp_buffers setting. +SELECT pg_relation_size('test_io_local') / current_setting('block_size')::int8 > 100 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (pg_relation_size('test_io_local') / current_setting('block_size')::int8) > 100" +== 386 +-- truncate_limit: 100 +SELECT sum(reads) AS io_sum_local_before_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(reads) AS io_sum_local_before_reads FROM pg_stat_io WHERE ..." +== 387 +-- truncate_limit: 100 +-- Read in evicted buffers, generating reads. +SELECT COUNT(*) FROM test_io_local +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_io_local" +== 388 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 389 +-- truncate_limit: 100 +SELECT sum(evictions) AS evictions, + sum(reads) AS reads, + sum(writes) AS writes, + sum(extends) AS extends + FROM pg_stat_io + WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation'" +== 390 +-- truncate_limit: 100 +SELECT :io_sum_local_after_evictions > :io_sum_local_before_evictions, + :io_sum_local_after_reads > :io_sum_local_before_reads, + :io_sum_local_after_writes > :io_sum_local_before_writes, + :io_sum_local_after_extends > :io_sum_local_before_extends +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 391 +-- truncate_limit: 100 +-- Change the tablespaces so that the temporary table is rewritten to other +-- local buffers, exercising a different codepath than standard local buffer +-- writes. +ALTER TABLE test_io_local SET TABLESPACE regress_tblspace +-- +TABLE: name="test_io_local" schema="" table="test_io_local" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_io_local SET TABLESPACE regress_tblspace" +== 392 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 393 +-- truncate_limit: 100 +SELECT sum(writes) AS io_sum_local_new_tblspc_writes + FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +FILTER: schema="" table="" column="object" +STMT: SelectStmt +TRUNCATED: "SELECT sum(writes) AS io_sum_local_new_tblspc_writes FROM pg_stat_io WHERE ..." +== 394 +-- truncate_limit: 100 +SELECT :io_sum_local_new_tblspc_writes > :io_sum_local_after_writes +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 395 +-- truncate_limit: 100 +RESET temp_buffers +-- +STMT: VariableSetStmt +TRUNCATED: "RESET temp_buffers" +== 396 +-- truncate_limit: 100 +-- Test that reuse of strategy buffers and reads of blocks into these reused +-- buffers while VACUUMing are tracked in pg_stat_io. If there is sufficient +-- demand for shared buffers from concurrent queries, some buffers may be +-- pinned by other backends before they can be reused. In such cases, the +-- backend will evict a buffer from outside the ring and add it to the +-- ring. This is considered an eviction and not a reuse. + +-- Set wal_skip_threshold smaller than the expected size of +-- test_io_vac_strategy so that, even if wal_level is minimal, VACUUM FULL will +-- fsync the newly rewritten test_io_vac_strategy instead of writing it to WAL. +-- Writing it to WAL will result in the newly written relation pages being in +-- shared buffers -- preventing us from testing BAS_VACUUM BufferAccessStrategy +-- reads. +SET wal_skip_threshold = '1 kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET wal_skip_threshold TO \"1 kB\"" +== 397 +-- truncate_limit: 100 +SELECT sum(reuses) AS reuses, sum(reads) AS reads, sum(evictions) AS evictions + FROM pg_stat_io WHERE context = 'vacuum' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'vacuum'" +== 398 +-- truncate_limit: 100 +CREATE TABLE test_io_vac_strategy(a int, b int) WITH (autovacuum_enabled = 'false') +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_io_vac_strategy (a int, b int) WITH (autovacuum_enabled=false)" +== 399 +-- truncate_limit: 100 +INSERT INTO test_io_vac_strategy SELECT i, i from generate_series(1, 4500)i +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_io_vac_strategy SELECT i, i FROM generate_series(1, 4500) i" +== 400 +-- truncate_limit: 100 +-- Ensure that the next VACUUM will need to perform IO by rewriting the table +-- first with VACUUM (FULL). +VACUUM (FULL) test_io_vac_strategy +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) test_io_vac_strategy" +== 401 +-- truncate_limit: 100 +-- Use the minimum BUFFER_USAGE_LIMIT to cause reuses or evictions with the +-- smallest table possible. +VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) test_io_vac_strategy +-- +TABLE: name="test_io_vac_strategy" schema="" table="test_io_vac_strategy" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) test_io_vac_strategy" +== 402 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 403 +-- truncate_limit: 100 +SELECT sum(reuses) AS reuses, sum(reads) AS reads, sum(evictions) AS evictions + FROM pg_stat_io WHERE context = 'vacuum' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'vacuum'" +== 404 +-- truncate_limit: 100 +SELECT :io_sum_vac_strategy_after_reads > :io_sum_vac_strategy_before_reads +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 405 +-- truncate_limit: 100 +SELECT (:io_sum_vac_strategy_after_reuses + :io_sum_vac_strategy_after_evictions) > + (:io_sum_vac_strategy_before_reuses + :io_sum_vac_strategy_before_evictions) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 406 +-- truncate_limit: 100 +RESET wal_skip_threshold +-- +STMT: VariableSetStmt +TRUNCATED: "RESET wal_skip_threshold" +== 407 +-- truncate_limit: 100 +-- Test that extends done by a CTAS, which uses a BAS_BULKWRITE +-- BufferAccessStrategy, are tracked in pg_stat_io. +SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_before + FROM pg_stat_io WHERE context = 'bulkwrite' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'bulkwrite'" +== 408 +-- truncate_limit: 100 +CREATE TABLE test_io_bulkwrite_strategy AS SELECT i FROM generate_series(1,100)i +-- +TABLE: name="test_io_bulkwrite_strategy" schema="" table="test_io_bulkwrite_strategy" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test_io_bulkwrite_strategy AS SELECT i FROM generate_series(1, 100) i" +== 409 +-- truncate_limit: 100 +SELECT pg_stat_force_next_flush() +-- +FUNCTION: name="pg_stat_force_next_flush" function="pg_stat_force_next_flush" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_force_next_flush()" +== 410 +-- truncate_limit: 100 +SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_after + FROM pg_stat_io WHERE context = 'bulkwrite' +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="context" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io WHERE context = 'bulkwrite'" +== 411 +-- truncate_limit: 100 +SELECT :io_sum_bulkwrite_strategy_extends_after > :io_sum_bulkwrite_strategy_extends_before +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 412 +-- truncate_limit: 100 +-- Test IO stats reset +SELECT pg_stat_have_stats('io', 0, 0) +-- +FUNCTION: name="pg_stat_have_stats" function="pg_stat_have_stats" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_have_stats('io', 0, 0)" +== 413 +-- truncate_limit: 100 +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS io_stats_pre_reset + FROM pg_stat_io +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io" +== 414 +-- truncate_limit: 100 +SELECT pg_stat_reset_shared('io') +-- +FUNCTION: name="pg_stat_reset_shared" function="pg_stat_reset_shared" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_shared('io')" +== 415 +-- truncate_limit: 100 +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS io_stats_post_reset + FROM pg_stat_io +-- +TABLE: name="pg_stat_io" schema="" table="pg_stat_io" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_io" +== 416 +-- truncate_limit: 100 +SELECT :io_stats_post_reset < :io_stats_pre_reset +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 417 +-- truncate_limit: 100 +-- test BRIN index doesn't block HOT update +CREATE TABLE brin_hot ( + id integer PRIMARY KEY, + val integer NOT NULL +) WITH (autovacuum_enabled = off, fillfactor = 70) +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_hot (id int PRIMARY KEY, val int NOT NULL) WITH (autovacuum_enabled=off, fillfa..." +== 418 +-- truncate_limit: 100 +INSERT INTO brin_hot SELECT *, 0 FROM generate_series(1, 235) +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_hot SELECT *, 0 FROM generate_series(1, 235)" +== 419 +-- truncate_limit: 100 +CREATE INDEX val_brin ON brin_hot using brin(val) +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX val_brin ON brin_hot USING brin (val)" +== 420 +-- truncate_limit: 100 +CREATE FUNCTION wait_for_hot_stats() RETURNS void AS $$ +DECLARE + start_time timestamptz := clock_timestamp(); + updated bool; +BEGIN + -- we don't want to wait forever; loop will exit after 30 seconds + FOR i IN 1 .. 300 LOOP + SELECT (pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid) > 0) INTO updated; + EXIT WHEN updated; + + -- wait a little + PERFORM pg_sleep_for('100 milliseconds'); + -- reset stats snapshot so we can test again + PERFORM pg_stat_clear_snapshot(); + END LOOP; + -- report time waited in postmaster log (where it won't change test output) + RAISE log 'wait_for_hot_stats delayed % seconds', + EXTRACT(epoch FROM clock_timestamp() - start_time); +END +$$ LANGUAGE plpgsql +-- +FUNCTION: name="wait_for_hot_stats" function="wait_for_hot_stats" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION wait_for_hot_stats() RETURNS void AS $$\nDECLARE\n start_time timestamptz := clock..." +== 421 +-- truncate_limit: 100 +UPDATE brin_hot SET val = -3 WHERE id = 42 +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brin_hot SET val = -3 WHERE id = 42" +== 422 +-- truncate_limit: 100 +-- We can't just call wait_for_hot_stats() at this point, because we only +-- transmit stats when the session goes idle, and we probably didn't +-- transmit the last couple of counts yet thanks to the rate-limiting logic +-- in pgstat_report_stat(). But instead of waiting for the rate limiter's +-- timeout to elapse, let's just start a new session. The old one will +-- then send its stats before dying. + +SELECT wait_for_hot_stats() +-- +FUNCTION: name="wait_for_hot_stats" function="wait_for_hot_stats" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT wait_for_hot_stats()" +== 423 +-- truncate_limit: 100 +SELECT pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid) +-- +FUNCTION: name="pg_stat_get_tuples_hot_updated" function="pg_stat_get_tuples_hot_updated" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid)" +== 424 +-- truncate_limit: 100 +DROP TABLE brin_hot +-- +TABLE: name="brin_hot" schema="" table="brin_hot" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_hot" +== 425 +-- truncate_limit: 100 +DROP FUNCTION wait_for_hot_stats() +-- +FUNCTION: name="wait_for_hot_stats" function="wait_for_hot_stats" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION wait_for_hot_stats()" +== 426 +-- truncate_limit: 100 +-- Test handling of index predicates - updating attributes in precicates +-- should not block HOT when summarizing indexes are involved. We update +-- a row that was not indexed due to the index predicate, and becomes +-- indexable - the HOT-updated tuple is forwarded to the BRIN index. +CREATE TABLE brin_hot_2 (a int, b int) +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_hot_2 (a int, b int)" +== 427 +-- truncate_limit: 100 +INSERT INTO brin_hot_2 VALUES (1, 100) +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_hot_2 VALUES (1, 100)" +== 428 +-- truncate_limit: 100 +CREATE INDEX ON brin_hot_2 USING brin (b) WHERE a = 2 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_hot_2 USING brin (b) WHERE a = 2" +== 429 +-- truncate_limit: 100 +UPDATE brin_hot_2 SET a = 2 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brin_hot_2 SET a = 2" +== 430 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100" +== 431 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_hot_2 WHERE a = 2 AND b = 100" +== 432 +-- truncate_limit: 100 +SET enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 433 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100" +== 434 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_hot_2 WHERE a = 2 AND b = 100" +== 435 +-- truncate_limit: 100 +DROP TABLE brin_hot_2 +-- +TABLE: name="brin_hot_2" schema="" table="brin_hot_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_hot_2" +== 436 +-- truncate_limit: 100 +-- Test that updates to indexed columns are still propagated to the +-- BRIN column. +-- https://postgr.es/m/05ebcb44-f383-86e3-4f31-0a97a55634cf@enterprisedb.com +CREATE TABLE brin_hot_3 (a int, filler text) WITH (fillfactor = 10) +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE brin_hot_3 (a int, filler text) WITH (fillfactor=10)" +== 437 +-- truncate_limit: 100 +INSERT INTO brin_hot_3 SELECT 1, repeat(' ', 500) FROM generate_series(1, 20) +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO brin_hot_3 SELECT 1, repeat(' ', 500) FROM generate_series(1, 20)" +== 438 +-- truncate_limit: 100 +CREATE INDEX ON brin_hot_3 USING brin (a) WITH (pages_per_range = 1) +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON brin_hot_3 USING brin (a) WITH (pages_per_range=1)" +== 439 +-- truncate_limit: 100 +UPDATE brin_hot_3 SET a = 2 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE brin_hot_3 SET a = 2" +== 440 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_3 WHERE a = 2 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM brin_hot_3 WHERE a = 2" +== 441 +-- truncate_limit: 100 +SELECT COUNT(*) FROM brin_hot_3 WHERE a = 2 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM brin_hot_3 WHERE a = 2" +== 442 +-- truncate_limit: 100 +DROP TABLE brin_hot_3 +-- +TABLE: name="brin_hot_3" schema="" table="brin_hot_3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE brin_hot_3" +== 443 +-- truncate_limit: 100 +SET enable_seqscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 444 +-- truncate_limit: 100 +-- Test that estimation of relation size works with tuples wider than the +-- relation fillfactor. We create a table with wide inline attributes and +-- low fillfactor, insert rows and then see how many rows EXPLAIN shows +-- before running analyze. We disable autovacuum so that it does not +-- interfere with the test. +CREATE TABLE table_fillfactor ( + n char(1000) +) with (fillfactor=10, autovacuum_enabled=off) +-- +TABLE: name="table_fillfactor" schema="" table="table_fillfactor" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE table_fillfactor (n char(1000)) WITH (fillfactor=10, autovacuum_enabled=off)" +== 445 +-- truncate_limit: 100 +INSERT INTO table_fillfactor +SELECT 'x' FROM generate_series(1,1000) +-- +TABLE: name="table_fillfactor" schema="" table="table_fillfactor" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO table_fillfactor SELECT 'x' FROM generate_series(1, 1000)" +== 446 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM table_fillfactor') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM table_fillfactor')" +== 447 +-- truncate_limit: 100 +DROP TABLE table_fillfactor +-- +TABLE: name="table_fillfactor" schema="" table="table_fillfactor" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE table_fillfactor" diff --git a/parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json b/parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json new file mode 100644 index 0000000..b2f6706 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json @@ -0,0 +1,820 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/stats_ext.test b/parser/testdata/summary_truncate/postgres_regress/stats_ext.test new file mode 100644 index 0000000..4d36ae9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/stats_ext.test @@ -0,0 +1,6196 @@ +== 001 +-- truncate_limit: 100 +-- Generic extended statistics support + +|-- +-- Note: tables for which we check estimated row counts should be created +-- with autovacuum_enabled = off, so that we don't have unstable results +-- from auto-analyze happening when we didn't expect it. +|-- + +-- check the number of estimated/actual rows in the top node +create function check_estimated_rows(text) returns table (estimated int, actual int) +language plpgsql as +$$ +declare + ln text; + tmp text[]; + first_row bool := true; +begin + for ln in + execute format('explain analyze %s', $1) + loop + if first_row then + first_row := false; + tmp := regexp_match(ln, 'rows=(\d*) .* rows=(\d*)'); + return query select tmp[1]::int, tmp[2]::int; + end if; + end loop; +end; +$$ +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION check_estimated_rows(text) RETURNS TABLE (estimated int, actual int) LANGUAGE plp..." +== 002 +-- truncate_limit: 100 +-- Verify failures +CREATE TABLE ext_stats_test (x text, y int, z int) +-- +TABLE: name="ext_stats_test" schema="" table="ext_stats_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ext_stats_test (x text, y int, z int)" +== 003 +-- truncate_limit: 100 +CREATE STATISTICS tst +-- +ERROR: syntax error at end of input +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a, b +-- +ERROR: syntax error at end of input +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- truncate_limit: 100 +CREATE STATISTICS tst FROM sometab +-- +ERROR: syntax error at or near "FROM" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a, b FROM nonexistent +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a, b FROM nonexistent" +== 007 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a, b FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a, b FROM ext_stats_test" +== 008 +-- truncate_limit: 100 +CREATE STATISTICS tst ON x, x, y FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON x, x, y FROM ext_stats_test" +== 009 +-- truncate_limit: 100 +CREATE STATISTICS tst ON x, x, y, x, x, y, x, x, y FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON x, x, y, x, x, y, x, x, y FROM ext_stats_test" +== 010 +-- truncate_limit: 100 +CREATE STATISTICS tst ON x, x, y, x, x, (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1) FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON x, x, y, x, x, (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1) FROM..." +== 011 +-- truncate_limit: 100 +CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1) FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1), (x || ..." +== 012 +-- truncate_limit: 100 +CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), y FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), y FROM ext_stats_test" +== 013 +-- truncate_limit: 100 +CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test" +== 014 +-- truncate_limit: 100 +-- unsupported targets +CREATE STATISTICS tst ON a FROM (VALUES (x)) AS foo +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a FROM (VALUES (x)) foo" +== 015 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a FROM foo NATURAL JOIN bar +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a FROM foo NATURAL JOIN bar" +== 016 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a FROM (SELECT * FROM ext_stats_test) AS foo +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a FROM (SELECT * FROM ext_stats_test) foo" +== 017 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a FROM ext_stats_test s TABLESAMPLE system (x) +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a FROM ext_stats_test s TABLESAMPLE system(x)" +== 018 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a FROM XMLTABLE('foo' PASSING 'bar' COLUMNS a text) +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a FROM xmltable(('foo') PASSING 'bar' COLUMNS a text)" +== 019 +-- truncate_limit: 100 +CREATE STATISTICS tst ON a FROM JSON_TABLE(jsonb '123', '$' COLUMNS (item int)) +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON a FROM JSON_TABLE('123'::jsonb , '$' COLUMNS (item int ))" +== 020 +-- truncate_limit: 100 +CREATE FUNCTION tftest(int) returns table(a int, b int) as $$ +SELECT $1, $1+i FROM generate_series(1,5) g(i); +$$ LANGUAGE sql IMMUTABLE STRICT +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tftest(int) RETURNS TABLE (a int, b int) AS $$\nSELECT $1, $1+i FROM generate_seri..." +== 021 +-- truncate_limit: 100 +CREATE STATISTICS alt_stat2 ON a FROM tftest(1) +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS alt_stat2 ON a FROM tftest(1)" +== 022 +-- truncate_limit: 100 +DROP FUNCTION tftest +-- +FUNCTION: name="tftest" function="tftest" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION tftest" +== 023 +-- truncate_limit: 100 +-- incorrect expressions +CREATE STATISTICS tst ON (y) FROM ext_stats_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tst ON (y) FROM ext_stats_test" +== 024 +-- truncate_limit: 100 +-- single column reference +CREATE STATISTICS tst ON y + z FROM ext_stats_test +-- +ERROR: syntax error at or near "+" +CURSORPOS: 55 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 025 +-- truncate_limit: 100 +-- missing parentheses +CREATE STATISTICS tst ON (x, y) FROM ext_stats_test +-- +ERROR: syntax error at or near "," +CURSORPOS: 51 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 026 +-- truncate_limit: 100 +-- tuple expression +DROP TABLE ext_stats_test +-- +TABLE: name="ext_stats_test" schema="" table="ext_stats_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ext_stats_test" +== 027 +-- truncate_limit: 100 +-- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it +CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab1 (a int, b int, c int)" +== 028 +-- truncate_limit: 100 +CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1" +== 029 +-- truncate_limit: 100 +COMMENT ON STATISTICS ab1_a_b_stats IS 'new comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON STATISTICS ab1_a_b_stats IS 'new comment'" +== 030 +-- truncate_limit: 100 +CREATE ROLE regress_stats_ext +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_stats_ext" +== 031 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_stats_ext +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_ext" +== 032 +-- truncate_limit: 100 +COMMENT ON STATISTICS ab1_a_b_stats IS 'changed comment' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON STATISTICS ab1_a_b_stats IS 'changed comment'" +== 033 +-- truncate_limit: 100 +DROP STATISTICS ab1_a_b_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS ab1_a_b_stats" +== 034 +-- truncate_limit: 100 +ALTER STATISTICS ab1_a_b_stats RENAME TO ab1_a_b_stats_new +-- +STMT: RenameStmt +TRUNCATED: "ALTER STATISTICS ab1_a_b_stats RENAME TO ab1_a_b_stats_new" +== 035 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 036 +-- truncate_limit: 100 +DROP ROLE regress_stats_ext +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_stats_ext" +== 037 +-- truncate_limit: 100 +CREATE STATISTICS pg_temp.stats_ext_temp ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS pg_temp.stats_ext_temp ON a, b FROM ab1" +== 038 +-- truncate_limit: 100 +SELECT regexp_replace(pg_describe_object(tableoid, oid, 0), + 'pg_temp_[0-9]*', 'pg_temp_REDACTED') AS descr, + pg_statistics_obj_is_visible(oid) AS visible + FROM pg_statistic_ext + WHERE stxname = 'stats_ext_temp' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FUNCTION: name="pg_describe_object" function="pg_describe_object" schema="" ctx=Call +FUNCTION: name="pg_statistics_obj_is_visible" function="pg_statistics_obj_is_visible" schema="" ctx=Call +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_statistic_ext WHERE stxname = 'stats_ext_temp'" +== 039 +-- truncate_limit: 100 +DROP STATISTICS stats_ext_temp +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS stats_ext_temp" +== 040 +-- truncate_limit: 100 +-- shall fail +DROP STATISTICS pg_temp.stats_ext_temp +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS pg_temp.stats_ext_temp" +== 041 +-- truncate_limit: 100 +CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1" +== 042 +-- truncate_limit: 100 +DROP STATISTICS ab1_a_b_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS ab1_a_b_stats" +== 043 +-- truncate_limit: 100 +CREATE SCHEMA regress_schema_2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA regress_schema_2" +== 044 +-- truncate_limit: 100 +CREATE STATISTICS regress_schema_2.ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS regress_schema_2.ab1_a_b_stats ON a, b FROM ab1" +== 045 +-- truncate_limit: 100 +-- Let's also verify the pg_get_statisticsobjdef output looks sane. +SELECT pg_get_statisticsobjdef(oid) FROM pg_statistic_ext WHERE stxname = 'ab1_a_b_stats' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FUNCTION: name="pg_get_statisticsobjdef" function="pg_get_statisticsobjdef" schema="" ctx=Call +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_statisticsobjdef(oid) FROM pg_statistic_ext WHERE stxname = 'ab1_a_b_stats'" +== 046 +-- truncate_limit: 100 +DROP STATISTICS regress_schema_2.ab1_a_b_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS regress_schema_2.ab1_a_b_stats" +== 047 +-- truncate_limit: 100 +-- Ensure statistics are dropped when columns are +CREATE STATISTICS ab1_b_c_stats ON b, c FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_b_c_stats ON b, c FROM ab1" +== 048 +-- truncate_limit: 100 +CREATE STATISTICS ab1_a_b_c_stats ON a, b, c FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_a_b_c_stats ON a, b, c FROM ab1" +== 049 +-- truncate_limit: 100 +CREATE STATISTICS ab1_b_a_stats ON b, a FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_b_a_stats ON b, a FROM ab1" +== 050 +-- truncate_limit: 100 +ALTER TABLE ab1 DROP COLUMN a +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ab1 DROP a" +== 051 +-- truncate_limit: 100 +-- Ensure statistics are dropped when table is +SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +TRUNCATED: "SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%'" +== 052 +-- truncate_limit: 100 +DROP TABLE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ab1" +== 053 +-- truncate_limit: 100 +SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +TRUNCATED: "SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%'" +== 054 +-- truncate_limit: 100 +-- Ensure things work sanely with SET STATISTICS 0 +CREATE TABLE ab1 (a INTEGER, b INTEGER) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab1 (a int, b int)" +== 055 +-- truncate_limit: 100 +ALTER TABLE ab1 ALTER a SET STATISTICS 0 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ab1 ALTER COLUMN a SET STATISTICS 0" +== 056 +-- truncate_limit: 100 +INSERT INTO ab1 SELECT a, a%23 FROM generate_series(1, 1000) a +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ab1 SELECT a, a % 23 FROM generate_series(1, 1000) a" +== 057 +-- truncate_limit: 100 +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1" +== 058 +-- truncate_limit: 100 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ab1" +== 059 +-- truncate_limit: 100 +ALTER TABLE ab1 ALTER a SET STATISTICS -1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ab1 ALTER COLUMN a SET STATISTICS -1" +== 060 +-- truncate_limit: 100 +-- setting statistics target 0 skips the statistics, without printing any message, so check catalog +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0 +-- +STMT: AlterStatsStmt +TRUNCATED: "ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0" +== 061 +-- truncate_limit: 100 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ab1" +== 062 +-- truncate_limit: 100 +SELECT stxname, stxdndistinct, stxddependencies, stxdmcv, stxdinherit + FROM pg_statistic_ext s LEFT JOIN pg_statistic_ext_data d ON (d.stxoid = s.oid) + WHERE s.stxname = 'ab1_a_b_stats' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_statistic_ext s LEFT JOIN pg_statistic_ext_data d ON d.stxoid = s.oid WHERE ..." +== 063 +-- truncate_limit: 100 +ALTER STATISTICS ab1_a_b_stats SET STATISTICS -1 +-- +STMT: AlterStatsStmt +TRUNCATED: "ALTER STATISTICS ab1_a_b_stats SET STATISTICS -1" +== 064 +-- truncate_limit: 100 +-- partial analyze doesn't build stats either +ANALYZE ab1 (a) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ab1(a)" +== 065 +-- truncate_limit: 100 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ab1" +== 066 +-- truncate_limit: 100 +DROP TABLE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ab1" +== 067 +-- truncate_limit: 100 +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0 +-- +STMT: AlterStatsStmt +TRUNCATED: "ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0" +== 068 +-- truncate_limit: 100 +ALTER STATISTICS IF EXISTS ab1_a_b_stats SET STATISTICS 0 +-- +STMT: AlterStatsStmt +TRUNCATED: "ALTER STATISTICS IF EXISTS ab1_a_b_stats SET STATISTICS 0" +== 069 +-- truncate_limit: 100 +-- Ensure we can build statistics for tables with inheritance. +CREATE TABLE ab1 (a INTEGER, b INTEGER) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab1 (a int, b int)" +== 070 +-- truncate_limit: 100 +CREATE TABLE ab1c () INHERITS (ab1) +-- +TABLE: name="ab1c" schema="" table="ab1c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab1c () INHERITS (ab1)" +== 071 +-- truncate_limit: 100 +INSERT INTO ab1 VALUES (1,1) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ab1 VALUES (1, 1)" +== 072 +-- truncate_limit: 100 +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1" +== 073 +-- truncate_limit: 100 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ab1" +== 074 +-- truncate_limit: 100 +DROP TABLE ab1 CASCADE +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ab1 CASCADE" +== 075 +-- truncate_limit: 100 +-- Tests for stats with inheritance +CREATE TABLE stxdinh(a int, b int) +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stxdinh (a int, b int)" +== 076 +-- truncate_limit: 100 +CREATE TABLE stxdinh1() INHERITS(stxdinh) +-- +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stxdinh1 () INHERITS (stxdinh)" +== 077 +-- truncate_limit: 100 +CREATE TABLE stxdinh2() INHERITS(stxdinh) +-- +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stxdinh2 () INHERITS (stxdinh)" +== 078 +-- truncate_limit: 100 +INSERT INTO stxdinh SELECT mod(a,50), mod(a,100) FROM generate_series(0, 1999) a +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO stxdinh SELECT mod(a, 50), mod(a, 100) FROM generate_series(0, 1999) a" +== 079 +-- truncate_limit: 100 +INSERT INTO stxdinh1 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a +-- +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO stxdinh1 SELECT mod(a, 100), mod(a, 100) FROM generate_series(0, 999) a" +== 080 +-- truncate_limit: 100 +INSERT INTO stxdinh2 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a +-- +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO stxdinh2 SELECT mod(a, 100), mod(a, 100) FROM generate_series(0, 999) a" +== 081 +-- truncate_limit: 100 +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2 +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) stxdinh, stxdinh1, stxdinh2" +== 082 +-- truncate_limit: 100 +-- Ensure non-inherited stats are not applied to inherited query +-- Without stats object, it looks like this +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2')" +== 083 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0')" +== 084 +-- truncate_limit: 100 +CREATE STATISTICS stxdinh ON a, b FROM stxdinh +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS stxdinh ON a, b FROM stxdinh" +== 085 +-- truncate_limit: 100 +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2 +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) stxdinh, stxdinh1, stxdinh2" +== 086 +-- truncate_limit: 100 +-- See if the extended stats affect the estimates +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2')" +== 087 +-- truncate_limit: 100 +-- Dependencies are applied at individual relations (within append), so +-- this estimate changes a bit because we improve estimates for the parent +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0')" +== 088 +-- truncate_limit: 100 +-- Ensure correct (non-inherited) stats are applied to inherited query +SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh GROUP BY 1, 2')" +== 089 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh WHERE a = 0 AND b = 0')" +== 090 +-- truncate_limit: 100 +DROP TABLE stxdinh, stxdinh1, stxdinh2 +-- +TABLE: name="stxdinh" schema="" table="stxdinh" ctx=DDL +TABLE: name="stxdinh1" schema="" table="stxdinh1" ctx=DDL +TABLE: name="stxdinh2" schema="" table="stxdinh2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE stxdinh, stxdinh1, stxdinh2" +== 091 +-- truncate_limit: 100 +-- Ensure inherited stats ARE applied to inherited query in partitioned table +CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i) +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stxdinp (i int, a int, b int) PARTITION BY RANGE (i)" +== 092 +-- truncate_limit: 100 +CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100) +-- +TABLE: name="stxdinp1" schema="" table="stxdinp1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100)" +== 093 +-- truncate_limit: 100 +INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO stxdinp SELECT 1, a / 100, a / 100 FROM generate_series(1, 999) a" +== 094 +-- truncate_limit: 100 +CREATE STATISTICS stxdinp ON (a + 1), a, b FROM stxdinp +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS stxdinp ON (a + 1), a, b FROM stxdinp" +== 095 +-- truncate_limit: 100 +VACUUM ANALYZE stxdinp +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) stxdinp" +== 096 +-- truncate_limit: 100 +-- partitions are processed recursively +SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxrelid" +STMT: SelectStmt +TRUNCATED: "SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass" +== 097 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2')" +== 098 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT a + 1, b FROM ONLY stxdinp GROUP BY 1, 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT a + 1, b FROM ONLY stxdinp GROUP BY 1, 2')" +== 099 +-- truncate_limit: 100 +DROP TABLE stxdinp +-- +TABLE: name="stxdinp" schema="" table="stxdinp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE stxdinp" +== 100 +-- truncate_limit: 100 +-- basic test for statistics on expressions +CREATE TABLE ab1 (a INTEGER, b INTEGER, c TIMESTAMP, d TIMESTAMPTZ) +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ab1 (a int, b int, c timestamp, d timestamptz)" +== 101 +-- truncate_limit: 100 +-- expression stats may be built on a single expression column +CREATE STATISTICS ab1_exprstat_1 ON (a+b) FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_exprstat_1 ON (a + b) FROM ab1" +== 102 +-- truncate_limit: 100 +-- with a single expression, we only enable expression statistics +CREATE STATISTICS ab1_exprstat_2 ON (a+b) FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_exprstat_2 ON (a + b) FROM ab1" +== 103 +-- truncate_limit: 100 +SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_2' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +TRUNCATED: "SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_2'" +== 104 +-- truncate_limit: 100 +-- adding anything to the expression builds all statistics kinds +CREATE STATISTICS ab1_exprstat_3 ON (a+b), a FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_exprstat_3 ON (a + b), a FROM ab1" +== 105 +-- truncate_limit: 100 +SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_3' +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +FILTER: schema="" table="" column="stxname" +STMT: SelectStmt +TRUNCATED: "SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_3'" +== 106 +-- truncate_limit: 100 +-- date_trunc on timestamptz is not immutable, but that should not matter +CREATE STATISTICS ab1_exprstat_4 ON date_trunc('day', d) FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_exprstat_4 ON (date_trunc('day', d)) FROM ab1" +== 107 +-- truncate_limit: 100 +-- date_trunc on timestamp is immutable +CREATE STATISTICS ab1_exprstat_5 ON date_trunc('day', c) FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_exprstat_5 ON (date_trunc('day', c)) FROM ab1" +== 108 +-- truncate_limit: 100 +-- check use of a boolean-returning expression +CREATE STATISTICS ab1_exprstat_6 ON + (case a when 1 then true else false end), b FROM ab1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ab1_exprstat_6 ON (CASE a WHEN 1 THEN true ELSE false END), b FROM ab1" +== 109 +-- truncate_limit: 100 +-- insert some data and run analyze, to test that these cases build properly +INSERT INTO ab1 +SELECT x / 10, x / 3, + '2020-10-01'::timestamp + x * interval '1 day', + '2020-10-01'::timestamptz + x * interval '1 day' +FROM generate_series(1, 100) x +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ab1 SELECT ... FROM generate_series(1, 100) x" +== 110 +-- truncate_limit: 100 +ANALYZE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ab1" +== 111 +-- truncate_limit: 100 +-- apply some stats +SELECT * FROM check_estimated_rows('SELECT * FROM ab1 WHERE (case a when 1 then true else false end) AND b=2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM ab1 WHERE (case a when 1 then true else false e..." +== 112 +-- truncate_limit: 100 +DROP TABLE ab1 +-- +TABLE: name="ab1" schema="" table="ab1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ab1" +== 113 +-- truncate_limit: 100 +-- Verify supported object types for extended statistics +CREATE schema tststats +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA tststats" +== 114 +-- truncate_limit: 100 +CREATE TABLE tststats.t (a int, b int, c text) +-- +TABLE: name="tststats.t" schema="tststats" table="t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tststats.t (a int, b int, c text)" +== 115 +-- truncate_limit: 100 +CREATE INDEX ti ON tststats.t (a, b) +-- +TABLE: name="tststats.t" schema="tststats" table="t" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ti ON tststats.t USING btree (a, b)" +== 116 +-- truncate_limit: 100 +CREATE SEQUENCE tststats.s +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE tststats.s" +== 117 +-- truncate_limit: 100 +CREATE VIEW tststats.v AS SELECT * FROM tststats.t +-- +TABLE: name="tststats.v" schema="tststats" table="v" ctx=DDL +TABLE: name="tststats.t" schema="tststats" table="t" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tststats.v AS SELECT * FROM tststats.t" +== 118 +-- truncate_limit: 100 +CREATE MATERIALIZED VIEW tststats.mv AS SELECT * FROM tststats.t +-- +TABLE: name="tststats.mv" schema="tststats" table="mv" ctx=DDL +TABLE: name="tststats.t" schema="tststats" table="t" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW tststats.mv AS SELECT * FROM tststats.t" +== 119 +-- truncate_limit: 100 +CREATE TYPE tststats.ty AS (a int, b int, c text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE tststats.ty AS (a int, b int, c text)" +== 120 +-- truncate_limit: 100 +CREATE FOREIGN DATA WRAPPER extstats_dummy_fdw +-- +STMT: CreateFdwStmt +TRUNCATED: "CREATE FOREIGN DATA WRAPPER extstats_dummy_fdw" +== 121 +-- truncate_limit: 100 +CREATE SERVER extstats_dummy_srv FOREIGN DATA WRAPPER extstats_dummy_fdw +-- +STMT: CreateForeignServerStmt +TRUNCATED: "CREATE SERVER extstats_dummy_srv FOREIGN DATA WRAPPER extstats_dummy_fdw" +== 122 +-- truncate_limit: 100 +CREATE FOREIGN TABLE tststats.f (a int, b int, c text) SERVER extstats_dummy_srv +-- +STMT: CreateForeignTableStmt +TRUNCATED: "CREATE FOREIGN TABLE tststats.f (a int, b int, c text) SERVER extstats_dummy_srv" +== 123 +-- truncate_limit: 100 +CREATE TABLE tststats.pt (a int, b int, c text) PARTITION BY RANGE (a, b) +-- +TABLE: name="tststats.pt" schema="tststats" table="pt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tststats.pt (a int, b int, c text) PARTITION BY RANGE (a, b)" +== 124 +-- truncate_limit: 100 +CREATE TABLE tststats.pt1 PARTITION OF tststats.pt FOR VALUES FROM (-10, -10) TO (10, 10) +-- +TABLE: name="tststats.pt1" schema="tststats" table="pt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tststats.pt1 PARTITION OF tststats.pt FOR VALUES FROM (-10, -10) TO (10, 10)" +== 125 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s1 ON a, b FROM tststats.t +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s1 ON a, b FROM tststats.t" +== 126 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s2 ON a, b FROM tststats.ti +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s2 ON a, b FROM tststats.ti" +== 127 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s3 ON a, b FROM tststats.s +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s3 ON a, b FROM tststats.s" +== 128 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s4 ON a, b FROM tststats.v +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s4 ON a, b FROM tststats.v" +== 129 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s5 ON a, b FROM tststats.mv +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s5 ON a, b FROM tststats.mv" +== 130 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s6 ON a, b FROM tststats.ty +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s6 ON a, b FROM tststats.ty" +== 131 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s7 ON a, b FROM tststats.f +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s7 ON a, b FROM tststats.f" +== 132 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s8 ON a, b FROM tststats.pt +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s8 ON a, b FROM tststats.pt" +== 133 +-- truncate_limit: 100 +CREATE STATISTICS tststats.s9 ON a, b FROM tststats.pt1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.s9 ON a, b FROM tststats.pt1" +== 134 +-- truncate_limit: 100 +DO $$ +DECLARE + relname text := reltoastrelid::regclass FROM pg_class WHERE oid = 'tststats.t'::regclass; +BEGIN + EXECUTE 'CREATE STATISTICS tststats.s10 ON a, b FROM ' || relname; +EXCEPTION WHEN wrong_object_type THEN + RAISE NOTICE 'stats on toast table not created'; +END; +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n\trelname text := reltoastrelid::regclass FROM pg_class WHERE oid = 'tststats.t'::re..." +== 135 +-- truncate_limit: 100 +DROP SCHEMA tststats CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA tststats CASCADE" +== 136 +-- truncate_limit: 100 +DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE" +== 137 +-- truncate_limit: 100 +-- n-distinct tests +CREATE TABLE ndistinct ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b INT, + filler3 DATE, + c INT, + d INT +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ndistinct (filler1 text, filler2 numeric, a int, b int, filler3 date, c int, d int) ..." +== 138 +-- truncate_limit: 100 +-- over-estimates when using only per-column statistics +INSERT INTO ndistinct (a, b, c, filler1) + SELECT i/100, i/100, i/100, (i/100) || ' dollars and zero cents' + FROM generate_series(1,1000) s(i) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ndistinct (a, b, c, filler1) SELECT ... FROM generate_series(1, 1000) s(i)" +== 139 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 140 +-- truncate_limit: 100 +-- Group Aggregate, due to over-estimate of the number of groups +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 141 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c')" +== 142 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c')" +== 143 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d')" +== 144 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d')" +== 145 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)')" +== 146 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)')" +== 147 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)')" +== 148 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)')" +== 149 +-- truncate_limit: 100 +-- correct command +CREATE STATISTICS s10 ON a, b, c FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s10 ON a, b, c FROM ndistinct" +== 150 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 151 +-- truncate_limit: 100 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT s.stxkind, d.stxdndistinct FROM pg_statistic_ext s, pg_statistic_ext_data d WHERE ..." +== 152 +-- truncate_limit: 100 +-- minor improvement, make sure the ctid does not break the matching +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b')" +== 153 +-- truncate_limit: 100 +-- Hash Aggregate, thanks to estimates improved by the statistic +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 154 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c')" +== 155 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c')" +== 156 +-- truncate_limit: 100 +-- partial improvement (match on attributes) +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)')" +== 157 +-- truncate_limit: 100 +-- expressions - no improvement +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)')" +== 158 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)')" +== 159 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)')" +== 160 +-- truncate_limit: 100 +-- last two plans keep using Group Aggregate, because 'd' is not covered +-- by the statistic and while it's NULL-only we assume 200 values for it +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d')" +== 161 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d')" +== 162 +-- truncate_limit: 100 +TRUNCATE TABLE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ndistinct" +== 163 +-- truncate_limit: 100 +-- under-estimates when using only per-column statistics +INSERT INTO ndistinct (a, b, c, filler1) + SELECT mod(i,13), mod(i,17), mod(i,19), + mod(i,23) || ' dollars and zero cents' + FROM generate_series(1,1000) s(i) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ndistinct (a, b, c, filler1) SELECT ... FROM generate_series(1, 1000) s(i)" +== 164 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 165 +-- truncate_limit: 100 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT s.stxkind, d.stxdndistinct FROM pg_statistic_ext s, pg_statistic_ext_data d WHERE ..." +== 166 +-- truncate_limit: 100 +-- correct estimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 167 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c')" +== 168 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d')" +== 169 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d')" +== 170 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d')" +== 171 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)')" +== 172 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)')" +== 173 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)')" +== 174 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)')" +== 175 +-- truncate_limit: 100 +DROP STATISTICS s10 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s10" +== 176 +-- truncate_limit: 100 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT s.stxkind, d.stxdndistinct FROM pg_statistic_ext s, pg_statistic_ext_data d WHERE ..." +== 177 +-- truncate_limit: 100 +-- dropping the statistics results in under-estimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 178 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c')" +== 179 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d')" +== 180 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d')" +== 181 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d')" +== 182 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)')" +== 183 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)')" +== 184 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)')" +== 185 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)')" +== 186 +-- truncate_limit: 100 +-- ndistinct estimates with statistics on expressions +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)')" +== 187 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)')" +== 188 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)')" +== 189 +-- truncate_limit: 100 +CREATE STATISTICS s10 (ndistinct) ON (a+1), (b+100), (2*c) FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s10 (ndistinct) ON (a + 1), (b + 100), (2 * c) FROM ndistinct" +== 190 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 191 +-- truncate_limit: 100 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT s.stxkind, d.stxdndistinct FROM pg_statistic_ext s, pg_statistic_ext_data d WHERE ..." +== 192 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)')" +== 193 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)')" +== 194 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)')" +== 195 +-- truncate_limit: 100 +DROP STATISTICS s10 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s10" +== 196 +-- truncate_limit: 100 +-- a mix of attributes and expressions +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 197 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)')" +== 198 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)')" +== 199 +-- truncate_limit: 100 +CREATE STATISTICS s10 (ndistinct) ON a, b, (2*c) FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s10 (ndistinct) ON a, b, (2 * c) FROM ndistinct" +== 200 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 201 +-- truncate_limit: 100 +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxrelid" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT s.stxkind, d.stxdndistinct FROM pg_statistic_ext s, pg_statistic_ext_data d WHERE ..." +== 202 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 203 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)')" +== 204 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)')" +== 205 +-- truncate_limit: 100 +DROP STATISTICS s10 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s10" +== 206 +-- truncate_limit: 100 +-- combination of multiple ndistinct statistics, with/without expressions +TRUNCATE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ndistinct" +== 207 +-- truncate_limit: 100 +-- two mostly independent groups of columns +INSERT INTO ndistinct (a, b, c, d) + SELECT mod(i,3), mod(i,9), mod(i,5), mod(i,20) + FROM generate_series(1,1000) s(i) +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ndistinct (a, b, c, d) SELECT ... FROM generate_series(1, 1000) s(i)" +== 208 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 209 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 210 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)')" +== 211 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b')" +== 212 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)')" +== 213 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c')" +== 214 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)')" +== 215 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)')" +== 216 +-- truncate_limit: 100 +-- basic statistics on both attributes (no expressions) +CREATE STATISTICS s11 (ndistinct) ON a, b FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s11 (ndistinct) ON a, b FROM ndistinct" +== 217 +-- truncate_limit: 100 +CREATE STATISTICS s12 (ndistinct) ON c, d FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s12 (ndistinct) ON c, d FROM ndistinct" +== 218 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 219 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 220 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)')" +== 221 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b')" +== 222 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)')" +== 223 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c')" +== 224 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)')" +== 225 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)')" +== 226 +-- truncate_limit: 100 +-- replace the second statistics by statistics on expressions + +DROP STATISTICS s12 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s12" +== 227 +-- truncate_limit: 100 +CREATE STATISTICS s12 (ndistinct) ON (c * 10), (d - 1) FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s12 (ndistinct) ON (c * 10), (d - 1) FROM ndistinct" +== 228 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 229 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 230 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)')" +== 231 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b')" +== 232 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)')" +== 233 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c')" +== 234 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)')" +== 235 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)')" +== 236 +-- truncate_limit: 100 +-- replace the second statistics by statistics on both attributes and expressions + +DROP STATISTICS s12 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s12" +== 237 +-- truncate_limit: 100 +CREATE STATISTICS s12 (ndistinct) ON c, d, (c * 10), (d - 1) FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s12 (ndistinct) ON c, d, (c * 10), (d - 1) FROM ndistinct" +== 238 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 239 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 240 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)')" +== 241 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b')" +== 242 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)')" +== 243 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c')" +== 244 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)')" +== 245 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)')" +== 246 +-- truncate_limit: 100 +-- replace the other statistics by statistics on both attributes and expressions + +DROP STATISTICS s11 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s11" +== 247 +-- truncate_limit: 100 +CREATE STATISTICS s11 (ndistinct) ON a, b, (a*5), (b+1) FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s11 (ndistinct) ON a, b, (a * 5), (b + 1) FROM ndistinct" +== 248 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 249 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 250 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)')" +== 251 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b')" +== 252 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)')" +== 253 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c')" +== 254 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)')" +== 255 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)')" +== 256 +-- truncate_limit: 100 +-- replace statistics by somewhat overlapping ones (this expected to get worse estimate +-- because the first statistics shall be applied to 3 columns, and the second one can't +-- be really applied) + +DROP STATISTICS s11 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s11" +== 257 +-- truncate_limit: 100 +DROP STATISTICS s12 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s12" +== 258 +-- truncate_limit: 100 +CREATE STATISTICS s11 (ndistinct) ON a, b, (a*5), (b+1) FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s11 (ndistinct) ON a, b, (a * 5), (b + 1) FROM ndistinct" +== 259 +-- truncate_limit: 100 +CREATE STATISTICS s12 (ndistinct) ON a, (b+1), (c * 10) FROM ndistinct +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s12 (ndistinct) ON a, (b + 1), (c * 10) FROM ndistinct" +== 260 +-- truncate_limit: 100 +ANALYZE ndistinct +-- +TABLE: name="ndistinct" schema="" table="ndistinct" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE ndistinct" +== 261 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b')" +== 262 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)')" +== 263 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b')" +== 264 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)')" +== 265 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c')" +== 266 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)')" +== 267 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)')" +== 268 +-- truncate_limit: 100 +DROP STATISTICS s11 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s11" +== 269 +-- truncate_limit: 100 +DROP STATISTICS s12 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS s12" +== 270 +-- truncate_limit: 100 +-- functional dependencies tests +CREATE TABLE functional_dependencies ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b TEXT, + filler3 DATE, + c INT, + d TEXT +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE functional_dependencies (filler1 text, filler2 numeric, a int, b text, filler3 date,..." +== 271 +-- truncate_limit: 100 +CREATE INDEX fdeps_ab_idx ON functional_dependencies (a, b) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fdeps_ab_idx ON functional_dependencies USING btree (a, b)" +== 272 +-- truncate_limit: 100 +CREATE INDEX fdeps_abc_idx ON functional_dependencies (a, b, c) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fdeps_abc_idx ON functional_dependencies USING btree (a, b, c)" +== 273 +-- truncate_limit: 100 +-- random data (no functional dependencies) +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT mod(i, 5), mod(i, 7), mod(i, 11), i FROM generate_series(1,1000) s(i) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO functional_dependencies (a, b, c, filler1) SELECT ... FROM generate_series(1, 1000) s(i)" +== 274 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 275 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 276 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 277 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies" +== 278 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 279 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 280 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 281 +-- truncate_limit: 100 +-- a => b, a => c, b => c +TRUNCATE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE functional_dependencies" +== 282 +-- truncate_limit: 100 +DROP STATISTICS func_deps_stat +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS func_deps_stat" +== 283 +-- truncate_limit: 100 +-- now do the same thing, but with expressions +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,5000) s(i) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO functional_dependencies (a, b, c, filler1) SELECT ... FROM generate_series(1, 5000) s(i)" +== 284 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 285 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AN..." +== 286 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1 AND mod(c, 7) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AN..." +== 287 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS func_deps_stat (dependencies) ON (mod(a,11)), (mod(b::int, 13)), (mod(c, 7)) FROM functional_dependencies +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS func_deps_stat (dependencies) ON (mod(a, 11)), (mod(b::int, 13)), (mod(c, 7)) F..." +== 288 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 289 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AN..." +== 290 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1 AND mod(c, 7) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AN..." +== 291 +-- truncate_limit: 100 +-- a => b, a => c, b => c +TRUNCATE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE functional_dependencies" +== 292 +-- truncate_limit: 100 +DROP STATISTICS func_deps_stat +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS func_deps_stat" +== 293 +-- truncate_limit: 100 +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), i FROM generate_series(1,5000) s(i) +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO functional_dependencies (a, b, c, filler1) SELECT ... FROM generate_series(1, 5000) s(i)" +== 294 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 295 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 296 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 297 +-- truncate_limit: 100 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 298 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 299 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 5..." +== 300 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 5..." +== 301 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, ..." +== 302 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c IN (1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, ..." +== 303 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 27, 51, 52, 76, 77) AND b IN (''1'', ''2'', ''26'', ''27'') AND c IN (1, 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 2..." +== 304 +-- truncate_limit: 100 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51)..." +== 305 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51)..." +== 306 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 O..." +== 307 +-- truncate_limit: 100 +-- OR clauses referencing different attributes +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1'') AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1..." +== 308 +-- truncate_limit: 100 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 309 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 310 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 311 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 312 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = ANY (ARRAY[1])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 313 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 26, 27, 51, 52, 76, 77]) AND b = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND c = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 314 +-- truncate_limit: 100 +-- ANY with inequalities should not benefit from functional dependencies +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1, 51]) AND b > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1,..." +== 315 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1, 51]) AND b <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1..." +== 316 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1, 2, 51, 52]) AND b >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1..." +== 317 +-- truncate_limit: 100 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 318 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 319 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 5..." +== 320 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies" +== 321 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 322 +-- truncate_limit: 100 +-- print the detected dependencies +SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat' +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +FILTER: schema="" table="" column="statistics_name" +STMT: SelectStmt +TRUNCATED: "SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat'" +== 323 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 324 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 325 +-- truncate_limit: 100 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 326 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 327 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 5..." +== 328 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 5..." +== 329 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, ..." +== 330 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c IN (1)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, ..." +== 331 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 27, 51, 52, 76, 77) AND b IN (''1'', ''2'', ''26'', ''27'') AND c IN (1, 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 2..." +== 332 +-- truncate_limit: 100 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51)..." +== 333 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51)..." +== 334 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 O..." +== 335 +-- truncate_limit: 100 +-- OR clauses referencing different attributes are incompatible +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1'') AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1..." +== 336 +-- truncate_limit: 100 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 337 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 338 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 339 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 340 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = ANY (ARRAY[1])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 341 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 26, 27, 51, 52, 76, 77]) AND b = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND c = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1,..." +== 342 +-- truncate_limit: 100 +-- ANY with inequalities should not benefit from functional dependencies +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1, 51]) AND b > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1,..." +== 343 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1, 51]) AND b <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1..." +== 344 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1, 2, 51, 52]) AND b >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1..." +== 345 +-- truncate_limit: 100 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 346 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND ..." +== 347 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 5..." +== 348 +-- truncate_limit: 100 +-- changing the type of column c causes all its stats to be dropped, reverting +-- to default estimates without any statistics, i.e. 0.5% selectivity for each +-- condition +ALTER TABLE functional_dependencies ALTER COLUMN c TYPE numeric +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE functional_dependencies ALTER COLUMN c TYPE numeric" +== 349 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 350 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 351 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1..." +== 352 +-- truncate_limit: 100 +DROP STATISTICS func_deps_stat +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS func_deps_stat" +== 353 +-- truncate_limit: 100 +-- now try functional dependencies with expressions + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND u..." +== 354 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'' AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND u..." +== 355 +-- truncate_limit: 100 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 356 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 357 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 358 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 359 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52..." +== 360 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) IN (2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52..." +== 361 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 52, 54, 102, 104, 152, 154) AND upper(b) IN (''1'', ''2'', ''26'', ''27'') AND (c + 1) IN (2, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 362 +-- truncate_limit: 100 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (..." +== 363 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (..." +== 364 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 4 OR (a * 2) = 102 OR (a * 2) = 104) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (..." +== 365 +-- truncate_limit: 100 +-- OR clauses referencing different attributes +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR upper(b) = ''1'') AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR u..." +== 366 +-- truncate_limit: 100 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 367 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 368 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 102, 104]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 369 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 370 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = ANY (ARRAY[2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 371 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 52, 54, 102, 104, 152, 154]) AND upper(b) = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND (c + 1) = ANY (ARRAY[2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 372 +-- truncate_limit: 100 +-- ANY with inequalities should not benefit from functional dependencies +-- the estimates however improve thanks to having expression statistics +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (ARRAY[2, 102]) AND upper(b) > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (AR..." +== 373 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (ARRAY[2, 102]) AND upper(b) <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (A..." +== 374 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (ARRAY[2, 4, 102, 104]) AND upper(b) >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (A..." +== 375 +-- truncate_limit: 100 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 376 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 377 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 378 +-- truncate_limit: 100 +-- create statistics on expressions +CREATE STATISTICS func_deps_stat (dependencies) ON (a * 2), upper(b), (c + 1) FROM functional_dependencies +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS func_deps_stat (dependencies) ON (a * 2), (upper(b)), (c + 1) FROM functional_d..." +== 379 +-- truncate_limit: 100 +ANALYZE functional_dependencies +-- +TABLE: name="functional_dependencies" schema="" table="functional_dependencies" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies" +== 380 +-- truncate_limit: 100 +-- print the detected dependencies +SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat' +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +FILTER: schema="" table="" column="statistics_name" +STMT: SelectStmt +TRUNCATED: "SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat'" +== 381 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND u..." +== 382 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'' AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND u..." +== 383 +-- truncate_limit: 100 +-- IN +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 384 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 385 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) IN (''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 386 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 387 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52..." +== 388 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) IN (2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52..." +== 389 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 52, 54, 102, 104, 152, 154) AND upper(b) IN (''1'', ''2'', ''26'', ''27'') AND (c + 1) IN (2, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 390 +-- truncate_limit: 100 +-- OR clauses referencing the same attribute +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (..." +== 391 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (..." +== 392 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 4 OR (a * 2) = 102 OR (a * 2) = 104) AND (upper(b) = ''1'' OR upper(b) = ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (..." +== 393 +-- truncate_limit: 100 +-- OR clauses referencing different attributes +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR upper(b) = ''1'') AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR u..." +== 394 +-- truncate_limit: 100 +-- ANY +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 395 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 396 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 102, 104]) AND upper(b) = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 397 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = 2') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 398 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = ANY (ARRAY[2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 399 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 52, 54, 102, 104, 152, 154]) AND upper(b) = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND (c + 1) = ANY (ARRAY[2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (AR..." +== 400 +-- truncate_limit: 100 +-- ANY with inequalities should not benefit from functional dependencies +-- the estimates however improve thanks to having expression statistics +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (ARRAY[2, 102]) AND upper(b) > ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (AR..." +== 401 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (ARRAY[2, 102]) AND upper(b) <= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (A..." +== 402 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (ARRAY[2, 4, 102, 104]) AND upper(b) >= ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (A..." +== 403 +-- truncate_limit: 100 +-- ALL (should not benefit from functional dependencies) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 404 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 10..." +== 405 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ALL (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4,..." +== 406 +-- truncate_limit: 100 +-- check the ability to use multiple functional dependencies +CREATE TABLE functional_dependencies_multi ( + a INTEGER, + b INTEGER, + c INTEGER, + d INTEGER +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE functional_dependencies_multi (a int, b int, c int, d int) WITH (autovacuum_enabled=..." +== 407 +-- truncate_limit: 100 +INSERT INTO functional_dependencies_multi (a, b, c, d) + SELECT + mod(i,7), + mod(i,7), + mod(i,11), + mod(i,11) + FROM generate_series(1,5000) s(i) +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO functional_dependencies_multi (a, b, c, d) SELECT ... FROM generate_series(1, 5000) s(i)" +== 408 +-- truncate_limit: 100 +ANALYZE functional_dependencies_multi +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies_multi" +== 409 +-- truncate_limit: 100 +-- estimates without any functional dependencies +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b..." +== 410 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0 = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0..." +== 411 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d..." +== 412 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b..." +== 413 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b = 0 AND 0 = c AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b..." +== 414 +-- truncate_limit: 100 +-- create separate functional dependencies +CREATE STATISTICS functional_dependencies_multi_1 (dependencies) ON a, b FROM functional_dependencies_multi +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS functional_dependencies_multi_1 (dependencies) ON a, b FROM functional_dependen..." +== 415 +-- truncate_limit: 100 +CREATE STATISTICS functional_dependencies_multi_2 (dependencies) ON c, d FROM functional_dependencies_multi +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS functional_dependencies_multi_2 (dependencies) ON c, d FROM functional_dependen..." +== 416 +-- truncate_limit: 100 +ANALYZE functional_dependencies_multi +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE functional_dependencies_multi" +== 417 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b..." +== 418 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0 = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0..." +== 419 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d..." +== 420 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b..." +== 421 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b = 0 AND 0 = c AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b..." +== 422 +-- truncate_limit: 100 +DROP TABLE functional_dependencies_multi +-- +TABLE: name="functional_dependencies_multi" schema="" table="functional_dependencies_multi" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE functional_dependencies_multi" +== 423 +-- truncate_limit: 100 +-- MCV lists +CREATE TABLE mcv_lists ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b VARCHAR, + filler3 DATE, + c INT, + d TEXT, + ia INT[] +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcv_lists (filler1 text, filler2 numeric, a int, b varchar, filler3 date, c int, d t..." +== 424 +-- truncate_limit: 100 +-- random data (no MCV list) +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT mod(i,37), mod(i,41), mod(i,43), mod(i,47) FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists (a, b, c, filler1) SELECT ... FROM generate_series(1, 5000) s(i)" +== 425 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 426 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''')" +== 427 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1')" +== 428 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists" +== 429 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 430 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''')" +== 431 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1')" +== 432 +-- truncate_limit: 100 +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mcv_lists" +== 433 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats" +== 434 +-- truncate_limit: 100 +-- random data (no MCV list), but with expression +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,1000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists (a, b, c, filler1) SELECT i, i, i, i FROM generate_series(1, 1000) s(i)" +== 435 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 436 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11)..." +== 437 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1 AND mod(c,13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11)..." +== 438 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a,7)), (mod(b::int,11)), (mod(c,13)) FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a, 7)), (mod(b::int, 11)), (mod(c, 13)) FROM mcv_..." +== 439 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 440 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11)..." +== 441 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1 AND mod(c,13) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11)..." +== 442 +-- truncate_limit: 100 +-- 100 distinct combinations, all in the MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mcv_lists" +== 443 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats" +== 444 +-- truncate_limit: 100 +INSERT INTO mcv_lists (a, b, c, ia, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), array[mod(i,25)], i + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists (a, b, c, ia, filler1) SELECT ... FROM generate_series(1, 5000) s(i)" +== 445 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 446 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''')" +== 447 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b')" +== 448 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1''')" +== 449 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b')" +== 450 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0''')" +== 451 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b')" +== 452 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1')" +== 453 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5')" +== 454 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c')" +== 455 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4')" +== 456 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c')" +== 457 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1')" +== 458 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR ..." +== 459 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ..." +== 460 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b IN ( ''1'', ''2'', NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b..." +== 461 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) A..." +== 462 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2'', NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, ..." +== 463 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b..." +== 464 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3]) AND b IN (''1'', ''2'', NULL, ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3])..." +== 465 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > A..." +== 466 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3, NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > A..." +== 467 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN ..." +== 468 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', NULL, ''3'') AND c > ANY (ARRAY[1, 2, NULL, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN ..." +== 469 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = AN..." +== 470 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c, ia FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c, ia FROM mcv_lists" +== 471 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 472 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''')" +== 473 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b')" +== 474 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1''')" +== 475 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b')" +== 476 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0''')" +== 477 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b')" +== 478 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1')" +== 479 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5')" +== 480 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c')" +== 481 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4')" +== 482 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c')" +== 483 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1')" +== 484 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR ..." +== 485 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR ..." +== 486 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ..." +== 487 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b IN ( ''1'', ''2'', NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b..." +== 488 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) A..." +== 489 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2'', NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, ..." +== 490 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b..." +== 491 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3]) AND b IN (''1'', ''2'', NULL, ''3'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3])..." +== 492 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > A..." +== 493 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3, NULL])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > A..." +== 494 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN ..." +== 495 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', NULL, ''3'') AND c > ANY (ARRAY[1, 2, NULL, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN ..." +== 496 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = AN..." +== 497 +-- truncate_limit: 100 +-- check change of unrelated column type does not reset the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN d TYPE VARCHAR(64) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mcv_lists ALTER COLUMN d TYPE varchar(64)" +== 498 +-- truncate_limit: 100 +SELECT d.stxdmcv IS NOT NULL + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FILTER: schema="" table="s" column="stxname" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT d.stxdmcv IS NOT NULL FROM pg_statistic_ext s, pg_statistic_ext_data d WHERE ..." +== 499 +-- truncate_limit: 100 +-- check change of column type resets the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric" +== 500 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''')" +== 501 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 502 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''')" +== 503 +-- truncate_limit: 100 +-- 100 distinct combinations, all in the MCV list, but with expressions +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mcv_lists" +== 504 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats" +== 505 +-- truncate_limit: 100 +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,1000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists (a, b, c, filler1) SELECT i, i, i, i FROM generate_series(1, 1000) s(i)" +== 506 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 507 +-- truncate_limit: 100 +-- without any stats on the expressions, we have to use default selectivities, which +-- is why the estimates here are different from the pre-computed case above + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10..." +== 508 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::in..." +== 509 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10..." +== 510 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::in..." +== 511 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10..." +== 512 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10)..." +== 513 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NUL..." +== 514 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51..." +== 515 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL..." +== 516 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) A..." +== 517 +-- truncate_limit: 100 +-- create statistics with expressions only (we create three separate stats, in order not to build more complex extended stats) +CREATE STATISTICS mcv_lists_stats_1 ON (mod(a,20)) FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats_1 ON (mod(a, 20)) FROM mcv_lists" +== 518 +-- truncate_limit: 100 +CREATE STATISTICS mcv_lists_stats_2 ON (mod(b::int,10)) FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats_2 ON (mod(b::int, 10)) FROM mcv_lists" +== 519 +-- truncate_limit: 100 +CREATE STATISTICS mcv_lists_stats_3 ON (mod(c,5)) FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats_3 ON (mod(c, 5)) FROM mcv_lists" +== 520 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 521 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10..." +== 522 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::in..." +== 523 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10..." +== 524 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::in..." +== 525 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10..." +== 526 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10)..." +== 527 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NUL..." +== 528 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51..." +== 529 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL..." +== 530 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) A..." +== 531 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats_1 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats_1" +== 532 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats_2 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats_2" +== 533 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats_3 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats_3" +== 534 +-- truncate_limit: 100 +-- create statistics with both MCV and expressions +CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a,20)), (mod(b::int,10)), (mod(c,5)) FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a, 20)), (mod(b::int, 10)), (mod(c, 5)) FROM mcv_..." +== 535 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 536 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10..." +== 537 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::in..." +== 538 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10..." +== 539 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::in..." +== 540 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10..." +== 541 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10)..." +== 542 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NUL..." +== 543 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51..." +== 544 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL..." +== 545 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) A..." +== 546 +-- truncate_limit: 100 +-- we can't use the statistic for OR clauses that are not fully covered (missing 'd' attribute) +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,5) = 1 OR d IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10)..." +== 547 +-- truncate_limit: 100 +-- 100 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mcv_lists" +== 548 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats" +== 549 +-- truncate_limit: 100 +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT + (CASE WHEN mod(i,100) = 1 THEN NULL ELSE mod(i,100) END), + (CASE WHEN mod(i,50) = 1 THEN NULL ELSE mod(i,50) END), + (CASE WHEN mod(i,25) = 1 THEN NULL ELSE mod(i,25) END), + i + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists (a, b, c, filler1) SELECT ... FROM generate_series(1, 5000) s(i)" +== 550 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 551 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL')" +== 552 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c I..." +== 553 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL')" +== 554 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND c IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND..." +== 555 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''1'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''..." +== 556 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists" +== 557 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 558 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL')" +== 559 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c I..." +== 560 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL')" +== 561 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND c IS NOT NULL') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND..." +== 562 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''1'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''..." +== 563 +-- truncate_limit: 100 +-- test pg_mcv_list_items with a very simple (single item) MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mcv_lists" +== 564 +-- truncate_limit: 100 +INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1,1000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1, 1000) s(i)" +== 565 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 566 +-- truncate_limit: 100 +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FUNCTION: name="pg_mcv_list_items" function="pg_mcv_list_items" schema="" ctx=Call +FILTER: schema="" table="s" column="stxname" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT m.* FROM pg_statistic_ext s, pg_statistic_ext_data d, pg_mcv_list_items(d.stxdmcv) m WHERE..." +== 567 +-- truncate_limit: 100 +-- 2 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE mcv_lists" +== 568 +-- truncate_limit: 100 +DROP STATISTICS mcv_lists_stats +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS mcv_lists_stats" +== 569 +-- truncate_limit: 100 +INSERT INTO mcv_lists (a, b, c, d) + SELECT + NULL, -- always NULL + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 0 END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END) + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists (a, b, c, d) SELECT ... FROM generate_series(1, 5000) s(i)" +== 570 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 571 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x''')" +== 572 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x''')" +== 573 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d = ''x'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d =..." +== 574 +-- truncate_limit: 100 +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, d FROM mcv_lists +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, d FROM mcv_lists" +== 575 +-- truncate_limit: 100 +ANALYZE mcv_lists +-- +TABLE: name="mcv_lists" schema="" table="mcv_lists" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists" +== 576 +-- truncate_limit: 100 +-- test pg_mcv_list_items with MCV list containing variable-length data and NULLs +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid +-- +TABLE: name="pg_statistic_ext" schema="" table="pg_statistic_ext" ctx=Select +TABLE: name="pg_statistic_ext_data" schema="" table="pg_statistic_ext_data" ctx=Select +ALIAS: "d"="pg_statistic_ext_data" +ALIAS: "s"="pg_statistic_ext" +FUNCTION: name="pg_mcv_list_items" function="pg_mcv_list_items" schema="" ctx=Call +FILTER: schema="" table="s" column="stxname" +FILTER: schema="" table="d" column="stxoid" +FILTER: schema="" table="s" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT m.* FROM pg_statistic_ext s, pg_statistic_ext_data d, pg_mcv_list_items(d.stxdmcv) m WHERE..." +== 577 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x''')" +== 578 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x''')" +== 579 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d = ''x'')') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d =..." +== 580 +-- truncate_limit: 100 +-- mcv with pass-by-ref fixlen types, e.g. uuid +CREATE TABLE mcv_lists_uuid ( + a UUID, + b UUID, + c UUID +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcv_lists_uuid (a uuid, b uuid, c uuid) WITH (autovacuum_enabled=off)" +== 581 +-- truncate_limit: 100 +INSERT INTO mcv_lists_uuid (a, b, c) + SELECT + fipshash(mod(i,100)::text)::uuid, + fipshash(mod(i,50)::text)::uuid, + fipshash(mod(i,25)::text)::uuid + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DML +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists_uuid (a, b, c) SELECT ... FROM generate_series(1, 5000) s(i)" +== 582 +-- truncate_limit: 100 +ANALYZE mcv_lists_uuid +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_uuid" +== 583 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-c..." +== 584 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND c = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-c..." +== 585 +-- truncate_limit: 100 +CREATE STATISTICS mcv_lists_uuid_stats (mcv) ON a, b, c + FROM mcv_lists_uuid +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_uuid_stats (mcv) ON a, b, c FROM mcv_lists_uuid" +== 586 +-- truncate_limit: 100 +ANALYZE mcv_lists_uuid +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_uuid" +== 587 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-c..." +== 588 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND c = ''e7f6c011-776e-8db7-cd33-0b54174fd76f''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-c..." +== 589 +-- truncate_limit: 100 +DROP TABLE mcv_lists_uuid +-- +TABLE: name="mcv_lists_uuid" schema="" table="mcv_lists_uuid" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcv_lists_uuid" +== 590 +-- truncate_limit: 100 +-- mcv with arrays +CREATE TABLE mcv_lists_arrays ( + a TEXT[], + b NUMERIC[], + c INT[] +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_arrays" schema="" table="mcv_lists_arrays" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcv_lists_arrays (a text[], b numeric[], c int[]) WITH (autovacuum_enabled=off)" +== 591 +-- truncate_limit: 100 +INSERT INTO mcv_lists_arrays (a, b, c) + SELECT + ARRAY[fipshash((i/100)::text), fipshash((i/100-1)::text), fipshash((i/100+1)::text)], + ARRAY[(i/100-1)::numeric/1000, (i/100)::numeric/1000, (i/100+1)::numeric/1000], + ARRAY[(i/100-1), i/100, (i/100+1)] + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists_arrays" schema="" table="mcv_lists_arrays" ctx=DML +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists_arrays (a, b, c) SELECT ... FROM generate_series(1, 5000) s(i)" +== 592 +-- truncate_limit: 100 +CREATE STATISTICS mcv_lists_arrays_stats (mcv) ON a, b, c + FROM mcv_lists_arrays +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_arrays_stats (mcv) ON a, b, c FROM mcv_lists_arrays" +== 593 +-- truncate_limit: 100 +ANALYZE mcv_lists_arrays +-- +TABLE: name="mcv_lists_arrays" schema="" table="mcv_lists_arrays" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_arrays" +== 594 +-- truncate_limit: 100 +-- mcv with bool +CREATE TABLE mcv_lists_bool ( + a BOOL, + b BOOL, + c BOOL +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcv_lists_bool (a bool, b bool, c bool) WITH (autovacuum_enabled=off)" +== 595 +-- truncate_limit: 100 +INSERT INTO mcv_lists_bool (a, b, c) + SELECT + (mod(i,2) = 0), (mod(i,4) = 0), (mod(i,8) = 0) + FROM generate_series(1,10000) s(i) +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists_bool (a, b, c) SELECT ... FROM generate_series(1, 10000) s(i)" +== 596 +-- truncate_limit: 100 +ANALYZE mcv_lists_bool +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_bool" +== 597 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c')" +== 598 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c')" +== 599 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c')" +== 600 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c')" +== 601 +-- truncate_limit: 100 +CREATE STATISTICS mcv_lists_bool_stats (mcv) ON a, b, c + FROM mcv_lists_bool +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_bool_stats (mcv) ON a, b, c FROM mcv_lists_bool" +== 602 +-- truncate_limit: 100 +ANALYZE mcv_lists_bool +-- +TABLE: name="mcv_lists_bool" schema="" table="mcv_lists_bool" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_bool" +== 603 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c')" +== 604 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c')" +== 605 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c')" +== 606 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c')" +== 607 +-- truncate_limit: 100 +-- mcv covering just a small fraction of data +CREATE TABLE mcv_lists_partial ( + a INT, + b INT, + c INT +) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcv_lists_partial (a int, b int, c int)" +== 608 +-- truncate_limit: 100 +-- 10 frequent groups, each with 100 elements +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + mod(i,10), + mod(i,10), + mod(i,10) + FROM generate_series(0,999) s(i) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists_partial (a, b, c) SELECT ... FROM generate_series(0, 999) s(i)" +== 609 +-- truncate_limit: 100 +-- 100 groups that will make it to the MCV list (includes the 10 frequent ones) +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + i, + i, + i + FROM generate_series(0,99) s(i) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists_partial (a, b, c) SELECT i, i, i FROM generate_series(0, 99) s(i)" +== 610 +-- truncate_limit: 100 +-- 4000 groups in total, most of which won't make it (just a single item) +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + i, + i, + i + FROM generate_series(0,3999) s(i) +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists_partial (a, b, c) SELECT i, i, i FROM generate_series(0, 3999) s(i)" +== 611 +-- truncate_limit: 100 +ANALYZE mcv_lists_partial +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_partial" +== 612 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c =..." +== 613 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0')" +== 614 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c..." +== 615 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c =..." +== 616 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c =..." +== 617 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10')" +== 618 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c ..." +== 619 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a..." +== 620 +-- truncate_limit: 100 +CREATE STATISTICS mcv_lists_partial_stats (mcv) ON a, b, c + FROM mcv_lists_partial +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_partial_stats (mcv) ON a, b, c FROM mcv_lists_partial" +== 621 +-- truncate_limit: 100 +ANALYZE mcv_lists_partial +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_partial" +== 622 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c =..." +== 623 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0')" +== 624 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c..." +== 625 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c =..." +== 626 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c =..." +== 627 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10')" +== 628 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c ..." +== 629 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a..." +== 630 +-- truncate_limit: 100 +DROP TABLE mcv_lists_partial +-- +TABLE: name="mcv_lists_partial" schema="" table="mcv_lists_partial" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcv_lists_partial" +== 631 +-- truncate_limit: 100 +-- check the ability to use multiple MCV lists +CREATE TABLE mcv_lists_multi ( + a INTEGER, + b INTEGER, + c INTEGER, + d INTEGER +) +WITH (autovacuum_enabled = off) +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mcv_lists_multi (a int, b int, c int, d int) WITH (autovacuum_enabled=off)" +== 632 +-- truncate_limit: 100 +INSERT INTO mcv_lists_multi (a, b, c, d) + SELECT + mod(i,5), + mod(i,5), + mod(i,7), + mod(i,7) + FROM generate_series(1,5000) s(i) +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mcv_lists_multi (a, b, c, d) SELECT ... FROM generate_series(1, 5000) s(i)" +== 633 +-- truncate_limit: 100 +ANALYZE mcv_lists_multi +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_multi" +== 634 +-- truncate_limit: 100 +-- estimates without any mcv statistics +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0')" +== 635 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0')" +== 636 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0')" +== 637 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0')" +== 638 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0..." +== 639 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c = 0 AND d = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c =..." +== 640 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 OR d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 O..." +== 641 +-- truncate_limit: 100 +-- create separate MCV statistics +CREATE STATISTICS mcv_lists_multi_1 (mcv) ON a, b FROM mcv_lists_multi +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_multi_1 (mcv) ON a, b FROM mcv_lists_multi" +== 642 +-- truncate_limit: 100 +CREATE STATISTICS mcv_lists_multi_2 (mcv) ON c, d FROM mcv_lists_multi +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS mcv_lists_multi_2 (mcv) ON c, d FROM mcv_lists_multi" +== 643 +-- truncate_limit: 100 +ANALYZE mcv_lists_multi +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE mcv_lists_multi" +== 644 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0')" +== 645 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0')" +== 646 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0')" +== 647 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0')" +== 648 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0..." +== 649 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c = 0 AND d = 0)') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c =..." +== 650 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 OR d = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 O..." +== 651 +-- truncate_limit: 100 +DROP TABLE mcv_lists_multi +-- +TABLE: name="mcv_lists_multi" schema="" table="mcv_lists_multi" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mcv_lists_multi" +== 652 +-- truncate_limit: 100 +-- statistics on integer expressions +CREATE TABLE expr_stats (a int, b int, c int) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE expr_stats (a int, b int, c int)" +== 653 +-- truncate_limit: 100 +INSERT INTO expr_stats SELECT mod(i,10), mod(i,10), mod(i,10) FROM generate_series(1,1000) s(i) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO expr_stats SELECT mod(i, 10), mod(i, 10), mod(i, 10) FROM generate_series(1, 1000) s(i)" +== 654 +-- truncate_limit: 100 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE expr_stats" +== 655 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0')" +== 656 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0')" +== 657 +-- truncate_limit: 100 +CREATE STATISTICS expr_stats_1 (mcv) ON (a+b), (a-b), (2*a), (3*b) FROM expr_stats +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS expr_stats_1 (mcv) ON (a + b), (a - b), (2 * a), (3 * b) FROM expr_stats" +== 658 +-- truncate_limit: 100 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE expr_stats" +== 659 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0')" +== 660 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0')" +== 661 +-- truncate_limit: 100 +DROP STATISTICS expr_stats_1 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS expr_stats_1" +== 662 +-- truncate_limit: 100 +DROP TABLE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE expr_stats" +== 663 +-- truncate_limit: 100 +-- statistics on a mix columns and expressions +CREATE TABLE expr_stats (a int, b int, c int) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE expr_stats (a int, b int, c int)" +== 664 +-- truncate_limit: 100 +INSERT INTO expr_stats SELECT mod(i,10), mod(i,10), mod(i,10) FROM generate_series(1,1000) s(i) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO expr_stats SELECT mod(i, 10), mod(i, 10), mod(i, 10) FROM generate_series(1, 1000) s(i)" +== 665 +-- truncate_limit: 100 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE expr_stats" +== 666 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) ..." +== 667 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0')" +== 668 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0')" +== 669 +-- truncate_limit: 100 +CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (2*a), (3*b), (a+b), (a-b) FROM expr_stats +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (2 * a), (3 * b), (a + b), (a - b) FROM expr_stats" +== 670 +-- truncate_limit: 100 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE expr_stats" +== 671 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) ..." +== 672 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0')" +== 673 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0')" +== 674 +-- truncate_limit: 100 +DROP TABLE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE expr_stats" +== 675 +-- truncate_limit: 100 +-- statistics on expressions with different data types +CREATE TABLE expr_stats (a int, b name, c text) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE expr_stats (a int, b name, c text)" +== 676 +-- truncate_limit: 100 +INSERT INTO expr_stats SELECT mod(i,10), fipshash(mod(i,10)::text), fipshash(mod(i,10)::text) FROM generate_series(1,1000) s(i) +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO expr_stats SELECT ... FROM generate_series(1, 1000) s(i)" +== 677 +-- truncate_limit: 100 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE expr_stats" +== 678 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AND (c || b) >= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AN..." +== 679 +-- truncate_limit: 100 +CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (b || c), (c || b) FROM expr_stats +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (b || c), (c || b) FROM expr_stats" +== 680 +-- truncate_limit: 100 +ANALYZE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE expr_stats" +== 681 +-- truncate_limit: 100 +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AND (c || b) >= ''0''') +-- +FUNCTION: name="check_estimated_rows" function="check_estimated_rows" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AN..." +== 682 +-- truncate_limit: 100 +DROP TABLE expr_stats +-- +TABLE: name="expr_stats" schema="" table="expr_stats" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE expr_stats" +== 683 +-- truncate_limit: 100 +-- test handling of a mix of compatible and incompatible expressions +CREATE TABLE expr_stats_incompatible_test ( + c0 double precision, + c1 boolean NOT NULL +) +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE expr_stats_incompatible_test (c0 double precision, c1 boolean NOT NULL)" +== 684 +-- truncate_limit: 100 +CREATE STATISTICS expr_stat_comp_1 ON c0, c1 FROM expr_stats_incompatible_test +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS expr_stat_comp_1 ON c0, c1 FROM expr_stats_incompatible_test" +== 685 +-- truncate_limit: 100 +INSERT INTO expr_stats_incompatible_test VALUES (1234,false), (5678,true) +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO expr_stats_incompatible_test VALUES (1234, false), (5678, true)" +== 686 +-- truncate_limit: 100 +ANALYZE expr_stats_incompatible_test +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE expr_stats_incompatible_test" +== 687 +-- truncate_limit: 100 +SELECT c0 FROM ONLY expr_stats_incompatible_test WHERE +( + upper('x') LIKE ('x'||('[0,1]'::int4range)) + AND + (c0 IN (0, 1) OR c1) +) +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FUNCTION: name="upper" function="upper" schema="" ctx=Call +FILTER: schema="" table="" column="c0" +FILTER: schema="" table="" column="c1" +STMT: SelectStmt +TRUNCATED: "SELECT c0 FROM ONLY expr_stats_incompatible_test WHERE ..." +== 688 +-- truncate_limit: 100 +DROP TABLE expr_stats_incompatible_test +-- +TABLE: name="expr_stats_incompatible_test" schema="" table="expr_stats_incompatible_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE expr_stats_incompatible_test" +== 689 +-- truncate_limit: 100 +-- Permission tests. Users should not be able to see specific data values in +-- the extended statistics, if they lack permission to see those values in +-- the underlying table. +|-- +-- Currently this is only relevant for MCV stats. +CREATE SCHEMA tststats +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA tststats" +== 690 +-- truncate_limit: 100 +CREATE TABLE tststats.priv_test_tbl ( + a int, + b int +) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tststats.priv_test_tbl (a int, b int)" +== 691 +-- truncate_limit: 100 +INSERT INTO tststats.priv_test_tbl + SELECT mod(i,5), mod(i,10) FROM generate_series(1,100) s(i) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DML +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="mod" function="mod" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tststats.priv_test_tbl SELECT mod(i, 5), mod(i, 10) FROM generate_series(1, 100) s(i)" +== 692 +-- truncate_limit: 100 +CREATE STATISTICS tststats.priv_test_stats (mcv) ON a, b + FROM tststats.priv_test_tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS tststats.priv_test_stats (mcv) ON a, b FROM tststats.priv_test_tbl" +== 693 +-- truncate_limit: 100 +ANALYZE tststats.priv_test_tbl +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE tststats.priv_test_tbl" +== 694 +-- truncate_limit: 100 +-- Check printing info about extended statistics by \dX +create table stts_t1 (a int, b int) +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stts_t1 (a int, b int)" +== 695 +-- truncate_limit: 100 +create statistics (ndistinct) on a, b from stts_t1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS (ndistinct) ON a, b FROM stts_t1" +== 696 +-- truncate_limit: 100 +create statistics (ndistinct, dependencies) on a, b from stts_t1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS (ndistinct, dependencies) ON a, b FROM stts_t1" +== 697 +-- truncate_limit: 100 +create statistics (ndistinct, dependencies, mcv) on a, b from stts_t1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS (ndistinct, dependencies, mcv) ON a, b FROM stts_t1" +== 698 +-- truncate_limit: 100 +create table stts_t2 (a int, b int, c int) +-- +TABLE: name="stts_t2" schema="" table="stts_t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stts_t2 (a int, b int, c int)" +== 699 +-- truncate_limit: 100 +create statistics on b, c from stts_t2 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ON b, c FROM stts_t2" +== 700 +-- truncate_limit: 100 +create table stts_t3 (col1 int, col2 int, col3 int) +-- +TABLE: name="stts_t3" schema="" table="stts_t3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stts_t3 (col1 int, col2 int, col3 int)" +== 701 +-- truncate_limit: 100 +create statistics stts_hoge on col1, col2, col3 from stts_t3 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS stts_hoge ON col1, col2, col3 FROM stts_t3" +== 702 +-- truncate_limit: 100 +create schema stts_s1 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA stts_s1" +== 703 +-- truncate_limit: 100 +create schema stts_s2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA stts_s2" +== 704 +-- truncate_limit: 100 +create statistics stts_s1.stts_foo on col1, col2 from stts_t3 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS stts_s1.stts_foo ON col1, col2 FROM stts_t3" +== 705 +-- truncate_limit: 100 +create statistics stts_s2.stts_yama (dependencies, mcv) on col1, col3 from stts_t3 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS stts_s2.stts_yama (dependencies, mcv) ON col1, col3 FROM stts_t3" +== 706 +-- truncate_limit: 100 +insert into stts_t1 select i,i from generate_series(1,100) i +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO stts_t1 SELECT i, i FROM generate_series(1, 100) i" +== 707 +-- truncate_limit: 100 +analyze stts_t1 +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE stts_t1" +== 708 +-- truncate_limit: 100 +set search_path to public, stts_s1, stts_s2, tststats +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO public, stts_s1, stts_s2, tststats" +== 709 +-- truncate_limit: 100 +create statistics (mcv) ON a, b, (a+b), (a-b) FROM stts_t1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS (mcv) ON a, b, (a + b), (a - b) FROM stts_t1" +== 710 +-- truncate_limit: 100 +create statistics (mcv) ON a, b, (a+b), (a-b) FROM stts_t1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS (mcv) ON a, b, (a + b), (a - b) FROM stts_t1" +== 711 +-- truncate_limit: 100 +create statistics (mcv) ON (a+b), (a-b) FROM stts_t1 +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS (mcv) ON (a + b), (a - b) FROM stts_t1" +== 712 +-- truncate_limit: 100 +drop statistics stts_t1_a_b_expr_expr_stat +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS stts_t1_a_b_expr_expr_stat" +== 713 +-- truncate_limit: 100 +drop statistics stts_t1_a_b_expr_expr_stat1 +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS stts_t1_a_b_expr_expr_stat1" +== 714 +-- truncate_limit: 100 +drop statistics stts_t1_expr_expr_stat +-- +STMT: DropStmt +TRUNCATED: "DROP STATISTICS stts_t1_expr_expr_stat" +== 715 +-- truncate_limit: 100 +set search_path to public, stts_s1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO public, stts_s1" +== 716 +-- truncate_limit: 100 +create role regress_stats_ext nosuperuser +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_stats_ext WITH NOSUPERUSER" +== 717 +-- truncate_limit: 100 +set role regress_stats_ext +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_stats_ext" +== 718 +-- truncate_limit: 100 +reset role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 719 +-- truncate_limit: 100 +drop table stts_t1, stts_t2, stts_t3 +-- +TABLE: name="stts_t1" schema="" table="stts_t1" ctx=DDL +TABLE: name="stts_t2" schema="" table="stts_t2" ctx=DDL +TABLE: name="stts_t3" schema="" table="stts_t3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE stts_t1, stts_t2, stts_t3" +== 720 +-- truncate_limit: 100 +drop schema stts_s1, stts_s2 cascade +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA stts_s1, stts_s2 CASCADE" +== 721 +-- truncate_limit: 100 +drop user regress_stats_ext +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_stats_ext" +== 722 +-- truncate_limit: 100 +reset search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 723 +-- truncate_limit: 100 +-- User with no access +CREATE USER regress_stats_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_stats_user1" +== 724 +-- truncate_limit: 100 +GRANT USAGE ON SCHEMA tststats TO regress_stats_user1 +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON SCHEMA tststats TO regress_stats_user1" +== 725 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 726 +-- truncate_limit: 100 +SELECT * FROM tststats.priv_test_tbl +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_tbl" +== 727 +-- truncate_limit: 100 +-- Permission denied + +-- Check individual columns if we don't have table privilege +SELECT * FROM tststats.priv_test_tbl + WHERE a = 1 and tststats.priv_test_tbl.* > (1, 1) is not null +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_tbl WHERE a = 1 AND tststats.priv_test_tbl.* > (1, 1) IS NOT NULL" +== 728 +-- truncate_limit: 100 +-- Attempt to gain access using a leaky operator +CREATE FUNCTION op_leak(int, int) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION op_leak(int, int) RETURNS bool AS $$BEGIN RAISE NOTICE 'op_leak => %, %', $1, $2;..." +== 729 +-- truncate_limit: 100 +CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, + restrict = scalarltsel) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, restrict = scalarltsel)" +== 730 +-- truncate_limit: 100 +CREATE FUNCTION op_leak(record, record) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION op_leak(record, record) RETURNS bool AS $$BEGIN RAISE NOTICE 'op_leak => %, %', $..." +== 731 +-- truncate_limit: 100 +CREATE OPERATOR <<< (procedure = op_leak, leftarg = record, rightarg = record, + restrict = scalarltsel) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR <<< (procedure = op_leak, leftarg = record, rightarg = record, restrict = scalarl..." +== 732 +-- truncate_limit: 100 +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0" +== 733 +-- truncate_limit: 100 +-- Permission denied +SELECT * FROM tststats.priv_test_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_tbl t WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL)" +== 734 +-- truncate_limit: 100 +-- Permission denied +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0" +== 735 +-- truncate_limit: 100 +-- Permission denied + +-- Grant access via a security barrier view, but hide all data +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 736 +-- truncate_limit: 100 +CREATE VIEW tststats.priv_test_view WITH (security_barrier=true) + AS SELECT * FROM tststats.priv_test_tbl WHERE false +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=DDL +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tststats.priv_test_view WITH (security_barrier=true) AS SELECT * FROM tststats.priv_t..." +== 737 +-- truncate_limit: 100 +GRANT SELECT, DELETE ON tststats.priv_test_view TO regress_stats_user1 +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select, delete ON tststats.priv_test_view TO regress_stats_user1" +== 738 +-- truncate_limit: 100 +-- Should now have access via the view, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 739 +-- truncate_limit: 100 +SELECT * FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0" +== 740 +-- truncate_limit: 100 +-- Should not leak +SELECT * FROM tststats.priv_test_view t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=Select +ALIAS: "t"="tststats.priv_test_view" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_view t WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL)" +== 741 +-- truncate_limit: 100 +-- Should not leak +DELETE FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_view" schema="tststats" table="priv_test_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0" +== 742 +-- truncate_limit: 100 +-- Should not leak + +-- Grant table access, but hide all data with RLS +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 743 +-- truncate_limit: 100 +ALTER TABLE tststats.priv_test_tbl ENABLE ROW LEVEL SECURITY +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tststats.priv_test_tbl ENABLE ROW LEVEL SECURITY" +== 744 +-- truncate_limit: 100 +CREATE POLICY priv_test_tbl_pol ON tststats.priv_test_tbl USING (2 * a < 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY priv_test_tbl_pol ON tststats.priv_test_tbl TO public USING ((2 * a) < 0)" +== 745 +-- truncate_limit: 100 +GRANT SELECT, DELETE ON tststats.priv_test_tbl TO regress_stats_user1 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select, delete ON tststats.priv_test_tbl TO regress_stats_user1" +== 746 +-- truncate_limit: 100 +-- Should now have direct table access, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 747 +-- truncate_limit: 100 +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0" +== 748 +-- truncate_limit: 100 +-- Should not leak +SELECT * FROM tststats.priv_test_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_tbl t WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL)" +== 749 +-- truncate_limit: 100 +-- Should not leak +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0" +== 750 +-- truncate_limit: 100 +-- Should not leak + +-- Create plain inheritance parent table with no access permissions +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 751 +-- truncate_limit: 100 +CREATE TABLE tststats.priv_test_parent_tbl (a int, b int) +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tststats.priv_test_parent_tbl (a int, b int)" +== 752 +-- truncate_limit: 100 +ALTER TABLE tststats.priv_test_tbl INHERIT tststats.priv_test_parent_tbl +-- +TABLE: name="tststats.priv_test_tbl" schema="tststats" table="priv_test_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tststats.priv_test_tbl INHERIT tststats.priv_test_parent_tbl" +== 753 +-- truncate_limit: 100 +-- Should not have access to parent, and should leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 754 +-- truncate_limit: 100 +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0" +== 755 +-- truncate_limit: 100 +-- Permission denied +SELECT * FROM tststats.priv_test_parent_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_parent_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_parent_tbl t WHERE ..." +== 756 +-- truncate_limit: 100 +-- Permission denied +DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0" +== 757 +-- truncate_limit: 100 +-- Permission denied + +-- Grant table access to parent, but hide all data with RLS +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 758 +-- truncate_limit: 100 +ALTER TABLE tststats.priv_test_parent_tbl ENABLE ROW LEVEL SECURITY +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tststats.priv_test_parent_tbl ENABLE ROW LEVEL SECURITY" +== 759 +-- truncate_limit: 100 +CREATE POLICY priv_test_parent_tbl_pol ON tststats.priv_test_parent_tbl USING (2 * a < 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY priv_test_parent_tbl_pol ON tststats.priv_test_parent_tbl TO public USING ((2 * a) ..." +== 760 +-- truncate_limit: 100 +GRANT SELECT, DELETE ON tststats.priv_test_parent_tbl TO regress_stats_user1 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select, delete ON tststats.priv_test_parent_tbl TO regress_stats_user1" +== 761 +-- truncate_limit: 100 +-- Should now have direct table access to parent, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 762 +-- truncate_limit: 100 +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0" +== 763 +-- truncate_limit: 100 +-- Should not leak +SELECT * FROM tststats.priv_test_parent_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL) +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=Select +ALIAS: "t"="tststats.priv_test_parent_tbl" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tststats.priv_test_parent_tbl t WHERE ..." +== 764 +-- truncate_limit: 100 +-- Should not leak +DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0 +-- +TABLE: name="tststats.priv_test_parent_tbl" schema="tststats" table="priv_test_parent_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0" +== 765 +-- truncate_limit: 100 +-- Should not leak + +-- privilege checks for pg_stats_ext and pg_stats_ext_exprs +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 766 +-- truncate_limit: 100 +CREATE TABLE stats_ext_tbl (id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, col TEXT) +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stats_ext_tbl (id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, col text)" +== 767 +-- truncate_limit: 100 +INSERT INTO stats_ext_tbl (col) VALUES ('secret'), ('secret'), ('very secret') +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO stats_ext_tbl (col) VALUES ('secret'), ('secret'), ('very secret')" +== 768 +-- truncate_limit: 100 +CREATE STATISTICS s_col ON id, col FROM stats_ext_tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s_col ON id, col FROM stats_ext_tbl" +== 769 +-- truncate_limit: 100 +CREATE STATISTICS s_expr ON mod(id, 2), lower(col) FROM stats_ext_tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS s_expr ON (mod(id, 2)), (lower(col)) FROM stats_ext_tbl" +== 770 +-- truncate_limit: 100 +ANALYZE stats_ext_tbl +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE stats_ext_tbl" +== 771 +-- truncate_limit: 100 +-- unprivileged role should not have access +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 772 +-- truncate_limit: 100 +SELECT statistics_name, most_common_vals FROM pg_stats_ext x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +ALIAS: "x"="pg_stats_ext" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stats_ext x WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*)" +== 773 +-- truncate_limit: 100 +SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext_exprs" schema="" table="pg_stats_ext_exprs" ctx=Select +ALIAS: "x"="pg_stats_ext_exprs" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stats_ext_exprs x WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*)" +== 774 +-- truncate_limit: 100 +-- give unprivileged role ownership of table +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 775 +-- truncate_limit: 100 +ALTER TABLE stats_ext_tbl OWNER TO regress_stats_user1 +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE stats_ext_tbl OWNER TO regress_stats_user1" +== 776 +-- truncate_limit: 100 +-- unprivileged role should now have access +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 777 +-- truncate_limit: 100 +SELECT statistics_name, most_common_vals FROM pg_stats_ext x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext" schema="" table="pg_stats_ext" ctx=Select +ALIAS: "x"="pg_stats_ext" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stats_ext x WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*)" +== 778 +-- truncate_limit: 100 +SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*) +-- +TABLE: name="pg_stats_ext_exprs" schema="" table="pg_stats_ext_exprs" ctx=Select +ALIAS: "x"="pg_stats_ext_exprs" +FILTER: schema="" table="" column="tablename" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stats_ext_exprs x WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*)" +== 779 +-- truncate_limit: 100 +-- CREATE STATISTICS checks for CREATE on the schema +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 780 +-- truncate_limit: 100 +CREATE SCHEMA sts_sch1 CREATE TABLE sts_sch1.tbl (a INT, b INT, c INT GENERATED ALWAYS AS (b * 2) STORED) +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA sts_sch1 CREATE TABLE sts_sch1.tbl (a int, b int, c int GENERATED ALWAYS AS (b * 2)..." +== 781 +-- truncate_limit: 100 +CREATE SCHEMA sts_sch2 +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA sts_sch2" +== 782 +-- truncate_limit: 100 +GRANT USAGE ON SCHEMA sts_sch1, sts_sch2 TO regress_stats_user1 +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON SCHEMA sts_sch1, sts_sch2 TO regress_stats_user1" +== 783 +-- truncate_limit: 100 +ALTER TABLE sts_sch1.tbl OWNER TO regress_stats_user1 +-- +TABLE: name="sts_sch1.tbl" schema="sts_sch1" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE sts_sch1.tbl OWNER TO regress_stats_user1" +== 784 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 785 +-- truncate_limit: 100 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl" +== 786 +-- truncate_limit: 100 +CREATE STATISTICS sts_sch2.fail ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS sts_sch2.fail ON a, b, c FROM sts_sch1.tbl" +== 787 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 788 +-- truncate_limit: 100 +GRANT CREATE ON SCHEMA sts_sch1 TO regress_stats_user1 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON SCHEMA sts_sch1 TO regress_stats_user1" +== 789 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 790 +-- truncate_limit: 100 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl" +== 791 +-- truncate_limit: 100 +CREATE STATISTICS sts_sch2.fail ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS sts_sch2.fail ON a, b, c FROM sts_sch1.tbl" +== 792 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 793 +-- truncate_limit: 100 +REVOKE CREATE ON SCHEMA sts_sch1 FROM regress_stats_user1 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE create ON SCHEMA sts_sch1 FROM regress_stats_user1" +== 794 +-- truncate_limit: 100 +GRANT CREATE ON SCHEMA sts_sch2 TO regress_stats_user1 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON SCHEMA sts_sch2 TO regress_stats_user1" +== 795 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 796 +-- truncate_limit: 100 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl" +== 797 +-- truncate_limit: 100 +CREATE STATISTICS sts_sch2.pass1 ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS sts_sch2.pass1 ON a, b, c FROM sts_sch1.tbl" +== 798 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 799 +-- truncate_limit: 100 +GRANT CREATE ON SCHEMA sts_sch1, sts_sch2 TO regress_stats_user1 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON SCHEMA sts_sch1, sts_sch2 TO regress_stats_user1" +== 800 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 801 +-- truncate_limit: 100 +CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS ON a, b, c FROM sts_sch1.tbl" +== 802 +-- truncate_limit: 100 +CREATE STATISTICS sts_sch2.pass2 ON a, b, c FROM sts_sch1.tbl +-- +STMT: CreateStatsStmt +TRUNCATED: "CREATE STATISTICS sts_sch2.pass2 ON a, b, c FROM sts_sch1.tbl" +== 803 +-- truncate_limit: 100 +-- re-creating statistics via ALTER TABLE bypasses checks for CREATE on schema +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 804 +-- truncate_limit: 100 +REVOKE CREATE ON SCHEMA sts_sch1, sts_sch2 FROM regress_stats_user1 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE create ON SCHEMA sts_sch1, sts_sch2 FROM regress_stats_user1" +== 805 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_stats_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_stats_user1" +== 806 +-- truncate_limit: 100 +ALTER TABLE sts_sch1.tbl ALTER COLUMN a TYPE SMALLINT +-- +TABLE: name="sts_sch1.tbl" schema="sts_sch1" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE sts_sch1.tbl ALTER COLUMN a TYPE smallint" +== 807 +-- truncate_limit: 100 +ALTER TABLE sts_sch1.tbl ALTER COLUMN c SET EXPRESSION AS (a * 3) +-- +TABLE: name="sts_sch1.tbl" schema="sts_sch1" table="tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE sts_sch1.tbl ALTER COLUMN c SET EXPRESSION AS (a * 3)" +== 808 +-- truncate_limit: 100 +-- Tidy up +DROP OPERATOR <<< (int, int) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR <<<(int, int)" +== 809 +-- truncate_limit: 100 +DROP FUNCTION op_leak(int, int) +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION op_leak(int, int)" +== 810 +-- truncate_limit: 100 +DROP OPERATOR <<< (record, record) +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR <<<(record, record)" +== 811 +-- truncate_limit: 100 +DROP FUNCTION op_leak(record, record) +-- +FUNCTION: name="op_leak" function="op_leak" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION op_leak(record, record)" +== 812 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 813 +-- truncate_limit: 100 +DROP TABLE stats_ext_tbl +-- +TABLE: name="stats_ext_tbl" schema="" table="stats_ext_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE stats_ext_tbl" +== 814 +-- truncate_limit: 100 +DROP SCHEMA tststats CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA tststats CASCADE" +== 815 +-- truncate_limit: 100 +DROP SCHEMA sts_sch1, sts_sch2 CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA sts_sch1, sts_sch2 CASCADE" +== 816 +-- truncate_limit: 100 +DROP USER regress_stats_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_stats_user1" diff --git a/parser/testdata/summary_truncate/postgres_regress/strings.metadata.json b/parser/testdata/summary_truncate/postgres_regress/strings.metadata.json new file mode 100644 index 0000000..f23fe5c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/strings.metadata.json @@ -0,0 +1,5 @@ +{ + "todo": [ + "001" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/strings.test b/parser/testdata/summary_truncate/postgres_regress/strings.test new file mode 100644 index 0000000..209da30 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/strings.test @@ -0,0 +1,869 @@ +== 001 +-- truncate_limit: 100 +|-- +-- STRINGS +-- Test various data entry syntaxes. +|-- + +-- SQL string continuation syntax +-- E021-03 character string literals +SELECT 'first line' +' - next line' + ' - third line' + AS "Three lines to one"; + +-- illegal string continuation syntax +SELECT 'first line' +' - next line' /* this comment is not allowed here */ +' - third line' + AS "Illegal comment within continuation"; + +-- Unicode escapes +SET standard_conforming_strings TO on; + +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; +SELECT U&'a\\b' AS "a\b"; + +SELECT U&' \' UESCAPE '!' AS "tricky"; +SELECT 'tricky' AS U&"\" UESCAPE '!'; + +SELECT U&'wrong: \061'; +SELECT U&'wrong: \+0061'; +SELECT U&'wrong: +0061' UESCAPE +; +SELECT U&'wrong: +0061' UESCAPE '+'; + +SELECT U&'wrong: \db99'; +SELECT U&'wrong: \db99xy'; +SELECT U&'wrong: \db99\\'; +SELECT U&'wrong: \db99\0061'; +SELECT U&'wrong: \+00db99\+000061'; +SELECT U&'wrong: \+2FFFFF'; + +-- while we're here, check the same cases in E-style literals +SELECT E'd\u0061t\U00000061' AS "data"; +SELECT E'a\\b' AS "a\b"; +SELECT E'wrong: \u061'; +SELECT E'wrong: \U0061'; +SELECT E'wrong: \udb99'; +SELECT E'wrong: \udb99xy'; +SELECT E'wrong: \udb99\\'; +SELECT E'wrong: \udb99\u0061'; +SELECT E'wrong: \U0000db99\U00000061'; +SELECT E'wrong: \U002FFFFF'; + +SET standard_conforming_strings TO off; + +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; + +SELECT U&' \' UESCAPE '!' AS "tricky"; +SELECT 'tricky' AS U&"\" UESCAPE '!'; + +SELECT U&'wrong: \061'; +SELECT U&'wrong: \+0061'; +SELECT U&'wrong: +0061' UESCAPE '+'; + +RESET standard_conforming_strings; + +-- bytea +SET bytea_output TO hex; +SELECT E'\\xDeAdBeEf'::bytea; +SELECT E'\\x De Ad Be Ef '::bytea; +SELECT E'\\xDeAdBeE'::bytea; +SELECT E'\\xDeAdBeEx'::bytea; +SELECT E'\\xDe00BeEf'::bytea; +SELECT E'DeAdBeEf'::bytea; +SELECT E'De\\000dBeEf'::bytea; +SELECT E'De\123dBeEf'::bytea; +SELECT E'De\\123dBeEf'::bytea; +SELECT E'De\\678dBeEf'::bytea; + +SET bytea_output TO escape; +SELECT E'\\xDeAdBeEf'::bytea; +SELECT E'\\x De Ad Be Ef '::bytea; +SELECT E'\\xDe00BeEf'::bytea; +SELECT E'DeAdBeEf'::bytea; +SELECT E'De\\000dBeEf'::bytea; +SELECT E'De\\123dBeEf'::bytea; + +-- Test non-error-throwing API too +SELECT pg_input_is_valid(E'\\xDeAdBeE', 'bytea'); +SELECT * FROM pg_input_error_info(E'\\xDeAdBeE', 'bytea'); +SELECT * FROM pg_input_error_info(E'\\xDeAdBeEx', 'bytea'); +SELECT * FROM pg_input_error_info(E'foo\\99bar', 'bytea'); + +|-- +-- test conversions between various string types +-- E021-10 implicit casting among the character data types +|-- + +SELECT CAST(f1 AS text) AS "text(char)" FROM CHAR_TBL; + +SELECT CAST(f1 AS text) AS "text(varchar)" FROM VARCHAR_TBL; + +SELECT CAST(name 'namefield' AS text) AS "text(name)"; + +-- since this is an explicit cast, it should truncate w/o error: +SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; +-- note: implicit-cast case is tested in char.sql + +SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL; + +SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL; + +SELECT CAST(name 'namefield' AS char(10)) AS "char(name)"; + +SELECT CAST(f1 AS varchar) AS "varchar(text)" FROM TEXT_TBL; + +SELECT CAST(f1 AS varchar) AS "varchar(char)" FROM CHAR_TBL; + +SELECT CAST(name 'namefield' AS varchar) AS "varchar(name)"; + +|-- +-- test SQL string functions +-- E### and T### are feature reference numbers from SQL99 +|-- + +-- E021-09 trim function +SELECT TRIM(BOTH FROM ' bunch o blanks ') = 'bunch o blanks' AS "bunch o blanks"; + +SELECT TRIM(LEADING FROM ' bunch o blanks ') = 'bunch o blanks ' AS "bunch o blanks "; + +SELECT TRIM(TRAILING FROM ' bunch o blanks ') = ' bunch o blanks' AS " bunch o blanks"; + +SELECT TRIM(BOTH 'x' FROM 'xxxxxsome Xsxxxxx') = 'some Xs' AS "some Xs"; + +-- E021-06 substring expression +SELECT SUBSTRING('1234567890' FROM 3) = '34567890' AS "34567890"; + +SELECT SUBSTRING('1234567890' FROM 4 FOR 3) = '456' AS "456"; + +-- test overflow cases +SELECT SUBSTRING('string' FROM 2 FOR 2147483646) AS "tring"; +SELECT SUBSTRING('string' FROM -10 FOR 2147483646) AS "string"; +SELECT SUBSTRING('string' FROM -10 FOR -2147483646) AS "error"; + +-- T581 regular expression substring (with SQL's bizarre regexp syntax) +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"(b_d)#"%' ESCAPE '#') AS "bcd"; +-- obsolete SQL99 syntax +SELECT SUBSTRING('abcdefg' FROM 'a#"(b_d)#"%' FOR '#') AS "bcd"; + +-- No match should return NULL +SELECT SUBSTRING('abcdefg' SIMILAR '#"(b_d)#"%' ESCAPE '#') IS NULL AS "True"; + +-- Null inputs should return NULL +SELECT SUBSTRING('abcdefg' SIMILAR '%' ESCAPE NULL) IS NULL AS "True"; +SELECT SUBSTRING(NULL SIMILAR '%' ESCAPE '#') IS NULL AS "True"; +SELECT SUBSTRING('abcdefg' SIMILAR NULL ESCAPE '#') IS NULL AS "True"; + +-- The first and last parts should act non-greedy +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%#"g' ESCAPE '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a*#"%#"g*' ESCAPE '#') AS "abcdefg"; + +-- Vertical bar in any part affects only that part +SELECT SUBSTRING('abcdefg' SIMILAR 'a|b#"%#"g' ESCAPE '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%#"x|g' ESCAPE '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%|ab#"g' ESCAPE '#') AS "bcdef"; + +-- Can't have more than two part separators +SELECT SUBSTRING('abcdefg' SIMILAR 'a*#"%#"g*#"x' ESCAPE '#') AS "error"; + +-- Postgres extension: with 0 or 1 separator, assume parts 1 and 3 are empty +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%g' ESCAPE '#') AS "bcdefg"; +SELECT SUBSTRING('abcdefg' SIMILAR 'a%g' ESCAPE '#') AS "abcdefg"; + +-- substring() with just two arguments is not allowed by SQL spec; +-- we accept it, but we interpret the pattern as a POSIX regexp not SQL +SELECT SUBSTRING('abcdefg' FROM 'c.e') AS "cde"; + +-- With a parenthesized subexpression, return only what matches the subexpr +SELECT SUBSTRING('abcdefg' FROM 'b(.*)f') AS "cde"; +-- Check case where we have a match, but not a subexpression match +SELECT SUBSTRING('foo' FROM 'foo(bar)?') IS NULL AS t; + +-- Check behavior of SIMILAR TO, which uses largely the same regexp variant +SELECT 'abcdefg' SIMILAR TO '_bcd%' AS true; +SELECT 'abcdefg' SIMILAR TO 'bcd%' AS false; +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '#' AS false; +SELECT 'abcd%' SIMILAR TO '_bcd#%' ESCAPE '#' AS true; +-- Postgres uses '\' as the default escape character, which is not per spec +SELECT 'abcdefg' SIMILAR TO '_bcd\%' AS false; +-- and an empty string to mean "no escape", which is also not per spec +SELECT 'abcd\efg' SIMILAR TO '_bcd\%' ESCAPE '' AS true; +-- these behaviors are per spec, though: +SELECT 'abcdefg' SIMILAR TO '_bcd%' ESCAPE NULL AS null; +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '##' AS error; + +-- Characters that should be left alone in character classes when a +-- SIMILAR TO regexp pattern is converted to POSIX style. +-- Underscore "_" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '_[_[:alpha:]_]_'; +-- Percentage "%" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '%[%[:alnum:]%]%'; +-- Dot "." +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '.[.[:alnum:].].'; +-- Dollar "$" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '$[$[:alnum:]$]$'; +-- Opening parenthesis "(" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '()[([:alnum:](]()'; +-- Caret "^" +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '^[^[:alnum:]^[^^][[^^]][\^][[\^]]\^]^'; +-- Closing square bracket "]" at the beginning of character class +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[]%][^]%][^%]%'; +-- Closing square bracket effective after two carets at the beginning +-- of character class. +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[^^]^'; +-- Closing square bracket after an escape sequence at the beginning of +-- a character closes the character class +EXPLAIN (COSTS OFF) SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[|a]%' ESCAPE '|'; + +-- Test backslash escapes in regexp_replace's replacement string +SELECT regexp_replace('1112223333', E'(\\d{3})(\\d{3})(\\d{4})', E'(\\1) \\2-\\3'); +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\&Y', 'g'); +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\\\Y', 'g'); +-- not an error, though perhaps it should be: +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\Y\\1Z\\'); + +SELECT regexp_replace('AAA BBB CCC ', E'\\s+', ' ', 'g'); +SELECT regexp_replace('AAA', '^|$', 'Z', 'g'); +SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'gi'); +-- invalid regexp option +SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'z'); + +-- extended regexp_replace tests +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 1); +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 1, 2); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 1, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 2, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 9, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 7, 0, 'i'); +-- 'g' flag should be ignored when N is specified +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 1, 'g'); +-- errors +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', -1, 0, 'i'); +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, -1, 'i'); +-- erroneous invocation of non-extended form +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', '1'); + +-- regexp_count tests +SELECT regexp_count('123123123123123', '(12)3'); +SELECT regexp_count('123123123123', '123', 1); +SELECT regexp_count('123123123123', '123', 3); +SELECT regexp_count('123123123123', '123', 33); +SELECT regexp_count('ABCABCABCABC', 'Abc', 1, ''); +SELECT regexp_count('ABCABCABCABC', 'Abc', 1, 'i'); +-- errors +SELECT regexp_count('123123123123', '123', 0); +SELECT regexp_count('123123123123', '123', -3); + +-- regexp_like tests +SELECT regexp_like('Steven', '^Ste(v|ph)en$'); +SELECT regexp_like('a'||CHR(10)||'d', 'a.d', 'n'); +SELECT regexp_like('a'||CHR(10)||'d', 'a.d', 's'); +SELECT regexp_like('abc', ' a . c ', 'x'); +SELECT regexp_like('abc', 'a.c', 'g'); -- error + +-- regexp_instr tests +SELECT regexp_instr('abcdefghi', 'd.f'); +SELECT regexp_instr('abcdefghi', 'd.q'); +SELECT regexp_instr('abcabcabc', 'a.c'); +SELECT regexp_instr('abcabcabc', 'a.c', 2); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 3); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 4); +SELECT regexp_instr('abcabcabc', 'A.C', 1, 2, 0, 'i'); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 0); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 1); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 2); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 3); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 4); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 5); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 0); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 1); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 2); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 3); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 4); +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 5); +-- Check case where we have a match, but not a subexpression match +SELECT regexp_instr('foo', 'foo(bar)?', 1, 1, 0, '', 1); +-- errors +SELECT regexp_instr('abcabcabc', 'a.c', 0, 1); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 0); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, -1); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 2); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, 'g'); +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, '', -1); + +-- regexp_substr tests +SELECT regexp_substr('abcdefghi', 'd.f'); +SELECT regexp_substr('abcdefghi', 'd.q') IS NULL AS t; +SELECT regexp_substr('abcabcabc', 'a.c'); +SELECT regexp_substr('abcabcabc', 'a.c', 2); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 3); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 4) IS NULL AS t; +SELECT regexp_substr('abcabcabc', 'A.C', 1, 2, 'i'); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 0); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 1); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 2); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 3); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 4); +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 5) IS NULL AS t; +-- Check case where we have a match, but not a subexpression match +SELECT regexp_substr('foo', 'foo(bar)?', 1, 1, '', 1) IS NULL AS t; +-- errors +SELECT regexp_substr('abcabcabc', 'a.c', 0, 1); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 0); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, 'g'); +SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, '', -1); + +-- set so we can tell NULL from empty string + +-- return all matches from regexp +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$); + +-- test case insensitive +SELECT regexp_matches('foObARbEqUEbAz', $re$(bar)(beque)$re$, 'i'); + +-- global option - more than one match +SELECT regexp_matches('foobarbequebazilbarfbonk', $re$(b[^b]+)(b[^b]+)$re$, 'g'); + +-- empty capture group (matched empty string) +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.*)(beque)$re$); +-- no match +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.+)(beque)$re$); +-- optional capture group did not match, null entry in array +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.+)?(beque)$re$); + +-- no capture groups +SELECT regexp_matches('foobarbequebaz', $re$barbeque$re$); + +-- start/end-of-line matches are of zero length +SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '^', 'mg'); +SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '$', 'mg'); +SELECT regexp_matches('1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '^.?', 'mg'); +SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '.?$', 'mg'); +SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4', '.?$', 'mg'); + +-- give me errors +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$, 'gz'); +SELECT regexp_matches('foobarbequebaz', $re$(barbeque$re$); +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque){2,1}$re$); + +-- split string on regexp +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', $re$\s+$re$) AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', $re$\s+$re$); + +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', $re$\s*$re$) AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', $re$\s*$re$); +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '') AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', ''); +-- case insensitive +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'i') AS foo; +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'i'); +-- no match of pattern +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', 'nomatch') AS foo; +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', 'nomatch'); +-- some corner cases +SELECT regexp_split_to_array('123456','1'); +SELECT regexp_split_to_array('123456','6'); +SELECT regexp_split_to_array('123456','.'); +SELECT regexp_split_to_array('123456',''); +SELECT regexp_split_to_array('123456','(?:)'); +SELECT regexp_split_to_array('1',''); +-- errors +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'zippy') AS foo; +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'iz'); +-- global option meaningless for regexp_split +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g') AS foo; +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g'); + +-- change NULL-display back + +-- E021-11 position expression +SELECT POSITION('4' IN '1234567890') = '4' AS "4"; + +SELECT POSITION('5' IN '1234567890') = '5' AS "5"; + +-- T312 character overlay function +SELECT OVERLAY('abcdef' PLACING '45' FROM 4) AS "abc45f"; + +SELECT OVERLAY('yabadoo' PLACING 'daba' FROM 5) AS "yabadaba"; + +SELECT OVERLAY('yabadoo' PLACING 'daba' FROM 5 FOR 0) AS "yabadabadoo"; + +SELECT OVERLAY('babosa' PLACING 'ubb' FROM 2 FOR 4) AS "bubba"; + +|-- +-- test LIKE +-- Be sure to form every test as a LIKE/NOT LIKE pair. +|-- + +-- simplest examples +-- E061-04 like predicate +SELECT 'hawkeye' LIKE 'h%' AS "true"; +SELECT 'hawkeye' NOT LIKE 'h%' AS "false"; + +SELECT 'hawkeye' LIKE 'H%' AS "false"; +SELECT 'hawkeye' NOT LIKE 'H%' AS "true"; + +SELECT 'hawkeye' LIKE 'indio%' AS "false"; +SELECT 'hawkeye' NOT LIKE 'indio%' AS "true"; + +SELECT 'hawkeye' LIKE 'h%eye' AS "true"; +SELECT 'hawkeye' NOT LIKE 'h%eye' AS "false"; + +SELECT 'indio' LIKE '_ndio' AS "true"; +SELECT 'indio' NOT LIKE '_ndio' AS "false"; + +SELECT 'indio' LIKE 'in__o' AS "true"; +SELECT 'indio' NOT LIKE 'in__o' AS "false"; + +SELECT 'indio' LIKE 'in_o' AS "false"; +SELECT 'indio' NOT LIKE 'in_o' AS "true"; + +SELECT 'abc'::name LIKE '_b_' AS "true"; +SELECT 'abc'::name NOT LIKE '_b_' AS "false"; + +SELECT 'abc'::bytea LIKE '_b_'::bytea AS "true"; +SELECT 'abc'::bytea NOT LIKE '_b_'::bytea AS "false"; + +-- unused escape character +SELECT 'hawkeye' LIKE 'h%' ESCAPE '#' AS "true"; +SELECT 'hawkeye' NOT LIKE 'h%' ESCAPE '#' AS "false"; + +SELECT 'indio' LIKE 'ind_o' ESCAPE '$' AS "true"; +SELECT 'indio' NOT LIKE 'ind_o' ESCAPE '$' AS "false"; + +-- escape character +-- E061-05 like predicate with escape clause +SELECT 'h%' LIKE 'h#%' ESCAPE '#' AS "true"; +SELECT 'h%' NOT LIKE 'h#%' ESCAPE '#' AS "false"; + +SELECT 'h%wkeye' LIKE 'h#%' ESCAPE '#' AS "false"; +SELECT 'h%wkeye' NOT LIKE 'h#%' ESCAPE '#' AS "true"; + +SELECT 'h%wkeye' LIKE 'h#%%' ESCAPE '#' AS "true"; +SELECT 'h%wkeye' NOT LIKE 'h#%%' ESCAPE '#' AS "false"; + +SELECT 'h%awkeye' LIKE 'h#%a%k%e' ESCAPE '#' AS "true"; +SELECT 'h%awkeye' NOT LIKE 'h#%a%k%e' ESCAPE '#' AS "false"; + +SELECT 'indio' LIKE '_ndio' ESCAPE '$' AS "true"; +SELECT 'indio' NOT LIKE '_ndio' ESCAPE '$' AS "false"; + +SELECT 'i_dio' LIKE 'i$_d_o' ESCAPE '$' AS "true"; +SELECT 'i_dio' NOT LIKE 'i$_d_o' ESCAPE '$' AS "false"; + +SELECT 'i_dio' LIKE 'i$_nd_o' ESCAPE '$' AS "false"; +SELECT 'i_dio' NOT LIKE 'i$_nd_o' ESCAPE '$' AS "true"; + +SELECT 'i_dio' LIKE 'i$_d%o' ESCAPE '$' AS "true"; +SELECT 'i_dio' NOT LIKE 'i$_d%o' ESCAPE '$' AS "false"; + +SELECT 'a_c'::bytea LIKE 'a$__'::bytea ESCAPE '$'::bytea AS "true"; +SELECT 'a_c'::bytea NOT LIKE 'a$__'::bytea ESCAPE '$'::bytea AS "false"; + +-- escape character same as pattern character +SELECT 'maca' LIKE 'm%aca' ESCAPE '%' AS "true"; +SELECT 'maca' NOT LIKE 'm%aca' ESCAPE '%' AS "false"; + +SELECT 'ma%a' LIKE 'm%a%%a' ESCAPE '%' AS "true"; +SELECT 'ma%a' NOT LIKE 'm%a%%a' ESCAPE '%' AS "false"; + +SELECT 'bear' LIKE 'b_ear' ESCAPE '_' AS "true"; +SELECT 'bear' NOT LIKE 'b_ear' ESCAPE '_' AS "false"; + +SELECT 'be_r' LIKE 'b_e__r' ESCAPE '_' AS "true"; +SELECT 'be_r' NOT LIKE 'b_e__r' ESCAPE '_' AS "false"; + +SELECT 'be_r' LIKE '__e__r' ESCAPE '_' AS "false"; +SELECT 'be_r' NOT LIKE '__e__r' ESCAPE '_' AS "true"; + + +|-- +-- test ILIKE (case-insensitive LIKE) +-- Be sure to form every test as an ILIKE/NOT ILIKE pair. +|-- + +SELECT 'hawkeye' ILIKE 'h%' AS "true"; +SELECT 'hawkeye' NOT ILIKE 'h%' AS "false"; + +SELECT 'hawkeye' ILIKE 'H%' AS "true"; +SELECT 'hawkeye' NOT ILIKE 'H%' AS "false"; + +SELECT 'hawkeye' ILIKE 'H%Eye' AS "true"; +SELECT 'hawkeye' NOT ILIKE 'H%Eye' AS "false"; + +SELECT 'Hawkeye' ILIKE 'h%' AS "true"; +SELECT 'Hawkeye' NOT ILIKE 'h%' AS "false"; + +SELECT 'ABC'::name ILIKE '_b_' AS "true"; +SELECT 'ABC'::name NOT ILIKE '_b_' AS "false"; + +|-- +-- test %/_ combination cases, cf bugs #4821 and #5478 +|-- + +SELECT 'foo' LIKE '_%' as t, 'f' LIKE '_%' as t, '' LIKE '_%' as f; +SELECT 'foo' LIKE '%_' as t, 'f' LIKE '%_' as t, '' LIKE '%_' as f; + +SELECT 'foo' LIKE '__%' as t, 'foo' LIKE '___%' as t, 'foo' LIKE '____%' as f; +SELECT 'foo' LIKE '%__' as t, 'foo' LIKE '%___' as t, 'foo' LIKE '%____' as f; + +SELECT 'jack' LIKE '%____%' AS t; + + +|-- +-- basic tests of LIKE with indexes +|-- + +CREATE TABLE texttest (a text PRIMARY KEY, b int); +SELECT * FROM texttest WHERE a LIKE '%1%'; + +CREATE TABLE byteatest (a bytea PRIMARY KEY, b int); +SELECT * FROM byteatest WHERE a LIKE '%1%'; + +DROP TABLE texttest, byteatest; + + +|-- +-- test implicit type conversion +|-- + +-- E021-07 character concatenation +SELECT 'unknown' || ' and unknown' AS "Concat unknown types"; + +SELECT text 'text' || ' and unknown' AS "Concat text to unknown type"; + +SELECT char(20) 'characters' || ' and text' AS "Concat char to unknown type"; + +SELECT text 'text' || char(20) ' and characters' AS "Concat text to char"; + +SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar"; + +|-- +-- test substr with toasted text values +|-- +CREATE TABLE toasttest(f1 text); + +insert into toasttest values(repeat('1234567890',10000)); +insert into toasttest values(repeat('1234567890',10000)); + +|-- +-- Ensure that some values are uncompressed, to test the faster substring +-- operation used in that case +|-- +alter table toasttest alter column f1 set storage external; +insert into toasttest values(repeat('1234567890',10000)); +insert into toasttest values(repeat('1234567890',10000)); + +-- If the starting position is zero or less, then return from the start of the string +-- adjusting the length to be consistent with the "negative start" per SQL. +SELECT substr(f1, -1, 5) from toasttest; + +-- If the length is less than zero, an ERROR is thrown. +SELECT substr(f1, 5, -1) from toasttest; + +-- If no third argument (length) is provided, the length to the end of the +-- string is assumed. +SELECT substr(f1, 99995) from toasttest; + +-- If start plus length is > string length, the result is truncated to +-- string length +SELECT substr(f1, 99995, 10) from toasttest; + +TRUNCATE TABLE toasttest; +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +-- expect >0 blocks +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + +TRUNCATE TABLE toasttest; +ALTER TABLE toasttest set (toast_tuple_target = 4080); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +INSERT INTO toasttest values (repeat('1234567890',300)); +-- expect 0 blocks +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + +DROP TABLE toasttest; + +|-- +-- test substr with toasted bytea values +|-- +CREATE TABLE toasttest(f1 bytea); + +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +|-- +-- Ensure that some values are uncompressed, to test the faster substring +-- operation used in that case +|-- +alter table toasttest alter column f1 set storage external; +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +-- If the starting position is zero or less, then return from the start of the string +-- adjusting the length to be consistent with the "negative start" per SQL. +SELECT substr(f1, -1, 5) from toasttest; + +-- If the length is less than zero, an ERROR is thrown. +SELECT substr(f1, 5, -1) from toasttest; + +-- If no third argument (length) is provided, the length to the end of the +-- string is assumed. +SELECT substr(f1, 99995) from toasttest; + +-- If start plus length is > string length, the result is truncated to +-- string length +SELECT substr(f1, 99995, 10) from toasttest; + +DROP TABLE toasttest; + +-- test internally compressing datums + +-- this tests compressing a datum to a very small size which exercises a +-- corner case in packed-varlena handling: even though small, the compressed +-- datum must be given a 4-byte header because there are no bits to indicate +-- compression in a 1-byte header + +CREATE TABLE toasttest (c char(4096)); +INSERT INTO toasttest VALUES('x'); +SELECT length(c), c::text FROM toasttest; +SELECT c FROM toasttest; +DROP TABLE toasttest; + +|-- +-- test length +|-- + +SELECT length('abcdef') AS "length_6"; + +|-- +-- test strpos +|-- + +SELECT strpos('abcdef', 'cd') AS "pos_3"; + +SELECT strpos('abcdef', 'xy') AS "pos_0"; + +SELECT strpos('abcdef', '') AS "pos_1"; + +SELECT strpos('', 'xy') AS "pos_0"; + +SELECT strpos('', '') AS "pos_1"; + +|-- +-- test replace +|-- +SELECT replace('abcdef', 'de', '45') AS "abc45f"; + +SELECT replace('yabadabadoo', 'ba', '123') AS "ya123da123doo"; + +SELECT replace('yabadoo', 'bad', '') AS "yaoo"; + +|-- +-- test split_part +|-- +select split_part('','@',1) AS "empty string"; + +select split_part('','@',-1) AS "empty string"; + +select split_part('joeuser@mydatabase','',1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','',2) AS "empty string"; + +select split_part('joeuser@mydatabase','',-1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','',-2) AS "empty string"; + +select split_part('joeuser@mydatabase','@',0) AS "an error"; + +select split_part('joeuser@mydatabase','@@',1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','@@',2) AS "empty string"; + +select split_part('joeuser@mydatabase','@',1) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',2) AS "mydatabase"; + +select split_part('joeuser@mydatabase','@',3) AS "empty string"; + +select split_part('@joeuser@mydatabase@','@',2) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',-1) AS "mydatabase"; + +select split_part('joeuser@mydatabase','@',-2) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',-3) AS "empty string"; + +select split_part('@joeuser@mydatabase@','@',-2) AS "mydatabase"; + +|-- +-- test to_bin, to_oct, and to_hex +|-- +select to_bin(-1234) AS "11111111111111111111101100101110"; +select to_bin(-1234::bigint); +select to_bin(256*256*256 - 1) AS "111111111111111111111111"; +select to_bin(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "11111111111111111111111111111111"; + +select to_oct(-1234) AS "37777775456"; +select to_oct(-1234::bigint) AS "1777777777777777775456"; +select to_oct(256*256*256 - 1) AS "77777777"; +select to_oct(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "37777777777"; + +select to_hex(-1234) AS "fffffb2e"; +select to_hex(-1234::bigint) AS "fffffffffffffb2e"; +select to_hex(256*256*256 - 1) AS "ffffff"; +select to_hex(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "ffffffff"; + +|-- +-- SHA-2 +|-- +SET bytea_output TO hex; + +SELECT sha224(''); +SELECT sha224('The quick brown fox jumps over the lazy dog.'); + +SELECT sha256(''); +SELECT sha256('The quick brown fox jumps over the lazy dog.'); + +SELECT sha384(''); +SELECT sha384('The quick brown fox jumps over the lazy dog.'); + +SELECT sha512(''); +SELECT sha512('The quick brown fox jumps over the lazy dog.'); + +|-- +-- encode/decode +|-- +SELECT encode('\x1234567890abcdef00', 'hex'); +SELECT decode('1234567890abcdef00', 'hex'); +SELECT encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea, 'base64'); +SELECT decode(encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea, + 'base64'), 'base64'); +SELECT encode('\x1234567890abcdef00', 'escape'); +SELECT decode(encode('\x1234567890abcdef00', 'escape'), 'escape'); + +|-- +-- get_bit/set_bit etc +|-- +SELECT get_bit('\x1234567890abcdef00'::bytea, 43); +SELECT get_bit('\x1234567890abcdef00'::bytea, 99); -- error +SELECT set_bit('\x1234567890abcdef00'::bytea, 43, 0); +SELECT set_bit('\x1234567890abcdef00'::bytea, 99, 0); -- error +SELECT get_byte('\x1234567890abcdef00'::bytea, 3); +SELECT get_byte('\x1234567890abcdef00'::bytea, 99); -- error +SELECT set_byte('\x1234567890abcdef00'::bytea, 7, 11); +SELECT set_byte('\x1234567890abcdef00'::bytea, 99, 11); -- error + +|-- +-- test behavior of escape_string_warning and standard_conforming_strings options +|-- +set escape_string_warning = off; +set standard_conforming_strings = off; + +show escape_string_warning; +show standard_conforming_strings; + +set escape_string_warning = on; +set standard_conforming_strings = on; + +show escape_string_warning; +show standard_conforming_strings; + +select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; + +set standard_conforming_strings = off; + +select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; + +set escape_string_warning = off; +set standard_conforming_strings = on; + +select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; + +set standard_conforming_strings = off; + +select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; + +reset standard_conforming_strings; + + +|-- +-- Additional string functions +|-- +SET bytea_output TO escape; + +SELECT initcap('hi THOMAS'); + +SELECT lpad('hi', 5, 'xy'); +SELECT lpad('hi', 5); +SELECT lpad('hi', -5, 'xy'); +SELECT lpad('hello', 2); +SELECT lpad('hi', 5, ''); + +SELECT rpad('hi', 5, 'xy'); +SELECT rpad('hi', 5); +SELECT rpad('hi', -5, 'xy'); +SELECT rpad('hello', 2); +SELECT rpad('hi', 5, ''); + +SELECT ltrim('zzzytrim', 'xyz'); + +SELECT translate('', '14', 'ax'); +SELECT translate('12345', '14', 'ax'); +SELECT translate('12345', '134', 'a'); + +SELECT ascii('x'); +SELECT ascii(''); + +SELECT chr(65); +SELECT chr(0); + +SELECT repeat('Pg', 4); +SELECT repeat('Pg', -4); + +SELECT SUBSTRING('1234567890'::bytea FROM 3) "34567890"; +SELECT SUBSTRING('1234567890'::bytea FROM 4 FOR 3) AS "456"; +SELECT SUBSTRING('string'::bytea FROM 2 FOR 2147483646) AS "tring"; +SELECT SUBSTRING('string'::bytea FROM -10 FOR 2147483646) AS "string"; +SELECT SUBSTRING('string'::bytea FROM -10 FOR -2147483646) AS "error"; + +SELECT trim(E'\\000'::bytea from E'\\000Tom\\000'::bytea); +SELECT trim(leading E'\\000'::bytea from E'\\000Tom\\000'::bytea); +SELECT trim(trailing E'\\000'::bytea from E'\\000Tom\\000'::bytea); +SELECT btrim(E'\\000trim\\000'::bytea, E'\\000'::bytea); +SELECT btrim(''::bytea, E'\\000'::bytea); +SELECT btrim(E'\\000trim\\000'::bytea, ''::bytea); +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'Th\\001omas'::bytea from 2),'escape'); +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 8),'escape'); +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5 for 3),'escape'); + +SELECT bit_count('\x1234567890'::bytea); + +SELECT unistr('\0064at\+0000610'); +SELECT unistr('d\u0061t\U000000610'); +SELECT unistr('a\\b'); +-- errors: +SELECT unistr('wrong: \db99'); +SELECT unistr('wrong: \db99\0061'); +SELECT unistr('wrong: \+00db99\+000061'); +SELECT unistr('wrong: \+2FFFFF'); +SELECT unistr('wrong: \udb99\u0061'); +SELECT unistr('wrong: \U0000db99\U00000061'); +SELECT unistr('wrong: \U002FFFFF'); +SELECT unistr('wrong: \xyz'); +-- +ERROR: syntax error at or near "' - third line'" +CURSORPOS: 318 +FILENAME: scan.l +FUNCNAME: scanner_yyerror diff --git a/parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json b/parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json new file mode 100644 index 0000000..d3267aa --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json @@ -0,0 +1,163 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/subscription.test b/parser/testdata/summary_truncate/postgres_regress/subscription.test new file mode 100644 index 0000000..b39244a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/subscription.test @@ -0,0 +1,1048 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SUBSCRIPTION +|-- + +CREATE ROLE regress_subscription_user LOGIN SUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_subscription_user WITH LOGIN SUPERUSER" +== 002 +-- truncate_limit: 100 +CREATE ROLE regress_subscription_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_subscription_user2" +== 003 +-- truncate_limit: 100 +CREATE ROLE regress_subscription_user3 IN ROLE pg_create_subscription +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_subscription_user3 WITH IN ROLE pg_create_subscription" +== 004 +-- truncate_limit: 100 +CREATE ROLE regress_subscription_user_dummy LOGIN NOSUPERUSER +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_subscription_user_dummy WITH LOGIN NOSUPERUSER" +== 005 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION 'regress_subscription_user' +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user" +== 006 +-- truncate_limit: 100 +-- fail - no publications +CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo' +-- +ERROR: syntax error at end of input +CURSORPOS: 79 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 007 +-- truncate_limit: 100 +-- fail - no connection +CREATE SUBSCRIPTION regress_testsub PUBLICATION foo +-- +ERROR: syntax error at or near "PUBLICATION" +CURSORPOS: 61 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 008 +-- truncate_limit: 100 +-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 009 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot)" +== 010 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 011 +-- truncate_limit: 100 +-- fail - invalid connection string +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub" +== 012 +-- truncate_limit: 100 +-- fail - duplicate publications +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, tes..." +== 013 +-- truncate_limit: 100 +-- ok +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 014 +-- truncate_limit: 100 +COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'" +== 015 +-- truncate_limit: 100 +SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s +-- +TABLE: name="pg_subscription" schema="" table="pg_subscription" ctx=Select +ALIAS: "s"="pg_subscription" +FUNCTION: name="obj_description" function="obj_description" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s" +== 016 +-- truncate_limit: 100 +-- Check if the subscription stats are created and stats_reset is updated +-- by pg_stat_reset_subscription_stats(). +SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_stat_subscription_stats" schema="" table="pg_stat_subscription_stats" ctx=Select +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub'" +== 017 +-- truncate_limit: 100 +SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_subscription" schema="" table="pg_subscription" ctx=Select +FUNCTION: name="pg_stat_reset_subscription_stats" function="pg_stat_reset_subscription_stats" schema="" ctx=Call +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub'" +== 018 +-- truncate_limit: 100 +SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_stat_subscription_stats" schema="" table="pg_stat_subscription_stats" ctx=Select +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub'" +== 019 +-- truncate_limit: 100 +-- Reset the stats again and check if the new reset_stats is updated. +SELECT stats_reset as prev_stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_stat_subscription_stats" schema="" table="pg_stat_subscription_stats" ctx=Select +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub'" +== 020 +-- truncate_limit: 100 +SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub' +-- +TABLE: name="pg_subscription" schema="" table="pg_subscription" ctx=Select +FUNCTION: name="pg_stat_reset_subscription_stats" function="pg_stat_reset_subscription_stats" schema="" ctx=Call +FILTER: schema="" table="" column="subname" +STMT: SelectStmt +TRUNCATED: "SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub'" +== 021 +-- truncate_limit: 100 +SELECT :'prev_stats_reset' < stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 8 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 022 +-- truncate_limit: 100 +-- fail - name already exists +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 023 +-- truncate_limit: 100 +-- fail - must be superuser +SET SESSION AUTHORIZATION 'regress_subscription_user2' +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user2" +== 024 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WIT..." +== 025 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION 'regress_subscription_user' +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user" +== 026 +-- truncate_limit: 100 +-- fail - invalid option combinations +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 027 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 028 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 029 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 030 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false, create_slot = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 031 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 032 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 033 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 034 +-- truncate_limit: 100 +-- ok - with slot_name = NONE +CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 035 +-- truncate_limit: 100 +-- fail +ALTER SUBSCRIPTION regress_testsub3 ENABLE +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub3 ENABLE" +== 036 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION" +== 037 +-- truncate_limit: 100 +-- fail - origin must be either none or any +CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = foo) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 038 +-- truncate_limit: 100 +-- now it works +CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = none) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub..." +== 039 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub4 SET (origin = any) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub4 SET (origin = any)" +== 040 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub3 +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub3" +== 041 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub4 +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub4" +== 042 +-- truncate_limit: 100 +-- fail, connection string does not parse +CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'i_dont_exist=param' PUBLICATION testpub +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'i_dont_exist=param' PUBLICATION testpub" +== 043 +-- truncate_limit: 100 +-- fail, connection string parses, but doesn't work (and does so without +-- connecting, so this is reliable and safe) +CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'port=-1' PUBLICATION testpub +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'port=-1' PUBLICATION testpub" +== 044 +-- truncate_limit: 100 +-- fail - invalid connection string during ALTER +ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar' +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'" +== 045 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false)" +== 046 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2' +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'" +== 047 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname') +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname')" +== 048 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (password_required = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (password_required = false)" +== 049 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = true) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = true)" +== 050 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (password_required = true) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (password_required = true)" +== 051 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = false)" +== 052 +-- truncate_limit: 100 +-- fail +ALTER SUBSCRIPTION regress_testsub SET (slot_name = '') +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = '')" +== 053 +-- truncate_limit: 100 +-- fail +ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2' +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2'" +== 054 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (create_slot = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (create_slot = false)" +== 055 +-- truncate_limit: 100 +-- ok +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/12345') +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/12345')" +== 056 +-- truncate_limit: 100 +-- ok - with lsn = NONE +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SKIP (lsn = NONE)" +== 057 +-- truncate_limit: 100 +-- fail +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/0') +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/0')" +== 058 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 059 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub ENABLE +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub ENABLE" +== 060 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub DISABLE +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub DISABLE" +== 061 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 062 +-- truncate_limit: 100 +-- fail - must be owner of subscription +SET ROLE regress_subscription_user_dummy +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_subscription_user_dummy" +== 063 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy +-- +STMT: RenameStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy" +== 064 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 065 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo +-- +STMT: RenameStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo" +== 066 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local)" +== 067 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar)" +== 068 +-- truncate_limit: 100 +-- rename back to keep the rest simple +ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub +-- +STMT: RenameStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub" +== 069 +-- truncate_limit: 100 +-- ok, we're a superuser +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2" +== 070 +-- truncate_limit: 100 +-- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 071 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 072 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 073 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 074 +-- truncate_limit: 100 +-- now it works +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 075 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 076 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 077 +-- truncate_limit: 100 +DROP SUBSCRIPTION IF EXISTS regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION IF EXISTS regress_testsub" +== 078 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 079 +-- truncate_limit: 100 +-- fail + +-- fail - binary must be boolean +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = foo) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 080 +-- truncate_limit: 100 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 081 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (binary = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (\"binary\" = false)" +== 082 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 083 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 084 +-- truncate_limit: 100 +-- fail - streaming must be boolean or 'parallel' +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = foo) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 085 +-- truncate_limit: 100 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 086 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (streaming = parallel) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (streaming = parallel)" +== 087 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (streaming = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (streaming = false)" +== 088 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 089 +-- truncate_limit: 100 +-- fail - publication already exists +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub WITH (refresh = false)" +== 090 +-- truncate_limit: 100 +-- fail - publication used more than once +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub1 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub1 WITH (refresh = false)" +== 091 +-- truncate_limit: 100 +-- ok - add two publications into subscription +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 WITH (refresh = false)" +== 092 +-- truncate_limit: 100 +-- fail - publications already exist +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 WITH (refresh = false)" +== 093 +-- truncate_limit: 100 +-- fail - publication used more than once +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub1 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub1 WITH (refresh = false)" +== 094 +-- truncate_limit: 100 +-- fail - all publications are deleted +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub, testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub, testpub1, testpub2 WITH (refresh = f..." +== 095 +-- truncate_limit: 100 +-- fail - publication does not exist in subscription +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub3 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub3 WITH (refresh = false)" +== 096 +-- truncate_limit: 100 +-- ok - delete publications +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub2 WITH (refresh = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub2 WITH (refresh = false)" +== 097 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 098 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION mypub + WITH (connect = false, create_slot = false, copy_data = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION mypub WI..." +== 099 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub ENABLE +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub ENABLE" +== 100 +-- truncate_limit: 100 +-- fail - ALTER SUBSCRIPTION with refresh is not allowed in a transaction +-- block or function +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 101 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh = true) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh = true)" +== 102 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 103 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 104 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub REFRESH PUBLICATION +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub REFRESH PUBLICATION" +== 105 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 106 +-- truncate_limit: 100 +CREATE FUNCTION func() RETURNS VOID AS +$$ ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh = true) $$ LANGUAGE SQL +-- +FUNCTION: name="func" function="func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION func() RETURNS void AS $$ ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypu..." +== 107 +-- truncate_limit: 100 +SELECT func() +-- +FUNCTION: name="func" function="func" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT func()" +== 108 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub DISABLE +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub DISABLE" +== 109 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 110 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 111 +-- truncate_limit: 100 +DROP FUNCTION func +-- +FUNCTION: name="func" function="func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION func" +== 112 +-- truncate_limit: 100 +-- fail - two_phase must be boolean +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = foo) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 113 +-- truncate_limit: 100 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 114 +-- truncate_limit: 100 +--fail - alter of two_phase option not supported. +ALTER SUBSCRIPTION regress_testsub SET (two_phase = false) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (two_phase = false)" +== 115 +-- truncate_limit: 100 +-- but can alter streaming when two_phase enabled +ALTER SUBSCRIPTION regress_testsub SET (streaming = true) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (streaming = true)" +== 116 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 117 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 118 +-- truncate_limit: 100 +-- two_phase and streaming are compatible. +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true, two_phase = true) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 119 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 120 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 121 +-- truncate_limit: 100 +-- fail - disable_on_error must be boolean +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = foo) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 122 +-- truncate_limit: 100 +-- now it works +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 123 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (disable_on_error = true) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (disable_on_error = true)" +== 124 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 125 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 126 +-- truncate_limit: 100 +-- let's do some tests with pg_create_subscription rather than superuser +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user3" +== 127 +-- truncate_limit: 100 +-- fail, not enough privileges +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 128 +-- truncate_limit: 100 +-- fail, must specify password +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 129 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_subscription_user3" +== 130 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user3" +== 131 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 132 +-- truncate_limit: 100 +-- fail, can't set password_required=false +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 133 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_subscription_user3" +== 134 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user3" +== 135 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, password_required = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub ..." +== 136 +-- truncate_limit: 100 +-- ok +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 137 +-- truncate_limit: 100 +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3 +-- +STMT: GrantStmt +TRUNCATED: "GRANT create ON DATABASE regression TO regress_subscription_user3" +== 138 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user3" +== 139 +-- truncate_limit: 100 +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist password=regress_fakepassword' PUBLICATION testpub WITH (connect = false) +-- +STMT: CreateSubscriptionStmt +TRUNCATED: "CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist password=regress_fake..." +== 140 +-- truncate_limit: 100 +-- we cannot give the subscription away to some random user +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user" +== 141 +-- truncate_limit: 100 +-- but we can rename the subscription we just created +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2" +== 142 +-- truncate_limit: 100 +-- ok, even after losing pg_create_subscription we can still rename it +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 143 +-- truncate_limit: 100 +REVOKE pg_create_subscription FROM regress_subscription_user3 +-- +STMT: GrantRoleStmt +TRUNCATED: "REVOKE pg_create_subscription FROM regress_subscription_user3" +== 144 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user3" +== 145 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub2 RENAME TO regress_testsub +-- +STMT: RenameStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub2 RENAME TO regress_testsub" +== 146 +-- truncate_limit: 100 +-- fail, after losing CREATE on the database we can't rename it any more +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 147 +-- truncate_limit: 100 +REVOKE CREATE ON DATABASE REGRESSION FROM regress_subscription_user3 +-- +STMT: GrantStmt +TRUNCATED: "REVOKE create ON DATABASE regression FROM regress_subscription_user3" +== 148 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_subscription_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_subscription_user3" +== 149 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2 +-- +STMT: RenameStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2" +== 150 +-- truncate_limit: 100 +-- fail - cannot do ALTER SUBSCRIPTION SET (failover) inside transaction block +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 151 +-- truncate_limit: 100 +ALTER SUBSCRIPTION regress_testsub SET (failover) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (failover)" +== 152 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 153 +-- truncate_limit: 100 +-- ok, owning it is enough for this stuff +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE) +-- +STMT: AlterSubscriptionStmt +TRUNCATED: "ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE)" +== 154 +-- truncate_limit: 100 +DROP SUBSCRIPTION regress_testsub +-- +STMT: DropSubscriptionStmt +TRUNCATED: "DROP SUBSCRIPTION regress_testsub" +== 155 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 156 +-- truncate_limit: 100 +DROP ROLE regress_subscription_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_subscription_user" +== 157 +-- truncate_limit: 100 +DROP ROLE regress_subscription_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_subscription_user2" +== 158 +-- truncate_limit: 100 +DROP ROLE regress_subscription_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_subscription_user3" +== 159 +-- truncate_limit: 100 +DROP ROLE regress_subscription_user_dummy +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_subscription_user_dummy" diff --git a/parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json b/parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json new file mode 100644 index 0000000..354a8d0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json @@ -0,0 +1,273 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/subselect.test b/parser/testdata/summary_truncate/postgres_regress/subselect.test new file mode 100644 index 0000000..a30ce98 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/subselect.test @@ -0,0 +1,3098 @@ +== 001 +-- truncate_limit: 100 +|-- +-- SUBSELECT +|-- + +SELECT 1 AS one WHERE 1 IN (SELECT 1) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one WHERE 1 IN (SELECT 1)" +== 002 +-- truncate_limit: 100 +SELECT 1 AS zero WHERE 1 NOT IN (SELECT 1) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS zero WHERE NOT 1 IN (SELECT 1)" +== 003 +-- truncate_limit: 100 +SELECT 1 AS zero WHERE 1 IN (SELECT 2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS zero WHERE 1 IN (SELECT 2)" +== 004 +-- truncate_limit: 100 +-- Check grammar's handling of extra parens in assorted contexts + +SELECT * FROM (SELECT 1 AS x) ss +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 1 AS x) ss" +== 005 +-- truncate_limit: 100 +SELECT * FROM ((SELECT 1 AS x)) ss +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 1 AS x) ss" +== 006 +-- truncate_limit: 100 +SELECT * FROM ((SELECT 1 AS x)), ((SELECT * FROM ((SELECT 2 AS y)))) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 1 AS x), (SELECT * FROM (SELECT 2 AS y))" +== 007 +-- truncate_limit: 100 +(SELECT 2) UNION SELECT 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 UNION SELECT 2" +== 008 +-- truncate_limit: 100 +((SELECT 2)) UNION SELECT 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2 UNION SELECT 2" +== 009 +-- truncate_limit: 100 +SELECT ((SELECT 2) UNION SELECT 2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT 2 UNION SELECT 2)" +== 010 +-- truncate_limit: 100 +SELECT (((SELECT 2)) UNION SELECT 2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT 2 UNION SELECT 2)" +== 011 +-- truncate_limit: 100 +SELECT (SELECT ARRAY[1,2,3])[1] +-- +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT ARRAY[1, 2, 3])[1]" +== 012 +-- truncate_limit: 100 +SELECT ((SELECT ARRAY[1,2,3]))[2] +-- +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT ARRAY[1, 2, 3])[2]" +== 013 +-- truncate_limit: 100 +SELECT (((SELECT ARRAY[1,2,3])))[3] +-- +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT ARRAY[1, 2, 3])[3]" +== 014 +-- truncate_limit: 100 +-- Set up some simple test tables + +CREATE TABLE SUBSELECT_TBL ( + f1 integer, + f2 integer, + f3 float +) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE subselect_tbl (f1 int, f2 int, f3 double precision)" +== 015 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (1, 2, 3)" +== 016 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (2, 3, 4)" +== 017 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (3, 4, 5)" +== 018 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (1, 1, 1) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (1, 1, 1)" +== 019 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (2, 2, 2) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (2, 2, 2)" +== 020 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (3, 3, 3) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (3, 3, 3)" +== 021 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (6, 7, 8) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (6, 7, 8)" +== 022 +-- truncate_limit: 100 +INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO subselect_tbl VALUES (8, 9, NULL)" +== 023 +-- truncate_limit: 100 +SELECT * FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM subselect_tbl" +== 024 +-- truncate_limit: 100 +-- Uncorrelated subselects + +SELECT f1 AS "Constant Select" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT 1) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Constant Select\" FROM subselect_tbl WHERE f1 IN (SELECT 1)" +== 025 +-- truncate_limit: 100 +SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Uncorrelated Field\" FROM subselect_tbl WHERE f1 IN (SELECT f2 FROM subselect_tbl)" +== 026 +-- truncate_limit: 100 +SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE + f2 IN (SELECT f1 FROM SUBSELECT_TBL)) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Uncorrelated Field\" FROM subselect_tbl WHERE ..." +== 027 +-- truncate_limit: 100 +SELECT f1, f2 + FROM SUBSELECT_TBL + WHERE (f1, f2) NOT IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL + WHERE f3 IS NOT NULL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +TRUNCATED: "SELECT f1, f2 FROM subselect_tbl WHERE NOT (f1, f2) IN (SELECT ... FROM subselect_tbl WHERE ...)" +== 028 +-- truncate_limit: 100 +-- Correlated subselects + +SELECT f1 AS "Correlated Field", f2 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "upper"="subselect_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="upper" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Correlated Field\", f2 AS \"Second Field\" FROM subselect_tbl upper WHERE ..." +== 029 +-- truncate_limit: 100 +SELECT f1 AS "Correlated Field", f3 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f1 IN + (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "upper"="subselect_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="upper" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Correlated Field\", f3 AS \"Second Field\" FROM subselect_tbl upper WHERE ..." +== 030 +-- truncate_limit: 100 +SELECT f1 AS "Correlated Field", f3 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f3 IN (SELECT upper.f1 + f2 FROM SUBSELECT_TBL + WHERE f2 = CAST(f3 AS integer)) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "upper"="subselect_tbl" +FILTER: schema="" table="" column="f3" +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Correlated Field\", f3 AS \"Second Field\" FROM subselect_tbl upper WHERE ..." +== 031 +-- truncate_limit: 100 +SELECT f1 AS "Correlated Field" + FROM SUBSELECT_TBL + WHERE (f1, f2) IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL + WHERE f3 IS NOT NULL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +FILTER: schema="" table="" column="f3" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Correlated Field\" FROM subselect_tbl WHERE ..." +== 032 +-- truncate_limit: 100 +-- Check ROWCOMPARE cases, both correlated and not + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM subselect_tbl" +== 033 +-- truncate_limit: 100 +SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM subselect_tbl" +== 034 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM subselect_tbl" +== 035 +-- truncate_limit: 100 +SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM SUBSELECT_TBL +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM subselect_tbl" +== 036 +-- truncate_limit: 100 +SELECT ROW(1, 2) = (SELECT f1, f2 FROM SUBSELECT_TBL) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ROW(1, 2) = (SELECT f1, f2 FROM subselect_tbl)" +== 037 +-- truncate_limit: 100 +-- error + +-- Subselects without aliases + +SELECT count FROM (SELECT COUNT(DISTINCT name) FROM road) +-- +TABLE: name="road" schema="" table="road" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count FROM (SELECT count(DISTINCT name) FROM road)" +== 038 +-- truncate_limit: 100 +SELECT COUNT(*) FROM (SELECT DISTINCT name FROM road) +-- +TABLE: name="road" schema="" table="road" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT DISTINCT name FROM road)" +== 039 +-- truncate_limit: 100 +SELECT * FROM (SELECT * FROM int4_tbl), (VALUES (123456)) WHERE f1 = column1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="column1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM int4_tbl), (VALUES (123456)) WHERE f1 = column1" +== 040 +-- truncate_limit: 100 +CREATE VIEW view_unnamed_ss AS +SELECT * FROM (SELECT * FROM (SELECT abs(f1) AS a1 FROM int4_tbl)), + (SELECT * FROM int8_tbl) + WHERE a1 < 10 AND q1 > a1 ORDER BY q1, q2 +-- +TABLE: name="view_unnamed_ss" schema="" table="view_unnamed_ss" ctx=DDL +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a1" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="a1" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_unnamed_ss AS SELECT * FROM (SELECT * FROM (SELECT abs(f1) AS a1 FROM int4_tbl))..." +== 041 +-- truncate_limit: 100 +SELECT * FROM view_unnamed_ss +-- +TABLE: name="view_unnamed_ss" schema="" table="view_unnamed_ss" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM view_unnamed_ss" +== 042 +-- truncate_limit: 100 +DROP VIEW view_unnamed_ss +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW view_unnamed_ss" +== 043 +-- truncate_limit: 100 +-- Test matching of locking clause to correct alias + +CREATE VIEW view_unnamed_ss_locking AS +SELECT * FROM (SELECT * FROM int4_tbl), int8_tbl AS unnamed_subquery + WHERE f1 = q1 + FOR UPDATE OF unnamed_subquery +-- +TABLE: name="view_unnamed_ss_locking" schema="" table="view_unnamed_ss_locking" ctx=DDL +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "unnamed_subquery"="int8_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="q1" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW view_unnamed_ss_locking AS SELECT * FROM (SELECT * FROM int4_tbl), int8_tbl unnamed_s..." +== 044 +-- truncate_limit: 100 +DROP VIEW view_unnamed_ss_locking +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW view_unnamed_ss_locking" +== 045 +-- truncate_limit: 100 +|-- +-- Use some existing tables in the regression test +|-- + +SELECT ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" + FROM SUBSELECT_TBL ss + WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL + WHERE f1 != ss.f1 AND f1 < 2147483647) +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "ss"="subselect_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="ss" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT ss.f1 AS \"Correlated Field\", ss.f3 AS \"Second Field\" FROM subselect_tbl ss WHERE ..." +== 046 +-- truncate_limit: 100 +select q1, float8(count(*)) / (select count(*) from int8_tbl) +from int8_tbl group by q1 order by q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="float8" function="float8" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q1, float8(count(*)) / (SELECT count(*) FROM int8_tbl) FROM int8_tbl GROUP BY q1 ORDER BY q1" +== 047 +-- truncate_limit: 100 +-- Unspecified-type literals in output columns should resolve as text + +SELECT *, pg_typeof(f1) FROM + (SELECT 'foo' AS f1 FROM generate_series(1,3)) ss ORDER BY 1 +-- +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT *, pg_typeof(f1) FROM (SELECT 'foo' AS f1 FROM generate_series(1, 3)) ss ORDER BY 1" +== 048 +-- truncate_limit: 100 +-- ... unless there's context to suggest differently + +explain (verbose, costs off) select '42' union all select '43' +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT '42' UNION ALL SELECT '43'" +== 049 +-- truncate_limit: 100 +explain (verbose, costs off) select '42' union all select 43 +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT '42' UNION ALL SELECT 43" +== 050 +-- truncate_limit: 100 +-- check materialization of an initplan reference (bug #14524) +explain (verbose, costs off) +select 1 = all (select (select 1)) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 = ALL (SELECT (SELECT 1))" +== 051 +-- truncate_limit: 100 +select 1 = all (select (select 1)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 = ALL (SELECT (SELECT 1))" +== 052 +-- truncate_limit: 100 +|-- +-- Check EXISTS simplification with LIMIT +|-- +explain (costs off) +select * from int4_tbl o where exists + (select 1 from int4_tbl i where i.f1=o.f1 limit null) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="o" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl o WHERE EXISTS (SELECT 1 FROM int4_tbl i WHERE i.f1 = ..." +== 053 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl o where not exists + (select 1 from int4_tbl i where i.f1=o.f1 limit 1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="o" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl o WHERE NOT EXISTS (SELECT 1 FROM int4_tbl i WHERE i.f..." +== 054 +-- truncate_limit: 100 +explain (costs off) +select * from int4_tbl o where exists + (select 1 from int4_tbl i where i.f1=o.f1 limit 0) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FILTER: schema="" table="i" column="f1" +FILTER: schema="" table="o" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int4_tbl o WHERE EXISTS (SELECT 1 FROM int4_tbl i WHERE i.f1 = ..." +== 055 +-- truncate_limit: 100 +|-- +-- Test cases to catch unpleasant interactions between IN-join processing +-- and subquery pullup. +|-- + +select count(*) from + (select 1 from tenk1 a + where unique1 IN (select hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT 1 FROM tenk1 a WHERE unique1 IN (SELECT hundred FROM tenk1 b)) ss" +== 056 +-- truncate_limit: 100 +select count(distinct ss.ten) from + (select ten from tenk1 a + where unique1 IN (select hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT ss.ten) FROM (SELECT ten FROM tenk1 a WHERE ...) ss" +== 057 +-- truncate_limit: 100 +select count(*) from + (select 1 from tenk1 a + where unique1 IN (select distinct hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT 1 FROM tenk1 a WHERE ...) ss" +== 058 +-- truncate_limit: 100 +select count(distinct ss.ten) from + (select ten from tenk1 a + where unique1 IN (select distinct hundred from tenk1 b)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT ss.ten) FROM (SELECT ten FROM tenk1 a WHERE ...) ss" +== 059 +-- truncate_limit: 100 +|-- +-- Test cases to check for overenthusiastic optimization of +-- "IN (SELECT DISTINCT ...)" and related cases. Per example from +-- Luca Pireddu and Michael Fuhr. +|-- + +CREATE TEMP TABLE foo (id integer) +-- +TABLE: name="foo" schema="" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE foo (id int)" +== 060 +-- truncate_limit: 100 +CREATE TEMP TABLE bar (id1 integer, id2 integer) +-- +TABLE: name="bar" schema="" table="bar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE bar (id1 int, id2 int)" +== 061 +-- truncate_limit: 100 +INSERT INTO foo VALUES (1) +-- +TABLE: name="foo" schema="" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO foo VALUES (1)" +== 062 +-- truncate_limit: 100 +INSERT INTO bar VALUES (1, 1) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar VALUES (1, 1)" +== 063 +-- truncate_limit: 100 +INSERT INTO bar VALUES (2, 2) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar VALUES (2, 2)" +== 064 +-- truncate_limit: 100 +INSERT INTO bar VALUES (3, 1) +-- +TABLE: name="bar" schema="" table="bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO bar VALUES (3, 1)" +== 065 +-- truncate_limit: 100 +-- These cases require an extra level of distinct-ing above subquery s +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT DISTINCT id1, id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo WHERE id IN (SELECT id2 FROM (SELECT DISTINCT id1, id2 FROM bar) s)" +== 066 +-- truncate_limit: 100 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id1,id2 FROM bar GROUP BY id1,id2) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo WHERE id IN (SELECT id2 FROM (SELECT id1, id2 FROM bar GROUP BY id1, id2) s)" +== 067 +-- truncate_limit: 100 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id1, id2 FROM bar UNION + SELECT id1, id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo WHERE id IN (SELECT id2 FROM (SELECT ... FROM bar UNION SELECT ... FROM bar) s)" +== 068 +-- truncate_limit: 100 +-- These cases do not +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT DISTINCT ON (id2) id1, id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo WHERE id IN (SELECT id2 FROM (SELECT DISTINCT ON (id2) id1, id2 FROM bar) s)" +== 069 +-- truncate_limit: 100 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id2 FROM bar GROUP BY id2) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo WHERE id IN (SELECT id2 FROM (SELECT id2 FROM bar GROUP BY id2) s)" +== 070 +-- truncate_limit: 100 +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id2 FROM bar UNION + SELECT id2 FROM bar) AS s) +-- +TABLE: name="foo" schema="" table="foo" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +TABLE: name="bar" schema="" table="bar" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM foo WHERE id IN (SELECT id2 FROM (SELECT id2 FROM bar UNION SELECT id2 FROM bar) s)" +== 071 +-- truncate_limit: 100 +|-- +-- Test case to catch problems with multiply nested sub-SELECTs not getting +-- recalculated properly. Per bug report from Didier Moens. +|-- + +CREATE TABLE orderstest ( + approver_ref integer, + po_ref integer, + ordercanceled boolean +) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE orderstest (approver_ref int, po_ref int, ordercanceled boolean)" +== 072 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (1, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (1, 1, false)" +== 073 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (66, 5, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (66, 5, false)" +== 074 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (66, 6, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (66, 6, false)" +== 075 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (66, 7, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (66, 7, false)" +== 076 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (66, 1, true) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (66, 1, true)" +== 077 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (66, 8, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (66, 8, false)" +== 078 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (66, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (66, 1, false)" +== 079 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (77, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (77, 1, false)" +== 080 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (1, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (1, 1, false)" +== 081 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (66, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (66, 1, false)" +== 082 +-- truncate_limit: 100 +INSERT INTO orderstest VALUES (1, 1, false) +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO orderstest VALUES (1, 1, false)" +== 083 +-- truncate_limit: 100 +CREATE VIEW orders_view AS +SELECT *, +(SELECT CASE + WHEN ord.approver_ref=1 THEN '---' ELSE 'Approved' + END) AS "Approved", +(SELECT CASE + WHEN ord.ordercanceled + THEN 'Canceled' + ELSE + (SELECT CASE + WHEN ord.po_ref=1 + THEN + (SELECT CASE + WHEN ord.approver_ref=1 + THEN '---' + ELSE 'Approved' + END) + ELSE 'PO' + END) +END) AS "Status", +(CASE + WHEN ord.ordercanceled + THEN 'Canceled' + ELSE + (CASE + WHEN ord.po_ref=1 + THEN + (CASE + WHEN ord.approver_ref=1 + THEN '---' + ELSE 'Approved' + END) + ELSE 'PO' + END) +END) AS "Status_OK" +FROM orderstest ord +-- +TABLE: name="orders_view" schema="" table="orders_view" ctx=DDL +TABLE: name="orderstest" schema="" table="orderstest" ctx=Select +ALIAS: "ord"="orderstest" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW orders_view AS SELECT *, (SELECT CASE WHEN ord.approver_ref = 1 THEN '---' ELSE 'Appr..." +== 084 +-- truncate_limit: 100 +SELECT * FROM orders_view +-- +TABLE: name="orders_view" schema="" table="orders_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM orders_view" +== 085 +-- truncate_limit: 100 +DROP TABLE orderstest cascade +-- +TABLE: name="orderstest" schema="" table="orderstest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE orderstest CASCADE" +== 086 +-- truncate_limit: 100 +|-- +-- Test cases to catch situations where rule rewriter fails to propagate +-- hasSubLinks flag correctly. Per example from Kyle Bateman. +|-- + +create temp table parts ( + partnum text, + cost float8 +) +-- +TABLE: name="parts" schema="" table="parts" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parts (partnum text, cost float8)" +== 087 +-- truncate_limit: 100 +create temp table shipped ( + ttype char(2), + ordnum int4, + partnum text, + value float8 +) +-- +TABLE: name="shipped" schema="" table="shipped" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE shipped (ttype char(2), ordnum int4, partnum text, value float8)" +== 088 +-- truncate_limit: 100 +create temp view shipped_view as + select * from shipped where ttype = 'wt' +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DDL +TABLE: name="shipped" schema="" table="shipped" ctx=Select +FILTER: schema="" table="" column="ttype" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW shipped_view AS SELECT * FROM shipped WHERE ttype = 'wt'" +== 089 +-- truncate_limit: 100 +create rule shipped_view_insert as on insert to shipped_view do instead + insert into shipped values('wt', new.ordnum, new.partnum, new.value) +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE shipped_view_insert AS ON INSERT TO shipped_view DO INSTEAD INSERT INTO shipped VALUE..." +== 090 +-- truncate_limit: 100 +insert into parts (partnum, cost) values (1, 1234.56) +-- +TABLE: name="parts" schema="" table="parts" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parts (partnum, cost) VALUES (1, 1234.56)" +== 091 +-- truncate_limit: 100 +insert into shipped_view (ordnum, partnum, value) + values (0, 1, (select cost from parts where partnum = '1')) +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DML +TABLE: name="parts" schema="" table="parts" ctx=Select +FILTER: schema="" table="" column="partnum" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shipped_view (ordnum, partnum, value) VALUES (0, 1, (SELECT cost FROM parts WHERE ...))" +== 092 +-- truncate_limit: 100 +select * from shipped_view +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shipped_view" +== 093 +-- truncate_limit: 100 +create rule shipped_view_update as on update to shipped_view do instead + update shipped set partnum = new.partnum, value = new.value + where ttype = new.ttype and ordnum = new.ordnum +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE shipped_view_update AS ON UPDATE TO shipped_view DO INSTEAD UPDATE shipped SET partnu..." +== 094 +-- truncate_limit: 100 +update shipped_view set value = 11 + from int4_tbl a join int4_tbl b + on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)) + where ordnum = a.f1 +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +ALIAS: "c"="int4_tbl" +FILTER: schema="" table="c" column="f1" +FILTER: schema="" table="b" column="f1" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE shipped_view SET ... = ... FROM int4_tbl a JOIN int4_tbl b ON a.f1 = (SELECT f1 FROM int4_..." +== 095 +-- truncate_limit: 100 +select * from shipped_view +-- +TABLE: name="shipped_view" schema="" table="shipped_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM shipped_view" +== 096 +-- truncate_limit: 100 +select f1, ss1 as relabel from + (select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1 + from int4_tbl a) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "a"="int4_tbl" +ALIAS: "b"="int4_tbl" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="a" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1, ss1 AS relabel FROM (SELECT ... FROM int4_tbl a) ss" +== 097 +-- truncate_limit: 100 +|-- +-- Test cases involving PARAM_EXEC parameters and min/max index optimizations. +-- Per bug report from David Sanchez i Gregori. +|-- + +select * from ( + select max(unique1) from tenk1 as a + where exists (select 1 from tenk1 as b where b.thousand = a.unique2) +) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="max" function="max" schema="" ctx=Call +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="a" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT max(unique1) FROM tenk1 a WHERE EXISTS (SELECT 1 FROM tenk1 b WHERE ...)) ss" +== 098 +-- truncate_limit: 100 +select * from ( + select min(unique1) from tenk1 as a + where not exists (select 1 from tenk1 as b where b.unique2 = 10000) +) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="b" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT min(unique1) FROM tenk1 a WHERE ...) ss" +== 099 +-- truncate_limit: 100 +|-- +-- Test that an IN implemented using a UniquePath does unique-ification +-- with the right semantics, as per bug #4113. (Unfortunately we have +-- no simple way to ensure that this test case actually chooses that type +-- of plan, but it does in releases 7.4-8.3. Note that an ordering difference +-- here might mean that some other plan type is being used, rendering the test +-- pointless.) +|-- + +create temp table numeric_table (num_col numeric) +-- +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE numeric_table (num_col numeric)" +== 100 +-- truncate_limit: 100 +insert into numeric_table values (1), (1.000000000000000000001), (2), (3) +-- +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numeric_table VALUES (1), (1.000000000000000000001), (2), (3)" +== 101 +-- truncate_limit: 100 +create temp table float_table (float_col float8) +-- +TABLE: name="float_table" schema="" table="float_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE float_table (float_col float8)" +== 102 +-- truncate_limit: 100 +insert into float_table values (1), (2), (3) +-- +TABLE: name="float_table" schema="" table="float_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float_table VALUES (1), (2), (3)" +== 103 +-- truncate_limit: 100 +select * from float_table + where float_col in (select num_col from numeric_table) +-- +TABLE: name="float_table" schema="" table="float_table" ctx=Select +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=Select +FILTER: schema="" table="" column="float_col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM float_table WHERE float_col IN (SELECT num_col FROM numeric_table)" +== 104 +-- truncate_limit: 100 +select * from numeric_table + where num_col in (select float_col from float_table) +-- +TABLE: name="numeric_table" schema="" table="numeric_table" ctx=Select +TABLE: name="float_table" schema="" table="float_table" ctx=Select +FILTER: schema="" table="" column="num_col" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM numeric_table WHERE num_col IN (SELECT float_col FROM float_table)" +== 105 +-- truncate_limit: 100 +|-- +-- Test case for bug #4290: bogus calculation of subplan param sets +|-- + +create temp table ta (id int primary key, val int) +-- +TABLE: name="ta" schema="" table="ta" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE ta (id int PRIMARY KEY, val int)" +== 106 +-- truncate_limit: 100 +insert into ta values(1,1) +-- +TABLE: name="ta" schema="" table="ta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ta VALUES (1, 1)" +== 107 +-- truncate_limit: 100 +insert into ta values(2,2) +-- +TABLE: name="ta" schema="" table="ta" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ta VALUES (2, 2)" +== 108 +-- truncate_limit: 100 +create temp table tb (id int primary key, aval int) +-- +TABLE: name="tb" schema="" table="tb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tb (id int PRIMARY KEY, aval int)" +== 109 +-- truncate_limit: 100 +insert into tb values(1,1) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tb VALUES (1, 1)" +== 110 +-- truncate_limit: 100 +insert into tb values(2,1) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tb VALUES (2, 1)" +== 111 +-- truncate_limit: 100 +insert into tb values(3,2) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tb VALUES (3, 2)" +== 112 +-- truncate_limit: 100 +insert into tb values(4,2) +-- +TABLE: name="tb" schema="" table="tb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tb VALUES (4, 2)" +== 113 +-- truncate_limit: 100 +create temp table tc (id int primary key, aid int) +-- +TABLE: name="tc" schema="" table="tc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tc (id int PRIMARY KEY, aid int)" +== 114 +-- truncate_limit: 100 +insert into tc values(1,1) +-- +TABLE: name="tc" schema="" table="tc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tc VALUES (1, 1)" +== 115 +-- truncate_limit: 100 +insert into tc values(2,2) +-- +TABLE: name="tc" schema="" table="tc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tc VALUES (2, 2)" +== 116 +-- truncate_limit: 100 +select + ( select min(tb.id) from tb + where tb.aval = (select ta.val from ta where ta.id = tc.aid) ) as min_tb_id +from tc +-- +TABLE: name="tc" schema="" table="tc" ctx=Select +TABLE: name="tb" schema="" table="tb" ctx=Select +TABLE: name="ta" schema="" table="ta" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="tb" column="aval" +FILTER: schema="" table="ta" column="id" +FILTER: schema="" table="tc" column="aid" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT min(tb.id) FROM tb WHERE ...) AS min_tb_id FROM tc" +== 117 +-- truncate_limit: 100 +|-- +-- Test case for 8.3 "failed to locate grouping columns" bug +|-- + +create temp table t1 (f1 numeric(14,0), f2 varchar(30)) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (f1 numeric(14, 0), f2 varchar(30))" +== 118 +-- truncate_limit: 100 +select * from + (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs + from t1 up) ss +group by f1,f2,fs +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t1" schema="" table="t1" ctx=Select +ALIAS: "up"="t1" +ALIAS: "x"="t1" +FILTER: schema="" table="x" column="f1" +FILTER: schema="" table="up" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT DISTINCT ... AS ... FROM t1 up) ss GROUP BY f1, f2, fs" +== 119 +-- truncate_limit: 100 +|-- +-- Test case for bug #5514 (mishandling of whole-row Vars in subselects) +|-- + +create temp table table_a(id integer) +-- +TABLE: name="table_a" schema="" table="table_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE table_a (id int)" +== 120 +-- truncate_limit: 100 +insert into table_a values (42) +-- +TABLE: name="table_a" schema="" table="table_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO table_a VALUES (42)" +== 121 +-- truncate_limit: 100 +create temp view view_a as select * from table_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=DDL +TABLE: name="table_a" schema="" table="table_a" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW view_a AS SELECT * FROM table_a" +== 122 +-- truncate_limit: 100 +select view_a from view_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT view_a FROM view_a" +== 123 +-- truncate_limit: 100 +select (select view_a) from view_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT view_a) FROM view_a" +== 124 +-- truncate_limit: 100 +select (select (select view_a)) from view_a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT (SELECT view_a)) FROM view_a" +== 125 +-- truncate_limit: 100 +select (select (a.*)::text) from view_a a +-- +TABLE: name="view_a" schema="" table="view_a" ctx=Select +ALIAS: "a"="view_a" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT a.*::text) FROM view_a a" +== 126 +-- truncate_limit: 100 +|-- +-- Test case for bug #19037: no relation entry for relid N +|-- + +explain (costs off) +select (1 = any(array_agg(f1))) = any (select false) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 = ANY(array_agg(f1)) = ANY (SELECT false) FROM int4_tbl" +== 127 +-- truncate_limit: 100 +select (1 = any(array_agg(f1))) = any (select false) from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 1 = ANY(array_agg(f1)) = ANY (SELECT false) FROM int4_tbl" +== 128 +-- truncate_limit: 100 +|-- +-- Check that whole-row Vars reading the result of a subselect don't include +-- any junk columns therein +|-- + +select q from (select max(f1) from int4_tbl group by f1 order by f1) q +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q FROM (SELECT max(f1) FROM int4_tbl GROUP BY f1 ORDER BY f1) q" +== 129 +-- truncate_limit: 100 +with q as (select max(f1) from int4_tbl group by f1 order by f1) + select q from q +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "q" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH q AS (SELECT max(f1) FROM int4_tbl GROUP BY f1 ORDER BY f1) SELECT q FROM q" +== 130 +-- truncate_limit: 100 +|-- +-- Test case for sublinks pulled up into joinaliasvars lists in an +-- inherited update/delete query +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 131 +-- truncate_limit: 100 +-- this shouldn't delete anything, but be safe + +delete from road +where exists ( + select 1 + from + int4_tbl cross join + ( select f1, array(select q1 from int8_tbl) as arr + from text_tbl ) ss + where road.name = ss.f1 ) +-- +TABLE: name="road" schema="" table="road" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FILTER: schema="" table="road" column="name" +FILTER: schema="" table="ss" column="f1" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "DELETE FROM road WHERE ..." +== 132 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 133 +-- truncate_limit: 100 +|-- +-- Test case for sublinks pushed down into subselects via join alias expansion +|-- + +select + (select sq1) as qq1 +from + (select exists(select 1 from int4_tbl where f1 = q2) as sq1, 42 as dummy + from int8_tbl) sq0 + join + int4_tbl i4 on dummy = i4.f1 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT sq1) AS qq1 FROM (SELECT ... FROM int8_tbl) sq0 JOIN int4_tbl i4 ON dummy = i4.f1" +== 134 +-- truncate_limit: 100 +|-- +-- Test case for subselect within UPDATE of INSERT...ON CONFLICT DO UPDATE +|-- +create temp table upsert(key int4 primary key, val text) +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE upsert (key int4 PRIMARY KEY, val text)" +== 135 +-- truncate_limit: 100 +insert into upsert values(1, 'val') on conflict (key) do update set val = 'not seen' +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (1, 'val') ON CONFLICT (key) DO UPDATE SET val = 'not seen'" +== 136 +-- truncate_limit: 100 +insert into upsert values(1, 'val') on conflict (key) do update set val = 'seen with subselect ' || (select f1 from int4_tbl where f1 != 0 limit 1)::text +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (1, 'val') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 137 +-- truncate_limit: 100 +select * from upsert +-- +TABLE: name="upsert" schema="" table="upsert" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM upsert" +== 138 +-- truncate_limit: 100 +with aa as (select 'int4_tbl' u from int4_tbl limit 1) +insert into upsert values (1, 'x'), (999, 'y') +on conflict (key) do update set val = (select u from aa) +returning * +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "aa" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aa AS (...) INSERT INTO upsert VALUES (...) ON CONFLICT (key) DO UPDATE SET ... = ... RETURN..." +== 139 +-- truncate_limit: 100 +|-- +-- Test case for cross-type partial matching in hashed subplan (bug #7597) +|-- + +create temp table outer_7597 (f1 int4, f2 int4) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE outer_7597 (f1 int4, f2 int4)" +== 140 +-- truncate_limit: 100 +insert into outer_7597 values (0, 0) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_7597 VALUES (0, 0)" +== 141 +-- truncate_limit: 100 +insert into outer_7597 values (1, 0) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_7597 VALUES (1, 0)" +== 142 +-- truncate_limit: 100 +insert into outer_7597 values (0, null) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_7597 VALUES (0, NULL)" +== 143 +-- truncate_limit: 100 +insert into outer_7597 values (1, null) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_7597 VALUES (1, NULL)" +== 144 +-- truncate_limit: 100 +create temp table inner_7597(c1 int8, c2 int8) +-- +TABLE: name="inner_7597" schema="" table="inner_7597" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE inner_7597 (c1 int8, c2 int8)" +== 145 +-- truncate_limit: 100 +insert into inner_7597 values(0, null) +-- +TABLE: name="inner_7597" schema="" table="inner_7597" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inner_7597 VALUES (0, NULL)" +== 146 +-- truncate_limit: 100 +select * from outer_7597 where (f1, f2) not in (select * from inner_7597) +-- +TABLE: name="outer_7597" schema="" table="outer_7597" ctx=Select +TABLE: name="inner_7597" schema="" table="inner_7597" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM outer_7597 WHERE NOT (f1, f2) IN (SELECT * FROM inner_7597)" +== 147 +-- truncate_limit: 100 +|-- +-- Similar test case using text that verifies that collation +-- information is passed through by execTuplesEqual() in nodeSubplan.c +-- (otherwise it would error in texteq()) +|-- + +create temp table outer_text (f1 text, f2 text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE outer_text (f1 text, f2 text)" +== 148 +-- truncate_limit: 100 +insert into outer_text values ('a', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('a', 'a')" +== 149 +-- truncate_limit: 100 +insert into outer_text values ('b', 'a') +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('b', 'a')" +== 150 +-- truncate_limit: 100 +insert into outer_text values ('a', null) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('a', NULL)" +== 151 +-- truncate_limit: 100 +insert into outer_text values ('b', null) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO outer_text VALUES ('b', NULL)" +== 152 +-- truncate_limit: 100 +create temp table inner_text (c1 text, c2 text) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE inner_text (c1 text, c2 text)" +== 153 +-- truncate_limit: 100 +insert into inner_text values ('a', null) +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inner_text VALUES ('a', NULL)" +== 154 +-- truncate_limit: 100 +insert into inner_text values ('123', '456') +-- +TABLE: name="inner_text" schema="" table="inner_text" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO inner_text VALUES ('123', '456')" +== 155 +-- truncate_limit: 100 +select * from outer_text where (f1, f2) not in (select * from inner_text) +-- +TABLE: name="outer_text" schema="" table="outer_text" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM outer_text WHERE NOT (f1, f2) IN (SELECT * FROM inner_text)" +== 156 +-- truncate_limit: 100 +|-- +-- Another test case for cross-type hashed subplans: comparison of +-- inner-side values must be done with appropriate operator +|-- + +explain (verbose, costs off) +select 'foo'::text in (select 'bar'::name union all select 'bar'::name) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT 'foo'::text IN (SELECT 'bar'::name UNION ALL SELECT 'bar'::name)" +== 157 +-- truncate_limit: 100 +select 'foo'::text in (select 'bar'::name union all select 'bar'::name) +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo'::text IN (SELECT 'bar'::name UNION ALL SELECT 'bar'::name)" +== 158 +-- truncate_limit: 100 +|-- +-- Test that we don't try to hash nested records (bug #17363) +-- (Hashing could be supported, but for now we don't) +|-- + +explain (verbose, costs off) +select row(row(row(1))) = any (select row(row(1))) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT ROW(ROW(ROW(1))) = ANY (SELECT ROW(ROW(1)))" +== 159 +-- truncate_limit: 100 +select row(row(row(1))) = any (select row(row(1))) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ROW(ROW(ROW(1))) = ANY (SELECT ROW(ROW(1)))" +== 160 +-- truncate_limit: 100 +|-- +-- Test case for premature memory release during hashing of subplan output +|-- + +select '1'::text in (select '1'::name union all select '1'::name) +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::text IN (SELECT '1'::name UNION ALL SELECT '1'::name)" +== 161 +-- truncate_limit: 100 +|-- +-- Test that we don't try to use a hashed subplan if the simplified +-- testexpr isn't of the right shape +|-- + +-- this fails by default, of course +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q1 IN (SELECT c1 FROM inner_text)" +== 162 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 163 +-- truncate_limit: 100 +-- make an operator to allow it to succeed +create function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $1::text = $2' +-- +FUNCTION: name="bogus_int8_text_eq" function="bogus_int8_text_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bogus_int8_text_eq(int8, text) RETURNS boolean LANGUAGE sql AS $$select $1::text ..." +== 164 +-- truncate_limit: 100 +create operator = (procedure=bogus_int8_text_eq, leftarg=int8, rightarg=text) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR = (procedure = bogus_int8_text_eq, leftarg = int8, rightarg = text)" +== 165 +-- truncate_limit: 100 +explain (costs off) +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl WHERE q1 IN (SELECT c1 FROM inner_text)" +== 166 +-- truncate_limit: 100 +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q1 IN (SELECT c1 FROM inner_text)" +== 167 +-- truncate_limit: 100 +-- inlining of this function results in unusual number of hash clauses, +-- which we can still cope with +create or replace function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $1::text = $2 and $1::text = $2' +-- +FUNCTION: name="bogus_int8_text_eq" function="bogus_int8_text_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION bogus_int8_text_eq(int8, text) RETURNS boolean LANGUAGE sql AS $$selec..." +== 168 +-- truncate_limit: 100 +explain (costs off) +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl WHERE q1 IN (SELECT c1 FROM inner_text)" +== 169 +-- truncate_limit: 100 +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q1 IN (SELECT c1 FROM inner_text)" +== 170 +-- truncate_limit: 100 +-- inlining of this function causes LHS and RHS to be switched, +-- which we can't cope with, so hashing should be abandoned +create or replace function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $2 = $1::text' +-- +FUNCTION: name="bogus_int8_text_eq" function="bogus_int8_text_eq" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION bogus_int8_text_eq(int8, text) RETURNS boolean LANGUAGE sql AS $$selec..." +== 171 +-- truncate_limit: 100 +explain (costs off) +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM int8_tbl WHERE q1 IN (SELECT c1 FROM inner_text)" +== 172 +-- truncate_limit: 100 +select * from int8_tbl where q1 in (select c1 from inner_text) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="inner_text" schema="" table="inner_text" ctx=Select +FILTER: schema="" table="" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl WHERE q1 IN (SELECT c1 FROM inner_text)" +== 173 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 174 +-- truncate_limit: 100 +-- to get rid of the bogus operator + +|-- +-- Test resolution of hashed vs non-hashed implementation of EXISTS subplan +|-- +explain (costs off) +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 t WHERE EXISTS (SELECT 1 FROM tenk1 k WHERE k.uniq..." +== 175 +-- truncate_limit: 100 +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 t WHERE EXISTS (SELECT 1 FROM tenk1 k WHERE ...) OR ten < 0" +== 176 +-- truncate_limit: 100 +explain (costs off) +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) + and thousand = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 t WHERE (EXISTS (SELECT 1 FROM tenk1 k WHERE k.uni..." +== 177 +-- truncate_limit: 100 +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) + and thousand = 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "k"="tenk1" +ALIAS: "t"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="k" column="unique1" +FILTER: schema="" table="t" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 t WHERE ..." +== 178 +-- truncate_limit: 100 +-- It's possible for the same EXISTS to get resolved both ways +create temp table exists_tbl (c1 int, c2 int, c3 int) partition by list (c1) +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE exists_tbl (c1 int, c2 int, c3 int) PARTITION BY LIST (c1)" +== 179 +-- truncate_limit: 100 +create temp table exists_tbl_null partition of exists_tbl for values in (null) +-- +TABLE: name="exists_tbl_null" schema="" table="exists_tbl_null" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE exists_tbl_null PARTITION OF exists_tbl FOR VALUES IN (NULL)" +== 180 +-- truncate_limit: 100 +create temp table exists_tbl_def partition of exists_tbl default +-- +TABLE: name="exists_tbl_def" schema="" table="exists_tbl_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE exists_tbl_def PARTITION OF exists_tbl DEFAULT" +== 181 +-- truncate_limit: 100 +insert into exists_tbl select x, x/2, x+1 from generate_series(0,10) x +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO exists_tbl SELECT x, x / 2, x + 1 FROM generate_series(0, 10) x" +== 182 +-- truncate_limit: 100 +analyze exists_tbl +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE exists_tbl" +== 183 +-- truncate_limit: 100 +explain (costs off) +select * from exists_tbl t1 + where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0) +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +ALIAS: "t1"="exists_tbl" +ALIAS: "t2"="exists_tbl" +FILTER: schema="" table="t1" column="c1" +FILTER: schema="" table="t2" column="c2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM exists_tbl t1 WHERE EXISTS (SELECT 1 FROM exists_tbl t2 WHERE t..." +== 184 +-- truncate_limit: 100 +select * from exists_tbl t1 + where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0) +-- +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +TABLE: name="exists_tbl" schema="" table="exists_tbl" ctx=Select +ALIAS: "t1"="exists_tbl" +ALIAS: "t2"="exists_tbl" +FILTER: schema="" table="t1" column="c1" +FILTER: schema="" table="t2" column="c2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM exists_tbl t1 WHERE EXISTS (SELECT 1 FROM exists_tbl t2 WHERE t1.c1 = t2.c2) OR c3 < 0" +== 185 +-- truncate_limit: 100 +|-- +-- Test case for planner bug with nested EXISTS handling +|-- +select a.thousand from tenk1 a, tenk1 b +where a.thousand = b.thousand + and exists ( select 1 from tenk1 c where b.hundred = c.hundred + and not exists ( select 1 from tenk1 d + where a.thousand = d.thousand ) ) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +ALIAS: "c"="tenk1" +ALIAS: "d"="tenk1" +FILTER: schema="" table="a" column="thousand" +FILTER: schema="" table="b" column="thousand" +FILTER: schema="" table="b" column="hundred" +FILTER: schema="" table="c" column="hundred" +FILTER: schema="" table="a" column="thousand" +FILTER: schema="" table="d" column="thousand" +STMT: SelectStmt +TRUNCATED: "SELECT a.thousand FROM tenk1 a, tenk1 b WHERE ..." +== 186 +-- truncate_limit: 100 +|-- +-- Check that nested sub-selects are not pulled up if they contain volatiles +|-- +explain (verbose, costs off) + select x, x from + (select (select now()) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT x, x FROM (SELECT (SELECT now()) AS x FROM (VALUES (1), (2)) ..." +== 187 +-- truncate_limit: 100 +explain (verbose, costs off) + select x, x from + (select (select random()) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT x, x FROM (SELECT (SELECT random()) AS x FROM (VALUES (1), (2..." +== 188 +-- truncate_limit: 100 +explain (verbose, costs off) + select x, x from + (select (select now() where y=y) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT x, x FROM (SELECT (SELECT now() WHERE y = y) AS x FROM (VALUE..." +== 189 +-- truncate_limit: 100 +explain (verbose, costs off) + select x, x from + (select (select random() where y=y) as x from (values(1),(2)) v(y)) ss +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="y" +FILTER: schema="" table="" column="y" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT x, x FROM (SELECT (SELECT random() WHERE y = y) AS x FROM (VA..." +== 190 +-- truncate_limit: 100 +|-- +-- Test rescan of a hashed subplan (the use of random() is to prevent the +-- sub-select from being pulled up, which would result in not hashing) +|-- +explain (verbose, costs off) +select sum(ss.tst::int) from + onek o cross join lateral ( + select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, + random() as r + from onek i where i.unique1 = o.unique1 ) ss +where o.ten = 0 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="onek" +ALIAS: "o"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="o" column="hundred" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT sum(ss.tst::int) FROM onek o CROSS JOIN LATERAL (SELECT i.ten..." +== 191 +-- truncate_limit: 100 +select sum(ss.tst::int) from + onek o cross join lateral ( + select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, + random() as r + from onek i where i.unique1 = o.unique1 ) ss +where o.ten = 0 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="onek" +ALIAS: "o"="onek" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="o" column="hundred" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek o CROSS JOIN LATERAL (SELECT ... FROM onek i WHERE ...) ss WHERE o.ten = 0" +== 192 +-- truncate_limit: 100 +|-- +-- Test rescan of a SetOp node +|-- +explain (costs off) +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "i1"="onek" +ALIAS: "i2"="onek" +ALIAS: "o"="onek" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i1" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="i2" column="unique1" +FILTER: schema="" table="o" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM onek o CROSS JOIN LATERAL (SELECT * FROM onek i1 WHERE i..." +== 193 +-- truncate_limit: 100 +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "i1"="onek" +ALIAS: "i2"="onek" +ALIAS: "o"="onek" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="i1" column="unique1" +FILTER: schema="" table="o" column="unique1" +FILTER: schema="" table="i2" column="unique1" +FILTER: schema="" table="o" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek o CROSS JOIN LATERAL (SELECT * FROM onek i1 WHERE ... EXCEPT SELECT * FROM o..." +== 194 +-- truncate_limit: 100 +|-- +-- Test rescan of a RecursiveUnion node +|-- +explain (costs off) +select sum(o.four), sum(ss.a) from + onek o cross join lateral ( + with recursive x(a) as + (select o.four as a + union + select a + 1 from x + where a < 10) + select * from x + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "o"="onek" +CTE: "x" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT sum(o.four), sum(ss.a) FROM onek o CROSS JOIN LATERAL (WITH RECURSIVE ..." +== 195 +-- truncate_limit: 100 +select sum(o.four), sum(ss.a) from + onek o cross join lateral ( + with recursive x(a) as + (select o.four as a + union + select a + 1 from x + where a < 10) + select * from x + ) ss +where o.ten = 1 +-- +TABLE: name="onek" schema="" table="onek" ctx=Select +ALIAS: "o"="onek" +CTE: "x" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="o" column="ten" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM onek o CROSS JOIN LATERAL (WITH RECURSIVE x(a) AS (...) SELECT * FROM x) ss WHERE..." +== 196 +-- truncate_limit: 100 +|-- +-- Check we don't misoptimize a NOT IN where the subquery returns no rows. +|-- +create temp table notinouter (a int) +-- +TABLE: name="notinouter" schema="" table="notinouter" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE notinouter (a int)" +== 197 +-- truncate_limit: 100 +create temp table notininner (b int not null) +-- +TABLE: name="notininner" schema="" table="notininner" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE notininner (b int NOT NULL)" +== 198 +-- truncate_limit: 100 +insert into notinouter values (null), (1) +-- +TABLE: name="notinouter" schema="" table="notinouter" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO notinouter VALUES (NULL), (1)" +== 199 +-- truncate_limit: 100 +select * from notinouter where a not in (select b from notininner) +-- +TABLE: name="notinouter" schema="" table="notinouter" ctx=Select +TABLE: name="notininner" schema="" table="notininner" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM notinouter WHERE NOT a IN (SELECT b FROM notininner)" +== 200 +-- truncate_limit: 100 +|-- +-- Check we behave sanely in corner case of empty SELECT list (bug #8648) +|-- +create temp table nocolumns() +-- +TABLE: name="nocolumns" schema="" table="nocolumns" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE nocolumns ()" +== 201 +-- truncate_limit: 100 +select exists(select * from nocolumns) +-- +TABLE: name="nocolumns" schema="" table="nocolumns" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT EXISTS (SELECT * FROM nocolumns)" +== 202 +-- truncate_limit: 100 +|-- +-- Check behavior with a SubPlan in VALUES (bug #14924) +|-- +select val.x + from generate_series(1,10) as s(i), + lateral ( + values ((select s.i + 1)), (s.i + 101) + ) as val(x) +where s.i < 10 and (select val.x) < 110 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="s" column="i" +STMT: SelectStmt +TRUNCATED: "SELECT val.x FROM generate_series(1, 10) s(i), LATERAL (VALUES (...)) val(x) WHERE ..." +== 203 +-- truncate_limit: 100 +-- another variant of that (bug #16213) +explain (verbose, costs off) +select * from +(values + (3 not in (select * from (values (1), (2)) ss1)), + (false) +) ss +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (VALUES (NOT 3 IN (SELECT * FROM (VALUES (1), (2)) ss1..." +== 204 +-- truncate_limit: 100 +select * from +(values + (3 not in (select * from (values (1), (2)) ss1)), + (false) +) ss +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (NOT 3 IN (SELECT * FROM (VALUES (1), (2)) ss1)), (false)) ss" +== 205 +-- truncate_limit: 100 +|-- +-- Check sane behavior with nested IN SubLinks +|-- +explain (verbose, costs off) +select * from int4_tbl where + (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in + (select ten from tenk1 b) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl WHERE CASE WHEN f1 IN (SELECT unique1 FROM te..." +== 206 +-- truncate_limit: 100 +select * from int4_tbl where + (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in + (select ten from tenk1 b) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl WHERE ..." +== 207 +-- truncate_limit: 100 +|-- +-- Check for incorrect optimization when IN subquery contains a SRF +|-- +explain (verbose, costs off) +select * from int4_tbl o where (f1, f1) in + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl o WHERE (f1, f1) IN (SELECT f1, generate_seri..." +== 208 +-- truncate_limit: 100 +select * from int4_tbl o where (f1, f1) in + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i"="int4_tbl" +ALIAS: "o"="int4_tbl" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl o WHERE (f1, f1) IN (SELECT ... FROM int4_tbl i GROUP BY f1)" +== 209 +-- truncate_limit: 100 +|-- +-- check for over-optimization of whole-row Var referencing an Append plan +|-- +select (select q from + (select 1,2,3 where f1 > 0 + union all + select 4,5,6.0 where f1 <= 0 + ) q ) +from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT q FROM (SELECT ... WHERE f1 > 0 UNION ALL SELECT ... WHERE f1 <= 0) q) FROM int4_tbl" +== 210 +-- truncate_limit: 100 +|-- +-- Check for sane handling of a lateral reference in a subquery's quals +-- (most of the complication here is to prevent the test case from being +-- flattened too much) +|-- +explain (verbose, costs off) +select * from + int4_tbl i4, + lateral ( + select i4.f1 > 1 as b, 1 as id + from (select random() order by 1) as t1 + union all + select true as b, 2 as id + ) as t2 +where b and f1 >= 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM int4_tbl i4, LATERAL (SELECT i4.f1 > 1 AS b, 1 AS id F..." +== 211 +-- truncate_limit: 100 +select * from + int4_tbl i4, + lateral ( + select i4.f1 > 1 as b, 1 as id + from (select random() order by 1) as t1 + union all + select true as b, 2 as id + ) as t2 +where b and f1 >= 0 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4_tbl i4, LATERAL (SELECT ... FROM (SELECT ... ORDER BY 1) t1 UNION ALL SELECT ...." +== 212 +-- truncate_limit: 100 +|-- +-- Check that volatile quals aren't pushed down past a DISTINCT: +-- nextval() should not be called more than the nominal number of times +|-- +create temp sequence ts1 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE TEMPORARY SEQUENCE ts1" +== 213 +-- truncate_limit: 100 +select * from + (select distinct ten from tenk1) ss + where ten < 10 + nextval('ts1') + order by 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +FILTER: schema="" table="" column="ten" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT DISTINCT ten FROM tenk1) ss WHERE ten < (10 + nextval('ts1')) ORDER BY 1" +== 214 +-- truncate_limit: 100 +select nextval('ts1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('ts1')" +== 215 +-- truncate_limit: 100 +|-- +-- Check that volatile quals aren't pushed down past a set-returning function; +-- while a nonvolatile qual can be, if it doesn't reference the SRF. +|-- +create function tattle(x int, y int) returns bool +volatile language plpgsql as $$ +begin + raise notice 'x = %, y = %', x, y; + return x > y; +end$$ +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tattle(x int, y int) RETURNS bool VOLATILE LANGUAGE plpgsql AS $$\nbegin\n raise n..." +== 216 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT 9 AS x, unnest(ARRAY[1, 2, 3, 11, 12, 13]) AS ..." +== 217 +-- truncate_limit: 100 +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 9 AS x, unnest(ARRAY[1, 2, 3, 11, 12, 13]) AS u) ss WHERE tattle(x, 8)" +== 218 +-- truncate_limit: 100 +-- if we pretend it's stable, we get different results: +alter function tattle(x int, y int) stable +-- +STMT: AlterFunctionStmt +TRUNCATED: "ALTER FUNCTION tattle(x int, y int) STABLE" +== 219 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT 9 AS x, unnest(ARRAY[1, 2, 3, 11, 12, 13]) AS ..." +== 220 +-- truncate_limit: 100 +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 9 AS x, unnest(ARRAY[1, 2, 3, 11, 12, 13]) AS u) ss WHERE tattle(x, 8)" +== 221 +-- truncate_limit: 100 +-- although even a stable qual should not be pushed down if it references SRF +explain (verbose, costs off) +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, u) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="u" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT 9 AS x, unnest(ARRAY[1, 2, 3, 11, 12, 13]) AS ..." +== 222 +-- truncate_limit: 100 +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, u) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="tattle" function="tattle" schema="" ctx=Call +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="u" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 9 AS x, unnest(ARRAY[1, 2, 3, 11, 12, 13]) AS u) ss WHERE tattle(x, u)" +== 223 +-- truncate_limit: 100 +drop function tattle(x int, y int) +-- +FUNCTION: name="tattle" function="tattle" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION tattle(x int, y int)" +== 224 +-- truncate_limit: 100 +|-- +-- Test that LIMIT can be pushed to SORT through a subquery that just projects +-- columns. We check for that having happened by looking to see if EXPLAIN +-- ANALYZE shows that a top-N sort was used. We must suppress or filter away +-- all the non-invariant parts of the EXPLAIN ANALYZE output. +|-- +create table sq_limit (pk int primary key, c1 int, c2 int) +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sq_limit (pk int PRIMARY KEY, c1 int, c2 int)" +== 225 +-- truncate_limit: 100 +insert into sq_limit values + (1, 1, 1), + (2, 2, 2), + (3, 3, 3), + (4, 4, 4), + (5, 1, 1), + (6, 2, 2), + (7, 3, 3), + (8, 4, 4) +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sq_limit VALUES (...)" +== 226 +-- truncate_limit: 100 +create function explain_sq_limit() returns setof text language plpgsql as +$$ +declare ln text; +begin + for ln in + explain (analyze, summary off, timing off, costs off) + select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3 + loop + ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx'); + return next ln; + end loop; +end; +$$ +-- +FUNCTION: name="explain_sq_limit" function="explain_sq_limit" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION explain_sq_limit() RETURNS SETOF text LANGUAGE plpgsql AS $$\ndeclare ln text;\nbeg..." +== 227 +-- truncate_limit: 100 +select * from explain_sq_limit() +-- +FUNCTION: name="explain_sq_limit" function="explain_sq_limit" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM explain_sq_limit()" +== 228 +-- truncate_limit: 100 +select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3 +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT pk, c2 FROM sq_limit ORDER BY c1, pk) x LIMIT 3" +== 229 +-- truncate_limit: 100 +drop function explain_sq_limit() +-- +FUNCTION: name="explain_sq_limit" function="explain_sq_limit" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION explain_sq_limit()" +== 230 +-- truncate_limit: 100 +drop table sq_limit +-- +TABLE: name="sq_limit" schema="" table="sq_limit" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE sq_limit" +== 231 +-- truncate_limit: 100 +|-- +-- Ensure that backward scan direction isn't propagated into +-- expression subqueries (bug #15336) +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 232 +-- truncate_limit: 100 +declare c1 scroll cursor for + select * from generate_series(1,4) i + where i <> all (values (2),(3)) +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c1 SCROLL CURSOR FOR SELECT * FROM generate_series(1, 4) i WHERE i <> ALL (VALUES (2), (3))" +== 233 +-- truncate_limit: 100 +move forward all in c1 +-- +STMT: FetchStmt +TRUNCATED: "MOVE ALL c1" +== 234 +-- truncate_limit: 100 +fetch backward all in c1 +-- +STMT: FetchStmt +TRUNCATED: "FETCH BACKWARD ALL c1" +== 235 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 236 +-- truncate_limit: 100 +|-- +-- Check that JsonConstructorExpr is treated as non-strict, and thus can be +-- wrapped in a PlaceHolderVar +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 237 +-- truncate_limit: 100 +create temp table json_tab (a int) +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE json_tab (a int)" +== 238 +-- truncate_limit: 100 +insert into json_tab values (1) +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO json_tab VALUES (1)" +== 239 +-- truncate_limit: 100 +explain (verbose, costs off) +select * from json_tab t1 left join (select json_array(1, a) from json_tab t2) s on false +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +ALIAS: "t1"="json_tab" +ALIAS: "t2"="json_tab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM json_tab t1 LEFT JOIN (SELECT JSON_ARRAY(1, a) FROM js..." +== 240 +-- truncate_limit: 100 +select * from json_tab t1 left join (select json_array(1, a) from json_tab t2) s on false +-- +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +TABLE: name="json_tab" schema="" table="json_tab" ctx=Select +ALIAS: "t1"="json_tab" +ALIAS: "t2"="json_tab" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM json_tab t1 LEFT JOIN (SELECT JSON_ARRAY(1, a) FROM json_tab t2) s ON false" +== 241 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 242 +-- truncate_limit: 100 +|-- +-- Verify that we correctly flatten cases involving a subquery output +-- expression that doesn't need to be wrapped in a PlaceHolderVar +|-- + +explain (costs off) +select tname, attname from ( +select relname::information_schema.sql_identifier as tname, * from + (select * from pg_class c) ss1) ss2 + right join pg_attribute a on a.attrelid = ss2.oid +where tname = 'tenk1' and attnum = 1 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="tname" +FILTER: schema="" table="" column="attnum" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT tname, attname FROM (SELECT relname::information_schema.sql_identifier..." +== 243 +-- truncate_limit: 100 +select tname, attname from ( +select relname::information_schema.sql_identifier as tname, * from + (select * from pg_class c) ss1) ss2 + right join pg_attribute a on a.attrelid = ss2.oid +where tname = 'tenk1' and attnum = 1 +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "c"="pg_class" +FILTER: schema="" table="" column="tname" +FILTER: schema="" table="" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM (SELECT * FROM pg_class c) ss1) ss2 RIGHT JOIN pg_attribute a ON..." +== 244 +-- truncate_limit: 100 +-- Check behavior when there's a lateral reference in the output expression +explain (verbose, costs off) +select t1.ten, sum(x) from + tenk1 t1 left join lateral ( + select t1.ten + t2.ten as x, t2.fivethous from tenk1 t2 + ) ss on t1.unique1 = ss.fivethous +group by t1.ten +order by t1.ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.ten, sum(x) FROM tenk1 t1 LEFT JOIN LATERAL (SELECT t1.ten..." +== 245 +-- truncate_limit: 100 +select t1.ten, sum(x) from + tenk1 t1 left join lateral ( + select t1.ten + t2.ten as x, t2.fivethous from tenk1 t2 + ) ss on t1.unique1 = ss.fivethous +group by t1.ten +order by t1.ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 t1 LEFT JOIN LATERAL (SELECT ... FROM tenk1 t2) ss ON t1.unique1 = ss.fivet..." +== 246 +-- truncate_limit: 100 +explain (verbose, costs off) +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.q1, x FROM int8_tbl t1 LEFT JOIN (int8_tbl t2 LEFT JOIN LA..." +== 247 +-- truncate_limit: 100 +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "t1"="int8_tbl" +ALIAS: "t2"="int8_tbl" +ALIAS: "t3"="int8_tbl" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM int8_tbl t1 LEFT JOIN (int8_tbl t2 LEFT JOIN LATERAL (SELECT ... FROM int8_tbl t3..." +== 248 +-- truncate_limit: 100 +|-- +-- Tests for CTE inlining behavior +|-- + +-- Basic subquery that can be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT * FROM (SELECT f1 FROM subselect_tbl) ss) SELECT *..." +== 249 +-- truncate_limit: 100 +-- Explicitly request materialization +explain (verbose, costs off) +with x as materialized (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS MATERIALIZED (SELECT * FROM (SELECT f1 FROM subselect_tbl)..." +== 250 +-- truncate_limit: 100 +-- Stable functions are safe to inline +explain (verbose, costs off) +with x as (select * from (select f1, now() from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT * FROM (SELECT f1, now() FROM subselect_tbl) ss) S..." +== 251 +-- truncate_limit: 100 +-- Volatile functions prevent inlining +explain (verbose, costs off) +with x as (select * from (select f1, random() from subselect_tbl) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT * FROM (SELECT f1, random() FROM subselect_tbl) ss..." +== 252 +-- truncate_limit: 100 +-- SELECT FOR UPDATE cannot be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl for update) ss) +select * from x where f1 = 1 +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT * FROM (SELECT f1 FROM subselect_tbl FOR UPDATE) s..." +== 253 +-- truncate_limit: 100 +-- Multiply-referenced CTEs are inlined only when requested +explain (verbose, costs off) +with x as (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "x2"="x" +CTE: "x" +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="x" column="n" +FILTER: schema="" table="x2" column="n" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT * FROM (SELECT f1, now() AS n FROM subselect_tbl) ..." +== 254 +-- truncate_limit: 100 +explain (verbose, costs off) +with x as not materialized (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +ALIAS: "x2"="x" +CTE: "x" +FUNCTION: name="now" function="now" schema="" ctx=Call +FILTER: schema="" table="x" column="n" +FILTER: schema="" table="x2" column="n" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS NOT MATERIALIZED (SELECT * FROM (SELECT f1, now() AS n FRO..." +== 255 +-- truncate_limit: 100 +-- Multiply-referenced CTEs can't be inlined if they contain outer self-refs +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x +-- +ALIAS: "z1"="z" +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z1" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE x(a) AS (VALUES ('a'), ('b') UNION ALL (WITH z AS NOT..." +== 256 +-- truncate_limit: 100 +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x +-- +ALIAS: "z1"="z" +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z1" column="a" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(a) AS (...) SELECT * FROM x" +== 257 +-- truncate_limit: 100 +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x +-- +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE x(a) AS (VALUES ('a'), ('b') UNION ALL (WITH z AS NOT..." +== 258 +-- truncate_limit: 100 +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x +-- +CTE: "x" +CTE: "z" +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="z" column="a" +FILTER: schema="" table="z" column="a" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(a) AS (...) SELECT * FROM x" +== 259 +-- truncate_limit: 100 +-- Check handling of outer references +explain (verbose, costs off) +with x as (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "y" +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT * FROM int4_tbl) SELECT * FROM (WITH y AS (SELECT ..." +== 260 +-- truncate_limit: 100 +explain (verbose, costs off) +with x as materialized (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "y" +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS MATERIALIZED (SELECT * FROM int4_tbl) SELECT * FROM (WITH ..." +== 261 +-- truncate_limit: 100 +-- Ensure that we inline the correct CTE when there are +-- multiple CTEs with the same name +explain (verbose, costs off) +with x as (select 1 as y) +select * from (with x as (select 2 as y) select * from x) ss +-- +CTE: "x" +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT 1 AS y) SELECT * FROM (WITH x AS (SELECT 2 AS y) S..." +== 262 +-- truncate_limit: 100 +-- Row marks are not pushed into CTEs +explain (verbose, costs off) +with x as (select * from subselect_tbl) +select * from x for update +-- +TABLE: name="subselect_tbl" schema="" table="subselect_tbl" ctx=Select +CTE: "x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH x AS (SELECT * FROM subselect_tbl) SELECT * FROM x FOR UPDATE" +== 263 +-- truncate_limit: 100 +-- Pull up direct-correlated ANY_SUBLINKs +explain (costs off) +select * from tenk1 A where hundred in (select hundred from tenk2 B where B.odd = A.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +FILTER: schema="" table="" column="hundred" +FILTER: schema="" table="b" column="odd" +FILTER: schema="" table="a" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a WHERE hundred IN (SELECT hundred FROM tenk2 b WHERE b.o..." +== 264 +-- truncate_limit: 100 +explain (costs off) +select * from tenk1 A where exists +(select 1 from tenk2 B +where A.hundred in (select C.hundred FROM tenk2 C +WHERE c.odd = b.odd)) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="a" column="hundred" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a WHERE EXISTS (SELECT 1 FROM tenk2 b WHERE a.hundred IN ..." +== 265 +-- truncate_limit: 100 +-- we should only try to pull up the sublink into RHS of a left join +-- but a.hundred is not available. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON A.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = b.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a LEFT JOIN tenk2 b ON a.hundred IN (SELECT c.hundred FRO..." +== 266 +-- truncate_limit: 100 +-- we should only try to pull up the sublink into RHS of a left join +-- but a.odd is not available for this. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON B.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = a.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="a" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a LEFT JOIN tenk2 b ON b.hundred IN (SELECT c.hundred FRO..." +== 267 +-- truncate_limit: 100 +-- should be able to pull up since all the references are available. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON B.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = b.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a LEFT JOIN tenk2 b ON b.hundred IN (SELECT c.hundred FRO..." +== 268 +-- truncate_limit: 100 +-- we can pull up the sublink into the inner JoinExpr. +explain (costs off) +SELECT * FROM tenk1 A INNER JOIN tenk2 B +ON A.hundred in (SELECT c.hundred FROM tenk2 C WHERE c.odd = b.odd) +WHERE a.thousand < 750 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FILTER: schema="" table="a" column="thousand" +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a JOIN tenk2 b ON a.hundred IN (SELECT c.hundred FROM ten..." +== 269 +-- truncate_limit: 100 +-- we can pull up the aggregate sublink into RHS of a left join. +explain (costs off) +SELECT * FROM tenk1 A LEFT JOIN tenk2 B +ON B.hundred in (SELECT min(c.hundred) FROM tenk2 C WHERE c.odd = b.odd) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk2" +ALIAS: "c"="tenk2" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="c" column="odd" +FILTER: schema="" table="b" column="odd" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 a LEFT JOIN tenk2 b ON b.hundred IN (SELECT min(c.hundred..." diff --git a/parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json new file mode 100644 index 0000000..7249d3a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json @@ -0,0 +1,31 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/sysviews.test b/parser/testdata/summary_truncate/postgres_regress/sysviews.test new file mode 100644 index 0000000..76f79ac --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/sysviews.test @@ -0,0 +1,253 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Test assorted system views +|-- +-- This test is mainly meant to provide some code coverage for the +-- set-returning functions that underlie certain system views. +-- The output of most of these functions is very environment-dependent, +-- so our ability to test with fixed expected output is pretty limited; +-- but even a trivial check of count(*) will exercise the normal code path +-- through the SRF. + +select count(*) >= 0 as ok from pg_available_extension_versions +-- +TABLE: name="pg_available_extension_versions" schema="" table="pg_available_extension_versions" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) >= 0 AS ok FROM pg_available_extension_versions" +== 002 +-- truncate_limit: 100 +select count(*) >= 0 as ok from pg_available_extensions +-- +TABLE: name="pg_available_extensions" schema="" table="pg_available_extensions" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) >= 0 AS ok FROM pg_available_extensions" +== 003 +-- truncate_limit: 100 +-- The entire output of pg_backend_memory_contexts is not stable, +-- we test only the existence and basic condition of TopMemoryContext. +select name, ident, parent, level, total_bytes >= free_bytes + from pg_backend_memory_contexts where level = 0 +-- +TABLE: name="pg_backend_memory_contexts" schema="" table="pg_backend_memory_contexts" ctx=Select +FILTER: schema="" table="" column="level" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_backend_memory_contexts WHERE level = 0" +== 004 +-- truncate_limit: 100 +-- We can exercise some MemoryContext type stats functions. Most of the +-- column values are too platform-dependant to display. + +-- Ensure stats from the bump allocator look sane. Bump isn't a commonly +-- used context, but it is used in tuplesort.c, so open a cursor to keep +-- the tuplesort alive long enough for us to query the context stats. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 005 +-- truncate_limit: 100 +declare cur cursor for select left(a,10), b + from (values(repeat('a', 512 * 1024),1),(repeat('b', 512),2)) v(a,b) + order by v.a desc +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE cur CURSOR FOR SELECT \"left\"(a, 10), b FROM (VALUES (repeat('a', 512 * 1024), 1), (repeat..." +== 006 +-- truncate_limit: 100 +fetch 1 from cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH cur" +== 007 +-- truncate_limit: 100 +select name, parent, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks +from pg_backend_memory_contexts where name = 'Caller tuples' +-- +TABLE: name="pg_backend_memory_contexts" schema="" table="pg_backend_memory_contexts" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_backend_memory_contexts WHERE name = 'Caller tuples'" +== 008 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 009 +-- truncate_limit: 100 +-- At introduction, pg_config had 23 entries; it may grow +select count(*) > 20 as ok from pg_config +-- +TABLE: name="pg_config" schema="" table="pg_config" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 20 AS ok FROM pg_config" +== 010 +-- truncate_limit: 100 +-- We expect no cursors in this test; see also portals.sql +select count(*) = 0 as ok from pg_cursors +-- +TABLE: name="pg_cursors" schema="" table="pg_cursors" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) = 0 AS ok FROM pg_cursors" +== 011 +-- truncate_limit: 100 +select count(*) >= 0 as ok from pg_file_settings +-- +TABLE: name="pg_file_settings" schema="" table="pg_file_settings" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) >= 0 AS ok FROM pg_file_settings" +== 012 +-- truncate_limit: 100 +-- There will surely be at least one rule, with no errors. +select count(*) > 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err + from pg_hba_file_rules +-- +TABLE: name="pg_hba_file_rules" schema="" table="pg_hba_file_rules" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_hba_file_rules" +== 013 +-- truncate_limit: 100 +-- There may be no rules, and there should be no errors. +select count(*) >= 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err + from pg_ident_file_mappings +-- +TABLE: name="pg_ident_file_mappings" schema="" table="pg_ident_file_mappings" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_ident_file_mappings" +== 014 +-- truncate_limit: 100 +-- There will surely be at least one active lock +select count(*) > 0 as ok from pg_locks +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM pg_locks" +== 015 +-- truncate_limit: 100 +-- We expect no prepared statements in this test; see also prepare.sql +select count(*) = 0 as ok from pg_prepared_statements +-- +TABLE: name="pg_prepared_statements" schema="" table="pg_prepared_statements" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) = 0 AS ok FROM pg_prepared_statements" +== 016 +-- truncate_limit: 100 +-- See also prepared_xacts.sql +select count(*) >= 0 as ok from pg_prepared_xacts +-- +TABLE: name="pg_prepared_xacts" schema="" table="pg_prepared_xacts" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) >= 0 AS ok FROM pg_prepared_xacts" +== 017 +-- truncate_limit: 100 +-- There will surely be at least one SLRU cache +select count(*) > 0 as ok from pg_stat_slru +-- +TABLE: name="pg_stat_slru" schema="" table="pg_stat_slru" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) > 0 AS ok FROM pg_stat_slru" +== 018 +-- truncate_limit: 100 +-- There must be only one record +select count(*) = 1 as ok from pg_stat_wal +-- +TABLE: name="pg_stat_wal" schema="" table="pg_stat_wal" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) = 1 AS ok FROM pg_stat_wal" +== 019 +-- truncate_limit: 100 +-- We expect no walreceiver running in this test +select count(*) = 0 as ok from pg_stat_wal_receiver +-- +TABLE: name="pg_stat_wal_receiver" schema="" table="pg_stat_wal_receiver" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) = 0 AS ok FROM pg_stat_wal_receiver" +== 020 +-- truncate_limit: 100 +-- This is to record the prevailing planner enable_foo settings during +-- a regression test run. +select name, setting from pg_settings where name like 'enable%' +-- +TABLE: name="pg_settings" schema="" table="pg_settings" ctx=Select +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%'" +== 021 +-- truncate_limit: 100 +-- There are always wait event descriptions for various types. InjectionPoint +-- may be present or absent, depending on history since last postmaster start. +select type, count(*) > 0 as ok FROM pg_wait_events + where type <> 'InjectionPoint' group by type order by type COLLATE "C" +-- +TABLE: name="pg_wait_events" schema="" table="pg_wait_events" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="type" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_wait_events WHERE ... GROUP BY type ORDER BY type COLLATE \"C\"" +== 022 +-- truncate_limit: 100 +-- Test that the pg_timezone_names and pg_timezone_abbrevs views are +-- more-or-less working. We can't test their contents in any great detail +-- without the outputs changing anytime IANA updates the underlying data, +-- but it seems reasonable to expect at least one entry per major meridian. +-- (At the time of writing, the actual counts are around 38 because of +-- zones using fractional GMT offsets, so this is a pretty loose test.) +select count(distinct utc_offset) >= 24 as ok from pg_timezone_names +-- +TABLE: name="pg_timezone_names" schema="" table="pg_timezone_names" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT utc_offset) >= 24 AS ok FROM pg_timezone_names" +== 023 +-- truncate_limit: 100 +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs +-- +TABLE: name="pg_timezone_abbrevs" schema="" table="pg_timezone_abbrevs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT utc_offset) >= 24 AS ok FROM pg_timezone_abbrevs" +== 024 +-- truncate_limit: 100 +-- Let's check the non-default timezone abbreviation sets, too +set timezone_abbreviations = 'Australia' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone_abbreviations TO \"Australia\"" +== 025 +-- truncate_limit: 100 +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs +-- +TABLE: name="pg_timezone_abbrevs" schema="" table="pg_timezone_abbrevs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT utc_offset) >= 24 AS ok FROM pg_timezone_abbrevs" +== 026 +-- truncate_limit: 100 +set timezone_abbreviations = 'India' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone_abbreviations TO \"India\"" +== 027 +-- truncate_limit: 100 +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs +-- +TABLE: name="pg_timezone_abbrevs" schema="" table="pg_timezone_abbrevs" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT utc_offset) >= 24 AS ok FROM pg_timezone_abbrevs" diff --git a/parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json new file mode 100644 index 0000000..dc9d431 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json @@ -0,0 +1,60 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tablesample.test b/parser/testdata/summary_truncate/postgres_regress/tablesample.test new file mode 100644 index 0000000..410d346 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tablesample.test @@ -0,0 +1,438 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE test_tablesample (id int, name text) WITH (fillfactor=10) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tablesample (id int, name text) WITH (fillfactor=10)" +== 002 +-- truncate_limit: 100 +-- use fillfactor so we don't have to load too much data to get multiple pages + +INSERT INTO test_tablesample + SELECT i, repeat(i::text, 200) FROM generate_series(0, 9) s(i) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_tablesample SELECT i, repeat(i::text, 200) FROM generate_series(0, 9) s(i)" +== 003 +-- truncate_limit: 100 +SELECT t.id FROM test_tablesample AS t TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +ALIAS: "t"="test_tablesample" +STMT: SelectStmt +TRUNCATED: "SELECT t.id FROM test_tablesample t TABLESAMPLE system(50) REPEATABLE (0)" +== 004 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (100.0/11) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE system(100.0 / 11) REPEATABLE (0)" +== 005 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE system(50) REPEATABLE (0)" +== 006 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE bernoulli(50) REPEATABLE (0)" +== 007 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (5.5) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE bernoulli(5.5) REPEATABLE (0)" +== 008 +-- truncate_limit: 100 +-- 100% should give repeatable count results (ie, all rows) in any case +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tablesample TABLESAMPLE system(100)" +== 009 +-- truncate_limit: 100 +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (1+2) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tablesample TABLESAMPLE system(100) REPEATABLE (1 + 2)" +== 010 +-- truncate_limit: 100 +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (0.4) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tablesample TABLESAMPLE system(100) REPEATABLE (0.4)" +== 011 +-- truncate_limit: 100 +CREATE VIEW test_tablesample_v1 AS + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (10*2) REPEATABLE (2) +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=DDL +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW test_tablesample_v1 AS SELECT id FROM test_tablesample TABLESAMPLE system(10 * 2) REP..." +== 012 +-- truncate_limit: 100 +CREATE VIEW test_tablesample_v2 AS + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (99) +-- +TABLE: name="test_tablesample_v2" schema="" table="test_tablesample_v2" ctx=DDL +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW test_tablesample_v2 AS SELECT id FROM test_tablesample TABLESAMPLE system(99)" +== 013 +-- truncate_limit: 100 +-- check a sampled query doesn't affect cursor in progress +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 014 +-- truncate_limit: 100 +DECLARE tablesample_cur SCROLL CURSOR FOR + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE tablesample_cur SCROLL CURSOR FOR SELECT id FROM test_tablesample TABLESAMPLE system(50) ..." +== 015 +-- truncate_limit: 100 +FETCH FIRST FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH FIRST tablesample_cur" +== 016 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 017 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 018 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE system(50) REPEATABLE (0)" +== 019 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 020 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 021 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 022 +-- truncate_limit: 100 +FETCH FIRST FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH FIRST tablesample_cur" +== 023 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 024 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 025 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 026 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 027 +-- truncate_limit: 100 +FETCH NEXT FROM tablesample_cur +-- +STMT: FetchStmt +TRUNCATED: "FETCH tablesample_cur" +== 028 +-- truncate_limit: 100 +CLOSE tablesample_cur +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE tablesample_cur" +== 029 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 030 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (2) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT id FROM test_tablesample TABLESAMPLE system(50) REPEATABLE (2)" +== 031 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) + SELECT * FROM test_tablesample_v1 +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM test_tablesample_v1" +== 032 +-- truncate_limit: 100 +-- check inheritance behavior +explain (costs off) + select count(*) from person tablesample bernoulli (100) +-- +TABLE: name="person" schema="" table="person" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM person TABLESAMPLE bernoulli(100)" +== 033 +-- truncate_limit: 100 +select count(*) from person tablesample bernoulli (100) +-- +TABLE: name="person" schema="" table="person" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM person TABLESAMPLE bernoulli(100)" +== 034 +-- truncate_limit: 100 +select count(*) from person +-- +TABLE: name="person" schema="" table="person" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM person" +== 035 +-- truncate_limit: 100 +-- check that collations get assigned within the tablesample arguments +SELECT count(*) FROM test_tablesample TABLESAMPLE bernoulli (('1'::text < '0'::text)::int) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tablesample TABLESAMPLE bernoulli(('1'::text < '0'::text)::int)" +== 036 +-- truncate_limit: 100 +-- check behavior during rescans, as well as correct handling of min/max pct +select * from + (values (0),(100)) v(pct), + lateral (select count(*) from tenk1 tablesample bernoulli (pct)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(pct), LATERAL (SELECT ... FROM tenk1 TABLESAMPLE bernoulli(pct)) ss" +== 037 +-- truncate_limit: 100 +select * from + (values (0),(100)) v(pct), + lateral (select count(*) from tenk1 tablesample system (pct)) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (VALUES (...)) v(pct), LATERAL (SELECT count(*) FROM tenk1 TABLESAMPLE system(pct)) ss" +== 038 +-- truncate_limit: 100 +explain (costs off) +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample bernoulli (pct)) ss + group by pct +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT pct, count(unique1) FROM (VALUES (0), (100)) v(pct), LATERAL (SELECT *..." +== 039 +-- truncate_limit: 100 +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample bernoulli (pct)) ss + group by pct +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(pct), LATERAL (SELECT * FROM tenk1 TABLESAMPLE bernoulli(pct)) s..." +== 040 +-- truncate_limit: 100 +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample system (pct)) ss + group by pct +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(pct), LATERAL (SELECT * FROM tenk1 TABLESAMPLE system(pct)) ss G..." +== 041 +-- truncate_limit: 100 +-- errors +SELECT id FROM test_tablesample TABLESAMPLE FOOBAR (1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE foobar(1)" +== 042 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (NULL) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE system(NULL)" +== 043 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (NULL) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE system(50) REPEATABLE (NULL)" +== 044 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (-1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE bernoulli(-1)" +== 045 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (200) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE bernoulli(200)" +== 046 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (-1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE system(-1)" +== 047 +-- truncate_limit: 100 +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (200) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample TABLESAMPLE system(200)" +== 048 +-- truncate_limit: 100 +SELECT id FROM test_tablesample_v1 TABLESAMPLE BERNOULLI (1) +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT id FROM test_tablesample_v1 TABLESAMPLE bernoulli(1)" +== 049 +-- truncate_limit: 100 +INSERT INTO test_tablesample_v1 VALUES(1) +-- +TABLE: name="test_tablesample_v1" schema="" table="test_tablesample_v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_tablesample_v1 VALUES (1)" +== 050 +-- truncate_limit: 100 +WITH query_select AS (SELECT * FROM test_tablesample) +SELECT * FROM query_select TABLESAMPLE BERNOULLI (5.5) REPEATABLE (1) +-- +TABLE: name="test_tablesample" schema="" table="test_tablesample" ctx=Select +CTE: "query_select" +STMT: SelectStmt +TRUNCATED: "WITH query_select AS (...) SELECT * FROM query_select TABLESAMPLE bernoulli(5.5) REPEATABLE (1)" +== 051 +-- truncate_limit: 100 +SELECT q.* FROM (SELECT * FROM test_tablesample) as q TABLESAMPLE BERNOULLI (5) +-- +ERROR: syntax error at or near "TABLESAMPLE" +CURSORPOS: 55 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 052 +-- truncate_limit: 100 +-- check partitioned tables support tablesample +create table parted_sample (a int) partition by list (a) +-- +TABLE: name="parted_sample" schema="" table="parted_sample" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_sample (a int) PARTITION BY LIST (a)" +== 053 +-- truncate_limit: 100 +create table parted_sample_1 partition of parted_sample for values in (1) +-- +TABLE: name="parted_sample_1" schema="" table="parted_sample_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_sample_1 PARTITION OF parted_sample FOR VALUES IN (1)" +== 054 +-- truncate_limit: 100 +create table parted_sample_2 partition of parted_sample for values in (2) +-- +TABLE: name="parted_sample_2" schema="" table="parted_sample_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_sample_2 PARTITION OF parted_sample FOR VALUES IN (2)" +== 055 +-- truncate_limit: 100 +explain (costs off) + select * from parted_sample tablesample bernoulli (100) +-- +TABLE: name="parted_sample" schema="" table="parted_sample" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM parted_sample TABLESAMPLE bernoulli(100)" +== 056 +-- truncate_limit: 100 +drop table parted_sample, parted_sample_1, parted_sample_2 +-- +TABLE: name="parted_sample" schema="" table="parted_sample" ctx=DDL +TABLE: name="parted_sample_1" schema="" table="parted_sample_1" ctx=DDL +TABLE: name="parted_sample_2" schema="" table="parted_sample_2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_sample, parted_sample_1, parted_sample_2" diff --git a/parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json new file mode 100644 index 0000000..479ae3b --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json @@ -0,0 +1,208 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tablespace.test b/parser/testdata/summary_truncate/postgres_regress/tablespace.test new file mode 100644 index 0000000..599f79a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tablespace.test @@ -0,0 +1,1606 @@ +== 001 +-- truncate_limit: 100 +-- relative tablespace locations are not allowed +CREATE TABLESPACE regress_tblspace LOCATION 'relative' +-- +STMT: CreateTableSpaceStmt +TRUNCATED: "CREATE TABLESPACE regress_tblspace LOCATION 'relative'" +== 002 +-- truncate_limit: 100 +-- fail + +-- empty tablespace locations are not usually allowed +CREATE TABLESPACE regress_tblspace LOCATION '' +-- +STMT: CreateTableSpaceStmt +TRUNCATED: "CREATE TABLESPACE regress_tblspace LOCATION ''" +== 003 +-- truncate_limit: 100 +-- fail + +-- as a special developer-only option to allow us to use tablespaces +-- with streaming replication on the same server, an empty location +-- can be allowed as a way to say that the tablespace should be created +-- as a directory in pg_tblspc, rather than being a symlink +SET allow_in_place_tablespaces = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET allow_in_place_tablespaces TO TRUE" +== 004 +-- truncate_limit: 100 +-- create a tablespace using WITH clause +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (some_nonexistent_parameter = true) +-- +STMT: CreateTableSpaceStmt +TRUNCATED: "CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (some_nonexistent_parameter=true)" +== 005 +-- truncate_limit: 100 +-- fail +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (random_page_cost = 3.0) +-- +STMT: CreateTableSpaceStmt +TRUNCATED: "CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (random_page_cost=3.0)" +== 006 +-- truncate_limit: 100 +-- ok + +-- check to see the parameter was used +SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith' +-- +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +FILTER: schema="" table="" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'" +== 007 +-- truncate_limit: 100 +-- drop the tablespace so we can re-use the location +DROP TABLESPACE regress_tblspacewith +-- +STMT: DropTableSpaceStmt +TRUNCATED: "DROP TABLESPACE regress_tblspacewith" +== 008 +-- truncate_limit: 100 +-- This returns a relative path as of an effect of allow_in_place_tablespaces, +-- masking the tablespace OID used in the path name. +SELECT regexp_replace(pg_tablespace_location(oid), '(pg_tblspc)/(\d+)', '\1/NNN') + FROM pg_tablespace WHERE spcname = 'regress_tblspace' +-- +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +FUNCTION: name="regexp_replace" function="regexp_replace" schema="" ctx=Call +FUNCTION: name="pg_tablespace_location" function="pg_tablespace_location" schema="" ctx=Call +FILTER: schema="" table="" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_tablespace WHERE spcname = 'regress_tblspace'" +== 009 +-- truncate_limit: 100 +-- try setting and resetting some properties for the new tablespace +ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1) +-- +STMT: AlterTableSpaceOptionsStmt +TRUNCATED: "ALTER TABLESPACE regress_tblspace SET (random_page_cost=1.0, seq_page_cost=1.1)" +== 010 +-- truncate_limit: 100 +ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true) +-- +STMT: AlterTableSpaceOptionsStmt +TRUNCATED: "ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter=true)" +== 011 +-- truncate_limit: 100 +-- fail +ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0) +-- +STMT: AlterTableSpaceOptionsStmt +TRUNCATED: "ALTER TABLESPACE regress_tblspace RESET (random_page_cost=2.0)" +== 012 +-- truncate_limit: 100 +-- fail +ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency) +-- +STMT: AlterTableSpaceOptionsStmt +TRUNCATED: "ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency)" +== 013 +-- truncate_limit: 100 +-- ok + +-- REINDEX (TABLESPACE) +-- catalogs and system tablespaces +-- system catalog, fail +REINDEX (TABLESPACE regress_tblspace) TABLE pg_am +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) TABLE pg_am" +== 014 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_am +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE pg_am" +== 015 +-- truncate_limit: 100 +-- shared catalog, fail +REINDEX (TABLESPACE regress_tblspace) TABLE pg_authid +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) TABLE pg_authid" +== 016 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_authid +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE pg_authid" +== 017 +-- truncate_limit: 100 +-- toast relations, fail +REINDEX (TABLESPACE regress_tblspace) INDEX pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) INDEX pg_toast.pg_toast_1260_index" +== 018 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) INDEX CONCURRENTLY pg_toast.pg_toast_1260_index +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) INDEX pg_toast.pg_toast_1260_index" +== 019 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) TABLE pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) TABLE pg_toast.pg_toast_1260" +== 020 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_toast.pg_toast_1260 +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE pg_toast.pg_toast_1260" +== 021 +-- truncate_limit: 100 +-- system catalog, fail +REINDEX (TABLESPACE pg_global) TABLE pg_authid +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE pg_global) TABLE pg_authid" +== 022 +-- truncate_limit: 100 +REINDEX (TABLESPACE pg_global) TABLE CONCURRENTLY pg_authid +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE pg_global, CONCURRENTLY) TABLE pg_authid" +== 023 +-- truncate_limit: 100 +-- table with toast relation +CREATE TABLE regress_tblspace_test_tbl (num1 bigint, num2 double precision, t text) +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE regress_tblspace_test_tbl (num1 bigint, num2 double precision, t text)" +== 024 +-- truncate_limit: 100 +INSERT INTO regress_tblspace_test_tbl (num1, num2, t) + SELECT round(random()*100), random(), 'text' + FROM generate_series(1, 10) s(i) +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DML +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO regress_tblspace_test_tbl (num1, num2, t) SELECT ... FROM generate_series(1, 10) s(i)" +== 025 +-- truncate_limit: 100 +CREATE INDEX regress_tblspace_test_tbl_idx ON regress_tblspace_test_tbl (num1) +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX regress_tblspace_test_tbl_idx ON regress_tblspace_test_tbl USING btree (num1)" +== 026 +-- truncate_limit: 100 +-- move to global tablespace, fail +REINDEX (TABLESPACE pg_global) INDEX regress_tblspace_test_tbl_idx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE pg_global) INDEX regress_tblspace_test_tbl_idx" +== 027 +-- truncate_limit: 100 +REINDEX (TABLESPACE pg_global) INDEX CONCURRENTLY regress_tblspace_test_tbl_idx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE pg_global, CONCURRENTLY) INDEX regress_tblspace_test_tbl_idx" +== 028 +-- truncate_limit: 100 +-- check transactional behavior of REINDEX (TABLESPACE) +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 029 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) INDEX regress_tblspace_test_tbl_idx +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) INDEX regress_tblspace_test_tbl_idx" +== 030 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl" +== 031 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 032 +-- truncate_limit: 100 +-- no relation moved to the new tablespace +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT c.relname FROM pg_class c, pg_tablespace s WHERE ..." +== 033 +-- truncate_limit: 100 +-- check that all indexes are moved to a new tablespace with different +-- relfilenode. +-- Save first the existing relfilenode for the toast and main relations. +SELECT relfilenode as main_filenode FROM pg_class + WHERE relname = 'regress_tblspace_test_tbl_idx' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relfilenode AS main_filenode FROM pg_class WHERE relname = 'regress_tblspace_test_tbl_idx'" +== 034 +-- truncate_limit: 100 +SELECT relfilenode as toast_filenode FROM pg_class + WHERE oid = + (SELECT i.indexrelid + FROM pg_class c, + pg_index i + WHERE i.indrelid = c.reltoastrelid AND + c.relname = 'regress_tblspace_test_tbl') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_index" schema="" table="pg_index" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "i"="pg_index" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="i" column="indrelid" +FILTER: schema="" table="c" column="reltoastrelid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relfilenode AS toast_filenode FROM pg_class WHERE ..." +== 035 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl" +== 036 +-- truncate_limit: 100 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT c.relname FROM pg_class c, pg_tablespace s WHERE ... ORDER BY c.relname" +== 037 +-- truncate_limit: 100 +ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE regress_tblspace +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE regress_tblspace" +== 038 +-- truncate_limit: 100 +ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE pg_default +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE pg_default" +== 039 +-- truncate_limit: 100 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT c.relname FROM pg_class c, pg_tablespace s WHERE ... ORDER BY c.relname" +== 040 +-- truncate_limit: 100 +-- Move back to the default tablespace. +ALTER INDEX regress_tblspace_test_tbl_idx SET TABLESPACE pg_default +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX regress_tblspace_test_tbl_idx SET TABLESPACE pg_default" +== 041 +-- truncate_limit: 100 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT c.relname FROM pg_class c, pg_tablespace s WHERE ... ORDER BY c.relname" +== 042 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE regress_tblspace_test_tbl +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE regress_tblspace_test_tbl" +== 043 +-- truncate_limit: 100 +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_tablespace" schema="" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="s" column="oid" +FILTER: schema="" table="s" column="spcname" +STMT: SelectStmt +TRUNCATED: "SELECT c.relname FROM pg_class c, pg_tablespace s WHERE ... ORDER BY c.relname" +== 044 +-- truncate_limit: 100 +SELECT relfilenode = :main_filenode AS main_same FROM pg_class + WHERE relname = 'regress_tblspace_test_tbl_idx' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 045 +-- truncate_limit: 100 +SELECT relfilenode = :toast_filenode as toast_same FROM pg_class + WHERE oid = + (SELECT i.indexrelid + FROM pg_class c, + pg_index i + WHERE i.indrelid = c.reltoastrelid AND + c.relname = 'regress_tblspace_test_tbl') +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 046 +-- truncate_limit: 100 +DROP TABLE regress_tblspace_test_tbl +-- +TABLE: name="regress_tblspace_test_tbl" schema="" table="regress_tblspace_test_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE regress_tblspace_test_tbl" +== 047 +-- truncate_limit: 100 +-- REINDEX (TABLESPACE) with partitions +-- Create a partition tree and check the set of relations reindexed +-- with their new tablespace. +CREATE TABLE tbspace_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1) +-- +TABLE: name="tbspace_reindex_part" schema="" table="tbspace_reindex_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbspace_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1)" +== 048 +-- truncate_limit: 100 +CREATE TABLE tbspace_reindex_part_0 PARTITION OF tbspace_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2) +-- +TABLE: name="tbspace_reindex_part_0" schema="" table="tbspace_reindex_part_0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbspace_reindex_part_0 PARTITION OF tbspace_reindex_part FOR VALUES FROM (0) TO (10)..." +== 049 +-- truncate_limit: 100 +CREATE TABLE tbspace_reindex_part_0_1 PARTITION OF tbspace_reindex_part_0 + FOR VALUES IN (1) +-- +TABLE: name="tbspace_reindex_part_0_1" schema="" table="tbspace_reindex_part_0_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbspace_reindex_part_0_1 PARTITION OF tbspace_reindex_part_0 FOR VALUES IN (1)" +== 050 +-- truncate_limit: 100 +CREATE TABLE tbspace_reindex_part_0_2 PARTITION OF tbspace_reindex_part_0 + FOR VALUES IN (2) +-- +TABLE: name="tbspace_reindex_part_0_2" schema="" table="tbspace_reindex_part_0_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbspace_reindex_part_0_2 PARTITION OF tbspace_reindex_part_0 FOR VALUES IN (2)" +== 051 +-- truncate_limit: 100 +-- This partitioned table will have no partitions. +CREATE TABLE tbspace_reindex_part_10 PARTITION OF tbspace_reindex_part + FOR VALUES FROM (10) TO (20) PARTITION BY list (c2) +-- +TABLE: name="tbspace_reindex_part_10" schema="" table="tbspace_reindex_part_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tbspace_reindex_part_10 PARTITION OF tbspace_reindex_part FOR VALUES FROM (10) TO (2..." +== 052 +-- truncate_limit: 100 +-- Create some partitioned indexes +CREATE INDEX tbspace_reindex_part_index ON ONLY tbspace_reindex_part (c1) +-- +TABLE: name="tbspace_reindex_part" schema="" table="tbspace_reindex_part" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbspace_reindex_part_index ON ONLY tbspace_reindex_part USING btree (c1)" +== 053 +-- truncate_limit: 100 +CREATE INDEX tbspace_reindex_part_index_0 ON ONLY tbspace_reindex_part_0 (c1) +-- +TABLE: name="tbspace_reindex_part_0" schema="" table="tbspace_reindex_part_0" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbspace_reindex_part_index_0 ON ONLY tbspace_reindex_part_0 USING btree (c1)" +== 054 +-- truncate_limit: 100 +ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_0 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_0" +== 055 +-- truncate_limit: 100 +-- This partitioned index will have no partitions. +CREATE INDEX tbspace_reindex_part_index_10 ON ONLY tbspace_reindex_part_10 (c1) +-- +TABLE: name="tbspace_reindex_part_10" schema="" table="tbspace_reindex_part_10" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbspace_reindex_part_index_10 ON ONLY tbspace_reindex_part_10 USING btree (c1)" +== 056 +-- truncate_limit: 100 +ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_10 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_10" +== 057 +-- truncate_limit: 100 +CREATE INDEX tbspace_reindex_part_index_0_1 ON ONLY tbspace_reindex_part_0_1 (c1) +-- +TABLE: name="tbspace_reindex_part_0_1" schema="" table="tbspace_reindex_part_0_1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbspace_reindex_part_index_0_1 ON ONLY tbspace_reindex_part_0_1 USING btree (c1)" +== 058 +-- truncate_limit: 100 +ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_1 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_1" +== 059 +-- truncate_limit: 100 +CREATE INDEX tbspace_reindex_part_index_0_2 ON ONLY tbspace_reindex_part_0_2 (c1) +-- +TABLE: name="tbspace_reindex_part_0_2" schema="" table="tbspace_reindex_part_0_2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tbspace_reindex_part_index_0_2 ON ONLY tbspace_reindex_part_0_2 USING btree (c1)" +== 060 +-- truncate_limit: 100 +ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_2 +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_2" +== 061 +-- truncate_limit: 100 +SELECT relid, parentrelid, level FROM pg_partition_tree('tbspace_reindex_part_index') + ORDER BY relid, level +-- +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_partition_tree('tbspace_reindex_part_index') ORDER BY relid, level" +== 062 +-- truncate_limit: 100 +-- Track the original tablespace, relfilenode and OID of each index +-- in the tree. +CREATE TEMP TABLE reindex_temp_before AS + SELECT oid, relname, relfilenode, reltablespace + FROM pg_class + WHERE relname ~ 'tbspace_reindex_part_index' +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=DDL +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE reindex_temp_before AS SELECT oid, relname, relfilenode, reltablespace FRO..." +== 063 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tbspace_reindex_part +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tbspace_reindex_part" +== 064 +-- truncate_limit: 100 +-- REINDEX CONCURRENTLY changes the OID of the old relation, hence a check +-- based on the relation name below. +SELECT b.relname, + CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' + ELSE 'relfilenode has changed' END AS filenode, + CASE WHEN a.reltablespace = b.reltablespace THEN 'reltablespace is unchanged' + ELSE 'reltablespace has changed' END AS tbspace + FROM reindex_temp_before b JOIN pg_class a ON b.relname = a.relname + ORDER BY 1 +-- +TABLE: name="reindex_temp_before" schema="" table="reindex_temp_before" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a"="pg_class" +ALIAS: "b"="reindex_temp_before" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM reindex_temp_before b JOIN pg_class a ON b.relname = a.relname ORDER BY 1" +== 065 +-- truncate_limit: 100 +DROP TABLE tbspace_reindex_part +-- +TABLE: name="tbspace_reindex_part" schema="" table="tbspace_reindex_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tbspace_reindex_part" +== 066 +-- truncate_limit: 100 +-- create a schema we can use +CREATE SCHEMA testschema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA testschema" +== 067 +-- truncate_limit: 100 +-- try a table +CREATE TABLE testschema.foo (i int) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.foo (i int) TABLESPACE regress_tblspace" +== 068 +-- truncate_limit: 100 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'foo' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c WHERE ..." +== 069 +-- truncate_limit: 100 +INSERT INTO testschema.foo VALUES(1) +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testschema.foo VALUES (1)" +== 070 +-- truncate_limit: 100 +INSERT INTO testschema.foo VALUES(2) +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testschema.foo VALUES (2)" +== 071 +-- truncate_limit: 100 +-- tables from dynamic sources +CREATE TABLE testschema.asselect TABLESPACE regress_tblspace AS SELECT 1 +-- +TABLE: name="testschema.asselect" schema="testschema" table="asselect" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE testschema.asselect TABLESPACE regress_tblspace AS SELECT 1" +== 072 +-- truncate_limit: 100 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'asselect' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c WHERE ..." +== 073 +-- truncate_limit: 100 +PREPARE selectsource(int) AS SELECT $1 +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE selectsource(int) AS SELECT $1" +== 074 +-- truncate_limit: 100 +CREATE TABLE testschema.asexecute TABLESPACE regress_tblspace + AS EXECUTE selectsource(2) +-- +TABLE: name="testschema.asexecute" schema="testschema" table="asexecute" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TABLE testschema.asexecute TABLESPACE regress_tblspace AS EXECUTE selectsource(2)" +== 075 +-- truncate_limit: 100 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'asexecute' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c WHERE ..." +== 076 +-- truncate_limit: 100 +-- index +CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.foo" schema="testschema" table="foo" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX foo_idx ON testschema.foo USING btree (i) TABLESPACE regress_tblspace" +== 077 +-- truncate_limit: 100 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'foo_idx' +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c WHERE ..." +== 078 +-- truncate_limit: 100 +-- check \d output + +|-- +-- partitioned table +|-- +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a) +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part (a int) PARTITION BY LIST (a)" +== 079 +-- truncate_limit: 100 +SET default_tablespace TO pg_global +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO pg_global" +== 080 +-- truncate_limit: 100 +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1) +-- +TABLE: name="testschema.part_1" schema="testschema" table="part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1)" +== 081 +-- truncate_limit: 100 +RESET default_tablespace +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_tablespace" +== 082 +-- truncate_limit: 100 +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1) +-- +TABLE: name="testschema.part_1" schema="testschema" table="part_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1)" +== 083 +-- truncate_limit: 100 +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO regress_tblspace" +== 084 +-- truncate_limit: 100 +CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2) +-- +TABLE: name="testschema.part_2" schema="testschema" table="part_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2)" +== 085 +-- truncate_limit: 100 +SET default_tablespace TO pg_global +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO pg_global" +== 086 +-- truncate_limit: 100 +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3) +-- +TABLE: name="testschema.part_3" schema="testschema" table="part_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3)" +== 087 +-- truncate_limit: 100 +ALTER TABLE testschema.part SET TABLESPACE regress_tblspace +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.part SET TABLESPACE regress_tblspace" +== 088 +-- truncate_limit: 100 +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3) +-- +TABLE: name="testschema.part_3" schema="testschema" table="part_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3)" +== 089 +-- truncate_limit: 100 +CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) + TABLESPACE pg_default +-- +TABLE: name="testschema.part_4" schema="testschema" table="part_4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) TABLESPACE pg_default" +== 090 +-- truncate_limit: 100 +CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) + PARTITION BY LIST (a) +-- +TABLE: name="testschema.part_56" schema="testschema" table="part_56" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) PARTITION BY LI..." +== 091 +-- truncate_limit: 100 +ALTER TABLE testschema.part SET TABLESPACE pg_default +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.part SET TABLESPACE pg_default" +== 092 +-- truncate_limit: 100 +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a) +-- +TABLE: name="testschema.part_78" schema="testschema" table="part_78" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) PARTITION BY LI..." +== 093 +-- truncate_limit: 100 +CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) + PARTITION BY LIST (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.part_910" schema="testschema" table="part_910" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) PARTITION BY ..." +== 094 +-- truncate_limit: 100 +RESET default_tablespace +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_tablespace" +== 095 +-- truncate_limit: 100 +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a) +-- +TABLE: name="testschema.part_78" schema="testschema" table="part_78" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) PARTITION BY LI..." +== 096 +-- truncate_limit: 100 +SELECT relname, spcname FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) + LEFT JOIN pg_catalog.pg_tablespace t ON c.reltablespace = t.oid + where c.relname LIKE 'part%' AND n.nspname = 'testschema' order by relname +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +TABLE: name="pg_catalog.pg_namespace" schema="pg_catalog" table="pg_namespace" ctx=Select +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "n"="pg_catalog.pg_namespace" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="n" column="nspname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid LE..." +== 097 +-- truncate_limit: 100 +RESET default_tablespace +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_tablespace" +== 098 +-- truncate_limit: 100 +DROP TABLE testschema.part +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testschema.part" +== 099 +-- truncate_limit: 100 +-- partitioned index +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a) +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part (a int) PARTITION BY LIST (a)" +== 100 +-- truncate_limit: 100 +CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1) +-- +TABLE: name="testschema.part1" schema="testschema" table="part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1)" +== 101 +-- truncate_limit: 100 +CREATE INDEX part_a_idx ON testschema.part (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.part" schema="testschema" table="part" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX part_a_idx ON testschema.part USING btree (a) TABLESPACE regress_tblspace" +== 102 +-- truncate_limit: 100 +CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2) +-- +TABLE: name="testschema.part2" schema="testschema" table="part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2)" +== 103 +-- truncate_limit: 100 +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname LIKE 'part%_idx' ORDER BY relname +-- +TABLE: name="pg_catalog.pg_tablespace" schema="pg_catalog" table="pg_tablespace" ctx=Select +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=Select +ALIAS: "c"="pg_catalog.pg_class" +ALIAS: "t"="pg_catalog.pg_tablespace" +FILTER: schema="" table="c" column="reltablespace" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c WHERE ... ORDER BY relname" +== 104 +-- truncate_limit: 100 +-- partitioned rels cannot specify the default tablespace. These fail: +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE pg_default +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE pg_default" +== 105 +-- truncate_limit: 100 +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE pg_default) PARTITION BY LIST (a) +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE pg_default) PARTITION BY L..." +== 106 +-- truncate_limit: 100 +SET default_tablespace TO 'pg_default' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO pg_default" +== 107 +-- truncate_limit: 100 +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE regress_tblspace" +== 108 +-- truncate_limit: 100 +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a) +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITIO..." +== 109 +-- truncate_limit: 100 +-- but these work: +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITIO..." +== 110 +-- truncate_limit: 100 +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO ''" +== 111 +-- truncate_limit: 100 +CREATE TABLE testschema.dflt2 (a int PRIMARY KEY) PARTITION BY LIST (a) +-- +TABLE: name="testschema.dflt2" schema="testschema" table="dflt2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.dflt2 (a int PRIMARY KEY) PARTITION BY LIST (a)" +== 112 +-- truncate_limit: 100 +DROP TABLE testschema.dflt, testschema.dflt2 +-- +TABLE: name="testschema.dflt" schema="testschema" table="dflt" ctx=DDL +TABLE: name="testschema.dflt2" schema="testschema" table="dflt2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testschema.dflt, testschema.dflt2" +== 113 +-- truncate_limit: 100 +-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds +CREATE TABLE testschema.test_default_tab(id bigint) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.test_default_tab (id bigint) TABLESPACE regress_tblspace" +== 114 +-- truncate_limit: 100 +INSERT INTO testschema.test_default_tab VALUES (1) +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testschema.test_default_tab VALUES (1)" +== 115 +-- truncate_limit: 100 +CREATE INDEX test_index1 on testschema.test_default_tab (id) +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_index1 ON testschema.test_default_tab USING btree (id)" +== 116 +-- truncate_limit: 100 +CREATE INDEX test_index2 on testschema.test_default_tab (id) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_index2 ON testschema.test_default_tab USING btree (id) TABLESPACE regress_tblspace" +== 117 +-- truncate_limit: 100 +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index3 PRIMARY KEY (id) +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index3 PRIMARY KEY (id)" +== 118 +-- truncate_limit: 100 +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLES..." +== 119 +-- truncate_limit: 100 +-- use a custom tablespace for default_tablespace +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO regress_tblspace" +== 120 +-- truncate_limit: 100 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab ALTER COLUMN id TYPE bigint" +== 121 +-- truncate_limit: 100 +SELECT * FROM testschema.test_default_tab +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testschema.test_default_tab" +== 122 +-- truncate_limit: 100 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE int +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab ALTER COLUMN id TYPE int" +== 123 +-- truncate_limit: 100 +SELECT * FROM testschema.test_default_tab +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testschema.test_default_tab" +== 124 +-- truncate_limit: 100 +-- now use the default tablespace for default_tablespace +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO ''" +== 125 +-- truncate_limit: 100 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE int +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab ALTER COLUMN id TYPE int" +== 126 +-- truncate_limit: 100 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab ALTER COLUMN id TYPE bigint" +== 127 +-- truncate_limit: 100 +DROP TABLE testschema.test_default_tab +-- +TABLE: name="testschema.test_default_tab" schema="testschema" table="test_default_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testschema.test_default_tab" +== 128 +-- truncate_limit: 100 +-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds +-- (this time with a partitioned table) +CREATE TABLE testschema.test_default_tab_p(id bigint, val bigint) + PARTITION BY LIST (id) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.test_default_tab_p (id bigint, val bigint) PARTITION BY LIST (id) TABLESP..." +== 129 +-- truncate_limit: 100 +CREATE TABLE testschema.test_default_tab_p1 PARTITION OF testschema.test_default_tab_p + FOR VALUES IN (1) +-- +TABLE: name="testschema.test_default_tab_p1" schema="testschema" table="test_default_tab_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.test_default_tab_p1 PARTITION OF testschema.test_default_tab_p FOR VALUES..." +== 130 +-- truncate_limit: 100 +INSERT INTO testschema.test_default_tab_p VALUES (1) +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testschema.test_default_tab_p VALUES (1)" +== 131 +-- truncate_limit: 100 +CREATE INDEX test_index1 on testschema.test_default_tab_p (val) +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_index1 ON testschema.test_default_tab_p USING btree (val)" +== 132 +-- truncate_limit: 100 +CREATE INDEX test_index2 on testschema.test_default_tab_p (val) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_index2 ON testschema.test_default_tab_p USING btree (val) TABLESPACE regress_tb..." +== 133 +-- truncate_limit: 100 +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index3 PRIMARY KEY (id) +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index3 PRIMARY KEY (id)" +== 134 +-- truncate_limit: 100 +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABL..." +== 135 +-- truncate_limit: 100 +-- use a custom tablespace for default_tablespace +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO regress_tblspace" +== 136 +-- truncate_limit: 100 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab_p ALTER COLUMN val TYPE bigint" +== 137 +-- truncate_limit: 100 +SELECT * FROM testschema.test_default_tab_p +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testschema.test_default_tab_p" +== 138 +-- truncate_limit: 100 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab_p ALTER COLUMN val TYPE int" +== 139 +-- truncate_limit: 100 +SELECT * FROM testschema.test_default_tab_p +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testschema.test_default_tab_p" +== 140 +-- truncate_limit: 100 +-- now use the default tablespace for default_tablespace +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO ''" +== 141 +-- truncate_limit: 100 +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab_p ALTER COLUMN val TYPE int" +== 142 +-- truncate_limit: 100 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_default_tab_p ALTER COLUMN val TYPE bigint" +== 143 +-- truncate_limit: 100 +DROP TABLE testschema.test_default_tab_p +-- +TABLE: name="testschema.test_default_tab_p" schema="testschema" table="test_default_tab_p" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testschema.test_default_tab_p" +== 144 +-- truncate_limit: 100 +-- check that default_tablespace affects index additions in ALTER TABLE +CREATE TABLE testschema.test_tab(id int) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.test_tab (id int) TABLESPACE regress_tblspace" +== 145 +-- truncate_limit: 100 +INSERT INTO testschema.test_tab VALUES (1) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testschema.test_tab VALUES (1)" +== 146 +-- truncate_limit: 100 +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO regress_tblspace" +== 147 +-- truncate_limit: 100 +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (id) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (id)" +== 148 +-- truncate_limit: 100 +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO ''" +== 149 +-- truncate_limit: 100 +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_pkey PRIMARY KEY (id) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_pkey PRIMARY KEY (id)" +== 150 +-- truncate_limit: 100 +SELECT * FROM testschema.test_tab +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM testschema.test_tab" +== 151 +-- truncate_limit: 100 +DROP TABLE testschema.test_tab +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testschema.test_tab" +== 152 +-- truncate_limit: 100 +-- check that default_tablespace is handled correctly by multi-command +-- ALTER TABLE that includes a tablespace-preserving rewrite +CREATE TABLE testschema.test_tab(a int, b int, c int) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.test_tab (a int, b int, c int)" +== 153 +-- truncate_limit: 100 +SET default_tablespace TO regress_tblspace +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO regress_tblspace" +== 154 +-- truncate_limit: 100 +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (a) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (a)" +== 155 +-- truncate_limit: 100 +CREATE INDEX test_tab_a_idx ON testschema.test_tab (a) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_tab_a_idx ON testschema.test_tab USING btree (a)" +== 156 +-- truncate_limit: 100 +SET default_tablespace TO '' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_tablespace TO ''" +== 157 +-- truncate_limit: 100 +CREATE INDEX test_tab_b_idx ON testschema.test_tab (b) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX test_tab_b_idx ON testschema.test_tab USING btree (b)" +== 158 +-- truncate_limit: 100 +ALTER TABLE testschema.test_tab ALTER b TYPE bigint, ADD UNIQUE (c) +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.test_tab ALTER COLUMN b TYPE bigint, ADD UNIQUE (c)" +== 159 +-- truncate_limit: 100 +DROP TABLE testschema.test_tab +-- +TABLE: name="testschema.test_tab" schema="testschema" table="test_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE testschema.test_tab" +== 160 +-- truncate_limit: 100 +-- let's try moving a table from one place to another +CREATE TABLE testschema.atable AS VALUES (1), (2) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE testschema.atable AS VALUES (1), (2)" +== 161 +-- truncate_limit: 100 +CREATE UNIQUE INDEX anindex ON testschema.atable(column1) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX anindex ON testschema.atable USING btree (column1)" +== 162 +-- truncate_limit: 100 +ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace" +== 163 +-- truncate_limit: 100 +ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace" +== 164 +-- truncate_limit: 100 +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_global +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_global" +== 165 +-- truncate_limit: 100 +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default" +== 166 +-- truncate_limit: 100 +ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace" +== 167 +-- truncate_limit: 100 +INSERT INTO testschema.atable VALUES(3) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testschema.atable VALUES (3)" +== 168 +-- truncate_limit: 100 +-- ok +INSERT INTO testschema.atable VALUES(1) +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testschema.atable VALUES (1)" +== 169 +-- truncate_limit: 100 +-- fail (checks index) +SELECT COUNT(*) FROM testschema.atable +-- +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testschema.atable" +== 170 +-- truncate_limit: 100 +-- checks heap + +-- let's try moving a materialized view from one place to another +CREATE MATERIALIZED VIEW testschema.amv AS SELECT * FROM testschema.atable +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=DDL +TABLE: name="testschema.atable" schema="testschema" table="atable" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW testschema.amv AS SELECT * FROM testschema.atable" +== 171 +-- truncate_limit: 100 +ALTER MATERIALIZED VIEW testschema.amv SET TABLESPACE regress_tblspace +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER MATERIALIZED VIEW testschema.amv SET TABLESPACE regress_tblspace" +== 172 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW testschema.amv +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW testschema.amv" +== 173 +-- truncate_limit: 100 +SELECT COUNT(*) FROM testschema.amv +-- +TABLE: name="testschema.amv" schema="testschema" table="amv" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM testschema.amv" +== 174 +-- truncate_limit: 100 +-- Will fail with bad path +CREATE TABLESPACE regress_badspace LOCATION '/no/such/location' +-- +STMT: CreateTableSpaceStmt +TRUNCATED: "CREATE TABLESPACE regress_badspace LOCATION '/no/such/location'" +== 175 +-- truncate_limit: 100 +-- No such tablespace +CREATE TABLE bar (i int) TABLESPACE regress_nosuchspace +-- +TABLE: name="bar" schema="" table="bar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE bar (i int) TABLESPACE regress_nosuchspace" +== 176 +-- truncate_limit: 100 +-- Fail, in use for some partitioned object +DROP TABLESPACE regress_tblspace +-- +STMT: DropTableSpaceStmt +TRUNCATED: "DROP TABLESPACE regress_tblspace" +== 177 +-- truncate_limit: 100 +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default +-- +STMT: AlterTableStmt +TRUNCATED: "ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default" +== 178 +-- truncate_limit: 100 +-- Fail, not empty +DROP TABLESPACE regress_tblspace +-- +STMT: DropTableSpaceStmt +TRUNCATED: "DROP TABLESPACE regress_tblspace" +== 179 +-- truncate_limit: 100 +-- Adequate cache initialization before GRANT +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 180 +-- truncate_limit: 100 +GRANT ALL ON TABLESPACE regress_tblspace TO PUBLIC +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON TABLESPACE regress_tblspace TO public" +== 181 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 182 +-- truncate_limit: 100 +CREATE ROLE regress_tablespace_user1 login +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_tablespace_user1 WITH LOGIN" +== 183 +-- truncate_limit: 100 +CREATE ROLE regress_tablespace_user2 login +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_tablespace_user2 WITH LOGIN" +== 184 +-- truncate_limit: 100 +GRANT USAGE ON SCHEMA testschema TO regress_tablespace_user2 +-- +STMT: GrantStmt +TRUNCATED: "GRANT usage ON SCHEMA testschema TO regress_tablespace_user2" +== 185 +-- truncate_limit: 100 +ALTER TABLESPACE regress_tblspace OWNER TO regress_tablespace_user1 +-- +STMT: AlterOwnerStmt +TRUNCATED: "ALTER TABLESPACE regress_tblspace OWNER TO regress_tablespace_user1" +== 186 +-- truncate_limit: 100 +CREATE TABLE testschema.tablespace_acl (c int) +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testschema.tablespace_acl (c int)" +== 187 +-- truncate_limit: 100 +-- new owner lacks permission to create this index from scratch +CREATE INDEX k ON testschema.tablespace_acl (c) TABLESPACE regress_tblspace +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX k ON testschema.tablespace_acl USING btree (c) TABLESPACE regress_tblspace" +== 188 +-- truncate_limit: 100 +ALTER TABLE testschema.tablespace_acl OWNER TO regress_tablespace_user2 +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.tablespace_acl OWNER TO regress_tablespace_user2" +== 189 +-- truncate_limit: 100 +SET SESSION ROLE regress_tablespace_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_tablespace_user2" +== 190 +-- truncate_limit: 100 +CREATE TABLE tablespace_table (i int) TABLESPACE regress_tblspace +-- +TABLE: name="tablespace_table" schema="" table="tablespace_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tablespace_table (i int) TABLESPACE regress_tblspace" +== 191 +-- truncate_limit: 100 +-- fail +ALTER TABLE testschema.tablespace_acl ALTER c TYPE bigint +-- +TABLE: name="testschema.tablespace_acl" schema="testschema" table="tablespace_acl" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testschema.tablespace_acl ALTER COLUMN c TYPE bigint" +== 192 +-- truncate_limit: 100 +REINDEX (TABLESPACE regress_tblspace) TABLE tablespace_table +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace) TABLE tablespace_table" +== 193 +-- truncate_limit: 100 +-- fail +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tablespace_table +-- +STMT: ReindexStmt +TRUNCATED: "REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tablespace_table" +== 194 +-- truncate_limit: 100 +-- fail +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 195 +-- truncate_limit: 100 +ALTER TABLESPACE regress_tblspace RENAME TO regress_tblspace_renamed +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLESPACE regress_tblspace RENAME TO regress_tblspace_renamed" +== 196 +-- truncate_limit: 100 +ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +TRUNCATED: "ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default" +== 197 +-- truncate_limit: 100 +ALTER INDEX ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +TRUNCATED: "ALTER INDEX ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default" +== 198 +-- truncate_limit: 100 +ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +TRUNCATED: "ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default" +== 199 +-- truncate_limit: 100 +-- Should show notice that nothing was done +ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +TRUNCATED: "ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default" +== 200 +-- truncate_limit: 100 +ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default +-- +STMT: AlterTableMoveAllStmt +TRUNCATED: "ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default" +== 201 +-- truncate_limit: 100 +-- Should succeed +DROP TABLESPACE regress_tblspace_renamed +-- +STMT: DropTableSpaceStmt +TRUNCATED: "DROP TABLESPACE regress_tblspace_renamed" +== 202 +-- truncate_limit: 100 +DROP SCHEMA testschema CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SCHEMA testschema CASCADE" +== 203 +-- truncate_limit: 100 +DROP ROLE regress_tablespace_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_tablespace_user1" +== 204 +-- truncate_limit: 100 +DROP ROLE regress_tablespace_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_tablespace_user2" diff --git a/parser/testdata/summary_truncate/postgres_regress/temp.metadata.json b/parser/testdata/summary_truncate/postgres_regress/temp.metadata.json new file mode 100644 index 0000000..4e31a92 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/temp.metadata.json @@ -0,0 +1,166 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/temp.test b/parser/testdata/summary_truncate/postgres_regress/temp.test new file mode 100644 index 0000000..89e99e8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/temp.test @@ -0,0 +1,1188 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TEMP +-- Test temp relations and indexes +|-- + +-- test temp table/index masking + +CREATE TABLE temptest(col int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE temptest (col int)" +== 002 +-- truncate_limit: 100 +CREATE INDEX i_temptest ON temptest(col) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX i_temptest ON temptest USING btree (col)" +== 003 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest(tcol int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest (tcol int)" +== 004 +-- truncate_limit: 100 +CREATE INDEX i_temptest ON temptest(tcol) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX i_temptest ON temptest USING btree (tcol)" +== 005 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 006 +-- truncate_limit: 100 +DROP INDEX i_temptest +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX i_temptest" +== 007 +-- truncate_limit: 100 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temptest" +== 008 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 009 +-- truncate_limit: 100 +DROP INDEX i_temptest +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX i_temptest" +== 010 +-- truncate_limit: 100 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temptest" +== 011 +-- truncate_limit: 100 +-- test temp table selects + +CREATE TABLE temptest(col int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE temptest (col int)" +== 012 +-- truncate_limit: 100 +INSERT INTO temptest VALUES (1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest VALUES (1)" +== 013 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest(tcol float) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest (tcol double precision)" +== 014 +-- truncate_limit: 100 +INSERT INTO temptest VALUES (2.1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest VALUES (2.1)" +== 015 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 016 +-- truncate_limit: 100 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temptest" +== 017 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 018 +-- truncate_limit: 100 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temptest" +== 019 +-- truncate_limit: 100 +-- test temp table deletion + +CREATE TEMP TABLE temptest(col int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest (col int)" +== 020 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 021 +-- truncate_limit: 100 +-- Test ON COMMIT DELETE ROWS + +CREATE TEMP TABLE temptest(col int) ON COMMIT DELETE ROWS +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest (col int) ON COMMIT DELETE ROWS" +== 022 +-- truncate_limit: 100 +-- while we're here, verify successful truncation of index with SQL function +CREATE INDEX ON temptest(bit_length('')) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +FUNCTION: name="bit_length" function="bit_length" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON temptest USING btree (bit_length(''))" +== 023 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 024 +-- truncate_limit: 100 +INSERT INTO temptest VALUES (1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest VALUES (1)" +== 025 +-- truncate_limit: 100 +INSERT INTO temptest VALUES (2) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest VALUES (2)" +== 026 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 027 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 028 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 029 +-- truncate_limit: 100 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temptest" +== 030 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 031 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1 +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1" +== 032 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 033 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 034 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 035 +-- truncate_limit: 100 +DROP TABLE temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temptest" +== 036 +-- truncate_limit: 100 +-- Test ON COMMIT DROP + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 037 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest(col int) ON COMMIT DROP +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest (col int) ON COMMIT DROP" +== 038 +-- truncate_limit: 100 +INSERT INTO temptest VALUES (1) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest VALUES (1)" +== 039 +-- truncate_limit: 100 +INSERT INTO temptest VALUES (2) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest VALUES (2)" +== 040 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 041 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 042 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 043 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 044 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest(col) ON COMMIT DROP AS SELECT 1 +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest(col) ON COMMIT DROP AS SELECT 1" +== 045 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 046 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 047 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 048 +-- truncate_limit: 100 +-- Test it with a CHECK condition that produces a toasted pg_constraint entry +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 049 +-- truncate_limit: 100 +do $$ +begin + execute format($cmd$ + CREATE TEMP TABLE temptest (col text CHECK (col < %L)) ON COMMIT DROP + $cmd$, + (SELECT string_agg(g.i::text || ':' || random()::text, '|') + FROM generate_series(1, 100) g(i))); +end$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nbegin\n execute format($cmd$\n CREATE TEMP TABLE temptest (col text CHECK (col < %L)) ON ..." +== 050 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 051 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 052 +-- truncate_limit: 100 +SELECT * FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest" +== 053 +-- truncate_limit: 100 +-- ON COMMIT is only allowed for TEMP + +CREATE TABLE temptest(col int) ON COMMIT DELETE ROWS +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE temptest (col int) ON COMMIT DELETE ROWS" +== 054 +-- truncate_limit: 100 +CREATE TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1 +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1" +== 055 +-- truncate_limit: 100 +-- Test foreign keys +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 056 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest1(col int PRIMARY KEY) +-- +TABLE: name="temptest1" schema="" table="temptest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest1 (col int PRIMARY KEY)" +== 057 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest2(col int REFERENCES temptest1) + ON COMMIT DELETE ROWS +-- +TABLE: name="temptest2" schema="" table="temptest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest2 (col int REFERENCES temptest1) ON COMMIT DELETE ROWS" +== 058 +-- truncate_limit: 100 +INSERT INTO temptest1 VALUES (1) +-- +TABLE: name="temptest1" schema="" table="temptest1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest1 VALUES (1)" +== 059 +-- truncate_limit: 100 +INSERT INTO temptest2 VALUES (1) +-- +TABLE: name="temptest2" schema="" table="temptest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temptest2 VALUES (1)" +== 060 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 061 +-- truncate_limit: 100 +SELECT * FROM temptest1 +-- +TABLE: name="temptest1" schema="" table="temptest1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest1" +== 062 +-- truncate_limit: 100 +SELECT * FROM temptest2 +-- +TABLE: name="temptest2" schema="" table="temptest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temptest2" +== 063 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 064 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest3(col int PRIMARY KEY) ON COMMIT DELETE ROWS +-- +TABLE: name="temptest3" schema="" table="temptest3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest3 (col int PRIMARY KEY) ON COMMIT DELETE ROWS" +== 065 +-- truncate_limit: 100 +CREATE TEMP TABLE temptest4(col int REFERENCES temptest3) +-- +TABLE: name="temptest4" schema="" table="temptest4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest4 (col int REFERENCES temptest3)" +== 066 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 067 +-- truncate_limit: 100 +-- Test manipulation of temp schema's placement in search path + +create table public.whereami (f1 text) +-- +TABLE: name="public.whereami" schema="public" table="whereami" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE public.whereami (f1 text)" +== 068 +-- truncate_limit: 100 +insert into public.whereami values ('public') +-- +TABLE: name="public.whereami" schema="public" table="whereami" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO public.whereami VALUES ('public')" +== 069 +-- truncate_limit: 100 +create temp table whereami (f1 text) +-- +TABLE: name="whereami" schema="" table="whereami" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE whereami (f1 text)" +== 070 +-- truncate_limit: 100 +insert into whereami values ('temp') +-- +TABLE: name="whereami" schema="" table="whereami" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO whereami VALUES ('temp')" +== 071 +-- truncate_limit: 100 +create function public.whoami() returns text + as $$select 'public'::text$$ language sql +-- +FUNCTION: name="public.whoami" function="whoami" schema="public" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION public.whoami() RETURNS text AS $$select 'public'::text$$ LANGUAGE sql" +== 072 +-- truncate_limit: 100 +create function pg_temp.whoami() returns text + as $$select 'temp'::text$$ language sql +-- +FUNCTION: name="pg_temp.whoami" function="whoami" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pg_temp.whoami() RETURNS text AS $$select 'temp'::text$$ LANGUAGE sql" +== 073 +-- truncate_limit: 100 +-- default should have pg_temp implicitly first, but only for tables +select * from whereami +-- +TABLE: name="whereami" schema="" table="whereami" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM whereami" +== 074 +-- truncate_limit: 100 +select whoami() +-- +FUNCTION: name="whoami" function="whoami" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT whoami()" +== 075 +-- truncate_limit: 100 +-- can list temp first explicitly, but it still doesn't affect functions +set search_path = pg_temp, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO pg_temp, public" +== 076 +-- truncate_limit: 100 +select * from whereami +-- +TABLE: name="whereami" schema="" table="whereami" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM whereami" +== 077 +-- truncate_limit: 100 +select whoami() +-- +FUNCTION: name="whoami" function="whoami" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT whoami()" +== 078 +-- truncate_limit: 100 +-- or put it last for security +set search_path = public, pg_temp +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO public, pg_temp" +== 079 +-- truncate_limit: 100 +select * from whereami +-- +TABLE: name="whereami" schema="" table="whereami" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM whereami" +== 080 +-- truncate_limit: 100 +select whoami() +-- +FUNCTION: name="whoami" function="whoami" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT whoami()" +== 081 +-- truncate_limit: 100 +-- you can invoke a temp function explicitly, though +select pg_temp.whoami() +-- +FUNCTION: name="pg_temp.whoami" function="whoami" schema="pg_temp" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_temp.whoami()" +== 082 +-- truncate_limit: 100 +drop table public.whereami +-- +TABLE: name="public.whereami" schema="public" table="whereami" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE public.whereami" +== 083 +-- truncate_limit: 100 +-- types in temp schema +set search_path = pg_temp, public +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO pg_temp, public" +== 084 +-- truncate_limit: 100 +create domain pg_temp.nonempty as text check (value <> '') +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN pg_temp.nonempty AS text CHECK (value <> '')" +== 085 +-- truncate_limit: 100 +-- function-syntax invocation of types matches rules for functions +select nonempty('') +-- +FUNCTION: name="nonempty" function="nonempty" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nonempty('')" +== 086 +-- truncate_limit: 100 +select pg_temp.nonempty('') +-- +FUNCTION: name="pg_temp.nonempty" function="nonempty" schema="pg_temp" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_temp.nonempty('')" +== 087 +-- truncate_limit: 100 +-- other syntax matches rules for tables +select ''::nonempty +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::nonempty" +== 088 +-- truncate_limit: 100 +reset search_path +-- +STMT: VariableSetStmt +TRUNCATED: "RESET search_path" +== 089 +-- truncate_limit: 100 +-- For partitioned temp tables, ON COMMIT actions ignore storage-less +-- partitioned tables. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 090 +-- truncate_limit: 100 +create temp table temp_parted_oncommit (a int) + partition by list (a) on commit delete rows +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit (a int) PARTITION BY LIST (a) ON COMMIT DELETE ROWS" +== 091 +-- truncate_limit: 100 +create temp table temp_parted_oncommit_1 + partition of temp_parted_oncommit + for values in (1) on commit delete rows +-- +TABLE: name="temp_parted_oncommit_1" schema="" table="temp_parted_oncommit_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit_1 PARTITION OF temp_parted_oncommit FOR VALUES IN (1)..." +== 092 +-- truncate_limit: 100 +insert into temp_parted_oncommit values (1) +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temp_parted_oncommit VALUES (1)" +== 093 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 094 +-- truncate_limit: 100 +-- partitions are emptied by the previous commit +select * from temp_parted_oncommit +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temp_parted_oncommit" +== 095 +-- truncate_limit: 100 +drop table temp_parted_oncommit +-- +TABLE: name="temp_parted_oncommit" schema="" table="temp_parted_oncommit" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_parted_oncommit" +== 096 +-- truncate_limit: 100 +-- Check dependencies between ON COMMIT actions with a partitioned +-- table and its partitions. Using ON COMMIT DROP on a parent removes +-- the whole set. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 097 +-- truncate_limit: 100 +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit drop +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit_test (a int) PARTITION BY LIST (a) ON COMMIT DROP" +== 098 +-- truncate_limit: 100 +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit delete rows +-- +TABLE: name="temp_parted_oncommit_test1" schema="" table="temp_parted_oncommit_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit_test1 PARTITION OF temp_parted_oncommit_test FOR VALU..." +== 099 +-- truncate_limit: 100 +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop +-- +TABLE: name="temp_parted_oncommit_test2" schema="" table="temp_parted_oncommit_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit_test2 PARTITION OF temp_parted_oncommit_test FOR VALU..." +== 100 +-- truncate_limit: 100 +insert into temp_parted_oncommit_test values (1), (2) +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temp_parted_oncommit_test VALUES (1), (2)" +== 101 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 102 +-- truncate_limit: 100 +-- no relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ~ '^temp_parted_oncommit_test'" +== 103 +-- truncate_limit: 100 +-- Using ON COMMIT DELETE on a partitioned table does not remove +-- all rows if partitions preserve their data. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 104 +-- truncate_limit: 100 +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit delete rows +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit_test (a int) PARTITION BY LIST (a) ON COMMIT DELETE ROWS" +== 105 +-- truncate_limit: 100 +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit preserve rows +-- +TABLE: name="temp_parted_oncommit_test1" schema="" table="temp_parted_oncommit_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit_test1 PARTITION OF temp_parted_oncommit_test FOR VALU..." +== 106 +-- truncate_limit: 100 +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop +-- +TABLE: name="temp_parted_oncommit_test2" schema="" table="temp_parted_oncommit_test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_parted_oncommit_test2 PARTITION OF temp_parted_oncommit_test FOR VALU..." +== 107 +-- truncate_limit: 100 +insert into temp_parted_oncommit_test values (1), (2) +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temp_parted_oncommit_test VALUES (1), (2)" +== 108 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 109 +-- truncate_limit: 100 +-- Data from the remaining partition is still here as its rows are +-- preserved. +select * from temp_parted_oncommit_test +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temp_parted_oncommit_test" +== 110 +-- truncate_limit: 100 +-- two relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test' + order by relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ~ '^temp_parted_oncommit_test' ORDER BY relname" +== 111 +-- truncate_limit: 100 +drop table temp_parted_oncommit_test +-- +TABLE: name="temp_parted_oncommit_test" schema="" table="temp_parted_oncommit_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_parted_oncommit_test" +== 112 +-- truncate_limit: 100 +-- Check dependencies between ON COMMIT actions with inheritance trees. +-- Using ON COMMIT DROP on a parent removes the whole set. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 113 +-- truncate_limit: 100 +create temp table temp_inh_oncommit_test (a int) on commit drop +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_inh_oncommit_test (a int) ON COMMIT DROP" +== 114 +-- truncate_limit: 100 +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit delete rows +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_inh_oncommit_test1 () INHERITS (temp_inh_oncommit_test) ON COMMIT DEL..." +== 115 +-- truncate_limit: 100 +insert into temp_inh_oncommit_test1 values (1) +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temp_inh_oncommit_test1 VALUES (1)" +== 116 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 117 +-- truncate_limit: 100 +-- no relations remain in this case +select relname from pg_class where relname ~ '^temp_inh_oncommit_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ~ '^temp_inh_oncommit_test'" +== 118 +-- truncate_limit: 100 +-- Data on the parent is removed, and the child goes away. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 119 +-- truncate_limit: 100 +create temp table temp_inh_oncommit_test (a int) on commit delete rows +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_inh_oncommit_test (a int) ON COMMIT DELETE ROWS" +== 120 +-- truncate_limit: 100 +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit drop +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temp_inh_oncommit_test1 () INHERITS (temp_inh_oncommit_test) ON COMMIT DROP" +== 121 +-- truncate_limit: 100 +insert into temp_inh_oncommit_test1 values (1) +-- +TABLE: name="temp_inh_oncommit_test1" schema="" table="temp_inh_oncommit_test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temp_inh_oncommit_test1 VALUES (1)" +== 122 +-- truncate_limit: 100 +insert into temp_inh_oncommit_test values (1) +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO temp_inh_oncommit_test VALUES (1)" +== 123 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 124 +-- truncate_limit: 100 +select * from temp_inh_oncommit_test +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM temp_inh_oncommit_test" +== 125 +-- truncate_limit: 100 +-- one relation remains +select relname from pg_class where relname ~ '^temp_inh_oncommit_test' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relname FROM pg_class WHERE relname ~ '^temp_inh_oncommit_test'" +== 126 +-- truncate_limit: 100 +drop table temp_inh_oncommit_test +-- +TABLE: name="temp_inh_oncommit_test" schema="" table="temp_inh_oncommit_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE temp_inh_oncommit_test" +== 127 +-- truncate_limit: 100 +-- Tests with two-phase commit +-- Transactions creating objects in a temporary namespace cannot be used +-- with two-phase commit. + +-- These cases generate errors about temporary namespace. +-- Function creation +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 128 +-- truncate_limit: 100 +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql +-- +FUNCTION: name="pg_temp.twophase_func" function="twophase_func" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pg_temp.twophase_func() RETURNS void AS $$ select '2pc_func'::text $$ LANGUAGE sql" +== 129 +-- truncate_limit: 100 +prepare transaction 'twophase_func' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_func'" +== 130 +-- truncate_limit: 100 +-- Function drop +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql +-- +FUNCTION: name="pg_temp.twophase_func" function="twophase_func" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pg_temp.twophase_func() RETURNS void AS $$ select '2pc_func'::text $$ LANGUAGE sql" +== 131 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 132 +-- truncate_limit: 100 +drop function pg_temp.twophase_func() +-- +FUNCTION: name="pg_temp.twophase_func" function="twophase_func" schema="pg_temp" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION pg_temp.twophase_func()" +== 133 +-- truncate_limit: 100 +prepare transaction 'twophase_func' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_func'" +== 134 +-- truncate_limit: 100 +-- Operator creation +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 135 +-- truncate_limit: 100 +create operator pg_temp.@@ (leftarg = int4, rightarg = int4, procedure = int4mi) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR pg_temp.@@ (leftarg = int4, rightarg = int4, procedure = int4mi)" +== 136 +-- truncate_limit: 100 +prepare transaction 'twophase_operator' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_operator'" +== 137 +-- truncate_limit: 100 +-- These generate errors about temporary tables. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 138 +-- truncate_limit: 100 +create type pg_temp.twophase_type as (a int) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE pg_temp.twophase_type AS (a int)" +== 139 +-- truncate_limit: 100 +prepare transaction 'twophase_type' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_type'" +== 140 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 141 +-- truncate_limit: 100 +create view pg_temp.twophase_view as select 1 +-- +TABLE: name="pg_temp.twophase_view" schema="pg_temp" table="twophase_view" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW pg_temp.twophase_view AS SELECT 1" +== 142 +-- truncate_limit: 100 +prepare transaction 'twophase_view' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_view'" +== 143 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 144 +-- truncate_limit: 100 +create sequence pg_temp.twophase_seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE pg_temp.twophase_seq" +== 145 +-- truncate_limit: 100 +prepare transaction 'twophase_sequence' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_sequence'" +== 146 +-- truncate_limit: 100 +-- Temporary tables cannot be used with two-phase commit. +create temp table twophase_tab (a int) +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE twophase_tab (a int)" +== 147 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 148 +-- truncate_limit: 100 +select a from twophase_tab +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a FROM twophase_tab" +== 149 +-- truncate_limit: 100 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_tab'" +== 150 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 151 +-- truncate_limit: 100 +insert into twophase_tab values (1) +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO twophase_tab VALUES (1)" +== 152 +-- truncate_limit: 100 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_tab'" +== 153 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 154 +-- truncate_limit: 100 +lock twophase_tab in access exclusive mode +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DDL +STMT: LockStmt +TRUNCATED: "LOCK TABLE twophase_tab" +== 155 +-- truncate_limit: 100 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_tab'" +== 156 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 157 +-- truncate_limit: 100 +drop table twophase_tab +-- +TABLE: name="twophase_tab" schema="" table="twophase_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE twophase_tab" +== 158 +-- truncate_limit: 100 +prepare transaction 'twophase_tab' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_tab'" +== 159 +-- truncate_limit: 100 +-- Corner case: current_schema may create a temporary schema if namespace +-- creation is pending, so check after that. First reset the connection +-- to remove the temporary namespace. +SET search_path TO 'pg_temp' +-- +STMT: VariableSetStmt +TRUNCATED: "SET search_path TO pg_temp" +== 160 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 161 +-- truncate_limit: 100 +SELECT current_schema() ~ 'pg_temp' AS is_temp_schema +-- +FUNCTION: name="current_schema" function="current_schema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT \"current_schema\"() ~ 'pg_temp' AS is_temp_schema" +== 162 +-- truncate_limit: 100 +PREPARE TRANSACTION 'twophase_search' +-- +STMT: TransactionStmt +TRUNCATED: "PREPARE TRANSACTION 'twophase_search'" diff --git a/parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json b/parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json new file mode 100644 index 0000000..abfc1a2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json @@ -0,0 +1,73 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/test_setup.test b/parser/testdata/summary_truncate/postgres_regress/test_setup.test new file mode 100644 index 0000000..656164e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/test_setup.test @@ -0,0 +1,669 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TEST_SETUP --- prepare environment expected by regression test scripts +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +|-- +-- synchronous_commit=off delays when hint bits may be set. Some plans change +-- depending on the number of all-visible pages, which in turn can be +-- influenced by the delayed hint bits. Force synchronous_commit=on to avoid +-- that source of variability. +|-- +SET synchronous_commit = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET synchronous_commit TO ON" +== 002 +-- truncate_limit: 100 +|-- +-- Postgres formerly made the public schema read/write by default, +-- and most of the core regression tests still expect that. +|-- +GRANT ALL ON SCHEMA public TO public +-- +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON SCHEMA public TO public" +== 003 +-- truncate_limit: 100 +-- Create a tablespace we can use in tests. +SET allow_in_place_tablespaces = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET allow_in_place_tablespaces TO TRUE" +== 004 +-- truncate_limit: 100 +CREATE TABLESPACE regress_tblspace LOCATION '' +-- +STMT: CreateTableSpaceStmt +TRUNCATED: "CREATE TABLESPACE regress_tblspace LOCATION ''" +== 005 +-- truncate_limit: 100 +|-- +-- These tables have traditionally been referenced by many tests, +-- so create and populate them. Insert only non-error values here. +-- (Some subsequent tests try to insert erroneous values. That's okay +-- because the table won't actually change. Do not change the contents +-- of these tables in later tests, as it may affect other tests.) +|-- + +CREATE TABLE CHAR_TBL(f1 char(4)) +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE char_tbl (f1 char(4))" +== 006 +-- truncate_limit: 100 +INSERT INTO CHAR_TBL (f1) VALUES + ('a'), + ('ab'), + ('abcd'), + ('abcd ') +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO char_tbl (f1) VALUES ('a'), ('ab'), ('abcd'), ('abcd ')" +== 007 +-- truncate_limit: 100 +VACUUM CHAR_TBL +-- +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM char_tbl" +== 008 +-- truncate_limit: 100 +CREATE TABLE FLOAT8_TBL(f1 float8) +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE float8_tbl (f1 float8)" +== 009 +-- truncate_limit: 100 +INSERT INTO FLOAT8_TBL(f1) VALUES + ('0.0'), + ('-34.84'), + ('-1004.30'), + ('-1.2345678901234e+200'), + ('-1.2345678901234e-200') +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO float8_tbl (f1) VALUES (...)" +== 010 +-- truncate_limit: 100 +VACUUM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM float8_tbl" +== 011 +-- truncate_limit: 100 +CREATE TABLE INT2_TBL(f1 int2) +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE int2_tbl (f1 int2)" +== 012 +-- truncate_limit: 100 +INSERT INTO INT2_TBL(f1) VALUES + ('0 '), + (' 1234 '), + (' -1234'), + ('32767'), -- largest and smallest values + ('-32767') +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int2_tbl (f1) VALUES ('0 '), (' 1234 '), (' -1234'), ('32767'), ('-32767')" +== 013 +-- truncate_limit: 100 +VACUUM INT2_TBL +-- +TABLE: name="int2_tbl" schema="" table="int2_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM int2_tbl" +== 014 +-- truncate_limit: 100 +CREATE TABLE INT4_TBL(f1 int4) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE int4_tbl (f1 int4)" +== 015 +-- truncate_limit: 100 +INSERT INTO INT4_TBL(f1) VALUES + (' 0 '), + ('123456 '), + (' -123456'), + ('2147483647'), -- largest and smallest values + ('-2147483647') +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int4_tbl (f1) VALUES (...)" +== 016 +-- truncate_limit: 100 +VACUUM INT4_TBL +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM int4_tbl" +== 017 +-- truncate_limit: 100 +CREATE TABLE INT8_TBL(q1 int8, q2 int8) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE int8_tbl (q1 int8, q2 int8)" +== 018 +-- truncate_limit: 100 +INSERT INTO INT8_TBL VALUES + (' 123 ',' 456'), + ('123 ','4567890123456789'), + ('4567890123456789','123'), + (+4567890123456789,'4567890123456789'), + ('+4567890123456789','-4567890123456789') +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO int8_tbl VALUES (...)" +== 019 +-- truncate_limit: 100 +VACUUM INT8_TBL +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM int8_tbl" +== 020 +-- truncate_limit: 100 +CREATE TABLE POINT_TBL(f1 point) +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE point_tbl (f1 point)" +== 021 +-- truncate_limit: 100 +INSERT INTO POINT_TBL(f1) VALUES + ('(0.0,0.0)'), + ('(-10.0,0.0)'), + ('(-3.0,4.0)'), + ('(5.1, 34.5)'), + ('(-5.0,-12.0)'), + ('(1e-300,-1e-300)'), -- To underflow + ('(1e+300,Inf)'), -- To overflow + ('(Inf,1e+300)'), -- Transposed + (' ( Nan , NaN ) '), + ('10.0,10.0') +-- +TABLE: name="point_tbl" schema="" table="point_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO point_tbl (f1) VALUES (...)" +== 022 +-- truncate_limit: 100 +-- We intentionally don't vacuum point_tbl here; geometry depends on that + +CREATE TABLE TEXT_TBL (f1 text) +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE text_tbl (f1 text)" +== 023 +-- truncate_limit: 100 +INSERT INTO TEXT_TBL VALUES + ('doh!'), + ('hi de ho neighbor') +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO text_tbl VALUES ('doh!'), ('hi de ho neighbor')" +== 024 +-- truncate_limit: 100 +VACUUM TEXT_TBL +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM text_tbl" +== 025 +-- truncate_limit: 100 +CREATE TABLE VARCHAR_TBL(f1 varchar(4)) +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE varchar_tbl (f1 varchar(4))" +== 026 +-- truncate_limit: 100 +INSERT INTO VARCHAR_TBL (f1) VALUES + ('a'), + ('ab'), + ('abcd'), + ('abcd ') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('a'), ('ab'), ('abcd'), ('abcd ')" +== 027 +-- truncate_limit: 100 +VACUUM VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM varchar_tbl" +== 028 +-- truncate_limit: 100 +CREATE TABLE onek ( + unique1 int4, + unique2 int4, + two int4, + four int4, + ten int4, + twenty int4, + hundred int4, + thousand int4, + twothousand int4, + fivethous int4, + tenthous int4, + odd int4, + even int4, + stringu1 name, + stringu2 name, + string4 name +) +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE onek (unique1 int4, unique2 int4, two int4, four int4, ten int4, twenty int4, hundre..." +== 029 +-- truncate_limit: 100 +COPY onek FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 030 +-- truncate_limit: 100 +VACUUM ANALYZE onek +-- +TABLE: name="onek" schema="" table="onek" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) onek" +== 031 +-- truncate_limit: 100 +CREATE TABLE onek2 AS SELECT * FROM onek +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +TABLE: name="onek" schema="" table="onek" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE onek2 AS SELECT * FROM onek" +== 032 +-- truncate_limit: 100 +VACUUM ANALYZE onek2 +-- +TABLE: name="onek2" schema="" table="onek2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) onek2" +== 033 +-- truncate_limit: 100 +CREATE TABLE tenk1 ( + unique1 int4, + unique2 int4, + two int4, + four int4, + ten int4, + twenty int4, + hundred int4, + thousand int4, + twothousand int4, + fivethous int4, + tenthous int4, + odd int4, + even int4, + stringu1 name, + stringu2 name, + string4 name +) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tenk1 (unique1 int4, unique2 int4, two int4, four int4, ten int4, twenty int4, hundr..." +== 034 +-- truncate_limit: 100 +COPY tenk1 FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 17 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 035 +-- truncate_limit: 100 +VACUUM ANALYZE tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) tenk1" +== 036 +-- truncate_limit: 100 +CREATE TABLE tenk2 AS SELECT * FROM tenk1 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE tenk2 AS SELECT * FROM tenk1" +== 037 +-- truncate_limit: 100 +VACUUM ANALYZE tenk2 +-- +TABLE: name="tenk2" schema="" table="tenk2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) tenk2" +== 038 +-- truncate_limit: 100 +CREATE TABLE person ( + name text, + age int4, + location point +) +-- +TABLE: name="person" schema="" table="person" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE person (name text, age int4, location point)" +== 039 +-- truncate_limit: 100 +COPY person FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 18 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 040 +-- truncate_limit: 100 +VACUUM ANALYZE person +-- +TABLE: name="person" schema="" table="person" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) person" +== 041 +-- truncate_limit: 100 +CREATE TABLE emp ( + salary int4, + manager name +) INHERITS (person) +-- +TABLE: name="emp" schema="" table="emp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE emp (salary int4, manager name) INHERITS (person)" +== 042 +-- truncate_limit: 100 +COPY emp FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 15 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 043 +-- truncate_limit: 100 +VACUUM ANALYZE emp +-- +TABLE: name="emp" schema="" table="emp" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) emp" +== 044 +-- truncate_limit: 100 +CREATE TABLE student ( + gpa float8 +) INHERITS (person) +-- +TABLE: name="student" schema="" table="student" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE student (gpa float8) INHERITS (person)" +== 045 +-- truncate_limit: 100 +COPY student FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 046 +-- truncate_limit: 100 +VACUUM ANALYZE student +-- +TABLE: name="student" schema="" table="student" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) student" +== 047 +-- truncate_limit: 100 +CREATE TABLE stud_emp ( + percent int4 +) INHERITS (emp, student) +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stud_emp (percent int4) INHERITS (emp, student)" +== 048 +-- truncate_limit: 100 +COPY stud_emp FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 049 +-- truncate_limit: 100 +VACUUM ANALYZE stud_emp +-- +TABLE: name="stud_emp" schema="" table="stud_emp" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) stud_emp" +== 050 +-- truncate_limit: 100 +CREATE TABLE road ( + name text, + thepath path +) +-- +TABLE: name="road" schema="" table="road" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE road (name text, thepath path)" +== 051 +-- truncate_limit: 100 +COPY road FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 16 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 052 +-- truncate_limit: 100 +VACUUM ANALYZE road +-- +TABLE: name="road" schema="" table="road" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) road" +== 053 +-- truncate_limit: 100 +CREATE TABLE ihighway () INHERITS (road) +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ihighway () INHERITS (road)" +== 054 +-- truncate_limit: 100 +INSERT INTO ihighway + SELECT * + FROM ONLY road + WHERE name ~ 'I- .*' +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DML +TABLE: name="road" schema="" table="road" ctx=Select +FILTER: schema="" table="" column="name" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ihighway SELECT * FROM ONLY road WHERE name ~ 'I- .*'" +== 055 +-- truncate_limit: 100 +VACUUM ANALYZE ihighway +-- +TABLE: name="ihighway" schema="" table="ihighway" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) ihighway" +== 056 +-- truncate_limit: 100 +CREATE TABLE shighway ( + surface text +) INHERITS (road) +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE shighway (surface text) INHERITS (road)" +== 057 +-- truncate_limit: 100 +INSERT INTO shighway + SELECT *, 'asphalt' + FROM ONLY road + WHERE name ~ 'State Hwy.*' +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DML +TABLE: name="road" schema="" table="road" ctx=Select +FILTER: schema="" table="" column="name" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO shighway SELECT *, 'asphalt' FROM ONLY road WHERE name ~ 'State Hwy.*'" +== 058 +-- truncate_limit: 100 +VACUUM ANALYZE shighway +-- +TABLE: name="shighway" schema="" table="shighway" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) shighway" +== 059 +-- truncate_limit: 100 +|-- +-- We must have some enum type in the database for opr_sanity and type_sanity. +|-- + +create type stoplight as enum ('red', 'yellow', 'green') +-- +STMT: CreateEnumStmt +TRUNCATED: "CREATE TYPE stoplight AS ENUM ('red', 'yellow', 'green')" +== 060 +-- truncate_limit: 100 +|-- +-- Also create some non-built-in range types. +|-- + +create type float8range as range (subtype = float8, subtype_diff = float8mi) +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE float8range AS RANGE (subtype = float8, subtype_diff = float8mi)" +== 061 +-- truncate_limit: 100 +create type textrange as range (subtype = text, collation = "C") +-- +STMT: CreateRangeStmt +TRUNCATED: "CREATE TYPE textrange AS RANGE (subtype = text, \"collation\" = \"C\")" +== 062 +-- truncate_limit: 100 +|-- +-- Create some C functions that will be used by various tests. +|-- + +CREATE FUNCTION binary_coercible(oid, oid) + RETURNS bool + AS :'regresslib', 'binary_coercible' + LANGUAGE C STRICT STABLE PARALLEL SAFE +-- +ERROR: syntax error at or near ":" +CURSORPOS: 138 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 063 +-- truncate_limit: 100 +CREATE FUNCTION ttdummy () + RETURNS trigger + AS :'regresslib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 55 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 064 +-- truncate_limit: 100 +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different machines. The hash function for int4 simply returns +-- the sum of the values passed to it and the one for text returns the length +-- of the non-empty string value passed to it or 0. + +create function part_hashint4_noop(value int4, seed int8) + returns int8 as $$ + select value + seed; + $$ language sql strict immutable parallel safe +-- +FUNCTION: name="part_hashint4_noop" function="part_hashint4_noop" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION part_hashint4_noop(value int4, seed int8) RETURNS int8 AS $$\n select value + s..." +== 065 +-- truncate_limit: 100 +create operator class part_test_int4_ops for type int4 using hash as + operator 1 =, + function 2 part_hashint4_noop(int4, int8) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS part_test_int4_ops FOR TYPE int4 USING hash AS OPERATOR 1 =, FUNCTION 2 par..." +== 066 +-- truncate_limit: 100 +create function part_hashtext_length(value text, seed int8) + returns int8 as $$ + select length(coalesce(value, ''))::int8 + $$ language sql strict immutable parallel safe +-- +FUNCTION: name="part_hashtext_length" function="part_hashtext_length" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION part_hashtext_length(value text, seed int8) RETURNS int8 AS $$\n select length(..." +== 067 +-- truncate_limit: 100 +create operator class part_test_text_ops for type text using hash as + operator 1 =, + function 2 part_hashtext_length(text, int8) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS part_test_text_ops FOR TYPE text USING hash AS OPERATOR 1 =, FUNCTION 2 par..." +== 068 +-- truncate_limit: 100 +|-- +-- These functions are used in tests that used to use md5(), which we now +-- mostly avoid so that the tests will pass in FIPS mode. +|-- + +create function fipshash(bytea) + returns text + strict immutable parallel safe leakproof + return substr(encode(sha256($1), 'hex'), 1, 32) +-- +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fipshash(bytea) RETURNS text RETURNS NULL ON NULL INPUT IMMUTABLE PARALLEL safe L..." +== 069 +-- truncate_limit: 100 +create function fipshash(text) + returns text + strict immutable parallel safe leakproof + return substr(encode(sha256($1::bytea), 'hex'), 1, 32) +-- +FUNCTION: name="fipshash" function="fipshash" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION fipshash(text) RETURNS text RETURNS NULL ON NULL INPUT IMMUTABLE PARALLEL safe LE..." diff --git a/parser/testdata/summary_truncate/postgres_regress/text.metadata.json b/parser/testdata/summary_truncate/postgres_regress/text.metadata.json new file mode 100644 index 0000000..2ff9db8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/text.metadata.json @@ -0,0 +1,77 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/text.test b/parser/testdata/summary_truncate/postgres_regress/text.test new file mode 100644 index 0000000..b4975d7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/text.test @@ -0,0 +1,547 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TEXT +|-- + +SELECT text 'this is a text string' = text 'this is a text string' AS true +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'this is a text string'::text = 'this is a text string'::text AS \"true\"" +== 002 +-- truncate_limit: 100 +SELECT text 'this is a text string' = text 'this is a text strin' AS false +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'this is a text string'::text = 'this is a text strin'::text AS \"false\"" +== 003 +-- truncate_limit: 100 +-- text_tbl was already created and filled in test_setup.sql. +SELECT * FROM TEXT_TBL +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM text_tbl" +== 004 +-- truncate_limit: 100 +-- As of 8.3 we have removed most implicit casts to text, so that for example +-- this no longer works: + +select length(42) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(42)" +== 005 +-- truncate_limit: 100 +-- But as a special exception for usability's sake, we still allow implicit +-- casting to text in concatenations, so long as the other input is text or +-- an unknown literal. So these work: + +select 'four: '::text || 2+2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'four: '::text || (2 + 2)" +== 006 +-- truncate_limit: 100 +select 'four: ' || 2+2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'four: ' || (2 + 2)" +== 007 +-- truncate_limit: 100 +-- but not this: + +select 3 || 4.0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3 || 4.0" +== 008 +-- truncate_limit: 100 +/* + * various string functions + */ +select concat('one') +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat('one')" +== 009 +-- truncate_limit: 100 +select concat(1,2,3,'hello',true, false, to_date('20100309','YYYYMMDD')) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat(1, 2, 3, 'hello', true, false, to_date('20100309', 'YYYYMMDD'))" +== 010 +-- truncate_limit: 100 +select concat_ws('#','one') +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws('#', 'one')" +== 011 +-- truncate_limit: 100 +select concat_ws('#',1,2,3,'hello',true, false, to_date('20100309','YYYYMMDD')) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +FUNCTION: name="to_date" function="to_date" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws('#', 1, 2, 3, 'hello', true, false, to_date('20100309', 'YYYYMMDD'))" +== 012 +-- truncate_limit: 100 +select concat_ws(',',10,20,null,30) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws(',', 10, 20, NULL, 30)" +== 013 +-- truncate_limit: 100 +select concat_ws('',10,20,null,30) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws('', 10, 20, NULL, 30)" +== 014 +-- truncate_limit: 100 +select concat_ws(NULL,10,20,null,30) is null +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws(NULL, 10, 20, NULL, 30) IS NULL" +== 015 +-- truncate_limit: 100 +select reverse('abcde') +-- +FUNCTION: name="reverse" function="reverse" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT reverse('abcde')" +== 016 +-- truncate_limit: 100 +select i, left('ahoj', i), right('ahoj', i) from generate_series(-5, 5) t(i) order by i +-- +FUNCTION: name="left" function="left" schema="" ctx=Call +FUNCTION: name="right" function="right" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT i, \"left\"('ahoj', i), \"right\"('ahoj', i) FROM generate_series(-5, 5) t(i) ORDER BY i" +== 017 +-- truncate_limit: 100 +select quote_literal('') +-- +FUNCTION: name="quote_literal" function="quote_literal" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT quote_literal('')" +== 018 +-- truncate_limit: 100 +select quote_literal('abc''') +-- +FUNCTION: name="quote_literal" function="quote_literal" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT quote_literal('abc''')" +== 019 +-- truncate_limit: 100 +select quote_literal(e'\\') +-- +FUNCTION: name="quote_literal" function="quote_literal" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT quote_literal(E'\\\\')" +== 020 +-- truncate_limit: 100 +-- check variadic labeled argument +select concat(variadic array[1,2,3]) +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat(VARIADIC ARRAY[1, 2, 3])" +== 021 +-- truncate_limit: 100 +select concat_ws(',', variadic array[1,2,3]) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws(',', VARIADIC ARRAY[1, 2, 3])" +== 022 +-- truncate_limit: 100 +select concat_ws(',', variadic NULL::int[]) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws(',', VARIADIC NULL::int[])" +== 023 +-- truncate_limit: 100 +select concat(variadic NULL::int[]) is NULL +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat(VARIADIC NULL::int[]) IS NULL" +== 024 +-- truncate_limit: 100 +select concat(variadic '{}'::int[]) = '' +-- +FUNCTION: name="concat" function="concat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat(VARIADIC '{}'::int[]) = ''" +== 025 +-- truncate_limit: 100 +--should fail +select concat_ws(',', variadic 10) +-- +FUNCTION: name="concat_ws" function="concat_ws" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT concat_ws(',', VARIADIC 10)" +== 026 +-- truncate_limit: 100 +/* + * format + */ +select format(NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format(NULL)" +== 027 +-- truncate_limit: 100 +select format('Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello')" +== 028 +-- truncate_limit: 100 +select format('Hello %s', 'World') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %s', 'World')" +== 029 +-- truncate_limit: 100 +select format('Hello %%') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %%')" +== 030 +-- truncate_limit: 100 +select format('Hello %%%%') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %%%%')" +== 031 +-- truncate_limit: 100 +-- should fail +select format('Hello %s %s', 'World') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %s %s', 'World')" +== 032 +-- truncate_limit: 100 +select format('Hello %s') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %s')" +== 033 +-- truncate_limit: 100 +select format('Hello %x', 20) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %x', 20)" +== 034 +-- truncate_limit: 100 +-- check literal and sql identifiers +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, 'Hello')" +== 035 +-- truncate_limit: 100 +select format('%s%s%s','Hello', NULL,'World') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%s%s%s', 'Hello', NULL, 'World')" +== 036 +-- truncate_limit: 100 +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, NULL)" +== 037 +-- truncate_limit: 100 +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', NULL, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('INSERT INTO %I VALUES(%L,%L)', 'mytab', NULL, 'Hello')" +== 038 +-- truncate_limit: 100 +-- should fail, sql identifier cannot be NULL +select format('INSERT INTO %I VALUES(%L,%L)', NULL, 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('INSERT INTO %I VALUES(%L,%L)', NULL, 10, 'Hello')" +== 039 +-- truncate_limit: 100 +-- check positional placeholders +select format('%1$s %3$s', 1, 2, 3) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%1$s %3$s', 1, 2, 3)" +== 040 +-- truncate_limit: 100 +select format('%1$s %12$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%1$s %12$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)" +== 041 +-- truncate_limit: 100 +-- should fail +select format('%1$s %4$s', 1, 2, 3) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%1$s %4$s', 1, 2, 3)" +== 042 +-- truncate_limit: 100 +select format('%1$s %13$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%1$s %13$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)" +== 043 +-- truncate_limit: 100 +select format('%0$s', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%0$s', 'Hello')" +== 044 +-- truncate_limit: 100 +select format('%*0$s', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%*0$s', 'Hello')" +== 045 +-- truncate_limit: 100 +select format('%1$', 1) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%1$', 1)" +== 046 +-- truncate_limit: 100 +select format('%1$1', 1) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%1$1', 1)" +== 047 +-- truncate_limit: 100 +-- check mix of positional and ordered placeholders +select format('Hello %s %1$s %s', 'World', 'Hello again') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %s %1$s %s', 'World', 'Hello again')" +== 048 +-- truncate_limit: 100 +select format('Hello %s %s, %2$s %2$s', 'World', 'Hello again') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello %s %s, %2$s %2$s', 'World', 'Hello again')" +== 049 +-- truncate_limit: 100 +-- check variadic labeled arguments +select format('%s, %s', variadic array['Hello','World']) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%s, %s', VARIADIC ARRAY['Hello', 'World'])" +== 050 +-- truncate_limit: 100 +select format('%s, %s', variadic array[1, 2]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%s, %s', VARIADIC ARRAY[1, 2])" +== 051 +-- truncate_limit: 100 +select format('%s, %s', variadic array[true, false]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%s, %s', VARIADIC ARRAY[true, false])" +== 052 +-- truncate_limit: 100 +select format('%s, %s', variadic array[true, false]::text[]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%s, %s', VARIADIC ARRAY[true, false]::text[])" +== 053 +-- truncate_limit: 100 +-- check variadic with positional placeholders +select format('%2$s, %1$s', variadic array['first', 'second']) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%2$s, %1$s', VARIADIC ARRAY['first', 'second'])" +== 054 +-- truncate_limit: 100 +select format('%2$s, %1$s', variadic array[1, 2]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('%2$s, %1$s', VARIADIC ARRAY[1, 2])" +== 055 +-- truncate_limit: 100 +-- variadic argument can be array type NULL, but should not be referenced +select format('Hello', variadic NULL::int[]) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('Hello', VARIADIC NULL::int[])" +== 056 +-- truncate_limit: 100 +-- variadic argument allows simulating more than FUNC_MAX_ARGS parameters +select format(string_agg('%s',','), variadic array_agg(i)) +from generate_series(1,200) g(i) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +FUNCTION: name="string_agg" function="string_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format(string_agg('%s', ','), VARIADIC array_agg(i)) FROM generate_series(1, 200) g(i)" +== 057 +-- truncate_limit: 100 +-- check field widths and left, right alignment +select format('>>%10s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%10s<<', 'Hello')" +== 058 +-- truncate_limit: 100 +select format('>>%10s<<', NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%10s<<', NULL)" +== 059 +-- truncate_limit: 100 +select format('>>%10s<<', '') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%10s<<', '')" +== 060 +-- truncate_limit: 100 +select format('>>%-10s<<', '') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%-10s<<', '')" +== 061 +-- truncate_limit: 100 +select format('>>%-10s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%-10s<<', 'Hello')" +== 062 +-- truncate_limit: 100 +select format('>>%-10s<<', NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%-10s<<', NULL)" +== 063 +-- truncate_limit: 100 +select format('>>%1$10s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%1$10s<<', 'Hello')" +== 064 +-- truncate_limit: 100 +select format('>>%1$-10I<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%1$-10I<<', 'Hello')" +== 065 +-- truncate_limit: 100 +select format('>>%2$*1$L<<', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%2$*1$L<<', 10, 'Hello')" +== 066 +-- truncate_limit: 100 +select format('>>%2$*1$L<<', 10, NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%2$*1$L<<', 10, NULL)" +== 067 +-- truncate_limit: 100 +select format('>>%2$*1$L<<', -10, NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%2$*1$L<<', -10, NULL)" +== 068 +-- truncate_limit: 100 +select format('>>%*s<<', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%*s<<', 10, 'Hello')" +== 069 +-- truncate_limit: 100 +select format('>>%*1$s<<', 10, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%*1$s<<', 10, 'Hello')" +== 070 +-- truncate_limit: 100 +select format('>>%-s<<', 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%-s<<', 'Hello')" +== 071 +-- truncate_limit: 100 +select format('>>%10L<<', NULL) +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%10L<<', NULL)" +== 072 +-- truncate_limit: 100 +select format('>>%2$*1$L<<', NULL, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%2$*1$L<<', NULL, 'Hello')" +== 073 +-- truncate_limit: 100 +select format('>>%2$*1$L<<', 0, 'Hello') +-- +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT format('>>%2$*1$L<<', 0, 'Hello')" diff --git a/parser/testdata/summary_truncate/postgres_regress/tid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tid.metadata.json new file mode 100644 index 0000000..66f0b1d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tid.metadata.json @@ -0,0 +1,45 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tid.test b/parser/testdata/summary_truncate/postgres_regress/tid.test new file mode 100644 index 0000000..359a8d8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tid.test @@ -0,0 +1,321 @@ +== 001 +-- truncate_limit: 100 +-- basic tests for the TID data type + +SELECT + '(0,0)'::tid as tid00, + '(0,1)'::tid as tid01, + '(-1,0)'::tid as tidm10, + '(4294967295,65535)'::tid as tidmax +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 002 +-- truncate_limit: 100 +SELECT '(4294967296,1)'::tid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(4294967296,1)'::tid" +== 003 +-- truncate_limit: 100 +-- error +SELECT '(1,65536)'::tid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1,65536)'::tid" +== 004 +-- truncate_limit: 100 +-- error + +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('(0)', 'tid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(0)', 'tid')" +== 005 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(0)', 'tid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(0)', 'tid')" +== 006 +-- truncate_limit: 100 +SELECT pg_input_is_valid('(0,-1)', 'tid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('(0,-1)', 'tid')" +== 007 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('(0,-1)', 'tid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('(0,-1)', 'tid')" +== 008 +-- truncate_limit: 100 +-- tests for functions related to TID handling + +CREATE TABLE tid_tab (a int) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tid_tab (a int)" +== 009 +-- truncate_limit: 100 +-- min() and max() for TIDs +INSERT INTO tid_tab VALUES (1), (2) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tid_tab VALUES (1), (2)" +== 010 +-- truncate_limit: 100 +SELECT min(ctid) FROM tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(ctid) FROM tid_tab" +== 011 +-- truncate_limit: 100 +SELECT max(ctid) FROM tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT max(ctid) FROM tid_tab" +== 012 +-- truncate_limit: 100 +TRUNCATE tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE tid_tab" +== 013 +-- truncate_limit: 100 +-- Tests for currtid2() with various relation kinds + +-- Materialized view +CREATE MATERIALIZED VIEW tid_matview AS SELECT a FROM tid_tab +-- +TABLE: name="tid_matview" schema="" table="tid_matview" ctx=DDL +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW tid_matview AS SELECT a FROM tid_tab" +== 014 +-- truncate_limit: 100 +SELECT currtid2('tid_matview'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_matview'::text, '(0,1)'::tid)" +== 015 +-- truncate_limit: 100 +-- fails +INSERT INTO tid_tab VALUES (1) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tid_tab VALUES (1)" +== 016 +-- truncate_limit: 100 +REFRESH MATERIALIZED VIEW tid_matview +-- +TABLE: name="tid_matview" schema="" table="tid_matview" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW tid_matview" +== 017 +-- truncate_limit: 100 +SELECT currtid2('tid_matview'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_matview'::text, '(0,1)'::tid)" +== 018 +-- truncate_limit: 100 +-- ok +DROP MATERIALIZED VIEW tid_matview +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW tid_matview" +== 019 +-- truncate_limit: 100 +TRUNCATE tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE tid_tab" +== 020 +-- truncate_limit: 100 +-- Sequence +CREATE SEQUENCE tid_seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE tid_seq" +== 021 +-- truncate_limit: 100 +SELECT currtid2('tid_seq'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_seq'::text, '(0,1)'::tid)" +== 022 +-- truncate_limit: 100 +-- ok +DROP SEQUENCE tid_seq +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE tid_seq" +== 023 +-- truncate_limit: 100 +-- Index, fails with incorrect relation type +CREATE INDEX tid_ind ON tid_tab(a) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tid_ind ON tid_tab USING btree (a)" +== 024 +-- truncate_limit: 100 +SELECT currtid2('tid_ind'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_ind'::text, '(0,1)'::tid)" +== 025 +-- truncate_limit: 100 +-- fails +DROP INDEX tid_ind +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX tid_ind" +== 026 +-- truncate_limit: 100 +-- Partitioned table, no storage +CREATE TABLE tid_part (a int) PARTITION BY RANGE (a) +-- +TABLE: name="tid_part" schema="" table="tid_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tid_part (a int) PARTITION BY RANGE (a)" +== 027 +-- truncate_limit: 100 +SELECT currtid2('tid_part'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_part'::text, '(0,1)'::tid)" +== 028 +-- truncate_limit: 100 +-- fails +DROP TABLE tid_part +-- +TABLE: name="tid_part" schema="" table="tid_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tid_part" +== 029 +-- truncate_limit: 100 +-- Views +-- ctid not defined in the view +CREATE VIEW tid_view_no_ctid AS SELECT a FROM tid_tab +-- +TABLE: name="tid_view_no_ctid" schema="" table="tid_view_no_ctid" ctx=DDL +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tid_view_no_ctid AS SELECT a FROM tid_tab" +== 030 +-- truncate_limit: 100 +SELECT currtid2('tid_view_no_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_view_no_ctid'::text, '(0,1)'::tid)" +== 031 +-- truncate_limit: 100 +-- fails +DROP VIEW tid_view_no_ctid +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW tid_view_no_ctid" +== 032 +-- truncate_limit: 100 +-- ctid fetched directly from the source table. +CREATE VIEW tid_view_with_ctid AS SELECT ctid, a FROM tid_tab +-- +TABLE: name="tid_view_with_ctid" schema="" table="tid_view_with_ctid" ctx=DDL +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tid_view_with_ctid AS SELECT ctid, a FROM tid_tab" +== 033 +-- truncate_limit: 100 +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid)" +== 034 +-- truncate_limit: 100 +-- fails +INSERT INTO tid_tab VALUES (1) +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tid_tab VALUES (1)" +== 035 +-- truncate_limit: 100 +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid)" +== 036 +-- truncate_limit: 100 +-- ok +DROP VIEW tid_view_with_ctid +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW tid_view_with_ctid" +== 037 +-- truncate_limit: 100 +TRUNCATE tid_tab +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE tid_tab" +== 038 +-- truncate_limit: 100 +-- ctid attribute with incorrect data type +CREATE VIEW tid_view_fake_ctid AS SELECT 1 AS ctid, 2 AS a +-- +TABLE: name="tid_view_fake_ctid" schema="" table="tid_view_fake_ctid" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW tid_view_fake_ctid AS SELECT 1 AS ctid, 2 AS a" +== 039 +-- truncate_limit: 100 +SELECT currtid2('tid_view_fake_ctid'::text, '(0,1)'::tid) +-- +FUNCTION: name="currtid2" function="currtid2" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT currtid2('tid_view_fake_ctid'::text, '(0,1)'::tid)" +== 040 +-- truncate_limit: 100 +-- fails +DROP VIEW tid_view_fake_ctid +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW tid_view_fake_ctid" +== 041 +-- truncate_limit: 100 +DROP TABLE tid_tab CASCADE +-- +TABLE: name="tid_tab" schema="" table="tid_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tid_tab CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json new file mode 100644 index 0000000..f069709 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json @@ -0,0 +1,49 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tidrangescan.test b/parser/testdata/summary_truncate/postgres_regress/tidrangescan.test new file mode 100644 index 0000000..ed4c449 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tidrangescan.test @@ -0,0 +1,402 @@ +== 001 +-- truncate_limit: 100 +-- tests for tidrangescans + +SET enable_seqscan TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 002 +-- truncate_limit: 100 +CREATE TABLE tidrangescan(id integer, data text) +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tidrangescan (id int, data text)" +== 003 +-- truncate_limit: 100 +-- empty table +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)'" +== 004 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)'" +== 005 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)'" +== 006 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)'" +== 007 +-- truncate_limit: 100 +-- insert enough tuples to fill at least two pages +INSERT INTO tidrangescan SELECT i,repeat('x', 100) FROM generate_series(1,200) AS s(i) +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tidrangescan SELECT i, repeat('x', 100) FROM generate_series(1, 200) s(i)" +== 008 +-- truncate_limit: 100 +-- remove all tuples after the 10th tuple on each page. Trying to ensure +-- we get the same layout with all CPU architectures and smaller than standard +-- page sizes. +DELETE FROM tidrangescan +WHERE substring(ctid::text FROM ',(\d+)\)')::integer > 10 OR substring(ctid::text FROM '\((\d+),')::integer > 2 +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DML +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.substring" function="substring" schema="pg_catalog" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tidrangescan WHERE ..." +== 009 +-- truncate_limit: 100 +VACUUM tidrangescan +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM tidrangescan" +== 010 +-- truncate_limit: 100 +-- range scans with upper bound +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'" +== 011 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'" +== 012 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)'" +== 013 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)'" +== 014 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)'" +== 015 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)'" +== 016 +-- truncate_limit: 100 +-- range scans with lower bound +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)'" +== 017 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)'" +== 018 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid" +== 019 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid" +== 020 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)'" +== 021 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)'" +== 022 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)'" +== 023 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)'" +== 024 +-- truncate_limit: 100 +-- range scans with both bounds +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid" +== 025 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid" +== 026 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)'" +== 027 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)'" +== 028 +-- truncate_limit: 100 +-- extreme offsets +SELECT ctid FROM tidrangescan WHERE ctid > '(0,65535)' AND ctid < '(1,0)' LIMIT 1 +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid > '(0,65535)' AND ctid < '(1,0)' LIMIT 1" +== 029 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' LIMIT 1 +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' LIMIT 1" +== 030 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid > '(4294967295,65535)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid > '(4294967295,65535)'" +== 031 +-- truncate_limit: 100 +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)'" +== 032 +-- truncate_limit: 100 +-- NULLs in the range cannot return tuples +SELECT ctid FROM tidrangescan WHERE ctid >= (SELECT NULL::tid) +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid FROM tidrangescan WHERE ctid >= (SELECT NULL::tid)" +== 033 +-- truncate_limit: 100 +-- rescans +EXPLAIN (COSTS OFF) +SELECT t.ctid,t2.c FROM tidrangescan t, +LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2 +WHERE t.ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +ALIAS: "t"="tidrangescan" +ALIAS: "t2"="tidrangescan" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t" column="ctid" +FILTER: schema="" table="t2" column="ctid" +FILTER: schema="" table="t" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t.ctid, t2.c FROM tidrangescan t, LATERAL (SELECT count(*) AS c FROM t..." +== 034 +-- truncate_limit: 100 +SELECT t.ctid,t2.c FROM tidrangescan t, +LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2 +WHERE t.ctid < '(1,0)' +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=Select +ALIAS: "t"="tidrangescan" +ALIAS: "t2"="tidrangescan" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t" column="ctid" +FILTER: schema="" table="t2" column="ctid" +FILTER: schema="" table="t" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tidrangescan t, LATERAL (SELECT ... FROM tidrangescan t2 WHERE ...) t2 WHERE ..." +== 035 +-- truncate_limit: 100 +-- cursors + +-- Ensure we get a TID Range scan without a Materialize node. +EXPLAIN (COSTS OFF) +DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'" +== 036 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 037 +-- truncate_limit: 100 +DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)' +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'" +== 038 +-- truncate_limit: 100 +FETCH NEXT c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 039 +-- truncate_limit: 100 +FETCH NEXT c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 040 +-- truncate_limit: 100 +FETCH PRIOR c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 041 +-- truncate_limit: 100 +FETCH FIRST c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FIRST c" +== 042 +-- truncate_limit: 100 +FETCH LAST c +-- +STMT: FetchStmt +TRUNCATED: "FETCH LAST c" +== 043 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 044 +-- truncate_limit: 100 +DROP TABLE tidrangescan +-- +TABLE: name="tidrangescan" schema="" table="tidrangescan" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tidrangescan" +== 045 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" diff --git a/parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json new file mode 100644 index 0000000..74725a7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json @@ -0,0 +1,53 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tidscan.test b/parser/testdata/summary_truncate/postgres_regress/tidscan.test new file mode 100644 index 0000000..e0ee55e --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tidscan.test @@ -0,0 +1,438 @@ +== 001 +-- truncate_limit: 100 +-- tests for tidscans + +CREATE TABLE tidscan(id integer) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tidscan (id int)" +== 002 +-- truncate_limit: 100 +-- only insert a few rows, we don't want to spill onto a second table page +INSERT INTO tidscan VALUES (1), (2), (3) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tidscan VALUES (1), (2), (3)" +== 003 +-- truncate_limit: 100 +-- show ctids +SELECT ctid, * FROM tidscan +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ctid, * FROM tidscan" +== 004 +-- truncate_limit: 100 +-- ctid equality - implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)' +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)'" +== 005 +-- truncate_limit: 100 +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)' +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)'" +== 006 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid" +== 007 +-- truncate_limit: 100 +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid" +== 008 +-- truncate_limit: 100 +-- OR'd clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid" +== 009 +-- truncate_limit: 100 +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid" +== 010 +-- truncate_limit: 100 +-- ctid = ScalarArrayOp - implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[])" +== 011 +-- truncate_limit: 100 +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[])" +== 012 +-- truncate_limit: 100 +-- ctid != ScalarArrayOp - can't be implemented as tidscan +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid <> ANY(ARRAY['(0,1)', '(0,2)']::tid[])" +== 013 +-- truncate_limit: 100 +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, * FROM tidscan WHERE ctid <> ANY(ARRAY['(0,1)', '(0,2)']::tid[])" +== 014 +-- truncate_limit: 100 +-- tid equality extracted from sub-AND clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="id" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR ..." +== 015 +-- truncate_limit: 100 +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1) +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="ctid" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ctid, * FROM tidscan WHERE ..." +== 016 +-- truncate_limit: 100 +-- nestloop-with-inner-tidscan joins on tid +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 017 +-- truncate_limit: 100 +-- otherwise hash join might win +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.ctid, t1.*, t2.ctid, t2.* FROM tidscan t1 JOIN tidscan t2 ON t1.cti..." +== 018 +-- truncate_limit: 100 +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1" +== 019 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.ctid, t1.*, t2.ctid, t2.* FROM tidscan t1 LEFT JOIN tidscan t2 ON t..." +== 020 +-- truncate_limit: 100 +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1 +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +ALIAS: "t1"="tidscan" +ALIAS: "t2"="tidscan" +FILTER: schema="" table="t1" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1" +== 021 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 022 +-- truncate_limit: 100 +-- exercise backward scan and rewind +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 023 +-- truncate_limit: 100 +DECLARE c CURSOR FOR +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]) +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[])" +== 024 +-- truncate_limit: 100 +FETCH ALL FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH ALL c" +== 025 +-- truncate_limit: 100 +FETCH BACKWARD 1 FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 026 +-- truncate_limit: 100 +FETCH FIRST FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FIRST c" +== 027 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 028 +-- truncate_limit: 100 +-- tidscan via CURRENT OF +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 029 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan" +== 030 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 031 +-- truncate_limit: 100 +-- skip one row +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 032 +-- truncate_limit: 100 +-- perform update +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING * +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) UPDATE tidscan SET id = - id WHERE CURRENT ..." +== 033 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 034 +-- truncate_limit: 100 +-- perform update +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING * +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) UPDATE tidscan SET id = - id WHERE CURRENT ..." +== 035 +-- truncate_limit: 100 +SELECT * FROM tidscan +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tidscan" +== 036 +-- truncate_limit: 100 +-- position cursor past any rows +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 037 +-- truncate_limit: 100 +-- should error out +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING * +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) UPDATE tidscan SET id = - id WHERE CURRENT ..." +== 038 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 039 +-- truncate_limit: 100 +-- bulk joins on CTID +-- (these plans don't use TID scans, but this still seems like an +-- appropriate place for these tests) +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid" +== 040 +-- truncate_limit: 100 +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid" +== 041 +-- truncate_limit: 100 +SET enable_hashjoin TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashjoin TO OFF" +== 042 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid" +== 043 +-- truncate_limit: 100 +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid" +== 044 +-- truncate_limit: 100 +RESET enable_hashjoin +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashjoin" +== 045 +-- truncate_limit: 100 +-- check predicate lock on CTID +BEGIN ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 046 +-- truncate_limit: 100 +SELECT * FROM tidscan WHERE ctid = '(0,1)' +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=Select +FILTER: schema="" table="" column="ctid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tidscan WHERE ctid = '(0,1)'" +== 047 +-- truncate_limit: 100 +-- locktype should be 'tuple' +SELECT locktype, mode FROM pg_locks WHERE pid = pg_backend_pid() AND mode = 'SIReadLock' +-- +TABLE: name="pg_locks" schema="" table="pg_locks" ctx=Select +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FUNCTION: name="pg_backend_pid" function="pg_backend_pid" schema="" ctx=Call +FILTER: schema="" table="" column="pid" +FILTER: schema="" table="" column="mode" +STMT: SelectStmt +TRUNCATED: "SELECT locktype, mode FROM pg_locks WHERE pid = pg_backend_pid() AND mode = 'SIReadLock'" +== 048 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 049 +-- truncate_limit: 100 +DROP TABLE tidscan +-- +TABLE: name="tidscan" schema="" table="tidscan" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tidscan" diff --git a/parser/testdata/summary_truncate/postgres_regress/time.metadata.json b/parser/testdata/summary_truncate/postgres_regress/time.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/time.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/time.test b/parser/testdata/summary_truncate/postgres_regress/time.test new file mode 100644 index 0000000..6b10075 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/time.test @@ -0,0 +1,348 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TIME +|-- + +CREATE TABLE TIME_TBL (f1 time(2)) +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE time_tbl (f1 time(2))" +== 002 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('00:00') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('00:00')" +== 003 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('01:00') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('01:00')" +== 004 +-- truncate_limit: 100 +-- as of 7.4, timezone spec should be accepted and ignored +INSERT INTO TIME_TBL VALUES ('02:03 PST') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('02:03 PST')" +== 005 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('11:59 EDT') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('11:59 EDT')" +== 006 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('12:00') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('12:00')" +== 007 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('12:01') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('12:01')" +== 008 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('23:59') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('23:59')" +== 009 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('11:59:59.99 PM') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('11:59:59.99 PM')" +== 010 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('2003-03-07 15:36:39 America/New_York') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('2003-03-07 15:36:39 America/New_York')" +== 011 +-- truncate_limit: 100 +INSERT INTO TIME_TBL VALUES ('2003-07-07 15:36:39 America/New_York') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('2003-07-07 15:36:39 America/New_York')" +== 012 +-- truncate_limit: 100 +-- this should fail (the timezone offset is not known) +INSERT INTO TIME_TBL VALUES ('15:36:39 America/New_York') +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO time_tbl VALUES ('15:36:39 America/New_York')" +== 013 +-- truncate_limit: 100 +SELECT f1 AS "Time" FROM TIME_TBL +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Time\" FROM time_tbl" +== 014 +-- truncate_limit: 100 +SELECT f1 AS "Three" FROM TIME_TBL WHERE f1 < '05:06:07' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Three\" FROM time_tbl WHERE f1 < '05:06:07'" +== 015 +-- truncate_limit: 100 +SELECT f1 AS "Five" FROM TIME_TBL WHERE f1 > '05:06:07' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Five\" FROM time_tbl WHERE f1 > '05:06:07'" +== 016 +-- truncate_limit: 100 +SELECT f1 AS "None" FROM TIME_TBL WHERE f1 < '00:00' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"None\" FROM time_tbl WHERE f1 < '00:00'" +== 017 +-- truncate_limit: 100 +SELECT f1 AS "Eight" FROM TIME_TBL WHERE f1 >= '00:00' +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Eight\" FROM time_tbl WHERE f1 >= '00:00'" +== 018 +-- truncate_limit: 100 +-- Check edge cases +SELECT '23:59:59.999999'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:59.999999'::time" +== 019 +-- truncate_limit: 100 +SELECT '23:59:59.9999999'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:59.9999999'::time" +== 020 +-- truncate_limit: 100 +-- rounds up +SELECT '23:59:60'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:60'::time" +== 021 +-- truncate_limit: 100 +-- rounds up +SELECT '24:00:00'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '24:00:00'::time" +== 022 +-- truncate_limit: 100 +-- allowed +SELECT '24:00:00.01'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '24:00:00.01'::time" +== 023 +-- truncate_limit: 100 +-- not allowed +SELECT '23:59:60.01'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:60.01'::time" +== 024 +-- truncate_limit: 100 +-- not allowed +SELECT '24:01:00'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '24:01:00'::time" +== 025 +-- truncate_limit: 100 +-- not allowed +SELECT '25:00:00'::time +-- +STMT: SelectStmt +TRUNCATED: "SELECT '25:00:00'::time" +== 026 +-- truncate_limit: 100 +-- not allowed + +-- Test non-error-throwing API +SELECT pg_input_is_valid('12:00:00', 'time') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('12:00:00', 'time')" +== 027 +-- truncate_limit: 100 +SELECT pg_input_is_valid('25:00:00', 'time') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('25:00:00', 'time')" +== 028 +-- truncate_limit: 100 +SELECT pg_input_is_valid('15:36:39 America/New_York', 'time') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('15:36:39 America/New_York', 'time')" +== 029 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('25:00:00', 'time') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('25:00:00', 'time')" +== 030 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'time') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'time')" +== 031 +-- truncate_limit: 100 +|-- +-- TIME simple math +|-- +-- We now make a distinction between time and intervals, +-- and adding two times together makes no sense at all. +-- Leave in one query to show that it is rejected, +-- and do the rest of the testing in horology.sql +-- where we do mixed-type arithmetic. - thomas 2000-12-02 + +SELECT f1 + time '00:01' AS "Illegal" FROM TIME_TBL +-- +TABLE: name="time_tbl" schema="" table="time_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 + '00:01'::time AS \"Illegal\" FROM time_tbl" +== 032 +-- truncate_limit: 100 +|-- +-- test EXTRACT +|-- +SELECT EXTRACT(MICROSECOND FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('microsecond' FROM '2020-05-26 13:30:25.575401'::time)" +== 033 +-- truncate_limit: 100 +SELECT EXTRACT(MILLISECOND FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millisecond' FROM '2020-05-26 13:30:25.575401'::time)" +== 034 +-- truncate_limit: 100 +SELECT EXTRACT(SECOND FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('second' FROM '2020-05-26 13:30:25.575401'::time)" +== 035 +-- truncate_limit: 100 +SELECT EXTRACT(MINUTE FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('minute' FROM '2020-05-26 13:30:25.575401'::time)" +== 036 +-- truncate_limit: 100 +SELECT EXTRACT(HOUR FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('hour' FROM '2020-05-26 13:30:25.575401'::time)" +== 037 +-- truncate_limit: 100 +SELECT EXTRACT(DAY FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('day' FROM '2020-05-26 13:30:25.575401'::time)" +== 038 +-- truncate_limit: 100 +-- error +SELECT EXTRACT(FORTNIGHT FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('fortnight' FROM '2020-05-26 13:30:25.575401'::time)" +== 039 +-- truncate_limit: 100 +-- error +SELECT EXTRACT(TIMEZONE FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone' FROM '2020-05-26 13:30:25.575401'::time)" +== 040 +-- truncate_limit: 100 +-- error +SELECT EXTRACT(EPOCH FROM TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '2020-05-26 13:30:25.575401'::time)" +== 041 +-- truncate_limit: 100 +-- date_part implementation is mostly the same as extract, so only +-- test a few cases for additional coverage. +SELECT date_part('microsecond', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('microsecond', '2020-05-26 13:30:25.575401'::time)" +== 042 +-- truncate_limit: 100 +SELECT date_part('millisecond', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('millisecond', '2020-05-26 13:30:25.575401'::time)" +== 043 +-- truncate_limit: 100 +SELECT date_part('second', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('second', '2020-05-26 13:30:25.575401'::time)" +== 044 +-- truncate_limit: 100 +SELECT date_part('epoch', TIME '2020-05-26 13:30:25.575401') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('epoch', '2020-05-26 13:30:25.575401'::time)" diff --git a/parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json b/parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json new file mode 100644 index 0000000..91e3e07 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json @@ -0,0 +1,175 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/timestamp.test b/parser/testdata/summary_truncate/postgres_regress/timestamp.test new file mode 100644 index 0000000..4a194cf --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/timestamp.test @@ -0,0 +1,1506 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TIMESTAMP +|-- + +CREATE TABLE TIMESTAMP_TBL (d1 timestamp(2) without time zone) +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE timestamp_tbl (d1 timestamp(2))" +== 002 +-- truncate_limit: 100 +-- Test shorthand input values +-- We can't just "select" the results since they aren't constants; test for +-- equality instead. We can do that by running the test inside a transaction +-- block, within which the value of 'now' shouldn't change, and so these +-- related values shouldn't either. + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 003 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('today') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('today')" +== 004 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('yesterday') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('yesterday')" +== 005 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('tomorrow')" +== 006 +-- truncate_limit: 100 +-- time zone should be ignored by this data type +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow EST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('tomorrow EST')" +== 007 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow zulu') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('tomorrow zulu')" +== 008 +-- truncate_limit: 100 +SELECT count(*) AS One FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'today' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamp_tbl WHERE d1 = 'today'::timestamp" +== 009 +-- truncate_limit: 100 +SELECT count(*) AS Three FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'tomorrow' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS three FROM timestamp_tbl WHERE d1 = 'tomorrow'::timestamp" +== 010 +-- truncate_limit: 100 +SELECT count(*) AS One FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'yesterday' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamp_tbl WHERE d1 = 'yesterday'::timestamp" +== 011 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 012 +-- truncate_limit: 100 +DELETE FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM timestamp_tbl" +== 013 +-- truncate_limit: 100 +-- Verify that 'now' *does* change over a reasonable interval such as 100 msec, +-- and that it doesn't change over the same interval within a transaction block + +INSERT INTO TIMESTAMP_TBL VALUES ('now') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('now')" +== 014 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 015 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 016 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('now') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('now')" +== 017 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 018 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('now') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('now')" +== 019 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 020 +-- truncate_limit: 100 +SELECT count(*) AS two FROM TIMESTAMP_TBL WHERE d1 = timestamp(2) without time zone 'now' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS two FROM timestamp_tbl WHERE d1 = 'now'::timestamp(2)" +== 021 +-- truncate_limit: 100 +SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM timestamp_tbl" +== 022 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 023 +-- truncate_limit: 100 +TRUNCATE TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE timestamp_tbl" +== 024 +-- truncate_limit: 100 +-- Special values +INSERT INTO TIMESTAMP_TBL VALUES ('-infinity') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('-infinity')" +== 025 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('infinity') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('infinity')" +== 026 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('epoch') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('epoch')" +== 027 +-- truncate_limit: 100 +SELECT timestamp 'infinity' = timestamp '+infinity' AS t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamp = '+infinity'::timestamp AS t" +== 028 +-- truncate_limit: 100 +-- Postgres v6.0 standard output format +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mon Feb 10 17:32:01 1997 PST')" +== 029 +-- truncate_limit: 100 +-- Variations on Postgres v6.1 standard output format +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mon Feb 10 17:32:01.000001 1997 PST')" +== 030 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mon Feb 10 17:32:01.999999 1997 PST')" +== 031 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.4 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mon Feb 10 17:32:01.4 1997 PST')" +== 032 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.5 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mon Feb 10 17:32:01.5 1997 PST')" +== 033 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.6 1997 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mon Feb 10 17:32:01.6 1997 PST')" +== 034 +-- truncate_limit: 100 +-- ISO 8601 format +INSERT INTO TIMESTAMP_TBL VALUES ('1997-01-02') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-01-02')" +== 035 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-01-02 03:04:05') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-01-02 03:04:05')" +== 036 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01-08') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-02-10 17:32:01-08')" +== 037 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01-0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-02-10 17:32:01-0800')" +== 038 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01 -08:00') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-02-10 17:32:01 -08:00')" +== 039 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 -0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('19970210 173201 -0800')" +== 040 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 17:32:01 -07:00') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-06-10 17:32:01 -07:00')" +== 041 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('2001-09-22T18:19:20') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('2001-09-22T18:19:20')" +== 042 +-- truncate_limit: 100 +-- POSIX format (note that the timezone abbrev is just decoration here) +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 08:14:01 GMT+8') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('2000-03-15 08:14:01 GMT+8')" +== 043 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 13:14:02 GMT-1') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('2000-03-15 13:14:02 GMT-1')" +== 044 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 12:14:03 GMT-2') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('2000-03-15 12:14:03 GMT-2')" +== 045 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 03:14:04 PST+8') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('2000-03-15 03:14:04 PST+8')" +== 046 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 02:14:05 MST+7:00') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('2000-03-15 02:14:05 MST+7:00')" +== 047 +-- truncate_limit: 100 +-- Variations for acceptable input formats +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997 -0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 10 17:32:01 1997 -0800')" +== 048 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 10 17:32:01 1997')" +== 049 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 5:32PM 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 10 5:32PM 1997')" +== 050 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997/02/10 17:32:01-0800') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997/02/10 17:32:01-0800')" +== 051 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-02-10 17:32:01 PST')" +== 052 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb-10-1997 17:32:01 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb-10-1997 17:32:01 PST')" +== 053 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('02-10-1997 17:32:01 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('02-10-1997 17:32:01 PST')" +== 054 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 PST') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('19970210 173201 PST')" +== 055 +-- truncate_limit: 100 +set datestyle to ymd +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO ymd" +== 056 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('97FEB10 5:32:01PM UTC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('97FEB10 5:32:01PM UTC')" +== 057 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('97/02/10 17:32:01 UTC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('97/02/10 17:32:01 UTC')" +== 058 +-- truncate_limit: 100 +reset datestyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" +== 059 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('1997.041 17:32:01 UTC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997.041 17:32:01 UTC')" +== 060 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 America/New_York') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('19970210 173201 America/New_York')" +== 061 +-- truncate_limit: 100 +-- this fails (even though TZ is a no-op, we still look it up) +INSERT INTO TIMESTAMP_TBL VALUES ('19970710 173201 America/Does_not_exist') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('19970710 173201 America/Does_not_exist')" +== 062 +-- truncate_limit: 100 +-- Test non-error-throwing API +SELECT pg_input_is_valid('now', 'timestamp') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('now', 'timestamp')" +== 063 +-- truncate_limit: 100 +SELECT pg_input_is_valid('garbage', 'timestamp') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('garbage', 'timestamp')" +== 064 +-- truncate_limit: 100 +SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp')" +== 065 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('garbage', 'timestamp') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('garbage', 'timestamp')" +== 066 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp')" +== 067 +-- truncate_limit: 100 +-- Check date conversion and date arithmetic +INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 18:32:01 PDT') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('1997-06-10 18:32:01 PDT')" +== 068 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 10 17:32:01 1997')" +== 069 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 11 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 11 17:32:01 1997')" +== 070 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 12 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 12 17:32:01 1997')" +== 071 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 13 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 13 17:32:01 1997')" +== 072 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 14 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 14 17:32:01 1997')" +== 073 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 15 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 15 17:32:01 1997')" +== 074 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 1997')" +== 075 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0097 BC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 0097 BC')" +== 076 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 0097')" +== 077 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0597') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 0597')" +== 078 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 1097')" +== 079 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1697') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 1697')" +== 080 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1797') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 1797')" +== 081 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1897') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 1897')" +== 082 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 1997')" +== 083 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 2097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 2097')" +== 084 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 28 17:32:01 1996')" +== 085 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 29 17:32:01 1996')" +== 086 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mar 01 17:32:01 1996')" +== 087 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Dec 30 17:32:01 1996')" +== 088 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1996') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Dec 31 17:32:01 1996')" +== 089 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Jan 01 17:32:01 1997')" +== 090 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 28 17:32:01 1997')" +== 091 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 29 17:32:01 1997')" +== 092 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Mar 01 17:32:01 1997')" +== 093 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Dec 30 17:32:01 1997')" +== 094 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1997') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Dec 31 17:32:01 1997')" +== 095 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1999') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Dec 31 17:32:01 1999')" +== 096 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2000') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Jan 01 17:32:01 2000')" +== 097 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 2000') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Dec 31 17:32:01 2000')" +== 098 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2001') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Jan 01 17:32:01 2001')" +== 099 +-- truncate_limit: 100 +-- Currently unsupported syntax and ranges +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 -0097') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 -0097')" +== 100 +-- truncate_limit: 100 +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 5097 BC') +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamp_tbl VALUES ('Feb 16 17:32:01 5097 BC')" +== 101 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamp_tbl" +== 102 +-- truncate_limit: 100 +-- Check behavior at the boundaries of the timestamp range +SELECT '4714-11-24 00:00:00 BC'::timestamp +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-24 00:00:00 BC'::timestamp" +== 103 +-- truncate_limit: 100 +SELECT '4714-11-23 23:59:59 BC'::timestamp +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-23 23:59:59 BC'::timestamp" +== 104 +-- truncate_limit: 100 +-- out of range +SELECT '294276-12-31 23:59:59'::timestamp +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294276-12-31 23:59:59'::timestamp" +== 105 +-- truncate_limit: 100 +SELECT '294277-01-01 00:00:00'::timestamp +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294277-01-01 00:00:00'::timestamp" +== 106 +-- truncate_limit: 100 +-- out of range + +-- Demonstrate functions and operators +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 > timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamp_tbl WHERE d1 > '1997-01-02'::timestamp" +== 107 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 < timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamp_tbl WHERE d1 < '1997-01-02'::timestamp" +== 108 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 = timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamp_tbl WHERE d1 = '1997-01-02'::timestamp" +== 109 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 != timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamp_tbl WHERE d1 <> '1997-01-02'::timestamp" +== 110 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 <= timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamp_tbl WHERE d1 <= '1997-01-02'::timestamp" +== 111 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 >= timestamp without time zone '1997-01-02' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamp_tbl WHERE d1 >= '1997-01-02'::timestamp" +== 112 +-- truncate_limit: 100 +SELECT d1 - timestamp without time zone '1997-01-02' AS diff + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 - '1997-01-02'::timestamp AS diff FROM timestamp_tbl WHERE ..." +== 113 +-- truncate_limit: 100 +SELECT date_trunc( 'week', timestamp '2004-02-29 15:44:17.71393' ) AS week_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('week', '2004-02-29 15:44:17.71393'::timestamp) AS week_trunc" +== 114 +-- truncate_limit: 100 +-- verify date_bin behaves the same as date_trunc for relevant intervals + +-- case 1: AD dates, origin < input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2001-01-01') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '2020-02-29 15:44:17.71393')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) intervals(str, \"interval\"), (VALUES (...)) ts(ts)" +== 115 +-- truncate_limit: 100 +-- case 2: BC dates, origin < input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2000-01-01 BC') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '0055-6-10 15:44:17.71393 BC')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) intervals(str, \"interval\"), (VALUES (...)) ts(ts)" +== 116 +-- truncate_limit: 100 +-- case 3: AD dates, origin > input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2020-03-02') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '2020-02-29 15:44:17.71393')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) intervals(str, \"interval\"), (VALUES (...)) ts(ts)" +== 117 +-- truncate_limit: 100 +-- case 4: BC dates, origin > input +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '0055-06-17 BC') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '0055-6-10 15:44:17.71393 BC')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) intervals(str, \"interval\"), (VALUES (...)) ts(ts)" +== 118 +-- truncate_limit: 100 +-- bin timestamps into arbitrary intervals +SELECT + interval, + ts, + origin, + date_bin(interval::interval, ts, origin) +FROM ( + VALUES + ('15 days'), + ('2 hours'), + ('1 hour 30 minutes'), + ('15 minutes'), + ('10 seconds'), + ('100 milliseconds'), + ('250 microseconds') +) intervals (interval), +(VALUES (timestamp '2020-02-11 15:44:17.71393')) ts (ts), +(VALUES (timestamp '2001-01-01')) origin (origin) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) intervals(\"interval\"), (VALUES (...)) ts(ts), (VALUES (...)) origi..." +== 119 +-- truncate_limit: 100 +-- shift bins using the origin parameter: +SELECT date_bin('5 min'::interval, timestamp '2020-02-01 01:01:01', timestamp '2020-02-01 00:02:30') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 120 +-- truncate_limit: 100 +-- test roundoff edge case when source < origin +SELECT date_bin('30 minutes'::interval, timestamp '2024-02-01 15:00:00', timestamp '2024-02-01 17:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 121 +-- truncate_limit: 100 +-- disallow intervals with months or years +SELECT date_bin('5 months'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('5 months'::interval, '2020-02-01 01:01:01'::timestamp, '2001-01-01'::timestamp)" +== 122 +-- truncate_limit: 100 +SELECT date_bin('5 years'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('5 years'::interval, '2020-02-01 01:01:01'::timestamp, '2001-01-01'::timestamp)" +== 123 +-- truncate_limit: 100 +-- disallow zero intervals +SELECT date_bin('0 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 124 +-- truncate_limit: 100 +-- disallow negative intervals +SELECT date_bin('-2 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 125 +-- truncate_limit: 100 +-- test overflow cases +select date_bin('15 minutes'::interval, timestamp '294276-12-30', timestamp '4000-12-20 BC') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('15 minutes'::interval, '294276-12-30'::timestamp, '4000-12-20 BC'::timestamp)" +== 126 +-- truncate_limit: 100 +select date_bin('200000000 days'::interval, '2024-02-01'::timestamp, '2024-01-01'::timestamp) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('200000000 days'::interval, '2024-02-01'::timestamp, '2024-01-01'::timestamp)" +== 127 +-- truncate_limit: 100 +select date_bin('365000 days'::interval, '4400-01-01 BC'::timestamp, '4000-01-01 BC'::timestamp) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('365000 days'::interval, '4400-01-01 BC'::timestamp, '4000-01-01 BC'::timestamp)" +== 128 +-- truncate_limit: 100 +-- Test casting within a BETWEEN qualifier +SELECT d1 - timestamp without time zone '1997-01-02' AS diff + FROM TIMESTAMP_TBL + WHERE d1 BETWEEN timestamp without time zone '1902-01-01' + AND timestamp without time zone '2038-01-01' +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 - '1997-01-02'::timestamp AS diff FROM timestamp_tbl WHERE ..." +== 129 +-- truncate_limit: 100 +-- DATE_PART (timestamp_part) +SELECT d1 as "timestamp", + date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, + date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, + date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl" +== 130 +-- truncate_limit: 100 +SELECT d1 as "timestamp", + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl" +== 131 +-- truncate_limit: 100 +SELECT d1 as "timestamp", + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow, + date_part( 'doy', d1) AS doy + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl" +== 132 +-- truncate_limit: 100 +SELECT d1 as "timestamp", + date_part( 'decade', d1) AS decade, + date_part( 'century', d1) AS century, + date_part( 'millennium', d1) AS millennium, + round(date_part( 'julian', d1)) AS julian, + date_part( 'epoch', d1) AS epoch + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl" +== 133 +-- truncate_limit: 100 +-- extract implementation is mostly the same as date_part, so only +-- test a few cases for additional coverage. +SELECT d1 as "timestamp", + extract(microseconds from d1) AS microseconds, + extract(milliseconds from d1) AS milliseconds, + extract(seconds from d1) AS seconds, + round(extract(julian from d1)) AS julian, + extract(epoch from d1) AS epoch + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl" +== 134 +-- truncate_limit: 100 +-- value near upper bound uses special case in code +SELECT date_part('epoch', '294270-01-01 00:00:00'::timestamp) +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('epoch', '294270-01-01 00:00:00'::timestamp)" +== 135 +-- truncate_limit: 100 +SELECT extract(epoch from '294270-01-01 00:00:00'::timestamp) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '294270-01-01 00:00:00'::timestamp)" +== 136 +-- truncate_limit: 100 +-- another internal overflow test case +SELECT extract(epoch from '5000-01-01 00:00:00'::timestamp) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '5000-01-01 00:00:00'::timestamp)" +== 137 +-- truncate_limit: 100 +-- test edge-case overflow in timestamp subtraction +SELECT timestamp '294276-12-31 23:59:59' - timestamp '1999-12-23 19:59:04.224193' AS ok +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294276-12-31 23:59:59'::timestamp - '1999-12-23 19:59:04.224193'::timestamp AS ok" +== 138 +-- truncate_limit: 100 +SELECT timestamp '294276-12-31 23:59:59' - timestamp '1999-12-23 19:59:04.224192' AS overflows +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294276-12-31 23:59:59'::timestamp - '1999-12-23 19:59:04.224192'::timestamp AS overflows" +== 139 +-- truncate_limit: 100 +-- TO_CHAR() +SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') FROM timestamp_tbl" +== 140 +-- truncate_limit: 100 +SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') FROM timestamp_tbl" +== 141 +-- truncate_limit: 100 +SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') FROM timestamp_tbl" +== 142 +-- truncate_limit: 100 +SELECT to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM FMWW FMDDD FMDD FMD FMJ') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl" +== 143 +-- truncate_limit: 100 +SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') FROM timestamp_tbl" +== 144 +-- truncate_limit: 100 +SELECT to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, E'\"HH:MI:SS is\" HH:MI:SS \"\\\\\"text between quote marks\\\\\"\"') FROM timestamp_tbl" +== 145 +-- truncate_limit: 100 +SELECT to_char(d1, 'HH24--text--MI--text--SS') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'HH24--text--MI--text--SS') FROM timestamp_tbl" +== 146 +-- truncate_limit: 100 +SELECT to_char(d1, 'YYYYTH YYYYth Jth') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'YYYYTH YYYYth Jth') FROM timestamp_tbl" +== 147 +-- truncate_limit: 100 +SELECT to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamp_tbl" +== 148 +-- truncate_limit: 100 +SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') FROM timestamp_tbl" +== 149 +-- truncate_limit: 100 +SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') + FROM TIMESTAMP_TBL +-- +TABLE: name="timestamp_tbl" schema="" table="timestamp_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') FROM timestamp_tbl" +== 150 +-- truncate_limit: 100 +SELECT to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamp), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d) +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) d(d)" +== 151 +-- truncate_limit: 100 +-- Roman months, with upper and lower case. +SELECT i, + to_char(i * interval '1mon', 'rm'), + to_char(i * interval '1mon', 'RM') + FROM generate_series(-13, 13) i +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(-13, 13) i" +== 152 +-- truncate_limit: 100 +-- timestamp numeric fields constructor +SELECT make_timestamp(2014, 12, 28, 6, 30, 45.887) +-- +FUNCTION: name="make_timestamp" function="make_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamp(2014, 12, 28, 6, 30, 45.887)" +== 153 +-- truncate_limit: 100 +SELECT make_timestamp(-44, 3, 15, 12, 30, 15) +-- +FUNCTION: name="make_timestamp" function="make_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamp(-44, 3, 15, 12, 30, 15)" +== 154 +-- truncate_limit: 100 +-- should fail +select make_timestamp(0, 7, 15, 12, 30, 15) +-- +FUNCTION: name="make_timestamp" function="make_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamp(0, 7, 15, 12, 30, 15)" +== 155 +-- truncate_limit: 100 +-- generate_series for timestamp +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '1 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('2020-01-01 00:00'::timestamp, '2020-01-02 03:00'::timestamp, '1 ho..." +== 156 +-- truncate_limit: 100 +-- the LIMIT should allow this to terminate in a reasonable amount of time +-- (but that unfortunately doesn't work yet for SELECT * FROM ...) +select generate_series('2022-01-01 00:00'::timestamp, + 'infinity'::timestamp, + '1 month'::interval) limit 10 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... LIMIT 10" +== 157 +-- truncate_limit: 100 +-- errors +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '0 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('2020-01-01 00:00'::timestamp, '2020-01-02 03:00'::timestamp, '0 ho..." +== 158 +-- truncate_limit: 100 +select generate_series(timestamp '1995-08-06 12:12:12', timestamp '1996-08-06 12:12:12', interval 'infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 159 +-- truncate_limit: 100 +select generate_series(timestamp '1995-08-06 12:12:12', timestamp '1996-08-06 12:12:12', interval '-infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 160 +-- truncate_limit: 100 +-- test arithmetic with infinite timestamps +select timestamp 'infinity' - timestamp 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamp - 'infinity'::timestamp" +== 161 +-- truncate_limit: 100 +select timestamp 'infinity' - timestamp '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamp - '-infinity'::timestamp" +== 162 +-- truncate_limit: 100 +select timestamp '-infinity' - timestamp 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::timestamp - 'infinity'::timestamp" +== 163 +-- truncate_limit: 100 +select timestamp '-infinity' - timestamp '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::timestamp - '-infinity'::timestamp" +== 164 +-- truncate_limit: 100 +select timestamp 'infinity' - timestamp '1995-08-06 12:12:12' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamp - '1995-08-06 12:12:12'::timestamp" +== 165 +-- truncate_limit: 100 +select timestamp '-infinity' - timestamp '1995-08-06 12:12:12' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::timestamp - '1995-08-06 12:12:12'::timestamp" +== 166 +-- truncate_limit: 100 +-- test age() with infinite timestamps +select age(timestamp 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('infinity'::timestamp)" +== 167 +-- truncate_limit: 100 +select age(timestamp '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('-infinity'::timestamp)" +== 168 +-- truncate_limit: 100 +select age(timestamp 'infinity', timestamp 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('infinity'::timestamp, 'infinity'::timestamp)" +== 169 +-- truncate_limit: 100 +select age(timestamp 'infinity', timestamp '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('infinity'::timestamp, '-infinity'::timestamp)" +== 170 +-- truncate_limit: 100 +select age(timestamp '-infinity', timestamp 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('-infinity'::timestamp, 'infinity'::timestamp)" +== 171 +-- truncate_limit: 100 +select age(timestamp '-infinity', timestamp '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('-infinity'::timestamp, '-infinity'::timestamp)" diff --git a/parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json b/parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json new file mode 100644 index 0000000..82ef9cc --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json @@ -0,0 +1,386 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/timestamptz.test b/parser/testdata/summary_truncate/postgres_regress/timestamptz.test new file mode 100644 index 0000000..a2a6fd2 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/timestamptz.test @@ -0,0 +1,2991 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TIMESTAMPTZ +|-- + +CREATE TABLE TIMESTAMPTZ_TBL (d1 timestamp(2) with time zone) +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE timestamptz_tbl (d1 timestamp (2) with time zone)" +== 002 +-- truncate_limit: 100 +-- Test shorthand input values +-- We can't just "select" the results since they aren't constants; test for +-- equality instead. We can do that by running the test inside a transaction +-- block, within which the value of 'now' shouldn't change, and so these +-- related values shouldn't either. + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 003 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('today') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('today')" +== 004 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('yesterday') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('yesterday')" +== 005 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('tomorrow')" +== 006 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow EST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('tomorrow EST')" +== 007 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow zulu') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('tomorrow zulu')" +== 008 +-- truncate_limit: 100 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'today' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamptz_tbl WHERE d1 = 'today'::timestamp with time zone" +== 009 +-- truncate_limit: 100 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamptz_tbl WHERE d1 = 'tomorrow'::timestamp with time zone" +== 010 +-- truncate_limit: 100 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'yesterday' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamptz_tbl WHERE d1 = 'yesterday'::timestamp with time zone" +== 011 +-- truncate_limit: 100 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow EST' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamptz_tbl WHERE d1 = 'tomorrow EST'::timestamp with time zone" +== 012 +-- truncate_limit: 100 +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow zulu' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS one FROM timestamptz_tbl WHERE d1 = 'tomorrow zulu'::timestamp with time zone" +== 013 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 014 +-- truncate_limit: 100 +DELETE FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM timestamptz_tbl" +== 015 +-- truncate_limit: 100 +-- Verify that 'now' *does* change over a reasonable interval such as 100 msec, +-- and that it doesn't change over the same interval within a transaction block + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('now')" +== 016 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 017 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 018 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('now')" +== 019 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 020 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('now')" +== 021 +-- truncate_limit: 100 +SELECT pg_sleep(0.1) +-- +FUNCTION: name="pg_sleep" function="pg_sleep" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_sleep(0.1)" +== 022 +-- truncate_limit: 100 +SELECT count(*) AS two FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp(2) with time zone 'now' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS two FROM timestamptz_tbl WHERE d1 = 'now'::timestamp (2) with time zone" +== 023 +-- truncate_limit: 100 +SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM timestamptz_tbl" +== 024 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 025 +-- truncate_limit: 100 +TRUNCATE TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE timestamptz_tbl" +== 026 +-- truncate_limit: 100 +-- Special values +INSERT INTO TIMESTAMPTZ_TBL VALUES ('-infinity') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('-infinity')" +== 027 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('infinity') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('infinity')" +== 028 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('epoch') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('epoch')" +== 029 +-- truncate_limit: 100 +SELECT timestamptz 'infinity' = timestamptz '+infinity' AS t +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamptz = '+infinity'::timestamptz AS t" +== 030 +-- truncate_limit: 100 +-- Postgres v6.0 standard output format +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mon Feb 10 17:32:01 1997 PST')" +== 031 +-- truncate_limit: 100 +-- Variations on Postgres v6.1 standard output format +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mon Feb 10 17:32:01.000001 1997 PST')" +== 032 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mon Feb 10 17:32:01.999999 1997 PST')" +== 033 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.4 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mon Feb 10 17:32:01.4 1997 PST')" +== 034 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.5 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mon Feb 10 17:32:01.5 1997 PST')" +== 035 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.6 1997 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mon Feb 10 17:32:01.6 1997 PST')" +== 036 +-- truncate_limit: 100 +-- ISO 8601 format +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-01-02') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-01-02')" +== 037 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-01-02 03:04:05') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-01-02 03:04:05')" +== 038 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01-08') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-02-10 17:32:01-08')" +== 039 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01-0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-02-10 17:32:01-0800')" +== 040 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01 -08:00') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-02-10 17:32:01 -08:00')" +== 041 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 -0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('19970210 173201 -0800')" +== 042 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-06-10 17:32:01 -07:00') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-06-10 17:32:01 -07:00')" +== 043 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2001-09-22T18:19:20') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('2001-09-22T18:19:20')" +== 044 +-- truncate_limit: 100 +-- POSIX format (note that the timezone abbrev is just decoration here) +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 08:14:01 GMT+8') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('2000-03-15 08:14:01 GMT+8')" +== 045 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 13:14:02 GMT-1') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('2000-03-15 13:14:02 GMT-1')" +== 046 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 12:14:03 GMT-2') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('2000-03-15 12:14:03 GMT-2')" +== 047 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 03:14:04 PST+8') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('2000-03-15 03:14:04 PST+8')" +== 048 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 02:14:05 MST+7:00') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('2000-03-15 02:14:05 MST+7:00')" +== 049 +-- truncate_limit: 100 +-- Variations for acceptable input formats +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997 -0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 10 17:32:01 1997 -0800')" +== 050 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 10 17:32:01 1997')" +== 051 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 5:32PM 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 10 5:32PM 1997')" +== 052 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997/02/10 17:32:01-0800') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997/02/10 17:32:01-0800')" +== 053 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-02-10 17:32:01 PST')" +== 054 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb-10-1997 17:32:01 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb-10-1997 17:32:01 PST')" +== 055 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('02-10-1997 17:32:01 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('02-10-1997 17:32:01 PST')" +== 056 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 PST') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('19970210 173201 PST')" +== 057 +-- truncate_limit: 100 +set datestyle to ymd +-- +STMT: VariableSetStmt +TRUNCATED: "SET datestyle TO ymd" +== 058 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('97FEB10 5:32:01PM UTC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('97FEB10 5:32:01PM UTC')" +== 059 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('97/02/10 17:32:01 UTC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('97/02/10 17:32:01 UTC')" +== 060 +-- truncate_limit: 100 +reset datestyle +-- +STMT: VariableSetStmt +TRUNCATED: "RESET datestyle" +== 061 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997.041 17:32:01 UTC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997.041 17:32:01 UTC')" +== 062 +-- truncate_limit: 100 +-- timestamps at different timezones +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 America/New_York') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('19970210 173201 America/New_York')" +== 063 +-- truncate_limit: 100 +SELECT '19970210 173201' AT TIME ZONE 'America/New_York' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '19970210 173201' AT TIME ZONE 'America/New_York'" +== 064 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America/New_York') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('19970710 173201 America/New_York')" +== 065 +-- truncate_limit: 100 +SELECT '19970710 173201' AT TIME ZONE 'America/New_York' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '19970710 173201' AT TIME ZONE 'America/New_York'" +== 066 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America/Does_not_exist') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('19970710 173201 America/Does_not_exist')" +== 067 +-- truncate_limit: 100 +SELECT '19970710 173201' AT TIME ZONE 'America/Does_not_exist' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '19970710 173201' AT TIME ZONE 'America/Does_not_exist'" +== 068 +-- truncate_limit: 100 +-- Daylight saving time for timestamps beyond 32-bit time_t range. +SELECT '20500710 173201 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20500710 173201 Europe/Helsinki'::timestamptz" +== 069 +-- truncate_limit: 100 +-- DST +SELECT '20500110 173201 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '20500110 173201 Europe/Helsinki'::timestamptz" +== 070 +-- truncate_limit: 100 +-- non-DST + +SELECT '205000-07-10 17:32:01 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '205000-07-10 17:32:01 Europe/Helsinki'::timestamptz" +== 071 +-- truncate_limit: 100 +-- DST +SELECT '205000-01-10 17:32:01 Europe/Helsinki'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '205000-01-10 17:32:01 Europe/Helsinki'::timestamptz" +== 072 +-- truncate_limit: 100 +-- non-DST + +-- Test non-error-throwing API +SELECT pg_input_is_valid('now', 'timestamptz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('now', 'timestamptz')" +== 073 +-- truncate_limit: 100 +SELECT pg_input_is_valid('garbage', 'timestamptz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('garbage', 'timestamptz')" +== 074 +-- truncate_limit: 100 +SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz')" +== 075 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('garbage', 'timestamptz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('garbage', 'timestamptz')" +== 076 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz')" +== 077 +-- truncate_limit: 100 +-- Check date conversion and date arithmetic +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-06-10 18:32:01 PDT') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('1997-06-10 18:32:01 PDT')" +== 078 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 10 17:32:01 1997')" +== 079 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 11 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 11 17:32:01 1997')" +== 080 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 12 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 12 17:32:01 1997')" +== 081 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 13 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 13 17:32:01 1997')" +== 082 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 14 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 14 17:32:01 1997')" +== 083 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 15 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 15 17:32:01 1997')" +== 084 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 1997')" +== 085 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0097 BC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 0097 BC')" +== 086 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 0097')" +== 087 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0597') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 0597')" +== 088 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 1097')" +== 089 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1697') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 1697')" +== 090 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1797') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 1797')" +== 091 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1897') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 1897')" +== 092 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 1997')" +== 093 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 2097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 2097')" +== 094 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 28 17:32:01 1996')" +== 095 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 29 17:32:01 1996')" +== 096 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mar 01 17:32:01 1996')" +== 097 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Dec 30 17:32:01 1996')" +== 098 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1996') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Dec 31 17:32:01 1996')" +== 099 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Jan 01 17:32:01 1997')" +== 100 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 28 17:32:01 1997')" +== 101 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 29 17:32:01 1997')" +== 102 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Mar 01 17:32:01 1997')" +== 103 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Dec 30 17:32:01 1997')" +== 104 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1997') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Dec 31 17:32:01 1997')" +== 105 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1999') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Dec 31 17:32:01 1999')" +== 106 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2000') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Jan 01 17:32:01 2000')" +== 107 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 2000') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Dec 31 17:32:01 2000')" +== 108 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2001') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Jan 01 17:32:01 2001')" +== 109 +-- truncate_limit: 100 +-- Currently unsupported syntax and ranges +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 -0097')" +== 110 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC') +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tbl VALUES ('Feb 16 17:32:01 5097 BC')" +== 111 +-- truncate_limit: 100 +-- Alternative field order that we've historically supported (sort of) +-- with regular and POSIXy timezone specs +SELECT 'Wed Jul 11 10:51:14 America/New_York 2001'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Wed Jul 11 10:51:14 America/New_York 2001'::timestamptz" +== 112 +-- truncate_limit: 100 +SELECT 'Wed Jul 11 10:51:14 GMT-4 2001'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Wed Jul 11 10:51:14 GMT-4 2001'::timestamptz" +== 113 +-- truncate_limit: 100 +SELECT 'Wed Jul 11 10:51:14 GMT+4 2001'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Wed Jul 11 10:51:14 GMT+4 2001'::timestamptz" +== 114 +-- truncate_limit: 100 +SELECT 'Wed Jul 11 10:51:14 PST-03:00 2001'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Wed Jul 11 10:51:14 PST-03:00 2001'::timestamptz" +== 115 +-- truncate_limit: 100 +SELECT 'Wed Jul 11 10:51:14 PST+03:00 2001'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Wed Jul 11 10:51:14 PST+03:00 2001'::timestamptz" +== 116 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamptz_tbl" +== 117 +-- truncate_limit: 100 +-- Check behavior at the boundaries of the timestamp range +SELECT '4714-11-24 00:00:00+00 BC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-24 00:00:00+00 BC'::timestamptz" +== 118 +-- truncate_limit: 100 +SELECT '4714-11-23 16:00:00-08 BC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-23 16:00:00-08 BC'::timestamptz" +== 119 +-- truncate_limit: 100 +SELECT 'Sun Nov 23 16:00:00 4714 PST BC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'Sun Nov 23 16:00:00 4714 PST BC'::timestamptz" +== 120 +-- truncate_limit: 100 +SELECT '4714-11-23 23:59:59+00 BC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '4714-11-23 23:59:59+00 BC'::timestamptz" +== 121 +-- truncate_limit: 100 +-- out of range +SELECT '294276-12-31 23:59:59+00'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294276-12-31 23:59:59+00'::timestamptz" +== 122 +-- truncate_limit: 100 +SELECT '294276-12-31 15:59:59-08'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294276-12-31 15:59:59-08'::timestamptz" +== 123 +-- truncate_limit: 100 +SELECT '294277-01-01 00:00:00+00'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294277-01-01 00:00:00+00'::timestamptz" +== 124 +-- truncate_limit: 100 +-- out of range +SELECT '294277-12-31 16:00:00-08'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '294277-12-31 16:00:00-08'::timestamptz" +== 125 +-- truncate_limit: 100 +-- out of range + +-- Demonstrate functions and operators +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 > timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamptz_tbl WHERE d1 > '1997-01-02'::timestamp with time zone" +== 126 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 < timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamptz_tbl WHERE d1 < '1997-01-02'::timestamp with time zone" +== 127 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 = timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamptz_tbl WHERE d1 = '1997-01-02'::timestamp with time zone" +== 128 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 != timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamptz_tbl WHERE d1 <> '1997-01-02'::timestamp with time zone" +== 129 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 <= timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamptz_tbl WHERE d1 <= '1997-01-02'::timestamp with time zone" +== 130 +-- truncate_limit: 100 +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 >= timestamp with time zone '1997-01-02' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 FROM timestamptz_tbl WHERE d1 >= '1997-01-02'::timestamp with time zone" +== 131 +-- truncate_limit: 100 +SELECT d1 - timestamp with time zone '1997-01-02' AS diff + FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'" +== 132 +-- truncate_limit: 100 +SELECT date_trunc( 'week', timestamp with time zone '2004-02-29 15:44:17.71393' ) AS week_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('week', '2004-02-29 15:44:17.71393'::timestamp with time zone) AS week_trunc" +== 133 +-- truncate_limit: 100 +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'Australia/Sydney') as sydney_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 134 +-- truncate_limit: 100 +-- zone name +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'GMT') as gmt_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('day', '2001-02-16 20:38:40+00'::timestamp with time zone, 'GMT') AS gmt_trunc" +== 135 +-- truncate_limit: 100 +-- fixed-offset abbreviation +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'VET') as vet_trunc +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_trunc('day', '2001-02-16 20:38:40+00'::timestamp with time zone, 'VET') AS vet_trunc" +== 136 +-- truncate_limit: 100 +-- variable-offset abbreviation + +-- verify date_bin behaves the same as date_trunc for relevant intervals +SELECT + str, + interval, + date_trunc(str, ts, 'Australia/Sydney') = date_bin(interval::interval, ts, timestamp with time zone '2001-01-01+11') AS equal +FROM ( + VALUES + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamptz '2020-02-29 15:44:17.71393+00')) ts (ts) +-- +FUNCTION: name="date_trunc" function="date_trunc" schema="" ctx=Call +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) intervals(str, \"interval\"), (VALUES (...)) ts(ts)" +== 137 +-- truncate_limit: 100 +-- bin timestamps into arbitrary intervals +SELECT + interval, + ts, + origin, + date_bin(interval::interval, ts, origin) +FROM ( + VALUES + ('15 days'), + ('2 hours'), + ('1 hour 30 minutes'), + ('15 minutes'), + ('10 seconds'), + ('100 milliseconds'), + ('250 microseconds') +) intervals (interval), +(VALUES (timestamptz '2020-02-11 15:44:17.71393')) ts (ts), +(VALUES (timestamptz '2001-01-01')) origin (origin) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) intervals(\"interval\"), (VALUES (...)) ts(ts), (VALUES (...)) origi..." +== 138 +-- truncate_limit: 100 +-- shift bins using the origin parameter: +SELECT date_bin('5 min'::interval, timestamptz '2020-02-01 01:01:01+00', timestamptz '2020-02-01 00:02:30+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 139 +-- truncate_limit: 100 +-- test roundoff edge case when source < origin +SELECT date_bin('30 minutes'::interval, timestamptz '2024-02-01 15:00:00', timestamptz '2024-02-01 17:00:00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 140 +-- truncate_limit: 100 +-- disallow intervals with months or years +SELECT date_bin('5 months'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 141 +-- truncate_limit: 100 +SELECT date_bin('5 years'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 142 +-- truncate_limit: 100 +-- disallow zero intervals +SELECT date_bin('0 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 143 +-- truncate_limit: 100 +-- disallow negative intervals +SELECT date_bin('-2 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 144 +-- truncate_limit: 100 +-- test overflow cases +select date_bin('15 minutes'::interval, timestamptz '294276-12-30', timestamptz '4000-12-20 BC') +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('15 minutes'::interval, '294276-12-30'::timestamptz, '4000-12-20 BC'::timestamptz)" +== 145 +-- truncate_limit: 100 +select date_bin('200000000 days'::interval, '2024-02-01'::timestamptz, '2024-01-01'::timestamptz) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('200000000 days'::interval, '2024-02-01'::timestamptz, '2024-01-01'::timestamptz)" +== 146 +-- truncate_limit: 100 +select date_bin('365000 days'::interval, '4400-01-01 BC'::timestamptz, '4000-01-01 BC'::timestamptz) +-- +FUNCTION: name="date_bin" function="date_bin" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_bin('365000 days'::interval, '4400-01-01 BC'::timestamptz, '4000-01-01 BC'::timestamptz)" +== 147 +-- truncate_limit: 100 +-- Test casting within a BETWEEN qualifier +SELECT d1 - timestamp with time zone '1997-01-02' AS diff + FROM TIMESTAMPTZ_TBL + WHERE d1 BETWEEN timestamp with time zone '1902-01-01' AND timestamp with time zone '2038-01-01' +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FILTER: schema="" table="" column="d1" +STMT: SelectStmt +TRUNCATED: "SELECT d1 - '1997-01-02'::timestamp with time zone AS diff FROM timestamptz_tbl WHERE ..." +== 148 +-- truncate_limit: 100 +-- DATE_PART (timestamptz_part) +SELECT d1 as timestamptz, + date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, + date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, + date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 149 +-- truncate_limit: 100 +SELECT d1 as timestamptz, + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 150 +-- truncate_limit: 100 +SELECT d1 as timestamptz, + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow, + date_part( 'doy', d1) AS doy + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 151 +-- truncate_limit: 100 +SELECT d1 as timestamptz, + date_part( 'decade', d1) AS decade, + date_part( 'century', d1) AS century, + date_part( 'millennium', d1) AS millennium, + round(date_part( 'julian', d1)) AS julian, + date_part( 'epoch', d1) AS epoch + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 152 +-- truncate_limit: 100 +SELECT d1 as timestamptz, + date_part( 'timezone', d1) AS timezone, + date_part( 'timezone_hour', d1) AS timezone_hour, + date_part( 'timezone_minute', d1) AS timezone_minute + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 153 +-- truncate_limit: 100 +-- extract implementation is mostly the same as date_part, so only +-- test a few cases for additional coverage. +SELECT d1 as "timestamp", + extract(microseconds from d1) AS microseconds, + extract(milliseconds from d1) AS milliseconds, + extract(seconds from d1) AS seconds, + round(extract(julian from d1)) AS julian, + extract(epoch from d1) AS epoch + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="round" function="round" schema="" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 154 +-- truncate_limit: 100 +-- value near upper bound uses special case in code +SELECT date_part('epoch', '294270-01-01 00:00:00+00'::timestamptz) +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('epoch', '294270-01-01 00:00:00+00'::timestamptz)" +== 155 +-- truncate_limit: 100 +SELECT extract(epoch from '294270-01-01 00:00:00+00'::timestamptz) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '294270-01-01 00:00:00+00'::timestamptz)" +== 156 +-- truncate_limit: 100 +-- another internal overflow test case +SELECT extract(epoch from '5000-01-01 00:00:00+00'::timestamptz) +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '5000-01-01 00:00:00+00'::timestamptz)" +== 157 +-- truncate_limit: 100 +-- test edge-case overflow in timestamp subtraction +SELECT timestamptz '294276-12-31 23:59:59 UTC' - timestamptz '1999-12-23 19:59:04.224193 UTC' AS ok +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 158 +-- truncate_limit: 100 +SELECT timestamptz '294276-12-31 23:59:59 UTC' - timestamptz '1999-12-23 19:59:04.224192 UTC' AS overflows +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 159 +-- truncate_limit: 100 +-- TO_CHAR() +SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') FROM timestamptz_tbl" +== 160 +-- truncate_limit: 100 +SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') FROM timestamptz_tbl" +== 161 +-- truncate_limit: 100 +SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') FROM timestamptz_tbl" +== 162 +-- truncate_limit: 100 +SELECT to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM FMWW FMDDD FMDD FMD FMJ') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 163 +-- truncate_limit: 100 +SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') FROM timestamptz_tbl" +== 164 +-- truncate_limit: 100 +SELECT to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, E'\"HH:MI:SS is\" HH:MI:SS \"\\\\\"text between quote marks\\\\\"\"') FROM timestamptz_tbl" +== 165 +-- truncate_limit: 100 +SELECT to_char(d1, 'HH24--text--MI--text--SS') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'HH24--text--MI--text--SS') FROM timestamptz_tbl" +== 166 +-- truncate_limit: 100 +SELECT to_char(d1, 'YYYYTH YYYYth Jth') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'YYYYTH YYYYth Jth') FROM timestamptz_tbl" +== 167 +-- truncate_limit: 100 +SELECT to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timestamptz_tbl" +== 168 +-- truncate_limit: 100 +SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') FROM timestamptz_tbl" +== 169 +-- truncate_limit: 100 +SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') + FROM TIMESTAMPTZ_TBL +-- +TABLE: name="timestamptz_tbl" schema="" table="timestamptz_tbl" ctx=Select +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') FROM timestamptz_tbl" +== 170 +-- truncate_limit: 100 +SELECT to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamptz), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d) +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) d(d)" +== 171 +-- truncate_limit: 100 +-- Check OF, TZH, TZM with various zone offsets, particularly fractional hours +SET timezone = '00:00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"00:00\"" +== 172 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 173 +-- truncate_limit: 100 +SET timezone = '+02:00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"+02:00\"" +== 174 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 175 +-- truncate_limit: 100 +SET timezone = '-13:00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-13:00\"" +== 176 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 177 +-- truncate_limit: 100 +SET timezone = '-00:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-00:30\"" +== 178 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 179 +-- truncate_limit: 100 +SET timezone = '00:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"00:30\"" +== 180 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 181 +-- truncate_limit: 100 +SET timezone = '-04:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-04:30\"" +== 182 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 183 +-- truncate_limit: 100 +SET timezone = '04:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"04:30\"" +== 184 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 185 +-- truncate_limit: 100 +SET timezone = '-04:15' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-04:15\"" +== 186 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 187 +-- truncate_limit: 100 +SET timezone = '04:15' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"04:15\"" +== 188 +-- truncate_limit: 100 +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'OF') AS \"OF\", to_char(now(), 'TZH:TZM') AS \"TZH:TZM\"" +== 189 +-- truncate_limit: 100 +RESET timezone +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" +== 190 +-- truncate_limit: 100 +-- Check of, tzh, tzm with various zone offsets. +SET timezone = '00:00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"00:00\"" +== 191 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "Of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS \"Of\", to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 192 +-- truncate_limit: 100 +SET timezone = '+02:00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"+02:00\"" +== 193 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 194 +-- truncate_limit: 100 +SET timezone = '-13:00' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-13:00\"" +== 195 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 196 +-- truncate_limit: 100 +SET timezone = '-00:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-00:30\"" +== 197 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 198 +-- truncate_limit: 100 +SET timezone = '00:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"00:30\"" +== 199 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 200 +-- truncate_limit: 100 +SET timezone = '-04:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-04:30\"" +== 201 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 202 +-- truncate_limit: 100 +SET timezone = '04:30' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"04:30\"" +== 203 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 204 +-- truncate_limit: 100 +SET timezone = '-04:15' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"-04:15\"" +== 205 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 206 +-- truncate_limit: 100 +SET timezone = '04:15' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"04:15\"" +== 207 +-- truncate_limit: 100 +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm" +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_char(now(), 'of') AS of, to_char(now(), 'tzh:tzm') AS \"tzh:tzm\"" +== 208 +-- truncate_limit: 100 +RESET timezone +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" +== 209 +-- truncate_limit: 100 +CREATE TABLE TIMESTAMPTZ_TST (a int , b timestamptz) +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE timestamptz_tst (a int, b timestamptz)" +== 210 +-- truncate_limit: 100 +-- Test year field value with len > 4 +INSERT INTO TIMESTAMPTZ_TST VALUES(1, 'Sat Mar 12 23:58:48 1000 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tst VALUES (1, 'Sat Mar 12 23:58:48 1000 IST')" +== 211 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TST VALUES(2, 'Sat Mar 12 23:58:48 10000 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tst VALUES (2, 'Sat Mar 12 23:58:48 10000 IST')" +== 212 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TST VALUES(3, 'Sat Mar 12 23:58:48 100000 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tst VALUES (3, 'Sat Mar 12 23:58:48 100000 IST')" +== 213 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TST VALUES(3, '10000 Mar 12 23:58:48 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tst VALUES (3, '10000 Mar 12 23:58:48 IST')" +== 214 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '100000312 23:58:48 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tst VALUES (4, '100000312 23:58:48 IST')" +== 215 +-- truncate_limit: 100 +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '1000000312 23:58:48 IST') +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timestamptz_tst VALUES (4, '1000000312 23:58:48 IST')" +== 216 +-- truncate_limit: 100 +--Verify data +SELECT * FROM TIMESTAMPTZ_TST ORDER BY a +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM timestamptz_tst ORDER BY a" +== 217 +-- truncate_limit: 100 +--Cleanup +DROP TABLE TIMESTAMPTZ_TST +-- +TABLE: name="timestamptz_tst" schema="" table="timestamptz_tst" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE timestamptz_tst" +== 218 +-- truncate_limit: 100 +-- test timestamptz constructors +set TimeZone to 'America/New_York' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"America/New_York\"" +== 219 +-- truncate_limit: 100 +-- numeric timezone +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33) +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1973, 7, 15, 8, 15, 55.33)" +== 220 +-- truncate_limit: 100 +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '+2') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1973, 7, 15, 8, 15, 55.33, '+2')" +== 221 +-- truncate_limit: 100 +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '-2') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1973, 7, 15, 8, 15, 55.33, '-2')" +== 222 +-- truncate_limit: 100 +WITH tzs (tz) AS (VALUES + ('+1'), ('+1:'), ('+1:0'), ('+100'), ('+1:00'), ('+01:00'), + ('+10'), ('+1000'), ('+10:'), ('+10:0'), ('+10:00'), ('+10:00:'), + ('+10:00:1'), ('+10:00:01'), + ('+10:00:10')) + SELECT make_timestamptz(2010, 2, 27, 3, 45, 00, tz), tz FROM tzs +-- +CTE: "tzs" +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH tzs(tz) AS (VALUES (...)) SELECT make_timestamptz(2010, 2, 27, 3, 45, 0, tz), tz FROM tzs" +== 223 +-- truncate_limit: 100 +-- these should fail +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '2') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1973, 7, 15, 8, 15, 55.33, '2')" +== 224 +-- truncate_limit: 100 +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '+16') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '+16')" +== 225 +-- truncate_limit: 100 +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '-16') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '-16')" +== 226 +-- truncate_limit: 100 +-- should be true +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '+2') = '1973-07-15 08:15:55.33+02'::timestamptz +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1973, 7, 15, 8, 15, 55.33, '+2') = '1973-07-15 08:15:55.33+02'::timestamptz" +== 227 +-- truncate_limit: 100 +-- full timezone names +SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') = timestamptz '2014-12-10 00:00:00 Europe/Prague' +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 228 +-- truncate_limit: 100 +SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') AT TIME ZONE 'UTC'" +== 229 +-- truncate_limit: 100 +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Asia/Singapore') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Asia/Singapore') AT TIME ZONE 'UTC'" +== 230 +-- truncate_limit: 100 +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Pacific/Honolulu') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Pacific/Honolulu') AT TIME ZONE 'UTC'" +== 231 +-- truncate_limit: 100 +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Europe/Paris') AT TIME ZONE 'UTC' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Europe/Paris') AT TIME ZONE 'UTC'" +== 232 +-- truncate_limit: 100 +SELECT make_timestamptz(1910, 12, 24, 0, 0, 0, 'Nehwon/Lankhmar') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(1910, 12, 24, 0, 0, 0, 'Nehwon/Lankhmar')" +== 233 +-- truncate_limit: 100 +-- abbreviations +SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EST') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EST')" +== 234 +-- truncate_limit: 100 +SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EDT') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EDT')" +== 235 +-- truncate_limit: 100 +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'FOO8BAR') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'FOO8BAR')" +== 236 +-- truncate_limit: 100 +-- POSIX +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT,M3.2.0,M11.1.0') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT,M3.2.0,M11.1.0')" +== 237 +-- truncate_limit: 100 +RESET TimeZone +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" +== 238 +-- truncate_limit: 100 +-- generate_series for timestamptz +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '1 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('2020-01-01 00:00'::timestamptz, '2020-01-02 03:00'::timestamptz, '..." +== 239 +-- truncate_limit: 100 +-- the LIMIT should allow this to terminate in a reasonable amount of time +-- (but that unfortunately doesn't work yet for SELECT * FROM ...) +select generate_series('2022-01-01 00:00'::timestamptz, + 'infinity'::timestamptz, + '1 month'::interval) limit 10 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... LIMIT 10" +== 240 +-- truncate_limit: 100 +-- errors +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '0 hour'::interval) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('2020-01-01 00:00'::timestamptz, '2020-01-02 03:00'::timestamptz, '..." +== 241 +-- truncate_limit: 100 +select generate_series(timestamptz '1995-08-06 12:12:12', timestamptz '1996-08-06 12:12:12', interval 'infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 242 +-- truncate_limit: 100 +select generate_series(timestamptz '1995-08-06 12:12:12', timestamptz '1996-08-06 12:12:12', interval '-infinity') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 243 +-- truncate_limit: 100 +-- Interval crossing time shift for Europe/Warsaw timezone (with DST) +SET TimeZone to 'UTC' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"UTC\"" +== 244 +-- truncate_limit: 100 +SELECT date_add('2022-10-30 00:00:00+01'::timestamptz, + '1 day'::interval) +-- +FUNCTION: name="date_add" function="date_add" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_add('2022-10-30 00:00:00+01'::timestamptz, '1 day'::interval)" +== 245 +-- truncate_limit: 100 +SELECT date_add('2021-10-31 00:00:00+02'::timestamptz, + '1 day'::interval, + 'Europe/Warsaw') +-- +FUNCTION: name="date_add" function="date_add" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_add('2021-10-31 00:00:00+02'::timestamptz, '1 day'::interval, 'Europe/Warsaw')" +== 246 +-- truncate_limit: 100 +SELECT date_subtract('2022-10-30 00:00:00+01'::timestamptz, + '1 day'::interval) +-- +FUNCTION: name="date_subtract" function="date_subtract" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_subtract('2022-10-30 00:00:00+01'::timestamptz, '1 day'::interval)" +== 247 +-- truncate_limit: 100 +SELECT date_subtract('2021-10-31 00:00:00+02'::timestamptz, + '1 day'::interval, + 'Europe/Warsaw') +-- +FUNCTION: name="date_subtract" function="date_subtract" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_subtract('2021-10-31 00:00:00+02'::timestamptz, '1 day'::interval, 'Europe/Warsaw')" +== 248 +-- truncate_limit: 100 +SELECT * FROM generate_series('2021-12-31 23:00:00+00'::timestamptz, + '2020-12-31 23:00:00+00'::timestamptz, + '-1 month'::interval, + 'Europe/Warsaw') +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series('2021-12-31 23:00:00+00'::timestamptz, '2020-12-31 23:00:00+00'::ti..." +== 249 +-- truncate_limit: 100 +RESET TimeZone +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" +== 250 +-- truncate_limit: 100 +|-- +-- Test behavior with a dynamic (time-varying) timezone abbreviation. +-- These tests rely on the knowledge that MSK (Europe/Moscow standard time) +-- moved forwards in Mar 2011 and backwards again in Oct 2014. +|-- + +SET TimeZone to 'UTC' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"UTC\"" +== 251 +-- truncate_limit: 100 +SELECT '2011-03-27 00:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 00:00:00 Europe/Moscow'::timestamptz" +== 252 +-- truncate_limit: 100 +SELECT '2011-03-27 01:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:00:00 Europe/Moscow'::timestamptz" +== 253 +-- truncate_limit: 100 +SELECT '2011-03-27 01:59:59 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:59:59 Europe/Moscow'::timestamptz" +== 254 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:00 Europe/Moscow'::timestamptz" +== 255 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:01 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:01 Europe/Moscow'::timestamptz" +== 256 +-- truncate_limit: 100 +SELECT '2011-03-27 02:59:59 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:59:59 Europe/Moscow'::timestamptz" +== 257 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:00 Europe/Moscow'::timestamptz" +== 258 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:01 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:01 Europe/Moscow'::timestamptz" +== 259 +-- truncate_limit: 100 +SELECT '2011-03-27 04:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 04:00:00 Europe/Moscow'::timestamptz" +== 260 +-- truncate_limit: 100 +SELECT '2011-03-27 00:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 00:00:00 MSK'::timestamptz" +== 261 +-- truncate_limit: 100 +SELECT '2011-03-27 01:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:00:00 MSK'::timestamptz" +== 262 +-- truncate_limit: 100 +SELECT '2011-03-27 01:59:59 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:59:59 MSK'::timestamptz" +== 263 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:00 MSK'::timestamptz" +== 264 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:01 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:01 MSK'::timestamptz" +== 265 +-- truncate_limit: 100 +SELECT '2011-03-27 02:59:59 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:59:59 MSK'::timestamptz" +== 266 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:00 MSK'::timestamptz" +== 267 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:01 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:01 MSK'::timestamptz" +== 268 +-- truncate_limit: 100 +SELECT '2011-03-27 04:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 04:00:00 MSK'::timestamptz" +== 269 +-- truncate_limit: 100 +SELECT '2014-10-26 00:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:00:00 Europe/Moscow'::timestamptz" +== 270 +-- truncate_limit: 100 +SELECT '2014-10-26 00:59:59 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:59:59 Europe/Moscow'::timestamptz" +== 271 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:00 Europe/Moscow'::timestamptz" +== 272 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:01 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:01 Europe/Moscow'::timestamptz" +== 273 +-- truncate_limit: 100 +SELECT '2014-10-26 02:00:00 Europe/Moscow'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 02:00:00 Europe/Moscow'::timestamptz" +== 274 +-- truncate_limit: 100 +SELECT '2014-10-26 00:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:00:00 MSK'::timestamptz" +== 275 +-- truncate_limit: 100 +SELECT '2014-10-26 00:59:59 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:59:59 MSK'::timestamptz" +== 276 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:00 MSK'::timestamptz" +== 277 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:01 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:01 MSK'::timestamptz" +== 278 +-- truncate_limit: 100 +SELECT '2014-10-26 02:00:00 MSK'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 02:00:00 MSK'::timestamptz" +== 279 +-- truncate_limit: 100 +SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 280 +-- truncate_limit: 100 +SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 281 +-- truncate_limit: 100 +SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 282 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 283 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 284 +-- truncate_limit: 100 +SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 285 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 286 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 287 +-- truncate_limit: 100 +SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 288 +-- truncate_limit: 100 +SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'MSK'" +== 289 +-- truncate_limit: 100 +SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'MSK'" +== 290 +-- truncate_limit: 100 +SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'MSK'" +== 291 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'MSK'" +== 292 +-- truncate_limit: 100 +SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'MSK'" +== 293 +-- truncate_limit: 100 +SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'MSK'" +== 294 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'MSK'" +== 295 +-- truncate_limit: 100 +SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'MSK'" +== 296 +-- truncate_limit: 100 +SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'MSK'" +== 297 +-- truncate_limit: 100 +SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 298 +-- truncate_limit: 100 +SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 299 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 300 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 301 +-- truncate_limit: 100 +SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'" +== 302 +-- truncate_limit: 100 +SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'MSK'" +== 303 +-- truncate_limit: 100 +SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'MSK'" +== 304 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'MSK'" +== 305 +-- truncate_limit: 100 +SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'MSK'" +== 306 +-- truncate_limit: 100 +SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'MSK'" +== 307 +-- truncate_limit: 100 +SELECT make_timestamptz(2014, 10, 26, 0, 0, 0, 'MSK') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2014, 10, 26, 0, 0, 0, 'MSK')" +== 308 +-- truncate_limit: 100 +SELECT make_timestamptz(2014, 10, 26, 1, 0, 0, 'MSK') +-- +FUNCTION: name="make_timestamptz" function="make_timestamptz" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT make_timestamptz(2014, 10, 26, 1, 0, 0, 'MSK')" +== 309 +-- truncate_limit: 100 +SELECT to_timestamp( 0) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(0)" +== 310 +-- truncate_limit: 100 +-- 1970-01-01 00:00:00+00 +SELECT to_timestamp( 946684800) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(946684800)" +== 311 +-- truncate_limit: 100 +-- 2000-01-01 00:00:00+00 +SELECT to_timestamp(1262349296.7890123) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(1262349296.7890123)" +== 312 +-- truncate_limit: 100 +-- 2010-01-01 12:34:56.789012+00 +-- edge cases +SELECT to_timestamp(-210866803200) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(-210866803200)" +== 313 +-- truncate_limit: 100 +-- 4714-11-24 00:00:00+00 BC +-- upper limit varies between integer and float timestamps, so hard to test +-- nonfinite values +SELECT to_timestamp(' Infinity'::float) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp(' Infinity'::double precision)" +== 314 +-- truncate_limit: 100 +SELECT to_timestamp('-Infinity'::float) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('-Infinity'::double precision)" +== 315 +-- truncate_limit: 100 +SELECT to_timestamp('NaN'::float) +-- +FUNCTION: name="to_timestamp" function="to_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_timestamp('NaN'::double precision)" +== 316 +-- truncate_limit: 100 +SET TimeZone to 'Europe/Moscow' +-- +STMT: VariableSetStmt +TRUNCATED: "SET timezone TO \"Europe/Moscow\"" +== 317 +-- truncate_limit: 100 +SELECT '2011-03-26 21:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 21:00:00 UTC'::timestamptz" +== 318 +-- truncate_limit: 100 +SELECT '2011-03-26 22:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 22:00:00 UTC'::timestamptz" +== 319 +-- truncate_limit: 100 +SELECT '2011-03-26 22:59:59 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 22:59:59 UTC'::timestamptz" +== 320 +-- truncate_limit: 100 +SELECT '2011-03-26 23:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:00:00 UTC'::timestamptz" +== 321 +-- truncate_limit: 100 +SELECT '2011-03-26 23:00:01 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:00:01 UTC'::timestamptz" +== 322 +-- truncate_limit: 100 +SELECT '2011-03-26 23:59:59 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:59:59 UTC'::timestamptz" +== 323 +-- truncate_limit: 100 +SELECT '2011-03-27 00:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 00:00:00 UTC'::timestamptz" +== 324 +-- truncate_limit: 100 +SELECT '2014-10-25 21:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 21:00:00 UTC'::timestamptz" +== 325 +-- truncate_limit: 100 +SELECT '2014-10-25 21:59:59 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 21:59:59 UTC'::timestamptz" +== 326 +-- truncate_limit: 100 +SELECT '2014-10-25 22:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 22:00:00 UTC'::timestamptz" +== 327 +-- truncate_limit: 100 +SELECT '2014-10-25 22:00:01 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 22:00:01 UTC'::timestamptz" +== 328 +-- truncate_limit: 100 +SELECT '2014-10-25 23:00:00 UTC'::timestamptz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 23:00:00 UTC'::timestamptz" +== 329 +-- truncate_limit: 100 +RESET TimeZone +-- +STMT: VariableSetStmt +TRUNCATED: "RESET timezone" +== 330 +-- truncate_limit: 100 +SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 331 +-- truncate_limit: 100 +SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 332 +-- truncate_limit: 100 +SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 333 +-- truncate_limit: 100 +SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 334 +-- truncate_limit: 100 +SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 335 +-- truncate_limit: 100 +SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 336 +-- truncate_limit: 100 +SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 337 +-- truncate_limit: 100 +SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 338 +-- truncate_limit: 100 +SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 339 +-- truncate_limit: 100 +SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 340 +-- truncate_limit: 100 +SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 341 +-- truncate_limit: 100 +SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'" +== 342 +-- truncate_limit: 100 +SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 343 +-- truncate_limit: 100 +SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 344 +-- truncate_limit: 100 +SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 345 +-- truncate_limit: 100 +SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 346 +-- truncate_limit: 100 +SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 347 +-- truncate_limit: 100 +SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 348 +-- truncate_limit: 100 +SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 349 +-- truncate_limit: 100 +SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 350 +-- truncate_limit: 100 +SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 351 +-- truncate_limit: 100 +SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 352 +-- truncate_limit: 100 +SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 353 +-- truncate_limit: 100 +SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK' +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'" +== 354 +-- truncate_limit: 100 +|-- +-- Test LOCAL time zone +|-- +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 355 +-- truncate_limit: 100 +SET LOCAL TIME ZONE 'Europe/Paris' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO \"Europe/Paris\"" +== 356 +-- truncate_limit: 100 +VALUES (CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "VALUES ('1978-07-07 19:38 America/New_York'::timestamp with time zone AT LOCAL)" +== 357 +-- truncate_limit: 100 +VALUES (TIMESTAMP '1978-07-07 19:38' AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "VALUES ('1978-07-07 19:38'::timestamp AT LOCAL)" +== 358 +-- truncate_limit: 100 +SET LOCAL TIME ZONE 'Australia/Sydney' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO \"Australia/Sydney\"" +== 359 +-- truncate_limit: 100 +VALUES (CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "VALUES ('1978-07-07 19:38 America/New_York'::timestamp with time zone AT LOCAL)" +== 360 +-- truncate_limit: 100 +VALUES (TIMESTAMP '1978-07-07 19:38' AT LOCAL) +-- +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "VALUES ('1978-07-07 19:38'::timestamp AT LOCAL)" +== 361 +-- truncate_limit: 100 +SET LOCAL TimeZone TO 'UTC' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO \"UTC\"" +== 362 +-- truncate_limit: 100 +CREATE VIEW timestamp_local_view AS + SELECT CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL AS ttz_at_local, + timezone(CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE)) AS ttz_func, + TIMESTAMP '1978-07-07 19:38' AT LOCAL AS t_at_local, + timezone(TIMESTAMP '1978-07-07 19:38') AS t_func +-- +TABLE: name="timestamp_local_view" schema="" table="timestamp_local_view" ctx=DDL +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW timestamp_local_view AS SELECT '1978-07-07 19:38 America/New_York'::timestamp with ti..." +== 363 +-- truncate_limit: 100 +SELECT pg_get_viewdef('timestamp_local_view', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('timestamp_local_view', true)" +== 364 +-- truncate_limit: 100 +TABLE timestamp_local_view +-- +TABLE: name="timestamp_local_view" schema="" table="timestamp_local_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM timestamp_local_view" +== 365 +-- truncate_limit: 100 +DROP VIEW timestamp_local_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW timestamp_local_view" +== 366 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 367 +-- truncate_limit: 100 +|-- +-- Test that AT TIME ZONE isn't misoptimized when using an index (bug #14504) +|-- +create temp table tmptz (f1 timestamptz primary key) +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tmptz (f1 timestamptz PRIMARY KEY)" +== 368 +-- truncate_limit: 100 +insert into tmptz values ('2017-01-18 00:00+00') +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tmptz VALUES ('2017-01-18 00:00+00')" +== 369 +-- truncate_limit: 100 +explain (costs off) +select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00' +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=Select +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tmptz WHERE f1 AT TIME ZONE 'utc' = '2017-01-18 00:00'" +== 370 +-- truncate_limit: 100 +select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00' +-- +TABLE: name="tmptz" schema="" table="tmptz" ctx=Select +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tmptz WHERE f1 AT TIME ZONE 'utc' = '2017-01-18 00:00'" +== 371 +-- truncate_limit: 100 +-- test arithmetic with infinite timestamps +SELECT timestamptz 'infinity' - timestamptz 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamptz - 'infinity'::timestamptz" +== 372 +-- truncate_limit: 100 +SELECT timestamptz 'infinity' - timestamptz '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamptz - '-infinity'::timestamptz" +== 373 +-- truncate_limit: 100 +SELECT timestamptz '-infinity' - timestamptz 'infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::timestamptz - 'infinity'::timestamptz" +== 374 +-- truncate_limit: 100 +SELECT timestamptz '-infinity' - timestamptz '-infinity' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::timestamptz - '-infinity'::timestamptz" +== 375 +-- truncate_limit: 100 +SELECT timestamptz 'infinity' - timestamptz '1995-08-06 12:12:12' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'infinity'::timestamptz - '1995-08-06 12:12:12'::timestamptz" +== 376 +-- truncate_limit: 100 +SELECT timestamptz '-infinity' - timestamptz '1995-08-06 12:12:12' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '-infinity'::timestamptz - '1995-08-06 12:12:12'::timestamptz" +== 377 +-- truncate_limit: 100 +-- test age() with infinite timestamps +SELECT age(timestamptz 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('infinity'::timestamptz)" +== 378 +-- truncate_limit: 100 +SELECT age(timestamptz '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('-infinity'::timestamptz)" +== 379 +-- truncate_limit: 100 +SELECT age(timestamptz 'infinity', timestamptz 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('infinity'::timestamptz, 'infinity'::timestamptz)" +== 380 +-- truncate_limit: 100 +SELECT age(timestamptz 'infinity', timestamptz '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('infinity'::timestamptz, '-infinity'::timestamptz)" +== 381 +-- truncate_limit: 100 +SELECT age(timestamptz '-infinity', timestamptz 'infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('-infinity'::timestamptz, 'infinity'::timestamptz)" +== 382 +-- truncate_limit: 100 +SELECT age(timestamptz '-infinity', timestamptz '-infinity') +-- +FUNCTION: name="age" function="age" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT age('-infinity'::timestamptz, '-infinity'::timestamptz)" diff --git a/parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json b/parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json new file mode 100644 index 0000000..7c6405d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json @@ -0,0 +1,61 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/timetz.test b/parser/testdata/summary_truncate/postgres_regress/timetz.test new file mode 100644 index 0000000..88761df --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/timetz.test @@ -0,0 +1,463 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TIMETZ +|-- + +CREATE TABLE TIMETZ_TBL (f1 time(2) with time zone) +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE timetz_tbl (f1 time (2) with time zone)" +== 002 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('00:01 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('00:01 PDT')" +== 003 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('01:00 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('01:00 PDT')" +== 004 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('02:03 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('02:03 PDT')" +== 005 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('07:07 PST') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('07:07 PST')" +== 006 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('08:08 EDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('08:08 EDT')" +== 007 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('11:59 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('11:59 PDT')" +== 008 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('12:00 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('12:00 PDT')" +== 009 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('12:01 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('12:01 PDT')" +== 010 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('23:59 PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('23:59 PDT')" +== 011 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('11:59:59.99 PM PDT') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('11:59:59.99 PM PDT')" +== 012 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('2003-03-07 15:36:39 America/New_York') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('2003-03-07 15:36:39 America/New_York')" +== 013 +-- truncate_limit: 100 +INSERT INTO TIMETZ_TBL VALUES ('2003-07-07 15:36:39 America/New_York') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('2003-07-07 15:36:39 America/New_York')" +== 014 +-- truncate_limit: 100 +-- this should fail (the timezone offset is not known) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('15:36:39 America/New_York')" +== 015 +-- truncate_limit: 100 +-- this should fail (timezone not specified without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('15:36:39 m2')" +== 016 +-- truncate_limit: 100 +-- this should fail (dynamic timezone abbreviation without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2') +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO timetz_tbl VALUES ('15:36:39 MSK m2')" +== 017 +-- truncate_limit: 100 +SELECT f1 AS "Time TZ" FROM TIMETZ_TBL +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Time TZ\" FROM timetz_tbl" +== 018 +-- truncate_limit: 100 +SELECT f1 AS "Three" FROM TIMETZ_TBL WHERE f1 < '05:06:07-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Three\" FROM timetz_tbl WHERE f1 < '05:06:07-07'" +== 019 +-- truncate_limit: 100 +SELECT f1 AS "Seven" FROM TIMETZ_TBL WHERE f1 > '05:06:07-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Seven\" FROM timetz_tbl WHERE f1 > '05:06:07-07'" +== 020 +-- truncate_limit: 100 +SELECT f1 AS "None" FROM TIMETZ_TBL WHERE f1 < '00:00-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"None\" FROM timetz_tbl WHERE f1 < '00:00-07'" +== 021 +-- truncate_limit: 100 +SELECT f1 AS "Ten" FROM TIMETZ_TBL WHERE f1 >= '00:00-07' +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS \"Ten\" FROM timetz_tbl WHERE f1 >= '00:00-07'" +== 022 +-- truncate_limit: 100 +-- Check edge cases +SELECT '23:59:59.999999 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:59.999999 PDT'::timetz" +== 023 +-- truncate_limit: 100 +SELECT '23:59:59.9999999 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:59.9999999 PDT'::timetz" +== 024 +-- truncate_limit: 100 +-- rounds up +SELECT '23:59:60 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:60 PDT'::timetz" +== 025 +-- truncate_limit: 100 +-- rounds up +SELECT '24:00:00 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '24:00:00 PDT'::timetz" +== 026 +-- truncate_limit: 100 +-- allowed +SELECT '24:00:00.01 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '24:00:00.01 PDT'::timetz" +== 027 +-- truncate_limit: 100 +-- not allowed +SELECT '23:59:60.01 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '23:59:60.01 PDT'::timetz" +== 028 +-- truncate_limit: 100 +-- not allowed +SELECT '24:01:00 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '24:01:00 PDT'::timetz" +== 029 +-- truncate_limit: 100 +-- not allowed +SELECT '25:00:00 PDT'::timetz +-- +STMT: SelectStmt +TRUNCATED: "SELECT '25:00:00 PDT'::timetz" +== 030 +-- truncate_limit: 100 +-- not allowed + +-- Test non-error-throwing API +SELECT pg_input_is_valid('12:00:00 PDT', 'timetz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('12:00:00 PDT', 'timetz')" +== 031 +-- truncate_limit: 100 +SELECT pg_input_is_valid('25:00:00 PDT', 'timetz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('25:00:00 PDT', 'timetz')" +== 032 +-- truncate_limit: 100 +SELECT pg_input_is_valid('15:36:39 America/New_York', 'timetz') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('15:36:39 America/New_York', 'timetz')" +== 033 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('25:00:00 PDT', 'timetz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('25:00:00 PDT', 'timetz')" +== 034 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'timetz') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'timetz')" +== 035 +-- truncate_limit: 100 +|-- +-- TIME simple math +|-- +-- We now make a distinction between time and intervals, +-- and adding two times together makes no sense at all. +-- Leave in one query to show that it is rejected, +-- and do the rest of the testing in horology.sql +-- where we do mixed-type arithmetic. - thomas 2000-12-02 + +SELECT f1 + time with time zone '00:01' AS "Illegal" FROM TIMETZ_TBL +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 + '00:01'::time with time zone AS \"Illegal\" FROM timetz_tbl" +== 036 +-- truncate_limit: 100 +|-- +-- test EXTRACT +|-- +SELECT EXTRACT(MICROSECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('microsecond' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 037 +-- truncate_limit: 100 +SELECT EXTRACT(MILLISECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('millisecond' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 038 +-- truncate_limit: 100 +SELECT EXTRACT(SECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('second' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 039 +-- truncate_limit: 100 +SELECT EXTRACT(MINUTE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('minute' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 040 +-- truncate_limit: 100 +SELECT EXTRACT(HOUR FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('hour' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 041 +-- truncate_limit: 100 +SELECT EXTRACT(DAY FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('day' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 042 +-- truncate_limit: 100 +-- error +SELECT EXTRACT(FORTNIGHT FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('fortnight' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 043 +-- truncate_limit: 100 +-- error +SELECT EXTRACT(TIMEZONE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone' FROM '2020-05-26 13:30:25.575401-04:30'::time with time zone)" +== 044 +-- truncate_limit: 100 +SELECT EXTRACT(TIMEZONE_HOUR FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone_hour' FROM '2020-05-26 13:30:25.575401-04:30'::time with time zone)" +== 045 +-- truncate_limit: 100 +SELECT EXTRACT(TIMEZONE_MINUTE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('timezone_minute' FROM '2020-05-26 13:30:25.575401-04:30'::time with time zone)" +== 046 +-- truncate_limit: 100 +SELECT EXTRACT(EPOCH FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT extract ('epoch' FROM '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 047 +-- truncate_limit: 100 +-- date_part implementation is mostly the same as extract, so only +-- test a few cases for additional coverage. +SELECT date_part('microsecond', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('microsecond', '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 048 +-- truncate_limit: 100 +SELECT date_part('millisecond', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('millisecond', '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 049 +-- truncate_limit: 100 +SELECT date_part('second', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('second', '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 050 +-- truncate_limit: 100 +SELECT date_part('epoch', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04') +-- +FUNCTION: name="date_part" function="date_part" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT date_part('epoch', '2020-05-26 13:30:25.575401-04'::time with time zone)" +== 051 +-- truncate_limit: 100 +|-- +-- Test timetz_zone, timetz_izone, AT LOCAL +|-- +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 052 +-- truncate_limit: 100 +SET LOCAL TimeZone TO 'UTC' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL timezone TO \"UTC\"" +== 053 +-- truncate_limit: 100 +CREATE VIEW timetz_local_view AS + SELECT f1 AS dat, + timezone(f1) AS dat_func, + f1 AT LOCAL AS dat_at_local, + f1 AT TIME ZONE current_setting('TimeZone') AS dat_at_tz, + f1 AT TIME ZONE INTERVAL '00:00' AS dat_at_int + FROM TIMETZ_TBL + ORDER BY f1 +-- +TABLE: name="timetz_local_view" schema="" table="timetz_local_view" ctx=DDL +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FUNCTION: name="timezone" function="timezone" schema="" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW timetz_local_view AS SELECT f1 AS dat, timezone(f1) AS dat_func, f1 AT LOCAL AS dat_a..." +== 054 +-- truncate_limit: 100 +SELECT pg_get_viewdef('timetz_local_view', true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('timetz_local_view', true)" +== 055 +-- truncate_limit: 100 +TABLE timetz_local_view +-- +TABLE: name="timetz_local_view" schema="" table="timetz_local_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM timetz_local_view" +== 056 +-- truncate_limit: 100 +SELECT f1 AS dat, + f1 AT TIME ZONE 'UTC+10' AS dat_at_tz, + f1 AT TIME ZONE INTERVAL '-10:00' AS dat_at_int + FROM TIMETZ_TBL + ORDER BY f1 +-- +TABLE: name="timetz_tbl" schema="" table="timetz_tbl" ctx=Select +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.timezone" function="timezone" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM timetz_tbl ORDER BY f1" +== 057 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json b/parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json new file mode 100644 index 0000000..342e97a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json @@ -0,0 +1,494 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/transactions.test b/parser/testdata/summary_truncate/postgres_regress/transactions.test new file mode 100644 index 0000000..e0264d3 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/transactions.test @@ -0,0 +1,3477 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TRANSACTIONS +|-- + +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 002 +-- truncate_limit: 100 +CREATE TABLE xacttest (a smallint, b real) +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE xacttest (a smallint, b real)" +== 003 +-- truncate_limit: 100 +INSERT INTO xacttest VALUES + (56, 7.8), + (100, 99.097), + (0, 0.09561), + (42, 324.78) +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xacttest VALUES (56, 7.8), (100, 99.097), (0, 0.09561), (42, 324.78)" +== 004 +-- truncate_limit: 100 +INSERT INTO xacttest (a, b) VALUES (777, 777.777) +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xacttest (a, b) VALUES (777, 777.777)" +== 005 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 006 +-- truncate_limit: 100 +-- should retrieve one value-- +SELECT a FROM xacttest WHERE a > 100 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM xacttest WHERE a > 100" +== 007 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 008 +-- truncate_limit: 100 +CREATE TABLE disappear (a int4) +-- +TABLE: name="disappear" schema="" table="disappear" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE disappear (a int4)" +== 009 +-- truncate_limit: 100 +DELETE FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM xacttest" +== 010 +-- truncate_limit: 100 +-- should be empty +SELECT * FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xacttest" +== 011 +-- truncate_limit: 100 +ABORT +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 012 +-- truncate_limit: 100 +-- should not exist +SELECT oid FROM pg_class WHERE relname = 'disappear' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT oid FROM pg_class WHERE relname = 'disappear'" +== 013 +-- truncate_limit: 100 +-- should have members again +SELECT * FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xacttest" +== 014 +-- truncate_limit: 100 +-- Test that transaction characteristics cannot be reset. +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 015 +-- truncate_limit: 100 +SELECT COUNT(*) FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM xacttest" +== 016 +-- truncate_limit: 100 +RESET transaction_isolation +-- +STMT: VariableSetStmt +TRUNCATED: "RESET transaction_isolation" +== 017 +-- truncate_limit: 100 +-- error +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 018 +-- truncate_limit: 100 +BEGIN TRANSACTION READ ONLY +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN READ ONLY" +== 019 +-- truncate_limit: 100 +SELECT COUNT(*) FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM xacttest" +== 020 +-- truncate_limit: 100 +RESET transaction_read_only +-- +STMT: VariableSetStmt +TRUNCATED: "RESET transaction_read_only" +== 021 +-- truncate_limit: 100 +-- error +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 022 +-- truncate_limit: 100 +BEGIN TRANSACTION DEFERRABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN DEFERRABLE" +== 023 +-- truncate_limit: 100 +SELECT COUNT(*) FROM xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM xacttest" +== 024 +-- truncate_limit: 100 +RESET transaction_deferrable +-- +STMT: VariableSetStmt +TRUNCATED: "RESET transaction_deferrable" +== 025 +-- truncate_limit: 100 +-- error +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 026 +-- truncate_limit: 100 +CREATE FUNCTION errfunc() RETURNS int LANGUAGE SQL AS 'SELECT 1' +SET transaction_read_only = on +-- +FUNCTION: name="errfunc" function="errfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION errfunc() RETURNS int LANGUAGE sql AS $$SELECT 1$$ SET transaction_read_only TO ON" +== 027 +-- truncate_limit: 100 +-- error + +-- Read-only tests + +CREATE TABLE writetest (a int) +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE writetest (a int)" +== 028 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE temptest (a int) +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE temptest (a int)" +== 029 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 030 +-- truncate_limit: 100 +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY, DEFERRABLE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY, DEFERRABLE" +== 031 +-- truncate_limit: 100 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest" +== 032 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ WRITE" +== 033 +-- truncate_limit: 100 +--fail +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 034 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 035 +-- truncate_limit: 100 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 036 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ WRITE" +== 037 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 038 +-- truncate_limit: 100 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest" +== 039 +-- truncate_limit: 100 +-- ok +SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 040 +-- truncate_limit: 100 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 041 +-- truncate_limit: 100 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest" +== 042 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 043 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ WRITE" +== 044 +-- truncate_limit: 100 +--fail +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 045 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 046 +-- truncate_limit: 100 +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ WRITE" +== 047 +-- truncate_limit: 100 +-- ok +SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 048 +-- truncate_limit: 100 +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ WRITE" +== 049 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 050 +-- truncate_limit: 100 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest" +== 051 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 052 +-- truncate_limit: 100 +-- ok +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ WRITE" +== 053 +-- truncate_limit: 100 +--fail +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 054 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 055 +-- truncate_limit: 100 +SET TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ WRITE" +== 056 +-- truncate_limit: 100 +-- ok +SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 057 +-- truncate_limit: 100 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 058 +-- truncate_limit: 100 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest" +== 059 +-- truncate_limit: 100 +-- ok +ROLLBACK TO SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 060 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 061 +-- truncate_limit: 100 +-- off +SAVEPOINT y +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT y" +== 062 +-- truncate_limit: 100 +SET TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION READ ONLY" +== 063 +-- truncate_limit: 100 +-- ok +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest" +== 064 +-- truncate_limit: 100 +-- ok +RELEASE SAVEPOINT y +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE y" +== 065 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 066 +-- truncate_limit: 100 +-- off +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 067 +-- truncate_limit: 100 +SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY +-- +STMT: VariableSetStmt +TRUNCATED: "SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY" +== 068 +-- truncate_limit: 100 +DROP TABLE writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE writetest" +== 069 +-- truncate_limit: 100 +-- fail +INSERT INTO writetest VALUES (1) +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO writetest VALUES (1)" +== 070 +-- truncate_limit: 100 +-- fail +SELECT * FROM writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest" +== 071 +-- truncate_limit: 100 +-- ok +DELETE FROM temptest +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM temptest" +== 072 +-- truncate_limit: 100 +-- ok +UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a +-- +TABLE: name="temptest" schema="" table="temptest" ctx=DML +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: UpdateStmt +TRUNCATED: "UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a" +== 073 +-- truncate_limit: 100 +-- ok +PREPARE test AS UPDATE writetest SET a = 0 +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DML +STMT: PrepareStmt +STMT: UpdateStmt +TRUNCATED: "PREPARE test AS UPDATE writetest SET a = 0" +== 074 +-- truncate_limit: 100 +-- ok +EXECUTE test +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE test" +== 075 +-- truncate_limit: 100 +-- fail +SELECT * FROM writetest, temptest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=Select +TABLE: name="temptest" schema="" table="temptest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM writetest, temptest" +== 076 +-- truncate_limit: 100 +-- ok +CREATE TABLE test AS SELECT * FROM writetest +-- +TABLE: name="test" schema="" table="test" ctx=DDL +TABLE: name="writetest" schema="" table="writetest" ctx=Select +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE test AS SELECT * FROM writetest" +== 077 +-- truncate_limit: 100 +-- fail + +START TRANSACTION READ WRITE +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION READ WRITE" +== 078 +-- truncate_limit: 100 +DROP TABLE writetest +-- +TABLE: name="writetest" schema="" table="writetest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE writetest" +== 079 +-- truncate_limit: 100 +-- ok +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 080 +-- truncate_limit: 100 +-- Subtransactions, basic tests +-- create & drop tables +SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE +-- +STMT: VariableSetStmt +TRUNCATED: "SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE" +== 081 +-- truncate_limit: 100 +CREATE TABLE trans_foobar (a int) +-- +TABLE: name="trans_foobar" schema="" table="trans_foobar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_foobar (a int)" +== 082 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 083 +-- truncate_limit: 100 +CREATE TABLE trans_foo (a int) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_foo (a int)" +== 084 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 085 +-- truncate_limit: 100 +DROP TABLE trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_foo" +== 086 +-- truncate_limit: 100 +CREATE TABLE trans_bar (a int) +-- +TABLE: name="trans_bar" schema="" table="trans_bar" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_bar (a int)" +== 087 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 088 +-- truncate_limit: 100 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 089 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 090 +-- truncate_limit: 100 +CREATE TABLE trans_baz (a int) +-- +TABLE: name="trans_baz" schema="" table="trans_baz" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_baz (a int)" +== 091 +-- truncate_limit: 100 +RELEASE SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE two" +== 092 +-- truncate_limit: 100 +drop TABLE trans_foobar +-- +TABLE: name="trans_foobar" schema="" table="trans_foobar" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_foobar" +== 093 +-- truncate_limit: 100 +CREATE TABLE trans_barbaz (a int) +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_barbaz (a int)" +== 094 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 095 +-- truncate_limit: 100 +-- should exist: trans_barbaz, trans_baz, trans_foo +SELECT * FROM trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_foo" +== 096 +-- truncate_limit: 100 +-- should be empty +SELECT * FROM trans_bar +-- +TABLE: name="trans_bar" schema="" table="trans_bar" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_bar" +== 097 +-- truncate_limit: 100 +-- shouldn't exist +SELECT * FROM trans_barbaz +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_barbaz" +== 098 +-- truncate_limit: 100 +-- should be empty +SELECT * FROM trans_baz +-- +TABLE: name="trans_baz" schema="" table="trans_baz" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_baz" +== 099 +-- truncate_limit: 100 +-- should be empty + +-- inserts +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 100 +-- truncate_limit: 100 +INSERT INTO trans_foo VALUES (1) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_foo VALUES (1)" +== 101 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 102 +-- truncate_limit: 100 +INSERT into trans_bar VALUES (1) +-- +TABLE: name="trans_bar" schema="" table="trans_bar" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_bar VALUES (1)" +== 103 +-- truncate_limit: 100 +ROLLBACK TO one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 104 +-- truncate_limit: 100 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 105 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 106 +-- truncate_limit: 100 +INSERT into trans_barbaz VALUES (1) +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_barbaz VALUES (1)" +== 107 +-- truncate_limit: 100 +RELEASE two +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE two" +== 108 +-- truncate_limit: 100 +SAVEPOINT three +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT three" +== 109 +-- truncate_limit: 100 +SAVEPOINT four +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT four" +== 110 +-- truncate_limit: 100 +INSERT INTO trans_foo VALUES (2) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_foo VALUES (2)" +== 111 +-- truncate_limit: 100 +RELEASE SAVEPOINT four +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE four" +== 112 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT three +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT three" +== 113 +-- truncate_limit: 100 +RELEASE SAVEPOINT three +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE three" +== 114 +-- truncate_limit: 100 +INSERT INTO trans_foo VALUES (3) +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_foo VALUES (3)" +== 115 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 116 +-- truncate_limit: 100 +SELECT * FROM trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_foo" +== 117 +-- truncate_limit: 100 +-- should have 1 and 3 +SELECT * FROM trans_barbaz +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_barbaz" +== 118 +-- truncate_limit: 100 +-- should have 1 + +-- test whole-tree commit +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 119 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 120 +-- truncate_limit: 100 +SELECT trans_foo +-- +STMT: SelectStmt +TRUNCATED: "SELECT trans_foo" +== 121 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 122 +-- truncate_limit: 100 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 123 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 124 +-- truncate_limit: 100 +CREATE TABLE savepoints (a int) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE savepoints (a int)" +== 125 +-- truncate_limit: 100 +SAVEPOINT three +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT three" +== 126 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (1) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (1)" +== 127 +-- truncate_limit: 100 +SAVEPOINT four +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT four" +== 128 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (2) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (2)" +== 129 +-- truncate_limit: 100 +SAVEPOINT five +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT five" +== 130 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (3) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (3)" +== 131 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT five +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT five" +== 132 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 133 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 134 +-- truncate_limit: 100 +-- should not be in a transaction block +SELECT * FROM savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM savepoints" +== 135 +-- truncate_limit: 100 +-- test whole-tree rollback +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 136 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 137 +-- truncate_limit: 100 +DELETE FROM savepoints WHERE a=1 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM savepoints WHERE a = 1" +== 138 +-- truncate_limit: 100 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 139 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 140 +-- truncate_limit: 100 +DELETE FROM savepoints WHERE a=1 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM savepoints WHERE a = 1" +== 141 +-- truncate_limit: 100 +SAVEPOINT three +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT three" +== 142 +-- truncate_limit: 100 +DELETE FROM savepoints WHERE a=2 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM savepoints WHERE a = 2" +== 143 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 144 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 145 +-- truncate_limit: 100 +-- should not be in a transaction block + +SELECT * FROM savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM savepoints" +== 146 +-- truncate_limit: 100 +-- test whole-tree commit on an aborted subtransaction +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 147 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (4) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (4)" +== 148 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 149 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (5) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (5)" +== 150 +-- truncate_limit: 100 +SELECT trans_foo +-- +STMT: SelectStmt +TRUNCATED: "SELECT trans_foo" +== 151 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 152 +-- truncate_limit: 100 +SELECT * FROM savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM savepoints" +== 153 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 154 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (6) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (6)" +== 155 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 156 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (7) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (7)" +== 157 +-- truncate_limit: 100 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 158 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (8) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (8)" +== 159 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 160 +-- truncate_limit: 100 +-- rows 6 and 8 should have been created by the same xact +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=8 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +ALIAS: "a"="savepoints" +ALIAS: "b"="savepoints" +FILTER: schema="" table="a" column="a" +FILTER: schema="" table="b" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a = 6 AND b.a = 8" +== 161 +-- truncate_limit: 100 +-- rows 6 and 7 should have been created by different xacts +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=7 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +ALIAS: "a"="savepoints" +ALIAS: "b"="savepoints" +FILTER: schema="" table="a" column="a" +FILTER: schema="" table="b" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a = 6 AND b.a = 7" +== 162 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 163 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (9) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (9)" +== 164 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 165 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (10) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (10)" +== 166 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 167 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (11) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (11)" +== 168 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 169 +-- truncate_limit: 100 +SELECT a FROM savepoints WHERE a in (9, 10, 11) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM savepoints WHERE a IN (9, 10, 11)" +== 170 +-- truncate_limit: 100 +-- rows 9 and 11 should have been created by different xacts +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=9 AND b.a=11 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +ALIAS: "a"="savepoints" +ALIAS: "b"="savepoints" +FILTER: schema="" table="a" column="a" +FILTER: schema="" table="b" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a = 9 AND b.a = 11" +== 171 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 172 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (12) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (12)" +== 173 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 174 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (13) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (13)" +== 175 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 176 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (14) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (14)" +== 177 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 178 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (15) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (15)" +== 179 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 180 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (16) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (16)" +== 181 +-- truncate_limit: 100 +SAVEPOINT three +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT three" +== 182 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (17) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (17)" +== 183 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 184 +-- truncate_limit: 100 +SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17" +== 185 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 186 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (18) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (18)" +== 187 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 188 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (19) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (19)" +== 189 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 190 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (20) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (20)" +== 191 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 192 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (21) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (21)" +== 193 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 194 +-- truncate_limit: 100 +INSERT INTO savepoints VALUES (22) +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO savepoints VALUES (22)" +== 195 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 196 +-- truncate_limit: 100 +SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22 +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22" +== 197 +-- truncate_limit: 100 +DROP TABLE savepoints +-- +TABLE: name="savepoints" schema="" table="savepoints" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE savepoints" +== 198 +-- truncate_limit: 100 +-- only in a transaction block: +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 199 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 200 +-- truncate_limit: 100 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 201 +-- truncate_limit: 100 +-- Only "rollback to" allowed in aborted state +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 202 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 203 +-- truncate_limit: 100 +SELECT 0/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 0 / 0" +== 204 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 205 +-- truncate_limit: 100 +-- ignored till the end of ... + RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 206 +-- truncate_limit: 100 +-- ignored till the end of ... + ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 207 +-- truncate_limit: 100 +SELECT 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1" +== 208 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 209 +-- truncate_limit: 100 +SELECT 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1" +== 210 +-- truncate_limit: 100 +-- this should work + +-- check non-transactional behavior of cursors +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 211 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT unique2 FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT unique2 FROM tenk1 ORDER BY unique2" +== 212 +-- truncate_limit: 100 +SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT one" +== 213 +-- truncate_limit: 100 +FETCH 10 FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 10 c" +== 214 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT one" +== 215 +-- truncate_limit: 100 +FETCH 10 FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 10 c" +== 216 +-- truncate_limit: 100 +RELEASE SAVEPOINT one +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE one" +== 217 +-- truncate_limit: 100 +FETCH 10 FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 10 c" +== 218 +-- truncate_limit: 100 +CLOSE c +-- +STMT: ClosePortalStmt +TRUNCATED: "CLOSE c" +== 219 +-- truncate_limit: 100 +DECLARE c CURSOR FOR SELECT unique2/0 FROM tenk1 ORDER BY unique2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c CURSOR FOR SELECT unique2 / 0 FROM tenk1 ORDER BY unique2" +== 220 +-- truncate_limit: 100 +SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT two" +== 221 +-- truncate_limit: 100 +FETCH 10 FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 10 c" +== 222 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT two" +== 223 +-- truncate_limit: 100 +-- c is now dead to the world ... + FETCH 10 FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 10 c" +== 224 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT two" +== 225 +-- truncate_limit: 100 +RELEASE SAVEPOINT two +-- +STMT: TransactionStmt +TRUNCATED: "RELEASE two" +== 226 +-- truncate_limit: 100 +FETCH 10 FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH FORWARD 10 c" +== 227 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 228 +-- truncate_limit: 100 +|-- +-- Check that "stable" functions are really stable. They should not be +-- able to see the partial results of the calling query. (Ideally we would +-- also check that they don't see commits of concurrent transactions, but +-- that's a mite hard to do within the limitations of pg_regress.) +|-- +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xacttest" +== 229 +-- truncate_limit: 100 +create or replace function max_xacttest() returns smallint language sql as +'select max(a) from xacttest' stable +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION max_xacttest() RETURNS smallint LANGUAGE sql AS $$select max(a) from x..." +== 230 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 231 +-- truncate_limit: 100 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE xacttest SET a = max_xacttest() + 10 WHERE a > 0" +== 232 +-- truncate_limit: 100 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xacttest" +== 233 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 234 +-- truncate_limit: 100 +-- But a volatile function can see the partial results of the calling query +create or replace function max_xacttest() returns smallint language sql as +'select max(a) from xacttest' volatile +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION max_xacttest() RETURNS smallint LANGUAGE sql AS $$select max(a) from x..." +== 235 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 236 +-- truncate_limit: 100 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE xacttest SET a = max_xacttest() + 10 WHERE a > 0" +== 237 +-- truncate_limit: 100 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xacttest" +== 238 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 239 +-- truncate_limit: 100 +-- Now the same test with plpgsql (since it depends on SPI which is different) +create or replace function max_xacttest() returns smallint language plpgsql as +'begin return max(a) from xacttest; end' stable +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION max_xacttest() RETURNS smallint LANGUAGE plpgsql AS $$begin return max..." +== 240 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 241 +-- truncate_limit: 100 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE xacttest SET a = max_xacttest() + 10 WHERE a > 0" +== 242 +-- truncate_limit: 100 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xacttest" +== 243 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 244 +-- truncate_limit: 100 +create or replace function max_xacttest() returns smallint language plpgsql as +'begin return max(a) from xacttest; end' volatile +-- +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION max_xacttest() RETURNS smallint LANGUAGE plpgsql AS $$begin return max..." +== 245 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 246 +-- truncate_limit: 100 +update xacttest set a = max_xacttest() + 10 where a > 0 +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=DML +FUNCTION: name="max_xacttest" function="max_xacttest" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE xacttest SET a = max_xacttest() + 10 WHERE a > 0" +== 247 +-- truncate_limit: 100 +select * from xacttest +-- +TABLE: name="xacttest" schema="" table="xacttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xacttest" +== 248 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 249 +-- truncate_limit: 100 +-- test case for problems with dropping an open relation during abort +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 250 +-- truncate_limit: 100 +savepoint x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 251 +-- truncate_limit: 100 +CREATE TABLE koju (a INT UNIQUE) +-- +TABLE: name="koju" schema="" table="koju" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE koju (a int UNIQUE)" +== 252 +-- truncate_limit: 100 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO koju VALUES (1)" +== 253 +-- truncate_limit: 100 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO koju VALUES (1)" +== 254 +-- truncate_limit: 100 +rollback to x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 255 +-- truncate_limit: 100 +CREATE TABLE koju (a INT UNIQUE) +-- +TABLE: name="koju" schema="" table="koju" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE koju (a int UNIQUE)" +== 256 +-- truncate_limit: 100 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO koju VALUES (1)" +== 257 +-- truncate_limit: 100 +INSERT INTO koju VALUES (1) +-- +TABLE: name="koju" schema="" table="koju" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO koju VALUES (1)" +== 258 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 259 +-- truncate_limit: 100 +DROP TABLE trans_foo +-- +TABLE: name="trans_foo" schema="" table="trans_foo" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_foo" +== 260 +-- truncate_limit: 100 +DROP TABLE trans_baz +-- +TABLE: name="trans_baz" schema="" table="trans_baz" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_baz" +== 261 +-- truncate_limit: 100 +DROP TABLE trans_barbaz +-- +TABLE: name="trans_barbaz" schema="" table="trans_barbaz" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_barbaz" +== 262 +-- truncate_limit: 100 +-- test case for problems with revalidating an open relation during abort +create function inverse(int) returns float8 as +$$ +begin + analyze revalidate_bug; + return 1::float8/$1; +exception + when division_by_zero then return 0; +end$$ language plpgsql volatile +-- +FUNCTION: name="inverse" function="inverse" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION inverse(int) RETURNS float8 AS $$\nbegin\n analyze revalidate_bug;\n return 1::flo..." +== 263 +-- truncate_limit: 100 +create table revalidate_bug (c float8 unique) +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE revalidate_bug (c float8 UNIQUE)" +== 264 +-- truncate_limit: 100 +insert into revalidate_bug values (1) +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO revalidate_bug VALUES (1)" +== 265 +-- truncate_limit: 100 +insert into revalidate_bug values (inverse(0)) +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DML +FUNCTION: name="inverse" function="inverse" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO revalidate_bug VALUES (inverse(0))" +== 266 +-- truncate_limit: 100 +drop table revalidate_bug +-- +TABLE: name="revalidate_bug" schema="" table="revalidate_bug" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE revalidate_bug" +== 267 +-- truncate_limit: 100 +drop function inverse(int) +-- +FUNCTION: name="inverse" function="inverse" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION inverse(int)" +== 268 +-- truncate_limit: 100 +-- verify that cursors created during an aborted subtransaction are +-- closed, but that we do not rollback the effect of any FETCHs +-- performed in the aborted subtransaction +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 269 +-- truncate_limit: 100 +savepoint x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 270 +-- truncate_limit: 100 +create table trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_abc (a int)" +== 271 +-- truncate_limit: 100 +insert into trans_abc values (5) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (5)" +== 272 +-- truncate_limit: 100 +insert into trans_abc values (10) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (10)" +== 273 +-- truncate_limit: 100 +declare foo cursor for select * from trans_abc +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo CURSOR FOR SELECT * FROM trans_abc" +== 274 +-- truncate_limit: 100 +fetch from foo +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo" +== 275 +-- truncate_limit: 100 +rollback to x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 276 +-- truncate_limit: 100 +-- should fail +fetch from foo +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo" +== 277 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 278 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 279 +-- truncate_limit: 100 +create table trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_abc (a int)" +== 280 +-- truncate_limit: 100 +insert into trans_abc values (5) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (5)" +== 281 +-- truncate_limit: 100 +insert into trans_abc values (10) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (10)" +== 282 +-- truncate_limit: 100 +insert into trans_abc values (15) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (15)" +== 283 +-- truncate_limit: 100 +declare foo cursor for select * from trans_abc +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE foo CURSOR FOR SELECT * FROM trans_abc" +== 284 +-- truncate_limit: 100 +fetch from foo +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo" +== 285 +-- truncate_limit: 100 +savepoint x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 286 +-- truncate_limit: 100 +fetch from foo +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo" +== 287 +-- truncate_limit: 100 +rollback to x +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" +== 288 +-- truncate_limit: 100 +fetch from foo +-- +STMT: FetchStmt +TRUNCATED: "FETCH foo" +== 289 +-- truncate_limit: 100 +abort +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 290 +-- truncate_limit: 100 +-- Test for proper cleanup after a failure in a cursor portal +-- that was created in an outer subtransaction +CREATE FUNCTION invert(x float8) RETURNS float8 LANGUAGE plpgsql AS +$$ begin return 1/x; end $$ +-- +FUNCTION: name="invert" function="invert" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION invert(x float8) RETURNS float8 LANGUAGE plpgsql AS $$ begin return 1/x; end $$" +== 291 +-- truncate_limit: 100 +CREATE FUNCTION create_temp_tab() RETURNS text +LANGUAGE plpgsql AS $$ +BEGIN + CREATE TEMP TABLE new_table (f1 float8); + -- case of interest is that we fail while holding an open + -- relcache reference to new_table + INSERT INTO new_table SELECT invert(0.0); + RETURN 'foo'; +END $$ +-- +FUNCTION: name="create_temp_tab" function="create_temp_tab" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION create_temp_tab() RETURNS text LANGUAGE plpgsql AS $$\nBEGIN\n CREATE TEMP TABLE n..." +== 292 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 293 +-- truncate_limit: 100 +DECLARE ok CURSOR FOR SELECT * FROM int8_tbl +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE ok CURSOR FOR SELECT * FROM int8_tbl" +== 294 +-- truncate_limit: 100 +DECLARE ctt CURSOR FOR SELECT create_temp_tab() +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE ctt CURSOR FOR SELECT create_temp_tab()" +== 295 +-- truncate_limit: 100 +FETCH ok +-- +STMT: FetchStmt +TRUNCATED: "FETCH ok" +== 296 +-- truncate_limit: 100 +SAVEPOINT s1 +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT s1" +== 297 +-- truncate_limit: 100 +FETCH ok +-- +STMT: FetchStmt +TRUNCATED: "FETCH ok" +== 298 +-- truncate_limit: 100 +-- should work +FETCH ctt +-- +STMT: FetchStmt +TRUNCATED: "FETCH ctt" +== 299 +-- truncate_limit: 100 +-- error occurs here +ROLLBACK TO s1 +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT s1" +== 300 +-- truncate_limit: 100 +FETCH ok +-- +STMT: FetchStmt +TRUNCATED: "FETCH ok" +== 301 +-- truncate_limit: 100 +-- should work +FETCH ctt +-- +STMT: FetchStmt +TRUNCATED: "FETCH ctt" +== 302 +-- truncate_limit: 100 +-- must be rejected +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 303 +-- truncate_limit: 100 +DROP FUNCTION create_temp_tab() +-- +FUNCTION: name="create_temp_tab" function="create_temp_tab" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION create_temp_tab()" +== 304 +-- truncate_limit: 100 +DROP FUNCTION invert(x float8) +-- +FUNCTION: name="invert" function="invert" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION invert(x float8)" +== 305 +-- truncate_limit: 100 +-- Tests for AND CHAIN + +CREATE TABLE trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_abc (a int)" +== 306 +-- truncate_limit: 100 +-- set nondefault value so we have something to override below +SET default_transaction_read_only = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_transaction_read_only TO ON" +== 307 +-- truncate_limit: 100 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE" +== 308 +-- truncate_limit: 100 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 309 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 310 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 311 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (1) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (1)" +== 312 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (2) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (2)" +== 313 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 314 +-- truncate_limit: 100 +-- TBLOCK_END +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 315 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 316 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 317 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES ('error') +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES ('error')" +== 318 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (3) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (3)" +== 319 +-- truncate_limit: 100 +-- check it's really aborted +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 320 +-- truncate_limit: 100 +-- TBLOCK_ABORT_END +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 321 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 322 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 323 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (4) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (4)" +== 324 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 325 +-- truncate_limit: 100 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE" +== 326 +-- truncate_limit: 100 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 327 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 328 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 329 +-- truncate_limit: 100 +SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 330 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES ('error') +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES ('error')" +== 331 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 332 +-- truncate_limit: 100 +-- TBLOCK_ABORT_PENDING +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 333 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 334 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 335 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (5) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (5)" +== 336 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 337 +-- truncate_limit: 100 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE" +== 338 +-- truncate_limit: 100 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 339 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 340 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 341 +-- truncate_limit: 100 +SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 342 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 343 +-- truncate_limit: 100 +-- TBLOCK_SUBCOMMIT +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 344 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 345 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 346 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 347 +-- truncate_limit: 100 +START TRANSACTION ISOLATION LEVEL READ COMMITTED, READ WRITE, DEFERRABLE +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION ISOLATION LEVEL READ COMMITTED, READ WRITE, DEFERRABLE" +== 348 +-- truncate_limit: 100 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 349 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 350 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 351 +-- truncate_limit: 100 +SAVEPOINT x +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT x" +== 352 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 353 +-- truncate_limit: 100 +-- TBLOCK_SUBCOMMIT +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 354 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 355 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 356 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 357 +-- truncate_limit: 100 +-- different mix of options just for fun +START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE +-- +STMT: TransactionStmt +TRUNCATED: "START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE" +== 358 +-- truncate_limit: 100 +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 359 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 360 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 361 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (6) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES (6)" +== 362 +-- truncate_limit: 100 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK AND CHAIN" +== 363 +-- truncate_limit: 100 +-- TBLOCK_ABORT_PENDING +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 364 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 365 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 366 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES ('error') +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_abc VALUES ('error')" +== 367 +-- truncate_limit: 100 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK AND CHAIN" +== 368 +-- truncate_limit: 100 +-- TBLOCK_ABORT_END +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 369 +-- truncate_limit: 100 +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 370 +-- truncate_limit: 100 +SHOW transaction_deferrable +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_deferrable" +== 371 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 372 +-- truncate_limit: 100 +-- not allowed outside a transaction block +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 373 +-- truncate_limit: 100 +-- error +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK AND CHAIN" +== 374 +-- truncate_limit: 100 +-- error + +SELECT * FROM trans_abc ORDER BY 1 +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_abc ORDER BY 1" +== 375 +-- truncate_limit: 100 +RESET default_transaction_read_only +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_transaction_read_only" +== 376 +-- truncate_limit: 100 +DROP TABLE trans_abc +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_abc" +== 377 +-- truncate_limit: 100 +-- Test assorted behaviors around the implicit transaction block created +-- when multiple SQL commands are sent in a single Query message. These +-- tests rely on the fact that psql will not break SQL commands apart at a +-- backslash-quoted semicolon, but will send them as one Query. + +create temp table i_table (f1 int) +-- +TABLE: name="i_table" schema="" table="i_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE i_table (f1 int)" +== 378 +-- truncate_limit: 100 +-- psql will show all results of a multi-statement Query +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 66 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 379 +-- truncate_limit: 100 +SELECT 2\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 380 +-- truncate_limit: 100 +SELECT 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3" +== 381 +-- truncate_limit: 100 +-- this implicitly commits: +insert into i_table values(1)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 58 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 382 +-- truncate_limit: 100 +select * from i_table +-- +TABLE: name="i_table" schema="" table="i_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM i_table" +== 383 +-- truncate_limit: 100 +-- 1/0 error will cause rolling back the whole implicit transaction +insert into i_table values(2)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 98 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 384 +-- truncate_limit: 100 +select * from i_table\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 385 +-- truncate_limit: 100 +select 1/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0" +== 386 +-- truncate_limit: 100 +select * from i_table +-- +TABLE: name="i_table" schema="" table="i_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM i_table" +== 387 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 388 +-- truncate_limit: 100 +-- we are not in a transaction at this point + +-- can use regular begin/commit/rollback within a single Query +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 115 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 389 +-- truncate_limit: 100 +insert into i_table values(3)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 390 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 391 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 392 +-- truncate_limit: 100 +-- we are not in a transaction at this point +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 51 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 393 +-- truncate_limit: 100 +insert into i_table values(4)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 394 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 395 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 396 +-- truncate_limit: 100 +-- we are not in a transaction at this point + +-- begin converts implicit transaction into a regular one that +-- can extend past the end of the Query +select 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 158 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 397 +-- truncate_limit: 100 +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 398 +-- truncate_limit: 100 +insert into i_table values(5) +-- +TABLE: name="i_table" schema="" table="i_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO i_table VALUES (5)" +== 399 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 400 +-- truncate_limit: 100 +select 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 401 +-- truncate_limit: 100 +begin\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 402 +-- truncate_limit: 100 +insert into i_table values(6) +-- +TABLE: name="i_table" schema="" table="i_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO i_table VALUES (6)" +== 403 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 404 +-- truncate_limit: 100 +-- commit in implicit-transaction state commits but issues a warning. +insert into i_table values(7)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 100 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 405 +-- truncate_limit: 100 +commit\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 406 +-- truncate_limit: 100 +insert into i_table values(8)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 30 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 407 +-- truncate_limit: 100 +select 1/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0" +== 408 +-- truncate_limit: 100 +-- similarly, rollback aborts but issues a warning. +insert into i_table values(9)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 82 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 409 +-- truncate_limit: 100 +rollback\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 410 +-- truncate_limit: 100 +select 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2" +== 411 +-- truncate_limit: 100 +select * from i_table +-- +TABLE: name="i_table" schema="" table="i_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM i_table" +== 412 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 413 +-- truncate_limit: 100 +-- we are not in a transaction at this point + +-- implicit transaction block is still a transaction block, for e.g. VACUUM +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 131 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 414 +-- truncate_limit: 100 +VACUUM +-- +STMT: VacuumStmt +TRUNCATED: "VACUUM" +== 415 +-- truncate_limit: 100 +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 416 +-- truncate_limit: 100 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 417 +-- truncate_limit: 100 +VACUUM +-- +STMT: VacuumStmt +TRUNCATED: "VACUUM" +== 418 +-- truncate_limit: 100 +-- we disallow savepoint-related commands in implicit-transaction state +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 81 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 419 +-- truncate_limit: 100 +SAVEPOINT sp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp" +== 420 +-- truncate_limit: 100 +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 421 +-- truncate_limit: 100 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 422 +-- truncate_limit: 100 +SAVEPOINT sp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT sp" +== 423 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 424 +-- truncate_limit: 100 +SELECT 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 2" +== 425 +-- truncate_limit: 100 +SELECT 2\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 426 +-- truncate_limit: 100 +RELEASE SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 427 +-- truncate_limit: 100 +SELECT 3 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 3" +== 428 +-- truncate_limit: 100 +-- but this is OK, because the BEGIN converts it to a regular xact +SELECT 1\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 76 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 429 +-- truncate_limit: 100 +BEGIN\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 6 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 430 +-- truncate_limit: 100 +SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 13 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 431 +-- truncate_limit: 100 +ROLLBACK TO SAVEPOINT sp\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 432 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 433 +-- truncate_limit: 100 +-- Tests for AND CHAIN in implicit transaction blocks + +SET TRANSACTION READ ONLY\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 81 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 434 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 435 +-- truncate_limit: 100 +-- error +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 436 +-- truncate_limit: 100 +SET TRANSACTION READ ONLY\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 26 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 437 +-- truncate_limit: 100 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK AND CHAIN" +== 438 +-- truncate_limit: 100 +-- error +SHOW transaction_read_only +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW transaction_read_only" +== 439 +-- truncate_limit: 100 +CREATE TABLE trans_abc (a int) +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_abc (a int)" +== 440 +-- truncate_limit: 100 +-- COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +INSERT INTO trans_abc VALUES (7)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 80 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 441 +-- truncate_limit: 100 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 442 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (8)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 33 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 443 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 444 +-- truncate_limit: 100 +-- 7 commit, 8 error +INSERT INTO trans_abc VALUES (9)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 54 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 445 +-- truncate_limit: 100 +ROLLBACK\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 446 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (10)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 447 +-- truncate_limit: 100 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK AND CHAIN" +== 448 +-- truncate_limit: 100 +-- 9 rollback, 10 error + +-- COMMIT/ROLLBACK AND CHAIN + COMMIT/ROLLBACK +INSERT INTO trans_abc VALUES (11)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 106 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 449 +-- truncate_limit: 100 +COMMIT AND CHAIN\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 17 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 450 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (12)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 451 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 452 +-- truncate_limit: 100 +-- 11 error, 12 not reached +INSERT INTO trans_abc VALUES (13)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 62 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 453 +-- truncate_limit: 100 +ROLLBACK AND CHAIN\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 19 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 454 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (14)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 455 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 456 +-- truncate_limit: 100 +-- 13 error, 14 not reached + +-- START TRANSACTION + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 128 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 457 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (15)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 458 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 459 +-- truncate_limit: 100 +-- 15 ok +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 460 +-- truncate_limit: 100 +-- transaction is active at this point +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 461 +-- truncate_limit: 100 +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 50 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 462 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (16)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 463 +-- truncate_limit: 100 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK AND CHAIN" +== 464 +-- truncate_limit: 100 +-- 16 ok +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 465 +-- truncate_limit: 100 +-- transaction is active at this point +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 466 +-- truncate_limit: 100 +SET default_transaction_isolation = 'read committed' +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_transaction_isolation TO \"read committed\"" +== 467 +-- truncate_limit: 100 +-- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 117 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 468 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (17)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 469 +-- truncate_limit: 100 +COMMIT\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 7 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 470 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (18)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 471 +-- truncate_limit: 100 +COMMIT AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT AND CHAIN" +== 472 +-- truncate_limit: 100 +-- 17 commit, 18 error +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 473 +-- truncate_limit: 100 +-- out of transaction block + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 79 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 474 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (19)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 475 +-- truncate_limit: 100 +ROLLBACK\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 9 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 476 +-- truncate_limit: 100 +INSERT INTO trans_abc VALUES (20)\ +-- +ERROR: syntax error at or near "\" +CURSORPOS: 34 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 477 +-- truncate_limit: 100 +ROLLBACK AND CHAIN +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK AND CHAIN" +== 478 +-- truncate_limit: 100 +-- 19 rollback, 20 error +SHOW transaction_isolation +-- +STMT: VariableShowStmt +TRUNCATED: "SHOW TRANSACTION ISOLATION LEVEL" +== 479 +-- truncate_limit: 100 +-- out of transaction block + +RESET default_transaction_isolation +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_transaction_isolation" +== 480 +-- truncate_limit: 100 +SELECT * FROM trans_abc ORDER BY 1 +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trans_abc ORDER BY 1" +== 481 +-- truncate_limit: 100 +DROP TABLE trans_abc +-- +TABLE: name="trans_abc" schema="" table="trans_abc" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_abc" +== 482 +-- truncate_limit: 100 +-- TRANSACTION SNAPSHOT +-- Incorrect identifier. +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL REPEATABLE READ" +== 483 +-- truncate_limit: 100 +SET TRANSACTION SNAPSHOT 'Incorrect Identifier' +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION SNAPSHOT 'Incorrect Identifier'" +== 484 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 485 +-- truncate_limit: 100 +-- Correct identifier, missing file. +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL REPEATABLE READ" +== 486 +-- truncate_limit: 100 +SET TRANSACTION SNAPSHOT 'FFF-FFF-F' +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION SNAPSHOT 'FFF-FFF-F'" +== 487 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 488 +-- truncate_limit: 100 +-- Test for successful cleanup of an aborted transaction at session exit. +-- THIS MUST BE THE LAST TEST IN THIS FILE. + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 489 +-- truncate_limit: 100 +select 1/0 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 / 0" +== 490 +-- truncate_limit: 100 +rollback to X +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT x" diff --git a/parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json b/parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json new file mode 100644 index 0000000..a56f329 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json @@ -0,0 +1,1060 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/triggers.test b/parser/testdata/summary_truncate/postgres_regress/triggers.test new file mode 100644 index 0000000..78f069a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/triggers.test @@ -0,0 +1,9044 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TRIGGERS +|-- + +-- directory paths and dlsuffix are passed to us in environment variables + + +CREATE FUNCTION autoinc () + RETURNS trigger + AS :'autoinclib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 144 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 002 +-- truncate_limit: 100 +CREATE FUNCTION check_primary_key () + RETURNS trigger + AS :'refintlib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 59 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 003 +-- truncate_limit: 100 +CREATE FUNCTION check_foreign_key () + RETURNS trigger + AS :'refintlib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 59 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 004 +-- truncate_limit: 100 +CREATE FUNCTION trigger_return_old () + RETURNS trigger + AS :'regresslib' + LANGUAGE C +-- +ERROR: syntax error at or near ":" +CURSORPOS: 74 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 005 +-- truncate_limit: 100 +CREATE FUNCTION set_ttdummy (int4) + RETURNS int4 + AS :'regresslib' + LANGUAGE C STRICT +-- +ERROR: syntax error at or near ":" +CURSORPOS: 68 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 006 +-- truncate_limit: 100 +create table pkeys (pkey1 int4 not null, pkey2 text not null) +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pkeys (pkey1 int4 NOT NULL, pkey2 text NOT NULL)" +== 007 +-- truncate_limit: 100 +create table fkeys (fkey1 int4, fkey2 text, fkey3 int) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkeys (fkey1 int4, fkey2 text, fkey3 int)" +== 008 +-- truncate_limit: 100 +create table fkeys2 (fkey21 int4, fkey22 text, pkey23 int not null) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE fkeys2 (fkey21 int4, fkey22 text, pkey23 int NOT NULL)" +== 009 +-- truncate_limit: 100 +create index fkeys_i on fkeys (fkey1, fkey2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fkeys_i ON fkeys USING btree (fkey1, fkey2)" +== 010 +-- truncate_limit: 100 +create index fkeys2_i on fkeys2 (fkey21, fkey22) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fkeys2_i ON fkeys2 USING btree (fkey21, fkey22)" +== 011 +-- truncate_limit: 100 +create index fkeys2p_i on fkeys2 (pkey23) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX fkeys2p_i ON fkeys2 USING btree (pkey23)" +== 012 +-- truncate_limit: 100 +insert into pkeys values (10, '1') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pkeys VALUES (10, '1')" +== 013 +-- truncate_limit: 100 +insert into pkeys values (20, '2') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pkeys VALUES (20, '2')" +== 014 +-- truncate_limit: 100 +insert into pkeys values (30, '3') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pkeys VALUES (30, '3')" +== 015 +-- truncate_limit: 100 +insert into pkeys values (40, '4') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pkeys VALUES (40, '4')" +== 016 +-- truncate_limit: 100 +insert into pkeys values (50, '5') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pkeys VALUES (50, '5')" +== 017 +-- truncate_limit: 100 +insert into pkeys values (60, '6') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pkeys VALUES (60, '6')" +== 018 +-- truncate_limit: 100 +create unique index pkeys_i on pkeys (pkey1, pkey2) +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX pkeys_i ON pkeys USING btree (pkey1, pkey2)" +== 019 +-- truncate_limit: 100 +|-- +-- For fkeys: +-- (fkey1, fkey2) --> pkeys (pkey1, pkey2) +-- (fkey3) --> fkeys2 (pkey23) +|-- +create trigger check_fkeys_pkey_exist + before insert or update on fkeys + for each row + execute function + check_primary_key ('fkey1', 'fkey2', 'pkeys', 'pkey1', 'pkey2') +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER check_fkeys_pkey_exist BEFORE INSERT OR UPDATE ON fkeys FOR EACH ROW EXECUTE FUNCT..." +== 020 +-- truncate_limit: 100 +create trigger check_fkeys_pkey2_exist + before insert or update on fkeys + for each row + execute function check_primary_key ('fkey3', 'fkeys2', 'pkey23') +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER check_fkeys_pkey2_exist BEFORE INSERT OR UPDATE ON fkeys FOR EACH ROW EXECUTE FUNC..." +== 021 +-- truncate_limit: 100 +|-- +-- For fkeys2: +-- (fkey21, fkey22) --> pkeys (pkey1, pkey2) +|-- +create trigger check_fkeys2_pkey_exist + before insert or update on fkeys2 + for each row + execute procedure + check_primary_key ('fkey21', 'fkey22', 'pkeys', 'pkey1', 'pkey2') +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER check_fkeys2_pkey_exist BEFORE INSERT OR UPDATE ON fkeys2 FOR EACH ROW EXECUTE FUN..." +== 022 +-- truncate_limit: 100 +-- Test comments +COMMENT ON TRIGGER check_fkeys2_pkey_bad ON fkeys2 IS 'wrong' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TRIGGER check_fkeys2_pkey_bad ON fkeys2 IS 'wrong'" +== 023 +-- truncate_limit: 100 +COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS 'right' +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS 'right'" +== 024 +-- truncate_limit: 100 +COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS NULL +-- +STMT: CommentStmt +TRUNCATED: "COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS NULL" +== 025 +-- truncate_limit: 100 +|-- +-- For pkeys: +-- ON DELETE/UPDATE (pkey1, pkey2) CASCADE: +-- fkeys (fkey1, fkey2) and fkeys2 (fkey21, fkey22) +|-- +create trigger check_pkeys_fkey_cascade + before delete or update on pkeys + for each row + execute procedure + check_foreign_key (2, 'cascade', 'pkey1', 'pkey2', + 'fkeys', 'fkey1', 'fkey2', 'fkeys2', 'fkey21', 'fkey22') +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER check_pkeys_fkey_cascade BEFORE DELETE OR UPDATE ON pkeys FOR EACH ROW EXECUTE FUN..." +== 026 +-- truncate_limit: 100 +|-- +-- For fkeys2: +-- ON DELETE/UPDATE (pkey23) RESTRICT: +-- fkeys (fkey3) +|-- +create trigger check_fkeys2_fkey_restrict + before delete or update on fkeys2 + for each row + execute procedure check_foreign_key (1, 'restrict', 'pkey23', 'fkeys', 'fkey3') +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER check_fkeys2_fkey_restrict BEFORE DELETE OR UPDATE ON fkeys2 FOR EACH ROW EXECUTE ..." +== 027 +-- truncate_limit: 100 +insert into fkeys2 values (10, '1', 1) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys2 VALUES (10, '1', 1)" +== 028 +-- truncate_limit: 100 +insert into fkeys2 values (30, '3', 2) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys2 VALUES (30, '3', 2)" +== 029 +-- truncate_limit: 100 +insert into fkeys2 values (40, '4', 5) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys2 VALUES (40, '4', 5)" +== 030 +-- truncate_limit: 100 +insert into fkeys2 values (50, '5', 3) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys2 VALUES (50, '5', 3)" +== 031 +-- truncate_limit: 100 +-- no key in pkeys +insert into fkeys2 values (70, '5', 3) +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys2 VALUES (70, '5', 3)" +== 032 +-- truncate_limit: 100 +insert into fkeys values (10, '1', 2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys VALUES (10, '1', 2)" +== 033 +-- truncate_limit: 100 +insert into fkeys values (30, '3', 3) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys VALUES (30, '3', 3)" +== 034 +-- truncate_limit: 100 +insert into fkeys values (40, '4', 2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys VALUES (40, '4', 2)" +== 035 +-- truncate_limit: 100 +insert into fkeys values (50, '5', 2) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys VALUES (50, '5', 2)" +== 036 +-- truncate_limit: 100 +-- no key in pkeys +insert into fkeys values (70, '5', 1) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys VALUES (70, '5', 1)" +== 037 +-- truncate_limit: 100 +-- no key in fkeys2 +insert into fkeys values (60, '6', 4) +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fkeys VALUES (60, '6', 4)" +== 038 +-- truncate_limit: 100 +delete from pkeys where pkey1 = 30 and pkey2 = '3' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pkeys WHERE pkey1 = 30 AND pkey2 = '3'" +== 039 +-- truncate_limit: 100 +delete from pkeys where pkey1 = 40 and pkey2 = '4' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pkeys WHERE pkey1 = 40 AND pkey2 = '4'" +== 040 +-- truncate_limit: 100 +update pkeys set pkey1 = 7, pkey2 = '70' where pkey1 = 50 and pkey2 = '5' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pkeys SET pkey1 = 7, pkey2 = '70' WHERE pkey1 = 50 AND pkey2 = '5'" +== 041 +-- truncate_limit: 100 +update pkeys set pkey1 = 7, pkey2 = '70' where pkey1 = 10 and pkey2 = '1' +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pkeys SET pkey1 = 7, pkey2 = '70' WHERE pkey1 = 10 AND pkey2 = '1'" +== 042 +-- truncate_limit: 100 +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table in ('pkeys', 'fkeys', 'fkeys2') + ORDER BY trigger_name COLLATE "C", 2 +-- +TABLE: name="information_schema.triggers" schema="information_schema" table="triggers" ctx=Select +FILTER: schema="" table="" column="event_object_table" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.triggers WHERE ... ORDER BY trigger_name COLLATE \"C\", 2" +== 043 +-- truncate_limit: 100 +DROP TABLE pkeys +-- +TABLE: name="pkeys" schema="" table="pkeys" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pkeys" +== 044 +-- truncate_limit: 100 +DROP TABLE fkeys +-- +TABLE: name="fkeys" schema="" table="fkeys" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fkeys" +== 045 +-- truncate_limit: 100 +DROP TABLE fkeys2 +-- +TABLE: name="fkeys2" schema="" table="fkeys2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fkeys2" +== 046 +-- truncate_limit: 100 +-- Check behavior when trigger returns unmodified trigtuple +create table trigtest (f1 int, f2 text) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigtest (f1 int, f2 text)" +== 047 +-- truncate_limit: 100 +create trigger trigger_return_old + before insert or delete or update on trigtest + for each row execute procedure trigger_return_old() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigger_return_old BEFORE INSERT OR DELETE OR UPDATE ON trigtest FOR EACH ROW EXEC..." +== 048 +-- truncate_limit: 100 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigtest VALUES (1, 'foo')" +== 049 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 050 +-- truncate_limit: 100 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigtest SET f2 = f2 || 'bar'" +== 051 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 052 +-- truncate_limit: 100 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trigtest" +== 053 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 054 +-- truncate_limit: 100 +-- Also check what happens when such a trigger runs before or after others +create function f1_times_10() returns trigger as +$$ begin new.f1 := new.f1 * 10; return new; end $$ language plpgsql +-- +FUNCTION: name="f1_times_10" function="f1_times_10" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f1_times_10() RETURNS trigger AS $$ begin new.f1 := new.f1 * 10; return new; end ..." +== 055 +-- truncate_limit: 100 +create trigger trigger_alpha + before insert or update on trigtest + for each row execute procedure f1_times_10() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigger_alpha BEFORE INSERT OR UPDATE ON trigtest FOR EACH ROW EXECUTE FUNCTION f1..." +== 056 +-- truncate_limit: 100 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigtest VALUES (1, 'foo')" +== 057 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 058 +-- truncate_limit: 100 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigtest SET f2 = f2 || 'bar'" +== 059 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 060 +-- truncate_limit: 100 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trigtest" +== 061 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 062 +-- truncate_limit: 100 +create trigger trigger_zed + before insert or update on trigtest + for each row execute procedure f1_times_10() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigger_zed BEFORE INSERT OR UPDATE ON trigtest FOR EACH ROW EXECUTE FUNCTION f1_t..." +== 063 +-- truncate_limit: 100 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigtest VALUES (1, 'foo')" +== 064 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 065 +-- truncate_limit: 100 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigtest SET f2 = f2 || 'bar'" +== 066 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 067 +-- truncate_limit: 100 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trigtest" +== 068 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 069 +-- truncate_limit: 100 +drop trigger trigger_alpha on trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trigger_alpha ON trigtest" +== 070 +-- truncate_limit: 100 +insert into trigtest values(1, 'foo') +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigtest VALUES (1, 'foo')" +== 071 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 072 +-- truncate_limit: 100 +update trigtest set f2 = f2 || 'bar' +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigtest SET f2 = f2 || 'bar'" +== 073 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 074 +-- truncate_limit: 100 +delete from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trigtest" +== 075 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 076 +-- truncate_limit: 100 +drop table trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigtest" +== 077 +-- truncate_limit: 100 +-- Check behavior with an implicit column default, too (bug #16644) +create table trigtest ( + a integer, + b bool default true not null, + c text default 'xyzzy' not null) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigtest (a int, b bool DEFAULT true NOT NULL, c text DEFAULT 'xyzzy' NOT NULL)" +== 078 +-- truncate_limit: 100 +create trigger trigger_return_old + before insert or delete or update on trigtest + for each row execute procedure trigger_return_old() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigger_return_old BEFORE INSERT OR DELETE OR UPDATE ON trigtest FOR EACH ROW EXEC..." +== 079 +-- truncate_limit: 100 +insert into trigtest values(1) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigtest VALUES (1)" +== 080 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 081 +-- truncate_limit: 100 +alter table trigtest add column d integer default 42 not null +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigtest ADD COLUMN d int DEFAULT 42 NOT NULL" +== 082 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 083 +-- truncate_limit: 100 +update trigtest set a = 2 where a = 1 returning * +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigtest SET a = 2 WHERE a = 1 RETURNING *" +== 084 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 085 +-- truncate_limit: 100 +alter table trigtest drop column b +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigtest DROP b" +== 086 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 087 +-- truncate_limit: 100 +update trigtest set a = 2 where a = 1 returning * +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigtest SET a = 2 WHERE a = 1 RETURNING *" +== 088 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 089 +-- truncate_limit: 100 +drop table trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigtest" +== 090 +-- truncate_limit: 100 +create sequence ttdummy_seq increment 10 start 0 minvalue 0 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE ttdummy_seq INCREMENT 10 START 0 MINVALUE 0" +== 091 +-- truncate_limit: 100 +create table tttest ( + price_id int4, + price_val int4, + price_on int4, + price_off int4 default 999999 +) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tttest (price_id int4, price_val int4, price_on int4, price_off int4 DEFAULT 999999)" +== 092 +-- truncate_limit: 100 +create trigger ttdummy + before delete or update on tttest + for each row + execute procedure + ttdummy (price_on, price_off) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER ttdummy BEFORE DELETE OR UPDATE ON tttest FOR EACH ROW EXECUTE FUNCTION ttdummy('p..." +== 093 +-- truncate_limit: 100 +create trigger ttserial + before insert or update on tttest + for each row + execute procedure + autoinc (price_on, ttdummy_seq) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER ttserial BEFORE INSERT OR UPDATE ON tttest FOR EACH ROW EXECUTE FUNCTION autoinc('..." +== 094 +-- truncate_limit: 100 +insert into tttest values (1, 1, null) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tttest VALUES (1, 1, NULL)" +== 095 +-- truncate_limit: 100 +insert into tttest values (2, 2, null) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tttest VALUES (2, 2, NULL)" +== 096 +-- truncate_limit: 100 +insert into tttest values (3, 3, 0) +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tttest VALUES (3, 3, 0)" +== 097 +-- truncate_limit: 100 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest" +== 098 +-- truncate_limit: 100 +delete from tttest where price_id = 2 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tttest WHERE price_id = 2" +== 099 +-- truncate_limit: 100 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest" +== 100 +-- truncate_limit: 100 +-- what do we see ? + +-- get current prices +select * from tttest where price_off = 999999 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +FILTER: schema="" table="" column="price_off" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest WHERE price_off = 999999" +== 101 +-- truncate_limit: 100 +-- change price for price_id == 3 +update tttest set price_val = 30 where price_id = 3 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tttest SET price_val = 30 WHERE price_id = 3" +== 102 +-- truncate_limit: 100 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest" +== 103 +-- truncate_limit: 100 +-- now we want to change pric_id in ALL tuples +-- this gets us not what we need +update tttest set price_id = 5 where price_id = 3 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tttest SET price_id = 5 WHERE price_id = 3" +== 104 +-- truncate_limit: 100 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest" +== 105 +-- truncate_limit: 100 +-- restore data as before last update: +select set_ttdummy(0) +-- +FUNCTION: name="set_ttdummy" function="set_ttdummy" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_ttdummy(0)" +== 106 +-- truncate_limit: 100 +delete from tttest where price_id = 5 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM tttest WHERE price_id = 5" +== 107 +-- truncate_limit: 100 +update tttest set price_off = 999999 where price_val = 30 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tttest SET price_off = 999999 WHERE price_val = 30" +== 108 +-- truncate_limit: 100 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest" +== 109 +-- truncate_limit: 100 +-- and try change price_id now! +update tttest set price_id = 5 where price_id = 3 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tttest SET price_id = 5 WHERE price_id = 3" +== 110 +-- truncate_limit: 100 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest" +== 111 +-- truncate_limit: 100 +-- isn't it what we need ? + +select set_ttdummy(1) +-- +FUNCTION: name="set_ttdummy" function="set_ttdummy" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_ttdummy(1)" +== 112 +-- truncate_limit: 100 +-- we want to correct some "date" +update tttest set price_on = -1 where price_id = 1 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tttest SET price_on = -1 WHERE price_id = 1" +== 113 +-- truncate_limit: 100 +-- but this doesn't work + +-- try in this way +select set_ttdummy(0) +-- +FUNCTION: name="set_ttdummy" function="set_ttdummy" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT set_ttdummy(0)" +== 114 +-- truncate_limit: 100 +update tttest set price_on = -1 where price_id = 1 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE tttest SET price_on = -1 WHERE price_id = 1" +== 115 +-- truncate_limit: 100 +select * from tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest" +== 116 +-- truncate_limit: 100 +-- isn't it what we need ? + +-- get price for price_id == 5 as it was @ "date" 35 +select * from tttest where price_on <= 35 and price_off > 35 and price_id = 5 +-- +TABLE: name="tttest" schema="" table="tttest" ctx=Select +FILTER: schema="" table="" column="price_on" +FILTER: schema="" table="" column="price_off" +FILTER: schema="" table="" column="price_id" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tttest WHERE price_on <= 35 AND price_off > 35 AND price_id = 5" +== 117 +-- truncate_limit: 100 +drop table tttest +-- +TABLE: name="tttest" schema="" table="tttest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tttest" +== 118 +-- truncate_limit: 100 +drop sequence ttdummy_seq +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE ttdummy_seq" +== 119 +-- truncate_limit: 100 +|-- +-- tests for per-statement triggers +|-- + +CREATE TABLE log_table (tstamp timestamp default timeofday()::timestamp) +-- +TABLE: name="log_table" schema="" table="log_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE log_table (tstamp timestamp DEFAULT (timeofday()::timestamp))" +== 120 +-- truncate_limit: 100 +CREATE TABLE main_table (a int unique, b int) +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE main_table (a int UNIQUE, b int)" +== 121 +-- truncate_limit: 100 +COPY main_table (a,b) FROM stdin +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY main_table(a, b) FROM STDIN" +== 122 +-- truncate_limit: 100 +CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS ' +BEGIN + RAISE NOTICE ''trigger_func(%) called: action = %, when = %, level = %'', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; + RETURN NULL; +END;' +-- +FUNCTION: name="trigger_func" function="trigger_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS $$\nBEGIN\n\tRAISE NOTICE 'trigge..." +== 123 +-- truncate_limit: 100 +CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_ins_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_table EXECUTE FUNCTION trigger_func('be..." +== 124 +-- truncate_limit: 100 +CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_ins_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_table EXECUTE FUNCTION trigger_func('afte..." +== 125 +-- truncate_limit: 100 +|-- +-- if neither 'FOR EACH ROW' nor 'FOR EACH STATEMENT' was specified, +-- CREATE TRIGGER should default to 'FOR EACH STATEMENT' +|-- +CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_table +EXECUTE PROCEDURE trigger_func('after_upd_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_table EXECUTE FUNCTION trigger_func('afte..." +== 126 +-- truncate_limit: 100 +-- Both insert and update statement level triggers (before and after) should +-- fire. Doesn't fire UPDATE before trigger, but only because one isn't +-- defined. +INSERT INTO main_table (a, b) VALUES (5, 10) ON CONFLICT (a) + DO UPDATE SET b = EXCLUDED.b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO main_table (a, b) VALUES (5, 10) ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 127 +-- truncate_limit: 100 +CREATE TRIGGER after_upd_row_trig AFTER UPDATE ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_upd_row_trig AFTER UPDATE ON main_table FOR EACH ROW EXECUTE FUNCTION trigge..." +== 128 +-- truncate_limit: 100 +INSERT INTO main_table DEFAULT VALUES +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO main_table DEFAULT VALUES" +== 129 +-- truncate_limit: 100 +UPDATE main_table SET a = a + 1 WHERE b < 30 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_table SET a = a + 1 WHERE b < 30" +== 130 +-- truncate_limit: 100 +-- UPDATE that effects zero rows should still call per-statement trigger +UPDATE main_table SET a = a + 2 WHERE b > 100 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_table SET a = a + 2 WHERE b > 100" +== 131 +-- truncate_limit: 100 +-- constraint now unneeded +ALTER TABLE main_table DROP CONSTRAINT main_table_a_key +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE main_table DROP CONSTRAINT main_table_a_key" +== 132 +-- truncate_limit: 100 +-- COPY should fire per-row and per-statement INSERT triggers +COPY main_table (a, b) FROM stdin +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY main_table(a, b) FROM STDIN" +== 133 +-- truncate_limit: 100 +SELECT * FROM main_table ORDER BY a, b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM main_table ORDER BY a, b" +== 134 +-- truncate_limit: 100 +|-- +-- test triggers with WHEN clause +|-- + +CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) EXECUTE PROCEDURE trigger_func('modified_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.a <> new.a) EXE..." +== 135 +-- truncate_limit: 100 +CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table +FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) EXECUTE PROCEDURE trigger_func('modified_any') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.* IS DISTINCT..." +== 136 +-- truncate_limit: 100 +CREATE TRIGGER insert_a AFTER INSERT ON main_table +FOR EACH ROW WHEN (NEW.a = 123) EXECUTE PROCEDURE trigger_func('insert_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER insert_a AFTER INSERT ON main_table FOR EACH ROW WHEN (new.a = 123) EXECUTE FUNCTI..." +== 137 +-- truncate_limit: 100 +CREATE TRIGGER delete_a AFTER DELETE ON main_table +FOR EACH ROW WHEN (OLD.a = 123) EXECUTE PROCEDURE trigger_func('delete_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER delete_a AFTER DELETE ON main_table FOR EACH ROW WHEN (old.a = 123) EXECUTE FUNCTI..." +== 138 +-- truncate_limit: 100 +CREATE TRIGGER insert_when BEFORE INSERT ON main_table +FOR EACH STATEMENT WHEN (true) EXECUTE PROCEDURE trigger_func('insert_when') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER insert_when BEFORE INSERT ON main_table WHEN (true) EXECUTE FUNCTION trigger_func(..." +== 139 +-- truncate_limit: 100 +CREATE TRIGGER delete_when AFTER DELETE ON main_table +FOR EACH STATEMENT WHEN (true) EXECUTE PROCEDURE trigger_func('delete_when') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER delete_when AFTER DELETE ON main_table WHEN (true) EXECUTE FUNCTION trigger_func('..." +== 140 +-- truncate_limit: 100 +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table IN ('main_table') + ORDER BY trigger_name COLLATE "C", 2 +-- +TABLE: name="information_schema.triggers" schema="information_schema" table="triggers" ctx=Select +FILTER: schema="" table="" column="event_object_table" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.triggers WHERE ... ORDER BY trigger_name COLLATE \"C\", 2" +== 141 +-- truncate_limit: 100 +INSERT INTO main_table (a) VALUES (123), (456) +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO main_table (a) VALUES (123), (456)" +== 142 +-- truncate_limit: 100 +COPY main_table FROM stdin +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY main_table FROM STDIN" +== 143 +-- truncate_limit: 100 +DELETE FROM main_table WHERE a IN (123, 456) +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM main_table WHERE a IN (123, 456)" +== 144 +-- truncate_limit: 100 +UPDATE main_table SET a = 50, b = 60 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_table SET a = 50, b = 60" +== 145 +-- truncate_limit: 100 +SELECT * FROM main_table ORDER BY a, b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM main_table ORDER BY a, b" +== 146 +-- truncate_limit: 100 +SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE ..." +== 147 +-- truncate_limit: 100 +SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE ..." +== 148 +-- truncate_limit: 100 +SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE ..." +== 149 +-- truncate_limit: 100 +-- Test RENAME TRIGGER +ALTER TRIGGER modified_a ON main_table RENAME TO modified_modified_a +-- +STMT: RenameStmt +TRUNCATED: "ALTER TRIGGER modified_a ON main_table RENAME TO modified_modified_a" +== 150 +-- truncate_limit: 100 +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'" +== 151 +-- truncate_limit: 100 +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_modified_a' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_trigger WHERE ..." +== 152 +-- truncate_limit: 100 +DROP TRIGGER modified_modified_a ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER modified_modified_a ON main_table" +== 153 +-- truncate_limit: 100 +DROP TRIGGER modified_any ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER modified_any ON main_table" +== 154 +-- truncate_limit: 100 +DROP TRIGGER insert_a ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER insert_a ON main_table" +== 155 +-- truncate_limit: 100 +DROP TRIGGER delete_a ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER delete_a ON main_table" +== 156 +-- truncate_limit: 100 +DROP TRIGGER insert_when ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER insert_when ON main_table" +== 157 +-- truncate_limit: 100 +DROP TRIGGER delete_when ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER delete_when ON main_table" +== 158 +-- truncate_limit: 100 +-- Test WHEN condition accessing system columns. +create table table_with_oids(a int) +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE table_with_oids (a int)" +== 159 +-- truncate_limit: 100 +insert into table_with_oids values (1) +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO table_with_oids VALUES (1)" +== 160 +-- truncate_limit: 100 +create trigger oid_unchanged_trig after update on table_with_oids + for each row + when (new.tableoid = old.tableoid AND new.tableoid <> 0) + execute procedure trigger_func('after_upd_oid_unchanged') +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER oid_unchanged_trig AFTER UPDATE ON table_with_oids FOR EACH ROW WHEN (new.tableoid..." +== 161 +-- truncate_limit: 100 +update table_with_oids set a = a + 1 +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE table_with_oids SET a = a + 1" +== 162 +-- truncate_limit: 100 +drop table table_with_oids +-- +TABLE: name="table_with_oids" schema="" table="table_with_oids" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE table_with_oids" +== 163 +-- truncate_limit: 100 +-- Test column-level triggers +DROP TRIGGER after_upd_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER after_upd_row_trig ON main_table" +== 164 +-- truncate_limit: 100 +CREATE TRIGGER before_upd_a_row_trig BEFORE UPDATE OF a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_a_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_upd_a_row_trig BEFORE UPDATE OF a ON main_table FOR EACH ROW EXECUTE FUNCTI..." +== 165 +-- truncate_limit: 100 +CREATE TRIGGER after_upd_b_row_trig AFTER UPDATE OF b ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_b_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_upd_b_row_trig AFTER UPDATE OF b ON main_table FOR EACH ROW EXECUTE FUNCTION..." +== 166 +-- truncate_limit: 100 +CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_a_b_row') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON main_table FOR EACH ROW EXECUTE FUN..." +== 167 +-- truncate_limit: 100 +CREATE TRIGGER before_upd_a_stmt_trig BEFORE UPDATE OF a ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_upd_a_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_upd_a_stmt_trig BEFORE UPDATE OF a ON main_table EXECUTE FUNCTION trigger_f..." +== 168 +-- truncate_limit: 100 +CREATE TRIGGER after_upd_b_stmt_trig AFTER UPDATE OF b ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_upd_b_stmt') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_upd_b_stmt_trig AFTER UPDATE OF b ON main_table EXECUTE FUNCTION trigger_fun..." +== 169 +-- truncate_limit: 100 +SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'after_upd_a_b_row_trig' +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="pg_get_triggerdef" function="pg_get_triggerdef" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE ..." +== 170 +-- truncate_limit: 100 +UPDATE main_table SET a = 50 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_table SET a = 50" +== 171 +-- truncate_limit: 100 +UPDATE main_table SET b = 10 +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_table SET b = 10" +== 172 +-- truncate_limit: 100 +|-- +-- Test case for bug with BEFORE trigger followed by AFTER trigger with WHEN +|-- + +CREATE TABLE some_t (some_col boolean NOT NULL) +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE some_t (some_col boolean NOT NULL)" +== 173 +-- truncate_limit: 100 +CREATE FUNCTION dummy_update_func() RETURNS trigger AS $$ +BEGIN + RAISE NOTICE 'dummy_update_func(%) called: action = %, old = %, new = %', + TG_ARGV[0], TG_OP, OLD, NEW; + RETURN NEW; +END; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="dummy_update_func" function="dummy_update_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION dummy_update_func() RETURNS trigger AS $$\nBEGIN\n RAISE NOTICE 'dummy_update_func..." +== 174 +-- truncate_limit: 100 +CREATE TRIGGER some_trig_before BEFORE UPDATE ON some_t FOR EACH ROW + EXECUTE PROCEDURE dummy_update_func('before') +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER some_trig_before BEFORE UPDATE ON some_t FOR EACH ROW EXECUTE FUNCTION dummy_updat..." +== 175 +-- truncate_limit: 100 +CREATE TRIGGER some_trig_aftera AFTER UPDATE ON some_t FOR EACH ROW + WHEN (NOT OLD.some_col AND NEW.some_col) + EXECUTE PROCEDURE dummy_update_func('aftera') +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER some_trig_aftera AFTER UPDATE ON some_t FOR EACH ROW WHEN (NOT old.some_col AND ne..." +== 176 +-- truncate_limit: 100 +CREATE TRIGGER some_trig_afterb AFTER UPDATE ON some_t FOR EACH ROW + WHEN (NOT NEW.some_col) + EXECUTE PROCEDURE dummy_update_func('afterb') +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER some_trig_afterb AFTER UPDATE ON some_t FOR EACH ROW WHEN (NOT new.some_col) EXECU..." +== 177 +-- truncate_limit: 100 +INSERT INTO some_t VALUES (TRUE) +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO some_t VALUES (true)" +== 178 +-- truncate_limit: 100 +UPDATE some_t SET some_col = TRUE +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE some_t SET some_col = true" +== 179 +-- truncate_limit: 100 +UPDATE some_t SET some_col = FALSE +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE some_t SET some_col = false" +== 180 +-- truncate_limit: 100 +UPDATE some_t SET some_col = TRUE +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE some_t SET some_col = true" +== 181 +-- truncate_limit: 100 +DROP TABLE some_t +-- +TABLE: name="some_t" schema="" table="some_t" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE some_t" +== 182 +-- truncate_limit: 100 +-- bogus cases +CREATE TRIGGER error_upd_and_col BEFORE UPDATE OR UPDATE OF a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('error_upd_and_col') +-- +ERROR: duplicate trigger events specified at or near "ON" +CURSORPOS: 78 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 183 +-- truncate_limit: 100 +CREATE TRIGGER error_upd_a_a BEFORE UPDATE OF a, a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('error_upd_a_a') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER error_upd_a_a BEFORE UPDATE OF a, a ON main_table FOR EACH ROW EXECUTE FUNCTION tr..." +== 184 +-- truncate_limit: 100 +CREATE TRIGGER error_ins_a BEFORE INSERT OF a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('error_ins_a') +-- +ERROR: syntax error at or near "OF" +CURSORPOS: 42 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 185 +-- truncate_limit: 100 +CREATE TRIGGER error_ins_when BEFORE INSERT OR UPDATE ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) +EXECUTE PROCEDURE trigger_func('error_ins_old') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER error_ins_when BEFORE INSERT OR UPDATE ON main_table FOR EACH ROW WHEN (old.a <> n..." +== 186 +-- truncate_limit: 100 +CREATE TRIGGER error_del_when BEFORE DELETE OR UPDATE ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) +EXECUTE PROCEDURE trigger_func('error_del_new') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER error_del_when BEFORE DELETE OR UPDATE ON main_table FOR EACH ROW WHEN (old.a <> n..." +== 187 +-- truncate_limit: 100 +CREATE TRIGGER error_del_when BEFORE INSERT OR UPDATE ON main_table +FOR EACH ROW WHEN (NEW.tableoid <> 0) +EXECUTE PROCEDURE trigger_func('error_when_sys_column') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER error_del_when BEFORE INSERT OR UPDATE ON main_table FOR EACH ROW WHEN (new.tableo..." +== 188 +-- truncate_limit: 100 +CREATE TRIGGER error_stmt_when BEFORE UPDATE OF a ON main_table +FOR EACH STATEMENT WHEN (OLD.* IS DISTINCT FROM NEW.*) +EXECUTE PROCEDURE trigger_func('error_stmt_when') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER error_stmt_when BEFORE UPDATE OF a ON main_table WHEN (old.* IS DISTINCT FROM new...." +== 189 +-- truncate_limit: 100 +-- check dependency restrictions +ALTER TABLE main_table DROP COLUMN b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE main_table DROP b" +== 190 +-- truncate_limit: 100 +-- this should succeed, but we'll roll it back to keep the triggers around +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 191 +-- truncate_limit: 100 +DROP TRIGGER after_upd_a_b_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER after_upd_a_b_row_trig ON main_table" +== 192 +-- truncate_limit: 100 +DROP TRIGGER after_upd_b_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER after_upd_b_row_trig ON main_table" +== 193 +-- truncate_limit: 100 +DROP TRIGGER after_upd_b_stmt_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER after_upd_b_stmt_trig ON main_table" +== 194 +-- truncate_limit: 100 +ALTER TABLE main_table DROP COLUMN b +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE main_table DROP b" +== 195 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 196 +-- truncate_limit: 100 +-- Test enable/disable triggers + +create table trigtest (i serial primary key) +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigtest (i serial PRIMARY KEY)" +== 197 +-- truncate_limit: 100 +-- test that disabling RI triggers works +create table trigtest2 (i int references trigtest(i) on delete cascade) +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigtest2 (i int REFERENCES trigtest (i) ON DELETE CASCADE)" +== 198 +-- truncate_limit: 100 +create function trigtest() returns trigger as $$ +begin + raise notice '% % % %', TG_TABLE_NAME, TG_OP, TG_WHEN, TG_LEVEL; + return new; +end;$$ language plpgsql +-- +FUNCTION: name="trigtest" function="trigtest" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trigtest() RETURNS trigger AS $$\nbegin\n\traise notice '% % % %', TG_TABLE_NAME, TG..." +== 199 +-- truncate_limit: 100 +create trigger trigtest_b_row_tg before insert or update or delete on trigtest +for each row execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_b_row_tg BEFORE INSERT OR DELETE OR UPDATE ON trigtest FOR EACH ROW EXECU..." +== 200 +-- truncate_limit: 100 +create trigger trigtest_a_row_tg after insert or update or delete on trigtest +for each row execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_a_row_tg AFTER INSERT OR DELETE OR UPDATE ON trigtest FOR EACH ROW EXECUT..." +== 201 +-- truncate_limit: 100 +create trigger trigtest_b_stmt_tg before insert or update or delete on trigtest +for each statement execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_b_stmt_tg BEFORE INSERT OR DELETE OR UPDATE ON trigtest EXECUTE FUNCTION ..." +== 202 +-- truncate_limit: 100 +create trigger trigtest_a_stmt_tg after insert or update or delete on trigtest +for each statement execute procedure trigtest() +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigtest_a_stmt_tg AFTER INSERT OR DELETE OR UPDATE ON trigtest EXECUTE FUNCTION t..." +== 203 +-- truncate_limit: 100 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trigtest DEFAULT VALUES" +== 204 +-- truncate_limit: 100 +alter table trigtest disable trigger trigtest_b_row_tg +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigtest DISABLE TRIGGER trigtest_b_row_tg" +== 205 +-- truncate_limit: 100 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trigtest DEFAULT VALUES" +== 206 +-- truncate_limit: 100 +alter table trigtest disable trigger user +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigtest DISABLE TRIGGER USER" +== 207 +-- truncate_limit: 100 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trigtest DEFAULT VALUES" +== 208 +-- truncate_limit: 100 +alter table trigtest enable trigger trigtest_a_stmt_tg +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigtest ENABLE TRIGGER trigtest_a_stmt_tg" +== 209 +-- truncate_limit: 100 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trigtest DEFAULT VALUES" +== 210 +-- truncate_limit: 100 +set session_replication_role = replica +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_replication_role TO replica" +== 211 +-- truncate_limit: 100 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trigtest DEFAULT VALUES" +== 212 +-- truncate_limit: 100 +-- does not trigger +alter table trigtest enable always trigger trigtest_a_stmt_tg +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigtest ENABLE ALWAYS TRIGGER trigtest_a_stmt_tg" +== 213 +-- truncate_limit: 100 +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trigtest DEFAULT VALUES" +== 214 +-- truncate_limit: 100 +-- now it does +reset session_replication_role +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_replication_role" +== 215 +-- truncate_limit: 100 +insert into trigtest2 values(1) +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigtest2 VALUES (1)" +== 216 +-- truncate_limit: 100 +insert into trigtest2 values(2) +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigtest2 VALUES (2)" +== 217 +-- truncate_limit: 100 +delete from trigtest where i=2 +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trigtest WHERE i = 2" +== 218 +-- truncate_limit: 100 +select * from trigtest2 +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest2" +== 219 +-- truncate_limit: 100 +alter table trigtest disable trigger all +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigtest DISABLE TRIGGER ALL" +== 220 +-- truncate_limit: 100 +delete from trigtest where i=1 +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trigtest WHERE i = 1" +== 221 +-- truncate_limit: 100 +select * from trigtest2 +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest2" +== 222 +-- truncate_limit: 100 +-- ensure we still insert, even when all triggers are disabled +insert into trigtest default values +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO trigtest DEFAULT VALUES" +== 223 +-- truncate_limit: 100 +select * from trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trigtest" +== 224 +-- truncate_limit: 100 +drop table trigtest2 +-- +TABLE: name="trigtest2" schema="" table="trigtest2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigtest2" +== 225 +-- truncate_limit: 100 +drop table trigtest +-- +TABLE: name="trigtest" schema="" table="trigtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigtest" +== 226 +-- truncate_limit: 100 +-- dump trigger data +CREATE TABLE trigger_test ( + i int, + v varchar +) +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_test (i int, v varchar)" +== 227 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger +LANGUAGE plpgsql AS $$ + +declare + + argstr text; + relid text; + +begin + + relid := TG_relid::regclass; + + -- plpgsql can't discover its trigger data in a hash like perl and python + -- can, or by a sort of reflection like tcl can, + -- so we have to hard code the names. + raise NOTICE 'TG_NAME: %', TG_name; + raise NOTICE 'TG_WHEN: %', TG_when; + raise NOTICE 'TG_LEVEL: %', TG_level; + raise NOTICE 'TG_OP: %', TG_op; + raise NOTICE 'TG_RELID::regclass: %', relid; + raise NOTICE 'TG_RELNAME: %', TG_relname; + raise NOTICE 'TG_TABLE_NAME: %', TG_table_name; + raise NOTICE 'TG_TABLE_SCHEMA: %', TG_table_schema; + raise NOTICE 'TG_NARGS: %', TG_nargs; + + argstr := '['; + for i in 0 .. TG_nargs - 1 loop + if i > 0 then + argstr := argstr || ', '; + end if; + argstr := argstr || TG_argv[i]; + end loop; + argstr := argstr || ']'; + raise NOTICE 'TG_ARGV: %', argstr; + + if TG_OP != 'INSERT' then + raise NOTICE 'OLD: %', OLD; + end if; + + if TG_OP != 'DELETE' then + raise NOTICE 'NEW: %', NEW; + end if; + + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; + +end; +$$ +-- +FUNCTION: name="trigger_data" function="trigger_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpgsql AS $$\n\ndeclare\n\n\targst..." +== 228 +-- truncate_limit: 100 +CREATE TRIGGER show_trigger_data_trig +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER show_trigger_data_trig BEFORE INSERT OR DELETE OR UPDATE ON trigger_test FOR EACH ..." +== 229 +-- truncate_limit: 100 +insert into trigger_test values(1,'insert') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigger_test VALUES (1, 'insert')" +== 230 +-- truncate_limit: 100 +update trigger_test set v = 'update' where i = 1 +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigger_test SET v = 'update' WHERE i = 1" +== 231 +-- truncate_limit: 100 +delete from trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trigger_test" +== 232 +-- truncate_limit: 100 +DROP TRIGGER show_trigger_data_trig on trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER show_trigger_data_trig ON trigger_test" +== 233 +-- truncate_limit: 100 +DROP FUNCTION trigger_data() +-- +FUNCTION: name="trigger_data" function="trigger_data" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION trigger_data()" +== 234 +-- truncate_limit: 100 +DROP TABLE trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigger_test" +== 235 +-- truncate_limit: 100 +|-- +-- Test use of row comparisons on OLD/NEW +|-- + +CREATE TABLE trigger_test (f1 int, f2 text, f3 text) +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_test (f1 int, f2 text, f3 text)" +== 236 +-- truncate_limit: 100 +-- this is the obvious (and wrong...) way to compare rows +CREATE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql as $$ +begin + if row(old.*) = row(new.*) then + raise notice 'row % not changed', new.f1; + else + raise notice 'row % changed', new.f1; + end if; + return new; +end$$ +-- +FUNCTION: name="mytrigger" function="mytrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n\tif row(old.*) = row(new..." +== 237 +-- truncate_limit: 100 +CREATE TRIGGER t +BEFORE UPDATE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE mytrigger() +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER t BEFORE UPDATE ON trigger_test FOR EACH ROW EXECUTE FUNCTION mytrigger()" +== 238 +-- truncate_limit: 100 +INSERT INTO trigger_test VALUES(1, 'foo', 'bar') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigger_test VALUES (1, 'foo', 'bar')" +== 239 +-- truncate_limit: 100 +INSERT INTO trigger_test VALUES(2, 'baz', 'quux') +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigger_test VALUES (2, 'baz', 'quux')" +== 240 +-- truncate_limit: 100 +UPDATE trigger_test SET f3 = 'bar' +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigger_test SET f3 = 'bar'" +== 241 +-- truncate_limit: 100 +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigger_test SET f3 = NULL" +== 242 +-- truncate_limit: 100 +-- this demonstrates that the above isn't really working as desired: +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigger_test SET f3 = NULL" +== 243 +-- truncate_limit: 100 +-- the right way when considering nulls is +CREATE OR REPLACE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql as $$ +begin + if row(old.*) is distinct from row(new.*) then + raise notice 'row % changed', new.f1; + else + raise notice 'row % not changed', new.f1; + end if; + return new; +end$$ +-- +FUNCTION: name="mytrigger" function="mytrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n\tif row(old.*..." +== 244 +-- truncate_limit: 100 +UPDATE trigger_test SET f3 = 'bar' +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigger_test SET f3 = 'bar'" +== 245 +-- truncate_limit: 100 +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigger_test SET f3 = NULL" +== 246 +-- truncate_limit: 100 +UPDATE trigger_test SET f3 = NULL +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trigger_test SET f3 = NULL" +== 247 +-- truncate_limit: 100 +DROP TABLE trigger_test +-- +TABLE: name="trigger_test" schema="" table="trigger_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigger_test" +== 248 +-- truncate_limit: 100 +DROP FUNCTION mytrigger() +-- +FUNCTION: name="mytrigger" function="mytrigger" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION mytrigger()" +== 249 +-- truncate_limit: 100 +-- Test snapshot management in serializable transactions involving triggers +-- per bug report in 6bc73d4c0910042358k3d1adff3qa36f8df75198ecea@mail.gmail.com +CREATE FUNCTION serializable_update_trig() RETURNS trigger LANGUAGE plpgsql AS +$$ +declare + rec record; +begin + new.description = 'updated in trigger'; + return new; +end; +$$ +-- +FUNCTION: name="serializable_update_trig" function="serializable_update_trig" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION serializable_update_trig() RETURNS trigger LANGUAGE plpgsql AS $$\ndeclare\n\trec re..." +== 250 +-- truncate_limit: 100 +CREATE TABLE serializable_update_tab ( + id int, + filler text, + description text +) +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE serializable_update_tab (id int, filler text, description text)" +== 251 +-- truncate_limit: 100 +CREATE TRIGGER serializable_update_trig BEFORE UPDATE ON serializable_update_tab + FOR EACH ROW EXECUTE PROCEDURE serializable_update_trig() +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER serializable_update_trig BEFORE UPDATE ON serializable_update_tab FOR EACH ROW EXE..." +== 252 +-- truncate_limit: 100 +INSERT INTO serializable_update_tab SELECT a, repeat('xyzxz', 100), 'new' + FROM generate_series(1, 50) a +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO serializable_update_tab SELECT ... FROM generate_series(1, 50) a" +== 253 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 254 +-- truncate_limit: 100 +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: VariableSetStmt +TRUNCATED: "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE" +== 255 +-- truncate_limit: 100 +UPDATE serializable_update_tab SET description = 'no no', id = 1 WHERE id = 1 +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE serializable_update_tab SET description = 'no no', id = 1 WHERE id = 1" +== 256 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 257 +-- truncate_limit: 100 +SELECT description FROM serializable_update_tab WHERE id = 1 +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=Select +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT description FROM serializable_update_tab WHERE id = 1" +== 258 +-- truncate_limit: 100 +DROP TABLE serializable_update_tab +-- +TABLE: name="serializable_update_tab" schema="" table="serializable_update_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE serializable_update_tab" +== 259 +-- truncate_limit: 100 +-- minimal update trigger + +CREATE TABLE min_updates_test ( + f1 text, + f2 int, + f3 int) +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE min_updates_test (f1 text, f2 int, f3 int)" +== 260 +-- truncate_limit: 100 +INSERT INTO min_updates_test VALUES ('a',1,2),('b','2',null) +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO min_updates_test VALUES ('a', 1, 2), ('b', '2', NULL)" +== 261 +-- truncate_limit: 100 +CREATE TRIGGER z_min_update +BEFORE UPDATE ON min_updates_test +FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger() +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER z_min_update BEFORE UPDATE ON min_updates_test FOR EACH ROW EXECUTE FUNCTION suppr..." +== 262 +-- truncate_limit: 100 +UPDATE min_updates_test SET f1 = f1 +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE min_updates_test SET f1 = f1" +== 263 +-- truncate_limit: 100 +UPDATE min_updates_test SET f2 = f2 + 1 +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE min_updates_test SET f2 = f2 + 1" +== 264 +-- truncate_limit: 100 +UPDATE min_updates_test SET f3 = 2 WHERE f3 is null +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE min_updates_test SET f3 = 2 WHERE f3 IS NULL" +== 265 +-- truncate_limit: 100 +SELECT * FROM min_updates_test +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM min_updates_test" +== 266 +-- truncate_limit: 100 +DROP TABLE min_updates_test +-- +TABLE: name="min_updates_test" schema="" table="min_updates_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE min_updates_test" +== 267 +-- truncate_limit: 100 +|-- +-- Test triggers on views +|-- + +CREATE VIEW main_view AS SELECT a, b FROM main_table +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +TABLE: name="main_table" schema="" table="main_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW main_view AS SELECT a, b FROM main_table" +== 268 +-- truncate_limit: 100 +-- VIEW trigger function +CREATE OR REPLACE FUNCTION view_trigger() RETURNS trigger +LANGUAGE plpgsql AS $$ +declare + argstr text := ''; +begin + for i in 0 .. TG_nargs - 1 loop + if i > 0 then + argstr := argstr || ', '; + end if; + argstr := argstr || TG_argv[i]; + end loop; + + raise notice '% % % % (%)', TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, argstr; + + if TG_LEVEL = 'ROW' then + if TG_OP = 'INSERT' then + raise NOTICE 'NEW: %', NEW; + INSERT INTO main_table VALUES (NEW.a, NEW.b); + RETURN NEW; + end if; + + if TG_OP = 'UPDATE' then + raise NOTICE 'OLD: %, NEW: %', OLD, NEW; + UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b; + if NOT FOUND then RETURN NULL; end if; + RETURN NEW; + end if; + + if TG_OP = 'DELETE' then + raise NOTICE 'OLD: %', OLD; + DELETE FROM main_table WHERE a = OLD.a AND b = OLD.b; + if NOT FOUND then RETURN NULL; end if; + RETURN OLD; + end if; + end if; + + RETURN NULL; +end; +$$ +-- +FUNCTION: name="view_trigger" function="view_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION view_trigger() RETURNS trigger LANGUAGE plpgsql AS $$\ndeclare\n args..." +== 269 +-- truncate_limit: 100 +-- Before row triggers aren't allowed on views +CREATE TRIGGER invalid_trig BEFORE INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_ins_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig BEFORE INSERT ON main_view FOR EACH ROW EXECUTE FUNCTION trigger_func..." +== 270 +-- truncate_limit: 100 +CREATE TRIGGER invalid_trig BEFORE UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig BEFORE UPDATE ON main_view FOR EACH ROW EXECUTE FUNCTION trigger_func..." +== 271 +-- truncate_limit: 100 +CREATE TRIGGER invalid_trig BEFORE DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_del_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig BEFORE DELETE ON main_view FOR EACH ROW EXECUTE FUNCTION trigger_func..." +== 272 +-- truncate_limit: 100 +-- After row triggers aren't allowed on views +CREATE TRIGGER invalid_trig AFTER INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_ins_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig AFTER INSERT ON main_view FOR EACH ROW EXECUTE FUNCTION trigger_func(..." +== 273 +-- truncate_limit: 100 +CREATE TRIGGER invalid_trig AFTER UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig AFTER UPDATE ON main_view FOR EACH ROW EXECUTE FUNCTION trigger_func(..." +== 274 +-- truncate_limit: 100 +CREATE TRIGGER invalid_trig AFTER DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_del_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig AFTER DELETE ON main_view FOR EACH ROW EXECUTE FUNCTION trigger_func(..." +== 275 +-- truncate_limit: 100 +-- Truncate triggers aren't allowed on views +CREATE TRIGGER invalid_trig BEFORE TRUNCATE ON main_view +EXECUTE PROCEDURE trigger_func('before_tru_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig BEFORE TRUNCATE ON main_view EXECUTE FUNCTION trigger_func('before_tr..." +== 276 +-- truncate_limit: 100 +CREATE TRIGGER invalid_trig AFTER TRUNCATE ON main_view +EXECUTE PROCEDURE trigger_func('before_tru_row') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig AFTER TRUNCATE ON main_view EXECUTE FUNCTION trigger_func('before_tru..." +== 277 +-- truncate_limit: 100 +-- INSTEAD OF triggers aren't allowed on tables +CREATE TRIGGER invalid_trig INSTEAD OF INSERT ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig INSTEAD OF INSERT ON main_table FOR EACH ROW EXECUTE FUNCTION view_tr..." +== 278 +-- truncate_limit: 100 +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_table FOR EACH ROW EXECUTE FUNCTION view_tr..." +== 279 +-- truncate_limit: 100 +CREATE TRIGGER invalid_trig INSTEAD OF DELETE ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del') +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig INSTEAD OF DELETE ON main_table FOR EACH ROW EXECUTE FUNCTION view_tr..." +== 280 +-- truncate_limit: 100 +-- Don't support WHEN clauses with INSTEAD OF triggers +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view +FOR EACH ROW WHEN (OLD.a <> NEW.a) EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW WHEN (old.a <> new.a) EXE..." +== 281 +-- truncate_limit: 100 +-- Don't support column-level INSTEAD OF triggers +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE OF a ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig INSTEAD OF UPDATE OF a ON main_view FOR EACH ROW EXECUTE FUNCTION vie..." +== 282 +-- truncate_limit: 100 +-- Don't support statement-level INSTEAD OF triggers +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view +EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view EXECUTE FUNCTION view_trigger('instead..." +== 283 +-- truncate_limit: 100 +-- Valid INSTEAD OF triggers +CREATE TRIGGER instead_of_insert_trig INSTEAD OF INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER instead_of_insert_trig INSTEAD OF INSERT ON main_view FOR EACH ROW EXECUTE FUNCTIO..." +== 284 +-- truncate_limit: 100 +CREATE TRIGGER instead_of_update_trig INSTEAD OF UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE FUNCTIO..." +== 285 +-- truncate_limit: 100 +CREATE TRIGGER instead_of_delete_trig INSTEAD OF DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER instead_of_delete_trig INSTEAD OF DELETE ON main_view FOR EACH ROW EXECUTE FUNCTIO..." +== 286 +-- truncate_limit: 100 +-- Valid BEFORE statement VIEW triggers +CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_ins_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_view EXECUTE FUNCTION view_trigger('bef..." +== 287 +-- truncate_limit: 100 +CREATE TRIGGER before_upd_stmt_trig BEFORE UPDATE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_upd_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_upd_stmt_trig BEFORE UPDATE ON main_view EXECUTE FUNCTION view_trigger('bef..." +== 288 +-- truncate_limit: 100 +CREATE TRIGGER before_del_stmt_trig BEFORE DELETE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_del_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_del_stmt_trig BEFORE DELETE ON main_view EXECUTE FUNCTION view_trigger('bef..." +== 289 +-- truncate_limit: 100 +-- Valid AFTER statement VIEW triggers +CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_ins_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_view EXECUTE FUNCTION view_trigger('after..." +== 290 +-- truncate_limit: 100 +CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_upd_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_view EXECUTE FUNCTION view_trigger('after..." +== 291 +-- truncate_limit: 100 +CREATE TRIGGER after_del_stmt_trig AFTER DELETE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_del_stmt') +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER after_del_stmt_trig AFTER DELETE ON main_view EXECUTE FUNCTION view_trigger('after..." +== 292 +-- truncate_limit: 100 +-- Insert into view using trigger +INSERT INTO main_view VALUES (20, 30) +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO main_view VALUES (20, 30)" +== 293 +-- truncate_limit: 100 +INSERT INTO main_view VALUES (21, 31) RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO main_view VALUES (21, 31) RETURNING a, b" +== 294 +-- truncate_limit: 100 +-- Table trigger will prevent updates +UPDATE main_view SET b = 31 WHERE a = 20 +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_view SET b = 31 WHERE a = 20" +== 295 +-- truncate_limit: 100 +UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b" +== 296 +-- truncate_limit: 100 +-- Remove table trigger to allow updates +DROP TRIGGER before_upd_a_row_trig ON main_table +-- +TABLE: name="main_table" schema="" table="main_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER before_upd_a_row_trig ON main_table" +== 297 +-- truncate_limit: 100 +UPDATE main_view SET b = 31 WHERE a = 20 +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_view SET b = 31 WHERE a = 20" +== 298 +-- truncate_limit: 100 +UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b" +== 299 +-- truncate_limit: 100 +-- Before and after stmt triggers should fire even when no rows are affected +UPDATE main_view SET b = 0 WHERE false +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE main_view SET b = 0 WHERE false" +== 300 +-- truncate_limit: 100 +-- Delete from view using trigger +DELETE FROM main_view WHERE a IN (20,21) +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM main_view WHERE a IN (20, 21)" +== 301 +-- truncate_limit: 100 +DELETE FROM main_view WHERE a = 31 RETURNING a, b +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM main_view WHERE a = 31 RETURNING a, b" +== 302 +-- truncate_limit: 100 +-- Describe view should list triggers + +-- Test dropping view triggers +DROP TRIGGER instead_of_insert_trig ON main_view +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER instead_of_insert_trig ON main_view" +== 303 +-- truncate_limit: 100 +DROP TRIGGER instead_of_delete_trig ON main_view +-- +TABLE: name="main_view" schema="" table="main_view" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER instead_of_delete_trig ON main_view" +== 304 +-- truncate_limit: 100 +DROP VIEW main_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW main_view" +== 305 +-- truncate_limit: 100 +|-- +-- Test triggers on a join view +|-- +CREATE TABLE country_table ( + country_id serial primary key, + country_name text unique not null, + continent text not null +) +-- +TABLE: name="country_table" schema="" table="country_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE country_table (country_id serial PRIMARY KEY, country_name text UNIQUE NOT NULL, con..." +== 306 +-- truncate_limit: 100 +INSERT INTO country_table (country_name, continent) + VALUES ('Japan', 'Asia'), + ('UK', 'Europe'), + ('USA', 'North America') + RETURNING * +-- +TABLE: name="country_table" schema="" table="country_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO country_table (country_name, continent) VALUES (...) RETURNING *" +== 307 +-- truncate_limit: 100 +CREATE TABLE city_table ( + city_id serial primary key, + city_name text not null, + population bigint, + country_id int references country_table +) +-- +TABLE: name="city_table" schema="" table="city_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE city_table (city_id serial PRIMARY KEY, city_name text NOT NULL, population bigint, ..." +== 308 +-- truncate_limit: 100 +CREATE VIEW city_view AS + SELECT city_id, city_name, population, country_name, continent + FROM city_table ci + LEFT JOIN country_table co ON co.country_id = ci.country_id +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +TABLE: name="city_table" schema="" table="city_table" ctx=Select +TABLE: name="country_table" schema="" table="country_table" ctx=Select +ALIAS: "ci"="city_table" +ALIAS: "co"="country_table" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW city_view AS SELECT city_id, city_name, population, country_name, continent FROM city..." +== 309 +-- truncate_limit: 100 +CREATE FUNCTION city_insert() RETURNS trigger LANGUAGE plpgsql AS $$ +declare + ctry_id int; +begin + if NEW.country_name IS NOT NULL then + SELECT country_id, continent INTO ctry_id, NEW.continent + FROM country_table WHERE country_name = NEW.country_name; + if NOT FOUND then + raise exception 'No such country: "%"', NEW.country_name; + end if; + else + NEW.continent := NULL; + end if; + + if NEW.city_id IS NOT NULL then + INSERT INTO city_table + VALUES(NEW.city_id, NEW.city_name, NEW.population, ctry_id); + else + INSERT INTO city_table(city_name, population, country_id) + VALUES(NEW.city_name, NEW.population, ctry_id) + RETURNING city_id INTO NEW.city_id; + end if; + + RETURN NEW; +end; +$$ +-- +FUNCTION: name="city_insert" function="city_insert" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION city_insert() RETURNS trigger LANGUAGE plpgsql AS $$\ndeclare\n ctry_id int;\nbeg..." +== 310 +-- truncate_limit: 100 +CREATE TRIGGER city_insert_trig INSTEAD OF INSERT ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_insert() +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER city_insert_trig INSTEAD OF INSERT ON city_view FOR EACH ROW EXECUTE FUNCTION city..." +== 311 +-- truncate_limit: 100 +CREATE FUNCTION city_delete() RETURNS trigger LANGUAGE plpgsql AS $$ +begin + DELETE FROM city_table WHERE city_id = OLD.city_id; + if NOT FOUND then RETURN NULL; end if; + RETURN OLD; +end; +$$ +-- +FUNCTION: name="city_delete" function="city_delete" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION city_delete() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n DELETE FROM city_t..." +== 312 +-- truncate_limit: 100 +CREATE TRIGGER city_delete_trig INSTEAD OF DELETE ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_delete() +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER city_delete_trig INSTEAD OF DELETE ON city_view FOR EACH ROW EXECUTE FUNCTION city..." +== 313 +-- truncate_limit: 100 +CREATE FUNCTION city_update() RETURNS trigger LANGUAGE plpgsql AS $$ +declare + ctry_id int; +begin + if NEW.country_name IS DISTINCT FROM OLD.country_name then + SELECT country_id, continent INTO ctry_id, NEW.continent + FROM country_table WHERE country_name = NEW.country_name; + if NOT FOUND then + raise exception 'No such country: "%"', NEW.country_name; + end if; + + UPDATE city_table SET city_name = NEW.city_name, + population = NEW.population, + country_id = ctry_id + WHERE city_id = OLD.city_id; + else + UPDATE city_table SET city_name = NEW.city_name, + population = NEW.population + WHERE city_id = OLD.city_id; + NEW.continent := OLD.continent; + end if; + + if NOT FOUND then RETURN NULL; end if; + RETURN NEW; +end; +$$ +-- +FUNCTION: name="city_update" function="city_update" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION city_update() RETURNS trigger LANGUAGE plpgsql AS $$\ndeclare\n ctry_id int;\nbeg..." +== 314 +-- truncate_limit: 100 +CREATE TRIGGER city_update_trig INSTEAD OF UPDATE ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_update() +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER city_update_trig INSTEAD OF UPDATE ON city_view FOR EACH ROW EXECUTE FUNCTION city..." +== 315 +-- truncate_limit: 100 +-- INSERT .. RETURNING +INSERT INTO city_view(city_name) VALUES('Tokyo') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO city_view (city_name) VALUES ('Tokyo') RETURNING *" +== 316 +-- truncate_limit: 100 +INSERT INTO city_view(city_name, population) VALUES('London', 7556900) RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO city_view (city_name, population) VALUES ('London', 7556900) RETURNING *" +== 317 +-- truncate_limit: 100 +INSERT INTO city_view(city_name, country_name) VALUES('Washington DC', 'USA') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO city_view (city_name, country_name) VALUES ('Washington DC', 'USA') RETURNING *" +== 318 +-- truncate_limit: 100 +INSERT INTO city_view(city_id, city_name) VALUES(123456, 'New York') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO city_view (city_id, city_name) VALUES (123456, 'New York') RETURNING *" +== 319 +-- truncate_limit: 100 +INSERT INTO city_view VALUES(234567, 'Birmingham', 1016800, 'UK', 'EU') RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO city_view VALUES (234567, 'Birmingham', 1016800, 'UK', 'EU') RETURNING *" +== 320 +-- truncate_limit: 100 +-- UPDATE .. RETURNING +UPDATE city_view SET country_name = 'Japon' WHERE city_name = 'Tokyo' +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET country_name = 'Japon' WHERE city_name = 'Tokyo'" +== 321 +-- truncate_limit: 100 +-- error +UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Takyo' +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Takyo'" +== 322 +-- truncate_limit: 100 +-- no match +UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Tokyo' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Tokyo' RETURNING *" +== 323 +-- truncate_limit: 100 +-- OK + +UPDATE city_view SET population = 13010279 WHERE city_name = 'Tokyo' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET population = 13010279 WHERE city_name = 'Tokyo' RETURNING *" +== 324 +-- truncate_limit: 100 +UPDATE city_view SET country_name = 'UK' WHERE city_name = 'New York' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET country_name = 'UK' WHERE city_name = 'New York' RETURNING *" +== 325 +-- truncate_limit: 100 +UPDATE city_view SET country_name = 'USA', population = 8391881 WHERE city_name = 'New York' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET ... = ... WHERE city_name = 'New York' RETURNING *" +== 326 +-- truncate_limit: 100 +UPDATE city_view SET continent = 'EU' WHERE continent = 'Europe' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET continent = 'EU' WHERE continent = 'Europe' RETURNING *" +== 327 +-- truncate_limit: 100 +UPDATE city_view v1 SET country_name = v2.country_name FROM city_view v2 + WHERE v2.city_name = 'Birmingham' AND v1.city_name = 'London' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +TABLE: name="city_view" schema="" table="city_view" ctx=Select +ALIAS: "v1"="city_view" +ALIAS: "v2"="city_view" +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view v1 SET country_name = v2.country_name FROM city_view v2 WHERE ... RETURNING *" +== 328 +-- truncate_limit: 100 +-- DELETE .. RETURNING +DELETE FROM city_view WHERE city_name = 'Birmingham' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM city_view WHERE city_name = 'Birmingham' RETURNING *" +== 329 +-- truncate_limit: 100 +-- read-only view with WHERE clause +CREATE VIEW european_city_view AS + SELECT * FROM city_view WHERE continent = 'Europe' +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +TABLE: name="city_view" schema="" table="city_view" ctx=Select +FILTER: schema="" table="" column="continent" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW european_city_view AS SELECT * FROM city_view WHERE continent = 'Europe'" +== 330 +-- truncate_limit: 100 +SELECT count(*) FROM european_city_view +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM european_city_view" +== 331 +-- truncate_limit: 100 +CREATE FUNCTION no_op_trig_fn() RETURNS trigger LANGUAGE plpgsql +AS 'begin RETURN NULL; end' +-- +FUNCTION: name="no_op_trig_fn" function="no_op_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION no_op_trig_fn() RETURNS trigger LANGUAGE plpgsql AS $$begin RETURN NULL; end$$" +== 332 +-- truncate_limit: 100 +CREATE TRIGGER no_op_trig INSTEAD OF INSERT OR UPDATE OR DELETE +ON european_city_view FOR EACH ROW EXECUTE PROCEDURE no_op_trig_fn() +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER no_op_trig INSTEAD OF INSERT OR DELETE OR UPDATE ON european_city_view FOR EACH RO..." +== 333 +-- truncate_limit: 100 +INSERT INTO european_city_view VALUES (0, 'x', 10000, 'y', 'z') +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO european_city_view VALUES (0, 'x', 10000, 'y', 'z')" +== 334 +-- truncate_limit: 100 +UPDATE european_city_view SET population = 10000 +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE european_city_view SET population = 10000" +== 335 +-- truncate_limit: 100 +DELETE FROM european_city_view +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM european_city_view" +== 336 +-- truncate_limit: 100 +-- rules bypassing no-op triggers +CREATE RULE european_city_insert_rule AS ON INSERT TO european_city_view +DO INSTEAD INSERT INTO city_view +VALUES (NEW.city_id, NEW.city_name, NEW.population, NEW.country_name, NEW.continent) +RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE european_city_insert_rule AS ON INSERT TO european_city_view DO INSTEAD INSERT INTO c..." +== 337 +-- truncate_limit: 100 +CREATE RULE european_city_update_rule AS ON UPDATE TO european_city_view +DO INSTEAD UPDATE city_view SET + city_name = NEW.city_name, + population = NEW.population, + country_name = NEW.country_name +WHERE city_id = OLD.city_id +RETURNING NEW.* +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE european_city_update_rule AS ON UPDATE TO european_city_view DO INSTEAD UPDATE city_v..." +== 338 +-- truncate_limit: 100 +CREATE RULE european_city_delete_rule AS ON DELETE TO european_city_view +DO INSTEAD DELETE FROM city_view WHERE city_id = OLD.city_id RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE european_city_delete_rule AS ON DELETE TO european_city_view DO INSTEAD DELETE FROM c..." +== 339 +-- truncate_limit: 100 +-- INSERT not limited by view's WHERE clause, but UPDATE AND DELETE are +INSERT INTO european_city_view(city_name, country_name) + VALUES ('Cambridge', 'USA') RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO european_city_view (city_name, country_name) VALUES ('Cambridge', 'USA') RETURNING *" +== 340 +-- truncate_limit: 100 +UPDATE european_city_view SET country_name = 'UK' + WHERE city_name = 'Cambridge' +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE european_city_view SET country_name = 'UK' WHERE city_name = 'Cambridge'" +== 341 +-- truncate_limit: 100 +DELETE FROM european_city_view WHERE city_name = 'Cambridge' +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM european_city_view WHERE city_name = 'Cambridge'" +== 342 +-- truncate_limit: 100 +-- UPDATE and DELETE via rule and trigger +UPDATE city_view SET country_name = 'UK' + WHERE city_name = 'Cambridge' RETURNING * +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view SET country_name = 'UK' WHERE city_name = 'Cambridge' RETURNING *" +== 343 +-- truncate_limit: 100 +UPDATE european_city_view SET population = 122800 + WHERE city_name = 'Cambridge' RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE european_city_view SET population = 122800 WHERE city_name = 'Cambridge' RETURNING *" +== 344 +-- truncate_limit: 100 +DELETE FROM european_city_view WHERE city_name = 'Cambridge' RETURNING * +-- +TABLE: name="european_city_view" schema="" table="european_city_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM european_city_view WHERE city_name = 'Cambridge' RETURNING *" +== 345 +-- truncate_limit: 100 +-- join UPDATE test +UPDATE city_view v SET population = 599657 + FROM city_table ci, country_table co + WHERE ci.city_name = 'Washington DC' and co.country_name = 'USA' + AND v.city_id = ci.city_id AND v.country_name = co.country_name + RETURNING co.country_id, v.country_name, + v.city_id, v.city_name, v.population +-- +TABLE: name="city_view" schema="" table="city_view" ctx=DML +TABLE: name="city_table" schema="" table="city_table" ctx=Select +TABLE: name="country_table" schema="" table="country_table" ctx=Select +ALIAS: "ci"="city_table" +ALIAS: "co"="country_table" +ALIAS: "v"="city_view" +STMT: UpdateStmt +TRUNCATED: "UPDATE city_view v SET ... = ... FROM city_table ci, country_table co WHERE ... RETURNING co.coun..." +== 346 +-- truncate_limit: 100 +SELECT * FROM city_view +-- +TABLE: name="city_view" schema="" table="city_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM city_view" +== 347 +-- truncate_limit: 100 +DROP TABLE city_table CASCADE +-- +TABLE: name="city_table" schema="" table="city_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE city_table CASCADE" +== 348 +-- truncate_limit: 100 +DROP TABLE country_table +-- +TABLE: name="country_table" schema="" table="country_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE country_table" +== 349 +-- truncate_limit: 100 +-- Test pg_trigger_depth() + +create table depth_a (id int not null primary key) +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE depth_a (id int NOT NULL PRIMARY KEY)" +== 350 +-- truncate_limit: 100 +create table depth_b (id int not null primary key) +-- +TABLE: name="depth_b" schema="" table="depth_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE depth_b (id int NOT NULL PRIMARY KEY)" +== 351 +-- truncate_limit: 100 +create table depth_c (id int not null primary key) +-- +TABLE: name="depth_c" schema="" table="depth_c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE depth_c (id int NOT NULL PRIMARY KEY)" +== 352 +-- truncate_limit: 100 +create function depth_a_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + insert into depth_b values (new.id); + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + return new; +end; +$$ +-- +FUNCTION: name="depth_a_tf" function="depth_a_tf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION depth_a_tf() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n raise notice '%: dept..." +== 353 +-- truncate_limit: 100 +create trigger depth_a_tr before insert on depth_a + for each row execute procedure depth_a_tf() +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER depth_a_tr BEFORE INSERT ON depth_a FOR EACH ROW EXECUTE FUNCTION depth_a_tf()" +== 354 +-- truncate_limit: 100 +create function depth_b_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + begin + execute 'insert into depth_c values (' || new.id::text || ')'; + exception + when sqlstate 'U9999' then + raise notice 'SQLSTATE = U9999: depth = %', pg_trigger_depth(); + end; + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + if new.id = 1 then + execute 'insert into depth_c values (' || new.id::text || ')'; + end if; + return new; +end; +$$ +-- +FUNCTION: name="depth_b_tf" function="depth_b_tf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION depth_b_tf() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n raise notice '%: dept..." +== 355 +-- truncate_limit: 100 +create trigger depth_b_tr before insert on depth_b + for each row execute procedure depth_b_tf() +-- +TABLE: name="depth_b" schema="" table="depth_b" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER depth_b_tr BEFORE INSERT ON depth_b FOR EACH ROW EXECUTE FUNCTION depth_b_tf()" +== 356 +-- truncate_limit: 100 +create function depth_c_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + if new.id = 1 then + raise exception sqlstate 'U9999'; + end if; + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + return new; +end; +$$ +-- +FUNCTION: name="depth_c_tf" function="depth_c_tf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION depth_c_tf() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n raise notice '%: dept..." +== 357 +-- truncate_limit: 100 +create trigger depth_c_tr before insert on depth_c + for each row execute procedure depth_c_tf() +-- +TABLE: name="depth_c" schema="" table="depth_c" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER depth_c_tr BEFORE INSERT ON depth_c FOR EACH ROW EXECUTE FUNCTION depth_c_tf()" +== 358 +-- truncate_limit: 100 +select pg_trigger_depth() +-- +FUNCTION: name="pg_trigger_depth" function="pg_trigger_depth" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_trigger_depth()" +== 359 +-- truncate_limit: 100 +insert into depth_a values (1) +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO depth_a VALUES (1)" +== 360 +-- truncate_limit: 100 +select pg_trigger_depth() +-- +FUNCTION: name="pg_trigger_depth" function="pg_trigger_depth" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_trigger_depth()" +== 361 +-- truncate_limit: 100 +insert into depth_a values (2) +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO depth_a VALUES (2)" +== 362 +-- truncate_limit: 100 +select pg_trigger_depth() +-- +FUNCTION: name="pg_trigger_depth" function="pg_trigger_depth" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_trigger_depth()" +== 363 +-- truncate_limit: 100 +drop table depth_a, depth_b, depth_c +-- +TABLE: name="depth_a" schema="" table="depth_a" ctx=DDL +TABLE: name="depth_b" schema="" table="depth_b" ctx=DDL +TABLE: name="depth_c" schema="" table="depth_c" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE depth_a, depth_b, depth_c" +== 364 +-- truncate_limit: 100 +drop function depth_a_tf() +-- +FUNCTION: name="depth_a_tf" function="depth_a_tf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION depth_a_tf()" +== 365 +-- truncate_limit: 100 +drop function depth_b_tf() +-- +FUNCTION: name="depth_b_tf" function="depth_b_tf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION depth_b_tf()" +== 366 +-- truncate_limit: 100 +drop function depth_c_tf() +-- +FUNCTION: name="depth_c_tf" function="depth_c_tf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION depth_c_tf()" +== 367 +-- truncate_limit: 100 +|-- +-- Test updates to rows during firing of BEFORE ROW triggers. +-- As of 9.2, such cases should be rejected (see bug #6123). +|-- + +create temp table parent ( + aid int not null primary key, + val1 text, + val2 text, + val3 text, + val4 text, + bcnt int not null default 0) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parent (aid int NOT NULL PRIMARY KEY, val1 text, val2 text, val3 text, val..." +== 368 +-- truncate_limit: 100 +create temp table child ( + bid int not null primary key, + aid int not null, + val1 text) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE child (bid int NOT NULL PRIMARY KEY, aid int NOT NULL, val1 text)" +== 369 +-- truncate_limit: 100 +create function parent_upd_func() + returns trigger language plpgsql as +$$ +begin + if old.val1 <> new.val1 then + new.val2 = new.val1; + delete from child where child.aid = new.aid and child.val1 = new.val1; + end if; + return new; +end; +$$ +-- +FUNCTION: name="parent_upd_func" function="parent_upd_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION parent_upd_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n if old.val1 <> n..." +== 370 +-- truncate_limit: 100 +create trigger parent_upd_trig before update on parent + for each row execute procedure parent_upd_func() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_upd_trig BEFORE UPDATE ON parent FOR EACH ROW EXECUTE FUNCTION parent_upd_f..." +== 371 +-- truncate_limit: 100 +create function parent_del_func() + returns trigger language plpgsql as +$$ +begin + delete from child where aid = old.aid; + return old; +end; +$$ +-- +FUNCTION: name="parent_del_func" function="parent_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION parent_del_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n delete from chil..." +== 372 +-- truncate_limit: 100 +create trigger parent_del_trig before delete on parent + for each row execute procedure parent_del_func() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_del_trig BEFORE DELETE ON parent FOR EACH ROW EXECUTE FUNCTION parent_del_f..." +== 373 +-- truncate_limit: 100 +create function child_ins_func() + returns trigger language plpgsql as +$$ +begin + update parent set bcnt = bcnt + 1 where aid = new.aid; + return new; +end; +$$ +-- +FUNCTION: name="child_ins_func" function="child_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION child_ins_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n update parent set..." +== 374 +-- truncate_limit: 100 +create trigger child_ins_trig after insert on child + for each row execute procedure child_ins_func() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child_ins_trig AFTER INSERT ON child FOR EACH ROW EXECUTE FUNCTION child_ins_func()" +== 375 +-- truncate_limit: 100 +create function child_del_func() + returns trigger language plpgsql as +$$ +begin + update parent set bcnt = bcnt - 1 where aid = old.aid; + return old; +end; +$$ +-- +FUNCTION: name="child_del_func" function="child_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION child_del_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n update parent set..." +== 376 +-- truncate_limit: 100 +create trigger child_del_trig after delete on child + for each row execute procedure child_del_func() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child_del_trig AFTER DELETE ON child FOR EACH ROW EXECUTE FUNCTION child_del_func()" +== 377 +-- truncate_limit: 100 +insert into parent values (1, 'a', 'a', 'a', 'a', 0) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (1, 'a', 'a', 'a', 'a', 0)" +== 378 +-- truncate_limit: 100 +insert into child values (10, 1, 'b') +-- +TABLE: name="child" schema="" table="child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child VALUES (10, 1, 'b')" +== 379 +-- truncate_limit: 100 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 380 +-- truncate_limit: 100 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM child" +== 381 +-- truncate_limit: 100 +update parent set val1 = 'b' where aid = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parent SET val1 = 'b' WHERE aid = 1" +== 382 +-- truncate_limit: 100 +-- should fail +merge into parent p using (values (1)) as v(id) on p.aid = v.id + when matched then update set val1 = 'b' +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +ALIAS: "p"="parent" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO parent p USING (VALUES (1)) v(id) ON p.aid = v.id WHEN MATCHED THEN UPDATE SET val1 = 'b'" +== 383 +-- truncate_limit: 100 +-- should fail +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 384 +-- truncate_limit: 100 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM child" +== 385 +-- truncate_limit: 100 +delete from parent where aid = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parent WHERE aid = 1" +== 386 +-- truncate_limit: 100 +-- should fail +merge into parent p using (values (1)) as v(id) on p.aid = v.id + when matched then delete +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +ALIAS: "p"="parent" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO parent p USING (VALUES (1)) v(id) ON p.aid = v.id WHEN MATCHED THEN DELETE" +== 387 +-- truncate_limit: 100 +-- should fail +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 388 +-- truncate_limit: 100 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM child" +== 389 +-- truncate_limit: 100 +-- replace the trigger function with one that restarts the deletion after +-- having modified a child +create or replace function parent_del_func() + returns trigger language plpgsql as +$$ +begin + delete from child where aid = old.aid; + if found then + delete from parent where aid = old.aid; + return null; -- cancel outer deletion + end if; + return old; +end; +$$ +-- +FUNCTION: name="parent_del_func" function="parent_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION parent_del_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n delet..." +== 390 +-- truncate_limit: 100 +delete from parent where aid = 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parent WHERE aid = 1" +== 391 +-- truncate_limit: 100 +select * from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 392 +-- truncate_limit: 100 +select * from child +-- +TABLE: name="child" schema="" table="child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM child" +== 393 +-- truncate_limit: 100 +drop table parent, child +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent, child" +== 394 +-- truncate_limit: 100 +drop function parent_upd_func() +-- +FUNCTION: name="parent_upd_func" function="parent_upd_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION parent_upd_func()" +== 395 +-- truncate_limit: 100 +drop function parent_del_func() +-- +FUNCTION: name="parent_del_func" function="parent_del_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION parent_del_func()" +== 396 +-- truncate_limit: 100 +drop function child_ins_func() +-- +FUNCTION: name="child_ins_func" function="child_ins_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION child_ins_func()" +== 397 +-- truncate_limit: 100 +drop function child_del_func() +-- +FUNCTION: name="child_del_func" function="child_del_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION child_del_func()" +== 398 +-- truncate_limit: 100 +-- similar case, but with a self-referencing FK so that parent and child +-- rows can be affected by a single operation + +create temp table self_ref_trigger ( + id int primary key, + parent int references self_ref_trigger, + data text, + nchildren int not null default 0 +) +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE self_ref_trigger (id int PRIMARY KEY, parent int REFERENCES self_ref_trigg..." +== 399 +-- truncate_limit: 100 +create function self_ref_trigger_ins_func() + returns trigger language plpgsql as +$$ +begin + if new.parent is not null then + update self_ref_trigger set nchildren = nchildren + 1 + where id = new.parent; + end if; + return new; +end; +$$ +-- +FUNCTION: name="self_ref_trigger_ins_func" function="self_ref_trigger_ins_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION self_ref_trigger_ins_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n if new..." +== 400 +-- truncate_limit: 100 +create trigger self_ref_trigger_ins_trig before insert on self_ref_trigger + for each row execute procedure self_ref_trigger_ins_func() +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER self_ref_trigger_ins_trig BEFORE INSERT ON self_ref_trigger FOR EACH ROW EXECUTE F..." +== 401 +-- truncate_limit: 100 +create function self_ref_trigger_del_func() + returns trigger language plpgsql as +$$ +begin + if old.parent is not null then + update self_ref_trigger set nchildren = nchildren - 1 + where id = old.parent; + end if; + return old; +end; +$$ +-- +FUNCTION: name="self_ref_trigger_del_func" function="self_ref_trigger_del_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION self_ref_trigger_del_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n if old..." +== 402 +-- truncate_limit: 100 +create trigger self_ref_trigger_del_trig before delete on self_ref_trigger + for each row execute procedure self_ref_trigger_del_func() +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER self_ref_trigger_del_trig BEFORE DELETE ON self_ref_trigger FOR EACH ROW EXECUTE F..." +== 403 +-- truncate_limit: 100 +insert into self_ref_trigger values (1, null, 'root') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO self_ref_trigger VALUES (1, NULL, 'root')" +== 404 +-- truncate_limit: 100 +insert into self_ref_trigger values (2, 1, 'root child A') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO self_ref_trigger VALUES (2, 1, 'root child A')" +== 405 +-- truncate_limit: 100 +insert into self_ref_trigger values (3, 1, 'root child B') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO self_ref_trigger VALUES (3, 1, 'root child B')" +== 406 +-- truncate_limit: 100 +insert into self_ref_trigger values (4, 2, 'grandchild 1') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO self_ref_trigger VALUES (4, 2, 'grandchild 1')" +== 407 +-- truncate_limit: 100 +insert into self_ref_trigger values (5, 3, 'grandchild 2') +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO self_ref_trigger VALUES (5, 3, 'grandchild 2')" +== 408 +-- truncate_limit: 100 +update self_ref_trigger set data = 'root!' where id = 1 +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE self_ref_trigger SET data = 'root!' WHERE id = 1" +== 409 +-- truncate_limit: 100 +select * from self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM self_ref_trigger" +== 410 +-- truncate_limit: 100 +delete from self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM self_ref_trigger" +== 411 +-- truncate_limit: 100 +select * from self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM self_ref_trigger" +== 412 +-- truncate_limit: 100 +drop table self_ref_trigger +-- +TABLE: name="self_ref_trigger" schema="" table="self_ref_trigger" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE self_ref_trigger" +== 413 +-- truncate_limit: 100 +drop function self_ref_trigger_ins_func() +-- +FUNCTION: name="self_ref_trigger_ins_func" function="self_ref_trigger_ins_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION self_ref_trigger_ins_func()" +== 414 +-- truncate_limit: 100 +drop function self_ref_trigger_del_func() +-- +FUNCTION: name="self_ref_trigger_del_func" function="self_ref_trigger_del_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION self_ref_trigger_del_func()" +== 415 +-- truncate_limit: 100 +|-- +-- Check that statement triggers work correctly even with all children excluded +|-- + +create table stmt_trig_on_empty_upd (a int) +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stmt_trig_on_empty_upd (a int)" +== 416 +-- truncate_limit: 100 +create table stmt_trig_on_empty_upd1 () inherits (stmt_trig_on_empty_upd) +-- +TABLE: name="stmt_trig_on_empty_upd1" schema="" table="stmt_trig_on_empty_upd1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stmt_trig_on_empty_upd1 () INHERITS (stmt_trig_on_empty_upd)" +== 417 +-- truncate_limit: 100 +create function update_stmt_notice() returns trigger as $$ +begin + raise notice 'updating %', TG_TABLE_NAME; + return null; +end; +$$ language plpgsql +-- +FUNCTION: name="update_stmt_notice" function="update_stmt_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION update_stmt_notice() RETURNS trigger AS $$\nbegin\n\traise notice 'updating %', TG_T..." +== 418 +-- truncate_limit: 100 +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd + execute procedure update_stmt_notice() +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_stmt_trigger BEFORE UPDATE ON stmt_trig_on_empty_upd EXECUTE FUNCTION updat..." +== 419 +-- truncate_limit: 100 +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd1 + execute procedure update_stmt_notice() +-- +TABLE: name="stmt_trig_on_empty_upd1" schema="" table="stmt_trig_on_empty_upd1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER before_stmt_trigger BEFORE UPDATE ON stmt_trig_on_empty_upd1 EXECUTE FUNCTION upda..." +== 420 +-- truncate_limit: 100 +-- inherited no-op update +update stmt_trig_on_empty_upd set a = a where false returning a+1 as aa +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE stmt_trig_on_empty_upd SET a = a WHERE false RETURNING a + 1 AS aa" +== 421 +-- truncate_limit: 100 +-- simple no-op update +update stmt_trig_on_empty_upd1 set a = a where false returning a+1 as aa +-- +TABLE: name="stmt_trig_on_empty_upd1" schema="" table="stmt_trig_on_empty_upd1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE stmt_trig_on_empty_upd1 SET a = a WHERE false RETURNING a + 1 AS aa" +== 422 +-- truncate_limit: 100 +drop table stmt_trig_on_empty_upd cascade +-- +TABLE: name="stmt_trig_on_empty_upd" schema="" table="stmt_trig_on_empty_upd" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE stmt_trig_on_empty_upd CASCADE" +== 423 +-- truncate_limit: 100 +drop function update_stmt_notice() +-- +FUNCTION: name="update_stmt_notice" function="update_stmt_notice" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION update_stmt_notice()" +== 424 +-- truncate_limit: 100 +|-- +-- Check that index creation (or DDL in general) is prohibited in a trigger +|-- + +create table trigger_ddl_table ( + col1 integer, + col2 integer +) +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_ddl_table (col1 int, col2 int)" +== 425 +-- truncate_limit: 100 +create function trigger_ddl_func() returns trigger as $$ +begin + alter table trigger_ddl_table add primary key (col1); + return new; +end$$ language plpgsql +-- +FUNCTION: name="trigger_ddl_func" function="trigger_ddl_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trigger_ddl_func() RETURNS trigger AS $$\nbegin\n alter table trigger_ddl_table ad..." +== 426 +-- truncate_limit: 100 +create trigger trigger_ddl_func before insert on trigger_ddl_table for each row + execute procedure trigger_ddl_func() +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trigger_ddl_func BEFORE INSERT ON trigger_ddl_table FOR EACH ROW EXECUTE FUNCTION ..." +== 427 +-- truncate_limit: 100 +insert into trigger_ddl_table values (1, 42) +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigger_ddl_table VALUES (1, 42)" +== 428 +-- truncate_limit: 100 +-- fail + +create or replace function trigger_ddl_func() returns trigger as $$ +begin + create index on trigger_ddl_table (col2); + return new; +end$$ language plpgsql +-- +FUNCTION: name="trigger_ddl_func" function="trigger_ddl_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION trigger_ddl_func() RETURNS trigger AS $$\nbegin\n create index on trigg..." +== 429 +-- truncate_limit: 100 +insert into trigger_ddl_table values (1, 42) +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trigger_ddl_table VALUES (1, 42)" +== 430 +-- truncate_limit: 100 +-- fail + +drop table trigger_ddl_table +-- +TABLE: name="trigger_ddl_table" schema="" table="trigger_ddl_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigger_ddl_table" +== 431 +-- truncate_limit: 100 +drop function trigger_ddl_func() +-- +FUNCTION: name="trigger_ddl_func" function="trigger_ddl_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION trigger_ddl_func()" +== 432 +-- truncate_limit: 100 +|-- +-- Verify behavior of before and after triggers with INSERT...ON CONFLICT +-- DO UPDATE +|-- +create table upsert (key int4 primary key, color text) +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE upsert (key int4 PRIMARY KEY, color text)" +== 433 +-- truncate_limit: 100 +create function upsert_before_func() + returns trigger language plpgsql as +$$ +begin + if (TG_OP = 'UPDATE') then + raise warning 'before update (old): %', old.*::text; + raise warning 'before update (new): %', new.*::text; + elsif (TG_OP = 'INSERT') then + raise warning 'before insert (new): %', new.*::text; + if new.key % 2 = 0 then + new.key := new.key + 1; + new.color := new.color || ' trig modified'; + raise warning 'before insert (new, modified): %', new.*::text; + end if; + end if; + return new; +end; +$$ +-- +FUNCTION: name="upsert_before_func" function="upsert_before_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION upsert_before_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n if (TG_OP = '..." +== 434 +-- truncate_limit: 100 +create trigger upsert_before_trig before insert or update on upsert + for each row execute procedure upsert_before_func() +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER upsert_before_trig BEFORE INSERT OR UPDATE ON upsert FOR EACH ROW EXECUTE FUNCTION..." +== 435 +-- truncate_limit: 100 +create function upsert_after_func() + returns trigger language plpgsql as +$$ +begin + if (TG_OP = 'UPDATE') then + raise warning 'after update (old): %', old.*::text; + raise warning 'after update (new): %', new.*::text; + elsif (TG_OP = 'INSERT') then + raise warning 'after insert (new): %', new.*::text; + end if; + return null; +end; +$$ +-- +FUNCTION: name="upsert_after_func" function="upsert_after_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION upsert_after_func() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n if (TG_OP = 'U..." +== 436 +-- truncate_limit: 100 +create trigger upsert_after_trig after insert or update on upsert + for each row execute procedure upsert_after_func() +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER upsert_after_trig AFTER INSERT OR UPDATE ON upsert FOR EACH ROW EXECUTE FUNCTION u..." +== 437 +-- truncate_limit: 100 +insert into upsert values(1, 'black') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (1, 'black') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 438 +-- truncate_limit: 100 +insert into upsert values(2, 'red') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (2, 'red') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 439 +-- truncate_limit: 100 +insert into upsert values(3, 'orange') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (3, 'orange') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 440 +-- truncate_limit: 100 +insert into upsert values(4, 'green') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (4, 'green') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 441 +-- truncate_limit: 100 +insert into upsert values(5, 'purple') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (5, 'purple') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 442 +-- truncate_limit: 100 +insert into upsert values(6, 'white') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (6, 'white') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 443 +-- truncate_limit: 100 +insert into upsert values(7, 'pink') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (7, 'pink') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 444 +-- truncate_limit: 100 +insert into upsert values(8, 'yellow') on conflict (key) do update set color = 'updated ' || upsert.color +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert VALUES (8, 'yellow') ON CONFLICT (key) DO UPDATE SET ... = ..." +== 445 +-- truncate_limit: 100 +select * from upsert +-- +TABLE: name="upsert" schema="" table="upsert" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM upsert" +== 446 +-- truncate_limit: 100 +drop table upsert +-- +TABLE: name="upsert" schema="" table="upsert" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE upsert" +== 447 +-- truncate_limit: 100 +drop function upsert_before_func() +-- +FUNCTION: name="upsert_before_func" function="upsert_before_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION upsert_before_func()" +== 448 +-- truncate_limit: 100 +drop function upsert_after_func() +-- +FUNCTION: name="upsert_after_func" function="upsert_after_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION upsert_after_func()" +== 449 +-- truncate_limit: 100 +|-- +-- Verify that triggers with transition tables are not allowed on +-- views +|-- + +create table my_table (i int) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE my_table (i int)" +== 450 +-- truncate_limit: 100 +create view my_view as select * from my_table +-- +TABLE: name="my_view" schema="" table="my_view" ctx=DDL +TABLE: name="my_table" schema="" table="my_table" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW my_view AS SELECT * FROM my_table" +== 451 +-- truncate_limit: 100 +create function my_trigger_function() returns trigger as $$ begin end; $$ language plpgsql +-- +FUNCTION: name="my_trigger_function" function="my_trigger_function" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION my_trigger_function() RETURNS trigger AS $$ begin end; $$ LANGUAGE plpgsql" +== 452 +-- truncate_limit: 100 +create trigger my_trigger after update on my_view referencing old table as old_table + for each statement execute procedure my_trigger_function() +-- +TABLE: name="my_view" schema="" table="my_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_trigger AFTER UPDATE ON my_view REFERENCING OLD TABLE old_table EXECUTE FUNCTIO..." +== 453 +-- truncate_limit: 100 +drop function my_trigger_function() +-- +FUNCTION: name="my_trigger_function" function="my_trigger_function" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION my_trigger_function()" +== 454 +-- truncate_limit: 100 +drop view my_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW my_view" +== 455 +-- truncate_limit: 100 +drop table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE my_table" +== 456 +-- truncate_limit: 100 +|-- +-- Verify cases that are unsupported with partitioned tables +|-- +create table parted_trig (a int) partition by list (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig (a int) PARTITION BY LIST (a)" +== 457 +-- truncate_limit: 100 +create function trigger_nothing() returns trigger + language plpgsql as $$ begin end; $$ +-- +FUNCTION: name="trigger_nothing" function="trigger_nothing" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trigger_nothing() RETURNS trigger LANGUAGE plpgsql AS $$ begin end; $$" +== 458 +-- truncate_limit: 100 +create trigger failed instead of update on parted_trig + for each row execute procedure trigger_nothing() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER failed INSTEAD OF UPDATE ON parted_trig FOR EACH ROW EXECUTE FUNCTION trigger_noth..." +== 459 +-- truncate_limit: 100 +create trigger failed after update on parted_trig + referencing old table as old_table + for each row execute procedure trigger_nothing() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER failed AFTER UPDATE ON parted_trig REFERENCING OLD TABLE old_table FOR EACH ROW EX..." +== 460 +-- truncate_limit: 100 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_trig" +== 461 +-- truncate_limit: 100 +|-- +-- Verify trigger creation for partitioned tables, and drop behavior +|-- +create table trigpart (a int, b int) partition by range (a) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart (a int, b int) PARTITION BY RANGE (a)" +== 462 +-- truncate_limit: 100 +create table trigpart1 partition of trigpart for values from (0) to (1000) +-- +TABLE: name="trigpart1" schema="" table="trigpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart1 PARTITION OF trigpart FOR VALUES FROM (0) TO (1000)" +== 463 +-- truncate_limit: 100 +create trigger trg1 after insert on trigpart for each row execute procedure trigger_nothing() +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trg1 AFTER INSERT ON trigpart FOR EACH ROW EXECUTE FUNCTION trigger_nothing()" +== 464 +-- truncate_limit: 100 +create table trigpart2 partition of trigpart for values from (1000) to (2000) +-- +TABLE: name="trigpart2" schema="" table="trigpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart2 PARTITION OF trigpart FOR VALUES FROM (1000) TO (2000)" +== 465 +-- truncate_limit: 100 +create table trigpart3 (like trigpart) +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart3 (LIKE trigpart)" +== 466 +-- truncate_limit: 100 +alter table trigpart attach partition trigpart3 for values from (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart ATTACH PARTITION trigpart3 FOR VALUES FROM (2000) TO (3000)" +== 467 +-- truncate_limit: 100 +create table trigpart4 partition of trigpart for values from (3000) to (4000) partition by range (a) +-- +TABLE: name="trigpart4" schema="" table="trigpart4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart4 PARTITION OF trigpart FOR VALUES FROM (3000) TO (4000) PARTITION BY RANGE (a)" +== 468 +-- truncate_limit: 100 +create table trigpart41 partition of trigpart4 for values from (3000) to (3500) +-- +TABLE: name="trigpart41" schema="" table="trigpart41" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart41 PARTITION OF trigpart4 FOR VALUES FROM (3000) TO (3500)" +== 469 +-- truncate_limit: 100 +create table trigpart42 (like trigpart) +-- +TABLE: name="trigpart42" schema="" table="trigpart42" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart42 (LIKE trigpart)" +== 470 +-- truncate_limit: 100 +alter table trigpart4 attach partition trigpart42 for values from (3500) to (4000) +-- +TABLE: name="trigpart4" schema="" table="trigpart4" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart4 ATTACH PARTITION trigpart42 FOR VALUES FROM (3500) TO (4000)" +== 471 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text" +== 472 +-- truncate_limit: 100 +drop trigger trg1 on trigpart1 +-- +TABLE: name="trigpart1" schema="" table="trigpart1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trg1 ON trigpart1" +== 473 +-- truncate_limit: 100 +-- fail +drop trigger trg1 on trigpart2 +-- +TABLE: name="trigpart2" schema="" table="trigpart2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trg1 ON trigpart2" +== 474 +-- truncate_limit: 100 +-- fail +drop trigger trg1 on trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trg1 ON trigpart3" +== 475 +-- truncate_limit: 100 +-- fail +drop table trigpart2 +-- +TABLE: name="trigpart2" schema="" table="trigpart2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigpart2" +== 476 +-- truncate_limit: 100 +-- ok, trigger should be gone in that partition +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text" +== 477 +-- truncate_limit: 100 +drop trigger trg1 on trigpart +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trg1 ON trigpart" +== 478 +-- truncate_limit: 100 +-- ok, all gone +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text" +== 479 +-- truncate_limit: 100 +-- check detach behavior +create trigger trg1 after insert on trigpart for each row execute procedure trigger_nothing() +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trg1 AFTER INSERT ON trigpart FOR EACH ROW EXECUTE FUNCTION trigger_nothing()" +== 480 +-- truncate_limit: 100 +alter table trigpart detach partition trigpart3 +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart DETACH PARTITION trigpart3" +== 481 +-- truncate_limit: 100 +drop trigger trg1 on trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trg1 ON trigpart3" +== 482 +-- truncate_limit: 100 +-- fail due to "does not exist" +alter table trigpart detach partition trigpart4 +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart DETACH PARTITION trigpart4" +== 483 +-- truncate_limit: 100 +drop trigger trg1 on trigpart41 +-- +TABLE: name="trigpart41" schema="" table="trigpart41" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trg1 ON trigpart41" +== 484 +-- truncate_limit: 100 +-- fail due to "does not exist" +drop table trigpart4 +-- +TABLE: name="trigpart4" schema="" table="trigpart4" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigpart4" +== 485 +-- truncate_limit: 100 +alter table trigpart attach partition trigpart3 for values from (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart ATTACH PARTITION trigpart3 FOR VALUES FROM (2000) TO (3000)" +== 486 +-- truncate_limit: 100 +alter table trigpart detach partition trigpart3 +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart DETACH PARTITION trigpart3" +== 487 +-- truncate_limit: 100 +alter table trigpart attach partition trigpart3 for values from (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart ATTACH PARTITION trigpart3 FOR VALUES FROM (2000) TO (3000)" +== 488 +-- truncate_limit: 100 +drop table trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigpart3" +== 489 +-- truncate_limit: 100 +select tgrelid::regclass::text, tgname, tgfoid::regproc, tgenabled, tgisinternal from pg_trigger + where tgname ~ '^trg1' order by 1 +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE tgname ~ '^trg1' ORDER BY 1" +== 490 +-- truncate_limit: 100 +create table trigpart3 (like trigpart) +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigpart3 (LIKE trigpart)" +== 491 +-- truncate_limit: 100 +create trigger trg1 after insert on trigpart3 for each row execute procedure trigger_nothing() +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trg1 AFTER INSERT ON trigpart3 FOR EACH ROW EXECUTE FUNCTION trigger_nothing()" +== 492 +-- truncate_limit: 100 +alter table trigpart attach partition trigpart3 FOR VALUES FROM (2000) to (3000) +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigpart ATTACH PARTITION trigpart3 FOR VALUES FROM (2000) TO (3000)" +== 493 +-- truncate_limit: 100 +-- fail +drop table trigpart3 +-- +TABLE: name="trigpart3" schema="" table="trigpart3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigpart3" +== 494 +-- truncate_limit: 100 +-- check display of unrelated triggers +create trigger samename after delete on trigpart execute function trigger_nothing() +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER samename AFTER DELETE ON trigpart EXECUTE FUNCTION trigger_nothing()" +== 495 +-- truncate_limit: 100 +create trigger samename after delete on trigpart1 execute function trigger_nothing() +-- +TABLE: name="trigpart1" schema="" table="trigpart1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER samename AFTER DELETE ON trigpart1 EXECUTE FUNCTION trigger_nothing()" +== 496 +-- truncate_limit: 100 +drop table trigpart +-- +TABLE: name="trigpart" schema="" table="trigpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trigpart" +== 497 +-- truncate_limit: 100 +drop function trigger_nothing() +-- +FUNCTION: name="trigger_nothing" function="trigger_nothing" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION trigger_nothing()" +== 498 +-- truncate_limit: 100 +|-- +-- Verify that triggers are fired for partitioned tables +|-- +create table parted_stmt_trig (a int) partition by list (a) +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_stmt_trig (a int) PARTITION BY LIST (a)" +== 499 +-- truncate_limit: 100 +create table parted_stmt_trig1 partition of parted_stmt_trig for values in (1) +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_stmt_trig1 PARTITION OF parted_stmt_trig FOR VALUES IN (1)" +== 500 +-- truncate_limit: 100 +create table parted_stmt_trig2 partition of parted_stmt_trig for values in (2) +-- +TABLE: name="parted_stmt_trig2" schema="" table="parted_stmt_trig2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_stmt_trig2 PARTITION OF parted_stmt_trig FOR VALUES IN (2)" +== 501 +-- truncate_limit: 100 +create table parted2_stmt_trig (a int) partition by list (a) +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted2_stmt_trig (a int) PARTITION BY LIST (a)" +== 502 +-- truncate_limit: 100 +create table parted2_stmt_trig1 partition of parted2_stmt_trig for values in (1) +-- +TABLE: name="parted2_stmt_trig1" schema="" table="parted2_stmt_trig1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted2_stmt_trig1 PARTITION OF parted2_stmt_trig FOR VALUES IN (1)" +== 503 +-- truncate_limit: 100 +create table parted2_stmt_trig2 partition of parted2_stmt_trig for values in (2) +-- +TABLE: name="parted2_stmt_trig2" schema="" table="parted2_stmt_trig2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted2_stmt_trig2 PARTITION OF parted2_stmt_trig FOR VALUES IN (2)" +== 504 +-- truncate_limit: 100 +create or replace function trigger_notice() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %', TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL; + if TG_LEVEL = 'ROW' then + return NEW; + end if; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice" function="trigger_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION trigger_notice() RETURNS trigger AS $$\n begin\n raise notice 'trigg..." +== 505 +-- truncate_limit: 100 +-- insert/update/delete statement-level triggers on the parent +create trigger trig_ins_before before insert on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_before BEFORE INSERT ON parted_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 506 +-- truncate_limit: 100 +create trigger trig_ins_after after insert on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_after AFTER INSERT ON parted_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 507 +-- truncate_limit: 100 +create trigger trig_upd_before before update on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_before BEFORE UPDATE ON parted_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 508 +-- truncate_limit: 100 +create trigger trig_upd_after after update on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_after AFTER UPDATE ON parted_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 509 +-- truncate_limit: 100 +create trigger trig_del_before before delete on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_before BEFORE DELETE ON parted_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 510 +-- truncate_limit: 100 +create trigger trig_del_after after delete on parted_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_after AFTER DELETE ON parted_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 511 +-- truncate_limit: 100 +-- insert/update/delete row-level triggers on the parent +create trigger trig_ins_after_parent after insert on parted_stmt_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_after_parent AFTER INSERT ON parted_stmt_trig FOR EACH ROW EXECUTE FUNCTI..." +== 512 +-- truncate_limit: 100 +create trigger trig_upd_after_parent after update on parted_stmt_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_after_parent AFTER UPDATE ON parted_stmt_trig FOR EACH ROW EXECUTE FUNCTI..." +== 513 +-- truncate_limit: 100 +create trigger trig_del_after_parent after delete on parted_stmt_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_after_parent AFTER DELETE ON parted_stmt_trig FOR EACH ROW EXECUTE FUNCTI..." +== 514 +-- truncate_limit: 100 +-- insert/update/delete row-level triggers on the first partition +create trigger trig_ins_before_child before insert on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_before_child BEFORE INSERT ON parted_stmt_trig1 FOR EACH ROW EXECUTE FUNC..." +== 515 +-- truncate_limit: 100 +create trigger trig_ins_after_child after insert on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_after_child AFTER INSERT ON parted_stmt_trig1 FOR EACH ROW EXECUTE FUNCTI..." +== 516 +-- truncate_limit: 100 +create trigger trig_upd_before_child before update on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_before_child BEFORE UPDATE ON parted_stmt_trig1 FOR EACH ROW EXECUTE FUNC..." +== 517 +-- truncate_limit: 100 +create trigger trig_upd_after_child after update on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_after_child AFTER UPDATE ON parted_stmt_trig1 FOR EACH ROW EXECUTE FUNCTI..." +== 518 +-- truncate_limit: 100 +create trigger trig_del_before_child before delete on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_before_child BEFORE DELETE ON parted_stmt_trig1 FOR EACH ROW EXECUTE FUNC..." +== 519 +-- truncate_limit: 100 +create trigger trig_del_after_child after delete on parted_stmt_trig1 + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_after_child AFTER DELETE ON parted_stmt_trig1 FOR EACH ROW EXECUTE FUNCTI..." +== 520 +-- truncate_limit: 100 +-- insert/update/delete statement-level triggers on the parent +create trigger trig_ins_before_3 before insert on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_before_3 BEFORE INSERT ON parted2_stmt_trig EXECUTE FUNCTION trigger_noti..." +== 521 +-- truncate_limit: 100 +create trigger trig_ins_after_3 after insert on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_ins_after_3 AFTER INSERT ON parted2_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 522 +-- truncate_limit: 100 +create trigger trig_upd_before_3 before update on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_before_3 BEFORE UPDATE ON parted2_stmt_trig EXECUTE FUNCTION trigger_noti..." +== 523 +-- truncate_limit: 100 +create trigger trig_upd_after_3 after update on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_upd_after_3 AFTER UPDATE ON parted2_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 524 +-- truncate_limit: 100 +create trigger trig_del_before_3 before delete on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_before_3 BEFORE DELETE ON parted2_stmt_trig EXECUTE FUNCTION trigger_noti..." +== 525 +-- truncate_limit: 100 +create trigger trig_del_after_3 after delete on parted2_stmt_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_del_after_3 AFTER DELETE ON parted2_stmt_trig EXECUTE FUNCTION trigger_notice()" +== 526 +-- truncate_limit: 100 +with ins (a) as ( + insert into parted2_stmt_trig values (1), (2) returning a +) insert into parted_stmt_trig select a from ins returning tableoid::regclass, a +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DML +CTE: "ins" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH ins(a) AS (...) INSERT INTO parted_stmt_trig SELECT a FROM ins RETURNING tableoid::regclass, a" +== 527 +-- truncate_limit: 100 +with upd as ( + update parted2_stmt_trig set a = a +) update parted_stmt_trig set a = a +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DML +CTE: "upd" +STMT: UpdateStmt +TRUNCATED: "WITH upd AS (UPDATE parted2_stmt_trig SET a = a) UPDATE parted_stmt_trig SET a = a" +== 528 +-- truncate_limit: 100 +delete from parted_stmt_trig +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parted_stmt_trig" +== 529 +-- truncate_limit: 100 +-- insert via copy on the parent +copy parted_stmt_trig(a) from stdin +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parted_stmt_trig(a) FROM STDIN" +== 530 +-- truncate_limit: 100 +-- insert via copy on the first partition +copy parted_stmt_trig1(a) from stdin +-- +TABLE: name="parted_stmt_trig1" schema="" table="parted_stmt_trig1" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parted_stmt_trig1(a) FROM STDIN" +== 531 +-- truncate_limit: 100 +-- Disabling a trigger in the parent table should disable children triggers too +alter table parted_stmt_trig disable trigger trig_ins_after_parent +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_stmt_trig DISABLE TRIGGER trig_ins_after_parent" +== 532 +-- truncate_limit: 100 +insert into parted_stmt_trig values (1) +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_stmt_trig VALUES (1)" +== 533 +-- truncate_limit: 100 +alter table parted_stmt_trig enable trigger trig_ins_after_parent +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_stmt_trig ENABLE TRIGGER trig_ins_after_parent" +== 534 +-- truncate_limit: 100 +insert into parted_stmt_trig values (1) +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_stmt_trig VALUES (1)" +== 535 +-- truncate_limit: 100 +drop table parted_stmt_trig, parted2_stmt_trig +-- +TABLE: name="parted_stmt_trig" schema="" table="parted_stmt_trig" ctx=DDL +TABLE: name="parted2_stmt_trig" schema="" table="parted2_stmt_trig" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_stmt_trig, parted2_stmt_trig" +== 536 +-- truncate_limit: 100 +-- Verify that triggers fire in alphabetical order +create table parted_trig (a int) partition by range (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig (a int) PARTITION BY RANGE (a)" +== 537 +-- truncate_limit: 100 +create table parted_trig_1 partition of parted_trig for values from (0) to (1000) + partition by range (a) +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig_1 PARTITION OF parted_trig FOR VALUES FROM (0) TO (1000) PARTITION BY RA..." +== 538 +-- truncate_limit: 100 +create table parted_trig_1_1 partition of parted_trig_1 for values from (0) to (100) +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig_1_1 PARTITION OF parted_trig_1 FOR VALUES FROM (0) TO (100)" +== 539 +-- truncate_limit: 100 +create table parted_trig_2 partition of parted_trig for values from (1000) to (2000) +-- +TABLE: name="parted_trig_2" schema="" table="parted_trig_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig_2 PARTITION OF parted_trig FOR VALUES FROM (1000) TO (2000)" +== 540 +-- truncate_limit: 100 +create trigger zzz after insert on parted_trig for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER zzz AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION trigger_notice()" +== 541 +-- truncate_limit: 100 +create trigger mmm after insert on parted_trig_1_1 for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER mmm AFTER INSERT ON parted_trig_1_1 FOR EACH ROW EXECUTE FUNCTION trigger_notice()" +== 542 +-- truncate_limit: 100 +create trigger aaa after insert on parted_trig_1 for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER aaa AFTER INSERT ON parted_trig_1 FOR EACH ROW EXECUTE FUNCTION trigger_notice()" +== 543 +-- truncate_limit: 100 +create trigger bbb after insert on parted_trig for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER bbb AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION trigger_notice()" +== 544 +-- truncate_limit: 100 +create trigger qqq after insert on parted_trig_1_1 for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER qqq AFTER INSERT ON parted_trig_1_1 FOR EACH ROW EXECUTE FUNCTION trigger_notice()" +== 545 +-- truncate_limit: 100 +insert into parted_trig values (50), (1500) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig VALUES (50), (1500)" +== 546 +-- truncate_limit: 100 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_trig" +== 547 +-- truncate_limit: 100 +-- Verify that the correct triggers fire for cross-partition updates +create table parted_trig (a int) partition by list (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig (a int) PARTITION BY LIST (a)" +== 548 +-- truncate_limit: 100 +create table parted_trig1 partition of parted_trig for values in (1) +-- +TABLE: name="parted_trig1" schema="" table="parted_trig1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig1 PARTITION OF parted_trig FOR VALUES IN (1)" +== 549 +-- truncate_limit: 100 +create table parted_trig2 partition of parted_trig for values in (2) +-- +TABLE: name="parted_trig2" schema="" table="parted_trig2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig2 PARTITION OF parted_trig FOR VALUES IN (2)" +== 550 +-- truncate_limit: 100 +insert into parted_trig values (1) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig VALUES (1)" +== 551 +-- truncate_limit: 100 +create or replace function trigger_notice() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %', TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL; + if TG_LEVEL = 'ROW' then + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; + end if; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice" function="trigger_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION trigger_notice() RETURNS trigger AS $$\n begin\n raise notice 'trigg..." +== 552 +-- truncate_limit: 100 +create trigger parted_trig_before_stmt before insert or update or delete on parted_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trig_before_stmt BEFORE INSERT OR DELETE OR UPDATE ON parted_trig EXECUTE F..." +== 553 +-- truncate_limit: 100 +create trigger parted_trig_before_row before insert or update or delete on parted_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trig_before_row BEFORE INSERT OR DELETE OR UPDATE ON parted_trig FOR EACH R..." +== 554 +-- truncate_limit: 100 +create trigger parted_trig_after_row after insert or update or delete on parted_trig + for each row execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trig_after_row AFTER INSERT OR DELETE OR UPDATE ON parted_trig FOR EACH ROW..." +== 555 +-- truncate_limit: 100 +create trigger parted_trig_after_stmt after insert or update or delete on parted_trig + for each statement execute procedure trigger_notice() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trig_after_stmt AFTER INSERT OR DELETE OR UPDATE ON parted_trig EXECUTE FUN..." +== 556 +-- truncate_limit: 100 +update parted_trig set a = 2 where a = 1 +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted_trig SET a = 2 WHERE a = 1" +== 557 +-- truncate_limit: 100 +-- update action in merge should behave the same +merge into parted_trig using (select 1) as ss on true + when matched and a = 2 then update set a = 1 +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO parted_trig USING (SELECT 1) ss ON true WHEN MATCHED AND a = 2 THEN UPDATE SET a = 1" +== 558 +-- truncate_limit: 100 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_trig" +== 559 +-- truncate_limit: 100 +-- Verify propagation of trigger arguments to partitions +create table parted_trig (a int) partition by list (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig (a int) PARTITION BY LIST (a)" +== 560 +-- truncate_limit: 100 +create table parted_trig1 partition of parted_trig for values in (1) +-- +TABLE: name="parted_trig1" schema="" table="parted_trig1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig1 PARTITION OF parted_trig FOR VALUES IN (1)" +== 561 +-- truncate_limit: 100 +create or replace function trigger_notice() returns trigger as $$ + declare + arg1 text = TG_ARGV[0]; + arg2 integer = TG_ARGV[1]; + begin + raise notice 'trigger % on % % % for % args % %', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, arg1, arg2; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice" function="trigger_notice" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION trigger_notice() RETURNS trigger AS $$\n declare\n arg1 text = TG_AR..." +== 562 +-- truncate_limit: 100 +create trigger aaa after insert on parted_trig + for each row execute procedure trigger_notice('quirky', 1) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER aaa AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION trigger_notice('quir..." +== 563 +-- truncate_limit: 100 +-- Verify propagation of trigger arguments to partitions attached after creating trigger +create table parted_trig2 partition of parted_trig for values in (2) +-- +TABLE: name="parted_trig2" schema="" table="parted_trig2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig2 PARTITION OF parted_trig FOR VALUES IN (2)" +== 564 +-- truncate_limit: 100 +create table parted_trig3 (like parted_trig) +-- +TABLE: name="parted_trig3" schema="" table="parted_trig3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig3 (LIKE parted_trig)" +== 565 +-- truncate_limit: 100 +alter table parted_trig attach partition parted_trig3 for values in (3) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trig ATTACH PARTITION parted_trig3 FOR VALUES IN (3)" +== 566 +-- truncate_limit: 100 +insert into parted_trig values (1), (2), (3) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig VALUES (1), (2), (3)" +== 567 +-- truncate_limit: 100 +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_trig" +== 568 +-- truncate_limit: 100 +-- test irregular partitions (i.e., different column definitions), +-- including that the WHEN clause works +create function bark(text) returns bool language plpgsql immutable + as $$ begin raise notice '% <- woof!', $1; return true; end; $$ +-- +FUNCTION: name="bark" function="bark" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION bark(text) RETURNS bool LANGUAGE plpgsql IMMUTABLE AS $$ begin raise notice '% <-..." +== 569 +-- truncate_limit: 100 +create or replace function trigger_notice_ab() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %: (a,b)=(%,%)', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, + NEW.a, NEW.b; + if TG_LEVEL = 'ROW' then + return NEW; + end if; + return null; + end; + $$ language plpgsql +-- +FUNCTION: name="trigger_notice_ab" function="trigger_notice_ab" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION trigger_notice_ab() RETURNS trigger AS $$\n begin\n raise notice 'tr..." +== 570 +-- truncate_limit: 100 +create table parted_irreg_ancestor (fd text, b text, fd2 int, fd3 int, a int) + partition by range (b) +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_irreg_ancestor (fd text, b text, fd2 int, fd3 int, a int) PARTITION BY RANGE (b)" +== 571 +-- truncate_limit: 100 +alter table parted_irreg_ancestor drop column fd, + drop column fd2, drop column fd3 +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_irreg_ancestor DROP fd, DROP fd2, DROP fd3" +== 572 +-- truncate_limit: 100 +create table parted_irreg (fd int, a int, fd2 int, b text) + partition by range (b) +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_irreg (fd int, a int, fd2 int, b text) PARTITION BY RANGE (b)" +== 573 +-- truncate_limit: 100 +alter table parted_irreg drop column fd, drop column fd2 +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_irreg DROP fd, DROP fd2" +== 574 +-- truncate_limit: 100 +alter table parted_irreg_ancestor attach partition parted_irreg + for values from ('aaaa') to ('zzzz') +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_irreg_ancestor ATTACH PARTITION parted_irreg FOR VALUES FROM ('aaaa') TO ('zzzz')" +== 575 +-- truncate_limit: 100 +create table parted1_irreg (b text, fd int, a int) +-- +TABLE: name="parted1_irreg" schema="" table="parted1_irreg" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted1_irreg (b text, fd int, a int)" +== 576 +-- truncate_limit: 100 +alter table parted1_irreg drop column fd +-- +TABLE: name="parted1_irreg" schema="" table="parted1_irreg" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted1_irreg DROP fd" +== 577 +-- truncate_limit: 100 +alter table parted_irreg attach partition parted1_irreg + for values from ('aaaa') to ('bbbb') +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_irreg ATTACH PARTITION parted1_irreg FOR VALUES FROM ('aaaa') TO ('bbbb')" +== 578 +-- truncate_limit: 100 +create trigger parted_trig after insert on parted_irreg + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trig AFTER INSERT ON parted_irreg FOR EACH ROW EXECUTE FUNCTION trigger_not..." +== 579 +-- truncate_limit: 100 +create trigger parted_trig_odd after insert on parted_irreg for each row + when (bark(new.b) AND new.a % 2 = 1) execute procedure trigger_notice_ab() +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trig_odd AFTER INSERT ON parted_irreg FOR EACH ROW WHEN (bark(new.b) AND (n..." +== 580 +-- truncate_limit: 100 +-- we should hear barking for every insert, but parted_trig_odd only emits +-- noise for odd values of a. parted_trig does it for all inserts. +insert into parted_irreg values (1, 'aardvark'), (2, 'aanimals') +-- +TABLE: name="parted_irreg" schema="" table="parted_irreg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_irreg VALUES (1, 'aardvark'), (2, 'aanimals')" +== 581 +-- truncate_limit: 100 +insert into parted1_irreg values ('aardwolf', 2) +-- +TABLE: name="parted1_irreg" schema="" table="parted1_irreg" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted1_irreg VALUES ('aardwolf', 2)" +== 582 +-- truncate_limit: 100 +insert into parted_irreg_ancestor values ('aasvogel', 3) +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_irreg_ancestor VALUES ('aasvogel', 3)" +== 583 +-- truncate_limit: 100 +drop table parted_irreg_ancestor +-- +TABLE: name="parted_irreg_ancestor" schema="" table="parted_irreg_ancestor" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_irreg_ancestor" +== 584 +-- truncate_limit: 100 +-- Before triggers and partitions +create table parted (a int, b int, c text) partition by list (a) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted (a int, b int, c text) PARTITION BY LIST (a)" +== 585 +-- truncate_limit: 100 +create table parted_1 partition of parted for values in (1) + partition by list (b) +-- +TABLE: name="parted_1" schema="" table="parted_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_1 PARTITION OF parted FOR VALUES IN (1) PARTITION BY LIST (b)" +== 586 +-- truncate_limit: 100 +create table parted_1_1 partition of parted_1 for values in (1) +-- +TABLE: name="parted_1_1" schema="" table="parted_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_1_1 PARTITION OF parted_1 FOR VALUES IN (1)" +== 587 +-- truncate_limit: 100 +create function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.a = new.a + 1; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION parted_trigfunc() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n new.a = new.a + ..." +== 588 +-- truncate_limit: 100 +insert into parted values (1, 1, 'uno uno v1') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 1, 'uno uno v1')" +== 589 +-- truncate_limit: 100 +-- works +create trigger t before insert or update or delete on parted + for each row execute function parted_trigfunc() +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER t BEFORE INSERT OR DELETE OR UPDATE ON parted FOR EACH ROW EXECUTE FUNCTION parted..." +== 590 +-- truncate_limit: 100 +insert into parted values (1, 1, 'uno uno v2') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 1, 'uno uno v2')" +== 591 +-- truncate_limit: 100 +-- fail +update parted set c = c || 'v3' +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted SET c = c || 'v3'" +== 592 +-- truncate_limit: 100 +-- fail +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.b = new.b + 1; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION parted_trigfunc() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n new.b..." +== 593 +-- truncate_limit: 100 +insert into parted values (1, 1, 'uno uno v4') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 1, 'uno uno v4')" +== 594 +-- truncate_limit: 100 +-- fail +update parted set c = c || 'v5' +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted SET c = c || 'v5'" +== 595 +-- truncate_limit: 100 +-- fail +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.c = new.c || ' did '|| TG_OP; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION parted_trigfunc() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n new.c..." +== 596 +-- truncate_limit: 100 +insert into parted values (1, 1, 'uno uno') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 1, 'uno uno')" +== 597 +-- truncate_limit: 100 +-- works +update parted set c = c || ' v6' +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted SET c = c || ' v6'" +== 598 +-- truncate_limit: 100 +-- works +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM parted" +== 599 +-- truncate_limit: 100 +-- update itself moves tuple to new partition; trigger still works +truncate table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted" +== 600 +-- truncate_limit: 100 +create table parted_2 partition of parted for values in (2) +-- +TABLE: name="parted_2" schema="" table="parted_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_2 PARTITION OF parted FOR VALUES IN (2)" +== 601 +-- truncate_limit: 100 +insert into parted values (1, 1, 'uno uno v5') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 1, 'uno uno v5')" +== 602 +-- truncate_limit: 100 +update parted set a = 2 +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted SET a = 2" +== 603 +-- truncate_limit: 100 +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM parted" +== 604 +-- truncate_limit: 100 +-- both trigger and update change the partition +create or replace function parted_trigfunc2() returns trigger language plpgsql as $$ +begin + new.a = new.a + 1; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc2" function="parted_trigfunc2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION parted_trigfunc2() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n new...." +== 605 +-- truncate_limit: 100 +create trigger t2 before update on parted + for each row execute function parted_trigfunc2() +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER t2 BEFORE UPDATE ON parted FOR EACH ROW EXECUTE FUNCTION parted_trigfunc2()" +== 606 +-- truncate_limit: 100 +truncate table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE parted" +== 607 +-- truncate_limit: 100 +insert into parted values (1, 1, 'uno uno v6') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 1, 'uno uno v6')" +== 608 +-- truncate_limit: 100 +create table parted_3 partition of parted for values in (3) +-- +TABLE: name="parted_3" schema="" table="parted_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_3 PARTITION OF parted FOR VALUES IN (3)" +== 609 +-- truncate_limit: 100 +update parted set a = a + 1 +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted SET a = a + 1" +== 610 +-- truncate_limit: 100 +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM parted" +== 611 +-- truncate_limit: 100 +-- there's no partition for a=0, but this update works anyway because +-- the trigger causes the tuple to be routed to another partition +update parted set a = 0 +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted SET a = 0" +== 612 +-- truncate_limit: 100 +select tableoid::regclass, * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM parted" +== 613 +-- truncate_limit: 100 +drop table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted" +== 614 +-- truncate_limit: 100 +create table parted (a int, b int, c text) partition by list ((a + b)) +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted (a int, b int, c text) PARTITION BY LIST ((a + b))" +== 615 +-- truncate_limit: 100 +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.a = new.a + new.b; + return new; +end; +$$ +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION parted_trigfunc() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\n new.a..." +== 616 +-- truncate_limit: 100 +create table parted_1 partition of parted for values in (1, 2) +-- +TABLE: name="parted_1" schema="" table="parted_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_1 PARTITION OF parted FOR VALUES IN (1, 2)" +== 617 +-- truncate_limit: 100 +create table parted_2 partition of parted for values in (3, 4) +-- +TABLE: name="parted_2" schema="" table="parted_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_2 PARTITION OF parted FOR VALUES IN (3, 4)" +== 618 +-- truncate_limit: 100 +create trigger t before insert or update on parted + for each row execute function parted_trigfunc() +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER t BEFORE INSERT OR UPDATE ON parted FOR EACH ROW EXECUTE FUNCTION parted_trigfunc()" +== 619 +-- truncate_limit: 100 +insert into parted values (0, 1, 'zero win') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (0, 1, 'zero win')" +== 620 +-- truncate_limit: 100 +insert into parted values (1, 1, 'one fail') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 1, 'one fail')" +== 621 +-- truncate_limit: 100 +insert into parted values (1, 2, 'two fail') +-- +TABLE: name="parted" schema="" table="parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted VALUES (1, 2, 'two fail')" +== 622 +-- truncate_limit: 100 +select * from parted +-- +TABLE: name="parted" schema="" table="parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parted" +== 623 +-- truncate_limit: 100 +drop table parted +-- +TABLE: name="parted" schema="" table="parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted" +== 624 +-- truncate_limit: 100 +drop function parted_trigfunc() +-- +FUNCTION: name="parted_trigfunc" function="parted_trigfunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION parted_trigfunc()" +== 625 +-- truncate_limit: 100 +|-- +-- Constraint triggers and partitioned tables +create table parted_constr_ancestor (a int, b text) + partition by range (b) +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_constr_ancestor (a int, b text) PARTITION BY RANGE (b)" +== 626 +-- truncate_limit: 100 +create table parted_constr (a int, b text) + partition by range (b) +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_constr (a int, b text) PARTITION BY RANGE (b)" +== 627 +-- truncate_limit: 100 +alter table parted_constr_ancestor attach partition parted_constr + for values from ('aaaa') to ('zzzz') +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_constr_ancestor ATTACH PARTITION parted_constr FOR VALUES FROM ('aaaa') TO ('z..." +== 628 +-- truncate_limit: 100 +create table parted1_constr (a int, b text) +-- +TABLE: name="parted1_constr" schema="" table="parted1_constr" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted1_constr (a int, b text)" +== 629 +-- truncate_limit: 100 +alter table parted_constr attach partition parted1_constr + for values from ('aaaa') to ('bbbb') +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_constr ATTACH PARTITION parted1_constr FOR VALUES FROM ('aaaa') TO ('bbbb')" +== 630 +-- truncate_limit: 100 +create constraint trigger parted_trig after insert on parted_constr_ancestor + deferrable + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER parted_trig AFTER INSERT ON parted_constr_ancestor DEFERRABLE FOR EACH ..." +== 631 +-- truncate_limit: 100 +create constraint trigger parted_trig_two after insert on parted_constr + deferrable initially deferred + for each row when (bark(new.b) AND new.a % 2 = 1) + execute procedure trigger_notice_ab() +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER parted_trig_two AFTER INSERT ON parted_constr DEFERRABLE INITIALLY DEFE..." +== 632 +-- truncate_limit: 100 +-- The immediate constraint is fired immediately; the WHEN clause of the +-- deferred constraint is also called immediately. The deferred constraint +-- is fired at commit time. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 633 +-- truncate_limit: 100 +insert into parted_constr values (1, 'aardvark') +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_constr VALUES (1, 'aardvark')" +== 634 +-- truncate_limit: 100 +insert into parted1_constr values (2, 'aardwolf') +-- +TABLE: name="parted1_constr" schema="" table="parted1_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted1_constr VALUES (2, 'aardwolf')" +== 635 +-- truncate_limit: 100 +insert into parted_constr_ancestor values (3, 'aasvogel') +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_constr_ancestor VALUES (3, 'aasvogel')" +== 636 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 637 +-- truncate_limit: 100 +-- The WHEN clause is immediate, and both constraint triggers are fired at +-- commit time. +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 638 +-- truncate_limit: 100 +set constraints parted_trig deferred +-- +STMT: ConstraintsSetStmt +TRUNCATED: "SET CONSTRAINTS parted_trig DEFERRED" +== 639 +-- truncate_limit: 100 +insert into parted_constr values (1, 'aardvark') +-- +TABLE: name="parted_constr" schema="" table="parted_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_constr VALUES (1, 'aardvark')" +== 640 +-- truncate_limit: 100 +insert into parted1_constr values (2, 'aardwolf'), (3, 'aasvogel') +-- +TABLE: name="parted1_constr" schema="" table="parted1_constr" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted1_constr VALUES (2, 'aardwolf'), (3, 'aasvogel')" +== 641 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 642 +-- truncate_limit: 100 +drop table parted_constr_ancestor +-- +TABLE: name="parted_constr_ancestor" schema="" table="parted_constr_ancestor" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_constr_ancestor" +== 643 +-- truncate_limit: 100 +drop function bark(text) +-- +FUNCTION: name="bark" function="bark" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION bark(text)" +== 644 +-- truncate_limit: 100 +-- Test that the WHEN clause is set properly to partitions +create table parted_trigger (a int, b text) partition by range (a) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger (a int, b text) PARTITION BY RANGE (a)" +== 645 +-- truncate_limit: 100 +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000) +-- +TABLE: name="parted_trigger_1" schema="" table="parted_trigger_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_1 PARTITION OF parted_trigger FOR VALUES FROM (0) TO (1000)" +== 646 +-- truncate_limit: 100 +create table parted_trigger_2 (drp int, a int, b text) +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_2 (drp int, a int, b text)" +== 647 +-- truncate_limit: 100 +alter table parted_trigger_2 drop column drp +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger_2 DROP drp" +== 648 +-- truncate_limit: 100 +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger ATTACH PARTITION parted_trigger_2 FOR VALUES FROM (1000) TO (2000)" +== 649 +-- truncate_limit: 100 +create trigger parted_trigger after update on parted_trigger + for each row when (new.a % 2 = 1 and length(old.b) >= 2) execute procedure trigger_notice_ab() +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trigger AFTER UPDATE ON parted_trigger FOR EACH ROW WHEN ((new.a % 2) = 1 A..." +== 650 +-- truncate_limit: 100 +create table parted_trigger_3 (b text, a int) partition by range (length(b)) +-- +TABLE: name="parted_trigger_3" schema="" table="parted_trigger_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3 (b text, a int) PARTITION BY RANGE ((length(b)))" +== 651 +-- truncate_limit: 100 +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (3) +-- +TABLE: name="parted_trigger_3_1" schema="" table="parted_trigger_3_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3_1 PARTITION OF parted_trigger_3 FOR VALUES FROM (1) TO (3)" +== 652 +-- truncate_limit: 100 +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (3) to (5) +-- +TABLE: name="parted_trigger_3_2" schema="" table="parted_trigger_3_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3_2 PARTITION OF parted_trigger_3 FOR VALUES FROM (3) TO (5)" +== 653 +-- truncate_limit: 100 +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger ATTACH PARTITION parted_trigger_3 FOR VALUES FROM (2000) TO (3000)" +== 654 +-- truncate_limit: 100 +insert into parted_trigger values + (0, 'a'), (1, 'bbb'), (2, 'bcd'), (3, 'c'), + (1000, 'c'), (1001, 'ddd'), (1002, 'efg'), (1003, 'f'), + (2000, 'e'), (2001, 'fff'), (2002, 'ghi'), (2003, 'h') +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trigger VALUES (...)" +== 655 +-- truncate_limit: 100 +update parted_trigger set a = a + 2 +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted_trigger SET a = a + 2" +== 656 +-- truncate_limit: 100 +-- notice for odd 'a' values, long 'b' values +drop table parted_trigger +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_trigger" +== 657 +-- truncate_limit: 100 +-- try a constraint trigger, also +create table parted_referenced (a int) +-- +TABLE: name="parted_referenced" schema="" table="parted_referenced" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_referenced (a int)" +== 658 +-- truncate_limit: 100 +create table unparted_trigger (a int, b text) +-- +TABLE: name="unparted_trigger" schema="" table="unparted_trigger" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE unparted_trigger (a int, b text)" +== 659 +-- truncate_limit: 100 +-- for comparison purposes +create table parted_trigger (a int, b text) partition by range (a) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger (a int, b text) PARTITION BY RANGE (a)" +== 660 +-- truncate_limit: 100 +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000) +-- +TABLE: name="parted_trigger_1" schema="" table="parted_trigger_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_1 PARTITION OF parted_trigger FOR VALUES FROM (0) TO (1000)" +== 661 +-- truncate_limit: 100 +create table parted_trigger_2 (drp int, a int, b text) +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_2 (drp int, a int, b text)" +== 662 +-- truncate_limit: 100 +alter table parted_trigger_2 drop column drp +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger_2 DROP drp" +== 663 +-- truncate_limit: 100 +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger ATTACH PARTITION parted_trigger_2 FOR VALUES FROM (1000) TO (2000)" +== 664 +-- truncate_limit: 100 +create constraint trigger parted_trigger after update on parted_trigger + from parted_referenced + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER parted_trigger AFTER UPDATE ON parted_trigger FROM parted_referenced FO..." +== 665 +-- truncate_limit: 100 +create constraint trigger parted_trigger after update on unparted_trigger + from parted_referenced + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="unparted_trigger" schema="" table="unparted_trigger" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE CONSTRAINT TRIGGER parted_trigger AFTER UPDATE ON unparted_trigger FROM parted_referenced ..." +== 666 +-- truncate_limit: 100 +create table parted_trigger_3 (b text, a int) partition by range (length(b)) +-- +TABLE: name="parted_trigger_3" schema="" table="parted_trigger_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3 (b text, a int) PARTITION BY RANGE ((length(b)))" +== 667 +-- truncate_limit: 100 +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (3) +-- +TABLE: name="parted_trigger_3_1" schema="" table="parted_trigger_3_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3_1 PARTITION OF parted_trigger_3 FOR VALUES FROM (1) TO (3)" +== 668 +-- truncate_limit: 100 +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (3) to (5) +-- +TABLE: name="parted_trigger_3_2" schema="" table="parted_trigger_3_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3_2 PARTITION OF parted_trigger_3 FOR VALUES FROM (3) TO (5)" +== 669 +-- truncate_limit: 100 +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger ATTACH PARTITION parted_trigger_3 FOR VALUES FROM (2000) TO (3000)" +== 670 +-- truncate_limit: 100 +select tgname, conname, t.tgrelid::regclass, t.tgconstrrelid::regclass, + c.conrelid::regclass, c.confrelid::regclass + from pg_trigger t join pg_constraint c on (t.tgconstraint = c.oid) + where tgname = 'parted_trigger' + order by t.tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_constraint" schema="" table="pg_constraint" ctx=Select +ALIAS: "c"="pg_constraint" +ALIAS: "t"="pg_trigger" +FILTER: schema="" table="" column="tgname" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger t JOIN pg_constraint c ON t.tgconstraint = c.oid WHERE ... ORDER BY t...." +== 671 +-- truncate_limit: 100 +drop table parted_referenced, parted_trigger, unparted_trigger +-- +TABLE: name="parted_referenced" schema="" table="parted_referenced" ctx=DDL +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +TABLE: name="unparted_trigger" schema="" table="unparted_trigger" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_referenced, parted_trigger, unparted_trigger" +== 672 +-- truncate_limit: 100 +-- verify that the "AFTER UPDATE OF columns" event is propagated correctly +create table parted_trigger (a int, b text) partition by range (a) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger (a int, b text) PARTITION BY RANGE (a)" +== 673 +-- truncate_limit: 100 +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000) +-- +TABLE: name="parted_trigger_1" schema="" table="parted_trigger_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_1 PARTITION OF parted_trigger FOR VALUES FROM (0) TO (1000)" +== 674 +-- truncate_limit: 100 +create table parted_trigger_2 (drp int, a int, b text) +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_2 (drp int, a int, b text)" +== 675 +-- truncate_limit: 100 +alter table parted_trigger_2 drop column drp +-- +TABLE: name="parted_trigger_2" schema="" table="parted_trigger_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger_2 DROP drp" +== 676 +-- truncate_limit: 100 +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger ATTACH PARTITION parted_trigger_2 FOR VALUES FROM (1000) TO (2000)" +== 677 +-- truncate_limit: 100 +create trigger parted_trigger after update of b on parted_trigger + for each row execute procedure trigger_notice_ab() +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_trigger AFTER UPDATE OF b ON parted_trigger FOR EACH ROW EXECUTE FUNCTION t..." +== 678 +-- truncate_limit: 100 +create table parted_trigger_3 (b text, a int) partition by range (length(b)) +-- +TABLE: name="parted_trigger_3" schema="" table="parted_trigger_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3 (b text, a int) PARTITION BY RANGE ((length(b)))" +== 679 +-- truncate_limit: 100 +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (4) +-- +TABLE: name="parted_trigger_3_1" schema="" table="parted_trigger_3_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3_1 PARTITION OF parted_trigger_3 FOR VALUES FROM (1) TO (4)" +== 680 +-- truncate_limit: 100 +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (4) to (8) +-- +TABLE: name="parted_trigger_3_2" schema="" table="parted_trigger_3_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trigger_3_2 PARTITION OF parted_trigger_3 FOR VALUES FROM (4) TO (8)" +== 681 +-- truncate_limit: 100 +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000) +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parted_trigger ATTACH PARTITION parted_trigger_3 FOR VALUES FROM (2000) TO (3000)" +== 682 +-- truncate_limit: 100 +insert into parted_trigger values (0, 'a'), (1000, 'c'), (2000, 'e'), (2001, 'eeee') +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trigger VALUES (0, 'a'), (1000, 'c'), (2000, 'e'), (2001, 'eeee')" +== 683 +-- truncate_limit: 100 +update parted_trigger set a = a + 2 +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted_trigger SET a = a + 2" +== 684 +-- truncate_limit: 100 +-- no notices here +update parted_trigger set b = b || 'b' +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parted_trigger SET b = b || 'b'" +== 685 +-- truncate_limit: 100 +-- all triggers should fire +drop table parted_trigger +-- +TABLE: name="parted_trigger" schema="" table="parted_trigger" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_trigger" +== 686 +-- truncate_limit: 100 +drop function trigger_notice_ab() +-- +FUNCTION: name="trigger_notice_ab" function="trigger_notice_ab" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION trigger_notice_ab()" +== 687 +-- truncate_limit: 100 +-- Make sure we don't end up with unnecessary copies of triggers, when +-- cloning them. +create table trg_clone (a int) partition by range (a) +-- +TABLE: name="trg_clone" schema="" table="trg_clone" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trg_clone (a int) PARTITION BY RANGE (a)" +== 688 +-- truncate_limit: 100 +create table trg_clone1 partition of trg_clone for values from (0) to (1000) +-- +TABLE: name="trg_clone1" schema="" table="trg_clone1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trg_clone1 PARTITION OF trg_clone FOR VALUES FROM (0) TO (1000)" +== 689 +-- truncate_limit: 100 +alter table trg_clone add constraint uniq unique (a) deferrable +-- +TABLE: name="trg_clone" schema="" table="trg_clone" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trg_clone ADD CONSTRAINT uniq UNIQUE (a) DEFERRABLE" +== 690 +-- truncate_limit: 100 +create table trg_clone2 partition of trg_clone for values from (1000) to (2000) +-- +TABLE: name="trg_clone2" schema="" table="trg_clone2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trg_clone2 PARTITION OF trg_clone FOR VALUES FROM (1000) TO (2000)" +== 691 +-- truncate_limit: 100 +create table trg_clone3 partition of trg_clone for values from (2000) to (3000) + partition by range (a) +-- +TABLE: name="trg_clone3" schema="" table="trg_clone3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trg_clone3 PARTITION OF trg_clone FOR VALUES FROM (2000) TO (3000) PARTITION BY RANG..." +== 692 +-- truncate_limit: 100 +create table trg_clone_3_3 partition of trg_clone3 for values from (2000) to (2100) +-- +TABLE: name="trg_clone_3_3" schema="" table="trg_clone_3_3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trg_clone_3_3 PARTITION OF trg_clone3 FOR VALUES FROM (2000) TO (2100)" +== 693 +-- truncate_limit: 100 +select tgrelid::regclass, count(*) from pg_trigger + where tgrelid::regclass in ('trg_clone', 'trg_clone1', 'trg_clone2', + 'trg_clone3', 'trg_clone_3_3') + group by tgrelid::regclass order by tgrelid::regclass +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... GROUP BY tgrelid::regclass ORDER BY tgrelid::regclass" +== 694 +-- truncate_limit: 100 +drop table trg_clone +-- +TABLE: name="trg_clone" schema="" table="trg_clone" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trg_clone" +== 695 +-- truncate_limit: 100 +-- Test the interaction between ALTER TABLE .. DISABLE TRIGGER and +-- both kinds of inheritance. Historically, legacy inheritance has +-- not recursed to children, so that behavior is preserved. +create table parent (a int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a int)" +== 696 +-- truncate_limit: 100 +create table child1 () inherits (parent) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child1 () INHERITS (parent)" +== 697 +-- truncate_limit: 100 +create function trig_nothing() returns trigger language plpgsql + as $$ begin return null; end $$ +-- +FUNCTION: name="trig_nothing" function="trig_nothing" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trig_nothing() RETURNS trigger LANGUAGE plpgsql AS $$ begin return null; end $$" +== 698 +-- truncate_limit: 100 +create trigger tg after insert on parent + for each row execute function trig_nothing() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg AFTER INSERT ON parent FOR EACH ROW EXECUTE FUNCTION trig_nothing()" +== 699 +-- truncate_limit: 100 +create trigger tg after insert on child1 + for each row execute function trig_nothing() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg AFTER INSERT ON child1 FOR EACH ROW EXECUTE FUNCTION trig_nothing()" +== 700 +-- truncate_limit: 100 +alter table parent disable trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent DISABLE TRIGGER tg" +== 701 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text" +== 702 +-- truncate_limit: 100 +alter table only parent enable always trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parent ENABLE ALWAYS TRIGGER tg" +== 703 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text" +== 704 +-- truncate_limit: 100 +drop table parent, child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent, child1" +== 705 +-- truncate_limit: 100 +create table parent (a int) partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a int) PARTITION BY LIST (a)" +== 706 +-- truncate_limit: 100 +create table child1 partition of parent for values in (1) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child1 PARTITION OF parent FOR VALUES IN (1)" +== 707 +-- truncate_limit: 100 +create trigger tg after insert on parent + for each row execute procedure trig_nothing() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg AFTER INSERT ON parent FOR EACH ROW EXECUTE FUNCTION trig_nothing()" +== 708 +-- truncate_limit: 100 +create trigger tg_stmt after insert on parent + for statement execute procedure trig_nothing() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg_stmt AFTER INSERT ON parent EXECUTE FUNCTION trig_nothing()" +== 709 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text, tgname" +== 710 +-- truncate_limit: 100 +alter table only parent enable always trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY parent ENABLE ALWAYS TRIGGER tg" +== 711 +-- truncate_limit: 100 +-- no recursion because ONLY +alter table parent enable always trigger tg_stmt +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ENABLE ALWAYS TRIGGER tg_stmt" +== 712 +-- truncate_limit: 100 +-- no recursion because statement trigger +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text, tgname" +== 713 +-- truncate_limit: 100 +-- The following is a no-op for the parent trigger but not so +-- for the child trigger, so recursion should be applied. +alter table parent enable always trigger tg +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ENABLE ALWAYS TRIGGER tg" +== 714 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text, tgname" +== 715 +-- truncate_limit: 100 +-- This variant malfunctioned in some releases. +alter table parent disable trigger user +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent DISABLE TRIGGER USER" +== 716 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text, tgname" +== 717 +-- truncate_limit: 100 +drop table parent, child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent, child1" +== 718 +-- truncate_limit: 100 +-- Check processing of foreign key triggers +create table parent (a int primary key, f int references parent) + partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a int PRIMARY KEY, f int REFERENCES parent) PARTITION BY LIST (a)" +== 719 +-- truncate_limit: 100 +create table child1 partition of parent for values in (1) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child1 PARTITION OF parent FOR VALUES IN (1)" +== 720 +-- truncate_limit: 100 +select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname, + tgfoid::regproc, tgenabled + from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgfoid +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="rtrim" function="rtrim" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text, tgfoid" +== 721 +-- truncate_limit: 100 +alter table parent disable trigger all +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent DISABLE TRIGGER ALL" +== 722 +-- truncate_limit: 100 +select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname, + tgfoid::regproc, tgenabled + from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgfoid +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +FUNCTION: name="rtrim" function="rtrim" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text, tgfoid" +== 723 +-- truncate_limit: 100 +drop table parent, child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent, child1" +== 724 +-- truncate_limit: 100 +-- Verify that firing state propagates correctly on creation, too +CREATE TABLE trgfire (i int) PARTITION BY RANGE (i) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire (i int) PARTITION BY RANGE (i)" +== 725 +-- truncate_limit: 100 +CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10) +-- +TABLE: name="trgfire1" schema="" table="trgfire1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10)" +== 726 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION tgf() RETURNS trigger LANGUAGE plpgsql + AS $$ begin raise exception 'except'; end $$ +-- +FUNCTION: name="tgf" function="tgf" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION tgf() RETURNS trigger LANGUAGE plpgsql AS $$ begin raise exception 'ex..." +== 727 +-- truncate_limit: 100 +CREATE TRIGGER tg AFTER INSERT ON trgfire FOR EACH ROW EXECUTE FUNCTION tgf() +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tg AFTER INSERT ON trgfire FOR EACH ROW EXECUTE FUNCTION tgf()" +== 728 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (1) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (1)" +== 729 +-- truncate_limit: 100 +ALTER TABLE trgfire DISABLE TRIGGER tg +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trgfire DISABLE TRIGGER tg" +== 730 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (1) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (1)" +== 731 +-- truncate_limit: 100 +CREATE TABLE trgfire2 PARTITION OF trgfire FOR VALUES FROM (10) TO (20) +-- +TABLE: name="trgfire2" schema="" table="trgfire2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire2 PARTITION OF trgfire FOR VALUES FROM (10) TO (20)" +== 732 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (11) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (11)" +== 733 +-- truncate_limit: 100 +CREATE TABLE trgfire3 (LIKE trgfire) +-- +TABLE: name="trgfire3" schema="" table="trgfire3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire3 (LIKE trgfire)" +== 734 +-- truncate_limit: 100 +ALTER TABLE trgfire ATTACH PARTITION trgfire3 FOR VALUES FROM (20) TO (30) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trgfire ATTACH PARTITION trgfire3 FOR VALUES FROM (20) TO (30)" +== 735 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (21) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (21)" +== 736 +-- truncate_limit: 100 +CREATE TABLE trgfire4 PARTITION OF trgfire FOR VALUES FROM (30) TO (40) PARTITION BY LIST (i) +-- +TABLE: name="trgfire4" schema="" table="trgfire4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire4 PARTITION OF trgfire FOR VALUES FROM (30) TO (40) PARTITION BY LIST (i)" +== 737 +-- truncate_limit: 100 +CREATE TABLE trgfire4_30 PARTITION OF trgfire4 FOR VALUES IN (30) +-- +TABLE: name="trgfire4_30" schema="" table="trgfire4_30" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire4_30 PARTITION OF trgfire4 FOR VALUES IN (30)" +== 738 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (30) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (30)" +== 739 +-- truncate_limit: 100 +CREATE TABLE trgfire5 (LIKE trgfire) PARTITION BY LIST (i) +-- +TABLE: name="trgfire5" schema="" table="trgfire5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire5 (LIKE trgfire) PARTITION BY LIST (i)" +== 740 +-- truncate_limit: 100 +CREATE TABLE trgfire5_40 PARTITION OF trgfire5 FOR VALUES IN (40) +-- +TABLE: name="trgfire5_40" schema="" table="trgfire5_40" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trgfire5_40 PARTITION OF trgfire5 FOR VALUES IN (40)" +== 741 +-- truncate_limit: 100 +ALTER TABLE trgfire ATTACH PARTITION trgfire5 FOR VALUES FROM (40) TO (50) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trgfire ATTACH PARTITION trgfire5 FOR VALUES FROM (40) TO (50)" +== 742 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (40) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (40)" +== 743 +-- truncate_limit: 100 +SELECT tgrelid::regclass, tgenabled FROM pg_trigger + WHERE tgrelid::regclass IN (SELECT oid from pg_class where relname LIKE 'trgfire%') + ORDER BY tgrelid::regclass::text +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT tgrelid::regclass, tgenabled FROM pg_trigger WHERE ... ORDER BY tgrelid::regclass::text" +== 744 +-- truncate_limit: 100 +ALTER TABLE trgfire ENABLE TRIGGER tg +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trgfire ENABLE TRIGGER tg" +== 745 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (1) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (1)" +== 746 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (11) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (11)" +== 747 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (21) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (21)" +== 748 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (30) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (30)" +== 749 +-- truncate_limit: 100 +INSERT INTO trgfire VALUES (40) +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trgfire VALUES (40)" +== 750 +-- truncate_limit: 100 +DROP TABLE trgfire +-- +TABLE: name="trgfire" schema="" table="trgfire" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trgfire" +== 751 +-- truncate_limit: 100 +DROP FUNCTION tgf() +-- +FUNCTION: name="tgf" function="tgf" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION tgf()" +== 752 +-- truncate_limit: 100 +|-- +-- Test the interaction between transition tables and both kinds of +-- inheritance. We'll dump the contents of the transition tables in a +-- format that shows the attribute order, so that we can distinguish +-- tuple formats (though not dropped attributes). +|-- + +create or replace function dump_insert() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, new table = %', + TG_NAME, + (select string_agg(new_table::text, ', ' order by a) from new_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_insert" function="dump_insert" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dump_insert() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n raise..." +== 753 +-- truncate_limit: 100 +create or replace function dump_update() 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; +$$ +-- +FUNCTION: name="dump_update" function="dump_update" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dump_update() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n raise..." +== 754 +-- truncate_limit: 100 +create or replace function dump_delete() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, old table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by a) from old_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_delete" function="dump_delete" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dump_delete() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n raise..." +== 755 +-- truncate_limit: 100 +|-- +-- Verify behavior of statement triggers on partition hierarchy with +-- transition tables. Tuples should appear to each trigger in the +-- format of the relation the trigger is attached to. +|-- + +-- set up a partition hierarchy with some different TupleDescriptors +create table parent (a text, b int) partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a text, b int) PARTITION BY LIST (a)" +== 756 +-- truncate_limit: 100 +-- a child matching parent +create table child1 partition of parent for values in ('AAA') +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child1 PARTITION OF parent FOR VALUES IN ('AAA')" +== 757 +-- truncate_limit: 100 +-- a child with a dropped column +create table child2 (x int, a text, b int) +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child2 (x int, a text, b int)" +== 758 +-- truncate_limit: 100 +alter table child2 drop column x +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child2 DROP x" +== 759 +-- truncate_limit: 100 +alter table parent attach partition child2 for values in ('BBB') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ATTACH PARTITION child2 FOR VALUES IN ('BBB')" +== 760 +-- truncate_limit: 100 +-- a child with a different column order +create table child3 (b int, a text) +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child3 (b int, a text)" +== 761 +-- truncate_limit: 100 +alter table parent attach partition child3 for values in ('CCC') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ATTACH PARTITION child3 FOR VALUES IN ('CCC')" +== 762 +-- truncate_limit: 100 +create trigger parent_insert_trig + after insert on parent referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_insert_trig AFTER INSERT ON parent REFERENCING NEW TABLE new_table EXECUTE ..." +== 763 +-- truncate_limit: 100 +create trigger parent_update_trig + after update on parent referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_update_trig AFTER UPDATE ON parent REFERENCING OLD TABLE old_table NEW TABL..." +== 764 +-- truncate_limit: 100 +create trigger parent_delete_trig + after delete on parent referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_delete_trig AFTER DELETE ON parent REFERENCING OLD TABLE old_table EXECUTE ..." +== 765 +-- truncate_limit: 100 +create trigger child1_insert_trig + after insert on child1 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child1_insert_trig AFTER INSERT ON child1 REFERENCING NEW TABLE new_table EXECUTE ..." +== 766 +-- truncate_limit: 100 +create trigger child1_update_trig + after update on child1 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child1_update_trig AFTER UPDATE ON child1 REFERENCING OLD TABLE old_table NEW TABL..." +== 767 +-- truncate_limit: 100 +create trigger child1_delete_trig + after delete on child1 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child1_delete_trig AFTER DELETE ON child1 REFERENCING OLD TABLE old_table EXECUTE ..." +== 768 +-- truncate_limit: 100 +create trigger child2_insert_trig + after insert on child2 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child2_insert_trig AFTER INSERT ON child2 REFERENCING NEW TABLE new_table EXECUTE ..." +== 769 +-- truncate_limit: 100 +create trigger child2_update_trig + after update on child2 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child2_update_trig AFTER UPDATE ON child2 REFERENCING OLD TABLE old_table NEW TABL..." +== 770 +-- truncate_limit: 100 +create trigger child2_delete_trig + after delete on child2 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child2_delete_trig AFTER DELETE ON child2 REFERENCING OLD TABLE old_table EXECUTE ..." +== 771 +-- truncate_limit: 100 +create trigger child3_insert_trig + after insert on child3 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child3_insert_trig AFTER INSERT ON child3 REFERENCING NEW TABLE new_table EXECUTE ..." +== 772 +-- truncate_limit: 100 +create trigger child3_update_trig + after update on child3 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child3_update_trig AFTER UPDATE ON child3 REFERENCING OLD TABLE old_table NEW TABL..." +== 773 +-- truncate_limit: 100 +create trigger child3_delete_trig + after delete on child3 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child3_delete_trig AFTER DELETE ON child3 REFERENCING OLD TABLE old_table EXECUTE ..." +== 774 +-- truncate_limit: 100 +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table IN ('parent', 'child1', 'child2', 'child3') + ORDER BY trigger_name COLLATE "C", 2 +-- +TABLE: name="information_schema.triggers" schema="information_schema" table="triggers" ctx=Select +FILTER: schema="" table="" column="event_object_table" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.triggers WHERE ... ORDER BY trigger_name COLLATE \"C\", 2" +== 775 +-- truncate_limit: 100 +-- insert directly into children sees respective child-format tuples +insert into child1 values ('AAA', 42) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child1 VALUES ('AAA', 42)" +== 776 +-- truncate_limit: 100 +insert into child2 values ('BBB', 42) +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child2 VALUES ('BBB', 42)" +== 777 +-- truncate_limit: 100 +insert into child3 values (42, 'CCC') +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child3 VALUES (42, 'CCC')" +== 778 +-- truncate_limit: 100 +-- update via parent sees parent-format tuples +update parent set b = b + 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parent SET b = b + 1" +== 779 +-- truncate_limit: 100 +-- delete via parent sees parent-format tuples +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parent" +== 780 +-- truncate_limit: 100 +-- insert into parent sees parent-format tuples +insert into parent values ('AAA', 42) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES ('AAA', 42)" +== 781 +-- truncate_limit: 100 +insert into parent values ('BBB', 42) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES ('BBB', 42)" +== 782 +-- truncate_limit: 100 +insert into parent values ('CCC', 42) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES ('CCC', 42)" +== 783 +-- truncate_limit: 100 +-- delete from children sees respective child-format tuples +delete from child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM child1" +== 784 +-- truncate_limit: 100 +delete from child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM child2" +== 785 +-- truncate_limit: 100 +delete from child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM child3" +== 786 +-- truncate_limit: 100 +-- copy into parent sees parent-format tuples +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parent(a, b) FROM STDIN" +== 787 +-- truncate_limit: 100 +-- check detach/reattach behavior; statement triggers with transition tables +-- should not prevent a table from becoming a partition again +alter table parent detach partition child1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent DETACH PARTITION child1" +== 788 +-- truncate_limit: 100 +alter table parent attach partition child1 for values in ('AAA') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ATTACH PARTITION child1 FOR VALUES IN ('AAA')" +== 789 +-- truncate_limit: 100 +-- DML affecting parent sees tuples collected from children even if +-- there is no transition table trigger on the children +drop trigger child1_insert_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child1_insert_trig ON child1" +== 790 +-- truncate_limit: 100 +drop trigger child1_update_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child1_update_trig ON child1" +== 791 +-- truncate_limit: 100 +drop trigger child1_delete_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child1_delete_trig ON child1" +== 792 +-- truncate_limit: 100 +drop trigger child2_insert_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child2_insert_trig ON child2" +== 793 +-- truncate_limit: 100 +drop trigger child2_update_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child2_update_trig ON child2" +== 794 +-- truncate_limit: 100 +drop trigger child2_delete_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child2_delete_trig ON child2" +== 795 +-- truncate_limit: 100 +drop trigger child3_insert_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child3_insert_trig ON child3" +== 796 +-- truncate_limit: 100 +drop trigger child3_update_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child3_update_trig ON child3" +== 797 +-- truncate_limit: 100 +drop trigger child3_delete_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child3_delete_trig ON child3" +== 798 +-- truncate_limit: 100 +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parent" +== 799 +-- truncate_limit: 100 +-- copy into parent sees tuples collected from children even if there +-- is no transition-table trigger on the children +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parent(a, b) FROM STDIN" +== 800 +-- truncate_limit: 100 +-- insert into parent with a before trigger on a child tuple before +-- insertion, and we capture the newly modified row in parent format +create or replace function intercept_insert() returns trigger language plpgsql as +$$ + begin + new.b = new.b + 1000; + return new; + end; +$$ +-- +FUNCTION: name="intercept_insert" function="intercept_insert" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION intercept_insert() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n ..." +== 801 +-- truncate_limit: 100 +create trigger intercept_insert_child3 + before insert on child3 + for each row execute procedure intercept_insert() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER intercept_insert_child3 BEFORE INSERT ON child3 FOR EACH ROW EXECUTE FUNCTION inte..." +== 802 +-- truncate_limit: 100 +-- insert, parent trigger sees post-modification parent-format tuple +insert into parent values ('AAA', 42), ('BBB', 42), ('CCC', 66) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES ('AAA', 42), ('BBB', 42), ('CCC', 66)" +== 803 +-- truncate_limit: 100 +-- copy, parent trigger sees post-modification parent-format tuple +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parent(a, b) FROM STDIN" +== 804 +-- truncate_limit: 100 +drop table child1, child2, child3, parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +TABLE: name="child2" schema="" table="child2" ctx=DDL +TABLE: name="child3" schema="" table="child3" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child1, child2, child3, parent" +== 805 +-- truncate_limit: 100 +drop function intercept_insert() +-- +FUNCTION: name="intercept_insert" function="intercept_insert" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION intercept_insert()" +== 806 +-- truncate_limit: 100 +|-- +-- Verify prohibition of row triggers with transition triggers on +-- partitions +|-- +create table parent (a text, b int) partition by list (a) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a text, b int) PARTITION BY LIST (a)" +== 807 +-- truncate_limit: 100 +create table child partition of parent for values in ('AAA') +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child PARTITION OF parent FOR VALUES IN ('AAA')" +== 808 +-- truncate_limit: 100 +-- adding row trigger with transition table fails +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child_row_trig AFTER INSERT ON child REFERENCING NEW TABLE new_table FOR EACH ROW ..." +== 809 +-- truncate_limit: 100 +-- detaching it first works +alter table parent detach partition child +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent DETACH PARTITION child" +== 810 +-- truncate_limit: 100 +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child_row_trig AFTER INSERT ON child REFERENCING NEW TABLE new_table FOR EACH ROW ..." +== 811 +-- truncate_limit: 100 +-- but now we're not allowed to reattach it +alter table parent attach partition child for values in ('AAA') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ATTACH PARTITION child FOR VALUES IN ('AAA')" +== 812 +-- truncate_limit: 100 +-- drop the trigger, and now we're allowed to attach it again +drop trigger child_row_trig on child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child_row_trig ON child" +== 813 +-- truncate_limit: 100 +alter table parent attach partition child for values in ('AAA') +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE parent ATTACH PARTITION child FOR VALUES IN ('AAA')" +== 814 +-- truncate_limit: 100 +drop table child, parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child, parent" +== 815 +-- truncate_limit: 100 +|-- +-- Verify access of transition tables with UPDATE triggers and tuples +-- moved across partitions. +|-- +create or replace function dump_update_new() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, new table = %', TG_NAME, + (select string_agg(new_table::text, ', ' order by a) from new_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_update_new" function="dump_update_new" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dump_update_new() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n r..." +== 816 +-- truncate_limit: 100 +create or replace function dump_update_old() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, old table = %', TG_NAME, + (select string_agg(old_table::text, ', ' order by a) from old_table); + return null; + end; +$$ +-- +FUNCTION: name="dump_update_old" function="dump_update_old" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dump_update_old() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n r..." +== 817 +-- truncate_limit: 100 +create table trans_tab_parent (a text) partition by list (a) +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_tab_parent (a text) PARTITION BY LIST (a)" +== 818 +-- truncate_limit: 100 +create table trans_tab_child1 partition of trans_tab_parent for values in ('AAA1', 'AAA2') +-- +TABLE: name="trans_tab_child1" schema="" table="trans_tab_child1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_tab_child1 PARTITION OF trans_tab_parent FOR VALUES IN ('AAA1', 'AAA2')" +== 819 +-- truncate_limit: 100 +create table trans_tab_child2 partition of trans_tab_parent for values in ('BBB1', 'BBB2') +-- +TABLE: name="trans_tab_child2" schema="" table="trans_tab_child2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trans_tab_child2 PARTITION OF trans_tab_parent FOR VALUES IN ('BBB1', 'BBB2')" +== 820 +-- truncate_limit: 100 +create trigger trans_tab_parent_update_trig + after update on trans_tab_parent referencing old table as old_table + for each statement execute procedure dump_update_old() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trans_tab_parent_update_trig AFTER UPDATE ON trans_tab_parent REFERENCING OLD TABL..." +== 821 +-- truncate_limit: 100 +create trigger trans_tab_parent_insert_trig + after insert on trans_tab_parent referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trans_tab_parent_insert_trig AFTER INSERT ON trans_tab_parent REFERENCING NEW TABL..." +== 822 +-- truncate_limit: 100 +create trigger trans_tab_parent_delete_trig + after delete on trans_tab_parent referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trans_tab_parent_delete_trig AFTER DELETE ON trans_tab_parent REFERENCING OLD TABL..." +== 823 +-- truncate_limit: 100 +insert into trans_tab_parent values ('AAA1'), ('BBB1') +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trans_tab_parent VALUES ('AAA1'), ('BBB1')" +== 824 +-- truncate_limit: 100 +-- should not trigger access to new table when moving across partitions. +update trans_tab_parent set a = 'BBB2' where a = 'AAA1' +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trans_tab_parent SET a = 'BBB2' WHERE a = 'AAA1'" +== 825 +-- truncate_limit: 100 +drop trigger trans_tab_parent_update_trig on trans_tab_parent +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trans_tab_parent_update_trig ON trans_tab_parent" +== 826 +-- truncate_limit: 100 +create trigger trans_tab_parent_update_trig + after update on trans_tab_parent referencing new table as new_table + for each statement execute procedure dump_update_new() +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trans_tab_parent_update_trig AFTER UPDATE ON trans_tab_parent REFERENCING NEW TABL..." +== 827 +-- truncate_limit: 100 +-- should not trigger access to old table when moving across partitions. +update trans_tab_parent set a = 'AAA2' where a = 'BBB1' +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE trans_tab_parent SET a = 'AAA2' WHERE a = 'BBB1'" +== 828 +-- truncate_limit: 100 +delete from trans_tab_parent +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM trans_tab_parent" +== 829 +-- truncate_limit: 100 +-- clean up +drop table trans_tab_parent, trans_tab_child1, trans_tab_child2 +-- +TABLE: name="trans_tab_parent" schema="" table="trans_tab_parent" ctx=DDL +TABLE: name="trans_tab_child1" schema="" table="trans_tab_child1" ctx=DDL +TABLE: name="trans_tab_child2" schema="" table="trans_tab_child2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trans_tab_parent, trans_tab_child1, trans_tab_child2" +== 830 +-- truncate_limit: 100 +drop function dump_update_new, dump_update_old +-- +FUNCTION: name="dump_update_new" function="dump_update_new" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dump_update_new, dump_update_old" +== 831 +-- truncate_limit: 100 +|-- +-- Verify behavior of statement triggers on (non-partition) +-- inheritance hierarchy with transition tables; similar to the +-- partition case, except there is no rerouting on insertion and child +-- tables can have extra columns +|-- + +-- set up inheritance hierarchy with different TupleDescriptors +create table parent (a text, b int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a text, b int)" +== 832 +-- truncate_limit: 100 +-- a child matching parent +create table child1 () inherits (parent) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child1 () INHERITS (parent)" +== 833 +-- truncate_limit: 100 +-- a child with a different column order +create table child2 (b int, a text) +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child2 (b int, a text)" +== 834 +-- truncate_limit: 100 +alter table child2 inherit parent +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child2 INHERIT parent" +== 835 +-- truncate_limit: 100 +-- a child with an extra column +create table child3 (c text) inherits (parent) +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child3 (c text) INHERITS (parent)" +== 836 +-- truncate_limit: 100 +create trigger parent_insert_trig + after insert on parent referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_insert_trig AFTER INSERT ON parent REFERENCING NEW TABLE new_table EXECUTE ..." +== 837 +-- truncate_limit: 100 +create trigger parent_update_trig + after update on parent referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_update_trig AFTER UPDATE ON parent REFERENCING OLD TABLE old_table NEW TABL..." +== 838 +-- truncate_limit: 100 +create trigger parent_delete_trig + after delete on parent referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_delete_trig AFTER DELETE ON parent REFERENCING OLD TABLE old_table EXECUTE ..." +== 839 +-- truncate_limit: 100 +create trigger child1_insert_trig + after insert on child1 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child1_insert_trig AFTER INSERT ON child1 REFERENCING NEW TABLE new_table EXECUTE ..." +== 840 +-- truncate_limit: 100 +create trigger child1_update_trig + after update on child1 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child1_update_trig AFTER UPDATE ON child1 REFERENCING OLD TABLE old_table NEW TABL..." +== 841 +-- truncate_limit: 100 +create trigger child1_delete_trig + after delete on child1 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child1_delete_trig AFTER DELETE ON child1 REFERENCING OLD TABLE old_table EXECUTE ..." +== 842 +-- truncate_limit: 100 +create trigger child2_insert_trig + after insert on child2 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child2_insert_trig AFTER INSERT ON child2 REFERENCING NEW TABLE new_table EXECUTE ..." +== 843 +-- truncate_limit: 100 +create trigger child2_update_trig + after update on child2 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child2_update_trig AFTER UPDATE ON child2 REFERENCING OLD TABLE old_table NEW TABL..." +== 844 +-- truncate_limit: 100 +create trigger child2_delete_trig + after delete on child2 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child2_delete_trig AFTER DELETE ON child2 REFERENCING OLD TABLE old_table EXECUTE ..." +== 845 +-- truncate_limit: 100 +create trigger child3_insert_trig + after insert on child3 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child3_insert_trig AFTER INSERT ON child3 REFERENCING NEW TABLE new_table EXECUTE ..." +== 846 +-- truncate_limit: 100 +create trigger child3_update_trig + after update on child3 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child3_update_trig AFTER UPDATE ON child3 REFERENCING OLD TABLE old_table NEW TABL..." +== 847 +-- truncate_limit: 100 +create trigger child3_delete_trig + after delete on child3 referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child3_delete_trig AFTER DELETE ON child3 REFERENCING OLD TABLE old_table EXECUTE ..." +== 848 +-- truncate_limit: 100 +-- insert directly into children sees respective child-format tuples +insert into child1 values ('AAA', 42) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child1 VALUES ('AAA', 42)" +== 849 +-- truncate_limit: 100 +insert into child2 values (42, 'BBB') +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child2 VALUES (42, 'BBB')" +== 850 +-- truncate_limit: 100 +insert into child3 values ('CCC', 42, 'foo') +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child3 VALUES ('CCC', 42, 'foo')" +== 851 +-- truncate_limit: 100 +-- update via parent sees parent-format tuples +update parent set b = b + 1 +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE parent SET b = b + 1" +== 852 +-- truncate_limit: 100 +-- delete via parent sees parent-format tuples +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parent" +== 853 +-- truncate_limit: 100 +-- reinsert values into children for next test... +insert into child1 values ('AAA', 42) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child1 VALUES ('AAA', 42)" +== 854 +-- truncate_limit: 100 +insert into child2 values (42, 'BBB') +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child2 VALUES (42, 'BBB')" +== 855 +-- truncate_limit: 100 +insert into child3 values ('CCC', 42, 'foo') +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child3 VALUES ('CCC', 42, 'foo')" +== 856 +-- truncate_limit: 100 +-- delete from children sees respective child-format tuples +delete from child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM child1" +== 857 +-- truncate_limit: 100 +delete from child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM child2" +== 858 +-- truncate_limit: 100 +delete from child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM child3" +== 859 +-- truncate_limit: 100 +-- copy into parent sees parent-format tuples (no rerouting, so these +-- are really inserted into the parent) +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parent(a, b) FROM STDIN" +== 860 +-- truncate_limit: 100 +-- same behavior for copy if there is an index (interesting because rows are +-- captured by a different code path in copyfrom.c if there are indexes) +create index on parent(b) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON parent USING btree (b)" +== 861 +-- truncate_limit: 100 +copy parent (a, b) from stdin +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: CopyStmt +TRUNCATED: "COPY parent(a, b) FROM STDIN" +== 862 +-- truncate_limit: 100 +-- check disinherit/reinherit behavior; statement triggers with transition +-- tables should not prevent a table from becoming an inheritance child again +alter table child1 no inherit parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child1 NO INHERIT parent" +== 863 +-- truncate_limit: 100 +alter table child1 inherit parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child1 INHERIT parent" +== 864 +-- truncate_limit: 100 +-- DML affecting parent sees tuples collected from children even if +-- there is no transition table trigger on the children +drop trigger child1_insert_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child1_insert_trig ON child1" +== 865 +-- truncate_limit: 100 +drop trigger child1_update_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child1_update_trig ON child1" +== 866 +-- truncate_limit: 100 +drop trigger child1_delete_trig on child1 +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child1_delete_trig ON child1" +== 867 +-- truncate_limit: 100 +drop trigger child2_insert_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child2_insert_trig ON child2" +== 868 +-- truncate_limit: 100 +drop trigger child2_update_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child2_update_trig ON child2" +== 869 +-- truncate_limit: 100 +drop trigger child2_delete_trig on child2 +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child2_delete_trig ON child2" +== 870 +-- truncate_limit: 100 +drop trigger child3_insert_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child3_insert_trig ON child3" +== 871 +-- truncate_limit: 100 +drop trigger child3_update_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child3_update_trig ON child3" +== 872 +-- truncate_limit: 100 +drop trigger child3_delete_trig on child3 +-- +TABLE: name="child3" schema="" table="child3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child3_delete_trig ON child3" +== 873 +-- truncate_limit: 100 +delete from parent +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parent" +== 874 +-- truncate_limit: 100 +drop table child1, child2, child3, parent +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +TABLE: name="child2" schema="" table="child2" ctx=DDL +TABLE: name="child3" schema="" table="child3" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child1, child2, child3, parent" +== 875 +-- truncate_limit: 100 +|-- +-- Verify prohibition of row triggers with transition triggers on +-- inheritance children +|-- +create table parent (a text, b int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a text, b int)" +== 876 +-- truncate_limit: 100 +create table child () inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child () INHERITS (parent)" +== 877 +-- truncate_limit: 100 +-- adding row trigger with transition table fails +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child_row_trig AFTER INSERT ON child REFERENCING NEW TABLE new_table FOR EACH ROW ..." +== 878 +-- truncate_limit: 100 +-- disinheriting it first works +alter table child no inherit parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child NO INHERIT parent" +== 879 +-- truncate_limit: 100 +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER child_row_trig AFTER INSERT ON child REFERENCING NEW TABLE new_table FOR EACH ROW ..." +== 880 +-- truncate_limit: 100 +-- but now we're not allowed to make it inherit anymore +alter table child inherit parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child INHERIT parent" +== 881 +-- truncate_limit: 100 +-- drop the trigger, and now we're allowed to make it inherit again +drop trigger child_row_trig on child +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER child_row_trig ON child" +== 882 +-- truncate_limit: 100 +alter table child inherit parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE child INHERIT parent" +== 883 +-- truncate_limit: 100 +drop table child, parent +-- +TABLE: name="child" schema="" table="child" ctx=DDL +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE child, parent" +== 884 +-- truncate_limit: 100 +|-- +-- Verify behavior of queries with wCTEs, where multiple transition +-- tuplestores can be active at the same time because there are +-- multiple DML statements that might fire triggers with transition +-- tables +|-- +create table table1 (a int) +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE table1 (a int)" +== 885 +-- truncate_limit: 100 +create table table2 (a text) +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE table2 (a text)" +== 886 +-- truncate_limit: 100 +create trigger table1_trig + after insert on table1 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER table1_trig AFTER INSERT ON table1 REFERENCING NEW TABLE new_table EXECUTE FUNCTIO..." +== 887 +-- truncate_limit: 100 +create trigger table2_trig + after insert on table2 referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER table2_trig AFTER INSERT ON table2 REFERENCING NEW TABLE new_table EXECUTE FUNCTIO..." +== 888 +-- truncate_limit: 100 +with wcte as (insert into table1 values (42)) + insert into table2 values ('hello world') +-- +TABLE: name="table2" schema="" table="table2" ctx=DML +TABLE: name="table1" schema="" table="table1" ctx=DML +CTE: "wcte" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH wcte AS (INSERT INTO table1 VALUES (42)) INSERT INTO table2 VALUES ('hello world')" +== 889 +-- truncate_limit: 100 +with wcte as (insert into table1 values (43)) + insert into table1 values (44) +-- +TABLE: name="table1" schema="" table="table1" ctx=DML +TABLE: name="table1" schema="" table="table1" ctx=DML +CTE: "wcte" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH wcte AS (INSERT INTO table1 VALUES (43)) INSERT INTO table1 VALUES (44)" +== 890 +-- truncate_limit: 100 +select * from table1 +-- +TABLE: name="table1" schema="" table="table1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM table1" +== 891 +-- truncate_limit: 100 +select * from table2 +-- +TABLE: name="table2" schema="" table="table2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM table2" +== 892 +-- truncate_limit: 100 +drop table table1 +-- +TABLE: name="table1" schema="" table="table1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE table1" +== 893 +-- truncate_limit: 100 +drop table table2 +-- +TABLE: name="table2" schema="" table="table2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE table2" +== 894 +-- truncate_limit: 100 +|-- +-- Verify behavior of INSERT ... ON CONFLICT DO UPDATE ... with +-- transition tables. +|-- + +create table my_table (a int primary key, b text) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE my_table (a int PRIMARY KEY, b text)" +== 895 +-- truncate_limit: 100 +create trigger my_table_insert_trig + after insert on my_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_table_insert_trig AFTER INSERT ON my_table REFERENCING NEW TABLE new_table EXEC..." +== 896 +-- truncate_limit: 100 +create trigger my_table_update_trig + after update on my_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_table_update_trig AFTER UPDATE ON my_table REFERENCING OLD TABLE old_table NEW ..." +== 897 +-- truncate_limit: 100 +-- inserts only +insert into my_table values (1, 'AAA'), (2, 'BBB') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO my_table VALUES (1, 'AAA'), (2, 'BBB') ON CONFLICT (a) DO UPDATE SET ... = ..." +== 898 +-- truncate_limit: 100 +-- mixture of inserts and updates +insert into my_table values (1, 'AAA'), (2, 'BBB'), (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO my_table VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ..." +== 899 +-- truncate_limit: 100 +-- updates only +insert into my_table values (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO my_table VALUES (3, 'CCC'), (4, 'DDD') ON CONFLICT (a) DO UPDATE SET ... = ..." +== 900 +-- truncate_limit: 100 +|-- +-- now using a partitioned table +|-- + +create table iocdu_tt_parted (a int primary key, b text) partition by list (a) +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iocdu_tt_parted (a int PRIMARY KEY, b text) PARTITION BY LIST (a)" +== 901 +-- truncate_limit: 100 +create table iocdu_tt_parted1 partition of iocdu_tt_parted for values in (1) +-- +TABLE: name="iocdu_tt_parted1" schema="" table="iocdu_tt_parted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iocdu_tt_parted1 PARTITION OF iocdu_tt_parted FOR VALUES IN (1)" +== 902 +-- truncate_limit: 100 +create table iocdu_tt_parted2 partition of iocdu_tt_parted for values in (2) +-- +TABLE: name="iocdu_tt_parted2" schema="" table="iocdu_tt_parted2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iocdu_tt_parted2 PARTITION OF iocdu_tt_parted FOR VALUES IN (2)" +== 903 +-- truncate_limit: 100 +create table iocdu_tt_parted3 partition of iocdu_tt_parted for values in (3) +-- +TABLE: name="iocdu_tt_parted3" schema="" table="iocdu_tt_parted3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iocdu_tt_parted3 PARTITION OF iocdu_tt_parted FOR VALUES IN (3)" +== 904 +-- truncate_limit: 100 +create table iocdu_tt_parted4 partition of iocdu_tt_parted for values in (4) +-- +TABLE: name="iocdu_tt_parted4" schema="" table="iocdu_tt_parted4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE iocdu_tt_parted4 PARTITION OF iocdu_tt_parted FOR VALUES IN (4)" +== 905 +-- truncate_limit: 100 +create trigger iocdu_tt_parted_insert_trig + after insert on iocdu_tt_parted referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER iocdu_tt_parted_insert_trig AFTER INSERT ON iocdu_tt_parted REFERENCING NEW TABLE ..." +== 906 +-- truncate_limit: 100 +create trigger iocdu_tt_parted_update_trig + after update on iocdu_tt_parted referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER iocdu_tt_parted_update_trig AFTER UPDATE ON iocdu_tt_parted REFERENCING OLD TABLE ..." +== 907 +-- truncate_limit: 100 +-- inserts only +insert into iocdu_tt_parted values (1, 'AAA'), (2, 'BBB') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iocdu_tt_parted VALUES (1, 'AAA'), (2, 'BBB') ON CONFLICT (a) DO UPDATE SET ... = ..." +== 908 +-- truncate_limit: 100 +-- mixture of inserts and updates +insert into iocdu_tt_parted values (1, 'AAA'), (2, 'BBB'), (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iocdu_tt_parted VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ..." +== 909 +-- truncate_limit: 100 +-- updates only +insert into iocdu_tt_parted values (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO iocdu_tt_parted VALUES (3, 'CCC'), (4, 'DDD') ON CONFLICT (a) DO UPDATE SET ... = ..." +== 910 +-- truncate_limit: 100 +drop table iocdu_tt_parted +-- +TABLE: name="iocdu_tt_parted" schema="" table="iocdu_tt_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE iocdu_tt_parted" +== 911 +-- truncate_limit: 100 +|-- +-- Verify that you can't create a trigger with transition tables for +-- more than one event. +|-- + +create trigger my_table_multievent_trig + after insert or update on my_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_table_multievent_trig AFTER INSERT OR UPDATE ON my_table REFERENCING NEW TABLE ..." +== 912 +-- truncate_limit: 100 +|-- +-- Verify that you can't create a trigger with transition tables with +-- a column list. +|-- + +create trigger my_table_col_update_trig + after update of b on my_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_table_col_update_trig AFTER UPDATE OF b ON my_table REFERENCING NEW TABLE new_t..." +== 913 +-- truncate_limit: 100 +drop table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE my_table" +== 914 +-- truncate_limit: 100 +|-- +-- Test firing of triggers with transition tables by foreign key cascades +|-- + +create table refd_table (a int primary key, b text) +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE refd_table (a int PRIMARY KEY, b text)" +== 915 +-- truncate_limit: 100 +create table trig_table (a int, b text, + foreign key (a) references refd_table on update cascade on delete cascade +) +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trig_table (a int, b text, FOREIGN KEY (a) REFERENCES refd_table ON UPDATE CASCADE O..." +== 916 +-- truncate_limit: 100 +create trigger trig_table_before_trig + before insert or update or delete on trig_table + for each statement execute procedure trigger_func('trig_table') +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_table_before_trig BEFORE INSERT OR DELETE OR UPDATE ON trig_table EXECUTE FUN..." +== 917 +-- truncate_limit: 100 +create trigger trig_table_insert_trig + after insert on trig_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_table_insert_trig AFTER INSERT ON trig_table REFERENCING NEW TABLE new_table ..." +== 918 +-- truncate_limit: 100 +create trigger trig_table_update_trig + after update on trig_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_table_update_trig AFTER UPDATE ON trig_table REFERENCING OLD TABLE old_table ..." +== 919 +-- truncate_limit: 100 +create trigger trig_table_delete_trig + after delete on trig_table referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_table_delete_trig AFTER DELETE ON trig_table REFERENCING OLD TABLE old_table ..." +== 920 +-- truncate_limit: 100 +insert into refd_table values + (1, 'one'), + (2, 'two'), + (3, 'three') +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO refd_table VALUES (1, 'one'), (2, 'two'), (3, 'three')" +== 921 +-- truncate_limit: 100 +insert into trig_table values + (1, 'one a'), + (1, 'one b'), + (2, 'two a'), + (2, 'two b'), + (3, 'three a'), + (3, 'three b') +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trig_table VALUES (...)" +== 922 +-- truncate_limit: 100 +update refd_table set a = 11 where b = 'one' +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE refd_table SET a = 11 WHERE b = 'one'" +== 923 +-- truncate_limit: 100 +select * from trig_table +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trig_table" +== 924 +-- truncate_limit: 100 +delete from refd_table where length(b) = 3 +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DML +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM refd_table WHERE length(b) = 3" +== 925 +-- truncate_limit: 100 +select * from trig_table +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trig_table" +== 926 +-- truncate_limit: 100 +drop table refd_table, trig_table +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE refd_table, trig_table" +== 927 +-- truncate_limit: 100 +|-- +-- Test that we can drop a not-yet-fired deferred trigger +|-- + +create table refd_table (id int primary key) +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE refd_table (id int PRIMARY KEY)" +== 928 +-- truncate_limit: 100 +create table trig_table (fk int references refd_table initially deferred) +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trig_table (fk int REFERENCES refd_table INITIALLY DEFERRED)" +== 929 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 930 +-- truncate_limit: 100 +insert into trig_table values (1) +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trig_table VALUES (1)" +== 931 +-- truncate_limit: 100 +drop table refd_table cascade +-- +TABLE: name="refd_table" schema="" table="refd_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE refd_table CASCADE" +== 932 +-- truncate_limit: 100 +commit +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 933 +-- truncate_limit: 100 +drop table trig_table +-- +TABLE: name="trig_table" schema="" table="trig_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trig_table" +== 934 +-- truncate_limit: 100 +|-- +-- self-referential FKs are even more fun +|-- + +create table self_ref (a int primary key, + b int references self_ref(a) on delete cascade) +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE self_ref (a int PRIMARY KEY, b int REFERENCES self_ref (a) ON DELETE CASCADE)" +== 935 +-- truncate_limit: 100 +create trigger self_ref_before_trig + before delete on self_ref + for each statement execute procedure trigger_func('self_ref') +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER self_ref_before_trig BEFORE DELETE ON self_ref EXECUTE FUNCTION trigger_func('self..." +== 936 +-- truncate_limit: 100 +create trigger self_ref_r_trig + after delete on self_ref referencing old table as old_table + for each row execute procedure dump_delete() +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER self_ref_r_trig AFTER DELETE ON self_ref REFERENCING OLD TABLE old_table FOR EACH ..." +== 937 +-- truncate_limit: 100 +create trigger self_ref_s_trig + after delete on self_ref referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER self_ref_s_trig AFTER DELETE ON self_ref REFERENCING OLD TABLE old_table EXECUTE F..." +== 938 +-- truncate_limit: 100 +insert into self_ref values (1, null), (2, 1), (3, 2) +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO self_ref VALUES (1, NULL), (2, 1), (3, 2)" +== 939 +-- truncate_limit: 100 +delete from self_ref where a = 1 +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM self_ref WHERE a = 1" +== 940 +-- truncate_limit: 100 +-- without AR trigger, cascaded deletes all end up in one transition table +drop trigger self_ref_r_trig on self_ref +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER self_ref_r_trig ON self_ref" +== 941 +-- truncate_limit: 100 +insert into self_ref values (1, null), (2, 1), (3, 2), (4, 3) +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO self_ref VALUES (1, NULL), (2, 1), (3, 2), (4, 3)" +== 942 +-- truncate_limit: 100 +delete from self_ref where a = 1 +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM self_ref WHERE a = 1" +== 943 +-- truncate_limit: 100 +drop table self_ref +-- +TABLE: name="self_ref" schema="" table="self_ref" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE self_ref" +== 944 +-- truncate_limit: 100 +|-- +-- test transition tables with MERGE +|-- +create table merge_target_table (a int primary key, b text) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE merge_target_table (a int PRIMARY KEY, b text)" +== 945 +-- truncate_limit: 100 +create trigger merge_target_table_insert_trig + after insert on merge_target_table referencing new table as new_table + for each statement execute procedure dump_insert() +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_target_table_insert_trig AFTER INSERT ON merge_target_table REFERENCING NEW ..." +== 946 +-- truncate_limit: 100 +create trigger merge_target_table_update_trig + after update on merge_target_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update() +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_target_table_update_trig AFTER UPDATE ON merge_target_table REFERENCING OLD ..." +== 947 +-- truncate_limit: 100 +create trigger merge_target_table_delete_trig + after delete on merge_target_table referencing old table as old_table + for each statement execute procedure dump_delete() +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER merge_target_table_delete_trig AFTER DELETE ON merge_target_table REFERENCING OLD ..." +== 948 +-- truncate_limit: 100 +create table merge_source_table (a int, b text) +-- +TABLE: name="merge_source_table" schema="" table="merge_source_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE merge_source_table (a int, b text)" +== 949 +-- truncate_limit: 100 +insert into merge_source_table + values (1, 'initial1'), (2, 'initial2'), + (3, 'initial3'), (4, 'initial4') +-- +TABLE: name="merge_source_table" schema="" table="merge_source_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO merge_source_table VALUES (...)" +== 950 +-- truncate_limit: 100 +merge into merge_target_table t +using merge_source_table s +on t.a = s.a +when not matched then + insert values (a, b) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DML +ALIAS: "t"="merge_target_table" +STMT: MergeStmt +TRUNCATED: "MERGE INTO merge_target_table t USING merge_source_table s ON t.a = s.a WHEN NOT MATCHED THEN INS..." +== 951 +-- truncate_limit: 100 +merge into merge_target_table t +using merge_source_table s +on t.a = s.a +when matched and s.a <= 2 then + update set b = t.b || ' updated by merge' +when matched and s.a > 2 then + delete +when not matched then + insert values (a, b) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DML +ALIAS: "t"="merge_target_table" +STMT: MergeStmt +TRUNCATED: "MERGE INTO merge_target_table t USING merge_source_table s ON t.a = s.a WHEN MATCHED AND s.a <= 2..." +== 952 +-- truncate_limit: 100 +merge into merge_target_table t +using merge_source_table s +on t.a = s.a +when matched and s.a <= 2 then + update set b = t.b || ' updated again by merge' +when matched and s.a > 2 then + delete +when not matched then + insert values (a, b) +-- +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DML +ALIAS: "t"="merge_target_table" +STMT: MergeStmt +TRUNCATED: "MERGE INTO merge_target_table t USING merge_source_table s ON t.a = s.a WHEN MATCHED AND s.a <= 2..." +== 953 +-- truncate_limit: 100 +drop table merge_source_table, merge_target_table +-- +TABLE: name="merge_source_table" schema="" table="merge_source_table" ctx=DDL +TABLE: name="merge_target_table" schema="" table="merge_target_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE merge_source_table, merge_target_table" +== 954 +-- truncate_limit: 100 +-- cleanup +drop function dump_insert() +-- +FUNCTION: name="dump_insert" function="dump_insert" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dump_insert()" +== 955 +-- truncate_limit: 100 +drop function dump_update() +-- +FUNCTION: name="dump_update" function="dump_update" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dump_update()" +== 956 +-- truncate_limit: 100 +drop function dump_delete() +-- +FUNCTION: name="dump_delete" function="dump_delete" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dump_delete()" +== 957 +-- truncate_limit: 100 +|-- +-- Tests for CREATE OR REPLACE TRIGGER +|-- +create table my_table (id integer) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE my_table (id int)" +== 958 +-- truncate_limit: 100 +create function funcA() returns trigger as $$ +begin + raise notice 'hello from funcA'; + return null; +end; $$ language plpgsql +-- +FUNCTION: name="funca" function="funca" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION funca() RETURNS trigger AS $$\nbegin\n raise notice 'hello from funcA';\n return n..." +== 959 +-- truncate_limit: 100 +create function funcB() returns trigger as $$ +begin + raise notice 'hello from funcB'; + return null; +end; $$ language plpgsql +-- +FUNCTION: name="funcb" function="funcb" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION funcb() RETURNS trigger AS $$\nbegin\n raise notice 'hello from funcB';\n return n..." +== 960 +-- truncate_limit: 100 +create trigger my_trig + after insert on my_table + for each row execute procedure funcA() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_trig AFTER INSERT ON my_table FOR EACH ROW EXECUTE FUNCTION funca()" +== 961 +-- truncate_limit: 100 +create trigger my_trig + before insert on my_table + for each row execute procedure funcB() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_trig BEFORE INSERT ON my_table FOR EACH ROW EXECUTE FUNCTION funcb()" +== 962 +-- truncate_limit: 100 +-- should fail + +insert into my_table values (1) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO my_table VALUES (1)" +== 963 +-- truncate_limit: 100 +create or replace trigger my_trig + before insert on my_table + for each row execute procedure funcB() +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE OR REPLACE TRIGGER my_trig BEFORE INSERT ON my_table FOR EACH ROW EXECUTE FUNCTION funcb()" +== 964 +-- truncate_limit: 100 +-- OK + +insert into my_table values (2) +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO my_table VALUES (2)" +== 965 +-- truncate_limit: 100 +-- this insert should become a no-op + +table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM my_table" +== 966 +-- truncate_limit: 100 +drop table my_table +-- +TABLE: name="my_table" schema="" table="my_table" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE my_table" +== 967 +-- truncate_limit: 100 +-- test CREATE OR REPLACE TRIGGER on partition table +create table parted_trig (a int) partition by range (a) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig (a int) PARTITION BY RANGE (a)" +== 968 +-- truncate_limit: 100 +create table parted_trig_1 partition of parted_trig + for values from (0) to (1000) partition by range (a) +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig_1 PARTITION OF parted_trig FOR VALUES FROM (0) TO (1000) PARTITION BY RA..." +== 969 +-- truncate_limit: 100 +create table parted_trig_1_1 partition of parted_trig_1 for values from (0) to (100) +-- +TABLE: name="parted_trig_1_1" schema="" table="parted_trig_1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig_1_1 PARTITION OF parted_trig_1 FOR VALUES FROM (0) TO (100)" +== 970 +-- truncate_limit: 100 +create table parted_trig_2 partition of parted_trig for values from (1000) to (2000) +-- +TABLE: name="parted_trig_2" schema="" table="parted_trig_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parted_trig_2 PARTITION OF parted_trig FOR VALUES FROM (1000) TO (2000)" +== 971 +-- truncate_limit: 100 +create table default_parted_trig partition of parted_trig default +-- +TABLE: name="default_parted_trig" schema="" table="default_parted_trig" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE default_parted_trig PARTITION OF parted_trig DEFAULT" +== 972 +-- truncate_limit: 100 +-- test that trigger can be replaced by another one +-- at the same level of partition table +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcA() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE OR REPLACE TRIGGER my_trig AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION funca()" +== 973 +-- truncate_limit: 100 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 974 +-- truncate_limit: 100 +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcB() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE OR REPLACE TRIGGER my_trig AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION funcb()" +== 975 +-- truncate_limit: 100 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 976 +-- truncate_limit: 100 +-- test that child trigger cannot be replaced directly +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcA() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE OR REPLACE TRIGGER my_trig AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION funca()" +== 977 +-- truncate_limit: 100 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 978 +-- truncate_limit: 100 +create or replace trigger my_trig + after insert on parted_trig_1 + for each row execute procedure funcB() +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE OR REPLACE TRIGGER my_trig AFTER INSERT ON parted_trig_1 FOR EACH ROW EXECUTE FUNCTION fun..." +== 979 +-- truncate_limit: 100 +-- should fail +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 980 +-- truncate_limit: 100 +drop trigger my_trig on parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER my_trig ON parted_trig" +== 981 +-- truncate_limit: 100 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 982 +-- truncate_limit: 100 +-- test that user trigger can be overwritten by one defined at upper level +create trigger my_trig + after insert on parted_trig_1 + for each row execute procedure funcA() +-- +TABLE: name="parted_trig_1" schema="" table="parted_trig_1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_trig AFTER INSERT ON parted_trig_1 FOR EACH ROW EXECUTE FUNCTION funca()" +== 983 +-- truncate_limit: 100 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 984 +-- truncate_limit: 100 +create trigger my_trig + after insert on parted_trig + for each row execute procedure funcB() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER my_trig AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION funcb()" +== 985 +-- truncate_limit: 100 +-- should fail +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 986 +-- truncate_limit: 100 +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcB() +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE OR REPLACE TRIGGER my_trig AFTER INSERT ON parted_trig FOR EACH ROW EXECUTE FUNCTION funcb()" +== 987 +-- truncate_limit: 100 +insert into parted_trig (a) values (50) +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parted_trig (a) VALUES (50)" +== 988 +-- truncate_limit: 100 +-- cleanup +drop table parted_trig +-- +TABLE: name="parted_trig" schema="" table="parted_trig" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parted_trig" +== 989 +-- truncate_limit: 100 +drop function funcA() +-- +FUNCTION: name="funca" function="funca" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION funca()" +== 990 +-- truncate_limit: 100 +drop function funcB() +-- +FUNCTION: name="funcb" function="funcb" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION funcb()" +== 991 +-- truncate_limit: 100 +-- Leave around some objects for other tests +create table trigger_parted (a int primary key) partition by list (a) +-- +TABLE: name="trigger_parted" schema="" table="trigger_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_parted (a int PRIMARY KEY) PARTITION BY LIST (a)" +== 992 +-- truncate_limit: 100 +create function trigger_parted_trigfunc() returns trigger language plpgsql as + $$ begin end; $$ +-- +FUNCTION: name="trigger_parted_trigfunc" function="trigger_parted_trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trigger_parted_trigfunc() RETURNS trigger LANGUAGE plpgsql AS $$ begin end; $$" +== 993 +-- truncate_limit: 100 +create trigger aft_row after insert or update on trigger_parted + for each row execute function trigger_parted_trigfunc() +-- +TABLE: name="trigger_parted" schema="" table="trigger_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER aft_row AFTER INSERT OR UPDATE ON trigger_parted FOR EACH ROW EXECUTE FUNCTION tri..." +== 994 +-- truncate_limit: 100 +create table trigger_parted_p1 partition of trigger_parted for values in (1) + partition by list (a) +-- +TABLE: name="trigger_parted_p1" schema="" table="trigger_parted_p1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_parted_p1 PARTITION OF trigger_parted FOR VALUES IN (1) PARTITION BY LIST (a)" +== 995 +-- truncate_limit: 100 +create table trigger_parted_p1_1 partition of trigger_parted_p1 for values in (1) +-- +TABLE: name="trigger_parted_p1_1" schema="" table="trigger_parted_p1_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_parted_p1_1 PARTITION OF trigger_parted_p1 FOR VALUES IN (1)" +== 996 +-- truncate_limit: 100 +create table trigger_parted_p2 partition of trigger_parted for values in (2) + partition by list (a) +-- +TABLE: name="trigger_parted_p2" schema="" table="trigger_parted_p2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_parted_p2 PARTITION OF trigger_parted FOR VALUES IN (2) PARTITION BY LIST (a)" +== 997 +-- truncate_limit: 100 +create table trigger_parted_p2_2 partition of trigger_parted_p2 for values in (2) +-- +TABLE: name="trigger_parted_p2_2" schema="" table="trigger_parted_p2_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trigger_parted_p2_2 PARTITION OF trigger_parted_p2 FOR VALUES IN (2)" +== 998 +-- truncate_limit: 100 +alter table only trigger_parted_p2 disable trigger aft_row +-- +TABLE: name="trigger_parted_p2" schema="" table="trigger_parted_p2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE ONLY trigger_parted_p2 DISABLE TRIGGER aft_row" +== 999 +-- truncate_limit: 100 +alter table trigger_parted_p2_2 enable always trigger aft_row +-- +TABLE: name="trigger_parted_p2_2" schema="" table="trigger_parted_p2_2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE trigger_parted_p2_2 ENABLE ALWAYS TRIGGER aft_row" +== 1000 +-- truncate_limit: 100 +-- verify transition table conversion slot's lifetime +-- https://postgr.es/m/39a71864-b120-5a5c-8cc5-c632b6f16761@amazon.com +create table convslot_test_parent (col1 text primary key) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE convslot_test_parent (col1 text PRIMARY KEY)" +== 1001 +-- truncate_limit: 100 +create table convslot_test_child (col1 text primary key, + foreign key (col1) references convslot_test_parent(col1) on delete cascade on update cascade +) +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE convslot_test_child (col1 text PRIMARY KEY, FOREIGN KEY (col1) REFERENCES convslot_t..." +== 1002 +-- truncate_limit: 100 +alter table convslot_test_child add column col2 text not null default 'tutu' +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE convslot_test_child ADD COLUMN col2 text NOT NULL DEFAULT 'tutu'" +== 1003 +-- truncate_limit: 100 +insert into convslot_test_parent(col1) values ('1') +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO convslot_test_parent (col1) VALUES ('1')" +== 1004 +-- truncate_limit: 100 +insert into convslot_test_child(col1) values ('1') +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO convslot_test_child (col1) VALUES ('1')" +== 1005 +-- truncate_limit: 100 +insert into convslot_test_parent(col1) values ('3') +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO convslot_test_parent (col1) VALUES ('3')" +== 1006 +-- truncate_limit: 100 +insert into convslot_test_child(col1) values ('3') +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO convslot_test_child (col1) VALUES ('3')" +== 1007 +-- truncate_limit: 100 +create function convslot_trig1() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, old_table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by col1) from old_table); +return null; +end; $$ +-- +FUNCTION: name="convslot_trig1" function="convslot_trig1" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION convslot_trig1() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\nraise notice 'trigg..." +== 1008 +-- truncate_limit: 100 +create function convslot_trig2() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, new table = %', + TG_NAME, + (select string_agg(new_table::text, ', ' order by col1) from new_table); +return null; +end; $$ +-- +FUNCTION: name="convslot_trig2" function="convslot_trig2" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION convslot_trig2() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\nraise notice 'trigg..." +== 1009 +-- truncate_limit: 100 +create trigger but_trigger after update on convslot_test_child +referencing new table as new_table +for each statement execute function convslot_trig2() +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER but_trigger AFTER UPDATE ON convslot_test_child REFERENCING NEW TABLE new_table EX..." +== 1010 +-- truncate_limit: 100 +update convslot_test_parent set col1 = col1 || '1' +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE convslot_test_parent SET col1 = col1 || '1'" +== 1011 +-- truncate_limit: 100 +create function convslot_trig3() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, old_table = %, new table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by col1) from old_table), + (select string_agg(new_table::text, ', ' order by col1) from new_table); +return null; +end; $$ +-- +FUNCTION: name="convslot_trig3" function="convslot_trig3" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION convslot_trig3() RETURNS trigger LANGUAGE plpgsql AS $$\nbegin\nraise notice 'trigg..." +== 1012 +-- truncate_limit: 100 +create trigger but_trigger2 after update on convslot_test_child +referencing old table as old_table new table as new_table +for each statement execute function convslot_trig3() +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER but_trigger2 AFTER UPDATE ON convslot_test_child REFERENCING OLD TABLE old_table N..." +== 1013 +-- truncate_limit: 100 +update convslot_test_parent set col1 = col1 || '1' +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE convslot_test_parent SET col1 = col1 || '1'" +== 1014 +-- truncate_limit: 100 +create trigger bdt_trigger after delete on convslot_test_child +referencing old table as old_table +for each statement execute function convslot_trig1() +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER bdt_trigger AFTER DELETE ON convslot_test_child REFERENCING OLD TABLE old_table EX..." +== 1015 +-- truncate_limit: 100 +delete from convslot_test_parent +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM convslot_test_parent" +== 1016 +-- truncate_limit: 100 +drop table convslot_test_child, convslot_test_parent +-- +TABLE: name="convslot_test_child" schema="" table="convslot_test_child" ctx=DDL +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE convslot_test_child, convslot_test_parent" +== 1017 +-- truncate_limit: 100 +drop function convslot_trig1() +-- +FUNCTION: name="convslot_trig1" function="convslot_trig1" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION convslot_trig1()" +== 1018 +-- truncate_limit: 100 +drop function convslot_trig2() +-- +FUNCTION: name="convslot_trig2" function="convslot_trig2" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION convslot_trig2()" +== 1019 +-- truncate_limit: 100 +drop function convslot_trig3() +-- +FUNCTION: name="convslot_trig3" function="convslot_trig3" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION convslot_trig3()" +== 1020 +-- truncate_limit: 100 +-- Bug #17607: variant of above in which trigger function raises an error; +-- we don't see any ill effects unless trigger tuple requires mapping + +create table convslot_test_parent (id int primary key, val int) +partition by range (id) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE convslot_test_parent (id int PRIMARY KEY, val int) PARTITION BY RANGE (id)" +== 1021 +-- truncate_limit: 100 +create table convslot_test_part (val int, id int not null) +-- +TABLE: name="convslot_test_part" schema="" table="convslot_test_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE convslot_test_part (val int, id int NOT NULL)" +== 1022 +-- truncate_limit: 100 +alter table convslot_test_parent + attach partition convslot_test_part for values from (1) to (1000) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE convslot_test_parent ATTACH PARTITION convslot_test_part FOR VALUES FROM (1) TO (1000)" +== 1023 +-- truncate_limit: 100 +create function convslot_trig4() returns trigger as +$$begin raise exception 'BOOM!'; end$$ language plpgsql +-- +FUNCTION: name="convslot_trig4" function="convslot_trig4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION convslot_trig4() RETURNS trigger AS $$begin raise exception 'BOOM!'; end$$ LANGUA..." +== 1024 +-- truncate_limit: 100 +create trigger convslot_test_parent_update + after update on convslot_test_parent + referencing old table as old_rows new table as new_rows + for each statement execute procedure convslot_trig4() +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER convslot_test_parent_update AFTER UPDATE ON convslot_test_parent REFERENCING OLD T..." +== 1025 +-- truncate_limit: 100 +insert into convslot_test_parent (id, val) values (1, 2) +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO convslot_test_parent (id, val) VALUES (1, 2)" +== 1026 +-- truncate_limit: 100 +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 1027 +-- truncate_limit: 100 +savepoint svp +-- +STMT: TransactionStmt +TRUNCATED: "SAVEPOINT svp" +== 1028 +-- truncate_limit: 100 +update convslot_test_parent set val = 3 +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE convslot_test_parent SET val = 3" +== 1029 +-- truncate_limit: 100 +-- error expected +rollback to savepoint svp +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK TO SAVEPOINT svp" +== 1030 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 1031 +-- truncate_limit: 100 +drop table convslot_test_parent +-- +TABLE: name="convslot_test_parent" schema="" table="convslot_test_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE convslot_test_parent" +== 1032 +-- truncate_limit: 100 +drop function convslot_trig4() +-- +FUNCTION: name="convslot_trig4" function="convslot_trig4" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION convslot_trig4()" +== 1033 +-- truncate_limit: 100 +-- Test trigger renaming on partitioned tables +create table grandparent (id int, primary key (id)) partition by range (id) +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE grandparent (id int, PRIMARY KEY (id)) PARTITION BY RANGE (id)" +== 1034 +-- truncate_limit: 100 +create table middle partition of grandparent for values from (1) to (10) +partition by range (id) +-- +TABLE: name="middle" schema="" table="middle" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE middle PARTITION OF grandparent FOR VALUES FROM (1) TO (10) PARTITION BY RANGE (id)" +== 1035 +-- truncate_limit: 100 +create table chi partition of middle for values from (1) to (5) +-- +TABLE: name="chi" schema="" table="chi" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE chi PARTITION OF middle FOR VALUES FROM (1) TO (5)" +== 1036 +-- truncate_limit: 100 +create table cho partition of middle for values from (6) to (10) +-- +TABLE: name="cho" schema="" table="cho" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE cho PARTITION OF middle FOR VALUES FROM (6) TO (10)" +== 1037 +-- truncate_limit: 100 +create function f () returns trigger as +$$ begin return new; end; $$ +language plpgsql +-- +FUNCTION: name="f" function="f" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION f() RETURNS trigger AS $$ begin return new; end; $$ LANGUAGE plpgsql" +== 1038 +-- truncate_limit: 100 +create trigger a after insert on grandparent +for each row execute procedure f() +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER a AFTER INSERT ON grandparent FOR EACH ROW EXECUTE FUNCTION f()" +== 1039 +-- truncate_limit: 100 +alter trigger a on grandparent rename to b +-- +STMT: RenameStmt +TRUNCATED: "ALTER TRIGGER a ON grandparent RENAME TO b" +== 1040 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, +(select tgname from pg_trigger tr where tr.oid = pg_trigger.tgparentid) parent_tgname +from pg_trigger where tgrelid in (select relid from pg_partition_tree('grandparent')) +order by tgname, tgrelid::regclass::text COLLATE "C" +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +ALIAS: "tr"="pg_trigger" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="tr" column="oid" +FILTER: schema="" table="pg_trigger" column="tgparentid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgname, tgrelid::regclass::text COLLATE \"C\"" +== 1041 +-- truncate_limit: 100 +alter trigger a on only grandparent rename to b +-- +ERROR: syntax error at or near "only" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 1042 +-- truncate_limit: 100 +-- ONLY not supported +alter trigger b on middle rename to c +-- +STMT: RenameStmt +TRUNCATED: "ALTER TRIGGER b ON middle RENAME TO c" +== 1043 +-- truncate_limit: 100 +-- can't rename trigger on partition +create trigger c after insert on middle +for each row execute procedure f() +-- +TABLE: name="middle" schema="" table="middle" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER c AFTER INSERT ON middle FOR EACH ROW EXECUTE FUNCTION f()" +== 1044 +-- truncate_limit: 100 +alter trigger b on grandparent rename to c +-- +STMT: RenameStmt +TRUNCATED: "ALTER TRIGGER b ON grandparent RENAME TO c" +== 1045 +-- truncate_limit: 100 +-- Rename cascading does not affect statement triggers +create trigger p after insert on grandparent for each statement execute function f() +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER p AFTER INSERT ON grandparent EXECUTE FUNCTION f()" +== 1046 +-- truncate_limit: 100 +create trigger p after insert on middle for each statement execute function f() +-- +TABLE: name="middle" schema="" table="middle" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER p AFTER INSERT ON middle EXECUTE FUNCTION f()" +== 1047 +-- truncate_limit: 100 +alter trigger p on grandparent rename to q +-- +STMT: RenameStmt +TRUNCATED: "ALTER TRIGGER p ON grandparent RENAME TO q" +== 1048 +-- truncate_limit: 100 +select tgrelid::regclass, tgname, +(select tgname from pg_trigger tr where tr.oid = pg_trigger.tgparentid) parent_tgname +from pg_trigger where tgrelid in (select relid from pg_partition_tree('grandparent')) +order by tgname, tgrelid::regclass::text COLLATE "C" +-- +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +TABLE: name="pg_trigger" schema="" table="pg_trigger" ctx=Select +ALIAS: "tr"="pg_trigger" +FUNCTION: name="pg_partition_tree" function="pg_partition_tree" schema="" ctx=Call +FILTER: schema="" table="" column="tgrelid" +FILTER: schema="" table="tr" column="oid" +FILTER: schema="" table="pg_trigger" column="tgparentid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_trigger WHERE ... ORDER BY tgname, tgrelid::regclass::text COLLATE \"C\"" +== 1049 +-- truncate_limit: 100 +drop table grandparent +-- +TABLE: name="grandparent" schema="" table="grandparent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE grandparent" +== 1050 +-- truncate_limit: 100 +-- Trigger renaming does not recurse on legacy inheritance +create table parent (a int) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parent (a int)" +== 1051 +-- truncate_limit: 100 +create table child () inherits (parent) +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE child () INHERITS (parent)" +== 1052 +-- truncate_limit: 100 +create trigger parenttrig after insert on parent +for each row execute procedure f() +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parenttrig AFTER INSERT ON parent FOR EACH ROW EXECUTE FUNCTION f()" +== 1053 +-- truncate_limit: 100 +create trigger parenttrig after insert on child +for each row execute procedure f() +-- +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parenttrig AFTER INSERT ON child FOR EACH ROW EXECUTE FUNCTION f()" +== 1054 +-- truncate_limit: 100 +alter trigger parenttrig on parent rename to anothertrig +-- +STMT: RenameStmt +TRUNCATED: "ALTER TRIGGER parenttrig ON parent RENAME TO anothertrig" +== 1055 +-- truncate_limit: 100 +drop table parent, child +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +TABLE: name="child" schema="" table="child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parent, child" +== 1056 +-- truncate_limit: 100 +drop function f() +-- +FUNCTION: name="f" function="f" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION f()" diff --git a/parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json new file mode 100644 index 0000000..5ad4c2c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json @@ -0,0 +1,197 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/truncate.test b/parser/testdata/summary_truncate/postgres_regress/truncate.test new file mode 100644 index 0000000..97df7a8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/truncate.test @@ -0,0 +1,1497 @@ +== 001 +-- truncate_limit: 100 +-- Test basic TRUNCATE functionality. +CREATE TABLE truncate_a (col1 integer primary key) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncate_a (col1 int PRIMARY KEY)" +== 002 +-- truncate_limit: 100 +INSERT INTO truncate_a VALUES (1) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO truncate_a VALUES (1)" +== 003 +-- truncate_limit: 100 +INSERT INTO truncate_a VALUES (2) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO truncate_a VALUES (2)" +== 004 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 005 +-- truncate_limit: 100 +-- Roll truncate back +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 006 +-- truncate_limit: 100 +TRUNCATE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a" +== 007 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 008 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 009 +-- truncate_limit: 100 +-- Commit the truncate this time +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 010 +-- truncate_limit: 100 +TRUNCATE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a" +== 011 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 012 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 013 +-- truncate_limit: 100 +-- Test foreign-key checks +CREATE TABLE trunc_b (a int REFERENCES truncate_a) +-- +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_b (a int REFERENCES truncate_a)" +== 014 +-- truncate_limit: 100 +CREATE TABLE trunc_c (a serial PRIMARY KEY) +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_c (a serial PRIMARY KEY)" +== 015 +-- truncate_limit: 100 +CREATE TABLE trunc_d (a int REFERENCES trunc_c) +-- +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_d (a int REFERENCES trunc_c)" +== 016 +-- truncate_limit: 100 +CREATE TABLE trunc_e (a int REFERENCES truncate_a, b int REFERENCES trunc_c) +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_e (a int REFERENCES truncate_a, b int REFERENCES trunc_c)" +== 017 +-- truncate_limit: 100 +TRUNCATE TABLE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a" +== 018 +-- truncate_limit: 100 +-- fail +TRUNCATE TABLE truncate_a,trunc_b +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a, trunc_b" +== 019 +-- truncate_limit: 100 +-- fail +TRUNCATE TABLE truncate_a,trunc_b,trunc_e +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a, trunc_b, trunc_e" +== 020 +-- truncate_limit: 100 +-- ok +TRUNCATE TABLE truncate_a,trunc_e +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a, trunc_e" +== 021 +-- truncate_limit: 100 +-- fail +TRUNCATE TABLE trunc_c +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c" +== 022 +-- truncate_limit: 100 +-- fail +TRUNCATE TABLE trunc_c,trunc_d +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, trunc_d" +== 023 +-- truncate_limit: 100 +-- fail +TRUNCATE TABLE trunc_c,trunc_d,trunc_e +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, trunc_d, trunc_e" +== 024 +-- truncate_limit: 100 +-- ok +TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, trunc_d, trunc_e, truncate_a" +== 025 +-- truncate_limit: 100 +-- fail +TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, trunc_d, trunc_e, truncate_a, trunc_b" +== 026 +-- truncate_limit: 100 +-- ok + +TRUNCATE TABLE truncate_a RESTRICT +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a" +== 027 +-- truncate_limit: 100 +-- fail +TRUNCATE TABLE truncate_a CASCADE +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a CASCADE" +== 028 +-- truncate_limit: 100 +-- ok + +-- circular references +ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c" +== 029 +-- truncate_limit: 100 +-- Add some data to verify that truncating actually works ... +INSERT INTO trunc_c VALUES (1) +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_c VALUES (1)" +== 030 +-- truncate_limit: 100 +INSERT INTO truncate_a VALUES (1) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO truncate_a VALUES (1)" +== 031 +-- truncate_limit: 100 +INSERT INTO trunc_b VALUES (1) +-- +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_b VALUES (1)" +== 032 +-- truncate_limit: 100 +INSERT INTO trunc_d VALUES (1) +-- +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_d VALUES (1)" +== 033 +-- truncate_limit: 100 +INSERT INTO trunc_e VALUES (1,1) +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_e VALUES (1, 1)" +== 034 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_c +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c" +== 035 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_c,truncate_a +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, truncate_a" +== 036 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_c,truncate_a,trunc_d +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, truncate_a, trunc_d" +== 037 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, truncate_a, trunc_d, trunc_e" +== 038 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e,trunc_b +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c, truncate_a, trunc_d, trunc_e, trunc_b" +== 039 +-- truncate_limit: 100 +-- Verify that truncating did actually work +SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=Select +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=Select +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=Select +STMT: SelectStmt +TRUNCATED: "((SELECT * FROM truncate_a UNION ALL SELECT * FROM trunc_c) UNION ALL SELECT * FROM trunc_b) UNIO..." +== 040 +-- truncate_limit: 100 +SELECT * FROM trunc_e +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_e" +== 041 +-- truncate_limit: 100 +-- Add data again to test TRUNCATE ... CASCADE +INSERT INTO trunc_c VALUES (1) +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_c VALUES (1)" +== 042 +-- truncate_limit: 100 +INSERT INTO truncate_a VALUES (1) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO truncate_a VALUES (1)" +== 043 +-- truncate_limit: 100 +INSERT INTO trunc_b VALUES (1) +-- +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_b VALUES (1)" +== 044 +-- truncate_limit: 100 +INSERT INTO trunc_d VALUES (1) +-- +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_d VALUES (1)" +== 045 +-- truncate_limit: 100 +INSERT INTO trunc_e VALUES (1,1) +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_e VALUES (1, 1)" +== 046 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_c CASCADE +-- +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_c CASCADE" +== 047 +-- truncate_limit: 100 +-- ok + +SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=Select +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=Select +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=Select +STMT: SelectStmt +TRUNCATED: "((SELECT * FROM truncate_a UNION ALL SELECT * FROM trunc_c) UNION ALL SELECT * FROM trunc_b) UNIO..." +== 048 +-- truncate_limit: 100 +SELECT * FROM trunc_e +-- +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_e" +== 049 +-- truncate_limit: 100 +DROP TABLE truncate_a,trunc_c,trunc_b,trunc_d,trunc_e CASCADE +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +TABLE: name="trunc_c" schema="" table="trunc_c" ctx=DDL +TABLE: name="trunc_b" schema="" table="trunc_b" ctx=DDL +TABLE: name="trunc_d" schema="" table="trunc_d" ctx=DDL +TABLE: name="trunc_e" schema="" table="trunc_e" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE truncate_a, trunc_c, trunc_b, trunc_d, trunc_e CASCADE" +== 050 +-- truncate_limit: 100 +-- Test TRUNCATE with inheritance + +CREATE TABLE trunc_f (col1 integer primary key) +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_f (col1 int PRIMARY KEY)" +== 051 +-- truncate_limit: 100 +INSERT INTO trunc_f VALUES (1) +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_f VALUES (1)" +== 052 +-- truncate_limit: 100 +INSERT INTO trunc_f VALUES (2) +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_f VALUES (2)" +== 053 +-- truncate_limit: 100 +CREATE TABLE trunc_fa (col2a text) INHERITS (trunc_f) +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_fa (col2a text) INHERITS (trunc_f)" +== 054 +-- truncate_limit: 100 +INSERT INTO trunc_fa VALUES (3, 'three') +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_fa VALUES (3, 'three')" +== 055 +-- truncate_limit: 100 +CREATE TABLE trunc_fb (col2b int) INHERITS (trunc_f) +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_fb (col2b int) INHERITS (trunc_f)" +== 056 +-- truncate_limit: 100 +INSERT INTO trunc_fb VALUES (4, 444) +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_fb VALUES (4, 444)" +== 057 +-- truncate_limit: 100 +CREATE TABLE trunc_faa (col3 text) INHERITS (trunc_fa) +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_faa (col3 text) INHERITS (trunc_fa)" +== 058 +-- truncate_limit: 100 +INSERT INTO trunc_faa VALUES (5, 'five', 'FIVE') +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_faa VALUES (5, 'five', 'FIVE')" +== 059 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 060 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 061 +-- truncate_limit: 100 +TRUNCATE trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_f" +== 062 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 063 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 064 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 065 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 066 +-- truncate_limit: 100 +TRUNCATE ONLY trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ONLY trunc_f" +== 067 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 068 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 069 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 070 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 071 +-- truncate_limit: 100 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_fa" +== 072 +-- truncate_limit: 100 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_faa" +== 073 +-- truncate_limit: 100 +TRUNCATE ONLY trunc_fb, ONLY trunc_fa +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DDL +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ONLY trunc_fb, ONLY trunc_fa" +== 074 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 075 +-- truncate_limit: 100 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_fa" +== 076 +-- truncate_limit: 100 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_faa" +== 077 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 078 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 079 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 080 +-- truncate_limit: 100 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_fa" +== 081 +-- truncate_limit: 100 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_faa" +== 082 +-- truncate_limit: 100 +TRUNCATE ONLY trunc_fb, trunc_fa +-- +TABLE: name="trunc_fb" schema="" table="trunc_fb" ctx=DDL +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ONLY trunc_fb, trunc_fa" +== 083 +-- truncate_limit: 100 +SELECT * FROM trunc_f +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_f" +== 084 +-- truncate_limit: 100 +SELECT * FROM trunc_fa +-- +TABLE: name="trunc_fa" schema="" table="trunc_fa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_fa" +== 085 +-- truncate_limit: 100 +SELECT * FROM trunc_faa +-- +TABLE: name="trunc_faa" schema="" table="trunc_faa" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_faa" +== 086 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 087 +-- truncate_limit: 100 +DROP TABLE trunc_f CASCADE +-- +TABLE: name="trunc_f" schema="" table="trunc_f" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trunc_f CASCADE" +== 088 +-- truncate_limit: 100 +-- Test ON TRUNCATE triggers + +CREATE TABLE trunc_trigger_test (f1 int, f2 text, f3 text) +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_trigger_test (f1 int, f2 text, f3 text)" +== 089 +-- truncate_limit: 100 +CREATE TABLE trunc_trigger_log (tgop text, tglevel text, tgwhen text, + tgargv text, tgtable name, rowcount bigint) +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_trigger_log (tgop text, tglevel text, tgwhen text, tgargv text, tgtable name, ..." +== 090 +-- truncate_limit: 100 +CREATE FUNCTION trunctrigger() RETURNS trigger as $$ +declare c bigint; +begin + execute 'select count(*) from ' || quote_ident(tg_table_name) into c; + insert into trunc_trigger_log values + (TG_OP, TG_LEVEL, TG_WHEN, TG_ARGV[0], tg_table_name, c); + return null; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="trunctrigger" function="trunctrigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trunctrigger() RETURNS trigger AS $$\ndeclare c bigint;\nbegin\n execute 'select ..." +== 091 +-- truncate_limit: 100 +-- basic before trigger +INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_trigger_test VALUES (1, 'foo', 'bar'), (2, 'baz', 'quux')" +== 092 +-- truncate_limit: 100 +CREATE TRIGGER t +BEFORE TRUNCATE ON trunc_trigger_test +FOR EACH STATEMENT +EXECUTE PROCEDURE trunctrigger('before trigger truncate') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER t BEFORE TRUNCATE ON trunc_trigger_test EXECUTE FUNCTION trunctrigger('before trig..." +== 093 +-- truncate_limit: 100 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS \"Row count in test table\" FROM trunc_trigger_test" +== 094 +-- truncate_limit: 100 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_trigger_log" +== 095 +-- truncate_limit: 100 +TRUNCATE trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_trigger_test" +== 096 +-- truncate_limit: 100 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS \"Row count in test table\" FROM trunc_trigger_test" +== 097 +-- truncate_limit: 100 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_trigger_log" +== 098 +-- truncate_limit: 100 +DROP TRIGGER t ON trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER t ON trunc_trigger_test" +== 099 +-- truncate_limit: 100 +truncate trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_trigger_log" +== 100 +-- truncate_limit: 100 +-- same test with an after trigger +INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_trigger_test VALUES (1, 'foo', 'bar'), (2, 'baz', 'quux')" +== 101 +-- truncate_limit: 100 +CREATE TRIGGER tt +AFTER TRUNCATE ON trunc_trigger_test +FOR EACH STATEMENT +EXECUTE PROCEDURE trunctrigger('after trigger truncate') +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tt AFTER TRUNCATE ON trunc_trigger_test EXECUTE FUNCTION trunctrigger('after trigg..." +== 102 +-- truncate_limit: 100 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS \"Row count in test table\" FROM trunc_trigger_test" +== 103 +-- truncate_limit: 100 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_trigger_log" +== 104 +-- truncate_limit: 100 +TRUNCATE trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_trigger_test" +== 105 +-- truncate_limit: 100 +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS \"Row count in test table\" FROM trunc_trigger_test" +== 106 +-- truncate_limit: 100 +SELECT * FROM trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM trunc_trigger_log" +== 107 +-- truncate_limit: 100 +DROP TABLE trunc_trigger_test +-- +TABLE: name="trunc_trigger_test" schema="" table="trunc_trigger_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trunc_trigger_test" +== 108 +-- truncate_limit: 100 +DROP TABLE trunc_trigger_log +-- +TABLE: name="trunc_trigger_log" schema="" table="trunc_trigger_log" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trunc_trigger_log" +== 109 +-- truncate_limit: 100 +DROP FUNCTION trunctrigger() +-- +FUNCTION: name="trunctrigger" function="trunctrigger" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION trunctrigger()" +== 110 +-- truncate_limit: 100 +-- test TRUNCATE ... RESTART IDENTITY +CREATE SEQUENCE truncate_a_id1 START WITH 33 +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE truncate_a_id1 START 33" +== 111 +-- truncate_limit: 100 +CREATE TABLE truncate_a (id serial, + id1 integer default nextval('truncate_a_id1')) +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncate_a (id serial, id1 int DEFAULT nextval('truncate_a_id1'))" +== 112 +-- truncate_limit: 100 +ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1 +-- +STMT: AlterSeqStmt +TRUNCATED: "ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1" +== 113 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 114 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 115 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 116 +-- truncate_limit: 100 +TRUNCATE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a" +== 117 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 118 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 119 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 120 +-- truncate_limit: 100 +TRUNCATE truncate_a RESTART IDENTITY +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a RESTART IDENTITY" +== 121 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 122 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 123 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 124 +-- truncate_limit: 100 +CREATE TABLE truncate_b (id int GENERATED ALWAYS AS IDENTITY (START WITH 44)) +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncate_b (id int GENERATED ALWAYS AS IDENTITY (START 44 ))" +== 125 +-- truncate_limit: 100 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_b DEFAULT VALUES" +== 126 +-- truncate_limit: 100 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_b DEFAULT VALUES" +== 127 +-- truncate_limit: 100 +SELECT * FROM truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_b" +== 128 +-- truncate_limit: 100 +TRUNCATE truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_b" +== 129 +-- truncate_limit: 100 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_b DEFAULT VALUES" +== 130 +-- truncate_limit: 100 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_b DEFAULT VALUES" +== 131 +-- truncate_limit: 100 +SELECT * FROM truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_b" +== 132 +-- truncate_limit: 100 +TRUNCATE truncate_b RESTART IDENTITY +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_b RESTART IDENTITY" +== 133 +-- truncate_limit: 100 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_b DEFAULT VALUES" +== 134 +-- truncate_limit: 100 +INSERT INTO truncate_b DEFAULT VALUES +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_b DEFAULT VALUES" +== 135 +-- truncate_limit: 100 +SELECT * FROM truncate_b +-- +TABLE: name="truncate_b" schema="" table="truncate_b" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_b" +== 136 +-- truncate_limit: 100 +-- check rollback of a RESTART IDENTITY operation +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 137 +-- truncate_limit: 100 +TRUNCATE truncate_a RESTART IDENTITY +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncate_a RESTART IDENTITY" +== 138 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 139 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 140 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 141 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 142 +-- truncate_limit: 100 +INSERT INTO truncate_a DEFAULT VALUES +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO truncate_a DEFAULT VALUES" +== 143 +-- truncate_limit: 100 +SELECT * FROM truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM truncate_a" +== 144 +-- truncate_limit: 100 +DROP TABLE truncate_a +-- +TABLE: name="truncate_a" schema="" table="truncate_a" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE truncate_a" +== 145 +-- truncate_limit: 100 +SELECT nextval('truncate_a_id1') +-- +FUNCTION: name="nextval" function="nextval" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nextval('truncate_a_id1')" +== 146 +-- truncate_limit: 100 +-- fail, seq should have been dropped + +-- partitioned table +CREATE TABLE truncparted (a int, b char) PARTITION BY LIST (a) +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncparted (a int, b char(1)) PARTITION BY LIST (a)" +== 147 +-- truncate_limit: 100 +-- error, can't truncate a partitioned table +TRUNCATE ONLY truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ONLY truncparted" +== 148 +-- truncate_limit: 100 +CREATE TABLE truncparted1 PARTITION OF truncparted FOR VALUES IN (1) +-- +TABLE: name="truncparted1" schema="" table="truncparted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncparted1 PARTITION OF truncparted FOR VALUES IN (1)" +== 149 +-- truncate_limit: 100 +INSERT INTO truncparted VALUES (1, 'a') +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO truncparted VALUES (1, 'a')" +== 150 +-- truncate_limit: 100 +-- error, must truncate partitions +TRUNCATE ONLY truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE ONLY truncparted" +== 151 +-- truncate_limit: 100 +TRUNCATE truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncparted" +== 152 +-- truncate_limit: 100 +DROP TABLE truncparted +-- +TABLE: name="truncparted" schema="" table="truncparted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE truncparted" +== 153 +-- truncate_limit: 100 +-- foreign key on partitioned table: partition key is referencing column. +-- Make sure truncate did execute on all tables +CREATE FUNCTION tp_ins_data() RETURNS void LANGUAGE plpgsql AS $$ + BEGIN + INSERT INTO truncprim VALUES (1), (100), (150); + INSERT INTO truncpart VALUES (1), (100), (150); + END +$$ +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tp_ins_data() RETURNS void LANGUAGE plpgsql AS $$\n BEGIN\n\tINSERT INTO truncprim ..." +== 154 +-- truncate_limit: 100 +CREATE FUNCTION tp_chk_data(OUT pktb regclass, OUT pkval int, OUT fktb regclass, OUT fkval int) + RETURNS SETOF record LANGUAGE plpgsql AS $$ + BEGIN + RETURN QUERY SELECT + pk.tableoid::regclass, pk.a, fk.tableoid::regclass, fk.a + FROM truncprim pk FULL JOIN truncpart fk USING (a) + ORDER BY 2, 4; + END +$$ +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION tp_chk_data(OUT pktb regclass, OUT pkval int, OUT fktb regclass, OUT fkval int) R..." +== 155 +-- truncate_limit: 100 +CREATE TABLE truncprim (a int PRIMARY KEY) +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncprim (a int PRIMARY KEY)" +== 156 +-- truncate_limit: 100 +CREATE TABLE truncpart (a int REFERENCES truncprim) + PARTITION BY RANGE (a) +-- +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncpart (a int REFERENCES truncprim) PARTITION BY RANGE (a)" +== 157 +-- truncate_limit: 100 +CREATE TABLE truncpart_1 PARTITION OF truncpart FOR VALUES FROM (0) TO (100) +-- +TABLE: name="truncpart_1" schema="" table="truncpart_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncpart_1 PARTITION OF truncpart FOR VALUES FROM (0) TO (100)" +== 158 +-- truncate_limit: 100 +CREATE TABLE truncpart_2 PARTITION OF truncpart FOR VALUES FROM (100) TO (200) + PARTITION BY RANGE (a) +-- +TABLE: name="truncpart_2" schema="" table="truncpart_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncpart_2 PARTITION OF truncpart FOR VALUES FROM (100) TO (200) PARTITION BY RANGE..." +== 159 +-- truncate_limit: 100 +CREATE TABLE truncpart_2_1 PARTITION OF truncpart_2 FOR VALUES FROM (100) TO (150) +-- +TABLE: name="truncpart_2_1" schema="" table="truncpart_2_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncpart_2_1 PARTITION OF truncpart_2 FOR VALUES FROM (100) TO (150)" +== 160 +-- truncate_limit: 100 +CREATE TABLE truncpart_2_d PARTITION OF truncpart_2 DEFAULT +-- +TABLE: name="truncpart_2_d" schema="" table="truncpart_2_d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE truncpart_2_d PARTITION OF truncpart_2 DEFAULT" +== 161 +-- truncate_limit: 100 +TRUNCATE TABLE truncprim +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncprim" +== 162 +-- truncate_limit: 100 +-- should fail + +select tp_ins_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tp_ins_data()" +== 163 +-- truncate_limit: 100 +-- should truncate everything +TRUNCATE TABLE truncprim, truncpart +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncprim, truncpart" +== 164 +-- truncate_limit: 100 +select * from tp_chk_data() +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tp_chk_data()" +== 165 +-- truncate_limit: 100 +select tp_ins_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tp_ins_data()" +== 166 +-- truncate_limit: 100 +-- should truncate everything +TRUNCATE TABLE truncprim CASCADE +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncprim CASCADE" +== 167 +-- truncate_limit: 100 +SELECT * FROM tp_chk_data() +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tp_chk_data()" +== 168 +-- truncate_limit: 100 +SELECT tp_ins_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tp_ins_data()" +== 169 +-- truncate_limit: 100 +-- should truncate all partitions +TRUNCATE TABLE truncpart +-- +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE truncpart" +== 170 +-- truncate_limit: 100 +SELECT * FROM tp_chk_data() +-- +FUNCTION: name="tp_chk_data" function="tp_chk_data" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tp_chk_data()" +== 171 +-- truncate_limit: 100 +DROP TABLE truncprim, truncpart +-- +TABLE: name="truncprim" schema="" table="truncprim" ctx=DDL +TABLE: name="truncpart" schema="" table="truncpart" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE truncprim, truncpart" +== 172 +-- truncate_limit: 100 +DROP FUNCTION tp_ins_data(), tp_chk_data() +-- +FUNCTION: name="tp_ins_data" function="tp_ins_data" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION tp_ins_data(), tp_chk_data()" +== 173 +-- truncate_limit: 100 +-- test cascade when referencing a partitioned table +CREATE TABLE trunc_a (a INT PRIMARY KEY) PARTITION BY RANGE (a) +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_a (a int PRIMARY KEY) PARTITION BY RANGE (a)" +== 174 +-- truncate_limit: 100 +CREATE TABLE trunc_a1 PARTITION OF trunc_a FOR VALUES FROM (0) TO (10) +-- +TABLE: name="trunc_a1" schema="" table="trunc_a1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_a1 PARTITION OF trunc_a FOR VALUES FROM (0) TO (10)" +== 175 +-- truncate_limit: 100 +CREATE TABLE trunc_a2 PARTITION OF trunc_a FOR VALUES FROM (10) TO (20) + PARTITION BY RANGE (a) +-- +TABLE: name="trunc_a2" schema="" table="trunc_a2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_a2 PARTITION OF trunc_a FOR VALUES FROM (10) TO (20) PARTITION BY RANGE (a)" +== 176 +-- truncate_limit: 100 +CREATE TABLE trunc_a21 PARTITION OF trunc_a2 FOR VALUES FROM (10) TO (12) +-- +TABLE: name="trunc_a21" schema="" table="trunc_a21" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_a21 PARTITION OF trunc_a2 FOR VALUES FROM (10) TO (12)" +== 177 +-- truncate_limit: 100 +CREATE TABLE trunc_a22 PARTITION OF trunc_a2 FOR VALUES FROM (12) TO (16) +-- +TABLE: name="trunc_a22" schema="" table="trunc_a22" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_a22 PARTITION OF trunc_a2 FOR VALUES FROM (12) TO (16)" +== 178 +-- truncate_limit: 100 +CREATE TABLE trunc_a2d PARTITION OF trunc_a2 DEFAULT +-- +TABLE: name="trunc_a2d" schema="" table="trunc_a2d" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_a2d PARTITION OF trunc_a2 DEFAULT" +== 179 +-- truncate_limit: 100 +CREATE TABLE trunc_a3 PARTITION OF trunc_a FOR VALUES FROM (20) TO (30) +-- +TABLE: name="trunc_a3" schema="" table="trunc_a3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE trunc_a3 PARTITION OF trunc_a FOR VALUES FROM (20) TO (30)" +== 180 +-- truncate_limit: 100 +INSERT INTO trunc_a VALUES (0), (5), (10), (15), (20), (25) +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO trunc_a VALUES (0), (5), (10), (15), (20), (25)" +== 181 +-- truncate_limit: 100 +-- truncate a partition cascading to a table +CREATE TABLE ref_b ( + b INT PRIMARY KEY, + a INT REFERENCES trunc_a(a) ON DELETE CASCADE +) +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref_b (b int PRIMARY KEY, a int REFERENCES trunc_a (a) ON DELETE CASCADE)" +== 182 +-- truncate_limit: 100 +INSERT INTO ref_b VALUES (10, 0), (50, 5), (100, 10), (150, 15) +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ref_b VALUES (10, 0), (50, 5), (100, 10), (150, 15)" +== 183 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_a1 CASCADE +-- +TABLE: name="trunc_a1" schema="" table="trunc_a1" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_a1 CASCADE" +== 184 +-- truncate_limit: 100 +SELECT a FROM ref_b +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a FROM ref_b" +== 185 +-- truncate_limit: 100 +DROP TABLE ref_b +-- +TABLE: name="ref_b" schema="" table="ref_b" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE ref_b" +== 186 +-- truncate_limit: 100 +-- truncate a partition cascading to a partitioned table +CREATE TABLE ref_c ( + c INT PRIMARY KEY, + a INT REFERENCES trunc_a(a) ON DELETE CASCADE +) PARTITION BY RANGE (c) +-- +TABLE: name="ref_c" schema="" table="ref_c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref_c (c int PRIMARY KEY, a int REFERENCES trunc_a (a) ON DELETE CASCADE) PARTITION ..." +== 187 +-- truncate_limit: 100 +CREATE TABLE ref_c1 PARTITION OF ref_c FOR VALUES FROM (100) TO (200) +-- +TABLE: name="ref_c1" schema="" table="ref_c1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref_c1 PARTITION OF ref_c FOR VALUES FROM (100) TO (200)" +== 188 +-- truncate_limit: 100 +CREATE TABLE ref_c2 PARTITION OF ref_c FOR VALUES FROM (200) TO (300) +-- +TABLE: name="ref_c2" schema="" table="ref_c2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref_c2 PARTITION OF ref_c FOR VALUES FROM (200) TO (300)" +== 189 +-- truncate_limit: 100 +INSERT INTO ref_c VALUES (100, 10), (150, 15), (200, 20), (250, 25) +-- +TABLE: name="ref_c" schema="" table="ref_c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ref_c VALUES (100, 10), (150, 15), (200, 20), (250, 25)" +== 190 +-- truncate_limit: 100 +TRUNCATE TABLE trunc_a21 CASCADE +-- +TABLE: name="trunc_a21" schema="" table="trunc_a21" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE trunc_a21 CASCADE" +== 191 +-- truncate_limit: 100 +SELECT a as "from table ref_c" FROM ref_c +-- +TABLE: name="ref_c" schema="" table="ref_c" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a AS \"from table ref_c\" FROM ref_c" +== 192 +-- truncate_limit: 100 +SELECT a as "from table trunc_a" FROM trunc_a ORDER BY a +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a AS \"from table trunc_a\" FROM trunc_a ORDER BY a" +== 193 +-- truncate_limit: 100 +DROP TABLE trunc_a, ref_c +-- +TABLE: name="trunc_a" schema="" table="trunc_a" ctx=DDL +TABLE: name="ref_c" schema="" table="ref_c" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE trunc_a, ref_c" diff --git a/parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json new file mode 100644 index 0000000..507be8d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json @@ -0,0 +1,135 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tsdicts.test b/parser/testdata/summary_truncate/postgres_regress/tsdicts.test new file mode 100644 index 0000000..bf6e34d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tsdicts.test @@ -0,0 +1,994 @@ +== 001 +-- truncate_limit: 100 +--Test text search dictionaries and configurations + +-- Test ISpell dictionary with ispell affix file +CREATE TEXT SEARCH DICTIONARY ispell ( + Template=ispell, + DictFile=ispell_sample, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY ispell (template = ispell, dictfile = ispell_sample, afffile = ispe..." +== 002 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'skies')" +== 003 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'bookings')" +== 004 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'booking')" +== 005 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'foot')" +== 006 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'foots')" +== 007 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'rebookings')" +== 008 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'rebooking')" +== 009 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'rebook')" +== 010 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'unbookings')" +== 011 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'unbooking')" +== 012 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'unbook')" +== 013 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'footklubber')" +== 014 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'footballklubber')" +== 015 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'ballyklubber')" +== 016 +-- truncate_limit: 100 +SELECT ts_lexize('ispell', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('ispell', 'footballyklubber')" +== 017 +-- truncate_limit: 100 +-- Test ISpell dictionary with hunspell affix file +CREATE TEXT SEARCH DICTIONARY hunspell ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell (template = ispell, dictfile = ispell_sample, afffile = hu..." +== 018 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'skies')" +== 019 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'bookings')" +== 020 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'booking')" +== 021 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'foot')" +== 022 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'foots')" +== 023 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'rebookings')" +== 024 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'rebooking')" +== 025 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'rebook')" +== 026 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'unbookings')" +== 027 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'unbooking')" +== 028 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'unbook')" +== 029 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'footklubber')" +== 030 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'footballklubber')" +== 031 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'ballyklubber')" +== 032 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell', 'footballyklubber')" +== 033 +-- truncate_limit: 100 +-- Test ISpell dictionary with hunspell affix file with FLAG long parameter +CREATE TEXT SEARCH DICTIONARY hunspell_long ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=hunspell_sample_long +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_long (template = ispell, dictfile = hunspell_sample_long, ..." +== 034 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'skies')" +== 035 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'bookings')" +== 036 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'booking')" +== 037 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'foot')" +== 038 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'foots')" +== 039 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'rebookings')" +== 040 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'rebooking')" +== 041 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'rebook')" +== 042 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'unbookings')" +== 043 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'unbooking')" +== 044 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'unbook')" +== 045 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'booked') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'booked')" +== 046 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'footklubber')" +== 047 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'footballklubber')" +== 048 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'ballyklubber')" +== 049 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'ballsklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'ballsklubber')" +== 050 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'footballyklubber')" +== 051 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_long', 'ex-machina') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_long', 'ex-machina')" +== 052 +-- truncate_limit: 100 +-- Test ISpell dictionary with hunspell affix file with FLAG num parameter +CREATE TEXT SEARCH DICTIONARY hunspell_num ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=hunspell_sample_num +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_num (template = ispell, dictfile = hunspell_sample_num, af..." +== 053 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'skies')" +== 054 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'sk') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'sk')" +== 055 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'bookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'bookings')" +== 056 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'booking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'booking')" +== 057 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'foot') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'foot')" +== 058 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'foots') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'foots')" +== 059 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'rebookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'rebookings')" +== 060 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'rebooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'rebooking')" +== 061 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'rebook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'rebook')" +== 062 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'unbookings') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'unbookings')" +== 063 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'unbooking') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'unbooking')" +== 064 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'unbook') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'unbook')" +== 065 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'booked') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'booked')" +== 066 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'footklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'footklubber')" +== 067 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'footballklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'footballklubber')" +== 068 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'ballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'ballyklubber')" +== 069 +-- truncate_limit: 100 +SELECT ts_lexize('hunspell_num', 'footballyklubber') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('hunspell_num', 'footballyklubber')" +== 070 +-- truncate_limit: 100 +-- Test suitability of affix and dict files +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample_long +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_err (template = ispell, dictfile = ispell_sample, afffile ..." +== 071 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample_num +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_err (template = ispell, dictfile = ispell_sample, afffile ..." +== 072 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 (template = ispell, dictfile = hunspell_sample_l..." +== 073 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=hunspell_sample_num +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 (template = ispell, dictfile = hunspell_sample_l..." +== 074 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=ispell_sample +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 (template = ispell, dictfile = hunspell_sample_n..." +== 075 +-- truncate_limit: 100 +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=hunspell_sample_long +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY hunspell_err (template = ispell, dictfile = hunspell_sample_num, af..." +== 076 +-- truncate_limit: 100 +-- Synonym dictionary +CREATE TEXT SEARCH DICTIONARY synonym ( + Template=synonym, + Synonyms=synonym_sample +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY synonym (template = synonym, synonyms = synonym_sample)" +== 077 +-- truncate_limit: 100 +SELECT ts_lexize('synonym', 'PoStGrEs') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('synonym', 'PoStGrEs')" +== 078 +-- truncate_limit: 100 +SELECT ts_lexize('synonym', 'Gogle') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('synonym', 'Gogle')" +== 079 +-- truncate_limit: 100 +SELECT ts_lexize('synonym', 'indices') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('synonym', 'indices')" +== 080 +-- truncate_limit: 100 +-- test altering boolean parameters +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym' +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictname" +STMT: SelectStmt +TRUNCATED: "SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym'" +== 081 +-- truncate_limit: 100 +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = 1) +-- +STMT: AlterTSDictionaryStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY synonym (casesensitive = 1)" +== 082 +-- truncate_limit: 100 +SELECT ts_lexize('synonym', 'PoStGrEs') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('synonym', 'PoStGrEs')" +== 083 +-- truncate_limit: 100 +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym' +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictname" +STMT: SelectStmt +TRUNCATED: "SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym'" +== 084 +-- truncate_limit: 100 +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = 2) +-- +STMT: AlterTSDictionaryStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY synonym (casesensitive = 2)" +== 085 +-- truncate_limit: 100 +-- fail + +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = off) +-- +STMT: AlterTSDictionaryStmt +TRUNCATED: "ALTER TEXT SEARCH DICTIONARY synonym (casesensitive = off)" +== 086 +-- truncate_limit: 100 +SELECT ts_lexize('synonym', 'PoStGrEs') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('synonym', 'PoStGrEs')" +== 087 +-- truncate_limit: 100 +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym' +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictname" +STMT: SelectStmt +TRUNCATED: "SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym'" +== 088 +-- truncate_limit: 100 +-- Create and simple test thesaurus dictionary +-- More tests in configuration checks because ts_lexize() +-- cannot pass more than one word to thesaurus. +CREATE TEXT SEARCH DICTIONARY thesaurus ( + Template=thesaurus, + DictFile=thesaurus_sample, + Dictionary=english_stem +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY thesaurus (template = thesaurus, dictfile = thesaurus_sample, dicti..." +== 089 +-- truncate_limit: 100 +SELECT ts_lexize('thesaurus', 'one') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('thesaurus', 'one')" +== 090 +-- truncate_limit: 100 +-- Test ispell dictionary in configuration +CREATE TEXT SEARCH CONFIGURATION ispell_tst ( + COPY=english +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION ispell_tst (copy = english)" +== 091 +-- truncate_limit: 100 +ALTER TEXT SEARCH CONFIGURATION ispell_tst ALTER MAPPING FOR + word, numword, asciiword, hword, numhword, asciihword, hword_part, hword_numpart, hword_asciipart + WITH ispell, english_stem +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION ispell_tst ALTER MAPPING FOR word, numword, asciiword, hword, num..." +== 092 +-- truncate_limit: 100 +SELECT to_tsvector('ispell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 093 +-- truncate_limit: 100 +SELECT to_tsquery('ispell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('ispell_tst', 'footballklubber')" +== 094 +-- truncate_limit: 100 +SELECT to_tsquery('ispell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('ispell_tst', 'footballyklubber:b & rebookings:A & sky')" +== 095 +-- truncate_limit: 100 +-- Test ispell dictionary with hunspell affix in configuration +CREATE TEXT SEARCH CONFIGURATION hunspell_tst ( + COPY=ispell_tst +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION hunspell_tst (copy = ispell_tst)" +== 096 +-- truncate_limit: 100 +ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING + REPLACE ispell WITH hunspell +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING REPLACE ispell WITH hunspell" +== 097 +-- truncate_limit: 100 +SELECT to_tsvector('hunspell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 098 +-- truncate_limit: 100 +SELECT to_tsquery('hunspell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('hunspell_tst', 'footballklubber')" +== 099 +-- truncate_limit: 100 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky')" +== 100 +-- truncate_limit: 100 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b <-> sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('hunspell_tst', 'footballyklubber:b <-> sky')" +== 101 +-- truncate_limit: 100 +SELECT phraseto_tsquery('hunspell_tst', 'footballyklubber sky') +-- +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT phraseto_tsquery('hunspell_tst', 'footballyklubber sky')" +== 102 +-- truncate_limit: 100 +-- Test ispell dictionary with hunspell affix with FLAG long in configuration +ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING + REPLACE hunspell WITH hunspell_long +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING REPLACE hunspell WITH hunspell_long" +== 103 +-- truncate_limit: 100 +SELECT to_tsvector('hunspell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 104 +-- truncate_limit: 100 +SELECT to_tsquery('hunspell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('hunspell_tst', 'footballklubber')" +== 105 +-- truncate_limit: 100 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky')" +== 106 +-- truncate_limit: 100 +-- Test ispell dictionary with hunspell affix with FLAG num in configuration +ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING + REPLACE hunspell_long WITH hunspell_num +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION hunspell_tst ALTER MAPPING REPLACE hunspell_long WITH hunspell_num" +== 107 +-- truncate_limit: 100 +SELECT to_tsvector('hunspell_tst', 'Booking the skies after rebookings for footballklubber from a foot') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 108 +-- truncate_limit: 100 +SELECT to_tsquery('hunspell_tst', 'footballklubber') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('hunspell_tst', 'footballklubber')" +== 109 +-- truncate_limit: 100 +SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('hunspell_tst', 'footballyklubber:b & rebookings:A & sky')" +== 110 +-- truncate_limit: 100 +-- Test synonym dictionary in configuration +CREATE TEXT SEARCH CONFIGURATION synonym_tst ( + COPY=english +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION synonym_tst (copy = english)" +== 111 +-- truncate_limit: 100 +ALTER TEXT SEARCH CONFIGURATION synonym_tst ALTER MAPPING FOR + asciiword, hword_asciipart, asciihword + WITH synonym, english_stem +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION synonym_tst ALTER MAPPING FOR asciiword, hword_asciipart, asciihw..." +== 112 +-- truncate_limit: 100 +SELECT to_tsvector('synonym_tst', 'Postgresql is often called as postgres or pgsql and pronounced as postgre') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 113 +-- truncate_limit: 100 +SELECT to_tsvector('synonym_tst', 'Most common mistake is to write Gogle instead of Google') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('synonym_tst', 'Most common mistake is to write Gogle instead of Google')" +== 114 +-- truncate_limit: 100 +SELECT to_tsvector('synonym_tst', 'Indexes or indices - Which is right plural form of index?') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('synonym_tst', 'Indexes or indices - Which is right plural form of index?')" +== 115 +-- truncate_limit: 100 +SELECT to_tsquery('synonym_tst', 'Index & indices') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('synonym_tst', 'Index & indices')" +== 116 +-- truncate_limit: 100 +-- test thesaurus in configuration +-- see thesaurus_sample.ths to understand 'odd' resulting tsvector +CREATE TEXT SEARCH CONFIGURATION thesaurus_tst ( + COPY=synonym_tst +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION thesaurus_tst (copy = synonym_tst)" +== 117 +-- truncate_limit: 100 +ALTER TEXT SEARCH CONFIGURATION thesaurus_tst ALTER MAPPING FOR + asciiword, hword_asciipart, asciihword + WITH synonym, thesaurus, english_stem +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION thesaurus_tst ALTER MAPPING FOR asciiword, hword_asciipart, ascii..." +== 118 +-- truncate_limit: 100 +SELECT to_tsvector('thesaurus_tst', 'one postgres one two one two three one') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('thesaurus_tst', 'one postgres one two one two three one')" +== 119 +-- truncate_limit: 100 +SELECT to_tsvector('thesaurus_tst', 'Supernovae star is very new star and usually called supernovae (abbreviation SN)') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 120 +-- truncate_limit: 100 +SELECT to_tsvector('thesaurus_tst', 'Booking tickets is looking like a booking a tickets') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('thesaurus_tst', 'Booking tickets is looking like a booking a tickets')" +== 121 +-- truncate_limit: 100 +-- invalid: non-lowercase quoted identifiers +CREATE TEXT SEARCH DICTIONARY tsdict_case +( + Template = ispell, + "DictFile" = ispell_sample, + "AffFile" = ispell_sample +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH DICTIONARY tsdict_case (template = ispell, \"DictFile\" = ispell_sample, \"AffFil..." +== 122 +-- truncate_limit: 100 +-- Test grammar for configurations +CREATE TEXT SEARCH CONFIGURATION dummy_tst (COPY=english) +-- +STMT: DefineStmt +TRUNCATED: "CREATE TEXT SEARCH CONFIGURATION dummy_tst (copy = english)" +== 123 +-- truncate_limit: 100 +-- Overridden mapping change with duplicated tokens. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + ALTER MAPPING FOR word, word WITH ispell +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst ALTER MAPPING FOR word, word WITH ispell" +== 124 +-- truncate_limit: 100 +-- Not a token supported by the configuration's parser, fails. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING FOR not_a_token, not_a_token +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst DROP MAPPING FOR not_a_token, not_a_token" +== 125 +-- truncate_limit: 100 +-- Not a token supported by the configuration's parser, fails even +-- with IF EXISTS. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING IF EXISTS FOR not_a_token, not_a_token +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst DROP MAPPING IF EXISTS FOR not_a_token, not_a_token" +== 126 +-- truncate_limit: 100 +-- Token supported by the configuration's parser, succeeds. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING FOR word, word +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst DROP MAPPING FOR word, word" +== 127 +-- truncate_limit: 100 +-- No mapping for token supported by the configuration's parser, fails. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING FOR word +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst DROP MAPPING FOR word" +== 128 +-- truncate_limit: 100 +-- Token supported by the configuration's parser, cannot be found, +-- succeeds with IF EXISTS. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + DROP MAPPING IF EXISTS FOR word, word +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst DROP MAPPING IF EXISTS FOR word, word" +== 129 +-- truncate_limit: 100 +-- Re-add mapping, with duplicated tokens supported by the parser. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + ADD MAPPING FOR word, word WITH ispell +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst ADD MAPPING FOR word, word WITH ispell" +== 130 +-- truncate_limit: 100 +-- Not a token supported by the configuration's parser, fails. +ALTER TEXT SEARCH CONFIGURATION dummy_tst + ADD MAPPING FOR not_a_token WITH ispell +-- +STMT: AlterTSConfigurationStmt +TRUNCATED: "ALTER TEXT SEARCH CONFIGURATION dummy_tst ADD MAPPING FOR not_a_token WITH ispell" +== 131 +-- truncate_limit: 100 +DROP TEXT SEARCH CONFIGURATION dummy_tst +-- +STMT: DropStmt +TRUNCATED: "DROP TEXT SEARCH CONFIGURATION dummy_tst" diff --git a/parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json new file mode 100644 index 0000000..16d1dd4 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json @@ -0,0 +1,446 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tsearch.test b/parser/testdata/summary_truncate/postgres_regress/tsearch.test new file mode 100644 index 0000000..579990c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tsearch.test @@ -0,0 +1,3874 @@ +== 001 +-- truncate_limit: 100 +-- directory paths are passed to us in environment variables + +|-- +-- Sanity checks for text search catalogs +|-- +-- NB: we assume the oidjoins test will have caught any dangling links, +-- that is OID or REGPROC fields that are not zero and do not match some +-- row in the linked-to table. However, if we want to enforce that a link +-- field can't be 0, we have to check it here. + +-- Find unexpected zero link entries + +SELECT oid, prsname +FROM pg_ts_parser +WHERE prsnamespace = 0 OR prsstart = 0 OR prstoken = 0 OR prsend = 0 OR + -- prsheadline is optional + prslextype = 0 +-- +TABLE: name="pg_ts_parser" schema="" table="pg_ts_parser" ctx=Select +FILTER: schema="" table="" column="prsnamespace" +FILTER: schema="" table="" column="prsstart" +FILTER: schema="" table="" column="prstoken" +FILTER: schema="" table="" column="prsend" +FILTER: schema="" table="" column="prslextype" +STMT: SelectStmt +TRUNCATED: "SELECT oid, prsname FROM pg_ts_parser WHERE ..." +== 002 +-- truncate_limit: 100 +SELECT oid, dictname +FROM pg_ts_dict +WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0 +-- +TABLE: name="pg_ts_dict" schema="" table="pg_ts_dict" ctx=Select +FILTER: schema="" table="" column="dictnamespace" +FILTER: schema="" table="" column="dictowner" +FILTER: schema="" table="" column="dicttemplate" +STMT: SelectStmt +TRUNCATED: "SELECT oid, dictname FROM pg_ts_dict WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0" +== 003 +-- truncate_limit: 100 +SELECT oid, tmplname +FROM pg_ts_template +WHERE tmplnamespace = 0 OR tmpllexize = 0 +-- +TABLE: name="pg_ts_template" schema="" table="pg_ts_template" ctx=Select +FILTER: schema="" table="" column="tmplnamespace" +FILTER: schema="" table="" column="tmpllexize" +STMT: SelectStmt +TRUNCATED: "SELECT oid, tmplname FROM pg_ts_template WHERE tmplnamespace = 0 OR tmpllexize = 0" +== 004 +-- truncate_limit: 100 +-- tmplinit is optional + +SELECT oid, cfgname +FROM pg_ts_config +WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0 +-- +TABLE: name="pg_ts_config" schema="" table="pg_ts_config" ctx=Select +FILTER: schema="" table="" column="cfgnamespace" +FILTER: schema="" table="" column="cfgowner" +FILTER: schema="" table="" column="cfgparser" +STMT: SelectStmt +TRUNCATED: "SELECT oid, cfgname FROM pg_ts_config WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0" +== 005 +-- truncate_limit: 100 +SELECT mapcfg, maptokentype, mapseqno +FROM pg_ts_config_map +WHERE mapcfg = 0 OR mapdict = 0 +-- +TABLE: name="pg_ts_config_map" schema="" table="pg_ts_config_map" ctx=Select +FILTER: schema="" table="" column="mapcfg" +FILTER: schema="" table="" column="mapdict" +STMT: SelectStmt +TRUNCATED: "SELECT mapcfg, maptokentype, mapseqno FROM pg_ts_config_map WHERE mapcfg = 0 OR mapdict = 0" +== 006 +-- truncate_limit: 100 +-- Look for pg_ts_config_map entries that aren't one of parser's token types +SELECT * FROM + ( SELECT oid AS cfgid, (ts_token_type(cfgparser)).tokid AS tokid + FROM pg_ts_config ) AS tt +RIGHT JOIN pg_ts_config_map AS m + ON (tt.cfgid=m.mapcfg AND tt.tokid=m.maptokentype) +WHERE + tt.cfgid IS NULL OR tt.tokid IS NULL +-- +TABLE: name="pg_ts_config_map" schema="" table="pg_ts_config_map" ctx=Select +TABLE: name="pg_ts_config" schema="" table="pg_ts_config" ctx=Select +ALIAS: "m"="pg_ts_config_map" +FUNCTION: name="ts_token_type" function="ts_token_type" schema="" ctx=Call +FILTER: schema="" table="tt" column="cfgid" +FILTER: schema="" table="tt" column="tokid" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM pg_ts_config) tt RIGHT JOIN pg_ts_config_map m ON tt.cfgid = m.map..." +== 007 +-- truncate_limit: 100 +-- Load some test data +CREATE TABLE test_tsvector( + t text, + a tsvector +) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tsvector (t text, a tsvector)" +== 008 +-- truncate_limit: 100 +COPY test_tsvector FROM :'filename' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 25 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 009 +-- truncate_limit: 100 +ANALYZE test_tsvector +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE test_tsvector" +== 010 +-- truncate_limit: 100 +-- test basic text search behavior without indexes, then with + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 011 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'" +== 012 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'" +== 013 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'" +== 014 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'" +== 015 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'" +== 016 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'" +== 017 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ ANY('{wr,qh}')" +== 018 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'" +== 019 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'" +== 020 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'" +== 021 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'" +== 022 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'" +== 023 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'" +== 024 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'" +== 025 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'" +== 026 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'" +== 027 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'" +== 028 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'" +== 029 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'" +== 030 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'" +== 031 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'" +== 032 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'" +== 033 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'" +== 034 +-- truncate_limit: 100 +create index wowidx on test_tsvector using gist (a) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx ON test_tsvector USING gist (a)" +== 035 +-- truncate_limit: 100 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 036 +-- truncate_limit: 100 +SET enable_indexscan=ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 037 +-- truncate_limit: 100 +SET enable_bitmapscan=OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 038 +-- truncate_limit: 100 +explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 039 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 040 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'" +== 041 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'" +== 042 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'" +== 043 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'" +== 044 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'" +== 045 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'" +== 046 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ ANY('{wr,qh}')" +== 047 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'" +== 048 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'" +== 049 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'" +== 050 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'" +== 051 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'" +== 052 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'" +== 053 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'" +== 054 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'" +== 055 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'" +== 056 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'" +== 057 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'" +== 058 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'" +== 059 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'" +== 060 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'" +== 061 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'" +== 062 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'" +== 063 +-- truncate_limit: 100 +SET enable_indexscan=OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO OFF" +== 064 +-- truncate_limit: 100 +SET enable_bitmapscan=ON +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO ON" +== 065 +-- truncate_limit: 100 +explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 066 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 067 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'" +== 068 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'" +== 069 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'" +== 070 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'" +== 071 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'" +== 072 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'" +== 073 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ ANY('{wr,qh}')" +== 074 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'" +== 075 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'" +== 076 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'" +== 077 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'" +== 078 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'" +== 079 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'" +== 080 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'" +== 081 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'" +== 082 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'" +== 083 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'" +== 084 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'" +== 085 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'" +== 086 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'" +== 087 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'" +== 088 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'" +== 089 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'" +== 090 +-- truncate_limit: 100 +-- Test siglen parameter of GiST tsvector_ops +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(foo=1)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(foo=1))" +== 091 +-- truncate_limit: 100 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=0)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=0))" +== 092 +-- truncate_limit: 100 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=2048)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=2048))" +== 093 +-- truncate_limit: 100 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100,foo='bar')) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100, foo='bar'))" +== 094 +-- truncate_limit: 100 +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100, siglen = 200)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100, siglen=200))" +== 095 +-- truncate_limit: 100 +CREATE INDEX wowidx2 ON test_tsvector USING gist (a tsvector_ops(siglen=1)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx2 ON test_tsvector USING gist (a tsvector_ops(siglen=1))" +== 096 +-- truncate_limit: 100 +DROP INDEX wowidx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX wowidx" +== 097 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 098 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 099 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'" +== 100 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'" +== 101 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'" +== 102 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'" +== 103 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'" +== 104 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'" +== 105 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ ANY('{wr,qh}')" +== 106 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'" +== 107 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'" +== 108 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'" +== 109 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'" +== 110 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'" +== 111 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'" +== 112 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'" +== 113 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'" +== 114 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'" +== 115 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'" +== 116 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'" +== 117 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'" +== 118 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'" +== 119 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'" +== 120 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'" +== 121 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'" +== 122 +-- truncate_limit: 100 +DROP INDEX wowidx2 +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX wowidx2" +== 123 +-- truncate_limit: 100 +CREATE INDEX wowidx ON test_tsvector USING gist (a tsvector_ops(siglen=484)) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx ON test_tsvector USING gist (a tsvector_ops(siglen=484))" +== 124 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 125 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 126 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'" +== 127 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'" +== 128 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'" +== 129 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'" +== 130 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'" +== 131 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'" +== 132 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ ANY('{wr,qh}')" +== 133 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'" +== 134 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'" +== 135 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'" +== 136 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'" +== 137 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'" +== 138 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'" +== 139 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'" +== 140 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'" +== 141 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'" +== 142 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'" +== 143 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'" +== 144 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'" +== 145 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'" +== 146 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'" +== 147 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'" +== 148 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'" +== 149 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 150 +-- truncate_limit: 100 +RESET enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 151 +-- truncate_limit: 100 +RESET enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 152 +-- truncate_limit: 100 +DROP INDEX wowidx +-- +STMT: DropStmt +TRUNCATED: "DROP INDEX wowidx" +== 153 +-- truncate_limit: 100 +CREATE INDEX wowidx ON test_tsvector USING gin (a) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX wowidx ON test_tsvector USING gin (a)" +== 154 +-- truncate_limit: 100 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 155 +-- truncate_limit: 100 +-- GIN only supports bitmapscan, so no need to test plain indexscan + +explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 156 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'" +== 157 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'" +== 158 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'" +== 159 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'" +== 160 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'" +== 161 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'" +== 162 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'" +== 163 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ ANY('{wr,qh}')" +== 164 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'" +== 165 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'" +== 166 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'" +== 167 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'" +== 168 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'" +== 169 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'" +== 170 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'" +== 171 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'" +== 172 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'" +== 173 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'" +== 174 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'" +== 175 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'" +== 176 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'" +== 177 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'" +== 178 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'" +== 179 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'" +== 180 +-- truncate_limit: 100 +-- Test optimization of non-empty GIN_SEARCH_MODE_ALL queries +EXPLAIN (COSTS OFF) +SELECT count(*) FROM test_tsvector WHERE a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_tsvector WHERE a @@ '!qh'" +== 181 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ '!qh'" +== 182 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh'" +== 183 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh'" +== 184 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 185 +-- truncate_limit: 100 +INSERT INTO test_tsvector VALUES ('???', 'DFG:1A,2B,6C,10 FGH') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_tsvector VALUES ('???', 'DFG:1A,2B,6C,10 FGH')" +== 186 +-- truncate_limit: 100 +SELECT * FROM ts_stat('SELECT a FROM test_tsvector') ORDER BY ndoc DESC, nentry DESC, word LIMIT 10 +-- +FUNCTION: name="ts_stat" function="ts_stat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_stat('SELECT a FROM test_tsvector') ORDER BY ndoc DESC, nentry DESC, word LIMIT 10" +== 187 +-- truncate_limit: 100 +SELECT * FROM ts_stat('SELECT a FROM test_tsvector', 'AB') ORDER BY ndoc DESC, nentry DESC, word +-- +FUNCTION: name="ts_stat" function="ts_stat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_stat('SELECT a FROM test_tsvector', 'AB') ORDER BY ndoc DESC, nentry DESC, word" +== 188 +-- truncate_limit: 100 +--dictionaries and to_tsvector + +SELECT ts_lexize('english_stem', 'skies') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('english_stem', 'skies')" +== 189 +-- truncate_limit: 100 +SELECT ts_lexize('english_stem', 'identity') +-- +FUNCTION: name="ts_lexize" function="ts_lexize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_lexize('english_stem', 'identity')" +== 190 +-- truncate_limit: 100 +SELECT * FROM ts_token_type('default') +-- +FUNCTION: name="ts_token_type" function="ts_token_type" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_token_type('default')" +== 191 +-- truncate_limit: 100 +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') +-- +FUNCTION: name="ts_parse" function="ts_parse" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&d..." +== 192 +-- truncate_limit: 100 +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') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 193 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 194 +-- truncate_limit: 100 +-- ts_debug + +SELECT * from ts_debug('english', 'abc&nm1;def©ghiõjkl') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_debug('english', 'abc&nm1;def©ghiõjkl') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_debug('english', 'http://www.harewoodsolutions.co.uk/press.aspx')" +== 196 +-- truncate_limit: 100 +SELECT * from ts_debug('english', 'http://aew.wer0c.ewr/id?ad=qwe&dw') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_debug('english', 'http://aew.wer0c.ewr/id?ad=qwe&dw')" +== 197 +-- truncate_limit: 100 +SELECT * from ts_debug('english', 'http://5aew.werc.ewr:8100/?') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_debug('english', 'http://5aew.werc.ewr:8100/?')" +== 198 +-- truncate_limit: 100 +SELECT * from ts_debug('english', '5aew.werc.ewr:8100/?xx') +-- +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ts_debug('english', '5aew.werc.ewr:8100/?xx')" +== 199 +-- truncate_limit: 100 +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') +-- +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="array_dims" function="array_dims" schema="" ctx=Call +FUNCTION: name="ts_debug" function="ts_debug" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM ts_debug('english', 'a title')" +== 200 +-- truncate_limit: 100 +-- to_tsquery + +SELECT to_tsquery('english', 'qwe & sKies ') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 'qwe & sKies ')" +== 201 +-- truncate_limit: 100 +SELECT to_tsquery('simple', 'qwe & sKies ') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('simple', 'qwe & sKies ')" +== 202 +-- truncate_limit: 100 +SELECT to_tsquery('english', '''the wether'':dc & '' sKies '':BC ') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '''the wether'':dc & '' sKies '':BC ')" +== 203 +-- truncate_limit: 100 +SELECT to_tsquery('english', 'asd&(and|fghj)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 'asd&(and|fghj)')" +== 204 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(asd&and)|fghj') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(asd&and)|fghj')" +== 205 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(asd&!and)|fghj') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(asd&!and)|fghj')" +== 206 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(the|and&(i&1))&fghj') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(the|and&(i&1))&fghj')" +== 207 +-- truncate_limit: 100 +SELECT plainto_tsquery('english', 'the and z 1))& fghj') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT plainto_tsquery('english', 'the and z 1))& fghj')" +== 208 +-- truncate_limit: 100 +SELECT plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd')" +== 209 +-- truncate_limit: 100 +SELECT plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg')" +== 210 +-- truncate_limit: 100 +SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT plainto_tsquery('english', 'foo bar') || (!! plainto_tsquery('english', 'asd fg'))" +== 211 +-- truncate_limit: 100 +SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg' +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg'" +== 212 +-- truncate_limit: 100 +-- Check stop word deletion, a and s are stop-words +SELECT to_tsquery('english', '!(a & !b) & c') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '!(a & !b) & c')" +== 213 +-- truncate_limit: 100 +SELECT to_tsquery('english', '!(a & !b)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '!(a & !b)')" +== 214 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(1 <-> 2) <-> a') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(1 <-> 2) <-> a')" +== 215 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(1 <-> a) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(1 <-> a) <-> 2')" +== 216 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(a <-> 1) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(a <-> 1) <-> 2')" +== 217 +-- truncate_limit: 100 +SELECT to_tsquery('english', 'a <-> (1 <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 'a <-> (1 <-> 2)')" +== 218 +-- truncate_limit: 100 +SELECT to_tsquery('english', '1 <-> (a <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '1 <-> (a <-> 2)')" +== 219 +-- truncate_limit: 100 +SELECT to_tsquery('english', '1 <-> (2 <-> a)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '1 <-> (2 <-> a)')" +== 220 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(1 <-> 2) <3> a') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(1 <-> 2) <3> a')" +== 221 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(1 <-> a) <3> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(1 <-> a) <3> 2')" +== 222 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(a <-> 1) <3> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(a <-> 1) <3> 2')" +== 223 +-- truncate_limit: 100 +SELECT to_tsquery('english', 'a <3> (1 <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 'a <3> (1 <-> 2)')" +== 224 +-- truncate_limit: 100 +SELECT to_tsquery('english', '1 <3> (a <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '1 <3> (a <-> 2)')" +== 225 +-- truncate_limit: 100 +SELECT to_tsquery('english', '1 <3> (2 <-> a)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '1 <3> (2 <-> a)')" +== 226 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(1 <3> 2) <-> a') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(1 <3> 2) <-> a')" +== 227 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(1 <3> a) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(1 <3> a) <-> 2')" +== 228 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(a <3> 1) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(a <3> 1) <-> 2')" +== 229 +-- truncate_limit: 100 +SELECT to_tsquery('english', 'a <-> (1 <3> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 'a <-> (1 <3> 2)')" +== 230 +-- truncate_limit: 100 +SELECT to_tsquery('english', '1 <-> (a <3> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '1 <-> (a <3> 2)')" +== 231 +-- truncate_limit: 100 +SELECT to_tsquery('english', '1 <-> (2 <3> a)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '1 <-> (2 <3> a)')" +== 232 +-- truncate_limit: 100 +SELECT to_tsquery('english', '((a <-> 1) <-> 2) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '((a <-> 1) <-> 2) <-> s')" +== 233 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(2 <-> (a <-> 1)) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(2 <-> (a <-> 1)) <-> s')" +== 234 +-- truncate_limit: 100 +SELECT to_tsquery('english', '((1 <-> a) <-> 2) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '((1 <-> a) <-> 2) <-> s')" +== 235 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(2 <-> (1 <-> a)) <-> s') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(2 <-> (1 <-> a)) <-> s')" +== 236 +-- truncate_limit: 100 +SELECT to_tsquery('english', 's <-> ((a <-> 1) <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 's <-> ((a <-> 1) <-> 2)')" +== 237 +-- truncate_limit: 100 +SELECT to_tsquery('english', 's <-> (2 <-> (a <-> 1))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 's <-> (2 <-> (a <-> 1))')" +== 238 +-- truncate_limit: 100 +SELECT to_tsquery('english', 's <-> ((1 <-> a) <-> 2)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 's <-> ((1 <-> a) <-> 2)')" +== 239 +-- truncate_limit: 100 +SELECT to_tsquery('english', 's <-> (2 <-> (1 <-> a))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 's <-> (2 <-> (1 <-> a))')" +== 240 +-- truncate_limit: 100 +SELECT to_tsquery('english', '((a <-> 1) <-> s) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '((a <-> 1) <-> s) <-> 2')" +== 241 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(s <-> (a <-> 1)) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(s <-> (a <-> 1)) <-> 2')" +== 242 +-- truncate_limit: 100 +SELECT to_tsquery('english', '((1 <-> a) <-> s) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '((1 <-> a) <-> s) <-> 2')" +== 243 +-- truncate_limit: 100 +SELECT to_tsquery('english', '(s <-> (1 <-> a)) <-> 2') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '(s <-> (1 <-> a)) <-> 2')" +== 244 +-- truncate_limit: 100 +SELECT to_tsquery('english', '2 <-> ((a <-> 1) <-> s)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '2 <-> ((a <-> 1) <-> s)')" +== 245 +-- truncate_limit: 100 +SELECT to_tsquery('english', '2 <-> (s <-> (a <-> 1))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '2 <-> (s <-> (a <-> 1))')" +== 246 +-- truncate_limit: 100 +SELECT to_tsquery('english', '2 <-> ((1 <-> a) <-> s)') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '2 <-> ((1 <-> a) <-> s)')" +== 247 +-- truncate_limit: 100 +SELECT to_tsquery('english', '2 <-> (s <-> (1 <-> a))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '2 <-> (s <-> (1 <-> a))')" +== 248 +-- truncate_limit: 100 +SELECT to_tsquery('english', 'foo <-> (a <-> (the <-> bar))') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 'foo <-> (a <-> (the <-> bar))')" +== 249 +-- truncate_limit: 100 +SELECT to_tsquery('english', '((foo <-> a) <-> the) <-> bar') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', '((foo <-> a) <-> the) <-> bar')" +== 250 +-- truncate_limit: 100 +SELECT to_tsquery('english', 'foo <-> a <-> the <-> bar') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('english', 'foo <-> a <-> the <-> bar')" +== 251 +-- truncate_limit: 100 +SELECT phraseto_tsquery('english', 'PostgreSQL can be extended by the user in many ways') +-- +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT phraseto_tsquery('english', 'PostgreSQL can be extended by the user in many ways')" +== 252 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 253 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 254 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 255 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 256 +-- truncate_limit: 100 +SELECT ts_rank_cd(strip(to_tsvector('both stripped')), + to_tsquery('both & stripped')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(strip(to_tsvector('both stripped')), to_tsquery('both & stripped'))" +== 257 +-- truncate_limit: 100 +SELECT ts_rank_cd(to_tsvector('unstripped') || strip(to_tsvector('stripped')), + to_tsquery('unstripped & stripped')) +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 258 +-- truncate_limit: 100 +--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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 259 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 260 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 261 +-- truncate_limit: 100 +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', 'day & drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 262 +-- truncate_limit: 100 +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', 'day | drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 263 +-- truncate_limit: 100 +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', 'day | !drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 264 +-- truncate_limit: 100 +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', 'painted <-> Ship & drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 265 +-- truncate_limit: 100 +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', 'painted <-> Ship | drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 266 +-- truncate_limit: 100 +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', 'painted <-> Ship | !drink')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 267 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 268 +-- truncate_limit: 100 +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')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 269 +-- truncate_limit: 100 +SELECT ts_headline('english', +'Lorem ipsum urna. Nullam nullam ullamcorper urna.', +to_tsquery('english','Lorem') && phraseto_tsquery('english','ullamcorper urna'), +'MaxWords=100, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 270 +-- truncate_limit: 100 +SELECT ts_headline('english', +'Lorem ipsum urna. Nullam nullam ullamcorper urna.', +phraseto_tsquery('english','ullamcorper urna'), +'MaxWords=100, MinWords=5') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 271 +-- truncate_limit: 100 +SELECT ts_headline('english', ' + + + +Sea view wow foo bar qq +YES   +ff-bg + + +', +to_tsquery('english', 'sea&foo'), 'HighlightAll=true') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 272 +-- truncate_limit: 100 +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=2, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=2, MinWords=1')" +== 273 +-- truncate_limit: 100 +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 & 3', 'MaxWords=4, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 & 3', 'MaxWords=4, MinWords=1')" +== 274 +-- truncate_limit: 100 +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=4, MinWords=1') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=4, MinWords=1')" +== 275 +-- truncate_limit: 100 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 276 +-- truncate_limit: 100 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 277 +-- truncate_limit: 100 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 278 +-- truncate_limit: 100 +--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=***') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 279 +-- truncate_limit: 100 +--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') +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 280 +-- truncate_limit: 100 +-- Edge cases with empty query +SELECT ts_headline('english', +'', to_tsquery('english', '')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('english', '', to_tsquery('english', ''))" +== 281 +-- truncate_limit: 100 +SELECT ts_headline('english', +'foo bar', to_tsquery('english', '')) +-- +FUNCTION: name="ts_headline" function="ts_headline" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_headline('english', 'foo bar', to_tsquery('english', ''))" +== 282 +-- truncate_limit: 100 +--Rewrite sub system + +CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE test_tsquery (txtkeyword text, txtsample text)" +== 283 +-- truncate_limit: 100 +'New York' new <-> york | big <-> apple | nyc +Moscow moskva | moscow +'Sanct Peter' Peterburg | peter | 'Sanct Peterburg' +foo & bar & qq foo & (bar | qq) & city +1 & (2 <-> 3) 2 <-> 4 +5 <-> 6 5 <-> 7 + +ALTER TABLE test_tsquery ADD COLUMN keyword tsquery +-- +ERROR: syntax error at or near "'New York'" +CURSORPOS: 1 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 284 +-- truncate_limit: 100 +UPDATE test_tsquery SET keyword = to_tsquery('english', txtkeyword) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DML +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE test_tsquery SET keyword = to_tsquery('english', txtkeyword)" +== 285 +-- truncate_limit: 100 +ALTER TABLE test_tsquery ADD COLUMN sample tsquery +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE test_tsquery ADD COLUMN sample tsquery" +== 286 +-- truncate_limit: 100 +UPDATE test_tsquery SET sample = to_tsquery('english', txtsample::text) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DML +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE test_tsquery SET sample = to_tsquery('english', txtsample::text)" +== 287 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword < 'new <-> york'" +== 288 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword <= 'new <-> york'" +== 289 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword = 'new <-> york'" +== 290 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword >= 'new <-> york'" +== 291 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword > 'new <-> york'" +== 292 +-- truncate_limit: 100 +CREATE UNIQUE INDEX bt_tsq ON test_tsquery (keyword) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX bt_tsq ON test_tsquery USING btree (keyword)" +== 293 +-- truncate_limit: 100 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 294 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword < 'new <-> york'" +== 295 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword <= 'new <-> york'" +== 296 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword = 'new <-> york'" +== 297 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword >= 'new <-> york'" +== 298 +-- truncate_limit: 100 +SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new <-> york' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsquery WHERE keyword > 'new <-> york'" +== 299 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 300 +-- truncate_limit: 100 +SELECT ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 301 +-- truncate_limit: 100 +SELECT ts_rewrite(ts_rewrite('new & !york ', 'york', '!jersey'), + 'jersey', 'mexico') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite(ts_rewrite('new & !york ', 'york', '!jersey'), 'jersey', 'mexico')" +== 302 +-- truncate_limit: 100 +SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text)" +== 303 +-- truncate_limit: 100 +SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::text)" +== 304 +-- truncate_limit: 100 +SELECT ts_rewrite('bar & qq & foo & (new <-> york)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 305 +-- truncate_limit: 100 +SELECT ts_rewrite( 'moscow', 'SELECT keyword, sample FROM test_tsquery') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery')" +== 306 +-- truncate_limit: 100 +SELECT ts_rewrite( 'moscow & hotel', 'SELECT keyword, sample FROM test_tsquery') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery')" +== 307 +-- truncate_limit: 100 +SELECT ts_rewrite( 'bar & qq & foo & (new <-> york)', 'SELECT keyword, sample FROM test_tsquery') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('bar & qq & foo & (new <-> york)', 'SELECT keyword, sample FROM test_tsquery')" +== 308 +-- truncate_limit: 100 +SELECT ts_rewrite('1 & (2 <-> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('1 & (2 <-> 3)', 'SELECT keyword, sample FROM test_tsquery'::text)" +== 309 +-- truncate_limit: 100 +SELECT ts_rewrite('1 & (2 <2> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('1 & (2 <2> 3)', 'SELECT keyword, sample FROM test_tsquery'::text)" +== 310 +-- truncate_limit: 100 +SELECT ts_rewrite('5 <-> (1 & (2 <-> 3))', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('5 <-> (1 & (2 <-> 3))', 'SELECT keyword, sample FROM test_tsquery'::text)" +== 311 +-- truncate_limit: 100 +SELECT ts_rewrite('5 <-> (6 | 8)', 'SELECT keyword, sample FROM test_tsquery'::text ) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite('5 <-> (6 | 8)', 'SELECT keyword, sample FROM test_tsquery'::text)" +== 312 +-- truncate_limit: 100 +-- Check empty substitution +SELECT ts_rewrite(to_tsquery('5 & (6 | 5)'), to_tsquery('5'), to_tsquery('')) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite(to_tsquery('5 & (6 | 5)'), to_tsquery('5'), to_tsquery(''))" +== 313 +-- truncate_limit: 100 +SELECT ts_rewrite(to_tsquery('!5'), to_tsquery('5'), to_tsquery('')) +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite(to_tsquery('!5'), to_tsquery('5'), to_tsquery(''))" +== 314 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword @> 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword @> 'new'" +== 315 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow'" +== 316 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword <@ 'new'" +== 317 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow'" +== 318 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow') query" +== 319 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow & hotel') query" +== 320 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') query" +== 321 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow') query" +== 322 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow & hotel') query" +== 323 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') query" +== 324 +-- truncate_limit: 100 +CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops) +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops)" +== 325 +-- truncate_limit: 100 +SET enable_seqscan=OFF +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 326 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword @> 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword @> 'new'" +== 327 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow'" +== 328 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'new' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword <@ 'new'" +== 329 +-- truncate_limit: 100 +SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow' +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FILTER: schema="" table="" column="keyword" +STMT: SelectStmt +TRUNCATED: "SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow'" +== 330 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow') query" +== 331 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow & hotel') query" +== 332 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') query" +== 333 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow') query" +== 334 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'moscow & hotel') query" +== 335 +-- truncate_limit: 100 +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') query" +== 336 +-- truncate_limit: 100 +SELECT ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz') +-- +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz')" +== 337 +-- truncate_limit: 100 +SELECT to_tsvector('foo bar') @@ + ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('foo bar') @@ ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz')" +== 338 +-- truncate_limit: 100 +SELECT to_tsvector('bar baz') @@ + ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="ts_rewrite" function="ts_rewrite" schema="" ctx=Call +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('bar baz') @@ ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz')" +== 339 +-- truncate_limit: 100 +RESET enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 340 +-- truncate_limit: 100 +--test GUC +SET default_text_search_config=simple +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_text_search_config TO simple" +== 341 +-- truncate_limit: 100 +SELECT to_tsvector('SKIES My booKs') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('SKIES My booKs')" +== 342 +-- truncate_limit: 100 +SELECT plainto_tsquery('SKIES My booKs') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT plainto_tsquery('SKIES My booKs')" +== 343 +-- truncate_limit: 100 +SELECT to_tsquery('SKIES & My | booKs') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('SKIES & My | booKs')" +== 344 +-- truncate_limit: 100 +SET default_text_search_config=english +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_text_search_config TO english" +== 345 +-- truncate_limit: 100 +SELECT to_tsvector('SKIES My booKs') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('SKIES My booKs')" +== 346 +-- truncate_limit: 100 +SELECT plainto_tsquery('SKIES My booKs') +-- +FUNCTION: name="plainto_tsquery" function="plainto_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT plainto_tsquery('SKIES My booKs')" +== 347 +-- truncate_limit: 100 +SELECT to_tsquery('SKIES & My | booKs') +-- +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsquery('SKIES & My | booKs')" +== 348 +-- truncate_limit: 100 +--trigger +CREATE TRIGGER tsvectorupdate +BEFORE UPDATE OR INSERT ON test_tsvector +FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t) +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON test_tsvector FOR EACH ROW EXECUTE FUNCT..." +== 349 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty')" +== 350 +-- truncate_limit: 100 +INSERT INTO test_tsvector (t) VALUES ('345 qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_tsvector (t) VALUES ('345 qwerty')" +== 351 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty')" +== 352 +-- truncate_limit: 100 +UPDATE test_tsvector SET t = null WHERE t = '345 qwerty' +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE test_tsvector SET t = NULL WHERE t = '345 qwerty'" +== 353 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty')" +== 354 +-- truncate_limit: 100 +INSERT INTO test_tsvector (t) VALUES ('345 qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_tsvector (t) VALUES ('345 qwerty')" +== 355 +-- truncate_limit: 100 +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty') +-- +TABLE: name="test_tsvector" schema="" table="test_tsvector" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty')" +== 356 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="txtsample" +FILTER: schema="" table="" column="q" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM test_tsquery, to_tsquery('new') q WHERE txtsample @@ q" +== 357 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="test_tsquery" schema="" table="test_tsquery" ctx=Select +FUNCTION: name="to_tsquery" function="to_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="txtsample" +FILTER: schema="" table="" column="q" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM test_tsquery, to_tsquery('english', 'new') q WHERE txtsample @@ q" +== 358 +-- truncate_limit: 100 +-- test finding items in GIN's pending list +create temp table pendtest (ts tsvector) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE pendtest (ts tsvector)" +== 359 +-- truncate_limit: 100 +create index pendtest_idx on pendtest using gin(ts) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX pendtest_idx ON pendtest USING gin (ts)" +== 360 +-- truncate_limit: 100 +insert into pendtest values (to_tsvector('Lore ipsam')) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DML +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pendtest VALUES (to_tsvector('Lore ipsam'))" +== 361 +-- truncate_limit: 100 +insert into pendtest values (to_tsvector('Lore ipsum')) +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=DML +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pendtest VALUES (to_tsvector('Lore ipsum'))" +== 362 +-- truncate_limit: 100 +select * from pendtest where 'ipsu:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pendtest WHERE 'ipsu:*'::tsquery @@ ts" +== 363 +-- truncate_limit: 100 +select * from pendtest where 'ipsa:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pendtest WHERE 'ipsa:*'::tsquery @@ ts" +== 364 +-- truncate_limit: 100 +select * from pendtest where 'ips:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pendtest WHERE 'ips:*'::tsquery @@ ts" +== 365 +-- truncate_limit: 100 +select * from pendtest where 'ipt:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pendtest WHERE 'ipt:*'::tsquery @@ ts" +== 366 +-- truncate_limit: 100 +select * from pendtest where 'ipi:*'::tsquery @@ ts +-- +TABLE: name="pendtest" schema="" table="pendtest" ctx=Select +FILTER: schema="" table="" column="ts" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pendtest WHERE 'ipi:*'::tsquery @@ ts" +== 367 +-- truncate_limit: 100 +--check OP_PHRASE on index +create temp table phrase_index_test(fts tsvector) +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE phrase_index_test (fts tsvector)" +== 368 +-- truncate_limit: 100 +insert into phrase_index_test values ('A fat cat has just eaten a rat.') +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO phrase_index_test VALUES ('A fat cat has just eaten a rat.')" +== 369 +-- truncate_limit: 100 +insert into phrase_index_test values (to_tsvector('english', 'A fat cat has just eaten a rat.')) +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DML +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO phrase_index_test VALUES (to_tsvector('english', 'A fat cat has just eaten a rat.'))" +== 370 +-- truncate_limit: 100 +create index phrase_index_test_idx on phrase_index_test using gin(fts) +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX phrase_index_test_idx ON phrase_index_test USING gin (fts)" +== 371 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 372 +-- truncate_limit: 100 +select * from phrase_index_test where fts @@ phraseto_tsquery('english', 'fat cat') +-- +TABLE: name="phrase_index_test" schema="" table="phrase_index_test" ctx=Select +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +FUNCTION: name="phraseto_tsquery" function="phraseto_tsquery" schema="" ctx=Call +FILTER: schema="" table="" column="fts" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM phrase_index_test WHERE fts @@ phraseto_tsquery('english', 'fat cat')" +== 373 +-- truncate_limit: 100 +set enable_seqscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 374 +-- truncate_limit: 100 +-- test websearch_to_tsquery function +select websearch_to_tsquery('simple', 'I have a fat:*ABCD cat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'I have a fat:*ABCD cat')" +== 375 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'orange:**AABBCCDD') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'orange:**AABBCCDD')" +== 376 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat:A!cat:B|rat:C<') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat:A!cat:B|rat:C<')" +== 377 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat:A : cat:B') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat:A : cat:B')" +== 378 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat*rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat*rat')" +== 379 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat-rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat-rat')" +== 380 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat_rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat_rat')" +== 381 +-- truncate_limit: 100 +-- weights are completely ignored +select websearch_to_tsquery('simple', 'abc : def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc : def')" +== 382 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'abc:def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc:def')" +== 383 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'a:::b') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'a:::b')" +== 384 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'abc:d') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc:d')" +== 385 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', ':') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', ':')" +== 386 +-- truncate_limit: 100 +-- these operators are ignored +select websearch_to_tsquery('simple', 'abc & def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc & def')" +== 387 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'abc | def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc | def')" +== 388 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'abc <-> def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc <-> def')" +== 389 +-- truncate_limit: 100 +-- parens are ignored, too +select websearch_to_tsquery('simple', 'abc (pg or class)') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc (pg or class)')" +== 390 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', '(foo bar) or (ding dong)') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', '(foo bar) or (ding dong)')" +== 391 +-- truncate_limit: 100 +-- NOT is ignored in quotes +select websearch_to_tsquery('english', 'My brand new smartphone') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'My brand new smartphone')" +== 392 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'My brand "new smartphone"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'My brand \"new smartphone\"')" +== 393 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'My brand "new -smartphone"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'My brand \"new -smartphone\"')" +== 394 +-- truncate_limit: 100 +-- test OR operator +select websearch_to_tsquery('simple', 'cat or rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'cat or rat')" +== 395 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'cat OR rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'cat OR rat')" +== 396 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'cat "OR" rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'cat \"OR\" rat')" +== 397 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'cat OR') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'cat OR')" +== 398 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'OR rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'OR rat')" +== 399 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', '"fat cat OR rat"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', '\"fat cat OR rat\"')" +== 400 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat (cat OR rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat (cat OR rat')" +== 401 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'or OR or') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'or OR or')" +== 402 +-- truncate_limit: 100 +-- OR is an operator here ... +select websearch_to_tsquery('simple', '"fat cat"or"fat rat"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', '\"fat cat\"or\"fat rat\"')" +== 403 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat or(rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat or(rat')" +== 404 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat or)rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat or)rat')" +== 405 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat or&rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat or&rat')" +== 406 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat or|rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat or|rat')" +== 407 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat or!rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat or!rat')" +== 408 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat orrat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat or>rat')" +== 410 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'fat or ') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'fat or ')" +== 411 +-- truncate_limit: 100 +-- ... but not here +select websearch_to_tsquery('simple', 'abc orange') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc orange')" +== 412 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'abc OR1234') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc OR1234')" +== 413 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'abc or-abc') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc or-abc')" +== 414 +-- truncate_limit: 100 +select websearch_to_tsquery('simple', 'abc OR_abc') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('simple', 'abc OR_abc')" +== 415 +-- truncate_limit: 100 +-- test quotes +select websearch_to_tsquery('english', '"pg_class pg') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"pg_class pg')" +== 416 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'pg_class pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'pg_class pg\"')" +== 417 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"pg_class pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"pg_class pg\"')" +== 418 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"pg_class : pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"pg_class : pg\"')" +== 419 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'abc "pg_class pg"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'abc \"pg_class pg\"')" +== 420 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"pg_class pg" def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"pg_class pg\" def')" +== 421 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'abc "pg pg_class pg" def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'abc \"pg pg_class pg\" def')" +== 422 +-- truncate_limit: 100 +select websearch_to_tsquery('english', ' or "pg pg_class pg" or ') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', ' or \"pg pg_class pg\" or ')" +== 423 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '""pg pg_class pg""') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"\"pg pg_class pg\"\"')" +== 424 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'abc """"" def') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'abc \"\"\"\"\" def')" +== 425 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'cat -"fat rat"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'cat -\"fat rat\"')" +== 426 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'cat -"fat rat" cheese') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'cat -\"fat rat\" cheese')" +== 427 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'abc "def -"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'abc \"def -\"')" +== 428 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'abc "def :"') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'abc \"def :\"')" +== 429 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"A fat cat" has just eaten a -rat.') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"A fat cat\" has just eaten a -rat.')" +== 430 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"A fat cat" has just eaten OR !rat.') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"A fat cat\" has just eaten OR !rat.')" +== 431 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"A fat cat" has just (+eaten OR -rat)') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"A fat cat\" has just (+eaten OR -rat)')" +== 432 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'this is ----fine') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'this is ----fine')" +== 433 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '(()) )))) this ||| is && -fine, "dear friend" OR good') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '(()) )))) this ||| is && -fine, \"dear friend\" OR good')" +== 434 +-- truncate_limit: 100 +select websearch_to_tsquery('english', 'an old <-> cat " is fine &&& too') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', 'an old <-> cat \" is fine &&& too')" +== 435 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"A the" OR just on') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"A the\" OR just on')" +== 436 +-- truncate_limit: 100 +select websearch_to_tsquery('english', '"a fat cat" ate a rat') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('english', '\"a fat cat\" ate a rat')" +== 437 +-- truncate_limit: 100 +select to_tsvector('english', 'A fat cat ate a rat') @@ + websearch_to_tsquery('english', '"a fat cat" ate a rat') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 438 +-- truncate_limit: 100 +select to_tsvector('english', 'A fat grey cat ate a rat') @@ + websearch_to_tsquery('english', '"a fat cat" ate a rat') +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 439 +-- truncate_limit: 100 +-- cases handled by gettoken_tsvector() +select websearch_to_tsquery('''') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('''')" +== 440 +-- truncate_limit: 100 +select websearch_to_tsquery('''abc''''def''') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery('''abc''''def''')" +== 441 +-- truncate_limit: 100 +select websearch_to_tsquery('\abc') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery(E'\\\\abc')" +== 442 +-- truncate_limit: 100 +select websearch_to_tsquery('\') +-- +FUNCTION: name="websearch_to_tsquery" function="websearch_to_tsquery" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT websearch_to_tsquery(E'\\\\')" diff --git a/parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json new file mode 100644 index 0000000..e49ea16 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json @@ -0,0 +1,78 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tsrf.test b/parser/testdata/summary_truncate/postgres_regress/tsrf.test new file mode 100644 index 0000000..00447dd --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tsrf.test @@ -0,0 +1,695 @@ +== 001 +-- truncate_limit: 100 +|-- +-- tsrf - targetlist set returning function tests +|-- + +-- simple srf +SELECT generate_series(1, 3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 3)" +== 002 +-- truncate_limit: 100 +-- parallel iteration +SELECT generate_series(1, 3), generate_series(3,5) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 3), generate_series(3, 5)" +== 003 +-- truncate_limit: 100 +-- parallel iteration, different number of rows +SELECT generate_series(1, 2), generate_series(1,4) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 2), generate_series(1, 4)" +== 004 +-- truncate_limit: 100 +-- srf, with SRF argument +SELECT generate_series(1, generate_series(1, 3)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, generate_series(1, 3))" +== 005 +-- truncate_limit: 100 +-- but we've traditionally rejected the same in FROM +SELECT * FROM generate_series(1, generate_series(1, 3)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM generate_series(1, generate_series(1, 3))" +== 006 +-- truncate_limit: 100 +-- srf, with two SRF arguments +SELECT generate_series(generate_series(1,3), generate_series(2, 4)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(generate_series(1, 3), generate_series(2, 4))" +== 007 +-- truncate_limit: 100 +-- check proper nesting of SRFs in different expressions +explain (verbose, costs off) +SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4)" +== 008 +-- truncate_limit: 100 +SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4)" +== 009 +-- truncate_limit: 100 +CREATE TABLE few(id int, dataa text, datab text) +-- +TABLE: name="few" schema="" table="few" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE few (id int, dataa text, datab text)" +== 010 +-- truncate_limit: 100 +INSERT INTO few VALUES(1, 'a', 'foo'),(2, 'a', 'bar'),(3, 'b', 'bar') +-- +TABLE: name="few" schema="" table="few" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO few VALUES (1, 'a', 'foo'), (2, 'a', 'bar'), (3, 'b', 'bar')" +== 011 +-- truncate_limit: 100 +-- SRF with a provably-dummy relation +explain (verbose, costs off) +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT unnest(ARRAY[1, 2]) FROM few WHERE false" +== 012 +-- truncate_limit: 100 +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest(ARRAY[1, 2]) FROM few WHERE false" +== 013 +-- truncate_limit: 100 +-- SRF shouldn't prevent upper query from recognizing lower as dummy +explain (verbose, costs off) +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss +-- +TABLE: name="few" schema="" table="few" ctx=Select +TABLE: name="few" schema="" table="few" ctx=Select +ALIAS: "f1"="few" +ALIAS: "f2"="few" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM few f1, (SELECT unnest(ARRAY[1, 2]) FROM few f2 WHERE ..." +== 014 +-- truncate_limit: 100 +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss +-- +TABLE: name="few" schema="" table="few" ctx=Select +TABLE: name="few" schema="" table="few" ctx=Select +ALIAS: "f1"="few" +ALIAS: "f2"="few" +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM few f1, (SELECT unnest(ARRAY[1, 2]) FROM few f2 WHERE false OFFSET 0) ss" +== 015 +-- truncate_limit: 100 +-- SRF output order of sorting is maintained, if SRF is not referenced +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT few.id, generate_series(1, 3) AS g FROM few ORDER BY id DESC" +== 016 +-- truncate_limit: 100 +-- but SRFs can be referenced in sort +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, g DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT few.id, generate_series(1, 3) AS g FROM few ORDER BY id, g DESC" +== 017 +-- truncate_limit: 100 +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, generate_series(1,3) DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT few.id, generate_series(1, 3) AS g FROM few ORDER BY id, generate_series(1, 3) DESC" +== 018 +-- truncate_limit: 100 +-- it's weird to have ORDER BYs that increase the number of results +SELECT few.id FROM few ORDER BY id, generate_series(1,3) DESC +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT few.id FROM few ORDER BY id, generate_series(1, 3) DESC" +== 019 +-- truncate_limit: 100 +-- SRFs are computed after aggregation +SET enable_hashagg TO 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO 0" +== 020 +-- truncate_limit: 100 +-- stable output order +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="few" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few WHERE few.id = 1 GROUP BY few.dataa" +== 021 +-- truncate_limit: 100 +-- unless referenced in GROUP BY clause +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, unnest('{1,1,3}'::int[]) +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="few" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few WHERE few.id = 1 GROUP BY few.dataa, unnest('{1,1,3}'::int[])" +== 022 +-- truncate_limit: 100 +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, 5 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="few" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few WHERE few.id = 1 GROUP BY few.dataa, 5" +== 023 +-- truncate_limit: 100 +RESET enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 024 +-- truncate_limit: 100 +-- check HAVING works when GROUP BY does [not] reference SRF output +SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1 HAVING count(*) > 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dataa, generate_series(1, 1), count(*) FROM few GROUP BY 1 HAVING count(*) > 1" +== 025 +-- truncate_limit: 100 +SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1, 2 HAVING count(*) > 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dataa, generate_series(1, 1), count(*) FROM few GROUP BY 1, 2 HAVING count(*) > 1" +== 026 +-- truncate_limit: 100 +-- it's weird to have GROUP BYs that increase the number of results +SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa ORDER BY 2 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="dataa" +STMT: SelectStmt +TRUNCATED: "SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa ORDER BY 2" +== 027 +-- truncate_limit: 100 +SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa, unnest('{1,1,3}'::int[]) ORDER BY 2 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +FILTER: schema="" table="" column="dataa" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few WHERE dataa = 'a' GROUP BY few.dataa, unnest('{1,1,3}'::int[]) ORDER BY 2" +== 028 +-- truncate_limit: 100 +-- SRFs are not allowed if they'd need to be conditionally executed +SELECT q1, case when q1 > 0 then generate_series(1,3) else 0 end FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q1, CASE WHEN q1 > 0 THEN generate_series(1, 3) ELSE 0 END FROM int8_tbl" +== 029 +-- truncate_limit: 100 +SELECT q1, coalesce(generate_series(1,3), 0) FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT q1, COALESCE(generate_series(1, 3), 0) FROM int8_tbl" +== 030 +-- truncate_limit: 100 +-- SRFs are not allowed in aggregate arguments +SELECT min(generate_series(1, 3)) FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(generate_series(1, 3)) FROM few" +== 031 +-- truncate_limit: 100 +-- ... unless they're within a sub-select +SELECT sum((3 = ANY(SELECT generate_series(1,4)))::int) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(3 = ANY (SELECT generate_series(1, 4))::int)" +== 032 +-- truncate_limit: 100 +SELECT sum((3 = ANY(SELECT lag(x) over(order by x) + FROM generate_series(1,4) x))::int) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT sum(3 = ANY (SELECT lag(x) OVER (ORDER BY x) FROM generate_series(1, 4) x)::int)" +== 033 +-- truncate_limit: 100 +-- SRFs are not allowed in window function arguments, either +SELECT min(generate_series(1, 3)) OVER() FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(generate_series(1, 3)) OVER () FROM few" +== 034 +-- truncate_limit: 100 +-- SRFs are normally computed after window functions +SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT id, lag(id) OVER (), count(*) OVER (), generate_series(1, 3) FROM few" +== 035 +-- truncate_limit: 100 +-- unless referencing SRFs +SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few GROUP BY g" +== 036 +-- truncate_limit: 100 +-- sorting + grouping +SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few GROUP BY few.dataa ORDER BY 5, 1" +== 037 +-- truncate_limit: 100 +-- grouping sets are a bit special, they produce NULLs in columns not actually NULL +set enable_hashagg = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 038 +-- truncate_limit: 100 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT dataa, datab AS b, generate_series(1, 2) AS g, count(*) FROM few GROUP BY CUBE (dataa, datab)" +== 039 +-- truncate_limit: 100 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY dataa +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few GROUP BY CUBE (dataa, datab) ORDER BY dataa" +== 040 +-- truncate_limit: 100 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY g +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few GROUP BY CUBE (dataa, datab) ORDER BY g" +== 041 +-- truncate_limit: 100 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few GROUP BY CUBE (dataa, datab, g)" +== 042 +-- truncate_limit: 100 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY dataa +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few GROUP BY CUBE (dataa, datab, g) ORDER BY dataa" +== 043 +-- truncate_limit: 100 +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY g +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM few GROUP BY CUBE (dataa, datab, g) ORDER BY g" +== 044 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 045 +-- truncate_limit: 100 +-- case with degenerate ORDER BY +explain (verbose, costs off) +select 'foo' as f, generate_series(1,2) as g from few order by 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT 'foo' AS f, generate_series(1, 2) AS g FROM few ORDER BY 1" +== 046 +-- truncate_limit: 100 +select 'foo' as f, generate_series(1,2) as g from few order by 1 +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'foo' AS f, generate_series(1, 2) AS g FROM few ORDER BY 1" +== 047 +-- truncate_limit: 100 +-- data modification +CREATE TABLE fewmore AS SELECT generate_series(1,3) AS data +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE fewmore AS SELECT generate_series(1, 3) AS data" +== 048 +-- truncate_limit: 100 +INSERT INTO fewmore VALUES(generate_series(4,5)) +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fewmore VALUES (generate_series(4, 5))" +== 049 +-- truncate_limit: 100 +SELECT * FROM fewmore +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM fewmore" +== 050 +-- truncate_limit: 100 +-- SRFs are not allowed in UPDATE (they once were, but it was nonsense) +UPDATE fewmore SET data = generate_series(4,9) +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE fewmore SET data = generate_series(4, 9)" +== 051 +-- truncate_limit: 100 +-- SRFs are not allowed in RETURNING +INSERT INTO fewmore VALUES(1) RETURNING generate_series(1,3) +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO fewmore VALUES (1) RETURNING generate_series(1, 3)" +== 052 +-- truncate_limit: 100 +-- nor standalone VALUES (but surely this is a bug?) +VALUES(1, generate_series(1,2)) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "VALUES (1, generate_series(1, 2))" +== 053 +-- truncate_limit: 100 +-- We allow tSRFs that are not at top level +SELECT int4mul(generate_series(1,2), 10) +-- +FUNCTION: name="int4mul" function="int4mul" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT int4mul(generate_series(1, 2), 10)" +== 054 +-- truncate_limit: 100 +SELECT generate_series(1,3) IS DISTINCT FROM 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 3) IS DISTINCT FROM 2" +== 055 +-- truncate_limit: 100 +-- but SRFs in function RTEs must be at top level (annoying restriction) +SELECT * FROM int4mul(generate_series(1,2), 10) +-- +FUNCTION: name="int4mul" function="int4mul" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int4mul(generate_series(1, 2), 10)" +== 056 +-- truncate_limit: 100 +-- DISTINCT ON is evaluated before tSRF evaluation if SRF is not +-- referenced either in ORDER BY or in the DISTINCT ON list. The ORDER +-- BY reference can be implicitly generated, if there's no other ORDER BY. + +-- implicit reference (via implicit ORDER) to all columns +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (a) a, b, generate_series(1, 3) AS g FROM (VALUES (...)) t(a, b)" +== 057 +-- truncate_limit: 100 +-- unreferenced in DISTINCT ON or ORDER BY +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (a) ... AS ... FROM (VALUES (...)) t(a, b) ORDER BY a, b DESC" +== 058 +-- truncate_limit: 100 +-- referenced in ORDER BY +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC, g DESC +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (a) ... AS ... FROM (VALUES (...)) t(a, b) ORDER BY a, b DESC, g DESC" +== 059 +-- truncate_limit: 100 +-- referenced in ORDER BY and DISTINCT ON +SELECT DISTINCT ON (a, b, g) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC, g DESC +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (a, b, g) ... AS ... FROM (VALUES (...)) t(a, b) ORDER BY a, b DESC, g DESC" +== 060 +-- truncate_limit: 100 +-- only SRF mentioned in DISTINCT ON +SELECT DISTINCT ON (g) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT ON (g) a, b, generate_series(1, 3) AS g FROM (VALUES (...)) t(a, b)" +== 061 +-- truncate_limit: 100 +-- LIMIT / OFFSET is evaluated after SRF evaluation +SELECT a, generate_series(1,2) FROM (VALUES(1),(2),(3)) r(a) LIMIT 2 OFFSET 2 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, generate_series(1, 2) FROM (VALUES (1), (2), (3)) r(a) LIMIT 2 OFFSET 2" +== 062 +-- truncate_limit: 100 +-- SRFs are not allowed in LIMIT. +SELECT 1 LIMIT generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 1 LIMIT generate_series(1, 3)" +== 063 +-- truncate_limit: 100 +-- tSRF in correlated subquery, referencing table outside +SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET few.id) FROM few +-- +TABLE: name="few" schema="" table="few" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT generate_series(1, 3) LIMIT 1 OFFSET few.id) FROM few" +== 064 +-- truncate_limit: 100 +-- tSRF in correlated subquery, referencing SRF outside +SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET g.i) FROM generate_series(0,3) g(i) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT (SELECT generate_series(1, 3) LIMIT 1 OFFSET g.i) FROM generate_series(0, 3) g(i)" +== 065 +-- truncate_limit: 100 +-- Operators can return sets too +CREATE OPERATOR |@| (PROCEDURE = unnest, RIGHTARG = ANYARRAY) +-- +STMT: DefineStmt +TRUNCATED: "CREATE OPERATOR |@| (procedure = unnest, rightarg = anyarray)" +== 066 +-- truncate_limit: 100 +SELECT |@|ARRAY[1,2,3] +-- +STMT: SelectStmt +TRUNCATED: "SELECT |@| ARRAY[1, 2, 3]" +== 067 +-- truncate_limit: 100 +-- Some fun cases involving duplicate SRF calls +explain (verbose, costs off) +select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT generate_series(1, 3) AS x, generate_series(1, 3) + 1 AS xp1" +== 068 +-- truncate_limit: 100 +select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1 +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 3) AS x, generate_series(1, 3) + 1 AS xp1" +== 069 +-- truncate_limit: 100 +explain (verbose, costs off) +select generate_series(1,3)+1 order by generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT generate_series(1, 3) + 1 ORDER BY generate_series(1, 3)" +== 070 +-- truncate_limit: 100 +select generate_series(1,3)+1 order by generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 3) + 1 ORDER BY generate_series(1, 3)" +== 071 +-- truncate_limit: 100 +-- Check that SRFs of same nesting level run in lockstep +explain (verbose, costs off) +select generate_series(1,3) as x, generate_series(3,6) + 1 as y +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT generate_series(1, 3) AS x, generate_series(3, 6) + 1 AS y" +== 072 +-- truncate_limit: 100 +select generate_series(1,3) as x, generate_series(3,6) + 1 as y +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 3) AS x, generate_series(3, 6) + 1 AS y" +== 073 +-- truncate_limit: 100 +-- Clean up +DROP TABLE few +-- +TABLE: name="few" schema="" table="few" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE few" +== 074 +-- truncate_limit: 100 +DROP TABLE fewmore +-- +TABLE: name="fewmore" schema="" table="fewmore" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE fewmore" diff --git a/parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json new file mode 100644 index 0000000..1ef8c5f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json @@ -0,0 +1,242 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tstypes.test b/parser/testdata/summary_truncate/postgres_regress/tstypes.test new file mode 100644 index 0000000..bf66b1f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tstypes.test @@ -0,0 +1,1586 @@ +== 001 +-- truncate_limit: 100 +-- deal with numeric instability of ts_rank +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO 0" +== 002 +-- truncate_limit: 100 +--Base tsvector test + +SELECT '1'::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::tsvector" +== 003 +-- truncate_limit: 100 +SELECT '1 '::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 '::tsvector" +== 004 +-- truncate_limit: 100 +SELECT ' 1'::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 1'::tsvector" +== 005 +-- truncate_limit: 100 +SELECT ' 1 '::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 1 '::tsvector" +== 006 +-- truncate_limit: 100 +SELECT '1 2'::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 2'::tsvector" +== 007 +-- truncate_limit: 100 +SELECT '''1 2'''::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT '''1 2'''::tsvector" +== 008 +-- truncate_limit: 100 +SELECT E'''1 \\''2'''::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'''1 \\\\''2'''::tsvector" +== 009 +-- truncate_limit: 100 +SELECT E'''1 \\''2''3'::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'''1 \\\\''2''3'::tsvector" +== 010 +-- truncate_limit: 100 +SELECT E'''1 \\''2'' 3'::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'''1 \\\\''2'' 3'::tsvector" +== 011 +-- truncate_limit: 100 +SELECT E'''1 \\''2'' '' 3'' 4 '::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'''1 \\\\''2'' '' 3'' 4 '::tsvector" +== 012 +-- truncate_limit: 100 +SELECT $$'\\as' ab\c ab\\c AB\\\c ab\\\\c$$::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'''\\\\\\\\as'' ab\\\\c ab\\\\\\\\c AB\\\\\\\\\\\\c ab\\\\\\\\\\\\\\\\c'::tsvector" +== 013 +-- truncate_limit: 100 +SELECT tsvectorin(tsvectorout($$'\\as' ab\c ab\\c AB\\\c ab\\\\c$$::tsvector)) +-- +FUNCTION: name="tsvectorin" function="tsvectorin" schema="" ctx=Call +FUNCTION: name="tsvectorout" function="tsvectorout" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tsvectorin(tsvectorout(E'''\\\\\\\\as'' ab\\\\c ab\\\\\\\\c AB\\\\\\\\\\\\c ab\\\\\\\\\\\\\\\\c'::tsvector))" +== 014 +-- truncate_limit: 100 +SELECT '''w'':4A,3B,2C,1D,5 a:8' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '''w'':4A,3B,2C,1D,5 a:8'" +== 015 +-- truncate_limit: 100 +SELECT 'a:3A b:2a'::tsvector || 'ba:1234 a:1B' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:3A b:2a'::tsvector || 'ba:1234 a:1B'" +== 016 +-- truncate_limit: 100 +SELECT $$'' '1' '2'$$::tsvector +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''''' ''1'' ''2'''::tsvector" +== 017 +-- truncate_limit: 100 +-- error, empty lexeme is not allowed + +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('foo', 'tsvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('foo', 'tsvector')" +== 018 +-- truncate_limit: 100 +SELECT pg_input_is_valid($$''$$, 'tsvector') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('''''', 'tsvector')" +== 019 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info($$''$$, 'tsvector') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('''''', 'tsvector')" +== 020 +-- truncate_limit: 100 +--Base tsquery test +SELECT '1'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::tsquery" +== 021 +-- truncate_limit: 100 +SELECT '1 '::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1 '::tsquery" +== 022 +-- truncate_limit: 100 +SELECT ' 1'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 1'::tsquery" +== 023 +-- truncate_limit: 100 +SELECT ' 1 '::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' 1 '::tsquery" +== 024 +-- truncate_limit: 100 +SELECT '''1 2'''::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '''1 2'''::tsquery" +== 025 +-- truncate_limit: 100 +SELECT E'''1 \\''2'''::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'''1 \\\\''2'''::tsquery" +== 026 +-- truncate_limit: 100 +SELECT '!1'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!1'::tsquery" +== 027 +-- truncate_limit: 100 +SELECT '1|2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|2'::tsquery" +== 028 +-- truncate_limit: 100 +SELECT '1|!2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|!2'::tsquery" +== 029 +-- truncate_limit: 100 +SELECT '!1|2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!1|2'::tsquery" +== 030 +-- truncate_limit: 100 +SELECT '!1|!2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!1|!2'::tsquery" +== 031 +-- truncate_limit: 100 +SELECT '!(!1|!2)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(!1|!2)'::tsquery" +== 032 +-- truncate_limit: 100 +SELECT '!(!1|2)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(!1|2)'::tsquery" +== 033 +-- truncate_limit: 100 +SELECT '!(1|!2)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(1|!2)'::tsquery" +== 034 +-- truncate_limit: 100 +SELECT '!(1|2)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(1|2)'::tsquery" +== 035 +-- truncate_limit: 100 +SELECT '1&2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1&2'::tsquery" +== 036 +-- truncate_limit: 100 +SELECT '!1&2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!1&2'::tsquery" +== 037 +-- truncate_limit: 100 +SELECT '1&!2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1&!2'::tsquery" +== 038 +-- truncate_limit: 100 +SELECT '!1&!2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!1&!2'::tsquery" +== 039 +-- truncate_limit: 100 +SELECT '(1&2)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1&2)'::tsquery" +== 040 +-- truncate_limit: 100 +SELECT '1&(2)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1&(2)'::tsquery" +== 041 +-- truncate_limit: 100 +SELECT '!(1)&2'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(1)&2'::tsquery" +== 042 +-- truncate_limit: 100 +SELECT '!(1&2)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(1&2)'::tsquery" +== 043 +-- truncate_limit: 100 +SELECT '1|2&3'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|2&3'::tsquery" +== 044 +-- truncate_limit: 100 +SELECT '1|(2&3)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|(2&3)'::tsquery" +== 045 +-- truncate_limit: 100 +SELECT '(1|2)&3'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(1|2)&3'::tsquery" +== 046 +-- truncate_limit: 100 +SELECT '1|2&!3'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|2&!3'::tsquery" +== 047 +-- truncate_limit: 100 +SELECT '1|!2&3'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|!2&3'::tsquery" +== 048 +-- truncate_limit: 100 +SELECT '!1|2&3'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!1|2&3'::tsquery" +== 049 +-- truncate_limit: 100 +SELECT '!1|(2&3)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!1|(2&3)'::tsquery" +== 050 +-- truncate_limit: 100 +SELECT '!(1|2)&3'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(1|2)&3'::tsquery" +== 051 +-- truncate_limit: 100 +SELECT '(!1|2)&3'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '(!1|2)&3'::tsquery" +== 052 +-- truncate_limit: 100 +SELECT '1|(2|(4|(5|6)))'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|(2|(4|(5|6)))'::tsquery" +== 053 +-- truncate_limit: 100 +SELECT '1|2|4|5|6'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1|2|4|5|6'::tsquery" +== 054 +-- truncate_limit: 100 +SELECT '1&(2&(4&(5&6)))'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1&(2&(4&(5&6)))'::tsquery" +== 055 +-- truncate_limit: 100 +SELECT '1&2&4&5&6'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1&2&4&5&6'::tsquery" +== 056 +-- truncate_limit: 100 +SELECT '1&(2&(4&(5|6)))'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1&(2&(4&(5|6)))'::tsquery" +== 057 +-- truncate_limit: 100 +SELECT '1&(2&(4&(5|!6)))'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1&(2&(4&(5|!6)))'::tsquery" +== 058 +-- truncate_limit: 100 +SELECT E'1&(''2''&('' 4''&(\\|5 | ''6 \\'' !|&'')))'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'1&(''2''&('' 4''&(\\\\|5 | ''6 \\\\'' !|&'')))'::tsquery" +== 059 +-- truncate_limit: 100 +SELECT $$'\\as'$$::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT E'''\\\\\\\\as'''::tsquery" +== 060 +-- truncate_limit: 100 +SELECT 'a:* & nbb:*ac | doo:a* | goo'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:* & nbb:*ac | doo:a* | goo'::tsquery" +== 061 +-- truncate_limit: 100 +SELECT '!!b'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!!b'::tsquery" +== 062 +-- truncate_limit: 100 +SELECT '!!!b'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!!!b'::tsquery" +== 063 +-- truncate_limit: 100 +SELECT '!(!b)'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!(!b)'::tsquery" +== 064 +-- truncate_limit: 100 +SELECT 'a & !!b'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a & !!b'::tsquery" +== 065 +-- truncate_limit: 100 +SELECT '!!a & b'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!!a & b'::tsquery" +== 066 +-- truncate_limit: 100 +SELECT '!!a & !!b'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT '!!a & !!b'::tsquery" +== 067 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('foo', 'tsquery') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('foo', 'tsquery')" +== 068 +-- truncate_limit: 100 +SELECT pg_input_is_valid('foo!', 'tsquery') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('foo!', 'tsquery')" +== 069 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('foo!', 'tsquery') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('foo!', 'tsquery')" +== 070 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('a <100000> b', 'tsquery') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('a <100000> b', 'tsquery')" +== 071 +-- truncate_limit: 100 +--comparisons +SELECT 'a' < 'b & c'::tsquery as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a' < 'b & c'::tsquery AS \"true\"" +== 072 +-- truncate_limit: 100 +SELECT 'a' > 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a' > 'b & c'::tsquery AS \"false\"" +== 073 +-- truncate_limit: 100 +SELECT 'a | f' < 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a | f' < 'b & c'::tsquery AS \"false\"" +== 074 +-- truncate_limit: 100 +SELECT 'a | ff' < 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a | ff' < 'b & c'::tsquery AS \"false\"" +== 075 +-- truncate_limit: 100 +SELECT 'a | f | g' < 'b & c'::tsquery as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a | f | g' < 'b & c'::tsquery AS \"false\"" +== 076 +-- truncate_limit: 100 +--concatenation +SELECT numnode( 'new'::tsquery ) +-- +FUNCTION: name="numnode" function="numnode" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numnode('new'::tsquery)" +== 077 +-- truncate_limit: 100 +SELECT numnode( 'new & york'::tsquery ) +-- +FUNCTION: name="numnode" function="numnode" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numnode('new & york'::tsquery)" +== 078 +-- truncate_limit: 100 +SELECT numnode( 'new & york | qwery'::tsquery ) +-- +FUNCTION: name="numnode" function="numnode" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT numnode('new & york | qwery'::tsquery)" +== 079 +-- truncate_limit: 100 +SELECT 'foo & bar'::tsquery && 'asd' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo & bar'::tsquery && 'asd'" +== 080 +-- truncate_limit: 100 +SELECT 'foo & bar'::tsquery || 'asd & fg' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo & bar'::tsquery || 'asd & fg'" +== 081 +-- truncate_limit: 100 +SELECT 'foo & bar'::tsquery || !!'asd & fg'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo & bar'::tsquery || (!! 'asd & fg'::tsquery)" +== 082 +-- truncate_limit: 100 +SELECT 'foo & bar'::tsquery && 'asd | fg' +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'foo & bar'::tsquery && 'asd | fg'" +== 083 +-- truncate_limit: 100 +SELECT 'a' <-> 'b & d'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a' <-> 'b & d'::tsquery" +== 084 +-- truncate_limit: 100 +SELECT 'a & g' <-> 'b & d'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a & g' <-> 'b & d'::tsquery" +== 085 +-- truncate_limit: 100 +SELECT 'a & g' <-> 'b | d'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a & g' <-> 'b | d'::tsquery" +== 086 +-- truncate_limit: 100 +SELECT 'a & g' <-> 'b <-> d'::tsquery +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a & g' <-> 'b <-> d'::tsquery" +== 087 +-- truncate_limit: 100 +SELECT tsquery_phrase('a <3> g', 'b & d', 10) +-- +FUNCTION: name="tsquery_phrase" function="tsquery_phrase" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tsquery_phrase('a <3> g', 'b & d', 10)" +== 088 +-- truncate_limit: 100 +-- tsvector-tsquery operations + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca' AS \"true\"" +== 089 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:B' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:B' AS \"true\"" +== 090 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:A' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:A' AS \"true\"" +== 091 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:C' as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:C' AS \"false\"" +== 092 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:CB' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:CB' AS \"true\"" +== 093 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*C' as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*C' AS \"false\"" +== 094 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*CB' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*CB' AS \"true\"" +== 095 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64b cb:80c d:34c'::tsvector @@ 'd:AC & c:*C' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64b cb:80c d:34c'::tsvector @@ 'd:AC & c:*C' AS \"true\"" +== 096 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*C' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*C' AS \"true\"" +== 097 +-- truncate_limit: 100 +SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*B' as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*B' AS \"true\"" +== 098 +-- truncate_limit: 100 +SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D & w:*A'::tsquery as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D & w:*A'::tsquery AS \"true\"" +== 099 +-- truncate_limit: 100 +SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D <-> w:*A'::tsquery as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D <-> w:*A'::tsquery AS \"true\"" +== 100 +-- truncate_limit: 100 +SELECT 'wa:1A wb:2D'::tsvector @@ 'w:*D <-> w:*A'::tsquery as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'wa:1A wb:2D'::tsvector @@ 'w:*D <-> w:*A'::tsquery AS \"false\"" +== 101 +-- truncate_limit: 100 +SELECT 'wa:1A'::tsvector @@ 'w:*A'::tsquery as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'wa:1A'::tsvector @@ 'w:*A'::tsquery AS \"true\"" +== 102 +-- truncate_limit: 100 +SELECT 'wa:1A'::tsvector @@ 'w:*D'::tsquery as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'wa:1A'::tsvector @@ 'w:*D'::tsquery AS \"false\"" +== 103 +-- truncate_limit: 100 +SELECT 'wa:1A'::tsvector @@ '!w:*A'::tsquery as "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'wa:1A'::tsvector @@ '!w:*A'::tsquery AS \"false\"" +== 104 +-- truncate_limit: 100 +SELECT 'wa:1A'::tsvector @@ '!w:*D'::tsquery as "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'wa:1A'::tsvector @@ '!w:*D'::tsquery AS \"true\"" +== 105 +-- truncate_limit: 100 +-- historically, a stripped tsvector matches queries ignoring weights: +SELECT strip('wa:1A'::tsvector) @@ 'w:*A'::tsquery as "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip('wa:1A'::tsvector) @@ 'w:*A'::tsquery AS \"true\"" +== 106 +-- truncate_limit: 100 +SELECT strip('wa:1A'::tsvector) @@ 'w:*D'::tsquery as "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip('wa:1A'::tsvector) @@ 'w:*D'::tsquery AS \"true\"" +== 107 +-- truncate_limit: 100 +SELECT strip('wa:1A'::tsvector) @@ '!w:*A'::tsquery as "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip('wa:1A'::tsvector) @@ '!w:*A'::tsquery AS \"false\"" +== 108 +-- truncate_limit: 100 +SELECT strip('wa:1A'::tsvector) @@ '!w:*D'::tsquery as "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip('wa:1A'::tsvector) @@ '!w:*D'::tsquery AS \"false\"" +== 109 +-- truncate_limit: 100 +SELECT 'supernova'::tsvector @@ 'super'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'supernova'::tsvector @@ 'super'::tsquery AS \"false\"" +== 110 +-- truncate_limit: 100 +SELECT 'supeanova supernova'::tsvector @@ 'super'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'supeanova supernova'::tsvector @@ 'super'::tsquery AS \"false\"" +== 111 +-- truncate_limit: 100 +SELECT 'supeznova supernova'::tsvector @@ 'super'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'supeznova supernova'::tsvector @@ 'super'::tsquery AS \"false\"" +== 112 +-- truncate_limit: 100 +SELECT 'supernova'::tsvector @@ 'super:*'::tsquery AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'supernova'::tsvector @@ 'super:*'::tsquery AS \"true\"" +== 113 +-- truncate_limit: 100 +SELECT 'supeanova supernova'::tsvector @@ 'super:*'::tsquery AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'supeanova supernova'::tsvector @@ 'super:*'::tsquery AS \"true\"" +== 114 +-- truncate_limit: 100 +SELECT 'supeznova supernova'::tsvector @@ 'super:*'::tsquery AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'supeznova supernova'::tsvector @@ 'super:*'::tsquery AS \"true\"" +== 115 +-- truncate_limit: 100 +--phrase search +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 2' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 2' AS \"true\"" +== 116 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 2' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 2' AS \"false\"" +== 117 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 3' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 3' AS \"false\"" +== 118 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 3' AS \"true\"" +== 119 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 1 2') @@ '1 <3> 2' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 1 2') @@ '1 <3> 2' AS \"true\"" +== 120 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 11 3') @@ '1 <-> 3' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 11 3') @@ '1 <-> 3' AS \"false\"" +== 121 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 11 3') @@ '1:* <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 11 3') @@ '1:* <-> 3' AS \"true\"" +== 122 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> 2 <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> 2 <-> 3' AS \"true\"" +== 123 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 3 4') @@ '(1 <-> 2) <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 4') @@ '(1 <-> 2) <-> 3' AS \"true\"" +== 124 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> (2 <-> 3)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> (2 <-> 3)' AS \"true\"" +== 125 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <2> (2 <-> 3)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <2> (2 <-> 3)' AS \"false\"" +== 126 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '(1 <-> 2) <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '(1 <-> 2) <-> 3' AS \"true\"" +== 127 +-- truncate_limit: 100 +SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '1 <-> 2 <-> 3' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '1 <-> 2 <-> 3' AS \"true\"" +== 128 +-- truncate_limit: 100 +-- without position data, phrase search does not match +SELECT strip(to_tsvector('simple', '1 2 3 4')) @@ '1 <-> 2 <-> 3' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip(to_tsvector('simple', '1 2 3 4')) @@ '1 <-> 2 <-> 3' AS \"false\"" +== 129 +-- truncate_limit: 100 +select to_tsvector('simple', 'q x q y') @@ 'q <-> (x & y)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'q x q y') @@ 'q <-> (x & y)' AS \"false\"" +== 130 +-- truncate_limit: 100 +select to_tsvector('simple', 'q x') @@ 'q <-> (x | y <-> z)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'q x') @@ 'q <-> (x | y <-> z)' AS \"true\"" +== 131 +-- truncate_limit: 100 +select to_tsvector('simple', 'q y') @@ 'q <-> (x | y <-> z)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'q y') @@ 'q <-> (x | y <-> z)' AS \"false\"" +== 132 +-- truncate_limit: 100 +select to_tsvector('simple', 'q y z') @@ 'q <-> (x | y <-> z)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'q y z') @@ 'q <-> (x | y <-> z)' AS \"true\"" +== 133 +-- truncate_limit: 100 +select to_tsvector('simple', 'q y x') @@ 'q <-> (x | y <-> z)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'q y x') @@ 'q <-> (x | y <-> z)' AS \"false\"" +== 134 +-- truncate_limit: 100 +select to_tsvector('simple', 'q x y') @@ 'q <-> (x | y <-> z)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'q x y') @@ 'q <-> (x | y <-> z)' AS \"true\"" +== 135 +-- truncate_limit: 100 +select to_tsvector('simple', 'q x') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'q x') @@ '(x | y <-> z) <-> q' AS \"false\"" +== 136 +-- truncate_limit: 100 +select to_tsvector('simple', 'x q') @@ '(x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x q') @@ '(x | y <-> z) <-> q' AS \"true\"" +== 137 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q') @@ '(x | y <-> z) <-> q' AS \"false\"" +== 138 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y z') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y z') @@ '(x | y <-> z) <-> q' AS \"false\"" +== 139 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y z q') @@ '(x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y z q') @@ '(x | y <-> z) <-> q' AS \"true\"" +== 140 +-- truncate_limit: 100 +select to_tsvector('simple', 'y z q') @@ '(x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'y z q') @@ '(x | y <-> z) <-> q' AS \"true\"" +== 141 +-- truncate_limit: 100 +select to_tsvector('simple', 'y y q') @@ '(x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'y y q') @@ '(x | y <-> z) <-> q' AS \"false\"" +== 142 +-- truncate_limit: 100 +select to_tsvector('simple', 'y y q') @@ '(!x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'y y q') @@ '(!x | y <-> z) <-> q' AS \"true\"" +== 143 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q') @@ '(!x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q') @@ '(!x | y <-> z) <-> q' AS \"true\"" +== 144 +-- truncate_limit: 100 +select to_tsvector('simple', 'y y q') @@ '(x | y <-> !z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'y y q') @@ '(x | y <-> !z) <-> q' AS \"true\"" +== 145 +-- truncate_limit: 100 +select to_tsvector('simple', 'x q') @@ '(x | y <-> !z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x q') @@ '(x | y <-> !z) <-> q' AS \"true\"" +== 146 +-- truncate_limit: 100 +select to_tsvector('simple', 'x q') @@ '(!x | y <-> z) <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x q') @@ '(!x | y <-> z) <-> q' AS \"false\"" +== 147 +-- truncate_limit: 100 +select to_tsvector('simple', 'z q') @@ '(!x | y <-> z) <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'z q') @@ '(!x | y <-> z) <-> q' AS \"true\"" +== 148 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q') @@ '(!x | y) <-> y <-> q' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q') @@ '(!x | y) <-> y <-> q' AS \"false\"" +== 149 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q') @@ '(!x | !y) <-> y <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q') @@ '(!x | !y) <-> y <-> q' AS \"true\"" +== 150 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q') @@ '(x | !y) <-> y <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q') @@ '(x | !y) <-> y <-> q' AS \"true\"" +== 151 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q') @@ '(x | !!z) <-> y <-> q' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q') @@ '(x | !!z) <-> y <-> q' AS \"true\"" +== 152 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q y') @@ '!x <-> y' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q y') @@ '!x <-> y' AS \"true\"" +== 153 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q y') @@ '!x <-> !y' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q y') @@ '!x <-> !y' AS \"true\"" +== 154 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q y') @@ '!x <-> !!y' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q y') @@ '!x <-> !!y' AS \"true\"" +== 155 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q y') @@ '!(x <-> y)' AS "false" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q y') @@ '!(x <-> y)' AS \"false\"" +== 156 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q y') @@ '!(x <2> y)' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q y') @@ '!(x <2> y)' AS \"true\"" +== 157 +-- truncate_limit: 100 +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> y' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> y' AS \"false\"" +== 158 +-- truncate_limit: 100 +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !y' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !y' AS \"false\"" +== 159 +-- truncate_limit: 100 +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !!y' AS "false" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !!y' AS \"false\"" +== 160 +-- truncate_limit: 100 +select strip(to_tsvector('simple', 'x y q y')) @@ '!(x <-> y)' AS "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip(to_tsvector('simple', 'x y q y')) @@ '!(x <-> y)' AS \"true\"" +== 161 +-- truncate_limit: 100 +select strip(to_tsvector('simple', 'x y q y')) @@ '!(x <2> y)' AS "true" +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip(to_tsvector('simple', 'x y q y')) @@ '!(x <2> y)' AS \"true\"" +== 162 +-- truncate_limit: 100 +select to_tsvector('simple', 'x y q y') @@ '!foo' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', 'x y q y') @@ '!foo' AS \"true\"" +== 163 +-- truncate_limit: 100 +select to_tsvector('simple', '') @@ '!foo' AS "true" +-- +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT to_tsvector('simple', '') @@ '!foo' AS \"true\"" +== 164 +-- truncate_limit: 100 +--ranking +SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a | s')" +== 165 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s')" +== 166 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s:*') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s:*')" +== 167 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | sa:*') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | sa:*')" +== 168 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a | s')" +== 169 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a | s')" +== 170 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a & s')" +== 171 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a & s')" +== 172 +-- truncate_limit: 100 +SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank" function="ts_rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a & s')" +== 173 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a | s')" +== 174 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s')" +== 175 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s:*')" +== 176 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | sa:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | sa:*')" +== 177 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:3C sab:2c d g'::tsvector, 'a | sa:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:3C sab:2c d g'::tsvector, 'a | sa:*')" +== 178 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a | s')" +== 179 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a | s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a | s')" +== 180 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a & s')" +== 181 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a & s')" +== 182 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a & s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a & s')" +== 183 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2A d g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2A d g'::tsvector, 'a <-> s')" +== 184 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a <-> s')" +== 185 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a <-> s')" +== 186 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2 d:2A g'::tsvector, 'a <-> s') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2 d:2A g'::tsvector, 'a <-> s')" +== 187 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 s:2,3A d:2A g'::tsvector, 'a <2> s:A') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 s:2,3A d:2A g'::tsvector, 'a <2> s:A')" +== 188 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 b:2 s:3A d:2A g'::tsvector, 'a <2> s:A') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 b:2 s:3A d:2A g'::tsvector, 'a <2> s:A')" +== 189 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:2D sb:2A g'::tsvector, 'a <-> s:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:2D sb:2A g'::tsvector, 'a <-> s:*')" +== 190 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:*') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:*')" +== 191 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:A') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:A')" +== 192 +-- truncate_limit: 100 +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:B') +-- +FUNCTION: name="ts_rank_cd" function="ts_rank_cd" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:B')" +== 193 +-- truncate_limit: 100 +SELECT 'a:1 b:2'::tsvector @@ 'a <-> b'::tsquery AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:2'::tsvector @@ 'a <-> b'::tsquery AS \"true\"" +== 194 +-- truncate_limit: 100 +SELECT 'a:1 b:2'::tsvector @@ 'a <0> b'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:2'::tsvector @@ 'a <0> b'::tsquery AS \"false\"" +== 195 +-- truncate_limit: 100 +SELECT 'a:1 b:2'::tsvector @@ 'a <1> b'::tsquery AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:2'::tsvector @@ 'a <1> b'::tsquery AS \"true\"" +== 196 +-- truncate_limit: 100 +SELECT 'a:1 b:2'::tsvector @@ 'a <2> b'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:2'::tsvector @@ 'a <2> b'::tsquery AS \"false\"" +== 197 +-- truncate_limit: 100 +SELECT 'a:1 b:3'::tsvector @@ 'a <-> b'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:3'::tsvector @@ 'a <-> b'::tsquery AS \"false\"" +== 198 +-- truncate_limit: 100 +SELECT 'a:1 b:3'::tsvector @@ 'a <0> b'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:3'::tsvector @@ 'a <0> b'::tsquery AS \"false\"" +== 199 +-- truncate_limit: 100 +SELECT 'a:1 b:3'::tsvector @@ 'a <1> b'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:3'::tsvector @@ 'a <1> b'::tsquery AS \"false\"" +== 200 +-- truncate_limit: 100 +SELECT 'a:1 b:3'::tsvector @@ 'a <2> b'::tsquery AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:3'::tsvector @@ 'a <2> b'::tsquery AS \"true\"" +== 201 +-- truncate_limit: 100 +SELECT 'a:1 b:3'::tsvector @@ 'a <3> b'::tsquery AS "false" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:3'::tsvector @@ 'a <3> b'::tsquery AS \"false\"" +== 202 +-- truncate_limit: 100 +SELECT 'a:1 b:3'::tsvector @@ 'a <0> a:*'::tsquery AS "true" +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'a:1 b:3'::tsvector @@ 'a <0> a:*'::tsquery AS \"true\"" +== 203 +-- truncate_limit: 100 +-- tsvector editing operations + +SELECT strip('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd'::tsvector) +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd'::tsvector)" +== 204 +-- truncate_limit: 100 +SELECT strip('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector)" +== 205 +-- truncate_limit: 100 +SELECT strip('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="strip" function="strip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT strip('base hidden rebel spaceship strike'::tsvector)" +== 206 +-- truncate_limit: 100 +SELECT ts_delete(to_tsvector('english', 'Rebel spaceships, striking from a hidden base'), 'spaceship') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +FUNCTION: name="to_tsvector" function="to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 207 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'base') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'base')" +== 208 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bas') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bas')" +== 209 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bases') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bases')" +== 210 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'spaceship') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 211 +-- truncate_limit: 100 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, 'spaceship') +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, 'spaceship')" +== 212 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceship','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 213 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceships','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 214 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceshi','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 215 +-- truncate_limit: 100 +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceship','leya','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 216 +-- truncate_limit: 100 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 217 +-- truncate_limit: 100 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel','rebel']) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 218 +-- truncate_limit: 100 +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel', '', NULL]) +-- +FUNCTION: name="ts_delete" function="ts_delete" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 219 +-- truncate_limit: 100 +SELECT unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector)" +== 220 +-- truncate_limit: 100 +SELECT unnest('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unnest('base hidden rebel spaceship strike'::tsvector)" +== 221 +-- truncate_limit: 100 +SELECT * FROM unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector)" +== 222 +-- truncate_limit: 100 +SELECT * FROM unnest('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unnest('base hidden rebel spaceship strike'::tsvector)" +== 223 +-- truncate_limit: 100 +SELECT lexeme, positions[1] from unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="unnest" function="unnest" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector)" +== 224 +-- truncate_limit: 100 +SELECT tsvector_to_array('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector) +-- +FUNCTION: name="tsvector_to_array" function="tsvector_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tsvector_to_array('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector)" +== 225 +-- truncate_limit: 100 +SELECT tsvector_to_array('base hidden rebel spaceship strike'::tsvector) +-- +FUNCTION: name="tsvector_to_array" function="tsvector_to_array" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT tsvector_to_array('base hidden rebel spaceship strike'::tsvector)" +== 226 +-- truncate_limit: 100 +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship','strike']) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_tsvector(ARRAY['base', 'hidden', 'rebel', 'spaceship', 'strike'])" +== 227 +-- truncate_limit: 100 +-- null and empty string are disallowed, since we mustn't make an empty lexeme +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship', NULL]) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_tsvector(ARRAY['base', 'hidden', 'rebel', 'spaceship', NULL])" +== 228 +-- truncate_limit: 100 +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship', '']) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_tsvector(ARRAY['base', 'hidden', 'rebel', 'spaceship', ''])" +== 229 +-- truncate_limit: 100 +-- array_to_tsvector must sort and de-dup +SELECT array_to_tsvector(ARRAY['foo','bar','baz','bar']) +-- +FUNCTION: name="array_to_tsvector" function="array_to_tsvector" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT array_to_tsvector(ARRAY['foo', 'bar', 'baz', 'bar'])" +== 230 +-- truncate_limit: 100 +SELECT setweight('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd zxc:81,567,222A'::tsvector, 'c') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setweight('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd zxc:81,567,222A'::tsvector, 'c')" +== 231 +-- truncate_limit: 100 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c')" +== 232 +-- truncate_limit: 100 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}')" +== 233 +-- truncate_limit: 100 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}')" +== 234 +-- truncate_limit: 100 +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a,zxc}') +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a,zxc}')" +== 235 +-- truncate_limit: 100 +SELECT setweight('a asd w:5,6,12B,13A zxc'::tsvector, 'c', ARRAY['a', 'zxc', '', NULL]) +-- +FUNCTION: name="setweight" function="setweight" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT setweight('a asd w:5,6,12B,13A zxc'::tsvector, 'c', ARRAY['a', 'zxc', '', NULL])" +== 236 +-- truncate_limit: 100 +SELECT ts_filter('base:7A empir:17 evil:15 first:11 galact:16 hidden:6A rebel:1A spaceship:2A strike:3A victori:12 won:9'::tsvector, '{a}') +-- +FUNCTION: name="ts_filter" function="ts_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 237 +-- truncate_limit: 100 +SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a}') +-- +FUNCTION: name="ts_filter" function="ts_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a}')" +== 238 +-- truncate_limit: 100 +SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a,b,NULL}') +-- +FUNCTION: name="ts_filter" function="ts_filter" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a,b,NULL}')" diff --git a/parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json new file mode 100644 index 0000000..c2deed3 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json @@ -0,0 +1,110 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/tuplesort.test b/parser/testdata/summary_truncate/postgres_regress/tuplesort.test new file mode 100644 index 0000000..d689e3c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/tuplesort.test @@ -0,0 +1,869 @@ +== 001 +-- truncate_limit: 100 +-- only use parallelism when explicitly intending to do so +SET max_parallel_maintenance_workers = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_maintenance_workers TO 0" +== 002 +-- truncate_limit: 100 +SET max_parallel_workers = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers TO 0" +== 003 +-- truncate_limit: 100 +-- A table with contents that, when sorted, triggers abbreviated +-- key aborts. One easy way to achieve that is to use uuids that all +-- have the same prefix, as abbreviated keys for uuids just use the +-- first sizeof(Datum) bytes. +CREATE TEMP TABLE abbrev_abort_uuids ( + id serial not null, + abort_increasing uuid, + abort_decreasing uuid, + noabort_increasing uuid, + noabort_decreasing uuid) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE abbrev_abort_uuids (id serial NOT NULL, abort_increasing uuid, abort_decre..." +== 004 +-- truncate_limit: 100 +INSERT INTO abbrev_abort_uuids (abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing) + SELECT + ('00000000-0000-0000-0000-'||to_char(g.i, '000000000000FM'))::uuid abort_increasing, + ('00000000-0000-0000-0000-'||to_char(20000 - g.i, '000000000000FM'))::uuid abort_decreasing, + (to_char(g.i % 10009, '00000000FM')||'-0000-0000-0000-'||to_char(g.i, '000000000000FM'))::uuid noabort_increasing, + (to_char(((20000 - g.i) % 10009), '00000000FM')||'-0000-0000-0000-'||to_char(20000 - g.i, '000000000000FM'))::uuid noabort_decreasing + FROM generate_series(0, 20000, 1) g(i) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO abbrev_abort_uuids (...) SELECT ... FROM generate_series(0, 20000, 1) g(i)" +== 005 +-- truncate_limit: 100 +-- and a few NULLs +INSERT INTO abbrev_abort_uuids(id) VALUES(0) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO abbrev_abort_uuids (id) VALUES (0)" +== 006 +-- truncate_limit: 100 +INSERT INTO abbrev_abort_uuids DEFAULT VALUES +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO abbrev_abort_uuids DEFAULT VALUES" +== 007 +-- truncate_limit: 100 +INSERT INTO abbrev_abort_uuids DEFAULT VALUES +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO abbrev_abort_uuids DEFAULT VALUES" +== 008 +-- truncate_limit: 100 +-- add just a few duplicates +INSERT INTO abbrev_abort_uuids (abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing) + SELECT abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing + FROM abbrev_abort_uuids + WHERE (id < 10 OR id > 19990) AND id % 3 = 0 AND abort_increasing is not null +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DML +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="abort_increasing" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO abbrev_abort_uuids (...) SELECT ... FROM abbrev_abort_uuids WHERE ..." +== 009 +-- truncate_limit: 100 +---- +-- Check sort node uses of tuplesort wrt. abbreviated keys +---- + +-- plain sort triggering abbreviated abort +SELECT abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY abort_increasing OFFSET 20000 - 4" +== 010 +-- truncate_limit: 100 +SELECT abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing NULLS FIRST OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY abort_decreasing NULLS FIRST OFFSET 20000 - 4" +== 011 +-- truncate_limit: 100 +-- plain sort not triggering abbreviated abort +SELECT noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY noabort_increasing OFFSET 20000 - 4" +== 012 +-- truncate_limit: 100 +SELECT noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing NULLS FIRST OFFSET 20000 - 4 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY noabort_decreasing NULLS FIRST OFFSET 20000 - 4" +== 013 +-- truncate_limit: 100 +-- bounded sort (disables abbreviated keys) +SELECT abort_increasing, noabort_increasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5" +== 014 +-- truncate_limit: 100 +SELECT abort_increasing, noabort_increasing FROM abbrev_abort_uuids ORDER BY noabort_increasing NULLS FIRST LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY noabort_increasing NULLS FIRST LIMIT 5" +== 015 +-- truncate_limit: 100 +---- +-- Check index creation uses of tuplesort wrt. abbreviated keys +---- + +-- index creation using abbreviated keys successfully +CREATE INDEX abbrev_abort_uuids__noabort_increasing_idx ON abbrev_abort_uuids (noabort_increasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX abbrev_abort_uuids__noabort_increasing_idx ON abbrev_abort_uuids USING btree (noabor..." +== 016 +-- truncate_limit: 100 +CREATE INDEX abbrev_abort_uuids__noabort_decreasing_idx ON abbrev_abort_uuids (noabort_decreasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX abbrev_abort_uuids__noabort_decreasing_idx ON abbrev_abort_uuids USING btree (noabor..." +== 017 +-- truncate_limit: 100 +-- verify +EXPLAIN (COSTS OFF) +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORD..." +== 018 +-- truncate_limit: 100 +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY noabort_increasing LIMIT 5" +== 019 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORD..." +== 020 +-- truncate_limit: 100 +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY noabort_decreasing LIMIT 5" +== 021 +-- truncate_limit: 100 +-- index creation using abbreviated keys, hitting abort +CREATE INDEX abbrev_abort_uuids__abort_increasing_idx ON abbrev_abort_uuids (abort_increasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX abbrev_abort_uuids__abort_increasing_idx ON abbrev_abort_uuids USING btree (abort_in..." +== 022 +-- truncate_limit: 100 +CREATE INDEX abbrev_abort_uuids__abort_decreasing_idx ON abbrev_abort_uuids (abort_decreasing) +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX abbrev_abort_uuids__abort_decreasing_idx ON abbrev_abort_uuids USING btree (abort_de..." +== 023 +-- truncate_limit: 100 +-- verify +EXPLAIN (COSTS OFF) +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER B..." +== 024 +-- truncate_limit: 100 +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5" +== 025 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER B..." +== 026 +-- truncate_limit: 100 +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY abort_decreasing LIMIT 5" +== 027 +-- truncate_limit: 100 +---- +-- Check CLUSTER uses of tuplesort wrt. abbreviated keys +---- + +-- when aborting, increasing order +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 028 +-- truncate_limit: 100 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO FALSE" +== 029 +-- truncate_limit: 100 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_increasing_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_increasing_idx" +== 030 +-- truncate_limit: 100 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid LIMIT 5" +== 031 +-- truncate_limit: 100 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid DESC LIMIT 5" +== 032 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 033 +-- truncate_limit: 100 +-- when aborting, decreasing order +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 034 +-- truncate_limit: 100 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO FALSE" +== 035 +-- truncate_limit: 100 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_decreasing_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_decreasing_idx" +== 036 +-- truncate_limit: 100 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid LIMIT 5" +== 037 +-- truncate_limit: 100 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid DESC LIMIT 5" +== 038 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 039 +-- truncate_limit: 100 +-- when not aborting, increasing order +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 040 +-- truncate_limit: 100 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO FALSE" +== 041 +-- truncate_limit: 100 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_increasing_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_increasing_idx" +== 042 +-- truncate_limit: 100 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid LIMIT 5" +== 043 +-- truncate_limit: 100 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid DESC LIMIT 5" +== 044 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 045 +-- truncate_limit: 100 +-- when no aborting, decreasing order +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 046 +-- truncate_limit: 100 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO FALSE" +== 047 +-- truncate_limit: 100 +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_decreasing_idx +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_decreasing_idx" +== 048 +-- truncate_limit: 100 +-- head +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid LIMIT 5" +== 049 +-- truncate_limit: 100 +-- tail +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5 +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM abbrev_abort_uuids ORDER BY ctid DESC LIMIT 5" +== 050 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 051 +-- truncate_limit: 100 +---- +-- test sorting of large datums VALUES +---- + +-- Ensure the order is correct and values look intact +SELECT LEFT(a,10),b FROM + (VALUES(REPEAT('a', 512 * 1024),1),(REPEAT('b', 512 * 1024),2)) v(a,b) +ORDER BY v.a DESC +-- +FUNCTION: name="left" function="left" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT \"left\"(a, 10), b FROM (VALUES (...)) v(a, b) ORDER BY v.a DESC" +== 052 +-- truncate_limit: 100 +---- +-- test forward and backward scans for in-memory and disk based tuplesort +---- + +-- in-memory +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 053 +-- truncate_limit: 100 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO FALSE" +== 054 +-- truncate_limit: 100 +-- unfortunately can't show analyze output confirming sort method, +-- the memory used output wouldn't be stable +EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids..." +== 055 +-- truncate_limit: 100 +DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_de..." +== 056 +-- truncate_limit: 100 +-- first and second +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 057 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 058 +-- truncate_limit: 100 +-- scroll beyond beginning +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 059 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 060 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 061 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 062 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 063 +-- truncate_limit: 100 +-- scroll beyond end +FETCH LAST FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH LAST c" +== 064 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 065 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 066 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 067 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 068 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 069 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 070 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 071 +-- truncate_limit: 100 +-- disk based +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 072 +-- truncate_limit: 100 +SET LOCAL enable_indexscan = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_indexscan TO FALSE" +== 073 +-- truncate_limit: 100 +SET LOCAL work_mem = '100kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"100kB\"" +== 074 +-- truncate_limit: 100 +-- unfortunately can't show analyze output confirming sort method, +-- the memory used output wouldn't be stable +EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: ExplainStmt +STMT: DeclareCursorStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids..." +== 075 +-- truncate_limit: 100 +DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_de..." +== 076 +-- truncate_limit: 100 +-- first and second +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 077 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 078 +-- truncate_limit: 100 +-- scroll beyond beginning +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 079 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 080 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 081 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 082 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 083 +-- truncate_limit: 100 +-- scroll beyond end +FETCH LAST FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH LAST c" +== 084 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 085 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 086 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 087 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 088 +-- truncate_limit: 100 +FETCH BACKWARD FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH PRIOR c" +== 089 +-- truncate_limit: 100 +FETCH NEXT FROM c +-- +STMT: FetchStmt +TRUNCATED: "FETCH c" +== 090 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 091 +-- truncate_limit: 100 +---- +-- test tuplesort using both in-memory and disk sort +--- + +-- memory based +SELECT + -- fixed-width by-value datum + (array_agg(id ORDER BY id DESC NULLS FIRST))[0:5], + -- fixed-width by-ref datum + (array_agg(abort_increasing ORDER BY abort_increasing DESC NULLS LAST))[0:5], + -- variable-width datum + (array_agg(id::text ORDER BY id::text DESC NULLS LAST))[0:5], + -- fixed width by-value datum tuplesort + percentile_disc(0.99) WITHIN GROUP (ORDER BY id), + -- ensure state is shared + percentile_disc(0.01) WITHIN GROUP (ORDER BY id), + -- fixed width by-ref datum tuplesort + percentile_disc(0.8) WITHIN GROUP (ORDER BY abort_increasing), + -- variable width by-ref datum tuplesort + percentile_disc(0.2) WITHIN GROUP (ORDER BY id::text), + -- multi-column tuplesort + rank('00000000-0000-0000-0000-000000000000', '2', '2') WITHIN GROUP (ORDER BY noabort_increasing, id, id::text) +FROM ( + SELECT * FROM abbrev_abort_uuids + UNION ALL + SELECT NULL, NULL, NULL, NULL, NULL) s +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM abbrev_abort_uuids UNION ALL SELECT ...) s" +== 092 +-- truncate_limit: 100 +-- disk based (see also above) +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 093 +-- truncate_limit: 100 +SET LOCAL work_mem = '100kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"100kB\"" +== 094 +-- truncate_limit: 100 +SELECT + (array_agg(id ORDER BY id DESC NULLS FIRST))[0:5], + (array_agg(abort_increasing ORDER BY abort_increasing DESC NULLS LAST))[0:5], + (array_agg(id::text ORDER BY id::text DESC NULLS LAST))[0:5], + percentile_disc(0.99) WITHIN GROUP (ORDER BY id), + percentile_disc(0.01) WITHIN GROUP (ORDER BY id), + percentile_disc(0.8) WITHIN GROUP (ORDER BY abort_increasing), + percentile_disc(0.2) WITHIN GROUP (ORDER BY id::text), + rank('00000000-0000-0000-0000-000000000000', '2', '2') WITHIN GROUP (ORDER BY noabort_increasing, id, id::text) +FROM ( + SELECT * FROM abbrev_abort_uuids + UNION ALL + SELECT NULL, NULL, NULL, NULL, NULL) s +-- +TABLE: name="abbrev_abort_uuids" schema="" table="abbrev_abort_uuids" ctx=Select +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="percentile_disc" function="percentile_disc" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM abbrev_abort_uuids UNION ALL SELECT ...) s" +== 095 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 096 +-- truncate_limit: 100 +---- +-- test tuplesort mark/restore +--- + +CREATE TEMP TABLE test_mark_restore(col1 int, col2 int, col12 int) +-- +TABLE: name="test_mark_restore" schema="" table="test_mark_restore" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE test_mark_restore (col1 int, col2 int, col12 int)" +== 097 +-- truncate_limit: 100 +-- need a few duplicates for mark/restore to matter +INSERT INTO test_mark_restore(col1, col2, col12) + SELECT a.i, b.i, a.i * b.i FROM generate_series(1, 500) a(i), generate_series(1, 5) b(i) +-- +TABLE: name="test_mark_restore" schema="" table="test_mark_restore" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO test_mark_restore (...) SELECT ... FROM generate_series(1, 500) a(i), generate_series..." +== 098 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 099 +-- truncate_limit: 100 +SET LOCAL enable_nestloop = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_nestloop TO OFF" +== 100 +-- truncate_limit: 100 +SET LOCAL enable_hashjoin = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_hashjoin TO OFF" +== 101 +-- truncate_limit: 100 +SET LOCAL enable_material = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL enable_material TO OFF" +== 102 +-- truncate_limit: 100 +-- set query into variable once, to avoid repetition of the fairly long query +SELECT $$ + SELECT col12, count(distinct a.col1), count(distinct a.col2), count(distinct b.col1), count(distinct b.col2), count(*) + FROM test_mark_restore a + JOIN test_mark_restore b USING(col12) + GROUP BY 1 + HAVING count(*) > 1 + ORDER BY 2 DESC, 1 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC + LIMIT 10 +$$ AS qry +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 103 +-- truncate_limit: 100 +-- test mark/restore with in-memory sorts +EXPLAIN (COSTS OFF) :qry +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 104 +-- truncate_limit: 100 +-- test mark/restore with on-disk sorts +SET LOCAL work_mem = '100kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL work_mem TO \"100kB\"" +== 105 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) :qry +-- +ERROR: syntax error at or near ":" +CURSORPOS: 21 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 106 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" diff --git a/parser/testdata/summary_truncate/postgres_regress/txid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/txid.metadata.json new file mode 100644 index 0000000..c7ce9e3 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/txid.metadata.json @@ -0,0 +1,51 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/txid.test b/parser/testdata/summary_truncate/postgres_regress/txid.test new file mode 100644 index 0000000..f250605 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/txid.test @@ -0,0 +1,373 @@ +== 001 +-- truncate_limit: 100 +-- txid_snapshot data type and related functions +-- Note: these are backward-compatibility functions and types, and have been +-- replaced by new xid8-based variants. See xid.sql. The txid variants will +-- be removed in a future release. + +-- i/o +select '12:13:'::txid_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:13:'::txid_snapshot" +== 002 +-- truncate_limit: 100 +select '12:18:14,16'::txid_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:18:14,16'::txid_snapshot" +== 003 +-- truncate_limit: 100 +select '12:16:14,14'::txid_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:16:14,14'::txid_snapshot" +== 004 +-- truncate_limit: 100 +-- errors +select '31:12:'::txid_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '31:12:'::txid_snapshot" +== 005 +-- truncate_limit: 100 +select '0:1:'::txid_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0:1:'::txid_snapshot" +== 006 +-- truncate_limit: 100 +select '12:13:0'::txid_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:13:0'::txid_snapshot" +== 007 +-- truncate_limit: 100 +select '12:16:14,13'::txid_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:16:14,13'::txid_snapshot" +== 008 +-- truncate_limit: 100 +create temp table snapshot_test ( + nr integer, + snap txid_snapshot +) +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE snapshot_test (nr int, snap txid_snapshot)" +== 009 +-- truncate_limit: 100 +insert into snapshot_test values (1, '12:13:') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (1, '12:13:')" +== 010 +-- truncate_limit: 100 +insert into snapshot_test values (2, '12:20:13,15,18') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (2, '12:20:13,15,18')" +== 011 +-- truncate_limit: 100 +insert into snapshot_test values (3, '100001:100009:100005,100007,100008') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (3, '100001:100009:100005,100007,100008')" +== 012 +-- truncate_limit: 100 +insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (...)" +== 013 +-- truncate_limit: 100 +select snap from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT snap FROM snapshot_test ORDER BY nr" +== 014 +-- truncate_limit: 100 +select txid_snapshot_xmin(snap), + txid_snapshot_xmax(snap), + txid_snapshot_xip(snap) +from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="txid_snapshot_xmin" function="txid_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="txid_snapshot_xmax" function="txid_snapshot_xmax" schema="" ctx=Call +FUNCTION: name="txid_snapshot_xip" function="txid_snapshot_xip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM snapshot_test ORDER BY nr" +== 015 +-- truncate_limit: 100 +select id, txid_visible_in_snapshot(id, snap) +from snapshot_test, generate_series(11, 21) id +where nr = 2 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM snapshot_test, generate_series(11, 21) id WHERE nr = 2" +== 016 +-- truncate_limit: 100 +-- test bsearch +select id, txid_visible_in_snapshot(id, snap) +from snapshot_test, generate_series(90, 160) id +where nr = 4 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM snapshot_test, generate_series(90, 160) id WHERE nr = 4" +== 017 +-- truncate_limit: 100 +-- test current values also +select txid_current() >= txid_snapshot_xmin(txid_current_snapshot()) +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +FUNCTION: name="txid_snapshot_xmin" function="txid_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="txid_current_snapshot" function="txid_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_current() >= txid_snapshot_xmin(txid_current_snapshot())" +== 018 +-- truncate_limit: 100 +-- we can't assume current is always less than xmax, however + +select txid_visible_in_snapshot(txid_current(), txid_current_snapshot()) +-- +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +FUNCTION: name="txid_current_snapshot" function="txid_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_visible_in_snapshot(txid_current(), txid_current_snapshot())" +== 019 +-- truncate_limit: 100 +-- test 64bitness + +select txid_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1000100010001000:1000100010001100:1000100010001012,1000100010001013'::txid_snapshot" +== 020 +-- truncate_limit: 100 +select txid_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 021 +-- truncate_limit: 100 +select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="txid_visible_in_snapshot" function="txid_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 022 +-- truncate_limit: 100 +-- test 64bit overflow +SELECT txid_snapshot '1:9223372036854775807:3' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1:9223372036854775807:3'::txid_snapshot" +== 023 +-- truncate_limit: 100 +SELECT txid_snapshot '1:9223372036854775808:3' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1:9223372036854775808:3'::txid_snapshot" +== 024 +-- truncate_limit: 100 +-- test txid_current_if_assigned +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 025 +-- truncate_limit: 100 +SELECT txid_current_if_assigned() IS NULL +-- +FUNCTION: name="txid_current_if_assigned" function="txid_current_if_assigned" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_current_if_assigned() IS NULL" +== 026 +-- truncate_limit: 100 +SELECT txid_current() +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_current()" +== 027 +-- truncate_limit: 100 +SELECT txid_current_if_assigned() IS NOT DISTINCT FROM BIGINT :'txid_current' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 63 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 028 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 029 +-- truncate_limit: 100 +-- test xid status functions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 030 +-- truncate_limit: 100 +SELECT txid_current() AS committed +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_current() AS committed" +== 031 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 032 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 033 +-- truncate_limit: 100 +SELECT txid_current() AS rolledback +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_current() AS rolledback" +== 034 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 035 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 036 +-- truncate_limit: 100 +SELECT txid_current() AS inprogress +-- +FUNCTION: name="txid_current" function="txid_current" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_current() AS inprogress" +== 037 +-- truncate_limit: 100 +SELECT txid_status(:committed) AS committed +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 038 +-- truncate_limit: 100 +SELECT txid_status(:rolledback) AS rolledback +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 039 +-- truncate_limit: 100 +SELECT txid_status(:inprogress) AS inprogress +-- +ERROR: syntax error at or near ":" +CURSORPOS: 20 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 040 +-- truncate_limit: 100 +SELECT txid_status(1) +-- +FUNCTION: name="txid_status" function="txid_status" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_status(1)" +== 041 +-- truncate_limit: 100 +-- BootstrapTransactionId is always committed +SELECT txid_status(2) +-- +FUNCTION: name="txid_status" function="txid_status" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_status(2)" +== 042 +-- truncate_limit: 100 +-- FrozenTransactionId is always committed +SELECT txid_status(3) +-- +FUNCTION: name="txid_status" function="txid_status" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT txid_status(3)" +== 043 +-- truncate_limit: 100 +-- in regress testing FirstNormalTransactionId will always be behind oldestXmin + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 044 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 045 +-- truncate_limit: 100 +CREATE FUNCTION test_future_xid_status(bigint) +RETURNS void +LANGUAGE plpgsql +AS +$$ +BEGIN + PERFORM txid_status($1); + RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected'; +EXCEPTION + WHEN invalid_parameter_value THEN + RAISE NOTICE 'Got expected error for xid in the future'; +END; +$$ +-- +FUNCTION: name="test_future_xid_status" function="test_future_xid_status" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_future_xid_status(bigint) RETURNS void LANGUAGE plpgsql AS $$\nBEGIN\n PERFOR..." +== 046 +-- truncate_limit: 100 +SELECT test_future_xid_status(:inprogress + 10000) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 31 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 047 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json new file mode 100644 index 0000000..6a71114 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json @@ -0,0 +1,65 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/type_sanity.test b/parser/testdata/summary_truncate/postgres_regress/type_sanity.test new file mode 100644 index 0000000..666174a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/type_sanity.test @@ -0,0 +1,1302 @@ +== 001 +-- truncate_limit: 100 +|-- +-- TYPE_SANITY +-- Sanity checks for common errors in making type-related system tables: +-- pg_type, pg_class, pg_attribute, pg_range. +|-- +-- None of the SELECTs here should ever find any matching entries, +-- so the expected output is easy to maintain ;-). +-- A test failure indicates someone messed up an entry in the system tables. +|-- +-- NB: we assume the oidjoins test will have caught any dangling links, +-- that is OID or REGPROC fields that are not zero and do not match some +-- row in the linked-to table. However, if we want to enforce that a link +-- field can't be 0, we have to check it here. + +-- **************** pg_type **************** + +-- Look for illegal values in pg_type fields. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typnamespace = 0 OR + (t1.typlen <= 0 AND t1.typlen != -1 AND t1.typlen != -2) OR + (t1.typtype not in ('b', 'c', 'd', 'e', 'm', 'p', 'r')) OR + NOT t1.typisdefined OR + (t1.typalign not in ('c', 's', 'i', 'd')) OR + (t1.typstorage not in ('p', 'x', 'e', 'm')) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typnamespace" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typisdefined" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typstorage" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname FROM pg_type t1 WHERE ..." +== 002 +-- truncate_limit: 100 +-- Look for "pass by value" types that can't be passed by value. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typbyval AND + (t1.typlen != 1 OR t1.typalign != 'c') AND + (t1.typlen != 2 OR t1.typalign != 's') AND + (t1.typlen != 4 OR t1.typalign != 'i') AND + (t1.typlen != 8 OR t1.typalign != 'd') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typbyval" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typalign" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname FROM pg_type t1 WHERE ..." +== 003 +-- truncate_limit: 100 +-- Look for "toastable" types that aren't varlena. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typstorage != 'p' AND + (t1.typbyval OR t1.typlen != -1) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typstorage" +FILTER: schema="" table="t1" column="typbyval" +FILTER: schema="" table="t1" column="typlen" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname FROM pg_type t1 WHERE ..." +== 004 +-- truncate_limit: 100 +-- Look for complex types that do not have a typrelid entry, +-- or basic types that do. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE (t1.typtype = 'c' AND t1.typrelid = 0) OR + (t1.typtype != 'c' AND t1.typrelid != 0) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typrelid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typrelid" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname FROM pg_type t1 WHERE ..." +== 005 +-- truncate_limit: 100 +-- Look for types that should have an array type but don't. +-- Generally anything that's not a pseudotype should have an array type. +-- However, we do have a small number of exceptions. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typtype not in ('p') AND t1.typname NOT LIKE E'\\_%' + AND NOT EXISTS + (SELECT 1 FROM pg_type as t2 + WHERE t2.typname = ('_' || t1.typname)::name AND + t2.typelem = t1.oid and t1.typarray = t2.oid) +ORDER BY t1.oid +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typname" +FILTER: schema="" table="t2" column="typname" +FILTER: schema="" table="t1" column="typname" +FILTER: schema="" table="t2" column="typelem" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname FROM pg_type t1 WHERE ... ORDER BY t1.oid" +== 006 +-- truncate_limit: 100 +-- Make sure typarray points to a "true" array type of our own base +SELECT t1.oid, t1.typname as basetype, t2.typname as arraytype, + t2.typsubscript +FROM pg_type t1 LEFT JOIN pg_type t2 ON (t1.typarray = t2.oid) +WHERE t1.typarray <> 0 AND + (t2.oid IS NULL OR + t2.typsubscript <> 'array_subscript_handler'::regproc) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t2" column="typsubscript" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type t1 LEFT JOIN pg_type t2 ON t1.typarray = t2.oid WHERE ..." +== 007 +-- truncate_limit: 100 +-- Look for range types that do not have a pg_range entry +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typtype = 'r' AND + NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = t1.oid) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="" column="rngtypid" +FILTER: schema="" table="t1" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname FROM pg_type t1 WHERE ..." +== 008 +-- truncate_limit: 100 +-- Look for range types whose typalign isn't sufficient +SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign +FROM pg_type as t1 + LEFT JOIN pg_range as r ON rngtypid = t1.oid + LEFT JOIN pg_type as t2 ON rngsubtype = t2.oid +WHERE t1.typtype = 'r' AND + (t1.typalign != (CASE WHEN t2.typalign = 'd' THEN 'd'::"char" + ELSE 'i'::"char" END) + OR t2.oid IS NULL) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="t2" column="typalign" +FILTER: schema="" table="t2" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type t1 LEFT JOIN pg_range r ON rngtypid = t1.oid LEFT JOIN pg_type t2 ON rngs..." +== 009 +-- truncate_limit: 100 +-- Text conversion routines must be provided. + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE (t1.typinput = 0 OR t1.typoutput = 0) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="t1" column="typoutput" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname FROM pg_type t1 WHERE t1.typinput = 0 OR t1.typoutput = 0" +== 010 +-- truncate_limit: 100 +-- Check for bogus typinput routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND NOT + ((p1.pronargs = 1 AND p1.proargtypes[0] = 'cstring'::regtype) OR + (p1.pronargs = 2 AND p1.proargtypes[0] = 'cstring'::regtype AND + p1.proargtypes[1] = 'oid'::regtype) OR + (p1.pronargs = 3 AND p1.proargtypes[0] = 'cstring'::regtype AND + p1.proargtypes[1] = 'oid'::regtype AND + p1.proargtypes[2] = 'int4'::regtype)) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 011 +-- truncate_limit: 100 +-- As of 8.0, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.prorettype = t1.oid AND NOT p1.proretset) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ... ORDER BY 1" +== 012 +-- truncate_limit: 100 +-- Varlena array types will point to array_in +-- Exception as of 8.1: int2vector and oidvector have their own I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.oid = 'array_in'::regproc) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ... ORDER BY 1" +== 013 +-- truncate_limit: 100 +-- typinput routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 014 +-- truncate_limit: 100 +-- Composites, domains, enums, multiranges, ranges should all use the same input routines +SELECT DISTINCT typtype, typinput +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT typtype, typinput FROM pg_type t1 WHERE t1.typtype NOT IN ('b', 'p') ORDER BY 1" +== 015 +-- truncate_limit: 100 +-- Check for bogus typoutput routines + +-- As of 8.0, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (p1.pronargs = 1 AND + (p1.proargtypes[0] = t1.oid OR + (p1.oid = 'array_out'::regproc AND + t1.typelem != 0 AND t1.typlen = -1))) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ... ORDER BY 1" +== 016 +-- truncate_limit: 100 +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND NOT + (p1.prorettype = 'cstring'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 017 +-- truncate_limit: 100 +-- typoutput routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 018 +-- truncate_limit: 100 +-- Composites, enums, multiranges, ranges should all use the same output routines +SELECT DISTINCT typtype, typoutput +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'd', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT typtype, typoutput FROM pg_type t1 WHERE ... ORDER BY 1" +== 019 +-- truncate_limit: 100 +-- Domains should have same typoutput as their base types +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid +WHERE t1.typtype = 'd' AND t1.typoutput IS DISTINCT FROM t2.typoutput +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typoutput" +FILTER: schema="" table="t2" column="typoutput" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type t1 LEFT JOIN pg_type t2 ON t1.typbasetype = t2.oid WHERE ..." +== 020 +-- truncate_limit: 100 +-- Check for bogus typreceive routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND NOT + ((p1.pronargs = 1 AND p1.proargtypes[0] = 'internal'::regtype) OR + (p1.pronargs = 2 AND p1.proargtypes[0] = 'internal'::regtype AND + p1.proargtypes[1] = 'oid'::regtype) OR + (p1.pronargs = 3 AND p1.proargtypes[0] = 'internal'::regtype AND + p1.proargtypes[1] = 'oid'::regtype AND + p1.proargtypes[2] = 'int4'::regtype)) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="proargtypes" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 021 +-- truncate_limit: 100 +-- As of 7.4, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.prorettype = t1.oid AND NOT p1.proretset) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ... ORDER BY 1" +== 022 +-- truncate_limit: 100 +-- Varlena array types will point to array_recv +-- Exception as of 8.1: int2vector and oidvector have their own I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.oid = 'array_recv'::regproc) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="p1" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ... ORDER BY 1" +== 023 +-- truncate_limit: 100 +-- Suspicious if typreceive doesn't take same number of args as typinput +SELECT t1.oid, t1.typname, p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_type AS t1, pg_proc AS p1, pg_proc AS p2 +WHERE t1.typinput = p1.oid AND t1.typreceive = p2.oid AND + p1.pronargs != p2.pronargs +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "p2"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typinput" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p2" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p2" column="pronargs" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type t1, pg_proc p1, pg_proc p2 WHERE ..." +== 024 +-- truncate_limit: 100 +-- typreceive routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typreceive" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 025 +-- truncate_limit: 100 +-- Composites, domains, enums, multiranges, ranges should all use the same receive routines +SELECT DISTINCT typtype, typreceive +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT typtype, typreceive FROM pg_type t1 WHERE t1.typtype NOT IN ('b', 'p') ORDER BY 1" +== 026 +-- truncate_limit: 100 +-- Check for bogus typsend routines + +-- As of 7.4, this check finds refcursor, which is borrowing +-- other types' I/O routines +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (p1.pronargs = 1 AND + (p1.proargtypes[0] = t1.oid OR + (p1.oid = 'array_send'::regproc AND + t1.typelem != 0 AND t1.typlen = -1))) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ... ORDER BY 1" +== 027 +-- truncate_limit: 100 +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND NOT + (p1.prorettype = 'bytea'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 028 +-- truncate_limit: 100 +-- typsend routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 029 +-- truncate_limit: 100 +-- Composites, enums, multiranges, ranges should all use the same send routines +SELECT DISTINCT typtype, typsend +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'd', 'p') +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typtype" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT typtype, typsend FROM pg_type t1 WHERE t1.typtype NOT IN ('b', 'd', 'p') ORDER BY 1" +== 030 +-- truncate_limit: 100 +-- Domains should have same typsend as their base types +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid +WHERE t1.typtype = 'd' AND t1.typsend IS DISTINCT FROM t2.typsend +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typtype" +FILTER: schema="" table="t1" column="typsend" +FILTER: schema="" table="t2" column="typsend" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type t1 LEFT JOIN pg_type t2 ON t1.typbasetype = t2.oid WHERE ..." +== 031 +-- truncate_limit: 100 +-- Check for bogus typmodin routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodin = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'cstring[]'::regtype AND + p1.prorettype = 'int4'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodin" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 032 +-- truncate_limit: 100 +-- typmodin routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodin = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodin" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 033 +-- truncate_limit: 100 +-- Check for bogus typmodout routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodout = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'int4'::regtype AND + p1.prorettype = 'cstring'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodout" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 034 +-- truncate_limit: 100 +-- typmodout routines should not be volatile +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodout = p1.oid AND p1.provolatile NOT IN ('i', 's') +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typmodout" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="provolatile" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 035 +-- truncate_limit: 100 +-- Array types should have same typmodin/out as their element types + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typelem = t2.oid AND NOT + (t1.typmodin = t2.typmodin AND t1.typmodout = t2.typmodout) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t1" column="typmodin" +FILTER: schema="" table="t2" column="typmodin" +FILTER: schema="" table="t1" column="typmodout" +FILTER: schema="" table="t2" column="typmodout" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, t2.oid, t2.typname FROM pg_type t1, pg_type t2 WHERE ..." +== 036 +-- truncate_limit: 100 +-- Array types should have same typdelim as their element types + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typarray = t2.oid AND NOT (t1.typdelim = t2.typdelim) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t1" column="typdelim" +FILTER: schema="" table="t2" column="typdelim" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, t2.oid, t2.typname FROM pg_type t1, pg_type t2 WHERE ..." +== 037 +-- truncate_limit: 100 +-- Look for array types whose typalign isn't sufficient + +SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typarray = t2.oid AND + t2.typalign != (CASE WHEN t1.typalign = 'd' THEN 'd'::"char" + ELSE 'i'::"char" END) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +ALIAS: "t2"="pg_type" +FILTER: schema="" table="t1" column="typarray" +FILTER: schema="" table="t2" column="oid" +FILTER: schema="" table="t2" column="typalign" +FILTER: schema="" table="t1" column="typalign" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type t1, pg_type t2 WHERE ..." +== 038 +-- truncate_limit: 100 +-- Check for typelem set without a handler + +SELECT t1.oid, t1.typname, t1.typelem +FROM pg_type AS t1 +WHERE t1.typelem != 0 AND t1.typsubscript = 0 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typsubscript" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, t1.typelem FROM pg_type t1 WHERE t1.typelem <> 0 AND t1.typsubscript = 0" +== 039 +-- truncate_limit: 100 +-- Check for misuse of standard subscript handlers + +SELECT t1.oid, t1.typname, + t1.typelem, t1.typlen, t1.typbyval +FROM pg_type AS t1 +WHERE t1.typsubscript = 'array_subscript_handler'::regproc AND NOT + (t1.typelem != 0 AND t1.typlen = -1 AND NOT t1.typbyval) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsubscript" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typbyval" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, t1.typelem, t1.typlen, t1.typbyval FROM pg_type t1 WHERE ..." +== 040 +-- truncate_limit: 100 +SELECT t1.oid, t1.typname, + t1.typelem, t1.typlen, t1.typbyval +FROM pg_type AS t1 +WHERE t1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT + (t1.typelem != 0 AND t1.typlen > 0 AND NOT t1.typbyval) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typsubscript" +FILTER: schema="" table="t1" column="typelem" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="t1" column="typbyval" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, t1.typelem, t1.typlen, t1.typbyval FROM pg_type t1 WHERE ..." +== 041 +-- truncate_limit: 100 +-- Check for bogus typanalyze routines + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typanalyze = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'internal'::regtype AND + p1.prorettype = 'bool'::regtype AND NOT p1.proretset) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p1"="pg_proc" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="t1" column="typanalyze" +FILTER: schema="" table="p1" column="oid" +FILTER: schema="" table="p1" column="pronargs" +FILTER: schema="" table="p1" column="proargtypes" +FILTER: schema="" table="p1" column="prorettype" +FILTER: schema="" table="p1" column="proretset" +STMT: SelectStmt +TRUNCATED: "SELECT t1.oid, t1.typname, p1.oid, p1.proname FROM pg_type t1, pg_proc p1 WHERE ..." +== 042 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "d"="pg_type" +ALIAS: "t"="pg_type" +FILTER: schema="" table="d" column="typanalyze" +FILTER: schema="" table="t" column="typanalyze" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type d JOIN pg_type t ON d.typbasetype = t.oid WHERE d.typanalyze <> t.typanalyze" +== 043 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t"="pg_type" +FILTER: schema="" table="t" column="typbasetype" +FILTER: schema="" table="t" column="typanalyze" +FILTER: schema="" table="r" column="rngtypid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_type t LEFT JOIN pg_range r ON t.oid = r.rngtypid WHERE ..." +== 044 +-- truncate_limit: 100 +-- 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) != + (t.typsubscript = 'array_subscript_handler'::regproc) +ORDER BY 1 +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "t"="pg_type" +FILTER: schema="" table="t" column="typbasetype" +FILTER: schema="" table="t" column="typanalyze" +FILTER: schema="" table="t" column="typsubscript" +STMT: SelectStmt +TRUNCATED: "SELECT t.oid, t.typname, t.typanalyze FROM pg_type t WHERE ... ORDER BY 1" +== 045 +-- truncate_limit: 100 +-- **************** pg_class **************** + +-- Look for illegal values in pg_class fields + +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p', 'I') OR + relpersistence NOT IN ('p', 'u', 't') OR + relreplident NOT IN ('d', 'n', 'f', 'i') +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c1"="pg_class" +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relpersistence" +FILTER: schema="" table="" column="relreplident" +STMT: SelectStmt +TRUNCATED: "SELECT c1.oid, c1.relname FROM pg_class c1 WHERE ..." +== 046 +-- truncate_limit: 100 +-- All tables, indexes, partitioned indexes and matviews should have an +-- access method. +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE c1.relkind NOT IN ('S', 'v', 'f', 'c', 'p') and + c1.relam = 0 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c1"="pg_class" +FILTER: schema="" table="c1" column="relkind" +FILTER: schema="" table="c1" column="relam" +STMT: SelectStmt +TRUNCATED: "SELECT c1.oid, c1.relname FROM pg_class c1 WHERE ..." +== 047 +-- truncate_limit: 100 +-- Conversely, sequences, views, foreign tables, types and partitioned +-- tables shouldn't have them. +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE c1.relkind IN ('S', 'v', 'f', 'c', 'p') and + c1.relam != 0 +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c1"="pg_class" +FILTER: schema="" table="c1" column="relkind" +FILTER: schema="" table="c1" column="relam" +STMT: SelectStmt +TRUNCATED: "SELECT c1.oid, c1.relname FROM pg_class c1 WHERE ..." +== 048 +-- truncate_limit: 100 +-- Indexes and partitioned 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', 'I') and + pa.amtype != 'i' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +FILTER: schema="" table="pc" column="relkind" +FILTER: schema="" table="pa" column="amtype" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_am pa ON pc.relam = pa.oid WHERE ..." +== 049 +-- truncate_limit: 100 +-- 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' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_am" schema="" table="pg_am" ctx=Select +ALIAS: "pa"="pg_am" +ALIAS: "pc"="pg_class" +FILTER: schema="" table="pc" column="relkind" +FILTER: schema="" table="pa" column="amtype" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_class pc JOIN pg_am pa ON pc.relam = pa.oid WHERE ..." +== 050 +-- truncate_limit: 100 +-- **************** pg_attribute **************** + +-- Look for illegal values in pg_attribute fields + +SELECT a1.attrelid, a1.attname +FROM pg_attribute as a1 +WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR + a1.attcacheoff != -1 OR a1.attinhcount < 0 OR + (a1.attinhcount = 0 AND NOT a1.attislocal) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a1"="pg_attribute" +FILTER: schema="" table="a1" column="attrelid" +FILTER: schema="" table="a1" column="atttypid" +FILTER: schema="" table="a1" column="attnum" +FILTER: schema="" table="a1" column="attcacheoff" +FILTER: schema="" table="a1" column="attinhcount" +FILTER: schema="" table="a1" column="attinhcount" +FILTER: schema="" table="a1" column="attislocal" +STMT: SelectStmt +TRUNCATED: "SELECT a1.attrelid, a1.attname FROM pg_attribute a1 WHERE ..." +== 051 +-- truncate_limit: 100 +-- Cross-check attnum against parent relation + +SELECT a1.attrelid, a1.attname, c1.oid, c1.relname +FROM pg_attribute AS a1, pg_class AS c1 +WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "a1"="pg_attribute" +ALIAS: "c1"="pg_class" +FILTER: schema="" table="a1" column="attrelid" +FILTER: schema="" table="c1" column="oid" +FILTER: schema="" table="a1" column="attnum" +FILTER: schema="" table="c1" column="relnatts" +STMT: SelectStmt +TRUNCATED: "SELECT a1.attrelid, a1.attname, c1.oid, c1.relname FROM pg_attribute a1, pg_class c1 WHERE ..." +== 052 +-- truncate_limit: 100 +-- Detect missing pg_attribute entries: should have as many non-system +-- attributes as parent relation expects + +SELECT c1.oid, c1.relname +FROM pg_class AS c1 +WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1 + WHERE a1.attrelid = c1.oid AND a1.attnum > 0) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a1"="pg_attribute" +ALIAS: "c1"="pg_class" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="c1" column="relnatts" +FILTER: schema="" table="a1" column="attrelid" +FILTER: schema="" table="c1" column="oid" +FILTER: schema="" table="a1" column="attnum" +STMT: SelectStmt +TRUNCATED: "SELECT c1.oid, c1.relname FROM pg_class c1 WHERE ..." +== 053 +-- truncate_limit: 100 +-- 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 a1.attrelid, a1.attname, t1.oid, t1.typname +FROM pg_attribute AS a1, pg_type AS t1 +WHERE a1.atttypid = t1.oid AND + (a1.attlen != t1.typlen OR + a1.attalign != t1.typalign OR + a1.attbyval != t1.typbyval OR + (a1.attstorage != t1.typstorage AND a1.attstorage != 'p')) +-- +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "a1"="pg_attribute" +ALIAS: "t1"="pg_type" +FILTER: schema="" table="a1" column="atttypid" +FILTER: schema="" table="t1" column="oid" +FILTER: schema="" table="a1" column="attlen" +FILTER: schema="" table="t1" column="typlen" +FILTER: schema="" table="a1" column="attalign" +FILTER: schema="" table="t1" column="typalign" +FILTER: schema="" table="a1" column="attbyval" +FILTER: schema="" table="t1" column="typbyval" +FILTER: schema="" table="a1" column="attstorage" +FILTER: schema="" table="t1" column="typstorage" +FILTER: schema="" table="a1" column="attstorage" +STMT: SelectStmt +TRUNCATED: "SELECT a1.attrelid, a1.attname, t1.oid, t1.typname FROM pg_attribute a1, pg_type t1 WHERE ..." +== 054 +-- truncate_limit: 100 +-- **************** pg_range **************** + +-- Look for illegal values in pg_range fields. + +SELECT r.rngtypid, r.rngsubtype +FROM pg_range as r +WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0 +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +FILTER: schema="" table="r" column="rngtypid" +FILTER: schema="" table="r" column="rngsubtype" +FILTER: schema="" table="r" column="rngsubopc" +STMT: SelectStmt +TRUNCATED: "SELECT r.rngtypid, r.rngsubtype FROM pg_range r WHERE ..." +== 055 +-- truncate_limit: 100 +-- rngcollation should be specified iff subtype is collatable + +SELECT r.rngtypid, r.rngsubtype, r.rngcollation, t.typcollation +FROM pg_range r JOIN pg_type t ON t.oid = r.rngsubtype +WHERE (rngcollation = 0) != (typcollation = 0) +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +ALIAS: "r"="pg_range" +ALIAS: "t"="pg_type" +FILTER: schema="" table="" column="rngcollation" +FILTER: schema="" table="" column="typcollation" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_range r JOIN pg_type t ON t.oid = r.rngsubtype WHERE ..." +== 056 +-- truncate_limit: 100 +-- opclass had better be a btree opclass accepting the subtype. +-- We must allow anyarray matches, cf IsBinaryCoercible() + +SELECT r.rngtypid, r.rngsubtype, o.opcmethod, o.opcname +FROM pg_range r JOIN pg_opclass o ON o.oid = r.rngsubopc +WHERE o.opcmethod != 403 OR + ((o.opcintype != r.rngsubtype) AND NOT + (o.opcintype = 'pg_catalog.anyarray'::regtype AND + EXISTS(select 1 from pg_catalog.pg_type where + oid = r.rngsubtype and typelem != 0 and + typsubscript = 'array_subscript_handler'::regproc))) +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_opclass" schema="" table="pg_opclass" ctx=Select +TABLE: name="pg_catalog.pg_type" schema="pg_catalog" table="pg_type" ctx=Select +ALIAS: "o"="pg_opclass" +ALIAS: "r"="pg_range" +FILTER: schema="" table="o" column="opcmethod" +FILTER: schema="" table="o" column="opcintype" +FILTER: schema="" table="r" column="rngsubtype" +FILTER: schema="" table="o" column="opcintype" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="r" column="rngsubtype" +FILTER: schema="" table="" column="typelem" +FILTER: schema="" table="" column="typsubscript" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_range r JOIN pg_opclass o ON o.oid = r.rngsubopc WHERE ..." +== 057 +-- truncate_limit: 100 +-- canonical function, if any, had better match the range type + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngcanonical +WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p"="pg_proc" +ALIAS: "r"="pg_range" +FILTER: schema="" table="" column="pronargs" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="rngtypid" +FILTER: schema="" table="" column="prorettype" +FILTER: schema="" table="" column="rngtypid" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_range r JOIN pg_proc p ON p.oid = r.rngcanonical WHERE ..." +== 058 +-- truncate_limit: 100 +-- subdiff function, if any, had better match the subtype + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngsubdiff +WHERE pronargs != 2 + OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype + OR prorettype != 'pg_catalog.float8'::regtype +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +ALIAS: "p"="pg_proc" +ALIAS: "r"="pg_range" +FILTER: schema="" table="" column="pronargs" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="rngsubtype" +FILTER: schema="" table="" column="proargtypes" +FILTER: schema="" table="" column="rngsubtype" +FILTER: schema="" table="" column="prorettype" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_range r JOIN pg_proc p ON p.oid = r.rngsubdiff WHERE ..." +== 059 +-- truncate_limit: 100 +-- every range should have a valid multirange + +SELECT r.rngtypid, r.rngsubtype, r.rngmultitypid +FROM pg_range r +WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0 +-- +TABLE: name="pg_range" schema="" table="pg_range" ctx=Select +ALIAS: "r"="pg_range" +FILTER: schema="" table="r" column="rngmultitypid" +FILTER: schema="" table="r" column="rngmultitypid" +STMT: SelectStmt +TRUNCATED: "SELECT r.rngtypid, r.rngsubtype, r.rngmultitypid FROM pg_range r WHERE ..." +== 060 +-- truncate_limit: 100 +-- Create a table that holds all the known in-core data types and leave it +-- around so as pg_upgrade is able to test their binary compatibility. +CREATE TABLE tab_core_types AS SELECT + '(11,12)'::point, + '(1,1),(2,2)'::line, + '((11,11),(12,12))'::lseg, + '((11,11),(13,13))'::box, + '((11,12),(13,13),(14,14))'::path AS openedpath, + '[(11,12),(13,13),(14,14)]'::path AS closedpath, + '((11,12),(13,13),(14,14))'::polygon, + '1,1,1'::circle, + 'today'::date, + 'now'::time, + 'now'::timestamp, + 'now'::timetz, + 'now'::timestamptz, + '12 seconds'::interval, + '{"reason":"because"}'::json, + '{"when":"now"}'::jsonb, + '$.a[*] ? (@ > 2)'::jsonpath, + '127.0.0.1'::inet, + '127.0.0.0/8'::cidr, + '00:01:03:86:1c:ba'::macaddr8, + '00:01:03:86:1c:ba'::macaddr, + 2::int2, 4::int4, 8::int8, + 4::float4, '8'::float8, pi()::numeric, + 'foo'::"char", + 'c'::bpchar, + 'abc'::varchar, + 'name'::name, + 'txt'::text, + true::bool, + E'\\xDEADBEEF'::bytea, + B'10001'::bit, + B'10001'::varbit AS varbit, + '12.34'::money, + 'abc'::refcursor, + '1 2'::int2vector, + '1 2'::oidvector, + format('%I=UC/%I', USER, USER)::aclitem AS aclitem, + 'a fat cat sat on a mat and ate a fat rat'::tsvector, + 'fat & rat'::tsquery, + 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, + '11'::xid8, + 'pg_class'::regclass, + 'regtype'::regtype type, + 'pg_monitor'::regrole, + 'pg_class'::regclass::oid, + '(1,1)'::tid, '2'::xid, '3'::cid, + '10:20:10,14,15'::txid_snapshot, + '10:20:10,14,15'::pg_snapshot, + '16/B374D848'::pg_lsn, + 1::information_schema.cardinal_number, + 'l'::information_schema.character_data, + 'n'::information_schema.sql_identifier, + 'now'::information_schema.time_stamp, + 'YES'::information_schema.yes_or_no, + '(1,2)'::int4range, '{(1,2)}'::int4multirange, + '(3,4)'::int8range, '{(3,4)}'::int8multirange, + '(3,4)'::numrange, '{(3,4)}'::nummultirange, + '(2020-01-02, 2021-02-03)'::daterange, + '{(2020-01-02, 2021-02-03)}'::datemultirange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tsrange, + '{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tsmultirange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tstzrange, + '{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tstzmultirange +-- +TABLE: name="tab_core_types" schema="" table="tab_core_types" ctx=DDL +FUNCTION: name="pi" function="pi" schema="" ctx=Call +FUNCTION: name="format" function="format" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE tab_core_types AS SELECT '(11,12)'::point, '(1,1),(2,2)'::line, '((11,11),(12,12))':..." +== 061 +-- truncate_limit: 100 +-- Sanity check on the previous table, checking that all core types are +-- included in this table. +SELECT oid, typname, typtype, typelem, typarray + FROM pg_type t + WHERE oid < 16384 AND + -- Exclude pseudotypes and composite types. + typtype NOT IN ('p', 'c') AND + -- These reg* types cannot be pg_upgraded, so discard them. + oid != ALL(ARRAY['regproc', 'regprocedure', 'regoper', + 'regoperator', 'regconfig', 'regdictionary', + 'regnamespace', 'regcollation']::regtype[]) AND + -- Discard types that do not accept input values as these cannot be + -- tested easily. + -- Note: XML might be disabled at compile-time. + oid != ALL(ARRAY['gtsvector', 'pg_node_tree', + 'pg_ndistinct', 'pg_dependencies', 'pg_mcv_list', + 'pg_brin_bloom_summary', + 'pg_brin_minmax_multi_summary', 'xml']::regtype[]) AND + -- Discard arrays. + NOT EXISTS (SELECT 1 FROM pg_type u WHERE u.typarray = t.oid) + -- Exclude everything from the table created above. This checks + -- that no in-core types are missing in tab_core_types. + AND NOT EXISTS (SELECT 1 + FROM pg_attribute a + WHERE a.atttypid=t.oid AND + a.attnum > 0 AND + a.attrelid='tab_core_types'::regclass) +-- +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_type" schema="" table="pg_type" ctx=Select +TABLE: name="pg_attribute" schema="" table="pg_attribute" ctx=Select +ALIAS: "a"="pg_attribute" +ALIAS: "t"="pg_type" +ALIAS: "u"="pg_type" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="typtype" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="u" column="typarray" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="a" column="atttypid" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="a" column="attnum" +FILTER: schema="" table="a" column="attrelid" +STMT: SelectStmt +TRUNCATED: "SELECT oid, typname, typtype, typelem, typarray FROM pg_type t WHERE ..." diff --git a/parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json b/parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json new file mode 100644 index 0000000..d49a93c --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json @@ -0,0 +1,32 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/typed_table.test b/parser/testdata/summary_truncate/postgres_regress/typed_table.test new file mode 100644 index 0000000..01e6307 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/typed_table.test @@ -0,0 +1,219 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE ttable1 OF nothing +-- +TABLE: name="ttable1" schema="" table="ttable1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ttable1 OF nothing" +== 002 +-- truncate_limit: 100 +CREATE TYPE person_type AS (id int, name text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE person_type AS (id int, name text)" +== 003 +-- truncate_limit: 100 +CREATE TABLE persons OF person_type +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons OF person_type" +== 004 +-- truncate_limit: 100 +CREATE TABLE IF NOT EXISTS persons OF person_type +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE IF NOT EXISTS persons OF person_type" +== 005 +-- truncate_limit: 100 +SELECT * FROM persons +-- +TABLE: name="persons" schema="" table="persons" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM persons" +== 006 +-- truncate_limit: 100 +CREATE FUNCTION get_all_persons() RETURNS SETOF person_type +LANGUAGE SQL +AS $$ + SELECT * FROM persons; +$$ +-- +FUNCTION: name="get_all_persons" function="get_all_persons" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION get_all_persons() RETURNS SETOF person_type LANGUAGE sql AS $$\n SELECT * FROM ..." +== 007 +-- truncate_limit: 100 +SELECT * FROM get_all_persons() +-- +FUNCTION: name="get_all_persons" function="get_all_persons" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM get_all_persons()" +== 008 +-- truncate_limit: 100 +-- certain ALTER TABLE operations on typed tables are not allowed +ALTER TABLE persons ADD COLUMN comment text +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE persons ADD COLUMN comment text" +== 009 +-- truncate_limit: 100 +ALTER TABLE persons DROP COLUMN name +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE persons DROP name" +== 010 +-- truncate_limit: 100 +ALTER TABLE persons RENAME COLUMN id TO num +-- +STMT: RenameStmt +TRUNCATED: "ALTER TABLE persons RENAME COLUMN id TO num" +== 011 +-- truncate_limit: 100 +ALTER TABLE persons ALTER COLUMN name TYPE varchar +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE persons ALTER COLUMN name TYPE varchar" +== 012 +-- truncate_limit: 100 +CREATE TABLE stuff (id int) +-- +TABLE: name="stuff" schema="" table="stuff" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE stuff (id int)" +== 013 +-- truncate_limit: 100 +ALTER TABLE persons INHERIT stuff +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE persons INHERIT stuff" +== 014 +-- truncate_limit: 100 +CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL) +-- +TABLE: name="personsx" schema="" table="personsx" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE personsx OF person_type (myname NOT NULL)" +== 015 +-- truncate_limit: 100 +-- error + +CREATE TABLE persons2 OF person_type ( + id WITH OPTIONS PRIMARY KEY, + UNIQUE (name) +) +-- +TABLE: name="persons2" schema="" table="persons2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons2 OF person_type (id PRIMARY KEY, UNIQUE (name))" +== 016 +-- truncate_limit: 100 +CREATE TABLE persons3 OF person_type ( + PRIMARY KEY (id), + name WITH OPTIONS DEFAULT '' +) +-- +TABLE: name="persons3" schema="" table="persons3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons3 OF person_type (PRIMARY KEY (id), name DEFAULT '')" +== 017 +-- truncate_limit: 100 +CREATE TABLE persons4 OF person_type ( + name WITH OPTIONS NOT NULL, + name WITH OPTIONS DEFAULT '' -- error, specified more than once +) +-- +TABLE: name="persons4" schema="" table="persons4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons4 OF person_type (name NOT NULL, name DEFAULT '')" +== 018 +-- truncate_limit: 100 +DROP TYPE person_type RESTRICT +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE person_type" +== 019 +-- truncate_limit: 100 +DROP TYPE person_type CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE person_type CASCADE" +== 020 +-- truncate_limit: 100 +CREATE TABLE persons5 OF stuff +-- +TABLE: name="persons5" schema="" table="persons5" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons5 OF stuff" +== 021 +-- truncate_limit: 100 +-- only CREATE TYPE AS types may be used + +DROP TABLE stuff +-- +TABLE: name="stuff" schema="" table="stuff" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE stuff" +== 022 +-- truncate_limit: 100 +-- implicit casting + +CREATE TYPE person_type AS (id int, name text) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE person_type AS (id int, name text)" +== 023 +-- truncate_limit: 100 +CREATE TABLE persons OF person_type +-- +TABLE: name="persons" schema="" table="persons" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons OF person_type" +== 024 +-- truncate_limit: 100 +INSERT INTO persons VALUES (1, 'test') +-- +TABLE: name="persons" schema="" table="persons" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO persons VALUES (1, 'test')" +== 025 +-- truncate_limit: 100 +CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE SQL AS $$ SELECT length($1.name) $$ +-- +FUNCTION: name="namelen" function="namelen" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE sql AS $$ SELECT length($1.name) $$" +== 026 +-- truncate_limit: 100 +SELECT id, namelen(persons) FROM persons +-- +TABLE: name="persons" schema="" table="persons" ctx=Select +FUNCTION: name="namelen" function="namelen" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT id, namelen(persons) FROM persons" +== 027 +-- truncate_limit: 100 +CREATE TABLE persons2 OF person_type ( + id WITH OPTIONS PRIMARY KEY, + UNIQUE (name) +) +-- +TABLE: name="persons2" schema="" table="persons2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons2 OF person_type (id PRIMARY KEY, UNIQUE (name))" +== 028 +-- truncate_limit: 100 +CREATE TABLE persons3 OF person_type ( + PRIMARY KEY (id), + name NOT NULL DEFAULT '' +) +-- +TABLE: name="persons3" schema="" table="persons3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE persons3 OF person_type (PRIMARY KEY (id), name NOT NULL DEFAULT '')" diff --git a/parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json b/parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json new file mode 100644 index 0000000..f51f5c0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json @@ -0,0 +1,21 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/unicode.test b/parser/testdata/summary_truncate/postgres_regress/unicode.test new file mode 100644 index 0000000..6aa9c63 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/unicode.test @@ -0,0 +1,134 @@ +== 001 +-- truncate_limit: 100 +SELECT getdatabaseencoding() <> 'UTF8' AS skip_test +-- +FUNCTION: name="getdatabaseencoding" function="getdatabaseencoding" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT getdatabaseencoding() <> 'UTF8' AS skip_test" +== 002 +-- truncate_limit: 100 +SELECT U&'\0061\0308bc' <> U&'\00E4bc' COLLATE "C" AS sanity_check +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'äbc' <> 'äbc' COLLATE \"C\" AS sanity_check" +== 003 +-- truncate_limit: 100 +SELECT unicode_version() IS NOT NULL +-- +FUNCTION: name="unicode_version" function="unicode_version" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unicode_version() IS NOT NULL" +== 004 +-- truncate_limit: 100 +SELECT unicode_assigned(U&'abc') +-- +FUNCTION: name="unicode_assigned" function="unicode_assigned" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unicode_assigned('abc')" +== 005 +-- truncate_limit: 100 +SELECT unicode_assigned(U&'abc\+10FFFF') +-- +FUNCTION: name="unicode_assigned" function="unicode_assigned" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT unicode_assigned('abc\U0010ffff')" +== 006 +-- truncate_limit: 100 +SELECT normalize('') +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT normalize ('')" +== 007 +-- truncate_limit: 100 +SELECT normalize(U&'\0061\0308\24D1c') = U&'\00E4\24D1c' COLLATE "C" AS test_default +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT normalize ('äⓑc') = 'äⓑc' COLLATE \"C\" AS test_default" +== 008 +-- truncate_limit: 100 +SELECT normalize(U&'\0061\0308\24D1c', NFC) = U&'\00E4\24D1c' COLLATE "C" AS test_nfc +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT normalize ('äⓑc', NFC) = 'äⓑc' COLLATE \"C\" AS test_nfc" +== 009 +-- truncate_limit: 100 +SELECT normalize(U&'\00E4bc', NFC) = U&'\00E4bc' COLLATE "C" AS test_nfc_idem +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT normalize ('äbc', NFC) = 'äbc' COLLATE \"C\" AS test_nfc_idem" +== 010 +-- truncate_limit: 100 +SELECT normalize(U&'\00E4\24D1c', NFD) = U&'\0061\0308\24D1c' COLLATE "C" AS test_nfd +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT normalize ('äⓑc', NFD) = 'äⓑc' COLLATE \"C\" AS test_nfd" +== 011 +-- truncate_limit: 100 +SELECT normalize(U&'\0061\0308\24D1c', NFKC) = U&'\00E4bc' COLLATE "C" AS test_nfkc +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT normalize ('äⓑc', NFKC) = 'äbc' COLLATE \"C\" AS test_nfkc" +== 012 +-- truncate_limit: 100 +SELECT normalize(U&'\00E4\24D1c', NFKD) = U&'\0061\0308bc' COLLATE "C" AS test_nfkd +-- +FUNCTION: name="pg_catalog.normalize" function="normalize" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT normalize ('äⓑc', NFKD) = 'äbc' COLLATE \"C\" AS test_nfkd" +== 013 +-- truncate_limit: 100 +SELECT "normalize"('abc', 'def') +-- +FUNCTION: name="normalize" function="normalize" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT \"normalize\"('abc', 'def')" +== 014 +-- truncate_limit: 100 +-- run-time error + +SELECT U&'\00E4\24D1c' IS NORMALIZED AS test_default +-- +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'äⓑc' IS NORMALIZED AS test_default" +== 015 +-- truncate_limit: 100 +SELECT U&'\00E4\24D1c' IS NFC NORMALIZED AS test_nfc +-- +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT 'äⓑc' IS NFC NORMALIZED AS test_nfc" +== 016 +-- truncate_limit: 100 +SELECT num, val, + val IS NFC NORMALIZED AS NFC, + val IS NFD NORMALIZED AS NFD, + val IS NFKC NORMALIZED AS NFKC, + val IS NFKD NORMALIZED AS NFKD +FROM + (VALUES (1, U&'\00E4bc'), + (2, U&'\0061\0308bc'), + (3, U&'\00E4\24D1c'), + (4, U&'\0061\0308\24D1c'), + (5, '')) vals (num, val) +ORDER BY num +-- +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +FUNCTION: name="pg_catalog.is_normalized" function="is_normalized" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) vals(num, val) ORDER BY num" +== 017 +-- truncate_limit: 100 +SELECT is_normalized('abc', 'def') +-- +FUNCTION: name="is_normalized" function="is_normalized" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT is_normalized('abc', 'def')" diff --git a/parser/testdata/summary_truncate/postgres_regress/union.metadata.json b/parser/testdata/summary_truncate/postgres_regress/union.metadata.json new file mode 100644 index 0000000..c2aa882 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/union.metadata.json @@ -0,0 +1,195 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/union.test b/parser/testdata/summary_truncate/postgres_regress/union.test new file mode 100644 index 0000000..ba1d819 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/union.test @@ -0,0 +1,1715 @@ +== 001 +-- truncate_limit: 100 +|-- +-- UNION (also INTERSECT, EXCEPT) +|-- + +-- Simple UNION constructs + +SELECT 1 AS two UNION SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS two UNION SELECT 2 ORDER BY 1" +== 002 +-- truncate_limit: 100 +SELECT 1 AS one UNION SELECT 1 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one UNION SELECT 1 ORDER BY 1" +== 003 +-- truncate_limit: 100 +SELECT 1 AS two UNION ALL SELECT 2 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS two UNION ALL SELECT 2" +== 004 +-- truncate_limit: 100 +SELECT 1 AS two UNION ALL SELECT 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS two UNION ALL SELECT 1" +== 005 +-- truncate_limit: 100 +SELECT 1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1 AS three UNION SELECT 2) UNION SELECT 3 ORDER BY 1" +== 006 +-- truncate_limit: 100 +SELECT 1 AS two UNION SELECT 2 UNION SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1 AS two UNION SELECT 2) UNION SELECT 2 ORDER BY 1" +== 007 +-- truncate_limit: 100 +SELECT 1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1 AS three UNION SELECT 2) UNION ALL SELECT 2 ORDER BY 1" +== 008 +-- truncate_limit: 100 +SELECT 1.1 AS two UNION SELECT 2.2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1.1 AS two UNION SELECT 2.2 ORDER BY 1" +== 009 +-- truncate_limit: 100 +-- Mixed types + +SELECT 1.1 AS two UNION SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1.1 AS two UNION SELECT 2 ORDER BY 1" +== 010 +-- truncate_limit: 100 +SELECT 1 AS two UNION SELECT 2.2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS two UNION SELECT 2.2 ORDER BY 1" +== 011 +-- truncate_limit: 100 +SELECT 1 AS one UNION SELECT 1.0::float8 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1 AS one UNION SELECT (1.0)::float8 ORDER BY 1" +== 012 +-- truncate_limit: 100 +SELECT 1.1 AS two UNION ALL SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1.1 AS two UNION ALL SELECT 2 ORDER BY 1" +== 013 +-- truncate_limit: 100 +SELECT 1.0::float8 AS two UNION ALL SELECT 1 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT (1.0)::float8 AS two UNION ALL SELECT 1 ORDER BY 1" +== 014 +-- truncate_limit: 100 +SELECT 1.1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1.1 AS three UNION SELECT 2) UNION SELECT 3 ORDER BY 1" +== 015 +-- truncate_limit: 100 +SELECT 1.1::float8 AS two UNION SELECT 2 UNION SELECT 2.0::float8 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT (1.1)::float8 AS two UNION SELECT 2) UNION SELECT (2.0)::float8 ORDER BY 1" +== 016 +-- truncate_limit: 100 +SELECT 1.1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1.1 AS three UNION SELECT 2) UNION ALL SELECT 2 ORDER BY 1" +== 017 +-- truncate_limit: 100 +SELECT 1.1 AS two UNION (SELECT 2 UNION ALL SELECT 2) ORDER BY 1 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 1.1 AS two UNION (SELECT 2 UNION ALL SELECT 2) ORDER BY 1" +== 018 +-- truncate_limit: 100 +|-- +-- Try testing from tables... +|-- + +SELECT f1 AS five FROM FLOAT8_TBL +UNION +SELECT f1 FROM FLOAT8_TBL +ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS five FROM float8_tbl UNION SELECT f1 FROM float8_tbl ORDER BY 1" +== 019 +-- truncate_limit: 100 +SELECT f1 AS ten FROM FLOAT8_TBL +UNION ALL +SELECT f1 FROM FLOAT8_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS ten FROM float8_tbl UNION ALL SELECT f1 FROM float8_tbl" +== 020 +-- truncate_limit: 100 +SELECT f1 AS nine FROM FLOAT8_TBL +UNION +SELECT f1 FROM INT4_TBL +ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS nine FROM float8_tbl UNION SELECT f1 FROM int4_tbl ORDER BY 1" +== 021 +-- truncate_limit: 100 +SELECT f1 AS ten FROM FLOAT8_TBL +UNION ALL +SELECT f1 FROM INT4_TBL +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS ten FROM float8_tbl UNION ALL SELECT f1 FROM int4_tbl" +== 022 +-- truncate_limit: 100 +SELECT f1 AS five FROM FLOAT8_TBL + WHERE f1 BETWEEN -1e6 AND 1e6 +UNION +SELECT f1 FROM INT4_TBL + WHERE f1 BETWEEN 0 AND 1000000 +ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS five FROM float8_tbl WHERE ... UNION SELECT f1 FROM int4_tbl WHERE ... ORDER BY 1" +== 023 +-- truncate_limit: 100 +SELECT CAST(f1 AS char(4)) AS three FROM VARCHAR_TBL +UNION +SELECT f1 FROM CHAR_TBL +ORDER BY 1 +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1::char(4) AS three FROM varchar_tbl UNION SELECT f1 FROM char_tbl ORDER BY 1" +== 024 +-- truncate_limit: 100 +SELECT f1 AS three FROM VARCHAR_TBL +UNION +SELECT CAST(f1 AS varchar) FROM CHAR_TBL +ORDER BY 1 +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS three FROM varchar_tbl UNION SELECT f1::varchar FROM char_tbl ORDER BY 1" +== 025 +-- truncate_limit: 100 +SELECT f1 AS eight FROM VARCHAR_TBL +UNION ALL +SELECT f1 FROM CHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 AS eight FROM varchar_tbl UNION ALL SELECT f1 FROM char_tbl" +== 026 +-- truncate_limit: 100 +SELECT f1 AS five FROM TEXT_TBL +UNION +SELECT f1 FROM VARCHAR_TBL +UNION +SELECT TRIM(TRAILING FROM f1) FROM CHAR_TBL +ORDER BY 1 +-- +TABLE: name="text_tbl" schema="" table="text_tbl" ctx=Select +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="char_tbl" schema="" table="char_tbl" ctx=Select +FUNCTION: name="pg_catalog.rtrim" function="rtrim" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "(SELECT ... FROM text_tbl UNION SELECT f1 FROM varchar_tbl) UNION SELECT ... FROM char_tbl ORDER ..." +== 027 +-- truncate_limit: 100 +|-- +-- INTERSECT and EXCEPT +|-- + +SELECT q2 FROM int8_tbl INTERSECT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q2 FROM int8_tbl INTERSECT SELECT q1 FROM int8_tbl ORDER BY 1" +== 028 +-- truncate_limit: 100 +SELECT q2 FROM int8_tbl INTERSECT ALL SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q2 FROM int8_tbl INTERSECT ALL SELECT q1 FROM int8_tbl ORDER BY 1" +== 029 +-- truncate_limit: 100 +SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1" +== 030 +-- truncate_limit: 100 +SELECT q2 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q2 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl ORDER BY 1" +== 031 +-- truncate_limit: 100 +SELECT q2 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q2 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q1 FROM int8_tbl ORDER BY 1" +== 032 +-- truncate_limit: 100 +SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY 1" +== 033 +-- truncate_limit: 100 +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q2 FROM int8_tbl ORDER BY 1" +== 034 +-- truncate_limit: 100 +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q2 FROM int8_tbl ORDER BY 1" +== 035 +-- truncate_limit: 100 +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl FOR NO KEY UPDATE +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl FOR NO KEY UPDATE" +== 036 +-- truncate_limit: 100 +-- nested cases +(SELECT 1,2,3 UNION SELECT 4,5,6) INTERSECT SELECT 4,5,6 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1, 2, 3 UNION SELECT 4, 5, 6) INTERSECT SELECT 4, 5, 6" +== 037 +-- truncate_limit: 100 +(SELECT 1,2,3 UNION SELECT 4,5,6 ORDER BY 1,2) INTERSECT SELECT 4,5,6 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1, 2, 3 UNION SELECT 4, 5, 6 ORDER BY 1, 2) INTERSECT SELECT 4, 5, 6" +== 038 +-- truncate_limit: 100 +(SELECT 1,2,3 UNION SELECT 4,5,6) EXCEPT SELECT 4,5,6 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1, 2, 3 UNION SELECT 4, 5, 6) EXCEPT SELECT 4, 5, 6" +== 039 +-- truncate_limit: 100 +(SELECT 1,2,3 UNION SELECT 4,5,6 ORDER BY 1,2) EXCEPT SELECT 4,5,6 +-- +STMT: SelectStmt +TRUNCATED: "(SELECT 1, 2, 3 UNION SELECT 4, 5, 6 ORDER BY 1, 2) EXCEPT SELECT 4, 5, 6" +== 040 +-- truncate_limit: 100 +-- exercise both hashed and sorted implementations of UNION/INTERSECT/EXCEPT + +set enable_hashagg to on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO ON" +== 041 +-- truncate_limit: 100 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM (SELECT unique1 FROM tenk1 UNION SELECT fivethous FROM t..." +== 042 +-- truncate_limit: 100 +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT unique1 FROM tenk1 UNION SELECT fivethous FROM tenk1) ss" +== 043 +-- truncate_limit: 100 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM (SELECT unique1 FROM tenk1 INTERSECT SELECT fivethous FR..." +== 044 +-- truncate_limit: 100 +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT unique1 FROM tenk1 INTERSECT SELECT fivethous FROM tenk1) ss" +== 045 +-- truncate_limit: 100 +explain (costs off) +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 EXCEPT SELECT unique2 FROM tenk1 WHERE unique2 <> 10" +== 046 +-- truncate_limit: 100 +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 EXCEPT SELECT unique2 FROM tenk1 WHERE unique2 <> 10" +== 047 +-- truncate_limit: 100 +set enable_hashagg to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 048 +-- truncate_limit: 100 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM (SELECT unique1 FROM tenk1 UNION SELECT fivethous FROM t..." +== 049 +-- truncate_limit: 100 +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT unique1 FROM tenk1 UNION SELECT fivethous FROM tenk1) ss" +== 050 +-- truncate_limit: 100 +explain (costs off) +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) FROM (SELECT unique1 FROM tenk1 INTERSECT SELECT fivethous FR..." +== 051 +-- truncate_limit: 100 +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (SELECT unique1 FROM tenk1 INTERSECT SELECT fivethous FROM tenk1) ss" +== 052 +-- truncate_limit: 100 +explain (costs off) +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT unique1 FROM tenk1 EXCEPT SELECT unique2 FROM tenk1 WHERE unique2 <> 10" +== 053 +-- truncate_limit: 100 +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT unique1 FROM tenk1 EXCEPT SELECT unique2 FROM tenk1 WHERE unique2 <> 10" +== 054 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 055 +-- truncate_limit: 100 +-- non-hashable type +set enable_hashagg to on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO ON" +== 056 +-- truncate_limit: 100 +explain (costs off) +select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES ('11'::varbit), ('10'::varbit)) _(x) UNION SELECT x FRO..." +== 057 +-- truncate_limit: 100 +set enable_hashagg to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 058 +-- truncate_limit: 100 +explain (costs off) +select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES ('11'::varbit), ('10'::varbit)) _(x) UNION SELECT x FRO..." +== 059 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 060 +-- truncate_limit: 100 +-- arrays +set enable_hashagg to on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO ON" +== 061 +-- truncate_limit: 100 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 3])) _(x) UNION SELECT x FROM ..." +== 062 +-- truncate_limit: 100 +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) UNION SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 4])) _(x)" +== 063 +-- truncate_limit: 100 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 3])) _(x) INTERSECT SELECT x F..." +== 064 +-- truncate_limit: 100 +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) INTERSECT SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 4])) _(x)" +== 065 +-- truncate_limit: 100 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 3])) _(x) EXCEPT SELECT x FROM..." +== 066 +-- truncate_limit: 100 +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) EXCEPT SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 4])) _(x)" +== 067 +-- truncate_limit: 100 +-- non-hashable type +explain (costs off) +select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ARRAY['10'::varbit]), (ARRAY['11'::varbit])) _(x) UNIO..." +== 068 +-- truncate_limit: 100 +select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) UNION SELECT x FROM (VALUES (...)) _(x)" +== 069 +-- truncate_limit: 100 +set enable_hashagg to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 070 +-- truncate_limit: 100 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 3])) _(x) UNION SELECT x FROM ..." +== 071 +-- truncate_limit: 100 +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) UNION SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 4])) _(x)" +== 072 +-- truncate_limit: 100 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 3])) _(x) INTERSECT SELECT x F..." +== 073 +-- truncate_limit: 100 +select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) INTERSECT SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 4])) _(x)" +== 074 +-- truncate_limit: 100 +explain (costs off) +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 3])) _(x) EXCEPT SELECT x FROM..." +== 075 +-- truncate_limit: 100 +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) EXCEPT SELECT x FROM (VALUES (ARRAY[1, 2]), (ARRAY[1, 4])) _(x)" +== 076 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 077 +-- truncate_limit: 100 +-- records +set enable_hashagg to on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO ON" +== 078 +-- truncate_limit: 100 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 3))) _(x) UNION SELECT x FROM (VAL..." +== 079 +-- truncate_limit: 100 +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) UNION SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 4))) _(x)" +== 080 +-- truncate_limit: 100 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 3))) _(x) INTERSECT SELECT x FROM ..." +== 081 +-- truncate_limit: 100 +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) INTERSECT SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 4))) _(x)" +== 082 +-- truncate_limit: 100 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 3))) _(x) EXCEPT SELECT x FROM (VA..." +== 083 +-- truncate_limit: 100 +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) EXCEPT SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 4))) _(x)" +== 084 +-- truncate_limit: 100 +-- non-hashable type + +-- With an anonymous row type, the typcache does not report that the +-- type is hashable. (Otherwise, this would fail at execution time.) +explain (costs off) +select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW('10'::varbit)), (ROW('11'::varbit))) _(x) UNION SE..." +== 085 +-- truncate_limit: 100 +select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) UNION SELECT x FROM (VALUES (...)) _(x)" +== 086 +-- truncate_limit: 100 +-- With a defined row type, the typcache can inspect the type's fields +-- for hashability. +create type ct1 as (f1 varbit) +-- +STMT: CompositeTypeStmt +TRUNCATED: "CREATE TYPE ct1 AS (f1 varbit)" +== 087 +-- truncate_limit: 100 +explain (costs off) +select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW('10'::varbit)::ct1), (ROW('11'::varbit)::ct1)) _(x..." +== 088 +-- truncate_limit: 100 +select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) UNION SELECT x FROM (VALUES (...)) _(x)" +== 089 +-- truncate_limit: 100 +drop type ct1 +-- +STMT: DropStmt +TRUNCATED: "DROP TYPE ct1" +== 090 +-- truncate_limit: 100 +set enable_hashagg to off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 091 +-- truncate_limit: 100 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 3))) _(x) UNION SELECT x FROM (VAL..." +== 092 +-- truncate_limit: 100 +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) UNION SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 4))) _(x)" +== 093 +-- truncate_limit: 100 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 3))) _(x) INTERSECT SELECT x FROM ..." +== 094 +-- truncate_limit: 100 +select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) INTERSECT SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 4))) _(x)" +== 095 +-- truncate_limit: 100 +explain (costs off) +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 3))) _(x) EXCEPT SELECT x FROM (VA..." +== 096 +-- truncate_limit: 100 +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x) +-- +STMT: SelectStmt +TRUNCATED: "SELECT x FROM (VALUES (...)) _(x) EXCEPT SELECT x FROM (VALUES (ROW(1, 2)), (ROW(1, 4))) _(x)" +== 097 +-- truncate_limit: 100 +-- non-sortable type + +-- Ensure we get a HashAggregate plan. Keep enable_hashagg=off to ensure +-- there's no chance of a sort. +explain (costs off) select '123'::xid union select '123'::xid +-- +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT '123'::xid UNION SELECT '123'::xid" +== 098 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 099 +-- truncate_limit: 100 +|-- +-- Mixed types +|-- + +SELECT f1 FROM float8_tbl INTERSECT SELECT f1 FROM int4_tbl ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM float8_tbl INTERSECT SELECT f1 FROM int4_tbl ORDER BY 1" +== 100 +-- truncate_limit: 100 +SELECT f1 FROM float8_tbl EXCEPT SELECT f1 FROM int4_tbl ORDER BY 1 +-- +TABLE: name="float8_tbl" schema="" table="float8_tbl" ctx=Select +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT f1 FROM float8_tbl EXCEPT SELECT f1 FROM int4_tbl ORDER BY 1" +== 101 +-- truncate_limit: 100 +|-- +-- Operator precedence and (((((extra))))) parentheses +|-- + +SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl) UNION ALL SELECT q2 FROM int8_tbl ORD..." +== 102 +-- truncate_limit: 100 +SELECT q1 FROM int8_tbl INTERSECT (((SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl INTERSECT (SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl) ORD..." +== 103 +-- truncate_limit: 100 +(((SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl ORDER BY 1))) UNION ALL SELECT q2 FROM int8_tbl +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl ORDER BY 1) UNION ALL SELECT q2 FROM i..." +== 104 +-- truncate_limit: 100 +SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl) EXCEPT SELECT q1 FROM int8_tbl ORDER ..." +== 105 +-- truncate_limit: 100 +SELECT q1 FROM int8_tbl UNION ALL (((SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1))) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl UNION ALL (SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER B..." +== 106 +-- truncate_limit: 100 +(((SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "(SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl) EXCEPT SELECT q1 FROM int8_tbl ORDER ..." +== 107 +-- truncate_limit: 100 +|-- +-- Subqueries with ORDER BY & LIMIT clauses +|-- + +-- In this syntax, ORDER BY/LIMIT apply to the result of the EXCEPT +SELECT q1,q2 FROM int8_tbl EXCEPT SELECT q2,q1 FROM int8_tbl +ORDER BY q2,q1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1, q2 FROM int8_tbl EXCEPT SELECT q2, q1 FROM int8_tbl ORDER BY q2, q1" +== 108 +-- truncate_limit: 100 +-- This should fail, because q2 isn't a name of an EXCEPT output column +SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1" +== 109 +-- truncate_limit: 100 +-- But this should work: +SELECT q1 FROM int8_tbl EXCEPT (((SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1))) ORDER BY 1 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM int8_tbl EXCEPT (SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1) ORDER BY 1" +== 110 +-- truncate_limit: 100 +|-- +-- New syntaxes (7.1) permit new tests +|-- + +(((((select * from int8_tbl))))) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM int8_tbl" +== 111 +-- truncate_limit: 100 +|-- +-- Check behavior with empty select list (allowed since 9.4) +|-- + +select union select +-- +STMT: SelectStmt +TRUNCATED: "SELECT UNION SELECT" +== 112 +-- truncate_limit: 100 +select intersect select +-- +STMT: SelectStmt +TRUNCATED: "SELECT INTERSECT SELECT" +== 113 +-- truncate_limit: 100 +select except select +-- +STMT: SelectStmt +TRUNCATED: "SELECT EXCEPT SELECT" +== 114 +-- truncate_limit: 100 +-- check hashed implementation +set enable_hashagg = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO TRUE" +== 115 +-- truncate_limit: 100 +set enable_sort = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO FALSE" +== 116 +-- truncate_limit: 100 +-- We've no way to check hashed UNION as the empty pathkeys in the Append are +-- fine to make use of Unique, which is cheaper than HashAggregate and we've +-- no means to disable Unique. +explain (costs off) +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT FROM generate_series(1, 5) INTERSECT SELECT FROM generate_series(1, 3)" +== 117 +-- truncate_limit: 100 +select from generate_series(1,5) union all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) UNION ALL SELECT FROM generate_series(1, 3)" +== 118 +-- truncate_limit: 100 +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) INTERSECT SELECT FROM generate_series(1, 3)" +== 119 +-- truncate_limit: 100 +select from generate_series(1,5) intersect all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) INTERSECT ALL SELECT FROM generate_series(1, 3)" +== 120 +-- truncate_limit: 100 +select from generate_series(1,5) except select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) EXCEPT SELECT FROM generate_series(1, 3)" +== 121 +-- truncate_limit: 100 +select from generate_series(1,5) except all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) EXCEPT ALL SELECT FROM generate_series(1, 3)" +== 122 +-- truncate_limit: 100 +-- check sorted implementation +set enable_hashagg = false +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO FALSE" +== 123 +-- truncate_limit: 100 +set enable_sort = true +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO TRUE" +== 124 +-- truncate_limit: 100 +explain (costs off) +select from generate_series(1,5) union select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT FROM generate_series(1, 5) UNION SELECT FROM generate_series(1, 3)" +== 125 +-- truncate_limit: 100 +explain (costs off) +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT FROM generate_series(1, 5) INTERSECT SELECT FROM generate_series(1, 3)" +== 126 +-- truncate_limit: 100 +select from generate_series(1,5) union select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) UNION SELECT FROM generate_series(1, 3)" +== 127 +-- truncate_limit: 100 +select from generate_series(1,5) union all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) UNION ALL SELECT FROM generate_series(1, 3)" +== 128 +-- truncate_limit: 100 +select from generate_series(1,5) intersect select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) INTERSECT SELECT FROM generate_series(1, 3)" +== 129 +-- truncate_limit: 100 +select from generate_series(1,5) intersect all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) INTERSECT ALL SELECT FROM generate_series(1, 3)" +== 130 +-- truncate_limit: 100 +select from generate_series(1,5) except select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) EXCEPT SELECT FROM generate_series(1, 3)" +== 131 +-- truncate_limit: 100 +select from generate_series(1,5) except all select from generate_series(1,3) +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT FROM generate_series(1, 5) EXCEPT ALL SELECT FROM generate_series(1, 3)" +== 132 +-- truncate_limit: 100 +-- Try a variation of the above but with a CTE which contains a column, again +-- with an empty final select list. + +-- Ensure we get the expected 1 row with 0 columns +with cte as materialized (select s from generate_series(1,5) s) +select from cte union select from cte +-- +CTE: "cte" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte AS MATERIALIZED (...) SELECT FROM cte UNION SELECT FROM cte" +== 133 +-- truncate_limit: 100 +-- Ensure we get the same result as the above. +with cte as not materialized (select s from generate_series(1,5) s) +select from cte union select from cte +-- +CTE: "cte" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte AS NOT MATERIALIZED (...) SELECT FROM cte UNION SELECT FROM cte" +== 134 +-- truncate_limit: 100 +reset enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 135 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 136 +-- truncate_limit: 100 +|-- +-- Check handling of a case with unknown constants. We don't guarantee +-- an undecorated constant will work in all cases, but historically this +-- usage has worked, so test we don't break it. +|-- + +SELECT a.f1 FROM (SELECT 'test' AS f1 FROM varchar_tbl) a +UNION +SELECT b.f1 FROM (SELECT f1 FROM varchar_tbl) b +ORDER BY 1 +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM varchar_tbl) a UNION SELECT ... FROM (SELECT f1 FROM varchar_tbl..." +== 137 +-- truncate_limit: 100 +-- This should fail, but it should produce an error cursor +SELECT '3.4'::numeric UNION SELECT 'foo' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '3.4'::numeric UNION SELECT 'foo'" +== 138 +-- truncate_limit: 100 +|-- +-- Test that expression-index constraints can be pushed down through +-- UNION or UNION ALL +|-- + +CREATE TEMP TABLE t1 (a text, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (a text, b text)" +== 139 +-- truncate_limit: 100 +CREATE INDEX t1_ab_idx on t1 ((a || b)) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX t1_ab_idx ON t1 USING btree ((a || b))" +== 140 +-- truncate_limit: 100 +CREATE TEMP TABLE t2 (ab text primary key) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t2 (ab text PRIMARY KEY)" +== 141 +-- truncate_limit: 100 +INSERT INTO t1 VALUES ('a', 'b'), ('x', 'y') +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES ('a', 'b'), ('x', 'y')" +== 142 +-- truncate_limit: 100 +INSERT INTO t2 VALUES ('ab'), ('xy') +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 VALUES ('ab'), ('xy')" +== 143 +-- truncate_limit: 100 +set enable_seqscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO OFF" +== 144 +-- truncate_limit: 100 +set enable_indexscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexscan TO ON" +== 145 +-- truncate_limit: 100 +set enable_bitmapscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_bitmapscan TO OFF" +== 146 +-- truncate_limit: 100 +set enable_sort = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_sort TO OFF" +== 147 +-- truncate_limit: 100 +explain (costs off) + SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION ALL + SELECT * FROM t2) t + WHERE ab = 'ab' +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +FILTER: schema="" table="" column="ab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT a || b AS ab FROM t1 UNION ALL SELECT * FROM t2) t WHER..." +== 148 +-- truncate_limit: 100 +explain (costs off) + SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION + SELECT * FROM t2) t + WHERE ab = 'ab' +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +FILTER: schema="" table="" column="ab" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT a || b AS ab FROM t1 UNION SELECT * FROM t2) t WHERE ab..." +== 149 +-- truncate_limit: 100 +|-- +-- Test that ORDER BY for UNION ALL can be pushed down to inheritance +-- children. +|-- + +CREATE TEMP TABLE t1c (b text, a text) +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1c (b text, a text)" +== 150 +-- truncate_limit: 100 +ALTER TABLE t1c INHERIT t1 +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE t1c INHERIT t1" +== 151 +-- truncate_limit: 100 +CREATE TEMP TABLE t2c (primary key (ab)) INHERITS (t2) +-- +TABLE: name="t2c" schema="" table="t2c" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t2c (PRIMARY KEY (ab)) INHERITS (t2)" +== 152 +-- truncate_limit: 100 +INSERT INTO t1c VALUES ('v', 'w'), ('c', 'd'), ('m', 'n'), ('e', 'f') +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1c VALUES ('v', 'w'), ('c', 'd'), ('m', 'n'), ('e', 'f')" +== 153 +-- truncate_limit: 100 +INSERT INTO t2c VALUES ('vw'), ('cd'), ('mn'), ('ef') +-- +TABLE: name="t2c" schema="" table="t2c" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2c VALUES ('vw'), ('cd'), ('mn'), ('ef')" +== 154 +-- truncate_limit: 100 +CREATE INDEX t1c_ab_idx on t1c ((a || b)) +-- +TABLE: name="t1c" schema="" table="t1c" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX t1c_ab_idx ON t1c USING btree ((a || b))" +== 155 +-- truncate_limit: 100 +set enable_seqscan = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_seqscan TO ON" +== 156 +-- truncate_limit: 100 +set enable_indexonlyscan = off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_indexonlyscan TO OFF" +== 157 +-- truncate_limit: 100 +explain (costs off) + SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION ALL + SELECT ab FROM t2) t + ORDER BY 1 LIMIT 8 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT a || b AS ab FROM t1 UNION ALL SELECT ab FROM t2) t ORD..." +== 158 +-- truncate_limit: 100 +SELECT * FROM + (SELECT a || b AS ab FROM t1 + UNION ALL + SELECT ab FROM t2) t + ORDER BY 1 LIMIT 8 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT a || b AS ab FROM t1 UNION ALL SELECT ab FROM t2) t ORDER BY 1 LIMIT 8" +== 159 +-- truncate_limit: 100 +reset enable_seqscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_seqscan" +== 160 +-- truncate_limit: 100 +reset enable_indexscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexscan" +== 161 +-- truncate_limit: 100 +reset enable_bitmapscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_bitmapscan" +== 162 +-- truncate_limit: 100 +reset enable_sort +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_sort" +== 163 +-- truncate_limit: 100 +-- This simpler variant of the above test has been observed to fail differently + +create table events (event_id int primary key) +-- +TABLE: name="events" schema="" table="events" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE events (event_id int PRIMARY KEY)" +== 164 +-- truncate_limit: 100 +create table other_events (event_id int primary key) +-- +TABLE: name="other_events" schema="" table="other_events" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE other_events (event_id int PRIMARY KEY)" +== 165 +-- truncate_limit: 100 +create table events_child () inherits (events) +-- +TABLE: name="events_child" schema="" table="events_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE events_child () INHERITS (events)" +== 166 +-- truncate_limit: 100 +explain (costs off) +select event_id + from (select event_id from events + union all + select event_id from other_events) ss + order by event_id +-- +TABLE: name="events" schema="" table="events" ctx=Select +TABLE: name="other_events" schema="" table="other_events" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT event_id FROM (SELECT event_id FROM events UNION ALL SELECT event_id F..." +== 167 +-- truncate_limit: 100 +drop table events_child, events, other_events +-- +TABLE: name="events_child" schema="" table="events_child" ctx=DDL +TABLE: name="events" schema="" table="events" ctx=DDL +TABLE: name="other_events" schema="" table="other_events" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE events_child, events, other_events" +== 168 +-- truncate_limit: 100 +reset enable_indexonlyscan +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_indexonlyscan" +== 169 +-- truncate_limit: 100 +-- Test constraint exclusion of UNION ALL subqueries +explain (costs off) + SELECT * FROM + (SELECT 1 AS t, * FROM tenk1 a + UNION ALL + SELECT 2 AS t, * FROM tenk1 b) c + WHERE t = 2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +FILTER: schema="" table="" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT 1 AS t, * FROM tenk1 a UNION ALL SELECT 2 AS t, * FROM ..." +== 170 +-- truncate_limit: 100 +-- Test that we push quals into UNION sub-selects only when it's safe +explain (costs off) +SELECT * FROM + (SELECT 1 AS t, 2 AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT 1 AS t, 2 AS x UNION SELECT 2 AS t, 4 AS x) ss WHERE x ..." +== 171 +-- truncate_limit: 100 +SELECT * FROM + (SELECT 1 AS t, 2 AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT 1 AS t, 2 AS x UNION SELECT 2 AS t, 4 AS x) ss WHERE x < 4 ORDER BY x" +== 172 +-- truncate_limit: 100 +explain (costs off) +SELECT * FROM + (SELECT 1 AS t, generate_series(1,10) AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT 1 AS t, generate_series(1, 10) AS x UNION SELECT 2 AS t..." +== 173 +-- truncate_limit: 100 +SELECT * FROM + (SELECT 1 AS t, generate_series(1,10) AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x < 4 +ORDER BY x +-- +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... UNION SELECT 2 AS t, 4 AS x) ss WHERE x < 4 ORDER BY x" +== 174 +-- truncate_limit: 100 +explain (costs off) +SELECT * FROM + (SELECT 1 AS t, (random()*3)::int AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x > 3 +ORDER BY x +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT 1 AS t, (random() * 3)::int AS x UNION SELECT 2 AS t, 4..." +== 175 +-- truncate_limit: 100 +SELECT * FROM + (SELECT 1 AS t, (random()*3)::int AS x + UNION + SELECT 2 AS t, 4 AS x) ss +WHERE x > 3 +ORDER BY x +-- +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="x" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... UNION SELECT 2 AS t, 4 AS x) ss WHERE x > 3 ORDER BY x" +== 176 +-- truncate_limit: 100 +-- Test cases where the native ordering of a sub-select has more pathkeys +-- than the outer query cares about +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT q1 FROM (SELECT DISTINCT * FROM int8_tbl i81 UNION ALL SELECT..." +== 177 +-- truncate_limit: 100 +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT q1 FROM (SELECT DISTINCT * FROM int8_tbl i81 UNION ALL SELECT DISTINCT * FROM int..." +== 178 +-- truncate_limit: 100 +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT q1 FROM (SELECT DISTINCT * FROM int8_tbl i81 UNION ALL SELECT..." +== 179 +-- truncate_limit: 100 +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i81"="int8_tbl" +ALIAS: "i82"="int8_tbl" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT DISTINCT q1 FROM (SELECT DISTINCT * FROM int8_tbl i81 UNION ALL SELECT DISTINCT * FROM int..." +== 180 +-- truncate_limit: 100 +-- Test proper handling of parameterized appendrel paths when the +-- potential join qual is expensive +create function expensivefunc(int) returns int +language plpgsql immutable strict cost 10000 +as $$begin return $1; end$$ +-- +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION expensivefunc(int) RETURNS int LANGUAGE plpgsql IMMUTABLE RETURNS NULL ON NULL IN..." +== 181 +-- truncate_limit: 100 +create temp table t3 as select generate_series(-1000,1000) as x +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE t3 AS SELECT generate_series(-1000, 1000) AS x" +== 182 +-- truncate_limit: 100 +create index t3i on t3 (expensivefunc(x)) +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX t3i ON t3 USING btree (expensivefunc(x))" +== 183 +-- truncate_limit: 100 +analyze t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t3" +== 184 +-- truncate_limit: 100 +explain (costs off) +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "a"="t3" +ALIAS: "b"="t3" +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT * FROM t3 a UNION ALL SELECT * FROM t3 b) ss JOIN int4_..." +== 185 +-- truncate_limit: 100 +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x) +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +TABLE: name="t3" schema="" table="t3" ctx=Select +ALIAS: "a"="t3" +ALIAS: "b"="t3" +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT * FROM t3 a UNION ALL SELECT * FROM t3 b) ss JOIN int4_tbl ON f1 = expensiv..." +== 186 +-- truncate_limit: 100 +drop table t3 +-- +TABLE: name="t3" schema="" table="t3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t3" +== 187 +-- truncate_limit: 100 +drop function expensivefunc(int) +-- +FUNCTION: name="expensivefunc" function="expensivefunc" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION expensivefunc(int)" +== 188 +-- truncate_limit: 100 +-- Test handling of appendrel quals that const-simplify into an AND +explain (costs off) +select * from + (select *, 0 as x from int8_tbl a + union all + select *, 1 as x from int8_tbl b) ss +where (x = 0) or (q1 >= q2 and q1 <= q2) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT *, 0 AS x FROM int8_tbl a UNION ALL SELECT *, 1 AS x FR..." +== 189 +-- truncate_limit: 100 +select * from + (select *, 0 as x from int8_tbl a + union all + select *, 1 as x from int8_tbl b) ss +where (x = 0) or (q1 >= q2 and q1 <= q2) +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "a"="int8_tbl" +ALIAS: "b"="int8_tbl" +FILTER: schema="" table="" column="x" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +FILTER: schema="" table="" column="q1" +FILTER: schema="" table="" column="q2" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM int8_tbl a UNION ALL SELECT ... FROM int8_tbl b) ss WHERE ..." +== 190 +-- truncate_limit: 100 +|-- +-- Test the planner's ability to produce cheap startup plans with Append nodes +|-- + +-- Ensure we get a Nested Loop join between tenk1 and tenk2 +explain (costs off) +select t1.unique1 from tenk1 t1 +inner join tenk2 t2 on t1.tenthous = t2.tenthous and t2.thousand = 0 + union all +(values(1)) limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT t1.unique1 FROM tenk1 t1 JOIN tenk2 t2 ON t1.tenthous = t2.tenthous AN..." +== 191 +-- truncate_limit: 100 +-- Ensure there is no problem if cheapest_startup_path is NULL +explain (costs off) +select * from tenk1 t1 +left join lateral + (select t1.tenthous from tenk2 t2 union all (values(1))) +on true limit 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM tenk1 t1 LEFT JOIN LATERAL (SELECT t1.tenthous FROM tenk2 t2 UN..." diff --git a/parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json b/parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json new file mode 100644 index 0000000..317bbe8 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json @@ -0,0 +1,1104 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "101", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "102", + "1020", + "1021", + "1022", + "1023", + "1024", + "1025", + "1026", + "1027", + "1028", + "1029", + "103", + "1030", + "1031", + "1032", + "1033", + "1034", + "1035", + "1036", + "1037", + "1038", + "1039", + "104", + "1040", + "1041", + "1042", + "1043", + "1044", + "1045", + "1046", + "1047", + "1048", + "1049", + "105", + "1050", + "1051", + "1052", + "1053", + "1054", + "1055", + "1056", + "1057", + "1058", + "1059", + "106", + "1060", + "1061", + "1062", + "1063", + "1064", + "1065", + "1066", + "1067", + "1068", + "1069", + "107", + "1070", + "1071", + "1072", + "1073", + "1074", + "1075", + "1076", + "1077", + "1078", + "1079", + "108", + "1080", + "1081", + "1082", + "1083", + "1084", + "1085", + "1086", + "1087", + "1088", + "1089", + "109", + "1090", + "1091", + "1092", + "1093", + "1094", + "1095", + "1096", + "1097", + "1098", + "1099", + "110", + "1100", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "641", + "642", + "643", + "644", + "645", + "646", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "656", + "657", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "673", + "674", + "675", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "768", + "769", + "770", + "771", + "772", + "773", + "774", + "775", + "776", + "777", + "778", + "779", + "780", + "781", + "782", + "783", + "784", + "785", + "786", + "787", + "788", + "789", + "790", + "791", + "792", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/updatable_views.test b/parser/testdata/summary_truncate/postgres_regress/updatable_views.test new file mode 100644 index 0000000..672d695 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/updatable_views.test @@ -0,0 +1,9450 @@ +== 001 +-- truncate_limit: 100 +|-- +-- UPDATABLE VIEWS +|-- + +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET extra_float_digits TO 0" +== 002 +-- truncate_limit: 100 +-- check that non-updatable views and columns are rejected with useful error +-- messages + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified')" +== 003 +-- truncate_limit: 100 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i)" +== 004 +-- truncate_limit: 100 +CREATE VIEW ro_view1 AS SELECT DISTINCT a, b FROM base_tbl +-- +TABLE: name="ro_view1" schema="" table="ro_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view1 AS SELECT DISTINCT a, b FROM base_tbl" +== 005 +-- truncate_limit: 100 +-- DISTINCT not supported +CREATE VIEW ro_view2 AS SELECT a, b FROM base_tbl GROUP BY a, b +-- +TABLE: name="ro_view2" schema="" table="ro_view2" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view2 AS SELECT a, b FROM base_tbl GROUP BY a, b" +== 006 +-- truncate_limit: 100 +-- GROUP BY not supported +CREATE VIEW ro_view3 AS SELECT 1 FROM base_tbl HAVING max(a) > 0 +-- +TABLE: name="ro_view3" schema="" table="ro_view3" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view3 AS SELECT 1 FROM base_tbl HAVING max(a) > 0" +== 007 +-- truncate_limit: 100 +-- HAVING not supported +CREATE VIEW ro_view4 AS SELECT count(*) FROM base_tbl +-- +TABLE: name="ro_view4" schema="" table="ro_view4" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view4 AS SELECT count(*) FROM base_tbl" +== 008 +-- truncate_limit: 100 +-- Aggregate functions not supported +CREATE VIEW ro_view5 AS SELECT a, rank() OVER() FROM base_tbl +-- +TABLE: name="ro_view5" schema="" table="ro_view5" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view5 AS SELECT a, rank() OVER () FROM base_tbl" +== 009 +-- truncate_limit: 100 +-- Window functions not supported +CREATE VIEW ro_view6 AS SELECT a, b FROM base_tbl UNION SELECT -a, b FROM base_tbl +-- +TABLE: name="ro_view6" schema="" table="ro_view6" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view6 AS SELECT a, b FROM base_tbl UNION SELECT - a, b FROM base_tbl" +== 010 +-- truncate_limit: 100 +-- Set ops not supported +CREATE VIEW ro_view7 AS WITH t AS (SELECT a, b FROM base_tbl) SELECT * FROM t +-- +TABLE: name="ro_view7" schema="" table="ro_view7" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +CTE: "t" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view7 AS WITH t AS (SELECT a, b FROM base_tbl) SELECT * FROM t" +== 011 +-- truncate_limit: 100 +-- WITH not supported +CREATE VIEW ro_view8 AS SELECT a, b FROM base_tbl ORDER BY a OFFSET 1 +-- +TABLE: name="ro_view8" schema="" table="ro_view8" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view8 AS SELECT a, b FROM base_tbl ORDER BY a OFFSET 1" +== 012 +-- truncate_limit: 100 +-- OFFSET not supported +CREATE VIEW ro_view9 AS SELECT a, b FROM base_tbl ORDER BY a LIMIT 1 +-- +TABLE: name="ro_view9" schema="" table="ro_view9" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view9 AS SELECT a, b FROM base_tbl ORDER BY a LIMIT 1" +== 013 +-- truncate_limit: 100 +-- LIMIT not supported +CREATE VIEW ro_view10 AS SELECT 1 AS a +-- +TABLE: name="ro_view10" schema="" table="ro_view10" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view10 AS SELECT 1 AS a" +== 014 +-- truncate_limit: 100 +-- No base relations +CREATE VIEW ro_view11 AS SELECT b1.a, b2.b FROM base_tbl b1, base_tbl b2 +-- +TABLE: name="ro_view11" schema="" table="ro_view11" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +ALIAS: "b1"="base_tbl" +ALIAS: "b2"="base_tbl" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view11 AS SELECT b1.a, b2.b FROM base_tbl b1, base_tbl b2" +== 015 +-- truncate_limit: 100 +-- Multiple base relations +CREATE VIEW ro_view12 AS SELECT * FROM generate_series(1, 10) AS g(a) +-- +TABLE: name="ro_view12" schema="" table="ro_view12" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view12 AS SELECT * FROM generate_series(1, 10) g(a)" +== 016 +-- truncate_limit: 100 +-- SRF in rangetable +CREATE VIEW ro_view13 AS SELECT a, b FROM (SELECT * FROM base_tbl) AS t +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view13 AS SELECT a, b FROM (SELECT * FROM base_tbl) t" +== 017 +-- truncate_limit: 100 +-- Subselect in rangetable +CREATE VIEW rw_view14 AS SELECT ctid, a, b FROM base_tbl +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view14 AS SELECT ctid, a, b FROM base_tbl" +== 018 +-- truncate_limit: 100 +-- System columns may be part of an updatable view +CREATE VIEW rw_view15 AS SELECT a, upper(b) FROM base_tbl +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view15 AS SELECT a, upper(b) FROM base_tbl" +== 019 +-- truncate_limit: 100 +-- Expression/function may be part of an updatable view +CREATE VIEW rw_view16 AS SELECT a, b, a AS aa FROM base_tbl +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view16 AS SELECT a, b, a AS aa FROM base_tbl" +== 020 +-- truncate_limit: 100 +-- Repeated column may be part of an updatable view +CREATE VIEW ro_view17 AS SELECT * FROM ro_view1 +-- +TABLE: name="ro_view17" schema="" table="ro_view17" ctx=DDL +TABLE: name="ro_view1" schema="" table="ro_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view17 AS SELECT * FROM ro_view1" +== 021 +-- truncate_limit: 100 +-- Base relation not updatable +CREATE VIEW ro_view18 AS SELECT * FROM (VALUES(1)) AS tmp(a) +-- +TABLE: name="ro_view18" schema="" table="ro_view18" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view18 AS SELECT * FROM (VALUES (1)) tmp(a)" +== 022 +-- truncate_limit: 100 +-- VALUES in rangetable +CREATE SEQUENCE uv_seq +-- +STMT: CreateSeqStmt +TRUNCATED: "CREATE SEQUENCE uv_seq" +== 023 +-- truncate_limit: 100 +CREATE VIEW ro_view19 AS SELECT * FROM uv_seq +-- +TABLE: name="ro_view19" schema="" table="ro_view19" ctx=DDL +TABLE: name="uv_seq" schema="" table="uv_seq" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view19 AS SELECT * FROM uv_seq" +== 024 +-- truncate_limit: 100 +-- View based on a sequence +CREATE VIEW ro_view20 AS SELECT a, b, generate_series(1, a) g FROM base_tbl +-- +TABLE: name="ro_view20" schema="" table="ro_view20" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW ro_view20 AS SELECT a, b, generate_series(1, a) AS g FROM base_tbl" +== 025 +-- truncate_limit: 100 +-- SRF in targetlist not supported + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE E'r_\\\\_view%' ORDER BY table_name" +== 026 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE E'r_\\\\_view%' ORDER BY table_name" +== 027 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 028 +-- truncate_limit: 100 +-- Read-only views +DELETE FROM ro_view1 +-- +TABLE: name="ro_view1" schema="" table="ro_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ro_view1" +== 029 +-- truncate_limit: 100 +DELETE FROM ro_view2 +-- +TABLE: name="ro_view2" schema="" table="ro_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ro_view2" +== 030 +-- truncate_limit: 100 +DELETE FROM ro_view3 +-- +TABLE: name="ro_view3" schema="" table="ro_view3" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ro_view3" +== 031 +-- truncate_limit: 100 +DELETE FROM ro_view4 +-- +TABLE: name="ro_view4" schema="" table="ro_view4" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ro_view4" +== 032 +-- truncate_limit: 100 +DELETE FROM ro_view5 +-- +TABLE: name="ro_view5" schema="" table="ro_view5" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ro_view5" +== 033 +-- truncate_limit: 100 +DELETE FROM ro_view6 +-- +TABLE: name="ro_view6" schema="" table="ro_view6" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ro_view6" +== 034 +-- truncate_limit: 100 +UPDATE ro_view7 SET a=a+1 +-- +TABLE: name="ro_view7" schema="" table="ro_view7" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view7 SET a = a + 1" +== 035 +-- truncate_limit: 100 +UPDATE ro_view8 SET a=a+1 +-- +TABLE: name="ro_view8" schema="" table="ro_view8" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view8 SET a = a + 1" +== 036 +-- truncate_limit: 100 +UPDATE ro_view9 SET a=a+1 +-- +TABLE: name="ro_view9" schema="" table="ro_view9" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view9 SET a = a + 1" +== 037 +-- truncate_limit: 100 +UPDATE ro_view10 SET a=a+1 +-- +TABLE: name="ro_view10" schema="" table="ro_view10" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view10 SET a = a + 1" +== 038 +-- truncate_limit: 100 +UPDATE ro_view11 SET a=a+1 +-- +TABLE: name="ro_view11" schema="" table="ro_view11" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view11 SET a = a + 1" +== 039 +-- truncate_limit: 100 +UPDATE ro_view12 SET a=a+1 +-- +TABLE: name="ro_view12" schema="" table="ro_view12" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view12 SET a = a + 1" +== 040 +-- truncate_limit: 100 +INSERT INTO ro_view13 VALUES (3, 'Row 3') +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ro_view13 VALUES (3, 'Row 3')" +== 041 +-- truncate_limit: 100 +MERGE INTO ro_view13 AS t USING (VALUES (1, 'Row 1')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ro_view13 t USING (VALUES (1, 'Row 1')) v(a, b) ON t.a = v.a WHEN MATCHED THEN DELETE" +== 042 +-- truncate_limit: 100 +MERGE INTO ro_view13 AS t USING (VALUES (2, 'Row 2')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = v.b +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ro_view13 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b =..." +== 043 +-- truncate_limit: 100 +MERGE INTO ro_view13 AS t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.b) +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ro_view13 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VAL..." +== 044 +-- truncate_limit: 100 +MERGE INTO ro_view13 AS t USING (VALUES (2, 'Row 2')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN DO NOTHING +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ro_view13 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED THEN DO NOTHING WHE..." +== 045 +-- truncate_limit: 100 +-- should be OK to do nothing +MERGE INTO ro_view13 AS t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN DO NOTHING +-- +TABLE: name="ro_view13" schema="" table="ro_view13" ctx=DML +ALIAS: "t"="ro_view13" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ro_view13 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED THEN DO NOTHING WHE..." +== 046 +-- truncate_limit: 100 +-- should be OK to do nothing +-- Partially updatable view +INSERT INTO rw_view14 VALUES (null, 3, 'Row 3') +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view14 VALUES (NULL, 3, 'Row 3')" +== 047 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view14 (a, b) VALUES (3, 'Row 3') +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view14 (a, b) VALUES (3, 'Row 3')" +== 048 +-- truncate_limit: 100 +-- should be OK +UPDATE rw_view14 SET ctid=null WHERE a=3 +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view14 SET ctid = NULL WHERE a = 3" +== 049 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view14 SET b='ROW 3' WHERE a=3 +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view14 SET b = 'ROW 3' WHERE a = 3" +== 050 +-- truncate_limit: 100 +-- should be OK +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 051 +-- truncate_limit: 100 +DELETE FROM rw_view14 WHERE a=3 +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view14 WHERE a = 3" +== 052 +-- truncate_limit: 100 +-- should be OK +MERGE INTO rw_view14 AS t + USING (VALUES (2, 'Merged row 2'), (3, 'Merged row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = v.b -- should be OK, except... + WHEN NOT MATCHED THEN INSERT VALUES (null, v.a, v.b) +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +ALIAS: "t"="rw_view14" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view14 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b =..." +== 053 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view14 AS t + USING (VALUES (2, 'Merged row 2'), (3, 'Merged row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = v.b -- should be OK + WHEN NOT MATCHED THEN INSERT (a,b) VALUES (v.a, v.b) +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +ALIAS: "t"="rw_view14" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view14 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b =..." +== 054 +-- truncate_limit: 100 +-- should be OK +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 055 +-- truncate_limit: 100 +MERGE INTO rw_view14 AS t + USING (VALUES (2, 'Row 2'), (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED AND t.a = 2 THEN UPDATE SET b = v.b -- should be OK + WHEN MATCHED AND t.a = 3 THEN DELETE +-- +TABLE: name="rw_view14" schema="" table="rw_view14" ctx=DML +ALIAS: "t"="rw_view14" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view14 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED AND t.a = 2 THEN UP..." +== 056 +-- truncate_limit: 100 +-- should be OK +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 057 +-- truncate_limit: 100 +-- Partially updatable view +INSERT INTO rw_view15 VALUES (3, 'ROW 3') +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view15 VALUES (3, 'ROW 3')" +== 058 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view15 (a) VALUES (3) +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view15 (a) VALUES (3)" +== 059 +-- truncate_limit: 100 +-- should be OK +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT DO NOTHING +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT DO NOTHING" +== 060 +-- truncate_limit: 100 +-- succeeds +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view15" +== 061 +-- truncate_limit: 100 +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO NOTHING +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO NOTHING" +== 062 +-- truncate_limit: 100 +-- succeeds +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view15" +== 063 +-- truncate_limit: 100 +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE set a = excluded.a +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE SET a = excluded.a" +== 064 +-- truncate_limit: 100 +-- succeeds +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view15" +== 065 +-- truncate_limit: 100 +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE set upper = 'blarg' +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE SET upper = 'blarg'" +== 066 +-- truncate_limit: 100 +-- fails +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view15" +== 067 +-- truncate_limit: 100 +SELECT * FROM rw_view15 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view15" +== 068 +-- truncate_limit: 100 +ALTER VIEW rw_view15 ALTER COLUMN upper SET DEFAULT 'NOT SET' +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view15 ALTER COLUMN upper SET DEFAULT 'NOT SET'" +== 069 +-- truncate_limit: 100 +INSERT INTO rw_view15 (a) VALUES (4) +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view15 (a) VALUES (4)" +== 070 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view15 SET upper='ROW 3' WHERE a=3 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view15 SET upper = 'ROW 3' WHERE a = 3" +== 071 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view15 SET upper=DEFAULT WHERE a=3 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view15 SET upper = DEFAULT WHERE a = 3" +== 072 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view15 SET a=4 WHERE a=3 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view15 SET a = 4 WHERE a = 3" +== 073 +-- truncate_limit: 100 +-- should be OK +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 074 +-- truncate_limit: 100 +DELETE FROM rw_view15 WHERE a=4 +-- +TABLE: name="rw_view15" schema="" table="rw_view15" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view15 WHERE a = 4" +== 075 +-- truncate_limit: 100 +-- should be OK +-- Partially updatable view +INSERT INTO rw_view16 VALUES (3, 'Row 3', 3) +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view16 VALUES (3, 'Row 3', 3)" +== 076 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3') +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3')" +== 077 +-- truncate_limit: 100 +-- should be OK +UPDATE rw_view16 SET a=3, aa=-3 WHERE a=3 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view16 SET a = 3, aa = -3 WHERE a = 3" +== 078 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view16 SET aa=-3 WHERE a=3 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view16 SET aa = -3 WHERE a = 3" +== 079 +-- truncate_limit: 100 +-- should be OK +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 080 +-- truncate_limit: 100 +DELETE FROM rw_view16 WHERE a=-3 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view16 WHERE a = -3" +== 081 +-- truncate_limit: 100 +-- should be OK +-- Read-only views +INSERT INTO ro_view17 VALUES (3, 'ROW 3') +-- +TABLE: name="ro_view17" schema="" table="ro_view17" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ro_view17 VALUES (3, 'ROW 3')" +== 082 +-- truncate_limit: 100 +DELETE FROM ro_view18 +-- +TABLE: name="ro_view18" schema="" table="ro_view18" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ro_view18" +== 083 +-- truncate_limit: 100 +MERGE INTO ro_view18 AS t USING (VALUES (1, 'Row 1')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING +-- +TABLE: name="ro_view18" schema="" table="ro_view18" ctx=DML +ALIAS: "t"="ro_view18" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ro_view18 t USING (VALUES (1, 'Row 1')) v(a, b) ON t.a = v.a WHEN MATCHED THEN DO NOTHING" +== 084 +-- truncate_limit: 100 +-- should be OK to do nothing +UPDATE ro_view19 SET last_value=1000 +-- +TABLE: name="ro_view19" schema="" table="ro_view19" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view19 SET last_value = 1000" +== 085 +-- truncate_limit: 100 +UPDATE ro_view20 SET b=upper(b) +-- +TABLE: name="ro_view20" schema="" table="ro_view20" ctx=DML +FUNCTION: name="upper" function="upper" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE ro_view20 SET b = upper(b)" +== 086 +-- truncate_limit: 100 +-- A view with a conditional INSTEAD rule but no unconditional INSTEAD rules +-- or INSTEAD OF triggers should be non-updatable and generate useful error +-- messages with appropriate detail +CREATE RULE rw_view16_ins_rule AS ON INSERT TO rw_view16 + WHERE NEW.a > 0 DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, NEW.b) +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view16_ins_rule AS ON INSERT TO rw_view16 WHERE ... DO INSTEAD INSERT INTO base_tb..." +== 087 +-- truncate_limit: 100 +CREATE RULE rw_view16_upd_rule AS ON UPDATE TO rw_view16 + WHERE OLD.a > 0 DO INSTEAD UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view16_upd_rule AS ON UPDATE TO rw_view16 WHERE ... DO INSTEAD UPDATE base_tbl SET..." +== 088 +-- truncate_limit: 100 +CREATE RULE rw_view16_del_rule AS ON DELETE TO rw_view16 + WHERE OLD.a > 0 DO INSTEAD DELETE FROM base_tbl WHERE a=OLD.a +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view16_del_rule AS ON DELETE TO rw_view16 WHERE ... DO INSTEAD DELETE FROM base_tb..." +== 089 +-- truncate_limit: 100 +INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3') +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3')" +== 090 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view16 SET b='ROW 2' WHERE a=2 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view16 SET b = 'ROW 2' WHERE a = 2" +== 091 +-- truncate_limit: 100 +-- should fail +DELETE FROM rw_view16 WHERE a=2 +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view16 WHERE a = 2" +== 092 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view16 AS t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.b) +-- +TABLE: name="rw_view16" schema="" table="rw_view16" ctx=DML +ALIAS: "t"="rw_view16" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view16 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VAL..." +== 093 +-- truncate_limit: 100 +-- should fail + +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 094 +-- truncate_limit: 100 +DROP VIEW ro_view10, ro_view12, ro_view18 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW ro_view10, ro_view12, ro_view18" +== 095 +-- truncate_limit: 100 +DROP SEQUENCE uv_seq CASCADE +-- +STMT: DropStmt +TRUNCATED: "DROP SEQUENCE uv_seq CASCADE" +== 096 +-- truncate_limit: 100 +-- simple updatable view + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified')" +== 097 +-- truncate_limit: 100 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i)" +== 098 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a>0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a > 0" +== 099 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT table_name, is_insertable_into FROM information_schema.tables WHERE table_name = 'rw_view1'" +== 100 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name = 'rw_view1'" +== 101 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view1' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name = 'rw_view1' ORDER BY ordinal_position" +== 102 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (3, 'Row 3') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (3, 'Row 3')" +== 103 +-- truncate_limit: 100 +INSERT INTO rw_view1 (a) VALUES (4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (a) VALUES (4)" +== 104 +-- truncate_limit: 100 +UPDATE rw_view1 SET a=5 WHERE a=4 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET a = 5 WHERE a = 4" +== 105 +-- truncate_limit: 100 +DELETE FROM rw_view1 WHERE b='Row 2' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE b = 'Row 2'" +== 106 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 107 +-- truncate_limit: 100 +MERGE INTO rw_view1 t + USING (VALUES (0, 'ROW 0'), (1, 'ROW 1'), + (2, 'ROW 2'), (3, 'ROW 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED AND t.a <= 1 THEN UPDATE SET b = v.b + WHEN MATCHED THEN DELETE + WHEN NOT MATCHED AND a > 0 THEN INSERT (a) VALUES (v.a) + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED AND t.a <= 1 THEN UP..." +== 108 +-- truncate_limit: 100 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 109 +-- truncate_limit: 100 +MERGE INTO rw_view1 t + USING (VALUES (0, 'R0'), (1, 'R1'), + (2, 'R2'), (3, 'R3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED AND t.a <= 1 THEN UPDATE SET b = v.b + WHEN MATCHED THEN DELETE + WHEN NOT MATCHED BY SOURCE THEN DELETE + WHEN NOT MATCHED AND a > 0 THEN INSERT (a) VALUES (v.a) + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED AND t.a <= 1 THEN UP..." +== 110 +-- truncate_limit: 100 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 111 +-- truncate_limit: 100 +EXPLAIN (costs off) UPDATE rw_view1 SET a=6 WHERE a=5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view1 SET a = 6 WHERE a = 5" +== 112 +-- truncate_limit: 100 +EXPLAIN (costs off) DELETE FROM rw_view1 WHERE a=5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM rw_view1 WHERE a = 5" +== 113 +-- truncate_limit: 100 +EXPLAIN (costs off) +MERGE INTO rw_view1 t USING (VALUES (5, 'X')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO rw_view1 t USING (VALUES (5, 'X')) v(a, b) ON t.a = v.a WHEN MATCH..." +== 114 +-- truncate_limit: 100 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (SELECT * FROM generate_series(1,5)) AS s(a) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = 'Updated' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO rw_view1 t USING (SELECT * FROM generate_series(1, 5)) s(a) ON t.a..." +== 115 +-- truncate_limit: 100 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (SELECT * FROM generate_series(1,5)) AS s(a) ON t.a = s.a + WHEN NOT MATCHED BY SOURCE THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO rw_view1 t USING (SELECT * FROM generate_series(1, 5)) s(a) ON t.a..." +== 116 +-- truncate_limit: 100 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (SELECT * FROM generate_series(1,5)) AS s(a) ON t.a = s.a + WHEN NOT MATCHED THEN INSERT (a) VALUES (s.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO rw_view1 t USING (SELECT * FROM generate_series(1, 5)) s(a) ON t.a..." +== 117 +-- truncate_limit: 100 +-- it's still updatable if we add a DO ALSO rule + +CREATE TABLE base_tbl_hist(ts timestamptz default now(), a int, b text) +-- +TABLE: name="base_tbl_hist" schema="" table="base_tbl_hist" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl_hist (ts timestamptz DEFAULT now(), a int, b text)" +== 118 +-- truncate_limit: 100 +CREATE RULE base_tbl_log AS ON INSERT TO rw_view1 DO ALSO + INSERT INTO base_tbl_hist(a,b) VALUES(new.a, new.b) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE base_tbl_log AS ON INSERT TO rw_view1 DO INSERT INTO base_tbl_hist (a, b) VALUES (new..." +== 119 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name = 'rw_view1'" +== 120 +-- truncate_limit: 100 +-- Check behavior with DEFAULTs (bug #17633) + +INSERT INTO rw_view1 VALUES (9, DEFAULT), (10, DEFAULT) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (9, DEFAULT), (10, DEFAULT)" +== 121 +-- truncate_limit: 100 +SELECT a, b FROM base_tbl_hist +-- +TABLE: name="base_tbl_hist" schema="" table="base_tbl_hist" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT a, b FROM base_tbl_hist" +== 122 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 123 +-- truncate_limit: 100 +DROP TABLE base_tbl_hist +-- +TABLE: name="base_tbl_hist" schema="" table="base_tbl_hist" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl_hist" +== 124 +-- truncate_limit: 100 +-- view on top of view + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified')" +== 125 +-- truncate_limit: 100 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i)" +== 126 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl WHERE a>0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl WHERE a > 0" +== 127 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS SELECT aa AS aaa, bb AS bbb FROM rw_view1 WHERE aa<10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="aa" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT aa AS aaa, bb AS bbb FROM rw_view1 WHERE aa < 10" +== 128 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT table_name, is_insertable_into FROM information_schema.tables WHERE table_name = 'rw_view2'" +== 129 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name = 'rw_view2'" +== 130 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view2' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name = 'rw_view2' ORDER BY ordinal_position" +== 131 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (3, 'Row 3') +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (3, 'Row 3')" +== 132 +-- truncate_limit: 100 +INSERT INTO rw_view2 (aaa) VALUES (4) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 (aaa) VALUES (4)" +== 133 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 134 +-- truncate_limit: 100 +UPDATE rw_view2 SET bbb='Row 4' WHERE aaa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = 'Row 4' WHERE aaa = 4" +== 135 +-- truncate_limit: 100 +DELETE FROM rw_view2 WHERE aaa=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE aaa = 2" +== 136 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 137 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (VALUES (3, 'R3'), (4, 'R4'), (5, 'R5')) AS v(a,b) ON aaa = v.a + WHEN MATCHED AND aaa = 3 THEN DELETE + WHEN MATCHED THEN UPDATE SET bbb = v.b + WHEN NOT MATCHED THEN INSERT (aaa) VALUES (v.a) + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (...)) v(a, b) ON aaa = v.a WHEN MATCHED AND aaa = 3 THEN DEL..." +== 138 +-- truncate_limit: 100 +SELECT * FROM rw_view2 ORDER BY aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 ORDER BY aaa" +== 139 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (VALUES (4, 'r4'), (5, 'r5'), (6, 'r6')) AS v(a,b) ON aaa = v.a + WHEN MATCHED AND aaa = 4 THEN DELETE + WHEN MATCHED THEN UPDATE SET bbb = v.b + WHEN NOT MATCHED THEN INSERT (aaa) VALUES (v.a) + WHEN NOT MATCHED BY SOURCE THEN UPDATE SET bbb = 'Not matched by source' + RETURNING merge_action(), v.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (...)) v(a, b) ON aaa = v.a WHEN MATCHED AND aaa = 4 THEN DEL..." +== 140 +-- truncate_limit: 100 +SELECT * FROM rw_view2 ORDER BY aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 ORDER BY aaa" +== 141 +-- truncate_limit: 100 +EXPLAIN (costs off) UPDATE rw_view2 SET aaa=5 WHERE aaa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view2 SET aaa = 5 WHERE aaa = 4" +== 142 +-- truncate_limit: 100 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE aaa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM rw_view2 WHERE aaa = 4" +== 143 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 144 +-- truncate_limit: 100 +-- view on top of view with rules + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified')" +== 145 +-- truncate_limit: 100 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i)" +== 146 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a>0 OFFSET 0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a > 0 OFFSET 0" +== 147 +-- truncate_limit: 100 +-- not updatable without rules/triggers +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a<10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10" +== 148 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 149 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 150 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 151 +-- truncate_limit: 100 +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, NEW.b) RETURNING * +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 DO INSTEAD INSERT INTO base_tbl VALUES (ne..." +== 152 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 153 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 154 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 155 +-- truncate_limit: 100 +CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 + DO INSTEAD UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a RETURNING NEW.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 DO INSTEAD UPDATE base_tbl SET b = new.b W..." +== 156 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 157 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 158 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 159 +-- truncate_limit: 100 +CREATE RULE rw_view1_del_rule AS ON DELETE TO rw_view1 + DO INSTEAD DELETE FROM base_tbl WHERE a=OLD.a RETURNING OLD.* +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view1_del_rule AS ON DELETE TO rw_view1 DO INSTEAD DELETE FROM base_tbl WHERE a = ..." +== 160 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 161 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 162 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 163 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING *" +== 164 +-- truncate_limit: 100 +UPDATE rw_view2 SET b='Row three' WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'Row three' WHERE a = 3 RETURNING *" +== 165 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 166 +-- truncate_limit: 100 +DELETE FROM rw_view2 WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE a = 3 RETURNING *" +== 167 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 168 +-- truncate_limit: 100 +MERGE INTO rw_view2 t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VALU..." +== 169 +-- truncate_limit: 100 +-- should fail + +EXPLAIN (costs off) UPDATE rw_view2 SET a=3 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view2 SET a = 3 WHERE a = 2" +== 170 +-- truncate_limit: 100 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM rw_view2 WHERE a = 2" +== 171 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 172 +-- truncate_limit: 100 +-- view on top of view with triggers + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified')" +== 173 +-- truncate_limit: 100 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i)" +== 174 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a>0 OFFSET 0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a > 0 OFFSET 0" +== 175 +-- truncate_limit: 100 +-- not updatable without rules/triggers +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a<10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10" +== 176 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 177 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 178 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 179 +-- truncate_limit: 100 +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + INSERT INTO base_tbl VALUES (NEW.a, NEW.b); + RETURN NEW; + ELSIF TG_OP = 'UPDATE' THEN + UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a; + RETURN NEW; + ELSIF TG_OP = 'DELETE' THEN + DELETE FROM base_tbl WHERE a=OLD.a; + RETURN OLD; + END IF; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rw_view1_trig_fn() RETURNS trigger AS $$\nBEGIN\n IF TG_OP = 'INSERT' THEN\n INS..." +== 180 +-- truncate_limit: 100 +CREATE TRIGGER rw_view1_ins_trig INSTEAD OF INSERT ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER rw_view1_ins_trig INSTEAD OF INSERT ON rw_view1 FOR EACH ROW EXECUTE FUNCTION rw_v..." +== 181 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 182 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 183 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 184 +-- truncate_limit: 100 +CREATE TRIGGER rw_view1_upd_trig INSTEAD OF UPDATE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER rw_view1_upd_trig INSTEAD OF UPDATE ON rw_view1 FOR EACH ROW EXECUTE FUNCTION rw_v..." +== 185 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 186 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 187 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 188 +-- truncate_limit: 100 +CREATE TRIGGER rw_view1_del_trig INSTEAD OF DELETE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER rw_view1_del_trig INSTEAD OF DELETE ON rw_view1 FOR EACH ROW EXECUTE FUNCTION rw_v..." +== 189 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 190 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'rw_view%' ORDER BY table_name" +== 191 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 192 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING *" +== 193 +-- truncate_limit: 100 +UPDATE rw_view2 SET b='Row three' WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'Row three' WHERE a = 3 RETURNING *" +== 194 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 195 +-- truncate_limit: 100 +DELETE FROM rw_view2 WHERE a=3 RETURNING * +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE a = 3 RETURNING *" +== 196 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 197 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED AND t.a <= 1 THEN DELETE + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) + RETURNING merge_action(), s.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 3) x) s(a, b) ON t.a = s.a WHEN M..." +== 198 +-- truncate_limit: 100 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 199 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (SELECT x, 'r'||x FROM generate_series(0,2) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) + WHEN NOT MATCHED BY SOURCE THEN UPDATE SET b = 'Not matched by source' + RETURNING merge_action(), s.*, t.* +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 2) x) s(a, b) ON t.a = s.a WHEN M..." +== 200 +-- truncate_limit: 100 +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 201 +-- truncate_limit: 100 +EXPLAIN (costs off) UPDATE rw_view2 SET a=3 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view2 SET a = 3 WHERE a = 2" +== 202 +-- truncate_limit: 100 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE a=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM rw_view2 WHERE a = 2" +== 203 +-- truncate_limit: 100 +EXPLAIN (costs off) +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED AND t.a <= 1 THEN DELETE + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO rw_view2 t USING (SELECT x, 'R' || x FROM generate_series(0, 3) x)..." +== 204 +-- truncate_limit: 100 +-- MERGE with incomplete set of INSTEAD OF triggers +DROP TRIGGER rw_view1_del_trig ON rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER rw_view1_del_trig ON rw_view1" +== 205 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED AND t.a <= 1 THEN DELETE + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 3) x) s(a, b) ON t.a = s.a WHEN M..." +== 206 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 3) x) s(a, b) ON t.a = s.a WHEN M..." +== 207 +-- truncate_limit: 100 +-- ok + +DROP TRIGGER rw_view1_ins_trig ON rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER rw_view1_ins_trig ON rw_view1" +== 208 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 3) x) s(a, b) ON t.a = s.a WHEN M..." +== 209 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 3) x) s(a, b) ON t.a = s.a WHEN M..." +== 210 +-- truncate_limit: 100 +-- ok + +-- MERGE with INSTEAD OF triggers on auto-updatable view +CREATE TRIGGER rw_view2_upd_trig INSTEAD OF UPDATE ON rw_view2 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER rw_view2_upd_trig INSTEAD OF UPDATE ON rw_view2 FOR EACH ROW EXECUTE FUNCTION rw_v..." +== 211 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b + WHEN NOT MATCHED AND s.a > 0 THEN INSERT VALUES (s.a, s.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 3) x) s(a, b) ON t.a = s.a WHEN M..." +== 212 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view2 t + USING (SELECT x, 'R'||x FROM generate_series(0,3) x) AS s(a,b) ON t.a = s.a + WHEN MATCHED THEN UPDATE SET b = s.b +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (SELECT ... FROM generate_series(0, 3) x) s(a, b) ON t.a = s.a WHEN M..." +== 213 +-- truncate_limit: 100 +-- ok +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 214 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 215 +-- truncate_limit: 100 +DROP FUNCTION rw_view1_trig_fn() +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rw_view1_trig_fn()" +== 216 +-- truncate_limit: 100 +-- update using whole row from view + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified')" +== 217 +-- truncate_limit: 100 +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i)" +== 218 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl" +== 219 +-- truncate_limit: 100 +CREATE FUNCTION rw_view1_aa(x rw_view1) + RETURNS int AS $$ SELECT x.aa $$ LANGUAGE sql +-- +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rw_view1_aa(x rw_view1) RETURNS int AS $$ SELECT x.aa $$ LANGUAGE sql" +== 220 +-- truncate_limit: 100 +UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2 + RETURNING rw_view1_aa(v), v.bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "v"="rw_view1" +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 v SET bb = 'Updated row 2' WHERE rw_view1_aa(v) = 2 RETURNING rw_view1_aa(v), v.bb" +== 221 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 222 +-- truncate_limit: 100 +EXPLAIN (costs off) +UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2 + RETURNING rw_view1_aa(v), v.bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "v"="rw_view1" +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +FUNCTION: name="rw_view1_aa" function="rw_view1_aa" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view1 v SET bb = 'Updated row 2' WHERE rw_view1_aa(v) = 2 RETURNING..." +== 223 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 224 +-- truncate_limit: 100 +-- permissions checks + +CREATE USER regress_view_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_view_user1" +== 225 +-- truncate_limit: 100 +CREATE USER regress_view_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_view_user2" +== 226 +-- truncate_limit: 100 +CREATE USER regress_view_user3 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_view_user3" +== 227 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 228 +-- truncate_limit: 100 +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b text, c double precision)" +== 229 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0)" +== 230 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl" +== 231 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2)" +== 232 +-- truncate_limit: 100 +GRANT SELECT ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON base_tbl TO regress_view_user2" +== 233 +-- truncate_limit: 100 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rw_view1 TO regress_view_user2" +== 234 +-- truncate_limit: 100 +GRANT UPDATE (a,c) ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (a, c) ON base_tbl TO regress_view_user2" +== 235 +-- truncate_limit: 100 +GRANT UPDATE (bb,cc) ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (bb, cc) ON rw_view1 TO regress_view_user2" +== 236 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 237 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 238 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl" +== 239 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 240 +-- truncate_limit: 100 +-- ok +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 241 +-- truncate_limit: 100 +-- ok +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 242 +-- truncate_limit: 100 +-- ok + +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0)" +== 243 +-- truncate_limit: 100 +-- not allowed +INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3)" +== 244 +-- truncate_limit: 100 +-- not allowed +INSERT INTO rw_view2 VALUES ('Row 3', 3.0, 3) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES ('Row 3', 3.0, 3)" +== 245 +-- truncate_limit: 100 +-- not allowed + +MERGE INTO rw_view1 t + USING (VALUES ('Row 3', 3.0, 3)) AS v(b,c,a) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.b, v.c, v.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (...)) v(b, c, a) ON t.aa = v.a WHEN NOT MATCHED THEN INSERT ..." +== 246 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t + USING (VALUES ('Row 3', 3.0, 3)) AS v(b,c,a) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.b, v.c, v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (...)) v(b, c, a) ON t.aa = v.a WHEN NOT MATCHED THEN INSERT ..." +== 247 +-- truncate_limit: 100 +-- not allowed + +UPDATE base_tbl SET a=a, c=c +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE base_tbl SET a = a, c = c" +== 248 +-- truncate_limit: 100 +-- ok +UPDATE base_tbl SET b=b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE base_tbl SET b = b" +== 249 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET bb=bb, cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET bb = bb, cc = cc" +== 250 +-- truncate_limit: 100 +-- ok +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET aa = aa" +== 251 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET aa=aa, cc=cc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aa = aa, cc = cc" +== 252 +-- truncate_limit: 100 +-- ok +UPDATE rw_view2 SET bb=bb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bb = bb" +== 253 +-- truncate_limit: 100 +-- not allowed + +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb, cc = cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET bb = bb,..." +== 254 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET aa = aa" +== 255 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa, cc = cc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET aa = aa,..." +== 256 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET bb = bb" +== 257 +-- truncate_limit: 100 +-- not allowed + +DELETE FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM base_tbl" +== 258 +-- truncate_limit: 100 +-- not allowed +DELETE FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1" +== 259 +-- truncate_limit: 100 +-- not allowed +DELETE FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2" +== 260 +-- truncate_limit: 100 +-- not allowed +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 261 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 262 +-- truncate_limit: 100 +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert, delete ON base_tbl TO regress_view_user2" +== 263 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 264 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 265 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0)" +== 266 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4)" +== 267 +-- truncate_limit: 100 +-- not allowed +INSERT INTO rw_view2 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES ('Row 4', 4.0, 4)" +== 268 +-- truncate_limit: 100 +-- ok +DELETE FROM base_tbl WHERE a=1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM base_tbl WHERE a = 1" +== 269 +-- truncate_limit: 100 +-- ok +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE aa = 2" +== 270 +-- truncate_limit: 100 +-- not allowed +DELETE FROM rw_view2 WHERE aa=2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE aa = 2" +== 271 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED AND bb = 'xxx' THEN DELETE" +== 272 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED AND bb = 'xxx' THEN DELETE" +== 273 +-- truncate_limit: 100 +-- ok +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 274 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 275 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 276 +-- truncate_limit: 100 +REVOKE INSERT, DELETE ON base_tbl FROM regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE insert, delete ON base_tbl FROM regress_view_user2" +== 277 +-- truncate_limit: 100 +GRANT INSERT, DELETE ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert, delete ON rw_view1 TO regress_view_user2" +== 278 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 279 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 280 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (5, 'Row 5', 5.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (5, 'Row 5', 5.0)" +== 281 +-- truncate_limit: 100 +-- not allowed +INSERT INTO rw_view1 VALUES ('Row 5', 5.0, 5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 5', 5.0, 5)" +== 282 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view2 VALUES ('Row 6', 6.0, 6) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES ('Row 6', 6.0, 6)" +== 283 +-- truncate_limit: 100 +-- not allowed +DELETE FROM base_tbl WHERE a=3 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM base_tbl WHERE a = 3" +== 284 +-- truncate_limit: 100 +-- not allowed +DELETE FROM rw_view1 WHERE aa=3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE aa = 3" +== 285 +-- truncate_limit: 100 +-- ok +DELETE FROM rw_view2 WHERE aa=4 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE aa = 4" +== 286 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED AND bb = 'xxx' THEN DELETE" +== 287 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED AND bb = 'xxx' THEN DELETE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED AND bb = 'xxx' THEN DELETE" +== 288 +-- truncate_limit: 100 +-- not allowed +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 289 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 290 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 291 +-- truncate_limit: 100 +-- nested-view permissions + +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b text, c double precision)" +== 292 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0)" +== 293 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 294 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl" +== 295 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 296 +-- truncate_limit: 100 +-- not allowed +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1 FOR UPDATE" +== 297 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b = 'foo' WHERE a = 1" +== 298 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 299 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 300 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM rw_view1" +== 301 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 302 +-- truncate_limit: 100 +-- not allowed +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 FOR UPDATE" +== 303 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'bar' WHERE a = 1" +== 304 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 305 +-- truncate_limit: 100 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 306 +-- truncate_limit: 100 +GRANT SELECT ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON base_tbl TO regress_view_user1" +== 307 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 308 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 309 +-- truncate_limit: 100 +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1 FOR UPDATE" +== 310 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b = 'foo' WHERE a = 1" +== 311 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 312 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 313 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 314 +-- truncate_limit: 100 +-- not allowed +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 FOR UPDATE" +== 315 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'bar' WHERE a = 1" +== 316 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 317 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 318 +-- truncate_limit: 100 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rw_view1 TO regress_view_user2" +== 319 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 320 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 321 +-- truncate_limit: 100 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 FOR UPDATE" +== 322 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'bar' WHERE a = 1" +== 323 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 324 +-- truncate_limit: 100 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 325 +-- truncate_limit: 100 +GRANT UPDATE ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON base_tbl TO regress_view_user1" +== 326 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 327 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 328 +-- truncate_limit: 100 +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1 FOR UPDATE" +== 329 +-- truncate_limit: 100 +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b = 'foo' WHERE a = 1" +== 330 +-- truncate_limit: 100 +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 331 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 332 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 333 +-- truncate_limit: 100 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 FOR UPDATE" +== 334 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'bar' WHERE a = 1" +== 335 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'bar' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'bar'" +== 336 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 337 +-- truncate_limit: 100 +GRANT UPDATE ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update ON rw_view1 TO regress_view_user2" +== 338 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 339 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 340 +-- truncate_limit: 100 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 FOR UPDATE" +== 341 +-- truncate_limit: 100 +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'bar' WHERE a = 1" +== 342 +-- truncate_limit: 100 +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'fud' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'fud'" +== 343 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 344 +-- truncate_limit: 100 +REVOKE UPDATE ON base_tbl FROM regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE update ON base_tbl FROM regress_view_user1" +== 345 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 346 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 347 +-- truncate_limit: 100 +SELECT * FROM rw_view1 FOR UPDATE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1 FOR UPDATE" +== 348 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b = 'foo' WHERE a = 1" +== 349 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 350 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 351 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 352 +-- truncate_limit: 100 +SELECT * FROM rw_view2 FOR UPDATE +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 FOR UPDATE" +== 353 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET b = 'bar' WHERE a = 1" +== 354 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET b = 'foo' +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = 'foo'" +== 355 +-- truncate_limit: 100 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 356 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 357 +-- truncate_limit: 100 +-- security invoker view permissions + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 358 +-- truncate_limit: 100 +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b text, c double precision)" +== 359 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0)" +== 360 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl" +== 361 +-- truncate_limit: 100 +ALTER VIEW rw_view1 SET (security_invoker = true) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view1 SET (security_invoker=true)" +== 362 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2)" +== 363 +-- truncate_limit: 100 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rw_view1 TO regress_view_user2" +== 364 +-- truncate_limit: 100 +GRANT UPDATE (bb,cc) ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (bb, cc) ON rw_view1 TO regress_view_user2" +== 365 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 366 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 367 +-- truncate_limit: 100 +-- not allowed +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 368 +-- truncate_limit: 100 +-- not allowed +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0)" +== 369 +-- truncate_limit: 100 +-- not allowed +INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3)" +== 370 +-- truncate_limit: 100 +-- not allowed +UPDATE base_tbl SET a=a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE base_tbl SET a = a" +== 371 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET bb=bb, cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET bb = bb, cc = cc" +== 372 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET bb = bb" +== 373 +-- truncate_limit: 100 +-- not allowed +DELETE FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM base_tbl" +== 374 +-- truncate_limit: 100 +-- not allowed +DELETE FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1" +== 375 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN DELETE" +== 376 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 377 +-- truncate_limit: 100 +GRANT SELECT ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON base_tbl TO regress_view_user2" +== 378 +-- truncate_limit: 100 +GRANT UPDATE (a,c) ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (a, c) ON base_tbl TO regress_view_user2" +== 379 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 380 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 381 +-- truncate_limit: 100 +-- ok +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 382 +-- truncate_limit: 100 +-- ok +UPDATE base_tbl SET a=a, c=c +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE base_tbl SET a = a, c = c" +== 383 +-- truncate_limit: 100 +-- ok +UPDATE base_tbl SET b=b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE base_tbl SET b = b" +== 384 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET cc = cc" +== 385 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET cc = cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET cc = cc" +== 386 +-- truncate_limit: 100 +-- ok +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET aa = aa" +== 387 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET bb=bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET bb = bb" +== 388 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET aa = aa" +== 389 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET bb = bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET bb = bb" +== 390 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 391 +-- truncate_limit: 100 +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert, delete ON base_tbl TO regress_view_user2" +== 392 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 393 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0)" +== 394 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4)" +== 395 +-- truncate_limit: 100 +-- not allowed +DELETE FROM base_tbl WHERE a=1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM base_tbl WHERE a = 1" +== 396 +-- truncate_limit: 100 +-- ok +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE aa = 2" +== 397 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN DELETE" +== 398 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 399 +-- truncate_limit: 100 +REVOKE INSERT, DELETE ON base_tbl FROM regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE insert, delete ON base_tbl FROM regress_view_user2" +== 400 +-- truncate_limit: 100 +GRANT INSERT, DELETE ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert, delete ON rw_view1 TO regress_view_user2" +== 401 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 402 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4)" +== 403 +-- truncate_limit: 100 +-- not allowed +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE aa = 2" +== 404 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN DELETE" +== 405 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 406 +-- truncate_limit: 100 +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert, delete ON base_tbl TO regress_view_user2" +== 407 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 408 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4)" +== 409 +-- truncate_limit: 100 +-- ok +DELETE FROM rw_view1 WHERE aa=2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE aa = 2" +== 410 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view1 t USING (VALUES (3)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN DELETE +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (3)) v(a) ON t.aa = v.a WHEN MATCHED THEN DELETE" +== 411 +-- truncate_limit: 100 +-- ok +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 412 +-- truncate_limit: 100 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 413 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 414 +-- truncate_limit: 100 +-- ordinary view on top of security invoker view permissions + +CREATE TABLE base_tbl(a int, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b text, c double precision)" +== 415 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0)" +== 416 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 417 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl" +== 418 +-- truncate_limit: 100 +ALTER VIEW rw_view1 SET (security_invoker = true) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view1 SET (security_invoker=true)" +== 419 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 420 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET aa = aa" +== 421 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (2, 'Row 2', 2.0)) AS v(a,b,c) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.b, v.c, v.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (...)) v(a, b, c) ON t.aa = v.a WHEN NOT MATCHED THEN INSERT ..." +== 422 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 423 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS SELECT cc AS ccc, aa AS aaa, bb AS bbb FROM rw_view1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT cc AS ccc, aa AS aaa, bb AS bbb FROM rw_view1" +== 424 +-- truncate_limit: 100 +GRANT SELECT, UPDATE ON rw_view2 TO regress_view_user3 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select, update ON rw_view2 TO regress_view_user3" +== 425 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 426 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 427 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (2, 'Row 2', 2.0)) AS v(a,b,c) ON t.aaa = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.c, v.a, v.b) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (...)) v(a, b, c) ON t.aaa = v.a WHEN NOT MATCHED THEN INSERT..." +== 428 +-- truncate_limit: 100 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 429 +-- truncate_limit: 100 +GRANT SELECT ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON base_tbl TO regress_view_user1" +== 430 +-- truncate_limit: 100 +GRANT UPDATE (a, b) ON base_tbl TO regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (a, b) ON base_tbl TO regress_view_user1" +== 431 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 432 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 433 +-- truncate_limit: 100 +-- ok +UPDATE rw_view1 SET aa=aa, bb=bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET aa = aa, bb = bb" +== 434 +-- truncate_limit: 100 +-- ok +UPDATE rw_view1 SET cc=cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET cc = cc" +== 435 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa, bb = bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET aa = aa,..." +== 436 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET cc = cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET cc = cc" +== 437 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 438 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 439 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 440 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 441 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user3" +== 442 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 443 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 444 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 445 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 446 +-- truncate_limit: 100 +GRANT SELECT ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON rw_view1 TO regress_view_user2" +== 447 +-- truncate_limit: 100 +GRANT UPDATE (bb, cc) ON rw_view1 TO regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (bb, cc) ON rw_view1 TO regress_view_user2" +== 448 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 449 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 450 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 451 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 452 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user3" +== 453 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 454 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 455 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 456 +-- truncate_limit: 100 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 457 +-- truncate_limit: 100 +GRANT SELECT ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON base_tbl TO regress_view_user2" +== 458 +-- truncate_limit: 100 +GRANT UPDATE (a, c) ON base_tbl TO regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (a, c) ON base_tbl TO regress_view_user2" +== 459 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 460 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 461 +-- truncate_limit: 100 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 462 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 463 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET ccc = ccc" +== 464 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 465 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 466 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET ccc = ccc" +== 467 +-- truncate_limit: 100 +-- ok + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user3" +== 468 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 469 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 470 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 471 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET ccc = ccc" +== 472 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 473 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 474 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET ccc = ccc" +== 475 +-- truncate_limit: 100 +-- not allowed + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 476 +-- truncate_limit: 100 +GRANT SELECT ON base_tbl TO regress_view_user3 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select ON base_tbl TO regress_view_user3" +== 477 +-- truncate_limit: 100 +GRANT UPDATE (a, c) ON base_tbl TO regress_view_user3 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (a, c) ON base_tbl TO regress_view_user3" +== 478 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user3" +== 479 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 480 +-- truncate_limit: 100 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 481 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 482 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET ccc = ccc" +== 483 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 484 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 485 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET ccc = ccc" +== 486 +-- truncate_limit: 100 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 487 +-- truncate_limit: 100 +REVOKE SELECT, UPDATE ON base_tbl FROM regress_view_user1 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select, update ON base_tbl FROM regress_view_user1" +== 488 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 489 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 490 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view1 SET aa=aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET aa = aa" +== 491 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.aa = v.a + WHEN MATCHED THEN UPDATE SET aa = aa +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.aa = v.a WHEN MATCHED THEN UPDATE SET aa = aa" +== 492 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 493 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 494 +-- truncate_limit: 100 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 495 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 496 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET ccc = ccc" +== 497 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 498 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 499 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET ccc = ccc" +== 500 +-- truncate_limit: 100 +-- ok + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user3" +== 501 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 502 +-- truncate_limit: 100 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 503 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 504 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET ccc = ccc" +== 505 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 506 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 507 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET ccc = ccc" +== 508 +-- truncate_limit: 100 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 509 +-- truncate_limit: 100 +REVOKE SELECT, UPDATE ON base_tbl FROM regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE select, update ON base_tbl FROM regress_view_user2" +== 510 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 511 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 512 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 513 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 514 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET ccc = ccc" +== 515 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 516 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 517 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET ccc = ccc" +== 518 +-- truncate_limit: 100 +-- not allowed + +SET SESSION AUTHORIZATION regress_view_user3 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user3" +== 519 +-- truncate_limit: 100 +SELECT * FROM rw_view2 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2" +== 520 +-- truncate_limit: 100 +-- ok +UPDATE rw_view2 SET aaa=aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET aaa = aaa" +== 521 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET bbb=bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET bbb = bbb" +== 522 +-- truncate_limit: 100 +-- not allowed +UPDATE rw_view2 SET ccc=ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET ccc = ccc" +== 523 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET aaa = aaa +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET aaa = aaa" +== 524 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET bbb = bbb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET bbb = bbb" +== 525 +-- truncate_limit: 100 +-- not allowed +MERGE INTO rw_view2 t USING (VALUES (1)) AS v(a) ON t.aaa = v.a + WHEN MATCHED THEN UPDATE SET ccc = ccc +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (1)) v(a) ON t.aaa = v.a WHEN MATCHED THEN UPDATE SET ccc = ccc" +== 526 +-- truncate_limit: 100 +-- ok + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 527 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 528 +-- truncate_limit: 100 +DROP USER regress_view_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_view_user1" +== 529 +-- truncate_limit: 100 +DROP USER regress_view_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_view_user2" +== 530 +-- truncate_limit: 100 +DROP USER regress_view_user3 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_view_user3" +== 531 +-- truncate_limit: 100 +-- column defaults + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified', c serial) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified', c serial)" +== 532 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1, 'Row 1') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'Row 1')" +== 533 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (2, 'Row 2') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (2, 'Row 2')" +== 534 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (3) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (3)" +== 535 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl" +== 536 +-- truncate_limit: 100 +ALTER VIEW rw_view1 ALTER COLUMN bb SET DEFAULT 'View default' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view1 ALTER COLUMN bb SET DEFAULT 'View default'" +== 537 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (4, 'Row 4') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (4, 'Row 4')" +== 538 +-- truncate_limit: 100 +INSERT INTO rw_view1 (aa) VALUES (5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (aa) VALUES (5)" +== 539 +-- truncate_limit: 100 +MERGE INTO rw_view1 t USING (VALUES (6)) AS v(a) ON t.aa = v.a + WHEN NOT MATCHED THEN INSERT (aa) VALUES (v.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (6)) v(a) ON t.aa = v.a WHEN NOT MATCHED THEN INSERT (aa) VAL..." +== 540 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 541 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 542 +-- truncate_limit: 100 +-- Table having triggers + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified')" +== 543 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1, 'Row 1') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'Row 1')" +== 544 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (2, 'Row 2') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (2, 'Row 2')" +== 545 +-- truncate_limit: 100 +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + UPDATE base_tbl SET b=NEW.b WHERE a=1; + RETURN NULL; + END IF; + RETURN NULL; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rw_view1_trig_fn() RETURNS trigger AS $$\nBEGIN\n IF TG_OP = 'INSERT' THEN\n UPD..." +== 546 +-- truncate_limit: 100 +CREATE TRIGGER rw_view1_ins_trig AFTER INSERT ON base_tbl + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER rw_view1_ins_trig AFTER INSERT ON base_tbl FOR EACH ROW EXECUTE FUNCTION rw_view1_..." +== 547 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl" +== 548 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (3, 'Row 3') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (3, 'Row 3')" +== 549 +-- truncate_limit: 100 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 550 +-- truncate_limit: 100 +DROP VIEW rw_view1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rw_view1" +== 551 +-- truncate_limit: 100 +DROP TRIGGER rw_view1_ins_trig on base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER rw_view1_ins_trig ON base_tbl" +== 552 +-- truncate_limit: 100 +DROP FUNCTION rw_view1_trig_fn() +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rw_view1_trig_fn()" +== 553 +-- truncate_limit: 100 +DROP TABLE base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl" +== 554 +-- truncate_limit: 100 +-- view with ORDER BY + +CREATE TABLE base_tbl (a int, b int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b int)" +== 555 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1,2), (4,5), (3,-3) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 2), (4, 5), (3, -3)" +== 556 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl ORDER BY a+b +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl ORDER BY a + b" +== 557 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 558 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (7,-8) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (7, -8)" +== 559 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 560 +-- truncate_limit: 100 +EXPLAIN (verbose, costs off) UPDATE rw_view1 SET b = b + 1 RETURNING * +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE rw_view1 SET b = b + 1 RETURNING *" +== 561 +-- truncate_limit: 100 +UPDATE rw_view1 SET b = b + 1 RETURNING * +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b = b + 1 RETURNING *" +== 562 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 563 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 564 +-- truncate_limit: 100 +-- multiple array-column updates + +CREATE TABLE base_tbl (a int, arr int[]) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, arr int[])" +== 565 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1,ARRAY[2]), (3,ARRAY[4]) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, ARRAY[2]), (3, ARRAY[4])" +== 566 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl" +== 567 +-- truncate_limit: 100 +UPDATE rw_view1 SET arr[1] = 42, arr[2] = 77 WHERE a = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET arr[1] = 42, arr[2] = 77 WHERE a = 3" +== 568 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 569 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 570 +-- truncate_limit: 100 +-- views with updatable and non-updatable columns + +CREATE TABLE base_tbl(a float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a double precision)" +== 571 +-- truncate_limit: 100 +INSERT INTO base_tbl SELECT i/10.0 FROM generate_series(1,10) g(i) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl SELECT i / 10.0 FROM generate_series(1, 10) g(i)" +== 572 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS + SELECT ctid, sin(a) s, a, cos(a) c + FROM base_tbl + WHERE a != 0 + ORDER BY abs(a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FUNCTION: name="sin" function="sin" schema="" ctx=Call +FUNCTION: name="cos" function="cos" schema="" ctx=Call +FUNCTION: name="abs" function="abs" schema="" ctx=Call +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT ctid, sin(a) AS s, a, cos(a) AS c FROM base_tbl WHERE a <> 0 ORDER..." +== 573 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (null, null, 1.1, null) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (NULL, NULL, 1.1, NULL)" +== 574 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view1 (s, c, a) VALUES (null, null, 1.1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (s, c, a) VALUES (NULL, NULL, 1.1)" +== 575 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view1 (s, c, a) VALUES (default, default, 1.1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (s, c, a) VALUES (DEFAULT, DEFAULT, 1.1)" +== 576 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view1 (a) VALUES (1.1) RETURNING a, s, c +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (a) VALUES (1.1) RETURNING a, s, c" +== 577 +-- truncate_limit: 100 +-- OK +UPDATE rw_view1 SET s = s WHERE a = 1.1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET s = s WHERE a = 1.1" +== 578 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view1 SET a = 1.05 WHERE a = 1.1 RETURNING s +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET a = 1.05 WHERE a = 1.1 RETURNING s" +== 579 +-- truncate_limit: 100 +-- OK +DELETE FROM rw_view1 WHERE a = 1.05 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE a = 1.05" +== 580 +-- truncate_limit: 100 +-- OK + +CREATE VIEW rw_view2 AS + SELECT s, c, s/c t, a base_a, ctid + FROM rw_view1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT s, c, s / c AS t, a AS base_a, ctid FROM rw_view1" +== 581 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (null, null, null, 1.1, null) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (NULL, NULL, NULL, 1.1, NULL)" +== 582 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view2(s, c, base_a) VALUES (null, null, 1.1) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 (s, c, base_a) VALUES (NULL, NULL, 1.1)" +== 583 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view2(base_a) VALUES (1.1) RETURNING t +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 (base_a) VALUES (1.1) RETURNING t" +== 584 +-- truncate_limit: 100 +-- OK +UPDATE rw_view2 SET s = s WHERE base_a = 1.1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET s = s WHERE base_a = 1.1" +== 585 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view2 SET t = t WHERE base_a = 1.1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET t = t WHERE base_a = 1.1" +== 586 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view2 SET base_a = 1.05 WHERE base_a = 1.1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET base_a = 1.05 WHERE base_a = 1.1" +== 587 +-- truncate_limit: 100 +-- OK +DELETE FROM rw_view2 WHERE base_a = 1.05 RETURNING base_a, s, c, t +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE base_a = 1.05 RETURNING base_a, s, c, t" +== 588 +-- truncate_limit: 100 +-- OK + +CREATE VIEW rw_view3 AS + SELECT s, c, s/c t, ctid + FROM rw_view1 +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view3 AS SELECT s, c, s / c AS t, ctid FROM rw_view1" +== 589 +-- truncate_limit: 100 +INSERT INTO rw_view3 VALUES (null, null, null, null) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view3 VALUES (NULL, NULL, NULL, NULL)" +== 590 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view3(s) VALUES (null) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view3 (s) VALUES (NULL)" +== 591 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view3 SET s = s +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view3 SET s = s" +== 592 +-- truncate_limit: 100 +-- should fail +DELETE FROM rw_view3 WHERE s = sin(0.1) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +FUNCTION: name="sin" function="sin" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view3 WHERE s = sin(0.1)" +== 593 +-- truncate_limit: 100 +-- should be OK +SELECT * FROM base_tbl ORDER BY a +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a" +== 594 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.tables WHERE table_name LIKE E'r_\\\\_view%' ORDER BY table_name" +== 595 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE E'r_\\\\_view%' ORDER BY table_name" +== 596 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name, ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE ... ORDER BY table_name, ordinal_position" +== 597 +-- truncate_limit: 100 +SELECT events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + FROM pg_catalog.pg_relation_is_updatable('rw_view3'::regclass, false) t(events) +-- +FUNCTION: name="pg_catalog.pg_relation_is_updatable" function="pg_relation_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_catalog.pg_relation_is_updatable('rw_view3'::regclass, false) t(events)" +== 598 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 599 +-- truncate_limit: 100 +-- view on table with GENERATED columns + +CREATE TABLE base_tbl (id int, idplus1 int GENERATED ALWAYS AS (id + 1) STORED) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (id int, idplus1 int GENERATED ALWAYS AS (id + 1) STORED)" +== 600 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl" +== 601 +-- truncate_limit: 100 +INSERT INTO base_tbl (id) VALUES (1) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl (id) VALUES (1)" +== 602 +-- truncate_limit: 100 +INSERT INTO rw_view1 (id) VALUES (2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (id) VALUES (2)" +== 603 +-- truncate_limit: 100 +INSERT INTO base_tbl (id, idplus1) VALUES (3, DEFAULT) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl (id, idplus1) VALUES (3, DEFAULT)" +== 604 +-- truncate_limit: 100 +INSERT INTO rw_view1 (id, idplus1) VALUES (4, DEFAULT) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (id, idplus1) VALUES (4, DEFAULT)" +== 605 +-- truncate_limit: 100 +INSERT INTO base_tbl (id, idplus1) VALUES (5, 6) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl (id, idplus1) VALUES (5, 6)" +== 606 +-- truncate_limit: 100 +-- error +INSERT INTO rw_view1 (id, idplus1) VALUES (6, 7) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (id, idplus1) VALUES (6, 7)" +== 607 +-- truncate_limit: 100 +-- error + +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 608 +-- truncate_limit: 100 +UPDATE base_tbl SET id = 2000 WHERE id = 2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE base_tbl SET id = 2000 WHERE id = 2" +== 609 +-- truncate_limit: 100 +UPDATE rw_view1 SET id = 3000 WHERE id = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET id = 3000 WHERE id = 3" +== 610 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 611 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 612 +-- truncate_limit: 100 +-- inheritance tests + +CREATE TABLE base_tbl_parent (a int) +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl_parent (a int)" +== 613 +-- truncate_limit: 100 +CREATE TABLE base_tbl_child (CHECK (a > 0)) INHERITS (base_tbl_parent) +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl_child (CHECK (a > 0)) INHERITS (base_tbl_parent)" +== 614 +-- truncate_limit: 100 +INSERT INTO base_tbl_parent SELECT * FROM generate_series(-8, -1) +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl_parent SELECT * FROM generate_series(-8, -1)" +== 615 +-- truncate_limit: 100 +INSERT INTO base_tbl_child SELECT * FROM generate_series(1, 8) +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl_child SELECT * FROM generate_series(1, 8)" +== 616 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl_parent +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl_parent" +== 617 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS SELECT * FROM ONLY base_tbl_parent +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM ONLY base_tbl_parent" +== 618 +-- truncate_limit: 100 +SELECT * FROM rw_view1 ORDER BY a +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1 ORDER BY a" +== 619 +-- truncate_limit: 100 +SELECT * FROM ONLY rw_view1 ORDER BY a +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY rw_view1 ORDER BY a" +== 620 +-- truncate_limit: 100 +SELECT * FROM rw_view2 ORDER BY a +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 ORDER BY a" +== 621 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (-100), (100) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (-100), (100)" +== 622 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (-200), (200) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (-200), (200)" +== 623 +-- truncate_limit: 100 +UPDATE rw_view1 SET a = a*10 WHERE a IN (-1, 1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET a = a * 10 WHERE a IN (-1, 1)" +== 624 +-- truncate_limit: 100 +-- Should produce -10 and 10 +UPDATE ONLY rw_view1 SET a = a*10 WHERE a IN (-2, 2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ONLY rw_view1 SET a = a * 10 WHERE a IN (-2, 2)" +== 625 +-- truncate_limit: 100 +-- Should produce -20 and 20 +UPDATE rw_view2 SET a = a*10 WHERE a IN (-3, 3) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET a = a * 10 WHERE a IN (-3, 3)" +== 626 +-- truncate_limit: 100 +-- Should produce -30 only +UPDATE ONLY rw_view2 SET a = a*10 WHERE a IN (-4, 4) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE ONLY rw_view2 SET a = a * 10 WHERE a IN (-4, 4)" +== 627 +-- truncate_limit: 100 +-- Should produce -40 only + +DELETE FROM rw_view1 WHERE a IN (-5, 5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE a IN (-5, 5)" +== 628 +-- truncate_limit: 100 +-- Should delete -5 and 5 +DELETE FROM ONLY rw_view1 WHERE a IN (-6, 6) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ONLY rw_view1 WHERE a IN (-6, 6)" +== 629 +-- truncate_limit: 100 +-- Should delete -6 and 6 +DELETE FROM rw_view2 WHERE a IN (-7, 7) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE a IN (-7, 7)" +== 630 +-- truncate_limit: 100 +-- Should delete -7 only +DELETE FROM ONLY rw_view2 WHERE a IN (-8, 8) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM ONLY rw_view2 WHERE a IN (-8, 8)" +== 631 +-- truncate_limit: 100 +-- Should delete -8 only + +SELECT * FROM ONLY base_tbl_parent ORDER BY a +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY base_tbl_parent ORDER BY a" +== 632 +-- truncate_limit: 100 +SELECT * FROM base_tbl_child ORDER BY a +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl_child ORDER BY a" +== 633 +-- truncate_limit: 100 +MERGE INTO rw_view1 t USING (VALUES (-200), (10)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (...)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET a = t.a..." +== 634 +-- truncate_limit: 100 +-- Should produce -199 and 11 +MERGE INTO ONLY rw_view1 t USING (VALUES (-100), (20)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ONLY rw_view1 t USING (VALUES (...)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET a ..." +== 635 +-- truncate_limit: 100 +-- Should produce -99 and 21 +MERGE INTO rw_view2 t USING (VALUES (-40), (3)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (...)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET a = t.a..." +== 636 +-- truncate_limit: 100 +-- Should produce -39 only +MERGE INTO ONLY rw_view2 t USING (VALUES (-30), (4)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a+1 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO ONLY rw_view2 t USING (VALUES (...)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET a ..." +== 637 +-- truncate_limit: 100 +-- Should produce -29 only + +SELECT * FROM ONLY base_tbl_parent ORDER BY a +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY base_tbl_parent ORDER BY a" +== 638 +-- truncate_limit: 100 +SELECT * FROM base_tbl_child ORDER BY a +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl_child ORDER BY a" +== 639 +-- truncate_limit: 100 +CREATE TABLE other_tbl_parent (id int) +-- +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE other_tbl_parent (id int)" +== 640 +-- truncate_limit: 100 +CREATE TABLE other_tbl_child () INHERITS (other_tbl_parent) +-- +TABLE: name="other_tbl_child" schema="" table="other_tbl_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE other_tbl_child () INHERITS (other_tbl_parent)" +== 641 +-- truncate_limit: 100 +INSERT INTO other_tbl_parent VALUES (7),(200) +-- +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO other_tbl_parent VALUES (7), (200)" +== 642 +-- truncate_limit: 100 +INSERT INTO other_tbl_child VALUES (8),(100) +-- +TABLE: name="other_tbl_child" schema="" table="other_tbl_child" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO other_tbl_child VALUES (8), (100)" +== 643 +-- truncate_limit: 100 +EXPLAIN (costs off) +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=Select +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id" +== 644 +-- truncate_limit: 100 +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=Select +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id" +== 645 +-- truncate_limit: 100 +SELECT * FROM ONLY base_tbl_parent ORDER BY a +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM ONLY base_tbl_parent ORDER BY a" +== 646 +-- truncate_limit: 100 +SELECT * FROM base_tbl_child ORDER BY a +-- +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl_child ORDER BY a" +== 647 +-- truncate_limit: 100 +DROP TABLE base_tbl_parent, base_tbl_child CASCADE +-- +TABLE: name="base_tbl_parent" schema="" table="base_tbl_parent" ctx=DDL +TABLE: name="base_tbl_child" schema="" table="base_tbl_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl_parent, base_tbl_child CASCADE" +== 648 +-- truncate_limit: 100 +DROP TABLE other_tbl_parent CASCADE +-- +TABLE: name="other_tbl_parent" schema="" table="other_tbl_parent" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE other_tbl_parent CASCADE" +== 649 +-- truncate_limit: 100 +-- simple WITH CHECK OPTION + +CREATE TABLE base_tbl (a int, b int DEFAULT 10) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b int DEFAULT 10)" +== 650 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1,2), (2,3), (1,-1) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 2), (2, 3), (1, -1)" +== 651 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b + WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b WITH LOCAL CHECK OPTION" +== 652 +-- truncate_limit: 100 +SELECT * FROM information_schema.views WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.views WHERE table_name = 'rw_view1'" +== 653 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES(3,4) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (3, 4)" +== 654 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1 VALUES(4,3) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (4, 3)" +== 655 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view1 VALUES(5,null) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (5, NULL)" +== 656 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view1 SET b = 5 WHERE a = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b = 5 WHERE a = 3" +== 657 +-- truncate_limit: 100 +-- ok +UPDATE rw_view1 SET b = -5 WHERE a = 3 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b = -5 WHERE a = 3" +== 658 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view1(a) VALUES (9) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (a) VALUES (9)" +== 659 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1(a) VALUES (10) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 (a) VALUES (10)" +== 660 +-- truncate_limit: 100 +-- should fail +SELECT * FROM base_tbl ORDER BY a, b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a, b" +== 661 +-- truncate_limit: 100 +MERGE INTO rw_view1 t USING (VALUES (10)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.a + 1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (10)) v(a) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VALUES (..." +== 662 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view1 t USING (VALUES (11)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a, v.a - 1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (11)) v(a) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VALUES (..." +== 663 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view1 t USING (VALUES (1)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a - 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (1)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET a = t.a - 1" +== 664 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view1 t USING (VALUES (2)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a + 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (2)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET a = t.a + 1" +== 665 +-- truncate_limit: 100 +-- should fail +SELECT * FROM base_tbl ORDER BY a, b +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl ORDER BY a, b" +== 666 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 667 +-- truncate_limit: 100 +-- WITH LOCAL/CASCADED CHECK OPTION + +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int)" +== 668 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a > 0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a > 0" +== 669 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 + WITH CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 WITH CHECK OPTION" +== 670 +-- truncate_limit: 100 +-- implicitly cascaded +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.views WHERE table_name = 'rw_view2'" +== 671 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (-5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (-5)" +== 672 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (5)" +== 673 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view2 VALUES (15) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (15)" +== 674 +-- truncate_limit: 100 +-- should fail +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 675 +-- truncate_limit: 100 +UPDATE rw_view2 SET a = a - 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET a = a - 10" +== 676 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view2 SET a = a + 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET a = a + 10" +== 677 +-- truncate_limit: 100 +-- should fail + +CREATE OR REPLACE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 + WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 WITH LOCAL CHECK OPTION" +== 678 +-- truncate_limit: 100 +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.views WHERE table_name = 'rw_view2'" +== 679 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (-10) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (-10)" +== 680 +-- truncate_limit: 100 +-- ok, but not in view +INSERT INTO rw_view2 VALUES (20) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (20)" +== 681 +-- truncate_limit: 100 +-- should fail +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 682 +-- truncate_limit: 100 +ALTER VIEW rw_view1 SET (check_option=here) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view1 SET (check_option=here)" +== 683 +-- truncate_limit: 100 +-- invalid +ALTER VIEW rw_view1 SET (check_option=local) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view1 SET (check_option=local)" +== 684 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (-20) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (-20)" +== 685 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view2 VALUES (30) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (30)" +== 686 +-- truncate_limit: 100 +-- should fail + +ALTER VIEW rw_view2 RESET (check_option) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view2 RESET (check_option)" +== 687 +-- truncate_limit: 100 +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.views WHERE table_name = 'rw_view2'" +== 688 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (30) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (30)" +== 689 +-- truncate_limit: 100 +-- ok, but not in view +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 690 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 691 +-- truncate_limit: 100 +-- WITH CHECK OPTION with no local view qual + +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int)" +== 692 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WITH CHECK OPTION" +== 693 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a > 0 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a > 0" +== 694 +-- truncate_limit: 100 +CREATE VIEW rw_view3 AS SELECT * FROM rw_view2 WITH CHECK OPTION +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DDL +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view3 AS SELECT * FROM rw_view2 WITH CHECK OPTION" +== 695 +-- truncate_limit: 100 +SELECT * FROM information_schema.views WHERE table_name LIKE E'rw\\_view_' ORDER BY table_name +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM information_schema.views WHERE table_name LIKE E'rw\\\\_view_' ORDER BY table_name" +== 696 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (-1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (-1)" +== 697 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1 VALUES (1) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (1)" +== 698 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view2 VALUES (-2) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (-2)" +== 699 +-- truncate_limit: 100 +-- ok, but not in view +INSERT INTO rw_view2 VALUES (2) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (2)" +== 700 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view3 VALUES (-3) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view3 VALUES (-3)" +== 701 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view3 VALUES (3) +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view3 VALUES (3)" +== 702 +-- truncate_limit: 100 +-- ok + +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 703 +-- truncate_limit: 100 +-- WITH CHECK OPTION with scalar array ops + +CREATE TABLE base_tbl (a int, b int[]) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b int[])" +== 704 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a = ANY (b) + WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a = ANY(b) WITH CHECK OPTION" +== 705 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (1, ARRAY[1,2,3]) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (1, ARRAY[1, 2, 3])" +== 706 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1 VALUES (10, ARRAY[4,5]) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (10, ARRAY[4, 5])" +== 707 +-- truncate_limit: 100 +-- should fail + +UPDATE rw_view1 SET b[2] = -b[2] WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b[2] = - b[2] WHERE a = 1" +== 708 +-- truncate_limit: 100 +-- ok +UPDATE rw_view1 SET b[1] = -b[1] WHERE a = 1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET b[1] = - b[1] WHERE a = 1" +== 709 +-- truncate_limit: 100 +-- should fail + +PREPARE ins(int, int[]) AS INSERT INTO rw_view1 VALUES($1, $2) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: PrepareStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "PREPARE ins(int, int[]) AS INSERT INTO rw_view1 VALUES ($1, $2)" +== 710 +-- truncate_limit: 100 +EXECUTE ins(2, ARRAY[1,2,3]) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE ins(2, ARRAY[1, 2, 3])" +== 711 +-- truncate_limit: 100 +-- ok +EXECUTE ins(10, ARRAY[4,5]) +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE ins(10, ARRAY[4, 5])" +== 712 +-- truncate_limit: 100 +-- should fail +DEALLOCATE PREPARE ins +-- +STMT: DeallocateStmt +TRUNCATED: "DEALLOCATE ins" +== 713 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 714 +-- truncate_limit: 100 +-- WITH CHECK OPTION with subquery + +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int)" +== 715 +-- truncate_limit: 100 +CREATE TABLE ref_tbl (a int PRIMARY KEY) +-- +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE ref_tbl (a int PRIMARY KEY)" +== 716 +-- truncate_limit: 100 +INSERT INTO ref_tbl SELECT * FROM generate_series(1,10) +-- +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO ref_tbl SELECT * FROM generate_series(1, 10)" +== 717 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS + SELECT * FROM base_tbl b + WHERE EXISTS(SELECT 1 FROM ref_tbl r WHERE r.a = b.a) + WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=Select +ALIAS: "b"="base_tbl" +ALIAS: "r"="ref_tbl" +FILTER: schema="" table="r" column="a" +FILTER: schema="" table="b" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl b WHERE EXISTS (SELECT 1 FROM ref_tbl r WHERE r.a ..." +== 718 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (5)" +== 719 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1 VALUES (15) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (15)" +== 720 +-- truncate_limit: 100 +-- should fail + +UPDATE rw_view1 SET a = a + 5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET a = a + 5" +== 721 +-- truncate_limit: 100 +-- ok +UPDATE rw_view1 SET a = a + 5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET a = a + 5" +== 722 +-- truncate_limit: 100 +-- should fail + +EXPLAIN (costs off) INSERT INTO rw_view1 VALUES (5) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO rw_view1 VALUES (5)" +== 723 +-- truncate_limit: 100 +EXPLAIN (costs off) UPDATE rw_view1 SET a = a + 5 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view1 SET a = a + 5" +== 724 +-- truncate_limit: 100 +DROP TABLE base_tbl, ref_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +TABLE: name="ref_tbl" schema="" table="ref_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl, ref_tbl CASCADE" +== 725 +-- truncate_limit: 100 +-- WITH CHECK OPTION with BEFORE trigger on base table + +CREATE TABLE base_tbl (a int, b int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b int)" +== 726 +-- truncate_limit: 100 +CREATE FUNCTION base_tbl_trig_fn() +RETURNS trigger AS +$$ +BEGIN + NEW.b := 10; + RETURN NEW; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="base_tbl_trig_fn" function="base_tbl_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION base_tbl_trig_fn() RETURNS trigger AS $$\nBEGIN\n NEW.b := 10;\n RETURN NEW;\nEND;\n..." +== 727 +-- truncate_limit: 100 +CREATE TRIGGER base_tbl_trig BEFORE INSERT OR UPDATE ON base_tbl + FOR EACH ROW EXECUTE PROCEDURE base_tbl_trig_fn() +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER base_tbl_trig BEFORE INSERT OR UPDATE ON base_tbl FOR EACH ROW EXECUTE FUNCTION ba..." +== 728 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b WITH CHECK OPTION +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b WITH CHECK OPTION" +== 729 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (5,0) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (5, 0)" +== 730 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view1 VALUES (15, 20) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (15, 20)" +== 731 +-- truncate_limit: 100 +-- should fail +UPDATE rw_view1 SET a = 20, b = 30 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET a = 20, b = 30" +== 732 +-- truncate_limit: 100 +-- should fail + +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 733 +-- truncate_limit: 100 +DROP FUNCTION base_tbl_trig_fn() +-- +FUNCTION: name="base_tbl_trig_fn" function="base_tbl_trig_fn" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION base_tbl_trig_fn()" +== 734 +-- truncate_limit: 100 +-- WITH LOCAL CHECK OPTION with INSTEAD OF trigger on base view + +CREATE TABLE base_tbl (a int, b int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int, b int)" +== 735 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT a FROM base_tbl WHERE a < b +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT a FROM base_tbl WHERE a < b" +== 736 +-- truncate_limit: 100 +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + INSERT INTO base_tbl VALUES (NEW.a, 10); + RETURN NEW; + ELSIF TG_OP = 'UPDATE' THEN + UPDATE base_tbl SET a=NEW.a WHERE a=OLD.a; + RETURN NEW; + ELSIF TG_OP = 'DELETE' THEN + DELETE FROM base_tbl WHERE a=OLD.a; + RETURN OLD; + END IF; +END; +$$ +LANGUAGE plpgsql +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION rw_view1_trig_fn() RETURNS trigger AS $$\nBEGIN\n IF TG_OP = 'INSERT' THEN\n INS..." +== 737 +-- truncate_limit: 100 +CREATE TRIGGER rw_view1_trig + INSTEAD OF INSERT OR UPDATE OR DELETE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn() +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER rw_view1_trig INSTEAD OF INSERT OR DELETE OR UPDATE ON rw_view1 FOR EACH ROW EXECU..." +== 738 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS + SELECT * FROM rw_view1 WHERE a > 0 WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a > 0 WITH LOCAL CHECK OPTION" +== 739 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (-5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (-5)" +== 740 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view2 t USING (VALUES (-5)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (-5)) v(a) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VALUES (..." +== 741 +-- truncate_limit: 100 +-- should fail +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (5)" +== 742 +-- truncate_limit: 100 +-- ok +MERGE INTO rw_view2 t USING (VALUES (6)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (6)) v(a) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VALUES (v.a)" +== 743 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view2 VALUES (50) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (50)" +== 744 +-- truncate_limit: 100 +-- ok, but not in view +MERGE INTO rw_view2 t USING (VALUES (60)) AS v(a) ON t.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (60)) v(a) ON t.a = v.a WHEN NOT MATCHED THEN INSERT VALUES (..." +== 745 +-- truncate_limit: 100 +-- ok, but not in view +UPDATE rw_view2 SET a = a - 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET a = a - 10" +== 746 +-- truncate_limit: 100 +-- should fail +MERGE INTO rw_view2 t USING (VALUES (6)) AS v(a) ON t.a = v.a + WHEN MATCHED THEN UPDATE SET a = t.a - 10 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (6)) v(a) ON t.a = v.a WHEN MATCHED THEN UPDATE SET a = t.a - 10" +== 747 +-- truncate_limit: 100 +-- should fail +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 748 +-- truncate_limit: 100 +-- Check option won't cascade down to base view with INSTEAD OF triggers + +ALTER VIEW rw_view2 SET (check_option=cascaded) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view2 SET (check_option=cascaded)" +== 749 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (100) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (100)" +== 750 +-- truncate_limit: 100 +-- ok, but not in view (doesn't fail rw_view1's check) +UPDATE rw_view2 SET a = 200 WHERE a = 5 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET a = 200 WHERE a = 5" +== 751 +-- truncate_limit: 100 +-- ok, but not in view (doesn't fail rw_view1's check) +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 752 +-- truncate_limit: 100 +-- Neither local nor cascaded check options work with INSTEAD rules + +DROP TRIGGER rw_view1_trig ON rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER rw_view1_trig ON rw_view1" +== 753 +-- truncate_limit: 100 +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, 10) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 DO INSTEAD INSERT INTO base_tbl VALUES (ne..." +== 754 +-- truncate_limit: 100 +CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 + DO INSTEAD UPDATE base_tbl SET a=NEW.a WHERE a=OLD.a +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 DO INSTEAD UPDATE base_tbl SET a = new.a W..." +== 755 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (-10) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (-10)" +== 756 +-- truncate_limit: 100 +-- ok, but not in view (doesn't fail rw_view2's check) +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (5)" +== 757 +-- truncate_limit: 100 +-- ok +INSERT INTO rw_view2 VALUES (20) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (20)" +== 758 +-- truncate_limit: 100 +-- ok, but not in view (doesn't fail rw_view1's check) +UPDATE rw_view2 SET a = 30 WHERE a = 5 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET a = 30 WHERE a = 5" +== 759 +-- truncate_limit: 100 +-- ok, but not in view (doesn't fail rw_view1's check) +INSERT INTO rw_view2 VALUES (5) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (5)" +== 760 +-- truncate_limit: 100 +-- ok +UPDATE rw_view2 SET a = -5 WHERE a = 5 +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET a = -5 WHERE a = 5" +== 761 +-- truncate_limit: 100 +-- ok, but not in view (doesn't fail rw_view2's check) +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 762 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 763 +-- truncate_limit: 100 +DROP FUNCTION rw_view1_trig_fn() +-- +FUNCTION: name="rw_view1_trig_fn" function="rw_view1_trig_fn" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION rw_view1_trig_fn()" +== 764 +-- truncate_limit: 100 +CREATE TABLE base_tbl (a int) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int)" +== 765 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS SELECT a,10 AS b FROM base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT a, 10 AS b FROM base_tbl" +== 766 +-- truncate_limit: 100 +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 DO INSTEAD INSERT INTO base_tbl VALUES (ne..." +== 767 +-- truncate_limit: 100 +CREATE VIEW rw_view2 AS + SELECT * FROM rw_view1 WHERE a > b WITH LOCAL CHECK OPTION +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="b" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a > b WITH LOCAL CHECK OPTION" +== 768 +-- truncate_limit: 100 +INSERT INTO rw_view2 VALUES (2,3) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 VALUES (2, 3)" +== 769 +-- truncate_limit: 100 +-- ok, but not in view (doesn't fail rw_view2's check) +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 770 +-- truncate_limit: 100 +-- security barrier view + +CREATE TABLE base_tbl (person text, visibility text) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (person text, visibility text)" +== 771 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES ('Tom', 'public'), + ('Dick', 'private'), + ('Harry', 'public') +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES ('Tom', 'public'), ('Dick', 'private'), ('Harry', 'public')" +== 772 +-- truncate_limit: 100 +CREATE VIEW rw_view1 AS + SELECT person FROM base_tbl WHERE visibility = 'public' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="visibility" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT person FROM base_tbl WHERE visibility = 'public'" +== 773 +-- truncate_limit: 100 +CREATE FUNCTION snoop(anyelement) +RETURNS boolean AS +$$ +BEGIN + RAISE NOTICE 'snooped value: %', $1; + RETURN true; +END; +$$ +LANGUAGE plpgsql COST 0.000001 +-- +FUNCTION: name="snoop" function="snoop" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION snoop(anyelement) RETURNS boolean AS $$\nBEGIN\n RAISE NOTICE 'snooped value: %', ..." +== 774 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION leakproof(anyelement) +RETURNS boolean AS +$$ +BEGIN + RETURN true; +END; +$$ +LANGUAGE plpgsql STRICT IMMUTABLE LEAKPROOF +-- +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION leakproof(anyelement) RETURNS boolean AS $$\nBEGIN\n RETURN true;\nEND;\n..." +== 775 +-- truncate_limit: 100 +SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1 WHERE snoop(person)" +== 776 +-- truncate_limit: 100 +UPDATE rw_view1 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET person = person WHERE snoop(person)" +== 777 +-- truncate_limit: 100 +DELETE FROM rw_view1 WHERE NOT snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE NOT snoop(person)" +== 778 +-- truncate_limit: 100 +ALTER VIEW rw_view1 SET (security_barrier = true) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW rw_view1 SET (security_barrier=true)" +== 779 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT table_name, is_insertable_into FROM information_schema.tables WHERE table_name = 'rw_view1'" +== 780 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name = 'rw_view1'" +== 781 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view1' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name = 'rw_view1' ORDER BY ordinal_position" +== 782 +-- truncate_limit: 100 +SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1 WHERE snoop(person)" +== 783 +-- truncate_limit: 100 +UPDATE rw_view1 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view1 SET person = person WHERE snoop(person)" +== 784 +-- truncate_limit: 100 +DELETE FROM rw_view1 WHERE NOT snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE NOT snoop(person)" +== 785 +-- truncate_limit: 100 +MERGE INTO rw_view1 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view1 t USING (VALUES (...)) v(person) ON t.person = v.person WHEN MATCHED AND snoo..." +== 786 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rw_view1 WHERE snoop(person)" +== 787 +-- truncate_limit: 100 +EXPLAIN (costs off) UPDATE rw_view1 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view1 SET person = person WHERE snoop(person)" +== 788 +-- truncate_limit: 100 +EXPLAIN (costs off) DELETE FROM rw_view1 WHERE NOT snoop(person) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM rw_view1 WHERE NOT snoop(person)" +== 789 +-- truncate_limit: 100 +EXPLAIN (costs off) +MERGE INTO rw_view1 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +ALIAS: "t"="rw_view1" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO rw_view1 t USING (VALUES ('Tom'), ('Dick'), ('Harry')) v(person) O..." +== 790 +-- truncate_limit: 100 +-- security barrier view on top of security barrier view + +CREATE VIEW rw_view2 WITH (security_barrier = true) AS + SELECT * FROM rw_view1 WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 WITH (security_barrier=true) AS SELECT * FROM rw_view1 WHERE snoop(person)" +== 791 +-- truncate_limit: 100 +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.tables" schema="information_schema" table="tables" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT table_name, is_insertable_into FROM information_schema.tables WHERE table_name = 'rw_view2'" +== 792 +-- truncate_limit: 100 +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view2' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name = 'rw_view2'" +== 793 +-- truncate_limit: 100 +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view2' + ORDER BY ordinal_position +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name = 'rw_view2' ORDER BY ordinal_position" +== 794 +-- truncate_limit: 100 +SELECT * FROM rw_view2 WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view2 WHERE snoop(person)" +== 795 +-- truncate_limit: 100 +UPDATE rw_view2 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE rw_view2 SET person = person WHERE snoop(person)" +== 796 +-- truncate_limit: 100 +DELETE FROM rw_view2 WHERE NOT snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view2 WHERE NOT snoop(person)" +== 797 +-- truncate_limit: 100 +MERGE INTO rw_view2 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO rw_view2 t USING (VALUES (...)) v(person) ON t.person = v.person WHEN MATCHED AND snoo..." +== 798 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT * FROM rw_view2 WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=Select +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FILTER: schema="" table="" column="person" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM rw_view2 WHERE snoop(person)" +== 799 +-- truncate_limit: 100 +EXPLAIN (costs off) UPDATE rw_view2 SET person=person WHERE snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE rw_view2 SET person = person WHERE snoop(person)" +== 800 +-- truncate_limit: 100 +EXPLAIN (costs off) DELETE FROM rw_view2 WHERE NOT snoop(person) +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM rw_view2 WHERE NOT snoop(person)" +== 801 +-- truncate_limit: 100 +EXPLAIN (costs off) +MERGE INTO rw_view2 t + USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person + WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +ALIAS: "t"="rw_view2" +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) MERGE INTO rw_view2 t USING (VALUES ('Tom'), ('Dick'), ('Harry')) v(person) O..." +== 802 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 803 +-- truncate_limit: 100 +-- security barrier view on top of table with rules + +CREATE TABLE base_tbl(id int PRIMARY KEY, data text, deleted boolean) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (id int PRIMARY KEY, data text, deleted boolean)" +== 804 +-- truncate_limit: 100 +INSERT INTO base_tbl VALUES (1, 'Row 1', false), (2, 'Row 2', true) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'Row 1', false), (2, 'Row 2', true)" +== 805 +-- truncate_limit: 100 +CREATE RULE base_tbl_ins_rule AS ON INSERT TO base_tbl + WHERE EXISTS (SELECT 1 FROM base_tbl t WHERE t.id = new.id) + DO INSTEAD + UPDATE base_tbl SET data = new.data, deleted = false WHERE id = new.id +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE base_tbl_ins_rule AS ON INSERT TO base_tbl WHERE ... DO INSTEAD UPDATE base_tbl SET d..." +== 806 +-- truncate_limit: 100 +CREATE RULE base_tbl_del_rule AS ON DELETE TO base_tbl + DO INSTEAD + UPDATE base_tbl SET deleted = true WHERE id = old.id +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE base_tbl_del_rule AS ON DELETE TO base_tbl DO INSTEAD UPDATE base_tbl SET deleted = t..." +== 807 +-- truncate_limit: 100 +CREATE VIEW rw_view1 WITH (security_barrier=true) AS + SELECT id, data FROM base_tbl WHERE NOT deleted +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +FILTER: schema="" table="" column="deleted" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 WITH (security_barrier=true) AS SELECT id, data FROM base_tbl WHERE NOT deleted" +== 808 +-- truncate_limit: 100 +SELECT * FROM rw_view1 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM rw_view1" +== 809 +-- truncate_limit: 100 +EXPLAIN (costs off) DELETE FROM rw_view1 WHERE id = 1 AND snoop(data) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: ExplainStmt +STMT: DeleteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) DELETE FROM rw_view1 WHERE id = 1 AND snoop(data)" +== 810 +-- truncate_limit: 100 +DELETE FROM rw_view1 WHERE id = 1 AND snoop(data) +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM rw_view1 WHERE id = 1 AND snoop(data)" +== 811 +-- truncate_limit: 100 +EXPLAIN (costs off) INSERT INTO rw_view1 VALUES (2, 'New row 2') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO rw_view1 VALUES (2, 'New row 2')" +== 812 +-- truncate_limit: 100 +INSERT INTO rw_view1 VALUES (2, 'New row 2') +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES (2, 'New row 2')" +== 813 +-- truncate_limit: 100 +SELECT * FROM base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 814 +-- truncate_limit: 100 +DROP TABLE base_tbl CASCADE +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl CASCADE" +== 815 +-- truncate_limit: 100 +-- security barrier view based on inheritance set +CREATE TABLE t1 (a int, b float, c text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (a int, b double precision, c text)" +== 816 +-- truncate_limit: 100 +CREATE INDEX t1_a_idx ON t1(a) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX t1_a_idx ON t1 USING btree (a)" +== 817 +-- truncate_limit: 100 +INSERT INTO t1 +SELECT i,i,'t1' FROM generate_series(1,10) g(i) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 SELECT i, i, 't1' FROM generate_series(1, 10) g(i)" +== 818 +-- truncate_limit: 100 +ANALYZE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t1" +== 819 +-- truncate_limit: 100 +CREATE TABLE t11 (d text) INHERITS (t1) +-- +TABLE: name="t11" schema="" table="t11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t11 (d text) INHERITS (t1)" +== 820 +-- truncate_limit: 100 +CREATE INDEX t11_a_idx ON t11(a) +-- +TABLE: name="t11" schema="" table="t11" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX t11_a_idx ON t11 USING btree (a)" +== 821 +-- truncate_limit: 100 +INSERT INTO t11 +SELECT i,i,'t11','t11d' FROM generate_series(1,10) g(i) +-- +TABLE: name="t11" schema="" table="t11" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t11 SELECT i, i, 't11', 't11d' FROM generate_series(1, 10) g(i)" +== 822 +-- truncate_limit: 100 +ANALYZE t11 +-- +TABLE: name="t11" schema="" table="t11" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t11" +== 823 +-- truncate_limit: 100 +CREATE TABLE t12 (e int[]) INHERITS (t1) +-- +TABLE: name="t12" schema="" table="t12" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t12 (e int[]) INHERITS (t1)" +== 824 +-- truncate_limit: 100 +CREATE INDEX t12_a_idx ON t12(a) +-- +TABLE: name="t12" schema="" table="t12" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX t12_a_idx ON t12 USING btree (a)" +== 825 +-- truncate_limit: 100 +INSERT INTO t12 +SELECT i,i,'t12','{1,2}'::int[] FROM generate_series(1,10) g(i) +-- +TABLE: name="t12" schema="" table="t12" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t12 SELECT i, i, 't12', '{1,2}'::int[] FROM generate_series(1, 10) g(i)" +== 826 +-- truncate_limit: 100 +ANALYZE t12 +-- +TABLE: name="t12" schema="" table="t12" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t12" +== 827 +-- truncate_limit: 100 +CREATE TABLE t111 () INHERITS (t11, t12) +-- +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t111 () INHERITS (t11, t12)" +== 828 +-- truncate_limit: 100 +CREATE INDEX t111_a_idx ON t111(a) +-- +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX t111_a_idx ON t111 USING btree (a)" +== 829 +-- truncate_limit: 100 +INSERT INTO t111 +SELECT i,i,'t111','t111d','{1,1,1}'::int[] FROM generate_series(1,10) g(i) +-- +TABLE: name="t111" schema="" table="t111" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t111 SELECT i, i, 't111', 't111d', '{1,1,1}'::int[] FROM generate_series(1, 10) g(i)" +== 830 +-- truncate_limit: 100 +ANALYZE t111 +-- +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE t111" +== 831 +-- truncate_limit: 100 +CREATE VIEW v1 WITH (security_barrier=true) AS +SELECT *, (SELECT d FROM t11 WHERE t11.a = t1.a LIMIT 1) AS d +FROM t1 +WHERE a > 5 AND EXISTS(SELECT 1 FROM t12 WHERE t12.a = t1.a) +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +TABLE: name="t11" schema="" table="t11" ctx=Select +TABLE: name="t12" schema="" table="t12" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="t11" column="a" +FILTER: schema="" table="t1" column="a" +FILTER: schema="" table="t12" column="a" +FILTER: schema="" table="t1" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1 WITH (security_barrier=true) AS SELECT *, (SELECT d FROM t11 WHERE t11.a = t1.a LI..." +== 832 +-- truncate_limit: 100 +SELECT * FROM v1 WHERE a=3 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v1 WHERE a = 3" +== 833 +-- truncate_limit: 100 +-- should not see anything +SELECT * FROM v1 WHERE a=8 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v1 WHERE a = 8" +== 834 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE v1 SET a = 100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND ..." +== 835 +-- truncate_limit: 100 +UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE v1 SET a = 100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a <> 6" +== 836 +-- truncate_limit: 100 +SELECT * FROM v1 WHERE a=100 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v1 WHERE a = 100" +== 837 +-- truncate_limit: 100 +-- Nothing should have been changed to 100 +SELECT * FROM t1 WHERE a=100 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1 WHERE a = 100" +== 838 +-- truncate_limit: 100 +-- Nothing should have been changed to 100 + +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE v1 SET a = a + 1 WHERE snoop(a) AND leakproof(a) AND a = 8" +== 839 +-- truncate_limit: 100 +UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8 +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE v1 SET a = a + 1 WHERE snoop(a) AND leakproof(a) AND a = 8" +== 840 +-- truncate_limit: 100 +SELECT * FROM v1 WHERE b=8 +-- +TABLE: name="v1" schema="" table="v1" ctx=Select +FILTER: schema="" table="" column="b" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v1 WHERE b = 8" +== 841 +-- truncate_limit: 100 +DELETE FROM v1 WHERE snoop(a) AND leakproof(a) +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +FUNCTION: name="snoop" function="snoop" schema="" ctx=Call +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM v1 WHERE snoop(a) AND leakproof(a)" +== 842 +-- truncate_limit: 100 +-- should not delete everything, just where a>5 + +TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM t1" +== 843 +-- truncate_limit: 100 +-- verify all a<=5 are intact + +DROP TABLE t1, t11, t12, t111 CASCADE +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +TABLE: name="t11" schema="" table="t11" ctx=DDL +TABLE: name="t12" schema="" table="t12" ctx=DDL +TABLE: name="t111" schema="" table="t111" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1, t11, t12, t111 CASCADE" +== 844 +-- truncate_limit: 100 +DROP FUNCTION snoop(anyelement) +-- +FUNCTION: name="snoop" function="snoop" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION snoop(anyelement)" +== 845 +-- truncate_limit: 100 +DROP FUNCTION leakproof(anyelement) +-- +FUNCTION: name="leakproof" function="leakproof" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION leakproof(anyelement)" +== 846 +-- truncate_limit: 100 +CREATE TABLE tx1 (a integer) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx1 (a int)" +== 847 +-- truncate_limit: 100 +CREATE TABLE tx2 (b integer) +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx2 (b int)" +== 848 +-- truncate_limit: 100 +CREATE TABLE tx3 (c integer) +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx3 (c int)" +== 849 +-- truncate_limit: 100 +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=Select +TABLE: name="tx2" schema="" table="tx2" ctx=Select +TABLE: name="tx3" schema="" table="tx3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS (SELECT 1 FROM tx2 JOIN tx3 ON b = c)" +== 850 +-- truncate_limit: 100 +INSERT INTO vx1 values (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vx1 VALUES (1)" +== 851 +-- truncate_limit: 100 +SELECT * FROM tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tx1" +== 852 +-- truncate_limit: 100 +SELECT * FROM vx1 +-- +TABLE: name="vx1" schema="" table="vx1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vx1" +== 853 +-- truncate_limit: 100 +DROP VIEW vx1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vx1" +== 854 +-- truncate_limit: 100 +DROP TABLE tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx1" +== 855 +-- truncate_limit: 100 +DROP TABLE tx2 +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx2" +== 856 +-- truncate_limit: 100 +DROP TABLE tx3 +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx3" +== 857 +-- truncate_limit: 100 +CREATE TABLE tx1 (a integer) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx1 (a int)" +== 858 +-- truncate_limit: 100 +CREATE TABLE tx2 (b integer) +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx2 (b int)" +== 859 +-- truncate_limit: 100 +CREATE TABLE tx3 (c integer) +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx3 (c int)" +== 860 +-- truncate_limit: 100 +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=Select +TABLE: name="tx2" schema="" table="tx2" ctx=Select +TABLE: name="tx3" schema="" table="tx3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS (SELECT 1 FROM tx2 JOIN tx3 ON b = c)" +== 861 +-- truncate_limit: 100 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vx1 VALUES (1)" +== 862 +-- truncate_limit: 100 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vx1 VALUES (1)" +== 863 +-- truncate_limit: 100 +SELECT * FROM tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tx1" +== 864 +-- truncate_limit: 100 +SELECT * FROM vx1 +-- +TABLE: name="vx1" schema="" table="vx1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vx1" +== 865 +-- truncate_limit: 100 +DROP VIEW vx1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vx1" +== 866 +-- truncate_limit: 100 +DROP TABLE tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx1" +== 867 +-- truncate_limit: 100 +DROP TABLE tx2 +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx2" +== 868 +-- truncate_limit: 100 +DROP TABLE tx3 +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx3" +== 869 +-- truncate_limit: 100 +CREATE TABLE tx1 (a integer, b integer) +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx1 (a int, b int)" +== 870 +-- truncate_limit: 100 +CREATE TABLE tx2 (b integer, c integer) +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx2 (b int, c int)" +== 871 +-- truncate_limit: 100 +CREATE TABLE tx3 (c integer, d integer) +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE tx3 (c int, d int)" +== 872 +-- truncate_limit: 100 +ALTER TABLE tx1 DROP COLUMN b +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tx1 DROP b" +== 873 +-- truncate_limit: 100 +ALTER TABLE tx2 DROP COLUMN c +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tx2 DROP c" +== 874 +-- truncate_limit: 100 +ALTER TABLE tx3 DROP COLUMN d +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE tx3 DROP d" +== 875 +-- truncate_limit: 100 +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DDL +TABLE: name="tx1" schema="" table="tx1" ctx=Select +TABLE: name="tx2" schema="" table="tx2" ctx=Select +TABLE: name="tx3" schema="" table="tx3" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS (SELECT 1 FROM tx2 JOIN tx3 ON b = c)" +== 876 +-- truncate_limit: 100 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vx1 VALUES (1)" +== 877 +-- truncate_limit: 100 +INSERT INTO vx1 VALUES (1) +-- +TABLE: name="vx1" schema="" table="vx1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vx1 VALUES (1)" +== 878 +-- truncate_limit: 100 +SELECT * FROM tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM tx1" +== 879 +-- truncate_limit: 100 +SELECT * FROM vx1 +-- +TABLE: name="vx1" schema="" table="vx1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vx1" +== 880 +-- truncate_limit: 100 +DROP VIEW vx1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vx1" +== 881 +-- truncate_limit: 100 +DROP TABLE tx1 +-- +TABLE: name="tx1" schema="" table="tx1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx1" +== 882 +-- truncate_limit: 100 +DROP TABLE tx2 +-- +TABLE: name="tx2" schema="" table="tx2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx2" +== 883 +-- truncate_limit: 100 +DROP TABLE tx3 +-- +TABLE: name="tx3" schema="" table="tx3" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE tx3" +== 884 +-- truncate_limit: 100 +|-- +-- Test handling of vars from correlated subqueries in quals from outer +-- security barrier views, per bug #13988 +|-- +CREATE TABLE t1 (a int, b text, c int) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (a int, b text, c int)" +== 885 +-- truncate_limit: 100 +INSERT INTO t1 VALUES (1, 'one', 10) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES (1, 'one', 10)" +== 886 +-- truncate_limit: 100 +CREATE TABLE t2 (cc int) +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t2 (cc int)" +== 887 +-- truncate_limit: 100 +INSERT INTO t2 VALUES (10), (20) +-- +TABLE: name="t2" schema="" table="t2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t2 VALUES (10), (20)" +== 888 +-- truncate_limit: 100 +CREATE VIEW v1 WITH (security_barrier = true) AS + SELECT * FROM t1 WHERE (a > 0) + WITH CHECK OPTION +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1 WITH (security_barrier=true) AS SELECT * FROM t1 WHERE a > 0 WITH CHECK OPTION" +== 889 +-- truncate_limit: 100 +CREATE VIEW v2 WITH (security_barrier = true) AS + SELECT * FROM v1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.cc = v1.c) + WITH CHECK OPTION +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +TABLE: name="t2" schema="" table="t2" ctx=Select +FILTER: schema="" table="t2" column="cc" +FILTER: schema="" table="v1" column="c" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v2 WITH (security_barrier=true) AS SELECT * FROM v1 WHERE EXISTS (SELECT 1 FROM t2 WH..." +== 890 +-- truncate_limit: 100 +INSERT INTO v2 VALUES (2, 'two', 20) +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO v2 VALUES (2, 'two', 20)" +== 891 +-- truncate_limit: 100 +-- ok +INSERT INTO v2 VALUES (-2, 'minus two', 20) +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO v2 VALUES (-2, 'minus two', 20)" +== 892 +-- truncate_limit: 100 +-- not allowed +INSERT INTO v2 VALUES (3, 'three', 30) +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO v2 VALUES (3, 'three', 30)" +== 893 +-- truncate_limit: 100 +-- not allowed + +UPDATE v2 SET b = 'ONE' WHERE a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE v2 SET b = 'ONE' WHERE a = 1" +== 894 +-- truncate_limit: 100 +-- ok +UPDATE v2 SET a = -1 WHERE a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE v2 SET a = -1 WHERE a = 1" +== 895 +-- truncate_limit: 100 +-- not allowed +UPDATE v2 SET c = 30 WHERE a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE v2 SET c = 30 WHERE a = 1" +== 896 +-- truncate_limit: 100 +-- not allowed + +DELETE FROM v2 WHERE a = 2 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM v2 WHERE a = 2" +== 897 +-- truncate_limit: 100 +-- ok +SELECT * FROM v2 +-- +TABLE: name="v2" schema="" table="v2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v2" +== 898 +-- truncate_limit: 100 +DROP VIEW v2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW v2" +== 899 +-- truncate_limit: 100 +DROP VIEW v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW v1" +== 900 +-- truncate_limit: 100 +DROP TABLE t2 +-- +TABLE: name="t2" schema="" table="t2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t2" +== 901 +-- truncate_limit: 100 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1" +== 902 +-- truncate_limit: 100 +|-- +-- Test sub-select in nested security barrier views, per bug #17972 +|-- +CREATE TABLE t1 (a int) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (a int)" +== 903 +-- truncate_limit: 100 +CREATE VIEW v1 WITH (security_barrier = true) AS + SELECT * FROM t1 +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1 WITH (security_barrier=true) AS SELECT * FROM t1" +== 904 +-- truncate_limit: 100 +CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD + UPDATE t1 SET a = NEW.a WHERE a = OLD.a +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD UPDATE t1 SET a = new.a WHERE a = old.a" +== 905 +-- truncate_limit: 100 +CREATE VIEW v2 WITH (security_barrier = true) AS + SELECT * FROM v1 WHERE EXISTS (SELECT 1) +-- +TABLE: name="v2" schema="" table="v2" ctx=DDL +TABLE: name="v1" schema="" table="v1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v2 WITH (security_barrier=true) AS SELECT * FROM v1 WHERE EXISTS (SELECT 1)" +== 906 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) UPDATE v2 SET a = 1 +-- +TABLE: name="v2" schema="" table="v2" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE v2 SET a = 1" +== 907 +-- truncate_limit: 100 +DROP VIEW v2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW v2" +== 908 +-- truncate_limit: 100 +DROP VIEW v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW v1" +== 909 +-- truncate_limit: 100 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1" +== 910 +-- truncate_limit: 100 +|-- +-- Test CREATE OR REPLACE VIEW turning a non-updatable view into an +-- auto-updatable view and adding check options in a single step +|-- +CREATE TABLE t1 (a int, b text) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE t1 (a int, b text)" +== 911 +-- truncate_limit: 100 +CREATE VIEW v1 AS SELECT null::int AS a +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW v1 AS SELECT NULL::int AS a" +== 912 +-- truncate_limit: 100 +CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 WHERE a > 0 WITH CHECK OPTION +-- +TABLE: name="v1" schema="" table="v1" ctx=DDL +TABLE: name="t1" schema="" table="t1" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 WHERE a > 0 WITH CHECK OPTION" +== 913 +-- truncate_limit: 100 +INSERT INTO v1 VALUES (1, 'ok') +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO v1 VALUES (1, 'ok')" +== 914 +-- truncate_limit: 100 +-- ok +INSERT INTO v1 VALUES (-1, 'invalid') +-- +TABLE: name="v1" schema="" table="v1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO v1 VALUES (-1, 'invalid')" +== 915 +-- truncate_limit: 100 +-- should fail + +DROP VIEW v1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW v1" +== 916 +-- truncate_limit: 100 +DROP TABLE t1 +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE t1" +== 917 +-- truncate_limit: 100 +-- check that an auto-updatable view on a partitioned table works correctly +create table uv_pt (a int, b int, v varchar) partition by range (a, b) +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE uv_pt (a int, b int, v varchar) PARTITION BY RANGE (a, b)" +== 918 +-- truncate_limit: 100 +create table uv_pt1 (b int not null, v varchar, a int not null) partition by range (b) +-- +TABLE: name="uv_pt1" schema="" table="uv_pt1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE uv_pt1 (b int NOT NULL, v varchar, a int NOT NULL) PARTITION BY RANGE (b)" +== 919 +-- truncate_limit: 100 +create table uv_pt11 (like uv_pt1) +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE uv_pt11 (LIKE uv_pt1)" +== 920 +-- truncate_limit: 100 +alter table uv_pt11 drop a +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE uv_pt11 DROP a" +== 921 +-- truncate_limit: 100 +alter table uv_pt11 add a int +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE uv_pt11 ADD COLUMN a int" +== 922 +-- truncate_limit: 100 +alter table uv_pt11 drop a +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE uv_pt11 DROP a" +== 923 +-- truncate_limit: 100 +alter table uv_pt11 add a int not null +-- +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE uv_pt11 ADD COLUMN a int NOT NULL" +== 924 +-- truncate_limit: 100 +alter table uv_pt1 attach partition uv_pt11 for values from (2) to (5) +-- +TABLE: name="uv_pt1" schema="" table="uv_pt1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE uv_pt1 ATTACH PARTITION uv_pt11 FOR VALUES FROM (2) TO (5)" +== 925 +-- truncate_limit: 100 +alter table uv_pt attach partition uv_pt1 for values from (1, 2) to (1, 10) +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE uv_pt ATTACH PARTITION uv_pt1 FOR VALUES FROM (1, 2) TO (1, 10)" +== 926 +-- truncate_limit: 100 +create view uv_ptv as select * from uv_pt +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DDL +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW uv_ptv AS SELECT * FROM uv_pt" +== 927 +-- truncate_limit: 100 +select events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + from pg_catalog.pg_relation_is_updatable('uv_pt'::regclass, false) t(events) +-- +FUNCTION: name="pg_catalog.pg_relation_is_updatable" function="pg_relation_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM pg_catalog.pg_relation_is_updatable('uv_pt'::regclass, false) t(events)" +== 928 +-- truncate_limit: 100 +select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 1::smallint, false) +-- +FUNCTION: name="pg_catalog.pg_column_is_updatable" function="pg_column_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 1::smallint, false)" +== 929 +-- truncate_limit: 100 +select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 2::smallint, false) +-- +FUNCTION: name="pg_catalog.pg_column_is_updatable" function="pg_column_is_updatable" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 2::smallint, false)" +== 930 +-- truncate_limit: 100 +select table_name, is_updatable, is_insertable_into + from information_schema.views where table_name = 'uv_ptv' +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name = 'uv_ptv'" +== 931 +-- truncate_limit: 100 +select table_name, column_name, is_updatable + from information_schema.columns where table_name = 'uv_ptv' order by column_name +-- +TABLE: name="information_schema.columns" schema="information_schema" table="columns" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.columns WHERE table_name = 'uv_ptv' ORDER BY column_name" +== 932 +-- truncate_limit: 100 +insert into uv_ptv values (1, 2) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_ptv VALUES (1, 2)" +== 933 +-- truncate_limit: 100 +select tableoid::regclass, * from uv_pt +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM uv_pt" +== 934 +-- truncate_limit: 100 +create view uv_ptv_wco as select * from uv_pt where a = 0 with check option +-- +TABLE: name="uv_ptv_wco" schema="" table="uv_ptv_wco" ctx=DDL +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +FILTER: schema="" table="" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW uv_ptv_wco AS SELECT * FROM uv_pt WHERE a = 0 WITH CHECK OPTION" +== 935 +-- truncate_limit: 100 +insert into uv_ptv_wco values (1, 2) +-- +TABLE: name="uv_ptv_wco" schema="" table="uv_ptv_wco" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_ptv_wco VALUES (1, 2)" +== 936 +-- truncate_limit: 100 +merge into uv_ptv t + using (values (1,2), (1,4)) as v(a,b) on t.a = v.a -- fail: matches 2 src rows + when matched then update set b = t.b + 1 + when not matched then insert values (v.a, v.b + 1) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +ALIAS: "t"="uv_ptv" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO uv_ptv t USING (VALUES (...)) v(a, b) ON t.a = v.a WHEN MATCHED THEN UPDATE SET b = t...." +== 937 +-- truncate_limit: 100 +merge into uv_ptv t + using (values (1,2), (1,4)) as v(a,b) on t.a = v.a and t.b = v.b + when matched then update set b = t.b + 1 + when not matched then insert values (v.a, v.b + 1) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +ALIAS: "t"="uv_ptv" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO uv_ptv t USING (VALUES (...)) v(a, b) ON t.a = v.a AND t.b = v.b WHEN MATCHED THEN UPD..." +== 938 +-- truncate_limit: 100 +-- fail: no partition for b=5 +merge into uv_ptv t + using (values (1,2), (1,3)) as v(a,b) on t.a = v.a and t.b = v.b + when matched then update set b = t.b + 1 + when not matched then insert values (v.a, v.b + 1) +-- +TABLE: name="uv_ptv" schema="" table="uv_ptv" ctx=DML +ALIAS: "t"="uv_ptv" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "MERGE INTO uv_ptv t USING (VALUES (...)) v(a, b) ON t.a = v.a AND t.b = v.b WHEN MATCHED THEN UPD..." +== 939 +-- truncate_limit: 100 +-- ok +select tableoid::regclass, * from uv_pt order by a, b +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass, * FROM uv_pt ORDER BY a, b" +== 940 +-- truncate_limit: 100 +drop view uv_ptv, uv_ptv_wco +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW uv_ptv, uv_ptv_wco" +== 941 +-- truncate_limit: 100 +drop table uv_pt, uv_pt1, uv_pt11 +-- +TABLE: name="uv_pt" schema="" table="uv_pt" ctx=DDL +TABLE: name="uv_pt1" schema="" table="uv_pt1" ctx=DDL +TABLE: name="uv_pt11" schema="" table="uv_pt11" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE uv_pt, uv_pt1, uv_pt11" +== 942 +-- truncate_limit: 100 +-- check that wholerow vars appearing in WITH CHECK OPTION constraint expressions +-- work fine with partitioned tables +create table wcowrtest (a int) partition by list (a) +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE wcowrtest (a int) PARTITION BY LIST (a)" +== 943 +-- truncate_limit: 100 +create table wcowrtest1 partition of wcowrtest for values in (1) +-- +TABLE: name="wcowrtest1" schema="" table="wcowrtest1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE wcowrtest1 PARTITION OF wcowrtest FOR VALUES IN (1)" +== 944 +-- truncate_limit: 100 +create view wcowrtest_v as select * from wcowrtest where wcowrtest = '(2)'::wcowrtest with check option +-- +TABLE: name="wcowrtest_v" schema="" table="wcowrtest_v" ctx=DDL +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=Select +FILTER: schema="" table="" column="wcowrtest" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW wcowrtest_v AS SELECT * FROM wcowrtest WHERE wcowrtest = '(2)'::wcowrtest WITH CHECK ..." +== 945 +-- truncate_limit: 100 +insert into wcowrtest_v values (1) +-- +TABLE: name="wcowrtest_v" schema="" table="wcowrtest_v" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wcowrtest_v VALUES (1)" +== 946 +-- truncate_limit: 100 +alter table wcowrtest add b text +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE wcowrtest ADD COLUMN b text" +== 947 +-- truncate_limit: 100 +create table wcowrtest2 (b text, c int, a int) +-- +TABLE: name="wcowrtest2" schema="" table="wcowrtest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE wcowrtest2 (b text, c int, a int)" +== 948 +-- truncate_limit: 100 +alter table wcowrtest2 drop c +-- +TABLE: name="wcowrtest2" schema="" table="wcowrtest2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE wcowrtest2 DROP c" +== 949 +-- truncate_limit: 100 +alter table wcowrtest attach partition wcowrtest2 for values in (2) +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE wcowrtest ATTACH PARTITION wcowrtest2 FOR VALUES IN (2)" +== 950 +-- truncate_limit: 100 +create table sometable (a int, b text) +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sometable (a int, b text)" +== 951 +-- truncate_limit: 100 +insert into sometable values (1, 'a'), (2, 'b') +-- +TABLE: name="sometable" schema="" table="sometable" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sometable VALUES (1, 'a'), (2, 'b')" +== 952 +-- truncate_limit: 100 +create view wcowrtest_v2 as + select * + from wcowrtest r + where r in (select s from sometable s where r.a = s.a) +with check option +-- +TABLE: name="wcowrtest_v2" schema="" table="wcowrtest_v2" ctx=DDL +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=Select +TABLE: name="sometable" schema="" table="sometable" ctx=Select +ALIAS: "r"="wcowrtest" +ALIAS: "s"="sometable" +FILTER: schema="" table="" column="r" +FILTER: schema="" table="r" column="a" +FILTER: schema="" table="s" column="a" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW wcowrtest_v2 AS SELECT * FROM wcowrtest r WHERE r IN (SELECT s FROM sometable s WHERE..." +== 953 +-- truncate_limit: 100 +-- WITH CHECK qual will be processed with wcowrtest2's +-- rowtype after tuple-routing +insert into wcowrtest_v2 values (2, 'no such row in sometable') +-- +TABLE: name="wcowrtest_v2" schema="" table="wcowrtest_v2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO wcowrtest_v2 VALUES (2, 'no such row in sometable')" +== 954 +-- truncate_limit: 100 +drop view wcowrtest_v, wcowrtest_v2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW wcowrtest_v, wcowrtest_v2" +== 955 +-- truncate_limit: 100 +drop table wcowrtest, sometable +-- +TABLE: name="wcowrtest" schema="" table="wcowrtest" ctx=DDL +TABLE: name="sometable" schema="" table="sometable" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE wcowrtest, sometable" +== 956 +-- truncate_limit: 100 +-- Check INSERT .. ON CONFLICT DO UPDATE works correctly when the view's +-- columns are named and ordered differently than the underlying table's. +create table uv_iocu_tab (a text unique, b float) +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE uv_iocu_tab (a text UNIQUE, b double precision)" +== 957 +-- truncate_limit: 100 +insert into uv_iocu_tab values ('xyxyxy', 0) +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_tab VALUES ('xyxyxy', 0)" +== 958 +-- truncate_limit: 100 +create view uv_iocu_view as + select b, b+1 as c, a, '2.0'::text as two from uv_iocu_tab +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DDL +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW uv_iocu_view AS SELECT b, b + 1 AS c, a, '2.0'::text AS two FROM uv_iocu_tab" +== 959 +-- truncate_limit: 100 +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = uv_iocu_view.b +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (a, b) VALUES ('xyxyxy', 1) ON CONFLICT (a) DO UPDATE SET ... = ..." +== 960 +-- truncate_limit: 100 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_tab" +== 961 +-- truncate_limit: 100 +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = excluded.b +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (a, b) VALUES ('xyxyxy', 1) ON CONFLICT (a) DO UPDATE SET b = excluded.b" +== 962 +-- truncate_limit: 100 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_tab" +== 963 +-- truncate_limit: 100 +-- OK to access view columns that are not present in underlying base +-- relation in the ON CONFLICT portion of the query +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = cast(excluded.two as float) +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (a, b) VALUES ('xyxyxy', 3) ON CONFLICT (a) DO UPDATE SET ... = ..." +== 964 +-- truncate_limit: 100 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_tab" +== 965 +-- truncate_limit: 100 +explain (costs off) +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0 +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO uv_iocu_view (a, b) VALUES ('xyxyxy', 3) ON CONFLICT (a) DO UPDAT..." +== 966 +-- truncate_limit: 100 +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0 +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (a, b) VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... WHERE ..." +== 967 +-- truncate_limit: 100 +select * from uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_tab" +== 968 +-- truncate_limit: 100 +drop view uv_iocu_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW uv_iocu_view" +== 969 +-- truncate_limit: 100 +drop table uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE uv_iocu_tab" +== 970 +-- truncate_limit: 100 +-- Test whole-row references to the view +create table uv_iocu_tab (a int unique, b text) +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE uv_iocu_tab (a int UNIQUE, b text)" +== 971 +-- truncate_limit: 100 +create view uv_iocu_view as + select b as bb, a as aa, uv_iocu_tab::text as cc from uv_iocu_tab +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DDL +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW uv_iocu_view AS SELECT b AS bb, a AS aa, uv_iocu_tab::text AS cc FROM uv_iocu_tab" +== 972 +-- truncate_limit: 100 +insert into uv_iocu_view (aa,bb) values (1,'x') +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (aa, bb) VALUES (1, 'x')" +== 973 +-- truncate_limit: 100 +explain (costs off) +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: ExplainStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) INSERT INTO uv_iocu_view (aa, bb) VALUES (1, 'y') ON CONFLICT (aa) DO UPDATE ..." +== 974 +-- truncate_limit: 100 +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (aa, bb) VALUES (1, 'y') ON CONFLICT (aa) DO UPDATE SET ... = ... WHERE ..." +== 975 +-- truncate_limit: 100 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_view" +== 976 +-- truncate_limit: 100 +-- Test omitting a column of the base relation +delete from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM uv_iocu_view" +== 977 +-- truncate_limit: 100 +insert into uv_iocu_view (aa,bb) values (1,'x') +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (aa, bb) VALUES (1, 'x')" +== 978 +-- truncate_limit: 100 +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.* +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (aa) VALUES (1) ON CONFLICT (aa) DO UPDATE SET ... = ..." +== 979 +-- truncate_limit: 100 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_view" +== 980 +-- truncate_limit: 100 +alter table uv_iocu_tab alter column b set default 'table default' +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE uv_iocu_tab ALTER COLUMN b SET DEFAULT 'table default'" +== 981 +-- truncate_limit: 100 +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.* +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (aa) VALUES (1) ON CONFLICT (aa) DO UPDATE SET ... = ..." +== 982 +-- truncate_limit: 100 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_view" +== 983 +-- truncate_limit: 100 +alter view uv_iocu_view alter column bb set default 'view default' +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW uv_iocu_view ALTER COLUMN bb SET DEFAULT 'view default'" +== 984 +-- truncate_limit: 100 +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.* +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (aa) VALUES (1) ON CONFLICT (aa) DO UPDATE SET ... = ..." +== 985 +-- truncate_limit: 100 +select * from uv_iocu_view +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM uv_iocu_view" +== 986 +-- truncate_limit: 100 +-- Should fail to update non-updatable columns +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set cc = 'XXX' +-- +TABLE: name="uv_iocu_view" schema="" table="uv_iocu_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO uv_iocu_view (aa) VALUES (1) ON CONFLICT (aa) DO UPDATE SET cc = 'XXX'" +== 987 +-- truncate_limit: 100 +drop view uv_iocu_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW uv_iocu_view" +== 988 +-- truncate_limit: 100 +drop table uv_iocu_tab +-- +TABLE: name="uv_iocu_tab" schema="" table="uv_iocu_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE uv_iocu_tab" +== 989 +-- truncate_limit: 100 +-- ON CONFLICT DO UPDATE permissions checks +create user regress_view_user1 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_view_user1" +== 990 +-- truncate_limit: 100 +create user regress_view_user2 +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_view_user2" +== 991 +-- truncate_limit: 100 +set session authorization regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 992 +-- truncate_limit: 100 +create table base_tbl(a int unique, b text, c float) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tbl (a int UNIQUE, b text, c double precision)" +== 993 +-- truncate_limit: 100 +insert into base_tbl values (1,'xxx',1.0) +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tbl VALUES (1, 'xxx', 1.0)" +== 994 +-- truncate_limit: 100 +create view rw_view1 as select b as bb, c as cc, a as aa from base_tbl +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl" +== 995 +-- truncate_limit: 100 +grant select (aa,bb) on rw_view1 to regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (aa, bb) ON rw_view1 TO regress_view_user2" +== 996 +-- truncate_limit: 100 +grant insert on rw_view1 to regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert ON rw_view1 TO regress_view_user2" +== 997 +-- truncate_limit: 100 +grant update (bb) on rw_view1 to regress_view_user2 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (bb) ON rw_view1 TO regress_view_user2" +== 998 +-- truncate_limit: 100 +set session authorization regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 999 +-- truncate_limit: 100 +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('yyy', 2.0, 1) ON CONFLICT (aa) DO UPDATE SET bb = excluded.cc" +== 1000 +-- truncate_limit: 100 +-- Not allowed +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = rw_view1.cc +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('yyy', 2.0, 1) ON CONFLICT (aa) DO UPDATE SET bb = rw_view1.cc" +== 1001 +-- truncate_limit: 100 +-- Not allowed +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('yyy', 2.0, 1) ON CONFLICT (aa) DO UPDATE SET bb = excluded.bb" +== 1002 +-- truncate_limit: 100 +-- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set bb = rw_view1.bb||'xxx' +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('zzz', 2.0, 1) ON CONFLICT (aa) DO UPDATE SET bb = rw_view1.bb || 'xxx'" +== 1003 +-- truncate_limit: 100 +-- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set cc = 3.0 +-- +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view1 VALUES ('zzz', 2.0, 1) ON CONFLICT (aa) DO UPDATE SET cc = 3.0" +== 1004 +-- truncate_limit: 100 +-- Not allowed +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 1005 +-- truncate_limit: 100 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 1006 +-- truncate_limit: 100 +set session authorization regress_view_user1 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user1" +== 1007 +-- truncate_limit: 100 +grant select (a,b) on base_tbl to regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT select (a, b) ON base_tbl TO regress_view_user2" +== 1008 +-- truncate_limit: 100 +grant insert (a,b) on base_tbl to regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT insert (a, b) ON base_tbl TO regress_view_user2" +== 1009 +-- truncate_limit: 100 +grant update (a,b) on base_tbl to regress_view_user2 +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT update (a, b) ON base_tbl TO regress_view_user2" +== 1010 +-- truncate_limit: 100 +set session authorization regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 1011 +-- truncate_limit: 100 +create view rw_view2 as select b as bb, c as cc, a as aa from base_tbl +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view2 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl" +== 1012 +-- truncate_limit: 100 +insert into rw_view2 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view2" schema="" table="rw_view2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view2 (aa, bb) VALUES (1, 'xxx') ON CONFLICT (aa) DO UPDATE SET bb = excluded.bb" +== 1013 +-- truncate_limit: 100 +-- Not allowed +create view rw_view3 as select b as bb, a as aa from base_tbl +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DDL +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view3 AS SELECT b AS bb, a AS aa FROM base_tbl" +== 1014 +-- truncate_limit: 100 +insert into rw_view3 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view3" schema="" table="rw_view3" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view3 (aa, bb) VALUES (1, 'xxx') ON CONFLICT (aa) DO UPDATE SET bb = excluded.bb" +== 1015 +-- truncate_limit: 100 +-- OK +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 1016 +-- truncate_limit: 100 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 1017 +-- truncate_limit: 100 +set session authorization regress_view_user2 +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_view_user2" +== 1018 +-- truncate_limit: 100 +create view rw_view4 as select aa, bb, cc FROM rw_view1 +-- +TABLE: name="rw_view4" schema="" table="rw_view4" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view4 AS SELECT aa, bb, cc FROM rw_view1" +== 1019 +-- truncate_limit: 100 +insert into rw_view4 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view4" schema="" table="rw_view4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view4 (aa, bb) VALUES (1, 'yyy') ON CONFLICT (aa) DO UPDATE SET bb = excluded.bb" +== 1020 +-- truncate_limit: 100 +-- Not allowed +create view rw_view5 as select aa, bb FROM rw_view1 +-- +TABLE: name="rw_view5" schema="" table="rw_view5" ctx=DDL +TABLE: name="rw_view1" schema="" table="rw_view1" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW rw_view5 AS SELECT aa, bb FROM rw_view1" +== 1021 +-- truncate_limit: 100 +insert into rw_view5 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb +-- +TABLE: name="rw_view5" schema="" table="rw_view5" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO rw_view5 (aa, bb) VALUES (1, 'yyy') ON CONFLICT (aa) DO UPDATE SET bb = excluded.bb" +== 1022 +-- truncate_limit: 100 +-- OK +reset session authorization +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 1023 +-- truncate_limit: 100 +select * from base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tbl" +== 1024 +-- truncate_limit: 100 +drop view rw_view5 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rw_view5" +== 1025 +-- truncate_limit: 100 +drop view rw_view4 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rw_view4" +== 1026 +-- truncate_limit: 100 +drop view rw_view3 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rw_view3" +== 1027 +-- truncate_limit: 100 +drop view rw_view2 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rw_view2" +== 1028 +-- truncate_limit: 100 +drop view rw_view1 +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW rw_view1" +== 1029 +-- truncate_limit: 100 +drop table base_tbl +-- +TABLE: name="base_tbl" schema="" table="base_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tbl" +== 1030 +-- truncate_limit: 100 +drop user regress_view_user1 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_view_user1" +== 1031 +-- truncate_limit: 100 +drop user regress_view_user2 +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_view_user2" +== 1032 +-- truncate_limit: 100 +-- Test single- and multi-row inserts with table and view defaults. +-- Table defaults should be used, unless overridden by view defaults. +create table base_tab_def (a int, b text default 'Table default', + c text default 'Table default', d text, e text) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tab_def (a int, b text DEFAULT 'Table default', c text DEFAULT 'Table default',..." +== 1033 +-- truncate_limit: 100 +create view base_tab_def_view as select * from base_tab_def +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW base_tab_def_view AS SELECT * FROM base_tab_def" +== 1034 +-- truncate_limit: 100 +alter view base_tab_def_view alter b set default 'View default' +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW base_tab_def_view ALTER COLUMN b SET DEFAULT 'View default'" +== 1035 +-- truncate_limit: 100 +alter view base_tab_def_view alter d set default 'View default' +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW base_tab_def_view ALTER COLUMN d SET DEFAULT 'View default'" +== 1036 +-- truncate_limit: 100 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (1)" +== 1037 +-- truncate_limit: 100 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (2), (3)" +== 1038 +-- truncate_limit: 100 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (4, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1039 +-- truncate_limit: 100 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (...)" +== 1040 +-- truncate_limit: 100 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (11)" +== 1041 +-- truncate_limit: 100 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (12), (13)" +== 1042 +-- truncate_limit: 100 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (14, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1043 +-- truncate_limit: 100 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (...)" +== 1044 +-- truncate_limit: 100 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (17), (DEFAULT)" +== 1045 +-- truncate_limit: 100 +select * from base_tab_def order by a +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tab_def ORDER BY a" +== 1046 +-- truncate_limit: 100 +-- Adding an INSTEAD OF trigger should cause NULLs to be inserted instead of +-- table defaults, where there are no view defaults. +create function base_tab_def_view_instrig_func() returns trigger +as +$$ +begin + insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); + return new; +end; +$$ +language plpgsql +-- +FUNCTION: name="base_tab_def_view_instrig_func" function="base_tab_def_view_instrig_func" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION base_tab_def_view_instrig_func() RETURNS trigger AS $$\nbegin\n insert into base_t..." +== 1047 +-- truncate_limit: 100 +create trigger base_tab_def_view_instrig instead of insert on base_tab_def_view + for each row execute function base_tab_def_view_instrig_func() +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER base_tab_def_view_instrig INSTEAD OF INSERT ON base_tab_def_view FOR EACH ROW EXEC..." +== 1048 +-- truncate_limit: 100 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE base_tab_def" +== 1049 +-- truncate_limit: 100 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (1)" +== 1050 +-- truncate_limit: 100 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (2), (3)" +== 1051 +-- truncate_limit: 100 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (4, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1052 +-- truncate_limit: 100 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (...)" +== 1053 +-- truncate_limit: 100 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (11)" +== 1054 +-- truncate_limit: 100 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (12), (13)" +== 1055 +-- truncate_limit: 100 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (14, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1056 +-- truncate_limit: 100 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (...)" +== 1057 +-- truncate_limit: 100 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (17), (DEFAULT)" +== 1058 +-- truncate_limit: 100 +select * from base_tab_def order by a +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tab_def ORDER BY a" +== 1059 +-- truncate_limit: 100 +-- Using an unconditional DO INSTEAD rule should also cause NULLs to be +-- inserted where there are no view defaults. +drop trigger base_tab_def_view_instrig on base_tab_def_view +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER base_tab_def_view_instrig ON base_tab_def_view" +== 1060 +-- truncate_limit: 100 +drop function base_tab_def_view_instrig_func +-- +FUNCTION: name="base_tab_def_view_instrig_func" function="base_tab_def_view_instrig_func" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION base_tab_def_view_instrig_func" +== 1061 +-- truncate_limit: 100 +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do instead insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE base_tab_def_view_ins_rule AS ON INSERT TO base_tab_def_view DO INSTEAD INSERT INTO b..." +== 1062 +-- truncate_limit: 100 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE base_tab_def" +== 1063 +-- truncate_limit: 100 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (1)" +== 1064 +-- truncate_limit: 100 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (2), (3)" +== 1065 +-- truncate_limit: 100 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (4, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1066 +-- truncate_limit: 100 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (...)" +== 1067 +-- truncate_limit: 100 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (11)" +== 1068 +-- truncate_limit: 100 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (12), (13)" +== 1069 +-- truncate_limit: 100 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (14, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1070 +-- truncate_limit: 100 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (...)" +== 1071 +-- truncate_limit: 100 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (17), (DEFAULT)" +== 1072 +-- truncate_limit: 100 +select * from base_tab_def order by a +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tab_def ORDER BY a" +== 1073 +-- truncate_limit: 100 +-- A DO ALSO rule should cause each row to be inserted twice. The first +-- insert should behave the same as an auto-updatable view (using table +-- defaults, unless overridden by view defaults). The second insert should +-- behave the same as a rule-updatable view (inserting NULLs where there are +-- no view defaults). +drop rule base_tab_def_view_ins_rule on base_tab_def_view +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE base_tab_def_view_ins_rule ON base_tab_def_view" +== 1074 +-- truncate_limit: 100 +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do also insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE base_tab_def_view_ins_rule AS ON INSERT TO base_tab_def_view DO INSERT INTO base_tab_..." +== 1075 +-- truncate_limit: 100 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE base_tab_def" +== 1076 +-- truncate_limit: 100 +insert into base_tab_def values (1) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (1)" +== 1077 +-- truncate_limit: 100 +insert into base_tab_def values (2), (3) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (2), (3)" +== 1078 +-- truncate_limit: 100 +insert into base_tab_def values (4, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (4, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1079 +-- truncate_limit: 100 +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default) +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def VALUES (...)" +== 1080 +-- truncate_limit: 100 +insert into base_tab_def_view values (11) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (11)" +== 1081 +-- truncate_limit: 100 +insert into base_tab_def_view values (12), (13) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (12), (13)" +== 1082 +-- truncate_limit: 100 +insert into base_tab_def_view values (14, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (14, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1083 +-- truncate_limit: 100 +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (...)" +== 1084 +-- truncate_limit: 100 +insert into base_tab_def_view values (17), (default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (17), (DEFAULT)" +== 1085 +-- truncate_limit: 100 +select * from base_tab_def order by a, c NULLS LAST +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tab_def ORDER BY a, c NULLS LAST" +== 1086 +-- truncate_limit: 100 +-- Test a DO ALSO INSERT ... SELECT rule +drop rule base_tab_def_view_ins_rule on base_tab_def_view +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE base_tab_def_view_ins_rule ON base_tab_def_view" +== 1087 +-- truncate_limit: 100 +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do also insert into base_tab_def (a, b, e) select new.a, new.b, 'xxx' +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE base_tab_def_view_ins_rule AS ON INSERT TO base_tab_def_view DO INSERT INTO base_tab_..." +== 1088 +-- truncate_limit: 100 +truncate base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE base_tab_def" +== 1089 +-- truncate_limit: 100 +insert into base_tab_def_view values (1, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (1, DEFAULT, DEFAULT, DEFAULT, DEFAULT)" +== 1090 +-- truncate_limit: 100 +insert into base_tab_def_view values (2, default, default, default, default), + (3, default, default, default, default) +-- +TABLE: name="base_tab_def_view" schema="" table="base_tab_def_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_def_view VALUES (...)" +== 1091 +-- truncate_limit: 100 +select * from base_tab_def order by a, e nulls first +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tab_def ORDER BY a, e NULLS FIRST" +== 1092 +-- truncate_limit: 100 +drop view base_tab_def_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW base_tab_def_view" +== 1093 +-- truncate_limit: 100 +drop table base_tab_def +-- +TABLE: name="base_tab_def" schema="" table="base_tab_def" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tab_def" +== 1094 +-- truncate_limit: 100 +-- Test defaults with array assignments +create table base_tab (a serial, b int[], c text, d text default 'Table default') +-- +TABLE: name="base_tab" schema="" table="base_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE base_tab (a serial, b int[], c text, d text DEFAULT 'Table default')" +== 1095 +-- truncate_limit: 100 +create view base_tab_view as select c, a, b from base_tab +-- +TABLE: name="base_tab_view" schema="" table="base_tab_view" ctx=DDL +TABLE: name="base_tab" schema="" table="base_tab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW base_tab_view AS SELECT c, a, b FROM base_tab" +== 1096 +-- truncate_limit: 100 +alter view base_tab_view alter column c set default 'View default' +-- +TABLE: name="base_tab_view" schema="" table="base_tab_view" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER VIEW base_tab_view ALTER COLUMN c SET DEFAULT 'View default'" +== 1097 +-- truncate_limit: 100 +insert into base_tab_view (b[1], b[2], c, b[5], b[4], a, b[3]) +values (1, 2, default, 5, 4, default, 3), (10, 11, 'C value', 14, 13, 100, 12) +-- +TABLE: name="base_tab_view" schema="" table="base_tab_view" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO base_tab_view (b[1], b[2], c, b[5], b[4], a, b[3]) VALUES (...)" +== 1098 +-- truncate_limit: 100 +select * from base_tab order by a +-- +TABLE: name="base_tab" schema="" table="base_tab" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM base_tab ORDER BY a" +== 1099 +-- truncate_limit: 100 +drop view base_tab_view +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW base_tab_view" +== 1100 +-- truncate_limit: 100 +drop table base_tab +-- +TABLE: name="base_tab" schema="" table="base_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE base_tab" diff --git a/parser/testdata/summary_truncate/postgres_regress/update.metadata.json b/parser/testdata/summary_truncate/postgres_regress/update.metadata.json new file mode 100644 index 0000000..1b73a29 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/update.metadata.json @@ -0,0 +1,261 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/update.test b/parser/testdata/summary_truncate/postgres_regress/update.test new file mode 100644 index 0000000..b65f81f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/update.test @@ -0,0 +1,2192 @@ +== 001 +-- truncate_limit: 100 +|-- +-- UPDATE syntax tests +|-- + +CREATE TABLE update_test ( + a INT DEFAULT 10, + b INT, + c TEXT +) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE update_test (a int DEFAULT 10, b int, c text)" +== 002 +-- truncate_limit: 100 +CREATE TABLE upsert_test ( + a INT PRIMARY KEY, + b TEXT +) +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE upsert_test (a int PRIMARY KEY, b text)" +== 003 +-- truncate_limit: 100 +INSERT INTO update_test VALUES (5, 10, 'foo') +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO update_test VALUES (5, 10, 'foo')" +== 004 +-- truncate_limit: 100 +INSERT INTO update_test(b, a) VALUES (15, 10) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO update_test (b, a) VALUES (15, 10)" +== 005 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 006 +-- truncate_limit: 100 +UPDATE update_test SET a = DEFAULT, b = DEFAULT +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test SET a = DEFAULT, b = DEFAULT" +== 007 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 008 +-- truncate_limit: 100 +-- aliases for the UPDATE target table +UPDATE update_test AS t SET b = 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test t SET b = 10 WHERE t.a = 10" +== 009 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 010 +-- truncate_limit: 100 +UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10" +== 011 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 012 +-- truncate_limit: 100 +-- error, you're not supposed to qualify the target column +UPDATE update_test t SET t.b = t.b + 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test t SET t.b = t.b + 10 WHERE t.a = 10" +== 013 +-- truncate_limit: 100 +|-- +-- Test VALUES in FROM +|-- + +UPDATE update_test SET a=v.i FROM (VALUES(100, 20)) AS v(i, j) + WHERE update_test.b = v.j +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test SET a = v.i FROM (VALUES (100, 20)) v(i, j) WHERE update_test.b = v.j" +== 014 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 015 +-- truncate_limit: 100 +-- fail, wrong data type: +UPDATE update_test SET a = v.* FROM (VALUES(100, 20)) AS v(i, j) + WHERE update_test.b = v.j +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test SET a = v.* FROM (VALUES (100, 20)) v(i, j) WHERE update_test.b = v.j" +== 016 +-- truncate_limit: 100 +|-- +-- Test multiple-set-clause syntax +|-- + +INSERT INTO update_test SELECT a,b+1,c FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO update_test SELECT a, b + 1, c FROM update_test" +== 017 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 018 +-- truncate_limit: 100 +UPDATE update_test SET (c,b,a) = ('bugle', b+11, DEFAULT) WHERE c = 'foo' +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test SET (c, b, a) = ('bugle', b + 11, DEFAULT) WHERE c = 'foo'" +== 019 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 020 +-- truncate_limit: 100 +UPDATE update_test SET (c,b) = ('car', a+b), a = a + 1 WHERE a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test SET (c, b) = ('car', a + b), a = a + 1 WHERE a = 10" +== 021 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 022 +-- truncate_limit: 100 +-- fail, multi assignment to same column: +UPDATE update_test SET (c,b) = ('car', a+b), b = a + 1 WHERE a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test SET (c, b) = ('car', a + b), b = a + 1 WHERE a = 10" +== 023 +-- truncate_limit: 100 +-- uncorrelated sub-select: +UPDATE update_test + SET (b,a) = (select a,b from update_test where b = 41 and c = 'car') + WHERE a = 100 AND b = 20 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +FILTER: schema="" table="" column="b" +FILTER: schema="" table="" column="c" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test SET (b, a) = (SELECT a, b FROM update_test WHERE ...) WHERE a = 100 AND b = 20" +== 024 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 025 +-- truncate_limit: 100 +-- correlated sub-select: +UPDATE update_test o + SET (b,a) = (select a+1,b from update_test i + where i.a=o.a and i.b=o.b and i.c is not distinct from o.c) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +ALIAS: "i"="update_test" +ALIAS: "o"="update_test" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="o" column="a" +FILTER: schema="" table="i" column="b" +FILTER: schema="" table="o" column="b" +FILTER: schema="" table="i" column="c" +FILTER: schema="" table="o" column="c" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="o" column="a" +FILTER: schema="" table="i" column="b" +FILTER: schema="" table="o" column="b" +FILTER: schema="" table="i" column="c" +FILTER: schema="" table="o" column="c" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test o SET (b, a) = (SELECT a + 1, b FROM update_test i WHERE ...)" +== 026 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 027 +-- truncate_limit: 100 +-- fail, multiple rows supplied: +UPDATE update_test SET (b,a) = (select a+1,b from update_test) +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test SET (b, a) = (SELECT a + 1, b FROM update_test)" +== 028 +-- truncate_limit: 100 +-- set to null if no rows supplied: +UPDATE update_test SET (b,a) = (select a+1,b from update_test where a = 1000) + WHERE a = 11 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test SET (b, a) = (SELECT a + 1, b FROM update_test WHERE a = 1000) WHERE a = 11" +== 029 +-- truncate_limit: 100 +SELECT * FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM update_test" +== 030 +-- truncate_limit: 100 +-- *-expansion should work in this context: +UPDATE update_test SET (a,b) = ROW(v.*) FROM (VALUES(21, 100)) AS v(i, j) + WHERE update_test.a = v.i +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test SET (a, b) = ROW(v.*) FROM (VALUES (21, 100)) v(i, j) WHERE update_test.a = v.i" +== 031 +-- truncate_limit: 100 +-- you might expect this to work, but syntactically it's not a RowExpr: +UPDATE update_test SET (a,b) = (v.*) FROM (VALUES(21, 101)) AS v(i, j) + WHERE update_test.a = v.i +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test SET (a, b) = v.* FROM (VALUES (21, 101)) v(i, j) WHERE update_test.a = v.i" +== 032 +-- truncate_limit: 100 +-- if an alias for the target table is specified, don't allow references +-- to the original table name +UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10 +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +ALIAS: "t"="update_test" +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test t SET b = update_test.b + 10 WHERE t.a = 10" +== 033 +-- truncate_limit: 100 +-- Make sure that we can update to a TOASTed value. +UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car' +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: UpdateStmt +TRUNCATED: "UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car'" +== 034 +-- truncate_limit: 100 +SELECT a, b, char_length(c) FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, char_length(c) FROM update_test" +== 035 +-- truncate_limit: 100 +-- Check multi-assignment with a Result node to handle a one-time filter. +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +ALIAS: "s"="update_test" +ALIAS: "t"="update_test" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +STMT: ExplainStmt +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) UPDATE update_test t SET (a, b) = (SELECT b, a FROM update_test s WH..." +== 036 +-- truncate_limit: 100 +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DML +TABLE: name="update_test" schema="" table="update_test" ctx=Select +TABLE: name="update_test" schema="" table="update_test" ctx=Select +ALIAS: "s"="update_test" +ALIAS: "t"="update_test" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +FILTER: schema="" table="s" column="a" +FILTER: schema="" table="t" column="a" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE update_test t SET ... = ... WHERE current_user = session_user" +== 037 +-- truncate_limit: 100 +SELECT a, b, char_length(c) FROM update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=Select +FUNCTION: name="char_length" function="char_length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT a, b, char_length(c) FROM update_test" +== 038 +-- truncate_limit: 100 +-- Test ON CONFLICT DO UPDATE + +INSERT INTO upsert_test VALUES(1, 'Boo'), (3, 'Zoo') +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert_test VALUES (1, 'Boo'), (3, 'Zoo')" +== 039 +-- truncate_limit: 100 +-- uncorrelated sub-select: +WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test + VALUES (1, 'Bar') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +CTE: "aaa" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aaa AS (...) INSERT INTO upsert_test VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... RE..." +== 040 +-- truncate_limit: 100 +-- correlated sub-select: +INSERT INTO upsert_test VALUES (1, 'Baz'), (3, 'Zaz') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Correlated', a from upsert_test i WHERE i.a = upsert_test.a) + RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="upsert_test" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="upsert_test" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert_test VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... RETURNING *" +== 041 +-- truncate_limit: 100 +-- correlated sub-select (EXCLUDED.* alias): +INSERT INTO upsert_test VALUES (1, 'Bat'), (3, 'Zot') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert_test VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... RETURNING *" +== 042 +-- truncate_limit: 100 +-- ON CONFLICT using system attributes in RETURNING, testing both the +-- inserting and updating paths. See bug report at: +-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au +INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = 0 AS xmax_correct +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert_test VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... RETURNING tableoid::..." +== 043 +-- truncate_limit: 100 +-- currently xmax is set after a conflict - that's probably not good, +-- but it seems worthwhile to have to be explicit if that changes. +INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = pg_current_xact_id()::xid AS xmax_correct +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=Select +ALIAS: "i"="upsert_test" +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +FILTER: schema="" table="i" column="a" +FILTER: schema="" table="excluded" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert_test VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... RETURNING tableoid::..." +== 044 +-- truncate_limit: 100 +DROP TABLE update_test +-- +TABLE: name="update_test" schema="" table="update_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE update_test" +== 045 +-- truncate_limit: 100 +DROP TABLE upsert_test +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE upsert_test" +== 046 +-- truncate_limit: 100 +-- Test ON CONFLICT DO UPDATE with partitioned table and non-identical children + +CREATE TABLE upsert_test ( + a INT PRIMARY KEY, + b TEXT +) PARTITION BY LIST (a) +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE upsert_test (a int PRIMARY KEY, b text) PARTITION BY LIST (a)" +== 047 +-- truncate_limit: 100 +CREATE TABLE upsert_test_1 PARTITION OF upsert_test FOR VALUES IN (1) +-- +TABLE: name="upsert_test_1" schema="" table="upsert_test_1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE upsert_test_1 PARTITION OF upsert_test FOR VALUES IN (1)" +== 048 +-- truncate_limit: 100 +CREATE TABLE upsert_test_2 (b TEXT, a INT PRIMARY KEY) +-- +TABLE: name="upsert_test_2" schema="" table="upsert_test_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE upsert_test_2 (b text, a int PRIMARY KEY)" +== 049 +-- truncate_limit: 100 +ALTER TABLE upsert_test ATTACH PARTITION upsert_test_2 FOR VALUES IN (2) +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE upsert_test ATTACH PARTITION upsert_test_2 FOR VALUES IN (2)" +== 050 +-- truncate_limit: 100 +INSERT INTO upsert_test VALUES(1, 'Boo'), (2, 'Zoo') +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO upsert_test VALUES (1, 'Boo'), (2, 'Zoo')" +== 051 +-- truncate_limit: 100 +-- uncorrelated sub-select: +WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test + VALUES (1, 'Bar') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +CTE: "aaa" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aaa AS (...) INSERT INTO upsert_test VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... RE..." +== 052 +-- truncate_limit: 100 +-- correlated sub-select: +WITH aaa AS (SELECT 1 AS ctea, ' Foo' AS cteb) INSERT INTO upsert_test + VALUES (1, 'Bar'), (2, 'Baz') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT upsert_test.b||cteb, upsert_test.a FROM aaa) RETURNING * +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DML +CTE: "aaa" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aaa AS (...) INSERT INTO upsert_test VALUES (...) ON CONFLICT (a) DO UPDATE SET ... = ... RE..." +== 053 +-- truncate_limit: 100 +DROP TABLE upsert_test +-- +TABLE: name="upsert_test" schema="" table="upsert_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE upsert_test" +== 054 +-- truncate_limit: 100 +--------------------------- +-- UPDATE with row movement +--------------------------- + +-- When a partitioned table receives an UPDATE to the partitioned key and the +-- new values no longer meet the partition's bound, the row must be moved to +-- the correct partition for the new partition key (if one exists). We must +-- also ensure that updatable views on partitioned tables properly enforce any +-- WITH CHECK OPTION that is defined. The situation with triggers in this case +-- also requires thorough testing as partition key updates causing row +-- movement convert UPDATEs into DELETE+INSERT. + +CREATE TABLE range_parted ( + a text, + b bigint, + c numeric, + d int, + e varchar +) PARTITION BY RANGE (a, b) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE range_parted (a text, b bigint, c numeric, d int, e varchar) PARTITION BY RANGE (a, b)" +== 055 +-- truncate_limit: 100 +-- Create partitions intentionally in descending bound order, so as to test +-- that update-row-movement works with the leaf partitions not in bound order. +CREATE TABLE part_b_20_b_30 (e varchar, c numeric, a text, b bigint, d int) +-- +TABLE: name="part_b_20_b_30" schema="" table="part_b_20_b_30" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_b_20_b_30 (e varchar, c numeric, a text, b bigint, d int)" +== 056 +-- truncate_limit: 100 +ALTER TABLE range_parted ATTACH PARTITION part_b_20_b_30 FOR VALUES FROM ('b', 20) TO ('b', 30) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION part_b_20_b_30 FOR VALUES FROM ('b', 20) TO ('b', 30)" +== 057 +-- truncate_limit: 100 +CREATE TABLE part_b_10_b_20 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY RANGE (c) +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_b_10_b_20 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY RANGE (c)" +== 058 +-- truncate_limit: 100 +CREATE TABLE part_b_1_b_10 PARTITION OF range_parted FOR VALUES FROM ('b', 1) TO ('b', 10) +-- +TABLE: name="part_b_1_b_10" schema="" table="part_b_1_b_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_b_1_b_10 PARTITION OF range_parted FOR VALUES FROM ('b', 1) TO ('b', 10)" +== 059 +-- truncate_limit: 100 +ALTER TABLE range_parted ATTACH PARTITION part_b_10_b_20 FOR VALUES FROM ('b', 10) TO ('b', 20) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ATTACH PARTITION part_b_10_b_20 FOR VALUES FROM ('b', 10) TO ('b', 20)" +== 060 +-- truncate_limit: 100 +CREATE TABLE part_a_10_a_20 PARTITION OF range_parted FOR VALUES FROM ('a', 10) TO ('a', 20) +-- +TABLE: name="part_a_10_a_20" schema="" table="part_a_10_a_20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_a_10_a_20 PARTITION OF range_parted FOR VALUES FROM ('a', 10) TO ('a', 20)" +== 061 +-- truncate_limit: 100 +CREATE TABLE part_a_1_a_10 PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('a', 10) +-- +TABLE: name="part_a_1_a_10" schema="" table="part_a_1_a_10" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_a_1_a_10 PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('a', 10)" +== 062 +-- truncate_limit: 100 +-- Check that partition-key UPDATE works sanely on a partitioned table that +-- does not have any child partitions. +UPDATE part_b_10_b_20 set b = b - 6 +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_b_10_b_20 SET b = b - 6" +== 063 +-- truncate_limit: 100 +-- Create some more partitions following the above pattern of descending bound +-- order, but let's make the situation a bit more complex by having the +-- attribute numbers of the columns vary from their parent partition. +CREATE TABLE part_c_100_200 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY range (abs(d)) +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_c_100_200 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY RANGE ((..." +== 064 +-- truncate_limit: 100 +ALTER TABLE part_c_100_200 DROP COLUMN e, DROP COLUMN c, DROP COLUMN a +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_c_100_200 DROP e, DROP c, DROP a" +== 065 +-- truncate_limit: 100 +ALTER TABLE part_c_100_200 ADD COLUMN c numeric, ADD COLUMN e varchar, ADD COLUMN a text +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_c_100_200 ADD COLUMN c numeric, ADD COLUMN e varchar, ADD COLUMN a text" +== 066 +-- truncate_limit: 100 +ALTER TABLE part_c_100_200 DROP COLUMN b +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_c_100_200 DROP b" +== 067 +-- truncate_limit: 100 +ALTER TABLE part_c_100_200 ADD COLUMN b bigint +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_c_100_200 ADD COLUMN b bigint" +== 068 +-- truncate_limit: 100 +CREATE TABLE part_d_1_15 PARTITION OF part_c_100_200 FOR VALUES FROM (1) TO (15) +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_d_1_15 PARTITION OF part_c_100_200 FOR VALUES FROM (1) TO (15)" +== 069 +-- truncate_limit: 100 +CREATE TABLE part_d_15_20 PARTITION OF part_c_100_200 FOR VALUES FROM (15) TO (20) +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_d_15_20 PARTITION OF part_c_100_200 FOR VALUES FROM (15) TO (20)" +== 070 +-- truncate_limit: 100 +ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_100_200 FOR VALUES FROM (100) TO (200) +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_100_200 FOR VALUES FROM (100) TO (200)" +== 071 +-- truncate_limit: 100 +CREATE TABLE part_c_1_100 (e varchar, d int, c numeric, b bigint, a text) +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_c_1_100 (e varchar, d int, c numeric, b bigint, a text)" +== 072 +-- truncate_limit: 100 +ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_1_100 FOR VALUES FROM (1) TO (100) +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_1_100 FOR VALUES FROM (1) TO (100)" +== 073 +-- truncate_limit: 100 +-- The order of subplans should be in bound order +EXPLAIN (costs off) UPDATE range_parted set c = c - 50 WHERE c > 97 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: ExplainStmt +STMT: UpdateStmt +TRUNCATED: "EXPLAIN (COSTS OFF) UPDATE range_parted SET c = c - 50 WHERE c > 97" +== 074 +-- truncate_limit: 100 +-- fail, row movement happens only within the partition subtree. +UPDATE part_c_100_200 set c = c - 20, d = c WHERE c = 105 +-- +TABLE: name="part_c_100_200" schema="" table="part_c_100_200" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_c_100_200 SET c = c - 20, d = c WHERE c = 105" +== 075 +-- truncate_limit: 100 +-- fail, no partition key update, so no attempt to move tuple, +-- but "a = 'a'" violates partition constraint enforced by root partition) +UPDATE part_b_10_b_20 set a = 'a' +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_b_10_b_20 SET a = 'a'" +== 076 +-- truncate_limit: 100 +-- ok, partition key update, no constraint violation +UPDATE range_parted set d = d - 10 WHERE d > 10 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET d = d - 10 WHERE d > 10" +== 077 +-- truncate_limit: 100 +-- ok, no partition key update, no constraint violation +UPDATE range_parted set e = d +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET e = d" +== 078 +-- truncate_limit: 100 +-- No row found +UPDATE part_c_1_100 set c = c + 20 WHERE c = 98 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_c_1_100 SET c = c + 20 WHERE c = 98" +== 079 +-- truncate_limit: 100 +-- ok, row movement +UPDATE part_b_10_b_20 set c = c + 20 returning c, b, a +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_b_10_b_20 SET c = c + 20 RETURNING c, b, a" +== 080 +-- truncate_limit: 100 +-- fail, row movement happens only within the partition subtree. +UPDATE part_b_10_b_20 set b = b - 6 WHERE c > 116 returning * +-- +TABLE: name="part_b_10_b_20" schema="" table="part_b_10_b_20" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_b_10_b_20 SET b = b - 6 WHERE c > 116 RETURNING *" +== 081 +-- truncate_limit: 100 +-- ok, row movement, with subset of rows moved into different partition. +UPDATE range_parted set b = b - 6 WHERE c > 116 returning a, b + c +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET b = b - 6 WHERE c > 116 RETURNING a, b + c" +== 082 +-- truncate_limit: 100 +-- Common table needed for multiple test scenarios. +CREATE TABLE mintab(c1 int) +-- +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE mintab (c1 int)" +== 083 +-- truncate_limit: 100 +INSERT into mintab VALUES (120) +-- +TABLE: name="mintab" schema="" table="mintab" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO mintab VALUES (120)" +== 084 +-- truncate_limit: 100 +-- update partition key using updatable view. +CREATE VIEW upview AS SELECT * FROM range_parted WHERE (select c > c1 FROM mintab) WITH CHECK OPTION +-- +TABLE: name="upview" schema="" table="upview" ctx=DDL +TABLE: name="range_parted" schema="" table="range_parted" ctx=Select +TABLE: name="mintab" schema="" table="mintab" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW upview AS SELECT * FROM range_parted WHERE (SELECT c > c1 FROM mintab) WITH CHECK OPTION" +== 085 +-- truncate_limit: 100 +-- ok +UPDATE upview set c = 199 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE upview SET c = 199 WHERE b = 4" +== 086 +-- truncate_limit: 100 +-- fail, check option violation +UPDATE upview set c = 120 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE upview SET c = 120 WHERE b = 4" +== 087 +-- truncate_limit: 100 +-- fail, row movement with check option violation +UPDATE upview set a = 'b', b = 15, c = 120 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE upview SET a = 'b', b = 15, c = 120 WHERE b = 4" +== 088 +-- truncate_limit: 100 +-- ok, row movement, check option passes +UPDATE upview set a = 'b', b = 15 WHERE b = 4 +-- +TABLE: name="upview" schema="" table="upview" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE upview SET a = 'b', b = 15 WHERE b = 4" +== 089 +-- truncate_limit: 100 +-- cleanup +DROP VIEW upview +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW upview" +== 090 +-- truncate_limit: 100 +UPDATE range_parted set c = 95 WHERE a = 'b' and b > 10 and c > 100 returning (range_parted), * +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET c = 95 WHERE a = 'b' AND b > 10 AND c > 100 RETURNING range_parted, *" +== 091 +-- truncate_limit: 100 +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; +$$ +-- +FUNCTION: name="trans_updatetrigfunc" function="trans_updatetrigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trans_updatetrigfunc() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n raise n..." +== 092 +-- truncate_limit: 100 +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() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trans_updatetrig AFTER UPDATE ON range_parted REFERENCING OLD TABLE old_table NEW ..." +== 093 +-- truncate_limit: 100 +UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end ) WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET ... = ... WHERE a = 'b' AND b > 10 AND c >= 96" +== 094 +-- truncate_limit: 100 +-- 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() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trans_deletetrig AFTER DELETE ON range_parted REFERENCING OLD TABLE old_table EXEC..." +== 095 +-- truncate_limit: 100 +CREATE TRIGGER trans_inserttrig + AFTER INSERT ON range_parted REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trans_inserttrig AFTER INSERT ON range_parted REFERENCING NEW TABLE new_table EXEC..." +== 096 +-- truncate_limit: 100 +UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET c = c + 50 WHERE a = 'b' AND b > 10 AND c >= 96" +== 097 +-- truncate_limit: 100 +DROP TRIGGER trans_deletetrig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trans_deletetrig ON range_parted" +== 098 +-- truncate_limit: 100 +DROP TRIGGER trans_inserttrig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trans_inserttrig ON range_parted" +== 099 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION func_parted_mod_b() RETURNS trigger AS $$\nBEGIN\n NEW.b = NEW.b + 1;\n return N..." +== 100 +-- truncate_limit: 100 +CREATE TRIGGER trig_c1_100 BEFORE UPDATE OR INSERT ON part_c_1_100 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_c1_100 BEFORE INSERT OR UPDATE ON part_c_1_100 FOR EACH ROW EXECUTE FUNCTION ..." +== 101 +-- truncate_limit: 100 +CREATE TRIGGER trig_d1_15 BEFORE UPDATE OR INSERT ON part_d_1_15 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_d1_15 BEFORE INSERT OR UPDATE ON part_d_1_15 FOR EACH ROW EXECUTE FUNCTION fu..." +== 102 +-- truncate_limit: 100 +CREATE TRIGGER trig_d15_20 BEFORE UPDATE OR INSERT ON part_d_15_20 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_d15_20 BEFORE INSERT OR UPDATE ON part_d_15_20 FOR EACH ROW EXECUTE FUNCTION ..." +== 103 +-- truncate_limit: 100 +UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end) WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET ... = ... WHERE a = 'b' AND b > 10 AND c >= 96" +== 104 +-- truncate_limit: 100 +UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET c = c + 50 WHERE a = 'b' AND b > 10 AND c >= 96" +== 105 +-- truncate_limit: 100 +UPDATE range_parted set b = 15 WHERE b = 1 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET b = 15 WHERE b = 1" +== 106 +-- truncate_limit: 100 +DROP TRIGGER trans_updatetrig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trans_updatetrig ON range_parted" +== 107 +-- truncate_limit: 100 +DROP TRIGGER trig_c1_100 ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trig_c1_100 ON part_c_1_100" +== 108 +-- truncate_limit: 100 +DROP TRIGGER trig_d1_15 ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trig_d1_15 ON part_d_1_15" +== 109 +-- truncate_limit: 100 +DROP TRIGGER trig_d15_20 ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trig_d15_20 ON part_d_15_20" +== 110 +-- truncate_limit: 100 +DROP FUNCTION func_parted_mod_b() +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION func_parted_mod_b()" +== 111 +-- truncate_limit: 100 +-- RLS policies with update-row-movement +----------------------------------------- + +ALTER TABLE range_parted ENABLE ROW LEVEL SECURITY +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE range_parted ENABLE ROW LEVEL SECURITY" +== 112 +-- truncate_limit: 100 +CREATE USER regress_range_parted_user +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE USER regress_range_parted_user" +== 113 +-- truncate_limit: 100 +GRANT ALL ON range_parted, mintab TO regress_range_parted_user +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: GrantStmt +TRUNCATED: "GRANT ALL ON range_parted, mintab TO regress_range_parted_user" +== 114 +-- truncate_limit: 100 +CREATE POLICY seeall ON range_parted AS PERMISSIVE FOR SELECT USING (true) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY seeall ON range_parted FOR SELECT TO public USING (true)" +== 115 +-- truncate_limit: 100 +CREATE POLICY policy_range_parted ON range_parted for UPDATE USING (true) WITH CHECK (c % 2 = 0) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY policy_range_parted ON range_parted FOR UPDATE TO public USING (true) WITH CHECK ((..." +== 116 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_range_parted_user" +== 117 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b', c = 151 WHERE a = 'a' AND c = 200" +== 118 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 119 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="func_d_1_15" function="func_d_1_15" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION func_d_1_15() RETURNS trigger AS $$\nBEGIN\n NEW.c = NEW.c + 1; -- Make even numb..." +== 120 +-- truncate_limit: 100 +CREATE TRIGGER trig_d_1_15 BEFORE INSERT ON part_d_1_15 + FOR EACH ROW EXECUTE PROCEDURE func_d_1_15() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_d_1_15 BEFORE INSERT ON part_d_1_15 FOR EACH ROW EXECUTE FUNCTION func_d_1_15()" +== 121 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_range_parted_user" +== 122 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b', c = 151 WHERE a = 'a' AND c = 200" +== 123 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 124 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_range_parted_user" +== 125 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b', c = 150 WHERE a = 'a' AND c = 200" +== 126 +-- truncate_limit: 100 +-- Cleanup +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 127 +-- truncate_limit: 100 +DROP TRIGGER trig_d_1_15 ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trig_d_1_15 ON part_d_1_15" +== 128 +-- truncate_limit: 100 +DROP FUNCTION func_d_1_15() +-- +FUNCTION: name="func_d_1_15" function="func_d_1_15" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION func_d_1_15()" +== 129 +-- truncate_limit: 100 +-- Policy expression contains SubPlan +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 130 +-- truncate_limit: 100 +CREATE POLICY policy_range_parted_subplan on range_parted + AS RESTRICTIVE for UPDATE USING (true) + WITH CHECK ((SELECT range_parted.c <= c1 FROM mintab)) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY policy_range_parted_subplan ON range_parted AS RESTRICTIVE FOR UPDATE TO public USI..." +== 131 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_range_parted_user" +== 132 +-- truncate_limit: 100 +-- fail, mintab has row with c1 = 120 +UPDATE range_parted set a = 'b', c = 122 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b', c = 122 WHERE a = 'a' AND c = 200" +== 133 +-- truncate_limit: 100 +-- ok +UPDATE range_parted set a = 'b', c = 120 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b', c = 120 WHERE a = 'a' AND c = 200" +== 134 +-- truncate_limit: 100 +-- RLS policy expression contains whole row. + +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 135 +-- truncate_limit: 100 +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) +-- +STMT: CreatePolicyStmt +TRUNCATED: "CREATE POLICY policy_range_parted_wholerow ON range_parted AS RESTRICTIVE FOR UPDATE TO public US..." +== 136 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_range_parted_user" +== 137 +-- truncate_limit: 100 +-- ok, should pass the RLS check +UPDATE range_parted set a = 'b', c = 112 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b', c = 112 WHERE a = 'a' AND c = 200" +== 138 +-- truncate_limit: 100 +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 139 +-- truncate_limit: 100 +SET SESSION AUTHORIZATION regress_range_parted_user +-- +STMT: VariableSetStmt +TRUNCATED: "SET session_authorization TO regress_range_parted_user" +== 140 +-- truncate_limit: 100 +-- fail, the whole row RLS check should fail +UPDATE range_parted set a = 'b', c = 116 WHERE a = 'a' and c = 200 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b', c = 116 WHERE a = 'a' AND c = 200" +== 141 +-- truncate_limit: 100 +-- Cleanup +RESET SESSION AUTHORIZATION +-- +STMT: VariableSetStmt +TRUNCATED: "RESET session_authorization" +== 142 +-- truncate_limit: 100 +DROP POLICY policy_range_parted ON range_parted +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY policy_range_parted ON range_parted" +== 143 +-- truncate_limit: 100 +DROP POLICY policy_range_parted_subplan ON range_parted +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY policy_range_parted_subplan ON range_parted" +== 144 +-- truncate_limit: 100 +DROP POLICY policy_range_parted_wholerow ON range_parted +-- +STMT: DropStmt +TRUNCATED: "DROP POLICY policy_range_parted_wholerow ON range_parted" +== 145 +-- truncate_limit: 100 +REVOKE ALL ON range_parted, mintab FROM regress_range_parted_user +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: GrantStmt +TRUNCATED: "REVOKE ALL ON range_parted, mintab FROM regress_range_parted_user" +== 146 +-- truncate_limit: 100 +DROP USER regress_range_parted_user +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_range_parted_user" +== 147 +-- truncate_limit: 100 +DROP TABLE mintab +-- +TABLE: name="mintab" schema="" table="mintab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE mintab" +== 148 +-- truncate_limit: 100 +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; +$$ +-- +FUNCTION: name="trigfunc" function="trigfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION trigfunc() RETURNS trigger LANGUAGE plpgsql AS $$\n begin\n raise notice 'trigg..." +== 149 +-- truncate_limit: 100 +-- Triggers on root partition +CREATE TRIGGER parent_delete_trig + AFTER DELETE ON range_parted for each statement execute procedure trigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_delete_trig AFTER DELETE ON range_parted EXECUTE FUNCTION trigfunc()" +== 150 +-- truncate_limit: 100 +CREATE TRIGGER parent_update_trig + AFTER UPDATE ON range_parted for each statement execute procedure trigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_update_trig AFTER UPDATE ON range_parted EXECUTE FUNCTION trigfunc()" +== 151 +-- truncate_limit: 100 +CREATE TRIGGER parent_insert_trig + AFTER INSERT ON range_parted for each statement execute procedure trigfunc() +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parent_insert_trig AFTER INSERT ON range_parted EXECUTE FUNCTION trigfunc()" +== 152 +-- truncate_limit: 100 +-- 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() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER c1_delete_trig AFTER DELETE ON part_c_1_100 EXECUTE FUNCTION trigfunc()" +== 153 +-- truncate_limit: 100 +CREATE TRIGGER c1_update_trig + AFTER UPDATE ON part_c_1_100 for each statement execute procedure trigfunc() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER c1_update_trig AFTER UPDATE ON part_c_1_100 EXECUTE FUNCTION trigfunc()" +== 154 +-- truncate_limit: 100 +CREATE TRIGGER c1_insert_trig + AFTER INSERT ON part_c_1_100 for each statement execute procedure trigfunc() +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER c1_insert_trig AFTER INSERT ON part_c_1_100 EXECUTE FUNCTION trigfunc()" +== 155 +-- truncate_limit: 100 +-- 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() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER d1_delete_trig AFTER DELETE ON part_d_1_15 EXECUTE FUNCTION trigfunc()" +== 156 +-- truncate_limit: 100 +CREATE TRIGGER d1_update_trig + AFTER UPDATE ON part_d_1_15 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER d1_update_trig AFTER UPDATE ON part_d_1_15 EXECUTE FUNCTION trigfunc()" +== 157 +-- truncate_limit: 100 +CREATE TRIGGER d1_insert_trig + AFTER INSERT ON part_d_1_15 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER d1_insert_trig AFTER INSERT ON part_d_1_15 EXECUTE FUNCTION trigfunc()" +== 158 +-- truncate_limit: 100 +-- 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() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER d15_delete_trig AFTER DELETE ON part_d_15_20 EXECUTE FUNCTION trigfunc()" +== 159 +-- truncate_limit: 100 +CREATE TRIGGER d15_update_trig + AFTER UPDATE ON part_d_15_20 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER d15_update_trig AFTER UPDATE ON part_d_15_20 EXECUTE FUNCTION trigfunc()" +== 160 +-- truncate_limit: 100 +CREATE TRIGGER d15_insert_trig + AFTER INSERT ON part_d_15_20 for each statement execute procedure trigfunc() +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER d15_insert_trig AFTER INSERT ON part_d_15_20 EXECUTE FUNCTION trigfunc()" +== 161 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET c = c - 50 WHERE c > 97" +== 162 +-- truncate_limit: 100 +DROP TRIGGER parent_delete_trig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER parent_delete_trig ON range_parted" +== 163 +-- truncate_limit: 100 +DROP TRIGGER parent_update_trig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER parent_update_trig ON range_parted" +== 164 +-- truncate_limit: 100 +DROP TRIGGER parent_insert_trig ON range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER parent_insert_trig ON range_parted" +== 165 +-- truncate_limit: 100 +DROP TRIGGER c1_delete_trig ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER c1_delete_trig ON part_c_1_100" +== 166 +-- truncate_limit: 100 +DROP TRIGGER c1_update_trig ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER c1_update_trig ON part_c_1_100" +== 167 +-- truncate_limit: 100 +DROP TRIGGER c1_insert_trig ON part_c_1_100 +-- +TABLE: name="part_c_1_100" schema="" table="part_c_1_100" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER c1_insert_trig ON part_c_1_100" +== 168 +-- truncate_limit: 100 +DROP TRIGGER d1_delete_trig ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER d1_delete_trig ON part_d_1_15" +== 169 +-- truncate_limit: 100 +DROP TRIGGER d1_update_trig ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER d1_update_trig ON part_d_1_15" +== 170 +-- truncate_limit: 100 +DROP TRIGGER d1_insert_trig ON part_d_1_15 +-- +TABLE: name="part_d_1_15" schema="" table="part_d_1_15" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER d1_insert_trig ON part_d_1_15" +== 171 +-- truncate_limit: 100 +DROP TRIGGER d15_delete_trig ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER d15_delete_trig ON part_d_15_20" +== 172 +-- truncate_limit: 100 +DROP TRIGGER d15_update_trig ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER d15_update_trig ON part_d_15_20" +== 173 +-- truncate_limit: 100 +DROP TRIGGER d15_insert_trig ON part_d_15_20 +-- +TABLE: name="part_d_15_20" schema="" table="part_d_15_20" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER d15_insert_trig ON part_d_15_20" +== 174 +-- truncate_limit: 100 +create table part_def partition of range_parted default +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE part_def PARTITION OF range_parted DEFAULT" +== 175 +-- truncate_limit: 100 +insert into range_parted values ('c', 9) +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO range_parted VALUES ('c', 9)" +== 176 +-- truncate_limit: 100 +-- ok +update part_def set a = 'd' where a = 'c' +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_def SET a = 'd' WHERE a = 'c'" +== 177 +-- truncate_limit: 100 +-- fail +update part_def set a = 'a' where a = 'd' +-- +TABLE: name="part_def" schema="" table="part_def" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_def SET a = 'a' WHERE a = 'd'" +== 178 +-- truncate_limit: 100 +-- 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' +-- +TABLE: name="part_a_10_a_20" schema="" table="part_a_10_a_20" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE part_a_10_a_20 SET a = 'ad' WHERE a = 'a'" +== 179 +-- truncate_limit: 100 +-- ok +UPDATE range_parted set a = 'ad' WHERE a = 'a' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'ad' WHERE a = 'a'" +== 180 +-- truncate_limit: 100 +UPDATE range_parted set a = 'bd' WHERE a = 'b' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'bd' WHERE a = 'b'" +== 181 +-- truncate_limit: 100 +-- Update row movement from default to non-default partitions. +-- ok +UPDATE range_parted set a = 'a' WHERE a = 'ad' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'a' WHERE a = 'ad'" +== 182 +-- truncate_limit: 100 +UPDATE range_parted set a = 'b' WHERE a = 'bd' +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE range_parted SET a = 'b' WHERE a = 'bd'" +== 183 +-- truncate_limit: 100 +-- Cleanup: range_parted no longer needed. +DROP TABLE range_parted +-- +TABLE: name="range_parted" schema="" table="range_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE range_parted" +== 184 +-- truncate_limit: 100 +CREATE TABLE list_parted ( + a text, + b int +) PARTITION BY list (a) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted (a text, b int) PARTITION BY LIST (a)" +== 185 +-- truncate_limit: 100 +CREATE TABLE list_part1 PARTITION OF list_parted for VALUES in ('a', 'b') +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_part1 PARTITION OF list_parted FOR VALUES IN ('a', 'b')" +== 186 +-- truncate_limit: 100 +CREATE TABLE list_default PARTITION OF list_parted default +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_default PARTITION OF list_parted DEFAULT" +== 187 +-- truncate_limit: 100 +INSERT into list_part1 VALUES ('a', 1) +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_part1 VALUES ('a', 1)" +== 188 +-- truncate_limit: 100 +INSERT into list_default VALUES ('d', 10) +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_default VALUES ('d', 10)" +== 189 +-- truncate_limit: 100 +-- fail +UPDATE list_default set a = 'a' WHERE a = 'd' +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE list_default SET a = 'a' WHERE a = 'd'" +== 190 +-- truncate_limit: 100 +-- ok +UPDATE list_default set a = 'x' WHERE a = 'd' +-- +TABLE: name="list_default" schema="" table="list_default" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE list_default SET a = 'x' WHERE a = 'd'" +== 191 +-- truncate_limit: 100 +DROP TABLE list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE list_parted" +== 192 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE utrtest (a int, b text) PARTITION BY LIST (a)" +== 193 +-- truncate_limit: 100 +create table utr1 (a int check (a in (1)), q text, b text) +-- +TABLE: name="utr1" schema="" table="utr1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE utr1 (a int CHECK (a IN (1)), q text, b text)" +== 194 +-- truncate_limit: 100 +create table utr2 (a int check (a in (2)), b text) +-- +TABLE: name="utr2" schema="" table="utr2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE utr2 (a int CHECK (a IN (2)), b text)" +== 195 +-- truncate_limit: 100 +alter table utr1 drop column q +-- +TABLE: name="utr1" schema="" table="utr1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE utr1 DROP q" +== 196 +-- truncate_limit: 100 +alter table utrtest attach partition utr1 for values in (1) +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE utrtest ATTACH PARTITION utr1 FOR VALUES IN (1)" +== 197 +-- truncate_limit: 100 +alter table utrtest attach partition utr2 for values in (2) +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE utrtest ATTACH PARTITION utr2 FOR VALUES IN (2)" +== 198 +-- truncate_limit: 100 +insert into utrtest values (1, 'foo') + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO utrtest VALUES (...) RETURNING *, tableoid::regclass, xmin = pg_current_xact_id()::xi..." +== 199 +-- truncate_limit: 100 +insert into utrtest values (2, 'bar') + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO utrtest VALUES (...) RETURNING *, tableoid::regclass, xmin = pg_current_xact_id()::xi..." +== 200 +-- truncate_limit: 100 +-- fails +insert into utrtest values (2, 'bar') + returning *, tableoid::regclass +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO utrtest VALUES (2, 'bar') RETURNING *, tableoid::regclass" +== 201 +-- truncate_limit: 100 +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 +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE utrtest SET ... = ... FROM (VALUES (...)) s(x) WHERE ... RETURNING *, tableoid::regclass, ..." +== 202 +-- truncate_limit: 100 +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 +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE utrtest SET ... = ... FROM (VALUES (...)) s(x) WHERE ... RETURNING *, tableoid::regclass, ..." +== 203 +-- truncate_limit: 100 +-- fails + +update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x + returning *, tableoid::regclass +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "UPDATE utrtest SET a = 3 - a FROM (VALUES (...)) s(x) WHERE a = s.x RETURNING *, tableoid::regclass" +== 204 +-- truncate_limit: 100 +delete from utrtest + returning *, tableoid::regclass, xmax = pg_current_xact_id()::xid as xmax_ok +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DML +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM utrtest RETURNING *, tableoid::regclass, xmax = pg_current_xact_id()::xid AS xmax_ok" +== 205 +-- truncate_limit: 100 +drop table utrtest +-- +TABLE: name="utrtest" schema="" table="utrtest" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE utrtest" +== 206 +-- truncate_limit: 100 +-------------- +-- 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) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_parted (a numeric, b int, c int8) PARTITION BY LIST (a)" +== 207 +-- truncate_limit: 100 +CREATE TABLE sub_parted PARTITION OF list_parted for VALUES in (1) PARTITION BY list (b) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sub_parted PARTITION OF list_parted FOR VALUES IN (1) PARTITION BY LIST (b)" +== 208 +-- truncate_limit: 100 +CREATE TABLE sub_part1(b int, c int8, a numeric) +-- +TABLE: name="sub_part1" schema="" table="sub_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sub_part1 (b int, c int8, a numeric)" +== 209 +-- truncate_limit: 100 +ALTER TABLE sub_parted ATTACH PARTITION sub_part1 for VALUES in (1) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE sub_parted ATTACH PARTITION sub_part1 FOR VALUES IN (1)" +== 210 +-- truncate_limit: 100 +CREATE TABLE sub_part2(b int, c int8, a numeric) +-- +TABLE: name="sub_part2" schema="" table="sub_part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE sub_part2 (b int, c int8, a numeric)" +== 211 +-- truncate_limit: 100 +ALTER TABLE sub_parted ATTACH PARTITION sub_part2 for VALUES in (2) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE sub_parted ATTACH PARTITION sub_part2 FOR VALUES IN (2)" +== 212 +-- truncate_limit: 100 +CREATE TABLE list_part1(a numeric, b int, c int8) +-- +TABLE: name="list_part1" schema="" table="list_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE list_part1 (a numeric, b int, c int8)" +== 213 +-- truncate_limit: 100 +ALTER TABLE list_parted ATTACH PARTITION list_part1 for VALUES in (2,3) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE list_parted ATTACH PARTITION list_part1 FOR VALUES IN (2, 3)" +== 214 +-- truncate_limit: 100 +INSERT into list_parted VALUES (2,5,50) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES (2, 5, 50)" +== 215 +-- truncate_limit: 100 +INSERT into list_parted VALUES (3,6,60) +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO list_parted VALUES (3, 6, 60)" +== 216 +-- truncate_limit: 100 +INSERT into sub_parted VALUES (1,1,60) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sub_parted VALUES (1, 1, 60)" +== 217 +-- truncate_limit: 100 +INSERT into sub_parted VALUES (1,2,10) +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO sub_parted VALUES (1, 2, 10)" +== 218 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="sub_parted" schema="" table="sub_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE sub_parted SET a = 2 WHERE c = 10" +== 219 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1" +== 220 +-- truncate_limit: 100 +UPDATE list_parted set b = c + a WHERE a = 2 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE list_parted SET b = c + a WHERE a = 2" +== 221 +-- truncate_limit: 100 +SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +FILTER: schema="" table="" column="a" +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1" +== 222 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION func_parted_mod_b() RETURNS trigger AS $$\nBEGIN\n NEW.b = 2; -- This is changing..." +== 223 +-- truncate_limit: 100 +CREATE TRIGGER parted_mod_b before update on sub_part1 + for each row execute procedure func_parted_mod_b() +-- +TABLE: name="sub_part1" schema="" table="sub_part1" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER parted_mod_b BEFORE UPDATE ON sub_part1 FOR EACH ROW EXECUTE FUNCTION func_parted_..." +== 224 +-- truncate_limit: 100 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4" +== 225 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE list_parted SET c = 70 WHERE b = 1" +== 226 +-- truncate_limit: 100 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4" +== 227 +-- truncate_limit: 100 +DROP TRIGGER parted_mod_b ON sub_part1 +-- +TABLE: name="sub_part1" schema="" table="sub_part1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER parted_mod_b ON sub_part1" +== 228 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION func_parted_mod_b() RETURNS trigger AS $$\nBEGIN\n raise notice 'Trigg..." +== 229 +-- truncate_limit: 100 +CREATE TRIGGER trig_skip_delete before delete on sub_part2 + for each row execute procedure func_parted_mod_b() +-- +TABLE: name="sub_part2" schema="" table="sub_part2" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER trig_skip_delete BEFORE DELETE ON sub_part2 FOR EACH ROW EXECUTE FUNCTION func_par..." +== 230 +-- truncate_limit: 100 +UPDATE list_parted set b = 1 WHERE c = 70 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE list_parted SET b = 1 WHERE c = 70" +== 231 +-- truncate_limit: 100 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4" +== 232 +-- truncate_limit: 100 +-- Drop the trigger. Now the row should be moved. +DROP TRIGGER trig_skip_delete ON sub_part2 +-- +TABLE: name="sub_part2" schema="" table="sub_part2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER trig_skip_delete ON sub_part2" +== 233 +-- truncate_limit: 100 +UPDATE list_parted set b = 1 WHERE c = 70 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE list_parted SET b = 1 WHERE c = 70" +== 234 +-- truncate_limit: 100 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4" +== 235 +-- truncate_limit: 100 +DROP FUNCTION func_parted_mod_b() +-- +FUNCTION: name="func_parted_mod_b" function="func_parted_mod_b" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION func_parted_mod_b()" +== 236 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="non_parted" schema="" table="non_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE non_parted (id int)" +== 237 +-- truncate_limit: 100 +INSERT into non_parted VALUES (1), (1), (1), (2), (2), (2), (3), (3), (3) +-- +TABLE: name="non_parted" schema="" table="non_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO non_parted VALUES (1), (1), (1), (2), (2), (2), (3), (3), (3)" +== 238 +-- truncate_limit: 100 +UPDATE list_parted t1 set a = 2 FROM non_parted t2 WHERE t1.a = t2.id and a = 1 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DML +TABLE: name="non_parted" schema="" table="non_parted" ctx=Select +ALIAS: "t1"="list_parted" +ALIAS: "t2"="non_parted" +STMT: UpdateStmt +TRUNCATED: "UPDATE list_parted t1 SET a = 2 FROM non_parted t2 WHERE t1.a = t2.id AND a = 1" +== 239 +-- truncate_limit: 100 +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4 +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4" +== 240 +-- truncate_limit: 100 +DROP TABLE non_parted +-- +TABLE: name="non_parted" schema="" table="non_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE non_parted" +== 241 +-- truncate_limit: 100 +-- Cleanup: list_parted no longer needed. +DROP TABLE list_parted +-- +TABLE: name="list_parted" schema="" table="list_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE list_parted" +== 242 +-- truncate_limit: 100 +-- 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 +-- +FUNCTION: name="dummy_hashint4" function="dummy_hashint4" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION dummy_hashint4(a int4, seed int8) RETURNS int8 AS $$ begin return (a +..." +== 243 +-- truncate_limit: 100 +create operator class custom_opclass for type int4 using hash as +operator 1 = , function 2 dummy_hashint4(int4, int8) +-- +STMT: CreateOpClassStmt +TRUNCATED: "CREATE OPERATOR CLASS custom_opclass FOR TYPE int4 USING hash AS OPERATOR 1 =, FUNCTION 2 dummy_h..." +== 244 +-- truncate_limit: 100 +create table hash_parted ( + a int, + b int +) partition by hash (a custom_opclass, b custom_opclass) +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hash_parted (a int, b int) PARTITION BY HASH (a custom_opclass, b custom_opclass)" +== 245 +-- truncate_limit: 100 +create table hpart1 partition of hash_parted for values with (modulus 2, remainder 1) +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 246 +-- truncate_limit: 100 +create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2) +-- +TABLE: name="hpart2" schema="" table="hpart2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 2)" +== 247 +-- truncate_limit: 100 +create table hpart3 partition of hash_parted for values with (modulus 8, remainder 0) +-- +TABLE: name="hpart3" schema="" table="hpart3" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 8, REMAINDER 0)" +== 248 +-- truncate_limit: 100 +create table hpart4 partition of hash_parted for values with (modulus 8, remainder 4) +-- +TABLE: name="hpart4" schema="" table="hpart4" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE hpart4 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 8, REMAINDER 4)" +== 249 +-- truncate_limit: 100 +insert into hpart1 values (1, 1) +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart1 VALUES (1, 1)" +== 250 +-- truncate_limit: 100 +insert into hpart2 values (2, 5) +-- +TABLE: name="hpart2" schema="" table="hpart2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart2 VALUES (2, 5)" +== 251 +-- truncate_limit: 100 +insert into hpart4 values (3, 4) +-- +TABLE: name="hpart4" schema="" table="hpart4" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO hpart4 VALUES (3, 4)" +== 252 +-- truncate_limit: 100 +-- fail +update hpart1 set a = 3, b=4 where a = 1 +-- +TABLE: name="hpart1" schema="" table="hpart1" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hpart1 SET a = 3, b = 4 WHERE a = 1" +== 253 +-- truncate_limit: 100 +-- ok, row movement +update hash_parted set b = b - 1 where b = 1 +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_parted SET b = b - 1 WHERE b = 1" +== 254 +-- truncate_limit: 100 +-- ok +update hash_parted set b = b + 8 where b = 1 +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE hash_parted SET b = b + 8 WHERE b = 1" +== 255 +-- truncate_limit: 100 +-- cleanup +drop table hash_parted +-- +TABLE: name="hash_parted" schema="" table="hash_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE hash_parted" +== 256 +-- truncate_limit: 100 +drop operator class custom_opclass using hash +-- +STMT: DropStmt +TRUNCATED: "DROP OPERATOR CLASS custom_opclass USING hash" +== 257 +-- truncate_limit: 100 +drop function dummy_hashint4(a int4, seed int8) +-- +FUNCTION: name="dummy_hashint4" function="dummy_hashint4" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION dummy_hashint4(a int4, seed int8)" diff --git a/parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json new file mode 100644 index 0000000..c30fd55 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json @@ -0,0 +1,48 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/uuid.test b/parser/testdata/summary_truncate/postgres_regress/uuid.test new file mode 100644 index 0000000..946a6f9 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/uuid.test @@ -0,0 +1,400 @@ +== 001 +-- truncate_limit: 100 +-- regression test for the uuid datatype +-- creating test tables +CREATE TABLE guid1 +( + guid_field UUID, + text_field TEXT DEFAULT(now()) +) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE guid1 (guid_field uuid, text_field text DEFAULT now())" +== 002 +-- truncate_limit: 100 +CREATE TABLE guid2 +( + guid_field UUID, + text_field TEXT DEFAULT(now()) +) +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE guid2 (guid_field uuid, text_field text DEFAULT now())" +== 003 +-- truncate_limit: 100 +-- inserting invalid data tests +-- too long +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111F') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('11111111-1111-1111-1111-111111111111F')" +== 004 +-- truncate_limit: 100 +-- too short +INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-1111-11111111111}') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('{11111111-1111-1111-1111-11111111111}')" +== 005 +-- truncate_limit: 100 +-- valid data but invalid format +INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('111-11111-1111-1111-1111-111111111111')" +== 006 +-- truncate_limit: 100 +INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222 ') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('{22222222-2222-2222-2222-222222222222 ')" +== 007 +-- truncate_limit: 100 +-- invalid data +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('11111111-1111-1111-G111-111111111111')" +== 008 +-- truncate_limit: 100 +INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('11+11111-1111-1111-1111-111111111111')" +== 009 +-- truncate_limit: 100 +-- test non-error-throwing API +SELECT pg_input_is_valid('11', 'uuid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('11', 'uuid')" +== 010 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('11', 'uuid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('11', 'uuid')" +== 011 +-- truncate_limit: 100 +--inserting three input formats +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('11111111-1111-1111-1111-111111111111')" +== 012 +-- truncate_limit: 100 +INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('{22222222-2222-2222-2222-222222222222}')" +== 013 +-- truncate_limit: 100 +INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('3f3e3c3b3a3039383736353433a2313e')" +== 014 +-- truncate_limit: 100 +-- retrieving the inserted data +SELECT guid_field FROM guid1 +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT guid_field FROM guid1" +== 015 +-- truncate_limit: 100 +-- ordering test +SELECT guid_field FROM guid1 ORDER BY guid_field ASC +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT guid_field FROM guid1 ORDER BY guid_field ASC" +== 016 +-- truncate_limit: 100 +SELECT guid_field FROM guid1 ORDER BY guid_field DESC +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT guid_field FROM guid1 ORDER BY guid_field DESC" +== 017 +-- truncate_limit: 100 +-- = operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e'" +== 018 +-- truncate_limit: 100 +-- <> operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111'" +== 019 +-- truncate_limit: 100 +-- < operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field < '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 WHERE guid_field < '22222222-2222-2222-2222-222222222222'" +== 020 +-- truncate_limit: 100 +-- <= operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field <= '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 WHERE guid_field <= '22222222-2222-2222-2222-222222222222'" +== 021 +-- truncate_limit: 100 +-- > operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field > '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 WHERE guid_field > '22222222-2222-2222-2222-222222222222'" +== 022 +-- truncate_limit: 100 +-- >= operator test +SELECT COUNT(*) FROM guid1 WHERE guid_field >= '22222222-2222-2222-2222-222222222222' +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="guid_field" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 WHERE guid_field >= '22222222-2222-2222-2222-222222222222'" +== 023 +-- truncate_limit: 100 +-- btree and hash index creation test +CREATE INDEX guid1_btree ON guid1 USING BTREE (guid_field) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX guid1_btree ON guid1 USING btree (guid_field)" +== 024 +-- truncate_limit: 100 +CREATE INDEX guid1_hash ON guid1 USING HASH (guid_field) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX guid1_hash ON guid1 USING hash (guid_field)" +== 025 +-- truncate_limit: 100 +-- unique index test +CREATE UNIQUE INDEX guid1_unique_BTREE ON guid1 USING BTREE (guid_field) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX guid1_unique_btree ON guid1 USING btree (guid_field)" +== 026 +-- truncate_limit: 100 +-- should fail +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('11111111-1111-1111-1111-111111111111')" +== 027 +-- truncate_limit: 100 +-- check to see whether the new indexes are actually there +SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="relkind" +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM pg_class WHERE relkind = 'i' AND relname LIKE 'guid%'" +== 028 +-- truncate_limit: 100 +-- populating the test tables with additional records +INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444') +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES ('44444444-4444-4444-4444-444444444444')" +== 029 +-- truncate_limit: 100 +INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111') +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid2 (guid_field) VALUES ('11111111-1111-1111-1111-111111111111')" +== 030 +-- truncate_limit: 100 +INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}') +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid2 (guid_field) VALUES ('{22222222-2222-2222-2222-222222222222}')" +== 031 +-- truncate_limit: 100 +INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e') +-- +TABLE: name="guid2" schema="" table="guid2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid2 (guid_field) VALUES ('3f3e3c3b3a3039383736353433a2313e')" +== 032 +-- truncate_limit: 100 +-- join test +SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +TABLE: name="guid2" schema="" table="guid2" ctx=Select +ALIAS: "g1"="guid1" +ALIAS: "g2"="guid2" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 g1 JOIN guid2 g2 ON g1.guid_field = g2.guid_field" +== 033 +-- truncate_limit: 100 +SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE g2.guid_field IS NULL +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +TABLE: name="guid2" schema="" table="guid2" ctx=Select +ALIAS: "g1"="guid1" +ALIAS: "g2"="guid2" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="g2" column="guid_field" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE ..." +== 034 +-- truncate_limit: 100 +-- generation test +TRUNCATE guid1 +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE guid1" +== 035 +-- truncate_limit: 100 +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid())" +== 036 +-- truncate_limit: 100 +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()) +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DML +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid())" +== 037 +-- truncate_limit: 100 +SELECT count(DISTINCT guid_field) FROM guid1 +-- +TABLE: name="guid1" schema="" table="guid1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(DISTINCT guid_field) FROM guid1" +== 038 +-- truncate_limit: 100 +-- extract functions + +-- version +SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111') +-- +FUNCTION: name="uuid_extract_version" function="uuid_extract_version" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111')" +== 039 +-- truncate_limit: 100 +-- 5 +SELECT uuid_extract_version(gen_random_uuid()) +-- +FUNCTION: name="uuid_extract_version" function="uuid_extract_version" schema="" ctx=Call +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT uuid_extract_version(gen_random_uuid())" +== 040 +-- truncate_limit: 100 +-- 4 +SELECT uuid_extract_version('11111111-1111-1111-1111-111111111111') +-- +FUNCTION: name="uuid_extract_version" function="uuid_extract_version" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT uuid_extract_version('11111111-1111-1111-1111-111111111111')" +== 041 +-- truncate_limit: 100 +-- null + +-- timestamp +SELECT uuid_extract_timestamp('C232AB00-9414-11EC-B3C8-9F6BDECED846') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00' +-- +FUNCTION: name="uuid_extract_timestamp" function="uuid_extract_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 042 +-- truncate_limit: 100 +-- RFC 4122bis test vector +SELECT uuid_extract_timestamp(gen_random_uuid()) +-- +FUNCTION: name="uuid_extract_timestamp" function="uuid_extract_timestamp" schema="" ctx=Call +FUNCTION: name="gen_random_uuid" function="gen_random_uuid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT uuid_extract_timestamp(gen_random_uuid())" +== 043 +-- truncate_limit: 100 +-- null +SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111') +-- +FUNCTION: name="uuid_extract_timestamp" function="uuid_extract_timestamp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111')" +== 044 +-- truncate_limit: 100 +-- null + + +-- clean up +DROP TABLE guid1, guid2 CASCADE +-- +TABLE: name="guid1" schema="" table="guid1" ctx=DDL +TABLE: name="guid2" schema="" table="guid2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE guid1, guid2 CASCADE" diff --git a/parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json b/parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json new file mode 100644 index 0000000..11c34e0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json @@ -0,0 +1,300 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/vacuum.test b/parser/testdata/summary_truncate/postgres_regress/vacuum.test new file mode 100644 index 0000000..4c1e9fe --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/vacuum.test @@ -0,0 +1,2263 @@ +== 001 +-- truncate_limit: 100 +|-- +-- VACUUM +|-- + +CREATE TABLE vactst (i INT) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vactst (i int)" +== 002 +-- truncate_limit: 100 +INSERT INTO vactst VALUES (1) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst VALUES (1)" +== 003 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 004 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 005 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 006 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 007 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 008 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 009 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 010 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 011 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 012 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 013 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 014 +-- truncate_limit: 100 +INSERT INTO vactst VALUES (0) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst VALUES (0)" +== 015 +-- truncate_limit: 100 +SELECT count(*) FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM vactst" +== 016 +-- truncate_limit: 100 +DELETE FROM vactst WHERE i != 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM vactst WHERE i <> 0" +== 017 +-- truncate_limit: 100 +SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vactst" +== 018 +-- truncate_limit: 100 +VACUUM FULL vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vactst" +== 019 +-- truncate_limit: 100 +UPDATE vactst SET i = i + 1 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE vactst SET i = i + 1" +== 020 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 021 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 022 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 023 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 024 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 025 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 026 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 027 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 028 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 029 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 030 +-- truncate_limit: 100 +INSERT INTO vactst SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT * FROM vactst" +== 031 +-- truncate_limit: 100 +INSERT INTO vactst VALUES (0) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst VALUES (0)" +== 032 +-- truncate_limit: 100 +SELECT count(*) FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM vactst" +== 033 +-- truncate_limit: 100 +DELETE FROM vactst WHERE i != 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM vactst WHERE i <> 0" +== 034 +-- truncate_limit: 100 +VACUUM (FULL) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vactst" +== 035 +-- truncate_limit: 100 +DELETE FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM vactst" +== 036 +-- truncate_limit: 100 +SELECT * FROM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vactst" +== 037 +-- truncate_limit: 100 +VACUUM (FULL, FREEZE) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL, FREEZE) vactst" +== 038 +-- truncate_limit: 100 +VACUUM (ANALYZE, FULL) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE, FULL) vactst" +== 039 +-- truncate_limit: 100 +CREATE TABLE vaccluster (i INT PRIMARY KEY) +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vaccluster (i int PRIMARY KEY)" +== 040 +-- truncate_limit: 100 +ALTER TABLE vaccluster CLUSTER ON vaccluster_pkey +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vaccluster CLUSTER ON vaccluster_pkey" +== 041 +-- truncate_limit: 100 +CLUSTER vaccluster +-- +STMT: ClusterStmt +TRUNCATED: "CLUSTER vaccluster" +== 042 +-- truncate_limit: 100 +CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL + AS 'ANALYZE pg_am' +-- +FUNCTION: name="do_analyze" function="do_analyze" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION do_analyze() RETURNS void VOLATILE LANGUAGE sql AS $$ANALYZE pg_am$$" +== 043 +-- truncate_limit: 100 +CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL + AS 'SELECT $1 FROM public.do_analyze()' +-- +FUNCTION: name="wrap_do_analyze" function="wrap_do_analyze" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION wrap_do_analyze(c int) RETURNS int IMMUTABLE LANGUAGE sql AS $$SELECT $1 FROM pub..." +== 044 +-- truncate_limit: 100 +CREATE INDEX ON vaccluster(wrap_do_analyze(i)) +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +FUNCTION: name="wrap_do_analyze" function="wrap_do_analyze" schema="" ctx=Call +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON vaccluster USING btree (wrap_do_analyze(i))" +== 045 +-- truncate_limit: 100 +INSERT INTO vaccluster VALUES (1), (2) +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vaccluster VALUES (1), (2)" +== 046 +-- truncate_limit: 100 +ANALYZE vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vaccluster" +== 047 +-- truncate_limit: 100 +-- Test ANALYZE in transaction, where the transaction surrounding +-- analyze performed modifications. This tests for the bug at +-- https://postgr.es/m/c7988239-d42c-ddc4-41db-171b23b35e4f%40ssinger.info +-- (which hopefully is unlikely to be reintroduced), but also seems +-- independently worthwhile to cover. +INSERT INTO vactst SELECT generate_series(1, 300) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT generate_series(1, 300)" +== 048 +-- truncate_limit: 100 +DELETE FROM vactst WHERE i % 7 = 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM vactst WHERE (i % 7) = 0" +== 049 +-- truncate_limit: 100 +-- delete a few rows outside +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 050 +-- truncate_limit: 100 +INSERT INTO vactst SELECT generate_series(301, 400) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vactst SELECT generate_series(301, 400)" +== 051 +-- truncate_limit: 100 +DELETE FROM vactst WHERE i % 5 <> 0 +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM vactst WHERE (i % 5) <> 0" +== 052 +-- truncate_limit: 100 +-- delete a few rows inside +ANALYZE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst" +== 053 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 054 +-- truncate_limit: 100 +-- Test ANALYZE setting relhassubclass=f for non-partitioning inheritance +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 055 +-- truncate_limit: 100 +CREATE TABLE past_inh_parent () +-- +TABLE: name="past_inh_parent" schema="" table="past_inh_parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE past_inh_parent ()" +== 056 +-- truncate_limit: 100 +CREATE TABLE past_inh_child () INHERITS (past_inh_parent) +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE past_inh_child () INHERITS (past_inh_parent)" +== 057 +-- truncate_limit: 100 +INSERT INTO past_inh_child DEFAULT VALUES +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO past_inh_child DEFAULT VALUES" +== 058 +-- truncate_limit: 100 +INSERT INTO past_inh_child DEFAULT VALUES +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DML +STMT: InsertStmt +TRUNCATED: "INSERT INTO past_inh_child DEFAULT VALUES" +== 059 +-- truncate_limit: 100 +ANALYZE past_inh_parent +-- +TABLE: name="past_inh_parent" schema="" table="past_inh_parent" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE past_inh_parent" +== 060 +-- truncate_limit: 100 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltuples, relhassubclass FROM pg_class WHERE oid = 'past_inh_parent'::regclass" +== 061 +-- truncate_limit: 100 +DROP TABLE past_inh_child +-- +TABLE: name="past_inh_child" schema="" table="past_inh_child" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE past_inh_child" +== 062 +-- truncate_limit: 100 +ANALYZE past_inh_parent +-- +TABLE: name="past_inh_parent" schema="" table="past_inh_parent" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE past_inh_parent" +== 063 +-- truncate_limit: 100 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_parent'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltuples, relhassubclass FROM pg_class WHERE oid = 'past_inh_parent'::regclass" +== 064 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 065 +-- truncate_limit: 100 +-- Test ANALYZE setting relhassubclass=f for partitioning +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 066 +-- truncate_limit: 100 +CREATE TABLE past_parted (i int) PARTITION BY LIST(i) +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE past_parted (i int) PARTITION BY LIST (i)" +== 067 +-- truncate_limit: 100 +CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1) +-- +TABLE: name="past_part" schema="" table="past_part" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1)" +== 068 +-- truncate_limit: 100 +INSERT INTO past_parted VALUES (1),(1) +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO past_parted VALUES (1), (1)" +== 069 +-- truncate_limit: 100 +ANALYZE past_parted +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE past_parted" +== 070 +-- truncate_limit: 100 +DROP TABLE past_part +-- +TABLE: name="past_part" schema="" table="past_part" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE past_part" +== 071 +-- truncate_limit: 100 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_parted'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltuples, relhassubclass FROM pg_class WHERE oid = 'past_parted'::regclass" +== 072 +-- truncate_limit: 100 +ANALYZE past_parted +-- +TABLE: name="past_parted" schema="" table="past_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE past_parted" +== 073 +-- truncate_limit: 100 +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_parted'::regclass +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT reltuples, relhassubclass FROM pg_class WHERE oid = 'past_parted'::regclass" +== 074 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 075 +-- truncate_limit: 100 +VACUUM FULL pg_am +-- +TABLE: name="pg_am" schema="" table="pg_am" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) pg_am" +== 076 +-- truncate_limit: 100 +VACUUM FULL pg_class +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) pg_class" +== 077 +-- truncate_limit: 100 +VACUUM FULL pg_database +-- +TABLE: name="pg_database" schema="" table="pg_database" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) pg_database" +== 078 +-- truncate_limit: 100 +VACUUM FULL vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vaccluster" +== 079 +-- truncate_limit: 100 +VACUUM FULL vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vactst" +== 080 +-- truncate_limit: 100 +VACUUM (DISABLE_PAGE_SKIPPING) vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (DISABLE_PAGE_SKIPPING) vaccluster" +== 081 +-- truncate_limit: 100 +-- PARALLEL option +CREATE TABLE pvactst (i INT, a INT[], p POINT) with (autovacuum_enabled = off) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pvactst (i int, a int[], p point) WITH (autovacuum_enabled=off)" +== 082 +-- truncate_limit: 100 +INSERT INTO pvactst SELECT i, array[1,2,3], point(i, i+1) FROM generate_series(1,1000) i +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DML +FUNCTION: name="point" function="point" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pvactst SELECT i, ARRAY[1, 2, 3], point(i, i + 1) FROM generate_series(1, 1000) i" +== 083 +-- truncate_limit: 100 +CREATE INDEX btree_pvactst ON pvactst USING btree (i) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX btree_pvactst ON pvactst USING btree (i)" +== 084 +-- truncate_limit: 100 +CREATE INDEX hash_pvactst ON pvactst USING hash (i) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX hash_pvactst ON pvactst USING hash (i)" +== 085 +-- truncate_limit: 100 +CREATE INDEX brin_pvactst ON pvactst USING brin (i) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX brin_pvactst ON pvactst USING brin (i)" +== 086 +-- truncate_limit: 100 +CREATE INDEX gin_pvactst ON pvactst USING gin (a) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gin_pvactst ON pvactst USING gin (a)" +== 087 +-- truncate_limit: 100 +CREATE INDEX gist_pvactst ON pvactst USING gist (p) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX gist_pvactst ON pvactst USING gist (p)" +== 088 +-- truncate_limit: 100 +CREATE INDEX spgist_pvactst ON pvactst USING spgist (p) +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX spgist_pvactst ON pvactst USING spgist (p)" +== 089 +-- truncate_limit: 100 +CREATE TABLE pvactst2 (i INT) WITH (autovacuum_enabled = off) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE pvactst2 (i int) WITH (autovacuum_enabled=off)" +== 090 +-- truncate_limit: 100 +INSERT INTO pvactst2 SELECT generate_series(1, 1000) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO pvactst2 SELECT generate_series(1, 1000)" +== 091 +-- truncate_limit: 100 +CREATE INDEX ON pvactst2 (i) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON pvactst2 USING btree (i)" +== 092 +-- truncate_limit: 100 +CREATE INDEX ON pvactst2 (i) +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON pvactst2 USING btree (i)" +== 093 +-- truncate_limit: 100 +-- VACUUM invokes parallel index cleanup +SET min_parallel_index_scan_size to 0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_index_scan_size TO 0" +== 094 +-- truncate_limit: 100 +VACUUM (PARALLEL 2) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 2) pvactst" +== 095 +-- truncate_limit: 100 +-- VACUUM invokes parallel bulk-deletion +UPDATE pvactst SET i = i WHERE i < 1000 +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pvactst SET i = i WHERE i < 1000" +== 096 +-- truncate_limit: 100 +VACUUM (PARALLEL 2) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 2) pvactst" +== 097 +-- truncate_limit: 100 +UPDATE pvactst SET i = i WHERE i < 1000 +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE pvactst SET i = i WHERE i < 1000" +== 098 +-- truncate_limit: 100 +VACUUM (PARALLEL 0) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 0) pvactst" +== 099 +-- truncate_limit: 100 +-- disable parallel vacuum + +VACUUM (PARALLEL -1) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL -1) pvactst" +== 100 +-- truncate_limit: 100 +-- error +VACUUM (PARALLEL 2, INDEX_CLEANUP FALSE) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 2, INDEX_CLEANUP FALSE) pvactst" +== 101 +-- truncate_limit: 100 +VACUUM (PARALLEL 2, FULL TRUE) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 2, FULL TRUE) pvactst" +== 102 +-- truncate_limit: 100 +-- error, cannot use both PARALLEL and FULL +VACUUM (PARALLEL) pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL) pvactst" +== 103 +-- truncate_limit: 100 +-- error, cannot use PARALLEL option without parallel degree + +-- Test parallel vacuum using the minimum maintenance_work_mem with and without +-- dead tuples. +SET maintenance_work_mem TO 64 +-- +STMT: VariableSetStmt +TRUNCATED: "SET maintenance_work_mem TO 64" +== 104 +-- truncate_limit: 100 +VACUUM (PARALLEL 2) pvactst2 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 2) pvactst2" +== 105 +-- truncate_limit: 100 +DELETE FROM pvactst2 WHERE i < 1000 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM pvactst2 WHERE i < 1000" +== 106 +-- truncate_limit: 100 +VACUUM (PARALLEL 2) pvactst2 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 2) pvactst2" +== 107 +-- truncate_limit: 100 +RESET maintenance_work_mem +-- +STMT: VariableSetStmt +TRUNCATED: "RESET maintenance_work_mem" +== 108 +-- truncate_limit: 100 +-- Test different combinations of parallel and full options for temporary tables +CREATE TEMPORARY TABLE tmp (a int PRIMARY KEY) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tmp (a int PRIMARY KEY)" +== 109 +-- truncate_limit: 100 +CREATE INDEX tmp_idx1 ON tmp (a) +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX tmp_idx1 ON tmp USING btree (a)" +== 110 +-- truncate_limit: 100 +VACUUM (PARALLEL 1, FULL FALSE) tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 1, FULL FALSE) tmp" +== 111 +-- truncate_limit: 100 +-- parallel vacuum disabled for temp tables +VACUUM (PARALLEL 0, FULL TRUE) tmp +-- +TABLE: name="tmp" schema="" table="tmp" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 0, FULL TRUE) tmp" +== 112 +-- truncate_limit: 100 +-- can specify parallel disabled (even though that's implied by FULL) +RESET min_parallel_index_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_index_scan_size" +== 113 +-- truncate_limit: 100 +DROP TABLE pvactst +-- +TABLE: name="pvactst" schema="" table="pvactst" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pvactst" +== 114 +-- truncate_limit: 100 +DROP TABLE pvactst2 +-- +TABLE: name="pvactst2" schema="" table="pvactst2" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE pvactst2" +== 115 +-- truncate_limit: 100 +-- INDEX_CLEANUP option +CREATE TABLE no_index_cleanup (i INT PRIMARY KEY, t TEXT) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE no_index_cleanup (i int PRIMARY KEY, t text)" +== 116 +-- truncate_limit: 100 +-- Use uncompressed data stored in toast. +CREATE INDEX no_index_cleanup_idx ON no_index_cleanup(t) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX no_index_cleanup_idx ON no_index_cleanup USING btree (t)" +== 117 +-- truncate_limit: 100 +ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE EXTERNAL +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE external" +== 118 +-- truncate_limit: 100 +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(1,30), + repeat('1234567890',269)) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO no_index_cleanup (i, t) VALUES (generate_series(1, 30), repeat('1234567890', 269))" +== 119 +-- truncate_limit: 100 +-- index cleanup option is ignored if VACUUM FULL +VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup" +== 120 +-- truncate_limit: 100 +VACUUM (FULL TRUE) no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL TRUE) no_index_cleanup" +== 121 +-- truncate_limit: 100 +-- Toast inherits the value from its parent table. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup=false)" +== 122 +-- truncate_limit: 100 +DELETE FROM no_index_cleanup WHERE i < 15 +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM no_index_cleanup WHERE i < 15" +== 123 +-- truncate_limit: 100 +-- Nothing is cleaned up. +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM no_index_cleanup" +== 124 +-- truncate_limit: 100 +-- Both parent relation and toast are cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup=true)" +== 125 +-- truncate_limit: 100 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM no_index_cleanup" +== 126 +-- truncate_limit: 100 +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = auto) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup=auto)" +== 127 +-- truncate_limit: 100 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM no_index_cleanup" +== 128 +-- truncate_limit: 100 +-- Parameter is set for both the parent table and its toast relation. +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), + repeat('1234567890',269)) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="repeat" function="repeat" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO no_index_cleanup (i, t) VALUES (generate_series(31, 60), repeat('1234567890', 269))" +== 129 +-- truncate_limit: 100 +DELETE FROM no_index_cleanup WHERE i < 45 +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM no_index_cleanup WHERE i < 45" +== 130 +-- truncate_limit: 100 +-- Only toast index is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, + toast.vacuum_index_cleanup = yes) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup=off, toast.vacuum_index_cleanup=yes)" +== 131 +-- truncate_limit: 100 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM no_index_cleanup" +== 132 +-- truncate_limit: 100 +-- Only parent is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, + toast.vacuum_index_cleanup = false) +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup=true, toast.vacuum_index_cleanup=false)" +== 133 +-- truncate_limit: 100 +VACUUM no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM no_index_cleanup" +== 134 +-- truncate_limit: 100 +-- Test some extra relations. +VACUUM (INDEX_CLEANUP FALSE) vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (INDEX_CLEANUP FALSE) vaccluster" +== 135 +-- truncate_limit: 100 +VACUUM (INDEX_CLEANUP AUTO) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (INDEX_CLEANUP auto) vactst" +== 136 +-- truncate_limit: 100 +-- index cleanup option is ignored if no indexes +VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster" +== 137 +-- truncate_limit: 100 +-- TRUNCATE option +CREATE TEMP TABLE vac_truncate_test(i INT NOT NULL, j text) + WITH (vacuum_truncate=true, autovacuum_enabled=false) +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE vac_truncate_test (i int NOT NULL, j text) WITH (vacuum_truncate=true, aut..." +== 138 +-- truncate_limit: 100 +INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL) +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL)" +== 139 +-- truncate_limit: 100 +VACUUM (TRUNCATE FALSE, DISABLE_PAGE_SKIPPING) vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (TRUNCATE FALSE, DISABLE_PAGE_SKIPPING) vac_truncate_test" +== 140 +-- truncate_limit: 100 +SELECT pg_relation_size('vac_truncate_test') > 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_relation_size('vac_truncate_test') > 0" +== 141 +-- truncate_limit: 100 +VACUUM (DISABLE_PAGE_SKIPPING) vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (DISABLE_PAGE_SKIPPING) vac_truncate_test" +== 142 +-- truncate_limit: 100 +SELECT pg_relation_size('vac_truncate_test') = 0 +-- +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_relation_size('vac_truncate_test') = 0" +== 143 +-- truncate_limit: 100 +VACUUM (TRUNCATE FALSE, FULL TRUE) vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (TRUNCATE FALSE, FULL TRUE) vac_truncate_test" +== 144 +-- truncate_limit: 100 +DROP TABLE vac_truncate_test +-- +TABLE: name="vac_truncate_test" schema="" table="vac_truncate_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vac_truncate_test" +== 145 +-- truncate_limit: 100 +-- partitioned table +CREATE TABLE vacparted (a int, b char) PARTITION BY LIST (a) +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacparted (a int, b char(1)) PARTITION BY LIST (a)" +== 146 +-- truncate_limit: 100 +CREATE TABLE vacparted1 PARTITION OF vacparted FOR VALUES IN (1) +-- +TABLE: name="vacparted1" schema="" table="vacparted1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacparted1 PARTITION OF vacparted FOR VALUES IN (1)" +== 147 +-- truncate_limit: 100 +INSERT INTO vacparted VALUES (1, 'a') +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vacparted VALUES (1, 'a')" +== 148 +-- truncate_limit: 100 +UPDATE vacparted SET b = 'b' +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DML +STMT: UpdateStmt +TRUNCATED: "UPDATE vacparted SET b = 'b'" +== 149 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacparted" +== 150 +-- truncate_limit: 100 +VACUUM (FULL) vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vacparted" +== 151 +-- truncate_limit: 100 +VACUUM (FREEZE) vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FREEZE) vacparted" +== 152 +-- truncate_limit: 100 +-- check behavior with duplicate column mentions +VACUUM ANALYZE vacparted(a,b,a) +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacparted(a, b, a)" +== 153 +-- truncate_limit: 100 +ANALYZE vacparted(a,b,b) +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacparted(a, b, b)" +== 154 +-- truncate_limit: 100 +-- partitioned table with index +CREATE TABLE vacparted_i (a int primary key, b varchar(100)) + PARTITION BY HASH (a) +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacparted_i (a int PRIMARY KEY, b varchar(100)) PARTITION BY HASH (a)" +== 155 +-- truncate_limit: 100 +CREATE TABLE vacparted_i1 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 0) +-- +TABLE: name="vacparted_i1" schema="" table="vacparted_i1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacparted_i1 PARTITION OF vacparted_i FOR VALUES WITH (MODULUS 2, REMAINDER 0)" +== 156 +-- truncate_limit: 100 +CREATE TABLE vacparted_i2 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 1) +-- +TABLE: name="vacparted_i2" schema="" table="vacparted_i2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacparted_i2 PARTITION OF vacparted_i FOR VALUES WITH (MODULUS 2, REMAINDER 1)" +== 157 +-- truncate_limit: 100 +INSERT INTO vacparted_i SELECT i, 'test_'|| i from generate_series(1,10) i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vacparted_i SELECT i, 'test_' || i FROM generate_series(1, 10) i" +== 158 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacparted_i" +== 159 +-- truncate_limit: 100 +VACUUM (FULL) vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vacparted_i" +== 160 +-- truncate_limit: 100 +VACUUM (FREEZE) vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FREEZE) vacparted_i" +== 161 +-- truncate_limit: 100 +SELECT relname, relhasindex FROM pg_class + WHERE relname LIKE 'vacparted_i%' AND relkind IN ('p','r') + ORDER BY relname +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +FILTER: schema="" table="" column="relkind" +STMT: SelectStmt +TRUNCATED: "SELECT relname, relhasindex FROM pg_class WHERE ... ORDER BY relname" +== 162 +-- truncate_limit: 100 +DROP TABLE vacparted_i +-- +TABLE: name="vacparted_i" schema="" table="vacparted_i" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vacparted_i" +== 163 +-- truncate_limit: 100 +-- multiple tables specified +VACUUM vaccluster, vactst +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vaccluster, vactst" +== 164 +-- truncate_limit: 100 +VACUUM vacparted, does_not_exist +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacparted, does_not_exist" +== 165 +-- truncate_limit: 100 +VACUUM (FREEZE) vacparted, vaccluster, vactst +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FREEZE) vacparted, vaccluster, vactst" +== 166 +-- truncate_limit: 100 +VACUUM (FREEZE) does_not_exist, vaccluster +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FREEZE) does_not_exist, vaccluster" +== 167 +-- truncate_limit: 100 +VACUUM ANALYZE vactst, vacparted (a) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vactst, vacparted(a)" +== 168 +-- truncate_limit: 100 +VACUUM ANALYZE vactst (does_not_exist), vacparted (b) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vactst(does_not_exist), vacparted(b)" +== 169 +-- truncate_limit: 100 +VACUUM FULL vacparted, vactst +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vacparted, vactst" +== 170 +-- truncate_limit: 100 +VACUUM FULL vactst, vacparted (a, b), vaccluster (i) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (FULL) vactst, vacparted(a, b), vaccluster(i)" +== 171 +-- truncate_limit: 100 +ANALYZE vactst, vacparted +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst, vacparted" +== 172 +-- truncate_limit: 100 +ANALYZE vacparted (b), vactst +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacparted(b), vactst" +== 173 +-- truncate_limit: 100 +ANALYZE vactst, does_not_exist, vacparted +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst, does_not_exist, vacparted" +== 174 +-- truncate_limit: 100 +ANALYZE vactst (i), vacparted (does_not_exist) +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst(i), vacparted(does_not_exist)" +== 175 +-- truncate_limit: 100 +ANALYZE vactst, vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst, vactst" +== 176 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 177 +-- truncate_limit: 100 +-- ANALYZE behaves differently inside a transaction block +ANALYZE vactst, vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst, vactst" +== 178 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 179 +-- truncate_limit: 100 +-- parenthesized syntax for ANALYZE +ANALYZE (VERBOSE) does_not_exist +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE (VERBOSE) does_not_exist" +== 180 +-- truncate_limit: 100 +ANALYZE (nonexistent-arg) does_not_exist +-- +ERROR: syntax error at or near "arg" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 181 +-- truncate_limit: 100 +ANALYZE (nonexistentarg) does_not_exit +-- +TABLE: name="does_not_exit" schema="" table="does_not_exit" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE (NONEXISTENTARG) does_not_exit" +== 182 +-- truncate_limit: 100 +-- ensure argument order independence, and that SKIP_LOCKED on non-existing +-- relation still errors out. Suppress WARNING messages caused by concurrent +-- autovacuums. +SET client_min_messages TO 'ERROR' +-- +STMT: VariableSetStmt +TRUNCATED: "SET client_min_messages TO \"ERROR\"" +== 183 +-- truncate_limit: 100 +ANALYZE (SKIP_LOCKED, VERBOSE) does_not_exist +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE (SKIP_LOCKED, VERBOSE) does_not_exist" +== 184 +-- truncate_limit: 100 +ANALYZE (VERBOSE, SKIP_LOCKED) does_not_exist +-- +TABLE: name="does_not_exist" schema="" table="does_not_exist" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE (VERBOSE, SKIP_LOCKED) does_not_exist" +== 185 +-- truncate_limit: 100 +-- SKIP_LOCKED option +VACUUM (SKIP_LOCKED) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (SKIP_LOCKED) vactst" +== 186 +-- truncate_limit: 100 +VACUUM (SKIP_LOCKED, FULL) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (SKIP_LOCKED, FULL) vactst" +== 187 +-- truncate_limit: 100 +ANALYZE (SKIP_LOCKED) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE (SKIP_LOCKED) vactst" +== 188 +-- truncate_limit: 100 +RESET client_min_messages +-- +STMT: VariableSetStmt +TRUNCATED: "RESET client_min_messages" +== 189 +-- truncate_limit: 100 +-- ensure VACUUM and ANALYZE don't have a problem with serializable +SET default_transaction_isolation = serializable +-- +STMT: VariableSetStmt +TRUNCATED: "SET default_transaction_isolation TO serializable" +== 190 +-- truncate_limit: 100 +VACUUM vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vactst" +== 191 +-- truncate_limit: 100 +ANALYZE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst" +== 192 +-- truncate_limit: 100 +RESET default_transaction_isolation +-- +STMT: VariableSetStmt +TRUNCATED: "RESET default_transaction_isolation" +== 193 +-- truncate_limit: 100 +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN ISOLATION LEVEL SERIALIZABLE" +== 194 +-- truncate_limit: 100 +ANALYZE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vactst" +== 195 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 196 +-- truncate_limit: 100 +-- PROCESS_TOAST option +CREATE TABLE vac_option_tab (a INT, t TEXT) +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vac_option_tab (a int, t text)" +== 197 +-- truncate_limit: 100 +INSERT INTO vac_option_tab SELECT a, 't' || a FROM generate_series(1, 10) AS a +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO vac_option_tab SELECT a, 't' || a FROM generate_series(1, 10) a" +== 198 +-- truncate_limit: 100 +ALTER TABLE vac_option_tab ALTER COLUMN t SET STORAGE EXTERNAL +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vac_option_tab ALTER COLUMN t SET STORAGE external" +== 199 +-- truncate_limit: 100 +-- Check the number of vacuums done on table vac_option_tab and on its +-- toast relation, to check that PROCESS_TOAST and PROCESS_MAIN work on +-- what they should. +CREATE VIEW vac_option_tab_counts AS + SELECT CASE WHEN c.relname IS NULL + THEN 'main' ELSE 'toast' END as rel, + s.vacuum_count + FROM pg_stat_all_tables s + LEFT JOIN pg_class c ON s.relid = c.reltoastrelid + WHERE c.relname = 'vac_option_tab' OR s.relname = 'vac_option_tab' + ORDER BY rel +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=DDL +TABLE: name="pg_stat_all_tables" schema="" table="pg_stat_all_tables" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "s"="pg_stat_all_tables" +FILTER: schema="" table="c" column="relname" +FILTER: schema="" table="s" column="relname" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW vac_option_tab_counts AS SELECT CASE WHEN c.relname IS NULL THEN 'main' ELSE 'toast' ..." +== 200 +-- truncate_limit: 100 +VACUUM (PROCESS_TOAST TRUE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PROCESS_TOAST TRUE) vac_option_tab" +== 201 +-- truncate_limit: 100 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vac_option_tab_counts" +== 202 +-- truncate_limit: 100 +VACUUM (PROCESS_TOAST FALSE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PROCESS_TOAST FALSE) vac_option_tab" +== 203 +-- truncate_limit: 100 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vac_option_tab_counts" +== 204 +-- truncate_limit: 100 +VACUUM (PROCESS_TOAST FALSE, FULL) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PROCESS_TOAST FALSE, FULL) vac_option_tab" +== 205 +-- truncate_limit: 100 +-- error + +-- PROCESS_MAIN option +-- Only the toast table is processed. +VACUUM (PROCESS_MAIN FALSE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PROCESS_MAIN FALSE) vac_option_tab" +== 206 +-- truncate_limit: 100 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vac_option_tab_counts" +== 207 +-- truncate_limit: 100 +-- Nothing is processed. +VACUUM (PROCESS_MAIN FALSE, PROCESS_TOAST FALSE) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PROCESS_MAIN FALSE, PROCESS_TOAST FALSE) vac_option_tab" +== 208 +-- truncate_limit: 100 +SELECT * FROM vac_option_tab_counts +-- +TABLE: name="vac_option_tab_counts" schema="" table="vac_option_tab_counts" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vac_option_tab_counts" +== 209 +-- truncate_limit: 100 +-- Check if the filenodes nodes have been updated as wanted after FULL. +SELECT relfilenode AS main_filenode FROM pg_class + WHERE relname = 'vac_option_tab' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FILTER: schema="" table="" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT relfilenode AS main_filenode FROM pg_class WHERE relname = 'vac_option_tab'" +== 210 +-- truncate_limit: 100 +SELECT t.relfilenode AS toast_filenode FROM pg_class c, pg_class t + WHERE c.reltoastrelid = t.oid AND c.relname = 'vac_option_tab' +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +ALIAS: "c"="pg_class" +ALIAS: "t"="pg_class" +FILTER: schema="" table="c" column="reltoastrelid" +FILTER: schema="" table="t" column="oid" +FILTER: schema="" table="c" column="relname" +STMT: SelectStmt +TRUNCATED: "SELECT t.relfilenode AS toast_filenode FROM pg_class c, pg_class t WHERE ..." +== 211 +-- truncate_limit: 100 +-- Only the toast relation is processed. +VACUUM (PROCESS_MAIN FALSE, FULL) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PROCESS_MAIN FALSE, FULL) vac_option_tab" +== 212 +-- truncate_limit: 100 +SELECT relfilenode = :main_filenode AS is_same_main_filenode + FROM pg_class WHERE relname = 'vac_option_tab' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 22 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 213 +-- truncate_limit: 100 +SELECT t.relfilenode = :toast_filenode AS is_same_toast_filenode + FROM pg_class c, pg_class t + WHERE c.reltoastrelid = t.oid AND c.relname = 'vac_option_tab' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 24 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 214 +-- truncate_limit: 100 +-- BUFFER_USAGE_LIMIT option +VACUUM (BUFFER_USAGE_LIMIT '512 kB') vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (BUFFER_USAGE_LIMIT \"512 kB\") vac_option_tab" +== 215 +-- truncate_limit: 100 +ANALYZE (BUFFER_USAGE_LIMIT '512 kB') vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE (BUFFER_USAGE_LIMIT \"512 kB\") vac_option_tab" +== 216 +-- truncate_limit: 100 +-- try disabling the buffer usage limit +VACUUM (BUFFER_USAGE_LIMIT 0) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (BUFFER_USAGE_LIMIT 0) vac_option_tab" +== 217 +-- truncate_limit: 100 +ANALYZE (BUFFER_USAGE_LIMIT 0) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE (BUFFER_USAGE_LIMIT 0) vac_option_tab" +== 218 +-- truncate_limit: 100 +-- value exceeds max size error +VACUUM (BUFFER_USAGE_LIMIT 16777220) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (BUFFER_USAGE_LIMIT 16777220) vac_option_tab" +== 219 +-- truncate_limit: 100 +-- value is less than min size error +VACUUM (BUFFER_USAGE_LIMIT 120) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (BUFFER_USAGE_LIMIT 120) vac_option_tab" +== 220 +-- truncate_limit: 100 +-- integer overflow error +VACUUM (BUFFER_USAGE_LIMIT 10000000000) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (BUFFER_USAGE_LIMIT 10000000000) vac_option_tab" +== 221 +-- truncate_limit: 100 +-- incompatible with VACUUM FULL error +VACUUM (BUFFER_USAGE_LIMIT '512 kB', FULL) vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (BUFFER_USAGE_LIMIT \"512 kB\", FULL) vac_option_tab" +== 222 +-- truncate_limit: 100 +-- SKIP_DATABASE_STATS option +VACUUM (SKIP_DATABASE_STATS) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (SKIP_DATABASE_STATS) vactst" +== 223 +-- truncate_limit: 100 +-- ONLY_DATABASE_STATS option +VACUUM (ONLY_DATABASE_STATS) +-- +STMT: VacuumStmt +TRUNCATED: "VACUUM (ONLY_DATABASE_STATS)" +== 224 +-- truncate_limit: 100 +VACUUM (ONLY_DATABASE_STATS) vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ONLY_DATABASE_STATS) vactst" +== 225 +-- truncate_limit: 100 +-- error + +DROP VIEW vac_option_tab_counts +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW vac_option_tab_counts" +== 226 +-- truncate_limit: 100 +DROP TABLE vac_option_tab +-- +TABLE: name="vac_option_tab" schema="" table="vac_option_tab" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vac_option_tab" +== 227 +-- truncate_limit: 100 +DROP TABLE vaccluster +-- +TABLE: name="vaccluster" schema="" table="vaccluster" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vaccluster" +== 228 +-- truncate_limit: 100 +DROP TABLE vactst +-- +TABLE: name="vactst" schema="" table="vactst" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vactst" +== 229 +-- truncate_limit: 100 +DROP TABLE vacparted +-- +TABLE: name="vacparted" schema="" table="vacparted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vacparted" +== 230 +-- truncate_limit: 100 +DROP TABLE no_index_cleanup +-- +TABLE: name="no_index_cleanup" schema="" table="no_index_cleanup" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE no_index_cleanup" +== 231 +-- truncate_limit: 100 +-- relation ownership, WARNING logs generated as all are skipped. +CREATE TABLE vacowned (a int) +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacowned (a int)" +== 232 +-- truncate_limit: 100 +CREATE TABLE vacowned_parted (a int) PARTITION BY LIST (a) +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacowned_parted (a int) PARTITION BY LIST (a)" +== 233 +-- truncate_limit: 100 +CREATE TABLE vacowned_part1 PARTITION OF vacowned_parted FOR VALUES IN (1) +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacowned_part1 PARTITION OF vacowned_parted FOR VALUES IN (1)" +== 234 +-- truncate_limit: 100 +CREATE TABLE vacowned_part2 PARTITION OF vacowned_parted FOR VALUES IN (2) +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE vacowned_part2 PARTITION OF vacowned_parted FOR VALUES IN (2)" +== 235 +-- truncate_limit: 100 +CREATE ROLE regress_vacuum +-- +STMT: CreateRoleStmt +TRUNCATED: "CREATE ROLE regress_vacuum" +== 236 +-- truncate_limit: 100 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_vacuum" +== 237 +-- truncate_limit: 100 +-- Simple table +VACUUM vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned" +== 238 +-- truncate_limit: 100 +ANALYZE vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned" +== 239 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned" +== 240 +-- truncate_limit: 100 +-- Catalog +VACUUM pg_catalog.pg_class +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM pg_catalog.pg_class" +== 241 +-- truncate_limit: 100 +ANALYZE pg_catalog.pg_class +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pg_catalog.pg_class" +== 242 +-- truncate_limit: 100 +VACUUM (ANALYZE) pg_catalog.pg_class +-- +TABLE: name="pg_catalog.pg_class" schema="pg_catalog" table="pg_class" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) pg_catalog.pg_class" +== 243 +-- truncate_limit: 100 +-- Shared catalog +VACUUM pg_catalog.pg_authid +-- +TABLE: name="pg_catalog.pg_authid" schema="pg_catalog" table="pg_authid" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM pg_catalog.pg_authid" +== 244 +-- truncate_limit: 100 +ANALYZE pg_catalog.pg_authid +-- +TABLE: name="pg_catalog.pg_authid" schema="pg_catalog" table="pg_authid" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE pg_catalog.pg_authid" +== 245 +-- truncate_limit: 100 +VACUUM (ANALYZE) pg_catalog.pg_authid +-- +TABLE: name="pg_catalog.pg_authid" schema="pg_catalog" table="pg_authid" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) pg_catalog.pg_authid" +== 246 +-- truncate_limit: 100 +-- Partitioned table and its partitions, nothing owned by other user. +-- Relations are not listed in a single command to test ownership +-- independently. +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_parted" +== 247 +-- truncate_limit: 100 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part1" +== 248 +-- truncate_limit: 100 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part2" +== 249 +-- truncate_limit: 100 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_parted" +== 250 +-- truncate_limit: 100 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part1" +== 251 +-- truncate_limit: 100 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part2" +== 252 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_parted" +== 253 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part1" +== 254 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part2" +== 255 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 256 +-- truncate_limit: 100 +-- Partitioned table and one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vacowned_parted OWNER TO regress_vacuum" +== 257 +-- truncate_limit: 100 +ALTER TABLE vacowned_part1 OWNER TO regress_vacuum +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vacowned_part1 OWNER TO regress_vacuum" +== 258 +-- truncate_limit: 100 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_vacuum" +== 259 +-- truncate_limit: 100 +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_parted" +== 260 +-- truncate_limit: 100 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part1" +== 261 +-- truncate_limit: 100 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part2" +== 262 +-- truncate_limit: 100 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_parted" +== 263 +-- truncate_limit: 100 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part1" +== 264 +-- truncate_limit: 100 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part2" +== 265 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_parted" +== 266 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part1" +== 267 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part2" +== 268 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 269 +-- truncate_limit: 100 +-- Only one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO CURRENT_USER +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vacowned_parted OWNER TO CURRENT_USER" +== 270 +-- truncate_limit: 100 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_vacuum" +== 271 +-- truncate_limit: 100 +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_parted" +== 272 +-- truncate_limit: 100 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part1" +== 273 +-- truncate_limit: 100 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part2" +== 274 +-- truncate_limit: 100 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_parted" +== 275 +-- truncate_limit: 100 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part1" +== 276 +-- truncate_limit: 100 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part2" +== 277 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_parted" +== 278 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part1" +== 279 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part2" +== 280 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 281 +-- truncate_limit: 100 +-- Only partitioned table owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vacowned_parted OWNER TO regress_vacuum" +== 282 +-- truncate_limit: 100 +ALTER TABLE vacowned_part1 OWNER TO CURRENT_USER +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE vacowned_part1 OWNER TO CURRENT_USER" +== 283 +-- truncate_limit: 100 +SET ROLE regress_vacuum +-- +STMT: VariableSetStmt +TRUNCATED: "SET role TO regress_vacuum" +== 284 +-- truncate_limit: 100 +VACUUM vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_parted" +== 285 +-- truncate_limit: 100 +VACUUM vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part1" +== 286 +-- truncate_limit: 100 +VACUUM vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM vacowned_part2" +== 287 +-- truncate_limit: 100 +ANALYZE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_parted" +== 288 +-- truncate_limit: 100 +ANALYZE vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part1" +== 289 +-- truncate_limit: 100 +ANALYZE vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "ANALYZE vacowned_part2" +== 290 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_parted" +== 291 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part1 +-- +TABLE: name="vacowned_part1" schema="" table="vacowned_part1" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part1" +== 292 +-- truncate_limit: 100 +VACUUM (ANALYZE) vacowned_part2 +-- +TABLE: name="vacowned_part2" schema="" table="vacowned_part2" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (ANALYZE) vacowned_part2" +== 293 +-- truncate_limit: 100 +RESET ROLE +-- +STMT: VariableSetStmt +TRUNCATED: "RESET role" +== 294 +-- truncate_limit: 100 +DROP TABLE vacowned +-- +TABLE: name="vacowned" schema="" table="vacowned" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vacowned" +== 295 +-- truncate_limit: 100 +DROP TABLE vacowned_parted +-- +TABLE: name="vacowned_parted" schema="" table="vacowned_parted" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE vacowned_parted" +== 296 +-- truncate_limit: 100 +DROP ROLE regress_vacuum +-- +STMT: DropRoleStmt +TRUNCATED: "DROP ROLE regress_vacuum" diff --git a/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json b/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json new file mode 100644 index 0000000..5a08d01 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json @@ -0,0 +1,18 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.test b/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.test new file mode 100644 index 0000000..d0be9a5 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.test @@ -0,0 +1,138 @@ +== 001 +-- truncate_limit: 100 +SET max_parallel_maintenance_workers TO 4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_maintenance_workers TO 4" +== 002 +-- truncate_limit: 100 +SET min_parallel_index_scan_size TO '128kB' +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_index_scan_size TO \"128kB\"" +== 003 +-- truncate_limit: 100 +-- Bug #17245: Make sure that we don't totally fail to VACUUM individual indexes that +-- happen to be below min_parallel_index_scan_size during parallel VACUUM: +CREATE TABLE parallel_vacuum_table (a int) WITH (autovacuum_enabled = off) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE parallel_vacuum_table (a int) WITH (autovacuum_enabled=off)" +== 004 +-- truncate_limit: 100 +INSERT INTO parallel_vacuum_table SELECT i from generate_series(1, 10000) i +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parallel_vacuum_table SELECT i FROM generate_series(1, 10000) i" +== 005 +-- truncate_limit: 100 +-- Parallel VACUUM will never be used unless there are at least two indexes +-- that exceed min_parallel_index_scan_size. Create two such indexes, and +-- a third index that is smaller than min_parallel_index_scan_size. +CREATE INDEX regular_sized_index ON parallel_vacuum_table(a) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX regular_sized_index ON parallel_vacuum_table USING btree (a)" +== 006 +-- truncate_limit: 100 +CREATE INDEX typically_sized_index ON parallel_vacuum_table(a) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX typically_sized_index ON parallel_vacuum_table USING btree (a)" +== 007 +-- truncate_limit: 100 +-- Note: vacuum_in_leader_small_index can apply deduplication, making it ~3x +-- smaller than the other indexes +CREATE INDEX vacuum_in_leader_small_index ON parallel_vacuum_table((1)) +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX vacuum_in_leader_small_index ON parallel_vacuum_table USING btree ((1))" +== 008 +-- truncate_limit: 100 +-- Verify (as best we can) that the cost model for parallel VACUUM +-- will make our VACUUM run in parallel, while always leaving it up to the +-- parallel leader to handle the vacuum_in_leader_small_index index: +SELECT EXISTS ( +SELECT 1 +FROM pg_class +WHERE oid = 'vacuum_in_leader_small_index'::regclass AND + pg_relation_size(oid) < + pg_size_bytes(current_setting('min_parallel_index_scan_size')) +) as leader_will_handle_small_index +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT EXISTS (SELECT 1 FROM pg_class WHERE ...) AS leader_will_handle_small_index" +== 009 +-- truncate_limit: 100 +SELECT count(*) as trigger_parallel_vacuum_nindexes +FROM pg_class +WHERE oid in ('regular_sized_index'::regclass, 'typically_sized_index'::regclass) AND + pg_relation_size(oid) >= + pg_size_bytes(current_setting('min_parallel_index_scan_size')) +-- +TABLE: name="pg_class" schema="" table="pg_class" ctx=Select +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_relation_size" function="pg_relation_size" schema="" ctx=Call +FUNCTION: name="pg_size_bytes" function="pg_size_bytes" schema="" ctx=Call +FUNCTION: name="current_setting" function="current_setting" schema="" ctx=Call +FILTER: schema="" table="" column="oid" +FILTER: schema="" table="" column="oid" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) AS trigger_parallel_vacuum_nindexes FROM pg_class WHERE ..." +== 010 +-- truncate_limit: 100 +-- Parallel VACUUM with B-Tree page deletions, ambulkdelete calls: +DELETE FROM parallel_vacuum_table +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DML +STMT: DeleteStmt +TRUNCATED: "DELETE FROM parallel_vacuum_table" +== 011 +-- truncate_limit: 100 +VACUUM (PARALLEL 4, INDEX_CLEANUP ON) parallel_vacuum_table +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DDL +STMT: VacuumStmt +TRUNCATED: "VACUUM (PARALLEL 4, INDEX_CLEANUP ON) parallel_vacuum_table" +== 012 +-- truncate_limit: 100 +-- Since vacuum_in_leader_small_index uses deduplication, we expect an +-- assertion failure with bug #17245 (in the absence of bugfix): +INSERT INTO parallel_vacuum_table SELECT i FROM generate_series(1, 10000) i +-- +TABLE: name="parallel_vacuum_table" schema="" table="parallel_vacuum_table" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parallel_vacuum_table SELECT i FROM generate_series(1, 10000) i" +== 013 +-- truncate_limit: 100 +RESET max_parallel_maintenance_workers +-- +STMT: VariableSetStmt +TRUNCATED: "RESET max_parallel_maintenance_workers" +== 014 +-- truncate_limit: 100 +RESET min_parallel_index_scan_size +-- +STMT: VariableSetStmt +TRUNCATED: "RESET min_parallel_index_scan_size" diff --git a/parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json b/parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json new file mode 100644 index 0000000..edb706f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json @@ -0,0 +1,26 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/varchar.test b/parser/testdata/summary_truncate/postgres_regress/varchar.test new file mode 100644 index 0000000..698eb12 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/varchar.test @@ -0,0 +1,207 @@ +== 001 +-- truncate_limit: 100 +|-- +-- VARCHAR +|-- + +|-- +-- Build a table for testing +-- (This temporarily hides the table created in test_setup.sql) +|-- + +CREATE TEMP TABLE VARCHAR_TBL(f1 varchar(1)) +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE varchar_tbl (f1 varchar(1))" +== 002 +-- truncate_limit: 100 +INSERT INTO VARCHAR_TBL (f1) VALUES ('a') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('a')" +== 003 +-- truncate_limit: 100 +INSERT INTO VARCHAR_TBL (f1) VALUES ('A') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('A')" +== 004 +-- truncate_limit: 100 +-- any of the following three input formats are acceptable +INSERT INTO VARCHAR_TBL (f1) VALUES ('1') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('1')" +== 005 +-- truncate_limit: 100 +INSERT INTO VARCHAR_TBL (f1) VALUES (2) +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES (2)" +== 006 +-- truncate_limit: 100 +INSERT INTO VARCHAR_TBL (f1) VALUES ('3') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('3')" +== 007 +-- truncate_limit: 100 +-- zero-length char +INSERT INTO VARCHAR_TBL (f1) VALUES ('') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('')" +== 008 +-- truncate_limit: 100 +-- try varchar's of greater than 1 length +INSERT INTO VARCHAR_TBL (f1) VALUES ('cd') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('cd')" +== 009 +-- truncate_limit: 100 +INSERT INTO VARCHAR_TBL (f1) VALUES ('c ') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('c ')" +== 010 +-- truncate_limit: 100 +SELECT * FROM VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM varchar_tbl" +== 011 +-- truncate_limit: 100 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 <> 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM varchar_tbl c WHERE c.f1 <> 'a'" +== 012 +-- truncate_limit: 100 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 = 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM varchar_tbl c WHERE c.f1 = 'a'" +== 013 +-- truncate_limit: 100 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 < 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM varchar_tbl c WHERE c.f1 < 'a'" +== 014 +-- truncate_limit: 100 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 <= 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM varchar_tbl c WHERE c.f1 <= 'a'" +== 015 +-- truncate_limit: 100 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 > 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM varchar_tbl c WHERE c.f1 > 'a'" +== 016 +-- truncate_limit: 100 +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 >= 'a' +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +ALIAS: "c"="varchar_tbl" +FILTER: schema="" table="c" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT c.* FROM varchar_tbl c WHERE c.f1 >= 'a'" +== 017 +-- truncate_limit: 100 +DROP TABLE VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE varchar_tbl" +== 018 +-- truncate_limit: 100 +|-- +-- Now test longer arrays of char +|-- +-- This varchar_tbl was already created and filled in test_setup.sql. +-- Here we just try to insert bad values. +|-- + +INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde') +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO varchar_tbl (f1) VALUES ('abcde')" +== 019 +-- truncate_limit: 100 +SELECT * FROM VARCHAR_TBL +-- +TABLE: name="varchar_tbl" schema="" table="varchar_tbl" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM varchar_tbl" +== 020 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('abcd ', 'varchar(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('abcd ', 'varchar(4)')" +== 021 +-- truncate_limit: 100 +SELECT pg_input_is_valid('abcde', 'varchar(4)') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('abcde', 'varchar(4)')" +== 022 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('abcde', 'varchar(4)') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('abcde', 'varchar(4)')" diff --git a/parser/testdata/summary_truncate/postgres_regress/window.metadata.json b/parser/testdata/summary_truncate/postgres_regress/window.metadata.json new file mode 100644 index 0000000..a1f4321 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/window.metadata.json @@ -0,0 +1,390 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/window.test b/parser/testdata/summary_truncate/postgres_regress/window.test new file mode 100644 index 0000000..ef3441a --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/window.test @@ -0,0 +1,4627 @@ +== 001 +-- truncate_limit: 100 +|-- +-- WINDOW FUNCTIONS +|-- + +CREATE TEMPORARY TABLE empsalary ( + depname varchar, + empno bigint, + salary int, + enroll_date date +) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE empsalary (depname varchar, empno bigint, salary int, enroll_date date)" +== 002 +-- truncate_limit: 100 +INSERT INTO empsalary VALUES +('develop', 10, 5200, '2007-08-01'), +('sales', 1, 5000, '2006-10-01'), +('personnel', 5, 3500, '2007-12-10'), +('sales', 4, 4800, '2007-08-08'), +('personnel', 2, 3900, '2006-12-23'), +('develop', 7, 4200, '2008-01-01'), +('develop', 9, 4500, '2008-01-01'), +('sales', 3, 4800, '2007-08-01'), +('develop', 8, 6000, '2006-10-01'), +('develop', 11, 5200, '2007-08-15') +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO empsalary VALUES (...)" +== 003 +-- truncate_limit: 100 +SELECT depname, empno, salary, sum(salary) OVER (PARTITION BY depname) FROM empsalary ORDER BY depname, salary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary ORDER BY depname, salary" +== 004 +-- truncate_limit: 100 +SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary) FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary) FROM empsalary" +== 005 +-- truncate_limit: 100 +-- with GROUP BY +SELECT four, ten, SUM(SUM(four)) OVER (PARTITION BY four), AVG(ten) FROM tenk1 +GROUP BY four, ten ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 GROUP BY four, ten ORDER BY four, ten" +== 006 +-- truncate_limit: 100 +SELECT depname, empno, salary, sum(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT depname, empno, salary, sum(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname)" +== 007 +-- truncate_limit: 100 +SELECT depname, empno, salary, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary) ORDER BY rank() OVER w +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary) ORDER BY rank() OVER w" +== 008 +-- truncate_limit: 100 +-- empty window specification +SELECT COUNT(*) OVER () FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) OVER () FROM tenk1 WHERE unique2 < 10" +== 009 +-- truncate_limit: 100 +SELECT COUNT(*) OVER w FROM tenk1 WHERE unique2 < 10 WINDOW w AS () +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) OVER w FROM tenk1 WHERE unique2 < 10 WINDOW w AS ()" +== 010 +-- truncate_limit: 100 +-- no window operation +SELECT four FROM tenk1 WHERE FALSE WINDOW w AS (PARTITION BY ten) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT four FROM tenk1 WHERE false WINDOW w AS (PARTITION BY ten)" +== 011 +-- truncate_limit: 100 +-- cumulative aggregate +SELECT sum(four) OVER (PARTITION BY ten ORDER BY unique2) AS sum_1, ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10" +== 012 +-- truncate_limit: 100 +SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10" +== 013 +-- truncate_limit: 100 +SELECT rank() OVER (PARTITION BY four ORDER BY ten) AS rank_1, ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10" +== 014 +-- truncate_limit: 100 +SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10" +== 015 +-- truncate_limit: 100 +SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10" +== 016 +-- truncate_limit: 100 +SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="cume_dist" function="cume_dist" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10" +== 017 +-- truncate_limit: 100 +SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10" +== 018 +-- truncate_limit: 100 +SELECT ntile(NULL) OVER (ORDER BY ten, four), ten, four FROM tenk1 LIMIT 2 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ntile(NULL) OVER (ORDER BY ten, four), ten, four FROM tenk1 LIMIT 2" +== 019 +-- truncate_limit: 100 +SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10" +== 020 +-- truncate_limit: 100 +SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10" +== 021 +-- truncate_limit: 100 +SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10" +== 022 +-- truncate_limit: 100 +SELECT lag(ten, four, 0.7) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten" +== 023 +-- truncate_limit: 100 +SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10" +== 024 +-- truncate_limit: 100 +SELECT lead(ten * 2, 1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10" +== 025 +-- truncate_limit: 100 +SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10" +== 026 +-- truncate_limit: 100 +SELECT lead(ten * 2, 1, -1.4) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten" +== 027 +-- truncate_limit: 100 +SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10" +== 028 +-- truncate_limit: 100 +-- last_value returns the last row of the frame, which is CURRENT ROW in ORDER BY window. +SELECT last_value(four) OVER (ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT last_value(four) OVER (ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10" +== 029 +-- truncate_limit: 100 +SELECT last_value(ten) OVER (PARTITION BY four), ten, four FROM + (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s + ORDER BY four, ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM tenk1 WHERE ... ORDER BY four, ten) s ORDER BY four, ten" +== 030 +-- truncate_limit: 100 +SELECT nth_value(ten, four + 1) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM tenk1 WHERE ... ORDER BY four, ten) s" +== 031 +-- truncate_limit: 100 +SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER (PARTITION BY two ORDER BY ten) AS wsum +FROM tenk1 GROUP BY ten, two +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 GROUP BY ten, two" +== 032 +-- truncate_limit: 100 +SELECT count(*) OVER (PARTITION BY four), four FROM (SELECT * FROM tenk1 WHERE two = 1)s WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="" column="two" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM tenk1 WHERE ...) s WHERE unique2 < 10" +== 033 +-- truncate_limit: 100 +SELECT (count(*) OVER (PARTITION BY four ORDER BY ten) + + sum(hundred) OVER (PARTITION BY four ORDER BY ten))::varchar AS cntsum + FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique2 < 10" +== 034 +-- truncate_limit: 100 +-- opexpr with different windows evaluation. +SELECT * FROM( + SELECT count(*) OVER (PARTITION BY four ORDER BY ten) + + sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS total, + count(*) OVER (PARTITION BY four ORDER BY ten) AS fourcount, + sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS twosum + FROM tenk1 +)sub +WHERE total <> fourcount + twosum +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="total" +FILTER: schema="" table="" column="fourcount" +FILTER: schema="" table="" column="twosum" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM tenk1) sub WHERE total <> (fourcount + twosum)" +== 035 +-- truncate_limit: 100 +SELECT avg(four) OVER (PARTITION BY four ORDER BY thousand / 100) FROM tenk1 WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT avg(four) OVER (PARTITION BY four ORDER BY thousand / 100) FROM tenk1 WHERE unique2 < 10" +== 036 +-- truncate_limit: 100 +SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER win AS wsum +FROM tenk1 GROUP BY ten, two WINDOW win AS (PARTITION BY two ORDER BY ten) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 GROUP BY ten, two WINDOW win AS (PARTITION BY two ORDER BY ten)" +== 037 +-- truncate_limit: 100 +-- more than one window with GROUP BY +SELECT sum(salary), + row_number() OVER (ORDER BY depname), + sum(sum(salary)) OVER (ORDER BY depname DESC) +FROM empsalary GROUP BY depname +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary GROUP BY depname" +== 038 +-- truncate_limit: 100 +-- identical windows with different names +SELECT sum(salary) OVER w1, count(*) OVER w2 +FROM empsalary WINDOW w1 AS (ORDER BY salary), w2 AS (ORDER BY salary) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary WINDOW w1 AS (ORDER BY salary), w2 AS (ORDER BY salary)" +== 039 +-- truncate_limit: 100 +-- subplan +SELECT lead(ten, (SELECT two FROM tenk1 WHERE s.unique2 = unique2)) OVER (PARTITION BY four ORDER BY ten) +FROM tenk1 s WHERE unique2 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "s"="tenk1" +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +FILTER: schema="" table="s" column="unique2" +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 s WHERE unique2 < 10" +== 040 +-- truncate_limit: 100 +-- empty table +SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 WHERE FALSE)s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 WHERE false) s" +== 041 +-- truncate_limit: 100 +-- mixture of agg/wfunc in the same window +SELECT sum(salary) OVER w, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC)" +== 042 +-- truncate_limit: 100 +-- strict aggs +SELECT empno, depname, salary, bonus, depadj, MIN(bonus) OVER (ORDER BY empno), MAX(depadj) OVER () FROM( + SELECT *, + CASE WHEN enroll_date < '2008-01-01' THEN 2008 - extract(YEAR FROM enroll_date) END * 500 AS bonus, + CASE WHEN + AVG(salary) OVER (PARTITION BY depname) < salary + THEN 200 END AS depadj FROM empsalary +)s +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +FUNCTION: name="pg_catalog.extract" function="extract" schema="pg_catalog" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM empsalary) s" +== 043 +-- truncate_limit: 100 +-- window function over ungrouped agg over empty row set (bug before 9.1) +SELECT SUM(COUNT(f1)) OVER () FROM int4_tbl WHERE f1=42 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +STMT: SelectStmt +TRUNCATED: "SELECT sum(count(f1)) OVER () FROM int4_tbl WHERE f1 = 42" +== 044 +-- truncate_limit: 100 +-- window function with ORDER BY an expression involving aggregates (9.1 bug) +select ten, + sum(unique1) + sum(unique2) as res, + rank() over (order by sum(unique1) + sum(unique2)) as rank +from tenk1 +group by ten order by ten +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 GROUP BY ten ORDER BY ten" +== 045 +-- truncate_limit: 100 +-- window and aggregate with GROUP BY expression (9.2 bug) +explain (costs off) +select first_value(max(x)) over (), y + from (select unique1 as x, ten+four as y from tenk1) ss + group by y +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT first_value(max(x)) OVER (), y FROM (SELECT unique1 AS x, ten + four A..." +== 046 +-- truncate_limit: 100 +-- window functions returning pass-by-ref values from different rows +select x, lag(x, 1) over (order by x), lead(x, 3) over (order by x) +from (select x::numeric as x from generate_series(1,10) x) +-- +FUNCTION: name="lag" function="lag" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM generate_series(1, 10) x)" +== 047 +-- truncate_limit: 100 +-- test non-default frame specifications +SELECT four, ten, + sum(ten) over (partition by four order by ten), + last_value(ten) over (partition by four order by ten) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT DISTINCT ... AS ... FROM tenk1) ss" +== 048 +-- truncate_limit: 100 +SELECT four, ten, + sum(ten) over (partition by four order by ten range between unbounded preceding and current row), + last_value(ten) over (partition by four order by ten range between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT DISTINCT ... AS ... FROM tenk1) ss" +== 049 +-- truncate_limit: 100 +SELECT four, ten, + sum(ten) over (partition by four order by ten range between unbounded preceding and unbounded following), + last_value(ten) over (partition by four order by ten range between unbounded preceding and unbounded following) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT DISTINCT ... AS ... FROM tenk1) ss" +== 050 +-- truncate_limit: 100 +SELECT four, ten/4 as two, + sum(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row), + last_value(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT DISTINCT ... AS ... FROM tenk1) ss" +== 051 +-- truncate_limit: 100 +SELECT four, ten/4 as two, + sum(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row), + last_value(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT DISTINCT ... AS ... FROM tenk1) ss" +== 052 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four range between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 053 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 054 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 2 preceding and 2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 055 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude no others), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 056 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 057 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 058 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 059 +-- truncate_limit: 100 +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 060 +-- truncate_limit: 100 +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 061 +-- truncate_limit: 100 +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 062 +-- truncate_limit: 100 +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 063 +-- truncate_limit: 100 +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 064 +-- truncate_limit: 100 +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 065 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 2 preceding and 1 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 066 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 1 following and 3 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 067 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between unbounded preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 068 +-- truncate_limit: 100 +SELECT sum(unique1) over (w range between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10 WINDOW w AS (ORDER BY four)" +== 069 +-- truncate_limit: 100 +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10 WINDOW w AS (ORDER BY four)" +== 070 +-- truncate_limit: 100 +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10 WINDOW w AS (ORDER BY four)" +== 071 +-- truncate_limit: 100 +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10 WINDOW w AS (ORDER BY four)" +== 072 +-- truncate_limit: 100 +SELECT first_value(unique1) over w, + nth_value(unique1, 2) over w AS nth_2, + last_value(unique1) over w, unique1, four +FROM tenk1 WHERE unique1 < 10 +WINDOW w AS (order by four range between current row and unbounded following) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE ... WINDOW w AS (ORDER BY four RANGE BETWEEN CURRENT ROW AND UNBOUNDE..." +== 073 +-- truncate_limit: 100 +SELECT sum(unique1) over + (order by unique1 + rows (SELECT unique1 FROM tenk1 ORDER BY unique1 LIMIT 1) + 1 PRECEDING), + unique1 +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 074 +-- truncate_limit: 100 +CREATE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following) as sum_rows + FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v_window AS SELECT i, sum(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND ..." +== 075 +-- truncate_limit: 100 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_window" +== 076 +-- truncate_limit: 100 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_window')" +== 077 +-- truncate_limit: 100 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude current row) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v_window AS SELECT i, sum(i) OVER (ORDER BY i ROWS BETWEEN 1 PRE..." +== 078 +-- truncate_limit: 100 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_window" +== 079 +-- truncate_limit: 100 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_window')" +== 080 +-- truncate_limit: 100 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude group) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v_window AS SELECT i, sum(i) OVER (ORDER BY i ROWS BETWEEN 1 PRE..." +== 081 +-- truncate_limit: 100 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_window" +== 082 +-- truncate_limit: 100 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_window')" +== 083 +-- truncate_limit: 100 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude ties) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v_window AS SELECT i, sum(i) OVER (ORDER BY i ROWS BETWEEN 1 PRE..." +== 084 +-- truncate_limit: 100 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_window" +== 085 +-- truncate_limit: 100 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_window')" +== 086 +-- truncate_limit: 100 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude no others) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v_window AS SELECT i, sum(i) OVER (ORDER BY i ROWS BETWEEN 1 PRE..." +== 087 +-- truncate_limit: 100 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_window" +== 088 +-- truncate_limit: 100 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_window')" +== 089 +-- truncate_limit: 100 +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i groups between 1 preceding and 1 following) as sum_rows FROM generate_series(1, 10) i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE TEMPORARY VIEW v_window AS SELECT i, sum(i) OVER (ORDER BY i GROUPS BETWEEN 1 P..." +== 090 +-- truncate_limit: 100 +SELECT * FROM v_window +-- +TABLE: name="v_window" schema="" table="v_window" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_window" +== 091 +-- truncate_limit: 100 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_window')" +== 092 +-- truncate_limit: 100 +DROP VIEW v_window +-- +STMT: DropStmt +TRUNCATED: "DROP VIEW v_window" +== 093 +-- truncate_limit: 100 +CREATE TEMP VIEW v_window AS + SELECT i, min(i) over (order by i range between '1 day' preceding and '10 days' following) as min_i + FROM generate_series(now(), now()+'100 days'::interval, '1 hour') i +-- +TABLE: name="v_window" schema="" table="v_window" ctx=DDL +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v_window AS SELECT i, min(i) OVER (ORDER BY i RANGE BETWEEN '1 day' PRECEDI..." +== 094 +-- truncate_limit: 100 +SELECT pg_get_viewdef('v_window') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_window')" +== 095 +-- truncate_limit: 100 +-- RANGE offset PRECEDING/FOLLOWING tests + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 096 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four desc range between 2::int8 preceding and 1::int2 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 097 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude no others), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 098 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 099 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 100 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 101 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 102 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 103 +-- truncate_limit: 100 +SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 104 +-- truncate_limit: 100 +SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following + exclude current row),unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 105 +-- truncate_limit: 100 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 106 +-- truncate_limit: 100 +select sum(salary) over (order by enroll_date desc range between '1 year'::interval preceding and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 107 +-- truncate_limit: 100 +select sum(salary) over (order by enroll_date desc range between '1 year'::interval following and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 108 +-- truncate_limit: 100 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude current row), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 109 +-- truncate_limit: 100 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude group), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 110 +-- truncate_limit: 100 +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 111 +-- truncate_limit: 100 +select first_value(salary) over(order by salary range between 1000 preceding and 1000 following), + lead(salary) over(order by salary range between 1000 preceding and 1000 following), + nth_value(salary, 1) over(order by salary range between 1000 preceding and 1000 following), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 112 +-- truncate_limit: 100 +select last_value(salary) over(order by salary range between 1000 preceding and 1000 following), + lag(salary) over(order by salary range between 1000 preceding and 1000 following), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 113 +-- truncate_limit: 100 +select first_value(salary) over(order by salary range between 1000 following and 3000 following + exclude current row), + lead(salary) over(order by salary range between 1000 following and 3000 following exclude ties), + nth_value(salary, 1) over(order by salary range between 1000 following and 3000 following + exclude ties), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 114 +-- truncate_limit: 100 +select last_value(salary) over(order by salary range between 1000 following and 3000 following + exclude group), + lag(salary) over(order by salary range between 1000 following and 3000 following exclude group), + salary from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 115 +-- truncate_limit: 100 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 116 +-- truncate_limit: 100 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 117 +-- truncate_limit: 100 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude group), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude group), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 118 +-- truncate_limit: 100 +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude current row), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude current row), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 119 +-- truncate_limit: 100 +-- RANGE offset PRECEDING/FOLLOWING with null values +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x asc nulls first range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM ((SELECT ... FROM generate_series(1, 5) x UNION ALL SELECT ...) UNION ALL SELECT ..." +== 120 +-- truncate_limit: 100 +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x asc nulls last range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM ((SELECT ... FROM generate_series(1, 5) x UNION ALL SELECT ...) UNION ALL SELECT ..." +== 121 +-- truncate_limit: 100 +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x desc nulls first range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM ((SELECT ... FROM generate_series(1, 5) x UNION ALL SELECT ...) UNION ALL SELECT ..." +== 122 +-- truncate_limit: 100 +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x desc nulls last range between 2 preceding and 2 following) +-- +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM ((SELECT ... FROM generate_series(1, 5) x UNION ALL SELECT ...) UNION ALL SELECT ..." +== 123 +-- truncate_limit: 100 +-- There is a syntactic ambiguity in the SQL standard. Since +-- UNBOUNDED is a non-reserved word, it could be the name of a +-- function parameter and be used as an expression. There is a +-- grammar hack to resolve such cases as the keyword. The following +-- tests record this behavior. + +CREATE FUNCTION unbounded_syntax_test1a(x int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +BEGIN ATOMIC + SELECT sum(unique1) over (rows between x preceding and x following), + unique1, four + FROM tenk1 WHERE unique1 < 10 +-- +ERROR: syntax error at end of input +CURSORPOS: 525 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 124 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 125 +-- truncate_limit: 100 +CREATE FUNCTION unbounded_syntax_test1b(x int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +AS $$ + SELECT sum(unique1) over (rows between x preceding and x following), + unique1, four + FROM tenk1 WHERE unique1 < 10; +$$ +-- +FUNCTION: name="unbounded_syntax_test1b" function="unbounded_syntax_test1b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION unbounded_syntax_test1b(x int) RETURNS TABLE (a int, b int, c int) LANGUAGE sql A..." +== 126 +-- truncate_limit: 100 +-- These will apply the argument to the window specification inside the function. +SELECT * FROM unbounded_syntax_test1a(2) +-- +FUNCTION: name="unbounded_syntax_test1a" function="unbounded_syntax_test1a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unbounded_syntax_test1a(2)" +== 127 +-- truncate_limit: 100 +SELECT * FROM unbounded_syntax_test1b(2) +-- +FUNCTION: name="unbounded_syntax_test1b" function="unbounded_syntax_test1b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unbounded_syntax_test1b(2)" +== 128 +-- truncate_limit: 100 +CREATE FUNCTION unbounded_syntax_test2a(unbounded int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +BEGIN ATOMIC + SELECT sum(unique1) over (rows between unbounded preceding and unbounded following), + unique1, four + FROM tenk1 WHERE unique1 < 10 +-- +ERROR: syntax error at end of input +CURSORPOS: 259 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 129 +-- truncate_limit: 100 +END +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 130 +-- truncate_limit: 100 +CREATE FUNCTION unbounded_syntax_test2b(unbounded int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +AS $$ + SELECT sum(unique1) over (rows between unbounded preceding and unbounded following), + unique1, four + FROM tenk1 WHERE unique1 < 10; +$$ +-- +FUNCTION: name="unbounded_syntax_test2b" function="unbounded_syntax_test2b" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION unbounded_syntax_test2b(unbounded int) RETURNS TABLE (a int, b int, c int) LANGUA..." +== 131 +-- truncate_limit: 100 +-- These will not apply the argument but instead treat UNBOUNDED as a keyword. +SELECT * FROM unbounded_syntax_test2a(2) +-- +FUNCTION: name="unbounded_syntax_test2a" function="unbounded_syntax_test2a" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unbounded_syntax_test2a(2)" +== 132 +-- truncate_limit: 100 +SELECT * FROM unbounded_syntax_test2b(2) +-- +FUNCTION: name="unbounded_syntax_test2b" function="unbounded_syntax_test2b" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM unbounded_syntax_test2b(2)" +== 133 +-- truncate_limit: 100 +DROP FUNCTION unbounded_syntax_test1a, unbounded_syntax_test1b, + unbounded_syntax_test2a, unbounded_syntax_test2b +-- +FUNCTION: name="unbounded_syntax_test1a" function="unbounded_syntax_test1a" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION unbounded_syntax_test1a, unbounded_syntax_test1b, unbounded_syntax_test2a, unbounde..." +== 134 +-- truncate_limit: 100 +-- Other tests with token UNBOUNDED in potentially problematic position +CREATE FUNCTION unbounded(x int) RETURNS int LANGUAGE SQL IMMUTABLE RETURN x +-- +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION unbounded(x int) RETURNS int LANGUAGE sql IMMUTABLE RETURN x" +== 135 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between 1 preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 136 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between unbounded(1) preceding and unbounded(1) following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=Call +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 137 +-- truncate_limit: 100 +SELECT sum(unique1) over (rows between unbounded.x preceding and unbounded.x following), + unique1, four +FROM tenk1, (values (1)) as unbounded(x) WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1, (VALUES (1)) unbounded(x) WHERE unique1 < 10" +== 138 +-- truncate_limit: 100 +DROP FUNCTION unbounded +-- +FUNCTION: name="unbounded" function="unbounded" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION unbounded" +== 139 +-- truncate_limit: 100 +-- Check overflow behavior for various integer sizes + +select x, last_value(x) over (order by x::smallint range between current row and 2147450884 following) +from generate_series(32764, 32766) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(32764, 32766) x" +== 140 +-- truncate_limit: 100 +select x, last_value(x) over (order by x::smallint desc range between current row and 2147450885 following) +from generate_series(-32766, -32764) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(-32766, -32764) x" +== 141 +-- truncate_limit: 100 +select x, last_value(x) over (order by x range between current row and 4 following) +from generate_series(2147483644, 2147483646) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(2147483644, 2147483646) x" +== 142 +-- truncate_limit: 100 +select x, last_value(x) over (order by x desc range between current row and 5 following) +from generate_series(-2147483646, -2147483644) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(-2147483646, -2147483644) x" +== 143 +-- truncate_limit: 100 +select x, last_value(x) over (order by x range between current row and 4 following) +from generate_series(9223372036854775804, 9223372036854775806) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(9223372036854775804, 9223372036854775806) x" +== 144 +-- truncate_limit: 100 +select x, last_value(x) over (order by x desc range between current row and 5 following) +from generate_series(-9223372036854775806, -9223372036854775804) x +-- +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(-9223372036854775806, -9223372036854775804) x" +== 145 +-- truncate_limit: 100 +-- Test in_range for other numeric datatypes + +create temp table numerics( + id int, + f_float4 float4, + f_float8 float8, + f_numeric numeric +) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE numerics (id int, f_float4 float4, f_float8 float8, f_numeric numeric)" +== 146 +-- truncate_limit: 100 +insert into numerics values +(0, '-infinity', '-infinity', '-infinity'), +(1, -3, -3, -3), +(2, -1, -1, -1), +(3, 0, 0, 0), +(4, 1.1, 1.1, 1.1), +(5, 1.12, 1.12, 1.12), +(6, 2, 2, 2), +(7, 100, 100, 100), +(8, 'infinity', 'infinity', 'infinity'), +(9, 'NaN', 'NaN', 'NaN') +-- +TABLE: name="numerics" schema="" table="numerics" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO numerics VALUES (...)" +== 147 +-- truncate_limit: 100 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1 preceding and 1 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float4 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)" +== 148 +-- truncate_limit: 100 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1 preceding and 1.1::float4 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float4 RANGE BETWEEN 1 PRECEDING AND (1.1)::floa..." +== 149 +-- truncate_limit: 100 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' preceding and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float4 RANGE BETWEEN 'inf' PRECEDING AND 'inf' F..." +== 150 +-- truncate_limit: 100 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' preceding and 'inf' preceding) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float4 RANGE BETWEEN 'inf' PRECEDING AND 'inf' P..." +== 151 +-- truncate_limit: 100 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' following and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float4 RANGE BETWEEN 'inf' FOLLOWING AND 'inf' F..." +== 152 +-- truncate_limit: 100 +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1.1 preceding and 'NaN' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float4 RANGE BETWEEN 1.1 PRECEDING AND 'NaN' FOL..." +== 153 +-- truncate_limit: 100 +-- error, NaN disallowed + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1 preceding and 1 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float8 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)" +== 154 +-- truncate_limit: 100 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1 preceding and 1.1::float8 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float8 RANGE BETWEEN 1 PRECEDING AND (1.1)::floa..." +== 155 +-- truncate_limit: 100 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' preceding and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float8 RANGE BETWEEN 'inf' PRECEDING AND 'inf' F..." +== 156 +-- truncate_limit: 100 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' preceding and 'inf' preceding) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float8 RANGE BETWEEN 'inf' PRECEDING AND 'inf' P..." +== 157 +-- truncate_limit: 100 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' following and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float8 RANGE BETWEEN 'inf' FOLLOWING AND 'inf' F..." +== 158 +-- truncate_limit: 100 +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1.1 preceding and 'NaN' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_float8 RANGE BETWEEN 1.1 PRECEDING AND 'NaN' FOL..." +== 159 +-- truncate_limit: 100 +-- error, NaN disallowed + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_numeric RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)" +== 160 +-- truncate_limit: 100 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1.1::numeric following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_numeric RANGE BETWEEN 1 PRECEDING AND (1.1)::num..." +== 161 +-- truncate_limit: 100 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1.1::float8 following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_numeric RANGE BETWEEN 1 PRECEDING AND (1.1)::flo..." +== 162 +-- truncate_limit: 100 +-- currently unsupported +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' preceding and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_numeric RANGE BETWEEN 'inf' PRECEDING AND 'inf' ..." +== 163 +-- truncate_limit: 100 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' preceding and 'inf' preceding) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_numeric RANGE BETWEEN 'inf' PRECEDING AND 'inf' ..." +== 164 +-- truncate_limit: 100 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' following and 'inf' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_numeric RANGE BETWEEN 'inf' FOLLOWING AND 'inf' ..." +== 165 +-- truncate_limit: 100 +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1.1 preceding and 'NaN' following) +-- +TABLE: name="numerics" schema="" table="numerics" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM numerics WINDOW w AS (ORDER BY f_numeric RANGE BETWEEN 1.1 PRECEDING AND 'NaN' FO..." +== 166 +-- truncate_limit: 100 +-- error, NaN disallowed + +-- Test in_range for other datetime datatypes + +create temp table datetimes( + id int, + f_time time, + f_timetz timetz, + f_interval interval, + f_timestamptz timestamptz, + f_timestamp timestamp +) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE datetimes (id int, f_time time, f_timetz timetz, f_interval interval, f_ti..." +== 167 +-- truncate_limit: 100 +insert into datetimes values +(0, '10:00', '10:00 BST', '-infinity', '-infinity', '-infinity'), +(1, '11:00', '11:00 BST', '1 year', '2000-10-19 10:23:54+01', '2000-10-19 10:23:54'), +(2, '12:00', '12:00 BST', '2 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'), +(3, '13:00', '13:00 BST', '3 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'), +(4, '14:00', '14:00 BST', '4 years', '2002-10-19 10:23:54+01', '2002-10-19 10:23:54'), +(5, '15:00', '15:00 BST', '5 years', '2003-10-19 10:23:54+01', '2003-10-19 10:23:54'), +(6, '15:00', '15:00 BST', '5 years', '2004-10-19 10:23:54+01', '2004-10-19 10:23:54'), +(7, '17:00', '17:00 BST', '7 years', '2005-10-19 10:23:54+01', '2005-10-19 10:23:54'), +(8, '18:00', '18:00 BST', '8 years', '2006-10-19 10:23:54+01', '2006-10-19 10:23:54'), +(9, '19:00', '19:00 BST', '9 years', '2007-10-19 10:23:54+01', '2007-10-19 10:23:54'), +(10, '20:00', '20:00 BST', '10 years', '2008-10-19 10:23:54+01', '2008-10-19 10:23:54'), +(11, '21:00', '21:00 BST', 'infinity', 'infinity', 'infinity') +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO datetimes VALUES (...)" +== 168 +-- truncate_limit: 100 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + '70 min'::interval preceding and '2 hours'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_time RANGE BETWEEN '70 min'::interval PRECEDING..." +== 169 +-- truncate_limit: 100 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time desc range between + '70 min' preceding and '2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_time DESC RANGE BETWEEN '70 min' PRECEDING AND ..." +== 170 +-- truncate_limit: 100 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time desc range between + '-70 min' preceding and '2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_time DESC RANGE BETWEEN '-70 min' PRECEDING AND..." +== 171 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_time RANGE BETWEEN 'infinity'::interval PRECEDI..." +== 172 +-- truncate_limit: 100 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_time RANGE BETWEEN 'infinity'::interval PRECEDI..." +== 173 +-- truncate_limit: 100 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_time RANGE BETWEEN 'infinity'::interval FOLLOWI..." +== 174 +-- truncate_limit: 100 +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_time RANGE BETWEEN '-infinity'::interval FOLLOW..." +== 175 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + '70 min'::interval preceding and '2 hours'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timetz RANGE BETWEEN '70 min'::interval PRECEDI..." +== 176 +-- truncate_limit: 100 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz desc range between + '70 min' preceding and '2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timetz DESC RANGE BETWEEN '70 min' PRECEDING AN..." +== 177 +-- truncate_limit: 100 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz desc range between + '70 min' preceding and '-2 hours' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timetz DESC RANGE BETWEEN '70 min' PRECEDING AN..." +== 178 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timetz RANGE BETWEEN 'infinity'::interval PRECE..." +== 179 +-- truncate_limit: 100 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timetz RANGE BETWEEN 'infinity'::interval PRECE..." +== 180 +-- truncate_limit: 100 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timetz RANGE BETWEEN 'infinity'::interval FOLLO..." +== 181 +-- truncate_limit: 100 +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval following and + '-infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timetz RANGE BETWEEN 'infinity'::interval FOLLO..." +== 182 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + '1 year'::interval preceding and '1 year'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_interval RANGE BETWEEN '1 year'::interval PRECE..." +== 183 +-- truncate_limit: 100 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval desc range between + '1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_interval DESC RANGE BETWEEN '1 year' PRECEDING ..." +== 184 +-- truncate_limit: 100 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval desc range between + '-1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_interval DESC RANGE BETWEEN '-1 year' PRECEDING..." +== 185 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_interval RANGE BETWEEN 'infinity'::interval PRE..." +== 186 +-- truncate_limit: 100 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_interval RANGE BETWEEN 'infinity'::interval PRE..." +== 187 +-- truncate_limit: 100 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_interval RANGE BETWEEN 'infinity'::interval FOL..." +== 188 +-- truncate_limit: 100 +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_interval RANGE BETWEEN '-infinity'::interval FO..." +== 189 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + '1 year'::interval preceding and '1 year'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamptz RANGE BETWEEN '1 year'::interval PR..." +== 190 +-- truncate_limit: 100 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz desc range between + '1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamptz DESC RANGE BETWEEN '1 year' PRECEDI..." +== 191 +-- truncate_limit: 100 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz desc range between + '1 year' preceding and '-1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamptz DESC RANGE BETWEEN '1 year' PRECEDI..." +== 192 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamptz RANGE BETWEEN 'infinity'::interval ..." +== 193 +-- truncate_limit: 100 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamptz RANGE BETWEEN 'infinity'::interval ..." +== 194 +-- truncate_limit: 100 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamptz RANGE BETWEEN 'infinity'::interval ..." +== 195 +-- truncate_limit: 100 +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamptz RANGE BETWEEN '-infinity'::interval..." +== 196 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + '1 year'::interval preceding and '1 year'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamp RANGE BETWEEN '1 year'::interval PREC..." +== 197 +-- truncate_limit: 100 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp desc range between + '1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamp DESC RANGE BETWEEN '1 year' PRECEDING..." +== 198 +-- truncate_limit: 100 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp desc range between + '-1 year' preceding and '1 year' following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamp DESC RANGE BETWEEN '-1 year' PRECEDIN..." +== 199 +-- truncate_limit: 100 +-- error, negative offset disallowed + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval preceding and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamp RANGE BETWEEN 'infinity'::interval PR..." +== 200 +-- truncate_limit: 100 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval preceding and 'infinity'::interval preceding) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamp RANGE BETWEEN 'infinity'::interval PR..." +== 201 +-- truncate_limit: 100 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval following and 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamp RANGE BETWEEN 'infinity'::interval FO..." +== 202 +-- truncate_limit: 100 +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + '-infinity'::interval following and + 'infinity'::interval following) +-- +TABLE: name="datetimes" schema="" table="datetimes" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM datetimes WINDOW w AS (ORDER BY f_timestamp RANGE BETWEEN '-infinity'::interval F..." +== 203 +-- truncate_limit: 100 +-- error, negative offset disallowed + +-- RANGE offset PRECEDING/FOLLOWING error cases +select sum(salary) over (order by enroll_date, salary range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 204 +-- truncate_limit: 100 +select sum(salary) over (range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 205 +-- truncate_limit: 100 +select sum(salary) over (order by depname range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 206 +-- truncate_limit: 100 +select max(enroll_date) over (order by enroll_date range between 1 preceding and 2 following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 207 +-- truncate_limit: 100 +select max(enroll_date) over (order by salary range between -1 preceding and 2 following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 208 +-- truncate_limit: 100 +select max(enroll_date) over (order by salary range between 1 preceding and -2 following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 209 +-- truncate_limit: 100 +select max(enroll_date) over (order by salary range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 210 +-- truncate_limit: 100 +select max(enroll_date) over (order by enroll_date range between '1 year'::interval preceding and '-2 years'::interval following + exclude ties), salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 211 +-- truncate_limit: 100 +-- GROUPS tests + +SELECT sum(unique1) over (order by four groups between unbounded preceding and current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 212 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between unbounded preceding and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 213 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 214 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 1 preceding and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 215 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 1 following and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 216 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between unbounded preceding and 2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 217 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 218 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 219 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 0 preceding and 0 following), + unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 220 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude current row), unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 221 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude group), unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 222 +-- truncate_limit: 100 +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude ties), unique1, four +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 223 +-- truncate_limit: 100 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following),unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 224 +-- truncate_limit: 100 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude current row), unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 225 +-- truncate_limit: 100 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude group), unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 226 +-- truncate_limit: 100 +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude ties), unique1, four, ten +FROM tenk1 WHERE unique1 < 10 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM tenk1 WHERE unique1 < 10" +== 227 +-- truncate_limit: 100 +select first_value(salary) over(order by enroll_date groups between 1 preceding and 1 following), + lead(salary) over(order by enroll_date groups between 1 preceding and 1 following), + nth_value(salary, 1) over(order by enroll_date groups between 1 preceding and 1 following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 228 +-- truncate_limit: 100 +select last_value(salary) over(order by enroll_date groups between 1 preceding and 1 following), + lag(salary) over(order by enroll_date groups between 1 preceding and 1 following), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 229 +-- truncate_limit: 100 +select first_value(salary) over(order by enroll_date groups between 1 following and 3 following + exclude current row), + lead(salary) over(order by enroll_date groups between 1 following and 3 following exclude ties), + nth_value(salary, 1) over(order by enroll_date groups between 1 following and 3 following + exclude ties), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="first_value" function="first_value" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 230 +-- truncate_limit: 100 +select last_value(salary) over(order by enroll_date groups between 1 following and 3 following + exclude group), + lag(salary) over(order by enroll_date groups between 1 following and 3 following exclude group), + salary, enroll_date from empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="last_value" function="last_value" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 231 +-- truncate_limit: 100 +-- Show differences in offset interpretation between ROWS, RANGE, and GROUPS +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte(x) AS (...) SELECT ... FROM cte WINDOW w AS (ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 F..." +== 232 +-- truncate_limit: 100 +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x range between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte(x) AS (...) SELECT ... FROM cte WINDOW w AS (ORDER BY x RANGE BETWEEN 1 PRECEDING AND 1 ..." +== 233 +-- truncate_limit: 100 +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte(x) AS (...) SELECT ... FROM cte WINDOW w AS (ORDER BY x GROUPS BETWEEN 1 PRECEDING AND 1..." +== 234 +-- truncate_limit: 100 +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte(x) AS (...) SELECT ... FROM cte WINDOW w AS (ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 F..." +== 235 +-- truncate_limit: 100 +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x range between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte(x) AS (...) SELECT ... FROM cte WINDOW w AS (ORDER BY x RANGE BETWEEN 1 PRECEDING AND 1 ..." +== 236 +-- truncate_limit: 100 +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following) +-- +CTE: "cte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH cte(x) AS (...) SELECT ... FROM cte WINDOW w AS (ORDER BY x GROUPS BETWEEN 1 PRECEDING AND 1..." +== 237 +-- truncate_limit: 100 +-- with UNION +SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2)s LIMIT 0 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk2" schema="" table="tenk2" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2) s LIMIT 0" +== 238 +-- truncate_limit: 100 +-- check some degenerate cases +create temp table t1 (f1 int, f2 int8) +-- +TABLE: name="t1" schema="" table="t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE t1 (f1 int, f2 int8)" +== 239 +-- truncate_limit: 100 +insert into t1 values (1,1),(1,2),(2,2) +-- +TABLE: name="t1" schema="" table="t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO t1 VALUES (1, 1), (1, 2), (2, 2)" +== 240 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1 + range between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 241 +-- truncate_limit: 100 +-- error, must have order by +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT f1, sum(f1) OVER (PARTITION BY f1 ORDER BY f2 RANGE BETWEEN 1 PRECEDIN..." +== 242 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 243 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1, f1 order by f2 + range between 2 preceding and 1 preceding) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 244 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1, f2 order by f2 + range between 1 following and 2 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 245 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1 + groups between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 246 +-- truncate_limit: 100 +-- error, must have order by +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT f1, sum(f1) OVER (PARTITION BY f1 ORDER BY f2 GROUPS BETWEEN 1 PRECEDI..." +== 247 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 248 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1, f1 order by f2 + groups between 2 preceding and 1 preceding) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 249 +-- truncate_limit: 100 +select f1, sum(f1) over (partition by f1, f2 order by f2 + groups between 1 following and 2 following) +from t1 where f1 = f2 +-- +TABLE: name="t1" schema="" table="t1" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="f1" +FILTER: schema="" table="" column="f2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM t1 WHERE f1 = f2" +== 250 +-- truncate_limit: 100 +-- ordering by a non-integer constant is allowed +SELECT rank() OVER (ORDER BY length('abc')) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank() OVER (ORDER BY length('abc'))" +== 251 +-- truncate_limit: 100 +-- can't order by another window function +SELECT rank() OVER (ORDER BY rank() OVER (ORDER BY random())) +-- +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank() OVER (ORDER BY rank() OVER (ORDER BY random()))" +== 252 +-- truncate_limit: 100 +-- some other errors +SELECT * FROM empsalary WHERE row_number() OVER (ORDER BY salary) < 10 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="salary" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM empsalary WHERE row_number() OVER (ORDER BY salary) < 10" +== 253 +-- truncate_limit: 100 +SELECT * FROM empsalary INNER JOIN tenk1 ON row_number() OVER (ORDER BY salary) < 10 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM empsalary JOIN tenk1 ON row_number() OVER (ORDER BY salary) < 10" +== 254 +-- truncate_limit: 100 +SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GROUP BY 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GROUP BY 1" +== 255 +-- truncate_limit: 100 +SELECT * FROM rank() OVER (ORDER BY random()) +-- +ERROR: syntax error at or near "ORDER" +CURSORPOS: 28 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 256 +-- truncate_limit: 100 +DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())) > 10 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DML +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM empsalary WHERE rank() OVER (ORDER BY random()) > 10" +== 257 +-- truncate_limit: 100 +DELETE FROM empsalary RETURNING rank() OVER (ORDER BY random()) +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DML +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: DeleteStmt +TRUNCATED: "DELETE FROM empsalary RETURNING rank() OVER (ORDER BY random())" +== 258 +-- truncate_limit: 100 +SELECT count(*) OVER w FROM tenk1 WINDOW w AS (ORDER BY unique1), w AS (ORDER BY unique1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) OVER w FROM tenk1 WINDOW w AS (ORDER BY unique1), w AS (ORDER BY unique1)" +== 259 +-- truncate_limit: 100 +SELECT rank() OVER (PARTITION BY four, ORDER BY ten) FROM tenk1 +-- +ERROR: syntax error at or near "ORDER" +CURSORPOS: 40 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 260 +-- truncate_limit: 100 +SELECT count() OVER () FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count() OVER () FROM tenk1" +== 261 +-- truncate_limit: 100 +SELECT generate_series(1, 100) OVER () FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT generate_series(1, 100) OVER () FROM empsalary" +== 262 +-- truncate_limit: 100 +SELECT ntile(0) OVER (ORDER BY ten), ten, four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ntile(0) OVER (ORDER BY ten), ten, four FROM tenk1" +== 263 +-- truncate_limit: 100 +SELECT nth_value(four, 0) OVER (ORDER BY ten), ten, four FROM tenk1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value" function="nth_value" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT nth_value(four, 0) OVER (ORDER BY ten), ten, four FROM tenk1" +== 264 +-- truncate_limit: 100 +-- filter + +SELECT sum(salary), row_number() OVER (ORDER BY depname), sum( + sum(salary) FILTER (WHERE enroll_date > '2007-01-01') +) FILTER (WHERE depname <> 'sales') OVER (ORDER BY depname DESC) AS "filtered_sum", + depname +FROM empsalary GROUP BY depname +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary GROUP BY depname" +== 265 +-- truncate_limit: 100 +|-- +-- Test SupportRequestOptimizeWindowClause's ability to de-duplicate +-- WindowClauses +|-- + +-- Ensure WindowClause frameOptions are changed so that only a single +-- WindowAgg exists in the plan. +EXPLAIN (COSTS OFF) +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + dense_rank() OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) drnk, + ntile(10) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) nt, + percent_rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) pr, + cume_dist() OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) cd +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FUNCTION: name="percent_rank" function="percent_rank" schema="" ctx=Call +FUNCTION: name="cume_dist" function="cume_dist" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT empno, depname, row_number() OVER (PARTITION BY depname ORDER BY enrol..." +== 266 +-- truncate_limit: 100 +-- Ensure WindowFuncs which cannot support their WindowClause's frameOptions +-- being changed are untouched +EXPLAIN (COSTS OFF, VERBOSE) +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + count(*) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) cnt +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT empno, depname, row_number() OVER (PARTITION BY depname ORDER..." +== 267 +-- truncate_limit: 100 +-- Ensure the above query gives us the expected results +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + count(*) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) cnt +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM empsalary" +== 268 +-- truncate_limit: 100 +-- Test pushdown of quals into a subquery containing window functions + +-- pushdown is safe because all PARTITION BY clauses include depname: +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname) depsalary, + min(salary) OVER (PARTITION BY depname || 'A', depname) depminsalary + FROM empsalary) emp +WHERE depname = 'sales' +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="depname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT depname, sum(salary) OVER (PARTITION BY depname) AS dep..." +== 269 +-- truncate_limit: 100 +-- pushdown is unsafe because there's a PARTITION BY clause without depname: +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY enroll_date) enroll_salary, + min(salary) OVER (PARTITION BY depname) depminsalary + FROM empsalary) emp +WHERE depname = 'sales' +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="depname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT depname, sum(salary) OVER (PARTITION BY enroll_date) AS..." +== 270 +-- truncate_limit: 100 +-- Test window function run conditions are properly pushed down into the +-- WindowAgg +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, row_number() OVER (ORDER BY empno) AS rn FROM em..." +== 271 +-- truncate_limit: 100 +-- The following 3 statements should result the same result. +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE rn < 3" +== 272 +-- truncate_limit: 100 +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE 3 > rn +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE 3 > rn" +== 273 +-- truncate_limit: 100 +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE 2 >= rn +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE 2 >= rn" +== 274 +-- truncate_limit: 100 +-- Ensure r <= 3 is pushed down into the run condition of the window agg +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + rank() OVER (ORDER BY salary DESC) r + FROM empsalary) emp +WHERE r <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="r" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, rank() OVER (ORDER BY salary DESC) AS r ..." +== 275 +-- truncate_limit: 100 +SELECT * FROM + (SELECT empno, + salary, + rank() OVER (ORDER BY salary DESC) r + FROM empsalary) emp +WHERE r <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="rank" function="rank" schema="" ctx=Call +FILTER: schema="" table="" column="r" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE r <= 3" +== 276 +-- truncate_limit: 100 +-- Ensure dr = 1 is converted to dr <= 1 to get all rows leading up to dr = 1 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="dr" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, dense_rank() OVER (ORDER BY salary DESC)..." +== 277 +-- truncate_limit: 100 +SELECT * FROM + (SELECT empno, + salary, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="dr" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE dr = 1" +== 278 +-- truncate_limit: 100 +-- Check COUNT() and COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(*) OVER (ORDER BY salary DESC) AS ..." +== 279 +-- truncate_limit: 100 +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE c <= 3" +== 280 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(empno) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(empno) OVER (ORDER BY salary DESC)..." +== 281 +-- truncate_limit: 100 +SELECT * FROM + (SELECT empno, + salary, + count(empno) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE c <= 3" +== 282 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) c + FROM empsalary) emp +WHERE c >= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(*) OVER (ORDER BY salary DESC ROWS..." +== 283 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER () c + FROM empsalary) emp +WHERE 11 <= c +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(*) OVER () AS c FROM empsalary) em..." +== 284 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="dense_rank" function="dense_rank" schema="" ctx=Call +FILTER: schema="" table="" column="dr" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(*) OVER (ORDER BY salary DESC) AS ..." +== 285 +-- truncate_limit: 100 +-- Ensure we get a run condition when there's a PARTITION BY clause +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, depname, row_number() OVER (PARTITION BY depname..." +== 286 +-- truncate_limit: 100 +-- and ensure we get the correct results from the above plan +SELECT * FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE rn < 3" +== 287 +-- truncate_limit: 100 +-- ensure that "unused" subquery columns are not removed when the column only +-- exists in the run condition +EXPLAIN (COSTS OFF) +SELECT empno, depname FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT empno, depname FROM (SELECT empno, depname, row_number() OVER (PARTITI..." +== 288 +-- truncate_limit: 100 +-- likewise with count(empno) instead of row_number() +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (PARTITION BY depname ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, depname, salary, count(empno) OVER (PARTITION BY..." +== 289 +-- truncate_limit: 100 +-- and again, check the results are what we expect. +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (PARTITION BY depname ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE c <= 3" +== 290 +-- truncate_limit: 100 +-- Ensure we get the correct run condition when the window function is both +-- monotonically increasing and decreasing. +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER () c + FROM empsalary) emp +WHERE c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, depname, salary, count(empno) OVER () AS c FROM ..." +== 291 +-- truncate_limit: 100 +-- Try another case with a WindowFunc with a byref return type +SELECT * FROM + (SELECT row_number() OVER (PARTITION BY salary) AS rn, + lead(depname) OVER (PARTITION BY salary) || ' Department' AS n_dep + FROM empsalary) emp +WHERE rn < 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE rn < 1" +== 292 +-- truncate_limit: 100 +-- Some more complex cases with multiple window clauses +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT *, + count(salary) OVER (PARTITION BY depname || '') c1, -- w1 + row_number() OVER (PARTITION BY depname) rn, -- w2 + count(*) OVER (PARTITION BY depname) c2, -- w2 + count(*) OVER (PARTITION BY '' || depname) c3, -- w3 + ntile(2) OVER (PARTITION BY depname) nt -- w2 + FROM empsalary +) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="nt" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT *, count(salary) OVER (PARTITION BY depname || '') AS c..." +== 293 +-- truncate_limit: 100 +-- Ensure we correctly filter out all of the run conditions from each window +SELECT * FROM + (SELECT *, + count(salary) OVER (PARTITION BY depname || '') c1, -- w1 + row_number() OVER (PARTITION BY depname) rn, -- w2 + count(*) OVER (PARTITION BY depname) c2, -- w2 + count(*) OVER (PARTITION BY '' || depname) c3, -- w3 + ntile(2) OVER (PARTITION BY depname) nt -- w2 + FROM empsalary +) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="" column="rn" +FILTER: schema="" table="" column="c1" +FILTER: schema="" table="" column="nt" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2" +== 294 +-- truncate_limit: 100 +-- Ensure we remove references to reduced outer joins as nulling rels in run +-- conditions +EXPLAIN (COSTS OFF) +SELECT 1 FROM + (SELECT ntile(e2.salary) OVER (PARTITION BY e1.depname) AS c + FROM empsalary e1 LEFT JOIN empsalary e2 ON TRUE + WHERE e1.empno = e2.empno) s +WHERE s.c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +ALIAS: "e1"="empsalary" +ALIAS: "e2"="empsalary" +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="s" column="c" +FILTER: schema="" table="e1" column="empno" +FILTER: schema="" table="e2" column="empno" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM (SELECT ntile(e2.salary) OVER (PARTITION BY e1.depname) AS c FR..." +== 295 +-- truncate_limit: 100 +-- Ensure the run condition optimization is used in cases where the WindowFunc +-- has a Var from another query level +EXPLAIN (COSTS OFF) +SELECT 1 FROM + (SELECT ntile(s1.x) OVER () AS c + FROM (SELECT (SELECT 1) AS x) AS s1) s +WHERE s.c = 1 +-- +FUNCTION: name="ntile" function="ntile" schema="" ctx=Call +FILTER: schema="" table="s" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT 1 FROM (SELECT ntile(s1.x) OVER () AS c FROM (SELECT (SELECT 1) AS x) ..." +== 296 +-- truncate_limit: 100 +-- Tests to ensure we don't push down the run condition when it's not valid to +-- do so. + +-- Ensure we don't push down when the frame options show that the window +-- function is not monotonically increasing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) c + FROM empsalary) emp +WHERE c <= 3 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(*) OVER (ORDER BY salary DESC ROWS..." +== 297 +-- truncate_limit: 100 +-- Ensure we don't push down when the window function's monotonic properties +-- don't match that of the clauses. +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary) c + FROM empsalary) emp +WHERE 3 <= c +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(*) OVER (ORDER BY salary) AS c FRO..." +== 298 +-- truncate_limit: 100 +-- Ensure we don't use a run condition when there's a volatile function in the +-- WindowFunc +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(random()) OVER (ORDER BY empno DESC) c + FROM empsalary) emp +WHERE c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count(random()) OVER (ORDER BY empno DES..." +== 299 +-- truncate_limit: 100 +-- Ensure we don't use a run condition when the WindowFunc contains subplans +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count((SELECT 1)) OVER (ORDER BY empno DESC) c + FROM empsalary) emp +WHERE c = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="c" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, salary, count((SELECT 1)) OVER (ORDER BY empno D..." +== 300 +-- truncate_limit: 100 +-- Test Sort node collapsing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname, empno order by enroll_date) depminsalary + FROM empsalary) emp +WHERE depname = 'sales' +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="" column="depname" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT depname, sum(salary) OVER (PARTITION BY depname ORDER B..." +== 301 +-- truncate_limit: 100 +-- Ensure that the evaluation order of the WindowAggs results in the WindowAgg +-- with the same sort order that's required by the ORDER BY is evaluated last. +EXPLAIN (COSTS OFF) +SELECT empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, empno +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT empno, enroll_date, depname, sum(salary) OVER (PARTITION BY depname OR..." +== 302 +-- truncate_limit: 100 +-- As above, but with an adjusted ORDER BY to ensure the above plan didn't +-- perform only 2 sorts by accident. +EXPLAIN (COSTS OFF) +SELECT empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, enroll_date +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT empno, enroll_date, depname, sum(salary) OVER (PARTITION BY depname OR..." +== 303 +-- truncate_limit: 100 +SET enable_hashagg TO off +-- +STMT: VariableSetStmt +TRUNCATED: "SET enable_hashagg TO OFF" +== 304 +-- truncate_limit: 100 +-- Ensure we don't get a sort for both DISTINCT and ORDER BY. We expect the +-- sort for the DISTINCT to provide presorted input for the ORDER BY. +EXPLAIN (COSTS OFF) +SELECT DISTINCT + empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, enroll_date +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT empno, enroll_date, depname, sum(salary) OVER (PARTITION BY d..." +== 305 +-- truncate_limit: 100 +-- As above but adjust the ORDER BY clause to help ensure the plan with the +-- minimum amount of sorting wasn't a fluke. +EXPLAIN (COSTS OFF) +SELECT DISTINCT + empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, empno +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="min" function="min" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT DISTINCT empno, enroll_date, depname, sum(salary) OVER (PARTITION BY d..." +== 306 +-- truncate_limit: 100 +RESET enable_hashagg +-- +STMT: VariableSetStmt +TRUNCATED: "RESET enable_hashagg" +== 307 +-- truncate_limit: 100 +-- Test Sort node reordering +EXPLAIN (COSTS OFF) +SELECT + lead(1) OVER (PARTITION BY depname ORDER BY salary, enroll_date), + lag(1) OVER (PARTITION BY depname ORDER BY salary,enroll_date,empno) +FROM empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="lead" function="lead" schema="" ctx=Call +FUNCTION: name="lag" function="lag" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT lead(1) OVER (PARTITION BY depname ORDER BY salary, enroll_date), lag(..." +== 308 +-- truncate_limit: 100 +-- Test incremental sorting +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + empno, + salary, + enroll_date, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp + FROM empsalary) emp +WHERE first_emp = 1 OR last_emp = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="first_emp" +FILTER: schema="" table="" column="last_emp" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM (SELECT depname, empno, salary, enroll_date, row_number() OVER ..." +== 309 +-- truncate_limit: 100 +SELECT * FROM + (SELECT depname, + empno, + salary, + enroll_date, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp + FROM empsalary) emp +WHERE first_emp = 1 OR last_emp = 1 +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=Select +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="" column="first_emp" +FILTER: schema="" table="" column="last_emp" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM (SELECT ... FROM empsalary) emp WHERE first_emp = 1 OR last_emp = 1" +== 310 +-- truncate_limit: 100 +-- cleanup +DROP TABLE empsalary +-- +TABLE: name="empsalary" schema="" table="empsalary" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE empsalary" +== 311 +-- truncate_limit: 100 +-- test user-defined window function with named args and default args +CREATE FUNCTION nth_value_def(val anyelement, n integer = 1) RETURNS anyelement + LANGUAGE internal WINDOW IMMUTABLE STRICT AS 'window_nth_value' +-- +FUNCTION: name="nth_value_def" function="nth_value_def" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION nth_value_def(val anyelement, n int = 1) RETURNS anyelement LANGUAGE internal WIN..." +== 312 +-- truncate_limit: 100 +SELECT nth_value_def(n := 2, val := ten) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value_def" function="nth_value_def" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM tenk1 WHERE ... ORDER BY four, ten) s" +== 313 +-- truncate_limit: 100 +SELECT nth_value_def(ten) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="nth_value_def" function="nth_value_def" schema="" ctx=Call +FILTER: schema="" table="" column="unique2" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT * FROM tenk1 WHERE ... ORDER BY four, ten) s" +== 314 +-- truncate_limit: 100 +|-- +-- Test the basic moving-aggregate machinery +|-- + +-- create aggregates that record the series of transform calls (these are +-- intentionally not true inverses) + +CREATE FUNCTION logging_sfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT COALESCE($1, '') || '*' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="logging_sfunc_nonstrict" function="logging_sfunc_nonstrict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION logging_sfunc_nonstrict(text, anyelement) RETURNS text AS $$ SELECT COALESCE($1, ..." +== 315 +-- truncate_limit: 100 +CREATE FUNCTION logging_msfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT COALESCE($1, '') || '+' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="logging_msfunc_nonstrict" function="logging_msfunc_nonstrict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION logging_msfunc_nonstrict(text, anyelement) RETURNS text AS $$ SELECT COALESCE($1,..." +== 316 +-- truncate_limit: 100 +CREATE FUNCTION logging_minvfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '-' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE +-- +FUNCTION: name="logging_minvfunc_nonstrict" function="logging_minvfunc_nonstrict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION logging_minvfunc_nonstrict(text, anyelement) RETURNS text AS $$ SELECT $1 || '-' ..." +== 317 +-- truncate_limit: 100 +CREATE AGGREGATE logging_agg_nonstrict (anyelement) +( + stype = text, + sfunc = logging_sfunc_nonstrict, + mstype = text, + msfunc = logging_msfunc_nonstrict, + minvfunc = logging_minvfunc_nonstrict +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE logging_agg_nonstrict (anyelement) (stype = text, sfunc = logging_sfunc_nonstric..." +== 318 +-- truncate_limit: 100 +CREATE AGGREGATE logging_agg_nonstrict_initcond (anyelement) +( + stype = text, + sfunc = logging_sfunc_nonstrict, + mstype = text, + msfunc = logging_msfunc_nonstrict, + minvfunc = logging_minvfunc_nonstrict, + initcond = 'I', + minitcond = 'MI' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE logging_agg_nonstrict_initcond (anyelement) (stype = text, sfunc = logging_sfunc..." +== 319 +-- truncate_limit: 100 +CREATE FUNCTION logging_sfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '*' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE +-- +FUNCTION: name="logging_sfunc_strict" function="logging_sfunc_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION logging_sfunc_strict(text, anyelement) RETURNS text AS $$ SELECT $1 || '*' || quo..." +== 320 +-- truncate_limit: 100 +CREATE FUNCTION logging_msfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '+' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE +-- +FUNCTION: name="logging_msfunc_strict" function="logging_msfunc_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION logging_msfunc_strict(text, anyelement) RETURNS text AS $$ SELECT $1 || '+' || qu..." +== 321 +-- truncate_limit: 100 +CREATE FUNCTION logging_minvfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '-' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE +-- +FUNCTION: name="logging_minvfunc_strict" function="logging_minvfunc_strict" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION logging_minvfunc_strict(text, anyelement) RETURNS text AS $$ SELECT $1 || '-' || ..." +== 322 +-- truncate_limit: 100 +CREATE AGGREGATE logging_agg_strict (text) +( + stype = text, + sfunc = logging_sfunc_strict, + mstype = text, + msfunc = logging_msfunc_strict, + minvfunc = logging_minvfunc_strict +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE logging_agg_strict (text) (stype = text, sfunc = logging_sfunc_strict, mstype = ..." +== 323 +-- truncate_limit: 100 +CREATE AGGREGATE logging_agg_strict_initcond (anyelement) +( + stype = text, + sfunc = logging_sfunc_strict, + mstype = text, + msfunc = logging_msfunc_strict, + minvfunc = logging_minvfunc_strict, + initcond = 'I', + minitcond = 'MI' +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE logging_agg_strict_initcond (anyelement) (stype = text, sfunc = logging_sfunc_st..." +== 324 +-- truncate_limit: 100 +-- test strict and non-strict cases +SELECT + p::text || ',' || i::text || ':' || COALESCE(v::text, 'NULL') AS row, + logging_agg_nonstrict(v) over wnd as nstrict, + logging_agg_nonstrict_initcond(v) over wnd as nstrict_init, + logging_agg_strict(v::text) over wnd as strict, + logging_agg_strict_initcond(v) over wnd as strict_init +FROM (VALUES + (1, 1, NULL), + (1, 2, 'a'), + (1, 3, 'b'), + (1, 4, NULL), + (1, 5, NULL), + (1, 6, 'c'), + (2, 1, NULL), + (2, 2, 'x'), + (3, 1, 'z') +) AS t(p, i, v) +WINDOW wnd AS (PARTITION BY P ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY p, i +-- +FUNCTION: name="logging_agg_nonstrict" function="logging_agg_nonstrict" schema="" ctx=Call +FUNCTION: name="logging_agg_nonstrict_initcond" function="logging_agg_nonstrict_initcond" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict_initcond" function="logging_agg_strict_initcond" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(p, i, v) WINDOW wnd AS (PARTITION BY p ORDER BY i ROWS BETWEEN 1..." +== 325 +-- truncate_limit: 100 +-- and again, but with filter +SELECT + p::text || ',' || i::text || ':' || + CASE WHEN f THEN COALESCE(v::text, 'NULL') ELSE '-' END as row, + logging_agg_nonstrict(v) filter(where f) over wnd as nstrict_filt, + logging_agg_nonstrict_initcond(v) filter(where f) over wnd as nstrict_init_filt, + logging_agg_strict(v::text) filter(where f) over wnd as strict_filt, + logging_agg_strict_initcond(v) filter(where f) over wnd as strict_init_filt +FROM (VALUES + (1, 1, true, NULL), + (1, 2, false, 'a'), + (1, 3, true, 'b'), + (1, 4, false, NULL), + (1, 5, false, NULL), + (1, 6, false, 'c'), + (2, 1, false, NULL), + (2, 2, true, 'x'), + (3, 1, true, 'z') +) AS t(p, i, f, v) +WINDOW wnd AS (PARTITION BY p ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY p, i +-- +FUNCTION: name="logging_agg_nonstrict" function="logging_agg_nonstrict" schema="" ctx=Call +FUNCTION: name="logging_agg_nonstrict_initcond" function="logging_agg_nonstrict_initcond" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict_initcond" function="logging_agg_strict_initcond" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(p, i, f, v) WINDOW wnd AS (PARTITION BY p ORDER BY i ROWS BETWEE..." +== 326 +-- truncate_limit: 100 +-- test that volatile arguments disable moving-aggregate mode +SELECT + i::text || ':' || COALESCE(v::text, 'NULL') as row, + logging_agg_strict(v::text) + over wnd as inverse, + logging_agg_strict(v::text || CASE WHEN random() < 0 then '?' ELSE '' END) + over wnd as noinverse +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY i +-- +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v) WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CUR..." +== 327 +-- truncate_limit: 100 +SELECT + i::text || ':' || COALESCE(v::text, 'NULL') as row, + logging_agg_strict(v::text) filter(where true) + over wnd as inverse, + logging_agg_strict(v::text) filter(where random() >= 0) + over wnd as noinverse +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY i +-- +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v) WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CUR..." +== 328 +-- truncate_limit: 100 +-- test that non-overlapping windows don't use inverse transitions +SELECT + logging_agg_strict(v::text) OVER wnd +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW) +ORDER BY i +-- +FUNCTION: name="logging_agg_strict" function="logging_agg_strict" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v) WINDOW wnd AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND CUR..." +== 329 +-- truncate_limit: 100 +-- test that returning NULL from the inverse transition functions +-- restarts the aggregation from scratch. The second aggregate is supposed +-- to test cases where only some aggregates restart, the third one checks +-- that one aggregate restarting doesn't cause others to restart. + +CREATE FUNCTION sum_int_randrestart_minvfunc(int4, int4) RETURNS int4 AS +$$ SELECT CASE WHEN random() < 0.2 THEN NULL ELSE $1 - $2 END $$ +LANGUAGE SQL STRICT +-- +FUNCTION: name="sum_int_randrestart_minvfunc" function="sum_int_randrestart_minvfunc" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION sum_int_randrestart_minvfunc(int4, int4) RETURNS int4 AS $$ SELECT CASE WHEN rand..." +== 330 +-- truncate_limit: 100 +CREATE AGGREGATE sum_int_randomrestart (int4) +( + stype = int4, + sfunc = int4pl, + mstype = int4, + msfunc = int4pl, + minvfunc = sum_int_randrestart_minvfunc +) +-- +STMT: DefineStmt +TRUNCATED: "CREATE AGGREGATE sum_int_randomrestart (int4) (stype = int4, sfunc = int4pl, mstype = int4, msfun..." +== 331 +-- truncate_limit: 100 +WITH +vs AS ( + SELECT i, (random() * 100)::int4 AS v + FROM generate_series(1, 100) AS i +), +sum_following AS ( + SELECT i, SUM(v) OVER + (ORDER BY i DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS s + FROM vs +) +SELECT DISTINCT + sum_following.s = sum_int_randomrestart(v) OVER fwd AS eq1, + -sum_following.s = sum_int_randomrestart(-v) OVER fwd AS eq2, + 100*3+(vs.i-1)*3 = length(logging_agg_nonstrict(''::text) OVER fwd) AS eq3 +FROM vs +JOIN sum_following ON sum_following.i = vs.i +WINDOW fwd AS ( + ORDER BY vs.i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +) +-- +CTE: "vs" +CTE: "sum_following" +FUNCTION: name="sum_int_randomrestart" function="sum_int_randomrestart" schema="" ctx=Call +FUNCTION: name="sum_int_randomrestart" function="sum_int_randomrestart" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="logging_agg_nonstrict" function="logging_agg_nonstrict" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH vs AS (...), sum_following AS (...) SELECT DISTINCT ... AS ... FROM vs JOIN sum_following ON..." +== 332 +-- truncate_limit: 100 +|-- +-- Test various built-in aggregates that have moving-aggregate support +|-- + +-- test inverse transition functions handle NULLs properly +SELECT i,AVG(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 333 +-- truncate_limit: 100 +SELECT i,AVG(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 334 +-- truncate_limit: 100 +SELECT i,AVG(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 335 +-- truncate_limit: 100 +SELECT i,AVG(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.5),(2,2.5),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 336 +-- truncate_limit: 100 +SELECT i,AVG(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 337 +-- truncate_limit: 100 +-- moving aggregates over infinite intervals +SELECT x + ,avg(x) OVER(ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ) as curr_next_avg + ,avg(x) OVER(ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) as prev_curr_avg + ,sum(x) OVER(ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ) as curr_next_sum + ,sum(x) OVER(ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) as prev_curr_sum +FROM (VALUES (NULL::interval), + ('infinity'::interval), + ('-2147483648 days -2147483648 months -9223372036854775807 usecs'), -- extreme interval value + ('-infinity'::interval), + ('2147483647 days 2147483647 months 9223372036854775806 usecs'), -- extreme interval value + ('infinity'::interval), + ('6 days'::interval), + ('7 days'::interval), + (NULL::interval), + ('-infinity'::interval)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(x)" +== 338 +-- truncate_limit: 100 +--should fail. +SELECT x, avg(x) OVER(ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) +FROM (VALUES (NULL::interval), + ('3 days'::interval), + ('infinity'::timestamptz - now()), + ('6 days'::interval), + ('-infinity'::interval)) v(x) +-- +FUNCTION: name="avg" function="avg" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, avg(x) OVER (ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) FROM (VALUES (...)) v(x)" +== 339 +-- truncate_limit: 100 +--should fail. +SELECT x, sum(x) OVER(ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) +FROM (VALUES (NULL::interval), + ('3 days'::interval), + ('infinity'::timestamptz - now()), + ('6 days'::interval), + ('-infinity'::interval)) v(x) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="now" function="now" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT x, sum(x) OVER (ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) FROM (VALUES (...)) v(x)" +== 340 +-- truncate_limit: 100 +SELECT i,SUM(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 341 +-- truncate_limit: 100 +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 342 +-- truncate_limit: 100 +SELECT i,SUM(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 343 +-- truncate_limit: 100 +SELECT i,SUM(v::money) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1.10'),(2,'2.20'),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 344 +-- truncate_limit: 100 +SELECT i,SUM(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 345 +-- truncate_limit: 100 +SELECT i,SUM(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.1),(2,2.2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 346 +-- truncate_limit: 100 +SELECT SUM(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.01),(2,2),(3,3)) v(i,n) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(i, n)" +== 347 +-- truncate_limit: 100 +SELECT i,COUNT(v) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 348 +-- truncate_limit: 100 +SELECT i,COUNT(*) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 349 +-- truncate_limit: 100 +SELECT VAR_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 350 +-- truncate_limit: 100 +SELECT VAR_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 351 +-- truncate_limit: 100 +SELECT VAR_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 352 +-- truncate_limit: 100 +SELECT VAR_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_pop" function="var_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 353 +-- truncate_limit: 100 +SELECT VAR_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 354 +-- truncate_limit: 100 +SELECT VAR_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 355 +-- truncate_limit: 100 +SELECT VAR_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 356 +-- truncate_limit: 100 +SELECT VAR_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="var_samp" function="var_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 357 +-- truncate_limit: 100 +SELECT VARIANCE(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 358 +-- truncate_limit: 100 +SELECT VARIANCE(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 359 +-- truncate_limit: 100 +SELECT VARIANCE(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 360 +-- truncate_limit: 100 +SELECT VARIANCE(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="variance" function="variance" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 361 +-- truncate_limit: 100 +SELECT STDDEV_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 362 +-- truncate_limit: 100 +SELECT STDDEV_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 363 +-- truncate_limit: 100 +SELECT STDDEV_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 364 +-- truncate_limit: 100 +SELECT STDDEV_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_pop" function="stddev_pop" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 365 +-- truncate_limit: 100 +SELECT STDDEV_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 366 +-- truncate_limit: 100 +SELECT STDDEV_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 367 +-- truncate_limit: 100 +SELECT STDDEV_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 368 +-- truncate_limit: 100 +SELECT STDDEV_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n) +-- +FUNCTION: name="stddev_samp" function="stddev_samp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 369 +-- truncate_limit: 100 +SELECT STDDEV(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 370 +-- truncate_limit: 100 +SELECT STDDEV(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 371 +-- truncate_limit: 100 +SELECT STDDEV(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 372 +-- truncate_limit: 100 +SELECT STDDEV(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n) +-- +FUNCTION: name="stddev" function="stddev" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) r(i, n)" +== 373 +-- truncate_limit: 100 +-- test that inverse transition functions work with various frame options +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 374 +-- truncate_limit: 100 +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 375 +-- truncate_limit: 100 +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,3),(4,4)) t(i,v) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(i, v)" +== 376 +-- truncate_limit: 100 +-- ensure aggregate over numeric properly recovers from NaN values +SELECT a, b, + SUM(b) OVER(ORDER BY A ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +FROM (VALUES(1,1::numeric),(2,2),(3,'NaN'),(4,3),(5,4)) t(a,b) +-- +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) t(a, b)" +== 377 +-- truncate_limit: 100 +-- It might be tempting for someone to add an inverse trans function for +-- float and double precision. This should not be done as it can give incorrect +-- results. This test should fail if anyone ever does this without thinking too +-- hard about it. +SELECT to_char(SUM(n::float8) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),'999999999999999999999D9') + FROM (VALUES(1,1e20),(2,1)) n(i,n) +-- +FUNCTION: name="to_char" function="to_char" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) n(i, n)" +== 378 +-- truncate_limit: 100 +SELECT i, b, bool_and(b) OVER w, bool_or(b) OVER w + FROM (VALUES (1,true), (2,true), (3,false), (4,false), (5,true)) v(i,b) + WINDOW w AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) +-- +FUNCTION: name="bool_and" function="bool_and" schema="" ctx=Call +FUNCTION: name="bool_or" function="bool_or" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (VALUES (...)) v(i, b) WINDOW w AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOL..." +== 379 +-- truncate_limit: 100 +|-- +-- Test WindowAgg costing takes into account the number of rows that need to +-- be fetched before the first row can be output. +|-- + +-- Ensure we get a cheap start up plan as the WindowAgg can output the first +-- row after reading 1 row from the join. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER (ORDER BY t1.unique1) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) OVER (ORDER BY t1.unique1) FROM tenk1 t1 JOIN tenk1 t2 ON t1...." +== 380 +-- truncate_limit: 100 +-- Ensure we get a cheap total plan. Lack of ORDER BY in the WindowClause +-- means that all rows must be read from the join, so a cheap startup plan +-- isn't a good choice. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER () +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +WHERE t2.two = 1 +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="t2" column="two" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) OVER () FROM tenk1 t1 JOIN tenk1 t2 ON t1.unique1 = t2.tentho..." +== 381 +-- truncate_limit: 100 +-- Ensure we get a cheap total plan. This time use UNBOUNDED FOLLOWING, which +-- needs to read all join rows to output the first WindowAgg row. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AN..." +== 382 +-- truncate_limit: 100 +-- Ensure we get a cheap total plan. This time use 10000 FOLLOWING so we need +-- to read all join rows. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND 10000 FOLLOWING) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1 +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "t1"="tenk1" +ALIAS: "t2"="tenk1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT count(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AN..." +== 383 +-- truncate_limit: 100 +-- Tests for problems with failure to walk or mutate expressions +-- within window frame clauses. + +-- test walker (fails with collation error if expressions are not walked) +SELECT array_agg(i) OVER w + FROM generate_series(1,5) i +WINDOW w AS (ORDER BY i ROWS BETWEEN (('foo' < 'foobar')::integer) PRECEDING AND CURRENT ROW) +-- +FUNCTION: name="array_agg" function="array_agg" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM generate_series(1, 5) i WINDOW w AS (ORDER BY i ROWS BETWEEN ('foo' < 'foobar')::..." +== 384 +-- truncate_limit: 100 +-- test mutator (fails when inlined if expressions are not mutated) +CREATE FUNCTION pg_temp.f(group_size BIGINT) RETURNS SETOF integer[] +AS $$ + SELECT array_agg(s) OVER w + FROM generate_series(1,5) s + WINDOW w AS (ORDER BY s ROWS BETWEEN CURRENT ROW AND GROUP_SIZE FOLLOWING) +$$ LANGUAGE SQL STABLE +-- +FUNCTION: name="pg_temp.f" function="f" schema="pg_temp" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION pg_temp.f(group_size bigint) RETURNS SETOF int[] AS $$\n SELECT array_agg(s) OV..." +== 385 +-- truncate_limit: 100 +EXPLAIN (costs off) SELECT * FROM pg_temp.f(2) +-- +FUNCTION: name="pg_temp.f" function="f" schema="pg_temp" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM pg_temp.f(2)" +== 386 +-- truncate_limit: 100 +SELECT * FROM pg_temp.f(2) +-- +FUNCTION: name="pg_temp.f" function="f" schema="pg_temp" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_temp.f(2)" diff --git a/parser/testdata/summary_truncate/postgres_regress/with.metadata.json b/parser/testdata/summary_truncate/postgres_regress/with.metadata.json new file mode 100644 index 0000000..b24b526 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/with.metadata.json @@ -0,0 +1,297 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/with.test b/parser/testdata/summary_truncate/postgres_regress/with.test new file mode 100644 index 0000000..262aac7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/with.test @@ -0,0 +1,3894 @@ +== 001 +-- truncate_limit: 100 +|-- +-- Tests for common table expressions (WITH query, ... SELECT ...) +|-- + +-- Basic WITH +WITH q1(x,y) AS (SELECT 1,2) +SELECT * FROM q1, q1 AS q2 +-- +ALIAS: "q2"="q1" +CTE: "q1" +STMT: SelectStmt +TRUNCATED: "WITH q1(x, y) AS (SELECT 1, 2) SELECT * FROM q1, q1 q2" +== 002 +-- truncate_limit: 100 +-- Multiple uses are evaluated only once +SELECT count(*) FROM ( + WITH q1(x) AS (SELECT random() FROM generate_series(1, 5)) + SELECT * FROM q1 + UNION + SELECT * FROM q1 +) ss +-- +CTE: "q1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="random" function="random" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (WITH q1(x) AS (...) SELECT * FROM q1 UNION SELECT * FROM q1) ss" +== 003 +-- truncate_limit: 100 +-- WITH RECURSIVE + +-- sum of 1..100 +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t +-- +CTE: "t" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (VALUES (1) UNION ALL SELECT n + 1 FROM t WHERE n < 100) SELECT sum(n) FROM t" +== 004 +-- truncate_limit: 100 +WITH RECURSIVE t(n) AS ( + SELECT (VALUES(1)) +UNION ALL + SELECT n+1 FROM t WHERE n < 5 +) +SELECT * FROM t +-- +CTE: "t" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (SELECT ... UNION ALL SELECT n + 1 FROM t WHERE n < 5) SELECT * FROM t" +== 005 +-- truncate_limit: 100 +-- UNION DISTINCT requires hashable type +WITH RECURSIVE t(n) AS ( + VALUES ('01'::varbit) +UNION + SELECT n || '10'::varbit FROM t WHERE n < '100'::varbit +) +SELECT n FROM t +-- +CTE: "t" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (VALUES ('01'::varbit) UNION SELECT ... FROM t WHERE ...) SELECT n FROM t" +== 006 +-- truncate_limit: 100 +-- recursive view +CREATE RECURSIVE VIEW nums (n) AS + VALUES (1) +UNION ALL + SELECT n+1 FROM nums WHERE n < 5 +-- +CTE: "nums" +FILTER: schema="" table="" column="n" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW nums (n) AS WITH RECURSIVE nums(n) AS (VALUES (1) UNION ALL SELECT n + 1 FROM nums WH..." +== 007 +-- truncate_limit: 100 +SELECT * FROM nums +-- +TABLE: name="nums" schema="" table="nums" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nums" +== 008 +-- truncate_limit: 100 +CREATE OR REPLACE RECURSIVE VIEW nums (n) AS + VALUES (1) +UNION ALL + SELECT n+1 FROM nums WHERE n < 6 +-- +CTE: "nums" +FILTER: schema="" table="" column="n" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE OR REPLACE VIEW nums (n) AS WITH RECURSIVE nums(n) AS (VALUES (1) UNION ALL SELECT n + 1 F..." +== 009 +-- truncate_limit: 100 +SELECT * FROM nums +-- +TABLE: name="nums" schema="" table="nums" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM nums" +== 010 +-- truncate_limit: 100 +-- This is an infinite loop with UNION ALL, but not with UNION +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT 10-n FROM t) +SELECT * FROM t +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (SELECT 1 UNION SELECT 10 - n FROM t) SELECT * FROM t" +== 011 +-- truncate_limit: 100 +-- This'd be an infinite loop, but outside query reads only as much as needed +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10 +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (VALUES (1) UNION ALL SELECT n + 1 FROM t) SELECT * FROM t LIMIT 10" +== 012 +-- truncate_limit: 100 +-- UNION case should have same property +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10 +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (SELECT 1 UNION SELECT n + 1 FROM t) SELECT * FROM t LIMIT 10" +== 013 +-- truncate_limit: 100 +-- Test behavior with an unknown-type literal in the WITH +WITH q AS (SELECT 'foo' AS x) +SELECT x, pg_typeof(x) FROM q +-- +CTE: "q" +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH q AS (SELECT 'foo' AS x) SELECT x, pg_typeof(x) FROM q" +== 014 +-- truncate_limit: 100 +WITH RECURSIVE t(n) AS ( + SELECT 'foo' +UNION ALL + SELECT n || ' bar' FROM t WHERE length(n) < 20 +) +SELECT n, pg_typeof(n) FROM t +-- +CTE: "t" +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (...) SELECT n, pg_typeof(n) FROM t" +== 015 +-- truncate_limit: 100 +-- In a perfect world, this would work and resolve the literal as int ... +-- but for now, we have to be content with resolving to text too soon. +WITH RECURSIVE t(n) AS ( + SELECT '7' +UNION ALL + SELECT n+1 FROM t WHERE n < 10 +) +SELECT n, pg_typeof(n) FROM t +-- +CTE: "t" +FUNCTION: name="pg_typeof" function="pg_typeof" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(n) AS (...) SELECT n, pg_typeof(n) FROM t" +== 016 +-- truncate_limit: 100 +-- Deeply nested WITH caused a list-munging problem in v13 +-- Detection of cross-references and self-references +WITH RECURSIVE w1(c1) AS + (WITH w2(c2) AS + (WITH w3(c3) AS + (WITH w4(c4) AS + (WITH w5(c5) AS + (WITH RECURSIVE w6(c6) AS + (WITH w6(c6) AS + (WITH w8(c8) AS + (SELECT 1) + SELECT * FROM w8) + SELECT * FROM w6) + SELECT * FROM w6) + SELECT * FROM w5) + SELECT * FROM w4) + SELECT * FROM w3) + SELECT * FROM w2) +SELECT * FROM w1 +-- +CTE: "w1" +CTE: "w2" +CTE: "w3" +CTE: "w4" +CTE: "w5" +CTE: "w6" +CTE: "w6" +CTE: "w8" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE w1(c1) AS (WITH w2(c2) AS (...) SELECT * FROM w2) SELECT * FROM w1" +== 017 +-- truncate_limit: 100 +-- Detection of invalid self-references +WITH RECURSIVE outermost(x) AS ( + SELECT 1 + UNION (WITH innermost1 AS ( + SELECT 2 + UNION (WITH innermost2 AS ( + SELECT 3 + UNION (WITH innermost3 AS ( + SELECT 4 + UNION (WITH innermost4 AS ( + SELECT 5 + UNION (WITH innermost5 AS ( + SELECT 6 + UNION (WITH innermost6 AS + (SELECT 7) + SELECT * FROM innermost6)) + SELECT * FROM innermost5)) + SELECT * FROM innermost4)) + SELECT * FROM innermost3)) + SELECT * FROM innermost2)) + SELECT * FROM outermost + UNION SELECT * FROM innermost1) + ) + SELECT * FROM outermost ORDER BY 1 +-- +CTE: "outermost" +CTE: "innermost1" +CTE: "innermost2" +CTE: "innermost3" +CTE: "innermost4" +CTE: "innermost5" +CTE: "innermost6" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE outermost(x) AS (...) SELECT * FROM outermost ORDER BY 1" +== 018 +-- truncate_limit: 100 +|-- +-- Some examples with a tree +|-- +-- department structure represented here is as follows: +|-- +-- ROOT-+->A-+->B-+->C +-- | | +-- | +->D-+->F +-- +->E-+->G + +CREATE TEMP TABLE department ( + id INTEGER PRIMARY KEY, -- department ID + parent_department INTEGER REFERENCES department, -- upper department ID + name TEXT -- department name +) +-- +TABLE: name="department" schema="" table="department" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE department (id int PRIMARY KEY, parent_department int REFERENCES departmen..." +== 019 +-- truncate_limit: 100 +INSERT INTO department VALUES (0, NULL, 'ROOT') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (0, NULL, 'ROOT')" +== 020 +-- truncate_limit: 100 +INSERT INTO department VALUES (1, 0, 'A') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (1, 0, 'A')" +== 021 +-- truncate_limit: 100 +INSERT INTO department VALUES (2, 1, 'B') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (2, 1, 'B')" +== 022 +-- truncate_limit: 100 +INSERT INTO department VALUES (3, 2, 'C') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (3, 2, 'C')" +== 023 +-- truncate_limit: 100 +INSERT INTO department VALUES (4, 2, 'D') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (4, 2, 'D')" +== 024 +-- truncate_limit: 100 +INSERT INTO department VALUES (5, 0, 'E') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (5, 0, 'E')" +== 025 +-- truncate_limit: 100 +INSERT INTO department VALUES (6, 4, 'F') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (6, 4, 'F')" +== 026 +-- truncate_limit: 100 +INSERT INTO department VALUES (7, 5, 'G') +-- +TABLE: name="department" schema="" table="department" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO department VALUES (7, 5, 'G')" +== 027 +-- truncate_limit: 100 +-- extract all departments under 'A'. Result should be A, B, C, D and F +WITH RECURSIVE subdepartment AS +( + -- non recursive term + SELECT name as root_name, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE subdepartment AS (...) SELECT * FROM subdepartment ORDER BY name" +== 028 +-- truncate_limit: 100 +-- extract all departments under 'A' with "level" number +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE subdepartment(level, id, parent_department, name) AS (...) SELECT * FROM subdepart..." +== 029 +-- truncate_limit: 100 +-- extract all departments under 'A' with "level" number. +-- Only shows level 2 or more +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment WHERE level >= 2 ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="level" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE subdepartment(level, id, parent_department, name) AS (...) SELECT * FROM subdepart..." +== 030 +-- truncate_limit: 100 +-- "RECURSIVE" is ignored if the query has no self-reference +WITH RECURSIVE subdepartment AS +( + -- note lack of recursive UNION structure + SELECT * FROM department WHERE name = 'A' +) +SELECT * FROM subdepartment ORDER BY name +-- +TABLE: name="department" schema="" table="department" ctx=Select +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE subdepartment AS (...) SELECT * FROM subdepartment ORDER BY name" +== 031 +-- truncate_limit: 100 +-- inside subqueries +SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 500 + ) + SELECT * FROM t) AS t WHERE n < ( + SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 100 + ) + SELECT * FROM t WHERE n < 50000 + ) AS t WHERE n < 100) +-- +CTE: "t" +CTE: "t" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "SELECT count(*) FROM (WITH RECURSIVE t(n) AS (...) SELECT * FROM t) t WHERE ..." +== 032 +-- truncate_limit: 100 +-- use same CTE twice at different subquery levels +WITH q1(x,y) AS ( + SELECT hundred, sum(ten) FROM tenk1 GROUP BY hundred + ) +SELECT count(*) FROM q1 WHERE y > (SELECT sum(y)/100 FROM q1 qsub) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "qsub"="q1" +CTE: "q1" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="y" +STMT: SelectStmt +TRUNCATED: "WITH q1(x, y) AS (...) SELECT count(*) FROM q1 WHERE y > (SELECT sum(y) / 100 FROM q1 qsub)" +== 033 +-- truncate_limit: 100 +-- via a VIEW +CREATE TEMPORARY VIEW vsubdepartment AS + WITH RECURSIVE subdepartment AS + ( + -- non recursive term + SELECT * FROM department WHERE name = 'A' + UNION ALL + -- recursive term + SELECT d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id + ) + SELECT * FROM subdepartment +-- +TABLE: name="vsubdepartment" schema="" table="vsubdepartment" ctx=DDL +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +ALIAS: "d"="department" +ALIAS: "sd"="subdepartment" +CTE: "subdepartment" +FILTER: schema="" table="" column="name" +FILTER: schema="" table="d" column="parent_department" +FILTER: schema="" table="sd" column="id" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW vsubdepartment AS WITH RECURSIVE subdepartment AS (SELECT * FROM department..." +== 034 +-- truncate_limit: 100 +SELECT * FROM vsubdepartment ORDER BY name +-- +TABLE: name="vsubdepartment" schema="" table="vsubdepartment" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM vsubdepartment ORDER BY name" +== 035 +-- truncate_limit: 100 +-- Check reverse listing +SELECT pg_get_viewdef('vsubdepartment'::regclass) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vsubdepartment'::regclass)" +== 036 +-- truncate_limit: 100 +SELECT pg_get_viewdef('vsubdepartment'::regclass, true) +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('vsubdepartment'::regclass, true)" +== 037 +-- truncate_limit: 100 +-- Another reverse-listing example +CREATE VIEW sums_1_100 AS +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t +-- +TABLE: name="sums_1_100" schema="" table="sums_1_100" ctx=DDL +CTE: "t" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +FILTER: schema="" table="" column="n" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW sums_1_100 AS WITH RECURSIVE t(n) AS (VALUES (1) UNION ALL SELECT n + 1 FROM t WHERE ..." +== 038 +-- truncate_limit: 100 +-- corner case in which sub-WITH gets initialized first +with recursive q as ( + select * from department + union all + (with x as (select * from q) + select * from x) + ) +select * from q limit 24 +-- +TABLE: name="department" schema="" table="department" ctx=Select +CTE: "q" +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE q AS (...) SELECT * FROM q LIMIT 24" +== 039 +-- truncate_limit: 100 +with recursive q as ( + select * from department + union all + (with recursive x as ( + select * from department + union all + (select * from q union all select * from x) + ) + select * from x) + ) +select * from q limit 32 +-- +TABLE: name="department" schema="" table="department" ctx=Select +TABLE: name="department" schema="" table="department" ctx=Select +CTE: "q" +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE q AS (...) SELECT * FROM q LIMIT 32" +== 040 +-- truncate_limit: 100 +-- 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 +-- +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(i, j) AS (...) SELECT * FROM t" +== 041 +-- truncate_limit: 100 +|-- +-- different tree example +|-- +CREATE TEMPORARY TABLE tree( + id INTEGER PRIMARY KEY, + parent_id INTEGER REFERENCES tree(id) +) +-- +TABLE: name="tree" schema="" table="tree" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE tree (id int PRIMARY KEY, parent_id int REFERENCES tree (id))" +== 042 +-- truncate_limit: 100 +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) +-- +TABLE: name="tree" schema="" table="tree" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO tree VALUES (...)" +== 043 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="tree" schema="" table="tree" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +CTE: "t" +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(id, path) AS (...) SELECT ... FROM t t1 JOIN t t2 ON t1.path[1] = t2.path[1] AND..." +== 044 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="tree" schema="" table="tree" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +CTE: "t" +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +FUNCTION: name="array_upper" function="array_upper" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(id, path) AS (...) SELECT ... FROM t t1 JOIN t t2 ON t1.path[1] = t2.path[1] AND..." +== 045 +-- truncate_limit: 100 +-- 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) +-- +TABLE: name="tree" schema="" table="tree" ctx=Select +ALIAS: "t1"="t" +ALIAS: "t2"="t" +CTE: "t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(id, path) AS (...) SELECT t1.id, t2.path, t2 FROM t t1 JOIN t t2 ON t1.id = t2.id" +== 046 +-- truncate_limit: 100 +CREATE TEMP TABLE duplicates (a INT NOT NULL) +-- +TABLE: name="duplicates" schema="" table="duplicates" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE duplicates (a int NOT NULL)" +== 047 +-- truncate_limit: 100 +INSERT INTO duplicates VALUES(1), (1) +-- +TABLE: name="duplicates" schema="" table="duplicates" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO duplicates VALUES (1), (1)" +== 048 +-- truncate_limit: 100 +-- Try out a recursive UNION case where the non-recursive part's table slot +-- uses TTSOpsBufferHeapTuple and contains duplicate rows. +WITH RECURSIVE cte (a) as ( + SELECT a FROM duplicates + UNION + SELECT a FROM cte +) +SELECT a FROM cte +-- +TABLE: name="duplicates" schema="" table="duplicates" ctx=Select +CTE: "cte" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE cte(a) AS (SELECT a FROM duplicates UNION SELECT a FROM cte) SELECT a FROM cte" +== 049 +-- truncate_limit: 100 +-- test that column statistics from a materialized CTE are available +-- to upper planner (otherwise, we'd get a stupider plan) +explain (costs off) +with x as materialized (select unique1 from tenk1 b) +select count(*) from tenk1 a + where unique1 in (select * from x) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) WITH x AS MATERIALIZED (SELECT unique1 FROM tenk1 b) SELECT count(*) FROM ten..." +== 050 +-- truncate_limit: 100 +explain (costs off) +with x as materialized (insert into tenk1 default values returning unique1) +select count(*) from tenk1 a + where unique1 in (select * from x) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=DML +ALIAS: "a"="tenk1" +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "EXPLAIN (COSTS OFF) WITH x AS MATERIALIZED (INSERT INTO tenk1 DEFAULT VALUES RETURNING unique1) S..." +== 051 +-- truncate_limit: 100 +-- test that pathkeys from a materialized CTE are propagated up to the +-- outer query +explain (costs off) +with x as materialized (select unique1 from tenk1 b order by unique1) +select count(*) from tenk1 a + where unique1 in (select * from x) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +ALIAS: "a"="tenk1" +ALIAS: "b"="tenk1" +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +FILTER: schema="" table="" column="unique1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) WITH x AS MATERIALIZED (SELECT unique1 FROM tenk1 b ORDER BY unique1) SELECT ..." +== 052 +-- truncate_limit: 100 +-- SEARCH clause + +create temp table graph0( f int, t int, label text ) +-- +TABLE: name="graph0" schema="" table="graph0" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE graph0 (f int, t int, label text)" +== 053 +-- truncate_limit: 100 +insert into graph0 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') +-- +TABLE: name="graph0" schema="" table="graph0" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO graph0 VALUES (...)" +== 054 +-- truncate_limit: 100 +explain (verbose, costs off) +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE search_graph(f, t, label) AS (SELECT * FROM graph0 g ..." +== 055 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET seq SELECT * FRO..." +== 056 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union distinct + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET seq SELECT * FRO..." +== 057 +-- truncate_limit: 100 +explain (verbose, costs off) +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE search_graph(f, t, label) AS (SELECT * FROM graph0 g ..." +== 058 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH BREADTH FIRST BY f, t SET seq SELECT * F..." +== 059 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union distinct + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH BREADTH FIRST BY f, t SET seq SELECT * F..." +== 060 +-- truncate_limit: 100 +-- a constant initial value causes issues for EXPLAIN +explain (verbose, costs off) +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search depth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE test AS (SELECT 1 AS x UNION ALL SELECT x + 1 FROM te..." +== 061 +-- truncate_limit: 100 +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search depth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE test AS (...) SEARCH DEPTH FIRST BY x SET y SELECT * FROM test LIMIT 5" +== 062 +-- truncate_limit: 100 +explain (verbose, costs off) +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search breadth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE test AS (SELECT 1 AS x UNION ALL SELECT x + 1 FROM te..." +== 063 +-- truncate_limit: 100 +with recursive test as ( + select 1 as x + union all + select x + 1 + from test +) search breadth first by x set y +select * from test limit 5 +-- +CTE: "test" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE test AS (...) SEARCH BREADTH FIRST BY x SET y SELECT * FROM test LIMIT 5" +== 064 +-- truncate_limit: 100 +-- various syntax errors +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by foo, tar set seq +select * from search_graph +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY foo, tar SET seq SELECT *..." +== 065 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set label +select * from search_graph +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET label SELECT * F..." +== 066 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t, f set seq +select * from search_graph +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t, f SET seq SELECT * ..." +== 067 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET seq SELECT * FRO..." +== 068 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + (select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t) +) search depth first by f, t set seq +select * from search_graph order by seq +-- +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET seq SELECT * FRO..." +== 069 +-- truncate_limit: 100 +-- check that we distinguish same CTE name used at different levels +-- (this case could be supported, perhaps, but it isn't today) +with recursive x(col) as ( + select 1 + union + (with x as (select * from x) + select * from x) +) search depth first by col set seq +select * from x +-- +CTE: "x" +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(col) AS (...) SEARCH DEPTH FIRST BY col SET seq SELECT * FROM x" +== 070 +-- truncate_limit: 100 +-- test ruleutils and view expansion +create temp view v_search as +with recursive search_graph(f, t, label) as ( + select * from graph0 g + union all + select g.* + from graph0 g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq +select f, t, label from search_graph +-- +TABLE: name="v_search" schema="" table="v_search" ctx=DDL +TABLE: name="graph0" schema="" table="graph0" ctx=Select +TABLE: name="graph0" schema="" table="graph0" ctx=Select +ALIAS: "g"="graph0" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v_search AS WITH RECURSIVE search_graph(f, t, label) AS (SELECT * FROM grap..." +== 071 +-- truncate_limit: 100 +select pg_get_viewdef('v_search') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_search')" +== 072 +-- truncate_limit: 100 +select * from v_search +-- +TABLE: name="v_search" schema="" table="v_search" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_search" +== 073 +-- truncate_limit: 100 +|-- +-- test cycle detection +|-- +create temp table graph( f int, t int, label text ) +-- +TABLE: name="graph" schema="" table="graph" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE graph (f int, t int, label text)" +== 074 +-- truncate_limit: 100 +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') +-- +TABLE: name="graph" schema="" table="graph" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO graph VALUES (...)" +== 075 +-- truncate_limit: 100 +with recursive search_graph(f, t, label, is_cycle, path) as ( + select *, false, array[row(g.f, g.t)] from graph g + union all + select g.*, row(g.f, g.t) = any(path), path || row(g.f, g.t) + from graph g, search_graph sg + where g.f = sg.t and not is_cycle +) +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label, is_cycle, path) AS (...) SELECT * FROM search_graph" +== 076 +-- truncate_limit: 100 +-- UNION DISTINCT exercises row type hashing support +with recursive search_graph(f, t, label, is_cycle, path) as ( + select *, false, array[row(g.f, g.t)] from graph g + union distinct + select g.*, row(g.f, g.t) = any(path), path || row(g.f, g.t) + from graph g, search_graph sg + where g.f = sg.t and not is_cycle +) +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label, is_cycle, path) AS (...) SELECT * FROM search_graph" +== 077 +-- truncate_limit: 100 +-- ordering by the path column has same effect as SEARCH DEPTH FIRST +with recursive search_graph(f, t, label, is_cycle, path) as ( + select *, false, array[row(g.f, g.t)] from graph g + union all + select g.*, row(g.f, g.t) = any(path), path || row(g.f, g.t) + from graph g, search_graph sg + where g.f = sg.t and not is_cycle +) +select * from search_graph order by path +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label, is_cycle, path) AS (...) SELECT * FROM search_graph ORDE..." +== 078 +-- truncate_limit: 100 +-- CYCLE clause + +explain (verbose, costs off) +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE search_graph(f, t, label) AS (SELECT * FROM graph g U..." +== 079 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t SET is_cycle TO true DEFAULT false U..." +== 080 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union distinct + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to 'Y' default 'N' using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t SET is_cycle TO 'Y' DEFAULT 'N' USIN..." +== 081 +-- truncate_limit: 100 +explain (verbose, costs off) +with recursive test as ( + select 0 as x + union all + select (x + 1) % 10 + from test +) cycle x set is_cycle using path +select * from test +-- +CTE: "test" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH RECURSIVE test AS (SELECT 0 AS x UNION ALL SELECT (x + 1) % 10 ..." +== 082 +-- truncate_limit: 100 +with recursive test as ( + select 0 as x + union all + select (x + 1) % 10 + from test +) cycle x set is_cycle using path +select * from test +-- +CTE: "test" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE test AS (...) CYCLE x SET is_cycle TO true DEFAULT false USING path SELECT * FROM ..." +== 083 +-- truncate_limit: 100 +with recursive test as ( + select 0 as x + union all + select (x + 1) % 10 + from test + where not is_cycle -- redundant, but legal +) cycle x set is_cycle using path +select * from test +-- +CTE: "test" +FILTER: schema="" table="" column="is_cycle" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE test AS (...) CYCLE x SET is_cycle TO true DEFAULT false USING path SELECT * FROM ..." +== 084 +-- truncate_limit: 100 +-- multiple CTEs +with recursive +graph(f, t, label) as ( + 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') +), +search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to true default false using path +select f, t, label from search_graph +-- +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE graph(f, t, label) AS (...), search_graph(f, t, label) AS (...) CYCLE f, t SET is_..." +== 085 +-- truncate_limit: 100 +-- star expansion +with recursive a as ( + select 1 as b + union all + select * from a +) cycle b set c using p +select * from a +-- +CTE: "a" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE a AS (...) CYCLE b SET c TO true DEFAULT false USING p SELECT * FROM a" +== 086 +-- truncate_limit: 100 +-- search+cycle +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search depth first by f, t set seq + cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET seq CYCLE f, t S..." +== 087 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search breadth first by f, t set seq + cycle f, t set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH BREADTH FIRST BY f, t SET seq CYCLE f, t..." +== 088 +-- truncate_limit: 100 +-- various syntax errors +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle foo, tar set is_cycle using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE foo, tar SET is_cycle TO true DEFAULT fal..." +== 089 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to true default 55 using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t SET is_cycle TO true DEFAULT 55 USIN..." +== 090 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to point '(1,1)' default point '(0,0)' using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t SET is_cycle TO point '(1,1)' DEFAU..." +== 091 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set label to true default false using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t SET label TO true DEFAULT false USIN..." +== 092 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to true default false using label +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t SET is_cycle TO true DEFAULT false U..." +== 093 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set foo to true default false using foo +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t SET foo TO true DEFAULT false USING ..." +== 094 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t, f set is_cycle to true default false using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) CYCLE f, t, f SET is_cycle TO true DEFAULT fals..." +== 095 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search depth first by f, t set foo + cycle f, t set foo to true default false using path +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET foo CYCLE f, t S..." +== 096 +-- truncate_limit: 100 +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) search depth first by f, t set foo + cycle f, t set is_cycle to true default false using foo +select * from search_graph +-- +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE search_graph(f, t, label) AS (...) SEARCH DEPTH FIRST BY f, t SET foo CYCLE f, t S..." +== 097 +-- truncate_limit: 100 +-- test ruleutils and view expansion +create temp view v_cycle1 as +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle using path +select f, t, label from search_graph +-- +TABLE: name="v_cycle1" schema="" table="v_cycle1" ctx=DDL +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v_cycle1 AS WITH RECURSIVE search_graph(f, t, label) AS (SELECT * FROM grap..." +== 098 +-- truncate_limit: 100 +create temp view v_cycle2 as +with recursive search_graph(f, t, label) as ( + select * from graph g + union all + select g.* + from graph g, search_graph sg + where g.f = sg.t +) cycle f, t set is_cycle to 'Y' default 'N' using path +select f, t, label from search_graph +-- +TABLE: name="v_cycle2" schema="" table="v_cycle2" ctx=DDL +TABLE: name="graph" schema="" table="graph" ctx=Select +TABLE: name="graph" schema="" table="graph" ctx=Select +ALIAS: "g"="graph" +ALIAS: "sg"="search_graph" +CTE: "search_graph" +FILTER: schema="" table="g" column="f" +FILTER: schema="" table="sg" column="t" +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY VIEW v_cycle2 AS WITH RECURSIVE search_graph(f, t, label) AS (SELECT * FROM grap..." +== 099 +-- truncate_limit: 100 +select pg_get_viewdef('v_cycle1') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_cycle1')" +== 100 +-- truncate_limit: 100 +select pg_get_viewdef('v_cycle2') +-- +FUNCTION: name="pg_get_viewdef" function="pg_get_viewdef" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_get_viewdef('v_cycle2')" +== 101 +-- truncate_limit: 100 +select * from v_cycle1 +-- +TABLE: name="v_cycle1" schema="" table="v_cycle1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_cycle1" +== 102 +-- truncate_limit: 100 +select * from v_cycle2 +-- +TABLE: name="v_cycle2" schema="" table="v_cycle2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM v_cycle2" +== 103 +-- truncate_limit: 100 +|-- +-- 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 +-- +CTE: "y" +CTE: "x" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE y(id) AS (VALUES (1)), x(id) AS (...) SELECT * FROM x" +== 104 +-- truncate_limit: 100 +-- 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 +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(id) AS (...), y(id) AS (VALUES (1)) SELECT * FROM x" +== 105 +-- truncate_limit: 100 +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) +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(id) AS (...), y(id) AS (...) SELECT y.*, x.* FROM y LEFT JOIN x USING (id)" +== 106 +-- truncate_limit: 100 +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) +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(id) AS (...), y(id) AS (...) SELECT y.*, x.* FROM y LEFT JOIN x USING (id)" +== 107 +-- truncate_limit: 100 +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 +-- +CTE: "x" +CTE: "y" +CTE: "z" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(id) AS (...), y(id) AS (...), z(id) AS (...) SELECT * FROM z" +== 108 +-- truncate_limit: 100 +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 +-- +CTE: "x" +CTE: "y" +CTE: "z" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(id) AS (...), y(id) AS (...), z(id) AS (...) SELECT * FROM z" +== 109 +-- truncate_limit: 100 +|-- +-- Test WITH attached to a data-modifying statement +|-- + +CREATE TEMPORARY TABLE y (a INTEGER) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE y (a int)" +== 110 +-- truncate_limit: 100 +INSERT INTO y SELECT generate_series(1, 10) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y SELECT generate_series(1, 10)" +== 111 +-- truncate_limit: 100 +WITH t AS ( + SELECT a FROM y +) +INSERT INTO y +SELECT a+20 FROM t RETURNING * +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "t" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH t AS (SELECT a FROM y) INSERT INTO y SELECT a + 20 FROM t RETURNING *" +== 112 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 113 +-- truncate_limit: 100 +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 +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "t" +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "WITH t AS (...) UPDATE y SET a = y.a - 10 FROM t WHERE y.a > 20 AND t.a = y.a RETURNING y.a" +== 114 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 115 +-- truncate_limit: 100 +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 +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +FILTER: schema="" table="" column="a" +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(a) AS (...) DELETE FROM y USING t WHERE t.a = y.a RETURNING y.a" +== 116 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 117 +-- truncate_limit: 100 +DROP TABLE y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE y" +== 118 +-- truncate_limit: 100 +|-- +-- error cases +|-- + +WITH x(n, b) AS (SELECT 1) +SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH x(n, b) AS (SELECT 1) SELECT * FROM x" +== 119 +-- truncate_limit: 100 +-- INTERSECT +WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n + 1 FROM x) SELECT * FROM x" +== 120 +-- truncate_limit: 100 +WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n + 1 FROM x) SELECT * FROM x" +== 121 +-- truncate_limit: 100 +-- EXCEPT +WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n + 1 FROM x) SELECT * FROM x" +== 122 +-- truncate_limit: 100 +WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n + 1 FROM x) SELECT * FROM x" +== 123 +-- truncate_limit: 100 +-- no non-recursive term +WITH RECURSIVE x(n) AS (SELECT n FROM x) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT n FROM x) SELECT * FROM x" +== 124 +-- truncate_limit: 100 +-- 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 +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1) SELECT * FROM x" +== 125 +-- truncate_limit: 100 +-- allow this, because we historically have +WITH RECURSIVE x(n) AS ( + WITH x1 AS (SELECT 1 AS n) + SELECT 0 + UNION + SELECT * FROM x1) + SELECT * FROM x +-- +CTE: "x" +CTE: "x1" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (WITH x1 AS (SELECT 1 AS n) SELECT 0 UNION SELECT * FROM x1) SELECT * FROM x" +== 126 +-- truncate_limit: 100 +-- but this should be rejected +WITH RECURSIVE x(n) AS ( + WITH x1 AS (SELECT 1 FROM x) + SELECT 0 + UNION + SELECT * FROM x1) + SELECT * FROM x +-- +CTE: "x" +CTE: "x1" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (WITH x1 AS (...) SELECT 0 UNION SELECT * FROM x1) SELECT * FROM x" +== 127 +-- truncate_limit: 100 +-- and this too +WITH RECURSIVE x(n) AS ( + (WITH x1 AS (SELECT 1 FROM x) SELECT * FROM x1) + UNION + SELECT 0) + SELECT * FROM x +-- +CTE: "x" +CTE: "x1" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS ((WITH x1 AS (...) SELECT * FROM x1) UNION SELECT 0) SELECT * FROM x" +== 128 +-- truncate_limit: 100 +-- and this +WITH RECURSIVE x(n) AS ( + SELECT 0 UNION SELECT 1 + ORDER BY (SELECT n FROM x)) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 0 UNION SELECT 1 ORDER BY (SELECT n FROM x)) SELECT * FROM x" +== 129 +-- truncate_limit: 100 +-- and this +WITH RECURSIVE x(n) AS ( + WITH sub_cte AS (SELECT * FROM x) + DELETE FROM graph RETURNING f) + SELECT * FROM x +-- +TABLE: name="graph" schema="" table="graph" ctx=DML +CTE: "x" +CTE: "sub_cte" +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (WITH sub_cte AS (...) DELETE FROM graph RETURNING f) SELECT * FROM x" +== 130 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE y (a INTEGER) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE y (a int)" +== 131 +-- truncate_limit: 100 +INSERT INTO y SELECT generate_series(1, 10) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y SELECT generate_series(1, 10)" +== 132 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (...) SELECT * FROM x" +== 133 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (...) SELECT * FROM x" +== 134 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "x" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (...) SELECT * FROM x" +== 135 +-- truncate_limit: 100 +-- subquery +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x + WHERE n IN (SELECT * FROM x)) + SELECT * FROM x +-- +CTE: "x" +FILTER: schema="" table="" column="n" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM x WHERE ...) SELECT * FROM x" +== 136 +-- truncate_limit: 100 +-- aggregate functions +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x) + SELECT * FROM x +-- +CTE: "x" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x) SELECT * FROM x" +== 137 +-- truncate_limit: 100 +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x) + SELECT * FROM x +-- +CTE: "x" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x) SELECT * FROM x" +== 138 +-- truncate_limit: 100 +-- ORDER BY +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM x ORDER BY 1) SELECT * FROM x" +== 139 +-- truncate_limit: 100 +-- LIMIT/OFFSET +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM x LIMIT 10 OFFSET 1) SELECT * FROM x" +== 140 +-- truncate_limit: 100 +-- FOR UPDATE +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE) + SELECT * FROM x +-- +CTE: "x" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM x FOR UPDATE) SELECT * FROM x" +== 141 +-- truncate_limit: 100 +-- 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 +-- +CTE: "x" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(id) AS (VALUES (1) UNION ALL SELECT ... FROM x WHERE id < 5) SELECT * FROM x" +== 142 +-- truncate_limit: 100 +-- 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 +-- +CTE: "x" +CTE: "y" +FILTER: schema="" table="" column="id" +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE x(id) AS (...), y(id) AS (...) SELECT * FROM x" +== 143 +-- truncate_limit: 100 +-- 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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(i) AS (...) SELECT * FROM foo" +== 144 +-- truncate_limit: 100 +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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(i) AS (...) SELECT * FROM foo" +== 145 +-- truncate_limit: 100 +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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(i) AS (...) SELECT * FROM foo" +== 146 +-- truncate_limit: 100 +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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(i) AS (...) SELECT * FROM foo" +== 147 +-- truncate_limit: 100 +-- 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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(i) AS (...) SELECT * FROM foo" +== 148 +-- truncate_limit: 100 +-- 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 +-- +CTE: "foo" +FILTER: schema="" table="" column="i" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE foo(i) AS (...) SELECT * FROM foo" +== 149 +-- truncate_limit: 100 +-- disallow OLD/NEW reference in CTE +CREATE TEMPORARY TABLE x (n integer) +-- +TABLE: name="x" schema="" table="x" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE x (n int)" +== 150 +-- truncate_limit: 100 +CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD + WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t +-- +TABLE: name="x" schema="" table="x" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD WITH t AS (SELECT old.*) UPDATE y SET a = t.n FROM t" +== 151 +-- truncate_limit: 100 +|-- +-- test for bug #4902 +|-- +with cte(foo) as ( values(42) ) values((select foo from cte)) +-- +CTE: "cte" +STMT: SelectStmt +TRUNCATED: "WITH cte(foo) AS (VALUES (42)) VALUES ((SELECT foo FROM cte))" +== 152 +-- truncate_limit: 100 +with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q +-- +CTE: "cte" +STMT: SelectStmt +TRUNCATED: "WITH cte(foo) AS (SELECT 42) SELECT * FROM (SELECT foo FROM cte) q" +== 153 +-- truncate_limit: 100 +-- 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 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "cte" +STMT: SelectStmt +TRUNCATED: "SELECT (WITH cte(foo) AS (VALUES (f1)) SELECT (SELECT foo FROM cte)) FROM int4_tbl" +== 154 +-- truncate_limit: 100 +select ( with cte(foo) as ( values(f1) ) + values((select foo from cte)) ) +from int4_tbl +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +CTE: "cte" +STMT: SelectStmt +TRUNCATED: "SELECT (WITH cte(foo) AS (VALUES (f1)) VALUES ((SELECT foo FROM cte))) FROM int4_tbl" +== 155 +-- truncate_limit: 100 +|-- +-- test for bug #19055: interaction of WITH with aggregates +|-- +-- The reference to cte1 must determine the aggregate's level, +-- even though it contains no Vars referencing cte1 +explain (verbose, costs off) +select f1, (with cte1(x,y) as (select 1,2) + select count((select i4.f1 from cte1))) as ss +from int4_tbl i4 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +CTE: "cte1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT f1, (WITH cte1(x, y) AS (SELECT 1, 2) SELECT count((SELECT i4..." +== 156 +-- truncate_limit: 100 +select f1, (with cte1(x,y) as (select 1,2) + select count((select i4.f1 from cte1))) as ss +from int4_tbl i4 +-- +TABLE: name="int4_tbl" schema="" table="int4_tbl" ctx=Select +ALIAS: "i4"="int4_tbl" +CTE: "cte1" +FUNCTION: name="count" function="count" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT f1, (WITH cte1(x, y) AS (...) SELECT count((SELECT ... FROM cte1))) AS ss FROM int4_tbl i4" +== 157 +-- truncate_limit: 100 +|-- +-- 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 +-- +CTE: "t" +CTE: "s" +FILTER: schema="" table="" column="i" +FILTER: schema="" table="" column="j" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE t(j) AS (...) SELECT * FROM t" +== 158 +-- truncate_limit: 100 +|-- +-- 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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +TRUNCATED: "WITH outermost(x) AS (...) SELECT * FROM outermost ORDER BY 1" +== 159 +-- truncate_limit: 100 +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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +TRUNCATED: "WITH outermost(x) AS (...) SELECT * FROM outermost ORDER BY 1" +== 160 +-- truncate_limit: 100 +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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE outermost(x) AS (...) SELECT * FROM outermost ORDER BY 1" +== 161 +-- truncate_limit: 100 +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 +-- +CTE: "outermost" +CTE: "innermost" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE outermost(x) AS (...) SELECT * FROM outermost ORDER BY 1" +== 162 +-- truncate_limit: 100 +|-- +-- 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 +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +CTE: "a" +CTE: "b" +CTE: "c" +FUNCTION: name="row_number" function="row_number" schema="" ctx=Call +FILTER: schema="" table="b" column="id" +FILTER: schema="" table="a" column="id" +STMT: SelectStmt +TRUNCATED: "WITH a AS (SELECT ... FROM int8_tbl), b AS (SELECT ... FROM a), c AS (...) SELECT * FROM c" +== 163 +-- truncate_limit: 100 +|-- +-- 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' + ) + SELECT * FROM first_remaining + UNION ALL SELECT * FROM effect + ) + ) +SELECT * FROM iter +-- +ALIAS: "e"="first_remaining" +CTE: "tab" +CTE: "iter" +CTE: "remaining" +CTE: "first_remaining" +CTE: "effect" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="tab" column="id_key" +FILTER: schema="" table="iter" column="id_key" +FILTER: schema="" table="" column="id_key" +FILTER: schema="" table="" column="min" +FILTER: schema="" table="e" column="row_type" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE tab(id_key, link) AS (...), iter(id_key, row_type, link) AS (...) SELECT * FROM iter" +== 164 +-- truncate_limit: 100 +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 ( + 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' + ) + SELECT * FROM first_remaining + UNION ALL SELECT * FROM effect + ) + ) +SELECT * FROM iter +-- +ALIAS: "e"="first_remaining" +CTE: "tab" +CTE: "iter" +CTE: "remaining" +CTE: "first_remaining" +CTE: "effect" +FUNCTION: name="min" function="min" schema="" ctx=Call +FILTER: schema="" table="tab" column="id_key" +FILTER: schema="" table="iter" column="id_key" +FILTER: schema="" table="" column="id_key" +FILTER: schema="" table="" column="min" +FILTER: schema="" table="e" column="row_type" +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE tab(id_key, link) AS (...), iter(id_key, row_type, link) AS (...) SELECT * FROM iter" +== 165 +-- truncate_limit: 100 +|-- +-- Data-modifying statements in WITH +|-- + +-- INSERT ... RETURNING +WITH t AS ( + INSERT INTO y + VALUES + (11), + (12), + (13), + (14), + (15), + (16), + (17), + (18), + (19), + (20) + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (...) RETURNING *) SELECT * FROM t" +== 166 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 167 +-- truncate_limit: 100 +-- UPDATE ... RETURNING +WITH t AS ( + UPDATE y + SET a=a+1 + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: UpdateStmt +TRUNCATED: "WITH t AS (UPDATE y SET a = a + 1 RETURNING *) SELECT * FROM t" +== 168 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 169 +-- truncate_limit: 100 +-- DELETE ... RETURNING +WITH t AS ( + DELETE FROM y + WHERE a <= 10 + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH t AS (DELETE FROM y WHERE a <= 10 RETURNING *) SELECT * FROM t" +== 170 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 171 +-- truncate_limit: 100 +-- forward reference +WITH RECURSIVE t AS ( + INSERT INTO y + SELECT a+5 FROM t2 WHERE a > 5 + RETURNING * +), t2 AS ( + UPDATE y SET a=a-11 RETURNING * +) +SELECT * FROM t +UNION ALL +SELECT * FROM t2 +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +CTE: "t2" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +STMT: InsertStmt +STMT: UpdateStmt +TRUNCATED: "WITH RECURSIVE t AS (...), t2 AS (...) SELECT * FROM t UNION ALL SELECT * FROM t2" +== 172 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 173 +-- truncate_limit: 100 +-- unconditional DO INSTEAD rule +CREATE RULE y_rule AS ON DELETE TO y DO INSTEAD + INSERT INTO y VALUES(42) RETURNING * +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE y_rule AS ON DELETE TO y DO INSTEAD INSERT INTO y VALUES (42) RETURNING *" +== 174 +-- truncate_limit: 100 +WITH t AS ( + DELETE FROM y RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH t AS (DELETE FROM y RETURNING *) SELECT * FROM t" +== 175 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 176 +-- truncate_limit: 100 +DROP RULE y_rule ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE y_rule ON y" +== 177 +-- truncate_limit: 100 +-- check merging of outer CTE with CTE in a rule action +CREATE TEMP TABLE bug6051 AS + select i from generate_series(1,3) as t(i) +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE bug6051 AS SELECT i FROM generate_series(1, 3) t(i)" +== 178 +-- truncate_limit: 100 +SELECT * FROM bug6051 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bug6051" +== 179 +-- truncate_limit: 100 +WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) +INSERT INTO bug6051 SELECT * FROM t1 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH t1 AS (DELETE FROM bug6051 RETURNING *) INSERT INTO bug6051 SELECT * FROM t1" +== 180 +-- truncate_limit: 100 +SELECT * FROM bug6051 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bug6051" +== 181 +-- truncate_limit: 100 +CREATE TEMP TABLE bug6051_2 (i int) +-- +TABLE: name="bug6051_2" schema="" table="bug6051_2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE bug6051_2 (i int)" +== 182 +-- truncate_limit: 100 +CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD + INSERT INTO bug6051_2 + VALUES(NEW.i) +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD INSERT INTO bug6051_2 VALUES (new.i)" +== 183 +-- truncate_limit: 100 +WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) +INSERT INTO bug6051 SELECT * FROM t1 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH t1 AS (DELETE FROM bug6051 RETURNING *) INSERT INTO bug6051 SELECT * FROM t1" +== 184 +-- truncate_limit: 100 +SELECT * FROM bug6051 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bug6051" +== 185 +-- truncate_limit: 100 +SELECT * FROM bug6051_2 +-- +TABLE: name="bug6051_2" schema="" table="bug6051_2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bug6051_2" +== 186 +-- truncate_limit: 100 +-- check INSERT ... SELECT rule actions are disallowed on commands +-- that have modifyingCTEs +CREATE OR REPLACE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD + INSERT INTO bug6051_2 + SELECT NEW.i +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD INSERT INTO bug6051_2 SELEC..." +== 187 +-- truncate_limit: 100 +WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) +INSERT INTO bug6051 SELECT * FROM t1 +-- +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +TABLE: name="bug6051" schema="" table="bug6051" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH t1 AS (DELETE FROM bug6051 RETURNING *) INSERT INTO bug6051 SELECT * FROM t1" +== 188 +-- truncate_limit: 100 +-- silly example to verify that hasModifyingCTE flag is propagated +CREATE TEMP TABLE bug6051_3 AS + SELECT a FROM generate_series(11,13) AS a +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TEMPORARY TABLE bug6051_3 AS SELECT a FROM generate_series(11, 13) a" +== 189 +-- truncate_limit: 100 +CREATE RULE bug6051_3_ins AS ON INSERT TO bug6051_3 DO INSTEAD + SELECT i FROM bug6051_2 +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE bug6051_3_ins AS ON INSERT TO bug6051_3 DO INSTEAD SELECT i FROM bug6051_2" +== 190 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 191 +-- truncate_limit: 100 +SET LOCAL debug_parallel_query = on +-- +STMT: VariableSetStmt +TRUNCATED: "SET LOCAL debug_parallel_query TO ON" +== 192 +-- truncate_limit: 100 +WITH t1 AS ( DELETE FROM bug6051_3 RETURNING * ) + INSERT INTO bug6051_3 SELECT * FROM t1 +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DML +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=DML +CTE: "t1" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH t1 AS (DELETE FROM bug6051_3 RETURNING *) INSERT INTO bug6051_3 SELECT * FROM t1" +== 193 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 194 +-- truncate_limit: 100 +SELECT * FROM bug6051_3 +-- +TABLE: name="bug6051_3" schema="" table="bug6051_3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM bug6051_3" +== 195 +-- truncate_limit: 100 +-- check case where CTE reference is removed due to optimization +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT q1 FROM (WITH t_cte AS (SELECT * FROM int8_tbl t) SELECT q1, ..." +== 196 +-- truncate_limit: 100 +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM (WITH t_cte AS (...) SELECT ... FROM int8_tbl i8) ss" +== 197 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT q1 FROM (WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t..." +== 198 +-- truncate_limit: 100 +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss +-- +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=Select +ALIAS: "i8"="int8_tbl" +ALIAS: "t"="int8_tbl" +CTE: "t_cte" +FILTER: schema="" table="t_cte" column="q1" +FILTER: schema="" table="i8" column="q1" +STMT: SelectStmt +TRUNCATED: "SELECT q1 FROM (WITH t_cte AS MATERIALIZED (...) SELECT ... FROM int8_tbl i8) ss" +== 199 +-- truncate_limit: 100 +-- a truly recursive CTE in the same list +WITH RECURSIVE t(a) AS ( + SELECT 0 + UNION ALL + SELECT a+1 FROM t WHERE a+1 < 5 +), t2 as ( + INSERT INTO y + SELECT * FROM t RETURNING * +) +SELECT * FROM t2 JOIN y USING (a) ORDER BY a +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +CTE: "t2" +FILTER: schema="" table="" column="a" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH RECURSIVE t(a) AS (...), t2 AS (...) SELECT * FROM t2 JOIN y USING (a) ORDER BY a" +== 200 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 201 +-- truncate_limit: 100 +-- data-modifying WITH in a modifying statement +WITH t AS ( + DELETE FROM y + WHERE a <= 10 + RETURNING * +) +INSERT INTO y SELECT -a FROM t RETURNING * +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: InsertStmt +STMT: SelectStmt +STMT: DeleteStmt +TRUNCATED: "WITH t AS (DELETE FROM y WHERE a <= 10 RETURNING *) INSERT INTO y SELECT - a FROM t RETURNING *" +== 202 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 203 +-- truncate_limit: 100 +-- check that WITH query is run to completion even if outer query isn't +WITH t AS ( + UPDATE y SET a = a * 100 RETURNING * +) +SELECT * FROM t LIMIT 10 +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: UpdateStmt +TRUNCATED: "WITH t AS (UPDATE y SET a = a * 100 RETURNING *) SELECT * FROM t LIMIT 10" +== 204 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 205 +-- truncate_limit: 100 +-- data-modifying WITH containing INSERT...ON CONFLICT DO UPDATE +CREATE TABLE withz AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i +-- +TABLE: name="withz" schema="" table="withz" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE withz AS SELECT i AS k, (i || ' v')::text AS v FROM generate_series(1, 16, 3) i" +== 206 +-- truncate_limit: 100 +ALTER TABLE withz ADD UNIQUE (k) +-- +TABLE: name="withz" schema="" table="withz" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE withz ADD UNIQUE (k)" +== 207 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO withz SELECT i, 'insert' + FROM generate_series(0, 16) i + ON CONFLICT (k) DO UPDATE SET v = withz.v || ', now update' + RETURNING * +) +SELECT * FROM t JOIN y ON t.k = y.a ORDER BY a, k +-- +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "t" +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (...) SELECT * FROM t JOIN y ON t.k = y.a ORDER BY a, k" +== 208 +-- truncate_limit: 100 +-- Test EXCLUDED.* reference within CTE +WITH aa AS ( + INSERT INTO withz VALUES(1, 5) ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v + WHERE withz.k != EXCLUDED.k + RETURNING * +) +SELECT * FROM aa +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH aa AS (...) SELECT * FROM aa" +== 209 +-- truncate_limit: 100 +-- New query/snapshot demonstrates side-effects of previous query. +SELECT * FROM withz ORDER BY k +-- +TABLE: name="withz" schema="" table="withz" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM withz ORDER BY k" +== 210 +-- truncate_limit: 100 +|-- +-- Ensure subqueries within the update clause work, even if they +-- reference outside values +|-- +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aa AS (...) INSERT INTO withz VALUES (1, 'insert') ON CONFLICT (k) DO UPDATE SET ... = ..." +== 211 +-- truncate_limit: 100 +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = ' update' WHERE withz.k = (SELECT a FROM aa) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aa AS (...) INSERT INTO withz VALUES (...) ON CONFLICT (k) DO UPDATE SET ... = ... WHERE ..." +== 212 +-- truncate_limit: 100 +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aa AS (...) INSERT INTO withz VALUES (1, 'insert') ON CONFLICT (k) DO UPDATE SET ... = ..." +== 213 +-- truncate_limit: 100 +WITH aa AS (SELECT 'a' a, 'b' b UNION ALL SELECT 'a' a, 'b' b) +INSERT INTO withz VALUES(1, 'insert') +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 'a' LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aa AS (...) INSERT INTO withz VALUES (1, 'insert') ON CONFLICT (k) DO UPDATE SET ... = ..." +== 214 +-- truncate_limit: 100 +WITH aa AS (SELECT 1 a, 2 b) +INSERT INTO withz VALUES(1, (SELECT b || ' insert' FROM aa WHERE a = 1 )) +ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1) +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "aa" +FILTER: schema="" table="" column="a" +FILTER: schema="" table="" column="a" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH aa AS (...) INSERT INTO withz VALUES (...) ON CONFLICT (k) DO UPDATE SET ... = ..." +== 215 +-- truncate_limit: 100 +-- Update a row more than once, in different parts of a wCTE. That is +-- an allowed, presumably very rare, edge case, but since it was +-- broken in the past, having a test seems worthwhile. +WITH simpletup AS ( + SELECT 2 k, 'Green' v), +upsert_cte AS ( + INSERT INTO withz VALUES(2, 'Blue') ON CONFLICT (k) DO + UPDATE SET (k, v) = (SELECT k, v FROM simpletup WHERE simpletup.k = withz.k) + RETURNING k, v) +INSERT INTO withz VALUES(2, 'Red') ON CONFLICT (k) DO +UPDATE SET (k, v) = (SELECT k, v FROM upsert_cte WHERE upsert_cte.k = withz.k) +RETURNING k, v +-- +TABLE: name="withz" schema="" table="withz" ctx=DML +TABLE: name="withz" schema="" table="withz" ctx=DML +CTE: "simpletup" +CTE: "upsert_cte" +FILTER: schema="" table="upsert_cte" column="k" +FILTER: schema="" table="withz" column="k" +FILTER: schema="" table="upsert_cte" column="k" +FILTER: schema="" table="withz" column="k" +FILTER: schema="" table="simpletup" column="k" +FILTER: schema="" table="withz" column="k" +FILTER: schema="" table="simpletup" column="k" +FILTER: schema="" table="withz" column="k" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH simpletup AS (...), upsert_cte AS (...) INSERT INTO withz VALUES (...) ON CONFLICT (k) DO UP..." +== 216 +-- truncate_limit: 100 +DROP TABLE withz +-- +TABLE: name="withz" schema="" table="withz" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE withz" +== 217 +-- truncate_limit: 100 +-- WITH referenced by MERGE statement +CREATE TABLE m AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i +-- +TABLE: name="m" schema="" table="m" ctx=DDL +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE m AS SELECT i AS k, (i || ' v')::text AS v FROM generate_series(1, 16, 3) i" +== 218 +-- truncate_limit: 100 +ALTER TABLE m ADD UNIQUE (k) +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE m ADD UNIQUE (k)" +== 219 +-- truncate_limit: 100 +WITH RECURSIVE cte_basic AS (SELECT 1 a, 'cte_basic val' b) +MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_basic" +FILTER: schema="" table="cte_basic" column="a" +FILTER: schema="" table="m" column="k" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "WITH RECURSIVE cte_basic AS (...) MERGE INTO m USING (SELECT ...) o ON m.k = o.k WHEN MATCHED THE..." +== 220 +-- truncate_limit: 100 +-- Basic: +WITH cte_basic AS MATERIALIZED (SELECT 1 a, 'cte_basic val' b) +MERGE INTO m USING (select 0 k, 'merge source SubPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_basic" +FILTER: schema="" table="cte_basic" column="a" +FILTER: schema="" table="m" column="k" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "WITH cte_basic AS MATERIALIZED (...) MERGE INTO m USING (SELECT ... OFFSET 0) o ON m.k = o.k WHEN..." +== 221 +-- truncate_limit: 100 +-- Examine +SELECT * FROM m where k = 0 +-- +TABLE: name="m" schema="" table="m" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM m WHERE k = 0" +== 222 +-- truncate_limit: 100 +-- See EXPLAIN output for same query: +EXPLAIN (VERBOSE, COSTS OFF) +WITH cte_basic AS MATERIALIZED (SELECT 1 a, 'cte_basic val' b) +MERGE INTO m USING (select 0 k, 'merge source SubPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_basic" +FILTER: schema="" table="cte_basic" column="a" +FILTER: schema="" table="m" column="k" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH cte_basic AS MATERIALIZED (SELECT 1 AS a, 'cte_basic val' AS b)..." +== 223 +-- truncate_limit: 100 +-- InitPlan +WITH cte_init AS MATERIALIZED (SELECT 1 a, 'cte_init val' b) +MERGE INTO m USING (select 1 k, 'merge source InitPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_init" +FILTER: schema="" table="" column="a" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "WITH cte_init AS MATERIALIZED (...) MERGE INTO m USING (SELECT ... OFFSET 0) o ON m.k = o.k WHEN ..." +== 224 +-- truncate_limit: 100 +-- Examine +SELECT * FROM m where k = 1 +-- +TABLE: name="m" schema="" table="m" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM m WHERE k = 1" +== 225 +-- truncate_limit: 100 +-- See EXPLAIN output for same query: +EXPLAIN (VERBOSE, COSTS OFF) +WITH cte_init AS MATERIALIZED (SELECT 1 a, 'cte_init val' b) +MERGE INTO m USING (select 1 k, 'merge source InitPlan' v offset 0) o ON m.k=o.k +WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) +WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "cte_init" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH cte_init AS MATERIALIZED (SELECT 1 AS a, 'cte_init val' AS b) M..." +== 226 +-- truncate_limit: 100 +-- MERGE source comes from CTE: +WITH merge_source_cte AS MATERIALIZED (SELECT 15 a, 'merge_source_cte val' b) +MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a +WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) +WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "merge_source_cte" +FILTER: schema="" table="" column="a" +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "WITH merge_source_cte AS MATERIALIZED (...) MERGE INTO m USING (SELECT * FROM merge_source_cte) o..." +== 227 +-- truncate_limit: 100 +-- Examine +SELECT * FROM m where k = 15 +-- +TABLE: name="m" schema="" table="m" ctx=Select +FILTER: schema="" table="" column="k" +STMT: SelectStmt +TRUNCATED: "SELECT * FROM m WHERE k = 15" +== 228 +-- truncate_limit: 100 +-- See EXPLAIN output for same query: +EXPLAIN (VERBOSE, COSTS OFF) +WITH merge_source_cte AS MATERIALIZED (SELECT 15 a, 'merge_source_cte val' b) +MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a +WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) +WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)) +-- +TABLE: name="m" schema="" table="m" ctx=DML +CTE: "merge_source_cte" +FILTER: schema="" table="" column="a" +STMT: ExplainStmt +STMT: MergeStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH merge_source_cte AS MATERIALIZED (SELECT 15 AS a, 'merge_source..." +== 229 +-- truncate_limit: 100 +DROP TABLE m +-- +TABLE: name="m" schema="" table="m" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE m" +== 230 +-- truncate_limit: 100 +-- check that run to completion happens in proper ordering + +TRUNCATE TABLE y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE y" +== 231 +-- truncate_limit: 100 +INSERT INTO y SELECT generate_series(1, 3) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y SELECT generate_series(1, 3)" +== 232 +-- truncate_limit: 100 +CREATE TEMPORARY TABLE yy (a INTEGER) +-- +TABLE: name="yy" schema="" table="yy" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE yy (a int)" +== 233 +-- truncate_limit: 100 +WITH RECURSIVE t1 AS ( + INSERT INTO y SELECT * FROM y RETURNING * +), t2 AS ( + INSERT INTO yy SELECT * FROM t1 RETURNING * +) +SELECT 1 +-- +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +TABLE: name="yy" schema="" table="yy" ctx=DML +CTE: "t1" +CTE: "t2" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH RECURSIVE t1 AS (INSERT INTO y SELECT * FROM y RETURNING *), t2 AS (...) SELECT 1" +== 234 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 235 +-- truncate_limit: 100 +SELECT * FROM yy +-- +TABLE: name="yy" schema="" table="yy" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM yy" +== 236 +-- truncate_limit: 100 +WITH RECURSIVE t1 AS ( + INSERT INTO yy SELECT * FROM t2 RETURNING * +), t2 AS ( + INSERT INTO y SELECT * FROM y RETURNING * +) +SELECT 1 +-- +TABLE: name="yy" schema="" table="yy" ctx=DML +TABLE: name="y" schema="" table="y" ctx=DML +TABLE: name="y" schema="" table="y" ctx=Select +CTE: "t1" +CTE: "t2" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH RECURSIVE t1 AS (...), t2 AS (INSERT INTO y SELECT * FROM y RETURNING *) SELECT 1" +== 237 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 238 +-- truncate_limit: 100 +SELECT * FROM yy +-- +TABLE: name="yy" schema="" table="yy" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM yy" +== 239 +-- truncate_limit: 100 +-- triggers + +TRUNCATE TABLE y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: TruncateStmt +TRUNCATED: "TRUNCATE y" +== 240 +-- truncate_limit: 100 +INSERT INTO y SELECT generate_series(1, 10) +-- +TABLE: name="y" schema="" table="y" ctx=DML +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO y SELECT generate_series(1, 10)" +== 241 +-- truncate_limit: 100 +CREATE FUNCTION y_trigger() RETURNS trigger AS $$ +begin + raise notice 'y_trigger: a = %', new.a; + return new; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="y_trigger" function="y_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION y_trigger() RETURNS trigger AS $$\nbegin\n raise notice 'y_trigger: a = %', new.a;..." +== 242 +-- truncate_limit: 100 +CREATE TRIGGER y_trig BEFORE INSERT ON y FOR EACH ROW + EXECUTE PROCEDURE y_trigger() +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER y_trig BEFORE INSERT ON y FOR EACH ROW EXECUTE FUNCTION y_trigger()" +== 243 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y + VALUES + (21), + (22), + (23) + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (21), (22), (23) RETURNING *) SELECT * FROM t" +== 244 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 245 +-- truncate_limit: 100 +DROP TRIGGER y_trig ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER y_trig ON y" +== 246 +-- truncate_limit: 100 +CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH ROW + EXECUTE PROCEDURE y_trigger() +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH ROW EXECUTE FUNCTION y_trigger()" +== 247 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y + VALUES + (31), + (32), + (33) + RETURNING * +) +SELECT * FROM t LIMIT 1 +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (31), (32), (33) RETURNING *) SELECT * FROM t LIMIT 1" +== 248 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 249 +-- truncate_limit: 100 +DROP TRIGGER y_trig ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER y_trig ON y" +== 250 +-- truncate_limit: 100 +CREATE OR REPLACE FUNCTION y_trigger() RETURNS trigger AS $$ +begin + raise notice 'y_trigger'; + return null; +end; +$$ LANGUAGE plpgsql +-- +FUNCTION: name="y_trigger" function="y_trigger" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE OR REPLACE FUNCTION y_trigger() RETURNS trigger AS $$\nbegin\n raise notice 'y_trigger';\n ..." +== 251 +-- truncate_limit: 100 +CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH STATEMENT + EXECUTE PROCEDURE y_trigger() +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: CreateTrigStmt +TRUNCATED: "CREATE TRIGGER y_trig AFTER INSERT ON y EXECUTE FUNCTION y_trigger()" +== 252 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y + VALUES + (41), + (42), + (43) + RETURNING * +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (41), (42), (43) RETURNING *) SELECT * FROM t" +== 253 +-- truncate_limit: 100 +SELECT * FROM y +-- +TABLE: name="y" schema="" table="y" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM y" +== 254 +-- truncate_limit: 100 +DROP TRIGGER y_trig ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TRIGGER y_trig ON y" +== 255 +-- truncate_limit: 100 +DROP FUNCTION y_trigger() +-- +FUNCTION: name="y_trigger" function="y_trigger" schema="" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP FUNCTION y_trigger()" +== 256 +-- truncate_limit: 100 +-- WITH attached to inherited UPDATE or DELETE + +CREATE TEMP TABLE parent ( id int, val text ) +-- +TABLE: name="parent" schema="" table="parent" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE parent (id int, val text)" +== 257 +-- truncate_limit: 100 +CREATE TEMP TABLE child1 ( ) INHERITS ( parent ) +-- +TABLE: name="child1" schema="" table="child1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE child1 () INHERITS (parent)" +== 258 +-- truncate_limit: 100 +CREATE TEMP TABLE child2 ( ) INHERITS ( parent ) +-- +TABLE: name="child2" schema="" table="child2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE child2 () INHERITS (parent)" +== 259 +-- truncate_limit: 100 +INSERT INTO parent VALUES ( 1, 'p1' ) +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO parent VALUES (1, 'p1')" +== 260 +-- truncate_limit: 100 +INSERT INTO child1 VALUES ( 11, 'c11' ),( 12, 'c12' ) +-- +TABLE: name="child1" schema="" table="child1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child1 VALUES (11, 'c11'), (12, 'c12')" +== 261 +-- truncate_limit: 100 +INSERT INTO child2 VALUES ( 23, 'c21' ),( 24, 'c22' ) +-- +TABLE: name="child2" schema="" table="child2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO child2 VALUES (23, 'c21'), (24, 'c22')" +== 262 +-- truncate_limit: 100 +WITH rcte AS ( SELECT sum(id) AS totalid FROM parent ) +UPDATE parent SET id = id + totalid FROM rcte +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="parent" schema="" table="parent" ctx=Select +CTE: "rcte" +FUNCTION: name="sum" function="sum" schema="" ctx=Call +STMT: UpdateStmt +STMT: SelectStmt +TRUNCATED: "WITH rcte AS (SELECT sum(id) AS totalid FROM parent) UPDATE parent SET id = id + totalid FROM rcte" +== 263 +-- truncate_limit: 100 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 264 +-- truncate_limit: 100 +WITH wcte AS ( INSERT INTO child1 VALUES ( 42, 'new' ) RETURNING id AS newid ) +UPDATE parent SET id = id + newid FROM wcte +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="child1" schema="" table="child1" ctx=DML +CTE: "wcte" +STMT: UpdateStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH wcte AS (...) UPDATE parent SET id = id + newid FROM wcte" +== 265 +-- truncate_limit: 100 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 266 +-- truncate_limit: 100 +WITH rcte AS ( SELECT max(id) AS maxid FROM parent ) +DELETE FROM parent USING rcte WHERE id = maxid +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="parent" schema="" table="parent" ctx=Select +CTE: "rcte" +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: DeleteStmt +STMT: SelectStmt +TRUNCATED: "WITH rcte AS (SELECT max(id) AS maxid FROM parent) DELETE FROM parent USING rcte WHERE id = maxid" +== 267 +-- truncate_limit: 100 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 268 +-- truncate_limit: 100 +WITH wcte AS ( INSERT INTO child2 VALUES ( 42, 'new2' ) RETURNING id AS newid ) +DELETE FROM parent USING wcte WHERE id = newid +-- +TABLE: name="parent" schema="" table="parent" ctx=DML +TABLE: name="child2" schema="" table="child2" ctx=DML +CTE: "wcte" +STMT: DeleteStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH wcte AS (...) DELETE FROM parent USING wcte WHERE id = newid" +== 269 +-- truncate_limit: 100 +SELECT * FROM parent +-- +TABLE: name="parent" schema="" table="parent" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM parent" +== 270 +-- truncate_limit: 100 +-- check EXPLAIN VERBOSE for a wCTE with RETURNING + +EXPLAIN (VERBOSE, COSTS OFF) +WITH wcte AS ( INSERT INTO int8_tbl VALUES ( 42, 47 ) RETURNING q2 ) +DELETE FROM a_star USING wcte WHERE aa = q2 +-- +TABLE: name="a_star" schema="" table="a_star" ctx=DML +TABLE: name="int8_tbl" schema="" table="int8_tbl" ctx=DML +CTE: "wcte" +STMT: ExplainStmt +STMT: DeleteStmt +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) WITH wcte AS (INSERT INTO int8_tbl VALUES (42, 47) RETURNING q2) DEL..." +== 271 +-- truncate_limit: 100 +-- error cases + +-- data-modifying WITH tries to use its own output +WITH RECURSIVE t AS ( + INSERT INTO y + SELECT * FROM t +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH RECURSIVE t AS (INSERT INTO y SELECT * FROM t) VALUES (false)" +== 272 +-- truncate_limit: 100 +-- no RETURNING in a referenced data-modifying WITH +WITH t AS ( + INSERT INTO y VALUES(0) +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (0)) SELECT * FROM t" +== 273 +-- truncate_limit: 100 +-- RETURNING tries to return its own output +WITH RECURSIVE t(action, a) AS ( + MERGE INTO y USING (VALUES (11)) v(a) ON y.a = v.a + WHEN NOT MATCHED THEN INSERT VALUES (v.a) + RETURNING merge_action(), (SELECT a FROM t) +) +SELECT * FROM t +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: MergeStmt +TRUNCATED: "WITH RECURSIVE t(action, a) AS (...) SELECT * FROM t" +== 274 +-- truncate_limit: 100 +-- data-modifying WITH allowed only at the top level +SELECT * FROM ( + WITH t AS (UPDATE y SET a=a+1 RETURNING *) + SELECT * FROM t +) ss +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: UpdateStmt +TRUNCATED: "SELECT * FROM (WITH t AS (UPDATE y SET a = a + 1 RETURNING *) SELECT * FROM t) ss" +== 275 +-- truncate_limit: 100 +-- most variants of rules aren't allowed +CREATE RULE y_rule AS ON INSERT TO y WHERE a=0 DO INSTEAD DELETE FROM y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE RULE y_rule AS ON INSERT TO y WHERE a = 0 DO INSTEAD DELETE FROM y" +== 276 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (0)) VALUES (false)" +== 277 +-- truncate_limit: 100 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING" +== 278 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (0)) VALUES (false)" +== 279 +-- truncate_limit: 100 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo" +== 280 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (0)) VALUES (false)" +== 281 +-- truncate_limit: 100 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO ALSO NOTIFY foo +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO NOTIFY foo" +== 282 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (0)) VALUES (false)" +== 283 +-- truncate_limit: 100 +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y + DO INSTEAD (NOTIFY foo; NOTIFY bar) +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: RuleStmt +TRUNCATED: "CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD (NOTIFY foo; NOTIFY bar)" +== 284 +-- truncate_limit: 100 +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE) +-- +TABLE: name="y" schema="" table="y" ctx=DML +CTE: "t" +STMT: SelectStmt +STMT: InsertStmt +TRUNCATED: "WITH t AS (INSERT INTO y VALUES (0)) VALUES (false)" +== 285 +-- truncate_limit: 100 +DROP RULE y_rule ON y +-- +TABLE: name="y" schema="" table="y" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP RULE y_rule ON y" +== 286 +-- truncate_limit: 100 +-- check that parser lookahead for WITH doesn't cause any odd behavior +create table foo (with baz) +-- +ERROR: syntax error at or near "with" +CURSORPOS: 90 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 287 +-- truncate_limit: 100 +-- fail, WITH is a reserved word +create table foo (with ordinality) +-- +ERROR: syntax error at or near "with" +CURSORPOS: 52 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 288 +-- truncate_limit: 100 +-- fail, WITH is a reserved word +with ordinality as (select 1 as x) select * from ordinality +-- +CTE: "ordinality" +STMT: SelectStmt +TRUNCATED: "WITH ordinality AS (SELECT 1 AS x) SELECT * FROM ordinality" +== 289 +-- truncate_limit: 100 +-- check sane response to attempt to modify CTE relation +WITH with_test AS (SELECT 42) INSERT INTO with_test VALUES (1) +-- +CTE: "with_test" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH with_test AS (SELECT 42) INSERT INTO with_test VALUES (1)" +== 290 +-- truncate_limit: 100 +-- check response to attempt to modify table with same name as a CTE (perhaps +-- surprisingly it works, because CTEs don't hide tables from data-modifying +-- statements) +create temp table with_test (i int) +-- +TABLE: name="with_test" schema="" table="with_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE with_test (i int)" +== 291 +-- truncate_limit: 100 +with with_test as (select 42) insert into with_test select * from with_test +-- +CTE: "with_test" +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "WITH with_test AS (SELECT 42) INSERT INTO with_test SELECT * FROM with_test" +== 292 +-- truncate_limit: 100 +select * from with_test +-- +TABLE: name="with_test" schema="" table="with_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM with_test" +== 293 +-- truncate_limit: 100 +drop table with_test +-- +TABLE: name="with_test" schema="" table="with_test" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE with_test" diff --git a/parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json b/parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json new file mode 100644 index 0000000..edb706f --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json @@ -0,0 +1,26 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/write_parallel.test b/parser/testdata/summary_truncate/postgres_regress/write_parallel.test new file mode 100644 index 0000000..c68de3d --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/write_parallel.test @@ -0,0 +1,193 @@ +== 001 +-- truncate_limit: 100 +|-- +-- PARALLEL +|-- + +begin +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 002 +-- truncate_limit: 100 +-- encourage use of parallel plans +set parallel_setup_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_setup_cost TO 0" +== 003 +-- truncate_limit: 100 +set parallel_tuple_cost=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET parallel_tuple_cost TO 0" +== 004 +-- truncate_limit: 100 +set min_parallel_table_scan_size=0 +-- +STMT: VariableSetStmt +TRUNCATED: "SET min_parallel_table_scan_size TO 0" +== 005 +-- truncate_limit: 100 +set max_parallel_workers_per_gather=4 +-- +STMT: VariableSetStmt +TRUNCATED: "SET max_parallel_workers_per_gather TO 4" +== 006 +-- truncate_limit: 100 +|-- +-- Test write operations that has an underlying query that is eligible +-- for parallel plans +|-- +explain (costs off) create table parallel_write as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) CREATE TABLE parallel_write AS SELECT length(stringu1) FROM tenk1 GROUP BY le..." +== 007 +-- truncate_limit: 100 +create table parallel_write as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE parallel_write AS SELECT length(stringu1) FROM tenk1 GROUP BY length(stringu1)" +== 008 +-- truncate_limit: 100 +drop table parallel_write +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parallel_write" +== 009 +-- truncate_limit: 100 +explain (costs off) select length(stringu1) into parallel_write + from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT length(stringu1) INTO parallel_write FROM tenk1 GROUP BY length(stringu1)" +== 010 +-- truncate_limit: 100 +select length(stringu1) into parallel_write + from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT length(stringu1) INTO parallel_write FROM tenk1 GROUP BY length(stringu1)" +== 011 +-- truncate_limit: 100 +drop table parallel_write +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parallel_write" +== 012 +-- truncate_limit: 100 +explain (costs off) create materialized view parallel_mat_view as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) CREATE MATERIALIZED VIEW parallel_mat_view AS SELECT length(stringu1) FROM te..." +== 013 +-- truncate_limit: 100 +create materialized view parallel_mat_view as + select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE MATERIALIZED VIEW parallel_mat_view AS SELECT length(stringu1) FROM tenk1 GROUP BY length(..." +== 014 +-- truncate_limit: 100 +create unique index on parallel_mat_view(length) +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE UNIQUE INDEX ON parallel_mat_view USING btree (length)" +== 015 +-- truncate_limit: 100 +refresh materialized view parallel_mat_view +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW parallel_mat_view" +== 016 +-- truncate_limit: 100 +refresh materialized view concurrently parallel_mat_view +-- +TABLE: name="parallel_mat_view" schema="" table="parallel_mat_view" ctx=DDL +STMT: RefreshMatViewStmt +TRUNCATED: "REFRESH MATERIALIZED VIEW CONCURRENTLY parallel_mat_view" +== 017 +-- truncate_limit: 100 +drop materialized view parallel_mat_view +-- +STMT: DropStmt +TRUNCATED: "DROP MATERIALIZED VIEW parallel_mat_view" +== 018 +-- truncate_limit: 100 +prepare prep_stmt as select length(stringu1) from tenk1 group by length(stringu1) +-- +TABLE: name="tenk1" schema="" table="tenk1" ctx=Select +FUNCTION: name="length" function="length" schema="" ctx=Call +FUNCTION: name="length" function="length" schema="" ctx=Call +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE prep_stmt AS SELECT length(stringu1) FROM tenk1 GROUP BY length(stringu1)" +== 019 +-- truncate_limit: 100 +explain (costs off) create table parallel_write as execute prep_stmt +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: ExplainStmt +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "EXPLAIN (COSTS OFF) CREATE TABLE parallel_write AS EXECUTE prep_stmt" +== 020 +-- truncate_limit: 100 +create table parallel_write as execute prep_stmt +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: CreateTableAsStmt +STMT: ExecuteStmt +TRUNCATED: "CREATE TABLE parallel_write AS EXECUTE prep_stmt" +== 021 +-- truncate_limit: 100 +drop table parallel_write +-- +TABLE: name="parallel_write" schema="" table="parallel_write" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE parallel_write" +== 022 +-- truncate_limit: 100 +rollback +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/xid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/xid.metadata.json new file mode 100644 index 0000000..7852793 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/xid.metadata.json @@ -0,0 +1,88 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/xid.test b/parser/testdata/summary_truncate/postgres_regress/xid.test new file mode 100644 index 0000000..329ade0 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/xid.test @@ -0,0 +1,638 @@ +== 001 +-- truncate_limit: 100 +-- xid and xid8 + +-- values in range, in octal, decimal, hex +select '010'::xid, + '42'::xid, + '0xffffffff'::xid, + '-1'::xid, + '010'::xid8, + '42'::xid8, + '0xffffffffffffffff'::xid8, + '-1'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 002 +-- truncate_limit: 100 +-- garbage values +select ''::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::xid" +== 003 +-- truncate_limit: 100 +select 'asdf'::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'asdf'::xid" +== 004 +-- truncate_limit: 100 +select ''::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::xid8" +== 005 +-- truncate_limit: 100 +select 'asdf'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'asdf'::xid8" +== 006 +-- truncate_limit: 100 +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('42', 'xid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('42', 'xid')" +== 007 +-- truncate_limit: 100 +SELECT pg_input_is_valid('asdf', 'xid') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('asdf', 'xid')" +== 008 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('0xffffffffff', 'xid') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('0xffffffffff', 'xid')" +== 009 +-- truncate_limit: 100 +SELECT pg_input_is_valid('42', 'xid8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('42', 'xid8')" +== 010 +-- truncate_limit: 100 +SELECT pg_input_is_valid('asdf', 'xid8') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('asdf', 'xid8')" +== 011 +-- truncate_limit: 100 +SELECT * FROM pg_input_error_info('0xffffffffffffffffffff', 'xid8') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('0xffffffffffffffffffff', 'xid8')" +== 012 +-- truncate_limit: 100 +-- equality +select '1'::xid = '1'::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid = '1'::xid" +== 013 +-- truncate_limit: 100 +select '1'::xid != '1'::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid <> '1'::xid" +== 014 +-- truncate_limit: 100 +select '1'::xid8 = '1'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid8 = '1'::xid8" +== 015 +-- truncate_limit: 100 +select '1'::xid8 != '1'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid8 <> '1'::xid8" +== 016 +-- truncate_limit: 100 +-- conversion +select '1'::xid = '1'::xid8::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid = '1'::xid8::xid" +== 017 +-- truncate_limit: 100 +select '1'::xid != '1'::xid8::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid <> '1'::xid8::xid" +== 018 +-- truncate_limit: 100 +-- we don't want relational operators for xid, due to use of modular arithmetic +select '1'::xid < '2'::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid < '2'::xid" +== 019 +-- truncate_limit: 100 +select '1'::xid <= '2'::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid <= '2'::xid" +== 020 +-- truncate_limit: 100 +select '1'::xid > '2'::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid > '2'::xid" +== 021 +-- truncate_limit: 100 +select '1'::xid >= '2'::xid +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid >= '2'::xid" +== 022 +-- truncate_limit: 100 +-- we want them for xid8 though +select '1'::xid8 < '2'::xid8, '2'::xid8 < '2'::xid8, '2'::xid8 < '1'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid8 < '2'::xid8, '2'::xid8 < '2'::xid8, '2'::xid8 < '1'::xid8" +== 023 +-- truncate_limit: 100 +select '1'::xid8 <= '2'::xid8, '2'::xid8 <= '2'::xid8, '2'::xid8 <= '1'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid8 <= '2'::xid8, '2'::xid8 <= '2'::xid8, '2'::xid8 <= '1'::xid8" +== 024 +-- truncate_limit: 100 +select '1'::xid8 > '2'::xid8, '2'::xid8 > '2'::xid8, '2'::xid8 > '1'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid8 > '2'::xid8, '2'::xid8 > '2'::xid8, '2'::xid8 > '1'::xid8" +== 025 +-- truncate_limit: 100 +select '1'::xid8 >= '2'::xid8, '2'::xid8 >= '2'::xid8, '2'::xid8 >= '1'::xid8 +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1'::xid8 >= '2'::xid8, '2'::xid8 >= '2'::xid8, '2'::xid8 >= '1'::xid8" +== 026 +-- truncate_limit: 100 +-- we also have a 3way compare for btrees +select xid8cmp('1', '2'), xid8cmp('2', '2'), xid8cmp('2', '1') +-- +FUNCTION: name="xid8cmp" function="xid8cmp" schema="" ctx=Call +FUNCTION: name="xid8cmp" function="xid8cmp" schema="" ctx=Call +FUNCTION: name="xid8cmp" function="xid8cmp" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xid8cmp('1', '2'), xid8cmp('2', '2'), xid8cmp('2', '1')" +== 027 +-- truncate_limit: 100 +-- min() and max() for xid8 +create table xid8_t1 (x xid8) +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE xid8_t1 (x xid8)" +== 028 +-- truncate_limit: 100 +insert into xid8_t1 values ('0'), ('010'), ('42'), ('0xffffffffffffffff'), ('-1') +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xid8_t1 VALUES ('0'), ('010'), ('42'), ('0xffffffffffffffff'), ('-1')" +== 029 +-- truncate_limit: 100 +select min(x), max(x) from xid8_t1 +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=Select +FUNCTION: name="min" function="min" schema="" ctx=Call +FUNCTION: name="max" function="max" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT min(x), max(x) FROM xid8_t1" +== 030 +-- truncate_limit: 100 +-- xid8 has btree and hash opclasses +create index on xid8_t1 using btree(x) +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON xid8_t1 USING btree (x)" +== 031 +-- truncate_limit: 100 +create index on xid8_t1 using hash(x) +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: IndexStmt +TRUNCATED: "CREATE INDEX ON xid8_t1 USING hash (x)" +== 032 +-- truncate_limit: 100 +drop table xid8_t1 +-- +TABLE: name="xid8_t1" schema="" table="xid8_t1" ctx=DDL +STMT: DropStmt +TRUNCATED: "DROP TABLE xid8_t1" +== 033 +-- truncate_limit: 100 +-- pg_snapshot data type and related functions + +-- Note: another set of tests similar to this exists in txid.sql, for a limited +-- time (the relevant functions share C code) + +-- i/o +select '12:13:'::pg_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:13:'::pg_snapshot" +== 034 +-- truncate_limit: 100 +select '12:18:14,16'::pg_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:18:14,16'::pg_snapshot" +== 035 +-- truncate_limit: 100 +select '12:16:14,14'::pg_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:16:14,14'::pg_snapshot" +== 036 +-- truncate_limit: 100 +-- errors +select '31:12:'::pg_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '31:12:'::pg_snapshot" +== 037 +-- truncate_limit: 100 +select '0:1:'::pg_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '0:1:'::pg_snapshot" +== 038 +-- truncate_limit: 100 +select '12:13:0'::pg_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:13:0'::pg_snapshot" +== 039 +-- truncate_limit: 100 +select '12:16:14,13'::pg_snapshot +-- +STMT: SelectStmt +TRUNCATED: "SELECT '12:16:14,13'::pg_snapshot" +== 040 +-- truncate_limit: 100 +-- also try it with non-error-throwing API +select pg_input_is_valid('12:13:', 'pg_snapshot') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('12:13:', 'pg_snapshot')" +== 041 +-- truncate_limit: 100 +select pg_input_is_valid('31:12:', 'pg_snapshot') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('31:12:', 'pg_snapshot')" +== 042 +-- truncate_limit: 100 +select * from pg_input_error_info('31:12:', 'pg_snapshot') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('31:12:', 'pg_snapshot')" +== 043 +-- truncate_limit: 100 +select pg_input_is_valid('12:16:14,13', 'pg_snapshot') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('12:16:14,13', 'pg_snapshot')" +== 044 +-- truncate_limit: 100 +select * from pg_input_error_info('12:16:14,13', 'pg_snapshot') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT * FROM pg_input_error_info('12:16:14,13', 'pg_snapshot')" +== 045 +-- truncate_limit: 100 +create temp table snapshot_test ( + nr integer, + snap pg_snapshot +) +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TEMPORARY TABLE snapshot_test (nr int, snap pg_snapshot)" +== 046 +-- truncate_limit: 100 +insert into snapshot_test values (1, '12:13:') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (1, '12:13:')" +== 047 +-- truncate_limit: 100 +insert into snapshot_test values (2, '12:20:13,15,18') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (2, '12:20:13,15,18')" +== 048 +-- truncate_limit: 100 +insert into snapshot_test values (3, '100001:100009:100005,100007,100008') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (3, '100001:100009:100005,100007,100008')" +== 049 +-- truncate_limit: 100 +insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131') +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO snapshot_test VALUES (...)" +== 050 +-- truncate_limit: 100 +select snap from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT snap FROM snapshot_test ORDER BY nr" +== 051 +-- truncate_limit: 100 +select pg_snapshot_xmin(snap), + pg_snapshot_xmax(snap), + pg_snapshot_xip(snap) +from snapshot_test order by nr +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="pg_snapshot_xmin" function="pg_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="pg_snapshot_xmax" function="pg_snapshot_xmax" schema="" ctx=Call +FUNCTION: name="pg_snapshot_xip" function="pg_snapshot_xip" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM snapshot_test ORDER BY nr" +== 052 +-- truncate_limit: 100 +select id, pg_visible_in_snapshot(id::text::xid8, snap) +from snapshot_test, generate_series(11, 21) id +where nr = 2 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM snapshot_test, generate_series(11, 21) id WHERE nr = 2" +== 053 +-- truncate_limit: 100 +-- test bsearch +select id, pg_visible_in_snapshot(id::text::xid8, snap) +from snapshot_test, generate_series(90, 160) id +where nr = 4 +-- +TABLE: name="snapshot_test" schema="" table="snapshot_test" ctx=Select +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="generate_series" function="generate_series" schema="" ctx=Call +FILTER: schema="" table="" column="nr" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM snapshot_test, generate_series(90, 160) id WHERE nr = 4" +== 054 +-- truncate_limit: 100 +-- test current values also +select pg_current_xact_id() >= pg_snapshot_xmin(pg_current_snapshot()) +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_snapshot_xmin" function="pg_snapshot_xmin" schema="" ctx=Call +FUNCTION: name="pg_current_snapshot" function="pg_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_current_xact_id() >= pg_snapshot_xmin(pg_current_snapshot())" +== 055 +-- truncate_limit: 100 +-- we can't assume current is always less than xmax, however + +select pg_visible_in_snapshot(pg_current_xact_id(), pg_current_snapshot()) +-- +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +FUNCTION: name="pg_current_snapshot" function="pg_current_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_visible_in_snapshot(pg_current_xact_id(), pg_current_snapshot())" +== 056 +-- truncate_limit: 100 +-- test 64bitness + +select pg_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1000100010001000:1000100010001100:1000100010001012,1000100010001013'::pg_snapshot" +== 057 +-- truncate_limit: 100 +select pg_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 058 +-- truncate_limit: 100 +select pg_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013') +-- +FUNCTION: name="pg_visible_in_snapshot" function="pg_visible_in_snapshot" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 059 +-- truncate_limit: 100 +-- test 64bit overflow +SELECT pg_snapshot '1:9223372036854775807:3' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1:9223372036854775807:3'::pg_snapshot" +== 060 +-- truncate_limit: 100 +SELECT pg_snapshot '1:9223372036854775808:3' +-- +STMT: SelectStmt +TRUNCATED: "SELECT '1:9223372036854775808:3'::pg_snapshot" +== 061 +-- truncate_limit: 100 +-- test pg_current_xact_id_if_assigned +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 062 +-- truncate_limit: 100 +SELECT pg_current_xact_id_if_assigned() IS NULL +-- +FUNCTION: name="pg_current_xact_id_if_assigned" function="pg_current_xact_id_if_assigned" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_current_xact_id_if_assigned() IS NULL" +== 063 +-- truncate_limit: 100 +SELECT pg_current_xact_id() +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_current_xact_id()" +== 064 +-- truncate_limit: 100 +SELECT pg_current_xact_id_if_assigned() IS NOT DISTINCT FROM xid8 :'pg_current_xact_id' +-- +ERROR: syntax error at or near ":" +CURSORPOS: 67 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 065 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 066 +-- truncate_limit: 100 +-- test xid status functions +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 067 +-- truncate_limit: 100 +SELECT pg_current_xact_id() AS committed +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_current_xact_id() AS committed" +== 068 +-- truncate_limit: 100 +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 069 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 070 +-- truncate_limit: 100 +SELECT pg_current_xact_id() AS rolledback +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_current_xact_id() AS rolledback" +== 071 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" +== 072 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 073 +-- truncate_limit: 100 +SELECT pg_current_xact_id() AS inprogress +-- +FUNCTION: name="pg_current_xact_id" function="pg_current_xact_id" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_current_xact_id() AS inprogress" +== 074 +-- truncate_limit: 100 +SELECT pg_xact_status(:committed::text::xid8) AS committed +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 075 +-- truncate_limit: 100 +SELECT pg_xact_status(:rolledback::text::xid8) AS rolledback +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 076 +-- truncate_limit: 100 +SELECT pg_xact_status(:inprogress::text::xid8) AS inprogress +-- +ERROR: syntax error at or near ":" +CURSORPOS: 23 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 077 +-- truncate_limit: 100 +SELECT pg_xact_status('1'::xid8) +-- +FUNCTION: name="pg_xact_status" function="pg_xact_status" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_xact_status('1'::xid8)" +== 078 +-- truncate_limit: 100 +-- BootstrapTransactionId is always committed +SELECT pg_xact_status('2'::xid8) +-- +FUNCTION: name="pg_xact_status" function="pg_xact_status" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_xact_status('2'::xid8)" +== 079 +-- truncate_limit: 100 +-- FrozenTransactionId is always committed +SELECT pg_xact_status('3'::xid8) +-- +FUNCTION: name="pg_xact_status" function="pg_xact_status" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_xact_status('3'::xid8)" +== 080 +-- truncate_limit: 100 +-- in regress testing FirstNormalTransactionId will always be behind oldestXmin + +COMMIT +-- +STMT: TransactionStmt +TRUNCATED: "COMMIT" +== 081 +-- truncate_limit: 100 +BEGIN +-- +STMT: TransactionStmt +TRUNCATED: "BEGIN" +== 082 +-- truncate_limit: 100 +CREATE FUNCTION test_future_xid_status(xid8) +RETURNS void +LANGUAGE plpgsql +AS +$$ +BEGIN + PERFORM pg_xact_status($1); + RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected'; +EXCEPTION + WHEN invalid_parameter_value THEN + RAISE NOTICE 'Got expected error for xid in the future'; +END; +$$ +-- +FUNCTION: name="test_future_xid_status" function="test_future_xid_status" schema="" ctx=DDL +STMT: CreateFunctionStmt +TRUNCATED: "CREATE FUNCTION test_future_xid_status(xid8) RETURNS void LANGUAGE plpgsql AS $$\nBEGIN\n PERFORM ..." +== 083 +-- truncate_limit: 100 +SELECT test_future_xid_status((:inprogress + 10000)::text::xid8) +-- +ERROR: syntax error at or near ":" +CURSORPOS: 32 +FILENAME: scan.l +FUNCNAME: scanner_yyerror +== 084 +-- truncate_limit: 100 +ROLLBACK +-- +STMT: TransactionStmt +TRUNCATED: "ROLLBACK" diff --git a/parser/testdata/summary_truncate/postgres_regress/xml.metadata.json b/parser/testdata/summary_truncate/postgres_regress/xml.metadata.json new file mode 100644 index 0000000..a6ce2f7 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/xml.metadata.json @@ -0,0 +1,274 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/xml.test b/parser/testdata/summary_truncate/postgres_regress/xml.test new file mode 100644 index 0000000..4f54f77 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/xml.test @@ -0,0 +1,2189 @@ +== 001 +-- truncate_limit: 100 +CREATE TABLE xmltest ( + id int, + data xml +) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE xmltest (id int, data xml)" +== 002 +-- truncate_limit: 100 +INSERT INTO xmltest VALUES (1, 'one') +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest VALUES (1, 'one')" +== 003 +-- truncate_limit: 100 +INSERT INTO xmltest VALUES (2, 'two') +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest VALUES (2, 'two')" +== 004 +-- truncate_limit: 100 +INSERT INTO xmltest VALUES (3, 'one', 'xml') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('one', 'xml')" +== 007 +-- truncate_limit: 100 +SELECT pg_input_is_valid('oneoneoneone', 'xml') +-- +FUNCTION: name="pg_input_is_valid" function="pg_input_is_valid" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT pg_input_is_valid('', 'xml')" +== 010 +-- truncate_limit: 100 +SELECT message FROM pg_input_error_info('', 'xml') +-- +FUNCTION: name="pg_input_error_info" function="pg_input_error_info" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT message FROM pg_input_error_info('', 'xml')" +== 011 +-- truncate_limit: 100 +SELECT xmlcomment('test') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlcomment('test')" +== 012 +-- truncate_limit: 100 +SELECT xmlcomment('-test') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlcomment('-test')" +== 013 +-- truncate_limit: 100 +SELECT xmlcomment('test-') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlcomment('test-')" +== 014 +-- truncate_limit: 100 +SELECT xmlcomment('--test') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlcomment('--test')" +== 015 +-- truncate_limit: 100 +SELECT xmlcomment('te st') +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlcomment('te st')" +== 016 +-- truncate_limit: 100 +SELECT xmlconcat(xmlcomment('hello'), + xmlelement(NAME qux, 'foo'), + xmlcomment('world')) +-- +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlconcat(xmlcomment('hello'), xmlelement(name qux, 'foo'), xmlcomment('world'))" +== 017 +-- truncate_limit: 100 +SELECT xmlconcat('hello', 'you') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlconcat('hello', 'you')" +== 018 +-- truncate_limit: 100 +SELECT xmlconcat(1, 2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlconcat(1, 2)" +== 019 +-- truncate_limit: 100 +SELECT xmlconcat('bad', '', NULL, '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlconcat('', NULL, '')" +== 021 +-- truncate_limit: 100 +SELECT xmlconcat('', NULL, '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlconcat('', NULL, '')" +== 022 +-- truncate_limit: 100 +SELECT xmlconcat(NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlconcat(NULL)" +== 023 +-- truncate_limit: 100 +SELECT xmlconcat(NULL, NULL) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlconcat(NULL, NULL)" +== 024 +-- truncate_limit: 100 +SELECT xmlelement(name element, + xmlattributes (1 as one, 'deuce' as two), + 'content') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name element, xmlattributes(1 AS one, 'deuce' AS two), 'content')" +== 025 +-- truncate_limit: 100 +SELECT xmlelement(name element, + xmlattributes ('unnamed and wrong')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name element, xmlattributes('unnamed and wrong'))" +== 026 +-- truncate_limit: 100 +SELECT xmlelement(name element, xmlelement(name nested, 'stuff')) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name element, xmlelement(name nested, 'stuff'))" +== 027 +-- truncate_limit: 100 +SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp +-- +TABLE: name="emp" schema="" table="emp" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name employee, xmlforest(name, age, salary AS pay)) FROM emp" +== 028 +-- truncate_limit: 100 +SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name duplicate, xmlattributes(1 AS a, 2 AS b, 3 AS a))" +== 029 +-- truncate_limit: 100 +SELECT xmlelement(name num, 37) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name num, 37)" +== 030 +-- truncate_limit: 100 +SELECT xmlelement(name foo, text 'bar') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, 'bar'::text)" +== 031 +-- truncate_limit: 100 +SELECT xmlelement(name foo, xml 'bar') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, 'bar'::xml)" +== 032 +-- truncate_limit: 100 +SELECT xmlelement(name foo, text 'br') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, 'br'::text)" +== 033 +-- truncate_limit: 100 +SELECT xmlelement(name foo, xml 'br') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, 'br'::xml)" +== 034 +-- truncate_limit: 100 +SELECT xmlelement(name foo, array[1, 2, 3]) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, ARRAY[1, 2, 3])" +== 035 +-- truncate_limit: 100 +SET xmlbinary TO base64 +-- +STMT: VariableSetStmt +TRUNCATED: "SET xmlbinary TO base64" +== 036 +-- truncate_limit: 100 +SELECT xmlelement(name foo, bytea 'bar') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, 'bar'::bytea)" +== 037 +-- truncate_limit: 100 +SET xmlbinary TO hex +-- +STMT: VariableSetStmt +TRUNCATED: "SET xmlbinary TO hex" +== 038 +-- truncate_limit: 100 +SELECT xmlelement(name foo, bytea 'bar') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, 'bar'::bytea)" +== 039 +-- truncate_limit: 100 +SELECT xmlelement(name foo, xmlattributes(true as bar)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, xmlattributes(true AS bar))" +== 040 +-- truncate_limit: 100 +SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as bar)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp AS bar))" +== 041 +-- truncate_limit: 100 +SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp AS bar))" +== 042 +-- truncate_limit: 100 +SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'br' as funnier)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name foo, xmlattributes('<>&\"''' AS funny, 'br'::xml AS funnier))" +== 043 +-- truncate_limit: 100 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content '')" +== 044 +-- truncate_limit: 100 +SELECT xmlparse(content ' ') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content ' ')" +== 045 +-- truncate_limit: 100 +SELECT xmlparse(content 'abc') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content 'abc')" +== 046 +-- truncate_limit: 100 +SELECT xmlparse(content 'x') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content 'x')" +== 047 +-- truncate_limit: 100 +SELECT xmlparse(content '&') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content '&')" +== 048 +-- truncate_limit: 100 +SELECT xmlparse(content '&idontexist;') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content '&idontexist;')" +== 049 +-- truncate_limit: 100 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content '')" +== 050 +-- truncate_limit: 100 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content '')" +== 051 +-- truncate_limit: 100 +SELECT xmlparse(content '&idontexist;') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content '&idontexist;')" +== 052 +-- truncate_limit: 100 +SELECT xmlparse(content '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(content '')" +== 053 +-- truncate_limit: 100 +SELECT xmlparse(document ' ') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document ' ')" +== 054 +-- truncate_limit: 100 +SELECT xmlparse(document 'abc') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document 'abc')" +== 055 +-- truncate_limit: 100 +SELECT xmlparse(document 'x') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document 'x')" +== 056 +-- truncate_limit: 100 +SELECT xmlparse(document '&') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document '&')" +== 057 +-- truncate_limit: 100 +SELECT xmlparse(document '&idontexist;') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document '&idontexist;')" +== 058 +-- truncate_limit: 100 +SELECT xmlparse(document '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document '')" +== 059 +-- truncate_limit: 100 +SELECT xmlparse(document '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document '')" +== 060 +-- truncate_limit: 100 +SELECT xmlparse(document '&idontexist;') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document '&idontexist;')" +== 061 +-- truncate_limit: 100 +SELECT xmlparse(document '') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document '')" +== 062 +-- truncate_limit: 100 +SELECT xmlpi(name foo) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name foo)" +== 063 +-- truncate_limit: 100 +SELECT xmlpi(name xml) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name xml)" +== 064 +-- truncate_limit: 100 +SELECT xmlpi(name xmlstuff) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name xmlstuff)" +== 065 +-- truncate_limit: 100 +SELECT xmlpi(name foo, 'bar') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name foo, 'bar')" +== 066 +-- truncate_limit: 100 +SELECT xmlpi(name foo, 'in?>valid') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name foo, 'in?>valid')" +== 067 +-- truncate_limit: 100 +SELECT xmlpi(name foo, null) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name foo, NULL)" +== 068 +-- truncate_limit: 100 +SELECT xmlpi(name xml, null) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name xml, NULL)" +== 069 +-- truncate_limit: 100 +SELECT xmlpi(name xmlstuff, null) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name xmlstuff, NULL)" +== 070 +-- truncate_limit: 100 +SELECT xmlpi(name "xml-stylesheet", 'href="mystyle.css" type="text/css"') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name \"xml-stylesheet\", 'href=\"mystyle.css\" type=\"text/css\"')" +== 071 +-- truncate_limit: 100 +SELECT xmlpi(name foo, ' bar') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name foo, ' bar')" +== 072 +-- truncate_limit: 100 +SELECT xmlroot(xml '', version no value, standalone no value) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlroot(''::xml, version no value, standalone no value)" +== 073 +-- truncate_limit: 100 +SELECT xmlroot(xml '', version '2.0') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlroot(''::xml, version '2.0')" +== 074 +-- truncate_limit: 100 +SELECT xmlroot(xml '', version no value, standalone yes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlroot(''::xml, version no value, standalone yes)" +== 075 +-- truncate_limit: 100 +SELECT xmlroot(xml '', version no value, standalone yes) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlroot(''::xml, version no value, standalone yes)" +== 076 +-- truncate_limit: 100 +SELECT xmlroot(xmlroot(xml '', version '1.0'), version '1.1', standalone no) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlroot(xmlroot(''::xml, version '1.0'), version '1.1', standalone no)" +== 077 +-- truncate_limit: 100 +SELECT xmlroot('', version no value, standalone no) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlroot('', version no value, standalone no)" +== 078 +-- truncate_limit: 100 +SELECT xmlroot('', version no value, standalone no value) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 079 +-- truncate_limit: 100 +SELECT xmlroot('', version no value) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlroot('', version no value)" +== 080 +-- truncate_limit: 100 +SELECT xmlroot ( + xmlelement ( + name gazonk, + xmlattributes ( + 'val' AS name, + 1 + 1 AS num + ), + xmlelement ( + NAME qux, + 'foo' + ) + ), + version '1.0', + standalone yes +) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 081 +-- truncate_limit: 100 +SELECT xmlserialize(content data as character varying(20)) FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content data AS varchar(20)) FROM xmltest" +== 082 +-- truncate_limit: 100 +SELECT xmlserialize(content 'good' as char(10)) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content 'good' AS char(10))" +== 083 +-- truncate_limit: 100 +SELECT xmlserialize(document 'bad' as text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document 'bad' AS text)" +== 084 +-- truncate_limit: 100 +-- indent +SELECT xmlserialize(DOCUMENT '42' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document '42' AS text INDENT)" +== 085 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '42' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content '42' AS text INDENT)" +== 086 +-- truncate_limit: 100 +-- no indent +SELECT xmlserialize(DOCUMENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document '42' AS text)" +== 087 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content '42' AS text)" +== 088 +-- truncate_limit: 100 +-- indent non singly-rooted xml +SELECT xmlserialize(DOCUMENT '7342' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document '7342' AS text INDENT)" +== 089 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '7342' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content '7342' AS text INDENT)" +== 090 +-- truncate_limit: 100 +-- indent non singly-rooted xml with mixed contents +SELECT xmlserialize(DOCUMENT 'text node73text node42' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 091 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT 'text node73text node42' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 092 +-- truncate_limit: 100 +-- indent singly-rooted xml with mixed contents +SELECT xmlserialize(DOCUMENT '42text node73' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 093 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '42text node73' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 094 +-- truncate_limit: 100 +-- indent empty string +SELECT xmlserialize(DOCUMENT '' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document '' AS text INDENT)" +== 095 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content '' AS text INDENT)" +== 096 +-- truncate_limit: 100 +-- whitespaces +SELECT xmlserialize(DOCUMENT ' ' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document ' ' AS text INDENT)" +== 097 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT ' ' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content ' ' AS text INDENT)" +== 098 +-- truncate_limit: 100 +-- indent null +SELECT xmlserialize(DOCUMENT NULL AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document NULL AS text INDENT)" +== 099 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT NULL AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content NULL AS text INDENT)" +== 100 +-- truncate_limit: 100 +-- indent with XML declaration +SELECT xmlserialize(DOCUMENT '73' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 101 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '73' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 102 +-- truncate_limit: 100 +-- indent containing DOCTYPE declaration +SELECT xmlserialize(DOCUMENT '' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document '' AS text INDENT)" +== 103 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content '' AS text INDENT)" +== 104 +-- truncate_limit: 100 +-- indent xml with empty element +SELECT xmlserialize(DOCUMENT '' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document '' AS text INDENT)" +== 105 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content '' AS text INDENT)" +== 106 +-- truncate_limit: 100 +-- 'no indent' = not using 'no indent' +SELECT xmlserialize(DOCUMENT '42' AS text) = xmlserialize(DOCUMENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 107 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT '42' AS text) = xmlserialize(CONTENT '42' AS text NO INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 108 +-- truncate_limit: 100 +-- indent xml strings containing blank nodes +SELECT xmlserialize(DOCUMENT ' ' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(document ' ' AS text INDENT)" +== 109 +-- truncate_limit: 100 +SELECT xmlserialize(CONTENT 'text node ' AS text INDENT) +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlserialize(content 'text node ' AS text INDENT)" +== 110 +-- truncate_limit: 100 +SELECT xml 'bar' IS DOCUMENT +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'bar'::xml IS DOCUMENT" +== 111 +-- truncate_limit: 100 +SELECT xml 'barfoo' IS DOCUMENT +-- +STMT: SelectStmt +TRUNCATED: "SELECT 'barfoo'::xml IS DOCUMENT" +== 112 +-- truncate_limit: 100 +SELECT xml '' IS NOT DOCUMENT +-- +STMT: SelectStmt +TRUNCATED: "SELECT NOT ''::xml IS DOCUMENT" +== 113 +-- truncate_limit: 100 +SELECT xml 'abc' IS NOT DOCUMENT +-- +STMT: SelectStmt +TRUNCATED: "SELECT NOT 'abc'::xml IS DOCUMENT" +== 114 +-- truncate_limit: 100 +SELECT '<>' IS NOT DOCUMENT +-- +STMT: SelectStmt +TRUNCATED: "SELECT NOT '<>' IS DOCUMENT" +== 115 +-- truncate_limit: 100 +SELECT xmlagg(data) FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlagg(data) FROM xmltest" +== 116 +-- truncate_limit: 100 +SELECT xmlagg(data) FROM xmltest WHERE id > 10 +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +FILTER: schema="" table="" column="id" +STMT: SelectStmt +TRUNCATED: "SELECT xmlagg(data) FROM xmltest WHERE id > 10" +== 117 +-- truncate_limit: 100 +SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp +-- +TABLE: name="emp" schema="" table="emp" ctx=Select +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp" +== 118 +-- truncate_limit: 100 +-- Check mapping SQL identifier to XML name + +SELECT xmlpi(name ":::_xml_abc135.%-&_") +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name \":::_xml_abc135.%-&_\")" +== 119 +-- truncate_limit: 100 +SELECT xmlpi(name "123") +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlpi(name \"123\")" +== 120 +-- truncate_limit: 100 +PREPARE foo (xml) AS SELECT xmlconcat('', $1) +-- +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE foo(xml) AS SELECT xmlconcat('', $1)" +== 121 +-- truncate_limit: 100 +SET XML OPTION DOCUMENT +-- +STMT: VariableSetStmt +TRUNCATED: "SET xmloption TO \"DOCUMENT\"" +== 122 +-- truncate_limit: 100 +EXECUTE foo ('') +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo('')" +== 123 +-- truncate_limit: 100 +EXECUTE foo ('bad') +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo('bad')" +== 124 +-- truncate_limit: 100 +SELECT xml '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::xml" +== 125 +-- truncate_limit: 100 +SET XML OPTION CONTENT +-- +STMT: VariableSetStmt +TRUNCATED: "SET xmloption TO \"CONTENT\"" +== 126 +-- truncate_limit: 100 +EXECUTE foo ('') +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo('')" +== 127 +-- truncate_limit: 100 +EXECUTE foo ('good') +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE foo('good')" +== 128 +-- truncate_limit: 100 +SELECT xml ' ' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' '::xml" +== 129 +-- truncate_limit: 100 +SELECT xml ' ' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' '::xml" +== 130 +-- truncate_limit: 100 +SELECT xml '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::xml" +== 131 +-- truncate_limit: 100 +SELECT xml ' oops ' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' oops '::xml" +== 132 +-- truncate_limit: 100 +SELECT xml ' ' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ' '::xml" +== 133 +-- truncate_limit: 100 +SELECT xml '' +-- +STMT: SelectStmt +TRUNCATED: "SELECT ''::xml" +== 134 +-- truncate_limit: 100 +-- Test backwards parsing + +CREATE VIEW xmlview1 AS SELECT xmlcomment('test') +-- +TABLE: name="xmlview1" schema="" table="xmlview1" ctx=DDL +FUNCTION: name="xmlcomment" function="xmlcomment" schema="" ctx=Call +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview1 AS SELECT xmlcomment('test')" +== 135 +-- truncate_limit: 100 +CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you') +-- +TABLE: name="xmlview2" schema="" table="xmlview2" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you')" +== 136 +-- truncate_limit: 100 +CREATE VIEW xmlview3 AS SELECT xmlelement(name element, xmlattributes (1 as ":one:", 'deuce' as two), 'content&') +-- +TABLE: name="xmlview3" schema="" table="xmlview3" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview3 AS SELECT xmlelement(name element, xmlattributes(1 AS \":one:\", 'deuce' AS tw..." +== 137 +-- truncate_limit: 100 +CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp +-- +TABLE: name="xmlview4" schema="" table="xmlview4" ctx=DDL +TABLE: name="emp" schema="" table="emp" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary AS pay)) FRO..." +== 138 +-- truncate_limit: 100 +CREATE VIEW xmlview5 AS SELECT xmlparse(content 'x') +-- +TABLE: name="xmlview5" schema="" table="xmlview5" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview5 AS SELECT xmlparse(content 'x')" +== 139 +-- truncate_limit: 100 +CREATE VIEW xmlview6 AS SELECT xmlpi(name foo, 'bar') +-- +TABLE: name="xmlview6" schema="" table="xmlview6" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview6 AS SELECT xmlpi(name foo, 'bar')" +== 140 +-- truncate_limit: 100 +CREATE VIEW xmlview7 AS SELECT xmlroot(xml '', version no value, standalone yes) +-- +TABLE: name="xmlview7" schema="" table="xmlview7" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview7 AS SELECT xmlroot(''::xml, version no value, standalone yes)" +== 141 +-- truncate_limit: 100 +CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10)) +-- +TABLE: name="xmlview8" schema="" table="xmlview8" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' AS char(10))" +== 142 +-- truncate_limit: 100 +CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text) +-- +TABLE: name="xmlview9" schema="" table="xmlview9" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' AS text)" +== 143 +-- truncate_limit: 100 +CREATE VIEW xmlview10 AS SELECT xmlserialize(document '42' AS text indent) +-- +TABLE: name="xmlview10" schema="" table="xmlview10" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview10 AS SELECT xmlserialize(document '42' AS text INDENT)" +== 144 +-- truncate_limit: 100 +CREATE VIEW xmlview11 AS SELECT xmlserialize(document '42' AS character varying no indent) +-- +TABLE: name="xmlview11" schema="" table="xmlview11" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmlview11 AS SELECT xmlserialize(document '42' AS varchar)" +== 145 +-- truncate_limit: 100 +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'xmlview%' ORDER BY 1 +-- +TABLE: name="information_schema.views" schema="information_schema" table="views" ctx=Select +FILTER: schema="" table="" column="table_name" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM information_schema.views WHERE table_name LIKE 'xmlview%' ORDER BY 1" +== 146 +-- truncate_limit: 100 +-- Text XPath expressions evaluation + +SELECT xpath('/value', data) FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('/value', data) FROM xmltest" +== 147 +-- truncate_limit: 100 +SELECT xpath(NULL, NULL) IS NULL FROM xmltest +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath(NULL, NULL) IS NULL FROM xmltest" +== 148 +-- truncate_limit: 100 +SELECT xpath('', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('', '')" +== 149 +-- truncate_limit: 100 +SELECT xpath('//text()', 'number one') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 150 +-- truncate_limit: 100 +SELECT xpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]) +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 151 +-- truncate_limit: 100 +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]) +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 152 +-- truncate_limit: 100 +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]) +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 153 +-- truncate_limit: 100 +SELECT xpath('//b', 'one two three etc') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('//b', 'one two three etc')" +== 154 +-- truncate_limit: 100 +SELECT xpath('//text()', '<') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('//text()', '<')" +== 155 +-- truncate_limit: 100 +SELECT xpath('//@value', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('//@value', '')" +== 156 +-- truncate_limit: 100 +SELECT xpath('''<>''', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('''<>''', '')" +== 157 +-- truncate_limit: 100 +SELECT xpath('count(//*)', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('count(//*)', '')" +== 158 +-- truncate_limit: 100 +SELECT xpath('count(//*)=0', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('count(//*)=0', '')" +== 159 +-- truncate_limit: 100 +SELECT xpath('count(//*)=3', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('count(//*)=3', '')" +== 160 +-- truncate_limit: 100 +SELECT xpath('name(/*)', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('name(/*)', '')" +== 161 +-- truncate_limit: 100 +SELECT xpath('/nosuchtag', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('/nosuchtag', '')" +== 162 +-- truncate_limit: 100 +SELECT xpath('root', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('root', '')" +== 163 +-- truncate_limit: 100 +-- Round-trip non-ASCII data through xpath(). +DO $$ +DECLARE + xml_declaration text := ''; + degree_symbol text; + res xml[]; +BEGIN + -- Per the documentation, except when the server encoding is UTF8, xpath() + -- may not work on non-ASCII data. The untranslatable_character and + -- undefined_function traps below, currently dead code, will become relevant + -- if we remove this limitation. + IF current_setting('server_encoding') <> 'UTF8' THEN + RAISE LOG 'skip: encoding % unsupported for xpath', + current_setting('server_encoding'); + RETURN; + END IF; + + degree_symbol := convert_from('\xc2b0', 'UTF8'); + res := xpath('text()', (xml_declaration || + '' || degree_symbol || '')::xml); + IF degree_symbol <> res[1]::text THEN + RAISE 'expected % (%), got % (%)', + degree_symbol, convert_to(degree_symbol, 'UTF8'), + res[1], convert_to(res[1]::text, 'UTF8'); + END IF; +EXCEPTION + -- character with byte sequence 0xc2 0xb0 in encoding "UTF8" has no equivalent in encoding "LATIN8" + WHEN untranslatable_character + -- default conversion function for encoding "UTF8" to "MULE_INTERNAL" does not exist + OR undefined_function + -- unsupported XML feature + OR feature_not_supported THEN + RAISE LOG 'skip: %', SQLERRM; +END +$$ +-- +STMT: DoStmt +TRUNCATED: "DO $$\nDECLARE\n xml_declaration text := '';\n degree_s..." +== 164 +-- truncate_limit: 100 +-- Test xmlexists and xpath_exists +SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF 'Bidford-on-AvonCwmbranBristol') +-- +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 165 +-- truncate_limit: 100 +SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF 'Bidford-on-AvonCwmbranBristol') +-- +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 166 +-- truncate_limit: 100 +SELECT xmlexists('count(/nosuchtag)' PASSING BY REF '') +-- +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmlexists ('count(/nosuchtag)' PASSING '')" +== 167 +-- truncate_limit: 100 +SELECT xpath_exists('//town[text() = ''Toronto'']','Bidford-on-AvonCwmbranBristol'::xml) +-- +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 168 +-- truncate_limit: 100 +SELECT xpath_exists('//town[text() = ''Cwmbran'']','Bidford-on-AvonCwmbranBristol'::xml) +-- +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 169 +-- truncate_limit: 100 +SELECT xpath_exists('count(/nosuchtag)', ''::xml) +-- +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath_exists('count(/nosuchtag)', ''::xml)" +== 170 +-- truncate_limit: 100 +INSERT INTO xmltest VALUES (4, 'BudvarfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest VALUES (...)" +== 171 +-- truncate_limit: 100 +INSERT INTO xmltest VALUES (5, 'MolsonfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest VALUES (...)" +== 172 +-- truncate_limit: 100 +INSERT INTO xmltest VALUES (6, 'BudvarfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest VALUES (...)" +== 173 +-- truncate_limit: 100 +INSERT INTO xmltest VALUES (7, 'MolsonfreeCarlinglots'::xml) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest VALUES (...)" +== 174 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE xmlexists ('/menu/beer' PASSING data)" +== 175 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING BY REF data BY REF) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE xmlexists ('/menu/beer' PASSING data)" +== 176 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers' PASSING BY REF data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE xmlexists ('/menu/beers' PASSING data)" +== 177 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molson'']' PASSING BY REF data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE xmlexists ('/menu/beers/name[text() = ''Molson'']' PASSING data)" +== 178 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beer',data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE xpath_exists('/menu/beer', data)" +== 179 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers',data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE xpath_exists('/menu/beers', data)" +== 180 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers/name[text() = ''Molson'']',data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE xpath_exists('/menu/beers/name[text() = ''Molson'']', data)" +== 181 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beer',data,ARRAY[ARRAY['myns','http://myns.com']]) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE ..." +== 182 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers',data,ARRAY[ARRAY['myns','http://myns.com']]) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE ..." +== 183 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers/myns:name[text() = ''Molson'']',data,ARRAY[ARRAY['myns','http://myns.com']]) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="xpath_exists" function="xpath_exists" schema="" ctx=Call +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest WHERE ..." +== 184 +-- truncate_limit: 100 +CREATE TABLE query ( expr TEXT ) +-- +TABLE: name="query" schema="" table="query" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE query (expr text)" +== 185 +-- truncate_limit: 100 +INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']') +-- +TABLE: name="query" schema="" table="query" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']')" +== 186 +-- truncate_limit: 100 +SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data) +-- +TABLE: name="xmltest" schema="" table="xmltest" ctx=Select +TABLE: name="query" schema="" table="query" ctx=Select +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FUNCTION: name="count" function="count" schema="" ctx=Call +FUNCTION: name="pg_catalog.xmlexists" function="xmlexists" schema="pg_catalog" ctx=Call +FILTER: schema="" table="" column="expr" +FILTER: schema="" table="" column="data" +STMT: SelectStmt +TRUNCATED: "SELECT count(id) FROM xmltest, query WHERE xmlexists (expr PASSING data)" +== 187 +-- truncate_limit: 100 +-- Test xml_is_well_formed and variants + +SELECT xml_is_well_formed_document('bar') +-- +FUNCTION: name="xml_is_well_formed_document" function="xml_is_well_formed_document" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed_document('bar')" +== 188 +-- truncate_limit: 100 +SELECT xml_is_well_formed_document('abc') +-- +FUNCTION: name="xml_is_well_formed_document" function="xml_is_well_formed_document" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed_document('abc')" +== 189 +-- truncate_limit: 100 +SELECT xml_is_well_formed_content('bar') +-- +FUNCTION: name="xml_is_well_formed_content" function="xml_is_well_formed_content" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed_content('bar')" +== 190 +-- truncate_limit: 100 +SELECT xml_is_well_formed_content('abc') +-- +FUNCTION: name="xml_is_well_formed_content" function="xml_is_well_formed_content" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed_content('abc')" +== 191 +-- truncate_limit: 100 +SET xmloption TO DOCUMENT +-- +STMT: VariableSetStmt +TRUNCATED: "SET xmloption TO document" +== 192 +-- truncate_limit: 100 +SELECT xml_is_well_formed('abc') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('abc')" +== 193 +-- truncate_limit: 100 +SELECT xml_is_well_formed('<>') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('<>')" +== 194 +-- truncate_limit: 100 +SELECT xml_is_well_formed('') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('')" +== 195 +-- truncate_limit: 100 +SELECT xml_is_well_formed('bar') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('bar')" +== 196 +-- truncate_limit: 100 +SELECT xml_is_well_formed('barbarbaz') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('baz')" +== 198 +-- truncate_limit: 100 +SELECT xml_is_well_formed('number one') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 199 +-- truncate_limit: 100 +SELECT xml_is_well_formed('bar') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('bar')" +== 200 +-- truncate_limit: 100 +SELECT xml_is_well_formed('bar') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('bar')" +== 201 +-- truncate_limit: 100 +SELECT xml_is_well_formed('&') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('&')" +== 202 +-- truncate_limit: 100 +SELECT xml_is_well_formed('&idontexist;') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('&idontexist;')" +== 203 +-- truncate_limit: 100 +SELECT xml_is_well_formed('') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('')" +== 204 +-- truncate_limit: 100 +SELECT xml_is_well_formed('') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('')" +== 205 +-- truncate_limit: 100 +SELECT xml_is_well_formed('&idontexist;') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('&idontexist;')" +== 206 +-- truncate_limit: 100 +SET xmloption TO CONTENT +-- +STMT: VariableSetStmt +TRUNCATED: "SET xmloption TO content" +== 207 +-- truncate_limit: 100 +SELECT xml_is_well_formed('abc') +-- +FUNCTION: name="xml_is_well_formed" function="xml_is_well_formed" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xml_is_well_formed('abc')" +== 208 +-- truncate_limit: 100 +-- Since xpath() deals with namespaces, it's a bit stricter about +-- what's well-formed and what's not. If we don't obey these rules +-- (i.e. ignore namespace-related errors from libxml), xpath() +-- fails in subtle ways. The following would for example produce +-- the xml value +-- +-- which is invalid because '<' may not appear un-escaped in +-- attribute values. +-- Since different libxml versions emit slightly different +-- error messages, we suppress the DETAIL in this test. +SELECT xpath('/*', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('/*', '')" +== 209 +-- truncate_limit: 100 +-- Again, the XML isn't well-formed for namespace purposes +SELECT xpath('/*', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('/*', '')" +== 210 +-- truncate_limit: 100 +-- XPath deprecates relative namespaces, but they're not supposed to +-- throw an error, only a warning. +SELECT xpath('/*', '') +-- +FUNCTION: name="xpath" function="xpath" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xpath('/*', '')" +== 211 +-- truncate_limit: 100 +-- External entity references should not leak filesystem information. +SELECT XMLPARSE(DOCUMENT ']>&c;') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document ']>&c;')" +== 212 +-- truncate_limit: 100 +SELECT XMLPARSE(DOCUMENT ']>&c;') +-- +STMT: SelectStmt +TRUNCATED: "SELECT xmlparse(document ']>&c;')" +== 213 +-- truncate_limit: 100 +-- This might or might not load the requested DTD, but it mustn't throw error. +SELECT XMLPARSE(DOCUMENT ' ') +-- +STMT: SelectStmt +TRUNCATED: "SELECT ..." +== 214 +-- truncate_limit: 100 +-- XMLPATH tests +CREATE TABLE xmldata(data xml) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE xmldata (data xml)" +== 215 +-- truncate_limit: 100 +INSERT INTO xmldata VALUES(' + + AU + Australia + 3 + + + CN + China + 3 + + + HK + HongKong + 3 + + + IN + India + 3 + + + JP + Japan + 3Sinzo Abe + + + SG + Singapore + 3791 + +') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmldata VALUES (...)" +== 216 +-- truncate_limit: 100 +-- XMLTABLE with columns +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM xmldata) x, LATERAL xmltable(('/ROWS/ROW') PASSING data COLUMNS ..." +== 217 +-- truncate_limit: 100 +CREATE VIEW xmltableview1 AS SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=DDL +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmltableview1 AS SELECT \"xmltable\".* FROM (SELECT data FROM xmldata) x, LATERAL xmlta..." +== 218 +-- truncate_limit: 100 +SELECT * FROM xmltableview1 +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltableview1" +== 219 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1 +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1" +== 220 +-- truncate_limit: 100 +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1 +-- +TABLE: name="xmltableview1" schema="" table="xmltableview1" ctx=Select +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1" +== 221 +-- truncate_limit: 100 +-- errors +SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable((ROW()) PASSING NULL COLUMNS v1 timestamp) AS f(v1, v2)" +== 222 +-- truncate_limit: 100 +SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_not_null 1) AS f (v1) +-- +ERROR: option name "__pg__is_not_null" cannot be used in XMLTABLE +CURSORPOS: 66 +FILENAME: gram.y +FUNCNAME: base_yyparse +== 223 +-- truncate_limit: 100 +-- XMLNAMESPACES tests +SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), + '/zz:rows/zz:row' + PASSING '10' + COLUMNS a int PATH 'zz:a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(xmlnamespaces('http://x.y' AS zz), ('/zz:rows/zz:row') PASSING '10' + COLUMNS a int PATH 'Zz:a') +-- +TABLE: name="xmltableview2" schema="" table="xmltableview2" ctx=DDL +STMT: ViewStmt +STMT: SelectStmt +TRUNCATED: "CREATE VIEW xmltableview2 AS SELECT * FROM xmltable(xmlnamespaces('http://x.y' AS \"Zz\"), ('/Zz:ro..." +== 225 +-- truncate_limit: 100 +SELECT * FROM xmltableview2 +-- +TABLE: name="xmltableview2" schema="" table="xmltableview2" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltableview2" +== 226 +-- truncate_limit: 100 +SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), + '/rows/row' + PASSING '10' + COLUMNS a int PATH 'a') +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(xmlnamespaces(DEFAULT 'http://x.y'), ('/rows/row') PASSING '' + COLUMNS a text PATH 'foo/namespace::node()') +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('.') PASSING '' COLUMNS a text PATH 'foo/namespace::node()')" +== 228 +-- truncate_limit: 100 +-- used in prepare statements +PREPARE pp AS +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: PrepareStmt +STMT: SelectStmt +TRUNCATED: "PREPARE pp AS SELECT \"xmltable\".* FROM (SELECT data FROM xmldata) x, LATERAL xmltable(('/ROWS/ROW..." +== 229 +-- truncate_limit: 100 +EXECUTE pp +-- +STMT: ExecuteStmt +TRUNCATED: "EXECUTE pp" +== 230 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmldata, LATERAL xmltable(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India..." +== 231 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id FOR ORDINALITY, "COUNTRY_NAME" text, "REGION_ID" int) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmldata, LATERAL xmltable(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India..." +== 232 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmldata, LATERAL xmltable(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India..." +== 233 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmldata, LATERAL xmltable(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India..." +== 234 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id FOR ORDINALITY) +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmldata, LATERAL xmltable(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India..." +== 235 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int, rawdata xml PATH '.') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmldata, LATERAL xmltable(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India..." +== 236 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int, rawdata xml PATH './*') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmldata, LATERAL xmltable(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India..." +== 237 +-- truncate_limit: 100 +SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('/root') PASSING 'a1aa2a b..." +== 238 +-- truncate_limit: 100 +SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text PATH 'element/text()') +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('/root') PASSING 'a1aa2a b..." +== 239 +-- truncate_limit: 100 +-- should fail + +-- CDATA test +select * from xmltable('d/r' passing ' &"<>!foo]]>2' columns c text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('d/r') PASSING ' &\"<>!foo]]>'"&<>' COLUMNS ent text) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('/x/a') PASSING ''"'"&<>' COLUMNS ent xml) +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('/x/a') PASSING ''" + + CZ + Czech Republic + 2Milos Zeman + + + DE + Germany + 2 + + + FR + France + 2 + +') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmldata VALUES (...)" +== 247 +-- truncate_limit: 100 +INSERT INTO xmldata VALUES(' + + EG + Egypt + 1 + + + SD + Sudan + 1 + +') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmldata VALUES (...)" +== 248 +-- truncate_limit: 100 +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM xmldata) x, LATERAL xmltable(('/ROWS/ROW') PASSING data COLUMNS ..." +== 249 +-- truncate_limit: 100 +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') + WHERE region_id = 2 +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +FILTER: schema="" table="" column="region_id" +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM xmldata) x, LATERAL xmltable(('/ROWS/ROW') PASSING data COLUMNS ..." +== 250 +-- truncate_limit: 100 +EXPLAIN (VERBOSE, COSTS OFF) +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') + WHERE region_id = 2 +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +FILTER: schema="" table="" column="region_id" +STMT: ExplainStmt +STMT: SelectStmt +TRUNCATED: "EXPLAIN (VERBOSE, COSTS OFF) SELECT \"xmltable\".* FROM (SELECT data FROM xmldata) x, LATERAL xmlta..." +== 251 +-- truncate_limit: 100 +-- should fail, NULL value +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE' NOT NULL, + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') +-- +TABLE: name="xmldata" schema="" table="xmldata" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM (SELECT ... FROM xmldata) x, LATERAL xmltable(('/ROWS/ROW') PASSING data COLUMNS ..." +== 252 +-- truncate_limit: 100 +-- if all is ok, then result is empty +-- one line xml test +WITH + x AS (SELECT proname, proowner, procost::numeric, pronargs, + array_to_string(proargnames,',') as proargnames, + case when proargtypes <> '' then array_to_string(proargtypes::oid[],',') end as proargtypes + FROM pg_proc WHERE proname = 'f_leak'), + y AS (SELECT xmlelement(name proc, + xmlforest(proname, proowner, + procost, pronargs, + proargnames, proargtypes)) as proc + FROM x), + z AS (SELECT xmltable.* + FROM y, + LATERAL xmltable('/proc' PASSING proc + COLUMNS proname name, + proowner oid, + procost float, + pronargs int, + proargnames text, + proargtypes text)) + SELECT * FROM z + EXCEPT SELECT * FROM x +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +CTE: "x" +CTE: "y" +CTE: "z" +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FILTER: schema="" table="" column="proname" +STMT: SelectStmt +TRUNCATED: "WITH x AS (...), y AS (SELECT ... FROM x), z AS (...) SELECT * FROM z EXCEPT SELECT * FROM x" +== 253 +-- truncate_limit: 100 +-- multi line xml test, result should be empty too +WITH + x AS (SELECT proname, proowner, procost::numeric, pronargs, + array_to_string(proargnames,',') as proargnames, + case when proargtypes <> '' then array_to_string(proargtypes::oid[],',') end as proargtypes + FROM pg_proc), + y AS (SELECT xmlelement(name data, + xmlagg(xmlelement(name proc, + xmlforest(proname, proowner, procost, + pronargs, proargnames, proargtypes)))) as doc + FROM x), + z AS (SELECT xmltable.* + FROM y, + LATERAL xmltable('/data/proc' PASSING doc + COLUMNS proname name, + proowner oid, + procost float, + pronargs int, + proargnames text, + proargtypes text)) + SELECT * FROM z + EXCEPT SELECT * FROM x +-- +TABLE: name="pg_proc" schema="" table="pg_proc" ctx=Select +CTE: "x" +CTE: "y" +CTE: "z" +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="array_to_string" function="array_to_string" schema="" ctx=Call +FUNCTION: name="xmlagg" function="xmlagg" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "WITH x AS (...), y AS (SELECT ... FROM x), z AS (...) SELECT * FROM z EXCEPT SELECT * FROM x" +== 254 +-- truncate_limit: 100 +CREATE TABLE xmltest2(x xml, _path text) +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE xmltest2 (x xml, _path text)" +== 255 +-- truncate_limit: 100 +INSERT INTO xmltest2 VALUES('1', 'A') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest2 VALUES ('1', 'A')" +== 256 +-- truncate_limit: 100 +INSERT INTO xmltest2 VALUES('2', 'B') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest2 VALUES ('2', 'B')" +== 257 +-- truncate_limit: 100 +INSERT INTO xmltest2 VALUES('3', 'C') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest2 VALUES ('3', 'C')" +== 258 +-- truncate_limit: 100 +INSERT INTO xmltest2 VALUES('2', 'D') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO xmltest2 VALUES ('2', 'D')" +== 259 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmltest2, LATERAL xmltable('/d/r' PASSING x COLUMNS a int PATH '' || lower(_path) || 'c') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmltest2, LATERAL xmltable(('/d/r') PASSING x COLUMNS a int PATH ('' || lower(_pa..." +== 260 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH '.') +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmltest2, LATERAL xmltable((('/d/r/' || lower(_path)) || 'c') PASSING x COLUMNS a..." +== 261 +-- truncate_limit: 100 +SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH 'x' DEFAULT ascii(_path) - 54) +-- +TABLE: name="xmltest2" schema="" table="xmltest2" ctx=Select +FUNCTION: name="lower" function="lower" schema="" ctx=Call +FUNCTION: name="ascii" function="ascii" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT ... FROM xmltest2, LATERAL xmltable((('/d/r/' || lower(_path)) || 'c') PASSING x COLUMNS a..." +== 262 +-- truncate_limit: 100 +-- XPath result can be boolean or number too +SELECT * FROM XMLTABLE('*' PASSING 'a' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"', e integer PATH 'string-length(.)') +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('*') PASSING 'a' COLUMNS a xml PATH '.', b text PATH '.', c text P..." +== 263 +-- truncate_limit: 100 +SELECT * FROM XMLTABLE('*' PASSING 'pre&deeppost' COLUMNS x xml PATH '/e/n2', y xml PATH '/') +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('*') PASSING 'pre&deep"', b xml PATH '""') +-- +STMT: SelectStmt +TRUNCATED: "SELECT * FROM xmltable(('.') PASSING xmlelement(name a) COLUMNS a varchar(20) PATH '\"\"', b ..." +== 265 +-- truncate_limit: 100 +SELECT xmltext(NULL) +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmltext(NULL)" +== 266 +-- truncate_limit: 100 +SELECT xmltext('') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmltext('')" +== 267 +-- truncate_limit: 100 +SELECT xmltext(' ') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmltext(' ')" +== 268 +-- truncate_limit: 100 +SELECT xmltext('foo `$_-+?=*^%!|/\()[]{}') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmltext(E'foo `$_-+?=*^%!|/\\\\()[]{}')" +== 269 +-- truncate_limit: 100 +SELECT xmltext('foo & <"bar">') +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmltext('foo & <\"bar\">')" +== 270 +-- truncate_limit: 100 +SELECT xmltext('x'|| '

      73

      '::xml || .42 || true || 'j'::char) +-- +FUNCTION: name="xmltext" function="xmltext" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT xmltext(((('x' || '

      73

      '::xml) || .42) || true) || 'j'::char(1))" diff --git a/parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json b/parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json new file mode 100644 index 0000000..32e0be1 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json @@ -0,0 +1,44 @@ +{ + "todo": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040" + ] +} diff --git a/parser/testdata/summary_truncate/postgres_regress/xmlmap.test b/parser/testdata/summary_truncate/postgres_regress/xmlmap.test new file mode 100644 index 0000000..a28b586 --- /dev/null +++ b/parser/testdata/summary_truncate/postgres_regress/xmlmap.test @@ -0,0 +1,289 @@ +== 001 +-- truncate_limit: 100 +CREATE SCHEMA testxmlschema +-- +STMT: CreateSchemaStmt +TRUNCATED: "CREATE SCHEMA testxmlschema" +== 002 +-- truncate_limit: 100 +CREATE TABLE testxmlschema.test1 (a int, b text) +-- +TABLE: name="testxmlschema.test1" schema="testxmlschema" table="test1" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testxmlschema.test1 (a int, b text)" +== 003 +-- truncate_limit: 100 +INSERT INTO testxmlschema.test1 VALUES (1, 'one'), (2, 'two'), (-1, null) +-- +TABLE: name="testxmlschema.test1" schema="testxmlschema" table="test1" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testxmlschema.test1 VALUES (1, 'one'), (2, 'two'), (-1, NULL)" +== 004 +-- truncate_limit: 100 +CREATE DOMAIN testxmldomain AS varchar +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testxmldomain AS varchar" +== 005 +-- truncate_limit: 100 +CREATE TABLE testxmlschema.test2 (z int, y varchar(500), x char(6), + w numeric(9,2), v smallint, u bigint, t real, + s time, stz timetz, r timestamp, rtz timestamptz, q date, + p xml, o testxmldomain, n bool, m bytea, aaa text) +-- +TABLE: name="testxmlschema.test2" schema="testxmlschema" table="test2" ctx=DDL +STMT: CreateStmt +TRUNCATED: "CREATE TABLE testxmlschema.test2 (z int, y varchar(500), x char(6), w numeric(9, 2), v smallint, ..." +== 006 +-- truncate_limit: 100 +ALTER TABLE testxmlschema.test2 DROP COLUMN aaa +-- +TABLE: name="testxmlschema.test2" schema="testxmlschema" table="test2" ctx=DDL +STMT: AlterTableStmt +TRUNCATED: "ALTER TABLE testxmlschema.test2 DROP aaa" +== 007 +-- truncate_limit: 100 +INSERT INTO testxmlschema.test2 VALUES (55, 'abc', 'def', + 98.6, 2, 999, 0, + '21:07', '21:11 +05', '2009-06-08 21:07:30', '2009-06-08 21:07:30 -07', '2009-06-08', + NULL, 'ABC', true, 'XYZ') +-- +TABLE: name="testxmlschema.test2" schema="testxmlschema" table="test2" ctx=DML +STMT: InsertStmt +STMT: SelectStmt +TRUNCATED: "INSERT INTO testxmlschema.test2 VALUES (...)" +== 008 +-- truncate_limit: 100 +SELECT table_to_xml('testxmlschema.test1', false, false, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml('testxmlschema.test1', false, false, '')" +== 009 +-- truncate_limit: 100 +SELECT table_to_xml('testxmlschema.test1', true, false, 'foo') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml('testxmlschema.test1', true, false, 'foo')" +== 010 +-- truncate_limit: 100 +SELECT table_to_xml('testxmlschema.test1', false, true, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml('testxmlschema.test1', false, true, '')" +== 011 +-- truncate_limit: 100 +SELECT table_to_xml('testxmlschema.test1', true, true, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml('testxmlschema.test1', true, true, '')" +== 012 +-- truncate_limit: 100 +SELECT table_to_xml('testxmlschema.test2', false, false, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml('testxmlschema.test2', false, false, '')" +== 013 +-- truncate_limit: 100 +SELECT table_to_xmlschema('testxmlschema.test1', false, false, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xmlschema('testxmlschema.test1', false, false, '')" +== 014 +-- truncate_limit: 100 +SELECT table_to_xmlschema('testxmlschema.test1', true, false, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xmlschema('testxmlschema.test1', true, false, '')" +== 015 +-- truncate_limit: 100 +SELECT table_to_xmlschema('testxmlschema.test1', false, true, 'foo') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xmlschema('testxmlschema.test1', false, true, 'foo')" +== 016 +-- truncate_limit: 100 +SELECT table_to_xmlschema('testxmlschema.test1', true, true, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xmlschema('testxmlschema.test1', true, true, '')" +== 017 +-- truncate_limit: 100 +SELECT table_to_xmlschema('testxmlschema.test2', false, false, '') +-- +FUNCTION: name="table_to_xmlschema" function="table_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xmlschema('testxmlschema.test2', false, false, '')" +== 018 +-- truncate_limit: 100 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, false, '') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, false, '')" +== 019 +-- truncate_limit: 100 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, false, '') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, false, '')" +== 020 +-- truncate_limit: 100 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, true, '') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, true, '')" +== 021 +-- truncate_limit: 100 +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, true, 'foo') +-- +FUNCTION: name="table_to_xml_and_xmlschema" function="table_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, true, 'foo')" +== 022 +-- truncate_limit: 100 +SELECT query_to_xml('SELECT * FROM testxmlschema.test1', false, false, '') +-- +FUNCTION: name="query_to_xml" function="query_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT query_to_xml('SELECT * FROM testxmlschema.test1', false, false, '')" +== 023 +-- truncate_limit: 100 +SELECT query_to_xmlschema('SELECT * FROM testxmlschema.test1', false, false, '') +-- +FUNCTION: name="query_to_xmlschema" function="query_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT query_to_xmlschema('SELECT * FROM testxmlschema.test1', false, false, '')" +== 024 +-- truncate_limit: 100 +SELECT query_to_xml_and_xmlschema('SELECT * FROM testxmlschema.test1', true, true, '') +-- +FUNCTION: name="query_to_xml_and_xmlschema" function="query_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT query_to_xml_and_xmlschema('SELECT * FROM testxmlschema.test1', true, true, '')" +== 025 +-- truncate_limit: 100 +DECLARE xc CURSOR WITH HOLD FOR SELECT * FROM testxmlschema.test1 ORDER BY 1, 2 +-- +STMT: DeclareCursorStmt +TRUNCATED: "DECLARE xc CURSOR WITH HOLD FOR SELECT * FROM testxmlschema.test1 ORDER BY 1, 2" +== 026 +-- truncate_limit: 100 +SELECT cursor_to_xml('xc'::refcursor, 5, false, true, '') +-- +FUNCTION: name="cursor_to_xml" function="cursor_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cursor_to_xml('xc'::refcursor, 5, false, true, '')" +== 027 +-- truncate_limit: 100 +SELECT cursor_to_xmlschema('xc'::refcursor, false, true, '') +-- +FUNCTION: name="cursor_to_xmlschema" function="cursor_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cursor_to_xmlschema('xc'::refcursor, false, true, '')" +== 028 +-- truncate_limit: 100 +MOVE BACKWARD ALL IN xc +-- +STMT: FetchStmt +TRUNCATED: "MOVE BACKWARD ALL xc" +== 029 +-- truncate_limit: 100 +SELECT cursor_to_xml('xc'::refcursor, 5, true, false, '') +-- +FUNCTION: name="cursor_to_xml" function="cursor_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cursor_to_xml('xc'::refcursor, 5, true, false, '')" +== 030 +-- truncate_limit: 100 +SELECT cursor_to_xmlschema('xc'::refcursor, true, false, '') +-- +FUNCTION: name="cursor_to_xmlschema" function="cursor_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT cursor_to_xmlschema('xc'::refcursor, true, false, '')" +== 031 +-- truncate_limit: 100 +SELECT schema_to_xml('testxmlschema', false, true, '') +-- +FUNCTION: name="schema_to_xml" function="schema_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT schema_to_xml('testxmlschema', false, true, '')" +== 032 +-- truncate_limit: 100 +SELECT schema_to_xml('testxmlschema', true, false, '') +-- +FUNCTION: name="schema_to_xml" function="schema_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT schema_to_xml('testxmlschema', true, false, '')" +== 033 +-- truncate_limit: 100 +SELECT schema_to_xmlschema('testxmlschema', false, true, '') +-- +FUNCTION: name="schema_to_xmlschema" function="schema_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT schema_to_xmlschema('testxmlschema', false, true, '')" +== 034 +-- truncate_limit: 100 +SELECT schema_to_xmlschema('testxmlschema', true, false, '') +-- +FUNCTION: name="schema_to_xmlschema" function="schema_to_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT schema_to_xmlschema('testxmlschema', true, false, '')" +== 035 +-- truncate_limit: 100 +SELECT schema_to_xml_and_xmlschema('testxmlschema', true, true, 'foo') +-- +FUNCTION: name="schema_to_xml_and_xmlschema" function="schema_to_xml_and_xmlschema" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT schema_to_xml_and_xmlschema('testxmlschema', true, true, 'foo')" +== 036 +-- truncate_limit: 100 +-- test that domains are transformed like their base types + +CREATE DOMAIN testboolxmldomain AS bool +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testboolxmldomain AS bool" +== 037 +-- truncate_limit: 100 +CREATE DOMAIN testdatexmldomain AS date +-- +STMT: CreateDomainStmt +TRUNCATED: "CREATE DOMAIN testdatexmldomain AS date" +== 038 +-- truncate_limit: 100 +CREATE TABLE testxmlschema.test3 + AS SELECT true c1, + true::testboolxmldomain c2, + '2013-02-21'::date c3, + '2013-02-21'::testdatexmldomain c4 +-- +TABLE: name="testxmlschema.test3" schema="testxmlschema" table="test3" ctx=DDL +STMT: CreateTableAsStmt +STMT: SelectStmt +TRUNCATED: "CREATE TABLE testxmlschema.test3 AS SELECT true AS c1, true::testboolxmldomain AS c2, '2013-02-21..." +== 039 +-- truncate_limit: 100 +SELECT xmlforest(c1, c2, c3, c4) FROM testxmlschema.test3 +-- +TABLE: name="testxmlschema.test3" schema="testxmlschema" table="test3" ctx=Select +STMT: SelectStmt +TRUNCATED: "SELECT xmlforest(c1, c2, c3, c4) FROM testxmlschema.test3" +== 040 +-- truncate_limit: 100 +SELECT table_to_xml('testxmlschema.test3', true, true, '') +-- +FUNCTION: name="table_to_xml" function="table_to_xml" schema="" ctx=Call +STMT: SelectStmt +TRUNCATED: "SELECT table_to_xml('testxmlschema.test3', true, true, '')" From 1d0bb5405f07de3cd8bdad2614e7ec45d73821e0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 04:13:06 +0000 Subject: [PATCH 2/5] =?UTF-8?q?Milestone=2010:=20Summary=20=E2=80=94=20cla?= =?UTF-8?q?ssification=20walk=20+=20smart=20truncation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port pg_query_summary.c, pg_query_summary_statement_type.c, and pg_query_summary_truncate.c into internal/summary: - A faithful raw_expression_tree_walker (nodeFuncs.c, PostgreSQL 17) over the protobuf tree, gated exactly as pg_query_raw_tree_walker_supports allows; list nodes are walked as nodes so the truncation pass's depth accounting matches. - The summary walk (tables with contexts, aliases, CTE names, functions, filter columns) including its quirks: WHERE clauses walked twice, the filter-column pass aborting at sub-SELECTs, and functions in WHERE clauses recorded once per pass. - The statement-type walk (insertion-ordered set of node type names). - Truncation: possible truncations collected with depth/length priority, sorted with the pg_qsort port (list_sort maps to pg_qsort at the pin, so tie order needs the exact algorithm), applied cumulatively against the milestone-9 deparser, with the multibyte-aware fallback chop. pg_query_go's summary_test.go is ported verbatim (import swap only). Gate: all 43,992 summary and 43,345 summary_truncate corpus cases pass. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01C5Ummi5YEg7pxk5fvRUd3U --- compat_test.go | 2 - internal/deparse/state.go | 5 + internal/summary/qsort.go | 128 ++ internal/summary/stmt_types.go | 271 +++ internal/summary/summary.go | 441 +++++ internal/summary/truncate.go | 375 ++++ internal/summary/walker.go | 286 +++ parser/parser.go | 23 +- .../summary/libpg_query.metadata.json | 105 +- .../plpgsql_array.metadata.json | 34 +- .../plpgsql_cache.metadata.json | 16 +- .../plpgsql_call.metadata.json | 86 +- .../plpgsql_control.metadata.json | 56 +- .../plpgsql_copy.metadata.json | 4 +- .../plpgsql_domain.metadata.json | 85 +- .../plpgsql_misc.metadata.json | 17 +- .../plpgsql_record.metadata.json | 161 +- .../plpgsql_simple.metadata.json | 27 +- .../plpgsql_transaction.metadata.json | 120 +- .../plpgsql_trap.metadata.json | 45 +- .../plpgsql_trigger.metadata.json | 9 +- .../plpgsql_varprops.metadata.json | 40 +- .../advisory_lock.metadata.json | 41 +- .../postgres_regress/aggregates.metadata.json | 517 +---- .../alter_generic.metadata.json | 335 +--- .../alter_operator.metadata.json | 68 +- .../alter_table.metadata.json | 1656 +---------------- .../postgres_regress/amutils.metadata.json | 13 +- .../postgres_regress/arrays.metadata.json | 487 +---- .../postgres_regress/async.metadata.json | 14 +- .../postgres_regress/bit.metadata.json | 135 +- .../postgres_regress/bitmapops.metadata.json | 13 +- .../postgres_regress/boolean.metadata.json | 101 +- .../postgres_regress/box.metadata.json | 104 +- .../postgres_regress/brin.metadata.json | 71 +- .../postgres_regress/brin_bloom.metadata.json | 43 +- .../postgres_regress/brin_multi.metadata.json | 175 +- .../btree_index.metadata.json | 99 +- .../postgres_regress/case.metadata.json | 67 +- .../postgres_regress/char.metadata.json | 35 +- .../postgres_regress/circle.metadata.json | 25 +- .../postgres_regress/cluster.metadata.json | 207 +-- .../collate.icu.utf8.metadata.json | 504 +---- .../collate.linux.utf8.metadata.json | 206 +- .../postgres_regress/collate.metadata.json | 147 +- .../collate.utf8.metadata.json | 27 +- .../collate.windows.win1252.metadata.json | 176 +- .../postgres_regress/combocid.metadata.json | 65 +- .../postgres_regress/comments.metadata.json | 9 +- .../compression.metadata.json | 90 +- .../constraints.metadata.json | 322 +--- .../postgres_regress/conversion.metadata.json | 68 +- .../postgres_regress/copy.metadata.json | 90 +- .../postgres_regress/copy2.metadata.json | 4 +- .../postgres_regress/copydml.metadata.json | 62 +- .../postgres_regress/copyselect.metadata.json | 24 +- .../create_aggregate.metadata.json | 62 +- .../postgres_regress/create_am.metadata.json | 145 +- .../create_cast.metadata.json | 27 +- .../create_function_c.metadata.json | 8 +- .../create_function_sql.metadata.json | 158 +- .../create_index.metadata.json | 614 +----- .../create_index_spgist.metadata.json | 205 +- .../create_misc.metadata.json | 91 +- .../create_operator.metadata.json | 93 +- .../create_procedure.metadata.json | 112 +- .../create_role.metadata.json | 140 +- .../create_schema.metadata.json | 30 +- .../create_table.metadata.json | 329 +--- .../create_table_like.metadata.json | 147 +- .../create_type.metadata.json | 88 +- .../create_view.metadata.json | 310 +-- .../postgres_regress/database.metadata.json | 19 +- .../postgres_regress/date.metadata.json | 273 +-- .../postgres_regress/dbsize.metadata.json | 28 +- .../postgres_regress/delete.metadata.json | 13 +- .../postgres_regress/dependency.metadata.json | 65 +- .../postgres_regress/domain.metadata.json | 322 +--- .../drop_if_exists.metadata.json | 164 +- .../drop_operator.metadata.json | 15 +- .../postgres_regress/enum.metadata.json | 173 +- .../postgres_regress/equivclass.metadata.json | 82 +- .../postgres_regress/errors.metadata.json | 88 +- .../event_trigger.metadata.json | 233 +-- .../event_trigger_login.metadata.json | 14 +- .../postgres_regress/explain.metadata.json | 54 +- .../expressions.metadata.json | 74 +- .../fast_default.metadata.json | 272 +-- .../postgres_regress/float4.metadata.json | 103 +- .../postgres_regress/float8.metadata.json | 172 +- .../foreign_data.metadata.json | 533 +----- .../foreign_key.metadata.json | 1157 +----------- .../functional_deps.metadata.json | 43 +- .../postgres_regress/generated.metadata.json | 122 +- .../postgres_regress/geometry.metadata.json | 165 +- .../postgres_regress/gin.metadata.json | 62 +- .../postgres_regress/gist.metadata.json | 65 +- .../groupingsets.metadata.json | 175 +- .../postgres_regress/guc.metadata.json | 217 +-- .../postgres_regress/hash_func.metadata.json | 46 +- .../postgres_regress/hash_index.metadata.json | 100 +- .../postgres_regress/hash_part.metadata.json | 31 +- .../postgres_regress/horology.metadata.json | 391 +--- .../postgres_regress/identity.metadata.json | 273 +-- .../incremental_sort.metadata.json | 122 +- .../index_including.metadata.json | 138 +- .../index_including_gist.metadata.json | 53 +- .../postgres_regress/indexing.metadata.json | 563 +----- .../indirect_toast.metadata.json | 31 +- .../postgres_regress/inet.metadata.json | 114 +- .../infinite_recurse.metadata.json | 6 +- .../postgres_regress/inherit.metadata.json | 680 +------ .../postgres_regress/init_privs.metadata.json | 7 +- .../postgres_regress/insert.metadata.json | 390 +--- .../insert_conflict.metadata.json | 260 +-- .../postgres_regress/int2.metadata.json | 79 +- .../postgres_regress/int4.metadata.json | 97 +- .../postgres_regress/int8.metadata.json | 170 +- .../postgres_regress/interval.metadata.json | 446 +---- .../postgres_regress/join.metadata.json | 718 +------ .../postgres_regress/join_hash.metadata.json | 282 +-- .../postgres_regress/json.metadata.json | 463 +---- .../json_encoding.metadata.json | 47 +- .../postgres_regress/jsonb.metadata.json | 1062 +---------- .../jsonb_jsonpath.metadata.json | 824 +------- .../postgres_regress/jsonpath.metadata.json | 227 +-- .../jsonpath_encoding.metadata.json | 35 +- .../largeobject.metadata.json | 127 +- .../postgres_regress/limit.metadata.json | 83 +- .../postgres_regress/line.metadata.json | 38 +- .../postgres_regress/lock.metadata.json | 134 +- .../postgres_regress/lseg.metadata.json | 19 +- .../postgres_regress/macaddr.metadata.json | 38 +- .../postgres_regress/macaddr8.metadata.json | 74 +- .../maintain_every.metadata.json | 19 +- .../postgres_regress/matview.metadata.json | 182 +- .../postgres_regress/md5.metadata.json | 17 +- .../postgres_regress/memoize.metadata.json | 72 +- .../postgres_regress/merge.metadata.json | 575 +----- .../postgres_regress/misc.metadata.json | 64 +- .../misc_functions.metadata.json | 122 +- .../misc_sanity.metadata.json | 8 +- .../postgres_regress/money.metadata.json | 112 +- .../multirangetypes.metadata.json | 608 +----- .../postgres_regress/mvcc.metadata.json | 14 +- .../postgres_regress/name.metadata.json | 43 +- .../postgres_regress/namespace.metadata.json | 45 +- .../postgres_regress/numeric.metadata.json | 1021 +--------- .../numeric_big.metadata.json | 555 +----- .../postgres_regress/numerology.metadata.json | 4 +- .../object_address.metadata.json | 84 +- .../postgres_regress/oid.metadata.json | 40 +- .../postgres_regress/oidjoins.metadata.json | 4 +- .../postgres_regress/opr_sanity.metadata.json | 133 +- .../partition_aggregate.metadata.json | 138 +- .../partition_info.metadata.json | 76 +- .../partition_join.metadata.json | 603 +----- .../partition_prune.metadata.json | 701 +------ .../postgres_regress/password.metadata.json | 54 +- .../postgres_regress/path.metadata.json | 26 +- .../postgres_regress/pg_lsn.metadata.json | 34 +- .../postgres_regress/plancache.metadata.json | 100 +- .../postgres_regress/plpgsql.metadata.json | 944 +--------- .../postgres_regress/point.metadata.json | 46 +- .../postgres_regress/polygon.metadata.json | 65 +- .../polymorphism.metadata.json | 426 +---- .../postgres_regress/portals.metadata.json | 352 +--- .../postgres_regress/portals_p2.metadata.json | 44 +- .../postgres_regress/predicate.metadata.json | 45 +- .../postgres_regress/prepare.metadata.json | 36 +- .../prepared_xacts.metadata.json | 86 +- .../postgres_regress/privileges.metadata.json | 334 +--- .../postgres_regress/psql.metadata.json | 199 +- .../psql_crosstab.metadata.json | 11 +- .../publication.metadata.json | 658 +------ .../postgres_regress/random.metadata.json | 51 +- .../postgres_regress/rangefuncs.metadata.json | 431 +---- .../postgres_regress/rangetypes.metadata.json | 410 +--- .../postgres_regress/regex.metadata.json | 108 +- .../postgres_regress/regproc.metadata.json | 108 +- .../reindex_catalog.metadata.json | 23 +- .../postgres_regress/reloptions.metadata.json | 69 +- .../replica_identity.metadata.json | 59 +- .../postgres_regress/returning.metadata.json | 80 +- .../roleattributes.metadata.json | 83 +- .../rowsecurity.metadata.json | 778 +------- .../postgres_regress/rowtypes.metadata.json | 240 +-- .../postgres_regress/rules.metadata.json | 623 +------ .../sanity_check.metadata.json | 6 +- .../security_label.metadata.json | 31 +- .../postgres_regress/select.metadata.json | 90 +- .../select_distinct.metadata.json | 79 +- .../select_distinct_on.metadata.json | 11 +- .../select_having.metadata.json | 26 +- .../select_implicit.metadata.json | 47 +- .../select_into.metadata.json | 70 +- .../select_parallel.metadata.json | 238 +-- .../select_views.metadata.json | 55 +- .../postgres_regress/sequence.metadata.json | 263 +-- .../postgres_regress/spgist.metadata.json | 34 +- .../postgres_regress/sqljson.metadata.json | 222 +-- .../sqljson_jsontable.metadata.json | 120 +- .../sqljson_queryfuncs.metadata.json | 313 +--- .../postgres_regress/stats.metadata.json | 450 +---- .../postgres_regress/stats_ext.metadata.json | 819 +------- .../postgres_regress/strings.metadata.json | 4 +- .../subscription.metadata.json | 162 +- .../postgres_regress/subselect.metadata.json | 272 +-- .../postgres_regress/sysviews.metadata.json | 30 +- .../tablesample.metadata.json | 59 +- .../postgres_regress/tablespace.metadata.json | 207 +-- .../postgres_regress/temp.metadata.json | 165 +- .../postgres_regress/test_setup.metadata.json | 72 +- .../postgres_regress/text.metadata.json | 76 +- .../postgres_regress/tid.metadata.json | 44 +- .../tidrangescan.metadata.json | 48 +- .../postgres_regress/tidscan.metadata.json | 52 +- .../postgres_regress/time.metadata.json | 47 +- .../postgres_regress/timestamp.metadata.json | 174 +- .../timestamptz.metadata.json | 385 +--- .../postgres_regress/timetz.metadata.json | 60 +- .../transactions.metadata.json | 493 +---- .../postgres_regress/triggers.metadata.json | 1059 +---------- .../postgres_regress/truncate.metadata.json | 196 +- .../postgres_regress/tsdicts.metadata.json | 134 +- .../postgres_regress/tsearch.metadata.json | 445 +---- .../postgres_regress/tsrf.metadata.json | 77 +- .../postgres_regress/tstypes.metadata.json | 241 +-- .../postgres_regress/tuplesort.metadata.json | 109 +- .../postgres_regress/txid.metadata.json | 50 +- .../type_sanity.metadata.json | 64 +- .../typed_table.metadata.json | 31 +- .../postgres_regress/unicode.metadata.json | 20 +- .../postgres_regress/union.metadata.json | 194 +- .../updatable_views.metadata.json | 1103 +---------- .../postgres_regress/update.metadata.json | 260 +-- .../postgres_regress/uuid.metadata.json | 47 +- .../postgres_regress/vacuum.metadata.json | 299 +-- .../vacuum_parallel.metadata.json | 17 +- .../postgres_regress/varchar.metadata.json | 25 +- .../postgres_regress/window.metadata.json | 389 +--- .../postgres_regress/with.metadata.json | 296 +-- .../write_parallel.metadata.json | 25 +- .../postgres_regress/xid.metadata.json | 87 +- .../postgres_regress/xml.metadata.json | 273 +-- .../postgres_regress/xmlmap.metadata.json | 43 +- .../libpg_query.metadata.json | 119 +- .../advisory_lock.metadata.json | 41 +- .../postgres_regress/aggregates.metadata.json | 517 +---- .../alter_generic.metadata.json | 335 +--- .../alter_operator.metadata.json | 68 +- .../alter_table.metadata.json | 1656 +---------------- .../postgres_regress/amutils.metadata.json | 13 +- .../postgres_regress/arrays.metadata.json | 487 +---- .../postgres_regress/async.metadata.json | 14 +- .../postgres_regress/bit.metadata.json | 135 +- .../postgres_regress/bitmapops.metadata.json | 13 +- .../postgres_regress/boolean.metadata.json | 101 +- .../postgres_regress/box.metadata.json | 104 +- .../postgres_regress/brin.metadata.json | 71 +- .../postgres_regress/brin_bloom.metadata.json | 43 +- .../postgres_regress/brin_multi.metadata.json | 175 +- .../btree_index.metadata.json | 99 +- .../postgres_regress/case.metadata.json | 67 +- .../postgres_regress/char.metadata.json | 35 +- .../postgres_regress/circle.metadata.json | 25 +- .../postgres_regress/cluster.metadata.json | 207 +-- .../collate.icu.utf8.metadata.json | 504 +---- .../collate.linux.utf8.metadata.json | 206 +- .../postgres_regress/collate.metadata.json | 147 +- .../collate.utf8.metadata.json | 27 +- .../collate.windows.win1252.metadata.json | 176 +- .../postgres_regress/combocid.metadata.json | 65 +- .../postgres_regress/comments.metadata.json | 9 +- .../compression.metadata.json | 90 +- .../constraints.metadata.json | 322 +--- .../postgres_regress/conversion.metadata.json | 68 +- .../postgres_regress/copy.metadata.json | 90 +- .../postgres_regress/copy2.metadata.json | 4 +- .../postgres_regress/copydml.metadata.json | 62 +- .../postgres_regress/copyselect.metadata.json | 24 +- .../create_aggregate.metadata.json | 62 +- .../postgres_regress/create_am.metadata.json | 145 +- .../create_cast.metadata.json | 27 +- .../create_function_c.metadata.json | 8 +- .../create_function_sql.metadata.json | 158 +- .../create_index.metadata.json | 614 +----- .../create_index_spgist.metadata.json | 205 +- .../create_misc.metadata.json | 91 +- .../create_operator.metadata.json | 93 +- .../create_procedure.metadata.json | 112 +- .../create_role.metadata.json | 140 +- .../create_schema.metadata.json | 30 +- .../create_table.metadata.json | 329 +--- .../create_table_like.metadata.json | 147 +- .../create_type.metadata.json | 88 +- .../create_view.metadata.json | 310 +-- .../postgres_regress/database.metadata.json | 19 +- .../postgres_regress/date.metadata.json | 273 +-- .../postgres_regress/dbsize.metadata.json | 28 +- .../postgres_regress/delete.metadata.json | 13 +- .../postgres_regress/dependency.metadata.json | 65 +- .../postgres_regress/domain.metadata.json | 322 +--- .../drop_if_exists.metadata.json | 164 +- .../drop_operator.metadata.json | 15 +- .../postgres_regress/enum.metadata.json | 173 +- .../postgres_regress/equivclass.metadata.json | 82 +- .../postgres_regress/errors.metadata.json | 88 +- .../event_trigger.metadata.json | 233 +-- .../event_trigger_login.metadata.json | 14 +- .../postgres_regress/explain.metadata.json | 54 +- .../expressions.metadata.json | 74 +- .../fast_default.metadata.json | 272 +-- .../postgres_regress/float4.metadata.json | 103 +- .../postgres_regress/float8.metadata.json | 172 +- .../foreign_data.metadata.json | 533 +----- .../foreign_key.metadata.json | 1157 +----------- .../functional_deps.metadata.json | 43 +- .../postgres_regress/generated.metadata.json | 122 +- .../postgres_regress/geometry.metadata.json | 165 +- .../postgres_regress/gin.metadata.json | 62 +- .../postgres_regress/gist.metadata.json | 65 +- .../groupingsets.metadata.json | 175 +- .../postgres_regress/guc.metadata.json | 217 +-- .../postgres_regress/hash_func.metadata.json | 46 +- .../postgres_regress/hash_index.metadata.json | 100 +- .../postgres_regress/hash_part.metadata.json | 31 +- .../postgres_regress/horology.metadata.json | 391 +--- .../postgres_regress/identity.metadata.json | 273 +-- .../incremental_sort.metadata.json | 122 +- .../index_including.metadata.json | 138 +- .../index_including_gist.metadata.json | 53 +- .../postgres_regress/indexing.metadata.json | 563 +----- .../indirect_toast.metadata.json | 31 +- .../postgres_regress/inet.metadata.json | 114 +- .../infinite_recurse.metadata.json | 6 +- .../postgres_regress/inherit.metadata.json | 680 +------ .../postgres_regress/init_privs.metadata.json | 7 +- .../postgres_regress/insert.metadata.json | 390 +--- .../insert_conflict.metadata.json | 260 +-- .../postgres_regress/int2.metadata.json | 79 +- .../postgres_regress/int4.metadata.json | 97 +- .../postgres_regress/int8.metadata.json | 170 +- .../postgres_regress/interval.metadata.json | 446 +---- .../postgres_regress/join.metadata.json | 718 +------ .../postgres_regress/join_hash.metadata.json | 282 +-- .../postgres_regress/json.metadata.json | 463 +---- .../json_encoding.metadata.json | 47 +- .../postgres_regress/jsonb.metadata.json | 1062 +---------- .../jsonb_jsonpath.metadata.json | 824 +------- .../postgres_regress/jsonpath.metadata.json | 227 +-- .../jsonpath_encoding.metadata.json | 35 +- .../largeobject.metadata.json | 127 +- .../postgres_regress/limit.metadata.json | 83 +- .../postgres_regress/line.metadata.json | 38 +- .../postgres_regress/lock.metadata.json | 134 +- .../postgres_regress/lseg.metadata.json | 19 +- .../postgres_regress/macaddr.metadata.json | 38 +- .../postgres_regress/macaddr8.metadata.json | 74 +- .../maintain_every.metadata.json | 19 +- .../postgres_regress/matview.metadata.json | 182 +- .../postgres_regress/md5.metadata.json | 17 +- .../postgres_regress/memoize.metadata.json | 72 +- .../postgres_regress/merge.metadata.json | 575 +----- .../postgres_regress/misc.metadata.json | 64 +- .../misc_functions.metadata.json | 122 +- .../misc_sanity.metadata.json | 8 +- .../postgres_regress/money.metadata.json | 112 +- .../multirangetypes.metadata.json | 608 +----- .../postgres_regress/mvcc.metadata.json | 14 +- .../postgres_regress/name.metadata.json | 43 +- .../postgres_regress/namespace.metadata.json | 45 +- .../postgres_regress/numeric.metadata.json | 1021 +--------- .../numeric_big.metadata.json | 555 +----- .../postgres_regress/numerology.metadata.json | 4 +- .../object_address.metadata.json | 84 +- .../postgres_regress/oid.metadata.json | 40 +- .../postgres_regress/oidjoins.metadata.json | 4 +- .../postgres_regress/opr_sanity.metadata.json | 133 +- .../partition_aggregate.metadata.json | 138 +- .../partition_info.metadata.json | 76 +- .../partition_join.metadata.json | 603 +----- .../partition_prune.metadata.json | 701 +------ .../postgres_regress/password.metadata.json | 54 +- .../postgres_regress/path.metadata.json | 26 +- .../postgres_regress/pg_lsn.metadata.json | 34 +- .../postgres_regress/plancache.metadata.json | 100 +- .../postgres_regress/plpgsql.metadata.json | 944 +--------- .../postgres_regress/point.metadata.json | 46 +- .../postgres_regress/polygon.metadata.json | 65 +- .../polymorphism.metadata.json | 426 +---- .../postgres_regress/portals.metadata.json | 352 +--- .../postgres_regress/portals_p2.metadata.json | 44 +- .../postgres_regress/predicate.metadata.json | 45 +- .../postgres_regress/prepare.metadata.json | 36 +- .../prepared_xacts.metadata.json | 86 +- .../postgres_regress/privileges.metadata.json | 334 +--- .../postgres_regress/psql.metadata.json | 199 +- .../psql_crosstab.metadata.json | 11 +- .../publication.metadata.json | 658 +------ .../postgres_regress/random.metadata.json | 51 +- .../postgres_regress/rangefuncs.metadata.json | 431 +---- .../postgres_regress/rangetypes.metadata.json | 410 +--- .../postgres_regress/regex.metadata.json | 108 +- .../postgres_regress/regproc.metadata.json | 108 +- .../reindex_catalog.metadata.json | 23 +- .../postgres_regress/reloptions.metadata.json | 69 +- .../replica_identity.metadata.json | 59 +- .../postgres_regress/returning.metadata.json | 80 +- .../roleattributes.metadata.json | 83 +- .../rowsecurity.metadata.json | 778 +------- .../postgres_regress/rowtypes.metadata.json | 240 +-- .../postgres_regress/rules.metadata.json | 623 +------ .../sanity_check.metadata.json | 6 +- .../security_label.metadata.json | 31 +- .../postgres_regress/select.metadata.json | 90 +- .../select_distinct.metadata.json | 79 +- .../select_distinct_on.metadata.json | 11 +- .../select_having.metadata.json | 26 +- .../select_implicit.metadata.json | 47 +- .../select_into.metadata.json | 70 +- .../select_parallel.metadata.json | 238 +-- .../select_views.metadata.json | 55 +- .../postgres_regress/sequence.metadata.json | 263 +-- .../postgres_regress/spgist.metadata.json | 34 +- .../postgres_regress/sqljson.metadata.json | 222 +-- .../sqljson_jsontable.metadata.json | 120 +- .../sqljson_queryfuncs.metadata.json | 313 +--- .../postgres_regress/stats.metadata.json | 450 +---- .../postgres_regress/stats_ext.metadata.json | 819 +------- .../postgres_regress/strings.metadata.json | 4 +- .../subscription.metadata.json | 162 +- .../postgres_regress/subselect.metadata.json | 272 +-- .../postgres_regress/sysviews.metadata.json | 30 +- .../tablesample.metadata.json | 59 +- .../postgres_regress/tablespace.metadata.json | 207 +-- .../postgres_regress/temp.metadata.json | 165 +- .../postgres_regress/test_setup.metadata.json | 72 +- .../postgres_regress/text.metadata.json | 76 +- .../postgres_regress/tid.metadata.json | 44 +- .../tidrangescan.metadata.json | 48 +- .../postgres_regress/tidscan.metadata.json | 52 +- .../postgres_regress/time.metadata.json | 47 +- .../postgres_regress/timestamp.metadata.json | 174 +- .../timestamptz.metadata.json | 385 +--- .../postgres_regress/timetz.metadata.json | 60 +- .../transactions.metadata.json | 493 +---- .../postgres_regress/triggers.metadata.json | 1059 +---------- .../postgres_regress/truncate.metadata.json | 196 +- .../postgres_regress/tsdicts.metadata.json | 134 +- .../postgres_regress/tsearch.metadata.json | 445 +---- .../postgres_regress/tsrf.metadata.json | 77 +- .../postgres_regress/tstypes.metadata.json | 241 +-- .../postgres_regress/tuplesort.metadata.json | 109 +- .../postgres_regress/txid.metadata.json | 50 +- .../type_sanity.metadata.json | 64 +- .../typed_table.metadata.json | 31 +- .../postgres_regress/unicode.metadata.json | 20 +- .../postgres_regress/union.metadata.json | 194 +- .../updatable_views.metadata.json | 1103 +---------- .../postgres_regress/update.metadata.json | 260 +-- .../postgres_regress/uuid.metadata.json | 47 +- .../postgres_regress/vacuum.metadata.json | 299 +-- .../vacuum_parallel.metadata.json | 17 +- .../postgres_regress/varchar.metadata.json | 25 +- .../postgres_regress/window.metadata.json | 389 +--- .../postgres_regress/with.metadata.json | 296 +-- .../write_parallel.metadata.json | 25 +- .../postgres_regress/xid.metadata.json | 87 +- .../postgres_regress/xml.metadata.json | 273 +-- .../postgres_regress/xmlmap.metadata.json | 43 +- summary_test.go | 132 ++ 472 files changed, 2123 insertions(+), 88266 deletions(-) create mode 100644 internal/summary/qsort.go create mode 100644 internal/summary/stmt_types.go create mode 100644 internal/summary/summary.go create mode 100644 internal/summary/truncate.go create mode 100644 internal/summary/walker.go create mode 100644 summary_test.go diff --git a/compat_test.go b/compat_test.go index 3085e28..39a6057 100644 --- a/compat_test.go +++ b/compat_test.go @@ -35,8 +35,6 @@ func TestNotImplementedErrors(t *testing.T) { _, err := pg_query.ParsePlPgSqlToJSON("SELECT 1") check("ParsePlPgSqlToJSON", err) - _, err = pg_query.Summary("SELECT 1", 0) - check("Summary", err) } // TestScanTokens pins one token stream end-to-end through the public Scan diff --git a/internal/deparse/state.go b/internal/deparse/state.go index 43fe263..dad01bb 100644 --- a/internal/deparse/state.go +++ b/internal/deparse/state.go @@ -332,6 +332,11 @@ func Deparse(tree *ast.ParseResult) (result string, err error) { return string(out), nil } +// QuoteIdentifier exposes quoteIdentifier to the other internal packages +// that need ruleutils.c's quote_identifier (the summary walk renders table +// names with it). +func QuoteIdentifier(ident string) string { return quoteIdentifier(ident) } + // quoteIdentifier is ruleutils.c's quote_identifier (quote_all_identifiers // is always false in libpg_query). func quoteIdentifier(ident string) string { diff --git a/internal/summary/qsort.go b/internal/summary/qsort.go new file mode 100644 index 0000000..b892777 --- /dev/null +++ b/internal/summary/qsort.go @@ -0,0 +1,128 @@ +// pg_qsort (src/port/qsort.c via lib/sort_template.h): the Bentley & McIlroy +// quicksort PostgreSQL uses — list_sort() maps to it at the pin (port.h +// defines qsort as pg_qsort). It is not stable, so the order of +// equal-priority truncations depends on the exact algorithm; byte-parity +// needs the algorithm, not just the comparator. Same port as +// internal/normalize/qsort.go, over possible truncations. +package summary + +func med3T(a []*possibleTruncation, x, y, z int) int { + if cmpPossibleTruncations(a[x], a[y]) < 0 { + if cmpPossibleTruncations(a[y], a[z]) < 0 { + return y + } + if cmpPossibleTruncations(a[x], a[z]) < 0 { + return z + } + return x + } + if cmpPossibleTruncations(a[y], a[z]) > 0 { + return y + } + if cmpPossibleTruncations(a[x], a[z]) < 0 { + return x + } + return z +} + +func swapNT(a []*possibleTruncation, x, y, n int) { + for i := 0; i < n; i++ { + a[x+i], a[y+i] = a[y+i], a[x+i] + } +} + +// pgQsortTruncations sorts a exactly as ST_SORT in sort_template.h. +func pgQsortTruncations(a []*possibleTruncation) { + n := len(a) +loop: + if n < 7 { + for pm := 1; pm < n; pm++ { + for pl := pm; pl > 0 && cmpPossibleTruncations(a[pl-1], a[pl]) > 0; pl-- { + a[pl], a[pl-1] = a[pl-1], a[pl] + } + } + return + } + presorted := true + for pm := 1; pm < n; pm++ { + if cmpPossibleTruncations(a[pm-1], a[pm]) > 0 { + presorted = false + break + } + } + if presorted { + return + } + pm := n / 2 + if n > 7 { + pl := 0 + pn := n - 1 + if n > 40 { + d := n / 8 + pl = med3T(a, pl, pl+d, pl+2*d) + pm = med3T(a, pm-d, pm, pm+d) + pn = med3T(a, pn-2*d, pn-d, pn) + } + pm = med3T(a, pl, pm, pn) + } + a[0], a[pm] = a[pm], a[0] + pa, pb := 1, 1 + pc, pd := n-1, n-1 + for { + var r int + for pb <= pc { + if r = cmpPossibleTruncations(a[pb], a[0]); r > 0 { + break + } + if r == 0 { + a[pa], a[pb] = a[pb], a[pa] + pa++ + } + pb++ + } + for pb <= pc { + if r = cmpPossibleTruncations(a[pc], a[0]); r < 0 { + break + } + if r == 0 { + a[pc], a[pd] = a[pd], a[pc] + pd-- + } + pc-- + } + if pb > pc { + break + } + a[pb], a[pc] = a[pc], a[pb] + pb++ + pc-- + } + pn := n + d1 := min(pa, pb-pa) + swapNT(a, 0, pb-d1, d1) + d1 = min(pd-pc, pn-pd-1) + swapNT(a, pb, pn-d1, d1) + d1 = pb - pa + d2 := pd - pc + if d1 <= d2 { + // Recurse on left partition, then iterate on right partition. + if d1 > 1 { + pgQsortTruncations(a[:d1]) + } + if d2 > 1 { + a = a[pn-d2:] + n = d2 + goto loop + } + } else { + // Recurse on right partition, then iterate on left partition. + if d2 > 1 { + pgQsortTruncations(a[pn-d2 : pn]) + } + if d1 > 1 { + a = a[:d1] + n = d1 + goto loop + } + } +} diff --git a/internal/summary/stmt_types.go b/internal/summary/stmt_types.go new file mode 100644 index 0000000..b903c43 --- /dev/null +++ b/internal/summary/stmt_types.go @@ -0,0 +1,271 @@ +package summary + +import "github.com/sqlc-dev/oliphant/ast" + +// addStmtType is add_stmt_type_if_needed: an insertion-ordered set. +func (s *state) addStmtType(name string) { + for _, t := range s.statementTypes { + if t == name { + return + } + } + s.statementTypes = append(s.statementTypes, name) +} + +// stmtWalk is pg_query_summary_stmt_walk_impl +// (pg_query_summary_statement_type.c): record the statement type of every +// node the raw walker can reach, with explicit sub-walks for the four +// utility statements that wrap a query but are not raw-walkable themselves. +func (s *state) stmtWalk(item any) bool { + c := concrete(item) + if isNil(c) { + return false + } + + switch v := c.(type) { + case *ast.RawStmt: + return s.stmtWalk(v.Stmt) + case *ast.CreateTableAsStmt: + s.addStmtType("CreateTableAsStmt") + if v.Query != nil { + s.stmtWalk(v.Query) + } + case *ast.ExplainStmt: + s.addStmtType("ExplainStmt") + if v.Query != nil { + s.stmtWalk(v.Query) + } + case *ast.PrepareStmt: + s.addStmtType("PrepareStmt") + if v.Query != nil { + s.stmtWalk(v.Query) + } + case *ast.ViewStmt: + s.addStmtType("ViewStmt") + if v.Query != nil { + s.stmtWalk(v.Query) + } + case *ast.AlterCollationStmt: + s.addStmtType("AlterCollationStmt") + case *ast.AlterDatabaseSetStmt: + s.addStmtType("AlterDatabaseSetStmt") + case *ast.AlterDatabaseStmt: + s.addStmtType("AlterDatabaseStmt") + case *ast.AlterDefaultPrivilegesStmt: + s.addStmtType("AlterDefaultPrivilegesStmt") + case *ast.AlterDomainStmt: + s.addStmtType("AlterDomainStmt") + case *ast.AlterEnumStmt: + s.addStmtType("AlterEnumStmt") + case *ast.AlterEventTrigStmt: + s.addStmtType("AlterEventTrigStmt") + case *ast.AlterExtensionContentsStmt: + s.addStmtType("AlterExtensionContentsStmt") + case *ast.AlterExtensionStmt: + s.addStmtType("AlterExtensionStmt") + case *ast.AlterFdwStmt: + s.addStmtType("AlterFdwStmt") + case *ast.AlterForeignServerStmt: + s.addStmtType("AlterForeignServerStmt") + case *ast.AlterFunctionStmt: + s.addStmtType("AlterFunctionStmt") + case *ast.AlterObjectDependsStmt: + s.addStmtType("AlterObjectDependsStmt") + case *ast.AlterObjectSchemaStmt: + s.addStmtType("AlterObjectSchemaStmt") + case *ast.AlterOpFamilyStmt: + s.addStmtType("AlterOpFamilyStmt") + case *ast.AlterOperatorStmt: + s.addStmtType("AlterOperatorStmt") + case *ast.AlterOwnerStmt: + s.addStmtType("AlterOwnerStmt") + case *ast.AlterPolicyStmt: + s.addStmtType("AlterPolicyStmt") + case *ast.AlterPublicationStmt: + s.addStmtType("AlterPublicationStmt") + case *ast.AlterRoleSetStmt: + s.addStmtType("AlterRoleSetStmt") + case *ast.AlterRoleStmt: + s.addStmtType("AlterRoleStmt") + case *ast.AlterSeqStmt: + s.addStmtType("AlterSeqStmt") + case *ast.AlterStatsStmt: + s.addStmtType("AlterStatsStmt") + case *ast.AlterSubscriptionStmt: + s.addStmtType("AlterSubscriptionStmt") + case *ast.AlterSystemStmt: + s.addStmtType("AlterSystemStmt") + case *ast.AlterTableCmd: + s.addStmtType("AlterTableCmd") + case *ast.AlterTableMoveAllStmt: + s.addStmtType("AlterTableMoveAllStmt") + case *ast.AlterTableSpaceOptionsStmt: + s.addStmtType("AlterTableSpaceOptionsStmt") + case *ast.AlterTableStmt: + s.addStmtType("AlterTableStmt") + case *ast.AlterTSConfigurationStmt: + s.addStmtType("AlterTSConfigurationStmt") + case *ast.AlterTSDictionaryStmt: + s.addStmtType("AlterTSDictionaryStmt") + case *ast.AlterTypeStmt: + s.addStmtType("AlterTypeStmt") + case *ast.AlterUserMappingStmt: + s.addStmtType("AlterUserMappingStmt") + case *ast.CallStmt: + s.addStmtType("CallStmt") + case *ast.CheckPointStmt: + s.addStmtType("CheckPointStmt") + case *ast.ClosePortalStmt: + s.addStmtType("ClosePortalStmt") + case *ast.ClusterStmt: + s.addStmtType("ClusterStmt") + case *ast.CommentStmt: + s.addStmtType("CommentStmt") + case *ast.CompositeTypeStmt: + s.addStmtType("CompositeTypeStmt") + case *ast.ConstraintsSetStmt: + s.addStmtType("ConstraintsSetStmt") + case *ast.CopyStmt: + s.addStmtType("CopyStmt") + case *ast.CreateAmStmt: + s.addStmtType("CreateAmStmt") + case *ast.CreateCastStmt: + s.addStmtType("CreateCastStmt") + case *ast.CreateConversionStmt: + s.addStmtType("CreateConversionStmt") + case *ast.CreateDomainStmt: + s.addStmtType("CreateDomainStmt") + case *ast.CreateEnumStmt: + s.addStmtType("CreateEnumStmt") + case *ast.CreateEventTrigStmt: + s.addStmtType("CreateEventTrigStmt") + case *ast.CreateExtensionStmt: + s.addStmtType("CreateExtensionStmt") + case *ast.CreateFdwStmt: + s.addStmtType("CreateFdwStmt") + case *ast.CreateForeignServerStmt: + s.addStmtType("CreateForeignServerStmt") + case *ast.CreateForeignTableStmt: + s.addStmtType("CreateForeignTableStmt") + case *ast.CreateFunctionStmt: + s.addStmtType("CreateFunctionStmt") + case *ast.CreateOpClassStmt: + s.addStmtType("CreateOpClassStmt") + case *ast.CreateOpFamilyStmt: + s.addStmtType("CreateOpFamilyStmt") + case *ast.CreatePLangStmt: + s.addStmtType("CreatePLangStmt") + case *ast.CreatePolicyStmt: + s.addStmtType("CreatePolicyStmt") + case *ast.CreatePublicationStmt: + s.addStmtType("CreatePublicationStmt") + case *ast.CreateRangeStmt: + s.addStmtType("CreateRangeStmt") + case *ast.CreateRoleStmt: + s.addStmtType("CreateRoleStmt") + case *ast.CreateSchemaStmt: + s.addStmtType("CreateSchemaStmt") + case *ast.CreateSeqStmt: + s.addStmtType("CreateSeqStmt") + case *ast.CreateStatsStmt: + s.addStmtType("CreateStatsStmt") + case *ast.CreateStmt: + s.addStmtType("CreateStmt") + case *ast.CreateSubscriptionStmt: + s.addStmtType("CreateSubscriptionStmt") + case *ast.CreateTableSpaceStmt: + s.addStmtType("CreateTableSpaceStmt") + case *ast.CreateTransformStmt: + s.addStmtType("CreateTransformStmt") + case *ast.CreateTrigStmt: + s.addStmtType("CreateTrigStmt") + case *ast.CreateUserMappingStmt: + s.addStmtType("CreateUserMappingStmt") + case *ast.CreatedbStmt: + s.addStmtType("CreatedbStmt") + case *ast.DeallocateStmt: + s.addStmtType("DeallocateStmt") + case *ast.DeclareCursorStmt: + s.addStmtType("DeclareCursorStmt") + case *ast.DefineStmt: + s.addStmtType("DefineStmt") + case *ast.DeleteStmt: + s.addStmtType("DeleteStmt") + case *ast.DiscardStmt: + s.addStmtType("DiscardStmt") + case *ast.DoStmt: + s.addStmtType("DoStmt") + case *ast.DropOwnedStmt: + s.addStmtType("DropOwnedStmt") + case *ast.DropRoleStmt: + s.addStmtType("DropRoleStmt") + case *ast.DropStmt: + s.addStmtType("DropStmt") + case *ast.DropSubscriptionStmt: + s.addStmtType("DropSubscriptionStmt") + case *ast.DropTableSpaceStmt: + s.addStmtType("DropTableSpaceStmt") + case *ast.DropUserMappingStmt: + s.addStmtType("DropUserMappingStmt") + case *ast.DropdbStmt: + s.addStmtType("DropdbStmt") + case *ast.ExecuteStmt: + s.addStmtType("ExecuteStmt") + case *ast.FetchStmt: + s.addStmtType("FetchStmt") + case *ast.GrantRoleStmt: + s.addStmtType("GrantRoleStmt") + case *ast.GrantStmt: + s.addStmtType("GrantStmt") + case *ast.ImportForeignSchemaStmt: + s.addStmtType("ImportForeignSchemaStmt") + case *ast.IndexStmt: + s.addStmtType("IndexStmt") + case *ast.InsertStmt: + s.addStmtType("InsertStmt") + case *ast.ListenStmt: + s.addStmtType("ListenStmt") + case *ast.LoadStmt: + s.addStmtType("LoadStmt") + case *ast.LockStmt: + s.addStmtType("LockStmt") + case *ast.MergeStmt: + s.addStmtType("MergeStmt") + case *ast.NotifyStmt: + s.addStmtType("NotifyStmt") + case *ast.ReassignOwnedStmt: + s.addStmtType("ReassignOwnedStmt") + case *ast.RefreshMatViewStmt: + s.addStmtType("RefreshMatViewStmt") + case *ast.ReindexStmt: + s.addStmtType("ReindexStmt") + case *ast.RenameStmt: + s.addStmtType("RenameStmt") + case *ast.ReplicaIdentityStmt: + s.addStmtType("ReplicaIdentityStmt") + case *ast.RuleStmt: + s.addStmtType("RuleStmt") + case *ast.SecLabelStmt: + s.addStmtType("SecLabelStmt") + case *ast.SelectStmt: + s.addStmtType("SelectStmt") + case *ast.SetOperationStmt: + s.addStmtType("SetOperationStmt") + case *ast.TransactionStmt: + s.addStmtType("TransactionStmt") + case *ast.TruncateStmt: + s.addStmtType("TruncateStmt") + case *ast.UnlistenStmt: + s.addStmtType("UnlistenStmt") + case *ast.UpdateStmt: + s.addStmtType("UpdateStmt") + case *ast.VacuumStmt: + s.addStmtType("VacuumStmt") + case *ast.VariableSetStmt: + s.addStmtType("VariableSetStmt") + case *ast.VariableShowStmt: + s.addStmtType("VariableShowStmt") + } + + return walkChildren(item, s.stmtWalk) +} diff --git a/internal/summary/summary.go b/internal/summary/summary.go new file mode 100644 index 0000000..f115cec --- /dev/null +++ b/internal/summary/summary.go @@ -0,0 +1,441 @@ +package summary + +import ( + "strings" + + "github.com/sqlc-dev/oliphant/ast" + "github.com/sqlc-dev/oliphant/internal/deparse" +) + +// Error carries an ereport raised during the summary walk (there is exactly +// one reachable site: makeRangeVarFromNameList). +type Error struct { + Message string + Filename string + Funcname string +} + +func (e *Error) Error() string { return e.Message } + +// Summarize is pg_query_summary_internal (pg_query_summary.c) minus the raw +// parse, which the caller has already done: the summary walk, the +// statement-type walk, and — when truncateLimit is not -1 — the truncation +// pass. +func Summarize(tree *ast.ParseResult, truncateLimit int) (result *ast.SummaryResult, err error) { + defer func() { + if r := recover(); r != nil { + if se, ok := r.(*Error); ok { + result, err = nil, se + return + } + panic(r) + } + }() + + s := &state{} + root := rawStmtList(tree.Stmts) + + // pg_query_summary_walk: the main walk, then the deferred range-var pass + // (CTEs can be referenced before they are defined, so tables are only + // resolved against cte_names once the walk has seen everything). + if len(root) > 0 { + s.walk(root) + } + for _, rv := range s.rangeVars { + s.handleRangeVar(rv.node, rv.context) + } + + // pg_query_summary_statement_walk. + if len(root) > 0 { + s.stmtWalk(root) + } + + res := &ast.SummaryResult{ + Tables: s.tables, + CteNames: s.cteNames, + Functions: s.functions, + FilterColumns: s.filterColumns, + StatementTypes: s.statementTypes, + } + if len(s.aliases) > 0 { + // The C list becomes a protobuf map; duplicate keys collapse with the + // last occurrence winning, exactly as protobuf map decoding does. + res.Aliases = map[string]string{} + for _, kv := range s.aliases { + res.Aliases[kv.key] = kv.value + } + } + + if truncateLimit != -1 { + res.TruncatedQuery = truncate(tree.Stmts, truncateLimit) + } + return res, nil +} + +type rangeVarCtx struct { + node *ast.RangeVar + context ast.SummaryResult_Context +} + +type aliasKV struct{ key, value string } + +type state struct { + rangeVars []rangeVarCtx + tables []*ast.SummaryResult_Table + aliases []aliasKV + cteNames []string + functions []*ast.SummaryResult_Function + filterColumns []*ast.SummaryResult_FilterColumn + statementTypes []string + saveFilterColumns bool +} + +// addRangeVar is add_range_var (pg_query_summary.c): wrap a FROM-clause item +// (or statement target relation) and stash it for the deferred pass. +func (s *state) addRangeVar(item any, context ast.SummaryResult_Context) { + c := concrete(item) + if isNil(c) { + return + } + switch v := c.(type) { + case *ast.JoinExpr: + s.addRangeVar(v.Larg, context) + s.addRangeVar(v.Rarg, context) + // je->quals is handled by the regular tree walk. + case *ast.RangeTableSample: + s.addRangeVar(v.Relation, context) + case *ast.JsonTable, *ast.RangeTableFunc, *ast.RangeFunction, *ast.RangeSubselect: + // These are handled by the tree walker. + case *ast.RangeVar: + s.rangeVars = append(s.rangeVars, rangeVarCtx{node: v, context: context}) + default: + // elog(ERROR, "unexpected node type"): unreachable for grammar-built + // trees (table_ref only produces the shapes above). + panic(&Error{Message: "unexpected node type in add_range_var"}) + } +} + +func (s *state) addRangeVarList(clause []*ast.Node, context ast.SummaryResult_Context) { + for _, n := range clause { + s.addRangeVar(n, context) + } +} + +// addFunction is add_function: name via NameListToString, schema from the +// qualification, function from the last name part. +func (s *state) addFunction(funcname []*ast.Node, context ast.SummaryResult_Context) { + fn := &ast.SummaryResult_Function{ + Name: nameListToString(funcname), + Context: context, + } + switch len(funcname) { + case 3: + fn.SchemaName = funcname[1].GetString_().GetSval() + case 2: + fn.SchemaName = funcname[0].GetString_().GetSval() + } + if len(funcname) > 0 { + fn.FunctionName = funcname[len(funcname)-1].GetString_().GetSval() + } + s.functions = append(s.functions, fn) +} + +// walk is pg_query_summary_walk_impl. Returning true aborts the walk up the +// chain, exactly like a C tree-walker callback. +func (s *state) walk(item any) bool { + c := concrete(item) + if isNil(c) { + return false + } + + switch v := c.(type) { + case *ast.CommonTableExpr: + s.cteNames = append(s.cteNames, v.Ctename) + + case *ast.CallStmt: + if v.Funccall != nil { + return s.walk(v.Funccall) + } + // The C case falls through into the SelectStmt arm and reads garbage; + // unreachable, since the grammar always sets funccall. + return false + + case *ast.SelectStmt: + // Don't descend into sub-SELECTs in the WHERE clause when saving + // filter columns. + if s.saveFilterColumns { + return true + } + if v.Op == ast.SetOperation_SETOP_NONE { + s.addRangeVarList(v.FromClause, ast.SummaryResult_Select) + } + // For SETOP_UNION/EXCEPT/INTERSECT the walkChildren call at the end + // handles larg/rarg. + if v.IntoClause != nil { + s.addRangeVar(v.IntoClause.Rel, ast.SummaryResult_DDL) + } + if v.WhereClause != nil { + // The WHERE clause is intentionally walked twice; when saving + // filter columns we don't descend into sub-SELECTs. + s.saveFilterColumns = true + s.walk(v.WhereClause) + s.saveFilterColumns = false + } + + case *ast.InsertStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DML) + + case *ast.UpdateStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DML) + s.addRangeVarList(v.FromClause, ast.SummaryResult_Select) + + case *ast.MergeStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DML) + + case *ast.DeleteStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DML) + s.addRangeVarList(v.UsingClause, ast.SummaryResult_Select) + + case *ast.CopyStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_Select) + s.walk(v.Query) + + case *ast.AlterTableStmt: + // `ALTER INDEX index_name` is ignored. + if v.Objtype != ast.ObjectType_OBJECT_INDEX { + s.addRangeVar(v.Relation, ast.SummaryResult_DDL) + } + + case *ast.CreateStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DDL) + + case *ast.CreateTableAsStmt: + if v.Into != nil && v.Into.Rel != nil { + s.addRangeVar(v.Into.Rel, ast.SummaryResult_DDL) + } + s.walk(v.Query) + + case *ast.TruncateStmt: + s.addRangeVarList(v.Relations, ast.SummaryResult_DDL) + + case *ast.ViewStmt: + s.addRangeVar(v.View, ast.SummaryResult_DDL) + s.walk(v.Query) + + case *ast.IndexStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DDL) + for _, ie := range v.IndexParams { + s.walk(ie.GetIndexElem().GetExpr()) + } + s.walk(v.WhereClause) + + case *ast.CreateTrigStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DDL) + + case *ast.RuleStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DDL) + + case *ast.VacuumStmt: + for _, r := range v.Rels { + s.addRangeVar(r.GetVacuumRelation().GetRelation(), ast.SummaryResult_DDL) + } + + case *ast.RefreshMatViewStmt: + s.addRangeVar(v.Relation, ast.SummaryResult_DDL) + + case *ast.DropStmt: + switch v.RemoveType { + case ast.ObjectType_OBJECT_TABLE: + for _, obj := range v.Objects { + if list := obj.GetList(); list != nil { + if len(list.Items) == 0 { + continue + } + s.addRangeVar(makeRangeVarFromNameList(list.Items), ast.SummaryResult_DDL) + } + } + case ast.ObjectType_OBJECT_RULE, ast.ObjectType_OBJECT_TRIGGER: + for _, obj := range v.Objects { + if list := obj.GetList(); list != nil { + // Ignore the last string (the rule/trigger name). + items := list.Items[:max(len(list.Items)-1, 0)] + if len(items) == 0 { + continue + } + s.addRangeVar(makeRangeVarFromNameList(items), ast.SummaryResult_DDL) + } + } + case ast.ObjectType_OBJECT_FUNCTION: + if len(v.Objects) > 0 { + if obj := v.Objects[0].GetObjectWithArgs(); obj != nil && len(obj.Objname) > 0 { + s.addFunction(obj.Objname, ast.SummaryResult_DDL) + } + } + } + + case *ast.GrantStmt: + switch v.Objtype { + case ast.ObjectType_OBJECT_TABLE: + for _, obj := range v.Objects { + if rv := obj.GetRangeVar(); rv != nil { + s.addRangeVar(rv, ast.SummaryResult_DDL) + } + } + case ast.ObjectType_OBJECT_FUNCTION, ast.ObjectType_OBJECT_PROCEDURE, + ast.ObjectType_OBJECT_ROUTINE: + for _, obj := range v.Objects { + if owa := obj.GetObjectWithArgs(); owa != nil && len(owa.Objname) > 0 { + s.addFunction(owa.Objname, ast.SummaryResult_DDL) + } + } + } + + case *ast.LockStmt: + s.addRangeVarList(v.Relations, ast.SummaryResult_DDL) + + case *ast.ExplainStmt: + return s.walk(v.Query) + + case *ast.CreateFunctionStmt: + s.addFunction(v.Funcname, ast.SummaryResult_DDL) + + case *ast.RenameStmt: + switch v.RenameType { + case ast.ObjectType_OBJECT_TABLE: + s.addRangeVar(v.Relation, ast.SummaryResult_DDL) + s.addRangeVar(&ast.RangeVar{ + Schemaname: v.Relation.GetSchemaname(), + Relname: v.Newname, + Inh: true, + Relpersistence: "p", + Location: -1, + }, ast.SummaryResult_DDL) + case ast.ObjectType_OBJECT_FUNCTION, ast.ObjectType_OBJECT_PROCEDURE, + ast.ObjectType_OBJECT_ROUTINE: + if owa := v.Object.GetObjectWithArgs(); owa != nil { + s.addFunction(owa.Objname, ast.SummaryResult_DDL) + s.addFunction([]*ast.Node{makeStringNode(v.Newname)}, ast.SummaryResult_DDL) + } + } + + case *ast.PrepareStmt: + return s.walk(v.Query) + + case *ast.RawStmt: + return s.walk(v.Stmt) + + case *ast.FuncCall: + s.addFunction(v.Funcname, ast.SummaryResult_Call) + + case *ast.ColumnRef: + // Added to avoid needing subselect_items, like Rust and Ruby use. + if !s.saveFilterColumns { + break + } + if len(v.Fields) == 0 { + break + } + column := v.Fields[len(v.Fields)-1].GetString_() + // Check that we are not in the A_Star case here. (Columns can be + // stars, but nothing else can.) + if column == nil { + break + } + fc := &ast.SummaryResult_FilterColumn{Column: column.Sval} + switch len(v.Fields) { + case 2: + fc.TableName = v.Fields[0].GetString_().GetSval() + case 3: + fc.SchemaName = v.Fields[0].GetString_().GetSval() + fc.TableName = v.Fields[1].GetString_().GetSval() + } + s.filterColumns = append(s.filterColumns, fc) + } + + return walkChildren(item, s.walk) +} + +// rangeVarToName is range_var_to_name: quote_identifier-rendered, dotted. +func rangeVarToName(rv *ast.RangeVar) string { + var b strings.Builder + if rv.Schemaname != "" { + b.WriteString(deparse.QuoteIdentifier(rv.Schemaname)) + b.WriteByte('.') + } + b.WriteString(deparse.QuoteIdentifier(rv.Relname)) + return b.String() +} + +// cteNamesInclude is cte_names_include: exact-match scan. +func (s *state) cteNamesInclude(relname string) bool { + for _, name := range s.cteNames { + if name == relname { + return true + } + } + return false +} + +// handleRangeVar is handle_range_var: emit a table (unless the name is a CTE) +// and an alias entry. +func (s *state) handleRangeVar(rv *ast.RangeVar, context ast.SummaryResult_Context) { + if rv == nil { + return + } + if !s.cteNamesInclude(rv.Relname) { + s.tables = append(s.tables, &ast.SummaryResult_Table{ + Name: rangeVarToName(rv), + SchemaName: rv.Schemaname, + TableName: rv.Relname, + Context: context, + }) + } + if rv.Alias != nil { + s.aliases = append(s.aliases, aliasKV{key: rv.Alias.Aliasname, value: rangeVarToName(rv)}) + } +} + +// nameListToString is NameListToString (catalog/namespace.c): dotted, no +// quoting; A_Star renders as "*". +func nameListToString(names []*ast.Node) string { + var b strings.Builder + for i, n := range names { + if i > 0 { + b.WriteByte('.') + } + if s := n.GetString_(); s != nil { + b.WriteString(s.Sval) + } else { + b.WriteString("*") + } + } + return b.String() +} + +// makeRangeVarFromNameList (makefuncs.c; vendored by libpg_query into +// src_backend_catalog_namespace.c, which is the filename its ereport carries). +func makeRangeVarFromNameList(names []*ast.Node) *ast.RangeVar { + rv := &ast.RangeVar{Inh: true, Relpersistence: "p", Location: -1} + switch len(names) { + case 1: + rv.Relname = names[0].GetString_().GetSval() + case 2: + rv.Schemaname = names[0].GetString_().GetSval() + rv.Relname = names[1].GetString_().GetSval() + case 3: + rv.Catalogname = names[0].GetString_().GetSval() + rv.Schemaname = names[1].GetString_().GetSval() + rv.Relname = names[2].GetString_().GetSval() + default: + panic(&Error{ + Message: "improper relation name (too many dotted names): " + nameListToString(names), + Filename: "src_backend_catalog_namespace.c", + Funcname: "makeRangeVarFromNameList", + }) + } + return rv +} + +func makeStringNode(s string) *ast.Node { + return &ast.Node{Node: &ast.Node_String_{String_: &ast.String{Sval: s}}} +} diff --git a/internal/summary/truncate.go b/internal/summary/truncate.go new file mode 100644 index 0000000..c22b689 --- /dev/null +++ b/internal/summary/truncate.go @@ -0,0 +1,375 @@ +package summary + +import ( + "strings" + + "github.com/sqlc-dev/oliphant/ast" + "github.com/sqlc-dev/oliphant/internal/deparse" +) + +// Port of pg_query_summary_truncate.c: deparse the statements; if the result +// is over the limit, collect the possible truncations (target lists, WHERE +// clauses, VALUES lists, INSERT column lists, CTE bodies), sort them deepest +// then longest first, and apply them cumulatively until the deparse fits; +// fall back to a plain multibyte-aware chop. + +type truncationAttr int + +const ( + truncTargetList truncationAttr = iota + truncWhereClause + truncValuesLists + truncCols + truncCTEQuery +) + +type possibleTruncation struct { + attr truncationAttr + node any + depth int32 + length int32 +} + +type truncationState struct { + truncations []*possibleTruncation + depth int32 +} + +// truncate is pg_query_summary_truncate. +func truncate(stmts []*ast.RawStmt, truncateLimit int) string { + state := &truncationState{} + + output := deparseRawStmtList(stmts) + if len(output) <= truncateLimit { + return output + } + + if len(stmts) > 0 { + state.generate(rawStmtList(stmts)) + } + pgQsortTruncations(state.truncations) + return applyTruncations(stmts, state, truncateLimit) +} + +// truncateMbstr is truncate_mbstr: chop to max_chars characters (multibyte +// aware, pg_mblen-style) with a "..." suffix. max_chars is a size_t in C, so +// a limit below 3 wraps around and the clip keeps everything, appending the +// ellipsis to the full string. +func truncateMbstr(s string, maxChars int) string { + if mbstrlen(s) <= maxChars { + return s + } + nBytes := len(s) + if maxChars >= 3 { + nBytes = mbCharClipLen(s, maxChars-3) + } + return s[:nBytes] + "..." +} + +func (ts *truncationState) add(attr truncationAttr, node any, length int32) { + // Don't bother truncating if it won't become shorter. + if length <= 3 { + return + } + ts.truncations = append(ts.truncations, &possibleTruncation{ + attr: attr, + node: node, + depth: ts.depth, + length: length, + }) +} + +func (ts *truncationState) addWhereClause(node any, whereClause *ast.Node) { + if whereClause == nil { + return + } + ts.add(truncWhereClause, node, whereClauseLen(whereClause)) +} + +// generate is generate_possible_truncations. +func (ts *truncationState) generate(item any) bool { + c := concrete(item) + if isNil(c) { + return false + } + + switch v := c.(type) { + case *ast.RawStmt: + return ts.generate(v.Stmt) + + case *ast.SelectStmt: + if len(v.TargetList) != 0 { + ts.add(truncTargetList, v, selectTargetListLen(v.TargetList)) + } + ts.addWhereClause(v, v.WhereClause) + if len(v.ValuesLists) != 0 { + ts.add(truncValuesLists, v, selectValuesListsLen(v.ValuesLists)) + } + + case *ast.InsertStmt: + if len(v.Cols) != 0 { + ts.add(truncCols, v, colsLen(v.Cols)) + } + + case *ast.UpdateStmt: + if len(v.TargetList) != 0 { + ts.add(truncTargetList, v, updateTargetListLen(v.TargetList)) + } + ts.addWhereClause(v, v.WhereClause) + + case *ast.DeleteStmt: + ts.addWhereClause(v, v.WhereClause) + + case *ast.CopyStmt: + ts.addWhereClause(v, v.WhereClause) + + case *ast.IndexStmt: + ts.addWhereClause(v, v.WhereClause) + + case *ast.RuleStmt: + ts.addWhereClause(v, v.WhereClause) + + case *ast.CommonTableExpr: + if v.Ctequery != nil { + ts.add(truncCTEQuery, v, int32(deparseStmtLen(v.Ctequery))) + } + + case *ast.InferClause: + ts.addWhereClause(v, v.WhereClause) + + case *ast.OnConflictClause: + if len(v.TargetList) != 0 { + ts.add(truncTargetList, v, updateTargetListLen(v.TargetList)) + } + ts.addWhereClause(v, v.WhereClause) + } + + // The supports gate lives in walkChildren's default arm; the depth + // save/restore brackets the descent exactly as the C walker call does + // (list nodes count as a level, matching WALK on a List field). + oldDepth := ts.depth + ts.depth++ + result := walkChildren(item, ts.generate) + ts.depth = oldDepth + return result +} + +// cmpPossibleTruncations is cmp_possible_truncations: deepest first, then +// longest first. +func cmpPossibleTruncations(a, b *possibleTruncation) int { + if d := b.depth - a.depth; d != 0 { + return int(d) + } + return int(b.length - a.length) +} + +// globalReplace is global_replace: in-place scan-and-splice; equivalent to a +// left-to-right non-overlapping replace when the replacement is no longer +// than the pattern (asserted in C). +func globalReplace(s, pattern, replacement string) string { + return strings.ReplaceAll(s, pattern, replacement) +} + +// applyTruncations is apply_truncations: apply cumulatively in sorted order, +// re-deparsing after each, until the output fits. +func applyTruncations(stmts []*ast.RawStmt, state *truncationState, truncationLimit int) string { + output := "" + deparsed := false + + for _, truncation := range state.truncations { + switch v := truncation.node.(type) { + case *ast.SelectStmt: + switch truncation.attr { + case truncTargetList: + v.TargetList = []*ast.Node{dummyTargetNode()} + case truncWhereClause: + v.WhereClause = dummyColumnNode() + case truncValuesLists: + v.ValuesLists = []*ast.Node{{Node: &ast.Node_List{List: &ast.List{Items: []*ast.Node{dummyColumnNode()}}}}} + } + case *ast.UpdateStmt: + switch truncation.attr { + case truncTargetList: + v.TargetList = []*ast.Node{dummyTargetNode()} + case truncWhereClause: + v.WhereClause = dummyColumnNode() + } + case *ast.InsertStmt: + v.Cols = []*ast.Node{dummyTargetNode()} + case *ast.DeleteStmt: + v.WhereClause = dummyColumnNode() + case *ast.CopyStmt: + v.WhereClause = dummyColumnNode() + case *ast.IndexStmt: + v.WhereClause = dummyColumnNode() + case *ast.RuleStmt: + v.WhereClause = dummyColumnNode() + case *ast.CommonTableExpr: + v.Ctequery = dummySelectNode(nil, dummyColumnNode(), nil) + case *ast.InferClause: + v.WhereClause = dummyColumnNode() + case *ast.OnConflictClause: + switch truncation.attr { + case truncTargetList: + v.TargetList = []*ast.Node{dummyTargetNode()} + case truncWhereClause: + v.WhereClause = dummyColumnNode() + } + default: + panic(&Error{Message: "apply_truncations() got unknown truncation type"}) + } + + output = deparseRawStmtList(stmts) + deparsed = true + + output = globalReplace(output, `SELECT "…" AS "…"`, `SELECT "…"`) + output = globalReplace(output, `SELECT WHERE "…"`, `"…"`) + output = globalReplace(output, `"…"`, `...`) + + if len(output) <= truncationLimit { + return output + } + } + + if !deparsed { + output = deparseRawStmtList(stmts) + } + return truncateMbstr(output, truncationLimit) +} + +// --- dummy nodes ------------------------------------------------------------- + +func dummyColumnNode() *ast.Node { + return &ast.Node{Node: &ast.Node_ColumnRef{ColumnRef: &ast.ColumnRef{ + Fields: []*ast.Node{makeStringNode("…")}, + Location: 0, + }}} +} + +func dummyTargetNode() *ast.Node { + return &ast.Node{Node: &ast.Node_ResTarget{ResTarget: &ast.ResTarget{ + Name: "…", + Val: dummyColumnNode(), + Location: 0, + }}} +} + +// dummySelect leaves every other field zeroed, like makeNode does; the +// protobuf enums for op/limitOption are their explicit SETOP_NONE / +// LIMIT_OPTION_DEFAULT values (the C zero values at the pin, patch 05). +func dummySelect(targetList []*ast.Node, whereClause *ast.Node, valuesLists []*ast.Node) *ast.SelectStmt { + return &ast.SelectStmt{ + TargetList: targetList, + WhereClause: whereClause, + ValuesLists: valuesLists, + LimitOption: ast.LimitOption_LIMIT_OPTION_DEFAULT, + Op: ast.SetOperation_SETOP_NONE, + } +} + +func dummySelectNode(targetList []*ast.Node, whereClause *ast.Node, valuesLists []*ast.Node) *ast.Node { + return &ast.Node{Node: &ast.Node_SelectStmt{SelectStmt: dummySelect(targetList, whereClause, valuesLists)}} +} + +func dummyRangeVarX() *ast.RangeVar { + return &ast.RangeVar{Relname: "x", Inh: true, Relpersistence: "p", Location: 0} +} + +// dummyInsert sets override = 1 exactly as the C code does — which is +// OVERRIDING_USER_VALUE in the C enum (protobuf value 2, after the UNDEFINED +// slot), inflating the measured length by "OVERRIDING USER VALUE ". A sort +// key quirk, ported faithfully. +func dummyInsert(cols []*ast.Node) *ast.Node { + return &ast.Node{Node: &ast.Node_InsertStmt{InsertStmt: &ast.InsertStmt{ + Relation: dummyRangeVarX(), + Cols: cols, + Override: ast.OverridingKind_OVERRIDING_USER_VALUE, + }}} +} + +func dummyUpdate(targetList []*ast.Node) *ast.Node { + return &ast.Node{Node: &ast.Node_UpdateStmt{UpdateStmt: &ast.UpdateStmt{ + Relation: dummyRangeVarX(), + TargetList: targetList, + }}} +} + +// --- length measurement ------------------------------------------------------ + +func selectTargetListLen(nodes []*ast.Node) int32 { + return int32(deparseStmtLen(dummySelectNode(nodes, nil, nil))) - 7 /* "SELECT " */ +} + +func selectValuesListsLen(nodes []*ast.Node) int32 { + return int32(deparseStmtLen(dummySelectNode(nil, nil, nodes))) - 9 /* "VALUES ()" */ +} + +func updateTargetListLen(nodes []*ast.Node) int32 { + return int32(deparseStmtLen(dummyUpdate(nodes))) - 13 /* "UPDATE x SET " */ +} + +func whereClauseLen(node *ast.Node) int32 { + return int32(deparseStmtLen(dummySelectNode(nil, node, nil))) - 13 /* "SELECT WHERE " */ +} + +func colsLen(nodes []*ast.Node) int32 { + return int32(deparseStmtLen(dummyInsert(nodes))) - 31 /* "INSERT INTO x () DEFAULT VALUES" */ +} + +// deparseStmtLen is deparse_stmt_len: wrap in a RawStmt and measure. +func deparseStmtLen(node *ast.Node) int { + raw := &ast.RawStmt{Stmt: node, StmtLocation: -1, StmtLen: 0} + return len(deparseRawStmtList([]*ast.RawStmt{raw})) +} + +// deparseRawStmtList is deparse_raw_stmt_list: statements joined with "; ". +// A deparse failure ereports in C and unwinds to pg_query_summary's catch +// block; the panic here unwinds to Summarize's recover the same way. +func deparseRawStmtList(stmts []*ast.RawStmt) string { + out, err := deparse.Deparse(&ast.ParseResult{Stmts: stmts}) + if err != nil { + panic(&Error{Message: err.Error()}) + } + return out +} + +// --- multibyte helpers (mb/mbutils.c, UTF-8 database encoding) --------------- + +// pgUtfMblen is pg_utf_mblen: sequence length from the first byte. +func pgUtfMblen(b byte) int { + switch { + case b&0x80 == 0: + return 1 + case b&0xE0 == 0xC0: + return 2 + case b&0xF0 == 0xE0: + return 3 + case b&0xF8 == 0xF0: + return 4 + default: + return 1 + } +} + +// mbstrlen is pg_mbstrlen. +func mbstrlen(s string) int { + n := 0 + for i := 0; i < len(s); i += pgUtfMblen(s[i]) { + n++ + } + return n +} + +// mbCharClipLen is pg_mbcharcliplen: byte length of the first limit +// characters. +func mbCharClipLen(s string, limit int) int { + chars, i := 0, 0 + for i < len(s) && chars < limit { + i += pgUtfMblen(s[i]) + chars++ + } + if i > len(s) { + return len(s) + } + return i +} diff --git a/internal/summary/walker.go b/internal/summary/walker.go new file mode 100644 index 0000000..3797345 --- /dev/null +++ b/internal/summary/walker.go @@ -0,0 +1,286 @@ +// Package summary ports libpg_query's summary API: pg_query_summary.c (the +// table/alias/CTE/function/filter-column walk), pg_query_summary_statement_type.c +// (the statement-type walk), and pg_query_summary_truncate.c (deparse-driven +// smart truncation). +package summary + +import ( + "reflect" + + "github.com/sqlc-dev/oliphant/ast" +) + +// The C walks operate on Node* where a node may be a T_List; the callback is +// invoked for list nodes too (which matters for the truncation walk's depth +// accounting). nodeList and rawStmtList model those list nodes over the +// protobuf tree. +type nodeList []*ast.Node + +type rawStmtList []*ast.RawStmt + +// concrete unwraps an *ast.Node into its inner concrete pointer (the oneof +// member), so callbacks can switch on one representation regardless of +// whether a child arrived generically (*ast.Node) or as a typed field +// (*ast.RangeVar, *ast.FuncCall, ...). +func concrete(item any) any { + n, ok := item.(*ast.Node) + if !ok { + return item + } + if n == nil || n.Node == nil { + return nil + } + // Every oneof wrapper (ast.Node_SelectStmt, ...) has exactly one field. + return reflect.ValueOf(n.Node).Elem().Field(0).Interface() +} + +// wl boxes a list-valued child the way the C walker passes a List node to the +// callback: NIL (empty) lists short-circuit to "no child". +func wl(list []*ast.Node) any { + if len(list) == 0 { + return nil + } + return nodeList(list) +} + +// isNil reports whether a child slot is empty (NULL in the C tree). +func isNil(item any) bool { + if item == nil { + return true + } + v := reflect.ValueOf(item) + return v.Kind() == reflect.Pointer && v.IsNil() +} + +// walkChildren is raw_expression_tree_walker_impl (src/backend/nodes/ +// nodeFuncs.c, PostgreSQL 17) gated exactly as pg_query_raw_tree_walker_supports +// allows: node types outside the walker's switch return false without +// descending (the summary C files check the gate before calling the walker; +// folding it into the default arm is equivalent). Child order is the C +// walker's, verbatim — it decides the order of every summary list. +func walkChildren(item any, cb func(any) bool) bool { + w := func(children ...any) bool { + for _, c := range children { + if isNil(c) { + continue + } + if cb(c) { + return true + } + } + return false + } + + switch v := concrete(item).(type) { + case rawStmtList: + for _, rs := range v { + if cb(rs) { + return true + } + } + return false + case nodeList: + for _, n := range v { + if n == nil || n.Node == nil { + continue + } + if cb(n) { + return true + } + } + return false + case *ast.List: + // A List that appears as a node (e.g. the [function, coldeflist] + // sublists of RangeFunction->functions). + for _, n := range v.Items { + if n == nil || n.Node == nil { + continue + } + if cb(n) { + return true + } + } + return false + case *ast.JsonFormat, *ast.SetToDefault, *ast.CurrentOfExpr, + *ast.SQLValueFunction, *ast.Integer, *ast.Float, *ast.Boolean, + *ast.String, *ast.BitString, *ast.ParamRef, *ast.A_Const, *ast.A_Star, + *ast.MergeSupportFunc: + // primitive node types with no subnodes + return false + case *ast.Alias: + // we assume the colnames list isn't interesting + return false + case *ast.RangeVar: + return w(v.Alias) + case *ast.GroupingFunc: + return w(wl(v.Args)) + case *ast.SubLink: + return w(v.Testexpr, v.Subselect) + case *ast.CaseExpr: + if w(v.Arg) { + return true + } + // we assume walker doesn't care about CaseWhens, either + for _, item := range v.Args { + when := item.GetCaseWhen() + if w(when.GetExpr(), when.GetResult()) { + return true + } + } + return w(v.Defresult) + case *ast.RowExpr: + // Assume colnames isn't interesting + return w(wl(v.Args)) + case *ast.CoalesceExpr: + return w(wl(v.Args)) + case *ast.MinMaxExpr: + return w(wl(v.Args)) + case *ast.XmlExpr: + // we assume walker doesn't care about arg_names + return w(wl(v.NamedArgs), wl(v.Args)) + case *ast.JsonReturning: + return w(v.Format) + case *ast.JsonValueExpr: + return w(v.RawExpr, v.FormattedExpr, v.Format) + case *ast.JsonParseExpr: + return w(v.Expr, v.Output) + case *ast.JsonScalarExpr: + return w(v.Expr, v.Output) + case *ast.JsonSerializeExpr: + return w(v.Expr, v.Output) + case *ast.JsonConstructorExpr: + return w(wl(v.Args), v.Func, v.Coercion, v.Returning) + case *ast.JsonIsPredicate: + return w(v.Expr) + case *ast.JsonArgument: + return w(v.Val) + case *ast.JsonFuncExpr: + return w(v.ContextItem, v.Pathspec, wl(v.Passing), v.Output, v.OnEmpty, v.OnError) + case *ast.JsonBehavior: + return w(v.Expr) + case *ast.JsonTable: + return w(v.ContextItem, v.Pathspec, wl(v.Passing), wl(v.Columns), v.OnError) + case *ast.JsonTableColumn: + return w(v.TypeName, v.OnEmpty, v.OnError, wl(v.Columns)) + case *ast.JsonTablePathSpec: + return w(v.String_) + case *ast.NullTest: + return w(v.Arg) + case *ast.BooleanTest: + return w(v.Arg) + case *ast.JoinExpr: + // using list is deemed uninteresting + return w(v.Larg, v.Rarg, v.Quals, v.Alias) + case *ast.IntoClause: + // colNames, options are deemed uninteresting + // viewQuery should be null in raw parsetree, but check it + return w(v.Rel, v.ViewQuery) + case *ast.InsertStmt: + return w(v.Relation, wl(v.Cols), v.SelectStmt, v.OnConflictClause, + wl(v.ReturningList), v.WithClause) + case *ast.DeleteStmt: + return w(v.Relation, wl(v.UsingClause), v.WhereClause, + wl(v.ReturningList), v.WithClause) + case *ast.UpdateStmt: + return w(v.Relation, wl(v.TargetList), v.WhereClause, wl(v.FromClause), + wl(v.ReturningList), v.WithClause) + case *ast.MergeStmt: + return w(v.Relation, v.SourceRelation, v.JoinCondition, + wl(v.MergeWhenClauses), wl(v.ReturningList), v.WithClause) + case *ast.MergeWhenClause: + return w(v.Condition, wl(v.TargetList), wl(v.Values)) + case *ast.SelectStmt: + return w(wl(v.DistinctClause), v.IntoClause, wl(v.TargetList), + wl(v.FromClause), v.WhereClause, wl(v.GroupClause), v.HavingClause, + wl(v.WindowClause), wl(v.ValuesLists), wl(v.SortClause), + v.LimitOffset, v.LimitCount, wl(v.LockingClause), v.WithClause, + v.Larg, v.Rarg) + case *ast.PLAssignStmt: + return w(wl(v.Indirection), v.Val) + case *ast.A_Expr: + // operator name is deemed uninteresting + return w(v.Lexpr, v.Rexpr) + case *ast.BoolExpr: + return w(wl(v.Args)) + case *ast.ColumnRef: + // we assume the fields contain nothing interesting + return false + case *ast.FuncCall: + // function name is deemed uninteresting + return w(wl(v.Args), wl(v.AggOrder), v.AggFilter, v.Over) + case *ast.NamedArgExpr: + return w(v.Arg) + case *ast.A_Indices: + return w(v.Lidx, v.Uidx) + case *ast.A_Indirection: + return w(v.Arg, wl(v.Indirection)) + case *ast.A_ArrayExpr: + return w(wl(v.Elements)) + case *ast.ResTarget: + return w(wl(v.Indirection), v.Val) + case *ast.MultiAssignRef: + return w(v.Source) + case *ast.TypeCast: + return w(v.Arg, v.TypeName) + case *ast.CollateClause: + return w(v.Arg) + case *ast.SortBy: + return w(v.Node) + case *ast.WindowDef: + return w(wl(v.PartitionClause), wl(v.OrderClause), v.StartOffset, v.EndOffset) + case *ast.RangeSubselect: + return w(v.Subquery, v.Alias) + case *ast.RangeFunction: + return w(wl(v.Functions), v.Alias, wl(v.Coldeflist)) + case *ast.RangeTableSample: + // method name is deemed uninteresting + return w(v.Relation, wl(v.Args), v.Repeatable) + case *ast.RangeTableFunc: + return w(v.Docexpr, v.Rowexpr, wl(v.Namespaces), wl(v.Columns), v.Alias) + case *ast.RangeTableFuncCol: + return w(v.Colexpr, v.Coldefexpr) + case *ast.TypeName: + // type name itself is deemed uninteresting + return w(wl(v.Typmods), wl(v.ArrayBounds)) + case *ast.ColumnDef: + // for now, constraints are ignored + return w(v.TypeName, v.RawDefault, v.CollClause) + case *ast.IndexElem: + // collation and opclass names are deemed uninteresting + return w(v.Expr) + case *ast.GroupingSet: + return w(wl(v.Content)) + case *ast.LockingClause: + return w(wl(v.LockedRels)) + case *ast.XmlSerialize: + return w(v.Expr, v.TypeName) + case *ast.WithClause: + return w(wl(v.Ctes)) + case *ast.InferClause: + return w(wl(v.IndexElems), v.WhereClause) + case *ast.OnConflictClause: + return w(v.Infer, wl(v.TargetList), v.WhereClause) + case *ast.CommonTableExpr: + // search_clause and cycle_clause are not interesting here + return w(v.Ctequery) + case *ast.JsonOutput: + return w(v.TypeName, v.Returning) + case *ast.JsonKeyValue: + return w(v.Key, v.Value) + case *ast.JsonObjectConstructor: + return w(v.Output, wl(v.Exprs)) + case *ast.JsonArrayConstructor: + return w(v.Output, wl(v.Exprs)) + case *ast.JsonAggConstructor: + return w(v.Output, wl(v.AggOrder), v.AggFilter, v.Over) + case *ast.JsonObjectAgg: + return w(v.Constructor, v.Arg) + case *ast.JsonArrayAgg: + return w(v.Constructor, v.Arg) + case *ast.JsonArrayQueryConstructor: + return w(v.Output, v.Query) + default: + // Not covered by pg_query_raw_tree_walker_supports: no descent. + return false + } +} diff --git a/parser/parser.go b/parser/parser.go index 7100fac..3506b22 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -8,6 +8,7 @@ package parser import ( + "errors" "fmt" "strings" @@ -20,6 +21,7 @@ import ( "github.com/sqlc-dev/oliphant/internal/lexer" "github.com/sqlc-dev/oliphant/internal/normalize" "github.com/sqlc-dev/oliphant/internal/parse" + "github.com/sqlc-dev/oliphant/internal/summary" "github.com/sqlc-dev/oliphant/internal/xxh3" ) @@ -247,6 +249,25 @@ func IsUtilityStmt(input string) (result []bool, err error) { return result, nil } +// SummaryToProtobuf is pg_query_summary: parse, walk for tables/aliases/ +// CTEs/functions/filter columns/statement types, and — unless truncateLimit +// is -1 — produce the smart-truncated query text. func SummaryToProtobuf(input string, truncateLimit int) ([]byte, error) { - return nil, errNotImplemented("SummaryToProtobuf") + tree, perr := parse.Parse(input) + if perr != nil { + return nil, scanErr(perr) + } + res, serr := summary.Summarize(tree, truncateLimit) + if serr != nil { + var se *summary.Error + if errors.As(serr, &se) { + return nil, &Error{ + Message: se.Message, + Filename: se.Filename, + Funcname: se.Funcname, + } + } + return nil, &Error{Message: serr.Error()} + } + return proto.Marshal(res) } diff --git a/parser/testdata/summary/libpg_query.metadata.json b/parser/testdata/summary/libpg_query.metadata.json index 59f8291..737fd31 100644 --- a/parser/testdata/summary/libpg_query.metadata.json +++ b/parser/testdata/summary/libpg_query.metadata.json @@ -1,106 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json index 442b788..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_array.metadata.json @@ -1,35 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json index 70c818b..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_cache.metadata.json @@ -1,17 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json index 449cbc1..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_call.metadata.json @@ -1,87 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json index 706d53c..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_control.metadata.json @@ -1,57 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_copy.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json index aa06c83..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_domain.metadata.json @@ -1,86 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json index 5a08d01..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_misc.metadata.json @@ -1,18 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json index 780860b..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_record.metadata.json @@ -1,162 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json index 5d34ab7..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_simple.metadata.json @@ -1,28 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json index 17a73dc..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_transaction.metadata.json @@ -1,121 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json index 6e8763d..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_trap.metadata.json @@ -1,46 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json index 980156f..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_trigger.metadata.json @@ -1,10 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006" - ] + "todo": [] } diff --git a/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json index 6a83420..737fd31 100644 --- a/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json +++ b/parser/testdata/summary/plpgsql_regress/plpgsql_varprops.metadata.json @@ -1,41 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/advisory_lock.metadata.json b/parser/testdata/summary/postgres_regress/advisory_lock.metadata.json index 251a33e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/advisory_lock.metadata.json +++ b/parser/testdata/summary/postgres_regress/advisory_lock.metadata.json @@ -1,42 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/aggregates.metadata.json b/parser/testdata/summary/postgres_regress/aggregates.metadata.json index 592c419..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/aggregates.metadata.json +++ b/parser/testdata/summary/postgres_regress/aggregates.metadata.json @@ -1,518 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/alter_generic.metadata.json b/parser/testdata/summary/postgres_regress/alter_generic.metadata.json index d5998bc..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/alter_generic.metadata.json +++ b/parser/testdata/summary/postgres_regress/alter_generic.metadata.json @@ -1,336 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/alter_operator.metadata.json b/parser/testdata/summary/postgres_regress/alter_operator.metadata.json index 8836c0c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/alter_operator.metadata.json +++ b/parser/testdata/summary/postgres_regress/alter_operator.metadata.json @@ -1,69 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/alter_table.metadata.json b/parser/testdata/summary/postgres_regress/alter_table.metadata.json index bfe6d13..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/alter_table.metadata.json +++ b/parser/testdata/summary/postgres_regress/alter_table.metadata.json @@ -1,1657 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "1060", - "1061", - "1062", - "1063", - "1064", - "1065", - "1066", - "1067", - "1068", - "1069", - "107", - "1070", - "1071", - "1072", - "1073", - "1074", - "1075", - "1076", - "1077", - "1078", - "1079", - "108", - "1080", - "1081", - "1082", - "1083", - "1084", - "1085", - "1086", - "1087", - "1088", - "1089", - "109", - "1090", - "1091", - "1092", - "1093", - "1094", - "1095", - "1096", - "1097", - "1098", - "1099", - "110", - "1100", - "1101", - "1102", - "1103", - "1104", - "1105", - "1106", - "1107", - "1108", - "1109", - "111", - "1110", - "1111", - "1112", - "1113", - "1114", - "1115", - "1116", - "1117", - "1118", - "1119", - "112", - "1120", - "1121", - "1122", - "1123", - "1124", - "1125", - "1126", - "1127", - "1128", - "1129", - "113", - "1130", - "1131", - "1132", - "1133", - "1134", - "1135", - "1136", - "1137", - "1138", - "1139", - "114", - "1140", - "1141", - "1142", - "1143", - "1144", - "1145", - "1146", - "1147", - "1148", - "1149", - "115", - "1150", - "1151", - "1152", - "1153", - "1154", - "1155", - "1156", - "1157", - "1158", - "1159", - "116", - "1160", - "1161", - "1162", - "1163", - "1164", - "1165", - "1166", - "1167", - "1168", - "1169", - "117", - "1170", - "1171", - "1172", - "1173", - "1174", - "1175", - "1176", - "1177", - "1178", - "1179", - "118", - "1180", - "1181", - "1182", - "1183", - "1184", - "1185", - "1186", - "1187", - "1188", - "1189", - "119", - "1190", - "1191", - "1192", - "1193", - "1194", - "1195", - "1196", - "1197", - "1198", - "1199", - "120", - "1200", - "1201", - "1202", - "1203", - "1204", - "1205", - "1206", - "1207", - "1208", - "1209", - "121", - "1210", - "1211", - "1212", - "1213", - "1214", - "1215", - "1216", - "1217", - "1218", - "1219", - "122", - "1220", - "1221", - "1222", - "1223", - "1224", - "1225", - "1226", - "1227", - "1228", - "1229", - "123", - "1230", - "1231", - "1232", - "1233", - "1234", - "1235", - "1236", - "1237", - "1238", - "1239", - "124", - "1240", - "1241", - "1242", - "1243", - "1244", - "1245", - "1246", - "1247", - "1248", - "1249", - "125", - "1250", - "1251", - "1252", - "1253", - "1254", - "1255", - "1256", - "1257", - "1258", - "1259", - "126", - "1260", - "1261", - "1262", - "1263", - "1264", - "1265", - "1266", - "1267", - "1268", - "1269", - "127", - "1270", - "1271", - "1272", - "1273", - "1274", - "1275", - "1276", - "1277", - "1278", - "1279", - "128", - "1280", - "1281", - "1282", - "1283", - "1284", - "1285", - "1286", - "1287", - "1288", - "1289", - "129", - "1290", - "1291", - "1292", - "1293", - "1294", - "1295", - "1296", - "1297", - "1298", - "1299", - "130", - "1300", - "1301", - "1302", - "1303", - "1304", - "1305", - "1306", - "1307", - "1308", - "1309", - "131", - "1310", - "1311", - "1312", - "1313", - "1314", - "1315", - "1316", - "1317", - "1318", - "1319", - "132", - "1320", - "1321", - "1322", - "1323", - "1324", - "1325", - "1326", - "1327", - "1328", - "1329", - "133", - "1330", - "1331", - "1332", - "1333", - "1334", - "1335", - "1336", - "1337", - "1338", - "1339", - "134", - "1340", - "1341", - "1342", - "1343", - "1344", - "1345", - "1346", - "1347", - "1348", - "1349", - "135", - "1350", - "1351", - "1352", - "1353", - "1354", - "1355", - "1356", - "1357", - "1358", - "1359", - "136", - "1360", - "1361", - "1362", - "1363", - "1364", - "1365", - "1366", - "1367", - "1368", - "1369", - "137", - "1370", - "1371", - "1372", - "1373", - "1374", - "1375", - "1376", - "1377", - "1378", - "1379", - "138", - "1380", - "1381", - "1382", - "1383", - "1384", - "1385", - "1386", - "1387", - "1388", - "1389", - "139", - "1390", - "1391", - "1392", - "1393", - "1394", - "1395", - "1396", - "1397", - "1398", - "1399", - "140", - "1400", - "1401", - "1402", - "1403", - "1404", - "1405", - "1406", - "1407", - "1408", - "1409", - "141", - "1410", - "1411", - "1412", - "1413", - "1414", - "1415", - "1416", - "1417", - "1418", - "1419", - "142", - "1420", - "1421", - "1422", - "1423", - "1424", - "1425", - "1426", - "1427", - "1428", - "1429", - "143", - "1430", - "1431", - "1432", - "1433", - "1434", - "1435", - "1436", - "1437", - "1438", - "1439", - "144", - "1440", - "1441", - "1442", - "1443", - "1444", - "1445", - "1446", - "1447", - "1448", - "1449", - "145", - "1450", - "1451", - "1452", - "1453", - "1454", - "1455", - "1456", - "1457", - "1458", - "1459", - "146", - "1460", - "1461", - "1462", - "1463", - "1464", - "1465", - "1466", - "1467", - "1468", - "1469", - "147", - "1470", - "1471", - "1472", - "1473", - "1474", - "1475", - "1476", - "1477", - "1478", - "1479", - "148", - "1480", - "1481", - "1482", - "1483", - "1484", - "1485", - "1486", - "1487", - "1488", - "1489", - "149", - "1490", - "1491", - "1492", - "1493", - "1494", - "1495", - "1496", - "1497", - "1498", - "1499", - "150", - "1500", - "1501", - "1502", - "1503", - "1504", - "1505", - "1506", - "1507", - "1508", - "1509", - "151", - "1510", - "1511", - "1512", - "1513", - "1514", - "1515", - "1516", - "1517", - "1518", - "1519", - "152", - "1520", - "1521", - "1522", - "1523", - "1524", - "1525", - "1526", - "1527", - "1528", - "1529", - "153", - "1530", - "1531", - "1532", - "1533", - "1534", - "1535", - "1536", - "1537", - "1538", - "1539", - "154", - "1540", - "1541", - "1542", - "1543", - "1544", - "1545", - "1546", - "1547", - "1548", - "1549", - "155", - "1550", - "1551", - "1552", - "1553", - "1554", - "1555", - "1556", - "1557", - "1558", - "1559", - "156", - "1560", - "1561", - "1562", - "1563", - "1564", - "1565", - "1566", - "1567", - "1568", - "1569", - "157", - "1570", - "1571", - "1572", - "1573", - "1574", - "1575", - "1576", - "1577", - "1578", - "1579", - "158", - "1580", - "1581", - "1582", - "1583", - "1584", - "1585", - "1586", - "1587", - "1588", - "1589", - "159", - "1590", - "1591", - "1592", - "1593", - "1594", - "1595", - "1596", - "1597", - "1598", - "1599", - "160", - "1600", - "1601", - "1602", - "1603", - "1604", - "1605", - "1606", - "1607", - "1608", - "1609", - "161", - "1610", - "1611", - "1612", - "1613", - "1614", - "1615", - "1616", - "1617", - "1618", - "1619", - "162", - "1620", - "1621", - "1622", - "1623", - "1624", - "1625", - "1626", - "1627", - "1628", - "1629", - "163", - "1630", - "1631", - "1632", - "1633", - "1634", - "1635", - "1636", - "1637", - "1638", - "1639", - "164", - "1640", - "1641", - "1642", - "1643", - "1644", - "1645", - "1646", - "1647", - "1648", - "1649", - "165", - "1650", - "1651", - "1652", - "1653", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/amutils.metadata.json b/parser/testdata/summary/postgres_regress/amutils.metadata.json index 92b8f9e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/amutils.metadata.json +++ b/parser/testdata/summary/postgres_regress/amutils.metadata.json @@ -1,14 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/arrays.metadata.json b/parser/testdata/summary/postgres_regress/arrays.metadata.json index a8dc578..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/arrays.metadata.json +++ b/parser/testdata/summary/postgres_regress/arrays.metadata.json @@ -1,488 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/async.metadata.json b/parser/testdata/summary/postgres_regress/async.metadata.json index 4739b17..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/async.metadata.json +++ b/parser/testdata/summary/postgres_regress/async.metadata.json @@ -1,15 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/bit.metadata.json b/parser/testdata/summary/postgres_regress/bit.metadata.json index 0b25d44..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/bit.metadata.json +++ b/parser/testdata/summary/postgres_regress/bit.metadata.json @@ -1,136 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/bitmapops.metadata.json b/parser/testdata/summary/postgres_regress/bitmapops.metadata.json index 92b8f9e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/bitmapops.metadata.json +++ b/parser/testdata/summary/postgres_regress/bitmapops.metadata.json @@ -1,14 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/boolean.metadata.json b/parser/testdata/summary/postgres_regress/boolean.metadata.json index 463f4d4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/boolean.metadata.json +++ b/parser/testdata/summary/postgres_regress/boolean.metadata.json @@ -1,102 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/box.metadata.json b/parser/testdata/summary/postgres_regress/box.metadata.json index 8b15b4c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/box.metadata.json +++ b/parser/testdata/summary/postgres_regress/box.metadata.json @@ -1,105 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/brin.metadata.json b/parser/testdata/summary/postgres_regress/brin.metadata.json index af46f65..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/brin.metadata.json +++ b/parser/testdata/summary/postgres_regress/brin.metadata.json @@ -1,72 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/brin_bloom.metadata.json b/parser/testdata/summary/postgres_regress/brin_bloom.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/brin_bloom.metadata.json +++ b/parser/testdata/summary/postgres_regress/brin_bloom.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/brin_multi.metadata.json b/parser/testdata/summary/postgres_regress/brin_multi.metadata.json index 643d115..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/brin_multi.metadata.json +++ b/parser/testdata/summary/postgres_regress/brin_multi.metadata.json @@ -1,176 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/btree_index.metadata.json b/parser/testdata/summary/postgres_regress/btree_index.metadata.json index 11ed4d1..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/btree_index.metadata.json +++ b/parser/testdata/summary/postgres_regress/btree_index.metadata.json @@ -1,100 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/case.metadata.json b/parser/testdata/summary/postgres_regress/case.metadata.json index f47f175..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/case.metadata.json +++ b/parser/testdata/summary/postgres_regress/case.metadata.json @@ -1,68 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/char.metadata.json b/parser/testdata/summary/postgres_regress/char.metadata.json index efb3a10..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/char.metadata.json +++ b/parser/testdata/summary/postgres_regress/char.metadata.json @@ -1,36 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/circle.metadata.json b/parser/testdata/summary/postgres_regress/circle.metadata.json index edb706f..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/circle.metadata.json +++ b/parser/testdata/summary/postgres_regress/circle.metadata.json @@ -1,26 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/cluster.metadata.json b/parser/testdata/summary/postgres_regress/cluster.metadata.json index 479ae3b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/cluster.metadata.json +++ b/parser/testdata/summary/postgres_regress/cluster.metadata.json @@ -1,208 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json b/parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json index faccb98..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json +++ b/parser/testdata/summary/postgres_regress/collate.icu.utf8.metadata.json @@ -1,505 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json b/parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json index 648a6d3..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json +++ b/parser/testdata/summary/postgres_regress/collate.linux.utf8.metadata.json @@ -1,207 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/collate.metadata.json b/parser/testdata/summary/postgres_regress/collate.metadata.json index 267f283..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/collate.metadata.json +++ b/parser/testdata/summary/postgres_regress/collate.metadata.json @@ -1,148 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/collate.utf8.metadata.json b/parser/testdata/summary/postgres_regress/collate.utf8.metadata.json index 5d34ab7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/collate.utf8.metadata.json +++ b/parser/testdata/summary/postgres_regress/collate.utf8.metadata.json @@ -1,28 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json b/parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json index a4f4300..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json +++ b/parser/testdata/summary/postgres_regress/collate.windows.win1252.metadata.json @@ -1,177 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/combocid.metadata.json b/parser/testdata/summary/postgres_regress/combocid.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/combocid.metadata.json +++ b/parser/testdata/summary/postgres_regress/combocid.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/comments.metadata.json b/parser/testdata/summary/postgres_regress/comments.metadata.json index 980156f..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/comments.metadata.json +++ b/parser/testdata/summary/postgres_regress/comments.metadata.json @@ -1,10 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/compression.metadata.json b/parser/testdata/summary/postgres_regress/compression.metadata.json index 8e8d1f7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/compression.metadata.json +++ b/parser/testdata/summary/postgres_regress/compression.metadata.json @@ -1,91 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/constraints.metadata.json b/parser/testdata/summary/postgres_regress/constraints.metadata.json index 60d70f4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/constraints.metadata.json +++ b/parser/testdata/summary/postgres_regress/constraints.metadata.json @@ -1,323 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/conversion.metadata.json b/parser/testdata/summary/postgres_regress/conversion.metadata.json index 8836c0c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/conversion.metadata.json +++ b/parser/testdata/summary/postgres_regress/conversion.metadata.json @@ -1,69 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/copy.metadata.json b/parser/testdata/summary/postgres_regress/copy.metadata.json index 8e8d1f7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/copy.metadata.json +++ b/parser/testdata/summary/postgres_regress/copy.metadata.json @@ -1,91 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/copy2.metadata.json b/parser/testdata/summary/postgres_regress/copy2.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/copy2.metadata.json +++ b/parser/testdata/summary/postgres_regress/copy2.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/copydml.metadata.json b/parser/testdata/summary/postgres_regress/copydml.metadata.json index f53b7f4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/copydml.metadata.json +++ b/parser/testdata/summary/postgres_regress/copydml.metadata.json @@ -1,63 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/copyselect.metadata.json b/parser/testdata/summary/postgres_regress/copyselect.metadata.json index 56098cb..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/copyselect.metadata.json +++ b/parser/testdata/summary/postgres_regress/copyselect.metadata.json @@ -1,25 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_aggregate.metadata.json b/parser/testdata/summary/postgres_regress/create_aggregate.metadata.json index f53b7f4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_aggregate.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_aggregate.metadata.json @@ -1,63 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_am.metadata.json b/parser/testdata/summary/postgres_regress/create_am.metadata.json index 83b3df4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_am.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_am.metadata.json @@ -1,146 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_cast.metadata.json b/parser/testdata/summary/postgres_regress/create_cast.metadata.json index 5d34ab7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_cast.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_cast.metadata.json @@ -1,28 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_function_c.metadata.json b/parser/testdata/summary/postgres_regress/create_function_c.metadata.json index e8e06a4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_function_c.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_function_c.metadata.json @@ -1,9 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_function_sql.metadata.json b/parser/testdata/summary/postgres_regress/create_function_sql.metadata.json index 643249b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_function_sql.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_function_sql.metadata.json @@ -1,159 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_index.metadata.json b/parser/testdata/summary/postgres_regress/create_index.metadata.json index 528c575..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_index.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_index.metadata.json @@ -1,615 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json b/parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json index 18fb3ca..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_index_spgist.metadata.json @@ -1,206 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_misc.metadata.json b/parser/testdata/summary/postgres_regress/create_misc.metadata.json index aa15346..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_misc.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_misc.metadata.json @@ -1,92 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_operator.metadata.json b/parser/testdata/summary/postgres_regress/create_operator.metadata.json index 44e163a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_operator.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_operator.metadata.json @@ -1,94 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_procedure.metadata.json b/parser/testdata/summary/postgres_regress/create_procedure.metadata.json index c169184..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_procedure.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_procedure.metadata.json @@ -1,113 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_role.metadata.json b/parser/testdata/summary/postgres_regress/create_role.metadata.json index 6835d4b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_role.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_role.metadata.json @@ -1,141 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_schema.metadata.json b/parser/testdata/summary/postgres_regress/create_schema.metadata.json index 7249d3a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_schema.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_schema.metadata.json @@ -1,31 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_table.metadata.json b/parser/testdata/summary/postgres_regress/create_table.metadata.json index f382372..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_table.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_table.metadata.json @@ -1,330 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_table_like.metadata.json b/parser/testdata/summary/postgres_regress/create_table_like.metadata.json index 267f283..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_table_like.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_table_like.metadata.json @@ -1,148 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_type.metadata.json b/parser/testdata/summary/postgres_regress/create_type.metadata.json index b064cb7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_type.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_type.metadata.json @@ -1,89 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/create_view.metadata.json b/parser/testdata/summary/postgres_regress/create_view.metadata.json index 5d2a46c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/create_view.metadata.json +++ b/parser/testdata/summary/postgres_regress/create_view.metadata.json @@ -1,311 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/database.metadata.json b/parser/testdata/summary/postgres_regress/database.metadata.json index e71b2c2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/database.metadata.json +++ b/parser/testdata/summary/postgres_regress/database.metadata.json @@ -1,20 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/date.metadata.json b/parser/testdata/summary/postgres_regress/date.metadata.json index a6ce2f7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/date.metadata.json +++ b/parser/testdata/summary/postgres_regress/date.metadata.json @@ -1,274 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/dbsize.metadata.json b/parser/testdata/summary/postgres_regress/dbsize.metadata.json index 253273e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/dbsize.metadata.json +++ b/parser/testdata/summary/postgres_regress/dbsize.metadata.json @@ -1,29 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/delete.metadata.json b/parser/testdata/summary/postgres_regress/delete.metadata.json index 92b8f9e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/delete.metadata.json +++ b/parser/testdata/summary/postgres_regress/delete.metadata.json @@ -1,14 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/dependency.metadata.json b/parser/testdata/summary/postgres_regress/dependency.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/dependency.metadata.json +++ b/parser/testdata/summary/postgres_regress/dependency.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/domain.metadata.json b/parser/testdata/summary/postgres_regress/domain.metadata.json index 60d70f4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/domain.metadata.json +++ b/parser/testdata/summary/postgres_regress/domain.metadata.json @@ -1,323 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json b/parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json index 3b3c7f2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json +++ b/parser/testdata/summary/postgres_regress/drop_if_exists.metadata.json @@ -1,165 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/drop_operator.metadata.json b/parser/testdata/summary/postgres_regress/drop_operator.metadata.json index bf73c3a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/drop_operator.metadata.json +++ b/parser/testdata/summary/postgres_regress/drop_operator.metadata.json @@ -1,16 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/enum.metadata.json b/parser/testdata/summary/postgres_regress/enum.metadata.json index 6f770d9..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/enum.metadata.json +++ b/parser/testdata/summary/postgres_regress/enum.metadata.json @@ -1,174 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/equivclass.metadata.json b/parser/testdata/summary/postgres_regress/equivclass.metadata.json index 364fcc5..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/equivclass.metadata.json +++ b/parser/testdata/summary/postgres_regress/equivclass.metadata.json @@ -1,83 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/errors.metadata.json b/parser/testdata/summary/postgres_regress/errors.metadata.json index b064cb7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/errors.metadata.json +++ b/parser/testdata/summary/postgres_regress/errors.metadata.json @@ -1,89 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/event_trigger.metadata.json b/parser/testdata/summary/postgres_regress/event_trigger.metadata.json index 21e7df0..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/event_trigger.metadata.json +++ b/parser/testdata/summary/postgres_regress/event_trigger.metadata.json @@ -1,234 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json b/parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json index 4739b17..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json +++ b/parser/testdata/summary/postgres_regress/event_trigger_login.metadata.json @@ -1,15 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/explain.metadata.json b/parser/testdata/summary/postgres_regress/explain.metadata.json index fbb3e40..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/explain.metadata.json +++ b/parser/testdata/summary/postgres_regress/explain.metadata.json @@ -1,55 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/expressions.metadata.json b/parser/testdata/summary/postgres_regress/expressions.metadata.json index fb72ee9..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/expressions.metadata.json +++ b/parser/testdata/summary/postgres_regress/expressions.metadata.json @@ -1,75 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/fast_default.metadata.json b/parser/testdata/summary/postgres_regress/fast_default.metadata.json index 354a8d0..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/fast_default.metadata.json +++ b/parser/testdata/summary/postgres_regress/fast_default.metadata.json @@ -1,273 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/float4.metadata.json b/parser/testdata/summary/postgres_regress/float4.metadata.json index a864d8e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/float4.metadata.json +++ b/parser/testdata/summary/postgres_regress/float4.metadata.json @@ -1,104 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/float8.metadata.json b/parser/testdata/summary/postgres_regress/float8.metadata.json index 194b55b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/float8.metadata.json +++ b/parser/testdata/summary/postgres_regress/float8.metadata.json @@ -1,173 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/foreign_data.metadata.json b/parser/testdata/summary/postgres_regress/foreign_data.metadata.json index efde331..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/foreign_data.metadata.json +++ b/parser/testdata/summary/postgres_regress/foreign_data.metadata.json @@ -1,534 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/foreign_key.metadata.json b/parser/testdata/summary/postgres_regress/foreign_key.metadata.json index 0d39ce9..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/foreign_key.metadata.json +++ b/parser/testdata/summary/postgres_regress/foreign_key.metadata.json @@ -1,1158 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "1060", - "1061", - "1062", - "1063", - "1064", - "1065", - "1066", - "1067", - "1068", - "1069", - "107", - "1070", - "1071", - "1072", - "1073", - "1074", - "1075", - "1076", - "1077", - "1078", - "1079", - "108", - "1080", - "1081", - "1082", - "1083", - "1084", - "1085", - "1086", - "1087", - "1088", - "1089", - "109", - "1090", - "1091", - "1092", - "1093", - "1094", - "1095", - "1096", - "1097", - "1098", - "1099", - "110", - "1100", - "1101", - "1102", - "1103", - "1104", - "1105", - "1106", - "1107", - "1108", - "1109", - "111", - "1110", - "1111", - "1112", - "1113", - "1114", - "1115", - "1116", - "1117", - "1118", - "1119", - "112", - "1120", - "1121", - "1122", - "1123", - "1124", - "1125", - "1126", - "1127", - "1128", - "1129", - "113", - "1130", - "1131", - "1132", - "1133", - "1134", - "1135", - "1136", - "1137", - "1138", - "1139", - "114", - "1140", - "1141", - "1142", - "1143", - "1144", - "1145", - "1146", - "1147", - "1148", - "1149", - "115", - "1150", - "1151", - "1152", - "1153", - "1154", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/functional_deps.metadata.json b/parser/testdata/summary/postgres_regress/functional_deps.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/functional_deps.metadata.json +++ b/parser/testdata/summary/postgres_regress/functional_deps.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/generated.metadata.json b/parser/testdata/summary/postgres_regress/generated.metadata.json index b6ecb7b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/generated.metadata.json +++ b/parser/testdata/summary/postgres_regress/generated.metadata.json @@ -1,123 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/geometry.metadata.json b/parser/testdata/summary/postgres_regress/geometry.metadata.json index 4e31a92..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/geometry.metadata.json +++ b/parser/testdata/summary/postgres_regress/geometry.metadata.json @@ -1,166 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/gin.metadata.json b/parser/testdata/summary/postgres_regress/gin.metadata.json index f53b7f4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/gin.metadata.json +++ b/parser/testdata/summary/postgres_regress/gin.metadata.json @@ -1,63 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/gist.metadata.json b/parser/testdata/summary/postgres_regress/gist.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/gist.metadata.json +++ b/parser/testdata/summary/postgres_regress/gist.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/groupingsets.metadata.json b/parser/testdata/summary/postgres_regress/groupingsets.metadata.json index 643d115..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/groupingsets.metadata.json +++ b/parser/testdata/summary/postgres_regress/groupingsets.metadata.json @@ -1,176 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/guc.metadata.json b/parser/testdata/summary/postgres_regress/guc.metadata.json index 8f8fab6..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/guc.metadata.json +++ b/parser/testdata/summary/postgres_regress/guc.metadata.json @@ -1,218 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/hash_func.metadata.json b/parser/testdata/summary/postgres_regress/hash_func.metadata.json index e74143a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/hash_func.metadata.json +++ b/parser/testdata/summary/postgres_regress/hash_func.metadata.json @@ -1,47 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/hash_index.metadata.json b/parser/testdata/summary/postgres_regress/hash_index.metadata.json index ba349a5..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/hash_index.metadata.json +++ b/parser/testdata/summary/postgres_regress/hash_index.metadata.json @@ -1,101 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/hash_part.metadata.json b/parser/testdata/summary/postgres_regress/hash_part.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/hash_part.metadata.json +++ b/parser/testdata/summary/postgres_regress/hash_part.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/horology.metadata.json b/parser/testdata/summary/postgres_regress/horology.metadata.json index 820fe8a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/horology.metadata.json +++ b/parser/testdata/summary/postgres_regress/horology.metadata.json @@ -1,392 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/identity.metadata.json b/parser/testdata/summary/postgres_regress/identity.metadata.json index a6ce2f7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/identity.metadata.json +++ b/parser/testdata/summary/postgres_regress/identity.metadata.json @@ -1,274 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/incremental_sort.metadata.json b/parser/testdata/summary/postgres_regress/incremental_sort.metadata.json index b6ecb7b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/incremental_sort.metadata.json +++ b/parser/testdata/summary/postgres_regress/incremental_sort.metadata.json @@ -1,123 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/index_including.metadata.json b/parser/testdata/summary/postgres_regress/index_including.metadata.json index e6f6795..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/index_including.metadata.json +++ b/parser/testdata/summary/postgres_regress/index_including.metadata.json @@ -1,139 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/index_including_gist.metadata.json b/parser/testdata/summary/postgres_regress/index_including_gist.metadata.json index 147070d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/index_including_gist.metadata.json +++ b/parser/testdata/summary/postgres_regress/index_including_gist.metadata.json @@ -1,54 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/indexing.metadata.json b/parser/testdata/summary/postgres_regress/indexing.metadata.json index 44a2d56..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/indexing.metadata.json +++ b/parser/testdata/summary/postgres_regress/indexing.metadata.json @@ -1,564 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/indirect_toast.metadata.json b/parser/testdata/summary/postgres_regress/indirect_toast.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/indirect_toast.metadata.json +++ b/parser/testdata/summary/postgres_regress/indirect_toast.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/inet.metadata.json b/parser/testdata/summary/postgres_regress/inet.metadata.json index 1211f6e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/inet.metadata.json +++ b/parser/testdata/summary/postgres_regress/inet.metadata.json @@ -1,115 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json b/parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json index 3e33966..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json +++ b/parser/testdata/summary/postgres_regress/infinite_recurse.metadata.json @@ -1,7 +1,3 @@ { - "todo": [ - "001", - "002", - "003" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/inherit.metadata.json b/parser/testdata/summary/postgres_regress/inherit.metadata.json index 53ffb30..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/inherit.metadata.json +++ b/parser/testdata/summary/postgres_regress/inherit.metadata.json @@ -1,681 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/init_privs.metadata.json b/parser/testdata/summary/postgres_regress/init_privs.metadata.json index f1ffe06..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/init_privs.metadata.json +++ b/parser/testdata/summary/postgres_regress/init_privs.metadata.json @@ -1,8 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/insert.metadata.json b/parser/testdata/summary/postgres_regress/insert.metadata.json index 1751d7d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/insert.metadata.json +++ b/parser/testdata/summary/postgres_regress/insert.metadata.json @@ -1,391 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/insert_conflict.metadata.json b/parser/testdata/summary/postgres_regress/insert_conflict.metadata.json index 1b73a29..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/insert_conflict.metadata.json +++ b/parser/testdata/summary/postgres_regress/insert_conflict.metadata.json @@ -1,261 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/int2.metadata.json b/parser/testdata/summary/postgres_regress/int2.metadata.json index f476ef8..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/int2.metadata.json +++ b/parser/testdata/summary/postgres_regress/int2.metadata.json @@ -1,80 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/int4.metadata.json b/parser/testdata/summary/postgres_regress/int4.metadata.json index da94530..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/int4.metadata.json +++ b/parser/testdata/summary/postgres_regress/int4.metadata.json @@ -1,98 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/int8.metadata.json b/parser/testdata/summary/postgres_regress/int8.metadata.json index 6eafe87..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/int8.metadata.json +++ b/parser/testdata/summary/postgres_regress/int8.metadata.json @@ -1,171 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/interval.metadata.json b/parser/testdata/summary/postgres_regress/interval.metadata.json index df238f5..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/interval.metadata.json +++ b/parser/testdata/summary/postgres_regress/interval.metadata.json @@ -1,447 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/join.metadata.json b/parser/testdata/summary/postgres_regress/join.metadata.json index 3b007a6..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/join.metadata.json +++ b/parser/testdata/summary/postgres_regress/join.metadata.json @@ -1,719 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/join_hash.metadata.json b/parser/testdata/summary/postgres_regress/join_hash.metadata.json index 5bababc..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/join_hash.metadata.json +++ b/parser/testdata/summary/postgres_regress/join_hash.metadata.json @@ -1,283 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/json.metadata.json b/parser/testdata/summary/postgres_regress/json.metadata.json index 15b4f09..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/json.metadata.json +++ b/parser/testdata/summary/postgres_regress/json.metadata.json @@ -1,464 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/json_encoding.metadata.json b/parser/testdata/summary/postgres_regress/json_encoding.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/json_encoding.metadata.json +++ b/parser/testdata/summary/postgres_regress/json_encoding.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/jsonb.metadata.json b/parser/testdata/summary/postgres_regress/jsonb.metadata.json index 4c380dc..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/jsonb.metadata.json +++ b/parser/testdata/summary/postgres_regress/jsonb.metadata.json @@ -1,1063 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json b/parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json index b53b6f2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json +++ b/parser/testdata/summary/postgres_regress/jsonb_jsonpath.metadata.json @@ -1,825 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/jsonpath.metadata.json b/parser/testdata/summary/postgres_regress/jsonpath.metadata.json index 402e8ee..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/jsonpath.metadata.json +++ b/parser/testdata/summary/postgres_regress/jsonpath.metadata.json @@ -1,228 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json b/parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json index efb3a10..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json +++ b/parser/testdata/summary/postgres_regress/jsonpath_encoding.metadata.json @@ -1,36 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/largeobject.metadata.json b/parser/testdata/summary/postgres_regress/largeobject.metadata.json index 48ba122..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/largeobject.metadata.json +++ b/parser/testdata/summary/postgres_regress/largeobject.metadata.json @@ -1,128 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/limit.metadata.json b/parser/testdata/summary/postgres_regress/limit.metadata.json index fb87925..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/limit.metadata.json +++ b/parser/testdata/summary/postgres_regress/limit.metadata.json @@ -1,84 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/line.metadata.json b/parser/testdata/summary/postgres_regress/line.metadata.json index bfeb57a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/line.metadata.json +++ b/parser/testdata/summary/postgres_regress/line.metadata.json @@ -1,39 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/lock.metadata.json b/parser/testdata/summary/postgres_regress/lock.metadata.json index 507be8d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/lock.metadata.json +++ b/parser/testdata/summary/postgres_regress/lock.metadata.json @@ -1,135 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/lseg.metadata.json b/parser/testdata/summary/postgres_regress/lseg.metadata.json index e71b2c2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/lseg.metadata.json +++ b/parser/testdata/summary/postgres_regress/lseg.metadata.json @@ -1,20 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/macaddr.metadata.json b/parser/testdata/summary/postgres_regress/macaddr.metadata.json index bfeb57a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/macaddr.metadata.json +++ b/parser/testdata/summary/postgres_regress/macaddr.metadata.json @@ -1,39 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/macaddr8.metadata.json b/parser/testdata/summary/postgres_regress/macaddr8.metadata.json index fb72ee9..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/macaddr8.metadata.json +++ b/parser/testdata/summary/postgres_regress/macaddr8.metadata.json @@ -1,75 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/maintain_every.metadata.json b/parser/testdata/summary/postgres_regress/maintain_every.metadata.json index e71b2c2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/maintain_every.metadata.json +++ b/parser/testdata/summary/postgres_regress/maintain_every.metadata.json @@ -1,20 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/matview.metadata.json b/parser/testdata/summary/postgres_regress/matview.metadata.json index 784b93c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/matview.metadata.json +++ b/parser/testdata/summary/postgres_regress/matview.metadata.json @@ -1,183 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/md5.metadata.json b/parser/testdata/summary/postgres_regress/md5.metadata.json index 5a08d01..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/md5.metadata.json +++ b/parser/testdata/summary/postgres_regress/md5.metadata.json @@ -1,18 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/memoize.metadata.json b/parser/testdata/summary/postgres_regress/memoize.metadata.json index abfc1a2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/memoize.metadata.json +++ b/parser/testdata/summary/postgres_regress/memoize.metadata.json @@ -1,73 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/merge.metadata.json b/parser/testdata/summary/postgres_regress/merge.metadata.json index 168c3f9..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/merge.metadata.json +++ b/parser/testdata/summary/postgres_regress/merge.metadata.json @@ -1,576 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/misc.metadata.json b/parser/testdata/summary/postgres_regress/misc.metadata.json index 6a71114..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/misc.metadata.json +++ b/parser/testdata/summary/postgres_regress/misc.metadata.json @@ -1,65 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/misc_functions.metadata.json b/parser/testdata/summary/postgres_regress/misc_functions.metadata.json index b6ecb7b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/misc_functions.metadata.json +++ b/parser/testdata/summary/postgres_regress/misc_functions.metadata.json @@ -1,123 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/misc_sanity.metadata.json b/parser/testdata/summary/postgres_regress/misc_sanity.metadata.json index e8e06a4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/misc_sanity.metadata.json +++ b/parser/testdata/summary/postgres_regress/misc_sanity.metadata.json @@ -1,9 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/money.metadata.json b/parser/testdata/summary/postgres_regress/money.metadata.json index c169184..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/money.metadata.json +++ b/parser/testdata/summary/postgres_regress/money.metadata.json @@ -1,113 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/multirangetypes.metadata.json b/parser/testdata/summary/postgres_regress/multirangetypes.metadata.json index 6769ac6..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/multirangetypes.metadata.json +++ b/parser/testdata/summary/postgres_regress/multirangetypes.metadata.json @@ -1,609 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/mvcc.metadata.json b/parser/testdata/summary/postgres_regress/mvcc.metadata.json index 4739b17..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/mvcc.metadata.json +++ b/parser/testdata/summary/postgres_regress/mvcc.metadata.json @@ -1,15 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/name.metadata.json b/parser/testdata/summary/postgres_regress/name.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/name.metadata.json +++ b/parser/testdata/summary/postgres_regress/name.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/namespace.metadata.json b/parser/testdata/summary/postgres_regress/namespace.metadata.json index 6e8763d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/namespace.metadata.json +++ b/parser/testdata/summary/postgres_regress/namespace.metadata.json @@ -1,46 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/numeric.metadata.json b/parser/testdata/summary/postgres_regress/numeric.metadata.json index e7297cf..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/numeric.metadata.json +++ b/parser/testdata/summary/postgres_regress/numeric.metadata.json @@ -1,1022 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/numeric_big.metadata.json b/parser/testdata/summary/postgres_regress/numeric_big.metadata.json index 05e97cf..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/numeric_big.metadata.json +++ b/parser/testdata/summary/postgres_regress/numeric_big.metadata.json @@ -1,556 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/numerology.metadata.json b/parser/testdata/summary/postgres_regress/numerology.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/numerology.metadata.json +++ b/parser/testdata/summary/postgres_regress/numerology.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/object_address.metadata.json b/parser/testdata/summary/postgres_regress/object_address.metadata.json index 5c84308..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/object_address.metadata.json +++ b/parser/testdata/summary/postgres_regress/object_address.metadata.json @@ -1,85 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/oid.metadata.json b/parser/testdata/summary/postgres_regress/oid.metadata.json index 6a83420..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/oid.metadata.json +++ b/parser/testdata/summary/postgres_regress/oid.metadata.json @@ -1,41 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/oidjoins.metadata.json b/parser/testdata/summary/postgres_regress/oidjoins.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/oidjoins.metadata.json +++ b/parser/testdata/summary/postgres_regress/oidjoins.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/opr_sanity.metadata.json b/parser/testdata/summary/postgres_regress/opr_sanity.metadata.json index 304478c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/opr_sanity.metadata.json +++ b/parser/testdata/summary/postgres_regress/opr_sanity.metadata.json @@ -1,134 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json b/parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json index e6f6795..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json +++ b/parser/testdata/summary/postgres_regress/partition_aggregate.metadata.json @@ -1,139 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/partition_info.metadata.json b/parser/testdata/summary/postgres_regress/partition_info.metadata.json index 2ff9db8..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/partition_info.metadata.json +++ b/parser/testdata/summary/postgres_regress/partition_info.metadata.json @@ -1,77 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/partition_join.metadata.json b/parser/testdata/summary/postgres_regress/partition_join.metadata.json index 6fa7813..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/partition_join.metadata.json +++ b/parser/testdata/summary/postgres_regress/partition_join.metadata.json @@ -1,604 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/partition_prune.metadata.json b/parser/testdata/summary/postgres_regress/partition_prune.metadata.json index 6644147..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/partition_prune.metadata.json +++ b/parser/testdata/summary/postgres_regress/partition_prune.metadata.json @@ -1,702 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/password.metadata.json b/parser/testdata/summary/postgres_regress/password.metadata.json index fbb3e40..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/password.metadata.json +++ b/parser/testdata/summary/postgres_regress/password.metadata.json @@ -1,55 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/path.metadata.json b/parser/testdata/summary/postgres_regress/path.metadata.json index 880b1d2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/path.metadata.json +++ b/parser/testdata/summary/postgres_regress/path.metadata.json @@ -1,27 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/pg_lsn.metadata.json b/parser/testdata/summary/postgres_regress/pg_lsn.metadata.json index 442b788..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/pg_lsn.metadata.json +++ b/parser/testdata/summary/postgres_regress/pg_lsn.metadata.json @@ -1,35 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/plancache.metadata.json b/parser/testdata/summary/postgres_regress/plancache.metadata.json index ba349a5..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/plancache.metadata.json +++ b/parser/testdata/summary/postgres_regress/plancache.metadata.json @@ -1,101 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/plpgsql.metadata.json b/parser/testdata/summary/postgres_regress/plpgsql.metadata.json index 35fd146..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/plpgsql.metadata.json +++ b/parser/testdata/summary/postgres_regress/plpgsql.metadata.json @@ -1,945 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/point.metadata.json b/parser/testdata/summary/postgres_regress/point.metadata.json index e74143a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/point.metadata.json +++ b/parser/testdata/summary/postgres_regress/point.metadata.json @@ -1,47 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/polygon.metadata.json b/parser/testdata/summary/postgres_regress/polygon.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/polygon.metadata.json +++ b/parser/testdata/summary/postgres_regress/polygon.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/polymorphism.metadata.json b/parser/testdata/summary/postgres_regress/polymorphism.metadata.json index 835764e..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/polymorphism.metadata.json +++ b/parser/testdata/summary/postgres_regress/polymorphism.metadata.json @@ -1,427 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/portals.metadata.json b/parser/testdata/summary/postgres_regress/portals.metadata.json index f599902..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/portals.metadata.json +++ b/parser/testdata/summary/postgres_regress/portals.metadata.json @@ -1,353 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/portals_p2.metadata.json b/parser/testdata/summary/postgres_regress/portals_p2.metadata.json index 66f0b1d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/portals_p2.metadata.json +++ b/parser/testdata/summary/postgres_regress/portals_p2.metadata.json @@ -1,45 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/predicate.metadata.json b/parser/testdata/summary/postgres_regress/predicate.metadata.json index 6e8763d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/predicate.metadata.json +++ b/parser/testdata/summary/postgres_regress/predicate.metadata.json @@ -1,46 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/prepare.metadata.json b/parser/testdata/summary/postgres_regress/prepare.metadata.json index daef5f1..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/prepare.metadata.json +++ b/parser/testdata/summary/postgres_regress/prepare.metadata.json @@ -1,37 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/prepared_xacts.metadata.json b/parser/testdata/summary/postgres_regress/prepared_xacts.metadata.json index 449cbc1..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/prepared_xacts.metadata.json +++ b/parser/testdata/summary/postgres_regress/prepared_xacts.metadata.json @@ -1,87 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/privileges.metadata.json b/parser/testdata/summary/postgres_regress/privileges.metadata.json index 302fef8..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/privileges.metadata.json +++ b/parser/testdata/summary/postgres_regress/privileges.metadata.json @@ -1,335 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/psql.metadata.json b/parser/testdata/summary/postgres_regress/psql.metadata.json index 0612d4a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/psql.metadata.json +++ b/parser/testdata/summary/postgres_regress/psql.metadata.json @@ -1,200 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json b/parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json index 5e6664a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json +++ b/parser/testdata/summary/postgres_regress/psql_crosstab.metadata.json @@ -1,12 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/publication.metadata.json b/parser/testdata/summary/postgres_regress/publication.metadata.json index 8cf9d31..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/publication.metadata.json +++ b/parser/testdata/summary/postgres_regress/publication.metadata.json @@ -1,659 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/random.metadata.json b/parser/testdata/summary/postgres_regress/random.metadata.json index 634de79..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/random.metadata.json +++ b/parser/testdata/summary/postgres_regress/random.metadata.json @@ -1,52 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/rangefuncs.metadata.json b/parser/testdata/summary/postgres_regress/rangefuncs.metadata.json index 526d3ef..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/rangefuncs.metadata.json +++ b/parser/testdata/summary/postgres_regress/rangefuncs.metadata.json @@ -1,432 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/rangetypes.metadata.json b/parser/testdata/summary/postgres_regress/rangetypes.metadata.json index fa6f7df..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/rangetypes.metadata.json +++ b/parser/testdata/summary/postgres_regress/rangetypes.metadata.json @@ -1,411 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/regex.metadata.json b/parser/testdata/summary/postgres_regress/regex.metadata.json index 60e76e3..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/regex.metadata.json +++ b/parser/testdata/summary/postgres_regress/regex.metadata.json @@ -1,109 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/regproc.metadata.json b/parser/testdata/summary/postgres_regress/regproc.metadata.json index 60e76e3..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/regproc.metadata.json +++ b/parser/testdata/summary/postgres_regress/regproc.metadata.json @@ -1,109 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/reindex_catalog.metadata.json b/parser/testdata/summary/postgres_regress/reindex_catalog.metadata.json index 229dde4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/reindex_catalog.metadata.json +++ b/parser/testdata/summary/postgres_regress/reindex_catalog.metadata.json @@ -1,24 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/reloptions.metadata.json b/parser/testdata/summary/postgres_regress/reloptions.metadata.json index 7a82cd3..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/reloptions.metadata.json +++ b/parser/testdata/summary/postgres_regress/reloptions.metadata.json @@ -1,70 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/replica_identity.metadata.json b/parser/testdata/summary/postgres_regress/replica_identity.metadata.json index dc9d431..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/replica_identity.metadata.json +++ b/parser/testdata/summary/postgres_regress/replica_identity.metadata.json @@ -1,60 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/returning.metadata.json b/parser/testdata/summary/postgres_regress/returning.metadata.json index 2be5689..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/returning.metadata.json +++ b/parser/testdata/summary/postgres_regress/returning.metadata.json @@ -1,81 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/roleattributes.metadata.json b/parser/testdata/summary/postgres_regress/roleattributes.metadata.json index fb87925..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/roleattributes.metadata.json +++ b/parser/testdata/summary/postgres_regress/roleattributes.metadata.json @@ -1,84 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/rowsecurity.metadata.json b/parser/testdata/summary/postgres_regress/rowsecurity.metadata.json index dcaa437..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/rowsecurity.metadata.json +++ b/parser/testdata/summary/postgres_regress/rowsecurity.metadata.json @@ -1,779 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/rowtypes.metadata.json b/parser/testdata/summary/postgres_regress/rowtypes.metadata.json index e9da7a5..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/rowtypes.metadata.json +++ b/parser/testdata/summary/postgres_regress/rowtypes.metadata.json @@ -1,241 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/rules.metadata.json b/parser/testdata/summary/postgres_regress/rules.metadata.json index 75d8f0c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/rules.metadata.json +++ b/parser/testdata/summary/postgres_regress/rules.metadata.json @@ -1,624 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/sanity_check.metadata.json b/parser/testdata/summary/postgres_regress/sanity_check.metadata.json index 3e33966..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/sanity_check.metadata.json +++ b/parser/testdata/summary/postgres_regress/sanity_check.metadata.json @@ -1,7 +1,3 @@ { - "todo": [ - "001", - "002", - "003" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/security_label.metadata.json b/parser/testdata/summary/postgres_regress/security_label.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/security_label.metadata.json +++ b/parser/testdata/summary/postgres_regress/security_label.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select.metadata.json b/parser/testdata/summary/postgres_regress/select.metadata.json index 8e8d1f7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select.metadata.json +++ b/parser/testdata/summary/postgres_regress/select.metadata.json @@ -1,91 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select_distinct.metadata.json b/parser/testdata/summary/postgres_regress/select_distinct.metadata.json index f476ef8..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select_distinct.metadata.json +++ b/parser/testdata/summary/postgres_regress/select_distinct.metadata.json @@ -1,80 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json b/parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json index 5e6664a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json +++ b/parser/testdata/summary/postgres_regress/select_distinct_on.metadata.json @@ -1,12 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select_having.metadata.json b/parser/testdata/summary/postgres_regress/select_having.metadata.json index 880b1d2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select_having.metadata.json +++ b/parser/testdata/summary/postgres_regress/select_having.metadata.json @@ -1,27 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select_implicit.metadata.json b/parser/testdata/summary/postgres_regress/select_implicit.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select_implicit.metadata.json +++ b/parser/testdata/summary/postgres_regress/select_implicit.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select_into.metadata.json b/parser/testdata/summary/postgres_regress/select_into.metadata.json index 0a7b0c8..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select_into.metadata.json +++ b/parser/testdata/summary/postgres_regress/select_into.metadata.json @@ -1,71 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select_parallel.metadata.json b/parser/testdata/summary/postgres_regress/select_parallel.metadata.json index 60ff1c2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select_parallel.metadata.json +++ b/parser/testdata/summary/postgres_regress/select_parallel.metadata.json @@ -1,239 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/select_views.metadata.json b/parser/testdata/summary/postgres_regress/select_views.metadata.json index f37dd99..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/select_views.metadata.json +++ b/parser/testdata/summary/postgres_regress/select_views.metadata.json @@ -1,56 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/sequence.metadata.json b/parser/testdata/summary/postgres_regress/sequence.metadata.json index 38ac4c2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/sequence.metadata.json +++ b/parser/testdata/summary/postgres_regress/sequence.metadata.json @@ -1,264 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/spgist.metadata.json b/parser/testdata/summary/postgres_regress/spgist.metadata.json index 442b788..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/spgist.metadata.json +++ b/parser/testdata/summary/postgres_regress/spgist.metadata.json @@ -1,35 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/sqljson.metadata.json b/parser/testdata/summary/postgres_regress/sqljson.metadata.json index 78efa1d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/sqljson.metadata.json +++ b/parser/testdata/summary/postgres_regress/sqljson.metadata.json @@ -1,223 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json b/parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json index 17a73dc..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json +++ b/parser/testdata/summary/postgres_regress/sqljson_jsontable.metadata.json @@ -1,121 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json b/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json index b0ece40..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json +++ b/parser/testdata/summary/postgres_regress/sqljson_queryfuncs.metadata.json @@ -1,314 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/stats.metadata.json b/parser/testdata/summary/postgres_regress/stats.metadata.json index 5fff658..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/stats.metadata.json +++ b/parser/testdata/summary/postgres_regress/stats.metadata.json @@ -1,451 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/stats_ext.metadata.json b/parser/testdata/summary/postgres_regress/stats_ext.metadata.json index b2f6706..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/stats_ext.metadata.json +++ b/parser/testdata/summary/postgres_regress/stats_ext.metadata.json @@ -1,820 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/strings.metadata.json b/parser/testdata/summary/postgres_regress/strings.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/strings.metadata.json +++ b/parser/testdata/summary/postgres_regress/strings.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/subscription.metadata.json b/parser/testdata/summary/postgres_regress/subscription.metadata.json index d3267aa..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/subscription.metadata.json +++ b/parser/testdata/summary/postgres_regress/subscription.metadata.json @@ -1,163 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/subselect.metadata.json b/parser/testdata/summary/postgres_regress/subselect.metadata.json index 354a8d0..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/subselect.metadata.json +++ b/parser/testdata/summary/postgres_regress/subselect.metadata.json @@ -1,273 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/sysviews.metadata.json b/parser/testdata/summary/postgres_regress/sysviews.metadata.json index 7249d3a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/sysviews.metadata.json +++ b/parser/testdata/summary/postgres_regress/sysviews.metadata.json @@ -1,31 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tablesample.metadata.json b/parser/testdata/summary/postgres_regress/tablesample.metadata.json index dc9d431..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tablesample.metadata.json +++ b/parser/testdata/summary/postgres_regress/tablesample.metadata.json @@ -1,60 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tablespace.metadata.json b/parser/testdata/summary/postgres_regress/tablespace.metadata.json index 479ae3b..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tablespace.metadata.json +++ b/parser/testdata/summary/postgres_regress/tablespace.metadata.json @@ -1,208 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/temp.metadata.json b/parser/testdata/summary/postgres_regress/temp.metadata.json index 4e31a92..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/temp.metadata.json +++ b/parser/testdata/summary/postgres_regress/temp.metadata.json @@ -1,166 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/test_setup.metadata.json b/parser/testdata/summary/postgres_regress/test_setup.metadata.json index abfc1a2..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/test_setup.metadata.json +++ b/parser/testdata/summary/postgres_regress/test_setup.metadata.json @@ -1,73 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/text.metadata.json b/parser/testdata/summary/postgres_regress/text.metadata.json index 2ff9db8..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/text.metadata.json +++ b/parser/testdata/summary/postgres_regress/text.metadata.json @@ -1,77 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tid.metadata.json b/parser/testdata/summary/postgres_regress/tid.metadata.json index 66f0b1d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tid.metadata.json +++ b/parser/testdata/summary/postgres_regress/tid.metadata.json @@ -1,45 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tidrangescan.metadata.json b/parser/testdata/summary/postgres_regress/tidrangescan.metadata.json index f069709..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tidrangescan.metadata.json +++ b/parser/testdata/summary/postgres_regress/tidrangescan.metadata.json @@ -1,49 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tidscan.metadata.json b/parser/testdata/summary/postgres_regress/tidscan.metadata.json index 74725a7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tidscan.metadata.json +++ b/parser/testdata/summary/postgres_regress/tidscan.metadata.json @@ -1,53 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/time.metadata.json b/parser/testdata/summary/postgres_regress/time.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/time.metadata.json +++ b/parser/testdata/summary/postgres_regress/time.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/timestamp.metadata.json b/parser/testdata/summary/postgres_regress/timestamp.metadata.json index 91e3e07..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/timestamp.metadata.json +++ b/parser/testdata/summary/postgres_regress/timestamp.metadata.json @@ -1,175 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/timestamptz.metadata.json b/parser/testdata/summary/postgres_regress/timestamptz.metadata.json index 82ef9cc..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/timestamptz.metadata.json +++ b/parser/testdata/summary/postgres_regress/timestamptz.metadata.json @@ -1,386 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/timetz.metadata.json b/parser/testdata/summary/postgres_regress/timetz.metadata.json index 7c6405d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/timetz.metadata.json +++ b/parser/testdata/summary/postgres_regress/timetz.metadata.json @@ -1,61 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/transactions.metadata.json b/parser/testdata/summary/postgres_regress/transactions.metadata.json index 342e97a..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/transactions.metadata.json +++ b/parser/testdata/summary/postgres_regress/transactions.metadata.json @@ -1,494 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/triggers.metadata.json b/parser/testdata/summary/postgres_regress/triggers.metadata.json index a56f329..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/triggers.metadata.json +++ b/parser/testdata/summary/postgres_regress/triggers.metadata.json @@ -1,1060 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/truncate.metadata.json b/parser/testdata/summary/postgres_regress/truncate.metadata.json index 5ad4c2c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/truncate.metadata.json +++ b/parser/testdata/summary/postgres_regress/truncate.metadata.json @@ -1,197 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tsdicts.metadata.json b/parser/testdata/summary/postgres_regress/tsdicts.metadata.json index 507be8d..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tsdicts.metadata.json +++ b/parser/testdata/summary/postgres_regress/tsdicts.metadata.json @@ -1,135 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tsearch.metadata.json b/parser/testdata/summary/postgres_regress/tsearch.metadata.json index 16d1dd4..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tsearch.metadata.json +++ b/parser/testdata/summary/postgres_regress/tsearch.metadata.json @@ -1,446 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tsrf.metadata.json b/parser/testdata/summary/postgres_regress/tsrf.metadata.json index e49ea16..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tsrf.metadata.json +++ b/parser/testdata/summary/postgres_regress/tsrf.metadata.json @@ -1,78 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tstypes.metadata.json b/parser/testdata/summary/postgres_regress/tstypes.metadata.json index 1ef8c5f..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tstypes.metadata.json +++ b/parser/testdata/summary/postgres_regress/tstypes.metadata.json @@ -1,242 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/tuplesort.metadata.json b/parser/testdata/summary/postgres_regress/tuplesort.metadata.json index c2deed3..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/tuplesort.metadata.json +++ b/parser/testdata/summary/postgres_regress/tuplesort.metadata.json @@ -1,110 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/txid.metadata.json b/parser/testdata/summary/postgres_regress/txid.metadata.json index c7ce9e3..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/txid.metadata.json +++ b/parser/testdata/summary/postgres_regress/txid.metadata.json @@ -1,51 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/type_sanity.metadata.json b/parser/testdata/summary/postgres_regress/type_sanity.metadata.json index 6a71114..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/type_sanity.metadata.json +++ b/parser/testdata/summary/postgres_regress/type_sanity.metadata.json @@ -1,65 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/typed_table.metadata.json b/parser/testdata/summary/postgres_regress/typed_table.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/typed_table.metadata.json +++ b/parser/testdata/summary/postgres_regress/typed_table.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/unicode.metadata.json b/parser/testdata/summary/postgres_regress/unicode.metadata.json index f51f5c0..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/unicode.metadata.json +++ b/parser/testdata/summary/postgres_regress/unicode.metadata.json @@ -1,21 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/union.metadata.json b/parser/testdata/summary/postgres_regress/union.metadata.json index c2aa882..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/union.metadata.json +++ b/parser/testdata/summary/postgres_regress/union.metadata.json @@ -1,195 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/updatable_views.metadata.json b/parser/testdata/summary/postgres_regress/updatable_views.metadata.json index 317bbe8..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/updatable_views.metadata.json +++ b/parser/testdata/summary/postgres_regress/updatable_views.metadata.json @@ -1,1104 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "1060", - "1061", - "1062", - "1063", - "1064", - "1065", - "1066", - "1067", - "1068", - "1069", - "107", - "1070", - "1071", - "1072", - "1073", - "1074", - "1075", - "1076", - "1077", - "1078", - "1079", - "108", - "1080", - "1081", - "1082", - "1083", - "1084", - "1085", - "1086", - "1087", - "1088", - "1089", - "109", - "1090", - "1091", - "1092", - "1093", - "1094", - "1095", - "1096", - "1097", - "1098", - "1099", - "110", - "1100", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/update.metadata.json b/parser/testdata/summary/postgres_regress/update.metadata.json index 1b73a29..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/update.metadata.json +++ b/parser/testdata/summary/postgres_regress/update.metadata.json @@ -1,261 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/uuid.metadata.json b/parser/testdata/summary/postgres_regress/uuid.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/uuid.metadata.json +++ b/parser/testdata/summary/postgres_regress/uuid.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/vacuum.metadata.json b/parser/testdata/summary/postgres_regress/vacuum.metadata.json index 11c34e0..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/vacuum.metadata.json +++ b/parser/testdata/summary/postgres_regress/vacuum.metadata.json @@ -1,300 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json b/parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json index 5a08d01..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json +++ b/parser/testdata/summary/postgres_regress/vacuum_parallel.metadata.json @@ -1,18 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/varchar.metadata.json b/parser/testdata/summary/postgres_regress/varchar.metadata.json index edb706f..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/varchar.metadata.json +++ b/parser/testdata/summary/postgres_regress/varchar.metadata.json @@ -1,26 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/window.metadata.json b/parser/testdata/summary/postgres_regress/window.metadata.json index a1f4321..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/window.metadata.json +++ b/parser/testdata/summary/postgres_regress/window.metadata.json @@ -1,390 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/with.metadata.json b/parser/testdata/summary/postgres_regress/with.metadata.json index b24b526..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/with.metadata.json +++ b/parser/testdata/summary/postgres_regress/with.metadata.json @@ -1,297 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/write_parallel.metadata.json b/parser/testdata/summary/postgres_regress/write_parallel.metadata.json index edb706f..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/write_parallel.metadata.json +++ b/parser/testdata/summary/postgres_regress/write_parallel.metadata.json @@ -1,26 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/xid.metadata.json b/parser/testdata/summary/postgres_regress/xid.metadata.json index 7852793..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/xid.metadata.json +++ b/parser/testdata/summary/postgres_regress/xid.metadata.json @@ -1,88 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/xml.metadata.json b/parser/testdata/summary/postgres_regress/xml.metadata.json index a6ce2f7..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/xml.metadata.json +++ b/parser/testdata/summary/postgres_regress/xml.metadata.json @@ -1,274 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270" - ] + "todo": [] } diff --git a/parser/testdata/summary/postgres_regress/xmlmap.metadata.json b/parser/testdata/summary/postgres_regress/xmlmap.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary/postgres_regress/xmlmap.metadata.json +++ b/parser/testdata/summary/postgres_regress/xmlmap.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/libpg_query.metadata.json b/parser/testdata/summary_truncate/libpg_query.metadata.json index 8cf86ed..737fd31 100644 --- a/parser/testdata/summary_truncate/libpg_query.metadata.json +++ b/parser/testdata/summary_truncate/libpg_query.metadata.json @@ -1,120 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json b/parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json index 251a33e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/advisory_lock.metadata.json @@ -1,42 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json b/parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json index 592c419..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/aggregates.metadata.json @@ -1,518 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json b/parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json index d5998bc..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/alter_generic.metadata.json @@ -1,336 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json b/parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json index 8836c0c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/alter_operator.metadata.json @@ -1,69 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json b/parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json index bfe6d13..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/alter_table.metadata.json @@ -1,1657 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "1060", - "1061", - "1062", - "1063", - "1064", - "1065", - "1066", - "1067", - "1068", - "1069", - "107", - "1070", - "1071", - "1072", - "1073", - "1074", - "1075", - "1076", - "1077", - "1078", - "1079", - "108", - "1080", - "1081", - "1082", - "1083", - "1084", - "1085", - "1086", - "1087", - "1088", - "1089", - "109", - "1090", - "1091", - "1092", - "1093", - "1094", - "1095", - "1096", - "1097", - "1098", - "1099", - "110", - "1100", - "1101", - "1102", - "1103", - "1104", - "1105", - "1106", - "1107", - "1108", - "1109", - "111", - "1110", - "1111", - "1112", - "1113", - "1114", - "1115", - "1116", - "1117", - "1118", - "1119", - "112", - "1120", - "1121", - "1122", - "1123", - "1124", - "1125", - "1126", - "1127", - "1128", - "1129", - "113", - "1130", - "1131", - "1132", - "1133", - "1134", - "1135", - "1136", - "1137", - "1138", - "1139", - "114", - "1140", - "1141", - "1142", - "1143", - "1144", - "1145", - "1146", - "1147", - "1148", - "1149", - "115", - "1150", - "1151", - "1152", - "1153", - "1154", - "1155", - "1156", - "1157", - "1158", - "1159", - "116", - "1160", - "1161", - "1162", - "1163", - "1164", - "1165", - "1166", - "1167", - "1168", - "1169", - "117", - "1170", - "1171", - "1172", - "1173", - "1174", - "1175", - "1176", - "1177", - "1178", - "1179", - "118", - "1180", - "1181", - "1182", - "1183", - "1184", - "1185", - "1186", - "1187", - "1188", - "1189", - "119", - "1190", - "1191", - "1192", - "1193", - "1194", - "1195", - "1196", - "1197", - "1198", - "1199", - "120", - "1200", - "1201", - "1202", - "1203", - "1204", - "1205", - "1206", - "1207", - "1208", - "1209", - "121", - "1210", - "1211", - "1212", - "1213", - "1214", - "1215", - "1216", - "1217", - "1218", - "1219", - "122", - "1220", - "1221", - "1222", - "1223", - "1224", - "1225", - "1226", - "1227", - "1228", - "1229", - "123", - "1230", - "1231", - "1232", - "1233", - "1234", - "1235", - "1236", - "1237", - "1238", - "1239", - "124", - "1240", - "1241", - "1242", - "1243", - "1244", - "1245", - "1246", - "1247", - "1248", - "1249", - "125", - "1250", - "1251", - "1252", - "1253", - "1254", - "1255", - "1256", - "1257", - "1258", - "1259", - "126", - "1260", - "1261", - "1262", - "1263", - "1264", - "1265", - "1266", - "1267", - "1268", - "1269", - "127", - "1270", - "1271", - "1272", - "1273", - "1274", - "1275", - "1276", - "1277", - "1278", - "1279", - "128", - "1280", - "1281", - "1282", - "1283", - "1284", - "1285", - "1286", - "1287", - "1288", - "1289", - "129", - "1290", - "1291", - "1292", - "1293", - "1294", - "1295", - "1296", - "1297", - "1298", - "1299", - "130", - "1300", - "1301", - "1302", - "1303", - "1304", - "1305", - "1306", - "1307", - "1308", - "1309", - "131", - "1310", - "1311", - "1312", - "1313", - "1314", - "1315", - "1316", - "1317", - "1318", - "1319", - "132", - "1320", - "1321", - "1322", - "1323", - "1324", - "1325", - "1326", - "1327", - "1328", - "1329", - "133", - "1330", - "1331", - "1332", - "1333", - "1334", - "1335", - "1336", - "1337", - "1338", - "1339", - "134", - "1340", - "1341", - "1342", - "1343", - "1344", - "1345", - "1346", - "1347", - "1348", - "1349", - "135", - "1350", - "1351", - "1352", - "1353", - "1354", - "1355", - "1356", - "1357", - "1358", - "1359", - "136", - "1360", - "1361", - "1362", - "1363", - "1364", - "1365", - "1366", - "1367", - "1368", - "1369", - "137", - "1370", - "1371", - "1372", - "1373", - "1374", - "1375", - "1376", - "1377", - "1378", - "1379", - "138", - "1380", - "1381", - "1382", - "1383", - "1384", - "1385", - "1386", - "1387", - "1388", - "1389", - "139", - "1390", - "1391", - "1392", - "1393", - "1394", - "1395", - "1396", - "1397", - "1398", - "1399", - "140", - "1400", - "1401", - "1402", - "1403", - "1404", - "1405", - "1406", - "1407", - "1408", - "1409", - "141", - "1410", - "1411", - "1412", - "1413", - "1414", - "1415", - "1416", - "1417", - "1418", - "1419", - "142", - "1420", - "1421", - "1422", - "1423", - "1424", - "1425", - "1426", - "1427", - "1428", - "1429", - "143", - "1430", - "1431", - "1432", - "1433", - "1434", - "1435", - "1436", - "1437", - "1438", - "1439", - "144", - "1440", - "1441", - "1442", - "1443", - "1444", - "1445", - "1446", - "1447", - "1448", - "1449", - "145", - "1450", - "1451", - "1452", - "1453", - "1454", - "1455", - "1456", - "1457", - "1458", - "1459", - "146", - "1460", - "1461", - "1462", - "1463", - "1464", - "1465", - "1466", - "1467", - "1468", - "1469", - "147", - "1470", - "1471", - "1472", - "1473", - "1474", - "1475", - "1476", - "1477", - "1478", - "1479", - "148", - "1480", - "1481", - "1482", - "1483", - "1484", - "1485", - "1486", - "1487", - "1488", - "1489", - "149", - "1490", - "1491", - "1492", - "1493", - "1494", - "1495", - "1496", - "1497", - "1498", - "1499", - "150", - "1500", - "1501", - "1502", - "1503", - "1504", - "1505", - "1506", - "1507", - "1508", - "1509", - "151", - "1510", - "1511", - "1512", - "1513", - "1514", - "1515", - "1516", - "1517", - "1518", - "1519", - "152", - "1520", - "1521", - "1522", - "1523", - "1524", - "1525", - "1526", - "1527", - "1528", - "1529", - "153", - "1530", - "1531", - "1532", - "1533", - "1534", - "1535", - "1536", - "1537", - "1538", - "1539", - "154", - "1540", - "1541", - "1542", - "1543", - "1544", - "1545", - "1546", - "1547", - "1548", - "1549", - "155", - "1550", - "1551", - "1552", - "1553", - "1554", - "1555", - "1556", - "1557", - "1558", - "1559", - "156", - "1560", - "1561", - "1562", - "1563", - "1564", - "1565", - "1566", - "1567", - "1568", - "1569", - "157", - "1570", - "1571", - "1572", - "1573", - "1574", - "1575", - "1576", - "1577", - "1578", - "1579", - "158", - "1580", - "1581", - "1582", - "1583", - "1584", - "1585", - "1586", - "1587", - "1588", - "1589", - "159", - "1590", - "1591", - "1592", - "1593", - "1594", - "1595", - "1596", - "1597", - "1598", - "1599", - "160", - "1600", - "1601", - "1602", - "1603", - "1604", - "1605", - "1606", - "1607", - "1608", - "1609", - "161", - "1610", - "1611", - "1612", - "1613", - "1614", - "1615", - "1616", - "1617", - "1618", - "1619", - "162", - "1620", - "1621", - "1622", - "1623", - "1624", - "1625", - "1626", - "1627", - "1628", - "1629", - "163", - "1630", - "1631", - "1632", - "1633", - "1634", - "1635", - "1636", - "1637", - "1638", - "1639", - "164", - "1640", - "1641", - "1642", - "1643", - "1644", - "1645", - "1646", - "1647", - "1648", - "1649", - "165", - "1650", - "1651", - "1652", - "1653", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json b/parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json index 92b8f9e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/amutils.metadata.json @@ -1,14 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json b/parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json index a8dc578..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/arrays.metadata.json @@ -1,488 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/async.metadata.json b/parser/testdata/summary_truncate/postgres_regress/async.metadata.json index 4739b17..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/async.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/async.metadata.json @@ -1,15 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/bit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/bit.metadata.json index 0b25d44..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/bit.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/bit.metadata.json @@ -1,136 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json b/parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json index 92b8f9e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/bitmapops.metadata.json @@ -1,14 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json b/parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json index 463f4d4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/boolean.metadata.json @@ -1,102 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/box.metadata.json b/parser/testdata/summary_truncate/postgres_regress/box.metadata.json index 8b15b4c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/box.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/box.metadata.json @@ -1,105 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/brin.metadata.json b/parser/testdata/summary_truncate/postgres_regress/brin.metadata.json index af46f65..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/brin.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/brin.metadata.json @@ -1,72 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json b/parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/brin_bloom.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json b/parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json index 643d115..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/brin_multi.metadata.json @@ -1,176 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json b/parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json index 11ed4d1..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/btree_index.metadata.json @@ -1,100 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/case.metadata.json b/parser/testdata/summary_truncate/postgres_regress/case.metadata.json index f47f175..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/case.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/case.metadata.json @@ -1,68 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/char.metadata.json b/parser/testdata/summary_truncate/postgres_regress/char.metadata.json index efb3a10..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/char.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/char.metadata.json @@ -1,36 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/circle.metadata.json b/parser/testdata/summary_truncate/postgres_regress/circle.metadata.json index edb706f..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/circle.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/circle.metadata.json @@ -1,26 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json b/parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json index 479ae3b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/cluster.metadata.json @@ -1,208 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json index faccb98..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/collate.icu.utf8.metadata.json @@ -1,505 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json index 648a6d3..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/collate.linux.utf8.metadata.json @@ -1,207 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.metadata.json index 267f283..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/collate.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/collate.metadata.json @@ -1,148 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json index 5d34ab7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/collate.utf8.metadata.json @@ -1,28 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json b/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json index a4f4300..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/collate.windows.win1252.metadata.json @@ -1,177 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/combocid.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/comments.metadata.json b/parser/testdata/summary_truncate/postgres_regress/comments.metadata.json index 980156f..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/comments.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/comments.metadata.json @@ -1,10 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/compression.metadata.json b/parser/testdata/summary_truncate/postgres_regress/compression.metadata.json index 8e8d1f7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/compression.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/compression.metadata.json @@ -1,91 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json b/parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json index 60d70f4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/constraints.metadata.json @@ -1,323 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json b/parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json index 8836c0c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/conversion.metadata.json @@ -1,69 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/copy.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copy.metadata.json index 8e8d1f7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/copy.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/copy.metadata.json @@ -1,91 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/copy2.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json index f53b7f4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/copydml.metadata.json @@ -1,63 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json b/parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json index 56098cb..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/copyselect.metadata.json @@ -1,25 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json index f53b7f4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_aggregate.metadata.json @@ -1,63 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json index 83b3df4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_am.metadata.json @@ -1,146 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json index 5d34ab7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_cast.metadata.json @@ -1,28 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json index e8e06a4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_function_c.metadata.json @@ -1,9 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json index 643249b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_function_sql.metadata.json @@ -1,159 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json index 528c575..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_index.metadata.json @@ -1,615 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json index 18fb3ca..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_index_spgist.metadata.json @@ -1,206 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json index aa15346..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_misc.metadata.json @@ -1,92 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json index 44e163a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_operator.metadata.json @@ -1,94 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json index c169184..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_procedure.metadata.json @@ -1,113 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json index 6835d4b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_role.metadata.json @@ -1,141 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json index 7249d3a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_schema.metadata.json @@ -1,31 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json index f382372..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_table.metadata.json @@ -1,330 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json index 267f283..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_table_like.metadata.json @@ -1,148 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json index b064cb7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_type.metadata.json @@ -1,89 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json b/parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json index 5d2a46c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/create_view.metadata.json @@ -1,311 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/database.metadata.json b/parser/testdata/summary_truncate/postgres_regress/database.metadata.json index e71b2c2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/database.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/database.metadata.json @@ -1,20 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/date.metadata.json b/parser/testdata/summary_truncate/postgres_regress/date.metadata.json index a6ce2f7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/date.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/date.metadata.json @@ -1,274 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json b/parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json index 253273e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/dbsize.metadata.json @@ -1,29 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/delete.metadata.json b/parser/testdata/summary_truncate/postgres_regress/delete.metadata.json index 92b8f9e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/delete.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/delete.metadata.json @@ -1,14 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json b/parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/dependency.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/domain.metadata.json b/parser/testdata/summary_truncate/postgres_regress/domain.metadata.json index 60d70f4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/domain.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/domain.metadata.json @@ -1,323 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json b/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json index 3b3c7f2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/drop_if_exists.metadata.json @@ -1,165 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json b/parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json index bf73c3a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/drop_operator.metadata.json @@ -1,16 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/enum.metadata.json b/parser/testdata/summary_truncate/postgres_regress/enum.metadata.json index 6f770d9..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/enum.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/enum.metadata.json @@ -1,174 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json b/parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json index 364fcc5..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/equivclass.metadata.json @@ -1,83 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/errors.metadata.json b/parser/testdata/summary_truncate/postgres_regress/errors.metadata.json index b064cb7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/errors.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/errors.metadata.json @@ -1,89 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json b/parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json index 21e7df0..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/event_trigger.metadata.json @@ -1,234 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json b/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json index 4739b17..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/event_trigger_login.metadata.json @@ -1,15 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/explain.metadata.json b/parser/testdata/summary_truncate/postgres_regress/explain.metadata.json index fbb3e40..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/explain.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/explain.metadata.json @@ -1,55 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json b/parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json index fb72ee9..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/expressions.metadata.json @@ -1,75 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json b/parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json index 354a8d0..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/fast_default.metadata.json @@ -1,273 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/float4.metadata.json b/parser/testdata/summary_truncate/postgres_regress/float4.metadata.json index a864d8e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/float4.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/float4.metadata.json @@ -1,104 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/float8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/float8.metadata.json index 194b55b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/float8.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/float8.metadata.json @@ -1,173 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json b/parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json index efde331..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/foreign_data.metadata.json @@ -1,534 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json b/parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json index 0d39ce9..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/foreign_key.metadata.json @@ -1,1158 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "1060", - "1061", - "1062", - "1063", - "1064", - "1065", - "1066", - "1067", - "1068", - "1069", - "107", - "1070", - "1071", - "1072", - "1073", - "1074", - "1075", - "1076", - "1077", - "1078", - "1079", - "108", - "1080", - "1081", - "1082", - "1083", - "1084", - "1085", - "1086", - "1087", - "1088", - "1089", - "109", - "1090", - "1091", - "1092", - "1093", - "1094", - "1095", - "1096", - "1097", - "1098", - "1099", - "110", - "1100", - "1101", - "1102", - "1103", - "1104", - "1105", - "1106", - "1107", - "1108", - "1109", - "111", - "1110", - "1111", - "1112", - "1113", - "1114", - "1115", - "1116", - "1117", - "1118", - "1119", - "112", - "1120", - "1121", - "1122", - "1123", - "1124", - "1125", - "1126", - "1127", - "1128", - "1129", - "113", - "1130", - "1131", - "1132", - "1133", - "1134", - "1135", - "1136", - "1137", - "1138", - "1139", - "114", - "1140", - "1141", - "1142", - "1143", - "1144", - "1145", - "1146", - "1147", - "1148", - "1149", - "115", - "1150", - "1151", - "1152", - "1153", - "1154", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json b/parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/functional_deps.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/generated.metadata.json b/parser/testdata/summary_truncate/postgres_regress/generated.metadata.json index b6ecb7b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/generated.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/generated.metadata.json @@ -1,123 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json b/parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json index 4e31a92..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/geometry.metadata.json @@ -1,166 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/gin.metadata.json b/parser/testdata/summary_truncate/postgres_regress/gin.metadata.json index f53b7f4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/gin.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/gin.metadata.json @@ -1,63 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/gist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/gist.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/gist.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/gist.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json b/parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json index 643d115..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/groupingsets.metadata.json @@ -1,176 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/guc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/guc.metadata.json index 8f8fab6..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/guc.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/guc.metadata.json @@ -1,218 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json b/parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json index e74143a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/hash_func.metadata.json @@ -1,47 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json b/parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json index ba349a5..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/hash_index.metadata.json @@ -1,101 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json b/parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/hash_part.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/horology.metadata.json b/parser/testdata/summary_truncate/postgres_regress/horology.metadata.json index 820fe8a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/horology.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/horology.metadata.json @@ -1,392 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/identity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/identity.metadata.json index a6ce2f7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/identity.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/identity.metadata.json @@ -1,274 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json b/parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json index b6ecb7b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/incremental_sort.metadata.json @@ -1,123 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json b/parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json index e6f6795..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/index_including.metadata.json @@ -1,139 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json index 147070d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/index_including_gist.metadata.json @@ -1,54 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json b/parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json index 44a2d56..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/indexing.metadata.json @@ -1,564 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json b/parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/indirect_toast.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/inet.metadata.json b/parser/testdata/summary_truncate/postgres_regress/inet.metadata.json index 1211f6e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/inet.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/inet.metadata.json @@ -1,115 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json b/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json index 3e33966..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/infinite_recurse.metadata.json @@ -1,7 +1,3 @@ { - "todo": [ - "001", - "002", - "003" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json index 53ffb30..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/inherit.metadata.json @@ -1,681 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json b/parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json index f1ffe06..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/init_privs.metadata.json @@ -1,8 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/insert.metadata.json b/parser/testdata/summary_truncate/postgres_regress/insert.metadata.json index 1751d7d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/insert.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/insert.metadata.json @@ -1,391 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json b/parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json index 1b73a29..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/insert_conflict.metadata.json @@ -1,261 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/int2.metadata.json b/parser/testdata/summary_truncate/postgres_regress/int2.metadata.json index f476ef8..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/int2.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/int2.metadata.json @@ -1,80 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/int4.metadata.json b/parser/testdata/summary_truncate/postgres_regress/int4.metadata.json index da94530..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/int4.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/int4.metadata.json @@ -1,98 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/int8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/int8.metadata.json index 6eafe87..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/int8.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/int8.metadata.json @@ -1,171 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/interval.metadata.json b/parser/testdata/summary_truncate/postgres_regress/interval.metadata.json index df238f5..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/interval.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/interval.metadata.json @@ -1,447 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/join.metadata.json b/parser/testdata/summary_truncate/postgres_regress/join.metadata.json index 3b007a6..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/join.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/join.metadata.json @@ -1,719 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json b/parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json index 5bababc..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/join_hash.metadata.json @@ -1,283 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/json.metadata.json b/parser/testdata/summary_truncate/postgres_regress/json.metadata.json index 15b4f09..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/json.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/json.metadata.json @@ -1,464 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json b/parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/json_encoding.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json index 4c380dc..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/jsonb.metadata.json @@ -1,1063 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json index b53b6f2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/jsonb_jsonpath.metadata.json @@ -1,825 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json index 402e8ee..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/jsonpath.metadata.json @@ -1,228 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json b/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json index efb3a10..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/jsonpath_encoding.metadata.json @@ -1,36 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json b/parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json index 48ba122..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/largeobject.metadata.json @@ -1,128 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/limit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/limit.metadata.json index fb87925..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/limit.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/limit.metadata.json @@ -1,84 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/line.metadata.json b/parser/testdata/summary_truncate/postgres_regress/line.metadata.json index bfeb57a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/line.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/line.metadata.json @@ -1,39 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/lock.metadata.json b/parser/testdata/summary_truncate/postgres_regress/lock.metadata.json index 507be8d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/lock.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/lock.metadata.json @@ -1,135 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json b/parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json index e71b2c2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/lseg.metadata.json @@ -1,20 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json b/parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json index bfeb57a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/macaddr.metadata.json @@ -1,39 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json b/parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json index fb72ee9..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/macaddr8.metadata.json @@ -1,75 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json b/parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json index e71b2c2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/maintain_every.metadata.json @@ -1,20 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/matview.metadata.json b/parser/testdata/summary_truncate/postgres_regress/matview.metadata.json index 784b93c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/matview.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/matview.metadata.json @@ -1,183 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/md5.metadata.json b/parser/testdata/summary_truncate/postgres_regress/md5.metadata.json index 5a08d01..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/md5.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/md5.metadata.json @@ -1,18 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json b/parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json index abfc1a2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/memoize.metadata.json @@ -1,73 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/merge.metadata.json b/parser/testdata/summary_truncate/postgres_regress/merge.metadata.json index 168c3f9..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/merge.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/merge.metadata.json @@ -1,576 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/misc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/misc.metadata.json index 6a71114..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/misc.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/misc.metadata.json @@ -1,65 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json b/parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json index b6ecb7b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/misc_functions.metadata.json @@ -1,123 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json index e8e06a4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/misc_sanity.metadata.json @@ -1,9 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/money.metadata.json b/parser/testdata/summary_truncate/postgres_regress/money.metadata.json index c169184..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/money.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/money.metadata.json @@ -1,113 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json index 6769ac6..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/multirangetypes.metadata.json @@ -1,609 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json index 4739b17..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/mvcc.metadata.json @@ -1,15 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/name.metadata.json b/parser/testdata/summary_truncate/postgres_regress/name.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/name.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/name.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json b/parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json index 6e8763d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/namespace.metadata.json @@ -1,46 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json b/parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json index e7297cf..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/numeric.metadata.json @@ -1,1022 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json b/parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json index 05e97cf..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/numeric_big.metadata.json @@ -1,556 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json b/parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/numerology.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json b/parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json index 5c84308..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/object_address.metadata.json @@ -1,85 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/oid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/oid.metadata.json index 6a83420..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/oid.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/oid.metadata.json @@ -1,41 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json b/parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/oidjoins.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json index 304478c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/opr_sanity.metadata.json @@ -1,134 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json index e6f6795..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/partition_aggregate.metadata.json @@ -1,139 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json index 2ff9db8..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/partition_info.metadata.json @@ -1,77 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json index 6fa7813..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/partition_join.metadata.json @@ -1,604 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json b/parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json index 6644147..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/partition_prune.metadata.json @@ -1,702 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/password.metadata.json b/parser/testdata/summary_truncate/postgres_regress/password.metadata.json index fbb3e40..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/password.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/password.metadata.json @@ -1,55 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/path.metadata.json b/parser/testdata/summary_truncate/postgres_regress/path.metadata.json index 880b1d2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/path.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/path.metadata.json @@ -1,27 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json b/parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json index 442b788..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/pg_lsn.metadata.json @@ -1,35 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json b/parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json index ba349a5..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/plancache.metadata.json @@ -1,101 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json b/parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json index 35fd146..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/plpgsql.metadata.json @@ -1,945 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/point.metadata.json b/parser/testdata/summary_truncate/postgres_regress/point.metadata.json index e74143a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/point.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/point.metadata.json @@ -1,47 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json b/parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json index 7d59f7e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/polygon.metadata.json @@ -1,66 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json b/parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json index 835764e..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/polymorphism.metadata.json @@ -1,427 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/portals.metadata.json b/parser/testdata/summary_truncate/postgres_regress/portals.metadata.json index f599902..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/portals.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/portals.metadata.json @@ -1,353 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json b/parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json index 66f0b1d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/portals_p2.metadata.json @@ -1,45 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json index 6e8763d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/predicate.metadata.json @@ -1,46 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json b/parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json index daef5f1..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/prepare.metadata.json @@ -1,37 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json b/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json index 449cbc1..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/prepared_xacts.metadata.json @@ -1,87 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json b/parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json index 302fef8..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/privileges.metadata.json @@ -1,335 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/psql.metadata.json b/parser/testdata/summary_truncate/postgres_regress/psql.metadata.json index 0612d4a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/psql.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/psql.metadata.json @@ -1,200 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json b/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json index 5e6664a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/psql_crosstab.metadata.json @@ -1,12 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/publication.metadata.json b/parser/testdata/summary_truncate/postgres_regress/publication.metadata.json index 8cf9d31..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/publication.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/publication.metadata.json @@ -1,659 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/random.metadata.json b/parser/testdata/summary_truncate/postgres_regress/random.metadata.json index 634de79..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/random.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/random.metadata.json @@ -1,52 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json index 526d3ef..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/rangefuncs.metadata.json @@ -1,432 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json index fa6f7df..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/rangetypes.metadata.json @@ -1,411 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/regex.metadata.json b/parser/testdata/summary_truncate/postgres_regress/regex.metadata.json index 60e76e3..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/regex.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/regex.metadata.json @@ -1,109 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/regproc.metadata.json b/parser/testdata/summary_truncate/postgres_regress/regproc.metadata.json index 60e76e3..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/regproc.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/regproc.metadata.json @@ -1,109 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/reindex_catalog.metadata.json b/parser/testdata/summary_truncate/postgres_regress/reindex_catalog.metadata.json index 229dde4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/reindex_catalog.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/reindex_catalog.metadata.json @@ -1,24 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/reloptions.metadata.json b/parser/testdata/summary_truncate/postgres_regress/reloptions.metadata.json index 7a82cd3..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/reloptions.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/reloptions.metadata.json @@ -1,70 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json index dc9d431..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/replica_identity.metadata.json @@ -1,60 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/returning.metadata.json b/parser/testdata/summary_truncate/postgres_regress/returning.metadata.json index 2be5689..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/returning.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/returning.metadata.json @@ -1,81 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json index fb87925..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/roleattributes.metadata.json @@ -1,84 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json index dcaa437..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/rowsecurity.metadata.json @@ -1,779 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json index e9da7a5..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/rowtypes.metadata.json @@ -1,241 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/rules.metadata.json b/parser/testdata/summary_truncate/postgres_regress/rules.metadata.json index 75d8f0c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/rules.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/rules.metadata.json @@ -1,624 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json index 3e33966..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/sanity_check.metadata.json @@ -1,7 +1,3 @@ { - "todo": [ - "001", - "002", - "003" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json b/parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/security_label.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select.metadata.json index 8e8d1f7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select.metadata.json @@ -1,91 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json index f476ef8..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select_distinct.metadata.json @@ -1,80 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json index 5e6664a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select_distinct_on.metadata.json @@ -1,12 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json index 880b1d2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select_having.metadata.json @@ -1,27 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select_implicit.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json index 0a7b0c8..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select_into.metadata.json @@ -1,71 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json index 60ff1c2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select_parallel.metadata.json @@ -1,239 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json b/parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json index f37dd99..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/select_views.metadata.json @@ -1,56 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json index 38ac4c2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/sequence.metadata.json @@ -1,264 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json b/parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json index 442b788..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/spgist.metadata.json @@ -1,35 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json index 78efa1d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson.metadata.json @@ -1,223 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json index 17a73dc..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson_jsontable.metadata.json @@ -1,121 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json index b0ece40..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/sqljson_queryfuncs.metadata.json @@ -1,314 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/stats.metadata.json b/parser/testdata/summary_truncate/postgres_regress/stats.metadata.json index 5fff658..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/stats.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/stats.metadata.json @@ -1,451 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json b/parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json index b2f6706..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/stats_ext.metadata.json @@ -1,820 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/strings.metadata.json b/parser/testdata/summary_truncate/postgres_regress/strings.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/strings.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/strings.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json b/parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json index d3267aa..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/subscription.metadata.json @@ -1,163 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json b/parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json index 354a8d0..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/subselect.metadata.json @@ -1,273 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json b/parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json index 7249d3a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/sysviews.metadata.json @@ -1,31 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json index dc9d431..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tablesample.metadata.json @@ -1,60 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json index 479ae3b..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tablespace.metadata.json @@ -1,208 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/temp.metadata.json b/parser/testdata/summary_truncate/postgres_regress/temp.metadata.json index 4e31a92..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/temp.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/temp.metadata.json @@ -1,166 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json b/parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json index abfc1a2..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/test_setup.metadata.json @@ -1,73 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/text.metadata.json b/parser/testdata/summary_truncate/postgres_regress/text.metadata.json index 2ff9db8..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/text.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/text.metadata.json @@ -1,77 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tid.metadata.json index 66f0b1d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tid.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tid.metadata.json @@ -1,45 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json index f069709..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tidrangescan.metadata.json @@ -1,49 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json index 74725a7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tidscan.metadata.json @@ -1,53 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/time.metadata.json b/parser/testdata/summary_truncate/postgres_regress/time.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/time.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/time.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json b/parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json index 91e3e07..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/timestamp.metadata.json @@ -1,175 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json b/parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json index 82ef9cc..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/timestamptz.metadata.json @@ -1,386 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json b/parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json index 7c6405d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/timetz.metadata.json @@ -1,61 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json b/parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json index 342e97a..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/transactions.metadata.json @@ -1,494 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json b/parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json index a56f329..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/triggers.metadata.json @@ -1,1060 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json b/parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json index 5ad4c2c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/truncate.metadata.json @@ -1,197 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json index 507be8d..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tsdicts.metadata.json @@ -1,135 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json index 16d1dd4..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tsearch.metadata.json @@ -1,446 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json index e49ea16..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tsrf.metadata.json @@ -1,78 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json index 1ef8c5f..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tstypes.metadata.json @@ -1,242 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json b/parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json index c2deed3..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/tuplesort.metadata.json @@ -1,110 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/txid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/txid.metadata.json index c7ce9e3..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/txid.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/txid.metadata.json @@ -1,51 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json b/parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json index 6a71114..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/type_sanity.metadata.json @@ -1,65 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json b/parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json index d49a93c..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/typed_table.metadata.json @@ -1,32 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json b/parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json index f51f5c0..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/unicode.metadata.json @@ -1,21 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/union.metadata.json b/parser/testdata/summary_truncate/postgres_regress/union.metadata.json index c2aa882..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/union.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/union.metadata.json @@ -1,195 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json b/parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json index 317bbe8..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/updatable_views.metadata.json @@ -1,1104 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "1000", - "1001", - "1002", - "1003", - "1004", - "1005", - "1006", - "1007", - "1008", - "1009", - "101", - "1010", - "1011", - "1012", - "1013", - "1014", - "1015", - "1016", - "1017", - "1018", - "1019", - "102", - "1020", - "1021", - "1022", - "1023", - "1024", - "1025", - "1026", - "1027", - "1028", - "1029", - "103", - "1030", - "1031", - "1032", - "1033", - "1034", - "1035", - "1036", - "1037", - "1038", - "1039", - "104", - "1040", - "1041", - "1042", - "1043", - "1044", - "1045", - "1046", - "1047", - "1048", - "1049", - "105", - "1050", - "1051", - "1052", - "1053", - "1054", - "1055", - "1056", - "1057", - "1058", - "1059", - "106", - "1060", - "1061", - "1062", - "1063", - "1064", - "1065", - "1066", - "1067", - "1068", - "1069", - "107", - "1070", - "1071", - "1072", - "1073", - "1074", - "1075", - "1076", - "1077", - "1078", - "1079", - "108", - "1080", - "1081", - "1082", - "1083", - "1084", - "1085", - "1086", - "1087", - "1088", - "1089", - "109", - "1090", - "1091", - "1092", - "1093", - "1094", - "1095", - "1096", - "1097", - "1098", - "1099", - "110", - "1100", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386", - "387", - "388", - "389", - "390", - "391", - "392", - "393", - "394", - "395", - "396", - "397", - "398", - "399", - "400", - "401", - "402", - "403", - "404", - "405", - "406", - "407", - "408", - "409", - "410", - "411", - "412", - "413", - "414", - "415", - "416", - "417", - "418", - "419", - "420", - "421", - "422", - "423", - "424", - "425", - "426", - "427", - "428", - "429", - "430", - "431", - "432", - "433", - "434", - "435", - "436", - "437", - "438", - "439", - "440", - "441", - "442", - "443", - "444", - "445", - "446", - "447", - "448", - "449", - "450", - "451", - "452", - "453", - "454", - "455", - "456", - "457", - "458", - "459", - "460", - "461", - "462", - "463", - "464", - "465", - "466", - "467", - "468", - "469", - "470", - "471", - "472", - "473", - "474", - "475", - "476", - "477", - "478", - "479", - "480", - "481", - "482", - "483", - "484", - "485", - "486", - "487", - "488", - "489", - "490", - "491", - "492", - "493", - "494", - "495", - "496", - "497", - "498", - "499", - "500", - "501", - "502", - "503", - "504", - "505", - "506", - "507", - "508", - "509", - "510", - "511", - "512", - "513", - "514", - "515", - "516", - "517", - "518", - "519", - "520", - "521", - "522", - "523", - "524", - "525", - "526", - "527", - "528", - "529", - "530", - "531", - "532", - "533", - "534", - "535", - "536", - "537", - "538", - "539", - "540", - "541", - "542", - "543", - "544", - "545", - "546", - "547", - "548", - "549", - "550", - "551", - "552", - "553", - "554", - "555", - "556", - "557", - "558", - "559", - "560", - "561", - "562", - "563", - "564", - "565", - "566", - "567", - "568", - "569", - "570", - "571", - "572", - "573", - "574", - "575", - "576", - "577", - "578", - "579", - "580", - "581", - "582", - "583", - "584", - "585", - "586", - "587", - "588", - "589", - "590", - "591", - "592", - "593", - "594", - "595", - "596", - "597", - "598", - "599", - "600", - "601", - "602", - "603", - "604", - "605", - "606", - "607", - "608", - "609", - "610", - "611", - "612", - "613", - "614", - "615", - "616", - "617", - "618", - "619", - "620", - "621", - "622", - "623", - "624", - "625", - "626", - "627", - "628", - "629", - "630", - "631", - "632", - "633", - "634", - "635", - "636", - "637", - "638", - "639", - "640", - "641", - "642", - "643", - "644", - "645", - "646", - "647", - "648", - "649", - "650", - "651", - "652", - "653", - "654", - "655", - "656", - "657", - "658", - "659", - "660", - "661", - "662", - "663", - "664", - "665", - "666", - "667", - "668", - "669", - "670", - "671", - "672", - "673", - "674", - "675", - "676", - "677", - "678", - "679", - "680", - "681", - "682", - "683", - "684", - "685", - "686", - "687", - "688", - "689", - "690", - "691", - "692", - "693", - "694", - "695", - "696", - "697", - "698", - "699", - "700", - "701", - "702", - "703", - "704", - "705", - "706", - "707", - "708", - "709", - "710", - "711", - "712", - "713", - "714", - "715", - "716", - "717", - "718", - "719", - "720", - "721", - "722", - "723", - "724", - "725", - "726", - "727", - "728", - "729", - "730", - "731", - "732", - "733", - "734", - "735", - "736", - "737", - "738", - "739", - "740", - "741", - "742", - "743", - "744", - "745", - "746", - "747", - "748", - "749", - "750", - "751", - "752", - "753", - "754", - "755", - "756", - "757", - "758", - "759", - "760", - "761", - "762", - "763", - "764", - "765", - "766", - "767", - "768", - "769", - "770", - "771", - "772", - "773", - "774", - "775", - "776", - "777", - "778", - "779", - "780", - "781", - "782", - "783", - "784", - "785", - "786", - "787", - "788", - "789", - "790", - "791", - "792", - "793", - "794", - "795", - "796", - "797", - "798", - "799", - "800", - "801", - "802", - "803", - "804", - "805", - "806", - "807", - "808", - "809", - "810", - "811", - "812", - "813", - "814", - "815", - "816", - "817", - "818", - "819", - "820", - "821", - "822", - "823", - "824", - "825", - "826", - "827", - "828", - "829", - "830", - "831", - "832", - "833", - "834", - "835", - "836", - "837", - "838", - "839", - "840", - "841", - "842", - "843", - "844", - "845", - "846", - "847", - "848", - "849", - "850", - "851", - "852", - "853", - "854", - "855", - "856", - "857", - "858", - "859", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "867", - "868", - "869", - "870", - "871", - "872", - "873", - "874", - "875", - "876", - "877", - "878", - "879", - "880", - "881", - "882", - "883", - "884", - "885", - "886", - "887", - "888", - "889", - "890", - "891", - "892", - "893", - "894", - "895", - "896", - "897", - "898", - "899", - "900", - "901", - "902", - "903", - "904", - "905", - "906", - "907", - "908", - "909", - "910", - "911", - "912", - "913", - "914", - "915", - "916", - "917", - "918", - "919", - "920", - "921", - "922", - "923", - "924", - "925", - "926", - "927", - "928", - "929", - "930", - "931", - "932", - "933", - "934", - "935", - "936", - "937", - "938", - "939", - "940", - "941", - "942", - "943", - "944", - "945", - "946", - "947", - "948", - "949", - "950", - "951", - "952", - "953", - "954", - "955", - "956", - "957", - "958", - "959", - "960", - "961", - "962", - "963", - "964", - "965", - "966", - "967", - "968", - "969", - "970", - "971", - "972", - "973", - "974", - "975", - "976", - "977", - "978", - "979", - "980", - "981", - "982", - "983", - "984", - "985", - "986", - "987", - "988", - "989", - "990", - "991", - "992", - "993", - "994", - "995", - "996", - "997", - "998", - "999" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/update.metadata.json b/parser/testdata/summary_truncate/postgres_regress/update.metadata.json index 1b73a29..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/update.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/update.metadata.json @@ -1,261 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json index c30fd55..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/uuid.metadata.json @@ -1,48 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json b/parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json index 11c34e0..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/vacuum.metadata.json @@ -1,300 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json b/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json index 5a08d01..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/vacuum_parallel.metadata.json @@ -1,18 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json b/parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json index edb706f..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/varchar.metadata.json @@ -1,26 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/window.metadata.json b/parser/testdata/summary_truncate/postgres_regress/window.metadata.json index a1f4321..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/window.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/window.metadata.json @@ -1,390 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293", - "294", - "295", - "296", - "297", - "298", - "299", - "300", - "301", - "302", - "303", - "304", - "305", - "306", - "307", - "308", - "309", - "310", - "311", - "312", - "313", - "314", - "315", - "316", - "317", - "318", - "319", - "320", - "321", - "322", - "323", - "324", - "325", - "326", - "327", - "328", - "329", - "330", - "331", - "332", - "333", - "334", - "335", - "336", - "337", - "338", - "339", - "340", - "341", - "342", - "343", - "344", - "345", - "346", - "347", - "348", - "349", - "350", - "351", - "352", - "353", - "354", - "355", - "356", - "357", - "358", - "359", - "360", - "361", - "362", - "363", - "364", - "365", - "366", - "367", - "368", - "369", - "370", - "371", - "372", - "373", - "374", - "375", - "376", - "377", - "378", - "379", - "380", - "381", - "382", - "383", - "384", - "385", - "386" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/with.metadata.json b/parser/testdata/summary_truncate/postgres_regress/with.metadata.json index b24b526..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/with.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/with.metadata.json @@ -1,297 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270", - "271", - "272", - "273", - "274", - "275", - "276", - "277", - "278", - "279", - "280", - "281", - "282", - "283", - "284", - "285", - "286", - "287", - "288", - "289", - "290", - "291", - "292", - "293" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json b/parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json index edb706f..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/write_parallel.metadata.json @@ -1,26 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/xid.metadata.json b/parser/testdata/summary_truncate/postgres_regress/xid.metadata.json index 7852793..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/xid.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/xid.metadata.json @@ -1,88 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/xml.metadata.json b/parser/testdata/summary_truncate/postgres_regress/xml.metadata.json index a6ce2f7..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/xml.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/xml.metadata.json @@ -1,274 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158", - "159", - "160", - "161", - "162", - "163", - "164", - "165", - "166", - "167", - "168", - "169", - "170", - "171", - "172", - "173", - "174", - "175", - "176", - "177", - "178", - "179", - "180", - "181", - "182", - "183", - "184", - "185", - "186", - "187", - "188", - "189", - "190", - "191", - "192", - "193", - "194", - "195", - "196", - "197", - "198", - "199", - "200", - "201", - "202", - "203", - "204", - "205", - "206", - "207", - "208", - "209", - "210", - "211", - "212", - "213", - "214", - "215", - "216", - "217", - "218", - "219", - "220", - "221", - "222", - "223", - "224", - "225", - "226", - "227", - "228", - "229", - "230", - "231", - "232", - "233", - "234", - "235", - "236", - "237", - "238", - "239", - "240", - "241", - "242", - "243", - "244", - "245", - "246", - "247", - "248", - "249", - "250", - "251", - "252", - "253", - "254", - "255", - "256", - "257", - "258", - "259", - "260", - "261", - "262", - "263", - "264", - "265", - "266", - "267", - "268", - "269", - "270" - ] + "todo": [] } diff --git a/parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json b/parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json index 32e0be1..737fd31 100644 --- a/parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json +++ b/parser/testdata/summary_truncate/postgres_regress/xmlmap.metadata.json @@ -1,44 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040" - ] + "todo": [] } diff --git a/summary_test.go b/summary_test.go new file mode 100644 index 0000000..f2aadc3 --- /dev/null +++ b/summary_test.go @@ -0,0 +1,132 @@ +package oliphant_test + +import ( + "testing" + + "google.golang.org/protobuf/proto" + + pg_query "github.com/sqlc-dev/oliphant" +) + +var summaryTests = []struct { + input string + truncateLimit int + expected *pg_query.SummaryResult +}{ + // Basic SELECT with filter column + { + input: "SELECT * FROM users WHERE id = 1", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "users", TableName: "users", Context: pg_query.SummaryResult_Select}}, + FilterColumns: []*pg_query.SummaryResult_FilterColumn{{Column: "id"}}, + StatementTypes: []string{"SelectStmt"}, + }, + }, + // Query truncation + { + input: "SELECT id, name, email FROM users WHERE id = 1", + truncateLimit: 30, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "users", TableName: "users", Context: pg_query.SummaryResult_Select}}, + FilterColumns: []*pg_query.SummaryResult_FilterColumn{{Column: "id"}}, + StatementTypes: []string{"SelectStmt"}, + TruncatedQuery: "SELECT ... FROM users WHERE...", + }, + }, + // JOIN with table aliases + { + input: "SELECT * FROM users u JOIN orders o ON u.id = o.user_id", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{ + {Name: "users", TableName: "users", Context: pg_query.SummaryResult_Select}, + {Name: "orders", TableName: "orders", Context: pg_query.SummaryResult_Select}, + }, + Aliases: map[string]string{"u": "users", "o": "orders"}, + StatementTypes: []string{"SelectStmt"}, + }, + }, + // Aggregate functions (count, max) + { + input: "SELECT count(*), max(id) FROM users", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "users", TableName: "users", Context: pg_query.SummaryResult_Select}}, + Functions: []*pg_query.SummaryResult_Function{ + {Name: "count", FunctionName: "count", Context: pg_query.SummaryResult_Call}, + {Name: "max", FunctionName: "max", Context: pg_query.SummaryResult_Call}, + }, + StatementTypes: []string{"SelectStmt"}, + }, + }, + // Common Table Expression (CTE) + { + input: "WITH active_users AS (SELECT * FROM users WHERE active = true) SELECT * FROM active_users", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "users", TableName: "users", Context: pg_query.SummaryResult_Select}}, + CteNames: []string{"active_users"}, + FilterColumns: []*pg_query.SummaryResult_FilterColumn{{Column: "active"}}, + StatementTypes: []string{"SelectStmt"}, + }, + }, + // Schema-qualified table name + { + input: "SELECT * FROM public.users", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "public.users", SchemaName: "public", TableName: "users", Context: pg_query.SummaryResult_Select}}, + StatementTypes: []string{"SelectStmt"}, + }, + }, + // INSERT statement + { + input: "INSERT INTO users (name) VALUES ('test')", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "users", TableName: "users", Context: pg_query.SummaryResult_DML}}, + StatementTypes: []string{"InsertStmt", "SelectStmt"}, + }, + }, + // UPDATE statement + { + input: "UPDATE users SET name = 'test' WHERE id = 1", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "users", TableName: "users", Context: pg_query.SummaryResult_DML}}, + StatementTypes: []string{"UpdateStmt"}, + }, + }, + // DELETE statement + { + input: "DELETE FROM users WHERE id = 1", + truncateLimit: -1, + expected: &pg_query.SummaryResult{ + Tables: []*pg_query.SummaryResult_Table{{Name: "users", TableName: "users", Context: pg_query.SummaryResult_DML}}, + StatementTypes: []string{"DeleteStmt"}, + }, + }, +} + +func TestSummary(t *testing.T) { + for _, tt := range summaryTests { + t.Run(tt.input, func(t *testing.T) { + result, err := pg_query.Summary(tt.input, tt.truncateLimit) + if err != nil { + t.Fatalf("Summary() error: %s", err) + } + + if !proto.Equal(result, tt.expected) { + t.Errorf("Summary() mismatch:\n got: %v\n expected: %v", result, tt.expected) + } + }) + } +} + +func TestSummaryError(t *testing.T) { + _, err := pg_query.Summary("SELECT * FROM", -1) + if err == nil { + t.Error("expected error for invalid SQL") + } +} From eca5f8298f8c3a8e6db61cef836fff8b44f7de6f Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 04:47:39 +0000 Subject: [PATCH 3/5] =?UTF-8?q?Milestone=2011:=20PL/pgSQL=20=E2=80=94=20pl?= =?UTF-8?q?=5Fgram=20port=20+=20JSON=20dump=20behind=20ParsePlPgSqlToJSON?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port the PL/pgSQL support libpg_query builds at the pin: - internal/plpgsql: pl_gram.y as recursive descent (statement linenos computed at bison's reduce points, since plpgsql_latest_lineno is stateful and feeds the compile error context), the pl_scanner.c token layer over the core lexer (PL reserved keywords re-classified from the SQL scanner's output, pushback stack, A.B.C composition), the pl_comp.c/pl_funcs.c subset (namespace chain, datums, recfields, exception conditions), pg_query_json_plpgsql.c's dump, and the pg_query_parse_plpgsql.c driver — including libpg_query's mocks: parse_datatype keeps the type text verbatim, %TYPE/%ROWTYPE lookups return NULL, make_return_stmt drops return-type checks, and function_parse_error_transpose always fails (errors carry the "near line N" context, no cursor). - internal/parse: ParseWithMode with the RAW_PARSE_PLPGSQL_EXPR and ASSIGN1..3 grammar modes (PLpgSQL_Expr / PLAssignStmt productions), which check_sql_expr uses to validate embedded SQL. - internal/rawwalk: the raw_expression_tree_walker port moves out of internal/summary so the driver's statement collection can share it. - cmd/generate -plpgsql emits internal/plpgsql/tables.go from the newly vendored pl_reserved_kwlist.h / pl_unreserved_kwlist.h / plerrcodes.h (internal/reference gains those plus patched pl_gram.y, pl_scanner.c). Gate: all 690 plpgsql corpus cases (plpgsql_regress + plpgsql_samples + per-statement tiers) pass, as does pg_query_go's TestParsePlPgSQL; the corpus todo list is now empty across all eleven suites — 308,561 cases. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01C5Ummi5YEg7pxk5fvRUd3U --- .github/workflows/ci.yml | 2 +- cmd/generate/main.go | 11 +- cmd/generate/plpgsql.go | 97 + compat_test.go | 18 - internal/emit/emit.go | 5 + internal/parse/modes.go | 174 + internal/plpgsql/ast.go | 533 +++ internal/plpgsql/comp.go | 461 ++ internal/plpgsql/entry.go | 329 ++ internal/plpgsql/gram.go | 1518 ++++++ internal/plpgsql/gram_support.go | 960 ++++ internal/plpgsql/json.go | 456 ++ internal/plpgsql/scanner.go | 513 ++ internal/plpgsql/tables.go | 373 ++ internal/{summary => rawwalk}/walker.go | 33 +- internal/reference/README.md | 21 +- internal/reference/pl_gram.y | 4173 +++++++++++++++++ internal/reference/pl_reserved_kwlist.h | 52 + internal/reference/pl_scanner.c | 642 +++ internal/reference/pl_unreserved_kwlist.h | 112 + internal/reference/plerrcodes.h | 998 ++++ internal/summary/stmt_types.go | 11 +- internal/summary/summary.go | 13 +- internal/summary/truncate.go | 9 +- parser/parser.go | 16 +- .../plpgsql_array.metadata.json | 34 +- .../plpgsql_cache.metadata.json | 16 +- .../plpgsql_call.metadata.json | 86 +- .../plpgsql_control.metadata.json | 56 +- .../plpgsql_copy.metadata.json | 4 +- .../plpgsql_domain.metadata.json | 85 +- .../plpgsql_misc.metadata.json | 17 +- .../plpgsql_record.metadata.json | 161 +- .../plpgsql_simple.metadata.json | 27 +- .../plpgsql_transaction.metadata.json | 120 +- .../plpgsql_trap.metadata.json | 45 +- .../plpgsql_trigger.metadata.json | 9 +- .../plpgsql_varprops.metadata.json | 40 +- .../plpgsql/plpgsql_samples.metadata.json | 32 +- 39 files changed, 11489 insertions(+), 773 deletions(-) create mode 100644 cmd/generate/plpgsql.go create mode 100644 internal/parse/modes.go create mode 100644 internal/plpgsql/ast.go create mode 100644 internal/plpgsql/comp.go create mode 100644 internal/plpgsql/entry.go create mode 100644 internal/plpgsql/gram.go create mode 100644 internal/plpgsql/gram_support.go create mode 100644 internal/plpgsql/json.go create mode 100644 internal/plpgsql/scanner.go create mode 100644 internal/plpgsql/tables.go rename internal/{summary => rawwalk}/walker.go (92%) create mode 100644 internal/reference/pl_gram.y create mode 100644 internal/reference/pl_reserved_kwlist.h create mode 100644 internal/reference/pl_scanner.c create mode 100644 internal/reference/pl_unreserved_kwlist.h create mode 100644 internal/reference/plerrcodes.h diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 156142c..1ec0d3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,5 +39,5 @@ jobs: go-version-file: go.mod - name: cmd/generate output is committed and current run: | - go run ./cmd/generate -aliases -keywords + go run ./cmd/generate -aliases -keywords -plpgsql git diff --exit-code diff --git a/cmd/generate/main.go b/cmd/generate/main.go index 653056f..37da929 100644 --- a/cmd/generate/main.go +++ b/cmd/generate/main.go @@ -21,10 +21,11 @@ func main() { proto := flag.Bool("proto", false, "regenerate ast/pg_query.pb.go (needs protoc + protoc-gen-go)") aliases := flag.Bool("aliases", false, "regenerate aliases.go") keywords := flag.Bool("keywords", false, "regenerate internal/lexer/keywords.go") + plpgsql := flag.Bool("plpgsql", false, "regenerate internal/plpgsql/tables.go") flag.Parse() - if !*proto && !*aliases && !*keywords { - *aliases, *keywords = true, true + if !*proto && !*aliases && !*keywords && !*plpgsql { + *aliases, *keywords, *plpgsql = true, true, true } if *proto { @@ -47,6 +48,12 @@ func main() { } fmt.Println("wrote internal/lexer/keywords.go") } + if *plpgsql { + if err := generatePlpgsql("internal/reference", "internal/plpgsql/tables.go"); err != nil { + fatal(err) + } + fmt.Println("wrote internal/plpgsql/tables.go") + } } func run(name string, args ...string) { diff --git a/cmd/generate/plpgsql.go b/cmd/generate/plpgsql.go new file mode 100644 index 0000000..77cee46 --- /dev/null +++ b/cmd/generate/plpgsql.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "go/format" + "os" + "regexp" + "sort" + "strings" +) + +// generatePlpgsql emits internal/plpgsql/tables.go from the pinned +// pl_reserved_kwlist.h / pl_unreserved_kwlist.h (keyword → token maps, the +// data pl_scanner.c compiles in) and plerrcodes.h (the exception condition +// name table pl_comp.c's exception_label_map includes; only the name and its +// number of entries matter — dump_condition serializes condname alone, and +// duplicate names produce chains of that length). +func generatePlpgsql(refDir, outPath string) error { + kwRe := regexp.MustCompile(`PG_KEYWORD\("([a-z_]+)",\s*(K_[A-Z_]+)\)`) + readKeywords := func(file string) ([][2]string, error) { + src, err := os.ReadFile(refDir + "/" + file) + if err != nil { + return nil, err + } + var out [][2]string + for _, m := range kwRe.FindAllStringSubmatch(string(src), -1) { + out = append(out, [2]string{m[1], m[2]}) + } + if len(out) == 0 { + return nil, fmt.Errorf("%s: no PG_KEYWORD entries found", file) + } + return out, nil + } + + reserved, err := readKeywords("pl_reserved_kwlist.h") + if err != nil { + return err + } + unreserved, err := readKeywords("pl_unreserved_kwlist.h") + if err != nil { + return err + } + + errSrc, err := os.ReadFile(refDir + "/plerrcodes.h") + if err != nil { + return err + } + condRe := regexp.MustCompile(`"([a-z_]+)",\s*ERRCODE_[A-Z_0-9]+`) + condCount := map[string]int{} + var condOrder []string + for _, m := range condRe.FindAllStringSubmatch(string(errSrc), -1) { + if condCount[m[1]] == 0 { + condOrder = append(condOrder, m[1]) + } + condCount[m[1]]++ + } + if len(condOrder) == 0 { + return fmt.Errorf("plerrcodes.h: no condition entries found") + } + sort.Strings(condOrder) + + var b strings.Builder + b.WriteString("// Code generated by cmd/generate -plpgsql from internal/reference/\n") + b.WriteString("// pl_reserved_kwlist.h, pl_unreserved_kwlist.h, and plerrcodes.h\n") + b.WriteString("// (libpg_query 17-6.2.2). DO NOT EDIT.\n\npackage plpgsql\n\n") + + b.WriteString("// reservedKeywords is pl_reserved_kwlist.h: these are passed to the core\n") + b.WriteString("// scanner's keyword list, so they win over any variable name.\n") + b.WriteString("var reservedKeywords = map[string]plToken{\n") + for _, kw := range reserved { + fmt.Fprintf(&b, "\t%q: %s,\n", kw[0], kw[1]) + } + b.WriteString("}\n\n") + + b.WriteString("// unreservedKeywords is pl_unreserved_kwlist.h: checked only where the\n") + b.WriteString("// grammar wants a keyword and no variable matched.\n") + b.WriteString("var unreservedKeywords = map[string]plToken{\n") + for _, kw := range unreserved { + fmt.Fprintf(&b, "\t%q: %s,\n", kw[0], kw[1]) + } + b.WriteString("}\n\n") + + b.WriteString("// errConditions maps exception condition names to their number of\n") + b.WriteString("// entries in exception_label_map (plpgsql_parse_err_condition returns a\n") + b.WriteString("// chain with one node per entry).\n") + b.WriteString("var errConditions = map[string]int{\n") + for _, name := range condOrder { + fmt.Fprintf(&b, "\t%q: %d,\n", name, condCount[name]) + } + b.WriteString("}\n") + + src, err := format.Source([]byte(b.String())) + if err != nil { + return fmt.Errorf("gofmt plpgsql tables: %w", err) + } + return os.WriteFile(outPath, src, 0o644) +} diff --git a/compat_test.go b/compat_test.go index 39a6057..70193af 100644 --- a/compat_test.go +++ b/compat_test.go @@ -19,24 +19,6 @@ func skipUnlessImplemented(t *testing.T) { } } -// TestNotImplementedErrors pins the milestone-1 API contract: every entry -// point exists with pg_query_go's exact signature and fails loudly (not -// silently) until its milestone lands. -func TestNotImplementedErrors(t *testing.T) { - check := func(name string, err error) { - t.Helper() - if err == nil { - t.Fatalf("%s: expected a not-implemented error, got nil", name) - } - if !strings.Contains(err.Error(), "not implemented") { - t.Fatalf("%s: unexpected error %q", name, err) - } - } - - _, err := pg_query.ParsePlPgSqlToJSON("SELECT 1") - check("ParsePlPgSqlToJSON", err) -} - // TestScanTokens pins one token stream end-to-end through the public Scan // API (pg_query_go's TestScan is a smoke test; the corpus goldens carry the // exhaustive coverage). diff --git a/internal/emit/emit.go b/internal/emit/emit.go index fb55ab4..ffd6168 100644 --- a/internal/emit/emit.go +++ b/internal/emit/emit.go @@ -270,6 +270,11 @@ func emitAConst(b *strings.Builder, m protoreflect.Message) { fmt.Fprintf(b, `,"location":%d`, loc) } +// Token exposes emitToken to the other internal packages that emit the same +// JSON string encoding (the PL/pgSQL dump shares _outToken with this +// emitter via pg_query_json_helper.c). +func Token(b *strings.Builder, s string) { emitToken(b, s) } + // emitToken is _outToken: JSON string quoting with the reference's exact // escape set — \b \f \n \r \t \" \\ as two-character escapes, and \u%04x for // other control bytes plus '<' and '>'. diff --git a/internal/parse/modes.go b/internal/parse/modes.go new file mode 100644 index 0000000..6fd3f75 --- /dev/null +++ b/internal/parse/modes.go @@ -0,0 +1,174 @@ +package parse + +import ( + "fmt" + + "github.com/sqlc-dev/oliphant/ast" + "github.com/sqlc-dev/oliphant/internal/lexer" +) + +// Mode mirrors RawParseMode for the entry points raw_parser exposes beyond +// RAW_PARSE_DEFAULT. The PL/pgSQL compiler's check_sql_expr drives the +// non-default modes; RAW_PARSE_TYPE_NAME has no caller here (libpg_query +// mocks parse_datatype away). +type Mode int + +const ( + ModeDefault Mode = iota + ModeTypeName + ModePlpgsqlExpr + ModePlpgsqlAssign1 + ModePlpgsqlAssign2 + ModePlpgsqlAssign3 +) + +// ParseWithMode is raw_parser: parse_toplevel's MODE_* alternatives, each +// wrapping its result in a RawStmt exactly as the grammar actions do. +func ParseWithMode(input string, mode Mode) (res *ast.ParseResult, err *lexer.Error) { + if mode == ModeDefault { + return Parse(input) + } + s := lexer.New(input) + p := &parser{src: s.Input(), filter: lexer.NewFilter(s)} + defer func() { + if r := recover(); r != nil { + if b, ok := r.(bail); ok { + res, err = nil, b.err + return + } + panic(r) + } + }() + + res = &ast.ParseResult{Version: pgVersionNum} + var stmt *ast.Node + switch mode { + case ModePlpgsqlExpr: + // parse_toplevel: MODE_PLPGSQL_EXPR PLpgSQL_Expr + stmt = p.parsePLpgSQLExpr() + case ModePlpgsqlAssign1, ModePlpgsqlAssign2, ModePlpgsqlAssign3: + // parse_toplevel: MODE_PLPGSQL_ASSIGNn PLAssignStmt + nnames := int32(1 + int(mode-ModePlpgsqlAssign1)) + stmt = p.parsePLAssignStmt(nnames) + default: + panic(fmt.Sprintf("parse mode %d not supported", mode)) + } + + // The mode productions cover the whole input; anything left over is a + // syntax error at that token, as in bison. + if tok := p.peek(); tok.Kind != 0 { + p.syntaxError(tok) + } + + res.Stmts = []*ast.RawStmt{{Stmt: stmt, StmtLocation: 0}} + return res, nil +} + +// parsePLpgSQLExpr is gram.y's PLpgSQL_Expr: everything that can follow +// SELECT, without the SELECT keyword; the result is a SelectStmt. +func (p *parser) parsePLpgSQLExpr() *ast.Node { + n := &ast.SelectStmt{ + LimitOption: ast.LimitOption_LIMIT_OPTION_DEFAULT, + Op: ast.SetOperation_SETOP_NONE, + } + + // opt_distinct_clause: distinct_clause | opt_all_clause + requireTargets := false + switch p.kind() { + case ast.Token_ALL: + p.next() + case ast.Token_DISTINCT: + p.next() + if p.have(ast.Token_ON) { + p.expect(ast.Token('(')) + n.DistinctClause = p.parseExprList() + p.expect(ast.Token(')')) + } else { + // DISTINCT: list_make1(NIL) — a single empty-list placeholder. + n.DistinctClause = []*ast.Node{{}} + } + requireTargets = true + } + + // opt_target_list + if requireTargets || p.startsTargetEl() { + n.TargetList = p.parseTargetList() + } + // from_clause + if p.have(ast.Token_FROM) { + n.FromClause = p.parseFromList() + } + // where_clause + if p.have(ast.Token_WHERE) { + n.WhereClause = p.parseAExpr(0) + } + // group_clause + if p.kind() == ast.Token_GROUP_P { + p.next() + p.expect(ast.Token_BY) + if p.have(ast.Token_ALL) { + } else if p.have(ast.Token_DISTINCT) { + n.GroupDistinct = true + } + n.GroupClause = p.parseGroupByList() + } + // having_clause + if p.have(ast.Token_HAVING) { + n.HavingClause = p.parseAExpr(0) + } + // window_clause + if p.have(ast.Token_WINDOW) { + n.WindowClause = p.parseWindowDefinitionList() + } + // opt_sort_clause + if p.kind() == ast.Token_ORDER { + n.SortClause = p.parseSortClauseKeyword() + } + // opt_select_limit + if p.kind() == ast.Token_LIMIT || p.kind() == ast.Token_OFFSET || + p.kind() == ast.Token_FETCH { + limit := p.parseSelectLimit() + n.LimitOffset = limit.limitOffset + n.LimitCount = limit.limitCount + if n.SortClause == nil && limit.limitOption == ast.LimitOption_LIMIT_OPTION_WITH_TIES { + p.ereport("base_yyparse", "WITH TIES cannot be specified without ORDER BY clause", -1) + } + n.LimitOption = limit.limitOption + } + // opt_for_locking_clause + for p.kind() == ast.Token_FOR { + n.LockingClause = append(n.LockingClause, p.parseForLockingClause()...) + } + + return nSelectStmt(n) +} + +// parsePLAssignStmt is gram.y's PLAssignStmt: +// plassign_target opt_indirection plassign_equals PLpgSQL_Expr. +func (p *parser) parsePLAssignStmt(nnames int32) *ast.Node { + n := &ast.PLAssignStmt{Nnames: nnames} + + // plassign_target: ColId | PARAM + tok := p.peek() + n.Location = tok.Start + if tok.Kind == ast.Token_PARAM { + p.next() + n.Name = fmt.Sprintf("$%d", tok.Ival) + } else { + n.Name = p.colId() + } + + n.Indirection = p.check_indirection(p.parseOptIndirection()) + + // plassign_equals: COLON_EQUALS | '=' + tok = p.peek() + if tok.Kind != ast.Token_COLON_EQUALS && tok.Kind != ast.Token('=') { + p.syntaxError(tok) + } + p.next() + + val := p.parsePLpgSQLExpr() + n.Val = val.GetSelectStmt() + + return &ast.Node{Node: &ast.Node_PlassignStmt{PlassignStmt: n}} +} diff --git a/internal/plpgsql/ast.go b/internal/plpgsql/ast.go new file mode 100644 index 0000000..f3d751c --- /dev/null +++ b/internal/plpgsql/ast.go @@ -0,0 +1,533 @@ +// Package plpgsql is the hand-written port of libpg_query's PL/pgSQL support +// as pinned at 17-6.2.2: pl_gram.y + pl_scanner.c (patched, see +// internal/reference/), the pl_comp.c / pl_funcs.c subset libpg_query +// extracts (including its mocks — parse_datatype and friends do not consult +// the catalogs), pg_query_json_plpgsql.c, and the pg_query_parse_plpgsql.c +// driver behind ParsePlPgSqlToJSON. +package plpgsql + +// The execution-tree node structs mirror plpgsql.h field-for-field, limited +// to what the parser fills in and the JSON dump reads. + +// plpgsql.h: PLpgSQL_datum_type +type datumType int + +const ( + dtypeVar datumType = iota + dtypeRow + dtypeRec + dtypeRecfield + dtypePromise +) + +// plpgsql.h: PLpgSQL_type_type +type typeType int + +const ( + ttypeScalar typeType = iota + ttypeRec + ttypePseudo +) + +// plpgsql.h: PLpgSQL_nsitem_type / PLpgSQL_label_type +type nsItemType int + +const ( + nsTypeLabel nsItemType = iota + nsTypeVar + nsTypeRec +) + +type labelType int + +const ( + labelBlock labelType = iota + labelLoop + labelOther +) + +// plpgsql.h: PLpgSQL_getdiag_kind +type getdiagKind int + +const ( + getdiagRowCount getdiagKind = iota + getdiagRoutineOid + getdiagContext + getdiagErrorContext + getdiagErrorDetail + getdiagErrorHint + getdiagReturnedSqlstate + getdiagColumnName + getdiagConstraintName + getdiagDatatypeName + getdiagMessageText + getdiagTableName + getdiagSchemaName +) + +// pl_funcs.c: plpgsql_getdiag_kindname +func getdiagKindname(kind getdiagKind) string { + switch kind { + case getdiagRowCount: + return "ROW_COUNT" + case getdiagRoutineOid: + return "PG_ROUTINE_OID" + case getdiagContext: + return "PG_CONTEXT" + case getdiagErrorContext: + return "PG_EXCEPTION_CONTEXT" + case getdiagErrorDetail: + return "PG_EXCEPTION_DETAIL" + case getdiagErrorHint: + return "PG_EXCEPTION_HINT" + case getdiagReturnedSqlstate: + return "RETURNED_SQLSTATE" + case getdiagColumnName: + return "COLUMN_NAME" + case getdiagConstraintName: + return "CONSTRAINT_NAME" + case getdiagDatatypeName: + return "PG_DATATYPE_NAME" + case getdiagMessageText: + return "MESSAGE_TEXT" + case getdiagTableName: + return "TABLE_NAME" + case getdiagSchemaName: + return "SCHEMA_NAME" + } + return "unknown" +} + +// plpgsql.h: PLpgSQL_raise_option_type +type raiseOptionType int + +const ( + raiseOptionErrcode raiseOptionType = iota + raiseOptionMessage + raiseOptionDetail + raiseOptionHint + raiseOptionColumn + raiseOptionConstraint + raiseOptionDatatype + raiseOptionTable + raiseOptionSchema +) + +// utils/elog.h severity levels (the subset RAISE uses). +const ( + elogDebug1 = 14 + elogLog = 15 + elogInfo = 17 + elogNotice = 18 + elogWarning = 19 + elogError = 21 +) + +// nodes/parsenodes.h: cursor options and FETCH_ALL +const ( + cursorOptScroll = 0x0002 + cursorOptNoScroll = 0x0004 + cursorOptFastPlan = 0x0100 + + fetchAll = int64(^uint64(0) >> 1) // FETCH_ALL = LONG_MAX +) + +// nodes/parsenodes.h: FetchDirection +type fetchDirection int + +const ( + fetchForward fetchDirection = iota + fetchBackward + fetchAbsolute + fetchRelative +) + +// nodes/parsenodes.h: RawParseMode +type rawParseMode int + +const ( + rawParseDefault rawParseMode = iota + rawParseTypeName + rawParsePlpgsqlExpr + rawParsePlpgsqlAssign1 + rawParsePlpgsqlAssign2 + rawParsePlpgsqlAssign3 +) + +// plpgsql.h: PLpgSQL_resolve_option +type resolveOption int + +const ( + resolveError resolveOption = iota + resolveVariable + resolveColumn +) + +// --- datums ------------------------------------------------------------------ + +// datum is the common interface of PLpgSQL_datum structs (dno + dtype). +type datum interface { + datumNo() int + setDatumNo(int) + datumType() datumType +} + +type datumCommon struct { + dno int +} + +func (d *datumCommon) datumNo() int { return d.dno } +func (d *datumCommon) setDatumNo(n int) { d.dno = n } + +// plType is PLpgSQL_type (the fields the libpg_query build fills). +type plType struct { + typname string // patched in: the source spelling (or quoted qualified name) + ttype typeType + typoid uint32 // only refcursor/text/bool/int4 distinctions matter + atttypmod int32 + collation uint32 + typisarray bool +} + +// plVar is PLpgSQL_var. +type plVar struct { + datumCommon + refname string + lineno int + datatype *plType + isconst bool + notnull bool + + defaultVal *plExpr + cursorExplicitExpr *plExpr + cursorExplicitArgrow int + cursorOptions int +} + +func (*plVar) datumType() datumType { return dtypeVar } + +// plRow is PLpgSQL_row. +type plRow struct { + datumCommon + refname string + lineno int + fieldnames []string + varnos []int +} + +func (*plRow) datumType() datumType { return dtypeRow } + +// plRec is PLpgSQL_rec. +type plRec struct { + datumCommon + refname string + lineno int + datatype *plType + rectypeid uint32 + firstfield int +} + +func (*plRec) datumType() datumType { return dtypeRec } + +// plRecfield is PLpgSQL_recfield. +type plRecfield struct { + datumCommon + fieldname string + recparentno int + nextfield int +} + +func (*plRecfield) datumType() datumType { return dtypeRecfield } + +// variable() reports whether a datum is a PLpgSQL_variable (var/row/rec) and +// gives access to the shared header fields. +type plVariable interface { + datum + varRefname() string + varIsConst() bool +} + +func (v *plVar) varRefname() string { return v.refname } +func (v *plVar) varIsConst() bool { return v.isconst } +func (r *plRow) varRefname() string { return r.refname } +func (r *plRow) varIsConst() bool { return false } +func (r *plRec) varRefname() string { return r.refname } +func (r *plRec) varIsConst() bool { return false } + +// plExpr is PLpgSQL_expr. +type plExpr struct { + query string + parseMode rawParseMode +} + +// --- statements -------------------------------------------------------------- + +type plStmt interface{ stmtLineno() int } + +type stmtCommon struct { + lineno int +} + +func (s *stmtCommon) stmtLineno() int { return s.lineno } + +type stmtBlock struct { + stmtCommon + label string + body []plStmt + initVarnos []int // n_initvars/initvarnos (not serialized) + exceptions *exceptionBlock +} + +type exceptionBlock struct { + sqlstateVarno int + sqlerrmVarno int + excList []*plException +} + +type plException struct { + lineno int + conditions *plCondition + action []plStmt +} + +type plCondition struct { + sqlerrstate int + condname string + next *plCondition +} + +type stmtAssign struct { + stmtCommon + varno int + expr *plExpr +} + +type stmtIf struct { + stmtCommon + cond *plExpr + thenBody []plStmt + elsifList []*ifElsif + elseBody []plStmt +} + +type ifElsif struct { + lineno int + cond *plExpr + stmts []plStmt +} + +type stmtCase struct { + stmtCommon + tExpr *plExpr + tVarno int + caseWhenList []*caseWhen + haveElse bool + elseStmts []plStmt +} + +type caseWhen struct { + lineno int + expr *plExpr + stmts []plStmt +} + +type stmtLoop struct { + stmtCommon + label string + body []plStmt +} + +type stmtWhile struct { + stmtCommon + label string + cond *plExpr + body []plStmt +} + +type stmtFori struct { + stmtCommon + label string + varDat *plVar + lower *plExpr + upper *plExpr + step *plExpr + reverse bool + body []plStmt +} + +type stmtFors struct { + stmtCommon + label string + varDat plVariable + body []plStmt + query *plExpr +} + +type stmtForc struct { + stmtCommon + label string + varDat plVariable + body []plStmt + curvar int + argquery *plExpr +} + +type stmtDynfors struct { + stmtCommon + label string + varDat plVariable + body []plStmt + query *plExpr + params []*plExpr +} + +type stmtForeachA struct { + stmtCommon + label string + varno int + slice int + expr *plExpr + body []plStmt +} + +type stmtExit struct { + stmtCommon + isExit bool + label string + cond *plExpr +} + +type stmtReturn struct { + stmtCommon + expr *plExpr + retvarno int +} + +type stmtReturnNext struct { + stmtCommon + expr *plExpr + retvarno int +} + +type stmtReturnQuery struct { + stmtCommon + query *plExpr + dynquery *plExpr + params []*plExpr +} + +type stmtRaise struct { + stmtCommon + elogLevel int + condname string + message string + hasMessage bool + params []*plExpr + options []*raiseOption +} + +type raiseOption struct { + optType raiseOptionType + expr *plExpr +} + +type stmtAssert struct { + stmtCommon + cond *plExpr + message *plExpr +} + +type stmtExecsql struct { + stmtCommon + sqlstmt *plExpr + into bool + strict bool + target plVariable +} + +type stmtDynexecute struct { + stmtCommon + query *plExpr + into bool + strict bool + target plVariable + params []*plExpr +} + +type stmtGetdiag struct { + stmtCommon + isStacked bool + diagItems []*diagItem +} + +type diagItem struct { + kind getdiagKind + target int +} + +type stmtOpen struct { + stmtCommon + curvar int + cursorOptions int + argquery *plExpr + query *plExpr + dynquery *plExpr + params []*plExpr +} + +type stmtFetch struct { + stmtCommon + target plVariable + curvar int + direction fetchDirection + howMany int64 + expr *plExpr + isMove bool + returnsMultipleRows bool +} + +type stmtClose struct { + stmtCommon + curvar int +} + +type stmtPerform struct { + stmtCommon + expr *plExpr +} + +type stmtCall struct { + stmtCommon + expr *plExpr + isCall bool + target plVariable +} + +type stmtCommit struct { + stmtCommon + chain bool +} + +type stmtRollback struct { + stmtCommon + chain bool +} + +// plFunction is PLpgSQL_function (the serialized subset). +type plFunction struct { + fnSignature string + fnRetset bool + fnIsProc bool // PROKIND_PROCEDURE (unused: driver always compiles as FUNCTION) + + newVarno int + oldVarno int + foundVarno int + outParamVarno int + + datums []datum + action *stmtBlock + nstatements uint32 + + printStrictParams bool + resolveOption resolveOption +} diff --git a/internal/plpgsql/comp.go b/internal/plpgsql/comp.go new file mode 100644 index 0000000..2ef0048 --- /dev/null +++ b/internal/plpgsql/comp.go @@ -0,0 +1,461 @@ +package plpgsql + +import ( + "github.com/sqlc-dev/oliphant/ast" + "github.com/sqlc-dev/oliphant/internal/deparse" +) + +// compileError carries an ereport out of the compile (message and the C +// error-data fields the golden format serializes). Context is attached at +// the catch site by the compile error callback logic. +type compileError struct { + Message string + Filename string + Funcname string + Cursorpos int + Context string +} + +func (e *compileError) Error() string { return e.Message } + +// Filenames as __FILE__ expands in the vendored libpg_query build. +const ( + plGramFilename = "pl_gram.y" + plCompFilename = "src_pl_plpgsql_src_pl_comp.c" +) + +// pg_type.h OIDs (the ones the stripped pl_comp build distinguishes). +const ( + oidBool = 16 + oidInt4 = 23 + oidText = 25 + oidUnknown = 705 + oidRefcursor = 1790 + oidRecord = 2249 + oidVoid = 2278 + + oidDefaultCollation = 100 +) + +// compiler bundles the per-compile globals of pl_comp.c / pl_scanner.c. +type compiler struct { + scan *plScanner + + fn *plFunction + + nsTop *nsItem + + datums []datum // plpgsql_Datums + datumsLast int // datums_last + + checkSyntax bool // plpgsql_check_syntax (always true here) + errFuncname string // plpgsql_error_funcname + nDatums int // plpgsql_nDatums (== len(datums)) +} + +// --- namespace (pl_funcs.c) -------------------------------------------------- + +type nsItem struct { + itemtype nsItemType + itemno int + prev *nsItem + name string +} + +// nsInit is plpgsql_ns_init. +func (c *compiler) nsInit() { c.nsTop = nil } + +// nsPush is plpgsql_ns_push. +func (c *compiler) nsPush(label string, labelType labelType) { + c.nsAdditem(nsTypeLabel, int(labelType), label) +} + +// nsPop is plpgsql_ns_pop. +func (c *compiler) nsPop() { + for c.nsTop.itemtype != nsTypeLabel { + c.nsTop = c.nsTop.prev + } + c.nsTop = c.nsTop.prev +} + +// nsAdditem is plpgsql_ns_additem. +func (c *compiler) nsAdditem(itemtype nsItemType, itemno int, name string) { + c.nsTop = &nsItem{itemtype: itemtype, itemno: itemno, prev: c.nsTop, name: name} +} + +// nsLookup is plpgsql_ns_lookup. name2/name3 empty mean NULL. +func (c *compiler) nsLookup(nsCur *nsItem, localmode bool, name1, name2, name3 string) (*nsItem, int) { + for nsCur != nil { + var nsitem *nsItem + + // Check this level for unqualified match to variable name + for nsitem = nsCur; nsitem.itemtype != nsTypeLabel; nsitem = nsitem.prev { + if nsitem.name == name1 { + if name2 == "" || nsitem.itemtype != nsTypeVar { + return nsitem, 1 + } + } + } + + // Check this level for qualified match to variable name + if name2 != "" && nsitem.name == name1 { + for inner := nsCur; inner.itemtype != nsTypeLabel; inner = inner.prev { + if inner.name == name2 { + if name3 == "" || inner.itemtype != nsTypeVar { + return inner, 2 + } + } + } + } + + if localmode { + break // do not look into upper levels + } + nsCur = nsitem.prev + } + return nil, 0 +} + +// nsLookupLabel is plpgsql_ns_lookup_label. +func (c *compiler) nsLookupLabel(nsCur *nsItem, name string) *nsItem { + for ; nsCur != nil; nsCur = nsCur.prev { + if nsCur.itemtype == nsTypeLabel && nsCur.name == name { + return nsCur + } + } + return nil +} + +// nsFindNearestLoop is plpgsql_ns_find_nearest_loop. +func (c *compiler) nsFindNearestLoop(nsCur *nsItem) *nsItem { + for ; nsCur != nil; nsCur = nsCur.prev { + if nsCur.itemtype == nsTypeLabel && nsCur.itemno == int(labelLoop) { + return nsCur + } + } + return nil +} + +// --- datums ------------------------------------------------------------------ + +// startDatums is plpgsql_start_datums. +func (c *compiler) startDatums() { + c.datums = nil + c.datumsLast = 0 +} + +// addDatum is plpgsql_adddatum. +func (c *compiler) addDatum(d datum) { + d.setDatumNo(len(c.datums)) + c.datums = append(c.datums, d) +} + +// finishDatums is plpgsql_finish_datums. +func (c *compiler) finishDatums() { + c.fn.datums = append([]datum(nil), c.datums...) +} + +// addInitdatums is plpgsql_add_initdatums; varnos == nil forgets. +func (c *compiler) addInitdatums(collect bool) []int { + var varnos []int + for i := c.datumsLast; i < len(c.datums); i++ { + switch c.datums[i].datumType() { + case dtypeVar, dtypeRec: + if collect { + varnos = append(varnos, c.datums[i].datumNo()) + } + } + } + c.datumsLast = len(c.datums) + return varnos +} + +// --- variable building ------------------------------------------------------- + +// buildVariable is plpgsql_build_variable. +func (c *compiler) buildVariable(refname string, lineno int, dtype *plType, add2namespace bool) plVariable { + switch dtype.ttype { + case ttypeScalar: + v := &plVar{ + refname: refname, + lineno: lineno, + datatype: dtype, + cursorExplicitArgrow: 0, + } + c.addDatum(v) + if add2namespace { + c.nsAdditem(nsTypeVar, v.dno, refname) + } + return v + case ttypeRec: + return c.buildRecord(refname, lineno, dtype, dtype.typoid, add2namespace) + case ttypePseudo: + // format_type_be is mocked to "-" in the vendored build. + panic(&compileError{ + Message: `variable "` + refname + `" has pseudo-type -`, + Filename: plCompFilename, + Funcname: "plpgsql_build_variable", + }) + } + return nil +} + +// buildRecord is plpgsql_build_record. +func (c *compiler) buildRecord(refname string, lineno int, dtype *plType, rectypeid uint32, add2namespace bool) *plRec { + rec := &plRec{ + refname: refname, + lineno: lineno, + datatype: dtype, + rectypeid: rectypeid, + firstfield: -1, + } + c.addDatum(rec) + if add2namespace { + c.nsAdditem(nsTypeRec, rec.dno, rec.refname) + } + return rec +} + +// buildRecfield is plpgsql_build_recfield. +func (c *compiler) buildRecfield(rec *plRec, fldname string) *plRecfield { + for i := rec.firstfield; i >= 0; { + fld := c.datums[i].(*plRecfield) + if fld.fieldname == fldname { + return fld + } + i = fld.nextfield + } + recfield := &plRecfield{ + fieldname: fldname, + recparentno: rec.dno, + } + c.addDatum(recfield) + recfield.nextfield = rec.firstfield + rec.firstfield = recfield.dno + return recfield +} + +// buildDatatype is the vendored plpgsql_build_datatype mock: no catalog +// access; the type name comes from the parsed TypeName (or the handful of +// hardwired OIDs). +func buildDatatype(typeOid uint32, typmod int32, collation uint32, origtypname *ast.TypeName) *plType { + typ := &plType{ + ttype: ttypeScalar, + atttypmod: typmod, + collation: collation, + } + var ident, ns string + if origtypname != nil { + typ.typoid = uint32(origtypname.TypeOid) + switch len(origtypname.Names) { + case 1: + ident = origtypname.Names[0].GetString_().GetSval() + case 2: + ns = origtypname.Names[0].GetString_().GetSval() + ident = origtypname.Names[1].GetString_().GetSval() + if ns != "pg_catalog" { + typ.ttype = ttypeRec + } + } + } else { + typ.typoid = typeOid + ns = "pg_catalog" + switch typeOid { + case oidBool: + ident = "boolean" + case oidInt4: + ident = "integer" + case oidText: + ident = "text" + case oidRefcursor: + ident = "refcursor" + } + } + if ident != "" { + typ.typname = quoteQualifiedIdentifier(ns, ident) + } + return typ +} + +// buildDatatypeArrayof is the vendored plpgsql_build_datatype_arrayof mock. +func buildDatatypeArrayof(dtype *plType) *plType { + if dtype.typisarray { + return dtype + } + arr := &plType{ + ttype: ttypeRec, + atttypmod: dtype.atttypmod, + collation: dtype.collation, + typisarray: true, + } + switch dtype.typoid { + case oidBool: + arr.typname = "boolean[]" + case oidInt4: + arr.typname = "integer[]" + case oidText: + arr.typname = "text[]" + default: + arr.typname = "UNKNOWN" + } + arr.typoid = dtype.typoid + return arr +} + +// quoteQualifiedIdentifier is ruleutils.c's quote_qualified_identifier. +func quoteQualifiedIdentifier(qualifier, ident string) string { + if qualifier != "" { + return deparse.QuoteIdentifier(qualifier) + "." + deparse.QuoteIdentifier(ident) + } + return deparse.QuoteIdentifier(ident) +} + +// --- word lookup (pl_comp.c) ------------------------------------------------- + +// parseWord is plpgsql_parse_word. +func (c *compiler) parseWord(word1 string, quoted bool, lookup bool, wdatum *plWdatum, word *plWord) bool { + if lookup && c.scan.identifierLookup == lookupNormal { + if ns, _ := c.nsLookup(c.nsTop, false, word1, "", ""); ns != nil { + switch ns.itemtype { + case nsTypeVar, nsTypeRec: + wdatum.datum = c.datums[ns.itemno] + wdatum.ident = word1 + wdatum.quoted = quoted + wdatum.idents = nil + return true + } + } + } + word.ident = word1 + word.quoted = quoted + return false +} + +// parseDblword is plpgsql_parse_dblword. +func (c *compiler) parseDblword(word1, word2 string, wdatum *plWdatum, cword *[]string) bool { + idents := []string{word1, word2} + if c.scan.identifierLookup != lookupDeclare { + ns, nnames := c.nsLookup(c.nsTop, false, word1, word2, "") + if ns != nil { + switch ns.itemtype { + case nsTypeVar: + // Block-qualified reference to scalar variable. + wdatum.datum = c.datums[ns.itemno] + wdatum.ident = "" + wdatum.quoted = false + wdatum.idents = idents + return true + case nsTypeRec: + if nnames == 1 { + // First word is a record name; second could be a field. + rec := c.datums[ns.itemno].(*plRec) + wdatum.datum = c.buildRecfield(rec, word2) + } else { + // Block-qualified reference to record variable. + wdatum.datum = c.datums[ns.itemno] + } + wdatum.ident = "" + wdatum.quoted = false + wdatum.idents = idents + return true + } + } + } + *cword = idents + return false +} + +// parseTripword is plpgsql_parse_tripword. +func (c *compiler) parseTripword(word1, word2, word3 string, wdatum *plWdatum, cword *[]string) bool { + if c.scan.identifierLookup != lookupDeclare { + ns, nnames := c.nsLookup(c.nsTop, false, word1, word2, word3) + if ns != nil && ns.itemtype == nsTypeRec { + rec := c.datums[ns.itemno].(*plRec) + var idents []string + var fld *plRecfield + if nnames == 1 { + fld = c.buildRecfield(rec, word2) + idents = []string{word1, word2} + } else { + fld = c.buildRecfield(rec, word3) + idents = []string{word1, word2, word3} + } + wdatum.datum = fld + wdatum.ident = "" + wdatum.quoted = false + wdatum.idents = idents + return true + } + } + *cword = []string{word1, word2, word3} + return false +} + +// %TYPE / %ROWTYPE lookups are mocked to NULL in the vendored build. +func (c *compiler) parseWordType(string) *plType { return nil } +func (c *compiler) parseWordRowType(string) *plType { return nil } +func (c *compiler) parseCwordType([]string) *plType { return nil } +func (c *compiler) parseCwordRowType([]string) *plType { + return nil +} + +// --- exception conditions ---------------------------------------------------- + +// recognizeErrCondition is plpgsql_recognize_err_condition (the returned +// SQLSTATE value is never serialized, so only validity matters). +func recognizeErrCondition(condname string, allowSqlstate bool) { + if allowSqlstate && len(condname) == 5 && isSqlstate(condname) { + return + } + if errConditions[condname] > 0 { + return + } + panic(&compileError{ + Message: `unrecognized exception condition "` + condname + `"`, + Filename: plCompFilename, + Funcname: "plpgsql_recognize_err_condition", + }) +} + +// parseErrCondition is plpgsql_parse_err_condition: one chain node per +// exception_label_map entry with the name (duplicates produce chains). +func parseErrCondition(condname string) *plCondition { + if condname == "others" { + return &plCondition{condname: condname} + } + n := errConditions[condname] + if n == 0 { + panic(&compileError{ + Message: `unrecognized exception condition "` + condname + `"`, + Filename: plCompFilename, + Funcname: "plpgsql_parse_err_condition", + }) + } + var prev *plCondition + for i := 0; i < n; i++ { + prev = &plCondition{condname: condname, next: prev} + } + return prev +} + +func isSqlstate(s string) bool { + for i := 0; i < len(s); i++ { + c := s[i] + if !(c >= '0' && c <= '9' || c >= 'A' && c <= 'Z') { + return false + } + } + return true +} + +// nameListToString is NameListToString over plain identifier lists. +func nameListToString(names []string) string { + out := "" + for i, n := range names { + if i > 0 { + out += "." + } + out += n + } + return out +} diff --git a/internal/plpgsql/entry.go b/internal/plpgsql/entry.go new file mode 100644 index 0000000..d347bc2 --- /dev/null +++ b/internal/plpgsql/entry.go @@ -0,0 +1,329 @@ +package plpgsql + +import ( + "fmt" + "strings" + + "github.com/sqlc-dev/oliphant/ast" + "github.com/sqlc-dev/oliphant/internal/parse" + "github.com/sqlc-dev/oliphant/internal/rawwalk" +) + +// Error is the public error shape of a PL/pgSQL parse or compile failure. +type Error struct { + Message string + Filename string + Funcname string + Cursorpos int + Context string +} + +func (e *Error) Error() string { return e.Message } + +// ParseToJSON is pg_query_parse_plpgsql: parse the whole input with the SQL +// parser, collect CREATE FUNCTION/PROCEDURE and DO statements, compile each +// with the PL/pgSQL parser, and emit the JSON array of function dumps. +func ParseToJSON(input string) (string, *Error) { + tree, perr := parse.Parse(input) + if perr != nil { + return "", &Error{ + Message: perr.Message, + Filename: perr.Filename, + Funcname: perr.Funcname, + Cursorpos: perr.Cursorpos, + } + } + + // stmts_walker: collect CreateFunctionStmt and DoStmt nodes. + var stmts []any + var walk func(item any) bool + walk = func(item any) bool { + c := rawwalk.Concrete(item) + if rawwalk.IsNil(c) { + return false + } + switch v := c.(type) { + case *ast.CreateFunctionStmt: + stmts = append(stmts, v) + case *ast.DoStmt: + stmts = append(stmts, v) + case *ast.RawStmt: + return walk(v.Stmt) + } + return rawwalk.WalkChildren(item, walk) + } + if len(tree.Stmts) > 0 { + walk(rawwalk.RawStmtList(tree.Stmts)) + } + + if len(stmts) == 0 { + return "[]", nil + } + + var out strings.Builder + out.WriteString("[\n") + for _, stmt := range stmts { + fn, cerr := rawParsePlpgsql(stmt) + if cerr != nil { + return "", cerr + } + out.WriteString(toJSON(fn)) + out.WriteString(",\n") + } + // Replace the trailing ",\n" with "\n]". + s := out.String() + return s[:len(s)-2] + "\n]", nil +} + +// rawParsePlpgsql is pg_query_raw_parse_plpgsql: compile one statement, +// catching ereports and decorating them with the compile error context +// (function_parse_error_transpose is mocked to false in this build, so the +// "near line N" context is always used). +func rawParsePlpgsql(stmt any) (fn *plFunction, outErr *Error) { + c := &compiler{checkSyntax: true} + + defer func() { + if r := recover(); r != nil { + ce, ok := r.(*compileError) + if !ok { + panic(r) + } + e := &Error{ + Message: ce.Message, + Filename: ce.Filename, + Funcname: ce.Funcname, + Cursorpos: ce.Cursorpos, + } + // plpgsql_compile_error_callback. + if c.errFuncname != "" { + lineno := 0 + if c.scan != nil { + lineno = c.scan.latestLineno() + } + e.Context = fmt.Sprintf("compilation of PL/pgSQL function \"%s\" near line %d", + c.errFuncname, lineno) + } + fn, outErr = nil, e + } + }() + + switch v := stmt.(type) { + case *ast.CreateFunctionStmt: + return c.compileCreateFunctionStmt(v), nil + case *ast.DoStmt: + return c.compileDoStmt(v), nil + } + return nil, nil +} + +// compileDoStmt is compile_do_stmt. +func (c *compiler) compileDoStmt(stmt *ast.DoStmt) *plFunction { + procSource := "" + haveSource := false + language := "plpgsql" + for _, arg := range stmt.Args { + elem := arg.GetDefElem() + if elem == nil { + continue + } + switch elem.Defname { + case "as": + procSource = elem.Arg.GetString_().GetSval() + haveSource = true + case "language": + language = elem.Arg.GetString_().GetSval() + } + } + _ = haveSource + + if language != "plpgsql" { + return &plFunction{} + } + return c.compileInline(procSource) +} + +// compileInline is plpgsql_compile_inline (pl_comp.c). +func (c *compiler) compileInline(procSource string) *plFunction { + funcName := "inline_code_block" + + c.scan = newScanner(procSource, c) + c.errFuncname = funcName + + // Do extra syntax checking if check_function_bodies is on (it is). + c.checkSyntax = true + + fn := &plFunction{ + fnSignature: funcName, + outParamVarno: -1, + resolveOption: resolveError, + } + c.fn = fn + + c.nsInit() + c.nsPush(funcName, labelBlock) + c.startDatums() + + // Set up as though in a function returning VOID. + fn.fnRetset = false + + // Create the magic FOUND variable. + v := c.buildVariable("found", 0, buildDatatype(oidBool, -1, 0, nil), true) + fn.foundVarno = v.datumNo() + + // Now parse the function's text. + fn.action = c.parseFunction() + + // If it returns VOID (always true at the moment), we allow control to + // fall off the end without an explicit RETURN statement. + c.addDummyReturnInline() + + c.finishDatums() + c.errFuncname = "" + return fn +} + +// addDummyReturnInline is pl_comp.c's add_dummy_return (checks label as well +// as exceptions when deciding to wrap the outer block). +func (c *compiler) addDummyReturnInline() { + fn := c.fn + if fn.action.exceptions != nil || fn.action.label != "" { + wrap := &stmtBlock{body: []plStmt{fn.action}} + fn.action = wrap + } + c.appendDummyReturn() +} + +// addDummyReturnDriver is pg_query_parse_plpgsql.c's local add_dummy_return +// (only the EXCEPTION clause forces the wrapper block). +func (c *compiler) addDummyReturnDriver() { + fn := c.fn + if fn.action.exceptions != nil { + wrap := &stmtBlock{body: []plStmt{fn.action}} + fn.action = wrap + } + c.appendDummyReturn() +} + +func (c *compiler) appendDummyReturn() { + fn := c.fn + body := fn.action.body + needReturn := len(body) == 0 + if !needReturn { + _, isReturn := body[len(body)-1].(*stmtReturn) + needReturn = !isReturn + } + if needReturn { + fn.action.body = append(fn.action.body, &stmtReturn{retvarno: fn.outParamVarno}) + } +} + +// compileCreateFunctionStmt is pg_query_parse_plpgsql.c's +// compile_create_function_stmt. +func (c *compiler) compileCreateFunctionStmt(stmt *ast.CreateFunctionStmt) *plFunction { + funcName := "" + if len(stmt.Funcname) > 0 { + funcName = stmt.Funcname[0].GetString_().GetSval() + } + + procSource := "" + language := "plpgsql" + for _, opt := range stmt.Options { + elem := opt.GetDefElem() + if elem == nil { + continue + } + switch elem.Defname { + case "as": + for _, item := range elem.Arg.GetList().GetItems() { + procSource = item.GetString_().GetSval() + } + case "language": + language = elem.Arg.GetString_().GetSval() + } + } + + if language != "plpgsql" { + return &plFunction{} + } + + isTrigger := false + isSetof := false + if stmt.ReturnType != nil { + for _, n := range stmt.ReturnType.Names { + if n.GetString_().GetSval() == "trigger" { + isTrigger = true + } + } + if stmt.ReturnType.Setof { + isSetof = true + } + } + + c.scan = newScanner(procSource, c) + c.errFuncname = funcName + c.checkSyntax = true + + fn := &plFunction{ + fnSignature: funcName, + outParamVarno: -1, + resolveOption: resolveError, + } + c.fn = fn + + c.nsInit() + c.nsPush(funcName, labelBlock) + c.startDatums() + + // Setup parameter names. + for i, p := range stmt.Parameters { + param := p.GetFunctionParameter() + if param == nil { + continue + } + buf := fmt.Sprintf("$%d", i+1) + argdtype := buildDatatype(oidUnknown, -1, 0, param.ArgType) + name := param.Name + if name == "" { + name = buf + } + argvariable := c.buildVariable(name, 0, argdtype, false) + if param.Mode == ast.FunctionParameterMode_FUNC_PARAM_OUT || + param.Mode == ast.FunctionParameterMode_FUNC_PARAM_INOUT || + param.Mode == ast.FunctionParameterMode_FUNC_PARAM_TABLE { + fn.outParamVarno = argvariable.datumNo() + } + argitemtype := nsTypeVar + if argvariable.datumType() != dtypeVar { + argitemtype = nsTypeRec + } + c.nsAdditem(argitemtype, argvariable.datumNo(), buf) + if param.Name != "" { + c.nsAdditem(argitemtype, argvariable.datumNo(), param.Name) + } + } + + // Set up as though in a function returning VOID. + fn.fnRetset = isSetof + + // Create the magic FOUND variable. + v := c.buildVariable("found", 0, buildDatatype(oidBool, -1, 0, nil), true) + fn.foundVarno = v.datumNo() + + if isTrigger { + // Add the records for referencing NEW and OLD. + rec := c.buildRecord("new", 0, nil, oidRecord, true) + fn.newVarno = rec.dno + rec = c.buildRecord("old", 0, nil, oidRecord, true) + fn.oldVarno = rec.dno + } + + // Now parse the function's text. + fn.action = c.parseFunction() + + // Allow control to fall off the end without an explicit RETURN. + c.addDummyReturnDriver() + + c.finishDatums() + c.errFuncname = "" + return fn +} diff --git a/internal/plpgsql/gram.go b/internal/plpgsql/gram.go new file mode 100644 index 0000000..d286c85 --- /dev/null +++ b/internal/plpgsql/gram.go @@ -0,0 +1,1518 @@ +package plpgsql + +// The productions of pl_gram.y as recursive descent. Support functions live +// in gram_support.go; the scanner interface layer in scanner.go. Actions run +// where bison runs them (statement linenos are computed at the C action's +// point in the token stream, since plpgsql_latest_lineno is stateful and +// feeds the compile error context). + +// parseFunction is pl_function: comp_options pl_block opt_semi. +func (c *compiler) parseFunction() *stmtBlock { + tok := c.compOptions() + + // pl_block's opt_block_label. + var label string + if tok == LESS_LESS { + label = c.anyIdentifier(c.lex()) + c.expect(GREATER_GREATER) + tok = c.lex() + } + c.nsPush(label, labelBlock) + blk := c.plBlock(label, tok) + + // opt_semi, then end of input. + tok = c.lex() + if tok == plToken(';') { + tok = c.lex() + } + if tok != 0 { + c.scan.yyerror("syntax error") + } + return blk +} + +// compOptions is comp_options/comp_option: leading '#' directives. Returns +// the first token that is not part of an option. +func (c *compiler) compOptions() plToken { + for { + tok := c.lex() + if tok != plToken('#') { + return tok + } + tok = c.lex() + switch tok { + case K_OPTION: + c.expect(K_DUMP) + // plpgsql_DumpExecTree = true: no output effect here + case K_PRINT_STRICT_PARAMS: + val := c.optionValue() + switch val { + case "on": + c.fn.printStrictParams = true + case "off": + c.fn.printStrictParams = false + default: + c.ereportGram("unrecognized print_strict_params option %s", val) + } + case K_VARIABLE_CONFLICT: + tok = c.lex() + switch tok { + case K_ERROR: + c.fn.resolveOption = resolveError + case K_USE_VARIABLE: + c.fn.resolveOption = resolveVariable + case K_USE_COLUMN: + c.fn.resolveOption = resolveColumn + default: + c.scan.yyerror("syntax error") + } + default: + c.scan.yyerror("syntax error") + } + } +} + +// option_value: T_WORD | unreserved_keyword. +func (c *compiler) optionValue() string { + tok := c.lex() + if tok == T_WORD { + return c.cur().word.ident + } + if tokenIsUnreservedKeyword(tok) { + return c.cur().keyword + } + c.scan.yyerror("syntax error") + return "" +} + +// plBlock is pl_block minus opt_block_label (the caller parsed the label and +// pushed the namespace); firstTok is the already-consumed K_DECLARE or +// K_BEGIN (or anything else, which is a syntax error exactly as bison finds +// when it can't shift into decl_sect/K_BEGIN). +func (c *compiler) plBlock(label string, firstTok plToken) *stmtBlock { + var initVarnos []int + + tok := firstTok + if tok == K_DECLARE { + // decl_start action: forget variables created before the block and + // disable identifier lookup during declarations. + c.addInitdatums(false) + c.scan.identifierLookup = lookupDeclare + + declared := false + decls: + for { + tok = c.lex() + switch { + case tok == K_DECLARE: + // We allow useless extra DECLAREs + case tok == LESS_LESS: + c.ereportGram("block label must be placed before DECLARE, not after") + case tok == T_WORD || tokenIsUnreservedKeyword(tok): + c.declStatement(tok) + declared = true + default: + break decls + } + } + if declared { + initVarnos = c.addInitdatums(true) + } + } + + // decl_sect action: done with decls, so resume identifier lookup. + c.scan.identifierLookup = lookupNormal + + if tok != K_BEGIN { + c.scan.yyerror("syntax error") + } + beginLoc := c.loc() + + body := c.procSect() + exceptions := c.exceptionSect() + c.expect(K_END) + endLabel := c.optLabel() + + blk := &stmtBlock{ + label: label, + initVarnos: initVarnos, + body: body, + exceptions: exceptions, + } + blk.lineno = c.scan.locationToLineno(beginLoc) + + checkLabels(label, endLabel) + c.nsPop() + + return blk +} + +// declStatement is decl_statement; firstTok is the decl_varname's token. +func (c *compiler) declStatement(firstTok plToken) { + name, lineno := c.declVarname(firstTok) + + tok := c.lex() + switch tok { + case K_ALIAS: + // decl_varname K_ALIAS K_FOR decl_aliasitem ';' + c.expect(K_FOR) + nsi := c.declAliasitem() + c.expect(plToken(';')) + c.nsAdditem(nsi.itemtype, nsi.itemno, name) + return + + case K_NO: + c.expect(K_SCROLL) + c.expect(K_CURSOR) + c.declCursor(name, lineno, cursorOptNoScroll) + return + case K_SCROLL: + c.expect(K_CURSOR) + c.declCursor(name, lineno, cursorOptScroll) + return + case K_CURSOR: + c.declCursor(name, lineno, 0) + return + } + + // Ordinary variable declaration. + isConst := false + if tok == K_CONSTANT { + isConst = true + } else { + c.scan.pushBackToken(tok) + } + + dtype := c.readDatatype(0, false) + + // decl_collate (get_collation_oid is mocked to the default collation). + collation := uint32(0) + tok = c.lex() + if tok == K_COLLATE { + tok = c.lex() + if tok == T_WORD || tokenIsUnreservedKeyword(tok) || tok == T_CWORD { + collation = oidDefaultCollation + } else { + c.scan.yyerror("syntax error") + } + } else { + c.scan.pushBackToken(tok) + } + + // decl_notnull. + notnull := false + tok = c.lex() + if tok == K_NOT { + c.expect(K_NULL) + notnull = true + } else { + c.scan.pushBackToken(tok) + } + + // decl_defval. + var defval *plExpr + tok = c.lex() + switch tok { + case plToken(';'): + case plToken('='), tokCOLON_EQUALS, K_DEFAULT: + defval = c.readSQLExpression(plToken(';'), ";") + default: + c.scan.yyerror("syntax error") + } + + // decl_statement action. + if collation != 0 { + if dtype.collation == 0 { + // format_type_be is mocked to "-". + c.ereportGram("collations are not supported by type -") + } + dtype.collation = collation + } + + v := c.buildVariable(name, lineno, dtype, true) + if vr, ok := v.(*plVar); ok { + vr.isconst = isConst + vr.notnull = notnull + vr.defaultVal = defval + if vr.notnull && vr.defaultVal == nil { + c.ereportGram(`variable "%s" must have a default value, since it's declared NOT NULL`, vr.refname) + } + } else if rec, ok := v.(*plRec); ok { + // PLpgSQL_variable header fields: isconst/notnull/default_val live on + // the C supertype; only the NOT NULL check reads them afterwards. + _ = rec + if notnull && defval == nil { + c.ereportGram(`variable "%s" must have a default value, since it's declared NOT NULL`, rec.refname) + } + } +} + +// declVarname is decl_varname. +func (c *compiler) declVarname(tok plToken) (string, int) { + var name string + switch { + case tok == T_WORD: + name = c.cur().word.ident + case tokenIsUnreservedKeyword(tok): + name = c.cur().keyword + default: + c.scan.yyerror("syntax error") + } + lineno := c.scan.locationToLineno(c.loc()) + // Check to make sure name isn't already declared in the current block. + if ns, _ := c.nsLookup(c.nsTop, true, name, "", ""); ns != nil { + c.scan.yyerror("duplicate declaration") + } + // XCHECK_SHADOWVAR warnings are disabled (extra_warnings/errors are 0). + return name, lineno +} + +// declAliasitem is decl_aliasitem. +func (c *compiler) declAliasitem() *nsItem { + tok := c.lex() + switch { + case tok == T_WORD: + ident := c.cur().word.ident + nsi, _ := c.nsLookup(c.nsTop, false, ident, "", "") + if nsi == nil { + c.ereportGram(`variable "%s" does not exist`, ident) + } + return nsi + case tokenIsUnreservedKeyword(tok): + ident := c.cur().keyword + nsi, _ := c.nsLookup(c.nsTop, false, ident, "", "") + if nsi == nil { + c.ereportGram(`variable "%s" does not exist`, ident) + } + return nsi + case tok == T_CWORD: + idents := c.cur().cword + var nsi *nsItem + if len(idents) == 2 { + nsi, _ = c.nsLookup(c.nsTop, false, idents[0], idents[1], "") + } else if len(idents) == 3 { + nsi, _ = c.nsLookup(c.nsTop, false, idents[0], idents[1], idents[2]) + } + if nsi == nil { + c.ereportGram(`variable "%s" does not exist`, nameListToString(idents)) + } + return nsi + default: + c.scan.yyerror("syntax error") + return nil + } +} + +// declCursor is the cursor arm of decl_statement (after K_CURSOR). +func (c *compiler) declCursor(name string, lineno int, scrollOption int) { + // Mid-rule action: push a private namespace level for the cursor args. + c.nsPush(name, labelOther) + + // decl_cursor_args. + var argrow *plRow + tok := c.lex() + if tok == plToken('(') { + openLoc := c.loc() + var args []plVariable + for { + args = append(args, c.declCursorArg()) + tok = c.lex() + if tok != plToken(',') { + break + } + } + if tok != plToken(')') { + c.scan.yyerror("syntax error") + } + row := &plRow{ + refname: "(unnamed row)", + lineno: c.scan.locationToLineno(openLoc), + } + for _, arg := range args { + row.fieldnames = append(row.fieldnames, arg.varRefname()) + row.varnos = append(row.varnos, arg.datumNo()) + } + c.addDatum(row) + argrow = row + } else { + c.scan.pushBackToken(tok) + } + + // decl_is_for. + tok = c.lex() + if tok != K_IS && tok != K_FOR { + c.scan.yyerror("syntax error") + } + + // decl_cursor_query. + query := c.readSQLStmt() + + // decl_statement's cursor action: pop the arg namespace, then build. + c.nsPop() + + nv := c.buildVariable(name, lineno, + buildDatatype(oidRefcursor, -1, 0, nil), true).(*plVar) + nv.cursorExplicitExpr = query + if argrow == nil { + nv.cursorExplicitArgrow = -1 + } else { + nv.cursorExplicitArgrow = argrow.dno + } + nv.cursorOptions = cursorOptFastPlan | scrollOption +} + +// decl_cursor_arg: decl_varname decl_datatype. +func (c *compiler) declCursorArg() plVariable { + name, lineno := c.declVarname(c.lex()) + dtype := c.readDatatype(0, false) + return c.buildVariable(name, lineno, dtype, true) +} + +// optLabel is opt_label. +func (c *compiler) optLabel() string { + tok := c.lex() + if tok == T_WORD || tok == T_DATUM || tokenIsUnreservedKeyword(tok) { + return c.anyIdentifier(tok) + } + c.scan.pushBackToken(tok) + return "" +} + +// anyIdentifier is any_identifier; tok is the already-consumed token. +func (c *compiler) anyIdentifier(tok plToken) string { + switch { + case tok == T_WORD: + return c.cur().word.ident + case tokenIsUnreservedKeyword(tok): + return c.cur().keyword + case tok == T_DATUM: + if c.cur().wdatum.ident == "" { + c.scan.yyerror("syntax error") // composite name not OK + } + return c.cur().wdatum.ident + default: + c.scan.yyerror("syntax error") + return "" + } +} + +// procSect is proc_sect: statements until a token that cannot start one. +func (c *compiler) procSect() []plStmt { + var stmts []plStmt + for { + tok := c.lex() + if !isStmtStart(tok) { + c.scan.pushBackToken(tok) + return stmts + } + st := c.procStmt(tok) + if st != nil { + stmts = append(stmts, st) + } + } +} + +// isStmtStart is FIRST(proc_stmt). +func isStmtStart(tok plToken) bool { + switch tok { + case LESS_LESS, K_DECLARE, K_BEGIN, T_DATUM, K_IF, K_CASE, K_LOOP, + K_WHILE, K_FOR, K_FOREACH, K_EXIT, K_CONTINUE, K_RETURN, K_RAISE, + K_ASSERT, K_IMPORT, K_INSERT, K_MERGE, T_WORD, T_CWORD, K_EXECUTE, + K_PERFORM, K_CALL, K_DO, K_GET, K_OPEN, K_FETCH, K_MOVE, K_CLOSE, + K_NULL, K_COMMIT, K_ROLLBACK: + return true + } + return false +} + +// procStmt is proc_stmt; tok is the statement's first token, consumed. +func (c *compiler) procStmt(tok plToken) plStmt { + loc := c.loc() + switch tok { + case LESS_LESS: + label := c.anyIdentifier(c.lex()) + c.expect(GREATER_GREATER) + tok = c.lex() + switch tok { + case K_DECLARE, K_BEGIN: + c.nsPush(label, labelBlock) + blk := c.plBlock(label, tok) + c.expect(plToken(';')) + return blk + case K_LOOP: + c.nsPush(label, labelLoop) + return c.stmtLoop(label) + case K_WHILE: + c.nsPush(label, labelLoop) + return c.stmtWhile(label) + case K_FOR: + c.nsPush(label, labelLoop) + return c.stmtFor(label) + case K_FOREACH: + c.nsPush(label, labelLoop) + return c.stmtForeachA(label) + default: + c.scan.yyerror("syntax error") + return nil + } + + case K_DECLARE, K_BEGIN: + c.nsPush("", labelBlock) + blk := c.plBlock("", tok) + c.expect(plToken(';')) + return blk + + case K_LOOP: + c.nsPush("", labelLoop) + return c.stmtLoop("") + case K_WHILE: + c.nsPush("", labelLoop) + return c.stmtWhile("") + case K_FOR: + c.nsPush("", labelLoop) + return c.stmtFor("") + case K_FOREACH: + c.nsPush("", labelLoop) + return c.stmtForeachA("") + + case T_DATUM: + return c.stmtAssign() + + case K_IF: + return c.stmtIf(loc) + case K_CASE: + return c.stmtCase(loc) + case K_EXIT: + return c.stmtExit(true, loc) + case K_CONTINUE: + return c.stmtExit(false, loc) + case K_RETURN: + return c.stmtReturn(loc) + case K_RAISE: + return c.stmtRaise(loc) + case K_ASSERT: + return c.stmtAssert(loc) + + case K_IMPORT, K_INSERT, K_MERGE: + return c.makeExecsqlStmt(tok, loc, nil) + case T_WORD: + word := c.cur().word + next := c.lex() + c.scan.pushBackToken(next) + if next == plToken('=') || next == tokCOLON_EQUALS || + next == plToken('[') || next == plToken('.') { + wordIsNotVariable(&word) + } + return c.makeExecsqlStmt(T_WORD, loc, &word) + case T_CWORD: + cword := c.cur().cword + next := c.lex() + c.scan.pushBackToken(next) + if next == plToken('=') || next == tokCOLON_EQUALS || + next == plToken('[') || next == plToken('.') { + cwordIsNotVariable(cword) + } + return c.makeExecsqlStmt(T_CWORD, loc, nil) + + case K_EXECUTE: + return c.stmtDynexecute(loc) + case K_PERFORM: + return c.stmtPerform(loc) + case K_CALL: + return c.stmtCallOrDo(loc, true) + case K_DO: + return c.stmtCallOrDo(loc, false) + case K_GET: + return c.stmtGetdiag(loc) + case K_OPEN: + return c.stmtOpen(loc) + case K_FETCH: + return c.stmtFetchOrMove(loc, false) + case K_MOVE: + return c.stmtFetchOrMove(loc, true) + case K_CLOSE: + return c.stmtClose(loc) + case K_NULL: + // stmt_null: K_NULL ';' — we do not bother building a node for NULL. + c.expect(plToken(';')) + return nil + case K_COMMIT: + return c.stmtCommit(loc) + case K_ROLLBACK: + return c.stmtRollback(loc) + } + c.scan.yyerror("syntax error") + return nil +} + +// stmt_perform. +func (c *compiler) stmtPerform(loc int) plStmt { + st := &stmtPerform{} + st.lineno = c.scan.locationToLineno(loc) + c.scan.pushBackToken(K_PERFORM) + + // Substitute "SELECT" for "PERFORM" in the parsed text; syntax checking + // happens after the substitution. + var startloc int + expr, _ := c.readSQLConstruct(plToken(';'), 0, 0, ";", + rawParseDefault, false, false, &startloc) + // overwrite "perform" (and the space the C memmove drops) + expr.query = "SELECT" + expr.query[7:] + c.checkSQLExpr(expr.query, expr.parseMode, startloc+1) + st.expr = expr + return st +} + +// stmt_call: K_CALL / K_DO. +func (c *compiler) stmtCallOrDo(loc int, isCall bool) plStmt { + st := &stmtCall{isCall: isCall} + st.lineno = c.scan.locationToLineno(loc) + if isCall { + c.scan.pushBackToken(K_CALL) + } else { + c.scan.pushBackToken(K_DO) + } + st.expr = c.readSQLStmt() + return st +} + +// stmt_assign (current token is T_DATUM). +func (c *compiler) stmtAssign() plStmt { + loc := c.loc() + w := c.cur().wdatum + + // see how many names identify the datum + nnames := 1 + if w.ident == "" { + nnames = len(w.idents) + } + var pmode rawParseMode + switch nnames { + case 1: + pmode = rawParsePlpgsqlAssign1 + case 2: + pmode = rawParsePlpgsqlAssign2 + case 3: + pmode = rawParsePlpgsqlAssign3 + } + + c.checkAssignable(w.datum) + st := &stmtAssign{varno: w.datum.datumNo()} + st.lineno = c.scan.locationToLineno(loc) + // Push back the head name to include it in the stmt + c.scan.pushBackToken(T_DATUM) + st.expr, _ = c.readSQLConstruct(plToken(';'), 0, 0, ";", pmode, false, true, nil) + return st +} + +// stmt_getdiag. +func (c *compiler) stmtGetdiag(loc int) plStmt { + st := &stmtGetdiag{} + + // getdiag_area_opt. + tok := c.lex() + switch tok { + case K_CURRENT: + case K_STACKED: + st.isStacked = true + default: + c.scan.pushBackToken(tok) + } + c.expect(K_DIAGNOSTICS) + + // getdiag_list. + for { + item := &diagItem{} + item.target = c.getdiagTarget() + // assign_operator. + tok = c.lex() + if tok != plToken('=') && tok != tokCOLON_EQUALS { + c.scan.yyerror("syntax error") + } + item.kind = c.getdiagItem() + st.diagItems = append(st.diagItems, item) + tok = c.lex() + if tok != plToken(',') { + break + } + } + if tok != plToken(';') { + c.scan.yyerror("syntax error") + } + + st.lineno = c.scan.locationToLineno(loc) + + // Check information items are valid for area option. + for _, ditem := range st.diagItems { + switch ditem.kind { + case getdiagRowCount, getdiagRoutineOid: + if st.isStacked { + c.ereportGram("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS", + getdiagKindname(ditem.kind)) + } + case getdiagErrorContext, getdiagErrorDetail, getdiagErrorHint, + getdiagReturnedSqlstate, getdiagColumnName, getdiagConstraintName, + getdiagDatatypeName, getdiagMessageText, getdiagTableName, + getdiagSchemaName: + if !st.isStacked { + c.ereportGram("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS", + getdiagKindname(ditem.kind)) + } + case getdiagContext: + } + } + + return st +} + +// getdiag_item. +func (c *compiler) getdiagItem() getdiagKind { + tok := c.lex() + switch { + case c.tokIsKeyword(tok, K_ROW_COUNT, "row_count"): + return getdiagRowCount + case c.tokIsKeyword(tok, K_PG_ROUTINE_OID, "pg_routine_oid"): + return getdiagRoutineOid + case c.tokIsKeyword(tok, K_PG_CONTEXT, "pg_context"): + return getdiagContext + case c.tokIsKeyword(tok, K_PG_EXCEPTION_DETAIL, "pg_exception_detail"): + return getdiagErrorDetail + case c.tokIsKeyword(tok, K_PG_EXCEPTION_HINT, "pg_exception_hint"): + return getdiagErrorHint + case c.tokIsKeyword(tok, K_PG_EXCEPTION_CONTEXT, "pg_exception_context"): + return getdiagErrorContext + case c.tokIsKeyword(tok, K_COLUMN_NAME, "column_name"): + return getdiagColumnName + case c.tokIsKeyword(tok, K_CONSTRAINT_NAME, "constraint_name"): + return getdiagConstraintName + case c.tokIsKeyword(tok, K_PG_DATATYPE_NAME, "pg_datatype_name"): + return getdiagDatatypeName + case c.tokIsKeyword(tok, K_MESSAGE_TEXT, "message_text"): + return getdiagMessageText + case c.tokIsKeyword(tok, K_TABLE_NAME, "table_name"): + return getdiagTableName + case c.tokIsKeyword(tok, K_SCHEMA_NAME, "schema_name"): + return getdiagSchemaName + case c.tokIsKeyword(tok, K_RETURNED_SQLSTATE, "returned_sqlstate"): + return getdiagReturnedSqlstate + default: + c.scan.yyerror("unrecognized GET DIAGNOSTICS item") + return 0 + } +} + +// getdiag_target. +func (c *compiler) getdiagTarget() int { + tok := c.lex() + switch tok { + case T_DATUM: + w := c.cur().wdatum + if w.datum.datumType() == dtypeRow || w.datum.datumType() == dtypeRec || + c.scan.peek() == plToken('[') { + c.ereportGram(`"%s" is not a scalar variable`, nameOfDatum(&w)) + } + c.checkAssignable(w.datum) + return w.datum.datumNo() + case T_WORD: + wordIsNotVariable(&c.cur().word) + case T_CWORD: + cwordIsNotVariable(c.cur().cword) + default: + c.scan.yyerror("syntax error") + } + return 0 +} + +// stmt_if. +func (c *compiler) stmtIf(loc int) plStmt { + st := &stmtIf{} + st.cond = c.readSQLExpression(K_THEN, "THEN") + st.thenBody = c.procSect() + + // stmt_elsifs (lineno computed at the C reduce point: after the body). + tok := c.lex() + for tok == K_ELSIF { + elsifLoc := c.loc() + e := &ifElsif{} + e.cond = c.readSQLExpression(K_THEN, "THEN") + e.stmts = c.procSect() + e.lineno = c.scan.locationToLineno(elsifLoc) + st.elsifList = append(st.elsifList, e) + tok = c.lex() + } + + // stmt_else. + if tok == K_ELSE { + st.elseBody = c.procSect() + tok = c.lex() + } + if tok != K_END { + c.scan.yyerror("syntax error") + } + c.expect(K_IF) + c.expect(plToken(';')) + + st.lineno = c.scan.locationToLineno(loc) + return st +} + +// stmt_case. +func (c *compiler) stmtCase(loc int) plStmt { + // opt_expr_until_when. + var tExpr *plExpr + tok := c.lex() + if tok != K_WHEN { + c.scan.pushBackToken(tok) + tExpr = c.readSQLExpression(K_WHEN, "WHEN") + } + + // case_when_list (lineno at the C reduce point: after the body). + var whens []*caseWhen + for { + whenLoc := c.loc() // location of K_WHEN + w := &caseWhen{} + w.expr = c.readSQLExpression(K_THEN, "THEN") + w.stmts = c.procSect() + w.lineno = c.scan.locationToLineno(whenLoc) + whens = append(whens, w) + tok = c.lex() + if tok != K_WHEN { + break + } + } + + // opt_case_else. + var elseStmts []plStmt + if tok == K_ELSE { + elseStmts = c.procSect() + if elseStmts == nil { + // distinguish empty ELSE from no ELSE: list with one NULL + elseStmts = []plStmt{nil} + } + tok = c.lex() + } + if tok != K_END { + c.scan.yyerror("syntax error") + } + c.expect(K_CASE) + c.expect(plToken(';')) + + return c.makeCase(loc, tExpr, whens, elseStmts) +} + +// loop_body: proc_sect K_END K_LOOP opt_label ';'. +func (c *compiler) loopBody() ([]plStmt, string) { + stmts := c.procSect() + c.expect(K_END) + c.expect(K_LOOP) + endLabel := c.optLabel() + c.expect(plToken(';')) + return stmts, endLabel +} + +// stmt_loop (K_LOOP consumed; its location is current). +func (c *compiler) stmtLoop(label string) plStmt { + loopLoc := c.loc() + body, endLabel := c.loopBody() + + st := &stmtLoop{label: label, body: body} + st.lineno = c.scan.locationToLineno(loopLoc) + checkLabels(label, endLabel) + c.nsPop() + return st +} + +// stmt_while. +func (c *compiler) stmtWhile(label string) plStmt { + whileLoc := c.loc() + cond := c.readSQLExpression(K_LOOP, "LOOP") + body, endLabel := c.loopBody() + + st := &stmtWhile{label: label, cond: cond, body: body} + st.lineno = c.scan.locationToLineno(whileLoc) + checkLabels(label, endLabel) + c.nsPop() + return st +} + +// stmt_for: opt_loop_label K_FOR for_control loop_body. +func (c *compiler) stmtFor(label string) plStmt { + forLoc := c.loc() + ctrl := c.forControl() + body, endLabel := c.loopBody() + + lineno := c.scan.locationToLineno(forLoc) + switch st := ctrl.(type) { + case *stmtFori: + st.lineno = lineno + st.label = label + st.body = body + case *stmtFors: + st.lineno = lineno + st.label = label + st.body = body + case *stmtForc: + st.lineno = lineno + st.label = label + st.body = body + case *stmtDynfors: + st.lineno = lineno + st.label = label + st.body = body + } + + checkLabels(label, endLabel) + c.nsPop() + return ctrl +} + +// forVariable is for_variable. +type forVariableResult struct { + name string + lineno int + scalar datum + row datum +} + +func (c *compiler) forVariable() forVariableResult { + var fv forVariableResult + tok := c.lex() + switch tok { + case T_DATUM: + w := c.cur().wdatum + loc := c.loc() + fv.name = nameOfDatum(&w) + fv.lineno = c.scan.locationToLineno(loc) + if w.datum.datumType() == dtypeRow || w.datum.datumType() == dtypeRec { + fv.row = w.datum + } else { + fv.scalar = w.datum + // check for comma-separated list + tok = c.lex() + c.scan.pushBackToken(tok) + if tok == plToken(',') { + fv.row = c.readIntoScalarList(fv.name, fv.scalar, loc) + } + } + case T_WORD: + word := c.cur().word + fv.name = word.ident + fv.lineno = c.scan.locationToLineno(c.loc()) + // check for comma-separated list + tok = c.lex() + c.scan.pushBackToken(tok) + if tok == plToken(',') { + wordIsNotVariable(&word) + } + case T_CWORD: + cwordIsNotVariable(c.cur().cword) + default: + c.scan.yyerror("syntax error") + } + return fv +} + +// forControl is for_control. +func (c *compiler) forControl() plStmt { + fv := c.forVariable() + c.expect(K_IN) + + tok := c.lex() + if tok == K_EXECUTE { + // EXECUTE means it's a dynamic FOR loop. + expr, term := c.readSQLExpression2(K_LOOP, K_USING, "LOOP or USING") + + st := &stmtDynfors{} + if fv.row != nil { + st.varDat = fv.row.(plVariable) + c.checkAssignable(fv.row) + } else if fv.scalar != nil { + st.varDat = c.makeScalarList1(fv.name, fv.scalar, fv.lineno) + } else { + c.ereportGram("loop variable of loop over rows must be a record variable or list of scalar variables") + } + st.query = expr + + if term == K_USING { + for { + expr, term = c.readSQLExpression2(plToken(','), K_LOOP, ", or LOOP") + st.params = append(st.params, expr) + if term != plToken(',') { + break + } + } + } + return st + } + + if tok == T_DATUM && c.cur().wdatum.datum.datumType() == dtypeVar && + c.cur().wdatum.datum.(*plVar).datatype.typoid == oidRefcursor { + // It's FOR var IN cursor. + cursor := c.cur().wdatum.datum.(*plVar) + st := &stmtForc{curvar: cursor.dno} + + // Should have had a single variable name. + if fv.scalar != nil && fv.row != nil { + c.ereportGram("cursor FOR loop must have only one target variable") + } + + // can't use an unbound cursor this way + if cursor.cursorExplicitExpr == nil { + c.ereportGram("cursor FOR loop must use a bound cursor variable") + } + + // collect cursor's parameters if any + st.argquery = c.readCursorArgs(cursor, K_LOOP) + + // create loop's private RECORD variable + st.varDat = c.buildRecord(fv.name, fv.lineno, nil, oidRecord, true) + return st + } + + // FOR var IN a..b or FOR var IN query. + reverse := false + if c.tokIsKeyword(tok, K_REVERSE, "reverse") { + reverse = true + } else { + c.scan.pushBackToken(tok) + } + + var expr1loc int + expr1, term := c.readSQLConstruct(tokDOT_DOT, K_LOOP, 0, "LOOP", + rawParseDefault, true, false, &expr1loc) + + if term == tokDOT_DOT { + // Saw "..", so it must be an integer loop. + + // Relabel first expression as an expression; then check its syntax. + expr1.parseMode = rawParsePlpgsqlExpr + c.checkSQLExpr(expr1.query, expr1.parseMode, expr1loc) + + // Read and check the second one + expr2, term2 := c.readSQLExpression2(K_LOOP, K_BY, "LOOP") + + // Get the BY clause if any + var exprBy *plExpr + if term2 == K_BY { + exprBy = c.readSQLExpression(K_LOOP, "LOOP") + } + + // Should have had a single variable name + if fv.scalar != nil && fv.row != nil { + c.ereportGram("integer FOR loop must have only one target variable") + } + + // create loop's private variable + fvar := c.buildVariable(fv.name, fv.lineno, + buildDatatype(oidInt4, -1, 0, nil), true).(*plVar) + + st := &stmtFori{ + varDat: fvar, + reverse: reverse, + lower: expr1, + upper: expr2, + step: exprBy, + } + return st + } + + // No "..", so it must be a query loop. + if reverse { + c.ereportGram("cannot specify REVERSE in query FOR loop") + } + + // Check syntax as a regular query + c.checkSQLExpr(expr1.query, expr1.parseMode, expr1loc) + + st := &stmtFors{} + if fv.row != nil { + st.varDat = fv.row.(plVariable) + c.checkAssignable(fv.row) + } else if fv.scalar != nil { + st.varDat = c.makeScalarList1(fv.name, fv.scalar, fv.lineno) + } else { + c.ereportGram("loop variable of loop over rows must be a record variable or list of scalar variables") + } + st.query = expr1 + return st +} + +// stmt_foreach_a. +func (c *compiler) stmtForeachA(label string) plStmt { + foreachLoc := c.loc() + fv := c.forVariable() + + // foreach_slice. + slice := 0 + tok := c.lex() + if tok == K_SLICE { + c.expect(tokICONST) + slice = int(c.cur().ival) + } else { + c.scan.pushBackToken(tok) + } + + c.expect(K_IN) + c.expect(K_ARRAY) + expr := c.readSQLExpression(K_LOOP, "LOOP") + body, endLabel := c.loopBody() + + st := &stmtForeachA{ + label: label, + slice: slice, + expr: expr, + body: body, + } + st.lineno = c.scan.locationToLineno(foreachLoc) + + if fv.row != nil { + st.varno = fv.row.datumNo() + c.checkAssignable(fv.row) + } else if fv.scalar != nil { + st.varno = fv.scalar.datumNo() + c.checkAssignable(fv.scalar) + } else { + c.ereportGram("loop variable of FOREACH must be a known variable or list of variables") + } + + checkLabels(label, endLabel) + c.nsPop() + return st +} + +// stmt_exit (exit_type consumed; loc is its location). +func (c *compiler) stmtExit(isExit bool, loc int) plStmt { + st := &stmtExit{isExit: isExit} + st.label = c.optLabel() + + // opt_exitcond. + tok := c.lex() + switch tok { + case plToken(';'): + case K_WHEN: + st.cond = c.readSQLExpression(plToken(';'), ";") + default: + c.scan.yyerror("syntax error") + } + + st.lineno = c.scan.locationToLineno(loc) + + if st.label != "" { + // We have a label, so verify it exists + labelItem := c.nsLookupLabel(c.nsTop, st.label) + if labelItem == nil { + c.ereportGram(`there is no label "%s" attached to any block or loop enclosing this statement`, st.label) + } + // CONTINUE only allows loop labels + if labelItem.itemno != int(labelLoop) && !st.isExit { + c.ereportGram(`block label "%s" cannot be used in CONTINUE`, st.label) + } + } else { + // No label, so make sure there is some loop + if c.nsFindNearestLoop(c.nsTop) == nil { + if st.isExit { + c.ereportGram("EXIT cannot be used outside a loop, unless it has a label") + } else { + c.ereportGram("CONTINUE cannot be used outside a loop") + } + } + } + + return st +} + +// stmt_return. +func (c *compiler) stmtReturn(loc int) plStmt { + tok := c.lex() + if tok == 0 { + c.scan.yyerror("unexpected end of function definition") + } + if c.tokIsKeyword(tok, K_NEXT, "next") { + return c.makeReturnNextStmt(loc) + } + if c.tokIsKeyword(tok, K_QUERY, "query") { + return c.makeReturnQueryStmt(loc) + } + c.scan.pushBackToken(tok) + return c.makeReturnStmt(loc) +} + +// stmt_raise. +func (c *compiler) stmtRaise(loc int) plStmt { + st := &stmtRaise{elogLevel: elogError} + st.lineno = c.scan.locationToLineno(loc) + + tok := c.lex() + if tok == 0 { + c.scan.yyerror("unexpected end of function definition") + } + + // We could have just RAISE, meaning to re-throw the current error. + if tok != plToken(';') { + // First is an optional elog severity level. + levelSet := true + switch { + case c.tokIsKeyword(tok, K_EXCEPTION, "exception"): + st.elogLevel = elogError + case c.tokIsKeyword(tok, K_WARNING, "warning"): + st.elogLevel = elogWarning + case c.tokIsKeyword(tok, K_NOTICE, "notice"): + st.elogLevel = elogNotice + case c.tokIsKeyword(tok, K_INFO, "info"): + st.elogLevel = elogInfo + case c.tokIsKeyword(tok, K_LOG, "log"): + st.elogLevel = elogLog + case c.tokIsKeyword(tok, K_DEBUG, "debug"): + st.elogLevel = elogDebug1 + default: + levelSet = false + } + if levelSet { + tok = c.lex() + } + if tok == 0 { + c.scan.yyerror("unexpected end of function definition") + } + + // Next: condition name, SQLSTATE 'xxxxx', old-style message string, + // or USING. + if tok == tokSCONST { + // old style message and parameters + st.message = c.cur().str + st.hasMessage = true + tok = c.lex() + if tok != plToken(',') && tok != plToken(';') && tok != K_USING { + c.scan.yyerror("syntax error") + } + for tok == plToken(',') { + var expr *plExpr + expr, tok = c.readSQLConstruct2(plToken(','), plToken(';'), K_USING, + ", or ; or USING") + st.params = append(st.params, expr) + } + } else if tok != K_USING { + // must be condition name or SQLSTATE + if c.tokIsKeyword(tok, K_SQLSTATE, "sqlstate") { + // next token should be a string literal + if c.lex() != tokSCONST { + c.scan.yyerror("syntax error") + } + sqlstatestr := c.cur().str + if len(sqlstatestr) != 5 { + c.scan.yyerror("invalid SQLSTATE code") + } + if !isSqlstate(sqlstatestr) { + c.scan.yyerror("invalid SQLSTATE code") + } + st.condname = sqlstatestr + } else { + if tok == T_WORD { + st.condname = c.cur().word.ident + } else if tokenIsUnreservedKeyword(tok) { + st.condname = c.cur().keyword + } else { + c.scan.yyerror("syntax error") + } + recognizeErrCondition(st.condname, false) + } + tok = c.lex() + if tok != plToken(';') && tok != K_USING { + c.scan.yyerror("syntax error") + } + } + + if tok == K_USING { + st.options = c.readRaiseOptions() + } + } + + checkRaiseParameters(st) + return st +} + +// readSQLConstruct2 is read_sql_construct with three terminators and the +// PLPGSQL_EXPR parse mode (the RAISE parameter shape). +func (c *compiler) readSQLConstruct2(until, until2, until3 plToken, expected string) (*plExpr, plToken) { + return c.readSQLConstruct(until, until2, until3, expected, + rawParsePlpgsqlExpr, true, true, nil) +} + +// stmt_assert. +func (c *compiler) stmtAssert(loc int) plStmt { + st := &stmtAssert{} + st.lineno = c.scan.locationToLineno(loc) + + var tok plToken + st.cond, tok = c.readSQLExpression2(plToken(','), plToken(';'), ", or ;") + if tok == plToken(',') { + st.message = c.readSQLExpression(plToken(';'), ";") + } + return st +} + +// stmt_dynexecute. +func (c *compiler) stmtDynexecute(loc int) plStmt { + expr, endtoken := c.readSQLConstruct(K_INTO, K_USING, plToken(';'), + "INTO or USING or ;", rawParsePlpgsqlExpr, true, true, nil) + + st := &stmtDynexecute{query: expr} + st.lineno = c.scan.locationToLineno(loc) + + for { + if endtoken == K_INTO { + if st.into { // multiple INTO + c.scan.yyerror("syntax error") + } + st.into = true + st.target, st.strict = c.readIntoTarget(true) + endtoken = c.lex() + } else if endtoken == K_USING { + if len(st.params) > 0 { // multiple USING + c.scan.yyerror("syntax error") + } + for { + expr, endtoken = c.readSQLConstruct(plToken(','), plToken(';'), K_INTO, + ", or ; or INTO", rawParsePlpgsqlExpr, true, true, nil) + st.params = append(st.params, expr) + if endtoken != plToken(',') { + break + } + } + } else if endtoken == plToken(';') { + break + } else { + c.scan.yyerror("syntax error") + } + } + + return st +} + +// cursor_variable. +func (c *compiler) cursorVariable() *plVar { + tok := c.lex() + switch tok { + case T_DATUM: + w := c.cur().wdatum + if w.datum.datumType() != dtypeVar || c.scan.peek() == plToken('[') { + c.ereportGram("cursor variable must be a simple variable") + } + v := w.datum.(*plVar) + if v.datatype.typoid != oidRefcursor { + c.ereportGram(`variable "%s" must be of type cursor or refcursor`, v.refname) + } + return v + case T_WORD: + wordIsNotVariable(&c.cur().word) + case T_CWORD: + cwordIsNotVariable(c.cur().cword) + default: + c.scan.yyerror("syntax error") + } + return nil +} + +// stmt_open. +func (c *compiler) stmtOpen(loc int) plStmt { + cursor := c.cursorVariable() + st := &stmtOpen{cursorOptions: cursorOptFastPlan} + st.lineno = c.scan.locationToLineno(loc) + st.curvar = cursor.dno + + if cursor.cursorExplicitExpr == nil { + // be nice if we could use opt_scrollable here + tok := c.lex() + if c.tokIsKeyword(tok, K_NO, "no") { + tok = c.lex() + if c.tokIsKeyword(tok, K_SCROLL, "scroll") { + st.cursorOptions |= cursorOptNoScroll + tok = c.lex() + } + } else if c.tokIsKeyword(tok, K_SCROLL, "scroll") { + st.cursorOptions |= cursorOptScroll + tok = c.lex() + } + + if tok != K_FOR { + c.scan.yyerror(`syntax error, expected "FOR"`) + } + + tok = c.lex() + if tok == K_EXECUTE { + var endtoken plToken + st.dynquery, endtoken = c.readSQLExpression2(K_USING, plToken(';'), "USING or ;") + + // If we found "USING", collect argument(s) + if endtoken == K_USING { + for { + var expr *plExpr + expr, endtoken = c.readSQLExpression2(plToken(','), plToken(';'), ", or ;") + st.params = append(st.params, expr) + if endtoken != plToken(',') { + break + } + } + } + } else { + c.scan.pushBackToken(tok) + st.query = c.readSQLStmt() + } + } else { + // predefined cursor query, so read args + st.argquery = c.readCursorArgs(cursor, plToken(';')) + } + + return st +} + +// stmt_fetch / stmt_move. +func (c *compiler) stmtFetchOrMove(loc int, isMove bool) plStmt { + fetch := c.readFetchDirection() + cursor := c.cursorVariable() + + if !isMove { + c.expect(K_INTO) + target, _ := c.readIntoTarget(false) + if c.lex() != plToken(';') { + c.scan.yyerror("syntax error") + } + // We don't allow multiple rows in PL/pgSQL's FETCH statement. + if fetch.returnsMultipleRows { + c.ereportGram("FETCH statement cannot return multiple rows") + } + fetch.target = target + } else { + c.expect(plToken(';')) + } + + fetch.lineno = c.scan.locationToLineno(loc) + fetch.curvar = cursor.dno + fetch.isMove = isMove + return fetch +} + +// stmt_close. +func (c *compiler) stmtClose(loc int) plStmt { + curvar := c.cursorVariable().dno + c.expect(plToken(';')) + st := &stmtClose{curvar: curvar} + st.lineno = c.scan.locationToLineno(loc) + return st +} + +// stmt_commit / stmt_rollback with opt_transaction_chain. +func (c *compiler) stmtCommit(loc int) plStmt { + chain := c.optTransactionChain() + c.expect(plToken(';')) + st := &stmtCommit{chain: chain} + st.lineno = c.scan.locationToLineno(loc) + return st +} + +func (c *compiler) stmtRollback(loc int) plStmt { + chain := c.optTransactionChain() + c.expect(plToken(';')) + st := &stmtRollback{chain: chain} + st.lineno = c.scan.locationToLineno(loc) + return st +} + +func (c *compiler) optTransactionChain() bool { + tok := c.lex() + if tok != K_AND { + c.scan.pushBackToken(tok) + return false + } + tok = c.lex() + if tok == K_CHAIN { + return true + } + if tok == K_NO { + c.expect(K_CHAIN) + return false + } + c.scan.yyerror("syntax error") + return false +} + +// exceptionSect is exception_sect. +func (c *compiler) exceptionSect() *exceptionBlock { + tok := c.lex() + if tok != K_EXCEPTION { + c.scan.pushBackToken(tok) + return nil + } + + // Mid-rule action: create the sqlstate/sqlerrm variables before parsing + // the WHEN clauses; their scope extends to the end of the current block. + lineno := c.scan.locationToLineno(c.loc()) + blk := &exceptionBlock{} + + v := c.buildVariable("sqlstate", lineno, + buildDatatype(oidText, -1, 0, nil), true).(*plVar) + v.isconst = true + blk.sqlstateVarno = v.dno + + v = c.buildVariable("sqlerrm", lineno, + buildDatatype(oidText, -1, 0, nil), true).(*plVar) + v.isconst = true + blk.sqlerrmVarno = v.dno + + // proc_exceptions (lineno at the C reduce point: after the action body). + for { + c.expect(K_WHEN) + whenLoc := c.loc() + exc := &plException{} + exc.conditions = c.procConditions() + c.expect(K_THEN) + exc.action = c.procSect() + exc.lineno = c.scan.locationToLineno(whenLoc) + blk.excList = append(blk.excList, exc) + + tok = c.lex() + c.scan.pushBackToken(tok) + if tok != K_WHEN { + break + } + } + + return blk +} + +// procConditions is proc_conditions: OR-joined condition chains. +func (c *compiler) procConditions() *plCondition { + head := c.procCondition() + for { + tok := c.lex() + if tok != K_OR { + c.scan.pushBackToken(tok) + return head + } + next := c.procCondition() + old := head + for old.next != nil { + old = old.next + } + old.next = next + } +} + +// procCondition is proc_condition. +func (c *compiler) procCondition() *plCondition { + name := c.anyIdentifier(c.lex()) + if name != "sqlstate" { + return parseErrCondition(name) + } + // next token should be a string literal + if c.lex() != tokSCONST { + c.scan.yyerror("syntax error") + } + sqlstatestr := c.cur().str + if len(sqlstatestr) != 5 { + c.scan.yyerror("invalid SQLSTATE code") + } + if !isSqlstate(sqlstatestr) { + c.scan.yyerror("invalid SQLSTATE code") + } + return &plCondition{condname: sqlstatestr} +} diff --git a/internal/plpgsql/gram_support.go b/internal/plpgsql/gram_support.go new file mode 100644 index 0000000..585d501 --- /dev/null +++ b/internal/plpgsql/gram_support.go @@ -0,0 +1,960 @@ +package plpgsql + +import ( + "fmt" + "strings" + + "github.com/sqlc-dev/oliphant/internal/deparse" + "github.com/sqlc-dev/oliphant/internal/parse" +) + +// The support functions from the bottom half of pl_gram.y, as built by +// libpg_query (parse_datatype and make_return_stmt are the mocked versions; +// %TYPE/%ROWTYPE lookups return NULL). + +// lex/expect/ereport plumbing ------------------------------------------------ + +func (c *compiler) lex() plToken { return c.scan.yylex() } +func (c *compiler) cur() *tokenAux { return &c.scan.cur } +func (c *compiler) loc() int { return c.scan.cur.lloc } + +// expect consumes one token and reports bison's plain "syntax error" at it +// when it is not the wanted one. +func (c *compiler) expect(tok plToken) { + if c.lex() != tok { + c.scan.yyerror("syntax error") + } +} + +// ereportGram is an ereport from a grammar action (funcname plpgsql_yyparse). +func (c *compiler) ereportGram(format string, args ...any) { + panic(&compileError{ + Message: fmt.Sprintf(format, args...), + Filename: plGramFilename, + Funcname: "plpgsql_yyparse", + }) +} + +// ereportFn is an ereport from a named pl_gram.y support function. +func ereportFn(funcname, format string, args ...any) { + panic(&compileError{ + Message: fmt.Sprintf(format, args...), + Filename: plGramFilename, + Funcname: funcname, + }) +} + +// tok_is_keyword (pl_gram.y). +func (c *compiler) tokIsKeyword(token plToken, kwToken plToken, kwStr string) bool { + if token == kwToken { + return true + } + if token == T_DATUM { + w := &c.cur().wdatum + if !w.quoted && w.ident != "" && w.ident == kwStr { + return true + } + } + return false +} + +// word_is_not_variable / cword_is_not_variable / current_token_is_not_variable. +func wordIsNotVariable(word *plWord) { + ereportFn("word_is_not_variable", `"%s" is not a known variable`, word.ident) +} + +func cwordIsNotVariable(idents []string) { + ereportFn("cword_is_not_variable", `"%s" is not a known variable`, nameListToString(idents)) +} + +func (c *compiler) currentTokenIsNotVariable(tok plToken) { + switch tok { + case T_WORD: + wordIsNotVariable(&c.cur().word) + case T_CWORD: + cwordIsNotVariable(c.cur().cword) + default: + c.scan.yyerror("syntax error") + } +} + +// read_sql_expression / read_sql_expression2 / read_sql_stmt ------------------ + +func (c *compiler) readSQLExpression(until plToken, expected string) *plExpr { + expr, _ := c.readSQLConstruct(until, 0, 0, expected, rawParsePlpgsqlExpr, true, true, nil) + return expr +} + +func (c *compiler) readSQLExpression2(until, until2 plToken, expected string) (*plExpr, plToken) { + return c.readSQLConstruct(until, until2, 0, expected, rawParsePlpgsqlExpr, true, true, nil) +} + +func (c *compiler) readSQLStmt() *plExpr { + expr, _ := c.readSQLConstruct(plToken(';'), 0, 0, ";", rawParseDefault, false, true, nil) + return expr +} + +// read_sql_construct (pl_gram.y). +func (c *compiler) readSQLConstruct(until, until2, until3 plToken, expected string, + parsemode rawParseMode, isexpression, validSQL bool, startloc *int) (*plExpr, plToken) { + + saveLookup := c.scan.identifierLookup + c.scan.identifierLookup = lookupExpr + + startlocation := -1 + endlocation := -1 + parenlevel := 0 + var tok plToken + + for { + tok = c.lex() + if startlocation < 0 { + startlocation = c.loc() + } + if tok == until && parenlevel == 0 { + break + } + if tok == until2 && parenlevel == 0 { + break + } + if until3 != 0 && tok == until3 && parenlevel == 0 { + break + } + if tok == plToken('(') || tok == plToken('[') { + parenlevel++ + } else if tok == plToken(')') || tok == plToken(']') { + parenlevel-- + if parenlevel < 0 { + c.scan.yyerror("mismatched parentheses") + } + } + if tok == 0 || tok == plToken(';') { + if parenlevel != 0 { + c.scan.yyerror("mismatched parentheses") + } + if isexpression { + c.ereportGram(`missing "%s" at end of SQL expression`, expected) + } + c.ereportGram(`missing "%s" at end of SQL statement`, expected) + } + endlocation = c.loc() + c.scan.tokenLength() + } + + c.scan.identifierLookup = saveLookup + + if startloc != nil { + *startloc = startlocation + } + + if startlocation >= endlocation { + if isexpression { + c.scan.yyerror("missing expression") + } + c.scan.yyerror("missing SQL statement") + } + + expr := &plExpr{ + query: c.scan.sourceText(startlocation, endlocation), + parseMode: parsemode, + } + + if validSQL { + c.checkSQLExpr(expr.query, expr.parseMode, startlocation) + } + + return expr, tok +} + +// read_datatype (pl_gram.y). tok < 0 means no lookahead (YYEMPTY). +func (c *compiler) readDatatype(tok plToken, haveTok bool) *plType { + var result *plType + + if !haveTok { + tok = c.lex() + } + + startlocation := c.loc() + parenlevel := 0 + + // If we have a simple or composite identifier, check for %TYPE and + // %ROWTYPE constructs (mocked to NULL lookups in this build). + if tok == T_WORD { + tok = c.lex() + if tok == plToken('%') { + tok = c.lex() + if c.tokIsKeyword(tok, K_TYPE, "type") { + result = c.parseWordType("") + } else if c.tokIsKeyword(tok, K_ROWTYPE, "rowtype") { + result = c.parseWordRowType("") + } + } + } else if tokenIsUnreservedKeyword(tok) { + tok = c.lex() + if tok == plToken('%') { + tok = c.lex() + if c.tokIsKeyword(tok, K_TYPE, "type") { + result = c.parseWordType("") + } else if c.tokIsKeyword(tok, K_ROWTYPE, "rowtype") { + result = c.parseWordRowType("") + } + } + } else if tok == T_CWORD { + tok = c.lex() + if tok == plToken('%') { + tok = c.lex() + if c.tokIsKeyword(tok, K_TYPE, "type") { + result = c.parseCwordType(nil) + } else if c.tokIsKeyword(tok, K_ROWTYPE, "rowtype") { + result = c.parseCwordRowType(nil) + } + } + } + + if result != nil { + // %TYPE/%ROWTYPE recognized: check for array decoration. (Unreachable + // in this build — the lookups above always return NULL — but kept for + // shape parity.) + isArray := false + tok = c.lex() + if c.tokIsKeyword(tok, K_ARRAY, "array") { + isArray = true + tok = c.lex() + } + for tok == plToken('[') { + isArray = true + tok = c.lex() + if tok == tokICONST { + tok = c.lex() + } + if tok != plToken(']') { + c.scan.yyerror(`syntax error, expected "]"`) + } + tok = c.lex() + } + c.scan.pushBackToken(tok) + if isArray { + result = buildDatatypeArrayof(result) + } + return result + } + + // Not %TYPE or %ROWTYPE: scan to the end of the datatype declaration. + for tok != plToken(';') { + if tok == 0 { + if parenlevel != 0 { + c.scan.yyerror("mismatched parentheses") + } + c.scan.yyerror("incomplete data type declaration") + } + // Possible followers for datatype in a declaration + if tok == K_COLLATE || tok == K_NOT || + tok == plToken('=') || tok == tokCOLON_EQUALS || tok == K_DEFAULT { + break + } + // Possible followers for datatype in a cursor_arg list + if (tok == plToken(',') || tok == plToken(')')) && parenlevel == 0 { + break + } + if tok == plToken('(') { + parenlevel++ + } else if tok == plToken(')') { + parenlevel-- + } + tok = c.lex() + } + + typeName := c.scan.sourceText(startlocation, c.loc()) + if typeName == "" { + c.scan.yyerror("missing data type declaration") + } + + result = parseDatatype(typeName) + + c.scan.pushBackToken(tok) + return result +} + +// parse_datatype — the vendored mock: no core-parser round trip; the type +// name is kept verbatim, with only RECORD/REFCURSOR/CURSOR/TEXT recognized +// by (length-limited, case-insensitive) prefix comparison. +func parseDatatype(s string) *plType { + n := len(s) + for n > 0 && isSpaceByte(s[n-1]) { + n-- + } + typ := &plType{typname: s, ttype: ttypeScalar} + if pgStrncasecmpEqual(s, "RECORD", n) { + typ.ttype = ttypeRec + } + if pgStrncasecmpEqual(s, "REFCURSOR", n) || pgStrncasecmpEqual(s, "CURSOR", n) { + typ.typoid = oidRefcursor + } else if pgStrncasecmpEqual(s, "TEXT", n) { + typ.typoid = oidText + typ.collation = oidDefaultCollation + } + return typ +} + +// pgStrncasecmpEqual is pg_strncasecmp(s, target, n) == 0, with C string +// semantics (target's NUL participates in the comparison). +func pgStrncasecmpEqual(s, target string, n int) bool { + for i := 0; i < n; i++ { + var a, b byte + if i < len(s) { + a = asciiLower(s[i]) + } + if i < len(target) { + b = asciiLower(target[i]) + } + if a != b { + return false + } + if a == 0 { + return true + } + } + return true +} + +func asciiLower(c byte) byte { + if c >= 'A' && c <= 'Z' { + return c + ('a' - 'A') + } + return c +} + +// scanner_isspace (scansup.c). +func isSpaceByte(c byte) bool { + return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' +} + +// make_execsql_stmt (pl_gram.y): read a generic SQL statement, spotting a +// PL/pgSQL INTO clause. +func (c *compiler) makeExecsqlStmt(firsttoken plToken, location int, word *plWord) plStmt { + saveLookup := c.scan.identifierLookup + c.scan.identifierLookup = lookupExpr + + var target plVariable + haveInto := false + haveStrict := false + intoStartLoc := -1 + intoEndLoc := -1 + parenDepth := 0 + beginDepth := 0 + inRoutineDefinition := false + tokenCount := 0 + var tokens [4]byte + + tok := firsttoken + if tok == T_WORD && word != nil && word.ident == "create" { + tokens[tokenCount] = 'c' + } + tokenCount++ + + for { + prevTok := tok + tok = c.lex() + if haveInto && intoEndLoc < 0 { + intoEndLoc = c.loc() // token after the INTO part + } + // Detect CREATE [OR REPLACE] {FUNCTION|PROCEDURE} + if tokens[0] == 'c' && tokenCount < len(tokens) { + if tok == K_OR { + tokens[tokenCount] = 'o' + } else if tok == T_WORD && c.cur().word.ident == "replace" { + tokens[tokenCount] = 'r' + } else if tok == T_WORD && c.cur().word.ident == "function" { + tokens[tokenCount] = 'f' + } else if tok == T_WORD && c.cur().word.ident == "procedure" { + tokens[tokenCount] = 'f' // treat same as "function" + } + if tokens[1] == 'f' || + (tokens[1] == 'o' && tokens[2] == 'r' && tokens[3] == 'f') { + inRoutineDefinition = true + } + tokenCount++ + } + // Track paren nesting (needed for CREATE RULE syntax) + if tok == plToken('(') { + parenDepth++ + } else if tok == plToken(')') && parenDepth > 0 { + parenDepth-- + } + // We need track BEGIN/END nesting only in a routine definition + if inRoutineDefinition && parenDepth == 0 { + if tok == K_BEGIN || tok == K_CASE { + beginDepth++ + } else if tok == K_END && beginDepth > 0 { + beginDepth-- + } + } + // Command-ending semicolon? + if tok == plToken(';') && parenDepth == 0 && beginDepth == 0 { + break + } + if tok == 0 { + c.scan.yyerror("unexpected end of function definition") + } + if tok == K_INTO { + if prevTok == K_INSERT { + continue // INSERT INTO is not an INTO-target + } + if prevTok == K_MERGE { + continue // MERGE INTO is not an INTO-target + } + if firsttoken == K_IMPORT { + continue // IMPORT ... INTO is not an INTO-target + } + if haveInto { + c.scan.yyerror("INTO specified more than once") + } + haveInto = true + intoStartLoc = c.loc() + c.scan.identifierLookup = lookupNormal + target, haveStrict = c.readIntoTarget(true) + c.scan.identifierLookup = lookupExpr + } + } + + c.scan.identifierLookup = saveLookup + + var ds string + if haveInto { + // Insert spaces for the INTO text so locations still line up. + ds = c.scan.sourceText(location, intoStartLoc) + + strings.Repeat(" ", intoEndLoc-intoStartLoc) + + c.scan.sourceText(intoEndLoc, c.loc()) + } else { + ds = c.scan.sourceText(location, c.loc()) + } + + // trim any trailing whitespace, for neatness + for len(ds) > 0 && isSpaceByte(ds[len(ds)-1]) { + ds = ds[:len(ds)-1] + } + + expr := &plExpr{query: ds, parseMode: rawParseDefault} + c.checkSQLExpr(expr.query, expr.parseMode, location) + + execsql := &stmtExecsql{ + sqlstmt: expr, + into: haveInto, + strict: haveStrict, + target: target, + } + execsql.lineno = c.scan.locationToLineno(location) + return execsql +} + +// read_fetch_direction (pl_gram.y). +func (c *compiler) readFetchDirection() *stmtFetch { + fetch := &stmtFetch{ + direction: fetchForward, + howMany: 1, + } + checkFROM := true + + tok := c.lex() + if tok == 0 { + c.scan.yyerror("unexpected end of function definition") + } + + switch { + case c.tokIsKeyword(tok, K_NEXT, "next"): + // use defaults + case c.tokIsKeyword(tok, K_PRIOR, "prior"): + fetch.direction = fetchBackward + case c.tokIsKeyword(tok, K_FIRST, "first"): + fetch.direction = fetchAbsolute + case c.tokIsKeyword(tok, K_LAST, "last"): + fetch.direction = fetchAbsolute + fetch.howMany = -1 + case c.tokIsKeyword(tok, K_ABSOLUTE, "absolute"): + fetch.direction = fetchAbsolute + fetch.expr, _ = c.readSQLExpression2(K_FROM, K_IN, "FROM or IN") + checkFROM = false + case c.tokIsKeyword(tok, K_RELATIVE, "relative"): + fetch.direction = fetchRelative + fetch.expr, _ = c.readSQLExpression2(K_FROM, K_IN, "FROM or IN") + checkFROM = false + case c.tokIsKeyword(tok, K_ALL, "all"): + fetch.howMany = fetchAll + fetch.returnsMultipleRows = true + case c.tokIsKeyword(tok, K_FORWARD, "forward"): + c.completeDirection(fetch, &checkFROM) + case c.tokIsKeyword(tok, K_BACKWARD, "backward"): + fetch.direction = fetchBackward + c.completeDirection(fetch, &checkFROM) + case tok == K_FROM || tok == K_IN: + // empty direction + checkFROM = false + case tok == T_DATUM: + // Assume there's no direction clause and tok is a cursor name + c.scan.pushBackToken(tok) + checkFROM = false + default: + // Assume it's a count expression with no preceding keyword. + c.scan.pushBackToken(tok) + fetch.expr, _ = c.readSQLExpression2(K_FROM, K_IN, "FROM or IN") + fetch.returnsMultipleRows = true + checkFROM = false + } + + if checkFROM { + tok = c.lex() + if tok != K_FROM && tok != K_IN { + c.scan.yyerror("expected FROM or IN") + } + } + + return fetch +} + +// complete_direction (pl_gram.y). +func (c *compiler) completeDirection(fetch *stmtFetch, checkFROM *bool) { + tok := c.lex() + if tok == 0 { + c.scan.yyerror("unexpected end of function definition") + } + if tok == K_FROM || tok == K_IN { + *checkFROM = false + return + } + if tok == K_ALL { + fetch.howMany = fetchAll + fetch.returnsMultipleRows = true + *checkFROM = true + return + } + c.scan.pushBackToken(tok) + fetch.expr, _ = c.readSQLExpression2(K_FROM, K_IN, "FROM or IN") + fetch.returnsMultipleRows = true + *checkFROM = false +} + +// make_return_stmt — the vendored mock: fn_rettype is always VOID here, so +// RETURN takes an optional expression and never captures a variable number. +func (c *compiler) makeReturnStmt(location int) plStmt { + st := &stmtReturn{retvarno: -1} + st.lineno = c.scan.locationToLineno(location) + tok := c.lex() + if tok != plToken(';') { + c.scan.pushBackToken(tok) + st.expr = c.readSQLExpression(plToken(';'), ";") + } + return st +} + +// make_return_next_stmt (pl_gram.y, unmocked). +func (c *compiler) makeReturnNextStmt(location int) plStmt { + if !c.fn.fnRetset { + ereportFn("make_return_next_stmt", "cannot use RETURN NEXT in a non-SETOF function") + } + st := &stmtReturnNext{retvarno: -1} + st.lineno = c.scan.locationToLineno(location) + if c.fn.outParamVarno >= 0 { + if c.lex() != plToken(';') { + ereportFn("make_return_next_stmt", "RETURN NEXT cannot have a parameter in function with OUT parameters") + } + st.retvarno = c.fn.outParamVarno + } else { + tok := c.lex() + if tok == T_DATUM && c.scan.peek() == plToken(';') && + isSimpleReturnDatum(c.cur().wdatum.datum) { + st.retvarno = c.cur().wdatum.datum.datumNo() + c.lex() // eat the semicolon token that we only peeked at above + } else { + c.scan.pushBackToken(tok) + st.expr = c.readSQLExpression(plToken(';'), ";") + } + } + return st +} + +func isSimpleReturnDatum(d datum) bool { + switch d.datumType() { + case dtypeVar, dtypePromise, dtypeRow, dtypeRec: + return true + } + return false +} + +// make_return_query_stmt (pl_gram.y). +func (c *compiler) makeReturnQueryStmt(location int) plStmt { + if !c.fn.fnRetset { + ereportFn("make_return_query_stmt", "cannot use RETURN QUERY in a non-SETOF function") + } + st := &stmtReturnQuery{} + st.lineno = c.scan.locationToLineno(location) + + if tok := c.lex(); tok != K_EXECUTE { + c.scan.pushBackToken(tok) + st.query = c.readSQLStmt() + } else { + var term plToken + st.dynquery, term = c.readSQLExpression2(plToken(';'), K_USING, "; or USING") + if term == K_USING { + for { + expr, t := c.readSQLExpression2(plToken(','), plToken(';'), ", or ;") + st.params = append(st.params, expr) + if t != plToken(',') { + break + } + } + } + } + return st +} + +// NameOfDatum (pl_gram.y). +func nameOfDatum(w *plWdatum) string { + if w.ident != "" { + return w.ident + } + return nameListToString(w.idents) +} + +// check_assignable (pl_gram.y). +func (c *compiler) checkAssignable(d datum) { + switch d.datumType() { + case dtypeVar, dtypePromise, dtypeRec: + v := d.(plVariable) + if v.varIsConst() { + ereportFn("check_assignable", `variable "%s" is declared CONSTANT`, v.varRefname()) + } + case dtypeRow: + // always assignable; member vars were checked at compile time + case dtypeRecfield: + // assignable if parent record is + c.checkAssignable(c.datums[d.(*plRecfield).recparentno]) + } +} + +// read_into_target (pl_gram.y). wantStrict selects whether STRICT is legal +// (the C signature's strict != NULL). +func (c *compiler) readIntoTarget(wantStrict bool) (target plVariable, strict bool) { + tok := c.lex() + if wantStrict && tok == K_STRICT { + strict = true + tok = c.lex() + } + + switch tok { + case T_DATUM: + w := c.cur().wdatum + if w.datum.datumType() == dtypeRow || w.datum.datumType() == dtypeRec { + c.checkAssignable(w.datum) + target = w.datum.(plVariable) + if tok = c.lex(); tok == plToken(',') { + c.ereportGram("record variable cannot be part of multiple-item INTO list") + } + c.scan.pushBackToken(tok) + } else { + target = c.readIntoScalarList(nameOfDatum(&w), w.datum, c.loc()) + } + default: + // just to give a better message than "syntax error" + c.currentTokenIsNotVariable(tok) + } + return target, strict +} + +// read_into_scalar_list (pl_gram.y). +func (c *compiler) readIntoScalarList(initialName string, initialDatum datum, initialLocation int) *plRow { + c.checkAssignable(initialDatum) + fieldnames := []string{initialName} + varnos := []int{initialDatum.datumNo()} + + var tok plToken + for { + tok = c.lex() + if tok != plToken(',') { + break + } + if len(fieldnames) >= 1024 { + c.ereportGram("too many INTO variables specified") + } + tok = c.lex() + switch tok { + case T_DATUM: + w := c.cur().wdatum + c.checkAssignable(w.datum) + if w.datum.datumType() == dtypeRow || w.datum.datumType() == dtypeRec { + c.ereportGram(`"%s" is not a scalar variable`, nameOfDatum(&w)) + } + fieldnames = append(fieldnames, nameOfDatum(&w)) + varnos = append(varnos, w.datum.datumNo()) + default: + c.currentTokenIsNotVariable(tok) + } + } + c.scan.pushBackToken(tok) + + row := &plRow{ + refname: "(unnamed row)", + lineno: c.scan.locationToLineno(initialLocation), + fieldnames: fieldnames, + varnos: varnos, + } + c.addDatum(row) + return row +} + +// make_scalar_list1 (pl_gram.y). +func (c *compiler) makeScalarList1(initialName string, initialDatum datum, lineno int) *plRow { + c.checkAssignable(initialDatum) + row := &plRow{ + refname: "(unnamed row)", + lineno: lineno, + fieldnames: []string{initialName}, + varnos: []int{initialDatum.datumNo()}, + } + c.addDatum(row) + return row +} + +// check_sql_expr (pl_gram.y): run the embedded SQL through the main parser. +// On failure, plpgsql_sql_error_callback flushes the external error cursor +// (only an internal one is kept), so the reported error loses its position +// but keeps message/filename/funcname. +func (c *compiler) checkSQLExpr(stmt string, parseMode rawParseMode, location int) { + if !c.checkSyntax { + return + } + var mode parse.Mode + switch parseMode { + case rawParsePlpgsqlExpr: + mode = parse.ModePlpgsqlExpr + case rawParsePlpgsqlAssign1: + mode = parse.ModePlpgsqlAssign1 + case rawParsePlpgsqlAssign2: + mode = parse.ModePlpgsqlAssign2 + case rawParsePlpgsqlAssign3: + mode = parse.ModePlpgsqlAssign3 + default: + mode = parse.ModeDefault + } + if _, err := parse.ParseWithMode(stmt, mode); err != nil { + panic(&compileError{ + Message: err.Message, + Filename: err.Filename, + Funcname: err.Funcname, + }) + } +} + +// check_labels (pl_gram.y). +func checkLabels(startLabel, endLabel string) { + if endLabel != "" { + if startLabel == "" { + ereportFn("check_labels", `end label "%s" specified for unlabeled block`, endLabel) + } + if startLabel != endLabel { + ereportFn("check_labels", `end label "%s" differs from block's label "%s"`, endLabel, startLabel) + } + } +} + +// read_cursor_args (pl_gram.y). +func (c *compiler) readCursorArgs(cursor *plVar, until plToken) *plExpr { + tok := c.lex() + if cursor.cursorExplicitArgrow < 0 { + // No arguments expected + if tok == plToken('(') { + c.ereportGram(`cursor "%s" has no arguments`, cursor.refname) + } + if tok != until { + c.scan.yyerror("syntax error") + } + return nil + } + + // Else better provide arguments + if tok != plToken('(') { + c.ereportGram(`cursor "%s" has arguments`, cursor.refname) + } + + row := c.datums[cursor.cursorExplicitArgrow].(*plRow) + argv := make([]string, len(row.fieldnames)) + filled := make([]bool, len(row.fieldnames)) + anyNamed := false + + for argc := 0; argc < len(row.fieldnames); argc++ { + argpos := argc + + // Check if it's a named parameter: "param := value" + tok1, tok2, _, _ := c.scan.peek2() + if tok1 == tokIDENT && tok2 == tokCOLON_EQUALS { + // Read the argument name, ignoring any matching variable + saveLookup := c.scan.identifierLookup + c.scan.identifierLookup = lookupDeclare + c.lex() + argname := c.cur().str + c.scan.identifierLookup = saveLookup + + // Match argument name to cursor arguments + argpos = -1 + for i, fn := range row.fieldnames { + if fn == argname { + argpos = i + break + } + } + if argpos < 0 { + c.ereportGram(`cursor "%s" has no argument named "%s"`, cursor.refname, argname) + } + + // Eat the ":=". + if c.lex() != tokCOLON_EQUALS { + c.scan.yyerror("syntax error") + } + + anyNamed = true + } + + if filled[argpos] { + c.ereportGram(`value for parameter "%s" of cursor "%s" specified more than once`, + row.fieldnames[argpos], cursor.refname) + } + + item, endtoken := c.readSQLConstruct(plToken(','), plToken(')'), 0, + ",\" or \")", rawParsePlpgsqlExpr, true, true, nil) + + argv[argpos] = item.query + filled[argpos] = true + + if endtoken == plToken(')') && argc != len(row.fieldnames)-1 { + c.ereportGram(`not enough arguments for cursor "%s"`, cursor.refname) + } + if endtoken == plToken(',') && argc == len(row.fieldnames)-1 { + c.ereportGram(`too many arguments for cursor "%s"`, cursor.refname) + } + } + + // Make positional argument list + var ds strings.Builder + for argc := 0; argc < len(row.fieldnames); argc++ { + ds.WriteString(argv[argc]) + if anyNamed { + ds.WriteString(" AS " + deparse.QuoteIdentifier(row.fieldnames[argc])) + } + if argc < len(row.fieldnames)-1 { + ds.WriteString(", ") + } + } + + expr := &plExpr{query: ds.String(), parseMode: rawParsePlpgsqlExpr} + + // Next we'd better find the until token + if c.lex() != until { + c.scan.yyerror("syntax error") + } + + return expr +} + +// read_raise_options (pl_gram.y). +func (c *compiler) readRaiseOptions() []*raiseOption { + var result []*raiseOption + for { + tok := c.lex() + if tok == 0 { + c.scan.yyerror("unexpected end of function definition") + } + + opt := &raiseOption{} + switch { + case c.tokIsKeyword(tok, K_ERRCODE, "errcode"): + opt.optType = raiseOptionErrcode + case c.tokIsKeyword(tok, K_MESSAGE, "message"): + opt.optType = raiseOptionMessage + case c.tokIsKeyword(tok, K_DETAIL, "detail"): + opt.optType = raiseOptionDetail + case c.tokIsKeyword(tok, K_HINT, "hint"): + opt.optType = raiseOptionHint + case c.tokIsKeyword(tok, K_COLUMN, "column"): + opt.optType = raiseOptionColumn + case c.tokIsKeyword(tok, K_CONSTRAINT, "constraint"): + opt.optType = raiseOptionConstraint + case c.tokIsKeyword(tok, K_DATATYPE, "datatype"): + opt.optType = raiseOptionDatatype + case c.tokIsKeyword(tok, K_TABLE, "table"): + opt.optType = raiseOptionTable + case c.tokIsKeyword(tok, K_SCHEMA, "schema"): + opt.optType = raiseOptionSchema + default: + c.scan.yyerror("unrecognized RAISE statement option") + } + + tok = c.lex() + if tok != plToken('=') && tok != tokCOLON_EQUALS { + c.scan.yyerror(`syntax error, expected "="`) + } + + var endTok plToken + opt.expr, endTok = c.readSQLExpression2(plToken(','), plToken(';'), ", or ;") + + result = append(result, opt) + + if endTok == plToken(';') { + break + } + } + return result +} + +// check_raise_parameters (pl_gram.y). +func checkRaiseParameters(st *stmtRaise) { + if !st.hasMessage { + return + } + expected := 0 + msg := st.message + for i := 0; i < len(msg); i++ { + if msg[i] == '%' { + if i+1 < len(msg) && msg[i+1] == '%' { + i++ + } else { + expected++ + } + } + } + if expected < len(st.params) { + ereportFn("check_raise_parameters", "too many parameters specified for RAISE") + } + if expected > len(st.params) { + ereportFn("check_raise_parameters", "too few parameters specified for RAISE") + } +} + +// make_case (pl_gram.y). +func (c *compiler) makeCase(location int, tExpr *plExpr, caseWhenList []*caseWhen, elseStmts []plStmt) plStmt { + st := &stmtCase{ + tExpr: tExpr, + caseWhenList: caseWhenList, + haveElse: elseStmts != nil, + } + st.lineno = c.scan.locationToLineno(location) + // Get rid of list-with-NULL hack + if len(elseStmts) == 1 && elseStmts[0] == nil { + st.elseStmts = nil + } else { + st.elseStmts = elseStmts + } + + if tExpr != nil { + // use a name unlikely to collide with any user names + varname := fmt.Sprintf("__Case__Variable_%d__", len(c.datums)) + + tVar := c.buildVariable(varname, st.lineno, + buildDatatype(oidInt4, -1, 0, nil), true).(*plVar) + st.tVarno = tVar.dno + + for _, cwt := range caseWhenList { + expr := cwt.expr + expr.query = fmt.Sprintf(`"%s" IN (%s)`, varname, expr.query) + } + } + + return st +} diff --git a/internal/plpgsql/json.go b/internal/plpgsql/json.go new file mode 100644 index 0000000..d384751 --- /dev/null +++ b/internal/plpgsql/json.go @@ -0,0 +1,456 @@ +package plpgsql + +import ( + "fmt" + "strings" + + "github.com/sqlc-dev/oliphant/internal/emit" +) + +// Port of pg_query_json_plpgsql.c: the hand-rolled JSON dump of a compiled +// function. Field order, zero-suppression, and the trailing-delimiter dance +// are the C macros' exactly; strings escape through the same _outToken as +// the parse-tree emitter. + +type jbuf struct { + b strings.Builder +} + +func (j *jbuf) s(s string) { j.b.WriteString(s) } +func (j *jbuf) c(c byte) { j.b.WriteByte(c) } +func (j *jbuf) tok(s string) { emit.Token(&j.b, s) } + +// removeTrailingDelimiter is the helper from pg_query_json_helper.c. +func (j *jbuf) removeTrailingDelimiter() { + s := j.b.String() + if len(s) > 0 && s[len(s)-1] == ',' { + j.b.Reset() + j.b.WriteString(s[:len(s)-1]) + } +} + +func (j *jbuf) nodeType(label string) { j.s(`"` + label + `":{`) } + +func (j *jbuf) intField(name string, v int) { + if v != 0 { + fmt.Fprintf(&j.b, `"%s":%d,`, name, v) + } +} + +func (j *jbuf) longField(name string, v int64) { + if v != 0 { + fmt.Fprintf(&j.b, `"%s":%d,`, name, v) + } +} + +func (j *jbuf) enumField(name string, v int) { + fmt.Fprintf(&j.b, `"%s":%d,`, name, v) +} + +func (j *jbuf) boolField(name string, v bool) { + if v { + j.s(`"` + name + `":true,`) + } +} + +func (j *jbuf) stringField(name, v string) { + j.s(`"` + name + `":`) + j.tok(v) + j.s(",") +} + +// objField is WRITE_OBJ_FIELD: `"name":{` + dump + `}},`. +func (j *jbuf) objField(name string, dump func()) { + j.s(`"` + name + `":{`) + dump() + j.removeTrailingDelimiter() + j.s("}},") +} + +func (j *jbuf) exprField(name string, e *plExpr) { + if e != nil { + j.objField(name, func() { j.dumpExpr(e) }) + } +} + +func (j *jbuf) variableField(name string, v plVariable) { + if v != nil { + j.objField(name, func() { j.dumpVariable(v) }) + } +} + +// stmtsField is WRITE_STATEMENTS_FIELD. +func (j *jbuf) stmtsField(name string, stmts []plStmt) { + if len(stmts) == 0 { + return + } + j.s(`"` + name + `":[`) + for _, st := range stmts { + j.dumpStmt(st) + } + j.removeTrailingDelimiter() + j.s("],") +} + +// listField is WRITE_LIST_FIELD. +func listField[T any](j *jbuf, name string, items []T, dump func(T)) { + if len(items) == 0 { + return + } + j.s(`"` + name + `":[`) + for _, it := range items { + j.s("{") + dump(it) + j.removeTrailingDelimiter() + j.s("}},") + } + j.removeTrailingDelimiter() + j.s("],") +} + +func (j *jbuf) dumpStmt(st plStmt) { + j.c('{') + switch v := st.(type) { + case *stmtBlock: + j.dumpBlock(v) + case *stmtAssign: + j.nodeType("PLpgSQL_stmt_assign") + j.intField("lineno", v.lineno) + j.intField("varno", v.varno) + j.exprField("expr", v.expr) + case *stmtIf: + j.nodeType("PLpgSQL_stmt_if") + j.intField("lineno", v.lineno) + j.exprField("cond", v.cond) + j.stmtsField("then_body", v.thenBody) + listField(j, "elsif_list", v.elsifList, func(e *ifElsif) { + j.nodeType("PLpgSQL_if_elsif") + j.intField("lineno", e.lineno) + j.exprField("cond", e.cond) + j.stmtsField("stmts", e.stmts) + }) + j.stmtsField("else_body", v.elseBody) + case *stmtCase: + j.nodeType("PLpgSQL_stmt_case") + j.intField("lineno", v.lineno) + j.exprField("t_expr", v.tExpr) + j.intField("t_varno", v.tVarno) + listField(j, "case_when_list", v.caseWhenList, func(w *caseWhen) { + j.nodeType("PLpgSQL_case_when") + j.intField("lineno", w.lineno) + j.exprField("expr", w.expr) + j.stmtsField("stmts", w.stmts) + }) + j.boolField("have_else", v.haveElse) + j.stmtsField("else_stmts", v.elseStmts) + case *stmtLoop: + j.nodeType("PLpgSQL_stmt_loop") + j.intField("lineno", v.lineno) + j.labelField(v.label) + j.stmtsField("body", v.body) + case *stmtWhile: + j.nodeType("PLpgSQL_stmt_while") + j.intField("lineno", v.lineno) + j.labelField(v.label) + j.exprField("cond", v.cond) + j.stmtsField("body", v.body) + case *stmtFori: + j.nodeType("PLpgSQL_stmt_fori") + j.intField("lineno", v.lineno) + j.labelField(v.label) + if v.varDat != nil { + j.objField("var", func() { j.dumpVar(v.varDat) }) + } + j.exprField("lower", v.lower) + j.exprField("upper", v.upper) + j.exprField("step", v.step) + j.boolField("reverse", v.reverse) + j.stmtsField("body", v.body) + case *stmtFors: + j.nodeType("PLpgSQL_stmt_fors") + j.intField("lineno", v.lineno) + j.labelField(v.label) + j.variableField("var", v.varDat) + j.stmtsField("body", v.body) + j.exprField("query", v.query) + case *stmtForc: + j.nodeType("PLpgSQL_stmt_forc") + j.intField("lineno", v.lineno) + j.labelField(v.label) + j.variableField("var", v.varDat) + j.stmtsField("body", v.body) + j.intField("curvar", v.curvar) + j.exprField("argquery", v.argquery) + case *stmtDynfors: + j.nodeType("PLpgSQL_stmt_dynfors") + j.intField("lineno", v.lineno) + j.labelField(v.label) + j.variableField("var", v.varDat) + j.stmtsField("body", v.body) + j.exprField("query", v.query) + listField(j, "params", v.params, func(e *plExpr) { j.dumpExpr(e) }) + case *stmtForeachA: + j.nodeType("PLpgSQL_stmt_foreach_a") + j.intField("lineno", v.lineno) + j.labelField(v.label) + j.intField("varno", v.varno) + j.intField("slice", v.slice) + j.exprField("expr", v.expr) + j.stmtsField("body", v.body) + case *stmtExit: + j.nodeType("PLpgSQL_stmt_exit") + j.intField("lineno", v.lineno) + j.boolField("is_exit", v.isExit) + j.labelField(v.label) + j.exprField("cond", v.cond) + case *stmtReturn: + j.nodeType("PLpgSQL_stmt_return") + j.intField("lineno", v.lineno) + j.exprField("expr", v.expr) + case *stmtReturnNext: + j.nodeType("PLpgSQL_stmt_return_next") + j.intField("lineno", v.lineno) + j.exprField("expr", v.expr) + case *stmtReturnQuery: + j.nodeType("PLpgSQL_stmt_return_query") + j.intField("lineno", v.lineno) + j.exprField("query", v.query) + j.exprField("dynquery", v.dynquery) + listField(j, "params", v.params, func(e *plExpr) { j.dumpExpr(e) }) + case *stmtRaise: + j.nodeType("PLpgSQL_stmt_raise") + j.intField("lineno", v.lineno) + j.intField("elog_level", v.elogLevel) + if v.condname != "" { + j.stringField("condname", v.condname) + } + if v.hasMessage { + j.stringField("message", v.message) + } + listField(j, "params", v.params, func(e *plExpr) { j.dumpExpr(e) }) + listField(j, "options", v.options, func(o *raiseOption) { + j.nodeType("PLpgSQL_raise_option") + j.enumField("opt_type", int(o.optType)) + j.exprField("expr", o.expr) + }) + case *stmtAssert: + j.nodeType("PLpgSQL_stmt_assert") + j.intField("lineno", v.lineno) + j.exprField("cond", v.cond) + j.exprField("message", v.message) + case *stmtExecsql: + j.nodeType("PLpgSQL_stmt_execsql") + j.intField("lineno", v.lineno) + j.exprField("sqlstmt", v.sqlstmt) + j.boolField("into", v.into) + j.boolField("strict", v.strict) + j.variableField("target", v.target) + case *stmtDynexecute: + j.nodeType("PLpgSQL_stmt_dynexecute") + j.intField("lineno", v.lineno) + j.exprField("query", v.query) + j.boolField("into", v.into) + j.boolField("strict", v.strict) + j.variableField("target", v.target) + listField(j, "params", v.params, func(e *plExpr) { j.dumpExpr(e) }) + case *stmtGetdiag: + j.nodeType("PLpgSQL_stmt_getdiag") + j.intField("lineno", v.lineno) + j.boolField("is_stacked", v.isStacked) + listField(j, "diag_items", v.diagItems, func(d *diagItem) { + j.nodeType("PLpgSQL_diag_item") + j.stringField("kind", getdiagKindname(d.kind)) + j.intField("target", d.target) + }) + case *stmtOpen: + j.nodeType("PLpgSQL_stmt_open") + j.intField("lineno", v.lineno) + j.intField("curvar", v.curvar) + j.intField("cursor_options", v.cursorOptions) + j.exprField("argquery", v.argquery) + j.exprField("query", v.query) + j.exprField("dynquery", v.dynquery) + listField(j, "params", v.params, func(e *plExpr) { j.dumpExpr(e) }) + case *stmtFetch: + j.nodeType("PLpgSQL_stmt_fetch") + j.intField("lineno", v.lineno) + j.variableField("target", v.target) + j.intField("curvar", v.curvar) + j.enumField("direction", int(v.direction)) + j.longField("how_many", v.howMany) + j.exprField("expr", v.expr) + j.boolField("is_move", v.isMove) + j.boolField("returns_multiple_rows", v.returnsMultipleRows) + case *stmtClose: + j.nodeType("PLpgSQL_stmt_close") + j.intField("lineno", v.lineno) + j.intField("curvar", v.curvar) + case *stmtPerform: + j.nodeType("PLpgSQL_stmt_perform") + j.intField("lineno", v.lineno) + j.exprField("expr", v.expr) + case *stmtCall: + j.nodeType("PLpgSQL_stmt_call") + j.intField("lineno", v.lineno) + j.exprField("expr", v.expr) + j.boolField("is_call", v.isCall) + j.variableField("target", v.target) + case *stmtCommit: + j.nodeType("PLpgSQL_stmt_commit") + j.intField("lineno", v.lineno) + j.boolField("chain", v.chain) + case *stmtRollback: + j.nodeType("PLpgSQL_stmt_rollback") + j.intField("lineno", v.lineno) + j.boolField("chain", v.chain) + } + j.removeTrailingDelimiter() + j.s("}},") +} + +// labelField is WRITE_STRING_FIELD(label): NULL labels ("" here) are omitted. +func (j *jbuf) labelField(label string) { + if label != "" { + j.stringField("label", label) + } +} + +func (j *jbuf) dumpBlock(v *stmtBlock) { + j.nodeType("PLpgSQL_stmt_block") + j.intField("lineno", v.lineno) + j.labelField(v.label) + j.stmtsField("body", v.body) + if v.exceptions != nil { + j.objField("exceptions", func() { + j.nodeType("PLpgSQL_exception_block") + listField(j, "exc_list", v.exceptions.excList, func(e *plException) { + j.nodeType("PLpgSQL_exception") + j.s(`"conditions":[`) + for cond := e.conditions; cond != nil; cond = cond.next { + j.s("{") + j.nodeType("PLpgSQL_condition") + if cond.condname != "" { + j.stringField("condname", cond.condname) + } + j.removeTrailingDelimiter() + j.s("}},") + } + j.removeTrailingDelimiter() + j.s("],") + j.stmtsField("action", e.action) + }) + }) + } + j.removeTrailingDelimiter() +} + +func (j *jbuf) dumpExpr(e *plExpr) { + j.nodeType("PLpgSQL_expr") + j.stringField("query", e.query) + j.enumField("parseMode", int(e.parseMode)) +} + +func (j *jbuf) dumpVariable(v plVariable) { + switch d := v.(type) { + case *plRec: + j.dumpRecord(d) + case *plVar: + j.dumpVar(d) + case *plRow: + j.dumpRow(d) + } +} + +func (j *jbuf) dumpType(t *plType) { + j.nodeType("PLpgSQL_type") + if t.typname != "" { + j.stringField("typname", t.typname) + } +} + +func (j *jbuf) dumpVar(v *plVar) { + j.nodeType("PLpgSQL_var") + j.stringField("refname", v.refname) + j.intField("lineno", v.lineno) + if v.datatype != nil { + j.objField("datatype", func() { j.dumpType(v.datatype) }) + } + j.boolField("isconst", v.isconst) + j.boolField("notnull", v.notnull) + j.exprField("default_val", v.defaultVal) + j.exprField("cursor_explicit_expr", v.cursorExplicitExpr) + j.intField("cursor_explicit_argrow", v.cursorExplicitArgrow) + j.intField("cursor_options", v.cursorOptions) +} + +func (j *jbuf) dumpRow(v *plRow) { + j.nodeType("PLpgSQL_row") + j.stringField("refname", v.refname) + j.intField("lineno", v.lineno) + j.s(`"fields":`) + j.c('[') + for i := range v.fieldnames { + if v.fieldnames[i] != "" { + j.c('{') + j.stringField("name", v.fieldnames[i]) + j.intField("varno", v.varnos[i]) + j.removeTrailingDelimiter() + j.s("},") + } else { + j.s("null,") + } + } + j.removeTrailingDelimiter() + j.s("],") +} + +func (j *jbuf) dumpRecord(v *plRec) { + j.nodeType("PLpgSQL_rec") + j.stringField("refname", v.refname) + j.intField("dno", v.dno) + j.intField("lineno", v.lineno) +} + +func (j *jbuf) dumpRecordField(v *plRecfield) { + j.nodeType("PLpgSQL_recfield") + j.stringField("fieldname", v.fieldname) + j.intField("recparentno", v.recparentno) +} + +// toJSON is plpgsqlToJSON. +func toJSON(fn *plFunction) string { + j := &jbuf{} + j.c('{') + + j.nodeType("PLpgSQL_function") + j.intField("new_varno", fn.newVarno) + j.intField("old_varno", fn.oldVarno) + + j.s(`"datums":`) + j.c('[') + for _, d := range fn.datums { + j.c('{') + switch v := d.(type) { + case *plVar: + j.dumpVar(v) + case *plRow: + j.dumpRow(v) + case *plRec: + j.dumpRecord(v) + case *plRecfield: + j.dumpRecordField(v) + } + j.removeTrailingDelimiter() + j.s("}},") + } + j.removeTrailingDelimiter() + j.s("],") + + if fn.action != nil { + j.objField("action", func() { j.dumpBlock(fn.action) }) + } + + j.removeTrailingDelimiter() + j.s("}}") + return j.b.String() +} diff --git a/internal/plpgsql/scanner.go b/internal/plpgsql/scanner.go new file mode 100644 index 0000000..f737efe --- /dev/null +++ b/internal/plpgsql/scanner.go @@ -0,0 +1,513 @@ +package plpgsql + +import ( + "strings" + + "github.com/sqlc-dev/oliphant/ast" + "github.com/sqlc-dev/oliphant/internal/lexer" +) + +// plToken is a token code as pl_gram.y sees it: single characters are their +// byte values, core-lexer tokens keep the bison numbers of the pinned SQL +// grammar (the ast.Token values), and the PL-specific tokens (T_WORD, +// T_CWORD, T_DATUM, LESS_LESS, GREATER_GREATER, and the K_* keywords) get +// codes far above that range. +type plToken int32 + +const ( + tokEOF = plToken(0) + tokIDENT = plToken(ast.Token_IDENT) + tokUIDENT = plToken(ast.Token_UIDENT) + tokFCONST = plToken(ast.Token_FCONST) + tokSCONST = plToken(ast.Token_SCONST) + tokUSCONST = plToken(ast.Token_USCONST) + tokBCONST = plToken(ast.Token_BCONST) + tokXCONST = plToken(ast.Token_XCONST) + tokOp = plToken(ast.Token_Op) + tokICONST = plToken(ast.Token_ICONST) + tokPARAM = plToken(ast.Token_PARAM) + tokTYPECAST = plToken(ast.Token_TYPECAST) + tokDOT_DOT = plToken(ast.Token_DOT_DOT) + tokCOLON_EQUALS = plToken(ast.Token_COLON_EQUALS) +) + +// pl_gram.y token declarations (the PL-specific ones). +const ( + T_WORD plToken = 20000 + iota + T_CWORD + T_DATUM + LESS_LESS + GREATER_GREATER + K_ABSOLUTE + K_ALIAS + K_ALL + K_AND + K_ARRAY + K_ASSERT + K_BACKWARD + K_BEGIN + K_BY + K_CALL + K_CASE + K_CHAIN + K_CLOSE + K_COLLATE + K_COLUMN + K_COLUMN_NAME + K_COMMIT + K_CONSTANT + K_CONSTRAINT + K_CONSTRAINT_NAME + K_CONTINUE + K_CURRENT + K_CURSOR + K_DATATYPE + K_DEBUG + K_DECLARE + K_DEFAULT + K_DETAIL + K_DIAGNOSTICS + K_DO + K_DUMP + K_ELSE + K_ELSIF + K_END + K_ERRCODE + K_ERROR + K_EXCEPTION + K_EXECUTE + K_EXIT + K_FETCH + K_FIRST + K_FOR + K_FOREACH + K_FORWARD + K_FROM + K_GET + K_HINT + K_IF + K_IMPORT + K_IN + K_INFO + K_INSERT + K_INTO + K_IS + K_LAST + K_LOG + K_LOOP + K_MERGE + K_MESSAGE + K_MESSAGE_TEXT + K_MOVE + K_NEXT + K_NO + K_NOT + K_NOTICE + K_NULL + K_OPEN + K_OPTION + K_OR + K_PERFORM + K_PG_CONTEXT + K_PG_DATATYPE_NAME + K_PG_EXCEPTION_CONTEXT + K_PG_EXCEPTION_DETAIL + K_PG_EXCEPTION_HINT + K_PG_ROUTINE_OID + K_PRINT_STRICT_PARAMS + K_PRIOR + K_QUERY + K_RAISE + K_RELATIVE + K_RETURN + K_RETURNED_SQLSTATE + K_REVERSE + K_ROLLBACK + K_ROW_COUNT + K_ROWTYPE + K_SCHEMA + K_SCHEMA_NAME + K_SCROLL + K_SLICE + K_SQLSTATE + K_STACKED + K_STRICT + K_TABLE + K_TABLE_NAME + K_THEN + K_TO + K_TYPE + K_USE_COLUMN + K_USE_VARIABLE + K_USING + K_VARIABLE_CONFLICT + K_WARNING + K_WHEN + K_WHILE +) + +// IdentifierLookup modes (plpgsql.h). +type identifierLookup int + +const ( + lookupNormal identifierLookup = iota + lookupDeclare + lookupExpr +) + +// plWord / plCword / plWdatum are PLword / PLcword / PLwdatum. +type plWord struct { + ident string + quoted bool +} + +type plWdatum struct { + datum datum + ident string + quoted bool + idents []string +} + +// tokenAux carries one token plus its auxiliary data (TokenAuxData: the +// YYSTYPE union collapses to a struct here; str doubles as the union's +// leading char* member, so it stays filled alongside word/keyword). +type tokenAux struct { + tok plToken + lloc int + leng int + + str string + ival int32 + keyword string + word plWord + cword []string + wdatum plWdatum +} + +// plScanner is pl_scanner.c's state: the core scanner (initialized with the +// PL reserved keyword list — modeled by re-classifying the SQL lexer's +// output), the pushback stack, and the location-to-lineno tracker. +type plScanner struct { + src string + core *lexer.Scanner + + identifierLookup identifierLookup + + cur tokenAux // token last returned by yylex (yylval/yylloc/yyleng/yytoken) + + pushback []tokenAux + + curLineStart int + curLineEnd int // byte index of the next '\n', or -1 + curLineNum int + + comp *compiler // for plpgsql_parse_word and friends +} + +// newScanner is plpgsql_scanner_init. +func newScanner(src string, comp *compiler) *plScanner { + core := lexer.New(src) + s := &plScanner{ + src: core.Input(), + core: core, + identifierLookup: lookupNormal, + comp: comp, + } + s.locationLinenoInit() + return s +} + +// internalYylex wraps the core lexer: pushback stack, the << >> # operator +// translations, PARAM-as-text, and comment-token skipping. The keyword +// re-classification models scanner_init with ReservedPLKeywords: SQL +// keywords come back as plain identifiers unless they are PL-reserved. +func (s *plScanner) internalYylex(aux *tokenAux) plToken { + if n := len(s.pushback); n > 0 { + *aux = s.pushback[n-1] + s.pushback = s.pushback[:n-1] + return aux.tok + } + + tok, lerr := s.core.Next() + if lerr != nil { + // A core-scanner ereport (scan.l): external error position, reported + // through the compile error path with context attached. + panic(&compileError{ + Message: lerr.Message, + Filename: lerr.Filename, + Funcname: lerr.Funcname, + Cursorpos: lerr.Cursorpos, + }) + } + + *aux = tokenAux{ + tok: plToken(tok.Kind), + lloc: int(tok.Start), + leng: int(tok.End - tok.Start), + str: tok.Str, + ival: tok.Ival, + } + + switch { + case tok.Kind == 0: + aux.tok = tokEOF + + case tok.Kind == ast.Token_SQL_COMMENT || tok.Kind == ast.Token_C_COMMENT: + return s.internalYylex(aux) + + case tok.Kind == ast.Token_Op: + // Check for << >> and #, which the core considers operators. + switch tok.Str { + case "<<": + aux.tok = LESS_LESS + case ">>": + aux.tok = GREATER_GREATER + case "#": + aux.tok = plToken('#') + } + + case tok.Kind == ast.Token_PARAM: + // The core returns PARAM as ival, but we treat it like IDENT. + aux.str = s.src[tok.Start:tok.End] + + case tok.KeywordKind != ast.KeywordKind_NO_KEYWORD: + // A keyword of the SQL scanner. With the PL reserved list installed + // instead, all of these lex as plain identifiers — except the ones + // that are PL-reserved, and the n'...' NCHAR special (which falls + // back to a 1-byte IDENT "n" when "nchar" is not in the list). + if int(tok.End-tok.Start) != len(tok.Str) && tok.Str == "nchar" { + aux.tok = tokIDENT + aux.str = "n" + break + } + if kw, ok := reservedKeywords[tok.Str]; ok { + aux.tok = kw + aux.keyword = tok.Str + break + } + aux.tok = tokIDENT + + case tok.Kind == ast.Token_IDENT: + // Unquoted identifiers can still match PL-reserved words the SQL + // scanner has no keyword for (LOOP, FOREACH, WHILE, ...). + if s.src[tok.Start] != '"' { + if kw, ok := reservedKeywords[tok.Str]; ok { + aux.tok = kw + aux.keyword = tok.Str + } + } + } + + return aux.tok +} + +// pushBackTokenAux is push_back_token. +func (s *plScanner) pushBackTokenAux(tok plToken, aux *tokenAux) { + a := *aux + a.tok = tok + s.pushback = append(s.pushback, a) +} + +// pushBackToken is plpgsql_push_back_token: re-queue the current token. +func (s *plScanner) pushBackToken(tok plToken) { + s.pushBackTokenAux(tok, &s.cur) +} + +// yylex is plpgsql_yylex: compose A.B.C identifiers and classify them as +// T_DATUM / T_CWORD / T_WORD / unreserved keyword. +func (s *plScanner) yylex() plToken { + var aux1 tokenAux + tok1 := s.internalYylex(&aux1) + if tok1 == tokIDENT || tok1 == tokPARAM { + var aux2 tokenAux + tok2 := s.internalYylex(&aux2) + if tok2 == plToken('.') { + var aux3 tokenAux + tok3 := s.internalYylex(&aux3) + if tok3 == tokIDENT { + var aux4 tokenAux + tok4 := s.internalYylex(&aux4) + if tok4 == plToken('.') { + var aux5 tokenAux + tok5 := s.internalYylex(&aux5) + if tok5 == tokIDENT { + if s.comp.parseTripword(aux1.str, aux3.str, aux5.str, &aux1.wdatum, &aux1.cword) { + tok1 = T_DATUM + } else { + tok1 = T_CWORD + } + // Adjust token length to include A.B.C + aux1.leng = aux5.lloc - aux1.lloc + aux5.leng + } else { + // not A.B.C, so just process A.B + s.pushBackTokenAux(tok5, &aux5) + s.pushBackTokenAux(tok4, &aux4) + if s.comp.parseDblword(aux1.str, aux3.str, &aux1.wdatum, &aux1.cword) { + tok1 = T_DATUM + } else { + tok1 = T_CWORD + } + aux1.leng = aux3.lloc - aux1.lloc + aux3.leng + } + } else { + // not A.B.C, so just process A.B + s.pushBackTokenAux(tok4, &aux4) + if s.comp.parseDblword(aux1.str, aux3.str, &aux1.wdatum, &aux1.cword) { + tok1 = T_DATUM + } else { + tok1 = T_CWORD + } + aux1.leng = aux3.lloc - aux1.lloc + aux3.leng + } + } else { + // not A.B, so just process A + s.pushBackTokenAux(tok3, &aux3) + s.pushBackTokenAux(tok2, &aux2) + if s.comp.parseWord(aux1.str, s.quotedAt(aux1.lloc), true, &aux1.wdatum, &aux1.word) { + tok1 = T_DATUM + } else if kw, ok := s.unreservedCheck(&aux1); ok { + tok1 = kw + } else { + tok1 = T_WORD + } + } + } else { + // not A.B, so just process A + s.pushBackTokenAux(tok2, &aux2) + + // See if it matches a variable name, except at start of statement + // when the next token isn't assignment or '['. + lookup := !atStmtStart(s.cur.tok) || + (tok2 == plToken('=') || tok2 == tokCOLON_EQUALS || tok2 == plToken('[')) + if s.comp.parseWord(aux1.str, s.quotedAt(aux1.lloc), lookup, &aux1.wdatum, &aux1.word) { + tok1 = T_DATUM + } else if kw, ok := s.unreservedCheck(&aux1); ok { + tok1 = kw + } else { + tok1 = T_WORD + } + } + } + + s.cur = aux1 + s.cur.tok = tok1 + return tok1 +} + +// unreservedCheck applies the unreserved-keyword lookup that follows a +// failed variable lookup (aux.word was filled in by parseWord). +func (s *plScanner) unreservedCheck(aux *tokenAux) (plToken, bool) { + if aux.word.quoted { + return 0, false + } + if kw, ok := unreservedKeywords[aux.word.ident]; ok { + aux.keyword = aux.word.ident + return kw, true + } + return 0, false +} + +// quotedAt reports whether the token starting at lloc was written quoted +// (yytxt[0] == '"' in the C checks). +func (s *plScanner) quotedAt(lloc int) bool { + return lloc < len(s.src) && s.src[lloc] == '"' +} + +// AT_STMT_START (pl_scanner.c). +func atStmtStart(prevToken plToken) bool { + return prevToken == plToken(';') || prevToken == K_BEGIN || + prevToken == K_THEN || prevToken == K_ELSE || prevToken == K_LOOP +} + +// tokenLength is plpgsql_token_length. +func (s *plScanner) tokenLength() int { return s.cur.leng } + +// peek is plpgsql_peek. +func (s *plScanner) peek() plToken { + var aux tokenAux + tok := s.internalYylex(&aux) + s.pushBackTokenAux(tok, &aux) + return tok +} + +// peek2 is plpgsql_peek2. +func (s *plScanner) peek2() (tok1, tok2 plToken, tok1loc, tok2loc int) { + var aux1, aux2 tokenAux + tok1 = s.internalYylex(&aux1) + tok2 = s.internalYylex(&aux2) + tok1loc, tok2loc = aux1.lloc, aux2.lloc + s.pushBackTokenAux(tok2, &aux2) + s.pushBackTokenAux(tok1, &aux1) + return +} + +// tokenIsUnreservedKeyword is plpgsql_token_is_unreserved_keyword. +func tokenIsUnreservedKeyword(tok plToken) bool { + for _, t := range unreservedKeywords { + if t == tok { + return true + } + } + return false +} + +// appendSourceText is plpgsql_append_source_text. +func (s *plScanner) sourceText(startLocation, endLocation int) string { + return s.src[startLocation:endLocation] +} + +// yyerror is plpgsql_yyerror: report at the current token. +func (s *plScanner) yyerror(message string) { + if s.cur.lloc >= len(s.src) { + panic(&compileError{ + Message: message + " at end of input", + Filename: plScannerFilename, + Funcname: "plpgsql_yyerror", + }) + } + yytext := s.src[s.cur.lloc:min(s.cur.lloc+s.cur.leng, len(s.src))] + panic(&compileError{ + Message: message + ` at or near "` + yytext + `"`, + Filename: plScannerFilename, + Funcname: "plpgsql_yyerror", + }) +} + +// plScannerFilename is what __FILE__ expands to in the vendored build. +const plScannerFilename = "src_pl_plpgsql_src_pl_scanner.c" + +// locationToLineno is plpgsql_location_to_lineno. +func (s *plScanner) locationToLineno(location int) int { + if location < 0 { + return 0 + } + if location < s.curLineStart { + s.locationLinenoInit() + } + for s.curLineEnd >= 0 && location > s.curLineEnd { + s.curLineStart = s.curLineEnd + 1 + s.curLineNum++ + s.curLineEnd = nextNewline(s.src, s.curLineStart) + } + return s.curLineNum +} + +func (s *plScanner) locationLinenoInit() { + s.curLineStart = 0 + s.curLineNum = 1 + s.curLineEnd = nextNewline(s.src, 0) +} + +// latestLineno is plpgsql_latest_lineno. +func (s *plScanner) latestLineno() int { return s.curLineNum } + +func nextNewline(src string, from int) int { + if from > len(src) { + return -1 + } + idx := strings.IndexByte(src[from:], '\n') + if idx < 0 { + return -1 + } + return from + idx +} diff --git a/internal/plpgsql/tables.go b/internal/plpgsql/tables.go new file mode 100644 index 0000000..b595fdf --- /dev/null +++ b/internal/plpgsql/tables.go @@ -0,0 +1,373 @@ +// Code generated by cmd/generate -plpgsql from internal/reference/ +// pl_reserved_kwlist.h, pl_unreserved_kwlist.h, and plerrcodes.h +// (libpg_query 17-6.2.2). DO NOT EDIT. + +package plpgsql + +// reservedKeywords is pl_reserved_kwlist.h: these are passed to the core +// scanner's keyword list, so they win over any variable name. +var reservedKeywords = map[string]plToken{ + "all": K_ALL, + "begin": K_BEGIN, + "by": K_BY, + "case": K_CASE, + "declare": K_DECLARE, + "else": K_ELSE, + "end": K_END, + "execute": K_EXECUTE, + "for": K_FOR, + "foreach": K_FOREACH, + "from": K_FROM, + "if": K_IF, + "in": K_IN, + "into": K_INTO, + "loop": K_LOOP, + "not": K_NOT, + "null": K_NULL, + "or": K_OR, + "strict": K_STRICT, + "then": K_THEN, + "to": K_TO, + "using": K_USING, + "when": K_WHEN, + "while": K_WHILE, +} + +// unreservedKeywords is pl_unreserved_kwlist.h: checked only where the +// grammar wants a keyword and no variable matched. +var unreservedKeywords = map[string]plToken{ + "absolute": K_ABSOLUTE, + "alias": K_ALIAS, + "and": K_AND, + "array": K_ARRAY, + "assert": K_ASSERT, + "backward": K_BACKWARD, + "call": K_CALL, + "chain": K_CHAIN, + "close": K_CLOSE, + "collate": K_COLLATE, + "column": K_COLUMN, + "column_name": K_COLUMN_NAME, + "commit": K_COMMIT, + "constant": K_CONSTANT, + "constraint": K_CONSTRAINT, + "constraint_name": K_CONSTRAINT_NAME, + "continue": K_CONTINUE, + "current": K_CURRENT, + "cursor": K_CURSOR, + "datatype": K_DATATYPE, + "debug": K_DEBUG, + "default": K_DEFAULT, + "detail": K_DETAIL, + "diagnostics": K_DIAGNOSTICS, + "do": K_DO, + "dump": K_DUMP, + "elseif": K_ELSIF, + "elsif": K_ELSIF, + "errcode": K_ERRCODE, + "error": K_ERROR, + "exception": K_EXCEPTION, + "exit": K_EXIT, + "fetch": K_FETCH, + "first": K_FIRST, + "forward": K_FORWARD, + "get": K_GET, + "hint": K_HINT, + "import": K_IMPORT, + "info": K_INFO, + "insert": K_INSERT, + "is": K_IS, + "last": K_LAST, + "log": K_LOG, + "merge": K_MERGE, + "message": K_MESSAGE, + "message_text": K_MESSAGE_TEXT, + "move": K_MOVE, + "next": K_NEXT, + "no": K_NO, + "notice": K_NOTICE, + "open": K_OPEN, + "option": K_OPTION, + "perform": K_PERFORM, + "pg_context": K_PG_CONTEXT, + "pg_datatype_name": K_PG_DATATYPE_NAME, + "pg_exception_context": K_PG_EXCEPTION_CONTEXT, + "pg_exception_detail": K_PG_EXCEPTION_DETAIL, + "pg_exception_hint": K_PG_EXCEPTION_HINT, + "pg_routine_oid": K_PG_ROUTINE_OID, + "print_strict_params": K_PRINT_STRICT_PARAMS, + "prior": K_PRIOR, + "query": K_QUERY, + "raise": K_RAISE, + "relative": K_RELATIVE, + "return": K_RETURN, + "returned_sqlstate": K_RETURNED_SQLSTATE, + "reverse": K_REVERSE, + "rollback": K_ROLLBACK, + "row_count": K_ROW_COUNT, + "rowtype": K_ROWTYPE, + "schema": K_SCHEMA, + "schema_name": K_SCHEMA_NAME, + "scroll": K_SCROLL, + "slice": K_SLICE, + "sqlstate": K_SQLSTATE, + "stacked": K_STACKED, + "table": K_TABLE, + "table_name": K_TABLE_NAME, + "type": K_TYPE, + "use_column": K_USE_COLUMN, + "use_variable": K_USE_VARIABLE, + "variable_conflict": K_VARIABLE_CONFLICT, + "warning": K_WARNING, +} + +// errConditions maps exception condition names to their number of +// entries in exception_label_map (plpgsql_parse_err_condition returns a +// chain with one node per entry). +var errConditions = map[string]int{ + "active_sql_transaction": 1, + "admin_shutdown": 1, + "ambiguous_alias": 1, + "ambiguous_column": 1, + "ambiguous_function": 1, + "ambiguous_parameter": 1, + "array_subscript_error": 1, + "assert_failure": 1, + "bad_copy_file_format": 1, + "branch_transaction_already_active": 1, + "cannot_coerce": 1, + "cannot_connect_now": 1, + "cant_change_runtime_param": 1, + "cardinality_violation": 1, + "case_not_found": 1, + "character_not_in_repertoire": 1, + "check_violation": 1, + "collation_mismatch": 1, + "config_file_error": 1, + "configuration_limit_exceeded": 1, + "connection_does_not_exist": 1, + "connection_exception": 1, + "connection_failure": 1, + "containing_sql_not_permitted": 1, + "crash_shutdown": 1, + "data_corrupted": 1, + "data_exception": 1, + "database_dropped": 1, + "datatype_mismatch": 1, + "datetime_field_overflow": 1, + "deadlock_detected": 1, + "dependent_objects_still_exist": 1, + "dependent_privilege_descriptors_still_exist": 1, + "diagnostics_exception": 1, + "disk_full": 1, + "division_by_zero": 1, + "duplicate_alias": 1, + "duplicate_column": 1, + "duplicate_cursor": 1, + "duplicate_database": 1, + "duplicate_file": 1, + "duplicate_function": 1, + "duplicate_json_object_key_value": 1, + "duplicate_object": 1, + "duplicate_prepared_statement": 1, + "duplicate_schema": 1, + "duplicate_table": 1, + "error_in_assignment": 1, + "escape_character_conflict": 1, + "event_trigger_protocol_violated": 1, + "exclusion_violation": 1, + "external_routine_exception": 1, + "external_routine_invocation_exception": 1, + "fdw_column_name_not_found": 1, + "fdw_dynamic_parameter_value_needed": 1, + "fdw_error": 1, + "fdw_function_sequence_error": 1, + "fdw_inconsistent_descriptor_information": 1, + "fdw_invalid_attribute_value": 1, + "fdw_invalid_column_name": 1, + "fdw_invalid_column_number": 1, + "fdw_invalid_data_type": 1, + "fdw_invalid_data_type_descriptors": 1, + "fdw_invalid_descriptor_field_identifier": 1, + "fdw_invalid_handle": 1, + "fdw_invalid_option_index": 1, + "fdw_invalid_option_name": 1, + "fdw_invalid_string_format": 1, + "fdw_invalid_string_length_or_buffer_length": 1, + "fdw_invalid_use_of_null_pointer": 1, + "fdw_no_schemas": 1, + "fdw_option_name_not_found": 1, + "fdw_out_of_memory": 1, + "fdw_reply_handle": 1, + "fdw_schema_not_found": 1, + "fdw_table_not_found": 1, + "fdw_too_many_handles": 1, + "fdw_unable_to_create_execution": 1, + "fdw_unable_to_create_reply": 1, + "fdw_unable_to_establish_connection": 1, + "feature_not_supported": 1, + "floating_point_exception": 1, + "foreign_key_violation": 1, + "function_executed_no_return_statement": 1, + "generated_always": 1, + "grouping_error": 1, + "held_cursor_requires_same_isolation_level": 1, + "idle_in_transaction_session_timeout": 1, + "idle_session_timeout": 1, + "in_failed_sql_transaction": 1, + "inappropriate_access_mode_for_branch_transaction": 1, + "inappropriate_isolation_level_for_branch_transaction": 1, + "indeterminate_collation": 1, + "indeterminate_datatype": 1, + "index_corrupted": 1, + "indicator_overflow": 1, + "insufficient_privilege": 1, + "insufficient_resources": 1, + "integrity_constraint_violation": 1, + "internal_error": 1, + "interval_field_overflow": 1, + "invalid_argument_for_logarithm": 1, + "invalid_argument_for_nth_value_function": 1, + "invalid_argument_for_ntile_function": 1, + "invalid_argument_for_power_function": 1, + "invalid_argument_for_sql_json_datetime_function": 1, + "invalid_argument_for_width_bucket_function": 1, + "invalid_authorization_specification": 1, + "invalid_binary_representation": 1, + "invalid_catalog_name": 1, + "invalid_character_value_for_cast": 1, + "invalid_column_definition": 1, + "invalid_column_reference": 1, + "invalid_cursor_definition": 1, + "invalid_cursor_name": 1, + "invalid_cursor_state": 1, + "invalid_database_definition": 1, + "invalid_datetime_format": 1, + "invalid_escape_character": 1, + "invalid_escape_octet": 1, + "invalid_escape_sequence": 1, + "invalid_foreign_key": 1, + "invalid_function_definition": 1, + "invalid_grant_operation": 1, + "invalid_grantor": 1, + "invalid_indicator_parameter_value": 1, + "invalid_json_text": 1, + "invalid_locator_specification": 1, + "invalid_name": 1, + "invalid_object_definition": 1, + "invalid_parameter_value": 1, + "invalid_password": 1, + "invalid_preceding_or_following_size": 1, + "invalid_prepared_statement_definition": 1, + "invalid_recursion": 1, + "invalid_regular_expression": 1, + "invalid_role_specification": 1, + "invalid_row_count_in_limit_clause": 1, + "invalid_row_count_in_result_offset_clause": 1, + "invalid_savepoint_specification": 1, + "invalid_schema_definition": 1, + "invalid_schema_name": 1, + "invalid_sql_json_subscript": 1, + "invalid_sql_statement_name": 1, + "invalid_sqlstate_returned": 1, + "invalid_table_definition": 1, + "invalid_tablesample_argument": 1, + "invalid_tablesample_repeat": 1, + "invalid_text_representation": 1, + "invalid_time_zone_displacement_value": 1, + "invalid_transaction_initiation": 1, + "invalid_transaction_state": 1, + "invalid_transaction_termination": 1, + "invalid_use_of_escape_character": 1, + "invalid_xml_comment": 1, + "invalid_xml_content": 1, + "invalid_xml_document": 1, + "invalid_xml_processing_instruction": 1, + "io_error": 1, + "locator_exception": 1, + "lock_file_exists": 1, + "lock_not_available": 1, + "modifying_sql_data_not_permitted": 2, + "more_than_one_sql_json_item": 1, + "most_specific_type_mismatch": 1, + "name_too_long": 1, + "no_active_sql_transaction": 1, + "no_active_sql_transaction_for_branch_transaction": 1, + "no_data_found": 1, + "no_sql_json_item": 1, + "non_numeric_sql_json_item": 1, + "non_unique_keys_in_a_json_object": 1, + "nonstandard_use_of_escape_character": 1, + "not_an_xml_document": 1, + "not_null_violation": 1, + "null_value_no_indicator_parameter": 1, + "null_value_not_allowed": 2, + "numeric_value_out_of_range": 1, + "object_in_use": 1, + "object_not_in_prerequisite_state": 1, + "operator_intervention": 1, + "out_of_memory": 1, + "plpgsql_error": 1, + "program_limit_exceeded": 1, + "prohibited_sql_statement_attempted": 2, + "protocol_violation": 1, + "query_canceled": 1, + "raise_exception": 1, + "read_only_sql_transaction": 1, + "reading_sql_data_not_permitted": 2, + "reserved_name": 1, + "restrict_violation": 1, + "savepoint_exception": 1, + "schema_and_data_statement_mixing_not_supported": 1, + "sequence_generator_limit_exceeded": 1, + "serialization_failure": 1, + "singleton_sql_json_item_required": 1, + "sql_json_array_not_found": 1, + "sql_json_item_cannot_be_cast_to_target_type": 1, + "sql_json_member_not_found": 1, + "sql_json_number_not_found": 1, + "sql_json_object_not_found": 1, + "sql_json_scalar_required": 1, + "sql_routine_exception": 1, + "sql_statement_not_yet_complete": 1, + "sqlclient_unable_to_establish_sqlconnection": 1, + "sqlserver_rejected_establishment_of_sqlconnection": 1, + "srf_protocol_violated": 1, + "stacked_diagnostics_accessed_without_active_handler": 1, + "statement_completion_unknown": 1, + "statement_too_complex": 1, + "string_data_length_mismatch": 1, + "string_data_right_truncation": 1, + "substring_error": 1, + "syntax_error": 1, + "syntax_error_or_access_rule_violation": 1, + "system_error": 1, + "too_many_arguments": 1, + "too_many_columns": 1, + "too_many_connections": 1, + "too_many_json_array_elements": 1, + "too_many_json_object_members": 1, + "too_many_rows": 1, + "transaction_integrity_constraint_violation": 1, + "transaction_resolution_unknown": 1, + "transaction_rollback": 1, + "transaction_timeout": 1, + "trigger_protocol_violated": 1, + "triggered_action_exception": 1, + "triggered_data_change_violation": 1, + "trim_error": 1, + "undefined_column": 1, + "undefined_file": 1, + "undefined_function": 1, + "undefined_object": 1, + "undefined_parameter": 1, + "undefined_table": 1, + "unique_violation": 1, + "unsafe_new_enum_value_usage": 1, + "unterminated_c_string": 1, + "untranslatable_character": 1, + "windowing_error": 1, + "with_check_option_violation": 1, + "wrong_object_type": 1, + "zero_length_character_string": 1, +} diff --git a/internal/summary/walker.go b/internal/rawwalk/walker.go similarity index 92% rename from internal/summary/walker.go rename to internal/rawwalk/walker.go index 3797345..5a6e14f 100644 --- a/internal/summary/walker.go +++ b/internal/rawwalk/walker.go @@ -1,8 +1,9 @@ -// Package summary ports libpg_query's summary API: pg_query_summary.c (the -// table/alias/CTE/function/filter-column walk), pg_query_summary_statement_type.c -// (the statement-type walk), and pg_query_summary_truncate.c (deparse-driven -// smart truncation). -package summary +// Package rawwalk is raw_expression_tree_walker (src/backend/nodes/ +// nodeFuncs.c, PostgreSQL 17) over the protobuf tree, gated exactly as +// pg_query_raw_tree_walker_supports allows: node types outside the walker's +// switch return false without descending. It drives the summary walks and +// the PL/pgSQL driver's statement collection. +package rawwalk import ( "reflect" @@ -12,17 +13,17 @@ import ( // The C walks operate on Node* where a node may be a T_List; the callback is // invoked for list nodes too (which matters for the truncation walk's depth -// accounting). nodeList and rawStmtList model those list nodes over the +// accounting). NodeList and RawStmtList model those list nodes over the // protobuf tree. -type nodeList []*ast.Node +type NodeList []*ast.Node -type rawStmtList []*ast.RawStmt +type RawStmtList []*ast.RawStmt // concrete unwraps an *ast.Node into its inner concrete pointer (the oneof // member), so callbacks can switch on one representation regardless of // whether a child arrived generically (*ast.Node) or as a typed field // (*ast.RangeVar, *ast.FuncCall, ...). -func concrete(item any) any { +func Concrete(item any) any { n, ok := item.(*ast.Node) if !ok { return item @@ -40,11 +41,11 @@ func wl(list []*ast.Node) any { if len(list) == 0 { return nil } - return nodeList(list) + return NodeList(list) } // isNil reports whether a child slot is empty (NULL in the C tree). -func isNil(item any) bool { +func IsNil(item any) bool { if item == nil { return true } @@ -58,10 +59,10 @@ func isNil(item any) bool { // descending (the summary C files check the gate before calling the walker; // folding it into the default arm is equivalent). Child order is the C // walker's, verbatim — it decides the order of every summary list. -func walkChildren(item any, cb func(any) bool) bool { +func WalkChildren(item any, cb func(any) bool) bool { w := func(children ...any) bool { for _, c := range children { - if isNil(c) { + if IsNil(c) { continue } if cb(c) { @@ -71,15 +72,15 @@ func walkChildren(item any, cb func(any) bool) bool { return false } - switch v := concrete(item).(type) { - case rawStmtList: + switch v := Concrete(item).(type) { + case RawStmtList: for _, rs := range v { if cb(rs) { return true } } return false - case nodeList: + case NodeList: for _, n := range v { if n == nil || n.Node == nil { continue diff --git a/internal/reference/README.md b/internal/reference/README.md index 39c21de..94133a3 100644 --- a/internal/reference/README.md +++ b/internal/reference/README.md @@ -1,8 +1,8 @@ # internal/reference — the pinned grammar, for humans These files are **documentation only**: nothing in the build reads them except -the keyword-table generator (`kwlist.h`). They are the source of truth every -`parse*` method's attribution comment points at. +the table generators (`kwlist.h`, `pl_*_kwlist.h`, `plerrcodes.h`). They are +the source of truth every `parse*` method's attribution comment points at. Provenance — PostgreSQL **17.7** source tarball with libpg_query **`17-6.2.2`**'s patches applied (the ones that touch these files): @@ -13,12 +13,27 @@ Provenance — PostgreSQL **17.7** source tarball with libpg_query | `scan.l` | `src/backend/parser/scan.l` | 03 (`yyllocend` token-end tracking), 04 (comments as tokens), 09 (`param_junk` removed) | | `parser.c` | `src/backend/parser/parser.c` | 03, 04 (`base_yylex` lookahead filter — the NOT_LA/NULLS_LA/WITH_LA/WITHOUT_LA/FORMAT_LA merges live here) | | `kwlist.h` | `src/include/parser/kwlist.h` | none (copied from libpg_query's extracted `src/postgres/include/parser/kwlist.h`) | +| `pl_gram.y` | `src/pl/plpgsql/src/pl_gram.y` | 04 (SQL_COMMENT/C_COMMENT token declarations) | +| `pl_scanner.c` | `src/pl/plpgsql/src/pl_scanner.c` | 04 (comment tokens skipped in `internal_yylex`) | +| `pl_reserved_kwlist.h` | `src/pl/plpgsql/src/pl_reserved_kwlist.h` | none (copied from libpg_query's `src/postgres/include/`) | +| `pl_unreserved_kwlist.h` | `src/pl/plpgsql/src/pl_unreserved_kwlist.h` | none (same) | +| `plerrcodes.h` | generated from `src/backend/utils/errcodes.txt` | none (copied from libpg_query's `src/postgres/include/`) | oliphant ports **patched** PostgreSQL, never vanilla: `$1` parameter references are legal in more grammar positions, the lexer tracks token end offsets and emits comments as tokens, and `param_junk` does not exist. The oracle for every golden is the pinned libpg_query build, not upstream PostgreSQL. -To re-derive: download `postgresql-17.7.tar.gz`, extract these four paths, and +For PL/pgSQL, the reference is further from vanilla than for SQL: libpg_query's +`extract_source.rb` **mocks** several pl_comp.c functions in the build the +oracle runs (see `internal/plpgsql`'s attribution comments) — `parse_datatype` +keeps the type text verbatim instead of consulting the catalogs, +`plpgsql_parse_wordtype`/`%ROWTYPE` lookups return NULL, `make_return_stmt` +drops the return-type checks, and `function_parse_error_transpose` always +fails (so compile errors carry a "near line N" context instead of a cursor). +The vendored `src/postgres/src_pl_plpgsql_src_pl_gram.c` at the pin is the +authority where it differs from `pl_gram.y`. + +To re-derive: download `postgresql-17.7.tar.gz`, extract these paths, and apply `patches/01,03,04,09` from the libpg_query tag (hunks touching other files skipped). diff --git a/internal/reference/pl_gram.y b/internal/reference/pl_gram.y new file mode 100644 index 0000000..165b9b0 --- /dev/null +++ b/internal/reference/pl_gram.y @@ -0,0 +1,4173 @@ +%{ +/*------------------------------------------------------------------------- + * + * pl_gram.y - Parser for the PL/pgSQL procedural language + * + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/pl/plpgsql/src/pl_gram.y + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "catalog/namespace.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_type.h" +#include "parser/parser.h" +#include "parser/parse_type.h" +#include "parser/scanner.h" +#include "parser/scansup.h" +#include "utils/builtins.h" + +#include "plpgsql.h" + + +/* Location tracking support --- simpler than bison's default */ +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + if (N) \ + (Current) = (Rhs)[1]; \ + else \ + (Current) = (Rhs)[0]; \ + } while (0) + +/* + * Bison doesn't allocate anything that needs to live across parser calls, + * so we can easily have it use palloc instead of malloc. This prevents + * memory leaks if we error out during parsing. + */ +#define YYMALLOC palloc +#define YYFREE pfree + + +typedef struct +{ + int location; +} sql_error_callback_arg; + +#define parser_errposition(pos) plpgsql_scanner_errposition(pos) + +union YYSTYPE; /* need forward reference for tok_is_keyword */ + +static bool tok_is_keyword(int token, union YYSTYPE *lval, + int kw_token, const char *kw_str); +static void word_is_not_variable(PLword *word, int location); +static void cword_is_not_variable(PLcword *cword, int location); +static void current_token_is_not_variable(int tok); +static PLpgSQL_expr *read_sql_construct(int until, + int until2, + int until3, + const char *expected, + RawParseMode parsemode, + bool isexpression, + bool valid_sql, + int *startloc, + int *endtoken); +static PLpgSQL_expr *read_sql_expression(int until, + const char *expected); +static PLpgSQL_expr *read_sql_expression2(int until, int until2, + const char *expected, + int *endtoken); +static PLpgSQL_expr *read_sql_stmt(void); +static PLpgSQL_type *read_datatype(int tok); +static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location, + PLword *word); +static PLpgSQL_stmt_fetch *read_fetch_direction(void); +static void complete_direction(PLpgSQL_stmt_fetch *fetch, + bool *check_FROM); +static PLpgSQL_stmt *make_return_stmt(int location); +static PLpgSQL_stmt *make_return_next_stmt(int location); +static PLpgSQL_stmt *make_return_query_stmt(int location); +static PLpgSQL_stmt *make_case(int location, PLpgSQL_expr *t_expr, + List *case_when_list, List *else_stmts); +static char *NameOfDatum(PLwdatum *wdatum); +static void check_assignable(PLpgSQL_datum *datum, int location); +static void read_into_target(PLpgSQL_variable **target, + bool *strict); +static PLpgSQL_row *read_into_scalar_list(char *initial_name, + PLpgSQL_datum *initial_datum, + int initial_location); +static PLpgSQL_row *make_scalar_list1(char *initial_name, + PLpgSQL_datum *initial_datum, + int lineno, int location); +static void check_sql_expr(const char *stmt, + RawParseMode parseMode, int location); +static void plpgsql_sql_error_callback(void *arg); +static PLpgSQL_type *parse_datatype(const char *string, int location); +static void check_labels(const char *start_label, + const char *end_label, + int end_location); +static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor, + int until); +static List *read_raise_options(void); +static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); + +%} + +%expect 0 +%name-prefix="plpgsql_yy" +%locations + +%union +{ + core_YYSTYPE core_yystype; + /* these fields must match core_YYSTYPE: */ + int ival; + char *str; + const char *keyword; + + PLword word; + PLcword cword; + PLwdatum wdatum; + bool boolean; + Oid oid; + struct + { + char *name; + int lineno; + } varname; + struct + { + char *name; + int lineno; + PLpgSQL_datum *scalar; + PLpgSQL_datum *row; + } forvariable; + struct + { + char *label; + int n_initvars; + int *initvarnos; + } declhdr; + struct + { + List *stmts; + char *end_label; + int end_label_location; + } loop_body; + List *list; + PLpgSQL_type *dtype; + PLpgSQL_datum *datum; + PLpgSQL_var *var; + PLpgSQL_expr *expr; + PLpgSQL_stmt *stmt; + PLpgSQL_condition *condition; + PLpgSQL_exception *exception; + PLpgSQL_exception_block *exception_block; + PLpgSQL_nsitem *nsitem; + PLpgSQL_diag_item *diagitem; + PLpgSQL_stmt_fetch *fetch; + PLpgSQL_case_when *casewhen; +} + +%type decl_sect +%type decl_varname +%type decl_const decl_notnull exit_type +%type decl_defval decl_cursor_query +%type decl_datatype +%type decl_collate +%type decl_cursor_args +%type decl_cursor_arglist +%type decl_aliasitem + +%type expr_until_semi +%type expr_until_then expr_until_loop opt_expr_until_when +%type opt_exitcond + +%type cursor_variable +%type decl_cursor_arg +%type for_variable +%type foreach_slice +%type for_control + +%type any_identifier opt_block_label opt_loop_label opt_label +%type option_value + +%type proc_sect stmt_elsifs stmt_else +%type loop_body +%type proc_stmt pl_block +%type stmt_assign stmt_if stmt_loop stmt_while stmt_exit +%type stmt_return stmt_raise stmt_assert stmt_execsql +%type stmt_dynexecute stmt_for stmt_perform stmt_call stmt_getdiag +%type stmt_open stmt_fetch stmt_move stmt_close stmt_null +%type stmt_commit stmt_rollback +%type stmt_case stmt_foreach_a + +%type proc_exceptions +%type exception_sect +%type proc_exception +%type proc_conditions proc_condition + +%type case_when +%type case_when_list opt_case_else + +%type getdiag_area_opt +%type getdiag_list +%type getdiag_list_item +%type getdiag_target +%type getdiag_item + +%type opt_scrollable +%type opt_fetch_direction + +%type opt_transaction_chain + +%type unreserved_keyword + + +/* + * Basic non-keyword token types. These are hard-wired into the core lexer. + * They must be listed first so that their numeric codes do not depend on + * the set of keywords. Keep this list in sync with backend/parser/gram.y! + * + * Some of these are not directly referenced in this file, but they must be + * here anyway. + */ +%token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op +%token ICONST PARAM +%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER +%token LESS_EQUALS GREATER_EQUALS NOT_EQUALS +%token SQL_COMMENT C_COMMENT + +/* + * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c). + */ +%token T_WORD /* unrecognized simple identifier */ +%token T_CWORD /* unrecognized composite identifier */ +%token T_DATUM /* a VAR, ROW, REC, or RECFIELD variable */ +%token LESS_LESS +%token GREATER_GREATER + +/* + * Keyword tokens. Some of these are reserved and some are not; + * see pl_scanner.c for info. Be sure unreserved keywords are listed + * in the "unreserved_keyword" production below. + */ +%token K_ABSOLUTE +%token K_ALIAS +%token K_ALL +%token K_AND +%token K_ARRAY +%token K_ASSERT +%token K_BACKWARD +%token K_BEGIN +%token K_BY +%token K_CALL +%token K_CASE +%token K_CHAIN +%token K_CLOSE +%token K_COLLATE +%token K_COLUMN +%token K_COLUMN_NAME +%token K_COMMIT +%token K_CONSTANT +%token K_CONSTRAINT +%token K_CONSTRAINT_NAME +%token K_CONTINUE +%token K_CURRENT +%token K_CURSOR +%token K_DATATYPE +%token K_DEBUG +%token K_DECLARE +%token K_DEFAULT +%token K_DETAIL +%token K_DIAGNOSTICS +%token K_DO +%token K_DUMP +%token K_ELSE +%token K_ELSIF +%token K_END +%token K_ERRCODE +%token K_ERROR +%token K_EXCEPTION +%token K_EXECUTE +%token K_EXIT +%token K_FETCH +%token K_FIRST +%token K_FOR +%token K_FOREACH +%token K_FORWARD +%token K_FROM +%token K_GET +%token K_HINT +%token K_IF +%token K_IMPORT +%token K_IN +%token K_INFO +%token K_INSERT +%token K_INTO +%token K_IS +%token K_LAST +%token K_LOG +%token K_LOOP +%token K_MERGE +%token K_MESSAGE +%token K_MESSAGE_TEXT +%token K_MOVE +%token K_NEXT +%token K_NO +%token K_NOT +%token K_NOTICE +%token K_NULL +%token K_OPEN +%token K_OPTION +%token K_OR +%token K_PERFORM +%token K_PG_CONTEXT +%token K_PG_DATATYPE_NAME +%token K_PG_EXCEPTION_CONTEXT +%token K_PG_EXCEPTION_DETAIL +%token K_PG_EXCEPTION_HINT +%token K_PG_ROUTINE_OID +%token K_PRINT_STRICT_PARAMS +%token K_PRIOR +%token K_QUERY +%token K_RAISE +%token K_RELATIVE +%token K_RETURN +%token K_RETURNED_SQLSTATE +%token K_REVERSE +%token K_ROLLBACK +%token K_ROW_COUNT +%token K_ROWTYPE +%token K_SCHEMA +%token K_SCHEMA_NAME +%token K_SCROLL +%token K_SLICE +%token K_SQLSTATE +%token K_STACKED +%token K_STRICT +%token K_TABLE +%token K_TABLE_NAME +%token K_THEN +%token K_TO +%token K_TYPE +%token K_USE_COLUMN +%token K_USE_VARIABLE +%token K_USING +%token K_VARIABLE_CONFLICT +%token K_WARNING +%token K_WHEN +%token K_WHILE + +%% + +pl_function : comp_options pl_block opt_semi + { + plpgsql_parse_result = (PLpgSQL_stmt_block *) $2; + } + ; + +comp_options : + | comp_options comp_option + ; + +comp_option : '#' K_OPTION K_DUMP + { + plpgsql_DumpExecTree = true; + } + | '#' K_PRINT_STRICT_PARAMS option_value + { + if (strcmp($3, "on") == 0) + plpgsql_curr_compile->print_strict_params = true; + else if (strcmp($3, "off") == 0) + plpgsql_curr_compile->print_strict_params = false; + else + elog(ERROR, "unrecognized print_strict_params option %s", $3); + } + | '#' K_VARIABLE_CONFLICT K_ERROR + { + plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_ERROR; + } + | '#' K_VARIABLE_CONFLICT K_USE_VARIABLE + { + plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_VARIABLE; + } + | '#' K_VARIABLE_CONFLICT K_USE_COLUMN + { + plpgsql_curr_compile->resolve_option = PLPGSQL_RESOLVE_COLUMN; + } + ; + +option_value : T_WORD + { + $$ = $1.ident; + } + | unreserved_keyword + { + $$ = pstrdup($1); + } + +opt_semi : + | ';' + ; + +pl_block : decl_sect K_BEGIN proc_sect exception_sect K_END opt_label + { + PLpgSQL_stmt_block *new; + + new = palloc0(sizeof(PLpgSQL_stmt_block)); + + new->cmd_type = PLPGSQL_STMT_BLOCK; + new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->label = $1.label; + new->n_initvars = $1.n_initvars; + new->initvarnos = $1.initvarnos; + new->body = $3; + new->exceptions = $4; + + check_labels($1.label, $6, @6); + plpgsql_ns_pop(); + + $$ = (PLpgSQL_stmt *) new; + } + ; + + +decl_sect : opt_block_label + { + /* done with decls, so resume identifier lookup */ + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; + $$.label = $1; + $$.n_initvars = 0; + $$.initvarnos = NULL; + } + | opt_block_label decl_start + { + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; + $$.label = $1; + $$.n_initvars = 0; + $$.initvarnos = NULL; + } + | opt_block_label decl_start decl_stmts + { + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; + $$.label = $1; + /* Remember variables declared in decl_stmts */ + $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos)); + } + ; + +decl_start : K_DECLARE + { + /* Forget any variables created before block */ + plpgsql_add_initdatums(NULL); + /* + * Disable scanner lookup of identifiers while + * we process the decl_stmts + */ + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE; + } + ; + +decl_stmts : decl_stmts decl_stmt + | decl_stmt + ; + +decl_stmt : decl_statement + | K_DECLARE + { + /* We allow useless extra DECLAREs */ + } + | LESS_LESS any_identifier GREATER_GREATER + { + /* + * Throw a helpful error if user tries to put block + * label just before BEGIN, instead of before DECLARE. + */ + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("block label must be placed before DECLARE, not after"), + parser_errposition(@1))); + } + ; + +decl_statement : decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval + { + PLpgSQL_variable *var; + + /* + * If a collation is supplied, insert it into the + * datatype. We assume decl_datatype always returns + * a freshly built struct not shared with other + * variables. + */ + if (OidIsValid($4)) + { + if (!OidIsValid($3->collation)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("collations are not supported by type %s", + format_type_be($3->typoid)), + parser_errposition(@4))); + $3->collation = $4; + } + + var = plpgsql_build_variable($1.name, $1.lineno, + $3, true); + var->isconst = $2; + var->notnull = $5; + var->default_val = $6; + + /* + * The combination of NOT NULL without an initializer + * can't work, so let's reject it at compile time. + */ + if (var->notnull && var->default_val == NULL) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("variable \"%s\" must have a default value, since it's declared NOT NULL", + var->refname), + parser_errposition(@5))); + } + | decl_varname K_ALIAS K_FOR decl_aliasitem ';' + { + plpgsql_ns_additem($4->itemtype, + $4->itemno, $1.name); + } + | decl_varname opt_scrollable K_CURSOR + { plpgsql_ns_push($1.name, PLPGSQL_LABEL_OTHER); } + decl_cursor_args decl_is_for decl_cursor_query + { + PLpgSQL_var *new; + + /* pop local namespace for cursor args */ + plpgsql_ns_pop(); + + new = (PLpgSQL_var *) + plpgsql_build_variable($1.name, $1.lineno, + plpgsql_build_datatype(REFCURSOROID, + -1, + InvalidOid, + NULL), + true); + + new->cursor_explicit_expr = $7; + if ($5 == NULL) + new->cursor_explicit_argrow = -1; + else + new->cursor_explicit_argrow = $5->dno; + new->cursor_options = CURSOR_OPT_FAST_PLAN | $2; + } + ; + +opt_scrollable : + { + $$ = 0; + } + | K_NO K_SCROLL + { + $$ = CURSOR_OPT_NO_SCROLL; + } + | K_SCROLL + { + $$ = CURSOR_OPT_SCROLL; + } + ; + +decl_cursor_query : + { + $$ = read_sql_stmt(); + } + ; + +decl_cursor_args : + { + $$ = NULL; + } + | '(' decl_cursor_arglist ')' + { + PLpgSQL_row *new; + int i; + ListCell *l; + + new = palloc0(sizeof(PLpgSQL_row)); + new->dtype = PLPGSQL_DTYPE_ROW; + new->refname = "(unnamed row)"; + new->lineno = plpgsql_location_to_lineno(@1); + new->rowtupdesc = NULL; + new->nfields = list_length($2); + new->fieldnames = palloc(new->nfields * sizeof(char *)); + new->varnos = palloc(new->nfields * sizeof(int)); + + i = 0; + foreach (l, $2) + { + PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l); + Assert(!arg->isconst); + new->fieldnames[i] = arg->refname; + new->varnos[i] = arg->dno; + i++; + } + list_free($2); + + plpgsql_adddatum((PLpgSQL_datum *) new); + $$ = (PLpgSQL_datum *) new; + } + ; + +decl_cursor_arglist : decl_cursor_arg + { + $$ = list_make1($1); + } + | decl_cursor_arglist ',' decl_cursor_arg + { + $$ = lappend($1, $3); + } + ; + +decl_cursor_arg : decl_varname decl_datatype + { + $$ = (PLpgSQL_datum *) + plpgsql_build_variable($1.name, $1.lineno, + $2, true); + } + ; + +decl_is_for : K_IS | /* Oracle */ + K_FOR; /* SQL standard */ + +decl_aliasitem : T_WORD + { + PLpgSQL_nsitem *nsi; + + nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, + $1.ident, NULL, NULL, + NULL); + if (nsi == NULL) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("variable \"%s\" does not exist", + $1.ident), + parser_errposition(@1))); + $$ = nsi; + } + | unreserved_keyword + { + PLpgSQL_nsitem *nsi; + + nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, + $1, NULL, NULL, + NULL); + if (nsi == NULL) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("variable \"%s\" does not exist", + $1), + parser_errposition(@1))); + $$ = nsi; + } + | T_CWORD + { + PLpgSQL_nsitem *nsi; + + if (list_length($1.idents) == 2) + nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, + strVal(linitial($1.idents)), + strVal(lsecond($1.idents)), + NULL, + NULL); + else if (list_length($1.idents) == 3) + nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, + strVal(linitial($1.idents)), + strVal(lsecond($1.idents)), + strVal(lthird($1.idents)), + NULL); + else + nsi = NULL; + if (nsi == NULL) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("variable \"%s\" does not exist", + NameListToString($1.idents)), + parser_errposition(@1))); + $$ = nsi; + } + ; + +decl_varname : T_WORD + { + $$.name = $1.ident; + $$.lineno = plpgsql_location_to_lineno(@1); + /* + * Check to make sure name isn't already declared + * in the current block. + */ + if (plpgsql_ns_lookup(plpgsql_ns_top(), true, + $1.ident, NULL, NULL, + NULL) != NULL) + yyerror("duplicate declaration"); + + if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR || + plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR) + { + PLpgSQL_nsitem *nsi; + nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, + $1.ident, NULL, NULL, NULL); + if (nsi != NULL) + ereport(plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR ? ERROR : WARNING, + (errcode(ERRCODE_DUPLICATE_ALIAS), + errmsg("variable \"%s\" shadows a previously defined variable", + $1.ident), + parser_errposition(@1))); + } + + } + | unreserved_keyword + { + $$.name = pstrdup($1); + $$.lineno = plpgsql_location_to_lineno(@1); + /* + * Check to make sure name isn't already declared + * in the current block. + */ + if (plpgsql_ns_lookup(plpgsql_ns_top(), true, + $1, NULL, NULL, + NULL) != NULL) + yyerror("duplicate declaration"); + + if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR || + plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR) + { + PLpgSQL_nsitem *nsi; + nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false, + $1, NULL, NULL, NULL); + if (nsi != NULL) + ereport(plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR ? ERROR : WARNING, + (errcode(ERRCODE_DUPLICATE_ALIAS), + errmsg("variable \"%s\" shadows a previously defined variable", + $1), + parser_errposition(@1))); + } + + } + ; + +decl_const : + { $$ = false; } + | K_CONSTANT + { $$ = true; } + ; + +decl_datatype : + { + /* + * If there's a lookahead token, read_datatype() will + * consume it, and then we must tell bison to forget + * it. + */ + $$ = read_datatype(yychar); + yyclearin; + } + ; + +decl_collate : + { $$ = InvalidOid; } + | K_COLLATE T_WORD + { + $$ = get_collation_oid(list_make1(makeString($2.ident)), + false); + } + | K_COLLATE unreserved_keyword + { + $$ = get_collation_oid(list_make1(makeString(pstrdup($2))), + false); + } + | K_COLLATE T_CWORD + { + $$ = get_collation_oid($2.idents, false); + } + ; + +decl_notnull : + { $$ = false; } + | K_NOT K_NULL + { $$ = true; } + ; + +decl_defval : ';' + { $$ = NULL; } + | decl_defkey + { + $$ = read_sql_expression(';', ";"); + } + ; + +decl_defkey : assign_operator + | K_DEFAULT + ; + +/* + * Ada-based PL/SQL uses := for assignment and variable defaults, while + * the SQL standard uses equals for these cases and for GET + * DIAGNOSTICS, so we support both. FOR and OPEN only support :=. + */ +assign_operator : '=' + | COLON_EQUALS + ; + +proc_sect : + { $$ = NIL; } + | proc_sect proc_stmt + { + /* don't bother linking null statements into list */ + if ($2 == NULL) + $$ = $1; + else + $$ = lappend($1, $2); + } + ; + +proc_stmt : pl_block ';' + { $$ = $1; } + | stmt_assign + { $$ = $1; } + | stmt_if + { $$ = $1; } + | stmt_case + { $$ = $1; } + | stmt_loop + { $$ = $1; } + | stmt_while + { $$ = $1; } + | stmt_for + { $$ = $1; } + | stmt_foreach_a + { $$ = $1; } + | stmt_exit + { $$ = $1; } + | stmt_return + { $$ = $1; } + | stmt_raise + { $$ = $1; } + | stmt_assert + { $$ = $1; } + | stmt_execsql + { $$ = $1; } + | stmt_dynexecute + { $$ = $1; } + | stmt_perform + { $$ = $1; } + | stmt_call + { $$ = $1; } + | stmt_getdiag + { $$ = $1; } + | stmt_open + { $$ = $1; } + | stmt_fetch + { $$ = $1; } + | stmt_move + { $$ = $1; } + | stmt_close + { $$ = $1; } + | stmt_null + { $$ = $1; } + | stmt_commit + { $$ = $1; } + | stmt_rollback + { $$ = $1; } + ; + +stmt_perform : K_PERFORM + { + PLpgSQL_stmt_perform *new; + int startloc; + + new = palloc0(sizeof(PLpgSQL_stmt_perform)); + new->cmd_type = PLPGSQL_STMT_PERFORM; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + plpgsql_push_back_token(K_PERFORM); + + /* + * Since PERFORM isn't legal SQL, we have to cheat to + * the extent of substituting "SELECT" for "PERFORM" + * in the parsed text. It does not seem worth + * inventing a separate parse mode for this one case. + * We can't do syntax-checking until after we make the + * substitution. + */ + new->expr = read_sql_construct(';', 0, 0, ";", + RAW_PARSE_DEFAULT, + false, false, + &startloc, NULL); + /* overwrite "perform" ... */ + memcpy(new->expr->query, " SELECT", 7); + /* left-justify to get rid of the leading space */ + memmove(new->expr->query, new->expr->query + 1, + strlen(new->expr->query)); + /* offset syntax error position to account for that */ + check_sql_expr(new->expr->query, new->expr->parseMode, + startloc + 1); + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_call : K_CALL + { + PLpgSQL_stmt_call *new; + + new = palloc0(sizeof(PLpgSQL_stmt_call)); + new->cmd_type = PLPGSQL_STMT_CALL; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + plpgsql_push_back_token(K_CALL); + new->expr = read_sql_stmt(); + new->is_call = true; + + /* Remember we may need a procedure resource owner */ + plpgsql_curr_compile->requires_procedure_resowner = true; + + $$ = (PLpgSQL_stmt *) new; + + } + | K_DO + { + /* use the same structures as for CALL, for simplicity */ + PLpgSQL_stmt_call *new; + + new = palloc0(sizeof(PLpgSQL_stmt_call)); + new->cmd_type = PLPGSQL_STMT_CALL; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + plpgsql_push_back_token(K_DO); + new->expr = read_sql_stmt(); + new->is_call = false; + + /* Remember we may need a procedure resource owner */ + plpgsql_curr_compile->requires_procedure_resowner = true; + + $$ = (PLpgSQL_stmt *) new; + + } + ; + +stmt_assign : T_DATUM + { + PLpgSQL_stmt_assign *new; + RawParseMode pmode; + + /* see how many names identify the datum */ + switch ($1.ident ? 1 : list_length($1.idents)) + { + case 1: + pmode = RAW_PARSE_PLPGSQL_ASSIGN1; + break; + case 2: + pmode = RAW_PARSE_PLPGSQL_ASSIGN2; + break; + case 3: + pmode = RAW_PARSE_PLPGSQL_ASSIGN3; + break; + default: + elog(ERROR, "unexpected number of names"); + pmode = 0; /* keep compiler quiet */ + } + + check_assignable($1.datum, @1); + new = palloc0(sizeof(PLpgSQL_stmt_assign)); + new->cmd_type = PLPGSQL_STMT_ASSIGN; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->varno = $1.datum->dno; + /* Push back the head name to include it in the stmt */ + plpgsql_push_back_token(T_DATUM); + new->expr = read_sql_construct(';', 0, 0, ";", + pmode, + false, true, + NULL, NULL); + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';' + { + PLpgSQL_stmt_getdiag *new; + ListCell *lc; + + new = palloc0(sizeof(PLpgSQL_stmt_getdiag)); + new->cmd_type = PLPGSQL_STMT_GETDIAG; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->is_stacked = $2; + new->diag_items = $4; + + /* + * Check information items are valid for area option. + */ + foreach(lc, new->diag_items) + { + PLpgSQL_diag_item *ditem = (PLpgSQL_diag_item *) lfirst(lc); + + switch (ditem->kind) + { + /* these fields are disallowed in stacked case */ + case PLPGSQL_GETDIAG_ROW_COUNT: + case PLPGSQL_GETDIAG_ROUTINE_OID: + if (new->is_stacked) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS", + plpgsql_getdiag_kindname(ditem->kind)), + parser_errposition(@1))); + break; + /* these fields are disallowed in current case */ + case PLPGSQL_GETDIAG_ERROR_CONTEXT: + case PLPGSQL_GETDIAG_ERROR_DETAIL: + case PLPGSQL_GETDIAG_ERROR_HINT: + case PLPGSQL_GETDIAG_RETURNED_SQLSTATE: + case PLPGSQL_GETDIAG_COLUMN_NAME: + case PLPGSQL_GETDIAG_CONSTRAINT_NAME: + case PLPGSQL_GETDIAG_DATATYPE_NAME: + case PLPGSQL_GETDIAG_MESSAGE_TEXT: + case PLPGSQL_GETDIAG_TABLE_NAME: + case PLPGSQL_GETDIAG_SCHEMA_NAME: + if (!new->is_stacked) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS", + plpgsql_getdiag_kindname(ditem->kind)), + parser_errposition(@1))); + break; + /* these fields are allowed in either case */ + case PLPGSQL_GETDIAG_CONTEXT: + break; + default: + elog(ERROR, "unrecognized diagnostic item kind: %d", + ditem->kind); + break; + } + } + + $$ = (PLpgSQL_stmt *) new; + } + ; + +getdiag_area_opt : + { + $$ = false; + } + | K_CURRENT + { + $$ = false; + } + | K_STACKED + { + $$ = true; + } + ; + +getdiag_list : getdiag_list ',' getdiag_list_item + { + $$ = lappend($1, $3); + } + | getdiag_list_item + { + $$ = list_make1($1); + } + ; + +getdiag_list_item : getdiag_target assign_operator getdiag_item + { + PLpgSQL_diag_item *new; + + new = palloc(sizeof(PLpgSQL_diag_item)); + new->target = $1->dno; + new->kind = $3; + + $$ = new; + } + ; + +getdiag_item : + { + int tok = yylex(); + + if (tok_is_keyword(tok, &yylval, + K_ROW_COUNT, "row_count")) + $$ = PLPGSQL_GETDIAG_ROW_COUNT; + else if (tok_is_keyword(tok, &yylval, + K_PG_ROUTINE_OID, "pg_routine_oid")) + $$ = PLPGSQL_GETDIAG_ROUTINE_OID; + else if (tok_is_keyword(tok, &yylval, + K_PG_CONTEXT, "pg_context")) + $$ = PLPGSQL_GETDIAG_CONTEXT; + else if (tok_is_keyword(tok, &yylval, + K_PG_EXCEPTION_DETAIL, "pg_exception_detail")) + $$ = PLPGSQL_GETDIAG_ERROR_DETAIL; + else if (tok_is_keyword(tok, &yylval, + K_PG_EXCEPTION_HINT, "pg_exception_hint")) + $$ = PLPGSQL_GETDIAG_ERROR_HINT; + else if (tok_is_keyword(tok, &yylval, + K_PG_EXCEPTION_CONTEXT, "pg_exception_context")) + $$ = PLPGSQL_GETDIAG_ERROR_CONTEXT; + else if (tok_is_keyword(tok, &yylval, + K_COLUMN_NAME, "column_name")) + $$ = PLPGSQL_GETDIAG_COLUMN_NAME; + else if (tok_is_keyword(tok, &yylval, + K_CONSTRAINT_NAME, "constraint_name")) + $$ = PLPGSQL_GETDIAG_CONSTRAINT_NAME; + else if (tok_is_keyword(tok, &yylval, + K_PG_DATATYPE_NAME, "pg_datatype_name")) + $$ = PLPGSQL_GETDIAG_DATATYPE_NAME; + else if (tok_is_keyword(tok, &yylval, + K_MESSAGE_TEXT, "message_text")) + $$ = PLPGSQL_GETDIAG_MESSAGE_TEXT; + else if (tok_is_keyword(tok, &yylval, + K_TABLE_NAME, "table_name")) + $$ = PLPGSQL_GETDIAG_TABLE_NAME; + else if (tok_is_keyword(tok, &yylval, + K_SCHEMA_NAME, "schema_name")) + $$ = PLPGSQL_GETDIAG_SCHEMA_NAME; + else if (tok_is_keyword(tok, &yylval, + K_RETURNED_SQLSTATE, "returned_sqlstate")) + $$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE; + else + yyerror("unrecognized GET DIAGNOSTICS item"); + } + ; + +getdiag_target : T_DATUM + { + /* + * In principle we should support a getdiag_target + * that is an array element, but for now we don't, so + * just throw an error if next token is '['. + */ + if ($1.datum->dtype == PLPGSQL_DTYPE_ROW || + $1.datum->dtype == PLPGSQL_DTYPE_REC || + plpgsql_peek() == '[') + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("\"%s\" is not a scalar variable", + NameOfDatum(&($1))), + parser_errposition(@1))); + check_assignable($1.datum, @1); + $$ = $1.datum; + } + | T_WORD + { + /* just to give a better message than "syntax error" */ + word_is_not_variable(&($1), @1); + } + | T_CWORD + { + /* just to give a better message than "syntax error" */ + cword_is_not_variable(&($1), @1); + } + ; + +stmt_if : K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';' + { + PLpgSQL_stmt_if *new; + + new = palloc0(sizeof(PLpgSQL_stmt_if)); + new->cmd_type = PLPGSQL_STMT_IF; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->cond = $2; + new->then_body = $3; + new->elsif_list = $4; + new->else_body = $5; + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_elsifs : + { + $$ = NIL; + } + | stmt_elsifs K_ELSIF expr_until_then proc_sect + { + PLpgSQL_if_elsif *new; + + new = palloc0(sizeof(PLpgSQL_if_elsif)); + new->lineno = plpgsql_location_to_lineno(@2); + new->cond = $3; + new->stmts = $4; + + $$ = lappend($1, new); + } + ; + +stmt_else : + { + $$ = NIL; + } + | K_ELSE proc_sect + { + $$ = $2; + } + ; + +stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';' + { + $$ = make_case(@1, $2, $3, $4); + } + ; + +opt_expr_until_when : + { + PLpgSQL_expr *expr = NULL; + int tok = yylex(); + + if (tok != K_WHEN) + { + plpgsql_push_back_token(tok); + expr = read_sql_expression(K_WHEN, "WHEN"); + } + plpgsql_push_back_token(K_WHEN); + $$ = expr; + } + ; + +case_when_list : case_when_list case_when + { + $$ = lappend($1, $2); + } + | case_when + { + $$ = list_make1($1); + } + ; + +case_when : K_WHEN expr_until_then proc_sect + { + PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when)); + + new->lineno = plpgsql_location_to_lineno(@1); + new->expr = $2; + new->stmts = $3; + $$ = new; + } + ; + +opt_case_else : + { + $$ = NIL; + } + | K_ELSE proc_sect + { + /* + * proc_sect could return an empty list, but we + * must distinguish that from not having ELSE at all. + * Simplest fix is to return a list with one NULL + * pointer, which make_case() must take care of. + */ + if ($2 != NIL) + $$ = $2; + else + $$ = list_make1(NULL); + } + ; + +stmt_loop : opt_loop_label K_LOOP loop_body + { + PLpgSQL_stmt_loop *new; + + new = palloc0(sizeof(PLpgSQL_stmt_loop)); + new->cmd_type = PLPGSQL_STMT_LOOP; + new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->label = $1; + new->body = $3.stmts; + + check_labels($1, $3.end_label, $3.end_label_location); + plpgsql_ns_pop(); + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_while : opt_loop_label K_WHILE expr_until_loop loop_body + { + PLpgSQL_stmt_while *new; + + new = palloc0(sizeof(PLpgSQL_stmt_while)); + new->cmd_type = PLPGSQL_STMT_WHILE; + new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->label = $1; + new->cond = $3; + new->body = $4.stmts; + + check_labels($1, $4.end_label, $4.end_label_location); + plpgsql_ns_pop(); + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_for : opt_loop_label K_FOR for_control loop_body + { + /* This runs after we've scanned the loop body */ + if ($3->cmd_type == PLPGSQL_STMT_FORI) + { + PLpgSQL_stmt_fori *new; + + new = (PLpgSQL_stmt_fori *) $3; + new->lineno = plpgsql_location_to_lineno(@2); + new->label = $1; + new->body = $4.stmts; + $$ = (PLpgSQL_stmt *) new; + } + else + { + PLpgSQL_stmt_forq *new; + + Assert($3->cmd_type == PLPGSQL_STMT_FORS || + $3->cmd_type == PLPGSQL_STMT_FORC || + $3->cmd_type == PLPGSQL_STMT_DYNFORS); + /* forq is the common supertype of all three */ + new = (PLpgSQL_stmt_forq *) $3; + new->lineno = plpgsql_location_to_lineno(@2); + new->label = $1; + new->body = $4.stmts; + $$ = (PLpgSQL_stmt *) new; + } + + check_labels($1, $4.end_label, $4.end_label_location); + /* close namespace started in opt_loop_label */ + plpgsql_ns_pop(); + } + ; + +for_control : for_variable K_IN + { + int tok = yylex(); + int tokloc = yylloc; + + if (tok == K_EXECUTE) + { + /* EXECUTE means it's a dynamic FOR loop */ + PLpgSQL_stmt_dynfors *new; + PLpgSQL_expr *expr; + int term; + + expr = read_sql_expression2(K_LOOP, K_USING, + "LOOP or USING", + &term); + + new = palloc0(sizeof(PLpgSQL_stmt_dynfors)); + new->cmd_type = PLPGSQL_STMT_DYNFORS; + new->stmtid = ++plpgsql_curr_compile->nstatements; + if ($1.row) + { + new->var = (PLpgSQL_variable *) $1.row; + check_assignable($1.row, @1); + } + else if ($1.scalar) + { + /* convert single scalar to list */ + new->var = (PLpgSQL_variable *) + make_scalar_list1($1.name, $1.scalar, + $1.lineno, @1); + /* make_scalar_list1 did check_assignable */ + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("loop variable of loop over rows must be a record variable or list of scalar variables"), + parser_errposition(@1))); + } + new->query = expr; + + if (term == K_USING) + { + do + { + expr = read_sql_expression2(',', K_LOOP, + ", or LOOP", + &term); + new->params = lappend(new->params, expr); + } while (term == ','); + } + + $$ = (PLpgSQL_stmt *) new; + } + else if (tok == T_DATUM && + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR && + ((PLpgSQL_var *) yylval.wdatum.datum)->datatype->typoid == REFCURSOROID) + { + /* It's FOR var IN cursor */ + PLpgSQL_stmt_forc *new; + PLpgSQL_var *cursor = (PLpgSQL_var *) yylval.wdatum.datum; + + new = (PLpgSQL_stmt_forc *) palloc0(sizeof(PLpgSQL_stmt_forc)); + new->cmd_type = PLPGSQL_STMT_FORC; + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->curvar = cursor->dno; + + /* Should have had a single variable name */ + if ($1.scalar && $1.row) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cursor FOR loop must have only one target variable"), + parser_errposition(@1))); + + /* can't use an unbound cursor this way */ + if (cursor->cursor_explicit_expr == NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cursor FOR loop must use a bound cursor variable"), + parser_errposition(tokloc))); + + /* collect cursor's parameters if any */ + new->argquery = read_cursor_args(cursor, + K_LOOP); + + /* create loop's private RECORD variable */ + new->var = (PLpgSQL_variable *) + plpgsql_build_record($1.name, + $1.lineno, + NULL, + RECORDOID, + true); + + $$ = (PLpgSQL_stmt *) new; + } + else + { + PLpgSQL_expr *expr1; + int expr1loc; + bool reverse = false; + + /* + * We have to distinguish between two + * alternatives: FOR var IN a .. b and FOR + * var IN query. Unfortunately this is + * tricky, since the query in the second + * form needn't start with a SELECT + * keyword. We use the ugly hack of + * looking for two periods after the first + * token. We also check for the REVERSE + * keyword, which means it must be an + * integer loop. + */ + if (tok_is_keyword(tok, &yylval, + K_REVERSE, "reverse")) + reverse = true; + else + plpgsql_push_back_token(tok); + + /* + * Read tokens until we see either a ".." + * or a LOOP. The text we read may be either + * an expression or a whole SQL statement, so + * we need to invoke read_sql_construct directly, + * and tell it not to check syntax yet. + */ + expr1 = read_sql_construct(DOT_DOT, + K_LOOP, + 0, + "LOOP", + RAW_PARSE_DEFAULT, + true, + false, + &expr1loc, + &tok); + + if (tok == DOT_DOT) + { + /* Saw "..", so it must be an integer loop */ + PLpgSQL_expr *expr2; + PLpgSQL_expr *expr_by; + PLpgSQL_var *fvar; + PLpgSQL_stmt_fori *new; + + /* + * Relabel first expression as an expression; + * then we can check its syntax. + */ + expr1->parseMode = RAW_PARSE_PLPGSQL_EXPR; + check_sql_expr(expr1->query, expr1->parseMode, + expr1loc); + + /* Read and check the second one */ + expr2 = read_sql_expression2(K_LOOP, K_BY, + "LOOP", + &tok); + + /* Get the BY clause if any */ + if (tok == K_BY) + expr_by = read_sql_expression(K_LOOP, + "LOOP"); + else + expr_by = NULL; + + /* Should have had a single variable name */ + if ($1.scalar && $1.row) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("integer FOR loop must have only one target variable"), + parser_errposition(@1))); + + /* create loop's private variable */ + fvar = (PLpgSQL_var *) + plpgsql_build_variable($1.name, + $1.lineno, + plpgsql_build_datatype(INT4OID, + -1, + InvalidOid, + NULL), + true); + + new = palloc0(sizeof(PLpgSQL_stmt_fori)); + new->cmd_type = PLPGSQL_STMT_FORI; + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->var = fvar; + new->reverse = reverse; + new->lower = expr1; + new->upper = expr2; + new->step = expr_by; + + $$ = (PLpgSQL_stmt *) new; + } + else + { + /* + * No "..", so it must be a query loop. + */ + PLpgSQL_stmt_fors *new; + + if (reverse) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cannot specify REVERSE in query FOR loop"), + parser_errposition(tokloc))); + + /* Check syntax as a regular query */ + check_sql_expr(expr1->query, expr1->parseMode, + expr1loc); + + new = palloc0(sizeof(PLpgSQL_stmt_fors)); + new->cmd_type = PLPGSQL_STMT_FORS; + new->stmtid = ++plpgsql_curr_compile->nstatements; + if ($1.row) + { + new->var = (PLpgSQL_variable *) $1.row; + check_assignable($1.row, @1); + } + else if ($1.scalar) + { + /* convert single scalar to list */ + new->var = (PLpgSQL_variable *) + make_scalar_list1($1.name, $1.scalar, + $1.lineno, @1); + /* make_scalar_list1 did check_assignable */ + } + else + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("loop variable of loop over rows must be a record variable or list of scalar variables"), + parser_errposition(@1))); + } + + new->query = expr1; + $$ = (PLpgSQL_stmt *) new; + } + } + } + ; + +/* + * Processing the for_variable is tricky because we don't yet know if the + * FOR is an integer FOR loop or a loop over query results. In the former + * case, the variable is just a name that we must instantiate as a loop + * local variable, regardless of any other definition it might have. + * Therefore, we always save the actual identifier into $$.name where it + * can be used for that case. We also save the outer-variable definition, + * if any, because that's what we need for the loop-over-query case. Note + * that we must NOT apply check_assignable() or any other semantic check + * until we know what's what. + * + * However, if we see a comma-separated list of names, we know that it + * can't be an integer FOR loop and so it's OK to check the variables + * immediately. In particular, for T_WORD followed by comma, we should + * complain that the name is not known rather than say it's a syntax error. + * Note that the non-error result of this case sets *both* $$.scalar and + * $$.row; see the for_control production. + */ +for_variable : T_DATUM + { + $$.name = NameOfDatum(&($1)); + $$.lineno = plpgsql_location_to_lineno(@1); + if ($1.datum->dtype == PLPGSQL_DTYPE_ROW || + $1.datum->dtype == PLPGSQL_DTYPE_REC) + { + $$.scalar = NULL; + $$.row = $1.datum; + } + else + { + int tok; + + $$.scalar = $1.datum; + $$.row = NULL; + /* check for comma-separated list */ + tok = yylex(); + plpgsql_push_back_token(tok); + if (tok == ',') + $$.row = (PLpgSQL_datum *) + read_into_scalar_list($$.name, + $$.scalar, + @1); + } + } + | T_WORD + { + int tok; + + $$.name = $1.ident; + $$.lineno = plpgsql_location_to_lineno(@1); + $$.scalar = NULL; + $$.row = NULL; + /* check for comma-separated list */ + tok = yylex(); + plpgsql_push_back_token(tok); + if (tok == ',') + word_is_not_variable(&($1), @1); + } + | T_CWORD + { + /* just to give a better message than "syntax error" */ + cword_is_not_variable(&($1), @1); + } + ; + +stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRAY expr_until_loop loop_body + { + PLpgSQL_stmt_foreach_a *new; + + new = palloc0(sizeof(PLpgSQL_stmt_foreach_a)); + new->cmd_type = PLPGSQL_STMT_FOREACH_A; + new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->label = $1; + new->slice = $4; + new->expr = $7; + new->body = $8.stmts; + + if ($3.row) + { + new->varno = $3.row->dno; + check_assignable($3.row, @3); + } + else if ($3.scalar) + { + new->varno = $3.scalar->dno; + check_assignable($3.scalar, @3); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("loop variable of FOREACH must be a known variable or list of variables"), + parser_errposition(@3))); + } + + check_labels($1, $8.end_label, $8.end_label_location); + plpgsql_ns_pop(); + + $$ = (PLpgSQL_stmt *) new; + } + ; + +foreach_slice : + { + $$ = 0; + } + | K_SLICE ICONST + { + $$ = $2; + } + ; + +stmt_exit : exit_type opt_label opt_exitcond + { + PLpgSQL_stmt_exit *new; + + new = palloc0(sizeof(PLpgSQL_stmt_exit)); + new->cmd_type = PLPGSQL_STMT_EXIT; + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->is_exit = $1; + new->lineno = plpgsql_location_to_lineno(@1); + new->label = $2; + new->cond = $3; + + if ($2) + { + /* We have a label, so verify it exists */ + PLpgSQL_nsitem *label; + + label = plpgsql_ns_lookup_label(plpgsql_ns_top(), $2); + if (label == NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("there is no label \"%s\" " + "attached to any block or loop enclosing this statement", + $2), + parser_errposition(@2))); + /* CONTINUE only allows loop labels */ + if (label->itemno != PLPGSQL_LABEL_LOOP && !new->is_exit) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("block label \"%s\" cannot be used in CONTINUE", + $2), + parser_errposition(@2))); + } + else + { + /* + * No label, so make sure there is some loop (an + * unlabeled EXIT does not match a block, so this + * is the same test for both EXIT and CONTINUE) + */ + if (plpgsql_ns_find_nearest_loop(plpgsql_ns_top()) == NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + new->is_exit ? + errmsg("EXIT cannot be used outside a loop, unless it has a label") : + errmsg("CONTINUE cannot be used outside a loop"), + parser_errposition(@1))); + } + + $$ = (PLpgSQL_stmt *) new; + } + ; + +exit_type : K_EXIT + { + $$ = true; + } + | K_CONTINUE + { + $$ = false; + } + ; + +stmt_return : K_RETURN + { + int tok; + + tok = yylex(); + if (tok == 0) + yyerror("unexpected end of function definition"); + + if (tok_is_keyword(tok, &yylval, + K_NEXT, "next")) + { + $$ = make_return_next_stmt(@1); + } + else if (tok_is_keyword(tok, &yylval, + K_QUERY, "query")) + { + $$ = make_return_query_stmt(@1); + } + else + { + plpgsql_push_back_token(tok); + $$ = make_return_stmt(@1); + } + } + ; + +stmt_raise : K_RAISE + { + PLpgSQL_stmt_raise *new; + int tok; + + new = palloc(sizeof(PLpgSQL_stmt_raise)); + + new->cmd_type = PLPGSQL_STMT_RAISE; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->elog_level = ERROR; /* default */ + new->condname = NULL; + new->message = NULL; + new->params = NIL; + new->options = NIL; + + tok = yylex(); + if (tok == 0) + yyerror("unexpected end of function definition"); + + /* + * We could have just RAISE, meaning to re-throw + * the current error. + */ + if (tok != ';') + { + /* + * First is an optional elog severity level. + */ + if (tok_is_keyword(tok, &yylval, + K_EXCEPTION, "exception")) + { + new->elog_level = ERROR; + tok = yylex(); + } + else if (tok_is_keyword(tok, &yylval, + K_WARNING, "warning")) + { + new->elog_level = WARNING; + tok = yylex(); + } + else if (tok_is_keyword(tok, &yylval, + K_NOTICE, "notice")) + { + new->elog_level = NOTICE; + tok = yylex(); + } + else if (tok_is_keyword(tok, &yylval, + K_INFO, "info")) + { + new->elog_level = INFO; + tok = yylex(); + } + else if (tok_is_keyword(tok, &yylval, + K_LOG, "log")) + { + new->elog_level = LOG; + tok = yylex(); + } + else if (tok_is_keyword(tok, &yylval, + K_DEBUG, "debug")) + { + new->elog_level = DEBUG1; + tok = yylex(); + } + if (tok == 0) + yyerror("unexpected end of function definition"); + + /* + * Next we can have a condition name, or + * equivalently SQLSTATE 'xxxxx', or a string + * literal that is the old-style message format, + * or USING to start the option list immediately. + */ + if (tok == SCONST) + { + /* old style message and parameters */ + new->message = yylval.str; + /* + * We expect either a semi-colon, which + * indicates no parameters, or a comma that + * begins the list of parameter expressions, + * or USING to begin the options list. + */ + tok = yylex(); + if (tok != ',' && tok != ';' && tok != K_USING) + yyerror("syntax error"); + + while (tok == ',') + { + PLpgSQL_expr *expr; + + expr = read_sql_construct(',', ';', K_USING, + ", or ; or USING", + RAW_PARSE_PLPGSQL_EXPR, + true, true, + NULL, &tok); + new->params = lappend(new->params, expr); + } + } + else if (tok != K_USING) + { + /* must be condition name or SQLSTATE */ + if (tok_is_keyword(tok, &yylval, + K_SQLSTATE, "sqlstate")) + { + /* next token should be a string literal */ + char *sqlstatestr; + + if (yylex() != SCONST) + yyerror("syntax error"); + sqlstatestr = yylval.str; + + if (strlen(sqlstatestr) != 5) + yyerror("invalid SQLSTATE code"); + if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5) + yyerror("invalid SQLSTATE code"); + new->condname = sqlstatestr; + } + else + { + if (tok == T_WORD) + new->condname = yylval.word.ident; + else if (plpgsql_token_is_unreserved_keyword(tok)) + new->condname = pstrdup(yylval.keyword); + else + yyerror("syntax error"); + plpgsql_recognize_err_condition(new->condname, + false); + } + tok = yylex(); + if (tok != ';' && tok != K_USING) + yyerror("syntax error"); + } + + if (tok == K_USING) + new->options = read_raise_options(); + } + + check_raise_parameters(new); + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_assert : K_ASSERT + { + PLpgSQL_stmt_assert *new; + int tok; + + new = palloc(sizeof(PLpgSQL_stmt_assert)); + + new->cmd_type = PLPGSQL_STMT_ASSERT; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + + new->cond = read_sql_expression2(',', ';', + ", or ;", + &tok); + + if (tok == ',') + new->message = read_sql_expression(';', ";"); + else + new->message = NULL; + + $$ = (PLpgSQL_stmt *) new; + } + ; + +loop_body : proc_sect K_END K_LOOP opt_label ';' + { + $$.stmts = $1; + $$.end_label = $4; + $$.end_label_location = @4; + } + ; + +/* + * T_WORD+T_CWORD match any initial identifier that is not a known plpgsql + * variable. (The composite case is probably a syntax error, but we'll let + * the core parser decide that.) Normally, we should assume that such a + * word is a SQL statement keyword that isn't also a plpgsql keyword. + * However, if the next token is assignment or '[' or '.', it can't be a valid + * SQL statement, and what we're probably looking at is an intended variable + * assignment. Give an appropriate complaint for that, instead of letting + * the core parser throw an unhelpful "syntax error". + */ +stmt_execsql : K_IMPORT + { + $$ = make_execsql_stmt(K_IMPORT, @1, NULL); + } + | K_INSERT + { + $$ = make_execsql_stmt(K_INSERT, @1, NULL); + } + | K_MERGE + { + $$ = make_execsql_stmt(K_MERGE, @1, NULL); + } + | T_WORD + { + int tok; + + tok = yylex(); + plpgsql_push_back_token(tok); + if (tok == '=' || tok == COLON_EQUALS || + tok == '[' || tok == '.') + word_is_not_variable(&($1), @1); + $$ = make_execsql_stmt(T_WORD, @1, &($1)); + } + | T_CWORD + { + int tok; + + tok = yylex(); + plpgsql_push_back_token(tok); + if (tok == '=' || tok == COLON_EQUALS || + tok == '[' || tok == '.') + cword_is_not_variable(&($1), @1); + $$ = make_execsql_stmt(T_CWORD, @1, NULL); + } + ; + +stmt_dynexecute : K_EXECUTE + { + PLpgSQL_stmt_dynexecute *new; + PLpgSQL_expr *expr; + int endtoken; + + expr = read_sql_construct(K_INTO, K_USING, ';', + "INTO or USING or ;", + RAW_PARSE_PLPGSQL_EXPR, + true, true, + NULL, &endtoken); + + new = palloc(sizeof(PLpgSQL_stmt_dynexecute)); + new->cmd_type = PLPGSQL_STMT_DYNEXECUTE; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->query = expr; + new->into = false; + new->strict = false; + new->target = NULL; + new->params = NIL; + + /* + * We loop to allow the INTO and USING clauses to + * appear in either order, since people easily get + * that wrong. This coding also prevents "INTO foo" + * from getting absorbed into a USING expression, + * which is *really* confusing. + */ + for (;;) + { + if (endtoken == K_INTO) + { + if (new->into) /* multiple INTO */ + yyerror("syntax error"); + new->into = true; + read_into_target(&new->target, &new->strict); + endtoken = yylex(); + } + else if (endtoken == K_USING) + { + if (new->params) /* multiple USING */ + yyerror("syntax error"); + do + { + expr = read_sql_construct(',', ';', K_INTO, + ", or ; or INTO", + RAW_PARSE_PLPGSQL_EXPR, + true, true, + NULL, &endtoken); + new->params = lappend(new->params, expr); + } while (endtoken == ','); + } + else if (endtoken == ';') + break; + else + yyerror("syntax error"); + } + + $$ = (PLpgSQL_stmt *) new; + } + ; + + +stmt_open : K_OPEN cursor_variable + { + PLpgSQL_stmt_open *new; + int tok; + + new = palloc0(sizeof(PLpgSQL_stmt_open)); + new->cmd_type = PLPGSQL_STMT_OPEN; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->curvar = $2->dno; + new->cursor_options = CURSOR_OPT_FAST_PLAN; + + if ($2->cursor_explicit_expr == NULL) + { + /* be nice if we could use opt_scrollable here */ + tok = yylex(); + if (tok_is_keyword(tok, &yylval, + K_NO, "no")) + { + tok = yylex(); + if (tok_is_keyword(tok, &yylval, + K_SCROLL, "scroll")) + { + new->cursor_options |= CURSOR_OPT_NO_SCROLL; + tok = yylex(); + } + } + else if (tok_is_keyword(tok, &yylval, + K_SCROLL, "scroll")) + { + new->cursor_options |= CURSOR_OPT_SCROLL; + tok = yylex(); + } + + if (tok != K_FOR) + yyerror("syntax error, expected \"FOR\""); + + tok = yylex(); + if (tok == K_EXECUTE) + { + int endtoken; + + new->dynquery = + read_sql_expression2(K_USING, ';', + "USING or ;", + &endtoken); + + /* If we found "USING", collect argument(s) */ + if (endtoken == K_USING) + { + PLpgSQL_expr *expr; + + do + { + expr = read_sql_expression2(',', ';', + ", or ;", + &endtoken); + new->params = lappend(new->params, + expr); + } while (endtoken == ','); + } + } + else + { + plpgsql_push_back_token(tok); + new->query = read_sql_stmt(); + } + } + else + { + /* predefined cursor query, so read args */ + new->argquery = read_cursor_args($2, ';'); + } + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO + { + PLpgSQL_stmt_fetch *fetch = $2; + PLpgSQL_variable *target; + + /* We have already parsed everything through the INTO keyword */ + read_into_target(&target, NULL); + + if (yylex() != ';') + yyerror("syntax error"); + + /* + * We don't allow multiple rows in PL/pgSQL's FETCH + * statement, only in MOVE. + */ + if (fetch->returns_multiple_rows) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("FETCH statement cannot return multiple rows"), + parser_errposition(@1))); + + fetch->lineno = plpgsql_location_to_lineno(@1); + fetch->target = target; + fetch->curvar = $3->dno; + fetch->is_move = false; + + $$ = (PLpgSQL_stmt *) fetch; + } + ; + +stmt_move : K_MOVE opt_fetch_direction cursor_variable ';' + { + PLpgSQL_stmt_fetch *fetch = $2; + + fetch->lineno = plpgsql_location_to_lineno(@1); + fetch->curvar = $3->dno; + fetch->is_move = true; + + $$ = (PLpgSQL_stmt *) fetch; + } + ; + +opt_fetch_direction : + { + $$ = read_fetch_direction(); + } + ; + +stmt_close : K_CLOSE cursor_variable ';' + { + PLpgSQL_stmt_close *new; + + new = palloc(sizeof(PLpgSQL_stmt_close)); + new->cmd_type = PLPGSQL_STMT_CLOSE; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->curvar = $2->dno; + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_null : K_NULL ';' + { + /* We do not bother building a node for NULL */ + $$ = NULL; + } + ; + +stmt_commit : K_COMMIT opt_transaction_chain ';' + { + PLpgSQL_stmt_commit *new; + + new = palloc(sizeof(PLpgSQL_stmt_commit)); + new->cmd_type = PLPGSQL_STMT_COMMIT; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->chain = $2; + + $$ = (PLpgSQL_stmt *) new; + } + ; + +stmt_rollback : K_ROLLBACK opt_transaction_chain ';' + { + PLpgSQL_stmt_rollback *new; + + new = palloc(sizeof(PLpgSQL_stmt_rollback)); + new->cmd_type = PLPGSQL_STMT_ROLLBACK; + new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->chain = $2; + + $$ = (PLpgSQL_stmt *) new; + } + ; + +opt_transaction_chain: + K_AND K_CHAIN { $$ = true; } + | K_AND K_NO K_CHAIN { $$ = false; } + | /* EMPTY */ { $$ = false; } + ; + + +cursor_variable : T_DATUM + { + /* + * In principle we should support a cursor_variable + * that is an array element, but for now we don't, so + * just throw an error if next token is '['. + */ + if ($1.datum->dtype != PLPGSQL_DTYPE_VAR || + plpgsql_peek() == '[') + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cursor variable must be a simple variable"), + parser_errposition(@1))); + + if (((PLpgSQL_var *) $1.datum)->datatype->typoid != REFCURSOROID) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("variable \"%s\" must be of type cursor or refcursor", + ((PLpgSQL_var *) $1.datum)->refname), + parser_errposition(@1))); + $$ = (PLpgSQL_var *) $1.datum; + } + | T_WORD + { + /* just to give a better message than "syntax error" */ + word_is_not_variable(&($1), @1); + } + | T_CWORD + { + /* just to give a better message than "syntax error" */ + cword_is_not_variable(&($1), @1); + } + ; + +exception_sect : + { $$ = NULL; } + | K_EXCEPTION + { + /* + * We use a mid-rule action to add these + * special variables to the namespace before + * parsing the WHEN clauses themselves. The + * scope of the names extends to the end of the + * current block. + */ + int lineno = plpgsql_location_to_lineno(@1); + PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block)); + PLpgSQL_variable *var; + + var = plpgsql_build_variable("sqlstate", lineno, + plpgsql_build_datatype(TEXTOID, + -1, + plpgsql_curr_compile->fn_input_collation, + NULL), + true); + var->isconst = true; + new->sqlstate_varno = var->dno; + + var = plpgsql_build_variable("sqlerrm", lineno, + plpgsql_build_datatype(TEXTOID, + -1, + plpgsql_curr_compile->fn_input_collation, + NULL), + true); + var->isconst = true; + new->sqlerrm_varno = var->dno; + + $$ = new; + } + proc_exceptions + { + PLpgSQL_exception_block *new = $2; + new->exc_list = $3; + + $$ = new; + } + ; + +proc_exceptions : proc_exceptions proc_exception + { + $$ = lappend($1, $2); + } + | proc_exception + { + $$ = list_make1($1); + } + ; + +proc_exception : K_WHEN proc_conditions K_THEN proc_sect + { + PLpgSQL_exception *new; + + new = palloc0(sizeof(PLpgSQL_exception)); + new->lineno = plpgsql_location_to_lineno(@1); + new->conditions = $2; + new->action = $4; + + $$ = new; + } + ; + +proc_conditions : proc_conditions K_OR proc_condition + { + PLpgSQL_condition *old; + + for (old = $1; old->next != NULL; old = old->next) + /* skip */ ; + old->next = $3; + $$ = $1; + } + | proc_condition + { + $$ = $1; + } + ; + +proc_condition : any_identifier + { + if (strcmp($1, "sqlstate") != 0) + { + $$ = plpgsql_parse_err_condition($1); + } + else + { + PLpgSQL_condition *new; + char *sqlstatestr; + + /* next token should be a string literal */ + if (yylex() != SCONST) + yyerror("syntax error"); + sqlstatestr = yylval.str; + + if (strlen(sqlstatestr) != 5) + yyerror("invalid SQLSTATE code"); + if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5) + yyerror("invalid SQLSTATE code"); + + new = palloc(sizeof(PLpgSQL_condition)); + new->sqlerrstate = + MAKE_SQLSTATE(sqlstatestr[0], + sqlstatestr[1], + sqlstatestr[2], + sqlstatestr[3], + sqlstatestr[4]); + new->condname = sqlstatestr; + new->next = NULL; + + $$ = new; + } + } + ; + +expr_until_semi : + { $$ = read_sql_expression(';', ";"); } + ; + +expr_until_then : + { $$ = read_sql_expression(K_THEN, "THEN"); } + ; + +expr_until_loop : + { $$ = read_sql_expression(K_LOOP, "LOOP"); } + ; + +opt_block_label : + { + plpgsql_ns_push(NULL, PLPGSQL_LABEL_BLOCK); + $$ = NULL; + } + | LESS_LESS any_identifier GREATER_GREATER + { + plpgsql_ns_push($2, PLPGSQL_LABEL_BLOCK); + $$ = $2; + } + ; + +opt_loop_label : + { + plpgsql_ns_push(NULL, PLPGSQL_LABEL_LOOP); + $$ = NULL; + } + | LESS_LESS any_identifier GREATER_GREATER + { + plpgsql_ns_push($2, PLPGSQL_LABEL_LOOP); + $$ = $2; + } + ; + +opt_label : + { + $$ = NULL; + } + | any_identifier + { + /* label validity will be checked by outer production */ + $$ = $1; + } + ; + +opt_exitcond : ';' + { $$ = NULL; } + | K_WHEN expr_until_semi + { $$ = $2; } + ; + +/* + * need to allow DATUM because scanner will have tried to resolve as variable + */ +any_identifier : T_WORD + { + $$ = $1.ident; + } + | unreserved_keyword + { + $$ = pstrdup($1); + } + | T_DATUM + { + if ($1.ident == NULL) /* composite name not OK */ + yyerror("syntax error"); + $$ = $1.ident; + } + ; + +unreserved_keyword : + K_ABSOLUTE + | K_ALIAS + | K_AND + | K_ARRAY + | K_ASSERT + | K_BACKWARD + | K_CALL + | K_CHAIN + | K_CLOSE + | K_COLLATE + | K_COLUMN + | K_COLUMN_NAME + | K_COMMIT + | K_CONSTANT + | K_CONSTRAINT + | K_CONSTRAINT_NAME + | K_CONTINUE + | K_CURRENT + | K_CURSOR + | K_DATATYPE + | K_DEBUG + | K_DEFAULT + | K_DETAIL + | K_DIAGNOSTICS + | K_DO + | K_DUMP + | K_ELSIF + | K_ERRCODE + | K_ERROR + | K_EXCEPTION + | K_EXIT + | K_FETCH + | K_FIRST + | K_FORWARD + | K_GET + | K_HINT + | K_IMPORT + | K_INFO + | K_INSERT + | K_IS + | K_LAST + | K_LOG + | K_MERGE + | K_MESSAGE + | K_MESSAGE_TEXT + | K_MOVE + | K_NEXT + | K_NO + | K_NOTICE + | K_OPEN + | K_OPTION + | K_PERFORM + | K_PG_CONTEXT + | K_PG_DATATYPE_NAME + | K_PG_EXCEPTION_CONTEXT + | K_PG_EXCEPTION_DETAIL + | K_PG_EXCEPTION_HINT + | K_PG_ROUTINE_OID + | K_PRINT_STRICT_PARAMS + | K_PRIOR + | K_QUERY + | K_RAISE + | K_RELATIVE + | K_RETURN + | K_RETURNED_SQLSTATE + | K_REVERSE + | K_ROLLBACK + | K_ROW_COUNT + | K_ROWTYPE + | K_SCHEMA + | K_SCHEMA_NAME + | K_SCROLL + | K_SLICE + | K_SQLSTATE + | K_STACKED + | K_TABLE + | K_TABLE_NAME + | K_TYPE + | K_USE_COLUMN + | K_USE_VARIABLE + | K_VARIABLE_CONFLICT + | K_WARNING + ; + +%% + +/* + * Check whether a token represents an "unreserved keyword". + * We have various places where we want to recognize a keyword in preference + * to a variable name, but not reserve that keyword in other contexts. + * Hence, this kluge. + */ +static bool +tok_is_keyword(int token, union YYSTYPE *lval, + int kw_token, const char *kw_str) +{ + if (token == kw_token) + { + /* Normal case, was recognized by scanner (no conflicting variable) */ + return true; + } + else if (token == T_DATUM) + { + /* + * It's a variable, so recheck the string name. Note we will not + * match composite names (hence an unreserved word followed by "." + * will not be recognized). + */ + if (!lval->wdatum.quoted && lval->wdatum.ident != NULL && + strcmp(lval->wdatum.ident, kw_str) == 0) + return true; + } + return false; /* not the keyword */ +} + +/* + * Convenience routine to complain when we expected T_DATUM and got T_WORD, + * ie, unrecognized variable. + */ +static void +word_is_not_variable(PLword *word, int location) +{ + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("\"%s\" is not a known variable", + word->ident), + parser_errposition(location))); +} + +/* Same, for a CWORD */ +static void +cword_is_not_variable(PLcword *cword, int location) +{ + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("\"%s\" is not a known variable", + NameListToString(cword->idents)), + parser_errposition(location))); +} + +/* + * Convenience routine to complain when we expected T_DATUM and got + * something else. "tok" must be the current token, since we also + * look at yylval and yylloc. + */ +static void +current_token_is_not_variable(int tok) +{ + if (tok == T_WORD) + word_is_not_variable(&(yylval.word), yylloc); + else if (tok == T_CWORD) + cword_is_not_variable(&(yylval.cword), yylloc); + else + yyerror("syntax error"); +} + +/* Convenience routine to read an expression with one possible terminator */ +static PLpgSQL_expr * +read_sql_expression(int until, const char *expected) +{ + return read_sql_construct(until, 0, 0, expected, + RAW_PARSE_PLPGSQL_EXPR, + true, true, NULL, NULL); +} + +/* Convenience routine to read an expression with two possible terminators */ +static PLpgSQL_expr * +read_sql_expression2(int until, int until2, const char *expected, + int *endtoken) +{ + return read_sql_construct(until, until2, 0, expected, + RAW_PARSE_PLPGSQL_EXPR, + true, true, NULL, endtoken); +} + +/* Convenience routine to read a SQL statement that must end with ';' */ +static PLpgSQL_expr * +read_sql_stmt(void) +{ + return read_sql_construct(';', 0, 0, ";", + RAW_PARSE_DEFAULT, + false, true, NULL, NULL); +} + +/* + * Read a SQL construct and build a PLpgSQL_expr for it. + * + * until: token code for expected terminator + * until2: token code for alternate terminator (pass 0 if none) + * until3: token code for another alternate terminator (pass 0 if none) + * expected: text to use in complaining that terminator was not found + * parsemode: raw_parser() mode to use + * isexpression: whether to say we're reading an "expression" or a "statement" + * valid_sql: whether to check the syntax of the expr + * startloc: if not NULL, location of first token is stored at *startloc + * endtoken: if not NULL, ending token is stored at *endtoken + * (this is only interesting if until2 or until3 isn't zero) + */ +static PLpgSQL_expr * +read_sql_construct(int until, + int until2, + int until3, + const char *expected, + RawParseMode parsemode, + bool isexpression, + bool valid_sql, + int *startloc, + int *endtoken) +{ + int tok; + StringInfoData ds; + IdentifierLookup save_IdentifierLookup; + int startlocation = -1; + int endlocation = -1; + int parenlevel = 0; + PLpgSQL_expr *expr; + + initStringInfo(&ds); + + /* special lookup mode for identifiers within the SQL text */ + save_IdentifierLookup = plpgsql_IdentifierLookup; + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; + + for (;;) + { + tok = yylex(); + if (startlocation < 0) /* remember loc of first token */ + startlocation = yylloc; + if (tok == until && parenlevel == 0) + break; + if (tok == until2 && parenlevel == 0) + break; + if (tok == until3 && parenlevel == 0) + break; + if (tok == '(' || tok == '[') + parenlevel++; + else if (tok == ')' || tok == ']') + { + parenlevel--; + if (parenlevel < 0) + yyerror("mismatched parentheses"); + } + /* + * End of function definition is an error, and we don't expect to + * hit a semicolon either (unless it's the until symbol, in which + * case we should have fallen out above). + */ + if (tok == 0 || tok == ';') + { + if (parenlevel != 0) + yyerror("mismatched parentheses"); + if (isexpression) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("missing \"%s\" at end of SQL expression", + expected), + parser_errposition(yylloc))); + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("missing \"%s\" at end of SQL statement", + expected), + parser_errposition(yylloc))); + } + /* Remember end+1 location of last accepted token */ + endlocation = yylloc + plpgsql_token_length(); + } + + plpgsql_IdentifierLookup = save_IdentifierLookup; + + if (startloc) + *startloc = startlocation; + if (endtoken) + *endtoken = tok; + + /* give helpful complaint about empty input */ + if (startlocation >= endlocation) + { + if (isexpression) + yyerror("missing expression"); + else + yyerror("missing SQL statement"); + } + + /* + * We save only the text from startlocation to endlocation-1. This + * suppresses the "until" token as well as any whitespace or comments + * following the last accepted token. (We used to strip such trailing + * whitespace by hand, but that causes problems if there's a "-- comment" + * in front of said whitespace.) + */ + plpgsql_append_source_text(&ds, startlocation, endlocation); + + expr = palloc0(sizeof(PLpgSQL_expr)); + expr->query = pstrdup(ds.data); + expr->parseMode = parsemode; + expr->plan = NULL; + expr->paramnos = NULL; + expr->target_param = -1; + expr->ns = plpgsql_ns_top(); + pfree(ds.data); + + if (valid_sql) + check_sql_expr(expr->query, expr->parseMode, startlocation); + + return expr; +} + +/* + * Read a datatype declaration, consuming the current lookahead token if any. + * Returns a PLpgSQL_type struct. + */ +static PLpgSQL_type * +read_datatype(int tok) +{ + StringInfoData ds; + char *type_name; + int startlocation; + PLpgSQL_type *result = NULL; + int parenlevel = 0; + + /* Should only be called while parsing DECLARE sections */ + Assert(plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_DECLARE); + + /* Often there will be a lookahead token, but if not, get one */ + if (tok == YYEMPTY) + tok = yylex(); + + /* The current token is the start of what we'll pass to parse_datatype */ + startlocation = yylloc; + + /* + * If we have a simple or composite identifier, check for %TYPE and + * %ROWTYPE constructs. + */ + if (tok == T_WORD) + { + char *dtname = yylval.word.ident; + + tok = yylex(); + if (tok == '%') + { + tok = yylex(); + if (tok_is_keyword(tok, &yylval, + K_TYPE, "type")) + result = plpgsql_parse_wordtype(dtname); + else if (tok_is_keyword(tok, &yylval, + K_ROWTYPE, "rowtype")) + result = plpgsql_parse_wordrowtype(dtname); + } + } + else if (plpgsql_token_is_unreserved_keyword(tok)) + { + char *dtname = pstrdup(yylval.keyword); + + tok = yylex(); + if (tok == '%') + { + tok = yylex(); + if (tok_is_keyword(tok, &yylval, + K_TYPE, "type")) + result = plpgsql_parse_wordtype(dtname); + else if (tok_is_keyword(tok, &yylval, + K_ROWTYPE, "rowtype")) + result = plpgsql_parse_wordrowtype(dtname); + } + } + else if (tok == T_CWORD) + { + List *dtnames = yylval.cword.idents; + + tok = yylex(); + if (tok == '%') + { + tok = yylex(); + if (tok_is_keyword(tok, &yylval, + K_TYPE, "type")) + result = plpgsql_parse_cwordtype(dtnames); + else if (tok_is_keyword(tok, &yylval, + K_ROWTYPE, "rowtype")) + result = plpgsql_parse_cwordrowtype(dtnames); + } + } + + /* + * If we recognized a %TYPE or %ROWTYPE construct, see if it is followed + * by array decoration: [ ARRAY ] [ '[' [ iconst ] ']' [ ... ] ] + * + * Like the core parser, we ignore the specific numbers and sizes of + * dimensions; arrays of different dimensionality are still the same type + * in Postgres. + */ + if (result) + { + bool is_array = false; + + tok = yylex(); + if (tok_is_keyword(tok, &yylval, + K_ARRAY, "array")) + { + is_array = true; + tok = yylex(); + } + while (tok == '[') + { + is_array = true; + tok = yylex(); + if (tok == ICONST) + tok = yylex(); + if (tok != ']') + yyerror("syntax error, expected \"]\""); + tok = yylex(); + } + plpgsql_push_back_token(tok); + + if (is_array) + result = plpgsql_build_datatype_arrayof(result); + + return result; + } + + /* + * Not %TYPE or %ROWTYPE, so scan to the end of the datatype declaration, + * which could include typmod or array decoration. We are not very picky + * here, instead relying on parse_datatype to complain about garbage. But + * we must count parens to handle typmods within cursor_arg correctly. + */ + while (tok != ';') + { + if (tok == 0) + { + if (parenlevel != 0) + yyerror("mismatched parentheses"); + else + yyerror("incomplete data type declaration"); + } + /* Possible followers for datatype in a declaration */ + if (tok == K_COLLATE || tok == K_NOT || + tok == '=' || tok == COLON_EQUALS || tok == K_DEFAULT) + break; + /* Possible followers for datatype in a cursor_arg list */ + if ((tok == ',' || tok == ')') && parenlevel == 0) + break; + if (tok == '(') + parenlevel++; + else if (tok == ')') + parenlevel--; + + tok = yylex(); + } + + /* set up ds to contain complete typename text */ + initStringInfo(&ds); + plpgsql_append_source_text(&ds, startlocation, yylloc); + type_name = ds.data; + + if (type_name[0] == '\0') + yyerror("missing data type declaration"); + + result = parse_datatype(type_name, startlocation); + + pfree(ds.data); + + plpgsql_push_back_token(tok); + + return result; +} + +/* + * Read a generic SQL statement. We have already read its first token; + * firsttoken is that token's code and location its starting location. + * If firsttoken == T_WORD, pass its yylval value as "word", else pass NULL. + */ +static PLpgSQL_stmt * +make_execsql_stmt(int firsttoken, int location, PLword *word) +{ + StringInfoData ds; + IdentifierLookup save_IdentifierLookup; + PLpgSQL_stmt_execsql *execsql; + PLpgSQL_expr *expr; + PLpgSQL_variable *target = NULL; + int tok; + int prev_tok; + bool have_into = false; + bool have_strict = false; + int into_start_loc = -1; + int into_end_loc = -1; + int paren_depth = 0; + int begin_depth = 0; + bool in_routine_definition = false; + int token_count = 0; + char tokens[4]; /* records the first few tokens */ + + initStringInfo(&ds); + + memset(tokens, 0, sizeof(tokens)); + + /* special lookup mode for identifiers within the SQL text */ + save_IdentifierLookup = plpgsql_IdentifierLookup; + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; + + /* + * Scan to the end of the SQL command. Identify any INTO-variables + * clause lurking within it, and parse that via read_into_target(). + * + * The end of the statement is defined by a semicolon ... except that + * semicolons within parentheses or BEGIN/END blocks don't terminate a + * statement. We follow psql's lead in not recognizing BEGIN/END except + * after CREATE [OR REPLACE] {FUNCTION|PROCEDURE}. END can also appear + * within a CASE construct, so we treat CASE/END like BEGIN/END. + * + * Because INTO is sometimes used in the main SQL grammar, we have to be + * careful not to take any such usage of INTO as a PL/pgSQL INTO clause. + * There are currently three such cases: + * + * 1. SELECT ... INTO. We don't care, we just override that with the + * PL/pgSQL definition. + * + * 2. INSERT INTO. This is relatively easy to recognize since the words + * must appear adjacently; but we can't assume INSERT starts the command, + * because it can appear in CREATE RULE or WITH. Unfortunately, INSERT is + * *not* fully reserved, so that means there is a chance of a false match; + * but it's not very likely. + * + * 3. IMPORT FOREIGN SCHEMA ... INTO. This is not allowed in CREATE RULE + * or WITH, so we just check for IMPORT as the command's first token. + * (If IMPORT FOREIGN SCHEMA returned data someone might wish to capture + * with an INTO-variables clause, we'd have to work much harder here.) + * + * Fortunately, INTO is a fully reserved word in the main grammar, so + * at least we need not worry about it appearing as an identifier. + * + * Any future additional uses of INTO in the main grammar will doubtless + * break this logic again ... beware! + */ + tok = firsttoken; + if (tok == T_WORD && strcmp(word->ident, "create") == 0) + tokens[token_count] = 'c'; + token_count++; + + for (;;) + { + prev_tok = tok; + tok = yylex(); + if (have_into && into_end_loc < 0) + into_end_loc = yylloc; /* token after the INTO part */ + /* Detect CREATE [OR REPLACE] {FUNCTION|PROCEDURE} */ + if (tokens[0] == 'c' && token_count < sizeof(tokens)) + { + if (tok == K_OR) + tokens[token_count] = 'o'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "replace") == 0) + tokens[token_count] = 'r'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "function") == 0) + tokens[token_count] = 'f'; + else if (tok == T_WORD && + strcmp(yylval.word.ident, "procedure") == 0) + tokens[token_count] = 'f'; /* treat same as "function" */ + if (tokens[1] == 'f' || + (tokens[1] == 'o' && tokens[2] == 'r' && tokens[3] == 'f')) + in_routine_definition = true; + token_count++; + } + /* Track paren nesting (needed for CREATE RULE syntax) */ + if (tok == '(') + paren_depth++; + else if (tok == ')' && paren_depth > 0) + paren_depth--; + /* We need track BEGIN/END nesting only in a routine definition */ + if (in_routine_definition && paren_depth == 0) + { + if (tok == K_BEGIN || tok == K_CASE) + begin_depth++; + else if (tok == K_END && begin_depth > 0) + begin_depth--; + } + /* Command-ending semicolon? */ + if (tok == ';' && paren_depth == 0 && begin_depth == 0) + break; + if (tok == 0) + yyerror("unexpected end of function definition"); + if (tok == K_INTO) + { + if (prev_tok == K_INSERT) + continue; /* INSERT INTO is not an INTO-target */ + if (prev_tok == K_MERGE) + continue; /* MERGE INTO is not an INTO-target */ + if (firsttoken == K_IMPORT) + continue; /* IMPORT ... INTO is not an INTO-target */ + if (have_into) + yyerror("INTO specified more than once"); + have_into = true; + into_start_loc = yylloc; + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; + read_into_target(&target, &have_strict); + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR; + } + } + + plpgsql_IdentifierLookup = save_IdentifierLookup; + + if (have_into) + { + /* + * Insert an appropriate number of spaces corresponding to the + * INTO text, so that locations within the redacted SQL statement + * still line up with those in the original source text. + */ + plpgsql_append_source_text(&ds, location, into_start_loc); + appendStringInfoSpaces(&ds, into_end_loc - into_start_loc); + plpgsql_append_source_text(&ds, into_end_loc, yylloc); + } + else + plpgsql_append_source_text(&ds, location, yylloc); + + /* trim any trailing whitespace, for neatness */ + while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1])) + ds.data[--ds.len] = '\0'; + + expr = palloc0(sizeof(PLpgSQL_expr)); + expr->query = pstrdup(ds.data); + expr->parseMode = RAW_PARSE_DEFAULT; + expr->plan = NULL; + expr->paramnos = NULL; + expr->target_param = -1; + expr->ns = plpgsql_ns_top(); + pfree(ds.data); + + check_sql_expr(expr->query, expr->parseMode, location); + + execsql = palloc0(sizeof(PLpgSQL_stmt_execsql)); + execsql->cmd_type = PLPGSQL_STMT_EXECSQL; + execsql->lineno = plpgsql_location_to_lineno(location); + execsql->stmtid = ++plpgsql_curr_compile->nstatements; + execsql->sqlstmt = expr; + execsql->into = have_into; + execsql->strict = have_strict; + execsql->target = target; + + return (PLpgSQL_stmt *) execsql; +} + + +/* + * Read FETCH or MOVE direction clause (everything through FROM/IN). + */ +static PLpgSQL_stmt_fetch * +read_fetch_direction(void) +{ + PLpgSQL_stmt_fetch *fetch; + int tok; + bool check_FROM = true; + + /* + * We create the PLpgSQL_stmt_fetch struct here, but only fill in + * the fields arising from the optional direction clause + */ + fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch)); + fetch->cmd_type = PLPGSQL_STMT_FETCH; + fetch->stmtid = ++plpgsql_curr_compile->nstatements; + /* set direction defaults: */ + fetch->direction = FETCH_FORWARD; + fetch->how_many = 1; + fetch->expr = NULL; + fetch->returns_multiple_rows = false; + + tok = yylex(); + if (tok == 0) + yyerror("unexpected end of function definition"); + + if (tok_is_keyword(tok, &yylval, + K_NEXT, "next")) + { + /* use defaults */ + } + else if (tok_is_keyword(tok, &yylval, + K_PRIOR, "prior")) + { + fetch->direction = FETCH_BACKWARD; + } + else if (tok_is_keyword(tok, &yylval, + K_FIRST, "first")) + { + fetch->direction = FETCH_ABSOLUTE; + } + else if (tok_is_keyword(tok, &yylval, + K_LAST, "last")) + { + fetch->direction = FETCH_ABSOLUTE; + fetch->how_many = -1; + } + else if (tok_is_keyword(tok, &yylval, + K_ABSOLUTE, "absolute")) + { + fetch->direction = FETCH_ABSOLUTE; + fetch->expr = read_sql_expression2(K_FROM, K_IN, + "FROM or IN", + NULL); + check_FROM = false; + } + else if (tok_is_keyword(tok, &yylval, + K_RELATIVE, "relative")) + { + fetch->direction = FETCH_RELATIVE; + fetch->expr = read_sql_expression2(K_FROM, K_IN, + "FROM or IN", + NULL); + check_FROM = false; + } + else if (tok_is_keyword(tok, &yylval, + K_ALL, "all")) + { + fetch->how_many = FETCH_ALL; + fetch->returns_multiple_rows = true; + } + else if (tok_is_keyword(tok, &yylval, + K_FORWARD, "forward")) + { + complete_direction(fetch, &check_FROM); + } + else if (tok_is_keyword(tok, &yylval, + K_BACKWARD, "backward")) + { + fetch->direction = FETCH_BACKWARD; + complete_direction(fetch, &check_FROM); + } + else if (tok == K_FROM || tok == K_IN) + { + /* empty direction */ + check_FROM = false; + } + else if (tok == T_DATUM) + { + /* Assume there's no direction clause and tok is a cursor name */ + plpgsql_push_back_token(tok); + check_FROM = false; + } + else + { + /* + * Assume it's a count expression with no preceding keyword. + * Note: we allow this syntax because core SQL does, but it's + * ambiguous with the case of an omitted direction clause; for + * instance, "MOVE n IN c" will fail if n is a variable, because the + * preceding else-arm will trigger. Perhaps this can be improved + * someday, but it hardly seems worth a lot of work. + */ + plpgsql_push_back_token(tok); + fetch->expr = read_sql_expression2(K_FROM, K_IN, + "FROM or IN", + NULL); + fetch->returns_multiple_rows = true; + check_FROM = false; + } + + /* check FROM or IN keyword after direction's specification */ + if (check_FROM) + { + tok = yylex(); + if (tok != K_FROM && tok != K_IN) + yyerror("expected FROM or IN"); + } + + return fetch; +} + +/* + * Process remainder of FETCH/MOVE direction after FORWARD or BACKWARD. + * Allows these cases: + * FORWARD expr, FORWARD ALL, FORWARD + * BACKWARD expr, BACKWARD ALL, BACKWARD + */ +static void +complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM) +{ + int tok; + + tok = yylex(); + if (tok == 0) + yyerror("unexpected end of function definition"); + + if (tok == K_FROM || tok == K_IN) + { + *check_FROM = false; + return; + } + + if (tok == K_ALL) + { + fetch->how_many = FETCH_ALL; + fetch->returns_multiple_rows = true; + *check_FROM = true; + return; + } + + plpgsql_push_back_token(tok); + fetch->expr = read_sql_expression2(K_FROM, K_IN, + "FROM or IN", + NULL); + fetch->returns_multiple_rows = true; + *check_FROM = false; +} + + +static PLpgSQL_stmt * +make_return_stmt(int location) +{ + PLpgSQL_stmt_return *new; + + new = palloc0(sizeof(PLpgSQL_stmt_return)); + new->cmd_type = PLPGSQL_STMT_RETURN; + new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->expr = NULL; + new->retvarno = -1; + + if (plpgsql_curr_compile->fn_retset) + { + if (yylex() != ';') + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("RETURN cannot have a parameter in function returning set"), + errhint("Use RETURN NEXT or RETURN QUERY."), + parser_errposition(yylloc))); + } + else if (plpgsql_curr_compile->fn_rettype == VOIDOID) + { + if (yylex() != ';') + { + if (plpgsql_curr_compile->fn_prokind == PROKIND_PROCEDURE) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("RETURN cannot have a parameter in a procedure"), + parser_errposition(yylloc))); + else + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("RETURN cannot have a parameter in function returning void"), + parser_errposition(yylloc))); + } + } + else if (plpgsql_curr_compile->out_param_varno >= 0) + { + if (yylex() != ';') + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("RETURN cannot have a parameter in function with OUT parameters"), + parser_errposition(yylloc))); + new->retvarno = plpgsql_curr_compile->out_param_varno; + } + else + { + /* + * We want to special-case simple variable references for efficiency. + * So peek ahead to see if that's what we have. + */ + int tok = yylex(); + + if (tok == T_DATUM && plpgsql_peek() == ';' && + (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)) + { + new->retvarno = yylval.wdatum.datum->dno; + /* eat the semicolon token that we only peeked at above */ + tok = yylex(); + Assert(tok == ';'); + } + else + { + /* + * Not (just) a variable name, so treat as expression. + * + * Note that a well-formed expression is _required_ here; + * anything else is a compile-time error. + */ + plpgsql_push_back_token(tok); + new->expr = read_sql_expression(';', ";"); + } + } + + return (PLpgSQL_stmt *) new; +} + + +static PLpgSQL_stmt * +make_return_next_stmt(int location) +{ + PLpgSQL_stmt_return_next *new; + + if (!plpgsql_curr_compile->fn_retset) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cannot use RETURN NEXT in a non-SETOF function"), + parser_errposition(location))); + + new = palloc0(sizeof(PLpgSQL_stmt_return_next)); + new->cmd_type = PLPGSQL_STMT_RETURN_NEXT; + new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->expr = NULL; + new->retvarno = -1; + + if (plpgsql_curr_compile->out_param_varno >= 0) + { + if (yylex() != ';') + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"), + parser_errposition(yylloc))); + new->retvarno = plpgsql_curr_compile->out_param_varno; + } + else + { + /* + * We want to special-case simple variable references for efficiency. + * So peek ahead to see if that's what we have. + */ + int tok = yylex(); + + if (tok == T_DATUM && plpgsql_peek() == ';' && + (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)) + { + new->retvarno = yylval.wdatum.datum->dno; + /* eat the semicolon token that we only peeked at above */ + tok = yylex(); + Assert(tok == ';'); + } + else + { + /* + * Not (just) a variable name, so treat as expression. + * + * Note that a well-formed expression is _required_ here; + * anything else is a compile-time error. + */ + plpgsql_push_back_token(tok); + new->expr = read_sql_expression(';', ";"); + } + } + + return (PLpgSQL_stmt *) new; +} + + +static PLpgSQL_stmt * +make_return_query_stmt(int location) +{ + PLpgSQL_stmt_return_query *new; + int tok; + + if (!plpgsql_curr_compile->fn_retset) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cannot use RETURN QUERY in a non-SETOF function"), + parser_errposition(location))); + + new = palloc0(sizeof(PLpgSQL_stmt_return_query)); + new->cmd_type = PLPGSQL_STMT_RETURN_QUERY; + new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; + + /* check for RETURN QUERY EXECUTE */ + if ((tok = yylex()) != K_EXECUTE) + { + /* ordinary static query */ + plpgsql_push_back_token(tok); + new->query = read_sql_stmt(); + } + else + { + /* dynamic SQL */ + int term; + + new->dynquery = read_sql_expression2(';', K_USING, "; or USING", + &term); + if (term == K_USING) + { + do + { + PLpgSQL_expr *expr; + + expr = read_sql_expression2(',', ';', ", or ;", &term); + new->params = lappend(new->params, expr); + } while (term == ','); + } + } + + return (PLpgSQL_stmt *) new; +} + + +/* convenience routine to fetch the name of a T_DATUM */ +static char * +NameOfDatum(PLwdatum *wdatum) +{ + if (wdatum->ident) + return wdatum->ident; + Assert(wdatum->idents != NIL); + return NameListToString(wdatum->idents); +} + +static void +check_assignable(PLpgSQL_datum *datum, int location) +{ + switch (datum->dtype) + { + case PLPGSQL_DTYPE_VAR: + case PLPGSQL_DTYPE_PROMISE: + case PLPGSQL_DTYPE_REC: + if (((PLpgSQL_variable *) datum)->isconst) + ereport(ERROR, + (errcode(ERRCODE_ERROR_IN_ASSIGNMENT), + errmsg("variable \"%s\" is declared CONSTANT", + ((PLpgSQL_variable *) datum)->refname), + parser_errposition(location))); + break; + case PLPGSQL_DTYPE_ROW: + /* always assignable; member vars were checked at compile time */ + break; + case PLPGSQL_DTYPE_RECFIELD: + /* assignable if parent record is */ + check_assignable(plpgsql_Datums[((PLpgSQL_recfield *) datum)->recparentno], + location); + break; + default: + elog(ERROR, "unrecognized dtype: %d", datum->dtype); + break; + } +} + +/* + * Read the argument of an INTO clause. On entry, we have just read the + * INTO keyword. + */ +static void +read_into_target(PLpgSQL_variable **target, bool *strict) +{ + int tok; + + /* Set default results */ + *target = NULL; + if (strict) + *strict = false; + + tok = yylex(); + if (strict && tok == K_STRICT) + { + *strict = true; + tok = yylex(); + } + + /* + * Currently, a row or record variable can be the single INTO target, + * but not a member of a multi-target list. So we throw error if there + * is a comma after it, because that probably means the user tried to + * write a multi-target list. If this ever gets generalized, we should + * probably refactor read_into_scalar_list so it handles all cases. + */ + switch (tok) + { + case T_DATUM: + if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC) + { + check_assignable(yylval.wdatum.datum, yylloc); + *target = (PLpgSQL_variable *) yylval.wdatum.datum; + + if ((tok = yylex()) == ',') + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("record variable cannot be part of multiple-item INTO list"), + parser_errposition(yylloc))); + plpgsql_push_back_token(tok); + } + else + { + *target = (PLpgSQL_variable *) + read_into_scalar_list(NameOfDatum(&(yylval.wdatum)), + yylval.wdatum.datum, yylloc); + } + break; + + default: + /* just to give a better message than "syntax error" */ + current_token_is_not_variable(tok); + } +} + +/* + * Given the first datum and name in the INTO list, continue to read + * comma-separated scalar variables until we run out. Then construct + * and return a fake "row" variable that represents the list of + * scalars. + */ +static PLpgSQL_row * +read_into_scalar_list(char *initial_name, + PLpgSQL_datum *initial_datum, + int initial_location) +{ + int nfields; + char *fieldnames[1024]; + int varnos[1024]; + PLpgSQL_row *row; + int tok; + + check_assignable(initial_datum, initial_location); + fieldnames[0] = initial_name; + varnos[0] = initial_datum->dno; + nfields = 1; + + while ((tok = yylex()) == ',') + { + /* Check for array overflow */ + if (nfields >= 1024) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("too many INTO variables specified"), + parser_errposition(yylloc))); + + tok = yylex(); + switch (tok) + { + case T_DATUM: + check_assignable(yylval.wdatum.datum, yylloc); + if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW || + yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("\"%s\" is not a scalar variable", + NameOfDatum(&(yylval.wdatum))), + parser_errposition(yylloc))); + fieldnames[nfields] = NameOfDatum(&(yylval.wdatum)); + varnos[nfields++] = yylval.wdatum.datum->dno; + break; + + default: + /* just to give a better message than "syntax error" */ + current_token_is_not_variable(tok); + } + } + + /* + * We read an extra, non-comma token from yylex(), so push it + * back onto the input stream + */ + plpgsql_push_back_token(tok); + + row = palloc0(sizeof(PLpgSQL_row)); + row->dtype = PLPGSQL_DTYPE_ROW; + row->refname = "(unnamed row)"; + row->lineno = plpgsql_location_to_lineno(initial_location); + row->rowtupdesc = NULL; + row->nfields = nfields; + row->fieldnames = palloc(sizeof(char *) * nfields); + row->varnos = palloc(sizeof(int) * nfields); + while (--nfields >= 0) + { + row->fieldnames[nfields] = fieldnames[nfields]; + row->varnos[nfields] = varnos[nfields]; + } + + plpgsql_adddatum((PLpgSQL_datum *) row); + + return row; +} + +/* + * Convert a single scalar into a "row" list. This is exactly + * like read_into_scalar_list except we never consume any input. + * + * Note: lineno could be computed from location, but since callers + * have it at hand already, we may as well pass it in. + */ +static PLpgSQL_row * +make_scalar_list1(char *initial_name, + PLpgSQL_datum *initial_datum, + int lineno, int location) +{ + PLpgSQL_row *row; + + check_assignable(initial_datum, location); + + row = palloc0(sizeof(PLpgSQL_row)); + row->dtype = PLPGSQL_DTYPE_ROW; + row->refname = "(unnamed row)"; + row->lineno = lineno; + row->rowtupdesc = NULL; + row->nfields = 1; + row->fieldnames = palloc(sizeof(char *)); + row->varnos = palloc(sizeof(int)); + row->fieldnames[0] = initial_name; + row->varnos[0] = initial_datum->dno; + + plpgsql_adddatum((PLpgSQL_datum *) row); + + return row; +} + +/* + * When the PL/pgSQL parser expects to see a SQL statement, it is very + * liberal in what it accepts; for example, we often assume an + * unrecognized keyword is the beginning of a SQL statement. This + * avoids the need to duplicate parts of the SQL grammar in the + * PL/pgSQL grammar, but it means we can accept wildly malformed + * input. To try and catch some of the more obviously invalid input, + * we run the strings we expect to be SQL statements through the main + * SQL parser. + * + * We only invoke the raw parser (not the analyzer); this doesn't do + * any database access and does not check any semantic rules, it just + * checks for basic syntactic correctness. We do this here, rather + * than after parsing has finished, because a malformed SQL statement + * may cause the PL/pgSQL parser to become confused about statement + * borders. So it is best to bail out as early as we can. + * + * It is assumed that "stmt" represents a copy of the function source text + * beginning at offset "location". We use this assumption to transpose + * any error cursor position back to the function source text. + * If no error cursor is provided, we'll just point at "location". + */ +static void +check_sql_expr(const char *stmt, RawParseMode parseMode, int location) +{ + sql_error_callback_arg cbarg; + ErrorContextCallback syntax_errcontext; + MemoryContext oldCxt; + + if (!plpgsql_check_syntax) + return; + + cbarg.location = location; + + syntax_errcontext.callback = plpgsql_sql_error_callback; + syntax_errcontext.arg = &cbarg; + syntax_errcontext.previous = error_context_stack; + error_context_stack = &syntax_errcontext; + + oldCxt = MemoryContextSwitchTo(plpgsql_compile_tmp_cxt); + (void) raw_parser(stmt, parseMode); + MemoryContextSwitchTo(oldCxt); + + /* Restore former ereport callback */ + error_context_stack = syntax_errcontext.previous; +} + +static void +plpgsql_sql_error_callback(void *arg) +{ + sql_error_callback_arg *cbarg = (sql_error_callback_arg *) arg; + int errpos; + + /* + * First, set up internalerrposition to point to the start of the + * statement text within the function text. Note this converts + * location (a byte offset) to a character number. + */ + parser_errposition(cbarg->location); + + /* + * If the core parser provided an error position, transpose it. + * Note we are dealing with 1-based character numbers at this point. + */ + errpos = geterrposition(); + if (errpos > 0) + { + int myerrpos = getinternalerrposition(); + + if (myerrpos > 0) /* safety check */ + internalerrposition(myerrpos + errpos - 1); + } + + /* In any case, flush errposition --- we want internalerrposition only */ + errposition(0); +} + +/* + * Parse a SQL datatype name and produce a PLpgSQL_type structure. + * + * The heavy lifting is done elsewhere. Here we are only concerned + * with setting up an errcontext link that will let us give an error + * cursor pointing into the plpgsql function source, if necessary. + * This is handled the same as in check_sql_expr(), and we likewise + * expect that the given string is a copy from the source text. + */ +static PLpgSQL_type * +parse_datatype(const char *string, int location) +{ + TypeName *typeName; + Oid type_id; + int32 typmod; + sql_error_callback_arg cbarg; + ErrorContextCallback syntax_errcontext; + + cbarg.location = location; + + syntax_errcontext.callback = plpgsql_sql_error_callback; + syntax_errcontext.arg = &cbarg; + syntax_errcontext.previous = error_context_stack; + error_context_stack = &syntax_errcontext; + + /* Let the main parser try to parse it under standard SQL rules */ + typeName = typeStringToTypeName(string, NULL); + typenameTypeIdAndMod(NULL, typeName, &type_id, &typmod); + + /* Restore former ereport callback */ + error_context_stack = syntax_errcontext.previous; + + /* Okay, build a PLpgSQL_type data structure for it */ + return plpgsql_build_datatype(type_id, typmod, + plpgsql_curr_compile->fn_input_collation, + typeName); +} + +/* + * Check block starting and ending labels match. + */ +static void +check_labels(const char *start_label, const char *end_label, int end_location) +{ + if (end_label) + { + if (!start_label) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("end label \"%s\" specified for unlabeled block", + end_label), + parser_errposition(end_location))); + + if (strcmp(start_label, end_label) != 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("end label \"%s\" differs from block's label \"%s\"", + end_label, start_label), + parser_errposition(end_location))); + } +} + +/* + * Read the arguments (if any) for a cursor, followed by the until token + * + * If cursor has no args, just swallow the until token and return NULL. + * If it does have args, we expect to see "( arg [, arg ...] )" followed + * by the until token, where arg may be a plain expression, or a named + * parameter assignment of the form argname := expr. Consume all that and + * return a SELECT query that evaluates the expression(s) (without the outer + * parens). + */ +static PLpgSQL_expr * +read_cursor_args(PLpgSQL_var *cursor, int until) +{ + PLpgSQL_expr *expr; + PLpgSQL_row *row; + int tok; + int argc; + char **argv; + StringInfoData ds; + bool any_named = false; + + tok = yylex(); + if (cursor->cursor_explicit_argrow < 0) + { + /* No arguments expected */ + if (tok == '(') + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cursor \"%s\" has no arguments", + cursor->refname), + parser_errposition(yylloc))); + + if (tok != until) + yyerror("syntax error"); + + return NULL; + } + + /* Else better provide arguments */ + if (tok != '(') + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cursor \"%s\" has arguments", + cursor->refname), + parser_errposition(yylloc))); + + /* + * Read the arguments, one by one. + */ + row = (PLpgSQL_row *) plpgsql_Datums[cursor->cursor_explicit_argrow]; + argv = (char **) palloc0(row->nfields * sizeof(char *)); + + for (argc = 0; argc < row->nfields; argc++) + { + PLpgSQL_expr *item; + int endtoken; + int argpos; + int tok1, + tok2; + int arglocation; + + /* Check if it's a named parameter: "param := value" */ + plpgsql_peek2(&tok1, &tok2, &arglocation, NULL); + if (tok1 == IDENT && tok2 == COLON_EQUALS) + { + char *argname; + IdentifierLookup save_IdentifierLookup; + + /* Read the argument name, ignoring any matching variable */ + save_IdentifierLookup = plpgsql_IdentifierLookup; + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE; + yylex(); + argname = yylval.str; + plpgsql_IdentifierLookup = save_IdentifierLookup; + + /* Match argument name to cursor arguments */ + for (argpos = 0; argpos < row->nfields; argpos++) + { + if (strcmp(row->fieldnames[argpos], argname) == 0) + break; + } + if (argpos == row->nfields) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cursor \"%s\" has no argument named \"%s\"", + cursor->refname, argname), + parser_errposition(yylloc))); + + /* + * Eat the ":=". We already peeked, so the error should never + * happen. + */ + tok2 = yylex(); + if (tok2 != COLON_EQUALS) + yyerror("syntax error"); + + any_named = true; + } + else + argpos = argc; + + if (argv[argpos] != NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("value for parameter \"%s\" of cursor \"%s\" specified more than once", + row->fieldnames[argpos], cursor->refname), + parser_errposition(arglocation))); + + /* + * Read the value expression. To provide the user with meaningful + * parse error positions, we check the syntax immediately, instead of + * checking the final expression that may have the arguments + * reordered. + */ + item = read_sql_construct(',', ')', 0, + ",\" or \")", + RAW_PARSE_PLPGSQL_EXPR, + true, true, + NULL, &endtoken); + + argv[argpos] = item->query; + + if (endtoken == ')' && !(argc == row->nfields - 1)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("not enough arguments for cursor \"%s\"", + cursor->refname), + parser_errposition(yylloc))); + + if (endtoken == ',' && (argc == row->nfields - 1)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("too many arguments for cursor \"%s\"", + cursor->refname), + parser_errposition(yylloc))); + } + + /* Make positional argument list */ + initStringInfo(&ds); + for (argc = 0; argc < row->nfields; argc++) + { + Assert(argv[argc] != NULL); + + /* + * Because named notation allows permutated argument lists, include + * the parameter name for meaningful runtime errors. + */ + appendStringInfoString(&ds, argv[argc]); + if (any_named) + appendStringInfo(&ds, " AS %s", + quote_identifier(row->fieldnames[argc])); + if (argc < row->nfields - 1) + appendStringInfoString(&ds, ", "); + } + + expr = palloc0(sizeof(PLpgSQL_expr)); + expr->query = pstrdup(ds.data); + expr->parseMode = RAW_PARSE_PLPGSQL_EXPR; + expr->plan = NULL; + expr->paramnos = NULL; + expr->target_param = -1; + expr->ns = plpgsql_ns_top(); + pfree(ds.data); + + /* Next we'd better find the until token */ + tok = yylex(); + if (tok != until) + yyerror("syntax error"); + + return expr; +} + +/* + * Parse RAISE ... USING options + */ +static List * +read_raise_options(void) +{ + List *result = NIL; + + for (;;) + { + PLpgSQL_raise_option *opt; + int tok; + + if ((tok = yylex()) == 0) + yyerror("unexpected end of function definition"); + + opt = (PLpgSQL_raise_option *) palloc(sizeof(PLpgSQL_raise_option)); + + if (tok_is_keyword(tok, &yylval, + K_ERRCODE, "errcode")) + opt->opt_type = PLPGSQL_RAISEOPTION_ERRCODE; + else if (tok_is_keyword(tok, &yylval, + K_MESSAGE, "message")) + opt->opt_type = PLPGSQL_RAISEOPTION_MESSAGE; + else if (tok_is_keyword(tok, &yylval, + K_DETAIL, "detail")) + opt->opt_type = PLPGSQL_RAISEOPTION_DETAIL; + else if (tok_is_keyword(tok, &yylval, + K_HINT, "hint")) + opt->opt_type = PLPGSQL_RAISEOPTION_HINT; + else if (tok_is_keyword(tok, &yylval, + K_COLUMN, "column")) + opt->opt_type = PLPGSQL_RAISEOPTION_COLUMN; + else if (tok_is_keyword(tok, &yylval, + K_CONSTRAINT, "constraint")) + opt->opt_type = PLPGSQL_RAISEOPTION_CONSTRAINT; + else if (tok_is_keyword(tok, &yylval, + K_DATATYPE, "datatype")) + opt->opt_type = PLPGSQL_RAISEOPTION_DATATYPE; + else if (tok_is_keyword(tok, &yylval, + K_TABLE, "table")) + opt->opt_type = PLPGSQL_RAISEOPTION_TABLE; + else if (tok_is_keyword(tok, &yylval, + K_SCHEMA, "schema")) + opt->opt_type = PLPGSQL_RAISEOPTION_SCHEMA; + else + yyerror("unrecognized RAISE statement option"); + + tok = yylex(); + if (tok != '=' && tok != COLON_EQUALS) + yyerror("syntax error, expected \"=\""); + + opt->expr = read_sql_expression2(',', ';', ", or ;", &tok); + + result = lappend(result, opt); + + if (tok == ';') + break; + } + + return result; +} + +/* + * Check that the number of parameter placeholders in the message matches the + * number of parameters passed to it, if a message was given. + */ +static void +check_raise_parameters(PLpgSQL_stmt_raise *stmt) +{ + char *cp; + int expected_nparams = 0; + + if (stmt->message == NULL) + return; + + for (cp = stmt->message; *cp; cp++) + { + if (cp[0] == '%') + { + /* ignore literal % characters */ + if (cp[1] == '%') + cp++; + else + expected_nparams++; + } + } + + if (expected_nparams < list_length(stmt->params)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("too many parameters specified for RAISE"))); + if (expected_nparams > list_length(stmt->params)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("too few parameters specified for RAISE"))); +} + +/* + * Fix up CASE statement + */ +static PLpgSQL_stmt * +make_case(int location, PLpgSQL_expr *t_expr, + List *case_when_list, List *else_stmts) +{ + PLpgSQL_stmt_case *new; + + new = palloc(sizeof(PLpgSQL_stmt_case)); + new->cmd_type = PLPGSQL_STMT_CASE; + new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->t_expr = t_expr; + new->t_varno = 0; + new->case_when_list = case_when_list; + new->have_else = (else_stmts != NIL); + /* Get rid of list-with-NULL hack */ + if (list_length(else_stmts) == 1 && linitial(else_stmts) == NULL) + new->else_stmts = NIL; + else + new->else_stmts = else_stmts; + + /* + * When test expression is present, we create a var for it and then + * convert all the WHEN expressions to "VAR IN (original_expression)". + * This is a bit klugy, but okay since we haven't yet done more than + * read the expressions as text. (Note that previous parsing won't + * have complained if the WHEN ... THEN expression contained multiple + * comma-separated values.) + */ + if (t_expr) + { + char varname[32]; + PLpgSQL_var *t_var; + ListCell *l; + + /* use a name unlikely to collide with any user names */ + snprintf(varname, sizeof(varname), "__Case__Variable_%d__", + plpgsql_nDatums); + + /* + * We don't yet know the result datatype of t_expr. Build the + * variable as if it were INT4; we'll fix this at runtime if needed. + */ + t_var = (PLpgSQL_var *) + plpgsql_build_variable(varname, new->lineno, + plpgsql_build_datatype(INT4OID, + -1, + InvalidOid, + NULL), + true); + new->t_varno = t_var->dno; + + foreach(l, case_when_list) + { + PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l); + PLpgSQL_expr *expr = cwt->expr; + StringInfoData ds; + + /* We expect to have expressions not statements */ + Assert(expr->parseMode == RAW_PARSE_PLPGSQL_EXPR); + + /* Do the string hacking */ + initStringInfo(&ds); + + appendStringInfo(&ds, "\"%s\" IN (%s)", + varname, expr->query); + + pfree(expr->query); + expr->query = pstrdup(ds.data); + /* Adjust expr's namespace to include the case variable */ + expr->ns = plpgsql_ns_top(); + + pfree(ds.data); + } + } + + return (PLpgSQL_stmt *) new; +} diff --git a/internal/reference/pl_reserved_kwlist.h b/internal/reference/pl_reserved_kwlist.h new file mode 100644 index 0000000..d338e9f --- /dev/null +++ b/internal/reference/pl_reserved_kwlist.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + * + * pl_reserved_kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/pl/plpgsql/src/pl_reserved_kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* There is deliberately not an #ifndef PL_RESERVED_KWLIST_H here. */ + +/* + * List of (keyword-name, keyword-token-value) pairs. + * + * Be careful not to put the same word into pl_unreserved_kwlist.h. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value */ +PG_KEYWORD("all", K_ALL) +PG_KEYWORD("begin", K_BEGIN) +PG_KEYWORD("by", K_BY) +PG_KEYWORD("case", K_CASE) +PG_KEYWORD("declare", K_DECLARE) +PG_KEYWORD("else", K_ELSE) +PG_KEYWORD("end", K_END) +PG_KEYWORD("execute", K_EXECUTE) +PG_KEYWORD("for", K_FOR) +PG_KEYWORD("foreach", K_FOREACH) +PG_KEYWORD("from", K_FROM) +PG_KEYWORD("if", K_IF) +PG_KEYWORD("in", K_IN) +PG_KEYWORD("into", K_INTO) +PG_KEYWORD("loop", K_LOOP) +PG_KEYWORD("not", K_NOT) +PG_KEYWORD("null", K_NULL) +PG_KEYWORD("or", K_OR) +PG_KEYWORD("strict", K_STRICT) +PG_KEYWORD("then", K_THEN) +PG_KEYWORD("to", K_TO) +PG_KEYWORD("using", K_USING) +PG_KEYWORD("when", K_WHEN) +PG_KEYWORD("while", K_WHILE) diff --git a/internal/reference/pl_scanner.c b/internal/reference/pl_scanner.c new file mode 100644 index 0000000..51919fe --- /dev/null +++ b/internal/reference/pl_scanner.c @@ -0,0 +1,642 @@ +/*------------------------------------------------------------------------- + * + * pl_scanner.c + * lexical scanning for PL/pgSQL + * + * + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/pl/plpgsql/src/pl_scanner.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "mb/pg_wchar.h" +#include "parser/scanner.h" + +#include "plpgsql.h" +#include "pl_gram.h" /* must be after parser/scanner.h */ + + +/* Klugy flag to tell scanner how to look up identifiers */ +IdentifierLookup plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; + +/* + * A word about keywords: + * + * We keep reserved and unreserved keywords in separate headers. Be careful + * not to put the same word in both headers. Also be sure that pl_gram.y's + * unreserved_keyword production agrees with the unreserved header. The + * reserved keywords are passed to the core scanner, so they will be + * recognized before (and instead of) any variable name. Unreserved words + * are checked for separately, usually after determining that the identifier + * isn't a known variable name. If plpgsql_IdentifierLookup is DECLARE then + * no variable names will be recognized, so the unreserved words always work. + * (Note in particular that this helps us avoid reserving keywords that are + * only needed in DECLARE sections.) + * + * In certain contexts it is desirable to prefer recognizing an unreserved + * keyword over recognizing a variable name. In particular, at the start + * of a statement we should prefer unreserved keywords unless the statement + * looks like an assignment (i.e., first token is followed by ':=' or '['). + * This rule allows most statement-introducing keywords to be kept unreserved. + * (We still have to reserve initial keywords that might follow a block + * label, unfortunately, since the method used to determine if we are at + * start of statement doesn't recognize such cases. We'd also have to + * reserve any keyword that could legitimately be followed by ':=' or '['.) + * Some additional cases are handled in pl_gram.y using tok_is_keyword(). + * + * We try to avoid reserving more keywords than we have to; but there's + * little point in not reserving a word if it's reserved in the core grammar. + * Currently, the following words are reserved here but not in the core: + * BEGIN BY DECLARE EXECUTE FOREACH IF LOOP STRICT WHILE + */ + +/* ScanKeywordList lookup data for PL/pgSQL keywords */ +#include "pl_reserved_kwlist_d.h" +#include "pl_unreserved_kwlist_d.h" + +/* Token codes for PL/pgSQL keywords */ +#define PG_KEYWORD(kwname, value) value, + +static const uint16 ReservedPLKeywordTokens[] = { +#include "pl_reserved_kwlist.h" +}; + +static const uint16 UnreservedPLKeywordTokens[] = { +#include "pl_unreserved_kwlist.h" +}; + +#undef PG_KEYWORD + +/* + * This macro must recognize all tokens that can immediately precede a + * PL/pgSQL executable statement (that is, proc_sect or proc_stmt in the + * grammar). Fortunately, there are not very many, so hard-coding in this + * fashion seems sufficient. + */ +#define AT_STMT_START(prev_token) \ + ((prev_token) == ';' || \ + (prev_token) == K_BEGIN || \ + (prev_token) == K_THEN || \ + (prev_token) == K_ELSE || \ + (prev_token) == K_LOOP) + + +/* Auxiliary data about a token (other than the token type) */ +typedef struct +{ + YYSTYPE lval; /* semantic information */ + YYLTYPE lloc; /* offset in scanbuf */ + int leng; /* length in bytes */ +} TokenAuxData; + +/* + * Scanner working state. At some point we might wish to fold all this + * into a YY_EXTRA struct. For the moment, there is no need for plpgsql's + * lexer to be re-entrant, and the notational burden of passing a yyscanner + * pointer around is great enough to not want to do it without need. + */ + +/* The stuff the core lexer needs */ +static core_yyscan_t yyscanner = NULL; +static core_yy_extra_type core_yy; + +/* The original input string */ +static const char *scanorig; + +/* Current token's length (corresponds to plpgsql_yylval and plpgsql_yylloc) */ +static int plpgsql_yyleng; + +/* Current token's code (corresponds to plpgsql_yylval and plpgsql_yylloc) */ +static int plpgsql_yytoken; + +/* Token pushback stack */ +#define MAX_PUSHBACKS 4 + +static int num_pushbacks; +static int pushback_token[MAX_PUSHBACKS]; +static TokenAuxData pushback_auxdata[MAX_PUSHBACKS]; + +/* State for plpgsql_location_to_lineno() */ +static const char *cur_line_start; +static const char *cur_line_end; +static int cur_line_num; + +/* Internal functions */ +static int internal_yylex(TokenAuxData *auxdata); +static void push_back_token(int token, TokenAuxData *auxdata); +static void location_lineno_init(void); + + +/* + * This is the yylex routine called from the PL/pgSQL grammar. + * It is a wrapper around the core lexer, with the ability to recognize + * PL/pgSQL variables and return them as special T_DATUM tokens. If a + * word or compound word does not match any variable name, or if matching + * is turned off by plpgsql_IdentifierLookup, it is returned as + * T_WORD or T_CWORD respectively, or as an unreserved keyword if it + * matches one of those. + */ +int +plpgsql_yylex(void) +{ + int tok1; + TokenAuxData aux1; + int kwnum; + + tok1 = internal_yylex(&aux1); + if (tok1 == IDENT || tok1 == PARAM) + { + int tok2; + TokenAuxData aux2; + + tok2 = internal_yylex(&aux2); + if (tok2 == '.') + { + int tok3; + TokenAuxData aux3; + + tok3 = internal_yylex(&aux3); + if (tok3 == IDENT) + { + int tok4; + TokenAuxData aux4; + + tok4 = internal_yylex(&aux4); + if (tok4 == '.') + { + int tok5; + TokenAuxData aux5; + + tok5 = internal_yylex(&aux5); + if (tok5 == IDENT) + { + if (plpgsql_parse_tripword(aux1.lval.str, + aux3.lval.str, + aux5.lval.str, + &aux1.lval.wdatum, + &aux1.lval.cword)) + tok1 = T_DATUM; + else + tok1 = T_CWORD; + /* Adjust token length to include A.B.C */ + aux1.leng = aux5.lloc - aux1.lloc + aux5.leng; + } + else + { + /* not A.B.C, so just process A.B */ + push_back_token(tok5, &aux5); + push_back_token(tok4, &aux4); + if (plpgsql_parse_dblword(aux1.lval.str, + aux3.lval.str, + &aux1.lval.wdatum, + &aux1.lval.cword)) + tok1 = T_DATUM; + else + tok1 = T_CWORD; + /* Adjust token length to include A.B */ + aux1.leng = aux3.lloc - aux1.lloc + aux3.leng; + } + } + else + { + /* not A.B.C, so just process A.B */ + push_back_token(tok4, &aux4); + if (plpgsql_parse_dblword(aux1.lval.str, + aux3.lval.str, + &aux1.lval.wdatum, + &aux1.lval.cword)) + tok1 = T_DATUM; + else + tok1 = T_CWORD; + /* Adjust token length to include A.B */ + aux1.leng = aux3.lloc - aux1.lloc + aux3.leng; + } + } + else + { + /* not A.B, so just process A */ + push_back_token(tok3, &aux3); + push_back_token(tok2, &aux2); + if (plpgsql_parse_word(aux1.lval.str, + core_yy.scanbuf + aux1.lloc, + true, + &aux1.lval.wdatum, + &aux1.lval.word)) + tok1 = T_DATUM; + else if (!aux1.lval.word.quoted && + (kwnum = ScanKeywordLookup(aux1.lval.word.ident, + &UnreservedPLKeywords)) >= 0) + { + aux1.lval.keyword = GetScanKeyword(kwnum, + &UnreservedPLKeywords); + tok1 = UnreservedPLKeywordTokens[kwnum]; + } + else + tok1 = T_WORD; + } + } + else + { + /* not A.B, so just process A */ + push_back_token(tok2, &aux2); + + /* + * See if it matches a variable name, except in the context where + * we are at start of statement and the next token isn't + * assignment or '['. In that case, it couldn't validly be a + * variable name, and skipping the lookup allows variable names to + * be used that would conflict with plpgsql or core keywords that + * introduce statements (e.g., "comment"). Without this special + * logic, every statement-introducing keyword would effectively be + * reserved in PL/pgSQL, which would be unpleasant. + * + * If it isn't a variable name, try to match against unreserved + * plpgsql keywords. If not one of those either, it's T_WORD. + * + * Note: we must call plpgsql_parse_word even if we don't want to + * do variable lookup, because it sets up aux1.lval.word for the + * non-variable cases. + */ + if (plpgsql_parse_word(aux1.lval.str, + core_yy.scanbuf + aux1.lloc, + (!AT_STMT_START(plpgsql_yytoken) || + (tok2 == '=' || tok2 == COLON_EQUALS || + tok2 == '[')), + &aux1.lval.wdatum, + &aux1.lval.word)) + tok1 = T_DATUM; + else if (!aux1.lval.word.quoted && + (kwnum = ScanKeywordLookup(aux1.lval.word.ident, + &UnreservedPLKeywords)) >= 0) + { + aux1.lval.keyword = GetScanKeyword(kwnum, + &UnreservedPLKeywords); + tok1 = UnreservedPLKeywordTokens[kwnum]; + } + else + tok1 = T_WORD; + } + } + else + { + /* + * Not a potential plpgsql variable name, just return the data. + * + * Note that we also come through here if the grammar pushed back a + * T_DATUM, T_CWORD, T_WORD, or unreserved-keyword token returned by a + * previous lookup cycle; thus, pushbacks do not incur extra lookup + * work, since we'll never do the above code twice for the same token. + * This property also makes it safe to rely on the old value of + * plpgsql_yytoken in the is-this-start-of-statement test above. + */ + } + + plpgsql_yylval = aux1.lval; + plpgsql_yylloc = aux1.lloc; + plpgsql_yyleng = aux1.leng; + plpgsql_yytoken = tok1; + return tok1; +} + +/* + * Return the length of the token last returned by plpgsql_yylex(). + * + * In the case of compound tokens, the length includes all the parts. + */ +int +plpgsql_token_length(void) +{ + return plpgsql_yyleng; +} + +/* + * Internal yylex function. This wraps the core lexer and adds one feature: + * a token pushback stack. We also make a couple of trivial single-token + * translations from what the core lexer does to what we want, in particular + * interfacing from the core_YYSTYPE to YYSTYPE union. + */ +static int +internal_yylex(TokenAuxData *auxdata) +{ + int token; + const char *yytext; + + if (num_pushbacks > 0) + { + num_pushbacks--; + token = pushback_token[num_pushbacks]; + *auxdata = pushback_auxdata[num_pushbacks]; + } + else + { + token = core_yylex(&auxdata->lval.core_yystype, + &auxdata->lloc, + yyscanner); + + /* remember the length of yytext before it gets changed */ + yytext = core_yy.scanbuf + auxdata->lloc; + auxdata->leng = strlen(yytext); + + /* Check for << >> and #, which the core considers operators */ + if (token == Op) + { + if (strcmp(auxdata->lval.str, "<<") == 0) + token = LESS_LESS; + else if (strcmp(auxdata->lval.str, ">>") == 0) + token = GREATER_GREATER; + else if (strcmp(auxdata->lval.str, "#") == 0) + token = '#'; + } + + /* The core returns PARAM as ival, but we treat it like IDENT */ + else if (token == PARAM) + { + auxdata->lval.str = pstrdup(yytext); + } + + else if (token == SQL_COMMENT || token == C_COMMENT) + { + token = internal_yylex(auxdata); + } + } + + return token; +} + +/* + * Push back a token to be re-read by next internal_yylex() call. + */ +static void +push_back_token(int token, TokenAuxData *auxdata) +{ + if (num_pushbacks >= MAX_PUSHBACKS) + elog(ERROR, "too many tokens pushed back"); + pushback_token[num_pushbacks] = token; + pushback_auxdata[num_pushbacks] = *auxdata; + num_pushbacks++; +} + +/* + * Push back a single token to be re-read by next plpgsql_yylex() call. + * + * NOTE: this does not cause yylval or yylloc to "back up". Also, it + * is not a good idea to push back a token code other than what you read. + */ +void +plpgsql_push_back_token(int token) +{ + TokenAuxData auxdata; + + auxdata.lval = plpgsql_yylval; + auxdata.lloc = plpgsql_yylloc; + auxdata.leng = plpgsql_yyleng; + push_back_token(token, &auxdata); +} + +/* + * Tell whether a token is an unreserved keyword. + * + * (If it is, its lowercased form was returned as the token value, so we + * do not need to offer that data here.) + */ +bool +plpgsql_token_is_unreserved_keyword(int token) +{ + int i; + + for (i = 0; i < lengthof(UnreservedPLKeywordTokens); i++) + { + if (UnreservedPLKeywordTokens[i] == token) + return true; + } + return false; +} + +/* + * Append the function text starting at startlocation and extending to + * (not including) endlocation onto the existing contents of "buf". + */ +void +plpgsql_append_source_text(StringInfo buf, + int startlocation, int endlocation) +{ + Assert(startlocation <= endlocation); + appendBinaryStringInfo(buf, scanorig + startlocation, + endlocation - startlocation); +} + +/* + * Peek one token ahead in the input stream. Only the token code is + * made available, not any of the auxiliary info such as location. + * + * NB: no variable or unreserved keyword lookup is performed here, they will + * be returned as IDENT. Reserved keywords are resolved as usual. + */ +int +plpgsql_peek(void) +{ + int tok1; + TokenAuxData aux1; + + tok1 = internal_yylex(&aux1); + push_back_token(tok1, &aux1); + return tok1; +} + +/* + * Peek two tokens ahead in the input stream. The first token and its + * location in the query are returned in *tok1_p and *tok1_loc, second token + * and its location in *tok2_p and *tok2_loc. + * + * NB: no variable or unreserved keyword lookup is performed here, they will + * be returned as IDENT. Reserved keywords are resolved as usual. + */ +void +plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc, int *tok2_loc) +{ + int tok1, + tok2; + TokenAuxData aux1, + aux2; + + tok1 = internal_yylex(&aux1); + tok2 = internal_yylex(&aux2); + + *tok1_p = tok1; + if (tok1_loc) + *tok1_loc = aux1.lloc; + *tok2_p = tok2; + if (tok2_loc) + *tok2_loc = aux2.lloc; + + push_back_token(tok2, &aux2); + push_back_token(tok1, &aux1); +} + +/* + * plpgsql_scanner_errposition + * Report an error cursor position, if possible. + * + * This is expected to be used within an ereport() call. The return value + * is a dummy (always 0, in fact). + * + * Note that this can only be used for messages emitted during initial + * parsing of a plpgsql function, since it requires the scanorig string + * to still be available. + */ +int +plpgsql_scanner_errposition(int location) +{ + int pos; + + if (location < 0 || scanorig == NULL) + return 0; /* no-op if location is unknown */ + + /* Convert byte offset to character number */ + pos = pg_mbstrlen_with_len(scanorig, location) + 1; + /* And pass it to the ereport mechanism */ + (void) internalerrposition(pos); + /* Also pass the function body string */ + return internalerrquery(scanorig); +} + +/* + * plpgsql_yyerror + * Report a lexer or grammar error. + * + * The message's cursor position refers to the current token (the one + * last returned by plpgsql_yylex()). + * This is OK for syntax error messages from the Bison parser, because Bison + * parsers report error as soon as the first unparsable token is reached. + * Beware of using yyerror for other purposes, as the cursor position might + * be misleading! + */ +void +plpgsql_yyerror(const char *message) +{ + char *yytext = core_yy.scanbuf + plpgsql_yylloc; + + if (*yytext == '\0') + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + /* translator: %s is typically the translation of "syntax error" */ + errmsg("%s at end of input", _(message)), + plpgsql_scanner_errposition(plpgsql_yylloc))); + } + else + { + /* + * If we have done any lookahead then flex will have restored the + * character after the end-of-token. Zap it again so that we report + * only the single token here. This modifies scanbuf but we no longer + * care about that. + */ + yytext[plpgsql_yyleng] = '\0'; + + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + /* translator: first %s is typically the translation of "syntax error" */ + errmsg("%s at or near \"%s\"", _(message), yytext), + plpgsql_scanner_errposition(plpgsql_yylloc))); + } +} + +/* + * Given a location (a byte offset in the function source text), + * return a line number. + * + * We expect that this is typically called for a sequence of increasing + * location values, so optimize accordingly by tracking the endpoints + * of the "current" line. + */ +int +plpgsql_location_to_lineno(int location) +{ + const char *loc; + + if (location < 0 || scanorig == NULL) + return 0; /* garbage in, garbage out */ + loc = scanorig + location; + + /* be correct, but not fast, if input location goes backwards */ + if (loc < cur_line_start) + location_lineno_init(); + + while (cur_line_end != NULL && loc > cur_line_end) + { + cur_line_start = cur_line_end + 1; + cur_line_num++; + cur_line_end = strchr(cur_line_start, '\n'); + } + + return cur_line_num; +} + +/* initialize or reset the state for plpgsql_location_to_lineno */ +static void +location_lineno_init(void) +{ + cur_line_start = scanorig; + cur_line_num = 1; + + cur_line_end = strchr(cur_line_start, '\n'); +} + +/* return the most recently computed lineno */ +int +plpgsql_latest_lineno(void) +{ + return cur_line_num; +} + + +/* + * Called before any actual parsing is done + * + * Note: the passed "str" must remain valid until plpgsql_scanner_finish(). + * Although it is not fed directly to flex, we need the original string + * to cite in error messages. + */ +void +plpgsql_scanner_init(const char *str) +{ + /* Start up the core scanner */ + yyscanner = scanner_init(str, &core_yy, + &ReservedPLKeywords, ReservedPLKeywordTokens); + + /* + * scanorig points to the original string, which unlike the scanner's + * scanbuf won't be modified on-the-fly by flex. Notice that although + * yytext points into scanbuf, we rely on being able to apply locations + * (offsets from string start) to scanorig as well. + */ + scanorig = str; + + /* Other setup */ + plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; + plpgsql_yytoken = 0; + + num_pushbacks = 0; + + location_lineno_init(); +} + +/* + * Called after parsing is done to clean up after plpgsql_scanner_init() + */ +void +plpgsql_scanner_finish(void) +{ + /* release storage */ + scanner_finish(yyscanner); + /* avoid leaving any dangling pointers */ + yyscanner = NULL; + scanorig = NULL; +} diff --git a/internal/reference/pl_unreserved_kwlist.h b/internal/reference/pl_unreserved_kwlist.h new file mode 100644 index 0000000..670b4cf --- /dev/null +++ b/internal/reference/pl_unreserved_kwlist.h @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------------- + * + * pl_unreserved_kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/pl/plpgsql/src/pl_unreserved_kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* There is deliberately not an #ifndef PL_UNRESERVED_KWLIST_H here. */ + +/* + * List of (keyword-name, keyword-token-value) pairs. + * + * Be careful not to put the same word into pl_reserved_kwlist.h. Also be + * sure that pl_gram.y's unreserved_keyword production agrees with this list. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value */ +PG_KEYWORD("absolute", K_ABSOLUTE) +PG_KEYWORD("alias", K_ALIAS) +PG_KEYWORD("and", K_AND) +PG_KEYWORD("array", K_ARRAY) +PG_KEYWORD("assert", K_ASSERT) +PG_KEYWORD("backward", K_BACKWARD) +PG_KEYWORD("call", K_CALL) +PG_KEYWORD("chain", K_CHAIN) +PG_KEYWORD("close", K_CLOSE) +PG_KEYWORD("collate", K_COLLATE) +PG_KEYWORD("column", K_COLUMN) +PG_KEYWORD("column_name", K_COLUMN_NAME) +PG_KEYWORD("commit", K_COMMIT) +PG_KEYWORD("constant", K_CONSTANT) +PG_KEYWORD("constraint", K_CONSTRAINT) +PG_KEYWORD("constraint_name", K_CONSTRAINT_NAME) +PG_KEYWORD("continue", K_CONTINUE) +PG_KEYWORD("current", K_CURRENT) +PG_KEYWORD("cursor", K_CURSOR) +PG_KEYWORD("datatype", K_DATATYPE) +PG_KEYWORD("debug", K_DEBUG) +PG_KEYWORD("default", K_DEFAULT) +PG_KEYWORD("detail", K_DETAIL) +PG_KEYWORD("diagnostics", K_DIAGNOSTICS) +PG_KEYWORD("do", K_DO) +PG_KEYWORD("dump", K_DUMP) +PG_KEYWORD("elseif", K_ELSIF) +PG_KEYWORD("elsif", K_ELSIF) +PG_KEYWORD("errcode", K_ERRCODE) +PG_KEYWORD("error", K_ERROR) +PG_KEYWORD("exception", K_EXCEPTION) +PG_KEYWORD("exit", K_EXIT) +PG_KEYWORD("fetch", K_FETCH) +PG_KEYWORD("first", K_FIRST) +PG_KEYWORD("forward", K_FORWARD) +PG_KEYWORD("get", K_GET) +PG_KEYWORD("hint", K_HINT) +PG_KEYWORD("import", K_IMPORT) +PG_KEYWORD("info", K_INFO) +PG_KEYWORD("insert", K_INSERT) +PG_KEYWORD("is", K_IS) +PG_KEYWORD("last", K_LAST) +PG_KEYWORD("log", K_LOG) +PG_KEYWORD("merge", K_MERGE) +PG_KEYWORD("message", K_MESSAGE) +PG_KEYWORD("message_text", K_MESSAGE_TEXT) +PG_KEYWORD("move", K_MOVE) +PG_KEYWORD("next", K_NEXT) +PG_KEYWORD("no", K_NO) +PG_KEYWORD("notice", K_NOTICE) +PG_KEYWORD("open", K_OPEN) +PG_KEYWORD("option", K_OPTION) +PG_KEYWORD("perform", K_PERFORM) +PG_KEYWORD("pg_context", K_PG_CONTEXT) +PG_KEYWORD("pg_datatype_name", K_PG_DATATYPE_NAME) +PG_KEYWORD("pg_exception_context", K_PG_EXCEPTION_CONTEXT) +PG_KEYWORD("pg_exception_detail", K_PG_EXCEPTION_DETAIL) +PG_KEYWORD("pg_exception_hint", K_PG_EXCEPTION_HINT) +PG_KEYWORD("pg_routine_oid", K_PG_ROUTINE_OID) +PG_KEYWORD("print_strict_params", K_PRINT_STRICT_PARAMS) +PG_KEYWORD("prior", K_PRIOR) +PG_KEYWORD("query", K_QUERY) +PG_KEYWORD("raise", K_RAISE) +PG_KEYWORD("relative", K_RELATIVE) +PG_KEYWORD("return", K_RETURN) +PG_KEYWORD("returned_sqlstate", K_RETURNED_SQLSTATE) +PG_KEYWORD("reverse", K_REVERSE) +PG_KEYWORD("rollback", K_ROLLBACK) +PG_KEYWORD("row_count", K_ROW_COUNT) +PG_KEYWORD("rowtype", K_ROWTYPE) +PG_KEYWORD("schema", K_SCHEMA) +PG_KEYWORD("schema_name", K_SCHEMA_NAME) +PG_KEYWORD("scroll", K_SCROLL) +PG_KEYWORD("slice", K_SLICE) +PG_KEYWORD("sqlstate", K_SQLSTATE) +PG_KEYWORD("stacked", K_STACKED) +PG_KEYWORD("table", K_TABLE) +PG_KEYWORD("table_name", K_TABLE_NAME) +PG_KEYWORD("type", K_TYPE) +PG_KEYWORD("use_column", K_USE_COLUMN) +PG_KEYWORD("use_variable", K_USE_VARIABLE) +PG_KEYWORD("variable_conflict", K_VARIABLE_CONFLICT) +PG_KEYWORD("warning", K_WARNING) diff --git a/internal/reference/plerrcodes.h b/internal/reference/plerrcodes.h new file mode 100644 index 0000000..c9900ac --- /dev/null +++ b/internal/reference/plerrcodes.h @@ -0,0 +1,998 @@ +/* autogenerated from src/backend/utils/errcodes.txt, do not edit */ +/* there is deliberately not an #ifndef PLERRCODES_H here */ + +{ + "sql_statement_not_yet_complete", ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE +}, + +{ + "connection_exception", ERRCODE_CONNECTION_EXCEPTION +}, + +{ + "connection_does_not_exist", ERRCODE_CONNECTION_DOES_NOT_EXIST +}, + +{ + "connection_failure", ERRCODE_CONNECTION_FAILURE +}, + +{ + "sqlclient_unable_to_establish_sqlconnection", ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION +}, + +{ + "sqlserver_rejected_establishment_of_sqlconnection", ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION +}, + +{ + "transaction_resolution_unknown", ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN +}, + +{ + "protocol_violation", ERRCODE_PROTOCOL_VIOLATION +}, + +{ + "triggered_action_exception", ERRCODE_TRIGGERED_ACTION_EXCEPTION +}, + +{ + "feature_not_supported", ERRCODE_FEATURE_NOT_SUPPORTED +}, + +{ + "invalid_transaction_initiation", ERRCODE_INVALID_TRANSACTION_INITIATION +}, + +{ + "locator_exception", ERRCODE_LOCATOR_EXCEPTION +}, + +{ + "invalid_locator_specification", ERRCODE_L_E_INVALID_SPECIFICATION +}, + +{ + "invalid_grantor", ERRCODE_INVALID_GRANTOR +}, + +{ + "invalid_grant_operation", ERRCODE_INVALID_GRANT_OPERATION +}, + +{ + "invalid_role_specification", ERRCODE_INVALID_ROLE_SPECIFICATION +}, + +{ + "diagnostics_exception", ERRCODE_DIAGNOSTICS_EXCEPTION +}, + +{ + "stacked_diagnostics_accessed_without_active_handler", ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER +}, + +{ + "case_not_found", ERRCODE_CASE_NOT_FOUND +}, + +{ + "cardinality_violation", ERRCODE_CARDINALITY_VIOLATION +}, + +{ + "data_exception", ERRCODE_DATA_EXCEPTION +}, + +{ + "array_subscript_error", ERRCODE_ARRAY_SUBSCRIPT_ERROR +}, + +{ + "character_not_in_repertoire", ERRCODE_CHARACTER_NOT_IN_REPERTOIRE +}, + +{ + "datetime_field_overflow", ERRCODE_DATETIME_FIELD_OVERFLOW +}, + +{ + "division_by_zero", ERRCODE_DIVISION_BY_ZERO +}, + +{ + "error_in_assignment", ERRCODE_ERROR_IN_ASSIGNMENT +}, + +{ + "escape_character_conflict", ERRCODE_ESCAPE_CHARACTER_CONFLICT +}, + +{ + "indicator_overflow", ERRCODE_INDICATOR_OVERFLOW +}, + +{ + "interval_field_overflow", ERRCODE_INTERVAL_FIELD_OVERFLOW +}, + +{ + "invalid_argument_for_logarithm", ERRCODE_INVALID_ARGUMENT_FOR_LOG +}, + +{ + "invalid_argument_for_ntile_function", ERRCODE_INVALID_ARGUMENT_FOR_NTILE +}, + +{ + "invalid_argument_for_nth_value_function", ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE +}, + +{ + "invalid_argument_for_power_function", ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION +}, + +{ + "invalid_argument_for_width_bucket_function", ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION +}, + +{ + "invalid_character_value_for_cast", ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST +}, + +{ + "invalid_datetime_format", ERRCODE_INVALID_DATETIME_FORMAT +}, + +{ + "invalid_escape_character", ERRCODE_INVALID_ESCAPE_CHARACTER +}, + +{ + "invalid_escape_octet", ERRCODE_INVALID_ESCAPE_OCTET +}, + +{ + "invalid_escape_sequence", ERRCODE_INVALID_ESCAPE_SEQUENCE +}, + +{ + "nonstandard_use_of_escape_character", ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER +}, + +{ + "invalid_indicator_parameter_value", ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE +}, + +{ + "invalid_parameter_value", ERRCODE_INVALID_PARAMETER_VALUE +}, + +{ + "invalid_preceding_or_following_size", ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE +}, + +{ + "invalid_regular_expression", ERRCODE_INVALID_REGULAR_EXPRESSION +}, + +{ + "invalid_row_count_in_limit_clause", ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE +}, + +{ + "invalid_row_count_in_result_offset_clause", ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE +}, + +{ + "invalid_tablesample_argument", ERRCODE_INVALID_TABLESAMPLE_ARGUMENT +}, + +{ + "invalid_tablesample_repeat", ERRCODE_INVALID_TABLESAMPLE_REPEAT +}, + +{ + "invalid_time_zone_displacement_value", ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE +}, + +{ + "invalid_use_of_escape_character", ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER +}, + +{ + "most_specific_type_mismatch", ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH +}, + +{ + "null_value_not_allowed", ERRCODE_NULL_VALUE_NOT_ALLOWED +}, + +{ + "null_value_no_indicator_parameter", ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER +}, + +{ + "numeric_value_out_of_range", ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE +}, + +{ + "sequence_generator_limit_exceeded", ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED +}, + +{ + "string_data_length_mismatch", ERRCODE_STRING_DATA_LENGTH_MISMATCH +}, + +{ + "string_data_right_truncation", ERRCODE_STRING_DATA_RIGHT_TRUNCATION +}, + +{ + "substring_error", ERRCODE_SUBSTRING_ERROR +}, + +{ + "trim_error", ERRCODE_TRIM_ERROR +}, + +{ + "unterminated_c_string", ERRCODE_UNTERMINATED_C_STRING +}, + +{ + "zero_length_character_string", ERRCODE_ZERO_LENGTH_CHARACTER_STRING +}, + +{ + "floating_point_exception", ERRCODE_FLOATING_POINT_EXCEPTION +}, + +{ + "invalid_text_representation", ERRCODE_INVALID_TEXT_REPRESENTATION +}, + +{ + "invalid_binary_representation", ERRCODE_INVALID_BINARY_REPRESENTATION +}, + +{ + "bad_copy_file_format", ERRCODE_BAD_COPY_FILE_FORMAT +}, + +{ + "untranslatable_character", ERRCODE_UNTRANSLATABLE_CHARACTER +}, + +{ + "not_an_xml_document", ERRCODE_NOT_AN_XML_DOCUMENT +}, + +{ + "invalid_xml_document", ERRCODE_INVALID_XML_DOCUMENT +}, + +{ + "invalid_xml_content", ERRCODE_INVALID_XML_CONTENT +}, + +{ + "invalid_xml_comment", ERRCODE_INVALID_XML_COMMENT +}, + +{ + "invalid_xml_processing_instruction", ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION +}, + +{ + "duplicate_json_object_key_value", ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE +}, + +{ + "invalid_argument_for_sql_json_datetime_function", ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION +}, + +{ + "invalid_json_text", ERRCODE_INVALID_JSON_TEXT +}, + +{ + "invalid_sql_json_subscript", ERRCODE_INVALID_SQL_JSON_SUBSCRIPT +}, + +{ + "more_than_one_sql_json_item", ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM +}, + +{ + "no_sql_json_item", ERRCODE_NO_SQL_JSON_ITEM +}, + +{ + "non_numeric_sql_json_item", ERRCODE_NON_NUMERIC_SQL_JSON_ITEM +}, + +{ + "non_unique_keys_in_a_json_object", ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT +}, + +{ + "singleton_sql_json_item_required", ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED +}, + +{ + "sql_json_array_not_found", ERRCODE_SQL_JSON_ARRAY_NOT_FOUND +}, + +{ + "sql_json_member_not_found", ERRCODE_SQL_JSON_MEMBER_NOT_FOUND +}, + +{ + "sql_json_number_not_found", ERRCODE_SQL_JSON_NUMBER_NOT_FOUND +}, + +{ + "sql_json_object_not_found", ERRCODE_SQL_JSON_OBJECT_NOT_FOUND +}, + +{ + "too_many_json_array_elements", ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS +}, + +{ + "too_many_json_object_members", ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS +}, + +{ + "sql_json_scalar_required", ERRCODE_SQL_JSON_SCALAR_REQUIRED +}, + +{ + "sql_json_item_cannot_be_cast_to_target_type", ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE +}, + +{ + "integrity_constraint_violation", ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION +}, + +{ + "restrict_violation", ERRCODE_RESTRICT_VIOLATION +}, + +{ + "not_null_violation", ERRCODE_NOT_NULL_VIOLATION +}, + +{ + "foreign_key_violation", ERRCODE_FOREIGN_KEY_VIOLATION +}, + +{ + "unique_violation", ERRCODE_UNIQUE_VIOLATION +}, + +{ + "check_violation", ERRCODE_CHECK_VIOLATION +}, + +{ + "exclusion_violation", ERRCODE_EXCLUSION_VIOLATION +}, + +{ + "invalid_cursor_state", ERRCODE_INVALID_CURSOR_STATE +}, + +{ + "invalid_transaction_state", ERRCODE_INVALID_TRANSACTION_STATE +}, + +{ + "active_sql_transaction", ERRCODE_ACTIVE_SQL_TRANSACTION +}, + +{ + "branch_transaction_already_active", ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE +}, + +{ + "held_cursor_requires_same_isolation_level", ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL +}, + +{ + "inappropriate_access_mode_for_branch_transaction", ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION +}, + +{ + "inappropriate_isolation_level_for_branch_transaction", ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION +}, + +{ + "no_active_sql_transaction_for_branch_transaction", ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION +}, + +{ + "read_only_sql_transaction", ERRCODE_READ_ONLY_SQL_TRANSACTION +}, + +{ + "schema_and_data_statement_mixing_not_supported", ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED +}, + +{ + "no_active_sql_transaction", ERRCODE_NO_ACTIVE_SQL_TRANSACTION +}, + +{ + "in_failed_sql_transaction", ERRCODE_IN_FAILED_SQL_TRANSACTION +}, + +{ + "idle_in_transaction_session_timeout", ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT +}, + +{ + "transaction_timeout", ERRCODE_TRANSACTION_TIMEOUT +}, + +{ + "invalid_sql_statement_name", ERRCODE_INVALID_SQL_STATEMENT_NAME +}, + +{ + "triggered_data_change_violation", ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION +}, + +{ + "invalid_authorization_specification", ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION +}, + +{ + "invalid_password", ERRCODE_INVALID_PASSWORD +}, + +{ + "dependent_privilege_descriptors_still_exist", ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST +}, + +{ + "dependent_objects_still_exist", ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST +}, + +{ + "invalid_transaction_termination", ERRCODE_INVALID_TRANSACTION_TERMINATION +}, + +{ + "sql_routine_exception", ERRCODE_SQL_ROUTINE_EXCEPTION +}, + +{ + "function_executed_no_return_statement", ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT +}, + +{ + "modifying_sql_data_not_permitted", ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED +}, + +{ + "prohibited_sql_statement_attempted", ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED +}, + +{ + "reading_sql_data_not_permitted", ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED +}, + +{ + "invalid_cursor_name", ERRCODE_INVALID_CURSOR_NAME +}, + +{ + "external_routine_exception", ERRCODE_EXTERNAL_ROUTINE_EXCEPTION +}, + +{ + "containing_sql_not_permitted", ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED +}, + +{ + "modifying_sql_data_not_permitted", ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED +}, + +{ + "prohibited_sql_statement_attempted", ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED +}, + +{ + "reading_sql_data_not_permitted", ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED +}, + +{ + "external_routine_invocation_exception", ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION +}, + +{ + "invalid_sqlstate_returned", ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED +}, + +{ + "null_value_not_allowed", ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED +}, + +{ + "trigger_protocol_violated", ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED +}, + +{ + "srf_protocol_violated", ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED +}, + +{ + "event_trigger_protocol_violated", ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED +}, + +{ + "savepoint_exception", ERRCODE_SAVEPOINT_EXCEPTION +}, + +{ + "invalid_savepoint_specification", ERRCODE_S_E_INVALID_SPECIFICATION +}, + +{ + "invalid_catalog_name", ERRCODE_INVALID_CATALOG_NAME +}, + +{ + "invalid_schema_name", ERRCODE_INVALID_SCHEMA_NAME +}, + +{ + "transaction_rollback", ERRCODE_TRANSACTION_ROLLBACK +}, + +{ + "transaction_integrity_constraint_violation", ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION +}, + +{ + "serialization_failure", ERRCODE_T_R_SERIALIZATION_FAILURE +}, + +{ + "statement_completion_unknown", ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN +}, + +{ + "deadlock_detected", ERRCODE_T_R_DEADLOCK_DETECTED +}, + +{ + "syntax_error_or_access_rule_violation", ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION +}, + +{ + "syntax_error", ERRCODE_SYNTAX_ERROR +}, + +{ + "insufficient_privilege", ERRCODE_INSUFFICIENT_PRIVILEGE +}, + +{ + "cannot_coerce", ERRCODE_CANNOT_COERCE +}, + +{ + "grouping_error", ERRCODE_GROUPING_ERROR +}, + +{ + "windowing_error", ERRCODE_WINDOWING_ERROR +}, + +{ + "invalid_recursion", ERRCODE_INVALID_RECURSION +}, + +{ + "invalid_foreign_key", ERRCODE_INVALID_FOREIGN_KEY +}, + +{ + "invalid_name", ERRCODE_INVALID_NAME +}, + +{ + "name_too_long", ERRCODE_NAME_TOO_LONG +}, + +{ + "reserved_name", ERRCODE_RESERVED_NAME +}, + +{ + "datatype_mismatch", ERRCODE_DATATYPE_MISMATCH +}, + +{ + "indeterminate_datatype", ERRCODE_INDETERMINATE_DATATYPE +}, + +{ + "collation_mismatch", ERRCODE_COLLATION_MISMATCH +}, + +{ + "indeterminate_collation", ERRCODE_INDETERMINATE_COLLATION +}, + +{ + "wrong_object_type", ERRCODE_WRONG_OBJECT_TYPE +}, + +{ + "generated_always", ERRCODE_GENERATED_ALWAYS +}, + +{ + "undefined_column", ERRCODE_UNDEFINED_COLUMN +}, + +{ + "undefined_function", ERRCODE_UNDEFINED_FUNCTION +}, + +{ + "undefined_table", ERRCODE_UNDEFINED_TABLE +}, + +{ + "undefined_parameter", ERRCODE_UNDEFINED_PARAMETER +}, + +{ + "undefined_object", ERRCODE_UNDEFINED_OBJECT +}, + +{ + "duplicate_column", ERRCODE_DUPLICATE_COLUMN +}, + +{ + "duplicate_cursor", ERRCODE_DUPLICATE_CURSOR +}, + +{ + "duplicate_database", ERRCODE_DUPLICATE_DATABASE +}, + +{ + "duplicate_function", ERRCODE_DUPLICATE_FUNCTION +}, + +{ + "duplicate_prepared_statement", ERRCODE_DUPLICATE_PSTATEMENT +}, + +{ + "duplicate_schema", ERRCODE_DUPLICATE_SCHEMA +}, + +{ + "duplicate_table", ERRCODE_DUPLICATE_TABLE +}, + +{ + "duplicate_alias", ERRCODE_DUPLICATE_ALIAS +}, + +{ + "duplicate_object", ERRCODE_DUPLICATE_OBJECT +}, + +{ + "ambiguous_column", ERRCODE_AMBIGUOUS_COLUMN +}, + +{ + "ambiguous_function", ERRCODE_AMBIGUOUS_FUNCTION +}, + +{ + "ambiguous_parameter", ERRCODE_AMBIGUOUS_PARAMETER +}, + +{ + "ambiguous_alias", ERRCODE_AMBIGUOUS_ALIAS +}, + +{ + "invalid_column_reference", ERRCODE_INVALID_COLUMN_REFERENCE +}, + +{ + "invalid_column_definition", ERRCODE_INVALID_COLUMN_DEFINITION +}, + +{ + "invalid_cursor_definition", ERRCODE_INVALID_CURSOR_DEFINITION +}, + +{ + "invalid_database_definition", ERRCODE_INVALID_DATABASE_DEFINITION +}, + +{ + "invalid_function_definition", ERRCODE_INVALID_FUNCTION_DEFINITION +}, + +{ + "invalid_prepared_statement_definition", ERRCODE_INVALID_PSTATEMENT_DEFINITION +}, + +{ + "invalid_schema_definition", ERRCODE_INVALID_SCHEMA_DEFINITION +}, + +{ + "invalid_table_definition", ERRCODE_INVALID_TABLE_DEFINITION +}, + +{ + "invalid_object_definition", ERRCODE_INVALID_OBJECT_DEFINITION +}, + +{ + "with_check_option_violation", ERRCODE_WITH_CHECK_OPTION_VIOLATION +}, + +{ + "insufficient_resources", ERRCODE_INSUFFICIENT_RESOURCES +}, + +{ + "disk_full", ERRCODE_DISK_FULL +}, + +{ + "out_of_memory", ERRCODE_OUT_OF_MEMORY +}, + +{ + "too_many_connections", ERRCODE_TOO_MANY_CONNECTIONS +}, + +{ + "configuration_limit_exceeded", ERRCODE_CONFIGURATION_LIMIT_EXCEEDED +}, + +{ + "program_limit_exceeded", ERRCODE_PROGRAM_LIMIT_EXCEEDED +}, + +{ + "statement_too_complex", ERRCODE_STATEMENT_TOO_COMPLEX +}, + +{ + "too_many_columns", ERRCODE_TOO_MANY_COLUMNS +}, + +{ + "too_many_arguments", ERRCODE_TOO_MANY_ARGUMENTS +}, + +{ + "object_not_in_prerequisite_state", ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE +}, + +{ + "object_in_use", ERRCODE_OBJECT_IN_USE +}, + +{ + "cant_change_runtime_param", ERRCODE_CANT_CHANGE_RUNTIME_PARAM +}, + +{ + "lock_not_available", ERRCODE_LOCK_NOT_AVAILABLE +}, + +{ + "unsafe_new_enum_value_usage", ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE +}, + +{ + "operator_intervention", ERRCODE_OPERATOR_INTERVENTION +}, + +{ + "query_canceled", ERRCODE_QUERY_CANCELED +}, + +{ + "admin_shutdown", ERRCODE_ADMIN_SHUTDOWN +}, + +{ + "crash_shutdown", ERRCODE_CRASH_SHUTDOWN +}, + +{ + "cannot_connect_now", ERRCODE_CANNOT_CONNECT_NOW +}, + +{ + "database_dropped", ERRCODE_DATABASE_DROPPED +}, + +{ + "idle_session_timeout", ERRCODE_IDLE_SESSION_TIMEOUT +}, + +{ + "system_error", ERRCODE_SYSTEM_ERROR +}, + +{ + "io_error", ERRCODE_IO_ERROR +}, + +{ + "undefined_file", ERRCODE_UNDEFINED_FILE +}, + +{ + "duplicate_file", ERRCODE_DUPLICATE_FILE +}, + +{ + "config_file_error", ERRCODE_CONFIG_FILE_ERROR +}, + +{ + "lock_file_exists", ERRCODE_LOCK_FILE_EXISTS +}, + +{ + "fdw_error", ERRCODE_FDW_ERROR +}, + +{ + "fdw_column_name_not_found", ERRCODE_FDW_COLUMN_NAME_NOT_FOUND +}, + +{ + "fdw_dynamic_parameter_value_needed", ERRCODE_FDW_DYNAMIC_PARAMETER_VALUE_NEEDED +}, + +{ + "fdw_function_sequence_error", ERRCODE_FDW_FUNCTION_SEQUENCE_ERROR +}, + +{ + "fdw_inconsistent_descriptor_information", ERRCODE_FDW_INCONSISTENT_DESCRIPTOR_INFORMATION +}, + +{ + "fdw_invalid_attribute_value", ERRCODE_FDW_INVALID_ATTRIBUTE_VALUE +}, + +{ + "fdw_invalid_column_name", ERRCODE_FDW_INVALID_COLUMN_NAME +}, + +{ + "fdw_invalid_column_number", ERRCODE_FDW_INVALID_COLUMN_NUMBER +}, + +{ + "fdw_invalid_data_type", ERRCODE_FDW_INVALID_DATA_TYPE +}, + +{ + "fdw_invalid_data_type_descriptors", ERRCODE_FDW_INVALID_DATA_TYPE_DESCRIPTORS +}, + +{ + "fdw_invalid_descriptor_field_identifier", ERRCODE_FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER +}, + +{ + "fdw_invalid_handle", ERRCODE_FDW_INVALID_HANDLE +}, + +{ + "fdw_invalid_option_index", ERRCODE_FDW_INVALID_OPTION_INDEX +}, + +{ + "fdw_invalid_option_name", ERRCODE_FDW_INVALID_OPTION_NAME +}, + +{ + "fdw_invalid_string_length_or_buffer_length", ERRCODE_FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH +}, + +{ + "fdw_invalid_string_format", ERRCODE_FDW_INVALID_STRING_FORMAT +}, + +{ + "fdw_invalid_use_of_null_pointer", ERRCODE_FDW_INVALID_USE_OF_NULL_POINTER +}, + +{ + "fdw_too_many_handles", ERRCODE_FDW_TOO_MANY_HANDLES +}, + +{ + "fdw_out_of_memory", ERRCODE_FDW_OUT_OF_MEMORY +}, + +{ + "fdw_no_schemas", ERRCODE_FDW_NO_SCHEMAS +}, + +{ + "fdw_option_name_not_found", ERRCODE_FDW_OPTION_NAME_NOT_FOUND +}, + +{ + "fdw_reply_handle", ERRCODE_FDW_REPLY_HANDLE +}, + +{ + "fdw_schema_not_found", ERRCODE_FDW_SCHEMA_NOT_FOUND +}, + +{ + "fdw_table_not_found", ERRCODE_FDW_TABLE_NOT_FOUND +}, + +{ + "fdw_unable_to_create_execution", ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION +}, + +{ + "fdw_unable_to_create_reply", ERRCODE_FDW_UNABLE_TO_CREATE_REPLY +}, + +{ + "fdw_unable_to_establish_connection", ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION +}, + +{ + "plpgsql_error", ERRCODE_PLPGSQL_ERROR +}, + +{ + "raise_exception", ERRCODE_RAISE_EXCEPTION +}, + +{ + "no_data_found", ERRCODE_NO_DATA_FOUND +}, + +{ + "too_many_rows", ERRCODE_TOO_MANY_ROWS +}, + +{ + "assert_failure", ERRCODE_ASSERT_FAILURE +}, + +{ + "internal_error", ERRCODE_INTERNAL_ERROR +}, + +{ + "data_corrupted", ERRCODE_DATA_CORRUPTED +}, + +{ + "index_corrupted", ERRCODE_INDEX_CORRUPTED +}, diff --git a/internal/summary/stmt_types.go b/internal/summary/stmt_types.go index b903c43..51ad2e1 100644 --- a/internal/summary/stmt_types.go +++ b/internal/summary/stmt_types.go @@ -1,6 +1,9 @@ package summary -import "github.com/sqlc-dev/oliphant/ast" +import ( + "github.com/sqlc-dev/oliphant/ast" + "github.com/sqlc-dev/oliphant/internal/rawwalk" +) // addStmtType is add_stmt_type_if_needed: an insertion-ordered set. func (s *state) addStmtType(name string) { @@ -17,8 +20,8 @@ func (s *state) addStmtType(name string) { // node the raw walker can reach, with explicit sub-walks for the four // utility statements that wrap a query but are not raw-walkable themselves. func (s *state) stmtWalk(item any) bool { - c := concrete(item) - if isNil(c) { + c := rawwalk.Concrete(item) + if rawwalk.IsNil(c) { return false } @@ -267,5 +270,5 @@ func (s *state) stmtWalk(item any) bool { s.addStmtType("VariableShowStmt") } - return walkChildren(item, s.stmtWalk) + return rawwalk.WalkChildren(item, s.stmtWalk) } diff --git a/internal/summary/summary.go b/internal/summary/summary.go index f115cec..e755dfe 100644 --- a/internal/summary/summary.go +++ b/internal/summary/summary.go @@ -5,6 +5,7 @@ import ( "github.com/sqlc-dev/oliphant/ast" "github.com/sqlc-dev/oliphant/internal/deparse" + "github.com/sqlc-dev/oliphant/internal/rawwalk" ) // Error carries an ereport raised during the summary walk (there is exactly @@ -33,7 +34,7 @@ func Summarize(tree *ast.ParseResult, truncateLimit int) (result *ast.SummaryRes }() s := &state{} - root := rawStmtList(tree.Stmts) + root := rawwalk.RawStmtList(tree.Stmts) // pg_query_summary_walk: the main walk, then the deferred range-var pass // (CTEs can be referenced before they are defined, so tables are only @@ -93,8 +94,8 @@ type state struct { // addRangeVar is add_range_var (pg_query_summary.c): wrap a FROM-clause item // (or statement target relation) and stash it for the deferred pass. func (s *state) addRangeVar(item any, context ast.SummaryResult_Context) { - c := concrete(item) - if isNil(c) { + c := rawwalk.Concrete(item) + if rawwalk.IsNil(c) { return } switch v := c.(type) { @@ -143,8 +144,8 @@ func (s *state) addFunction(funcname []*ast.Node, context ast.SummaryResult_Cont // walk is pg_query_summary_walk_impl. Returning true aborts the walk up the // chain, exactly like a C tree-walker callback. func (s *state) walk(item any) bool { - c := concrete(item) - if isNil(c) { + c := rawwalk.Concrete(item) + if rawwalk.IsNil(c) { return false } @@ -352,7 +353,7 @@ func (s *state) walk(item any) bool { s.filterColumns = append(s.filterColumns, fc) } - return walkChildren(item, s.walk) + return rawwalk.WalkChildren(item, s.walk) } // rangeVarToName is range_var_to_name: quote_identifier-rendered, dotted. diff --git a/internal/summary/truncate.go b/internal/summary/truncate.go index c22b689..0411cf7 100644 --- a/internal/summary/truncate.go +++ b/internal/summary/truncate.go @@ -5,6 +5,7 @@ import ( "github.com/sqlc-dev/oliphant/ast" "github.com/sqlc-dev/oliphant/internal/deparse" + "github.com/sqlc-dev/oliphant/internal/rawwalk" ) // Port of pg_query_summary_truncate.c: deparse the statements; if the result @@ -45,7 +46,7 @@ func truncate(stmts []*ast.RawStmt, truncateLimit int) string { } if len(stmts) > 0 { - state.generate(rawStmtList(stmts)) + state.generate(rawwalk.RawStmtList(stmts)) } pgQsortTruncations(state.truncations) return applyTruncations(stmts, state, truncateLimit) @@ -88,8 +89,8 @@ func (ts *truncationState) addWhereClause(node any, whereClause *ast.Node) { // generate is generate_possible_truncations. func (ts *truncationState) generate(item any) bool { - c := concrete(item) - if isNil(c) { + c := rawwalk.Concrete(item) + if rawwalk.IsNil(c) { return false } @@ -149,7 +150,7 @@ func (ts *truncationState) generate(item any) bool { // (list nodes count as a level, matching WALK on a List field). oldDepth := ts.depth ts.depth++ - result := walkChildren(item, ts.generate) + result := rawwalk.WalkChildren(item, ts.generate) ts.depth = oldDepth return result } diff --git a/parser/parser.go b/parser/parser.go index 3506b22..634b7e3 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -21,6 +21,7 @@ import ( "github.com/sqlc-dev/oliphant/internal/lexer" "github.com/sqlc-dev/oliphant/internal/normalize" "github.com/sqlc-dev/oliphant/internal/parse" + "github.com/sqlc-dev/oliphant/internal/plpgsql" "github.com/sqlc-dev/oliphant/internal/summary" "github.com/sqlc-dev/oliphant/internal/xxh3" ) @@ -118,8 +119,21 @@ func DeparseFromProtobuf(input []byte) (result string, err error) { return out, nil } +// ParsePlPgSqlToJSON is pg_query_parse_plpgsql: compile every CREATE +// FUNCTION/PROCEDURE and DO statement with the PL/pgSQL parser and render +// the JSON array of function dumps. func ParsePlPgSqlToJSON(input string) (result string, err error) { - return "", errNotImplemented("ParsePlPgSqlToJSON") + out, perr := plpgsql.ParseToJSON(input) + if perr != nil { + return "", &Error{ + Message: perr.Message, + Filename: perr.Filename, + Funcname: perr.Funcname, + Cursorpos: perr.Cursorpos, + Context: perr.Context, + } + } + return out, nil } // Normalize is pg_query_normalize: constants become $n parameter references. diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json index 442b788..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_array.metadata.json @@ -1,35 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json index 70c818b..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_cache.metadata.json @@ -1,17 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json index 449cbc1..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_call.metadata.json @@ -1,87 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json index 706d53c..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_control.metadata.json @@ -1,57 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json index f23fe5c..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_copy.metadata.json @@ -1,5 +1,3 @@ { - "todo": [ - "001" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json index aa06c83..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_domain.metadata.json @@ -1,86 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json index 5a08d01..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_misc.metadata.json @@ -1,18 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json index 780860b..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_record.metadata.json @@ -1,162 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124", - "125", - "126", - "127", - "128", - "129", - "130", - "131", - "132", - "133", - "134", - "135", - "136", - "137", - "138", - "139", - "140", - "141", - "142", - "143", - "144", - "145", - "146", - "147", - "148", - "149", - "150", - "151", - "152", - "153", - "154", - "155", - "156", - "157", - "158" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json index 5d34ab7..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_simple.metadata.json @@ -1,28 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json index 17a73dc..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_transaction.metadata.json @@ -1,121 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074", - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json index 6e8763d..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trap.metadata.json @@ -1,46 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json index 980156f..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_trigger.metadata.json @@ -1,10 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json index 6a83420..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_regress/plpgsql_varprops.metadata.json @@ -1,41 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037" - ] + "todo": [] } diff --git a/parser/testdata/plpgsql/plpgsql_samples.metadata.json b/parser/testdata/plpgsql/plpgsql_samples.metadata.json index d389286..737fd31 100644 --- a/parser/testdata/plpgsql/plpgsql_samples.metadata.json +++ b/parser/testdata/plpgsql/plpgsql_samples.metadata.json @@ -1,33 +1,3 @@ { - "todo": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029" - ] + "todo": [] } From 3d3025744fc1e0b94bf7dd9d02a16cc6e6c797fa Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 04:49:09 +0000 Subject: [PATCH 4/5] =?UTF-8?q?Docs:=20milestones=2010=E2=80=9311=20as-bui?= =?UTF-8?q?lt=20notes;=20status=20tables=20current?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PLAN.md gains the milestones 10–11 as-built notes (corpus tiers, the libpg_query mocks the PL/pgSQL port follows, the pg_qsort tie-order dependency in truncation, the raw-parse modes); README's status table catches up with milestones 3–11; CLAUDE.md and internal/reference/README cover the new generated file and vendored PL reference sources. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01C5Ummi5YEg7pxk5fvRUd3U --- CLAUDE.md | 3 +- PLAN.md | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++----- README.md | 20 +++++++------ 3 files changed, 94 insertions(+), 17 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 880e022..3e18a37 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,8 @@ the main module; the only module allowed to link pg_query_go (cgo) is - **Expected outputs are never edited by hand.** Goldens come from `cmd/regenerate` (the pinned oracle) or not at all. - Generated files (`ast/pg_query.pb.go`, `aliases.go`, - `internal/lexer/keywords.go`) are only ever written by `cmd/generate`. + `internal/lexer/keywords.go`, `internal/plpgsql/tables.go`) are only ever + written by `cmd/generate`. - The public API mirrors pg_query_go exactly; consumers must migrate by changing one import path. Never rename, add, or remove exported symbols without checking pg_query_go v6.2.2. diff --git a/PLAN.md b/PLAN.md index bbf847c..7d820f9 100644 --- a/PLAN.md +++ b/PLAN.md @@ -417,12 +417,19 @@ gate; the corpus harness exists before the first line of the lexer. reference's parse → deparse → reparse roundtrip criterion, since the goldens are the oracle's own deparse output). See "As-built notes (milestones 8–9)". -10. **Summary.** Port the summary API (classification + smart truncation). -11. **PL/pgSQL.** Port `pl_gram.y` + `pl_comp` subset + the JSON serializer - behind `ParsePlPgSqlToJSON`. Deliberately last: self-contained, and the - only piece whose deferral wouldn't block sqlc. If v1.0 ships without it, - the function returns a clear unimplemented error — flagged for an - explicit scope call rather than silently dropped. +10. **Summary.** ✅ *Landed 2026-08-17.* Port the summary API + (classification + smart truncation). **Gate:** the deferred summary + corpus extracted and green — met: all 43,992 summary and 43,345 + summary_truncate cases pass (the regress tiers untruncated and at limit + 100, plus libpg_query's summary test-call inputs at their upstream + limits). See "As-built notes (milestones 10–11)". +11. **PL/pgSQL.** ✅ *Landed 2026-08-17.* Port `pl_gram.y` + `pl_comp` + subset + the JSON serializer behind `ParsePlPgSqlToJSON`. **Gate:** the + deferred `plpgsql_regress/` + `plpgsql_samples` corpus green — met: all + 690 plpgsql cases pass, and the plpgsql_regress files also feed the + standard SQL suites (all passing on arrival). Every corpus suite's todo + list is empty: 2,067 files / 308,561 cases across eleven suites. See + "As-built notes (milestones 10–11)". 12. **Hardening.** `cmd/difftest` mutation fuzzing vs the live oracle as a scheduled CI job; `go test -race` over the parallel corpus run; benchmarks vs pg_query_go (cgo) and wasilibs (wasm) — expect wins from @@ -460,7 +467,10 @@ Measured at the pin, where the plan's estimates differ: - Deferred, deliberately: the **sqlc endtoend tier** (needs per-directory engine classification in the sqlc repo; import it alongside milestone 4), **`plpgsql_regress/`** (milestone 11), and **summary** golden extraction - (milestone 10). The stretch tarball tier remains stretch. + (milestone 10). The stretch tarball tier remains stretch. *(The plpgsql + and summary tiers landed with milestones 10–11: the corpus is now 2,067 + files / 308,561 cases across eleven suites; only the sqlc endtoend and + stretch tiers remain out.)* ### As-built notes (milestone 3) @@ -648,6 +658,70 @@ Measured at the pin, where the plan's estimates differ: unimplemented entry points are `Summary` (milestone 10) and `ParsePlPgSqlToJSON` (milestone 11). +### As-built notes (milestones 10–11) + +- The deferred corpus tiers landed first, as their own commit: `summary` + (regress + plpgsql_regress + libpg_query's summary test-call inputs, + untruncated), `summary_truncate` (the same regress statements at limit + 100 — the limit rides along as a `-- truncate_limit: N` directive line in + the case input, stripped by both sides — plus the upstream truncate tests + at their exact limits and every summary input at limit 50), and `plpgsql` + (`plpgsql_regress/` + `plpgsql_samples.sql`, one `ParsePlPgSqlToJSON` + golden per statement). libpg_query's summary tests are call sites, not + `tests[]` tables, so `cmd/regenerate` grew a call extractor + (`summary("...", 0, limit)` with C line splices removed); inputs are + transcribed mechanically, expectations always from the oracle. The + plpgsql_regress files also feed the five standard SQL suites — all of + those passed the existing implementation on arrival. +- Summary (`internal/summary`) is three ports over one shared + `raw_expression_tree_walker` (now `internal/rawwalk`, PostgreSQL 17's + nodeFuncs.c gated by `pg_query_raw_tree_walker_supports`): the + table/alias/CTE/function/filter-column walk with its quirks preserved + (WHERE clauses walked twice, so functions there are recorded once per + pass; the filter-column pass aborts at sub-SELECTs; `MERGE ... USING` + sources are never tables), the statement-type walk (insertion-ordered + set), and deparse-driven truncation. Truncation ordering needed the exact + `pg_qsort` algorithm again — `list_sort` maps to `pg_qsort` at the pin, + and equal (depth, length) pairs are ordered by the partition scheme, not + the comparator. List nodes count as depth levels, matching `WALK` on a + List field. The `"…"` dummy-node replacements and the multibyte fallback + chop (`pg_mbcharcliplen` over UTF-8) are byte-exact ports. +- PL/pgSQL (`internal/plpgsql`) ports what libpg_query *builds*, not + vanilla PostgreSQL: `extract_source.rb` mocks `parse_datatype` (type text + kept verbatim; only RECORD/REFCURSOR/CURSOR/TEXT recognized, by + length-limited case-insensitive prefix), stubs the `%TYPE`/`%ROWTYPE` + lookups to NULL (so `foo%rowtype` falls through to the verbatim-text + path), replaces `make_return_stmt` (no return-type checks; RETURN never + captures a varno), and fails `function_parse_error_transpose` + unconditionally — so compile errors carry `compilation of PL/pgSQL + function "f" near line N` context and no cursor, with filenames as the + vendored build's `__FILE__` (`pl_gram.y`, + `src_pl_plpgsql_src_pl_scanner.c`, ...). +- The pl scanner layers on the milestone-3 lexer: the core scanner runs + with the PL reserved keyword list, modeled by re-classifying the SQL + lexer's output (SQL keywords become plain identifiers unless + PL-reserved; the `n'...'` NCHAR special falls back to IDENT `"n"`), plus + the pushback stack, `A.B.C` datum composition, and the + statement-start/unreserved-keyword dance. `pl_gram.y` became recursive + descent with statement linenos computed at bison's reduce points — + `plpgsql_latest_lineno` is stateful and feeds the error context, so call + order is part of conformance. +- `check_sql_expr` needed the core grammar's PL/pgSQL raw-parse modes: + `parse.ParseWithMode` adds `RAW_PARSE_PLPGSQL_EXPR` (the `PLpgSQL_Expr` + production — everything that can follow SELECT, minus SELECT) and + `ASSIGN1..3` (`PLAssignStmt`). Embedded-SQL errors keep the core + message/filename/funcname but lose their cursor + (`plpgsql_sql_error_callback` flushes the external position). +- `cmd/generate -plpgsql` emits `internal/plpgsql/tables.go` from the newly + vendored `pl_reserved_kwlist.h`/`pl_unreserved_kwlist.h`/`plerrcodes.h` + (condition names with their duplicate counts — duplicate names produce + condition chains of that length). +- Corpus effect: all 43,992 summary, 43,345 summary_truncate, and 690 + plpgsql todos graduated; every suite's todo list is empty (2,067 files / + 308,561 cases). pg_query_go's `summary_test.go` is ported verbatim and + `TestParsePlPgSQL` now runs green; no entry point returns + not-implemented anymore. + ## Regeneration (the PostgreSQL-upgrade story) Everything derived is derived by committed tooling from the pin: diff --git a/README.md b/README.md index a1b3b79..a677004 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,15 @@ for the development loop. | Milestone | State | |---|---| | 1. Scaffolding + codegen | ✅ module, licenses, CI, vendored pin, `ast/` protobuf types, aliases, keyword tables, API surface, `parser.Error`; pg_query_go's parse_test tree literals compile unchanged | -| 2. Corpus + oracle | ✅ cgo oracle (`oracle/`), `cmd/regenerate`, 1,525 golden files / 217k cases across 8 suites, byte-reproducible; harness + `cmd/next-test` running everything as todo | -| 3. Lexer | — | -| 4. Expressions + SELECT | — | -| 5–7. DML, DDL, utility | — | -| 8. Normalize + fingerprint | — | -| 9. Deparse | — | -| 10–13. Summary, PL/pgSQL, hardening, sqlc integration | — | +| 2. Corpus + oracle | ✅ cgo oracle (`oracle/`), `cmd/regenerate`, byte-reproducible goldens; harness + `cmd/next-test` | +| 3. Lexer | ✅ `Scan`, `SplitWithScanner`, `HashXXH3_64`; token streams byte-identical across the corpus | +| 4. Expressions + SELECT | ✅ `Parse`/`ParseToJSON` for the SELECT family | +| 5–7. DML, DDL, utility | ✅ the full statement grammar; `SplitWithParser`, `IsUtilityStmt`; parse corpus at 100% | +| 8. Normalize + fingerprint | ✅ `Normalize`, `NormalizeUtility`, `Fingerprint` | +| 9. Deparse | ✅ `Deparse`, byte-equal to the oracle across the corpus | +| 10. Summary | ✅ `Summary` (classification + smart truncation) | +| 11. PL/pgSQL | ✅ `ParsePlPgSqlToJSON` (pl_gram + pl_comp subset + JSON dump) | +| 12–13. Hardening, sqlc integration | — | -Until the parser milestones land, every public entry point returns (or -panics with, for `HashXXH3_64`) a clear not-implemented error. +Every public entry point is implemented; the corpus — 2,067 golden files / +308,561 cases across eleven suites — passes with an empty todo list. From 4014bd89fe179c2cd6830b558311df3f747a2983 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 04:50:52 +0000 Subject: [PATCH 5/5] next-test: cover the summary, summary_truncate, and plpgsql suites The suite order predates milestones 10-11; with it stale, a future pin advance would put todos back on those suites that next-test silently skips. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01C5Ummi5YEg7pxk5fvRUd3U --- cmd/next-test/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/next-test/main.go b/cmd/next-test/main.go index 33afa05..18b641a 100644 --- a/cmd/next-test/main.go +++ b/cmd/next-test/main.go @@ -22,6 +22,7 @@ import ( var suiteOrder = []string{ "scan", "split_scanner", "parse", "deparse", "normalize", "normalize_utility", "fingerprint", "split_parser", + "summary", "summary_truncate", "plpgsql", } func main() {

    2. $hwr0(YK0fUcL$j`B7|_cK5XG|^ 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

      HhzRnqY8@CGMyc@XjY}*Zl?;a~= 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

    n|B|itfQ7=&C^WFmwgArWm})sC$=ub& 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

mhy3_l|K}WUFx^h8@Pty^RDn# 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